summaryrefslogtreecommitdiff
path: root/security/nss/lib
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib')
-rw-r--r--security/nss/lib/Makefile60
-rw-r--r--security/nss/lib/base/Makefile12
-rw-r--r--security/nss/lib/base/arena.c1218
-rw-r--r--security/nss/lib/base/base.h1398
-rw-r--r--security/nss/lib/base/baset.h129
-rw-r--r--security/nss/lib/base/config.mk20
-rw-r--r--security/nss/lib/base/error.c273
-rw-r--r--security/nss/lib/base/errorval.c66
-rw-r--r--security/nss/lib/base/hash.c377
-rw-r--r--security/nss/lib/base/hashops.c88
-rw-r--r--security/nss/lib/base/item.c212
-rw-r--r--security/nss/lib/base/libc.c168
-rw-r--r--security/nss/lib/base/list.c405
-rw-r--r--security/nss/lib/base/manifest.mn39
-rw-r--r--security/nss/lib/base/nssbase.h270
-rw-r--r--security/nss/lib/base/nssbaset.h123
-rw-r--r--security/nss/lib/base/tracker.c415
-rw-r--r--security/nss/lib/base/utf8.c730
-rw-r--r--security/nss/lib/certdb/.cvsignore1
-rw-r--r--security/nss/lib/certdb/Makefile48
-rw-r--r--security/nss/lib/certdb/alg1485.c1555
-rw-r--r--security/nss/lib/certdb/cert.h1650
-rw-r--r--security/nss/lib/certdb/certdb.c3273
-rw-r--r--security/nss/lib/certdb/certdb.h83
-rw-r--r--security/nss/lib/certdb/certi.h383
-rw-r--r--security/nss/lib/certdb/certt.h1345
-rw-r--r--security/nss/lib/certdb/certv3.c367
-rw-r--r--security/nss/lib/certdb/certxutl.c499
-rw-r--r--security/nss/lib/certdb/certxutl.h50
-rw-r--r--security/nss/lib/certdb/config.mk15
-rw-r--r--security/nss/lib/certdb/crl.c3373
-rw-r--r--security/nss/lib/certdb/genname.c1861
-rw-r--r--security/nss/lib/certdb/genname.h106
-rw-r--r--security/nss/lib/certdb/manifest.mn40
-rw-r--r--security/nss/lib/certdb/polcyxtn.c828
-rw-r--r--security/nss/lib/certdb/secname.c709
-rw-r--r--security/nss/lib/certdb/stanpcertdb.c1071
-rw-r--r--security/nss/lib/certdb/xauthkid.c128
-rw-r--r--security/nss/lib/certdb/xbsconst.c145
-rw-r--r--security/nss/lib/certdb/xconst.c286
-rw-r--r--security/nss/lib/certdb/xconst.h36
-rw-r--r--security/nss/lib/certhigh/Makefile48
-rw-r--r--security/nss/lib/certhigh/certhigh.c1193
-rw-r--r--security/nss/lib/certhigh/certhtml.c301
-rw-r--r--security/nss/lib/certhigh/certreq.c324
-rw-r--r--security/nss/lib/certhigh/certvfy.c1829
-rw-r--r--security/nss/lib/certhigh/certvfypkix.c2325
-rw-r--r--security/nss/lib/certhigh/certvfypkixprint.c206
-rw-r--r--security/nss/lib/certhigh/config.mk15
-rw-r--r--security/nss/lib/certhigh/crlv2.c162
-rw-r--r--security/nss/lib/certhigh/manifest.mn35
-rw-r--r--security/nss/lib/certhigh/ocsp.c5819
-rw-r--r--security/nss/lib/certhigh/ocsp.h705
-rw-r--r--security/nss/lib/certhigh/ocspi.h144
-rw-r--r--security/nss/lib/certhigh/ocspsig.c600
-rw-r--r--security/nss/lib/certhigh/ocspt.h303
-rw-r--r--security/nss/lib/certhigh/ocspti.h361
-rw-r--r--security/nss/lib/certhigh/xcrldist.c217
-rw-r--r--security/nss/lib/ckfw/Makefile40
-rw-r--r--security/nss/lib/ckfw/builtins/Makefile54
-rw-r--r--security/nss/lib/ckfw/builtins/README45
-rw-r--r--security/nss/lib/ckfw/builtins/anchor.c21
-rw-r--r--security/nss/lib/ckfw/builtins/bfind.c254
-rw-r--r--security/nss/lib/ckfw/builtins/binst.c106
-rw-r--r--security/nss/lib/ckfw/builtins/bobject.c226
-rw-r--r--security/nss/lib/ckfw/builtins/bsession.c79
-rw-r--r--security/nss/lib/ckfw/builtins/bslot.c95
-rw-r--r--security/nss/lib/ckfw/builtins/btoken.c155
-rw-r--r--security/nss/lib/ckfw/builtins/builtins.h76
-rw-r--r--security/nss/lib/ckfw/builtins/certdata.perl231
-rw-r--r--security/nss/lib/ckfw/builtins/certdata.txt24785
-rw-r--r--security/nss/lib/ckfw/builtins/ckbiver.c26
-rw-r--r--security/nss/lib/ckfw/builtins/config.mk38
-rw-r--r--security/nss/lib/ckfw/builtins/constants.c65
-rw-r--r--security/nss/lib/ckfw/builtins/manifest.mn31
-rw-r--r--security/nss/lib/ckfw/builtins/nssckbi.def26
-rw-r--r--security/nss/lib/ckfw/builtins/nssckbi.h60
-rw-r--r--security/nss/lib/ckfw/builtins/nssckbi.rc64
-rw-r--r--security/nss/lib/ckfw/capi/Makefile76
-rw-r--r--security/nss/lib/ckfw/capi/README7
-rw-r--r--security/nss/lib/ckfw/capi/anchor.c21
-rw-r--r--security/nss/lib/ckfw/capi/cfind.c584
-rw-r--r--security/nss/lib/ckfw/capi/cinst.c114
-rw-r--r--security/nss/lib/ckfw/capi/ckcapi.h275
-rw-r--r--security/nss/lib/ckfw/capi/ckcapiver.c25
-rw-r--r--security/nss/lib/ckfw/capi/cobject.c2308
-rw-r--r--security/nss/lib/ckfw/capi/config.mk35
-rw-r--r--security/nss/lib/ckfw/capi/constants.c64
-rw-r--r--security/nss/lib/ckfw/capi/crsa.c715
-rw-r--r--security/nss/lib/ckfw/capi/csession.c97
-rw-r--r--security/nss/lib/ckfw/capi/cslot.c95
-rw-r--r--security/nss/lib/ckfw/capi/ctoken.c212
-rw-r--r--security/nss/lib/ckfw/capi/manifest.mn34
-rw-r--r--security/nss/lib/ckfw/capi/nsscapi.def26
-rw-r--r--security/nss/lib/ckfw/capi/nsscapi.h41
-rw-r--r--security/nss/lib/ckfw/capi/nsscapi.rc64
-rw-r--r--security/nss/lib/ckfw/capi/staticobj.c43
-rw-r--r--security/nss/lib/ckfw/ck.api543
-rw-r--r--security/nss/lib/ckfw/ck.h92
-rw-r--r--security/nss/lib/ckfw/ckapi.perl451
-rw-r--r--security/nss/lib/ckfw/ckfw.h2430
-rw-r--r--security/nss/lib/ckfw/ckfwm.h132
-rw-r--r--security/nss/lib/ckfw/ckfwtm.h27
-rw-r--r--security/nss/lib/ckfw/ckmd.h36
-rw-r--r--security/nss/lib/ckfw/ckt.h8
-rw-r--r--security/nss/lib/ckfw/config.mk26
-rw-r--r--security/nss/lib/ckfw/crypto.c344
-rw-r--r--security/nss/lib/ckfw/dbm/Makefile10
-rw-r--r--security/nss/lib/ckfw/dbm/anchor.c21
-rw-r--r--security/nss/lib/ckfw/dbm/ckdbm.h252
-rw-r--r--security/nss/lib/ckfw/dbm/config.mk9
-rw-r--r--security/nss/lib/ckfw/dbm/db.c1036
-rw-r--r--security/nss/lib/ckfw/dbm/find.c137
-rw-r--r--security/nss/lib/ckfw/dbm/instance.c167
-rw-r--r--security/nss/lib/ckfw/dbm/manifest.mn26
-rw-r--r--security/nss/lib/ckfw/dbm/object.c175
-rw-r--r--security/nss/lib/ckfw/dbm/session.c269
-rw-r--r--security/nss/lib/ckfw/dbm/slot.c185
-rw-r--r--security/nss/lib/ckfw/dbm/token.c286
-rw-r--r--security/nss/lib/ckfw/find.c383
-rw-r--r--security/nss/lib/ckfw/hash.c306
-rw-r--r--security/nss/lib/ckfw/instance.c1344
-rw-r--r--security/nss/lib/ckfw/manifest.mn54
-rw-r--r--security/nss/lib/ckfw/mechanism.c1186
-rw-r--r--security/nss/lib/ckfw/mutex.c273
-rw-r--r--security/nss/lib/ckfw/nssck.api1858
-rw-r--r--security/nss/lib/ckfw/nssckepv.h10
-rw-r--r--security/nss/lib/ckfw/nssckft.h11
-rw-r--r--security/nss/lib/ckfw/nssckfw.h494
-rw-r--r--security/nss/lib/ckfw/nssckfwc.h1017
-rw-r--r--security/nss/lib/ckfw/nssckfwt.h114
-rw-r--r--security/nss/lib/ckfw/nssckg.h10
-rw-r--r--security/nss/lib/ckfw/nssckmdt.h1949
-rw-r--r--security/nss/lib/ckfw/nssckt.h13
-rw-r--r--security/nss/lib/ckfw/nssmkey/Makefile73
-rw-r--r--security/nss/lib/ckfw/nssmkey/README21
-rw-r--r--security/nss/lib/ckfw/nssmkey/ckmk.h202
-rw-r--r--security/nss/lib/ckfw/nssmkey/ckmkver.c25
-rw-r--r--security/nss/lib/ckfw/nssmkey/config.mk25
-rw-r--r--security/nss/lib/ckfw/nssmkey/manchor.c21
-rw-r--r--security/nss/lib/ckfw/nssmkey/manifest.mn34
-rw-r--r--security/nss/lib/ckfw/nssmkey/mconstants.c62
-rw-r--r--security/nss/lib/ckfw/nssmkey/mfind.c370
-rw-r--r--security/nss/lib/ckfw/nssmkey/minst.c114
-rw-r--r--security/nss/lib/ckfw/nssmkey/mobject.c1927
-rw-r--r--security/nss/lib/ckfw/nssmkey/mrsa.c514
-rw-r--r--security/nss/lib/ckfw/nssmkey/msession.c97
-rw-r--r--security/nss/lib/ckfw/nssmkey/mslot.c95
-rw-r--r--security/nss/lib/ckfw/nssmkey/mtoken.c212
-rw-r--r--security/nss/lib/ckfw/nssmkey/nssmkey.def26
-rw-r--r--security/nss/lib/ckfw/nssmkey/nssmkey.h41
-rw-r--r--security/nss/lib/ckfw/nssmkey/staticobj.c40
-rw-r--r--security/nss/lib/ckfw/object.c1027
-rw-r--r--security/nss/lib/ckfw/session.c2464
-rw-r--r--security/nss/lib/ckfw/sessobj.c1079
-rw-r--r--security/nss/lib/ckfw/slot.c727
-rw-r--r--security/nss/lib/ckfw/token.c1896
-rw-r--r--security/nss/lib/ckfw/wrap.c5676
-rw-r--r--security/nss/lib/crmf/Makefile49
-rw-r--r--security/nss/lib/crmf/asn1cmn.c220
-rw-r--r--security/nss/lib/crmf/challcli.c242
-rw-r--r--security/nss/lib/crmf/cmmf.h1090
-rw-r--r--security/nss/lib/crmf/cmmfasn1.c132
-rw-r--r--security/nss/lib/crmf/cmmfchal.c290
-rw-r--r--security/nss/lib/crmf/cmmfi.h98
-rw-r--r--security/nss/lib/crmf/cmmfit.h116
-rw-r--r--security/nss/lib/crmf/cmmfrec.c318
-rw-r--r--security/nss/lib/crmf/cmmfresp.c283
-rw-r--r--security/nss/lib/crmf/cmmft.h73
-rw-r--r--security/nss/lib/crmf/config.mk16
-rw-r--r--security/nss/lib/crmf/crmf.h1750
-rw-r--r--security/nss/lib/crmf/crmfcont.c1158
-rw-r--r--security/nss/lib/crmf/crmfdec.c363
-rw-r--r--security/nss/lib/crmf/crmfenc.c55
-rw-r--r--security/nss/lib/crmf/crmffut.h361
-rw-r--r--security/nss/lib/crmf/crmfget.c450
-rw-r--r--security/nss/lib/crmf/crmfi.h186
-rw-r--r--security/nss/lib/crmf/crmfit.h187
-rw-r--r--security/nss/lib/crmf/crmfpop.c600
-rw-r--r--security/nss/lib/crmf/crmfreq.c670
-rw-r--r--security/nss/lib/crmf/crmft.h188
-rw-r--r--security/nss/lib/crmf/crmftmpl.c270
-rw-r--r--security/nss/lib/crmf/encutil.c34
-rw-r--r--security/nss/lib/crmf/manifest.mn46
-rw-r--r--security/nss/lib/crmf/respcli.c137
-rw-r--r--security/nss/lib/crmf/respcmn.c406
-rw-r--r--security/nss/lib/crmf/servget.c978
-rw-r--r--security/nss/lib/cryptohi/Makefile49
-rw-r--r--security/nss/lib/cryptohi/config.mk15
-rw-r--r--security/nss/lib/cryptohi/cryptohi.h369
-rw-r--r--security/nss/lib/cryptohi/cryptoht.h16
-rw-r--r--security/nss/lib/cryptohi/dsautil.c267
-rw-r--r--security/nss/lib/cryptohi/key.h13
-rw-r--r--security/nss/lib/cryptohi/keyhi.h271
-rw-r--r--security/nss/lib/cryptohi/keyi.h24
-rw-r--r--security/nss/lib/cryptohi/keyt.h11
-rw-r--r--security/nss/lib/cryptohi/keythi.h258
-rw-r--r--security/nss/lib/cryptohi/manifest.mn33
-rw-r--r--security/nss/lib/cryptohi/sechash.c409
-rw-r--r--security/nss/lib/cryptohi/sechash.h59
-rw-r--r--security/nss/lib/cryptohi/seckey.c1937
-rw-r--r--security/nss/lib/cryptohi/secsign.c504
-rw-r--r--security/nss/lib/cryptohi/secvfy.c733
-rw-r--r--security/nss/lib/dev/Makefile25
-rw-r--r--security/nss/lib/dev/ckhelper.c592
-rw-r--r--security/nss/lib/dev/ckhelper.h161
-rw-r--r--security/nss/lib/dev/config.mk20
-rw-r--r--security/nss/lib/dev/dev.h942
-rw-r--r--security/nss/lib/dev/devm.h209
-rw-r--r--security/nss/lib/dev/devslot.c264
-rw-r--r--security/nss/lib/dev/devt.h160
-rw-r--r--security/nss/lib/dev/devtm.h29
-rw-r--r--security/nss/lib/dev/devtoken.c1584
-rw-r--r--security/nss/lib/dev/devutil.c1010
-rw-r--r--security/nss/lib/dev/manifest.mn36
-rw-r--r--security/nss/lib/dev/nssdev.h43
-rw-r--r--security/nss/lib/dev/nssdevt.h40
-rw-r--r--security/nss/lib/freebl/Makefile652
-rw-r--r--security/nss/lib/freebl/aeskeywrap.c385
-rw-r--r--security/nss/lib/freebl/alg2268.c487
-rw-r--r--security/nss/lib/freebl/alghmac.c165
-rw-r--r--security/nss/lib/freebl/alghmac.h64
-rw-r--r--security/nss/lib/freebl/arcfive.c89
-rw-r--r--security/nss/lib/freebl/arcfour-amd64-gas.s88
-rw-r--r--security/nss/lib/freebl/arcfour-amd64-masm.asm107
-rw-r--r--security/nss/lib/freebl/arcfour-amd64-sun.s84
-rw-r--r--security/nss/lib/freebl/arcfour.c573
-rw-r--r--security/nss/lib/freebl/blapi.h1414
-rw-r--r--security/nss/lib/freebl/blapii.h39
-rw-r--r--security/nss/lib/freebl/blapit.h415
-rw-r--r--security/nss/lib/freebl/camellia.c1786
-rw-r--r--security/nss/lib/freebl/camellia.h46
-rw-r--r--security/nss/lib/freebl/config.mk97
-rw-r--r--security/nss/lib/freebl/ctr.c167
-rw-r--r--security/nss/lib/freebl/ctr.h44
-rw-r--r--security/nss/lib/freebl/cts.c302
-rw-r--r--security/nss/lib/freebl/cts.h33
-rw-r--r--security/nss/lib/freebl/des.c680
-rw-r--r--security/nss/lib/freebl/des.h43
-rw-r--r--security/nss/lib/freebl/desblapi.c273
-rw-r--r--security/nss/lib/freebl/dh.c393
-rw-r--r--security/nss/lib/freebl/drbg.c915
-rw-r--r--security/nss/lib/freebl/dsa.c632
-rw-r--r--security/nss/lib/freebl/ec.c1080
-rw-r--r--security/nss/lib/freebl/ec.h13
-rw-r--r--security/nss/lib/freebl/ecl/Makefile194
-rw-r--r--security/nss/lib/freebl/ecl/README330
-rw-r--r--security/nss/lib/freebl/ecl/README.FP284
-rw-r--r--security/nss/lib/freebl/ecl/ec2.h92
-rw-r--r--security/nss/lib/freebl/ecl/ec2_163.c223
-rw-r--r--security/nss/lib/freebl/ecl/ec2_193.c240
-rw-r--r--security/nss/lib/freebl/ecl/ec2_233.c263
-rw-r--r--security/nss/lib/freebl/ecl/ec2_aff.c312
-rw-r--r--security/nss/lib/freebl/ecl/ec2_mont.c238
-rw-r--r--security/nss/lib/freebl/ecl/ec2_proj.c333
-rw-r--r--security/nss/lib/freebl/ecl/ec_naf.c69
-rw-r--r--security/nss/lib/freebl/ecl/ecl-curve.h110
-rw-r--r--security/nss/lib/freebl/ecl/ecl-exp.h162
-rw-r--r--security/nss/lib/freebl/ecl/ecl-priv.h246
-rw-r--r--security/nss/lib/freebl/ecl/ecl.c395
-rw-r--r--security/nss/lib/freebl/ecl/ecl.h57
-rw-r--r--security/nss/lib/freebl/ecl/ecl_curve.c89
-rw-r--r--security/nss/lib/freebl/ecl/ecl_gf.c997
-rw-r--r--security/nss/lib/freebl/ecl/ecl_mult.c322
-rw-r--r--security/nss/lib/freebl/ecl/ecp.h106
-rw-r--r--security/nss/lib/freebl/ecl/ecp_192.c484
-rw-r--r--security/nss/lib/freebl/ecl/ecp_224.c341
-rw-r--r--security/nss/lib/freebl/ecl/ecp_256.c377
-rw-r--r--security/nss/lib/freebl/ecl/ecp_384.c259
-rw-r--r--security/nss/lib/freebl/ecl/ecp_521.c138
-rw-r--r--security/nss/lib/freebl/ecl/ecp_aff.c317
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp.c531
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp.h372
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp160.c145
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp192.c143
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fp224.c156
-rw-r--r--security/nss/lib/freebl/ecl/ecp_fpinc.c821
-rw-r--r--security/nss/lib/freebl/ecl/ecp_jac.c514
-rw-r--r--security/nss/lib/freebl/ecl/ecp_jm.c289
-rw-r--r--security/nss/lib/freebl/ecl/ecp_mont.c155
-rw-r--r--security/nss/lib/freebl/ecl/tests/ec2_test.c482
-rw-r--r--security/nss/lib/freebl/ecl/tests/ec_naft.c117
-rw-r--r--security/nss/lib/freebl/ecl/tests/ecp_fpt.c1088
-rw-r--r--security/nss/lib/freebl/ecl/tests/ecp_test.c426
-rw-r--r--security/nss/lib/freebl/freebl.def26
-rw-r--r--security/nss/lib/freebl/freebl.rc68
-rw-r--r--security/nss/lib/freebl/freebl_hash.def39
-rw-r--r--security/nss/lib/freebl/freeblver.c24
-rw-r--r--security/nss/lib/freebl/gcm.c844
-rw-r--r--security/nss/lib/freebl/gcm.h31
-rw-r--r--security/nss/lib/freebl/genload.c167
-rw-r--r--security/nss/lib/freebl/hmacct.c336
-rw-r--r--security/nss/lib/freebl/hmacct.h38
-rw-r--r--security/nss/lib/freebl/intel-aes.h123
-rw-r--r--security/nss/lib/freebl/intel-aes.s2488
-rw-r--r--security/nss/lib/freebl/intel-gcm-wrap.c236
-rw-r--r--security/nss/lib/freebl/intel-gcm.h83
-rw-r--r--security/nss/lib/freebl/intel-gcm.s1340
-rw-r--r--security/nss/lib/freebl/jpake.c495
-rw-r--r--security/nss/lib/freebl/ldvector.c287
-rw-r--r--security/nss/lib/freebl/loader.c1909
-rw-r--r--security/nss/lib/freebl/loader.h612
-rw-r--r--security/nss/lib/freebl/manifest.mn163
-rw-r--r--security/nss/lib/freebl/md2.c268
-rw-r--r--security/nss/lib/freebl/md5.c594
-rw-r--r--security/nss/lib/freebl/mknewpc2.c210
-rw-r--r--security/nss/lib/freebl/mksp.c127
-rw-r--r--security/nss/lib/freebl/mpi/Makefile248
-rw-r--r--security/nss/lib/freebl/mpi/Makefile.os2247
-rw-r--r--security/nss/lib/freebl/mpi/Makefile.win258
-rw-r--r--security/nss/lib/freebl/mpi/README795
-rwxr-xr-xsecurity/nss/lib/freebl/mpi/all-tests83
-rw-r--r--security/nss/lib/freebl/mpi/doc/LICENSE11
-rw-r--r--security/nss/lib/freebl/mpi/doc/LICENSE-MPL35
-rw-r--r--security/nss/lib/freebl/mpi/doc/basecvt.pod67
-rwxr-xr-xsecurity/nss/lib/freebl/mpi/doc/build33
-rw-r--r--security/nss/lib/freebl/mpi/doc/div.txt68
-rw-r--r--security/nss/lib/freebl/mpi/doc/expt.txt99
-rw-r--r--security/nss/lib/freebl/mpi/doc/gcd.pod31
-rw-r--r--security/nss/lib/freebl/mpi/doc/invmod.pod37
-rw-r--r--security/nss/lib/freebl/mpi/doc/isprime.pod66
-rw-r--r--security/nss/lib/freebl/mpi/doc/lap.pod39
-rw-r--r--security/nss/lib/freebl/mpi/doc/mpi-test.pod53
-rw-r--r--security/nss/lib/freebl/mpi/doc/mul.txt81
-rw-r--r--security/nss/lib/freebl/mpi/doc/pi.txt57
-rw-r--r--security/nss/lib/freebl/mpi/doc/prime.txt6542
-rw-r--r--security/nss/lib/freebl/mpi/doc/prng.pod41
-rw-r--r--security/nss/lib/freebl/mpi/doc/redux.txt88
-rw-r--r--security/nss/lib/freebl/mpi/doc/sqrt.txt54
-rw-r--r--security/nss/lib/freebl/mpi/doc/square.txt76
-rw-r--r--security/nss/lib/freebl/mpi/doc/timing.txt217
-rw-r--r--security/nss/lib/freebl/mpi/hpma512.s615
-rw-r--r--security/nss/lib/freebl/mpi/hppa20.s904
-rw-r--r--security/nss/lib/freebl/mpi/hppatch.adb21
-rw-r--r--security/nss/lib/freebl/mpi/logtab.h30
-rwxr-xr-xsecurity/nss/lib/freebl/mpi/make-logtab31
-rwxr-xr-xsecurity/nss/lib/freebl/mpi/make-test-arrays101
-rw-r--r--security/nss/lib/freebl/mpi/mdxptest.c310
-rw-r--r--security/nss/lib/freebl/mpi/montmulf.c296
-rw-r--r--security/nss/lib/freebl/mpi/montmulf.h70
-rw-r--r--security/nss/lib/freebl/mpi/montmulf.il109
-rw-r--r--security/nss/lib/freebl/mpi/montmulf.s1938
-rw-r--r--security/nss/lib/freebl/mpi/montmulfv8.il109
-rw-r--r--security/nss/lib/freebl/mpi/montmulfv8.s1818
-rw-r--r--security/nss/lib/freebl/mpi/montmulfv9.il94
-rw-r--r--security/nss/lib/freebl/mpi/montmulfv9.s2348
-rw-r--r--security/nss/lib/freebl/mpi/mp_comba.c1298
-rw-r--r--security/nss/lib/freebl/mpi/mp_comba_amd64_masm.asm13066
-rw-r--r--security/nss/lib/freebl/mpi/mp_comba_amd64_sun.s16097
-rw-r--r--security/nss/lib/freebl/mpi/mp_gf2m-priv.h73
-rw-r--r--security/nss/lib/freebl/mpi/mp_gf2m.c579
-rw-r--r--security/nss/lib/freebl/mpi/mp_gf2m.h28
-rw-r--r--security/nss/lib/freebl/mpi/mpcpucache.c813
-rw-r--r--security/nss/lib/freebl/mpi/mpcpucache_amd64.s861
-rw-r--r--security/nss/lib/freebl/mpi/mpcpucache_x86.s901
-rw-r--r--security/nss/lib/freebl/mpi/mpi-config.h79
-rw-r--r--security/nss/lib/freebl/mpi/mpi-priv.h285
-rw-r--r--security/nss/lib/freebl/mpi/mpi-test.c1953
-rw-r--r--security/nss/lib/freebl/mpi/mpi.c4821
-rw-r--r--security/nss/lib/freebl/mpi/mpi.h301
-rw-r--r--security/nss/lib/freebl/mpi/mpi_amd64.c32
-rw-r--r--security/nss/lib/freebl/mpi/mpi_amd64_gas.s389
-rw-r--r--security/nss/lib/freebl/mpi/mpi_amd64_masm.asm388
-rw-r--r--security/nss/lib/freebl/mpi/mpi_amd64_sun.s385
-rw-r--r--security/nss/lib/freebl/mpi/mpi_arm.c171
-rw-r--r--security/nss/lib/freebl/mpi/mpi_hp.c83
-rw-r--r--security/nss/lib/freebl/mpi/mpi_i86pc.s316
-rw-r--r--security/nss/lib/freebl/mpi/mpi_mips.s472
-rw-r--r--security/nss/lib/freebl/mpi/mpi_sparc.c225
-rw-r--r--security/nss/lib/freebl/mpi/mpi_sse2.s294
-rw-r--r--security/nss/lib/freebl/mpi/mpi_x86.s544
-rw-r--r--security/nss/lib/freebl/mpi/mpi_x86_asm.c535
-rw-r--r--security/nss/lib/freebl/mpi/mpi_x86_os2.s541
-rw-r--r--security/nss/lib/freebl/mpi/mplogic.c433
-rw-r--r--security/nss/lib/freebl/mpi/mplogic.h53
-rw-r--r--security/nss/lib/freebl/mpi/mpmontg.c1174
-rw-r--r--security/nss/lib/freebl/mpi/mpprime.c584
-rw-r--r--security/nss/lib/freebl/mpi/mpprime.h38
-rw-r--r--security/nss/lib/freebl/mpi/mpv_sparc.c221
-rw-r--r--security/nss/lib/freebl/mpi/mpv_sparcv8.s1608
-rw-r--r--security/nss/lib/freebl/mpi/mpv_sparcv9.s1648
-rw-r--r--security/nss/lib/freebl/mpi/mpvalpha.c181
-rw-r--r--security/nss/lib/freebl/mpi/mulsqr.c83
-rwxr-xr-xsecurity/nss/lib/freebl/mpi/multest79
-rw-r--r--security/nss/lib/freebl/mpi/primes.c842
-rwxr-xr-xsecurity/nss/lib/freebl/mpi/stats42
-rw-r--r--security/nss/lib/freebl/mpi/target.mk233
-rw-r--r--security/nss/lib/freebl/mpi/test-arrays.txt58
-rw-r--r--security/nss/lib/freebl/mpi/test-info.c162
-rw-r--r--security/nss/lib/freebl/mpi/tests/LICENSE6
-rw-r--r--security/nss/lib/freebl/mpi/tests/LICENSE-MPL35
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-1.c43
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-2.c54
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-3.c99
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-3a.c112
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-4.c94
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-4a.c106
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-4b.c103
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-5.c71
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-5a.c133
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-6.c79
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-7.c75
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-8.c66
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-9.c84
-rw-r--r--security/nss/lib/freebl/mpi/tests/mptest-b.c186
-rw-r--r--security/nss/lib/freebl/mpi/tests/pi1k.txt1
-rw-r--r--security/nss/lib/freebl/mpi/tests/pi2k.txt1
-rw-r--r--security/nss/lib/freebl/mpi/tests/pi5k.txt1
-rwxr-xr-xsecurity/nss/lib/freebl/mpi/timetest103
-rwxr-xr-xsecurity/nss/lib/freebl/mpi/types.pl130
-rw-r--r--security/nss/lib/freebl/mpi/utils/LICENSE4
-rw-r--r--security/nss/lib/freebl/mpi/utils/LICENSE-MPL35
-rw-r--r--security/nss/lib/freebl/mpi/utils/PRIMES41
-rw-r--r--security/nss/lib/freebl/mpi/utils/README241
-rw-r--r--security/nss/lib/freebl/mpi/utils/basecvt.c68
-rw-r--r--security/nss/lib/freebl/mpi/utils/bbs_rand.c64
-rw-r--r--security/nss/lib/freebl/mpi/utils/bbs_rand.h25
-rw-r--r--security/nss/lib/freebl/mpi/utils/bbsrand.c35
-rw-r--r--security/nss/lib/freebl/mpi/utils/dec2hex.c39
-rw-r--r--security/nss/lib/freebl/mpi/utils/exptmod.c51
-rw-r--r--security/nss/lib/freebl/mpi/utils/fact.c83
-rw-r--r--security/nss/lib/freebl/mpi/utils/gcd.c87
-rw-r--r--security/nss/lib/freebl/mpi/utils/hex2dec.c39
-rw-r--r--security/nss/lib/freebl/mpi/utils/identest.c83
-rw-r--r--security/nss/lib/freebl/mpi/utils/invmod.c60
-rw-r--r--security/nss/lib/freebl/mpi/utils/isprime.c89
-rw-r--r--security/nss/lib/freebl/mpi/utils/lap.c89
-rw-r--r--security/nss/lib/freebl/mpi/utils/makeprime.c115
-rw-r--r--security/nss/lib/freebl/mpi/utils/metime.c103
-rw-r--r--security/nss/lib/freebl/mpi/utils/pi.c165
-rw-r--r--security/nss/lib/freebl/mpi/utils/primegen.c159
-rw-r--r--security/nss/lib/freebl/mpi/utils/prng.c58
-rwxr-xr-xsecurity/nss/lib/freebl/mpi/utils/ptab.pl29
-rw-r--r--security/nss/lib/freebl/mpi/utils/sieve.c236
-rw-r--r--security/nss/lib/freebl/mpi/vis_32.il1292
-rw-r--r--security/nss/lib/freebl/mpi/vis_64.il998
-rw-r--r--security/nss/lib/freebl/mpi/vis_proto.h235
-rw-r--r--security/nss/lib/freebl/nsslowhash.c398
-rw-r--r--security/nss/lib/freebl/nsslowhash.h28
-rw-r--r--security/nss/lib/freebl/os2_rand.c341
-rw-r--r--security/nss/lib/freebl/pqg.c1849
-rw-r--r--security/nss/lib/freebl/pqg.h25
-rw-r--r--security/nss/lib/freebl/rawhash.c161
-rw-r--r--security/nss/lib/freebl/ret_cr16.s27
-rw-r--r--security/nss/lib/freebl/rijndael.c1271
-rw-r--r--security/nss/lib/freebl/rijndael.h68
-rw-r--r--security/nss/lib/freebl/rijndael32.tab1219
-rw-r--r--security/nss/lib/freebl/rijndael_tables.c214
-rw-r--r--security/nss/lib/freebl/rsa.c1573
-rw-r--r--security/nss/lib/freebl/secmpi.h32
-rw-r--r--security/nss/lib/freebl/secrng.h67
-rw-r--r--security/nss/lib/freebl/seed.c646
-rw-r--r--security/nss/lib/freebl/seed.h128
-rw-r--r--security/nss/lib/freebl/sha-fast-amd64-sun.s2110
-rw-r--r--security/nss/lib/freebl/sha256.h19
-rw-r--r--security/nss/lib/freebl/sha512.c1599
-rw-r--r--security/nss/lib/freebl/sha_fast.c463
-rw-r--r--security/nss/lib/freebl/sha_fast.h171
-rw-r--r--security/nss/lib/freebl/shsign.h15
-rw-r--r--security/nss/lib/freebl/shvfy.c509
-rw-r--r--security/nss/lib/freebl/stubs.c639
-rw-r--r--security/nss/lib/freebl/stubs.h62
-rw-r--r--security/nss/lib/freebl/sysrand.c46
-rw-r--r--security/nss/lib/freebl/tlsprfalg.c137
-rw-r--r--security/nss/lib/freebl/unix_rand.c1151
-rw-r--r--security/nss/lib/freebl/win_rand.c463
-rw-r--r--security/nss/lib/jar/Makefile11
-rw-r--r--security/nss/lib/jar/config.mk26
-rw-r--r--security/nss/lib/jar/jar-ds.c36
-rw-r--r--security/nss/lib/jar/jar-ds.h78
-rw-r--r--security/nss/lib/jar/jar.c684
-rw-r--r--security/nss/lib/jar/jar.h373
-rw-r--r--security/nss/lib/jar/jarfile.c965
-rw-r--r--security/nss/lib/jar/jarfile.h76
-rw-r--r--security/nss/lib/jar/jarint.c52
-rw-r--r--security/nss/lib/jar/jarint.h55
-rw-r--r--security/nss/lib/jar/jarnav.c62
-rw-r--r--security/nss/lib/jar/jarsign.c238
-rw-r--r--security/nss/lib/jar/jarver.c1175
-rw-r--r--security/nss/lib/jar/jzconf.h190
-rw-r--r--security/nss/lib/jar/jzlib.h896
-rw-r--r--security/nss/lib/jar/manifest.mn25
-rwxr-xr-xsecurity/nss/lib/libpkix/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/config.mk16
-rwxr-xr-xsecurity/nss/lib/libpkix/include/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/include/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/include/manifest.mn32
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix.h301
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_certsel.h1826
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_certstore.h713
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_checker.h394
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_crlsel.h759
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_errorstrings.h1097
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_params.h1793
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_pl_pki.h2702
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_pl_system.h1545
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_results.h425
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_revchecker.h217
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_sample_modules.h418
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkix_util.h941
-rwxr-xr-xsecurity/nss/lib/libpkix/include/pkixt.h485
-rwxr-xr-xsecurity/nss/lib/libpkix/manifest.mn13
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/certsel/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/certsel/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/certsel/manifest.mn23
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/certsel/pkix_certselector.c1633
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/certsel/pkix_certselector.h41
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c1188
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.h57
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/manifest.mn45
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.c306
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.h42
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.c322
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.h36
-rw-r--r--security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.c440
-rw-r--r--security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.h68
-rw-r--r--security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c328
-rw-r--r--security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.h92
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.c113
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.h30
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.c121
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.h30
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c305
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.h43
-rw-r--r--security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c346
-rw-r--r--security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h67
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_policychecker.c2783
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_policychecker.h73
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c467
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h150
-rw-r--r--security/nss/lib/libpkix/pkix/checker/pkix_revocationmethod.c66
-rw-r--r--security/nss/lib/libpkix/pkix/checker/pkix_revocationmethod.h80
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.c443
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.h44
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c516
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.h47
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/crlsel/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/crlsel/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/crlsel/manifest.mn23
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c826
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h38
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c870
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.h40
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/manifest.mn11
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/manifest.mn27
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_buildparams.c284
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_buildparams.h32
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_procparams.c1417
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_procparams.h50
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_resourcelimits.c433
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_resourcelimits.h36
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_trustanchor.c521
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_trustanchor.h35
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_valparams.c335
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/params/pkix_valparams.h33
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/manifest.mn27
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_buildresult.c362
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_buildresult.h40
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_policynode.c1377
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_policynode.h74
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_valresult.c442
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_valresult.h43
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_verifynode.c1182
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/results/pkix_verifynode.h75
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/store/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/store/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/store/manifest.mn21
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/store/pkix_store.c415
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/store/pkix_store.h41
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/manifest.mn25
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_build.c3821
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_build.h123
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_lifecycle.c210
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_lifecycle.h23
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_validate.c1443
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/top/pkix_validate.h42
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/manifest.mn28
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/pkix_error.c565
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/pkix_error.h36
-rw-r--r--security/nss/lib/libpkix/pkix/util/pkix_errpaths.c103
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/pkix_list.c1701
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/pkix_list.h95
-rw-r--r--security/nss/lib/libpkix/pkix/util/pkix_logger.c1088
-rw-r--r--security/nss/lib/libpkix/pkix/util/pkix_logger.h57
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/pkix_tools.c1519
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix/util/pkix_tools.h1588
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/manifest.mn11
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/Makefile48
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/manifest.mn46
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c674
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h61
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.c1282
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.h34
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c1147
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h62
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c1662
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.h139
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.c1116
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.h75
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c2493
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.h82
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.c761
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.h86
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.c786
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.h96
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapt.h314
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaptemplates.c417
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.c319
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.h52
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c1049
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.h31
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c1690
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.h209
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/pki/Makefile49
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/pki/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn53
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.c407
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.h47
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c3710
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h107
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.c371
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h50
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.c386
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.h49
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.c365
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.h52
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c1068
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h48
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c151
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.h48
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c880
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.h46
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.c466
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.h55
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.c873
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.h49
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c870
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.h47
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c1274
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.h68
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c250
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h53
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c441
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h61
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c989
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h103
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c492
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.h38
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c722
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.h74
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/Makefile49
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/config.mk15
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/manifest.mn46
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.c398
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.h40
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.c504
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.h40
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.c1073
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h155
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_error.c26
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.c383
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.h29
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c271
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h89
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.c168
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.h24
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.c136
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.h33
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.c163
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.h33
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c1440
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.h76
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.c333
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.h39
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.c584
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.h102
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.c217
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.h35
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.c621
-rwxr-xr-xsecurity/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.h37
-rw-r--r--security/nss/lib/manifest.mn34
-rw-r--r--security/nss/lib/nss/Makefile46
-rw-r--r--security/nss/lib/nss/config.mk102
-rw-r--r--security/nss/lib/nss/manifest.mn29
-rw-r--r--security/nss/lib/nss/nss.def1029
-rw-r--r--security/nss/lib/nss/nss.h320
-rw-r--r--security/nss/lib/nss/nss.rc68
-rw-r--r--security/nss/lib/nss/nssinit.c1301
-rw-r--r--security/nss/lib/nss/nssrenam.h15
-rw-r--r--security/nss/lib/nss/nssver.c24
-rw-r--r--security/nss/lib/nss/pkixpriv.def322
-rw-r--r--security/nss/lib/nss/utilwrap.c794
-rw-r--r--security/nss/lib/pk11wrap/Makefile62
-rw-r--r--security/nss/lib/pk11wrap/config.mk15
-rw-r--r--security/nss/lib/pk11wrap/debug_module.c2733
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.c309
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.h34
-rw-r--r--security/nss/lib/pk11wrap/manifest.mn63
-rw-r--r--security/nss/lib/pk11wrap/pk11akey.c2387
-rw-r--r--security/nss/lib/pk11wrap/pk11auth.c788
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c2684
-rw-r--r--security/nss/lib/pk11wrap/pk11cxt.c1039
-rw-r--r--security/nss/lib/pk11wrap/pk11err.c135
-rw-r--r--security/nss/lib/pk11wrap/pk11func.h15
-rw-r--r--security/nss/lib/pk11wrap/pk11kea.c131
-rw-r--r--security/nss/lib/pk11wrap/pk11list.c95
-rw-r--r--security/nss/lib/pk11wrap/pk11load.c600
-rw-r--r--security/nss/lib/pk11wrap/pk11mech.c1872
-rw-r--r--security/nss/lib/pk11wrap/pk11merge.c1419
-rw-r--r--security/nss/lib/pk11wrap/pk11nobj.c785
-rw-r--r--security/nss/lib/pk11wrap/pk11obj.c1889
-rw-r--r--security/nss/lib/pk11wrap/pk11pars.c1134
-rw-r--r--security/nss/lib/pk11wrap/pk11pbe.c1432
-rw-r--r--security/nss/lib/pk11wrap/pk11pk12.c518
-rw-r--r--security/nss/lib/pk11wrap/pk11pqg.c512
-rw-r--r--security/nss/lib/pk11wrap/pk11pqg.h142
-rw-r--r--security/nss/lib/pk11wrap/pk11priv.h192
-rw-r--r--security/nss/lib/pk11wrap/pk11pub.h830
-rw-r--r--security/nss/lib/pk11wrap/pk11sdr.c377
-rw-r--r--security/nss/lib/pk11wrap/pk11sdr.h28
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c2668
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c2393
-rw-r--r--security/nss/lib/pk11wrap/pk11util.c1578
-rw-r--r--security/nss/lib/pk11wrap/secmod.h164
-rw-r--r--security/nss/lib/pk11wrap/secmodi.h174
-rw-r--r--security/nss/lib/pk11wrap/secmodt.h448
-rw-r--r--security/nss/lib/pk11wrap/secmodti.h187
-rw-r--r--security/nss/lib/pk11wrap/secpkcs5.h62
-rw-r--r--security/nss/lib/pkcs12/Makefile49
-rw-r--r--security/nss/lib/pkcs12/config.mk16
-rw-r--r--security/nss/lib/pkcs12/manifest.mn31
-rw-r--r--security/nss/lib/pkcs12/p12.h185
-rw-r--r--security/nss/lib/pkcs12/p12creat.c222
-rw-r--r--security/nss/lib/pkcs12/p12d.c3548
-rw-r--r--security/nss/lib/pkcs12/p12dec.c664
-rw-r--r--security/nss/lib/pkcs12/p12e.c2079
-rw-r--r--security/nss/lib/pkcs12/p12exp.c1378
-rw-r--r--security/nss/lib/pkcs12/p12local.c1342
-rw-r--r--security/nss/lib/pkcs12/p12local.h59
-rw-r--r--security/nss/lib/pkcs12/p12plcy.c125
-rw-r--r--security/nss/lib/pkcs12/p12plcy.h25
-rw-r--r--security/nss/lib/pkcs12/p12t.h155
-rw-r--r--security/nss/lib/pkcs12/p12tmpl.c291
-rw-r--r--security/nss/lib/pkcs12/pkcs12.h42
-rw-r--r--security/nss/lib/pkcs12/pkcs12t.h366
-rw-r--r--security/nss/lib/pkcs7/Makefile48
-rw-r--r--security/nss/lib/pkcs7/certread.c434
-rw-r--r--security/nss/lib/pkcs7/config.mk14
-rw-r--r--security/nss/lib/pkcs7/manifest.mn33
-rw-r--r--security/nss/lib/pkcs7/p7common.c693
-rw-r--r--security/nss/lib/pkcs7/p7create.c1293
-rw-r--r--security/nss/lib/pkcs7/p7decode.c1909
-rw-r--r--security/nss/lib/pkcs7/p7encode.c1112
-rw-r--r--security/nss/lib/pkcs7/p7local.c1321
-rw-r--r--security/nss/lib/pkcs7/p7local.h141
-rw-r--r--security/nss/lib/pkcs7/pkcs7t.h237
-rw-r--r--security/nss/lib/pkcs7/secmime.c824
-rw-r--r--security/nss/lib/pkcs7/secmime.h163
-rw-r--r--security/nss/lib/pkcs7/secpkcs7.h594
-rw-r--r--security/nss/lib/pki/Makefile12
-rw-r--r--security/nss/lib/pki/asymmkey.c402
-rw-r--r--security/nss/lib/pki/certdecode.c69
-rw-r--r--security/nss/lib/pki/certificate.c1176
-rw-r--r--security/nss/lib/pki/config.mk20
-rw-r--r--security/nss/lib/pki/cryptocontext.c986
-rw-r--r--security/nss/lib/pki/doc/standiag.pngbin20475 -> 0 bytes
-rw-r--r--security/nss/lib/pki/doc/standoc.html442
-rw-r--r--security/nss/lib/pki/manifest.mn46
-rw-r--r--security/nss/lib/pki/nsspki.h3168
-rw-r--r--security/nss/lib/pki/nsspkit.h251
-rw-r--r--security/nss/lib/pki/pki.h217
-rw-r--r--security/nss/lib/pki/pki3hack.c1435
-rw-r--r--security/nss/lib/pki/pki3hack.h168
-rw-r--r--security/nss/lib/pki/pkibase.c1258
-rw-r--r--security/nss/lib/pki/pkim.h699
-rw-r--r--security/nss/lib/pki/pkistore.c743
-rw-r--r--security/nss/lib/pki/pkistore.h172
-rw-r--r--security/nss/lib/pki/pkit.h192
-rw-r--r--security/nss/lib/pki/pkitm.h92
-rw-r--r--security/nss/lib/pki/symmkey.c268
-rw-r--r--security/nss/lib/pki/tdcache.c1150
-rw-r--r--security/nss/lib/pki/trustdomain.c1258
-rw-r--r--security/nss/lib/smime/Makefile48
-rw-r--r--security/nss/lib/smime/cms.h1155
-rw-r--r--security/nss/lib/smime/cmsarray.c187
-rw-r--r--security/nss/lib/smime/cmsasn1.c501
-rw-r--r--security/nss/lib/smime/cmsattr.c429
-rw-r--r--security/nss/lib/smime/cmscinfo.c373
-rw-r--r--security/nss/lib/smime/cmscipher.c717
-rw-r--r--security/nss/lib/smime/cmsdecode.c741
-rw-r--r--security/nss/lib/smime/cmsdigdata.c212
-rw-r--r--security/nss/lib/smime/cmsdigest.c262
-rw-r--r--security/nss/lib/smime/cmsencdata.c262
-rw-r--r--security/nss/lib/smime/cmsencode.c750
-rw-r--r--security/nss/lib/smime/cmsenvdata.c399
-rw-r--r--security/nss/lib/smime/cmslocal.h355
-rw-r--r--security/nss/lib/smime/cmsmessage.c293
-rw-r--r--security/nss/lib/smime/cmspubkey.c287
-rw-r--r--security/nss/lib/smime/cmsrecinfo.c682
-rw-r--r--security/nss/lib/smime/cmsreclist.c169
-rw-r--r--security/nss/lib/smime/cmsreclist.h30
-rw-r--r--security/nss/lib/smime/cmssigdata.c1143
-rw-r--r--security/nss/lib/smime/cmssiginfo.c1023
-rw-r--r--security/nss/lib/smime/cmst.h498
-rw-r--r--security/nss/lib/smime/cmsudf.c448
-rw-r--r--security/nss/lib/smime/cmsutil.c359
-rw-r--r--security/nss/lib/smime/config.mk63
-rw-r--r--security/nss/lib/smime/manifest.mn51
-rw-r--r--security/nss/lib/smime/smime.def269
-rw-r--r--security/nss/lib/smime/smime.h140
-rw-r--r--security/nss/lib/smime/smime.rc68
-rw-r--r--security/nss/lib/smime/smimemessage.c186
-rw-r--r--security/nss/lib/smime/smimesym.c12
-rw-r--r--security/nss/lib/smime/smimeutil.c783
-rw-r--r--security/nss/lib/smime/smimever.c24
-rw-r--r--security/nss/lib/softoken/Makefile68
-rw-r--r--security/nss/lib/softoken/config.mk67
-rw-r--r--security/nss/lib/softoken/ecdecode.c606
-rw-r--r--security/nss/lib/softoken/fipsaudt.c319
-rw-r--r--security/nss/lib/softoken/fipstest.c2101
-rw-r--r--security/nss/lib/softoken/fipstokn.c1575
-rw-r--r--security/nss/lib/softoken/jpakesftk.c350
-rw-r--r--security/nss/lib/softoken/legacydb/Makefile50
-rw-r--r--security/nss/lib/softoken/legacydb/cdbhdl.h53
-rw-r--r--security/nss/lib/softoken/legacydb/config.mk61
-rw-r--r--security/nss/lib/softoken/legacydb/dbmshim.c615
-rw-r--r--security/nss/lib/softoken/legacydb/keydb.c2268
-rw-r--r--security/nss/lib/softoken/legacydb/keydbi.h54
-rw-r--r--security/nss/lib/softoken/legacydb/lgattr.c1790
-rw-r--r--security/nss/lib/softoken/legacydb/lgcreate.c981
-rw-r--r--security/nss/lib/softoken/legacydb/lgdb.h177
-rw-r--r--security/nss/lib/softoken/legacydb/lgdestroy.c111
-rw-r--r--security/nss/lib/softoken/legacydb/lgfind.c915
-rw-r--r--security/nss/lib/softoken/legacydb/lginit.c665
-rw-r--r--security/nss/lib/softoken/legacydb/lgutil.c391
-rw-r--r--security/nss/lib/softoken/legacydb/lowcert.c828
-rw-r--r--security/nss/lib/softoken/legacydb/lowkey.c410
-rw-r--r--security/nss/lib/softoken/legacydb/lowkeyi.h153
-rw-r--r--security/nss/lib/softoken/legacydb/lowkeyti.h137
-rw-r--r--security/nss/lib/softoken/legacydb/manifest.mn31
-rw-r--r--security/nss/lib/softoken/legacydb/nssdbm.def31
-rw-r--r--security/nss/lib/softoken/legacydb/nssdbm.rc68
-rw-r--r--security/nss/lib/softoken/legacydb/pcert.h229
-rw-r--r--security/nss/lib/softoken/legacydb/pcertdb.c5356
-rw-r--r--security/nss/lib/softoken/legacydb/pcertt.h420
-rw-r--r--security/nss/lib/softoken/legacydb/pk11db.c717
-rw-r--r--security/nss/lib/softoken/lgglue.c436
-rw-r--r--security/nss/lib/softoken/lgglue.h60
-rw-r--r--security/nss/lib/softoken/lowkey.c492
-rw-r--r--security/nss/lib/softoken/lowkeyi.h75
-rw-r--r--security/nss/lib/softoken/lowkeyti.h94
-rw-r--r--security/nss/lib/softoken/lowpbe.c1378
-rw-r--r--security/nss/lib/softoken/lowpbe.h108
-rw-r--r--security/nss/lib/softoken/manifest.mn63
-rw-r--r--security/nss/lib/softoken/padbuf.c49
-rw-r--r--security/nss/lib/softoken/pkcs11.c4708
-rw-r--r--security/nss/lib/softoken/pkcs11c.c6931
-rw-r--r--security/nss/lib/softoken/pkcs11i.h744
-rw-r--r--security/nss/lib/softoken/pkcs11ni.h21
-rw-r--r--security/nss/lib/softoken/pkcs11u.c1979
-rw-r--r--security/nss/lib/softoken/rsawrapr.c1449
-rw-r--r--security/nss/lib/softoken/sdb.c2079
-rw-r--r--security/nss/lib/softoken/sdb.h78
-rw-r--r--security/nss/lib/softoken/sftkdb.c2737
-rw-r--r--security/nss/lib/softoken/sftkdb.h71
-rw-r--r--security/nss/lib/softoken/sftkdbt.h12
-rw-r--r--security/nss/lib/softoken/sftkdbti.h60
-rw-r--r--security/nss/lib/softoken/sftkhmac.c192
-rw-r--r--security/nss/lib/softoken/sftkpars.c248
-rw-r--r--security/nss/lib/softoken/sftkpars.h17
-rw-r--r--security/nss/lib/softoken/sftkpwd.c1275
-rw-r--r--security/nss/lib/softoken/softkver.c24
-rw-r--r--security/nss/lib/softoken/softkver.h35
-rw-r--r--security/nss/lib/softoken/softoken.h378
-rw-r--r--security/nss/lib/softoken/softokn.def28
-rw-r--r--security/nss/lib/softoken/softokn.rc68
-rw-r--r--security/nss/lib/softoken/softoknt.h59
-rw-r--r--security/nss/lib/softoken/tlsprf.c183
-rw-r--r--security/nss/lib/sqlite/Makefile48
-rw-r--r--security/nss/lib/sqlite/README3
-rw-r--r--security/nss/lib/sqlite/config.mk47
-rw-r--r--security/nss/lib/sqlite/manifest.mn34
-rw-r--r--security/nss/lib/sqlite/sqlite.def147
-rw-r--r--security/nss/lib/sqlite/sqlite3.c137413
-rw-r--r--security/nss/lib/sqlite/sqlite3.h7160
-rw-r--r--security/nss/lib/ssl/Makefile63
-rw-r--r--security/nss/lib/ssl/SSLerrs.h405
-rw-r--r--security/nss/lib/ssl/authcert.c90
-rw-r--r--security/nss/lib/ssl/cmpcert.c91
-rw-r--r--security/nss/lib/ssl/config.mk92
-rw-r--r--security/nss/lib/ssl/derive.c865
-rw-r--r--security/nss/lib/ssl/dtlscon.c1133
-rw-r--r--security/nss/lib/ssl/manifest.mn53
-rw-r--r--security/nss/lib/ssl/notes.txt134
-rw-r--r--security/nss/lib/ssl/os2_err.c281
-rw-r--r--security/nss/lib/ssl/os2_err.h54
-rw-r--r--security/nss/lib/ssl/preenc.h114
-rw-r--r--security/nss/lib/ssl/prelib.c35
-rw-r--r--security/nss/lib/ssl/ssl.def165
-rw-r--r--security/nss/lib/ssl/ssl.h980
-rw-r--r--security/nss/lib/ssl/ssl.rc68
-rw-r--r--security/nss/lib/ssl/ssl3con.c10825
-rw-r--r--security/nss/lib/ssl/ssl3ecc.c1158
-rw-r--r--security/nss/lib/ssl/ssl3ext.c1989
-rw-r--r--security/nss/lib/ssl/ssl3gthr.c408
-rw-r--r--security/nss/lib/ssl/ssl3prot.h323
-rw-r--r--security/nss/lib/ssl/sslauth.c258
-rw-r--r--security/nss/lib/ssl/sslcon.c3697
-rw-r--r--security/nss/lib/ssl/ssldef.c211
-rw-r--r--security/nss/lib/ssl/sslenum.c134
-rw-r--r--security/nss/lib/ssl/sslerr.c42
-rw-r--r--security/nss/lib/ssl/sslerr.h197
-rw-r--r--security/nss/lib/ssl/sslerrstrs.c34
-rw-r--r--security/nss/lib/ssl/sslgathr.c454
-rw-r--r--security/nss/lib/ssl/sslimpl.h1805
-rw-r--r--security/nss/lib/ssl/sslinfo.c387
-rw-r--r--security/nss/lib/ssl/sslinit.c29
-rw-r--r--security/nss/lib/ssl/sslmutex.c641
-rw-r--r--security/nss/lib/ssl/sslmutex.h126
-rw-r--r--security/nss/lib/ssl/sslnonce.c507
-rw-r--r--security/nss/lib/ssl/sslproto.h214
-rw-r--r--security/nss/lib/ssl/sslreveal.c118
-rw-r--r--security/nss/lib/ssl/sslsecur.c1505
-rw-r--r--security/nss/lib/ssl/sslsnce.c2214
-rw-r--r--security/nss/lib/ssl/sslsock.c3003
-rw-r--r--security/nss/lib/ssl/sslt.h191
-rw-r--r--security/nss/lib/ssl/ssltrace.c244
-rw-r--r--security/nss/lib/ssl/sslver.c24
-rw-r--r--security/nss/lib/ssl/unix_err.c518
-rw-r--r--security/nss/lib/ssl/unix_err.h58
-rw-r--r--security/nss/lib/ssl/win32err.c344
-rw-r--r--security/nss/lib/ssl/win32err.h52
-rw-r--r--security/nss/lib/sysinit/Makefile48
-rw-r--r--security/nss/lib/sysinit/config.mk80
-rw-r--r--security/nss/lib/sysinit/manifest.mn15
-rw-r--r--security/nss/lib/sysinit/nsssysinit.c403
-rw-r--r--security/nss/lib/util/Makefile56
-rw-r--r--security/nss/lib/util/SECerrs.h553
-rw-r--r--security/nss/lib/util/base64.h43
-rw-r--r--security/nss/lib/util/ciferfam.h61
-rw-r--r--security/nss/lib/util/config.mk45
-rw-r--r--security/nss/lib/util/derdec.c189
-rw-r--r--security/nss/lib/util/derenc.c473
-rw-r--r--security/nss/lib/util/dersubr.c246
-rw-r--r--security/nss/lib/util/dertime.c310
-rw-r--r--security/nss/lib/util/errstrs.c40
-rw-r--r--security/nss/lib/util/hasht.h62
-rw-r--r--security/nss/lib/util/manifest.mn86
-rw-r--r--security/nss/lib/util/nssb64.h96
-rw-r--r--security/nss/lib/util/nssb64d.c838
-rw-r--r--security/nss/lib/util/nssb64e.c733
-rw-r--r--security/nss/lib/util/nssb64t.h17
-rw-r--r--security/nss/lib/util/nssilckt.h191
-rw-r--r--security/nss/lib/util/nssilock.c498
-rw-r--r--security/nss/lib/util/nssilock.h288
-rw-r--r--security/nss/lib/util/nsslocks.h13
-rw-r--r--security/nss/lib/util/nssrwlk.c447
-rw-r--r--security/nss/lib/util/nssrwlk.h132
-rw-r--r--security/nss/lib/util/nssrwlkt.h20
-rw-r--r--security/nss/lib/util/nssutil.def272
-rw-r--r--security/nss/lib/util/nssutil.h41
-rw-r--r--security/nss/lib/util/nssutil.rc68
-rw-r--r--security/nss/lib/util/oidstring.c114
-rw-r--r--security/nss/lib/util/pkcs11.h257
-rw-r--r--security/nss/lib/util/pkcs11f.h905
-rw-r--r--security/nss/lib/util/pkcs11n.h464
-rw-r--r--security/nss/lib/util/pkcs11p.h22
-rw-r--r--security/nss/lib/util/pkcs11t.h1793
-rw-r--r--security/nss/lib/util/pkcs11u.h20
-rw-r--r--security/nss/lib/util/portreg.c377
-rw-r--r--security/nss/lib/util/portreg.h83
-rw-r--r--security/nss/lib/util/quickder.c897
-rw-r--r--security/nss/lib/util/secalgid.c127
-rw-r--r--security/nss/lib/util/secasn1.h294
-rw-r--r--security/nss/lib/util/secasn1d.c3237
-rw-r--r--security/nss/lib/util/secasn1e.c1615
-rw-r--r--security/nss/lib/util/secasn1t.h270
-rw-r--r--security/nss/lib/util/secasn1u.c99
-rw-r--r--security/nss/lib/util/seccomon.h94
-rw-r--r--security/nss/lib/util/secder.h176
-rw-r--r--security/nss/lib/util/secdert.h131
-rw-r--r--security/nss/lib/util/secdig.c181
-rw-r--r--security/nss/lib/util/secdig.h104
-rw-r--r--security/nss/lib/util/secdigt.h29
-rw-r--r--security/nss/lib/util/secerr.h218
-rw-r--r--security/nss/lib/util/secitem.c419
-rw-r--r--security/nss/lib/util/secitem.h102
-rw-r--r--security/nss/lib/util/secload.c182
-rw-r--r--security/nss/lib/util/secoid.c2194
-rw-r--r--security/nss/lib/util/secoid.h143
-rw-r--r--security/nss/lib/util/secoidt.h486
-rw-r--r--security/nss/lib/util/secplcy.c85
-rw-r--r--security/nss/lib/util/secplcy.h106
-rw-r--r--security/nss/lib/util/secport.c680
-rw-r--r--security/nss/lib/util/secport.h252
-rw-r--r--security/nss/lib/util/sectime.c161
-rw-r--r--security/nss/lib/util/templates.c136
-rw-r--r--security/nss/lib/util/utf8.c1800
-rw-r--r--security/nss/lib/util/utilmod.c684
-rw-r--r--security/nss/lib/util/utilmodt.h42
-rw-r--r--security/nss/lib/util/utilpars.c1117
-rw-r--r--security/nss/lib/util/utilpars.h56
-rw-r--r--security/nss/lib/util/utilparst.h76
-rw-r--r--security/nss/lib/util/utilrename.h162
-rw-r--r--security/nss/lib/zlib/Makefile55
-rw-r--r--security/nss/lib/zlib/README115
-rw-r--r--security/nss/lib/zlib/README.nss18
-rw-r--r--security/nss/lib/zlib/adler32.c169
-rw-r--r--security/nss/lib/zlib/compress.c80
-rw-r--r--security/nss/lib/zlib/config.mk16
-rw-r--r--security/nss/lib/zlib/crc32.c442
-rw-r--r--security/nss/lib/zlib/crc32.h445
-rw-r--r--security/nss/lib/zlib/deflate.c1834
-rw-r--r--security/nss/lib/zlib/deflate.h342
-rw-r--r--security/nss/lib/zlib/example.c565
-rw-r--r--security/nss/lib/zlib/gzclose.c25
-rw-r--r--security/nss/lib/zlib/gzguts.h132
-rw-r--r--security/nss/lib/zlib/gzlib.c537
-rw-r--r--security/nss/lib/zlib/gzread.c653
-rw-r--r--security/nss/lib/zlib/gzwrite.c531
-rw-r--r--security/nss/lib/zlib/infback.c632
-rw-r--r--security/nss/lib/zlib/inffast.c340
-rw-r--r--security/nss/lib/zlib/inffast.h11
-rw-r--r--security/nss/lib/zlib/inffixed.h98
-rw-r--r--security/nss/lib/zlib/inflate.c1480
-rw-r--r--security/nss/lib/zlib/inflate.h122
-rw-r--r--security/nss/lib/zlib/inftrees.c330
-rw-r--r--security/nss/lib/zlib/inftrees.h62
-rw-r--r--security/nss/lib/zlib/manifest.mn39
-rw-r--r--security/nss/lib/zlib/minigzip.c440
-rw-r--r--security/nss/lib/zlib/patches/msvc-vsnprintf.patch22
-rw-r--r--security/nss/lib/zlib/patches/prune-zlib.sh34
-rw-r--r--security/nss/lib/zlib/trees.c1244
-rw-r--r--security/nss/lib/zlib/trees.h132
-rw-r--r--security/nss/lib/zlib/uncompr.c59
-rw-r--r--security/nss/lib/zlib/zconf.h428
-rw-r--r--security/nss/lib/zlib/zlib.h1613
-rw-r--r--security/nss/lib/zlib/zutil.c318
-rw-r--r--security/nss/lib/zlib/zutil.h275
1054 files changed, 0 insertions, 687316 deletions
diff --git a/security/nss/lib/Makefile b/security/nss/lib/Makefile
deleted file mode 100644
index 364c44222..000000000
--- a/security/nss/lib/Makefile
+++ /dev/null
@@ -1,60 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-ifndef USE_SYSTEM_ZLIB
-ZLIB_SRCDIR = zlib # Add the zlib directory to DIRS.
-endif
-
-ifndef MOZILLA_CLIENT
-ifndef NSS_USE_SYSTEM_SQLITE
-SQLITE_SRCDIR = sqlite # Add the sqlite directory to DIRS.
-endif
-endif
-
-ifndef MOZILLA_CLIENT
-ifeq ($(OS_ARCH),Linux)
-SYSINIT_SRCDIR = sysinit # Add the sysinit directory to DIRS.
-endif
-endif
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
diff --git a/security/nss/lib/base/Makefile b/security/nss/lib/base/Makefile
deleted file mode 100644
index e0db1be1e..000000000
--- a/security/nss/lib/base/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-include manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-export:: private_export
diff --git a/security/nss/lib/base/arena.c b/security/nss/lib/base/arena.c
deleted file mode 100644
index 87ce7c938..000000000
--- a/security/nss/lib/base/arena.c
+++ /dev/null
@@ -1,1218 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * arena.c
- *
- * This contains the implementation of NSS's thread-safe arenas.
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#ifdef ARENA_THREADMARK
-#include "prthread.h"
-#endif /* ARENA_THREADMARK */
-
-#include "prlock.h"
-#include "plarena.h"
-
-#include <string.h>
-
-/*
- * NSSArena
- *
- * This is based on NSPR's arena code, but it is threadsafe.
- *
- * The public methods relating to this type are:
- *
- * NSSArena_Create -- constructor
- * NSSArena_Destroy
- * NSS_ZAlloc
- * NSS_ZRealloc
- * NSS_ZFreeIf
- *
- * The nonpublic methods relating to this type are:
- *
- * nssArena_Create -- constructor
- * nssArena_Destroy
- * nssArena_Mark
- * nssArena_Release
- * nssArena_Unmark
- *
- * nss_ZAlloc
- * nss_ZFreeIf
- * nss_ZRealloc
- *
- * In debug builds, the following calls are available:
- *
- * nssArena_verifyPointer
- * nssArena_registerDestructor
- * nssArena_deregisterDestructor
- */
-
-struct NSSArenaStr {
- PLArenaPool pool;
- PRLock *lock;
-#ifdef ARENA_THREADMARK
- PRThread *marking_thread;
- nssArenaMark *first_mark;
- nssArenaMark *last_mark;
-#endif /* ARENA_THREADMARK */
-#ifdef ARENA_DESTRUCTOR_LIST
- struct arena_destructor_node *first_destructor;
- struct arena_destructor_node *last_destructor;
-#endif /* ARENA_DESTRUCTOR_LIST */
-};
-
-/*
- * nssArenaMark
- *
- * This type is used to mark the current state of an NSSArena.
- */
-
-struct nssArenaMarkStr {
- PRUint32 magic;
- void *mark;
-#ifdef ARENA_THREADMARK
- nssArenaMark *next;
-#endif /* ARENA_THREADMARK */
-#ifdef ARENA_DESTRUCTOR_LIST
- struct arena_destructor_node *next_destructor;
- struct arena_destructor_node *prev_destructor;
-#endif /* ARENA_DESTRUCTOR_LIST */
-};
-
-#define MARK_MAGIC 0x4d41524b /* "MARK" how original */
-
-/*
- * But first, the pointer-tracking code
- */
-#ifdef DEBUG
-extern const NSSError NSS_ERROR_INTERNAL_ERROR;
-
-static nssPointerTracker arena_pointer_tracker;
-
-static PRStatus
-arena_add_pointer
-(
- const NSSArena *arena
-)
-{
- PRStatus rv;
-
- rv = nssPointerTracker_initialize(&arena_pointer_tracker);
- if( PR_SUCCESS != rv ) {
- return rv;
- }
-
- rv = nssPointerTracker_add(&arena_pointer_tracker, arena);
- if( PR_SUCCESS != rv ) {
- NSSError e = NSS_GetError();
- if( NSS_ERROR_NO_MEMORY != e ) {
- nss_SetError(NSS_ERROR_INTERNAL_ERROR);
- }
-
- return rv;
- }
-
- return PR_SUCCESS;
-}
-
-static PRStatus
-arena_remove_pointer
-(
- const NSSArena *arena
-)
-{
- PRStatus rv;
-
- rv = nssPointerTracker_remove(&arena_pointer_tracker, arena);
- if( PR_SUCCESS != rv ) {
- nss_SetError(NSS_ERROR_INTERNAL_ERROR);
- }
-
- return rv;
-}
-
-/*
- * nssArena_verifyPointer
- *
- * This method is only present in debug builds.
- *
- * If the specified pointer is a valid pointer to an NSSArena object,
- * this routine will return PR_SUCCESS. Otherwise, it will put an
- * error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- *
- * Return value:
- * PR_SUCCESS if the pointer is valid
- * PR_FAILURE if it isn't
- */
-
-NSS_IMPLEMENT PRStatus
-nssArena_verifyPointer
-(
- const NSSArena *arena
-)
-{
- PRStatus rv;
-
- rv = nssPointerTracker_initialize(&arena_pointer_tracker);
- if( PR_SUCCESS != rv ) {
- /*
- * This is a little disingenious. We have to initialize the
- * tracker, because someone could "legitimately" try to verify
- * an arena pointer before one is ever created. And this step
- * might fail, due to lack of memory. But the only way that
- * this step can fail is if it's doing the call_once stuff,
- * (later calls just no-op). And if it didn't no-op, there
- * aren't any valid arenas.. so the argument certainly isn't one.
- */
- nss_SetError(NSS_ERROR_INVALID_ARENA);
- return PR_FAILURE;
- }
-
- rv = nssPointerTracker_verify(&arena_pointer_tracker, arena);
- if( PR_SUCCESS != rv ) {
- nss_SetError(NSS_ERROR_INVALID_ARENA);
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-#endif /* DEBUG */
-
-#ifdef ARENA_DESTRUCTOR_LIST
-
-struct arena_destructor_node {
- struct arena_destructor_node *next;
- struct arena_destructor_node *prev;
- void (*destructor)(void *argument);
- void *arg;
-};
-
-/*
- * nssArena_registerDestructor
- *
- * This routine stores a pointer to a callback and an arbitrary
- * pointer-sized argument in the arena, at the current point in
- * the mark stack. If the arena is destroyed, or an "earlier"
- * mark is released, then this destructor will be called at that
- * time. Note that the destructor will be called with the arena
- * locked, which means the destructor may free memory in that
- * arena, but it may not allocate or cause to be allocated any
- * memory. This callback facility was included to support our
- * debug-version pointer-tracker feature; overuse runs counter to
- * the the original intent of arenas. This routine returns a
- * PRStatus value; if successful, it will return PR_SUCCESS. If
- * unsuccessful, it will set an error on the error stack and
- * return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssArena_registerDestructor
-(
- NSSArena *arena,
- void (*destructor)(void *argument),
- void *arg
-)
-{
- struct arena_destructor_node *it;
-
-#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
-#endif /* NSSDEBUG */
-
- it = nss_ZNEW(arena, struct arena_destructor_node);
- if( (struct arena_destructor_node *)NULL == it ) {
- return PR_FAILURE;
- }
-
- it->prev = arena->last_destructor;
- arena->last_destructor->next = it;
- arena->last_destructor = it;
- it->destructor = destructor;
- it->arg = arg;
-
- if( (nssArenaMark *)NULL != arena->last_mark ) {
- arena->last_mark->prev_destructor = it->prev;
- arena->last_mark->next_destructor = it->next;
- }
-
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssArena_deregisterDestructor
-(
- NSSArena *arena,
- void (*destructor)(void *argument),
- void *arg
-)
-{
- struct arena_destructor_node *it;
-
-#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
-#endif /* NSSDEBUG */
-
- for( it = arena->first_destructor; it; it = it->next ) {
- if( (it->destructor == destructor) && (it->arg == arg) ) {
- break;
- }
- }
-
- if( (struct arena_destructor_node *)NULL == it ) {
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
- }
-
- if( it == arena->first_destructor ) {
- arena->first_destructor = it->next;
- }
-
- if( it == arena->last_destructor ) {
- arena->last_destructor = it->prev;
- }
-
- if( (struct arena_destructor_node *)NULL != it->prev ) {
- it->prev->next = it->next;
- }
-
- if( (struct arena_destructor_node *)NULL != it->next ) {
- it->next->prev = it->prev;
- }
-
- {
- nssArenaMark *m;
- for( m = arena->first_mark; m; m = m->next ) {
- if( m->next_destructor == it ) {
- m->next_destructor = it->next;
- }
- if( m->prev_destructor == it ) {
- m->prev_destructor = it->prev;
- }
- }
- }
-
- nss_ZFreeIf(it);
- return PR_SUCCESS;
-}
-
-static void
-nss_arena_call_destructor_chain
-(
- struct arena_destructor_node *it
-)
-{
- for( ; it ; it = it->next ) {
- (*(it->destructor))(it->arg);
- }
-}
-
-#endif /* ARENA_DESTRUCTOR_LIST */
-
-/*
- * NSSArena_Create
- *
- * This routine creates a new memory arena. This routine may return
- * NULL upon error, in which case it will have created an error stack.
- *
- * The top-level error may be one of the following values:
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * NULL upon error
- * A pointer to an NSSArena upon success
- */
-
-NSS_IMPLEMENT NSSArena *
-NSSArena_Create
-(
- void
-)
-{
- nss_ClearErrorStack();
- return nssArena_Create();
-}
-
-/*
- * nssArena_Create
- *
- * This routine creates a new memory arena. This routine may return
- * NULL upon error, in which case it will have set an error on the
- * error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * NULL upon error
- * A pointer to an NSSArena upon success
- */
-
-NSS_IMPLEMENT NSSArena *
-nssArena_Create
-(
- void
-)
-{
- NSSArena *rv = (NSSArena *)NULL;
-
- rv = nss_ZNEW((NSSArena *)NULL, NSSArena);
- if( (NSSArena *)NULL == rv ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (NSSArena *)NULL;
- }
-
- rv->lock = PR_NewLock();
- if( (PRLock *)NULL == rv->lock ) {
- (void)nss_ZFreeIf(rv);
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (NSSArena *)NULL;
- }
-
- /*
- * Arena sizes. The current security code has 229 occurrences of
- * PORT_NewArena. The default chunksizes specified break down as
- *
- * Size Mult. Specified as
- * 512 1 512
- * 1024 7 1024
- * 2048 5 2048
- * 2048 5 CRMF_DEFAULT_ARENA_SIZE
- * 2048 190 DER_DEFAULT_CHUNKSIZE
- * 2048 20 SEC_ASN1_DEFAULT_ARENA_SIZE
- * 4096 1 4096
- *
- * Obviously this "default chunksize" flexibility isn't very
- * useful to us, so I'll just pick 2048.
- */
-
- PL_InitArenaPool(&rv->pool, "NSS", 2048, sizeof(double));
-
-#ifdef DEBUG
- {
- PRStatus st;
- st = arena_add_pointer(rv);
- if( PR_SUCCESS != st ) {
- PL_FinishArenaPool(&rv->pool);
- PR_DestroyLock(rv->lock);
- (void)nss_ZFreeIf(rv);
- return (NSSArena *)NULL;
- }
- }
-#endif /* DEBUG */
-
- return rv;
-}
-
-/*
- * NSSArena_Destroy
- *
- * This routine will destroy the specified arena, freeing all memory
- * allocated from it. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCESS. If unsuccessful, it will
- * create an error stack and return PR_FAILURE.
- *
- * The top-level error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- *
- * Return value:
- * PR_SUCCESS upon success
- * PR_FAILURE upon failure
- */
-
-NSS_IMPLEMENT PRStatus
-NSSArena_Destroy
-(
- NSSArena *arena
-)
-{
- nss_ClearErrorStack();
-
-#ifdef DEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
-#endif /* DEBUG */
-
- return nssArena_Destroy(arena);
-}
-
-/*
- * nssArena_Destroy
- *
- * This routine will destroy the specified arena, freeing all memory
- * allocated from it. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCESS. If unsuccessful, it will
- * set an error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssArena_Destroy
-(
- NSSArena *arena
-)
-{
- PRLock *lock;
-
-#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
-#endif /* NSSDEBUG */
-
- if( (PRLock *)NULL == arena->lock ) {
- /* Just got destroyed */
- nss_SetError(NSS_ERROR_INVALID_ARENA);
- return PR_FAILURE;
- }
- PR_Lock(arena->lock);
-
-#ifdef DEBUG
- if( PR_SUCCESS != arena_remove_pointer(arena) ) {
- PR_Unlock(arena->lock);
- return PR_FAILURE;
- }
-#endif /* DEBUG */
-
-#ifdef ARENA_DESTRUCTOR_LIST
- /* Note that the arena is locked at this time */
- nss_arena_call_destructor_chain(arena->first_destructor);
-#endif /* ARENA_DESTRUCTOR_LIST */
-
- PL_FinishArenaPool(&arena->pool);
- lock = arena->lock;
- arena->lock = (PRLock *)NULL;
- PR_Unlock(lock);
- PR_DestroyLock(lock);
- (void)nss_ZFreeIf(arena);
- return PR_SUCCESS;
-}
-
-static void *nss_zalloc_arena_locked(NSSArena *arena, PRUint32 size);
-
-/*
- * nssArena_Mark
- *
- * This routine "marks" the current state of an arena. Space
- * allocated after the arena has been marked can be freed by
- * releasing the arena back to the mark with nssArena_Release,
- * or committed by calling nssArena_Unmark. When successful,
- * this routine returns a valid nssArenaMark pointer. This
- * routine may return NULL upon error, in which case it will
- * have set an error on the error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon failure
- * An nssArenaMark pointer upon success
- */
-
-NSS_IMPLEMENT nssArenaMark *
-nssArena_Mark
-(
- NSSArena *arena
-)
-{
- nssArenaMark *rv;
- void *p;
-
-#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return (nssArenaMark *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if( (PRLock *)NULL == arena->lock ) {
- /* Just got destroyed */
- nss_SetError(NSS_ERROR_INVALID_ARENA);
- return (nssArenaMark *)NULL;
- }
- PR_Lock(arena->lock);
-
-#ifdef ARENA_THREADMARK
- if( (PRThread *)NULL == arena->marking_thread ) {
- /* Unmarked. Store our thread ID */
- arena->marking_thread = PR_GetCurrentThread();
- /* This call never fails. */
- } else {
- /* Marked. Verify it's the current thread */
- if( PR_GetCurrentThread() != arena->marking_thread ) {
- PR_Unlock(arena->lock);
- nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
- return (nssArenaMark *)NULL;
- }
- }
-#endif /* ARENA_THREADMARK */
-
- p = PL_ARENA_MARK(&arena->pool);
- /* No error possible */
-
- /* Do this after the mark */
- rv = (nssArenaMark *)nss_zalloc_arena_locked(arena, sizeof(nssArenaMark));
- if( (nssArenaMark *)NULL == rv ) {
- PR_Unlock(arena->lock);
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (nssArenaMark *)NULL;
- }
-
-#ifdef ARENA_THREADMARK
- if ( (nssArenaMark *)NULL == arena->first_mark) {
- arena->first_mark = rv;
- arena->last_mark = rv;
- } else {
- arena->last_mark->next = rv;
- arena->last_mark = rv;
- }
-#endif /* ARENA_THREADMARK */
-
- rv->mark = p;
- rv->magic = MARK_MAGIC;
-
-#ifdef ARENA_DESTRUCTOR_LIST
- rv->prev_destructor = arena->last_destructor;
-#endif /* ARENA_DESTRUCTOR_LIST */
-
- PR_Unlock(arena->lock);
-
- return rv;
-}
-
-/*
- * nss_arena_unmark_release
- *
- * This static routine implements the routines nssArena_Release
- * ans nssArena_Unmark, which are almost identical.
- */
-
-static PRStatus
-nss_arena_unmark_release
-(
- NSSArena *arena,
- nssArenaMark *arenaMark,
- PRBool release
-)
-{
- void *inner_mark;
-
-#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return PR_FAILURE;
- }
-#endif /* NSSDEBUG */
-
- if( MARK_MAGIC != arenaMark->magic ) {
- nss_SetError(NSS_ERROR_INVALID_ARENA_MARK);
- return PR_FAILURE;
- }
-
- if( (PRLock *)NULL == arena->lock ) {
- /* Just got destroyed */
- nss_SetError(NSS_ERROR_INVALID_ARENA);
- return PR_FAILURE;
- }
- PR_Lock(arena->lock);
-
-#ifdef ARENA_THREADMARK
- if( (PRThread *)NULL != arena->marking_thread ) {
- if( PR_GetCurrentThread() != arena->marking_thread ) {
- PR_Unlock(arena->lock);
- nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
- return PR_FAILURE;
- }
- }
-#endif /* ARENA_THREADMARK */
-
- if( MARK_MAGIC != arenaMark->magic ) {
- /* Just got released */
- PR_Unlock(arena->lock);
- nss_SetError(NSS_ERROR_INVALID_ARENA_MARK);
- return PR_FAILURE;
- }
-
- arenaMark->magic = 0;
- inner_mark = arenaMark->mark;
-
-#ifdef ARENA_THREADMARK
- {
- nssArenaMark **pMark = &arena->first_mark;
- nssArenaMark *rest;
- nssArenaMark *last = (nssArenaMark *)NULL;
-
- /* Find this mark */
- while( *pMark != arenaMark ) {
- last = *pMark;
- pMark = &(*pMark)->next;
- }
-
- /* Remember the pointer, then zero it */
- rest = (*pMark)->next;
- *pMark = (nssArenaMark *)NULL;
-
- arena->last_mark = last;
-
- /* Invalidate any later marks being implicitly released */
- for( ; (nssArenaMark *)NULL != rest; rest = rest->next ) {
- rest->magic = 0;
- }
-
- /* If we just got rid of the first mark, clear the thread ID */
- if( (nssArenaMark *)NULL == arena->first_mark ) {
- arena->marking_thread = (PRThread *)NULL;
- }
- }
-#endif /* ARENA_THREADMARK */
-
- if( release ) {
-#ifdef ARENA_DESTRUCTOR_LIST
- if( (struct arena_destructor_node *)NULL != arenaMark->prev_destructor ) {
- arenaMark->prev_destructor->next = (struct arena_destructor_node *)NULL;
- }
- arena->last_destructor = arenaMark->prev_destructor;
-
- /* Note that the arena is locked at this time */
- nss_arena_call_destructor_chain(arenaMark->next_destructor);
-#endif /* ARENA_DESTRUCTOR_LIST */
-
- PR_ARENA_RELEASE(&arena->pool, inner_mark);
- /* No error return */
- }
-
- PR_Unlock(arena->lock);
- return PR_SUCCESS;
-}
-
-/*
- * nssArena_Release
- *
- * This routine invalidates and releases all memory allocated from
- * the specified arena after the point at which the specified mark
- * was obtained. This routine returns a PRStatus value; if successful,
- * it will return PR_SUCCESS. If unsuccessful, it will set an error
- * on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_INVALID_ARENA_MARK
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssArena_Release
-(
- NSSArena *arena,
- nssArenaMark *arenaMark
-)
-{
- return nss_arena_unmark_release(arena, arenaMark, PR_TRUE);
-}
-
-/*
- * nssArena_Unmark
- *
- * This routine "commits" the indicated mark and any marks after
- * it, making them unreleasable. Note that any earlier marks can
- * still be released, and such a release will invalidate these
- * later unmarked regions. If an arena is to be safely shared by
- * more than one thread, all marks must be either released or
- * unmarked. This routine returns a PRStatus value; if successful,
- * it will return PR_SUCCESS. If unsuccessful, it will set an error
- * on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_INVALID_ARENA_MARK
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssArena_Unmark
-(
- NSSArena *arena,
- nssArenaMark *arenaMark
-)
-{
- return nss_arena_unmark_release(arena, arenaMark, PR_FALSE);
-}
-
-/*
- * We prefix this header to all allocated blocks. It is a multiple
- * of the alignment size. Note that this usage of a header may make
- * purify spew bogus warnings about "potentially leaked blocks" of
- * memory; if that gets too annoying we can add in a pointer to the
- * header in the header itself. There's not a lot of safety here;
- * maybe we should add a magic value?
- */
-struct pointer_header {
- NSSArena *arena;
- PRUint32 size;
-};
-
-static void *
-nss_zalloc_arena_locked
-(
- NSSArena *arena,
- PRUint32 size
-)
-{
- void *p;
- void *rv;
- struct pointer_header *h;
- PRUint32 my_size = size + sizeof(struct pointer_header);
- PR_ARENA_ALLOCATE(p, &arena->pool, my_size);
- if( (void *)NULL == p ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (void *)NULL;
- }
- /*
- * Do this before we unlock. This way if the user is using
- * an arena in one thread while destroying it in another, he'll
- * fault/FMR in his code, not ours.
- */
- h = (struct pointer_header *)p;
- h->arena = arena;
- h->size = size;
- rv = (void *)((char *)h + sizeof(struct pointer_header));
- (void)nsslibc_memset(rv, 0, size);
- return rv;
-}
-
-/*
- * NSS_ZAlloc
- *
- * This routine allocates and zeroes a section of memory of the
- * size, and returns to the caller a pointer to that memory. If
- * the optional arena argument is non-null, the memory will be
- * obtained from that arena; otherwise, the memory will be obtained
- * from the heap. This routine may return NULL upon error, in
- * which case it will have set an error upon the error stack. The
- * value specified for size may be zero; in which case a valid
- * zero-length block of memory will be allocated. This block may
- * be expanded by calling NSS_ZRealloc.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon error
- * A pointer to the new segment of zeroed memory
- */
-
-NSS_IMPLEMENT void *
-NSS_ZAlloc
-(
- NSSArena *arenaOpt,
- PRUint32 size
-)
-{
- return nss_ZAlloc(arenaOpt, size);
-}
-
-/*
- * nss_ZAlloc
- *
- * This routine allocates and zeroes a section of memory of the
- * size, and returns to the caller a pointer to that memory. If
- * the optional arena argument is non-null, the memory will be
- * obtained from that arena; otherwise, the memory will be obtained
- * from the heap. This routine may return NULL upon error, in
- * which case it will have set an error upon the error stack. The
- * value specified for size may be zero; in which case a valid
- * zero-length block of memory will be allocated. This block may
- * be expanded by calling nss_ZRealloc.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon error
- * A pointer to the new segment of zeroed memory
- */
-
-NSS_IMPLEMENT void *
-nss_ZAlloc
-(
- NSSArena *arenaOpt,
- PRUint32 size
-)
-{
- struct pointer_header *h;
- PRUint32 my_size = size + sizeof(struct pointer_header);
-
- if( my_size < sizeof(struct pointer_header) ) {
- /* Wrapped */
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (void *)NULL;
- }
-
- if( (NSSArena *)NULL == arenaOpt ) {
- /* Heap allocation, no locking required. */
- h = (struct pointer_header *)PR_Calloc(1, my_size);
- if( (struct pointer_header *)NULL == h ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (void *)NULL;
- }
-
- h->arena = (NSSArena *)NULL;
- h->size = size;
- /* We used calloc: it's already zeroed */
-
- return (void *)((char *)h + sizeof(struct pointer_header));
- } else {
- void *rv;
- /* Arena allocation */
-#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (void *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if( (PRLock *)NULL == arenaOpt->lock ) {
- /* Just got destroyed */
- nss_SetError(NSS_ERROR_INVALID_ARENA);
- return (void *)NULL;
- }
- PR_Lock(arenaOpt->lock);
-
-#ifdef ARENA_THREADMARK
- if( (PRThread *)NULL != arenaOpt->marking_thread ) {
- if( PR_GetCurrentThread() != arenaOpt->marking_thread ) {
- nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
- PR_Unlock(arenaOpt->lock);
- return (void *)NULL;
- }
- }
-#endif /* ARENA_THREADMARK */
-
- rv = nss_zalloc_arena_locked(arenaOpt, size);
-
- PR_Unlock(arenaOpt->lock);
- return rv;
- }
- /*NOTREACHED*/
-}
-
-/*
- * NSS_ZFreeIf
- *
- * If the specified pointer is non-null, then the region of memory
- * to which it points -- which must have been allocated with
- * NSS_ZAlloc -- will be zeroed and released. This routine
- * returns a PRStatus value; if successful, it will return PR_SUCCESS.
- * If unsuccessful, it will set an error on the error stack and return
- * PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-NSS_IMPLEMENT PRStatus
-NSS_ZFreeIf
-(
- void *pointer
-)
-{
- return nss_ZFreeIf(pointer);
-}
-
-/*
- * nss_ZFreeIf
- *
- * If the specified pointer is non-null, then the region of memory
- * to which it points -- which must have been allocated with
- * nss_ZAlloc -- will be zeroed and released. This routine
- * returns a PRStatus value; if successful, it will return PR_SUCCESS.
- * If unsuccessful, it will set an error on the error stack and return
- * PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nss_ZFreeIf
-(
- void *pointer
-)
-{
- struct pointer_header *h;
-
- if( (void *)NULL == pointer ) {
- return PR_SUCCESS;
- }
-
- h = (struct pointer_header *)((char *)pointer
- - sizeof(struct pointer_header));
-
- /* Check any magic here */
-
- if( (NSSArena *)NULL == h->arena ) {
- /* Heap */
- (void)nsslibc_memset(pointer, 0, h->size);
- PR_Free(h);
- return PR_SUCCESS;
- } else {
- /* Arena */
-#ifdef NSSDEBUG
- if( PR_SUCCESS != nssArena_verifyPointer(h->arena) ) {
- return PR_FAILURE;
- }
-#endif /* NSSDEBUG */
-
- if( (PRLock *)NULL == h->arena->lock ) {
- /* Just got destroyed.. so this pointer is invalid */
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
- PR_Lock(h->arena->lock);
-
- (void)nsslibc_memset(pointer, 0, h->size);
-
- /* No way to "free" it within an NSPR arena. */
-
- PR_Unlock(h->arena->lock);
- return PR_SUCCESS;
- }
- /*NOTREACHED*/
-}
-
-/*
- * NSS_ZRealloc
- *
- * This routine reallocates a block of memory obtained by calling
- * nss_ZAlloc or nss_ZRealloc. The portion of memory
- * between the new and old sizes -- which is either being newly
- * obtained or released -- is in either case zeroed. This routine
- * may return NULL upon failure, in which case it will have placed
- * an error on the error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon error
- * A pointer to the replacement segment of memory
- */
-
-NSS_EXTERN void *
-NSS_ZRealloc
-(
- void *pointer,
- PRUint32 newSize
-)
-{
- return nss_ZRealloc(pointer, newSize);
-}
-
-/*
- * nss_ZRealloc
- *
- * This routine reallocates a block of memory obtained by calling
- * nss_ZAlloc or nss_ZRealloc. The portion of memory
- * between the new and old sizes -- which is either being newly
- * obtained or released -- is in either case zeroed. This routine
- * may return NULL upon failure, in which case it will have placed
- * an error on the error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon error
- * A pointer to the replacement segment of memory
- */
-
-NSS_EXTERN void *
-nss_ZRealloc
-(
- void *pointer,
- PRUint32 newSize
-)
-{
- NSSArena *arena;
- struct pointer_header *h, *new_h;
- PRUint32 my_newSize = newSize + sizeof(struct pointer_header);
- void *rv;
-
- if( my_newSize < sizeof(struct pointer_header) ) {
- /* Wrapped */
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (void *)NULL;
- }
-
- if( (void *)NULL == pointer ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (void *)NULL;
- }
-
- h = (struct pointer_header *)((char *)pointer
- - sizeof(struct pointer_header));
-
- /* Check any magic here */
-
- if( newSize == h->size ) {
- /* saves thrashing */
- return pointer;
- }
-
- arena = h->arena;
- if (!arena) {
- /* Heap */
- new_h = (struct pointer_header *)PR_Calloc(1, my_newSize);
- if( (struct pointer_header *)NULL == new_h ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (void *)NULL;
- }
-
- new_h->arena = (NSSArena *)NULL;
- new_h->size = newSize;
- rv = (void *)((char *)new_h + sizeof(struct pointer_header));
-
- if( newSize > h->size ) {
- (void)nsslibc_memcpy(rv, pointer, h->size);
- (void)nsslibc_memset(&((char *)rv)[ h->size ],
- 0, (newSize - h->size));
- } else {
- (void)nsslibc_memcpy(rv, pointer, newSize);
- }
-
- (void)nsslibc_memset(pointer, 0, h->size);
- h->size = 0;
- PR_Free(h);
-
- return rv;
- } else {
- void *p;
- /* Arena */
-#ifdef NSSDEBUG
- if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
- return (void *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if (!arena->lock) {
- /* Just got destroyed.. so this pointer is invalid */
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (void *)NULL;
- }
- PR_Lock(arena->lock);
-
-#ifdef ARENA_THREADMARK
- if (arena->marking_thread) {
- if (PR_GetCurrentThread() != arena->marking_thread) {
- PR_Unlock(arena->lock);
- nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
- return (void *)NULL;
- }
- }
-#endif /* ARENA_THREADMARK */
-
- if( newSize < h->size ) {
- /*
- * We have no general way of returning memory to the arena
- * (mark/release doesn't work because things may have been
- * allocated after this object), so the memory is gone
- * anyway. We might as well just return the same pointer to
- * the user, saying "yeah, uh-hunh, you can only use less of
- * it now." We'll zero the leftover part, of course. And
- * in fact we might as well *not* adjust h->size-- this way,
- * if the user reallocs back up to something not greater than
- * the original size, then voila, there's the memory! This
- * way a thrash big/small/big/small doesn't burn up the arena.
- */
- char *extra = &((char *)pointer)[ newSize ];
- (void)nsslibc_memset(extra, 0, (h->size - newSize));
- PR_Unlock(arena->lock);
- return pointer;
- }
-
- PR_ARENA_ALLOCATE(p, &arena->pool, my_newSize);
- if( (void *)NULL == p ) {
- PR_Unlock(arena->lock);
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (void *)NULL;
- }
-
- new_h = (struct pointer_header *)p;
- new_h->arena = arena;
- new_h->size = newSize;
- rv = (void *)((char *)new_h + sizeof(struct pointer_header));
- if (rv != pointer) {
- (void)nsslibc_memcpy(rv, pointer, h->size);
- (void)nsslibc_memset(pointer, 0, h->size);
- }
- (void)nsslibc_memset(&((char *)rv)[ h->size ], 0, (newSize - h->size));
- h->arena = (NSSArena *)NULL;
- h->size = 0;
- PR_Unlock(arena->lock);
- return rv;
- }
- /*NOTREACHED*/
-}
-
-PRStatus
-nssArena_Shutdown(void)
-{
- PRStatus rv = PR_SUCCESS;
-#ifdef DEBUG
- rv = nssPointerTracker_finalize(&arena_pointer_tracker);
-#endif
- return rv;
-}
diff --git a/security/nss/lib/base/base.h b/security/nss/lib/base/base.h
deleted file mode 100644
index a729b6048..000000000
--- a/security/nss/lib/base/base.h
+++ /dev/null
@@ -1,1398 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef BASE_H
-#define BASE_H
-
-#ifdef DEBUG
-static const char BASE_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * base.h
- *
- * This header file contains basic prototypes and preprocessor
- * definitions used throughout nss but not available publicly.
- */
-
-#ifndef BASET_H
-#include "baset.h"
-#endif /* BASET_H */
-
-#ifndef NSSBASE_H
-#include "nssbase.h"
-#endif /* NSSBASE_H */
-
-#include "plhash.h"
-
-PR_BEGIN_EXTERN_C
-
-/*
- * NSSArena
- *
- * The nonpublic methods relating to this type are:
- *
- * nssArena_Create -- constructor
- * nssArena_Destroy
- * nssArena_Mark
- * nssArena_Release
- * nssArena_Unmark
- *
- * nss_ZAlloc
- * nss_ZFreeIf
- * nss_ZRealloc
- *
- * Additionally, there are some preprocessor macros:
- *
- * nss_ZNEW
- * nss_ZNEWARRAY
- *
- * In debug builds, the following calls are available:
- *
- * nssArena_verifyPointer
- * nssArena_registerDestructor
- * nssArena_deregisterDestructor
- *
- * The following preprocessor macro is also always available:
- *
- * nssArena_VERIFYPOINTER
- *
- * A constant PLHashAllocOps structure is available for users
- * of the NSPL PLHashTable routines.
- *
- * nssArenaHashAllocOps
- */
-
-/*
- * nssArena_Create
- *
- * This routine creates a new memory arena. This routine may return
- * NULL upon error, in which case it will have set an error on the
- * error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * NULL upon error
- * A pointer to an NSSArena upon success
- */
-
-/*
- * XXX fgmr
- * Arenas can be named upon creation; this is mostly of use when
- * debugging. Should we expose that here, allowing an optional
- * "const char *name" argument? Should the public version of this
- * call (NSSArena_Create) have it too?
- */
-
-NSS_EXTERN NSSArena *
-nssArena_Create
-(
- void
-);
-
-extern const NSSError NSS_ERROR_NO_MEMORY;
-
-/*
- * nssArena_Destroy
- *
- * This routine will destroy the specified arena, freeing all memory
- * allocated from it. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCESS. If unsuccessful, it will
- * set an error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_EXTERN PRStatus
-nssArena_Destroy
-(
- NSSArena *arena
-);
-
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-
-/*
- * nssArena_Mark
- *
- * This routine "marks" the current state of an arena. Space
- * allocated after the arena has been marked can be freed by
- * releasing the arena back to the mark with nssArena_Release,
- * or committed by calling nssArena_Unmark. When successful,
- * this routine returns a valid nssArenaMark pointer. This
- * routine may return NULL upon error, in which case it will
- * have set an error on the error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon failure
- * An nssArenaMark pointer upon success
- */
-
-NSS_EXTERN nssArenaMark *
-nssArena_Mark
-(
- NSSArena *arena
-);
-
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-extern const NSSError NSS_ERROR_NO_MEMORY;
-extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
-
-/*
- * nssArena_Release
- *
- * This routine invalidates and releases all memory allocated from
- * the specified arena after the point at which the specified mark
- * was obtained. This routine returns a PRStatus value; if successful,
- * it will return PR_SUCCESS. If unsuccessful, it will set an error
- * on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_INVALID_ARENA_MARK
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_EXTERN PRStatus
-nssArena_Release
-(
- NSSArena *arena,
- nssArenaMark *arenaMark
-);
-
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
-
-/*
- * nssArena_Unmark
- *
- * This routine "commits" the indicated mark and any marks after
- * it, making them unreleasable. Note that any earlier marks can
- * still be released, and such a release will invalidate these
- * later unmarked regions. If an arena is to be safely shared by
- * more than one thread, all marks must be either released or
- * unmarked. This routine returns a PRStatus value; if successful,
- * it will return PR_SUCCESS. If unsuccessful, it will set an error
- * on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_INVALID_ARENA_MARK
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_EXTERN PRStatus
-nssArena_Unmark
-(
- NSSArena *arena,
- nssArenaMark *arenaMark
-);
-
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
-extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
-
-#ifdef ARENA_DESTRUCTOR_LIST
-
-/*
- * nssArena_registerDestructor
- *
- * This routine stores a pointer to a callback and an arbitrary
- * pointer-sized argument in the arena, at the current point in
- * the mark stack. If the arena is destroyed, or an "earlier"
- * mark is released, then this destructor will be called at that
- * time. Note that the destructor will be called with the arena
- * locked, which means the destructor may free memory in that
- * arena, but it may not allocate or cause to be allocated any
- * memory. This callback facility was included to support our
- * debug-version pointer-tracker feature; overuse runs counter to
- * the the original intent of arenas. This routine returns a
- * PRStatus value; if successful, it will return PR_SUCCESS. If
- * unsuccessful, it will set an error on the error stack and
- * return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_EXTERN PRStatus
-nssArena_registerDestructor
-(
- NSSArena *arena,
- void (*destructor)(void *argument),
- void *arg
-);
-
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-extern const NSSError NSS_ERROR_NO_MEMORY;
-
-/*
- * nssArena_deregisterDestructor
- *
- * This routine will remove the first destructor in the specified
- * arena which has the specified destructor and argument values.
- * The destructor will not be called. This routine returns a
- * PRStatus value; if successful, it will return PR_SUCCESS. If
- * unsuccessful, it will set an error on the error stack and
- * return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NOT_FOUND
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_EXTERN PRStatus
-nssArena_deregisterDestructor
-(
- NSSArena *arena,
- void (*destructor)(void *argument),
- void *arg
-);
-
-extern const NSSError NSS_ERROR_INVALID_ITEM;
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-extern const NSSError NSS_ERROR_NOT_FOUND;
-
-#endif /* ARENA_DESTRUCTOR_LIST */
-
-/*
- * nss_ZAlloc
- *
- * This routine allocates and zeroes a section of memory of the
- * size, and returns to the caller a pointer to that memory. If
- * the optional arena argument is non-null, the memory will be
- * obtained from that arena; otherwise, the memory will be obtained
- * from the heap. This routine may return NULL upon error, in
- * which case it will have set an error upon the error stack. The
- * value specified for size may be zero; in which case a valid
- * zero-length block of memory will be allocated. This block may
- * be expanded by calling nss_ZRealloc.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon error
- * A pointer to the new segment of zeroed memory
- */
-
-NSS_EXTERN void *
-nss_ZAlloc
-(
- NSSArena *arenaOpt,
- PRUint32 size
-);
-
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-extern const NSSError NSS_ERROR_NO_MEMORY;
-extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
-
-/*
- * nss_ZFreeIf
- *
- * If the specified pointer is non-null, then the region of memory
- * to which it points -- which must have been allocated with
- * nss_ZAlloc -- will be zeroed and released. This routine
- * returns a PRStatus value; if successful, it will return PR_SUCCESS.
- * If unsuccessful, it will set an error on the error stack and return
- * PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_EXTERN PRStatus
-nss_ZFreeIf
-(
- void *pointer
-);
-
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-
-/*
- * nss_ZRealloc
- *
- * This routine reallocates a block of memory obtained by calling
- * nss_ZAlloc or nss_ZRealloc. The portion of memory
- * between the new and old sizes -- which is either being newly
- * obtained or released -- is in either case zeroed. This routine
- * may return NULL upon failure, in which case it will have placed
- * an error on the error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon error
- * A pointer to the replacement segment of memory
- */
-
-NSS_EXTERN void *
-nss_ZRealloc
-(
- void *pointer,
- PRUint32 newSize
-);
-
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-extern const NSSError NSS_ERROR_NO_MEMORY;
-extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
-
-/*
- * nss_ZNEW
- *
- * This preprocessor macro will allocate memory for a new object
- * of the specified type with nss_ZAlloc, and will cast the
- * return value appropriately. If the optional arena argument is
- * non-null, the memory will be obtained from that arena; otherwise,
- * the memory will be obtained from the heap. This routine may
- * return NULL upon error, in which case it will have set an error
- * upon the error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * NULL upon error
- * A pointer to the new segment of zeroed memory
- */
-
-/* The following line exceeds 72 characters, but emacs screws up if I split it. */
-#define nss_ZNEW(arenaOpt, type) ((type *)nss_ZAlloc((arenaOpt), sizeof(type)))
-
-/*
- * nss_ZNEWARRAY
- *
- * This preprocessor macro will allocate memory for an array of
- * new objects, and will cast the return value appropriately.
- * If the optional arena argument is non-null, the memory will
- * be obtained from that arena; otherwise, the memory will be
- * obtained from the heap. This routine may return NULL upon
- * error, in which case it will have set an error upon the error
- * stack. The array size may be specified as zero.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * NULL upon error
- * A pointer to the new segment of zeroed memory
- */
-
-/* The following line exceeds 72 characters, but emacs screws up if I split it. */
-#define nss_ZNEWARRAY(arenaOpt, type, quantity) ((type *)nss_ZAlloc((arenaOpt), sizeof(type) * (quantity)))
-
-/*
- * nss_ZREALLOCARRAY
- *
- * This preprocessor macro will reallocate memory for an array of
- * new objects, and will cast the return value appropriately.
- * This routine may return NULL upon error, in which case it will
- * have set an error upon the error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon error
- * A pointer to the replacement segment of memory
- */
-#define nss_ZREALLOCARRAY(p, type, quantity) ((type *)nss_ZRealloc((p), sizeof(type) * (quantity)))
-
-/*
- * nssArena_verifyPointer
- *
- * This method is only present in debug builds.
- *
- * If the specified pointer is a valid pointer to an NSSArena object,
- * this routine will return PR_SUCCESS. Otherwise, it will put an
- * error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- *
- * Return value:
- * PR_SUCCESS if the pointer is valid
- * PR_FAILURE if it isn't
- */
-
-#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssArena_verifyPointer
-(
- const NSSArena *arena
-);
-
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-#endif /* DEBUG */
-
-/*
- * nssArena_VERIFYPOINTER
- *
- * This macro is always available. In debug builds it will call
- * nssArena_verifyPointer; in non-debug builds, it will merely
- * check that the pointer is not null. Note that in non-debug
- * builds it cannot place an error on the error stack.
- *
- * Return value:
- * PR_SUCCESS if the pointer is valid
- * PR_FAILURE if it isn't
- */
-
-#ifdef DEBUG
-#define nssArena_VERIFYPOINTER(p) nssArena_verifyPointer(p)
-#else /* DEBUG */
-/* The following line exceeds 72 characters, but emacs screws up if I split it. */
-#define nssArena_VERIFYPOINTER(p) (((NSSArena *)NULL == (p))?PR_FAILURE:PR_SUCCESS)
-#endif /* DEBUG */
-
-/*
- * Private function to be called by NSS_Shutdown to cleanup nssArena
- * bookkeeping.
- */
-extern PRStatus
-nssArena_Shutdown(void);
-
-/*
- * nssArenaHashAllocOps
- *
- * This constant structure contains allocation callbacks designed for
- * use with the NSPL routine PL_NewHashTable. For example:
- *
- * NSSArena *hashTableArena = nssArena_Create();
- * PLHashTable *t = PL_NewHashTable(n, hasher, key_compare,
- * value_compare, nssArenaHashAllocOps, hashTableArena);
- */
-
-NSS_EXTERN_DATA PLHashAllocOps nssArenaHashAllocOps;
-
-/*
- * The error stack
- *
- * The nonpublic methods relating to the error stack are:
- *
- * nss_SetError
- * nss_ClearErrorStack
- */
-
-/*
- * nss_SetError
- *
- * This routine places a new error code on the top of the calling
- * thread's error stack. Calling this routine wiht an error code
- * of zero will clear the error stack.
- */
-
-NSS_EXTERN void
-nss_SetError
-(
- PRUint32 error
-);
-
-/*
- * nss_ClearErrorStack
- *
- * This routine clears the calling thread's error stack.
- */
-
-NSS_EXTERN void
-nss_ClearErrorStack
-(
- void
-);
-
-/*
- * nss_DestroyErrorStack
- *
- * This routine frees the calling thread's error stack.
- */
-
-NSS_EXTERN void
-nss_DestroyErrorStack
-(
- void
-);
-
-/*
- * NSSItem
- *
- * nssItem_Create
- * nssItem_Duplicate
- * nssItem_Equal
- */
-
-NSS_EXTERN NSSItem *
-nssItem_Create
-(
- NSSArena *arenaOpt,
- NSSItem *rvOpt,
- PRUint32 length,
- const void *data
-);
-
-NSS_EXTERN void
-nssItem_Destroy
-(
- NSSItem *item
-);
-
-NSS_EXTERN NSSItem *
-nssItem_Duplicate
-(
- NSSItem *obj,
- NSSArena *arenaOpt,
- NSSItem *rvOpt
-);
-
-NSS_EXTERN PRBool
-nssItem_Equal
-(
- const NSSItem *one,
- const NSSItem *two,
- PRStatus *statusOpt
-);
-
-/*
- * NSSUTF8
- *
- * nssUTF8_CaseIgnoreMatch
- * nssUTF8_Duplicate
- * nssUTF8_Size
- * nssUTF8_Length
- * nssUTF8_CopyIntoFixedBuffer
- */
-
-/*
- * nssUTF8_CaseIgnoreMatch
- *
- * Returns true if the two UTF8-encoded strings pointed to by the
- * two specified NSSUTF8 pointers differ only in typcase.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_TRUE if the strings match, ignoring case
- * PR_FALSE if they don't
- * PR_FALSE upon error
- */
-
-NSS_EXTERN PRBool
-nssUTF8_CaseIgnoreMatch
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-);
-
-/*
- * nssUTF8_Duplicate
- *
- * This routine duplicates the UTF8-encoded string pointed to by the
- * specified NSSUTF8 pointer. If the optional arenaOpt argument is
- * not null, the memory required will be obtained from that arena;
- * otherwise, the memory required will be obtained from the heap.
- * A pointer to the new string will be returned. In case of error,
- * an error will be placed on the error stack and NULL will be
- * returned.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- */
-
-NSS_EXTERN NSSUTF8 *
-nssUTF8_Duplicate
-(
- const NSSUTF8 *s,
- NSSArena *arenaOpt
-);
-
-/*
- * nssUTF8_PrintableMatch
- *
- * Returns true if the two Printable strings pointed to by the
- * two specified NSSUTF8 pointers match when compared with the
- * rules for Printable String (leading and trailing spaces are
- * disregarded, extents of whitespace match irregardless of length,
- * and case is not significant), then PR_TRUE will be returned.
- * Otherwise, PR_FALSE will be returned. Upon failure, PR_FALSE
- * will be returned. If the optional statusOpt argument is not
- * NULL, then PR_SUCCESS or PR_FAILURE will be stored in that
- * location.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_TRUE if the strings match, ignoring case
- * PR_FALSE if they don't
- * PR_FALSE upon error
- */
-
-NSS_EXTERN PRBool
-nssUTF8_PrintableMatch
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-);
-
-/*
- * nssUTF8_Size
- *
- * This routine returns the length in bytes (including the terminating
- * null) of the UTF8-encoded string pointed to by the specified
- * NSSUTF8 pointer. Zero is returned on error.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_VALUE_TOO_LARGE
- *
- * Return value:
- * nonzero size of the string
- * 0 on error
- */
-
-NSS_EXTERN PRUint32
-nssUTF8_Size
-(
- const NSSUTF8 *s,
- PRStatus *statusOpt
-);
-
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-extern const NSSError NSS_ERROR_VALUE_TOO_LARGE;
-
-/*
- * nssUTF8_Length
- *
- * This routine returns the length in characters (not including the
- * terminating null) of the UTF8-encoded string pointed to by the
- * specified NSSUTF8 pointer.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_VALUE_TOO_LARGE
- * NSS_ERROR_INVALID_STRING
- *
- * Return value:
- * length of the string (which may be zero)
- * 0 on error
- */
-
-NSS_EXTERN PRUint32
-nssUTF8_Length
-(
- const NSSUTF8 *s,
- PRStatus *statusOpt
-);
-
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-extern const NSSError NSS_ERROR_VALUE_TOO_LARGE;
-extern const NSSError NSS_ERROR_INVALID_STRING;
-
-/*
- * nssUTF8_Create
- *
- * This routine creates a UTF8 string from a string in some other
- * format. Some types of string may include embedded null characters,
- * so for them the length parameter must be used. For string types
- * that are null-terminated, the length parameter is optional; if it
- * is zero, it will be ignored. If the optional arena argument is
- * non-null, the memory used for the new string will be obtained from
- * that arena, otherwise it will be obtained from the heap. This
- * routine may return NULL upon error, in which case it will have
- * placed an error on the error stack.
- *
- * The error may be one of the following:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_UNSUPPORTED_TYPE
- *
- * Return value:
- * NULL upon error
- * A non-null pointer to a new UTF8 string otherwise
- */
-
-NSS_EXTERN NSSUTF8 *
-nssUTF8_Create
-(
- NSSArena *arenaOpt,
- nssStringType type,
- const void *inputString,
- PRUint32 size /* in bytes, not characters */
-);
-
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-extern const NSSError NSS_ERROR_NO_MEMORY;
-extern const NSSError NSS_ERROR_UNSUPPORTED_TYPE;
-
-NSS_EXTERN NSSItem *
-nssUTF8_GetEncoding
-(
- NSSArena *arenaOpt,
- NSSItem *rvOpt,
- nssStringType type,
- NSSUTF8 *string
-);
-
-/*
- * nssUTF8_CopyIntoFixedBuffer
- *
- * This will copy a UTF8 string into a fixed-length buffer, making
- * sure that the all characters are valid. Any remaining space will
- * be padded with the specified ASCII character, typically either
- * null or space.
- *
- * Blah, blah, blah.
- */
-
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-extern const NSSError NSS_ERROR_INVALID_ARGUMENT;
-
-NSS_EXTERN PRStatus
-nssUTF8_CopyIntoFixedBuffer
-(
- NSSUTF8 *string,
- char *buffer,
- PRUint32 bufferSize,
- char pad
-);
-
-/*
- * nssUTF8_Equal
- *
- */
-
-NSS_EXTERN PRBool
-nssUTF8_Equal
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-);
-
-/*
- * nssList
- *
- * The goal is to provide a simple, optionally threadsafe, linked list
- * class. Since NSS did not seem to use the circularity of PRCList
- * much before, this provides a list that appears to be a linear,
- * NULL-terminated list.
- */
-
-/*
- * nssList_Create
- *
- * If threadsafe is true, the list will be locked during modifications
- * and traversals.
- */
-NSS_EXTERN nssList *
-nssList_Create
-(
- NSSArena *arenaOpt,
- PRBool threadSafe
-);
-
-/*
- * nssList_Destroy
- */
-NSS_EXTERN PRStatus
-nssList_Destroy
-(
- nssList *list
-);
-
-NSS_EXTERN void
-nssList_Clear
-(
- nssList *list,
- nssListElementDestructorFunc destructor
-);
-
-/*
- * nssList_SetCompareFunction
- *
- * By default, two list elements will be compared by comparing their
- * data pointers. By setting this function, the user can control
- * how elements are compared.
- */
-NSS_EXTERN void
-nssList_SetCompareFunction
-(
- nssList *list,
- nssListCompareFunc compareFunc
-);
-
-/*
- * nssList_SetSortFunction
- *
- * Sort function to use for an ordered list.
- */
-NSS_EXTERN void
-nssList_SetSortFunction
-(
- nssList *list,
- nssListSortFunc sortFunc
-);
-
-/*
- * nssList_Add
- */
-NSS_EXTERN PRStatus
-nssList_Add
-(
- nssList *list,
- void *data
-);
-
-/*
- * nssList_AddUnique
- *
- * This will use the compare function to see if the element is already
- * in the list.
- */
-NSS_EXTERN PRStatus
-nssList_AddUnique
-(
- nssList *list,
- void *data
-);
-
-/*
- * nssList_Remove
- *
- * Uses the compare function to locate the element and remove it.
- */
-NSS_EXTERN PRStatus
-nssList_Remove(nssList *list, void *data);
-
-/*
- * nssList_Get
- *
- * Uses the compare function to locate an element. Also serves as
- * nssList_Exists.
- */
-NSS_EXTERN void *
-nssList_Get
-(
- nssList *list,
- void *data
-);
-
-/*
- * nssList_Count
- */
-NSS_EXTERN PRUint32
-nssList_Count
-(
- nssList *list
-);
-
-/*
- * nssList_GetArray
- *
- * Fill rvArray, up to maxElements, with elements in the list. The
- * array is NULL-terminated, so its allocated size must be maxElements + 1.
- */
-NSS_EXTERN PRStatus
-nssList_GetArray
-(
- nssList *list,
- void **rvArray,
- PRUint32 maxElements
-);
-
-/*
- * nssList_CreateIterator
- *
- * Create an iterator for list traversal.
- */
-NSS_EXTERN nssListIterator *
-nssList_CreateIterator
-(
- nssList *list
-);
-
-NSS_EXTERN nssList *
-nssList_Clone
-(
- nssList *list
-);
-
-/*
- * nssListIterator_Destroy
- */
-NSS_EXTERN void
-nssListIterator_Destroy
-(
- nssListIterator *iter
-);
-
-/*
- * nssListIterator_Start
- *
- * Begin a list iteration. After this call, if the list is threadSafe,
- * the list is *locked*.
- */
-NSS_EXTERN void *
-nssListIterator_Start
-(
- nssListIterator *iter
-);
-
-/*
- * nssListIterator_Next
- *
- * Continue a list iteration.
- */
-NSS_EXTERN void *
-nssListIterator_Next
-(
- nssListIterator *iter
-);
-
-/*
- * nssListIterator_Finish
- *
- * Complete a list iteration. This *must* be called in order for the
- * lock to be released.
- */
-NSS_EXTERN PRStatus
-nssListIterator_Finish
-(
- nssListIterator *iter
-);
-
-/*
- * nssHash
- *
- * nssHash_Create
- * nssHash_Destroy
- * nssHash_Add
- * nssHash_Remove
- * nssHash_Count
- * nssHash_Exists
- * nssHash_Lookup
- * nssHash_Iterate
- */
-
-/*
- * nssHash_Create
- *
- */
-
-NSS_EXTERN nssHash *
-nssHash_Create
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets,
- PLHashFunction keyHash,
- PLHashComparator keyCompare,
- PLHashComparator valueCompare
-);
-
-NSS_EXTERN nssHash *
-nssHash_CreatePointer
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-);
-
-NSS_EXTERN nssHash *
-nssHash_CreateString
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-);
-
-NSS_EXTERN nssHash *
-nssHash_CreateItem
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-);
-
-/*
- * nssHash_Destroy
- *
- */
-NSS_EXTERN void
-nssHash_Destroy
-(
- nssHash *hash
-);
-
-/*
- * nssHash_Add
- *
- */
-
-extern const NSSError NSS_ERROR_HASH_COLLISION;
-
-NSS_EXTERN PRStatus
-nssHash_Add
-(
- nssHash *hash,
- const void *key,
- const void *value
-);
-
-/*
- * nssHash_Remove
- *
- */
-NSS_EXTERN void
-nssHash_Remove
-(
- nssHash *hash,
- const void *it
-);
-
-/*
- * nssHash_Count
- *
- */
-NSS_EXTERN PRUint32
-nssHash_Count
-(
- nssHash *hash
-);
-
-/*
- * nssHash_Exists
- *
- */
-NSS_EXTERN PRBool
-nssHash_Exists
-(
- nssHash *hash,
- const void *it
-);
-
-/*
- * nssHash_Lookup
- *
- */
-NSS_EXTERN void *
-nssHash_Lookup
-(
- nssHash *hash,
- const void *it
-);
-
-/*
- * nssHash_Iterate
- *
- */
-NSS_EXTERN void
-nssHash_Iterate
-(
- nssHash *hash,
- nssHashIterator fcn,
- void *closure
-);
-
-
-/*
- * nssPointerTracker
- *
- * This type and these methods are only present in debug builds.
- *
- * The nonpublic methods relating to this type are:
- *
- * nssPointerTracker_initialize
- * nssPointerTracker_finalize
- * nssPointerTracker_add
- * nssPointerTracker_remove
- * nssPointerTracker_verify
- */
-
-/*
- * nssPointerTracker_initialize
- *
- * This method is only present in debug builds.
- *
- * This routine initializes an nssPointerTracker object. Note that
- * the object must have been declared *static* to guarantee that it
- * is in a zeroed state initially. This routine is idempotent, and
- * may even be safely called by multiple threads simultaneously with
- * the same argument. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCESS. On failure it will set an
- * error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_initialize
-(
- nssPointerTracker *tracker
-);
-
-extern const NSSError NSS_ERROR_NO_MEMORY;
-#endif /* DEBUG */
-
-/*
- * nssPointerTracker_finalize
- *
- * This method is only present in debug builds.
- *
- * This routine returns the nssPointerTracker object to the pre-
- * initialized state, releasing all resources used by the object.
- * It will *NOT* destroy the objects being tracked by the pointer
- * (should any remain), and therefore cannot be used to "sweep up"
- * remaining objects. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCES. On failure it will set an
- * error on the error stack and return PR_FAILURE. If any objects
- * remain in the tracker when it is finalized, that will be treated
- * as an error.
- *
- * The error may be one of the following values:
- * NSS_ERROR_TRACKER_NOT_EMPTY
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_finalize
-(
- nssPointerTracker *tracker
-);
-
-extern const NSSError NSS_ERROR_TRACKER_NOT_EMPTY;
-#endif /* DEBUG */
-
-/*
- * nssPointerTracker_add
- *
- * This method is only present in debug builds.
- *
- * This routine adds the specified pointer to the nssPointerTracker
- * object. It should be called in constructor objects to register
- * new valid objects. The nssPointerTracker is threadsafe, but this
- * call is not idempotent. This routine returns a PRStatus value;
- * if successful it will return PR_SUCCESS. On failure it will set
- * an error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_DUPLICATE_POINTER
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_add
-(
- nssPointerTracker *tracker,
- const void *pointer
-);
-
-extern const NSSError NSS_ERROR_NO_MEMORY;
-extern const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED;
-extern const NSSError NSS_ERROR_DUPLICATE_POINTER;
-#endif /* DEBUG */
-
-/*
- * nssPointerTracker_remove
- *
- * This method is only present in debug builds.
- *
- * This routine removes the specified pointer from the
- * nssPointerTracker object. It does not call any destructor for the
- * object; rather, this should be called from the object's destructor.
- * The nssPointerTracker is threadsafe, but this call is not
- * idempotent. This routine returns a PRStatus value; if successful
- * it will return PR_SUCCESS. On failure it will set an error on the
- * error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_POINTER_NOT_REGISTERED
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_remove
-(
- nssPointerTracker *tracker,
- const void *pointer
-);
-
-extern const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED;
-extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
-#endif /* DEBUG */
-
-/*
- * nssPointerTracker_verify
- *
- * This method is only present in debug builds.
- *
- * This routine verifies that the specified pointer has been registered
- * with the nssPointerTracker object. The nssPointerTracker object is
- * threadsafe, and this call may be safely called from multiple threads
- * simultaneously with the same arguments. This routine returns a
- * PRStatus value; if the pointer is registered this will return
- * PR_SUCCESS. Otherwise it will set an error on the error stack and
- * return PR_FAILURE. Although the error is suitable for leaving on
- * the stack, callers may wish to augment the information available by
- * placing a more type-specific error on the stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_POINTER_NOT_REGISTERED
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILRUE
- */
-
-#ifdef DEBUG
-NSS_EXTERN PRStatus
-nssPointerTracker_verify
-(
- nssPointerTracker *tracker,
- const void *pointer
-);
-
-extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
-#endif /* DEBUG */
-
-/*
- * libc
- *
- * nsslibc_memcpy
- * nsslibc_memset
- * nsslibc_offsetof
- */
-
-/*
- * nsslibc_memcpy
- *
- * Errors:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * NULL on error
- * The destination pointer on success
- */
-
-NSS_EXTERN void *
-nsslibc_memcpy
-(
- void *dest,
- const void *source,
- PRUint32 n
-);
-
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-
-/*
- * nsslibc_memset
- *
- * Errors:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * NULL on error
- * The destination pointer on success
- */
-
-NSS_EXTERN void *
-nsslibc_memset
-(
- void *dest,
- PRUint8 byte,
- PRUint32 n
-);
-
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-
-/*
- * nsslibc_memequal
- *
- * Errors:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_TRUE if they match
- * PR_FALSE if they don't
- * PR_FALSE upon error
- */
-
-NSS_EXTERN PRBool
-nsslibc_memequal
-(
- const void *a,
- const void *b,
- PRUint32 len,
- PRStatus *statusOpt
-);
-
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-
-#define nsslibc_offsetof(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))
-
-PR_END_EXTERN_C
-
-#endif /* BASE_H */
diff --git a/security/nss/lib/base/baset.h b/security/nss/lib/base/baset.h
deleted file mode 100644
index 4198ba420..000000000
--- a/security/nss/lib/base/baset.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef BASET_H
-#define BASET_H
-
-#ifdef DEBUG
-static const char BASET_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * baset.h
- *
- * This file contains definitions for the basic types used throughout
- * nss but not available publicly.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#include "plhash.h"
-
-PR_BEGIN_EXTERN_C
-
-/*
- * nssArenaMark
- *
- * This type is used to mark the current state of an NSSArena.
- */
-
-struct nssArenaMarkStr;
-typedef struct nssArenaMarkStr nssArenaMark;
-
-#ifdef DEBUG
-/*
- * ARENA_THREADMARK
- *
- * Optionally, this arena implementation can be compiled with some
- * runtime checking enabled, which will catch the situation where
- * one thread "marks" the arena, another thread allocates memory,
- * and then the mark is released. Usually this is a surprise to
- * the second thread, and this leads to weird runtime errors.
- * Define ARENA_THREADMARK to catch these cases; we define it for all
- * (internal and external) debug builds.
- */
-#define ARENA_THREADMARK
-
-/*
- * ARENA_DESTRUCTOR_LIST
- *
- * Unfortunately, our pointer-tracker facility, used in debug
- * builds to agressively fight invalid pointers, requries that
- * pointers be deregistered when objects are destroyed. This
- * conflicts with the standard arena usage where "memory-only"
- * objects (that don't hold onto resources outside the arena)
- * can be allocated in an arena, and never destroyed other than
- * when the arena is destroyed. Therefore we have added a
- * destructor-registratio facility to our arenas. This was not
- * a simple decision, since we're getting ever-further away from
- * the original arena philosophy. However, it was felt that
- * adding this in debug builds wouldn't be so bad; as it would
- * discourage them from being used for "serious" purposes.
- * This facility requires ARENA_THREADMARK to be defined.
- */
-#ifdef ARENA_THREADMARK
-#define ARENA_DESTRUCTOR_LIST
-#endif /* ARENA_THREADMARK */
-
-#endif /* DEBUG */
-
-typedef struct nssListStr nssList;
-typedef struct nssListIteratorStr nssListIterator;
-typedef PRBool (* nssListCompareFunc)(void *a, void *b);
-typedef PRIntn (* nssListSortFunc)(void *a, void *b);
-typedef void (* nssListElementDestructorFunc)(void *el);
-
-typedef struct nssHashStr nssHash;
-typedef void (PR_CALLBACK *nssHashIterator)(const void *key,
- void *value,
- void *arg);
-
-/*
- * nssPointerTracker
- *
- * This type is used in debug builds (both external and internal) to
- * track our object pointers. Objects of this type must be statically
- * allocated, which means the structure size must be available to the
- * compiler. Therefore we must expose the contents of this structure.
- * But please don't access elements directly; use the accessors.
- */
-
-#ifdef DEBUG
-struct nssPointerTrackerStr {
- PRCallOnceType once;
- PZLock *lock;
- PLHashTable *table;
-};
-typedef struct nssPointerTrackerStr nssPointerTracker;
-#endif /* DEBUG */
-
-/*
- * nssStringType
- *
- * There are several types of strings in the real world. We try to
- * use only UTF8 and avoid the rest, but that's not always possible.
- * So we have a couple converter routines to go to and from the other
- * string types. We have to be able to specify those string types,
- * so we have this enumeration.
- */
-
-enum nssStringTypeEnum {
- nssStringType_DirectoryString,
- nssStringType_TeletexString, /* Not "teletext" with trailing 't' */
- nssStringType_PrintableString,
- nssStringType_UniversalString,
- nssStringType_BMPString,
- nssStringType_UTF8String,
- nssStringType_PHGString,
- nssStringType_GeneralString,
-
- nssStringType_Unknown = -1
-};
-typedef enum nssStringTypeEnum nssStringType;
-
-PR_END_EXTERN_C
-
-#endif /* BASET_H */
diff --git a/security/nss/lib/base/config.mk b/security/nss/lib/base/config.mk
deleted file mode 100644
index f2758950c..000000000
--- a/security/nss/lib/base/config.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-ifdef BUILD_IDG
-DEFINES += -DNSSDEBUG
-endif
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/base/error.c b/security/nss/lib/base/error.c
deleted file mode 100644
index 3e1c20eb6..000000000
--- a/security/nss/lib/base/error.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * error.c
- *
- * This file contains the code implementing the per-thread error
- * stacks upon which most NSS routines report their errors.
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-#include <limits.h> /* for UINT_MAX */
-#include <string.h> /* for memmove */
-
-#define NSS_MAX_ERROR_STACK_COUNT 16 /* error codes */
-
-/*
- * The stack itself has a header, and a sequence of integers.
- * The header records the amount of space (as measured in stack
- * slots) already allocated for the stack, and the count of the
- * number of records currently being used.
- */
-
-struct stack_header_str {
- PRUint16 space;
- PRUint16 count;
-};
-
-struct error_stack_str {
- struct stack_header_str header;
- PRInt32 stack[1];
-};
-typedef struct error_stack_str error_stack;
-
-/*
- * error_stack_index
- *
- * Thread-private data must be indexed. This is that index.
- * See PR_NewThreadPrivateIndex for more information.
- *
- * Thread-private data indexes are in the range [0, 127].
- */
-
-#define INVALID_TPD_INDEX UINT_MAX
-static PRUintn error_stack_index = INVALID_TPD_INDEX;
-
-/*
- * call_once
- *
- * The thread-private index must be obtained (once!) at runtime.
- * This block is used for that one-time call.
- */
-
-static PRCallOnceType error_call_once;
-
-/*
- * error_once_function
- *
- * This is the once-called callback.
- */
-static PRStatus
-error_once_function ( void)
-{
- return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free);
-}
-
-/*
- * error_get_my_stack
- *
- * This routine returns the calling thread's error stack, creating
- * it if necessary. It may return NULL upon error, which implicitly
- * means that it ran out of memory.
- */
-
-static error_stack *
-error_get_my_stack ( void)
-{
- PRStatus st;
- error_stack *rv;
- PRUintn new_size;
- PRUint32 new_bytes;
- error_stack *new_stack;
-
- if( INVALID_TPD_INDEX == error_stack_index ) {
- st = PR_CallOnce(&error_call_once, error_once_function);
- if( PR_SUCCESS != st ) {
- return (error_stack *)NULL;
- }
- }
-
- rv = (error_stack *)PR_GetThreadPrivate(error_stack_index);
- if( (error_stack *)NULL == rv ) {
- /* Doesn't exist; create one */
- new_size = 16;
- } else if( rv->header.count == rv->header.space &&
- rv->header.count < NSS_MAX_ERROR_STACK_COUNT ) {
- /* Too small, expand it */
- new_size = PR_MIN( rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT);
- } else {
- /* Okay, return it */
- return rv;
- }
-
- new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack);
- /* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */
- new_stack = PR_Calloc(1, new_bytes);
-
- if( (error_stack *)NULL != new_stack ) {
- if( (error_stack *)NULL != rv ) {
- (void)nsslibc_memcpy(new_stack,rv,rv->header.space);
- }
- new_stack->header.space = new_size;
- }
-
- /* Set the value, whether or not the allocation worked */
- PR_SetThreadPrivate(error_stack_index, new_stack);
- return new_stack;
-}
-
-/*
- * The error stack
- *
- * The public methods relating to the error stack are:
- *
- * NSS_GetError
- * NSS_GetErrorStack
- *
- * The nonpublic methods relating to the error stack are:
- *
- * nss_SetError
- * nss_ClearErrorStack
- *
- */
-
-/*
- * NSS_GetError
- *
- * This routine returns the highest-level (most general) error set
- * by the most recent NSS library routine called by the same thread
- * calling this routine.
- *
- * This routine cannot fail. However, it may return zero, which
- * indicates that the previous NSS library call did not set an error.
- *
- * Return value:
- * 0 if no error has been set
- * A nonzero error number
- */
-
-NSS_IMPLEMENT PRInt32
-NSS_GetError ( void)
-{
- error_stack *es = error_get_my_stack();
-
- if( (error_stack *)NULL == es ) {
- return NSS_ERROR_NO_MEMORY; /* Good guess! */
- }
-
- if( 0 == es->header.count ) {
- return 0;
- }
-
- return es->stack[ es->header.count-1 ];
-}
-
-/*
- * NSS_GetErrorStack
- *
- * This routine returns a pointer to an array of integers, containing
- * the entire sequence or "stack" of errors set by the most recent NSS
- * library routine called by the same thread calling this routine.
- * NOTE: the caller DOES NOT OWN the memory pointed to by the return
- * value. The pointer will remain valid until the calling thread
- * calls another NSS routine. The lowest-level (most specific) error
- * is first in the array, and the highest-level is last. The array is
- * zero-terminated. This routine may return NULL upon error; this
- * indicates a low-memory situation.
- *
- * Return value:
- * NULL upon error, which is an implied NSS_ERROR_NO_MEMORY
- * A NON-caller-owned pointer to an array of integers
- */
-
-NSS_IMPLEMENT PRInt32 *
-NSS_GetErrorStack ( void)
-{
- error_stack *es = error_get_my_stack();
-
- if( (error_stack *)NULL == es ) {
- return (PRInt32 *)NULL;
- }
-
- /* Make sure it's terminated */
- es->stack[ es->header.count ] = 0;
-
- return es->stack;
-}
-
-/*
- * nss_SetError
- *
- * This routine places a new error code on the top of the calling
- * thread's error stack. Calling this routine wiht an error code
- * of zero will clear the error stack.
- */
-
-NSS_IMPLEMENT void
-nss_SetError ( PRUint32 error)
-{
- error_stack *es;
-
- if( 0 == error ) {
- nss_ClearErrorStack();
- return;
- }
-
- es = error_get_my_stack();
- if( (error_stack *)NULL == es ) {
- /* Oh, well. */
- return;
- }
-
- if (es->header.count < es->header.space) {
- es->stack[ es->header.count++ ] = error;
- } else {
- memmove(es->stack, es->stack + 1,
- (es->header.space - 1) * (sizeof es->stack[0]));
- es->stack[ es->header.space - 1 ] = error;
- }
- return;
-}
-
-/*
- * nss_ClearErrorStack
- *
- * This routine clears the calling thread's error stack.
- */
-
-NSS_IMPLEMENT void
-nss_ClearErrorStack ( void)
-{
- error_stack *es = error_get_my_stack();
- if( (error_stack *)NULL == es ) {
- /* Oh, well. */
- return;
- }
-
- es->header.count = 0;
- es->stack[0] = 0;
- return;
-}
-
-/*
- * nss_DestroyErrorStack
- *
- * This routine frees the calling thread's error stack.
- */
-
-NSS_IMPLEMENT void
-nss_DestroyErrorStack ( void)
-{
- if( INVALID_TPD_INDEX != error_stack_index ) {
- PR_SetThreadPrivate(error_stack_index, NULL);
- }
- return;
-}
diff --git a/security/nss/lib/base/errorval.c b/security/nss/lib/base/errorval.c
deleted file mode 100644
index 4c7dba606..000000000
--- a/security/nss/lib/base/errorval.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * errorval.c
- *
- * This file contains the actual error constants used in NSS.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-const NSSError NSS_ERROR_NO_ERROR = 0;
-const NSSError NSS_ERROR_INTERNAL_ERROR = 1;
-const NSSError NSS_ERROR_NO_MEMORY = 2;
-const NSSError NSS_ERROR_INVALID_POINTER = 3;
-const NSSError NSS_ERROR_INVALID_ARENA = 4;
-const NSSError NSS_ERROR_INVALID_ARENA_MARK = 5;
-const NSSError NSS_ERROR_DUPLICATE_POINTER = 6;
-const NSSError NSS_ERROR_POINTER_NOT_REGISTERED = 7;
-const NSSError NSS_ERROR_TRACKER_NOT_EMPTY = 8;
-const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED = 9;
-const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD = 10;
-const NSSError NSS_ERROR_VALUE_TOO_LARGE = 11;
-const NSSError NSS_ERROR_UNSUPPORTED_TYPE = 12;
-const NSSError NSS_ERROR_BUFFER_TOO_SHORT = 13;
-const NSSError NSS_ERROR_INVALID_ATOB_CONTEXT = 14;
-const NSSError NSS_ERROR_INVALID_BASE64 = 15;
-const NSSError NSS_ERROR_INVALID_BTOA_CONTEXT = 16;
-const NSSError NSS_ERROR_INVALID_ITEM = 17;
-const NSSError NSS_ERROR_INVALID_STRING = 18;
-const NSSError NSS_ERROR_INVALID_ASN1ENCODER = 19;
-const NSSError NSS_ERROR_INVALID_ASN1DECODER = 20;
-
-const NSSError NSS_ERROR_INVALID_BER = 21;
-const NSSError NSS_ERROR_INVALID_ATAV = 22;
-const NSSError NSS_ERROR_INVALID_ARGUMENT = 23;
-const NSSError NSS_ERROR_INVALID_UTF8 = 24;
-const NSSError NSS_ERROR_INVALID_NSSOID = 25;
-const NSSError NSS_ERROR_UNKNOWN_ATTRIBUTE = 26;
-
-const NSSError NSS_ERROR_NOT_FOUND = 27;
-
-const NSSError NSS_ERROR_INVALID_PASSWORD = 28;
-const NSSError NSS_ERROR_USER_CANCELED = 29;
-
-const NSSError NSS_ERROR_MAXIMUM_FOUND = 30;
-
-const NSSError NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND = 31;
-
-const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE = 32;
-
-const NSSError NSS_ERROR_HASH_COLLISION = 33;
-const NSSError NSS_ERROR_DEVICE_ERROR = 34;
-const NSSError NSS_ERROR_INVALID_CERTIFICATE = 35;
-const NSSError NSS_ERROR_BUSY = 36;
-const NSSError NSS_ERROR_ALREADY_INITIALIZED = 37;
-
-const NSSError NSS_ERROR_PKCS11 = 38;
-
diff --git a/security/nss/lib/base/hash.c b/security/nss/lib/base/hash.c
deleted file mode 100644
index 7191c1368..000000000
--- a/security/nss/lib/base/hash.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * hash.c
- *
- * This is merely a couple wrappers around NSPR's PLHashTable, using
- * the identity hash and arena-aware allocators.
- * This is a copy of ckfw/hash.c, with modifications to use NSS types
- * (not Cryptoki types). Would like for this to be a single implementation,
- * but doesn't seem like it will work.
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#include "prbit.h"
-
-/*
- * nssHash
- *
- * nssHash_Create
- * nssHash_Destroy
- * nssHash_Add
- * nssHash_Remove
- * nssHash_Count
- * nssHash_Exists
- * nssHash_Lookup
- * nssHash_Iterate
- */
-
-struct nssHashStr {
- NSSArena *arena;
- PRBool i_alloced_arena;
- PRLock *mutex;
-
- /*
- * The invariant that mutex protects is:
- * The count accurately reflects the hashtable state.
- */
-
- PLHashTable *plHashTable;
- PRUint32 count;
-};
-
-static PLHashNumber
-nss_identity_hash
-(
- const void *key
-)
-{
- PRUint32 i = (PRUint32)key;
- PR_ASSERT(sizeof(PLHashNumber) == sizeof(PRUint32));
- return (PLHashNumber)i;
-}
-
-static PLHashNumber
-nss_item_hash
-(
- const void *key
-)
-{
- unsigned int i;
- PLHashNumber h;
- NSSItem *it = (NSSItem *)key;
- h = 0;
- for (i=0; i<it->size; i++)
- h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)it->data)[i];
- return h;
-}
-
-static int
-nss_compare_items(const void *v1, const void *v2)
-{
- PRStatus ignore;
- return (int)nssItem_Equal((NSSItem *)v1, (NSSItem *)v2, &ignore);
-}
-
-/*
- * nssHash_create
- *
- */
-NSS_IMPLEMENT nssHash *
-nssHash_Create
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets,
- PLHashFunction keyHash,
- PLHashComparator keyCompare,
- PLHashComparator valueCompare
-)
-{
- nssHash *rv;
- NSSArena *arena;
- PRBool i_alloced;
-
-#ifdef NSSDEBUG
- if( arenaOpt && PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (nssHash *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if (arenaOpt) {
- arena = arenaOpt;
- i_alloced = PR_FALSE;
- } else {
- arena = nssArena_Create();
- i_alloced = PR_TRUE;
- }
-
- rv = nss_ZNEW(arena, nssHash);
- if( (nssHash *)NULL == rv ) {
- goto loser;
- }
-
- rv->mutex = PZ_NewLock(nssILockOther);
- if( (PZLock *)NULL == rv->mutex ) {
- goto loser;
- }
-
- rv->plHashTable = PL_NewHashTable(numBuckets,
- keyHash, keyCompare, valueCompare,
- &nssArenaHashAllocOps, arena);
- if( (PLHashTable *)NULL == rv->plHashTable ) {
- (void)PZ_DestroyLock(rv->mutex);
- goto loser;
- }
-
- rv->count = 0;
- rv->arena = arena;
- rv->i_alloced_arena = i_alloced;
-
- return rv;
-loser:
- (void)nss_ZFreeIf(rv);
- return (nssHash *)NULL;
-}
-
-/*
- * nssHash_CreatePointer
- *
- */
-NSS_IMPLEMENT nssHash *
-nssHash_CreatePointer
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-)
-{
- return nssHash_Create(arenaOpt, numBuckets,
- nss_identity_hash, PL_CompareValues, PL_CompareValues);
-}
-
-/*
- * nssHash_CreateString
- *
- */
-NSS_IMPLEMENT nssHash *
-nssHash_CreateString
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-)
-{
- return nssHash_Create(arenaOpt, numBuckets,
- PL_HashString, PL_CompareStrings, PL_CompareStrings);
-}
-
-/*
- * nssHash_CreateItem
- *
- */
-NSS_IMPLEMENT nssHash *
-nssHash_CreateItem
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-)
-{
- return nssHash_Create(arenaOpt, numBuckets,
- nss_item_hash, nss_compare_items, PL_CompareValues);
-}
-
-/*
- * nssHash_Destroy
- *
- */
-NSS_IMPLEMENT void
-nssHash_Destroy
-(
- nssHash *hash
-)
-{
- (void)PZ_DestroyLock(hash->mutex);
- PL_HashTableDestroy(hash->plHashTable);
- if (hash->i_alloced_arena) {
- nssArena_Destroy(hash->arena);
- } else {
- nss_ZFreeIf(hash);
- }
-}
-
-/*
- * nssHash_Add
- *
- */
-NSS_IMPLEMENT PRStatus
-nssHash_Add
-(
- nssHash *hash,
- const void *key,
- const void *value
-)
-{
- PRStatus error = PR_FAILURE;
- PLHashEntry *he;
-
- PZ_Lock(hash->mutex);
-
- he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
- if( (PLHashEntry *)NULL == he ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- } else if (he->value != value) {
- nss_SetError(NSS_ERROR_HASH_COLLISION);
- } else {
- hash->count++;
- error = PR_SUCCESS;
- }
-
- (void)PZ_Unlock(hash->mutex);
-
- return error;
-}
-
-/*
- * nssHash_Remove
- *
- */
-NSS_IMPLEMENT void
-nssHash_Remove
-(
- nssHash *hash,
- const void *it
-)
-{
- PRBool found;
-
- PZ_Lock(hash->mutex);
-
- found = PL_HashTableRemove(hash->plHashTable, it);
- if( found ) {
- hash->count--;
- }
-
- (void)PZ_Unlock(hash->mutex);
- return;
-}
-
-/*
- * nssHash_Count
- *
- */
-NSS_IMPLEMENT PRUint32
-nssHash_Count
-(
- nssHash *hash
-)
-{
- PRUint32 count;
-
- PZ_Lock(hash->mutex);
-
- count = hash->count;
-
- (void)PZ_Unlock(hash->mutex);
-
- return count;
-}
-
-/*
- * nssHash_Exists
- *
- */
-NSS_IMPLEMENT PRBool
-nssHash_Exists
-(
- nssHash *hash,
- const void *it
-)
-{
- void *value;
-
- PZ_Lock(hash->mutex);
-
- value = PL_HashTableLookup(hash->plHashTable, it);
-
- (void)PZ_Unlock(hash->mutex);
-
- if( (void *)NULL == value ) {
- return PR_FALSE;
- } else {
- return PR_TRUE;
- }
-}
-
-/*
- * nssHash_Lookup
- *
- */
-NSS_IMPLEMENT void *
-nssHash_Lookup
-(
- nssHash *hash,
- const void *it
-)
-{
- void *rv;
-
- PZ_Lock(hash->mutex);
-
- rv = PL_HashTableLookup(hash->plHashTable, it);
-
- (void)PZ_Unlock(hash->mutex);
-
- return rv;
-}
-
-struct arg_str {
- nssHashIterator fcn;
- void *closure;
-};
-
-static PRIntn
-nss_hash_enumerator
-(
- PLHashEntry *he,
- PRIntn index,
- void *arg
-)
-{
- struct arg_str *as = (struct arg_str *)arg;
- as->fcn(he->key, he->value, as->closure);
- return HT_ENUMERATE_NEXT;
-}
-
-/*
- * nssHash_Iterate
- *
- * NOTE that the iteration function will be called with the hashtable locked.
- */
-NSS_IMPLEMENT void
-nssHash_Iterate
-(
- nssHash *hash,
- nssHashIterator fcn,
- void *closure
-)
-{
- struct arg_str as;
- as.fcn = fcn;
- as.closure = closure;
-
- PZ_Lock(hash->mutex);
-
- PL_HashTableEnumerateEntries(hash->plHashTable, nss_hash_enumerator, &as);
-
- (void)PZ_Unlock(hash->mutex);
-
- return;
-}
diff --git a/security/nss/lib/base/hashops.c b/security/nss/lib/base/hashops.c
deleted file mode 100644
index db23b432f..000000000
--- a/security/nss/lib/base/hashops.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * hashops.c
- *
- * This file includes a set of PLHashAllocOps that use NSSArenas.
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-static void * PR_CALLBACK
-nss_arena_hash_alloc_table
-(
- void *pool,
- PRSize size
-)
-{
- NSSArena *arena = (NSSArena *)NULL;
-
-#ifdef NSSDEBUG
- if( (void *)NULL != arena ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return (void *)NULL;
- }
- }
-#endif /* NSSDEBUG */
-
- return nss_ZAlloc(arena, size);
-}
-
-static void PR_CALLBACK
-nss_arena_hash_free_table
-(
- void *pool,
- void *item
-)
-{
- (void)nss_ZFreeIf(item);
-}
-
-static PLHashEntry * PR_CALLBACK
-nss_arena_hash_alloc_entry
-(
- void *pool,
- const void *key
-)
-{
- NSSArena *arena = NULL;
-
-#ifdef NSSDEBUG
- if( (void *)NULL != arena ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- return (void *)NULL;
- }
- }
-#endif /* NSSDEBUG */
-
- return nss_ZNEW(arena, PLHashEntry);
-}
-
-static void PR_CALLBACK
-nss_arena_hash_free_entry
-(
- void *pool,
- PLHashEntry *he,
- PRUintn flag
-)
-{
- if( HT_FREE_ENTRY == flag ) {
- (void)nss_ZFreeIf(he);
- }
-}
-
-NSS_IMPLEMENT_DATA PLHashAllocOps
-nssArenaHashAllocOps = {
- nss_arena_hash_alloc_table,
- nss_arena_hash_free_table,
- nss_arena_hash_alloc_entry,
- nss_arena_hash_free_entry
-};
diff --git a/security/nss/lib/base/item.c b/security/nss/lib/base/item.c
deleted file mode 100644
index f36ab9ac7..000000000
--- a/security/nss/lib/base/item.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * item.c
- *
- * This contains some item-manipulation code.
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-/*
- * nssItem_Create
- *
- * -- fgmr comments --
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * A pointer to an NSSItem upon success
- * NULL upon failure
- */
-
-NSS_IMPLEMENT NSSItem *
-nssItem_Create
-(
- NSSArena *arenaOpt,
- NSSItem *rvOpt,
- PRUint32 length,
- const void *data
-)
-{
- NSSItem *rv = (NSSItem *)NULL;
-
-#ifdef DEBUG
- if( (NSSArena *)NULL != arenaOpt ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (NSSItem *)NULL;
- }
- }
-
- if( (const void *)NULL == data ) {
- if( length > 0 ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (NSSItem *)NULL;
- }
- }
-#endif /* DEBUG */
-
- if( (NSSItem *)NULL == rvOpt ) {
- rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem);
- if( (NSSItem *)NULL == rv ) {
- goto loser;
- }
- } else {
- rv = rvOpt;
- }
-
- rv->size = length;
- rv->data = nss_ZAlloc(arenaOpt, length);
- if( (void *)NULL == rv->data ) {
- goto loser;
- }
-
- if( length > 0 ) {
- (void)nsslibc_memcpy(rv->data, data, length);
- }
-
- return rv;
-
- loser:
- if( rv != rvOpt ) {
- nss_ZFreeIf(rv);
- }
-
- return (NSSItem *)NULL;
-}
-
-NSS_IMPLEMENT void
-nssItem_Destroy
-(
- NSSItem *item
-)
-{
- nss_ClearErrorStack();
-
- nss_ZFreeIf(item->data);
- nss_ZFreeIf(item);
-
-}
-
-/*
- * nssItem_Duplicate
- *
- * -- fgmr comments --
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- * NSS_ERROR_INVALID_ITEM
- *
- * Return value:
- * A pointer to an NSSItem upon success
- * NULL upon failure
- */
-
-NSS_IMPLEMENT NSSItem *
-nssItem_Duplicate
-(
- NSSItem *obj,
- NSSArena *arenaOpt,
- NSSItem *rvOpt
-)
-{
-#ifdef DEBUG
- if( (NSSArena *)NULL != arenaOpt ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (NSSItem *)NULL;
- }
- }
-
- if( (NSSItem *)NULL == obj ) {
- nss_SetError(NSS_ERROR_INVALID_ITEM);
- return (NSSItem *)NULL;
- }
-#endif /* DEBUG */
-
- return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data);
-}
-
-#ifdef DEBUG
-/*
- * nssItem_verifyPointer
- *
- * -- fgmr comments --
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ITEM
- *
- * Return value:
- * PR_SUCCESS upon success
- * PR_FAILURE upon failure
- */
-
-NSS_IMPLEMENT PRStatus
-nssItem_verifyPointer
-(
- const NSSItem *item
-)
-{
- if( ((const NSSItem *)NULL == item) ||
- (((void *)NULL == item->data) && (item->size > 0)) ) {
- nss_SetError(NSS_ERROR_INVALID_ITEM);
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-#endif /* DEBUG */
-
-/*
- * nssItem_Equal
- *
- * -- fgmr comments --
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ITEM
- *
- * Return value:
- * PR_TRUE if the items are identical
- * PR_FALSE if they aren't
- * PR_FALSE upon error
- */
-
-NSS_IMPLEMENT PRBool
-nssItem_Equal
-(
- const NSSItem *one,
- const NSSItem *two,
- PRStatus *statusOpt
-)
-{
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
-
- if( ((const NSSItem *)NULL == one) && ((const NSSItem *)NULL == two) ) {
- return PR_TRUE;
- }
-
- if( ((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two) ) {
- return PR_FALSE;
- }
-
- if( one->size != two->size ) {
- return PR_FALSE;
- }
-
- return nsslibc_memequal(one->data, two->data, one->size, statusOpt);
-}
diff --git a/security/nss/lib/base/libc.c b/security/nss/lib/base/libc.c
deleted file mode 100644
index 73b2e1809..000000000
--- a/security/nss/lib/base/libc.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * libc.c
- *
- * This file contains our wrappers/reimplementations for "standard"
- * libc functions. Things like "memcpy." We add to this as we need
- * it. Oh, and let's keep it in alphabetical order, should it ever
- * get large. Most string/character stuff should be in utf8.c, not
- * here. This file (and maybe utf8.c) should be the only ones in
- * NSS to include files with angle brackets.
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#include <string.h> /* memcpy, memset */
-
-/*
- * nsslibc_memcpy
- * nsslibc_memset
- * nsslibc_offsetof
- * nsslibc_memequal
- */
-
-/*
- * nsslibc_memcpy
- *
- * Errors:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * NULL on error
- * The destination pointer on success
- */
-
-NSS_IMPLEMENT void *
-nsslibc_memcpy
-(
- void *dest,
- const void *source,
- PRUint32 n
-)
-{
-#ifdef NSSDEBUG
- if( ((void *)NULL == dest) || ((const void *)NULL == source) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (void *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return memcpy(dest, source, (size_t)n);
-}
-
-/*
- * nsslibc_memset
- *
- * Errors:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * NULL on error
- * The destination pointer on success
- */
-
-NSS_IMPLEMENT void *
-nsslibc_memset
-(
- void *dest,
- PRUint8 byte,
- PRUint32 n
-)
-{
-#ifdef NSSDEBUG
- if( ((void *)NULL == dest) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (void *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return memset(dest, (int)byte, (size_t)n);
-}
-
-/*
- * nsslibc_memequal
- *
- * Errors:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_TRUE if they match
- * PR_FALSE if they don't
- * PR_FALSE upon error
- */
-
-NSS_IMPLEMENT PRBool
-nsslibc_memequal
-(
- const void *a,
- const void *b,
- PRUint32 len,
- PRStatus *statusOpt
-)
-{
-#ifdef NSSDEBUG
- if( (((void *)NULL == a) || ((void *)NULL == b)) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
- }
- return PR_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
-
- if( 0 == memcmp(a, b, len) ) {
- return PR_TRUE;
- } else {
- return PR_FALSE;
- }
-}
-
-/*
- * nsslibc_memcmp
- */
-
-NSS_IMPLEMENT PRInt32
-nsslibc_memcmp
-(
- const void *a,
- const void *b,
- PRUint32 len,
- PRStatus *statusOpt
-)
-{
- int v;
-
-#ifdef NSSDEBUG
- if( (((void *)NULL == a) || ((void *)NULL == b)) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
- }
- return -2;
- }
-#endif /* NSSDEBUG */
-
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
-
- v = memcmp(a, b, len);
- return (PRInt32)v;
-}
-
-/*
- * offsetof is a preprocessor definition
- */
diff --git a/security/nss/lib/base/list.c b/security/nss/lib/base/list.c
deleted file mode 100644
index 014d91707..000000000
--- a/security/nss/lib/base/list.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * list.c
- *
- * This contains the implementation of NSS's thread-safe linked list.
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-struct nssListElementStr {
- PRCList link;
- void *data;
-};
-
-typedef struct nssListElementStr nssListElement;
-
-struct nssListStr {
- NSSArena *arena;
- PZLock *lock;
- nssListElement *head;
- PRUint32 count;
- nssListCompareFunc compareFunc;
- nssListSortFunc sortFunc;
- PRBool i_alloced_arena;
-};
-
-struct nssListIteratorStr {
- PZLock *lock;
- nssList *list;
- nssListElement *current;
-};
-
-#define NSSLIST_LOCK_IF(list) \
- if ((list)->lock) PZ_Lock((list)->lock)
-
-#define NSSLIST_UNLOCK_IF(list) \
- if ((list)->lock) PZ_Unlock((list)->lock)
-
-static PRBool
-pointer_compare(void *a, void *b)
-{
- return (PRBool)(a == b);
-}
-
-static nssListElement *
-nsslist_get_matching_element(nssList *list, void *data)
-{
- PRCList *link;
- nssListElement *node;
- node = list->head;
- if (!node) {
- return NULL;
- }
- link = &node->link;
- while (node) {
- /* using a callback slows things down when it's just compare ... */
- if (list->compareFunc(node->data, data)) {
- break;
- }
- link = &node->link;
- if (link == PR_LIST_TAIL(&list->head->link)) {
- node = NULL;
- break;
- }
- node = (nssListElement *)PR_NEXT_LINK(&node->link);
- }
- return node;
-}
-
-NSS_IMPLEMENT nssList *
-nssList_Create
-(
- NSSArena *arenaOpt,
- PRBool threadSafe
-)
-{
- NSSArena *arena;
- nssList *list;
- PRBool i_alloced;
- if (arenaOpt) {
- arena = arenaOpt;
- i_alloced = PR_FALSE;
- } else {
- arena = nssArena_Create();
- i_alloced = PR_TRUE;
- }
- if (!arena) {
- return (nssList *)NULL;
- }
- list = nss_ZNEW(arena, nssList);
- if (!list) {
- if (!arenaOpt) {
- NSSArena_Destroy(arena);
- }
- return (nssList *)NULL;
- }
- if (threadSafe) {
- list->lock = PZ_NewLock(nssILockOther);
- if (!list->lock) {
- if (arenaOpt) {
- nss_ZFreeIf(list);
- } else {
- NSSArena_Destroy(arena);
- }
- return (nssList *)NULL;
- }
- }
- list->arena = arena;
- list->i_alloced_arena = i_alloced;
- list->compareFunc = pointer_compare;
- return list;
-}
-
-NSS_IMPLEMENT PRStatus
-nssList_Destroy(nssList *list)
-{
- if (!list->i_alloced_arena) {
- nssList_Clear(list, NULL);
- }
- if (list->lock) {
- (void)PZ_DestroyLock(list->lock);
- }
- if (list->i_alloced_arena) {
- NSSArena_Destroy(list->arena);
- list = NULL;
- }
- nss_ZFreeIf(list);
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT void
-nssList_SetCompareFunction(nssList *list, nssListCompareFunc compareFunc)
-{
- list->compareFunc = compareFunc;
-}
-
-NSS_IMPLEMENT void
-nssList_SetSortFunction(nssList *list, nssListSortFunc sortFunc)
-{
- /* XXX if list already has elements, sort them */
- list->sortFunc = sortFunc;
-}
-
-NSS_IMPLEMENT nssListCompareFunc
-nssList_GetCompareFunction(nssList *list)
-{
- return list->compareFunc;
-}
-
-NSS_IMPLEMENT void
-nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
-{
- PRCList *link;
- nssListElement *node, *tmp;
- NSSLIST_LOCK_IF(list);
- node = list->head;
- list->head = NULL;
- while (node && list->count > 0) {
- if (destructor) (*destructor)(node->data);
- link = &node->link;
- tmp = (nssListElement *)PR_NEXT_LINK(link);
- PR_REMOVE_LINK(link);
- nss_ZFreeIf(node);
- node = tmp;
- --list->count;
- }
- NSSLIST_UNLOCK_IF(list);
-}
-
-static PRStatus
-nsslist_add_element(nssList *list, void *data)
-{
- nssListElement *node = nss_ZNEW(list->arena, nssListElement);
- if (!node) {
- return PR_FAILURE;
- }
- PR_INIT_CLIST(&node->link);
- node->data = data;
- if (list->head) {
- if (list->sortFunc) {
- PRCList *link;
- nssListElement *currNode;
- currNode = list->head;
- /* insert in ordered list */
- while (currNode) {
- link = &currNode->link;
- if (list->sortFunc(data, currNode->data) <= 0) {
- /* new element goes before current node */
- PR_INSERT_BEFORE(&node->link, link);
- /* reset head if this is first */
- if (currNode == list->head) list->head = node;
- break;
- }
- if (link == PR_LIST_TAIL(&list->head->link)) {
- /* reached end of list, append */
- PR_INSERT_AFTER(&node->link, link);
- break;
- }
- currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
- }
- } else {
- /* not sorting */
- PR_APPEND_LINK(&node->link, &list->head->link);
- }
- } else {
- list->head = node;
- }
- ++list->count;
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssList_Add(nssList *list, void *data)
-{
- PRStatus nssrv;
- NSSLIST_LOCK_IF(list);
- nssrv = nsslist_add_element(list, data);
- NSSLIST_UNLOCK_IF(list);
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssList_AddUnique(nssList *list, void *data)
-{
- PRStatus nssrv;
- nssListElement *node;
- NSSLIST_LOCK_IF(list);
- node = nsslist_get_matching_element(list, data);
- if (node) {
- /* already in, finish */
- NSSLIST_UNLOCK_IF(list);
- return PR_SUCCESS;
- }
- nssrv = nsslist_add_element(list, data);
- NSSLIST_UNLOCK_IF(list);
- return nssrv;
-}
-
-NSS_IMPLEMENT PRStatus
-nssList_Remove(nssList *list, void *data)
-{
- nssListElement *node;
- NSSLIST_LOCK_IF(list);
- node = nsslist_get_matching_element(list, data);
- if (node) {
- if (node == list->head) {
- list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
- }
- PR_REMOVE_LINK(&node->link);
- nss_ZFreeIf(node);
- if (--list->count == 0) {
- list->head = NULL;
- }
- }
- NSSLIST_UNLOCK_IF(list);
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT void *
-nssList_Get(nssList *list, void *data)
-{
- nssListElement *node;
- NSSLIST_LOCK_IF(list);
- node = nsslist_get_matching_element(list, data);
- NSSLIST_UNLOCK_IF(list);
- return (node) ? node->data : NULL;
-}
-
-NSS_IMPLEMENT PRUint32
-nssList_Count(nssList *list)
-{
- return list->count;
-}
-
-NSS_IMPLEMENT PRStatus
-nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
-{
- nssListElement *node;
- PRUint32 i = 0;
- PR_ASSERT(maxElements > 0);
- node = list->head;
- if (!node) {
- return PR_SUCCESS;
- }
- NSSLIST_LOCK_IF(list);
- while (node) {
- rvArray[i++] = node->data;
- if (i == maxElements) break;
- node = (nssListElement *)PR_NEXT_LINK(&node->link);
- if (node == list->head) {
- break;
- }
- }
- NSSLIST_UNLOCK_IF(list);
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT nssList *
-nssList_Clone(nssList *list)
-{
- nssList *rvList;
- nssListElement *node;
- rvList = nssList_Create(NULL, (list->lock != NULL));
- if (!rvList) {
- return NULL;
- }
- NSSLIST_LOCK_IF(list);
- if (list->count > 0) {
- node = list->head;
- while (PR_TRUE) {
- nssList_Add(rvList, node->data);
- node = (nssListElement *)PR_NEXT_LINK(&node->link);
- if (node == list->head) {
- break;
- }
- }
- }
- NSSLIST_UNLOCK_IF(list);
- return rvList;
-}
-
-NSS_IMPLEMENT nssListIterator *
-nssList_CreateIterator(nssList *list)
-{
- nssListIterator *rvIterator;
- rvIterator = nss_ZNEW(NULL, nssListIterator);
- if (!rvIterator) {
- return NULL;
- }
- rvIterator->list = nssList_Clone(list);
- if (!rvIterator->list) {
- nss_ZFreeIf(rvIterator);
- return NULL;
- }
- rvIterator->current = rvIterator->list->head;
- if (list->lock) {
- rvIterator->lock = PZ_NewLock(nssILockOther);
- if (!rvIterator->lock) {
- nssList_Destroy(rvIterator->list);
- nss_ZFreeIf(rvIterator);
- rvIterator = NULL;
- }
- }
- return rvIterator;
-}
-
-NSS_IMPLEMENT void
-nssListIterator_Destroy(nssListIterator *iter)
-{
- if (iter->lock) {
- (void)PZ_DestroyLock(iter->lock);
- }
- nssList_Destroy(iter->list);
- nss_ZFreeIf(iter);
-}
-
-NSS_IMPLEMENT void *
-nssListIterator_Start(nssListIterator *iter)
-{
- NSSLIST_LOCK_IF(iter);
- if (iter->list->count == 0) {
- return NULL;
- }
- iter->current = iter->list->head;
- return iter->current->data;
-}
-
-NSS_IMPLEMENT void *
-nssListIterator_Next(nssListIterator *iter)
-{
- nssListElement *node;
- PRCList *link;
- if (iter->list->count == 1 || iter->current == NULL) {
- /* Reached the end of the list. Don't change the state, force to
- * user to call nssList_Finish to clean up.
- */
- return NULL;
- }
- node = (nssListElement *)PR_NEXT_LINK(&iter->current->link);
- link = &node->link;
- if (link == PR_LIST_TAIL(&iter->list->head->link)) {
- /* Signal the end of the list. */
- iter->current = NULL;
- return node->data;
- }
- iter->current = node;
- return node->data;
-}
-
-NSS_IMPLEMENT PRStatus
-nssListIterator_Finish(nssListIterator *iter)
-{
- iter->current = iter->list->head;
- return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS;
-}
-
diff --git a/security/nss/lib/base/manifest.mn b/security/nss/lib/base/manifest.mn
deleted file mode 100644
index 01eb39cd0..000000000
--- a/security/nss/lib/base/manifest.mn
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-CORE_DEPTH = ../../..
-
-PRIVATE_EXPORTS = \
- baset.h \
- base.h \
- $(NULL)
-
-EXPORTS = \
- nssbaset.h \
- nssbase.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- arena.c \
- error.c \
- errorval.c \
- hashops.c \
- libc.c \
- tracker.c \
- item.c \
- utf8.c \
- list.c \
- hash.c \
- $(NULL)
-
-REQUIRES = nspr
-
-LIBRARY_NAME = nssb
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/base/nssbase.h b/security/nss/lib/base/nssbase.h
deleted file mode 100644
index 4ea741e0d..000000000
--- a/security/nss/lib/base/nssbase.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSBASE_H
-#define NSSBASE_H
-
-#ifdef DEBUG
-static const char NSSBASE_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssbase.h
- *
- * This header file contains the prototypes of the basic public
- * NSS routines.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-PR_BEGIN_EXTERN_C
-
-/*
- * NSSArena
- *
- * The public methods relating to this type are:
- *
- * NSSArena_Create -- constructor
- * NSSArena_Destroy
- * NSS_ZAlloc
- * NSS_ZRealloc
- * NSS_ZFreeIf
- */
-
-/*
- * NSSArena_Create
- *
- * This routine creates a new memory arena. This routine may return
- * NULL upon error, in which case it will have created an error stack.
- *
- * The top-level error may be one of the following values:
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * NULL upon error
- * A pointer to an NSSArena upon success
- */
-
-NSS_EXTERN NSSArena *
-NSSArena_Create
-(
- void
-);
-
-extern const NSSError NSS_ERROR_NO_MEMORY;
-
-/*
- * NSSArena_Destroy
- *
- * This routine will destroy the specified arena, freeing all memory
- * allocated from it. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCESS. If unsuccessful, it will
- * create an error stack and return PR_FAILURE.
- *
- * The top-level error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- *
- * Return value:
- * PR_SUCCESS upon success
- * PR_FAILURE upon failure
- */
-
-NSS_EXTERN PRStatus
-NSSArena_Destroy
-(
- NSSArena *arena
-);
-
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-
-/*
- * The error stack
- *
- * The public methods relating to the error stack are:
- *
- * NSS_GetError
- * NSS_GetErrorStack
- */
-
-/*
- * NSS_GetError
- *
- * This routine returns the highest-level (most general) error set
- * by the most recent NSS library routine called by the same thread
- * calling this routine.
- *
- * This routine cannot fail. It may return NSS_ERROR_NO_ERROR, which
- * indicates that the previous NSS library call did not set an error.
- *
- * Return value:
- * 0 if no error has been set
- * A nonzero error number
- */
-
-NSS_EXTERN NSSError
-NSS_GetError
-(
- void
-);
-
-extern const NSSError NSS_ERROR_NO_ERROR;
-
-/*
- * NSS_GetErrorStack
- *
- * This routine returns a pointer to an array of NSSError values,
- * containingthe entire sequence or "stack" of errors set by the most
- * recent NSS library routine called by the same thread calling this
- * routine. NOTE: the caller DOES NOT OWN the memory pointed to by
- * the return value. The pointer will remain valid until the calling
- * thread calls another NSS routine. The lowest-level (most specific)
- * error is first in the array, and the highest-level is last. The
- * array is zero-terminated. This routine may return NULL upon error;
- * this indicates a low-memory situation.
- *
- * Return value:
- * NULL upon error, which is an implied NSS_ERROR_NO_MEMORY
- * A NON-caller-owned pointer to an array of NSSError values
- */
-
-NSS_EXTERN NSSError *
-NSS_GetErrorStack
-(
- void
-);
-
-/*
- * NSS_ZNEW
- *
- * This preprocessor macro will allocate memory for a new object
- * of the specified type with nss_ZAlloc, and will cast the
- * return value appropriately. If the optional arena argument is
- * non-null, the memory will be obtained from that arena; otherwise,
- * the memory will be obtained from the heap. This routine may
- * return NULL upon error, in which case it will have set an error
- * upon the error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * NULL upon error
- * A pointer to the new segment of zeroed memory
- */
-
-/* The following line exceeds 72 characters, but emacs barfs if we split it. */
-#define NSS_ZNEW(arenaOpt, type) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type)))
-
-/*
- * NSS_ZNEWARRAY
- *
- * This preprocessor macro will allocate memory for an array of
- * new objects, and will cast the return value appropriately.
- * If the optional arena argument is non-null, the memory will
- * be obtained from that arena; otherwise, the memory will be
- * obtained from the heap. This routine may return NULL upon
- * error, in which case it will have set an error upon the error
- * stack. The array size may be specified as zero.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * NULL upon error
- * A pointer to the new segment of zeroed memory
- */
-
-/* The following line exceeds 72 characters, but emacs barfs if we split it. */
-#define NSS_ZNEWARRAY(arenaOpt, type, quantity) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type) * (quantity)))
-
-
-/*
- * NSS_ZAlloc
- *
- * This routine allocates and zeroes a section of memory of the
- * size, and returns to the caller a pointer to that memory. If
- * the optional arena argument is non-null, the memory will be
- * obtained from that arena; otherwise, the memory will be obtained
- * from the heap. This routine may return NULL upon error, in
- * which case it will have set an error upon the error stack. The
- * value specified for size may be zero; in which case a valid
- * zero-length block of memory will be allocated. This block may
- * be expanded by calling NSS_ZRealloc.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon error
- * A pointer to the new segment of zeroed memory
- */
-
-NSS_EXTERN void *
-NSS_ZAlloc
-(
- NSSArena *arenaOpt,
- PRUint32 size
-);
-
-/*
- * NSS_ZRealloc
- *
- * This routine reallocates a block of memory obtained by calling
- * nss_ZAlloc or nss_ZRealloc. The portion of memory
- * between the new and old sizes -- which is either being newly
- * obtained or released -- is in either case zeroed. This routine
- * may return NULL upon failure, in which case it will have placed
- * an error on the error stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
- *
- * Return value:
- * NULL upon error
- * A pointer to the replacement segment of memory
- */
-
-NSS_EXTERN void *
-NSS_ZRealloc
-(
- void *pointer,
- PRUint32 newSize
-);
-
-
-/*
- * NSS_ZFreeIf
- *
- * If the specified pointer is non-null, then the region of memory
- * to which it points -- which must have been allocated with
- * nss_ZAlloc -- will be zeroed and released. This routine
- * returns a PRStatus value; if successful, it will return PR_SUCCESS.
- * If unsuccessful, it will set an error on the error stack and return
- * PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_EXTERN PRStatus
-NSS_ZFreeIf
-(
- void *pointer
-);
-
-PR_END_EXTERN_C
-
-#endif /* NSSBASE_H */
diff --git a/security/nss/lib/base/nssbaset.h b/security/nss/lib/base/nssbaset.h
deleted file mode 100644
index 287f4c3d8..000000000
--- a/security/nss/lib/base/nssbaset.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSBASET_H
-#define NSSBASET_H
-
-#ifdef DEBUG
-static const char NSSBASET_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssbaset.h
- *
- * This file contains the most low-level, fundamental public types.
- */
-
-#include "nspr.h"
-#include "nssilock.h"
-
-/*
- * NSS_EXTERN, NSS_IMPLEMENT, NSS_EXTERN_DATA, NSS_IMPLEMENT_DATA
- *
- * NSS has its own versions of these NSPR macros, in a form which
- * does not confuse ctags and other related utilities. NSPR
- * defines these macros to take the type as an argument, because
- * of certain OS requirements on platforms not supported by NSS.
- */
-
-#define DUMMY /* dummy */
-#define NSS_EXTERN extern
-#define NSS_EXTERN_DATA extern
-#define NSS_IMPLEMENT
-#define NSS_IMPLEMENT_DATA
-
-PR_BEGIN_EXTERN_C
-
-/*
- * NSSError
- *
- * Calls to NSS routines may result in one or more errors being placed
- * on the calling thread's "error stack." Every possible error that
- * may be returned from a function is declared where the function is
- * prototyped. All errors are of the following type.
- */
-
-typedef PRInt32 NSSError;
-
-/*
- * NSSArena
- *
- * Arenas are logical sets of heap memory, from which memory may be
- * allocated. When an arena is destroyed, all memory allocated within
- * that arena is implicitly freed. These arenas are thread-safe:
- * an arena pointer may be used by multiple threads simultaneously.
- * However, as they are not backed by shared memory, they may only be
- * used within one process.
- */
-
-struct NSSArenaStr;
-typedef struct NSSArenaStr NSSArena;
-
-/*
- * NSSItem
- *
- * This is the basic type used to refer to an unconstrained datum of
- * arbitrary size.
- */
-
-struct NSSItemStr {
- void *data;
- PRUint32 size;
-};
-typedef struct NSSItemStr NSSItem;
-
-
-/*
- * NSSBER
- *
- * Data packed according to the Basic Encoding Rules of ASN.1.
- */
-
-typedef NSSItem NSSBER;
-
-/*
- * NSSDER
- *
- * Data packed according to the Distinguished Encoding Rules of ASN.1;
- * this form is also known as the Canonical Encoding Rules form (CER).
- */
-
-typedef NSSBER NSSDER;
-
-/*
- * NSSBitString
- *
- * Some ASN.1 types use "bit strings," which are passed around as
- * octet strings but whose length is counted in bits. We use this
- * typedef of NSSItem to point out the occasions when the length
- * is counted in bits, not octets.
- */
-
-typedef NSSItem NSSBitString;
-
-/*
- * NSSUTF8
- *
- * Character strings encoded in UTF-8, as defined by RFC 2279.
- */
-
-typedef char NSSUTF8;
-
-/*
- * NSSASCII7
- *
- * Character strings guaranteed to be 7-bit ASCII.
- */
-
-typedef char NSSASCII7;
-
-PR_END_EXTERN_C
-
-#endif /* NSSBASET_H */
diff --git a/security/nss/lib/base/tracker.c b/security/nss/lib/base/tracker.c
deleted file mode 100644
index 532eed0e6..000000000
--- a/security/nss/lib/base/tracker.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * tracker.c
- *
- * This file contains the code used by the pointer-tracking calls used
- * in the debug builds to catch bad pointers. The entire contents are
- * only available in debug builds (both internal and external builds).
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#ifdef DEBUG
-/*
- * identity_hash
- *
- * This static callback is a PLHashFunction as defined in plhash.h
- * It merely returns the value of the object pointer as its hash.
- * There are no possible errors.
- */
-
-static PLHashNumber PR_CALLBACK
-identity_hash
-(
- const void *key
-)
-{
- return (PLHashNumber)key;
-}
-
-/*
- * trackerOnceFunc
- *
- * This function is called once, using the nssCallOnce function above.
- * It creates a new pointer tracker object; initialising its hash
- * table and protective lock.
- */
-
-static PRStatus
-trackerOnceFunc
-(
- void *arg
-)
-{
- nssPointerTracker *tracker = (nssPointerTracker *)arg;
-
- tracker->lock = PZ_NewLock(nssILockOther);
- if( (PZLock *)NULL == tracker->lock ) {
- return PR_FAILURE;
- }
-
- tracker->table = PL_NewHashTable(0,
- identity_hash,
- PL_CompareValues,
- PL_CompareValues,
- (PLHashAllocOps *)NULL,
- (void *)NULL);
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_DestroyLock(tracker->lock);
- tracker->lock = (PZLock *)NULL;
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-/*
- * nssPointerTracker_initialize
- *
- * This method is only present in debug builds.
- *
- * This routine initializes an nssPointerTracker object. Note that
- * the object must have been declared *static* to guarantee that it
- * is in a zeroed state initially. This routine is idempotent, and
- * may even be safely called by multiple threads simultaneously with
- * the same argument. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCESS. On failure it will set an
- * error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_NO_MEMORY
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_initialize
-(
- nssPointerTracker *tracker
-)
-{
- PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker);
- if( PR_SUCCESS != rv ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- }
-
- return rv;
-}
-
-#ifdef DONT_DESTROY_EMPTY_TABLES
-/* See same #ifdef below */
-/*
- * count_entries
- *
- * This static routine is a PLHashEnumerator, as defined in plhash.h.
- * It merely causes the enumeration function to count the number of
- * entries.
- */
-
-static PRIntn PR_CALLBACK
-count_entries
-(
- PLHashEntry *he,
- PRIntn index,
- void *arg
-)
-{
- return HT_ENUMERATE_NEXT;
-}
-#endif /* DONT_DESTROY_EMPTY_TABLES */
-
-/*
- * zero_once
- *
- * This is a guaranteed zeroed once block. It's used to help clear
- * the tracker.
- */
-
-static const PRCallOnceType zero_once;
-
-/*
- * nssPointerTracker_finalize
- *
- * This method is only present in debug builds.
- *
- * This routine returns the nssPointerTracker object to the pre-
- * initialized state, releasing all resources used by the object.
- * It will *NOT* destroy the objects being tracked by the pointer
- * (should any remain), and therefore cannot be used to "sweep up"
- * remaining objects. This routine returns a PRStatus value; if
- * successful, it will return PR_SUCCES. On failure it will set an
- * error on the error stack and return PR_FAILURE. If any objects
- * remain in the tracker when it is finalized, that will be treated
- * as an error.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_TRACKER_NOT_EMPTY
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_finalize
-(
- nssPointerTracker *tracker
-)
-{
- PZLock *lock;
-
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
-
- if( (PZLock *)NULL == tracker->lock ) {
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- lock = tracker->lock;
- PZ_Lock(lock);
-
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
-#ifdef DONT_DESTROY_EMPTY_TABLES
- /*
- * I changed my mind; I think we don't want this after all.
- * Comments?
- */
- count = PL_HashTableEnumerateEntries(tracker->table,
- count_entries,
- (void *)NULL);
-
- if( 0 != count ) {
- PZ_Unlock(lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_EMPTY);
- return PR_FAILURE;
- }
-#endif /* DONT_DESTROY_EMPTY_TABLES */
-
- PL_HashTableDestroy(tracker->table);
- /* memset(tracker, 0, sizeof(nssPointerTracker)); */
- tracker->once = zero_once;
- tracker->lock = (PZLock *)NULL;
- tracker->table = (PLHashTable *)NULL;
-
- PZ_Unlock(lock);
- PZ_DestroyLock(lock);
-
- return PR_SUCCESS;
-}
-
-/*
- * nssPointerTracker_add
- *
- * This method is only present in debug builds.
- *
- * This routine adds the specified pointer to the nssPointerTracker
- * object. It should be called in constructor objects to register
- * new valid objects. The nssPointerTracker is threadsafe, but this
- * call is not idempotent. This routine returns a PRStatus value;
- * if successful it will return PR_SUCCESS. On failure it will set
- * an error on the error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_DUPLICATE_POINTER
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_add
-(
- nssPointerTracker *tracker,
- const void *pointer
-)
-{
- void *check;
- PLHashEntry *entry;
-
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
-
- if( (PZLock *)NULL == tracker->lock ) {
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- PZ_Lock(tracker->lock);
-
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- check = PL_HashTableLookup(tracker->table, pointer);
- if( (void *)NULL != check ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_DUPLICATE_POINTER);
- return PR_FAILURE;
- }
-
- entry = PL_HashTableAdd(tracker->table, pointer, (void *)pointer);
-
- PZ_Unlock(tracker->lock);
-
- if( (PLHashEntry *)NULL == entry ) {
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-/*
- * nssPointerTracker_remove
- *
- * This method is only present in debug builds.
- *
- * This routine removes the specified pointer from the
- * nssPointerTracker object. It does not call any destructor for the
- * object; rather, this should be called from the object's destructor.
- * The nssPointerTracker is threadsafe, but this call is not
- * idempotent. This routine returns a PRStatus value; if successful
- * it will return PR_SUCCESS. On failure it will set an error on the
- * error stack and return PR_FAILURE.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_POINTER_NOT_REGISTERED
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILURE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_remove
-(
- nssPointerTracker *tracker,
- const void *pointer
-)
-{
- PRBool registered;
-
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
-
- if( (PZLock *)NULL == tracker->lock ) {
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- PZ_Lock(tracker->lock);
-
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- registered = PL_HashTableRemove(tracker->table, pointer);
- PZ_Unlock(tracker->lock);
-
- if( !registered ) {
- nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-/*
- * nssPointerTracker_verify
- *
- * This method is only present in debug builds.
- *
- * This routine verifies that the specified pointer has been registered
- * with the nssPointerTracker object. The nssPointerTracker object is
- * threadsafe, and this call may be safely called from multiple threads
- * simultaneously with the same arguments. This routine returns a
- * PRStatus value; if the pointer is registered this will return
- * PR_SUCCESS. Otherwise it will set an error on the error stack and
- * return PR_FAILURE. Although the error is suitable for leaving on
- * the stack, callers may wish to augment the information available by
- * placing a more type-specific error on the stack.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_TRACKER_NOT_INITIALIZED
- * NSS_ERROR_POINTER_NOT_REGISTERED
- *
- * Return value:
- * PR_SUCCESS
- * PR_FAILRUE
- */
-
-NSS_IMPLEMENT PRStatus
-nssPointerTracker_verify
-(
- nssPointerTracker *tracker,
- const void *pointer
-)
-{
- void *check;
-
- if( (nssPointerTracker *)NULL == tracker ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FAILURE;
- }
-
- if( (PZLock *)NULL == tracker->lock ) {
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- PZ_Lock(tracker->lock);
-
- if( (PLHashTable *)NULL == tracker->table ) {
- PZ_Unlock(tracker->lock);
- nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
- return PR_FAILURE;
- }
-
- check = PL_HashTableLookup(tracker->table, pointer);
- PZ_Unlock(tracker->lock);
-
- if( (void *)NULL == check ) {
- nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-#endif /* DEBUG */
diff --git a/security/nss/lib/base/utf8.c b/security/nss/lib/base/utf8.c
deleted file mode 100644
index 2df9749a7..000000000
--- a/security/nss/lib/base/utf8.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * utf8.c
- *
- * This file contains some additional utility routines required for
- * handling UTF8 strings.
- */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#include "plstr.h"
-
-/*
- * NOTES:
- *
- * There's an "is hex string" function in pki1/atav.c. If we need
- * it in more places, pull that one out.
- */
-
-/*
- * nssUTF8_CaseIgnoreMatch
- *
- * Returns true if the two UTF8-encoded strings pointed to by the
- * two specified NSSUTF8 pointers differ only in typcase.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_TRUE if the strings match, ignoring case
- * PR_FALSE if they don't
- * PR_FALSE upon error
- */
-
-NSS_IMPLEMENT PRBool
-nssUTF8_CaseIgnoreMatch
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-)
-{
-#ifdef NSSDEBUG
- if( ((const NSSUTF8 *)NULL == a) ||
- ((const NSSUTF8 *)NULL == b) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
- }
- return PR_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
-
- /*
- * XXX fgmr
- *
- * This is, like, so wrong!
- */
- if( 0 == PL_strcasecmp((const char *)a, (const char *)b) ) {
- return PR_TRUE;
- } else {
- return PR_FALSE;
- }
-}
-
-/*
- * nssUTF8_PrintableMatch
- *
- * Returns true if the two Printable strings pointed to by the
- * two specified NSSUTF8 pointers match when compared with the
- * rules for Printable String (leading and trailing spaces are
- * disregarded, extents of whitespace match irregardless of length,
- * and case is not significant), then PR_TRUE will be returned.
- * Otherwise, PR_FALSE will be returned. Upon failure, PR_FALSE
- * will be returned. If the optional statusOpt argument is not
- * NULL, then PR_SUCCESS or PR_FAILURE will be stored in that
- * location.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- *
- * Return value:
- * PR_TRUE if the strings match, ignoring case
- * PR_FALSE if they don't
- * PR_FALSE upon error
- */
-
-NSS_IMPLEMENT PRBool
-nssUTF8_PrintableMatch
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-)
-{
- PRUint8 *c;
- PRUint8 *d;
-
-#ifdef NSSDEBUG
- if( ((const NSSUTF8 *)NULL == a) ||
- ((const NSSUTF8 *)NULL == b) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
- }
- return PR_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
-
- c = (PRUint8 *)a;
- d = (PRUint8 *)b;
-
- while( ' ' == *c ) {
- c++;
- }
-
- while( ' ' == *d ) {
- d++;
- }
-
- while( ('\0' != *c) && ('\0' != *d) ) {
- PRUint8 e, f;
-
- e = *c;
- f = *d;
-
- if( ('a' <= e) && (e <= 'z') ) {
- e -= ('a' - 'A');
- }
-
- if( ('a' <= f) && (f <= 'z') ) {
- f -= ('a' - 'A');
- }
-
- if( e != f ) {
- return PR_FALSE;
- }
-
- c++;
- d++;
-
- if( ' ' == *c ) {
- while( ' ' == *c ) {
- c++;
- }
- c--;
- }
-
- if( ' ' == *d ) {
- while( ' ' == *d ) {
- d++;
- }
- d--;
- }
- }
-
- while( ' ' == *c ) {
- c++;
- }
-
- while( ' ' == *d ) {
- d++;
- }
-
- if( *c == *d ) {
- /* And both '\0', btw */
- return PR_TRUE;
- } else {
- return PR_FALSE;
- }
-}
-
-/*
- * nssUTF8_Duplicate
- *
- * This routine duplicates the UTF8-encoded string pointed to by the
- * specified NSSUTF8 pointer. If the optional arenaOpt argument is
- * not null, the memory required will be obtained from that arena;
- * otherwise, the memory required will be obtained from the heap.
- * A pointer to the new string will be returned. In case of error,
- * an error will be placed on the error stack and NULL will be
- * returned.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_INVALID_ARENA
- * NSS_ERROR_NO_MEMORY
- */
-
-NSS_IMPLEMENT NSSUTF8 *
-nssUTF8_Duplicate
-(
- const NSSUTF8 *s,
- NSSArena *arenaOpt
-)
-{
- NSSUTF8 *rv;
- PRUint32 len;
-
-#ifdef NSSDEBUG
- if( (const NSSUTF8 *)NULL == s ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (NSSUTF8 *)NULL;
- }
-
- if( (NSSArena *)NULL != arenaOpt ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (NSSUTF8 *)NULL;
- }
- }
-#endif /* NSSDEBUG */
-
- len = PL_strlen((const char *)s);
-#ifdef PEDANTIC
- if( '\0' != ((const char *)s)[ len ] ) {
- /* must have wrapped, e.g., too big for PRUint32 */
- nss_SetError(NSS_ERROR_NO_MEMORY);
- return (NSSUTF8 *)NULL;
- }
-#endif /* PEDANTIC */
- len++; /* zero termination */
-
- rv = nss_ZAlloc(arenaOpt, len);
- if( (void *)NULL == rv ) {
- return (NSSUTF8 *)NULL;
- }
-
- (void)nsslibc_memcpy(rv, s, len);
- return rv;
-}
-
-/*
- * nssUTF8_Size
- *
- * This routine returns the length in bytes (including the terminating
- * null) of the UTF8-encoded string pointed to by the specified
- * NSSUTF8 pointer. Zero is returned on error.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_VALUE_TOO_LARGE
- *
- * Return value:
- * 0 on error
- * nonzero length of the string.
- */
-
-NSS_IMPLEMENT PRUint32
-nssUTF8_Size
-(
- const NSSUTF8 *s,
- PRStatus *statusOpt
-)
-{
- PRUint32 sv;
-
-#ifdef NSSDEBUG
- if( (const NSSUTF8 *)NULL == s ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
- }
- return 0;
- }
-#endif /* NSSDEBUG */
-
- sv = PL_strlen((const char *)s) + 1;
-#ifdef PEDANTIC
- if( '\0' != ((const char *)s)[ sv-1 ] ) {
- /* wrapped */
- nss_SetError(NSS_ERROR_VALUE_TOO_LARGE);
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
- }
- return 0;
- }
-#endif /* PEDANTIC */
-
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
-
- return sv;
-}
-
-/*
- * nssUTF8_Length
- *
- * This routine returns the length in characters (not including the
- * terminating null) of the UTF8-encoded string pointed to by the
- * specified NSSUTF8 pointer.
- *
- * The error may be one of the following values:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_VALUE_TOO_LARGE
- * NSS_ERROR_INVALID_STRING
- *
- * Return value:
- * length of the string (which may be zero)
- * 0 on error
- */
-
-NSS_IMPLEMENT PRUint32
-nssUTF8_Length
-(
- const NSSUTF8 *s,
- PRStatus *statusOpt
-)
-{
- PRUint32 l = 0;
- const PRUint8 *c = (const PRUint8 *)s;
-
-#ifdef NSSDEBUG
- if( (const NSSUTF8 *)NULL == s ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- goto loser;
- }
-#endif /* NSSDEBUG */
-
- /*
- * From RFC 2044:
- *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- * 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- * 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
- * 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx
- */
-
- while( 0 != *c ) {
- PRUint32 incr;
- if( (*c & 0x80) == 0 ) {
- incr = 1;
- } else if( (*c & 0xE0) == 0xC0 ) {
- incr = 2;
- } else if( (*c & 0xF0) == 0xE0 ) {
- incr = 3;
- } else if( (*c & 0xF8) == 0xF0 ) {
- incr = 4;
- } else if( (*c & 0xFC) == 0xF8 ) {
- incr = 5;
- } else if( (*c & 0xFE) == 0xFC ) {
- incr = 6;
- } else {
- nss_SetError(NSS_ERROR_INVALID_STRING);
- goto loser;
- }
-
- l += incr;
-
-#ifdef PEDANTIC
- if( l < incr ) {
- /* Wrapped-- too big */
- nss_SetError(NSS_ERROR_VALUE_TOO_LARGE);
- goto loser;
- }
-
- {
- PRUint8 *d;
- for( d = &c[1]; d < &c[incr]; d++ ) {
- if( (*d & 0xC0) != 0xF0 ) {
- nss_SetError(NSS_ERROR_INVALID_STRING);
- goto loser;
- }
- }
- }
-#endif /* PEDANTIC */
-
- c += incr;
- }
-
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_SUCCESS;
- }
-
- return l;
-
- loser:
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
- }
-
- return 0;
-}
-
-
-/*
- * nssUTF8_Create
- *
- * This routine creates a UTF8 string from a string in some other
- * format. Some types of string may include embedded null characters,
- * so for them the length parameter must be used. For string types
- * that are null-terminated, the length parameter is optional; if it
- * is zero, it will be ignored. If the optional arena argument is
- * non-null, the memory used for the new string will be obtained from
- * that arena, otherwise it will be obtained from the heap. This
- * routine may return NULL upon error, in which case it will have
- * placed an error on the error stack.
- *
- * The error may be one of the following:
- * NSS_ERROR_INVALID_POINTER
- * NSS_ERROR_NO_MEMORY
- * NSS_ERROR_UNSUPPORTED_TYPE
- *
- * Return value:
- * NULL upon error
- * A non-null pointer to a new UTF8 string otherwise
- */
-
-extern const NSSError NSS_ERROR_INTERNAL_ERROR; /* XXX fgmr */
-
-NSS_IMPLEMENT NSSUTF8 *
-nssUTF8_Create
-(
- NSSArena *arenaOpt,
- nssStringType type,
- const void *inputString,
- PRUint32 size /* in bytes, not characters */
-)
-{
- NSSUTF8 *rv = NULL;
-
-#ifdef NSSDEBUG
- if( (NSSArena *)NULL != arenaOpt ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (NSSUTF8 *)NULL;
- }
- }
-
- if( (const void *)NULL == inputString ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (NSSUTF8 *)NULL;
- }
-#endif /* NSSDEBUG */
-
- switch( type ) {
- case nssStringType_DirectoryString:
- /* This is a composite type requiring BER */
- nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);
- break;
- case nssStringType_TeletexString:
- /*
- * draft-ietf-pkix-ipki-part1-11 says in part:
- *
- * In addition, many legacy implementations support names encoded
- * in the ISO 8859-1 character set (Latin1String) but tag them as
- * TeletexString. The Latin1String includes characters used in
- * Western European countries which are not part of the
- * TeletexString charcter set. Implementations that process
- * TeletexString SHOULD be prepared to handle the entire ISO
- * 8859-1 character set.[ISO 8859-1].
- */
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- case nssStringType_PrintableString:
- /*
- * PrintableString consists of A-Za-z0-9 ,()+,-./:=?
- * This is a subset of ASCII, which is a subset of UTF8.
- * So we can just duplicate the string over.
- */
-
- if( 0 == size ) {
- rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt);
- } else {
- rv = nss_ZAlloc(arenaOpt, size+1);
- if( (NSSUTF8 *)NULL == rv ) {
- return (NSSUTF8 *)NULL;
- }
-
- (void)nsslibc_memcpy(rv, inputString, size);
- }
-
- break;
- case nssStringType_UniversalString:
- /* 4-byte unicode */
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- case nssStringType_BMPString:
- /* Base Multilingual Plane of Unicode */
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- case nssStringType_UTF8String:
- if( 0 == size ) {
- rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt);
- } else {
- rv = nss_ZAlloc(arenaOpt, size+1);
- if( (NSSUTF8 *)NULL == rv ) {
- return (NSSUTF8 *)NULL;
- }
-
- (void)nsslibc_memcpy(rv, inputString, size);
- }
-
- break;
- case nssStringType_PHGString:
- /*
- * PHGString is an IA5String (with case-insensitive comparisons).
- * IA5 is ~almost~ ascii; ascii has dollar-sign where IA5 has
- * currency symbol.
- */
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- case nssStringType_GeneralString:
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- default:
- nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);
- break;
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT NSSItem *
-nssUTF8_GetEncoding
-(
- NSSArena *arenaOpt,
- NSSItem *rvOpt,
- nssStringType type,
- NSSUTF8 *string
-)
-{
- NSSItem *rv = (NSSItem *)NULL;
- PRStatus status = PR_SUCCESS;
-
-#ifdef NSSDEBUG
- if( (NSSArena *)NULL != arenaOpt ) {
- if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
- return (NSSItem *)NULL;
- }
- }
-
- if( (NSSUTF8 *)NULL == string ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return (NSSItem *)NULL;
- }
-#endif /* NSSDEBUG */
-
- switch( type ) {
- case nssStringType_DirectoryString:
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- case nssStringType_TeletexString:
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- case nssStringType_PrintableString:
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- case nssStringType_UniversalString:
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- case nssStringType_BMPString:
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- case nssStringType_UTF8String:
- {
- NSSUTF8 *dup = nssUTF8_Duplicate(string, arenaOpt);
- if( (NSSUTF8 *)NULL == dup ) {
- return (NSSItem *)NULL;
- }
-
- if( (NSSItem *)NULL == rvOpt ) {
- rv = nss_ZNEW(arenaOpt, NSSItem);
- if( (NSSItem *)NULL == rv ) {
- (void)nss_ZFreeIf(dup);
- return (NSSItem *)NULL;
- }
- } else {
- rv = rvOpt;
- }
-
- rv->data = dup;
- dup = (NSSUTF8 *)NULL;
- rv->size = nssUTF8_Size(rv->data, &status);
- if( (0 == rv->size) && (PR_SUCCESS != status) ) {
- if( (NSSItem *)NULL == rvOpt ) {
- (void)nss_ZFreeIf(rv);
- }
- return (NSSItem *)NULL;
- }
- }
- break;
- case nssStringType_PHGString:
- nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
- break;
- default:
- nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);
- break;
- }
-
- return rv;
-}
-
-/*
- * nssUTF8_CopyIntoFixedBuffer
- *
- * This will copy a UTF8 string into a fixed-length buffer, making
- * sure that the all characters are valid. Any remaining space will
- * be padded with the specified ASCII character, typically either
- * null or space.
- *
- * Blah, blah, blah.
- */
-
-NSS_IMPLEMENT PRStatus
-nssUTF8_CopyIntoFixedBuffer
-(
- NSSUTF8 *string,
- char *buffer,
- PRUint32 bufferSize,
- char pad
-)
-{
- PRUint32 stringSize = 0;
-
-#ifdef NSSDEBUG
- if( (char *)NULL == buffer ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- return PR_FALSE;
- }
-
- if( 0 == bufferSize ) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return PR_FALSE;
- }
-
- if( (pad & 0x80) != 0x00 ) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return PR_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if( (NSSUTF8 *)NULL == string ) {
- string = (NSSUTF8 *) "";
- }
-
- stringSize = nssUTF8_Size(string, (PRStatus *)NULL);
- stringSize--; /* don't count the trailing null */
- if( stringSize > bufferSize ) {
- PRUint32 bs = bufferSize;
- (void)nsslibc_memcpy(buffer, string, bufferSize);
-
- if( ( ((buffer[ bs-1 ] & 0x80) == 0x00)) ||
- ((bs > 1) && ((buffer[ bs-2 ] & 0xE0) == 0xC0)) ||
- ((bs > 2) && ((buffer[ bs-3 ] & 0xF0) == 0xE0)) ||
- ((bs > 3) && ((buffer[ bs-4 ] & 0xF8) == 0xF0)) ||
- ((bs > 4) && ((buffer[ bs-5 ] & 0xFC) == 0xF8)) ||
- ((bs > 5) && ((buffer[ bs-6 ] & 0xFE) == 0xFC)) ) {
- /* It fit exactly */
- return PR_SUCCESS;
- }
-
- /* Too long. We have to trim the last character */
- for( /*bs*/; bs != 0; bs-- ) {
- if( (buffer[bs-1] & 0xC0) != 0x80 ) {
- buffer[bs-1] = pad;
- break;
- } else {
- buffer[bs-1] = pad;
- }
- }
- } else {
- (void)nsslibc_memset(buffer, pad, bufferSize);
- (void)nsslibc_memcpy(buffer, string, stringSize);
- }
-
- return PR_SUCCESS;
-}
-
-/*
- * nssUTF8_Equal
- *
- */
-
-NSS_IMPLEMENT PRBool
-nssUTF8_Equal
-(
- const NSSUTF8 *a,
- const NSSUTF8 *b,
- PRStatus *statusOpt
-)
-{
- PRUint32 la, lb;
-
-#ifdef NSSDEBUG
- if( ((const NSSUTF8 *)NULL == a) ||
- ((const NSSUTF8 *)NULL == b) ) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- if( (PRStatus *)NULL != statusOpt ) {
- *statusOpt = PR_FAILURE;
- }
- return PR_FALSE;
- }
-#endif /* NSSDEBUG */
-
- la = nssUTF8_Size(a, statusOpt);
- if( 0 == la ) {
- return PR_FALSE;
- }
-
- lb = nssUTF8_Size(b, statusOpt);
- if( 0 == lb ) {
- return PR_FALSE;
- }
-
- if( la != lb ) {
- return PR_FALSE;
- }
-
- return nsslibc_memequal(a, b, la, statusOpt);
-}
diff --git a/security/nss/lib/certdb/.cvsignore b/security/nss/lib/certdb/.cvsignore
deleted file mode 100644
index ec60123e5..000000000
--- a/security/nss/lib/certdb/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-nscertinit.c
diff --git a/security/nss/lib/certdb/Makefile b/security/nss/lib/certdb/Makefile
deleted file mode 100644
index 36524f56a..000000000
--- a/security/nss/lib/certdb/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/certdb/alg1485.c b/security/nss/lib/certdb/alg1485.c
deleted file mode 100644
index ffdaf9cf9..000000000
--- a/security/nss/lib/certdb/alg1485.c
+++ /dev/null
@@ -1,1555 +0,0 @@
-/* alg1485.c - implementation of RFCs 1485, 1779 and 2253.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "prprf.h"
-#include "cert.h"
-#include "certi.h"
-#include "xconst.h"
-#include "genname.h"
-#include "secitem.h"
-#include "secerr.h"
-
-typedef struct NameToKindStr {
- const char * name;
- unsigned int maxLen; /* max bytes in UTF8 encoded string value */
- SECOidTag kind;
- int valueType;
-} NameToKind;
-
-/* local type for directory string--could be printable_string or utf8 */
-#define SEC_ASN1_DS SEC_ASN1_HIGH_TAG_NUMBER
-
-/* Add new entries to this table, and maybe to function ParseRFC1485AVA */
-static const NameToKind name2kinds[] = {
-/* IANA registered type names
- * (See: http://www.iana.org/assignments/ldap-parameters)
- */
-/* RFC 3280, 4630 MUST SUPPORT */
- { "CN", 64, SEC_OID_AVA_COMMON_NAME, SEC_ASN1_DS},
- { "ST", 128, SEC_OID_AVA_STATE_OR_PROVINCE,
- SEC_ASN1_DS},
- { "O", 64, SEC_OID_AVA_ORGANIZATION_NAME,
- SEC_ASN1_DS},
- { "OU", 64, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
- SEC_ASN1_DS},
- { "dnQualifier", 32767, SEC_OID_AVA_DN_QUALIFIER, SEC_ASN1_PRINTABLE_STRING},
- { "C", 2, SEC_OID_AVA_COUNTRY_NAME, SEC_ASN1_PRINTABLE_STRING},
- { "serialNumber", 64, SEC_OID_AVA_SERIAL_NUMBER,SEC_ASN1_PRINTABLE_STRING},
-
-/* RFC 3280, 4630 SHOULD SUPPORT */
- { "L", 128, SEC_OID_AVA_LOCALITY, SEC_ASN1_DS},
- { "title", 64, SEC_OID_AVA_TITLE, SEC_ASN1_DS},
- { "SN", 64, SEC_OID_AVA_SURNAME, SEC_ASN1_DS},
- { "givenName", 64, SEC_OID_AVA_GIVEN_NAME, SEC_ASN1_DS},
- { "initials", 64, SEC_OID_AVA_INITIALS, SEC_ASN1_DS},
- { "generationQualifier",
- 64, SEC_OID_AVA_GENERATION_QUALIFIER,
- SEC_ASN1_DS},
-/* RFC 3280, 4630 MAY SUPPORT */
- { "DC", 128, SEC_OID_AVA_DC, SEC_ASN1_IA5_STRING},
- { "MAIL", 256, SEC_OID_RFC1274_MAIL, SEC_ASN1_IA5_STRING},
- { "UID", 256, SEC_OID_RFC1274_UID, SEC_ASN1_DS},
-
-/* ------------------ "strict" boundary ---------------------------------
- * In strict mode, cert_NameToAscii does not encode any of the attributes
- * below this line. The first SECOidTag below this line must be used to
- * conditionally define the "endKind" in function AppendAVA() below.
- * Most new attribute names should be added below this line.
- * Maybe this line should be up higher? Say, after the 3280 MUSTs and
- * before the 3280 SHOULDs?
- */
-
-/* values from draft-ietf-ldapbis-user-schema-05 (not in RFC 3280) */
- { "postalAddress", 128, SEC_OID_AVA_POSTAL_ADDRESS, SEC_ASN1_DS},
- { "postalCode", 40, SEC_OID_AVA_POSTAL_CODE, SEC_ASN1_DS},
- { "postOfficeBox", 40, SEC_OID_AVA_POST_OFFICE_BOX,SEC_ASN1_DS},
- { "houseIdentifier",64, SEC_OID_AVA_HOUSE_IDENTIFIER,SEC_ASN1_DS},
-/* end of IANA registered type names */
-
-/* legacy keywords */
- { "E", 128, SEC_OID_PKCS9_EMAIL_ADDRESS,SEC_ASN1_IA5_STRING},
- { "STREET", 128, SEC_OID_AVA_STREET_ADDRESS, SEC_ASN1_DS},
- { "pseudonym", 64, SEC_OID_AVA_PSEUDONYM, SEC_ASN1_DS},
-
-/* values defined by the CAB Forum for EV */
- { "incorporationLocality", 128, SEC_OID_EV_INCORPORATION_LOCALITY,
- SEC_ASN1_DS},
- { "incorporationState", 128, SEC_OID_EV_INCORPORATION_STATE,
- SEC_ASN1_DS},
- { "incorporationCountry", 2, SEC_OID_EV_INCORPORATION_COUNTRY,
- SEC_ASN1_PRINTABLE_STRING},
- { "businessCategory", 64, SEC_OID_BUSINESS_CATEGORY, SEC_ASN1_DS},
-
- { 0, 256, SEC_OID_UNKNOWN, 0},
-};
-
-/* Table facilitates conversion of ASCII hex to binary. */
-static const PRInt16 x2b[256] = {
-/* #0x */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #1x */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #2x */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #3x */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-/* #4x */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #5x */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #6x */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #7x */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #8x */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #9x */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #ax */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #bx */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #cx */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #dx */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #ex */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-/* #fx */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-#define IS_HEX(c) (x2b[(PRUint8)(c)] >= 0)
-
-#define C_DOUBLE_QUOTE '\042'
-
-#define C_BACKSLASH '\134'
-
-#define C_EQUAL '='
-
-#define OPTIONAL_SPACE(c) \
- (((c) == ' ') || ((c) == '\r') || ((c) == '\n'))
-
-#define SPECIAL_CHAR(c) \
- (((c) == ',') || ((c) == '=') || ((c) == C_DOUBLE_QUOTE) || \
- ((c) == '\r') || ((c) == '\n') || ((c) == '+') || \
- ((c) == '<') || ((c) == '>') || ((c) == '#') || \
- ((c) == ';') || ((c) == C_BACKSLASH))
-
-
-#define IS_PRINTABLE(c) \
- ((((c) >= 'a') && ((c) <= 'z')) || \
- (((c) >= 'A') && ((c) <= 'Z')) || \
- (((c) >= '0') && ((c) <= '9')) || \
- ((c) == ' ') || \
- ((c) == '\'') || \
- ((c) == '\050') || /* ( */ \
- ((c) == '\051') || /* ) */ \
- (((c) >= '+') && ((c) <= '/')) || /* + , - . / */ \
- ((c) == ':') || \
- ((c) == '=') || \
- ((c) == '?'))
-
-/* RFC 2253 says we must escape ",+\"\\<>;=" EXCEPT inside a quoted string.
- * Inside a quoted string, we only need to escape " and \
- * We choose to quote strings containing any of those special characters,
- * so we only need to escape " and \
- */
-#define NEEDS_ESCAPE(c) \
- (c == C_DOUBLE_QUOTE || c == C_BACKSLASH)
-
-#define NEEDS_HEX_ESCAPE(c) \
- ((PRUint8)c < 0x20 || c == 0x7f)
-
-int
-cert_AVAOidTagToMaxLen(SECOidTag tag)
-{
- const NameToKind *n2k = name2kinds;
-
- while (n2k->kind != tag && n2k->kind != SEC_OID_UNKNOWN) {
- ++n2k;
- }
- return (n2k->kind != SEC_OID_UNKNOWN) ? n2k->maxLen : -1;
-}
-
-static PRBool
-IsPrintable(unsigned char *data, unsigned len)
-{
- unsigned char ch, *end;
-
- end = data + len;
- while (data < end) {
- ch = *data++;
- if (!IS_PRINTABLE(ch)) {
- return PR_FALSE;
- }
- }
- return PR_TRUE;
-}
-
-static void
-skipSpace(const char **pbp, const char *endptr)
-{
- const char *bp = *pbp;
- while (bp < endptr && OPTIONAL_SPACE(*bp)) {
- bp++;
- }
- *pbp = bp;
-}
-
-static SECStatus
-scanTag(const char **pbp, const char *endptr, char *tagBuf, int tagBufSize)
-{
- const char *bp;
- char *tagBufp;
- int taglen;
-
- PORT_Assert(tagBufSize > 0);
-
- /* skip optional leading space */
- skipSpace(pbp, endptr);
- if (*pbp == endptr) {
- /* nothing left */
- return SECFailure;
- }
-
- /* fill tagBuf */
- taglen = 0;
- bp = *pbp;
- tagBufp = tagBuf;
- while (bp < endptr && !OPTIONAL_SPACE(*bp) && (*bp != C_EQUAL)) {
- if (++taglen >= tagBufSize) {
- *pbp = bp;
- return SECFailure;
- }
- *tagBufp++ = *bp++;
- }
- /* null-terminate tagBuf -- guaranteed at least one space left */
- *tagBufp++ = 0;
- *pbp = bp;
-
- /* skip trailing spaces till we hit something - should be an equal sign */
- skipSpace(pbp, endptr);
- if (*pbp == endptr) {
- /* nothing left */
- return SECFailure;
- }
- if (**pbp != C_EQUAL) {
- /* should be an equal sign */
- return SECFailure;
- }
- /* skip over the equal sign */
- (*pbp)++;
-
- return SECSuccess;
-}
-
-/* Returns the number of bytes in the value. 0 means failure. */
-static int
-scanVal(const char **pbp, const char *endptr, char *valBuf, int valBufSize)
-{
- const char *bp;
- char *valBufp;
- int vallen = 0;
- PRBool isQuoted;
-
- PORT_Assert(valBufSize > 0);
-
- /* skip optional leading space */
- skipSpace(pbp, endptr);
- if(*pbp == endptr) {
- /* nothing left */
- return 0;
- }
-
- bp = *pbp;
-
- /* quoted? */
- if (*bp == C_DOUBLE_QUOTE) {
- isQuoted = PR_TRUE;
- /* skip over it */
- bp++;
- } else {
- isQuoted = PR_FALSE;
- }
-
- valBufp = valBuf;
- while (bp < endptr) {
- char c = *bp;
- if (c == C_BACKSLASH) {
- /* escape character */
- bp++;
- if (bp >= endptr) {
- /* escape charater must appear with paired char */
- *pbp = bp;
- return 0;
- }
- c = *bp;
- if (IS_HEX(c) && (endptr - bp) >= 2 && IS_HEX(bp[1])) {
- bp++;
- c = (char)((x2b[(PRUint8)c] << 4) | x2b[(PRUint8)*bp]);
- }
- } else if (c == '#' && bp == *pbp) {
- /* ignore leading #, quotation not required for it. */
- } else if (!isQuoted && SPECIAL_CHAR(c)) {
- /* unescaped special and not within quoted value */
- break;
- } else if (c == C_DOUBLE_QUOTE) {
- /* reached unescaped double quote */
- break;
- }
- /* append character */
- vallen++;
- if (vallen >= valBufSize) {
- *pbp = bp;
- return 0;
- }
- *valBufp++ = c;
- bp++;
- }
-
- /* strip trailing spaces from unquoted values */
- if (!isQuoted) {
- while (valBufp > valBuf) {
- char c = valBufp[-1];
- if (! OPTIONAL_SPACE(c))
- break;
- --valBufp;
- }
- vallen = valBufp - valBuf;
- }
-
- if (isQuoted) {
- /* insist that we stopped on a double quote */
- if (*bp != C_DOUBLE_QUOTE) {
- *pbp = bp;
- return 0;
- }
- /* skip over the quote and skip optional space */
- bp++;
- skipSpace(&bp, endptr);
- }
-
- *pbp = bp;
-
- /* null-terminate valBuf -- guaranteed at least one space left */
- *valBufp = 0;
-
- return vallen;
-}
-
-/* Caller must set error code upon failure */
-static SECStatus
-hexToBin(PLArenaPool *pool, SECItem * destItem, const char * src, int len)
-{
- PRUint8 * dest;
-
- destItem->data = NULL;
- if (len <= 0 || (len & 1)) {
- goto loser;
- }
- len >>= 1;
- if (!SECITEM_AllocItem(pool, destItem, len))
- goto loser;
- dest = destItem->data;
- for (; len > 0; len--, src += 2) {
- PRInt16 bin = (x2b[(PRUint8)src[0]] << 4) | x2b[(PRUint8)src[1]];
- if (bin < 0)
- goto loser;
- *dest++ = (PRUint8)bin;
- }
- return SECSuccess;
-loser:
- if (!pool)
- SECITEM_FreeItem(destItem, PR_FALSE);
- return SECFailure;
-}
-
-/* Parses one AVA, starting at *pbp. Stops at endptr.
- * Advances *pbp past parsed AVA and trailing separator (if present).
- * On any error, returns NULL and *pbp is undefined.
- * On success, returns CERTAVA allocated from arena, and (*pbp)[-1] was
- * the last character parsed. *pbp is either equal to endptr or
- * points to first character after separator.
- */
-static CERTAVA *
-ParseRFC1485AVA(PRArenaPool *arena, const char **pbp, const char *endptr)
-{
- CERTAVA *a;
- const NameToKind *n2k;
- const char *bp;
- int vt = -1;
- int valLen;
- SECOidTag kind = SEC_OID_UNKNOWN;
- SECStatus rv = SECFailure;
- SECItem derOid = { 0, NULL, 0 };
- SECItem derVal = { 0, NULL, 0};
- char sep = 0;
-
- char tagBuf[32];
- char valBuf[384];
-
- PORT_Assert(arena);
- if (SECSuccess != scanTag(pbp, endptr, tagBuf, sizeof tagBuf) ||
- !(valLen = scanVal(pbp, endptr, valBuf, sizeof valBuf))) {
- goto loser;
- }
-
- bp = *pbp;
- if (bp < endptr) {
- sep = *bp++; /* skip over separator */
- }
- *pbp = bp;
- /* if we haven't finished, insist that we've stopped on a separator */
- if (sep && sep != ',' && sep != ';' && sep != '+') {
- goto loser;
- }
-
- /* is this a dotted decimal OID attribute type ? */
- if (!PL_strncasecmp("oid.", tagBuf, 4)) {
- rv = SEC_StringToOID(arena, &derOid, tagBuf, strlen(tagBuf));
- } else {
- for (n2k = name2kinds; n2k->name; n2k++) {
- SECOidData *oidrec;
- if (PORT_Strcasecmp(n2k->name, tagBuf) == 0) {
- kind = n2k->kind;
- vt = n2k->valueType;
- oidrec = SECOID_FindOIDByTag(kind);
- if (oidrec == NULL)
- goto loser;
- derOid = oidrec->oid;
- break;
- }
- }
- }
- if (kind == SEC_OID_UNKNOWN && rv != SECSuccess)
- goto loser;
-
- /* Is this a hex encoding of a DER attribute value ? */
- if ('#' == valBuf[0]) {
- /* convert attribute value from hex to binary */
- rv = hexToBin(arena, &derVal, valBuf + 1, valLen - 1);
- if (rv)
- goto loser;
- a = CERT_CreateAVAFromRaw(arena, &derOid, &derVal);
- } else {
- if (kind == SEC_OID_UNKNOWN)
- goto loser;
- if (kind == SEC_OID_AVA_COUNTRY_NAME && valLen != 2)
- goto loser;
- if (vt == SEC_ASN1_PRINTABLE_STRING &&
- !IsPrintable((unsigned char*) valBuf, valLen))
- goto loser;
- if (vt == SEC_ASN1_DS) {
- /* RFC 4630: choose PrintableString or UTF8String */
- if (IsPrintable((unsigned char*) valBuf, valLen))
- vt = SEC_ASN1_PRINTABLE_STRING;
- else
- vt = SEC_ASN1_UTF8_STRING;
- }
-
- derVal.data = (unsigned char*) valBuf;
- derVal.len = valLen;
- a = CERT_CreateAVAFromSECItem(arena, kind, vt, &derVal);
- }
- return a;
-
-loser:
- /* matched no kind -- invalid tag */
- PORT_SetError(SEC_ERROR_INVALID_AVA);
- return 0;
-}
-
-static CERTName *
-ParseRFC1485Name(const char *buf, int len)
-{
- SECStatus rv;
- CERTName *name;
- const char *bp, *e;
- CERTAVA *ava;
- CERTRDN *rdn = NULL;
-
- name = CERT_CreateName(NULL);
- if (name == NULL) {
- return NULL;
- }
-
- e = buf + len;
- bp = buf;
- while (bp < e) {
- ava = ParseRFC1485AVA(name->arena, &bp, e);
- if (ava == 0)
- goto loser;
- if (!rdn) {
- rdn = CERT_CreateRDN(name->arena, ava, (CERTAVA *)0);
- if (rdn == 0)
- goto loser;
- rv = CERT_AddRDN(name, rdn);
- } else {
- rv = CERT_AddAVA(name->arena, rdn, ava);
- }
- if (rv)
- goto loser;
- if (bp[-1] != '+')
- rdn = NULL; /* done with this RDN */
- skipSpace(&bp, e);
- }
-
- if (name->rdns[0] == 0) {
- /* empty name -- illegal */
- goto loser;
- }
-
- /* Reverse order of RDNS to comply with RFC */
- {
- CERTRDN **firstRdn;
- CERTRDN **lastRdn;
- CERTRDN *tmp;
-
- /* get first one */
- firstRdn = name->rdns;
-
- /* find last one */
- lastRdn = name->rdns;
- while (*lastRdn) lastRdn++;
- lastRdn--;
-
- /* reverse list */
- for ( ; firstRdn < lastRdn; firstRdn++, lastRdn--) {
- tmp = *firstRdn;
- *firstRdn = *lastRdn;
- *lastRdn = tmp;
- }
- }
-
- /* return result */
- return name;
-
- loser:
- CERT_DestroyName(name);
- return NULL;
-}
-
-CERTName *
-CERT_AsciiToName(const char *string)
-{
- CERTName *name;
- name = ParseRFC1485Name(string, PORT_Strlen(string));
- return name;
-}
-
-/************************************************************************/
-
-typedef struct stringBufStr {
- char *buffer;
- unsigned offset;
- unsigned size;
-} stringBuf;
-
-#define DEFAULT_BUFFER_SIZE 200
-
-static SECStatus
-AppendStr(stringBuf *bufp, char *str)
-{
- char *buf;
- unsigned bufLen, bufSize, len;
- int size = 0;
-
- /* Figure out how much to grow buf by (add in the '\0') */
- buf = bufp->buffer;
- bufLen = bufp->offset;
- len = PORT_Strlen(str);
- bufSize = bufLen + len;
- if (!buf) {
- bufSize++;
- size = PR_MAX(DEFAULT_BUFFER_SIZE,bufSize*2);
- buf = (char *) PORT_Alloc(size);
- bufp->size = size;
- } else if (bufp->size < bufSize) {
- size = bufSize*2;
- buf =(char *) PORT_Realloc(buf,size);
- bufp->size = size;
- }
- if (!buf) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- bufp->buffer = buf;
- bufp->offset = bufSize;
-
- /* Concatenate str onto buf */
- buf = buf + bufLen;
- if (bufLen) buf--; /* stomp on old '\0' */
- PORT_Memcpy(buf, str, len+1); /* put in new null */
- return SECSuccess;
-}
-
-typedef enum {
- minimalEscape = 0, /* only hex escapes, and " and \ */
- minimalEscapeAndQuote, /* as above, plus quoting */
- fullEscape /* no quoting, full escaping */
-} EQMode;
-
-/* Some characters must be escaped as a hex string, e.g. c -> \nn .
- * Others must be escaped by preceding with a '\', e.g. c -> \c , but
- * there are certain "special characters" that may be handled by either
- * escaping them, or by enclosing the entire attribute value in quotes.
- * A NULL value for pEQMode implies selecting minimalEscape mode.
- * Some callers will do quoting when needed, others will not.
- * If a caller selects minimalEscapeAndQuote, and the string does not
- * need quoting, then this function changes it to minimalEscape.
- */
-static int
-cert_RFC1485_GetRequiredLen(const char *src, int srclen, EQMode *pEQMode)
-{
- int i, reqLen=0;
- EQMode mode = pEQMode ? *pEQMode : minimalEscape;
- PRBool needsQuoting = PR_FALSE;
- char lastC = 0;
-
- /* need to make an initial pass to determine if quoting is needed */
- for (i = 0; i < srclen; i++) {
- char c = src[i];
- reqLen++;
- if (NEEDS_HEX_ESCAPE(c)) { /* c -> \xx */
- reqLen += 2;
- } else if (NEEDS_ESCAPE(c)) { /* c -> \c */
- reqLen++;
- } else if (SPECIAL_CHAR(c)) {
- if (mode == minimalEscapeAndQuote) /* quoting is allowed */
- needsQuoting = PR_TRUE; /* entirety will need quoting */
- else if (mode == fullEscape)
- reqLen++; /* MAY escape this character */
- } else if (OPTIONAL_SPACE(c) && OPTIONAL_SPACE(lastC)) {
- if (mode == minimalEscapeAndQuote) /* quoting is allowed */
- needsQuoting = PR_TRUE; /* entirety will need quoting */
- }
- lastC = c;
- }
- /* if it begins or ends in optional space it needs quoting */
- if (!needsQuoting && srclen > 0 && mode == minimalEscapeAndQuote &&
- (OPTIONAL_SPACE(src[srclen-1]) || OPTIONAL_SPACE(src[0]))) {
- needsQuoting = PR_TRUE;
- }
-
- if (needsQuoting)
- reqLen += 2;
- if (pEQMode && mode == minimalEscapeAndQuote && !needsQuoting)
- *pEQMode = minimalEscape;
- return reqLen;
-}
-
-static const char hexChars[16] = { "0123456789abcdef" };
-
-static SECStatus
-escapeAndQuote(char *dst, int dstlen, char *src, int srclen, EQMode *pEQMode)
-{
- int i, reqLen=0;
- EQMode mode = pEQMode ? *pEQMode : minimalEscape;
-
- /* space for terminal null */
- reqLen = cert_RFC1485_GetRequiredLen(src, srclen, &mode) + 1;
- if (reqLen > dstlen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
-
- if (mode == minimalEscapeAndQuote)
- *dst++ = C_DOUBLE_QUOTE;
- for (i = 0; i < srclen; i++) {
- char c = src[i];
- if (NEEDS_HEX_ESCAPE(c)) {
- *dst++ = C_BACKSLASH;
- *dst++ = hexChars[ (c >> 4) & 0x0f ];
- *dst++ = hexChars[ c & 0x0f ];
- } else {
- if (NEEDS_ESCAPE(c) || (SPECIAL_CHAR(c) && mode == fullEscape)) {
- *dst++ = C_BACKSLASH;
- }
- *dst++ = c;
- }
- }
- if (mode == minimalEscapeAndQuote)
- *dst++ = C_DOUBLE_QUOTE;
- *dst++ = 0;
- if (pEQMode)
- *pEQMode = mode;
- return SECSuccess;
-}
-
-SECStatus
-CERT_RFC1485_EscapeAndQuote(char *dst, int dstlen, char *src, int srclen)
-{
- EQMode mode = minimalEscapeAndQuote;
- return escapeAndQuote(dst, dstlen, src, srclen, &mode);
-}
-
-
-/* convert an OID to dotted-decimal representation */
-/* Returns a string that must be freed with PR_smprintf_free(), */
-char *
-CERT_GetOidString(const SECItem *oid)
-{
- PRUint8 *stop; /* points to first byte after OID string */
- PRUint8 *first; /* byte of an OID component integer */
- PRUint8 *last; /* byte of an OID component integer */
- char *rvString = NULL;
- char *prefix = NULL;
-
-#define MAX_OID_LEN 1024 /* bytes */
-
- if (oid->len > MAX_OID_LEN) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return NULL;
- }
-
- /* first will point to the next sequence of bytes to decode */
- first = (PRUint8 *)oid->data;
- /* stop points to one past the legitimate data */
- stop = &first[ oid->len ];
-
- /*
- * Check for our pseudo-encoded single-digit OIDs
- */
- if ((*first == 0x80) && (2 == oid->len)) {
- /* Funky encoding. The second byte is the number */
- rvString = PR_smprintf("%lu", (PRUint32)first[1]);
- if (!rvString) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- return rvString;
- }
-
- for (; first < stop; first = last + 1) {
- unsigned int bytesBeforeLast;
-
- for (last = first; last < stop; last++) {
- if (0 == (*last & 0x80)) {
- break;
- }
- }
- bytesBeforeLast = (unsigned int)(last - first);
- if (bytesBeforeLast <= 3U) { /* 0-28 bit number */
- PRUint32 n = 0;
- PRUint32 c;
-
-#define CGET(i, m) \
- c = last[-i] & m; \
- n |= c << (7 * i)
-
-#define CASE(i, m) \
- case i: \
- CGET(i, m); \
- if (!n) goto unsupported \
- /* fall-through */
-
- switch (bytesBeforeLast) {
- CASE(3, 0x7f);
- CASE(2, 0x7f);
- CASE(1, 0x7f);
- case 0: n |= last[0] & 0x7f;
- break;
- }
- if (last[0] & 0x80)
- goto unsupported;
-
- if (!rvString) {
- /* This is the first number.. decompose it */
- PRUint32 one = PR_MIN(n/40, 2); /* never > 2 */
- PRUint32 two = n - (one * 40);
-
- rvString = PR_smprintf("OID.%lu.%lu", one, two);
- } else {
- prefix = rvString;
- rvString = PR_smprintf("%s.%lu", prefix, n);
- }
- } else if (bytesBeforeLast <= 9U) { /* 29-64 bit number */
- PRUint64 n = 0;
- PRUint64 c;
-
- switch (bytesBeforeLast) {
- CASE(9, 0x01);
- CASE(8, 0x7f);
- CASE(7, 0x7f);
- CASE(6, 0x7f);
- CASE(5, 0x7f);
- CASE(4, 0x7f);
- CGET(3, 0x7f);
- CGET(2, 0x7f);
- CGET(1, 0x7f);
- CGET(0, 0x7f);
- break;
- }
- if (last[0] & 0x80)
- goto unsupported;
-
- if (!rvString) {
- /* This is the first number.. decompose it */
- PRUint64 one = PR_MIN(n/40, 2); /* never > 2 */
- PRUint64 two = n - (one * 40);
-
- rvString = PR_smprintf("OID.%llu.%llu", one, two);
- } else {
- prefix = rvString;
- rvString = PR_smprintf("%s.%llu", prefix, n);
- }
- } else {
- /* More than a 64-bit number, or not minimal encoding. */
-unsupported:
- if (!rvString)
- rvString = PR_smprintf("OID.UNSUPPORTED");
- else {
- prefix = rvString;
- rvString = PR_smprintf("%s.UNSUPPORTED", prefix);
- }
- }
-
- if (prefix) {
- PR_smprintf_free(prefix);
- prefix = NULL;
- }
- if (!rvString) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- break;
- }
- }
- return rvString;
-}
-
-/* convert DER-encoded hex to a string */
-static SECItem *
-get_hex_string(SECItem *data)
-{
- SECItem *rv;
- unsigned int i, j;
- static const char hex[] = { "0123456789ABCDEF" };
-
- /* '#' + 2 chars per octet + terminator */
- rv = SECITEM_AllocItem(NULL, NULL, data->len*2 + 2);
- if (!rv) {
- return NULL;
- }
- rv->data[0] = '#';
- rv->len = 1 + 2 * data->len;
- for (i=0; i<data->len; i++) {
- j = data->data[i];
- rv->data[2*i+1] = hex[j >> 4];
- rv->data[2*i+2] = hex[j & 15];
- }
- rv->data[rv->len] = 0;
- return rv;
-}
-
-/* For compliance with RFC 2253, RFC 3280 and RFC 4630, we choose to
- * use the NAME=STRING form, rather than the OID.N.N=#hexXXXX form,
- * when both of these conditions are met:
- * 1) The attribute name OID (kind) has a known name string that is
- * defined in one of those RFCs, or in RFCs that they cite, AND
- * 2) The attribute's value encoding is RFC compliant for the kind
- * (e.g., the value's encoding tag is correct for the kind, and
- * the value's length is in the range allowed for the kind, and
- * the value's contents are appropriate for the encoding tag).
- * Otherwise, we use the OID.N.N=#hexXXXX form.
- *
- * If the caller prefers maximum human readability to RFC compliance,
- * then
- * - We print the kind in NAME= string form if we know the name
- * string for the attribute type OID, regardless of whether the
- * value is correctly encoded or not. else we use the OID.N.N= form.
- * - We use the non-hex STRING form for the attribute value if the
- * value can be represented in such a form. Otherwise, we use
- * the hex string form.
- * This implies that, for maximum human readability, in addition to
- * the two forms allowed by the RFC, we allow two other forms of output:
- * - the OID.N.N=STRING form, and
- * - the NAME=#hexXXXX form
- * When the caller prefers maximum human readability, we do not allow
- * the value of any attribute to exceed the length allowed by the RFC.
- * If the attribute value exceeds the allowed length, we truncate it to
- * the allowed length and append "...".
- * Also in this case, we arbitrarily impose a limit on the length of the
- * entire AVA encoding, regardless of the form, of 384 bytes per AVA.
- * This limit includes the trailing NULL character. If the encoded
- * AVA length exceeds that limit, this function reports failure to encode
- * the AVA.
- *
- * An ASCII representation of an AVA is said to be "invertible" if
- * conversion back to DER reproduces the original DER encoding exactly.
- * The RFC 2253 rules do not ensure that all ASCII AVAs derived according
- * to its rules are invertible. That is because the RFCs allow some
- * attribute values to be encoded in any of a number of encodings,
- * and the encoding type information is lost in the non-hex STRING form.
- * This is particularly true of attributes of type DirectoryString.
- * The encoding type information is always preserved in the hex string
- * form, because the hex includes the entire DER encoding of the value.
- *
- * So, when the caller perfers maximum invertibility, we apply the
- * RFC compliance rules stated above, and add a third required
- * condition on the use of the NAME=STRING form.
- * 3) The attribute's kind is not is allowed to be encoded in any of
- * several different encodings, such as DirectoryStrings.
- *
- * The chief difference between CERT_N2A_STRICT and CERT_N2A_INVERTIBLE
- * is that the latter forces DirectoryStrings to be hex encoded.
- *
- * As a simplification, we assume the value is correctly encoded for
- * its encoding type. That is, we do not test that all the characters
- * in a string encoded type are allowed by that type. We assume it.
- */
-static SECStatus
-AppendAVA(stringBuf *bufp, CERTAVA *ava, CertStrictnessLevel strict)
-{
-#define TMPBUF_LEN 384
- const NameToKind *pn2k = name2kinds;
- SECItem *avaValue = NULL;
- char *unknownTag = NULL;
- char *encodedAVA = NULL;
- PRBool useHex = PR_FALSE; /* use =#hexXXXX form */
- PRBool truncateName = PR_FALSE;
- PRBool truncateValue = PR_FALSE;
- SECOidTag endKind;
- SECStatus rv;
- unsigned int len;
- unsigned int nameLen, valueLen;
- unsigned int maxName, maxValue;
- EQMode mode = minimalEscapeAndQuote;
- NameToKind n2k = { NULL, 32767, SEC_OID_UNKNOWN, SEC_ASN1_DS };
- char tmpBuf[TMPBUF_LEN];
-
-#define tagName n2k.name /* non-NULL means use NAME= form */
-#define maxBytes n2k.maxLen
-#define tag n2k.kind
-#define vt n2k.valueType
-
- /* READABLE mode recognizes more names from the name2kinds table
- * than do STRICT or INVERTIBLE modes. This assignment chooses the
- * point in the table where the attribute type name scanning stops.
- */
- endKind = (strict == CERT_N2A_READABLE) ? SEC_OID_UNKNOWN
- : SEC_OID_AVA_POSTAL_ADDRESS;
- tag = CERT_GetAVATag(ava);
- while (pn2k->kind != tag && pn2k->kind != endKind) {
- ++pn2k;
- }
-
- if (pn2k->kind != endKind ) {
- n2k = *pn2k;
- } else if (strict != CERT_N2A_READABLE) {
- useHex = PR_TRUE;
- }
- /* For invertable form, force Directory Strings to use hex form. */
- if (strict == CERT_N2A_INVERTIBLE && vt == SEC_ASN1_DS) {
- tagName = NULL; /* must use OID.N form */
- useHex = PR_TRUE; /* must use hex string */
- }
- if (!useHex) {
- avaValue = CERT_DecodeAVAValue(&ava->value);
- if (!avaValue) {
- useHex = PR_TRUE;
- if (strict != CERT_N2A_READABLE) {
- tagName = NULL; /* must use OID.N form */
- }
- }
- }
- if (!tagName) {
- /* handle unknown attribute types per RFC 2253 */
- tagName = unknownTag = CERT_GetOidString(&ava->type);
- if (!tagName) {
- if (avaValue)
- SECITEM_FreeItem(avaValue, PR_TRUE);
- return SECFailure;
- }
- }
- if (useHex) {
- avaValue = get_hex_string(&ava->value);
- if (!avaValue) {
- if (unknownTag)
- PR_smprintf_free(unknownTag);
- return SECFailure;
- }
- }
-
- nameLen = strlen(tagName);
- valueLen = (useHex ? avaValue->len :
- cert_RFC1485_GetRequiredLen((char *)avaValue->data, avaValue->len,
- &mode));
- len = nameLen + valueLen + 2; /* Add 2 for '=' and trailing NUL */
-
- maxName = nameLen;
- maxValue = valueLen;
- if (len <= sizeof(tmpBuf)) {
- encodedAVA = tmpBuf;
- } else if (strict != CERT_N2A_READABLE) {
- encodedAVA = PORT_Alloc(len);
- if (!encodedAVA) {
- SECITEM_FreeItem(avaValue, PR_TRUE);
- if (unknownTag)
- PR_smprintf_free(unknownTag);
- return SECFailure;
- }
- } else {
- /* Must make output fit in tmpbuf */
- unsigned int fair = (sizeof tmpBuf)/2 - 1; /* for = and \0 */
-
- if (nameLen < fair) {
- /* just truncate the value */
- maxValue = (sizeof tmpBuf) - (nameLen + 6); /* for "=...\0",
- and possibly '"' */
- } else if (valueLen < fair) {
- /* just truncate the name */
- maxName = (sizeof tmpBuf) - (valueLen + 5); /* for "=...\0" */
- } else {
- /* truncate both */
- maxName = maxValue = fair - 3; /* for "..." */
- }
- if (nameLen > maxName) {
- PORT_Assert(unknownTag && unknownTag == tagName);
- truncateName = PR_TRUE;
- nameLen = maxName;
- }
- encodedAVA = tmpBuf;
- }
-
- memcpy(encodedAVA, tagName, nameLen);
- if (truncateName) {
- /* If tag name is too long, we know it is an OID form that was
- * allocated from the heap, so we can modify it in place
- */
- encodedAVA[nameLen-1] = '.';
- encodedAVA[nameLen-2] = '.';
- encodedAVA[nameLen-3] = '.';
- }
- encodedAVA[nameLen++] = '=';
- if (unknownTag)
- PR_smprintf_free(unknownTag);
-
- if (strict == CERT_N2A_READABLE && maxValue > maxBytes)
- maxValue = maxBytes;
- if (valueLen > maxValue) {
- valueLen = maxValue;
- truncateValue = PR_TRUE;
- }
- /* escape and quote as necessary - don't quote hex strings */
- if (useHex) {
- char * end = encodedAVA + nameLen + valueLen;
- memcpy(encodedAVA + nameLen, (char *)avaValue->data, valueLen);
- end[0] = '\0';
- if (truncateValue) {
- end[-1] = '.';
- end[-2] = '.';
- end[-3] = '.';
- }
- rv = SECSuccess;
- } else if (!truncateValue) {
- rv = escapeAndQuote(encodedAVA + nameLen, len - nameLen,
- (char *)avaValue->data, avaValue->len, &mode);
- } else {
- /* must truncate the escaped and quoted value */
- char bigTmpBuf[TMPBUF_LEN * 3 + 3];
- rv = escapeAndQuote(bigTmpBuf, sizeof bigTmpBuf,
- (char *)avaValue->data, valueLen, &mode);
-
- bigTmpBuf[valueLen--] = '\0'; /* hard stop here */
- /* See if we're in the middle of a multi-byte UTF8 character */
- while (((bigTmpBuf[valueLen] & 0xc0) == 0x80) && valueLen > 0) {
- bigTmpBuf[valueLen--] = '\0';
- }
- /* add ellipsis to signify truncation. */
- bigTmpBuf[++valueLen] = '.';
- bigTmpBuf[++valueLen] = '.';
- bigTmpBuf[++valueLen] = '.';
- if (bigTmpBuf[0] == '"')
- bigTmpBuf[++valueLen] = '"';
- bigTmpBuf[++valueLen] = '\0';
- PORT_Assert(nameLen + valueLen <= (sizeof tmpBuf) - 1);
- memcpy(encodedAVA + nameLen, bigTmpBuf, valueLen+1);
- }
-
- SECITEM_FreeItem(avaValue, PR_TRUE);
- if (rv == SECSuccess)
- rv = AppendStr(bufp, encodedAVA);
- if (encodedAVA != tmpBuf)
- PORT_Free(encodedAVA);
- return rv;
-}
-
-#undef tagName
-#undef maxBytes
-#undef tag
-#undef vt
-
-char *
-CERT_NameToAsciiInvertible(CERTName *name, CertStrictnessLevel strict)
-{
- CERTRDN** rdns;
- CERTRDN** lastRdn;
- CERTRDN** rdn;
- PRBool first = PR_TRUE;
- stringBuf strBuf = { NULL, 0, 0 };
-
- rdns = name->rdns;
- if (rdns == NULL) {
- return NULL;
- }
-
- /* find last RDN */
- lastRdn = rdns;
- while (*lastRdn) lastRdn++;
- lastRdn--;
-
- /*
- * Loop over name contents in _reverse_ RDN order appending to string
- */
- for (rdn = lastRdn; rdn >= rdns; rdn--) {
- CERTAVA** avas = (*rdn)->avas;
- CERTAVA* ava;
- PRBool newRDN = PR_TRUE;
-
- /*
- * XXX Do we need to traverse the AVAs in reverse order, too?
- */
- while (avas && (ava = *avas++) != NULL) {
- SECStatus rv;
- /* Put in comma or plus separator */
- if (!first) {
- /* Use of spaces is deprecated in RFC 2253. */
- rv = AppendStr(&strBuf, newRDN ? "," : "+");
- if (rv) goto loser;
- } else {
- first = PR_FALSE;
- }
-
- /* Add in tag type plus value into strBuf */
- rv = AppendAVA(&strBuf, ava, strict);
- if (rv) goto loser;
- newRDN = PR_FALSE;
- }
- }
- return strBuf.buffer;
-loser:
- if (strBuf.buffer) {
- PORT_Free(strBuf.buffer);
- }
- return NULL;
-}
-
-char *
-CERT_NameToAscii(CERTName *name)
-{
- return CERT_NameToAsciiInvertible(name, CERT_N2A_READABLE);
-}
-
-/*
- * Return the string representation of a DER encoded distinguished name
- * "dername" - The DER encoded name to convert
- */
-char *
-CERT_DerNameToAscii(SECItem *dername)
-{
- int rv;
- PRArenaPool *arena = NULL;
- CERTName name;
- char *retstr = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( arena == NULL) {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, &name, CERT_NameTemplate, dername);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- retstr = CERT_NameToAscii(&name);
-
-loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(retstr);
-}
-
-static char *
-avaToString(PRArenaPool *arena, CERTAVA *ava)
-{
- char * buf = NULL;
- SECItem* avaValue;
- int valueLen;
-
- avaValue = CERT_DecodeAVAValue(&ava->value);
- if(!avaValue) {
- return buf;
- }
- valueLen = cert_RFC1485_GetRequiredLen((char *)avaValue->data,
- avaValue->len, NULL) + 1;
- if (arena) {
- buf = (char *)PORT_ArenaZAlloc(arena, valueLen);
- } else {
- buf = (char *)PORT_ZAlloc(valueLen);
- }
- if (buf) {
- SECStatus rv = escapeAndQuote(buf, valueLen, (char *)avaValue->data,
- avaValue->len, NULL);
- if (rv != SECSuccess) {
- if (!arena)
- PORT_Free(buf);
- buf = NULL;
- }
- }
- SECITEM_FreeItem(avaValue, PR_TRUE);
- return buf;
-}
-
-/* RDNs are sorted from most general to most specific.
- * This code returns the FIRST one found, the most general one found.
- */
-static char *
-CERT_GetNameElement(PRArenaPool *arena, CERTName *name, int wantedTag)
-{
- CERTRDN** rdns = name->rdns;
- CERTRDN* rdn;
- CERTAVA* ava = NULL;
-
- while (rdns && (rdn = *rdns++) != 0) {
- CERTAVA** avas = rdn->avas;
- while (avas && (ava = *avas++) != 0) {
- int tag = CERT_GetAVATag(ava);
- if ( tag == wantedTag ) {
- avas = NULL;
- rdns = NULL; /* break out of all loops */
- }
- }
- }
- return ava ? avaToString(arena, ava) : NULL;
-}
-
-/* RDNs are sorted from most general to most specific.
- * This code returns the LAST one found, the most specific one found.
- * This is particularly appropriate for Common Name. See RFC 2818.
- */
-static char *
-CERT_GetLastNameElement(PRArenaPool *arena, CERTName *name, int wantedTag)
-{
- CERTRDN** rdns = name->rdns;
- CERTRDN* rdn;
- CERTAVA* lastAva = NULL;
-
- while (rdns && (rdn = *rdns++) != 0) {
- CERTAVA** avas = rdn->avas;
- CERTAVA* ava;
- while (avas && (ava = *avas++) != 0) {
- int tag = CERT_GetAVATag(ava);
- if ( tag == wantedTag ) {
- lastAva = ava;
- }
- }
- }
- return lastAva ? avaToString(arena, lastAva) : NULL;
-}
-
-char *
-CERT_GetCertificateEmailAddress(CERTCertificate *cert)
-{
- char *rawEmailAddr = NULL;
- SECItem subAltName;
- SECStatus rv;
- CERTGeneralName *nameList = NULL;
- CERTGeneralName *current;
- PRArenaPool *arena = NULL;
- int i;
-
- subAltName.data = NULL;
-
- rawEmailAddr = CERT_GetNameElement(cert->arena, &(cert->subject),
- SEC_OID_PKCS9_EMAIL_ADDRESS);
- if ( rawEmailAddr == NULL ) {
- rawEmailAddr = CERT_GetNameElement(cert->arena, &(cert->subject),
- SEC_OID_RFC1274_MAIL);
- }
- if ( rawEmailAddr == NULL) {
-
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
- &subAltName);
- if (rv != SECSuccess) {
- goto finish;
- }
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena) {
- goto finish;
- }
- nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName);
- if (!nameList ) {
- goto finish;
- }
- if (nameList != NULL) {
- do {
- if (current->type == certDirectoryName) {
- rawEmailAddr = CERT_GetNameElement(cert->arena,
- &(current->name.directoryName),
- SEC_OID_PKCS9_EMAIL_ADDRESS);
- if ( rawEmailAddr == NULL ) {
- rawEmailAddr = CERT_GetNameElement(cert->arena,
- &(current->name.directoryName), SEC_OID_RFC1274_MAIL);
- }
- } else if (current->type == certRFC822Name) {
- rawEmailAddr = (char*)PORT_ArenaZAlloc(cert->arena,
- current->name.other.len + 1);
- if (!rawEmailAddr) {
- goto finish;
- }
- PORT_Memcpy(rawEmailAddr, current->name.other.data,
- current->name.other.len);
- rawEmailAddr[current->name.other.len] = '\0';
- }
- if (rawEmailAddr) {
- break;
- }
- current = CERT_GetNextGeneralName(current);
- } while (current != nameList);
- }
- }
- if (rawEmailAddr) {
- for (i = 0; i <= (int) PORT_Strlen(rawEmailAddr); i++) {
- rawEmailAddr[i] = tolower(rawEmailAddr[i]);
- }
- }
-
-finish:
-
- /* Don't free nameList, it's part of the arena. */
-
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- if ( subAltName.data ) {
- SECITEM_FreeItem(&subAltName, PR_FALSE);
- }
-
- return(rawEmailAddr);
-}
-
-static char *
-appendStringToBuf(char *dest, char *src, PRUint32 *pRemaining)
-{
- PRUint32 len;
- if (dest && src && src[0] && *pRemaining > (len = PL_strlen(src))) {
- PRUint32 i;
- for (i = 0; i < len; ++i)
- dest[i] = tolower(src[i]);
- dest[len] = 0;
- dest += len + 1;
- *pRemaining -= len + 1;
- }
- return dest;
-}
-
-#undef NEEDS_HEX_ESCAPE
-#define NEEDS_HEX_ESCAPE(c) (c < 0x20)
-
-static char *
-appendItemToBuf(char *dest, SECItem *src, PRUint32 *pRemaining)
-{
- if (dest && src && src->data && src->len && src->data[0]) {
- PRUint32 len = src->len;
- PRUint32 i;
- PRUint32 reqLen = len + 1;
- /* are there any embedded control characters ? */
- for (i = 0; i < len; i++) {
- if (NEEDS_HEX_ESCAPE(src->data[i]))
- reqLen += 2;
- }
- if (*pRemaining > reqLen) {
- for (i = 0; i < len; ++i) {
- PRUint8 c = src->data[i];
- if (NEEDS_HEX_ESCAPE(c)) {
- *dest++ = C_BACKSLASH;
- *dest++ = hexChars[ (c >> 4) & 0x0f ];
- *dest++ = hexChars[ c & 0x0f ];
- } else {
- *dest++ = tolower(c);
- }
- }
- *dest++ = '\0';
- *pRemaining -= reqLen;
- }
- }
- return dest;
-}
-
-/* Returns a pointer to an environment-like string, a series of
-** null-terminated strings, terminated by a zero-length string.
-** This function is intended to be internal to NSS.
-*/
-char *
-cert_GetCertificateEmailAddresses(CERTCertificate *cert)
-{
- char * rawEmailAddr = NULL;
- char * addrBuf = NULL;
- char * pBuf = NULL;
- PRArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- PRUint32 maxLen = 0;
- PRInt32 finalLen = 0;
- SECStatus rv;
- SECItem subAltName;
-
- if (!tmpArena)
- return addrBuf;
-
- subAltName.data = NULL;
- maxLen = cert->derCert.len;
- PORT_Assert(maxLen);
- if (!maxLen)
- maxLen = 2000; /* a guess, should never happen */
-
- pBuf = addrBuf = (char *)PORT_ArenaZAlloc(tmpArena, maxLen + 1);
- if (!addrBuf)
- goto loser;
-
- rawEmailAddr = CERT_GetNameElement(tmpArena, &cert->subject,
- SEC_OID_PKCS9_EMAIL_ADDRESS);
- pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
-
- rawEmailAddr = CERT_GetNameElement(tmpArena, &cert->subject,
- SEC_OID_RFC1274_MAIL);
- pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
-
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
- &subAltName);
- if (rv == SECSuccess && subAltName.data) {
- CERTGeneralName *nameList = NULL;
-
- if (!!(nameList = CERT_DecodeAltNameExtension(tmpArena, &subAltName))) {
- CERTGeneralName *current = nameList;
- do {
- if (current->type == certDirectoryName) {
- rawEmailAddr = CERT_GetNameElement(tmpArena,
- &current->name.directoryName,
- SEC_OID_PKCS9_EMAIL_ADDRESS);
- pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
-
- rawEmailAddr = CERT_GetNameElement(tmpArena,
- &current->name.directoryName,
- SEC_OID_RFC1274_MAIL);
- pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
- } else if (current->type == certRFC822Name) {
- pBuf = appendItemToBuf(pBuf, &current->name.other, &maxLen);
- }
- current = CERT_GetNextGeneralName(current);
- } while (current != nameList);
- }
- SECITEM_FreeItem(&subAltName, PR_FALSE);
- /* Don't free nameList, it's part of the tmpArena. */
- }
- /* now copy superstring to cert's arena */
- finalLen = (pBuf - addrBuf) + 1;
- pBuf = NULL;
- if (finalLen > 1) {
- pBuf = PORT_ArenaAlloc(cert->arena, finalLen);
- if (pBuf) {
- PORT_Memcpy(pBuf, addrBuf, finalLen);
- }
- }
-loser:
- if (tmpArena)
- PORT_FreeArena(tmpArena, PR_FALSE);
-
- return pBuf;
-}
-
-/* returns pointer to storage in cert's arena. Storage remains valid
-** as long as cert's reference count doesn't go to zero.
-** Caller should strdup or otherwise copy.
-*/
-const char * /* const so caller won't muck with it. */
-CERT_GetFirstEmailAddress(CERTCertificate * cert)
-{
- if (cert && cert->emailAddr && cert->emailAddr[0])
- return (const char *)cert->emailAddr;
- return NULL;
-}
-
-/* returns pointer to storage in cert's arena. Storage remains valid
-** as long as cert's reference count doesn't go to zero.
-** Caller should strdup or otherwise copy.
-*/
-const char * /* const so caller won't muck with it. */
-CERT_GetNextEmailAddress(CERTCertificate * cert, const char * prev)
-{
- if (cert && prev && prev[0]) {
- PRUint32 len = PL_strlen(prev);
- prev += len + 1;
- if (prev && prev[0])
- return prev;
- }
- return NULL;
-}
-
-/* This is seriously bogus, now that certs store their email addresses in
-** subject Alternative Name extensions.
-** Returns a string allocated by PORT_StrDup, which the caller must free.
-*/
-char *
-CERT_GetCertEmailAddress(CERTName *name)
-{
- char *rawEmailAddr;
- char *emailAddr;
-
-
- rawEmailAddr = CERT_GetNameElement(NULL, name, SEC_OID_PKCS9_EMAIL_ADDRESS);
- if ( rawEmailAddr == NULL ) {
- rawEmailAddr = CERT_GetNameElement(NULL, name, SEC_OID_RFC1274_MAIL);
- }
- emailAddr = CERT_FixupEmailAddr(rawEmailAddr);
- if ( rawEmailAddr ) {
- PORT_Free(rawEmailAddr);
- }
- return(emailAddr);
-}
-
-/* The return value must be freed with PORT_Free. */
-char *
-CERT_GetCommonName(CERTName *name)
-{
- return(CERT_GetLastNameElement(NULL, name, SEC_OID_AVA_COMMON_NAME));
-}
-
-char *
-CERT_GetCountryName(CERTName *name)
-{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_COUNTRY_NAME));
-}
-
-char *
-CERT_GetLocalityName(CERTName *name)
-{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_LOCALITY));
-}
-
-char *
-CERT_GetStateName(CERTName *name)
-{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_STATE_OR_PROVINCE));
-}
-
-char *
-CERT_GetOrgName(CERTName *name)
-{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_ORGANIZATION_NAME));
-}
-
-char *
-CERT_GetDomainComponentName(CERTName *name)
-{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_DC));
-}
-
-char *
-CERT_GetOrgUnitName(CERTName *name)
-{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME));
-}
-
-char *
-CERT_GetDnQualifier(CERTName *name)
-{
- return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_DN_QUALIFIER));
-}
-
-char *
-CERT_GetCertUid(CERTName *name)
-{
- return(CERT_GetNameElement(NULL, name, SEC_OID_RFC1274_UID));
-}
-
diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h
deleted file mode 100644
index fb324a09d..000000000
--- a/security/nss/lib/certdb/cert.h
+++ /dev/null
@@ -1,1650 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * cert.h - public data structures and prototypes for the certificate library
- *
- * $Id$
- */
-
-#ifndef _CERT_H_
-#define _CERT_H_
-
-#include "utilrename.h"
-#include "plarena.h"
-#include "plhash.h"
-#include "prlong.h"
-#include "prlog.h"
-
-#include "seccomon.h"
-#include "secdert.h"
-#include "secoidt.h"
-#include "keyt.h"
-#include "certt.h"
-
-SEC_BEGIN_PROTOS
-
-/****************************************************************************
- *
- * RFC1485 ascii to/from X.? RelativeDistinguishedName (aka CERTName)
- *
- ****************************************************************************/
-
-/*
-** Convert an ascii RFC1485 encoded name into its CERTName equivalent.
-*/
-extern CERTName *CERT_AsciiToName(const char *string);
-
-/*
-** Convert an CERTName into its RFC1485 encoded equivalent.
-** Returns a string that must be freed with PORT_Free().
-** This version produces a string for maximum human readability,
-** not for strict RFC compliance.
-*/
-extern char *CERT_NameToAscii(CERTName *name);
-
-/*
-** Convert an CERTName into its RFC1485 encoded equivalent.
-** Returns a string that must be freed with PORT_Free().
-** Caller chooses encoding rules.
-*/
-extern char *CERT_NameToAsciiInvertible(CERTName *name,
- CertStrictnessLevel strict);
-
-extern CERTAVA *CERT_CopyAVA(PLArenaPool *arena, CERTAVA *src);
-
-/* convert an OID to dotted-decimal representation */
-/* Returns a string that must be freed with PR_smprintf_free(). */
-extern char * CERT_GetOidString(const SECItem *oid);
-
-/*
-** Examine an AVA and return the tag that refers to it. The AVA tags are
-** defined as SEC_OID_AVA*.
-*/
-extern SECOidTag CERT_GetAVATag(CERTAVA *ava);
-
-/*
-** Compare two AVA's, returning the difference between them.
-*/
-extern SECComparison CERT_CompareAVA(const CERTAVA *a, const CERTAVA *b);
-
-/*
-** Create an RDN (relative-distinguished-name). The argument list is a
-** NULL terminated list of AVA's.
-*/
-extern CERTRDN *CERT_CreateRDN(PLArenaPool *arena, CERTAVA *avas, ...);
-
-/*
-** Make a copy of "src" storing it in "dest".
-*/
-extern SECStatus CERT_CopyRDN(PLArenaPool *arena, CERTRDN *dest, CERTRDN *src);
-
-/*
-** Destory an RDN object.
-** "rdn" the RDN to destroy
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void CERT_DestroyRDN(CERTRDN *rdn, PRBool freeit);
-
-/*
-** Add an AVA to an RDN.
-** "rdn" the RDN to add to
-** "ava" the AVA to add
-*/
-extern SECStatus CERT_AddAVA(PLArenaPool *arena, CERTRDN *rdn, CERTAVA *ava);
-
-/*
-** Compare two RDN's, returning the difference between them.
-*/
-extern SECComparison CERT_CompareRDN(const CERTRDN *a, const CERTRDN *b);
-
-/*
-** Create an X.500 style name using a NULL terminated list of RDN's.
-*/
-extern CERTName *CERT_CreateName(CERTRDN *rdn, ...);
-
-/*
-** Make a copy of "src" storing it in "dest". Memory is allocated in
-** "dest" for each of the appropriate sub objects. Memory is not freed in
-** "dest" before allocation is done (use CERT_DestroyName(dest, PR_FALSE) to
-** do that).
-*/
-extern SECStatus CERT_CopyName(PLArenaPool *arena, CERTName *dest, CERTName *src);
-
-/*
-** Destroy a Name object.
-** "name" the CERTName to destroy
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void CERT_DestroyName(CERTName *name);
-
-/*
-** Add an RDN to a name.
-** "name" the name to add the RDN to
-** "rdn" the RDN to add to name
-*/
-extern SECStatus CERT_AddRDN(CERTName *name, CERTRDN *rdn);
-
-/*
-** Compare two names, returning the difference between them.
-*/
-extern SECComparison CERT_CompareName(const CERTName *a, const CERTName *b);
-
-/*
-** Convert a CERTName into something readable
-*/
-extern char *CERT_FormatName (CERTName *name);
-
-/*
-** Convert a der-encoded integer to a hex printable string form.
-** Perhaps this should be a SEC function but it's only used for certs.
-*/
-extern char *CERT_Hexify (SECItem *i, int do_colon);
-
-/*
-** Converts DER string (with explicit length) into zString, if destination
-** buffer is big enough to receive it. Does quoting and/or escaping as
-** specified in RFC 1485. Input string must be single or multi-byte DER
-** character set, (ASCII, UTF8, or ISO 8851-x) not a wide character set.
-** Returns SECSuccess or SECFailure with error code set. If output buffer
-** is too small, sets error code SEC_ERROR_OUTPUT_LEN.
-*/
-extern SECStatus
-CERT_RFC1485_EscapeAndQuote(char *dst, int dstlen, char *src, int srclen);
-
-/******************************************************************************
- *
- * Certificate handling operations
- *
- *****************************************************************************/
-
-/*
-** Create a new validity object given two unix time values.
-** "notBefore" the time before which the validity is not valid
-** "notAfter" the time after which the validity is not valid
-*/
-extern CERTValidity *CERT_CreateValidity(PRTime notBefore, PRTime notAfter);
-
-/*
-** Destroy a validity object.
-** "v" the validity to destroy
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void CERT_DestroyValidity(CERTValidity *v);
-
-/*
-** Copy the "src" object to "dest". Memory is allocated in "dest" for
-** each of the appropriate sub-objects. Memory in "dest" is not freed
-** before memory is allocated (use CERT_DestroyValidity(v, PR_FALSE) to do
-** that).
-*/
-extern SECStatus CERT_CopyValidity
- (PLArenaPool *arena, CERTValidity *dest, CERTValidity *src);
-
-/*
-** The cert lib considers a cert or CRL valid if the "notBefore" time is
-** in the not-too-distant future, e.g. within the next 24 hours. This
-** prevents freshly issued certificates from being considered invalid
-** because the local system's time zone is incorrectly set.
-** The amount of "pending slop time" is adjustable by the application.
-** Units of SlopTime are seconds. Default is 86400 (24 hours).
-** Negative SlopTime values are not allowed.
-*/
-PRInt32 CERT_GetSlopTime(void);
-
-SECStatus CERT_SetSlopTime(PRInt32 slop);
-
-/*
-** Create a new certificate object. The result must be wrapped with an
-** CERTSignedData to create a signed certificate.
-** "serialNumber" the serial number
-** "issuer" the name of the certificate issuer
-** "validity" the validity period of the certificate
-** "req" the certificate request that prompted the certificate issuance
-*/
-extern CERTCertificate *
-CERT_CreateCertificate (unsigned long serialNumber, CERTName *issuer,
- CERTValidity *validity, CERTCertificateRequest *req);
-
-/*
-** Destroy a certificate object
-** "cert" the certificate to destroy
-** NOTE: certificate's are reference counted. This call decrements the
-** reference count, and if the result is zero, then the object is destroyed
-** and optionally freed.
-*/
-extern void CERT_DestroyCertificate(CERTCertificate *cert);
-
-/*
-** Make a shallow copy of a certificate "c". Just increments the
-** reference count on "c".
-*/
-extern CERTCertificate *CERT_DupCertificate(CERTCertificate *c);
-
-/*
-** Create a new certificate request. This result must be wrapped with an
-** CERTSignedData to create a signed certificate request.
-** "name" the subject name (who the certificate request is from)
-** "spki" describes/defines the public key the certificate is for
-** "attributes" if non-zero, some optional attribute data
-*/
-extern CERTCertificateRequest *
-CERT_CreateCertificateRequest (CERTName *name, CERTSubjectPublicKeyInfo *spki,
- SECItem **attributes);
-
-/*
-** Destroy a certificate-request object
-** "r" the certificate-request to destroy
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void CERT_DestroyCertificateRequest(CERTCertificateRequest *r);
-
-/*
-** Start adding extensions to a certificate request.
-*/
-void *
-CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req);
-
-/*
-** Reformat the certificate extension list into a CertificateRequest
-** attribute list.
-*/
-SECStatus
-CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req);
-
-/*
-** Extract the Extension Requests from a DER CertRequest attribute list.
-*/
-SECStatus
-CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
- CERTCertExtension ***exts);
-
-/*
-** Extract a public key object from a certificate
-*/
-extern SECKEYPublicKey *CERT_ExtractPublicKey(CERTCertificate *cert);
-
-/*
-** Retrieve the Key Type associated with the cert we're dealing with
-*/
-
-extern KeyType CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki);
-
-/*
-** Initialize the certificate database. This is called to create
-** the initial list of certificates in the database.
-*/
-extern SECStatus CERT_InitCertDB(CERTCertDBHandle *handle);
-
-extern int CERT_GetDBContentVersion(CERTCertDBHandle *handle);
-
-/*
-** Default certificate database routines
-*/
-extern void CERT_SetDefaultCertDB(CERTCertDBHandle *handle);
-
-extern CERTCertDBHandle *CERT_GetDefaultCertDB(void);
-
-extern CERTCertList *CERT_GetCertChainFromCert(CERTCertificate *cert,
- PRTime time,
- SECCertUsage usage);
-extern CERTCertificate *
-CERT_NewTempCertificate (CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER);
-
-
-/******************************************************************************
- *
- * X.500 Name handling operations
- *
- *****************************************************************************/
-
-/*
-** Create an AVA (attribute-value-assertion)
-** "arena" the memory arena to alloc from
-** "kind" is one of SEC_OID_AVA_*
-** "valueType" is one of DER_PRINTABLE_STRING, DER_IA5_STRING, or
-** DER_T61_STRING
-** "value" is the null terminated string containing the value
-*/
-extern CERTAVA *CERT_CreateAVA
- (PLArenaPool *arena, SECOidTag kind, int valueType, char *value);
-
-/*
-** Extract the Distinguished Name from a DER encoded certificate
-** "derCert" is the DER encoded certificate
-** "derName" is the SECItem that the name is returned in
-*/
-extern SECStatus CERT_NameFromDERCert(SECItem *derCert, SECItem *derName);
-
-/*
-** Extract the Issuers Distinguished Name from a DER encoded certificate
-** "derCert" is the DER encoded certificate
-** "derName" is the SECItem that the name is returned in
-*/
-extern SECStatus CERT_IssuerNameFromDERCert(SECItem *derCert,
- SECItem *derName);
-
-extern SECItem *
-CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest,
- PLArenaPool *arena);
-
-extern CERTGeneralName *
-CERT_DecodeGeneralName(PLArenaPool *reqArena, SECItem *encodedName,
- CERTGeneralName *genName);
-
-
-
-/*
-** Generate a database search key for a certificate, based on the
-** issuer and serial number.
-** "arena" the memory arena to alloc from
-** "derCert" the DER encoded certificate
-** "key" the returned key
-*/
-extern SECStatus CERT_KeyFromDERCert(PLArenaPool *reqArena, SECItem *derCert,
- SECItem *key);
-
-extern SECStatus CERT_KeyFromIssuerAndSN(PLArenaPool *arena, SECItem *issuer,
- SECItem *sn, SECItem *key);
-
-extern SECStatus CERT_SerialNumberFromDERCert(SECItem *derCert,
- SECItem *derName);
-
-
-/*
-** Generate a database search key for a crl, based on the
-** issuer.
-** "arena" the memory arena to alloc from
-** "derCrl" the DER encoded crl
-** "key" the returned key
-*/
-extern SECStatus CERT_KeyFromDERCrl(PLArenaPool *arena, SECItem *derCrl, SECItem *key);
-
-/*
-** Open the certificate database. Use callback to get name of database.
-*/
-extern SECStatus CERT_OpenCertDB(CERTCertDBHandle *handle, PRBool readOnly,
- CERTDBNameFunc namecb, void *cbarg);
-
-/* Open the certificate database. Use given filename for database. */
-extern SECStatus CERT_OpenCertDBFilename(CERTCertDBHandle *handle,
- char *certdbname, PRBool readOnly);
-
-/*
-** Open and initialize a cert database that is entirely in memory. This
-** can be used when the permanent database can not be opened or created.
-*/
-extern SECStatus CERT_OpenVolatileCertDB(CERTCertDBHandle *handle);
-
-/*
-** Extract the list of host names, host name patters, IP address strings
-** this cert is valid for.
-** This function does NOT return nicknames.
-** Type CERTCertNicknames is being used because it's a convenient
-** data structure to carry a list of strings and its count.
-*/
-extern CERTCertNicknames *
- CERT_GetValidDNSPatternsFromCert(CERTCertificate *cert);
-
-/*
-** Check the hostname to make sure that it matches the shexp that
-** is given in the common name of the certificate.
-*/
-extern SECStatus CERT_VerifyCertName(CERTCertificate *cert, const char *hostname);
-
-/*
-** Add a domain name to the list of names that the user has explicitly
-** allowed (despite cert name mismatches) for use with a server cert.
-*/
-extern SECStatus CERT_AddOKDomainName(CERTCertificate *cert, const char *hostname);
-
-/*
-** Decode a DER encoded certificate into an CERTCertificate structure
-** "derSignedCert" is the DER encoded signed certificate
-** "copyDER" is true if the DER should be copied, false if the
-** existing copy should be referenced
-** "nickname" is the nickname to use in the database. If it is NULL
-** then a temporary nickname is generated.
-*/
-extern CERTCertificate *
-CERT_DecodeDERCertificate (SECItem *derSignedCert, PRBool copyDER, char *nickname);
-/*
-** Decode a DER encoded CRL into a CERTSignedCrl structure
-** "derSignedCrl" is the DER encoded signed CRL.
-** "type" must be SEC_CRL_TYPE.
-*/
-#define SEC_CRL_TYPE 1
-#define SEC_KRL_TYPE 0 /* deprecated */
-
-extern CERTSignedCrl *
-CERT_DecodeDERCrl (PLArenaPool *arena, SECItem *derSignedCrl,int type);
-
-/*
- * same as CERT_DecodeDERCrl, plus allow options to be passed in
- */
-
-extern CERTSignedCrl *
-CERT_DecodeDERCrlWithFlags(PLArenaPool *narena, SECItem *derSignedCrl,
- int type, PRInt32 options);
-
-/* CRL options to pass */
-
-#define CRL_DECODE_DEFAULT_OPTIONS 0x00000000
-
-/* when CRL_DECODE_DONT_COPY_DER is set, the DER is not copied . The
- application must then keep derSignedCrl until it destroys the
- CRL . Ideally, it should allocate derSignedCrl in an arena
- and pass that arena in as the first argument to
- CERT_DecodeDERCrlWithFlags */
-
-#define CRL_DECODE_DONT_COPY_DER 0x00000001
-#define CRL_DECODE_SKIP_ENTRIES 0x00000002
-#define CRL_DECODE_KEEP_BAD_CRL 0x00000004
-#define CRL_DECODE_ADOPT_HEAP_DER 0x00000008
-
-/* complete the decoding of a partially decoded CRL, ie. decode the
- entries. Note that entries is an optional field in a CRL, so the
- "entries" pointer in CERTCrlStr may still be NULL even after
- function returns SECSuccess */
-
-extern SECStatus CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl);
-
-/* Validate CRL then import it to the dbase. If there is already a CRL with the
- * same CA in the dbase, it will be replaced if derCRL is more up to date.
- * If the process successes, a CRL will be returned. Otherwise, a NULL will
- * be returned. The caller should call PORT_GetError() for the exactly error
- * code.
- */
-extern CERTSignedCrl *
-CERT_ImportCRL (CERTCertDBHandle *handle, SECItem *derCRL, char *url,
- int type, void * wincx);
-
-extern void CERT_DestroyCrl (CERTSignedCrl *crl);
-
-/* this is a hint to flush the CRL cache. crlKey is the DER subject of
- the issuer (CA). */
-void CERT_CRLCacheRefreshIssuer(CERTCertDBHandle* dbhandle, SECItem* crlKey);
-
-/* add the specified DER CRL object to the CRL cache. Doing so will allow
- certificate verification functions (such as CERT_VerifyCertificate)
- to automatically find and make use of this CRL object.
- Once a CRL is added to the CRL cache, the application must hold on to
- the object's memory, because the cache will reference it directly. The
- application can only free the object after it calls CERT_UncacheCRL to
- remove it from the CRL cache.
-*/
-SECStatus CERT_CacheCRL(CERTCertDBHandle* dbhandle, SECItem* newcrl);
-
-/* remove a previously added CRL object from the CRL cache. It is OK
- for the application to free the memory after a successful removal
-*/
-SECStatus CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* oldcrl);
-
-/*
-** Find a certificate in the database
-** "key" is the database key to look for
-*/
-extern CERTCertificate *CERT_FindCertByKey(CERTCertDBHandle *handle, SECItem *key);
-
-/*
-** Find a certificate in the database by name
-** "name" is the distinguished name to look up
-*/
-extern CERTCertificate *
-CERT_FindCertByName (CERTCertDBHandle *handle, SECItem *name);
-
-/*
-** Find a certificate in the database by name
-** "name" is the distinguished name to look up (in ascii)
-*/
-extern CERTCertificate *
-CERT_FindCertByNameString (CERTCertDBHandle *handle, char *name);
-
-/*
-** Find a certificate in the database by name and keyid
-** "name" is the distinguished name to look up
-** "keyID" is the value of the subjectKeyID to match
-*/
-extern CERTCertificate *
-CERT_FindCertByKeyID (CERTCertDBHandle *handle, SECItem *name, SECItem *keyID);
-
-/*
-** Generate a certificate key from the issuer and serialnumber, then look it
-** up in the database. Return the cert if found.
-** "issuerAndSN" is the issuer and serial number to look for
-*/
-extern CERTCertificate *
-CERT_FindCertByIssuerAndSN (CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN);
-
-/*
-** Find a certificate in the database by a subject key ID
-** "subjKeyID" is the subject Key ID to look for
-*/
-extern CERTCertificate *
-CERT_FindCertBySubjectKeyID (CERTCertDBHandle *handle, SECItem *subjKeyID);
-
-/*
-** Encode Certificate SKID (Subject Key ID) extension.
-**
-*/
-extern SECStatus
-CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
- SECItem *encodedValue);
-
-/*
-** Find a certificate in the database by a nickname
-** "nickname" is the ascii string nickname to look for
-*/
-extern CERTCertificate *
-CERT_FindCertByNickname (CERTCertDBHandle *handle, const char *nickname);
-
-/*
-** Find a certificate in the database by a DER encoded certificate
-** "derCert" is the DER encoded certificate
-*/
-extern CERTCertificate *
-CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert);
-
-/*
-** Find a certificate in the database by a email address
-** "emailAddr" is the email address to look up
-*/
-CERTCertificate *
-CERT_FindCertByEmailAddr(CERTCertDBHandle *handle, char *emailAddr);
-
-/*
-** Find a certificate in the database by a email address or nickname
-** "name" is the email address or nickname to look up
-*/
-CERTCertificate *
-CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name);
-
-/*
-** Find a certificate in the database by a email address or nickname
-** and require it to have the given usage.
-** "name" is the email address or nickname to look up
-*/
-CERTCertificate *
-CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
- const char *name,
- SECCertUsage lookingForUsage);
-
-/*
-** Find a certificate in the database by a digest of a subject public key
-** "spkDigest" is the digest to look up
-*/
-extern CERTCertificate *
-CERT_FindCertBySPKDigest(CERTCertDBHandle *handle, SECItem *spkDigest);
-
-/*
- * Find the issuer of a cert
- */
-CERTCertificate *
-CERT_FindCertIssuer(CERTCertificate *cert, PRTime validTime, SECCertUsage usage);
-
-/*
-** Check the validity times of a certificate vs. time 't', allowing
-** some slop for broken clocks and stuff.
-** "cert" is the certificate to be checked
-** "t" is the time to check against
-** "allowOverride" if true then check to see if the invalidity has
-** been overridden by the user.
-*/
-extern SECCertTimeValidity CERT_CheckCertValidTimes(CERTCertificate *cert,
- PRTime t,
- PRBool allowOverride);
-
-/*
-** WARNING - this function is deprecated, and will either go away or have
-** a new API in the near future.
-**
-** Check the validity times of a certificate vs. the current time, allowing
-** some slop for broken clocks and stuff.
-** "cert" is the certificate to be checked
-*/
-extern SECStatus CERT_CertTimesValid(CERTCertificate *cert);
-
-/*
-** Extract the validity times from a certificate
-** "c" is the certificate
-** "notBefore" is the start of the validity period
-** "notAfter" is the end of the validity period
-*/
-extern SECStatus
-CERT_GetCertTimes (CERTCertificate *c, PRTime *notBefore, PRTime *notAfter);
-
-/*
-** Extract the issuer and serial number from a certificate
-*/
-extern CERTIssuerAndSN *CERT_GetCertIssuerAndSN(PLArenaPool *,
- CERTCertificate *);
-
-/*
-** verify the signature of a signed data object with a given certificate
-** "sd" the signed data object to be verified
-** "cert" the certificate to use to check the signature
-*/
-extern SECStatus CERT_VerifySignedData(CERTSignedData *sd,
- CERTCertificate *cert,
- PRTime t,
- void *wincx);
-/*
-** verify the signature of a signed data object with the given DER publickey
-*/
-extern SECStatus
-CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd,
- CERTSubjectPublicKeyInfo *pubKeyInfo,
- void *wincx);
-
-/*
-** verify the signature of a signed data object with a SECKEYPublicKey.
-*/
-extern SECStatus
-CERT_VerifySignedDataWithPublicKey(CERTSignedData *sd,
- SECKEYPublicKey *pubKey, void *wincx);
-
-/*
-** NEW FUNCTIONS with new bit-field-FIELD SECCertificateUsage - please use
-** verify a certificate by checking validity times against a certain time,
-** that we trust the issuer, and that the signature on the certificate is
-** valid.
-** "cert" the certificate to verify
-** "checkSig" only check signatures if true
-*/
-extern SECStatus
-CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertificateUsage requiredUsages,
- PRTime t, void *wincx, CERTVerifyLog *log,
- SECCertificateUsage* returnedUsages);
-
-/* same as above, but uses current time */
-extern SECStatus
-CERT_VerifyCertificateNow(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertificateUsage requiredUsages,
- void *wincx, SECCertificateUsage* returnedUsages);
-
-/*
-** Verify that a CA cert can certify some (unspecified) leaf cert for a given
-** purpose. This is used by UI code to help identify where a chain may be
-** broken and why. This takes identical parameters to CERT_VerifyCert
-*/
-extern SECStatus
-CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, PRTime t,
- void *wincx, CERTVerifyLog *log);
-
-/*
-** OLD OBSOLETE FUNCTIONS with enum SECCertUsage - DO NOT USE FOR NEW CODE
-** verify a certificate by checking validity times against a certain time,
-** that we trust the issuer, and that the signature on the certificate is
-** valid.
-** "cert" the certificate to verify
-** "checkSig" only check signatures if true
-*/
-extern SECStatus
-CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, PRTime t,
- void *wincx, CERTVerifyLog *log);
-
-/* same as above, but uses current time */
-extern SECStatus
-CERT_VerifyCertNow(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, void *wincx);
-
-SECStatus
-CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, PRTime t,
- void *wincx, CERTVerifyLog *log);
-
-/*
-** Read a base64 ascii encoded DER certificate and convert it to our
-** internal format.
-** "certstr" is a null-terminated string containing the certificate
-*/
-extern CERTCertificate *CERT_ConvertAndDecodeCertificate(char *certstr);
-
-/*
-** Read a certificate in some foreign format, and convert it to our
-** internal format.
-** "certbuf" is the buffer containing the certificate
-** "certlen" is the length of the buffer
-** NOTE - currently supports netscape base64 ascii encoded raw certs
-** and netscape binary DER typed files.
-*/
-extern CERTCertificate *CERT_DecodeCertFromPackage(char *certbuf, int certlen);
-
-extern SECStatus
-CERT_ImportCAChain (SECItem *certs, int numcerts, SECCertUsage certUsage);
-
-extern SECStatus
-CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage);
-
-/*
-** Read a certificate chain in some foreign format, and pass it to a
-** callback function.
-** "certbuf" is the buffer containing the certificate
-** "certlen" is the length of the buffer
-** "f" is the callback function
-** "arg" is the callback argument
-*/
-typedef SECStatus (PR_CALLBACK *CERTImportCertificateFunc)
- (void *arg, SECItem **certs, int numcerts);
-
-extern SECStatus
-CERT_DecodeCertPackage(char *certbuf, int certlen, CERTImportCertificateFunc f,
- void *arg);
-
-/*
-** Returns the value of an AVA. This was a formerly static
-** function that has been exposed due to the need to decode
-** and convert unicode strings to UTF8.
-**
-** XXX This function resides in certhtml.c, should it be
-** moved elsewhere?
-*/
-extern SECItem *CERT_DecodeAVAValue(const SECItem *derAVAValue);
-
-
-
-/*
-** extract various element strings from a distinguished name.
-** "name" the distinguished name
-*/
-
-extern char *CERT_GetCertificateEmailAddress(CERTCertificate *cert);
-
-extern char *CERT_GetCertEmailAddress(CERTName *name);
-
-extern const char * CERT_GetFirstEmailAddress(CERTCertificate * cert);
-
-extern const char * CERT_GetNextEmailAddress(CERTCertificate * cert,
- const char * prev);
-
-/* The return value must be freed with PORT_Free. */
-extern char *CERT_GetCommonName(CERTName *name);
-
-extern char *CERT_GetCountryName(CERTName *name);
-
-extern char *CERT_GetLocalityName(CERTName *name);
-
-extern char *CERT_GetStateName(CERTName *name);
-
-extern char *CERT_GetOrgName(CERTName *name);
-
-extern char *CERT_GetOrgUnitName(CERTName *name);
-
-extern char *CERT_GetDomainComponentName(CERTName *name);
-
-extern char *CERT_GetCertUid(CERTName *name);
-
-/* manipulate the trust parameters of a certificate */
-
-extern SECStatus CERT_GetCertTrust(CERTCertificate *cert, CERTCertTrust *trust);
-
-extern SECStatus
-CERT_ChangeCertTrust (CERTCertDBHandle *handle, CERTCertificate *cert,
- CERTCertTrust *trust);
-
-extern SECStatus
-CERT_ChangeCertTrustByUsage(CERTCertDBHandle *certdb, CERTCertificate *cert,
- SECCertUsage usage);
-
-/*************************************************************************
- *
- * manipulate the extensions of a certificate
- *
- ************************************************************************/
-
-/*
-** Set up a cert for adding X509v3 extensions. Returns an opaque handle
-** used by the next two routines.
-** "cert" is the certificate we are adding extensions to
-*/
-extern void *CERT_StartCertExtensions(CERTCertificate *cert);
-
-/*
-** Add an extension to a certificate.
-** "exthandle" is the handle returned by the previous function
-** "idtag" is the integer tag for the OID that should ID this extension
-** "value" is the value of the extension
-** "critical" is the critical extension flag
-** "copyData" is a flag indicating whether the value data should be
-** copied.
-*/
-extern SECStatus CERT_AddExtension (void *exthandle, int idtag,
- SECItem *value, PRBool critical, PRBool copyData);
-
-extern SECStatus CERT_AddExtensionByOID (void *exthandle, SECItem *oid,
- SECItem *value, PRBool critical, PRBool copyData);
-
-extern SECStatus CERT_EncodeAndAddExtension
- (void *exthandle, int idtag, void *value, PRBool critical,
- const SEC_ASN1Template *atemplate);
-
-extern SECStatus CERT_EncodeAndAddBitStrExtension
- (void *exthandle, int idtag, SECItem *value, PRBool critical);
-
-
-extern SECStatus
-CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue);
-
-
-/*
-** Finish adding cert extensions. Does final processing on extension
-** data, putting it in the right format, and freeing any temporary
-** storage.
-** "exthandle" is the handle used to add extensions to a certificate
-*/
-extern SECStatus CERT_FinishExtensions(void *exthandle);
-
-/*
-** Merge an external list of extensions into a cert's extension list, adding one
-** only when its OID matches none of the cert's existing extensions. Call this
-** immediately before calling CERT_FinishExtensions().
-*/
-SECStatus
-CERT_MergeExtensions(void *exthandle, CERTCertExtension **exts);
-
-/* If the extension is found, return its criticality and value.
-** This allocate storage for the returning extension value.
-*/
-extern SECStatus CERT_GetExtenCriticality
- (CERTCertExtension **extensions, int tag, PRBool *isCritical);
-
-extern void
-CERT_DestroyOidSequence(CERTOidSequence *oidSeq);
-
-/****************************************************************************
- *
- * DER encode and decode extension values
- *
- ****************************************************************************/
-
-/* Encode the value of the basicConstraint extension.
-** arena - where to allocate memory for the encoded value.
-** value - extension value to encode
-** encodedValue - output encoded value
-*/
-extern SECStatus CERT_EncodeBasicConstraintValue
- (PLArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue);
-
-/*
-** Encode the value of the authorityKeyIdentifier extension.
-*/
-extern SECStatus CERT_EncodeAuthKeyID
- (PLArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue);
-
-/*
-** Encode the value of the crlDistributionPoints extension.
-*/
-extern SECStatus CERT_EncodeCRLDistributionPoints
- (PLArenaPool *arena, CERTCrlDistributionPoints *value,SECItem *derValue);
-
-/*
-** Decodes a DER encoded basicConstaint extension value into a readable format
-** value - decoded value
-** encodedValue - value to decoded
-*/
-extern SECStatus CERT_DecodeBasicConstraintValue
- (CERTBasicConstraints *value, SECItem *encodedValue);
-
-/* Decodes a DER encoded authorityKeyIdentifier extension value into a
-** readable format.
-** arena - where to allocate memory for the decoded value
-** encodedValue - value to be decoded
-** Returns a CERTAuthKeyID structure which contains the decoded value
-*/
-extern CERTAuthKeyID *CERT_DecodeAuthKeyID
- (PLArenaPool *arena, SECItem *encodedValue);
-
-
-/* Decodes a DER encoded crlDistributionPoints extension value into a
-** readable format.
-** arena - where to allocate memory for the decoded value
-** der - value to be decoded
-** Returns a CERTCrlDistributionPoints structure which contains the
-** decoded value
-*/
-extern CERTCrlDistributionPoints * CERT_DecodeCRLDistributionPoints
- (PLArenaPool *arena, SECItem *der);
-
-/* Extract certain name type from a generalName */
-extern void *CERT_GetGeneralNameByType
- (CERTGeneralName *genNames, CERTGeneralNameType type, PRBool derFormat);
-
-
-extern CERTOidSequence *
-CERT_DecodeOidSequence(SECItem *seqItem);
-
-
-
-
-/****************************************************************************
- *
- * Find extension values of a certificate
- *
- ***************************************************************************/
-
-extern SECStatus CERT_FindCertExtension
- (CERTCertificate *cert, int tag, SECItem *value);
-
-extern SECStatus CERT_FindNSCertTypeExtension
- (CERTCertificate *cert, SECItem *value);
-
-extern char * CERT_FindNSStringExtension (CERTCertificate *cert, int oidtag);
-
-extern SECStatus CERT_FindIssuerCertExtension
- (CERTCertificate *cert, int tag, SECItem *value);
-
-extern SECStatus CERT_FindCertExtensionByOID
- (CERTCertificate *cert, SECItem *oid, SECItem *value);
-
-extern char *CERT_FindCertURLExtension (CERTCertificate *cert, int tag,
- int catag);
-
-/* Returns the decoded value of the authKeyID extension.
-** Note that this uses passed in the arena to allocate storage for the result
-*/
-extern CERTAuthKeyID * CERT_FindAuthKeyIDExten (PLArenaPool *arena,CERTCertificate *cert);
-
-/* Returns the decoded value of the basicConstraint extension.
- */
-extern SECStatus CERT_FindBasicConstraintExten
- (CERTCertificate *cert, CERTBasicConstraints *value);
-
-/* Returns the decoded value of the crlDistributionPoints extension.
-** Note that the arena in cert is used to allocate storage for the result
-*/
-extern CERTCrlDistributionPoints * CERT_FindCRLDistributionPoints
- (CERTCertificate *cert);
-
-/* Returns value of the keyUsage extension. This uses PR_Alloc to allocate
-** buffer for the decoded value. The caller should free up the storage
-** allocated in value->data.
-*/
-extern SECStatus CERT_FindKeyUsageExtension (CERTCertificate *cert,
- SECItem *value);
-
-/* Return the decoded value of the subjectKeyID extension. The caller should
-** free up the storage allocated in retItem->data.
-*/
-extern SECStatus CERT_FindSubjectKeyIDExtension (CERTCertificate *cert,
- SECItem *retItem);
-
-/*
-** If cert is a v3 certificate, and a critical keyUsage extension is included,
-** then check the usage against the extension value. If a non-critical
-** keyUsage extension is included, this will return SECSuccess without
-** checking, since the extension is an advisory field, not a restriction.
-** If cert is not a v3 certificate, this will return SECSuccess.
-** cert - certificate
-** usage - one of the x.509 v3 the Key Usage Extension flags
-*/
-extern SECStatus CERT_CheckCertUsage (CERTCertificate *cert,
- unsigned char usage);
-
-/****************************************************************************
- *
- * CRL v2 Extensions supported routines
- *
- ****************************************************************************/
-
-extern SECStatus CERT_FindCRLExtensionByOID
- (CERTCrl *crl, SECItem *oid, SECItem *value);
-
-extern SECStatus CERT_FindCRLExtension
- (CERTCrl *crl, int tag, SECItem *value);
-
-extern SECStatus
- CERT_FindInvalidDateExten (CERTCrl *crl, PRTime *value);
-
-/*
-** Set up a crl for adding X509v3 extensions. Returns an opaque handle
-** used by routines that take an exthandle (void*) argument .
-** "crl" is the CRL we are adding extensions to
-*/
-extern void *CERT_StartCRLExtensions(CERTCrl *crl);
-
-/*
-** Set up a crl entry for adding X509v3 extensions. Returns an opaque handle
-** used by routines that take an exthandle (void*) argument .
-** "crl" is the crl we are adding certs entries to
-** "entry" is the crl entry we are adding extensions to
-*/
-extern void *CERT_StartCRLEntryExtensions(CERTCrl *crl, CERTCrlEntry *entry);
-
-extern CERTCertNicknames *CERT_GetCertNicknames (CERTCertDBHandle *handle,
- int what, void *wincx);
-
-/*
-** Finds the crlNumber extension and decodes its value into 'value'
-*/
-extern SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl,
- SECItem *value);
-
-extern SECStatus CERT_FindCRLEntryReasonExten (CERTCrlEntry *crlEntry,
- CERTCRLEntryReasonCode *value);
-
-extern void CERT_FreeNicknames(CERTCertNicknames *nicknames);
-
-extern PRBool CERT_CompareCerts(CERTCertificate *c1, CERTCertificate *c2);
-
-extern PRBool CERT_CompareCertsForRedirection(CERTCertificate *c1,
- CERTCertificate *c2);
-
-/*
-** Generate an array of the Distinguished Names that the given cert database
-** "trusts"
-*/
-extern CERTDistNames *CERT_GetSSLCACerts(CERTCertDBHandle *handle);
-
-extern void CERT_FreeDistNames(CERTDistNames *names);
-
-/* Duplicate distinguished name array */
-extern CERTDistNames *CERT_DupDistNames(CERTDistNames *orig);
-
-/*
-** Generate an array of Distinguished names from an array of nicknames
-*/
-extern CERTDistNames *CERT_DistNamesFromNicknames
- (CERTCertDBHandle *handle, char **nicknames, int nnames);
-
-/*
-** Generate an array of Distinguished names from a list of certs.
-*/
-extern CERTDistNames *CERT_DistNamesFromCertList(CERTCertList *list);
-
-/*
-** Generate a certificate chain from a certificate.
-*/
-extern CERTCertificateList *
-CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,
- PRBool includeRoot);
-
-extern CERTCertificateList *
-CERT_CertListFromCert(CERTCertificate *cert);
-
-extern CERTCertificateList *
-CERT_DupCertList(const CERTCertificateList * oldList);
-
-extern void CERT_DestroyCertificateList(CERTCertificateList *list);
-
-/*
-** is cert a user cert? i.e. does it have CERTDB_USER trust,
-** i.e. a private key?
-*/
-PRBool CERT_IsUserCert(CERTCertificate* cert);
-
-/* is cert a newer than cert b? */
-PRBool CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb);
-
-/* currently a stub for address book */
-PRBool
-CERT_IsCertRevoked(CERTCertificate *cert);
-
-void
-CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts);
-
-/* convert an email address to lower case */
-char *CERT_FixupEmailAddr(const char *emailAddr);
-
-/* decode string representation of trust flags into trust struct */
-SECStatus
-CERT_DecodeTrustString(CERTCertTrust *trust, const char *trusts);
-
-/* encode trust struct into string representation of trust flags */
-char *
-CERT_EncodeTrustString(CERTCertTrust *trust);
-
-/* find the next or prev cert in a subject list */
-CERTCertificate *
-CERT_PrevSubjectCert(CERTCertificate *cert);
-CERTCertificate *
-CERT_NextSubjectCert(CERTCertificate *cert);
-
-/*
- * import a collection of certs into the temporary or permanent cert
- * database
- */
-SECStatus
-CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
- unsigned int ncerts, SECItem **derCerts,
- CERTCertificate ***retCerts, PRBool keepCerts,
- PRBool caOnly, char *nickname);
-
-char *
-CERT_MakeCANickname(CERTCertificate *cert);
-
-PRBool
-CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype);
-
-PRBool
-CERT_IsCADERCert(SECItem *derCert, unsigned int *rettype);
-
-PRBool
-CERT_IsRootDERCert(SECItem *derCert);
-
-SECStatus
-CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
- SECItem *profileTime);
-
-/*
- * find the smime symmetric capabilities profile for a given cert
- */
-SECItem *
-CERT_FindSMimeProfile(CERTCertificate *cert);
-
-SECStatus
-CERT_AddNewCerts(CERTCertDBHandle *handle);
-
-CERTCertificatePolicies *
-CERT_DecodeCertificatePoliciesExtension(SECItem *extnValue);
-
-void
-CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies);
-
-CERTCertificatePolicyMappings *
-CERT_DecodePolicyMappingsExtension(SECItem *encodedCertPolicyMaps);
-
-SECStatus
-CERT_DestroyPolicyMappingsExtension(CERTCertificatePolicyMappings *mappings);
-
-SECStatus
-CERT_DecodePolicyConstraintsExtension(
- CERTCertificatePolicyConstraints *decodedValue, SECItem *encodedValue);
-
-SECStatus CERT_DecodeInhibitAnyExtension
- (CERTCertificateInhibitAny *decodedValue, SECItem *extnValue);
-
-CERTUserNotice *
-CERT_DecodeUserNotice(SECItem *noticeItem);
-
-extern CERTGeneralName *
-CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName);
-
-extern CERTNameConstraints *
-CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
- SECItem *encodedConstraints);
-
-/* returns addr of a NULL termainated array of pointers to CERTAuthInfoAccess */
-extern CERTAuthInfoAccess **
-CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
- SECItem *encodedExtension);
-
-extern CERTPrivKeyUsagePeriod *
-CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue);
-
-extern CERTGeneralName *
-CERT_GetNextGeneralName(CERTGeneralName *current);
-
-extern CERTGeneralName *
-CERT_GetPrevGeneralName(CERTGeneralName *current);
-
-CERTNameConstraint *
-CERT_GetNextNameConstraint(CERTNameConstraint *current);
-
-CERTNameConstraint *
-CERT_GetPrevNameConstraint(CERTNameConstraint *current);
-
-void
-CERT_DestroyUserNotice(CERTUserNotice *userNotice);
-
-typedef char * (* CERTPolicyStringCallback)(char *org,
- unsigned long noticeNumber,
- void *arg);
-void
-CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg);
-
-char *
-CERT_GetCertCommentString(CERTCertificate *cert);
-
-PRBool
-CERT_GovtApprovedBitSet(CERTCertificate *cert);
-
-SECStatus
-CERT_AddPermNickname(CERTCertificate *cert, char *nickname);
-
-CERTCertList *
-CERT_MatchUserCert(CERTCertDBHandle *handle,
- SECCertUsage usage,
- int nCANames, char **caNames,
- void *proto_win);
-
-CERTCertList *
-CERT_NewCertList(void);
-
-void
-CERT_DestroyCertList(CERTCertList *certs);
-
-/* remove the node and free the cert */
-void
-CERT_RemoveCertListNode(CERTCertListNode *node);
-
-SECStatus
-CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert);
-
-SECStatus
-CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert);
-
-SECStatus
-CERT_AddCertToListTailWithData(CERTCertList *certs, CERTCertificate *cert,
- void *appData);
-
-SECStatus
-CERT_AddCertToListHeadWithData(CERTCertList *certs, CERTCertificate *cert,
- void *appData);
-
-typedef PRBool (* CERTSortCallback)(CERTCertificate *certa,
- CERTCertificate *certb,
- void *arg);
-SECStatus
-CERT_AddCertToListSorted(CERTCertList *certs, CERTCertificate *cert,
- CERTSortCallback f, void *arg);
-
-/* callback for CERT_AddCertToListSorted that sorts based on validity
- * period and a given time.
- */
-PRBool
-CERT_SortCBValidity(CERTCertificate *certa,
- CERTCertificate *certb,
- void *arg);
-
-SECStatus
-CERT_CheckForEvilCert(CERTCertificate *cert);
-
-CERTGeneralName *
-CERT_GetCertificateNames(CERTCertificate *cert, PLArenaPool *arena);
-
-CERTGeneralName *
-CERT_GetConstrainedCertificateNames(CERTCertificate *cert, PLArenaPool *arena,
- PRBool includeSubjectCommonName);
-
-/*
- * Creates or adds to a list of all certs with a give subject name, sorted by
- * validity time, newest first. Invalid certs are considered older than
- * valid certs. If validOnly is set, do not include invalid certs on list.
- */
-CERTCertList *
-CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle,
- SECItem *name, PRTime sorttime, PRBool validOnly);
-
-/*
- * remove certs from a list that don't have keyUsage and certType
- * that match the given usage.
- */
-SECStatus
-CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage,
- PRBool ca);
-
-/*
- * check the key usage of a cert against a set of required values
- */
-SECStatus
-CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage);
-
-/*
- * return required key usage and cert type based on cert usage
- */
-SECStatus
-CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage,
- PRBool ca,
- unsigned int *retKeyUsage,
- unsigned int *retCertType);
-/*
- * return required trust flags for various cert usages for CAs
- */
-SECStatus
-CERT_TrustFlagsForCACertUsage(SECCertUsage usage,
- unsigned int *retFlags,
- SECTrustType *retTrustType);
-
-/*
- * Find all user certificates that match the given criteria.
- *
- * "handle" - database to search
- * "usage" - certificate usage to match
- * "oneCertPerName" - if set then only return the "best" cert per
- * name
- * "validOnly" - only return certs that are curently valid
- * "proto_win" - window handle passed to pkcs11
- */
-CERTCertList *
-CERT_FindUserCertsByUsage(CERTCertDBHandle *handle,
- SECCertUsage usage,
- PRBool oneCertPerName,
- PRBool validOnly,
- void *proto_win);
-
-/*
- * Find a user certificate that matchs the given criteria.
- *
- * "handle" - database to search
- * "nickname" - nickname to match
- * "usage" - certificate usage to match
- * "validOnly" - only return certs that are curently valid
- * "proto_win" - window handle passed to pkcs11
- */
-CERTCertificate *
-CERT_FindUserCertByUsage(CERTCertDBHandle *handle,
- const char *nickname,
- SECCertUsage usage,
- PRBool validOnly,
- void *proto_win);
-
-/*
- * Filter a list of certificates, removing those certs that do not have
- * one of the named CA certs somewhere in their cert chain.
- *
- * "certList" - the list of certificates to filter
- * "nCANames" - number of CA names
- * "caNames" - array of CA names in string(rfc 1485) form
- * "usage" - what use the certs are for, this is used when
- * selecting CA certs
- */
-SECStatus
-CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames,
- char **caNames, SECCertUsage usage);
-
-/*
- * Filter a list of certificates, removing those certs that aren't user certs
- */
-SECStatus
-CERT_FilterCertListForUserCerts(CERTCertList *certList);
-
-/*
- * Collect the nicknames from all certs in a CertList. If the cert is not
- * valid, append a string to that nickname.
- *
- * "certList" - the list of certificates
- * "expiredString" - the string to append to the nickname of any expired cert
- * "notYetGoodString" - the string to append to the nickname of any cert
- * that is not yet valid
- */
-CERTCertNicknames *
-CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString,
- char *notYetGoodString);
-
-/*
- * Extract the nickname from a nickmake string that may have either
- * expiredString or notYetGoodString appended.
- *
- * Args:
- * "namestring" - the string containing the nickname, and possibly
- * one of the validity label strings
- * "expiredString" - the expired validity label string
- * "notYetGoodString" - the not yet good validity label string
- *
- * Returns the raw nickname
- */
-char *
-CERT_ExtractNicknameString(char *namestring, char *expiredString,
- char *notYetGoodString);
-
-/*
- * Given a certificate, return a string containing the nickname, and possibly
- * one of the validity strings, based on the current validity state of the
- * certificate.
- *
- * "arena" - arena to allocate returned string from. If NULL, then heap
- * is used.
- * "cert" - the cert to get nickname from
- * "expiredString" - the string to append to the nickname if the cert is
- * expired.
- * "notYetGoodString" - the string to append to the nickname if the cert is
- * not yet good.
- */
-char *
-CERT_GetCertNicknameWithValidity(PLArenaPool *arena, CERTCertificate *cert,
- char *expiredString, char *notYetGoodString);
-
-/*
- * Return the string representation of a DER encoded distinguished name
- * "dername" - The DER encoded name to convert
- */
-char *
-CERT_DerNameToAscii(SECItem *dername);
-
-/*
- * Supported usage values and types:
- * certUsageSSLClient
- * certUsageSSLServer
- * certUsageSSLServerWithStepUp
- * certUsageEmailSigner
- * certUsageEmailRecipient
- * certUsageObjectSigner
- */
-
-CERTCertificate *
-CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName,
- CERTCertOwner owner, SECCertUsage usage,
- PRBool preferTrusted, PRTime validTime, PRBool validOnly);
-
-/*
- * Acquire the global lock on the cert database.
- * This lock is currently used for the following operations:
- * adding or deleting a cert to either the temp or perm databases
- * converting a temp to perm or perm to temp
- * changing(maybe just adding?) the trust of a cert
- * adjusting the reference count of a cert
- */
-void
-CERT_LockDB(CERTCertDBHandle *handle);
-
-/*
- * Free the global cert database lock.
- */
-void
-CERT_UnlockDB(CERTCertDBHandle *handle);
-
-/*
- * Get the certificate status checking configuratino data for
- * the certificate database
- */
-CERTStatusConfig *
-CERT_GetStatusConfig(CERTCertDBHandle *handle);
-
-/*
- * Set the certificate status checking information for the
- * database. The input structure becomes part of the certificate
- * database and will be freed by calling the 'Destroy' function in
- * the configuration object.
- */
-void
-CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *config);
-
-
-
-/*
- * Acquire the cert reference count lock
- * There is currently one global lock for all certs, but I'm putting a cert
- * arg here so that it will be easy to make it per-cert in the future if
- * that turns out to be necessary.
- */
-void
-CERT_LockCertRefCount(CERTCertificate *cert);
-
-/*
- * Free the cert reference count lock
- */
-void
-CERT_UnlockCertRefCount(CERTCertificate *cert);
-
-/*
- * Acquire the cert trust lock
- * There is currently one global lock for all certs, but I'm putting a cert
- * arg here so that it will be easy to make it per-cert in the future if
- * that turns out to be necessary.
- */
-void
-CERT_LockCertTrust(CERTCertificate *cert);
-
-/*
- * Free the cert trust lock
- */
-void
-CERT_UnlockCertTrust(CERTCertificate *cert);
-
-/*
- * Digest the cert's subject public key using the specified algorithm.
- * The necessary storage for the digest data is allocated. If "fill" is
- * non-null, the data is put there, otherwise a SECItem is allocated.
- * Allocation from "arena" if it is non-null, heap otherwise. Any problem
- * results in a NULL being returned (and an appropriate error set).
- */
-extern SECItem *
-CERT_GetSPKIDigest(PLArenaPool *arena, const CERTCertificate *cert,
- SECOidTag digestAlg, SECItem *fill);
-
-
-SECStatus CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer,
- const SECItem* dp, PRTime t, void* wincx);
-
-
-/*
- * Add a CERTNameConstraint to the CERTNameConstraint list
- */
-extern CERTNameConstraint *
-CERT_AddNameConstraint(CERTNameConstraint *list,
- CERTNameConstraint *constraint);
-
-/*
- * Allocate space and copy CERTNameConstraint from src to dest.
- * Arena is used to allocate result(if dest eq NULL) and its members
- * SECItem data.
- */
-extern CERTNameConstraint *
-CERT_CopyNameConstraint(PLArenaPool *arena,
- CERTNameConstraint *dest,
- CERTNameConstraint *src);
-
-/*
- * Verify name against all the constraints relevant to that type of
- * the name.
- */
-extern SECStatus
-CERT_CheckNameSpace(PLArenaPool *arena,
- CERTNameConstraints *constraints,
- CERTGeneralName *currentName);
-
-/*
- * Extract and allocate the name constraints extension from the CA cert.
- */
-extern SECStatus
-CERT_FindNameConstraintsExten(PLArenaPool *arena,
- CERTCertificate *cert,
- CERTNameConstraints **constraints);
-
-/*
- * Initialize a new GERTGeneralName fields (link)
- */
-extern CERTGeneralName *
-CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type);
-
-/*
- * PKIX extension encoding routines
- */
-extern SECStatus
-CERT_EncodePolicyConstraintsExtension(PLArenaPool *arena,
- CERTCertificatePolicyConstraints *constr,
- SECItem *dest);
-extern SECStatus
-CERT_EncodeInhibitAnyExtension(PLArenaPool *arena,
- CERTCertificateInhibitAny *inhibitAny,
- SECItem *dest);
-extern SECStatus
-CERT_EncodePolicyMappingExtension(PLArenaPool *arena,
- CERTCertificatePolicyMappings *maps,
- SECItem *dest);
-
-extern SECStatus CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
- CERTAuthInfoAccess **info,
- SECItem *dest);
-extern SECStatus
-CERT_EncodeUserNotice(PLArenaPool *arena,
- CERTUserNotice *notice,
- SECItem *dest);
-
-extern SECStatus
-CERT_EncodeDisplayText(PLArenaPool *arena,
- SECItem *text,
- SECItem *dest);
-
-extern SECStatus
-CERT_EncodeCertPoliciesExtension(PLArenaPool *arena,
- CERTPolicyInfo **info,
- SECItem *dest);
-extern SECStatus
-CERT_EncodeNoticeReference(PLArenaPool *arena,
- CERTNoticeReference *reference,
- SECItem *dest);
-
-/*
- * Returns a pointer to a static structure.
- */
-extern const CERTRevocationFlags*
-CERT_GetPKIXVerifyNistRevocationPolicy(void);
-
-/*
- * Returns a pointer to a static structure.
- */
-extern const CERTRevocationFlags*
-CERT_GetClassicOCSPEnabledSoftFailurePolicy(void);
-
-/*
- * Returns a pointer to a static structure.
- */
-extern const CERTRevocationFlags*
-CERT_GetClassicOCSPEnabledHardFailurePolicy(void);
-
-/*
- * Returns a pointer to a static structure.
- */
-extern const CERTRevocationFlags*
-CERT_GetClassicOCSPDisabledPolicy(void);
-
-/*
- * Verify a Cert with libpkix
- * paramsIn control the verification options. If a value isn't specified
- * in paramsIn, it reverts to the application default.
- * paramsOut specifies the parameters the caller would like to get back.
- * the caller may pass NULL, in which case no parameters are returned.
- */
-extern SECStatus CERT_PKIXVerifyCert(
- CERTCertificate *cert,
- SECCertificateUsage usages,
- CERTValInParam *paramsIn,
- CERTValOutParam *paramsOut,
- void *wincx);
-
-/* Makes old cert validation APIs(CERT_VerifyCert, CERT_VerifyCertificate)
- * to use libpkix validation engine. The function should be called ones at
- * application initialization time.
- * Function is not thread safe.*/
-extern SECStatus CERT_SetUsePKIXForValidation(PRBool enable);
-
-/* The function return PR_TRUE if cert validation should use
- * libpkix cert validation engine. */
-extern PRBool CERT_GetUsePKIXForValidation(void);
-
-/*
- * Allocate a parameter container of type CERTRevocationFlags,
- * and allocate the inner arrays of the given sizes.
- * To cleanup call CERT_DestroyCERTRevocationFlags.
- */
-extern CERTRevocationFlags *
-CERT_AllocCERTRevocationFlags(
- PRUint32 number_leaf_methods, PRUint32 number_leaf_pref_methods,
- PRUint32 number_chain_methods, PRUint32 number_chain_pref_methods);
-
-/*
- * Destroy the arrays inside flags,
- * and destroy the object pointed to by flags, too.
- */
-extern void
-CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags);
-
-SEC_END_PROTOS
-
-#endif /* _CERT_H_ */
diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c
deleted file mode 100644
index 809a96598..000000000
--- a/security/nss/lib/certdb/certdb.c
+++ /dev/null
@@ -1,3273 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Certificate handling code
- *
- * $Id$
- */
-
-#include "nssilock.h"
-#include "prmon.h"
-#include "prtime.h"
-#include "cert.h"
-#include "certi.h"
-#include "secder.h"
-#include "secoid.h"
-#include "secasn1.h"
-#include "genname.h"
-#include "keyhi.h"
-#include "secitem.h"
-#include "certdb.h"
-#include "prprf.h"
-#include "sechash.h"
-#include "prlong.h"
-#include "certxutl.h"
-#include "portreg.h"
-#include "secerr.h"
-#include "sslerr.h"
-#include "pk11func.h"
-#include "xconst.h" /* for CERT_DecodeAltNameExtension */
-
-#include "pki.h"
-#include "pki3hack.h"
-
-SEC_ASN1_MKSUB(CERT_TimeChoiceTemplate)
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(SEC_BitStringTemplate)
-SEC_ASN1_MKSUB(SEC_IntegerTemplate)
-SEC_ASN1_MKSUB(SEC_SkipTemplate)
-
-/*
- * Certificate database handling code
- */
-
-
-const SEC_ASN1Template CERT_CertExtensionTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCertExtension) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTCertExtension,id) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
- offsetof(CERTCertExtension,critical) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(CERTCertExtension,value) },
- { 0, }
-};
-
-const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, CERT_CertExtensionTemplate }
-};
-
-const SEC_ASN1Template CERT_TimeChoiceTemplate[] = {
- { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) },
- { SEC_ASN1_UTC_TIME, 0, 0, siUTCTime },
- { SEC_ASN1_GENERALIZED_TIME, 0, 0, siGeneralizedTime },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_ValidityTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTValidity) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTValidity,notBefore),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate), 0 },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTValidity,notAfter),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate), 0 },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_CertificateTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCertificate) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, /* XXX DER_DEFAULT */
- offsetof(CERTCertificate,version),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { SEC_ASN1_INTEGER,
- offsetof(CERTCertificate,serialNumber) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTCertificate,signature),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_SAVE,
- offsetof(CERTCertificate,derIssuer) },
- { SEC_ASN1_INLINE,
- offsetof(CERTCertificate,issuer),
- CERT_NameTemplate },
- { SEC_ASN1_INLINE,
- offsetof(CERTCertificate,validity),
- CERT_ValidityTemplate },
- { SEC_ASN1_SAVE,
- offsetof(CERTCertificate,derSubject) },
- { SEC_ASN1_INLINE,
- offsetof(CERTCertificate,subject),
- CERT_NameTemplate },
- { SEC_ASN1_SAVE,
- offsetof(CERTCertificate,derPublicKey) },
- { SEC_ASN1_INLINE,
- offsetof(CERTCertificate,subjectPublicKeyInfo),
- CERT_SubjectPublicKeyInfoTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- offsetof(CERTCertificate,issuerID),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
- offsetof(CERTCertificate,subjectID),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | 3,
- offsetof(CERTCertificate,extensions),
- CERT_SequenceOfCertExtensionTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_SignedCertificateTemplate[] =
-{
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCertificate) },
- { SEC_ASN1_SAVE,
- offsetof(CERTCertificate,signatureWrap.data) },
- { SEC_ASN1_INLINE,
- 0, CERT_CertificateTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTCertificate,signatureWrap.signatureAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_BIT_STRING,
- offsetof(CERTCertificate,signatureWrap.signature) },
- { 0 }
-};
-
-/*
- * Find the subjectName in a DER encoded certificate
- */
-const SEC_ASN1Template SEC_CertSubjectTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECItem) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- 0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */
- { SEC_ASN1_SKIP }, /* serial number */
- { SEC_ASN1_SKIP }, /* signature algorithm */
- { SEC_ASN1_SKIP }, /* issuer */
- { SEC_ASN1_SKIP }, /* validity */
- { SEC_ASN1_ANY, 0, NULL }, /* subject */
- { SEC_ASN1_SKIP_REST },
- { 0 }
-};
-
-/*
- * Find the issuerName in a DER encoded certificate
- */
-const SEC_ASN1Template SEC_CertIssuerTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECItem) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- 0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */
- { SEC_ASN1_SKIP }, /* serial number */
- { SEC_ASN1_SKIP }, /* signature algorithm */
- { SEC_ASN1_ANY, 0, NULL }, /* issuer */
- { SEC_ASN1_SKIP_REST },
- { 0 }
-};
-/*
- * Find the subjectName in a DER encoded certificate
- */
-const SEC_ASN1Template SEC_CertSerialNumberTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECItem) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- 0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */
- { SEC_ASN1_ANY, 0, NULL }, /* serial number */
- { SEC_ASN1_SKIP_REST },
- { 0 }
-};
-
-/*
- * Find the issuer and serialNumber in a DER encoded certificate.
- * This data is used as the database lookup key since its the unique
- * identifier of a certificate.
- */
-const SEC_ASN1Template CERT_CertKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCertKey) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- 0, SEC_ASN1_SUB(SEC_SkipTemplate) }, /* version */
- { SEC_ASN1_INTEGER,
- offsetof(CERTCertKey,serialNumber) },
- { SEC_ASN1_SKIP }, /* signature algorithm */
- { SEC_ASN1_ANY,
- offsetof(CERTCertKey,derIssuer) },
- { SEC_ASN1_SKIP_REST },
- { 0 }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SignedCertificateTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SequenceOfCertExtensionTemplate)
-
-SECStatus
-CERT_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn,
- SECItem *key)
-{
- key->len = sn->len + issuer->len;
-
- if ((sn->data == NULL) || (issuer->data == NULL)) {
- goto loser;
- }
-
- key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len);
- if ( !key->data ) {
- goto loser;
- }
-
- /* copy the serialNumber */
- PORT_Memcpy(key->data, sn->data, sn->len);
-
- /* copy the issuer */
- PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-
-/*
- * Extract the subject name from a DER certificate
- */
-SECStatus
-CERT_NameFromDERCert(SECItem *derCert, SECItem *derName)
-{
- int rv;
- PRArenaPool *arena;
- CERTSignedData sd;
- void *tmpptr;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- return(SECFailure);
- }
-
- PORT_Memset(&sd, 0, sizeof(CERTSignedData));
- rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
-
- if ( rv ) {
- goto loser;
- }
-
- PORT_Memset(derName, 0, sizeof(SECItem));
- rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSubjectTemplate, &sd.data);
-
- if ( rv ) {
- goto loser;
- }
-
- tmpptr = derName->data;
- derName->data = (unsigned char*)PORT_Alloc(derName->len);
- if ( derName->data == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(derName->data, tmpptr, derName->len);
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(SECFailure);
-}
-
-SECStatus
-CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName)
-{
- int rv;
- PRArenaPool *arena;
- CERTSignedData sd;
- void *tmpptr;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- return(SECFailure);
- }
-
- PORT_Memset(&sd, 0, sizeof(CERTSignedData));
- rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
-
- if ( rv ) {
- goto loser;
- }
-
- PORT_Memset(derName, 0, sizeof(SECItem));
- rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertIssuerTemplate, &sd.data);
-
- if ( rv ) {
- goto loser;
- }
-
- tmpptr = derName->data;
- derName->data = (unsigned char*)PORT_Alloc(derName->len);
- if ( derName->data == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(derName->data, tmpptr, derName->len);
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(SECFailure);
-}
-
-SECStatus
-CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName)
-{
- int rv;
- PRArenaPool *arena;
- CERTSignedData sd;
- void *tmpptr;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- return(SECFailure);
- }
-
- PORT_Memset(&sd, 0, sizeof(CERTSignedData));
- rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
-
- if ( rv ) {
- goto loser;
- }
-
- PORT_Memset(derName, 0, sizeof(SECItem));
- rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSerialNumberTemplate, &sd.data);
-
- if ( rv ) {
- goto loser;
- }
-
- tmpptr = derName->data;
- derName->data = (unsigned char*)PORT_Alloc(derName->len);
- if ( derName->data == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(derName->data, tmpptr, derName->len);
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(SECFailure);
-}
-
-/*
- * Generate a database key, based on serial number and issuer, from a
- * DER certificate.
- */
-SECStatus
-CERT_KeyFromDERCert(PRArenaPool *reqArena, SECItem *derCert, SECItem *key)
-{
- int rv;
- CERTSignedData sd;
- CERTCertKey certkey;
-
- if (!reqArena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- PORT_Memset(&sd, 0, sizeof(CERTSignedData));
- rv = SEC_QuickDERDecodeItem(reqArena, &sd, CERT_SignedDataTemplate,
- derCert);
-
- if ( rv ) {
- goto loser;
- }
-
- PORT_Memset(&certkey, 0, sizeof(CERTCertKey));
- rv = SEC_QuickDERDecodeItem(reqArena, &certkey, CERT_CertKeyTemplate,
- &sd.data);
-
- if ( rv ) {
- goto loser;
- }
-
- return(CERT_KeyFromIssuerAndSN(reqArena, &certkey.derIssuer,
- &certkey.serialNumber, key));
-loser:
- return(SECFailure);
-}
-
-/*
- * fill in keyUsage field of the cert based on the cert extension
- * if the extension is not critical, then we allow all uses
- */
-static SECStatus
-GetKeyUsage(CERTCertificate *cert)
-{
- SECStatus rv;
- SECItem tmpitem;
-
- rv = CERT_FindKeyUsageExtension(cert, &tmpitem);
- if ( rv == SECSuccess ) {
- /* remember the actual value of the extension */
- cert->rawKeyUsage = tmpitem.data[0];
- cert->keyUsagePresent = PR_TRUE;
- cert->keyUsage = tmpitem.data[0];
-
- PORT_Free(tmpitem.data);
- tmpitem.data = NULL;
-
- } else {
- /* if the extension is not present, then we allow all uses */
- cert->keyUsage = KU_ALL;
- cert->rawKeyUsage = KU_ALL;
- cert->keyUsagePresent = PR_FALSE;
- }
-
- if ( CERT_GovtApprovedBitSet(cert) ) {
- cert->keyUsage |= KU_NS_GOVT_APPROVED;
- cert->rawKeyUsage |= KU_NS_GOVT_APPROVED;
- }
-
- return(SECSuccess);
-}
-
-
-static SECStatus
-findOIDinOIDSeqByTagNum(CERTOidSequence *seq, SECOidTag tagnum)
-{
- SECItem **oids;
- SECItem *oid;
- SECStatus rv = SECFailure;
-
- if (seq != NULL) {
- oids = seq->oids;
- while (oids != NULL && *oids != NULL) {
- oid = *oids;
- if (SECOID_FindOIDTag(oid) == tagnum) {
- rv = SECSuccess;
- break;
- }
- oids++;
- }
- }
- return rv;
-}
-
-/*
- * fill in nsCertType field of the cert based on the cert extension
- */
-SECStatus
-cert_GetCertType(CERTCertificate *cert)
-{
- PRUint32 nsCertType;
-
- if (cert->nsCertType) {
- /* once set, no need to recalculate */
- return SECSuccess;
- }
- nsCertType = cert_ComputeCertType(cert);
-
- /* Assert that it is safe to cast &cert->nsCertType to "PRInt32 *" */
- PORT_Assert(sizeof(cert->nsCertType) == sizeof(PRInt32));
- PR_ATOMIC_SET((PRInt32 *)&cert->nsCertType, nsCertType);
- return SECSuccess;
-}
-
-PRUint32
-cert_ComputeCertType(CERTCertificate *cert)
-{
- SECStatus rv;
- SECItem tmpitem;
- SECItem encodedExtKeyUsage;
- CERTOidSequence *extKeyUsage = NULL;
- PRBool basicConstraintPresent = PR_FALSE;
- CERTBasicConstraints basicConstraint;
- PRUint32 nsCertType = 0;
-
- tmpitem.data = NULL;
- CERT_FindNSCertTypeExtension(cert, &tmpitem);
- encodedExtKeyUsage.data = NULL;
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE,
- &encodedExtKeyUsage);
- if (rv == SECSuccess) {
- extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage);
- }
- rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);
- if (rv == SECSuccess) {
- basicConstraintPresent = PR_TRUE;
- }
- if (tmpitem.data != NULL || extKeyUsage != NULL) {
- if (tmpitem.data == NULL) {
- nsCertType = 0;
- } else {
- nsCertType = tmpitem.data[0];
- }
-
- /* free tmpitem data pointer to avoid memory leak */
- PORT_Free(tmpitem.data);
- tmpitem.data = NULL;
-
- /*
- * for this release, we will allow SSL certs with an email address
- * to be used for email
- */
- if ( ( nsCertType & NS_CERT_TYPE_SSL_CLIENT ) &&
- cert->emailAddr && cert->emailAddr[0]) {
- nsCertType |= NS_CERT_TYPE_EMAIL;
- }
- /*
- * for this release, we will allow SSL intermediate CAs to be
- * email intermediate CAs too.
- */
- if ( nsCertType & NS_CERT_TYPE_SSL_CA ) {
- nsCertType |= NS_CERT_TYPE_EMAIL_CA;
- }
- /*
- * allow a cert with the extended key usage of EMail Protect
- * to be used for email or as an email CA, if basic constraints
- * indicates that it is a CA.
- */
- if (findOIDinOIDSeqByTagNum(extKeyUsage,
- SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) ==
- SECSuccess) {
- if (basicConstraintPresent == PR_TRUE &&
- (basicConstraint.isCA)) {
- nsCertType |= NS_CERT_TYPE_EMAIL_CA;
- } else {
- nsCertType |= NS_CERT_TYPE_EMAIL;
- }
- }
- if (findOIDinOIDSeqByTagNum(extKeyUsage,
- SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) ==
- SECSuccess){
- if (basicConstraintPresent == PR_TRUE &&
- (basicConstraint.isCA)) {
- nsCertType |= NS_CERT_TYPE_SSL_CA;
- } else {
- nsCertType |= NS_CERT_TYPE_SSL_SERVER;
- }
- }
- /*
- * Treat certs with step-up OID as also having SSL server type.
- * COMODO needs this behaviour until June 2020. See Bug 737802.
- */
- if (findOIDinOIDSeqByTagNum(extKeyUsage,
- SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) ==
- SECSuccess){
- if (basicConstraintPresent == PR_TRUE &&
- (basicConstraint.isCA)) {
- nsCertType |= NS_CERT_TYPE_SSL_CA;
- } else {
- nsCertType |= NS_CERT_TYPE_SSL_SERVER;
- }
- }
- if (findOIDinOIDSeqByTagNum(extKeyUsage,
- SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) ==
- SECSuccess){
- if (basicConstraintPresent == PR_TRUE &&
- (basicConstraint.isCA)) {
- nsCertType |= NS_CERT_TYPE_SSL_CA;
- } else {
- nsCertType |= NS_CERT_TYPE_SSL_CLIENT;
- }
- }
- if (findOIDinOIDSeqByTagNum(extKeyUsage,
- SEC_OID_EXT_KEY_USAGE_CODE_SIGN) ==
- SECSuccess) {
- if (basicConstraintPresent == PR_TRUE &&
- (basicConstraint.isCA)) {
- nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
- } else {
- nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING;
- }
- }
- if (findOIDinOIDSeqByTagNum(extKeyUsage,
- SEC_OID_EXT_KEY_USAGE_TIME_STAMP) ==
- SECSuccess) {
- nsCertType |= EXT_KEY_USAGE_TIME_STAMP;
- }
- if (findOIDinOIDSeqByTagNum(extKeyUsage,
- SEC_OID_OCSP_RESPONDER) ==
- SECSuccess) {
- nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
- }
- } else {
- /* If no NS Cert Type extension and no EKU extension, then */
- nsCertType = 0;
- if (CERT_IsCACert(cert, &nsCertType))
- nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
- /* if the basic constraint extension says the cert is a CA, then
- allow SSL CA and EMAIL CA and Status Responder */
- if (basicConstraintPresent && basicConstraint.isCA ) {
- nsCertType |= (NS_CERT_TYPE_SSL_CA |
- NS_CERT_TYPE_EMAIL_CA |
- EXT_KEY_USAGE_STATUS_RESPONDER);
- }
- /* allow any ssl or email (no ca or object signing. */
- nsCertType |= NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER |
- NS_CERT_TYPE_EMAIL;
- }
-
- if (encodedExtKeyUsage.data != NULL) {
- PORT_Free(encodedExtKeyUsage.data);
- }
- if (extKeyUsage != NULL) {
- CERT_DestroyOidSequence(extKeyUsage);
- }
- return nsCertType;
-}
-
-/*
- * cert_GetKeyID() - extract or generate the subjectKeyID from a certificate
- */
-SECStatus
-cert_GetKeyID(CERTCertificate *cert)
-{
- SECItem tmpitem;
- SECStatus rv;
-
- cert->subjectKeyID.len = 0;
-
- /* see of the cert has a key identifier extension */
- rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem);
- if ( rv == SECSuccess ) {
- cert->subjectKeyID.data = (unsigned char*) PORT_ArenaAlloc(cert->arena, tmpitem.len);
- if ( cert->subjectKeyID.data != NULL ) {
- PORT_Memcpy(cert->subjectKeyID.data, tmpitem.data, tmpitem.len);
- cert->subjectKeyID.len = tmpitem.len;
- cert->keyIDGenerated = PR_FALSE;
- }
-
- PORT_Free(tmpitem.data);
- }
-
- /* if the cert doesn't have a key identifier extension, then generate one*/
- if ( cert->subjectKeyID.len == 0 ) {
- /*
- * pkix says that if the subjectKeyID is not present, then we should
- * use the SHA-1 hash of the DER-encoded publicKeyInfo from the cert
- */
- cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, SHA1_LENGTH);
- if ( cert->subjectKeyID.data != NULL ) {
- rv = PK11_HashBuf(SEC_OID_SHA1,cert->subjectKeyID.data,
- cert->derPublicKey.data,
- cert->derPublicKey.len);
- if ( rv == SECSuccess ) {
- cert->subjectKeyID.len = SHA1_LENGTH;
- }
- }
- }
-
- if ( cert->subjectKeyID.len == 0 ) {
- return(SECFailure);
- }
- return(SECSuccess);
-
-}
-
-static PRBool
-cert_IsRootCert(CERTCertificate *cert)
-{
- SECStatus rv;
- SECItem tmpitem;
-
- /* cache the authKeyID extension, if present */
- cert->authKeyID = CERT_FindAuthKeyIDExten(cert->arena, cert);
-
- /* it MUST be self-issued to be a root */
- if (cert->derIssuer.len == 0 ||
- !SECITEM_ItemsAreEqual(&cert->derIssuer, &cert->derSubject))
- {
- return PR_FALSE;
- }
-
- /* check the authKeyID extension */
- if (cert->authKeyID) {
- /* authority key identifier is present */
- if (cert->authKeyID->keyID.len > 0) {
- /* the keyIdentifier field is set, look for subjectKeyID */
- rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem);
- if (rv == SECSuccess) {
- PRBool match;
- /* also present, they MUST match for it to be a root */
- match = SECITEM_ItemsAreEqual(&cert->authKeyID->keyID,
- &tmpitem);
- PORT_Free(tmpitem.data);
- if (!match) return PR_FALSE; /* else fall through */
- } else {
- /* the subject key ID is required when AKI is present */
- return PR_FALSE;
- }
- }
- if (cert->authKeyID->authCertIssuer) {
- SECItem *caName;
- caName = (SECItem *)CERT_GetGeneralNameByType(
- cert->authKeyID->authCertIssuer,
- certDirectoryName, PR_TRUE);
- if (caName) {
- if (!SECITEM_ItemsAreEqual(&cert->derIssuer, caName)) {
- return PR_FALSE;
- } /* else fall through */
- } /* else ??? could not get general name as directory name? */
- }
- if (cert->authKeyID->authCertSerialNumber.len > 0) {
- if (!SECITEM_ItemsAreEqual(&cert->serialNumber,
- &cert->authKeyID->authCertSerialNumber)) {
- return PR_FALSE;
- } /* else fall through */
- }
- /* all of the AKI fields that were present passed the test */
- return PR_TRUE;
- }
- /* else the AKI was not present, so this is a root */
- return PR_TRUE;
-}
-
-/*
- * take a DER certificate and decode it into a certificate structure
- */
-CERTCertificate *
-CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
- char *nickname)
-{
- CERTCertificate *cert;
- PRArenaPool *arena;
- void *data;
- int rv;
- int len;
- char *tmpname;
-
- /* make a new arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- return 0;
- }
-
- /* allocate the certificate structure */
- cert = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
-
- if ( !cert ) {
- goto loser;
- }
-
- cert->arena = arena;
-
- if ( copyDER ) {
- /* copy the DER data for the cert into this arena */
- data = (void *)PORT_ArenaAlloc(arena, derSignedCert->len);
- if ( !data ) {
- goto loser;
- }
- cert->derCert.data = (unsigned char *)data;
- cert->derCert.len = derSignedCert->len;
- PORT_Memcpy(data, derSignedCert->data, derSignedCert->len);
- } else {
- /* point to passed in DER data */
- cert->derCert = *derSignedCert;
- }
-
- /* decode the certificate info */
- rv = SEC_QuickDERDecodeItem(arena, cert, SEC_SignedCertificateTemplate,
- &cert->derCert);
-
- if ( rv ) {
- goto loser;
- }
-
- if (cert_HasUnknownCriticalExten (cert->extensions) == PR_TRUE) {
- cert->options.bits.hasUnsupportedCriticalExt = PR_TRUE;
- }
-
- /* generate and save the database key for the cert */
- rv = CERT_KeyFromIssuerAndSN(arena, &cert->derIssuer, &cert->serialNumber,
- &cert->certKey);
- if ( rv ) {
- goto loser;
- }
-
- /* set the nickname */
- if ( nickname == NULL ) {
- cert->nickname = NULL;
- } else {
- /* copy and install the nickname */
- len = PORT_Strlen(nickname) + 1;
- cert->nickname = (char*)PORT_ArenaAlloc(arena, len);
- if ( cert->nickname == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(cert->nickname, nickname, len);
- }
-
- /* set the email address */
- cert->emailAddr = cert_GetCertificateEmailAddresses(cert);
-
- /* initialize the subjectKeyID */
- rv = cert_GetKeyID(cert);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* initialize keyUsage */
- rv = GetKeyUsage(cert);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* determine if this is a root cert */
- cert->isRoot = cert_IsRootCert(cert);
-
- /* initialize the certType */
- rv = cert_GetCertType(cert);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- tmpname = CERT_NameToAscii(&cert->subject);
- if ( tmpname != NULL ) {
- cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname);
- PORT_Free(tmpname);
- }
-
- tmpname = CERT_NameToAscii(&cert->issuer);
- if ( tmpname != NULL ) {
- cert->issuerName = PORT_ArenaStrdup(cert->arena, tmpname);
- PORT_Free(tmpname);
- }
-
- cert->referenceCount = 1;
- cert->slot = NULL;
- cert->pkcs11ID = CK_INVALID_HANDLE;
- cert->dbnickname = NULL;
-
- return(cert);
-
-loser:
-
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(0);
-}
-
-CERTCertificate *
-__CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
- char *nickname)
-{
- return CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname);
-}
-
-
-CERTValidity *
-CERT_CreateValidity(int64 notBefore, int64 notAfter)
-{
- CERTValidity *v;
- int rv;
- PRArenaPool *arena;
-
- if (notBefore > notAfter) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- return(0);
- }
-
- v = (CERTValidity*) PORT_ArenaZAlloc(arena, sizeof(CERTValidity));
- if (v) {
- v->arena = arena;
- rv = DER_EncodeTimeChoice(arena, &v->notBefore, notBefore);
- if (rv) goto loser;
- rv = DER_EncodeTimeChoice(arena, &v->notAfter, notAfter);
- if (rv) goto loser;
- }
- return v;
-
- loser:
- CERT_DestroyValidity(v);
- return 0;
-}
-
-SECStatus
-CERT_CopyValidity(PRArenaPool *arena, CERTValidity *to, CERTValidity *from)
-{
- SECStatus rv;
-
- CERT_DestroyValidity(to);
- to->arena = arena;
-
- rv = SECITEM_CopyItem(arena, &to->notBefore, &from->notBefore);
- if (rv) return rv;
- rv = SECITEM_CopyItem(arena, &to->notAfter, &from->notAfter);
- return rv;
-}
-
-void
-CERT_DestroyValidity(CERTValidity *v)
-{
- if (v && v->arena) {
- PORT_FreeArena(v->arena, PR_FALSE);
- }
- return;
-}
-
-/*
-** Amount of time that a certifiate is allowed good before it is actually
-** good. This is used for pending certificates, ones that are about to be
-** valid. The slop is designed to allow for some variance in the clocks
-** of the machine checking the certificate.
-*/
-#define PENDING_SLOP (24L*60L*60L) /* seconds per day */
-static PRInt32 pendingSlop = PENDING_SLOP; /* seconds */
-
-PRInt32
-CERT_GetSlopTime(void)
-{
- return pendingSlop; /* seconds */
-}
-
-SECStatus
-CERT_SetSlopTime(PRInt32 slop) /* seconds */
-{
- if (slop < 0)
- return SECFailure;
- pendingSlop = slop;
- return SECSuccess;
-}
-
-SECStatus
-CERT_GetCertTimes(CERTCertificate *c, PRTime *notBefore, PRTime *notAfter)
-{
- SECStatus rv;
-
- if (!c || !notBefore || !notAfter) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* convert DER not-before time */
- rv = DER_DecodeTimeChoice(notBefore, &c->validity.notBefore);
- if (rv) {
- return(SECFailure);
- }
-
- /* convert DER not-after time */
- rv = DER_DecodeTimeChoice(notAfter, &c->validity.notAfter);
- if (rv) {
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-/*
- * Check the validity times of a certificate
- */
-SECCertTimeValidity
-CERT_CheckCertValidTimes(CERTCertificate *c, PRTime t, PRBool allowOverride)
-{
- PRTime notBefore, notAfter, llPendingSlop, tmp1;
- SECStatus rv;
-
- if (!c) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return(secCertTimeUndetermined);
- }
- /* if cert is already marked OK, then don't bother to check */
- if ( allowOverride && c->timeOK ) {
- return(secCertTimeValid);
- }
-
- rv = CERT_GetCertTimes(c, &notBefore, &notAfter);
-
- if (rv) {
- return(secCertTimeExpired); /*XXX is this the right thing to do here?*/
- }
-
- LL_I2L(llPendingSlop, pendingSlop);
- /* convert to micro seconds */
- LL_UI2L(tmp1, PR_USEC_PER_SEC);
- LL_MUL(llPendingSlop, llPendingSlop, tmp1);
- LL_SUB(notBefore, notBefore, llPendingSlop);
- if ( LL_CMP( t, <, notBefore ) ) {
- PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
- return(secCertTimeNotValidYet);
- }
- if ( LL_CMP( t, >, notAfter) ) {
- PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
- return(secCertTimeExpired);
- }
-
- return(secCertTimeValid);
-}
-
-SECStatus
-SEC_GetCrlTimes(CERTCrl *date, PRTime *notBefore, PRTime *notAfter)
-{
- int rv;
-
- /* convert DER not-before time */
- rv = DER_DecodeTimeChoice(notBefore, &date->lastUpdate);
- if (rv) {
- return(SECFailure);
- }
-
- /* convert DER not-after time */
- if (date->nextUpdate.data) {
- rv = DER_DecodeTimeChoice(notAfter, &date->nextUpdate);
- if (rv) {
- return(SECFailure);
- }
- }
- else {
- LL_I2L(*notAfter, 0L);
- }
- return(SECSuccess);
-}
-
-/* These routines should probably be combined with the cert
- * routines using an common extraction routine.
- */
-SECCertTimeValidity
-SEC_CheckCrlTimes(CERTCrl *crl, PRTime t) {
- PRTime notBefore, notAfter, llPendingSlop, tmp1;
- SECStatus rv;
-
- rv = SEC_GetCrlTimes(crl, &notBefore, &notAfter);
-
- if (rv) {
- return(secCertTimeExpired);
- }
-
- LL_I2L(llPendingSlop, pendingSlop);
- /* convert to micro seconds */
- LL_I2L(tmp1, PR_USEC_PER_SEC);
- LL_MUL(llPendingSlop, llPendingSlop, tmp1);
- LL_SUB(notBefore, notBefore, llPendingSlop);
- if ( LL_CMP( t, <, notBefore ) ) {
- return(secCertTimeNotValidYet);
- }
-
- /* If next update is omitted and the test for notBefore passes, then
- we assume that the crl is up to date.
- */
- if ( LL_IS_ZERO(notAfter) ) {
- return(secCertTimeValid);
- }
-
- if ( LL_CMP( t, >, notAfter) ) {
- return(secCertTimeExpired);
- }
-
- return(secCertTimeValid);
-}
-
-PRBool
-SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old) {
- PRTime newNotBefore, newNotAfter;
- PRTime oldNotBefore, oldNotAfter;
- SECStatus rv;
-
- /* problems with the new CRL? reject it */
- rv = SEC_GetCrlTimes(inNew, &newNotBefore, &newNotAfter);
- if (rv) return PR_FALSE;
-
- /* problems with the old CRL? replace it */
- rv = SEC_GetCrlTimes(old, &oldNotBefore, &oldNotAfter);
- if (rv) return PR_TRUE;
-
- /* Question: what about the notAfter's? */
- return ((PRBool)LL_CMP(oldNotBefore, <, newNotBefore));
-}
-
-/*
- * return required key usage and cert type based on cert usage
- */
-SECStatus
-CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage,
- PRBool ca,
- unsigned int *retKeyUsage,
- unsigned int *retCertType)
-{
- unsigned int requiredKeyUsage = 0;
- unsigned int requiredCertType = 0;
-
- if ( ca ) {
- switch ( usage ) {
- case certUsageSSLServerWithStepUp:
- requiredKeyUsage = KU_NS_GOVT_APPROVED | KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_SSL_CA;
- break;
- case certUsageSSLClient:
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_SSL_CA;
- break;
- case certUsageSSLServer:
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_SSL_CA;
- break;
- case certUsageSSLCA:
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_SSL_CA;
- break;
- case certUsageEmailSigner:
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_EMAIL_CA;
- break;
- case certUsageEmailRecipient:
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_EMAIL_CA;
- break;
- case certUsageObjectSigner:
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA;
- break;
- case certUsageAnyCA:
- case certUsageVerifyCA:
- case certUsageStatusResponder:
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA |
- NS_CERT_TYPE_EMAIL_CA |
- NS_CERT_TYPE_SSL_CA;
- break;
- default:
- PORT_Assert(0);
- goto loser;
- }
- } else {
- switch ( usage ) {
- case certUsageSSLClient:
- /*
- * RFC 5280 lists digitalSignature and keyAgreement for
- * id-kp-clientAuth. NSS does not support the *_fixed_dh and
- * *_fixed_ecdh client certificate types.
- */
- requiredKeyUsage = KU_DIGITAL_SIGNATURE;
- requiredCertType = NS_CERT_TYPE_SSL_CLIENT;
- break;
- case certUsageSSLServer:
- requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT;
- requiredCertType = NS_CERT_TYPE_SSL_SERVER;
- break;
- case certUsageSSLServerWithStepUp:
- requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT |
- KU_NS_GOVT_APPROVED;
- requiredCertType = NS_CERT_TYPE_SSL_SERVER;
- break;
- case certUsageSSLCA:
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_SSL_CA;
- break;
- case certUsageEmailSigner:
- requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION;
- requiredCertType = NS_CERT_TYPE_EMAIL;
- break;
- case certUsageEmailRecipient:
- requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT;
- requiredCertType = NS_CERT_TYPE_EMAIL;
- break;
- case certUsageObjectSigner:
- /* RFC 5280 lists only digitalSignature for id-kp-codeSigning. */
- requiredKeyUsage = KU_DIGITAL_SIGNATURE;
- requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING;
- break;
- case certUsageStatusResponder:
- requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION;
- requiredCertType = EXT_KEY_USAGE_STATUS_RESPONDER;
- break;
- default:
- PORT_Assert(0);
- goto loser;
- }
- }
-
- if ( retKeyUsage != NULL ) {
- *retKeyUsage = requiredKeyUsage;
- }
- if ( retCertType != NULL ) {
- *retCertType = requiredCertType;
- }
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-/*
- * check the key usage of a cert against a set of required values
- */
-SECStatus
-CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage)
-{
- if (!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* choose between key agreement or key encipherment based on key
- * type in cert
- */
- if ( requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT ) {
- KeyType keyType = CERT_GetCertKeyType(&cert->subjectPublicKeyInfo);
- /* turn off the special bit */
- requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT);
-
- switch (keyType) {
- case rsaKey:
- requiredUsage |= KU_KEY_ENCIPHERMENT;
- break;
- case dsaKey:
- requiredUsage |= KU_DIGITAL_SIGNATURE;
- break;
- case dhKey:
- requiredUsage |= KU_KEY_AGREEMENT;
- break;
- case ecKey:
- /* Accept either signature or agreement. */
- if (!(cert->keyUsage & (KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)))
- goto loser;
- break;
- default:
- goto loser;
- }
- }
-
- /* Allow either digital signature or non-repudiation */
- if ( requiredUsage & KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION ) {
- /* turn off the special bit */
- requiredUsage &= (~KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION);
-
- if (!(cert->keyUsage & (KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)))
- goto loser;
- }
-
- if ( (cert->keyUsage & requiredUsage) == requiredUsage )
- return SECSuccess;
-
-loser:
- PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
- return SECFailure;
-}
-
-
-CERTCertificate *
-CERT_DupCertificate(CERTCertificate *c)
-{
- if (c) {
- NSSCertificate *tmp = STAN_GetNSSCertificate(c);
- nssCertificate_AddRef(tmp);
- }
- return c;
-}
-
-/*
- * Allow use of default cert database, so that apps(such as mozilla) don't
- * have to pass the handle all over the place.
- */
-static CERTCertDBHandle *default_cert_db_handle = 0;
-
-void
-CERT_SetDefaultCertDB(CERTCertDBHandle *handle)
-{
- default_cert_db_handle = handle;
-
- return;
-}
-
-CERTCertDBHandle *
-CERT_GetDefaultCertDB(void)
-{
- return(default_cert_db_handle);
-}
-
-/* XXX this would probably be okay/better as an xp routine? */
-static void
-sec_lower_string(char *s)
-{
- if ( s == NULL ) {
- return;
- }
-
- while ( *s ) {
- *s = PORT_Tolower(*s);
- s++;
- }
-
- return;
-}
-
-static PRBool
-cert_IsIPAddr(const char *hn)
-{
- PRBool isIPaddr = PR_FALSE;
- PRNetAddr netAddr;
- isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr));
- return isIPaddr;
-}
-
-/*
-** Add a domain name to the list of names that the user has explicitly
-** allowed (despite cert name mismatches) for use with a server cert.
-*/
-SECStatus
-CERT_AddOKDomainName(CERTCertificate *cert, const char *hn)
-{
- CERTOKDomainName *domainOK;
- int newNameLen;
-
- if (!hn || !(newNameLen = strlen(hn))) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(cert->arena,
- (sizeof *domainOK) + newNameLen);
- if (!domainOK)
- return SECFailure; /* error code is already set. */
-
- PORT_Strcpy(domainOK->name, hn);
- sec_lower_string(domainOK->name);
-
- /* put at head of list. */
- domainOK->next = cert->domainOK;
- cert->domainOK = domainOK;
- return SECSuccess;
-}
-
-/* returns SECSuccess if hn matches pattern cn,
-** returns SECFailure with SSL_ERROR_BAD_CERT_DOMAIN if no match,
-** returns SECFailure with some other error code if another error occurs.
-**
-** This function may modify string cn, so caller must pass a modifiable copy.
-*/
-static SECStatus
-cert_TestHostName(char * cn, const char * hn)
-{
- static int useShellExp = -1;
-
- if (useShellExp < 0) {
- useShellExp = (NULL != PR_GetEnv("NSS_USE_SHEXP_IN_CERT_NAME"));
- }
- if (useShellExp) {
- /* Backward compatible code, uses Shell Expressions (SHEXP). */
- int regvalid = PORT_RegExpValid(cn);
- if (regvalid != NON_SXP) {
- SECStatus rv;
- /* cn is a regular expression, try to match the shexp */
- int match = PORT_RegExpCaseSearch(hn, cn);
-
- if ( match == 0 ) {
- rv = SECSuccess;
- } else {
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
- rv = SECFailure;
- }
- return rv;
- }
- } else {
- /* New approach conforms to RFC 2818. */
- char *wildcard = PORT_Strchr(cn, '*');
- char *firstcndot = PORT_Strchr(cn, '.');
- char *secondcndot = firstcndot ? PORT_Strchr(firstcndot+1, '.') : NULL;
- char *firsthndot = PORT_Strchr(hn, '.');
-
- /* For a cn pattern to be considered valid, the wildcard character...
- * - may occur only in a DNS name with at least 3 components, and
- * - may occur only as last character in the first component, and
- * - may be preceded by additional characters
- */
- if (wildcard && secondcndot && secondcndot[1] && firsthndot
- && firstcndot - wildcard == 1
- && secondcndot - firstcndot > 1
- && PORT_Strrchr(cn, '*') == wildcard
- && !PORT_Strncasecmp(cn, hn, wildcard - cn)
- && !PORT_Strcasecmp(firstcndot, firsthndot)) {
- /* valid wildcard pattern match */
- return SECSuccess;
- }
- }
- /* String cn has no wildcard or shell expression.
- * Compare entire string hn with cert name.
- */
- if (PORT_Strcasecmp(hn, cn) == 0) {
- return SECSuccess;
- }
-
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
- return SECFailure;
-}
-
-
-SECStatus
-cert_VerifySubjectAltName(CERTCertificate *cert, const char *hn)
-{
- PRArenaPool * arena = NULL;
- CERTGeneralName * nameList = NULL;
- CERTGeneralName * current;
- char * cn;
- int cnBufLen;
- unsigned int hnLen;
- int DNSextCount = 0;
- int IPextCount = 0;
- PRBool isIPaddr = PR_FALSE;
- SECStatus rv = SECFailure;
- SECItem subAltName;
- PRNetAddr netAddr;
- char cnbuf[128];
-
- subAltName.data = NULL;
- hnLen = strlen(hn);
- cn = cnbuf;
- cnBufLen = sizeof cnbuf;
-
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
- &subAltName);
- if (rv != SECSuccess) {
- goto fail;
- }
- isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr));
- rv = SECFailure;
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena)
- goto fail;
-
- nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName);
- if (!current)
- goto fail;
-
- do {
- switch (current->type) {
- case certDNSName:
- if (!isIPaddr) {
- /* DNS name current->name.other.data is not null terminated.
- ** so must copy it.
- */
- int cnLen = current->name.other.len;
- rv = CERT_RFC1485_EscapeAndQuote(cn, cnBufLen,
- (char *)current->name.other.data,
- cnLen);
- if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_OUTPUT_LEN) {
- cnBufLen = cnLen * 3 + 3; /* big enough for worst case */
- cn = (char *)PORT_ArenaAlloc(arena, cnBufLen);
- if (!cn)
- goto fail;
- rv = CERT_RFC1485_EscapeAndQuote(cn, cnBufLen,
- (char *)current->name.other.data,
- cnLen);
- }
- if (rv == SECSuccess)
- rv = cert_TestHostName(cn ,hn);
- if (rv == SECSuccess)
- goto finish;
- }
- DNSextCount++;
- break;
- case certIPAddress:
- if (isIPaddr) {
- int match = 0;
- PRIPv6Addr v6Addr;
- if (current->name.other.len == 4 && /* IP v4 address */
- netAddr.inet.family == PR_AF_INET) {
- match = !memcmp(&netAddr.inet.ip,
- current->name.other.data, 4);
- } else if (current->name.other.len == 16 && /* IP v6 address */
- netAddr.ipv6.family == PR_AF_INET6) {
- match = !memcmp(&netAddr.ipv6.ip,
- current->name.other.data, 16);
- } else if (current->name.other.len == 16 && /* IP v6 address */
- netAddr.inet.family == PR_AF_INET) {
- /* convert netAddr to ipv6, then compare. */
- /* ipv4 must be in Network Byte Order on input. */
- PR_ConvertIPv4AddrToIPv6(netAddr.inet.ip, &v6Addr);
- match = !memcmp(&v6Addr, current->name.other.data, 16);
- } else if (current->name.other.len == 4 && /* IP v4 address */
- netAddr.inet.family == PR_AF_INET6) {
- /* convert netAddr to ipv6, then compare. */
- PRUint32 ipv4 = (current->name.other.data[0] << 24) |
- (current->name.other.data[1] << 16) |
- (current->name.other.data[2] << 8) |
- current->name.other.data[3];
- /* ipv4 must be in Network Byte Order on input. */
- PR_ConvertIPv4AddrToIPv6(PR_htonl(ipv4), &v6Addr);
- match = !memcmp(&netAddr.ipv6.ip, &v6Addr, 16);
- }
- if (match) {
- rv = SECSuccess;
- goto finish;
- }
- }
- IPextCount++;
- break;
- default:
- break;
- }
- current = CERT_GetNextGeneralName(current);
- } while (current != nameList);
-
-fail:
-
- if (!(isIPaddr ? IPextCount : DNSextCount)) {
- /* no relevant value in the extension was found. */
- PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
- } else {
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
- }
- rv = SECFailure;
-
-finish:
-
- /* Don't free nameList, it's part of the arena. */
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- if (subAltName.data) {
- SECITEM_FreeItem(&subAltName, PR_FALSE);
- }
-
- return rv;
-}
-
-/*
- * If found:
- * - subAltName contains the extension (caller must free)
- * - return value is the decoded namelist (allocated off arena)
- * if not found, or if failure to decode:
- * - return value is NULL
- */
-CERTGeneralName *
-cert_GetSubjectAltNameList(CERTCertificate *cert, PRArenaPool *arena)
-{
- CERTGeneralName * nameList = NULL;
- SECStatus rv = SECFailure;
- SECItem subAltName;
-
- if (!cert || !arena)
- return NULL;
-
- subAltName.data = NULL;
-
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME,
- &subAltName);
- if (rv != SECSuccess)
- return NULL;
-
- nameList = CERT_DecodeAltNameExtension(arena, &subAltName);
- SECITEM_FreeItem(&subAltName, PR_FALSE);
- return nameList;
-}
-
-PRUint32
-cert_CountDNSPatterns(CERTGeneralName *firstName)
-{
- CERTGeneralName * current;
- PRUint32 count = 0;
-
- if (!firstName)
- return 0;
-
- current = firstName;
- do {
- switch (current->type) {
- case certDNSName:
- case certIPAddress:
- ++count;
- break;
- default:
- break;
- }
- current = CERT_GetNextGeneralName(current);
- } while (current != firstName);
-
- return count;
-}
-
-#ifndef INET6_ADDRSTRLEN
-#define INET6_ADDRSTRLEN 46
-#endif
-
-/* will fill nickNames,
- * will allocate all data from nickNames->arena,
- * numberOfGeneralNames should have been obtained from cert_CountDNSPatterns,
- * will ensure the numberOfGeneralNames matches the number of output entries.
- */
-SECStatus
-cert_GetDNSPatternsFromGeneralNames(CERTGeneralName *firstName,
- PRUint32 numberOfGeneralNames,
- CERTCertNicknames *nickNames)
-{
- CERTGeneralName *currentInput;
- char **currentOutput;
-
- if (!firstName || !nickNames || !numberOfGeneralNames)
- return SECFailure;
-
- nickNames->numnicknames = numberOfGeneralNames;
- nickNames->nicknames = PORT_ArenaAlloc(nickNames->arena,
- sizeof(char *) * numberOfGeneralNames);
- if (!nickNames->nicknames)
- return SECFailure;
-
- currentInput = firstName;
- currentOutput = nickNames->nicknames;
- do {
- char *cn = NULL;
- char ipbuf[INET6_ADDRSTRLEN];
- PRNetAddr addr;
-
- if (numberOfGeneralNames < 1) {
- /* internal consistency error */
- return SECFailure;
- }
-
- switch (currentInput->type) {
- case certDNSName:
- /* DNS name currentInput->name.other.data is not null terminated.
- ** so must copy it.
- */
- cn = (char *)PORT_ArenaAlloc(nickNames->arena,
- currentInput->name.other.len + 1);
- if (!cn)
- return SECFailure;
- PORT_Memcpy(cn, currentInput->name.other.data,
- currentInput->name.other.len);
- cn[currentInput->name.other.len] = 0;
- break;
- case certIPAddress:
- if (currentInput->name.other.len == 4) {
- addr.inet.family = PR_AF_INET;
- memcpy(&addr.inet.ip, currentInput->name.other.data,
- currentInput->name.other.len);
- } else if (currentInput->name.other.len == 16) {
- addr.ipv6.family = PR_AF_INET6;
- memcpy(&addr.ipv6.ip, currentInput->name.other.data,
- currentInput->name.other.len);
- }
- if (PR_NetAddrToString(&addr, ipbuf, sizeof(ipbuf)) == PR_FAILURE)
- return SECFailure;
- cn = PORT_ArenaStrdup(nickNames->arena, ipbuf);
- if (!cn)
- return SECFailure;
- break;
- default:
- break;
- }
- if (cn) {
- *currentOutput = cn;
- nickNames->totallen += PORT_Strlen(cn);
- ++currentOutput;
- --numberOfGeneralNames;
- }
- currentInput = CERT_GetNextGeneralName(currentInput);
- } while (currentInput != firstName);
-
- return (numberOfGeneralNames == 0) ? SECSuccess : SECFailure;
-}
-
-/*
- * Collect all valid DNS names from the given cert.
- * The output arena will reference some temporaray data,
- * but this saves us from dealing with two arenas.
- * The caller may free all data by freeing CERTCertNicknames->arena.
- */
-CERTCertNicknames *
-CERT_GetValidDNSPatternsFromCert(CERTCertificate *cert)
-{
- CERTGeneralName *generalNames;
- CERTCertNicknames *nickNames;
- PRArenaPool *arena;
- char *singleName;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena) {
- return NULL;
- }
-
- nickNames = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames));
- if (!nickNames) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
-
- /* init the structure */
- nickNames->arena = arena;
- nickNames->head = NULL;
- nickNames->numnicknames = 0;
- nickNames->nicknames = NULL;
- nickNames->totallen = 0;
-
- generalNames = cert_GetSubjectAltNameList(cert, arena);
- if (generalNames) {
- SECStatus rv_getnames = SECFailure;
- PRUint32 numNames = cert_CountDNSPatterns(generalNames);
-
- if (numNames) {
- rv_getnames = cert_GetDNSPatternsFromGeneralNames(generalNames,
- numNames, nickNames);
- }
-
- /* if there were names, we'll exit now, either with success or failure */
- if (numNames) {
- if (rv_getnames == SECSuccess) {
- return nickNames;
- }
-
- /* failure to produce output */
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
- }
-
- /* no SAN extension or no names found in extension */
- singleName = CERT_GetCommonName(&cert->subject);
- if (singleName) {
- nickNames->numnicknames = 1;
- nickNames->nicknames = PORT_ArenaAlloc(arena, sizeof(char *));
- if (nickNames->nicknames) {
- *nickNames->nicknames = PORT_ArenaStrdup(arena, singleName);
- }
- PORT_Free(singleName);
-
- /* Did we allocate both the buffer of pointers and the string? */
- if (nickNames->nicknames && *nickNames->nicknames) {
- return nickNames;
- }
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
-}
-
-/* Make sure that the name of the host we are connecting to matches the
- * name that is incoded in the common-name component of the certificate
- * that they are using.
- */
-SECStatus
-CERT_VerifyCertName(CERTCertificate *cert, const char *hn)
-{
- char * cn;
- SECStatus rv;
- CERTOKDomainName *domainOK;
-
- if (!hn || !strlen(hn)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* if the name is one that the user has already approved, it's OK. */
- for (domainOK = cert->domainOK; domainOK; domainOK = domainOK->next) {
- if (0 == PORT_Strcasecmp(hn, domainOK->name)) {
- return SECSuccess;
- }
- }
-
- /* Per RFC 2818, if the SubjectAltName extension is present, it must
- ** be used as the cert's identity.
- */
- rv = cert_VerifySubjectAltName(cert, hn);
- if (rv == SECSuccess || PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
- return rv;
-
- cn = CERT_GetCommonName(&cert->subject);
- if ( cn ) {
- PRBool isIPaddr = cert_IsIPAddr(hn);
- if (isIPaddr) {
- if (PORT_Strcasecmp(hn, cn) == 0) {
- rv = SECSuccess;
- } else {
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
- rv = SECFailure;
- }
- } else {
- rv = cert_TestHostName(cn, hn);
- }
- PORT_Free(cn);
- } else
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
- return rv;
-}
-
-PRBool
-CERT_CompareCerts(CERTCertificate *c1, CERTCertificate *c2)
-{
- SECComparison comp;
-
- comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert);
- if ( comp == SECEqual ) { /* certs are the same */
- return(PR_TRUE);
- } else {
- return(PR_FALSE);
- }
-}
-
-static SECStatus
-StringsEqual(char *s1, char *s2) {
- if ( ( s1 == NULL ) || ( s2 == NULL ) ) {
- if ( s1 != s2 ) { /* only one is null */
- return(SECFailure);
- }
- return(SECSuccess); /* both are null */
- }
-
- if ( PORT_Strcmp( s1, s2 ) != 0 ) {
- return(SECFailure); /* not equal */
- }
-
- return(SECSuccess); /* strings are equal */
-}
-
-
-PRBool
-CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2)
-{
- SECComparison comp;
- char *c1str, *c2str;
- SECStatus eq;
-
- comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert);
- if ( comp == SECEqual ) { /* certs are the same */
- return(PR_TRUE);
- }
-
- /* check if they are issued by the same CA */
- comp = SECITEM_CompareItem(&c1->derIssuer, &c2->derIssuer);
- if ( comp != SECEqual ) { /* different issuer */
- return(PR_FALSE);
- }
-
- /* check country name */
- c1str = CERT_GetCountryName(&c1->subject);
- c2str = CERT_GetCountryName(&c2->subject);
- eq = StringsEqual(c1str, c2str);
- PORT_Free(c1str);
- PORT_Free(c2str);
- if ( eq != SECSuccess ) {
- return(PR_FALSE);
- }
-
- /* check locality name */
- c1str = CERT_GetLocalityName(&c1->subject);
- c2str = CERT_GetLocalityName(&c2->subject);
- eq = StringsEqual(c1str, c2str);
- PORT_Free(c1str);
- PORT_Free(c2str);
- if ( eq != SECSuccess ) {
- return(PR_FALSE);
- }
-
- /* check state name */
- c1str = CERT_GetStateName(&c1->subject);
- c2str = CERT_GetStateName(&c2->subject);
- eq = StringsEqual(c1str, c2str);
- PORT_Free(c1str);
- PORT_Free(c2str);
- if ( eq != SECSuccess ) {
- return(PR_FALSE);
- }
-
- /* check org name */
- c1str = CERT_GetOrgName(&c1->subject);
- c2str = CERT_GetOrgName(&c2->subject);
- eq = StringsEqual(c1str, c2str);
- PORT_Free(c1str);
- PORT_Free(c2str);
- if ( eq != SECSuccess ) {
- return(PR_FALSE);
- }
-
-#ifdef NOTDEF
- /* check orgUnit name */
- /*
- * We need to revisit this and decide which fields should be allowed to be
- * different
- */
- c1str = CERT_GetOrgUnitName(&c1->subject);
- c2str = CERT_GetOrgUnitName(&c2->subject);
- eq = StringsEqual(c1str, c2str);
- PORT_Free(c1str);
- PORT_Free(c2str);
- if ( eq != SECSuccess ) {
- return(PR_FALSE);
- }
-#endif
-
- return(PR_TRUE); /* all fields but common name are the same */
-}
-
-
-/* CERT_CertChainFromCert and CERT_DestroyCertificateList moved
- to certhigh.c */
-
-
-CERTIssuerAndSN *
-CERT_GetCertIssuerAndSN(PRArenaPool *arena, CERTCertificate *cert)
-{
- CERTIssuerAndSN *result;
- SECStatus rv;
-
- if ( arena == NULL ) {
- arena = cert->arena;
- }
-
- result = (CERTIssuerAndSN*)PORT_ArenaZAlloc(arena, sizeof(*result));
- if (result == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- rv = SECITEM_CopyItem(arena, &result->derIssuer, &cert->derIssuer);
- if (rv != SECSuccess)
- return NULL;
-
- rv = CERT_CopyName(arena, &result->issuer, &cert->issuer);
- if (rv != SECSuccess)
- return NULL;
-
- rv = SECITEM_CopyItem(arena, &result->serialNumber, &cert->serialNumber);
- if (rv != SECSuccess)
- return NULL;
-
- return result;
-}
-
-char *
-CERT_MakeCANickname(CERTCertificate *cert)
-{
- char *firstname = NULL;
- char *org = NULL;
- char *nickname = NULL;
- int count;
- CERTCertificate *dummycert;
-
- firstname = CERT_GetCommonName(&cert->subject);
- if ( firstname == NULL ) {
- firstname = CERT_GetOrgUnitName(&cert->subject);
- }
-
- org = CERT_GetOrgName(&cert->issuer);
- if (org == NULL) {
- org = CERT_GetDomainComponentName(&cert->issuer);
- if (org == NULL) {
- if (firstname) {
- org = firstname;
- firstname = NULL;
- } else {
- org = PORT_Strdup("Unknown CA");
- }
- }
- }
-
- /* can only fail if PORT_Strdup fails, in which case
- * we're having memory problems. */
- if (org == NULL) {
- goto done;
- }
-
-
- count = 1;
- while ( 1 ) {
-
- if ( firstname ) {
- if ( count == 1 ) {
- nickname = PR_smprintf("%s - %s", firstname, org);
- } else {
- nickname = PR_smprintf("%s - %s #%d", firstname, org, count);
- }
- } else {
- if ( count == 1 ) {
- nickname = PR_smprintf("%s", org);
- } else {
- nickname = PR_smprintf("%s #%d", org, count);
- }
- }
- if ( nickname == NULL ) {
- goto done;
- }
-
- /* look up the nickname to make sure it isn't in use already */
- dummycert = CERT_FindCertByNickname(cert->dbhandle, nickname);
-
- if ( dummycert == NULL ) {
- goto done;
- }
-
- /* found a cert, destroy it and loop */
- CERT_DestroyCertificate(dummycert);
-
- /* free the nickname */
- PORT_Free(nickname);
-
- count++;
- }
-
-done:
- if ( firstname ) {
- PORT_Free(firstname);
- }
- if ( org ) {
- PORT_Free(org);
- }
-
- return(nickname);
-}
-
-/* CERT_Import_CAChain moved to certhigh.c */
-
-void
-CERT_DestroyCrl (CERTSignedCrl *crl)
-{
- SEC_DestroyCrl (crl);
-}
-
-static int
-cert_Version(CERTCertificate *cert)
-{
- int version = 0;
- if (cert && cert->version.data && cert->version.len) {
- version = DER_GetInteger(&cert->version);
- if (version < 0)
- version = 0;
- }
- return version;
-}
-
-static unsigned int
-cert_ComputeTrustOverrides(CERTCertificate *cert, unsigned int cType)
-{
- CERTCertTrust trust;
- SECStatus rv = SECFailure;
-
- rv = CERT_GetCertTrust(cert, &trust);
-
- if (rv == SECSuccess && (trust.sslFlags |
- trust.emailFlags |
- trust.objectSigningFlags)) {
-
- if (trust.sslFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED))
- cType |= NS_CERT_TYPE_SSL_SERVER|NS_CERT_TYPE_SSL_CLIENT;
- if (trust.sslFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA))
- cType |= NS_CERT_TYPE_SSL_CA;
-#if defined(CERTDB_NOT_TRUSTED)
- if (trust.sslFlags & CERTDB_NOT_TRUSTED)
- cType &= ~(NS_CERT_TYPE_SSL_SERVER|NS_CERT_TYPE_SSL_CLIENT|
- NS_CERT_TYPE_SSL_CA);
-#endif
- if (trust.emailFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED))
- cType |= NS_CERT_TYPE_EMAIL;
- if (trust.emailFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA))
- cType |= NS_CERT_TYPE_EMAIL_CA;
-#if defined(CERTDB_NOT_TRUSTED)
- if (trust.emailFlags & CERTDB_NOT_TRUSTED)
- cType &= ~(NS_CERT_TYPE_EMAIL|NS_CERT_TYPE_EMAIL_CA);
-#endif
- if (trust.objectSigningFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED))
- cType |= NS_CERT_TYPE_OBJECT_SIGNING;
- if (trust.objectSigningFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA))
- cType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
-#if defined(CERTDB_NOT_TRUSTED)
- if (trust.objectSigningFlags & CERTDB_NOT_TRUSTED)
- cType &= ~(NS_CERT_TYPE_OBJECT_SIGNING|
- NS_CERT_TYPE_OBJECT_SIGNING_CA);
-#endif
- }
- return cType;
-}
-
-/*
- * Does a cert belong to a CA? We decide based on perm database trust
- * flags, Netscape Cert Type Extension, and KeyUsage Extension.
- */
-PRBool
-CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype)
-{
- unsigned int cType = cert->nsCertType;
- PRBool ret = PR_FALSE;
-
- if (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
- NS_CERT_TYPE_OBJECT_SIGNING_CA)) {
- ret = PR_TRUE;
- } else {
- SECStatus rv;
- CERTBasicConstraints constraints;
-
- rv = CERT_FindBasicConstraintExten(cert, &constraints);
- if (rv == SECSuccess && constraints.isCA) {
- ret = PR_TRUE;
- cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
- }
- }
-
- /* finally check if it's an X.509 v1 root CA */
- if (!ret &&
- (cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3)) {
- ret = PR_TRUE;
- cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
- }
- /* Now apply trust overrides, if any */
- cType = cert_ComputeTrustOverrides(cert, cType);
- ret = (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
- NS_CERT_TYPE_OBJECT_SIGNING_CA)) ? PR_TRUE : PR_FALSE;
-
- if (rettype != NULL) {
- *rettype = cType;
- }
- return ret;
-}
-
-PRBool
-CERT_IsCADERCert(SECItem *derCert, unsigned int *type) {
- CERTCertificate *cert;
- PRBool isCA;
-
- /* This is okay -- only looks at extensions */
- cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
- if (cert == NULL) return PR_FALSE;
-
- isCA = CERT_IsCACert(cert,type);
- CERT_DestroyCertificate (cert);
- return isCA;
-}
-
-PRBool
-CERT_IsRootDERCert(SECItem *derCert)
-{
- CERTCertificate *cert;
- PRBool isRoot;
-
- /* This is okay -- only looks at extensions */
- cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
- if (cert == NULL) return PR_FALSE;
-
- isRoot = cert->isRoot;
- CERT_DestroyCertificate (cert);
- return isRoot;
-}
-
-CERTCompareValidityStatus
-CERT_CompareValidityTimes(CERTValidity* val_a, CERTValidity* val_b)
-{
- PRTime notBeforeA, notBeforeB, notAfterA, notAfterB;
-
- if (!val_a || !val_b)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return certValidityUndetermined;
- }
-
- if ( SECSuccess != DER_DecodeTimeChoice(&notBeforeA, &val_a->notBefore) ||
- SECSuccess != DER_DecodeTimeChoice(&notBeforeB, &val_b->notBefore) ||
- SECSuccess != DER_DecodeTimeChoice(&notAfterA, &val_a->notAfter) ||
- SECSuccess != DER_DecodeTimeChoice(&notAfterB, &val_b->notAfter) ) {
- return certValidityUndetermined;
- }
-
- /* sanity check */
- if (LL_CMP(notBeforeA,>,notAfterA) || LL_CMP(notBeforeB,>,notAfterB)) {
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return certValidityUndetermined;
- }
-
- if (LL_CMP(notAfterA,!=,notAfterB)) {
- /* one cert validity goes farther into the future, select it */
- return LL_CMP(notAfterA,<,notAfterB) ?
- certValidityChooseB : certValidityChooseA;
- }
- /* the two certs have the same expiration date */
- PORT_Assert(LL_CMP(notAfterA, == , notAfterB));
- /* do they also have the same start date ? */
- if (LL_CMP(notBeforeA,==,notBeforeB)) {
- return certValidityEqual;
- }
- /* choose cert with the later start date */
- return LL_CMP(notBeforeA,<,notBeforeB) ?
- certValidityChooseB : certValidityChooseA;
-}
-
-/*
- * is certa newer than certb? If one is expired, pick the other one.
- */
-PRBool
-CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb)
-{
- PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now;
- SECStatus rv;
- PRBool newerbefore, newerafter;
-
- rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
- if ( rv != SECSuccess ) {
- return(PR_FALSE);
- }
-
- rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
- if ( rv != SECSuccess ) {
- return(PR_TRUE);
- }
-
- newerbefore = PR_FALSE;
- if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
- newerbefore = PR_TRUE;
- }
-
- newerafter = PR_FALSE;
- if ( LL_CMP(notAfterA, >, notAfterB) ) {
- newerafter = PR_TRUE;
- }
-
- if ( newerbefore && newerafter ) {
- return(PR_TRUE);
- }
-
- if ( ( !newerbefore ) && ( !newerafter ) ) {
- return(PR_FALSE);
- }
-
- /* get current time */
- now = PR_Now();
-
- if ( newerbefore ) {
- /* cert A was issued after cert B, but expires sooner */
- /* if A is expired, then pick B */
- if ( LL_CMP(notAfterA, <, now ) ) {
- return(PR_FALSE);
- }
- return(PR_TRUE);
- } else {
- /* cert B was issued after cert A, but expires sooner */
- /* if B is expired, then pick A */
- if ( LL_CMP(notAfterB, <, now ) ) {
- return(PR_TRUE);
- }
- return(PR_FALSE);
- }
-}
-
-void
-CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts)
-{
- unsigned int i;
-
- if ( certs ) {
- for ( i = 0; i < ncerts; i++ ) {
- if ( certs[i] ) {
- CERT_DestroyCertificate(certs[i]);
- }
- }
-
- PORT_Free(certs);
- }
-
- return;
-}
-
-char *
-CERT_FixupEmailAddr(const char *emailAddr)
-{
- char *retaddr;
- char *str;
-
- if ( emailAddr == NULL ) {
- return(NULL);
- }
-
- /* copy the string */
- str = retaddr = PORT_Strdup(emailAddr);
- if ( str == NULL ) {
- return(NULL);
- }
-
- /* make it lower case */
- while ( *str ) {
- *str = tolower( *str );
- str++;
- }
-
- return(retaddr);
-}
-
-/*
- * NOTE - don't allow encode of govt-approved or invisible bits
- */
-SECStatus
-CERT_DecodeTrustString(CERTCertTrust *trust, const char *trusts)
-{
- unsigned int i;
- unsigned int *pflags;
-
- if (!trust) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- trust->sslFlags = 0;
- trust->emailFlags = 0;
- trust->objectSigningFlags = 0;
- if (!trusts) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- pflags = &trust->sslFlags;
-
- for (i=0; i < PORT_Strlen(trusts); i++) {
- switch (trusts[i]) {
- case 'p':
- *pflags = *pflags | CERTDB_TERMINAL_RECORD;
- break;
-
- case 'P':
- *pflags = *pflags | CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD;
- break;
-
- case 'w':
- *pflags = *pflags | CERTDB_SEND_WARN;
- break;
-
- case 'c':
- *pflags = *pflags | CERTDB_VALID_CA;
- break;
-
- case 'T':
- *pflags = *pflags | CERTDB_TRUSTED_CLIENT_CA | CERTDB_VALID_CA;
- break;
-
- case 'C' :
- *pflags = *pflags | CERTDB_TRUSTED_CA | CERTDB_VALID_CA;
- break;
-
- case 'u':
- *pflags = *pflags | CERTDB_USER;
- break;
-
- case 'i':
- *pflags = *pflags | CERTDB_INVISIBLE_CA;
- break;
- case 'g':
- *pflags = *pflags | CERTDB_GOVT_APPROVED_CA;
- break;
-
- case ',':
- if ( pflags == &trust->sslFlags ) {
- pflags = &trust->emailFlags;
- } else {
- pflags = &trust->objectSigningFlags;
- }
- break;
- default:
- return SECFailure;
- }
- }
-
- return SECSuccess;
-}
-
-static void
-EncodeFlags(char *trusts, unsigned int flags)
-{
- if (flags & CERTDB_VALID_CA)
- if (!(flags & CERTDB_TRUSTED_CA) &&
- !(flags & CERTDB_TRUSTED_CLIENT_CA))
- PORT_Strcat(trusts, "c");
- if (flags & CERTDB_TERMINAL_RECORD)
- if (!(flags & CERTDB_TRUSTED))
- PORT_Strcat(trusts, "p");
- if (flags & CERTDB_TRUSTED_CA)
- PORT_Strcat(trusts, "C");
- if (flags & CERTDB_TRUSTED_CLIENT_CA)
- PORT_Strcat(trusts, "T");
- if (flags & CERTDB_TRUSTED)
- PORT_Strcat(trusts, "P");
- if (flags & CERTDB_USER)
- PORT_Strcat(trusts, "u");
- if (flags & CERTDB_SEND_WARN)
- PORT_Strcat(trusts, "w");
- if (flags & CERTDB_INVISIBLE_CA)
- PORT_Strcat(trusts, "I");
- if (flags & CERTDB_GOVT_APPROVED_CA)
- PORT_Strcat(trusts, "G");
- return;
-}
-
-char *
-CERT_EncodeTrustString(CERTCertTrust *trust)
-{
- char tmpTrustSSL[32];
- char tmpTrustEmail[32];
- char tmpTrustSigning[32];
- char *retstr = NULL;
-
- if ( trust ) {
- tmpTrustSSL[0] = '\0';
- tmpTrustEmail[0] = '\0';
- tmpTrustSigning[0] = '\0';
-
- EncodeFlags(tmpTrustSSL, trust->sslFlags);
- EncodeFlags(tmpTrustEmail, trust->emailFlags);
- EncodeFlags(tmpTrustSigning, trust->objectSigningFlags);
-
- retstr = PR_smprintf("%s,%s,%s", tmpTrustSSL, tmpTrustEmail,
- tmpTrustSigning);
- }
-
- return(retstr);
-}
-
-SECStatus
-CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
- unsigned int ncerts, SECItem **derCerts,
- CERTCertificate ***retCerts, PRBool keepCerts,
- PRBool caOnly, char *nickname)
-{
- unsigned int i;
- CERTCertificate **certs = NULL;
- SECStatus rv;
- unsigned int fcerts = 0;
-
- if ( ncerts ) {
- certs = PORT_ZNewArray(CERTCertificate*, ncerts);
- if ( certs == NULL ) {
- return(SECFailure);
- }
-
- /* decode all of the certs into the temporary DB */
- for ( i = 0, fcerts= 0; i < ncerts; i++) {
- certs[fcerts] = CERT_NewTempCertificate(certdb,
- derCerts[i],
- NULL,
- PR_FALSE,
- PR_TRUE);
- if (certs[fcerts]) {
- SECItem subjKeyID = {siBuffer, NULL, 0};
- if (CERT_FindSubjectKeyIDExtension(certs[fcerts],
- &subjKeyID) == SECSuccess) {
- if (subjKeyID.data) {
- cert_AddSubjectKeyIDMapping(&subjKeyID, certs[fcerts]);
- }
- SECITEM_FreeItem(&subjKeyID, PR_FALSE);
- }
- fcerts++;
- }
- }
-
- if ( keepCerts ) {
- for ( i = 0; i < fcerts; i++ ) {
- char* canickname = NULL;
- PRBool isCA;
-
- SECKEY_UpdateCertPQG(certs[i]);
-
- isCA = CERT_IsCACert(certs[i], NULL);
- if ( isCA ) {
- canickname = CERT_MakeCANickname(certs[i]);
- }
-
- if(isCA && (fcerts > 1)) {
- /* if we are importing only a single cert and specifying
- * a nickname, we want to use that nickname if it a CA,
- * otherwise if there are more than one cert, we don't
- * know which cert it belongs to. But we still may try
- * the individual canickname from the cert itself.
- */
- rv = CERT_AddTempCertToPerm(certs[i], canickname, NULL);
- } else {
- rv = CERT_AddTempCertToPerm(certs[i],
- nickname?nickname:canickname, NULL);
- }
-
- PORT_Free(canickname);
- /* don't care if it fails - keep going */
- }
- }
- }
-
- if ( retCerts ) {
- *retCerts = certs;
- } else {
- if (certs) {
- CERT_DestroyCertArray(certs, fcerts);
- }
- }
-
- return ((fcerts || !ncerts) ? SECSuccess : SECFailure);
-}
-
-/*
- * a real list of certificates - need to convert CERTCertificateList
- * stuff and ASN 1 encoder/decoder over to using this...
- */
-CERTCertList *
-CERT_NewCertList(void)
-{
- PRArenaPool *arena = NULL;
- CERTCertList *ret = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- ret = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
- if ( ret == NULL ) {
- goto loser;
- }
-
- ret->arena = arena;
-
- PR_INIT_CLIST(&ret->list);
-
- return(ret);
-
-loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-void
-CERT_DestroyCertList(CERTCertList *certs)
-{
- PRCList *node;
-
- while( !PR_CLIST_IS_EMPTY(&certs->list) ) {
- node = PR_LIST_HEAD(&certs->list);
- CERT_DestroyCertificate(((CERTCertListNode *)node)->cert);
- PR_REMOVE_LINK(node);
- }
-
- PORT_FreeArena(certs->arena, PR_FALSE);
-
- return;
-}
-
-void
-CERT_RemoveCertListNode(CERTCertListNode *node)
-{
- CERT_DestroyCertificate(node->cert);
- PR_REMOVE_LINK(&node->links);
- return;
-}
-
-
-SECStatus
-CERT_AddCertToListTailWithData(CERTCertList *certs,
- CERTCertificate *cert, void *appData)
-{
- CERTCertListNode *node;
-
- node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
- sizeof(CERTCertListNode));
- if ( node == NULL ) {
- goto loser;
- }
-
- PR_INSERT_BEFORE(&node->links, &certs->list);
- /* certs->count++; */
- node->cert = cert;
- node->appData = appData;
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-SECStatus
-CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert)
-{
- return CERT_AddCertToListTailWithData(certs, cert, NULL);
-}
-
-SECStatus
-CERT_AddCertToListHeadWithData(CERTCertList *certs,
- CERTCertificate *cert, void *appData)
-{
- CERTCertListNode *node;
- CERTCertListNode *head;
-
- head = CERT_LIST_HEAD(certs);
-
- if (head == NULL) return CERT_AddCertToListTail(certs,cert);
-
- node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
- sizeof(CERTCertListNode));
- if ( node == NULL ) {
- goto loser;
- }
-
- PR_INSERT_BEFORE(&node->links, &head->links);
- /* certs->count++; */
- node->cert = cert;
- node->appData = appData;
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-SECStatus
-CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert)
-{
- return CERT_AddCertToListHeadWithData(certs, cert, NULL);
-}
-
-/*
- * Sort callback function to determine if cert a is newer than cert b.
- * Not valid certs are considered older than valid certs.
- */
-PRBool
-CERT_SortCBValidity(CERTCertificate *certa,
- CERTCertificate *certb,
- void *arg)
-{
- PRTime sorttime;
- PRTime notBeforeA, notAfterA, notBeforeB, notAfterB;
- SECStatus rv;
- PRBool newerbefore, newerafter;
- PRBool aNotValid = PR_FALSE, bNotValid = PR_FALSE;
-
- sorttime = *(PRTime *)arg;
-
- rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
- if ( rv != SECSuccess ) {
- return(PR_FALSE);
- }
-
- rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
- if ( rv != SECSuccess ) {
- return(PR_TRUE);
- }
- newerbefore = PR_FALSE;
- if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
- newerbefore = PR_TRUE;
- }
- newerafter = PR_FALSE;
- if ( LL_CMP(notAfterA, >, notAfterB) ) {
- newerafter = PR_TRUE;
- }
-
- /* check if A is valid at sorttime */
- if ( CERT_CheckCertValidTimes(certa, sorttime, PR_FALSE)
- != secCertTimeValid ) {
- aNotValid = PR_TRUE;
- }
-
- /* check if B is valid at sorttime */
- if ( CERT_CheckCertValidTimes(certb, sorttime, PR_FALSE)
- != secCertTimeValid ) {
- bNotValid = PR_TRUE;
- }
-
- /* a is valid, b is not */
- if ( bNotValid && ( ! aNotValid ) ) {
- return(PR_TRUE);
- }
-
- /* b is valid, a is not */
- if ( aNotValid && ( ! bNotValid ) ) {
- return(PR_FALSE);
- }
-
- /* a and b are either valid or not valid */
- if ( newerbefore && newerafter ) {
- return(PR_TRUE);
- }
-
- if ( ( !newerbefore ) && ( !newerafter ) ) {
- return(PR_FALSE);
- }
-
- if ( newerbefore ) {
- /* cert A was issued after cert B, but expires sooner */
- return(PR_TRUE);
- } else {
- /* cert B was issued after cert A, but expires sooner */
- return(PR_FALSE);
- }
-}
-
-
-SECStatus
-CERT_AddCertToListSorted(CERTCertList *certs,
- CERTCertificate *cert,
- CERTSortCallback f,
- void *arg)
-{
- CERTCertListNode *node;
- CERTCertListNode *head;
- PRBool ret;
-
- node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
- sizeof(CERTCertListNode));
- if ( node == NULL ) {
- goto loser;
- }
-
- head = CERT_LIST_HEAD(certs);
-
- while ( !CERT_LIST_END(head, certs) ) {
-
- /* if cert is already in the list, then don't add it again */
- if ( cert == head->cert ) {
- /*XXX*/
- /* don't keep a reference */
- CERT_DestroyCertificate(cert);
- goto done;
- }
-
- ret = (* f)(cert, head->cert, arg);
- /* if sort function succeeds, then insert before current node */
- if ( ret ) {
- PR_INSERT_BEFORE(&node->links, &head->links);
- goto done;
- }
-
- head = CERT_LIST_NEXT(head);
- }
- /* if we get to the end, then just insert it at the tail */
- PR_INSERT_BEFORE(&node->links, &certs->list);
-
-done:
- /* certs->count++; */
- node->cert = cert;
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/* This routine is here because pcertdb.c still has a call to it.
- * The SMIME profile code in pcertdb.c should be split into high (find
- * the email cert) and low (store the profile) code. At that point, we
- * can move this to certhigh.c where it belongs.
- *
- * remove certs from a list that don't have keyUsage and certType
- * that match the given usage.
- */
-SECStatus
-CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage,
- PRBool ca)
-{
- unsigned int requiredKeyUsage;
- unsigned int requiredCertType;
- CERTCertListNode *node, *savenode;
- SECStatus rv;
-
- if (certList == NULL) goto loser;
-
- rv = CERT_KeyUsageAndTypeForCertUsage(usage, ca, &requiredKeyUsage,
- &requiredCertType);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- node = CERT_LIST_HEAD(certList);
-
- while ( !CERT_LIST_END(node, certList) ) {
-
- PRBool bad = (PRBool)(!node->cert);
-
- /* bad key usage ? */
- if ( !bad &&
- CERT_CheckKeyUsage(node->cert, requiredKeyUsage) != SECSuccess ) {
- bad = PR_TRUE;
- }
- /* bad cert type ? */
- if ( !bad ) {
- unsigned int certType = 0;
- if ( ca ) {
- /* This function returns a more comprehensive cert type that
- * takes trust flags into consideration. Should probably
- * fix the cert decoding code to do this.
- */
- (void)CERT_IsCACert(node->cert, &certType);
- } else {
- certType = node->cert->nsCertType;
- }
- if ( !( certType & requiredCertType ) ) {
- bad = PR_TRUE;
- }
- }
-
- if ( bad ) {
- /* remove the node if it is bad */
- savenode = CERT_LIST_NEXT(node);
- CERT_RemoveCertListNode(node);
- node = savenode;
- } else {
- node = CERT_LIST_NEXT(node);
- }
- }
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-PRBool CERT_IsUserCert(CERTCertificate* cert)
-{
- CERTCertTrust trust;
- SECStatus rv = SECFailure;
-
- rv = CERT_GetCertTrust(cert, &trust);
- if (rv == SECSuccess &&
- ((trust.sslFlags & CERTDB_USER ) ||
- (trust.emailFlags & CERTDB_USER ) ||
- (trust.objectSigningFlags & CERTDB_USER )) ) {
- return PR_TRUE;
- } else {
- return PR_FALSE;
- }
-}
-
-SECStatus
-CERT_FilterCertListForUserCerts(CERTCertList *certList)
-{
- CERTCertListNode *node, *freenode;
- CERTCertificate *cert;
-
- if (!certList) {
- return SECFailure;
- }
-
- node = CERT_LIST_HEAD(certList);
-
- while ( ! CERT_LIST_END(node, certList) ) {
- cert = node->cert;
- if ( PR_TRUE != CERT_IsUserCert(cert) ) {
- /* Not a User Cert, so remove this cert from the list */
- freenode = node;
- node = CERT_LIST_NEXT(node);
- CERT_RemoveCertListNode(freenode);
- } else {
- /* Is a User cert, so leave it in the list */
- node = CERT_LIST_NEXT(node);
- }
- }
-
- return(SECSuccess);
-}
-
-static PZLock *certRefCountLock = NULL;
-
-/*
- * Acquire the cert reference count lock
- * There is currently one global lock for all certs, but I'm putting a cert
- * arg here so that it will be easy to make it per-cert in the future if
- * that turns out to be necessary.
- */
-void
-CERT_LockCertRefCount(CERTCertificate *cert)
-{
- PORT_Assert(certRefCountLock != NULL);
- PZ_Lock(certRefCountLock);
- return;
-}
-
-/*
- * Free the cert reference count lock
- */
-void
-CERT_UnlockCertRefCount(CERTCertificate *cert)
-{
- PRStatus prstat;
-
- PORT_Assert(certRefCountLock != NULL);
-
- prstat = PZ_Unlock(certRefCountLock);
-
- PORT_Assert(prstat == PR_SUCCESS);
-
- return;
-}
-
-static PZLock *certTrustLock = NULL;
-
-/*
- * Acquire the cert trust lock
- * There is currently one global lock for all certs, but I'm putting a cert
- * arg here so that it will be easy to make it per-cert in the future if
- * that turns out to be necessary.
- */
-void
-CERT_LockCertTrust(CERTCertificate *cert)
-{
- PORT_Assert(certTrustLock != NULL);
- PZ_Lock(certTrustLock);
- return;
-}
-
-SECStatus
-cert_InitLocks(void)
-{
- if ( certRefCountLock == NULL ) {
- certRefCountLock = PZ_NewLock(nssILockRefLock);
- PORT_Assert(certRefCountLock != NULL);
- if (!certRefCountLock) {
- return SECFailure;
- }
- }
-
- if ( certTrustLock == NULL ) {
- certTrustLock = PZ_NewLock(nssILockCertDB);
- PORT_Assert(certTrustLock != NULL);
- if (!certTrustLock) {
- PZ_DestroyLock(certRefCountLock);
- certRefCountLock = NULL;
- return SECFailure;
- }
- }
-
- return SECSuccess;
-}
-
-SECStatus
-cert_DestroyLocks(void)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(certRefCountLock != NULL);
- if (certRefCountLock) {
- PZ_DestroyLock(certRefCountLock);
- certRefCountLock = NULL;
- } else {
- rv = SECFailure;
- }
-
- PORT_Assert(certTrustLock != NULL);
- if (certTrustLock) {
- PZ_DestroyLock(certTrustLock);
- certTrustLock = NULL;
- } else {
- rv = SECFailure;
- }
- return rv;
-}
-
-/*
- * Free the cert trust lock
- */
-void
-CERT_UnlockCertTrust(CERTCertificate *cert)
-{
- PRStatus prstat;
-
- PORT_Assert(certTrustLock != NULL);
-
- prstat = PZ_Unlock(certTrustLock);
-
- PORT_Assert(prstat == PR_SUCCESS);
-
- return;
-}
-
-
-/*
- * Get the StatusConfig data for this handle
- */
-CERTStatusConfig *
-CERT_GetStatusConfig(CERTCertDBHandle *handle)
-{
- return handle->statusConfig;
-}
-
-/*
- * Set the StatusConfig data for this handle. There
- * should not be another configuration set.
- */
-void
-CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig)
-{
- PORT_Assert(handle->statusConfig == NULL);
- handle->statusConfig = statusConfig;
-}
-
-/*
- * Code for dealing with subjKeyID to cert mappings.
- */
-
-static PLHashTable *gSubjKeyIDHash = NULL;
-static PRLock *gSubjKeyIDLock = NULL;
-static PLHashTable *gSubjKeyIDSlotCheckHash = NULL;
-static PRLock *gSubjKeyIDSlotCheckLock = NULL;
-
-static void *cert_AllocTable(void *pool, PRSize size)
-{
- return PORT_Alloc(size);
-}
-
-static void cert_FreeTable(void *pool, void *item)
-{
- PORT_Free(item);
-}
-
-static PLHashEntry* cert_AllocEntry(void *pool, const void *key)
-{
- return PORT_New(PLHashEntry);
-}
-
-static void cert_FreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
-{
- SECITEM_FreeItem((SECItem*)(he->value), PR_TRUE);
- if (flag == HT_FREE_ENTRY) {
- SECITEM_FreeItem((SECItem*)(he->key), PR_TRUE);
- PORT_Free(he);
- }
-}
-
-static PLHashAllocOps cert_AllocOps = {
- cert_AllocTable, cert_FreeTable, cert_AllocEntry, cert_FreeEntry
-};
-
-SECStatus
-cert_CreateSubjectKeyIDSlotCheckHash(void)
-{
- /*
- * This hash is used to remember the series of a slot
- * when we last checked for user certs
- */
- gSubjKeyIDSlotCheckHash = PL_NewHashTable(0, SECITEM_Hash,
- SECITEM_HashCompare,
- SECITEM_HashCompare,
- &cert_AllocOps, NULL);
- if (!gSubjKeyIDSlotCheckHash) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- gSubjKeyIDSlotCheckLock = PR_NewLock();
- if (!gSubjKeyIDSlotCheckLock) {
- PL_HashTableDestroy(gSubjKeyIDSlotCheckHash);
- gSubjKeyIDSlotCheckHash = NULL;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-cert_CreateSubjectKeyIDHashTable(void)
-{
- gSubjKeyIDHash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
- SECITEM_HashCompare,
- &cert_AllocOps, NULL);
- if (!gSubjKeyIDHash) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- gSubjKeyIDLock = PR_NewLock();
- if (!gSubjKeyIDLock) {
- PL_HashTableDestroy(gSubjKeyIDHash);
- gSubjKeyIDHash = NULL;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- /* initialize the companion hash (for remembering slot series) */
- if (cert_CreateSubjectKeyIDSlotCheckHash() != SECSuccess) {
- cert_DestroySubjectKeyIDHashTable();
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert)
-{
- SECItem *newKeyID, *oldVal, *newVal;
- SECStatus rv = SECFailure;
-
- if (!gSubjKeyIDLock) {
- /* If one is created, then both are there. So only check for one. */
- return SECFailure;
- }
-
- newVal = SECITEM_DupItem(&cert->derCert);
- if (!newVal) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto done;
- }
- newKeyID = SECITEM_DupItem(subjKeyID);
- if (!newKeyID) {
- SECITEM_FreeItem(newVal, PR_TRUE);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto done;
- }
-
- PR_Lock(gSubjKeyIDLock);
- /* The hash table implementation does not free up the memory
- * associated with the key of an already existing entry if we add a
- * duplicate, so we would wind up leaking the previously allocated
- * key if we don't remove before adding.
- */
- oldVal = (SECItem*)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID);
- if (oldVal) {
- PL_HashTableRemove(gSubjKeyIDHash, subjKeyID);
- }
-
- rv = (PL_HashTableAdd(gSubjKeyIDHash, newKeyID, newVal)) ? SECSuccess :
- SECFailure;
- PR_Unlock(gSubjKeyIDLock);
-done:
- return rv;
-}
-
-SECStatus
-cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID)
-{
- SECStatus rv;
- if (!gSubjKeyIDLock)
- return SECFailure;
-
- PR_Lock(gSubjKeyIDLock);
- rv = (PL_HashTableRemove(gSubjKeyIDHash, subjKeyID)) ? SECSuccess :
- SECFailure;
- PR_Unlock(gSubjKeyIDLock);
- return rv;
-}
-
-SECStatus
-cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series)
-{
- SECItem *oldSeries, *newSlotid, *newSeries;
- SECStatus rv = SECFailure;
-
- if (!gSubjKeyIDSlotCheckLock) {
- return rv;
- }
-
- newSlotid = SECITEM_DupItem(slotid);
- newSeries = SECITEM_AllocItem(NULL, NULL, sizeof(int));
- if (!newSlotid || !newSeries ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(newSeries->data, &series, sizeof(int));
-
- PR_Lock(gSubjKeyIDSlotCheckLock);
- oldSeries = (SECItem *)PL_HashTableLookup(gSubjKeyIDSlotCheckHash, slotid);
- if (oldSeries) {
- /*
- * make sure we don't leak the key of an existing entry
- * (similar to cert_AddSubjectKeyIDMapping, see comment there)
- */
- PL_HashTableRemove(gSubjKeyIDSlotCheckHash, slotid);
- }
- rv = (PL_HashTableAdd(gSubjKeyIDSlotCheckHash, newSlotid, newSeries)) ?
- SECSuccess : SECFailure;
- PR_Unlock(gSubjKeyIDSlotCheckLock);
- if (rv == SECSuccess) {
- return rv;
- }
-
-loser:
- if (newSlotid) {
- SECITEM_FreeItem(newSlotid, PR_TRUE);
- }
- if (newSeries) {
- SECITEM_FreeItem(newSeries, PR_TRUE);
- }
- return rv;
-}
-
-int
-cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid)
-{
- SECItem *seriesItem = NULL;
- int series;
-
- if (!gSubjKeyIDSlotCheckLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return -1;
- }
-
- PR_Lock(gSubjKeyIDSlotCheckLock);
- seriesItem = (SECItem *)PL_HashTableLookup(gSubjKeyIDSlotCheckHash, slotid);
- PR_Unlock(gSubjKeyIDSlotCheckLock);
- /* getting a null series just means we haven't registered one yet,
- * just return 0 */
- if (seriesItem == NULL) {
- return 0;
- }
- /* if we got a series back, assert if it's not the proper length. */
- PORT_Assert(seriesItem->len == sizeof(int));
- if (seriesItem->len != sizeof(int)) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return -1;
- }
- PORT_Memcpy(&series, seriesItem->data, sizeof(int));
- return series;
-}
-
-SECStatus
-cert_DestroySubjectKeyIDSlotCheckHash(void)
-{
- if (gSubjKeyIDSlotCheckHash) {
- PR_Lock(gSubjKeyIDSlotCheckLock);
- PL_HashTableDestroy(gSubjKeyIDSlotCheckHash);
- gSubjKeyIDSlotCheckHash = NULL;
- PR_Unlock(gSubjKeyIDSlotCheckLock);
- PR_DestroyLock(gSubjKeyIDSlotCheckLock);
- gSubjKeyIDSlotCheckLock = NULL;
- }
- return SECSuccess;
-}
-
-SECStatus
-cert_DestroySubjectKeyIDHashTable(void)
-{
- if (gSubjKeyIDHash) {
- PR_Lock(gSubjKeyIDLock);
- PL_HashTableDestroy(gSubjKeyIDHash);
- gSubjKeyIDHash = NULL;
- PR_Unlock(gSubjKeyIDLock);
- PR_DestroyLock(gSubjKeyIDLock);
- gSubjKeyIDLock = NULL;
- }
- cert_DestroySubjectKeyIDSlotCheckHash();
- return SECSuccess;
-}
-
-SECItem*
-cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID)
-{
- SECItem *val;
-
- if (!gSubjKeyIDLock)
- return NULL;
-
- PR_Lock(gSubjKeyIDLock);
- val = (SECItem*)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID);
- if (val) {
- val = SECITEM_DupItem(val);
- }
- PR_Unlock(gSubjKeyIDLock);
- return val;
-}
-
-CERTCertificate*
-CERT_FindCertBySubjectKeyID(CERTCertDBHandle *handle, SECItem *subjKeyID)
-{
- CERTCertificate *cert = NULL;
- SECItem *derCert;
-
- derCert = cert_FindDERCertBySubjectKeyID(subjKeyID);
- if (derCert) {
- cert = CERT_FindCertByDERCert(handle, derCert);
- SECITEM_FreeItem(derCert, PR_TRUE);
- }
- return cert;
-}
diff --git a/security/nss/lib/certdb/certdb.h b/security/nss/lib/certdb/certdb.h
deleted file mode 100644
index 1c58f17be..000000000
--- a/security/nss/lib/certdb/certdb.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _CERTDB_H_
-#define _CERTDB_H_
-
-
-/* common flags for all types of certificates */
-#define CERTDB_TERMINAL_RECORD (1<<0)
-#define CERTDB_TRUSTED (1<<1)
-#define CERTDB_SEND_WARN (1<<2)
-#define CERTDB_VALID_CA (1<<3)
-#define CERTDB_TRUSTED_CA (1<<4) /* trusted for issuing server certs */
-#define CERTDB_NS_TRUSTED_CA (1<<5)
-#define CERTDB_USER (1<<6)
-#define CERTDB_TRUSTED_CLIENT_CA (1<<7) /* trusted for issuing client certs */
-#define CERTDB_INVISIBLE_CA (1<<8) /* don't show in UI */
-#define CERTDB_GOVT_APPROVED_CA (1<<9) /* can do strong crypto in export ver */
-
-/* old usage, to keep old programs compiling */
-/* On Windows, Mac, and Linux (and other gcc platforms), we can give compile
- * time deprecation warnings when applications use the old CERTDB_VALID_PEER
- * define */
-#if __GNUC__ > 3
-#if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
-typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated));
-#else
-typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated
- ("CERTDB_VALID_PEER is now CERTDB_TERMINAL_RECORD")));
-#endif
-#define CERTDB_VALID_PEER ((__CERTDB_VALID_PEER) CERTDB_TERMINAL_RECORD)
-#else
-#ifdef _WIN32
-#pragma deprecated(CERTDB_VALID_PEER)
-#endif
-#define CERTDB_VALID_PEER CERTDB_TERMINAL_RECORD
-#endif
-
-SEC_BEGIN_PROTOS
-
-CERTSignedCrl *
-SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type);
-
-CERTSignedCrl *
-SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type);
-
-CERTSignedCrl *
-SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type);
-
-PRBool
-SEC_CertNicknameConflict(const char *nickname, SECItem *derSubject,
- CERTCertDBHandle *handle);
-CERTSignedCrl *
-SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type);
-
-SECStatus
-SEC_DeletePermCRL(CERTSignedCrl *crl);
-
-
-SECStatus
-SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type);
-
-SECStatus
-SEC_DestroyCrl(CERTSignedCrl *crl);
-
-CERTSignedCrl* SEC_DupCrl(CERTSignedCrl* acrl);
-
-SECStatus
-CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
- CERTCertTrust *trust);
-
-SECStatus SEC_DeletePermCertificate(CERTCertificate *cert);
-
-PRBool
-SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
-
-SECCertTimeValidity
-SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
-
-SEC_END_PROTOS
-
-#endif /* _CERTDB_H_ */
diff --git a/security/nss/lib/certdb/certi.h b/security/nss/lib/certdb/certi.h
deleted file mode 100644
index 2b783ae37..000000000
--- a/security/nss/lib/certdb/certi.h
+++ /dev/null
@@ -1,383 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * certi.h - private data structures for the certificate library
- *
- * $Id$
- */
-#ifndef _CERTI_H_
-#define _CERTI_H_
-
-#include "certt.h"
-#include "nssrwlkt.h"
-
-/*
-#define GLOBAL_RWLOCK 1
-*/
-
-#define DPC_RWLOCK 1
-
-/* all definitions in this file are subject to change */
-
-typedef struct OpaqueCRLFieldsStr OpaqueCRLFields;
-typedef struct CRLEntryCacheStr CRLEntryCache;
-typedef struct CRLDPCacheStr CRLDPCache;
-typedef struct CRLIssuerCacheStr CRLIssuerCache;
-typedef struct CRLCacheStr CRLCache;
-typedef struct CachedCrlStr CachedCrl;
-typedef struct NamedCRLCacheStr NamedCRLCache;
-typedef struct NamedCRLCacheEntryStr NamedCRLCacheEntry;
-
-struct OpaqueCRLFieldsStr {
- PRBool partial;
- PRBool decodingError;
- PRBool badEntries;
- PRBool badDER;
- PRBool badExtensions;
- PRBool heapDER;
-};
-
-typedef struct PreAllocatorStr PreAllocator;
-
-struct PreAllocatorStr
-{
- PRSize len;
- void* data;
- PRSize used;
- PRArenaPool* arena;
- PRSize extra;
-};
-
-/* CRL entry cache.
- This is the same as an entry plus the next/prev pointers for the hash table
-*/
-
-struct CRLEntryCacheStr {
- CERTCrlEntry entry;
- CRLEntryCache *prev, *next;
-};
-
-#define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set
- if we have CRL objects with an invalid DER or signature. Can be
- cleared if the invalid objects are deleted from the token */
-#define CRL_CACHE_LAST_FETCH_FAILED 0x0002 /* this state will be set
- if the last CRL fetch encountered an error. Can be cleared if a
- new fetch succeeds */
-
-#define CRL_CACHE_OUT_OF_MEMORY 0x0004 /* this state will be set
- if we don't have enough memory to build the hash table of entries */
-
-typedef enum {
- CRL_OriginToken = 0, /* CRL came from PKCS#11 token */
- CRL_OriginExplicit = 1 /* CRL was explicitly added to the cache, from RAM */
-} CRLOrigin;
-
-typedef enum {
- dpcacheNoEntry = 0, /* no entry found for this SN */
- dpcacheFoundEntry = 1, /* entry found for this SN */
- dpcacheCallerError = 2, /* invalid args */
- dpcacheInvalidCacheError = 3, /* CRL in cache may be bad DER */
- /* or unverified */
- dpcacheEmpty = 4, /* no CRL in cache */
- dpcacheLookupError = 5 /* internal error */
-} dpcacheStatus;
-
-
-struct CachedCrlStr {
- CERTSignedCrl* crl;
- CRLOrigin origin;
- /* hash table of entries. We use a PLHashTable and pre-allocate the
- required amount of memory in one shot, so that our allocator can
- simply pass offsets into it when hashing.
-
- This won't work anymore when we support delta CRLs and iCRLs, because
- the size of the hash table will vary over time. At that point, the best
- solution will be to allocate large CRLEntry structures by modifying
- the DER decoding template. The extra space would be for next/prev
- pointers. This would allow entries from different CRLs to be mixed in
- the same hash table.
- */
- PLHashTable* entries;
- PreAllocator* prebuffer; /* big pre-allocated buffer mentioned above */
- PRBool sigChecked; /* this CRL signature has already been checked */
- PRBool sigValid; /* signature verification status .
- Only meaningful if checked is PR_TRUE . */
- PRBool unbuildable; /* Avoid using assosiated CRL is it fails
- * a decoding step */
-};
-
-/* CRL distribution point cache object
- This is a cache of CRL entries for a given distribution point of an issuer
- It is built from a collection of one full and 0 or more delta CRLs.
-*/
-
-struct CRLDPCacheStr {
-#ifdef DPC_RWLOCK
- NSSRWLock* lock;
-#else
- PRLock* lock;
-#endif
- CERTCertificate* issuer; /* issuer cert
- XXX there may be multiple issuer certs,
- with different validity dates. Also
- need to deal with SKID/AKID . See
- bugzilla 217387, 233118 */
- SECItem* subject; /* DER of issuer subject */
- SECItem* distributionPoint; /* DER of distribution point. This may be
- NULL when distribution points aren't
- in use (ie. the CA has a single CRL).
- Currently not used. */
-
- /* array of full CRLs matching this distribution point */
- PRUint32 ncrls; /* total number of CRLs in crls */
- CachedCrl** crls; /* array of all matching CRLs */
- /* XCRL With iCRLs and multiple DPs, the CRL can be shared accross several
- issuers. In the future, we'll need to globally recycle the CRL in a
- separate list in order to avoid extra lookups, decodes, and copies */
-
- /* pointers to good decoded CRLs used to build the cache */
- CachedCrl* selected; /* full CRL selected for use in the cache */
-#if 0
- /* for future use */
- PRInt32 numdeltas; /* number of delta CRLs used for the cache */
- CachedCrl** deltas; /* delta CRLs used for the cache */
-#endif
- /* cache invalidity bitflag */
- PRUint16 invalid; /* this state will be set if either
- CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set.
- In those cases, all certs are considered to have unknown status.
- The invalid state can only be cleared during an update if all
- error states are cleared */
- PRBool refresh; /* manual refresh from tokens has been forced */
- PRBool mustchoose; /* trigger reselection algorithm, for case when
- RAM CRL objects are dropped from the cache */
- PRTime lastfetch; /* time a CRL token fetch was last performed */
- PRTime lastcheck; /* time CRL token objects were last checked for
- existence */
-};
-
-/* CRL issuer cache object
- This object tracks all the distribution point caches for a given issuer.
- XCRL once we support multiple issuing distribution points, this object
- will be a hash table. For now, it just holds the single CRL distribution
- point cache structure.
-*/
-
-struct CRLIssuerCacheStr {
- SECItem* subject; /* DER of issuer subject */
- CRLDPCache* dpp;
-#if 0
- /* XCRL for future use.
- We don't need to lock at the moment because we only have one DP,
- which gets created at the same time as this object */
- NSSRWLock* lock;
- CRLDPCache** dps;
- PLHashTable* distributionpoints;
- CERTCertificate* issuer;
-#endif
-};
-
-/* CRL revocation cache object
- This object tracks all the issuer caches
-*/
-
-struct CRLCacheStr {
-#ifdef GLOBAL_RWLOCK
- NSSRWLock* lock;
-#else
- PRLock* lock;
-#endif
- /* hash table of issuer to CRLIssuerCacheStr,
- indexed by issuer DER subject */
- PLHashTable* issuers;
-};
-
-SECStatus InitCRLCache(void);
-SECStatus ShutdownCRLCache(void);
-
-/* Returns a pointer to an environment-like string, a series of
-** null-terminated strings, terminated by a zero-length string.
-** This function is intended to be internal to NSS.
-*/
-extern char * cert_GetCertificateEmailAddresses(CERTCertificate *cert);
-
-/*
- * These functions are used to map subjectKeyID extension values to certs
- * and to keep track of the checks for user certificates in each slot
- */
-SECStatus
-cert_CreateSubjectKeyIDHashTable(void);
-
-SECStatus
-cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert);
-
-SECStatus
-cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series);
-
-int
-cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid);
-
-/*
- * Call this function to remove an entry from the mapping table.
- */
-SECStatus
-cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID);
-
-SECStatus
-cert_DestroySubjectKeyIDHashTable(void);
-
-SECItem*
-cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID);
-
-/* return maximum length of AVA value based on its type OID tag. */
-extern int cert_AVAOidTagToMaxLen(SECOidTag tag);
-
-/* Make an AVA, allocated from pool, from OID and DER encoded value */
-extern CERTAVA * CERT_CreateAVAFromRaw(PRArenaPool *pool,
- const SECItem * OID, const SECItem * value);
-
-/* Make an AVA from binary input specified by SECItem */
-extern CERTAVA * CERT_CreateAVAFromSECItem(PRArenaPool *arena, SECOidTag kind,
- int valueType, SECItem *value);
-
-/*
- * get a DPCache object for the given issuer subject and dp
- * Automatically creates the cache object if it doesn't exist yet.
- */
-SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
- const SECItem* dp, int64 t, void* wincx,
- CRLDPCache** dpcache, PRBool* writeLocked);
-
-/* check if a particular SN is in the CRL cache and return its entry */
-dpcacheStatus DPCache_Lookup(CRLDPCache* cache, SECItem* sn,
- CERTCrlEntry** returned);
-
-/* release a DPCache object that was previously acquired */
-void ReleaseDPCache(CRLDPCache* dpcache, PRBool writeLocked);
-
-/*
- * map Stan errors into NSS errors
- * This function examines the stan error stack and automatically sets
- * PORT_SetError(); to the appropriate SEC_ERROR value.
- */
-void CERT_MapStanError();
-
-/* Interface function for libpkix cert validation engine:
- * cert_verify wrapper. */
-SECStatus
-cert_VerifyCertChainPkix(CERTCertificate *cert,
- PRBool checkSig,
- SECCertUsage requiredUsage,
- PRTime time,
- void *wincx,
- CERTVerifyLog *log,
- PRBool *sigError,
- PRBool *revoked);
-
-SECStatus cert_InitLocks(void);
-
-SECStatus cert_DestroyLocks(void);
-
-/*
- * fill in nsCertType field of the cert based on the cert extension
- */
-extern SECStatus cert_GetCertType(CERTCertificate *cert);
-
-/*
- * compute and return the value of nsCertType for cert, but do not
- * update the CERTCertificate.
- */
-extern PRUint32 cert_ComputeCertType(CERTCertificate *cert);
-
-void cert_AddToVerifyLog(CERTVerifyLog *log,CERTCertificate *cert,
- long errorCode, unsigned int depth,
- void *arg);
-
-/* Insert a DER CRL into the CRL cache, and take ownership of it.
- *
- * cert_CacheCRLByGeneralName takes ownership of the memory in crl argument
- * completely. crl must be freeable by SECITEM_FreeItem. It will be freed
- * immediately if it is rejected from the CRL cache, or later during cache
- * updates when a new crl is available, or at shutdown time.
- *
- * canonicalizedName represents the source of the CRL, a GeneralName.
- * The format of the encoding is not restricted, but all callers of
- * cert_CacheCRLByGeneralName and cert_FindCRLByGeneralName must use
- * the same encoding. To facilitate X.500 name matching, a canonicalized
- * encoding of the GeneralName should be used, if available.
- */
-
-SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
- const SECItem* canonicalizedName);
-
-struct NamedCRLCacheStr {
- PRLock* lock;
- PLHashTable* entries;
-};
-
-/* NamedCRLCacheEntryStr is filled in by cert_CacheCRLByGeneralName,
- * and read by cert_FindCRLByGeneralName */
-struct NamedCRLCacheEntryStr {
- SECItem* canonicalizedName;
- SECItem* crl; /* DER, kept only if CRL
- * is successfully cached */
- PRBool inCRLCache;
- PRTime successfulInsertionTime; /* insertion time */
- PRTime lastAttemptTime; /* time of last call to
- cert_CacheCRLByGeneralName with this name */
- PRBool badDER; /* ASN.1 error */
- PRBool dupe; /* matching DER CRL already in CRL cache */
- PRBool unsupported; /* IDP, delta, any other reason */
-};
-
-typedef enum {
- certRevocationStatusRevoked = 0,
- certRevocationStatusValid = 1,
- certRevocationStatusUnknown = 2
-} CERTRevocationStatus;
-
-/* Returns detailed status of the cert(revStatus variable). Tells if
- * issuer cache has OriginFetchedWithTimeout crl in it. */
-SECStatus
-cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
- const SECItem* dp, PRTime t, void *wincx,
- CERTRevocationStatus *revStatus,
- CERTCRLEntryReasonCode *revReason);
-
-
-SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned);
-
-/* cert_FindCRLByGeneralName must be called only while the named cache is
- * acquired, and the entry is only valid until cache is released.
- */
-SECStatus cert_FindCRLByGeneralName(NamedCRLCache* ncc,
- const SECItem* canonicalizedName,
- NamedCRLCacheEntry** retEntry);
-
-SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc);
-
-/* This is private for now. Maybe shoule be public. */
-CERTGeneralName *
-cert_GetSubjectAltNameList(CERTCertificate *cert, PRArenaPool *arena);
-
-/* Count DNS names and IP addresses in a list of GeneralNames */
-PRUint32
-cert_CountDNSPatterns(CERTGeneralName *firstName);
-
-/*
- * returns the trust status of the leaf certificate based on usage.
- * If the leaf is explicitly untrusted, this function will fail and
- * failedFlags will be set to the trust bit value that lead to the failure.
- * If the leaf is trusted, isTrusted is set to true and the function returns
- * SECSuccess. This function does not check if the cert is fit for a
- * particular usage.
- */
-SECStatus
-cert_CheckLeafTrust(CERTCertificate *cert,
- SECCertUsage usage,
- unsigned int *failedFlags,
- PRBool *isTrusted);
-
-#endif /* _CERTI_H_ */
-
diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h
deleted file mode 100644
index 681041b00..000000000
--- a/security/nss/lib/certdb/certt.h
+++ /dev/null
@@ -1,1345 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * certt.h - public data structures for the certificate library
- *
- * $Id$
- */
-#ifndef _CERTT_H_
-#define _CERTT_H_
-
-#include "prclist.h"
-#include "pkcs11t.h"
-#include "seccomon.h"
-#include "secmodt.h"
-#include "secoidt.h"
-#include "plarena.h"
-#include "prcvar.h"
-#include "nssilock.h"
-#include "prio.h"
-#include "prmon.h"
-
-/* Stan data types */
-struct NSSCertificateStr;
-struct NSSTrustDomainStr;
-
-/* Non-opaque objects */
-typedef struct CERTAVAStr CERTAVA;
-typedef struct CERTAttributeStr CERTAttribute;
-typedef struct CERTAuthInfoAccessStr CERTAuthInfoAccess;
-typedef struct CERTAuthKeyIDStr CERTAuthKeyID;
-typedef struct CERTBasicConstraintsStr CERTBasicConstraints;
-typedef struct NSSTrustDomainStr CERTCertDBHandle;
-typedef struct CERTCertExtensionStr CERTCertExtension;
-typedef struct CERTCertKeyStr CERTCertKey;
-typedef struct CERTCertListStr CERTCertList;
-typedef struct CERTCertListNodeStr CERTCertListNode;
-typedef struct CERTCertNicknamesStr CERTCertNicknames;
-typedef struct CERTCertTrustStr CERTCertTrust;
-typedef struct CERTCertificateStr CERTCertificate;
-typedef struct CERTCertificateListStr CERTCertificateList;
-typedef struct CERTCertificateRequestStr CERTCertificateRequest;
-typedef struct CERTCrlStr CERTCrl;
-typedef struct CERTCrlDistributionPointsStr CERTCrlDistributionPoints;
-typedef struct CERTCrlEntryStr CERTCrlEntry;
-typedef struct CERTCrlHeadNodeStr CERTCrlHeadNode;
-typedef struct CERTCrlKeyStr CERTCrlKey;
-typedef struct CERTCrlNodeStr CERTCrlNode;
-typedef struct CERTDERCertsStr CERTDERCerts;
-typedef struct CERTDistNamesStr CERTDistNames;
-typedef struct CERTGeneralNameStr CERTGeneralName;
-typedef struct CERTGeneralNameListStr CERTGeneralNameList;
-typedef struct CERTIssuerAndSNStr CERTIssuerAndSN;
-typedef struct CERTNameStr CERTName;
-typedef struct CERTNameConstraintStr CERTNameConstraint;
-typedef struct CERTNameConstraintsStr CERTNameConstraints;
-typedef struct CERTOKDomainNameStr CERTOKDomainName;
-typedef struct CERTPrivKeyUsagePeriodStr CERTPrivKeyUsagePeriod;
-typedef struct CERTPublicKeyAndChallengeStr CERTPublicKeyAndChallenge;
-typedef struct CERTRDNStr CERTRDN;
-typedef struct CERTSignedCrlStr CERTSignedCrl;
-typedef struct CERTSignedDataStr CERTSignedData;
-typedef struct CERTStatusConfigStr CERTStatusConfig;
-typedef struct CERTSubjectListStr CERTSubjectList;
-typedef struct CERTSubjectNodeStr CERTSubjectNode;
-typedef struct CERTSubjectPublicKeyInfoStr CERTSubjectPublicKeyInfo;
-typedef struct CERTValidityStr CERTValidity;
-typedef struct CERTVerifyLogStr CERTVerifyLog;
-typedef struct CERTVerifyLogNodeStr CERTVerifyLogNode;
-typedef struct CRLDistributionPointStr CRLDistributionPoint;
-
-/* CRL extensions type */
-typedef unsigned long CERTCrlNumber;
-
-/*
-** An X.500 AVA object
-*/
-struct CERTAVAStr {
- SECItem type;
- SECItem value;
-};
-
-/*
-** An X.500 RDN object
-*/
-struct CERTRDNStr {
- CERTAVA **avas;
-};
-
-/*
-** An X.500 name object
-*/
-struct CERTNameStr {
- PLArenaPool *arena;
- CERTRDN **rdns;
-};
-
-/*
-** An X.509 validity object
-*/
-struct CERTValidityStr {
- PLArenaPool *arena;
- SECItem notBefore;
- SECItem notAfter;
-};
-
-/*
- * A serial number and issuer name, which is used as a database key
- */
-struct CERTCertKeyStr {
- SECItem serialNumber;
- SECItem derIssuer;
-};
-
-/*
-** A signed data object. Used to implement the "signed" macro used
-** in the X.500 specs.
-*/
-struct CERTSignedDataStr {
- SECItem data;
- SECAlgorithmID signatureAlgorithm;
- SECItem signature;
-};
-
-/*
-** An X.509 subject-public-key-info object
-*/
-struct CERTSubjectPublicKeyInfoStr {
- PLArenaPool *arena;
- SECAlgorithmID algorithm;
- SECItem subjectPublicKey;
-};
-
-struct CERTPublicKeyAndChallengeStr {
- SECItem spki;
- SECItem challenge;
-};
-
-struct CERTCertTrustStr {
- unsigned int sslFlags;
- unsigned int emailFlags;
- unsigned int objectSigningFlags;
-};
-
-/*
- * defined the types of trust that exist
- */
-typedef enum SECTrustTypeEnum {
- trustSSL = 0,
- trustEmail = 1,
- trustObjectSigning = 2,
- trustTypeNone = 3
-} SECTrustType;
-
-#define SEC_GET_TRUST_FLAGS(trust,type) \
- (((type)==trustSSL)?((trust)->sslFlags): \
- (((type)==trustEmail)?((trust)->emailFlags): \
- (((type)==trustObjectSigning)?((trust)->objectSigningFlags):0)))
-
-/*
-** An X.509.3 certificate extension
-*/
-struct CERTCertExtensionStr {
- SECItem id;
- SECItem critical;
- SECItem value;
-};
-
-struct CERTSubjectNodeStr {
- struct CERTSubjectNodeStr *next;
- struct CERTSubjectNodeStr *prev;
- SECItem certKey;
- SECItem keyID;
-};
-
-struct CERTSubjectListStr {
- PLArenaPool *arena;
- int ncerts;
- char *emailAddr;
- CERTSubjectNode *head;
- CERTSubjectNode *tail; /* do we need tail? */
- void *entry;
-};
-
-/*
-** An X.509 certificate object (the unsigned form)
-*/
-struct CERTCertificateStr {
- /* the arena is used to allocate any data structures that have the same
- * lifetime as the cert. This is all stuff that hangs off of the cert
- * structure, and is all freed at the same time. I is used when the
- * cert is decoded, destroyed, and at some times when it changes
- * state
- */
- PLArenaPool *arena;
-
- /* The following fields are static after the cert has been decoded */
- char *subjectName;
- char *issuerName;
- CERTSignedData signatureWrap; /* XXX */
- SECItem derCert; /* original DER for the cert */
- SECItem derIssuer; /* DER for issuer name */
- SECItem derSubject; /* DER for subject name */
- SECItem derPublicKey; /* DER for the public key */
- SECItem certKey; /* database key for this cert */
- SECItem version;
- SECItem serialNumber;
- SECAlgorithmID signature;
- CERTName issuer;
- CERTValidity validity;
- CERTName subject;
- CERTSubjectPublicKeyInfo subjectPublicKeyInfo;
- SECItem issuerID;
- SECItem subjectID;
- CERTCertExtension **extensions;
- char *emailAddr;
- CERTCertDBHandle *dbhandle;
- SECItem subjectKeyID; /* x509v3 subject key identifier */
- PRBool keyIDGenerated; /* was the keyid generated? */
- unsigned int keyUsage; /* what uses are allowed for this cert */
- unsigned int rawKeyUsage; /* value of the key usage extension */
- PRBool keyUsagePresent; /* was the key usage extension present */
- PRUint32 nsCertType; /* value of the ns cert type extension */
- /* must be 32-bit for PR_ATOMIC_SET */
-
- /* these values can be set by the application to bypass certain checks
- * or to keep the cert in memory for an entire session.
- * XXX - need an api to set these
- */
- PRBool keepSession; /* keep this cert for entire session*/
- PRBool timeOK; /* is the bad validity time ok? */
- CERTOKDomainName *domainOK; /* these domain names are ok */
-
- /*
- * these values can change when the cert changes state. These state
- * changes include transitions from temp to perm or vice-versa, and
- * changes of trust flags
- */
- PRBool isperm;
- PRBool istemp;
- char *nickname;
- char *dbnickname;
- struct NSSCertificateStr *nssCertificate; /* This is Stan stuff. */
- CERTCertTrust *trust;
-
- /* the reference count is modified whenever someone looks up, dups
- * or destroys a certificate
- */
- int referenceCount;
-
- /* The subject list is a list of all certs with the same subject name.
- * It can be modified any time a cert is added or deleted from either
- * the in-memory(temporary) or on-disk(permanent) database.
- */
- CERTSubjectList *subjectList;
-
- /* these belong in the static section, but are here to maintain
- * the structure's integrity
- */
- CERTAuthKeyID * authKeyID; /* x509v3 authority key identifier */
- PRBool isRoot; /* cert is the end of a chain */
-
- /* these fields are used by client GUI code to keep track of ssl sockets
- * that are blocked waiting on GUI feedback related to this cert.
- * XXX - these should be moved into some sort of application specific
- * data structure. They are only used by the browser right now.
- */
- union {
- void* apointer; /* was struct SECSocketNode* authsocketlist */
- struct {
- unsigned int hasUnsupportedCriticalExt :1;
- /* add any new option bits needed here */
- } bits;
- } options;
- int series; /* was int authsocketcount; record the series of the pkcs11ID */
-
- /* This is PKCS #11 stuff. */
- PK11SlotInfo *slot; /*if this cert came of a token, which is it*/
- CK_OBJECT_HANDLE pkcs11ID; /*and which object on that token is it */
- PRBool ownSlot; /*true if the cert owns the slot reference */
-};
-#define SEC_CERTIFICATE_VERSION_1 0 /* default created */
-#define SEC_CERTIFICATE_VERSION_2 1 /* v2 */
-#define SEC_CERTIFICATE_VERSION_3 2 /* v3 extensions */
-
-#define SEC_CRL_VERSION_1 0 /* default */
-#define SEC_CRL_VERSION_2 1 /* v2 extensions */
-
-/*
- * used to identify class of cert in mime stream code
- */
-#define SEC_CERT_CLASS_CA 1
-#define SEC_CERT_CLASS_SERVER 2
-#define SEC_CERT_CLASS_USER 3
-#define SEC_CERT_CLASS_EMAIL 4
-
-struct CERTDERCertsStr {
- PLArenaPool *arena;
- int numcerts;
- SECItem *rawCerts;
-};
-
-/*
-** A PKCS ? Attribute
-** XXX this is duplicated through out the code, it *should* be moved
-** to a central location. Where would be appropriate?
-*/
-struct CERTAttributeStr {
- SECItem attrType;
- SECItem **attrValue;
-};
-
-/*
-** A PKCS#10 certificate-request object (the unsigned form)
-*/
-struct CERTCertificateRequestStr {
- PLArenaPool *arena;
- SECItem version;
- CERTName subject;
- CERTSubjectPublicKeyInfo subjectPublicKeyInfo;
- CERTAttribute **attributes;
-};
-#define SEC_CERTIFICATE_REQUEST_VERSION 0 /* what we *create* */
-
-
-/*
-** A certificate list object.
-*/
-struct CERTCertificateListStr {
- SECItem *certs;
- int len; /* number of certs */
- PLArenaPool *arena;
-};
-
-struct CERTCertListNodeStr {
- PRCList links;
- CERTCertificate *cert;
- void *appData;
-};
-
-struct CERTCertListStr {
- PRCList list;
- PLArenaPool *arena;
-};
-
-#define CERT_LIST_HEAD(l) ((CERTCertListNode *)PR_LIST_HEAD(&l->list))
-#define CERT_LIST_NEXT(n) ((CERTCertListNode *)n->links.next)
-#define CERT_LIST_END(n,l) (((void *)n) == ((void *)&l->list))
-#define CERT_LIST_EMPTY(l) CERT_LIST_END(CERT_LIST_HEAD(l), l)
-
-struct CERTCrlEntryStr {
- SECItem serialNumber;
- SECItem revocationDate;
- CERTCertExtension **extensions;
-};
-
-struct CERTCrlStr {
- PLArenaPool *arena;
- SECItem version;
- SECAlgorithmID signatureAlg;
- SECItem derName;
- CERTName name;
- SECItem lastUpdate;
- SECItem nextUpdate; /* optional for x.509 CRL */
- CERTCrlEntry **entries;
- CERTCertExtension **extensions;
- /* can't add anything there for binary backwards compatibility reasons */
-};
-
-struct CERTCrlKeyStr {
- SECItem derName;
- SECItem dummy; /* The decoder can not skip a primitive,
- this serves as a place holder for the
- decoder to finish its task only
- */
-};
-
-struct CERTSignedCrlStr {
- PLArenaPool *arena;
- CERTCrl crl;
- void *reserved1;
- PRBool reserved2;
- PRBool isperm;
- PRBool istemp;
- int referenceCount;
- CERTCertDBHandle *dbhandle;
- CERTSignedData signatureWrap; /* XXX */
- char *url;
- SECItem *derCrl;
- PK11SlotInfo *slot;
- CK_OBJECT_HANDLE pkcs11ID;
- void* opaque; /* do not touch */
-};
-
-
-struct CERTCrlHeadNodeStr {
- PLArenaPool *arena;
- CERTCertDBHandle *dbhandle;
- CERTCrlNode *first;
- CERTCrlNode *last;
-};
-
-
-struct CERTCrlNodeStr {
- CERTCrlNode *next;
- int type;
- CERTSignedCrl *crl;
-};
-
-
-/*
- * Array of X.500 Distinguished Names
- */
-struct CERTDistNamesStr {
- PLArenaPool *arena;
- int nnames;
- SECItem *names;
- void *head; /* private */
-};
-
-
-#define NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */
-#define NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */
-#define NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */
-#define NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */
-#define NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */
-#define NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */
-#define NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */
-#define NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */
-
-#define EXT_KEY_USAGE_TIME_STAMP (0x8000)
-#define EXT_KEY_USAGE_STATUS_RESPONDER (0x4000)
-
-#define NS_CERT_TYPE_APP ( NS_CERT_TYPE_SSL_CLIENT | \
- NS_CERT_TYPE_SSL_SERVER | \
- NS_CERT_TYPE_EMAIL | \
- NS_CERT_TYPE_OBJECT_SIGNING )
-
-#define NS_CERT_TYPE_CA ( NS_CERT_TYPE_SSL_CA | \
- NS_CERT_TYPE_EMAIL_CA | \
- NS_CERT_TYPE_OBJECT_SIGNING_CA | \
- EXT_KEY_USAGE_STATUS_RESPONDER )
-typedef enum SECCertUsageEnum {
- certUsageSSLClient = 0,
- certUsageSSLServer = 1,
- certUsageSSLServerWithStepUp = 2,
- certUsageSSLCA = 3,
- certUsageEmailSigner = 4,
- certUsageEmailRecipient = 5,
- certUsageObjectSigner = 6,
- certUsageUserCertImport = 7,
- certUsageVerifyCA = 8,
- certUsageProtectedObjectSigner = 9,
- certUsageStatusResponder = 10,
- certUsageAnyCA = 11
-} SECCertUsage;
-
-typedef PRInt64 SECCertificateUsage;
-
-#define certificateUsageCheckAllUsages (0x0000)
-#define certificateUsageSSLClient (0x0001)
-#define certificateUsageSSLServer (0x0002)
-#define certificateUsageSSLServerWithStepUp (0x0004)
-#define certificateUsageSSLCA (0x0008)
-#define certificateUsageEmailSigner (0x0010)
-#define certificateUsageEmailRecipient (0x0020)
-#define certificateUsageObjectSigner (0x0040)
-#define certificateUsageUserCertImport (0x0080)
-#define certificateUsageVerifyCA (0x0100)
-#define certificateUsageProtectedObjectSigner (0x0200)
-#define certificateUsageStatusResponder (0x0400)
-#define certificateUsageAnyCA (0x0800)
-
-#define certificateUsageHighest certificateUsageAnyCA
-
-/*
- * Does the cert belong to the user, a peer, or a CA.
- */
-typedef enum CERTCertOwnerEnum {
- certOwnerUser = 0,
- certOwnerPeer = 1,
- certOwnerCA = 2
-} CERTCertOwner;
-
-/*
- * This enum represents the state of validity times of a certificate
- */
-typedef enum SECCertTimeValidityEnum {
- secCertTimeValid = 0,
- secCertTimeExpired = 1,
- secCertTimeNotValidYet = 2,
- secCertTimeUndetermined = 3 /* validity could not be decoded from the
- cert, most likely because it was NULL */
-} SECCertTimeValidity;
-
-/*
- * This is used as return status in functions that compare the validity
- * periods of two certificates A and B, currently only
- * CERT_CompareValidityTimes.
- */
-
-typedef enum CERTCompareValidityStatusEnum
-{
- certValidityUndetermined = 0, /* the function is unable to select one cert
- over another */
- certValidityChooseB = 1, /* cert B should be preferred */
- certValidityEqual = 2, /* both certs have the same validity period */
- certValidityChooseA = 3 /* cert A should be preferred */
-} CERTCompareValidityStatus;
-
-/*
- * Interface for getting certificate nickname strings out of the database
- */
-
-/* these are values for the what argument below */
-#define SEC_CERT_NICKNAMES_ALL 1
-#define SEC_CERT_NICKNAMES_USER 2
-#define SEC_CERT_NICKNAMES_SERVER 3
-#define SEC_CERT_NICKNAMES_CA 4
-
-struct CERTCertNicknamesStr {
- PLArenaPool *arena;
- void *head;
- int numnicknames;
- char **nicknames;
- int what;
- int totallen;
-};
-
-struct CERTIssuerAndSNStr {
- SECItem derIssuer;
- CERTName issuer;
- SECItem serialNumber;
-};
-
-
-/* X.509 v3 Key Usage Extension flags */
-#define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */
-#define KU_NON_REPUDIATION (0x40) /* bit 1 */
-#define KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */
-#define KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */
-#define KU_KEY_AGREEMENT (0x08) /* bit 4 */
-#define KU_KEY_CERT_SIGN (0x04) /* bit 5 */
-#define KU_CRL_SIGN (0x02) /* bit 6 */
-#define KU_ENCIPHER_ONLY (0x01) /* bit 7 */
-#define KU_ALL (KU_DIGITAL_SIGNATURE | \
- KU_NON_REPUDIATION | \
- KU_KEY_ENCIPHERMENT | \
- KU_DATA_ENCIPHERMENT | \
- KU_KEY_AGREEMENT | \
- KU_KEY_CERT_SIGN | \
- KU_CRL_SIGN | \
- KU_ENCIPHER_ONLY)
-
-/* This value will not occur in certs. It is used internally for the case
- * when either digital signature or non-repudiation is the correct value.
- */
-#define KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION (0x2000)
-
-/* This value will not occur in certs. It is used internally for the case
- * when the key type is not know ahead of time and either key agreement or
- * key encipherment are the correct value based on key type
- */
-#define KU_KEY_AGREEMENT_OR_ENCIPHERMENT (0x4000)
-
-/* internal bits that do not match bits in the x509v3 spec, but are used
- * for similar purposes
- */
-#define KU_NS_GOVT_APPROVED (0x8000) /*don't make part of KU_ALL!*/
-/*
- * x.509 v3 Basic Constraints Extension
- * If isCA is false, the pathLenConstraint is ignored.
- * Otherwise, the following pathLenConstraint values will apply:
- * < 0 - there is no limit to the certificate path
- * 0 - CA can issues end-entity certificates only
- * > 0 - the number of certificates in the certificate path is
- * limited to this number
- */
-#define CERT_UNLIMITED_PATH_CONSTRAINT -2
-
-struct CERTBasicConstraintsStr {
- PRBool isCA; /* on if is CA */
- int pathLenConstraint; /* maximum number of certificates that can be
- in the cert path. Only applies to a CA
- certificate; otherwise, it's ignored.
- */
-};
-
-/* Maximum length of a certificate chain */
-#define CERT_MAX_CERT_CHAIN 20
-
-#define CERT_MAX_SERIAL_NUMBER_BYTES 20 /* from RFC 3280 */
-#define CERT_MAX_DN_BYTES 4096 /* arbitrary */
-
-/* x.509 v3 Reason Flags, used in CRLDistributionPoint Extension */
-#define RF_UNUSED (0x80) /* bit 0 */
-#define RF_KEY_COMPROMISE (0x40) /* bit 1 */
-#define RF_CA_COMPROMISE (0x20) /* bit 2 */
-#define RF_AFFILIATION_CHANGED (0x10) /* bit 3 */
-#define RF_SUPERSEDED (0x08) /* bit 4 */
-#define RF_CESSATION_OF_OPERATION (0x04) /* bit 5 */
-#define RF_CERTIFICATE_HOLD (0x02) /* bit 6 */
-
-/* enum for CRL Entry Reason Code */
-typedef enum CERTCRLEntryReasonCodeEnum {
- crlEntryReasonUnspecified = 0,
- crlEntryReasonKeyCompromise = 1,
- crlEntryReasonCaCompromise = 2,
- crlEntryReasonAffiliationChanged = 3,
- crlEntryReasonSuperseded = 4,
- crlEntryReasonCessationOfOperation = 5,
- crlEntryReasoncertificatedHold = 6,
- crlEntryReasonRemoveFromCRL = 8,
- crlEntryReasonPrivilegeWithdrawn = 9,
- crlEntryReasonAaCompromise = 10
-} CERTCRLEntryReasonCode;
-
-/* If we needed to extract the general name field, use this */
-/* General Name types */
-typedef enum CERTGeneralNameTypeEnum {
- certOtherName = 1,
- certRFC822Name = 2,
- certDNSName = 3,
- certX400Address = 4,
- certDirectoryName = 5,
- certEDIPartyName = 6,
- certURI = 7,
- certIPAddress = 8,
- certRegisterID = 9
-} CERTGeneralNameType;
-
-
-typedef struct OtherNameStr {
- SECItem name;
- SECItem oid;
-}OtherName;
-
-
-
-struct CERTGeneralNameStr {
- CERTGeneralNameType type; /* name type */
- union {
- CERTName directoryName; /* distinguish name */
- OtherName OthName; /* Other Name */
- SECItem other; /* the rest of the name forms */
- }name;
- SECItem derDirectoryName; /* this is saved to simplify directory name
- comparison */
- PRCList l;
-};
-
-struct CERTGeneralNameListStr {
- PLArenaPool *arena;
- CERTGeneralName *name;
- int refCount;
- int len;
- PZLock *lock;
-};
-
-struct CERTNameConstraintStr {
- CERTGeneralName name;
- SECItem DERName;
- SECItem min;
- SECItem max;
- PRCList l;
-};
-
-
-struct CERTNameConstraintsStr {
- CERTNameConstraint *permited;
- CERTNameConstraint *excluded;
- SECItem **DERPermited;
- SECItem **DERExcluded;
-};
-
-
-/* Private Key Usage Period extension struct. */
-struct CERTPrivKeyUsagePeriodStr {
- SECItem notBefore;
- SECItem notAfter;
- PLArenaPool *arena;
-};
-
-/* X.509 v3 Authority Key Identifier extension. For the authority certificate
- issuer field, we only support URI now.
- */
-struct CERTAuthKeyIDStr {
- SECItem keyID; /* unique key identifier */
- CERTGeneralName *authCertIssuer; /* CA's issuer name. End with a NULL */
- SECItem authCertSerialNumber; /* CA's certificate serial number */
- SECItem **DERAuthCertIssuer; /* This holds the DER encoded format of
- the authCertIssuer field. It is used
- by the encoding engine. It should be
- used as a read only field by the caller.
- */
-};
-
-/* x.509 v3 CRL Distributeion Point */
-
-/*
- * defined the types of CRL Distribution points
- */
-typedef enum DistributionPointTypesEnum {
- generalName = 1, /* only support this for now */
- relativeDistinguishedName = 2
-} DistributionPointTypes;
-
-struct CRLDistributionPointStr {
- DistributionPointTypes distPointType;
- union {
- CERTGeneralName *fullName;
- CERTRDN relativeName;
- } distPoint;
- SECItem reasons;
- CERTGeneralName *crlIssuer;
-
- /* Reserved for internal use only*/
- SECItem derDistPoint;
- SECItem derRelativeName;
- SECItem **derCrlIssuer;
- SECItem **derFullName;
- SECItem bitsmap;
-};
-
-struct CERTCrlDistributionPointsStr {
- CRLDistributionPoint **distPoints;
-};
-
-/*
- * This structure is used to keep a log of errors when verifying
- * a cert chain. This allows multiple errors to be reported all at
- * once.
- */
-struct CERTVerifyLogNodeStr {
- CERTCertificate *cert; /* what cert had the error */
- long error; /* what error was it? */
- unsigned int depth; /* how far up the chain are we */
- void *arg; /* error specific argument */
- struct CERTVerifyLogNodeStr *next; /* next in the list */
- struct CERTVerifyLogNodeStr *prev; /* next in the list */
-};
-
-
-struct CERTVerifyLogStr {
- PLArenaPool *arena;
- unsigned int count;
- struct CERTVerifyLogNodeStr *head;
- struct CERTVerifyLogNodeStr *tail;
-};
-
-
-struct CERTOKDomainNameStr {
- CERTOKDomainName *next;
- char name[1]; /* actual length may be longer. */
-};
-
-
-typedef SECStatus (PR_CALLBACK *CERTStatusChecker) (CERTCertDBHandle *handle,
- CERTCertificate *cert,
- PRTime time,
- void *pwArg);
-
-typedef SECStatus (PR_CALLBACK *CERTStatusDestroy) (CERTStatusConfig *handle);
-
-struct CERTStatusConfigStr {
- CERTStatusChecker statusChecker; /* NULL means no checking enabled */
- CERTStatusDestroy statusDestroy; /* enabled or no, will clean up */
- void *statusContext; /* cx specific to checking protocol */
-};
-
-struct CERTAuthInfoAccessStr {
- SECItem method;
- SECItem derLocation;
- CERTGeneralName *location; /* decoded location */
-};
-
-
-/* This is the typedef for the callback passed to CERT_OpenCertDB() */
-/* callback to return database name based on version number */
-typedef char * (*CERTDBNameFunc)(void *arg, int dbVersion);
-
-/*
- * types of cert packages that we can decode
- */
-typedef enum CERTPackageTypeEnum {
- certPackageNone = 0,
- certPackageCert = 1,
- certPackagePKCS7 = 2,
- certPackageNSCertSeq = 3,
- certPackageNSCertWrap = 4
-} CERTPackageType;
-
-/*
- * these types are for the PKIX Certificate Policies extension
- */
-typedef struct {
- SECOidTag oid;
- SECItem qualifierID;
- SECItem qualifierValue;
-} CERTPolicyQualifier;
-
-typedef struct {
- SECOidTag oid;
- SECItem policyID;
- CERTPolicyQualifier **policyQualifiers;
-} CERTPolicyInfo;
-
-typedef struct {
- PLArenaPool *arena;
- CERTPolicyInfo **policyInfos;
-} CERTCertificatePolicies;
-
-typedef struct {
- SECItem organization;
- SECItem **noticeNumbers;
-} CERTNoticeReference;
-
-typedef struct {
- PLArenaPool *arena;
- CERTNoticeReference noticeReference;
- SECItem derNoticeReference;
- SECItem displayText;
-} CERTUserNotice;
-
-typedef struct {
- PLArenaPool *arena;
- SECItem **oids;
-} CERTOidSequence;
-
-/*
- * these types are for the PKIX Policy Mappings extension
- */
-typedef struct {
- SECItem issuerDomainPolicy;
- SECItem subjectDomainPolicy;
-} CERTPolicyMap;
-
-typedef struct {
- PLArenaPool *arena;
- CERTPolicyMap **policyMaps;
-} CERTCertificatePolicyMappings;
-
-/*
- * these types are for the PKIX inhibitAnyPolicy extension
- */
-typedef struct {
- SECItem inhibitAnySkipCerts;
-} CERTCertificateInhibitAny;
-
-/*
- * these types are for the PKIX Policy Constraints extension
- */
-typedef struct {
- SECItem explicitPolicySkipCerts;
- SECItem inhibitMappingSkipCerts;
-} CERTCertificatePolicyConstraints;
-
-/*
- * These types are for the validate chain callback param.
- *
- * CERTChainVerifyCallback is an application-supplied callback that can be used
- * to augment libpkix's certificate chain validation with additional
- * application-specific checks. It may be called multiple times if there are
- * multiple potentially-valid paths for the certificate being validated. This
- * callback is called before revocation checking is done on the certificates in
- * the given chain.
- *
- * - isValidChainArg contains the application-provided opaque argument
- * - currentChain is the currently validated chain. It is ordered with the leaf
- * certificate at the head and the trust anchor at the tail.
- *
- * The callback should set *chainOK = PR_TRUE and return SECSuccess if the
- * certificate chain is acceptable. It should set *chainOK = PR_FALSE and
- * return SECSuccess if the chain is unacceptable, to indicate that the given
- * chain is bad and path building should continue. It should return SECFailure
- * to indicate an fatal error that will cause path validation to fail
- * immediately.
- */
-typedef SECStatus (*CERTChainVerifyCallbackFunc)
- (void *isChainValidArg,
- const CERTCertList *currentChain,
- PRBool *chainOK);
-
-/*
- * Note: If extending this structure, it will be necessary to change the
- * associated CERTValParamInType
- */
-typedef struct {
- CERTChainVerifyCallbackFunc isChainValid;
- void *isChainValidArg;
-} CERTChainVerifyCallback;
-
-/*
- * these types are for the CERT_PKIX* Verification functions
- * These are all optional parameters.
- */
-
-typedef enum {
- cert_pi_end = 0, /* SPECIAL: signifies end of array of
- * CERTValParam* */
- cert_pi_nbioContext = 1, /* specify a non-blocking IO context used to
- * resume a session. If this argument is
- * specified, no other arguments should be.
- * Specified in value.pointer.p. If the
- * operation completes the context will be
- * freed. */
- cert_pi_nbioAbort = 2, /* specify a non-blocking IO context for an
- * existing operation which the caller wants
- * to abort. If this argument is
- * specified, no other arguments should be.
- * Specified in value.pointer.p. If the
- * operation succeeds the context will be
- * freed. */
- cert_pi_certList = 3, /* specify the chain to validate against. If
- * this value is given, then the path
- * construction step in the validation is
- * skipped. Specified in value.pointer.chain */
- cert_pi_policyOID = 4, /* validate certificate for policy OID.
- * Specified in value.array.oids. Cert must
- * be good for at least one OID in order
- * to validate. Default is that the user is not
- * concerned about certificate policy. */
- cert_pi_policyFlags = 5, /* flags for each policy specified in policyOID.
- * Specified in value.scalar.ul. Policy flags
- * apply to all specified oids.
- * Use CERT_POLICY_FLAG_* macros below. If not
- * specified policy flags default to 0 */
- cert_pi_keyusage = 6, /* specify what the keyusages the certificate
- * will be evaluated against, specified in
- * value.scalar.ui. The cert must validate for
- * at least one of the specified key usages.
- * Values match the KU_ bit flags defined
- * in this file. Default is derived from
- * the 'usages' function argument */
- cert_pi_extendedKeyusage= 7, /* specify what the required extended key
- * usage of the certificate. Specified as
- * an array of oidTags in value.array.oids.
- * The cert must validate for at least one
- * of the specified extended key usages.
- * If not specified, no extended key usages
- * will be checked. */
- cert_pi_date = 8, /* validate certificate is valid as of date
- * specified in value.scalar.time. A special
- * value '0' indicates 'now'. default is '0' */
- cert_pi_revocationFlags = 9, /* Specify what revocation checking to do.
- * See CERT_REV_FLAG_* macros below
- * Set in value.pointer.revocation */
- cert_pi_certStores = 10,/* Bitmask of Cert Store flags (see below)
- * Set in value.scalar.ui */
- cert_pi_trustAnchors = 11,/* Specify the list of trusted roots to
- * validate against.
- * The default set of trusted roots, these are
- * root CA certs from libnssckbi.so or CA
- * certs trusted by user, are used in any of
- * the following cases:
- * * when the parameter is not set.
- * * when the list of trust anchors is empty.
- * Note that this handling can be further altered by altering the
- * cert_pi_useOnlyTrustAnchors flag
- * Specified in value.pointer.chain */
- cert_pi_useAIACertFetch = 12, /* Enables cert fetching using AIA extension.
- * In NSS 3.12.1 or later. Default is off.
- * Value is in value.scalar.b */
- cert_pi_chainVerifyCallback = 13,
- /* The callback container for doing extra
- * validation on the currently calculated chain.
- * Value is in value.pointer.chainVerifyCallback */
- cert_pi_useOnlyTrustAnchors = 14,/* If true, disables trusting any
- * certificates other than the ones passed in via cert_pi_trustAnchors.
- * If false, then the certificates specified via cert_pi_trustAnchors
- * will be combined with the pre-existing trusted roots, but only for
- * the certificate validation being performed.
- * If no value has been supplied via cert_pi_trustAnchors, this has no
- * effect.
- * The default value is true, meaning if this is not supplied, only
- * trust anchors supplied via cert_pi_trustAnchors are trusted.
- * Specified in value.scalar.b */
- cert_pi_max /* SPECIAL: signifies maximum allowed value,
- * can increase in future releases */
-} CERTValParamInType;
-
-/*
- * for all out parameters:
- * out parameters are only returned if the caller asks for them in
- * the CERTValOutParam array. Caller is responsible for the CERTValOutParam
- * array itself. The pkix verify function will allocate and other arrays
- * pointers, or objects. The Caller is responsible for freeing those results.
- * If SECWouldBlock is returned, only cert_pi_nbioContext is returned.
- */
-typedef enum {
- cert_po_end = 0, /* SPECIAL: signifies end of array of
- * CERTValParam* */
- cert_po_nbioContext = 1, /* Return a nonblocking context. If no
- * non-blocking context is specified, then
- * blocking IO will be used.
- * Returned in value.pointer.p. The context is
- * freed after an abort or a complete operation.
- * This value is only returned on SECWouldBlock.
- */
- cert_po_trustAnchor = 2, /* Return the trust anchor for the chain that
- * was validated. Returned in
- * value.pointer.cert, this value is only
- * returned on SECSuccess. */
- cert_po_certList = 3, /* Return the entire chain that was validated.
- * Returned in value.pointer.certList. If no
- * chain could be constructed, this value
- * would be NULL. */
- cert_po_policyOID = 4, /* Return the policies that were found to be
- * valid. Returned in value.array.oids as an
- * array. This is only returned on
- * SECSuccess. */
- cert_po_errorLog = 5, /* Return a log of problems with the chain.
- * Returned in value.pointer.log */
- cert_po_usages = 6, /* Return what usages the certificate is valid
- for. Returned in value.scalar.usages */
- cert_po_keyUsage = 7, /* Return what key usages the certificate
- * is valid for.
- * Returned in value.scalar.usage */
- cert_po_extendedKeyusage= 8, /* Return what extended key usages the
- * certificate is valid for.
- * Returned in value.array.oids */
- cert_po_max /* SPECIAL: signifies maximum allowed value,
- * can increase in future releases */
-
-} CERTValParamOutType;
-
-typedef enum {
- cert_revocation_method_crl = 0,
- cert_revocation_method_ocsp,
- cert_revocation_method_count
-} CERTRevocationMethodIndex;
-
-
-/*
- * The following flags are supposed to be used to control bits in
- * each integer contained in the array pointed to be:
- * CERTRevocationTests.cert_rev_flags_per_method
- * All Flags are prefixed by CERT_REV_M_, where _M_ indicates
- * this is a method dependent flag.
- */
-
-/*
- * Whether or not to use a method for revocation testing.
- * If set to "do not test", then all other flags are ignored.
- */
-#define CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD 0L
-#define CERT_REV_M_TEST_USING_THIS_METHOD 1L
-
-/*
- * Whether or not NSS is allowed to attempt to fetch fresh information
- * from the network.
- * (Although fetching will never happen if fresh information for the
- * method is already locally available.)
- */
-#define CERT_REV_M_ALLOW_NETWORK_FETCHING 0L
-#define CERT_REV_M_FORBID_NETWORK_FETCHING 2L
-
-/*
- * Example for an implicit default source:
- * The globally configured default OCSP responder.
- * IGNORE means:
- * ignore the implicit default source, whether it's configured or not.
- * ALLOW means:
- * if an implicit default source is configured,
- * then it overrides any available or missing source in the cert.
- * if no implicit default source is configured,
- * then we continue to use what's available (or not available)
- * in the certs.
- */
-#define CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE 0L
-#define CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE 4L
-
-/*
- * Defines the behavior if no fresh information is available,
- * fetching from the network is allowed, but the source of revocation
- * information is unknown (even after considering implicit sources,
- * if allowed by other flags).
- * SKIPT_TEST means:
- * We ignore that no fresh information is available and
- * skip this test.
- * REQUIRE_INFO means:
- * We still require that fresh information is available.
- * Other flags define what happens on missing fresh info.
- */
-#define CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE 0L
-#define CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE 8L
-
-/*
- * Defines the behavior if we are unable to obtain fresh information.
- * INGORE means:
- * Return "cert status unknown"
- * FAIL means:
- * Return "cert revoked".
- */
-#define CERT_REV_M_IGNORE_MISSING_FRESH_INFO 0L
-#define CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO 16L
-
-/*
- * What should happen if we were able to find fresh information using
- * this method, and the data indicated the cert is good?
- * STOP_TESTING means:
- * Our success is sufficient, do not continue testing
- * other methods.
- * CONTINUE_TESTING means:
- * We will continue and test the next allowed
- * specified method.
- */
-#define CERT_REV_M_STOP_TESTING_ON_FRESH_INFO 0L
-#define CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO 32L
-
-/*
- * The following flags are supposed to be used to control bits in
- * CERTRevocationTests.cert_rev_method_independent_flags
- * All Flags are prefixed by CERT_REV_M_, where _M_ indicates
- * this is a method independent flag.
- */
-
-/*
- * This defines the order to checking.
- * EACH_METHOD_SEPARATELY means:
- * Do all tests related to a particular allowed method
- * (both local information and network fetching) in a single step.
- * Only after testing for a particular method is done,
- * then switching to the next method will happen.
- * ALL_LOCAL_INFORMATION_FIRST means:
- * Start by testing the information for all allowed methods
- * which are already locally available. Only after that is done
- * consider to fetch from the network (as allowed by other flags).
- */
-#define CERT_REV_MI_TEST_EACH_METHOD_SEPARATELY 0L
-#define CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST 1L
-
-/*
- * Use this flag to specify that it's necessary that fresh information
- * is available for at least one of the allowed methods, but it's
- * irrelevant which of the mechanisms succeeded.
- * NO_OVERALL_INFO_REQUIREMENT means:
- * We strictly follow the requirements for each individual method.
- * REQUIRE_SOME_FRESH_INFO_AVAILABLE means:
- * After the individual tests have been executed, we must have
- * been able to find fresh information using at least one method.
- * If we were unable to find fresh info, it's a failure.
- * This setting overrides the CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO
- * flag on all methods.
- */
-#define CERT_REV_MI_NO_OVERALL_INFO_REQUIREMENT 0L
-#define CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE 2L
-
-
-typedef struct {
- /*
- * The size of the array that cert_rev_flags_per_method points to,
- * meaning, the number of methods that are known and defined
- * by the caller.
- */
- PRUint32 number_of_defined_methods;
-
- /*
- * A pointer to an array of integers.
- * Each integer defines revocation checking for a single method,
- * by having individual CERT_REV_M_* bits set or not set.
- * The meaning of index numbers into this array are defined by
- * enum CERTRevocationMethodIndex
- * The size of the array must be specified by the caller in the separate
- * variable number_of_defined_methods.
- * The size of the array may be smaller than
- * cert_revocation_method_count, it can happen if a caller
- * is not yet aware of the latest revocation methods
- * (or does not want to use them).
- */
- PRUint64 *cert_rev_flags_per_method;
-
- /*
- * How many preferred methods are specified?
- * This is equivalent to the size of the array that
- * preferred_revocation_methods points to.
- * It's allowed to set this value to zero,
- * then NSS will decide which methods to prefer.
- */
- PRUint32 number_of_preferred_methods;
-
- /* Array that may specify an optional order of preferred methods.
- * Each array entry shall contain a method identifier as defined
- * by CERTRevocationMethodIndex.
- * The entry at index [0] specifies the method with highest preferrence.
- * These methods will be tested first for locally available information.
- * Methods allowed for downloading will be attempted in the same order.
- */
- CERTRevocationMethodIndex *preferred_methods;
-
- /*
- * An integer which defines certain aspects of revocation checking
- * (independent of individual methods) by having individual
- * CERT_REV_MI_* bits set or not set.
- */
- PRUint64 cert_rev_method_independent_flags;
-} CERTRevocationTests;
-
-typedef struct {
- CERTRevocationTests leafTests;
- CERTRevocationTests chainTests;
-} CERTRevocationFlags;
-
-typedef struct CERTValParamInValueStr {
- union {
- PRBool b;
- PRInt32 i;
- PRUint32 ui;
- PRInt64 l;
- PRUint64 ul;
- PRTime time;
- } scalar;
- union {
- const void* p;
- const char* s;
- const CERTCertificate* cert;
- const CERTCertList *chain;
- const CERTRevocationFlags *revocation;
- const CERTChainVerifyCallback *chainVerifyCallback;
- } pointer;
- union {
- const PRInt32 *pi;
- const PRUint32 *pui;
- const PRInt64 *pl;
- const PRUint64 *pul;
- const SECOidTag *oids;
- } array;
- int arraySize;
-} CERTValParamInValue;
-
-
-typedef struct CERTValParamOutValueStr {
- union {
- PRBool b;
- PRInt32 i;
- PRUint32 ui;
- PRInt64 l;
- PRUint64 ul;
- SECCertificateUsage usages;
- } scalar;
- union {
- void* p;
- char* s;
- CERTVerifyLog *log;
- CERTCertificate* cert;
- CERTCertList *chain;
- } pointer;
- union {
- void *p;
- SECOidTag *oids;
- } array;
- int arraySize;
-} CERTValParamOutValue;
-
-typedef struct {
- CERTValParamInType type;
- CERTValParamInValue value;
-} CERTValInParam;
-
-typedef struct {
- CERTValParamOutType type;
- CERTValParamOutValue value;
-} CERTValOutParam;
-
-/*
- * Levels of standards conformance strictness for CERT_NameToAsciiInvertible
- */
-typedef enum CertStrictnessLevels {
- CERT_N2A_READABLE = 0, /* maximum human readability */
- CERT_N2A_STRICT = 10, /* strict RFC compliance */
- CERT_N2A_INVERTIBLE = 20 /* maximum invertibility,
- all DirectoryStrings encoded in hex */
-} CertStrictnessLevel;
-
-/*
- * policy flag defines
- */
-#define CERT_POLICY_FLAG_NO_MAPPING 1
-#define CERT_POLICY_FLAG_EXPLICIT 2
-#define CERT_POLICY_FLAG_NO_ANY 4
-
-/*
- * CertStore flags
- */
-#define CERT_ENABLE_LDAP_FETCH 1
-#define CERT_ENABLE_HTTP_FETCH 2
-
-/* This functin pointer type may be used for any function that takes
- * a CERTCertificate * and returns an allocated string, which must be
- * freed by a call to PORT_Free.
- */
-typedef char * (*CERT_StringFromCertFcn)(CERTCertificate *cert);
-
-/* XXX Lisa thinks the template declarations belong in cert.h, not here? */
-
-#include "secasn1t.h" /* way down here because I expect template stuff to
- * move out of here anyway */
-
-SEC_BEGIN_PROTOS
-
-extern const SEC_ASN1Template CERT_CertificateRequestTemplate[];
-extern const SEC_ASN1Template CERT_CertificateTemplate[];
-extern const SEC_ASN1Template SEC_SignedCertificateTemplate[];
-extern const SEC_ASN1Template CERT_CertExtensionTemplate[];
-extern const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[];
-extern const SEC_ASN1Template SECKEY_PublicKeyTemplate[];
-extern const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[];
-extern const SEC_ASN1Template CERT_TimeChoiceTemplate[];
-extern const SEC_ASN1Template CERT_ValidityTemplate[];
-extern const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[];
-extern const SEC_ASN1Template SEC_CertSequenceTemplate[];
-
-extern const SEC_ASN1Template CERT_IssuerAndSNTemplate[];
-extern const SEC_ASN1Template CERT_NameTemplate[];
-extern const SEC_ASN1Template CERT_SetOfSignedCrlTemplate[];
-extern const SEC_ASN1Template CERT_RDNTemplate[];
-extern const SEC_ASN1Template CERT_SignedDataTemplate[];
-extern const SEC_ASN1Template CERT_CrlTemplate[];
-extern const SEC_ASN1Template CERT_SignedCrlTemplate[];
-
-/*
-** XXX should the attribute stuff be centralized for all of ns/security?
-*/
-extern const SEC_ASN1Template CERT_AttributeTemplate[];
-extern const SEC_ASN1Template CERT_SetOfAttributeTemplate[];
-
-/* These functions simply return the address of the above-declared templates.
-** This is necessary for Windows DLLs. Sigh.
-*/
-SEC_ASN1_CHOOSER_DECLARE(CERT_CertificateRequestTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_CertificateTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_CrlTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_IssuerAndSNTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_NameTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_SequenceOfCertExtensionTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_SetOfSignedCrlTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_SignedDataTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_SubjectPublicKeyInfoTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_SignedCertificateTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_SignedCrlTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_TimeChoiceTemplate)
-
-SEC_END_PROTOS
-
-#endif /* _CERTT_H_ */
diff --git a/security/nss/lib/certdb/certv3.c b/security/nss/lib/certdb/certv3.c
deleted file mode 100644
index 0af53588f..000000000
--- a/security/nss/lib/certdb/certv3.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Code for dealing with X509.V3 extensions.
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "secder.h"
-#include "secasn1.h"
-#include "certxutl.h"
-#include "secerr.h"
-
-SECStatus
-CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid,
- SECItem *value)
-{
- return (cert_FindExtensionByOID (cert->extensions, oid, value));
-}
-
-
-SECStatus
-CERT_FindCertExtension(CERTCertificate *cert, int tag, SECItem *value)
-{
- return (cert_FindExtension (cert->extensions, tag, value));
-}
-
-static void
-SetExts(void *object, CERTCertExtension **exts)
-{
- CERTCertificate *cert = (CERTCertificate *)object;
-
- cert->extensions = exts;
- DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3);
-}
-
-void *
-CERT_StartCertExtensions(CERTCertificate *cert)
-{
- return (cert_StartExtensions ((void *)cert, cert->arena, SetExts));
-}
-
-/* find the given extension in the certificate of the Issuer of 'cert' */
-SECStatus
-CERT_FindIssuerCertExtension(CERTCertificate *cert, int tag, SECItem *value)
-{
- CERTCertificate *issuercert;
- SECStatus rv;
-
- issuercert = CERT_FindCertByName(cert->dbhandle, &cert->derIssuer);
- if ( issuercert ) {
- rv = cert_FindExtension(issuercert->extensions, tag, value);
- CERT_DestroyCertificate(issuercert);
- } else {
- rv = SECFailure;
- }
-
- return(rv);
-}
-
-/* find a URL extension in the cert or its CA
- * apply the base URL string if it exists
- */
-char *
-CERT_FindCertURLExtension(CERTCertificate *cert, int tag, int catag)
-{
- SECStatus rv;
- SECItem urlitem = {siBuffer,0};
- SECItem baseitem = {siBuffer,0};
- SECItem urlstringitem = {siBuffer,0};
- SECItem basestringitem = {siBuffer,0};
- PRArenaPool *arena = NULL;
- PRBool hasbase;
- char *urlstring;
- char *str;
- int len;
- unsigned int i;
-
- urlstring = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( ! arena ) {
- goto loser;
- }
-
- hasbase = PR_FALSE;
-
- rv = cert_FindExtension(cert->extensions, tag, &urlitem);
- if ( rv == SECSuccess ) {
- rv = cert_FindExtension(cert->extensions, SEC_OID_NS_CERT_EXT_BASE_URL,
- &baseitem);
- if ( rv == SECSuccess ) {
- hasbase = PR_TRUE;
- }
-
- } else if ( catag ) {
- /* if the cert doesn't have the extensions, see if the issuer does */
- rv = CERT_FindIssuerCertExtension(cert, catag, &urlitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- rv = CERT_FindIssuerCertExtension(cert, SEC_OID_NS_CERT_EXT_BASE_URL,
- &baseitem);
- if ( rv == SECSuccess ) {
- hasbase = PR_TRUE;
- }
- } else {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, &urlstringitem,
- SEC_ASN1_GET(SEC_IA5StringTemplate), &urlitem);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
- if ( hasbase ) {
- rv = SEC_QuickDERDecodeItem(arena, &basestringitem,
- SEC_ASN1_GET(SEC_IA5StringTemplate),
- &baseitem);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- len = urlstringitem.len + ( hasbase ? basestringitem.len : 0 ) + 1;
-
- str = urlstring = (char *)PORT_Alloc(len);
- if ( urlstring == NULL ) {
- goto loser;
- }
-
- /* copy the URL base first */
- if ( hasbase ) {
-
- /* if the urlstring has a : in it, then we assume it is an absolute
- * URL, and will not get the base string pre-pended
- */
- for ( i = 0; i < urlstringitem.len; i++ ) {
- if ( urlstringitem.data[i] == ':' ) {
- goto nobase;
- }
- }
-
- PORT_Memcpy(str, basestringitem.data, basestringitem.len);
- str += basestringitem.len;
-
- }
-
-nobase:
- /* copy the rest (or all) of the URL */
- PORT_Memcpy(str, urlstringitem.data, urlstringitem.len);
- str += urlstringitem.len;
-
- *str = '\0';
- goto done;
-
-loser:
- if ( urlstring ) {
- PORT_Free(urlstring);
- }
-
- urlstring = NULL;
-done:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- if ( baseitem.data ) {
- PORT_Free(baseitem.data);
- }
- if ( urlitem.data ) {
- PORT_Free(urlitem.data);
- }
-
- return(urlstring);
-}
-
-/*
- * get the value of the Netscape Certificate Type Extension
- */
-SECStatus
-CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem)
-{
-
- return (CERT_FindBitStringExtension
- (cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem));
-}
-
-
-/*
- * get the value of a string type extension
- */
-char *
-CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag)
-{
- SECItem wrapperItem, tmpItem = {siBuffer,0};
- SECStatus rv;
- PRArenaPool *arena = NULL;
- char *retstring = NULL;
-
- wrapperItem.data = NULL;
- tmpItem.data = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- goto loser;
- }
-
- rv = cert_FindExtension(cert->extensions, oidtag,
- &wrapperItem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
- SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- retstring = (char *)PORT_Alloc(tmpItem.len + 1 );
- if ( retstring == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(retstring, tmpItem.data, tmpItem.len);
- retstring[tmpItem.len] = '\0';
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- if ( wrapperItem.data ) {
- PORT_Free(wrapperItem.data);
- }
-
- return(retstring);
-}
-
-/*
- * get the value of the X.509 v3 Key Usage Extension
- */
-SECStatus
-CERT_FindKeyUsageExtension(CERTCertificate *cert, SECItem *retItem)
-{
-
- return (CERT_FindBitStringExtension(cert->extensions,
- SEC_OID_X509_KEY_USAGE, retItem));
-}
-
-/*
- * get the value of the X.509 v3 Key Usage Extension
- */
-SECStatus
-CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
-{
-
- SECStatus rv;
- SECItem encodedValue = {siBuffer, NULL, 0 };
- SECItem decodedValue = {siBuffer, NULL, 0 };
-
- rv = cert_FindExtension
- (cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue);
- if (rv == SECSuccess) {
- PLArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (tmpArena) {
- rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
- SEC_ASN1_GET(SEC_OctetStringTemplate),
- &encodedValue);
- if (rv == SECSuccess) {
- rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
- }
- PORT_FreeArena(tmpArena, PR_FALSE);
- } else {
- rv = SECFailure;
- }
- }
- SECITEM_FreeItem(&encodedValue, PR_FALSE);
- return rv;
-}
-
-SECStatus
-CERT_FindBasicConstraintExten(CERTCertificate *cert,
- CERTBasicConstraints *value)
-{
- SECItem encodedExtenValue;
- SECStatus rv;
-
- encodedExtenValue.data = NULL;
- encodedExtenValue.len = 0;
-
- rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS,
- &encodedExtenValue);
- if ( rv != SECSuccess ) {
- return (rv);
- }
-
- rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue);
-
- /* free the raw extension data */
- PORT_Free(encodedExtenValue.data);
- encodedExtenValue.data = NULL;
-
- return(rv);
-}
-
-CERTAuthKeyID *
-CERT_FindAuthKeyIDExten (PRArenaPool *arena, CERTCertificate *cert)
-{
- SECItem encodedExtenValue;
- SECStatus rv;
- CERTAuthKeyID *ret;
-
- encodedExtenValue.data = NULL;
- encodedExtenValue.len = 0;
-
- rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID,
- &encodedExtenValue);
- if ( rv != SECSuccess ) {
- return (NULL);
- }
-
- ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue);
-
- PORT_Free(encodedExtenValue.data);
- encodedExtenValue.data = NULL;
-
- return(ret);
-}
-
-SECStatus
-CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage)
-{
- SECItem keyUsage;
- SECStatus rv;
-
- /* There is no extension, v1 or v2 certificate */
- if (cert->extensions == NULL) {
- return (SECSuccess);
- }
-
- keyUsage.data = NULL;
-
- /* This code formerly ignored the Key Usage extension if it was
- ** marked non-critical. That was wrong. Since we do understand it,
- ** we are obligated to honor it, whether or not it is critical.
- */
- rv = CERT_FindKeyUsageExtension(cert, &keyUsage);
- if (rv == SECFailure) {
- rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ?
- SECSuccess : SECFailure;
- } else if (!(keyUsage.data[0] & usage)) {
- PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID);
- rv = SECFailure;
- }
- PORT_Free (keyUsage.data);
- return (rv);
-}
diff --git a/security/nss/lib/certdb/certxutl.c b/security/nss/lib/certdb/certxutl.c
deleted file mode 100644
index def071224..000000000
--- a/security/nss/lib/certdb/certxutl.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Certificate Extensions handling code
- *
- */
-
-#include "cert.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "secder.h"
-#include "secasn1.h"
-#include "certxutl.h"
-#include "secerr.h"
-
-#ifdef OLD
-#include "ocspti.h" /* XXX a better extensions interface would not
- * require knowledge of data structures of callers */
-#endif
-
-static CERTCertExtension *
-GetExtension (CERTCertExtension **extensions, SECItem *oid)
-{
- CERTCertExtension **exts;
- CERTCertExtension *ext = NULL;
- SECComparison comp;
-
- exts = extensions;
-
- if (exts) {
- while ( *exts ) {
- ext = *exts;
- comp = SECITEM_CompareItem(oid, &ext->id);
- if ( comp == SECEqual )
- break;
-
- exts++;
- }
- return (*exts ? ext : NULL);
- }
- return (NULL);
-}
-
-SECStatus
-cert_FindExtensionByOID (CERTCertExtension **extensions, SECItem *oid, SECItem *value)
-{
- CERTCertExtension *ext;
- SECStatus rv = SECSuccess;
-
- ext = GetExtension (extensions, oid);
- if (ext == NULL) {
- PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
- return (SECFailure);
- }
- if (value)
- rv = SECITEM_CopyItem(NULL, value, &ext->value);
- return (rv);
-}
-
-
-SECStatus
-CERT_GetExtenCriticality (CERTCertExtension **extensions, int tag, PRBool *isCritical)
-{
- CERTCertExtension *ext;
- SECOidData *oid;
-
- if (!isCritical)
- return (SECSuccess);
-
- /* find the extension in the extensions list */
- oid = SECOID_FindOIDByTag((SECOidTag)tag);
- if ( !oid ) {
- return(SECFailure);
- }
- ext = GetExtension (extensions, &oid->oid);
- if (ext == NULL) {
- PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
- return (SECFailure);
- }
-
- /* If the criticality is omitted, then it is false by default.
- ex->critical.data is NULL */
- if (ext->critical.data == NULL)
- *isCritical = PR_FALSE;
- else
- *isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
- return (SECSuccess);
-}
-
-SECStatus
-cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value)
-{
- SECOidData *oid;
-
- oid = SECOID_FindOIDByTag((SECOidTag)tag);
- if ( !oid ) {
- return(SECFailure);
- }
-
- return(cert_FindExtensionByOID(extensions, &oid->oid, value));
-}
-
-
-typedef struct _extNode {
- struct _extNode *next;
- CERTCertExtension *ext;
-} extNode;
-
-typedef struct {
- void (*setExts)(void *object, CERTCertExtension **exts);
- void *object;
- PRArenaPool *ownerArena;
- PRArenaPool *arena;
- extNode *head;
- int count;
-}extRec;
-
-/*
- * cert_StartExtensions
- *
- * NOTE: This interface changed significantly to remove knowledge
- * about callers data structures (owner objects)
- */
-void *
-cert_StartExtensions(void *owner, PRArenaPool *ownerArena,
- void (*setExts)(void *object, CERTCertExtension **exts))
-{
- PRArenaPool *arena;
- extRec *handle;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- return(0);
- }
-
- handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec));
- if ( !handle ) {
- PORT_FreeArena(arena, PR_FALSE);
- return(0);
- }
-
- handle->object = owner;
- handle->ownerArena = ownerArena;
- handle->setExts = setExts;
-
- handle->arena = arena;
- handle->head = 0;
- handle->count = 0;
-
- return(handle);
-}
-
-static unsigned char hextrue = 0xff;
-
-/*
- * Note - assumes that data pointed to by oid->data will not move
- */
-SECStatus
-CERT_AddExtensionByOID (void *exthandle, SECItem *oid, SECItem *value,
- PRBool critical, PRBool copyData)
-{
- CERTCertExtension *ext;
- SECStatus rv;
- extNode *node;
- extRec *handle;
-
- handle = (extRec *)exthandle;
-
- /* allocate space for extension and list node */
- ext = (CERTCertExtension*)PORT_ArenaZAlloc(handle->ownerArena,
- sizeof(CERTCertExtension));
- if ( !ext ) {
- return(SECFailure);
- }
-
- node = (extNode*)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
- if ( !node ) {
- return(SECFailure);
- }
-
- /* add to list */
- node->next = handle->head;
- handle->head = node;
-
- /* point to ext struct */
- node->ext = ext;
-
- /* the object ID of the extension */
- ext->id = *oid;
-
- /* set critical field */
- if ( critical ) {
- ext->critical.data = (unsigned char*)&hextrue;
- ext->critical.len = 1;
- }
-
- /* set the value */
- if ( copyData ) {
- rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
- if ( rv ) {
- return(SECFailure);
- }
- } else {
- ext->value = *value;
- }
-
- handle->count++;
-
- return(SECSuccess);
-
-}
-
-SECStatus
-CERT_AddExtension(void *exthandle, int idtag, SECItem *value,
- PRBool critical, PRBool copyData)
-{
- SECOidData *oid;
-
- oid = SECOID_FindOIDByTag((SECOidTag)idtag);
- if ( !oid ) {
- return(SECFailure);
- }
-
- return(CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical, copyData));
-}
-
-SECStatus
-CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
- PRBool critical, const SEC_ASN1Template *atemplate)
-{
- extRec *handle;
- SECItem *encitem;
-
- handle = (extRec *)exthandle;
-
- encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate);
- if ( encitem == NULL ) {
- return(SECFailure);
- }
-
- return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE);
-}
-
-void
-PrepareBitStringForEncoding (SECItem *bitsmap, SECItem *value)
-{
- unsigned char onebyte;
- unsigned int i, len = 0;
-
- /* to prevent warning on some platform at compile time */
- onebyte = '\0';
- /* Get the position of the right-most turn-on bit */
- for (i = 0; i < (value->len ) * 8; ++i) {
- if (i % 8 == 0)
- onebyte = value->data[i/8];
- if (onebyte & 0x80)
- len = i;
- onebyte <<= 1;
-
- }
- bitsmap->data = value->data;
- /* Add one here since we work with base 1 */
- bitsmap->len = len + 1;
-}
-
-SECStatus
-CERT_EncodeAndAddBitStrExtension (void *exthandle, int idtag,
- SECItem *value, PRBool critical)
-{
- SECItem bitsmap;
-
- PrepareBitStringForEncoding (&bitsmap, value);
- return (CERT_EncodeAndAddExtension
- (exthandle, idtag, &bitsmap, critical,
- SEC_ASN1_GET(SEC_BitStringTemplate)));
-}
-
-SECStatus
-CERT_FinishExtensions(void *exthandle)
-{
- extRec *handle;
- extNode *node;
- CERTCertExtension **exts;
- SECStatus rv = SECFailure;
-
- handle = (extRec *)exthandle;
-
- /* allocate space for extensions array */
- exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *,
- handle->count + 1);
- if (exts == NULL) {
- goto loser;
- }
-
- /* put extensions in owner object and update its version number */
-
-#ifdef OLD
- switch (handle->type) {
- case CertificateExtensions:
- handle->owner.cert->extensions = exts;
- DER_SetUInteger (ownerArena, &(handle->owner.cert->version),
- SEC_CERTIFICATE_VERSION_3);
- break;
- case CrlExtensions:
- handle->owner.crl->extensions = exts;
- DER_SetUInteger (ownerArena, &(handle->owner.crl->version),
- SEC_CRL_VERSION_2);
- break;
- case OCSPRequestExtensions:
- handle->owner.request->tbsRequest->requestExtensions = exts;
- break;
- case OCSPSingleRequestExtensions:
- handle->owner.singleRequest->singleRequestExtensions = exts;
- break;
- case OCSPResponseSingleExtensions:
- handle->owner.singleResponse->singleExtensions = exts;
- break;
- }
-#endif
-
- handle->setExts(handle->object, exts);
-
- /* update the version number */
-
- /* copy each extension pointer */
- node = handle->head;
- while ( node ) {
- *exts = node->ext;
-
- node = node->next;
- exts++;
- }
-
- /* terminate the array of extensions */
- *exts = 0;
-
- rv = SECSuccess;
-
-loser:
- /* free working arena */
- PORT_FreeArena(handle->arena, PR_FALSE);
- return rv;
-}
-
-SECStatus
-CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
-{
- CERTCertExtension *ext;
- SECStatus rv = SECSuccess;
- SECOidTag tag;
- extNode *node;
- extRec *handle = exthandle;
-
- if (!exthandle || !extensions) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- while ((ext = *extensions++) != NULL) {
- tag = SECOID_FindOIDTag(&ext->id);
- for (node=handle->head; node != NULL; node=node->next) {
- if (tag == 0) {
- if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
- break;
- }
- else {
- if (SECOID_FindOIDTag(&node->ext->id) == tag) {
- break;
- }
- }
- }
- if (node == NULL) {
- PRBool critical = (ext->critical.len != 0 &&
- ext->critical.data[ext->critical.len - 1] != 0);
- if (critical && tag == SEC_OID_UNKNOWN) {
- PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
- rv = SECFailure;
- break;
- }
- /* add to list */
- rv = CERT_AddExtensionByOID (exthandle, &ext->id, &ext->value,
- critical, PR_TRUE);
- if (rv != SECSuccess)
- break;
- }
- }
- return rv;
-}
-
-/*
- * get the value of the Netscape Certificate Type Extension
- */
-SECStatus
-CERT_FindBitStringExtension (CERTCertExtension **extensions, int tag,
- SECItem *retItem)
-{
- SECItem wrapperItem, tmpItem = {siBuffer,0};
- SECStatus rv;
- PRArenaPool *arena = NULL;
-
- wrapperItem.data = NULL;
- tmpItem.data = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( ! arena ) {
- return(SECFailure);
- }
-
- rv = cert_FindExtension(extensions, tag, &wrapperItem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
- SEC_ASN1_GET(SEC_BitStringTemplate),
- &wrapperItem);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- retItem->data = (unsigned char *)PORT_Alloc( ( tmpItem.len + 7 ) >> 3 );
- if ( retItem->data == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(retItem->data, tmpItem.data, ( tmpItem.len + 7 ) >> 3);
- retItem->len = tmpItem.len;
-
- rv = SECSuccess;
- goto done;
-
-loser:
- rv = SECFailure;
-
-done:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- if ( wrapperItem.data ) {
- PORT_Free(wrapperItem.data);
- }
-
- return(rv);
-}
-
-PRBool
-cert_HasCriticalExtension (CERTCertExtension **extensions)
-{
- CERTCertExtension **exts;
- CERTCertExtension *ext = NULL;
- PRBool hasCriticalExten = PR_FALSE;
-
- exts = extensions;
-
- if (exts) {
- while ( *exts ) {
- ext = *exts;
- /* If the criticality is omitted, it's non-critical */
- if (ext->critical.data && ext->critical.data[0] == 0xff) {
- hasCriticalExten = PR_TRUE;
- break;
- }
- exts++;
- }
- }
- return (hasCriticalExten);
-}
-
-PRBool
-cert_HasUnknownCriticalExten (CERTCertExtension **extensions)
-{
- CERTCertExtension **exts;
- CERTCertExtension *ext = NULL;
- PRBool hasUnknownCriticalExten = PR_FALSE;
-
- exts = extensions;
-
- if (exts) {
- while ( *exts ) {
- ext = *exts;
- /* If the criticality is omitted, it's non-critical.
- If an extension is critical, make sure that we know
- how to process the extension.
- */
- if (ext->critical.data && ext->critical.data[0] == 0xff) {
- if (SECOID_KnownCertExtenOID (&ext->id) == PR_FALSE) {
- hasUnknownCriticalExten = PR_TRUE;
- break;
- }
- }
- exts++;
- }
- }
- return (hasUnknownCriticalExten);
-}
diff --git a/security/nss/lib/certdb/certxutl.h b/security/nss/lib/certdb/certxutl.h
deleted file mode 100644
index 05ad572fd..000000000
--- a/security/nss/lib/certdb/certxutl.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * x.509 v3 certificate extension helper routines
- *
- */
-
-
-#ifndef _CERTXUTL_H_
-#define _CERTXUTL_H_
-
-#include "nspr.h"
-
-#ifdef OLD
-typedef enum {
- CertificateExtensions,
- CrlExtensions,
- OCSPRequestExtensions,
- OCSPSingleRequestExtensions,
- OCSPResponseSingleExtensions
-} ExtensionsType;
-#endif
-
-extern PRBool
-cert_HasCriticalExtension (CERTCertExtension **extensions);
-
-extern SECStatus
-CERT_FindBitStringExtension (CERTCertExtension **extensions,
- int tag, SECItem *retItem);
-extern void *
-cert_StartExtensions (void *owner, PLArenaPool *arena,
- void (*setExts)(void *object, CERTCertExtension **exts));
-
-extern SECStatus
-cert_FindExtension (CERTCertExtension **extensions, int tag, SECItem *value);
-
-extern SECStatus
-cert_FindExtensionByOID (CERTCertExtension **extensions,
- SECItem *oid, SECItem *value);
-
-extern SECStatus
-cert_GetExtenCriticality (CERTCertExtension **extensions,
- int tag, PRBool *isCritical);
-
-extern PRBool
-cert_HasUnknownCriticalExten (CERTCertExtension **extensions);
-
-#endif
diff --git a/security/nss/lib/certdb/config.mk b/security/nss/lib/certdb/config.mk
deleted file mode 100644
index b8c03de79..000000000
--- a/security/nss/lib/certdb/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c
deleted file mode 100644
index 8bb446cf3..000000000
--- a/security/nss/lib/certdb/crl.c
+++ /dev/null
@@ -1,3373 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Moved from secpkcs7.c
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "certi.h"
-#include "secder.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "certdb.h"
-#include "certxutl.h"
-#include "prtime.h"
-#include "secerr.h"
-#include "pk11func.h"
-#include "dev.h"
-#include "dev3hack.h"
-#include "nssbase.h"
-#if defined(DPC_RWLOCK) || defined(GLOBAL_RWLOCK)
-#include "nssrwlk.h"
-#endif
-#include "pk11priv.h"
-
-const SEC_ASN1Template SEC_CERTExtensionTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCertExtension) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTCertExtension,id) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
- offsetof(CERTCertExtension,critical), },
- { SEC_ASN1_OCTET_STRING,
- offsetof(CERTCertExtension,value) },
- { 0, }
-};
-
-static const SEC_ASN1Template SEC_CERTExtensionsTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_CERTExtensionTemplate}
-};
-
-/*
- * XXX Also, these templates need to be tested; Lisa did the obvious
- * translation but they still should be verified.
- */
-
-const SEC_ASN1Template CERT_IssuerAndSNTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTIssuerAndSN) },
- { SEC_ASN1_SAVE,
- offsetof(CERTIssuerAndSN,derIssuer) },
- { SEC_ASN1_INLINE,
- offsetof(CERTIssuerAndSN,issuer),
- CERT_NameTemplate },
- { SEC_ASN1_INTEGER,
- offsetof(CERTIssuerAndSN,serialNumber) },
- { 0 }
-};
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(CERT_TimeChoiceTemplate)
-
-static const SEC_ASN1Template cert_CrlKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCrlKey) },
- { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(CERTCrlKey,dummy) },
- { SEC_ASN1_SKIP },
- { SEC_ASN1_ANY, offsetof(CERTCrlKey,derName) },
- { SEC_ASN1_SKIP_REST },
- { 0 }
-};
-
-static const SEC_ASN1Template cert_CrlEntryTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCrlEntry) },
- { SEC_ASN1_INTEGER,
- offsetof(CERTCrlEntry,serialNumber) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTCrlEntry,revocationDate),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF,
- offsetof(CERTCrlEntry, extensions),
- SEC_CERTExtensionTemplate},
- { 0 }
-};
-
-const SEC_ASN1Template CERT_CrlTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCrl) },
- { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof (CERTCrl, version) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTCrl,signatureAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate)},
- { SEC_ASN1_SAVE,
- offsetof(CERTCrl,derName) },
- { SEC_ASN1_INLINE,
- offsetof(CERTCrl,name),
- CERT_NameTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTCrl,lastUpdate),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
- offsetof(CERTCrl,nextUpdate),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF,
- offsetof(CERTCrl,entries),
- cert_CrlEntryTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_EXPLICIT | 0,
- offsetof(CERTCrl,extensions),
- SEC_CERTExtensionsTemplate},
- { 0 }
-};
-
-const SEC_ASN1Template CERT_CrlTemplateNoEntries[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCrl) },
- { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof (CERTCrl, version) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTCrl,signatureAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_SAVE,
- offsetof(CERTCrl,derName) },
- { SEC_ASN1_INLINE,
- offsetof(CERTCrl,name),
- CERT_NameTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTCrl,lastUpdate),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
- offsetof(CERTCrl,nextUpdate),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF |
- SEC_ASN1_SKIP }, /* skip entries */
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_EXPLICIT | 0,
- offsetof(CERTCrl,extensions),
- SEC_CERTExtensionsTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_CrlTemplateEntriesOnly[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCrl) },
- { SEC_ASN1_SKIP | SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL },
- { SEC_ASN1_SKIP },
- { SEC_ASN1_SKIP },
- { SEC_ASN1_SKIP | SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTCrl,lastUpdate),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
- { SEC_ASN1_SKIP | SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
- offsetof(CERTCrl,nextUpdate),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF,
- offsetof(CERTCrl,entries),
- cert_CrlEntryTemplate }, /* decode entries */
- { SEC_ASN1_SKIP_REST },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_SignedCrlTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTSignedCrl) },
- { SEC_ASN1_SAVE,
- offsetof(CERTSignedCrl,signatureWrap.data) },
- { SEC_ASN1_INLINE,
- offsetof(CERTSignedCrl,crl),
- CERT_CrlTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN ,
- offsetof(CERTSignedCrl,signatureWrap.signatureAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_BIT_STRING,
- offsetof(CERTSignedCrl,signatureWrap.signature) },
- { 0 }
-};
-
-static const SEC_ASN1Template cert_SignedCrlTemplateNoEntries[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTSignedCrl) },
- { SEC_ASN1_SAVE,
- offsetof(CERTSignedCrl,signatureWrap.data) },
- { SEC_ASN1_INLINE,
- offsetof(CERTSignedCrl,crl),
- CERT_CrlTemplateNoEntries },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTSignedCrl,signatureWrap.signatureAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_BIT_STRING,
- offsetof(CERTSignedCrl,signatureWrap.signature) },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_SetOfSignedCrlTemplate[] = {
- { SEC_ASN1_SET_OF, 0, CERT_SignedCrlTemplate },
-};
-
-/* get CRL version */
-int cert_get_crl_version(CERTCrl * crl)
-{
- /* CRL version is defaulted to v1 */
- int version = SEC_CRL_VERSION_1;
- if (crl && crl->version.data != 0) {
- version = (int)DER_GetUInteger (&crl->version);
- }
- return version;
-}
-
-
-/* check the entries in the CRL */
-SECStatus cert_check_crl_entries (CERTCrl *crl)
-{
- CERTCrlEntry **entries;
- CERTCrlEntry *entry;
- PRBool hasCriticalExten = PR_FALSE;
- SECStatus rv = SECSuccess;
-
- if (!crl) {
- return SECFailure;
- }
-
- if (crl->entries == NULL) {
- /* CRLs with no entries are valid */
- return (SECSuccess);
- }
-
- /* Look in the crl entry extensions. If there is a critical extension,
- then the crl version must be v2; otherwise, it should be v1.
- */
- entries = crl->entries;
- while (*entries) {
- entry = *entries;
- if (entry->extensions) {
- /* If there is a critical extension in the entries, then the
- CRL must be of version 2. If we already saw a critical extension,
- there is no need to check the version again.
- */
- if (hasCriticalExten == PR_FALSE) {
- hasCriticalExten = cert_HasCriticalExtension (entry->extensions);
- if (hasCriticalExten) {
- if (cert_get_crl_version(crl) != SEC_CRL_VERSION_2) {
- /* only CRL v2 critical extensions are supported */
- PORT_SetError(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION);
- rv = SECFailure;
- break;
- }
- }
- }
-
- /* For each entry, make sure that it does not contain an unknown
- critical extension. If it does, we must reject the CRL since
- we don't know how to process the extension.
- */
- if (cert_HasUnknownCriticalExten (entry->extensions) == PR_TRUE) {
- PORT_SetError (SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION);
- rv = SECFailure;
- break;
- }
- }
- ++entries;
- }
- return(rv);
-}
-
-/* Check the version of the CRL. If there is a critical extension in the crl
- or crl entry, then the version must be v2. Otherwise, it should be v1. If
- the crl contains critical extension(s), then we must recognized the
- extension's OID.
- */
-SECStatus cert_check_crl_version (CERTCrl *crl)
-{
- PRBool hasCriticalExten = PR_FALSE;
- int version = cert_get_crl_version(crl);
-
- if (version > SEC_CRL_VERSION_2) {
- PORT_SetError (SEC_ERROR_CRL_INVALID_VERSION);
- return (SECFailure);
- }
-
- /* Check the crl extensions for a critial extension. If one is found,
- and the version is not v2, then we are done.
- */
- if (crl->extensions) {
- hasCriticalExten = cert_HasCriticalExtension (crl->extensions);
- if (hasCriticalExten) {
- if (version != SEC_CRL_VERSION_2) {
- /* only CRL v2 critical extensions are supported */
- PORT_SetError(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION);
- return (SECFailure);
- }
- /* make sure that there is no unknown critical extension */
- if (cert_HasUnknownCriticalExten (crl->extensions) == PR_TRUE) {
- PORT_SetError (SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION);
- return (SECFailure);
- }
- }
- }
-
- return (SECSuccess);
-}
-
-/*
- * Generate a database key, based on the issuer name from a
- * DER crl.
- */
-SECStatus
-CERT_KeyFromDERCrl(PRArenaPool *arena, SECItem *derCrl, SECItem *key)
-{
- SECStatus rv;
- CERTSignedData sd;
- CERTCrlKey crlkey;
- PRArenaPool* myArena;
-
- if (!arena) {
- /* arena needed for QuickDER */
- myArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- } else {
- myArena = arena;
- }
- PORT_Memset (&sd, 0, sizeof (sd));
- rv = SEC_QuickDERDecodeItem (myArena, &sd, CERT_SignedDataTemplate, derCrl);
- if (SECSuccess == rv) {
- PORT_Memset (&crlkey, 0, sizeof (crlkey));
- rv = SEC_QuickDERDecodeItem(myArena, &crlkey, cert_CrlKeyTemplate, &sd.data);
- }
-
- /* make a copy so the data doesn't point to memory inside derCrl, which
- may be temporary */
- if (SECSuccess == rv) {
- rv = SECITEM_CopyItem(arena, key, &crlkey.derName);
- }
-
- if (myArena != arena) {
- PORT_FreeArena(myArena, PR_FALSE);
- }
-
- return rv;
-}
-
-#define GetOpaqueCRLFields(x) ((OpaqueCRLFields*)x->opaque)
-
-SECStatus CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl)
-{
- SECStatus rv = SECSuccess;
- SECItem* crldata = NULL;
- OpaqueCRLFields* extended = NULL;
-
- if ( (!crl) ||
- (!(extended = (OpaqueCRLFields*) crl->opaque)) ||
- (PR_TRUE == extended->decodingError) ) {
- rv = SECFailure;
- } else {
- if (PR_FALSE == extended->partial) {
- /* the CRL has already been fully decoded */
- return SECSuccess;
- }
- if (PR_TRUE == extended->badEntries) {
- /* the entries decoding already failed */
- return SECFailure;
- }
- crldata = &crl->signatureWrap.data;
- if (!crldata) {
- rv = SECFailure;
- }
- }
-
- if (SECSuccess == rv) {
- rv = SEC_QuickDERDecodeItem(crl->arena,
- &crl->crl,
- CERT_CrlTemplateEntriesOnly,
- crldata);
- if (SECSuccess == rv) {
- extended->partial = PR_FALSE; /* successful decode, avoid
- decoding again */
- } else {
- extended->decodingError = PR_TRUE;
- extended->badEntries = PR_TRUE;
- /* cache the decoding failure. If it fails the first time,
- it will fail again, which will grow the arena and leak
- memory, so we want to avoid it */
- }
- rv = cert_check_crl_entries(&crl->crl);
- if (rv != SECSuccess) {
- extended->badExtensions = PR_TRUE;
- }
- }
- return rv;
-}
-
-/*
- * take a DER CRL and decode it into a CRL structure
- * allow reusing the input DER without making a copy
- */
-CERTSignedCrl *
-CERT_DecodeDERCrlWithFlags(PRArenaPool *narena, SECItem *derSignedCrl,
- int type, PRInt32 options)
-{
- PRArenaPool *arena;
- CERTSignedCrl *crl;
- SECStatus rv;
- OpaqueCRLFields* extended = NULL;
- const SEC_ASN1Template* crlTemplate = CERT_SignedCrlTemplate;
- PRInt32 testOptions = options;
-
- PORT_Assert(derSignedCrl);
- if (!derSignedCrl) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- /* Adopting DER requires not copying it. Code that sets ADOPT flag
- * but doesn't set DONT_COPY probably doesn't know What it is doing.
- * That condition is a programming error in the caller.
- */
- testOptions &= (CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_DONT_COPY_DER);
- PORT_Assert(testOptions != CRL_DECODE_ADOPT_HEAP_DER);
- if (testOptions == CRL_DECODE_ADOPT_HEAP_DER) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- /* make a new arena if needed */
- if (narena == NULL) {
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- return NULL;
- }
- } else {
- arena = narena;
- }
-
- /* allocate the CRL structure */
- crl = (CERTSignedCrl *)PORT_ArenaZAlloc(arena, sizeof(CERTSignedCrl));
- if ( !crl ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- crl->arena = arena;
-
- /* allocate opaque fields */
- crl->opaque = (void*)PORT_ArenaZAlloc(arena, sizeof(OpaqueCRLFields));
- if ( !crl->opaque ) {
- goto loser;
- }
- extended = (OpaqueCRLFields*) crl->opaque;
- if (options & CRL_DECODE_ADOPT_HEAP_DER) {
- extended->heapDER = PR_TRUE;
- }
- if (options & CRL_DECODE_DONT_COPY_DER) {
- crl->derCrl = derSignedCrl; /* DER is not copied . The application
- must keep derSignedCrl until it
- destroys the CRL */
- } else {
- crl->derCrl = (SECItem *)PORT_ArenaZAlloc(arena,sizeof(SECItem));
- if (crl->derCrl == NULL) {
- goto loser;
- }
- rv = SECITEM_CopyItem(arena, crl->derCrl, derSignedCrl);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
-
- /* Save the arena in the inner crl for CRL extensions support */
- crl->crl.arena = arena;
- if (options & CRL_DECODE_SKIP_ENTRIES) {
- crlTemplate = cert_SignedCrlTemplateNoEntries;
- extended->partial = PR_TRUE;
- }
-
- /* decode the CRL info */
- switch (type) {
- case SEC_CRL_TYPE:
- rv = SEC_QuickDERDecodeItem(arena, crl, crlTemplate, crl->derCrl);
- if (rv != SECSuccess) {
- extended->badDER = PR_TRUE;
- break;
- }
- /* check for critical extensions */
- rv = cert_check_crl_version (&crl->crl);
- if (rv != SECSuccess) {
- extended->badExtensions = PR_TRUE;
- break;
- }
-
- if (PR_TRUE == extended->partial) {
- /* partial decoding, don't verify entries */
- break;
- }
-
- rv = cert_check_crl_entries(&crl->crl);
- if (rv != SECSuccess) {
- extended->badExtensions = PR_TRUE;
- }
-
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- break;
- }
-
- if (rv != SECSuccess) {
- goto loser;
- }
-
- crl->referenceCount = 1;
-
- return(crl);
-
-loser:
- if (options & CRL_DECODE_KEEP_BAD_CRL) {
- if (extended) {
- extended->decodingError = PR_TRUE;
- }
- if (crl) {
- crl->referenceCount = 1;
- return(crl);
- }
- }
-
- if ((narena == NULL) && arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(0);
-}
-
-/*
- * take a DER CRL and decode it into a CRL structure
- */
-CERTSignedCrl *
-CERT_DecodeDERCrl(PRArenaPool *narena, SECItem *derSignedCrl, int type)
-{
- return CERT_DecodeDERCrlWithFlags(narena, derSignedCrl, type,
- CRL_DECODE_DEFAULT_OPTIONS);
-}
-
-/*
- * Lookup a CRL in the databases. We mirror the same fast caching data base
- * caching stuff used by certificates....?
- * return values :
- *
- * SECSuccess means we got a valid decodable DER CRL, or no CRL at all.
- * Caller may distinguish those cases by the value returned in "decoded".
- * When DER CRL is not found, error code will be SEC_ERROR_CRL_NOT_FOUND.
- *
- * SECFailure means we got a fatal error - most likely, we found a CRL,
- * and it failed decoding, or there was an out of memory error. Do NOT ignore
- * it and specifically do NOT treat it the same as having no CRL, as this
- * can compromise security !!! Ideally, you should treat this case as if you
- * received a "catch-all" CRL where all certs you were looking up are
- * considered to be revoked
- */
-static SECStatus
-SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type,
- CERTSignedCrl** decoded, PRInt32 decodeoptions)
-{
- SECStatus rv = SECSuccess;
- CERTSignedCrl *crl = NULL;
- SECItem *derCrl = NULL;
- CK_OBJECT_HANDLE crlHandle = 0;
- char *url = NULL;
-
- PORT_Assert(decoded);
- if (!decoded) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey, type, &url);
- if (derCrl == NULL) {
- /* if we had a problem other than the CRL just didn't exist, return
- * a failure to the upper level */
- int nsserror = PORT_GetError();
- if (nsserror != SEC_ERROR_CRL_NOT_FOUND) {
- rv = SECFailure;
- }
- goto loser;
- }
- PORT_Assert(crlHandle != CK_INVALID_HANDLE);
- /* PK11_FindCrlByName obtained a slot reference. */
-
- /* derCRL is a fresh HEAP copy made for us by PK11_FindCrlByName.
- Force adoption of the DER CRL from the heap - this will cause it
- to be automatically freed when SEC_DestroyCrl is invoked */
- decodeoptions |= (CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_DONT_COPY_DER);
-
- crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl, type, decodeoptions);
- if (crl) {
- crl->slot = slot;
- slot = NULL; /* adopt it */
- derCrl = NULL; /* adopted by the crl struct */
- crl->pkcs11ID = crlHandle;
- if (url) {
- crl->url = PORT_ArenaStrdup(crl->arena,url);
- }
- } else {
- rv = SECFailure;
- }
-
- if (url) {
- PORT_Free(url);
- }
-
- if (slot) {
- PK11_FreeSlot(slot);
- }
-
-loser:
- if (derCrl) {
- SECITEM_FreeItem(derCrl, PR_TRUE);
- }
-
- *decoded = crl;
-
- return rv;
-}
-
-
-CERTSignedCrl *
-crl_storeCRL (PK11SlotInfo *slot,char *url,
- CERTSignedCrl *newCrl, SECItem *derCrl, int type)
-{
- CERTSignedCrl *oldCrl = NULL, *crl = NULL;
- PRBool deleteOldCrl = PR_FALSE;
- CK_OBJECT_HANDLE crlHandle = CK_INVALID_HANDLE;
- SECStatus rv;
-
- PORT_Assert(newCrl);
- PORT_Assert(derCrl);
- PORT_Assert(type == SEC_CRL_TYPE);
-
- if (type != SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- /* we can't use the cache here because we must look in the same
- token */
- rv = SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type,
- &oldCrl, CRL_DECODE_SKIP_ENTRIES);
- /* if there is an old crl on the token, make sure the one we are
- installing is newer. If not, exit out, otherwise delete the
- old crl.
- */
- if (oldCrl != NULL) {
- /* if it's already there, quietly continue */
- if (SECITEM_CompareItem(newCrl->derCrl, oldCrl->derCrl)
- == SECEqual) {
- crl = newCrl;
- crl->slot = PK11_ReferenceSlot(slot);
- crl->pkcs11ID = oldCrl->pkcs11ID;
- if (oldCrl->url && !url)
- url = oldCrl->url;
- if (url)
- crl->url = PORT_ArenaStrdup(crl->arena, url);
- goto done;
- }
- if (!SEC_CrlIsNewer(&newCrl->crl,&oldCrl->crl)) {
- PORT_SetError(SEC_ERROR_OLD_CRL);
- goto done;
- }
-
- /* if we have a url in the database, use that one */
- if (oldCrl->url && !url) {
- url = oldCrl->url;
- }
-
- /* really destroy this crl */
- /* first drum it out of the permanment Data base */
- deleteOldCrl = PR_TRUE;
- }
-
- /* invalidate CRL cache for this issuer */
- CERT_CRLCacheRefreshIssuer(NULL, &newCrl->crl.derName);
- /* Write the new entry into the data base */
- crlHandle = PK11_PutCrl(slot, derCrl, &newCrl->crl.derName, url, type);
- if (crlHandle != CK_INVALID_HANDLE) {
- crl = newCrl;
- crl->slot = PK11_ReferenceSlot(slot);
- crl->pkcs11ID = crlHandle;
- if (url) {
- crl->url = PORT_ArenaStrdup(crl->arena,url);
- }
- }
-
-done:
- if (oldCrl) {
- if (deleteOldCrl && crlHandle != CK_INVALID_HANDLE) {
- SEC_DeletePermCRL(oldCrl);
- }
- SEC_DestroyCrl(oldCrl);
- }
-
- return crl;
-}
-
-/*
- *
- * create a new CRL from DER material.
- *
- * The signature on this CRL must be checked before you
- * load it. ???
- */
-CERTSignedCrl *
-SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type)
-{
- CERTSignedCrl* retCrl = NULL;
- PK11SlotInfo* slot = PK11_GetInternalKeySlot();
- retCrl = PK11_ImportCRL(slot, derCrl, url, type, NULL,
- CRL_IMPORT_BYPASS_CHECKS, NULL, CRL_DECODE_DEFAULT_OPTIONS);
- PK11_FreeSlot(slot);
-
- return retCrl;
-}
-
-CERTSignedCrl *
-SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type)
-{
- PRArenaPool *arena;
- SECItem crlKey;
- SECStatus rv;
- CERTSignedCrl *crl = NULL;
-
- /* create a scratch arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
- }
-
- /* extract the database key from the cert */
- rv = CERT_KeyFromDERCrl(arena, derCrl, &crlKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* find the crl */
- crl = SEC_FindCrlByName(handle, &crlKey, type);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(crl);
-}
-
-CERTSignedCrl* SEC_DupCrl(CERTSignedCrl* acrl)
-{
- if (acrl)
- {
- PR_ATOMIC_INCREMENT(&acrl->referenceCount);
- return acrl;
- }
- return NULL;
-}
-
-SECStatus
-SEC_DestroyCrl(CERTSignedCrl *crl)
-{
- if (crl) {
- if (PR_ATOMIC_DECREMENT(&crl->referenceCount) < 1) {
- if (crl->slot) {
- PK11_FreeSlot(crl->slot);
- }
- if (GetOpaqueCRLFields(crl) &&
- PR_TRUE == GetOpaqueCRLFields(crl)->heapDER) {
- SECITEM_FreeItem(crl->derCrl, PR_TRUE);
- }
- if (crl->arena) {
- PORT_FreeArena(crl->arena, PR_FALSE);
- }
- }
- return SECSuccess;
- } else {
- return SECFailure;
- }
-}
-
-SECStatus
-SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type)
-{
- CERTCrlHeadNode *head;
- PRArenaPool *arena = NULL;
- SECStatus rv;
-
- *nodes = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return SECFailure;
- }
-
- /* build a head structure */
- head = (CERTCrlHeadNode *)PORT_ArenaAlloc(arena, sizeof(CERTCrlHeadNode));
- head->arena = arena;
- head->first = NULL;
- head->last = NULL;
- head->dbhandle = handle;
-
- /* Look up the proper crl types */
- *nodes = head;
-
- rv = PK11_LookupCrls(head, type, NULL);
-
- if (rv != SECSuccess) {
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- *nodes = NULL;
- }
- }
-
- return rv;
-}
-
-/* These functions simply return the address of the above-declared templates.
-** This is necessary for Windows DLLs. Sigh.
-*/
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_IssuerAndSNTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CrlTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SignedCrlTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SetOfSignedCrlTemplate)
-
-/* CRL cache code starts here */
-
-/* constructor */
-static SECStatus CachedCrl_Create(CachedCrl** returned, CERTSignedCrl* crl,
- CRLOrigin origin);
-/* destructor */
-static SECStatus CachedCrl_Destroy(CachedCrl* crl);
-
-/* create hash table of CRL entries */
-static SECStatus CachedCrl_Populate(CachedCrl* crlobject);
-
-/* empty the cache content */
-static SECStatus CachedCrl_Depopulate(CachedCrl* crl);
-
-/* are these CRLs the same, as far as the cache is concerned ?
- Or are they the same token object, but with different DER ? */
-
-static SECStatus CachedCrl_Compare(CachedCrl* a, CachedCrl* b, PRBool* isDupe,
- PRBool* isUpdated);
-
-/* create a DPCache object */
-static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer,
- const SECItem* subject, SECItem* dp);
-
-/* destructor for CRL DPCache object */
-static SECStatus DPCache_Destroy(CRLDPCache* cache);
-
-/* add a new CRL object to the dynamic array of CRLs of the DPCache, and
- returns the cached CRL object . Needs write access to DPCache. */
-static SECStatus DPCache_AddCRL(CRLDPCache* cache, CachedCrl* crl,
- PRBool* added);
-
-/* fetch the CRL for this DP from the PKCS#11 tokens */
-static SECStatus DPCache_FetchFromTokens(CRLDPCache* cache, PRTime vfdate,
- void* wincx);
-
-/* update the content of the CRL cache, including fetching of CRLs, and
- reprocessing with specified issuer and date */
-static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate* issuer,
- PRBool readlocked, PRTime vfdate, void* wincx);
-
-/* returns true if there are CRLs from PKCS#11 slots */
-static PRBool DPCache_HasTokenCRLs(CRLDPCache* cache);
-
-/* remove CRL at offset specified */
-static SECStatus DPCache_RemoveCRL(CRLDPCache* cache, PRUint32 offset);
-
-/* Pick best CRL to use . needs write access */
-static SECStatus DPCache_SelectCRL(CRLDPCache* cache);
-
-/* create an issuer cache object (per CA subject ) */
-static SECStatus IssuerCache_Create(CRLIssuerCache** returned,
- CERTCertificate* issuer,
- const SECItem* subject, const SECItem* dp);
-
-/* destructor for CRL IssuerCache object */
-SECStatus IssuerCache_Destroy(CRLIssuerCache* cache);
-
-/* add a DPCache to the issuer cache */
-static SECStatus IssuerCache_AddDP(CRLIssuerCache* cache,
- CERTCertificate* issuer,
- const SECItem* subject,
- const SECItem* dp, CRLDPCache** newdpc);
-
-/* get a particular DPCache object from an IssuerCache */
-static CRLDPCache* IssuerCache_GetDPCache(CRLIssuerCache* cache,
- const SECItem* dp);
-
-/*
-** Pre-allocator hash allocator ops.
-*/
-
-/* allocate memory for hash table */
-static void * PR_CALLBACK
-PreAllocTable(void *pool, PRSize size)
-{
- PreAllocator* alloc = (PreAllocator*)pool;
- PORT_Assert(alloc);
- if (!alloc)
- {
- /* no allocator, or buffer full */
- return NULL;
- }
- if (size > (alloc->len - alloc->used))
- {
- /* initial buffer full, let's use the arena */
- alloc->extra += size;
- return PORT_ArenaAlloc(alloc->arena, size);
- }
- /* use the initial buffer */
- alloc->used += size;
- return (char*) alloc->data + alloc->used - size;
-}
-
-/* free hash table memory.
- Individual PreAllocator elements cannot be freed, so this is a no-op. */
-static void PR_CALLBACK
-PreFreeTable(void *pool, void *item)
-{
-}
-
-/* allocate memory for hash table */
-static PLHashEntry * PR_CALLBACK
-PreAllocEntry(void *pool, const void *key)
-{
- return PreAllocTable(pool, sizeof(PLHashEntry));
-}
-
-/* free hash table entry.
- Individual PreAllocator elements cannot be freed, so this is a no-op. */
-static void PR_CALLBACK
-PreFreeEntry(void *pool, PLHashEntry *he, PRUintn flag)
-{
-}
-
-/* methods required for PL hash table functions */
-static PLHashAllocOps preAllocOps =
-{
- PreAllocTable, PreFreeTable,
- PreAllocEntry, PreFreeEntry
-};
-
-/* destructor for PreAllocator object */
-void PreAllocator_Destroy(PreAllocator* PreAllocator)
-{
- if (!PreAllocator)
- {
- return;
- }
- if (PreAllocator->arena)
- {
- PORT_FreeArena(PreAllocator->arena, PR_TRUE);
- }
-}
-
-/* constructor for PreAllocator object */
-PreAllocator* PreAllocator_Create(PRSize size)
-{
- PRArenaPool* arena = NULL;
- PreAllocator* prebuffer = NULL;
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena)
- {
- return NULL;
- }
- prebuffer = (PreAllocator*)PORT_ArenaZAlloc(arena,
- sizeof(PreAllocator));
- if (!prebuffer)
- {
- PORT_FreeArena(arena, PR_TRUE);
- return NULL;
- }
- prebuffer->arena = arena;
-
- if (size)
- {
- prebuffer->len = size;
- prebuffer->data = PORT_ArenaAlloc(arena, size);
- if (!prebuffer->data)
- {
- PORT_FreeArena(arena, PR_TRUE);
- return NULL;
- }
- }
- return prebuffer;
-}
-
-/* global Named CRL cache object */
-static NamedCRLCache namedCRLCache = { NULL, NULL };
-
-/* global CRL cache object */
-static CRLCache crlcache = { NULL, NULL };
-
-/* initial state is off */
-static PRBool crlcache_initialized = PR_FALSE;
-
-PRTime CRLCache_Empty_TokenFetch_Interval = 60 * 1000000; /* how often
- to query the tokens for CRL objects, in order to discover new objects, if
- the cache does not contain any token CRLs . In microseconds */
-
-PRTime CRLCache_TokenRefetch_Interval = 600 * 1000000 ; /* how often
- to query the tokens for CRL objects, in order to discover new objects, if
- the cache already contains token CRLs In microseconds */
-
-PRTime CRLCache_ExistenceCheck_Interval = 60 * 1000000; /* how often to check
- if a token CRL object still exists. In microseconds */
-
-/* this function is called at NSS initialization time */
-SECStatus InitCRLCache(void)
-{
- if (PR_FALSE == crlcache_initialized)
- {
- PORT_Assert(NULL == crlcache.lock);
- PORT_Assert(NULL == crlcache.issuers);
- PORT_Assert(NULL == namedCRLCache.lock);
- PORT_Assert(NULL == namedCRLCache.entries);
- if (crlcache.lock || crlcache.issuers || namedCRLCache.lock ||
- namedCRLCache.entries)
- {
- /* CRL cache already partially initialized */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-#ifdef GLOBAL_RWLOCK
- crlcache.lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL);
-#else
- crlcache.lock = PR_NewLock();
-#endif
- namedCRLCache.lock = PR_NewLock();
- crlcache.issuers = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
- PL_CompareValues, NULL, NULL);
- namedCRLCache.entries = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
- PL_CompareValues, NULL, NULL);
- if (!crlcache.lock || !namedCRLCache.lock || !crlcache.issuers ||
- !namedCRLCache.entries)
- {
- if (crlcache.lock)
- {
-#ifdef GLOBAL_RWLOCK
- NSSRWLock_Destroy(crlcache.lock);
-#else
- PR_DestroyLock(crlcache.lock);
-#endif
- crlcache.lock = NULL;
- }
- if (namedCRLCache.lock)
- {
- PR_DestroyLock(namedCRLCache.lock);
- namedCRLCache.lock = NULL;
- }
- if (crlcache.issuers)
- {
- PL_HashTableDestroy(crlcache.issuers);
- crlcache.issuers = NULL;
- }
- if (namedCRLCache.entries)
- {
- PL_HashTableDestroy(namedCRLCache.entries);
- namedCRLCache.entries = NULL;
- }
-
- return SECFailure;
- }
- crlcache_initialized = PR_TRUE;
- return SECSuccess;
- }
- else
- {
- PORT_Assert(crlcache.lock);
- PORT_Assert(crlcache.issuers);
- if ( (NULL == crlcache.lock) || (NULL == crlcache.issuers) )
- {
- /* CRL cache not fully initialized */
- return SECFailure;
- }
- else
- {
- /* CRL cache already initialized */
- return SECSuccess;
- }
- }
-}
-
-/* destructor for CRL DPCache object */
-static SECStatus DPCache_Destroy(CRLDPCache* cache)
-{
- PRUint32 i = 0;
- PORT_Assert(cache);
- if (!cache)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (cache->lock)
- {
-#ifdef DPC_RWLOCK
- NSSRWLock_Destroy(cache->lock);
-#else
- PR_DestroyLock(cache->lock);
-#endif
- }
- else
- {
- PORT_Assert(0);
- return SECFailure;
- }
- /* destroy all our CRL objects */
- for (i=0;i<cache->ncrls;i++)
- {
- if (!cache->crls || !cache->crls[i] ||
- SECSuccess != CachedCrl_Destroy(cache->crls[i]))
- {
- return SECFailure;
- }
- }
- /* free the array of CRLs */
- if (cache->crls)
- {
- PORT_Free(cache->crls);
- }
- /* destroy the cert */
- if (cache->issuer)
- {
- CERT_DestroyCertificate(cache->issuer);
- }
- /* free the subject */
- if (cache->subject)
- {
- SECITEM_FreeItem(cache->subject, PR_TRUE);
- }
- /* free the distribution points */
- if (cache->distributionPoint)
- {
- SECITEM_FreeItem(cache->distributionPoint, PR_TRUE);
- }
- PORT_Free(cache);
- return SECSuccess;
-}
-
-/* destructor for CRL IssuerCache object */
-SECStatus IssuerCache_Destroy(CRLIssuerCache* cache)
-{
- PORT_Assert(cache);
- if (!cache)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-#ifdef XCRL
- if (cache->lock)
- {
- NSSRWLock_Destroy(cache->lock);
- }
- else
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (cache->issuer)
- {
- CERT_DestroyCertificate(cache->issuer);
- }
-#endif
- /* free the subject */
- if (cache->subject)
- {
- SECITEM_FreeItem(cache->subject, PR_TRUE);
- }
- if (SECSuccess != DPCache_Destroy(cache->dpp))
- {
- PORT_Assert(0);
- return SECFailure;
- }
- PORT_Free(cache);
- return SECSuccess;
-}
-
-/* create a named CRL entry object */
-static SECStatus NamedCRLCacheEntry_Create(NamedCRLCacheEntry** returned)
-{
- NamedCRLCacheEntry* entry = NULL;
- if (!returned)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- *returned = NULL;
- entry = (NamedCRLCacheEntry*) PORT_ZAlloc(sizeof(NamedCRLCacheEntry));
- if (!entry)
- {
- return SECFailure;
- }
- *returned = entry;
- return SECSuccess;
-}
-
-/* destroy a named CRL entry object */
-static SECStatus NamedCRLCacheEntry_Destroy(NamedCRLCacheEntry* entry)
-{
- if (!entry)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (entry->crl)
- {
- /* named CRL cache owns DER memory */
- SECITEM_ZfreeItem(entry->crl, PR_TRUE);
- }
- if (entry->canonicalizedName)
- {
- SECITEM_FreeItem(entry->canonicalizedName, PR_TRUE);
- }
- PORT_Free(entry);
- return SECSuccess;
-}
-
-/* callback function used in hash table destructor */
-static PRIntn PR_CALLBACK FreeIssuer(PLHashEntry *he, PRIntn i, void *arg)
-{
- CRLIssuerCache* issuer = NULL;
- SECStatus* rv = (SECStatus*) arg;
-
- PORT_Assert(he);
- if (!he)
- {
- return HT_ENUMERATE_NEXT;
- }
- issuer = (CRLIssuerCache*) he->value;
- PORT_Assert(issuer);
- if (issuer)
- {
- if (SECSuccess != IssuerCache_Destroy(issuer))
- {
- PORT_Assert(rv);
- if (rv)
- {
- *rv = SECFailure;
- }
- return HT_ENUMERATE_NEXT;
- }
- }
- return HT_ENUMERATE_NEXT;
-}
-
-/* callback function used in hash table destructor */
-static PRIntn PR_CALLBACK FreeNamedEntries(PLHashEntry *he, PRIntn i, void *arg)
-{
- NamedCRLCacheEntry* entry = NULL;
- SECStatus* rv = (SECStatus*) arg;
-
- PORT_Assert(he);
- if (!he)
- {
- return HT_ENUMERATE_NEXT;
- }
- entry = (NamedCRLCacheEntry*) he->value;
- PORT_Assert(entry);
- if (entry)
- {
- if (SECSuccess != NamedCRLCacheEntry_Destroy(entry))
- {
- PORT_Assert(rv);
- if (rv)
- {
- *rv = SECFailure;
- }
- return HT_ENUMERATE_NEXT;
- }
- }
- return HT_ENUMERATE_NEXT;
-}
-
-/* needs to be called at NSS shutdown time
- This will destroy the global CRL cache, including
- - the hash table of issuer cache objects
- - the issuer cache objects
- - DPCache objects in issuer cache objects */
-SECStatus ShutdownCRLCache(void)
-{
- SECStatus rv = SECSuccess;
- if (PR_FALSE == crlcache_initialized &&
- !crlcache.lock && !crlcache.issuers)
- {
- /* CRL cache has already been shut down */
- return SECSuccess;
- }
- if (PR_TRUE == crlcache_initialized &&
- (!crlcache.lock || !crlcache.issuers || !namedCRLCache.lock ||
- !namedCRLCache.entries))
- {
- /* CRL cache has partially been shut down */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* empty the CRL cache */
- /* free the issuers */
- PL_HashTableEnumerateEntries(crlcache.issuers, &FreeIssuer, &rv);
- /* free the hash table of issuers */
- PL_HashTableDestroy(crlcache.issuers);
- crlcache.issuers = NULL;
- /* free the global lock */
-#ifdef GLOBAL_RWLOCK
- NSSRWLock_Destroy(crlcache.lock);
-#else
- PR_DestroyLock(crlcache.lock);
-#endif
- crlcache.lock = NULL;
-
- /* empty the named CRL cache. This must be done after freeing the CRL
- * cache, since some CRLs in this cache are in the memory for the other */
- /* free the entries */
- PL_HashTableEnumerateEntries(namedCRLCache.entries, &FreeNamedEntries, &rv);
- /* free the hash table of issuers */
- PL_HashTableDestroy(namedCRLCache.entries);
- namedCRLCache.entries = NULL;
- /* free the global lock */
- PR_DestroyLock(namedCRLCache.lock);
- namedCRLCache.lock = NULL;
-
- crlcache_initialized = PR_FALSE;
- return rv;
-}
-
-/* add a new CRL object to the dynamic array of CRLs of the DPCache, and
- returns the cached CRL object . Needs write access to DPCache. */
-static SECStatus DPCache_AddCRL(CRLDPCache* cache, CachedCrl* newcrl,
- PRBool* added)
-{
- CachedCrl** newcrls = NULL;
- PRUint32 i = 0;
- PORT_Assert(cache);
- PORT_Assert(newcrl);
- PORT_Assert(added);
- if (!cache || !newcrl || !added)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- *added = PR_FALSE;
- /* before adding a new CRL, check if it is a duplicate */
- for (i=0;i<cache->ncrls;i++)
- {
- CachedCrl* existing = NULL;
- SECStatus rv = SECSuccess;
- PRBool dupe = PR_FALSE, updated = PR_FALSE;
- if (!cache->crls)
- {
- PORT_Assert(0);
- return SECFailure;
- }
- existing = cache->crls[i];
- if (!existing)
- {
- PORT_Assert(0);
- return SECFailure;
- }
- rv = CachedCrl_Compare(existing, newcrl, &dupe, &updated);
- if (SECSuccess != rv)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (PR_TRUE == dupe)
- {
- /* dupe */
- PORT_SetError(SEC_ERROR_CRL_ALREADY_EXISTS);
- return SECSuccess;
- }
- if (PR_TRUE == updated)
- {
- /* this token CRL is in the same slot and has the same object ID,
- but different content. We need to remove the old object */
- if (SECSuccess != DPCache_RemoveCRL(cache, i))
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return PR_FALSE;
- }
- }
- }
-
- newcrls = (CachedCrl**)PORT_Realloc(cache->crls,
- (cache->ncrls+1)*sizeof(CachedCrl*));
- if (!newcrls)
- {
- return SECFailure;
- }
- cache->crls = newcrls;
- cache->ncrls++;
- cache->crls[cache->ncrls-1] = newcrl;
- *added = PR_TRUE;
- return SECSuccess;
-}
-
-/* remove CRL at offset specified */
-static SECStatus DPCache_RemoveCRL(CRLDPCache* cache, PRUint32 offset)
-{
- CachedCrl* acrl = NULL;
- PORT_Assert(cache);
- if (!cache || (!cache->crls) || (!(offset<cache->ncrls)) )
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- acrl = cache->crls[offset];
- PORT_Assert(acrl);
- if (!acrl)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- cache->crls[offset] = cache->crls[cache->ncrls-1];
- cache->crls[cache->ncrls-1] = NULL;
- cache->ncrls--;
- if (cache->selected == acrl) {
- cache->selected = NULL;
- }
- if (SECSuccess != CachedCrl_Destroy(acrl))
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/* check whether a CRL object stored in a PKCS#11 token still exists in
- that token . This has to be efficient (the entire CRL value cannot be
- transferred accross the token boundaries), so this is accomplished by
- simply fetching the subject attribute and making sure it hasn't changed .
- Note that technically, the CRL object could have been replaced with a new
- PKCS#11 object of the same ID and subject (which actually happens in
- softoken), but this function has no way of knowing that the object
- value changed, since CKA_VALUE isn't checked. */
-static PRBool TokenCRLStillExists(CERTSignedCrl* crl)
-{
- NSSItem newsubject;
- SECItem subject;
- CK_ULONG crl_class;
- PRStatus status;
- PK11SlotInfo* slot = NULL;
- nssCryptokiObject instance;
- NSSArena* arena;
- PRBool xstatus = PR_TRUE;
- SECItem* oldSubject = NULL;
-
- PORT_Assert(crl);
- if (!crl)
- {
- return PR_FALSE;
- }
- slot = crl->slot;
- PORT_Assert(crl->slot);
- if (!slot)
- {
- return PR_FALSE;
- }
- oldSubject = &crl->crl.derName;
- PORT_Assert(oldSubject);
- if (!oldSubject)
- {
- return PR_FALSE;
- }
-
- /* query subject and type attributes in order to determine if the
- object has been deleted */
-
- /* first, make an nssCryptokiObject */
- instance.handle = crl->pkcs11ID;
- PORT_Assert(instance.handle);
- if (!instance.handle)
- {
- return PR_FALSE;
- }
- instance.token = PK11Slot_GetNSSToken(slot);
- PORT_Assert(instance.token);
- if (!instance.token)
- {
- return PR_FALSE;
- }
- instance.isTokenObject = PR_TRUE;
- instance.label = NULL;
-
- arena = NSSArena_Create();
- PORT_Assert(arena);
- if (!arena)
- {
- return PR_FALSE;
- }
-
- status = nssCryptokiCRL_GetAttributes(&instance,
- NULL, /* XXX sessionOpt */
- arena,
- NULL,
- &newsubject, /* subject */
- &crl_class, /* class */
- NULL,
- NULL);
- if (PR_SUCCESS == status)
- {
- subject.data = newsubject.data;
- subject.len = newsubject.size;
- if (SECITEM_CompareItem(oldSubject, &subject) != SECEqual)
- {
- xstatus = PR_FALSE;
- }
- if (CKO_NETSCAPE_CRL != crl_class)
- {
- xstatus = PR_FALSE;
- }
- }
- else
- {
- xstatus = PR_FALSE;
- }
- NSSArena_Destroy(arena);
- return xstatus;
-}
-
-/* verify the signature of a CRL against its issuer at a given date */
-static SECStatus CERT_VerifyCRL(
- CERTSignedCrl* crlobject,
- CERTCertificate* issuer,
- PRTime vfdate,
- void* wincx)
-{
- return CERT_VerifySignedData(&crlobject->signatureWrap,
- issuer, vfdate, wincx);
-}
-
-/* verify a CRL and update cache state */
-static SECStatus CachedCrl_Verify(CRLDPCache* cache, CachedCrl* crlobject,
- PRTime vfdate, void* wincx)
-{
- /* Check if it is an invalid CRL
- if we got a bad CRL, we want to cache it in order to avoid
- subsequent fetches of this same identical bad CRL. We set
- the cache to the invalid state to ensure that all certs on this
- DP are considered to have unknown status from now on. The cache
- object will remain in this state until the bad CRL object
- is removed from the token it was fetched from. If the cause
- of the failure is that we didn't have the issuer cert to
- verify the signature, this state can be cleared when
- the issuer certificate becomes available if that causes the
- signature to verify */
-
- if (!cache || !crlobject)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (PR_TRUE == GetOpaqueCRLFields(crlobject->crl)->decodingError)
- {
- crlobject->sigChecked = PR_TRUE; /* we can never verify a CRL
- with bogus DER. Mark it checked so we won't try again */
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECSuccess;
- }
- else
- {
- SECStatus signstatus = SECFailure;
- if (cache->issuer)
- {
- signstatus = CERT_VerifyCRL(crlobject->crl, cache->issuer, vfdate,
- wincx);
- }
- if (SECSuccess != signstatus)
- {
- if (!cache->issuer)
- {
- /* we tried to verify without an issuer cert . This is
- because this CRL came through a call to SEC_FindCrlByName.
- So, we don't cache this verification failure. We'll try
- to verify the CRL again when a certificate from that issuer
- becomes available */
- } else
- {
- crlobject->sigChecked = PR_TRUE;
- }
- PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
- return SECSuccess;
- } else
- {
- crlobject->sigChecked = PR_TRUE;
- crlobject->sigValid = PR_TRUE;
- }
- }
-
- return SECSuccess;
-}
-
-/* fetch the CRLs for this DP from the PKCS#11 tokens */
-static SECStatus DPCache_FetchFromTokens(CRLDPCache* cache, PRTime vfdate,
- void* wincx)
-{
- SECStatus rv = SECSuccess;
- CERTCrlHeadNode head;
- if (!cache)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* first, initialize list */
- memset(&head, 0, sizeof(head));
- head.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- rv = pk11_RetrieveCrls(&head, cache->subject, wincx);
-
- /* if this function fails, something very wrong happened, such as an out
- of memory error during CRL decoding. We don't want to proceed and must
- mark the cache object invalid */
- if (SECFailure == rv)
- {
- /* fetch failed, add error bit */
- cache->invalid |= CRL_CACHE_LAST_FETCH_FAILED;
- } else
- {
- /* fetch was successful, clear this error bit */
- cache->invalid &= (~CRL_CACHE_LAST_FETCH_FAILED);
- }
-
- /* add any CRLs found to our array */
- if (SECSuccess == rv)
- {
- CERTCrlNode* crlNode = NULL;
-
- for (crlNode = head.first; crlNode ; crlNode = crlNode->next)
- {
- CachedCrl* returned = NULL;
- CERTSignedCrl* crlobject = crlNode->crl;
- if (!crlobject)
- {
- PORT_Assert(0);
- continue;
- }
- rv = CachedCrl_Create(&returned, crlobject, CRL_OriginToken);
- if (SECSuccess == rv)
- {
- PRBool added = PR_FALSE;
- rv = DPCache_AddCRL(cache, returned, &added);
- if (PR_TRUE != added)
- {
- rv = CachedCrl_Destroy(returned);
- returned = NULL;
- }
- else if (vfdate)
- {
- rv = CachedCrl_Verify(cache, returned, vfdate, wincx);
- }
- }
- else
- {
- /* not enough memory to add the CRL to the cache. mark it
- invalid so we will try again . */
- cache->invalid |= CRL_CACHE_LAST_FETCH_FAILED;
- }
- if (SECFailure == rv)
- {
- break;
- }
- }
- }
-
- if (head.arena)
- {
- CERTCrlNode* crlNode = NULL;
- /* clean up the CRL list in case we got a partial one
- during a failed fetch */
- for (crlNode = head.first; crlNode ; crlNode = crlNode->next)
- {
- if (crlNode->crl)
- {
- SEC_DestroyCrl(crlNode->crl); /* free the CRL. Either it got
- added to the cache and the refcount got bumped, or not, and
- thus we need to free its RAM */
- }
- }
- PORT_FreeArena(head.arena, PR_FALSE); /* destroy CRL list */
- }
-
- return rv;
-}
-
-static SECStatus CachedCrl_GetEntry(CachedCrl* crl, SECItem* sn,
- CERTCrlEntry** returned)
-{
- CERTCrlEntry* acrlEntry;
-
- PORT_Assert(crl);
- PORT_Assert(crl->entries);
- PORT_Assert(sn);
- PORT_Assert(returned);
- if (!crl || !sn || !returned || !crl->entries)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- acrlEntry = PL_HashTableLookup(crl->entries, (void*)sn);
- if (acrlEntry)
- {
- *returned = acrlEntry;
- }
- else
- {
- *returned = NULL;
- }
- return SECSuccess;
-}
-
-/* check if a particular SN is in the CRL cache and return its entry */
-dpcacheStatus DPCache_Lookup(CRLDPCache* cache, SECItem* sn,
- CERTCrlEntry** returned)
-{
- SECStatus rv;
- if (!cache || !sn || !returned)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- /* no cache or SN to look up, or no way to return entry */
- return dpcacheCallerError;
- }
- *returned = NULL;
- if (0 != cache->invalid)
- {
- /* the cache contains a bad CRL, or there was a CRL fetching error. */
- PORT_SetError(SEC_ERROR_CRL_INVALID);
- return dpcacheInvalidCacheError;
- }
- if (!cache->selected)
- {
- /* no CRL means no entry to return. This is OK, except for
- * NIST policy */
- return dpcacheEmpty;
- }
- rv = CachedCrl_GetEntry(cache->selected, sn, returned);
- if (SECSuccess != rv)
- {
- return dpcacheLookupError;
- }
- else
- {
- if (*returned)
- {
- return dpcacheFoundEntry;
- }
- else
- {
- return dpcacheNoEntry;
- }
- }
-}
-
-#if defined(DPC_RWLOCK)
-
-#define DPCache_LockWrite() \
-{ \
- if (readlocked) \
- { \
- NSSRWLock_UnlockRead(cache->lock); \
- } \
- NSSRWLock_LockWrite(cache->lock); \
-}
-
-#define DPCache_UnlockWrite() \
-{ \
- if (readlocked) \
- { \
- NSSRWLock_LockRead(cache->lock); \
- } \
- NSSRWLock_UnlockWrite(cache->lock); \
-}
-
-#else
-
-/* with a global lock, we are always locked for read before we need write
- access, so do nothing */
-
-#define DPCache_LockWrite() \
-{ \
-}
-
-#define DPCache_UnlockWrite() \
-{ \
-}
-
-#endif
-
-/* update the content of the CRL cache, including fetching of CRLs, and
- reprocessing with specified issuer and date . We are always holding
- either the read or write lock on DPCache upon entry. */
-static SECStatus DPCache_GetUpToDate(CRLDPCache* cache, CERTCertificate*
- issuer, PRBool readlocked, PRTime vfdate,
- void* wincx)
-{
- /* Update the CRLDPCache now. We don't cache token CRL lookup misses
- yet, as we have no way of getting notified of new PKCS#11 object
- creation that happens in a token */
- SECStatus rv = SECSuccess;
- PRUint32 i = 0;
- PRBool forcedrefresh = PR_FALSE;
- PRBool dirty = PR_FALSE; /* whether something was changed in the
- cache state during this update cycle */
- PRBool hastokenCRLs = PR_FALSE;
- PRTime now = 0;
- PRTime lastfetch = 0;
- PRBool mustunlock = PR_FALSE;
-
- if (!cache)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- /* first, make sure we have obtained all the CRLs we need.
- We do an expensive token fetch in the following cases :
- 1) cache is empty because no fetch was ever performed yet
- 2) cache is explicitly set to refresh state
- 3) cache is in invalid state because last fetch failed
- 4) cache contains no token CRLs, and it's been more than one minute
- since the last fetch
- 5) cache contains token CRLs, and it's been more than 10 minutes since
- the last fetch
- */
- forcedrefresh = cache->refresh;
- lastfetch = cache->lastfetch;
- if (PR_TRUE != forcedrefresh &&
- (!(cache->invalid & CRL_CACHE_LAST_FETCH_FAILED)))
- {
- now = PR_Now();
- hastokenCRLs = DPCache_HasTokenCRLs(cache);
- }
- if ( (0 == lastfetch) ||
-
- (PR_TRUE == forcedrefresh) ||
-
- (cache->invalid & CRL_CACHE_LAST_FETCH_FAILED) ||
-
- ( (PR_FALSE == hastokenCRLs) &&
- ( (now - cache->lastfetch > CRLCache_Empty_TokenFetch_Interval) ||
- (now < cache->lastfetch)) ) ||
-
- ( (PR_TRUE == hastokenCRLs) &&
- ((now - cache->lastfetch > CRLCache_TokenRefetch_Interval) ||
- (now < cache->lastfetch)) ) )
- {
- /* the cache needs to be refreshed, and/or we had zero CRL for this
- DP. Try to get one from PKCS#11 tokens */
- DPCache_LockWrite();
- /* check if another thread updated before us, and skip update if so */
- if (lastfetch == cache->lastfetch)
- {
- /* we are the first */
- rv = DPCache_FetchFromTokens(cache, vfdate, wincx);
- if (PR_TRUE == cache->refresh)
- {
- cache->refresh = PR_FALSE; /* clear refresh state */
- }
- dirty = PR_TRUE;
- cache->lastfetch = PR_Now();
- }
- DPCache_UnlockWrite();
- }
-
- /* now, make sure we have no extraneous CRLs (deleted token objects)
- we'll do this inexpensive existence check either
- 1) if there was a token object fetch
- 2) every minute */
- if (( PR_TRUE != dirty) && (!now) )
- {
- now = PR_Now();
- }
- if ( (PR_TRUE == dirty) ||
- ( (now - cache->lastcheck > CRLCache_ExistenceCheck_Interval) ||
- (now < cache->lastcheck)) )
- {
- PRTime lastcheck = cache->lastcheck;
- mustunlock = PR_FALSE;
- /* check if all CRLs still exist */
- for (i = 0; (i < cache->ncrls) ; i++)
- {
- CachedCrl* savcrl = cache->crls[i];
- if ( (!savcrl) || (savcrl && CRL_OriginToken != savcrl->origin))
- {
- /* we only want to check token CRLs */
- continue;
- }
- if ((PR_TRUE != TokenCRLStillExists(savcrl->crl)))
- {
-
- /* this CRL is gone */
- if (PR_TRUE != mustunlock)
- {
- DPCache_LockWrite();
- mustunlock = PR_TRUE;
- }
- /* first, we need to check if another thread did an update
- before we did */
- if (lastcheck == cache->lastcheck)
- {
- /* the CRL is gone. And we are the one to do the update */
- DPCache_RemoveCRL(cache, i);
- dirty = PR_TRUE;
- }
- /* stay locked here intentionally so we do all the other
- updates in this thread for the remaining CRLs */
- }
- }
- if (PR_TRUE == mustunlock)
- {
- cache->lastcheck = PR_Now();
- DPCache_UnlockWrite();
- mustunlock = PR_FALSE;
- }
- }
-
- /* add issuer certificate if it was previously unavailable */
- if (issuer && (NULL == cache->issuer) &&
- (SECSuccess == CERT_CheckCertUsage(issuer, KU_CRL_SIGN)))
- {
- /* if we didn't have a valid issuer cert yet, but we do now. add it */
- DPCache_LockWrite();
- if (!cache->issuer)
- {
- dirty = PR_TRUE;
- cache->issuer = CERT_DupCertificate(issuer);
- }
- DPCache_UnlockWrite();
- }
-
- /* verify CRLs that couldn't be checked when inserted into the cache
- because the issuer cert or a verification date was unavailable.
- These are CRLs that were inserted into the cache through
- SEC_FindCrlByName, or through manual insertion, rather than through a
- certificate verification (CERT_CheckCRL) */
-
- if (cache->issuer && vfdate )
- {
- mustunlock = PR_FALSE;
- /* re-process all unverified CRLs */
- for (i = 0; i < cache->ncrls ; i++)
- {
- CachedCrl* savcrl = cache->crls[i];
- if (!savcrl)
- {
- continue;
- }
- if (PR_TRUE != savcrl->sigChecked)
- {
- if (!mustunlock)
- {
- DPCache_LockWrite();
- mustunlock = PR_TRUE;
- }
- /* first, we need to check if another thread updated
- it before we did, and abort if it has been modified since
- we acquired the lock. Make sure first that the CRL is still
- in the array at the same position */
- if ( (i<cache->ncrls) && (savcrl == cache->crls[i]) &&
- (PR_TRUE != savcrl->sigChecked) )
- {
- /* the CRL is still there, unverified. Do it */
- CachedCrl_Verify(cache, savcrl, vfdate, wincx);
- dirty = PR_TRUE;
- }
- /* stay locked here intentionally so we do all the other
- updates in this thread for the remaining CRLs */
- }
- if (mustunlock && !dirty)
- {
- DPCache_UnlockWrite();
- mustunlock = PR_FALSE;
- }
- }
- }
-
- if (dirty || cache->mustchoose)
- {
- /* changes to the content of the CRL cache necessitate examining all
- CRLs for selection of the most appropriate one to cache */
- if (!mustunlock)
- {
- DPCache_LockWrite();
- mustunlock = PR_TRUE;
- }
- DPCache_SelectCRL(cache);
- cache->mustchoose = PR_FALSE;
- }
- if (mustunlock)
- DPCache_UnlockWrite();
-
- return rv;
-}
-
-/* callback for qsort to sort by thisUpdate */
-static int SortCRLsByThisUpdate(const void* arg1, const void* arg2)
-{
- PRTime timea, timeb;
- SECStatus rv = SECSuccess;
- CachedCrl* a, *b;
-
- a = *(CachedCrl**) arg1;
- b = *(CachedCrl**) arg2;
-
- if (!a || !b)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- }
-
- if (SECSuccess == rv)
- {
- rv = DER_DecodeTimeChoice(&timea, &a->crl->crl.lastUpdate);
- }
- if (SECSuccess == rv)
- {
- rv = DER_DecodeTimeChoice(&timeb, &b->crl->crl.lastUpdate);
- }
- if (SECSuccess == rv)
- {
- if (timea > timeb)
- {
- return 1; /* a is better than b */
- }
- if (timea < timeb )
- {
- return -1; /* a is not as good as b */
- }
- }
-
- /* if they are equal, or if all else fails, use pointer differences */
- PORT_Assert(a != b); /* they should never be equal */
- return a>b?1:-1;
-}
-
-/* callback for qsort to sort a set of disparate CRLs, some of which are
- invalid DER or failed signature check.
-
- Validated CRLs are differentiated by thisUpdate .
- Validated CRLs are preferred over non-validated CRLs .
- Proper DER CRLs are preferred over non-DER data .
-*/
-static int SortImperfectCRLs(const void* arg1, const void* arg2)
-{
- CachedCrl* a, *b;
-
- a = *(CachedCrl**) arg1;
- b = *(CachedCrl**) arg2;
-
- if (!a || !b)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- PORT_Assert(0);
- }
- else
- {
- PRBool aDecoded = PR_FALSE, bDecoded = PR_FALSE;
- if ( (PR_TRUE == a->sigValid) && (PR_TRUE == b->sigValid) )
- {
- /* both CRLs have been validated, choose the latest one */
- return SortCRLsByThisUpdate(arg1, arg2);
- }
- if (PR_TRUE == a->sigValid)
- {
- return 1; /* a is greater than b */
- }
- if (PR_TRUE == b->sigValid)
- {
- return -1; /* a is not as good as b */
- }
- aDecoded = GetOpaqueCRLFields(a->crl)->decodingError;
- bDecoded = GetOpaqueCRLFields(b->crl)->decodingError;
- /* neither CRL had its signature check pass */
- if ( (PR_FALSE == aDecoded) && (PR_FALSE == bDecoded) )
- {
- /* both CRLs are proper DER, choose the latest one */
- return SortCRLsByThisUpdate(arg1, arg2);
- }
- if (PR_FALSE == aDecoded)
- {
- return 1; /* a is better than b */
- }
- if (PR_FALSE == bDecoded)
- {
- return -1; /* a is not as good as b */
- }
- /* both are invalid DER. sigh. */
- }
- /* if they are equal, or if all else fails, use pointer differences */
- PORT_Assert(a != b); /* they should never be equal */
- return a>b?1:-1;
-}
-
-
-/* Pick best CRL to use . needs write access */
-static SECStatus DPCache_SelectCRL(CRLDPCache* cache)
-{
- PRUint32 i;
- PRBool valid = PR_TRUE;
- CachedCrl* selected = NULL;
-
- PORT_Assert(cache);
- if (!cache)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* if any invalid CRL is present, then the CRL cache is
- considered invalid, for security reasons */
- for (i = 0 ; i<cache->ncrls; i++)
- {
- if (!cache->crls[i] || !cache->crls[i]->sigChecked ||
- !cache->crls[i]->sigValid)
- {
- valid = PR_FALSE;
- break;
- }
- }
- if (PR_TRUE == valid)
- {
- /* all CRLs are valid, clear this error */
- cache->invalid &= (~CRL_CACHE_INVALID_CRLS);
- } else
- {
- /* some CRLs are invalid, set this error */
- cache->invalid |= CRL_CACHE_INVALID_CRLS;
- }
-
- if (cache->invalid)
- {
- /* cache is in an invalid state, so reset it */
- if (cache->selected)
- {
- cache->selected = NULL;
- }
- /* also sort the CRLs imperfectly */
- qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*),
- SortImperfectCRLs);
- return SECSuccess;
- }
- /* all CRLs are good, sort them by thisUpdate */
- qsort(cache->crls, cache->ncrls, sizeof(CachedCrl*),
- SortCRLsByThisUpdate);
-
- if (cache->ncrls)
- {
- /* pick the newest CRL */
- selected = cache->crls[cache->ncrls-1];
-
- /* and populate the cache */
- if (SECSuccess != CachedCrl_Populate(selected))
- {
- return SECFailure;
- }
- }
-
- cache->selected = selected;
-
- return SECSuccess;
-}
-
-/* initialize a DPCache object */
-static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer,
- const SECItem* subject, SECItem* dp)
-{
- CRLDPCache* cache = NULL;
- PORT_Assert(returned);
- /* issuer and dp are allowed to be NULL */
- if (!returned || !subject)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- *returned = NULL;
- cache = PORT_ZAlloc(sizeof(CRLDPCache));
- if (!cache)
- {
- return SECFailure;
- }
-#ifdef DPC_RWLOCK
- cache->lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL);
-#else
- cache->lock = PR_NewLock();
-#endif
- if (!cache->lock)
- {
- PORT_Free(cache);
- return SECFailure;
- }
- if (issuer)
- {
- cache->issuer = CERT_DupCertificate(issuer);
- }
- cache->distributionPoint = SECITEM_DupItem(dp);
- cache->subject = SECITEM_DupItem(subject);
- cache->lastfetch = 0;
- cache->lastcheck = 0;
- *returned = cache;
- return SECSuccess;
-}
-
-/* create an issuer cache object (per CA subject ) */
-static SECStatus IssuerCache_Create(CRLIssuerCache** returned,
- CERTCertificate* issuer,
- const SECItem* subject, const SECItem* dp)
-{
- SECStatus rv = SECSuccess;
- CRLIssuerCache* cache = NULL;
- PORT_Assert(returned);
- PORT_Assert(subject);
- /* issuer and dp are allowed to be NULL */
- if (!returned || !subject)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- *returned = NULL;
- cache = (CRLIssuerCache*) PORT_ZAlloc(sizeof(CRLIssuerCache));
- if (!cache)
- {
- return SECFailure;
- }
- cache->subject = SECITEM_DupItem(subject);
-#ifdef XCRL
- cache->lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL);
- if (!cache->lock)
- {
- rv = SECFailure;
- }
- if (SECSuccess == rv && issuer)
- {
- cache->issuer = CERT_DupCertificate(issuer);
- if (!cache->issuer)
- {
- rv = SECFailure;
- }
- }
-#endif
- if (SECSuccess != rv)
- {
- PORT_Assert(SECSuccess == IssuerCache_Destroy(cache));
- return SECFailure;
- }
- *returned = cache;
- return SECSuccess;
-}
-
-/* add a DPCache to the issuer cache */
-static SECStatus IssuerCache_AddDP(CRLIssuerCache* cache,
- CERTCertificate* issuer,
- const SECItem* subject,
- const SECItem* dp,
- CRLDPCache** newdpc)
-{
- /* now create the required DP cache object */
- if (!cache || !subject || !newdpc)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (!dp)
- {
- /* default distribution point */
- SECStatus rv = DPCache_Create(&cache->dpp, issuer, subject, NULL);
- if (SECSuccess == rv)
- {
- *newdpc = cache->dpp;
- return SECSuccess;
- }
- }
- else
- {
- /* we should never hit this until we support multiple DPs */
- PORT_Assert(dp);
- /* XCRL allocate a new distribution point cache object, initialize it,
- and add it to the hash table of DPs */
- }
- return SECFailure;
-}
-
-/* add an IssuerCache to the global hash table of issuers */
-static SECStatus CRLCache_AddIssuer(CRLIssuerCache* issuer)
-{
- PORT_Assert(issuer);
- PORT_Assert(crlcache.issuers);
- if (!issuer || !crlcache.issuers)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (NULL == PL_HashTableAdd(crlcache.issuers, (void*) issuer->subject,
- (void*) issuer))
- {
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/* retrieve the issuer cache object for a given issuer subject */
-static SECStatus CRLCache_GetIssuerCache(CRLCache* cache,
- const SECItem* subject,
- CRLIssuerCache** returned)
-{
- /* we need to look up the issuer in the hash table */
- SECStatus rv = SECSuccess;
- PORT_Assert(cache);
- PORT_Assert(subject);
- PORT_Assert(returned);
- PORT_Assert(crlcache.issuers);
- if (!cache || !subject || !returned || !crlcache.issuers)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- }
-
- if (SECSuccess == rv)
- {
- *returned = (CRLIssuerCache*) PL_HashTableLookup(crlcache.issuers,
- (void*) subject);
- }
-
- return rv;
-}
-
-/* retrieve the full CRL object that best matches the content of a DPCache */
-static CERTSignedCrl* GetBestCRL(CRLDPCache* cache, PRBool entries)
-{
- CachedCrl* acrl = NULL;
-
- PORT_Assert(cache);
- if (!cache)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
-
- if (0 == cache->ncrls)
- {
- /* empty cache*/
- PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
- return NULL;
- }
-
- /* if we have a valid full CRL selected, return it */
- if (cache->selected)
- {
- return SEC_DupCrl(cache->selected->crl);
- }
-
- /* otherwise, use latest valid DER CRL */
- acrl = cache->crls[cache->ncrls-1];
-
- if (acrl && (PR_FALSE == GetOpaqueCRLFields(acrl->crl)->decodingError) )
- {
- SECStatus rv = SECSuccess;
- if (PR_TRUE == entries)
- {
- rv = CERT_CompleteCRLDecodeEntries(acrl->crl);
- }
- if (SECSuccess == rv)
- {
- return SEC_DupCrl(acrl->crl);
- }
- }
-
- PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
- return NULL;
-}
-
-/* get a particular DPCache object from an IssuerCache */
-static CRLDPCache* IssuerCache_GetDPCache(CRLIssuerCache* cache, const SECItem* dp)
-{
- CRLDPCache* dpp = NULL;
- PORT_Assert(cache);
- /* XCRL for now we only support the "default" DP, ie. the
- full CRL. So we can return the global one without locking. In
- the future we will have a lock */
- PORT_Assert(NULL == dp);
- if (!cache || dp)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
-#ifdef XCRL
- NSSRWLock_LockRead(cache->lock);
-#endif
- dpp = cache->dpp;
-#ifdef XCRL
- NSSRWLock_UnlockRead(cache->lock);
-#endif
- return dpp;
-}
-
-/* get a DPCache object for the given issuer subject and dp
- Automatically creates the cache object if it doesn't exist yet.
- */
-SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject,
- const SECItem* dp, PRTime t, void* wincx,
- CRLDPCache** dpcache, PRBool* writeLocked)
-{
- SECStatus rv = SECSuccess;
- CRLIssuerCache* issuercache = NULL;
-#ifdef GLOBAL_RWLOCK
- PRBool globalwrite = PR_FALSE;
-#endif
- PORT_Assert(crlcache.lock);
- if (!crlcache.lock)
- {
- /* CRL cache is not initialized */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-#ifdef GLOBAL_RWLOCK
- NSSRWLock_LockRead(crlcache.lock);
-#else
- PR_Lock(crlcache.lock);
-#endif
- rv = CRLCache_GetIssuerCache(&crlcache, subject, &issuercache);
- if (SECSuccess != rv)
- {
-#ifdef GLOBAL_RWLOCK
- NSSRWLock_UnlockRead(crlcache.lock);
-#else
- PR_Unlock(crlcache.lock);
-#endif
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (!issuercache)
- {
- /* there is no cache for this issuer yet. This means this is the
- first time we look up a cert from that issuer, and we need to
- create the cache. */
-
- rv = IssuerCache_Create(&issuercache, issuer, subject, dp);
- if (SECSuccess == rv && !issuercache)
- {
- PORT_Assert(issuercache);
- rv = SECFailure;
- }
-
- if (SECSuccess == rv)
- {
- /* This is the first time we look up a cert of this issuer.
- Create the DPCache for this DP . */
- rv = IssuerCache_AddDP(issuercache, issuer, subject, dp, dpcache);
- }
-
- if (SECSuccess == rv)
- {
- /* lock the DPCache for write to ensure the update happens in this
- thread */
- *writeLocked = PR_TRUE;
-#ifdef DPC_RWLOCK
- NSSRWLock_LockWrite((*dpcache)->lock);
-#else
- PR_Lock((*dpcache)->lock);
-#endif
- }
-
- if (SECSuccess == rv)
- {
- /* now add the new issuer cache to the global hash table of
- issuers */
-#ifdef GLOBAL_RWLOCK
- CRLIssuerCache* existing = NULL;
- NSSRWLock_UnlockRead(crlcache.lock);
- /* when using a r/w lock for the global cache, check if the issuer
- already exists before adding to the hash table */
- NSSRWLock_LockWrite(crlcache.lock);
- globalwrite = PR_TRUE;
- rv = CRLCache_GetIssuerCache(&crlcache, subject, &existing);
- if (!existing)
- {
-#endif
- rv = CRLCache_AddIssuer(issuercache);
- if (SECSuccess != rv)
- {
- /* failure */
- rv = SECFailure;
- }
-#ifdef GLOBAL_RWLOCK
- }
- else
- {
- /* somebody else updated before we did */
- IssuerCache_Destroy(issuercache); /* destroy the new object */
- issuercache = existing; /* use the existing one */
- *dpcache = IssuerCache_GetDPCache(issuercache, dp);
- }
-#endif
- }
-
- /* now unlock the global cache. We only want to lock the issuer hash
- table addition. Holding it longer would hurt scalability */
-#ifdef GLOBAL_RWLOCK
- if (PR_TRUE == globalwrite)
- {
- NSSRWLock_UnlockWrite(crlcache.lock);
- globalwrite = PR_FALSE;
- }
- else
- {
- NSSRWLock_UnlockRead(crlcache.lock);
- }
-#else
- PR_Unlock(crlcache.lock);
-#endif
-
- /* if there was a failure adding an issuer cache object, destroy it */
- if (SECSuccess != rv && issuercache)
- {
- if (PR_TRUE == *writeLocked)
- {
-#ifdef DPC_RWLOCK
- NSSRWLock_UnlockWrite((*dpcache)->lock);
-#else
- PR_Unlock((*dpcache)->lock);
-#endif
- }
- IssuerCache_Destroy(issuercache);
- issuercache = NULL;
- }
-
- if (SECSuccess != rv)
- {
- return SECFailure;
- }
- } else
- {
-#ifdef GLOBAL_RWLOCK
- NSSRWLock_UnlockRead(crlcache.lock);
-#else
- PR_Unlock(crlcache.lock);
-#endif
- *dpcache = IssuerCache_GetDPCache(issuercache, dp);
- }
- /* we now have a DPCache that we can use for lookups */
- /* lock it for read, unless we already locked for write */
- if (PR_FALSE == *writeLocked)
- {
-#ifdef DPC_RWLOCK
- NSSRWLock_LockRead((*dpcache)->lock);
-#else
- PR_Lock((*dpcache)->lock);
-#endif
- }
-
- if (SECSuccess == rv)
- {
- /* currently there is always one and only one DPCache per issuer */
- PORT_Assert(*dpcache);
- if (*dpcache)
- {
- /* make sure the DP cache is up to date before using it */
- rv = DPCache_GetUpToDate(*dpcache, issuer, PR_FALSE == *writeLocked,
- t, wincx);
- }
- else
- {
- rv = SECFailure;
- }
- }
- return rv;
-}
-
-/* unlock access to the DPCache */
-void ReleaseDPCache(CRLDPCache* dpcache, PRBool writeLocked)
-{
- if (!dpcache)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return;
- }
-#ifdef DPC_RWLOCK
- if (PR_TRUE == writeLocked)
- {
- NSSRWLock_UnlockWrite(dpcache->lock);
- }
- else
- {
- NSSRWLock_UnlockRead(dpcache->lock);
- }
-#else
- PR_Unlock(dpcache->lock);
-#endif
-}
-
-SECStatus
-cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
- const SECItem* dp, PRTime t, void *wincx,
- CERTRevocationStatus *revStatus,
- CERTCRLEntryReasonCode *revReason)
-{
- PRBool lockedwrite = PR_FALSE;
- SECStatus rv = SECSuccess;
- CRLDPCache* dpcache = NULL;
- CERTRevocationStatus status = certRevocationStatusRevoked;
- CERTCRLEntryReasonCode reason = crlEntryReasonUnspecified;
- CERTCrlEntry* entry = NULL;
- dpcacheStatus ds;
-
- if (!cert || !issuer)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- if (revStatus)
- {
- *revStatus = status;
- }
- if (revReason)
- {
- *revReason = reason;
- }
-
- if (t && SECSuccess != CERT_CheckCertValidTimes(issuer, t, PR_FALSE))
- {
- /* we won't be able to check the CRL's signature if the issuer cert
- is expired as of the time we are verifying. This may cause a valid
- CRL to be cached as bad. short-circuit to avoid this case. */
- PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE);
- return SECFailure;
- }
-
- rv = AcquireDPCache(issuer, &issuer->derSubject, dp, t, wincx, &dpcache,
- &lockedwrite);
- PORT_Assert(SECSuccess == rv);
- if (SECSuccess != rv)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* now look up the certificate SN in the DP cache's CRL */
- ds = DPCache_Lookup(dpcache, &cert->serialNumber, &entry);
- switch (ds)
- {
- case dpcacheFoundEntry:
- PORT_Assert(entry);
- /* check the time if we have one */
- if (entry->revocationDate.data && entry->revocationDate.len)
- {
- PRTime revocationDate = 0;
- if (SECSuccess == DER_DecodeTimeChoice(&revocationDate,
- &entry->revocationDate))
- {
- /* we got a good revocation date, only consider the
- certificate revoked if the time we are inquiring about
- is past the revocation date */
- if (t>=revocationDate)
- {
- rv = SECFailure;
- }
- else
- {
- status = certRevocationStatusValid;
- }
- }
- else
- {
- /* invalid revocation date, consider the certificate
- permanently revoked */
- rv = SECFailure;
- }
- }
- else
- {
- /* no revocation date, certificate is permanently revoked */
- rv = SECFailure;
- }
- if (SECFailure == rv)
- {
- SECStatus rv2 = CERT_FindCRLEntryReasonExten(entry, &reason);
- PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
- }
- break;
-
- case dpcacheEmpty:
- /* useful for NIST policy */
- status = certRevocationStatusUnknown;
- break;
-
- case dpcacheNoEntry:
- status = certRevocationStatusValid;
- break;
-
- case dpcacheInvalidCacheError:
- /* treat it as unknown and let the caller decide based on
- the policy */
- status = certRevocationStatusUnknown;
- break;
-
- default:
- /* leave status as revoked */
- break;
- }
-
- ReleaseDPCache(dpcache, lockedwrite);
- if (revStatus)
- {
- *revStatus = status;
- }
- if (revReason)
- {
- *revReason = reason;
- }
- return rv;
-}
-
-/* check CRL revocation status of given certificate and issuer */
-SECStatus
-CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer,
- const SECItem* dp, PRTime t, void* wincx)
-{
- return cert_CheckCertRevocationStatus(cert, issuer, dp, t, wincx,
- NULL, NULL);
-}
-
-/* retrieve full CRL object that best matches the cache status */
-CERTSignedCrl *
-SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type)
-{
- CERTSignedCrl* acrl = NULL;
- CRLDPCache* dpcache = NULL;
- SECStatus rv = SECSuccess;
- PRBool writeLocked = PR_FALSE;
-
- if (!crlKey)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- rv = AcquireDPCache(NULL, crlKey, NULL, 0, NULL, &dpcache, &writeLocked);
- if (SECSuccess == rv)
- {
- acrl = GetBestCRL(dpcache, PR_TRUE); /* decode entries, because
- SEC_FindCrlByName always returned fully decoded CRLs in the past */
- ReleaseDPCache(dpcache, writeLocked);
- }
- return acrl;
-}
-
-/* invalidate the CRL cache for a given issuer, which forces a refetch of
- CRL objects from PKCS#11 tokens */
-void CERT_CRLCacheRefreshIssuer(CERTCertDBHandle* dbhandle, SECItem* crlKey)
-{
- CRLDPCache* cache = NULL;
- SECStatus rv = SECSuccess;
- PRBool writeLocked = PR_FALSE;
- PRBool readlocked;
-
- (void) dbhandle; /* silence compiler warnings */
-
- /* XCRL we will need to refresh all the DPs of the issuer in the future,
- not just the default one */
- rv = AcquireDPCache(NULL, crlKey, NULL, 0, NULL, &cache, &writeLocked);
- if (SECSuccess != rv)
- {
- return;
- }
- /* we need to invalidate the DPCache here */
- readlocked = (writeLocked == PR_TRUE? PR_FALSE : PR_TRUE);
- DPCache_LockWrite();
- cache->refresh = PR_TRUE;
- DPCache_UnlockWrite();
- ReleaseDPCache(cache, writeLocked);
- return;
-}
-
-/* add the specified RAM CRL object to the cache */
-SECStatus CERT_CacheCRL(CERTCertDBHandle* dbhandle, SECItem* newdercrl)
-{
- CRLDPCache* cache = NULL;
- SECStatus rv = SECSuccess;
- PRBool writeLocked = PR_FALSE;
- PRBool readlocked;
- CachedCrl* returned = NULL;
- PRBool added = PR_FALSE;
- CERTSignedCrl* newcrl = NULL;
- int realerror = 0;
-
- if (!dbhandle || !newdercrl)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* first decode the DER CRL to make sure it's OK */
- newcrl = CERT_DecodeDERCrlWithFlags(NULL, newdercrl, SEC_CRL_TYPE,
- CRL_DECODE_DONT_COPY_DER |
- CRL_DECODE_SKIP_ENTRIES);
-
- if (!newcrl)
- {
- return SECFailure;
- }
-
- /* XXX check if it has IDP extension. If so, do not proceed and set error */
-
- rv = AcquireDPCache(NULL,
- &newcrl->crl.derName,
- NULL, 0, NULL, &cache, &writeLocked);
- if (SECSuccess == rv)
- {
- readlocked = (writeLocked == PR_TRUE? PR_FALSE : PR_TRUE);
-
- rv = CachedCrl_Create(&returned, newcrl, CRL_OriginExplicit);
- if (SECSuccess == rv && returned)
- {
- DPCache_LockWrite();
- rv = DPCache_AddCRL(cache, returned, &added);
- if (PR_TRUE != added)
- {
- realerror = PORT_GetError();
- CachedCrl_Destroy(returned);
- returned = NULL;
- }
- DPCache_UnlockWrite();
- }
-
- ReleaseDPCache(cache, writeLocked);
-
- if (!added)
- {
- rv = SECFailure;
- }
- }
- SEC_DestroyCrl(newcrl); /* free the CRL. Either it got added to the cache
- and the refcount got bumped, or not, and thus we need to free its
- RAM */
- if (realerror)
- {
- PORT_SetError(realerror);
- }
- return rv;
-}
-
-/* remove the specified RAM CRL object from the cache */
-SECStatus CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* olddercrl)
-{
- CRLDPCache* cache = NULL;
- SECStatus rv = SECSuccess;
- PRBool writeLocked = PR_FALSE;
- PRBool readlocked;
- PRBool removed = PR_FALSE;
- PRUint32 i;
- CERTSignedCrl* oldcrl = NULL;
-
- if (!dbhandle || !olddercrl)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* first decode the DER CRL to make sure it's OK */
- oldcrl = CERT_DecodeDERCrlWithFlags(NULL, olddercrl, SEC_CRL_TYPE,
- CRL_DECODE_DONT_COPY_DER |
- CRL_DECODE_SKIP_ENTRIES);
-
- if (!oldcrl)
- {
- /* if this DER CRL can't decode, it can't be in the cache */
- return SECFailure;
- }
-
- rv = AcquireDPCache(NULL,
- &oldcrl->crl.derName,
- NULL, 0, NULL, &cache, &writeLocked);
- if (SECSuccess == rv)
- {
- CachedCrl* returned = NULL;
-
- readlocked = (writeLocked == PR_TRUE? PR_FALSE : PR_TRUE);
-
- rv = CachedCrl_Create(&returned, oldcrl, CRL_OriginExplicit);
- if (SECSuccess == rv && returned)
- {
- DPCache_LockWrite();
- for (i=0;i<cache->ncrls;i++)
- {
- PRBool dupe = PR_FALSE, updated = PR_FALSE;
- rv = CachedCrl_Compare(returned, cache->crls[i],
- &dupe, &updated);
- if (SECSuccess != rv)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- break;
- }
- if (PR_TRUE == dupe)
- {
- rv = DPCache_RemoveCRL(cache, i); /* got a match */
- if (SECSuccess == rv) {
- cache->mustchoose = PR_TRUE;
- removed = PR_TRUE;
- }
- break;
- }
- }
-
- DPCache_UnlockWrite();
-
- if (SECSuccess != CachedCrl_Destroy(returned) ) {
- rv = SECFailure;
- }
- }
-
- ReleaseDPCache(cache, writeLocked);
- }
- if (SECSuccess != SEC_DestroyCrl(oldcrl) ) {
- /* need to do this because object is refcounted */
- rv = SECFailure;
- }
- if (SECSuccess == rv && PR_TRUE != removed)
- {
- PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
- }
- return rv;
-}
-
-SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned)
-{
- PORT_Assert(returned);
- if (!namedCRLCache.lock)
- {
- PORT_Assert(0);
- return SECFailure;
- }
- PR_Lock(namedCRLCache.lock);
- *returned = &namedCRLCache;
- return SECSuccess;
-}
-
-/* This must be called only while cache is acquired, and the entry is only
- * valid until cache is released.
- */
-SECStatus cert_FindCRLByGeneralName(NamedCRLCache* ncc,
- const SECItem* canonicalizedName,
- NamedCRLCacheEntry** retEntry)
-{
- if (!ncc || !canonicalizedName || !retEntry)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- *retEntry = (NamedCRLCacheEntry*) PL_HashTableLookup(namedCRLCache.entries,
- (void*) canonicalizedName);
- return SECSuccess;
-}
-
-SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc)
-{
- if (!ncc)
- {
- return SECFailure;
- }
- if (!ncc->lock)
- {
- PORT_Assert(0);
- return SECFailure;
- }
- PR_Unlock(namedCRLCache.lock);
- return SECSuccess;
-}
-
-/* creates new named cache entry from CRL, and tries to add it to CRL cache */
-static SECStatus addCRLToCache(CERTCertDBHandle* dbhandle, SECItem* crl,
- const SECItem* canonicalizedName,
- NamedCRLCacheEntry** newEntry)
-{
- SECStatus rv = SECSuccess;
- NamedCRLCacheEntry* entry = NULL;
-
- /* create new named entry */
- if (SECSuccess != NamedCRLCacheEntry_Create(newEntry) || !*newEntry)
- {
- /* no need to keep unused CRL around */
- SECITEM_ZfreeItem(crl, PR_TRUE);
- return SECFailure;
- }
- entry = *newEntry;
- entry->crl = crl; /* named CRL cache owns DER */
- entry->lastAttemptTime = PR_Now();
- entry->canonicalizedName = SECITEM_DupItem(canonicalizedName);
- if (!entry->canonicalizedName)
- {
- rv = NamedCRLCacheEntry_Destroy(entry); /* destroys CRL too */
- PORT_Assert(SECSuccess == rv);
- return SECFailure;
- }
- /* now, attempt to insert CRL into CRL cache */
- if (SECSuccess == CERT_CacheCRL(dbhandle, entry->crl))
- {
- entry->inCRLCache = PR_TRUE;
- entry->successfulInsertionTime = entry->lastAttemptTime;
- }
- else
- {
- switch (PR_GetError())
- {
- case SEC_ERROR_CRL_ALREADY_EXISTS:
- entry->dupe = PR_TRUE;
- break;
-
- case SEC_ERROR_BAD_DER:
- entry->badDER = PR_TRUE;
- break;
-
- /* all other reasons */
- default:
- entry->unsupported = PR_TRUE;
- break;
- }
- rv = SECFailure;
- /* no need to keep unused CRL around */
- SECITEM_ZfreeItem(entry->crl, PR_TRUE);
- entry->crl = NULL;
- }
- return rv;
-}
-
-/* take ownership of CRL, and insert it into the named CRL cache
- * and indexed CRL cache
- */
-SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
- const SECItem* canonicalizedName)
-{
- NamedCRLCacheEntry* oldEntry, * newEntry = NULL;
- NamedCRLCache* ncc = NULL;
- SECStatus rv = SECSuccess, rv2;
-
- PORT_Assert(namedCRLCache.lock);
- PORT_Assert(namedCRLCache.entries);
-
- if (!crl || !canonicalizedName)
- {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- rv = cert_AcquireNamedCRLCache(&ncc);
- PORT_Assert(SECSuccess == rv);
- if (SECSuccess != rv)
- {
- SECITEM_ZfreeItem(crl, PR_TRUE);
- return SECFailure;
- }
- rv = cert_FindCRLByGeneralName(ncc, canonicalizedName, &oldEntry);
- PORT_Assert(SECSuccess == rv);
- if (SECSuccess != rv)
- {
- rv = cert_ReleaseNamedCRLCache(ncc);
- SECITEM_ZfreeItem(crl, PR_TRUE);
- return SECFailure;
- }
- if (SECSuccess == addCRLToCache(dbhandle, crl, canonicalizedName,
- &newEntry) )
- {
- if (!oldEntry)
- {
- /* add new good entry to the hash table */
- if (NULL == PL_HashTableAdd(namedCRLCache.entries,
- (void*) newEntry->canonicalizedName,
- (void*) newEntry))
- {
- PORT_Assert(0);
- rv2 = NamedCRLCacheEntry_Destroy(newEntry);
- PORT_Assert(SECSuccess == rv2);
- rv = SECFailure;
- }
- }
- else
- {
- PRBool removed;
- /* remove the old CRL from the cache if needed */
- if (oldEntry->inCRLCache)
- {
- rv = CERT_UncacheCRL(dbhandle, oldEntry->crl);
- PORT_Assert(SECSuccess == rv);
- }
- removed = PL_HashTableRemove(namedCRLCache.entries,
- (void*) oldEntry->canonicalizedName);
- PORT_Assert(removed);
- if (!removed)
- {
- rv = SECFailure;
- /* leak old entry since we couldn't remove it from the hash table */
- }
- else
- {
- rv2 = NamedCRLCacheEntry_Destroy(oldEntry);
- PORT_Assert(SECSuccess == rv2);
- }
- if (NULL == PL_HashTableAdd(namedCRLCache.entries,
- (void*) newEntry->canonicalizedName,
- (void*) newEntry))
- {
- PORT_Assert(0);
- rv = SECFailure;
- }
- }
- } else
- {
- /* error adding new CRL to cache */
- if (!oldEntry)
- {
- /* no old cache entry, use the new one even though it's bad */
- if (NULL == PL_HashTableAdd(namedCRLCache.entries,
- (void*) newEntry->canonicalizedName,
- (void*) newEntry))
- {
- PORT_Assert(0);
- rv = SECFailure;
- }
- }
- else
- {
- if (oldEntry->inCRLCache)
- {
- /* previous cache entry was good, keep it and update time */
- oldEntry-> lastAttemptTime = newEntry->lastAttemptTime;
- /* throw away new bad entry */
- rv = NamedCRLCacheEntry_Destroy(newEntry);
- PORT_Assert(SECSuccess == rv);
- }
- else
- {
- /* previous cache entry was bad, just replace it */
- PRBool removed = PL_HashTableRemove(namedCRLCache.entries,
- (void*) oldEntry->canonicalizedName);
- PORT_Assert(removed);
- if (!removed)
- {
- /* leak old entry since we couldn't remove it from the hash table */
- rv = SECFailure;
- }
- else
- {
- rv2 = NamedCRLCacheEntry_Destroy(oldEntry);
- PORT_Assert(SECSuccess == rv2);
- }
- if (NULL == PL_HashTableAdd(namedCRLCache.entries,
- (void*) newEntry->canonicalizedName,
- (void*) newEntry))
- {
- PORT_Assert(0);
- rv = SECFailure;
- }
- }
- }
- }
- rv2 = cert_ReleaseNamedCRLCache(ncc);
- PORT_Assert(SECSuccess == rv2);
-
- return rv;
-}
-
-static SECStatus CachedCrl_Create(CachedCrl** returned, CERTSignedCrl* crl,
- CRLOrigin origin)
-{
- CachedCrl* newcrl = NULL;
- if (!returned)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- newcrl = PORT_ZAlloc(sizeof(CachedCrl));
- if (!newcrl)
- {
- return SECFailure;
- }
- newcrl->crl = SEC_DupCrl(crl);
- newcrl->origin = origin;
- *returned = newcrl;
- return SECSuccess;
-}
-
-/* empty the cache content */
-static SECStatus CachedCrl_Depopulate(CachedCrl* crl)
-{
- if (!crl)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* destroy the hash table */
- if (crl->entries)
- {
- PL_HashTableDestroy(crl->entries);
- crl->entries = NULL;
- }
-
- /* free the pre buffer */
- if (crl->prebuffer)
- {
- PreAllocator_Destroy(crl->prebuffer);
- crl->prebuffer = NULL;
- }
- return SECSuccess;
-}
-
-static SECStatus CachedCrl_Destroy(CachedCrl* crl)
-{
- if (!crl)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- CachedCrl_Depopulate(crl);
- SEC_DestroyCrl(crl->crl);
- PORT_Free(crl);
- return SECSuccess;
-}
-
-/* create hash table of CRL entries */
-static SECStatus CachedCrl_Populate(CachedCrl* crlobject)
-{
- SECStatus rv = SECFailure;
- CERTCrlEntry** crlEntry = NULL;
- PRUint32 numEntries = 0;
-
- if (!crlobject)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* complete the entry decoding . XXX thread-safety of CRL object */
- rv = CERT_CompleteCRLDecodeEntries(crlobject->crl);
- if (SECSuccess != rv)
- {
- crlobject->unbuildable = PR_TRUE; /* don't try to build this again */
- return SECFailure;
- }
-
- if (crlobject->entries && crlobject->prebuffer)
- {
- /* cache is already built */
- return SECSuccess;
- }
-
- /* build the hash table from the full CRL */
- /* count CRL entries so we can pre-allocate space for hash table entries */
- for (crlEntry = crlobject->crl->crl.entries; crlEntry && *crlEntry;
- crlEntry++)
- {
- numEntries++;
- }
- crlobject->prebuffer = PreAllocator_Create(numEntries*sizeof(PLHashEntry));
- PORT_Assert(crlobject->prebuffer);
- if (!crlobject->prebuffer)
- {
- return SECFailure;
- }
- /* create a new hash table */
- crlobject->entries = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
- PL_CompareValues, &preAllocOps, crlobject->prebuffer);
- PORT_Assert(crlobject->entries);
- if (!crlobject->entries)
- {
- return SECFailure;
- }
- /* add all serial numbers to the hash table */
- for (crlEntry = crlobject->crl->crl.entries; crlEntry && *crlEntry;
- crlEntry++)
- {
- PL_HashTableAdd(crlobject->entries, &(*crlEntry)->serialNumber,
- *crlEntry);
- }
-
- return SECSuccess;
-}
-
-/* returns true if there are CRLs from PKCS#11 slots */
-static PRBool DPCache_HasTokenCRLs(CRLDPCache* cache)
-{
- PRBool answer = PR_FALSE;
- PRUint32 i;
- for (i=0;i<cache->ncrls;i++)
- {
- if (cache->crls[i] && (CRL_OriginToken == cache->crls[i]->origin) )
- {
- answer = PR_TRUE;
- break;
- }
- }
- return answer;
-}
-
-/* are these CRLs the same, as far as the cache is concerned ? */
-/* are these CRLs the same token object but with different DER ?
- This can happen if the DER CRL got updated in the token, but the PKCS#11
- object ID did not change. NSS softoken has the unfortunate property to
- never change the object ID for CRL objects. */
-static SECStatus CachedCrl_Compare(CachedCrl* a, CachedCrl* b, PRBool* isDupe,
- PRBool* isUpdated)
-{
- PORT_Assert(a);
- PORT_Assert(b);
- PORT_Assert(isDupe);
- PORT_Assert(isUpdated);
- if (!a || !b || !isDupe || !isUpdated || !a->crl || !b->crl)
- {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- *isDupe = *isUpdated = PR_FALSE;
-
- if (a == b)
- {
- /* dupe */
- *isDupe = PR_TRUE;
- *isUpdated = PR_FALSE;
- return SECSuccess;
- }
- if (b->origin != a->origin)
- {
- /* CRLs of different origins are not considered dupes,
- and can't be updated either */
- return SECSuccess;
- }
- if (CRL_OriginToken == b->origin)
- {
- /* for token CRLs, slot and PKCS#11 object handle must match for CRL
- to truly be a dupe */
- if ( (b->crl->slot == a->crl->slot) &&
- (b->crl->pkcs11ID == a->crl->pkcs11ID) )
- {
- /* ASN.1 DER needs to match for dupe check */
- /* could optimize by just checking a few fields like thisUpdate */
- if ( SECEqual == SECITEM_CompareItem(b->crl->derCrl,
- a->crl->derCrl) )
- {
- *isDupe = PR_TRUE;
- }
- else
- {
- *isUpdated = PR_TRUE;
- }
- }
- return SECSuccess;
- }
- if (CRL_OriginExplicit == b->origin)
- {
- /* We need to make sure this is the same object that the user provided
- to CERT_CacheCRL previously. That API takes a SECItem*, thus, we
- just do a pointer comparison here.
- */
- if (b->crl->derCrl == a->crl->derCrl)
- {
- *isDupe = PR_TRUE;
- }
- }
- return SECSuccess;
-}
diff --git a/security/nss/lib/certdb/genname.c b/security/nss/lib/certdb/genname.c
deleted file mode 100644
index cf63a56d7..000000000
--- a/security/nss/lib/certdb/genname.c
+++ /dev/null
@@ -1,1861 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "plarena.h"
-#include "seccomon.h"
-#include "secitem.h"
-#include "secoidt.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "certt.h"
-#include "cert.h"
-#include "certi.h"
-#include "xconst.h"
-#include "secerr.h"
-#include "secoid.h"
-#include "prprf.h"
-#include "genname.h"
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(SEC_IntegerTemplate)
-SEC_ASN1_MKSUB(SEC_IA5StringTemplate)
-SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
-SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
-
-static const SEC_ASN1Template CERTNameConstraintTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraint) },
- { SEC_ASN1_ANY, offsetof(CERTNameConstraint, DERName) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(CERTNameConstraint, min),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- offsetof(CERTNameConstraint, max),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { 0, }
-};
-
-const SEC_ASN1Template CERT_NameConstraintSubtreeSubTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
-};
-
-static const SEC_ASN1Template CERTNameConstraintsTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraints) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(CERTNameConstraints, DERPermited),
- CERT_NameConstraintSubtreeSubTemplate},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(CERTNameConstraints, DERExcluded),
- CERT_NameConstraintSubtreeSubTemplate},
- { 0, }
-};
-
-
-static const SEC_ASN1Template CERTOthNameTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(OtherName) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(OtherName, oid) },
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
- SEC_ASN1_XTRN | 0, offsetof(OtherName, name),
- SEC_ASN1_SUB(SEC_AnyTemplate) },
- { 0, }
-};
-
-static const SEC_ASN1Template CERTOtherNameTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0 ,
- offsetof(CERTGeneralName, name.OthName), CERTOthNameTemplate,
- sizeof(CERTGeneralName) }
-};
-
-static const SEC_ASN1Template CERTOtherName2Template[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_CONTEXT_SPECIFIC | 0 ,
- 0, NULL, sizeof(CERTGeneralName) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTGeneralName, name.OthName) + offsetof(OtherName, oid) },
- { SEC_ASN1_ANY,
- offsetof(CERTGeneralName, name.OthName) + offsetof(OtherName, name) },
- { 0, }
-};
-
-static const SEC_ASN1Template CERT_RFC822NameTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1 ,
- offsetof(CERTGeneralName, name.other),
- SEC_ASN1_SUB(SEC_IA5StringTemplate),
- sizeof (CERTGeneralName)}
-};
-
-static const SEC_ASN1Template CERT_DNSNameTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2 ,
- offsetof(CERTGeneralName, name.other),
- SEC_ASN1_SUB(SEC_IA5StringTemplate),
- sizeof (CERTGeneralName)}
-};
-
-static const SEC_ASN1Template CERT_X400AddressTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 3,
- offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate),
- sizeof (CERTGeneralName)}
-};
-
-static const SEC_ASN1Template CERT_DirectoryNameTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
- SEC_ASN1_XTRN | 4, offsetof(CERTGeneralName, derDirectoryName),
- SEC_ASN1_SUB(SEC_AnyTemplate), sizeof (CERTGeneralName)}
-};
-
-
-static const SEC_ASN1Template CERT_EDIPartyNameTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_XTRN | 5,
- offsetof(CERTGeneralName, name.other), SEC_ASN1_SUB(SEC_AnyTemplate),
- sizeof (CERTGeneralName)}
-};
-
-static const SEC_ASN1Template CERT_URITemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 6 ,
- offsetof(CERTGeneralName, name.other),
- SEC_ASN1_SUB(SEC_IA5StringTemplate),
- sizeof (CERTGeneralName)}
-};
-
-static const SEC_ASN1Template CERT_IPAddressTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 7 ,
- offsetof(CERTGeneralName, name.other),
- SEC_ASN1_SUB(SEC_OctetStringTemplate),
- sizeof (CERTGeneralName)}
-};
-
-static const SEC_ASN1Template CERT_RegisteredIDTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 8 ,
- offsetof(CERTGeneralName, name.other),
- SEC_ASN1_SUB(SEC_ObjectIDTemplate),
- sizeof (CERTGeneralName)}
-};
-
-
-const SEC_ASN1Template CERT_GeneralNamesTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN , 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
-};
-
-
-
-CERTGeneralName *
-CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type)
-{
- CERTGeneralName *name = arena
- ? PORT_ArenaZNew(arena, CERTGeneralName)
- : PORT_ZNew(CERTGeneralName);
- if (name) {
- name->type = type;
- name->l.prev = name->l.next = &name->l;
- }
- return name;
-}
-
-/* Copy content of one General Name to another.
-** Caller has allocated destination general name.
-** This function does not change the destinate's GeneralName's list linkage.
-*/
-SECStatus
-cert_CopyOneGeneralName(PRArenaPool *arena,
- CERTGeneralName *dest,
- CERTGeneralName *src)
-{
- SECStatus rv;
- void *mark = NULL;
-
- PORT_Assert(dest != NULL);
- dest->type = src->type;
-
- mark = PORT_ArenaMark(arena);
-
- switch (src->type) {
- case certDirectoryName:
- rv = SECITEM_CopyItem(arena, &dest->derDirectoryName,
- &src->derDirectoryName);
- if (rv == SECSuccess)
- rv = CERT_CopyName(arena, &dest->name.directoryName,
- &src->name.directoryName);
- break;
-
- case certOtherName:
- rv = SECITEM_CopyItem(arena, &dest->name.OthName.name,
- &src->name.OthName.name);
- if (rv == SECSuccess)
- rv = SECITEM_CopyItem(arena, &dest->name.OthName.oid,
- &src->name.OthName.oid);
- break;
-
- default:
- rv = SECITEM_CopyItem(arena, &dest->name.other,
- &src->name.other);
- break;
-
- }
- if (rv != SECSuccess) {
- PORT_ArenaRelease(arena, mark);
- } else {
- PORT_ArenaUnmark(arena, mark);
- }
- return rv;
-}
-
-
-void
-CERT_DestroyGeneralNameList(CERTGeneralNameList *list)
-{
- PZLock *lock;
-
- if (list != NULL) {
- lock = list->lock;
- PZ_Lock(lock);
- if (--list->refCount <= 0 && list->arena != NULL) {
- PORT_FreeArena(list->arena, PR_FALSE);
- PZ_Unlock(lock);
- PZ_DestroyLock(lock);
- } else {
- PZ_Unlock(lock);
- }
- }
- return;
-}
-
-CERTGeneralNameList *
-CERT_CreateGeneralNameList(CERTGeneralName *name) {
- PRArenaPool *arena;
- CERTGeneralNameList *list = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto done;
- }
- list = PORT_ArenaZNew(arena, CERTGeneralNameList);
- if (!list)
- goto loser;
- if (name != NULL) {
- SECStatus rv;
- list->name = CERT_NewGeneralName(arena, (CERTGeneralNameType)0);
- if (!list->name)
- goto loser;
- rv = CERT_CopyGeneralName(arena, list->name, name);
- if (rv != SECSuccess)
- goto loser;
- }
- list->lock = PZ_NewLock(nssILockList);
- if (!list->lock)
- goto loser;
- list->arena = arena;
- list->refCount = 1;
-done:
- return list;
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
-}
-
-CERTGeneralName *
-CERT_GetNextGeneralName(CERTGeneralName *current)
-{
- PRCList *next;
-
- next = current->l.next;
- return (CERTGeneralName *) (((char *) next) - offsetof(CERTGeneralName, l));
-}
-
-CERTGeneralName *
-CERT_GetPrevGeneralName(CERTGeneralName *current)
-{
- PRCList *prev;
- prev = current->l.prev;
- return (CERTGeneralName *) (((char *) prev) - offsetof(CERTGeneralName, l));
-}
-
-CERTNameConstraint *
-CERT_GetNextNameConstraint(CERTNameConstraint *current)
-{
- PRCList *next;
-
- next = current->l.next;
- return (CERTNameConstraint *) (((char *) next) - offsetof(CERTNameConstraint, l));
-}
-
-CERTNameConstraint *
-CERT_GetPrevNameConstraint(CERTNameConstraint *current)
-{
- PRCList *prev;
- prev = current->l.prev;
- return (CERTNameConstraint *) (((char *) prev) - offsetof(CERTNameConstraint, l));
-}
-
-SECItem *
-CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PRArenaPool *arena)
-{
-
- const SEC_ASN1Template * template;
-
- PORT_Assert(arena);
- if (arena == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- /* TODO: mark arena */
- if (dest == NULL) {
- dest = PORT_ArenaZNew(arena, SECItem);
- if (!dest)
- goto loser;
- }
- if (genName->type == certDirectoryName) {
- if (genName->derDirectoryName.data == NULL) {
- /* The field hasn't been encoded yet. */
- SECItem * pre_dest =
- SEC_ASN1EncodeItem (arena, &(genName->derDirectoryName),
- &(genName->name.directoryName),
- CERT_NameTemplate);
- if (!pre_dest)
- goto loser;
- }
- if (genName->derDirectoryName.data == NULL) {
- goto loser;
- }
- }
- switch (genName->type) {
- case certURI: template = CERT_URITemplate; break;
- case certRFC822Name: template = CERT_RFC822NameTemplate; break;
- case certDNSName: template = CERT_DNSNameTemplate; break;
- case certIPAddress: template = CERT_IPAddressTemplate; break;
- case certOtherName: template = CERTOtherNameTemplate; break;
- case certRegisterID: template = CERT_RegisteredIDTemplate; break;
- /* for this type, we expect the value is already encoded */
- case certEDIPartyName: template = CERT_EDIPartyNameTemplate; break;
- /* for this type, we expect the value is already encoded */
- case certX400Address: template = CERT_X400AddressTemplate; break;
- case certDirectoryName: template = CERT_DirectoryNameTemplate; break;
- default:
- PORT_Assert(0); goto loser;
- }
- dest = SEC_ASN1EncodeItem(arena, dest, genName, template);
- if (!dest) {
- goto loser;
- }
- /* TODO: unmark arena */
- return dest;
-loser:
- /* TODO: release arena back to mark */
- return NULL;
-}
-
-SECItem **
-cert_EncodeGeneralNames(PRArenaPool *arena, CERTGeneralName *names)
-{
- CERTGeneralName *current_name;
- SECItem **items = NULL;
- int count = 0;
- int i;
- PRCList *head;
-
- PORT_Assert(arena);
- /* TODO: mark arena */
- current_name = names;
- if (names != NULL) {
- count = 1;
- }
- head = &(names->l);
- while (current_name->l.next != head) {
- current_name = CERT_GetNextGeneralName(current_name);
- ++count;
- }
- current_name = CERT_GetNextGeneralName(current_name);
- items = PORT_ArenaNewArray(arena, SECItem *, count + 1);
- if (items == NULL) {
- goto loser;
- }
- for (i = 0; i < count; i++) {
- items[i] = CERT_EncodeGeneralName(current_name, (SECItem *)NULL, arena);
- if (items[i] == NULL) {
- goto loser;
- }
- current_name = CERT_GetNextGeneralName(current_name);
- }
- items[i] = NULL;
- /* TODO: unmark arena */
- return items;
-loser:
- /* TODO: release arena to mark */
- return NULL;
-}
-
-CERTGeneralName *
-CERT_DecodeGeneralName(PRArenaPool *reqArena,
- SECItem *encodedName,
- CERTGeneralName *genName)
-{
- const SEC_ASN1Template * template;
- CERTGeneralNameType genNameType;
- SECStatus rv = SECSuccess;
- SECItem* newEncodedName;
-
- if (!reqArena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- /* make a copy for decoding so the data decoded with QuickDER doesn't
- point to temporary memory */
- newEncodedName = SECITEM_ArenaDupItem(reqArena, encodedName);
- if (!newEncodedName) {
- return NULL;
- }
- /* TODO: mark arena */
- genNameType = (CERTGeneralNameType)((*(newEncodedName->data) & 0x0f) + 1);
- if (genName == NULL) {
- genName = CERT_NewGeneralName(reqArena, genNameType);
- if (!genName)
- goto loser;
- } else {
- genName->type = genNameType;
- genName->l.prev = genName->l.next = &genName->l;
- }
-
- switch (genNameType) {
- case certURI: template = CERT_URITemplate; break;
- case certRFC822Name: template = CERT_RFC822NameTemplate; break;
- case certDNSName: template = CERT_DNSNameTemplate; break;
- case certIPAddress: template = CERT_IPAddressTemplate; break;
- case certOtherName: template = CERTOtherNameTemplate; break;
- case certRegisterID: template = CERT_RegisteredIDTemplate; break;
- case certEDIPartyName: template = CERT_EDIPartyNameTemplate; break;
- case certX400Address: template = CERT_X400AddressTemplate; break;
- case certDirectoryName: template = CERT_DirectoryNameTemplate; break;
- default:
- goto loser;
- }
- rv = SEC_QuickDERDecodeItem(reqArena, genName, template, newEncodedName);
- if (rv != SECSuccess)
- goto loser;
- if (genNameType == certDirectoryName) {
- rv = SEC_QuickDERDecodeItem(reqArena, &(genName->name.directoryName),
- CERT_NameTemplate,
- &(genName->derDirectoryName));
- if (rv != SECSuccess)
- goto loser;
- }
-
- /* TODO: unmark arena */
- return genName;
-loser:
- /* TODO: release arena to mark */
- return NULL;
-}
-
-CERTGeneralName *
-cert_DecodeGeneralNames (PRArenaPool *arena,
- SECItem **encodedGenName)
-{
- PRCList *head = NULL;
- PRCList *tail = NULL;
- CERTGeneralName *currentName = NULL;
-
- PORT_Assert(arena);
- if (!encodedGenName || !arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- /* TODO: mark arena */
- while (*encodedGenName != NULL) {
- currentName = CERT_DecodeGeneralName(arena, *encodedGenName, NULL);
- if (currentName == NULL)
- break;
- if (head == NULL) {
- head = &(currentName->l);
- tail = head;
- }
- currentName->l.next = head;
- currentName->l.prev = tail;
- tail = head->prev = tail->next = &(currentName->l);
- encodedGenName++;
- }
- if (currentName) {
- /* TODO: unmark arena */
- return CERT_GetNextGeneralName(currentName);
- }
- /* TODO: release arena to mark */
- return NULL;
-}
-
-void
-CERT_DestroyGeneralName(CERTGeneralName *name)
-{
- cert_DestroyGeneralNames(name);
-}
-
-SECStatus
-cert_DestroyGeneralNames(CERTGeneralName *name)
-{
- CERTGeneralName *first;
- CERTGeneralName *next = NULL;
-
-
- first = name;
- do {
- next = CERT_GetNextGeneralName(name);
- PORT_Free(name);
- name = next;
- } while (name != first);
- return SECSuccess;
-}
-
-static SECItem *
-cert_EncodeNameConstraint(CERTNameConstraint *constraint,
- SECItem *dest,
- PRArenaPool *arena)
-{
- PORT_Assert(arena);
- if (dest == NULL) {
- dest = PORT_ArenaZNew(arena, SECItem);
- if (dest == NULL) {
- return NULL;
- }
- }
- CERT_EncodeGeneralName(&(constraint->name), &(constraint->DERName), arena);
-
- dest = SEC_ASN1EncodeItem (arena, dest, constraint,
- CERTNameConstraintTemplate);
- return dest;
-}
-
-SECStatus
-cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints,
- PRArenaPool *arena,
- SECItem ***dest,
- PRBool permited)
-{
- CERTNameConstraint *current_constraint = constraints;
- SECItem **items = NULL;
- int count = 0;
- int i;
- PRCList *head;
-
- PORT_Assert(arena);
- /* TODO: mark arena */
- if (constraints != NULL) {
- count = 1;
- }
- head = &constraints->l;
- while (current_constraint->l.next != head) {
- current_constraint = CERT_GetNextNameConstraint(current_constraint);
- ++count;
- }
- current_constraint = CERT_GetNextNameConstraint(current_constraint);
- items = PORT_ArenaZNewArray(arena, SECItem *, count + 1);
- if (items == NULL) {
- goto loser;
- }
- for (i = 0; i < count; i++) {
- items[i] = cert_EncodeNameConstraint(current_constraint,
- (SECItem *) NULL, arena);
- if (items[i] == NULL) {
- goto loser;
- }
- current_constraint = CERT_GetNextNameConstraint(current_constraint);
- }
- *dest = items;
- if (*dest == NULL) {
- goto loser;
- }
- /* TODO: unmark arena */
- return SECSuccess;
-loser:
- /* TODO: release arena to mark */
- return SECFailure;
-}
-
-SECStatus
-cert_EncodeNameConstraints(CERTNameConstraints *constraints,
- PRArenaPool *arena,
- SECItem *dest)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(arena);
- /* TODO: mark arena */
- if (constraints->permited != NULL) {
- rv = cert_EncodeNameConstraintSubTree(constraints->permited, arena,
- &constraints->DERPermited,
- PR_TRUE);
- if (rv == SECFailure) {
- goto loser;
- }
- }
- if (constraints->excluded != NULL) {
- rv = cert_EncodeNameConstraintSubTree(constraints->excluded, arena,
- &constraints->DERExcluded,
- PR_FALSE);
- if (rv == SECFailure) {
- goto loser;
- }
- }
- dest = SEC_ASN1EncodeItem(arena, dest, constraints,
- CERTNameConstraintsTemplate);
- if (dest == NULL) {
- goto loser;
- }
- /* TODO: unmark arena */
- return SECSuccess;
-loser:
- /* TODO: release arena to mark */
- return SECFailure;
-}
-
-
-CERTNameConstraint *
-cert_DecodeNameConstraint(PRArenaPool *reqArena,
- SECItem *encodedConstraint)
-{
- CERTNameConstraint *constraint;
- SECStatus rv = SECSuccess;
- CERTGeneralName *temp;
- SECItem* newEncodedConstraint;
-
- if (!reqArena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- newEncodedConstraint = SECITEM_ArenaDupItem(reqArena, encodedConstraint);
- if (!newEncodedConstraint) {
- return NULL;
- }
- /* TODO: mark arena */
- constraint = PORT_ArenaZNew(reqArena, CERTNameConstraint);
- if (!constraint)
- goto loser;
- rv = SEC_QuickDERDecodeItem(reqArena, constraint,
- CERTNameConstraintTemplate,
- newEncodedConstraint);
- if (rv != SECSuccess) {
- goto loser;
- }
- temp = CERT_DecodeGeneralName(reqArena, &(constraint->DERName),
- &(constraint->name));
- if (temp != &(constraint->name)) {
- goto loser;
- }
-
- /* ### sjlee: since the name constraint contains only one
- * CERTGeneralName, the list within CERTGeneralName shouldn't
- * point anywhere else. Otherwise, bad things will happen.
- */
- constraint->name.l.prev = constraint->name.l.next = &(constraint->name.l);
- /* TODO: unmark arena */
- return constraint;
-loser:
- /* TODO: release arena back to mark */
- return NULL;
-}
-
-CERTNameConstraint *
-cert_DecodeNameConstraintSubTree(PRArenaPool *arena,
- SECItem **subTree,
- PRBool permited)
-{
- CERTNameConstraint *current = NULL;
- CERTNameConstraint *first = NULL;
- CERTNameConstraint *last = NULL;
- int i = 0;
-
- PORT_Assert(arena);
- /* TODO: mark arena */
- while (subTree[i] != NULL) {
- current = cert_DecodeNameConstraint(arena, subTree[i]);
- if (current == NULL) {
- goto loser;
- }
- if (last == NULL) {
- first = last = current;
- }
- current->l.prev = &(last->l);
- current->l.next = last->l.next;
- last->l.next = &(current->l);
- i++;
- }
- first->l.prev = &(current->l);
- /* TODO: unmark arena */
- return first;
-loser:
- /* TODO: release arena back to mark */
- return NULL;
-}
-
-CERTNameConstraints *
-cert_DecodeNameConstraints(PRArenaPool *reqArena,
- SECItem *encodedConstraints)
-{
- CERTNameConstraints *constraints;
- SECStatus rv;
- SECItem* newEncodedConstraints;
-
- if (!reqArena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- PORT_Assert(encodedConstraints);
- newEncodedConstraints = SECITEM_ArenaDupItem(reqArena, encodedConstraints);
-
- /* TODO: mark arena */
- constraints = PORT_ArenaZNew(reqArena, CERTNameConstraints);
- if (constraints == NULL) {
- goto loser;
- }
- rv = SEC_QuickDERDecodeItem(reqArena, constraints,
- CERTNameConstraintsTemplate,
- newEncodedConstraints);
- if (rv != SECSuccess) {
- goto loser;
- }
- if (constraints->DERPermited != NULL &&
- constraints->DERPermited[0] != NULL) {
- constraints->permited =
- cert_DecodeNameConstraintSubTree(reqArena,
- constraints->DERPermited,
- PR_TRUE);
- if (constraints->permited == NULL) {
- goto loser;
- }
- }
- if (constraints->DERExcluded != NULL &&
- constraints->DERExcluded[0] != NULL) {
- constraints->excluded =
- cert_DecodeNameConstraintSubTree(reqArena,
- constraints->DERExcluded,
- PR_FALSE);
- if (constraints->excluded == NULL) {
- goto loser;
- }
- }
- /* TODO: unmark arena */
- return constraints;
-loser:
- /* TODO: release arena back to mark */
- return NULL;
-}
-
-/* Copy a chain of one or more general names to a destination chain.
-** Caller has allocated at least the first destination GeneralName struct.
-** Both source and destination chains are circular doubly-linked lists.
-** The first source struct is copied to the first destination struct.
-** If the source chain has more than one member, and the destination chain
-** has only one member, then this function allocates new structs for all but
-** the first copy from the arena and links them into the destination list.
-** If the destination struct is part of a list with more than one member,
-** then this function traverses both the source and destination lists,
-** copying each source struct to the corresponding dest struct.
-** In that case, the destination list MUST contain at least as many
-** structs as the source list or some dest entries will be overwritten.
-*/
-SECStatus
-CERT_CopyGeneralName(PRArenaPool *arena,
- CERTGeneralName *dest,
- CERTGeneralName *src)
-{
- SECStatus rv;
- CERTGeneralName *destHead = dest;
- CERTGeneralName *srcHead = src;
-
- PORT_Assert(dest != NULL);
- if (!dest) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* TODO: mark arena */
- do {
- rv = cert_CopyOneGeneralName(arena, dest, src);
- if (rv != SECSuccess)
- goto loser;
- src = CERT_GetNextGeneralName(src);
- /* if there is only one general name, we shouldn't do this */
- if (src != srcHead) {
- if (dest->l.next == &destHead->l) {
- CERTGeneralName *temp;
- temp = CERT_NewGeneralName(arena, (CERTGeneralNameType)0);
- if (!temp)
- goto loser;
- temp->l.next = &destHead->l;
- temp->l.prev = &dest->l;
- destHead->l.prev = &temp->l;
- dest->l.next = &temp->l;
- dest = temp;
- } else {
- dest = CERT_GetNextGeneralName(dest);
- }
- }
- } while (src != srcHead && rv == SECSuccess);
- /* TODO: unmark arena */
- return rv;
-loser:
- /* TODO: release back to mark */
- return SECFailure;
-}
-
-
-CERTGeneralNameList *
-CERT_DupGeneralNameList(CERTGeneralNameList *list)
-{
- if (list != NULL) {
- PZ_Lock(list->lock);
- list->refCount++;
- PZ_Unlock(list->lock);
- }
- return list;
-}
-
-/* Allocate space and copy CERTNameConstraint from src to dest */
-CERTNameConstraint *
-CERT_CopyNameConstraint(PRArenaPool *arena,
- CERTNameConstraint *dest,
- CERTNameConstraint *src)
-{
- SECStatus rv;
-
- /* TODO: mark arena */
- if (dest == NULL) {
- dest = PORT_ArenaZNew(arena, CERTNameConstraint);
- if (!dest)
- goto loser;
- /* mark that it is not linked */
- dest->name.l.prev = dest->name.l.next = &(dest->name.l);
- }
- rv = CERT_CopyGeneralName(arena, &dest->name, &src->name);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECITEM_CopyItem(arena, &dest->DERName, &src->DERName);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECITEM_CopyItem(arena, &dest->min, &src->min);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECITEM_CopyItem(arena, &dest->max, &src->max);
- if (rv != SECSuccess) {
- goto loser;
- }
- dest->l.prev = dest->l.next = &dest->l;
- /* TODO: unmark arena */
- return dest;
-loser:
- /* TODO: release arena to mark */
- return NULL;
-}
-
-
-CERTGeneralName *
-cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2)
-{
- PRCList *begin1;
- PRCList *begin2;
- PRCList *end1;
- PRCList *end2;
-
- if (list1 == NULL){
- return list2;
- } else if (list2 == NULL) {
- return list1;
- } else {
- begin1 = &list1->l;
- begin2 = &list2->l;
- end1 = list1->l.prev;
- end2 = list2->l.prev;
- end1->next = begin2;
- end2->next = begin1;
- begin1->prev = end2;
- begin2->prev = end1;
- return list1;
- }
-}
-
-
-CERTNameConstraint *
-cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list2)
-{
- PRCList *begin1;
- PRCList *begin2;
- PRCList *end1;
- PRCList *end2;
-
- if (list1 == NULL){
- return list2;
- } else if (list2 == NULL) {
- return list1;
- } else {
- begin1 = &list1->l;
- begin2 = &list2->l;
- end1 = list1->l.prev;
- end2 = list2->l.prev;
- end1->next = begin2;
- end2->next = begin1;
- begin1->prev = end2;
- begin2->prev = end1;
- return list1;
- }
-}
-
-
-/* Add a CERTNameConstraint to the CERTNameConstraint list */
-CERTNameConstraint *
-CERT_AddNameConstraint(CERTNameConstraint *list,
- CERTNameConstraint *constraint)
-{
- PORT_Assert(constraint != NULL);
- constraint->l.next = constraint->l.prev = &constraint->l;
- list = cert_CombineConstraintsLists(list, constraint);
- return list;
-}
-
-
-SECStatus
-CERT_GetNameConstraintByType (CERTNameConstraint *constraints,
- CERTGeneralNameType type,
- CERTNameConstraint **returnList,
- PRArenaPool *arena)
-{
- CERTNameConstraint *current = NULL;
- void *mark = NULL;
-
- *returnList = NULL;
- if (!constraints)
- return SECSuccess;
-
- mark = PORT_ArenaMark(arena);
-
- current = constraints;
- do {
- PORT_Assert(current->name.type);
- if (current->name.type == type) {
- CERTNameConstraint *temp;
- temp = CERT_CopyNameConstraint(arena, NULL, current);
- if (temp == NULL)
- goto loser;
- *returnList = CERT_AddNameConstraint(*returnList, temp);
- }
- current = CERT_GetNextNameConstraint(current);
- } while (current != constraints);
- PORT_ArenaUnmark(arena, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(arena, mark);
- return SECFailure;
-}
-
-void *
-CERT_GetGeneralNameByType (CERTGeneralName *genNames,
- CERTGeneralNameType type, PRBool derFormat)
-{
- CERTGeneralName *current;
-
- if (!genNames)
- return NULL;
- current = genNames;
-
- do {
- if (current->type == type) {
- switch (type) {
- case certDNSName:
- case certEDIPartyName:
- case certIPAddress:
- case certRegisterID:
- case certRFC822Name:
- case certX400Address:
- case certURI:
- return (void *)&current->name.other; /* SECItem * */
-
- case certOtherName:
- return (void *)&current->name.OthName; /* OthName * */
-
- case certDirectoryName:
- return derFormat
- ? (void *)&current->derDirectoryName /* SECItem * */
- : (void *)&current->name.directoryName; /* CERTName * */
- }
- PORT_Assert(0);
- return NULL;
- }
- current = CERT_GetNextGeneralName(current);
- } while (current != genNames);
- return NULL;
-}
-
-int
-CERT_GetNamesLength(CERTGeneralName *names)
-{
- int length = 0;
- CERTGeneralName *first;
-
- first = names;
- if (names != NULL) {
- do {
- length++;
- names = CERT_GetNextGeneralName(names);
- } while (names != first);
- }
- return length;
-}
-
-/* Creates new GeneralNames for any email addresses found in the
-** input DN, and links them onto the list for the DN.
-*/
-SECStatus
-cert_ExtractDNEmailAddrs(CERTGeneralName *name, PLArenaPool *arena)
-{
- CERTGeneralName *nameList = NULL;
- const CERTRDN **nRDNs = (const CERTRDN **)(name->name.directoryName.rdns);
- SECStatus rv = SECSuccess;
-
- PORT_Assert(name->type == certDirectoryName);
- if (name->type != certDirectoryName) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* TODO: mark arena */
- while (nRDNs && *nRDNs) { /* loop over RDNs */
- const CERTRDN *nRDN = *nRDNs++;
- CERTAVA **nAVAs = nRDN->avas;
- while (nAVAs && *nAVAs) { /* loop over AVAs */
- int tag;
- CERTAVA *nAVA = *nAVAs++;
- tag = CERT_GetAVATag(nAVA);
- if ( tag == SEC_OID_PKCS9_EMAIL_ADDRESS ||
- tag == SEC_OID_RFC1274_MAIL) { /* email AVA */
- CERTGeneralName *newName = NULL;
- SECItem *avaValue = CERT_DecodeAVAValue(&nAVA->value);
- if (!avaValue)
- goto loser;
- rv = SECFailure;
- newName = CERT_NewGeneralName(arena, certRFC822Name);
- if (newName) {
- rv = SECITEM_CopyItem(arena, &newName->name.other, avaValue);
- }
- SECITEM_FreeItem(avaValue, PR_TRUE);
- if (rv != SECSuccess)
- goto loser;
- nameList = cert_CombineNamesLists(nameList, newName);
- } /* handle one email AVA */
- } /* loop over AVAs */
- } /* loop over RDNs */
- /* combine new names with old one. */
- name = cert_CombineNamesLists(name, nameList);
- /* TODO: unmark arena */
- return SECSuccess;
-
-loser:
- /* TODO: release arena back to mark */
- return SECFailure;
-}
-
-/* Extract all names except Subject Common Name from a cert
-** in preparation for a name constraints test.
-*/
-CERTGeneralName *
-CERT_GetCertificateNames(CERTCertificate *cert, PRArenaPool *arena)
-{
- return CERT_GetConstrainedCertificateNames(cert, arena, PR_FALSE);
-}
-
-/* This function is called by CERT_VerifyCertChain to extract all
-** names from a cert in preparation for a name constraints test.
-*/
-CERTGeneralName *
-CERT_GetConstrainedCertificateNames(CERTCertificate *cert, PRArenaPool *arena,
- PRBool includeSubjectCommonName)
-{
- CERTGeneralName *DN;
- CERTGeneralName *SAN;
- PRUint32 numDNSNames = 0;
- SECStatus rv;
-
- if (!arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- /* TODO: mark arena */
- DN = CERT_NewGeneralName(arena, certDirectoryName);
- if (DN == NULL) {
- goto loser;
- }
- rv = CERT_CopyName(arena, &DN->name.directoryName, &cert->subject);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECITEM_CopyItem(arena, &DN->derDirectoryName, &cert->derSubject);
- if (rv != SECSuccess) {
- goto loser;
- }
- /* Extract email addresses from DN, construct CERTGeneralName structs
- ** for them, add them to the name list
- */
- rv = cert_ExtractDNEmailAddrs(DN, arena);
- if (rv != SECSuccess)
- goto loser;
-
- /* Now extract any GeneralNames from the subject name names extension. */
- SAN = cert_GetSubjectAltNameList(cert, arena);
- if (SAN) {
- numDNSNames = cert_CountDNSPatterns(SAN);
- DN = cert_CombineNamesLists(DN, SAN);
- }
- if (!numDNSNames && includeSubjectCommonName) {
- char *cn = CERT_GetCommonName(&cert->subject);
- if (cn) {
- CERTGeneralName *CN = CERT_NewGeneralName(arena, certDNSName);
- if (CN) {
- SECItem cnItem = {siBuffer, NULL, 0};
- cnItem.data = (unsigned char *)cn;
- cnItem.len = strlen(cn);
- rv = SECITEM_CopyItem(arena, &CN->name.other, &cnItem);
- if (rv == SECSuccess) {
- DN = cert_CombineNamesLists(DN, CN);
- }
- }
- PORT_Free(cn);
- }
- }
- if (rv == SECSuccess) {
- /* TODO: unmark arena */
- return DN;
- }
-loser:
- /* TODO: release arena to mark */
- return NULL;
-}
-
-/* Returns SECSuccess if name matches constraint per RFC 3280 rules for
-** URI name constraints. SECFailure otherwise.
-** If the constraint begins with a dot, it is a domain name, otherwise
-** It is a host name. Examples:
-** Constraint Name Result
-** ------------ --------------- --------
-** foo.bar.com foo.bar.com matches
-** foo.bar.com FoO.bAr.CoM matches
-** foo.bar.com www.foo.bar.com no match
-** foo.bar.com nofoo.bar.com no match
-** .foo.bar.com www.foo.bar.com matches
-** .foo.bar.com nofoo.bar.com no match
-** .foo.bar.com foo.bar.com no match
-** .foo.bar.com www..foo.bar.com no match
-*/
-static SECStatus
-compareURIN2C(const SECItem *name, const SECItem *constraint)
-{
- int offset;
- /* The spec is silent on intepreting zero-length constraints.
- ** We interpret them as matching no URI names.
- */
- if (!constraint->len)
- return SECFailure;
- if (constraint->data[0] != '.') {
- /* constraint is a host name. */
- if (name->len != constraint->len ||
- PL_strncasecmp((char *)name->data,
- (char *)constraint->data, constraint->len))
- return SECFailure;
- return SECSuccess;
- }
- /* constraint is a domain name. */
- if (name->len < constraint->len)
- return SECFailure;
- offset = name->len - constraint->len;
- if (PL_strncasecmp((char *)(name->data + offset),
- (char *)constraint->data, constraint->len))
- return SECFailure;
- if (!offset ||
- (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1)
- return SECSuccess;
- return SECFailure;
-}
-
-/* for DNSname constraints, RFC 3280 says, (section 4.2.1.11, page 38)
-**
-** DNS name restrictions are expressed as foo.bar.com. Any DNS name
-** that can be constructed by simply adding to the left hand side of the
-** name satisfies the name constraint. For example, www.foo.bar.com
-** would satisfy the constraint but foo1.bar.com would not.
-**
-** But NIST's PKITS test suite requires that the constraint be treated
-** as a domain name, and requires that any name added to the left hand
-** side end in a dot ".". Sensible, but not strictly following the RFC.
-**
-** Constraint Name RFC 3280 NIST PKITS
-** ------------ --------------- -------- ----------
-** foo.bar.com foo.bar.com matches matches
-** foo.bar.com FoO.bAr.CoM matches matches
-** foo.bar.com www.foo.bar.com matches matches
-** foo.bar.com nofoo.bar.com MATCHES NO MATCH
-** .foo.bar.com www.foo.bar.com matches matches? disallowed?
-** .foo.bar.com foo.bar.com no match no match
-** .foo.bar.com www..foo.bar.com matches probably not
-**
-** We will try to conform to NIST's PKITS tests, and the unstated
-** rules they imply.
-*/
-static SECStatus
-compareDNSN2C(const SECItem *name, const SECItem *constraint)
-{
- int offset;
- /* The spec is silent on intepreting zero-length constraints.
- ** We interpret them as matching all DNSnames.
- */
- if (!constraint->len)
- return SECSuccess;
- if (name->len < constraint->len)
- return SECFailure;
- offset = name->len - constraint->len;
- if (PL_strncasecmp((char *)(name->data + offset),
- (char *)constraint->data, constraint->len))
- return SECFailure;
- if (!offset ||
- (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1)
- return SECSuccess;
- return SECFailure;
-}
-
-/* Returns SECSuccess if name matches constraint per RFC 3280 rules for
-** internet email addresses. SECFailure otherwise.
-** If constraint contains a '@' then the two strings much match exactly.
-** Else if constraint starts with a '.'. then it must match the right-most
-** substring of the name,
-** else constraint string must match entire name after the name's '@'.
-** Empty constraint string matches all names. All comparisons case insensitive.
-*/
-static SECStatus
-compareRFC822N2C(const SECItem *name, const SECItem *constraint)
-{
- int offset;
- if (!constraint->len)
- return SECSuccess;
- if (name->len < constraint->len)
- return SECFailure;
- if (constraint->len == 1 && constraint->data[0] == '.')
- return SECSuccess;
- for (offset = constraint->len - 1; offset >= 0; --offset) {
- if (constraint->data[offset] == '@') {
- return (name->len == constraint->len &&
- !PL_strncasecmp((char *)name->data,
- (char *)constraint->data, constraint->len))
- ? SECSuccess : SECFailure;
- }
- }
- offset = name->len - constraint->len;
- if (PL_strncasecmp((char *)(name->data + offset),
- (char *)constraint->data, constraint->len))
- return SECFailure;
- if (constraint->data[0] == '.')
- return SECSuccess;
- if (offset > 0 && name->data[offset - 1] == '@')
- return SECSuccess;
- return SECFailure;
-}
-
-/* name contains either a 4 byte IPv4 address or a 16 byte IPv6 address.
-** constraint contains an address of the same length, and a subnet mask
-** of the same length. Compare name's address to the constraint's
-** address, subject to the mask.
-** Return SECSuccess if they match, SECFailure if they don't.
-*/
-static SECStatus
-compareIPaddrN2C(const SECItem *name, const SECItem *constraint)
-{
- int i;
- if (name->len == 4 && constraint->len == 8) { /* ipv4 addr */
- for (i = 0; i < 4; i++) {
- if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+4])
- goto loser;
- }
- return SECSuccess;
- }
- if (name->len == 16 && constraint->len == 32) { /* ipv6 addr */
- for (i = 0; i < 16; i++) {
- if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+16])
- goto loser;
- }
- return SECSuccess;
- }
-loser:
- return SECFailure;
-}
-
-/* start with a SECItem that points to a URI. Parse it lookingg for
-** a hostname. Modify item->data and item->len to define the hostname,
-** but do not modify and data at item->data.
-** If anything goes wrong, the contents of *item are undefined.
-*/
-static SECStatus
-parseUriHostname(SECItem * item)
-{
- int i;
- PRBool found = PR_FALSE;
- for (i = 0; (unsigned)(i+2) < item->len; ++i) {
- if (item->data[i ] == ':' &&
- item->data[i+1] == '/' &&
- item->data[i+2] == '/') {
- i += 3;
- item->data += i;
- item->len -= i;
- found = PR_TRUE;
- break;
- }
- }
- if (!found)
- return SECFailure;
- /* now look for a '/', which is an upper bound in the end of the name */
- for (i = 0; (unsigned)i < item->len; ++i) {
- if (item->data[i] == '/') {
- item->len = i;
- break;
- }
- }
- /* now look for a ':', which marks the end of the name */
- for (i = item->len; --i >= 0; ) {
- if (item->data[i] == ':') {
- item->len = i;
- break;
- }
- }
- /* now look for an '@', which marks the beginning of the hostname */
- for (i = 0; (unsigned)i < item->len; ++i) {
- if (item->data[i] == '@') {
- ++i;
- item->data += i;
- item->len -= i;
- break;
- }
- }
- return item->len ? SECSuccess : SECFailure;
-}
-
-/* This function takes one name, and a list of constraints.
-** It searches the constraints looking for a match.
-** It returns SECSuccess if the name satisfies the constraints, i.e.,
-** if excluded, then the name does not match any constraint,
-** if permitted, then the name matches at least one constraint.
-** It returns SECFailure if the name fails to satisfy the constraints,
-** or if some code fails (e.g. out of memory, or invalid constraint)
-*/
-SECStatus
-cert_CompareNameWithConstraints(CERTGeneralName *name,
- CERTNameConstraint *constraints,
- PRBool excluded)
-{
- SECStatus rv = SECSuccess;
- SECStatus matched = SECFailure;
- CERTNameConstraint *current;
-
- PORT_Assert(constraints); /* caller should not call with NULL */
- if (!constraints) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- current = constraints;
- do {
- rv = SECSuccess;
- matched = SECFailure;
- PORT_Assert(name->type == current->name.type);
- switch (name->type) {
-
- case certDNSName:
- matched = compareDNSN2C(&name->name.other,
- &current->name.name.other);
- break;
-
- case certRFC822Name:
- matched = compareRFC822N2C(&name->name.other,
- &current->name.name.other);
- break;
-
- case certURI:
- {
- /* make a modifiable copy of the URI SECItem. */
- SECItem uri = name->name.other;
- /* find the hostname in the URI */
- rv = parseUriHostname(&uri);
- if (rv == SECSuccess) {
- /* does our hostname meet the constraint? */
- matched = compareURIN2C(&uri, &current->name.name.other);
- }
- }
- break;
-
- case certDirectoryName:
- /* Determine if the constraint directory name is a "prefix"
- ** for the directory name being tested.
- */
- {
- /* status defaults to SECEqual, so that a constraint with
- ** no AVAs will be a wildcard, matching all directory names.
- */
- SECComparison status = SECEqual;
- const CERTRDN **cRDNs =
- (const CERTRDN **)current->name.name.directoryName.rdns;
- const CERTRDN **nRDNs =
- (const CERTRDN **)name->name.directoryName.rdns;
- while (cRDNs && *cRDNs && nRDNs && *nRDNs) {
- /* loop over name RDNs and constraint RDNs in lock step */
- const CERTRDN *cRDN = *cRDNs++;
- const CERTRDN *nRDN = *nRDNs++;
- CERTAVA **cAVAs = cRDN->avas;
- while (cAVAs && *cAVAs) { /* loop over constraint AVAs */
- CERTAVA *cAVA = *cAVAs++;
- CERTAVA **nAVAs = nRDN->avas;
- while (nAVAs && *nAVAs) { /* loop over name AVAs */
- CERTAVA *nAVA = *nAVAs++;
- status = CERT_CompareAVA(cAVA, nAVA);
- if (status == SECEqual)
- break;
- } /* loop over name AVAs */
- if (status != SECEqual)
- break;
- } /* loop over constraint AVAs */
- if (status != SECEqual)
- break;
- } /* loop over name RDNs and constraint RDNs */
- matched = (status == SECEqual) ? SECSuccess : SECFailure;
- break;
- }
-
- case certIPAddress: /* type 8 */
- matched = compareIPaddrN2C(&name->name.other,
- &current->name.name.other);
- break;
-
- /* NSS does not know how to compare these "Other" type names with
- ** their respective constraints. But it does know how to tell
- ** if the constraint applies to the type of name (by comparing
- ** the constraint OID to the name OID). NSS makes no use of "Other"
- ** type names at all, so NSS errs on the side of leniency for these
- ** types, provided that their OIDs match. So, when an "Other"
- ** name constraint appears in an excluded subtree, it never causes
- ** a name to fail. When an "Other" name constraint appears in a
- ** permitted subtree, AND the constraint's OID matches the name's
- ** OID, then name is treated as if it matches the constraint.
- */
- case certOtherName: /* type 1 */
- matched = (!excluded &&
- name->type == current->name.type &&
- SECITEM_ItemsAreEqual(&name->name.OthName.oid,
- &current->name.name.OthName.oid))
- ? SECSuccess : SECFailure;
- break;
-
- /* NSS does not know how to compare these types of names with their
- ** respective constraints. But NSS makes no use of these types of
- ** names at all, so it errs on the side of leniency for these types.
- ** Constraints for these types of names never cause the name to
- ** fail the constraints test. NSS behaves as if the name matched
- ** for permitted constraints, and did not match for excluded ones.
- */
- case certX400Address: /* type 4 */
- case certEDIPartyName: /* type 6 */
- case certRegisterID: /* type 9 */
- matched = excluded ? SECFailure : SECSuccess;
- break;
-
- default: /* non-standard types are not supported */
- rv = SECFailure;
- break;
- }
- if (matched == SECSuccess || rv != SECSuccess)
- break;
- current = CERT_GetNextNameConstraint(current);
- } while (current != constraints);
- if (rv == SECSuccess) {
- if (matched == SECSuccess)
- rv = excluded ? SECFailure : SECSuccess;
- else
- rv = excluded ? SECSuccess : SECFailure;
- return rv;
- }
-
- return SECFailure;
-}
-
-/* Add and link a CERTGeneralName to a CERTNameConstraint list. Most
-** likely the CERTNameConstraint passed in is either the permitted
-** list or the excluded list of a CERTNameConstraints.
-*/
-SECStatus
-CERT_AddNameConstraintByGeneralName(PLArenaPool *arena,
- CERTNameConstraint **constraints,
- CERTGeneralName *name)
-{
- SECStatus rv;
- CERTNameConstraint *current = NULL;
- CERTNameConstraint *first = *constraints;
- void *mark = NULL;
-
- mark = PORT_ArenaMark(arena);
-
- current = PORT_ArenaZNew(arena, CERTNameConstraint);
- if (current == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- rv = cert_CopyOneGeneralName(arena, &current->name, name);
- if (rv != SECSuccess) {
- goto done;
- }
-
- current->name.l.prev = current->name.l.next = &(current->name.l);
-
- if (first == NULL) {
- *constraints = current;
- PR_INIT_CLIST(&current->l);
- } else {
- PR_INSERT_BEFORE(&current->l, &first->l);
- }
-
-done:
- if (rv == SECFailure) {
- PORT_ArenaRelease(arena, mark);
- } else {
- PORT_ArenaUnmark(arena, mark);
- }
- return rv;
-}
-
-/* Extract the name constraints extension from the CA cert. */
-SECStatus
-CERT_FindNameConstraintsExten(PRArenaPool *arena,
- CERTCertificate *cert,
- CERTNameConstraints **constraints)
-{
- SECStatus rv = SECSuccess;
- SECItem constraintsExtension;
- void *mark = NULL;
-
- *constraints = NULL;
-
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS,
- &constraintsExtension);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) {
- rv = SECSuccess;
- }
- return rv;
- }
-
- mark = PORT_ArenaMark(arena);
-
- *constraints = cert_DecodeNameConstraints(arena, &constraintsExtension);
- if (*constraints == NULL) { /* decode failed */
- rv = SECFailure;
- }
- PORT_Free (constraintsExtension.data);
-
- if (rv == SECFailure) {
- PORT_ArenaRelease(arena, mark);
- } else {
- PORT_ArenaUnmark(arena, mark);
- }
-
- return rv;
-}
-
-/* Verify name against all the constraints relevant to that type of
-** the name.
-*/
-SECStatus
-CERT_CheckNameSpace(PRArenaPool *arena,
- CERTNameConstraints *constraints,
- CERTGeneralName *currentName)
-{
- CERTNameConstraint *matchingConstraints;
- SECStatus rv = SECSuccess;
-
- if (constraints->excluded != NULL) {
- rv = CERT_GetNameConstraintByType(constraints->excluded,
- currentName->type,
- &matchingConstraints, arena);
- if (rv == SECSuccess && matchingConstraints != NULL) {
- rv = cert_CompareNameWithConstraints(currentName,
- matchingConstraints,
- PR_TRUE);
- }
- if (rv != SECSuccess) {
- return(rv);
- }
- }
-
- if (constraints->permited != NULL) {
- rv = CERT_GetNameConstraintByType(constraints->permited,
- currentName->type,
- &matchingConstraints, arena);
- if (rv == SECSuccess && matchingConstraints != NULL) {
- rv = cert_CompareNameWithConstraints(currentName,
- matchingConstraints,
- PR_FALSE);
- }
- if (rv != SECSuccess) {
- return(rv);
- }
- }
-
- return(SECSuccess);
-}
-
-/* Extract the name constraints extension from the CA cert.
-** Test each and every name in namesList against all the constraints
-** relevant to that type of name.
-** Returns NULL in pBadCert for success, if all names are acceptable.
-** If some name is not acceptable, returns a pointer to the cert that
-** contained that name.
-*/
-SECStatus
-CERT_CompareNameSpace(CERTCertificate *cert,
- CERTGeneralName *namesList,
- CERTCertificate **certsList,
- PRArenaPool *reqArena,
- CERTCertificate **pBadCert)
-{
- SECStatus rv = SECSuccess;
- CERTNameConstraints *constraints;
- CERTGeneralName *currentName;
- int count = 0;
- CERTCertificate *badCert = NULL;
-
- /* If no names to check, then no names can be bad. */
- if (!namesList)
- goto done;
- rv = CERT_FindNameConstraintsExten(reqArena, cert, &constraints);
- if (rv != SECSuccess) {
- count = -1;
- goto done;
- }
-
- currentName = namesList;
- do {
- if (constraints){
- rv = CERT_CheckNameSpace(reqArena, constraints, currentName);
- if (rv != SECSuccess) {
- break;
- }
- }
- currentName = CERT_GetNextGeneralName(currentName);
- count ++;
- } while (currentName != namesList);
-
-done:
- if (rv != SECSuccess) {
- badCert = (count >= 0) ? certsList[count] : cert;
- }
- if (pBadCert)
- *pBadCert = badCert;
-
- return rv;
-}
-
-#if 0
-/* not exported from shared libs, not used. Turn on if we ever need it. */
-SECStatus
-CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b)
-{
- CERTGeneralName *currentA;
- CERTGeneralName *currentB;
- PRBool found;
-
- currentA = a;
- currentB = b;
- if (a != NULL) {
- do {
- if (currentB == NULL) {
- return SECFailure;
- }
- currentB = CERT_GetNextGeneralName(currentB);
- currentA = CERT_GetNextGeneralName(currentA);
- } while (currentA != a);
- }
- if (currentB != b) {
- return SECFailure;
- }
- currentA = a;
- do {
- currentB = b;
- found = PR_FALSE;
- do {
- if (currentB->type == currentA->type) {
- switch (currentB->type) {
- case certDNSName:
- case certEDIPartyName:
- case certIPAddress:
- case certRegisterID:
- case certRFC822Name:
- case certX400Address:
- case certURI:
- if (SECITEM_CompareItem(&currentA->name.other,
- &currentB->name.other)
- == SECEqual) {
- found = PR_TRUE;
- }
- break;
- case certOtherName:
- if (SECITEM_CompareItem(&currentA->name.OthName.oid,
- &currentB->name.OthName.oid)
- == SECEqual &&
- SECITEM_CompareItem(&currentA->name.OthName.name,
- &currentB->name.OthName.name)
- == SECEqual) {
- found = PR_TRUE;
- }
- break;
- case certDirectoryName:
- if (CERT_CompareName(&currentA->name.directoryName,
- &currentB->name.directoryName)
- == SECEqual) {
- found = PR_TRUE;
- }
- }
-
- }
- currentB = CERT_GetNextGeneralName(currentB);
- } while (currentB != b && found != PR_TRUE);
- if (found != PR_TRUE) {
- return SECFailure;
- }
- currentA = CERT_GetNextGeneralName(currentA);
- } while (currentA != a);
- return SECSuccess;
-}
-
-SECStatus
-CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b)
-{
- SECStatus rv;
-
- if (a == b) {
- return SECSuccess;
- }
- if (a != NULL && b != NULL) {
- PZ_Lock(a->lock);
- PZ_Lock(b->lock);
- rv = CERT_CompareGeneralName(a->name, b->name);
- PZ_Unlock(a->lock);
- PZ_Unlock(b->lock);
- } else {
- rv = SECFailure;
- }
- return rv;
-}
-#endif
-
-#if 0
-/* This function is not exported from NSS shared libraries, and is not
-** used inside of NSS.
-** XXX it doesn't check for failed allocations. :-(
-*/
-void *
-CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
- CERTGeneralNameType type,
- PRArenaPool *arena)
-{
- CERTName *name = NULL;
- SECItem *item = NULL;
- OtherName *other = NULL;
- OtherName *tmpOther = NULL;
- void *data;
-
- PZ_Lock(list->lock);
- data = CERT_GetGeneralNameByType(list->name, type, PR_FALSE);
- if (data != NULL) {
- switch (type) {
- case certDNSName:
- case certEDIPartyName:
- case certIPAddress:
- case certRegisterID:
- case certRFC822Name:
- case certX400Address:
- case certURI:
- if (arena != NULL) {
- item = PORT_ArenaNew(arena, SECItem);
- if (item != NULL) {
-XXX SECITEM_CopyItem(arena, item, (SECItem *) data);
- }
- } else {
- item = SECITEM_DupItem((SECItem *) data);
- }
- PZ_Unlock(list->lock);
- return item;
- case certOtherName:
- other = (OtherName *) data;
- if (arena != NULL) {
- tmpOther = PORT_ArenaNew(arena, OtherName);
- } else {
- tmpOther = PORT_New(OtherName);
- }
- if (tmpOther != NULL) {
-XXX SECITEM_CopyItem(arena, &tmpOther->oid, &other->oid);
-XXX SECITEM_CopyItem(arena, &tmpOther->name, &other->name);
- }
- PZ_Unlock(list->lock);
- return tmpOther;
- case certDirectoryName:
- if (arena) {
- name = PORT_ArenaZNew(list->arena, CERTName);
- if (name) {
-XXX CERT_CopyName(arena, name, (CERTName *) data);
- }
- }
- PZ_Unlock(list->lock);
- return name;
- }
- }
- PZ_Unlock(list->lock);
- return NULL;
-}
-#endif
-
-#if 0
-/* This function is not exported from NSS shared libraries, and is not
-** used inside of NSS.
-** XXX it should NOT be a void function, since it does allocations
-** that can fail.
-*/
-void
-CERT_AddGeneralNameToList(CERTGeneralNameList *list,
- CERTGeneralNameType type,
- void *data, SECItem *oid)
-{
- CERTGeneralName *name;
-
- if (list != NULL && data != NULL) {
- PZ_Lock(list->lock);
- name = CERT_NewGeneralName(list->arena, type);
- if (!name)
- goto done;
- switch (type) {
- case certDNSName:
- case certEDIPartyName:
- case certIPAddress:
- case certRegisterID:
- case certRFC822Name:
- case certX400Address:
- case certURI:
-XXX SECITEM_CopyItem(list->arena, &name->name.other, (SECItem *)data);
- break;
- case certOtherName:
-XXX SECITEM_CopyItem(list->arena, &name->name.OthName.name,
- (SECItem *) data);
-XXX SECITEM_CopyItem(list->arena, &name->name.OthName.oid,
- oid);
- break;
- case certDirectoryName:
-XXX CERT_CopyName(list->arena, &name->name.directoryName,
- (CERTName *) data);
- break;
- }
- list->name = cert_CombineNamesLists(list->name, name);
- list->len++;
-done:
- PZ_Unlock(list->lock);
- }
- return;
-}
-#endif
diff --git a/security/nss/lib/certdb/genname.h b/security/nss/lib/certdb/genname.h
deleted file mode 100644
index 7a05d6344..000000000
--- a/security/nss/lib/certdb/genname.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _GENAME_H_
-#define _GENAME_H_
-
-#include "plarena.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "certt.h"
-
-/************************************************************************/
-SEC_BEGIN_PROTOS
-
-extern const SEC_ASN1Template CERT_GeneralNamesTemplate[];
-
-extern SECItem **
-cert_EncodeGeneralNames(PRArenaPool *arena, CERTGeneralName *names);
-
-extern CERTGeneralName *
-cert_DecodeGeneralNames(PRArenaPool *arena, SECItem **encodedGenName);
-
-extern SECStatus
-cert_DestroyGeneralNames(CERTGeneralName *name);
-
-extern SECStatus
-cert_EncodeNameConstraints(CERTNameConstraints *constraints, PRArenaPool *arena,
- SECItem *dest);
-
-extern CERTNameConstraints *
-cert_DecodeNameConstraints(PRArenaPool *arena, SECItem *encodedConstraints);
-
-extern CERTGeneralName *
-cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2);
-
-extern CERTNameConstraint *
-cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list2);
-
-/*********************************************************************/
-/* A thread safe implementation of General Names */
-/*********************************************************************/
-
-/* Destroy a Single CERTGeneralName */
-void
-CERT_DestroyGeneralName(CERTGeneralName *name);
-
-SECStatus
-CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b);
-
-SECStatus
-CERT_CopyGeneralName(PRArenaPool *arena,
- CERTGeneralName *dest,
- CERTGeneralName *src);
-
-/* General Name Lists are a thread safe, reference counting layer to
- * general names */
-
-/* Destroys a CERTGeneralNameList */
-void
-CERT_DestroyGeneralNameList(CERTGeneralNameList *list);
-
-/* Creates a CERTGeneralNameList */
-CERTGeneralNameList *
-CERT_CreateGeneralNameList(CERTGeneralName *name);
-
-/* Compares two CERTGeneralNameList */
-SECStatus
-CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b);
-
-/* returns a copy of the first name of the type requested */
-void *
-CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
- CERTGeneralNameType type,
- PRArenaPool *arena);
-
-/* Adds a name to the tail of the list */
-void
-CERT_AddGeneralNameToList(CERTGeneralNameList *list,
- CERTGeneralNameType type,
- void *data, SECItem *oid);
-
-/* returns a duplicate of the CERTGeneralNameList */
-CERTGeneralNameList *
-CERT_DupGeneralNameList(CERTGeneralNameList *list);
-
-/* returns the number of CERTGeneralName objects in the doubly linked
-** list of which *names is a member.
-*/
-extern int
-CERT_GetNamesLength(CERTGeneralName *names);
-
-/************************************************************************/
-
-SECStatus
-CERT_CompareNameSpace(CERTCertificate *cert,
- CERTGeneralName *namesList,
- CERTCertificate **certsList,
- PRArenaPool *reqArena,
- CERTCertificate **pBadCert);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/certdb/manifest.mn b/security/nss/lib/certdb/manifest.mn
deleted file mode 100644
index 181da5fba..000000000
--- a/security/nss/lib/certdb/manifest.mn
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-
-EXPORTS = \
- cert.h \
- certt.h \
- certdb.h \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- genname.h \
- xconst.h \
- certxutl.h \
- certi.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- alg1485.c \
- certdb.c \
- certv3.c \
- certxutl.c \
- crl.c \
- genname.c \
- stanpcertdb.c \
- polcyxtn.c \
- secname.c \
- xauthkid.c \
- xbsconst.c \
- xconst.c \
- $(NULL)
-
-LIBRARY_NAME = certdb
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/certdb/polcyxtn.c b/security/nss/lib/certdb/polcyxtn.c
deleted file mode 100644
index 93de0bd60..000000000
--- a/security/nss/lib/certdb/polcyxtn.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Support for various policy related extensions
- *
- * $Id$
- */
-
-#include "seccomon.h"
-#include "secport.h"
-#include "secder.h"
-#include "cert.h"
-#include "secoid.h"
-#include "secasn1.h"
-#include "secerr.h"
-#include "nspr.h"
-
-SEC_ASN1_MKSUB(SEC_IntegerTemplate)
-SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
-
-const SEC_ASN1Template CERT_DisplayTextTypeTemplate[] = {
- { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) },
- { SEC_ASN1_IA5_STRING, 0, 0, siAsciiString},
- { SEC_ASN1_VISIBLE_STRING , 0, 0, siVisibleString},
- { SEC_ASN1_BMP_STRING , 0, 0, siBMPString },
- { SEC_ASN1_UTF8_STRING , 0, 0, siUTF8String },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_NoticeReferenceTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTNoticeReference) },
- { SEC_ASN1_INLINE,
- offsetof(CERTNoticeReference, organization),
- CERT_DisplayTextTypeTemplate, 0 },
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
- offsetof(CERTNoticeReference, noticeNumbers),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_UserNoticeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTUserNotice) },
- { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
- offsetof(CERTUserNotice, noticeReference),
- CERT_NoticeReferenceTemplate, 0 },
- { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
- offsetof(CERTUserNotice, displayText),
- CERT_DisplayTextTypeTemplate, 0 },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_PolicyQualifierTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTPolicyQualifier) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTPolicyQualifier, qualifierID) },
- { SEC_ASN1_ANY,
- offsetof(CERTPolicyQualifier, qualifierValue) },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_PolicyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTPolicyInfo) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTPolicyInfo, policyID) },
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
- offsetof(CERTPolicyInfo, policyQualifiers),
- CERT_PolicyQualifierTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_CertificatePoliciesTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF,
- offsetof(CERTCertificatePolicies, policyInfos),
- CERT_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) }
-};
-
-const SEC_ASN1Template CERT_PolicyMapTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTPolicyMap) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTPolicyMap, issuerDomainPolicy) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTPolicyMap, subjectDomainPolicy) },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_PolicyMappingsTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF,
- offsetof(CERTCertificatePolicyMappings, policyMaps),
- CERT_PolicyMapTemplate, sizeof(CERTPolicyMap) }
-};
-
-const SEC_ASN1Template CERT_PolicyConstraintsTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTCertificatePolicyConstraints) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(CERTCertificatePolicyConstraints, explicitPolicySkipCerts),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- offsetof(CERTCertificatePolicyConstraints, inhibitMappingSkipCerts),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_InhibitAnyTemplate[] = {
- { SEC_ASN1_INTEGER,
- offsetof(CERTCertificateInhibitAny, inhibitAnySkipCerts),
- NULL, sizeof(CERTCertificateInhibitAny) }
-};
-
-static void
-breakLines(char *string)
-{
- char *tmpstr;
- char *lastspace = NULL;
- int curlen = 0;
- int c;
-
- tmpstr = string;
-
- while ( ( c = *tmpstr ) != '\0' ) {
- switch ( c ) {
- case ' ':
- lastspace = tmpstr;
- break;
- case '\n':
- lastspace = NULL;
- curlen = 0;
- break;
- }
-
- if ( ( curlen >= 55 ) && ( lastspace != NULL ) ) {
- *lastspace = '\n';
- curlen = ( tmpstr - lastspace );
- lastspace = NULL;
- }
-
- curlen++;
- tmpstr++;
- }
-
- return;
-}
-
-CERTCertificatePolicies *
-CERT_DecodeCertificatePoliciesExtension(SECItem *extnValue)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv;
- CERTCertificatePolicies *policies;
- CERTPolicyInfo **policyInfos, *policyInfo;
- CERTPolicyQualifier **policyQualifiers, *policyQualifier;
- SECItem newExtnValue;
-
- /* make a new arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- goto loser;
- }
-
- /* allocate the certificate policies structure */
- policies = (CERTCertificatePolicies *)
- PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicies));
-
- if ( policies == NULL ) {
- goto loser;
- }
-
- policies->arena = arena;
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* decode the policy info */
- rv = SEC_QuickDERDecodeItem(arena, policies, CERT_CertificatePoliciesTemplate,
- &newExtnValue);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* initialize the oid tags */
- policyInfos = policies->policyInfos;
- while (*policyInfos != NULL ) {
- policyInfo = *policyInfos;
- policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
- policyQualifiers = policyInfo->policyQualifiers;
- while ( policyQualifiers != NULL && *policyQualifiers != NULL ) {
- policyQualifier = *policyQualifiers;
- policyQualifier->oid =
- SECOID_FindOIDTag(&policyQualifier->qualifierID);
- policyQualifiers++;
- }
- policyInfos++;
- }
-
- return(policies);
-
-loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-void
-CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies)
-{
- if ( policies != NULL ) {
- PORT_FreeArena(policies->arena, PR_FALSE);
- }
- return;
-}
-
-CERTCertificatePolicyMappings *
-CERT_DecodePolicyMappingsExtension(SECItem *extnValue)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv;
- CERTCertificatePolicyMappings *mappings;
- SECItem newExtnValue;
-
- /* make a new arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- goto loser;
- }
-
- /* allocate the policy mappings structure */
- mappings = (CERTCertificatePolicyMappings *)
- PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicyMappings));
- if ( mappings == NULL ) {
- goto loser;
- }
- mappings->arena = arena;
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* decode the policy mappings */
- rv = SEC_QuickDERDecodeItem
- (arena, mappings, CERT_PolicyMappingsTemplate, &newExtnValue);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- return(mappings);
-
-loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-SECStatus
-CERT_DestroyPolicyMappingsExtension(CERTCertificatePolicyMappings *mappings)
-{
- if ( mappings != NULL ) {
- PORT_FreeArena(mappings->arena, PR_FALSE);
- }
- return SECSuccess;
-}
-
-SECStatus
-CERT_DecodePolicyConstraintsExtension
- (CERTCertificatePolicyConstraints *decodedValue,
- SECItem *encodedValue)
-{
- CERTCertificatePolicyConstraints decodeContext;
- PRArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
-
- /* initialize so we can tell when an optional component is omitted */
- PORT_Memset(&decodeContext, 0, sizeof(decodeContext));
-
- /* make a new arena */
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (!arena) {
- return SECFailure;
- }
-
- do {
- /* decode the policy constraints */
- rv = SEC_QuickDERDecodeItem(arena,
- &decodeContext, CERT_PolicyConstraintsTemplate, encodedValue);
-
- if ( rv != SECSuccess ) {
- break;
- }
-
- if (decodeContext.explicitPolicySkipCerts.len == 0) {
- *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data = -1;
- } else {
- *(PRInt32 *)decodedValue->explicitPolicySkipCerts.data =
- DER_GetInteger(&decodeContext.explicitPolicySkipCerts);
- }
-
- if (decodeContext.inhibitMappingSkipCerts.len == 0) {
- *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data = -1;
- } else {
- *(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data =
- DER_GetInteger(&decodeContext.inhibitMappingSkipCerts);
- }
-
- if ((*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data ==
- PR_INT32_MIN) ||
- (*(PRInt32 *)decodedValue->explicitPolicySkipCerts.data ==
- PR_INT32_MAX) ||
- (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data ==
- PR_INT32_MIN) ||
- (*(PRInt32 *)decodedValue->inhibitMappingSkipCerts.data ==
- PR_INT32_MAX)) {
- rv = SECFailure;
- }
-
- } while (0);
-
- PORT_FreeArena(arena, PR_FALSE);
- return(rv);
-}
-
-SECStatus CERT_DecodeInhibitAnyExtension
- (CERTCertificateInhibitAny *decodedValue, SECItem *encodedValue)
-{
- CERTCertificateInhibitAny decodeContext;
- PRArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
-
- /* make a new arena */
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if ( !arena ) {
- return SECFailure;
- }
-
- do {
-
- /* decode the policy mappings */
- decodeContext.inhibitAnySkipCerts.type = siUnsignedInteger;
- rv = SEC_QuickDERDecodeItem(arena,
- &decodeContext, CERT_InhibitAnyTemplate, encodedValue);
-
- if ( rv != SECSuccess ) {
- break;
- }
-
- *(PRInt32 *)decodedValue->inhibitAnySkipCerts.data =
- DER_GetInteger(&decodeContext.inhibitAnySkipCerts);
-
- } while (0);
-
- PORT_FreeArena(arena, PR_FALSE);
- return(rv);
-}
-
-CERTUserNotice *
-CERT_DecodeUserNotice(SECItem *noticeItem)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv;
- CERTUserNotice *userNotice;
- SECItem newNoticeItem;
-
- /* make a new arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- goto loser;
- }
-
- /* allocate the userNotice structure */
- userNotice = (CERTUserNotice *)PORT_ArenaZAlloc(arena,
- sizeof(CERTUserNotice));
-
- if ( userNotice == NULL ) {
- goto loser;
- }
-
- userNotice->arena = arena;
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newNoticeItem, noticeItem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* decode the user notice */
- rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate,
- &newNoticeItem);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- if (userNotice->derNoticeReference.data != NULL) {
-
- rv = SEC_QuickDERDecodeItem(arena, &userNotice->noticeReference,
- CERT_NoticeReferenceTemplate,
- &userNotice->derNoticeReference);
- if (rv == SECFailure) {
- goto loser;
- }
- }
-
- return(userNotice);
-
-loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-void
-CERT_DestroyUserNotice(CERTUserNotice *userNotice)
-{
- if ( userNotice != NULL ) {
- PORT_FreeArena(userNotice->arena, PR_FALSE);
- }
- return;
-}
-
-static CERTPolicyStringCallback policyStringCB = NULL;
-static void *policyStringCBArg = NULL;
-
-void
-CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg)
-{
- policyStringCB = cb;
- policyStringCBArg = cbarg;
- return;
-}
-
-char *
-stringFromUserNotice(SECItem *noticeItem)
-{
- SECItem *org;
- unsigned int len, headerlen;
- char *stringbuf;
- CERTUserNotice *userNotice;
- char *policystr;
- char *retstr = NULL;
- SECItem *displayText;
- SECItem **noticeNumbers;
- unsigned int strnum;
-
- /* decode the user notice */
- userNotice = CERT_DecodeUserNotice(noticeItem);
- if ( userNotice == NULL ) {
- return(NULL);
- }
-
- org = &userNotice->noticeReference.organization;
- if ( (org->len != 0 ) && ( policyStringCB != NULL ) ) {
- /* has a noticeReference */
-
- /* extract the org string */
- len = org->len;
- stringbuf = (char*)PORT_Alloc(len + 1);
- if ( stringbuf != NULL ) {
- PORT_Memcpy(stringbuf, org->data, len);
- stringbuf[len] = '\0';
-
- noticeNumbers = userNotice->noticeReference.noticeNumbers;
- while ( *noticeNumbers != NULL ) {
- /* XXX - only one byte integers right now*/
- strnum = (*noticeNumbers)->data[0];
- policystr = (* policyStringCB)(stringbuf,
- strnum,
- policyStringCBArg);
- if ( policystr != NULL ) {
- if ( retstr != NULL ) {
- retstr = PR_sprintf_append(retstr, "\n%s", policystr);
- } else {
- retstr = PR_sprintf_append(retstr, "%s", policystr);
- }
-
- PORT_Free(policystr);
- }
-
- noticeNumbers++;
- }
-
- PORT_Free(stringbuf);
- }
- }
-
- if ( retstr == NULL ) {
- if ( userNotice->displayText.len != 0 ) {
- displayText = &userNotice->displayText;
-
- if ( displayText->len > 2 ) {
- if ( displayText->data[0] == SEC_ASN1_VISIBLE_STRING ) {
- headerlen = 2;
- if ( displayText->data[1] & 0x80 ) {
- /* multibyte length */
- headerlen += ( displayText->data[1] & 0x7f );
- }
-
- len = displayText->len - headerlen;
- retstr = (char*)PORT_Alloc(len + 1);
- if ( retstr != NULL ) {
- PORT_Memcpy(retstr, &displayText->data[headerlen],len);
- retstr[len] = '\0';
- }
- }
- }
- }
- }
-
- CERT_DestroyUserNotice(userNotice);
-
- return(retstr);
-}
-
-char *
-CERT_GetCertCommentString(CERTCertificate *cert)
-{
- char *retstring = NULL;
- SECStatus rv;
- SECItem policyItem;
- CERTCertificatePolicies *policies = NULL;
- CERTPolicyInfo **policyInfos;
- CERTPolicyQualifier **policyQualifiers, *qualifier;
-
- policyItem.data = NULL;
-
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_CERTIFICATE_POLICIES,
- &policyItem);
- if ( rv != SECSuccess ) {
- goto nopolicy;
- }
-
- policies = CERT_DecodeCertificatePoliciesExtension(&policyItem);
- if ( policies == NULL ) {
- goto nopolicy;
- }
-
- policyInfos = policies->policyInfos;
- /* search through policyInfos looking for the verisign policy */
- while (*policyInfos != NULL ) {
- if ( (*policyInfos)->oid == SEC_OID_VERISIGN_USER_NOTICES ) {
- policyQualifiers = (*policyInfos)->policyQualifiers;
- /* search through the policy qualifiers looking for user notice */
- while ( policyQualifiers != NULL && *policyQualifiers != NULL ) {
- qualifier = *policyQualifiers;
- if ( qualifier->oid == SEC_OID_PKIX_USER_NOTICE_QUALIFIER ) {
- retstring =
- stringFromUserNotice(&qualifier->qualifierValue);
- break;
- }
-
- policyQualifiers++;
- }
- break;
- }
- policyInfos++;
- }
-
-nopolicy:
- if ( policyItem.data != NULL ) {
- PORT_Free(policyItem.data);
- }
-
- if ( policies != NULL ) {
- CERT_DestroyCertificatePoliciesExtension(policies);
- }
-
- if ( retstring == NULL ) {
- retstring = CERT_FindNSStringExtension(cert,
- SEC_OID_NS_CERT_EXT_COMMENT);
- }
-
- if ( retstring != NULL ) {
- breakLines(retstring);
- }
-
- return(retstring);
-}
-
-
-const SEC_ASN1Template CERT_OidSeqTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
- offsetof(CERTOidSequence, oids),
- SEC_ASN1_SUB(SEC_ObjectIDTemplate) }
-};
-
-CERTOidSequence *
-CERT_DecodeOidSequence(SECItem *seqItem)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv;
- CERTOidSequence *oidSeq;
- SECItem newSeqItem;
-
- /* make a new arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- goto loser;
- }
-
- /* allocate the userNotice structure */
- oidSeq = (CERTOidSequence *)PORT_ArenaZAlloc(arena,
- sizeof(CERTOidSequence));
-
- if ( oidSeq == NULL ) {
- goto loser;
- }
-
- oidSeq->arena = arena;
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newSeqItem, seqItem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* decode the user notice */
- rv = SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, &newSeqItem);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- return(oidSeq);
-
-loser:
- return(NULL);
-}
-
-
-void
-CERT_DestroyOidSequence(CERTOidSequence *oidSeq)
-{
- if ( oidSeq != NULL ) {
- PORT_FreeArena(oidSeq->arena, PR_FALSE);
- }
- return;
-}
-
-PRBool
-CERT_GovtApprovedBitSet(CERTCertificate *cert)
-{
- SECStatus rv;
- SECItem extItem;
- CERTOidSequence *oidSeq = NULL;
- PRBool ret;
- SECItem **oids;
- SECItem *oid;
- SECOidTag oidTag;
-
- extItem.data = NULL;
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- oidSeq = CERT_DecodeOidSequence(&extItem);
- if ( oidSeq == NULL ) {
- goto loser;
- }
-
- oids = oidSeq->oids;
- while ( oids != NULL && *oids != NULL ) {
- oid = *oids;
-
- oidTag = SECOID_FindOIDTag(oid);
-
- if ( oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED ) {
- goto success;
- }
-
- oids++;
- }
-
-loser:
- ret = PR_FALSE;
- goto done;
-success:
- ret = PR_TRUE;
-done:
- if ( oidSeq != NULL ) {
- CERT_DestroyOidSequence(oidSeq);
- }
- if (extItem.data != NULL) {
- PORT_Free(extItem.data);
- }
- return(ret);
-}
-
-
-SECStatus
-CERT_EncodePolicyConstraintsExtension(PRArenaPool *arena,
- CERTCertificatePolicyConstraints *constr,
- SECItem *dest)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(constr != NULL && dest != NULL);
- if (constr == NULL || dest == NULL) {
- return SECFailure;
- }
-
- if (SEC_ASN1EncodeItem (arena, dest, constr,
- CERT_PolicyConstraintsTemplate) == NULL) {
- rv = SECFailure;
- }
- return(rv);
-}
-
-SECStatus
-CERT_EncodePolicyMappingExtension(PRArenaPool *arena,
- CERTCertificatePolicyMappings *mapping,
- SECItem *dest)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(mapping != NULL && dest != NULL);
- if (mapping == NULL || dest == NULL) {
- return SECFailure;
- }
-
- if (SEC_ASN1EncodeItem (arena, dest, mapping,
- CERT_PolicyMappingsTemplate) == NULL) {
- rv = SECFailure;
- }
- return(rv);
-}
-
-
-
-SECStatus
-CERT_EncodeCertPoliciesExtension(PRArenaPool *arena,
- CERTPolicyInfo **info,
- SECItem *dest)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(info != NULL && dest != NULL);
- if (info == NULL || dest == NULL) {
- return SECFailure;
- }
-
- if (SEC_ASN1EncodeItem (arena, dest, info,
- CERT_CertificatePoliciesTemplate) == NULL) {
- rv = SECFailure;
- }
- return(rv);
-}
-
-SECStatus
-CERT_EncodeUserNotice(PRArenaPool *arena,
- CERTUserNotice *notice,
- SECItem *dest)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(notice != NULL && dest != NULL);
- if (notice == NULL || dest == NULL) {
- return SECFailure;
- }
-
- if (SEC_ASN1EncodeItem(arena, dest,
- notice, CERT_UserNoticeTemplate) == NULL) {
- rv = SECFailure;
- }
-
- return(rv);
-}
-
-SECStatus
-CERT_EncodeNoticeReference(PRArenaPool *arena,
- CERTNoticeReference *reference,
- SECItem *dest)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(reference != NULL && dest != NULL);
- if (reference == NULL || dest == NULL) {
- return SECFailure;
- }
-
- if (SEC_ASN1EncodeItem (arena, dest, reference,
- CERT_NoticeReferenceTemplate) == NULL) {
- rv = SECFailure;
- }
-
- return(rv);
-}
-
-SECStatus
-CERT_EncodeInhibitAnyExtension(PRArenaPool *arena,
- CERTCertificateInhibitAny *certInhibitAny,
- SECItem *dest)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(certInhibitAny != NULL && dest != NULL);
- if (certInhibitAny == NULL || dest == NULL) {
- return SECFailure;
- }
-
- if (SEC_ASN1EncodeItem (arena, dest, certInhibitAny,
- CERT_InhibitAnyTemplate) == NULL) {
- rv = SECFailure;
- }
- return(rv);
-}
diff --git a/security/nss/lib/certdb/secname.c b/security/nss/lib/certdb/secname.c
deleted file mode 100644
index 7800099f8..000000000
--- a/security/nss/lib/certdb/secname.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "cert.h"
-#include "secoid.h"
-#include "secder.h" /* XXX remove this when remove the DERTemplates */
-#include "secasn1.h"
-#include "secitem.h"
-#include <stdarg.h>
-#include "secerr.h"
-#include "certi.h"
-
-static const SEC_ASN1Template cert_AVATemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTAVA) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTAVA,type), },
- { SEC_ASN1_ANY,
- offsetof(CERTAVA,value), },
- { 0, }
-};
-
-const SEC_ASN1Template CERT_RDNTemplate[] = {
- { SEC_ASN1_SET_OF,
- offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) }
-};
-
-
-static int
-CountArray(void **array)
-{
- int count = 0;
- if (array) {
- while (*array++) {
- count++;
- }
- }
- return count;
-}
-
-static void **
-AddToArray(PRArenaPool *arena, void **array, void *element)
-{
- unsigned count;
- void **ap;
-
- /* Count up number of slots already in use in the array */
- count = 0;
- ap = array;
- if (ap) {
- while (*ap++) {
- count++;
- }
- }
-
- if (array) {
- array = (void**) PORT_ArenaGrow(arena, array,
- (count + 1) * sizeof(void *),
- (count + 2) * sizeof(void *));
- } else {
- array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
- }
- if (array) {
- array[count] = element;
- array[count+1] = 0;
- }
- return array;
-}
-
-
-SECOidTag
-CERT_GetAVATag(CERTAVA *ava)
-{
- SECOidData *oid;
- if (!ava->type.data) return (SECOidTag)-1;
-
- oid = SECOID_FindOID(&ava->type);
-
- if ( oid ) {
- return(oid->offset);
- }
- return (SECOidTag)-1;
-}
-
-static SECStatus
-SetupAVAType(PRArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp)
-{
- unsigned char *oid;
- unsigned oidLen;
- unsigned char *cp;
- int maxLen;
- SECOidData *oidrec;
-
- oidrec = SECOID_FindOIDByTag(type);
- if (oidrec == NULL)
- return SECFailure;
-
- oid = oidrec->oid.data;
- oidLen = oidrec->oid.len;
-
- maxLen = cert_AVAOidTagToMaxLen(type);
- if (maxLen < 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen);
- if (cp == NULL) {
- return SECFailure;
- }
- it->len = oidLen;
- PORT_Memcpy(cp, oid, oidLen);
- *maxLenp = (unsigned)maxLen;
- return SECSuccess;
-}
-
-static SECStatus
-SetupAVAValue(PRArenaPool *arena, int valueType, const SECItem *in,
- SECItem *out, unsigned maxLen)
-{
- PRUint8 *value, *cp, *ucs4Val;
- unsigned valueLen, valueLenLen, total;
- unsigned ucs4Len = 0, ucs4MaxLen;
-
- value = in->data;
- valueLen = in->len;
- switch (valueType) {
- case SEC_ASN1_PRINTABLE_STRING:
- case SEC_ASN1_IA5_STRING:
- case SEC_ASN1_T61_STRING:
- case SEC_ASN1_UTF8_STRING: /* no conversion required */
- break;
- case SEC_ASN1_UNIVERSAL_STRING:
- ucs4MaxLen = valueLen * 6;
- ucs4Val = (PRUint8 *)PORT_ArenaZAlloc(arena, ucs4MaxLen);
- if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, value, valueLen,
- ucs4Val, ucs4MaxLen, &ucs4Len)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- value = ucs4Val;
- valueLen = ucs4Len;
- maxLen *= 4;
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (valueLen > maxLen) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- valueLenLen = DER_LengthLength(valueLen);
- total = 1 + valueLenLen + valueLen;
- cp = (PRUint8*)PORT_ArenaAlloc(arena, total);
- if (!cp) {
- return SECFailure;
- }
- out->data = cp;
- out->len = total;
- cp = (PRUint8 *)DER_StoreHeader(cp, valueType, valueLen);
- PORT_Memcpy(cp, value, valueLen);
- return SECSuccess;
-}
-
-CERTAVA *
-CERT_CreateAVAFromRaw(PRArenaPool *pool, const SECItem * OID,
- const SECItem * value)
-{
- CERTAVA *ava;
- int rv;
-
- ava = PORT_ArenaZNew(pool, CERTAVA);
- if (ava) {
- rv = SECITEM_CopyItem(pool, &ava->type, OID);
- if (rv)
- return NULL;
-
- rv = SECITEM_CopyItem(pool, &ava->value, value);
- if (rv)
- return NULL;
- }
- return ava;
-}
-
-CERTAVA *
-CERT_CreateAVAFromSECItem(PRArenaPool *arena, SECOidTag kind, int valueType,
- SECItem *value)
-{
- CERTAVA *ava;
- int rv;
- unsigned maxLen;
-
- ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
- if (ava) {
- rv = SetupAVAType(arena, kind, &ava->type, &maxLen);
- if (rv) {
- /* Illegal AVA type */
- return NULL;
- }
- rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen);
- if (rv) {
- /* Illegal value type */
- return NULL;
- }
- }
- return ava;
-}
-
-CERTAVA *
-CERT_CreateAVA(PRArenaPool *arena, SECOidTag kind, int valueType, char *value)
-{
- SECItem item = { siBuffer, NULL, 0 };
-
- item.data = (PRUint8 *)value;
- item.len = PORT_Strlen(value);
-
- return CERT_CreateAVAFromSECItem(arena, kind, valueType, &item);
-}
-
-CERTAVA *
-CERT_CopyAVA(PRArenaPool *arena, CERTAVA *from)
-{
- CERTAVA *ava;
- int rv;
-
- ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
- if (ava) {
- rv = SECITEM_CopyItem(arena, &ava->type, &from->type);
- if (rv) goto loser;
- rv = SECITEM_CopyItem(arena, &ava->value, &from->value);
- if (rv) goto loser;
- }
- return ava;
-
- loser:
- return 0;
-}
-
-/************************************************************************/
-/* XXX This template needs to go away in favor of the new SEC_ASN1 version. */
-static const SEC_ASN1Template cert_RDNTemplate[] = {
- { SEC_ASN1_SET_OF,
- offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) }
-};
-
-
-CERTRDN *
-CERT_CreateRDN(PRArenaPool *arena, CERTAVA *ava0, ...)
-{
- CERTAVA *ava;
- CERTRDN *rdn;
- va_list ap;
- unsigned count;
- CERTAVA **avap;
-
- rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN));
- if (rdn) {
- /* Count number of avas going into the rdn */
- count = 0;
- if (ava0) {
- count++;
- va_start(ap, ava0);
- while ((ava = va_arg(ap, CERTAVA*)) != 0) {
- count++;
- }
- va_end(ap);
- }
-
- /* Now fill in the pointers */
- rdn->avas = avap =
- (CERTAVA**) PORT_ArenaAlloc( arena, (count + 1)*sizeof(CERTAVA*));
- if (!avap) {
- return 0;
- }
- if (ava0) {
- *avap++ = ava0;
- va_start(ap, ava0);
- while ((ava = va_arg(ap, CERTAVA*)) != 0) {
- *avap++ = ava;
- }
- va_end(ap);
- }
- *avap++ = 0;
- }
- return rdn;
-}
-
-SECStatus
-CERT_AddAVA(PRArenaPool *arena, CERTRDN *rdn, CERTAVA *ava)
-{
- rdn->avas = (CERTAVA**) AddToArray(arena, (void**) rdn->avas, ava);
- return rdn->avas ? SECSuccess : SECFailure;
-}
-
-SECStatus
-CERT_CopyRDN(PRArenaPool *arena, CERTRDN *to, CERTRDN *from)
-{
- CERTAVA **avas, *fava, *tava;
- SECStatus rv = SECSuccess;
-
- /* Copy each ava from from */
- avas = from->avas;
- if (avas) {
- if (avas[0] == NULL) {
- rv = CERT_AddAVA(arena, to, NULL);
- return rv;
- }
- while ((fava = *avas++) != 0) {
- tava = CERT_CopyAVA(arena, fava);
- if (!tava) {
- rv = SECFailure;
- break;
- }
- rv = CERT_AddAVA(arena, to, tava);
- if (rv != SECSuccess)
- break;
- }
- }
- return rv;
-}
-
-/************************************************************************/
-
-const SEC_ASN1Template CERT_NameTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF,
- offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate)
-
-CERTName *
-CERT_CreateName(CERTRDN *rdn0, ...)
-{
- CERTRDN *rdn;
- CERTName *name;
- va_list ap;
- unsigned count;
- CERTRDN **rdnp;
- PRArenaPool *arena;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- return(0);
- }
-
- name = (CERTName*) PORT_ArenaAlloc(arena, sizeof(CERTName));
- if (name) {
- name->arena = arena;
-
- /* Count number of RDNs going into the Name */
- if (!rdn0) {
- count = 0;
- } else {
- count = 1;
- va_start(ap, rdn0);
- while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
- count++;
- }
- va_end(ap);
- }
-
- /* Allocate space (including space for terminal null ptr) */
- name->rdns = rdnp =
- (CERTRDN**) PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN*));
- if (!name->rdns) {
- goto loser;
- }
-
- /* Now fill in the pointers */
- if (count > 0) {
- *rdnp++ = rdn0;
- va_start(ap, rdn0);
- while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
- *rdnp++ = rdn;
- }
- va_end(ap);
- }
-
- /* null terminate the list */
- *rdnp++ = 0;
- }
- return name;
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(0);
-}
-
-void
-CERT_DestroyName(CERTName *name)
-{
- if (name)
- {
- PRArenaPool *arena = name->arena;
- name->rdns = NULL;
- name->arena = NULL;
- if (arena) PORT_FreeArena(arena, PR_FALSE);
- }
-}
-
-SECStatus
-CERT_AddRDN(CERTName *name, CERTRDN *rdn)
-{
- name->rdns = (CERTRDN**) AddToArray(name->arena, (void**) name->rdns, rdn);
- return name->rdns ? SECSuccess : SECFailure;
-}
-
-SECStatus
-CERT_CopyName(PRArenaPool *arena, CERTName *to, CERTName *from)
-{
- CERTRDN **rdns, *frdn, *trdn;
- SECStatus rv = SECSuccess;
-
- if (!to || !from) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- CERT_DestroyName(to);
- to->arena = arena;
-
- /* Copy each rdn from from */
- rdns = from->rdns;
- if (rdns) {
- if (rdns[0] == NULL) {
- rv = CERT_AddRDN(to, NULL);
- return rv;
- }
- while ((frdn = *rdns++) != NULL) {
- trdn = CERT_CreateRDN(arena, NULL);
- if (!trdn) {
- rv = SECFailure;
- break;
- }
- rv = CERT_CopyRDN(arena, trdn, frdn);
- if (rv != SECSuccess)
- break;
- rv = CERT_AddRDN(to, trdn);
- if (rv != SECSuccess)
- break;
- }
- }
- return rv;
-}
-
-/************************************************************************/
-
-static void
-canonicalize(SECItem * foo)
-{
- int ch, lastch, len, src, dest;
-
- /* strip trailing whitespace. */
- len = foo->len;
- while (len > 0 && ((ch = foo->data[len - 1]) == ' ' ||
- ch == '\t' || ch == '\r' || ch == '\n')) {
- len--;
- }
-
- src = 0;
- /* strip leading whitespace. */
- while (src < len && ((ch = foo->data[src]) == ' ' ||
- ch == '\t' || ch == '\r' || ch == '\n')) {
- src++;
- }
- dest = 0; lastch = ' ';
- while (src < len) {
- ch = foo->data[src++];
- if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
- ch = ' ';
- if (ch == lastch)
- continue;
- } else if (ch >= 'A' && ch <= 'Z') {
- ch |= 0x20; /* downshift */
- }
- foo->data[dest++] = lastch = ch;
- }
- foo->len = dest;
-}
-
-/* SECItems a and b contain DER-encoded printable strings. */
-SECComparison
-CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b)
-{
- SECComparison rv = SECLessThan;
- SECItem * aVal = CERT_DecodeAVAValue(a);
- SECItem * bVal = CERT_DecodeAVAValue(b);
-
- if (aVal && aVal->len && aVal->data &&
- bVal && bVal->len && bVal->data) {
- canonicalize(aVal);
- canonicalize(bVal);
- rv = SECITEM_CompareItem(aVal, bVal);
- }
- SECITEM_FreeItem(aVal, PR_TRUE);
- SECITEM_FreeItem(bVal, PR_TRUE);
- return rv;
-}
-
-SECComparison
-CERT_CompareAVA(const CERTAVA *a, const CERTAVA *b)
-{
- SECComparison rv;
-
- rv = SECITEM_CompareItem(&a->type, &b->type);
- if (SECEqual != rv)
- return rv; /* Attribute types don't match. */
- /* Let's be optimistic. Maybe the values will just compare equal. */
- rv = SECITEM_CompareItem(&a->value, &b->value);
- if (SECEqual == rv)
- return rv; /* values compared exactly. */
- if (a->value.len && a->value.data && b->value.len && b->value.data) {
- /* Here, the values did not match.
- ** If the values had different encodings, convert them to the same
- ** encoding and compare that way.
- */
- if (a->value.data[0] != b->value.data[0]) {
- /* encodings differ. Convert both to UTF-8 and compare. */
- SECItem * aVal = CERT_DecodeAVAValue(&a->value);
- SECItem * bVal = CERT_DecodeAVAValue(&b->value);
- if (aVal && aVal->len && aVal->data &&
- bVal && bVal->len && bVal->data) {
- rv = SECITEM_CompareItem(aVal, bVal);
- }
- SECITEM_FreeItem(aVal, PR_TRUE);
- SECITEM_FreeItem(bVal, PR_TRUE);
- } else if (a->value.data[0] == 0x13) { /* both are printable strings. */
- /* printable strings */
- rv = CERT_CompareDERPrintableStrings(&a->value, &b->value);
- }
- }
- return rv;
-}
-
-SECComparison
-CERT_CompareRDN(const CERTRDN *a, const CERTRDN *b)
-{
- CERTAVA **aavas, *aava;
- CERTAVA **bavas, *bava;
- int ac, bc;
- SECComparison rv = SECEqual;
-
- aavas = a->avas;
- bavas = b->avas;
-
- /*
- ** Make sure array of ava's are the same length. If not, then we are
- ** not equal
- */
- ac = CountArray((void**) aavas);
- bc = CountArray((void**) bavas);
- if (ac < bc) return SECLessThan;
- if (ac > bc) return SECGreaterThan;
-
- while (NULL != (aava = *aavas++)) {
- for (bavas = b->avas; NULL != (bava = *bavas++); ) {
- rv = SECITEM_CompareItem(&aava->type, &bava->type);
- if (SECEqual == rv) {
- rv = CERT_CompareAVA(aava, bava);
- if (SECEqual != rv)
- return rv;
- break;
- }
- }
- if (!bava) /* didn't find a match */
- return SECGreaterThan;
- }
- return rv;
-}
-
-SECComparison
-CERT_CompareName(const CERTName *a, const CERTName *b)
-{
- CERTRDN **ardns, *ardn;
- CERTRDN **brdns, *brdn;
- int ac, bc;
- SECComparison rv = SECEqual;
-
- ardns = a->rdns;
- brdns = b->rdns;
-
- /*
- ** Make sure array of rdn's are the same length. If not, then we are
- ** not equal
- */
- ac = CountArray((void**) ardns);
- bc = CountArray((void**) brdns);
- if (ac < bc) return SECLessThan;
- if (ac > bc) return SECGreaterThan;
-
- for (;;) {
- ardn = *ardns++;
- brdn = *brdns++;
- if (!ardn) {
- break;
- }
- rv = CERT_CompareRDN(ardn, brdn);
- if (rv) return rv;
- }
- return rv;
-}
-
-/* Moved from certhtml.c */
-SECItem *
-CERT_DecodeAVAValue(const SECItem *derAVAValue)
-{
- SECItem *retItem;
- const SEC_ASN1Template *theTemplate = NULL;
- enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none;
- SECItem avaValue = {siBuffer, 0};
- PLArenaPool *newarena = NULL;
-
- if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- switch(derAVAValue->data[0]) {
- case SEC_ASN1_UNIVERSAL_STRING:
- convert = conv_ucs4;
- theTemplate = SEC_ASN1_GET(SEC_UniversalStringTemplate);
- break;
- case SEC_ASN1_IA5_STRING:
- theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
- break;
- case SEC_ASN1_PRINTABLE_STRING:
- theTemplate = SEC_ASN1_GET(SEC_PrintableStringTemplate);
- break;
- case SEC_ASN1_T61_STRING:
- /*
- * Per common practice, we're not decoding actual T.61, but instead
- * treating T61-labeled strings as containing ISO-8859-1.
- */
- convert = conv_iso88591;
- theTemplate = SEC_ASN1_GET(SEC_T61StringTemplate);
- break;
- case SEC_ASN1_BMP_STRING:
- convert = conv_ucs2;
- theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate);
- break;
- case SEC_ASN1_UTF8_STRING:
- /* No conversion needed ! */
- theTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate);
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_AVA);
- return NULL;
- }
-
- PORT_Memset(&avaValue, 0, sizeof(SECItem));
- newarena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!newarena) {
- return NULL;
- }
- if(SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue)
- != SECSuccess) {
- PORT_FreeArena(newarena, PR_FALSE);
- return NULL;
- }
-
- if (convert != conv_none) {
- unsigned int utf8ValLen = avaValue.len * 3;
- unsigned char *utf8Val = (unsigned char*)
- PORT_ArenaZAlloc(newarena, utf8ValLen);
-
- switch (convert) {
- case conv_ucs4:
- if(avaValue.len % 4 != 0 ||
- !PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
- utf8Val, utf8ValLen, &utf8ValLen)) {
- PORT_FreeArena(newarena, PR_FALSE);
- PORT_SetError(SEC_ERROR_INVALID_AVA);
- return NULL;
- }
- break;
- case conv_ucs2:
- if(avaValue.len % 2 != 0 ||
- !PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
- utf8Val, utf8ValLen, &utf8ValLen)) {
- PORT_FreeArena(newarena, PR_FALSE);
- PORT_SetError(SEC_ERROR_INVALID_AVA);
- return NULL;
- }
- break;
- case conv_iso88591:
- if(!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
- utf8Val, utf8ValLen, &utf8ValLen)) {
- PORT_FreeArena(newarena, PR_FALSE);
- PORT_SetError(SEC_ERROR_INVALID_AVA);
- return NULL;
- }
- break;
- case conv_none:
- PORT_Assert(0); /* not reached */
- break;
- }
-
- avaValue.data = utf8Val;
- avaValue.len = utf8ValLen;
- }
-
- retItem = SECITEM_DupItem(&avaValue);
- PORT_FreeArena(newarena, PR_FALSE);
- return retItem;
-}
diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c
deleted file mode 100644
index ce20b6f0b..000000000
--- a/security/nss/lib/certdb/stanpcertdb.c
+++ /dev/null
@@ -1,1071 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "prtime.h"
-
-#include "cert.h"
-#include "certi.h"
-#include "certdb.h"
-#include "secitem.h"
-#include "secder.h"
-
-/* Call to PK11_FreeSlot below */
-
-#include "secasn1.h"
-#include "secerr.h"
-#include "nssilock.h"
-#include "prmon.h"
-#include "base64.h"
-#include "sechash.h"
-#include "plhash.h"
-#include "pk11func.h" /* sigh */
-
-#include "nsspki.h"
-#include "pki.h"
-#include "pkim.h"
-#include "pki3hack.h"
-#include "ckhelper.h"
-#include "base.h"
-#include "pkistore.h"
-#include "dev3hack.h"
-#include "dev.h"
-
-PRBool
-SEC_CertNicknameConflict(const char *nickname, SECItem *derSubject,
- CERTCertDBHandle *handle)
-{
- CERTCertificate *cert;
- PRBool conflict = PR_FALSE;
-
- cert=CERT_FindCertByNickname(handle, nickname);
-
- if (!cert) {
- return conflict;
- }
-
- conflict = !SECITEM_ItemsAreEqual(derSubject,&cert->derSubject);
- CERT_DestroyCertificate(cert);
- return conflict;
-}
-
-SECStatus
-SEC_DeletePermCertificate(CERTCertificate *cert)
-{
- PRStatus nssrv;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSCertificate *c = STAN_GetNSSCertificate(cert);
- CERTCertTrust *certTrust;
-
- if (c == NULL) {
- /* error code is set */
- return SECFailure;
- }
-
- certTrust = nssTrust_GetCERTCertTrustForCert(c, cert);
- if (certTrust) {
- NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c);
- if (nssTrust) {
- nssrv = STAN_DeleteCertTrustMatchingSlot(c);
- if (nssrv != PR_SUCCESS) {
- CERT_MapStanError();
- }
- /* This call always returns PR_SUCCESS! */
- (void) nssTrust_Destroy(nssTrust);
- }
- }
-
- /* get rid of the token instances */
- nssrv = NSSCertificate_DeleteStoredObject(c, NULL);
-
- /* get rid of the cache entry */
- nssTrustDomain_LockCertCache(td);
- nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
- nssTrustDomain_UnlockCertCache(td);
-
- return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-}
-
-SECStatus
-CERT_GetCertTrust(CERTCertificate *cert, CERTCertTrust *trust)
-{
- SECStatus rv;
- CERT_LockCertTrust(cert);
- if ( cert->trust == NULL ) {
- rv = SECFailure;
- } else {
- *trust = *cert->trust;
- rv = SECSuccess;
- }
- CERT_UnlockCertTrust(cert);
- return(rv);
-}
-
-extern const NSSError NSS_ERROR_NO_ERROR;
-extern const NSSError NSS_ERROR_INTERNAL_ERROR;
-extern const NSSError NSS_ERROR_NO_MEMORY;
-extern const NSSError NSS_ERROR_INVALID_POINTER;
-extern const NSSError NSS_ERROR_INVALID_ARENA;
-extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
-extern const NSSError NSS_ERROR_DUPLICATE_POINTER;
-extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
-extern const NSSError NSS_ERROR_TRACKER_NOT_EMPTY;
-extern const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED;
-extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
-extern const NSSError NSS_ERROR_VALUE_TOO_LARGE;
-extern const NSSError NSS_ERROR_UNSUPPORTED_TYPE;
-extern const NSSError NSS_ERROR_BUFFER_TOO_SHORT;
-extern const NSSError NSS_ERROR_INVALID_ATOB_CONTEXT;
-extern const NSSError NSS_ERROR_INVALID_BASE64;
-extern const NSSError NSS_ERROR_INVALID_BTOA_CONTEXT;
-extern const NSSError NSS_ERROR_INVALID_ITEM;
-extern const NSSError NSS_ERROR_INVALID_STRING;
-extern const NSSError NSS_ERROR_INVALID_ASN1ENCODER;
-extern const NSSError NSS_ERROR_INVALID_ASN1DECODER;
-extern const NSSError NSS_ERROR_INVALID_BER;
-extern const NSSError NSS_ERROR_INVALID_ATAV;
-extern const NSSError NSS_ERROR_INVALID_ARGUMENT;
-extern const NSSError NSS_ERROR_INVALID_UTF8;
-extern const NSSError NSS_ERROR_INVALID_NSSOID;
-extern const NSSError NSS_ERROR_UNKNOWN_ATTRIBUTE;
-extern const NSSError NSS_ERROR_NOT_FOUND;
-extern const NSSError NSS_ERROR_INVALID_PASSWORD;
-extern const NSSError NSS_ERROR_USER_CANCELED;
-extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
-extern const NSSError NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND;
-extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
-extern const NSSError NSS_ERROR_HASH_COLLISION;
-extern const NSSError NSS_ERROR_DEVICE_ERROR;
-extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
-extern const NSSError NSS_ERROR_BUSY;
-extern const NSSError NSS_ERROR_ALREADY_INITIALIZED;
-extern const NSSError NSS_ERROR_PKCS11;
-
-
-/* Look at the stan error stack and map it to NSS 3 errors */
-#define STAN_MAP_ERROR(x,y) \
- else if (error == (x)) { \
- secError = y; \
- } \
-
-/*
- * map Stan errors into NSS errors
- * This function examines the stan error stack and automatically sets
- * PORT_SetError(); to the appropriate SEC_ERROR value.
- */
-void
-CERT_MapStanError()
-{
- PRInt32 *errorStack;
- NSSError error, prevError;
- int secError;
- int i;
-
- error = 0;
-
- errorStack = NSS_GetErrorStack();
- if (errorStack == 0) {
- PORT_SetError(0);
- return;
- }
- error = prevError = CKR_GENERAL_ERROR;
- /* get the 'top 2' error codes from the stack */
- for (i=0; errorStack[i]; i++) {
- prevError = error;
- error = errorStack[i];
- }
- if (error == NSS_ERROR_PKCS11) {
- /* map it */
- secError = PK11_MapError(prevError);
- }
- STAN_MAP_ERROR(NSS_ERROR_NO_ERROR, 0)
- STAN_MAP_ERROR(NSS_ERROR_NO_MEMORY, SEC_ERROR_NO_MEMORY)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_BASE64, SEC_ERROR_BAD_DATA)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_BER, SEC_ERROR_BAD_DER)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_ATAV, SEC_ERROR_INVALID_AVA)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_PASSWORD,SEC_ERROR_BAD_PASSWORD)
- STAN_MAP_ERROR(NSS_ERROR_BUSY, SEC_ERROR_BUSY)
- STAN_MAP_ERROR(NSS_ERROR_DEVICE_ERROR, SEC_ERROR_IO)
- STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND,
- SEC_ERROR_UNKNOWN_ISSUER)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_CERTIFICATE, SEC_ERROR_CERT_NOT_VALID)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_UTF8, SEC_ERROR_BAD_DATA)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_NSSOID, SEC_ERROR_BAD_DATA)
-
- /* these are library failure for lack of a better error code */
- STAN_MAP_ERROR(NSS_ERROR_NOT_FOUND, SEC_ERROR_LIBRARY_FAILURE)
- STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_IN_CACHE,
- SEC_ERROR_LIBRARY_FAILURE)
- STAN_MAP_ERROR(NSS_ERROR_MAXIMUM_FOUND, SEC_ERROR_LIBRARY_FAILURE)
- STAN_MAP_ERROR(NSS_ERROR_USER_CANCELED, SEC_ERROR_LIBRARY_FAILURE)
- STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_INITIALIZED,
- SEC_ERROR_LIBRARY_FAILURE)
- STAN_MAP_ERROR(NSS_ERROR_ALREADY_INITIALIZED, SEC_ERROR_LIBRARY_FAILURE)
- STAN_MAP_ERROR(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD,
- SEC_ERROR_LIBRARY_FAILURE)
- STAN_MAP_ERROR(NSS_ERROR_HASH_COLLISION, SEC_ERROR_LIBRARY_FAILURE)
-
- STAN_MAP_ERROR(NSS_ERROR_INTERNAL_ERROR, SEC_ERROR_LIBRARY_FAILURE)
-
- /* these are all invalid arguments */
- STAN_MAP_ERROR(NSS_ERROR_INVALID_ARGUMENT, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_POINTER, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA_MARK, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_DUPLICATE_POINTER, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_POINTER_NOT_REGISTERED, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_EMPTY, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_VALUE_TOO_LARGE, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_UNSUPPORTED_TYPE, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_BUFFER_TOO_SHORT, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_ATOB_CONTEXT, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_BTOA_CONTEXT, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_ITEM, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_STRING, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1ENCODER, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1DECODER, SEC_ERROR_INVALID_ARGS)
- STAN_MAP_ERROR(NSS_ERROR_UNKNOWN_ATTRIBUTE, SEC_ERROR_INVALID_ARGS)
- else {
- secError = SEC_ERROR_LIBRARY_FAILURE;
- }
- PORT_SetError(secError);
-}
-
-
-
-SECStatus
-CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
- CERTCertTrust *trust)
-{
- SECStatus rv = SECSuccess;
- PRStatus ret;
-
- ret = STAN_ChangeCertTrust(cert, trust);
- if (ret != PR_SUCCESS) {
- rv = SECFailure;
- CERT_MapStanError();
- }
- return rv;
-}
-
-extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
-
-SECStatus
-__CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
- CERTCertTrust *trust)
-{
- NSSUTF8 *stanNick;
- PK11SlotInfo *slot;
- NSSToken *internal;
- NSSCryptoContext *context;
- nssCryptokiObject *permInstance;
- NSSCertificate *c = STAN_GetNSSCertificate(cert);
- nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
- nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
- SECStatus rv;
- PRStatus ret;
-
- if (c == NULL) {
- CERT_MapStanError();
- return SECFailure;
- }
-
- context = c->object.cryptoContext;
- if (!context) {
- PORT_SetError(SEC_ERROR_ADDING_CERT);
- return SECFailure; /* wasn't a temp cert */
- }
- stanNick = nssCertificate_GetNickname(c, NULL);
- if (stanNick && nickname && strcmp(nickname, stanNick) != 0) {
- /* different: take the new nickname */
- cert->nickname = NULL;
- nss_ZFreeIf(stanNick);
- stanNick = NULL;
- }
- if (!stanNick && nickname) {
- /* Either there was no nickname yet, or we have a new nickname */
- stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL);
- } /* else: old stanNick is identical to new nickname */
- /* Delete the temp instance */
- nssCertificateStore_Lock(context->certStore, &lockTrace);
- nssCertificateStore_RemoveCertLOCKED(context->certStore, c);
- nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace);
- c->object.cryptoContext = NULL;
- /* Import the perm instance onto the internal token */
- slot = PK11_GetInternalKeySlot();
- internal = PK11Slot_GetNSSToken(slot);
- permInstance = nssToken_ImportCertificate(internal, NULL,
- NSSCertificateType_PKIX,
- &c->id,
- stanNick,
- &c->encoding,
- &c->issuer,
- &c->subject,
- &c->serial,
- cert->emailAddr,
- PR_TRUE);
- nss_ZFreeIf(stanNick);
- stanNick = NULL;
- PK11_FreeSlot(slot);
- if (!permInstance) {
- if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) {
- PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
- }
- return SECFailure;
- }
- nssPKIObject_AddInstance(&c->object, permInstance);
- nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
- /* reset the CERTCertificate fields */
- cert->nssCertificate = NULL;
- cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */
- if (!cert) {
- CERT_MapStanError();
- return SECFailure;
- }
- cert->istemp = PR_FALSE;
- cert->isperm = PR_TRUE;
- if (!trust) {
- return SECSuccess;
- }
- ret = STAN_ChangeCertTrust(cert, trust);
- rv = SECSuccess;
- if (ret != PR_SUCCESS) {
- rv = SECFailure;
- CERT_MapStanError();
- }
- return rv;
-}
-
-SECStatus
-CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
- CERTCertTrust *trust)
-{
- return __CERT_AddTempCertToPerm(cert, nickname, trust);
-}
-
-CERTCertificate *
-CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER)
-{
- NSSCertificate *c;
- CERTCertificate *cc;
- NSSCertificate *tempCert = NULL;
- nssPKIObject *pkio;
- NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext();
- NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain();
- if (!isperm) {
- NSSDER encoding;
- NSSITEM_FROM_SECITEM(&encoding, derCert);
- /* First, see if it is already a temp cert */
- c = NSSCryptoContext_FindCertificateByEncodedCertificate(gCC,
- &encoding);
- if (!c) {
- /* Then, see if it is already a perm cert */
- c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle,
- &encoding);
- }
- if (c) {
- /* actually, that search ends up going by issuer/serial,
- * so it is still possible to return a cert with the same
- * issuer/serial but a different encoding, and we're
- * going to reject that
- */
- if (!nssItem_Equal(&c->encoding, &encoding, NULL)) {
- nssCertificate_Destroy(c);
- PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
- cc = NULL;
- } else {
- cc = STAN_GetCERTCertificateOrRelease(c);
- if (cc == NULL) {
- CERT_MapStanError();
- }
- }
- return cc;
- }
- }
- pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC, nssPKIMonitor);
- if (!pkio) {
- CERT_MapStanError();
- return NULL;
- }
- c = nss_ZNEW(pkio->arena, NSSCertificate);
- if (!c) {
- CERT_MapStanError();
- nssPKIObject_Destroy(pkio);
- return NULL;
- }
- c->object = *pkio;
- if (copyDER) {
- nssItem_Create(c->object.arena, &c->encoding,
- derCert->len, derCert->data);
- } else {
- NSSITEM_FROM_SECITEM(&c->encoding, derCert);
- }
- /* Forces a decoding of the cert in order to obtain the parts used
- * below
- */
- /* 'c' is not adopted here, if we fail loser frees what has been
- * allocated so far for 'c' */
- cc = STAN_GetCERTCertificate(c);
- if (!cc) {
- CERT_MapStanError();
- goto loser;
- }
- nssItem_Create(c->object.arena,
- &c->issuer, cc->derIssuer.len, cc->derIssuer.data);
- nssItem_Create(c->object.arena,
- &c->subject, cc->derSubject.len, cc->derSubject.data);
- if (PR_TRUE) {
- /* CERTCertificate stores serial numbers decoded. I need the DER
- * here. sigh.
- */
- SECItem derSerial = { 0 };
- CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
- if (!derSerial.data) goto loser;
- nssItem_Create(c->object.arena, &c->serial, derSerial.len, derSerial.data);
- PORT_Free(derSerial.data);
- }
- if (nickname) {
- c->object.tempName = nssUTF8_Create(c->object.arena,
- nssStringType_UTF8String,
- (NSSUTF8 *)nickname,
- PORT_Strlen(nickname));
- }
- if (cc->emailAddr && cc->emailAddr[0]) {
- c->email = nssUTF8_Create(c->object.arena,
- nssStringType_PrintableString,
- (NSSUTF8 *)cc->emailAddr,
- PORT_Strlen(cc->emailAddr));
- }
-
- tempCert = NSSCryptoContext_FindOrImportCertificate(gCC, c);
- if (!tempCert) {
- CERT_MapStanError();
- goto loser;
- }
- /* destroy our copy */
- NSSCertificate_Destroy(c);
- /* and use the stored entry */
- c = tempCert;
- cc = STAN_GetCERTCertificateOrRelease(c);
- if (!cc) {
- /* STAN_GetCERTCertificateOrRelease destroys c on failure. */
- CERT_MapStanError();
- return NULL;
- }
-
- cc->istemp = PR_TRUE;
- cc->isperm = PR_FALSE;
- return cc;
-loser:
- /* Perhaps this should be nssCertificate_Destroy(c) */
- nssPKIObject_Destroy(&c->object);
- return NULL;
-}
-
-/* This symbol is exported for backward compatibility. */
-CERTCertificate *
-__CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER)
-{
- return CERT_NewTempCertificate(handle, derCert, nickname,
- isperm, copyDER);
-}
-
-/* maybe all the wincx's should be some const for internal token login? */
-CERTCertificate *
-CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN)
-{
- PK11SlotInfo *slot;
- CERTCertificate *cert;
-
- cert = PK11_FindCertByIssuerAndSN(&slot,issuerAndSN,NULL);
- if (cert && slot) {
- PK11_FreeSlot(slot);
- }
-
- return cert;
-}
-
-static NSSCertificate *
-get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp)
-{
- NSSUsage usage;
- NSSCertificate *arr[3];
- if (!ct) {
- return nssCertificate_AddRef(cp);
- } else if (!cp) {
- return nssCertificate_AddRef(ct);
- }
- arr[0] = ct;
- arr[1] = cp;
- arr[2] = NULL;
- usage.anyUsage = PR_TRUE;
- return nssCertificateArray_FindBestCertificate(arr, NULL, &usage, NULL);
-}
-
-CERTCertificate *
-CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name)
-{
- NSSCertificate *cp, *ct, *c;
- NSSDER subject;
- NSSUsage usage;
- NSSCryptoContext *cc;
- NSSITEM_FROM_SECITEM(&subject, name);
- usage.anyUsage = PR_TRUE;
- cc = STAN_GetDefaultCryptoContext();
- ct = NSSCryptoContext_FindBestCertificateBySubject(cc, &subject,
- NULL, &usage, NULL);
- cp = NSSTrustDomain_FindBestCertificateBySubject(handle, &subject,
- NULL, &usage, NULL);
- c = get_best_temp_or_perm(ct, cp);
- if (ct) {
- CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
- }
- if (cp) {
- CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(cp));
- }
- return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
-}
-
-CERTCertificate *
-CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID)
-{
- CERTCertList *list;
- CERTCertificate *cert = NULL;
- CERTCertListNode *node, *head;
-
- list = CERT_CreateSubjectCertList(NULL,handle,name,0,PR_FALSE);
- if (list == NULL) return NULL;
-
- node = head = CERT_LIST_HEAD(list);
- if (head) {
- do {
- if (node->cert &&
- SECITEM_ItemsAreEqual(&node->cert->subjectKeyID, keyID) ) {
- cert = CERT_DupCertificate(node->cert);
- goto done;
- }
- node = CERT_LIST_NEXT(node);
- } while (node && head != node);
- }
- PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
-done:
- if (list) {
- CERT_DestroyCertList(list);
- }
- return cert;
-}
-
-CERTCertificate *
-CERT_FindCertByNickname(CERTCertDBHandle *handle, const char *nickname)
-{
- NSSCryptoContext *cc;
- NSSCertificate *c, *ct;
- CERTCertificate *cert;
- NSSUsage usage;
- usage.anyUsage = PR_TRUE;
- cc = STAN_GetDefaultCryptoContext();
- ct = NSSCryptoContext_FindBestCertificateByNickname(cc, nickname,
- NULL, &usage, NULL);
- cert = PK11_FindCertFromNickname(nickname, NULL);
- c = NULL;
- if (cert) {
- c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
- CERT_DestroyCertificate(cert);
- if (ct) {
- CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
- }
- } else {
- c = ct;
- }
- return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
-}
-
-CERTCertificate *
-CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert)
-{
- NSSCryptoContext *cc;
- NSSCertificate *c;
- NSSDER encoding;
- NSSITEM_FROM_SECITEM(&encoding, derCert);
- cc = STAN_GetDefaultCryptoContext();
- c = NSSCryptoContext_FindCertificateByEncodedCertificate(cc, &encoding);
- if (!c) {
- c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle,
- &encoding);
- if (!c) return NULL;
- }
- return STAN_GetCERTCertificateOrRelease(c);
-}
-
-static CERTCertificate *
-common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
- const char *name,
- PRBool anyUsage,
- SECCertUsage lookingForUsage)
-{
- NSSCryptoContext *cc;
- NSSCertificate *c, *ct;
- CERTCertificate *cert = NULL;
- NSSUsage usage;
- CERTCertList *certlist;
-
- if (NULL == name) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- usage.anyUsage = anyUsage;
-
- if (!anyUsage) {
- usage.nss3lookingForCA = PR_FALSE;
- usage.nss3usage = lookingForUsage;
- }
-
- cc = STAN_GetDefaultCryptoContext();
- ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name,
- NULL, &usage, NULL);
- if (!ct && PORT_Strchr(name, '@') != NULL) {
- char* lowercaseName = CERT_FixupEmailAddr(name);
- if (lowercaseName) {
- ct = NSSCryptoContext_FindBestCertificateByEmail(cc, lowercaseName,
- NULL, &usage, NULL);
- PORT_Free(lowercaseName);
- }
- }
-
- if (anyUsage) {
- cert = PK11_FindCertFromNickname(name, NULL);
- }
- else {
- if (ct) {
- /* Does ct really have the required usage? */
- nssDecodedCert *dc;
- dc = nssCertificate_GetDecoding(ct);
- if (!dc->matchUsage(dc, &usage)) {
- CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
- ct = NULL;
- }
- }
-
- certlist = PK11_FindCertsFromNickname(name, NULL);
- if (certlist) {
- SECStatus rv = CERT_FilterCertListByUsage(certlist,
- lookingForUsage,
- PR_FALSE);
- if (SECSuccess == rv &&
- !CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) {
- cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert);
- }
- CERT_DestroyCertList(certlist);
- }
- }
-
- if (cert) {
- c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
- CERT_DestroyCertificate(cert);
- if (ct) {
- CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
- }
- } else {
- c = ct;
- }
- return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
-}
-
-CERTCertificate *
-CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name)
-{
- return common_FindCertByNicknameOrEmailAddrForUsage(handle, name,
- PR_TRUE, 0);
-}
-
-CERTCertificate *
-CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
- const char *name,
- SECCertUsage lookingForUsage)
-{
- return common_FindCertByNicknameOrEmailAddrForUsage(handle, name,
- PR_FALSE,
- lookingForUsage);
-}
-
-static void
-add_to_subject_list(CERTCertList *certList, CERTCertificate *cert,
- PRBool validOnly, int64 sorttime)
-{
- SECStatus secrv;
- if (!validOnly ||
- CERT_CheckCertValidTimes(cert, sorttime, PR_FALSE)
- == secCertTimeValid) {
- secrv = CERT_AddCertToListSorted(certList, cert,
- CERT_SortCBValidity,
- (void *)&sorttime);
- if (secrv != SECSuccess) {
- CERT_DestroyCertificate(cert);
- }
- } else {
- CERT_DestroyCertificate(cert);
- }
-}
-
-CERTCertList *
-CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle,
- SECItem *name, int64 sorttime, PRBool validOnly)
-{
- NSSCryptoContext *cc;
- NSSCertificate **tSubjectCerts, **pSubjectCerts;
- NSSCertificate **ci;
- CERTCertificate *cert;
- NSSDER subject;
- PRBool myList = PR_FALSE;
- cc = STAN_GetDefaultCryptoContext();
- NSSITEM_FROM_SECITEM(&subject, name);
- /* Collect both temp and perm certs for the subject */
- tSubjectCerts = NSSCryptoContext_FindCertificatesBySubject(cc,
- &subject,
- NULL,
- 0,
- NULL);
- pSubjectCerts = NSSTrustDomain_FindCertificatesBySubject(handle,
- &subject,
- NULL,
- 0,
- NULL);
- if (!tSubjectCerts && !pSubjectCerts) {
- return NULL;
- }
- if (certList == NULL) {
- certList = CERT_NewCertList();
- myList = PR_TRUE;
- if (!certList) goto loser;
- }
- /* Iterate over the matching temp certs. Add them to the list */
- ci = tSubjectCerts;
- while (ci && *ci) {
- cert = STAN_GetCERTCertificateOrRelease(*ci);
- /* *ci may be invalid at this point, don't reference it again */
- if (cert) {
- /* NOTE: add_to_subject_list adopts the incoming cert. */
- add_to_subject_list(certList, cert, validOnly, sorttime);
- }
- ci++;
- }
- /* Iterate over the matching perm certs. Add them to the list */
- ci = pSubjectCerts;
- while (ci && *ci) {
- cert = STAN_GetCERTCertificateOrRelease(*ci);
- /* *ci may be invalid at this point, don't reference it again */
- if (cert) {
- /* NOTE: add_to_subject_list adopts the incoming cert. */
- add_to_subject_list(certList, cert, validOnly, sorttime);
- }
- ci++;
- }
- /* all the references have been adopted or freed at this point, just
- * free the arrays now */
- nss_ZFreeIf(tSubjectCerts);
- nss_ZFreeIf(pSubjectCerts);
- return certList;
-loser:
- /* need to free the references in tSubjectCerts and pSubjectCerts! */
- nssCertificateArray_Destroy(tSubjectCerts);
- nssCertificateArray_Destroy(pSubjectCerts);
- if (myList && certList != NULL) {
- CERT_DestroyCertList(certList);
- }
- return NULL;
-}
-
-void
-CERT_DestroyCertificate(CERTCertificate *cert)
-{
- if ( cert ) {
- /* don't use STAN_GetNSSCertificate because we don't want to
- * go to the trouble of translating the CERTCertificate into
- * an NSSCertificate just to destroy it. If it hasn't been done
- * yet, don't do it at all.
- */
- NSSCertificate *tmp = cert->nssCertificate;
- if (tmp) {
- /* delete the NSSCertificate */
- NSSCertificate_Destroy(tmp);
- } else if (cert->arena) {
- PORT_FreeArena(cert->arena, PR_FALSE);
- }
- }
- return;
-}
-
-int
-CERT_GetDBContentVersion(CERTCertDBHandle *handle)
-{
- /* should read the DB content version from the pkcs #11 device */
- return 0;
-}
-
-SECStatus
-certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr,
- SECItem *emailProfile, SECItem *profileTime)
-{
- int64 oldtime;
- int64 newtime;
- SECStatus rv = SECFailure;
- PRBool saveit;
- SECItem oldprof, oldproftime;
- SECItem *oldProfile = NULL;
- SECItem *oldProfileTime = NULL;
- PK11SlotInfo *slot = NULL;
- NSSCertificate *c;
- NSSCryptoContext *cc;
- nssSMIMEProfile *stanProfile = NULL;
- PRBool freeOldProfile = PR_FALSE;
-
- c = STAN_GetNSSCertificate(cert);
- if (!c) return SECFailure;
- cc = c->object.cryptoContext;
- if (cc != NULL) {
- stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c);
- if (stanProfile) {
- PORT_Assert(stanProfile->profileData);
- SECITEM_FROM_NSSITEM(&oldprof, stanProfile->profileData);
- oldProfile = &oldprof;
- SECITEM_FROM_NSSITEM(&oldproftime, stanProfile->profileTime);
- oldProfileTime = &oldproftime;
- }
- } else {
- oldProfile = PK11_FindSMimeProfile(&slot, (char *)emailAddr,
- &cert->derSubject, &oldProfileTime);
- freeOldProfile = PR_TRUE;
- }
-
- saveit = PR_FALSE;
-
- /* both profileTime and emailProfile have to exist or not exist */
- if ( emailProfile == NULL ) {
- profileTime = NULL;
- } else if ( profileTime == NULL ) {
- emailProfile = NULL;
- }
-
- if ( oldProfileTime == NULL ) {
- saveit = PR_TRUE;
- } else {
- /* there was already a profile for this email addr */
- if ( profileTime ) {
- /* we have an old and new profile - save whichever is more recent*/
- if ( oldProfileTime->len == 0 ) {
- /* always replace if old entry doesn't have a time */
- oldtime = LL_MININT;
- } else {
- rv = DER_UTCTimeToTime(&oldtime, oldProfileTime);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- rv = DER_UTCTimeToTime(&newtime, profileTime);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- if ( LL_CMP(newtime, >, oldtime ) ) {
- /* this is a newer profile, save it and cert */
- saveit = PR_TRUE;
- }
- } else {
- saveit = PR_TRUE;
- }
- }
-
-
- if (saveit) {
- if (cc) {
- if (stanProfile) {
- /* stanProfile is already stored in the crypto context,
- * overwrite the data
- */
- NSSArena *arena = stanProfile->object.arena;
- stanProfile->profileTime = nssItem_Create(arena,
- NULL,
- profileTime->len,
- profileTime->data);
- stanProfile->profileData = nssItem_Create(arena,
- NULL,
- emailProfile->len,
- emailProfile->data);
- } else if (profileTime && emailProfile) {
- PRStatus nssrv;
- NSSItem profTime, profData;
- NSSITEM_FROM_SECITEM(&profTime, profileTime);
- NSSITEM_FROM_SECITEM(&profData, emailProfile);
- stanProfile = nssSMIMEProfile_Create(c, &profTime, &profData);
- if (!stanProfile) goto loser;
- nssrv = nssCryptoContext_ImportSMIMEProfile(cc, stanProfile);
- rv = (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
- }
- } else {
- rv = PK11_SaveSMimeProfile(slot, (char *)emailAddr,
- &cert->derSubject, emailProfile, profileTime);
- }
- } else {
- rv = SECSuccess;
- }
-
-loser:
- if (oldProfile && freeOldProfile) {
- SECITEM_FreeItem(oldProfile,PR_TRUE);
- }
- if (oldProfileTime && freeOldProfile) {
- SECITEM_FreeItem(oldProfileTime,PR_TRUE);
- }
- if (stanProfile) {
- nssSMIMEProfile_Destroy(stanProfile);
- }
- if (slot) {
- PK11_FreeSlot(slot);
- }
-
- return(rv);
-}
-
-/*
- *
- * Manage S/MIME profiles
- *
- */
-
-SECStatus
-CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
- SECItem *profileTime)
-{
- const char *emailAddr;
- SECStatus rv;
-
- if (!cert) {
- return SECFailure;
- }
-
- if (cert->slot && !PK11_IsInternal(cert->slot)) {
- /* this cert comes from an external source, we need to add it
- to the cert db before creating an S/MIME profile */
- PK11SlotInfo* internalslot = PK11_GetInternalKeySlot();
- if (!internalslot) {
- return SECFailure;
- }
- rv = PK11_ImportCert(internalslot, cert,
- CK_INVALID_HANDLE, NULL, PR_FALSE);
-
- PK11_FreeSlot(internalslot);
- if (rv != SECSuccess ) {
- return SECFailure;
- }
- }
-
- if (cert->slot && cert->isperm && CERT_IsUserCert(cert) &&
- (!emailProfile || !emailProfile->len)) {
- /* Don't clobber emailProfile for user certs. */
- return SECSuccess;
- }
-
- for (emailAddr = CERT_GetFirstEmailAddress(cert); emailAddr != NULL;
- emailAddr = CERT_GetNextEmailAddress(cert,emailAddr)) {
- rv = certdb_SaveSingleProfile(cert,emailAddr,emailProfile,profileTime);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- }
- return SECSuccess;
-
-}
-
-
-SECItem *
-CERT_FindSMimeProfile(CERTCertificate *cert)
-{
- PK11SlotInfo *slot = NULL;
- NSSCertificate *c;
- NSSCryptoContext *cc;
- SECItem *rvItem = NULL;
-
- if (!cert || !cert->emailAddr || !cert->emailAddr[0]) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- c = STAN_GetNSSCertificate(cert);
- if (!c) return NULL;
- cc = c->object.cryptoContext;
- if (cc != NULL) {
- nssSMIMEProfile *stanProfile;
- stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c);
- if (stanProfile) {
- rvItem = SECITEM_AllocItem(NULL, NULL,
- stanProfile->profileData->size);
- if (rvItem) {
- rvItem->data = stanProfile->profileData->data;
- }
- nssSMIMEProfile_Destroy(stanProfile);
- }
- return rvItem;
- }
- rvItem =
- PK11_FindSMimeProfile(&slot, cert->emailAddr, &cert->derSubject, NULL);
- if (slot) {
- PK11_FreeSlot(slot);
- }
- return rvItem;
-}
-
-/*
- * deprecated functions that are now just stubs.
- */
-/*
- * Close the database
- */
-void
-__CERT_ClosePermCertDB(CERTCertDBHandle *handle)
-{
- PORT_Assert("CERT_ClosePermCertDB is Deprecated" == NULL);
- return;
-}
-
-SECStatus
-CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname,
- PRBool readOnly)
-{
- PORT_Assert("CERT_OpenCertDBFilename is Deprecated" == NULL);
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-SECItem *
-SECKEY_HashPassword(char *pw, SECItem *salt)
-{
- PORT_Assert("SECKEY_HashPassword is Deprecated" == NULL);
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
-}
-
-SECStatus
-__CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle,
- SECItem *derSubject,
- void *cb, void *cbarg)
-{
- PORT_Assert("CERT_TraversePermCertsForSubject is Deprecated" == NULL);
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-
-SECStatus
-__CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
- void *cb, void *cbarg)
-{
- PORT_Assert("CERT_TraversePermCertsForNickname is Deprecated" == NULL);
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-
-
diff --git a/security/nss/lib/certdb/xauthkid.c b/security/nss/lib/certdb/xauthkid.c
deleted file mode 100644
index 462d22349..000000000
--- a/security/nss/lib/certdb/xauthkid.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * X.509 v3 Subject Key Usage Extension
- *
- */
-
-#include "prtypes.h"
-#include "seccomon.h"
-#include "secdert.h"
-#include "secoidt.h"
-#include "secasn1t.h"
-#include "secasn1.h"
-#include "secport.h"
-#include "certt.h"
-#include "genname.h"
-#include "secerr.h"
-
-SEC_ASN1_MKSUB(SEC_IntegerTemplate)
-SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
-
-const SEC_ASN1Template CERTAuthKeyIDTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(CERTAuthKeyID,keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate)},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
- offsetof(CERTAuthKeyID,authCertSerialNumber),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { 0 }
-};
-
-
-
-SECStatus CERT_EncodeAuthKeyID (PRArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue)
-{
- SECStatus rv = SECFailure;
-
- PORT_Assert (value);
- PORT_Assert (arena);
- PORT_Assert (value->DERAuthCertIssuer == NULL);
- PORT_Assert (encodedValue);
-
- do {
-
- /* If both of the authCertIssuer and the serial number exist, encode
- the name first. Otherwise, it is an error if one exist and the other
- is not.
- */
- if (value->authCertIssuer) {
- if (!value->authCertSerialNumber.data) {
- PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
- break;
- }
-
- value->DERAuthCertIssuer = cert_EncodeGeneralNames
- (arena, value->authCertIssuer);
- if (!value->DERAuthCertIssuer) {
- PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
- break;
- }
- }
- else if (value->authCertSerialNumber.data) {
- PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
- break;
- }
-
- if (SEC_ASN1EncodeItem (arena, encodedValue, value,
- CERTAuthKeyIDTemplate) == NULL)
- break;
- rv = SECSuccess;
-
- } while (0);
- return(rv);
-}
-
-CERTAuthKeyID *
-CERT_DecodeAuthKeyID (PRArenaPool *arena, SECItem *encodedValue)
-{
- CERTAuthKeyID * value = NULL;
- SECStatus rv = SECFailure;
- void * mark;
- SECItem newEncodedValue;
-
- PORT_Assert (arena);
-
- do {
- mark = PORT_ArenaMark (arena);
- value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value));
- if (value == NULL)
- break;
- value->DERAuthCertIssuer = NULL;
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
- if ( rv != SECSuccess ) {
- break;
- }
-
- rv = SEC_QuickDERDecodeItem
- (arena, value, CERTAuthKeyIDTemplate, &newEncodedValue);
- if (rv != SECSuccess)
- break;
-
- value->authCertIssuer = cert_DecodeGeneralNames (arena, value->DERAuthCertIssuer);
- if (value->authCertIssuer == NULL)
- break;
-
- /* what if the general name contains other format but not URI ?
- hl
- */
- if ((value->authCertSerialNumber.data && !value->authCertIssuer) ||
- (!value->authCertSerialNumber.data && value->authCertIssuer)){
- PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
- break;
- }
- } while (0);
-
- if (rv != SECSuccess) {
- PORT_ArenaRelease (arena, mark);
- return ((CERTAuthKeyID *)NULL);
- }
- PORT_ArenaUnmark(arena, mark);
- return (value);
-}
diff --git a/security/nss/lib/certdb/xbsconst.c b/security/nss/lib/certdb/xbsconst.c
deleted file mode 100644
index 41bf3c537..000000000
--- a/security/nss/lib/certdb/xbsconst.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * X.509 v3 Basic Constraints Extension
- */
-
-#include "prtypes.h"
-#include <limits.h> /* for LONG_MAX */
-#include "seccomon.h"
-#include "secdert.h"
-#include "secoidt.h"
-#include "secasn1t.h"
-#include "secasn1.h"
-#include "certt.h"
-#include "secder.h"
-#include "prprf.h"
-#include "secerr.h"
-
-typedef struct EncodedContext{
- SECItem isCA;
- SECItem pathLenConstraint;
- SECItem encodedValue;
- PRArenaPool *arena;
-}EncodedContext;
-
-static const SEC_ASN1Template CERTBasicConstraintsTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(EncodedContext) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
- offsetof(EncodedContext,isCA)},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
- offsetof(EncodedContext,pathLenConstraint) },
- { 0, }
-};
-
-static unsigned char hexTrue = 0xff;
-static unsigned char hexFalse = 0x00;
-
-#define GEN_BREAK(status) rv = status; break;
-
-SECStatus CERT_EncodeBasicConstraintValue
- (PRArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue)
-{
- EncodedContext encodeContext;
- PRArenaPool *our_pool = NULL;
- SECStatus rv = SECSuccess;
-
- do {
- PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
- if (!value->isCA && value->pathLenConstraint >= 0) {
- PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
- GEN_BREAK (SECFailure);
- }
-
- encodeContext.arena = arena;
- if (value->isCA == PR_TRUE) {
- encodeContext.isCA.data = &hexTrue ;
- encodeContext.isCA.len = 1;
- }
-
- /* If the pathLenConstraint is less than 0, then it should be
- * omitted from the encoding.
- */
- if (value->isCA && value->pathLenConstraint >= 0) {
- our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (our_pool == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- GEN_BREAK (SECFailure);
- }
- if (SEC_ASN1EncodeUnsignedInteger
- (our_pool, &encodeContext.pathLenConstraint,
- (unsigned long)value->pathLenConstraint) == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- GEN_BREAK (SECFailure);
- }
- }
- if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
- CERTBasicConstraintsTemplate) == NULL) {
- GEN_BREAK (SECFailure);
- }
- } while (0);
- if (our_pool)
- PORT_FreeArena (our_pool, PR_FALSE);
- return(rv);
-
-}
-
-SECStatus CERT_DecodeBasicConstraintValue
- (CERTBasicConstraints *value, SECItem *encodedValue)
-{
- EncodedContext decodeContext;
- PRArenaPool *our_pool;
- SECStatus rv = SECSuccess;
-
- do {
- PORT_Memset (&decodeContext, 0, sizeof (decodeContext));
- /* initialize the value just in case we got "0x30 00", or when the
- pathLenConstraint is omitted.
- */
- decodeContext.isCA.data =&hexFalse;
- decodeContext.isCA.len = 1;
-
- our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (our_pool == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- GEN_BREAK (SECFailure);
- }
-
- rv = SEC_QuickDERDecodeItem
- (our_pool, &decodeContext, CERTBasicConstraintsTemplate, encodedValue);
- if (rv == SECFailure)
- break;
-
- value->isCA = decodeContext.isCA.data
- ? (PRBool)(decodeContext.isCA.data[0] != 0)
- : PR_FALSE;
- if (decodeContext.pathLenConstraint.data == NULL) {
- /* if the pathLenConstraint is not encoded, and the current setting
- is CA, then the pathLenConstraint should be set to a negative number
- for unlimited certificate path.
- */
- if (value->isCA)
- value->pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
- } else if (value->isCA) {
- long len = DER_GetInteger (&decodeContext.pathLenConstraint);
- if (len < 0 || len == LONG_MAX) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- GEN_BREAK (SECFailure);
- }
- value->pathLenConstraint = len;
- } else {
- /* here we get an error where the subject is not a CA, but
- the pathLenConstraint is set */
- PORT_SetError (SEC_ERROR_BAD_DER);
- GEN_BREAK (SECFailure);
- break;
- }
-
- } while (0);
- PORT_FreeArena (our_pool, PR_FALSE);
- return (rv);
-
-}
diff --git a/security/nss/lib/certdb/xconst.c b/security/nss/lib/certdb/xconst.c
deleted file mode 100644
index 327b7ddc4..000000000
--- a/security/nss/lib/certdb/xconst.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * X.509 Extension Encoding
- */
-
-#include "prtypes.h"
-#include "seccomon.h"
-#include "secdert.h"
-#include "secoidt.h"
-#include "secasn1t.h"
-#include "secasn1.h"
-#include "cert.h"
-#include "secder.h"
-#include "prprf.h"
-#include "xconst.h"
-#include "genname.h"
-#include "secasn1.h"
-#include "secerr.h"
-
-
-static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
- { SEC_ASN1_OCTET_STRING }
-};
-
-
-static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
- { SEC_ASN1_IA5_STRING }
-};
-
-SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
-
-static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(CERTPrivKeyUsagePeriod, notBefore),
- SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- offsetof(CERTPrivKeyUsagePeriod, notAfter),
- SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate)},
- { 0, }
-};
-
-
-const SEC_ASN1Template CERTAltNameTemplate[] = {
- { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
- CERT_GeneralNamesTemplate}
-};
-
-const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTAuthInfoAccess) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTAuthInfoAccess, method) },
- { SEC_ASN1_ANY,
- offsetof(CERTAuthInfoAccess, derLocation) },
- { 0, }
-};
-
-const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
-};
-
-
-SECStatus
-CERT_EncodeSubjectKeyID(PRArenaPool *arena, const SECItem* srcString,
- SECItem *encodedValue)
-{
- SECStatus rv = SECSuccess;
-
- if (!srcString) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (SEC_ASN1EncodeItem (arena, encodedValue, srcString,
- CERTSubjectKeyIDTemplate) == NULL) {
- rv = SECFailure;
- }
-
- return(rv);
-}
-
-
-SECStatus
-CERT_EncodePrivateKeyUsagePeriod(PRArenaPool *arena,
- CERTPrivKeyUsagePeriod *pkup,
- SECItem *encodedValue)
-{
- SECStatus rv = SECSuccess;
-
- if (SEC_ASN1EncodeItem (arena, encodedValue, pkup,
- CERTPrivateKeyUsagePeriodTemplate) == NULL) {
- rv = SECFailure;
- }
- return(rv);
-}
-
-CERTPrivKeyUsagePeriod *
-CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
-{
- SECStatus rv;
- CERTPrivKeyUsagePeriod *pPeriod;
- SECItem newExtnValue;
-
- /* allocate the certificate policies structure */
- pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
- if ( pPeriod == NULL ) {
- goto loser;
- }
-
- pPeriod->arena = arena;
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, pPeriod,
- CERTPrivateKeyUsagePeriodTemplate,
- &newExtnValue);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- return pPeriod;
-
-loser:
- return NULL;
-}
-
-
-SECStatus
-CERT_EncodeIA5TypeExtension(PRArenaPool *arena, char *value, SECItem *encodedValue)
-{
- SECItem encodeContext;
- SECStatus rv = SECSuccess;
-
-
- PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
-
- if (value != NULL) {
- encodeContext.data = (unsigned char *)value;
- encodeContext.len = strlen(value);
- }
- if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
- CERTIA5TypeTemplate) == NULL) {
- rv = SECFailure;
- }
-
- return(rv);
-}
-
-SECStatus
-CERT_EncodeAltNameExtension(PRArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue)
-{
- SECItem **encodedGenName;
- SECStatus rv = SECSuccess;
-
- encodedGenName = cert_EncodeGeneralNames(arena, value);
- if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName,
- CERT_GeneralNamesTemplate) == NULL) {
- rv = SECFailure;
- }
-
- return rv;
-}
-
-CERTGeneralName *
-CERT_DecodeAltNameExtension(PRArenaPool *reqArena, SECItem *EncodedAltName)
-{
- SECStatus rv = SECSuccess;
- CERTAltNameEncodedContext encodedContext;
- SECItem* newEncodedAltName;
-
- if (!reqArena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName);
- if (!newEncodedAltName) {
- return NULL;
- }
-
- encodedContext.encodedGenName = NULL;
- PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
- rv = SEC_QuickDERDecodeItem (reqArena, &encodedContext,
- CERT_GeneralNamesTemplate, newEncodedAltName);
- if (rv == SECFailure) {
- goto loser;
- }
- if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
- return cert_DecodeGeneralNames(reqArena,
- encodedContext.encodedGenName);
- /* Extension contained an empty GeneralNames sequence */
- /* Treat as extension not found */
- PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
-loser:
- return NULL;
-}
-
-
-SECStatus
-CERT_EncodeNameConstraintsExtension(PRArenaPool *arena,
- CERTNameConstraints *value,
- SECItem *encodedValue)
-{
- SECStatus rv = SECSuccess;
-
- rv = cert_EncodeNameConstraints(value, arena, encodedValue);
- return rv;
-}
-
-
-CERTNameConstraints *
-CERT_DecodeNameConstraintsExtension(PRArenaPool *arena,
- SECItem *encodedConstraints)
-{
- return cert_DecodeNameConstraints(arena, encodedConstraints);
-}
-
-
-CERTAuthInfoAccess **
-CERT_DecodeAuthInfoAccessExtension(PRArenaPool *reqArena,
- SECItem *encodedExtension)
-{
- CERTAuthInfoAccess **info = NULL;
- SECStatus rv;
- int i;
- SECItem* newEncodedExtension;
-
- if (!reqArena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- newEncodedExtension = SECITEM_ArenaDupItem(reqArena, encodedExtension);
- if (!newEncodedExtension) {
- return NULL;
- }
-
- rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
- newEncodedExtension);
- if (rv != SECSuccess || info == NULL) {
- return NULL;
- }
-
- for (i = 0; info[i] != NULL; i++) {
- info[i]->location = CERT_DecodeGeneralName(reqArena,
- &(info[i]->derLocation),
- NULL);
- }
- return info;
-}
-
-SECStatus
-CERT_EncodeInfoAccessExtension(PRArenaPool *arena,
- CERTAuthInfoAccess **info,
- SECItem *dest)
-{
- SECItem *dummy;
- int i;
-
- PORT_Assert(info != NULL);
- PORT_Assert(dest != NULL);
- if (info == NULL || dest == NULL) {
- return SECFailure;
- }
-
- for (i = 0; info[i] != NULL; i++) {
- if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
- arena) == NULL)
- /* Note that this may leave some of the locations filled in. */
- return SECFailure;
- }
- dummy = SEC_ASN1EncodeItem(arena, dest, &info,
- CERTAuthInfoAccessTemplate);
- if (dummy == NULL) {
- return SECFailure;
- }
- return SECSuccess;
-}
diff --git a/security/nss/lib/certdb/xconst.h b/security/nss/lib/certdb/xconst.h
deleted file mode 100644
index 14eb75c98..000000000
--- a/security/nss/lib/certdb/xconst.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _XCONST_H_
-#define _XCONST_H_
-
-#include "certt.h"
-
-typedef struct CERTAltNameEncodedContextStr {
- SECItem **encodedGenName;
-} CERTAltNameEncodedContext;
-
-
-
-SEC_BEGIN_PROTOS
-
-extern SECStatus
-CERT_EncodePrivateKeyUsagePeriod(PRArenaPool *arena,
- CERTPrivKeyUsagePeriod *pkup,
- SECItem *encodedValue);
-
-extern SECStatus
-CERT_EncodeNameConstraintsExtension(PRArenaPool *arena,
- CERTNameConstraints *value,
- SECItem *encodedValue);
-
-extern SECStatus
-CERT_EncodeIA5TypeExtension(PRArenaPool *arena, char *value,
- SECItem *encodedValue);
-
-SECStatus
-cert_EncodeAuthInfoAccessExtension(PRArenaPool *arena,
- CERTAuthInfoAccess **info,
- SECItem *dest);
-SEC_END_PROTOS
-#endif
diff --git a/security/nss/lib/certhigh/Makefile b/security/nss/lib/certhigh/Makefile
deleted file mode 100644
index a2f0cf7d5..000000000
--- a/security/nss/lib/certhigh/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
--include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c
deleted file mode 100644
index e8447a683..000000000
--- a/security/nss/lib/certhigh/certhigh.c
+++ /dev/null
@@ -1,1193 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "nspr.h"
-#include "secerr.h"
-#include "secasn1.h"
-#include "seccomon.h"
-#include "pk11func.h"
-#include "certdb.h"
-#include "certt.h"
-#include "cert.h"
-#include "certxutl.h"
-
-#include "nsspki.h"
-#include "pki.h"
-#include "pkit.h"
-#include "pkitm.h"
-#include "pki3hack.h"
-
-
-PRBool
-CERT_MatchNickname(char *name1, char *name2) {
- char *nickname1= NULL;
- char *nickname2 = NULL;
- char *token1;
- char *token2;
- char *token = NULL;
- int len;
-
- /* first deal with the straight comparison */
- if (PORT_Strcmp(name1, name2) == 0) {
- return PR_TRUE;
- }
- /* we need to handle the case where one name has an explicit token and the other
- * doesn't */
- token1 = PORT_Strchr(name1,':');
- token2 = PORT_Strchr(name2,':');
- if ((token1 && token2) || (!token1 && !token2)) {
- /* either both token names are specified or neither are, not match */
- return PR_FALSE;
- }
- if (token1) {
- token=name1;
- nickname1=token1;
- nickname2=name2;
- } else {
- token=name2;
- nickname1=token2;
- nickname2=name1;
- }
- len = nickname1-token;
- nickname1++;
- if (PORT_Strcmp(nickname1,nickname2) != 0) {
- return PR_FALSE;
- }
- /* compare the other token with the internal slot here */
- return PR_TRUE;
-}
-
-/*
- * Find all user certificates that match the given criteria.
- *
- * "handle" - database to search
- * "usage" - certificate usage to match
- * "oneCertPerName" - if set then only return the "best" cert per
- * name
- * "validOnly" - only return certs that are curently valid
- * "proto_win" - window handle passed to pkcs11
- */
-CERTCertList *
-CERT_FindUserCertsByUsage(CERTCertDBHandle *handle,
- SECCertUsage usage,
- PRBool oneCertPerName,
- PRBool validOnly,
- void *proto_win)
-{
- CERTCertNicknames *nicknames = NULL;
- char **nnptr;
- int nn;
- CERTCertificate *cert = NULL;
- CERTCertList *certList = NULL;
- SECStatus rv;
- int64 time;
- CERTCertListNode *node = NULL;
- CERTCertListNode *freenode = NULL;
- int n;
-
- time = PR_Now();
-
- nicknames = CERT_GetCertNicknames(handle, SEC_CERT_NICKNAMES_USER,
- proto_win);
-
- if ( ( nicknames == NULL ) || ( nicknames->numnicknames == 0 ) ) {
- goto loser;
- }
-
- nnptr = nicknames->nicknames;
- nn = nicknames->numnicknames;
-
- while ( nn > 0 ) {
- cert = NULL;
- /* use the pk11 call so that we pick up any certs on tokens,
- * which may require login
- */
- if ( proto_win != NULL ) {
- cert = PK11_FindCertFromNickname(*nnptr,proto_win);
- }
-
- /* Sigh, It turns out if the cert is already in the temp db, because
- * it's in the perm db, then the nickname lookup doesn't work.
- * since we already have the cert here, though, than we can just call
- * CERT_CreateSubjectCertList directly. For those cases where we didn't
- * find the cert in pkcs #11 (because we didn't have a password arg,
- * or because the nickname is for a peer, server, or CA cert, then we
- * go look the cert up.
- */
- if (cert == NULL) {
- cert = CERT_FindCertByNickname(handle,*nnptr);
- }
-
- if ( cert != NULL ) {
- /* collect certs for this nickname, sorting them into the list */
- certList = CERT_CreateSubjectCertList(certList, handle,
- &cert->derSubject, time, validOnly);
-
- CERT_FilterCertListForUserCerts(certList);
-
- /* drop the extra reference */
- CERT_DestroyCertificate(cert);
- }
-
- nnptr++;
- nn--;
- }
-
- /* remove certs with incorrect usage */
- rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* remove any extra certs for each name */
- if ( oneCertPerName ) {
- PRBool *flags;
-
- nn = nicknames->numnicknames;
- nnptr = nicknames->nicknames;
-
- flags = (PRBool *)PORT_ZAlloc(sizeof(PRBool) * nn);
- if ( flags == NULL ) {
- goto loser;
- }
-
- node = CERT_LIST_HEAD(certList);
-
- /* treverse all certs in the list */
- while ( !CERT_LIST_END(node, certList) ) {
-
- /* find matching nickname index */
- for ( n = 0; n < nn; n++ ) {
- if ( CERT_MatchNickname(nnptr[n], node->cert->nickname) ) {
- /* We found a match. If this is the first one, then
- * set the flag and move on to the next cert. If this
- * is not the first one then delete it from the list.
- */
- if ( flags[n] ) {
- /* We have already seen a cert with this nickname,
- * so delete this one.
- */
- freenode = node;
- node = CERT_LIST_NEXT(node);
- CERT_RemoveCertListNode(freenode);
- } else {
- /* keep the first cert for each nickname, but set the
- * flag so we know to delete any others with the same
- * nickname.
- */
- flags[n] = PR_TRUE;
- node = CERT_LIST_NEXT(node);
- }
- break;
- }
- }
- if ( n == nn ) {
- /* if we get here it means that we didn't find a matching
- * nickname, which should not happen.
- */
- PORT_Assert(0);
- node = CERT_LIST_NEXT(node);
- }
- }
- PORT_Free(flags);
- }
-
- goto done;
-
-loser:
- if ( certList != NULL ) {
- CERT_DestroyCertList(certList);
- certList = NULL;
- }
-
-done:
- if ( nicknames != NULL ) {
- CERT_FreeNicknames(nicknames);
- }
-
- return(certList);
-}
-
-/*
- * Find a user certificate that matchs the given criteria.
- *
- * "handle" - database to search
- * "nickname" - nickname to match
- * "usage" - certificate usage to match
- * "validOnly" - only return certs that are curently valid
- * "proto_win" - window handle passed to pkcs11
- */
-CERTCertificate *
-CERT_FindUserCertByUsage(CERTCertDBHandle *handle,
- const char *nickname,
- SECCertUsage usage,
- PRBool validOnly,
- void *proto_win)
-{
- CERTCertificate *cert = NULL;
- CERTCertList *certList = NULL;
- SECStatus rv;
- int64 time;
-
- time = PR_Now();
-
- /* use the pk11 call so that we pick up any certs on tokens,
- * which may require login
- */
- /* XXX - why is this restricted? */
- if ( proto_win != NULL ) {
- cert = PK11_FindCertFromNickname(nickname,proto_win);
- }
-
-
- /* sigh, There are still problems find smart cards from the temp
- * db. This will get smart cards working again. The real fix
- * is to make sure we can search the temp db by their token nickname.
- */
- if (cert == NULL) {
- cert = CERT_FindCertByNickname(handle,nickname);
- }
-
- if ( cert != NULL ) {
- unsigned int requiredKeyUsage;
- unsigned int requiredCertType;
-
- rv = CERT_KeyUsageAndTypeForCertUsage(usage, PR_FALSE,
- &requiredKeyUsage, &requiredCertType);
- if ( rv != SECSuccess ) {
- /* drop the extra reference */
- CERT_DestroyCertificate(cert);
- cert = NULL;
- goto loser;
- }
- /* If we already found the right cert, just return it */
- if ( (!validOnly || CERT_CheckCertValidTimes(cert, time, PR_FALSE)
- == secCertTimeValid) &&
- (CERT_CheckKeyUsage(cert, requiredKeyUsage) == SECSuccess) &&
- (cert->nsCertType & requiredCertType) &&
- CERT_IsUserCert(cert) ) {
- return(cert);
- }
-
- /* collect certs for this nickname, sorting them into the list */
- certList = CERT_CreateSubjectCertList(certList, handle,
- &cert->derSubject, time, validOnly);
-
- CERT_FilterCertListForUserCerts(certList);
-
- /* drop the extra reference */
- CERT_DestroyCertificate(cert);
- cert = NULL;
- }
-
- if ( certList == NULL ) {
- goto loser;
- }
-
- /* remove certs with incorrect usage */
- rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- if ( ! CERT_LIST_END(CERT_LIST_HEAD(certList), certList) ) {
- cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert);
- }
-
-loser:
- if ( certList != NULL ) {
- CERT_DestroyCertList(certList);
- }
-
- return(cert);
-}
-
-CERTCertList *
-CERT_MatchUserCert(CERTCertDBHandle *handle,
- SECCertUsage usage,
- int nCANames, char **caNames,
- void *proto_win)
-{
- CERTCertList *certList = NULL;
- SECStatus rv;
-
- certList = CERT_FindUserCertsByUsage(handle, usage, PR_TRUE, PR_TRUE,
- proto_win);
- if ( certList == NULL ) {
- goto loser;
- }
-
- rv = CERT_FilterCertListByCANames(certList, nCANames, caNames, usage);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- goto done;
-
-loser:
- if ( certList != NULL ) {
- CERT_DestroyCertList(certList);
- certList = NULL;
- }
-
-done:
-
- return(certList);
-}
-
-
-typedef struct stringNode {
- struct stringNode *next;
- char *string;
-} stringNode;
-
-static PRStatus
-CollectNicknames( NSSCertificate *c, void *data)
-{
- CERTCertNicknames *names;
- PRBool saveit = PR_FALSE;
- stringNode *node;
- int len;
-#ifdef notdef
- NSSTrustDomain *td;
- NSSTrust *trust;
-#endif
- char *stanNickname;
- char *nickname = NULL;
-
- names = (CERTCertNicknames *)data;
-
- stanNickname = nssCertificate_GetNickname(c,NULL);
-
- if ( stanNickname ) {
- nss_ZFreeIf(stanNickname);
- stanNickname = NULL;
- if (names->what == SEC_CERT_NICKNAMES_USER) {
- saveit = NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL);
- }
-#ifdef notdef
- else {
- td = NSSCertificate_GetTrustDomain(c);
- if (!td) {
- return PR_SUCCESS;
- }
- trust = nssTrustDomain_FindTrustForCertificate(td,c);
-
- switch(names->what) {
- case SEC_CERT_NICKNAMES_ALL:
- if ((trust->sslFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) ||
- (trust->emailFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) ||
- (trust->objectSigningFlags &
- (CERTDB_VALID_CA|CERTDB_VALID_PEER))) {
- saveit = PR_TRUE;
- }
-
- break;
- case SEC_CERT_NICKNAMES_SERVER:
- if ( trust->sslFlags & CERTDB_VALID_PEER ) {
- saveit = PR_TRUE;
- }
-
- break;
- case SEC_CERT_NICKNAMES_CA:
- if (((trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA)||
- ((trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA) ||
- ((trust->objectSigningFlags & CERTDB_VALID_CA )
- == CERTDB_VALID_CA)) {
- saveit = PR_TRUE;
- }
- break;
- }
- }
-#endif
- }
-
- /* traverse the list of collected nicknames and make sure we don't make
- * a duplicate
- */
- if ( saveit ) {
- nickname = STAN_GetCERTCertificateName(NULL, c);
- /* nickname can only be NULL here if we are having memory
- * alloc problems */
- if (nickname == NULL) {
- return PR_FAILURE;
- }
- node = (stringNode *)names->head;
- while ( node != NULL ) {
- if ( PORT_Strcmp(nickname, node->string) == 0 ) {
- /* if the string matches, then don't save this one */
- saveit = PR_FALSE;
- break;
- }
- node = node->next;
- }
- }
-
- if ( saveit ) {
-
- /* allocate the node */
- node = (stringNode*)PORT_ArenaAlloc(names->arena, sizeof(stringNode));
- if ( node == NULL ) {
- PORT_Free(nickname);
- return PR_FAILURE;
- }
-
- /* copy the string */
- len = PORT_Strlen(nickname) + 1;
- node->string = (char*)PORT_ArenaAlloc(names->arena, len);
- if ( node->string == NULL ) {
- PORT_Free(nickname);
- return PR_FAILURE;
- }
- PORT_Memcpy(node->string, nickname, len);
-
- /* link it into the list */
- node->next = (stringNode *)names->head;
- names->head = (void *)node;
-
- /* bump the count */
- names->numnicknames++;
- }
-
- if (nickname) PORT_Free(nickname);
- return(PR_SUCCESS);
-}
-
-CERTCertNicknames *
-CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx)
-{
- PRArenaPool *arena;
- CERTCertNicknames *names;
- int i;
- stringNode *node;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(NULL);
- }
-
- names = (CERTCertNicknames *)PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames));
- if ( names == NULL ) {
- goto loser;
- }
-
- names->arena = arena;
- names->head = NULL;
- names->numnicknames = 0;
- names->nicknames = NULL;
- names->what = what;
- names->totallen = 0;
-
- /* make sure we are logged in */
- (void) pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, wincx);
-
- NSSTrustDomain_TraverseCertificates(handle,
- CollectNicknames, (void *)names);
- if ( names->numnicknames ) {
- names->nicknames = (char**)PORT_ArenaAlloc(arena,
- names->numnicknames * sizeof(char *));
-
- if ( names->nicknames == NULL ) {
- goto loser;
- }
-
- node = (stringNode *)names->head;
-
- for ( i = 0; i < names->numnicknames; i++ ) {
- PORT_Assert(node != NULL);
-
- names->nicknames[i] = node->string;
- names->totallen += PORT_Strlen(node->string);
- node = node->next;
- }
-
- PORT_Assert(node == NULL);
- }
-
- return(names);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(NULL);
-}
-
-void
-CERT_FreeNicknames(CERTCertNicknames *nicknames)
-{
- PORT_FreeArena(nicknames->arena, PR_FALSE);
-
- return;
-}
-
-/* [ FROM pcertdb.c ] */
-
-typedef struct dnameNode {
- struct dnameNode *next;
- SECItem name;
-} dnameNode;
-
-void
-CERT_FreeDistNames(CERTDistNames *names)
-{
- PORT_FreeArena(names->arena, PR_FALSE);
-
- return;
-}
-
-static SECStatus
-CollectDistNames( CERTCertificate *cert, SECItem *k, void *data)
-{
- CERTDistNames *names;
- PRBool saveit = PR_FALSE;
- CERTCertTrust trust;
- dnameNode *node;
- int len;
-
- names = (CERTDistNames *)data;
-
- if ( CERT_GetCertTrust(cert, &trust) == SECSuccess ) {
- /* only collect names of CAs trusted for issuing SSL clients */
- if ( trust.sslFlags & CERTDB_TRUSTED_CLIENT_CA ) {
- saveit = PR_TRUE;
- }
- }
-
- if ( saveit ) {
- /* allocate the node */
- node = (dnameNode*)PORT_ArenaAlloc(names->arena, sizeof(dnameNode));
- if ( node == NULL ) {
- return(SECFailure);
- }
-
- /* copy the name */
- node->name.len = len = cert->derSubject.len;
- node->name.type = siBuffer;
- node->name.data = (unsigned char*)PORT_ArenaAlloc(names->arena, len);
- if ( node->name.data == NULL ) {
- return(SECFailure);
- }
- PORT_Memcpy(node->name.data, cert->derSubject.data, len);
-
- /* link it into the list */
- node->next = (dnameNode *)names->head;
- names->head = (void *)node;
-
- /* bump the count */
- names->nnames++;
- }
-
- return(SECSuccess);
-}
-
-/*
- * Return all of the CAs that are "trusted" for SSL.
- */
-CERTDistNames *
-CERT_DupDistNames(CERTDistNames *orig)
-{
- PRArenaPool *arena;
- CERTDistNames *names;
- int i;
- SECStatus rv;
-
- /* allocate an arena to use */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(NULL);
- }
-
- /* allocate the header structure */
- names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames));
- if (names == NULL) {
- goto loser;
- }
-
- /* initialize the header struct */
- names->arena = arena;
- names->head = NULL;
- names->nnames = orig->nnames;
- names->names = NULL;
-
- /* construct the array from the list */
- if (orig->nnames) {
- names->names = (SECItem*)PORT_ArenaNewArray(arena, SECItem,
- orig->nnames);
- if (names->names == NULL) {
- goto loser;
- }
- for (i = 0; i < orig->nnames; i++) {
- rv = SECITEM_CopyItem(arena, &names->names[i], &orig->names[i]);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- }
- return(names);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(NULL);
-}
-
-CERTDistNames *
-CERT_GetSSLCACerts(CERTCertDBHandle *handle)
-{
- PRArenaPool *arena;
- CERTDistNames *names;
- int i;
- SECStatus rv;
- dnameNode *node;
-
- /* allocate an arena to use */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(NULL);
- }
-
- /* allocate the header structure */
- names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames));
- if ( names == NULL ) {
- goto loser;
- }
-
- /* initialize the header struct */
- names->arena = arena;
- names->head = NULL;
- names->nnames = 0;
- names->names = NULL;
-
- /* collect the names from the database */
- rv = PK11_TraverseSlotCerts(CollectDistNames, (void *)names, NULL);
- if ( rv ) {
- goto loser;
- }
-
- /* construct the array from the list */
- if ( names->nnames ) {
- names->names = (SECItem*)PORT_ArenaAlloc(arena, names->nnames * sizeof(SECItem));
-
- if ( names->names == NULL ) {
- goto loser;
- }
-
- node = (dnameNode *)names->head;
-
- for ( i = 0; i < names->nnames; i++ ) {
- PORT_Assert(node != NULL);
-
- names->names[i] = node->name;
- node = node->next;
- }
-
- PORT_Assert(node == NULL);
- }
-
- return(names);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(NULL);
-}
-
-CERTDistNames *
-CERT_DistNamesFromCertList(CERTCertList *certList)
-{
- CERTDistNames * dnames = NULL;
- PRArenaPool * arena;
- CERTCertListNode *node = NULL;
- SECItem * names = NULL;
- int listLen = 0, i = 0;
-
- if (certList == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- node = CERT_LIST_HEAD(certList);
- while ( ! CERT_LIST_END(node, certList) ) {
- listLen += 1;
- node = CERT_LIST_NEXT(node);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) goto loser;
- dnames = PORT_ArenaZNew(arena, CERTDistNames);
- if (dnames == NULL) goto loser;
-
- dnames->arena = arena;
- dnames->nnames = listLen;
- dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, listLen);
- if (names == NULL) goto loser;
-
- node = CERT_LIST_HEAD(certList);
- while ( ! CERT_LIST_END(node, certList) ) {
- CERTCertificate *cert = node->cert;
- SECStatus rv = SECITEM_CopyItem(arena, &names[i++], &cert->derSubject);
- if (rv == SECFailure) {
- goto loser;
- }
- node = CERT_LIST_NEXT(node);
- }
- return dnames;
-loser:
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return NULL;
-}
-
-CERTDistNames *
-CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames,
- int nnames)
-{
- CERTDistNames *dnames = NULL;
- PRArenaPool *arena;
- int i, rv;
- SECItem *names = NULL;
- CERTCertificate *cert = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) goto loser;
- dnames = PORT_ArenaZNew(arena, CERTDistNames);
- if (dnames == NULL) goto loser;
-
- dnames->arena = arena;
- dnames->nnames = nnames;
- dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, nnames);
- if (names == NULL) goto loser;
-
- for (i = 0; i < nnames; i++) {
- cert = CERT_FindCertByNicknameOrEmailAddr(handle, nicknames[i]);
- if (cert == NULL) goto loser;
- rv = SECITEM_CopyItem(arena, &names[i], &cert->derSubject);
- if (rv == SECFailure) goto loser;
- CERT_DestroyCertificate(cert);
- }
- return dnames;
-
-loser:
- if (cert != NULL)
- CERT_DestroyCertificate(cert);
- if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
-}
-
-/* [ from pcertdb.c - calls Ascii to Name ] */
-/*
- * Lookup a certificate in the database by name
- */
-CERTCertificate *
-CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr)
-{
- CERTName *name;
- SECItem *nameItem;
- CERTCertificate *cert = NULL;
- PRArenaPool *arena = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( arena == NULL ) {
- goto loser;
- }
-
- name = CERT_AsciiToName(nameStr);
-
- if ( name ) {
- nameItem = SEC_ASN1EncodeItem (arena, NULL, (void *)name,
- CERT_NameTemplate);
- if ( nameItem != NULL ) {
- cert = CERT_FindCertByName(handle, nameItem);
- }
- CERT_DestroyName(name);
- }
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(cert);
-}
-
-/* From certv3.c */
-
-CERTCrlDistributionPoints *
-CERT_FindCRLDistributionPoints (CERTCertificate *cert)
-{
- SECItem encodedExtenValue;
- SECStatus rv;
- CERTCrlDistributionPoints *dps;
-
- encodedExtenValue.data = NULL;
- encodedExtenValue.len = 0;
-
- rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS,
- &encodedExtenValue);
- if ( rv != SECSuccess ) {
- return (NULL);
- }
-
- dps = CERT_DecodeCRLDistributionPoints(cert->arena, &encodedExtenValue);
-
- PORT_Free(encodedExtenValue.data);
-
- return dps;
-}
-
-/* From crl.c */
-CERTSignedCrl * CERT_ImportCRL
- (CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, void *wincx)
-{
- CERTSignedCrl* retCrl = NULL;
- PK11SlotInfo* slot = PK11_GetInternalKeySlot();
- retCrl = PK11_ImportCRL(slot, derCRL, url, type, wincx,
- CRL_IMPORT_DEFAULT_OPTIONS, NULL, CRL_DECODE_DEFAULT_OPTIONS);
- PK11_FreeSlot(slot);
-
- return retCrl;
-}
-
-/* From certdb.c */
-static SECStatus
-cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool trusted)
-{
- SECStatus rv;
- SECItem *derCert;
- CERTCertificate *cert = NULL;
- CERTCertificate *newcert = NULL;
- CERTCertDBHandle *handle;
- CERTCertTrust trust;
- PRBool isca;
- char *nickname;
- unsigned int certtype;
-
- handle = CERT_GetDefaultCertDB();
-
- while (numcerts--) {
- derCert = certs;
- certs++;
-
- /* decode my certificate */
- /* This use is ok -- only looks at decoded parts, calls NewTemp later */
- newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
- if ( newcert == NULL ) {
- goto loser;
- }
-
- if (!trusted) {
- /* make sure that cert is valid */
- rv = CERT_CertTimesValid(newcert);
- if ( rv == SECFailure ) {
- goto endloop;
- }
- }
-
- /* does it have the CA extension */
-
- /*
- * Make sure that if this is an intermediate CA in the chain that
- * it was given permission by its signer to be a CA.
- */
- isca = CERT_IsCACert(newcert, &certtype);
-
- if ( !isca ) {
- if (!trusted) {
- goto endloop;
- }
- trust.sslFlags = CERTDB_VALID_CA;
- trust.emailFlags = CERTDB_VALID_CA;
- trust.objectSigningFlags = CERTDB_VALID_CA;
- } else {
- /* SSL ca's must have the ssl bit set */
- if ( ( certUsage == certUsageSSLCA ) &&
- (( certtype & NS_CERT_TYPE_SSL_CA ) != NS_CERT_TYPE_SSL_CA )) {
- goto endloop;
- }
-
- /* it passed all of the tests, so lets add it to the database */
- /* mark it as a CA */
- PORT_Memset((void *)&trust, 0, sizeof(trust));
- switch ( certUsage ) {
- case certUsageSSLCA:
- trust.sslFlags = CERTDB_VALID_CA;
- break;
- case certUsageUserCertImport:
- if ((certtype & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA) {
- trust.sslFlags = CERTDB_VALID_CA;
- }
- if ((certtype & NS_CERT_TYPE_EMAIL_CA)
- == NS_CERT_TYPE_EMAIL_CA ) {
- trust.emailFlags = CERTDB_VALID_CA;
- }
- if ( ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) ==
- NS_CERT_TYPE_OBJECT_SIGNING_CA ) {
- trust.objectSigningFlags = CERTDB_VALID_CA;
- }
- break;
- default:
- PORT_Assert(0);
- break;
- }
- }
-
- cert = CERT_NewTempCertificate(handle, derCert, NULL,
- PR_FALSE, PR_FALSE);
- if ( cert == NULL ) {
- goto loser;
- }
-
- /* if the cert is temp, make it perm; otherwise we're done */
- if (cert->istemp) {
- /* get a default nickname for it */
- nickname = CERT_MakeCANickname(cert);
-
- rv = CERT_AddTempCertToPerm(cert, nickname, &trust);
-
- /* free the nickname */
- if ( nickname ) {
- PORT_Free(nickname);
- }
- } else {
- rv = SECSuccess;
- }
-
- CERT_DestroyCertificate(cert);
- cert = NULL;
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
-endloop:
- if ( newcert ) {
- CERT_DestroyCertificate(newcert);
- newcert = NULL;
- }
-
- }
-
- rv = SECSuccess;
- goto done;
-loser:
- rv = SECFailure;
-done:
-
- if ( newcert ) {
- CERT_DestroyCertificate(newcert);
- newcert = NULL;
- }
-
- if ( cert ) {
- CERT_DestroyCertificate(cert);
- cert = NULL;
- }
-
- return(rv);
-}
-
-SECStatus
-CERT_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage)
-{
- return cert_ImportCAChain(certs, numcerts, certUsage, PR_FALSE);
-}
-
-SECStatus
-CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage) {
- return cert_ImportCAChain(certs, numcerts, certUsage, PR_TRUE);
-}
-
-/* Moved from certdb.c */
-/*
-** CERT_CertChainFromCert
-**
-** Construct a CERTCertificateList consisting of the given certificate and all
-** of the issuer certs until we either get to a self-signed cert or can't find
-** an issuer. Since we don't know how many certs are in the chain we have to
-** build a linked list first as we count them.
-*/
-
-typedef struct certNode {
- struct certNode *next;
- CERTCertificate *cert;
-} certNode;
-
-CERTCertificateList *
-CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,
- PRBool includeRoot)
-{
- CERTCertificateList *chain = NULL;
- NSSCertificate **stanChain;
- NSSCertificate *stanCert;
- PRArenaPool *arena;
- NSSUsage nssUsage;
- int i, len;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSCryptoContext *cc = STAN_GetDefaultCryptoContext();
-
- stanCert = STAN_GetNSSCertificate(cert);
- if (!stanCert) {
- /* error code is set */
- return NULL;
- }
- nssUsage.anyUsage = PR_FALSE;
- nssUsage.nss3usage = usage;
- nssUsage.nss3lookingForCA = PR_FALSE;
- stanChain = NSSCertificate_BuildChain(stanCert, NULL, &nssUsage, NULL, NULL,
- CERT_MAX_CERT_CHAIN, NULL, NULL, td, cc);
- if (!stanChain) {
- PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
- return NULL;
- }
-
- len = 0;
- stanCert = stanChain[0];
- while (stanCert) {
- stanCert = stanChain[++len];
- }
-
- arena = PORT_NewArena(4096);
- if (arena == NULL) {
- goto loser;
- }
-
- chain = (CERTCertificateList *)PORT_ArenaAlloc(arena,
- sizeof(CERTCertificateList));
- if (!chain) goto loser;
- chain->certs = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
- if (!chain->certs) goto loser;
- i = 0;
- stanCert = stanChain[i];
- while (stanCert) {
- SECItem derCert;
- CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
- if (!cCert) {
- goto loser;
- }
- derCert.len = (unsigned int)stanCert->encoding.size;
- derCert.data = (unsigned char *)stanCert->encoding.data;
- derCert.type = siBuffer;
- SECITEM_CopyItem(arena, &chain->certs[i], &derCert);
- stanCert = stanChain[++i];
- if (!stanCert && !cCert->isRoot) {
- /* reached the end of the chain, but the final cert is
- * not a root. Don't discard it.
- */
- includeRoot = PR_TRUE;
- }
- CERT_DestroyCertificate(cCert);
- }
- if ( !includeRoot && len > 1) {
- chain->len = len - 1;
- } else {
- chain->len = len;
- }
-
- chain->arena = arena;
- nss_ZFreeIf(stanChain);
- return chain;
-loser:
- i = 0;
- stanCert = stanChain[i];
- while (stanCert) {
- CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
- if (cCert) {
- CERT_DestroyCertificate(cCert);
- }
- stanCert = stanChain[++i];
- }
- nss_ZFreeIf(stanChain);
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return NULL;
-}
-
-/* Builds a CERTCertificateList holding just one DER-encoded cert, namely
-** the one for the cert passed as an argument.
-*/
-CERTCertificateList *
-CERT_CertListFromCert(CERTCertificate *cert)
-{
- CERTCertificateList *chain = NULL;
- int rv;
- PRArenaPool *arena;
-
- /* arena for SecCertificateList */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) goto no_memory;
-
- /* build the CERTCertificateList */
- chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList));
- if (chain == NULL) goto no_memory;
- chain->certs = (SECItem*)PORT_ArenaAlloc(arena, 1 * sizeof(SECItem));
- if (chain->certs == NULL) goto no_memory;
- rv = SECITEM_CopyItem(arena, chain->certs, &(cert->derCert));
- if (rv < 0) goto loser;
- chain->len = 1;
- chain->arena = arena;
-
- return chain;
-
-no_memory:
- PORT_SetError(SEC_ERROR_NO_MEMORY);
-loser:
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return NULL;
-}
-
-CERTCertificateList *
-CERT_DupCertList(const CERTCertificateList * oldList)
-{
- CERTCertificateList *newList = NULL;
- PRArenaPool *arena = NULL;
- SECItem *newItem;
- SECItem *oldItem;
- int len = oldList->len;
- int rv;
-
- /* arena for SecCertificateList */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- goto no_memory;
-
- /* now build the CERTCertificateList */
- newList = PORT_ArenaNew(arena, CERTCertificateList);
- if (newList == NULL)
- goto no_memory;
- newList->arena = arena;
- newItem = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
- if (newItem == NULL)
- goto no_memory;
- newList->certs = newItem;
- newList->len = len;
-
- for (oldItem = oldList->certs; len > 0; --len, ++newItem, ++oldItem) {
- rv = SECITEM_CopyItem(arena, newItem, oldItem);
- if (rv < 0)
- goto loser;
- }
- return newList;
-
-no_memory:
- PORT_SetError(SEC_ERROR_NO_MEMORY);
-loser:
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return NULL;
-}
-
-void
-CERT_DestroyCertificateList(CERTCertificateList *list)
-{
- PORT_FreeArena(list->arena, PR_FALSE);
-}
-
diff --git a/security/nss/lib/certhigh/certhtml.c b/security/nss/lib/certhigh/certhtml.c
deleted file mode 100644
index a1be435d2..000000000
--- a/security/nss/lib/certhigh/certhtml.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * certhtml.c --- convert a cert to html
- *
- * $Id$
- */
-
-#include "seccomon.h"
-#include "secitem.h"
-#include "sechash.h"
-#include "cert.h"
-#include "keyhi.h"
-#include "secder.h"
-#include "prprf.h"
-#include "secport.h"
-#include "secasn1.h"
-#include "pk11func.h"
-
-static char *hex = "0123456789ABCDEF";
-
-/*
-** Convert a der-encoded integer to a hex printable string form
-*/
-char *CERT_Hexify (SECItem *i, int do_colon)
-{
- unsigned char *cp, *end;
- char *rv, *o;
-
- if (!i->len) {
- return PORT_Strdup("00");
- }
-
- rv = o = (char*) PORT_Alloc(i->len * 3);
- if (!rv) return rv;
-
- cp = i->data;
- end = cp + i->len;
- while (cp < end) {
- unsigned char ch = *cp++;
- *o++ = hex[(ch >> 4) & 0xf];
- *o++ = hex[ch & 0xf];
- if (cp != end) {
- if (do_colon) {
- *o++ = ':';
- }
- }
- }
- *o = 0; /* Null terminate the string */
- return rv;
-}
-
-#define BREAK "<br>"
-#define BREAKLEN 4
-#define COMMA ", "
-#define COMMALEN 2
-
-#define MAX_OUS 20
-#define MAX_DC MAX_OUS
-
-
-char *CERT_FormatName (CERTName *name)
-{
- CERTRDN** rdns;
- CERTRDN * rdn;
- CERTAVA** avas;
- CERTAVA* ava;
- char * buf = 0;
- char * tmpbuf = 0;
- SECItem * cn = 0;
- SECItem * email = 0;
- SECItem * org = 0;
- SECItem * loc = 0;
- SECItem * state = 0;
- SECItem * country = 0;
- SECItem * dq = 0;
-
- unsigned len = 0;
- int tag;
- int i;
- int ou_count = 0;
- int dc_count = 0;
- PRBool first;
- SECItem * orgunit[MAX_OUS];
- SECItem * dc[MAX_DC];
-
- /* Loop over name components and gather the interesting ones */
- rdns = name->rdns;
- while ((rdn = *rdns++) != 0) {
- avas = rdn->avas;
- while ((ava = *avas++) != 0) {
- tag = CERT_GetAVATag(ava);
- switch(tag) {
- case SEC_OID_AVA_COMMON_NAME:
- if (cn) {
- break;
- }
- cn = CERT_DecodeAVAValue(&ava->value);
- if (!cn) {
- goto loser;
- }
- len += cn->len;
- break;
- case SEC_OID_AVA_COUNTRY_NAME:
- if (country) {
- break;
- }
- country = CERT_DecodeAVAValue(&ava->value);
- if (!country) {
- goto loser;
- }
- len += country->len;
- break;
- case SEC_OID_AVA_LOCALITY:
- if (loc) {
- break;
- }
- loc = CERT_DecodeAVAValue(&ava->value);
- if (!loc) {
- goto loser;
- }
- len += loc->len;
- break;
- case SEC_OID_AVA_STATE_OR_PROVINCE:
- if (state) {
- break;
- }
- state = CERT_DecodeAVAValue(&ava->value);
- if (!state) {
- goto loser;
- }
- len += state->len;
- break;
- case SEC_OID_AVA_ORGANIZATION_NAME:
- if (org) {
- break;
- }
- org = CERT_DecodeAVAValue(&ava->value);
- if (!org) {
- goto loser;
- }
- len += org->len;
- break;
- case SEC_OID_AVA_DN_QUALIFIER:
- if (dq) {
- break;
- }
- dq = CERT_DecodeAVAValue(&ava->value);
- if (!dq) {
- goto loser;
- }
- len += dq->len;
- break;
- case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
- if (ou_count < MAX_OUS) {
- orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value);
- if (!orgunit[ou_count]) {
- goto loser;
- }
- len += orgunit[ou_count++]->len;
- }
- break;
- case SEC_OID_AVA_DC:
- if (dc_count < MAX_DC) {
- dc[dc_count] = CERT_DecodeAVAValue(&ava->value);
- if (!dc[dc_count]) {
- goto loser;
- }
- len += dc[dc_count++]->len;
- }
- break;
- case SEC_OID_PKCS9_EMAIL_ADDRESS:
- case SEC_OID_RFC1274_MAIL:
- if (email) {
- break;
- }
- email = CERT_DecodeAVAValue(&ava->value);
- if (!email) {
- goto loser;
- }
- len += email->len;
- break;
- default:
- break;
- }
- }
- }
-
- /* XXX - add some for formatting */
- len += 128;
-
- /* allocate buffer */
- buf = (char *)PORT_Alloc(len);
- if ( !buf ) {
- goto loser;
- }
-
- tmpbuf = buf;
-
- if ( cn ) {
- PORT_Memcpy(tmpbuf, cn->data, cn->len);
- tmpbuf += cn->len;
- PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
- tmpbuf += BREAKLEN;
- }
- if ( email ) {
- PORT_Memcpy(tmpbuf, email->data, email->len);
- tmpbuf += ( email->len );
- PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
- tmpbuf += BREAKLEN;
- }
- for (i=ou_count-1; i >= 0; i--) {
- PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len);
- tmpbuf += ( orgunit[i]->len );
- PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
- tmpbuf += BREAKLEN;
- }
- if ( dq ) {
- PORT_Memcpy(tmpbuf, dq->data, dq->len);
- tmpbuf += ( dq->len );
- PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
- tmpbuf += BREAKLEN;
- }
- if ( org ) {
- PORT_Memcpy(tmpbuf, org->data, org->len);
- tmpbuf += ( org->len );
- PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
- tmpbuf += BREAKLEN;
- }
- for (i=dc_count-1; i >= 0; i--) {
- PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len);
- tmpbuf += ( dc[i]->len );
- PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
- tmpbuf += BREAKLEN;
- }
- first = PR_TRUE;
- if ( loc ) {
- PORT_Memcpy(tmpbuf, loc->data, loc->len);
- tmpbuf += ( loc->len );
- first = PR_FALSE;
- }
- if ( state ) {
- if ( !first ) {
- PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
- tmpbuf += COMMALEN;
- }
- PORT_Memcpy(tmpbuf, state->data, state->len);
- tmpbuf += ( state->len );
- first = PR_FALSE;
- }
- if ( country ) {
- if ( !first ) {
- PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
- tmpbuf += COMMALEN;
- }
- PORT_Memcpy(tmpbuf, country->data, country->len);
- tmpbuf += ( country->len );
- first = PR_FALSE;
- }
- if ( !first ) {
- PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
- tmpbuf += BREAKLEN;
- }
-
- *tmpbuf = 0;
-
- /* fall through and clean */
-loser:
- if ( cn ) {
- SECITEM_FreeItem(cn, PR_TRUE);
- }
- if ( email ) {
- SECITEM_FreeItem(email, PR_TRUE);
- }
- for (i=ou_count-1; i >= 0; i--) {
- SECITEM_FreeItem(orgunit[i], PR_TRUE);
- }
- if ( dq ) {
- SECITEM_FreeItem(dq, PR_TRUE);
- }
- if ( org ) {
- SECITEM_FreeItem(org, PR_TRUE);
- }
- for (i=dc_count-1; i >= 0; i--) {
- SECITEM_FreeItem(dc[i], PR_TRUE);
- }
- if ( loc ) {
- SECITEM_FreeItem(loc, PR_TRUE);
- }
- if ( state ) {
- SECITEM_FreeItem(state, PR_TRUE);
- }
- if ( country ) {
- SECITEM_FreeItem(country, PR_TRUE);
- }
-
- return(buf);
-}
-
diff --git a/security/nss/lib/certhigh/certreq.c b/security/nss/lib/certhigh/certreq.c
deleted file mode 100644
index 19753766f..000000000
--- a/security/nss/lib/certhigh/certreq.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "cert.h"
-#include "certt.h"
-#include "secder.h"
-#include "key.h"
-#include "secitem.h"
-#include "secasn1.h"
-#include "secerr.h"
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-
-const SEC_ASN1Template CERT_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTAttribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue),
- SEC_ASN1_SUB(SEC_AnyTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, CERT_AttributeTemplate },
-};
-
-const SEC_ASN1Template CERT_CertificateRequestTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCertificateRequest) },
- { SEC_ASN1_INTEGER,
- offsetof(CERTCertificateRequest,version) },
- { SEC_ASN1_INLINE,
- offsetof(CERTCertificateRequest,subject),
- CERT_NameTemplate },
- { SEC_ASN1_INLINE,
- offsetof(CERTCertificateRequest,subjectPublicKeyInfo),
- CERT_SubjectPublicKeyInfoTemplate },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(CERTCertificateRequest,attributes),
- CERT_SetOfAttributeTemplate },
- { 0 }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate)
-
-CERTCertificate *
-CERT_CreateCertificate(unsigned long serialNumber,
- CERTName *issuer,
- CERTValidity *validity,
- CERTCertificateRequest *req)
-{
- CERTCertificate *c;
- int rv;
- PRArenaPool *arena;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- if ( !arena ) {
- return(0);
- }
-
- c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
-
- if (!c) {
- PORT_FreeArena(arena, PR_FALSE);
- return 0;
- }
-
- c->referenceCount = 1;
- c->arena = arena;
-
- /*
- * Default is a plain version 1.
- * If extensions are added, it will get changed as appropriate.
- */
- rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1);
- if (rv) goto loser;
-
- rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber);
- if (rv) goto loser;
-
- rv = CERT_CopyName(arena, &c->issuer, issuer);
- if (rv) goto loser;
-
- rv = CERT_CopyValidity(arena, &c->validity, validity);
- if (rv) goto loser;
-
- rv = CERT_CopyName(arena, &c->subject, &req->subject);
- if (rv) goto loser;
- rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo,
- &req->subjectPublicKeyInfo);
- if (rv) goto loser;
-
- return c;
-
- loser:
- CERT_DestroyCertificate(c);
- return 0;
-}
-
-/************************************************************************/
-/* It's clear from the comments that the original author of this
- * function expected the template for certificate requests to treat
- * the attributes as a SET OF ANY. This function expected to be
- * passed an array of SECItems each of which contained an already encoded
- * Attribute. But the cert request template does not treat the
- * Attributes as a SET OF ANY, and AFAIK never has. Instead the template
- * encodes attributes as a SET OF xxxxxxx. That is, it expects to encode
- * each of the Attributes, not have them pre-encoded. Consequently an
- * array of SECItems containing encoded Attributes is of no value to this
- * function. But we cannot change the signature of this public function.
- * It must continue to take SECItems.
- *
- * I have recoded this function so that each SECItem contains an
- * encoded cert extension. The encoded cert extensions form the list for the
- * single attribute of the cert request. In this implementation there is at most
- * one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST.
- */
-
-CERTCertificateRequest *
-CERT_CreateCertificateRequest(CERTName *subject,
- CERTSubjectPublicKeyInfo *spki,
- SECItem **attributes)
-{
- CERTCertificateRequest *certreq;
- PRArenaPool *arena;
- CERTAttribute * attribute;
- SECOidData * oidData;
- SECStatus rv;
- int i = 0;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return NULL;
- }
-
- certreq = PORT_ArenaZNew(arena, CERTCertificateRequest);
- if (!certreq) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
- /* below here it is safe to goto loser */
-
- certreq->arena = arena;
-
- rv = DER_SetUInteger(arena, &certreq->version,
- SEC_CERTIFICATE_REQUEST_VERSION);
- if (rv != SECSuccess)
- goto loser;
-
- rv = CERT_CopyName(arena, &certreq->subject, subject);
- if (rv != SECSuccess)
- goto loser;
-
- rv = SECKEY_CopySubjectPublicKeyInfo(arena,
- &certreq->subjectPublicKeyInfo,
- spki);
- if (rv != SECSuccess)
- goto loser;
-
- certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute*, 2);
- if(!certreq->attributes)
- goto loser;
-
- /* Copy over attribute information */
- if (!attributes || !attributes[0]) {
- /*
- ** Invent empty attribute information. According to the
- ** pkcs#10 spec, attributes has this ASN.1 type:
- **
- ** attributes [0] IMPLICIT Attributes
- **
- ** Which means, we should create a NULL terminated list
- ** with the first entry being NULL;
- */
- certreq->attributes[0] = NULL;
- return certreq;
- }
-
- /* allocate space for attributes */
- attribute = PORT_ArenaZNew(arena, CERTAttribute);
- if (!attribute)
- goto loser;
-
- oidData = SECOID_FindOIDByTag( SEC_OID_PKCS9_EXTENSION_REQUEST );
- PORT_Assert(oidData);
- if (!oidData)
- goto loser;
- rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid);
- if (rv != SECSuccess)
- goto loser;
-
- for (i = 0; attributes[i] != NULL ; i++)
- ;
- attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i+1);
- if (!attribute->attrValue)
- goto loser;
-
- /* copy attributes */
- for (i = 0; attributes[i]; i++) {
- /*
- ** Attributes are a SetOf Attribute which implies
- ** lexigraphical ordering. It is assumes that the
- ** attributes are passed in sorted. If we need to
- ** add functionality to sort them, there is an
- ** example in the PKCS 7 code.
- */
- attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
- if(!attribute->attrValue[i])
- goto loser;
- }
-
- certreq->attributes[0] = attribute;
-
- return certreq;
-
-loser:
- CERT_DestroyCertificateRequest(certreq);
- return NULL;
-}
-
-void
-CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
-{
- if (req && req->arena) {
- PORT_FreeArena(req->arena, PR_FALSE);
- }
- return;
-}
-
-static void
-setCRExt(void *o, CERTCertExtension **exts)
-{
- ((CERTCertificateRequest *)o)->attributes = (struct CERTAttributeStr **)exts;
-}
-
-/*
-** Set up to start gathering cert extensions for a cert request.
-** The list is created as CertExtensions and converted to an
-** attribute list by CERT_FinishCRAttributes().
- */
-extern void *cert_StartExtensions(void *owner, PRArenaPool *ownerArena,
- void (*setExts)(void *object, CERTCertExtension **exts));
-void *
-CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
-{
- return (cert_StartExtensions ((void *)req, req->arena, setCRExt));
-}
-
-/*
-** At entry req->attributes actually contains an list of cert extensions--
-** req-attributes is overloaded until the list is DER encoded (the first
-** ...EncodeItem() below).
-** We turn this into an attribute list by encapsulating it
-** in a PKCS 10 Attribute structure
- */
-SECStatus
-CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
-{ SECItem *extlist;
- SECOidData *oidrec;
- CERTAttribute *attribute;
-
- if (!req || !req->arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (req->attributes == NULL || req->attributes[0] == NULL)
- return SECSuccess;
-
- extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes,
- SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate));
- if (extlist == NULL)
- return(SECFailure);
-
- oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
- if (oidrec == NULL)
- return SECFailure;
-
- /* now change the list of cert extensions into a list of attributes
- */
- req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute*, 2);
-
- attribute = PORT_ArenaZNew(req->arena, CERTAttribute);
-
- if (req->attributes == NULL || attribute == NULL ||
- SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem*, 2);
-
- if (attribute->attrValue == NULL)
- return SECFailure;
-
- attribute->attrValue[0] = extlist;
- attribute->attrValue[1] = NULL;
- req->attributes[0] = attribute;
- req->attributes[1] = NULL;
-
- return SECSuccess;
-}
-
-SECStatus
-CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
- CERTCertExtension ***exts)
-{
- if (req == NULL || exts == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (req->attributes == NULL || *req->attributes == NULL)
- return SECSuccess;
-
- if ((*req->attributes)->attrValue == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- return(SEC_ASN1DecodeItem(req->arena, exts,
- SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
- (*req->attributes)->attrValue[0]));
-}
diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c
deleted file mode 100644
index b7f6dddcb..000000000
--- a/security/nss/lib/certhigh/certvfy.c
+++ /dev/null
@@ -1,1829 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "nspr.h"
-#include "secerr.h"
-#include "secport.h"
-#include "seccomon.h"
-#include "secoid.h"
-#include "sslerr.h"
-#include "genname.h"
-#include "keyhi.h"
-#include "cert.h"
-#include "certdb.h"
-#include "certi.h"
-#include "cryptohi.h"
-#include "pkix.h"
-/*#include "pkix_sample_modules.h" */
-#include "pkix_pl_cert.h"
-
-
-#include "nsspki.h"
-#include "pkitm.h"
-#include "pkim.h"
-#include "pki3hack.h"
-#include "base.h"
-
-/*
- * Check the validity times of a certificate
- */
-SECStatus
-CERT_CertTimesValid(CERTCertificate *c)
-{
- SECCertTimeValidity valid = CERT_CheckCertValidTimes(c, PR_Now(), PR_TRUE);
- return (valid == secCertTimeValid) ? SECSuccess : SECFailure;
-}
-
-/*
- * verify the signature of a signed data object with the given DER publickey
- */
-SECStatus
-CERT_VerifySignedDataWithPublicKey(CERTSignedData *sd,
- SECKEYPublicKey *pubKey,
- void *wincx)
-{
- SECStatus rv;
- SECItem sig;
- SECOidTag hashAlg = SEC_OID_UNKNOWN;
-
- if ( !pubKey || !sd ) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
-
- /* check the signature */
- sig = sd->signature;
- /* convert sig->len from bit counts to byte count. */
- DER_ConvertBitString(&sig);
-
- rv = VFY_VerifyDataWithAlgorithmID(sd->data.data, sd->data.len, pubKey,
- &sig, &sd->signatureAlgorithm, &hashAlg, wincx);
- if (rv == SECSuccess) {
- /* Are we honoring signatures for this algorithm? */
- PRUint32 policyFlags = 0;
- rv = NSS_GetAlgorithmPolicy(hashAlg, &policyFlags);
- if (rv == SECSuccess &&
- !(policyFlags & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
- PORT_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
- rv = SECFailure;
- }
- }
- return rv;
-}
-
-/*
- * verify the signature of a signed data object with the given DER publickey
- */
-SECStatus
-CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd,
- CERTSubjectPublicKeyInfo *pubKeyInfo,
- void *wincx)
-{
- SECKEYPublicKey *pubKey;
- SECStatus rv = SECFailure;
-
- /* get cert's public key */
- pubKey = SECKEY_ExtractPublicKey(pubKeyInfo);
- if (pubKey) {
- rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx);
- SECKEY_DestroyPublicKey(pubKey);
- }
- return rv;
-}
-
-/*
- * verify the signature of a signed data object with the given certificate
- */
-SECStatus
-CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert,
- int64 t, void *wincx)
-{
- SECKEYPublicKey *pubKey = 0;
- SECStatus rv = SECFailure;
- SECCertTimeValidity validity;
-
- /* check the certificate's validity */
- validity = CERT_CheckCertValidTimes(cert, t, PR_FALSE);
- if ( validity != secCertTimeValid ) {
- return rv;
- }
-
- /* get cert's public key */
- pubKey = CERT_ExtractPublicKey(cert);
- if (pubKey) {
- rv = CERT_VerifySignedDataWithPublicKey(sd, pubKey, wincx);
- SECKEY_DestroyPublicKey(pubKey);
- }
- return rv;
-}
-
-
-SECStatus
-SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert,
- CERTCertificate *caCert, int64 t, void * wincx)
-{
- return CERT_CheckCRL(cert, caCert, NULL, t, wincx);
-}
-
-/*
- * Find the issuer of a cert. Use the authorityKeyID if it exists.
- */
-CERTCertificate *
-CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage)
-{
- NSSCertificate *me;
- NSSTime *nssTime;
- NSSTrustDomain *td;
- NSSCryptoContext *cc;
- NSSCertificate *chain[3];
- NSSUsage nssUsage;
- PRStatus status;
-
- me = STAN_GetNSSCertificate(cert);
- if (!me) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
- nssTime = NSSTime_SetPRTime(NULL, validTime);
- nssUsage.anyUsage = PR_FALSE;
- nssUsage.nss3usage = usage;
- nssUsage.nss3lookingForCA = PR_TRUE;
- memset(chain, 0, 3*sizeof(NSSCertificate *));
- td = STAN_GetDefaultTrustDomain();
- cc = STAN_GetDefaultCryptoContext();
- (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL,
- chain, 2, NULL, &status, td, cc);
- nss_ZFreeIf(nssTime);
- if (status == PR_SUCCESS) {
- PORT_Assert(me == chain[0]);
- /* if it's a root, the chain will only have one cert */
- if (!chain[1]) {
- /* already has a reference from the call to BuildChain */
- return cert;
- }
- NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */
- return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */
- }
- if (chain[0]) {
- PORT_Assert(me == chain[0]);
- NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */
- }
- PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER);
- return NULL;
-}
-
-/*
- * return required trust flags for various cert usages for CAs
- */
-SECStatus
-CERT_TrustFlagsForCACertUsage(SECCertUsage usage,
- unsigned int *retFlags,
- SECTrustType *retTrustType)
-{
- unsigned int requiredFlags;
- SECTrustType trustType;
-
- switch ( usage ) {
- case certUsageSSLClient:
- requiredFlags = CERTDB_TRUSTED_CLIENT_CA;
- trustType = trustSSL;
- break;
- case certUsageSSLServer:
- case certUsageSSLCA:
- requiredFlags = CERTDB_TRUSTED_CA;
- trustType = trustSSL;
- break;
- case certUsageSSLServerWithStepUp:
- requiredFlags = CERTDB_TRUSTED_CA | CERTDB_GOVT_APPROVED_CA;
- trustType = trustSSL;
- break;
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- requiredFlags = CERTDB_TRUSTED_CA;
- trustType = trustEmail;
- break;
- case certUsageObjectSigner:
- requiredFlags = CERTDB_TRUSTED_CA;
- trustType = trustObjectSigning;
- break;
- case certUsageVerifyCA:
- case certUsageAnyCA:
- case certUsageStatusResponder:
- requiredFlags = CERTDB_TRUSTED_CA;
- trustType = trustTypeNone;
- break;
- default:
- PORT_Assert(0);
- goto loser;
- }
- if ( retFlags != NULL ) {
- *retFlags = requiredFlags;
- }
- if ( retTrustType != NULL ) {
- *retTrustType = trustType;
- }
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-void
-cert_AddToVerifyLog(CERTVerifyLog *log, CERTCertificate *cert, long error,
- unsigned int depth, void *arg)
-{
- CERTVerifyLogNode *node, *tnode;
-
- PORT_Assert(log != NULL);
-
- node = (CERTVerifyLogNode *)PORT_ArenaAlloc(log->arena,
- sizeof(CERTVerifyLogNode));
- if ( node != NULL ) {
- node->cert = CERT_DupCertificate(cert);
- node->error = error;
- node->depth = depth;
- node->arg = arg;
-
- if ( log->tail == NULL ) {
- /* empty list */
- log->head = log->tail = node;
- node->prev = NULL;
- node->next = NULL;
- } else if ( depth >= log->tail->depth ) {
- /* add to tail */
- node->prev = log->tail;
- log->tail->next = node;
- log->tail = node;
- node->next = NULL;
- } else if ( depth < log->head->depth ) {
- /* add at head */
- node->prev = NULL;
- node->next = log->head;
- log->head->prev = node;
- log->head = node;
- } else {
- /* add in middle */
- tnode = log->tail;
- while ( tnode != NULL ) {
- if ( depth >= tnode->depth ) {
- /* insert after tnode */
- node->prev = tnode;
- node->next = tnode->next;
- tnode->next->prev = node;
- tnode->next = node;
- break;
- }
-
- tnode = tnode->prev;
- }
- }
-
- log->count++;
- }
- return;
-}
-
-#define EXIT_IF_NOT_LOGGING(log) \
- if ( log == NULL ) { \
- goto loser; \
- }
-
-#define LOG_ERROR_OR_EXIT(log,cert,depth,arg) \
- if ( log != NULL ) { \
- cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \
- (void *)(PRWord)arg); \
- } else { \
- goto loser; \
- }
-
-#define LOG_ERROR(log,cert,depth,arg) \
- if ( log != NULL ) { \
- cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \
- (void *)(PRWord)arg); \
- }
-
-static SECStatus
-cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, PRBool* sigerror,
- SECCertUsage certUsage, int64 t, void *wincx,
- CERTVerifyLog *log, PRBool* revoked)
-{
- SECTrustType trustType;
- CERTBasicConstraints basicConstraint;
- CERTCertificate *issuerCert = NULL;
- CERTCertificate *subjectCert = NULL;
- CERTCertificate *badCert = NULL;
- PRBool isca;
- SECStatus rv;
- SECStatus rvFinal = SECSuccess;
- int count;
- int currentPathLen = 0;
- int pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT;
- unsigned int caCertType;
- unsigned int requiredCAKeyUsage;
- unsigned int requiredFlags;
- PRArenaPool *arena = NULL;
- CERTGeneralName *namesList = NULL;
- CERTCertificate **certsList = NULL;
- int certsListLen = 16;
- int namesCount = 0;
- PRBool subjectCertIsSelfIssued;
- CERTCertTrust issuerTrust;
-
- if (revoked) {
- *revoked = PR_FALSE;
- }
-
- if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE,
- &requiredCAKeyUsage,
- &caCertType)
- != SECSuccess ) {
- PORT_Assert(0);
- EXIT_IF_NOT_LOGGING(log);
- requiredCAKeyUsage = 0;
- caCertType = 0;
- }
-
- switch ( certUsage ) {
- case certUsageSSLClient:
- case certUsageSSLServer:
- case certUsageSSLCA:
- case certUsageSSLServerWithStepUp:
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- case certUsageObjectSigner:
- case certUsageVerifyCA:
- case certUsageAnyCA:
- case certUsageStatusResponder:
- if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,
- &trustType) != SECSuccess ) {
- PORT_Assert(0);
- EXIT_IF_NOT_LOGGING(log);
- /* XXX continuing with requiredFlags = 0 seems wrong. It'll
- * cause the following test to be true incorrectly:
- * flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
- * if (( flags & requiredFlags ) == requiredFlags) {
- * rv = rvFinal;
- * goto done;
- * }
- * There are three other instances of this problem.
- */
- requiredFlags = 0;
- trustType = trustSSL;
- }
- break;
- default:
- PORT_Assert(0);
- EXIT_IF_NOT_LOGGING(log);
- requiredFlags = 0;
- trustType = trustSSL;/* This used to be 0, but we need something
- * that matches the enumeration type.
- */
- caCertType = 0;
- }
-
- subjectCert = CERT_DupCertificate(cert);
- if ( subjectCert == NULL ) {
- goto loser;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto loser;
- }
-
- certsList = PORT_ZNewArray(CERTCertificate *, certsListLen);
- if (certsList == NULL)
- goto loser;
-
- /* RFC 3280 says that the name constraints will apply to the names
- ** in the leaf (EE) cert, whether it is self issued or not, so
- ** we pretend that it is not.
- */
- subjectCertIsSelfIssued = PR_FALSE;
- for ( count = 0; count < CERT_MAX_CERT_CHAIN; count++ ) {
- PRBool validCAOverride = PR_FALSE;
-
- /* Construct a list of names for the current and all previous
- * certifcates (except leaf (EE) certs, root CAs, and self-issued
- * intermediate CAs) to be verified against the name constraints
- * extension of the issuer certificate.
- */
- if (subjectCertIsSelfIssued == PR_FALSE) {
- CERTGeneralName *subjectNameList;
- int subjectNameListLen;
- int i;
- PRBool getSubjectCN = (!count && certUsage == certUsageSSLServer);
- subjectNameList =
- CERT_GetConstrainedCertificateNames(subjectCert, arena,
- getSubjectCN);
- if (!subjectNameList)
- goto loser;
- subjectNameListLen = CERT_GetNamesLength(subjectNameList);
- if (!subjectNameListLen)
- goto loser;
- if (certsListLen <= namesCount + subjectNameListLen) {
- CERTCertificate **tmpCertsList;
- certsListLen = (namesCount + subjectNameListLen) * 2;
- tmpCertsList =
- (CERTCertificate **)PORT_Realloc(certsList,
- certsListLen * sizeof(CERTCertificate *));
- if (tmpCertsList == NULL) {
- goto loser;
- }
- certsList = tmpCertsList;
- }
- for (i = 0; i < subjectNameListLen; i++) {
- certsList[namesCount + i] = subjectCert;
- }
- namesCount += subjectNameListLen;
- namesList = cert_CombineNamesLists(namesList, subjectNameList);
- }
-
- /* check if the cert has an unsupported critical extension */
- if ( subjectCert->options.bits.hasUnsupportedCriticalExt ) {
- PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
- LOG_ERROR_OR_EXIT(log,subjectCert,count,0);
- }
-
- /* find the certificate of the issuer */
- issuerCert = CERT_FindCertIssuer(subjectCert, t, certUsage);
- if ( ! issuerCert ) {
- PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
- LOG_ERROR(log,subjectCert,count,0);
- goto loser;
- }
-
- /* verify the signature on the cert */
- if ( checkSig ) {
- rv = CERT_VerifySignedData(&subjectCert->signatureWrap,
- issuerCert, t, wincx);
-
- if ( rv != SECSuccess ) {
- if (sigerror) {
- *sigerror = PR_TRUE;
- }
- if ( PORT_GetError() == SEC_ERROR_EXPIRED_CERTIFICATE ) {
- PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE);
- LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0);
- } else {
- if (PORT_GetError() !=
- SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- }
- LOG_ERROR_OR_EXIT(log,subjectCert,count,0);
- }
- }
- }
-
- /* If the basicConstraint extension is included in an immediate CA
- * certificate, make sure that the isCA flag is on. If the
- * pathLenConstraint component exists, it must be greater than the
- * number of CA certificates we have seen so far. If the extension
- * is omitted, we will assume that this is a CA certificate with
- * an unlimited pathLenConstraint (since it already passes the
- * netscape-cert-type extension checking).
- */
-
- rv = CERT_FindBasicConstraintExten(issuerCert, &basicConstraint);
- if ( rv != SECSuccess ) {
- if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) {
- LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0);
- }
- pathLengthLimit = CERT_UNLIMITED_PATH_CONSTRAINT;
- /* no basic constraints found, we aren't (yet) a CA. */
- isca = PR_FALSE;
- } else {
- if ( basicConstraint.isCA == PR_FALSE ) {
- PORT_SetError (SEC_ERROR_CA_CERT_INVALID);
- LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0);
- }
- pathLengthLimit = basicConstraint.pathLenConstraint;
- isca = PR_TRUE;
- }
- /* make sure that the path len constraint is properly set.*/
- if (pathLengthLimit >= 0 && currentPathLen > pathLengthLimit) {
- PORT_SetError (SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID);
- LOG_ERROR_OR_EXIT(log, issuerCert, count+1, pathLengthLimit);
- }
-
- /* XXX - the error logging may need to go down into CRL stuff at some
- * point
- */
- /* check revoked list (issuer) */
- rv = SEC_CheckCRL(handle, subjectCert, issuerCert, t, wincx);
- if (rv == SECFailure) {
- if (revoked) {
- *revoked = PR_TRUE;
- }
- LOG_ERROR_OR_EXIT(log,subjectCert,count,0);
- } else if (rv == SECWouldBlock) {
- /* We found something fishy, so we intend to issue an
- * error to the user, but the user may wish to continue
- * processing, in which case we better make sure nothing
- * worse has happened... so keep cranking the loop */
- rvFinal = SECFailure;
- if (revoked) {
- *revoked = PR_TRUE;
- }
- LOG_ERROR(log,subjectCert,count,0);
- }
-
- if ( CERT_GetCertTrust(issuerCert, &issuerTrust) == SECSuccess) {
- /* we have some trust info, but this does NOT imply that this
- * cert is actually trusted for any purpose. The cert may be
- * explicitly UNtrusted. We won't know until we examine the
- * trust bits.
- */
- unsigned int flags;
-
- if (certUsage != certUsageAnyCA &&
- certUsage != certUsageStatusResponder) {
-
- /*
- * XXX This choice of trustType seems arbitrary.
- */
- if ( certUsage == certUsageVerifyCA ) {
- if ( subjectCert->nsCertType & NS_CERT_TYPE_EMAIL_CA ) {
- trustType = trustEmail;
- } else if ( subjectCert->nsCertType & NS_CERT_TYPE_SSL_CA ) {
- trustType = trustSSL;
- } else {
- trustType = trustObjectSigning;
- }
- }
-
- flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType);
- if (( flags & requiredFlags ) == requiredFlags) {
- /* we found a trusted one, so return */
- rv = rvFinal;
- goto done;
- }
- if (flags & CERTDB_VALID_CA) {
- validCAOverride = PR_TRUE;
- }
- /* is it explicitly distrusted? */
- if ((flags & CERTDB_TERMINAL_RECORD) &&
- ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
- /* untrusted -- the cert is explicitly untrusted, not
- * just that it doesn't chain to a trusted cert */
- PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
- LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags);
- }
- } else {
- /* Check if we have any valid trust when cheching for
- * certUsageAnyCA or certUsageStatusResponder. */
- for (trustType = trustSSL; trustType < trustTypeNone;
- trustType++) {
- flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType);
- if ((flags & requiredFlags) == requiredFlags) {
- rv = rvFinal;
- goto done;
- }
- if (flags & CERTDB_VALID_CA)
- validCAOverride = PR_TRUE;
- }
- /* We have 2 separate loops because we want any single trust
- * bit to allow this usage to return trusted. Only if none of
- * the trust bits are on do we check to see if the cert is
- * untrusted */
- for (trustType = trustSSL; trustType < trustTypeNone;
- trustType++) {
- flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType);
- /* is it explicitly distrusted? */
- if ((flags & CERTDB_TERMINAL_RECORD) &&
- ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
- /* untrusted -- the cert is explicitly untrusted, not
- * just that it doesn't chain to a trusted cert */
- PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
- LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags);
- }
- }
- }
- }
-
- if (!validCAOverride) {
- /*
- * Make sure that if this is an intermediate CA in the chain that
- * it was given permission by its signer to be a CA.
- */
- /*
- * if basicConstraints says it is a ca, then we check the
- * nsCertType. If the nsCertType has any CA bits set, then
- * it must have the right one.
- */
- if (!isca || (issuerCert->nsCertType & NS_CERT_TYPE_CA)) {
- isca = (issuerCert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE;
- }
-
- if ( !isca ) {
- PORT_SetError(SEC_ERROR_CA_CERT_INVALID);
- LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0);
- }
-
- /* make sure key usage allows cert signing */
- if (CERT_CheckKeyUsage(issuerCert, requiredCAKeyUsage) != SECSuccess) {
- PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
- LOG_ERROR_OR_EXIT(log,issuerCert,count+1,requiredCAKeyUsage);
- }
- }
-
- /* make sure that the entire chain is within the name space of the
- ** current issuer certificate.
- */
- rv = CERT_CompareNameSpace(issuerCert, namesList, certsList,
- arena, &badCert);
- if (rv != SECSuccess || badCert != NULL) {
- PORT_SetError(SEC_ERROR_CERT_NOT_IN_NAME_SPACE);
- LOG_ERROR_OR_EXIT(log, badCert, count + 1, 0);
- goto loser;
- }
- /* make sure that the issuer is not self signed. If it is, then
- * stop here to prevent looping.
- */
- if (issuerCert->isRoot) {
- PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
- LOG_ERROR(log, issuerCert, count+1, 0);
- goto loser;
- }
- /* The issuer cert will be the subject cert in the next loop.
- * A cert is self-issued if its subject and issuer are equal and
- * both are of non-zero length.
- */
- subjectCertIsSelfIssued = (PRBool)
- SECITEM_ItemsAreEqual(&issuerCert->derIssuer,
- &issuerCert->derSubject) &&
- issuerCert->derSubject.len > 0;
- if (subjectCertIsSelfIssued == PR_FALSE) {
- /* RFC 3280 says only non-self-issued intermediate CA certs
- * count in path length.
- */
- ++currentPathLen;
- }
-
- CERT_DestroyCertificate(subjectCert);
- subjectCert = issuerCert;
- issuerCert = NULL;
- }
-
- PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
- LOG_ERROR(log,subjectCert,count,0);
-loser:
- rv = SECFailure;
-done:
- if (certsList != NULL) {
- PORT_Free(certsList);
- }
- if ( issuerCert ) {
- CERT_DestroyCertificate(issuerCert);
- }
-
- if ( subjectCert ) {
- CERT_DestroyCertificate(subjectCert);
- }
-
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return rv;
-}
-
-SECStatus
-cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, PRBool* sigerror,
- SECCertUsage certUsage, int64 t, void *wincx,
- CERTVerifyLog *log, PRBool* revoked)
-{
- if (CERT_GetUsePKIXForValidation()) {
- return cert_VerifyCertChainPkix(cert, checkSig, certUsage, t,
- wincx, log, sigerror, revoked);
- }
- return cert_VerifyCertChainOld(handle, cert, checkSig, sigerror,
- certUsage, t, wincx, log, revoked);
-}
-
-SECStatus
-CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, int64 t,
- void *wincx, CERTVerifyLog *log)
-{
- return cert_VerifyCertChain(handle, cert, checkSig, NULL, certUsage, t,
- wincx, log, NULL);
-}
-
-/*
- * verify that a CA can sign a certificate with the requested usage.
- */
-SECStatus
-CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, int64 t,
- void *wincx, CERTVerifyLog *log)
-{
- SECTrustType trustType;
- CERTBasicConstraints basicConstraint;
- PRBool isca;
- PRBool validCAOverride = PR_FALSE;
- SECStatus rv;
- SECStatus rvFinal = SECSuccess;
- unsigned int flags;
- unsigned int caCertType;
- unsigned int requiredCAKeyUsage;
- unsigned int requiredFlags;
- CERTCertificate *issuerCert;
- CERTCertTrust certTrust;
-
-
- if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE,
- &requiredCAKeyUsage,
- &caCertType) != SECSuccess ) {
- PORT_Assert(0);
- EXIT_IF_NOT_LOGGING(log);
- requiredCAKeyUsage = 0;
- caCertType = 0;
- }
-
- switch ( certUsage ) {
- case certUsageSSLClient:
- case certUsageSSLServer:
- case certUsageSSLCA:
- case certUsageSSLServerWithStepUp:
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- case certUsageObjectSigner:
- case certUsageVerifyCA:
- case certUsageStatusResponder:
- if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,
- &trustType) != SECSuccess ) {
- PORT_Assert(0);
- EXIT_IF_NOT_LOGGING(log);
- requiredFlags = 0;
- trustType = trustSSL;
- }
- break;
- default:
- PORT_Assert(0);
- EXIT_IF_NOT_LOGGING(log);
- requiredFlags = 0;
- trustType = trustSSL;/* This used to be 0, but we need something
- * that matches the enumeration type.
- */
- caCertType = 0;
- }
-
- /* If the basicConstraint extension is included in an intermmediate CA
- * certificate, make sure that the isCA flag is on. If the
- * pathLenConstraint component exists, it must be greater than the
- * number of CA certificates we have seen so far. If the extension
- * is omitted, we will assume that this is a CA certificate with
- * an unlimited pathLenConstraint (since it already passes the
- * netscape-cert-type extension checking).
- */
-
- rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);
- if ( rv != SECSuccess ) {
- if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) {
- LOG_ERROR_OR_EXIT(log,cert,0,0);
- }
- /* no basic constraints found, we aren't (yet) a CA. */
- isca = PR_FALSE;
- } else {
- if ( basicConstraint.isCA == PR_FALSE ) {
- PORT_SetError (SEC_ERROR_CA_CERT_INVALID);
- LOG_ERROR_OR_EXIT(log,cert,0,0);
- }
-
- /* can't check path length if we don't know the previous path */
- isca = PR_TRUE;
- }
-
- if ( CERT_GetCertTrust(cert, &certTrust) == SECSuccess ) {
- /* we have some trust info, but this does NOT imply that this
- * cert is actually trusted for any purpose. The cert may be
- * explicitly UNtrusted. We won't know until we examine the
- * trust bits.
- */
- if (certUsage == certUsageStatusResponder) {
- /* Check the special case of certUsageStatusResponder */
- issuerCert = CERT_FindCertIssuer(cert, t, certUsage);
- if (issuerCert) {
- if (SEC_CheckCRL(handle, cert, issuerCert, t, wincx)
- != SECSuccess) {
- PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
- CERT_DestroyCertificate(issuerCert);
- goto loser;
- }
- CERT_DestroyCertificate(issuerCert);
- }
- /* XXX We have NOT determined that this cert is trusted.
- * For years, NSS has treated this as trusted,
- * but it seems incorrect.
- */
- rv = rvFinal;
- goto done;
- }
-
- /*
- * check the trust params of the issuer
- */
- flags = SEC_GET_TRUST_FLAGS(&certTrust, trustType);
- if ( ( flags & requiredFlags ) == requiredFlags) {
- /* we found a trusted one, so return */
- rv = rvFinal;
- goto done;
- }
- if (flags & CERTDB_VALID_CA) {
- validCAOverride = PR_TRUE;
- }
- /* is it explicitly distrusted? */
- if ((flags & CERTDB_TERMINAL_RECORD) &&
- ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
- /* untrusted -- the cert is explicitly untrusted, not
- * just that it doesn't chain to a trusted cert */
- PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
- LOG_ERROR_OR_EXIT(log,cert,0,flags);
- }
- }
- if (!validCAOverride) {
- /*
- * Make sure that if this is an intermediate CA in the chain that
- * it was given permission by its signer to be a CA.
- */
- /*
- * if basicConstraints says it is a ca, then we check the
- * nsCertType. If the nsCertType has any CA bits set, then
- * it must have the right one.
- */
- if (!isca || (cert->nsCertType & NS_CERT_TYPE_CA)) {
- isca = (cert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE;
- }
-
- if (!isca) {
- PORT_SetError(SEC_ERROR_CA_CERT_INVALID);
- LOG_ERROR_OR_EXIT(log,cert,0,0);
- }
-
- /* make sure key usage allows cert signing */
- if (CERT_CheckKeyUsage(cert, requiredCAKeyUsage) != SECSuccess) {
- PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
- LOG_ERROR_OR_EXIT(log,cert,0,requiredCAKeyUsage);
- }
- }
- /* make sure that the issuer is not self signed. If it is, then
- * stop here to prevent looping.
- */
- if (cert->isRoot) {
- PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
- LOG_ERROR(log, cert, 0, 0);
- goto loser;
- }
-
- return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t,
- wincx, log);
-loser:
- rv = SECFailure;
-done:
- return rv;
-}
-
-#define NEXT_USAGE() { \
- i*=2; \
- certUsage++; \
- continue; \
-}
-
-#define VALID_USAGE() { \
- NEXT_USAGE(); \
-}
-
-#define INVALID_USAGE() { \
- if (returnedUsages) { \
- *returnedUsages &= (~i); \
- } \
- if (PR_TRUE == requiredUsage) { \
- valid = SECFailure; \
- } \
- NEXT_USAGE(); \
-}
-
-/*
- * check the leaf cert against trust and usage.
- * returns success if the cert is not distrusted. If the cert is
- * trusted, then the trusted bool will be true.
- * returns failure if the cert is distrusted. If failure, flags
- * will return the flag bits that indicated distrust.
- */
-SECStatus
-cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
- unsigned int *failedFlags, PRBool *trusted)
-{
- unsigned int flags;
- CERTCertTrust trust;
-
- *failedFlags = 0;
- *trusted = PR_FALSE;
-
- /* check trust flags to see if this cert is directly trusted */
- if ( CERT_GetCertTrust(cert, &trust) == SECSuccess ) {
- switch ( certUsage ) {
- case certUsageSSLClient:
- case certUsageSSLServer:
- flags = trust.sslFlags;
-
- /* is the cert directly trusted or not trusted ? */
- if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
- * authoritative */
- if ( flags & CERTDB_TRUSTED ) { /* trust this cert */
- *trusted = PR_TRUE;
- return SECSuccess;
- } else { /* don't trust this cert */
- *failedFlags = flags;
- return SECFailure;
- }
- }
- break;
- case certUsageSSLServerWithStepUp:
- /* XXX - step up certs can't be directly trusted, only distrust */
- flags = trust.sslFlags;
- if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
- * authoritative */
- if (( flags & CERTDB_TRUSTED ) == 0) {
- /* don't trust this cert */
- *failedFlags = flags;
- return SECFailure;
- }
- }
- break;
- case certUsageSSLCA:
- flags = trust.sslFlags;
- if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
- * authoritative */
- if (( flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA) ) == 0) {
- /* don't trust this cert */
- *failedFlags = flags;
- return SECFailure;
- }
- }
- break;
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- flags = trust.emailFlags;
- if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
- * authoritative */
- if ( flags & CERTDB_TRUSTED ) { /* trust this cert */
- *trusted = PR_TRUE;
- return SECSuccess;
- }
- else { /* don't trust this cert */
- *failedFlags = flags;
- return SECFailure;
- }
- }
-
- break;
- case certUsageObjectSigner:
- flags = trust.objectSigningFlags;
-
- if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
- * authoritative */
- if ( flags & CERTDB_TRUSTED ) { /* trust this cert */
- *trusted = PR_TRUE;
- return SECSuccess;
- } else { /* don't trust this cert */
- *failedFlags = flags;
- return SECFailure;
- }
- }
- break;
- case certUsageVerifyCA:
- case certUsageStatusResponder:
- flags = trust.sslFlags;
- /* is the cert directly trusted or not trusted ? */
- if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) ==
- ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) {
- *trusted = PR_TRUE;
- return SECSuccess;
- }
- flags = trust.emailFlags;
- /* is the cert directly trusted or not trusted ? */
- if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) ==
- ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) {
- *trusted = PR_TRUE;
- return SECSuccess;
- }
- flags = trust.objectSigningFlags;
- /* is the cert directly trusted or not trusted ? */
- if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) ==
- ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) {
- *trusted = PR_TRUE;
- return SECSuccess;
- }
- /* fall through to test distrust */
- case certUsageAnyCA:
- case certUsageUserCertImport:
- /* do we distrust these certs explicitly */
- flags = trust.sslFlags;
- if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
- * authoritative */
- if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
- *failedFlags = flags;
- return SECFailure;
- }
- }
- flags = trust.emailFlags;
- if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
- * authoritative */
- if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
- *failedFlags = flags;
- return SECFailure;
- }
- }
- /* fall through */
- case certUsageProtectedObjectSigner:
- flags = trust.objectSigningFlags;
- if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
- * authoritative */
- if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
- *failedFlags = flags;
- return SECFailure;
- }
- }
- break;
- }
- }
- return SECSuccess;
-}
-
-/*
- * verify a certificate by checking if it's valid and that we
- * trust the issuer.
- *
- * certificateUsage contains a bitfield of all cert usages that are
- * required for verification to succeed
- *
- * a bitfield of cert usages is returned in *returnedUsages
- * if requiredUsages is non-zero, the returned bitmap is only
- * for those required usages, otherwise it is for all usages
- *
- */
-SECStatus
-CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertificateUsage requiredUsages, int64 t,
- void *wincx, CERTVerifyLog *log, SECCertificateUsage* returnedUsages)
-{
- SECStatus rv;
- SECStatus valid;
- unsigned int requiredKeyUsage;
- unsigned int requiredCertType;
- unsigned int flags;
- unsigned int certType;
- PRBool allowOverride;
- SECCertTimeValidity validity;
- CERTStatusConfig *statusConfig;
- PRInt32 i;
- SECCertUsage certUsage = 0;
- PRBool checkedOCSP = PR_FALSE;
- PRBool checkAllUsages = PR_FALSE;
- PRBool revoked = PR_FALSE;
- PRBool sigerror = PR_FALSE;
- PRBool trusted = PR_FALSE;
-
- if (!requiredUsages) {
- /* there are no required usages, so the user probably wants to
- get status for all usages */
- checkAllUsages = PR_TRUE;
- }
-
- if (returnedUsages) {
- *returnedUsages = 0;
- } else {
- /* we don't have a place to return status for all usages,
- so we can skip checks for usages that aren't required */
- checkAllUsages = PR_FALSE;
- }
- valid = SECSuccess ; /* start off assuming cert is valid */
-
- /* make sure that the cert is valid at time t */
- allowOverride = (PRBool)((requiredUsages & certificateUsageSSLServer) ||
- (requiredUsages & certificateUsageSSLServerWithStepUp));
- validity = CERT_CheckCertValidTimes(cert, t, allowOverride);
- if ( validity != secCertTimeValid ) {
- valid = SECFailure;
- LOG_ERROR_OR_EXIT(log,cert,0,validity);
- }
-
- /* check key usage and netscape cert type */
- cert_GetCertType(cert);
- certType = cert->nsCertType;
-
- for (i=1; i<=certificateUsageHighest &&
- (SECSuccess == valid || returnedUsages || log) ; ) {
- PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE;
- if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) {
- NEXT_USAGE();
- }
- if (returnedUsages) {
- *returnedUsages |= i; /* start off assuming this usage is valid */
- }
- switch ( certUsage ) {
- case certUsageSSLClient:
- case certUsageSSLServer:
- case certUsageSSLServerWithStepUp:
- case certUsageSSLCA:
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- case certUsageObjectSigner:
- case certUsageStatusResponder:
- rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE,
- &requiredKeyUsage,
- &requiredCertType);
- if ( rv != SECSuccess ) {
- PORT_Assert(0);
- /* EXIT_IF_NOT_LOGGING(log); XXX ??? */
- requiredKeyUsage = 0;
- requiredCertType = 0;
- INVALID_USAGE();
- }
- break;
-
- case certUsageAnyCA:
- case certUsageProtectedObjectSigner:
- case certUsageUserCertImport:
- case certUsageVerifyCA:
- /* these usages cannot be verified */
- NEXT_USAGE();
-
- default:
- PORT_Assert(0);
- requiredKeyUsage = 0;
- requiredCertType = 0;
- INVALID_USAGE();
- }
- if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) {
- if (PR_TRUE == requiredUsage) {
- PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
- }
- LOG_ERROR(log,cert,0,requiredKeyUsage);
- INVALID_USAGE();
- }
- if ( !( certType & requiredCertType ) ) {
- if (PR_TRUE == requiredUsage) {
- PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE);
- }
- LOG_ERROR(log,cert,0,requiredCertType);
- INVALID_USAGE();
- }
-
- rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted);
- if (rv == SECFailure) {
- if (PR_TRUE == requiredUsage) {
- PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
- }
- LOG_ERROR(log, cert, 0, flags);
- INVALID_USAGE();
- } else if (trusted) {
- VALID_USAGE();
- }
-
- if (PR_TRUE == revoked || PR_TRUE == sigerror) {
- INVALID_USAGE();
- }
-
- rv = cert_VerifyCertChain(handle, cert,
- checkSig, &sigerror,
- certUsage, t, wincx, log,
- &revoked);
-
- if (rv != SECSuccess) {
- /* EXIT_IF_NOT_LOGGING(log); XXX ???? */
- INVALID_USAGE();
- }
-
- /*
- * Check OCSP revocation status, but only if the cert we are checking
- * is not a status reponder itself. We only do this in the case
- * where we checked the cert chain (above); explicit trust "wins"
- * (avoids status checking, just as it avoids CRL checking) by
- * bypassing this code.
- */
-
- if (PR_FALSE == checkedOCSP) {
- checkedOCSP = PR_TRUE; /* only check OCSP once */
- statusConfig = CERT_GetStatusConfig(handle);
- if (requiredUsages != certificateUsageStatusResponder &&
- statusConfig != NULL) {
- if (statusConfig->statusChecker != NULL) {
- rv = (* statusConfig->statusChecker)(handle, cert,
- t, wincx);
- if (rv != SECSuccess) {
- LOG_ERROR(log,cert,0,0);
- revoked = PR_TRUE;
- INVALID_USAGE();
- }
- }
- }
- }
-
- NEXT_USAGE();
- }
-
-loser:
- return(valid);
-}
-
-SECStatus
-CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, int64 t,
- void *wincx, CERTVerifyLog *log)
-{
- SECStatus rv;
- unsigned int requiredKeyUsage;
- unsigned int requiredCertType;
- unsigned int flags;
- unsigned int certType;
- PRBool trusted;
- PRBool allowOverride;
- SECCertTimeValidity validity;
- CERTStatusConfig *statusConfig;
-
-#ifdef notdef
- /* check if this cert is in the Evil list */
- rv = CERT_CheckForEvilCert(cert);
- if ( rv != SECSuccess ) {
- PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
- LOG_ERROR_OR_EXIT(log,cert,0,0);
- }
-#endif
-
- /* make sure that the cert is valid at time t */
- allowOverride = (PRBool)((certUsage == certUsageSSLServer) ||
- (certUsage == certUsageSSLServerWithStepUp));
- validity = CERT_CheckCertValidTimes(cert, t, allowOverride);
- if ( validity != secCertTimeValid ) {
- LOG_ERROR_OR_EXIT(log,cert,0,validity);
- }
-
- /* check key usage and netscape cert type */
- cert_GetCertType(cert);
- certType = cert->nsCertType;
- switch ( certUsage ) {
- case certUsageSSLClient:
- case certUsageSSLServer:
- case certUsageSSLServerWithStepUp:
- case certUsageSSLCA:
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- case certUsageObjectSigner:
- case certUsageStatusResponder:
- rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE,
- &requiredKeyUsage,
- &requiredCertType);
- if ( rv != SECSuccess ) {
- PORT_Assert(0);
- EXIT_IF_NOT_LOGGING(log);
- requiredKeyUsage = 0;
- requiredCertType = 0;
- }
- break;
- case certUsageVerifyCA:
- case certUsageAnyCA:
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_CA;
- if ( ! ( certType & NS_CERT_TYPE_CA ) ) {
- certType |= NS_CERT_TYPE_CA;
- }
- break;
- default:
- PORT_Assert(0);
- EXIT_IF_NOT_LOGGING(log);
- requiredKeyUsage = 0;
- requiredCertType = 0;
- }
- if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) {
- PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
- LOG_ERROR_OR_EXIT(log,cert,0,requiredKeyUsage);
- }
- if ( !( certType & requiredCertType ) ) {
- PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE);
- LOG_ERROR_OR_EXIT(log,cert,0,requiredCertType);
- }
-
- rv = cert_CheckLeafTrust(cert,certUsage, &flags, &trusted);
- if (rv == SECFailure) {
- PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
- LOG_ERROR_OR_EXIT(log,cert,0,flags);
- } else if (trusted) {
- goto winner;
- }
-
-
- rv = CERT_VerifyCertChain(handle, cert, checkSig, certUsage,
- t, wincx, log);
- if (rv != SECSuccess) {
- EXIT_IF_NOT_LOGGING(log);
- }
-
- /*
- * Check revocation status, but only if the cert we are checking
- * is not a status reponder itself. We only do this in the case
- * where we checked the cert chain (above); explicit trust "wins"
- * (avoids status checking, just as it avoids CRL checking, which
- * is all done inside VerifyCertChain) by bypassing this code.
- */
- statusConfig = CERT_GetStatusConfig(handle);
- if (certUsage != certUsageStatusResponder && statusConfig != NULL) {
- if (statusConfig->statusChecker != NULL) {
- rv = (* statusConfig->statusChecker)(handle, cert,
- t, wincx);
- if (rv != SECSuccess) {
- LOG_ERROR_OR_EXIT(log,cert,0,0);
- }
- }
- }
-
-winner:
- return(SECSuccess);
-
-loser:
- rv = SECFailure;
-
- return(rv);
-}
-
-/*
- * verify a certificate by checking if its valid and that we
- * trust the issuer. Verify time against now.
- */
-SECStatus
-CERT_VerifyCertificateNow(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertificateUsage requiredUsages,
- void *wincx, SECCertificateUsage* returnedUsages)
-{
- return(CERT_VerifyCertificate(handle, cert, checkSig,
- requiredUsages, PR_Now(), wincx, NULL, returnedUsages));
-}
-
-/* obsolete, do not use for new code */
-SECStatus
-CERT_VerifyCertNow(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool checkSig, SECCertUsage certUsage, void *wincx)
-{
- return(CERT_VerifyCert(handle, cert, checkSig,
- certUsage, PR_Now(), wincx, NULL));
-}
-
-
-/* [ FROM pcertdb.c ] */
-/*
- * Supported usage values and types:
- * certUsageSSLClient
- * certUsageSSLServer
- * certUsageSSLServerWithStepUp
- * certUsageEmailSigner
- * certUsageEmailRecipient
- * certUsageObjectSigner
- */
-
-CERTCertificate *
-CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName,
- CERTCertOwner owner, SECCertUsage usage,
- PRBool preferTrusted, int64 validTime, PRBool validOnly)
-{
- CERTCertList *certList = NULL;
- CERTCertificate *cert = NULL;
- CERTCertTrust certTrust;
- unsigned int requiredTrustFlags;
- SECTrustType requiredTrustType;
- unsigned int flags;
-
- PRBool lookingForCA = PR_FALSE;
- SECStatus rv;
- CERTCertListNode *node;
- CERTCertificate *saveUntrustedCA = NULL;
-
- /* if preferTrusted is set, must be a CA cert */
- PORT_Assert( ! ( preferTrusted && ( owner != certOwnerCA ) ) );
-
- if ( owner == certOwnerCA ) {
- lookingForCA = PR_TRUE;
- if ( preferTrusted ) {
- rv = CERT_TrustFlagsForCACertUsage(usage, &requiredTrustFlags,
- &requiredTrustType);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- requiredTrustFlags |= CERTDB_VALID_CA;
- }
- }
-
- certList = CERT_CreateSubjectCertList(NULL, handle, derName, validTime,
- validOnly);
- if ( certList != NULL ) {
- rv = CERT_FilterCertListByUsage(certList, usage, lookingForCA);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- node = CERT_LIST_HEAD(certList);
-
- while ( !CERT_LIST_END(node, certList) ) {
- cert = node->cert;
-
- /* looking for a trusted CA cert */
- if ( ( owner == certOwnerCA ) && preferTrusted &&
- ( requiredTrustType != trustTypeNone ) ) {
-
- if ( CERT_GetCertTrust(cert, &certTrust) != SECSuccess ) {
- flags = 0;
- } else {
- flags = SEC_GET_TRUST_FLAGS(&certTrust, requiredTrustType);
- }
-
- if ( ( flags & requiredTrustFlags ) != requiredTrustFlags ) {
- /* cert is not trusted */
- /* if this is the first cert to get this far, then save
- * it, so we can use it if we can't find a trusted one
- */
- if ( saveUntrustedCA == NULL ) {
- saveUntrustedCA = cert;
- }
- goto endloop;
- }
- }
- /* if we got this far, then this cert meets all criteria */
- break;
-
-endloop:
- node = CERT_LIST_NEXT(node);
- cert = NULL;
- }
-
- /* use the saved one if we have it */
- if ( cert == NULL ) {
- cert = saveUntrustedCA;
- }
-
- /* if we found one then bump the ref count before freeing the list */
- if ( cert != NULL ) {
- /* bump the ref count */
- cert = CERT_DupCertificate(cert);
- }
-
- CERT_DestroyCertList(certList);
- }
-
- return(cert);
-
-loser:
- if ( certList != NULL ) {
- CERT_DestroyCertList(certList);
- }
-
- return(NULL);
-}
-
-
-/* [ From certdb.c ] */
-/*
- * Filter a list of certificates, removing those certs that do not have
- * one of the named CA certs somewhere in their cert chain.
- *
- * "certList" - the list of certificates to filter
- * "nCANames" - number of CA names
- * "caNames" - array of CA names in string(rfc 1485) form
- * "usage" - what use the certs are for, this is used when
- * selecting CA certs
- */
-SECStatus
-CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames,
- char **caNames, SECCertUsage usage)
-{
- CERTCertificate *issuerCert = NULL;
- CERTCertificate *subjectCert;
- CERTCertListNode *node, *freenode;
- CERTCertificate *cert;
- int n;
- char **names;
- PRBool found;
- int64 time;
-
- if ( nCANames <= 0 ) {
- return(SECSuccess);
- }
-
- time = PR_Now();
-
- node = CERT_LIST_HEAD(certList);
-
- while ( ! CERT_LIST_END(node, certList) ) {
- cert = node->cert;
-
- subjectCert = CERT_DupCertificate(cert);
-
- /* traverse the CA certs for this cert */
- found = PR_FALSE;
- while ( subjectCert != NULL ) {
- n = nCANames;
- names = caNames;
-
- if (subjectCert->issuerName != NULL) {
- while ( n > 0 ) {
- if ( PORT_Strcmp(*names, subjectCert->issuerName) == 0 ) {
- found = PR_TRUE;
- break;
- }
-
- n--;
- names++;
- }
- }
-
- if ( found ) {
- break;
- }
-
- issuerCert = CERT_FindCertIssuer(subjectCert, time, usage);
- if ( issuerCert == subjectCert ) {
- CERT_DestroyCertificate(issuerCert);
- issuerCert = NULL;
- break;
- }
- CERT_DestroyCertificate(subjectCert);
- subjectCert = issuerCert;
-
- }
- CERT_DestroyCertificate(subjectCert);
- if ( !found ) {
- /* CA was not found, so remove this cert from the list */
- freenode = node;
- node = CERT_LIST_NEXT(node);
- CERT_RemoveCertListNode(freenode);
- } else {
- /* CA was found, so leave it in the list */
- node = CERT_LIST_NEXT(node);
- }
- }
-
- return(SECSuccess);
-}
-
-/*
- * Given a certificate, return a string containing the nickname, and possibly
- * one of the validity strings, based on the current validity state of the
- * certificate.
- *
- * "arena" - arena to allocate returned string from. If NULL, then heap
- * is used.
- * "cert" - the cert to get nickname from
- * "expiredString" - the string to append to the nickname if the cert is
- * expired.
- * "notYetGoodString" - the string to append to the nickname if the cert is
- * not yet good.
- */
-char *
-CERT_GetCertNicknameWithValidity(PRArenaPool *arena, CERTCertificate *cert,
- char *expiredString, char *notYetGoodString)
-{
- SECCertTimeValidity validity;
- char *nickname = NULL, *tmpstr = NULL;
-
- validity = CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE);
-
- /* if the cert is good, then just use the nickname directly */
- if ( validity == secCertTimeValid ) {
- if ( arena == NULL ) {
- nickname = PORT_Strdup(cert->nickname);
- } else {
- nickname = PORT_ArenaStrdup(arena, cert->nickname);
- }
-
- if ( nickname == NULL ) {
- goto loser;
- }
- } else {
-
- /* if the cert is not valid, then tack one of the strings on the
- * end
- */
- if ( validity == secCertTimeExpired ) {
- tmpstr = PR_smprintf("%s%s", cert->nickname,
- expiredString);
- } else if ( validity == secCertTimeNotValidYet ) {
- /* not yet valid */
- tmpstr = PR_smprintf("%s%s", cert->nickname,
- notYetGoodString);
- } else {
- /* undetermined */
- tmpstr = PR_smprintf("%s",
- "(NULL) (Validity Unknown)");
- }
-
- if ( tmpstr == NULL ) {
- goto loser;
- }
-
- if ( arena ) {
- /* copy the string into the arena and free the malloc'd one */
- nickname = PORT_ArenaStrdup(arena, tmpstr);
- PORT_Free(tmpstr);
- } else {
- nickname = tmpstr;
- }
- if ( nickname == NULL ) {
- goto loser;
- }
- }
- return(nickname);
-
-loser:
- return(NULL);
-}
-
-/*
- * Collect the nicknames from all certs in a CertList. If the cert is not
- * valid, append a string to that nickname.
- *
- * "certList" - the list of certificates
- * "expiredString" - the string to append to the nickname of any expired cert
- * "notYetGoodString" - the string to append to the nickname of any cert
- * that is not yet valid
- */
-CERTCertNicknames *
-CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString,
- char *notYetGoodString)
-{
- CERTCertNicknames *names;
- PRArenaPool *arena;
- CERTCertListNode *node;
- char **nn;
-
- /* allocate an arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
- }
-
- /* allocate the structure */
- names = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames));
- if ( names == NULL ) {
- goto loser;
- }
-
- /* init the structure */
- names->arena = arena;
- names->head = NULL;
- names->numnicknames = 0;
- names->nicknames = NULL;
- names->totallen = 0;
-
- /* count the certs in the list */
- node = CERT_LIST_HEAD(certList);
- while ( ! CERT_LIST_END(node, certList) ) {
- names->numnicknames++;
- node = CERT_LIST_NEXT(node);
- }
-
- /* allocate nicknames array */
- names->nicknames = PORT_ArenaAlloc(arena,
- sizeof(char *) * names->numnicknames);
- if ( names->nicknames == NULL ) {
- goto loser;
- }
-
- /* just in case printf can't deal with null strings */
- if (expiredString == NULL ) {
- expiredString = "";
- }
-
- if ( notYetGoodString == NULL ) {
- notYetGoodString = "";
- }
-
- /* traverse the list of certs and collect the nicknames */
- nn = names->nicknames;
- node = CERT_LIST_HEAD(certList);
- while ( ! CERT_LIST_END(node, certList) ) {
- *nn = CERT_GetCertNicknameWithValidity(arena, node->cert,
- expiredString,
- notYetGoodString);
- if ( *nn == NULL ) {
- goto loser;
- }
-
- names->totallen += PORT_Strlen(*nn);
-
- nn++;
- node = CERT_LIST_NEXT(node);
- }
-
- return(names);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(NULL);
-}
-
-/*
- * Extract the nickname from a nickmake string that may have either
- * expiredString or notYetGoodString appended.
- *
- * Args:
- * "namestring" - the string containing the nickname, and possibly
- * one of the validity label strings
- * "expiredString" - the expired validity label string
- * "notYetGoodString" - the not yet good validity label string
- *
- * Returns the raw nickname
- */
-char *
-CERT_ExtractNicknameString(char *namestring, char *expiredString,
- char *notYetGoodString)
-{
- int explen, nyglen, namelen;
- int retlen;
- char *retstr;
-
- namelen = PORT_Strlen(namestring);
- explen = PORT_Strlen(expiredString);
- nyglen = PORT_Strlen(notYetGoodString);
-
- if ( namelen > explen ) {
- if ( PORT_Strcmp(expiredString, &namestring[namelen-explen]) == 0 ) {
- retlen = namelen - explen;
- retstr = (char *)PORT_Alloc(retlen+1);
- if ( retstr == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(retstr, namestring, retlen);
- retstr[retlen] = '\0';
- goto done;
- }
- }
-
- if ( namelen > nyglen ) {
- if ( PORT_Strcmp(notYetGoodString, &namestring[namelen-nyglen]) == 0) {
- retlen = namelen - nyglen;
- retstr = (char *)PORT_Alloc(retlen+1);
- if ( retstr == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(retstr, namestring, retlen);
- retstr[retlen] = '\0';
- goto done;
- }
- }
-
- /* if name string is shorter than either invalid string, then it must
- * be a raw nickname
- */
- retstr = PORT_Strdup(namestring);
-
-done:
- return(retstr);
-
-loser:
- return(NULL);
-}
-
-CERTCertList *
-CERT_GetCertChainFromCert(CERTCertificate *cert, int64 time, SECCertUsage usage)
-{
- CERTCertList *chain = NULL;
- int count = 0;
-
- if (NULL == cert) {
- return NULL;
- }
-
- cert = CERT_DupCertificate(cert);
- if (NULL == cert) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- chain = CERT_NewCertList();
- if (NULL == chain) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- while (cert != NULL && ++count <= CERT_MAX_CERT_CHAIN) {
- if (SECSuccess != CERT_AddCertToListTail(chain, cert)) {
- /* return partial chain */
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return chain;
- }
-
- if (cert->isRoot) {
- /* return complete chain */
- return chain;
- }
-
- cert = CERT_FindCertIssuer(cert, time, usage);
- }
-
- /* return partial chain */
- PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
- return chain;
-}
diff --git a/security/nss/lib/certhigh/certvfypkix.c b/security/nss/lib/certhigh/certvfypkix.c
deleted file mode 100644
index 1138566e7..000000000
--- a/security/nss/lib/certhigh/certvfypkix.c
+++ /dev/null
@@ -1,2325 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * nss_pkix_proxy.h
- *
- * PKIX - NSS proxy functions
- *
- * NOTE: All structures, functions, data types are parts of library private
- * api and are subjects to change in any following releases.
- *
- */
-#include "prerror.h"
-#include "prprf.h"
-
-#include "nspr.h"
-#include "pk11func.h"
-#include "certdb.h"
-#include "cert.h"
-#include "secerr.h"
-#include "nssb64.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "pkit.h"
-
-#include "pkix_pl_common.h"
-
-extern PRLogModuleInfo *pkixLog;
-
-#ifdef DEBUG_volkov
-/* Temporary declarations of functioins. Will be removed with fix for
- * 391183 */
-extern char *
-pkix_Error2ASCII(PKIX_Error *error, void *plContext);
-
-extern void
-cert_PrintCert(PKIX_PL_Cert *pkixCert, void *plContext);
-
-extern PKIX_Error *
-cert_PrintCertChain(PKIX_List *pkixCertChain, void *plContext);
-
-#endif /* DEBUG */
-
-#ifdef PKIX_OBJECT_LEAK_TEST
-
-extern PKIX_UInt32
-pkix_pl_lifecycle_ObjectLeakCheck(int *);
-
-extern SECStatus
-pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable);
-
-PRInt32 parallelFnInvocationCount;
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
-
-static PRBool usePKIXValidationEngine = PR_FALSE;
-
-/*
- * FUNCTION: CERT_SetUsePKIXForValidation
- * DESCRIPTION:
- *
- * Enables or disables use of libpkix for certificate validation
- *
- * PARAMETERS:
- * "enable"
- * PR_TRUE: enables use of libpkix for cert validation.
- * PR_FALSE: disables.
- * THREAD SAFETY:
- * NOT Thread Safe.
- * RETURNS:
- * Returns SECSuccess if successfully enabled
- */
-SECStatus
-CERT_SetUsePKIXForValidation(PRBool enable)
-{
- usePKIXValidationEngine = (enable > 0) ? PR_TRUE : PR_FALSE;
- return SECSuccess;
-}
-
-/*
- * FUNCTION: CERT_GetUsePKIXForValidation
- * DESCRIPTION:
- *
- * Checks if libpkix building function should be use for certificate
- * chain building.
- *
- * PARAMETERS:
- * NONE
- * THREAD SAFETY:
- * NOT Thread Safe
- * RETURNS:
- * Returns PR_TRUE if libpkix should be used. PR_FALSE otherwise.
- */
-PRBool
-CERT_GetUsePKIXForValidation()
-{
- return usePKIXValidationEngine;
-}
-
-#ifdef NOTDEF
-/*
- * FUNCTION: cert_NssKeyUsagesToPkix
- * DESCRIPTION:
- *
- * Converts nss key usage bit field(PRUint32) to pkix key usage
- * bit field.
- *
- * PARAMETERS:
- * "nssKeyUsage"
- * Nss key usage bit field.
- * "pkixKeyUsage"
- * Pkix key usage big field.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error*
-cert_NssKeyUsagesToPkix(
- PRUint32 nssKeyUsage,
- PKIX_UInt32 *pPkixKeyUsage,
- void *plContext)
-{
- PKIX_UInt32 pkixKeyUsage = 0;
-
- PKIX_ENTER(CERTVFYPKIX, "cert_NssKeyUsagesToPkix");
- PKIX_NULLCHECK_ONE(pPkixKeyUsage);
-
- *pPkixKeyUsage = 0;
-
- if (nssKeyUsage & KU_DIGITAL_SIGNATURE) {
- pkixKeyUsage |= PKIX_DIGITAL_SIGNATURE;
- }
-
- if (nssKeyUsage & KU_NON_REPUDIATION) {
- pkixKeyUsage |= PKIX_NON_REPUDIATION;
- }
-
- if (nssKeyUsage & KU_KEY_ENCIPHERMENT) {
- pkixKeyUsage |= PKIX_KEY_ENCIPHERMENT;
- }
-
- if (nssKeyUsage & KU_DATA_ENCIPHERMENT) {
- pkixKeyUsage |= PKIX_DATA_ENCIPHERMENT;
- }
-
- if (nssKeyUsage & KU_KEY_AGREEMENT) {
- pkixKeyUsage |= PKIX_KEY_AGREEMENT;
- }
-
- if (nssKeyUsage & KU_KEY_CERT_SIGN) {
- pkixKeyUsage |= PKIX_KEY_CERT_SIGN;
- }
-
- if (nssKeyUsage & KU_CRL_SIGN) {
- pkixKeyUsage |= PKIX_CRL_SIGN;
- }
-
- if (nssKeyUsage & KU_ENCIPHER_ONLY) {
- pkixKeyUsage |= PKIX_ENCIPHER_ONLY;
- }
-
- /* Not supported. XXX we should support this once it is
- * fixed in NSS */
- /* pkixKeyUsage |= PKIX_DECIPHER_ONLY; */
-
- *pPkixKeyUsage = pkixKeyUsage;
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-extern SECOidTag ekuOidStrings[];
-
-enum {
- ekuIndexSSLServer = 0,
- ekuIndexSSLClient,
- ekuIndexCodeSigner,
- ekuIndexEmail,
- ekuIndexTimeStamp,
- ekuIndexStatusResponder,
- ekuIndexUnknown
-} ekuIndex;
-
-typedef struct {
- SECCertUsage certUsage;
- PRUint32 ekuStringIndex;
-} SECCertUsageToEku;
-
-const SECCertUsageToEku certUsageEkuStringMap[] = {
- {certUsageSSLClient, ekuIndexSSLClient},
- {certUsageSSLServer, ekuIndexSSLServer},
- {certUsageSSLCA, ekuIndexSSLServer},
- {certUsageEmailSigner, ekuIndexEmail},
- {certUsageEmailRecipient, ekuIndexEmail},
- {certUsageObjectSigner, ekuIndexCodeSigner},
- {certUsageUserCertImport, ekuIndexUnknown},
- {certUsageVerifyCA, ekuIndexUnknown},
- {certUsageProtectedObjectSigner, ekuIndexUnknown},
- {certUsageStatusResponder, ekuIndexStatusResponder},
- {certUsageAnyCA, ekuIndexUnknown},
-};
-
-/*
- * FUNCTION: cert_NssCertificateUsageToPkixKUAndEKU
- * DESCRIPTION:
- *
- * Converts nss CERTCertificateUsage bit field to pkix key and
- * extended key usages.
- *
- * PARAMETERS:
- * "cert"
- * Pointer to CERTCertificate structure of validating cert.
- * "requiredCertUsages"
- * Required usage that will be converted to pkix eku and ku.
- * "requiredKeyUsage",
- * Additional key usages impose to cert.
- * "isCA",
- * it true, convert usages for cert that is a CA cert.
- * "ppkixEKUList"
- * Returned address of a list of pkix extended key usages.
- * "ppkixKU"
- * Returned address of pkix required key usages bit field.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error*
-cert_NssCertificateUsageToPkixKUAndEKU(
- CERTCertificate *cert,
- SECCertUsage requiredCertUsage,
- PRUint32 requiredKeyUsages,
- PRBool isCA,
- PKIX_List **ppkixEKUList,
- PKIX_UInt32 *ppkixKU,
- void *plContext)
-{
- PKIX_List *ekuOidsList = NULL;
- PKIX_PL_OID *ekuOid = NULL;
- int i = 0;
- int ekuIndex = ekuIndexUnknown;
-
- PKIX_ENTER(CERTVFYPKIX, "cert_NssCertificateUsageToPkixEku");
- PKIX_NULLCHECK_TWO(ppkixEKUList, ppkixKU);
-
- PKIX_CHECK(
- PKIX_List_Create(&ekuOidsList, plContext),
- PKIX_LISTCREATEFAILED);
-
- for (;i < PR_ARRAY_SIZE(certUsageEkuStringMap);i++) {
- const SECCertUsageToEku *usageToEkuElem =
- &certUsageEkuStringMap[i];
- if (usageToEkuElem->certUsage == requiredCertUsage) {
- ekuIndex = usageToEkuElem->ekuStringIndex;
- break;
- }
- }
- if (ekuIndex != ekuIndexUnknown) {
- PRUint32 reqKeyUsage = 0;
- PRUint32 reqCertType = 0;
-
- CERT_KeyUsageAndTypeForCertUsage(requiredCertUsage, isCA,
- &reqKeyUsage,
- &reqCertType);
-
- requiredKeyUsages |= reqKeyUsage;
-
- PKIX_CHECK(
- PKIX_PL_OID_Create(ekuOidStrings[ekuIndex], &ekuOid,
- plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_CHECK(
- PKIX_List_AppendItem(ekuOidsList, (PKIX_PL_Object *)ekuOid,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(ekuOid);
- }
-
- PKIX_CHECK(
- cert_NssKeyUsagesToPkix(requiredKeyUsages, ppkixKU, plContext),
- PKIX_NSSCERTIFICATEUSAGETOPKIXKUANDEKUFAILED);
-
- *ppkixEKUList = ekuOidsList;
- ekuOidsList = NULL;
-
-cleanup:
-
- PKIX_DECREF(ekuOid);
- PKIX_DECREF(ekuOidsList);
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-#endif
-
-/*
- * FUNCTION: cert_ProcessingParamsSetKeyAndCertUsage
- * DESCRIPTION:
- *
- * Converts cert usage to pkix KU type and sets
- * converted data into PKIX_ProcessingParams object. It also sets
- * proper cert usage into nsscontext object.
- *
- * PARAMETERS:
- * "procParams"
- * Pointer to PKIX_ProcessingParams used during validation.
- * "requiredCertUsage"
- * Required certificate usages the certificate and chain is built and
- * validated for.
- * "requiredKeyUsage"
- * Request additional key usages the certificate should be validated for.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error*
-cert_ProcessingParamsSetKeyAndCertUsage(
- PKIX_ProcessingParams *procParams,
- SECCertUsage requiredCertUsage,
- PRUint32 requiredKeyUsages,
- void *plContext)
-{
- PKIX_CertSelector *certSelector = NULL;
- PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext*)plContext;
-
- PKIX_ENTER(CERTVFYPKIX, "cert_ProcessingParamsSetKeyAndCertUsage");
- PKIX_NULLCHECK_TWO(procParams, nssContext);
-
- PKIX_CHECK(
- pkix_pl_NssContext_SetCertUsage(
- ((SECCertificateUsage)1) << requiredCertUsage, nssContext),
- PKIX_NSSCONTEXTSETCERTUSAGEFAILED);
-
- if (requiredKeyUsages) {
- PKIX_CHECK(
- PKIX_ProcessingParams_GetTargetCertConstraints(procParams,
- &certSelector, plContext),
- PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
-
- PKIX_CHECK(
- PKIX_CertSelector_GetCommonCertSelectorParams(certSelector,
- &certSelParams, plContext),
- PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
-
-
- PKIX_CHECK(
- PKIX_ComCertSelParams_SetKeyUsage(certSelParams, requiredKeyUsages,
- plContext),
- PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED);
- }
-cleanup:
- PKIX_DECREF(certSelector);
- PKIX_DECREF(certSelParams);
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-/*
- * Unused parameters:
- *
- * CERTCertList *initialChain,
- * CERTCertStores certStores,
- * CERTCertRevCheckers certRevCheckers,
- * CERTCertChainCheckers certChainCheckers,
- * SECItem *initPolicies,
- * PRBool policyQualifierRejected,
- * PRBool anyPolicyInhibited,
- * PRBool reqExplicitPolicy,
- * PRBool policyMappingInhibited,
- * PKIX_CertSelector certConstraints,
- */
-
-/*
- * FUNCTION: cert_CreatePkixProcessingParams
- * DESCRIPTION:
- *
- * Creates and fills in PKIX_ProcessingParams structure to be used
- * for certificate chain building.
- *
- * PARAMETERS:
- * "cert"
- * Pointer to the CERTCertificate: the leaf certificate of a chain.
- * "time"
- * Validity time.
- * "wincx"
- * Nss db password token.
- * "useArena"
- * Flags to use arena for data allocation during chain building process.
- * "pprocParams"
- * Address to return created processing parameters.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error*
-cert_CreatePkixProcessingParams(
- CERTCertificate *cert,
- PRBool checkSig, /* not used yet. See bug 391476 */
- PRTime time,
- void *wincx,
- PRBool useArena,
- PRBool disableOCSPRemoteFetching,
- PKIX_ProcessingParams **pprocParams,
- void **pplContext)
-{
- PKIX_List *anchors = NULL;
- PKIX_PL_Cert *targetCert = NULL;
- PKIX_PL_Date *date = NULL;
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_CertSelector *certSelector = NULL;
- PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_CertStore *certStore = NULL;
- PKIX_List *certStores = NULL;
- PKIX_RevocationChecker *revChecker = NULL;
- PKIX_UInt32 methodFlags = 0;
- void *plContext = NULL;
- CERTStatusConfig *statusConfig = NULL;
-
- PKIX_ENTER(CERTVFYPKIX, "cert_CreatePkixProcessingParams");
- PKIX_NULLCHECK_TWO(cert, pprocParams);
-
- PKIX_CHECK(
- PKIX_PL_NssContext_Create(0, useArena, wincx, &plContext),
- PKIX_NSSCONTEXTCREATEFAILED);
-
- *pplContext = plContext;
-
-#ifdef PKIX_NOTDEF
- /* Functions should be implemented in patch for 390532 */
- PKIX_CHECK(
- pkix_pl_NssContext_SetCertSignatureCheck(checkSig,
- (PKIX_PL_NssContext*)plContext),
- PKIX_NSSCONTEXTSETCERTSIGNCHECKFAILED);
-
-#endif /* PKIX_NOTDEF */
-
- PKIX_CHECK(
- PKIX_ProcessingParams_Create(&procParams, plContext),
- PKIX_PROCESSINGPARAMSCREATEFAILED);
-
- PKIX_CHECK(
- PKIX_ComCertSelParams_Create(&certSelParams, plContext),
- PKIX_COMCERTSELPARAMSCREATEFAILED);
-
- PKIX_CHECK(
- PKIX_PL_Cert_CreateFromCERTCertificate(cert, &targetCert, plContext),
- PKIX_CERTCREATEWITHNSSCERTFAILED);
-
- PKIX_CHECK(
- PKIX_ComCertSelParams_SetCertificate(certSelParams,
- targetCert, plContext),
- PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED);
-
- PKIX_CHECK(
- PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext),
- PKIX_COULDNOTCREATECERTSELECTOROBJECT);
-
- PKIX_CHECK(
- PKIX_CertSelector_SetCommonCertSelectorParams(certSelector,
- certSelParams, plContext),
- PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
-
- PKIX_CHECK(
- PKIX_ProcessingParams_SetTargetCertConstraints(procParams,
- certSelector, plContext),
- PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED);
-
- /* Turn off quialification of target cert since leaf cert is
- * already check for date validity, key usages and extended
- * key usages. */
- PKIX_CHECK(
- PKIX_ProcessingParams_SetQualifyTargetCert(procParams, PKIX_FALSE,
- plContext),
- PKIX_PROCESSINGPARAMSSETQUALIFYTARGETCERTFLAGFAILED);
-
- PKIX_CHECK(
- PKIX_PL_Pk11CertStore_Create(&certStore, plContext),
- PKIX_PK11CERTSTORECREATEFAILED);
-
- PKIX_CHECK(
- PKIX_List_Create(&certStores, plContext),
- PKIX_UNABLETOCREATELIST);
-
- PKIX_CHECK(
- PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(
- PKIX_ProcessingParams_SetCertStores(procParams, certStores,
- plContext),
- PKIX_PROCESSINGPARAMSADDCERTSTOREFAILED);
-
- PKIX_CHECK(
- PKIX_PL_Date_CreateFromPRTime(time, &date, plContext),
- PKIX_DATECREATEFROMPRTIMEFAILED);
-
- PKIX_CHECK(
- PKIX_ProcessingParams_SetDate(procParams, date, plContext),
- PKIX_PROCESSINGPARAMSSETDATEFAILED);
-
- PKIX_CHECK(
- PKIX_RevocationChecker_Create(
- PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
- PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
- PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
- PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
- &revChecker, plContext),
- PKIX_REVOCATIONCHECKERCREATEFAILED);
-
- PKIX_CHECK(
- PKIX_ProcessingParams_SetRevocationChecker(procParams, revChecker,
- plContext),
- PKIX_PROCESSINGPARAMSSETREVOCATIONCHECKERFAILED);
-
- /* CRL method flags */
- methodFlags =
- PKIX_REV_M_TEST_USING_THIS_METHOD |
- PKIX_REV_M_FORBID_NETWORK_FETCHING |
- PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */
- PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */
- PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;
-
- /* add CRL revocation method to check the leaf certificate */
- PKIX_CHECK(
- PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
- PKIX_RevocationMethod_CRL, methodFlags,
- 0, NULL, PKIX_TRUE, plContext),
- PKIX_REVOCATIONCHECKERADDMETHODFAILED);
-
- /* add CRL revocation method for other certs in the chain. */
- PKIX_CHECK(
- PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
- PKIX_RevocationMethod_CRL, methodFlags,
- 0, NULL, PKIX_FALSE, plContext),
- PKIX_REVOCATIONCHECKERADDMETHODFAILED);
-
- /* For compatibility with the old code, need to check that
- * statusConfig is set in the db handle and status checker
- * is defined befor allow ocsp status check on the leaf cert.*/
- statusConfig = CERT_GetStatusConfig(CERT_GetDefaultCertDB());
- if (statusConfig != NULL && statusConfig->statusChecker != NULL) {
-
- /* Enable OCSP revocation checking for the leaf cert. */
- /* OCSP method flags */
- methodFlags =
- PKIX_REV_M_TEST_USING_THIS_METHOD |
- PKIX_REV_M_ALLOW_NETWORK_FETCHING | /* 0 */
- PKIX_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE | /* 0 */
- PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */
- PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */
- PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;
-
- /* Disabling ocsp fetching when checking the status
- * of ocsp response signer. Here and in the next if,
- * adjust flags for ocsp signer cert validation case. */
- if (disableOCSPRemoteFetching) {
- methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
- }
-
- if (ocsp_FetchingFailureIsVerificationFailure()
- && !disableOCSPRemoteFetching) {
- methodFlags |=
- PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;
- }
-
- /* add OCSP revocation method to check only the leaf certificate.*/
- PKIX_CHECK(
- PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
- PKIX_RevocationMethod_OCSP, methodFlags,
- 1, NULL, PKIX_TRUE, plContext),
- PKIX_REVOCATIONCHECKERADDMETHODFAILED);
- }
-
- PKIX_CHECK(
- PKIX_ProcessingParams_SetAnyPolicyInhibited(procParams, PR_FALSE,
- plContext),
- PKIX_PROCESSINGPARAMSSETANYPOLICYINHIBITED);
-
- PKIX_CHECK(
- PKIX_ProcessingParams_SetExplicitPolicyRequired(procParams, PR_FALSE,
- plContext),
- PKIX_PROCESSINGPARAMSSETEXPLICITPOLICYREQUIRED);
-
- PKIX_CHECK(
- PKIX_ProcessingParams_SetPolicyMappingInhibited(procParams, PR_FALSE,
- plContext),
- PKIX_PROCESSINGPARAMSSETPOLICYMAPPINGINHIBITED);
-
- *pprocParams = procParams;
- procParams = NULL;
-
-cleanup:
- PKIX_DECREF(anchors);
- PKIX_DECREF(targetCert);
- PKIX_DECREF(date);
- PKIX_DECREF(certSelector);
- PKIX_DECREF(certSelParams);
- PKIX_DECREF(certStore);
- PKIX_DECREF(certStores);
- PKIX_DECREF(procParams);
- PKIX_DECREF(revChecker);
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-/*
- * FUNCTION: cert_PkixToNssCertsChain
- * DESCRIPTION:
- *
- * Converts pkix cert list into nss cert list.
- *
- * PARAMETERS:
- * "pkixCertChain"
- * Pkix certificate list.
- * "pvalidChain"
- * An address of returned nss certificate list.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error*
-cert_PkixToNssCertsChain(
- PKIX_List *pkixCertChain,
- CERTCertList **pvalidChain,
- void *plContext)
-{
- PRArenaPool *arena = NULL;
- CERTCertificate *nssCert = NULL;
- CERTCertList *validChain = NULL;
- PKIX_PL_Object *certItem = NULL;
- PKIX_UInt32 length = 0;
- PKIX_UInt32 i = 0;
-
- PKIX_ENTER(CERTVFYPKIX, "cert_PkixToNssCertsChain");
- PKIX_NULLCHECK_ONE(pvalidChain);
-
- if (pkixCertChain == NULL) {
- goto cleanup;
- }
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
- validChain = (CERTCertList*)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
- if (validChain == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
- PR_INIT_CLIST(&validChain->list);
- validChain->arena = arena;
- arena = NULL;
-
- PKIX_CHECK(
- PKIX_List_GetLength(pkixCertChain, &length, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < length; i++){
- CERTCertListNode *node = NULL;
-
- PKIX_CHECK(
- PKIX_List_GetItem(pkixCertChain, i, &certItem, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(
- PKIX_PL_Cert_GetCERTCertificate((PKIX_PL_Cert*)certItem, &nssCert,
- plContext),
- PKIX_CERTGETCERTCERTIFICATEFAILED);
-
- node =
- (CERTCertListNode *)PORT_ArenaZAlloc(validChain->arena,
- sizeof(CERTCertListNode));
- if ( node == NULL ) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- PR_INSERT_BEFORE(&node->links, &validChain->list);
-
- node->cert = nssCert;
- nssCert = NULL;
-
- PKIX_DECREF(certItem);
- }
-
- *pvalidChain = validChain;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED){
- if (validChain) {
- CERT_DestroyCertList(validChain);
- } else if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- if (nssCert) {
- CERT_DestroyCertificate(nssCert);
- }
- }
- PKIX_DECREF(certItem);
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-
-/*
- * FUNCTION: cert_BuildAndValidateChain
- * DESCRIPTION:
- *
- * The function builds and validates a cert chain based on certificate
- * selection criterias from procParams. This function call PKIX_BuildChain
- * to accomplish chain building. If PKIX_BuildChain returns with incomplete
- * IO, the function waits with PR_Poll until the blocking IO is finished and
- * return control back to PKIX_BuildChain.
- *
- * PARAMETERS:
- * "procParams"
- * Processing parameters to be used during chain building.
- * "pResult"
- * Returned build result.
- * "pVerifyNode"
- * Returned pointed to verify node structure: the tree-like structure
- * that reports points of chain building failures.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error*
-cert_BuildAndValidateChain(
- PKIX_ProcessingParams *procParams,
- PKIX_BuildResult **pResult,
- PKIX_VerifyNode **pVerifyNode,
- void *plContext)
-{
- PKIX_BuildResult *result = NULL;
- PKIX_VerifyNode *verifyNode = NULL;
- void *nbioContext = NULL;
- void *state = NULL;
-
- PKIX_ENTER(CERTVFYPKIX, "cert_BuildAndVerifyChain");
- PKIX_NULLCHECK_TWO(procParams, pResult);
-
- do {
- if (nbioContext && state) {
- /* PKIX-XXX: need to test functionality of NBIO handling in libPkix.
- * See bug 391180 */
- PRInt32 filesReady = 0;
- PRPollDesc *pollDesc = (PRPollDesc*)nbioContext;
- filesReady = PR_Poll(pollDesc, 1, PR_INTERVAL_NO_TIMEOUT);
- if (filesReady <= 0) {
- PKIX_ERROR(PKIX_PRPOLLRETBADFILENUM);
- }
- }
-
- PKIX_CHECK(
- PKIX_BuildChain(procParams, &nbioContext, &state,
- &result, &verifyNode, plContext),
- PKIX_UNABLETOBUILDCHAIN);
-
- } while (nbioContext && state);
-
- *pResult = result;
-
-cleanup:
- if (pVerifyNode) {
- *pVerifyNode = verifyNode;
- }
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-
-/*
- * FUNCTION: cert_PkixErrorToNssCode
- * DESCRIPTION:
- *
- * Converts pkix error(PKIX_Error) structure to PR error codes.
- *
- * PKIX-XXX to be implemented. See 391183.
- *
- * PARAMETERS:
- * "error"
- * Pkix error that will be converted.
- * "nssCode"
- * Corresponding nss error code.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-cert_PkixErrorToNssCode(
- PKIX_Error *error,
- SECErrorCodes *pNssErr,
- void *plContext)
-{
- int errLevel = 0;
- PKIX_Int32 nssErr = 0;
- PKIX_Error *errPtr = error;
-
- PKIX_ENTER(CERTVFYPKIX, "cert_PkixErrorToNssCode");
- PKIX_NULLCHECK_TWO(error, pNssErr);
-
- /* Loop until we find at least one error with non-null
- * plErr code, that is going to be nss error code. */
- while (errPtr) {
- if (errPtr->plErr && !nssErr) {
- nssErr = errPtr->plErr;
- if (!pkixLog) break;
- }
- if (pkixLog) {
-#ifdef PKIX_ERROR_DESCRIPTION
- PR_LOG(pkixLog, 2, ("Error at level %d: %s\n", errLevel,
- PKIX_ErrorText[errPtr->errCode]));
-#else
- PR_LOG(pkixLog, 2, ("Error at level %d: Error code %d\n", errLevel,
- errPtr->errCode));
-#endif /* PKIX_ERROR_DESCRIPTION */
- }
- errPtr = errPtr->cause;
- errLevel += 1;
- }
- PORT_Assert(nssErr);
- if (!nssErr) {
- *pNssErr = SEC_ERROR_LIBPKIX_INTERNAL;
- } else {
- *pNssErr = nssErr;
- }
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-/*
- * FUNCTION: cert_GetLogFromVerifyNode
- * DESCRIPTION:
- *
- * Recursive function that converts verify node tree-like set of structures
- * to CERTVerifyLog.
- *
- * PARAMETERS:
- * "log"
- * Pointed to already allocated CERTVerifyLog structure.
- * "node"
- * A node of PKIX_VerifyNode tree.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-cert_GetLogFromVerifyNode(
- CERTVerifyLog *log,
- PKIX_VerifyNode *node,
- void *plContext)
-{
- PKIX_List *children = NULL;
- PKIX_VerifyNode *childNode = NULL;
-
- PKIX_ENTER(CERTVFYPKIX, "cert_GetLogFromVerifyNode");
-
- children = node->children;
-
- if (children == NULL) {
- PKIX_ERRORCODE errCode = PKIX_ANCHORDIDNOTCHAINTOCERT;
- if (node->error && node->error->errCode != errCode) {
-#ifdef DEBUG_volkov
- char *string = pkix_Error2ASCII(node->error, plContext);
- fprintf(stderr, "Branch search finished with error: \t%s\n", string);
- PKIX_PL_Free(string, NULL);
-#endif
- if (log != NULL) {
- SECErrorCodes nssErrorCode = 0;
- CERTCertificate *cert = NULL;
-
- cert = node->verifyCert->nssCert;
-
- PKIX_CHECK(
- cert_PkixErrorToNssCode(node->error, &nssErrorCode,
- plContext),
- PKIX_GETPKIXERRORCODEFAILED);
-
- cert_AddToVerifyLog(log, cert, nssErrorCode, node->depth, NULL);
- }
- }
- PKIX_RETURN(CERTVFYPKIX);
- } else {
- PRUint32 i = 0;
- PKIX_UInt32 length = 0;
-
- PKIX_CHECK(
- PKIX_List_GetLength(children, &length, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < length; i++){
-
- PKIX_CHECK(
- PKIX_List_GetItem(children, i, (PKIX_PL_Object**)&childNode,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(
- cert_GetLogFromVerifyNode(log, childNode, plContext),
- PKIX_ERRORINRECURSIVEEQUALSCALL);
-
- PKIX_DECREF(childNode);
- }
- }
-
-cleanup:
- PKIX_DECREF(childNode);
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-/*
- * FUNCTION: cert_GetBuildResults
- * DESCRIPTION:
- *
- * Converts pkix build results to nss results. This function is called
- * regardless of build result.
- *
- * If it called after chain was successfully constructed, then it will
- * convert:
- * * pkix cert list that represent the chain to nss cert list
- * * trusted root the chain was anchored to nss certificate.
- *
- * In case of failure it will convert:
- * * pkix error to PR error code(will set it with PORT_SetError)
- * * pkix validation log to nss CERTVerifyLog
- *
- * PARAMETERS:
- * "buildResult"
- * Build results returned by PKIX_BuildChain.
- * "verifyNode"
- * Tree-like structure of chain building/validation failures
- * returned by PKIX_BuildChain. Ignored in case of success.
- * "error"
- * Final error returned by PKIX_BuildChain. Should be NULL in
- * case of success.
- * "log"
- * Address of pre-allocated(if not NULL) CERTVerifyLog structure.
- * "ptrustedRoot"
- * Address of returned trusted root the chain was anchored to.
- * "pvalidChain"
- * Address of returned valid chain.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Verify Error if the function fails in an unrecoverable way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error*
-cert_GetBuildResults(
- PKIX_BuildResult *buildResult,
- PKIX_VerifyNode *verifyNode,
- PKIX_Error *error,
- CERTVerifyLog *log,
- CERTCertificate **ptrustedRoot,
- CERTCertList **pvalidChain,
- void *plContext)
-{
- PKIX_ValidateResult *validResult = NULL;
- CERTCertList *validChain = NULL;
- CERTCertificate *trustedRoot = NULL;
- PKIX_TrustAnchor *trustAnchor = NULL;
- PKIX_PL_Cert *trustedCert = NULL;
- PKIX_List *pkixCertChain = NULL;
-#ifdef DEBUG_volkov
- PKIX_Error *tmpPkixError = NULL;
-#endif /* DEBUG */
-
- PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults");
- if (buildResult == NULL && error == NULL) {
- PKIX_ERROR(PKIX_NULLARGUMENT);
- }
-
- if (error) {
- SECErrorCodes nssErrorCode = 0;
-#ifdef DEBUG_volkov
- char *temp = pkix_Error2ASCII(error, plContext);
- fprintf(stderr, "BUILD ERROR:\n%s\n", temp);
- PKIX_PL_Free(temp, NULL);
-#endif /* DEBUG */
- if (verifyNode) {
- PKIX_Error *tmpError =
- cert_GetLogFromVerifyNode(log, verifyNode, plContext);
- if (tmpError) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
- }
- }
- cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
- PORT_SetError(nssErrorCode);
- goto cleanup;
- }
-
- if (pvalidChain) {
- PKIX_CHECK(
- PKIX_BuildResult_GetCertChain(buildResult, &pkixCertChain,
- plContext),
- PKIX_BUILDRESULTGETCERTCHAINFAILED);
-
-#ifdef DEBUG_volkov
- tmpPkixError = cert_PrintCertChain(pkixCertChain, plContext);
- if (tmpPkixError) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)tmpPkixError, plContext);
- }
-#endif
-
- PKIX_CHECK(
- cert_PkixToNssCertsChain(pkixCertChain, &validChain, plContext),
- PKIX_CERTCHAINTONSSCHAINFAILED);
- }
-
- if (ptrustedRoot) {
- PKIX_CHECK(
- PKIX_BuildResult_GetValidateResult(buildResult, &validResult,
- plContext),
- PKIX_BUILDRESULTGETVALIDATERESULTFAILED);
-
- PKIX_CHECK(
- PKIX_ValidateResult_GetTrustAnchor(validResult, &trustAnchor,
- plContext),
- PKIX_VALIDATERESULTGETTRUSTANCHORFAILED);
-
- PKIX_CHECK(
- PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustedCert,
- plContext),
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
-
-#ifdef DEBUG_volkov
- if (pvalidChain == NULL) {
- cert_PrintCert(trustedCert, plContext);
- }
-#endif
-
- PKIX_CHECK(
- PKIX_PL_Cert_GetCERTCertificate(trustedCert, &trustedRoot,
- plContext),
- PKIX_CERTGETCERTCERTIFICATEFAILED);
- }
-
- PORT_Assert(!PKIX_ERROR_RECEIVED);
-
- if (trustedRoot) {
- *ptrustedRoot = trustedRoot;
- }
- if (validChain) {
- *pvalidChain = validChain;
- }
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- if (trustedRoot) {
- CERT_DestroyCertificate(trustedRoot);
- }
- if (validChain) {
- CERT_DestroyCertList(validChain);
- }
- }
- PKIX_DECREF(trustAnchor);
- PKIX_DECREF(trustedCert);
- PKIX_DECREF(pkixCertChain);
- PKIX_DECREF(validResult);
- PKIX_DECREF(error);
- PKIX_DECREF(verifyNode);
- PKIX_DECREF(buildResult);
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-/*
- * FUNCTION: cert_VerifyCertChainPkix
- * DESCRIPTION:
- *
- * The main wrapper function that is called from CERT_VerifyCert and
- * CERT_VerifyCACertForUsage functions to validate cert with libpkix.
- *
- * PARAMETERS:
- * "cert"
- * Leaf certificate of a chain we want to build.
- * "checkSig"
- * Certificate signatures will not be verified if this
- * flag is set to PR_FALSE.
- * "requiredUsage"
- * Required usage for certificate and chain.
- * "time"
- * Validity time.
- * "wincx"
- * Nss database password token.
- * "log"
- * Address of already allocated CERTVerifyLog structure. Not
- * used if NULL;
- * "pSigerror"
- * Address of PRBool. If not NULL, returns true is cert chain
- * was invalidated because of bad certificate signature.
- * "pRevoked"
- * Address of PRBool. If not NULL, returns true is cert chain
- * was invalidated because a revoked certificate was found in
- * the chain.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * SECFailure is chain building process has failed. SECSuccess otherwise.
- */
-SECStatus
-cert_VerifyCertChainPkix(
- CERTCertificate *cert,
- PRBool checkSig,
- SECCertUsage requiredUsage,
- PRTime time,
- void *wincx,
- CERTVerifyLog *log,
- PRBool *pSigerror,
- PRBool *pRevoked)
-{
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_BuildResult *result = NULL;
- PKIX_VerifyNode *verifyNode = NULL;
- PKIX_Error *error = NULL;
-
- SECStatus rv = SECFailure;
- void *plContext = NULL;
-#ifdef DEBUG_volkov
- CERTCertificate *trustedRoot = NULL;
- CERTCertList *validChain = NULL;
-#endif /* DEBUG */
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- int leakedObjNum = 0;
- int memLeakLoopCount = 0;
- int objCountTable[PKIX_NUMTYPES];
- int fnInvLocalCount = 0;
- PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;
-
- if (usePKIXValidationEngine) {
- /* current memory leak testing implementation does not allow
- * to run simultaneous tests one the same or a different threads.
- * Setting the variable to false, to make additional chain
- * validations be handled by old nss. */
- usePKIXValidationEngine = PR_FALSE;
- }
- testStartFnStackPosition = 2;
- fnStackNameArr[0] = "cert_VerifyCertChainPkix";
- fnStackInvCountArr[0] = 0;
- PKIX_Boolean abortOnLeak =
- (PR_GetEnv("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ?
- PKIX_FALSE : PKIX_TRUE;
- runningLeakTest = PKIX_TRUE;
-
- /* Prevent multi-threaded run of object leak test */
- fnInvLocalCount = PR_ATOMIC_INCREMENT(&parallelFnInvocationCount);
- PORT_Assert(fnInvLocalCount == 1);
-
-do {
- rv = SECFailure;
- plContext = NULL;
- procParams = NULL;
- result = NULL;
- verifyNode = NULL;
- error = NULL;
-#ifdef DEBUG_volkov
- trustedRoot = NULL;
- validChain = NULL;
-#endif /* DEBUG */
- errorGenerated = PKIX_FALSE;
- stackPosition = 0;
-
- if (leakedObjNum) {
- pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
- }
- memLeakLoopCount += 1;
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- error =
- cert_CreatePkixProcessingParams(cert, checkSig, time, wincx,
- PR_FALSE/*use arena*/,
- requiredUsage == certUsageStatusResponder,
- &procParams, &plContext);
- if (error) {
- goto cleanup;
- }
-
- error =
- cert_ProcessingParamsSetKeyAndCertUsage(procParams, requiredUsage, 0,
- plContext);
- if (error) {
- goto cleanup;
- }
-
- error =
- cert_BuildAndValidateChain(procParams, &result, &verifyNode, plContext);
- if (error) {
- goto cleanup;
- }
-
- if (pRevoked) {
- /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
- *pRevoked = PR_FALSE;
- }
- if (pSigerror) {
- /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
- *pSigerror = PR_FALSE;
- }
- rv = SECSuccess;
-
-cleanup:
- error = cert_GetBuildResults(result, verifyNode, error, log,
-#ifdef DEBUG_volkov
- &trustedRoot, &validChain,
-#else
- NULL, NULL,
-#endif /* DEBUG */
- plContext);
- if (error) {
-#ifdef DEBUG_volkov
- char *temp = pkix_Error2ASCII(error, plContext);
- fprintf(stderr, "GET BUILD RES ERRORS:\n%s\n", temp);
- PKIX_PL_Free(temp, NULL);
-#endif /* DEBUG */
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- }
-#ifdef DEBUG_volkov
- if (trustedRoot) {
- CERT_DestroyCertificate(trustedRoot);
- }
- if (validChain) {
- CERT_DestroyCertList(validChain);
- }
-#endif /* DEBUG */
- if (procParams) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
- }
- if (plContext) {
- PKIX_PL_NssContext_Destroy(plContext);
- }
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- leakedObjNum =
- pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);
-
- if (pkixLog && leakedObjNum) {
- PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d."
- "Stack %s\n", memLeakLoopCount, errorFnStackString));
- }
- PR_Free(errorFnStackString);
- errorFnStackString = NULL;
- if (abortOnLeak) {
- PORT_Assert(leakedObjNum == 0);
- }
-
-} while (errorGenerated);
-
- runningLeakTest = PKIX_FALSE;
- PR_ATOMIC_DECREMENT(&parallelFnInvocationCount);
- usePKIXValidationEngine = savedUsePkixEngFlag;
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- return rv;
-}
-
-PKIX_CertSelector *
-cert_GetTargetCertConstraints(CERTCertificate *target, void *plContext)
-{
- PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_CertSelector *certSelector = NULL;
- PKIX_CertSelector *r= NULL;
- PKIX_PL_Cert *eeCert = NULL;
- PKIX_Error *error = NULL;
-
- error = PKIX_PL_Cert_CreateFromCERTCertificate(target, &eeCert, plContext);
- if (error != NULL) goto cleanup;
-
- error = PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext);
- if (error != NULL) goto cleanup;
-
- error = PKIX_ComCertSelParams_Create(&certSelParams, plContext);
- if (error != NULL) goto cleanup;
-
- error = PKIX_ComCertSelParams_SetCertificate(
- certSelParams, eeCert, plContext);
- if (error != NULL) goto cleanup;
-
- error = PKIX_CertSelector_SetCommonCertSelectorParams
- (certSelector, certSelParams, plContext);
- if (error != NULL) goto cleanup;
-
- error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certSelector, plContext);
- if (error == NULL) r = certSelector;
-
-cleanup:
- if (certSelParams != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelParams, plContext);
-
- if (eeCert != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)eeCert, plContext);
-
- if (certSelector != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);
-
- if (error != NULL) {
- SECErrorCodes nssErr;
-
- cert_PkixErrorToNssCode(error, &nssErr, plContext);
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- PORT_SetError(nssErr);
- }
-
- return r;
-}
-
-static PKIX_List *
-cert_GetCertStores(void *plContext)
-{
- PKIX_CertStore *certStore = NULL;
- PKIX_List *certStores = NULL;
- PKIX_List *r = NULL;
- PKIX_Error *error = NULL;
-
- error = PKIX_PL_Pk11CertStore_Create(&certStore, plContext);
- if (error != NULL) goto cleanup;
-
- error = PKIX_List_Create(&certStores, plContext);
- if (error != NULL) goto cleanup;
-
- error = PKIX_List_AppendItem( certStores,
- (PKIX_PL_Object *)certStore, plContext);
- if (error != NULL) goto cleanup;
-
- error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certStores, plContext);
- if (error == NULL) r = certStores;
-
-cleanup:
- if (certStores != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);
-
- if (certStore != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStore, plContext);
-
- if (error != NULL) {
- SECErrorCodes nssErr;
-
- cert_PkixErrorToNssCode(error, &nssErr, plContext);
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- PORT_SetError(nssErr);
- }
-
- return r;
-}
-
-
-struct fake_PKIX_PL_CertStruct {
- CERTCertificate *nssCert;
-};
-
-/* This needs to be part of the PKIX_PL_* */
-/* This definitely needs to go away, and be replaced with
- a real accessor function in PKIX */
-static CERTCertificate *
-cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert)
-{
- struct fake_PKIX_PL_CertStruct *fcert = NULL;
-
- fcert = (struct fake_PKIX_PL_CertStruct*)pkix_cert;
-
- return CERT_DupCertificate(fcert->nssCert);
-}
-
-PKIX_List *cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plContext)
-{
- PKIX_List *r = NULL;
- PKIX_List *policyList = NULL;
- PKIX_PL_OID *policyOID = NULL;
- PKIX_Error *error = NULL;
- int i;
-
- error = PKIX_List_Create(&policyList, plContext);
- if (error != NULL) {
- goto cleanup;
- }
-
- for (i=0; i<oidCount; i++) {
- error = PKIX_PL_OID_Create(oids[i], &policyOID, plContext);
- if (error) {
- goto cleanup;
- }
- error = PKIX_List_AppendItem(policyList,
- (PKIX_PL_Object *)policyOID, plContext);
- if (error != NULL) {
- goto cleanup;
- }
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
- policyOID = NULL;
- }
-
- error = PKIX_List_SetImmutable(policyList, plContext);
- if (error != NULL) goto cleanup;
-
- error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)policyList, plContext);
- if (error == NULL) r = policyList;
-
-cleanup:
- if (policyOID != NULL) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
- }
- if (policyList != NULL) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyList, plContext);
- }
- if (error != NULL) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- }
-
- return r;
-}
-
-CERTValOutParam *
-cert_pkix_FindOutputParam(CERTValOutParam *params, const CERTValParamOutType t)
-{
- CERTValOutParam *i;
- if (params == NULL) {
- return NULL;
- }
- for (i = params; i->type != cert_po_end; i++) {
- if (i->type == t) {
- return i;
- }
- }
- return NULL;
-}
-
-
-static PKIX_Error*
-setRevocationMethod(PKIX_RevocationChecker *revChecker,
- PKIX_ProcessingParams *procParams,
- const CERTRevocationTests *revTest,
- CERTRevocationMethodIndex certRevMethod,
- PKIX_RevocationMethodType pkixRevMethod,
- PKIX_Boolean verifyResponderUsages,
- PKIX_Boolean isLeafTest,
- void *plContext)
-{
- PKIX_UInt32 methodFlags = 0;
- PKIX_Error *error = NULL;
- int priority = 0;
-
- if (revTest->number_of_defined_methods <= certRevMethod) {
- return NULL;
- }
- if (revTest->preferred_methods) {
- int i = 0;
- for (;i < revTest->number_of_preferred_methods;i++) {
- if (revTest->preferred_methods[i] == certRevMethod)
- break;
- }
- priority = i;
- }
- methodFlags = revTest->cert_rev_flags_per_method[certRevMethod];
- if (verifyResponderUsages &&
- pkixRevMethod == PKIX_RevocationMethod_OCSP) {
- methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
- }
- error =
- PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
- pkixRevMethod, methodFlags,
- priority, NULL,
- isLeafTest, plContext);
- return error;
-}
-
-
-SECStatus
-cert_pkixSetParam(PKIX_ProcessingParams *procParams,
- const CERTValInParam *param, void *plContext)
-{
- PKIX_Error * error = NULL;
- SECStatus r=SECSuccess;
- PKIX_PL_Date *date = NULL;
- PKIX_List *policyOIDList = NULL;
- PKIX_List *certListPkix = NULL;
- const CERTRevocationFlags *flags;
- SECErrorCodes errCode = SEC_ERROR_INVALID_ARGS;
- const CERTCertList *certList = NULL;
- CERTCertListNode *node;
- PKIX_PL_Cert *certPkix = NULL;
- PKIX_TrustAnchor *trustAnchor = NULL;
- PKIX_PL_Date *revDate = NULL;
- PKIX_RevocationChecker *revChecker = NULL;
- PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext;
-
- /* XXX we need a way to map generic PKIX error to generic NSS errors */
-
- switch (param->type) {
-
- case cert_pi_policyOID:
-
- /* needed? */
- error = PKIX_ProcessingParams_SetExplicitPolicyRequired(
- procParams, PKIX_TRUE, plContext);
-
- if (error != NULL) {
- break;
- }
-
- policyOIDList = cert_PKIXMakeOIDList(param->value.array.oids,
- param->value.arraySize,plContext);
- if (policyOIDList == NULL) {
- r = SECFailure;
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- break;
- }
-
- error = PKIX_ProcessingParams_SetInitialPolicies(
- procParams,policyOIDList,plContext);
- break;
-
- case cert_pi_date:
- if (param->value.scalar.time == 0) {
- error = PKIX_PL_Date_Create_UTCTime(NULL, &date, plContext);
- if (error != NULL) {
- errCode = SEC_ERROR_INVALID_TIME;
- break;
- }
- } else {
- error = pkix_pl_Date_CreateFromPRTime(param->value.scalar.time,
- &date, plContext);
- if (error != NULL) {
- errCode = SEC_ERROR_INVALID_TIME;
- break;
- }
- }
-
- error = PKIX_ProcessingParams_SetDate(procParams, date, plContext);
- if (error != NULL) {
- errCode = SEC_ERROR_INVALID_TIME;
- }
- break;
-
- case cert_pi_revocationFlags:
- {
- PKIX_UInt32 leafIMFlags = 0;
- PKIX_UInt32 chainIMFlags = 0;
- PKIX_Boolean validatingResponderCert = PKIX_FALSE;
-
- flags = param->value.pointer.revocation;
- if (!flags) {
- PORT_SetError(errCode);
- r = SECFailure;
- break;
- }
-
- leafIMFlags =
- flags->leafTests.cert_rev_method_independent_flags;
- chainIMFlags =
- flags->chainTests.cert_rev_method_independent_flags;
-
- error =
- PKIX_RevocationChecker_Create(leafIMFlags, chainIMFlags,
- &revChecker, plContext);
- if (error) {
- break;
- }
-
- error =
- PKIX_ProcessingParams_SetRevocationChecker(procParams,
- revChecker, plContext);
- if (error) {
- break;
- }
-
- if (((PKIX_PL_NssContext*)plContext)->certificateUsage &
- certificateUsageStatusResponder) {
- validatingResponderCert = PKIX_TRUE;
- }
-
- error = setRevocationMethod(revChecker,
- procParams, &flags->leafTests,
- cert_revocation_method_crl,
- PKIX_RevocationMethod_CRL,
- validatingResponderCert,
- PKIX_TRUE, plContext);
- if (error) {
- break;
- }
-
- error = setRevocationMethod(revChecker,
- procParams, &flags->leafTests,
- cert_revocation_method_ocsp,
- PKIX_RevocationMethod_OCSP,
- validatingResponderCert,
- PKIX_TRUE, plContext);
- if (error) {
- break;
- }
-
- error = setRevocationMethod(revChecker,
- procParams, &flags->chainTests,
- cert_revocation_method_crl,
- PKIX_RevocationMethod_CRL,
- validatingResponderCert,
- PKIX_FALSE, plContext);
- if (error) {
- break;
- }
-
- error = setRevocationMethod(revChecker,
- procParams, &flags->chainTests,
- cert_revocation_method_ocsp,
- PKIX_RevocationMethod_OCSP,
- validatingResponderCert,
- PKIX_FALSE, plContext);
- if (error) {
- break;
- }
-
- }
- break;
-
- case cert_pi_trustAnchors:
- certList = param->value.pointer.chain;
- if (!certList) {
- PORT_SetError(errCode);
- r = SECFailure;
- break;
- }
- error = PKIX_List_Create(&certListPkix, plContext);
- if (error != NULL) {
- break;
- }
- for(node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList);
- node = CERT_LIST_NEXT(node) ) {
- error = PKIX_PL_Cert_CreateFromCERTCertificate(node->cert,
- &certPkix, plContext);
- if (error) {
- break;
- }
- error = PKIX_TrustAnchor_CreateWithCert(certPkix, &trustAnchor,
- plContext);
- if (error) {
- break;
- }
- error = PKIX_List_AppendItem(certListPkix,
- (PKIX_PL_Object*)trustAnchor, plContext);
- if (error) {
- break;
- }
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
- trustAnchor = NULL;
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext);
- certPkix = NULL;
- }
- error =
- PKIX_ProcessingParams_SetTrustAnchors(procParams, certListPkix,
- plContext);
- break;
-
- case cert_pi_useAIACertFetch:
- error =
- PKIX_ProcessingParams_SetUseAIAForCertFetching(procParams,
- (PRBool)(param->value.scalar.b != 0),
- plContext);
- break;
-
- case cert_pi_chainVerifyCallback:
- {
- const CERTChainVerifyCallback *chainVerifyCallback =
- param->value.pointer.chainVerifyCallback;
- if (!chainVerifyCallback || !chainVerifyCallback->isChainValid) {
- PORT_SetError(errCode);
- r = SECFailure;
- break;
- }
-
- nssContext->chainVerifyCallback = *chainVerifyCallback;
- }
- break;
-
- case cert_pi_useOnlyTrustAnchors:
- error =
- PKIX_ProcessingParams_SetUseOnlyTrustAnchors(procParams,
- (PRBool)(param->value.scalar.b != 0),
- plContext);
- break;
-
- default:
- PORT_SetError(errCode);
- r = SECFailure;
- break;
- }
-
- if (policyOIDList != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOIDList, plContext);
-
- if (date != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)date, plContext);
-
- if (revDate != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)revDate, plContext);
-
- if (revChecker != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)revChecker, plContext);
-
- if (certListPkix)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certListPkix, plContext);
-
- if (trustAnchor)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
-
- if (certPkix)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext);
-
- if (error != NULL) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- PORT_SetError(errCode);
- r = SECFailure;
- }
-
- return r;
-
-}
-
-void
-cert_pkixDestroyValOutParam(CERTValOutParam *params)
-{
- CERTValOutParam *i;
-
- if (params == NULL) {
- return;
- }
- for (i = params; i->type != cert_po_end; i++) {
- switch (i->type) {
- case cert_po_trustAnchor:
- if (i->value.pointer.cert) {
- CERT_DestroyCertificate(i->value.pointer.cert);
- i->value.pointer.cert = NULL;
- }
- break;
-
- case cert_po_certList:
- if (i->value.pointer.chain) {
- CERT_DestroyCertList(i->value.pointer.chain);
- i->value.pointer.chain = NULL;
- }
- break;
-
- default:
- break;
- }
- }
-}
-
-static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD
- | CERT_REV_M_FORBID_NETWORK_FETCHING
- | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- CERT_REV_M_TEST_USING_THIS_METHOD
-};
-
-static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD
- | CERT_REV_M_FORBID_NETWORK_FETCHING
- | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- 0
-};
-
-static CERTRevocationMethodIndex
-certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference = {
- cert_revocation_method_crl
-};
-
-static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy = {
- {
- /* leafTests */
- 2,
- certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags,
- 1,
- &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference,
- 0
- },
- {
- /* chainTests */
- 2,
- certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags,
- 0,
- 0,
- 0
- }
-};
-
-extern const CERTRevocationFlags*
-CERT_GetClassicOCSPEnabledSoftFailurePolicy()
-{
- return &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy;
-}
-
-
-static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD
- | CERT_REV_M_FORBID_NETWORK_FETCHING
- | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- CERT_REV_M_TEST_USING_THIS_METHOD
- | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO
-};
-
-static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD
- | CERT_REV_M_FORBID_NETWORK_FETCHING
- | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- 0
-};
-
-static CERTRevocationMethodIndex
-certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference = {
- cert_revocation_method_crl
-};
-
-static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy = {
- {
- /* leafTests */
- 2,
- certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags,
- 1,
- &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference,
- 0
- },
- {
- /* chainTests */
- 2,
- certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags,
- 0,
- 0,
- 0
- }
-};
-
-extern const CERTRevocationFlags*
-CERT_GetClassicOCSPEnabledHardFailurePolicy()
-{
- return &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy;
-}
-
-
-static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD
- | CERT_REV_M_FORBID_NETWORK_FETCHING
- | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- 0
-};
-
-static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD
- | CERT_REV_M_FORBID_NETWORK_FETCHING
- | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
- /* ocsp */
- 0
-};
-
-static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Disabled_Policy = {
- {
- /* leafTests */
- 2,
- certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags,
- 0,
- 0,
- 0
- },
- {
- /* chainTests */
- 2,
- certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags,
- 0,
- 0,
- 0
- }
-};
-
-extern const CERTRevocationFlags*
-CERT_GetClassicOCSPDisabledPolicy()
-{
- return &certRev_NSS_3_11_Ocsp_Disabled_Policy;
-}
-
-
-static PRUint64 certRev_PKIX_Verify_Nist_Policy_LeafFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD
- | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO
- | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE,
- /* ocsp */
- 0
-};
-
-static PRUint64 certRev_PKIX_Verify_Nist_Policy_ChainFlags[2] = {
- /* crl */
- CERT_REV_M_TEST_USING_THIS_METHOD
- | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO
- | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE,
- /* ocsp */
- 0
-};
-
-static const CERTRevocationFlags certRev_PKIX_Verify_Nist_Policy = {
- {
- /* leafTests */
- 2,
- certRev_PKIX_Verify_Nist_Policy_LeafFlags,
- 0,
- 0,
- 0
- },
- {
- /* chainTests */
- 2,
- certRev_PKIX_Verify_Nist_Policy_ChainFlags,
- 0,
- 0,
- 0
- }
-};
-
-extern const CERTRevocationFlags*
-CERT_GetPKIXVerifyNistRevocationPolicy()
-{
- return &certRev_PKIX_Verify_Nist_Policy;
-}
-
-CERTRevocationFlags *
-CERT_AllocCERTRevocationFlags(
- PRUint32 number_leaf_methods, PRUint32 number_leaf_pref_methods,
- PRUint32 number_chain_methods, PRUint32 number_chain_pref_methods)
-{
- CERTRevocationFlags *flags;
-
- flags = PORT_New(CERTRevocationFlags);
- if (!flags)
- return(NULL);
-
- flags->leafTests.number_of_defined_methods = number_leaf_methods;
- flags->leafTests.cert_rev_flags_per_method =
- PORT_NewArray(PRUint64, number_leaf_methods);
-
- flags->leafTests.number_of_preferred_methods = number_leaf_pref_methods;
- flags->leafTests.preferred_methods =
- PORT_NewArray(CERTRevocationMethodIndex, number_leaf_pref_methods);
-
- flags->chainTests.number_of_defined_methods = number_chain_methods;
- flags->chainTests.cert_rev_flags_per_method =
- PORT_NewArray(PRUint64, number_chain_methods);
-
- flags->chainTests.number_of_preferred_methods = number_chain_pref_methods;
- flags->chainTests.preferred_methods =
- PORT_NewArray(CERTRevocationMethodIndex, number_chain_pref_methods);
-
- if (!flags->leafTests.cert_rev_flags_per_method
- || !flags->leafTests.preferred_methods
- || !flags->chainTests.cert_rev_flags_per_method
- || !flags->chainTests.preferred_methods) {
- CERT_DestroyCERTRevocationFlags(flags);
- return (NULL);
- }
-
- return flags;
-}
-
-void CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags)
-{
- if (!flags)
- return;
-
- if (flags->leafTests.cert_rev_flags_per_method)
- PORT_Free(flags->leafTests.cert_rev_flags_per_method);
-
- if (flags->leafTests.preferred_methods)
- PORT_Free(flags->leafTests.preferred_methods);
-
- if (flags->chainTests.cert_rev_flags_per_method)
- PORT_Free(flags->chainTests.cert_rev_flags_per_method);
-
- if (flags->chainTests.preferred_methods)
- PORT_Free(flags->chainTests.preferred_methods);
-
- PORT_Free(flags);
-}
-
-/*
- * CERT_PKIXVerifyCert
- *
- * Verify a Certificate using the PKIX library.
- *
- * Parameters:
- * cert - the target certificate to verify. Must be non-null
- * params - an array of type/value parameters which can be
- * used to modify the behavior of the validation
- * algorithm, or supply additional constraints.
- *
- * outputTrustAnchor - the trust anchor which the certificate
- * chains to. The caller is responsible
- * for freeing this.
- *
- * Example Usage:
- * CERTValParam args[3];
- * args[0].type = cvpt_policyOID;
- * args[0].value.si = oid;
- * args[1].type = revCheckRequired;
- * args[1].value.b = PR_TRUE;
- * args[2].type = cvpt_end;
- *
- * CERT_PKIXVerifyCert(cert, &output, args
- */
-SECStatus CERT_PKIXVerifyCert(
- CERTCertificate *cert,
- SECCertificateUsage usages,
- CERTValInParam *paramsIn,
- CERTValOutParam *paramsOut,
- void *wincx)
-{
- SECStatus r = SECFailure;
- PKIX_Error * error = NULL;
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_BuildResult * buildResult = NULL;
- void * nbioContext = NULL; /* for non-blocking IO */
- void * buildState = NULL; /* for non-blocking IO */
- PKIX_CertSelector * certSelector = NULL;
- PKIX_List * certStores = NULL;
- PKIX_ValidateResult * valResult = NULL;
- PKIX_VerifyNode * verifyNode = NULL;
- PKIX_TrustAnchor * trustAnchor = NULL;
- PKIX_PL_Cert * trustAnchorCert = NULL;
- PKIX_List * builtCertList = NULL;
- CERTValOutParam * oparam = NULL;
- int i=0;
-
- void *plContext = NULL;
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- int leakedObjNum = 0;
- int memLeakLoopCount = 0;
- int objCountTable[PKIX_NUMTYPES];
- int fnInvLocalCount = 0;
- PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;
-
- if (usePKIXValidationEngine) {
- /* current memory leak testing implementation does not allow
- * to run simultaneous tests one the same or a different threads.
- * Setting the variable to false, to make additional chain
- * validations be handled by old nss. */
- usePKIXValidationEngine = PR_FALSE;
- }
- testStartFnStackPosition = 1;
- fnStackNameArr[0] = "CERT_PKIXVerifyCert";
- fnStackInvCountArr[0] = 0;
- PKIX_Boolean abortOnLeak =
- (PR_GetEnv("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ?
- PKIX_FALSE : PKIX_TRUE;
- runningLeakTest = PKIX_TRUE;
-
- /* Prevent multi-threaded run of object leak test */
- fnInvLocalCount = PR_ATOMIC_INCREMENT(&parallelFnInvocationCount);
- PORT_Assert(fnInvLocalCount == 1);
-
-do {
- r = SECFailure;
- error = NULL;
- procParams = NULL;
- buildResult = NULL;
- nbioContext = NULL; /* for non-blocking IO */
- buildState = NULL; /* for non-blocking IO */
- certSelector = NULL;
- certStores = NULL;
- valResult = NULL;
- verifyNode = NULL;
- trustAnchor = NULL;
- trustAnchorCert = NULL;
- builtCertList = NULL;
- oparam = NULL;
- i=0;
- errorGenerated = PKIX_FALSE;
- stackPosition = 0;
-
- if (leakedObjNum) {
- pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
- }
- memLeakLoopCount += 1;
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- error = PKIX_PL_NssContext_Create(
- 0, PR_FALSE /*use arena*/, wincx, &plContext);
- if (error != NULL) { /* need pkix->nss error map */
- PORT_SetError(SEC_ERROR_CERT_NOT_VALID);
- goto cleanup;
- }
-
- error = pkix_pl_NssContext_SetCertUsage(usages, plContext);
- if (error != NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
-
- error = PKIX_ProcessingParams_Create(&procParams, plContext);
- if (error != NULL) { /* need pkix->nss error map */
- PORT_SetError(SEC_ERROR_CERT_NOT_VALID);
- goto cleanup;
- }
-
- /* local cert store should be set into procParams before
- * filling in revocation settings. */
- certStores = cert_GetCertStores(plContext);
- if (certStores == NULL) {
- goto cleanup;
- }
- error = PKIX_ProcessingParams_SetCertStores
- (procParams, certStores, plContext);
- if (error != NULL) {
- goto cleanup;
- }
-
- /* now process the extensible input parameters structure */
- if (paramsIn != NULL) {
- i=0;
- while (paramsIn[i].type != cert_pi_end) {
- if (paramsIn[i].type >= cert_pi_max) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
- if (cert_pkixSetParam(procParams,
- &paramsIn[i],plContext) != SECSuccess) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
- i++;
- }
- }
-
- certSelector = cert_GetTargetCertConstraints(cert, plContext);
- if (certSelector == NULL) {
- goto cleanup;
- }
- error = PKIX_ProcessingParams_SetTargetCertConstraints
- (procParams, certSelector, plContext);
- if (error != NULL) {
- goto cleanup;
- }
-
- error = PKIX_BuildChain( procParams, &nbioContext,
- &buildState, &buildResult, &verifyNode,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
-
- error = PKIX_BuildResult_GetValidateResult( buildResult, &valResult,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
-
- error = PKIX_ValidateResult_GetTrustAnchor( valResult, &trustAnchor,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
-
- if (trustAnchor != NULL) {
- error = PKIX_TrustAnchor_GetTrustedCert( trustAnchor, &trustAnchorCert,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
- }
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- /* Can not continue if error was generated but not returned.
- * Jumping to cleanup. */
- if (errorGenerated) goto cleanup;
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_trustAnchor);
- if (oparam != NULL) {
- if (trustAnchorCert != NULL) {
- oparam->value.pointer.cert =
- cert_NSSCertFromPKIXCert(trustAnchorCert);
- } else {
- oparam->value.pointer.cert = NULL;
- }
- }
-
- error = PKIX_BuildResult_GetCertChain( buildResult, &builtCertList,
- plContext);
- if (error != NULL) {
- goto cleanup;
- }
-
- oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_certList);
- if (oparam != NULL) {
- error = cert_PkixToNssCertsChain(builtCertList,
- &oparam->value.pointer.chain,
- plContext);
- if (error) goto cleanup;
- }
-
- r = SECSuccess;
-
-cleanup:
- if (verifyNode) {
- /* Return validation log only upon error. */
- oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_errorLog);
-#ifdef PKIX_OBJECT_LEAK_TEST
- if (!errorGenerated)
-#endif /* PKIX_OBJECT_LEAK_TEST */
- if (r && oparam != NULL) {
- PKIX_Error *tmpError =
- cert_GetLogFromVerifyNode(oparam->value.pointer.log,
- verifyNode, plContext);
- if (tmpError) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
- }
- }
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)verifyNode, plContext);
- }
-
- if (procParams != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
-
- if (trustAnchorCert != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchorCert, plContext);
-
- if (trustAnchor != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
-
- if (valResult != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)valResult, plContext);
-
- if (buildResult != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)buildResult, plContext);
-
- if (certStores != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);
-
- if (certSelector != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);
-
- if (builtCertList != NULL)
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)builtCertList, plContext);
-
- if (error != NULL) {
- SECErrorCodes nssErrorCode = 0;
-
- cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
- cert_pkixDestroyValOutParam(paramsOut);
- PORT_SetError(nssErrorCode);
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
- }
-
- PKIX_PL_NssContext_Destroy(plContext);
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- leakedObjNum =
- pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);
-
- if (pkixLog && leakedObjNum) {
- PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d."
- "Stack %s\n", memLeakLoopCount, errorFnStackString));
- }
- PR_Free(errorFnStackString);
- errorFnStackString = NULL;
- if (abortOnLeak) {
- PORT_Assert(leakedObjNum == 0);
- }
-
-} while (errorGenerated);
-
- runningLeakTest = PKIX_FALSE;
- PR_ATOMIC_DECREMENT(&parallelFnInvocationCount);
- usePKIXValidationEngine = savedUsePkixEngFlag;
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- return r;
-}
diff --git a/security/nss/lib/certhigh/certvfypkixprint.c b/security/nss/lib/certhigh/certvfypkixprint.c
deleted file mode 100644
index d08d1be65..000000000
--- a/security/nss/lib/certhigh/certvfypkixprint.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * nss_pkix_proxy.h
- *
- * PKIX - NSS proxy functions
- *
- */
-#include "cert.h"
-#include "pkix_pl_common.h"
-
-#ifdef DEBUG
-
-char *
-pkix_Error2ASCII(PKIX_Error *error, void *plContext)
-{
- PKIX_UInt32 length;
- char *asciiString = NULL;
- PKIX_PL_String *pkixString = NULL;
- PKIX_Error *errorResult = NULL;
-
- errorResult = PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)error, &pkixString, plContext);
- if (errorResult) goto cleanup;
-
- errorResult = PKIX_PL_String_GetEncoded
- (pkixString,
- PKIX_ESCASCII,
- (void **)&asciiString,
- &length,
- plContext);
-
-cleanup:
-
- if (pkixString){
- if (PKIX_PL_Object_DecRef
- ((PKIX_PL_Object*)pkixString, plContext)){
- return (NULL);
- }
- }
-
- if (errorResult){
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)errorResult, plContext);
- return (NULL);
- }
-
- return (asciiString);
-}
-
-char *
-pkix_Object2ASCII(PKIX_PL_Object *object)
-{
- PKIX_UInt32 length;
- char *asciiString = NULL;
- PKIX_PL_String *pkixString = NULL;
- PKIX_Error *errorResult = NULL;
-
- errorResult = PKIX_PL_Object_ToString
- (object, &pkixString, NULL);
- if (errorResult) goto cleanup;
-
- errorResult = PKIX_PL_String_GetEncoded
- (pkixString, PKIX_ESCASCII, (void **)&asciiString, &length, NULL);
-
-cleanup:
-
- if (pkixString){
- if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixString, NULL)){
- return (NULL);
- }
- }
-
- if (errorResult){
- return (NULL);
- }
-
- return (asciiString);
-}
-
-char *
-pkix_Cert2ASCII(PKIX_PL_Cert *cert)
-{
- PKIX_PL_X500Name *issuer = NULL;
- void *issuerAscii = NULL;
- PKIX_PL_X500Name *subject = NULL;
- void *subjectAscii = NULL;
- void *asciiString = NULL;
- PKIX_Error *errorResult = NULL;
- PKIX_UInt32 numChars;
- PKIX_UInt32 refCount = 0;
-
- /* Issuer */
- errorResult = PKIX_PL_Cert_GetIssuer(cert, &issuer, NULL);
- if (errorResult) goto cleanup;
-
- issuerAscii = pkix_Object2ASCII((PKIX_PL_Object*)issuer);
-
- /* Subject */
- errorResult = PKIX_PL_Cert_GetSubject(cert, &subject, NULL);
- if (errorResult) goto cleanup;
-
- if (subject){
- subjectAscii = pkix_Object2ASCII((PKIX_PL_Object*)subject);
- }
-
-/* errorResult = PKIX_PL_Object_GetRefCount((PKIX_PL_Object*)cert, &refCount, NULL); */
- if (errorResult) goto cleanup;
-
- errorResult = PKIX_PL_Malloc(200, &asciiString, NULL);
- if (errorResult) goto cleanup;
-
- numChars =
- PR_snprintf
- (asciiString,
- 200,
- "Ref: %d Subject=%s\nIssuer=%s\n",
- refCount,
- subjectAscii,
- issuerAscii);
-
- if (!numChars) goto cleanup;
-
-cleanup:
-
- if (issuer){
- if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)issuer, NULL)){
- return (NULL);
- }
- }
-
- if (subject){
- if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)subject, NULL)){
- return (NULL);
- }
- }
-
- if (PKIX_PL_Free((PKIX_PL_Object*)issuerAscii, NULL)){
- return (NULL);
- }
-
- if (PKIX_PL_Free((PKIX_PL_Object*)subjectAscii, NULL)){
- return (NULL);
- }
-
- if (errorResult){
- return (NULL);
- }
-
- return (asciiString);
-}
-
-PKIX_Error *
-cert_PrintCertChain(
- PKIX_List *pkixCertChain,
- void *plContext)
-{
- PKIX_PL_Cert *cert = NULL;
- PKIX_UInt32 numCerts = 0, i = 0;
- char *asciiResult = NULL;
-
- PKIX_ENTER(CERTVFYPKIX, "cert_PrintCertChain");
-
- PKIX_CHECK(
- PKIX_List_GetLength(pkixCertChain, &numCerts, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- fprintf(stderr, "\n");
-
- for (i = 0; i < numCerts; i++){
- PKIX_CHECK
- (PKIX_List_GetItem
- (pkixCertChain, i, (PKIX_PL_Object**)&cert, plContext),
- PKIX_LISTGETITEMFAILED);
-
- asciiResult = pkix_Cert2ASCII(cert);
-
- fprintf(stderr, "CERT[%d]:\n%s\n", i, asciiResult);
-
- PKIX_PL_Free(asciiResult, plContext);
- asciiResult = NULL;
-
- PKIX_DECREF(cert);
- }
-
-cleanup:
- PKIX_DECREF(cert);
-
- PKIX_RETURN(CERTVFYPKIX);
-}
-
-void
-cert_PrintCert(
- PKIX_PL_Cert *pkixCert,
- void *plContext)
-{
- char *asciiResult = NULL;
-
- asciiResult = pkix_Cert2ASCII(pkixCert);
-
- fprintf(stderr, "CERT[0]:\n%s\n", asciiResult);
-
- PKIX_PL_Free(asciiResult, plContext);
-}
-
-#endif /* DEBUG */
diff --git a/security/nss/lib/certhigh/config.mk b/security/nss/lib/certhigh/config.mk
deleted file mode 100644
index b8c03de79..000000000
--- a/security/nss/lib/certhigh/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/certhigh/crlv2.c b/security/nss/lib/certhigh/crlv2.c
deleted file mode 100644
index c81ab5bff..000000000
--- a/security/nss/lib/certhigh/crlv2.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Code for dealing with x.509 v3 crl and crl entries extensions.
- *
- * $Id$
- */
-
-#include "cert.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "secoidt.h"
-#include "secder.h"
-#include "secasn1.h"
-#include "certxutl.h"
-
-SECStatus
-CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid, SECItem *value)
-{
- return (cert_FindExtensionByOID (crl->extensions, oid, value));
-}
-
-
-SECStatus
-CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value)
-{
- return (cert_FindExtension (crl->extensions, tag, value));
-}
-
-
-/* Callback to set extensions and adjust verison */
-static void
-SetCrlExts(void *object, CERTCertExtension **exts)
-{
- CERTCrl *crl = (CERTCrl *)object;
-
- crl->extensions = exts;
- DER_SetUInteger (crl->arena, &crl->version, SEC_CRL_VERSION_2);
-}
-
-void *
-CERT_StartCRLExtensions(CERTCrl *crl)
-{
- return (cert_StartExtensions ((void *)crl, crl->arena, SetCrlExts));
-}
-
-static void
-SetCrlEntryExts(void *object, CERTCertExtension **exts)
-{
- CERTCrlEntry *crlEntry = (CERTCrlEntry *)object;
-
- crlEntry->extensions = exts;
-}
-
-void *
-CERT_StartCRLEntryExtensions(CERTCrl *crl, CERTCrlEntry *entry)
-{
- return (cert_StartExtensions (entry, crl->arena, SetCrlEntryExts));
-}
-
-SECStatus CERT_FindCRLNumberExten (PRArenaPool *arena, CERTCrl *crl,
- SECItem *value)
-{
- SECItem encodedExtenValue;
- SECItem *tmpItem = NULL;
- SECStatus rv;
- void *mark = NULL;
-
- encodedExtenValue.data = NULL;
- encodedExtenValue.len = 0;
-
- rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER,
- &encodedExtenValue);
- if ( rv != SECSuccess )
- return (rv);
-
- mark = PORT_ArenaMark(arena);
-
- tmpItem = SECITEM_ArenaDupItem(arena, &encodedExtenValue);
- if (tmpItem) {
- rv = SEC_QuickDERDecodeItem (arena, value,
- SEC_ASN1_GET(SEC_IntegerTemplate),
- tmpItem);
- } else {
- rv = SECFailure;
- }
-
- PORT_Free (encodedExtenValue.data);
- if (rv == SECFailure) {
- PORT_ArenaRelease(arena, mark);
- } else {
- PORT_ArenaUnmark(arena, mark);
- }
- return (rv);
-}
-
-SECStatus CERT_FindCRLEntryReasonExten (CERTCrlEntry *crlEntry,
- CERTCRLEntryReasonCode *value)
-{
- SECItem wrapperItem = {siBuffer,0};
- SECItem tmpItem = {siBuffer,0};
- SECStatus rv;
- PRArenaPool *arena = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( ! arena ) {
- return(SECFailure);
- }
-
- rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE,
- &wrapperItem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
- SEC_ASN1_GET(SEC_EnumeratedTemplate),
- &wrapperItem);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- *value = (CERTCRLEntryReasonCode) DER_GetInteger(&tmpItem);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- if ( wrapperItem.data ) {
- PORT_Free(wrapperItem.data);
- }
-
- return (rv);
-}
-
-SECStatus CERT_FindInvalidDateExten (CERTCrl *crl, int64 *value)
-{
- SECItem encodedExtenValue;
- SECItem decodedExtenValue = {siBuffer,0};
- SECStatus rv;
-
- encodedExtenValue.data = decodedExtenValue.data = NULL;
- encodedExtenValue.len = decodedExtenValue.len = 0;
-
- rv = cert_FindExtension
- (crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue);
- if ( rv != SECSuccess )
- return (rv);
-
- rv = SEC_ASN1DecodeItem (NULL, &decodedExtenValue,
- SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
- &encodedExtenValue);
- if (rv == SECSuccess)
- rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue);
- PORT_Free (decodedExtenValue.data);
- PORT_Free (encodedExtenValue.data);
- return (rv);
-}
diff --git a/security/nss/lib/certhigh/manifest.mn b/security/nss/lib/certhigh/manifest.mn
deleted file mode 100644
index fe2ab1d46..000000000
--- a/security/nss/lib/certhigh/manifest.mn
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-
-EXPORTS = \
- ocsp.h \
- ocspt.h \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- ocspti.h \
- ocspi.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- certhtml.c \
- certreq.c \
- crlv2.c \
- ocsp.c \
- ocspsig.c \
- certhigh.c \
- certvfy.c \
- certvfypkix.c \
- certvfypkixprint.c \
- xcrldist.c \
- $(NULL)
-
-LIBRARY_NAME = certhi
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c
deleted file mode 100644
index f07da0849..000000000
--- a/security/nss/lib/certhigh/ocsp.c
+++ /dev/null
@@ -1,5819 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Implementation of OCSP services, for both client and server.
- * (XXX, really, mostly just for client right now, but intended to do both.)
- *
- * $Id$
- */
-
-#include "prerror.h"
-#include "prprf.h"
-#include "plarena.h"
-#include "prnetdb.h"
-
-#include "seccomon.h"
-#include "secitem.h"
-#include "secoidt.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "cert.h"
-#include "xconst.h"
-#include "secerr.h"
-#include "secoid.h"
-#include "hasht.h"
-#include "sechash.h"
-#include "secasn1.h"
-#include "keyhi.h"
-#include "cryptohi.h"
-#include "ocsp.h"
-#include "ocspti.h"
-#include "ocspi.h"
-#include "genname.h"
-#include "certxutl.h"
-#include "pk11func.h" /* for PK11_HashBuf */
-#include <stdarg.h>
-#include <plhash.h>
-
-#define DEFAULT_OCSP_CACHE_SIZE 1000
-#define DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT 1*60*60L
-#define DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT 24*60*60L
-#define DEFAULT_OSCP_TIMEOUT_SECONDS 60
-#define MICROSECONDS_PER_SECOND 1000000L
-
-typedef struct OCSPCacheItemStr OCSPCacheItem;
-typedef struct OCSPCacheDataStr OCSPCacheData;
-
-struct OCSPCacheItemStr {
- /* LRU linking */
- OCSPCacheItem *moreRecent;
- OCSPCacheItem *lessRecent;
-
- /* key */
- CERTOCSPCertID *certID;
- /* CertID's arena also used to allocate "this" cache item */
-
- /* cache control information */
- PRTime nextFetchAttemptTime;
-
- /* Cached contents. Use a separate arena, because lifetime is different */
- PRArenaPool *certStatusArena; /* NULL means: no cert status cached */
- ocspCertStatus certStatus;
-
- /* This may contain an error code when no OCSP response is available. */
- SECErrorCodes missingResponseError;
-
- PRPackedBool haveThisUpdate;
- PRPackedBool haveNextUpdate;
- PRTime thisUpdate;
- PRTime nextUpdate;
-};
-
-struct OCSPCacheDataStr {
- PLHashTable *entries;
- PRUint32 numberOfEntries;
- OCSPCacheItem *MRUitem; /* most recently used cache item */
- OCSPCacheItem *LRUitem; /* least recently used cache item */
-};
-
-static struct OCSPGlobalStruct {
- PRMonitor *monitor;
- const SEC_HttpClientFcn *defaultHttpClientFcn;
- PRInt32 maxCacheEntries;
- PRUint32 minimumSecondsToNextFetchAttempt;
- PRUint32 maximumSecondsToNextFetchAttempt;
- PRUint32 timeoutSeconds;
- OCSPCacheData cache;
- SEC_OcspFailureMode ocspFailureMode;
- CERT_StringFromCertFcn alternateOCSPAIAFcn;
-} OCSP_Global = { NULL,
- NULL,
- DEFAULT_OCSP_CACHE_SIZE,
- DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT,
- DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT,
- DEFAULT_OSCP_TIMEOUT_SECONDS,
- {NULL, 0, NULL, NULL},
- ocspMode_FailureIsVerificationFailure,
- NULL
- };
-
-
-
-/* Forward declarations */
-static SECItem *
-ocsp_GetEncodedOCSPResponseFromRequest(PRArenaPool *arena,
- CERTOCSPRequest *request,
- const char *location, int64 time,
- PRBool addServiceLocator,
- void *pwArg,
- CERTOCSPRequest **pRequest);
-static SECStatus
-ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
- CERTOCSPCertID *certID,
- CERTCertificate *cert,
- int64 time,
- void *pwArg,
- PRBool *certIDWasConsumed,
- SECStatus *rv_ocsp);
-
-static SECStatus
-ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle,
- CERTOCSPCertID *certID,
- CERTCertificate *cert,
- int64 time,
- void *pwArg,
- const SECItem *encodedResponse,
- PRBool cacheInvalid,
- PRBool *certIDWasConsumed,
- SECStatus *rv_ocsp);
-
-static SECStatus
-ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- int64 time,
- CERTOCSPSingleResponse **pSingleResponse);
-
-static SECStatus
-ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, int64 time);
-
-static CERTOCSPCertID *
-cert_DupOCSPCertID(CERTOCSPCertID *src);
-
-#ifndef DEBUG
-#define OCSP_TRACE(msg)
-#define OCSP_TRACE_TIME(msg, time)
-#define OCSP_TRACE_CERT(cert)
-#define OCSP_TRACE_CERTID(certid)
-#else
-#define OCSP_TRACE(msg) ocsp_Trace msg
-#define OCSP_TRACE_TIME(msg, time) ocsp_dumpStringWithTime(msg, time)
-#define OCSP_TRACE_CERT(cert) dumpCertificate(cert)
-#define OCSP_TRACE_CERTID(certid) dumpCertID(certid)
-
-#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS) \
- || defined(XP_MACOSX)
-#define NSS_HAVE_GETENV 1
-#endif
-
-static PRBool wantOcspTrace(void)
-{
- static PRBool firstTime = PR_TRUE;
- static PRBool wantTrace = PR_FALSE;
-
-#ifdef NSS_HAVE_GETENV
- if (firstTime) {
- char *ev = getenv("NSS_TRACE_OCSP");
- if (ev && ev[0]) {
- wantTrace = PR_TRUE;
- }
- firstTime = PR_FALSE;
- }
-#endif
- return wantTrace;
-}
-
-static void
-ocsp_Trace(const char *format, ...)
-{
- char buf[2000];
- va_list args;
-
- if (!wantOcspTrace())
- return;
- va_start(args, format);
- PR_vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
- PR_LogPrint("%s", buf);
-}
-
-static void
-ocsp_dumpStringWithTime(const char *str, int64 time)
-{
- PRExplodedTime timePrintable;
- char timestr[256];
-
- if (!wantOcspTrace())
- return;
- PR_ExplodeTime(time, PR_GMTParameters, &timePrintable);
- if (PR_FormatTime(timestr, 256, "%a %b %d %H:%M:%S %Y", &timePrintable)) {
- ocsp_Trace("OCSP %s %s\n", str, timestr);
- }
-}
-
-static void
-printHexString(const char *prefix, SECItem *hexval)
-{
- unsigned int i;
- char *hexbuf = NULL;
-
- for (i = 0; i < hexval->len; i++) {
- if (i != hexval->len - 1) {
- hexbuf = PR_sprintf_append(hexbuf, "%02x:", hexval->data[i]);
- } else {
- hexbuf = PR_sprintf_append(hexbuf, "%02x", hexval->data[i]);
- }
- }
- if (hexbuf) {
- ocsp_Trace("%s %s\n", prefix, hexbuf);
- PR_smprintf_free(hexbuf);
- }
-}
-
-static void
-dumpCertificate(CERTCertificate *cert)
-{
- if (!wantOcspTrace())
- return;
-
- ocsp_Trace("OCSP ----------------\n");
- ocsp_Trace("OCSP ## SUBJECT: %s\n", cert->subjectName);
- {
- int64 timeBefore, timeAfter;
- PRExplodedTime beforePrintable, afterPrintable;
- char beforestr[256], afterstr[256];
- PRStatus rv1, rv2;
- DER_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore);
- DER_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter);
- PR_ExplodeTime(timeBefore, PR_GMTParameters, &beforePrintable);
- PR_ExplodeTime(timeAfter, PR_GMTParameters, &afterPrintable);
- rv1 = PR_FormatTime(beforestr, 256, "%a %b %d %H:%M:%S %Y",
- &beforePrintable);
- rv2 = PR_FormatTime(afterstr, 256, "%a %b %d %H:%M:%S %Y",
- &afterPrintable);
- ocsp_Trace("OCSP ## VALIDITY: %s to %s\n", rv1 ? beforestr : "",
- rv2 ? afterstr : "");
- }
- ocsp_Trace("OCSP ## ISSUER: %s\n", cert->issuerName);
- printHexString("OCSP ## SERIAL NUMBER:", &cert->serialNumber);
-}
-
-static void
-dumpCertID(CERTOCSPCertID *certID)
-{
- if (!wantOcspTrace())
- return;
-
- printHexString("OCSP certID issuer", &certID->issuerNameHash);
- printHexString("OCSP certID serial", &certID->serialNumber);
-}
-#endif
-
-SECStatus
-SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable)
-{
- if (!OCSP_Global.monitor) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
-
- PR_EnterMonitor(OCSP_Global.monitor);
- OCSP_Global.defaultHttpClientFcn = fcnTable;
- PR_ExitMonitor(OCSP_Global.monitor);
-
- return SECSuccess;
-}
-
-SECStatus
-CERT_RegisterAlternateOCSPAIAInfoCallBack(
- CERT_StringFromCertFcn newCallback,
- CERT_StringFromCertFcn * oldCallback)
-{
- CERT_StringFromCertFcn old;
-
- if (!OCSP_Global.monitor) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
-
- PR_EnterMonitor(OCSP_Global.monitor);
- old = OCSP_Global.alternateOCSPAIAFcn;
- OCSP_Global.alternateOCSPAIAFcn = newCallback;
- PR_ExitMonitor(OCSP_Global.monitor);
- if (oldCallback)
- *oldCallback = old;
- return SECSuccess;
-}
-
-static PLHashNumber PR_CALLBACK
-ocsp_CacheKeyHashFunction(const void *key)
-{
- CERTOCSPCertID *cid = (CERTOCSPCertID *)key;
- PLHashNumber hash = 0;
- unsigned int i;
- unsigned char *walk;
-
- /* a very simple hash calculation for the initial coding phase */
- walk = (unsigned char*)cid->issuerNameHash.data;
- for (i=0; i < cid->issuerNameHash.len; ++i, ++walk) {
- hash += *walk;
- }
- walk = (unsigned char*)cid->issuerKeyHash.data;
- for (i=0; i < cid->issuerKeyHash.len; ++i, ++walk) {
- hash += *walk;
- }
- walk = (unsigned char*)cid->serialNumber.data;
- for (i=0; i < cid->serialNumber.len; ++i, ++walk) {
- hash += *walk;
- }
- return hash;
-}
-
-static PRIntn PR_CALLBACK
-ocsp_CacheKeyCompareFunction(const void *v1, const void *v2)
-{
- CERTOCSPCertID *cid1 = (CERTOCSPCertID *)v1;
- CERTOCSPCertID *cid2 = (CERTOCSPCertID *)v2;
-
- return (SECEqual == SECITEM_CompareItem(&cid1->issuerNameHash,
- &cid2->issuerNameHash)
- && SECEqual == SECITEM_CompareItem(&cid1->issuerKeyHash,
- &cid2->issuerKeyHash)
- && SECEqual == SECITEM_CompareItem(&cid1->serialNumber,
- &cid2->serialNumber));
-}
-
-static SECStatus
-ocsp_CopyRevokedInfo(PRArenaPool *arena, ocspCertStatus *dest,
- ocspRevokedInfo *src)
-{
- SECStatus rv = SECFailure;
- void *mark;
-
- mark = PORT_ArenaMark(arena);
-
- dest->certStatusInfo.revokedInfo =
- (ocspRevokedInfo *) PORT_ArenaZAlloc(arena, sizeof(ocspRevokedInfo));
- if (!dest->certStatusInfo.revokedInfo) {
- goto loser;
- }
-
- rv = SECITEM_CopyItem(arena,
- &dest->certStatusInfo.revokedInfo->revocationTime,
- &src->revocationTime);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- if (src->revocationReason) {
- dest->certStatusInfo.revokedInfo->revocationReason =
- SECITEM_ArenaDupItem(arena, src->revocationReason);
- if (!dest->certStatusInfo.revokedInfo->revocationReason) {
- goto loser;
- }
- } else {
- dest->certStatusInfo.revokedInfo->revocationReason = NULL;
- }
-
- PORT_ArenaUnmark(arena, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(arena, mark);
- return SECFailure;
-}
-
-static SECStatus
-ocsp_CopyCertStatus(PRArenaPool *arena, ocspCertStatus *dest,
- ocspCertStatus*src)
-{
- SECStatus rv = SECFailure;
- dest->certStatusType = src->certStatusType;
-
- switch (src->certStatusType) {
- case ocspCertStatus_good:
- dest->certStatusInfo.goodInfo =
- SECITEM_ArenaDupItem(arena, src->certStatusInfo.goodInfo);
- if (dest->certStatusInfo.goodInfo != NULL) {
- rv = SECSuccess;
- }
- break;
- case ocspCertStatus_revoked:
- rv = ocsp_CopyRevokedInfo(arena, dest,
- src->certStatusInfo.revokedInfo);
- break;
- case ocspCertStatus_unknown:
- dest->certStatusInfo.unknownInfo =
- SECITEM_ArenaDupItem(arena, src->certStatusInfo.unknownInfo);
- if (dest->certStatusInfo.unknownInfo != NULL) {
- rv = SECSuccess;
- }
- break;
- case ocspCertStatus_other:
- default:
- PORT_Assert(src->certStatusType == ocspCertStatus_other);
- dest->certStatusInfo.otherInfo =
- SECITEM_ArenaDupItem(arena, src->certStatusInfo.otherInfo);
- if (dest->certStatusInfo.otherInfo != NULL) {
- rv = SECSuccess;
- }
- break;
- }
- return rv;
-}
-
-static void
-ocsp_AddCacheItemToLinkedList(OCSPCacheData *cache, OCSPCacheItem *new_most_recent)
-{
- PR_EnterMonitor(OCSP_Global.monitor);
-
- if (!cache->LRUitem) {
- cache->LRUitem = new_most_recent;
- }
- new_most_recent->lessRecent = cache->MRUitem;
- new_most_recent->moreRecent = NULL;
-
- if (cache->MRUitem) {
- cache->MRUitem->moreRecent = new_most_recent;
- }
- cache->MRUitem = new_most_recent;
-
- PR_ExitMonitor(OCSP_Global.monitor);
-}
-
-static void
-ocsp_RemoveCacheItemFromLinkedList(OCSPCacheData *cache, OCSPCacheItem *item)
-{
- PR_EnterMonitor(OCSP_Global.monitor);
-
- if (!item->lessRecent && !item->moreRecent) {
- /*
- * Fail gracefully on attempts to remove an item from the list,
- * which is currently not part of the list.
- * But check for the edge case it is the single entry in the list.
- */
- if (item == cache->LRUitem &&
- item == cache->MRUitem) {
- /* remove the single entry */
- PORT_Assert(cache->numberOfEntries == 1);
- PORT_Assert(item->moreRecent == NULL);
- cache->MRUitem = NULL;
- cache->LRUitem = NULL;
- }
- PR_ExitMonitor(OCSP_Global.monitor);
- return;
- }
-
- PORT_Assert(cache->numberOfEntries > 1);
-
- if (item == cache->LRUitem) {
- PORT_Assert(item != cache->MRUitem);
- PORT_Assert(item->lessRecent == NULL);
- PORT_Assert(item->moreRecent != NULL);
- PORT_Assert(item->moreRecent->lessRecent == item);
- cache->LRUitem = item->moreRecent;
- cache->LRUitem->lessRecent = NULL;
- }
- else if (item == cache->MRUitem) {
- PORT_Assert(item->moreRecent == NULL);
- PORT_Assert(item->lessRecent != NULL);
- PORT_Assert(item->lessRecent->moreRecent == item);
- cache->MRUitem = item->lessRecent;
- cache->MRUitem->moreRecent = NULL;
- } else {
- /* remove an entry in the middle of the list */
- PORT_Assert(item->moreRecent != NULL);
- PORT_Assert(item->lessRecent != NULL);
- PORT_Assert(item->lessRecent->moreRecent == item);
- PORT_Assert(item->moreRecent->lessRecent == item);
- item->moreRecent->lessRecent = item->lessRecent;
- item->lessRecent->moreRecent = item->moreRecent;
- }
-
- item->lessRecent = NULL;
- item->moreRecent = NULL;
-
- PR_ExitMonitor(OCSP_Global.monitor);
-}
-
-static void
-ocsp_MakeCacheEntryMostRecent(OCSPCacheData *cache, OCSPCacheItem *new_most_recent)
-{
- OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent THREADID %p\n",
- PR_GetCurrentThread()));
- PR_EnterMonitor(OCSP_Global.monitor);
- if (cache->MRUitem == new_most_recent) {
- OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent ALREADY MOST\n"));
- PR_ExitMonitor(OCSP_Global.monitor);
- return;
- }
- OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent NEW entry\n"));
- ocsp_RemoveCacheItemFromLinkedList(cache, new_most_recent);
- ocsp_AddCacheItemToLinkedList(cache, new_most_recent);
- PR_ExitMonitor(OCSP_Global.monitor);
-}
-
-static PRBool
-ocsp_IsCacheDisabled(void)
-{
- /*
- * maxCacheEntries == 0 means unlimited cache entries
- * maxCacheEntries < 0 means cache is disabled
- */
- PRBool retval;
- PR_EnterMonitor(OCSP_Global.monitor);
- retval = (OCSP_Global.maxCacheEntries < 0);
- PR_ExitMonitor(OCSP_Global.monitor);
- return retval;
-}
-
-static OCSPCacheItem *
-ocsp_FindCacheEntry(OCSPCacheData *cache, CERTOCSPCertID *certID)
-{
- OCSPCacheItem *found_ocsp_item = NULL;
- OCSP_TRACE(("OCSP ocsp_FindCacheEntry\n"));
- OCSP_TRACE_CERTID(certID);
- PR_EnterMonitor(OCSP_Global.monitor);
- if (ocsp_IsCacheDisabled())
- goto loser;
-
- found_ocsp_item = (OCSPCacheItem *)PL_HashTableLookup(
- cache->entries, certID);
- if (!found_ocsp_item)
- goto loser;
-
- OCSP_TRACE(("OCSP ocsp_FindCacheEntry FOUND!\n"));
- ocsp_MakeCacheEntryMostRecent(cache, found_ocsp_item);
-
-loser:
- PR_ExitMonitor(OCSP_Global.monitor);
- return found_ocsp_item;
-}
-
-static void
-ocsp_FreeCacheItem(OCSPCacheItem *item)
-{
- OCSP_TRACE(("OCSP ocsp_FreeCacheItem\n"));
- if (item->certStatusArena) {
- PORT_FreeArena(item->certStatusArena, PR_FALSE);
- }
- if (item->certID->poolp) {
- /* freeing this poolp arena will also free item */
- PORT_FreeArena(item->certID->poolp, PR_FALSE);
- }
-}
-
-static void
-ocsp_RemoveCacheItem(OCSPCacheData *cache, OCSPCacheItem *item)
-{
- /* The item we're removing could be either the least recently used item,
- * or it could be an item that couldn't get updated with newer status info
- * because of an allocation failure, or it could get removed because we're
- * cleaning up.
- */
- PRBool couldRemoveFromHashTable;
- OCSP_TRACE(("OCSP ocsp_RemoveCacheItem, THREADID %p\n", PR_GetCurrentThread()));
- PR_EnterMonitor(OCSP_Global.monitor);
-
- ocsp_RemoveCacheItemFromLinkedList(cache, item);
- couldRemoveFromHashTable = PL_HashTableRemove(cache->entries,
- item->certID);
- PORT_Assert(couldRemoveFromHashTable);
- --cache->numberOfEntries;
- ocsp_FreeCacheItem(item);
- PR_ExitMonitor(OCSP_Global.monitor);
-}
-
-static void
-ocsp_CheckCacheSize(OCSPCacheData *cache)
-{
- OCSP_TRACE(("OCSP ocsp_CheckCacheSize\n"));
- PR_EnterMonitor(OCSP_Global.monitor);
- if (OCSP_Global.maxCacheEntries > 0) {
- /* Cache is not disabled. Number of cache entries is limited.
- * The monitor ensures that maxCacheEntries remains positive.
- */
- while (cache->numberOfEntries >
- (PRUint32)OCSP_Global.maxCacheEntries) {
- ocsp_RemoveCacheItem(cache, cache->LRUitem);
- }
- }
- PR_ExitMonitor(OCSP_Global.monitor);
-}
-
-SECStatus
-CERT_ClearOCSPCache(void)
-{
- OCSP_TRACE(("OCSP CERT_ClearOCSPCache\n"));
- PR_EnterMonitor(OCSP_Global.monitor);
- while (OCSP_Global.cache.numberOfEntries > 0) {
- ocsp_RemoveCacheItem(&OCSP_Global.cache,
- OCSP_Global.cache.LRUitem);
- }
- PR_ExitMonitor(OCSP_Global.monitor);
- return SECSuccess;
-}
-
-static SECStatus
-ocsp_CreateCacheItemAndConsumeCertID(OCSPCacheData *cache,
- CERTOCSPCertID *certID,
- OCSPCacheItem **pCacheItem)
-{
- PRArenaPool *arena;
- void *mark;
- PLHashEntry *new_hash_entry;
- OCSPCacheItem *item;
-
- PORT_Assert(pCacheItem != NULL);
- *pCacheItem = NULL;
-
- PR_EnterMonitor(OCSP_Global.monitor);
- arena = certID->poolp;
- mark = PORT_ArenaMark(arena);
-
- /* ZAlloc will init all Bools to False and all Pointers to NULL
- and all error codes to zero/good. */
- item = (OCSPCacheItem *)PORT_ArenaZAlloc(certID->poolp,
- sizeof(OCSPCacheItem));
- if (!item) {
- goto loser;
- }
- item->certID = certID;
- new_hash_entry = PL_HashTableAdd(cache->entries, item->certID,
- item);
- if (!new_hash_entry) {
- goto loser;
- }
- ++cache->numberOfEntries;
- PORT_ArenaUnmark(arena, mark);
- ocsp_AddCacheItemToLinkedList(cache, item);
- *pCacheItem = item;
-
- PR_ExitMonitor(OCSP_Global.monitor);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(arena, mark);
- PR_ExitMonitor(OCSP_Global.monitor);
- return SECFailure;
-}
-
-static SECStatus
-ocsp_SetCacheItemResponse(OCSPCacheItem *item,
- const CERTOCSPSingleResponse *response)
-{
- if (item->certStatusArena) {
- PORT_FreeArena(item->certStatusArena, PR_FALSE);
- item->certStatusArena = NULL;
- }
- item->haveThisUpdate = item->haveNextUpdate = PR_FALSE;
- if (response) {
- SECStatus rv;
- item->certStatusArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (item->certStatusArena == NULL) {
- return SECFailure;
- }
- rv = ocsp_CopyCertStatus(item->certStatusArena, &item->certStatus,
- response->certStatus);
- if (rv != SECSuccess) {
- PORT_FreeArena(item->certStatusArena, PR_FALSE);
- item->certStatusArena = NULL;
- return rv;
- }
- item->missingResponseError = 0;
- rv = DER_GeneralizedTimeToTime(&item->thisUpdate,
- &response->thisUpdate);
- item->haveThisUpdate = (rv == SECSuccess);
- if (response->nextUpdate) {
- rv = DER_GeneralizedTimeToTime(&item->nextUpdate,
- response->nextUpdate);
- item->haveNextUpdate = (rv == SECSuccess);
- } else {
- item->haveNextUpdate = PR_FALSE;
- }
- }
- return SECSuccess;
-}
-
-static void
-ocsp_FreshenCacheItemNextFetchAttemptTime(OCSPCacheItem *cacheItem)
-{
- PRTime now;
- PRTime earliestAllowedNextFetchAttemptTime;
- PRTime latestTimeWhenResponseIsConsideredFresh;
-
- OCSP_TRACE(("OCSP ocsp_FreshenCacheItemNextFetchAttemptTime\n"));
-
- PR_EnterMonitor(OCSP_Global.monitor);
-
- now = PR_Now();
- OCSP_TRACE_TIME("now:", now);
-
- if (cacheItem->haveThisUpdate) {
- OCSP_TRACE_TIME("thisUpdate:", cacheItem->thisUpdate);
- latestTimeWhenResponseIsConsideredFresh = cacheItem->thisUpdate +
- OCSP_Global.maximumSecondsToNextFetchAttempt *
- MICROSECONDS_PER_SECOND;
- OCSP_TRACE_TIME("latestTimeWhenResponseIsConsideredFresh:",
- latestTimeWhenResponseIsConsideredFresh);
- } else {
- latestTimeWhenResponseIsConsideredFresh = now +
- OCSP_Global.minimumSecondsToNextFetchAttempt *
- MICROSECONDS_PER_SECOND;
- OCSP_TRACE_TIME("no thisUpdate, "
- "latestTimeWhenResponseIsConsideredFresh:",
- latestTimeWhenResponseIsConsideredFresh);
- }
-
- if (cacheItem->haveNextUpdate) {
- OCSP_TRACE_TIME("have nextUpdate:", cacheItem->nextUpdate);
- }
-
- if (cacheItem->haveNextUpdate &&
- cacheItem->nextUpdate < latestTimeWhenResponseIsConsideredFresh) {
- latestTimeWhenResponseIsConsideredFresh = cacheItem->nextUpdate;
- OCSP_TRACE_TIME("nextUpdate is smaller than latestFresh, setting "
- "latestTimeWhenResponseIsConsideredFresh:",
- latestTimeWhenResponseIsConsideredFresh);
- }
-
- earliestAllowedNextFetchAttemptTime = now +
- OCSP_Global.minimumSecondsToNextFetchAttempt *
- MICROSECONDS_PER_SECOND;
- OCSP_TRACE_TIME("earliestAllowedNextFetchAttemptTime:",
- earliestAllowedNextFetchAttemptTime);
-
- if (latestTimeWhenResponseIsConsideredFresh <
- earliestAllowedNextFetchAttemptTime) {
- latestTimeWhenResponseIsConsideredFresh =
- earliestAllowedNextFetchAttemptTime;
- OCSP_TRACE_TIME("latest < earliest, setting latest to:",
- latestTimeWhenResponseIsConsideredFresh);
- }
-
- cacheItem->nextFetchAttemptTime =
- latestTimeWhenResponseIsConsideredFresh;
- OCSP_TRACE_TIME("nextFetchAttemptTime",
- latestTimeWhenResponseIsConsideredFresh);
-
- PR_ExitMonitor(OCSP_Global.monitor);
-}
-
-static PRBool
-ocsp_IsCacheItemFresh(OCSPCacheItem *cacheItem)
-{
- PRTime now;
- PRBool retval;
-
- PR_EnterMonitor(OCSP_Global.monitor);
- now = PR_Now();
- retval = (cacheItem->nextFetchAttemptTime > now);
- OCSP_TRACE(("OCSP ocsp_IsCacheItemFresh: %d\n", retval));
- PR_ExitMonitor(OCSP_Global.monitor);
- return retval;
-}
-
-/*
- * Status in *certIDWasConsumed will always be correct, regardless of
- * return value.
- * If the caller is unable to transfer ownership of certID,
- * then the caller must set certIDWasConsumed to NULL,
- * and this function will potentially duplicate the certID object.
- */
-static SECStatus
-ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache,
- CERTOCSPCertID *certID,
- CERTOCSPSingleResponse *single,
- PRBool *certIDWasConsumed)
-{
- SECStatus rv;
- OCSPCacheItem *cacheItem;
- OCSP_TRACE(("OCSP ocsp_CreateOrUpdateCacheEntry\n"));
-
- if (certIDWasConsumed)
- *certIDWasConsumed = PR_FALSE;
-
- PR_EnterMonitor(OCSP_Global.monitor);
- PORT_Assert(OCSP_Global.maxCacheEntries >= 0);
-
- cacheItem = ocsp_FindCacheEntry(cache, certID);
- if (!cacheItem) {
- CERTOCSPCertID *myCertID;
- if (certIDWasConsumed) {
- myCertID = certID;
- *certIDWasConsumed = PR_TRUE;
- } else {
- myCertID = cert_DupOCSPCertID(certID);
- if (!myCertID) {
- PR_ExitMonitor(OCSP_Global.monitor);
- PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
- return SECFailure;
- }
- }
-
- rv = ocsp_CreateCacheItemAndConsumeCertID(cache, myCertID,
- &cacheItem);
- if (rv != SECSuccess) {
- PR_ExitMonitor(OCSP_Global.monitor);
- return rv;
- }
- }
- if (single) {
- PRTime thisUpdate;
- rv = DER_GeneralizedTimeToTime(&thisUpdate, &single->thisUpdate);
-
- if (!cacheItem->haveThisUpdate ||
- (rv == SECSuccess && cacheItem->thisUpdate < thisUpdate)) {
- rv = ocsp_SetCacheItemResponse(cacheItem, single);
- if (rv != SECSuccess) {
- ocsp_RemoveCacheItem(cache, cacheItem);
- PR_ExitMonitor(OCSP_Global.monitor);
- return rv;
- }
- } else {
- OCSP_TRACE(("Not caching response because the response is not newer than the cache"));
- }
- } else {
- cacheItem->missingResponseError = PORT_GetError();
- if (cacheItem->certStatusArena) {
- PORT_FreeArena(cacheItem->certStatusArena, PR_FALSE);
- cacheItem->certStatusArena = NULL;
- }
- }
- ocsp_FreshenCacheItemNextFetchAttemptTime(cacheItem);
- ocsp_CheckCacheSize(cache);
-
- PR_ExitMonitor(OCSP_Global.monitor);
- return SECSuccess;
-}
-
-extern SECStatus
-CERT_SetOCSPFailureMode(SEC_OcspFailureMode ocspFailureMode)
-{
- switch (ocspFailureMode) {
- case ocspMode_FailureIsVerificationFailure:
- case ocspMode_FailureIsNotAVerificationFailure:
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- PR_EnterMonitor(OCSP_Global.monitor);
- OCSP_Global.ocspFailureMode = ocspFailureMode;
- PR_ExitMonitor(OCSP_Global.monitor);
- return SECSuccess;
-}
-
-SECStatus
-CERT_OCSPCacheSettings(PRInt32 maxCacheEntries,
- PRUint32 minimumSecondsToNextFetchAttempt,
- PRUint32 maximumSecondsToNextFetchAttempt)
-{
- if (minimumSecondsToNextFetchAttempt > maximumSecondsToNextFetchAttempt
- || maxCacheEntries < -1) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- PR_EnterMonitor(OCSP_Global.monitor);
-
- if (maxCacheEntries < 0) {
- OCSP_Global.maxCacheEntries = -1; /* disable cache */
- } else if (maxCacheEntries == 0) {
- OCSP_Global.maxCacheEntries = 0; /* unlimited cache entries */
- } else {
- OCSP_Global.maxCacheEntries = maxCacheEntries;
- }
-
- if (minimumSecondsToNextFetchAttempt <
- OCSP_Global.minimumSecondsToNextFetchAttempt
- || maximumSecondsToNextFetchAttempt <
- OCSP_Global.maximumSecondsToNextFetchAttempt) {
- /*
- * Ensure our existing cache entries are not used longer than the
- * new settings allow, we're lazy and just clear the cache
- */
- CERT_ClearOCSPCache();
- }
-
- OCSP_Global.minimumSecondsToNextFetchAttempt =
- minimumSecondsToNextFetchAttempt;
- OCSP_Global.maximumSecondsToNextFetchAttempt =
- maximumSecondsToNextFetchAttempt;
- ocsp_CheckCacheSize(&OCSP_Global.cache);
-
- PR_ExitMonitor(OCSP_Global.monitor);
- return SECSuccess;
-}
-
-SECStatus
-CERT_SetOCSPTimeout(PRUint32 seconds)
-{
- /* no locking, see bug 406120 */
- OCSP_Global.timeoutSeconds = seconds;
- return SECSuccess;
-}
-
-/* this function is called at NSS initialization time */
-SECStatus OCSP_InitGlobal(void)
-{
- SECStatus rv = SECFailure;
-
- if (OCSP_Global.monitor == NULL) {
- OCSP_Global.monitor = PR_NewMonitor();
- }
- if (!OCSP_Global.monitor)
- return SECFailure;
-
- PR_EnterMonitor(OCSP_Global.monitor);
- if (!OCSP_Global.cache.entries) {
- OCSP_Global.cache.entries =
- PL_NewHashTable(0,
- ocsp_CacheKeyHashFunction,
- ocsp_CacheKeyCompareFunction,
- PL_CompareValues,
- NULL,
- NULL);
- OCSP_Global.ocspFailureMode = ocspMode_FailureIsVerificationFailure;
- OCSP_Global.cache.numberOfEntries = 0;
- OCSP_Global.cache.MRUitem = NULL;
- OCSP_Global.cache.LRUitem = NULL;
- } else {
- /*
- * NSS might call this function twice while attempting to init.
- * But it's not allowed to call this again after any activity.
- */
- PORT_Assert(OCSP_Global.cache.numberOfEntries == 0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- }
- if (OCSP_Global.cache.entries)
- rv = SECSuccess;
- PR_ExitMonitor(OCSP_Global.monitor);
- return rv;
-}
-
-SECStatus OCSP_ShutdownGlobal(void)
-{
- if (!OCSP_Global.monitor)
- return SECSuccess;
-
- PR_EnterMonitor(OCSP_Global.monitor);
- if (OCSP_Global.cache.entries) {
- CERT_ClearOCSPCache();
- PL_HashTableDestroy(OCSP_Global.cache.entries);
- OCSP_Global.cache.entries = NULL;
- }
- PORT_Assert(OCSP_Global.cache.numberOfEntries == 0);
- OCSP_Global.cache.MRUitem = NULL;
- OCSP_Global.cache.LRUitem = NULL;
-
- OCSP_Global.defaultHttpClientFcn = NULL;
- OCSP_Global.maxCacheEntries = DEFAULT_OCSP_CACHE_SIZE;
- OCSP_Global.minimumSecondsToNextFetchAttempt =
- DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
- OCSP_Global.maximumSecondsToNextFetchAttempt =
- DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
- OCSP_Global.ocspFailureMode =
- ocspMode_FailureIsVerificationFailure;
- PR_ExitMonitor(OCSP_Global.monitor);
-
- PR_DestroyMonitor(OCSP_Global.monitor);
- OCSP_Global.monitor = NULL;
- return SECSuccess;
-}
-
-/*
- * A return value of NULL means:
- * The application did not register it's own HTTP client.
- */
-const SEC_HttpClientFcn *SEC_GetRegisteredHttpClient(void)
-{
- const SEC_HttpClientFcn *retval;
-
- if (!OCSP_Global.monitor) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return NULL;
- }
-
- PR_EnterMonitor(OCSP_Global.monitor);
- retval = OCSP_Global.defaultHttpClientFcn;
- PR_ExitMonitor(OCSP_Global.monitor);
-
- return retval;
-}
-
-/*
- * The following structure is only used internally. It is allocated when
- * someone turns on OCSP checking, and hangs off of the status-configuration
- * structure in the certdb structure. We use it to keep configuration
- * information specific to OCSP checking.
- */
-typedef struct ocspCheckingContextStr {
- PRBool useDefaultResponder;
- char *defaultResponderURI;
- char *defaultResponderNickname;
- CERTCertificate *defaultResponderCert;
-} ocspCheckingContext;
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(SEC_IntegerTemplate)
-SEC_ASN1_MKSUB(SEC_NullTemplate)
-SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
-SEC_ASN1_MKSUB(SEC_PointerToAnyTemplate)
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(SEC_SequenceOfAnyTemplate)
-SEC_ASN1_MKSUB(SEC_PointerToGeneralizedTimeTemplate)
-SEC_ASN1_MKSUB(SEC_PointerToEnumeratedTemplate)
-
-/*
- * Forward declarations of sub-types, so I can lay out the types in the
- * same order as the ASN.1 is laid out in the OCSP spec itself.
- *
- * These are in alphabetical order (case-insensitive); please keep it that way!
- */
-extern const SEC_ASN1Template ocsp_CertIDTemplate[];
-extern const SEC_ASN1Template ocsp_PointerToSignatureTemplate[];
-extern const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[];
-extern const SEC_ASN1Template ocsp_ResponseDataTemplate[];
-extern const SEC_ASN1Template ocsp_RevokedInfoTemplate[];
-extern const SEC_ASN1Template ocsp_SingleRequestTemplate[];
-extern const SEC_ASN1Template ocsp_SingleResponseTemplate[];
-extern const SEC_ASN1Template ocsp_TBSRequestTemplate[];
-
-
-/*
- * Request-related templates...
- */
-
-/*
- * OCSPRequest ::= SEQUENCE {
- * tbsRequest TBSRequest,
- * optionalSignature [0] EXPLICIT Signature OPTIONAL }
- */
-static const SEC_ASN1Template ocsp_OCSPRequestTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPRequest) },
- { SEC_ASN1_POINTER,
- offsetof(CERTOCSPRequest, tbsRequest),
- ocsp_TBSRequestTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(CERTOCSPRequest, optionalSignature),
- ocsp_PointerToSignatureTemplate },
- { 0 }
-};
-
-/*
- * TBSRequest ::= SEQUENCE {
- * version [0] EXPLICIT Version DEFAULT v1,
- * requestorName [1] EXPLICIT GeneralName OPTIONAL,
- * requestList SEQUENCE OF Request,
- * requestExtensions [2] EXPLICIT Extensions OPTIONAL }
- *
- * Version ::= INTEGER { v1(0) }
- *
- * Note: this should be static but the AIX compiler doesn't like it (because it
- * was forward-declared above); it is not meant to be exported, but this
- * is the only way it will compile.
- */
-const SEC_ASN1Template ocsp_TBSRequestTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspTBSRequest) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(ocspTBSRequest, version),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- offsetof(ocspTBSRequest, derRequestorName),
- SEC_ASN1_SUB(SEC_PointerToAnyTemplate) },
- { SEC_ASN1_SEQUENCE_OF,
- offsetof(ocspTBSRequest, requestList),
- ocsp_SingleRequestTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
- offsetof(ocspTBSRequest, requestExtensions),
- CERT_SequenceOfCertExtensionTemplate },
- { 0 }
-};
-
-/*
- * Signature ::= SEQUENCE {
- * signatureAlgorithm AlgorithmIdentifier,
- * signature BIT STRING,
- * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
- */
-static const SEC_ASN1Template ocsp_SignatureTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspSignature) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(ocspSignature, signatureAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_BIT_STRING,
- offsetof(ocspSignature, signature) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(ocspSignature, derCerts),
- SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) },
- { 0 }
-};
-
-/*
- * This template is just an extra level to use in an explicitly-tagged
- * reference to a Signature.
- *
- * Note: this should be static but the AIX compiler doesn't like it (because it
- * was forward-declared above); it is not meant to be exported, but this
- * is the only way it will compile.
- */
-const SEC_ASN1Template ocsp_PointerToSignatureTemplate[] = {
- { SEC_ASN1_POINTER, 0, ocsp_SignatureTemplate }
-};
-
-/*
- * Request ::= SEQUENCE {
- * reqCert CertID,
- * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
- *
- * Note: this should be static but the AIX compiler doesn't like it (because it
- * was forward-declared above); it is not meant to be exported, but this
- * is the only way it will compile.
- */
-const SEC_ASN1Template ocsp_SingleRequestTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspSingleRequest) },
- { SEC_ASN1_POINTER,
- offsetof(ocspSingleRequest, reqCert),
- ocsp_CertIDTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(ocspSingleRequest, singleRequestExtensions),
- CERT_SequenceOfCertExtensionTemplate },
- { 0 }
-};
-
-
-/*
- * This data structure and template (CertID) is used by both OCSP
- * requests and responses. It is the only one that is shared.
- *
- * CertID ::= SEQUENCE {
- * hashAlgorithm AlgorithmIdentifier,
- * issuerNameHash OCTET STRING, -- Hash of Issuer DN
- * issuerKeyHash OCTET STRING, -- Hash of Issuer public key
- * serialNumber CertificateSerialNumber }
- *
- * CertificateSerialNumber ::= INTEGER
- *
- * Note: this should be static but the AIX compiler doesn't like it (because it
- * was forward-declared above); it is not meant to be exported, but this
- * is the only way it will compile.
- */
-const SEC_ASN1Template ocsp_CertIDTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPCertID) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTOCSPCertID, hashAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(CERTOCSPCertID, issuerNameHash) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(CERTOCSPCertID, issuerKeyHash) },
- { SEC_ASN1_INTEGER,
- offsetof(CERTOCSPCertID, serialNumber) },
- { 0 }
-};
-
-
-/*
- * Response-related templates...
- */
-
-/*
- * OCSPResponse ::= SEQUENCE {
- * responseStatus OCSPResponseStatus,
- * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
- */
-const SEC_ASN1Template ocsp_OCSPResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPResponse) },
- { SEC_ASN1_ENUMERATED,
- offsetof(CERTOCSPResponse, responseStatus) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(CERTOCSPResponse, responseBytes),
- ocsp_PointerToResponseBytesTemplate },
- { 0 }
-};
-
-/*
- * ResponseBytes ::= SEQUENCE {
- * responseType OBJECT IDENTIFIER,
- * response OCTET STRING }
- */
-const SEC_ASN1Template ocsp_ResponseBytesTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspResponseBytes) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(ocspResponseBytes, responseType) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(ocspResponseBytes, response) },
- { 0 }
-};
-
-/*
- * This template is just an extra level to use in an explicitly-tagged
- * reference to a ResponseBytes.
- *
- * Note: this should be static but the AIX compiler doesn't like it (because it
- * was forward-declared above); it is not meant to be exported, but this
- * is the only way it will compile.
- */
-const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[] = {
- { SEC_ASN1_POINTER, 0, ocsp_ResponseBytesTemplate }
-};
-
-/*
- * BasicOCSPResponse ::= SEQUENCE {
- * tbsResponseData ResponseData,
- * signatureAlgorithm AlgorithmIdentifier,
- * signature BIT STRING,
- * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
- */
-static const SEC_ASN1Template ocsp_BasicOCSPResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspBasicOCSPResponse) },
- { SEC_ASN1_ANY | SEC_ASN1_SAVE,
- offsetof(ocspBasicOCSPResponse, tbsResponseDataDER) },
- { SEC_ASN1_POINTER,
- offsetof(ocspBasicOCSPResponse, tbsResponseData),
- ocsp_ResponseDataTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_BIT_STRING,
- offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
- SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) },
- { 0 }
-};
-
-/*
- * ResponseData ::= SEQUENCE {
- * version [0] EXPLICIT Version DEFAULT v1,
- * responderID ResponderID,
- * producedAt GeneralizedTime,
- * responses SEQUENCE OF SingleResponse,
- * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
- *
- * Note: this should be static but the AIX compiler doesn't like it (because it
- * was forward-declared above); it is not meant to be exported, but this
- * is the only way it will compile.
- */
-const SEC_ASN1Template ocsp_ResponseDataTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspResponseData) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(ocspResponseData, version),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { SEC_ASN1_ANY,
- offsetof(ocspResponseData, derResponderID) },
- { SEC_ASN1_GENERALIZED_TIME,
- offsetof(ocspResponseData, producedAt) },
- { SEC_ASN1_SEQUENCE_OF,
- offsetof(ocspResponseData, responses),
- ocsp_SingleResponseTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(ocspResponseData, responseExtensions),
- CERT_SequenceOfCertExtensionTemplate },
- { 0 }
-};
-
-/*
- * ResponderID ::= CHOICE {
- * byName [1] EXPLICIT Name,
- * byKey [2] EXPLICIT KeyHash }
- *
- * KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
- * (excluding the tag and length fields)
- *
- * XXX Because the ASN.1 encoder and decoder currently do not provide
- * a way to automatically handle a CHOICE, we need to do it in two
- * steps, looking at the type tag and feeding the exact choice back
- * to the ASN.1 code. Hopefully that will change someday and this
- * can all be simplified down into a single template. Anyway, for
- * now we list each choice as its own template:
- */
-const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[] = {
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(ocspResponderID, responderIDValue.name),
- CERT_NameTemplate }
-};
-const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[] = {
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 2,
- offsetof(ocspResponderID, responderIDValue.keyHash),
- SEC_ASN1_SUB(SEC_OctetStringTemplate) }
-};
-static const SEC_ASN1Template ocsp_ResponderIDOtherTemplate[] = {
- { SEC_ASN1_ANY,
- offsetof(ocspResponderID, responderIDValue.other) }
-};
-
-/* Decode choice container, but leave x509 name object encoded */
-static const SEC_ASN1Template ocsp_ResponderIDDerNameTemplate[] = {
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1, 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
-};
-
-/*
- * SingleResponse ::= SEQUENCE {
- * certID CertID,
- * certStatus CertStatus,
- * thisUpdate GeneralizedTime,
- * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
- * singleExtensions [1] EXPLICIT Extensions OPTIONAL }
- *
- * Note: this should be static but the AIX compiler doesn't like it (because it
- * was forward-declared above); it is not meant to be exported, but this
- * is the only way it will compile.
- */
-const SEC_ASN1Template ocsp_SingleResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPSingleResponse) },
- { SEC_ASN1_POINTER,
- offsetof(CERTOCSPSingleResponse, certID),
- ocsp_CertIDTemplate },
- { SEC_ASN1_ANY,
- offsetof(CERTOCSPSingleResponse, derCertStatus) },
- { SEC_ASN1_GENERALIZED_TIME,
- offsetof(CERTOCSPSingleResponse, thisUpdate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(CERTOCSPSingleResponse, nextUpdate),
- SEC_ASN1_SUB(SEC_PointerToGeneralizedTimeTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(CERTOCSPSingleResponse, singleExtensions),
- CERT_SequenceOfCertExtensionTemplate },
- { 0 }
-};
-
-/*
- * CertStatus ::= CHOICE {
- * good [0] IMPLICIT NULL,
- * revoked [1] IMPLICIT RevokedInfo,
- * unknown [2] IMPLICIT UnknownInfo }
- *
- * Because the ASN.1 encoder and decoder currently do not provide
- * a way to automatically handle a CHOICE, we need to do it in two
- * steps, looking at the type tag and feeding the exact choice back
- * to the ASN.1 code. Hopefully that will change someday and this
- * can all be simplified down into a single template. Anyway, for
- * now we list each choice as its own template:
- */
-static const SEC_ASN1Template ocsp_CertStatusGoodTemplate[] = {
- { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(ocspCertStatus, certStatusInfo.goodInfo),
- SEC_ASN1_SUB(SEC_NullTemplate) }
-};
-static const SEC_ASN1Template ocsp_CertStatusRevokedTemplate[] = {
- { SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
- ocsp_RevokedInfoTemplate }
-};
-static const SEC_ASN1Template ocsp_CertStatusUnknownTemplate[] = {
- { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
- offsetof(ocspCertStatus, certStatusInfo.unknownInfo),
- SEC_ASN1_SUB(SEC_NullTemplate) }
-};
-static const SEC_ASN1Template ocsp_CertStatusOtherTemplate[] = {
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(ocspCertStatus, certStatusInfo.otherInfo),
- SEC_ASN1_SUB(SEC_AnyTemplate) }
-};
-
-/*
- * RevokedInfo ::= SEQUENCE {
- * revocationTime GeneralizedTime,
- * revocationReason [0] EXPLICIT CRLReason OPTIONAL }
- *
- * Note: this should be static but the AIX compiler doesn't like it (because it
- * was forward-declared above); it is not meant to be exported, but this
- * is the only way it will compile.
- */
-const SEC_ASN1Template ocsp_RevokedInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspRevokedInfo) },
- { SEC_ASN1_GENERALIZED_TIME,
- offsetof(ocspRevokedInfo, revocationTime) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 0,
- offsetof(ocspRevokedInfo, revocationReason),
- SEC_ASN1_SUB(SEC_PointerToEnumeratedTemplate) },
- { 0 }
-};
-
-
-/*
- * OCSP-specific extension templates:
- */
-
-/*
- * ServiceLocator ::= SEQUENCE {
- * issuer Name,
- * locator AuthorityInfoAccessSyntax OPTIONAL }
- */
-static const SEC_ASN1Template ocsp_ServiceLocatorTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspServiceLocator) },
- { SEC_ASN1_POINTER,
- offsetof(ocspServiceLocator, issuer),
- CERT_NameTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(ocspServiceLocator, locator) },
- { 0 }
-};
-
-
-/*
- * REQUEST SUPPORT FUNCTIONS (encode/create/decode/destroy):
- */
-
-/*
- * FUNCTION: CERT_EncodeOCSPRequest
- * DER encodes an OCSP Request, possibly adding a signature as well.
- * XXX Signing is not yet supported, however; see comments in code.
- * INPUTS:
- * PRArenaPool *arena
- * The return value is allocated from here.
- * If a NULL is passed in, allocation is done from the heap instead.
- * CERTOCSPRequest *request
- * The request to be encoded.
- * void *pwArg
- * Pointer to argument for password prompting, if needed. (Definitely
- * not needed if not signing.)
- * RETURN:
- * Returns a NULL on error and a pointer to the SECItem with the
- * encoded value otherwise. Any error is likely to be low-level
- * (e.g. no memory).
- */
-SECItem *
-CERT_EncodeOCSPRequest(PRArenaPool *arena, CERTOCSPRequest *request,
- void *pwArg)
-{
- ocspTBSRequest *tbsRequest;
- SECStatus rv;
-
- /* XXX All of these should generate errors if they fail. */
- PORT_Assert(request);
- PORT_Assert(request->tbsRequest);
-
- tbsRequest = request->tbsRequest;
-
- if (request->tbsRequest->extensionHandle != NULL) {
- rv = CERT_FinishExtensions(request->tbsRequest->extensionHandle);
- request->tbsRequest->extensionHandle = NULL;
- if (rv != SECSuccess)
- return NULL;
- }
-
- /*
- * XXX When signed requests are supported and request->optionalSignature
- * is not NULL:
- * - need to encode tbsRequest->requestorName
- * - need to encode tbsRequest
- * - need to sign that encoded result (using cert in sig), filling in the
- * request->optionalSignature structure with the result, the signing
- * algorithm and (perhaps?) the cert (and its chain?) in derCerts
- */
-
- return SEC_ASN1EncodeItem(arena, NULL, request, ocsp_OCSPRequestTemplate);
-}
-
-
-/*
- * FUNCTION: CERT_DecodeOCSPRequest
- * Decode a DER encoded OCSP Request.
- * INPUTS:
- * SECItem *src
- * Pointer to a SECItem holding DER encoded OCSP Request.
- * RETURN:
- * Returns a pointer to a CERTOCSPRequest containing the decoded request.
- * On error, returns NULL. Most likely error is trouble decoding
- * (SEC_ERROR_OCSP_MALFORMED_REQUEST), or low-level problem (no memory).
- */
-CERTOCSPRequest *
-CERT_DecodeOCSPRequest(const SECItem *src)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv = SECFailure;
- CERTOCSPRequest *dest = NULL;
- int i;
- SECItem newSrc;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto loser;
- }
- dest = (CERTOCSPRequest *) PORT_ArenaZAlloc(arena,
- sizeof(CERTOCSPRequest));
- if (dest == NULL) {
- goto loser;
- }
- dest->arena = arena;
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newSrc, src);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, dest, ocsp_OCSPRequestTemplate, &newSrc);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_BAD_DER)
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
- goto loser;
- }
-
- /*
- * XXX I would like to find a way to get rid of the necessity
- * of doing this copying of the arena pointer.
- */
- for (i = 0; dest->tbsRequest->requestList[i] != NULL; i++) {
- dest->tbsRequest->requestList[i]->arena = arena;
- }
-
- return dest;
-
-loser:
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return NULL;
-}
-
-SECStatus
-CERT_DestroyOCSPCertID(CERTOCSPCertID* certID)
-{
- if (certID && certID->poolp) {
- PORT_FreeArena(certID->poolp, PR_FALSE);
- return SECSuccess;
- }
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
-}
-
-/*
- * Digest data using the specified algorithm.
- * The necessary storage for the digest data is allocated. If "fill" is
- * non-null, the data is put there, otherwise a SECItem is allocated.
- * Allocation from "arena" if it is non-null, heap otherwise. Any problem
- * results in a NULL being returned (and an appropriate error set).
- */
-
-SECItem *
-ocsp_DigestValue(PRArenaPool *arena, SECOidTag digestAlg,
- SECItem *fill, const SECItem *src)
-{
- const SECHashObject *digestObject;
- SECItem *result = NULL;
- void *mark = NULL;
- void *digestBuff = NULL;
-
- if ( arena != NULL ) {
- mark = PORT_ArenaMark(arena);
- }
-
- digestObject = HASH_GetHashObjectByOidTag(digestAlg);
- if ( digestObject == NULL ) {
- goto loser;
- }
-
- if (fill == NULL || fill->data == NULL) {
- result = SECITEM_AllocItem(arena, fill, digestObject->length);
- if ( result == NULL ) {
- goto loser;
- }
- digestBuff = result->data;
- } else {
- if (fill->len < digestObject->length) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
- }
- digestBuff = fill->data;
- }
-
- if (PK11_HashBuf(digestAlg, digestBuff,
- src->data, src->len) != SECSuccess) {
- goto loser;
- }
-
- if ( arena != NULL ) {
- PORT_ArenaUnmark(arena, mark);
- }
-
- if (result == NULL) {
- result = fill;
- }
- return result;
-
-loser:
- if (arena != NULL) {
- PORT_ArenaRelease(arena, mark);
- } else {
- if (result != NULL) {
- SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE);
- }
- }
- return(NULL);
-}
-
-/*
- * Digest the cert's subject public key using the specified algorithm.
- * The necessary storage for the digest data is allocated. If "fill" is
- * non-null, the data is put there, otherwise a SECItem is allocated.
- * Allocation from "arena" if it is non-null, heap otherwise. Any problem
- * results in a NULL being returned (and an appropriate error set).
- */
-SECItem *
-CERT_GetSPKIDigest(PRArenaPool *arena, const CERTCertificate *cert,
- SECOidTag digestAlg, SECItem *fill)
-{
- SECItem spk;
-
- /*
- * Copy just the length and data pointer (nothing needs to be freed)
- * of the subject public key so we can convert the length from bits
- * to bytes, which is what the digest function expects.
- */
- spk = cert->subjectPublicKeyInfo.subjectPublicKey;
- DER_ConvertBitString(&spk);
-
- return ocsp_DigestValue(arena, digestAlg, fill, &spk);
-}
-
-/*
- * Digest the cert's subject name using the specified algorithm.
- */
-static SECItem *
-cert_GetSubjectNameDigest(PRArenaPool *arena, const CERTCertificate *cert,
- SECOidTag digestAlg, SECItem *fill)
-{
- SECItem name;
-
- /*
- * Copy just the length and data pointer (nothing needs to be freed)
- * of the subject name
- */
- name = cert->derSubject;
-
- return ocsp_DigestValue(arena, digestAlg, fill, &name);
-}
-
-/*
- * Create and fill-in a CertID. This function fills in the hash values
- * (issuerNameHash and issuerKeyHash), and is hardwired to use SHA1.
- * Someday it might need to be more flexible about hash algorithm, but
- * for now we have no intention/need to create anything else.
- *
- * Error causes a null to be returned; most likely cause is trouble
- * finding the certificate issuer (SEC_ERROR_UNKNOWN_ISSUER).
- * Other errors are low-level problems (no memory, bad database, etc.).
- */
-static CERTOCSPCertID *
-ocsp_CreateCertID(PRArenaPool *arena, CERTCertificate *cert, int64 time)
-{
- CERTOCSPCertID *certID;
- CERTCertificate *issuerCert = NULL;
- void *mark = PORT_ArenaMark(arena);
- SECStatus rv;
-
- PORT_Assert(arena != NULL);
-
- certID = PORT_ArenaZNew(arena, CERTOCSPCertID);
- if (certID == NULL) {
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(arena, &certID->hashAlgorithm, SEC_OID_SHA1,
- NULL);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
- if (issuerCert == NULL) {
- goto loser;
- }
-
- if (cert_GetSubjectNameDigest(arena, issuerCert, SEC_OID_SHA1,
- &(certID->issuerNameHash)) == NULL) {
- goto loser;
- }
- certID->issuerSHA1NameHash.data = certID->issuerNameHash.data;
- certID->issuerSHA1NameHash.len = certID->issuerNameHash.len;
-
- if (cert_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD5,
- &(certID->issuerMD5NameHash)) == NULL) {
- goto loser;
- }
-
- if (cert_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD2,
- &(certID->issuerMD2NameHash)) == NULL) {
- goto loser;
- }
-
- if (CERT_GetSPKIDigest(arena, issuerCert, SEC_OID_SHA1,
- &(certID->issuerKeyHash)) == NULL) {
- goto loser;
- }
- certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data;
- certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len;
- /* cache the other two hash algorithms as well */
- if (CERT_GetSPKIDigest(arena, issuerCert, SEC_OID_MD5,
- &(certID->issuerMD5KeyHash)) == NULL) {
- goto loser;
- }
- if (CERT_GetSPKIDigest(arena, issuerCert, SEC_OID_MD2,
- &(certID->issuerMD2KeyHash)) == NULL) {
- goto loser;
- }
-
-
- /* now we are done with issuerCert */
- CERT_DestroyCertificate(issuerCert);
- issuerCert = NULL;
-
- rv = SECITEM_CopyItem(arena, &certID->serialNumber, &cert->serialNumber);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- PORT_ArenaUnmark(arena, mark);
- return certID;
-
-loser:
- if (issuerCert != NULL) {
- CERT_DestroyCertificate(issuerCert);
- }
- PORT_ArenaRelease(arena, mark);
- return NULL;
-}
-
-CERTOCSPCertID*
-CERT_CreateOCSPCertID(CERTCertificate *cert, int64 time)
-{
- PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- CERTOCSPCertID *certID;
- PORT_Assert(arena != NULL);
- if (!arena)
- return NULL;
-
- certID = ocsp_CreateCertID(arena, cert, time);
- if (!certID) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
- certID->poolp = arena;
- return certID;
-}
-
-static CERTOCSPCertID *
-cert_DupOCSPCertID(CERTOCSPCertID *src)
-{
- CERTOCSPCertID *dest;
- PRArenaPool *arena = NULL;
-
- if (!src) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena)
- goto loser;
-
- dest = PORT_ArenaZNew(arena, CERTOCSPCertID);
- if (!dest)
- goto loser;
-
-#define DUPHELP(element) \
- if (src->element.data) { \
- if (SECITEM_CopyItem(arena, &dest->element, &src->element) \
- != SECSuccess) \
- goto loser; \
- }
-
- DUPHELP(hashAlgorithm.algorithm)
- DUPHELP(hashAlgorithm.parameters)
- DUPHELP(issuerNameHash)
- DUPHELP(issuerKeyHash)
- DUPHELP(serialNumber)
- DUPHELP(issuerSHA1NameHash)
- DUPHELP(issuerMD5NameHash)
- DUPHELP(issuerMD2NameHash)
- DUPHELP(issuerSHA1KeyHash)
- DUPHELP(issuerMD5KeyHash)
- DUPHELP(issuerMD2KeyHash)
-
- dest->poolp = arena;
- return dest;
-
-loser:
- if (arena)
- PORT_FreeArena(arena, PR_FALSE);
- PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
- return NULL;
-}
-
-/*
- * Callback to set Extensions in request object
- */
-void SetSingleReqExts(void *object, CERTCertExtension **exts)
-{
- ocspSingleRequest *singleRequest =
- (ocspSingleRequest *)object;
-
- singleRequest->singleRequestExtensions = exts;
-}
-
-/*
- * Add the Service Locator extension to the singleRequestExtensions
- * for the given singleRequest.
- *
- * All errors are internal or low-level problems (e.g. no memory).
- */
-static SECStatus
-ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest,
- CERTCertificate *cert)
-{
- ocspServiceLocator *serviceLocator = NULL;
- void *extensionHandle = NULL;
- SECStatus rv = SECFailure;
-
- serviceLocator = PORT_ZNew(ocspServiceLocator);
- if (serviceLocator == NULL)
- goto loser;
-
- /*
- * Normally it would be a bad idea to do a direct reference like
- * this rather than allocate and copy the name *or* at least dup
- * a reference of the cert. But all we need is to be able to read
- * the issuer name during the encoding we are about to do, so a
- * copy is just a waste of time.
- */
- serviceLocator->issuer = &cert->issuer;
-
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
- &serviceLocator->locator);
- if (rv != SECSuccess) {
- if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
- goto loser;
- }
-
- /* prepare for following loser gotos */
- rv = SECFailure;
- PORT_SetError(0);
-
- extensionHandle = cert_StartExtensions(singleRequest,
- singleRequest->arena, SetSingleReqExts);
- if (extensionHandle == NULL)
- goto loser;
-
- rv = CERT_EncodeAndAddExtension(extensionHandle,
- SEC_OID_PKIX_OCSP_SERVICE_LOCATOR,
- serviceLocator, PR_FALSE,
- ocsp_ServiceLocatorTemplate);
-
-loser:
- if (extensionHandle != NULL) {
- /*
- * Either way we have to finish out the extension context (so it gets
- * freed). But careful not to override any already-set bad status.
- */
- SECStatus tmprv = CERT_FinishExtensions(extensionHandle);
- if (rv == SECSuccess)
- rv = tmprv;
- }
-
- /*
- * Finally, free the serviceLocator structure itself and we are done.
- */
- if (serviceLocator != NULL) {
- if (serviceLocator->locator.data != NULL)
- SECITEM_FreeItem(&serviceLocator->locator, PR_FALSE);
- PORT_Free(serviceLocator);
- }
-
- return rv;
-}
-
-/*
- * Creates an array of ocspSingleRequest based on a list of certs.
- * Note that the code which later compares the request list with the
- * response expects this array to be in the exact same order as the
- * certs are found in the list. It would be harder to change that
- * order than preserve it, but since the requirement is not obvious,
- * it deserves to be mentioned.
- *
- * Any problem causes a null return and error set:
- * SEC_ERROR_UNKNOWN_ISSUER
- * Other errors are low-level problems (no memory, bad database, etc.).
- */
-static ocspSingleRequest **
-ocsp_CreateSingleRequestList(PRArenaPool *arena, CERTCertList *certList,
- int64 time, PRBool includeLocator)
-{
- ocspSingleRequest **requestList = NULL;
- CERTCertListNode *node = NULL;
- int i, count;
- void *mark = PORT_ArenaMark(arena);
-
- node = CERT_LIST_HEAD(certList);
- for (count = 0; !CERT_LIST_END(node, certList); count++) {
- node = CERT_LIST_NEXT(node);
- }
-
- if (count == 0)
- goto loser;
-
- requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, count + 1);
- if (requestList == NULL)
- goto loser;
-
- node = CERT_LIST_HEAD(certList);
- for (i = 0; !CERT_LIST_END(node, certList); i++) {
- requestList[i] = PORT_ArenaZNew(arena, ocspSingleRequest);
- if (requestList[i] == NULL)
- goto loser;
-
- OCSP_TRACE(("OCSP CERT_CreateOCSPRequest %s\n", node->cert->subjectName));
- requestList[i]->arena = arena;
- requestList[i]->reqCert = ocsp_CreateCertID(arena, node->cert, time);
- if (requestList[i]->reqCert == NULL)
- goto loser;
-
- if (includeLocator == PR_TRUE) {
- SECStatus rv;
-
- rv = ocsp_AddServiceLocatorExtension(requestList[i], node->cert);
- if (rv != SECSuccess)
- goto loser;
- }
-
- node = CERT_LIST_NEXT(node);
- }
-
- PORT_Assert(i == count);
-
- PORT_ArenaUnmark(arena, mark);
- requestList[i] = NULL;
- return requestList;
-
-loser:
- PORT_ArenaRelease(arena, mark);
- return NULL;
-}
-
-static ocspSingleRequest **
-ocsp_CreateRequestFromCert(PRArenaPool *arena,
- CERTOCSPCertID *certID,
- CERTCertificate *singleCert,
- int64 time,
- PRBool includeLocator)
-{
- ocspSingleRequest **requestList = NULL;
- void *mark = PORT_ArenaMark(arena);
- PORT_Assert(certID != NULL && singleCert != NULL);
-
- /* meaning of value 2: one entry + one end marker */
- requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, 2);
- if (requestList == NULL)
- goto loser;
- requestList[0] = PORT_ArenaZNew(arena, ocspSingleRequest);
- if (requestList[0] == NULL)
- goto loser;
- requestList[0]->arena = arena;
- /* certID will live longer than the request */
- requestList[0]->reqCert = certID;
-
- if (includeLocator == PR_TRUE) {
- SECStatus rv;
- rv = ocsp_AddServiceLocatorExtension(requestList[0], singleCert);
- if (rv != SECSuccess)
- goto loser;
- }
-
- PORT_ArenaUnmark(arena, mark);
- requestList[1] = NULL;
- return requestList;
-
-loser:
- PORT_ArenaRelease(arena, mark);
- return NULL;
-}
-
-static CERTOCSPRequest *
-ocsp_prepareEmptyOCSPRequest(void)
-{
- PRArenaPool *arena = NULL;
- CERTOCSPRequest *request = NULL;
- ocspTBSRequest *tbsRequest = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto loser;
- }
- request = PORT_ArenaZNew(arena, CERTOCSPRequest);
- if (request == NULL) {
- goto loser;
- }
- request->arena = arena;
-
- tbsRequest = PORT_ArenaZNew(arena, ocspTBSRequest);
- if (tbsRequest == NULL) {
- goto loser;
- }
- request->tbsRequest = tbsRequest;
- /* version 1 is the default, so we need not fill in a version number */
- return request;
-
-loser:
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return NULL;
-}
-
-CERTOCSPRequest *
-cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
- CERTCertificate *singleCert,
- int64 time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert)
-{
- CERTOCSPRequest *request;
- OCSP_TRACE(("OCSP cert_CreateSingleCertOCSPRequest %s\n", singleCert->subjectName));
-
- /* XXX Support for signerCert may be implemented later,
- * see also the comment in CERT_CreateOCSPRequest.
- */
- if (signerCert != NULL) {
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
- }
-
- request = ocsp_prepareEmptyOCSPRequest();
- if (!request)
- return NULL;
- /*
- * Version 1 is the default, so we need not fill in a version number.
- * Now create the list of single requests, one for each cert.
- */
- request->tbsRequest->requestList =
- ocsp_CreateRequestFromCert(request->arena,
- certID,
- singleCert,
- time,
- addServiceLocator);
- if (request->tbsRequest->requestList == NULL) {
- PORT_FreeArena(request->arena, PR_FALSE);
- return NULL;
- }
- return request;
-}
-
-/*
- * FUNCTION: CERT_CreateOCSPRequest
- * Creates a CERTOCSPRequest, requesting the status of the certs in
- * the given list.
- * INPUTS:
- * CERTCertList *certList
- * A list of certs for which status will be requested.
- * Note that all of these certificates should have the same issuer,
- * or it's expected the response will be signed by a trusted responder.
- * If the certs need to be broken up into multiple requests, that
- * must be handled by the caller (and thus by having multiple calls
- * to this routine), who knows about where the request(s) are being
- * sent and whether there are any trusted responders in place.
- * int64 time
- * Indicates the time for which the certificate status is to be
- * determined -- this may be used in the search for the cert's issuer
- * but has no effect on the request itself.
- * PRBool addServiceLocator
- * If true, the Service Locator extension should be added to the
- * single request(s) for each cert.
- * CERTCertificate *signerCert
- * If non-NULL, means sign the request using this cert. Otherwise,
- * do not sign.
- * XXX note that request signing is not yet supported; see comment in code
- * RETURN:
- * A pointer to a CERTOCSPRequest structure containing an OCSP request
- * for the cert list. On error, null is returned, with an error set
- * indicating the reason. This is likely SEC_ERROR_UNKNOWN_ISSUER.
- * (The issuer is needed to create a request for the certificate.)
- * Other errors are low-level problems (no memory, bad database, etc.).
- */
-CERTOCSPRequest *
-CERT_CreateOCSPRequest(CERTCertList *certList, int64 time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert)
-{
- CERTOCSPRequest *request = NULL;
-
- if (!certList) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- /*
- * XXX When we are prepared to put signing of requests back in,
- * we will need to allocate a signature
- * structure for the request, fill in the "derCerts" field in it,
- * save the signerCert there, as well as fill in the "requestorName"
- * field of the tbsRequest.
- */
- if (signerCert != NULL) {
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
- }
- request = ocsp_prepareEmptyOCSPRequest();
- if (!request)
- return NULL;
- /*
- * Now create the list of single requests, one for each cert.
- */
- request->tbsRequest->requestList =
- ocsp_CreateSingleRequestList(request->arena,
- certList,
- time,
- addServiceLocator);
- if (request->tbsRequest->requestList == NULL) {
- PORT_FreeArena(request->arena, PR_FALSE);
- return NULL;
- }
- return request;
-}
-
-/*
- * FUNCTION: CERT_AddOCSPAcceptableResponses
- * Add the AcceptableResponses extension to an OCSP Request.
- * INPUTS:
- * CERTOCSPRequest *request
- * The request to which the extension should be added.
- * ...
- * A list (of one or more) of SECOidTag -- each of the response types
- * to be added. The last OID *must* be SEC_OID_PKIX_OCSP_BASIC_RESPONSE.
- * (This marks the end of the list, and it must be specified because a
- * client conforming to the OCSP standard is required to handle the basic
- * response type.) The OIDs are not checked in any way.
- * RETURN:
- * SECSuccess if the extension is added; SECFailure if anything goes wrong.
- * All errors are internal or low-level problems (e.g. no memory).
- */
-
-void SetRequestExts(void *object, CERTCertExtension **exts)
-{
- CERTOCSPRequest *request = (CERTOCSPRequest *)object;
-
- request->tbsRequest->requestExtensions = exts;
-}
-
-SECStatus
-CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
- SECOidTag responseType0, ...)
-{
- void *extHandle;
- va_list ap;
- int i, count;
- SECOidTag responseType;
- SECOidData *responseOid;
- SECItem **acceptableResponses = NULL;
- SECStatus rv = SECFailure;
-
- extHandle = request->tbsRequest->extensionHandle;
- if (extHandle == NULL) {
- extHandle = cert_StartExtensions(request, request->arena, SetRequestExts);
- if (extHandle == NULL)
- goto loser;
- }
-
- /* Count number of OIDS going into the extension value. */
- count = 1;
- if (responseType0 != SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
- va_start(ap, responseType0);
- do {
- count++;
- responseType = va_arg(ap, SECOidTag);
- } while (responseType != SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
- va_end(ap);
- }
-
- acceptableResponses = PORT_NewArray(SECItem *, count + 1);
- if (acceptableResponses == NULL)
- goto loser;
-
- i = 0;
- responseOid = SECOID_FindOIDByTag(responseType0);
- acceptableResponses[i++] = &(responseOid->oid);
- if (count > 1) {
- va_start(ap, responseType0);
- for ( ; i < count; i++) {
- responseType = va_arg(ap, SECOidTag);
- responseOid = SECOID_FindOIDByTag(responseType);
- acceptableResponses[i] = &(responseOid->oid);
- }
- va_end(ap);
- }
- acceptableResponses[i] = NULL;
-
- rv = CERT_EncodeAndAddExtension(extHandle, SEC_OID_PKIX_OCSP_RESPONSE,
- &acceptableResponses, PR_FALSE,
- SEC_ASN1_GET(SEC_SequenceOfObjectIDTemplate));
- if (rv != SECSuccess)
- goto loser;
-
- PORT_Free(acceptableResponses);
- if (request->tbsRequest->extensionHandle == NULL)
- request->tbsRequest->extensionHandle = extHandle;
- return SECSuccess;
-
-loser:
- if (acceptableResponses != NULL)
- PORT_Free(acceptableResponses);
- if (extHandle != NULL)
- (void) CERT_FinishExtensions(extHandle);
- return rv;
-}
-
-
-/*
- * FUNCTION: CERT_DestroyOCSPRequest
- * Frees an OCSP Request structure.
- * INPUTS:
- * CERTOCSPRequest *request
- * Pointer to CERTOCSPRequest to be freed.
- * RETURN:
- * No return value; no errors.
- */
-void
-CERT_DestroyOCSPRequest(CERTOCSPRequest *request)
-{
- if (request == NULL)
- return;
-
- if (request->tbsRequest != NULL) {
- if (request->tbsRequest->requestorName != NULL)
- CERT_DestroyGeneralNameList(request->tbsRequest->requestorName);
- if (request->tbsRequest->extensionHandle != NULL)
- (void) CERT_FinishExtensions(request->tbsRequest->extensionHandle);
- }
-
- if (request->optionalSignature != NULL) {
- if (request->optionalSignature->cert != NULL)
- CERT_DestroyCertificate(request->optionalSignature->cert);
-
- /*
- * XXX Need to free derCerts? Or do they come out of arena?
- * (Currently we never fill in derCerts, which is why the
- * answer is not obvious. Once we do, add any necessary code
- * here and remove this comment.)
- */
- }
-
- /*
- * We should actually never have a request without an arena,
- * but check just in case. (If there isn't one, there is not
- * much we can do about it...)
- */
- PORT_Assert(request->arena != NULL);
- if (request->arena != NULL)
- PORT_FreeArena(request->arena, PR_FALSE);
-}
-
-
-/*
- * RESPONSE SUPPORT FUNCTIONS (encode/create/decode/destroy):
- */
-
-/*
- * Helper function for encoding or decoding a ResponderID -- based on the
- * given type, return the associated template for that choice.
- */
-static const SEC_ASN1Template *
-ocsp_ResponderIDTemplateByType(CERTOCSPResponderIDType responderIDType)
-{
- const SEC_ASN1Template *responderIDTemplate;
-
- switch (responderIDType) {
- case ocspResponderID_byName:
- responderIDTemplate = ocsp_ResponderIDByNameTemplate;
- break;
- case ocspResponderID_byKey:
- responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
- break;
- case ocspResponderID_other:
- default:
- PORT_Assert(responderIDType == ocspResponderID_other);
- responderIDTemplate = ocsp_ResponderIDOtherTemplate;
- break;
- }
-
- return responderIDTemplate;
-}
-
-/*
- * Helper function for encoding or decoding a CertStatus -- based on the
- * given type, return the associated template for that choice.
- */
-static const SEC_ASN1Template *
-ocsp_CertStatusTemplateByType(ocspCertStatusType certStatusType)
-{
- const SEC_ASN1Template *certStatusTemplate;
-
- switch (certStatusType) {
- case ocspCertStatus_good:
- certStatusTemplate = ocsp_CertStatusGoodTemplate;
- break;
- case ocspCertStatus_revoked:
- certStatusTemplate = ocsp_CertStatusRevokedTemplate;
- break;
- case ocspCertStatus_unknown:
- certStatusTemplate = ocsp_CertStatusUnknownTemplate;
- break;
- case ocspCertStatus_other:
- default:
- PORT_Assert(certStatusType == ocspCertStatus_other);
- certStatusTemplate = ocsp_CertStatusOtherTemplate;
- break;
- }
-
- return certStatusTemplate;
-}
-
-/*
- * Helper function for decoding a certStatus -- turn the actual DER tag
- * into our local translation.
- */
-static ocspCertStatusType
-ocsp_CertStatusTypeByTag(int derTag)
-{
- ocspCertStatusType certStatusType;
-
- switch (derTag) {
- case 0:
- certStatusType = ocspCertStatus_good;
- break;
- case 1:
- certStatusType = ocspCertStatus_revoked;
- break;
- case 2:
- certStatusType = ocspCertStatus_unknown;
- break;
- default:
- certStatusType = ocspCertStatus_other;
- break;
- }
-
- return certStatusType;
-}
-
-/*
- * Helper function for decoding SingleResponses -- they each contain
- * a status which is encoded as CHOICE, which needs to be decoded "by hand".
- *
- * Note -- on error, this routine does not release the memory it may
- * have allocated; it expects its caller to do that.
- */
-static SECStatus
-ocsp_FinishDecodingSingleResponses(PRArenaPool *reqArena,
- CERTOCSPSingleResponse **responses)
-{
- ocspCertStatus *certStatus;
- ocspCertStatusType certStatusType;
- const SEC_ASN1Template *certStatusTemplate;
- int derTag;
- int i;
- SECStatus rv = SECFailure;
-
- if (!reqArena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (responses == NULL) /* nothing to do */
- return SECSuccess;
-
- for (i = 0; responses[i] != NULL; i++) {
- SECItem* newStatus;
- /*
- * The following assert points out internal errors (problems in
- * the template definitions or in the ASN.1 decoder itself, etc.).
- */
- PORT_Assert(responses[i]->derCertStatus.data != NULL);
-
- derTag = responses[i]->derCertStatus.data[0] & SEC_ASN1_TAGNUM_MASK;
- certStatusType = ocsp_CertStatusTypeByTag(derTag);
- certStatusTemplate = ocsp_CertStatusTemplateByType(certStatusType);
-
- certStatus = PORT_ArenaZAlloc(reqArena, sizeof(ocspCertStatus));
- if (certStatus == NULL) {
- goto loser;
- }
- newStatus = SECITEM_ArenaDupItem(reqArena, &responses[i]->derCertStatus);
- if (!newStatus) {
- goto loser;
- }
- rv = SEC_QuickDERDecodeItem(reqArena, certStatus, certStatusTemplate,
- newStatus);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_BAD_DER)
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- goto loser;
- }
-
- certStatus->certStatusType = certStatusType;
- responses[i]->certStatus = certStatus;
- }
-
- return SECSuccess;
-
-loser:
- return rv;
-}
-
-/*
- * Helper function for decoding a responderID -- turn the actual DER tag
- * into our local translation.
- */
-static CERTOCSPResponderIDType
-ocsp_ResponderIDTypeByTag(int derTag)
-{
- CERTOCSPResponderIDType responderIDType;
-
- switch (derTag) {
- case 1:
- responderIDType = ocspResponderID_byName;
- break;
- case 2:
- responderIDType = ocspResponderID_byKey;
- break;
- default:
- responderIDType = ocspResponderID_other;
- break;
- }
-
- return responderIDType;
-}
-
-/*
- * Decode "src" as a BasicOCSPResponse, returning the result.
- */
-static ocspBasicOCSPResponse *
-ocsp_DecodeBasicOCSPResponse(PRArenaPool *arena, SECItem *src)
-{
- void *mark;
- ocspBasicOCSPResponse *basicResponse;
- ocspResponseData *responseData;
- ocspResponderID *responderID;
- CERTOCSPResponderIDType responderIDType;
- const SEC_ASN1Template *responderIDTemplate;
- int derTag;
- SECStatus rv;
- SECItem newsrc;
-
- mark = PORT_ArenaMark(arena);
-
- basicResponse = PORT_ArenaZAlloc(arena, sizeof(ocspBasicOCSPResponse));
- if (basicResponse == NULL) {
- goto loser;
- }
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newsrc, src);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, basicResponse,
- ocsp_BasicOCSPResponseTemplate, &newsrc);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_BAD_DER)
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- goto loser;
- }
-
- responseData = basicResponse->tbsResponseData;
-
- /*
- * The following asserts point out internal errors (problems in
- * the template definitions or in the ASN.1 decoder itself, etc.).
- */
- PORT_Assert(responseData != NULL);
- PORT_Assert(responseData->derResponderID.data != NULL);
-
- /*
- * XXX Because responderID is a CHOICE, which is not currently handled
- * by our ASN.1 decoder, we have to decode it "by hand".
- */
- derTag = responseData->derResponderID.data[0] & SEC_ASN1_TAGNUM_MASK;
- responderIDType = ocsp_ResponderIDTypeByTag(derTag);
- responderIDTemplate = ocsp_ResponderIDTemplateByType(responderIDType);
-
- responderID = PORT_ArenaZAlloc(arena, sizeof(ocspResponderID));
- if (responderID == NULL) {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, responderID, responderIDTemplate,
- &responseData->derResponderID);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_BAD_DER)
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- goto loser;
- }
-
- responderID->responderIDType = responderIDType;
- responseData->responderID = responderID;
-
- /*
- * XXX Each SingleResponse also contains a CHOICE, which has to be
- * fixed up by hand.
- */
- rv = ocsp_FinishDecodingSingleResponses(arena, responseData->responses);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- PORT_ArenaUnmark(arena, mark);
- return basicResponse;
-
-loser:
- PORT_ArenaRelease(arena, mark);
- return NULL;
-}
-
-
-/*
- * Decode the responseBytes based on the responseType found in "rbytes",
- * leaving the resulting translated/decoded information in there as well.
- */
-static SECStatus
-ocsp_DecodeResponseBytes(PRArenaPool *arena, ocspResponseBytes *rbytes)
-{
- PORT_Assert(rbytes != NULL); /* internal error, really */
- if (rbytes == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS); /* XXX set better error? */
- return SECFailure;
- }
-
- rbytes->responseTypeTag = SECOID_FindOIDTag(&rbytes->responseType);
- switch (rbytes->responseTypeTag) {
- case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
- {
- ocspBasicOCSPResponse *basicResponse;
-
- basicResponse = ocsp_DecodeBasicOCSPResponse(arena,
- &rbytes->response);
- if (basicResponse == NULL)
- return SECFailure;
-
- rbytes->decodedResponse.basic = basicResponse;
- }
- break;
-
- /*
- * Add new/future response types here.
- */
-
- default:
- PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-
-/*
- * FUNCTION: CERT_DecodeOCSPResponse
- * Decode a DER encoded OCSP Response.
- * INPUTS:
- * SECItem *src
- * Pointer to a SECItem holding DER encoded OCSP Response.
- * RETURN:
- * Returns a pointer to a CERTOCSPResponse (the decoded OCSP Response);
- * the caller is responsible for destroying it. Or NULL if error (either
- * response could not be decoded (SEC_ERROR_OCSP_MALFORMED_RESPONSE),
- * it was of an unexpected type (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE),
- * or a low-level or internal error occurred).
- */
-CERTOCSPResponse *
-CERT_DecodeOCSPResponse(const SECItem *src)
-{
- PRArenaPool *arena = NULL;
- CERTOCSPResponse *response = NULL;
- SECStatus rv = SECFailure;
- ocspResponseStatus sv;
- SECItem newSrc;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto loser;
- }
- response = (CERTOCSPResponse *) PORT_ArenaZAlloc(arena,
- sizeof(CERTOCSPResponse));
- if (response == NULL) {
- goto loser;
- }
- response->arena = arena;
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newSrc, src);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, response, ocsp_OCSPResponseTemplate, &newSrc);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_BAD_DER)
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- goto loser;
- }
-
- sv = (ocspResponseStatus) DER_GetInteger(&response->responseStatus);
- response->statusValue = sv;
- if (sv != ocspResponse_successful) {
- /*
- * If the response status is anything but successful, then we
- * are all done with decoding; the status is all there is.
- */
- return response;
- }
-
- /*
- * A successful response contains much more information, still encoded.
- * Now we need to decode that.
- */
- rv = ocsp_DecodeResponseBytes(arena, response->responseBytes);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- return response;
-
-loser:
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return NULL;
-}
-
-/*
- * The way an OCSPResponse is defined, there are many levels to descend
- * before getting to the actual response information. And along the way
- * we need to check that the response *type* is recognizable, which for
- * now means that it is a BasicOCSPResponse, because that is the only
- * type currently defined. Rather than force all routines to perform
- * a bunch of sanity checking every time they want to work on a response,
- * this function isolates that and gives back the interesting part.
- * Note that no copying is done, this just returns a pointer into the
- * substructure of the response which is passed in.
- *
- * XXX This routine only works when a valid response structure is passed
- * into it; this is checked with many assertions. Assuming the response
- * was creating by decoding, it wouldn't make it this far without being
- * okay. That is a sufficient assumption since the entire OCSP interface
- * is only used internally. When this interface is officially exported,
- * each assertion below will need to be followed-up with setting an error
- * and returning (null).
- *
- * FUNCTION: ocsp_GetResponseData
- * Returns ocspResponseData structure and a pointer to tbs response
- * data DER from a valid ocsp response.
- * INPUTS:
- * CERTOCSPResponse *response
- * structure of a valid ocsp response
- * RETURN:
- * Returns a pointer to ocspResponseData structure: decoded OCSP response
- * data, and a pointer(tbsResponseDataDER) to its undecoded data DER.
- */
-ocspResponseData *
-ocsp_GetResponseData(CERTOCSPResponse *response, SECItem **tbsResponseDataDER)
-{
- ocspBasicOCSPResponse *basic;
- ocspResponseData *responseData;
-
- PORT_Assert(response != NULL);
-
- PORT_Assert(response->responseBytes != NULL);
-
- PORT_Assert(response->responseBytes->responseTypeTag
- == SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
-
- basic = response->responseBytes->decodedResponse.basic;
- PORT_Assert(basic != NULL);
-
- responseData = basic->tbsResponseData;
- PORT_Assert(responseData != NULL);
-
- if (tbsResponseDataDER) {
- *tbsResponseDataDER = &basic->tbsResponseDataDER;
-
- PORT_Assert((*tbsResponseDataDER)->data != NULL);
- PORT_Assert((*tbsResponseDataDER)->len != 0);
- }
-
- return responseData;
-}
-
-/*
- * Much like the routine above, except it returns the response signature.
- * Again, no copy is done.
- */
-ocspSignature *
-ocsp_GetResponseSignature(CERTOCSPResponse *response)
-{
- ocspBasicOCSPResponse *basic;
-
- PORT_Assert(response != NULL);
- if (NULL == response->responseBytes) {
- return NULL;
- }
- if (response->responseBytes->responseTypeTag
- != SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
- return NULL;
- }
- basic = response->responseBytes->decodedResponse.basic;
- PORT_Assert(basic != NULL);
-
- return &(basic->responseSignature);
-}
-
-
-/*
- * FUNCTION: CERT_DestroyOCSPResponse
- * Frees an OCSP Response structure.
- * INPUTS:
- * CERTOCSPResponse *request
- * Pointer to CERTOCSPResponse to be freed.
- * RETURN:
- * No return value; no errors.
- */
-void
-CERT_DestroyOCSPResponse(CERTOCSPResponse *response)
-{
- if (response != NULL) {
- ocspSignature *signature = ocsp_GetResponseSignature(response);
- if (signature && signature->cert != NULL)
- CERT_DestroyCertificate(signature->cert);
-
- /*
- * We should actually never have a response without an arena,
- * but check just in case. (If there isn't one, there is not
- * much we can do about it...)
- */
- PORT_Assert(response->arena != NULL);
- if (response->arena != NULL) {
- PORT_FreeArena(response->arena, PR_FALSE);
- }
- }
-}
-
-
-/*
- * OVERALL OCSP CLIENT SUPPORT (make and send a request, verify a response):
- */
-
-
-/*
- * Pick apart a URL, saving the important things in the passed-in pointers.
- *
- * We expect to find "http://<hostname>[:<port>]/[path]", though we will
- * tolerate that final slash character missing, as well as beginning and
- * trailing whitespace, and any-case-characters for "http". All of that
- * tolerance is what complicates this routine. What we want is just to
- * pick out the hostname, the port, and the path.
- *
- * On a successful return, the caller will need to free the output pieces
- * of hostname and path, which are copies of the values found in the url.
- */
-static SECStatus
-ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
-{
- unsigned short port = 80; /* default, in case not in url */
- char *hostname = NULL;
- char *path = NULL;
- const char *save;
- char c;
- int len;
-
- if (url == NULL)
- goto loser;
-
- /*
- * Skip beginning whitespace.
- */
- c = *url;
- while ((c == ' ' || c == '\t') && c != '\0') {
- url++;
- c = *url;
- }
- if (c == '\0')
- goto loser;
-
- /*
- * Confirm, then skip, protocol. (Since we only know how to do http,
- * that is all we will accept).
- */
- if (PORT_Strncasecmp(url, "http://", 7) != 0)
- goto loser;
- url += 7;
-
- /*
- * Whatever comes next is the hostname (or host IP address). We just
- * save it aside and then search for its end so we can determine its
- * length and copy it.
- *
- * XXX Note that because we treat a ':' as a terminator character
- * (and below, we expect that to mean there is a port specification
- * immediately following), we will not handle IPv6 addresses. That is
- * apparently an acceptable limitation, for the time being. Some day,
- * when there is a clear way to specify a URL with an IPv6 address that
- * can be parsed unambiguously, this code should be made to do that.
- */
- save = url;
- c = *url;
- while (c != '/' && c != ':' && c != '\0' && c != ' ' && c != '\t') {
- url++;
- c = *url;
- }
- len = url - save;
- hostname = PORT_Alloc(len + 1);
- if (hostname == NULL)
- goto loser;
- PORT_Memcpy(hostname, save, len);
- hostname[len] = '\0';
-
- /*
- * Now we figure out if there was a port specified or not.
- * If so, we need to parse it (as a number) and skip it.
- */
- if (c == ':') {
- url++;
- port = (unsigned short) PORT_Atoi(url);
- c = *url;
- while (c != '/' && c != '\0' && c != ' ' && c != '\t') {
- if (c < '0' || c > '9')
- goto loser;
- url++;
- c = *url;
- }
- }
-
- /*
- * Last thing to find is a path. There *should* be a slash,
- * if nothing else -- but if there is not we provide one.
- */
- if (c == '/') {
- save = url;
- while (c != '\0' && c != ' ' && c != '\t') {
- url++;
- c = *url;
- }
- len = url - save;
- path = PORT_Alloc(len + 1);
- if (path == NULL)
- goto loser;
- PORT_Memcpy(path, save, len);
- path[len] = '\0';
- } else {
- path = PORT_Strdup("/");
- if (path == NULL)
- goto loser;
- }
-
- *pHostname = hostname;
- *pPort = port;
- *pPath = path;
- return SECSuccess;
-
-loser:
- if (hostname != NULL)
- PORT_Free(hostname);
- PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
- return SECFailure;
-}
-
-/*
- * Open a socket to the specified host on the specified port, and return it.
- * The host is either a hostname or an IP address.
- */
-static PRFileDesc *
-ocsp_ConnectToHost(const char *host, PRUint16 port)
-{
- PRFileDesc *sock = NULL;
- PRIntervalTime timeout;
- PRNetAddr addr;
- char *netdbbuf = NULL;
-
- sock = PR_NewTCPSocket();
- if (sock == NULL)
- goto loser;
-
- /* XXX Some day need a way to set (and get?) the following value */
- timeout = PR_SecondsToInterval(30);
-
- /*
- * If the following converts an IP address string in "dot notation"
- * into a PRNetAddr. If it fails, we assume that is because we do not
- * have such an address, but instead a host *name*. In that case we
- * then lookup the host by name. Using the NSPR function this way
- * means we do not have to have our own logic for distinguishing a
- * valid numerical IP address from a hostname.
- */
- if (PR_StringToNetAddr(host, &addr) != PR_SUCCESS) {
- PRIntn hostIndex;
- PRHostEnt hostEntry;
-
- netdbbuf = PORT_Alloc(PR_NETDB_BUF_SIZE);
- if (netdbbuf == NULL)
- goto loser;
-
- if (PR_GetHostByName(host, netdbbuf, PR_NETDB_BUF_SIZE,
- &hostEntry) != PR_SUCCESS)
- goto loser;
-
- hostIndex = 0;
- do {
- hostIndex = PR_EnumerateHostEnt(hostIndex, &hostEntry, port, &addr);
- if (hostIndex <= 0)
- goto loser;
- } while (PR_Connect(sock, &addr, timeout) != PR_SUCCESS);
-
- PORT_Free(netdbbuf);
- } else {
- /*
- * First put the port into the address, then connect.
- */
- if (PR_InitializeNetAddr(PR_IpAddrNull, port, &addr) != PR_SUCCESS)
- goto loser;
- if (PR_Connect(sock, &addr, timeout) != PR_SUCCESS)
- goto loser;
- }
-
- return sock;
-
-loser:
- if (sock != NULL)
- PR_Close(sock);
- if (netdbbuf != NULL)
- PORT_Free(netdbbuf);
- return NULL;
-}
-
-/*
- * Sends an encoded OCSP request to the server identified by "location",
- * and returns the socket on which it was sent (so can listen for the reply).
- * "location" is expected to be a valid URL -- an error parsing it produces
- * SEC_ERROR_CERT_BAD_ACCESS_LOCATION. Other errors are likely problems
- * connecting to it, or writing to it, or allocating memory, and the low-level
- * errors appropriate to the problem will be set.
- */
-static PRFileDesc *
-ocsp_SendEncodedRequest(const char *location, SECItem *encodedRequest)
-{
- char *hostname = NULL;
- char *path = NULL;
- PRUint16 port;
- SECStatus rv;
- PRFileDesc *sock = NULL;
- PRFileDesc *returnSock = NULL;
- char *header = NULL;
- char portstr[16];
-
- /*
- * Take apart the location, getting the hostname, port, and path.
- */
- rv = ocsp_ParseURL(location, &hostname, &port, &path);
- if (rv != SECSuccess)
- goto loser;
-
- PORT_Assert(hostname != NULL);
- PORT_Assert(path != NULL);
-
- sock = ocsp_ConnectToHost(hostname, port);
- if (sock == NULL)
- goto loser;
-
- portstr[0] = '\0';
- if (port != 80) {
- PR_snprintf(portstr, sizeof(portstr), ":%d", port);
- }
-
- header = PR_smprintf("POST %s HTTP/1.0\r\n"
- "Host: %s%s\r\n"
- "Content-Type: application/ocsp-request\r\n"
- "Content-Length: %u\r\n\r\n",
- path, hostname, portstr, encodedRequest->len);
- if (header == NULL)
- goto loser;
-
- /*
- * The NSPR documentation promises that if it can, it will write the full
- * amount; this will not return a partial value expecting us to loop.
- */
- if (PR_Write(sock, header, (PRInt32) PORT_Strlen(header)) < 0)
- goto loser;
-
- if (PR_Write(sock, encodedRequest->data,
- (PRInt32) encodedRequest->len) < 0)
- goto loser;
-
- returnSock = sock;
- sock = NULL;
-
-loser:
- if (header != NULL)
- PORT_Free(header);
- if (sock != NULL)
- PR_Close(sock);
- if (path != NULL)
- PORT_Free(path);
- if (hostname != NULL)
- PORT_Free(hostname);
-
- return returnSock;
-}
-
-/*
- * Read from "fd" into "buf" -- expect/attempt to read a given number of bytes
- * Obviously, stop if hit end-of-stream. Timeout is passed in.
- */
-
-static int
-ocsp_read(PRFileDesc *fd, char *buf, int toread, PRIntervalTime timeout)
-{
- int total = 0;
-
- while (total < toread)
- {
- PRInt32 got;
-
- got = PR_Recv(fd, buf + total, (PRInt32) (toread - total), 0, timeout);
- if (got < 0)
- {
- if (0 == total)
- {
- total = -1; /* report the error if we didn't read anything yet */
- }
- break;
- }
- else
- if (got == 0)
- { /* EOS */
- break;
- }
-
- total += got;
- }
-
- return total;
-}
-
-#define OCSP_BUFSIZE 1024
-
-#define AbortHttpDecode(error) \
-{ \
- if (inBuffer) \
- PORT_Free(inBuffer); \
- PORT_SetError(error); \
- return NULL; \
-}
-
-
-/*
- * Reads on the given socket and returns an encoded response when received.
- * Properly formatted HTTP/1.0 response headers are expected to be read
- * from the socket, preceding a binary-encoded OCSP response. Problems
- * with parsing cause the error SEC_ERROR_OCSP_BAD_HTTP_RESPONSE to be
- * set; any other problems are likely low-level i/o or memory allocation
- * errors.
- */
-static SECItem *
-ocsp_GetEncodedResponse(PRArenaPool *arena, PRFileDesc *sock)
-{
- /* first read HTTP status line and headers */
-
- char* inBuffer = NULL;
- PRInt32 offset = 0;
- PRInt32 inBufsize = 0;
- const PRInt32 bufSizeIncrement = OCSP_BUFSIZE; /* 1 KB at a time */
- const PRInt32 maxBufSize = 8 * bufSizeIncrement ; /* 8 KB max */
- const char* CRLF = "\r\n";
- const PRInt32 CRLFlen = strlen(CRLF);
- const char* headerEndMark = "\r\n\r\n";
- const PRInt32 markLen = strlen(headerEndMark);
- const PRIntervalTime ocsptimeout =
- PR_SecondsToInterval(30); /* hardcoded to 30s for now */
- char* headerEnd = NULL;
- PRBool EOS = PR_FALSE;
- const char* httpprotocol = "HTTP/";
- const PRInt32 httplen = strlen(httpprotocol);
- const char* httpcode = NULL;
- const char* contenttype = NULL;
- PRInt32 contentlength = 0;
- PRInt32 bytesRead = 0;
- char* statusLineEnd = NULL;
- char* space = NULL;
- char* nextHeader = NULL;
- SECItem* result = NULL;
-
- /* read up to at least the end of the HTTP headers */
- do
- {
- inBufsize += bufSizeIncrement;
- inBuffer = PORT_Realloc(inBuffer, inBufsize+1);
- if (NULL == inBuffer)
- {
- AbortHttpDecode(SEC_ERROR_NO_MEMORY);
- }
- bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement,
- ocsptimeout);
- if (bytesRead > 0)
- {
- PRInt32 searchOffset = (offset - markLen) >0 ? offset-markLen : 0;
- offset += bytesRead;
- *(inBuffer + offset) = '\0'; /* NULL termination */
- headerEnd = strstr((const char*)inBuffer + searchOffset, headerEndMark);
- if (bytesRead < bufSizeIncrement)
- {
- /* we read less data than requested, therefore we are at
- EOS or there was a read error */
- EOS = PR_TRUE;
- }
- }
- else
- {
- /* recv error or EOS */
- EOS = PR_TRUE;
- }
- } while ( (!headerEnd) && (PR_FALSE == EOS) &&
- (inBufsize < maxBufSize) );
-
- if (!headerEnd)
- {
- AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- }
-
- /* parse the HTTP status line */
- statusLineEnd = strstr((const char*)inBuffer, CRLF);
- if (!statusLineEnd)
- {
- AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- }
- *statusLineEnd = '\0';
-
- /* check for HTTP/ response */
- space = strchr((const char*)inBuffer, ' ');
- if (!space || PORT_Strncasecmp((const char*)inBuffer, httpprotocol, httplen) != 0 )
- {
- AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- }
-
- /* check the HTTP status code of 200 */
- httpcode = space +1;
- space = strchr(httpcode, ' ');
- if (!space)
- {
- AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- }
- *space = 0;
- if (0 != strcmp(httpcode, "200"))
- {
- AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- }
-
- /* parse the HTTP headers in the buffer . We only care about
- content-type and content-length
- */
-
- nextHeader = statusLineEnd + CRLFlen;
- *headerEnd = '\0'; /* terminate */
- do
- {
- char* thisHeaderEnd = NULL;
- char* value = NULL;
- char* colon = strchr(nextHeader, ':');
-
- if (!colon)
- {
- AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- }
-
- *colon = '\0';
- value = colon + 1;
-
- /* jpierre - note : the following code will only handle the basic form
- of HTTP/1.0 response headers, of the form "name: value" . Headers
- split among multiple lines are not supported. This is not common
- and should not be an issue, but it could become one in the
- future */
-
- if (*value != ' ')
- {
- AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- }
-
- value++;
- thisHeaderEnd = strstr(value, CRLF);
- if (thisHeaderEnd )
- {
- *thisHeaderEnd = '\0';
- }
-
- if (0 == PORT_Strcasecmp(nextHeader, "content-type"))
- {
- contenttype = value;
- }
- else
- if (0 == PORT_Strcasecmp(nextHeader, "content-length"))
- {
- contentlength = atoi(value);
- }
-
- if (thisHeaderEnd )
- {
- nextHeader = thisHeaderEnd + CRLFlen;
- }
- else
- {
- nextHeader = NULL;
- }
-
- } while (nextHeader && (nextHeader < (headerEnd + CRLFlen) ) );
-
- /* check content-type */
- if (!contenttype ||
- (0 != PORT_Strcasecmp(contenttype, "application/ocsp-response")) )
- {
- AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- }
-
- /* read the body of the OCSP response */
- offset = offset - (PRInt32) (headerEnd - (const char*)inBuffer) - markLen;
- if (offset)
- {
- /* move all data to the beginning of the buffer */
- PORT_Memmove(inBuffer, headerEnd + markLen, offset);
- }
-
- /* resize buffer to only what's needed to hold the current response */
- inBufsize = (1 + (offset-1) / bufSizeIncrement ) * bufSizeIncrement ;
-
- while ( (PR_FALSE == EOS) &&
- ( (contentlength == 0) || (offset < contentlength) ) &&
- (inBufsize < maxBufSize)
- )
- {
- /* we still need to receive more body data */
- inBufsize += bufSizeIncrement;
- inBuffer = PORT_Realloc(inBuffer, inBufsize+1);
- if (NULL == inBuffer)
- {
- AbortHttpDecode(SEC_ERROR_NO_MEMORY);
- }
- bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement,
- ocsptimeout);
- if (bytesRead > 0)
- {
- offset += bytesRead;
- if (bytesRead < bufSizeIncrement)
- {
- /* we read less data than requested, therefore we are at
- EOS or there was a read error */
- EOS = PR_TRUE;
- }
- }
- else
- {
- /* recv error or EOS */
- EOS = PR_TRUE;
- }
- }
-
- if (0 == offset)
- {
- AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- }
-
- /*
- * Now allocate the item to hold the data.
- */
- result = SECITEM_AllocItem(arena, NULL, offset);
- if (NULL == result)
- {
- AbortHttpDecode(SEC_ERROR_NO_MEMORY);
- }
-
- /*
- * And copy the data left in the buffer.
- */
- PORT_Memcpy(result->data, inBuffer, offset);
-
- /* and free the temporary buffer */
- PORT_Free(inBuffer);
- return result;
-}
-
-SECStatus
-CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
-{
- return ocsp_ParseURL(url, pHostname, pPort, pPath);
-}
-
-/*
- * Limit the size of http responses we are willing to accept.
- */
-#define MAX_WANTED_OCSP_RESPONSE_LEN 64*1024
-
-static SECItem *
-fetchOcspHttpClientV1(PRArenaPool *arena,
- const SEC_HttpClientFcnV1 *hcv1,
- const char *location,
- SECItem *encodedRequest)
-{
- char *hostname = NULL;
- char *path = NULL;
- PRUint16 port;
- SECItem *encodedResponse = NULL;
- SEC_HTTP_SERVER_SESSION pServerSession = NULL;
- SEC_HTTP_REQUEST_SESSION pRequestSession = NULL;
- PRUint16 myHttpResponseCode;
- const char *myHttpResponseData;
- PRUint32 myHttpResponseDataLen;
-
- if (ocsp_ParseURL(location, &hostname, &port, &path) == SECFailure) {
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
- goto loser;
- }
-
- PORT_Assert(hostname != NULL);
- PORT_Assert(path != NULL);
-
- if ((*hcv1->createSessionFcn)(
- hostname,
- port,
- &pServerSession) != SECSuccess) {
- PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
- goto loser;
- }
-
- /* We use a non-zero timeout, which means:
- - the client will use blocking I/O
- - TryFcn will not return WOULD_BLOCK nor a poll descriptor
- - it's sufficient to call TryFcn once
- No lock for accessing OCSP_Global.timeoutSeconds, bug 406120
- */
-
- if ((*hcv1->createFcn)(
- pServerSession,
- "http",
- path,
- "POST",
- PR_TicksPerSecond() * OCSP_Global.timeoutSeconds,
- &pRequestSession) != SECSuccess) {
- PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
- goto loser;
- }
-
- if ((*hcv1->setPostDataFcn)(
- pRequestSession,
- (char*)encodedRequest->data,
- encodedRequest->len,
- "application/ocsp-request") != SECSuccess) {
- PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
- goto loser;
- }
-
- /* we don't want result objects larger than this: */
- myHttpResponseDataLen = MAX_WANTED_OCSP_RESPONSE_LEN;
-
- OCSP_TRACE(("OCSP trySendAndReceive %s\n", location));
-
- if ((*hcv1->trySendAndReceiveFcn)(
- pRequestSession,
- NULL,
- &myHttpResponseCode,
- NULL,
- NULL,
- &myHttpResponseData,
- &myHttpResponseDataLen) != SECSuccess) {
- PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
- goto loser;
- }
-
- OCSP_TRACE(("OCSP trySendAndReceive result http %d\n", myHttpResponseCode));
-
- if (myHttpResponseCode != 200) {
- PORT_SetError(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- goto loser;
- }
-
- encodedResponse = SECITEM_AllocItem(arena, NULL, myHttpResponseDataLen);
-
- if (!encodedResponse) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- PORT_Memcpy(encodedResponse->data, myHttpResponseData, myHttpResponseDataLen);
-
-loser:
- if (pRequestSession != NULL)
- (*hcv1->freeFcn)(pRequestSession);
- if (pServerSession != NULL)
- (*hcv1->freeSessionFcn)(pServerSession);
- if (path != NULL)
- PORT_Free(path);
- if (hostname != NULL)
- PORT_Free(hostname);
-
- return encodedResponse;
-}
-
-/*
- * FUNCTION: CERT_GetEncodedOCSPResponse
- * Creates and sends a request to an OCSP responder, then reads and
- * returns the (encoded) response.
- * INPUTS:
- * PRArenaPool *arena
- * Pointer to arena from which return value will be allocated.
- * If NULL, result will be allocated from the heap (and thus should
- * be freed via SECITEM_FreeItem).
- * CERTCertList *certList
- * A list of certs for which status will be requested.
- * Note that all of these certificates should have the same issuer,
- * or it's expected the response will be signed by a trusted responder.
- * If the certs need to be broken up into multiple requests, that
- * must be handled by the caller (and thus by having multiple calls
- * to this routine), who knows about where the request(s) are being
- * sent and whether there are any trusted responders in place.
- * const char *location
- * The location of the OCSP responder (a URL).
- * int64 time
- * Indicates the time for which the certificate status is to be
- * determined -- this may be used in the search for the cert's issuer
- * but has no other bearing on the operation.
- * PRBool addServiceLocator
- * If true, the Service Locator extension should be added to the
- * single request(s) for each cert.
- * CERTCertificate *signerCert
- * If non-NULL, means sign the request using this cert. Otherwise,
- * do not sign.
- * void *pwArg
- * Pointer to argument for password prompting, if needed. (Definitely
- * not needed if not signing.)
- * OUTPUTS:
- * CERTOCSPRequest **pRequest
- * Pointer in which to store the OCSP request created for the given
- * list of certificates. It is only filled in if the entire operation
- * is successful and the pointer is not null -- and in that case the
- * caller is then reponsible for destroying it.
- * RETURN:
- * Returns a pointer to the SECItem holding the response.
- * On error, returns null with error set describing the reason:
- * SEC_ERROR_UNKNOWN_ISSUER
- * SEC_ERROR_CERT_BAD_ACCESS_LOCATION
- * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE
- * Other errors are low-level problems (no memory, bad database, etc.).
- */
-SECItem *
-CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList,
- const char *location, int64 time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert, void *pwArg,
- CERTOCSPRequest **pRequest)
-{
- CERTOCSPRequest *request;
- request = CERT_CreateOCSPRequest(certList, time, addServiceLocator,
- signerCert);
- if (!request)
- return NULL;
- return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location,
- time, addServiceLocator,
- pwArg, pRequest);
-}
-
-static SECItem *
-ocsp_GetEncodedOCSPResponseFromRequest(PRArenaPool *arena,
- CERTOCSPRequest *request,
- const char *location, int64 time,
- PRBool addServiceLocator,
- void *pwArg,
- CERTOCSPRequest **pRequest)
-{
- SECItem *encodedRequest = NULL;
- SECItem *encodedResponse = NULL;
- PRFileDesc *sock = NULL;
- SECStatus rv;
- const SEC_HttpClientFcn *registeredHttpClient = NULL;
-
- rv = CERT_AddOCSPAcceptableResponses(request,
- SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
- if (rv != SECSuccess)
- goto loser;
-
- encodedRequest = CERT_EncodeOCSPRequest(NULL, request, pwArg);
- if (encodedRequest == NULL)
- goto loser;
-
- registeredHttpClient = SEC_GetRegisteredHttpClient();
-
- if (registeredHttpClient
- &&
- registeredHttpClient->version == 1) {
- encodedResponse = fetchOcspHttpClientV1(
- arena,
- &registeredHttpClient->fcnTable.ftable1,
- location,
- encodedRequest);
- }
- else {
- /* use internal http client */
-
- sock = ocsp_SendEncodedRequest(location, encodedRequest);
- if (sock == NULL)
- goto loser;
-
- encodedResponse = ocsp_GetEncodedResponse(arena, sock);
- }
-
- if (encodedResponse != NULL && pRequest != NULL) {
- *pRequest = request;
- request = NULL; /* avoid destroying below */
- }
-
-loser:
- if (request != NULL)
- CERT_DestroyOCSPRequest(request);
- if (encodedRequest != NULL)
- SECITEM_FreeItem(encodedRequest, PR_TRUE);
- if (sock != NULL)
- PR_Close(sock);
-
- return encodedResponse;
-}
-
-static SECItem *
-ocsp_GetEncodedOCSPResponseForSingleCert(PRArenaPool *arena,
- CERTOCSPCertID *certID,
- CERTCertificate *singleCert,
- const char *location, int64 time,
- PRBool addServiceLocator,
- void *pwArg,
- CERTOCSPRequest **pRequest)
-{
- CERTOCSPRequest *request;
- request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time,
- addServiceLocator, NULL);
- if (!request)
- return NULL;
- return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location,
- time, addServiceLocator,
- pwArg, pRequest);
-}
-
-/* Checks a certificate for the key usage extension of OCSP signer. */
-static PRBool
-ocsp_CertIsOCSPDesignatedResponder(CERTCertificate *cert)
-{
- SECStatus rv;
- SECItem extItem;
- SECItem **oids;
- SECItem *oid;
- SECOidTag oidTag;
- PRBool retval;
- CERTOidSequence *oidSeq = NULL;
-
-
- extItem.data = NULL;
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- oidSeq = CERT_DecodeOidSequence(&extItem);
- if ( oidSeq == NULL ) {
- goto loser;
- }
-
- oids = oidSeq->oids;
- while ( *oids != NULL ) {
- oid = *oids;
-
- oidTag = SECOID_FindOIDTag(oid);
-
- if ( oidTag == SEC_OID_OCSP_RESPONDER ) {
- goto success;
- }
-
- oids++;
- }
-
-loser:
- retval = PR_FALSE;
- PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
- goto done;
-success:
- retval = PR_TRUE;
-done:
- if ( extItem.data != NULL ) {
- PORT_Free(extItem.data);
- }
- if ( oidSeq != NULL ) {
- CERT_DestroyOidSequence(oidSeq);
- }
-
- return(retval);
-}
-
-
-#ifdef LATER /*
- * XXX This function is not currently used, but will
- * be needed later when we do revocation checking of
- * the responder certificate. Of course, it may need
- * revising then, if the cert extension interface has
- * changed. (Hopefully it will!)
- */
-
-/* Checks a certificate to see if it has the OCSP no check extension. */
-static PRBool
-ocsp_CertHasNoCheckExtension(CERTCertificate *cert)
-{
- SECStatus rv;
-
- rv = CERT_FindCertExtension(cert, SEC_OID_PKIX_OCSP_NO_CHECK,
- NULL);
- if (rv == SECSuccess) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-#endif /* LATER */
-
-static PRBool
-ocsp_matchcert(SECItem *certIndex,CERTCertificate *testCert)
-{
- SECItem item;
- unsigned char buf[HASH_LENGTH_MAX];
-
- item.data = buf;
- item.len = SHA1_LENGTH;
-
- if (CERT_GetSPKIDigest(NULL,testCert,SEC_OID_SHA1, &item) == NULL) {
- return PR_FALSE;
- }
- if (SECITEM_ItemsAreEqual(certIndex,&item)) {
- return PR_TRUE;
- }
- if (CERT_GetSPKIDigest(NULL,testCert,SEC_OID_MD5, &item) == NULL) {
- return PR_FALSE;
- }
- if (SECITEM_ItemsAreEqual(certIndex,&item)) {
- return PR_TRUE;
- }
- if (CERT_GetSPKIDigest(NULL,testCert,SEC_OID_MD2, &item) == NULL) {
- return PR_FALSE;
- }
- if (SECITEM_ItemsAreEqual(certIndex,&item)) {
- return PR_TRUE;
- }
-
- return PR_FALSE;
-}
-
-static CERTCertificate *
-ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID);
-
-CERTCertificate *
-ocsp_GetSignerCertificate(CERTCertDBHandle *handle, ocspResponseData *tbsData,
- ocspSignature *signature, CERTCertificate *issuer)
-{
- CERTCertificate **certs = NULL;
- CERTCertificate *signerCert = NULL;
- SECStatus rv = SECFailure;
- PRBool lookupByName = PR_TRUE;
- void *certIndex = NULL;
- int certCount = 0;
-
- PORT_Assert(tbsData->responderID != NULL);
- switch (tbsData->responderID->responderIDType) {
- case ocspResponderID_byName:
- lookupByName = PR_TRUE;
- certIndex = &tbsData->derResponderID;
- break;
- case ocspResponderID_byKey:
- lookupByName = PR_FALSE;
- certIndex = &tbsData->responderID->responderIDValue.keyHash;
- break;
- case ocspResponderID_other:
- default:
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- return NULL;
- }
-
- /*
- * If the signature contains some certificates as well, temporarily
- * import them in case they are needed for verification.
- *
- * Note that the result of this is that each cert in "certs" needs
- * to be destroyed.
- */
- if (signature->derCerts != NULL) {
- for (; signature->derCerts[certCount] != NULL; certCount++) {
- /* just counting */
- }
- rv = CERT_ImportCerts(handle, certUsageStatusResponder, certCount,
- signature->derCerts, &certs,
- PR_FALSE, PR_FALSE, NULL);
- if (rv != SECSuccess)
- goto finish;
- }
-
- /*
- * Now look up the certificate that did the signing.
- * The signer can be specified either by name or by key hash.
- */
- if (lookupByName) {
- SECItem *crIndex = (SECItem*)certIndex;
- SECItem encodedName;
- PLArenaPool *arena;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena != NULL) {
-
- rv = SEC_QuickDERDecodeItem(arena, &encodedName,
- ocsp_ResponderIDDerNameTemplate,
- crIndex);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_BAD_DER)
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- } else {
- signerCert = CERT_FindCertByName(handle, &encodedName);
- }
- PORT_FreeArena(arena, PR_FALSE);
- }
- } else {
- /*
- * The signer is either 1) a known issuer CA we passed in,
- * 2) the default OCSP responder, or 3) an intermediate CA
- * passed in the cert list to use. Figure out which it is.
- */
- int i;
- CERTCertificate *responder =
- ocsp_CertGetDefaultResponder(handle, NULL);
- if (responder && ocsp_matchcert(certIndex,responder)) {
- signerCert = CERT_DupCertificate(responder);
- } else if (issuer && ocsp_matchcert(certIndex,issuer)) {
- signerCert = CERT_DupCertificate(issuer);
- }
- for (i=0; (signerCert == NULL) && (i < certCount); i++) {
- if (ocsp_matchcert(certIndex,certs[i])) {
- signerCert = CERT_DupCertificate(certs[i]);
- }
- }
- }
-
-finish:
- if (certs != NULL) {
- CERT_DestroyCertArray(certs, certCount);
- }
-
- return signerCert;
-}
-
-SECStatus
-ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
- ocspSignature *signature,
- SECItem *tbsResponseDataDER,
- void *pwArg)
-{
- SECItem rawSignature;
- SECKEYPublicKey *signerKey = NULL;
- SECStatus rv = SECFailure;
-
- /*
- * Now get the public key from the signer's certificate; we need
- * it to perform the verification.
- */
- signerKey = CERT_ExtractPublicKey(signerCert);
- if (signerKey == NULL)
- return SECFailure;
- /*
- * We copy the signature data *pointer* and length, so that we can
- * modify the length without damaging the original copy. This is a
- * simple copy, not a dup, so no destroy/free is necessary.
- */
- rawSignature = signature->signature;
- /*
- * The raw signature is a bit string, but we need to represent its
- * length in bytes, because that is what the verify function expects.
- */
- DER_ConvertBitString(&rawSignature);
-
- rv = VFY_VerifyDataWithAlgorithmID(tbsResponseDataDER->data,
- tbsResponseDataDER->len,
- signerKey, &rawSignature,
- &signature->signatureAlgorithm,
- NULL, pwArg);
- if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_BAD_SIGNATURE) {
- PORT_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE);
- }
-
- if (signerKey != NULL) {
- SECKEY_DestroyPublicKey(signerKey);
- }
-
- return rv;
-}
-
-
-/*
- * FUNCTION: CERT_VerifyOCSPResponseSignature
- * Check the signature on an OCSP Response. Will also perform a
- * verification of the signer's certificate. Note, however, that a
- * successful verification does not make any statement about the
- * signer's *authority* to provide status for the certificate(s),
- * that must be checked individually for each certificate.
- * INPUTS:
- * CERTOCSPResponse *response
- * Pointer to response structure with signature to be checked.
- * CERTCertDBHandle *handle
- * Pointer to CERTCertDBHandle for certificate DB to use for verification.
- * void *pwArg
- * Pointer to argument for password prompting, if needed.
- * OUTPUTS:
- * CERTCertificate **pSignerCert
- * Pointer in which to store signer's certificate; only filled-in if
- * non-null.
- * RETURN:
- * Returns SECSuccess when signature is valid, anything else means invalid.
- * Possible errors set:
- * SEC_ERROR_OCSP_MALFORMED_RESPONSE - unknown type of ResponderID
- * SEC_ERROR_INVALID_TIME - bad format of "ProducedAt" time
- * SEC_ERROR_UNKNOWN_SIGNER - signer's cert could not be found
- * SEC_ERROR_BAD_SIGNATURE - the signature did not verify
- * Other errors are any of the many possible failures in cert verification
- * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
- * verifying the signer's cert, or low-level problems (no memory, etc.)
- */
-SECStatus
-CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
- CERTCertDBHandle *handle, void *pwArg,
- CERTCertificate **pSignerCert,
- CERTCertificate *issuer)
-{
- SECItem *tbsResponseDataDER;
- CERTCertificate *signerCert = NULL;
- SECStatus rv = SECFailure;
- int64 producedAt;
-
- /* ocsp_DecodeBasicOCSPResponse will fail if asn1 decoder is unable
- * to properly decode tbsData (see the function and
- * ocsp_BasicOCSPResponseTemplate). Thus, tbsData can not be
- * equal to null */
- ocspResponseData *tbsData = ocsp_GetResponseData(response,
- &tbsResponseDataDER);
- ocspSignature *signature = ocsp_GetResponseSignature(response);
-
- if (!signature) {
- PORT_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE);
- return SECFailure;
- }
-
- /*
- * If this signature has already gone through verification, just
- * return the cached result.
- */
- if (signature->wasChecked) {
- if (signature->status == SECSuccess) {
- if (pSignerCert != NULL)
- *pSignerCert = CERT_DupCertificate(signature->cert);
- } else {
- PORT_SetError(signature->failureReason);
- }
- return signature->status;
- }
-
- signerCert = ocsp_GetSignerCertificate(handle, tbsData,
- signature, issuer);
- if (signerCert == NULL) {
- rv = SECFailure;
- if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) {
- /* Make the error a little more specific. */
- PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
- }
- goto finish;
- }
-
- /*
- * We could mark this true at the top of this function, or always
- * below at "finish", but if the problem was just that we could not
- * find the signer's cert, leave that as if the signature hasn't
- * been checked in case a subsequent call might have better luck.
- */
- signature->wasChecked = PR_TRUE;
-
- /*
- * The function will also verify the signer certificate; we
- * need to tell it *when* that certificate must be valid -- for our
- * purposes we expect it to be valid when the response was signed.
- * The value of "producedAt" is the signing time.
- */
- rv = DER_GeneralizedTimeToTime(&producedAt, &tbsData->producedAt);
- if (rv != SECSuccess)
- goto finish;
-
- /*
- * Just because we have a cert does not mean it is any good; check
- * it for validity, trust and usage.
- */
- if (ocsp_CertIsOCSPDefaultResponder(handle, signerCert)) {
- rv = SECSuccess;
- } else {
- SECCertUsage certUsage;
- if (CERT_IsCACert(signerCert, NULL)) {
- certUsage = certUsageAnyCA;
- } else {
- certUsage = certUsageStatusResponder;
- }
- rv = CERT_VerifyCert(handle, signerCert, PR_TRUE,
- certUsage, producedAt, pwArg, NULL);
- if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
- goto finish;
- }
- }
-
- rv = ocsp_VerifyResponseSignature(signerCert, signature,
- tbsResponseDataDER,
- pwArg);
-
-finish:
- if (signature->wasChecked)
- signature->status = rv;
-
- if (rv != SECSuccess) {
- signature->failureReason = PORT_GetError();
- if (signerCert != NULL)
- CERT_DestroyCertificate(signerCert);
- } else {
- /*
- * Save signer's certificate in signature.
- */
- signature->cert = signerCert;
- if (pSignerCert != NULL) {
- /*
- * Pass pointer to signer's certificate back to our caller,
- * who is also now responsible for destroying it.
- */
- *pSignerCert = CERT_DupCertificate(signerCert);
- }
- }
-
- return rv;
-}
-
-/*
- * See if the request's certID and the single response's certID match.
- * This can be easy or difficult, depending on whether the same hash
- * algorithm was used.
- */
-static PRBool
-ocsp_CertIDsMatch(CERTCertDBHandle *handle,
- CERTOCSPCertID *requestCertID,
- CERTOCSPCertID *responseCertID)
-{
- PRBool match = PR_FALSE;
- SECOidTag hashAlg;
- SECItem *keyHash = NULL;
- SECItem *nameHash = NULL;
-
- /*
- * In order to match, they must have the same issuer and the same
- * serial number.
- *
- * We just compare the easier things first.
- */
- if (SECITEM_CompareItem(&requestCertID->serialNumber,
- &responseCertID->serialNumber) != SECEqual) {
- goto done;
- }
-
- /*
- * Make sure the "parameters" are not too bogus. Since we encoded
- * requestCertID->hashAlgorithm, we don't need to check it.
- */
- if (responseCertID->hashAlgorithm.parameters.len > 2) {
- goto done;
- }
- if (SECITEM_CompareItem(&requestCertID->hashAlgorithm.algorithm,
- &responseCertID->hashAlgorithm.algorithm) == SECEqual) {
- /*
- * If the hash algorithms match then we can do a simple compare
- * of the hash values themselves.
- */
- if ((SECITEM_CompareItem(&requestCertID->issuerNameHash,
- &responseCertID->issuerNameHash) == SECEqual)
- && (SECITEM_CompareItem(&requestCertID->issuerKeyHash,
- &responseCertID->issuerKeyHash) == SECEqual)) {
- match = PR_TRUE;
- }
- goto done;
- }
-
- hashAlg = SECOID_FindOIDTag(&responseCertID->hashAlgorithm.algorithm);
- switch (hashAlg) {
- case SEC_OID_SHA1:
- keyHash = &requestCertID->issuerSHA1KeyHash;
- nameHash = &requestCertID->issuerSHA1NameHash;
- break;
- case SEC_OID_MD5:
- keyHash = &requestCertID->issuerMD5KeyHash;
- nameHash = &requestCertID->issuerMD5NameHash;
- break;
- case SEC_OID_MD2:
- keyHash = &requestCertID->issuerMD2KeyHash;
- nameHash = &requestCertID->issuerMD2NameHash;
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
-
- if ((keyHash != NULL)
- && (SECITEM_CompareItem(nameHash,
- &responseCertID->issuerNameHash) == SECEqual)
- && (SECITEM_CompareItem(keyHash,
- &responseCertID->issuerKeyHash) == SECEqual)) {
- match = PR_TRUE;
- }
-
-done:
- return match;
-}
-
-/*
- * Find the single response for the cert specified by certID.
- * No copying is done; this just returns a pointer to the appropriate
- * response within responses, if it is found (and null otherwise).
- * This is fine, of course, since this function is internal-use only.
- */
-static CERTOCSPSingleResponse *
-ocsp_GetSingleResponseForCertID(CERTOCSPSingleResponse **responses,
- CERTCertDBHandle *handle,
- CERTOCSPCertID *certID)
-{
- CERTOCSPSingleResponse *single;
- int i;
-
- if (responses == NULL)
- return NULL;
-
- for (i = 0; responses[i] != NULL; i++) {
- single = responses[i];
- if (ocsp_CertIDsMatch(handle, certID, single->certID)) {
- return single;
- }
- }
-
- /*
- * The OCSP server should have included a response even if it knew
- * nothing about the certificate in question. Since it did not,
- * this will make it look as if it had.
- *
- * XXX Should we make this a separate error to notice the server's
- * bad behavior?
- */
- PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT);
- return NULL;
-}
-
-static ocspCheckingContext *
-ocsp_GetCheckingContext(CERTCertDBHandle *handle)
-{
- CERTStatusConfig *statusConfig;
- ocspCheckingContext *ocspcx = NULL;
-
- statusConfig = CERT_GetStatusConfig(handle);
- if (statusConfig != NULL) {
- ocspcx = statusConfig->statusContext;
-
- /*
- * This is actually an internal error, because we should never
- * have a good statusConfig without a good statusContext, too.
- * For lack of anything better, though, we just assert and use
- * the same error as if there were no statusConfig (set below).
- */
- PORT_Assert(ocspcx != NULL);
- }
-
- if (ocspcx == NULL)
- PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED);
-
- return ocspcx;
-}
-
-/*
- * Return cert reference if the given signerCert is the default responder for
- * the given certID. If not, or if any error, return NULL.
- */
-static CERTCertificate *
-ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle, CERTOCSPCertID *certID)
-{
- ocspCheckingContext *ocspcx;
-
- ocspcx = ocsp_GetCheckingContext(handle);
- if (ocspcx == NULL)
- goto loser;
-
- /*
- * Right now we have only one default responder. It applies to
- * all certs when it is used, so the check is simple and certID
- * has no bearing on the answer. Someday in the future we may
- * allow configuration of different responders for different
- * issuers, and then we would have to use the issuer specified
- * in certID to determine if signerCert is the right one.
- */
- if (ocspcx->useDefaultResponder) {
- PORT_Assert(ocspcx->defaultResponderCert != NULL);
- return ocspcx->defaultResponderCert;
- }
-
-loser:
- return NULL;
-}
-
-/*
- * Return true if the cert is one of the default responders configured for
- * ocsp context. If not, or if any error, return false.
- */
-PRBool
-ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert)
-{
- ocspCheckingContext *ocspcx;
-
- ocspcx = ocsp_GetCheckingContext(handle);
- if (ocspcx == NULL)
- return PR_FALSE;
-
- /*
- * Right now we have only one default responder. It applies to
- * all certs when it is used, so the check is simple and certID
- * has no bearing on the answer. Someday in the future we may
- * allow configuration of different responders for different
- * issuers, and then we would have to use the issuer specified
- * in certID to determine if signerCert is the right one.
- */
- if (ocspcx->useDefaultResponder &&
- CERT_CompareCerts(ocspcx->defaultResponderCert, cert)) {
- return PR_TRUE;
- }
-
- return PR_FALSE;
-}
-
-/*
- * Check that the given signer certificate is authorized to sign status
- * information for the given certID. Return true if it is, false if not
- * (or if there is any error along the way). If false is returned because
- * the signer is not authorized, the following error will be set:
- * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
- * Other errors are low-level problems (no memory, bad database, etc.).
- *
- * There are three ways to be authorized. In the order in which we check,
- * using the terms used in the OCSP spec, the signer must be one of:
- * 1. A "trusted responder" -- it matches a local configuration
- * of OCSP signing authority for the certificate in question.
- * 2. The CA who issued the certificate in question.
- * 3. A "CA designated responder", aka an "authorized responder" -- it
- * must be represented by a special cert issued by the CA who issued
- * the certificate in question.
- */
-static PRBool
-ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle,
- CERTCertificate *signerCert,
- CERTOCSPCertID *certID,
- int64 thisUpdate)
-{
- CERTCertificate *issuerCert = NULL, *defRespCert;
- SECItem *keyHash = NULL;
- SECItem *nameHash = NULL;
- SECOidTag hashAlg;
- PRBool keyHashEQ = PR_FALSE, nameHashEQ = PR_FALSE;
-
- /*
- * Check first for a trusted responder, which overrides everything else.
- */
- if ((defRespCert = ocsp_CertGetDefaultResponder(handle, certID)) &&
- CERT_CompareCerts(defRespCert, signerCert)) {
- return PR_TRUE;
- }
-
- /*
- * In the other two cases, we need to do an issuer comparison.
- * How we do it depends on whether the signer certificate has the
- * special extension (for a designated responder) or not.
- *
- * First, lets check if signer of the response is the actual issuer
- * of the cert. For that we will use signer cert key hash and cert subj
- * name hash and will compare them with already calculated issuer key
- * hash and issuer name hash. The hash algorithm is picked from response
- * certID hash to avoid second hash calculation.
- */
-
- hashAlg = SECOID_FindOIDTag(&certID->hashAlgorithm.algorithm);
-
- keyHash = CERT_GetSPKIDigest(NULL, signerCert, hashAlg, NULL);
- if (keyHash != NULL) {
-
- keyHashEQ =
- (SECITEM_CompareItem(keyHash,
- &certID->issuerKeyHash) == SECEqual);
- SECITEM_FreeItem(keyHash, PR_TRUE);
- }
- if (keyHashEQ &&
- (nameHash = cert_GetSubjectNameDigest(NULL, signerCert,
- hashAlg, NULL))) {
- nameHashEQ =
- (SECITEM_CompareItem(nameHash,
- &certID->issuerNameHash) == SECEqual);
-
- SECITEM_FreeItem(nameHash, PR_TRUE);
- if (nameHashEQ) {
- /* The issuer of the cert is the the signer of the response */
- return PR_TRUE;
- }
- }
-
-
- keyHashEQ = PR_FALSE;
- nameHashEQ = PR_FALSE;
-
- if (!ocsp_CertIsOCSPDesignatedResponder(signerCert)) {
- PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE);
- return PR_FALSE;
- }
-
- /*
- * The signer is a designated responder. Its issuer must match
- * the issuer of the cert being checked.
- */
- issuerCert = CERT_FindCertIssuer(signerCert, thisUpdate,
- certUsageAnyCA);
- if (issuerCert == NULL) {
- /*
- * We could leave the SEC_ERROR_UNKNOWN_ISSUER error alone,
- * but the following will give slightly more information.
- * Once we have an error stack, things will be much better.
- */
- PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE);
- return PR_FALSE;
- }
-
- keyHash = CERT_GetSPKIDigest(NULL, issuerCert, hashAlg, NULL);
- nameHash = cert_GetSubjectNameDigest(NULL, issuerCert, hashAlg, NULL);
-
- CERT_DestroyCertificate(issuerCert);
-
- if (keyHash != NULL && nameHash != NULL) {
- keyHashEQ =
- (SECITEM_CompareItem(keyHash,
- &certID->issuerKeyHash) == SECEqual);
-
- nameHashEQ =
- (SECITEM_CompareItem(nameHash,
- &certID->issuerNameHash) == SECEqual);
- }
-
- if (keyHash) {
- SECITEM_FreeItem(keyHash, PR_TRUE);
- }
- if (nameHash) {
- SECITEM_FreeItem(nameHash, PR_TRUE);
- }
-
- if (keyHashEQ && nameHashEQ) {
- return PR_TRUE;
- }
-
- PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE);
- return PR_FALSE;
-}
-
-/*
- * We need to check that a responder gives us "recent" information.
- * Since a responder can pre-package responses, we need to pick an amount
- * of time that is acceptable to us, and reject any response that is
- * older than that.
- *
- * XXX This *should* be based on some configuration parameter, so that
- * different usages could specify exactly what constitutes "sufficiently
- * recent". But that is not going to happen right away. For now, we
- * want something from within the last 24 hours. This macro defines that
- * number in seconds.
- */
-#define OCSP_ALLOWABLE_LAPSE_SECONDS (24L * 60L * 60L)
-
-static PRBool
-ocsp_TimeIsRecent(int64 checkTime)
-{
- int64 now = PR_Now();
- int64 lapse, tmp;
-
- LL_I2L(lapse, OCSP_ALLOWABLE_LAPSE_SECONDS);
- LL_I2L(tmp, PR_USEC_PER_SEC);
- LL_MUL(lapse, lapse, tmp); /* allowable lapse in microseconds */
-
- LL_ADD(checkTime, checkTime, lapse);
- if (LL_CMP(now, >, checkTime))
- return PR_FALSE;
-
- return PR_TRUE;
-}
-
-#define OCSP_SLOP (5L*60L) /* OCSP responses are allowed to be 5 minutes
- in the future by default */
-
-static PRUint32 ocspsloptime = OCSP_SLOP; /* seconds */
-
-/*
- * If an old response contains the revoked certificate status, we want
- * to return SECSuccess so the response will be used.
- */
-static SECStatus
-ocsp_HandleOldSingleResponse(CERTOCSPSingleResponse *single, PRTime time)
-{
- SECStatus rv;
- ocspCertStatus *status = single->certStatus;
- if (status->certStatusType == ocspCertStatus_revoked) {
- rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time);
- if (rv != SECSuccess &&
- PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE) {
- /*
- * Return SECSuccess now. The subsequent ocsp_CertRevokedAfter
- * call in ocsp_CertHasGoodStatus will cause
- * ocsp_CertHasGoodStatus to fail with
- * SEC_ERROR_REVOKED_CERTIFICATE.
- */
- return SECSuccess;
- }
-
- }
- PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE);
- return SECFailure;
-}
-
-/*
- * Check that this single response is okay. A return of SECSuccess means:
- * 1. The signer (represented by "signerCert") is authorized to give status
- * for the cert represented by the individual response in "single".
- * 2. The value of thisUpdate is earlier than now.
- * 3. The value of producedAt is later than or the same as thisUpdate.
- * 4. If nextUpdate is given:
- * - The value of nextUpdate is later than now.
- * - The value of producedAt is earlier than nextUpdate.
- * Else if no nextUpdate:
- * - The value of thisUpdate is fairly recent.
- * - The value of producedAt is fairly recent.
- * However we do not need to perform an explicit check for this last
- * constraint because it is already guaranteed by checking that
- * producedAt is later than thisUpdate and thisUpdate is recent.
- * Oh, and any responder is "authorized" to say that a cert is unknown to it.
- *
- * If any of those checks fail, SECFailure is returned and an error is set:
- * SEC_ERROR_OCSP_FUTURE_RESPONSE
- * SEC_ERROR_OCSP_OLD_RESPONSE
- * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
- * Other errors are low-level problems (no memory, bad database, etc.).
- */
-static SECStatus
-ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single,
- CERTCertDBHandle *handle,
- CERTCertificate *signerCert,
- int64 producedAt)
-{
- CERTOCSPCertID *certID = single->certID;
- int64 now, thisUpdate, nextUpdate, tmstamp, tmp;
- SECStatus rv;
-
- OCSP_TRACE(("OCSP ocsp_VerifySingleResponse, nextUpdate: %d\n",
- ((single->nextUpdate) != 0)));
- /*
- * If all the responder said was that the given cert was unknown to it,
- * that is a valid response. Not very interesting to us, of course,
- * but all this function is concerned with is validity of the response,
- * not the status of the cert.
- */
- PORT_Assert(single->certStatus != NULL);
- if (single->certStatus->certStatusType == ocspCertStatus_unknown)
- return SECSuccess;
-
- /*
- * We need to extract "thisUpdate" for use below and to pass along
- * to AuthorizedResponderForCertID in case it needs it for doing an
- * issuer look-up.
- */
- rv = DER_GeneralizedTimeToTime(&thisUpdate, &single->thisUpdate);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * First confirm that signerCert is authorized to give this status.
- */
- if (ocsp_AuthorizedResponderForCertID(handle, signerCert, certID,
- thisUpdate) != PR_TRUE)
- return SECFailure;
-
- /*
- * Now check the time stuff, as described above.
- */
- now = PR_Now();
- /* allow slop time for future response */
- LL_UI2L(tmstamp, ocspsloptime); /* get slop time in seconds */
- LL_UI2L(tmp, PR_USEC_PER_SEC);
- LL_MUL(tmp, tmstamp, tmp); /* convert the slop time to PRTime */
- LL_ADD(tmstamp, tmp, now); /* add current time to it */
-
- if (LL_CMP(thisUpdate, >, tmstamp) || LL_CMP(producedAt, <, thisUpdate)) {
- PORT_SetError(SEC_ERROR_OCSP_FUTURE_RESPONSE);
- return SECFailure;
- }
- if (single->nextUpdate != NULL) {
- rv = DER_GeneralizedTimeToTime(&nextUpdate, single->nextUpdate);
- if (rv != SECSuccess)
- return rv;
-
- LL_ADD(tmp, tmp, nextUpdate);
- if (LL_CMP(tmp, <, now) || LL_CMP(producedAt, >, nextUpdate))
- return ocsp_HandleOldSingleResponse(single, now);
- } else if (ocsp_TimeIsRecent(thisUpdate) != PR_TRUE) {
- return ocsp_HandleOldSingleResponse(single, now);
- }
-
- return SECSuccess;
-}
-
-
-/*
- * FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
- * Get the value of the URI of the OCSP responder for the given cert.
- * This is found in the (optional) Authority Information Access extension
- * in the cert.
- * INPUTS:
- * CERTCertificate *cert
- * The certificate being examined.
- * RETURN:
- * char *
- * A copy of the URI for the OCSP method, if found. If either the
- * extension is not present or it does not contain an entry for OCSP,
- * SEC_ERROR_CERT_BAD_ACCESS_LOCATION will be set and a NULL returned.
- * Any other error will also result in a NULL being returned.
- *
- * This result should be freed (via PORT_Free) when no longer in use.
- */
-char *
-CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert)
-{
- CERTGeneralName *locname = NULL;
- SECItem *location = NULL;
- SECItem *encodedAuthInfoAccess = NULL;
- CERTAuthInfoAccess **authInfoAccess = NULL;
- char *locURI = NULL;
- PRArenaPool *arena = NULL;
- SECStatus rv;
- int i;
-
- /*
- * Allocate this one from the heap because it will get filled in
- * by CERT_FindCertExtension which will also allocate from the heap,
- * and we can free the entire thing on our way out.
- */
- encodedAuthInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
- if (encodedAuthInfoAccess == NULL)
- goto loser;
-
- rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
- encodedAuthInfoAccess);
- if (rv == SECFailure) {
- PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
- goto loser;
- }
-
- /*
- * The rest of the things allocated in the routine will come out of
- * this arena, which is temporary just for us to decode and get at the
- * AIA extension. The whole thing will be destroyed on our way out,
- * after we have copied the location string (url) itself (if found).
- */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- goto loser;
-
- authInfoAccess = CERT_DecodeAuthInfoAccessExtension(arena,
- encodedAuthInfoAccess);
- if (authInfoAccess == NULL)
- goto loser;
-
- for (i = 0; authInfoAccess[i] != NULL; i++) {
- if (SECOID_FindOIDTag(&authInfoAccess[i]->method) == SEC_OID_PKIX_OCSP)
- locname = authInfoAccess[i]->location;
- }
-
- /*
- * If we found an AIA extension, but it did not include an OCSP method,
- * that should look to our caller as if we did not find the extension
- * at all, because it is only an OCSP method that we care about.
- * So set the same error that would be set if the AIA extension was
- * not there at all.
- */
- if (locname == NULL) {
- PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
- goto loser;
- }
-
- /*
- * The following is just a pointer back into locname (i.e. not a copy);
- * thus it should not be freed.
- */
- location = CERT_GetGeneralNameByType(locname, certURI, PR_FALSE);
- if (location == NULL) {
- /*
- * XXX Appears that CERT_GetGeneralNameByType does not set an
- * error if there is no name by that type. For lack of anything
- * better, act as if the extension was not found. In the future
- * this should probably be something more like the extension was
- * badly formed.
- */
- PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
- goto loser;
- }
-
- /*
- * That location is really a string, but it has a specified length
- * without a null-terminator. We need a real string that does have
- * a null-terminator, and we need a copy of it anyway to return to
- * our caller -- so allocate and copy.
- */
- locURI = PORT_Alloc(location->len + 1);
- if (locURI == NULL) {
- goto loser;
- }
- PORT_Memcpy(locURI, location->data, location->len);
- locURI[location->len] = '\0';
-
-loser:
- if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
-
- if (encodedAuthInfoAccess != NULL)
- SECITEM_FreeItem(encodedAuthInfoAccess, PR_TRUE);
-
- return locURI;
-}
-
-
-/*
- * Figure out where we should go to find out the status of the given cert
- * via OCSP. If allowed to use a default responder uri and a default
- * responder is set up, then that is our answer.
- * If not, see if the certificate has an Authority Information Access (AIA)
- * extension for OCSP, and return the value of that. Otherwise return NULL.
- * We also let our caller know whether or not the responder chosen was
- * a default responder or not through the output variable isDefault;
- * its value has no meaning unless a good (non-null) value is returned
- * for the location.
- *
- * The result needs to be freed (PORT_Free) when no longer in use.
- */
-char *
-ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRBool canUseDefault, PRBool *isDefault)
-{
- ocspCheckingContext *ocspcx = NULL;
- char *ocspUrl = NULL;
-
- if (canUseDefault) {
- ocspcx = ocsp_GetCheckingContext(handle);
- }
- if (ocspcx != NULL && ocspcx->useDefaultResponder) {
- /*
- * A default responder wins out, if specified.
- * XXX Someday this may be a more complicated determination based
- * on the cert's issuer. (That is, we could have different default
- * responders configured for different issuers.)
- */
- PORT_Assert(ocspcx->defaultResponderURI != NULL);
- *isDefault = PR_TRUE;
- return (PORT_Strdup(ocspcx->defaultResponderURI));
- }
-
- /*
- * No default responder set up, so go see if we can find an AIA
- * extension that has a value for OCSP, and get the url from that.
- */
- *isDefault = PR_FALSE;
- ocspUrl = CERT_GetOCSPAuthorityInfoAccessLocation(cert);
- if (!ocspUrl) {
- CERT_StringFromCertFcn altFcn;
-
- PR_EnterMonitor(OCSP_Global.monitor);
- altFcn = OCSP_Global.alternateOCSPAIAFcn;
- PR_ExitMonitor(OCSP_Global.monitor);
- if (altFcn) {
- ocspUrl = (*altFcn)(cert);
- if (ocspUrl)
- *isDefault = PR_TRUE;
- }
- }
- return ocspUrl;
-}
-
-/*
- * Return SECSuccess if the cert was revoked *after* "time",
- * SECFailure otherwise.
- */
-static SECStatus
-ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, int64 time)
-{
- int64 revokedTime;
- SECStatus rv;
-
- rv = DER_GeneralizedTimeToTime(&revokedTime, &revokedInfo->revocationTime);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * Set the error even if we will return success; someone might care.
- */
- PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
-
- if (LL_CMP(revokedTime, >, time))
- return SECSuccess;
-
- return SECFailure;
-}
-
-/*
- * See if the cert represented in the single response had a good status
- * at the specified time.
- */
-static SECStatus
-ocsp_CertHasGoodStatus(ocspCertStatus *status, int64 time)
-{
- SECStatus rv;
- switch (status->certStatusType) {
- case ocspCertStatus_good:
- rv = SECSuccess;
- break;
- case ocspCertStatus_revoked:
- rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time);
- break;
- case ocspCertStatus_unknown:
- PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT);
- rv = SECFailure;
- break;
- case ocspCertStatus_other:
- default:
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- rv = SECFailure;
- break;
- }
- return rv;
-}
-
-static SECStatus
-ocsp_SingleResponseCertHasGoodStatus(CERTOCSPSingleResponse *single,
- int64 time)
-{
- return ocsp_CertHasGoodStatus(single->certStatus, time);
-}
-
-/* Return value SECFailure means: not found or not fresh.
- * On SECSuccess, the out parameters contain the OCSP status.
- * rvOcsp contains the overall result of the OCSP operation.
- * Depending on input parameter ignoreGlobalOcspFailureSetting,
- * a soft failure might be converted into *rvOcsp=SECSuccess.
- * If the cached attempt to obtain OCSP information had resulted
- * in a failure, missingResponseError shows the error code of
- * that failure.
- */
-SECStatus
-ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID,
- int64 time,
- PRBool ignoreGlobalOcspFailureSetting,
- SECStatus *rvOcsp,
- SECErrorCodes *missingResponseError)
-{
- OCSPCacheItem *cacheItem = NULL;
- SECStatus rv = SECFailure;
-
- if (!certID || !missingResponseError || !rvOcsp) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- *rvOcsp = SECFailure;
- *missingResponseError = 0;
-
- PR_EnterMonitor(OCSP_Global.monitor);
- cacheItem = ocsp_FindCacheEntry(&OCSP_Global.cache, certID);
- if (cacheItem && ocsp_IsCacheItemFresh(cacheItem)) {
- /* having an arena means, we have a cached certStatus */
- if (cacheItem->certStatusArena) {
- *rvOcsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time);
- if (*rvOcsp != SECSuccess) {
- *missingResponseError = PORT_GetError();
- }
- rv = SECSuccess;
- } else {
- /*
- * No status cached, the previous attempt failed.
- * If OCSP is required, we never decide based on a failed attempt
- * However, if OCSP is optional, a recent OCSP failure is
- * an allowed good state.
- */
- if (!ignoreGlobalOcspFailureSetting &&
- OCSP_Global.ocspFailureMode ==
- ocspMode_FailureIsNotAVerificationFailure) {
- rv = SECSuccess;
- *rvOcsp = SECSuccess;
- }
- *missingResponseError = cacheItem->missingResponseError;
- }
- }
- PR_ExitMonitor(OCSP_Global.monitor);
- return rv;
-}
-
-PRBool
-ocsp_FetchingFailureIsVerificationFailure(void)
-{
- PRBool isFailure;
-
- PR_EnterMonitor(OCSP_Global.monitor);
- isFailure =
- OCSP_Global.ocspFailureMode == ocspMode_FailureIsVerificationFailure;
- PR_ExitMonitor(OCSP_Global.monitor);
- return isFailure;
-}
-
-/*
- * FUNCTION: CERT_CheckOCSPStatus
- * Checks the status of a certificate via OCSP. Will only check status for
- * a certificate that has an AIA (Authority Information Access) extension
- * for OCSP *or* when a "default responder" is specified and enabled.
- * (If no AIA extension for OCSP and no default responder in place, the
- * cert is considered to have a good status and SECSuccess is returned.)
- * INPUTS:
- * CERTCertDBHandle *handle
- * certificate DB of the cert that is being checked
- * CERTCertificate *cert
- * the certificate being checked
- * XXX in the long term also need a boolean parameter that specifies
- * whether to check the cert chain, as well; for now we check only
- * the leaf (the specified certificate)
- * int64 time
- * time for which status is to be determined
- * void *pwArg
- * argument for password prompting, if needed
- * RETURN:
- * Returns SECSuccess if an approved OCSP responder "knows" the cert
- * *and* returns a non-revoked status for it; SECFailure otherwise,
- * with an error set describing the reason:
- *
- * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE
- * SEC_ERROR_OCSP_FUTURE_RESPONSE
- * SEC_ERROR_OCSP_MALFORMED_REQUEST
- * SEC_ERROR_OCSP_MALFORMED_RESPONSE
- * SEC_ERROR_OCSP_OLD_RESPONSE
- * SEC_ERROR_OCSP_REQUEST_NEEDS_SIG
- * SEC_ERROR_OCSP_SERVER_ERROR
- * SEC_ERROR_OCSP_TRY_SERVER_LATER
- * SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST
- * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
- * SEC_ERROR_OCSP_UNKNOWN_CERT
- * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS
- * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE
- *
- * SEC_ERROR_BAD_SIGNATURE
- * SEC_ERROR_CERT_BAD_ACCESS_LOCATION
- * SEC_ERROR_INVALID_TIME
- * SEC_ERROR_REVOKED_CERTIFICATE
- * SEC_ERROR_UNKNOWN_ISSUER
- * SEC_ERROR_UNKNOWN_SIGNER
- *
- * Other errors are any of the many possible failures in cert verification
- * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
- * verifying the signer's cert, or low-level problems (error allocating
- * memory, error performing ASN.1 decoding, etc.).
- */
-SECStatus
-CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
- int64 time, void *pwArg)
-{
- CERTOCSPCertID *certID;
- PRBool certIDWasConsumed = PR_FALSE;
- SECStatus rv = SECFailure;
- SECStatus rvOcsp;
- SECErrorCodes dummy_error_code; /* we ignore this */
-
- OCSP_TRACE_CERT(cert);
- OCSP_TRACE_TIME("## requested validity time:", time);
-
- certID = CERT_CreateOCSPCertID(cert, time);
- if (!certID)
- return SECFailure;
- rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
- certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */
- &rvOcsp, &dummy_error_code);
- if (rv == SECSuccess) {
- CERT_DestroyOCSPCertID(certID);
- return rvOcsp;
- }
- rv = ocsp_GetOCSPStatusFromNetwork(handle, certID, cert, time, pwArg,
- &certIDWasConsumed,
- &rvOcsp);
- if (rv != SECSuccess) {
- /* we were unable to obtain ocsp status. Check if we should
- * return cert status revoked. */
- rvOcsp = ocsp_FetchingFailureIsVerificationFailure() ?
- SECFailure : SECSuccess;
- }
- if (!certIDWasConsumed) {
- CERT_DestroyOCSPCertID(certID);
- }
- return rvOcsp;
-}
-
-/*
- * FUNCTION: CERT_CacheOCSPResponseFromSideChannel
- * First, this function checks the OCSP cache to see if a good response
- * for the given certificate already exists. If it does, then the function
- * returns successfully.
- *
- * If not, then it validates that the given OCSP response is a valid,
- * good response for the given certificate and inserts it into the
- * cache.
- *
- * This function is intended for use when OCSP responses are provided via a
- * side-channel, i.e. TLS OCSP stapling (a.k.a. the status_request extension).
- *
- * INPUTS:
- * CERTCertDBHandle *handle
- * certificate DB of the cert that is being checked
- * CERTCertificate *cert
- * the certificate being checked
- * int64 time
- * time for which status is to be determined
- * SECItem *encodedResponse
- * the DER encoded bytes of the OCSP response
- * void *pwArg
- * argument for password prompting, if needed
- * RETURN:
- * SECSuccess if the cert was found in the cache, or if the OCSP response was
- * found to be valid and inserted into the cache. SECFailure otherwise.
- */
-SECStatus
-CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
- CERTCertificate *cert,
- int64 time,
- const SECItem *encodedResponse,
- void *pwArg)
-{
- CERTOCSPCertID *certID = NULL;
- PRBool certIDWasConsumed = PR_FALSE;
- SECStatus rv = SECFailure;
- SECStatus rvOcsp;
- SECErrorCodes dummy_error_code; /* we ignore this */
-
- /* The OCSP cache can be in three states regarding this certificate:
- * + Good (cached, timely, 'good' response, or revoked in the future)
- * + Revoked (cached, timely, but doesn't fit in the last category)
- * + Miss (no knowledge)
- *
- * Likewise, the side-channel information can be
- * + Good (timely, 'good' response, or revoked in the future)
- * + Revoked (timely, but doesn't fit in the last category)
- * + Invalid (bad syntax, bad signature, not timely etc)
- *
- * The common case is that the cache result is Good and so is the
- * side-channel information. We want to save processing time in this case
- * so we say that any time we see a Good result from the cache we return
- * early.
- *
- * Cache result
- * | Good Revoked Miss
- * ---+--------------------------------------------
- * G | noop Cache more Cache it
- * S | recent result
- * i |
- * d |
- * e |
- * R | noop Cache more Cache it
- * C | recent result
- * h |
- * a |
- * n |
- * n I | noop Noop Noop
- * e |
- * l |
- *
- * When we fetch from the network we might choose to cache a negative
- * result when the response is invalid. This saves us hammering, uselessly,
- * at a broken responder. However, side channels are commonly attacker
- * controlled and so we must not cache a negative result for an Invalid
- * side channel.
- */
-
- if (!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- certID = CERT_CreateOCSPCertID(cert, time);
- if (!certID)
- return SECFailure;
- rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
- certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */
- &rvOcsp, &dummy_error_code);
- if (rv == SECSuccess && rvOcsp == SECSuccess) {
- /* The cached value is good. We don't want to waste time validating
- * this OCSP response. This is the first column in the table above. */
- CERT_DestroyOCSPCertID(certID);
- return rv;
- }
-
- /* The logic for caching the more recent response is handled in
- * ocsp_CreateOrUpdateCacheEntry, which is called by this function. */
- rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time,
- pwArg, encodedResponse,
- PR_FALSE /* don't cache if invalid */,
- &certIDWasConsumed,
- &rvOcsp);
- if (!certIDWasConsumed) {
- CERT_DestroyOCSPCertID(certID);
- }
- return rv == SECSuccess ? rvOcsp : rv;
-}
-
-/*
- * Status in *certIDWasConsumed will always be correct, regardless of
- * return value.
- */
-static SECStatus
-ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
- CERTOCSPCertID *certID,
- CERTCertificate *cert,
- int64 time,
- void *pwArg,
- PRBool *certIDWasConsumed,
- SECStatus *rv_ocsp)
-{
- char *location = NULL;
- PRBool locationIsDefault;
- SECItem *encodedResponse = NULL;
- CERTOCSPRequest *request = NULL;
- SECStatus rv = SECFailure;
-
- if (!certIDWasConsumed || !rv_ocsp) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- *certIDWasConsumed = PR_FALSE;
- *rv_ocsp = SECFailure;
-
- /*
- * The first thing we need to do is find the location of the responder.
- * This will be the value of the default responder (if enabled), else
- * it will come out of the AIA extension in the cert (if present).
- * If we have no such location, then this cert does not "deserve" to
- * be checked -- that is, we consider it a success and just return.
- * The way we tell that is by looking at the error number to see if
- * the problem was no AIA extension was found; any other error was
- * a true failure that we unfortunately have to treat as an overall
- * failure here.
- */
- location = ocsp_GetResponderLocation(handle, cert, PR_TRUE,
- &locationIsDefault);
- if (location == NULL) {
- int err = PORT_GetError();
- if (err == SEC_ERROR_EXTENSION_NOT_FOUND ||
- err == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) {
- PORT_SetError(0);
- *rv_ocsp = SECSuccess;
- return SECSuccess;
- }
- return SECFailure;
- }
-
- /*
- * XXX In the fullness of time, we will want/need to handle a
- * certificate chain. This will be done either when a new parameter
- * tells us to, or some configuration variable tells us to. In any
- * case, handling it is complicated because we may need to send as
- * many requests (and receive as many responses) as we have certs
- * in the chain. If we are going to talk to a default responder,
- * and we only support one default responder, we can put all of the
- * certs together into one request. Otherwise, we must break them up
- * into multiple requests. (Even if all of the requests will go to
- * the same location, the signature on each response will be different,
- * because each issuer is different. Carefully read the OCSP spec
- * if you do not understand this.)
- */
-
- /*
- * XXX If/when signing of requests is supported, that second NULL
- * should be changed to be the signer certificate. Not sure if that
- * should be passed into this function or retrieved via some operation
- * on the handle/context.
- */
- encodedResponse =
- ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert, location,
- time, locationIsDefault,
- pwArg, &request);
- if (encodedResponse == NULL) {
- goto loser;
- }
-
- rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time, pwArg,
- encodedResponse,
- PR_TRUE /* cache if invalid */,
- certIDWasConsumed, rv_ocsp);
-
-loser:
- if (request != NULL)
- CERT_DestroyOCSPRequest(request);
- if (encodedResponse != NULL)
- SECITEM_FreeItem(encodedResponse, PR_TRUE);
- if (location != NULL)
- PORT_Free(location);
-
- return rv;
-}
-
-/*
- * FUNCTION: ocsp_CacheEncodedOCSPResponse
- * This function decodes an OCSP response and checks for a valid response
- * concerning the given certificate. If such a response is not found
- * then nothing is cached. Otherwise, if it is a good response, or if
- * cacheNegative is true, the results are stored in the OCSP cache.
- *
- * Note: a 'valid' response is one that parses successfully, is not an OCSP
- * exception (see RFC 2560 Section 2.3), is correctly signed and is current.
- * A 'good' response is a valid response that attests that the certificate
- * is not currently revoked (see RFC 2560 Section 2.2).
- *
- * INPUTS:
- * CERTCertDBHandle *handle
- * certificate DB of the cert that is being checked
- * CERTOCSPCertID *certID
- * the cert ID corresponding to |cert|
- * CERTCertificate *cert
- * the certificate being checked
- * int64 time
- * time for which status is to be determined
- * void *pwArg
- * the opaque argument to the password prompting function.
- * SECItem *encodedResponse
- * the DER encoded bytes of the OCSP response
- * PRBool cacheInvalid
- * If true then invalid responses will cause a negative cache entry to be
- * created. (Invalid means bad syntax, bad signature etc)
- * PRBool *certIDWasConsumed
- * (output) on return, this is true iff |certID| was consumed by this
- * function.
- * SECStatus *rv_ocsp
- * (output) on return, this is SECSuccess iff the response is good (see
- * definition of 'good' above).
- * RETURN:
- * SECSuccess iff the response is valid.
- */
-static SECStatus
-ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle,
- CERTOCSPCertID *certID,
- CERTCertificate *cert,
- int64 time,
- void *pwArg,
- const SECItem *encodedResponse,
- PRBool cacheInvalid,
- PRBool *certIDWasConsumed,
- SECStatus *rv_ocsp)
-{
- CERTOCSPResponse *response = NULL;
- CERTCertificate *signerCert = NULL;
- CERTCertificate *issuerCert = NULL;
- CERTOCSPSingleResponse *single = NULL;
- SECStatus rv = SECFailure;
-
- *certIDWasConsumed = PR_FALSE;
- *rv_ocsp = SECFailure;
-
- response = CERT_DecodeOCSPResponse(encodedResponse);
- if (response == NULL) {
- goto loser;
- }
-
- /*
- * Okay, we at least have a response that *looks* like a response!
- * Now see if the overall response status value is good or not.
- * If not, we set an error and give up. (It means that either the
- * server had a problem, or it didn't like something about our
- * request. Either way there is nothing to do but give up.)
- * Otherwise, we continue to find the actual per-cert status
- * in the response.
- */
- if (CERT_GetOCSPResponseStatus(response) != SECSuccess) {
- goto loser;
- }
-
- /*
- * If we've made it this far, we expect a response with a good signature.
- * So, check for that.
- */
- issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
- rv = CERT_VerifyOCSPResponseSignature(response, handle, pwArg, &signerCert,
- issuerCert);
- if (rv != SECSuccess)
- goto loser;
-
- PORT_Assert(signerCert != NULL); /* internal consistency check */
- /* XXX probably should set error, return failure if signerCert is null */
-
-
- /*
- * Again, we are only doing one request for one cert.
- * XXX When we handle cert chains, the following code will obviously
- * have to be modified, in coordation with the code above that will
- * have to determine how to make multiple requests, etc.
- */
-
- rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID,
- signerCert, time, &single);
- if (rv != SECSuccess)
- goto loser;
-
- *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(single, time);
-
-loser:
- /* If single == NULL here then the response was invalid. */
- if (single != NULL || cacheInvalid) {
- PR_EnterMonitor(OCSP_Global.monitor);
- if (OCSP_Global.maxCacheEntries >= 0) {
- /* single == NULL means: remember response failure */
- ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single,
- certIDWasConsumed);
- /* ignore cache update failures */
- }
- PR_ExitMonitor(OCSP_Global.monitor);
- }
-
- /* 'single' points within the response so there's no need to free it. */
-
- if (issuerCert != NULL)
- CERT_DestroyCertificate(issuerCert);
- if (signerCert != NULL)
- CERT_DestroyCertificate(signerCert);
- if (response != NULL)
- CERT_DestroyOCSPResponse(response);
- return rv;
-}
-
-static SECStatus
-ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- int64 time,
- CERTOCSPSingleResponse
- **pSingleResponse)
-{
- SECStatus rv;
- ocspResponseData *responseData;
- int64 producedAt;
- CERTOCSPSingleResponse *single;
-
- /*
- * The ResponseData part is the real guts of the response.
- */
- responseData = ocsp_GetResponseData(response, NULL);
- if (responseData == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- /*
- * There is one producedAt time for the entire response (and a separate
- * thisUpdate time for each individual single response). We need to
- * compare them, so get the overall time to pass into the check of each
- * single response.
- */
- rv = DER_GeneralizedTimeToTime(&producedAt, &responseData->producedAt);
- if (rv != SECSuccess)
- goto loser;
-
- single = ocsp_GetSingleResponseForCertID(responseData->responses,
- handle, certID);
- if (single == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = ocsp_VerifySingleResponse(single, handle, signerCert, producedAt);
- if (rv != SECSuccess)
- goto loser;
- *pSingleResponse = single;
-
-loser:
- return rv;
-}
-
-SECStatus
-CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- int64 time)
-{
- /*
- * We do not update the cache, because:
- *
- * CERT_GetOCSPStatusForCertID is an old exported API that was introduced
- * before the OCSP cache got implemented.
- *
- * The implementation of helper function cert_ProcessOCSPResponse
- * requires the ability to transfer ownership of the the given certID to
- * the cache. The external API doesn't allow us to prevent the caller from
- * destroying the certID. We don't have the original certificate available,
- * therefore we are unable to produce another certID object (that could
- * be stored in the cache).
- *
- * Should we ever implement code to produce a deep copy of certID,
- * then this could be changed to allow updating the cache.
- * The duplication would have to be done in
- * cert_ProcessOCSPResponse, if the out parameter to indicate
- * a transfer of ownership is NULL.
- */
- return cert_ProcessOCSPResponse(handle, response, certID,
- signerCert, time,
- NULL, NULL);
-}
-
-/*
- * The first 5 parameters match the definition of CERT_GetOCSPStatusForCertID.
- */
-SECStatus
-cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- int64 time,
- PRBool *certIDWasConsumed,
- SECStatus *cacheUpdateStatus)
-{
- SECStatus rv;
- SECStatus rv_cache = SECSuccess;
- CERTOCSPSingleResponse *single = NULL;
-
- rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID,
- signerCert, time, &single);
- if (rv == SECSuccess) {
- /*
- * Check whether the status says revoked, and if so
- * how that compares to the time value passed into this routine.
- */
- rv = ocsp_SingleResponseCertHasGoodStatus(single, time);
- }
-
- if (certIDWasConsumed) {
- /*
- * We don't have copy-of-certid implemented. In order to update
- * the cache, the caller must supply an out variable
- * certIDWasConsumed, allowing us to return ownership status.
- */
-
- PR_EnterMonitor(OCSP_Global.monitor);
- if (OCSP_Global.maxCacheEntries >= 0) {
- /* single == NULL means: remember response failure */
- rv_cache =
- ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID,
- single, certIDWasConsumed);
- }
- PR_ExitMonitor(OCSP_Global.monitor);
- if (cacheUpdateStatus) {
- *cacheUpdateStatus = rv_cache;
- }
- }
-
- return rv;
-}
-
-SECStatus
-cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
- PRBool *certIDWasConsumed)
-{
- SECStatus rv = SECSuccess;
- PR_EnterMonitor(OCSP_Global.monitor);
- if (OCSP_Global.maxCacheEntries >= 0) {
- rv = ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, NULL,
- certIDWasConsumed);
- }
- PR_ExitMonitor(OCSP_Global.monitor);
- return rv;
-}
-
-/*
- * Disable status checking and destroy related structures/data.
- */
-static SECStatus
-ocsp_DestroyStatusChecking(CERTStatusConfig *statusConfig)
-{
- ocspCheckingContext *statusContext;
-
- /*
- * Disable OCSP checking
- */
- statusConfig->statusChecker = NULL;
-
- statusContext = statusConfig->statusContext;
- PORT_Assert(statusContext != NULL);
- if (statusContext == NULL)
- return SECFailure;
-
- if (statusContext->defaultResponderURI != NULL)
- PORT_Free(statusContext->defaultResponderURI);
- if (statusContext->defaultResponderNickname != NULL)
- PORT_Free(statusContext->defaultResponderNickname);
-
- PORT_Free(statusContext);
- statusConfig->statusContext = NULL;
-
- PORT_Free(statusConfig);
-
- return SECSuccess;
-}
-
-
-/*
- * FUNCTION: CERT_DisableOCSPChecking
- * Turns off OCSP checking for the given certificate database.
- * This routine disables OCSP checking. Though it will return
- * SECFailure if OCSP checking is not enabled, it is "safe" to
- * call it that way and just ignore the return value, if it is
- * easier to just call it than to "remember" whether it is enabled.
- * INPUTS:
- * CERTCertDBHandle *handle
- * Certificate database for which OCSP checking will be disabled.
- * RETURN:
- * Returns SECFailure if an error occurred (usually means that OCSP
- * checking was not enabled or status contexts were not initialized --
- * error set will be SEC_ERROR_OCSP_NOT_ENABLED); SECSuccess otherwise.
- */
-SECStatus
-CERT_DisableOCSPChecking(CERTCertDBHandle *handle)
-{
- CERTStatusConfig *statusConfig;
- ocspCheckingContext *statusContext;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- statusConfig = CERT_GetStatusConfig(handle);
- statusContext = ocsp_GetCheckingContext(handle);
- if (statusContext == NULL)
- return SECFailure;
-
- if (statusConfig->statusChecker != CERT_CheckOCSPStatus) {
- /*
- * Status configuration is present, but either not currently
- * enabled or not for OCSP.
- */
- PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED);
- return SECFailure;
- }
-
- /* cache no longer necessary */
- CERT_ClearOCSPCache();
-
- /*
- * This is how we disable status checking. Everything else remains
- * in place in case we are enabled again.
- */
- statusConfig->statusChecker = NULL;
-
- return SECSuccess;
-}
-
-/*
- * Allocate and initialize the informational structures for status checking.
- * This is done when some configuration of OCSP is being done or when OCSP
- * checking is being turned on, whichever comes first.
- */
-static SECStatus
-ocsp_InitStatusChecking(CERTCertDBHandle *handle)
-{
- CERTStatusConfig *statusConfig = NULL;
- ocspCheckingContext *statusContext = NULL;
-
- PORT_Assert(CERT_GetStatusConfig(handle) == NULL);
- if (CERT_GetStatusConfig(handle) != NULL) {
- /* XXX or call statusConfig->statusDestroy and continue? */
- return SECFailure;
- }
-
- statusConfig = PORT_ZNew(CERTStatusConfig);
- if (statusConfig == NULL)
- goto loser;
-
- statusContext = PORT_ZNew(ocspCheckingContext);
- if (statusContext == NULL)
- goto loser;
-
- statusConfig->statusDestroy = ocsp_DestroyStatusChecking;
- statusConfig->statusContext = statusContext;
-
- CERT_SetStatusConfig(handle, statusConfig);
-
- return SECSuccess;
-
-loser:
- if (statusConfig != NULL)
- PORT_Free(statusConfig);
- return SECFailure;
-}
-
-
-/*
- * FUNCTION: CERT_EnableOCSPChecking
- * Turns on OCSP checking for the given certificate database.
- * INPUTS:
- * CERTCertDBHandle *handle
- * Certificate database for which OCSP checking will be enabled.
- * RETURN:
- * Returns SECFailure if an error occurred (likely only problem
- * allocating memory); SECSuccess otherwise.
- */
-SECStatus
-CERT_EnableOCSPChecking(CERTCertDBHandle *handle)
-{
- CERTStatusConfig *statusConfig;
-
- SECStatus rv;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- statusConfig = CERT_GetStatusConfig(handle);
- if (statusConfig == NULL) {
- rv = ocsp_InitStatusChecking(handle);
- if (rv != SECSuccess)
- return rv;
-
- /* Get newly established value */
- statusConfig = CERT_GetStatusConfig(handle);
- PORT_Assert(statusConfig != NULL);
- }
-
- /*
- * Setting the checker function is what really enables the checking
- * when each cert verification is done.
- */
- statusConfig->statusChecker = CERT_CheckOCSPStatus;
-
- return SECSuccess;
-}
-
-
-/*
- * FUNCTION: CERT_SetOCSPDefaultResponder
- * Specify the location and cert of the default responder.
- * If OCSP checking is already enabled *and* use of a default responder
- * is also already enabled, all OCSP checking from now on will go directly
- * to the specified responder. If OCSP checking is not enabled, or if
- * it is but use of a default responder is not enabled, the information
- * will be recorded and take effect whenever both are enabled.
- * INPUTS:
- * CERTCertDBHandle *handle
- * Cert database on which OCSP checking should use the default responder.
- * char *url
- * The location of the default responder (e.g. "http://foo.com:80/ocsp")
- * Note that the location will not be tested until the first attempt
- * to send a request there.
- * char *name
- * The nickname of the cert to trust (expected) to sign the OCSP responses.
- * If the corresponding cert cannot be found, SECFailure is returned.
- * RETURN:
- * Returns SECFailure if an error occurred; SECSuccess otherwise.
- * The most likely error is that the cert for "name" could not be found
- * (probably SEC_ERROR_UNKNOWN_CERT). Other errors are low-level (no memory,
- * bad database, etc.).
- */
-SECStatus
-CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
- const char *url, const char *name)
-{
- CERTCertificate *cert;
- ocspCheckingContext *statusContext;
- char *url_copy = NULL;
- char *name_copy = NULL;
- SECStatus rv;
-
- if (handle == NULL || url == NULL || name == NULL) {
- /*
- * XXX When interface is exported, probably want better errors;
- * perhaps different one for each parameter.
- */
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /*
- * Find the certificate for the specified nickname. Do this first
- * because it seems the most likely to fail.
- *
- * XXX Shouldn't need that cast if the FindCertByNickname interface
- * used const to convey that it does not modify the name. Maybe someday.
- */
- cert = CERT_FindCertByNickname(handle, (char *) name);
- if (cert == NULL) {
- /*
- * look for the cert on an external token.
- */
- cert = PK11_FindCertFromNickname((char *)name, NULL);
- }
- if (cert == NULL)
- return SECFailure;
-
- /*
- * Make a copy of the url and nickname.
- */
- url_copy = PORT_Strdup(url);
- name_copy = PORT_Strdup(name);
- if (url_copy == NULL || name_copy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- statusContext = ocsp_GetCheckingContext(handle);
-
- /*
- * Allocate and init the context if it doesn't already exist.
- */
- if (statusContext == NULL) {
- rv = ocsp_InitStatusChecking(handle);
- if (rv != SECSuccess)
- goto loser;
-
- statusContext = ocsp_GetCheckingContext(handle);
- PORT_Assert(statusContext != NULL); /* extreme paranoia */
- }
-
- /*
- * Note -- we do not touch the status context until after all of
- * the steps which could cause errors. If something goes wrong,
- * we want to leave things as they were.
- */
-
- /*
- * Get rid of old url and name if there.
- */
- if (statusContext->defaultResponderNickname != NULL)
- PORT_Free(statusContext->defaultResponderNickname);
- if (statusContext->defaultResponderURI != NULL)
- PORT_Free(statusContext->defaultResponderURI);
-
- /*
- * And replace them with the new ones.
- */
- statusContext->defaultResponderURI = url_copy;
- statusContext->defaultResponderNickname = name_copy;
-
- /*
- * If there was already a cert in place, get rid of it and replace it.
- * Otherwise, we are not currently enabled, so we don't want to save it;
- * it will get re-found and set whenever use of a default responder is
- * enabled.
- */
- if (statusContext->defaultResponderCert != NULL) {
- CERT_DestroyCertificate(statusContext->defaultResponderCert);
- statusContext->defaultResponderCert = cert;
- /*OCSP enabled, switching responder: clear cache*/
- CERT_ClearOCSPCache();
- } else {
- PORT_Assert(statusContext->useDefaultResponder == PR_FALSE);
- CERT_DestroyCertificate(cert);
- /*OCSP currently not enabled, no need to clear cache*/
- }
-
- return SECSuccess;
-
-loser:
- CERT_DestroyCertificate(cert);
- if (url_copy != NULL)
- PORT_Free(url_copy);
- if (name_copy != NULL)
- PORT_Free(name_copy);
- return rv;
-}
-
-
-/*
- * FUNCTION: CERT_EnableOCSPDefaultResponder
- * Turns on use of a default responder when OCSP checking.
- * If OCSP checking is already enabled, this will make subsequent checks
- * go directly to the default responder. (The location of the responder
- * and the nickname of the responder cert must already be specified.)
- * If OCSP checking is not enabled, this will be recorded and take effect
- * whenever it is enabled.
- * INPUTS:
- * CERTCertDBHandle *handle
- * Cert database on which OCSP checking should use the default responder.
- * RETURN:
- * Returns SECFailure if an error occurred; SECSuccess otherwise.
- * No errors are especially likely unless the caller did not previously
- * perform a successful call to SetOCSPDefaultResponder (in which case
- * the error set will be SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER).
- */
-SECStatus
-CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle)
-{
- ocspCheckingContext *statusContext;
- CERTCertificate *cert;
- SECStatus rv;
- SECCertificateUsage usage;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- statusContext = ocsp_GetCheckingContext(handle);
-
- if (statusContext == NULL) {
- /*
- * Strictly speaking, the error already set is "correct",
- * but cover over it with one more helpful in this context.
- */
- PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
- return SECFailure;
- }
-
- if (statusContext->defaultResponderURI == NULL) {
- PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
- return SECFailure;
- }
-
- if (statusContext->defaultResponderNickname == NULL) {
- PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
- return SECFailure;
- }
-
- /*
- * Find the cert for the nickname.
- */
- cert = CERT_FindCertByNickname(handle,
- statusContext->defaultResponderNickname);
- if (cert == NULL) {
- cert = PK11_FindCertFromNickname(statusContext->defaultResponderNickname,
- NULL);
- }
- /*
- * We should never have trouble finding the cert, because its
- * existence should have been proven by SetOCSPDefaultResponder.
- */
- PORT_Assert(cert != NULL);
- if (cert == NULL)
- return SECFailure;
-
- /*
- * Supplied cert should at least have a signing capability in order for us
- * to use it as a trusted responder cert. Ability to sign is guaranteed if
- * cert is validated to have any set of the usages below.
- */
- rv = CERT_VerifyCertificateNow(handle, cert, PR_TRUE,
- certificateUsageCheckAllUsages,
- NULL, &usage);
- if (rv != SECSuccess || (usage & (certificateUsageSSLClient |
- certificateUsageSSLServer |
- certificateUsageSSLServerWithStepUp |
- certificateUsageEmailSigner |
- certificateUsageObjectSigner |
- certificateUsageStatusResponder |
- certificateUsageSSLCA)) == 0) {
- PORT_SetError(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID);
- return SECFailure;
- }
-
- /*
- * And hang onto it.
- */
- statusContext->defaultResponderCert = cert;
-
- /* we don't allow a mix of cache entries from different responders */
- CERT_ClearOCSPCache();
-
- /*
- * Finally, record the fact that we now have a default responder enabled.
- */
- statusContext->useDefaultResponder = PR_TRUE;
- return SECSuccess;
-}
-
-
-/*
- * FUNCTION: CERT_DisableOCSPDefaultResponder
- * Turns off use of a default responder when OCSP checking.
- * (Does nothing if use of a default responder is not enabled.)
- * INPUTS:
- * CERTCertDBHandle *handle
- * Cert database on which OCSP checking should stop using a default
- * responder.
- * RETURN:
- * Returns SECFailure if an error occurred; SECSuccess otherwise.
- * Errors very unlikely (like random memory corruption...).
- */
-SECStatus
-CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle)
-{
- CERTStatusConfig *statusConfig;
- ocspCheckingContext *statusContext;
- CERTCertificate *tmpCert;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- statusConfig = CERT_GetStatusConfig(handle);
- if (statusConfig == NULL)
- return SECSuccess;
-
- statusContext = ocsp_GetCheckingContext(handle);
- PORT_Assert(statusContext != NULL);
- if (statusContext == NULL)
- return SECFailure;
-
- tmpCert = statusContext->defaultResponderCert;
- if (tmpCert) {
- statusContext->defaultResponderCert = NULL;
- CERT_DestroyCertificate(tmpCert);
- /* we don't allow a mix of cache entries from different responders */
- CERT_ClearOCSPCache();
- }
-
- /*
- * Finally, record the fact.
- */
- statusContext->useDefaultResponder = PR_FALSE;
- return SECSuccess;
-}
-
-
-SECStatus
-CERT_GetOCSPResponseStatus(CERTOCSPResponse *response)
-{
- PORT_Assert(response);
- if (response->statusValue == ocspResponse_successful)
- return SECSuccess;
-
- switch (response->statusValue) {
- case ocspResponse_malformedRequest:
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
- break;
- case ocspResponse_internalError:
- PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
- break;
- case ocspResponse_tryLater:
- PORT_SetError(SEC_ERROR_OCSP_TRY_SERVER_LATER);
- break;
- case ocspResponse_sigRequired:
- /* XXX We *should* retry with a signature, if possible. */
- PORT_SetError(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG);
- break;
- case ocspResponse_unauthorized:
- PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);
- break;
- case ocspResponse_unused:
- default:
- PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS);
- break;
- }
- return SECFailure;
-}
diff --git a/security/nss/lib/certhigh/ocsp.h b/security/nss/lib/certhigh/ocsp.h
deleted file mode 100644
index ffe21feac..000000000
--- a/security/nss/lib/certhigh/ocsp.h
+++ /dev/null
@@ -1,705 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Interface to the OCSP implementation.
- *
- * $Id$
- */
-
-#ifndef _OCSP_H_
-#define _OCSP_H_
-
-
-#include "plarena.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "keyt.h"
-#include "certt.h"
-#include "ocspt.h"
-
-
-/************************************************************************/
-SEC_BEGIN_PROTOS
-
-/*
- * This function registers the HttpClient with whose functions the
- * HttpClientFcn structure has been populated as the default Http
- * client.
- *
- * The function table must be a global object.
- * The caller must ensure that NSS will be able to call
- * the registered functions for the lifetime of the process.
- */
-extern SECStatus
-SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable);
-
-/*
- * This function obtains the HttpClient which has been registered
- * by an earlier call to SEC_RegisterDefaultHttpClient.
- */
-extern const SEC_HttpClientFcn *
-SEC_GetRegisteredHttpClient(void);
-
-/*
- * Sets parameters that control NSS' internal OCSP cache.
- * maxCacheEntries, special varlues are:
- * -1 disable cache
- * 0 unlimited cache entries
- * minimumSecondsToNextFetchAttempt:
- * whenever an OCSP request was attempted or completed over the network,
- * wait at least this number of seconds before trying to fetch again.
- * maximumSecondsToNextFetchAttempt:
- * this is the maximum age of a cached response we allow, until we try
- * to fetch an updated response, even if the OCSP responder expects
- * that newer information update will not be available yet.
- */
-extern SECStatus
-CERT_OCSPCacheSettings(PRInt32 maxCacheEntries,
- PRUint32 minimumSecondsToNextFetchAttempt,
- PRUint32 maximumSecondsToNextFetchAttempt);
-
-/*
- * Set the desired behaviour on OCSP failures.
- * See definition of ocspFailureMode for allowed choices.
- */
-extern SECStatus
-CERT_SetOCSPFailureMode(SEC_OcspFailureMode ocspFailureMode);
-
-/*
- * Configure the maximum time NSS will wait for an OCSP response.
- */
-extern SECStatus
-CERT_SetOCSPTimeout(PRUint32 seconds);
-
-/*
- * Removes all items currently stored in the OCSP cache.
- */
-extern SECStatus
-CERT_ClearOCSPCache(void);
-
-/*
- * FUNCTION: CERT_EnableOCSPChecking
- * Turns on OCSP checking for the given certificate database.
- * INPUTS:
- * CERTCertDBHandle *handle
- * Certificate database for which OCSP checking will be enabled.
- * RETURN:
- * Returns SECFailure if an error occurred (likely only problem
- * allocating memory); SECSuccess otherwise.
- */
-extern SECStatus
-CERT_EnableOCSPChecking(CERTCertDBHandle *handle);
-
-/*
- * FUNCTION: CERT_DisableOCSPChecking
- * Turns off OCSP checking for the given certificate database.
- * This routine disables OCSP checking. Though it will return
- * SECFailure if OCSP checking is not enabled, it is "safe" to
- * call it that way and just ignore the return value, if it is
- * easier to just call it than to "remember" whether it is enabled.
- * INPUTS:
- * CERTCertDBHandle *handle
- * Certificate database for which OCSP checking will be disabled.
- * RETURN:
- * Returns SECFailure if an error occurred (usually means that OCSP
- * checking was not enabled or status contexts were not initialized --
- * error set will be SEC_ERROR_OCSP_NOT_ENABLED); SECSuccess otherwise.
- */
-extern SECStatus
-CERT_DisableOCSPChecking(CERTCertDBHandle *handle);
-
-/*
- * FUNCTION: CERT_SetOCSPDefaultResponder
- * Specify the location and cert of the default responder.
- * If OCSP checking is already enabled *and* use of a default responder
- * is also already enabled, all OCSP checking from now on will go directly
- * to the specified responder. If OCSP checking is not enabled, or if
- * it is but use of a default responder is not enabled, the information
- * will be recorded and take effect whenever both are enabled.
- * INPUTS:
- * CERTCertDBHandle *handle
- * Cert database on which OCSP checking should use the default responder.
- * const char *url
- * The location of the default responder (e.g. "http://foo.com:80/ocsp")
- * Note that the location will not be tested until the first attempt
- * to send a request there.
- * const char *name
- * The nickname of the cert to trust (expected) to sign the OCSP responses.
- * If the corresponding cert cannot be found, SECFailure is returned.
- * RETURN:
- * Returns SECFailure if an error occurred; SECSuccess otherwise.
- * The most likely error is that the cert for "name" could not be found
- * (probably SEC_ERROR_UNKNOWN_CERT). Other errors are low-level (no memory,
- * bad database, etc.).
- */
-extern SECStatus
-CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
- const char *url, const char *name);
-
-/*
- * FUNCTION: CERT_EnableOCSPDefaultResponder
- * Turns on use of a default responder when OCSP checking.
- * If OCSP checking is already enabled, this will make subsequent checks
- * go directly to the default responder. (The location of the responder
- * and the nickname of the responder cert must already be specified.)
- * If OCSP checking is not enabled, this will be recorded and take effect
- * whenever it is enabled.
- * INPUTS:
- * CERTCertDBHandle *handle
- * Cert database on which OCSP checking should use the default responder.
- * RETURN:
- * Returns SECFailure if an error occurred; SECSuccess otherwise.
- * No errors are especially likely unless the caller did not previously
- * perform a successful call to SetOCSPDefaultResponder (in which case
- * the error set will be SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER).
- */
-extern SECStatus
-CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle);
-
-/*
- * FUNCTION: CERT_DisableOCSPDefaultResponder
- * Turns off use of a default responder when OCSP checking.
- * (Does nothing if use of a default responder is not enabled.)
- * INPUTS:
- * CERTCertDBHandle *handle
- * Cert database on which OCSP checking should stop using a default
- * responder.
- * RETURN:
- * Returns SECFailure if an error occurred; SECSuccess otherwise.
- * Errors very unlikely (like random memory corruption...).
- */
-extern SECStatus
-CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle);
-
-/*
- * -------------------------------------------------------
- * The Functions above are those expected to be used by a client
- * providing OCSP status checking along with every cert verification.
- * The functions below are for OCSP testing, debugging, or clients
- * or servers performing more specialized OCSP tasks.
- * -------------------------------------------------------
- */
-
-/*
- * FUNCTION: CERT_CreateOCSPRequest
- * Creates a CERTOCSPRequest, requesting the status of the certs in
- * the given list.
- * INPUTS:
- * CERTCertList *certList
- * A list of certs for which status will be requested.
- * Note that all of these certificates should have the same issuer,
- * or it's expected the response will be signed by a trusted responder.
- * If the certs need to be broken up into multiple requests, that
- * must be handled by the caller (and thus by having multiple calls
- * to this routine), who knows about where the request(s) are being
- * sent and whether there are any trusted responders in place.
- * PRTime time
- * Indicates the time for which the certificate status is to be
- * determined -- this may be used in the search for the cert's issuer
- * but has no effect on the request itself.
- * PRBool addServiceLocator
- * If true, the Service Locator extension should be added to the
- * single request(s) for each cert.
- * CERTCertificate *signerCert
- * If non-NULL, means sign the request using this cert. Otherwise,
- * do not sign.
- * XXX note that request signing is not yet supported; see comment in code
- * RETURN:
- * A pointer to a CERTOCSPRequest structure containing an OCSP request
- * for the cert list. On error, null is returned, with an error set
- * indicating the reason. This is likely SEC_ERROR_UNKNOWN_ISSUER.
- * (The issuer is needed to create a request for the certificate.)
- * Other errors are low-level problems (no memory, bad database, etc.).
- */
-extern CERTOCSPRequest *
-CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert);
-
-/*
- * FUNCTION: CERT_AddOCSPAcceptableResponses
- * Add the AcceptableResponses extension to an OCSP Request.
- * INPUTS:
- * CERTOCSPRequest *request
- * The request to which the extension should be added.
- * SECOidTag responseType0, ...
- * A list (of one or more) of SECOidTag -- each of the response types
- * to be added. The last OID *must* be SEC_OID_PKIX_OCSP_BASIC_RESPONSE.
- * (This marks the end of the list, and it must be specified because a
- * client conforming to the OCSP standard is required to handle the basic
- * response type.) The OIDs are not checked in any way.
- * RETURN:
- * SECSuccess if the extension is added; SECFailure if anything goes wrong.
- * All errors are internal or low-level problems (e.g. no memory).
- */
-extern SECStatus
-CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
- SECOidTag responseType0, ...);
-
-/*
- * FUNCTION: CERT_EncodeOCSPRequest
- * DER encodes an OCSP Request, possibly adding a signature as well.
- * XXX Signing is not yet supported, however; see comments in code.
- * INPUTS:
- * PLArenaPool *arena
- * The return value is allocated from here.
- * If a NULL is passed in, allocation is done from the heap instead.
- * CERTOCSPRequest *request
- * The request to be encoded.
- * void *pwArg
- * Pointer to argument for password prompting, if needed. (Definitely
- * not needed if not signing.)
- * RETURN:
- * Returns a NULL on error and a pointer to the SECItem with the
- * encoded value otherwise. Any error is likely to be low-level
- * (e.g. no memory).
- */
-extern SECItem *
-CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
- void *pwArg);
-
-/*
- * FUNCTION: CERT_DecodeOCSPRequest
- * Decode a DER encoded OCSP Request.
- * INPUTS:
- * SECItem *src
- * Pointer to a SECItem holding DER encoded OCSP Request.
- * RETURN:
- * Returns a pointer to a CERTOCSPRequest containing the decoded request.
- * On error, returns NULL. Most likely error is trouble decoding
- * (SEC_ERROR_OCSP_MALFORMED_REQUEST), or low-level problem (no memory).
- */
-extern CERTOCSPRequest *
-CERT_DecodeOCSPRequest(const SECItem *src);
-
-/*
- * FUNCTION: CERT_DestroyOCSPRequest
- * Frees an OCSP Request structure.
- * INPUTS:
- * CERTOCSPRequest *request
- * Pointer to CERTOCSPRequest to be freed.
- * RETURN:
- * No return value; no errors.
- */
-extern void
-CERT_DestroyOCSPRequest(CERTOCSPRequest *request);
-
-/*
- * FUNCTION: CERT_DecodeOCSPResponse
- * Decode a DER encoded OCSP Response.
- * INPUTS:
- * SECItem *src
- * Pointer to a SECItem holding DER encoded OCSP Response.
- * RETURN:
- * Returns a pointer to a CERTOCSPResponse (the decoded OCSP Response);
- * the caller is responsible for destroying it. Or NULL if error (either
- * response could not be decoded (SEC_ERROR_OCSP_MALFORMED_RESPONSE),
- * it was of an unexpected type (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE),
- * or a low-level or internal error occurred).
- */
-extern CERTOCSPResponse *
-CERT_DecodeOCSPResponse(const SECItem *src);
-
-/*
- * FUNCTION: CERT_DestroyOCSPResponse
- * Frees an OCSP Response structure.
- * INPUTS:
- * CERTOCSPResponse *request
- * Pointer to CERTOCSPResponse to be freed.
- * RETURN:
- * No return value; no errors.
- */
-extern void
-CERT_DestroyOCSPResponse(CERTOCSPResponse *response);
-
-/*
- * FUNCTION: CERT_GetEncodedOCSPResponse
- * Creates and sends a request to an OCSP responder, then reads and
- * returns the (encoded) response.
- * INPUTS:
- * PLArenaPool *arena
- * Pointer to arena from which return value will be allocated.
- * If NULL, result will be allocated from the heap (and thus should
- * be freed via SECITEM_FreeItem).
- * CERTCertList *certList
- * A list of certs for which status will be requested.
- * Note that all of these certificates should have the same issuer,
- * or it's expected the response will be signed by a trusted responder.
- * If the certs need to be broken up into multiple requests, that
- * must be handled by the caller (and thus by having multiple calls
- * to this routine), who knows about where the request(s) are being
- * sent and whether there are any trusted responders in place.
- * const char *location
- * The location of the OCSP responder (a URL).
- * PRTime time
- * Indicates the time for which the certificate status is to be
- * determined -- this may be used in the search for the cert's issuer
- * but has no other bearing on the operation.
- * PRBool addServiceLocator
- * If true, the Service Locator extension should be added to the
- * single request(s) for each cert.
- * CERTCertificate *signerCert
- * If non-NULL, means sign the request using this cert. Otherwise,
- * do not sign.
- * void *pwArg
- * Pointer to argument for password prompting, if needed. (Definitely
- * not needed if not signing.)
- * OUTPUTS:
- * CERTOCSPRequest **pRequest
- * Pointer in which to store the OCSP request created for the given
- * list of certificates. It is only filled in if the entire operation
- * is successful and the pointer is not null -- and in that case the
- * caller is then reponsible for destroying it.
- * RETURN:
- * Returns a pointer to the SECItem holding the response.
- * On error, returns null with error set describing the reason:
- * SEC_ERROR_UNKNOWN_ISSUER
- * SEC_ERROR_CERT_BAD_ACCESS_LOCATION
- * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE
- * Other errors are low-level problems (no memory, bad database, etc.).
- */
-extern SECItem *
-CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
- const char *location, PRTime time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert, void *pwArg,
- CERTOCSPRequest **pRequest);
-
-/*
- * FUNCTION: CERT_VerifyOCSPResponseSignature
- * Check the signature on an OCSP Response. Will also perform a
- * verification of the signer's certificate. Note, however, that a
- * successful verification does not make any statement about the
- * signer's *authority* to provide status for the certificate(s),
- * that must be checked individually for each certificate.
- * INPUTS:
- * CERTOCSPResponse *response
- * Pointer to response structure with signature to be checked.
- * CERTCertDBHandle *handle
- * Pointer to CERTCertDBHandle for certificate DB to use for verification.
- * void *pwArg
- * Pointer to argument for password prompting, if needed.
- * CERTCertificate *issuerCert
- * Issuer of the certificate that generated the OCSP request.
- * OUTPUTS:
- * CERTCertificate **pSignerCert
- * Pointer in which to store signer's certificate; only filled-in if
- * non-null.
- * RETURN:
- * Returns SECSuccess when signature is valid, anything else means invalid.
- * Possible errors set:
- * SEC_ERROR_OCSP_MALFORMED_RESPONSE - unknown type of ResponderID
- * SEC_ERROR_INVALID_TIME - bad format of "ProducedAt" time
- * SEC_ERROR_UNKNOWN_SIGNER - signer's cert could not be found
- * SEC_ERROR_BAD_SIGNATURE - the signature did not verify
- * Other errors are any of the many possible failures in cert verification
- * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
- * verifying the signer's cert, or low-level problems (no memory, etc.)
- */
-extern SECStatus
-CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
- CERTCertDBHandle *handle, void *pwArg,
- CERTCertificate **pSignerCert,
- CERTCertificate *issuerCert);
-
-/*
- * FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
- * Get the value of the URI of the OCSP responder for the given cert.
- * This is found in the (optional) Authority Information Access extension
- * in the cert.
- * INPUTS:
- * CERTCertificate *cert
- * The certificate being examined.
- * RETURN:
- * char *
- * A copy of the URI for the OCSP method, if found. If either the
- * extension is not present or it does not contain an entry for OCSP,
- * SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned.
- * Any other error will also result in a NULL being returned.
- *
- * This result should be freed (via PORT_Free) when no longer in use.
- */
-extern char *
-CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert);
-
-/*
- * FUNCTION: CERT_RegisterAlternateOCSPAIAInfoCallBack
- * This function serves two purposes.
- * 1) It registers the address of a callback function that will be
- * called for certs that have no OCSP AIA extension, to see if the
- * callback wishes to supply an alternative URL for such an OCSP inquiry.
- * 2) It outputs the previously registered function's address to the
- * address supplied by the caller, unless that is NULL.
- * The registered callback function returns NULL, or an allocated string
- * that may be subsequently freed by calling PORT_Free().
- * RETURN:
- * SECSuccess or SECFailure (if the library is not yet intialized)
- */
-extern SECStatus
-CERT_RegisterAlternateOCSPAIAInfoCallBack(
- CERT_StringFromCertFcn newCallback,
- CERT_StringFromCertFcn * oldCallback);
-
-/*
- * FUNCTION: CERT_ParseURL
- * Parse a URI into hostname, port, and path. The scheme in the URI must
- * be "http".
- * INPUTS:
- * const char *url
- * The URI to be parsed
- * OUTPUTS:
- * char **pHostname
- * Pointer to store the hostname obtained from the URI.
- * This result should be freed (via PORT_Free) when no longer in use.
- * PRUint16 *pPort
- * Pointer to store the port number obtained from the URI.
- * char **pPath
- * Pointer to store the path obtained from the URI.
- * This result should be freed (via PORT_Free) when no longer in use.
- * RETURN:
- * Returns SECSuccess when parsing was successful. Returns SECFailure when
- * problems were encountered.
- */
-extern SECStatus
-CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath);
-
-/*
- * FUNCTION: CERT_CheckOCSPStatus
- * Checks the status of a certificate via OCSP. Will only check status for
- * a certificate that has an AIA (Authority Information Access) extension
- * for OCSP *or* when a "default responder" is specified and enabled.
- * (If no AIA extension for OCSP and no default responder in place, the
- * cert is considered to have a good status and SECSuccess is returned.)
- * INPUTS:
- * CERTCertDBHandle *handle
- * certificate DB of the cert that is being checked
- * CERTCertificate *cert
- * the certificate being checked
- * XXX in the long term also need a boolean parameter that specifies
- * whether to check the cert chain, as well; for now we check only
- * the leaf (the specified certificate)
- * PRTime time
- * time for which status is to be determined
- * void *pwArg
- * argument for password prompting, if needed
- * RETURN:
- * Returns SECSuccess if an approved OCSP responder "knows" the cert
- * *and* returns a non-revoked status for it; SECFailure otherwise,
- * with an error set describing the reason:
- *
- * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE
- * SEC_ERROR_OCSP_FUTURE_RESPONSE
- * SEC_ERROR_OCSP_MALFORMED_REQUEST
- * SEC_ERROR_OCSP_MALFORMED_RESPONSE
- * SEC_ERROR_OCSP_OLD_RESPONSE
- * SEC_ERROR_OCSP_REQUEST_NEEDS_SIG
- * SEC_ERROR_OCSP_SERVER_ERROR
- * SEC_ERROR_OCSP_TRY_SERVER_LATER
- * SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST
- * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
- * SEC_ERROR_OCSP_UNKNOWN_CERT
- * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS
- * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE
- *
- * SEC_ERROR_BAD_SIGNATURE
- * SEC_ERROR_CERT_BAD_ACCESS_LOCATION
- * SEC_ERROR_INVALID_TIME
- * SEC_ERROR_REVOKED_CERTIFICATE
- * SEC_ERROR_UNKNOWN_ISSUER
- * SEC_ERROR_UNKNOWN_SIGNER
- *
- * Other errors are any of the many possible failures in cert verification
- * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
- * verifying the signer's cert, or low-level problems (error allocating
- * memory, error performing ASN.1 decoding, etc.).
- */
-extern SECStatus
-CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRTime time, void *pwArg);
-
-/*
- * FUNCTION: CERT_CacheOCSPResponseFromSideChannel
- * First, this function checks the OCSP cache to see if a good response
- * for the given certificate already exists. If it does, then the function
- * returns successfully.
- *
- * If not, then it validates that the given OCSP response is a valid,
- * good response for the given certificate and inserts it into the
- * cache.
- *
- * This function is intended for use when OCSP responses are provided via a
- * side-channel, i.e. TLS OCSP stapling (a.k.a. the status_request extension).
- *
- * INPUTS:
- * CERTCertDBHandle *handle
- * certificate DB of the cert that is being checked
- * CERTCertificate *cert
- * the certificate being checked
- * PRTime time
- * time for which status is to be determined
- * SECItem *encodedResponse
- * the DER encoded bytes of the OCSP response
- * void *pwArg
- * argument for password prompting, if needed
- * RETURN:
- * SECSuccess if the cert was found in the cache, or if the OCSP response was
- * found to be valid and inserted into the cache. SECFailure otherwise.
- */
-extern SECStatus
-CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
- CERTCertificate *cert,
- PRTime time,
- const SECItem *encodedResponse,
- void *pwArg);
-
-/*
- * FUNCTION: CERT_GetOCSPStatusForCertID
- * Returns the OCSP status contained in the passed in parameter response
- * that corresponds to the certID passed in.
- * INPUTS:
- * CERTCertDBHandle *handle
- * certificate DB of the cert that is being checked
- * CERTOCSPResponse *response
- * the OCSP response we want to retrieve status from.
- * CERTOCSPCertID *certID
- * the ID we want to look for from the response.
- * CERTCertificate *signerCert
- * the certificate that was used to sign the OCSP response.
- * must be obtained via a call to CERT_VerifyOCSPResponseSignature.
- * PRTime time
- * The time at which we're checking the status for.
- * RETURN:
- * Return values are the same as those for CERT_CheckOCSPStatus
- */
-extern SECStatus
-CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- PRTime time);
-
-/*
- * FUNCTION CERT_GetOCSPResponseStatus
- * Returns the response status for the response passed.
- * INPUTS:
- * CERTOCSPResponse *response
- * The response to query for status
- * RETURN:
- * Returns SECSuccess if the response has a successful status value.
- * Otherwise it returns SECFailure and sets one of the following error
- * codes via PORT_SetError
- * SEC_ERROR_OCSP_MALFORMED_REQUEST
- * SEC_ERROR_OCSP_SERVER_ERROR
- * SEC_ERROR_OCSP_TRY_SERVER_LATER
- * SEC_ERROR_OCSP_REQUEST_NEEDS_SIG
- * SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST
- * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS
- */
-extern SECStatus
-CERT_GetOCSPResponseStatus(CERTOCSPResponse *response);
-
-/*
- * FUNCTION CERT_CreateOCSPCertID
- * Returns the OCSP certID for the certificate passed in.
- * INPUTS:
- * CERTCertificate *cert
- * The certificate for which to create the certID for.
- * PRTime time
- * The time at which the id is requested for. This is used
- * to determine the appropriate issuer for the cert since
- * the issuing CA may be an older expired certificate.
- * RETURN:
- * A new copy of a CERTOCSPCertID*. The memory for this certID
- * should be freed by calling CERT_DestroyOCSPCertID when the
- * certID is no longer necessary.
- */
-extern CERTOCSPCertID*
-CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
-
-/*
- * FUNCTION: CERT_DestroyOCSPCertID
- * Frees the memory associated with the certID passed in.
- * INPUTS:
- * CERTOCSPCertID* certID
- * The certID that the caller no longer needs and wants to
- * free the associated memory.
- * RETURN:
- * SECSuccess if freeing the memory was successful. Returns
- * SECFailure if the memory passed in was not allocated with
- * a call to CERT_CreateOCSPCertID.
- */
-extern SECStatus
-CERT_DestroyOCSPCertID(CERTOCSPCertID* certID);
-
-
-extern CERTOCSPSingleResponse*
-CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
- CERTOCSPCertID *id,
- PRTime thisUpdate,
- const PRTime *nextUpdate);
-
-extern CERTOCSPSingleResponse*
-CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
- CERTOCSPCertID *id,
- PRTime thisUpdate,
- const PRTime *nextUpdate);
-
-extern CERTOCSPSingleResponse*
-CERT_CreateOCSPSingleResponseRevoked(
- PLArenaPool *arena,
- CERTOCSPCertID *id,
- PRTime thisUpdate,
- const PRTime *nextUpdate,
- PRTime revocationTime,
- const CERTCRLEntryReasonCode* revocationReason);
-
-extern SECItem*
-CERT_CreateEncodedOCSPSuccessResponse(
- PLArenaPool *arena,
- CERTCertificate *responderCert,
- CERTOCSPResponderIDType responderIDType,
- PRTime producedAt,
- CERTOCSPSingleResponse **responses,
- void *wincx);
-
-/*
- * FUNCTION: CERT_CreateEncodedOCSPErrorResponse
- * Creates an encoded OCSP response with an error response status.
- * INPUTS:
- * PLArenaPool *arena
- * The return value is allocated from here.
- * If a NULL is passed in, allocation is done from the heap instead.
- * int error
- * An NSS error code indicating an error response status. The error
- * code is mapped to an OCSP response status as follows:
- * SEC_ERROR_OCSP_MALFORMED_REQUEST -> malformedRequest
- * SEC_ERROR_OCSP_SERVER_ERROR -> internalError
- * SEC_ERROR_OCSP_TRY_SERVER_LATER -> tryLater
- * SEC_ERROR_OCSP_REQUEST_NEEDS_SIG -> sigRequired
- * SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST -> unauthorized
- * where the OCSP response status is an enumerated type defined in
- * RFC 2560:
- * OCSPResponseStatus ::= ENUMERATED {
- * successful (0), --Response has valid confirmations
- * malformedRequest (1), --Illegal confirmation request
- * internalError (2), --Internal error in issuer
- * tryLater (3), --Try again later
- * --(4) is not used
- * sigRequired (5), --Must sign the request
- * unauthorized (6) --Request unauthorized
- * }
- * RETURN:
- * Returns a pointer to the SECItem holding the response.
- * On error, returns null with error set describing the reason:
- * SEC_ERROR_INVALID_ARGS
- * Other errors are low-level problems (no memory, bad database, etc.).
- */
-extern SECItem*
-CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error);
-
-/************************************************************************/
-SEC_END_PROTOS
-
-#endif /* _OCSP_H_ */
diff --git a/security/nss/lib/certhigh/ocspi.h b/security/nss/lib/certhigh/ocspi.h
deleted file mode 100644
index 91d618557..000000000
--- a/security/nss/lib/certhigh/ocspi.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * ocspi.h - NSS internal interfaces to OCSP code
- *
- * $Id$
- */
-
-#ifndef _OCSPI_H_
-#define _OCSPI_H_
-
-SECStatus OCSP_InitGlobal(void);
-SECStatus OCSP_ShutdownGlobal(void);
-
-ocspResponseData *
-ocsp_GetResponseData(CERTOCSPResponse *response, SECItem **tbsResponseDataDER);
-
-ocspSignature *
-ocsp_GetResponseSignature(CERTOCSPResponse *response);
-
-SECItem *
-ocsp_DigestValue(PRArenaPool *arena, SECOidTag digestAlg,
- SECItem *fill, const SECItem *src);
-
-PRBool
-ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert);
-
-CERTCertificate *
-ocsp_GetSignerCertificate(CERTCertDBHandle *handle, ocspResponseData *tbsData,
- ocspSignature *signature, CERTCertificate *issuer);
-
-SECStatus
-ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
- ocspSignature *signature,
- SECItem *tbsResponseDataDER,
- void *pwArg);
-
-CERTOCSPRequest *
-cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
- CERTCertificate *singleCert,
- int64 time,
- PRBool addServiceLocator,
- CERTCertificate *signerCert);
-
-SECStatus
-ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID,
- int64 time,
- PRBool ignoreOcspFailureMode,
- SECStatus *rvOcsp,
- SECErrorCodes *missingResponseError);
-
-/*
- * FUNCTION: cert_ProcessOCSPResponse
- * Same behavior and basic parameters as CERT_GetOCSPStatusForCertID.
- * In addition it can update the OCSP cache (using information
- * available internally to this function).
- * INPUTS:
- * CERTCertDBHandle *handle
- * certificate DB of the cert that is being checked
- * CERTOCSPResponse *response
- * the OCSP response we want to retrieve status from.
- * CERTOCSPCertID *certID
- * the ID we want to look for from the response.
- * CERTCertificate *signerCert
- * the certificate that was used to sign the OCSP response.
- * must be obtained via a call to CERT_VerifyOCSPResponseSignature.
- * int64 time
- * The time at which we're checking the status for.
- * PRBool *certIDWasConsumed
- * In and Out parameter.
- * If certIDWasConsumed is NULL on input,
- * this function might produce a deep copy of cert ID
- * for storing it in the cache.
- * If out value is true, ownership of parameter certID was
- * transferred to the OCSP cache.
- * SECStatus *cacheUpdateStatus
- * This optional out parameter will contain the result
- * of the cache update operation (if requested).
- * RETURN:
- * The return value is not influenced by the cache operation,
- * it matches the documentation for CERT_CheckOCSPStatus
- */
-
-SECStatus
-cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
- CERTOCSPResponse *response,
- CERTOCSPCertID *certID,
- CERTCertificate *signerCert,
- int64 time,
- PRBool *certIDWasConsumed,
- SECStatus *cacheUpdateStatus);
-
-/*
- * FUNCTION: cert_RememberOCSPProcessingFailure
- * If an application notices a failure during OCSP processing,
- * it should finally call this function. The failure will be recorded
- * in the OCSP cache in order to avoid repetitive failures.
- * INPUTS:
- * CERTOCSPCertID *certID
- * the ID that was used for the failed OCSP processing
- * PRBool *certIDWasConsumed
- * Out parameter, if set to true, ownership of parameter certID was
- * transferred to the OCSP cache.
- * RETURN:
- * Status of the cache update operation.
- */
-
-SECStatus
-cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
- PRBool *certIDWasConsumed);
-
-/*
- * FUNCTION: ocsp_GetResponderLocation
- * Check ocspx context for user-designated responder URI first. If not
- * found, checks cert AIA extension.
- * INPUTS:
- * CERTCertDBHandle *handle
- * certificate DB of the cert that is being checked
- * CERTCertificate *cert
- * The certificate being examined.
- * PRBool *certIDWasConsumed
- * Out parameter, if set to true, URI of default responder is
- * returned.
- * RETURN:
- * Responder URI.
- */
-char *
-ocsp_GetResponderLocation(CERTCertDBHandle *handle,
- CERTCertificate *cert,
- PRBool canUseDefaultLocation,
- PRBool *isDefault);
-
-/* FUNCTION: ocsp_FetchingFailureIsVerificationFailure
- * The function checks the global ocsp settings and
- * tells how to treat an ocsp response fetching failure.
- * RETURNS:
- * if PR_TRUE is returned, then treat fetching as a
- * revoked cert status.
- */
-PRBool
-ocsp_FetchingFailureIsVerificationFailure(void);
-
-#endif /* _OCSPI_H_ */
diff --git a/security/nss/lib/certhigh/ocspsig.c b/security/nss/lib/certhigh/ocspsig.c
deleted file mode 100644
index 775c12411..000000000
--- a/security/nss/lib/certhigh/ocspsig.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "plarena.h"
-
-#include "seccomon.h"
-#include "secitem.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "cert.h"
-#include "secerr.h"
-#include "secoid.h"
-#include "sechash.h"
-#include "keyhi.h"
-#include "cryptohi.h"
-#include "ocsp.h"
-#include "ocspti.h"
-#include "ocspi.h"
-#include "pk11pub.h"
-
-
-extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[];
-extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[];
-extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[];
-
-ocspCertStatus*
-ocsp_CreateCertStatus(PLArenaPool *arena,
- ocspCertStatusType status,
- PRTime revocationTime)
-{
- ocspCertStatus *cs;
-
- if (!arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- switch (status) {
- case ocspCertStatus_good:
- case ocspCertStatus_unknown:
- case ocspCertStatus_revoked:
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- cs = PORT_ArenaZNew(arena, ocspCertStatus);
- if (!cs)
- return NULL;
- cs->certStatusType = status;
- switch (status) {
- case ocspCertStatus_good:
- cs->certStatusInfo.goodInfo = SECITEM_AllocItem(arena, NULL, 0);
- if (!cs->certStatusInfo.goodInfo)
- return NULL;
- break;
- case ocspCertStatus_unknown:
- cs->certStatusInfo.unknownInfo = SECITEM_AllocItem(arena, NULL, 0);
- if (!cs->certStatusInfo.unknownInfo)
- return NULL;
- break;
- case ocspCertStatus_revoked:
- cs->certStatusInfo.revokedInfo =
- PORT_ArenaZNew(arena, ocspRevokedInfo);
- if (!cs->certStatusInfo.revokedInfo)
- return NULL;
- cs->certStatusInfo.revokedInfo->revocationReason =
- SECITEM_AllocItem(arena, NULL, 0);
- if (!cs->certStatusInfo.revokedInfo->revocationReason)
- return NULL;
- if (DER_TimeToGeneralizedTimeArena(arena,
- &cs->certStatusInfo.revokedInfo->revocationTime,
- revocationTime) != SECSuccess)
- return NULL;
- break;
- default:
- PORT_Assert(PR_FALSE);
- }
- return cs;
-}
-
-static const SEC_ASN1Template mySEC_EnumeratedTemplate[] = {
- { SEC_ASN1_ENUMERATED, 0, NULL, sizeof(SECItem) }
-};
-
-static const SEC_ASN1Template mySEC_PointerToEnumeratedTemplate[] = {
- { SEC_ASN1_POINTER, 0, mySEC_EnumeratedTemplate }
-};
-
-static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = {
- { SEC_ASN1_GENERALIZED_TIME,
- offsetof(ocspRevokedInfo, revocationTime) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC| 0,
- offsetof(ocspRevokedInfo, revocationReason),
- mySEC_PointerToEnumeratedTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template ocsp_PointerToEncodeRevokedInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0,
- ocsp_EncodeRevokedInfoTemplate }
-};
-
-static const SEC_ASN1Template mySEC_NullTemplate[] = {
- { SEC_ASN1_NULL, 0, NULL, sizeof(SECItem) }
-};
-
-static const SEC_ASN1Template ocsp_CertStatusTemplate[] = {
- { SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType),
- 0, sizeof(ocspCertStatus) },
- { SEC_ASN1_CONTEXT_SPECIFIC | 0,
- 0, mySEC_NullTemplate, ocspCertStatus_good },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
- ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked },
- { SEC_ASN1_CONTEXT_SPECIFIC | 2,
- 0, mySEC_NullTemplate, ocspCertStatus_unknown },
- { 0 }
-};
-
-static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECAlgorithmID) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
-};
-
-static const SEC_ASN1Template mySEC_AnyTemplate[] = {
- { SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
-};
-
-static const SEC_ASN1Template mySEC_SequenceOfAnyTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, mySEC_AnyTemplate }
-};
-
-static const SEC_ASN1Template mySEC_PointerToSequenceOfAnyTemplate[] = {
- { SEC_ASN1_POINTER, 0, mySEC_SequenceOfAnyTemplate }
-};
-
-static const SEC_ASN1Template mySEC_IntegerTemplate[] = {
- { SEC_ASN1_INTEGER, 0, NULL, sizeof(SECItem) }
-};
-
-static const SEC_ASN1Template mySEC_PointerToIntegerTemplate[] = {
- { SEC_ASN1_POINTER, 0, mySEC_IntegerTemplate }
-};
-
-static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = {
- { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
-};
-
-static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
- { SEC_ASN1_POINTER, 0, mySEC_GeneralizedTimeTemplate }
-};
-
-static const SEC_ASN1Template ocsp_myCertIDTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPCertID) },
- { SEC_ASN1_INLINE,
- offsetof(CERTOCSPCertID, hashAlgorithm),
- mySECOID_AlgorithmIDTemplate },
- { SEC_ASN1_OCTET_STRING,
- offsetof(CERTOCSPCertID, issuerNameHash) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(CERTOCSPCertID, issuerKeyHash) },
- { SEC_ASN1_INTEGER,
- offsetof(CERTOCSPCertID, serialNumber) },
- { 0 }
-};
-
-static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTCertExtension) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CERTCertExtension,id) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
- offsetof(CERTCertExtension,critical) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(CERTCertExtension,value) },
- { 0, }
-};
-
-static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, myCERT_CertExtensionTemplate }
-};
-
-static const SEC_ASN1Template myCERT_PointerToSequenceOfCertExtensionTemplate[] = {
- { SEC_ASN1_POINTER, 0, myCERT_SequenceOfCertExtensionTemplate }
-};
-
-static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPSingleResponse) },
- { SEC_ASN1_POINTER,
- offsetof(CERTOCSPSingleResponse, certID),
- ocsp_myCertIDTemplate },
- { SEC_ASN1_ANY,
- offsetof(CERTOCSPSingleResponse, derCertStatus) },
- { SEC_ASN1_GENERALIZED_TIME,
- offsetof(CERTOCSPSingleResponse, thisUpdate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(CERTOCSPSingleResponse, nextUpdate),
- mySEC_PointerToGeneralizedTimeTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(CERTOCSPSingleResponse, singleExtensions),
- myCERT_PointerToSequenceOfCertExtensionTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template ocsp_myResponseDataTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspResponseData) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(ocspResponseData, version),
- mySEC_PointerToIntegerTemplate },
- { SEC_ASN1_ANY,
- offsetof(ocspResponseData, derResponderID) },
- { SEC_ASN1_GENERALIZED_TIME,
- offsetof(ocspResponseData, producedAt) },
- { SEC_ASN1_SEQUENCE_OF,
- offsetof(ocspResponseData, responses),
- ocsp_mySingleResponseTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(ocspResponseData, responseExtensions),
- myCERT_PointerToSequenceOfCertExtensionTemplate },
- { 0 }
-};
-
-
-static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(ocspBasicOCSPResponse) },
- { SEC_ASN1_POINTER,
- offsetof(ocspBasicOCSPResponse, tbsResponseData),
- ocsp_myResponseDataTemplate },
- { SEC_ASN1_INLINE,
- offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
- mySECOID_AlgorithmIDTemplate },
- { SEC_ASN1_BIT_STRING,
- offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
- mySEC_PointerToSequenceOfAnyTemplate },
- { 0 }
-};
-
-static CERTOCSPSingleResponse*
-ocsp_CreateSingleResponse(PLArenaPool *arena,
- CERTOCSPCertID *id, ocspCertStatus *status,
- PRTime thisUpdate, const PRTime *nextUpdate)
-{
- CERTOCSPSingleResponse *sr;
-
- if (!arena || !id || !status) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- sr = PORT_ArenaZNew(arena, CERTOCSPSingleResponse);
- if (!sr)
- return NULL;
- sr->arena = arena;
- sr->certID = id;
- sr->certStatus = status;
- if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate)
- != SECSuccess)
- return NULL;
- sr->nextUpdate = NULL;
- if (nextUpdate) {
- sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0);
- if (!sr->nextUpdate)
- return NULL;
- if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate)
- != SECSuccess)
- return NULL;
- }
-
- sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension*, 1);
- if (!sr->singleExtensions)
- return NULL;
-
- sr->singleExtensions[0] = NULL;
-
- if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus,
- status, ocsp_CertStatusTemplate))
- return NULL;
-
- return sr;
-}
-
-CERTOCSPSingleResponse*
-CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
- CERTOCSPCertID *id,
- PRTime thisUpdate,
- const PRTime *nextUpdate)
-{
- ocspCertStatus * cs;
- if (!arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- cs = ocsp_CreateCertStatus(arena, ocspCertStatus_good, 0);
- if (!cs)
- return NULL;
- return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
-}
-
-CERTOCSPSingleResponse*
-CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
- CERTOCSPCertID *id,
- PRTime thisUpdate,
- const PRTime *nextUpdate)
-{
- ocspCertStatus * cs;
- if (!arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- cs = ocsp_CreateCertStatus(arena, ocspCertStatus_unknown, 0);
- if (!cs)
- return NULL;
- return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
-}
-
-CERTOCSPSingleResponse*
-CERT_CreateOCSPSingleResponseRevoked(
- PLArenaPool *arena,
- CERTOCSPCertID *id,
- PRTime thisUpdate,
- const PRTime *nextUpdate,
- PRTime revocationTime,
- const CERTCRLEntryReasonCode* revocationReason)
-{
- ocspCertStatus * cs;
- /* revocationReason is not yet supported, so it must be NULL. */
- if (!arena || revocationReason) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- cs = ocsp_CreateCertStatus(arena, ocspCertStatus_revoked, revocationTime);
- if (!cs)
- return NULL;
- return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
-}
-
-/* responderCert == 0 means:
- * create a response with an invalid signature (for testing purposes) */
-SECItem*
-CERT_CreateEncodedOCSPSuccessResponse(
- PLArenaPool *arena,
- CERTCertificate *responderCert,
- CERTOCSPResponderIDType responderIDType,
- PRTime producedAt,
- CERTOCSPSingleResponse **responses,
- void *wincx)
-{
- PLArenaPool *tmpArena;
- ocspResponseData *rd = NULL;
- ocspResponderID *rid = NULL;
- const SEC_ASN1Template *responderIDTemplate = NULL;
- ocspBasicOCSPResponse *br = NULL;
- ocspResponseBytes *rb = NULL;
- CERTOCSPResponse *response = NULL;
-
- SECOidTag algID;
- SECOidData *od = NULL;
- SECKEYPrivateKey *privKey = NULL;
- SECItem *result = NULL;
-
- if (!arena || !responses) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- if (responderIDType != ocspResponderID_byName &&
- responderIDType != ocspResponderID_byKey) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!tmpArena)
- return NULL;
-
- rd = PORT_ArenaZNew(tmpArena, ocspResponseData);
- if (!rd)
- goto done;
- rid = PORT_ArenaZNew(tmpArena, ocspResponderID);
- if (!rid)
- goto done;
- br = PORT_ArenaZNew(tmpArena, ocspBasicOCSPResponse);
- if (!br)
- goto done;
- rb = PORT_ArenaZNew(tmpArena, ocspResponseBytes);
- if (!rb)
- goto done;
- response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse);
- if (!response)
- goto done;
-
- rd->version.data=NULL;
- rd->version.len=0;
- rd->responseExtensions = NULL;
- rd->responses = responses;
- if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt)
- != SECSuccess)
- goto done;
-
- if (!responderCert) {
- /* use invalid signature for testing purposes */
- char dummyChar = 'd';
- SECItem dummy;
-
- dummy.len = 1;
- dummy.data = &dummyChar;
-
- /* it's easier to produdce a keyHash out of nowhere,
- * than to produce an encoded subject,
- * so for our dummy response we always use byKey
- */
-
- rid->responderIDType = ocspResponderID_byKey;
- if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash,
- &dummy))
- goto done;
-
- if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
- ocsp_ResponderIDByKeyTemplate))
- goto done;
-
- br->tbsResponseData = rd;
-
- if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
- ocsp_myResponseDataTemplate))
- goto done;
-
- br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1);
- if (!br->responseSignature.derCerts)
- goto done;
- br->responseSignature.derCerts[0] = NULL;
-
- algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1);
- if (algID == SEC_OID_UNKNOWN)
- goto done;
-
- /* match the regular signature code, which doesn't use the arena */
- if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1))
- goto done;
- PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1);
-
- /* convert len-in-bytes to len-in-bits */
- br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
- }
- else {
- rid->responderIDType = responderIDType;
- if (responderIDType == ocspResponderID_byName) {
- responderIDTemplate = ocsp_ResponderIDByNameTemplate;
- if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
- &responderCert->subject) != SECSuccess)
- goto done;
- }
- else {
- responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
- if (!CERT_GetSPKIDigest(tmpArena, responderCert, SEC_OID_SHA1,
- &rid->responderIDValue.keyHash))
- goto done;
- }
-
- if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
- responderIDTemplate))
- goto done;
-
- br->tbsResponseData = rd;
-
- if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
- ocsp_myResponseDataTemplate))
- goto done;
-
- br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1);
- if (!br->responseSignature.derCerts)
- goto done;
- br->responseSignature.derCerts[0] = NULL;
-
- privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
- if (!privKey)
- goto done;
-
- algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
- if (algID == SEC_OID_UNKNOWN)
- goto done;
-
- if (SEC_SignData(&br->responseSignature.signature,
- br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
- privKey, algID)
- != SECSuccess)
- goto done;
-
- /* convert len-in-bytes to len-in-bits */
- br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
-
- /* br->responseSignature.signature wasn't allocated from arena,
- * we must free it when done. */
- }
-
- if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0)
- != SECSuccess)
- goto done;
-
- if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br,
- ocsp_EncodeBasicOCSPResponseTemplate))
- goto done;
-
- rb->responseTypeTag = SEC_OID_PKIX_OCSP_BASIC_RESPONSE;
-
- od = SECOID_FindOIDByTag(rb->responseTypeTag);
- if (!od)
- goto done;
-
- rb->responseType = od->oid;
- rb->decodedResponse.basic = br;
-
- response->arena = tmpArena;
- response->responseBytes = rb;
- response->statusValue = ocspResponse_successful;
-
- if (!SEC_ASN1EncodeInteger(tmpArena, &response->responseStatus,
- response->statusValue))
- goto done;
-
- result = SEC_ASN1EncodeItem(arena, NULL, response, ocsp_OCSPResponseTemplate);
-
-done:
- if (privKey)
- SECKEY_DestroyPrivateKey(privKey);
- if (br->responseSignature.signature.data)
- SECITEM_FreeItem(&br->responseSignature.signature, PR_FALSE);
- PORT_FreeArena(tmpArena, PR_FALSE);
-
- return result;
-}
-
-static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTOCSPResponse) },
- { SEC_ASN1_ENUMERATED,
- offsetof(CERTOCSPResponse, responseStatus) },
- { 0, 0,
- mySEC_NullTemplate },
- { 0 }
-};
-
-SECItem*
-CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error)
-{
- CERTOCSPResponse response;
- SECItem *result = NULL;
-
- switch (error) {
- case SEC_ERROR_OCSP_MALFORMED_REQUEST:
- response.statusValue = ocspResponse_malformedRequest;
- break;
- case SEC_ERROR_OCSP_SERVER_ERROR:
- response.statusValue = ocspResponse_internalError;
- break;
- case SEC_ERROR_OCSP_TRY_SERVER_LATER:
- response.statusValue = ocspResponse_tryLater;
- break;
- case SEC_ERROR_OCSP_REQUEST_NEEDS_SIG:
- response.statusValue = ocspResponse_sigRequired;
- break;
- case SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST:
- response.statusValue = ocspResponse_unauthorized;
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- if (!SEC_ASN1EncodeInteger(NULL, &response.responseStatus,
- response.statusValue))
- return NULL;
-
- result = SEC_ASN1EncodeItem(arena, NULL, &response,
- ocsp_OCSPErrorResponseTemplate);
-
- SECITEM_FreeItem(&response.responseStatus, PR_FALSE);
-
- return result;
-}
diff --git a/security/nss/lib/certhigh/ocspt.h b/security/nss/lib/certhigh/ocspt.h
deleted file mode 100644
index 7992861c8..000000000
--- a/security/nss/lib/certhigh/ocspt.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Public header for exported OCSP types.
- *
- * $Id$
- */
-
-#ifndef _OCSPT_H_
-#define _OCSPT_H_
-
-/*
- * The following are all opaque types. If someone needs to get at
- * a field within, then we need to fix the API. Try very hard not
- * make the type available to them.
- */
-typedef struct CERTOCSPRequestStr CERTOCSPRequest;
-typedef struct CERTOCSPResponseStr CERTOCSPResponse;
-
-/*
- * XXX I think only those first two above should need to be exported,
- * but until I know for certain I am leaving the rest of these here, too.
- */
-typedef struct CERTOCSPCertIDStr CERTOCSPCertID;
-typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse;
-
-/*
- * This interface is described in terms of an HttpClient which
- * supports at least a specified set of functions. (An implementer may
- * provide HttpClients with additional functionality accessible only to
- * users with a particular implementation in mind.) The basic behavior
- * is provided by defining a set of functions, listed in an
- * SEC_HttpServerFcnStruct. If the implementor of a SpecificHttpClient
- * registers his SpecificHttpClient as the default HttpClient, then his
- * functions will be called by the user of an HttpClient, such as an
- * OCSPChecker.
- *
- * The implementer of a specific HttpClient (e.g., the NSS-provided
- * DefaultHttpClient), populates an SEC_HttpClientFcnStruct, uses it to
- * register his client, and waits for his functions to be called.
- *
- * For future expandability, the SEC_HttpClientFcnStruct is defined as a
- * union, with the version field acting as a selector. The proposed
- * initial version of the structure is given following the definition
- * of the union. The HttpClientState structure is implementation-
- * dependent, and should be opaque to the user.
- */
-
-typedef void * SEC_HTTP_SERVER_SESSION;
-typedef void * SEC_HTTP_REQUEST_SESSION;
-
-/*
- * This function creates a SEC_HTTP_SERVER_SESSION object. The implementer of a
- * specific HttpClient will allocate the necessary space, when this
- * function is called, and will free it when the corresponding FreeFcn
- * is called. The SEC_HTTP_SERVER_SESSION object is passed, as an opaque object,
- * to subsequent calls.
- *
- * If the function returns SECSuccess, the returned SEC_HTTP_SERVER_SESSION
- * must be cleaned up with a call to SEC_HttpServer_FreeSession,
- * after processing is finished.
- */
-typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)(
- const char *host,
- PRUint16 portnum,
- SEC_HTTP_SERVER_SESSION *pSession);
-
-/*
- * This function is called to allow the implementation to attempt to keep
- * the connection alive. Depending on the underlying platform, it might
- * immediately return SECSuccess without having performed any operations.
- * (If a connection has not been kept alive, a subsequent call to
- * SEC_HttpRequest_TrySendAndReceiveFcn should reopen the connection
- * automatically.)
- *
- * If the connection uses nonblocking I/O, this function may return
- * SECWouldBlock and store a nonzero value at "pPollDesc". In that case
- * the caller may wait on the poll descriptor, and should call this function
- * again until SECSuccess (and a zero value at "pPollDesc") is obtained.
- */
-typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)(
- SEC_HTTP_SERVER_SESSION session,
- PRPollDesc **pPollDesc);
-
-/*
- * This function frees the client SEC_HTTP_SERVER_SESSION object, closes all
- * SEC_HTTP_REQUEST_SESSIONs created for that server, discards all partial results,
- * frees any memory that was allocated by the client, and invalidates any
- * response pointers that might have been returned by prior server or request
- * functions.
- */
-typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)(
- SEC_HTTP_SERVER_SESSION session);
-
-/*
- * This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a
- * specific HttpClient will allocate the necessary space, when this
- * function is called, and will free it when the corresponding FreeFcn
- * is called. The SEC_HTTP_REQUEST_SESSION object is passed, as an opaque object,
- * to subsequent calls.
- *
- * An implementation that does not support the requested protocol variant
- * (usually "http", but could eventually allow "https") or request method
- * should return SECFailure.
- *
- * Timeout values may include the constants PR_INTERVAL_NO_TIMEOUT (wait
- * forever) or PR_INTERVAL_NO_WAIT (nonblocking I/O).
- *
- * If the function returns SECSuccess, the returned SEC_HTTP_REQUEST_SESSION
- * must be cleaned up with a call to SEC_HttpRequest_FreeSession,
- * after processing is finished.
- */
-typedef SECStatus (*SEC_HttpRequest_CreateFcn)(
- SEC_HTTP_SERVER_SESSION session,
- const char *http_protocol_variant, /* usually "http" */
- const char *path_and_query_string,
- const char *http_request_method,
- const PRIntervalTime timeout,
- SEC_HTTP_REQUEST_SESSION *pRequest);
-
-/*
- * This function sets data to be sent to the server for an HTTP request
- * of http_request_method == POST. If a particular implementation
- * supports it, the details for the POST request can be set by calling
- * this function, prior to activating the request with TrySendAndReceiveFcn.
- *
- * An implementation that does not support the POST method should
- * implement a SetPostDataFcn function that returns immediately.
- *
- * Setting http_content_type is optional, the parameter may
- * by NULL or the empty string.
- */
-typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)(
- SEC_HTTP_REQUEST_SESSION request,
- const char *http_data,
- const PRUint32 http_data_len,
- const char *http_content_type);
-
-/*
- * This function sets an additional HTTP protocol request header.
- * If a particular implementation supports it, one or multiple headers
- * can be added to the request by calling this function once or multiple
- * times, prior to activating the request with TryFcn.
- *
- * An implementation that does not support setting additional headers
- * should implement an AddRequestHeaderFcn function that returns immediately.
- */
-typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
- SEC_HTTP_REQUEST_SESSION request,
- const char *http_header_name,
- const char *http_header_value);
-
-/*
- * This function initiates or continues an HTTP request. After
- * parameters have been set with the Create function and, optionally,
- * modified or enhanced with the AddParams function, this call creates
- * the socket connection and initiates the communication.
- *
- * If a timeout value of zero is specified, indicating non-blocking
- * I/O, the client creates a non-blocking socket, and returns a status
- * of SECWouldBlock and a non-NULL PRPollDesc if the operation is not
- * complete. In that case all other return parameters are undefined.
- * The caller is expected to repeat the call, possibly after using
- * PRPoll to determine that a completion has occurred, until a return
- * value of SECSuccess (and a NULL value for pPollDesc) or a return
- * value of SECFailure (indicating failure on the network level)
- * is obtained.
- *
- * http_response_data_len is both input and output parameter.
- * If a pointer to a PRUint32 is supplied, the http client is
- * expected to check the given integer value and always set an out
- * value, even on failure.
- * An input value of zero means, the caller will accept any response len.
- * A different input value indicates the maximum response value acceptable
- * to the caller.
- * If data is successfully read and the size is acceptable to the caller,
- * the function will return SECSuccess and set http_response_data_len to
- * the size of the block returned in http_response_data.
- * If the data read from the http server is larger than the acceptable
- * size, the function will return SECFailure.
- * http_response_data_len will be set to a value different from zero to
- * indicate the reason of the failure.
- * An out value of "0" means, the failure was unrelated to the
- * acceptable size.
- * An out value of "1" means, the result data is larger than the
- * accpeptable size, but the real size is not yet known to the http client
- * implementation and it stopped retrieving it,
- * Any other out value combined with a return value of SECFailure
- * will indicate the actual size of the server data.
- *
- * The caller is permitted to provide NULL values for any of the
- * http_response arguments, indicating the caller is not interested in
- * those values. If the caller does provide an address, the HttpClient
- * stores at that address a pointer to the corresponding argument, at
- * the completion of the operation.
- *
- * All returned pointers will be owned by the the HttpClient
- * implementation and will remain valid until the call to
- * SEC_HttpRequest_FreeFcn.
- */
-typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)(
- SEC_HTTP_REQUEST_SESSION request,
- PRPollDesc **pPollDesc,
- PRUint16 *http_response_code,
- const char **http_response_content_type,
- const char **http_response_headers,
- const char **http_response_data,
- PRUint32 *http_response_data_len);
-
-/*
- * Calling CancelFcn asks for premature termination of the request.
- *
- * Future calls to SEC_HttpRequest_TrySendAndReceive should
- * by avoided, but in this case the HttpClient implementation
- * is expected to return immediately with SECFailure.
- *
- * After calling CancelFcn, a separate call to SEC_HttpRequest_FreeFcn
- * is still necessary to free resources.
- */
-typedef SECStatus (*SEC_HttpRequest_CancelFcn)(
- SEC_HTTP_REQUEST_SESSION request);
-
-/*
- * Before calling this function, it must be assured the request
- * has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has
- * returned SECSuccess, or the request has been canceled with
- * a call to SEC_HttpRequest_CancelFcn.
- *
- * This function frees the client state object, closes all sockets,
- * discards all partial results, frees any memory that was allocated
- * by the client, and invalidates all response pointers that might
- * have been returned by SEC_HttpRequest_TrySendAndReceiveFcn
- */
-typedef SECStatus (*SEC_HttpRequest_FreeFcn)(
- SEC_HTTP_REQUEST_SESSION request);
-
-typedef struct SEC_HttpClientFcnV1Struct {
- SEC_HttpServer_CreateSessionFcn createSessionFcn;
- SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn;
- SEC_HttpServer_FreeSessionFcn freeSessionFcn;
- SEC_HttpRequest_CreateFcn createFcn;
- SEC_HttpRequest_SetPostDataFcn setPostDataFcn;
- SEC_HttpRequest_AddHeaderFcn addHeaderFcn;
- SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn;
- SEC_HttpRequest_CancelFcn cancelFcn;
- SEC_HttpRequest_FreeFcn freeFcn;
-} SEC_HttpClientFcnV1;
-
-typedef struct SEC_HttpClientFcnStruct {
- PRInt16 version;
- union {
- SEC_HttpClientFcnV1 ftable1;
- /* SEC_HttpClientFcnV2 ftable2; */
- /* ... */
- } fcnTable;
-} SEC_HttpClientFcn;
-
-/*
- * ocspMode_FailureIsVerificationFailure:
- * This is the classic behaviour of NSS.
- * Any OCSP failure is a verification failure (classic mode, default).
- * Without a good response, OCSP networking will be retried each time
- * it is required for verifying a cert.
- *
- * ocspMode_FailureIsNotAVerificationFailure:
- * If we fail to obtain a valid OCSP response, consider the
- * cert as good.
- * Failed OCSP attempts might get cached and not retried until
- * minimumSecondsToNextFetchAttempt.
- * If we are able to obtain a valid response, the cert
- * will be considered good, if either status is "good"
- * or the cert was not yet revoked at verification time.
- *
- * Additional failure modes might be added in the future.
- */
-typedef enum {
- ocspMode_FailureIsVerificationFailure = 0,
- ocspMode_FailureIsNotAVerificationFailure = 1
-} SEC_OcspFailureMode;
-
-/*
- * A ResponderID identifies the responder -- or more correctly, the
- * signer of the response. The ASN.1 definition of a ResponderID is:
- *
- * ResponderID ::= CHOICE {
- * byName [1] EXPLICIT Name,
- * byKey [2] EXPLICIT KeyHash }
- *
- * Because it is CHOICE, the type of identification used and the
- * identification itself are actually encoded together. To represent
- * this same information internally, we explicitly define a type and
- * save it, along with the value, into a data structure.
- */
-
-typedef enum {
- ocspResponderID_other = -1, /* unknown kind of responderID */
- ocspResponderID_byName = 1,
- ocspResponderID_byKey = 2
-} CERTOCSPResponderIDType;
-
-#endif /* _OCSPT_H_ */
diff --git a/security/nss/lib/certhigh/ocspti.h b/security/nss/lib/certhigh/ocspti.h
deleted file mode 100644
index 910b7db7c..000000000
--- a/security/nss/lib/certhigh/ocspti.h
+++ /dev/null
@@ -1,361 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Private header defining OCSP types.
- *
- * $Id$
- */
-
-#ifndef _OCSPTI_H_
-#define _OCSPTI_H_
-
-#include "ocspt.h"
-
-#include "certt.h"
-#include "plarena.h"
-#include "seccomon.h"
-#include "secoidt.h"
-
-
-/*
- * Some notes about naming conventions...
- *
- * The public data types all start with "CERTOCSP" (e.g. CERTOCSPRequest).
- * (Even the public types are opaque, however. Only their names are
- * "exported".)
- *
- * Internal-only data types drop the "CERT" prefix and use only the
- * lower-case "ocsp" (e.g. ocspTBSRequest), for brevity sake.
- *
- * In either case, the base/suffix of the type name usually matches the
- * name as defined in the OCSP specification. The exceptions to this are:
- * - When there is overlap between the "OCSP" or "ocsp" prefix and
- * the name used in the standard. That is, you cannot strip off the
- * "CERTOCSP" or "ocsp" prefix and necessarily get the name of the
- * type as it is defined in the standard; the "real" name will be
- * *either* "OCSPSuffix" or just "Suffix".
- * - When the name in the standard was a little too generic. (e.g. The
- * standard defines "Request" but we call it a "SingleRequest".)
- * In this case a comment above the type definition calls attention
- * to the difference.
- *
- * The definitions laid out in this header file are intended to follow
- * the same order as the definitions in the OCSP specification itself.
- * With the OCSP standard in hand, you should be able to move through
- * this file and follow along. To future modifiers of this file: please
- * try to keep it that way. The only exceptions are the few cases where
- * we need to define a type before it is referenced (e.g. enumerations),
- * whereas in the OCSP specification these are usually defined the other
- * way around (reference before definition).
- */
-
-
-/*
- * Forward-declarations of internal-only data structures.
- *
- * These are in alphabetical order (case-insensitive); please keep it that way!
- */
-typedef struct ocspBasicOCSPResponseStr ocspBasicOCSPResponse;
-typedef struct ocspCertStatusStr ocspCertStatus;
-typedef struct ocspResponderIDStr ocspResponderID;
-typedef struct ocspResponseBytesStr ocspResponseBytes;
-typedef struct ocspResponseDataStr ocspResponseData;
-typedef struct ocspRevokedInfoStr ocspRevokedInfo;
-typedef struct ocspServiceLocatorStr ocspServiceLocator;
-typedef struct ocspSignatureStr ocspSignature;
-typedef struct ocspSingleRequestStr ocspSingleRequest;
-typedef struct ocspSingleResponseStr ocspSingleResponse;
-typedef struct ocspTBSRequestStr ocspTBSRequest;
-
-
-/*
- * An OCSPRequest; this is what is sent (encoded) to an OCSP responder.
- */
-struct CERTOCSPRequestStr {
- PRArenaPool *arena; /* local; not part of encoding */
- ocspTBSRequest *tbsRequest;
- ocspSignature *optionalSignature;
-};
-
-/*
- * A TBSRequest; when an OCSPRequest is signed, the encoding of this
- * is what the signature is actually applied to. ("TBS" == To Be Signed)
- * Whether signed or not, however, this structure will be present, and
- * is the "meat" of the OCSPRequest.
- *
- * Note that the "requestorName" field cannot be encoded/decoded in the
- * same pass as the entire request -- it needs to be handled with a special
- * call to convert to/from our internal form of a GeneralName. Thus the
- * "derRequestorName" field, which is the actual DER-encoded bytes.
- *
- * The "extensionHandle" field is used on creation only; it holds
- * in-progress extensions as they are optionally added to the request.
- */
-struct ocspTBSRequestStr {
- SECItem version; /* an INTEGER */
- SECItem *derRequestorName; /* encoded GeneralName; see above */
- CERTGeneralNameList *requestorName; /* local; not part of encoding */
- ocspSingleRequest **requestList;
- CERTCertExtension **requestExtensions;
- void *extensionHandle; /* local; not part of encoding */
-};
-
-/*
- * This is the actual signature information for an OCSPRequest (applied to
- * the TBSRequest structure) or for a BasicOCSPResponse (applied to a
- * ResponseData structure).
- *
- * Note that the "signature" field itself is a BIT STRING; operations on
- * it need to keep that in mind, converting the length to bytes as needed
- * and back again afterward (so that the length is usually expressing bits).
- *
- * The "cert" field is the signer's certificate. In the case of a received
- * signature, it will be filled in when the signature is verified. In the
- * case of a created signature, it is filled in on creation and will be the
- * cert used to create the signature when the signing-and-encoding occurs,
- * as well as the cert (and its chain) to fill in derCerts if requested.
- *
- * The extra fields cache information about the signature after we have
- * attempted a verification. "wasChecked", if true, means the signature
- * has been checked against the appropriate data and thus that "status"
- * contains the result of that verification. If "status" is not SECSuccess,
- * "failureReason" is a copy of the error code that was set at the time;
- * presumably it tells why the signature verification failed.
- */
-struct ocspSignatureStr {
- SECAlgorithmID signatureAlgorithm;
- SECItem signature; /* a BIT STRING */
- SECItem **derCerts; /* a SEQUENCE OF Certificate */
- CERTCertificate *cert; /* local; not part of encoding */
- PRBool wasChecked; /* local; not part of encoding */
- SECStatus status; /* local; not part of encoding */
- int failureReason; /* local; not part of encoding */
-};
-
-/*
- * An OCSPRequest contains a SEQUENCE OF these, one for each certificate
- * whose status is being checked.
- *
- * Note that in the OCSP specification this is just called "Request",
- * but since that seemed confusing (vs. an OCSPRequest) and to be more
- * consistent with the parallel type "SingleResponse", I called it a
- * "SingleRequest".
- *
- * XXX figure out how to get rid of that arena -- there must be a way
- */
-struct ocspSingleRequestStr {
- PRArenaPool *arena; /* just a copy of the response arena,
- * needed here for extension handling
- * routines, on creation only */
- CERTOCSPCertID *reqCert;
- CERTCertExtension **singleRequestExtensions;
-};
-
-/*
- * A CertID is the means of identifying a certificate, used both in requests
- * and in responses.
- *
- * When in a SingleRequest it specifies the certificate to be checked.
- * When in a SingleResponse it is the cert whose status is being given.
- */
-struct CERTOCSPCertIDStr {
- SECAlgorithmID hashAlgorithm;
- SECItem issuerNameHash; /* an OCTET STRING */
- SECItem issuerKeyHash; /* an OCTET STRING */
- SECItem serialNumber; /* an INTEGER */
- SECItem issuerSHA1NameHash; /* keep other hashes around when */
- SECItem issuerMD5NameHash; /* we have them */
- SECItem issuerMD2NameHash;
- SECItem issuerSHA1KeyHash; /* keep other hashes around when */
- SECItem issuerMD5KeyHash; /* we have them */
- SECItem issuerMD2KeyHash;
- PRArenaPool *poolp;
-};
-
-/*
- * This describes the value of the responseStatus field in an OCSPResponse.
- * The corresponding ASN.1 definition is:
- *
- * OCSPResponseStatus ::= ENUMERATED {
- * successful (0), --Response has valid confirmations
- * malformedRequest (1), --Illegal confirmation request
- * internalError (2), --Internal error in issuer
- * tryLater (3), --Try again later
- * --(4) is not used
- * sigRequired (5), --Must sign the request
- * unauthorized (6), --Request unauthorized
- * }
- */
-typedef enum {
- ocspResponse_min = 0,
- ocspResponse_successful = 0,
- ocspResponse_malformedRequest = 1,
- ocspResponse_internalError = 2,
- ocspResponse_tryLater = 3,
- ocspResponse_unused = 4,
- ocspResponse_sigRequired = 5,
- ocspResponse_unauthorized = 6,
- ocspResponse_max = 6 /* Please update max when adding values.
- * Remember to also update arrays, e.g.
- * "responseStatusNames" in ocspclnt.c
- * and potentially other places. */
-} ocspResponseStatus;
-
-/*
- * An OCSPResponse is what is sent (encoded) by an OCSP responder.
- *
- * The field "responseStatus" is the ASN.1 encoded value; the field
- * "statusValue" is simply that same value translated into our local
- * type ocspResponseStatus.
- */
-struct CERTOCSPResponseStr {
- PRArenaPool *arena; /* local; not part of encoding */
- SECItem responseStatus; /* an ENUMERATED, see above */
- ocspResponseStatus statusValue; /* local; not part of encoding */
- ocspResponseBytes *responseBytes; /* only when status is successful */
-};
-
-/*
- * A ResponseBytes (despite appearances) is what contains the meat
- * of a successful response -- but still in encoded form. The type
- * given as "responseType" tells you how to decode the string.
- *
- * We look at the OID and translate it into our local OID representation
- * "responseTypeTag", and use that value to tell us how to decode the
- * actual response itself. For now the only kind of OCSP response we
- * know about is a BasicOCSPResponse. However, the intention in the
- * OCSP specification is to allow for other response types, so we are
- * building in that flexibility from the start and thus put a pointer
- * to that data structure inside of a union. Whenever OCSP adds more
- * response types, just add them to the union.
- */
-struct ocspResponseBytesStr {
- SECItem responseType; /* an OBJECT IDENTIFIER */
- SECOidTag responseTypeTag; /* local; not part of encoding */
- SECItem response; /* an OCTET STRING */
- union {
- ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */
- } decodedResponse; /* local; not part of encoding */
-};
-
-/*
- * A BasicOCSPResponse -- when the responseType in a ResponseBytes is
- * id-pkix-ocsp-basic, the "response" OCTET STRING above is the DER
- * encoding of one of these.
- *
- * Note that in the OCSP specification, the signature fields are not
- * part of a separate sub-structure. But since they are the same fields
- * as we define for the signature in a request, it made sense to share
- * the C data structure here and in some shared code to operate on them.
- */
-struct ocspBasicOCSPResponseStr {
- SECItem tbsResponseDataDER;
- ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
- ocspSignature responseSignature;
-};
-
-/*
- * A ResponseData is the part of a BasicOCSPResponse that is signed
- * (after it is DER encoded). It contains the real details of the response
- * (a per-certificate status).
- */
-struct ocspResponseDataStr {
- SECItem version; /* an INTEGER */
- SECItem derResponderID;
- ocspResponderID *responderID; /* local; not part of encoding */
- SECItem producedAt; /* a GeneralizedTime */
- CERTOCSPSingleResponse **responses;
- CERTCertExtension **responseExtensions;
-};
-
-struct ocspResponderIDStr {
- CERTOCSPResponderIDType responderIDType;/* local; not part of encoding */
- union {
- CERTName name; /* when ocspResponderID_byName */
- SECItem keyHash; /* when ocspResponderID_byKey */
- SECItem other; /* when ocspResponderID_other */
- } responderIDValue;
-};
-
-/*
- * The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF
- * SingleResponse -- one for each certificate whose status is being supplied.
- *
- * XXX figure out how to get rid of that arena -- there must be a way
- */
-struct CERTOCSPSingleResponseStr {
- PRArenaPool *arena; /* just a copy of the response arena,
- * needed here for extension handling
- * routines, on creation only */
- CERTOCSPCertID *certID;
- SECItem derCertStatus;
- ocspCertStatus *certStatus; /* local; not part of encoding */
- SECItem thisUpdate; /* a GeneralizedTime */
- SECItem *nextUpdate; /* a GeneralizedTime */
- CERTCertExtension **singleExtensions;
-};
-
-/*
- * A CertStatus is the actual per-certificate status. Its ASN.1 definition:
- *
- * CertStatus ::= CHOICE {
- * good [0] IMPLICIT NULL,
- * revoked [1] IMPLICIT RevokedInfo,
- * unknown [2] IMPLICIT UnknownInfo }
- *
- * (where for now UnknownInfo is defined to be NULL but in the
- * future may be replaced with an enumeration).
- *
- * Because it is CHOICE, the status value and its associated information
- * (if any) are actually encoded together. To represent this same
- * information internally, we explicitly define a type and save it,
- * along with the value, into a data structure.
- */
-
-typedef enum {
- ocspCertStatus_good, /* cert is not revoked */
- ocspCertStatus_revoked, /* cert is revoked */
- ocspCertStatus_unknown, /* cert was unknown to the responder */
- ocspCertStatus_other /* status was not an expected value */
-} ocspCertStatusType;
-
-/*
- * This is the actual per-certificate status.
- *
- * The "goodInfo" and "unknownInfo" items are only place-holders for a NULL.
- * (Though someday OCSP may replace UnknownInfo with an enumeration that
- * gives more detailed information.)
- */
-struct ocspCertStatusStr {
- ocspCertStatusType certStatusType; /* local; not part of encoding */
- union {
- SECItem *goodInfo; /* when ocspCertStatus_good */
- ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */
- SECItem *unknownInfo; /* when ocspCertStatus_unknown */
- SECItem *otherInfo; /* when ocspCertStatus_other */
- } certStatusInfo;
-};
-
-/*
- * A RevokedInfo gives information about a revoked certificate -- when it
- * was revoked and why.
- */
-struct ocspRevokedInfoStr {
- SECItem revocationTime; /* a GeneralizedTime */
- SECItem *revocationReason; /* a CRLReason; ignored for now */
-};
-
-/*
- * ServiceLocator can be included as one of the singleRequestExtensions.
- * When added, it specifies the (name of the) issuer of the cert being
- * checked, and optionally the value of the AuthorityInfoAccess extension
- * if the cert has one.
- */
-struct ocspServiceLocatorStr {
- CERTName *issuer;
- SECItem locator; /* DER encoded authInfoAccess extension from cert */
-};
-
-#endif /* _OCSPTI_H_ */
diff --git a/security/nss/lib/certhigh/xcrldist.c b/security/nss/lib/certhigh/xcrldist.c
deleted file mode 100644
index 286dc3775..000000000
--- a/security/nss/lib/certhigh/xcrldist.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Code for dealing with x.509 v3 CRL Distribution Point extension.
- */
-#include "genname.h"
-#include "certt.h"
-#include "secerr.h"
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(SEC_BitStringTemplate)
-
-extern void PrepareBitStringForEncoding (SECItem *bitMap, SECItem *value);
-
-static const SEC_ASN1Template FullNameTemplate[] = {
- {SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
- offsetof (CRLDistributionPoint,derFullName),
- CERT_GeneralNamesTemplate}
-};
-
-static const SEC_ASN1Template RelativeNameTemplate[] = {
- {SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
- offsetof (CRLDistributionPoint,distPoint.relativeName),
- CERT_RDNTemplate}
-};
-
-static const SEC_ASN1Template DistributionPointNameTemplate[] = {
- { SEC_ASN1_CHOICE,
- offsetof(CRLDistributionPoint, distPointType), NULL,
- sizeof(CRLDistributionPoint) },
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
- offsetof (CRLDistributionPoint, derFullName),
- CERT_GeneralNamesTemplate, generalName },
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
- offsetof (CRLDistributionPoint, distPoint.relativeName),
- CERT_RDNTemplate, relativeDistinguishedName },
- { 0 }
-};
-
-static const SEC_ASN1Template CRLDistributionPointTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRLDistributionPoint) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0,
- offsetof(CRLDistributionPoint,derDistPoint),
- SEC_ASN1_SUB(SEC_AnyTemplate)},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- offsetof(CRLDistributionPoint,bitsmap),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_CONSTRUCTED | 2,
- offsetof(CRLDistributionPoint, derCrlIssuer),
- CERT_GeneralNamesTemplate},
- { 0 }
-};
-
-const SEC_ASN1Template CERTCRLDistributionPointsTemplate[] = {
- {SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate}
-};
-
-SECStatus
-CERT_EncodeCRLDistributionPoints (PLArenaPool *arena,
- CERTCrlDistributionPoints *value,
- SECItem *derValue)
-{
- CRLDistributionPoint **pointList, *point;
- PLArenaPool *ourPool = NULL;
- SECStatus rv = SECSuccess;
-
- PORT_Assert (derValue);
- PORT_Assert (value && value->distPoints);
-
- do {
- ourPool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (ourPool == NULL) {
- rv = SECFailure;
- break;
- }
-
- pointList = value->distPoints;
- while (*pointList) {
- point = *pointList;
- point->derFullName = NULL;
- point->derDistPoint.data = NULL;
-
- switch (point->distPointType) {
- case generalName:
- point->derFullName = cert_EncodeGeneralNames
- (ourPool, point->distPoint.fullName);
-
- if (!point->derFullName ||
- !SEC_ASN1EncodeItem (ourPool, &point->derDistPoint,
- point, FullNameTemplate))
- rv = SECFailure;
- break;
-
- case relativeDistinguishedName:
- if (!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint,
- point, RelativeNameTemplate))
- rv = SECFailure;
- break;
-
- /* distributionPointName is omitted */
- case 0: break;
-
- default:
- PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
- rv = SECFailure;
- break;
- }
-
- if (rv != SECSuccess)
- break;
-
- if (point->reasons.data)
- PrepareBitStringForEncoding (&point->bitsmap, &point->reasons);
-
- if (point->crlIssuer) {
- point->derCrlIssuer = cert_EncodeGeneralNames
- (ourPool, point->crlIssuer);
- if (!point->derCrlIssuer) {
- rv = SECFailure;
- break;
- }
- }
- ++pointList;
- }
- if (rv != SECSuccess)
- break;
- if (!SEC_ASN1EncodeItem(arena, derValue, value,
- CERTCRLDistributionPointsTemplate)) {
- rv = SECFailure;
- break;
- }
- } while (0);
- PORT_FreeArena (ourPool, PR_FALSE);
- return rv;
-}
-
-CERTCrlDistributionPoints *
-CERT_DecodeCRLDistributionPoints (PLArenaPool *arena, SECItem *encodedValue)
-{
- CERTCrlDistributionPoints *value = NULL;
- CRLDistributionPoint **pointList, *point;
- SECStatus rv = SECSuccess;
- SECItem newEncodedValue;
-
- PORT_Assert (arena);
- do {
- value = PORT_ArenaZNew(arena, CERTCrlDistributionPoints);
- if (value == NULL) {
- rv = SECFailure;
- break;
- }
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
- if (rv != SECSuccess)
- break;
-
- rv = SEC_QuickDERDecodeItem(arena, &value->distPoints,
- CERTCRLDistributionPointsTemplate, &newEncodedValue);
- if (rv != SECSuccess)
- break;
-
- pointList = value->distPoints;
- while (NULL != (point = *pointList)) {
-
- /* get the data if the distributionPointName is not omitted */
- if (point->derDistPoint.data != NULL) {
- rv = SEC_QuickDERDecodeItem(arena, point,
- DistributionPointNameTemplate, &(point->derDistPoint));
- if (rv != SECSuccess)
- break;
-
- switch (point->distPointType) {
- case generalName:
- point->distPoint.fullName =
- cert_DecodeGeneralNames(arena, point->derFullName);
- rv = point->distPoint.fullName ? SECSuccess : SECFailure;
- break;
-
- case relativeDistinguishedName:
- break;
-
- default:
- PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
- rv = SECFailure;
- break;
- } /* end switch */
- if (rv != SECSuccess)
- break;
- } /* end if */
-
- /* Get the reason code if it's not omitted in the encoding */
- if (point->bitsmap.data != NULL) {
- SECItem bitsmap = point->bitsmap;
- DER_ConvertBitString(&bitsmap);
- rv = SECITEM_CopyItem(arena, &point->reasons, &bitsmap);
- if (rv != SECSuccess)
- break;
- }
-
- /* Get the crl issuer name if it's not omitted in the encoding */
- if (point->derCrlIssuer != NULL) {
- point->crlIssuer = cert_DecodeGeneralNames(arena,
- point->derCrlIssuer);
- if (!point->crlIssuer)
- break;
- }
- ++pointList;
- } /* end while points remain */
- } while (0);
- return (rv == SECSuccess ? value : NULL);
-}
diff --git a/security/nss/lib/ckfw/Makefile b/security/nss/lib/ckfw/Makefile
deleted file mode 100644
index 5f33dbb7b..000000000
--- a/security/nss/lib/ckfw/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-include manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-ifdef NOTDEF # was ifdef MOZILLA_CLIENT
-NSS_BUILD_CAPI = 1
-endif
-
-# This'll need some help from a build person.
-
-# The generated files are checked in, and differ from what ckapi.perl
-# will produce. ckapi.perl is currently newer than the targets, so
-# these rules are invoked, causing the wrong files to be generated.
-# Turning off to fix builds.
-#
-# nssckepv.h: ck.api ckapi.perl
-# nssckft.h: ck.api ckapi.perl
-# nssckg.h: ck.api ckapi.perl
-# nssck.api: ck.api ckapi.perl
-# $(PERL) ckapi.perl ck.api
-
-export:: private_export
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
-ifdef NSS_BUILD_CAPI
-DIRS += capi
-endif
-endif
-
-#ifeq ($(OS_ARCH), Darwin)
-#DIRS += nssmkey
-#endif
diff --git a/security/nss/lib/ckfw/builtins/Makefile b/security/nss/lib/ckfw/builtins/Makefile
deleted file mode 100644
index 13c6bce0d..000000000
--- a/security/nss/lib/ckfw/builtins/Makefile
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-include manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
-
-EXTRA_LIBS = \
- $(DIST)/lib/$(LIB_PREFIX)nssckfw.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
- $(NULL)
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-ifdef NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-else
-EXTRA_SHARED_LIBS += \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-else
-
-EXTRA_SHARED_LIBS += \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-endif
-
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-# Generate certdata.c.
-
-# By default, use the unmodified certdata.txt.
-ifndef NSS_CERTDATA_TXT
-NSS_CERTDATA_TXT = certdata.txt
-endif
-
-$(OBJDIR)/certdata.c: $(NSS_CERTDATA_TXT) certdata.perl
- $(PERL) certdata.perl < $(NSS_CERTDATA_TXT) > $@
diff --git a/security/nss/lib/ckfw/builtins/README b/security/nss/lib/ckfw/builtins/README
deleted file mode 100644
index fc0393c38..000000000
--- a/security/nss/lib/ckfw/builtins/README
+++ /dev/null
@@ -1,45 +0,0 @@
-This README file explains how to add a builtin root CA certificate to NSS
-or remove a builtin root CA certificate from NSS.
-
-The builtin root CA certificates in NSS are stored in the nssckbi PKCS #11
-module. The sources to the nssckbi module are in this directory.
-
-I. Adding a Builtin Root CA Certificate
-
-You need to use the addbuiltin command-line tool to add a root CA certificate
-to the nssckbi module. In the procedure described below, we assume that the
-new root CA certificate is distributed in DER format in the file newroot.der.
-
-1. Add the directory where the addbuiltin executable resides to your PATH
-environment variable. Then, add the directory where the NSPR and NSS shared
-libraries (DLLs) reside to the platform-specific environment variable that
-specifies your shared library search path: LD_LIBRARY_PATH (most Unix
-variants), SHLIB_PATH (32-bit HP-UX), LIBPATH (AIX), or PATH (Windows).
-
-2. Copy newroot.der to this directory.
-
-3. In this directory, run addbuiltin to add the new root certificate. The
-argument to the -n option should be replaced by the nickname of the root
-certificate.
-
- % addbuiltin -n "Nickname of the Root Certificate" -t C,C,C < newroot.der >> certdata.txt
-
-4. Edit nssckbi.h to bump the version of the module.
-
-5. Run gmake in this directory to build the nssckbi module.
-
-6. After you verify that the new nssckbi module is correct, check in
-certdata.txt and nssckbi.h.
-
-II. Removing a Builtin Root CA Certificate
-
-1. Change directory to this directory.
-
-2. Edit certdata.txt and remove the root CA certificate.
-
-3. Edit nssckbi.h to bump the version of the module.
-
-4. Run gmake in this directory to build the nssckbi module.
-
-5. After you verify that the new nssckbi module is correct, check in
-certdata.txt and nssckbi.h.
diff --git a/security/nss/lib/ckfw/builtins/anchor.c b/security/nss/lib/ckfw/builtins/anchor.c
deleted file mode 100644
index 5faa4795e..000000000
--- a/security/nss/lib/ckfw/builtins/anchor.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * builtins/anchor.c
- *
- * This file "anchors" the actual cryptoki entry points in this module's
- * shared library, which is required for dynamic loading. See the
- * comments in nssck.api for more information.
- */
-
-#include "builtins.h"
-
-#define MODULE_NAME builtins
-#define INSTANCE_NAME (NSSCKMDInstance *)&nss_builtins_mdInstance
-#include "nssck.api"
diff --git a/security/nss/lib/ckfw/builtins/bfind.c b/security/nss/lib/ckfw/builtins/bfind.c
deleted file mode 100644
index ea6c7f3cc..000000000
--- a/security/nss/lib/ckfw/builtins/bfind.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef BUILTINS_H
-#include "builtins.h"
-#endif /* BUILTINS_H */
-
-/*
- * builtins/find.c
- *
- * This file implements the NSSCKMDFindObjects object for the
- * "builtin objects" cryptoki module.
- */
-
-struct builtinsFOStr {
- NSSArena *arena;
- CK_ULONG n;
- CK_ULONG i;
- builtinsInternalObject **objs;
-};
-
-static void
-builtins_mdFindObjects_Final
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
- NSSArena *arena = fo->arena;
-
- nss_ZFreeIf(fo->objs);
- nss_ZFreeIf(fo);
- nss_ZFreeIf(mdFindObjects);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
-
- return;
-}
-
-static NSSCKMDObject *
-builtins_mdFindObjects_Next
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
-{
- struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
- builtinsInternalObject *io;
-
- if( fo->i == fo->n ) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
-
- io = fo->objs[ fo->i ];
- fo->i++;
-
- return nss_builtins_CreateMDObject(arena, io, pError);
-}
-
-static int
-builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest) {
- unsigned char *start = src;
- int len = 0;
-
- if (*src ++ != 2) {
- return 0;
- }
- len = *src++;
- if (len & 0x80) {
- int count = len & 0x7f;
- len =0;
-
- if (count+2 > size) {
- return 0;
- }
- while (count-- > 0) {
- len = (len << 8) | *src++;
- }
- }
- if (len + (src-start) != size) {
- return 0;
- }
- *dest = src;
- return len;
-}
-
-static CK_BBOOL
-builtins_attrmatch
-(
- CK_ATTRIBUTE_PTR a,
- const NSSItem *b
-)
-{
- PRBool prb;
-
- if( a->ulValueLen != b->size ) {
- /* match a decoded serial number */
- if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
- int len;
- unsigned char *data;
-
- len = builtins_derUnwrapInt(b->data,b->size,&data);
- if ((len == a->ulValueLen) &&
- nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
- return CK_TRUE;
- }
- }
- return CK_FALSE;
- }
-
- prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
-
- if( PR_TRUE == prb ) {
- return CK_TRUE;
- } else {
- return CK_FALSE;
- }
-}
-
-
-static CK_BBOOL
-builtins_match
-(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- builtinsInternalObject *o
-)
-{
- CK_ULONG i;
-
- for( i = 0; i < ulAttributeCount; i++ ) {
- CK_ULONG j;
-
- for( j = 0; j < o->n; j++ ) {
- if( o->types[j] == pTemplate[i].type ) {
- if( CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j]) ) {
- return CK_FALSE;
- } else {
- break;
- }
- }
- }
-
- if( j == o->n ) {
- /* Loop ran to the end: no matching attribute */
- return CK_FALSE;
- }
- }
-
- /* Every attribute passed */
- return CK_TRUE;
-}
-
-NSS_IMPLEMENT NSSCKMDFindObjects *
-nss_builtins_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- /* This could be made more efficient. I'm rather rushed. */
- NSSArena *arena;
- NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
- struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
- builtinsInternalObject **temp = (builtinsInternalObject **)NULL;
- PRUint32 i;
-
- arena = NSSArena_Create();
- if( (NSSArena *)NULL == arena ) {
- goto loser;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDFindObjects);
- if( (NSSCKMDFindObjects *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fo = nss_ZNEW(arena, struct builtinsFOStr);
- if( (struct builtinsFOStr *)NULL == fo ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fo->arena = arena;
- /* fo->n and fo->i are already zero */
-
- rv->etc = (void *)fo;
- rv->Final = builtins_mdFindObjects_Final;
- rv->Next = builtins_mdFindObjects_Next;
- rv->null = (void *)NULL;
-
- temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
- nss_builtins_nObjects);
- if( (builtinsInternalObject **)NULL == temp ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- for( i = 0; i < nss_builtins_nObjects; i++ ) {
- builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
-
- if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) {
- temp[ fo->n ] = o;
- fo->n++;
- }
- }
-
- fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n);
- if( (builtinsInternalObject **)NULL == fo->objs ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
- nss_ZFreeIf(temp);
- temp = (builtinsInternalObject **)NULL;
-
- return rv;
-
- loser:
- nss_ZFreeIf(temp);
- nss_ZFreeIf(fo);
- nss_ZFreeIf(rv);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
- return (NSSCKMDFindObjects *)NULL;
-}
-
diff --git a/security/nss/lib/ckfw/builtins/binst.c b/security/nss/lib/ckfw/builtins/binst.c
deleted file mode 100644
index d2830c2f8..000000000
--- a/security/nss/lib/ckfw/builtins/binst.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "builtins.h"
-
-/*
- * builtins/instance.c
- *
- * This file implements the NSSCKMDInstance object for the
- * "builtin objects" cryptoki module.
- */
-
-/*
- * NSSCKMDInstance methods
- */
-
-static CK_ULONG
-builtins_mdInstance_GetNSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (CK_ULONG)1;
-}
-
-static CK_VERSION
-builtins_mdInstance_GetCryptokiVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_builtins_CryptokiVersion;
-}
-
-static NSSUTF8 *
-builtins_mdInstance_GetManufacturerID
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_builtins_ManufacturerID;
-}
-
-static NSSUTF8 *
-builtins_mdInstance_GetLibraryDescription
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_builtins_LibraryDescription;
-}
-
-static CK_VERSION
-builtins_mdInstance_GetLibraryVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- extern const char __nss_builtins_rcsid[];
- extern const char __nss_builtins_sccsid[];
- volatile char c; /* force a reference that won't get optimized away */
-
- c = __nss_builtins_rcsid[0] + __nss_builtins_sccsid[0];
- return nss_builtins_LibraryVersion;
-}
-
-static CK_RV
-builtins_mdInstance_GetSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[]
-)
-{
- slots[0] = (NSSCKMDSlot *)&nss_builtins_mdSlot;
- return CKR_OK;
-}
-
-const NSSCKMDInstance
-nss_builtins_mdInstance = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Finalize */
- builtins_mdInstance_GetNSlots,
- builtins_mdInstance_GetCryptokiVersion,
- builtins_mdInstance_GetManufacturerID,
- builtins_mdInstance_GetLibraryDescription,
- builtins_mdInstance_GetLibraryVersion,
- NULL, /* ModuleHandlesSessionObjects -- defaults to false */
- builtins_mdInstance_GetSlots,
- NULL, /* WaitForSlotEvent */
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/builtins/bobject.c b/security/nss/lib/ckfw/builtins/bobject.c
deleted file mode 100644
index f407c207d..000000000
--- a/security/nss/lib/ckfw/builtins/bobject.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "builtins.h"
-
-/*
- * builtins/object.c
- *
- * This file implements the NSSCKMDObject object for the
- * "builtin objects" cryptoki module.
- */
-
-/*
- * Finalize - unneeded
- * Destroy - CKR_SESSION_READ_ONLY
- * IsTokenObject - CK_TRUE
- * GetAttributeCount
- * GetAttributeTypes
- * GetAttributeSize
- * GetAttribute
- * SetAttribute - unneeded
- * GetObjectSize
- */
-
-static CK_RV
-builtins_mdObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CKR_SESSION_READ_ONLY;
-}
-
-static CK_BBOOL
-builtins_mdObject_IsTokenObject
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_TRUE;
-}
-
-static CK_ULONG
-builtins_mdObject_GetAttributeCount
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
- return io->n;
-}
-
-static CK_RV
-builtins_mdObject_GetAttributeTypes
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-)
-{
- builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
- CK_ULONG i;
-
- if( io->n != ulCount ) {
- return CKR_BUFFER_TOO_SMALL;
- }
-
- for( i = 0; i < io->n; i++ ) {
- typeArray[i] = io->types[i];
- }
-
- return CKR_OK;
-}
-
-static CK_ULONG
-builtins_mdObject_GetAttributeSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
- CK_ULONG i;
-
- for( i = 0; i < io->n; i++ ) {
- if( attribute == io->types[i] ) {
- return (CK_ULONG)(io->items[i].size);
- }
- }
-
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return 0;
-}
-
-static NSSCKFWItem
-builtins_mdObject_GetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- NSSCKFWItem mdItem;
- builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
- CK_ULONG i;
-
- mdItem.needsFreeing = PR_FALSE;
- mdItem.item = (NSSItem*) NULL;
-
- for( i = 0; i < io->n; i++ ) {
- if( attribute == io->types[i] ) {
- mdItem.item = (NSSItem*) &io->items[i];
- return mdItem;
- }
- }
-
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return mdItem;
-}
-
-static CK_ULONG
-builtins_mdObject_GetObjectSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
- CK_ULONG i;
- CK_ULONG rv = sizeof(CK_ULONG);
-
- for( i = 0; i < io->n; i++ ) {
- rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size;
- }
-
- return rv;
-}
-
-static const NSSCKMDObject
-builtins_prototype_mdObject = {
- (void *)NULL, /* etc */
- NULL, /* Finalize */
- builtins_mdObject_Destroy,
- builtins_mdObject_IsTokenObject,
- builtins_mdObject_GetAttributeCount,
- builtins_mdObject_GetAttributeTypes,
- builtins_mdObject_GetAttributeSize,
- builtins_mdObject_GetAttribute,
- NULL, /* FreeAttribute */
- NULL, /* SetAttribute */
- builtins_mdObject_GetObjectSize,
- (void *)NULL /* null terminator */
-};
-
-NSS_IMPLEMENT NSSCKMDObject *
-nss_builtins_CreateMDObject
-(
- NSSArena *arena,
- builtinsInternalObject *io,
- CK_RV *pError
-)
-{
- if ( (void*)NULL == io->mdObject.etc) {
- (void) nsslibc_memcpy(&io->mdObject,&builtins_prototype_mdObject,
- sizeof(builtins_prototype_mdObject));
- io->mdObject.etc = (void *)io;
- }
-
- return &io->mdObject;
-}
diff --git a/security/nss/lib/ckfw/builtins/bsession.c b/security/nss/lib/ckfw/builtins/bsession.c
deleted file mode 100644
index 130c2be8c..000000000
--- a/security/nss/lib/ckfw/builtins/bsession.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "builtins.h"
-
-/*
- * builtins/session.c
- *
- * This file implements the NSSCKMDSession object for the
- * "builtin objects" cryptoki module.
- */
-
-static NSSCKMDFindObjects *
-builtins_mdSession_FindObjectsInit
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- return nss_builtins_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
-}
-
-NSS_IMPLEMENT NSSCKMDSession *
-nss_builtins_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
-{
- NSSArena *arena;
- NSSCKMDSession *rv;
-
- arena = NSSCKFWSession_GetArena(fwSession, pError);
- if( (NSSArena *)NULL == arena ) {
- return (NSSCKMDSession *)NULL;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDSession);
- if( (NSSCKMDSession *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDSession *)NULL;
- }
-
- /*
- * rv was zeroed when allocated, so we only
- * need to set the non-zero members.
- */
-
- rv->etc = (void *)fwSession;
- /* rv->Close */
- /* rv->GetDeviceError */
- /* rv->Login */
- /* rv->Logout */
- /* rv->InitPIN */
- /* rv->SetPIN */
- /* rv->GetOperationStateLen */
- /* rv->GetOperationState */
- /* rv->SetOperationState */
- /* rv->CreateObject */
- /* rv->CopyObject */
- rv->FindObjectsInit = builtins_mdSession_FindObjectsInit;
- /* rv->SeedRandom */
- /* rv->GetRandom */
- /* rv->null */
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/builtins/bslot.c b/security/nss/lib/ckfw/builtins/bslot.c
deleted file mode 100644
index 1a5f6982f..000000000
--- a/security/nss/lib/ckfw/builtins/bslot.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "builtins.h"
-
-/*
- * builtins/slot.c
- *
- * This file implements the NSSCKMDSlot object for the
- * "builtin objects" cryptoki module.
- */
-
-static NSSUTF8 *
-builtins_mdSlot_GetSlotDescription
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_builtins_SlotDescription;
-}
-
-static NSSUTF8 *
-builtins_mdSlot_GetManufacturerID
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_builtins_ManufacturerID;
-}
-
-static CK_VERSION
-builtins_mdSlot_GetHardwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_builtins_HardwareVersion;
-}
-
-static CK_VERSION
-builtins_mdSlot_GetFirmwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_builtins_FirmwareVersion;
-}
-
-static NSSCKMDToken *
-builtins_mdSlot_GetToken
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSCKMDToken *)&nss_builtins_mdToken;
-}
-
-const NSSCKMDSlot
-nss_builtins_mdSlot = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Destroy */
- builtins_mdSlot_GetSlotDescription,
- builtins_mdSlot_GetManufacturerID,
- NULL, /* GetTokenPresent -- defaults to true */
- NULL, /* GetRemovableDevice -- defaults to false */
- NULL, /* GetHardwareSlot -- defaults to false */
- builtins_mdSlot_GetHardwareVersion,
- builtins_mdSlot_GetFirmwareVersion,
- builtins_mdSlot_GetToken,
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/builtins/btoken.c b/security/nss/lib/ckfw/builtins/btoken.c
deleted file mode 100644
index 80702a8cd..000000000
--- a/security/nss/lib/ckfw/builtins/btoken.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "builtins.h"
-
-/*
- * builtins/token.c
- *
- * This file implements the NSSCKMDToken object for the
- * "builtin objects" cryptoki module.
- */
-
-static NSSUTF8 *
-builtins_mdToken_GetLabel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_builtins_TokenLabel;
-}
-
-static NSSUTF8 *
-builtins_mdToken_GetManufacturerID
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_builtins_ManufacturerID;
-}
-
-static NSSUTF8 *
-builtins_mdToken_GetModel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_builtins_TokenModel;
-}
-
-static NSSUTF8 *
-builtins_mdToken_GetSerialNumber
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_builtins_TokenSerialNumber;
-}
-
-static CK_BBOOL
-builtins_mdToken_GetIsWriteProtected
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_TRUE;
-}
-
-static CK_VERSION
-builtins_mdToken_GetHardwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_builtins_HardwareVersion;
-}
-
-static CK_VERSION
-builtins_mdToken_GetFirmwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_builtins_FirmwareVersion;
-}
-
-static NSSCKMDSession *
-builtins_mdToken_OpenSession
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_BBOOL rw,
- CK_RV *pError
-)
-{
- return nss_builtins_CreateSession(fwSession, pError);
-}
-
-const NSSCKMDToken
-nss_builtins_mdToken = {
- (void *)NULL, /* etc */
- NULL, /* Setup */
- NULL, /* Invalidate */
- NULL, /* InitToken -- default errs */
- builtins_mdToken_GetLabel,
- builtins_mdToken_GetManufacturerID,
- builtins_mdToken_GetModel,
- builtins_mdToken_GetSerialNumber,
- NULL, /* GetHasRNG -- default is false */
- builtins_mdToken_GetIsWriteProtected,
- NULL, /* GetLoginRequired -- default is false */
- NULL, /* GetUserPinInitialized -- default is false */
- NULL, /* GetRestoreKeyNotNeeded -- irrelevant */
- NULL, /* GetHasClockOnToken -- default is false */
- NULL, /* GetHasProtectedAuthenticationPath -- default is false */
- NULL, /* GetSupportsDualCryptoOperations -- default is false */
- NULL, /* GetMaxSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetMaxRwSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetMaxPinLen -- irrelevant */
- NULL, /* GetMinPinLen -- irrelevant */
- NULL, /* GetTotalPublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetFreePublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetTotalPrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetFreePrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
- builtins_mdToken_GetHardwareVersion,
- builtins_mdToken_GetFirmwareVersion,
- NULL, /* GetUTCTime -- no clock */
- builtins_mdToken_OpenSession,
- NULL, /* GetMechanismCount -- default is zero */
- NULL, /* GetMechanismTypes -- irrelevant */
- NULL, /* GetMechanism -- irrelevant */
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/builtins/builtins.h b/security/nss/lib/ckfw/builtins/builtins.h
deleted file mode 100644
index 9db0fb682..000000000
--- a/security/nss/lib/ckfw/builtins/builtins.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char BUILTINS_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "nssckmdt.h"
-#include "nssckfw.h"
-
-/*
- * I'm including this for access to the arena functions.
- * Looks like we should publish that API.
- */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-/*
- * This is where the Netscape extensions live, at least for now.
- */
-#ifndef CKT_H
-#include "ckt.h"
-#endif /* CKT_H */
-
-struct builtinsInternalObjectStr {
- CK_ULONG n;
- const CK_ATTRIBUTE_TYPE *types;
- const NSSItem *items;
- NSSCKMDObject mdObject;
-};
-typedef struct builtinsInternalObjectStr builtinsInternalObject;
-
-extern builtinsInternalObject nss_builtins_data[];
-extern const PRUint32 nss_builtins_nObjects;
-
-extern const CK_VERSION nss_builtins_CryptokiVersion;
-extern const CK_VERSION nss_builtins_LibraryVersion;
-extern const CK_VERSION nss_builtins_HardwareVersion;
-extern const CK_VERSION nss_builtins_FirmwareVersion;
-
-extern const NSSUTF8 nss_builtins_ManufacturerID[];
-extern const NSSUTF8 nss_builtins_LibraryDescription[];
-extern const NSSUTF8 nss_builtins_SlotDescription[];
-extern const NSSUTF8 nss_builtins_TokenLabel[];
-extern const NSSUTF8 nss_builtins_TokenModel[];
-extern const NSSUTF8 nss_builtins_TokenSerialNumber[];
-
-extern const NSSCKMDInstance nss_builtins_mdInstance;
-extern const NSSCKMDSlot nss_builtins_mdSlot;
-extern const NSSCKMDToken nss_builtins_mdToken;
-
-NSS_EXTERN NSSCKMDSession *
-nss_builtins_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDFindObjects *
-nss_builtins_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDObject *
-nss_builtins_CreateMDObject
-(
- NSSArena *arena,
- builtinsInternalObject *io,
- CK_RV *pError
-);
diff --git a/security/nss/lib/ckfw/builtins/certdata.perl b/security/nss/lib/ckfw/builtins/certdata.perl
deleted file mode 100644
index 26866b803..000000000
--- a/security/nss/lib/ckfw/builtins/certdata.perl
+++ /dev/null
@@ -1,231 +0,0 @@
-#!perl -w
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-my $cvs_id = '@(#) $RCSfile$ $Revision$ $Date$';
-use strict;
-
-my %constants;
-my $count = 0;
-my $o;
-my @objects = ();
-my @objsize;
-my $cvsid;
-
-$constants{CKO_DATA} = "static const CK_OBJECT_CLASS cko_data = CKO_DATA;\n";
-$constants{CK_TRUE} = "static const CK_BBOOL ck_true = CK_TRUE;\n";
-$constants{CK_FALSE} = "static const CK_BBOOL ck_false = CK_FALSE;\n";
-
-while(<>) {
- my @fields = ();
- my $size;
-
- s/^((?:[^"#]+|"[^"]*")*)(\s*#.*$)/$1/;
- next if (/^\s*$/);
-
- if( /(^CVS_ID\s+)(.*)/ ) {
- $cvsid = $2 . "\"; $cvs_id\"";
- my $scratch = $cvsid;
- $size = 1 + $scratch =~ s/[^"\n]//g;
- @{$objects[0][0]} = ( "CKA_CLASS", "&cko_data", "sizeof(CK_OBJECT_CLASS)" );
- @{$objects[0][1]} = ( "CKA_TOKEN", "&ck_true", "sizeof(CK_BBOOL)" );
- @{$objects[0][2]} = ( "CKA_PRIVATE", "&ck_false", "sizeof(CK_BBOOL)" );
- @{$objects[0][3]} = ( "CKA_MODIFIABLE", "&ck_false", "sizeof(CK_BBOOL)" );
- @{$objects[0][4]} = ( "CKA_LABEL", "\"CVS ID\"", "7" );
- @{$objects[0][5]} = ( "CKA_APPLICATION", "\"NSS\"", "4" );
- @{$objects[0][6]} = ( "CKA_VALUE", $cvsid, "$size" );
- $objsize[0] = 7;
- next;
- }
-
- # This was taken from the perl faq #4.
- my $text = $_;
- push(@fields, $+) while $text =~ m{
- "([^\"\\]*(?:\\.[^\"\\]*)*)"\s? # groups the phrase inside the quotes
- | ([^\s]+)\s?
- | \s
- }gx;
- push(@fields, undef) if substr($text,-1,1) eq '\s';
-
- if( $fields[0] =~ /BEGINDATA/ ) {
- next;
- }
-
- if( $fields[1] =~ /MULTILINE/ ) {
- $fields[2] = "";
- while(<>) {
- last if /END/;
- chomp;
- $fields[2] .= "\"$_\"\n";
- }
- }
-
- if( $fields[1] =~ /UTF8/ ) {
- if( $fields[2] =~ /^"/ ) {
- ;
- } else {
- $fields[2] = "\"" . $fields[2] . "\"";
- }
-
- my $scratch = eval($fields[2]);
-
- $size = length($scratch) + 1; # null terminate
- }
-
- if( $fields[1] =~ /OCTAL/ ) {
- if( $fields[2] =~ /^"/ ) {
- ;
- } else {
- $fields[2] = "\"" . $fields[2] . "\"";
- }
-
- my $scratch = $fields[2];
- $size = $scratch =~ tr/\\//;
- # no null termination
- }
-
- if( $fields[1] =~ /^CK_/ ) {
- my $lcv = $fields[2];
- $lcv =~ tr/A-Z/a-z/;
- if( !defined($constants{$fields[2]}) ) {
- $constants{$fields[2]} = "static const $fields[1] $lcv = $fields[2];\n";
- }
-
- $size = "sizeof($fields[1])";
- $fields[2] = "&$lcv";
- }
-
- if( $fields[0] =~ /CKA_CLASS/ ) {
- $count++;
- $objsize[$count] = 0;
- }
-
- @{$objects[$count][$objsize[$count]++]} = ( "$fields[0]", $fields[2], "$size" );
-
- # print "$fields[0] | $fields[1] | $size | $fields[2]\n";
-}
-
-doprint();
-
-sub dudump {
-my $i;
-for( $i = 0; $i <= $count; $i++ ) {
- print "\n";
- $o = $objects[$i];
- my @ob = @{$o};
- my $l;
- my $j;
- for( $j = 0; $j < @ob; $j++ ) {
- $l = $ob[$j];
- my @a = @{$l};
- print "$a[0] ! $a[1] ! $a[2]\n";
- }
-}
-
-}
-
-sub doprint {
-my $i;
-
-print <<EOD
-/* THIS IS A GENERATED FILE */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef DEBUG
-static const char CVS_ID[] = $cvsid;
-#endif /* DEBUG */
-
-#ifndef BUILTINS_H
-#include "builtins.h"
-#endif /* BUILTINS_H */
-
-EOD
- ;
-
-foreach $b (sort values(%constants)) {
- print $b;
-}
-
-for( $i = 0; $i <= $count; $i++ ) {
- if( 0 == $i ) {
- print "#ifdef DEBUG\n";
- }
-
- print "static const CK_ATTRIBUTE_TYPE nss_builtins_types_$i [] = {\n";
- $o = $objects[$i];
- my @ob = @{$o};
- my $j;
- for( $j = 0; $j < @ob; $j++ ) {
- my $l = $ob[$j];
- my @a = @{$l};
- print " $a[0]";
- if( $j+1 != @ob ) {
- print ", ";
- }
- }
- print "\n};\n";
-
- if( 0 == $i ) {
- print "#endif /* DEBUG */\n";
- }
-}
-
-for( $i = 0; $i <= $count; $i++ ) {
- if( 0 == $i ) {
- print "#ifdef DEBUG\n";
- }
-
- print "static const NSSItem nss_builtins_items_$i [] = {\n";
- $o = $objects[$i];
- my @ob = @{$o};
- my $j;
- for( $j = 0; $j < @ob; $j++ ) {
- my $l = $ob[$j];
- my @a = @{$l};
- print " { (void *)$a[1], (PRUint32)$a[2] }";
- if( $j+1 != @ob ) {
- print ",\n";
- } else {
- print "\n";
- }
- }
- print "};\n";
-
- if( 0 == $i ) {
- print "#endif /* DEBUG */\n";
- }
-}
-
-print "\nbuiltinsInternalObject\n";
-print "nss_builtins_data[] = {\n";
-
-for( $i = 0; $i <= $count; $i++ ) {
-
- if( 0 == $i ) {
- print "#ifdef DEBUG\n";
- }
-
- print " { $objsize[$i], nss_builtins_types_$i, nss_builtins_items_$i, {NULL} }";
-
- if( $i == $count ) {
- print "\n";
- } else {
- print ",\n";
- }
-
- if( 0 == $i ) {
- print "#endif /* DEBUG */\n";
- }
-}
-
-print "};\n";
-
-print "const PRUint32\n";
-print "#ifdef DEBUG\n";
-print " nss_builtins_nObjects = $count+1;\n";
-print "#else\n";
-print " nss_builtins_nObjects = $count;\n";
-print "#endif /* DEBUG */\n";
-}
diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt
deleted file mode 100644
index f1ffb17cb..000000000
--- a/security/nss/lib/ckfw/builtins/certdata.txt
+++ /dev/null
@@ -1,24785 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CVS_ID "@(#) $RCSfile$ $Revision$ $Date$"
-
-#
-# certdata.txt
-#
-# This file contains the object definitions for the certs and other
-# information "built into" NSS.
-#
-# Object definitions:
-#
-# Certificates
-#
-# -- Attribute -- -- type -- -- value --
-# CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-# CKA_TOKEN CK_BBOOL CK_TRUE
-# CKA_PRIVATE CK_BBOOL CK_FALSE
-# CKA_MODIFIABLE CK_BBOOL CK_FALSE
-# CKA_LABEL UTF8 (varies)
-# CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-# CKA_SUBJECT DER+base64 (varies)
-# CKA_ID byte array (varies)
-# CKA_ISSUER DER+base64 (varies)
-# CKA_SERIAL_NUMBER DER+base64 (varies)
-# CKA_VALUE DER+base64 (varies)
-# CKA_NSS_EMAIL ASCII7 (unused here)
-#
-# Trust
-#
-# -- Attribute -- -- type -- -- value --
-# CKA_CLASS CK_OBJECT_CLASS CKO_TRUST
-# CKA_TOKEN CK_BBOOL CK_TRUE
-# CKA_PRIVATE CK_BBOOL CK_FALSE
-# CKA_MODIFIABLE CK_BBOOL CK_FALSE
-# CKA_LABEL UTF8 (varies)
-# CKA_ISSUER DER+base64 (varies)
-# CKA_SERIAL_NUMBER DER+base64 (varies)
-# CKA_CERT_HASH binary+base64 (varies)
-# CKA_EXPIRES CK_DATE (not used here)
-# CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST (varies)
-# CKA_TRUST_NON_REPUDIATION CK_TRUST (varies)
-# CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST (varies)
-# CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST (varies)
-# CKA_TRUST_KEY_AGREEMENT CK_TRUST (varies)
-# CKA_TRUST_KEY_CERT_SIGN CK_TRUST (varies)
-# CKA_TRUST_CRL_SIGN CK_TRUST (varies)
-# CKA_TRUST_SERVER_AUTH CK_TRUST (varies)
-# CKA_TRUST_CLIENT_AUTH CK_TRUST (varies)
-# CKA_TRUST_CODE_SIGNING CK_TRUST (varies)
-# CKA_TRUST_EMAIL_PROTECTION CK_TRUST (varies)
-# CKA_TRUST_IPSEC_END_SYSTEM CK_TRUST (varies)
-# CKA_TRUST_IPSEC_TUNNEL CK_TRUST (varies)
-# CKA_TRUST_IPSEC_USER CK_TRUST (varies)
-# CKA_TRUST_TIME_STAMPING CK_TRUST (varies)
-# CKA_TRUST_STEP_UP_APPROVED CK_BBOOL (varies)
-# (other trust attributes can be defined)
-#
-
-#
-# The object to tell NSS that this is a root list and we don't
-# have to go looking for others.
-#
-BEGINDATA
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_BUILTIN_ROOT_LIST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Mozilla Builtin Roots"
-
-#
-# Certificate "GTE CyberTrust Global Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GTE CyberTrust Global Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\030\060\026\006\003\125\004\012\023\017\107\124\105\040\103\157
-\162\160\157\162\141\164\151\157\156\061\047\060\045\006\003\125
-\004\013\023\036\107\124\105\040\103\171\142\145\162\124\162\165
-\163\164\040\123\157\154\165\164\151\157\156\163\054\040\111\156
-\143\056\061\043\060\041\006\003\125\004\003\023\032\107\124\105
-\040\103\171\142\145\162\124\162\165\163\164\040\107\154\157\142
-\141\154\040\122\157\157\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\030\060\026\006\003\125\004\012\023\017\107\124\105\040\103\157
-\162\160\157\162\141\164\151\157\156\061\047\060\045\006\003\125
-\004\013\023\036\107\124\105\040\103\171\142\145\162\124\162\165
-\163\164\040\123\157\154\165\164\151\157\156\163\054\040\111\156
-\143\056\061\043\060\041\006\003\125\004\003\023\032\107\124\105
-\040\103\171\142\145\162\124\162\165\163\164\040\107\154\157\142
-\141\154\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\001\245
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\132\060\202\001\303\002\002\001\245\060\015\006\011
-\052\206\110\206\367\015\001\001\004\005\000\060\165\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\030\060\026\006\003
-\125\004\012\023\017\107\124\105\040\103\157\162\160\157\162\141
-\164\151\157\156\061\047\060\045\006\003\125\004\013\023\036\107
-\124\105\040\103\171\142\145\162\124\162\165\163\164\040\123\157
-\154\165\164\151\157\156\163\054\040\111\156\143\056\061\043\060
-\041\006\003\125\004\003\023\032\107\124\105\040\103\171\142\145
-\162\124\162\165\163\164\040\107\154\157\142\141\154\040\122\157
-\157\164\060\036\027\015\071\070\060\070\061\063\060\060\062\071
-\060\060\132\027\015\061\070\060\070\061\063\062\063\065\071\060
-\060\132\060\165\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\030\060\026\006\003\125\004\012\023\017\107\124\105\040
-\103\157\162\160\157\162\141\164\151\157\156\061\047\060\045\006
-\003\125\004\013\023\036\107\124\105\040\103\171\142\145\162\124
-\162\165\163\164\040\123\157\154\165\164\151\157\156\163\054\040
-\111\156\143\056\061\043\060\041\006\003\125\004\003\023\032\107
-\124\105\040\103\171\142\145\162\124\162\165\163\164\040\107\154
-\157\142\141\154\040\122\157\157\164\060\201\237\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\201\215\000\060
-\201\211\002\201\201\000\225\017\240\266\360\120\234\350\172\307
-\210\315\335\027\016\056\260\224\320\033\075\016\366\224\300\212
-\224\307\006\310\220\227\310\270\144\032\172\176\154\074\123\341
-\067\050\163\140\177\262\227\123\007\237\123\371\155\130\224\322
-\257\215\155\210\147\200\346\355\262\225\317\162\061\312\245\034
-\162\272\134\002\347\144\102\347\371\251\054\326\072\015\254\215
-\102\252\044\001\071\346\234\077\001\205\127\015\130\207\105\370
-\323\205\252\223\151\046\205\160\110\200\077\022\025\307\171\264
-\037\005\057\073\142\231\002\003\001\000\001\060\015\006\011\052
-\206\110\206\367\015\001\001\004\005\000\003\201\201\000\155\353
-\033\011\351\136\331\121\333\147\042\141\244\052\074\110\167\343
-\240\174\246\336\163\242\024\003\205\075\373\253\016\060\305\203
-\026\063\201\023\010\236\173\064\116\337\100\310\164\327\271\175
-\334\364\166\125\175\233\143\124\030\351\360\352\363\134\261\331
-\213\102\036\271\300\225\116\272\372\325\342\174\365\150\141\277
-\216\354\005\227\137\133\260\327\243\205\064\304\044\247\015\017
-\225\223\357\313\224\330\236\037\235\134\205\155\307\252\256\117
-\037\042\265\315\225\255\272\247\314\371\253\013\172\177
-END
-
-# Trust for Certificate "GTE CyberTrust Global Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GTE CyberTrust Global Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\227\201\171\120\330\034\226\160\314\064\330\011\317\171\104\061
-\066\176\364\164
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\312\075\323\150\361\003\134\320\062\372\270\053\131\350\132\333
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\030\060\026\006\003\125\004\012\023\017\107\124\105\040\103\157
-\162\160\157\162\141\164\151\157\156\061\047\060\045\006\003\125
-\004\013\023\036\107\124\105\040\103\171\142\145\162\124\162\165
-\163\164\040\123\157\154\165\164\151\157\156\163\054\040\111\156
-\143\056\061\043\060\041\006\003\125\004\003\023\032\107\124\105
-\040\103\171\142\145\162\124\162\165\163\164\040\107\154\157\142
-\141\154\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\001\245
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Thawte Server CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Thawte Server CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\304\061\013\060\011\006\003\125\004\006\023\002\132\101
-\061\025\060\023\006\003\125\004\010\023\014\127\145\163\164\145
-\162\156\040\103\141\160\145\061\022\060\020\006\003\125\004\007
-\023\011\103\141\160\145\040\124\157\167\156\061\035\060\033\006
-\003\125\004\012\023\024\124\150\141\167\164\145\040\103\157\156
-\163\165\154\164\151\156\147\040\143\143\061\050\060\046\006\003
-\125\004\013\023\037\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\123\145\162\166\151\143\145\163\040\104\151\166\151
-\163\151\157\156\061\031\060\027\006\003\125\004\003\023\020\124
-\150\141\167\164\145\040\123\145\162\166\145\162\040\103\101\061
-\046\060\044\006\011\052\206\110\206\367\015\001\011\001\026\027
-\163\145\162\166\145\162\055\143\145\162\164\163\100\164\150\141
-\167\164\145\056\143\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\304\061\013\060\011\006\003\125\004\006\023\002\132\101
-\061\025\060\023\006\003\125\004\010\023\014\127\145\163\164\145
-\162\156\040\103\141\160\145\061\022\060\020\006\003\125\004\007
-\023\011\103\141\160\145\040\124\157\167\156\061\035\060\033\006
-\003\125\004\012\023\024\124\150\141\167\164\145\040\103\157\156
-\163\165\154\164\151\156\147\040\143\143\061\050\060\046\006\003
-\125\004\013\023\037\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\123\145\162\166\151\143\145\163\040\104\151\166\151
-\163\151\157\156\061\031\060\027\006\003\125\004\003\023\020\124
-\150\141\167\164\145\040\123\145\162\166\145\162\040\103\101\061
-\046\060\044\006\011\052\206\110\206\367\015\001\011\001\026\027
-\163\145\162\166\145\162\055\143\145\162\164\163\100\164\150\141
-\167\164\145\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\023\060\202\002\174\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060
-\201\304\061\013\060\011\006\003\125\004\006\023\002\132\101\061
-\025\060\023\006\003\125\004\010\023\014\127\145\163\164\145\162
-\156\040\103\141\160\145\061\022\060\020\006\003\125\004\007\023
-\011\103\141\160\145\040\124\157\167\156\061\035\060\033\006\003
-\125\004\012\023\024\124\150\141\167\164\145\040\103\157\156\163
-\165\154\164\151\156\147\040\143\143\061\050\060\046\006\003\125
-\004\013\023\037\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\123\145\162\166\151\143\145\163\040\104\151\166\151\163
-\151\157\156\061\031\060\027\006\003\125\004\003\023\020\124\150
-\141\167\164\145\040\123\145\162\166\145\162\040\103\101\061\046
-\060\044\006\011\052\206\110\206\367\015\001\011\001\026\027\163
-\145\162\166\145\162\055\143\145\162\164\163\100\164\150\141\167
-\164\145\056\143\157\155\060\036\027\015\071\066\060\070\060\061
-\060\060\060\060\060\060\132\027\015\062\060\061\062\063\061\062
-\063\065\071\065\071\132\060\201\304\061\013\060\011\006\003\125
-\004\006\023\002\132\101\061\025\060\023\006\003\125\004\010\023
-\014\127\145\163\164\145\162\156\040\103\141\160\145\061\022\060
-\020\006\003\125\004\007\023\011\103\141\160\145\040\124\157\167
-\156\061\035\060\033\006\003\125\004\012\023\024\124\150\141\167
-\164\145\040\103\157\156\163\165\154\164\151\156\147\040\143\143
-\061\050\060\046\006\003\125\004\013\023\037\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\123\145\162\166\151\143\145
-\163\040\104\151\166\151\163\151\157\156\061\031\060\027\006\003
-\125\004\003\023\020\124\150\141\167\164\145\040\123\145\162\166
-\145\162\040\103\101\061\046\060\044\006\011\052\206\110\206\367
-\015\001\011\001\026\027\163\145\162\166\145\162\055\143\145\162
-\164\163\100\164\150\141\167\164\145\056\143\157\155\060\201\237
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\201\215\000\060\201\211\002\201\201\000\323\244\120\156\310\377
-\126\153\346\317\135\266\352\014\150\165\107\242\252\302\332\204
-\045\374\250\364\107\121\332\205\265\040\164\224\206\036\017\165
-\311\351\010\141\365\006\155\060\156\025\031\002\351\122\300\142
-\333\115\231\236\342\152\014\104\070\315\376\276\343\144\011\160
-\305\376\261\153\051\266\057\111\310\073\324\047\004\045\020\227
-\057\347\220\155\300\050\102\231\327\114\103\336\303\365\041\155
-\124\237\135\303\130\341\300\344\331\133\260\270\334\264\173\337
-\066\072\302\265\146\042\022\326\207\015\002\003\001\000\001\243
-\023\060\021\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\015\006\011\052\206\110\206\367\015\001\001
-\004\005\000\003\201\201\000\007\372\114\151\134\373\225\314\106
-\356\205\203\115\041\060\216\312\331\250\157\111\032\346\332\121
-\343\140\160\154\204\141\021\241\032\310\110\076\131\103\175\117
-\225\075\241\213\267\013\142\230\172\165\212\335\210\116\116\236
-\100\333\250\314\062\164\271\157\015\306\343\263\104\013\331\212
-\157\232\051\233\231\030\050\073\321\343\100\050\232\132\074\325
-\265\347\040\033\213\312\244\253\215\351\121\331\342\114\054\131
-\251\332\271\262\165\033\366\102\362\357\307\362\030\371\211\274
-\243\377\212\043\056\160\107
-END
-
-# Trust for Certificate "Thawte Server CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Thawte Server CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\043\345\224\224\121\225\362\101\110\003\264\325\144\322\243\243
-\365\330\213\214
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\305\160\304\242\355\123\170\014\310\020\123\201\144\313\320\035
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\304\061\013\060\011\006\003\125\004\006\023\002\132\101
-\061\025\060\023\006\003\125\004\010\023\014\127\145\163\164\145
-\162\156\040\103\141\160\145\061\022\060\020\006\003\125\004\007
-\023\011\103\141\160\145\040\124\157\167\156\061\035\060\033\006
-\003\125\004\012\023\024\124\150\141\167\164\145\040\103\157\156
-\163\165\154\164\151\156\147\040\143\143\061\050\060\046\006\003
-\125\004\013\023\037\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\123\145\162\166\151\143\145\163\040\104\151\166\151
-\163\151\157\156\061\031\060\027\006\003\125\004\003\023\020\124
-\150\141\167\164\145\040\123\145\162\166\145\162\040\103\101\061
-\046\060\044\006\011\052\206\110\206\367\015\001\011\001\026\027
-\163\145\162\166\145\162\055\143\145\162\164\163\100\164\150\141
-\167\164\145\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Thawte Premium Server CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Thawte Premium Server CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\316\061\013\060\011\006\003\125\004\006\023\002\132\101
-\061\025\060\023\006\003\125\004\010\023\014\127\145\163\164\145
-\162\156\040\103\141\160\145\061\022\060\020\006\003\125\004\007
-\023\011\103\141\160\145\040\124\157\167\156\061\035\060\033\006
-\003\125\004\012\023\024\124\150\141\167\164\145\040\103\157\156
-\163\165\154\164\151\156\147\040\143\143\061\050\060\046\006\003
-\125\004\013\023\037\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\123\145\162\166\151\143\145\163\040\104\151\166\151
-\163\151\157\156\061\041\060\037\006\003\125\004\003\023\030\124
-\150\141\167\164\145\040\120\162\145\155\151\165\155\040\123\145
-\162\166\145\162\040\103\101\061\050\060\046\006\011\052\206\110
-\206\367\015\001\011\001\026\031\160\162\145\155\151\165\155\055
-\163\145\162\166\145\162\100\164\150\141\167\164\145\056\143\157
-\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\316\061\013\060\011\006\003\125\004\006\023\002\132\101
-\061\025\060\023\006\003\125\004\010\023\014\127\145\163\164\145
-\162\156\040\103\141\160\145\061\022\060\020\006\003\125\004\007
-\023\011\103\141\160\145\040\124\157\167\156\061\035\060\033\006
-\003\125\004\012\023\024\124\150\141\167\164\145\040\103\157\156
-\163\165\154\164\151\156\147\040\143\143\061\050\060\046\006\003
-\125\004\013\023\037\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\123\145\162\166\151\143\145\163\040\104\151\166\151
-\163\151\157\156\061\041\060\037\006\003\125\004\003\023\030\124
-\150\141\167\164\145\040\120\162\145\155\151\165\155\040\123\145
-\162\166\145\162\040\103\101\061\050\060\046\006\011\052\206\110
-\206\367\015\001\011\001\026\031\160\162\145\155\151\165\155\055
-\163\145\162\166\145\162\100\164\150\141\167\164\145\056\143\157
-\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\047\060\202\002\220\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060
-\201\316\061\013\060\011\006\003\125\004\006\023\002\132\101\061
-\025\060\023\006\003\125\004\010\023\014\127\145\163\164\145\162
-\156\040\103\141\160\145\061\022\060\020\006\003\125\004\007\023
-\011\103\141\160\145\040\124\157\167\156\061\035\060\033\006\003
-\125\004\012\023\024\124\150\141\167\164\145\040\103\157\156\163
-\165\154\164\151\156\147\040\143\143\061\050\060\046\006\003\125
-\004\013\023\037\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\123\145\162\166\151\143\145\163\040\104\151\166\151\163
-\151\157\156\061\041\060\037\006\003\125\004\003\023\030\124\150
-\141\167\164\145\040\120\162\145\155\151\165\155\040\123\145\162
-\166\145\162\040\103\101\061\050\060\046\006\011\052\206\110\206
-\367\015\001\011\001\026\031\160\162\145\155\151\165\155\055\163
-\145\162\166\145\162\100\164\150\141\167\164\145\056\143\157\155
-\060\036\027\015\071\066\060\070\060\061\060\060\060\060\060\060
-\132\027\015\062\060\061\062\063\061\062\063\065\071\065\071\132
-\060\201\316\061\013\060\011\006\003\125\004\006\023\002\132\101
-\061\025\060\023\006\003\125\004\010\023\014\127\145\163\164\145
-\162\156\040\103\141\160\145\061\022\060\020\006\003\125\004\007
-\023\011\103\141\160\145\040\124\157\167\156\061\035\060\033\006
-\003\125\004\012\023\024\124\150\141\167\164\145\040\103\157\156
-\163\165\154\164\151\156\147\040\143\143\061\050\060\046\006\003
-\125\004\013\023\037\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\123\145\162\166\151\143\145\163\040\104\151\166\151
-\163\151\157\156\061\041\060\037\006\003\125\004\003\023\030\124
-\150\141\167\164\145\040\120\162\145\155\151\165\155\040\123\145
-\162\166\145\162\040\103\101\061\050\060\046\006\011\052\206\110
-\206\367\015\001\011\001\026\031\160\162\145\155\151\165\155\055
-\163\145\162\166\145\162\100\164\150\141\167\164\145\056\143\157
-\155\060\201\237\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\201\215\000\060\201\211\002\201\201\000\322\066
-\066\152\213\327\302\133\236\332\201\101\142\217\070\356\111\004
-\125\326\320\357\034\033\225\026\107\357\030\110\065\072\122\364
-\053\152\006\217\073\057\352\126\343\257\206\215\236\027\367\236
-\264\145\165\002\115\357\313\011\242\041\121\330\233\320\147\320
-\272\015\222\006\024\163\324\223\313\227\052\000\234\134\116\014
-\274\372\025\122\374\362\104\156\332\021\112\156\010\237\057\055
-\343\371\252\072\206\163\266\106\123\130\310\211\005\275\203\021
-\270\163\077\252\007\215\364\102\115\347\100\235\034\067\002\003
-\001\000\001\243\023\060\021\060\017\006\003\125\035\023\001\001
-\377\004\005\060\003\001\001\377\060\015\006\011\052\206\110\206
-\367\015\001\001\004\005\000\003\201\201\000\046\110\054\026\302
-\130\372\350\026\164\014\252\252\137\124\077\362\327\311\170\140
-\136\136\156\067\143\042\167\066\176\262\027\304\064\271\365\010
-\205\374\311\001\070\377\115\276\362\026\102\103\347\273\132\106
-\373\301\306\021\037\361\112\260\050\106\311\303\304\102\175\274
-\372\253\131\156\325\267\121\210\021\343\244\205\031\153\202\114
-\244\014\022\255\351\244\256\077\361\303\111\145\232\214\305\310
-\076\045\267\224\231\273\222\062\161\007\360\206\136\355\120\047
-\246\015\246\043\371\273\313\246\007\024\102
-END
-
-# Trust for Certificate "Thawte Premium Server CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Thawte Premium Server CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\142\177\215\170\047\145\143\231\322\175\177\220\104\311\376\263
-\363\076\372\232
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\006\237\151\171\026\146\220\002\033\214\214\242\303\007\157\072
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\316\061\013\060\011\006\003\125\004\006\023\002\132\101
-\061\025\060\023\006\003\125\004\010\023\014\127\145\163\164\145
-\162\156\040\103\141\160\145\061\022\060\020\006\003\125\004\007
-\023\011\103\141\160\145\040\124\157\167\156\061\035\060\033\006
-\003\125\004\012\023\024\124\150\141\167\164\145\040\103\157\156
-\163\165\154\164\151\156\147\040\143\143\061\050\060\046\006\003
-\125\004\013\023\037\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\123\145\162\166\151\143\145\163\040\104\151\166\151
-\163\151\157\156\061\041\060\037\006\003\125\004\003\023\030\124
-\150\141\167\164\145\040\120\162\145\155\151\165\155\040\123\145
-\162\166\145\162\040\103\101\061\050\060\046\006\011\052\206\110
-\206\367\015\001\011\001\026\031\160\162\145\155\151\165\155\055
-\163\145\162\166\145\162\100\164\150\141\167\164\145\056\143\157
-\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Equifax Secure CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Equifax Secure CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\020\060\016\006\003\125\004\012\023\007\105\161\165\151\146\141
-\170\061\055\060\053\006\003\125\004\013\023\044\105\161\165\151
-\146\141\170\040\123\145\143\165\162\145\040\103\145\162\164\151
-\146\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\020\060\016\006\003\125\004\012\023\007\105\161\165\151\146\141
-\170\061\055\060\053\006\003\125\004\013\023\044\105\161\165\151
-\146\141\170\040\123\145\143\165\162\145\040\103\145\162\164\151
-\146\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\065\336\364\317
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\040\060\202\002\211\240\003\002\001\002\002\004\065
-\336\364\317\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\116\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\020\060\016\006\003\125\004\012\023\007\105\161\165\151
-\146\141\170\061\055\060\053\006\003\125\004\013\023\044\105\161
-\165\151\146\141\170\040\123\145\143\165\162\145\040\103\145\162
-\164\151\146\151\143\141\164\145\040\101\165\164\150\157\162\151
-\164\171\060\036\027\015\071\070\060\070\062\062\061\066\064\061
-\065\061\132\027\015\061\070\060\070\062\062\061\066\064\061\065
-\061\132\060\116\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\020\060\016\006\003\125\004\012\023\007\105\161\165\151
-\146\141\170\061\055\060\053\006\003\125\004\013\023\044\105\161
-\165\151\146\141\170\040\123\145\143\165\162\145\040\103\145\162
-\164\151\146\151\143\141\164\145\040\101\165\164\150\157\162\151
-\164\171\060\201\237\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\201\215\000\060\201\211\002\201\201\000\301
-\135\261\130\147\010\142\356\240\232\055\037\010\155\221\024\150
-\230\012\036\376\332\004\157\023\204\142\041\303\321\174\316\237
-\005\340\270\001\360\116\064\354\342\212\225\004\144\254\361\153
-\123\137\005\263\313\147\200\277\102\002\216\376\335\001\011\354
-\341\000\024\117\374\373\360\014\335\103\272\133\053\341\037\200
-\160\231\025\127\223\026\361\017\227\152\267\302\150\043\034\314
-\115\131\060\254\121\036\073\257\053\326\356\143\105\173\305\331
-\137\120\322\343\120\017\072\210\347\277\024\375\340\307\271\002
-\003\001\000\001\243\202\001\011\060\202\001\005\060\160\006\003
-\125\035\037\004\151\060\147\060\145\240\143\240\141\244\137\060
-\135\061\013\060\011\006\003\125\004\006\023\002\125\123\061\020
-\060\016\006\003\125\004\012\023\007\105\161\165\151\146\141\170
-\061\055\060\053\006\003\125\004\013\023\044\105\161\165\151\146
-\141\170\040\123\145\143\165\162\145\040\103\145\162\164\151\146
-\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171\061
-\015\060\013\006\003\125\004\003\023\004\103\122\114\061\060\032
-\006\003\125\035\020\004\023\060\021\201\017\062\060\061\070\060
-\070\062\062\061\066\064\061\065\061\132\060\013\006\003\125\035
-\017\004\004\003\002\001\006\060\037\006\003\125\035\043\004\030
-\060\026\200\024\110\346\150\371\053\322\262\225\327\107\330\043
-\040\020\117\063\230\220\237\324\060\035\006\003\125\035\016\004
-\026\004\024\110\346\150\371\053\322\262\225\327\107\330\043\040
-\020\117\063\230\220\237\324\060\014\006\003\125\035\023\004\005
-\060\003\001\001\377\060\032\006\011\052\206\110\206\366\175\007
-\101\000\004\015\060\013\033\005\126\063\056\060\143\003\002\006
-\300\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\201\201\000\130\316\051\352\374\367\336\265\316\002\271\027
-\265\205\321\271\343\340\225\314\045\061\015\000\246\222\156\177
-\266\222\143\236\120\225\321\232\157\344\021\336\143\205\156\230
-\356\250\377\132\310\323\125\262\146\161\127\336\300\041\353\075
-\052\247\043\111\001\004\206\102\173\374\356\177\242\026\122\265
-\147\147\323\100\333\073\046\130\262\050\167\075\256\024\167\141
-\326\372\052\146\047\240\015\372\247\163\134\352\160\361\224\041
-\145\104\137\372\374\357\051\150\251\242\207\171\357\171\357\117
-\254\007\167\070
-END
-
-# Trust for Certificate "Equifax Secure CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Equifax Secure CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\322\062\011\255\043\323\024\043\041\164\344\015\177\235\142\023
-\227\206\143\072
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\147\313\235\300\023\044\212\202\233\262\027\036\321\033\354\324
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\020\060\016\006\003\125\004\012\023\007\105\161\165\151\146\141
-\170\061\055\060\053\006\003\125\004\013\023\044\105\161\165\151
-\146\141\170\040\123\145\143\165\162\145\040\103\145\162\164\151
-\146\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\065\336\364\317
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Digital Signature Trust Co. Global CA 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Digital Signature Trust Co. Global CA 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\066\160\025\226
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\051\060\202\002\222\240\003\002\001\002\002\004\066
-\160\025\226\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\106\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\044\060\042\006\003\125\004\012\023\033\104\151\147\151
-\164\141\154\040\123\151\147\156\141\164\165\162\145\040\124\162
-\165\163\164\040\103\157\056\061\021\060\017\006\003\125\004\013
-\023\010\104\123\124\103\101\040\105\061\060\036\027\015\071\070
-\061\062\061\060\061\070\061\060\062\063\132\027\015\061\070\061
-\062\061\060\061\070\064\060\062\063\132\060\106\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\044\060\042\006\003\125
-\004\012\023\033\104\151\147\151\164\141\154\040\123\151\147\156
-\141\164\165\162\145\040\124\162\165\163\164\040\103\157\056\061
-\021\060\017\006\003\125\004\013\023\010\104\123\124\103\101\040
-\105\061\060\201\235\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\201\213\000\060\201\207\002\201\201\000\240
-\154\201\251\317\064\036\044\335\376\206\050\314\336\203\057\371
-\136\324\102\322\350\164\140\146\023\230\006\034\251\121\022\151
-\157\061\125\271\111\162\000\010\176\323\245\142\104\067\044\231
-\217\331\203\110\217\231\155\225\023\273\103\073\056\111\116\210
-\067\301\273\130\177\376\341\275\370\273\141\315\363\107\300\231
-\246\361\363\221\350\170\174\000\313\141\311\104\047\161\151\125
-\112\176\111\115\355\242\243\276\002\114\000\312\002\250\356\001
-\002\061\144\017\122\055\023\164\166\066\265\172\264\055\161\002
-\001\003\243\202\001\044\060\202\001\040\060\021\006\011\140\206
-\110\001\206\370\102\001\001\004\004\003\002\000\007\060\150\006
-\003\125\035\037\004\141\060\137\060\135\240\133\240\131\244\127
-\060\125\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\061\061\015\060\013\006\003\125\004
-\003\023\004\103\122\114\061\060\053\006\003\125\035\020\004\044
-\060\042\200\017\061\071\071\070\061\062\061\060\061\070\061\060
-\062\063\132\201\017\062\060\061\070\061\062\061\060\061\070\061
-\060\062\063\132\060\013\006\003\125\035\017\004\004\003\002\001
-\006\060\037\006\003\125\035\043\004\030\060\026\200\024\152\171
-\176\221\151\106\030\023\012\002\167\245\131\133\140\230\045\016
-\242\370\060\035\006\003\125\035\016\004\026\004\024\152\171\176
-\221\151\106\030\023\012\002\167\245\131\133\140\230\045\016\242
-\370\060\014\006\003\125\035\023\004\005\060\003\001\001\377\060
-\031\006\011\052\206\110\206\366\175\007\101\000\004\014\060\012
-\033\004\126\064\056\060\003\002\004\220\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\201\201\000\042\022\330
-\172\035\334\201\006\266\011\145\262\207\310\037\136\264\057\351
-\304\036\362\074\301\273\004\220\021\112\203\116\176\223\271\115
-\102\307\222\046\240\134\064\232\070\162\370\375\153\026\076\040
-\356\202\213\061\052\223\066\205\043\210\212\074\003\150\323\311
-\011\017\115\374\154\244\332\050\162\223\016\211\200\260\175\376
-\200\157\145\155\030\063\227\213\302\153\211\356\140\075\310\233
-\357\177\053\062\142\163\223\313\074\343\173\342\166\170\105\274
-\241\223\004\273\206\237\072\133\103\172\303\212\145
-END
-
-# Trust for Certificate "Digital Signature Trust Co. Global CA 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Digital Signature Trust Co. Global CA 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\201\226\213\072\357\034\334\160\365\372\062\151\302\222\243\143
-\133\321\043\323
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\045\172\272\203\056\266\242\013\332\376\365\002\017\010\327\255
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\066\160\025\226
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Digital Signature Trust Co. Global CA 3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Digital Signature Trust Co. Global CA 3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\066\156\323\316
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\051\060\202\002\222\240\003\002\001\002\002\004\066
-\156\323\316\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\106\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\044\060\042\006\003\125\004\012\023\033\104\151\147\151
-\164\141\154\040\123\151\147\156\141\164\165\162\145\040\124\162
-\165\163\164\040\103\157\056\061\021\060\017\006\003\125\004\013
-\023\010\104\123\124\103\101\040\105\062\060\036\027\015\071\070
-\061\062\060\071\061\071\061\067\062\066\132\027\015\061\070\061
-\062\060\071\061\071\064\067\062\066\132\060\106\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\044\060\042\006\003\125
-\004\012\023\033\104\151\147\151\164\141\154\040\123\151\147\156
-\141\164\165\162\145\040\124\162\165\163\164\040\103\157\056\061
-\021\060\017\006\003\125\004\013\023\010\104\123\124\103\101\040
-\105\062\060\201\235\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\201\213\000\060\201\207\002\201\201\000\277
-\223\217\027\222\357\063\023\030\353\020\177\116\026\277\377\006
-\217\052\205\274\136\371\044\246\044\210\266\003\267\301\303\137
-\003\133\321\157\256\176\102\352\146\043\270\143\203\126\373\050
-\055\341\070\213\264\356\250\001\341\316\034\266\210\052\042\106
-\205\373\237\247\160\251\107\024\077\316\336\145\360\250\161\367
-\117\046\154\214\274\306\265\357\336\111\047\377\110\052\175\350
-\115\003\314\307\262\122\306\027\061\023\073\265\115\333\310\304
-\366\303\017\044\052\332\014\235\347\221\133\200\315\224\235\002
-\001\003\243\202\001\044\060\202\001\040\060\021\006\011\140\206
-\110\001\206\370\102\001\001\004\004\003\002\000\007\060\150\006
-\003\125\035\037\004\141\060\137\060\135\240\133\240\131\244\127
-\060\125\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\062\061\015\060\013\006\003\125\004
-\003\023\004\103\122\114\061\060\053\006\003\125\035\020\004\044
-\060\042\200\017\061\071\071\070\061\062\060\071\061\071\061\067
-\062\066\132\201\017\062\060\061\070\061\062\060\071\061\071\061
-\067\062\066\132\060\013\006\003\125\035\017\004\004\003\002\001
-\006\060\037\006\003\125\035\043\004\030\060\026\200\024\036\202
-\115\050\145\200\074\311\101\156\254\065\056\132\313\336\356\370
-\071\133\060\035\006\003\125\035\016\004\026\004\024\036\202\115
-\050\145\200\074\311\101\156\254\065\056\132\313\336\356\370\071
-\133\060\014\006\003\125\035\023\004\005\060\003\001\001\377\060
-\031\006\011\052\206\110\206\366\175\007\101\000\004\014\060\012
-\033\004\126\064\056\060\003\002\004\220\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\201\201\000\107\215\203
-\255\142\362\333\260\236\105\042\005\271\242\326\003\016\070\162
-\347\236\374\173\346\223\266\232\245\242\224\310\064\035\221\321
-\305\327\364\012\045\017\075\170\201\236\017\261\147\304\220\114
-\143\335\136\247\342\272\237\365\367\115\245\061\173\234\051\055
-\114\376\144\076\354\266\123\376\352\233\355\202\333\164\165\113
-\007\171\156\036\330\031\203\163\336\365\076\320\265\336\347\113
-\150\175\103\056\052\040\341\176\240\170\104\236\010\365\230\371
-\307\177\033\033\326\006\040\002\130\241\303\242\003
-END
-
-# Trust for Certificate "Digital Signature Trust Co. Global CA 3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Digital Signature Trust Co. Global CA 3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\253\110\363\063\333\004\253\271\300\162\332\133\014\301\320\127
-\360\066\233\106
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\223\302\216\021\173\324\363\003\031\275\050\165\023\112\105\112
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\106\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\040\103\157\056\061\021\060\017\006\003\125\004\013\023\010
-\104\123\124\103\101\040\105\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\066\156\323\316
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 3 Public Primary Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 3 Public Primary Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151
-\147\156\054\040\111\156\143\056\061\067\060\065\006\003\125\004
-\013\023\056\103\154\141\163\163\040\063\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151
-\147\156\054\040\111\156\143\056\061\067\060\065\006\003\125\004
-\013\023\056\103\154\141\163\163\040\063\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\160\272\344\035\020\331\051\064\266\070\312\173\003\314
-\272\277
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\074\060\202\001\245\002\020\160\272\344\035\020\331
-\051\064\266\070\312\173\003\314\272\277\060\015\006\011\052\206
-\110\206\367\015\001\001\002\005\000\060\137\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125\004
-\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156\143
-\056\061\067\060\065\006\003\125\004\013\023\056\103\154\141\163
-\163\040\063\040\120\165\142\154\151\143\040\120\162\151\155\141
-\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171\060\036\027\015\071\066
-\060\061\062\071\060\060\060\060\060\060\132\027\015\062\070\060
-\070\060\061\062\063\065\071\065\071\132\060\137\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125
-\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156
-\143\056\061\067\060\065\006\003\125\004\013\023\056\103\154\141
-\163\163\040\063\040\120\165\142\154\151\143\040\120\162\151\155
-\141\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\101\165\164\150\157\162\151\164\171\060\201\237\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\201\215
-\000\060\201\211\002\201\201\000\311\134\131\236\362\033\212\001
-\024\264\020\337\004\100\333\343\127\257\152\105\100\217\204\014
-\013\321\063\331\331\021\317\356\002\130\037\045\367\052\250\104
-\005\252\354\003\037\170\177\236\223\271\232\000\252\043\175\326
-\254\205\242\143\105\307\162\047\314\364\114\306\165\161\322\071
-\357\117\102\360\165\337\012\220\306\216\040\157\230\017\370\254
-\043\137\160\051\066\244\311\206\347\261\232\040\313\123\245\205
-\347\075\276\175\232\376\044\105\063\334\166\025\355\017\242\161
-\144\114\145\056\201\150\105\247\002\003\001\000\001\060\015\006
-\011\052\206\110\206\367\015\001\001\002\005\000\003\201\201\000
-\273\114\022\053\317\054\046\000\117\024\023\335\246\373\374\012
-\021\204\214\363\050\034\147\222\057\174\266\305\372\337\360\350
-\225\274\035\217\154\054\250\121\314\163\330\244\300\123\360\116
-\326\046\300\166\001\127\201\222\136\041\361\321\261\377\347\320
-\041\130\315\151\027\343\104\034\234\031\104\071\211\134\334\234
-\000\017\126\215\002\231\355\242\220\105\114\344\273\020\244\075
-\360\062\003\016\361\316\370\350\311\121\214\346\142\237\346\237
-\300\175\267\162\234\311\066\072\153\237\116\250\377\144\015\144
-END
-
-# Trust for Certificate "Verisign Class 3 Public Primary Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 3 Public Primary Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\164\054\061\222\346\007\344\044\353\105\111\124\053\341\273\305
-\076\141\164\342
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\020\374\143\135\366\046\076\015\363\045\276\137\171\315\147\147
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151
-\147\156\054\040\111\156\143\056\061\067\060\065\006\003\125\004
-\013\023\056\103\154\141\163\163\040\063\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\160\272\344\035\020\331\051\064\266\070\312\173\003\314
-\272\277
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 1 Public Primary Certification Authority - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 1 Public Primary Certification Authority - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\301\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\074\060\072\006\003\125
-\004\013\023\063\103\154\141\163\163\040\061\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\062\061\072\060\070\006\003\125\004\013
-\023\061\050\143\051\040\061\071\071\070\040\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\301\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\074\060\072\006\003\125
-\004\013\023\063\103\154\141\163\163\040\061\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\062\061\072\060\070\006\003\125\004\013
-\023\061\050\143\051\040\061\071\071\070\040\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\114\307\352\252\230\076\161\323\223\020\370\075\072\211
-\221\222
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\002\060\202\002\153\002\020\114\307\352\252\230\076
-\161\323\223\020\370\075\072\211\221\222\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\060\201\301\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125
-\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156
-\143\056\061\074\060\072\006\003\125\004\013\023\063\103\154\141
-\163\163\040\061\040\120\165\142\154\151\143\040\120\162\151\155
-\141\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107\062
-\061\072\060\070\006\003\125\004\013\023\061\050\143\051\040\061
-\071\071\070\040\126\145\162\151\123\151\147\156\054\040\111\156
-\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151
-\172\145\144\040\165\163\145\040\157\156\154\171\061\037\060\035
-\006\003\125\004\013\023\026\126\145\162\151\123\151\147\156\040
-\124\162\165\163\164\040\116\145\164\167\157\162\153\060\036\027
-\015\071\070\060\065\061\070\060\060\060\060\060\060\132\027\015
-\062\070\060\070\060\061\062\063\065\071\065\071\132\060\201\301
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\027\060
-\025\006\003\125\004\012\023\016\126\145\162\151\123\151\147\156
-\054\040\111\156\143\056\061\074\060\072\006\003\125\004\013\023
-\063\103\154\141\163\163\040\061\040\120\165\142\154\151\143\040
-\120\162\151\155\141\162\171\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040
-\055\040\107\062\061\072\060\070\006\003\125\004\013\023\061\050
-\143\051\040\061\071\071\070\040\126\145\162\151\123\151\147\156
-\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165\164
-\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171
-\061\037\060\035\006\003\125\004\013\023\026\126\145\162\151\123
-\151\147\156\040\124\162\165\163\164\040\116\145\164\167\157\162
-\153\060\201\237\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\201\215\000\060\201\211\002\201\201\000\252\320
-\272\276\026\055\270\203\324\312\322\017\274\166\061\312\224\330
-\035\223\214\126\002\274\331\157\032\157\122\066\156\165\126\012
-\125\323\337\103\207\041\021\145\212\176\217\275\041\336\153\062
-\077\033\204\064\225\005\235\101\065\353\222\353\226\335\252\131
-\077\001\123\155\231\117\355\345\342\052\132\220\301\271\304\246
-\025\317\310\105\353\246\135\216\234\076\360\144\044\166\245\315
-\253\032\157\266\330\173\121\141\156\246\177\207\310\342\267\345
-\064\334\101\210\352\011\100\276\163\222\075\153\347\165\002\003
-\001\000\001\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\003\201\201\000\251\117\303\015\307\147\276\054\313\331
-\250\315\055\165\347\176\025\236\073\162\353\176\353\134\055\011
-\207\326\153\155\140\174\345\256\305\220\043\014\134\112\320\257
-\261\135\363\307\266\012\333\340\025\223\015\335\003\274\307\166
-\212\265\335\117\303\233\023\165\270\001\300\346\311\133\153\245
-\270\211\334\254\244\335\162\355\116\241\367\117\274\006\323\352
-\310\144\164\173\302\225\101\234\145\163\130\361\220\232\074\152
-\261\230\311\304\207\274\317\105\155\105\342\156\042\077\376\274
-\017\061\134\350\362\331
-END
-
-# Trust for Certificate "Verisign Class 1 Public Primary Certification Authority - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 1 Public Primary Certification Authority - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\047\076\341\044\127\375\304\371\014\125\350\053\126\026\177\142
-\365\062\345\107
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\333\043\075\371\151\372\113\271\225\200\104\163\136\175\101\203
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\301\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\074\060\072\006\003\125
-\004\013\023\063\103\154\141\163\163\040\061\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\062\061\072\060\070\006\003\125\004\013
-\023\061\050\143\051\040\061\071\071\070\040\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\114\307\352\252\230\076\161\323\223\020\370\075\072\211
-\221\222
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 2 Public Primary Certification Authority - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 2 Public Primary Certification Authority - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\301\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\074\060\072\006\003\125
-\004\013\023\063\103\154\141\163\163\040\062\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\062\061\072\060\070\006\003\125\004\013
-\023\061\050\143\051\040\061\071\071\070\040\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\301\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\074\060\072\006\003\125
-\004\013\023\063\103\154\141\163\163\040\062\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\062\061\072\060\070\006\003\125\004\013
-\023\061\050\143\051\040\061\071\071\070\040\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\271\057\140\314\210\237\241\172\106\011\270\133\160
-\154\212\257
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\003\060\202\002\154\002\021\000\271\057\140\314\210
-\237\241\172\106\011\270\133\160\154\212\257\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\060\201\301\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003
-\125\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\061\074\060\072\006\003\125\004\013\023\063\103\154
-\141\163\163\040\062\040\120\165\142\154\151\143\040\120\162\151
-\155\141\162\171\040\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107
-\062\061\072\060\070\006\003\125\004\013\023\061\050\143\051\040
-\061\071\071\070\040\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162
-\151\172\145\144\040\165\163\145\040\157\156\154\171\061\037\060
-\035\006\003\125\004\013\023\026\126\145\162\151\123\151\147\156
-\040\124\162\165\163\164\040\116\145\164\167\157\162\153\060\036
-\027\015\071\070\060\065\061\070\060\060\060\060\060\060\132\027
-\015\062\070\060\070\060\061\062\063\065\071\065\071\132\060\201
-\301\061\013\060\011\006\003\125\004\006\023\002\125\123\061\027
-\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151\147
-\156\054\040\111\156\143\056\061\074\060\072\006\003\125\004\013
-\023\063\103\154\141\163\163\040\062\040\120\165\142\154\151\143
-\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-\040\055\040\107\062\061\072\060\070\006\003\125\004\013\023\061
-\050\143\051\040\061\071\071\070\040\126\145\162\151\123\151\147
-\156\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165
-\164\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154
-\171\061\037\060\035\006\003\125\004\013\023\026\126\145\162\151
-\123\151\147\156\040\124\162\165\163\164\040\116\145\164\167\157
-\162\153\060\201\237\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\201\215\000\060\201\211\002\201\201\000\247
-\210\001\041\164\054\347\032\003\360\230\341\227\074\017\041\010
-\361\234\333\227\351\232\374\302\004\006\023\276\137\122\310\314
-\036\054\022\126\054\270\001\151\054\314\231\037\255\260\226\256
-\171\004\362\023\071\301\173\230\272\010\054\350\302\204\023\054
-\252\151\351\011\364\307\251\002\244\102\302\043\117\112\330\360
-\016\242\373\061\154\311\346\157\231\047\007\365\346\364\114\170
-\236\155\353\106\206\372\271\206\311\124\362\262\304\257\324\106
-\034\132\311\025\060\377\015\154\365\055\016\155\316\177\167\002
-\003\001\000\001\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\003\201\201\000\162\056\371\177\321\361\161\373\304
-\236\366\305\136\121\212\100\230\270\150\370\233\034\203\330\342
-\235\275\377\355\241\346\146\352\057\011\364\312\327\352\245\053
-\225\366\044\140\206\115\104\056\203\245\304\055\240\323\256\170
-\151\157\162\332\154\256\010\360\143\222\067\346\273\304\060\027
-\255\167\314\111\065\252\317\330\217\321\276\267\030\226\107\163
-\152\124\042\064\144\055\266\026\233\131\133\264\121\131\072\263
-\013\024\364\022\337\147\240\364\255\062\144\136\261\106\162\047
-\214\022\173\305\104\264\256
-END
-
-# Trust for Certificate "Verisign Class 2 Public Primary Certification Authority - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 2 Public Primary Certification Authority - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\263\352\304\107\166\311\310\034\352\362\235\225\266\314\240\010
-\033\147\354\235
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\055\273\345\045\323\321\145\202\072\267\016\372\346\353\342\341
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\301\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\074\060\072\006\003\125
-\004\013\023\063\103\154\141\163\163\040\062\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\062\061\072\060\070\006\003\125\004\013
-\023\061\050\143\051\040\061\071\071\070\040\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\271\057\140\314\210\237\241\172\106\011\270\133\160
-\154\212\257
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 3 Public Primary Certification Authority - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 3 Public Primary Certification Authority - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\301\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\074\060\072\006\003\125
-\004\013\023\063\103\154\141\163\163\040\063\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\062\061\072\060\070\006\003\125\004\013
-\023\061\050\143\051\040\061\071\071\070\040\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\301\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\074\060\072\006\003\125
-\004\013\023\063\103\154\141\163\163\040\063\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\062\061\072\060\070\006\003\125\004\013
-\023\061\050\143\051\040\061\071\071\070\040\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\175\331\376\007\317\250\036\267\020\171\147\373\247\211
-\064\306
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\002\060\202\002\153\002\020\175\331\376\007\317\250
-\036\267\020\171\147\373\247\211\064\306\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\060\201\301\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125
-\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156
-\143\056\061\074\060\072\006\003\125\004\013\023\063\103\154\141
-\163\163\040\063\040\120\165\142\154\151\143\040\120\162\151\155
-\141\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107\062
-\061\072\060\070\006\003\125\004\013\023\061\050\143\051\040\061
-\071\071\070\040\126\145\162\151\123\151\147\156\054\040\111\156
-\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151
-\172\145\144\040\165\163\145\040\157\156\154\171\061\037\060\035
-\006\003\125\004\013\023\026\126\145\162\151\123\151\147\156\040
-\124\162\165\163\164\040\116\145\164\167\157\162\153\060\036\027
-\015\071\070\060\065\061\070\060\060\060\060\060\060\132\027\015
-\062\070\060\070\060\061\062\063\065\071\065\071\132\060\201\301
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\027\060
-\025\006\003\125\004\012\023\016\126\145\162\151\123\151\147\156
-\054\040\111\156\143\056\061\074\060\072\006\003\125\004\013\023
-\063\103\154\141\163\163\040\063\040\120\165\142\154\151\143\040
-\120\162\151\155\141\162\171\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040
-\055\040\107\062\061\072\060\070\006\003\125\004\013\023\061\050
-\143\051\040\061\071\071\070\040\126\145\162\151\123\151\147\156
-\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165\164
-\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171
-\061\037\060\035\006\003\125\004\013\023\026\126\145\162\151\123
-\151\147\156\040\124\162\165\163\164\040\116\145\164\167\157\162
-\153\060\201\237\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\201\215\000\060\201\211\002\201\201\000\314\136
-\321\021\135\134\151\320\253\323\271\152\114\231\037\131\230\060
-\216\026\205\040\106\155\107\077\324\205\040\204\341\155\263\370
-\244\355\014\361\027\017\073\371\247\371\045\327\301\317\204\143
-\362\174\143\317\242\107\362\306\133\063\216\144\100\004\150\301
-\200\271\144\034\105\167\307\330\156\365\225\051\074\120\350\064
-\327\170\037\250\272\155\103\221\225\217\105\127\136\176\305\373
-\312\244\004\353\352\227\067\124\060\157\273\001\107\062\063\315
-\334\127\233\144\151\141\370\233\035\034\211\117\134\147\002\003
-\001\000\001\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\003\201\201\000\121\115\315\276\134\313\230\031\234\025
-\262\001\071\170\056\115\017\147\160\160\231\306\020\132\224\244
-\123\115\124\155\053\257\015\135\100\213\144\323\327\356\336\126
-\141\222\137\246\304\035\020\141\066\323\054\047\074\350\051\011
-\271\021\144\164\314\265\163\237\034\110\251\274\141\001\356\342
-\027\246\014\343\100\010\073\016\347\353\104\163\052\232\361\151
-\222\357\161\024\303\071\254\161\247\221\011\157\344\161\006\263
-\272\131\127\046\171\000\366\370\015\242\063\060\050\324\252\130
-\240\235\235\151\221\375
-END
-
-# Trust for Certificate "Verisign Class 3 Public Primary Certification Authority - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 3 Public Primary Certification Authority - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\205\067\034\246\345\120\024\075\316\050\003\107\033\336\072\011
-\350\370\167\017
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\242\063\233\114\164\170\163\324\154\347\301\363\215\313\134\351
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\301\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\074\060\072\006\003\125
-\004\013\023\063\103\154\141\163\163\040\063\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\062\061\072\060\070\006\003\125\004\013
-\023\061\050\143\051\040\061\071\071\070\040\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\175\331\376\007\317\250\036\267\020\171\147\373\247\211
-\064\306
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GlobalSign Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GlobalSign Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\127\061\013\060\011\006\003\125\004\006\023\002\102\105\061
-\031\060\027\006\003\125\004\012\023\020\107\154\157\142\141\154
-\123\151\147\156\040\156\166\055\163\141\061\020\060\016\006\003
-\125\004\013\023\007\122\157\157\164\040\103\101\061\033\060\031
-\006\003\125\004\003\023\022\107\154\157\142\141\154\123\151\147
-\156\040\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\127\061\013\060\011\006\003\125\004\006\023\002\102\105\061
-\031\060\027\006\003\125\004\012\023\020\107\154\157\142\141\154
-\123\151\147\156\040\156\166\055\163\141\061\020\060\016\006\003
-\125\004\013\023\007\122\157\157\164\040\103\101\061\033\060\031
-\006\003\125\004\003\023\022\107\154\157\142\141\154\123\151\147
-\156\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\013\004\000\000\000\000\001\025\113\132\303\224
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\165\060\202\002\135\240\003\002\001\002\002\013\004
-\000\000\000\000\001\025\113\132\303\224\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\060\127\061\013\060\011\006
-\003\125\004\006\023\002\102\105\061\031\060\027\006\003\125\004
-\012\023\020\107\154\157\142\141\154\123\151\147\156\040\156\166
-\055\163\141\061\020\060\016\006\003\125\004\013\023\007\122\157
-\157\164\040\103\101\061\033\060\031\006\003\125\004\003\023\022
-\107\154\157\142\141\154\123\151\147\156\040\122\157\157\164\040
-\103\101\060\036\027\015\071\070\060\071\060\061\061\062\060\060
-\060\060\132\027\015\062\070\060\061\062\070\061\062\060\060\060
-\060\132\060\127\061\013\060\011\006\003\125\004\006\023\002\102
-\105\061\031\060\027\006\003\125\004\012\023\020\107\154\157\142
-\141\154\123\151\147\156\040\156\166\055\163\141\061\020\060\016
-\006\003\125\004\013\023\007\122\157\157\164\040\103\101\061\033
-\060\031\006\003\125\004\003\023\022\107\154\157\142\141\154\123
-\151\147\156\040\122\157\157\164\040\103\101\060\202\001\042\060
-\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202
-\001\017\000\060\202\001\012\002\202\001\001\000\332\016\346\231
-\215\316\243\343\117\212\176\373\361\213\203\045\153\352\110\037
-\361\052\260\271\225\021\004\275\360\143\321\342\147\146\317\034
-\335\317\033\110\053\356\215\211\216\232\257\051\200\145\253\351
-\307\055\022\313\253\034\114\160\007\241\075\012\060\315\025\215
-\117\370\335\324\214\120\025\034\357\120\356\304\056\367\374\351
-\122\362\221\175\340\155\325\065\060\216\136\103\163\362\101\351
-\325\152\343\262\211\072\126\071\070\157\006\074\210\151\133\052
-\115\305\247\124\270\154\211\314\233\371\074\312\345\375\211\365
-\022\074\222\170\226\326\334\164\156\223\104\141\321\215\307\106
-\262\165\016\206\350\031\212\325\155\154\325\170\026\225\242\351
-\310\012\070\353\362\044\023\117\163\124\223\023\205\072\033\274
-\036\064\265\213\005\214\271\167\213\261\333\037\040\221\253\011
-\123\156\220\316\173\067\164\271\160\107\221\042\121\143\026\171
-\256\261\256\101\046\010\310\031\053\321\106\252\110\326\144\052
-\327\203\064\377\054\052\301\154\031\103\112\007\205\347\323\174
-\366\041\150\357\352\362\122\237\177\223\220\317\002\003\001\000
-\001\243\102\060\100\060\016\006\003\125\035\017\001\001\377\004
-\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004
-\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004
-\024\140\173\146\032\105\015\227\312\211\120\057\175\004\315\064
-\250\377\374\375\113\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\003\202\001\001\000\326\163\347\174\117\166\320
-\215\277\354\272\242\276\064\305\050\062\265\174\374\154\234\054
-\053\275\011\236\123\277\153\136\252\021\110\266\345\010\243\263
-\312\075\141\115\323\106\011\263\076\303\240\343\143\125\033\362
-\272\357\255\071\341\103\271\070\243\346\057\212\046\073\357\240
-\120\126\371\306\012\375\070\315\304\013\160\121\224\227\230\004
-\337\303\137\224\325\025\311\024\101\234\304\135\165\144\025\015
-\377\125\060\354\206\217\377\015\357\054\271\143\106\366\252\374
-\337\274\151\375\056\022\110\144\232\340\225\360\246\357\051\217
-\001\261\025\265\014\035\245\376\151\054\151\044\170\036\263\247
-\034\161\142\356\312\310\227\254\027\135\212\302\370\107\206\156
-\052\304\126\061\225\320\147\211\205\053\371\154\246\135\106\235
-\014\252\202\344\231\121\335\160\267\333\126\075\141\344\152\341
-\134\326\366\376\075\336\101\314\007\256\143\122\277\123\123\364
-\053\351\307\375\266\367\202\137\205\322\101\030\333\201\263\004
-\034\305\037\244\200\157\025\040\311\336\014\210\012\035\326\146
-\125\342\374\110\311\051\046\151\340
-END
-
-# Trust for Certificate "GlobalSign Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GlobalSign Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\261\274\226\213\324\364\235\142\052\250\232\201\362\025\001\122
-\244\035\202\234
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\076\105\122\025\011\121\222\341\267\135\067\237\261\207\051\212
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\127\061\013\060\011\006\003\125\004\006\023\002\102\105\061
-\031\060\027\006\003\125\004\012\023\020\107\154\157\142\141\154
-\123\151\147\156\040\156\166\055\163\141\061\020\060\016\006\003
-\125\004\013\023\007\122\157\157\164\040\103\101\061\033\060\031
-\006\003\125\004\003\023\022\107\154\157\142\141\154\123\151\147
-\156\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\013\004\000\000\000\000\001\025\113\132\303\224
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GlobalSign Root CA - R2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GlobalSign Root CA - R2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\114\061\040\060\036\006\003\125\004\013\023\027\107\154\157
-\142\141\154\123\151\147\156\040\122\157\157\164\040\103\101\040
-\055\040\122\062\061\023\060\021\006\003\125\004\012\023\012\107
-\154\157\142\141\154\123\151\147\156\061\023\060\021\006\003\125
-\004\003\023\012\107\154\157\142\141\154\123\151\147\156
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\114\061\040\060\036\006\003\125\004\013\023\027\107\154\157
-\142\141\154\123\151\147\156\040\122\157\157\164\040\103\101\040
-\055\040\122\062\061\023\060\021\006\003\125\004\012\023\012\107
-\154\157\142\141\154\123\151\147\156\061\023\060\021\006\003\125
-\004\003\023\012\107\154\157\142\141\154\123\151\147\156
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\013\004\000\000\000\000\001\017\206\046\346\015
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\272\060\202\002\242\240\003\002\001\002\002\013\004
-\000\000\000\000\001\017\206\046\346\015\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\060\114\061\040\060\036\006
-\003\125\004\013\023\027\107\154\157\142\141\154\123\151\147\156
-\040\122\157\157\164\040\103\101\040\055\040\122\062\061\023\060
-\021\006\003\125\004\012\023\012\107\154\157\142\141\154\123\151
-\147\156\061\023\060\021\006\003\125\004\003\023\012\107\154\157
-\142\141\154\123\151\147\156\060\036\027\015\060\066\061\062\061
-\065\060\070\060\060\060\060\132\027\015\062\061\061\062\061\065
-\060\070\060\060\060\060\132\060\114\061\040\060\036\006\003\125
-\004\013\023\027\107\154\157\142\141\154\123\151\147\156\040\122
-\157\157\164\040\103\101\040\055\040\122\062\061\023\060\021\006
-\003\125\004\012\023\012\107\154\157\142\141\154\123\151\147\156
-\061\023\060\021\006\003\125\004\003\023\012\107\154\157\142\141
-\154\123\151\147\156\060\202\001\042\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001
-\012\002\202\001\001\000\246\317\044\016\276\056\157\050\231\105
-\102\304\253\076\041\124\233\013\323\177\204\160\372\022\263\313
-\277\207\137\306\177\206\323\262\060\134\326\375\255\361\173\334
-\345\370\140\226\011\222\020\365\320\123\336\373\173\176\163\210
-\254\122\210\173\112\246\312\111\246\136\250\247\214\132\021\274
-\172\202\353\276\214\351\263\254\226\045\007\227\112\231\052\007
-\057\264\036\167\277\212\017\265\002\174\033\226\270\305\271\072
-\054\274\326\022\271\353\131\175\342\320\006\206\137\136\111\152
-\265\071\136\210\064\354\274\170\014\010\230\204\154\250\315\113
-\264\240\175\014\171\115\360\270\055\313\041\312\325\154\133\175
-\341\240\051\204\241\371\323\224\111\313\044\142\221\040\274\335
-\013\325\331\314\371\352\047\012\053\163\221\306\235\033\254\310
-\313\350\340\240\364\057\220\213\115\373\260\066\033\366\031\172
-\205\340\155\362\141\023\210\134\237\340\223\012\121\227\212\132
-\316\257\253\325\367\252\011\252\140\275\334\331\137\337\162\251
-\140\023\136\000\001\311\112\372\077\244\352\007\003\041\002\216
-\202\312\003\302\233\217\002\003\001\000\001\243\201\234\060\201
-\231\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001
-\006\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
-\001\377\060\035\006\003\125\035\016\004\026\004\024\233\342\007
-\127\147\034\036\300\152\006\336\131\264\232\055\337\334\031\206
-\056\060\066\006\003\125\035\037\004\057\060\055\060\053\240\051
-\240\047\206\045\150\164\164\160\072\057\057\143\162\154\056\147
-\154\157\142\141\154\163\151\147\156\056\156\145\164\057\162\157
-\157\164\055\162\062\056\143\162\154\060\037\006\003\125\035\043
-\004\030\060\026\200\024\233\342\007\127\147\034\036\300\152\006
-\336\131\264\232\055\337\334\031\206\056\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\231\201
-\123\207\034\150\227\206\221\354\340\112\270\104\013\253\201\254
-\047\117\326\301\270\034\103\170\263\014\232\374\352\054\074\156
-\141\033\115\113\051\365\237\005\035\046\301\270\351\203\000\142
-\105\266\251\010\223\271\251\063\113\030\232\302\370\207\210\116
-\333\335\161\064\032\301\124\332\106\077\340\323\052\253\155\124
-\042\365\072\142\315\040\157\272\051\211\327\335\221\356\323\134
-\242\076\241\133\101\365\337\345\144\103\055\351\325\071\253\322
-\242\337\267\213\320\300\200\031\034\105\300\055\214\350\370\055
-\244\164\126\111\305\005\265\117\025\336\156\104\170\071\207\250
-\176\273\363\171\030\221\273\364\157\235\301\360\214\065\214\135
-\001\373\303\155\271\357\104\155\171\106\061\176\012\376\251\202
-\301\377\357\253\156\040\304\120\311\137\235\115\233\027\214\014
-\345\001\311\240\101\152\163\123\372\245\120\264\156\045\017\373
-\114\030\364\375\122\331\216\151\261\350\021\017\336\210\330\373
-\035\111\367\252\336\225\317\040\170\302\140\022\333\045\100\214
-\152\374\176\102\070\100\144\022\367\236\201\341\223\056
-END
-
-# Trust for Certificate "GlobalSign Root CA - R2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GlobalSign Root CA - R2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\165\340\253\266\023\205\022\047\034\004\370\137\335\336\070\344
-\267\044\056\376
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\224\024\167\176\076\136\375\217\060\275\101\260\317\347\320\060
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\114\061\040\060\036\006\003\125\004\013\023\027\107\154\157
-\142\141\154\123\151\147\156\040\122\157\157\164\040\103\101\040
-\055\040\122\062\061\023\060\021\006\003\125\004\012\023\012\107
-\154\157\142\141\154\123\151\147\156\061\023\060\021\006\003\125
-\004\003\023\012\107\154\157\142\141\154\123\151\147\156
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\013\004\000\000\000\000\001\017\206\046\346\015
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "ValiCert Class 1 VA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ValiCert Class 1 VA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\273\061\044\060\042\006\003\125\004\007\023\033\126\141
-\154\151\103\145\162\164\040\126\141\154\151\144\141\164\151\157
-\156\040\116\145\164\167\157\162\153\061\027\060\025\006\003\125
-\004\012\023\016\126\141\154\151\103\145\162\164\054\040\111\156
-\143\056\061\065\060\063\006\003\125\004\013\023\054\126\141\154
-\151\103\145\162\164\040\103\154\141\163\163\040\061\040\120\157
-\154\151\143\171\040\126\141\154\151\144\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\061\041\060\037\006\003\125
-\004\003\023\030\150\164\164\160\072\057\057\167\167\167\056\166
-\141\154\151\143\145\162\164\056\143\157\155\057\061\040\060\036
-\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156\146
-\157\100\166\141\154\151\143\145\162\164\056\143\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\273\061\044\060\042\006\003\125\004\007\023\033\126\141
-\154\151\103\145\162\164\040\126\141\154\151\144\141\164\151\157
-\156\040\116\145\164\167\157\162\153\061\027\060\025\006\003\125
-\004\012\023\016\126\141\154\151\103\145\162\164\054\040\111\156
-\143\056\061\065\060\063\006\003\125\004\013\023\054\126\141\154
-\151\103\145\162\164\040\103\154\141\163\163\040\061\040\120\157
-\154\151\143\171\040\126\141\154\151\144\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\061\041\060\037\006\003\125
-\004\003\023\030\150\164\164\160\072\057\057\167\167\167\056\166
-\141\154\151\143\145\162\164\056\143\157\155\057\061\040\060\036
-\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156\146
-\157\100\166\141\154\151\143\145\162\164\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\347\060\202\002\120\002\001\001\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\060\201\273\061\044\060
-\042\006\003\125\004\007\023\033\126\141\154\151\103\145\162\164
-\040\126\141\154\151\144\141\164\151\157\156\040\116\145\164\167
-\157\162\153\061\027\060\025\006\003\125\004\012\023\016\126\141
-\154\151\103\145\162\164\054\040\111\156\143\056\061\065\060\063
-\006\003\125\004\013\023\054\126\141\154\151\103\145\162\164\040
-\103\154\141\163\163\040\061\040\120\157\154\151\143\171\040\126
-\141\154\151\144\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\061\041\060\037\006\003\125\004\003\023\030\150\164
-\164\160\072\057\057\167\167\167\056\166\141\154\151\143\145\162
-\164\056\143\157\155\057\061\040\060\036\006\011\052\206\110\206
-\367\015\001\011\001\026\021\151\156\146\157\100\166\141\154\151
-\143\145\162\164\056\143\157\155\060\036\027\015\071\071\060\066
-\062\065\062\062\062\063\064\070\132\027\015\061\071\060\066\062
-\065\062\062\062\063\064\070\132\060\201\273\061\044\060\042\006
-\003\125\004\007\023\033\126\141\154\151\103\145\162\164\040\126
-\141\154\151\144\141\164\151\157\156\040\116\145\164\167\157\162
-\153\061\027\060\025\006\003\125\004\012\023\016\126\141\154\151
-\103\145\162\164\054\040\111\156\143\056\061\065\060\063\006\003
-\125\004\013\023\054\126\141\154\151\103\145\162\164\040\103\154
-\141\163\163\040\061\040\120\157\154\151\143\171\040\126\141\154
-\151\144\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\061\041\060\037\006\003\125\004\003\023\030\150\164\164\160
-\072\057\057\167\167\167\056\166\141\154\151\143\145\162\164\056
-\143\157\155\057\061\040\060\036\006\011\052\206\110\206\367\015
-\001\011\001\026\021\151\156\146\157\100\166\141\154\151\143\145
-\162\164\056\143\157\155\060\201\237\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\201\215\000\060\201\211\002
-\201\201\000\330\131\202\172\211\270\226\272\246\057\150\157\130
-\056\247\124\034\006\156\364\352\215\110\274\061\224\027\360\363
-\116\274\262\270\065\222\166\260\320\245\245\001\327\000\003\022
-\042\031\010\370\377\021\043\233\316\007\365\277\151\032\046\376
-\116\351\321\177\235\054\100\035\131\150\156\246\370\130\260\235
-\032\217\323\077\361\334\031\006\201\250\016\340\072\335\310\123
-\105\011\006\346\017\160\303\372\100\246\016\342\126\005\017\030
-\115\374\040\202\321\163\125\164\215\166\162\240\035\235\035\300
-\335\077\161\002\003\001\000\001\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\201\201\000\120\150\075\111\364
-\054\034\006\224\337\225\140\177\226\173\027\376\117\161\255\144
-\310\335\167\322\357\131\125\350\077\350\216\005\052\041\362\007
-\322\265\247\122\376\234\261\266\342\133\167\027\100\352\162\326
-\043\313\050\201\062\303\000\171\030\354\131\027\211\311\306\152
-\036\161\311\375\267\164\245\045\105\151\305\110\253\031\341\105
-\212\045\153\031\356\345\273\022\365\177\367\246\215\121\303\360
-\235\164\267\251\076\240\245\377\266\111\003\023\332\042\314\355
-\161\202\053\231\317\072\267\365\055\162\310
-END
-
-# Trust for Certificate "ValiCert Class 1 VA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ValiCert Class 1 VA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\345\337\164\074\266\001\304\233\230\103\334\253\214\350\152\201
-\020\237\344\216
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\145\130\253\025\255\127\154\036\250\247\265\151\254\277\377\353
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\273\061\044\060\042\006\003\125\004\007\023\033\126\141
-\154\151\103\145\162\164\040\126\141\154\151\144\141\164\151\157
-\156\040\116\145\164\167\157\162\153\061\027\060\025\006\003\125
-\004\012\023\016\126\141\154\151\103\145\162\164\054\040\111\156
-\143\056\061\065\060\063\006\003\125\004\013\023\054\126\141\154
-\151\103\145\162\164\040\103\154\141\163\163\040\061\040\120\157
-\154\151\143\171\040\126\141\154\151\144\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\061\041\060\037\006\003\125
-\004\003\023\030\150\164\164\160\072\057\057\167\167\167\056\166
-\141\154\151\143\145\162\164\056\143\157\155\057\061\040\060\036
-\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156\146
-\157\100\166\141\154\151\143\145\162\164\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "ValiCert Class 2 VA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ValiCert Class 2 VA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\273\061\044\060\042\006\003\125\004\007\023\033\126\141
-\154\151\103\145\162\164\040\126\141\154\151\144\141\164\151\157
-\156\040\116\145\164\167\157\162\153\061\027\060\025\006\003\125
-\004\012\023\016\126\141\154\151\103\145\162\164\054\040\111\156
-\143\056\061\065\060\063\006\003\125\004\013\023\054\126\141\154
-\151\103\145\162\164\040\103\154\141\163\163\040\062\040\120\157
-\154\151\143\171\040\126\141\154\151\144\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\061\041\060\037\006\003\125
-\004\003\023\030\150\164\164\160\072\057\057\167\167\167\056\166
-\141\154\151\143\145\162\164\056\143\157\155\057\061\040\060\036
-\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156\146
-\157\100\166\141\154\151\143\145\162\164\056\143\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\273\061\044\060\042\006\003\125\004\007\023\033\126\141
-\154\151\103\145\162\164\040\126\141\154\151\144\141\164\151\157
-\156\040\116\145\164\167\157\162\153\061\027\060\025\006\003\125
-\004\012\023\016\126\141\154\151\103\145\162\164\054\040\111\156
-\143\056\061\065\060\063\006\003\125\004\013\023\054\126\141\154
-\151\103\145\162\164\040\103\154\141\163\163\040\062\040\120\157
-\154\151\143\171\040\126\141\154\151\144\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\061\041\060\037\006\003\125
-\004\003\023\030\150\164\164\160\072\057\057\167\167\167\056\166
-\141\154\151\143\145\162\164\056\143\157\155\057\061\040\060\036
-\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156\146
-\157\100\166\141\154\151\143\145\162\164\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\347\060\202\002\120\002\001\001\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\060\201\273\061\044\060
-\042\006\003\125\004\007\023\033\126\141\154\151\103\145\162\164
-\040\126\141\154\151\144\141\164\151\157\156\040\116\145\164\167
-\157\162\153\061\027\060\025\006\003\125\004\012\023\016\126\141
-\154\151\103\145\162\164\054\040\111\156\143\056\061\065\060\063
-\006\003\125\004\013\023\054\126\141\154\151\103\145\162\164\040
-\103\154\141\163\163\040\062\040\120\157\154\151\143\171\040\126
-\141\154\151\144\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\061\041\060\037\006\003\125\004\003\023\030\150\164
-\164\160\072\057\057\167\167\167\056\166\141\154\151\143\145\162
-\164\056\143\157\155\057\061\040\060\036\006\011\052\206\110\206
-\367\015\001\011\001\026\021\151\156\146\157\100\166\141\154\151
-\143\145\162\164\056\143\157\155\060\036\027\015\071\071\060\066
-\062\066\060\060\061\071\065\064\132\027\015\061\071\060\066\062
-\066\060\060\061\071\065\064\132\060\201\273\061\044\060\042\006
-\003\125\004\007\023\033\126\141\154\151\103\145\162\164\040\126
-\141\154\151\144\141\164\151\157\156\040\116\145\164\167\157\162
-\153\061\027\060\025\006\003\125\004\012\023\016\126\141\154\151
-\103\145\162\164\054\040\111\156\143\056\061\065\060\063\006\003
-\125\004\013\023\054\126\141\154\151\103\145\162\164\040\103\154
-\141\163\163\040\062\040\120\157\154\151\143\171\040\126\141\154
-\151\144\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\061\041\060\037\006\003\125\004\003\023\030\150\164\164\160
-\072\057\057\167\167\167\056\166\141\154\151\143\145\162\164\056
-\143\157\155\057\061\040\060\036\006\011\052\206\110\206\367\015
-\001\011\001\026\021\151\156\146\157\100\166\141\154\151\143\145
-\162\164\056\143\157\155\060\201\237\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\201\215\000\060\201\211\002
-\201\201\000\316\072\161\312\345\253\310\131\222\125\327\253\330
-\164\016\371\356\331\366\125\107\131\145\107\016\005\125\334\353
-\230\066\074\134\123\135\323\060\317\070\354\275\101\211\355\045
-\102\011\044\153\012\136\263\174\335\122\055\114\346\324\326\175
-\132\131\251\145\324\111\023\055\044\115\034\120\157\265\301\205
-\124\073\376\161\344\323\134\102\371\200\340\221\032\012\133\071
-\066\147\363\077\125\174\033\077\264\137\144\163\064\343\264\022
-\277\207\144\370\332\022\377\067\047\301\263\103\273\357\173\156
-\056\151\367\002\003\001\000\001\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\201\201\000\073\177\120\157\157
-\120\224\231\111\142\070\070\037\113\370\245\310\076\247\202\201
-\366\053\307\350\305\316\350\072\020\202\313\030\000\216\115\275
-\250\130\177\241\171\000\265\273\351\215\257\101\331\017\064\356
-\041\201\031\240\062\111\050\364\304\216\126\325\122\063\375\120
-\325\176\231\154\003\344\311\114\374\313\154\253\146\263\112\041
-\214\345\265\014\062\076\020\262\314\154\241\334\232\230\114\002
-\133\363\316\271\236\245\162\016\112\267\077\074\346\026\150\370
-\276\355\164\114\274\133\325\142\037\103\335
-END
-
-# Trust for Certificate "ValiCert Class 2 VA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ValiCert Class 2 VA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\061\172\052\320\177\053\063\136\365\241\303\116\113\127\350\267
-\330\361\374\246
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\251\043\165\233\272\111\066\156\061\302\333\362\347\146\272\207
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\273\061\044\060\042\006\003\125\004\007\023\033\126\141
-\154\151\103\145\162\164\040\126\141\154\151\144\141\164\151\157
-\156\040\116\145\164\167\157\162\153\061\027\060\025\006\003\125
-\004\012\023\016\126\141\154\151\103\145\162\164\054\040\111\156
-\143\056\061\065\060\063\006\003\125\004\013\023\054\126\141\154
-\151\103\145\162\164\040\103\154\141\163\163\040\062\040\120\157
-\154\151\143\171\040\126\141\154\151\144\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\061\041\060\037\006\003\125
-\004\003\023\030\150\164\164\160\072\057\057\167\167\167\056\166
-\141\154\151\143\145\162\164\056\143\157\155\057\061\040\060\036
-\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156\146
-\157\100\166\141\154\151\143\145\162\164\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "RSA Root Certificate 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "RSA Root Certificate 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\273\061\044\060\042\006\003\125\004\007\023\033\126\141
-\154\151\103\145\162\164\040\126\141\154\151\144\141\164\151\157
-\156\040\116\145\164\167\157\162\153\061\027\060\025\006\003\125
-\004\012\023\016\126\141\154\151\103\145\162\164\054\040\111\156
-\143\056\061\065\060\063\006\003\125\004\013\023\054\126\141\154
-\151\103\145\162\164\040\103\154\141\163\163\040\063\040\120\157
-\154\151\143\171\040\126\141\154\151\144\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\061\041\060\037\006\003\125
-\004\003\023\030\150\164\164\160\072\057\057\167\167\167\056\166
-\141\154\151\143\145\162\164\056\143\157\155\057\061\040\060\036
-\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156\146
-\157\100\166\141\154\151\143\145\162\164\056\143\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\273\061\044\060\042\006\003\125\004\007\023\033\126\141
-\154\151\103\145\162\164\040\126\141\154\151\144\141\164\151\157
-\156\040\116\145\164\167\157\162\153\061\027\060\025\006\003\125
-\004\012\023\016\126\141\154\151\103\145\162\164\054\040\111\156
-\143\056\061\065\060\063\006\003\125\004\013\023\054\126\141\154
-\151\103\145\162\164\040\103\154\141\163\163\040\063\040\120\157
-\154\151\143\171\040\126\141\154\151\144\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\061\041\060\037\006\003\125
-\004\003\023\030\150\164\164\160\072\057\057\167\167\167\056\166
-\141\154\151\143\145\162\164\056\143\157\155\057\061\040\060\036
-\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156\146
-\157\100\166\141\154\151\143\145\162\164\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\347\060\202\002\120\002\001\001\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\060\201\273\061\044\060
-\042\006\003\125\004\007\023\033\126\141\154\151\103\145\162\164
-\040\126\141\154\151\144\141\164\151\157\156\040\116\145\164\167
-\157\162\153\061\027\060\025\006\003\125\004\012\023\016\126\141
-\154\151\103\145\162\164\054\040\111\156\143\056\061\065\060\063
-\006\003\125\004\013\023\054\126\141\154\151\103\145\162\164\040
-\103\154\141\163\163\040\063\040\120\157\154\151\143\171\040\126
-\141\154\151\144\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\061\041\060\037\006\003\125\004\003\023\030\150\164
-\164\160\072\057\057\167\167\167\056\166\141\154\151\143\145\162
-\164\056\143\157\155\057\061\040\060\036\006\011\052\206\110\206
-\367\015\001\011\001\026\021\151\156\146\157\100\166\141\154\151
-\143\145\162\164\056\143\157\155\060\036\027\015\071\071\060\066
-\062\066\060\060\062\062\063\063\132\027\015\061\071\060\066\062
-\066\060\060\062\062\063\063\132\060\201\273\061\044\060\042\006
-\003\125\004\007\023\033\126\141\154\151\103\145\162\164\040\126
-\141\154\151\144\141\164\151\157\156\040\116\145\164\167\157\162
-\153\061\027\060\025\006\003\125\004\012\023\016\126\141\154\151
-\103\145\162\164\054\040\111\156\143\056\061\065\060\063\006\003
-\125\004\013\023\054\126\141\154\151\103\145\162\164\040\103\154
-\141\163\163\040\063\040\120\157\154\151\143\171\040\126\141\154
-\151\144\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\061\041\060\037\006\003\125\004\003\023\030\150\164\164\160
-\072\057\057\167\167\167\056\166\141\154\151\143\145\162\164\056
-\143\157\155\057\061\040\060\036\006\011\052\206\110\206\367\015
-\001\011\001\026\021\151\156\146\157\100\166\141\154\151\143\145
-\162\164\056\143\157\155\060\201\237\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\201\215\000\060\201\211\002
-\201\201\000\343\230\121\226\034\350\325\261\006\201\152\127\303
-\162\165\223\253\317\236\246\374\363\026\122\326\055\115\237\065
-\104\250\056\004\115\007\111\212\070\051\365\167\067\347\267\253
-\135\337\066\161\024\231\217\334\302\222\361\347\140\222\227\354
-\330\110\334\277\301\002\040\306\044\244\050\114\060\132\166\155
-\261\134\363\335\336\236\020\161\241\210\307\133\233\101\155\312
-\260\270\216\025\356\255\063\053\317\107\004\134\165\161\012\230
-\044\230\051\247\111\131\245\335\370\267\103\142\141\363\323\342
-\320\125\077\002\003\001\000\001\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\201\201\000\126\273\002\130\204
-\147\010\054\337\037\333\173\111\063\365\323\147\235\364\264\012
-\020\263\311\305\054\342\222\152\161\170\047\362\160\203\102\323
-\076\317\251\124\364\361\330\222\026\214\321\004\313\113\253\311
-\237\105\256\074\212\251\260\161\063\135\310\305\127\337\257\250
-\065\263\177\211\207\351\350\045\222\270\177\205\172\256\326\274
-\036\067\130\052\147\311\221\317\052\201\076\355\306\071\337\300
-\076\031\234\031\314\023\115\202\101\265\214\336\340\075\140\010
-\040\017\105\176\153\242\177\243\214\025\356
-END
-
-# Trust for Certificate "RSA Root Certificate 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "RSA Root Certificate 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\151\275\214\364\234\323\000\373\131\056\027\223\312\125\152\363
-\354\252\065\373
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\242\157\123\267\356\100\333\112\150\347\372\030\331\020\113\162
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\273\061\044\060\042\006\003\125\004\007\023\033\126\141
-\154\151\103\145\162\164\040\126\141\154\151\144\141\164\151\157
-\156\040\116\145\164\167\157\162\153\061\027\060\025\006\003\125
-\004\012\023\016\126\141\154\151\103\145\162\164\054\040\111\156
-\143\056\061\065\060\063\006\003\125\004\013\023\054\126\141\154
-\151\103\145\162\164\040\103\154\141\163\163\040\063\040\120\157
-\154\151\143\171\040\126\141\154\151\144\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\061\041\060\037\006\003\125
-\004\003\023\030\150\164\164\160\072\057\057\167\167\167\056\166
-\141\154\151\143\145\162\164\056\143\157\155\057\061\040\060\036
-\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156\146
-\157\100\166\141\154\151\143\145\162\164\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 1 Public Primary Certification Authority - G3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 1 Public Primary Certification Authority - G3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\061\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\061\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\213\133\165\126\204\124\205\013\000\317\257\070\110
-\316\261\244
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\032\060\202\003\002\002\021\000\213\133\165\126\204
-\124\205\013\000\317\257\070\110\316\261\244\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\060\201\312\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003
-\125\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153\061\072\060\070\006\003\125\004\013\023\061\050
-\143\051\040\061\071\071\071\040\126\145\162\151\123\151\147\156
-\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165\164
-\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171
-\061\105\060\103\006\003\125\004\003\023\074\126\145\162\151\123
-\151\147\156\040\103\154\141\163\163\040\061\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\063\060\036\027\015\071\071\061\060\060
-\061\060\060\060\060\060\060\132\027\015\063\066\060\067\061\066
-\062\063\065\071\065\071\132\060\201\312\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\027\060\025\006\003\125\004\012
-\023\016\126\145\162\151\123\151\147\156\054\040\111\156\143\056
-\061\037\060\035\006\003\125\004\013\023\026\126\145\162\151\123
-\151\147\156\040\124\162\165\163\164\040\116\145\164\167\157\162
-\153\061\072\060\070\006\003\125\004\013\023\061\050\143\051\040
-\061\071\071\071\040\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162
-\151\172\145\144\040\165\163\145\040\157\156\154\171\061\105\060
-\103\006\003\125\004\003\023\074\126\145\162\151\123\151\147\156
-\040\103\154\141\163\163\040\061\040\120\165\142\154\151\143\040
-\120\162\151\155\141\162\171\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040
-\055\040\107\063\060\202\001\042\060\015\006\011\052\206\110\206
-\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012
-\002\202\001\001\000\335\204\324\271\264\371\247\330\363\004\170
-\234\336\075\334\154\023\026\331\172\335\044\121\146\300\307\046
-\131\015\254\006\010\302\224\321\063\037\360\203\065\037\156\033
-\310\336\252\156\025\116\124\047\357\304\155\032\354\013\343\016
-\360\104\245\127\307\100\130\036\243\107\037\161\354\140\366\155
-\224\310\030\071\355\376\102\030\126\337\344\114\111\020\170\116
-\001\166\065\143\022\066\335\146\274\001\004\066\243\125\150\325
-\242\066\011\254\253\041\046\124\006\255\077\312\024\340\254\312
-\255\006\035\225\342\370\235\361\340\140\377\302\177\165\053\114
-\314\332\376\207\231\041\352\272\376\076\124\327\322\131\170\333
-\074\156\317\240\023\000\032\270\047\241\344\276\147\226\312\240
-\305\263\234\335\311\165\236\353\060\232\137\243\315\331\256\170
-\031\077\043\351\134\333\051\275\255\125\310\033\124\214\143\366
-\350\246\352\307\067\022\134\243\051\036\002\331\333\037\073\264
-\327\017\126\107\201\025\004\112\257\203\047\321\305\130\210\301
-\335\366\252\247\243\030\332\150\252\155\021\121\341\277\145\153
-\237\226\166\321\075\002\003\001\000\001\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\253\146
-\215\327\263\272\307\232\266\346\125\320\005\361\237\061\215\132
-\252\331\252\106\046\017\161\355\245\255\123\126\142\001\107\052
-\104\351\376\077\164\013\023\233\271\364\115\033\262\321\137\262
-\266\322\210\134\263\237\315\313\324\247\331\140\225\204\072\370
-\301\067\035\141\312\347\260\305\345\221\332\124\246\254\061\201
-\256\227\336\315\010\254\270\300\227\200\177\156\162\244\347\151
-\023\225\145\037\304\223\074\375\171\217\004\324\076\117\352\367
-\236\316\315\147\174\117\145\002\377\221\205\124\163\307\377\066
-\367\206\055\354\320\136\117\377\021\237\162\006\326\270\032\361
-\114\015\046\145\342\104\200\036\307\237\343\335\350\012\332\354
-\245\040\200\151\150\241\117\176\341\153\317\007\101\372\203\216
-\274\070\335\260\056\021\261\153\262\102\314\232\274\371\110\042
-\171\112\031\017\262\034\076\040\164\331\152\303\276\362\050\170
-\023\126\171\117\155\120\352\033\260\265\127\261\067\146\130\043
-\363\334\017\337\012\207\304\357\206\005\325\070\024\140\231\243
-\113\336\006\226\161\054\362\333\266\037\244\357\077\356
-END
-
-# Trust for Certificate "Verisign Class 1 Public Primary Certification Authority - G3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 1 Public Primary Certification Authority - G3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\040\102\205\334\367\353\166\101\225\127\216\023\153\324\267\321
-\351\216\106\245
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\261\107\274\030\127\321\030\240\170\055\354\161\350\052\225\163
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\061\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\213\133\165\126\204\124\205\013\000\317\257\070\110
-\316\261\244
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 2 Public Primary Certification Authority - G3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 2 Public Primary Certification Authority - G3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\062\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\062\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\141\160\313\111\214\137\230\105\051\347\260\246\331\120
-\133\172
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\031\060\202\003\001\002\020\141\160\313\111\214\137
-\230\105\051\347\260\246\331\120\133\172\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\060\201\312\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125
-\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156
-\143\056\061\037\060\035\006\003\125\004\013\023\026\126\145\162
-\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164\167
-\157\162\153\061\072\060\070\006\003\125\004\013\023\061\050\143
-\051\040\061\071\071\071\040\126\145\162\151\123\151\147\156\054
-\040\111\156\143\056\040\055\040\106\157\162\040\141\165\164\150
-\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171\061
-\105\060\103\006\003\125\004\003\023\074\126\145\162\151\123\151
-\147\156\040\103\154\141\163\163\040\062\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\040\055\040\107\063\060\036\027\015\071\071\061\060\060\061
-\060\060\060\060\060\060\132\027\015\063\066\060\067\061\066\062
-\063\065\071\065\071\132\060\201\312\061\013\060\011\006\003\125
-\004\006\023\002\125\123\061\027\060\025\006\003\125\004\012\023
-\016\126\145\162\151\123\151\147\156\054\040\111\156\143\056\061
-\037\060\035\006\003\125\004\013\023\026\126\145\162\151\123\151
-\147\156\040\124\162\165\163\164\040\116\145\164\167\157\162\153
-\061\072\060\070\006\003\125\004\013\023\061\050\143\051\040\061
-\071\071\071\040\126\145\162\151\123\151\147\156\054\040\111\156
-\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151
-\172\145\144\040\165\163\145\040\157\156\154\171\061\105\060\103
-\006\003\125\004\003\023\074\126\145\162\151\123\151\147\156\040
-\103\154\141\163\163\040\062\040\120\165\142\154\151\143\040\120
-\162\151\155\141\162\171\040\103\145\162\164\151\146\151\143\141
-\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040\055
-\040\107\063\060\202\001\042\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002
-\202\001\001\000\257\012\015\302\325\054\333\147\271\055\345\224
-\047\335\245\276\340\260\115\217\263\141\126\074\326\174\303\364
-\315\076\206\313\242\210\342\341\330\244\151\305\265\342\277\301
-\246\107\120\136\106\071\213\325\226\272\265\157\024\277\020\316
-\047\023\236\005\107\233\061\172\023\330\037\331\323\002\067\213
-\255\054\107\360\216\201\006\247\015\060\014\353\367\074\017\040
-\035\334\162\106\356\245\002\310\133\303\311\126\151\114\305\030
-\301\221\173\013\325\023\000\233\274\357\303\110\076\106\140\040
-\205\052\325\220\266\315\213\240\314\062\335\267\375\100\125\262
-\120\034\126\256\314\215\167\115\307\040\115\247\061\166\357\150
-\222\212\220\036\010\201\126\262\255\151\243\122\320\313\034\304
-\043\075\037\231\376\114\350\026\143\216\306\010\216\366\061\366
-\322\372\345\166\335\265\034\222\243\111\315\315\001\315\150\315
-\251\151\272\243\353\035\015\234\244\040\246\301\240\305\321\106
-\114\027\155\322\254\146\077\226\214\340\204\324\066\377\042\131
-\305\371\021\140\250\137\004\175\362\032\366\045\102\141\017\304
-\112\270\076\211\002\003\001\000\001\060\015\006\011\052\206\110
-\206\367\015\001\001\005\005\000\003\202\001\001\000\064\046\025
-\074\300\215\115\103\111\035\275\351\041\222\327\146\234\267\336
-\305\270\320\344\135\137\166\042\300\046\371\204\072\072\371\214
-\265\373\354\140\361\350\316\004\260\310\335\247\003\217\060\363
-\230\337\244\346\244\061\337\323\034\013\106\334\162\040\077\256
-\356\005\074\244\063\077\013\071\254\160\170\163\113\231\053\337
-\060\302\124\260\250\073\125\241\376\026\050\315\102\275\164\156
-\200\333\047\104\247\316\104\135\324\033\220\230\015\036\102\224
-\261\000\054\004\320\164\243\002\005\042\143\143\315\203\265\373
-\301\155\142\153\151\165\375\135\160\101\271\365\277\174\337\276
-\301\062\163\042\041\213\130\201\173\025\221\172\272\343\144\110
-\260\177\373\066\045\332\225\320\361\044\024\027\335\030\200\153
-\106\043\071\124\365\216\142\011\004\035\224\220\246\233\346\045
-\342\102\105\252\270\220\255\276\010\217\251\013\102\030\224\317
-\162\071\341\261\103\340\050\317\267\347\132\154\023\153\111\263
-\377\343\030\174\211\213\063\135\254\063\327\247\371\332\072\125
-\311\130\020\371\252\357\132\266\317\113\113\337\052
-END
-
-# Trust for Certificate "Verisign Class 2 Public Primary Certification Authority - G3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 2 Public Primary Certification Authority - G3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\141\357\103\327\177\312\324\141\121\274\230\340\303\131\022\257
-\237\353\143\021
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\370\276\304\143\042\311\250\106\164\213\270\035\036\112\053\366
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\062\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\141\160\313\111\214\137\230\105\051\347\260\246\331\120
-\133\172
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 3 Public Primary Certification Authority - G3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 3 Public Primary Certification Authority - G3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\233\176\006\111\243\076\142\271\325\356\220\110\161
-\051\357\127
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\032\060\202\003\002\002\021\000\233\176\006\111\243
-\076\142\271\325\356\220\110\161\051\357\127\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\060\201\312\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003
-\125\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153\061\072\060\070\006\003\125\004\013\023\061\050
-\143\051\040\061\071\071\071\040\126\145\162\151\123\151\147\156
-\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165\164
-\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171
-\061\105\060\103\006\003\125\004\003\023\074\126\145\162\151\123
-\151\147\156\040\103\154\141\163\163\040\063\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\063\060\036\027\015\071\071\061\060\060
-\061\060\060\060\060\060\060\132\027\015\063\066\060\067\061\066
-\062\063\065\071\065\071\132\060\201\312\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\027\060\025\006\003\125\004\012
-\023\016\126\145\162\151\123\151\147\156\054\040\111\156\143\056
-\061\037\060\035\006\003\125\004\013\023\026\126\145\162\151\123
-\151\147\156\040\124\162\165\163\164\040\116\145\164\167\157\162
-\153\061\072\060\070\006\003\125\004\013\023\061\050\143\051\040
-\061\071\071\071\040\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162
-\151\172\145\144\040\165\163\145\040\157\156\154\171\061\105\060
-\103\006\003\125\004\003\023\074\126\145\162\151\123\151\147\156
-\040\103\154\141\163\163\040\063\040\120\165\142\154\151\143\040
-\120\162\151\155\141\162\171\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040
-\055\040\107\063\060\202\001\042\060\015\006\011\052\206\110\206
-\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012
-\002\202\001\001\000\313\272\234\122\374\170\037\032\036\157\033
-\067\163\275\370\311\153\224\022\060\117\360\066\107\365\320\221
-\012\365\027\310\245\141\301\026\100\115\373\212\141\220\345\166
-\040\301\021\006\175\253\054\156\246\365\021\101\216\372\055\255
-\052\141\131\244\147\046\114\320\350\274\122\133\160\040\004\130
-\321\172\311\244\151\274\203\027\144\255\005\213\274\320\130\316
-\215\214\365\353\360\102\111\013\235\227\047\147\062\156\341\256
-\223\025\034\160\274\040\115\057\030\336\222\210\350\154\205\127
-\021\032\351\176\343\046\021\124\242\105\226\125\203\312\060\211
-\350\334\330\243\355\052\200\077\177\171\145\127\076\025\040\146
-\010\057\225\223\277\252\107\057\250\106\227\360\022\342\376\302
-\012\053\121\346\166\346\267\106\267\342\015\246\314\250\303\114
-\131\125\211\346\350\123\134\034\352\235\360\142\026\013\247\311
-\137\014\360\336\302\166\316\257\367\152\362\372\101\246\242\063
-\024\311\345\172\143\323\236\142\067\325\205\145\236\016\346\123
-\044\164\033\136\035\022\123\133\307\054\347\203\111\073\025\256
-\212\150\271\127\227\002\003\001\000\001\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\021\024
-\226\301\253\222\010\367\077\057\311\262\376\344\132\237\144\336
-\333\041\117\206\231\064\166\066\127\335\320\025\057\305\255\177
-\025\037\067\142\163\076\324\347\137\316\027\003\333\065\372\053
-\333\256\140\011\137\036\137\217\156\273\013\075\352\132\023\036
-\014\140\157\265\300\265\043\042\056\007\013\313\251\164\313\107
-\273\035\301\327\245\153\314\057\322\102\375\111\335\247\211\317
-\123\272\332\000\132\050\277\202\337\370\272\023\035\120\206\202
-\375\216\060\217\051\106\260\036\075\065\332\070\142\026\030\112
-\255\346\266\121\154\336\257\142\353\001\320\036\044\376\172\217
-\022\032\022\150\270\373\146\231\024\024\105\134\256\347\256\151
-\027\201\053\132\067\311\136\052\364\306\342\241\134\124\233\246
-\124\000\317\360\361\301\307\230\060\032\073\066\026\333\243\156
-\352\375\255\262\302\332\357\002\107\023\212\300\361\263\061\255
-\117\034\341\117\234\257\017\014\235\367\170\015\330\364\065\126
-\200\332\267\155\027\217\235\036\201\144\341\376\305\105\272\255
-\153\271\012\172\116\117\113\204\356\113\361\175\335\021
-END
-
-# Trust for Certificate "Verisign Class 3 Public Primary Certification Authority - G3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 3 Public Primary Certification Authority - G3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\023\055\015\105\123\113\151\227\315\262\325\303\071\342\125\166
-\140\233\134\306
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\315\150\266\247\307\304\316\165\340\035\117\127\104\141\222\011
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\233\176\006\111\243\076\142\271\325\356\220\110\161
-\051\357\127
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 4 Public Primary Certification Authority - G3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 4 Public Primary Certification Authority - G3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\064\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\064\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\354\240\247\213\156\165\152\001\317\304\174\314\057
-\224\136\327
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\032\060\202\003\002\002\021\000\354\240\247\213\156
-\165\152\001\317\304\174\314\057\224\136\327\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\060\201\312\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003
-\125\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\061\037\060\035\006\003\125\004\013\023\026\126\145
-\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145\164
-\167\157\162\153\061\072\060\070\006\003\125\004\013\023\061\050
-\143\051\040\061\071\071\071\040\126\145\162\151\123\151\147\156
-\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165\164
-\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154\171
-\061\105\060\103\006\003\125\004\003\023\074\126\145\162\151\123
-\151\147\156\040\103\154\141\163\163\040\064\040\120\165\142\154
-\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\055\040\107\063\060\036\027\015\071\071\061\060\060
-\061\060\060\060\060\060\060\132\027\015\063\066\060\067\061\066
-\062\063\065\071\065\071\132\060\201\312\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\027\060\025\006\003\125\004\012
-\023\016\126\145\162\151\123\151\147\156\054\040\111\156\143\056
-\061\037\060\035\006\003\125\004\013\023\026\126\145\162\151\123
-\151\147\156\040\124\162\165\163\164\040\116\145\164\167\157\162
-\153\061\072\060\070\006\003\125\004\013\023\061\050\143\051\040
-\061\071\071\071\040\126\145\162\151\123\151\147\156\054\040\111
-\156\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162
-\151\172\145\144\040\165\163\145\040\157\156\154\171\061\105\060
-\103\006\003\125\004\003\023\074\126\145\162\151\123\151\147\156
-\040\103\154\141\163\163\040\064\040\120\165\142\154\151\143\040
-\120\162\151\155\141\162\171\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040
-\055\040\107\063\060\202\001\042\060\015\006\011\052\206\110\206
-\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012
-\002\202\001\001\000\255\313\245\021\151\306\131\253\361\217\265
-\031\017\126\316\314\265\037\040\344\236\046\045\113\340\163\145
-\211\131\336\320\203\344\365\017\265\273\255\361\174\350\041\374
-\344\350\014\356\174\105\042\031\166\222\264\023\267\040\133\011
-\372\141\256\250\362\245\215\205\302\052\326\336\146\066\322\233
-\002\364\250\222\140\174\234\151\264\217\044\036\320\206\122\366
-\062\234\101\130\036\042\275\315\105\142\225\010\156\320\146\335
-\123\242\314\360\020\334\124\163\213\004\241\106\063\063\134\027
-\100\271\236\115\323\363\276\125\203\350\261\211\216\132\174\232
-\226\042\220\073\210\045\362\322\123\210\002\014\013\170\362\346
-\067\027\113\060\106\007\344\200\155\246\330\226\056\350\054\370
-\021\263\070\015\146\246\233\352\311\043\133\333\216\342\363\023
-\216\032\131\055\252\002\360\354\244\207\146\334\301\077\365\330
-\271\364\354\202\306\322\075\225\035\345\300\117\204\311\331\243
-\104\050\006\152\327\105\254\360\153\152\357\116\137\370\021\202
-\036\070\143\064\146\120\324\076\223\163\372\060\303\146\255\377
-\223\055\227\357\003\002\003\001\000\001\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\217\372
-\045\153\117\133\344\244\116\047\125\253\042\025\131\074\312\265
-\012\324\112\333\253\335\241\137\123\305\240\127\071\302\316\107
-\053\276\072\310\126\277\302\331\047\020\072\261\005\074\300\167
-\061\273\072\323\005\173\155\232\034\060\214\200\313\223\223\052
-\203\253\005\121\202\002\000\021\147\153\363\210\141\107\137\003
-\223\325\133\015\340\361\324\241\062\065\205\262\072\333\260\202
-\253\321\313\012\274\117\214\133\305\113\000\073\037\052\202\246
-\176\066\205\334\176\074\147\000\265\344\073\122\340\250\353\135
-\025\371\306\155\360\255\035\016\205\267\251\232\163\024\132\133
-\217\101\050\300\325\350\055\115\244\136\315\252\331\355\316\334
-\330\325\074\102\035\027\301\022\135\105\070\303\070\363\374\205
-\056\203\106\110\262\327\040\137\222\066\217\347\171\017\230\136
-\231\350\360\320\244\273\365\123\275\052\316\131\260\257\156\177
-\154\273\322\036\000\260\041\355\370\101\142\202\271\330\262\304
-\273\106\120\363\061\305\217\001\250\164\353\365\170\047\332\347
-\367\146\103\363\236\203\076\040\252\303\065\140\221\316
-END
-
-# Trust for Certificate "Verisign Class 4 Public Primary Certification Authority - G3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 4 Public Primary Certification Authority - G3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\310\354\214\207\222\151\313\113\253\071\351\215\176\127\147\363
-\024\225\163\235
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\333\310\362\047\056\261\352\152\051\043\135\376\126\076\063\337
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\061\071\071\071\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\064\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\354\240\247\213\156\165\152\001\317\304\174\314\057
-\224\136\327
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Entrust.net Secure Server CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Entrust.net Secure Server CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\303\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\024\060\022\006\003\125\004\012\023\013\105\156\164\162\165
-\163\164\056\156\145\164\061\073\060\071\006\003\125\004\013\023
-\062\167\167\167\056\145\156\164\162\165\163\164\056\156\145\164
-\057\103\120\123\040\151\156\143\157\162\160\056\040\142\171\040
-\162\145\146\056\040\050\154\151\155\151\164\163\040\154\151\141
-\142\056\051\061\045\060\043\006\003\125\004\013\023\034\050\143
-\051\040\061\071\071\071\040\105\156\164\162\165\163\164\056\156
-\145\164\040\114\151\155\151\164\145\144\061\072\060\070\006\003
-\125\004\003\023\061\105\156\164\162\165\163\164\056\156\145\164
-\040\123\145\143\165\162\145\040\123\145\162\166\145\162\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\303\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\024\060\022\006\003\125\004\012\023\013\105\156\164\162\165
-\163\164\056\156\145\164\061\073\060\071\006\003\125\004\013\023
-\062\167\167\167\056\145\156\164\162\165\163\164\056\156\145\164
-\057\103\120\123\040\151\156\143\157\162\160\056\040\142\171\040
-\162\145\146\056\040\050\154\151\155\151\164\163\040\154\151\141
-\142\056\051\061\045\060\043\006\003\125\004\013\023\034\050\143
-\051\040\061\071\071\071\040\105\156\164\162\165\163\164\056\156
-\145\164\040\114\151\155\151\164\145\144\061\072\060\070\006\003
-\125\004\003\023\061\105\156\164\162\165\163\164\056\156\145\164
-\040\123\145\143\165\162\145\040\123\145\162\166\145\162\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\067\112\322\103
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\330\060\202\004\101\240\003\002\001\002\002\004\067
-\112\322\103\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\201\303\061\013\060\011\006\003\125\004\006\023\002
-\125\123\061\024\060\022\006\003\125\004\012\023\013\105\156\164
-\162\165\163\164\056\156\145\164\061\073\060\071\006\003\125\004
-\013\023\062\167\167\167\056\145\156\164\162\165\163\164\056\156
-\145\164\057\103\120\123\040\151\156\143\157\162\160\056\040\142
-\171\040\162\145\146\056\040\050\154\151\155\151\164\163\040\154
-\151\141\142\056\051\061\045\060\043\006\003\125\004\013\023\034
-\050\143\051\040\061\071\071\071\040\105\156\164\162\165\163\164
-\056\156\145\164\040\114\151\155\151\164\145\144\061\072\060\070
-\006\003\125\004\003\023\061\105\156\164\162\165\163\164\056\156
-\145\164\040\123\145\143\165\162\145\040\123\145\162\166\145\162
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\060\036\027\015\071\071\060\065
-\062\065\061\066\060\071\064\060\132\027\015\061\071\060\065\062
-\065\061\066\063\071\064\060\132\060\201\303\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\024\060\022\006\003\125\004
-\012\023\013\105\156\164\162\165\163\164\056\156\145\164\061\073
-\060\071\006\003\125\004\013\023\062\167\167\167\056\145\156\164
-\162\165\163\164\056\156\145\164\057\103\120\123\040\151\156\143
-\157\162\160\056\040\142\171\040\162\145\146\056\040\050\154\151
-\155\151\164\163\040\154\151\141\142\056\051\061\045\060\043\006
-\003\125\004\013\023\034\050\143\051\040\061\071\071\071\040\105
-\156\164\162\165\163\164\056\156\145\164\040\114\151\155\151\164
-\145\144\061\072\060\070\006\003\125\004\003\023\061\105\156\164
-\162\165\163\164\056\156\145\164\040\123\145\143\165\162\145\040
-\123\145\162\166\145\162\040\103\145\162\164\151\146\151\143\141
-\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\201
-\235\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\201\213\000\060\201\207\002\201\201\000\315\050\203\064\124
-\033\211\363\017\257\067\221\061\377\257\061\140\311\250\350\262
-\020\150\355\237\347\223\066\361\012\144\273\107\365\004\027\077
-\043\107\115\305\047\031\201\046\014\124\162\015\210\055\331\037
-\232\022\237\274\263\161\323\200\031\077\107\146\173\214\065\050
-\322\271\012\337\044\332\234\326\120\171\201\172\132\323\067\367
-\302\112\330\051\222\046\144\321\344\230\154\072\000\212\365\064
-\233\145\370\355\343\020\377\375\270\111\130\334\240\336\202\071
-\153\201\261\026\031\141\271\124\266\346\103\002\001\003\243\202
-\001\327\060\202\001\323\060\021\006\011\140\206\110\001\206\370
-\102\001\001\004\004\003\002\000\007\060\202\001\031\006\003\125
-\035\037\004\202\001\020\060\202\001\014\060\201\336\240\201\333
-\240\201\330\244\201\325\060\201\322\061\013\060\011\006\003\125
-\004\006\023\002\125\123\061\024\060\022\006\003\125\004\012\023
-\013\105\156\164\162\165\163\164\056\156\145\164\061\073\060\071
-\006\003\125\004\013\023\062\167\167\167\056\145\156\164\162\165
-\163\164\056\156\145\164\057\103\120\123\040\151\156\143\157\162
-\160\056\040\142\171\040\162\145\146\056\040\050\154\151\155\151
-\164\163\040\154\151\141\142\056\051\061\045\060\043\006\003\125
-\004\013\023\034\050\143\051\040\061\071\071\071\040\105\156\164
-\162\165\163\164\056\156\145\164\040\114\151\155\151\164\145\144
-\061\072\060\070\006\003\125\004\003\023\061\105\156\164\162\165
-\163\164\056\156\145\164\040\123\145\143\165\162\145\040\123\145
-\162\166\145\162\040\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\101\165\164\150\157\162\151\164\171\061\015\060\013
-\006\003\125\004\003\023\004\103\122\114\061\060\051\240\047\240
-\045\206\043\150\164\164\160\072\057\057\167\167\167\056\145\156
-\164\162\165\163\164\056\156\145\164\057\103\122\114\057\156\145
-\164\061\056\143\162\154\060\053\006\003\125\035\020\004\044\060
-\042\200\017\061\071\071\071\060\065\062\065\061\066\060\071\064
-\060\132\201\017\062\060\061\071\060\065\062\065\061\066\060\071
-\064\060\132\060\013\006\003\125\035\017\004\004\003\002\001\006
-\060\037\006\003\125\035\043\004\030\060\026\200\024\360\027\142
-\023\125\075\263\377\012\000\153\373\120\204\227\363\355\142\320
-\032\060\035\006\003\125\035\016\004\026\004\024\360\027\142\023
-\125\075\263\377\012\000\153\373\120\204\227\363\355\142\320\032
-\060\014\006\003\125\035\023\004\005\060\003\001\001\377\060\031
-\006\011\052\206\110\206\366\175\007\101\000\004\014\060\012\033
-\004\126\064\056\060\003\002\004\220\060\015\006\011\052\206\110
-\206\367\015\001\001\005\005\000\003\201\201\000\220\334\060\002
-\372\144\164\302\247\012\245\174\041\215\064\027\250\373\107\016
-\377\045\174\215\023\012\373\344\230\265\357\214\370\305\020\015
-\367\222\276\361\303\325\325\225\152\004\273\054\316\046\066\145
-\310\061\306\347\356\077\343\127\165\204\172\021\357\106\117\030
-\364\323\230\273\250\207\062\272\162\366\074\342\075\237\327\035
-\331\303\140\103\214\130\016\042\226\057\142\243\054\037\272\255
-\005\357\253\062\170\207\240\124\163\031\265\134\005\371\122\076
-\155\055\105\013\367\012\223\352\355\006\371\262
-END
-
-# Trust for Certificate "Entrust.net Secure Server CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Entrust.net Secure Server CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\231\246\233\346\032\376\210\153\115\053\202\000\174\270\124\374
-\061\176\025\071
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\337\362\200\163\314\361\346\141\163\374\365\102\351\305\174\356
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\303\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\024\060\022\006\003\125\004\012\023\013\105\156\164\162\165
-\163\164\056\156\145\164\061\073\060\071\006\003\125\004\013\023
-\062\167\167\167\056\145\156\164\162\165\163\164\056\156\145\164
-\057\103\120\123\040\151\156\143\157\162\160\056\040\142\171\040
-\162\145\146\056\040\050\154\151\155\151\164\163\040\154\151\141
-\142\056\051\061\045\060\043\006\003\125\004\013\023\034\050\143
-\051\040\061\071\071\071\040\105\156\164\162\165\163\164\056\156
-\145\164\040\114\151\155\151\164\145\144\061\072\060\070\006\003
-\125\004\003\023\061\105\156\164\162\165\163\164\056\156\145\164
-\040\123\145\143\165\162\145\040\123\145\162\166\145\162\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\067\112\322\103
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Entrust.net Premium 2048 Secure Server CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Entrust.net Premium 2048 Secure Server CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\264\061\024\060\022\006\003\125\004\012\023\013\105\156
-\164\162\165\163\164\056\156\145\164\061\100\060\076\006\003\125
-\004\013\024\067\167\167\167\056\145\156\164\162\165\163\164\056
-\156\145\164\057\103\120\123\137\062\060\064\070\040\151\156\143
-\157\162\160\056\040\142\171\040\162\145\146\056\040\050\154\151
-\155\151\164\163\040\154\151\141\142\056\051\061\045\060\043\006
-\003\125\004\013\023\034\050\143\051\040\061\071\071\071\040\105
-\156\164\162\165\163\164\056\156\145\164\040\114\151\155\151\164
-\145\144\061\063\060\061\006\003\125\004\003\023\052\105\156\164
-\162\165\163\164\056\156\145\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-\040\050\062\060\064\070\051
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\264\061\024\060\022\006\003\125\004\012\023\013\105\156
-\164\162\165\163\164\056\156\145\164\061\100\060\076\006\003\125
-\004\013\024\067\167\167\167\056\145\156\164\162\165\163\164\056
-\156\145\164\057\103\120\123\137\062\060\064\070\040\151\156\143
-\157\162\160\056\040\142\171\040\162\145\146\056\040\050\154\151
-\155\151\164\163\040\154\151\141\142\056\051\061\045\060\043\006
-\003\125\004\013\023\034\050\143\051\040\061\071\071\071\040\105
-\156\164\162\165\163\164\056\156\145\164\040\114\151\155\151\164
-\145\144\061\063\060\061\006\003\125\004\003\023\052\105\156\164
-\162\165\163\164\056\156\145\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-\040\050\062\060\064\070\051
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\070\143\271\146
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\134\060\202\003\104\240\003\002\001\002\002\004\070
-\143\271\146\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\201\264\061\024\060\022\006\003\125\004\012\023\013
-\105\156\164\162\165\163\164\056\156\145\164\061\100\060\076\006
-\003\125\004\013\024\067\167\167\167\056\145\156\164\162\165\163
-\164\056\156\145\164\057\103\120\123\137\062\060\064\070\040\151
-\156\143\157\162\160\056\040\142\171\040\162\145\146\056\040\050
-\154\151\155\151\164\163\040\154\151\141\142\056\051\061\045\060
-\043\006\003\125\004\013\023\034\050\143\051\040\061\071\071\071
-\040\105\156\164\162\165\163\164\056\156\145\164\040\114\151\155
-\151\164\145\144\061\063\060\061\006\003\125\004\003\023\052\105
-\156\164\162\165\163\164\056\156\145\164\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\050\062\060\064\070\051\060\036\027\015\071\071\061
-\062\062\064\061\067\065\060\065\061\132\027\015\061\071\061\062
-\062\064\061\070\062\060\065\061\132\060\201\264\061\024\060\022
-\006\003\125\004\012\023\013\105\156\164\162\165\163\164\056\156
-\145\164\061\100\060\076\006\003\125\004\013\024\067\167\167\167
-\056\145\156\164\162\165\163\164\056\156\145\164\057\103\120\123
-\137\062\060\064\070\040\151\156\143\157\162\160\056\040\142\171
-\040\162\145\146\056\040\050\154\151\155\151\164\163\040\154\151
-\141\142\056\051\061\045\060\043\006\003\125\004\013\023\034\050
-\143\051\040\061\071\071\071\040\105\156\164\162\165\163\164\056
-\156\145\164\040\114\151\155\151\164\145\144\061\063\060\061\006
-\003\125\004\003\023\052\105\156\164\162\165\163\164\056\156\145
-\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\040\050\062\060\064\070\051
-\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001
-\000\255\115\113\251\022\206\262\352\243\040\007\025\026\144\052
-\053\113\321\277\013\112\115\216\355\200\166\245\147\267\170\100
-\300\163\102\310\150\300\333\123\053\335\136\270\166\230\065\223
-\213\032\235\174\023\072\016\037\133\267\036\317\345\044\024\036
-\261\201\251\215\175\270\314\153\113\003\361\002\014\334\253\245
-\100\044\000\177\164\224\241\235\010\051\263\210\013\365\207\167
-\235\125\315\344\303\176\327\152\144\253\205\024\206\225\133\227
-\062\120\157\075\310\272\146\014\343\374\275\270\111\301\166\211
-\111\031\375\300\250\275\211\243\147\057\306\237\274\161\031\140
-\270\055\351\054\311\220\166\146\173\224\342\257\170\326\145\123
-\135\074\326\234\262\317\051\003\371\057\244\120\262\324\110\316
-\005\062\125\212\375\262\144\114\016\344\230\007\165\333\177\337
-\271\010\125\140\205\060\051\371\173\110\244\151\206\343\065\077
-\036\206\135\172\172\025\275\357\000\216\025\042\124\027\000\220
-\046\223\274\016\111\150\221\277\370\107\323\235\225\102\301\016
-\115\337\157\046\317\303\030\041\142\146\103\160\326\325\300\007
-\341\002\003\001\000\001\243\164\060\162\060\021\006\011\140\206
-\110\001\206\370\102\001\001\004\004\003\002\000\007\060\037\006
-\003\125\035\043\004\030\060\026\200\024\125\344\201\321\021\200
-\276\330\211\271\010\243\061\371\241\044\011\026\271\160\060\035
-\006\003\125\035\016\004\026\004\024\125\344\201\321\021\200\276
-\330\211\271\010\243\061\371\241\044\011\026\271\160\060\035\006
-\011\052\206\110\206\366\175\007\101\000\004\020\060\016\033\010
-\126\065\056\060\072\064\056\060\003\002\004\220\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000
-\131\107\254\041\204\212\027\311\234\211\123\036\272\200\205\032
-\306\074\116\076\261\234\266\174\306\222\135\030\144\002\343\323
-\006\010\021\141\174\143\343\053\235\061\003\160\166\322\243\050
-\240\364\273\232\143\163\355\155\345\052\333\355\024\251\053\306
-\066\021\320\053\353\007\213\245\332\236\134\031\235\126\022\365
-\124\051\310\005\355\262\022\052\215\364\003\033\377\347\222\020
-\207\260\072\265\303\235\005\067\022\243\307\364\025\271\325\244
-\071\026\233\123\072\043\221\361\250\202\242\152\210\150\301\171
-\002\042\274\252\246\326\256\337\260\024\137\270\207\320\335\174
-\177\173\377\257\034\317\346\333\007\255\136\333\205\235\320\053
-\015\063\333\004\321\346\111\100\023\053\166\373\076\351\234\211
-\017\025\316\030\260\205\170\041\117\153\117\016\372\066\147\315
-\007\362\377\010\320\342\336\331\277\052\257\270\207\206\041\074
-\004\312\267\224\150\177\317\074\351\230\327\070\377\354\300\331
-\120\360\056\113\130\256\106\157\320\056\303\140\332\162\125\162
-\275\114\105\236\141\272\277\204\201\222\003\321\322\151\174\305
-END
-
-# Trust for Certificate "Entrust.net Premium 2048 Secure Server CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Entrust.net Premium 2048 Secure Server CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\200\035\142\320\173\104\235\134\134\003\134\230\352\141\372\104
-\074\052\130\376
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\272\041\352\040\326\335\333\217\301\127\213\100\255\241\374\374
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\264\061\024\060\022\006\003\125\004\012\023\013\105\156
-\164\162\165\163\164\056\156\145\164\061\100\060\076\006\003\125
-\004\013\024\067\167\167\167\056\145\156\164\162\165\163\164\056
-\156\145\164\057\103\120\123\137\062\060\064\070\040\151\156\143
-\157\162\160\056\040\142\171\040\162\145\146\056\040\050\154\151
-\155\151\164\163\040\154\151\141\142\056\051\061\045\060\043\006
-\003\125\004\013\023\034\050\143\051\040\061\071\071\071\040\105
-\156\164\162\165\163\164\056\156\145\164\040\114\151\155\151\164
-\145\144\061\063\060\061\006\003\125\004\003\023\052\105\156\164
-\162\165\163\164\056\156\145\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-\040\050\062\060\064\070\051
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\070\143\271\146
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Baltimore CyberTrust Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Baltimore CyberTrust Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\111\105\061
-\022\060\020\006\003\125\004\012\023\011\102\141\154\164\151\155
-\157\162\145\061\023\060\021\006\003\125\004\013\023\012\103\171
-\142\145\162\124\162\165\163\164\061\042\060\040\006\003\125\004
-\003\023\031\102\141\154\164\151\155\157\162\145\040\103\171\142
-\145\162\124\162\165\163\164\040\122\157\157\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\111\105\061
-\022\060\020\006\003\125\004\012\023\011\102\141\154\164\151\155
-\157\162\145\061\023\060\021\006\003\125\004\013\023\012\103\171
-\142\145\162\124\162\165\163\164\061\042\060\040\006\003\125\004
-\003\023\031\102\141\154\164\151\155\157\162\145\040\103\171\142
-\145\162\124\162\165\163\164\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\002\000\000\271
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\167\060\202\002\137\240\003\002\001\002\002\004\002
-\000\000\271\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\132\061\013\060\011\006\003\125\004\006\023\002\111
-\105\061\022\060\020\006\003\125\004\012\023\011\102\141\154\164
-\151\155\157\162\145\061\023\060\021\006\003\125\004\013\023\012
-\103\171\142\145\162\124\162\165\163\164\061\042\060\040\006\003
-\125\004\003\023\031\102\141\154\164\151\155\157\162\145\040\103
-\171\142\145\162\124\162\165\163\164\040\122\157\157\164\060\036
-\027\015\060\060\060\065\061\062\061\070\064\066\060\060\132\027
-\015\062\065\060\065\061\062\062\063\065\071\060\060\132\060\132
-\061\013\060\011\006\003\125\004\006\023\002\111\105\061\022\060
-\020\006\003\125\004\012\023\011\102\141\154\164\151\155\157\162
-\145\061\023\060\021\006\003\125\004\013\023\012\103\171\142\145
-\162\124\162\165\163\164\061\042\060\040\006\003\125\004\003\023
-\031\102\141\154\164\151\155\157\162\145\040\103\171\142\145\162
-\124\162\165\163\164\040\122\157\157\164\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\243\004\273\042\253
-\230\075\127\350\046\162\232\265\171\324\051\342\341\350\225\200
-\261\260\343\133\216\053\051\232\144\337\241\135\355\260\011\005
-\155\333\050\056\316\142\242\142\376\264\210\332\022\353\070\353
-\041\235\300\101\053\001\122\173\210\167\323\034\217\307\272\271
-\210\265\152\011\347\163\350\021\100\247\321\314\312\142\215\055
-\345\217\013\246\120\322\250\120\303\050\352\365\253\045\207\212
-\232\226\034\251\147\270\077\014\325\367\371\122\023\057\302\033
-\325\160\160\360\217\300\022\312\006\313\232\341\331\312\063\172
-\167\326\370\354\271\361\150\104\102\110\023\322\300\302\244\256
-\136\140\376\266\246\005\374\264\335\007\131\002\324\131\030\230
-\143\365\245\143\340\220\014\175\135\262\006\172\363\205\352\353
-\324\003\256\136\204\076\137\377\025\355\151\274\371\071\066\162
-\165\317\167\122\115\363\311\220\054\271\075\345\311\043\123\077
-\037\044\230\041\134\007\231\051\275\306\072\354\347\156\206\072
-\153\227\164\143\063\275\150\030\061\360\170\215\166\277\374\236
-\216\135\052\206\247\115\220\334\047\032\071\002\003\001\000\001
-\243\105\060\103\060\035\006\003\125\035\016\004\026\004\024\345
-\235\131\060\202\107\130\314\254\372\010\124\066\206\173\072\265
-\004\115\360\060\022\006\003\125\035\023\001\001\377\004\010\060
-\006\001\001\377\002\001\003\060\016\006\003\125\035\017\001\001
-\377\004\004\003\002\001\006\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\003\202\001\001\000\205\014\135\216\344
-\157\121\150\102\005\240\335\273\117\047\045\204\003\275\367\144
-\375\055\327\060\343\244\020\027\353\332\051\051\266\171\077\166
-\366\031\023\043\270\020\012\371\130\244\324\141\160\275\004\141
-\152\022\212\027\325\012\275\305\274\060\174\326\351\014\045\215
-\206\100\117\354\314\243\176\070\306\067\021\117\355\335\150\061
-\216\114\322\263\001\164\356\276\165\136\007\110\032\177\160\377
-\026\134\204\300\171\205\270\005\375\177\276\145\021\243\017\300
-\002\264\370\122\067\071\004\325\251\061\172\030\277\240\052\364
-\022\231\367\243\105\202\343\074\136\365\235\236\265\310\236\174
-\056\310\244\236\116\010\024\113\155\375\160\155\153\032\143\275
-\144\346\037\267\316\360\362\237\056\273\033\267\362\120\210\163
-\222\302\342\343\026\215\232\062\002\253\216\030\335\351\020\021
-\356\176\065\253\220\257\076\060\224\172\320\063\075\247\145\017
-\365\374\216\236\142\317\107\104\054\001\135\273\035\265\062\322
-\107\322\070\056\320\376\201\334\062\152\036\265\356\074\325\374
-\347\201\035\031\303\044\102\352\143\071\251
-END
-
-# Trust for Certificate "Baltimore CyberTrust Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Baltimore CyberTrust Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\324\336\040\320\136\146\374\123\376\032\120\210\054\170\333\050
-\122\312\344\164
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\254\266\224\245\234\027\340\327\221\122\233\261\227\006\246\344
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\111\105\061
-\022\060\020\006\003\125\004\012\023\011\102\141\154\164\151\155
-\157\162\145\061\023\060\021\006\003\125\004\013\023\012\103\171
-\142\145\162\124\162\165\163\164\061\042\060\040\006\003\125\004
-\003\023\031\102\141\154\164\151\155\157\162\145\040\103\171\142
-\145\162\124\162\165\163\164\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\002\000\000\271
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Equifax Secure Global eBusiness CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Equifax Secure Global eBusiness CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060
-\053\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040
-\123\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102
-\165\163\151\156\145\163\163\040\103\101\055\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060
-\053\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040
-\123\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102
-\165\163\151\156\145\163\163\040\103\101\055\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\220\060\202\001\371\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060
-\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061\034
-\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141\170
-\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060\053
-\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040\123
-\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102\165
-\163\151\156\145\163\163\040\103\101\055\061\060\036\027\015\071
-\071\060\066\062\061\060\064\060\060\060\060\132\027\015\062\060
-\060\066\062\061\060\064\060\060\060\060\132\060\132\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\034\060\032\006\003
-\125\004\012\023\023\105\161\165\151\146\141\170\040\123\145\143
-\165\162\145\040\111\156\143\056\061\055\060\053\006\003\125\004
-\003\023\044\105\161\165\151\146\141\170\040\123\145\143\165\162
-\145\040\107\154\157\142\141\154\040\145\102\165\163\151\156\145
-\163\163\040\103\101\055\061\060\201\237\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\201\215\000\060\201\211
-\002\201\201\000\272\347\027\220\002\145\261\064\125\074\111\302
-\121\325\337\247\321\067\217\321\347\201\163\101\122\140\233\235
-\241\027\046\170\255\307\261\350\046\224\062\265\336\063\215\072
-\057\333\362\232\172\132\163\230\243\134\351\373\212\163\033\134
-\347\303\277\200\154\315\251\364\326\053\300\367\371\231\252\143
-\242\261\107\002\017\324\344\121\072\022\074\154\212\132\124\204
-\160\333\301\305\220\317\162\105\313\250\131\300\315\063\235\077
-\243\226\353\205\063\041\034\076\036\076\140\156\166\234\147\205
-\305\310\303\141\002\003\001\000\001\243\146\060\144\060\021\006
-\011\140\206\110\001\206\370\102\001\001\004\004\003\002\000\007
-\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001
-\377\060\037\006\003\125\035\043\004\030\060\026\200\024\276\250
-\240\164\162\120\153\104\267\311\043\330\373\250\377\263\127\153
-\150\154\060\035\006\003\125\035\016\004\026\004\024\276\250\240
-\164\162\120\153\104\267\311\043\330\373\250\377\263\127\153\150
-\154\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000
-\003\201\201\000\060\342\001\121\252\307\352\137\332\271\320\145
-\017\060\326\076\332\015\024\111\156\221\223\047\024\061\357\304
-\367\055\105\370\354\307\277\242\101\015\043\264\222\371\031\000
-\147\275\001\257\315\340\161\374\132\317\144\304\340\226\230\320
-\243\100\342\001\212\357\047\007\361\145\001\212\104\055\006\145
-\165\122\300\206\020\040\041\137\154\153\017\154\256\011\034\257
-\362\242\030\064\304\165\244\163\034\361\215\334\357\255\371\263
-\166\264\222\277\334\225\020\036\276\313\310\073\132\204\140\031
-\126\224\251\125
-END
-
-# Trust for Certificate "Equifax Secure Global eBusiness CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Equifax Secure Global eBusiness CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\176\170\112\020\034\202\145\314\055\341\361\155\107\264\100\312
-\331\012\031\105
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\217\135\167\006\047\304\230\074\133\223\170\347\327\175\233\314
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060
-\053\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040
-\123\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102
-\165\163\151\156\145\163\163\040\103\101\055\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Equifax Secure eBusiness CA 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Equifax Secure eBusiness CA 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\123\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\040\111\156\143\056\061\046\060
-\044\006\003\125\004\003\023\035\105\161\165\151\146\141\170\040
-\123\145\143\165\162\145\040\145\102\165\163\151\156\145\163\163
-\040\103\101\055\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\123\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\040\111\156\143\056\061\046\060
-\044\006\003\125\004\003\023\035\105\161\165\151\146\141\170\040
-\123\145\143\165\162\145\040\145\102\165\163\151\156\145\163\163
-\040\103\101\055\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\004
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\202\060\202\001\353\240\003\002\001\002\002\001\004
-\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060
-\123\061\013\060\011\006\003\125\004\006\023\002\125\123\061\034
-\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141\170
-\040\123\145\143\165\162\145\040\111\156\143\056\061\046\060\044
-\006\003\125\004\003\023\035\105\161\165\151\146\141\170\040\123
-\145\143\165\162\145\040\145\102\165\163\151\156\145\163\163\040
-\103\101\055\061\060\036\027\015\071\071\060\066\062\061\060\064
-\060\060\060\060\132\027\015\062\060\060\066\062\061\060\064\060
-\060\060\060\132\060\123\061\013\060\011\006\003\125\004\006\023
-\002\125\123\061\034\060\032\006\003\125\004\012\023\023\105\161
-\165\151\146\141\170\040\123\145\143\165\162\145\040\111\156\143
-\056\061\046\060\044\006\003\125\004\003\023\035\105\161\165\151
-\146\141\170\040\123\145\143\165\162\145\040\145\102\165\163\151
-\156\145\163\163\040\103\101\055\061\060\201\237\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\201\215\000\060
-\201\211\002\201\201\000\316\057\031\274\027\267\167\336\223\251
-\137\132\015\027\117\064\032\014\230\364\042\331\131\324\304\150
-\106\360\264\065\305\205\003\040\306\257\105\245\041\121\105\101
-\353\026\130\066\062\157\342\120\142\144\371\375\121\234\252\044
-\331\364\235\203\052\207\012\041\323\022\070\064\154\215\000\156
-\132\240\331\102\356\032\041\225\371\122\114\125\132\305\017\070
-\117\106\372\155\370\056\065\326\035\174\353\342\360\260\165\200
-\310\251\023\254\276\210\357\072\156\253\137\052\070\142\002\260
-\022\173\376\217\246\003\002\003\001\000\001\243\146\060\144\060
-\021\006\011\140\206\110\001\206\370\102\001\001\004\004\003\002
-\000\007\060\017\006\003\125\035\023\001\001\377\004\005\060\003
-\001\001\377\060\037\006\003\125\035\043\004\030\060\026\200\024
-\112\170\062\122\021\333\131\026\066\136\337\301\024\066\100\152
-\107\174\114\241\060\035\006\003\125\035\016\004\026\004\024\112
-\170\062\122\021\333\131\026\066\136\337\301\024\066\100\152\107
-\174\114\241\060\015\006\011\052\206\110\206\367\015\001\001\004
-\005\000\003\201\201\000\165\133\250\233\003\021\346\351\126\114
-\315\371\251\114\300\015\232\363\314\145\151\346\045\166\314\131
-\267\326\124\303\035\315\231\254\031\335\264\205\325\340\075\374
-\142\040\247\204\113\130\145\361\342\371\225\041\077\365\324\176
-\130\036\107\207\124\076\130\241\265\265\370\052\357\161\347\274
-\303\366\261\111\106\342\327\240\153\345\126\172\232\047\230\174
-\106\142\024\347\311\374\156\003\022\171\200\070\035\110\202\215
-\374\027\376\052\226\053\265\142\246\246\075\275\177\222\131\315
-\132\052\202\262\067\171
-END
-
-# Trust for Certificate "Equifax Secure eBusiness CA 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Equifax Secure eBusiness CA 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\332\100\030\213\221\211\243\355\356\256\332\227\376\057\235\365
-\267\321\212\101
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\144\234\357\056\104\374\306\217\122\007\320\121\163\217\313\075
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\123\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\040\111\156\143\056\061\046\060
-\044\006\003\125\004\003\023\035\105\161\165\151\146\141\170\040
-\123\145\143\165\162\145\040\145\102\165\163\151\156\145\163\163
-\040\103\101\055\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\004
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Equifax Secure eBusiness CA 2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Equifax Secure eBusiness CA 2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\061\046\060\044\006\003\125\004
-\013\023\035\105\161\165\151\146\141\170\040\123\145\143\165\162
-\145\040\145\102\165\163\151\156\145\163\163\040\103\101\055\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\061\046\060\044\006\003\125\004
-\013\023\035\105\161\165\151\146\141\170\040\123\145\143\165\162
-\145\040\145\102\165\163\151\156\145\163\163\040\103\101\055\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\067\160\317\265
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\040\060\202\002\211\240\003\002\001\002\002\004\067
-\160\317\265\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\116\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\027\060\025\006\003\125\004\012\023\016\105\161\165\151
-\146\141\170\040\123\145\143\165\162\145\061\046\060\044\006\003
-\125\004\013\023\035\105\161\165\151\146\141\170\040\123\145\143
-\165\162\145\040\145\102\165\163\151\156\145\163\163\040\103\101
-\055\062\060\036\027\015\071\071\060\066\062\063\061\062\061\064
-\064\065\132\027\015\061\071\060\066\062\063\061\062\061\064\064
-\065\132\060\116\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\027\060\025\006\003\125\004\012\023\016\105\161\165\151
-\146\141\170\040\123\145\143\165\162\145\061\046\060\044\006\003
-\125\004\013\023\035\105\161\165\151\146\141\170\040\123\145\143
-\165\162\145\040\145\102\165\163\151\156\145\163\163\040\103\101
-\055\062\060\201\237\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\201\215\000\060\201\211\002\201\201\000\344
-\071\071\223\036\122\006\033\050\066\370\262\243\051\305\355\216
-\262\021\275\376\353\347\264\164\302\217\377\005\347\331\235\006
-\277\022\310\077\016\362\326\321\044\262\021\336\321\163\011\212
-\324\261\054\230\011\015\036\120\106\262\203\246\105\215\142\150
-\273\205\033\040\160\062\252\100\315\246\226\137\304\161\067\077
-\004\363\267\101\044\071\007\032\036\056\141\130\240\022\013\345
-\245\337\305\253\352\067\161\314\034\310\067\072\271\227\122\247
-\254\305\152\044\224\116\234\173\317\300\152\326\337\041\275\002
-\003\001\000\001\243\202\001\011\060\202\001\005\060\160\006\003
-\125\035\037\004\151\060\147\060\145\240\143\240\141\244\137\060
-\135\061\013\060\011\006\003\125\004\006\023\002\125\123\061\027
-\060\025\006\003\125\004\012\023\016\105\161\165\151\146\141\170
-\040\123\145\143\165\162\145\061\046\060\044\006\003\125\004\013
-\023\035\105\161\165\151\146\141\170\040\123\145\143\165\162\145
-\040\145\102\165\163\151\156\145\163\163\040\103\101\055\062\061
-\015\060\013\006\003\125\004\003\023\004\103\122\114\061\060\032
-\006\003\125\035\020\004\023\060\021\201\017\062\060\061\071\060
-\066\062\063\061\062\061\064\064\065\132\060\013\006\003\125\035
-\017\004\004\003\002\001\006\060\037\006\003\125\035\043\004\030
-\060\026\200\024\120\236\013\352\257\136\271\040\110\246\120\152
-\313\375\330\040\172\247\202\166\060\035\006\003\125\035\016\004
-\026\004\024\120\236\013\352\257\136\271\040\110\246\120\152\313
-\375\330\040\172\247\202\166\060\014\006\003\125\035\023\004\005
-\060\003\001\001\377\060\032\006\011\052\206\110\206\366\175\007
-\101\000\004\015\060\013\033\005\126\063\056\060\143\003\002\006
-\300\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\201\201\000\014\206\202\255\350\116\032\365\216\211\047\342
-\065\130\075\051\264\007\217\066\120\225\277\156\301\236\353\304
-\220\262\205\250\273\267\102\340\017\007\071\337\373\236\220\262
-\321\301\076\123\237\003\104\260\176\113\364\157\344\174\037\347
-\342\261\344\270\232\357\303\275\316\336\013\062\064\331\336\050
-\355\063\153\304\324\327\075\022\130\253\175\011\055\313\160\365
-\023\212\224\241\047\244\326\160\305\155\224\265\311\175\235\240
-\322\306\010\111\331\146\233\246\323\364\013\334\305\046\127\341
-\221\060\352\315
-END
-
-# Trust for Certificate "Equifax Secure eBusiness CA 2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Equifax Secure eBusiness CA 2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\071\117\366\205\013\006\276\122\345\030\126\314\020\341\200\350
-\202\263\205\314
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\252\277\277\144\227\332\230\035\157\306\010\072\225\160\063\312
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\061\046\060\044\006\003\125\004
-\013\023\035\105\161\165\151\146\141\170\040\123\145\143\165\162
-\145\040\145\102\165\163\151\156\145\163\163\040\103\101\055\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\067\160\317\265
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "AddTrust Low-Value Services Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AddTrust Low-Value Services Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\145\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024
-\101\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\003\023\030\101
-\144\144\124\162\165\163\164\040\103\154\141\163\163\040\061\040
-\103\101\040\122\157\157\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\145\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024
-\101\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\003\023\030\101
-\144\144\124\162\165\163\164\040\103\154\141\163\163\040\061\040
-\103\101\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\030\060\202\003\000\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\145\061\013\060\011\006\003\125\004\006\023\002\123\105\061\024
-\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165\163
-\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024\101
-\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164\167
-\157\162\153\061\041\060\037\006\003\125\004\003\023\030\101\144
-\144\124\162\165\163\164\040\103\154\141\163\163\040\061\040\103
-\101\040\122\157\157\164\060\036\027\015\060\060\060\065\063\060
-\061\060\063\070\063\061\132\027\015\062\060\060\065\063\060\061
-\060\063\070\063\061\132\060\145\061\013\060\011\006\003\125\004
-\006\023\002\123\105\061\024\060\022\006\003\125\004\012\023\013
-\101\144\144\124\162\165\163\164\040\101\102\061\035\060\033\006
-\003\125\004\013\023\024\101\144\144\124\162\165\163\164\040\124
-\124\120\040\116\145\164\167\157\162\153\061\041\060\037\006\003
-\125\004\003\023\030\101\144\144\124\162\165\163\164\040\103\154
-\141\163\163\040\061\040\103\101\040\122\157\157\164\060\202\001
-\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\202\001\017\000\060\202\001\012\002\202\001\001\000\226\226
-\324\041\111\140\342\153\350\101\007\014\336\304\340\334\023\043
-\315\301\065\307\373\326\116\021\012\147\136\365\006\133\153\245
-\010\073\133\051\026\072\347\207\262\064\006\305\274\005\245\003
-\174\202\313\051\020\256\341\210\201\275\326\236\323\376\055\126
-\301\025\316\343\046\235\025\056\020\373\006\217\060\004\336\247
-\264\143\264\377\261\234\256\074\257\167\266\126\305\265\253\242
-\351\151\072\075\016\063\171\062\077\160\202\222\231\141\155\215
-\060\010\217\161\077\246\110\127\031\370\045\334\113\146\134\245
-\164\217\230\256\310\371\300\006\042\347\254\163\337\245\056\373
-\122\334\261\025\145\040\372\065\146\151\336\337\054\361\156\274
-\060\333\054\044\022\333\353\065\065\150\220\313\000\260\227\041
-\075\164\041\043\145\064\053\273\170\131\243\326\341\166\071\232
-\244\111\216\214\164\257\156\244\232\243\331\233\322\070\134\233
-\242\030\314\165\043\204\276\353\342\115\063\161\216\032\360\302
-\370\307\035\242\255\003\227\054\370\317\045\306\366\270\044\061
-\261\143\135\222\177\143\360\045\311\123\056\037\277\115\002\003
-\001\000\001\243\201\322\060\201\317\060\035\006\003\125\035\016
-\004\026\004\024\225\261\264\360\224\266\275\307\332\321\021\011
-\041\276\301\257\111\375\020\173\060\013\006\003\125\035\017\004
-\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004
-\005\060\003\001\001\377\060\201\217\006\003\125\035\043\004\201
-\207\060\201\204\200\024\225\261\264\360\224\266\275\307\332\321
-\021\011\041\276\301\257\111\375\020\173\241\151\244\147\060\145
-\061\013\060\011\006\003\125\004\006\023\002\123\105\061\024\060
-\022\006\003\125\004\012\023\013\101\144\144\124\162\165\163\164
-\040\101\102\061\035\060\033\006\003\125\004\013\023\024\101\144
-\144\124\162\165\163\164\040\124\124\120\040\116\145\164\167\157
-\162\153\061\041\060\037\006\003\125\004\003\023\030\101\144\144
-\124\162\165\163\164\040\103\154\141\163\163\040\061\040\103\101
-\040\122\157\157\164\202\001\001\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\202\001\001\000\054\155\144\033
-\037\315\015\335\271\001\372\226\143\064\062\110\107\231\256\227
-\355\375\162\026\246\163\107\132\364\353\335\351\365\326\373\105
-\314\051\211\104\135\277\106\071\075\350\356\274\115\124\206\036
-\035\154\343\027\047\103\341\211\126\053\251\157\162\116\111\063
-\343\162\174\052\043\232\274\076\377\050\052\355\243\377\034\043
-\272\103\127\011\147\115\113\142\006\055\370\377\154\235\140\036
-\330\034\113\175\265\061\057\331\320\174\135\370\336\153\203\030
-\170\067\127\057\350\063\007\147\337\036\307\153\052\225\166\256
-\217\127\243\360\364\122\264\251\123\010\317\340\117\323\172\123
-\213\375\273\034\126\066\362\376\262\266\345\166\273\325\042\145
-\247\077\376\321\146\255\013\274\153\231\206\357\077\175\363\030
-\062\312\173\306\343\253\144\106\225\370\046\151\331\125\203\173
-\054\226\007\377\131\054\104\243\306\345\351\251\334\241\143\200
-\132\041\136\041\317\123\124\360\272\157\211\333\250\252\225\317
-\213\343\161\314\036\033\040\104\010\300\172\266\100\375\304\344
-\065\341\035\026\034\320\274\053\216\326\161\331
-END
-
-# Trust for Certificate "AddTrust Low-Value Services Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AddTrust Low-Value Services Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\314\253\016\240\114\043\001\326\151\173\335\067\237\315\022\353
-\044\343\224\235
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\036\102\225\002\063\222\153\271\137\300\177\332\326\262\113\374
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\145\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024
-\101\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\003\023\030\101
-\144\144\124\162\165\163\164\040\103\154\141\163\163\040\061\040
-\103\101\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "AddTrust External Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AddTrust External Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\157\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\046\060\044\006\003\125\004\013\023\035
-\101\144\144\124\162\165\163\164\040\105\170\164\145\162\156\141
-\154\040\124\124\120\040\116\145\164\167\157\162\153\061\042\060
-\040\006\003\125\004\003\023\031\101\144\144\124\162\165\163\164
-\040\105\170\164\145\162\156\141\154\040\103\101\040\122\157\157
-\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\157\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\046\060\044\006\003\125\004\013\023\035
-\101\144\144\124\162\165\163\164\040\105\170\164\145\162\156\141
-\154\040\124\124\120\040\116\145\164\167\157\162\153\061\042\060
-\040\006\003\125\004\003\023\031\101\144\144\124\162\165\163\164
-\040\105\170\164\145\162\156\141\154\040\103\101\040\122\157\157
-\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\066\060\202\003\036\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\157\061\013\060\011\006\003\125\004\006\023\002\123\105\061\024
-\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165\163
-\164\040\101\102\061\046\060\044\006\003\125\004\013\023\035\101
-\144\144\124\162\165\163\164\040\105\170\164\145\162\156\141\154
-\040\124\124\120\040\116\145\164\167\157\162\153\061\042\060\040
-\006\003\125\004\003\023\031\101\144\144\124\162\165\163\164\040
-\105\170\164\145\162\156\141\154\040\103\101\040\122\157\157\164
-\060\036\027\015\060\060\060\065\063\060\061\060\064\070\063\070
-\132\027\015\062\060\060\065\063\060\061\060\064\070\063\070\132
-\060\157\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\046\060\044\006\003\125\004\013\023\035
-\101\144\144\124\162\165\163\164\040\105\170\164\145\162\156\141
-\154\040\124\124\120\040\116\145\164\167\157\162\153\061\042\060
-\040\006\003\125\004\003\023\031\101\144\144\124\162\165\163\164
-\040\105\170\164\145\162\156\141\154\040\103\101\040\122\157\157
-\164\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001
-\001\000\267\367\032\063\346\362\000\004\055\071\340\116\133\355
-\037\274\154\017\315\265\372\043\266\316\336\233\021\063\227\244
-\051\114\175\223\237\275\112\274\223\355\003\032\343\217\317\345
-\155\120\132\326\227\051\224\132\200\260\111\172\333\056\225\375
-\270\312\277\067\070\055\036\076\221\101\255\160\126\307\360\117
-\077\350\062\236\164\312\310\220\124\351\306\137\017\170\235\232
-\100\074\016\254\141\252\136\024\217\236\207\241\152\120\334\327
-\232\116\257\005\263\246\161\224\234\161\263\120\140\012\307\023
-\235\070\007\206\002\250\351\250\151\046\030\220\253\114\260\117
-\043\253\072\117\204\330\337\316\237\341\151\157\273\327\102\327
-\153\104\344\307\255\356\155\101\137\162\132\161\010\067\263\171
-\145\244\131\240\224\067\367\000\057\015\302\222\162\332\320\070
-\162\333\024\250\105\304\135\052\175\267\264\326\304\356\254\315
-\023\104\267\311\053\335\103\000\045\372\141\271\151\152\130\043
-\021\267\247\063\217\126\165\131\365\315\051\327\106\267\012\053
-\145\266\323\102\157\025\262\270\173\373\357\351\135\123\325\064
-\132\047\002\003\001\000\001\243\201\334\060\201\331\060\035\006
-\003\125\035\016\004\026\004\024\255\275\230\172\064\264\046\367
-\372\304\046\124\357\003\275\340\044\313\124\032\060\013\006\003
-\125\035\017\004\004\003\002\001\006\060\017\006\003\125\035\023
-\001\001\377\004\005\060\003\001\001\377\060\201\231\006\003\125
-\035\043\004\201\221\060\201\216\200\024\255\275\230\172\064\264
-\046\367\372\304\046\124\357\003\275\340\044\313\124\032\241\163
-\244\161\060\157\061\013\060\011\006\003\125\004\006\023\002\123
-\105\061\024\060\022\006\003\125\004\012\023\013\101\144\144\124
-\162\165\163\164\040\101\102\061\046\060\044\006\003\125\004\013
-\023\035\101\144\144\124\162\165\163\164\040\105\170\164\145\162
-\156\141\154\040\124\124\120\040\116\145\164\167\157\162\153\061
-\042\060\040\006\003\125\004\003\023\031\101\144\144\124\162\165
-\163\164\040\105\170\164\145\162\156\141\154\040\103\101\040\122
-\157\157\164\202\001\001\060\015\006\011\052\206\110\206\367\015
-\001\001\005\005\000\003\202\001\001\000\260\233\340\205\045\302
-\326\043\342\017\226\006\222\235\101\230\234\331\204\171\201\331
-\036\133\024\007\043\066\145\217\260\330\167\273\254\101\154\107
-\140\203\121\260\371\062\075\347\374\366\046\023\307\200\026\245
-\277\132\374\207\317\170\171\211\041\232\342\114\007\012\206\065
-\274\362\336\121\304\322\226\267\334\176\116\356\160\375\034\071
-\353\014\002\121\024\055\216\275\026\340\301\337\106\165\347\044
-\255\354\364\102\264\205\223\160\020\147\272\235\006\065\112\030
-\323\053\172\314\121\102\241\172\143\321\346\273\241\305\053\302
-\066\276\023\015\346\275\143\176\171\173\247\011\015\100\253\152
-\335\217\212\303\366\366\214\032\102\005\121\324\105\365\237\247
-\142\041\150\025\040\103\074\231\347\174\275\044\330\251\221\027
-\163\210\077\126\033\061\070\030\264\161\017\232\315\310\016\236
-\216\056\033\341\214\230\203\313\037\061\361\104\114\306\004\163
-\111\166\140\017\307\370\275\027\200\153\056\351\314\114\016\132
-\232\171\017\040\012\056\325\236\143\046\036\125\222\224\330\202
-\027\132\173\320\274\307\217\116\206\004
-END
-
-# Trust for Certificate "AddTrust External Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AddTrust External Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\002\372\363\342\221\103\124\150\140\170\127\151\115\365\344\133
-\150\205\030\150
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\035\065\124\004\205\170\260\077\102\102\115\277\040\163\012\077
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\157\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\046\060\044\006\003\125\004\013\023\035
-\101\144\144\124\162\165\163\164\040\105\170\164\145\162\156\141
-\154\040\124\124\120\040\116\145\164\167\157\162\153\061\042\060
-\040\006\003\125\004\003\023\031\101\144\144\124\162\165\163\164
-\040\105\170\164\145\162\156\141\154\040\103\101\040\122\157\157
-\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "AddTrust Public Services Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AddTrust Public Services Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\144\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024
-\101\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164
-\167\157\162\153\061\040\060\036\006\003\125\004\003\023\027\101
-\144\144\124\162\165\163\164\040\120\165\142\154\151\143\040\103
-\101\040\122\157\157\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\144\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024
-\101\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164
-\167\157\162\153\061\040\060\036\006\003\125\004\003\023\027\101
-\144\144\124\162\165\163\164\040\120\165\142\154\151\143\040\103
-\101\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\025\060\202\002\375\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\144\061\013\060\011\006\003\125\004\006\023\002\123\105\061\024
-\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165\163
-\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024\101
-\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164\167
-\157\162\153\061\040\060\036\006\003\125\004\003\023\027\101\144
-\144\124\162\165\163\164\040\120\165\142\154\151\143\040\103\101
-\040\122\157\157\164\060\036\027\015\060\060\060\065\063\060\061
-\060\064\061\065\060\132\027\015\062\060\060\065\063\060\061\060
-\064\061\065\060\132\060\144\061\013\060\011\006\003\125\004\006
-\023\002\123\105\061\024\060\022\006\003\125\004\012\023\013\101
-\144\144\124\162\165\163\164\040\101\102\061\035\060\033\006\003
-\125\004\013\023\024\101\144\144\124\162\165\163\164\040\124\124
-\120\040\116\145\164\167\157\162\153\061\040\060\036\006\003\125
-\004\003\023\027\101\144\144\124\162\165\163\164\040\120\165\142
-\154\151\143\040\103\101\040\122\157\157\164\060\202\001\042\060
-\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202
-\001\017\000\060\202\001\012\002\202\001\001\000\351\032\060\217
-\203\210\024\301\040\330\074\233\217\033\176\003\164\273\332\151
-\323\106\245\370\216\302\014\021\220\121\245\057\146\124\100\125
-\352\333\037\112\126\356\237\043\156\364\071\313\241\271\157\362
-\176\371\135\207\046\141\236\034\370\342\354\246\201\370\041\305
-\044\314\021\014\077\333\046\162\172\307\001\227\007\027\371\327
-\030\054\060\175\016\172\036\142\036\306\113\300\375\175\142\167
-\323\104\036\047\366\077\113\104\263\267\070\331\071\037\140\325
-\121\222\163\003\264\000\151\343\363\024\116\356\321\334\011\317
-\167\064\106\120\260\370\021\362\376\070\171\367\007\071\376\121
-\222\227\013\133\010\137\064\206\001\255\210\227\353\146\315\136
-\321\377\334\175\362\204\332\272\167\255\334\200\010\307\247\207
-\326\125\237\227\152\350\310\021\144\272\347\031\051\077\021\263
-\170\220\204\040\122\133\021\357\170\320\203\366\325\110\220\320
-\060\034\317\200\371\140\376\171\344\210\362\335\000\353\224\105
-\353\145\224\151\100\272\300\325\264\270\272\175\004\021\250\353
-\061\005\226\224\116\130\041\216\237\320\140\375\002\003\001\000
-\001\243\201\321\060\201\316\060\035\006\003\125\035\016\004\026
-\004\024\201\076\067\330\222\260\037\167\237\134\264\253\163\252
-\347\366\064\140\057\372\060\013\006\003\125\035\017\004\004\003
-\002\001\006\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\201\216\006\003\125\035\043\004\201\206\060
-\201\203\200\024\201\076\067\330\222\260\037\167\237\134\264\253
-\163\252\347\366\064\140\057\372\241\150\244\146\060\144\061\013
-\060\011\006\003\125\004\006\023\002\123\105\061\024\060\022\006
-\003\125\004\012\023\013\101\144\144\124\162\165\163\164\040\101
-\102\061\035\060\033\006\003\125\004\013\023\024\101\144\144\124
-\162\165\163\164\040\124\124\120\040\116\145\164\167\157\162\153
-\061\040\060\036\006\003\125\004\003\023\027\101\144\144\124\162
-\165\163\164\040\120\165\142\154\151\143\040\103\101\040\122\157
-\157\164\202\001\001\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\003\202\001\001\000\003\367\025\112\370\044\332
-\043\126\026\223\166\335\066\050\271\256\033\270\303\361\144\272
-\040\030\170\225\051\047\127\005\274\174\052\364\271\121\125\332
-\207\002\336\017\026\027\061\370\252\171\056\011\023\273\257\262
-\040\031\022\345\223\371\113\371\203\350\104\325\262\101\045\277
-\210\165\157\377\020\374\112\124\320\137\360\372\357\066\163\175
-\033\066\105\306\041\155\264\025\270\116\317\234\134\245\075\132
-\000\216\006\343\074\153\062\173\362\237\360\266\375\337\360\050
-\030\110\360\306\274\320\277\064\200\226\302\112\261\155\216\307
-\220\105\336\057\147\254\105\004\243\172\334\125\222\311\107\146
-\330\032\214\307\355\234\116\232\340\022\273\265\152\114\204\341
-\341\042\015\207\000\144\376\214\175\142\071\145\246\357\102\266
-\200\045\022\141\001\250\044\023\160\000\021\046\137\372\065\120
-\305\110\314\006\107\350\047\330\160\215\137\144\346\241\104\046
-\136\042\354\222\315\377\102\232\104\041\155\134\305\343\042\035
-\137\107\022\347\316\137\135\372\330\252\261\063\055\331\166\362
-\116\072\063\014\053\263\055\220\006
-END
-
-# Trust for Certificate "AddTrust Public Services Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AddTrust Public Services Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\052\266\050\110\136\170\373\363\255\236\171\020\335\153\337\231
-\162\054\226\345
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\301\142\076\043\305\202\163\234\003\131\113\053\351\167\111\177
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\144\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024
-\101\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164
-\167\157\162\153\061\040\060\036\006\003\125\004\003\023\027\101
-\144\144\124\162\165\163\164\040\120\165\142\154\151\143\040\103
-\101\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "AddTrust Qualified Certificates Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AddTrust Qualified Certificates Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\147\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024
-\101\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164
-\167\157\162\153\061\043\060\041\006\003\125\004\003\023\032\101
-\144\144\124\162\165\163\164\040\121\165\141\154\151\146\151\145
-\144\040\103\101\040\122\157\157\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\147\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024
-\101\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164
-\167\157\162\153\061\043\060\041\006\003\125\004\003\023\032\101
-\144\144\124\162\165\163\164\040\121\165\141\154\151\146\151\145
-\144\040\103\101\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\036\060\202\003\006\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\147\061\013\060\011\006\003\125\004\006\023\002\123\105\061\024
-\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165\163
-\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024\101
-\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164\167
-\157\162\153\061\043\060\041\006\003\125\004\003\023\032\101\144
-\144\124\162\165\163\164\040\121\165\141\154\151\146\151\145\144
-\040\103\101\040\122\157\157\164\060\036\027\015\060\060\060\065
-\063\060\061\060\064\064\065\060\132\027\015\062\060\060\065\063
-\060\061\060\064\064\065\060\132\060\147\061\013\060\011\006\003
-\125\004\006\023\002\123\105\061\024\060\022\006\003\125\004\012
-\023\013\101\144\144\124\162\165\163\164\040\101\102\061\035\060
-\033\006\003\125\004\013\023\024\101\144\144\124\162\165\163\164
-\040\124\124\120\040\116\145\164\167\157\162\153\061\043\060\041
-\006\003\125\004\003\023\032\101\144\144\124\162\165\163\164\040
-\121\165\141\154\151\146\151\145\144\040\103\101\040\122\157\157
-\164\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001
-\001\000\344\036\232\376\334\011\132\207\244\237\107\276\021\137
-\257\204\064\333\142\074\171\170\267\351\060\265\354\014\034\052
-\304\026\377\340\354\161\353\212\365\021\156\355\117\015\221\322
-\022\030\055\111\025\001\302\244\042\023\307\021\144\377\042\022
-\232\271\216\134\057\010\317\161\152\263\147\001\131\361\135\106
-\363\260\170\245\366\016\102\172\343\177\033\314\320\360\267\050
-\375\052\352\236\263\260\271\004\252\375\366\307\264\261\270\052
-\240\373\130\361\031\240\157\160\045\176\076\151\112\177\017\042
-\330\357\255\010\021\232\051\231\341\252\104\105\232\022\136\076
-\235\155\122\374\347\240\075\150\057\360\113\160\174\023\070\255
-\274\025\045\361\326\316\253\242\300\061\326\057\237\340\377\024
-\131\374\204\223\331\207\174\114\124\023\353\237\321\055\021\370
-\030\072\072\336\045\331\367\323\100\355\244\006\022\304\073\341
-\221\301\126\065\360\024\334\145\066\011\156\253\244\007\307\065
-\321\302\003\063\066\133\165\046\155\102\361\022\153\103\157\113
-\161\224\372\064\035\355\023\156\312\200\177\230\057\154\271\145
-\330\351\002\003\001\000\001\243\201\324\060\201\321\060\035\006
-\003\125\035\016\004\026\004\024\071\225\213\142\213\134\311\324
-\200\272\130\017\227\077\025\010\103\314\230\247\060\013\006\003
-\125\035\017\004\004\003\002\001\006\060\017\006\003\125\035\023
-\001\001\377\004\005\060\003\001\001\377\060\201\221\006\003\125
-\035\043\004\201\211\060\201\206\200\024\071\225\213\142\213\134
-\311\324\200\272\130\017\227\077\025\010\103\314\230\247\241\153
-\244\151\060\147\061\013\060\011\006\003\125\004\006\023\002\123
-\105\061\024\060\022\006\003\125\004\012\023\013\101\144\144\124
-\162\165\163\164\040\101\102\061\035\060\033\006\003\125\004\013
-\023\024\101\144\144\124\162\165\163\164\040\124\124\120\040\116
-\145\164\167\157\162\153\061\043\060\041\006\003\125\004\003\023
-\032\101\144\144\124\162\165\163\164\040\121\165\141\154\151\146
-\151\145\144\040\103\101\040\122\157\157\164\202\001\001\060\015
-\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001
-\001\000\031\253\165\352\370\213\145\141\225\023\272\151\004\357
-\206\312\023\240\307\252\117\144\033\077\030\366\250\055\054\125
-\217\005\267\060\352\102\152\035\300\045\121\055\247\277\014\263
-\355\357\010\177\154\074\106\032\352\030\103\337\166\314\371\146
-\206\234\054\150\365\351\027\370\061\263\030\304\326\110\175\043
-\114\150\301\176\273\001\024\157\305\331\156\336\273\004\102\152
-\370\366\134\175\345\332\372\207\353\015\065\122\147\320\236\227
-\166\005\223\077\225\307\001\346\151\125\070\177\020\141\231\311
-\343\137\246\312\076\202\143\110\252\342\010\110\076\252\362\262
-\205\142\246\264\247\331\275\067\234\150\265\055\126\175\260\267
-\077\240\261\007\326\351\117\334\336\105\161\060\062\177\033\056
-\011\371\277\122\241\356\302\200\076\006\134\056\125\100\301\033
-\365\160\105\260\334\135\372\366\162\132\167\322\143\315\317\130
-\211\000\102\143\077\171\071\320\104\260\202\156\101\031\350\335
-\340\301\210\132\321\036\161\223\037\044\060\164\345\036\250\336
-\074\047\067\177\203\256\236\167\317\360\060\261\377\113\231\350
-\306\241
-END
-
-# Trust for Certificate "AddTrust Qualified Certificates Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AddTrust Qualified Certificates Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\115\043\170\354\221\225\071\265\000\177\165\217\003\073\041\036
-\305\115\213\317
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\047\354\071\107\315\332\132\257\342\232\001\145\041\251\114\273
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\147\061\013\060\011\006\003\125\004\006\023\002\123\105\061
-\024\060\022\006\003\125\004\012\023\013\101\144\144\124\162\165
-\163\164\040\101\102\061\035\060\033\006\003\125\004\013\023\024
-\101\144\144\124\162\165\163\164\040\124\124\120\040\116\145\164
-\167\157\162\153\061\043\060\041\006\003\125\004\003\023\032\101
-\144\144\124\162\165\163\164\040\121\165\141\154\151\146\151\145
-\144\040\103\101\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Entrust Root Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Entrust Root Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\260\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165
-\163\164\054\040\111\156\143\056\061\071\060\067\006\003\125\004
-\013\023\060\167\167\167\056\145\156\164\162\165\163\164\056\156
-\145\164\057\103\120\123\040\151\163\040\151\156\143\157\162\160
-\157\162\141\164\145\144\040\142\171\040\162\145\146\145\162\145
-\156\143\145\061\037\060\035\006\003\125\004\013\023\026\050\143
-\051\040\062\060\060\066\040\105\156\164\162\165\163\164\054\040
-\111\156\143\056\061\055\060\053\006\003\125\004\003\023\044\105
-\156\164\162\165\163\164\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\260\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165
-\163\164\054\040\111\156\143\056\061\071\060\067\006\003\125\004
-\013\023\060\167\167\167\056\145\156\164\162\165\163\164\056\156
-\145\164\057\103\120\123\040\151\163\040\151\156\143\157\162\160
-\157\162\141\164\145\144\040\142\171\040\162\145\146\145\162\145
-\156\143\145\061\037\060\035\006\003\125\004\013\023\026\050\143
-\051\040\062\060\060\066\040\105\156\164\162\165\163\164\054\040
-\111\156\143\056\061\055\060\053\006\003\125\004\003\023\044\105
-\156\164\162\165\163\164\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\105\153\120\124
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\221\060\202\003\171\240\003\002\001\002\002\004\105
-\153\120\124\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\201\260\061\013\060\011\006\003\125\004\006\023\002
-\125\123\061\026\060\024\006\003\125\004\012\023\015\105\156\164
-\162\165\163\164\054\040\111\156\143\056\061\071\060\067\006\003
-\125\004\013\023\060\167\167\167\056\145\156\164\162\165\163\164
-\056\156\145\164\057\103\120\123\040\151\163\040\151\156\143\157
-\162\160\157\162\141\164\145\144\040\142\171\040\162\145\146\145
-\162\145\156\143\145\061\037\060\035\006\003\125\004\013\023\026
-\050\143\051\040\062\060\060\066\040\105\156\164\162\165\163\164
-\054\040\111\156\143\056\061\055\060\053\006\003\125\004\003\023
-\044\105\156\164\162\165\163\164\040\122\157\157\164\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150
-\157\162\151\164\171\060\036\027\015\060\066\061\061\062\067\062
-\060\062\063\064\062\132\027\015\062\066\061\061\062\067\062\060
-\065\063\064\062\132\060\201\260\061\013\060\011\006\003\125\004
-\006\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015
-\105\156\164\162\165\163\164\054\040\111\156\143\056\061\071\060
-\067\006\003\125\004\013\023\060\167\167\167\056\145\156\164\162
-\165\163\164\056\156\145\164\057\103\120\123\040\151\163\040\151
-\156\143\157\162\160\157\162\141\164\145\144\040\142\171\040\162
-\145\146\145\162\145\156\143\145\061\037\060\035\006\003\125\004
-\013\023\026\050\143\051\040\062\060\060\066\040\105\156\164\162
-\165\163\164\054\040\111\156\143\056\061\055\060\053\006\003\125
-\004\003\023\044\105\156\164\162\165\163\164\040\122\157\157\164
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\060\202\001\042\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000
-\060\202\001\012\002\202\001\001\000\266\225\266\103\102\372\306
-\155\052\157\110\337\224\114\071\127\005\356\303\171\021\101\150
-\066\355\354\376\232\001\217\241\070\050\374\367\020\106\146\056
-\115\036\032\261\032\116\306\321\300\225\210\260\311\377\061\213
-\063\003\333\267\203\173\076\040\204\136\355\262\126\050\247\370
-\340\271\100\161\067\305\313\107\016\227\052\150\300\042\225\142
-\025\333\107\331\365\320\053\377\202\113\311\255\076\336\114\333
-\220\200\120\077\011\212\204\000\354\060\012\075\030\315\373\375
-\052\131\232\043\225\027\054\105\236\037\156\103\171\155\014\134
-\230\376\110\247\305\043\107\134\136\375\156\347\036\264\366\150
-\105\321\206\203\133\242\212\215\261\343\051\200\376\045\161\210
-\255\276\274\217\254\122\226\113\252\121\215\344\023\061\031\350
-\116\115\237\333\254\263\152\325\274\071\124\161\312\172\172\177
-\220\335\175\035\200\331\201\273\131\046\302\021\376\346\223\342
-\367\200\344\145\373\064\067\016\051\200\160\115\257\070\206\056
-\236\177\127\257\236\027\256\353\034\313\050\041\137\266\034\330
-\347\242\004\042\371\323\332\330\313\002\003\001\000\001\243\201
-\260\060\201\255\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004\005
-\060\003\001\001\377\060\053\006\003\125\035\020\004\044\060\042
-\200\017\062\060\060\066\061\061\062\067\062\060\062\063\064\062
-\132\201\017\062\060\062\066\061\061\062\067\062\060\065\063\064
-\062\132\060\037\006\003\125\035\043\004\030\060\026\200\024\150
-\220\344\147\244\246\123\200\307\206\146\244\361\367\113\103\373
-\204\275\155\060\035\006\003\125\035\016\004\026\004\024\150\220
-\344\147\244\246\123\200\307\206\146\244\361\367\113\103\373\204
-\275\155\060\035\006\011\052\206\110\206\366\175\007\101\000\004
-\020\060\016\033\010\126\067\056\061\072\064\056\060\003\002\004
-\220\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\202\001\001\000\223\324\060\260\327\003\040\052\320\371\143
-\350\221\014\005\040\251\137\031\312\173\162\116\324\261\333\320
-\226\373\124\132\031\054\014\010\367\262\274\205\250\235\177\155
-\073\122\263\052\333\347\324\204\214\143\366\017\313\046\001\221
-\120\154\364\137\024\342\223\164\300\023\236\060\072\120\343\264
-\140\305\034\360\042\104\215\161\107\254\310\032\311\351\233\232
-\000\140\023\377\160\176\137\021\115\111\033\263\025\122\173\311
-\124\332\277\235\225\257\153\232\330\236\351\361\344\103\215\342
-\021\104\072\277\257\275\203\102\163\122\213\252\273\247\051\317
-\365\144\034\012\115\321\274\252\254\237\052\320\377\177\177\332
-\175\352\261\355\060\045\301\204\332\064\322\133\170\203\126\354
-\234\066\303\046\342\021\366\147\111\035\222\253\214\373\353\377
-\172\356\205\112\247\120\200\360\247\134\112\224\056\137\005\231
-\074\122\101\340\315\264\143\317\001\103\272\234\203\334\217\140
-\073\363\132\264\264\173\256\332\013\220\070\165\357\201\035\146
-\322\367\127\160\066\263\277\374\050\257\161\045\205\133\023\376
-\036\177\132\264\074
-END
-
-# Trust for Certificate "Entrust Root Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Entrust Root Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\263\036\261\267\100\343\154\204\002\332\334\067\324\115\365\324
-\147\111\122\371
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\326\245\303\355\135\335\076\000\301\075\207\222\037\035\077\344
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\260\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\105\156\164\162\165
-\163\164\054\040\111\156\143\056\061\071\060\067\006\003\125\004
-\013\023\060\167\167\167\056\145\156\164\162\165\163\164\056\156
-\145\164\057\103\120\123\040\151\163\040\151\156\143\157\162\160
-\157\162\141\164\145\144\040\142\171\040\162\145\146\145\162\145
-\156\143\145\061\037\060\035\006\003\125\004\013\023\026\050\143
-\051\040\062\060\060\066\040\105\156\164\162\165\163\164\054\040
-\111\156\143\056\061\055\060\053\006\003\125\004\003\023\044\105
-\156\164\162\165\163\164\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\105\153\120\124
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "RSA Security 2048 v3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "RSA Security 2048 v3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\072\061\031\060\027\006\003\125\004\012\023\020\122\123\101
-\040\123\145\143\165\162\151\164\171\040\111\156\143\061\035\060
-\033\006\003\125\004\013\023\024\122\123\101\040\123\145\143\165
-\162\151\164\171\040\062\060\064\070\040\126\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\072\061\031\060\027\006\003\125\004\012\023\020\122\123\101
-\040\123\145\143\165\162\151\164\171\040\111\156\143\061\035\060
-\033\006\003\125\004\013\023\024\122\123\101\040\123\145\143\165
-\162\151\164\171\040\062\060\064\070\040\126\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\012\001\001\001\000\000\002\174\000\000\000\012\000\000
-\000\002
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\141\060\202\002\111\240\003\002\001\002\002\020\012
-\001\001\001\000\000\002\174\000\000\000\012\000\000\000\002\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\072
-\061\031\060\027\006\003\125\004\012\023\020\122\123\101\040\123
-\145\143\165\162\151\164\171\040\111\156\143\061\035\060\033\006
-\003\125\004\013\023\024\122\123\101\040\123\145\143\165\162\151
-\164\171\040\062\060\064\070\040\126\063\060\036\027\015\060\061
-\060\062\062\062\062\060\063\071\062\063\132\027\015\062\066\060
-\062\062\062\062\060\063\071\062\063\132\060\072\061\031\060\027
-\006\003\125\004\012\023\020\122\123\101\040\123\145\143\165\162
-\151\164\171\040\111\156\143\061\035\060\033\006\003\125\004\013
-\023\024\122\123\101\040\123\145\143\165\162\151\164\171\040\062
-\060\064\070\040\126\063\060\202\001\042\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202
-\001\012\002\202\001\001\000\267\217\125\161\322\200\335\173\151
-\171\247\360\030\120\062\074\142\147\366\012\225\007\335\346\033
-\363\236\331\322\101\124\153\255\237\174\276\031\315\373\106\253
-\101\150\036\030\352\125\310\057\221\170\211\050\373\047\051\140
-\377\337\217\214\073\311\111\233\265\244\224\316\001\352\076\265
-\143\173\177\046\375\031\335\300\041\275\204\321\055\117\106\303
-\116\334\330\067\071\073\050\257\313\235\032\352\053\257\041\245
-\301\043\042\270\270\033\132\023\207\127\203\321\360\040\347\350
-\117\043\102\260\000\245\175\211\351\351\141\163\224\230\161\046
-\274\055\152\340\367\115\360\361\266\052\070\061\201\015\051\341
-\000\301\121\017\114\122\370\004\132\252\175\162\323\270\207\052
-\273\143\020\003\052\263\241\117\015\132\136\106\267\075\016\365
-\164\354\231\237\371\075\044\201\210\246\335\140\124\350\225\066
-\075\306\011\223\232\243\022\200\000\125\231\031\107\275\320\245
-\174\303\272\373\037\367\365\017\370\254\271\265\364\067\230\023
-\030\336\205\133\267\014\202\073\207\157\225\071\130\060\332\156
-\001\150\027\042\314\300\013\002\003\001\000\001\243\143\060\141
-\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001
-\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001
-\006\060\037\006\003\125\035\043\004\030\060\026\200\024\007\303
-\121\060\244\252\351\105\256\065\044\372\377\044\054\063\320\261
-\235\214\060\035\006\003\125\035\016\004\026\004\024\007\303\121
-\060\244\252\351\105\256\065\044\372\377\044\054\063\320\261\235
-\214\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\202\001\001\000\137\076\206\166\156\270\065\074\116\066\034
-\036\171\230\277\375\325\022\021\171\122\016\356\061\211\274\335
-\177\371\321\306\025\041\350\212\001\124\015\072\373\124\271\326
-\143\324\261\252\226\115\242\102\115\324\123\037\213\020\336\177
-\145\276\140\023\047\161\210\244\163\343\204\143\321\244\125\341
-\120\223\346\033\016\171\320\147\274\106\310\277\077\027\015\225
-\346\306\220\151\336\347\264\057\336\225\175\320\022\077\075\076
-\177\115\077\024\150\365\021\120\325\301\364\220\245\010\035\061
-\140\377\140\214\043\124\012\257\376\241\156\305\321\172\052\150
-\170\317\036\202\012\040\264\037\255\345\205\262\152\150\165\116
-\255\045\067\224\205\276\275\241\324\352\267\014\113\074\235\350
-\022\000\360\137\254\015\341\254\160\143\163\367\177\171\237\062
-\045\102\164\005\200\050\277\275\301\044\226\130\025\261\027\041
-\351\211\113\333\007\210\147\364\025\255\160\076\057\115\205\073
-\302\267\333\376\230\150\043\211\341\164\017\336\364\305\204\143
-\051\033\314\313\007\311\000\244\251\327\302\042\117\147\327\167
-\354\040\005\141\336
-END
-
-# Trust for Certificate "RSA Security 2048 v3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "RSA Security 2048 v3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\045\001\220\031\317\373\331\231\034\267\150\045\164\215\224\137
-\060\223\225\102
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\167\015\031\261\041\375\000\102\234\076\014\245\335\013\002\216
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\072\061\031\060\027\006\003\125\004\012\023\020\122\123\101
-\040\123\145\143\165\162\151\164\171\040\111\156\143\061\035\060
-\033\006\003\125\004\013\023\024\122\123\101\040\123\145\143\165
-\162\151\164\171\040\062\060\064\070\040\126\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\012\001\001\001\000\000\002\174\000\000\000\012\000\000
-\000\002
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GeoTrust Global CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Global CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\102\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\033\060\031\006\003\125\004\003
-\023\022\107\145\157\124\162\165\163\164\040\107\154\157\142\141
-\154\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\102\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\033\060\031\006\003\125\004\003
-\023\022\107\145\157\124\162\165\163\164\040\107\154\157\142\141
-\154\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\003\002\064\126
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\124\060\202\002\074\240\003\002\001\002\002\003\002
-\064\126\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\060\102\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162
-\165\163\164\040\111\156\143\056\061\033\060\031\006\003\125\004
-\003\023\022\107\145\157\124\162\165\163\164\040\107\154\157\142
-\141\154\040\103\101\060\036\027\015\060\062\060\065\062\061\060
-\064\060\060\060\060\132\027\015\062\062\060\065\062\061\060\064
-\060\060\060\060\132\060\102\061\013\060\011\006\003\125\004\006
-\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015\107
-\145\157\124\162\165\163\164\040\111\156\143\056\061\033\060\031
-\006\003\125\004\003\023\022\107\145\157\124\162\165\163\164\040
-\107\154\157\142\141\154\040\103\101\060\202\001\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017
-\000\060\202\001\012\002\202\001\001\000\332\314\030\143\060\375
-\364\027\043\032\126\176\133\337\074\154\070\344\161\267\170\221
-\324\274\241\330\114\370\250\103\266\003\351\115\041\007\010\210
-\332\130\057\146\071\051\275\005\170\213\235\070\350\005\267\152
-\176\161\244\346\304\140\246\260\357\200\344\211\050\017\236\045
-\326\355\203\363\255\246\221\307\230\311\102\030\065\024\235\255
-\230\106\222\056\117\312\361\207\103\301\026\225\127\055\120\357
-\211\055\200\172\127\255\362\356\137\153\322\000\215\271\024\370
-\024\025\065\331\300\106\243\173\162\310\221\277\311\125\053\315
-\320\227\076\234\046\144\314\337\316\203\031\161\312\116\346\324
-\325\173\251\031\315\125\336\310\354\322\136\070\123\345\134\117
-\214\055\376\120\043\066\374\146\346\313\216\244\071\031\000\267
-\225\002\071\221\013\016\376\070\056\321\035\005\232\366\115\076
-\157\017\007\035\257\054\036\217\140\071\342\372\066\123\023\071
-\324\136\046\053\333\075\250\024\275\062\353\030\003\050\122\004
-\161\345\253\063\075\341\070\273\007\066\204\142\234\171\352\026
-\060\364\137\300\053\350\161\153\344\371\002\003\001\000\001\243
-\123\060\121\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\300
-\172\230\150\215\211\373\253\005\144\014\021\175\252\175\145\270
-\312\314\116\060\037\006\003\125\035\043\004\030\060\026\200\024
-\300\172\230\150\215\211\373\253\005\144\014\021\175\252\175\145
-\270\312\314\116\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\003\202\001\001\000\065\343\051\152\345\057\135\124
-\216\051\120\224\237\231\032\024\344\217\170\052\142\224\242\047
-\147\236\320\317\032\136\107\351\301\262\244\317\335\101\032\005
-\116\233\113\356\112\157\125\122\263\044\241\067\012\353\144\166
-\052\056\054\363\375\073\165\220\277\372\161\330\307\075\067\322
-\265\005\225\142\271\246\336\211\075\066\173\070\167\110\227\254
-\246\040\217\056\246\311\014\302\262\231\105\000\307\316\021\121
-\042\042\340\245\352\266\025\110\011\144\352\136\117\164\367\005
-\076\307\212\122\014\333\025\264\275\155\233\345\306\261\124\150
-\251\343\151\220\266\232\245\017\270\271\077\040\175\256\112\265
-\270\234\344\035\266\253\346\224\245\301\307\203\255\333\365\047
-\207\016\004\154\325\377\335\240\135\355\207\122\267\053\025\002
-\256\071\246\152\164\351\332\304\347\274\115\064\036\251\134\115
-\063\137\222\011\057\210\146\135\167\227\307\035\166\023\251\325
-\345\361\026\011\021\065\325\254\333\044\161\160\054\230\126\013
-\331\027\264\321\343\121\053\136\165\350\325\320\334\117\064\355
-\302\005\146\200\241\313\346\063
-END
-
-# Trust for Certificate "GeoTrust Global CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Global CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\336\050\364\244\377\345\271\057\243\305\003\321\243\111\247\371
-\226\052\202\022
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\367\165\253\051\373\121\116\267\167\136\377\005\074\231\216\365
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\102\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\033\060\031\006\003\125\004\003
-\023\022\107\145\157\124\162\165\163\164\040\107\154\157\142\141
-\154\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\003\002\064\126
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GeoTrust Global CA 2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Global CA 2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003
-\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141
-\154\040\103\101\040\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003
-\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141
-\154\040\103\101\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\146\060\202\002\116\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026
-\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163
-\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003\023
-\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141\154
-\040\103\101\040\062\060\036\027\015\060\064\060\063\060\064\060
-\065\060\060\060\060\132\027\015\061\071\060\063\060\064\060\065
-\060\060\060\060\132\060\104\061\013\060\011\006\003\125\004\006
-\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015\107
-\145\157\124\162\165\163\164\040\111\156\143\056\061\035\060\033
-\006\003\125\004\003\023\024\107\145\157\124\162\165\163\164\040
-\107\154\157\142\141\154\040\103\101\040\062\060\202\001\042\060
-\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202
-\001\017\000\060\202\001\012\002\202\001\001\000\357\074\115\100
-\075\020\337\073\123\000\341\147\376\224\140\025\076\205\210\361
-\211\015\220\310\050\043\231\005\350\053\040\235\306\363\140\106
-\330\301\262\325\214\061\331\334\040\171\044\201\277\065\062\374
-\143\151\333\261\052\153\356\041\130\362\010\351\170\313\157\313
-\374\026\122\310\221\304\377\075\163\336\261\076\247\302\175\146
-\301\365\176\122\044\032\342\325\147\221\320\202\020\327\170\113
-\117\053\102\071\275\144\055\100\240\260\020\323\070\110\106\210
-\241\014\273\072\063\052\142\230\373\000\235\023\131\177\157\073
-\162\252\356\246\017\206\371\005\141\352\147\177\014\067\226\213
-\346\151\026\107\021\302\047\131\003\263\246\140\302\041\100\126
-\372\240\307\175\072\023\343\354\127\307\263\326\256\235\211\200
-\367\001\347\054\366\226\053\023\015\171\054\331\300\344\206\173
-\113\214\014\162\202\212\373\027\315\000\154\072\023\074\260\204
-\207\113\026\172\051\262\117\333\035\324\013\363\146\067\275\330
-\366\127\273\136\044\172\270\074\213\271\372\222\032\032\204\236
-\330\164\217\252\033\177\136\364\376\105\042\041\002\003\001\000
-\001\243\143\060\141\060\017\006\003\125\035\023\001\001\377\004
-\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004
-\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251\020
-\025\130\040\005\011\060\037\006\003\125\035\043\004\030\060\026
-\200\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251
-\020\025\130\040\005\011\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\206\060\015\006\011\052\206\110\206\367\015
-\001\001\005\005\000\003\202\001\001\000\003\367\265\053\253\135
-\020\374\173\262\262\136\254\233\016\176\123\170\131\076\102\004
-\376\165\243\255\254\201\116\327\002\213\136\304\055\310\122\166
-\307\054\037\374\201\062\230\321\113\306\222\223\063\065\061\057
-\374\330\035\104\335\340\201\177\235\351\213\341\144\221\142\013
-\071\010\214\254\164\235\131\331\172\131\122\227\021\271\026\173
-\157\105\323\226\331\061\175\002\066\017\234\073\156\317\054\015
-\003\106\105\353\240\364\177\110\104\306\010\100\314\336\033\160
-\265\051\255\272\213\073\064\145\165\033\161\041\035\054\024\012
-\260\226\225\270\326\352\362\145\373\051\272\117\352\221\223\164
-\151\266\362\377\341\032\320\014\321\166\205\313\212\045\275\227
-\136\054\157\025\231\046\347\266\051\377\042\354\311\002\307\126
-\000\315\111\271\263\154\173\123\004\032\342\250\311\252\022\005
-\043\302\316\347\273\004\002\314\300\107\242\344\304\051\057\133
-\105\127\211\121\356\074\353\122\010\377\007\065\036\237\065\152
-\107\112\126\230\321\132\205\037\214\365\042\277\253\316\203\363
-\342\042\051\256\175\203\100\250\272\154
-END
-
-# Trust for Certificate "GeoTrust Global CA 2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Global CA 2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\251\351\170\010\024\067\130\210\362\005\031\260\155\053\015\053
-\140\026\220\175
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\016\100\247\154\336\003\135\217\321\017\344\321\215\371\154\251
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003
-\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141
-\154\040\103\101\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GeoTrust Universal CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Universal CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003
-\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145
-\162\163\141\154\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003
-\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145
-\162\163\141\154\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\150\060\202\003\120\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026
-\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163
-\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003\023
-\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162
-\163\141\154\040\103\101\060\036\027\015\060\064\060\063\060\064
-\060\065\060\060\060\060\132\027\015\062\071\060\063\060\064\060
-\065\060\060\060\060\132\060\105\061\013\060\011\006\003\125\004
-\006\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015
-\107\145\157\124\162\165\163\164\040\111\156\143\056\061\036\060
-\034\006\003\125\004\003\023\025\107\145\157\124\162\165\163\164
-\040\125\156\151\166\145\162\163\141\154\040\103\101\060\202\002
-\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\202\002\017\000\060\202\002\012\002\202\002\001\000\246\025
-\125\240\243\306\340\037\214\235\041\120\327\301\276\053\133\265
-\244\236\241\331\162\130\275\000\033\114\277\141\311\024\035\105
-\202\253\306\035\200\326\075\353\020\234\072\257\155\044\370\274
-\161\001\236\006\365\174\137\036\301\016\125\312\203\232\131\060
-\256\031\313\060\110\225\355\042\067\215\364\112\232\162\146\076
-\255\225\300\340\026\000\340\020\037\053\061\016\327\224\124\323
-\102\063\240\064\035\036\105\166\335\117\312\030\067\354\205\025
-\172\031\010\374\325\307\234\360\362\251\056\020\251\222\346\075
-\130\075\251\026\150\074\057\165\041\030\177\050\167\245\341\141
-\027\267\246\351\370\036\231\333\163\156\364\012\242\041\154\356
-\332\252\205\222\146\257\366\172\153\202\332\272\042\010\065\017
-\317\102\361\065\372\152\356\176\053\045\314\072\021\344\155\257
-\163\262\166\035\255\320\262\170\147\032\244\071\034\121\013\147
-\126\203\375\070\135\015\316\335\360\273\053\226\037\336\173\062
-\122\375\035\273\265\006\241\262\041\136\245\326\225\150\177\360
-\231\236\334\105\010\076\347\322\011\015\065\224\335\200\116\123
-\227\327\265\011\104\040\144\026\027\003\002\114\123\015\150\336
-\325\252\162\115\223\155\202\016\333\234\275\317\264\363\134\135
-\124\172\151\011\226\326\333\021\301\215\165\250\264\317\071\310
-\316\074\274\044\174\346\142\312\341\275\175\247\275\127\145\013
-\344\376\045\355\266\151\020\334\050\032\106\275\001\035\320\227
-\265\341\230\073\300\067\144\326\075\224\356\013\341\365\050\256
-\013\126\277\161\213\043\051\101\216\206\305\113\122\173\330\161
-\253\037\212\025\246\073\203\132\327\130\001\121\306\114\101\331
-\177\330\101\147\162\242\050\337\140\203\251\236\310\173\374\123
-\163\162\131\365\223\172\027\166\016\316\367\345\134\331\013\125
-\064\242\252\133\265\152\124\347\023\312\127\354\227\155\364\136
-\006\057\105\213\130\324\043\026\222\344\026\156\050\143\131\060
-\337\120\001\234\143\211\032\237\333\027\224\202\160\067\303\044
-\236\232\107\326\132\312\116\250\151\211\162\037\221\154\333\176
-\236\033\255\307\037\163\335\054\117\031\145\375\177\223\100\020
-\056\322\360\355\074\236\056\050\076\151\046\063\305\173\002\003
-\001\000\001\243\143\060\141\060\017\006\003\125\035\023\001\001
-\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004
-\026\004\024\332\273\056\252\260\014\270\210\046\121\164\134\155
-\003\323\300\330\217\172\326\060\037\006\003\125\035\043\004\030
-\060\026\200\024\332\273\056\252\260\014\270\210\046\121\164\134
-\155\003\323\300\330\217\172\326\060\016\006\003\125\035\017\001
-\001\377\004\004\003\002\001\206\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\202\002\001\000\061\170\346\307
-\265\337\270\224\100\311\161\304\250\065\354\106\035\302\205\363
-\050\130\206\260\013\374\216\262\071\217\104\125\253\144\204\134
-\151\251\320\232\070\074\372\345\037\065\345\104\343\200\171\224
-\150\244\273\304\237\075\341\064\315\060\106\213\124\053\225\245
-\357\367\077\231\204\375\065\346\317\061\306\334\152\277\247\327
-\043\010\341\230\136\303\132\010\166\251\246\257\167\057\267\140
-\275\104\106\152\357\227\377\163\225\301\216\350\223\373\375\061
-\267\354\127\021\021\105\233\060\361\032\210\071\301\117\074\247
-\000\325\307\374\253\155\200\042\160\245\014\340\135\004\051\002
-\373\313\240\221\321\174\326\303\176\120\325\235\130\276\101\070
-\353\271\165\074\025\331\233\311\112\203\131\300\332\123\375\063
-\273\066\030\233\205\017\025\335\356\055\254\166\223\271\331\001
-\215\110\020\250\373\365\070\206\361\333\012\306\275\204\243\043
-\101\336\326\167\157\205\324\205\034\120\340\256\121\212\272\215
-\076\166\342\271\312\047\362\137\237\357\156\131\015\006\330\053
-\027\244\322\174\153\273\137\024\032\110\217\032\114\347\263\107
-\034\216\114\105\053\040\356\110\337\347\335\011\216\030\250\332
-\100\215\222\046\021\123\141\163\135\353\275\347\304\115\051\067
-\141\353\254\071\055\147\056\026\326\365\000\203\205\241\314\177
-\166\304\175\344\267\113\146\357\003\105\140\151\266\014\122\226
-\222\204\136\246\243\265\244\076\053\331\314\330\033\107\252\362
-\104\332\117\371\003\350\360\024\313\077\363\203\336\320\301\124
-\343\267\350\012\067\115\213\040\131\003\060\031\241\054\310\275
-\021\037\337\256\311\112\305\363\047\146\146\206\254\150\221\377
-\331\346\123\034\017\213\134\151\145\012\046\310\036\064\303\135
-\121\173\327\251\234\006\241\066\335\325\211\224\274\331\344\055
-\014\136\011\154\010\227\174\243\075\174\223\377\077\241\024\247
-\317\265\135\353\333\333\034\304\166\337\210\271\275\105\005\225
-\033\256\374\106\152\114\257\110\343\316\256\017\322\176\353\346
-\154\234\117\201\152\172\144\254\273\076\325\347\313\166\056\305
-\247\110\301\134\220\017\313\310\077\372\346\062\341\215\033\157
-\244\346\216\330\371\051\110\212\316\163\376\054
-END
-
-# Trust for Certificate "GeoTrust Universal CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Universal CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\346\041\363\065\103\171\005\232\113\150\060\235\212\057\164\042
-\025\207\354\171
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\222\145\130\213\242\032\061\162\163\150\134\264\245\172\007\110
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003
-\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145
-\162\163\141\154\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GeoTrust Universal CA 2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Universal CA 2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003
-\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145
-\162\163\141\154\040\103\101\040\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003
-\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145
-\162\163\141\154\040\103\101\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\154\060\202\003\124\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026
-\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163
-\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003\023
-\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162
-\163\141\154\040\103\101\040\062\060\036\027\015\060\064\060\063
-\060\064\060\065\060\060\060\060\132\027\015\062\071\060\063\060
-\064\060\065\060\060\060\060\132\060\107\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\026\060\024\006\003\125\004\012
-\023\015\107\145\157\124\162\165\163\164\040\111\156\143\056\061
-\040\060\036\006\003\125\004\003\023\027\107\145\157\124\162\165
-\163\164\040\125\156\151\166\145\162\163\141\154\040\103\101\040
-\062\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002
-\001\000\263\124\122\301\311\076\362\331\334\261\123\032\131\051
-\347\261\303\105\050\345\327\321\355\305\305\113\241\252\164\173
-\127\257\112\046\374\330\365\136\247\156\031\333\164\014\117\065
-\133\062\013\001\343\333\353\172\167\065\352\252\132\340\326\350
-\241\127\224\360\220\243\164\126\224\104\060\003\036\134\116\053
-\205\046\164\202\172\014\166\240\157\115\316\101\055\240\025\006
-\024\137\267\102\315\173\217\130\141\064\334\052\010\371\056\303
-\001\246\042\104\034\114\007\202\346\133\316\320\112\174\004\323
-\031\163\047\360\252\230\177\056\257\116\353\207\036\044\167\152
-\135\266\350\133\105\272\334\303\241\005\157\126\216\217\020\046
-\245\111\303\056\327\101\207\042\340\117\206\312\140\265\352\241
-\143\300\001\227\020\171\275\000\074\022\155\053\025\261\254\113
-\261\356\030\271\116\226\334\334\166\377\073\276\317\137\003\300
-\374\073\350\276\106\033\377\332\100\302\122\367\376\343\072\367
-\152\167\065\320\332\215\353\136\030\152\061\307\036\272\074\033
-\050\326\153\124\306\252\133\327\242\054\033\031\314\242\002\366
-\233\131\275\067\153\206\265\155\202\272\330\352\311\126\274\251
-\066\130\375\076\031\363\355\014\046\251\223\070\370\117\301\135
-\042\006\320\227\352\341\255\306\125\340\201\053\050\203\072\372
-\364\173\041\121\000\276\122\070\316\315\146\171\250\364\201\126
-\342\320\203\011\107\121\133\120\152\317\333\110\032\135\076\367
-\313\366\145\367\154\361\225\370\002\073\062\126\202\071\172\133
-\275\057\211\033\277\241\264\350\377\177\215\214\337\003\361\140
-\116\130\021\114\353\243\077\020\053\203\232\001\163\331\224\155
-\204\000\047\146\254\360\160\100\011\102\222\255\117\223\015\141
-\011\121\044\330\222\325\013\224\141\262\207\262\355\377\232\065
-\377\205\124\312\355\104\103\254\033\074\026\153\110\112\012\034
-\100\210\037\222\302\013\000\005\377\362\310\002\112\244\252\251
-\314\231\226\234\057\130\340\175\341\276\273\007\334\137\004\162
-\134\061\064\303\354\137\055\340\075\144\220\042\346\321\354\270
-\056\335\131\256\331\241\067\277\124\065\334\163\062\117\214\004
-\036\063\262\311\106\361\330\134\310\125\120\311\150\275\250\272
-\066\011\002\003\001\000\001\243\143\060\141\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\035\006\003
-\125\035\016\004\026\004\024\166\363\125\341\372\244\066\373\360
-\237\134\142\161\355\074\364\107\070\020\053\060\037\006\003\125
-\035\043\004\030\060\026\200\024\166\363\125\341\372\244\066\373
-\360\237\134\142\161\355\074\364\107\070\020\053\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\001\206\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001\000
-\146\301\306\043\363\331\340\056\156\137\350\317\256\260\260\045
-\115\053\370\073\130\233\100\044\067\132\313\253\026\111\377\263
-\165\171\063\241\057\155\160\027\064\221\376\147\176\217\354\233
-\345\136\202\251\125\037\057\334\324\121\007\022\376\254\026\076
-\054\065\306\143\374\334\020\353\015\243\252\320\174\314\321\320
-\057\121\056\304\024\132\336\350\031\341\076\306\314\244\051\347
-\056\204\252\006\060\170\166\124\163\050\230\131\070\340\000\015
-\142\323\102\175\041\237\256\075\072\214\325\372\167\015\030\053
-\026\016\137\066\341\374\052\265\060\044\317\340\143\014\173\130
-\032\376\231\272\102\022\261\221\364\174\150\342\310\350\257\054
-\352\311\176\256\273\052\075\015\025\334\064\225\266\030\164\250
-\152\017\307\264\364\023\304\344\133\355\012\322\244\227\114\052
-\355\057\154\022\211\075\361\047\160\252\152\003\122\041\237\100
-\250\147\120\362\363\132\037\337\337\043\366\334\170\116\346\230
-\117\125\072\123\343\357\362\364\237\307\174\330\130\257\051\042
-\227\270\340\275\221\056\260\166\354\127\021\317\357\051\104\363
-\351\205\172\140\143\344\135\063\211\027\331\061\252\332\326\363
-\030\065\162\317\207\053\057\143\043\204\135\204\214\077\127\240
-\210\374\231\221\050\046\151\231\324\217\227\104\276\216\325\110
-\261\244\050\051\361\025\264\341\345\236\335\370\217\246\157\046
-\327\011\074\072\034\021\016\246\154\067\367\255\104\207\054\050
-\307\330\164\202\263\320\157\112\127\273\065\051\047\240\213\350
-\041\247\207\144\066\135\314\330\026\254\307\262\047\100\222\125
-\070\050\215\121\156\335\024\147\123\154\161\134\046\204\115\165
-\132\266\176\140\126\251\115\255\373\233\036\227\363\015\331\322
-\227\124\167\332\075\022\267\340\036\357\010\006\254\371\205\207
-\351\242\334\257\176\030\022\203\375\126\027\101\056\325\051\202
-\175\231\364\061\366\161\251\317\054\001\047\245\005\271\252\262
-\110\116\052\357\237\223\122\121\225\074\122\163\216\126\114\027
-\100\300\011\050\344\213\152\110\123\333\354\315\125\125\361\306
-\370\351\242\054\114\246\321\046\137\176\257\132\114\332\037\246
-\362\034\054\176\256\002\026\322\126\320\057\127\123\107\350\222
-END
-
-# Trust for Certificate "GeoTrust Universal CA 2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Universal CA 2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\067\232\031\173\101\205\105\065\014\246\003\151\363\074\056\257
-\107\117\040\171
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\064\374\270\320\066\333\236\024\263\302\362\333\217\344\224\307
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003
-\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145
-\162\163\141\154\040\103\101\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "UTN-USER First-Network Applications"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN-USER First-Network Applications"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\243\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\053\060\051\006\003\125
-\004\003\023\042\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\116\145\164\167\157\162\153\040\101\160\160\154\151\143
-\141\164\151\157\156\163
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\243\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\053\060\051\006\003\125
-\004\003\023\042\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\116\145\164\167\157\162\153\040\101\160\160\154\151\143
-\141\164\151\157\156\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\060\113\300
-\063\167
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\144\060\202\003\114\240\003\002\001\002\002\020\104
-\276\014\213\120\000\044\264\021\323\066\060\113\300\063\167\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\243\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\053\060\051\006\003\125\004\003
-\023\042\125\124\116\055\125\123\105\122\106\151\162\163\164\055
-\116\145\164\167\157\162\153\040\101\160\160\154\151\143\141\164
-\151\157\156\163\060\036\027\015\071\071\060\067\060\071\061\070
-\064\070\063\071\132\027\015\061\071\060\067\060\071\061\070\065
-\067\064\071\132\060\201\243\061\013\060\011\006\003\125\004\006
-\023\002\125\123\061\013\060\011\006\003\125\004\010\023\002\125
-\124\061\027\060\025\006\003\125\004\007\023\016\123\141\154\164
-\040\114\141\153\145\040\103\151\164\171\061\036\060\034\006\003
-\125\004\012\023\025\124\150\145\040\125\123\105\122\124\122\125
-\123\124\040\116\145\164\167\157\162\153\061\041\060\037\006\003
-\125\004\013\023\030\150\164\164\160\072\057\057\167\167\167\056
-\165\163\145\162\164\162\165\163\164\056\143\157\155\061\053\060
-\051\006\003\125\004\003\023\042\125\124\116\055\125\123\105\122
-\106\151\162\163\164\055\116\145\164\167\157\162\153\040\101\160
-\160\154\151\143\141\164\151\157\156\163\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\263\373\221\241\344
-\066\125\205\254\006\064\133\240\232\130\262\370\265\017\005\167
-\203\256\062\261\166\222\150\354\043\112\311\166\077\343\234\266
-\067\171\003\271\253\151\215\007\045\266\031\147\344\260\033\030
-\163\141\112\350\176\315\323\057\144\343\246\174\014\372\027\200
-\243\015\107\211\117\121\161\057\356\374\077\371\270\026\200\207
-\211\223\045\040\232\103\202\151\044\166\050\131\065\241\035\300
-\177\203\006\144\026\040\054\323\111\244\205\264\300\141\177\121
-\010\370\150\025\221\200\313\245\325\356\073\072\364\204\004\136
-\140\131\247\214\064\162\356\270\170\305\321\073\022\112\157\176
-\145\047\271\244\125\305\271\157\103\244\305\035\054\231\300\122
-\244\170\114\025\263\100\230\010\153\103\306\001\260\172\173\365
-\153\034\042\077\313\357\377\250\320\072\113\166\025\236\322\321
-\306\056\343\333\127\033\062\242\270\157\350\206\246\077\160\253
-\345\160\222\253\104\036\100\120\373\234\243\142\344\154\156\240
-\310\336\342\200\102\372\351\057\350\316\062\004\217\174\215\267
-\034\243\065\074\025\335\236\303\256\227\245\002\003\001\000\001
-\243\201\221\060\201\216\060\013\006\003\125\035\017\004\004\003
-\002\001\306\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\372
-\206\311\333\340\272\351\170\365\113\250\326\025\337\360\323\341
-\152\024\074\060\117\006\003\125\035\037\004\110\060\106\060\104
-\240\102\240\100\206\076\150\164\164\160\072\057\057\143\162\154
-\056\165\163\145\162\164\162\165\163\164\056\143\157\155\057\125
-\124\116\055\125\123\105\122\106\151\162\163\164\055\116\145\164
-\167\157\162\153\101\160\160\154\151\143\141\164\151\157\156\163
-\056\143\162\154\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\003\202\001\001\000\244\363\045\314\321\324\221\203
-\042\320\314\062\253\233\226\116\064\221\124\040\045\064\141\137
-\052\002\025\341\213\252\377\175\144\121\317\012\377\274\175\330
-\041\152\170\313\057\121\157\370\102\035\063\275\353\265\173\224
-\303\303\251\240\055\337\321\051\037\035\376\217\077\273\250\105
-\052\177\321\156\125\044\342\273\002\373\061\077\276\350\274\354
-\100\053\370\001\324\126\070\344\312\104\202\265\141\040\041\147
-\145\366\360\013\347\064\370\245\302\234\243\134\100\037\205\223
-\225\006\336\117\324\047\251\266\245\374\026\315\163\061\077\270
-\145\047\317\324\123\032\360\254\156\237\117\005\014\003\201\247
-\204\051\304\132\275\144\127\162\255\073\317\067\030\246\230\306
-\255\006\264\334\010\243\004\325\051\244\226\232\022\147\112\214
-\140\105\235\361\043\232\260\000\234\150\265\230\120\323\357\216
-\056\222\145\261\110\076\041\276\025\060\052\015\265\014\243\153
-\077\256\177\127\365\037\226\174\337\157\335\202\060\054\145\033
-\100\112\315\150\271\162\354\161\166\354\124\216\037\205\014\001
-\152\372\246\070\254\037\304\204
-END
-
-# Trust for Certificate "UTN-USER First-Network Applications"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN-USER First-Network Applications"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\135\230\234\333\025\226\021\066\121\145\144\033\126\017\333\352
-\052\302\076\361
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\277\140\131\243\133\272\366\247\166\102\332\157\032\173\120\317
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\243\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\053\060\051\006\003\125
-\004\003\023\042\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\116\145\164\167\157\162\153\040\101\160\160\154\151\143
-\141\164\151\157\156\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\060\113\300
-\063\167
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "America Online Root Certification Authority 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "America Online Root Certification Authority 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\101\155\145\162\151\143
-\141\040\117\156\154\151\156\145\040\111\156\143\056\061\066\060
-\064\006\003\125\004\003\023\055\101\155\145\162\151\143\141\040
-\117\156\154\151\156\145\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\040\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\101\155\145\162\151\143
-\141\040\117\156\154\151\156\145\040\111\156\143\056\061\066\060
-\064\006\003\125\004\003\023\055\101\155\145\162\151\143\141\040
-\117\156\154\151\156\145\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\244\060\202\002\214\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061\034
-\060\032\006\003\125\004\012\023\023\101\155\145\162\151\143\141
-\040\117\156\154\151\156\145\040\111\156\143\056\061\066\060\064
-\006\003\125\004\003\023\055\101\155\145\162\151\143\141\040\117
-\156\154\151\156\145\040\122\157\157\164\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\061\060\036\027\015\060\062\060\065\062\070\060\066
-\060\060\060\060\132\027\015\063\067\061\061\061\071\062\060\064
-\063\060\060\132\060\143\061\013\060\011\006\003\125\004\006\023
-\002\125\123\061\034\060\032\006\003\125\004\012\023\023\101\155
-\145\162\151\143\141\040\117\156\154\151\156\145\040\111\156\143
-\056\061\066\060\064\006\003\125\004\003\023\055\101\155\145\162
-\151\143\141\040\117\156\154\151\156\145\040\122\157\157\164\040
-\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165
-\164\150\157\162\151\164\171\040\061\060\202\001\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017
-\000\060\202\001\012\002\202\001\001\000\250\057\350\244\151\006
-\003\107\303\351\052\230\377\031\242\160\232\306\120\262\176\245
-\337\150\115\033\174\017\266\227\150\175\055\246\213\227\351\144
-\206\311\243\357\240\206\277\140\145\234\113\124\210\302\110\305
-\112\071\277\024\343\131\125\345\031\264\164\310\264\005\071\134
-\026\245\342\225\005\340\022\256\131\213\242\063\150\130\034\246
-\324\025\267\330\237\327\334\161\253\176\232\277\233\216\063\017
-\042\375\037\056\347\007\066\357\142\071\305\335\313\272\045\024
-\043\336\014\306\075\074\316\202\010\346\146\076\332\121\073\026
-\072\243\005\177\240\334\207\325\234\374\162\251\240\175\170\344
-\267\061\125\036\145\273\324\141\260\041\140\355\020\062\162\305
-\222\045\036\370\220\112\030\170\107\337\176\060\067\076\120\033
-\333\034\323\153\232\206\123\007\260\357\254\006\170\370\204\231
-\376\041\215\114\200\266\014\202\366\146\160\171\032\323\117\243
-\317\361\317\106\260\113\017\076\335\210\142\270\214\251\011\050
-\073\172\307\227\341\036\345\364\237\300\300\256\044\240\310\241
-\331\017\326\173\046\202\151\062\075\247\002\003\001\000\001\243
-\143\060\141\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\000
-\255\331\243\366\171\366\156\164\251\177\063\075\201\027\327\114
-\317\063\336\060\037\006\003\125\035\043\004\030\060\026\200\024
-\000\255\331\243\366\171\366\156\164\251\177\063\075\201\027\327
-\114\317\063\336\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\206\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\003\202\001\001\000\174\212\321\037\030\067\202\340
-\270\260\243\355\126\225\310\142\141\234\005\242\315\302\142\046
-\141\315\020\026\327\314\264\145\064\320\021\212\255\250\251\005
-\146\357\164\363\155\137\235\231\257\366\213\373\353\122\262\005
-\230\242\157\052\305\124\275\045\275\137\256\310\206\352\106\054
-\301\263\275\301\351\111\160\030\026\227\010\023\214\040\340\033
-\056\072\107\313\036\344\000\060\225\133\364\105\243\300\032\260
-\001\116\253\275\300\043\156\143\077\200\112\305\007\355\334\342
-\157\307\301\142\361\343\162\326\004\310\164\147\013\372\210\253
-\241\001\310\157\360\024\257\322\231\315\121\223\176\355\056\070
-\307\275\316\106\120\075\162\343\171\045\235\233\210\053\020\040
-\335\245\270\062\237\215\340\051\337\041\164\206\202\333\057\202
-\060\306\307\065\206\263\371\226\137\106\333\014\105\375\363\120
-\303\157\306\303\110\255\106\246\341\047\107\012\035\016\233\266
-\302\167\177\143\362\340\175\032\276\374\340\337\327\307\247\154
-\260\371\256\272\074\375\164\264\021\350\130\015\200\274\323\250
-\200\072\231\355\165\314\106\173
-END
-
-# Trust for Certificate "America Online Root Certification Authority 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "America Online Root Certification Authority 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\071\041\301\025\301\135\016\312\134\313\133\304\360\175\041\330
-\005\013\126\152
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\024\361\010\255\235\372\144\342\211\347\034\317\250\255\175\136
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\101\155\145\162\151\143
-\141\040\117\156\154\151\156\145\040\111\156\143\056\061\066\060
-\064\006\003\125\004\003\023\055\101\155\145\162\151\143\141\040
-\117\156\154\151\156\145\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "America Online Root Certification Authority 2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "America Online Root Certification Authority 2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\101\155\145\162\151\143
-\141\040\117\156\154\151\156\145\040\111\156\143\056\061\066\060
-\064\006\003\125\004\003\023\055\101\155\145\162\151\143\141\040
-\117\156\154\151\156\145\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\040\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\101\155\145\162\151\143
-\141\040\117\156\154\151\156\145\040\111\156\143\056\061\066\060
-\064\006\003\125\004\003\023\055\101\155\145\162\151\143\141\040
-\117\156\154\151\156\145\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\244\060\202\003\214\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061\034
-\060\032\006\003\125\004\012\023\023\101\155\145\162\151\143\141
-\040\117\156\154\151\156\145\040\111\156\143\056\061\066\060\064
-\006\003\125\004\003\023\055\101\155\145\162\151\143\141\040\117
-\156\154\151\156\145\040\122\157\157\164\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\062\060\036\027\015\060\062\060\065\062\070\060\066
-\060\060\060\060\132\027\015\063\067\060\071\062\071\061\064\060
-\070\060\060\132\060\143\061\013\060\011\006\003\125\004\006\023
-\002\125\123\061\034\060\032\006\003\125\004\012\023\023\101\155
-\145\162\151\143\141\040\117\156\154\151\156\145\040\111\156\143
-\056\061\066\060\064\006\003\125\004\003\023\055\101\155\145\162
-\151\143\141\040\117\156\154\151\156\145\040\122\157\157\164\040
-\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165
-\164\150\157\162\151\164\171\040\062\060\202\002\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017
-\000\060\202\002\012\002\202\002\001\000\314\101\105\035\351\075
-\115\020\366\214\261\101\311\340\136\313\015\267\277\107\163\323
-\360\125\115\335\306\014\372\261\146\005\152\315\170\264\334\002
-\333\116\201\363\327\247\174\161\274\165\143\240\135\343\007\014
-\110\354\045\304\003\040\364\377\016\073\022\377\233\215\341\306
-\325\033\264\155\042\343\261\333\177\041\144\257\206\274\127\042
-\052\326\107\201\127\104\202\126\123\275\206\024\001\013\374\177
-\164\244\132\256\361\272\021\265\233\130\132\200\264\067\170\011
-\063\174\062\107\003\134\304\245\203\110\364\127\126\156\201\066
-\047\030\117\354\233\050\302\324\264\327\174\014\076\014\053\337
-\312\004\327\306\216\352\130\116\250\244\245\030\034\154\105\230
-\243\101\321\055\322\307\155\215\031\361\255\171\267\201\077\275
-\006\202\047\055\020\130\005\265\170\005\271\057\333\014\153\220
-\220\176\024\131\070\273\224\044\023\345\321\235\024\337\323\202
-\115\106\360\200\071\122\062\017\343\204\262\172\103\362\136\336
-\137\077\035\335\343\262\033\240\241\052\043\003\156\056\001\025
-\207\134\246\165\165\307\227\141\276\336\206\334\324\110\333\275
-\052\277\112\125\332\350\175\120\373\264\200\027\270\224\277\001
-\075\352\332\272\174\340\130\147\027\271\130\340\210\206\106\147
-\154\235\020\107\130\062\320\065\174\171\052\220\242\132\020\021
-\043\065\255\057\314\344\112\133\247\310\047\362\203\336\136\273
-\136\167\347\350\245\156\143\302\015\135\141\320\214\322\154\132
-\041\016\312\050\243\316\052\351\225\307\110\317\226\157\035\222
-\045\310\306\306\301\301\014\005\254\046\304\322\165\322\341\052
-\147\300\075\133\245\232\353\317\173\032\250\235\024\105\345\017
-\240\232\145\336\057\050\275\316\157\224\146\203\110\051\330\352
-\145\214\257\223\331\144\237\125\127\046\277\157\313\067\061\231
-\243\140\273\034\255\211\064\062\142\270\103\041\006\162\014\241
-\134\155\106\305\372\051\317\060\336\211\334\161\133\335\266\067
-\076\337\120\365\270\007\045\046\345\274\265\376\074\002\263\267
-\370\276\103\301\207\021\224\236\043\154\027\212\270\212\047\014
-\124\107\360\251\263\300\200\214\240\047\353\035\031\343\007\216
-\167\160\312\053\364\175\166\340\170\147\002\003\001\000\001\243
-\143\060\141\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\115
-\105\301\150\070\273\163\251\151\241\040\347\355\365\042\241\043
-\024\327\236\060\037\006\003\125\035\043\004\030\060\026\200\024
-\115\105\301\150\070\273\163\251\151\241\040\347\355\365\042\241
-\043\024\327\236\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\206\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\003\202\002\001\000\147\153\006\271\137\105\073\052
-\113\063\263\346\033\153\131\116\042\314\271\267\244\045\311\247
-\304\360\124\226\013\144\363\261\130\117\136\121\374\262\227\173
-\047\145\302\345\312\347\015\014\045\173\142\343\372\237\264\207
-\267\105\106\257\203\245\227\110\214\245\275\361\026\053\233\166
-\054\172\065\140\154\021\200\227\314\251\222\122\346\053\346\151
-\355\251\370\066\055\054\167\277\141\110\321\143\013\271\133\122
-\355\030\260\103\102\042\246\261\167\256\336\151\305\315\307\034
-\241\261\245\034\020\373\030\276\032\160\335\301\222\113\276\051
-\132\235\077\065\276\345\175\121\370\125\340\045\165\043\207\036
-\134\334\272\235\260\254\263\151\333\027\203\311\367\336\014\274
-\010\334\221\236\250\320\327\025\067\163\245\065\270\374\176\305
-\104\100\006\303\353\370\042\200\134\107\316\002\343\021\237\104
-\377\375\232\062\314\175\144\121\016\353\127\046\166\072\343\036
-\042\074\302\246\066\335\031\357\247\374\022\363\046\300\131\061
-\205\114\234\330\317\337\244\314\314\051\223\377\224\155\166\134
-\023\010\227\362\355\245\013\115\335\350\311\150\016\146\323\000
-\016\063\022\133\274\225\345\062\220\250\263\306\154\203\255\167
-\356\213\176\176\261\251\253\323\341\361\266\300\261\352\210\300
-\347\323\220\351\050\222\224\173\150\173\227\052\012\147\055\205
-\002\070\020\344\003\141\324\332\045\066\307\010\130\055\241\247
-\121\257\060\012\111\365\246\151\207\007\055\104\106\166\216\052
-\345\232\073\327\030\242\374\234\070\020\314\306\073\322\265\027
-\072\157\375\256\045\275\365\162\131\144\261\164\052\070\137\030
-\114\337\317\161\004\132\066\324\277\057\231\234\350\331\272\261
-\225\346\002\113\041\241\133\325\301\117\217\256\151\155\123\333
-\001\223\265\134\036\030\335\144\132\312\030\050\076\143\004\021
-\375\034\215\000\017\270\067\337\147\212\235\146\251\002\152\221
-\377\023\312\057\135\203\274\207\223\154\334\044\121\026\004\045
-\146\372\263\331\302\272\051\276\232\110\070\202\231\364\277\073
-\112\061\031\371\277\216\041\063\024\312\117\124\137\373\316\373
-\217\161\177\375\136\031\240\017\113\221\270\304\124\274\006\260
-\105\217\046\221\242\216\376\251
-END
-
-# Trust for Certificate "America Online Root Certification Authority 2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "America Online Root Certification Authority 2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\205\265\377\147\233\014\171\226\037\310\156\104\042\000\106\023
-\333\027\222\204
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\326\355\074\312\342\146\017\257\020\103\015\167\233\004\011\277
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\101\155\145\162\151\143
-\141\040\117\156\154\151\156\145\040\111\156\143\056\061\066\060
-\064\006\003\125\004\003\023\055\101\155\145\162\151\143\141\040
-\117\156\154\151\156\145\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Visa eCommerce Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Visa eCommerce Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\153\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\015\060\013\006\003\125\004\012\023\004\126\111\123\101\061\057
-\060\055\006\003\125\004\013\023\046\126\151\163\141\040\111\156
-\164\145\162\156\141\164\151\157\156\141\154\040\123\145\162\166
-\151\143\145\040\101\163\163\157\143\151\141\164\151\157\156\061
-\034\060\032\006\003\125\004\003\023\023\126\151\163\141\040\145
-\103\157\155\155\145\162\143\145\040\122\157\157\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\153\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\015\060\013\006\003\125\004\012\023\004\126\111\123\101\061\057
-\060\055\006\003\125\004\013\023\046\126\151\163\141\040\111\156
-\164\145\162\156\141\164\151\157\156\141\154\040\123\145\162\166
-\151\143\145\040\101\163\163\157\143\151\141\164\151\157\156\061
-\034\060\032\006\003\125\004\003\023\023\126\151\163\141\040\145
-\103\157\155\155\145\162\143\145\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\023\206\065\115\035\077\006\362\301\371\145\005\325\220
-\034\142
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\242\060\202\002\212\240\003\002\001\002\002\020\023
-\206\065\115\035\077\006\362\301\371\145\005\325\220\034\142\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\153
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\015\060
-\013\006\003\125\004\012\023\004\126\111\123\101\061\057\060\055
-\006\003\125\004\013\023\046\126\151\163\141\040\111\156\164\145
-\162\156\141\164\151\157\156\141\154\040\123\145\162\166\151\143
-\145\040\101\163\163\157\143\151\141\164\151\157\156\061\034\060
-\032\006\003\125\004\003\023\023\126\151\163\141\040\145\103\157
-\155\155\145\162\143\145\040\122\157\157\164\060\036\027\015\060
-\062\060\066\062\066\060\062\061\070\063\066\132\027\015\062\062
-\060\066\062\064\060\060\061\066\061\062\132\060\153\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\015\060\013\006\003
-\125\004\012\023\004\126\111\123\101\061\057\060\055\006\003\125
-\004\013\023\046\126\151\163\141\040\111\156\164\145\162\156\141
-\164\151\157\156\141\154\040\123\145\162\166\151\143\145\040\101
-\163\163\157\143\151\141\164\151\157\156\061\034\060\032\006\003
-\125\004\003\023\023\126\151\163\141\040\145\103\157\155\155\145
-\162\143\145\040\122\157\157\164\060\202\001\042\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000
-\060\202\001\012\002\202\001\001\000\257\127\336\126\036\156\241
-\332\140\261\224\047\313\027\333\007\077\200\205\117\310\234\266
-\320\364\157\117\317\231\330\341\333\302\110\134\072\254\071\063
-\307\037\152\213\046\075\053\065\365\110\261\221\301\002\116\004
-\226\221\173\260\063\360\261\024\116\021\157\265\100\257\033\105
-\245\112\357\176\266\254\362\240\037\130\077\022\106\140\074\215
-\241\340\175\317\127\076\063\036\373\107\361\252\025\227\007\125
-\146\245\265\055\056\330\200\131\262\247\015\267\106\354\041\143
-\377\065\253\245\002\317\052\364\114\376\173\365\224\135\204\115
-\250\362\140\217\333\016\045\074\237\163\161\317\224\337\112\352
-\333\337\162\070\214\363\226\275\361\027\274\322\272\073\105\132
-\306\247\366\306\027\213\001\235\374\031\250\052\203\026\270\072
-\110\376\116\076\240\253\006\031\351\123\363\200\023\007\355\055
-\277\077\012\074\125\040\071\054\054\000\151\164\225\112\274\040
-\262\251\171\345\030\211\221\250\334\034\115\357\273\176\067\013
-\135\376\071\245\210\122\214\000\154\354\030\174\101\275\366\213
-\165\167\272\140\235\204\347\376\055\002\003\001\000\001\243\102
-\060\100\060\017\006\003\125\035\023\001\001\377\004\005\060\003
-\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003
-\002\001\006\060\035\006\003\125\035\016\004\026\004\024\025\070
-\203\017\077\054\077\160\063\036\315\106\376\007\214\040\340\327
-\303\267\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\003\202\001\001\000\137\361\101\175\174\134\010\271\053\340
-\325\222\107\372\147\134\245\023\303\003\041\233\053\114\211\106
-\317\131\115\311\376\245\100\266\143\315\335\161\050\225\147\021
-\314\044\254\323\104\154\161\256\001\040\153\003\242\217\030\267
-\051\072\175\345\026\140\123\170\074\300\257\025\203\367\217\122
-\063\044\275\144\223\227\356\213\367\333\030\250\155\161\263\367
-\054\027\320\164\045\151\367\376\153\074\224\276\115\113\101\214
-\116\342\163\320\343\220\042\163\103\315\363\357\352\163\316\105
-\212\260\246\111\377\114\175\235\161\210\304\166\035\220\133\035
-\356\375\314\367\356\375\140\245\261\172\026\161\321\026\320\174
-\022\074\154\151\227\333\256\137\071\232\160\057\005\074\031\106
-\004\231\040\066\320\140\156\141\006\273\026\102\214\160\367\060
-\373\340\333\146\243\000\001\275\346\054\332\221\137\240\106\213
-\115\152\234\075\075\335\005\106\376\166\277\240\012\074\344\000
-\346\047\267\377\204\055\336\272\042\047\226\020\161\353\042\355
-\337\337\063\234\317\343\255\256\216\324\216\346\117\121\257\026
-\222\340\134\366\007\017
-END
-
-# Trust for Certificate "Visa eCommerce Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Visa eCommerce Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\160\027\233\206\214\000\244\372\140\221\122\042\077\237\076\062
-\275\340\005\142
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\374\021\270\330\010\223\060\000\155\043\371\176\353\122\036\002
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\153\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\015\060\013\006\003\125\004\012\023\004\126\111\123\101\061\057
-\060\055\006\003\125\004\013\023\046\126\151\163\141\040\111\156
-\164\145\162\156\141\164\151\157\156\141\154\040\123\145\162\166
-\151\143\145\040\101\163\163\157\143\151\141\164\151\157\156\061
-\034\060\032\006\003\125\004\003\023\023\126\151\163\141\040\145
-\103\157\155\155\145\162\143\145\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\023\206\065\115\035\077\006\362\301\371\145\005\325\220
-\034\142
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Certum Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certum Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\076\061\013\060\011\006\003\125\004\006\023\002\120\114\061
-\033\060\031\006\003\125\004\012\023\022\125\156\151\172\145\164
-\157\040\123\160\056\040\172\040\157\056\157\056\061\022\060\020
-\006\003\125\004\003\023\011\103\145\162\164\165\155\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\076\061\013\060\011\006\003\125\004\006\023\002\120\114\061
-\033\060\031\006\003\125\004\012\023\022\125\156\151\172\145\164
-\157\040\123\160\056\040\172\040\157\056\157\056\061\022\060\020
-\006\003\125\004\003\023\011\103\145\162\164\165\155\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\003\001\000\040
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\014\060\202\001\364\240\003\002\001\002\002\003\001
-\000\040\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\060\076\061\013\060\011\006\003\125\004\006\023\002\120\114
-\061\033\060\031\006\003\125\004\012\023\022\125\156\151\172\145
-\164\157\040\123\160\056\040\172\040\157\056\157\056\061\022\060
-\020\006\003\125\004\003\023\011\103\145\162\164\165\155\040\103
-\101\060\036\027\015\060\062\060\066\061\061\061\060\064\066\063
-\071\132\027\015\062\067\060\066\061\061\061\060\064\066\063\071
-\132\060\076\061\013\060\011\006\003\125\004\006\023\002\120\114
-\061\033\060\031\006\003\125\004\012\023\022\125\156\151\172\145
-\164\157\040\123\160\056\040\172\040\157\056\157\056\061\022\060
-\020\006\003\125\004\003\023\011\103\145\162\164\165\155\040\103
-\101\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001
-\001\000\316\261\301\056\323\117\174\315\045\316\030\076\117\304
-\214\157\200\152\163\310\133\121\370\233\322\334\273\000\134\261
-\240\374\165\003\356\201\360\210\356\043\122\351\346\025\063\215
-\254\055\011\305\166\371\053\071\200\211\344\227\113\220\245\250
-\170\370\163\103\173\244\141\260\330\130\314\341\154\146\176\234
-\363\011\136\125\143\204\325\250\357\363\261\056\060\150\263\304
-\074\330\254\156\215\231\132\220\116\064\334\066\232\217\201\210
-\120\267\155\226\102\011\363\327\225\203\015\101\113\260\152\153
-\370\374\017\176\142\237\147\304\355\046\137\020\046\017\010\117
-\360\244\127\050\316\217\270\355\105\366\156\356\045\135\252\156
-\071\276\344\223\057\331\107\240\162\353\372\246\133\257\312\123
-\077\342\016\306\226\126\021\156\367\351\146\251\046\330\177\225
-\123\355\012\205\210\272\117\051\245\102\214\136\266\374\205\040
-\000\252\150\013\241\032\205\001\234\304\106\143\202\210\266\042
-\261\356\376\252\106\131\176\317\065\054\325\266\332\135\367\110
-\063\024\124\266\353\331\157\316\315\210\326\253\033\332\226\073
-\035\131\002\003\001\000\001\243\023\060\021\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000
-\270\215\316\357\347\024\272\317\356\260\104\222\154\264\071\076
-\242\204\156\255\270\041\167\322\324\167\202\207\346\040\101\201
-\356\342\370\021\267\143\321\027\067\276\031\166\044\034\004\032
-\114\353\075\252\147\157\055\324\315\376\145\061\160\305\033\246
-\002\012\272\140\173\155\130\302\232\111\376\143\062\013\153\343
-\072\300\254\253\073\260\350\323\011\121\214\020\203\306\064\340
-\305\053\340\032\266\140\024\047\154\062\167\214\274\262\162\230
-\317\315\314\077\271\310\044\102\024\326\127\374\346\046\103\251
-\035\345\200\220\316\003\124\050\076\367\077\323\370\115\355\152
-\012\072\223\023\233\073\024\043\023\143\234\077\321\207\047\171
-\345\114\121\343\001\255\205\135\032\073\261\325\163\020\244\323
-\362\274\156\144\365\132\126\220\250\307\016\114\164\017\056\161
-\073\367\310\107\364\151\157\025\362\021\136\203\036\234\174\122
-\256\375\002\332\022\250\131\147\030\333\274\160\335\233\261\151
-\355\200\316\211\100\110\152\016\065\312\051\146\025\041\224\054
-\350\140\052\233\205\112\100\363\153\212\044\354\006\026\054\163
-END
-
-# Trust for Certificate "Certum Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certum Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\142\122\334\100\367\021\103\242\057\336\236\367\064\216\006\102
-\121\261\201\030
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\054\217\237\146\035\030\220\261\107\046\235\216\206\202\214\251
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\076\061\013\060\011\006\003\125\004\006\023\002\120\114\061
-\033\060\031\006\003\125\004\012\023\022\125\156\151\172\145\164
-\157\040\123\160\056\040\172\040\157\056\157\056\061\022\060\020
-\006\003\125\004\003\023\011\103\145\162\164\165\155\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\003\001\000\040
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Comodo AAA Services root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Comodo AAA Services root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\173\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\041\060\037\006\003
-\125\004\003\014\030\101\101\101\040\103\145\162\164\151\146\151
-\143\141\164\145\040\123\145\162\166\151\143\145\163
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\173\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\041\060\037\006\003
-\125\004\003\014\030\101\101\101\040\103\145\162\164\151\146\151
-\143\141\164\145\040\123\145\162\166\151\143\145\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\062\060\202\003\032\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\173\061\013\060\011\006\003\125\004\006\023\002\107\102\061\033
-\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145\162
-\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016\006
-\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032\060
-\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040\103
-\101\040\114\151\155\151\164\145\144\061\041\060\037\006\003\125
-\004\003\014\030\101\101\101\040\103\145\162\164\151\146\151\143
-\141\164\145\040\123\145\162\166\151\143\145\163\060\036\027\015
-\060\064\060\061\060\061\060\060\060\060\060\060\132\027\015\062
-\070\061\062\063\061\062\063\065\071\065\071\132\060\173\061\013
-\060\011\006\003\125\004\006\023\002\107\102\061\033\060\031\006
-\003\125\004\010\014\022\107\162\145\141\164\145\162\040\115\141
-\156\143\150\145\163\164\145\162\061\020\060\016\006\003\125\004
-\007\014\007\123\141\154\146\157\162\144\061\032\060\030\006\003
-\125\004\012\014\021\103\157\155\157\144\157\040\103\101\040\114
-\151\155\151\164\145\144\061\041\060\037\006\003\125\004\003\014
-\030\101\101\101\040\103\145\162\164\151\146\151\143\141\164\145
-\040\123\145\162\166\151\143\145\163\060\202\001\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017
-\000\060\202\001\012\002\202\001\001\000\276\100\235\364\156\341
-\352\166\207\034\115\105\104\216\276\106\310\203\006\235\301\052
-\376\030\037\216\344\002\372\363\253\135\120\212\026\061\013\232
-\006\320\305\160\042\315\111\055\124\143\314\266\156\150\106\013
-\123\352\313\114\044\300\274\162\116\352\361\025\256\364\124\232
-\022\012\303\172\262\063\140\342\332\211\125\363\042\130\363\336
-\334\317\357\203\206\242\214\224\117\237\150\362\230\220\106\204
-\047\307\166\277\343\314\065\054\213\136\007\144\145\202\300\110
-\260\250\221\371\141\237\166\040\120\250\221\307\146\265\353\170
-\142\003\126\360\212\032\023\352\061\243\036\240\231\375\070\366
-\366\047\062\130\157\007\365\153\270\373\024\053\257\267\252\314
-\326\143\137\163\214\332\005\231\250\070\250\313\027\170\066\121
-\254\351\236\364\170\072\215\317\017\331\102\342\230\014\253\057
-\237\016\001\336\357\237\231\111\361\055\337\254\164\115\033\230
-\265\107\305\345\051\321\371\220\030\307\142\234\276\203\307\046
-\173\076\212\045\307\300\335\235\346\065\150\020\040\235\217\330
-\336\322\303\204\234\015\136\350\057\311\002\003\001\000\001\243
-\201\300\060\201\275\060\035\006\003\125\035\016\004\026\004\024
-\240\021\012\043\076\226\361\007\354\342\257\051\357\202\245\177
-\320\060\244\264\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004\005
-\060\003\001\001\377\060\173\006\003\125\035\037\004\164\060\162
-\060\070\240\066\240\064\206\062\150\164\164\160\072\057\057\143
-\162\154\056\143\157\155\157\144\157\143\141\056\143\157\155\057
-\101\101\101\103\145\162\164\151\146\151\143\141\164\145\123\145
-\162\166\151\143\145\163\056\143\162\154\060\066\240\064\240\062
-\206\060\150\164\164\160\072\057\057\143\162\154\056\143\157\155
-\157\144\157\056\156\145\164\057\101\101\101\103\145\162\164\151
-\146\151\143\141\164\145\123\145\162\166\151\143\145\163\056\143
-\162\154\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\003\202\001\001\000\010\126\374\002\360\233\350\377\244\372
-\326\173\306\104\200\316\117\304\305\366\000\130\314\246\266\274
-\024\111\150\004\166\350\346\356\135\354\002\017\140\326\215\120
-\030\117\046\116\001\343\346\260\245\356\277\274\164\124\101\277
-\375\374\022\270\307\117\132\364\211\140\005\177\140\267\005\112
-\363\366\361\302\277\304\271\164\206\266\055\175\153\314\322\363
-\106\335\057\306\340\152\303\303\064\003\054\175\226\335\132\302
-\016\247\012\231\301\005\213\253\014\057\363\134\072\317\154\067
-\125\011\207\336\123\100\154\130\357\374\266\253\145\156\004\366
-\033\334\074\340\132\025\306\236\331\361\131\110\060\041\145\003
-\154\354\351\041\163\354\233\003\241\340\067\255\240\025\030\217
-\372\272\002\316\247\054\251\020\023\054\324\345\010\046\253\042
-\227\140\370\220\136\164\324\242\232\123\275\362\251\150\340\242
-\156\302\327\154\261\243\017\236\277\353\150\347\126\362\256\362
-\343\053\070\072\011\201\265\153\205\327\276\055\355\077\032\267
-\262\143\342\365\142\054\202\324\152\000\101\120\361\071\203\237
-\225\351\066\226\230\156
-END
-
-# Trust for Certificate "Comodo AAA Services root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Comodo AAA Services root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\321\353\043\244\155\027\326\217\331\045\144\302\361\361\140\027
-\144\330\343\111
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\111\171\004\260\353\207\031\254\107\260\274\021\121\233\164\320
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\173\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\041\060\037\006\003
-\125\004\003\014\030\101\101\101\040\103\145\162\164\151\146\151
-\143\141\164\145\040\123\145\162\166\151\143\145\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Comodo Secure Services root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Comodo Secure Services root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\176\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\044\060\042\006\003
-\125\004\003\014\033\123\145\143\165\162\145\040\103\145\162\164
-\151\146\151\143\141\164\145\040\123\145\162\166\151\143\145\163
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\176\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\044\060\042\006\003
-\125\004\003\014\033\123\145\143\165\162\145\040\103\145\162\164
-\151\146\151\143\141\164\145\040\123\145\162\166\151\143\145\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\077\060\202\003\047\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\176\061\013\060\011\006\003\125\004\006\023\002\107\102\061\033
-\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145\162
-\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016\006
-\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032\060
-\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040\103
-\101\040\114\151\155\151\164\145\144\061\044\060\042\006\003\125
-\004\003\014\033\123\145\143\165\162\145\040\103\145\162\164\151
-\146\151\143\141\164\145\040\123\145\162\166\151\143\145\163\060
-\036\027\015\060\064\060\061\060\061\060\060\060\060\060\060\132
-\027\015\062\070\061\062\063\061\062\063\065\071\065\071\132\060
-\176\061\013\060\011\006\003\125\004\006\023\002\107\102\061\033
-\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145\162
-\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016\006
-\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032\060
-\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040\103
-\101\040\114\151\155\151\164\145\144\061\044\060\042\006\003\125
-\004\003\014\033\123\145\143\165\162\145\040\103\145\162\164\151
-\146\151\143\141\164\145\040\123\145\162\166\151\143\145\163\060
-\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001
-\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000
-\300\161\063\202\212\320\160\353\163\207\202\100\325\035\344\313
-\311\016\102\220\371\336\064\271\241\272\021\364\045\205\363\314
-\162\155\362\173\227\153\263\007\361\167\044\221\137\045\217\366
-\164\075\344\200\302\370\074\015\363\277\100\352\367\310\122\321
-\162\157\357\310\253\101\270\156\056\027\052\225\151\014\315\322
-\036\224\173\055\224\035\252\165\327\263\230\313\254\274\144\123
-\100\274\217\254\254\066\313\134\255\273\335\340\224\027\354\321
-\134\320\277\357\245\225\311\220\305\260\254\373\033\103\337\172
-\010\135\267\270\362\100\033\053\047\236\120\316\136\145\202\210
-\214\136\323\116\014\172\352\010\221\266\066\252\053\102\373\352
-\302\243\071\345\333\046\070\255\213\012\356\031\143\307\034\044
-\337\003\170\332\346\352\301\107\032\013\013\106\011\335\002\374
-\336\313\207\137\327\060\143\150\241\256\334\062\241\272\276\376
-\104\253\150\266\245\027\025\375\275\325\247\247\232\344\104\063
-\351\210\216\374\355\121\353\223\161\116\255\001\347\104\216\253
-\055\313\250\376\001\111\110\360\300\335\307\150\330\222\376\075
-\002\003\001\000\001\243\201\307\060\201\304\060\035\006\003\125
-\035\016\004\026\004\024\074\330\223\210\302\300\202\011\314\001
-\231\006\223\040\351\236\160\011\143\117\060\016\006\003\125\035
-\017\001\001\377\004\004\003\002\001\006\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\201\201\006\003
-\125\035\037\004\172\060\170\060\073\240\071\240\067\206\065\150
-\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144\157
-\143\141\056\143\157\155\057\123\145\143\165\162\145\103\145\162
-\164\151\146\151\143\141\164\145\123\145\162\166\151\143\145\163
-\056\143\162\154\060\071\240\067\240\065\206\063\150\164\164\160
-\072\057\057\143\162\154\056\143\157\155\157\144\157\056\156\145
-\164\057\123\145\143\165\162\145\103\145\162\164\151\146\151\143
-\141\164\145\123\145\162\166\151\143\145\163\056\143\162\154\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202
-\001\001\000\207\001\155\043\035\176\133\027\175\301\141\062\317
-\217\347\363\212\224\131\146\340\236\050\250\136\323\267\364\064
-\346\252\071\262\227\026\305\202\157\062\244\351\214\347\257\375
-\357\302\350\271\113\252\243\364\346\332\215\145\041\373\272\200
-\353\046\050\205\032\376\071\214\336\133\004\004\264\124\371\243
-\147\236\101\372\011\122\314\005\110\250\311\077\041\004\036\316
-\110\153\374\205\350\302\173\257\177\267\314\370\137\072\375\065
-\306\015\357\227\334\114\253\021\341\153\313\061\321\154\373\110
-\200\253\334\234\067\270\041\024\113\015\161\075\354\203\063\156
-\321\156\062\026\354\230\307\026\213\131\246\064\253\005\127\055
-\223\367\252\023\313\322\023\342\267\056\073\315\153\120\027\011
-\150\076\265\046\127\356\266\340\266\335\271\051\200\171\175\217
-\243\360\244\050\244\025\304\205\364\047\324\153\277\345\134\344
-\145\002\166\124\264\343\067\146\044\323\031\141\310\122\020\345
-\213\067\232\271\251\371\035\277\352\231\222\141\226\377\001\315
-\241\137\015\274\161\274\016\254\013\035\107\105\035\301\354\174
-\354\375\051
-END
-
-# Trust for Certificate "Comodo Secure Services root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Comodo Secure Services root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\112\145\325\364\035\357\071\270\270\220\112\112\323\144\201\063
-\317\307\241\321
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\323\331\275\256\237\254\147\044\263\310\033\122\341\271\251\275
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\176\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\044\060\042\006\003
-\125\004\003\014\033\123\145\143\165\162\145\040\103\145\162\164
-\151\146\151\143\141\164\145\040\123\145\162\166\151\143\145\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Comodo Trusted Services root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Comodo Trusted Services root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\177\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\045\060\043\006\003
-\125\004\003\014\034\124\162\165\163\164\145\144\040\103\145\162
-\164\151\146\151\143\141\164\145\040\123\145\162\166\151\143\145
-\163
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\177\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\045\060\043\006\003
-\125\004\003\014\034\124\162\165\163\164\145\144\040\103\145\162
-\164\151\146\151\143\141\164\145\040\123\145\162\166\151\143\145
-\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\103\060\202\003\053\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\177\061\013\060\011\006\003\125\004\006\023\002\107\102\061\033
-\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145\162
-\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016\006
-\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032\060
-\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040\103
-\101\040\114\151\155\151\164\145\144\061\045\060\043\006\003\125
-\004\003\014\034\124\162\165\163\164\145\144\040\103\145\162\164
-\151\146\151\143\141\164\145\040\123\145\162\166\151\143\145\163
-\060\036\027\015\060\064\060\061\060\061\060\060\060\060\060\060
-\132\027\015\062\070\061\062\063\061\062\063\065\071\065\071\132
-\060\177\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\045\060\043\006\003
-\125\004\003\014\034\124\162\165\163\164\145\144\040\103\145\162
-\164\151\146\151\143\141\164\145\040\123\145\162\166\151\143\145
-\163\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001
-\001\000\337\161\157\066\130\123\132\362\066\124\127\200\304\164
-\010\040\355\030\177\052\035\346\065\232\036\045\254\234\345\226
-\176\162\122\240\025\102\333\131\335\144\172\032\320\270\173\335
-\071\025\274\125\110\304\355\072\000\352\061\021\272\362\161\164
-\032\147\270\317\063\314\250\061\257\243\343\327\177\277\063\055
-\114\152\074\354\213\303\222\322\123\167\044\164\234\007\156\160
-\374\275\013\133\166\272\137\362\377\327\067\113\112\140\170\367
-\360\372\312\160\264\352\131\252\243\316\110\057\251\303\262\013
-\176\027\162\026\014\246\007\014\033\070\317\311\142\267\077\240
-\223\245\207\101\362\267\160\100\167\330\276\024\174\343\250\300
-\172\216\351\143\152\321\017\232\306\322\364\213\072\024\004\126
-\324\355\270\314\156\365\373\342\054\130\275\177\117\153\053\367
-\140\044\130\044\316\046\357\064\221\072\325\343\201\320\262\360
-\004\002\327\133\267\076\222\254\153\022\212\371\344\005\260\073
-\221\111\134\262\353\123\352\370\237\107\206\356\277\225\300\300
-\006\237\322\133\136\021\033\364\307\004\065\051\322\125\134\344
-\355\353\002\003\001\000\001\243\201\311\060\201\306\060\035\006
-\003\125\035\016\004\026\004\024\305\173\130\275\355\332\045\151
-\322\367\131\026\250\263\062\300\173\047\133\364\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\001\006\060\017\006\003
-\125\035\023\001\001\377\004\005\060\003\001\001\377\060\201\203
-\006\003\125\035\037\004\174\060\172\060\074\240\072\240\070\206
-\066\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157
-\144\157\143\141\056\143\157\155\057\124\162\165\163\164\145\144
-\103\145\162\164\151\146\151\143\141\164\145\123\145\162\166\151
-\143\145\163\056\143\162\154\060\072\240\070\240\066\206\064\150
-\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144\157
-\056\156\145\164\057\124\162\165\163\164\145\144\103\145\162\164
-\151\146\151\143\141\164\145\123\145\162\166\151\143\145\163\056
-\143\162\154\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\003\202\001\001\000\310\223\201\073\211\264\257\270\204
-\022\114\215\322\360\333\160\272\127\206\025\064\020\271\057\177
-\036\260\250\211\140\241\212\302\167\014\120\112\233\000\213\330
-\213\364\101\342\320\203\212\112\034\024\006\260\243\150\005\160
-\061\060\247\123\233\016\351\112\240\130\151\147\016\256\235\366
-\245\054\101\277\074\006\153\344\131\314\155\020\361\226\157\037
-\337\364\004\002\244\237\105\076\310\330\372\066\106\104\120\077
-\202\227\221\037\050\333\030\021\214\052\344\145\203\127\022\022
-\214\027\077\224\066\376\135\260\300\004\167\023\270\364\025\325
-\077\070\314\224\072\125\320\254\230\365\272\000\137\340\206\031
-\201\170\057\050\300\176\323\314\102\012\365\256\120\240\321\076
-\306\241\161\354\077\240\040\214\146\072\211\264\216\324\330\261
-\115\045\107\356\057\210\310\265\341\005\105\300\276\024\161\336
-\172\375\216\173\175\115\010\226\245\022\163\360\055\312\067\047
-\164\022\047\114\313\266\227\351\331\256\010\155\132\071\100\335
-\005\107\165\152\132\041\263\243\030\317\116\367\056\127\267\230
-\160\136\310\304\170\260\142
-END
-
-# Trust for Certificate "Comodo Trusted Services root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Comodo Trusted Services root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\341\237\343\016\213\204\140\236\200\233\027\015\162\250\305\272
-\156\024\011\275
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\221\033\077\156\315\236\253\356\007\376\037\161\322\263\141\047
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\177\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\033\060\031\006\003\125\004\010\014\022\107\162\145\141\164\145
-\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016
-\006\003\125\004\007\014\007\123\141\154\146\157\162\144\061\032
-\060\030\006\003\125\004\012\014\021\103\157\155\157\144\157\040
-\103\101\040\114\151\155\151\164\145\144\061\045\060\043\006\003
-\125\004\003\014\034\124\162\165\163\164\145\144\040\103\145\162
-\164\151\146\151\143\141\164\145\040\123\145\162\166\151\143\145
-\163
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "QuoVadis Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "QuoVadis Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\177\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\045\060\043\006\003
-\125\004\013\023\034\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\061\056\060\054\006\003\125\004\003\023\045\121\165\157\126
-\141\144\151\163\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\177\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\045\060\043\006\003
-\125\004\013\023\034\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\061\056\060\054\006\003\125\004\003\023\045\121\165\157\126
-\141\144\151\163\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\072\266\120\213
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\320\060\202\004\270\240\003\002\001\002\002\004\072
-\266\120\213\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\177\061\013\060\011\006\003\125\004\006\023\002\102
-\115\061\031\060\027\006\003\125\004\012\023\020\121\165\157\126
-\141\144\151\163\040\114\151\155\151\164\145\144\061\045\060\043
-\006\003\125\004\013\023\034\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\061\056\060\054\006\003\125\004\003\023\045\121\165
-\157\126\141\144\151\163\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\060\036\027\015\060\061\060\063\061\071\061\070\063
-\063\063\063\132\027\015\062\061\060\063\061\067\061\070\063\063
-\063\063\132\060\177\061\013\060\011\006\003\125\004\006\023\002
-\102\115\061\031\060\027\006\003\125\004\012\023\020\121\165\157
-\126\141\144\151\163\040\114\151\155\151\164\145\144\061\045\060
-\043\006\003\125\004\013\023\034\122\157\157\164\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\061\056\060\054\006\003\125\004\003\023\045\121
-\165\157\126\141\144\151\163\040\122\157\157\164\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\060\202\001\042\060\015\006\011\052\206\110\206
-\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012
-\002\202\001\001\000\277\141\265\225\123\272\127\374\372\362\147
-\013\072\032\337\021\200\144\225\264\321\274\315\172\317\366\051
-\226\056\044\124\100\044\070\367\032\205\334\130\114\313\244\047
-\102\227\320\237\203\212\303\344\006\003\133\000\245\121\036\160
-\004\164\342\301\324\072\253\327\255\073\007\030\005\216\375\203
-\254\352\146\331\030\033\150\212\365\127\032\230\272\365\355\166
-\075\174\331\336\224\152\073\113\027\301\325\217\275\145\070\072
-\225\320\075\125\066\116\337\171\127\061\052\036\330\131\145\111
-\130\040\230\176\253\137\176\237\351\326\115\354\203\164\251\307
-\154\330\356\051\112\205\052\006\024\371\124\346\323\332\145\007
-\213\143\067\022\327\320\354\303\173\040\101\104\243\355\313\240
-\027\341\161\145\316\035\146\061\367\166\001\031\310\175\003\130
-\266\225\111\035\246\022\046\350\306\014\166\340\343\146\313\352
-\135\246\046\356\345\314\137\275\147\247\001\047\016\242\312\124
-\305\261\172\225\035\161\036\112\051\212\003\334\152\105\301\244
-\031\136\157\066\315\303\242\260\267\376\134\070\342\122\274\370
-\104\103\346\220\273\002\003\001\000\001\243\202\002\122\060\202
-\002\116\060\075\006\010\053\006\001\005\005\007\001\001\004\061
-\060\057\060\055\006\010\053\006\001\005\005\007\060\001\206\041
-\150\164\164\160\163\072\057\057\157\143\163\160\056\161\165\157
-\166\141\144\151\163\157\146\146\163\150\157\162\145\056\143\157
-\155\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
-\001\377\060\202\001\032\006\003\125\035\040\004\202\001\021\060
-\202\001\015\060\202\001\011\006\011\053\006\001\004\001\276\130
-\000\001\060\201\373\060\201\324\006\010\053\006\001\005\005\007
-\002\002\060\201\307\032\201\304\122\145\154\151\141\156\143\145
-\040\157\156\040\164\150\145\040\121\165\157\126\141\144\151\163
-\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164
-\145\040\142\171\040\141\156\171\040\160\141\162\164\171\040\141
-\163\163\165\155\145\163\040\141\143\143\145\160\164\141\156\143
-\145\040\157\146\040\164\150\145\040\164\150\145\156\040\141\160
-\160\154\151\143\141\142\154\145\040\163\164\141\156\144\141\162
-\144\040\164\145\162\155\163\040\141\156\144\040\143\157\156\144
-\151\164\151\157\156\163\040\157\146\040\165\163\145\054\040\143
-\145\162\164\151\146\151\143\141\164\151\157\156\040\160\162\141
-\143\164\151\143\145\163\054\040\141\156\144\040\164\150\145\040
-\121\165\157\126\141\144\151\163\040\103\145\162\164\151\146\151
-\143\141\164\145\040\120\157\154\151\143\171\056\060\042\006\010
-\053\006\001\005\005\007\002\001\026\026\150\164\164\160\072\057
-\057\167\167\167\056\161\165\157\166\141\144\151\163\056\142\155
-\060\035\006\003\125\035\016\004\026\004\024\213\113\155\355\323
-\051\271\006\031\354\071\071\251\360\227\204\152\313\357\337\060
-\201\256\006\003\125\035\043\004\201\246\060\201\243\200\024\213
-\113\155\355\323\051\271\006\031\354\071\071\251\360\227\204\152
-\313\357\337\241\201\204\244\201\201\060\177\061\013\060\011\006
-\003\125\004\006\023\002\102\115\061\031\060\027\006\003\125\004
-\012\023\020\121\165\157\126\141\144\151\163\040\114\151\155\151
-\164\145\144\061\045\060\043\006\003\125\004\013\023\034\122\157
-\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171\061\056\060\054\006\003
-\125\004\003\023\045\121\165\157\126\141\144\151\163\040\122\157
-\157\164\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171\202\004\072\266\120\213
-\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\001\001\000\212\324\024\265\376\364\232\222\247\031\324\244
-\176\162\030\217\331\150\174\122\044\335\147\157\071\172\304\252
-\136\075\342\130\260\115\160\230\204\141\350\033\343\151\030\016
-\316\373\107\120\240\116\377\360\044\037\275\262\316\365\047\374
-\354\057\123\252\163\173\003\075\164\156\346\026\236\353\245\056
-\304\277\126\047\120\053\142\272\276\113\034\074\125\134\101\035
-\044\276\202\040\107\135\325\104\176\172\026\150\337\175\115\121
-\160\170\127\035\063\036\375\002\231\234\014\315\012\005\117\307
-\273\216\244\165\372\112\155\261\200\216\011\126\271\234\032\140
-\376\135\301\327\172\334\021\170\320\326\135\301\267\325\255\062
-\231\003\072\212\314\124\045\071\061\201\173\023\042\121\272\106
-\154\241\273\236\372\004\154\111\046\164\217\322\163\353\314\060
-\242\346\352\131\042\207\370\227\365\016\375\352\314\222\244\026
-\304\122\030\352\041\316\261\361\346\204\201\345\272\251\206\050
-\362\103\132\135\022\235\254\036\331\250\345\012\152\247\177\240
-\207\051\317\362\211\115\324\354\305\342\346\172\320\066\043\212
-\112\164\066\371
-END
-
-# Trust for Certificate "QuoVadis Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "QuoVadis Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\336\077\100\275\120\223\323\233\154\140\366\332\274\007\142\001
-\000\211\166\311
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\047\336\066\376\162\267\000\003\000\235\364\360\036\154\004\044
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\177\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\045\060\043\006\003
-\125\004\013\023\034\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\061\056\060\054\006\003\125\004\003\023\045\121\165\157\126
-\141\144\151\163\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\072\266\120\213
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "QuoVadis Root CA 2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "QuoVadis Root CA 2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\033\060\031\006\003
-\125\004\003\023\022\121\165\157\126\141\144\151\163\040\122\157
-\157\164\040\103\101\040\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\033\060\031\006\003
-\125\004\003\023\022\121\165\157\126\141\144\151\163\040\122\157
-\157\164\040\103\101\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\005\011
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\267\060\202\003\237\240\003\002\001\002\002\002\005
-\011\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\060\105\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\033\060\031\006\003
-\125\004\003\023\022\121\165\157\126\141\144\151\163\040\122\157
-\157\164\040\103\101\040\062\060\036\027\015\060\066\061\061\062
-\064\061\070\062\067\060\060\132\027\015\063\061\061\061\062\064
-\061\070\062\063\063\063\132\060\105\061\013\060\011\006\003\125
-\004\006\023\002\102\115\061\031\060\027\006\003\125\004\012\023
-\020\121\165\157\126\141\144\151\163\040\114\151\155\151\164\145
-\144\061\033\060\031\006\003\125\004\003\023\022\121\165\157\126
-\141\144\151\163\040\122\157\157\164\040\103\101\040\062\060\202
-\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
-\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000\232
-\030\312\113\224\015\000\055\257\003\051\212\360\017\201\310\256
-\114\031\205\035\010\237\253\051\104\205\363\057\201\255\062\036
-\220\106\277\243\206\046\032\036\376\176\034\030\072\134\234\140
-\027\052\072\164\203\063\060\175\141\124\021\313\355\253\340\346
-\322\242\176\365\153\157\030\267\012\013\055\375\351\076\357\012
-\306\263\020\351\334\302\106\027\370\135\375\244\332\377\236\111
-\132\234\346\063\346\044\226\367\077\272\133\053\034\172\065\302
-\326\147\376\253\146\120\213\155\050\140\053\357\327\140\303\307
-\223\274\215\066\221\363\177\370\333\021\023\304\234\167\166\301
-\256\267\002\152\201\172\251\105\203\342\005\346\271\126\301\224
-\067\217\110\161\143\042\354\027\145\007\225\212\113\337\217\306
-\132\012\345\260\343\137\136\153\021\253\014\371\205\353\104\351
-\370\004\163\362\351\376\134\230\214\365\163\257\153\264\176\315
-\324\134\002\053\114\071\341\262\225\225\055\102\207\327\325\263
-\220\103\267\154\023\361\336\335\366\304\370\211\077\321\165\365
-\222\303\221\325\212\210\320\220\354\334\155\336\211\302\145\161
-\226\213\015\003\375\234\277\133\026\254\222\333\352\376\171\174
-\255\353\257\367\026\313\333\315\045\053\345\037\373\232\237\342
-\121\314\072\123\014\110\346\016\275\311\264\166\006\122\346\021
-\023\205\162\143\003\004\340\004\066\053\040\031\002\350\164\247
-\037\266\311\126\146\360\165\045\334\147\301\016\141\140\210\263
-\076\321\250\374\243\332\035\260\321\261\043\124\337\104\166\155
-\355\101\330\301\262\042\266\123\034\337\065\035\334\241\167\052
-\061\344\055\365\345\345\333\310\340\377\345\200\327\013\143\240
-\377\063\241\017\272\054\025\025\352\227\263\322\242\265\276\362
-\214\226\036\032\217\035\154\244\141\067\271\206\163\063\327\227
-\226\236\043\175\202\244\114\201\342\241\321\272\147\137\225\007
-\243\047\021\356\026\020\173\274\105\112\114\262\004\322\253\357
-\325\375\014\121\316\120\152\010\061\371\221\332\014\217\144\134
-\003\303\072\213\040\077\156\215\147\075\072\326\376\175\133\210
-\311\136\373\314\141\334\213\063\167\323\104\062\065\011\142\004
-\222\026\020\330\236\047\107\373\073\041\343\370\353\035\133\002
-\003\001\000\001\243\201\260\060\201\255\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\013\006\003\125
-\035\017\004\004\003\002\001\006\060\035\006\003\125\035\016\004
-\026\004\024\032\204\142\274\110\114\063\045\004\324\356\320\366
-\003\304\031\106\321\224\153\060\156\006\003\125\035\043\004\147
-\060\145\200\024\032\204\142\274\110\114\063\045\004\324\356\320
-\366\003\304\031\106\321\224\153\241\111\244\107\060\105\061\013
-\060\011\006\003\125\004\006\023\002\102\115\061\031\060\027\006
-\003\125\004\012\023\020\121\165\157\126\141\144\151\163\040\114
-\151\155\151\164\145\144\061\033\060\031\006\003\125\004\003\023
-\022\121\165\157\126\141\144\151\163\040\122\157\157\164\040\103
-\101\040\062\202\002\005\011\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\003\202\002\001\000\076\012\026\115\237
-\006\133\250\256\161\135\057\005\057\147\346\023\105\203\304\066
-\366\363\300\046\014\015\265\107\144\135\370\264\162\311\106\245
-\003\030\047\125\211\170\175\166\352\226\064\200\027\040\334\347
-\203\370\215\374\007\270\332\137\115\056\147\262\204\375\331\104
-\374\167\120\201\346\174\264\311\015\013\162\123\370\166\007\007
-\101\107\226\014\373\340\202\046\223\125\214\376\042\037\140\145
-\174\137\347\046\263\367\062\220\230\120\324\067\161\125\366\222
-\041\170\367\225\171\372\370\055\046\207\146\126\060\167\246\067
-\170\063\122\020\130\256\077\141\216\362\152\261\357\030\176\112
-\131\143\312\215\242\126\325\247\057\274\126\037\317\071\301\342
-\373\012\250\025\054\175\115\172\143\306\154\227\104\074\322\157
-\303\112\027\012\370\220\322\127\242\031\121\245\055\227\101\332
-\007\117\251\120\332\220\215\224\106\341\076\360\224\375\020\000
-\070\365\073\350\100\341\264\156\126\032\040\314\157\130\215\355
-\056\105\217\326\351\223\077\347\261\054\337\072\326\042\214\334
-\204\273\042\157\320\370\344\306\071\351\004\210\074\303\272\353
-\125\172\155\200\231\044\365\154\001\373\370\227\260\224\133\353
-\375\322\157\361\167\150\015\065\144\043\254\270\125\241\003\321
-\115\102\031\334\370\165\131\126\243\371\250\111\171\370\257\016
-\271\021\240\174\267\152\355\064\320\266\046\142\070\032\207\014
-\370\350\375\056\323\220\177\007\221\052\035\326\176\134\205\203
-\231\260\070\010\077\351\136\371\065\007\344\311\142\156\127\177
-\247\120\225\367\272\310\233\346\216\242\001\305\326\146\277\171
-\141\363\074\034\341\271\202\134\135\240\303\351\330\110\275\031
-\242\021\024\031\156\262\206\033\150\076\110\067\032\210\267\135
-\226\136\234\307\357\047\142\010\342\221\031\134\322\361\041\335
-\272\027\102\202\227\161\201\123\061\251\237\366\175\142\277\162
-\341\243\223\035\314\212\046\132\011\070\320\316\327\015\200\026
-\264\170\245\072\207\114\215\212\245\325\106\227\362\054\020\271
-\274\124\042\300\001\120\151\103\236\364\262\357\155\370\354\332
-\361\343\261\357\337\221\217\124\052\013\045\301\046\031\304\122
-\020\005\145\325\202\020\352\302\061\315\056
-END
-
-# Trust for Certificate "QuoVadis Root CA 2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "QuoVadis Root CA 2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\312\072\373\317\022\100\066\113\104\262\026\040\210\200\110\071
-\031\223\174\367
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\136\071\173\335\370\272\354\202\351\254\142\272\014\124\000\053
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\033\060\031\006\003
-\125\004\003\023\022\121\165\157\126\141\144\151\163\040\122\157
-\157\164\040\103\101\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\005\011
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "QuoVadis Root CA 3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "QuoVadis Root CA 3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\033\060\031\006\003
-\125\004\003\023\022\121\165\157\126\141\144\151\163\040\122\157
-\157\164\040\103\101\040\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\033\060\031\006\003
-\125\004\003\023\022\121\165\157\126\141\144\151\163\040\122\157
-\157\164\040\103\101\040\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\005\306
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\006\235\060\202\004\205\240\003\002\001\002\002\002\005
-\306\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\060\105\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\033\060\031\006\003
-\125\004\003\023\022\121\165\157\126\141\144\151\163\040\122\157
-\157\164\040\103\101\040\063\060\036\027\015\060\066\061\061\062
-\064\061\071\061\061\062\063\132\027\015\063\061\061\061\062\064
-\061\071\060\066\064\064\132\060\105\061\013\060\011\006\003\125
-\004\006\023\002\102\115\061\031\060\027\006\003\125\004\012\023
-\020\121\165\157\126\141\144\151\163\040\114\151\155\151\164\145
-\144\061\033\060\031\006\003\125\004\003\023\022\121\165\157\126
-\141\144\151\163\040\122\157\157\164\040\103\101\040\063\060\202
-\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
-\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000\314
-\127\102\026\124\234\346\230\323\323\115\356\376\355\307\237\103
-\071\112\145\263\350\026\210\064\333\015\131\221\164\317\222\270
-\004\100\255\002\113\061\253\274\215\221\150\330\040\016\032\001
-\342\032\173\116\027\135\342\212\267\077\231\032\315\353\141\253
-\302\145\246\037\267\267\275\267\217\374\375\160\217\013\240\147
-\276\001\242\131\317\161\346\017\051\166\377\261\126\171\105\053
-\037\236\172\124\350\243\051\065\150\244\001\117\017\244\056\067
-\357\033\277\343\217\020\250\162\253\130\127\347\124\206\310\311
-\363\133\332\054\332\135\216\156\074\243\076\332\373\202\345\335
-\362\134\262\005\063\157\212\066\316\320\023\116\377\277\112\014
-\064\114\246\303\041\275\120\004\125\353\261\273\235\373\105\036
-\144\025\336\125\001\214\002\166\265\313\241\077\102\151\274\057
-\275\150\103\026\126\211\052\067\141\221\375\246\256\116\300\313
-\024\145\224\067\113\222\006\357\004\320\310\234\210\333\013\173
-\201\257\261\075\052\304\145\072\170\266\356\334\200\261\322\323
-\231\234\072\356\153\132\153\263\215\267\325\316\234\302\276\245
-\113\057\026\261\236\150\073\006\157\256\175\237\370\336\354\314
-\051\247\230\243\045\103\057\357\361\137\046\341\210\115\370\136
-\156\327\331\024\156\031\063\151\247\073\204\211\223\304\123\125
-\023\241\121\170\100\370\270\311\242\356\173\272\122\102\203\236
-\024\355\005\122\132\131\126\247\227\374\235\077\012\051\330\334
-\117\221\016\023\274\336\225\244\337\213\231\276\254\233\063\210
-\357\265\201\257\033\306\042\123\310\366\307\356\227\024\260\305
-\174\170\122\310\360\316\156\167\140\204\246\351\052\166\040\355
-\130\001\027\060\223\351\032\213\340\163\143\331\152\222\224\111
-\116\264\255\112\205\304\243\042\060\374\011\355\150\042\163\246
-\210\014\125\041\130\305\341\072\237\052\335\312\341\220\340\331
-\163\253\154\200\270\350\013\144\223\240\234\214\031\377\263\322
-\014\354\221\046\207\212\263\242\341\160\217\054\012\345\315\155
-\150\121\353\332\077\005\177\213\062\346\023\134\153\376\137\100
-\342\042\310\264\264\144\117\326\272\175\110\076\250\151\014\327
-\273\206\161\311\163\270\077\073\235\045\113\332\377\100\353\002
-\003\001\000\001\243\202\001\225\060\202\001\221\060\017\006\003
-\125\035\023\001\001\377\004\005\060\003\001\001\377\060\201\341
-\006\003\125\035\040\004\201\331\060\201\326\060\201\323\006\011
-\053\006\001\004\001\276\130\000\003\060\201\305\060\201\223\006
-\010\053\006\001\005\005\007\002\002\060\201\206\032\201\203\101
-\156\171\040\165\163\145\040\157\146\040\164\150\151\163\040\103
-\145\162\164\151\146\151\143\141\164\145\040\143\157\156\163\164
-\151\164\165\164\145\163\040\141\143\143\145\160\164\141\156\143
-\145\040\157\146\040\164\150\145\040\121\165\157\126\141\144\151
-\163\040\122\157\157\164\040\103\101\040\063\040\103\145\162\164
-\151\146\151\143\141\164\145\040\120\157\154\151\143\171\040\057
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\120
-\162\141\143\164\151\143\145\040\123\164\141\164\145\155\145\156
-\164\056\060\055\006\010\053\006\001\005\005\007\002\001\026\041
-\150\164\164\160\072\057\057\167\167\167\056\161\165\157\166\141
-\144\151\163\147\154\157\142\141\154\056\143\157\155\057\143\160
-\163\060\013\006\003\125\035\017\004\004\003\002\001\006\060\035
-\006\003\125\035\016\004\026\004\024\362\300\023\340\202\103\076
-\373\356\057\147\062\226\065\134\333\270\313\002\320\060\156\006
-\003\125\035\043\004\147\060\145\200\024\362\300\023\340\202\103
-\076\373\356\057\147\062\226\065\134\333\270\313\002\320\241\111
-\244\107\060\105\061\013\060\011\006\003\125\004\006\023\002\102
-\115\061\031\060\027\006\003\125\004\012\023\020\121\165\157\126
-\141\144\151\163\040\114\151\155\151\164\145\144\061\033\060\031
-\006\003\125\004\003\023\022\121\165\157\126\141\144\151\163\040
-\122\157\157\164\040\103\101\040\063\202\002\005\306\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001
-\000\117\255\240\054\114\372\300\362\157\367\146\125\253\043\064
-\356\347\051\332\303\133\266\260\203\331\320\320\342\041\373\363
-\140\247\073\135\140\123\047\242\233\366\010\042\052\347\277\240
-\162\345\234\044\152\061\261\220\172\047\333\204\021\211\047\246
-\167\132\070\327\277\254\206\374\356\135\203\274\006\306\321\167
-\153\017\155\044\057\113\172\154\247\007\226\312\343\204\237\255
-\210\213\035\253\026\215\133\146\027\331\026\364\213\200\322\335
-\370\262\166\303\374\070\023\252\014\336\102\151\053\156\363\074
-\353\200\047\333\365\246\104\015\237\132\125\131\013\325\015\122
-\110\305\256\237\362\057\200\305\352\062\120\065\022\227\056\301
-\341\377\361\043\210\121\070\237\362\146\126\166\347\017\121\227
-\245\122\014\115\111\121\225\066\075\277\242\113\014\020\035\206
-\231\114\252\363\162\021\223\344\352\366\233\332\250\135\247\115
-\267\236\002\256\163\000\310\332\043\003\350\371\352\031\164\142
-\000\224\313\042\040\276\224\247\131\265\202\152\276\231\171\172
-\251\362\112\044\122\367\164\375\272\116\346\250\035\002\156\261
-\015\200\104\301\256\323\043\067\137\273\205\174\053\222\056\350
-\176\245\213\335\231\341\277\047\157\055\135\252\173\207\376\012
-\335\113\374\216\365\046\344\156\160\102\156\063\354\061\236\173
-\223\301\344\311\151\032\075\300\153\116\042\155\356\253\130\115
-\306\320\101\301\053\352\117\022\207\136\353\105\330\154\365\230
-\002\323\240\330\125\212\006\231\031\242\240\167\321\060\236\254
-\314\165\356\203\365\260\142\071\317\154\127\342\114\322\221\013
-\016\165\050\033\232\277\375\032\103\361\312\167\373\073\217\141
-\270\151\050\026\102\004\136\160\052\034\041\330\217\341\275\043
-\133\055\164\100\222\331\143\031\015\163\335\151\274\142\107\274
-\340\164\053\262\353\175\276\101\033\265\300\106\305\241\042\313
-\137\116\301\050\222\336\030\272\325\052\050\273\021\213\027\223
-\230\231\140\224\134\043\317\132\047\227\136\013\005\006\223\067
-\036\073\151\066\353\251\236\141\035\217\062\332\216\014\326\164
-\076\173\011\044\332\001\167\107\304\073\315\064\214\231\365\312
-\341\045\141\063\262\131\033\342\156\327\067\127\266\015\251\022
-\332
-END
-
-# Trust for Certificate "QuoVadis Root CA 3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "QuoVadis Root CA 3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\037\111\024\367\330\164\225\035\335\256\002\300\276\375\072\055
-\202\165\121\205
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\061\205\074\142\224\227\143\271\252\375\211\116\257\157\340\317
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\102\115\061
-\031\060\027\006\003\125\004\012\023\020\121\165\157\126\141\144
-\151\163\040\114\151\155\151\164\145\144\061\033\060\031\006\003
-\125\004\003\023\022\121\165\157\126\141\144\151\163\040\122\157
-\157\164\040\103\101\040\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\005\306
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Security Communication Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Security Communication Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\120\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\030\060\026\006\003\125\004\012\023\017\123\105\103\117\115\040
-\124\162\165\163\164\056\156\145\164\061\047\060\045\006\003\125
-\004\013\023\036\123\145\143\165\162\151\164\171\040\103\157\155
-\155\165\156\151\143\141\164\151\157\156\040\122\157\157\164\103
-\101\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\120\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\030\060\026\006\003\125\004\012\023\017\123\105\103\117\115\040
-\124\162\165\163\164\056\156\145\164\061\047\060\045\006\003\125
-\004\013\023\036\123\145\143\165\162\151\164\171\040\103\157\155
-\155\165\156\151\143\141\164\151\157\156\040\122\157\157\164\103
-\101\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\132\060\202\002\102\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\120\061\013\060\011\006\003\125\004\006\023\002\112\120\061\030
-\060\026\006\003\125\004\012\023\017\123\105\103\117\115\040\124
-\162\165\163\164\056\156\145\164\061\047\060\045\006\003\125\004
-\013\023\036\123\145\143\165\162\151\164\171\040\103\157\155\155
-\165\156\151\143\141\164\151\157\156\040\122\157\157\164\103\101
-\061\060\036\027\015\060\063\060\071\063\060\060\064\062\060\064
-\071\132\027\015\062\063\060\071\063\060\060\064\062\060\064\071
-\132\060\120\061\013\060\011\006\003\125\004\006\023\002\112\120
-\061\030\060\026\006\003\125\004\012\023\017\123\105\103\117\115
-\040\124\162\165\163\164\056\156\145\164\061\047\060\045\006\003
-\125\004\013\023\036\123\145\143\165\162\151\164\171\040\103\157
-\155\155\165\156\151\143\141\164\151\157\156\040\122\157\157\164
-\103\101\061\060\202\001\042\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002
-\202\001\001\000\263\263\376\177\323\155\261\357\026\174\127\245
-\014\155\166\212\057\113\277\144\373\114\356\212\360\363\051\174
-\365\377\356\052\340\351\351\272\133\144\042\232\232\157\054\072
-\046\151\121\005\231\046\334\325\034\152\161\306\232\175\036\235
-\335\174\154\306\214\147\147\112\076\370\161\260\031\047\251\011
-\014\246\225\277\113\214\014\372\125\230\073\330\350\042\241\113
-\161\070\171\254\227\222\151\263\211\176\352\041\150\006\230\024
-\226\207\322\141\066\274\155\047\126\236\127\356\300\300\126\375
-\062\317\244\331\216\302\043\327\215\250\363\330\045\254\227\344
-\160\070\364\266\072\264\235\073\227\046\103\243\241\274\111\131
-\162\114\043\060\207\001\130\366\116\276\034\150\126\146\257\315
-\101\135\310\263\115\052\125\106\253\037\332\036\342\100\075\333
-\315\175\271\222\200\234\067\335\014\226\144\235\334\042\367\144
-\213\337\141\336\025\224\122\025\240\175\122\311\113\250\041\311
-\306\261\355\313\303\225\140\321\017\360\253\160\370\337\313\115
-\176\354\326\372\253\331\275\177\124\362\245\351\171\372\331\326
-\166\044\050\163\002\003\001\000\001\243\077\060\075\060\035\006
-\003\125\035\016\004\026\004\024\240\163\111\231\150\334\205\133
-\145\343\233\050\057\127\237\275\063\274\007\110\060\013\006\003
-\125\035\017\004\004\003\002\001\006\060\017\006\003\125\035\023
-\001\001\377\004\005\060\003\001\001\377\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\150\100
-\251\250\273\344\117\135\171\263\005\265\027\263\140\023\353\306
-\222\135\340\321\323\152\376\373\276\233\155\277\307\005\155\131
-\040\304\034\360\267\332\204\130\002\143\372\110\026\357\117\245
-\013\367\112\230\362\077\236\033\255\107\153\143\316\010\107\353
-\122\077\170\234\257\115\256\370\325\117\317\232\230\052\020\101
-\071\122\304\335\331\233\016\357\223\001\256\262\056\312\150\102
-\044\102\154\260\263\072\076\315\351\332\110\304\025\313\351\371
-\007\017\222\120\111\212\335\061\227\137\311\351\067\252\073\131
-\145\227\224\062\311\263\237\076\072\142\130\305\111\255\142\016
-\161\245\062\252\057\306\211\166\103\100\023\023\147\075\242\124
-\045\020\313\361\072\362\331\372\333\111\126\273\246\376\247\101
-\065\303\340\210\141\311\210\307\337\066\020\042\230\131\352\260
-\112\373\126\026\163\156\254\115\367\042\241\117\255\035\172\055
-\105\047\345\060\301\136\362\332\023\313\045\102\121\225\107\003
-\214\154\041\314\164\102\355\123\377\063\213\217\017\127\001\026
-\057\317\246\356\311\160\042\024\275\375\276\154\013\003
-END
-
-# Trust for Certificate "Security Communication Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Security Communication Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\066\261\053\111\371\201\236\327\114\236\274\070\017\306\126\217
-\135\254\262\367
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\361\274\143\152\124\340\265\047\365\315\347\032\343\115\156\112
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\120\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\030\060\026\006\003\125\004\012\023\017\123\105\103\117\115\040
-\124\162\165\163\164\056\156\145\164\061\047\060\045\006\003\125
-\004\013\023\036\123\145\143\165\162\151\164\171\040\103\157\155
-\155\165\156\151\143\141\164\151\157\156\040\122\157\157\164\103
-\101\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Sonera Class 1 Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Sonera Class 1 Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\071\061\013\060\011\006\003\125\004\006\023\002\106\111\061
-\017\060\015\006\003\125\004\012\023\006\123\157\156\145\162\141
-\061\031\060\027\006\003\125\004\003\023\020\123\157\156\145\162
-\141\040\103\154\141\163\163\061\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\071\061\013\060\011\006\003\125\004\006\023\002\106\111\061
-\017\060\015\006\003\125\004\012\023\006\123\157\156\145\162\141
-\061\031\060\027\006\003\125\004\003\023\020\123\157\156\145\162
-\141\040\103\154\141\163\163\061\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\044
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\040\060\202\002\010\240\003\002\001\002\002\001\044
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\071\061\013\060\011\006\003\125\004\006\023\002\106\111\061\017
-\060\015\006\003\125\004\012\023\006\123\157\156\145\162\141\061
-\031\060\027\006\003\125\004\003\023\020\123\157\156\145\162\141
-\040\103\154\141\163\163\061\040\103\101\060\036\027\015\060\061
-\060\064\060\066\061\060\064\071\061\063\132\027\015\062\061\060
-\064\060\066\061\060\064\071\061\063\132\060\071\061\013\060\011
-\006\003\125\004\006\023\002\106\111\061\017\060\015\006\003\125
-\004\012\023\006\123\157\156\145\162\141\061\031\060\027\006\003
-\125\004\003\023\020\123\157\156\145\162\141\040\103\154\141\163
-\163\061\040\103\101\060\202\001\042\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001
-\012\002\202\001\001\000\265\211\037\053\117\147\012\171\377\305
-\036\370\177\074\355\321\176\332\260\315\155\057\066\254\064\306
-\333\331\144\027\010\143\060\063\042\212\114\356\216\273\017\015
-\102\125\311\235\056\245\357\367\247\214\303\253\271\227\313\216
-\357\077\025\147\250\202\162\143\123\017\101\214\175\020\225\044
-\241\132\245\006\372\222\127\235\372\245\001\362\165\351\037\274
-\126\046\122\116\170\031\145\130\125\003\130\300\024\256\214\174
-\125\137\160\133\167\043\006\066\227\363\044\265\232\106\225\344
-\337\015\013\005\105\345\321\362\035\202\273\306\023\340\376\252
-\172\375\151\060\224\363\322\105\205\374\362\062\133\062\336\350
-\154\135\037\313\244\042\164\260\200\216\135\224\367\006\000\113
-\251\324\136\056\065\120\011\363\200\227\364\014\027\256\071\330
-\137\315\063\301\034\312\211\302\042\367\105\022\355\136\022\223
-\235\143\253\202\056\271\353\102\101\104\313\112\032\000\202\015
-\236\371\213\127\076\114\307\027\355\054\213\162\063\137\162\172
-\070\126\325\346\331\256\005\032\035\165\105\261\313\245\045\034
-\022\127\066\375\042\067\002\003\001\000\001\243\063\060\061\060
-\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377
-\060\021\006\003\125\035\016\004\012\004\010\107\342\014\213\366
-\123\210\122\060\013\006\003\125\035\017\004\004\003\002\001\006
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\001\001\000\213\032\262\311\135\141\264\341\271\053\271\123
-\321\262\205\235\167\216\026\356\021\075\333\302\143\331\133\227
-\145\373\022\147\330\052\134\266\253\345\136\303\267\026\057\310
-\350\253\035\212\375\253\032\174\325\137\143\317\334\260\335\167
-\271\250\346\322\042\070\207\007\024\331\377\276\126\265\375\007
-\016\074\125\312\026\314\247\246\167\067\373\333\134\037\116\131
-\006\207\243\003\103\365\026\253\267\204\275\116\357\237\061\067
-\360\106\361\100\266\321\014\245\144\370\143\136\041\333\125\116
-\117\061\166\234\020\141\216\266\123\072\243\021\276\257\155\174
-\036\275\256\055\342\014\151\307\205\123\150\242\141\272\305\076
-\264\171\124\170\236\012\307\002\276\142\321\021\202\113\145\057
-\221\132\302\250\207\261\126\150\224\171\371\045\367\301\325\256
-\032\270\273\075\217\251\212\070\025\367\163\320\132\140\321\200
-\260\360\334\325\120\315\116\356\222\110\151\355\262\043\036\060
-\314\310\224\310\266\365\073\206\177\077\246\056\237\366\076\054
-\265\222\226\076\337\054\223\212\377\201\214\017\017\131\041\031
-\127\275\125\232
-END
-
-# Trust for Certificate "Sonera Class 1 Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Sonera Class 1 Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\007\107\042\001\231\316\164\271\174\260\075\171\262\144\242\310
-\125\351\063\377
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\063\267\204\365\137\047\327\150\047\336\024\336\022\052\355\157
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\071\061\013\060\011\006\003\125\004\006\023\002\106\111\061
-\017\060\015\006\003\125\004\012\023\006\123\157\156\145\162\141
-\061\031\060\027\006\003\125\004\003\023\020\123\157\156\145\162
-\141\040\103\154\141\163\163\061\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\044
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Sonera Class 2 Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Sonera Class 2 Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\071\061\013\060\011\006\003\125\004\006\023\002\106\111\061
-\017\060\015\006\003\125\004\012\023\006\123\157\156\145\162\141
-\061\031\060\027\006\003\125\004\003\023\020\123\157\156\145\162
-\141\040\103\154\141\163\163\062\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\071\061\013\060\011\006\003\125\004\006\023\002\106\111\061
-\017\060\015\006\003\125\004\012\023\006\123\157\156\145\162\141
-\061\031\060\027\006\003\125\004\003\023\020\123\157\156\145\162
-\141\040\103\154\141\163\163\062\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\035
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\040\060\202\002\010\240\003\002\001\002\002\001\035
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\071\061\013\060\011\006\003\125\004\006\023\002\106\111\061\017
-\060\015\006\003\125\004\012\023\006\123\157\156\145\162\141\061
-\031\060\027\006\003\125\004\003\023\020\123\157\156\145\162\141
-\040\103\154\141\163\163\062\040\103\101\060\036\027\015\060\061
-\060\064\060\066\060\067\062\071\064\060\132\027\015\062\061\060
-\064\060\066\060\067\062\071\064\060\132\060\071\061\013\060\011
-\006\003\125\004\006\023\002\106\111\061\017\060\015\006\003\125
-\004\012\023\006\123\157\156\145\162\141\061\031\060\027\006\003
-\125\004\003\023\020\123\157\156\145\162\141\040\103\154\141\163
-\163\062\040\103\101\060\202\001\042\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001
-\012\002\202\001\001\000\220\027\112\065\235\312\360\015\226\307
-\104\372\026\067\374\110\275\275\177\200\055\065\073\341\157\250
-\147\251\277\003\034\115\214\157\062\107\325\101\150\244\023\004
-\301\065\014\232\204\103\374\134\035\377\211\263\350\027\030\315
-\221\137\373\211\343\352\277\116\135\174\033\046\323\165\171\355
-\346\204\343\127\345\255\051\304\364\072\050\347\245\173\204\066
-\151\263\375\136\166\275\243\055\231\323\220\116\043\050\175\030
-\143\361\124\073\046\235\166\133\227\102\262\377\256\360\116\354
-\335\071\225\116\203\006\177\347\111\100\310\305\001\262\124\132
-\146\035\075\374\371\351\074\012\236\201\270\160\360\001\213\344
-\043\124\174\310\256\370\220\036\000\226\162\324\124\317\141\043
-\274\352\373\235\002\225\321\266\271\161\072\151\010\077\017\264
-\341\102\307\210\365\077\230\250\247\272\034\340\161\161\357\130
-\127\201\120\172\134\153\164\106\016\203\003\230\303\216\250\156
-\362\166\062\156\047\203\302\163\363\334\030\350\264\223\352\165
-\104\153\004\140\040\161\127\207\235\363\276\240\220\043\075\212
-\044\341\332\041\333\303\002\003\001\000\001\243\063\060\061\060
-\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377
-\060\021\006\003\125\035\016\004\012\004\010\112\240\252\130\204
-\323\136\074\060\013\006\003\125\035\017\004\004\003\002\001\006
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\001\001\000\132\316\207\371\026\162\025\127\113\035\331\233
-\347\242\046\060\354\223\147\337\326\055\322\064\257\367\070\245
-\316\253\026\271\253\057\174\065\313\254\320\017\264\114\053\374
-\200\357\153\214\221\137\066\166\367\333\263\033\031\352\364\262
-\021\375\141\161\104\277\050\263\072\035\277\263\103\350\237\277
-\334\061\010\161\260\235\215\326\064\107\062\220\306\145\044\367
-\240\112\174\004\163\217\071\157\027\214\162\265\275\113\310\172
-\370\173\203\303\050\116\234\011\352\147\077\262\147\004\033\303
-\024\332\370\347\111\044\221\320\035\152\372\141\071\357\153\347
-\041\165\006\007\330\022\264\041\040\160\102\161\201\332\074\232
-\066\276\246\133\015\152\154\232\037\221\173\371\371\357\102\272
-\116\116\236\314\014\215\224\334\331\105\234\136\354\102\120\143
-\256\364\135\304\261\022\334\312\073\250\056\235\024\132\005\165
-\267\354\327\143\342\272\065\266\004\010\221\350\332\235\234\366
-\146\265\030\254\012\246\124\046\064\063\322\033\301\324\177\032
-\072\216\013\252\062\156\333\374\117\045\237\331\062\307\226\132
-\160\254\337\114
-END
-
-# Trust for Certificate "Sonera Class 2 Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Sonera Class 2 Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\067\367\155\346\007\174\220\305\261\076\223\032\267\101\020\264
-\362\344\232\047
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\243\354\165\017\056\210\337\372\110\001\116\013\134\110\157\373
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\071\061\013\060\011\006\003\125\004\006\023\002\106\111\061
-\017\060\015\006\003\125\004\012\023\006\123\157\156\145\162\141
-\061\031\060\027\006\003\125\004\003\023\020\123\157\156\145\162
-\141\040\103\154\141\163\163\062\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\035
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Staat der Nederlanden Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Staat der Nederlanden Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\125\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\036\060\034\006\003\125\004\012\023\025\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061
-\046\060\044\006\003\125\004\003\023\035\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040
-\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\125\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\036\060\034\006\003\125\004\012\023\025\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061
-\046\060\044\006\003\125\004\003\023\035\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040
-\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\000\230\226\212
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\272\060\202\002\242\240\003\002\001\002\002\004\000
-\230\226\212\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\125\061\013\060\011\006\003\125\004\006\023\002\116
-\114\061\036\060\034\006\003\125\004\012\023\025\123\164\141\141
-\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145
-\156\061\046\060\044\006\003\125\004\003\023\035\123\164\141\141
-\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145
-\156\040\122\157\157\164\040\103\101\060\036\027\015\060\062\061
-\062\061\067\060\071\062\063\064\071\132\027\015\061\065\061\062
-\061\066\060\071\061\065\063\070\132\060\125\061\013\060\011\006
-\003\125\004\006\023\002\116\114\061\036\060\034\006\003\125\004
-\012\023\025\123\164\141\141\164\040\144\145\162\040\116\145\144
-\145\162\154\141\156\144\145\156\061\046\060\044\006\003\125\004
-\003\023\035\123\164\141\141\164\040\144\145\162\040\116\145\144
-\145\162\154\141\156\144\145\156\040\122\157\157\164\040\103\101
-\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001
-\000\230\322\265\121\021\172\201\246\024\230\161\155\276\314\347
-\023\033\326\047\016\172\263\152\030\034\266\141\132\325\141\011
-\277\336\220\023\307\147\356\335\363\332\305\014\022\236\065\125
-\076\054\047\210\100\153\367\334\335\042\141\365\302\307\016\365
-\366\325\166\123\115\217\214\274\030\166\067\205\235\350\312\111
-\307\322\117\230\023\011\242\076\042\210\234\177\326\362\020\145
-\264\356\137\030\325\027\343\370\305\375\342\235\242\357\123\016
-\205\167\242\017\341\060\107\356\000\347\063\175\104\147\032\013
-\121\350\213\240\236\120\230\150\064\122\037\056\155\001\362\140
-\105\362\061\353\251\061\150\051\273\172\101\236\306\031\177\224
-\264\121\071\003\177\262\336\247\062\233\264\107\216\157\264\112
-\256\345\257\261\334\260\033\141\274\231\162\336\344\211\267\172
-\046\135\332\063\111\133\122\234\016\365\212\255\303\270\075\350
-\006\152\302\325\052\013\154\173\204\275\126\005\313\206\145\222
-\354\104\053\260\216\271\334\160\013\106\332\255\274\143\210\071
-\372\333\152\376\043\372\274\344\110\364\147\053\152\021\020\041
-\111\002\003\001\000\001\243\201\221\060\201\216\060\014\006\003
-\125\035\023\004\005\060\003\001\001\377\060\117\006\003\125\035
-\040\004\110\060\106\060\104\006\004\125\035\040\000\060\074\060
-\072\006\010\053\006\001\005\005\007\002\001\026\056\150\164\164
-\160\072\057\057\167\167\167\056\160\153\151\157\166\145\162\150
-\145\151\144\056\156\154\057\160\157\154\151\143\151\145\163\057
-\162\157\157\164\055\160\157\154\151\143\171\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003\125
-\035\016\004\026\004\024\250\175\353\274\143\244\164\023\164\000
-\354\226\340\323\064\301\054\277\154\370\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\005\204
-\207\125\164\066\141\301\273\321\324\306\025\250\023\264\237\244
-\376\273\356\025\264\057\006\014\051\362\250\222\244\141\015\374
-\253\134\010\133\121\023\053\115\302\052\141\310\370\011\130\374
-\055\002\262\071\175\231\146\201\277\156\134\225\105\040\154\346
-\171\247\321\330\034\051\374\302\040\047\121\310\361\174\135\064
-\147\151\205\021\060\306\000\322\327\363\323\174\266\360\061\127
-\050\022\202\163\351\063\057\246\125\264\013\221\224\107\234\372
-\273\172\102\062\350\256\176\055\310\274\254\024\277\331\017\331
-\133\374\301\371\172\225\341\175\176\226\374\161\260\302\114\310
-\337\105\064\311\316\015\362\234\144\010\320\073\303\051\305\262
-\355\220\004\301\261\051\221\305\060\157\301\251\162\063\314\376
-\135\026\027\054\021\151\347\176\376\305\203\010\337\274\334\042
-\072\056\040\151\043\071\126\140\147\220\213\056\166\071\373\021
-\210\227\366\174\275\113\270\040\026\147\005\215\342\073\301\162
-\077\224\225\067\307\135\271\236\330\223\241\027\217\377\014\146
-\025\301\044\174\062\174\003\035\073\241\130\105\062\223
-END
-
-# Trust for Certificate "Staat der Nederlanden Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Staat der Nederlanden Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\020\035\372\077\325\013\313\273\233\265\140\014\031\125\244\032
-\364\163\072\004
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\140\204\174\132\316\333\014\324\313\247\351\376\002\306\251\300
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\125\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\036\060\034\006\003\125\004\012\023\025\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061
-\046\060\044\006\003\125\004\003\023\035\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040
-\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\000\230\226\212
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TDC Internet Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TDC Internet Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\103\061\013\060\011\006\003\125\004\006\023\002\104\113\061
-\025\060\023\006\003\125\004\012\023\014\124\104\103\040\111\156
-\164\145\162\156\145\164\061\035\060\033\006\003\125\004\013\023
-\024\124\104\103\040\111\156\164\145\162\156\145\164\040\122\157
-\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\103\061\013\060\011\006\003\125\004\006\023\002\104\113\061
-\025\060\023\006\003\125\004\012\023\014\124\104\103\040\111\156
-\164\145\162\156\145\164\061\035\060\033\006\003\125\004\013\023
-\024\124\104\103\040\111\156\164\145\162\156\145\164\040\122\157
-\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\072\314\245\114
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\053\060\202\003\023\240\003\002\001\002\002\004\072
-\314\245\114\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\103\061\013\060\011\006\003\125\004\006\023\002\104
-\113\061\025\060\023\006\003\125\004\012\023\014\124\104\103\040
-\111\156\164\145\162\156\145\164\061\035\060\033\006\003\125\004
-\013\023\024\124\104\103\040\111\156\164\145\162\156\145\164\040
-\122\157\157\164\040\103\101\060\036\027\015\060\061\060\064\060
-\065\061\066\063\063\061\067\132\027\015\062\061\060\064\060\065
-\061\067\060\063\061\067\132\060\103\061\013\060\011\006\003\125
-\004\006\023\002\104\113\061\025\060\023\006\003\125\004\012\023
-\014\124\104\103\040\111\156\164\145\162\156\145\164\061\035\060
-\033\006\003\125\004\013\023\024\124\104\103\040\111\156\164\145
-\162\156\145\164\040\122\157\157\164\040\103\101\060\202\001\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\001\017\000\060\202\001\012\002\202\001\001\000\304\270\100
-\274\221\325\143\037\327\231\240\213\014\100\036\164\267\110\235
-\106\214\002\262\340\044\137\360\031\023\247\067\203\153\135\307
-\216\371\204\060\316\032\073\372\373\316\213\155\043\306\303\156
-\146\237\211\245\337\340\102\120\147\372\037\154\036\364\320\005
-\326\277\312\326\116\344\150\140\154\106\252\034\135\143\341\007
-\206\016\145\000\247\056\246\161\306\274\271\201\250\072\175\032
-\322\371\321\254\113\313\316\165\257\334\173\372\201\163\324\374
-\272\275\101\210\324\164\263\371\136\070\072\074\103\250\322\225
-\116\167\155\023\014\235\217\170\001\267\132\040\037\003\067\065
-\342\054\333\113\053\054\170\271\111\333\304\320\307\234\234\344
-\212\040\011\041\026\126\146\377\005\354\133\343\360\317\253\044
-\044\136\303\177\160\172\022\304\322\265\020\240\266\041\341\215
-\170\151\125\104\151\365\312\226\034\064\205\027\045\167\342\366
-\057\047\230\170\375\171\006\072\242\326\132\103\301\377\354\004
-\073\356\023\357\323\130\132\377\222\353\354\256\332\362\067\003
-\107\101\266\227\311\055\012\101\042\273\273\346\247\002\003\001
-\000\001\243\202\001\045\060\202\001\041\060\021\006\011\140\206
-\110\001\206\370\102\001\001\004\004\003\002\000\007\060\145\006
-\003\125\035\037\004\136\060\134\060\132\240\130\240\126\244\124
-\060\122\061\013\060\011\006\003\125\004\006\023\002\104\113\061
-\025\060\023\006\003\125\004\012\023\014\124\104\103\040\111\156
-\164\145\162\156\145\164\061\035\060\033\006\003\125\004\013\023
-\024\124\104\103\040\111\156\164\145\162\156\145\164\040\122\157
-\157\164\040\103\101\061\015\060\013\006\003\125\004\003\023\004
-\103\122\114\061\060\053\006\003\125\035\020\004\044\060\042\200
-\017\062\060\060\061\060\064\060\065\061\066\063\063\061\067\132
-\201\017\062\060\062\061\060\064\060\065\061\067\060\063\061\067
-\132\060\013\006\003\125\035\017\004\004\003\002\001\006\060\037
-\006\003\125\035\043\004\030\060\026\200\024\154\144\001\307\375
-\205\155\254\310\332\236\120\010\205\010\265\074\126\250\120\060
-\035\006\003\125\035\016\004\026\004\024\154\144\001\307\375\205
-\155\254\310\332\236\120\010\205\010\265\074\126\250\120\060\014
-\006\003\125\035\023\004\005\060\003\001\001\377\060\035\006\011
-\052\206\110\206\366\175\007\101\000\004\020\060\016\033\010\126
-\065\056\060\072\064\056\060\003\002\004\220\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000\116
-\103\314\321\335\035\020\033\006\177\267\244\372\323\331\115\373
-\043\237\043\124\133\346\213\057\004\050\213\265\047\155\211\241
-\354\230\151\334\347\215\046\203\005\171\164\354\264\271\243\227
-\301\065\000\375\025\332\071\201\072\225\061\220\336\227\351\206
-\250\231\167\014\345\132\240\204\377\022\026\254\156\270\215\303
-\173\222\302\254\056\320\175\050\354\266\363\140\070\151\157\076
-\330\004\125\076\236\314\125\322\272\376\273\107\004\327\012\331
-\026\012\064\051\365\130\023\325\117\317\217\126\113\263\036\356
-\323\230\171\332\010\036\014\157\270\370\026\047\357\302\157\075
-\366\243\113\076\016\344\155\154\333\073\101\022\233\275\015\107
-\043\177\074\112\320\257\300\257\366\357\033\265\025\304\353\203
-\304\011\137\164\213\331\021\373\302\126\261\074\370\160\312\064
-\215\103\100\023\214\375\231\003\124\171\306\056\352\206\241\366
-\072\324\011\274\364\274\146\314\075\130\320\127\111\012\356\045
-\342\101\356\023\371\233\070\064\321\000\365\176\347\224\035\374
-\151\003\142\270\231\005\005\075\153\170\022\275\260\157\145
-END
-
-# Trust for Certificate "TDC Internet Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TDC Internet Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\041\374\275\216\177\154\257\005\033\321\263\103\354\250\347\141
-\107\362\017\212
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\221\364\003\125\040\241\370\143\054\142\336\254\373\141\034\216
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\103\061\013\060\011\006\003\125\004\006\023\002\104\113\061
-\025\060\023\006\003\125\004\012\023\014\124\104\103\040\111\156
-\164\145\162\156\145\164\061\035\060\033\006\003\125\004\013\023
-\024\124\104\103\040\111\156\164\145\162\156\145\164\040\122\157
-\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\072\314\245\114
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TDC OCES Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TDC OCES Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\061\061\013\060\011\006\003\125\004\006\023\002\104\113\061
-\014\060\012\006\003\125\004\012\023\003\124\104\103\061\024\060
-\022\006\003\125\004\003\023\013\124\104\103\040\117\103\105\123
-\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\061\061\013\060\011\006\003\125\004\006\023\002\104\113\061
-\014\060\012\006\003\125\004\012\023\003\124\104\103\061\024\060
-\022\006\003\125\004\003\023\013\124\104\103\040\117\103\105\123
-\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\076\110\275\304
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\031\060\202\004\001\240\003\002\001\002\002\004\076
-\110\275\304\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\061\061\013\060\011\006\003\125\004\006\023\002\104
-\113\061\014\060\012\006\003\125\004\012\023\003\124\104\103\061
-\024\060\022\006\003\125\004\003\023\013\124\104\103\040\117\103
-\105\123\040\103\101\060\036\027\015\060\063\060\062\061\061\060
-\070\063\071\063\060\132\027\015\063\067\060\062\061\061\060\071
-\060\071\063\060\132\060\061\061\013\060\011\006\003\125\004\006
-\023\002\104\113\061\014\060\012\006\003\125\004\012\023\003\124
-\104\103\061\024\060\022\006\003\125\004\003\023\013\124\104\103
-\040\117\103\105\123\040\103\101\060\202\001\042\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000
-\060\202\001\012\002\202\001\001\000\254\142\366\141\040\262\317
-\300\306\205\327\343\171\346\314\355\362\071\222\244\227\056\144
-\243\204\133\207\234\114\375\244\363\304\137\041\275\126\020\353
-\333\056\141\354\223\151\343\243\314\275\231\303\005\374\006\270
-\312\066\034\376\220\216\111\114\304\126\232\057\126\274\317\173
-\014\361\157\107\246\015\103\115\342\351\035\071\064\315\215\054
-\331\022\230\371\343\341\301\112\174\206\070\304\251\304\141\210
-\322\136\257\032\046\115\325\344\240\042\107\204\331\144\267\031
-\226\374\354\031\344\262\227\046\116\112\114\313\217\044\213\124
-\030\034\110\141\173\325\210\150\332\135\265\352\315\032\060\301
-\200\203\166\120\252\117\321\324\335\070\360\357\026\364\341\014
-\120\006\277\352\373\172\111\241\050\053\034\366\374\025\062\243
-\164\152\217\251\303\142\051\161\061\345\073\244\140\027\136\164
-\346\332\023\355\351\037\037\033\321\262\150\163\306\020\064\165
-\106\020\020\343\220\000\166\100\313\213\267\103\011\041\377\253
-\116\223\306\130\351\245\202\333\167\304\072\231\261\162\225\111
-\004\360\267\053\372\173\131\216\335\002\003\001\000\001\243\202
-\002\067\060\202\002\063\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\016\006\003\125\035\017\001\001
-\377\004\004\003\002\001\006\060\201\354\006\003\125\035\040\004
-\201\344\060\201\341\060\201\336\006\010\052\201\120\201\051\001
-\001\001\060\201\321\060\057\006\010\053\006\001\005\005\007\002
-\001\026\043\150\164\164\160\072\057\057\167\167\167\056\143\145
-\162\164\151\146\151\153\141\164\056\144\153\057\162\145\160\157
-\163\151\164\157\162\171\060\201\235\006\010\053\006\001\005\005
-\007\002\002\060\201\220\060\012\026\003\124\104\103\060\003\002
-\001\001\032\201\201\103\145\162\164\151\146\151\153\141\164\145
-\162\040\146\162\141\040\144\145\156\156\145\040\103\101\040\165
-\144\163\164\145\144\145\163\040\165\156\144\145\162\040\117\111
-\104\040\061\056\062\056\062\060\070\056\061\066\071\056\061\056
-\061\056\061\056\040\103\145\162\164\151\146\151\143\141\164\145
-\163\040\146\162\157\155\040\164\150\151\163\040\103\101\040\141
-\162\145\040\151\163\163\165\145\144\040\165\156\144\145\162\040
-\117\111\104\040\061\056\062\056\062\060\070\056\061\066\071\056
-\061\056\061\056\061\056\060\021\006\011\140\206\110\001\206\370
-\102\001\001\004\004\003\002\000\007\060\201\201\006\003\125\035
-\037\004\172\060\170\060\110\240\106\240\104\244\102\060\100\061
-\013\060\011\006\003\125\004\006\023\002\104\113\061\014\060\012
-\006\003\125\004\012\023\003\124\104\103\061\024\060\022\006\003
-\125\004\003\023\013\124\104\103\040\117\103\105\123\040\103\101
-\061\015\060\013\006\003\125\004\003\023\004\103\122\114\061\060
-\054\240\052\240\050\206\046\150\164\164\160\072\057\057\143\162
-\154\056\157\143\145\163\056\143\145\162\164\151\146\151\153\141
-\164\056\144\153\057\157\143\145\163\056\143\162\154\060\053\006
-\003\125\035\020\004\044\060\042\200\017\062\060\060\063\060\062
-\061\061\060\070\063\071\063\060\132\201\017\062\060\063\067\060
-\062\061\061\060\071\060\071\063\060\132\060\037\006\003\125\035
-\043\004\030\060\026\200\024\140\265\205\354\126\144\176\022\031
-\047\147\035\120\025\113\163\256\073\371\022\060\035\006\003\125
-\035\016\004\026\004\024\140\265\205\354\126\144\176\022\031\047
-\147\035\120\025\113\163\256\073\371\022\060\035\006\011\052\206
-\110\206\366\175\007\101\000\004\020\060\016\033\010\126\066\056
-\060\072\064\056\060\003\002\004\220\060\015\006\011\052\206\110
-\206\367\015\001\001\005\005\000\003\202\001\001\000\012\272\046
-\046\106\323\163\250\011\363\153\013\060\231\375\212\341\127\172
-\021\323\270\224\327\011\020\156\243\261\070\003\321\266\362\103
-\101\051\142\247\162\330\373\174\005\346\061\160\047\124\030\116
-\212\174\116\345\321\312\214\170\210\317\033\323\220\213\346\043
-\370\013\016\063\103\175\234\342\012\031\217\311\001\076\164\135
-\164\311\213\034\003\345\030\310\001\114\077\313\227\005\135\230
-\161\246\230\157\266\174\275\067\177\276\341\223\045\155\157\360
-\012\255\027\030\341\003\274\007\051\310\255\046\350\370\141\360
-\375\041\011\176\232\216\251\150\175\110\142\162\275\000\352\001
-\231\270\006\202\121\201\116\361\365\264\221\124\271\043\172\000
-\232\237\135\215\340\074\144\271\032\022\222\052\307\202\104\162
-\071\334\342\074\306\330\125\365\025\116\310\005\016\333\306\320
-\142\246\354\025\264\265\002\202\333\254\214\242\201\360\233\231
-\061\365\040\040\250\210\141\012\007\237\224\374\320\327\033\314
-\056\027\363\004\047\166\147\353\124\203\375\244\220\176\006\075
-\004\243\103\055\332\374\013\142\352\057\137\142\123
-END
-
-# Trust for Certificate "TDC OCES Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TDC OCES Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\207\201\302\132\226\275\302\373\114\145\006\117\371\071\013\046
-\004\212\016\001
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\223\177\220\034\355\204\147\027\244\145\137\233\313\060\002\227
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\061\061\013\060\011\006\003\125\004\006\023\002\104\113\061
-\014\060\012\006\003\125\004\012\023\003\124\104\103\061\024\060
-\022\006\003\125\004\003\023\013\124\104\103\040\117\103\105\123
-\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\076\110\275\304
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "UTN DATACorp SGC Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN DATACorp SGC Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\223\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\033\060\031\006\003\125
-\004\003\023\022\125\124\116\040\055\040\104\101\124\101\103\157
-\162\160\040\123\107\103
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\223\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\033\060\031\006\003\125
-\004\003\023\022\125\124\116\040\055\040\104\101\124\101\103\157
-\162\160\040\123\107\103
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\041\264\021\323\052\150\006\251
-\255\151
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\136\060\202\003\106\240\003\002\001\002\002\020\104
-\276\014\213\120\000\041\264\021\323\052\150\006\251\255\151\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\223\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\033\060\031\006\003\125\004\003
-\023\022\125\124\116\040\055\040\104\101\124\101\103\157\162\160
-\040\123\107\103\060\036\027\015\071\071\060\066\062\064\061\070
-\065\067\062\061\132\027\015\061\071\060\066\062\064\061\071\060
-\066\063\060\132\060\201\223\061\013\060\011\006\003\125\004\006
-\023\002\125\123\061\013\060\011\006\003\125\004\010\023\002\125
-\124\061\027\060\025\006\003\125\004\007\023\016\123\141\154\164
-\040\114\141\153\145\040\103\151\164\171\061\036\060\034\006\003
-\125\004\012\023\025\124\150\145\040\125\123\105\122\124\122\125
-\123\124\040\116\145\164\167\157\162\153\061\041\060\037\006\003
-\125\004\013\023\030\150\164\164\160\072\057\057\167\167\167\056
-\165\163\145\162\164\162\165\163\164\056\143\157\155\061\033\060
-\031\006\003\125\004\003\023\022\125\124\116\040\055\040\104\101
-\124\101\103\157\162\160\040\123\107\103\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\337\356\130\020\242
-\053\156\125\304\216\277\056\106\011\347\340\010\017\056\053\172
-\023\224\033\275\366\266\200\216\145\005\223\000\036\274\257\342
-\017\216\031\015\022\107\354\254\255\243\372\056\160\370\336\156
-\373\126\102\025\236\056\134\357\043\336\041\271\005\166\047\031
-\017\117\326\303\234\264\276\224\031\143\362\246\021\012\353\123
-\110\234\276\362\051\073\026\350\032\240\114\246\311\364\030\131
-\150\300\160\362\123\000\300\136\120\202\245\126\157\066\371\112
-\340\104\206\240\115\116\326\107\156\111\112\313\147\327\246\304
-\005\271\216\036\364\374\377\315\347\066\340\234\005\154\262\063
-\042\025\320\264\340\314\027\300\262\300\364\376\062\077\051\052
-\225\173\330\362\247\116\017\124\174\241\015\200\263\011\003\301
-\377\134\335\136\232\076\274\256\274\107\212\152\256\161\312\037
-\261\052\270\137\102\005\013\354\106\060\321\162\013\312\351\126
-\155\365\357\337\170\276\141\272\262\245\256\004\114\274\250\254
-\151\025\227\275\357\353\264\214\277\065\370\324\303\321\050\016
-\134\072\237\160\030\063\040\167\304\242\257\002\003\001\000\001
-\243\201\253\060\201\250\060\013\006\003\125\035\017\004\004\003
-\002\001\306\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\123
-\062\321\263\317\177\372\340\361\240\135\205\116\222\322\236\105
-\035\264\117\060\075\006\003\125\035\037\004\066\060\064\060\062
-\240\060\240\056\206\054\150\164\164\160\072\057\057\143\162\154
-\056\165\163\145\162\164\162\165\163\164\056\143\157\155\057\125
-\124\116\055\104\101\124\101\103\157\162\160\123\107\103\056\143
-\162\154\060\052\006\003\125\035\045\004\043\060\041\006\010\053
-\006\001\005\005\007\003\001\006\012\053\006\001\004\001\202\067
-\012\003\003\006\011\140\206\110\001\206\370\102\004\001\060\015
-\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001
-\001\000\047\065\227\000\212\213\050\275\306\063\060\036\051\374
-\342\367\325\230\324\100\273\140\312\277\253\027\054\011\066\177
-\120\372\101\334\256\226\072\012\043\076\211\131\311\243\007\355
-\033\067\255\374\174\276\121\111\132\336\072\012\124\010\026\105
-\302\231\261\207\315\214\150\340\151\003\351\304\116\230\262\073
-\214\026\263\016\240\014\230\120\233\223\251\160\011\310\054\243
-\217\337\002\344\340\161\072\361\264\043\162\240\252\001\337\337
-\230\076\024\120\240\061\046\275\050\351\132\060\046\165\371\173
-\140\034\215\363\315\120\046\155\004\047\232\337\325\015\105\107
-\051\153\054\346\166\331\251\051\175\062\335\311\066\074\275\256
-\065\361\021\236\035\273\220\077\022\107\116\216\327\176\017\142
-\163\035\122\046\070\034\030\111\375\060\164\232\304\345\042\057
-\330\300\215\355\221\172\114\000\217\162\177\135\332\335\033\213
-\105\153\347\335\151\227\250\305\126\114\017\014\366\237\172\221
-\067\366\227\202\340\335\161\151\377\166\077\140\115\074\317\367
-\231\371\306\127\364\311\125\071\170\272\054\171\311\246\210\053
-\364\010
-END
-
-# Trust for Certificate "UTN DATACorp SGC Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN DATACorp SGC Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\130\021\237\016\022\202\207\352\120\375\331\207\105\157\117\170
-\334\372\326\324
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\263\245\076\167\041\155\254\112\300\311\373\325\101\075\312\006
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\223\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\033\060\031\006\003\125
-\004\003\023\022\125\124\116\040\055\040\104\101\124\101\103\157
-\162\160\040\123\107\103
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\041\264\021\323\052\150\006\251
-\255\151
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "UTN USERFirst Email Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN USERFirst Email Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\066\060\064\006\003\125
-\004\003\023\055\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\103\154\151\145\156\164\040\101\165\164\150\145\156\164
-\151\143\141\164\151\157\156\040\141\156\144\040\105\155\141\151
-\154
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\066\060\064\006\003\125
-\004\003\023\055\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\103\154\151\145\156\164\040\101\165\164\150\145\156\164
-\151\143\141\164\151\157\156\040\141\156\144\040\105\155\141\151
-\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\045\045\147
-\311\211
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\242\060\202\003\212\240\003\002\001\002\002\020\104
-\276\014\213\120\000\044\264\021\323\066\045\045\147\311\211\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\256\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\066\060\064\006\003\125\004\003
-\023\055\125\124\116\055\125\123\105\122\106\151\162\163\164\055
-\103\154\151\145\156\164\040\101\165\164\150\145\156\164\151\143
-\141\164\151\157\156\040\141\156\144\040\105\155\141\151\154\060
-\036\027\015\071\071\060\067\060\071\061\067\062\070\065\060\132
-\027\015\061\071\060\067\060\071\061\067\063\066\065\070\132\060
-\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025
-\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145
-\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025
-\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145
-\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030
-\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164
-\162\165\163\164\056\143\157\155\061\066\060\064\006\003\125\004
-\003\023\055\125\124\116\055\125\123\105\122\106\151\162\163\164
-\055\103\154\151\145\156\164\040\101\165\164\150\145\156\164\151
-\143\141\164\151\157\156\040\141\156\144\040\105\155\141\151\154
-\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001
-\000\262\071\205\244\362\175\253\101\073\142\106\067\256\315\301
-\140\165\274\071\145\371\112\032\107\242\271\314\110\314\152\230
-\325\115\065\031\271\244\102\345\316\111\342\212\057\036\174\322
-\061\007\307\116\264\203\144\235\056\051\325\242\144\304\205\275
-\205\121\065\171\244\116\150\220\173\034\172\244\222\250\027\362
-\230\025\362\223\314\311\244\062\225\273\014\117\060\275\230\240
-\013\213\345\156\033\242\106\372\170\274\242\157\253\131\136\245
-\057\317\312\332\155\252\057\353\254\241\263\152\252\267\056\147
-\065\213\171\341\036\151\210\342\346\106\315\240\245\352\276\013
-\316\166\072\172\016\233\352\374\332\047\133\075\163\037\042\346
-\110\141\306\114\363\151\261\250\056\033\266\324\061\040\054\274
-\202\212\216\244\016\245\327\211\103\374\026\132\257\035\161\327
-\021\131\332\272\207\015\257\372\363\341\302\360\244\305\147\214
-\326\326\124\072\336\012\244\272\003\167\263\145\310\375\036\323
-\164\142\252\030\312\150\223\036\241\205\176\365\107\145\313\370
-\115\127\050\164\322\064\377\060\266\356\366\142\060\024\214\054
-\353\002\003\001\000\001\243\201\271\060\201\266\060\013\006\003
-\125\035\017\004\004\003\002\001\306\060\017\006\003\125\035\023
-\001\001\377\004\005\060\003\001\001\377\060\035\006\003\125\035
-\016\004\026\004\024\211\202\147\175\304\235\046\160\000\113\264
-\120\110\174\336\075\256\004\156\175\060\130\006\003\125\035\037
-\004\121\060\117\060\115\240\113\240\111\206\107\150\164\164\160
-\072\057\057\143\162\154\056\165\163\145\162\164\162\165\163\164
-\056\143\157\155\057\125\124\116\055\125\123\105\122\106\151\162
-\163\164\055\103\154\151\145\156\164\101\165\164\150\145\156\164
-\151\143\141\164\151\157\156\141\156\144\105\155\141\151\154\056
-\143\162\154\060\035\006\003\125\035\045\004\026\060\024\006\010
-\053\006\001\005\005\007\003\002\006\010\053\006\001\005\005\007
-\003\004\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\003\202\001\001\000\261\155\141\135\246\032\177\174\253\112
-\344\060\374\123\157\045\044\306\312\355\342\061\134\053\016\356
-\356\141\125\157\004\076\317\071\336\305\033\111\224\344\353\040
-\114\264\346\236\120\056\162\331\215\365\252\243\263\112\332\126
-\034\140\227\200\334\202\242\255\112\275\212\053\377\013\011\264
-\306\327\040\004\105\344\315\200\001\272\272\053\156\316\252\327
-\222\376\344\257\353\364\046\035\026\052\177\154\060\225\067\057
-\063\022\254\177\335\307\321\021\214\121\230\262\320\243\221\320
-\255\366\237\236\203\223\036\035\102\270\106\257\153\146\360\233
-\177\352\343\003\002\345\002\121\301\252\325\065\235\162\100\003
-\211\272\061\035\305\020\150\122\236\337\242\205\305\134\010\246
-\170\346\123\117\261\350\267\323\024\236\223\246\303\144\343\254
-\176\161\315\274\237\351\003\033\314\373\351\254\061\301\257\174
-\025\164\002\231\303\262\107\246\302\062\141\327\307\157\110\044
-\121\047\241\325\207\125\362\173\217\230\075\026\236\356\165\266
-\370\320\216\362\363\306\256\050\133\247\360\363\066\027\374\303
-\005\323\312\003\112\124
-END
-
-# Trust for Certificate "UTN USERFirst Email Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN USERFirst Email Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\261\162\261\245\155\225\371\037\345\002\207\341\115\067\352\152
-\104\143\166\212
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\327\064\075\357\035\047\011\050\341\061\002\133\023\053\335\367
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\066\060\064\006\003\125
-\004\003\023\055\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\103\154\151\145\156\164\040\101\165\164\150\145\156\164
-\151\143\141\164\151\157\156\040\141\156\144\040\105\155\141\151
-\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\045\045\147
-\311\211
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "UTN USERFirst Hardware Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN USERFirst Hardware Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\052\376\145
-\012\375
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\164\060\202\003\134\240\003\002\001\002\002\020\104
-\276\014\213\120\000\044\264\021\323\066\052\376\145\012\375\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004\003
-\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164\055
-\110\141\162\144\167\141\162\145\060\036\027\015\071\071\060\067
-\060\071\061\070\061\060\064\062\132\027\015\061\071\060\067\060
-\071\061\070\061\071\062\062\132\060\201\227\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\013\060\011\006\003\125\004
-\010\023\002\125\124\061\027\060\025\006\003\125\004\007\023\016
-\123\141\154\164\040\114\141\153\145\040\103\151\164\171\061\036
-\060\034\006\003\125\004\012\023\025\124\150\145\040\125\123\105
-\122\124\122\125\123\124\040\116\145\164\167\157\162\153\061\041
-\060\037\006\003\125\004\013\023\030\150\164\164\160\072\057\057
-\167\167\167\056\165\163\145\162\164\162\165\163\164\056\143\157
-\155\061\037\060\035\006\003\125\004\003\023\026\125\124\116\055
-\125\123\105\122\106\151\162\163\164\055\110\141\162\144\167\141
-\162\145\060\202\001\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202
-\001\001\000\261\367\303\070\077\264\250\177\317\071\202\121\147
-\320\155\237\322\377\130\363\347\237\053\354\015\211\124\231\271
-\070\231\026\367\340\041\171\110\302\273\141\164\022\226\035\074
-\152\162\325\074\020\147\072\071\355\053\023\315\146\353\225\011
-\063\244\154\227\261\350\306\354\301\165\171\234\106\136\215\253
-\320\152\375\271\052\125\027\020\124\263\031\360\232\366\361\261
-\135\266\247\155\373\340\161\027\153\242\210\373\000\337\376\032
-\061\167\014\232\001\172\261\062\343\053\001\007\070\156\303\245
-\136\043\274\105\233\173\120\301\311\060\217\333\345\053\172\323
-\133\373\063\100\036\240\325\230\027\274\213\207\303\211\323\135
-\240\216\262\252\252\366\216\151\210\006\305\372\211\041\363\010
-\235\151\056\011\063\233\051\015\106\017\214\314\111\064\260\151
-\121\275\371\006\315\150\255\146\114\274\076\254\141\275\012\210
-\016\310\337\075\356\174\004\114\235\012\136\153\221\326\356\307
-\355\050\215\253\115\207\211\163\320\156\244\320\036\026\213\024
-\341\166\104\003\177\143\254\344\315\111\234\305\222\364\253\062
-\241\110\133\002\003\001\000\001\243\201\271\060\201\266\060\013
-\006\003\125\035\017\004\004\003\002\001\306\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\035\006\003
-\125\035\016\004\026\004\024\241\162\137\046\033\050\230\103\225
-\135\007\067\325\205\226\235\113\322\303\105\060\104\006\003\125
-\035\037\004\075\060\073\060\071\240\067\240\065\206\063\150\164
-\164\160\072\057\057\143\162\154\056\165\163\145\162\164\162\165
-\163\164\056\143\157\155\057\125\124\116\055\125\123\105\122\106
-\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143\162
-\154\060\061\006\003\125\035\045\004\052\060\050\006\010\053\006
-\001\005\005\007\003\001\006\010\053\006\001\005\005\007\003\005
-\006\010\053\006\001\005\005\007\003\006\006\010\053\006\001\005
-\005\007\003\007\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\003\202\001\001\000\107\031\017\336\164\306\231\227
-\257\374\255\050\136\165\216\353\055\147\356\116\173\053\327\014
-\377\366\336\313\125\242\012\341\114\124\145\223\140\153\237\022
-\234\255\136\203\054\353\132\256\300\344\055\364\000\143\035\270
-\300\154\362\317\111\273\115\223\157\006\246\012\042\262\111\142
-\010\116\377\310\310\024\262\210\026\135\347\001\344\022\225\345
-\105\064\263\213\151\275\317\264\205\217\165\121\236\175\072\070
-\072\024\110\022\306\373\247\073\032\215\015\202\100\007\350\004
-\010\220\241\211\313\031\120\337\312\034\001\274\035\004\031\173
-\020\166\227\073\356\220\220\312\304\016\037\026\156\165\357\063
-\370\323\157\133\036\226\343\340\164\167\164\173\212\242\156\055
-\335\166\326\071\060\202\360\253\234\122\362\052\307\257\111\136
-\176\307\150\345\202\201\310\152\047\371\047\210\052\325\130\120
-\225\037\360\073\034\127\273\175\024\071\142\053\232\311\224\222
-\052\243\042\014\377\211\046\175\137\043\053\107\327\025\035\251
-\152\236\121\015\052\121\236\201\371\324\073\136\160\022\177\020
-\062\234\036\273\235\370\146\250
-END
-
-# Trust for Certificate "UTN USERFirst Hardware Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN USERFirst Hardware Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\004\203\355\063\231\254\066\010\005\207\042\355\274\136\106\000
-\343\276\371\327
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\114\126\101\345\015\273\053\350\312\243\355\030\010\255\103\071
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\052\376\145
-\012\375
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "UTN USERFirst Object Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN USERFirst Object Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\225\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\035\060\033\006\003\125
-\004\003\023\024\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\117\142\152\145\143\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\225\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\035\060\033\006\003\125
-\004\003\023\024\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\117\142\152\145\143\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\055\340\263
-\137\033
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\146\060\202\003\116\240\003\002\001\002\002\020\104
-\276\014\213\120\000\044\264\021\323\066\055\340\263\137\033\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\225\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\035\060\033\006\003\125\004\003
-\023\024\125\124\116\055\125\123\105\122\106\151\162\163\164\055
-\117\142\152\145\143\164\060\036\027\015\071\071\060\067\060\071
-\061\070\063\061\062\060\132\027\015\061\071\060\067\060\071\061
-\070\064\060\063\066\132\060\201\225\061\013\060\011\006\003\125
-\004\006\023\002\125\123\061\013\060\011\006\003\125\004\010\023
-\002\125\124\061\027\060\025\006\003\125\004\007\023\016\123\141
-\154\164\040\114\141\153\145\040\103\151\164\171\061\036\060\034
-\006\003\125\004\012\023\025\124\150\145\040\125\123\105\122\124
-\122\125\123\124\040\116\145\164\167\157\162\153\061\041\060\037
-\006\003\125\004\013\023\030\150\164\164\160\072\057\057\167\167
-\167\056\165\163\145\162\164\162\165\163\164\056\143\157\155\061
-\035\060\033\006\003\125\004\003\023\024\125\124\116\055\125\123
-\105\122\106\151\162\163\164\055\117\142\152\145\143\164\060\202
-\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
-\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000\316
-\252\201\077\243\243\141\170\252\061\000\125\225\021\236\047\017
-\037\034\337\072\233\202\150\060\300\112\141\035\361\057\016\372
-\276\171\367\245\043\357\125\121\226\204\315\333\343\271\156\076
-\061\330\012\040\147\307\364\331\277\224\353\107\004\076\002\316
-\052\242\135\207\004\011\366\060\235\030\212\227\262\252\034\374
-\101\322\241\066\313\373\075\221\272\347\331\160\065\372\344\347
-\220\303\233\243\233\323\074\365\022\231\167\261\267\011\340\150
-\346\034\270\363\224\143\210\152\152\376\013\166\311\276\364\042
-\344\147\271\253\032\136\167\301\205\007\335\015\154\277\356\006
-\307\167\152\101\236\247\017\327\373\356\224\027\267\374\205\276
-\244\253\304\034\061\335\327\266\321\344\360\357\337\026\217\262
-\122\223\327\241\324\211\241\007\056\277\341\001\022\102\036\032
-\341\330\225\064\333\144\171\050\377\272\056\021\302\345\350\133
-\222\110\373\107\013\302\154\332\255\062\203\101\363\245\345\101
-\160\375\145\220\155\372\372\121\304\371\275\226\053\031\004\054
-\323\155\247\334\360\177\157\203\145\342\152\253\207\206\165\002
-\003\001\000\001\243\201\257\060\201\254\060\013\006\003\125\035
-\017\004\004\003\002\001\306\060\017\006\003\125\035\023\001\001
-\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004
-\026\004\024\332\355\144\164\024\234\024\074\253\335\231\251\275
-\133\050\115\213\074\311\330\060\102\006\003\125\035\037\004\073
-\060\071\060\067\240\065\240\063\206\061\150\164\164\160\072\057
-\057\143\162\154\056\165\163\145\162\164\162\165\163\164\056\143
-\157\155\057\125\124\116\055\125\123\105\122\106\151\162\163\164
-\055\117\142\152\145\143\164\056\143\162\154\060\051\006\003\125
-\035\045\004\042\060\040\006\010\053\006\001\005\005\007\003\003
-\006\010\053\006\001\005\005\007\003\010\006\012\053\006\001\004
-\001\202\067\012\003\004\060\015\006\011\052\206\110\206\367\015
-\001\001\005\005\000\003\202\001\001\000\010\037\122\261\067\104
-\170\333\375\316\271\332\225\226\230\252\125\144\200\265\132\100
-\335\041\245\305\301\363\137\054\114\310\107\132\151\352\350\360
-\065\065\364\320\045\363\310\246\244\207\112\275\033\261\163\010
-\275\324\303\312\266\065\273\131\206\167\061\315\247\200\024\256
-\023\357\374\261\110\371\153\045\045\055\121\266\054\155\105\301
-\230\310\212\126\135\076\356\103\116\076\153\047\216\320\072\113
-\205\013\137\323\355\152\247\165\313\321\132\207\057\071\165\023
-\132\162\260\002\201\237\276\360\017\204\124\040\142\154\151\324
-\341\115\306\015\231\103\001\015\022\226\214\170\235\277\120\242
-\261\104\252\152\317\027\172\317\157\017\324\370\044\125\137\360
-\064\026\111\146\076\120\106\311\143\161\070\061\142\270\142\271
-\363\123\255\154\265\053\242\022\252\031\117\011\332\136\347\223
-\306\216\024\010\376\360\060\200\030\240\206\205\115\310\175\327
-\213\003\376\156\325\367\235\026\254\222\054\240\043\345\234\221
-\122\037\224\337\027\224\163\303\263\301\301\161\005\040\000\170
-\275\023\122\035\250\076\315\000\037\310
-END
-
-# Trust for Certificate "UTN USERFirst Object Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "UTN USERFirst Object Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\341\055\373\113\101\327\331\303\053\060\121\113\254\035\201\330
-\070\136\055\106
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\247\362\344\026\006\101\021\120\060\153\234\343\264\234\260\311
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\225\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\035\060\033\006\003\125
-\004\003\023\024\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\117\142\152\145\143\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\276\014\213\120\000\044\264\021\323\066\055\340\263
-\137\033
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Camerfirma Chambers of Commerce Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Camerfirma Chambers of Commerce Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\177\061\013\060\011\006\003\125\004\006\023\002\105\125\061
-\047\060\045\006\003\125\004\012\023\036\101\103\040\103\141\155
-\145\162\146\151\162\155\141\040\123\101\040\103\111\106\040\101
-\070\062\067\064\063\062\070\067\061\043\060\041\006\003\125\004
-\013\023\032\150\164\164\160\072\057\057\167\167\167\056\143\150
-\141\155\142\145\162\163\151\147\156\056\157\162\147\061\042\060
-\040\006\003\125\004\003\023\031\103\150\141\155\142\145\162\163
-\040\157\146\040\103\157\155\155\145\162\143\145\040\122\157\157
-\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\177\061\013\060\011\006\003\125\004\006\023\002\105\125\061
-\047\060\045\006\003\125\004\012\023\036\101\103\040\103\141\155
-\145\162\146\151\162\155\141\040\123\101\040\103\111\106\040\101
-\070\062\067\064\063\062\070\067\061\043\060\041\006\003\125\004
-\013\023\032\150\164\164\160\072\057\057\167\167\167\056\143\150
-\141\155\142\145\162\163\151\147\156\056\157\162\147\061\042\060
-\040\006\003\125\004\003\023\031\103\150\141\155\142\145\162\163
-\040\157\146\040\103\157\155\155\145\162\143\145\040\122\157\157
-\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\275\060\202\003\245\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\177\061\013\060\011\006\003\125\004\006\023\002\105\125\061\047
-\060\045\006\003\125\004\012\023\036\101\103\040\103\141\155\145
-\162\146\151\162\155\141\040\123\101\040\103\111\106\040\101\070
-\062\067\064\063\062\070\067\061\043\060\041\006\003\125\004\013
-\023\032\150\164\164\160\072\057\057\167\167\167\056\143\150\141
-\155\142\145\162\163\151\147\156\056\157\162\147\061\042\060\040
-\006\003\125\004\003\023\031\103\150\141\155\142\145\162\163\040
-\157\146\040\103\157\155\155\145\162\143\145\040\122\157\157\164
-\060\036\027\015\060\063\060\071\063\060\061\066\061\063\064\063
-\132\027\015\063\067\060\071\063\060\061\066\061\063\064\064\132
-\060\177\061\013\060\011\006\003\125\004\006\023\002\105\125\061
-\047\060\045\006\003\125\004\012\023\036\101\103\040\103\141\155
-\145\162\146\151\162\155\141\040\123\101\040\103\111\106\040\101
-\070\062\067\064\063\062\070\067\061\043\060\041\006\003\125\004
-\013\023\032\150\164\164\160\072\057\057\167\167\167\056\143\150
-\141\155\142\145\162\163\151\147\156\056\157\162\147\061\042\060
-\040\006\003\125\004\003\023\031\103\150\141\155\142\145\162\163
-\040\157\146\040\103\157\155\155\145\162\143\145\040\122\157\157
-\164\060\202\001\040\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\015\000\060\202\001\010\002\202\001
-\001\000\267\066\125\345\245\135\030\060\340\332\211\124\221\374
-\310\307\122\370\057\120\331\357\261\165\163\145\107\175\033\133
-\272\165\305\374\241\210\044\372\057\355\312\010\112\071\124\304
-\121\172\265\332\140\352\070\074\201\262\313\361\273\331\221\043
-\077\110\001\160\165\251\005\052\255\037\161\363\311\124\075\035
-\006\152\100\076\263\014\205\356\134\033\171\302\142\304\270\066
-\216\065\135\001\014\043\004\107\065\252\233\140\116\240\146\075
-\313\046\012\234\100\241\364\135\230\277\161\253\245\000\150\052
-\355\203\172\017\242\024\265\324\042\263\200\260\074\014\132\121
-\151\055\130\030\217\355\231\236\361\256\342\225\346\366\107\250
-\326\014\017\260\130\130\333\303\146\067\236\233\221\124\063\067
-\322\224\034\152\110\311\311\362\245\332\245\014\043\367\043\016
-\234\062\125\136\161\234\204\005\121\232\055\375\346\116\052\064
-\132\336\312\100\067\147\014\124\041\125\167\332\012\014\314\227
-\256\200\334\224\066\112\364\076\316\066\023\036\123\344\254\116
-\072\005\354\333\256\162\234\070\213\320\071\073\211\012\076\167
-\376\165\002\001\003\243\202\001\104\060\202\001\100\060\022\006
-\003\125\035\023\001\001\377\004\010\060\006\001\001\377\002\001
-\014\060\074\006\003\125\035\037\004\065\060\063\060\061\240\057
-\240\055\206\053\150\164\164\160\072\057\057\143\162\154\056\143
-\150\141\155\142\145\162\163\151\147\156\056\157\162\147\057\143
-\150\141\155\142\145\162\163\162\157\157\164\056\143\162\154\060
-\035\006\003\125\035\016\004\026\004\024\343\224\365\261\115\351
-\333\241\051\133\127\213\115\166\006\166\341\321\242\212\060\016
-\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\021
-\006\011\140\206\110\001\206\370\102\001\001\004\004\003\002\000
-\007\060\047\006\003\125\035\021\004\040\060\036\201\034\143\150
-\141\155\142\145\162\163\162\157\157\164\100\143\150\141\155\142
-\145\162\163\151\147\156\056\157\162\147\060\047\006\003\125\035
-\022\004\040\060\036\201\034\143\150\141\155\142\145\162\163\162
-\157\157\164\100\143\150\141\155\142\145\162\163\151\147\156\056
-\157\162\147\060\130\006\003\125\035\040\004\121\060\117\060\115
-\006\013\053\006\001\004\001\201\207\056\012\003\001\060\076\060
-\074\006\010\053\006\001\005\005\007\002\001\026\060\150\164\164
-\160\072\057\057\143\160\163\056\143\150\141\155\142\145\162\163
-\151\147\156\056\157\162\147\057\143\160\163\057\143\150\141\155
-\142\145\162\163\162\157\157\164\056\150\164\155\154\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001
-\000\014\101\227\302\032\206\300\042\174\237\373\220\363\032\321
-\003\261\357\023\371\041\137\004\234\332\311\245\215\047\154\226
-\207\221\276\101\220\001\162\223\347\036\175\137\366\211\306\135
-\247\100\011\075\254\111\105\105\334\056\215\060\150\262\011\272
-\373\303\057\314\272\013\337\077\167\173\106\175\072\022\044\216
-\226\217\074\005\012\157\322\224\050\035\155\014\300\056\210\042
-\325\330\317\035\023\307\360\110\327\327\005\247\317\307\107\236
-\073\074\064\310\200\117\324\024\273\374\015\120\367\372\263\354
-\102\137\251\335\155\310\364\165\317\173\301\162\046\261\001\034
-\134\054\375\172\116\264\001\305\005\127\271\347\074\252\005\331
-\210\351\007\106\101\316\357\101\201\256\130\337\203\242\256\312
-\327\167\037\347\000\074\235\157\216\344\062\011\035\115\170\064
-\170\064\074\224\233\046\355\117\161\306\031\172\275\040\042\110
-\132\376\113\175\003\267\347\130\276\306\062\116\164\036\150\335
-\250\150\133\263\076\356\142\175\331\200\350\012\165\172\267\356
-\264\145\232\041\220\340\252\320\230\274\070\265\163\074\213\370
-\334
-END
-
-# Trust for Certificate "Camerfirma Chambers of Commerce Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Camerfirma Chambers of Commerce Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\156\072\125\244\031\014\031\134\223\204\074\300\333\162\056\061
-\060\141\360\261
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\260\001\356\024\331\257\051\030\224\166\216\361\151\063\052\204
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\177\061\013\060\011\006\003\125\004\006\023\002\105\125\061
-\047\060\045\006\003\125\004\012\023\036\101\103\040\103\141\155
-\145\162\146\151\162\155\141\040\123\101\040\103\111\106\040\101
-\070\062\067\064\063\062\070\067\061\043\060\041\006\003\125\004
-\013\023\032\150\164\164\160\072\057\057\167\167\167\056\143\150
-\141\155\142\145\162\163\151\147\156\056\157\162\147\061\042\060
-\040\006\003\125\004\003\023\031\103\150\141\155\142\145\162\163
-\040\157\146\040\103\157\155\155\145\162\143\145\040\122\157\157
-\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Camerfirma Global Chambersign Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Camerfirma Global Chambersign Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\175\061\013\060\011\006\003\125\004\006\023\002\105\125\061
-\047\060\045\006\003\125\004\012\023\036\101\103\040\103\141\155
-\145\162\146\151\162\155\141\040\123\101\040\103\111\106\040\101
-\070\062\067\064\063\062\070\067\061\043\060\041\006\003\125\004
-\013\023\032\150\164\164\160\072\057\057\167\167\167\056\143\150
-\141\155\142\145\162\163\151\147\156\056\157\162\147\061\040\060
-\036\006\003\125\004\003\023\027\107\154\157\142\141\154\040\103
-\150\141\155\142\145\162\163\151\147\156\040\122\157\157\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\175\061\013\060\011\006\003\125\004\006\023\002\105\125\061
-\047\060\045\006\003\125\004\012\023\036\101\103\040\103\141\155
-\145\162\146\151\162\155\141\040\123\101\040\103\111\106\040\101
-\070\062\067\064\063\062\070\067\061\043\060\041\006\003\125\004
-\013\023\032\150\164\164\160\072\057\057\167\167\167\056\143\150
-\141\155\142\145\162\163\151\147\156\056\157\162\147\061\040\060
-\036\006\003\125\004\003\023\027\107\154\157\142\141\154\040\103
-\150\141\155\142\145\162\163\151\147\156\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\305\060\202\003\255\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\175\061\013\060\011\006\003\125\004\006\023\002\105\125\061\047
-\060\045\006\003\125\004\012\023\036\101\103\040\103\141\155\145
-\162\146\151\162\155\141\040\123\101\040\103\111\106\040\101\070
-\062\067\064\063\062\070\067\061\043\060\041\006\003\125\004\013
-\023\032\150\164\164\160\072\057\057\167\167\167\056\143\150\141
-\155\142\145\162\163\151\147\156\056\157\162\147\061\040\060\036
-\006\003\125\004\003\023\027\107\154\157\142\141\154\040\103\150
-\141\155\142\145\162\163\151\147\156\040\122\157\157\164\060\036
-\027\015\060\063\060\071\063\060\061\066\061\064\061\070\132\027
-\015\063\067\060\071\063\060\061\066\061\064\061\070\132\060\175
-\061\013\060\011\006\003\125\004\006\023\002\105\125\061\047\060
-\045\006\003\125\004\012\023\036\101\103\040\103\141\155\145\162
-\146\151\162\155\141\040\123\101\040\103\111\106\040\101\070\062
-\067\064\063\062\070\067\061\043\060\041\006\003\125\004\013\023
-\032\150\164\164\160\072\057\057\167\167\167\056\143\150\141\155
-\142\145\162\163\151\147\156\056\157\162\147\061\040\060\036\006
-\003\125\004\003\023\027\107\154\157\142\141\154\040\103\150\141
-\155\142\145\162\163\151\147\156\040\122\157\157\164\060\202\001
-\040\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\202\001\015\000\060\202\001\010\002\202\001\001\000\242\160
-\242\320\237\102\256\133\027\307\330\175\317\024\203\374\117\311
-\241\267\023\257\212\327\236\076\004\012\222\213\140\126\372\264
-\062\057\210\115\241\140\010\364\267\011\116\240\111\057\111\326
-\323\337\235\227\132\237\224\004\160\354\077\131\331\267\314\146
-\213\230\122\050\011\002\337\305\057\204\215\172\227\167\277\354
-\100\235\045\162\253\265\077\062\230\373\267\267\374\162\204\345
-\065\207\371\125\372\243\037\016\157\056\050\335\151\240\331\102
-\020\306\370\265\104\302\320\103\177\333\274\344\242\074\152\125
-\170\012\167\251\330\352\031\062\267\057\376\134\077\033\356\261
-\230\354\312\255\172\151\105\343\226\017\125\366\346\355\165\352
-\145\350\062\126\223\106\211\250\045\212\145\006\356\153\277\171
-\007\320\361\267\257\355\054\115\222\273\300\250\137\247\147\175
-\004\362\025\010\160\254\222\326\175\004\322\063\373\114\266\013
-\013\373\032\311\304\215\003\251\176\134\362\120\253\022\245\241
-\317\110\120\245\357\322\310\032\023\372\260\177\261\202\034\167
-\152\017\137\334\013\225\217\357\103\176\346\105\011\045\002\001
-\003\243\202\001\120\060\202\001\114\060\022\006\003\125\035\023
-\001\001\377\004\010\060\006\001\001\377\002\001\014\060\077\006
-\003\125\035\037\004\070\060\066\060\064\240\062\240\060\206\056
-\150\164\164\160\072\057\057\143\162\154\056\143\150\141\155\142
-\145\162\163\151\147\156\056\157\162\147\057\143\150\141\155\142
-\145\162\163\151\147\156\162\157\157\164\056\143\162\154\060\035
-\006\003\125\035\016\004\026\004\024\103\234\066\237\260\236\060
-\115\306\316\137\255\020\253\345\003\245\372\251\024\060\016\006
-\003\125\035\017\001\001\377\004\004\003\002\001\006\060\021\006
-\011\140\206\110\001\206\370\102\001\001\004\004\003\002\000\007
-\060\052\006\003\125\035\021\004\043\060\041\201\037\143\150\141
-\155\142\145\162\163\151\147\156\162\157\157\164\100\143\150\141
-\155\142\145\162\163\151\147\156\056\157\162\147\060\052\006\003
-\125\035\022\004\043\060\041\201\037\143\150\141\155\142\145\162
-\163\151\147\156\162\157\157\164\100\143\150\141\155\142\145\162
-\163\151\147\156\056\157\162\147\060\133\006\003\125\035\040\004
-\124\060\122\060\120\006\013\053\006\001\004\001\201\207\056\012
-\001\001\060\101\060\077\006\010\053\006\001\005\005\007\002\001
-\026\063\150\164\164\160\072\057\057\143\160\163\056\143\150\141
-\155\142\145\162\163\151\147\156\056\157\162\147\057\143\160\163
-\057\143\150\141\155\142\145\162\163\151\147\156\162\157\157\164
-\056\150\164\155\154\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\003\202\001\001\000\074\073\160\221\371\004\124
-\047\221\341\355\355\376\150\177\141\135\345\101\145\117\062\361
-\030\005\224\152\034\336\037\160\333\076\173\062\002\064\265\014
-\154\241\212\174\245\364\217\377\324\330\255\027\325\055\004\321
-\077\130\200\342\201\131\210\276\300\343\106\223\044\376\220\275
-\046\242\060\055\350\227\046\127\065\211\164\226\030\366\025\342
-\257\044\031\126\002\002\262\272\017\024\352\306\212\146\301\206
-\105\125\213\276\222\276\234\244\004\307\111\074\236\350\051\172
-\211\327\376\257\377\150\365\245\027\220\275\254\231\314\245\206
-\127\011\147\106\333\326\026\302\106\361\344\251\120\365\217\321
-\222\025\323\137\076\306\000\111\072\156\130\262\321\321\047\015
-\045\310\062\370\040\021\315\175\062\063\110\224\124\114\335\334
-\171\304\060\237\353\216\270\125\265\327\210\134\305\152\044\075
-\262\323\005\003\121\306\007\357\314\024\162\164\075\156\162\316
-\030\050\214\112\240\167\345\011\053\105\104\107\254\267\147\177
-\001\212\005\132\223\276\241\301\377\370\347\016\147\244\107\111
-\166\135\165\220\032\365\046\217\360
-END
-
-# Trust for Certificate "Camerfirma Global Chambersign Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Camerfirma Global Chambersign Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\063\233\153\024\120\044\233\125\172\001\207\162\204\331\340\057
-\303\322\330\351
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\305\346\173\277\006\320\117\103\355\304\172\145\212\373\153\031
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\175\061\013\060\011\006\003\125\004\006\023\002\105\125\061
-\047\060\045\006\003\125\004\012\023\036\101\103\040\103\141\155
-\145\162\146\151\162\155\141\040\123\101\040\103\111\106\040\101
-\070\062\067\064\063\062\070\067\061\043\060\041\006\003\125\004
-\013\023\032\150\164\164\160\072\057\057\167\167\167\056\143\150
-\141\155\142\145\162\163\151\147\156\056\157\162\147\061\040\060
-\036\006\003\125\004\003\023\027\107\154\157\142\141\154\040\103
-\150\141\155\142\145\162\163\151\147\156\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "NetLock Qualified (Class QA) Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Qualified (Class QA) Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160
-\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145
-\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172
-\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030
-\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004
-\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163
-\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151
-\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165
-\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034
-\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146
-\157\100\156\145\164\154\157\143\153\056\150\165
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160
-\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145
-\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172
-\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030
-\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004
-\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163
-\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151
-\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165
-\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034
-\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146
-\157\100\156\145\164\154\157\143\153\056\150\165
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\173
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\006\321\060\202\005\271\240\003\002\001\002\002\001\173
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125\061
-\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145
-\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145\164
-\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172\164
-\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030\006
-\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141\156
-\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004\003
-\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163\151
-\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151\040
-\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165\163
-\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034\006
-\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146\157
-\100\156\145\164\154\157\143\153\056\150\165\060\036\027\015\060
-\063\060\063\063\060\060\061\064\067\061\061\132\027\015\062\062
-\061\062\061\065\060\061\064\067\061\061\132\060\201\311\061\013
-\060\011\006\003\125\004\006\023\002\110\125\061\021\060\017\006
-\003\125\004\007\023\010\102\165\144\141\160\145\163\164\061\047
-\060\045\006\003\125\004\012\023\036\116\145\164\114\157\143\153
-\040\110\141\154\157\172\141\164\142\151\172\164\157\156\163\141
-\147\151\040\113\146\164\056\061\032\060\030\006\003\125\004\013
-\023\021\124\141\156\165\163\151\164\166\141\156\171\153\151\141
-\144\157\153\061\102\060\100\006\003\125\004\003\023\071\116\145
-\164\114\157\143\153\040\115\151\156\157\163\151\164\145\164\164
-\040\113\157\172\152\145\147\171\172\157\151\040\050\103\154\141
-\163\163\040\121\101\051\040\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\061\036\060\034\006\011\052\206\110
-\206\367\015\001\011\001\026\017\151\156\146\157\100\156\145\164
-\154\157\143\153\056\150\165\060\202\001\042\060\015\006\011\052
-\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060
-\202\001\012\002\202\001\001\000\307\122\045\262\330\075\324\204
-\125\011\247\033\275\154\271\024\364\212\002\333\166\374\152\052
-\170\253\345\167\360\156\340\214\043\147\333\245\144\231\271\335
-\001\076\157\357\055\232\074\042\360\135\311\127\240\125\101\177
-\362\103\136\130\202\123\061\145\316\036\362\046\272\000\124\036
-\257\260\274\034\344\122\214\240\062\257\267\067\261\123\147\150
-\164\147\120\366\055\056\144\336\256\046\171\337\337\231\206\253
-\253\177\205\354\240\373\200\314\364\270\014\036\223\105\143\271
-\334\270\133\233\355\133\071\324\137\142\260\247\216\174\146\070
-\054\252\261\010\143\027\147\175\314\275\263\361\303\077\317\120
-\071\355\321\031\203\025\333\207\022\047\226\267\332\352\345\235
-\274\272\352\071\117\213\357\164\232\347\305\320\322\352\206\121
-\034\344\376\144\010\050\004\171\005\353\312\305\161\016\013\357
-\253\352\354\022\021\241\030\005\062\151\321\014\054\032\075\045
-\231\077\265\174\312\155\260\256\231\231\372\010\140\347\031\302
-\362\275\121\323\314\323\002\254\301\021\014\200\316\253\334\224
-\235\153\243\071\123\072\326\205\002\003\000\305\175\243\202\002
-\300\060\202\002\274\060\022\006\003\125\035\023\001\001\377\004
-\010\060\006\001\001\377\002\001\004\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\001\006\060\202\002\165\006\011\140
-\206\110\001\206\370\102\001\015\004\202\002\146\026\202\002\142
-\106\111\107\131\105\114\105\115\041\040\105\172\145\156\040\164
-\141\156\165\163\151\164\166\141\156\171\040\141\040\116\145\164
-\114\157\143\153\040\113\146\164\056\040\115\151\156\157\163\151
-\164\145\164\164\040\123\172\157\154\147\141\154\164\141\164\141
-\163\151\040\123\172\141\142\141\154\171\172\141\164\141\142\141
-\156\040\154\145\151\162\164\040\145\154\152\141\162\141\163\157
-\153\040\141\154\141\160\152\141\156\040\153\145\163\172\165\154
-\164\056\040\101\040\155\151\156\157\163\151\164\145\164\164\040
-\145\154\145\153\164\162\157\156\151\153\165\163\040\141\154\141
-\151\162\141\163\040\152\157\147\150\141\164\141\163\040\145\162
-\166\145\156\171\145\163\165\154\145\163\145\156\145\153\054\040
-\166\141\154\141\155\151\156\164\040\145\154\146\157\147\141\144
-\141\163\141\156\141\153\040\146\145\154\164\145\164\145\154\145
-\040\141\040\115\151\156\157\163\151\164\145\164\164\040\123\172
-\157\154\147\141\154\164\141\164\141\163\151\040\123\172\141\142
-\141\154\171\172\141\164\142\141\156\054\040\141\172\040\101\154
-\164\141\154\141\156\157\163\040\123\172\145\162\172\157\144\145
-\163\151\040\106\145\154\164\145\164\145\154\145\153\142\145\156
-\040\145\154\157\151\162\164\040\145\154\154\145\156\157\162\172
-\145\163\151\040\145\154\152\141\162\141\163\040\155\145\147\164
-\145\164\145\154\145\056\040\101\040\144\157\153\165\155\145\156
-\164\165\155\157\153\040\155\145\147\164\141\154\141\154\150\141
-\164\157\153\040\141\040\150\164\164\160\163\072\057\057\167\167
-\167\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143
-\163\057\040\143\151\155\145\156\040\166\141\147\171\040\153\145
-\162\150\145\164\157\153\040\141\172\040\151\156\146\157\100\156
-\145\164\154\157\143\153\056\156\145\164\040\145\055\155\141\151
-\154\040\143\151\155\145\156\056\040\127\101\122\116\111\116\107
-\041\040\124\150\145\040\151\163\163\165\141\156\143\145\040\141
-\156\144\040\164\150\145\040\165\163\145\040\157\146\040\164\150
-\151\163\040\143\145\162\164\151\146\151\143\141\164\145\040\141
-\162\145\040\163\165\142\152\145\143\164\040\164\157\040\164\150
-\145\040\116\145\164\114\157\143\153\040\121\165\141\154\151\146
-\151\145\144\040\103\120\123\040\141\166\141\151\154\141\142\154
-\145\040\141\164\040\150\164\164\160\163\072\057\057\167\167\167
-\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143\163
-\057\040\157\162\040\142\171\040\145\055\155\141\151\154\040\141
-\164\040\151\156\146\157\100\156\145\164\154\157\143\153\056\156
-\145\164\060\035\006\003\125\035\016\004\026\004\024\011\152\142
-\026\222\260\132\273\125\016\313\165\062\072\062\345\262\041\311
-\050\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\202\001\001\000\221\152\120\234\333\170\201\233\077\213\102
-\343\073\374\246\303\356\103\340\317\363\342\200\065\111\105\166
-\002\342\343\057\005\305\361\052\347\300\101\063\306\266\233\320
-\063\071\315\300\333\241\255\154\067\002\114\130\101\073\362\227
-\222\306\110\250\315\345\212\071\211\141\371\122\227\351\275\366
-\371\224\164\350\161\016\274\167\206\303\006\314\132\174\112\176
-\064\120\060\056\373\177\062\232\215\075\363\040\133\370\152\312
-\206\363\061\114\054\131\200\002\175\376\070\311\060\165\034\267
-\125\343\274\237\272\250\155\204\050\005\165\263\213\015\300\221
-\124\041\347\246\013\264\231\365\121\101\334\315\243\107\042\331
-\307\001\201\304\334\107\117\046\352\037\355\333\315\015\230\364
-\243\234\264\163\062\112\226\231\376\274\177\310\045\130\370\130
-\363\166\146\211\124\244\246\076\304\120\134\272\211\030\202\165
-\110\041\322\117\023\350\140\176\007\166\333\020\265\121\346\252
-\271\150\252\315\366\235\220\165\022\352\070\032\312\104\350\267
-\231\247\052\150\225\146\225\253\255\357\211\313\140\251\006\022
-\306\224\107\351\050
-END
-
-# Trust for Certificate "NetLock Qualified (Class QA) Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Qualified (Class QA) Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\001\150\227\341\240\270\362\303\261\064\146\134\040\247\047\267
-\241\130\342\217
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\324\200\145\150\044\371\211\042\050\333\365\244\232\027\217\024
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160
-\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145
-\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172
-\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030
-\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004
-\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163
-\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151
-\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165
-\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034
-\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146
-\157\100\156\145\164\154\157\143\153\056\150\165
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\173
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "NetLock Notary (Class A) Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Notary (Class A) Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\257\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\020\060\016\006\003\125\004\010\023\007\110\165\156\147\141
-\162\171\061\021\060\017\006\003\125\004\007\023\010\102\165\144
-\141\160\145\163\164\061\047\060\045\006\003\125\004\012\023\036
-\116\145\164\114\157\143\153\040\110\141\154\157\172\141\164\142
-\151\172\164\157\156\163\141\147\151\040\113\146\164\056\061\032
-\060\030\006\003\125\004\013\023\021\124\141\156\165\163\151\164
-\166\141\156\171\153\151\141\144\157\153\061\066\060\064\006\003
-\125\004\003\023\055\116\145\164\114\157\143\153\040\113\157\172
-\152\145\147\171\172\157\151\040\050\103\154\141\163\163\040\101
-\051\040\124\141\156\165\163\151\164\166\141\156\171\153\151\141
-\144\157
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\257\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\020\060\016\006\003\125\004\010\023\007\110\165\156\147\141
-\162\171\061\021\060\017\006\003\125\004\007\023\010\102\165\144
-\141\160\145\163\164\061\047\060\045\006\003\125\004\012\023\036
-\116\145\164\114\157\143\153\040\110\141\154\157\172\141\164\142
-\151\172\164\157\156\163\141\147\151\040\113\146\164\056\061\032
-\060\030\006\003\125\004\013\023\021\124\141\156\165\163\151\164
-\166\141\156\171\153\151\141\144\157\153\061\066\060\064\006\003
-\125\004\003\023\055\116\145\164\114\157\143\153\040\113\157\172
-\152\145\147\171\172\157\151\040\050\103\154\141\163\163\040\101
-\051\040\124\141\156\165\163\151\164\166\141\156\171\153\151\141
-\144\157
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\001\003
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\006\175\060\202\005\145\240\003\002\001\002\002\002\001
-\003\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000
-\060\201\257\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\020\060\016\006\003\125\004\010\023\007\110\165\156\147\141
-\162\171\061\021\060\017\006\003\125\004\007\023\010\102\165\144
-\141\160\145\163\164\061\047\060\045\006\003\125\004\012\023\036
-\116\145\164\114\157\143\153\040\110\141\154\157\172\141\164\142
-\151\172\164\157\156\163\141\147\151\040\113\146\164\056\061\032
-\060\030\006\003\125\004\013\023\021\124\141\156\165\163\151\164
-\166\141\156\171\153\151\141\144\157\153\061\066\060\064\006\003
-\125\004\003\023\055\116\145\164\114\157\143\153\040\113\157\172
-\152\145\147\171\172\157\151\040\050\103\154\141\163\163\040\101
-\051\040\124\141\156\165\163\151\164\166\141\156\171\153\151\141
-\144\157\060\036\027\015\071\071\060\062\062\064\062\063\061\064
-\064\067\132\027\015\061\071\060\062\061\071\062\063\061\064\064
-\067\132\060\201\257\061\013\060\011\006\003\125\004\006\023\002
-\110\125\061\020\060\016\006\003\125\004\010\023\007\110\165\156
-\147\141\162\171\061\021\060\017\006\003\125\004\007\023\010\102
-\165\144\141\160\145\163\164\061\047\060\045\006\003\125\004\012
-\023\036\116\145\164\114\157\143\153\040\110\141\154\157\172\141
-\164\142\151\172\164\157\156\163\141\147\151\040\113\146\164\056
-\061\032\060\030\006\003\125\004\013\023\021\124\141\156\165\163
-\151\164\166\141\156\171\153\151\141\144\157\153\061\066\060\064
-\006\003\125\004\003\023\055\116\145\164\114\157\143\153\040\113
-\157\172\152\145\147\171\172\157\151\040\050\103\154\141\163\163
-\040\101\051\040\124\141\156\165\163\151\164\166\141\156\171\153
-\151\141\144\157\060\202\001\042\060\015\006\011\052\206\110\206
-\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012
-\002\202\001\001\000\274\164\214\017\273\114\364\067\036\251\005
-\202\330\346\341\154\160\352\170\265\156\321\070\104\015\250\203
-\316\135\322\326\325\201\305\324\113\347\133\224\160\046\333\073
-\235\152\114\142\367\161\363\144\326\141\073\075\353\163\243\067
-\331\317\352\214\222\073\315\367\007\334\146\164\227\364\105\042
-\335\364\134\340\277\155\363\276\145\063\344\025\072\277\333\230
-\220\125\070\304\355\246\125\143\013\260\170\004\364\343\156\301
-\077\216\374\121\170\037\222\236\203\302\376\331\260\251\311\274
-\132\000\377\251\250\230\164\373\366\054\076\025\071\015\266\004
-\125\250\016\230\040\102\263\261\045\255\176\232\157\135\123\261
-\253\014\374\353\340\363\172\263\250\263\377\106\366\143\242\330
-\072\230\173\266\254\205\377\260\045\117\164\143\347\023\007\245
-\012\217\005\367\300\144\157\176\247\047\200\226\336\324\056\206
-\140\307\153\053\136\163\173\027\347\221\077\144\014\330\113\042
-\064\053\233\062\362\110\037\237\241\012\204\172\342\302\255\227
-\075\216\325\301\371\126\243\120\351\306\264\372\230\242\356\225
-\346\052\003\214\337\002\003\001\000\001\243\202\002\237\060\202
-\002\233\060\016\006\003\125\035\017\001\001\377\004\004\003\002
-\000\006\060\022\006\003\125\035\023\001\001\377\004\010\060\006
-\001\001\377\002\001\004\060\021\006\011\140\206\110\001\206\370
-\102\001\001\004\004\003\002\000\007\060\202\002\140\006\011\140
-\206\110\001\206\370\102\001\015\004\202\002\121\026\202\002\115
-\106\111\107\131\105\114\105\115\041\040\105\172\145\156\040\164
-\141\156\165\163\151\164\166\141\156\171\040\141\040\116\145\164
-\114\157\143\153\040\113\146\164\056\040\101\154\164\141\154\141
-\156\157\163\040\123\172\157\154\147\141\154\164\141\164\141\163
-\151\040\106\145\154\164\145\164\145\154\145\151\142\145\156\040
-\154\145\151\162\164\040\145\154\152\141\162\141\163\157\153\040
-\141\154\141\160\152\141\156\040\153\145\163\172\165\154\164\056
-\040\101\040\150\151\164\145\154\145\163\151\164\145\163\040\146
-\157\154\171\141\155\141\164\141\164\040\141\040\116\145\164\114
-\157\143\153\040\113\146\164\056\040\164\145\162\155\145\153\146
-\145\154\145\154\157\163\163\145\147\055\142\151\172\164\157\163
-\151\164\141\163\141\040\166\145\144\151\056\040\101\040\144\151
-\147\151\164\141\154\151\163\040\141\154\141\151\162\141\163\040
-\145\154\146\157\147\141\144\141\163\141\156\141\153\040\146\145
-\154\164\145\164\145\154\145\040\141\172\040\145\154\157\151\162
-\164\040\145\154\154\145\156\157\162\172\145\163\151\040\145\154
-\152\141\162\141\163\040\155\145\147\164\145\164\145\154\145\056
-\040\101\172\040\145\154\152\141\162\141\163\040\154\145\151\162
-\141\163\141\040\155\145\147\164\141\154\141\154\150\141\164\157
-\040\141\040\116\145\164\114\157\143\153\040\113\146\164\056\040
-\111\156\164\145\162\156\145\164\040\150\157\156\154\141\160\152
-\141\156\040\141\040\150\164\164\160\163\072\057\057\167\167\167
-\056\156\145\164\154\157\143\153\056\156\145\164\057\144\157\143
-\163\040\143\151\155\145\156\040\166\141\147\171\040\153\145\162
-\150\145\164\157\040\141\172\040\145\154\154\145\156\157\162\172
-\145\163\100\156\145\164\154\157\143\153\056\156\145\164\040\145
-\055\155\141\151\154\040\143\151\155\145\156\056\040\111\115\120
-\117\122\124\101\116\124\041\040\124\150\145\040\151\163\163\165
-\141\156\143\145\040\141\156\144\040\164\150\145\040\165\163\145
-\040\157\146\040\164\150\151\163\040\143\145\162\164\151\146\151
-\143\141\164\145\040\151\163\040\163\165\142\152\145\143\164\040
-\164\157\040\164\150\145\040\116\145\164\114\157\143\153\040\103
-\120\123\040\141\166\141\151\154\141\142\154\145\040\141\164\040
-\150\164\164\160\163\072\057\057\167\167\167\056\156\145\164\154
-\157\143\153\056\156\145\164\057\144\157\143\163\040\157\162\040
-\142\171\040\145\055\155\141\151\154\040\141\164\040\143\160\163
-\100\156\145\164\154\157\143\153\056\156\145\164\056\060\015\006
-\011\052\206\110\206\367\015\001\001\004\005\000\003\202\001\001
-\000\110\044\106\367\272\126\157\372\310\050\003\100\116\345\061
-\071\153\046\153\123\177\333\337\337\363\161\075\046\300\024\016
-\306\147\173\043\250\014\163\335\001\273\306\312\156\067\071\125
-\325\307\214\126\040\016\050\012\016\322\052\244\260\111\122\306
-\070\007\376\276\012\011\214\321\230\317\312\332\024\061\241\117
-\322\071\374\017\021\054\103\303\335\253\223\307\125\076\107\174
-\030\032\000\334\363\173\330\362\177\122\154\040\364\013\137\151
-\122\364\356\370\262\051\140\353\343\111\061\041\015\326\265\020
-\101\342\101\011\154\342\032\232\126\113\167\002\366\240\233\232
-\047\207\350\125\051\161\302\220\237\105\170\032\341\025\144\075
-\320\016\330\240\166\237\256\305\320\056\352\326\017\126\354\144
-\177\132\233\024\130\001\047\176\023\120\307\153\052\346\150\074
-\277\134\240\012\033\341\016\172\351\342\200\303\351\351\366\375
-\154\021\236\320\345\050\047\053\124\062\102\024\202\165\346\112
-\360\053\146\165\143\214\242\373\004\076\203\016\233\066\360\030
-\344\046\040\303\214\360\050\007\255\074\027\146\210\265\375\266
-\210
-END
-
-# Trust for Certificate "NetLock Notary (Class A) Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Notary (Class A) Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\254\355\137\145\123\375\045\316\001\137\037\172\110\073\152\164
-\237\141\170\306
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\206\070\155\136\111\143\154\205\134\333\155\334\224\267\320\367
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\257\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\020\060\016\006\003\125\004\010\023\007\110\165\156\147\141
-\162\171\061\021\060\017\006\003\125\004\007\023\010\102\165\144
-\141\160\145\163\164\061\047\060\045\006\003\125\004\012\023\036
-\116\145\164\114\157\143\153\040\110\141\154\157\172\141\164\142
-\151\172\164\157\156\163\141\147\151\040\113\146\164\056\061\032
-\060\030\006\003\125\004\013\023\021\124\141\156\165\163\151\164
-\166\141\156\171\153\151\141\144\157\153\061\066\060\064\006\003
-\125\004\003\023\055\116\145\164\114\157\143\153\040\113\157\172
-\152\145\147\171\172\157\151\040\050\103\154\141\163\163\040\101
-\051\040\124\141\156\165\163\151\164\166\141\156\171\153\151\141
-\144\157
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\001\003
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "NetLock Business (Class B) Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Business (Class B) Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\231\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160
-\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145
-\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172
-\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030
-\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\153\061\062\060\060\006\003\125\004
-\003\023\051\116\145\164\114\157\143\153\040\125\172\154\145\164
-\151\040\050\103\154\141\163\163\040\102\051\040\124\141\156\165
-\163\151\164\166\141\156\171\153\151\141\144\157
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\231\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160
-\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145
-\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172
-\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030
-\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\153\061\062\060\060\006\003\125\004
-\003\023\051\116\145\164\114\157\143\153\040\125\172\154\145\164
-\151\040\050\103\154\141\163\163\040\102\051\040\124\141\156\165
-\163\151\164\166\141\156\171\153\151\141\144\157
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\151
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\113\060\202\004\264\240\003\002\001\002\002\001\151
-\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060
-\201\231\061\013\060\011\006\003\125\004\006\023\002\110\125\061
-\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145
-\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145\164
-\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172\164
-\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030\006
-\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141\156
-\171\153\151\141\144\157\153\061\062\060\060\006\003\125\004\003
-\023\051\116\145\164\114\157\143\153\040\125\172\154\145\164\151
-\040\050\103\154\141\163\163\040\102\051\040\124\141\156\165\163
-\151\164\166\141\156\171\153\151\141\144\157\060\036\027\015\071
-\071\060\062\062\065\061\064\061\060\062\062\132\027\015\061\071
-\060\062\062\060\061\064\061\060\062\062\132\060\201\231\061\013
-\060\011\006\003\125\004\006\023\002\110\125\061\021\060\017\006
-\003\125\004\007\023\010\102\165\144\141\160\145\163\164\061\047
-\060\045\006\003\125\004\012\023\036\116\145\164\114\157\143\153
-\040\110\141\154\157\172\141\164\142\151\172\164\157\156\163\141
-\147\151\040\113\146\164\056\061\032\060\030\006\003\125\004\013
-\023\021\124\141\156\165\163\151\164\166\141\156\171\153\151\141
-\144\157\153\061\062\060\060\006\003\125\004\003\023\051\116\145
-\164\114\157\143\153\040\125\172\154\145\164\151\040\050\103\154
-\141\163\163\040\102\051\040\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\060\201\237\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\201\215\000\060\201\211
-\002\201\201\000\261\352\004\354\040\240\043\302\217\070\140\317
-\307\106\263\325\033\376\373\271\231\236\004\334\034\177\214\112
-\201\230\356\244\324\312\212\027\271\042\177\203\012\165\114\233
-\300\151\330\144\071\243\355\222\243\375\133\134\164\032\300\107
-\312\072\151\166\232\272\342\104\027\374\114\243\325\376\270\227
-\210\257\210\003\211\037\244\362\004\076\310\007\013\346\371\263
-\057\172\142\024\011\106\024\312\144\365\213\200\265\142\250\330
-\153\326\161\223\055\263\277\011\124\130\355\006\353\250\173\334
-\103\261\241\151\002\003\001\000\001\243\202\002\237\060\202\002
-\233\060\022\006\003\125\035\023\001\001\377\004\010\060\006\001
-\001\377\002\001\004\060\016\006\003\125\035\017\001\001\377\004
-\004\003\002\000\006\060\021\006\011\140\206\110\001\206\370\102
-\001\001\004\004\003\002\000\007\060\202\002\140\006\011\140\206
-\110\001\206\370\102\001\015\004\202\002\121\026\202\002\115\106
-\111\107\131\105\114\105\115\041\040\105\172\145\156\040\164\141
-\156\165\163\151\164\166\141\156\171\040\141\040\116\145\164\114
-\157\143\153\040\113\146\164\056\040\101\154\164\141\154\141\156
-\157\163\040\123\172\157\154\147\141\154\164\141\164\141\163\151
-\040\106\145\154\164\145\164\145\154\145\151\142\145\156\040\154
-\145\151\162\164\040\145\154\152\141\162\141\163\157\153\040\141
-\154\141\160\152\141\156\040\153\145\163\172\165\154\164\056\040
-\101\040\150\151\164\145\154\145\163\151\164\145\163\040\146\157
-\154\171\141\155\141\164\141\164\040\141\040\116\145\164\114\157
-\143\153\040\113\146\164\056\040\164\145\162\155\145\153\146\145
-\154\145\154\157\163\163\145\147\055\142\151\172\164\157\163\151
-\164\141\163\141\040\166\145\144\151\056\040\101\040\144\151\147
-\151\164\141\154\151\163\040\141\154\141\151\162\141\163\040\145
-\154\146\157\147\141\144\141\163\141\156\141\153\040\146\145\154
-\164\145\164\145\154\145\040\141\172\040\145\154\157\151\162\164
-\040\145\154\154\145\156\157\162\172\145\163\151\040\145\154\152
-\141\162\141\163\040\155\145\147\164\145\164\145\154\145\056\040
-\101\172\040\145\154\152\141\162\141\163\040\154\145\151\162\141
-\163\141\040\155\145\147\164\141\154\141\154\150\141\164\157\040
-\141\040\116\145\164\114\157\143\153\040\113\146\164\056\040\111
-\156\164\145\162\156\145\164\040\150\157\156\154\141\160\152\141
-\156\040\141\040\150\164\164\160\163\072\057\057\167\167\167\056
-\156\145\164\154\157\143\153\056\156\145\164\057\144\157\143\163
-\040\143\151\155\145\156\040\166\141\147\171\040\153\145\162\150
-\145\164\157\040\141\172\040\145\154\154\145\156\157\162\172\145
-\163\100\156\145\164\154\157\143\153\056\156\145\164\040\145\055
-\155\141\151\154\040\143\151\155\145\156\056\040\111\115\120\117
-\122\124\101\116\124\041\040\124\150\145\040\151\163\163\165\141
-\156\143\145\040\141\156\144\040\164\150\145\040\165\163\145\040
-\157\146\040\164\150\151\163\040\143\145\162\164\151\146\151\143
-\141\164\145\040\151\163\040\163\165\142\152\145\143\164\040\164
-\157\040\164\150\145\040\116\145\164\114\157\143\153\040\103\120
-\123\040\141\166\141\151\154\141\142\154\145\040\141\164\040\150
-\164\164\160\163\072\057\057\167\167\167\056\156\145\164\154\157
-\143\153\056\156\145\164\057\144\157\143\163\040\157\162\040\142
-\171\040\145\055\155\141\151\154\040\141\164\040\143\160\163\100
-\156\145\164\154\157\143\153\056\156\145\164\056\060\015\006\011
-\052\206\110\206\367\015\001\001\004\005\000\003\201\201\000\004
-\333\256\214\027\257\370\016\220\061\116\315\076\011\300\155\072
-\260\370\063\114\107\114\343\165\210\020\227\254\260\070\025\221
-\306\051\226\314\041\300\155\074\245\164\317\330\202\245\071\303
-\145\343\102\160\273\042\220\343\175\333\065\166\341\240\265\332
-\237\160\156\223\032\060\071\035\060\333\056\343\174\262\221\262
-\321\067\051\372\271\326\027\134\107\117\343\035\070\353\237\325
-\173\225\250\050\236\025\112\321\321\320\053\000\227\240\342\222
-\066\053\143\254\130\001\153\063\051\120\206\203\361\001\110
-END
-
-# Trust for Certificate "NetLock Business (Class B) Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Business (Class B) Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\207\237\113\356\005\337\230\130\073\343\140\326\063\347\015\077
-\376\230\161\257
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\071\026\252\271\152\101\341\024\151\337\236\154\073\162\334\266
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\231\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160
-\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145
-\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172
-\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030
-\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\153\061\062\060\060\006\003\125\004
-\003\023\051\116\145\164\114\157\143\153\040\125\172\154\145\164
-\151\040\050\103\154\141\163\163\040\102\051\040\124\141\156\165
-\163\151\164\166\141\156\171\153\151\141\144\157
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\151
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "NetLock Express (Class C) Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Express (Class C) Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\233\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160
-\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145
-\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172
-\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030
-\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\153\061\064\060\062\006\003\125\004
-\003\023\053\116\145\164\114\157\143\153\040\105\170\160\162\145
-\163\163\172\040\050\103\154\141\163\163\040\103\051\040\124\141
-\156\165\163\151\164\166\141\156\171\153\151\141\144\157
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\233\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160
-\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145
-\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172
-\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030
-\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\153\061\064\060\062\006\003\125\004
-\003\023\053\116\145\164\114\157\143\153\040\105\170\160\162\145
-\163\163\172\040\050\103\154\141\163\163\040\103\051\040\124\141
-\156\165\163\151\164\166\141\156\171\153\151\141\144\157
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\150
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\117\060\202\004\270\240\003\002\001\002\002\001\150
-\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060
-\201\233\061\013\060\011\006\003\125\004\006\023\002\110\125\061
-\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145
-\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145\164
-\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172\164
-\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030\006
-\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141\156
-\171\153\151\141\144\157\153\061\064\060\062\006\003\125\004\003
-\023\053\116\145\164\114\157\143\153\040\105\170\160\162\145\163
-\163\172\040\050\103\154\141\163\163\040\103\051\040\124\141\156
-\165\163\151\164\166\141\156\171\153\151\141\144\157\060\036\027
-\015\071\071\060\062\062\065\061\064\060\070\061\061\132\027\015
-\061\071\060\062\062\060\061\064\060\070\061\061\132\060\201\233
-\061\013\060\011\006\003\125\004\006\023\002\110\125\061\021\060
-\017\006\003\125\004\007\023\010\102\165\144\141\160\145\163\164
-\061\047\060\045\006\003\125\004\012\023\036\116\145\164\114\157
-\143\153\040\110\141\154\157\172\141\164\142\151\172\164\157\156
-\163\141\147\151\040\113\146\164\056\061\032\060\030\006\003\125
-\004\013\023\021\124\141\156\165\163\151\164\166\141\156\171\153
-\151\141\144\157\153\061\064\060\062\006\003\125\004\003\023\053
-\116\145\164\114\157\143\153\040\105\170\160\162\145\163\163\172
-\040\050\103\154\141\163\163\040\103\051\040\124\141\156\165\163
-\151\164\166\141\156\171\153\151\141\144\157\060\201\237\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\201\215
-\000\060\201\211\002\201\201\000\353\354\260\154\141\212\043\045
-\257\140\040\343\331\237\374\223\013\333\135\215\260\241\263\100
-\072\202\316\375\165\340\170\062\003\206\132\206\225\221\355\123
-\372\235\100\374\346\350\335\331\133\172\003\275\135\363\073\014
-\303\121\171\233\255\125\240\351\320\003\020\257\012\272\024\102
-\331\122\046\021\042\307\322\040\314\202\244\232\251\376\270\201
-\166\235\152\267\322\066\165\076\261\206\011\366\156\155\176\116
-\267\172\354\256\161\204\366\004\063\010\045\062\353\164\254\026
-\104\306\344\100\223\035\177\255\002\003\001\000\001\243\202\002
-\237\060\202\002\233\060\022\006\003\125\035\023\001\001\377\004
-\010\060\006\001\001\377\002\001\004\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\000\006\060\021\006\011\140\206\110
-\001\206\370\102\001\001\004\004\003\002\000\007\060\202\002\140
-\006\011\140\206\110\001\206\370\102\001\015\004\202\002\121\026
-\202\002\115\106\111\107\131\105\114\105\115\041\040\105\172\145
-\156\040\164\141\156\165\163\151\164\166\141\156\171\040\141\040
-\116\145\164\114\157\143\153\040\113\146\164\056\040\101\154\164
-\141\154\141\156\157\163\040\123\172\157\154\147\141\154\164\141
-\164\141\163\151\040\106\145\154\164\145\164\145\154\145\151\142
-\145\156\040\154\145\151\162\164\040\145\154\152\141\162\141\163
-\157\153\040\141\154\141\160\152\141\156\040\153\145\163\172\165
-\154\164\056\040\101\040\150\151\164\145\154\145\163\151\164\145
-\163\040\146\157\154\171\141\155\141\164\141\164\040\141\040\116
-\145\164\114\157\143\153\040\113\146\164\056\040\164\145\162\155
-\145\153\146\145\154\145\154\157\163\163\145\147\055\142\151\172
-\164\157\163\151\164\141\163\141\040\166\145\144\151\056\040\101
-\040\144\151\147\151\164\141\154\151\163\040\141\154\141\151\162
-\141\163\040\145\154\146\157\147\141\144\141\163\141\156\141\153
-\040\146\145\154\164\145\164\145\154\145\040\141\172\040\145\154
-\157\151\162\164\040\145\154\154\145\156\157\162\172\145\163\151
-\040\145\154\152\141\162\141\163\040\155\145\147\164\145\164\145
-\154\145\056\040\101\172\040\145\154\152\141\162\141\163\040\154
-\145\151\162\141\163\141\040\155\145\147\164\141\154\141\154\150
-\141\164\157\040\141\040\116\145\164\114\157\143\153\040\113\146
-\164\056\040\111\156\164\145\162\156\145\164\040\150\157\156\154
-\141\160\152\141\156\040\141\040\150\164\164\160\163\072\057\057
-\167\167\167\056\156\145\164\154\157\143\153\056\156\145\164\057
-\144\157\143\163\040\143\151\155\145\156\040\166\141\147\171\040
-\153\145\162\150\145\164\157\040\141\172\040\145\154\154\145\156
-\157\162\172\145\163\100\156\145\164\154\157\143\153\056\156\145
-\164\040\145\055\155\141\151\154\040\143\151\155\145\156\056\040
-\111\115\120\117\122\124\101\116\124\041\040\124\150\145\040\151
-\163\163\165\141\156\143\145\040\141\156\144\040\164\150\145\040
-\165\163\145\040\157\146\040\164\150\151\163\040\143\145\162\164
-\151\146\151\143\141\164\145\040\151\163\040\163\165\142\152\145
-\143\164\040\164\157\040\164\150\145\040\116\145\164\114\157\143
-\153\040\103\120\123\040\141\166\141\151\154\141\142\154\145\040
-\141\164\040\150\164\164\160\163\072\057\057\167\167\167\056\156
-\145\164\154\157\143\153\056\156\145\164\057\144\157\143\163\040
-\157\162\040\142\171\040\145\055\155\141\151\154\040\141\164\040
-\143\160\163\100\156\145\164\154\157\143\153\056\156\145\164\056
-\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\003
-\201\201\000\020\255\177\327\014\062\200\012\330\206\361\171\230
-\265\255\324\315\263\066\304\226\110\301\134\315\232\331\005\056
-\237\276\120\353\364\046\024\020\055\324\146\027\370\236\301\047
-\375\361\355\344\173\113\240\154\265\253\232\127\160\246\355\240
-\244\355\056\365\375\374\275\376\115\067\010\014\274\343\226\203
-\042\365\111\033\177\113\053\264\124\301\200\174\231\116\035\320
-\214\356\320\254\345\222\372\165\126\376\144\240\023\217\270\270
-\026\235\141\005\147\200\310\320\330\245\007\002\064\230\004\215
-\063\004\324
-END
-
-# Trust for Certificate "NetLock Express (Class C) Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Express (Class C) Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\343\222\121\057\012\317\365\005\337\366\336\006\177\165\067\341
-\145\352\127\113
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\117\353\361\360\160\302\200\143\135\130\237\332\022\074\251\304
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\233\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160
-\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145
-\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172
-\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030
-\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141
-\156\171\153\151\141\144\157\153\061\064\060\062\006\003\125\004
-\003\023\053\116\145\164\114\157\143\153\040\105\170\160\162\145
-\163\163\172\040\050\103\154\141\163\163\040\103\051\040\124\141
-\156\165\163\151\164\166\141\156\171\153\151\141\144\157
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\150
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "XRamp Global CA Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "XRamp Global CA Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\036\060\034\006\003\125\004\013\023\025\167\167\167\056\170
-\162\141\155\160\163\145\143\165\162\151\164\171\056\143\157\155
-\061\044\060\042\006\003\125\004\012\023\033\130\122\141\155\160
-\040\123\145\143\165\162\151\164\171\040\123\145\162\166\151\143
-\145\163\040\111\156\143\061\055\060\053\006\003\125\004\003\023
-\044\130\122\141\155\160\040\107\154\157\142\141\154\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\036\060\034\006\003\125\004\013\023\025\167\167\167\056\170
-\162\141\155\160\163\145\143\165\162\151\164\171\056\143\157\155
-\061\044\060\042\006\003\125\004\012\023\033\130\122\141\155\160
-\040\123\145\143\165\162\151\164\171\040\123\145\162\166\151\143
-\145\163\040\111\156\143\061\055\060\053\006\003\125\004\003\023
-\044\130\122\141\155\160\040\107\154\157\142\141\154\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\120\224\154\354\030\352\325\234\115\325\227\357\165\217
-\240\255
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\060\060\202\003\030\240\003\002\001\002\002\020\120
-\224\154\354\030\352\325\234\115\325\227\357\165\217\240\255\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\202\061\013\060\011\006\003\125\004\006\023\002\125\123\061\036
-\060\034\006\003\125\004\013\023\025\167\167\167\056\170\162\141
-\155\160\163\145\143\165\162\151\164\171\056\143\157\155\061\044
-\060\042\006\003\125\004\012\023\033\130\122\141\155\160\040\123
-\145\143\165\162\151\164\171\040\123\145\162\166\151\143\145\163
-\040\111\156\143\061\055\060\053\006\003\125\004\003\023\044\130
-\122\141\155\160\040\107\154\157\142\141\154\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\060\036\027\015\060\064\061\061\060\061\061\067\061
-\064\060\064\132\027\015\063\065\060\061\060\061\060\065\063\067
-\061\071\132\060\201\202\061\013\060\011\006\003\125\004\006\023
-\002\125\123\061\036\060\034\006\003\125\004\013\023\025\167\167
-\167\056\170\162\141\155\160\163\145\143\165\162\151\164\171\056
-\143\157\155\061\044\060\042\006\003\125\004\012\023\033\130\122
-\141\155\160\040\123\145\143\165\162\151\164\171\040\123\145\162
-\166\151\143\145\163\040\111\156\143\061\055\060\053\006\003\125
-\004\003\023\044\130\122\141\155\160\040\107\154\157\142\141\154
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\060\202\001\042\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000
-\060\202\001\012\002\202\001\001\000\230\044\036\275\025\264\272
-\337\307\214\245\047\266\070\013\151\363\266\116\250\054\056\041
-\035\134\104\337\041\135\176\043\164\376\136\176\264\112\267\246
-\255\037\256\340\006\026\342\233\133\331\147\164\153\135\200\217
-\051\235\206\033\331\234\015\230\155\166\020\050\130\344\145\260
-\177\112\230\171\237\340\303\061\176\200\053\265\214\300\100\073
-\021\206\320\313\242\206\066\140\244\325\060\202\155\331\156\320
-\017\022\004\063\227\137\117\141\132\360\344\371\221\253\347\035
-\073\274\350\317\364\153\055\064\174\342\110\141\034\216\363\141
-\104\314\157\240\112\251\224\260\115\332\347\251\064\172\162\070
-\250\101\314\074\224\021\175\353\310\246\214\267\206\313\312\063
-\073\331\075\067\213\373\172\076\206\054\347\163\327\012\127\254
-\144\233\031\353\364\017\004\010\212\254\003\027\031\144\364\132
-\045\042\215\064\054\262\366\150\035\022\155\323\212\036\024\332
-\304\217\246\342\043\205\325\172\015\275\152\340\351\354\354\027
-\273\102\033\147\252\045\355\105\203\041\374\301\311\174\325\142
-\076\372\362\305\055\323\375\324\145\002\003\001\000\001\243\201
-\237\060\201\234\060\023\006\011\053\006\001\004\001\202\067\024
-\002\004\006\036\004\000\103\000\101\060\013\006\003\125\035\017
-\004\004\003\002\001\206\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026
-\004\024\306\117\242\075\006\143\204\011\234\316\142\344\004\254
-\215\134\265\351\266\033\060\066\006\003\125\035\037\004\057\060
-\055\060\053\240\051\240\047\206\045\150\164\164\160\072\057\057
-\143\162\154\056\170\162\141\155\160\163\145\143\165\162\151\164
-\171\056\143\157\155\057\130\107\103\101\056\143\162\154\060\020
-\006\011\053\006\001\004\001\202\067\025\001\004\003\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\001\001\000\221\025\071\003\001\033\147\373\112\034\371\012
-\140\133\241\332\115\227\142\371\044\123\047\327\202\144\116\220
-\056\303\111\033\053\232\334\374\250\170\147\065\361\035\360\021
-\275\267\110\343\020\366\015\337\077\322\311\266\252\125\244\110
-\272\002\333\336\131\056\025\133\073\235\026\175\107\327\067\352
-\137\115\166\022\066\273\037\327\241\201\004\106\040\243\054\155
-\251\236\001\176\077\051\316\000\223\337\375\311\222\163\211\211
-\144\236\347\053\344\034\221\054\322\271\316\175\316\157\061\231
-\323\346\276\322\036\220\360\011\024\171\134\043\253\115\322\332
-\041\037\115\231\171\235\341\317\047\237\020\233\034\210\015\260
-\212\144\101\061\270\016\154\220\044\244\233\134\161\217\272\273
-\176\034\033\333\152\200\017\041\274\351\333\246\267\100\364\262
-\213\251\261\344\357\232\032\320\075\151\231\356\250\050\243\341
-\074\263\360\262\021\234\317\174\100\346\335\347\103\175\242\330
-\072\265\251\215\362\064\231\304\324\020\341\006\375\011\204\020
-\073\356\304\114\364\354\047\174\102\302\164\174\202\212\011\311
-\264\003\045\274
-END
-
-# Trust for Certificate "XRamp Global CA Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "XRamp Global CA Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\270\001\206\321\353\234\206\245\101\004\317\060\124\363\114\122
-\267\345\130\306
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\241\013\104\263\312\020\330\000\156\235\017\330\017\222\012\321
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\036\060\034\006\003\125\004\013\023\025\167\167\167\056\170
-\162\141\155\160\163\145\143\165\162\151\164\171\056\143\157\155
-\061\044\060\042\006\003\125\004\012\023\033\130\122\141\155\160
-\040\123\145\143\165\162\151\164\171\040\123\145\162\166\151\143
-\145\163\040\111\156\143\061\055\060\053\006\003\125\004\003\023
-\044\130\122\141\155\160\040\107\154\157\142\141\154\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\120\224\154\354\030\352\325\234\115\325\227\357\165\217
-\240\255
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Go Daddy Class 2 CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Go Daddy Class 2 CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\041\060\037\006\003\125\004\012\023\030\124\150\145\040\107\157
-\040\104\141\144\144\171\040\107\162\157\165\160\054\040\111\156
-\143\056\061\061\060\057\006\003\125\004\013\023\050\107\157\040
-\104\141\144\144\171\040\103\154\141\163\163\040\062\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\041\060\037\006\003\125\004\012\023\030\124\150\145\040\107\157
-\040\104\141\144\144\171\040\107\162\157\165\160\054\040\111\156
-\143\056\061\061\060\057\006\003\125\004\013\023\050\107\157\040
-\104\141\144\144\171\040\103\154\141\163\163\040\062\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\000\060\202\002\350\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061\041
-\060\037\006\003\125\004\012\023\030\124\150\145\040\107\157\040
-\104\141\144\144\171\040\107\162\157\165\160\054\040\111\156\143
-\056\061\061\060\057\006\003\125\004\013\023\050\107\157\040\104
-\141\144\144\171\040\103\154\141\163\163\040\062\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\060\036\027\015\060\064\060\066\062\071\061\067
-\060\066\062\060\132\027\015\063\064\060\066\062\071\061\067\060
-\066\062\060\132\060\143\061\013\060\011\006\003\125\004\006\023
-\002\125\123\061\041\060\037\006\003\125\004\012\023\030\124\150
-\145\040\107\157\040\104\141\144\144\171\040\107\162\157\165\160
-\054\040\111\156\143\056\061\061\060\057\006\003\125\004\013\023
-\050\107\157\040\104\141\144\144\171\040\103\154\141\163\163\040
-\062\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\060\202\001\040\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\015
-\000\060\202\001\010\002\202\001\001\000\336\235\327\352\127\030
-\111\241\133\353\327\137\110\206\352\276\335\377\344\357\147\034
-\364\145\150\263\127\161\240\136\167\273\355\233\111\351\160\200
-\075\126\030\143\010\157\332\362\314\320\077\177\002\124\042\124
-\020\330\262\201\324\300\165\075\113\177\307\167\303\076\170\253
-\032\003\265\040\153\057\152\053\261\305\210\176\304\273\036\260
-\301\330\105\047\157\252\067\130\367\207\046\327\330\055\366\251
-\027\267\037\162\066\116\246\027\077\145\230\222\333\052\156\135
-\242\376\210\340\013\336\177\345\215\025\341\353\313\072\325\342
-\022\242\023\055\330\216\257\137\022\075\240\010\005\010\266\134
-\245\145\070\004\105\231\036\243\140\140\164\305\101\245\162\142
-\033\142\305\037\157\137\032\102\276\002\121\145\250\256\043\030
-\152\374\170\003\251\115\177\200\303\372\253\132\374\241\100\244
-\312\031\026\376\262\310\357\136\163\015\356\167\275\232\366\171
-\230\274\261\007\147\242\025\015\335\240\130\306\104\173\012\076
-\142\050\137\272\101\007\123\130\317\021\176\070\164\305\370\377
-\265\151\220\217\204\164\352\227\033\257\002\001\003\243\201\300
-\060\201\275\060\035\006\003\125\035\016\004\026\004\024\322\304
-\260\322\221\324\114\021\161\263\141\313\075\241\376\335\250\152
-\324\343\060\201\215\006\003\125\035\043\004\201\205\060\201\202
-\200\024\322\304\260\322\221\324\114\021\161\263\141\313\075\241
-\376\335\250\152\324\343\241\147\244\145\060\143\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\041\060\037\006\003\125
-\004\012\023\030\124\150\145\040\107\157\040\104\141\144\144\171
-\040\107\162\157\165\160\054\040\111\156\143\056\061\061\060\057
-\006\003\125\004\013\023\050\107\157\040\104\141\144\144\171\040
-\103\154\141\163\163\040\062\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\202
-\001\000\060\014\006\003\125\035\023\004\005\060\003\001\001\377
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\001\001\000\062\113\363\262\312\076\221\374\022\306\241\007
-\214\216\167\240\063\006\024\134\220\036\030\367\010\246\075\012
-\031\371\207\200\021\156\151\344\226\027\060\377\064\221\143\162
-\070\356\314\034\001\243\035\224\050\244\061\366\172\304\124\327
-\366\345\061\130\003\242\314\316\142\333\224\105\163\265\277\105
-\311\044\265\325\202\002\255\043\171\151\215\270\266\115\316\317
-\114\312\063\043\350\034\210\252\235\213\101\156\026\311\040\345
-\211\236\315\073\332\160\367\176\231\046\040\024\124\045\253\156
-\163\205\346\233\041\235\012\154\202\016\250\370\302\014\372\020
-\036\154\226\357\207\015\304\017\141\213\255\356\203\053\225\370
-\216\222\204\162\071\353\040\352\203\355\203\315\227\156\010\274
-\353\116\046\266\163\053\344\323\366\114\376\046\161\342\141\021
-\164\112\377\127\032\207\017\165\110\056\317\121\151\027\240\002
-\022\141\225\325\321\100\262\020\114\356\304\254\020\103\246\245
-\236\012\325\225\142\232\015\317\210\202\305\062\014\344\053\237
-\105\346\015\237\050\234\261\271\052\132\127\255\067\017\257\035
-\177\333\275\237
-END
-
-# Trust for Certificate "Go Daddy Class 2 CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Go Daddy Class 2 CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\047\226\272\346\077\030\001\342\167\046\033\240\327\167\160\002
-\217\040\356\344
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\221\336\006\045\253\332\375\062\027\014\273\045\027\052\204\147
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\041\060\037\006\003\125\004\012\023\030\124\150\145\040\107\157
-\040\104\141\144\144\171\040\107\162\157\165\160\054\040\111\156
-\143\056\061\061\060\057\006\003\125\004\013\023\050\107\157\040
-\104\141\144\144\171\040\103\154\141\163\163\040\062\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Starfield Class 2 CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Starfield Class 2 CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\150\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\045\060\043\006\003\125\004\012\023\034\123\164\141\162\146\151
-\145\154\144\040\124\145\143\150\156\157\154\157\147\151\145\163
-\054\040\111\156\143\056\061\062\060\060\006\003\125\004\013\023
-\051\123\164\141\162\146\151\145\154\144\040\103\154\141\163\163
-\040\062\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\150\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\045\060\043\006\003\125\004\012\023\034\123\164\141\162\146\151
-\145\154\144\040\124\145\143\150\156\157\154\157\147\151\145\163
-\054\040\111\156\143\056\061\062\060\060\006\003\125\004\013\023
-\051\123\164\141\162\146\151\145\154\144\040\103\154\141\163\163
-\040\062\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\017\060\202\002\367\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\150\061\013\060\011\006\003\125\004\006\023\002\125\123\061\045
-\060\043\006\003\125\004\012\023\034\123\164\141\162\146\151\145
-\154\144\040\124\145\143\150\156\157\154\157\147\151\145\163\054
-\040\111\156\143\056\061\062\060\060\006\003\125\004\013\023\051
-\123\164\141\162\146\151\145\154\144\040\103\154\141\163\163\040
-\062\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\060\036\027\015\060\064\060
-\066\062\071\061\067\063\071\061\066\132\027\015\063\064\060\066
-\062\071\061\067\063\071\061\066\132\060\150\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\045\060\043\006\003\125\004
-\012\023\034\123\164\141\162\146\151\145\154\144\040\124\145\143
-\150\156\157\154\157\147\151\145\163\054\040\111\156\143\056\061
-\062\060\060\006\003\125\004\013\023\051\123\164\141\162\146\151
-\145\154\144\040\103\154\141\163\163\040\062\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\060\202\001\040\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\015\000\060\202\001\010\002
-\202\001\001\000\267\062\310\376\351\161\246\004\205\255\014\021
-\144\337\316\115\357\310\003\030\207\077\241\253\373\074\246\237
-\360\303\241\332\324\330\156\053\123\220\373\044\244\076\204\360
-\236\350\137\354\345\047\104\365\050\246\077\173\336\340\052\360
-\310\257\123\057\236\312\005\001\223\036\217\146\034\071\247\115
-\372\132\266\163\004\045\146\353\167\177\347\131\306\112\231\045
-\024\124\353\046\307\363\177\031\325\060\160\217\257\260\106\052
-\377\255\353\051\355\327\237\252\004\207\243\324\371\211\245\064
-\137\333\103\221\202\066\331\146\074\261\270\271\202\375\234\072
-\076\020\310\073\357\006\145\146\172\233\031\030\075\377\161\121
-\074\060\056\137\276\075\167\163\262\135\006\154\303\043\126\232
-\053\205\046\222\034\247\002\263\344\077\015\257\010\171\202\270
-\066\075\352\234\323\065\263\274\151\312\365\314\235\350\375\144
-\215\027\200\063\156\136\112\135\231\311\036\207\264\235\032\300
-\325\156\023\065\043\136\337\233\137\075\357\326\367\166\302\352
-\076\273\170\015\034\102\147\153\004\330\370\326\332\157\213\362
-\104\240\001\253\002\001\003\243\201\305\060\201\302\060\035\006
-\003\125\035\016\004\026\004\024\277\137\267\321\316\335\037\206
-\364\133\125\254\334\327\020\302\016\251\210\347\060\201\222\006
-\003\125\035\043\004\201\212\060\201\207\200\024\277\137\267\321
-\316\335\037\206\364\133\125\254\334\327\020\302\016\251\210\347
-\241\154\244\152\060\150\061\013\060\011\006\003\125\004\006\023
-\002\125\123\061\045\060\043\006\003\125\004\012\023\034\123\164
-\141\162\146\151\145\154\144\040\124\145\143\150\156\157\154\157
-\147\151\145\163\054\040\111\156\143\056\061\062\060\060\006\003
-\125\004\013\023\051\123\164\141\162\146\151\145\154\144\040\103
-\154\141\163\163\040\062\040\103\145\162\164\151\146\151\143\141
-\164\151\157\156\040\101\165\164\150\157\162\151\164\171\202\001
-\000\060\014\006\003\125\035\023\004\005\060\003\001\001\377\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202
-\001\001\000\005\235\077\210\235\321\311\032\125\241\254\151\363
-\363\131\332\233\001\207\032\117\127\251\241\171\011\052\333\367
-\057\262\036\314\307\136\152\330\203\207\241\227\357\111\065\076
-\167\006\101\130\142\277\216\130\270\012\147\077\354\263\335\041
-\146\037\311\124\372\162\314\075\114\100\330\201\257\167\236\203
-\172\273\242\307\365\064\027\216\331\021\100\364\374\054\052\115
-\025\177\247\142\135\056\045\323\000\013\040\032\035\150\371\027
-\270\364\275\213\355\050\131\335\115\026\213\027\203\310\262\145
-\307\055\172\245\252\274\123\206\155\335\127\244\312\370\040\101
-\013\150\360\364\373\164\276\126\135\172\171\365\371\035\205\343
-\055\225\276\365\161\220\103\314\215\037\232\000\012\207\051\351
-\125\042\130\000\043\352\343\022\103\051\133\107\010\335\214\101
-\152\145\006\250\345\041\252\101\264\225\041\225\271\175\321\064
-\253\023\326\255\274\334\342\075\071\315\275\076\165\160\241\030
-\131\003\311\042\264\217\234\325\136\052\327\245\266\324\012\155
-\370\267\100\021\106\232\037\171\016\142\277\017\227\354\340\057
-\037\027\224
-END
-
-# Trust for Certificate "Starfield Class 2 CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Starfield Class 2 CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\255\176\034\050\260\144\357\217\140\003\100\040\024\303\320\343
-\067\016\265\212
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\062\112\113\273\310\143\151\233\276\164\232\306\335\035\106\044
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\150\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\045\060\043\006\003\125\004\012\023\034\123\164\141\162\146\151
-\145\154\144\040\124\145\143\150\156\157\154\157\147\151\145\163
-\054\040\111\156\143\056\061\062\060\060\006\003\125\004\013\023
-\051\123\164\141\162\146\151\145\154\144\040\103\154\141\163\163
-\040\062\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "StartCom Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "StartCom Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061
-\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103
-\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013
-\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154
-\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147
-\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123
-\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061
-\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103
-\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013
-\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154
-\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147
-\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123
-\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\007\311\060\202\005\261\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026
-\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157
-\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013\023
-\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154\040
-\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147\156
-\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123\164
-\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143\141
-\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\036
-\027\015\060\066\060\071\061\067\061\071\064\066\063\066\132\027
-\015\063\066\060\071\061\067\061\071\064\066\063\066\132\060\175
-\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026\060
-\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157\155
-\040\114\164\144\056\061\053\060\051\006\003\125\004\013\023\042
-\123\145\143\165\162\145\040\104\151\147\151\164\141\154\040\103
-\145\162\164\151\146\151\143\141\164\145\040\123\151\147\156\151
-\156\147\061\051\060\047\006\003\125\004\003\023\040\123\164\141
-\162\164\103\157\155\040\103\145\162\164\151\146\151\143\141\164
-\151\157\156\040\101\165\164\150\157\162\151\164\171\060\202\002
-\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\202\002\017\000\060\202\002\012\002\202\002\001\000\301\210
-\333\011\274\154\106\174\170\237\225\173\265\063\220\362\162\142
-\326\301\066\040\042\044\136\316\351\167\362\103\012\242\006\144
-\244\314\216\066\370\070\346\043\360\156\155\261\074\335\162\243
-\205\034\241\323\075\264\063\053\323\057\257\376\352\260\101\131
-\147\266\304\006\175\012\236\164\205\326\171\114\200\067\172\337
-\071\005\122\131\367\364\033\106\103\244\322\205\205\322\303\161
-\363\165\142\064\272\054\212\177\036\217\356\355\064\320\021\307
-\226\315\122\075\272\063\326\335\115\336\013\073\112\113\237\302
-\046\057\372\265\026\034\162\065\167\312\074\135\346\312\341\046
-\213\032\066\166\134\001\333\164\024\045\376\355\265\240\210\017
-\335\170\312\055\037\007\227\060\001\055\162\171\372\106\326\023
-\052\250\271\246\253\203\111\035\345\362\357\335\344\001\216\030
-\012\217\143\123\026\205\142\251\016\031\072\314\265\146\246\302
-\153\164\007\344\053\341\166\076\264\155\330\366\104\341\163\142
-\037\073\304\276\240\123\126\045\154\121\011\367\252\253\312\277
-\166\375\155\233\363\235\333\277\075\146\274\014\126\252\257\230
-\110\225\072\113\337\247\130\120\331\070\165\251\133\352\103\014
-\002\377\231\353\350\154\115\160\133\051\145\234\335\252\135\314
-\257\001\061\354\014\353\322\215\350\352\234\173\346\156\367\047
-\146\014\032\110\327\156\102\343\077\336\041\076\173\341\015\160
-\373\143\252\250\154\032\124\264\134\045\172\311\242\311\213\026
-\246\273\054\176\027\136\005\115\130\156\022\035\001\356\022\020
-\015\306\062\177\030\377\374\364\372\315\156\221\350\066\111\276
-\032\110\151\213\302\226\115\032\022\262\151\027\301\012\220\326
-\372\171\042\110\277\272\173\151\370\160\307\372\172\067\330\330
-\015\322\166\117\127\377\220\267\343\221\322\335\357\302\140\267
-\147\072\335\376\252\234\360\324\213\177\162\042\316\306\237\227
-\266\370\257\212\240\020\250\331\373\030\306\266\265\134\122\074
-\211\266\031\052\163\001\012\017\003\263\022\140\362\172\057\201
-\333\243\156\377\046\060\227\365\213\335\211\127\266\255\075\263
-\257\053\305\267\166\002\360\245\326\053\232\206\024\052\162\366
-\343\063\214\135\011\113\023\337\273\214\164\023\122\113\002\003
-\001\000\001\243\202\002\122\060\202\002\116\060\014\006\003\125
-\035\023\004\005\060\003\001\001\377\060\013\006\003\125\035\017
-\004\004\003\002\001\256\060\035\006\003\125\035\016\004\026\004
-\024\116\013\357\032\244\100\133\245\027\151\207\060\312\064\150
-\103\320\101\256\362\060\144\006\003\125\035\037\004\135\060\133
-\060\054\240\052\240\050\206\046\150\164\164\160\072\057\057\143
-\145\162\164\056\163\164\141\162\164\143\157\155\056\157\162\147
-\057\163\146\163\143\141\055\143\162\154\056\143\162\154\060\053
-\240\051\240\047\206\045\150\164\164\160\072\057\057\143\162\154
-\056\163\164\141\162\164\143\157\155\056\157\162\147\057\163\146
-\163\143\141\055\143\162\154\056\143\162\154\060\202\001\135\006
-\003\125\035\040\004\202\001\124\060\202\001\120\060\202\001\114
-\006\013\053\006\001\004\001\201\265\067\001\001\001\060\202\001
-\073\060\057\006\010\053\006\001\005\005\007\002\001\026\043\150
-\164\164\160\072\057\057\143\145\162\164\056\163\164\141\162\164
-\143\157\155\056\157\162\147\057\160\157\154\151\143\171\056\160
-\144\146\060\065\006\010\053\006\001\005\005\007\002\001\026\051
-\150\164\164\160\072\057\057\143\145\162\164\056\163\164\141\162
-\164\143\157\155\056\157\162\147\057\151\156\164\145\162\155\145
-\144\151\141\164\145\056\160\144\146\060\201\320\006\010\053\006
-\001\005\005\007\002\002\060\201\303\060\047\026\040\123\164\141
-\162\164\040\103\157\155\155\145\162\143\151\141\154\040\050\123
-\164\141\162\164\103\157\155\051\040\114\164\144\056\060\003\002
-\001\001\032\201\227\114\151\155\151\164\145\144\040\114\151\141
-\142\151\154\151\164\171\054\040\162\145\141\144\040\164\150\145
-\040\163\145\143\164\151\157\156\040\052\114\145\147\141\154\040
-\114\151\155\151\164\141\164\151\157\156\163\052\040\157\146\040
-\164\150\145\040\123\164\141\162\164\103\157\155\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\040\120\157\154\151\143\171\040\141\166\141\151
-\154\141\142\154\145\040\141\164\040\150\164\164\160\072\057\057
-\143\145\162\164\056\163\164\141\162\164\143\157\155\056\157\162
-\147\057\160\157\154\151\143\171\056\160\144\146\060\021\006\011
-\140\206\110\001\206\370\102\001\001\004\004\003\002\000\007\060
-\070\006\011\140\206\110\001\206\370\102\001\015\004\053\026\051
-\123\164\141\162\164\103\157\155\040\106\162\145\145\040\123\123
-\114\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\101\165\164\150\157\162\151\164\171\060\015\006\011\052\206\110
-\206\367\015\001\001\005\005\000\003\202\002\001\000\026\154\231
-\364\146\014\064\365\320\205\136\175\012\354\332\020\116\070\034
-\136\337\246\045\005\113\221\062\301\350\073\361\075\335\104\011
-\133\007\111\212\051\313\146\002\267\261\232\367\045\230\011\074
-\216\033\341\335\066\207\053\113\273\150\323\071\146\075\240\046
-\307\362\071\221\035\121\253\202\173\176\325\316\132\344\342\003
-\127\160\151\227\010\371\136\130\246\012\337\214\006\232\105\026
-\026\070\012\136\127\366\142\307\172\002\005\346\274\036\265\362
-\236\364\251\051\203\370\262\024\343\156\050\207\104\303\220\032
-\336\070\251\074\254\103\115\144\105\316\335\050\251\134\362\163
-\173\004\370\027\350\253\261\363\056\134\144\156\163\061\072\022
-\270\274\263\021\344\175\217\201\121\232\073\215\211\364\115\223
-\146\173\074\003\355\323\232\035\232\363\145\120\365\240\320\165
-\237\057\257\360\352\202\103\230\370\151\234\211\171\304\103\216
-\106\162\343\144\066\022\257\367\045\036\070\211\220\167\176\303
-\153\152\271\303\313\104\113\254\170\220\213\347\307\054\036\113
-\021\104\310\064\122\047\315\012\135\237\205\301\211\325\032\170
-\362\225\020\123\062\335\200\204\146\165\331\265\150\050\373\141
-\056\276\204\250\070\300\231\022\206\245\036\147\144\255\006\056
-\057\251\160\205\307\226\017\174\211\145\365\216\103\124\016\253
-\335\245\200\071\224\140\300\064\311\226\160\054\243\022\365\037
-\110\173\275\034\176\153\267\235\220\364\042\073\256\370\374\052
-\312\372\202\122\240\357\257\113\125\223\353\301\265\360\042\213
-\254\064\116\046\042\004\241\207\054\165\112\267\345\175\023\327
-\270\014\144\300\066\322\311\057\206\022\214\043\011\301\033\202
-\073\163\111\243\152\127\207\224\345\326\170\305\231\103\143\343
-\115\340\167\055\341\145\231\162\151\004\032\107\011\346\017\001
-\126\044\373\037\277\016\171\251\130\056\271\304\011\001\176\225
-\272\155\000\006\076\262\352\112\020\071\330\320\053\365\277\354
-\165\277\227\002\305\011\033\010\334\125\067\342\201\373\067\204
-\103\142\040\312\347\126\113\145\352\376\154\301\044\223\044\241
-\064\353\005\377\232\042\256\233\175\077\361\145\121\012\246\060
-\152\263\364\210\034\200\015\374\162\212\350\203\136
-END
-
-# Trust for Certificate "StartCom Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "StartCom Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\076\053\367\362\003\033\226\363\214\346\304\330\250\135\076\055
-\130\107\152\017
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\042\115\217\212\374\367\065\302\273\127\064\220\173\213\042\026
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061
-\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103
-\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013
-\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154
-\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147
-\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123
-\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Taiwan GRCA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Taiwan GRCA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156
-\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156
-\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343
-\136\366
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\162\060\202\003\132\240\003\002\001\002\002\020\037
-\235\131\132\327\057\302\006\104\245\200\010\151\343\136\366\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\077
-\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060\060
-\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155\145
-\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060
-\036\027\015\060\062\061\062\060\065\061\063\062\063\063\063\132
-\027\015\063\062\061\062\060\065\061\063\062\063\063\063\132\060
-\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060
-\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155
-\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001
-\000\232\045\270\354\314\242\165\250\173\367\316\133\131\212\311
-\321\206\022\010\124\354\234\362\347\106\366\210\363\174\351\245
-\337\114\107\066\244\033\001\034\177\036\127\212\215\303\305\321
-\041\343\332\044\077\110\053\373\237\056\241\224\347\054\034\223
-\321\277\033\001\207\123\231\316\247\365\012\041\166\167\377\251
-\267\306\163\224\117\106\367\020\111\067\372\250\131\111\135\152
-\201\007\126\362\212\371\006\320\367\160\042\115\264\267\101\271
-\062\270\261\360\261\303\234\077\160\375\123\335\201\252\330\143
-\170\366\330\123\156\241\254\152\204\044\162\124\206\306\322\262
-\312\034\016\171\201\326\265\160\142\010\001\056\116\117\016\325
-\021\257\251\257\345\232\277\334\314\207\155\046\344\311\127\242
-\373\226\371\314\341\077\123\214\154\114\176\233\123\010\013\154
-\027\373\147\310\302\255\261\315\200\264\227\334\166\001\026\025
-\351\152\327\244\341\170\107\316\206\325\373\061\363\372\061\276
-\064\252\050\373\160\114\035\111\307\257\054\235\155\146\246\266
-\215\144\176\265\040\152\235\073\201\266\217\100\000\147\113\211
-\206\270\314\145\376\025\123\351\004\301\326\137\035\104\327\012
-\057\047\232\106\175\241\015\165\255\124\206\025\334\111\073\361
-\226\316\017\233\240\354\243\172\135\276\325\052\165\102\345\173
-\336\245\266\252\257\050\254\254\220\254\070\267\325\150\065\046
-\172\334\367\073\363\375\105\233\321\273\103\170\156\157\361\102
-\124\152\230\360\015\255\227\351\122\136\351\325\152\162\336\152
-\367\033\140\024\364\245\344\266\161\147\252\037\352\342\115\301
-\102\100\376\147\106\027\070\057\107\077\161\234\256\345\041\312
-\141\055\155\007\250\204\174\055\356\121\045\361\143\220\236\375
-\341\127\210\153\357\212\043\155\261\346\275\077\255\321\075\226
-\013\205\215\315\153\047\273\267\005\233\354\273\221\251\012\007
-\022\002\227\116\040\220\360\377\015\036\342\101\073\323\100\072
-\347\215\135\332\146\344\002\260\007\122\230\134\016\216\063\234
-\302\246\225\373\125\031\156\114\216\256\113\017\275\301\070\115
-\136\217\204\035\146\315\305\140\226\264\122\132\005\211\216\225
-\172\230\301\221\074\225\043\262\016\364\171\264\311\174\301\112
-\041\002\003\001\000\001\243\152\060\150\060\035\006\003\125\035
-\016\004\026\004\024\314\314\357\314\051\140\244\073\261\222\266
-\074\372\062\142\217\254\045\025\073\060\014\006\003\125\035\023
-\004\005\060\003\001\001\377\060\071\006\004\147\052\007\000\004
-\061\060\057\060\055\002\001\000\060\011\006\005\053\016\003\002
-\032\005\000\060\007\006\005\147\052\003\000\000\004\024\003\233
-\360\042\023\377\225\050\066\323\334\236\300\062\373\061\072\212
-\121\145\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\003\202\002\001\000\100\200\112\372\046\311\316\136\060\335
-\117\206\164\166\130\365\256\263\203\063\170\244\172\164\027\031
-\116\351\122\265\271\340\012\164\142\252\150\312\170\240\114\232
-\216\054\043\056\325\152\022\044\277\324\150\323\212\320\330\234
-\237\264\037\014\336\070\176\127\070\374\215\342\117\136\014\237
-\253\073\322\377\165\227\313\244\343\147\010\377\345\300\026\265
-\110\001\175\351\371\012\377\033\345\152\151\277\170\041\250\302
-\247\043\251\206\253\166\126\350\016\014\366\023\335\052\146\212
-\144\111\075\032\030\207\220\004\237\102\122\267\117\313\376\107
-\101\166\065\357\377\000\166\066\105\062\233\306\106\205\135\342
-\044\260\036\343\110\226\230\127\107\224\125\172\017\101\261\104
-\044\363\301\376\032\153\277\210\375\301\246\332\223\140\136\201
-\112\231\040\234\110\146\031\265\000\171\124\017\270\054\057\113
-\274\251\135\133\140\177\214\207\245\340\122\143\052\276\330\073
-\205\100\025\376\036\266\145\077\305\113\332\176\265\172\065\051
-\243\056\172\230\140\042\243\364\175\047\116\055\352\264\164\074
-\351\017\244\063\017\020\021\274\023\001\326\345\016\323\277\265
-\022\242\341\105\043\300\314\010\156\141\267\211\253\203\343\044
-\036\346\135\007\347\037\040\076\317\147\310\347\254\060\155\047
-\113\150\156\113\052\134\002\010\064\333\370\166\344\147\243\046
-\234\077\242\062\302\112\305\201\030\061\020\126\252\204\357\055
-\012\377\270\037\167\322\277\245\130\240\142\344\327\113\221\165
-\215\211\200\230\176\155\313\123\116\136\257\366\262\227\205\227
-\271\332\125\006\271\044\356\327\306\070\036\143\033\022\073\225
-\341\130\254\362\337\204\325\137\231\057\015\125\133\346\070\333
-\056\077\162\351\110\205\313\273\051\023\217\036\070\125\271\363
-\262\304\060\231\043\116\135\362\110\241\022\014\334\022\220\011
-\220\124\221\003\074\107\345\325\311\145\340\267\113\175\354\107
-\323\263\013\076\255\236\320\164\000\016\353\275\121\255\300\336
-\054\300\303\152\376\357\334\013\247\372\106\337\140\333\234\246
-\131\120\165\043\151\163\223\262\371\374\002\323\107\346\161\316
-\020\002\356\047\214\204\377\254\105\015\023\134\203\062\340\045
-\245\206\054\174\364\022
-END
-
-# Trust for Certificate "Taiwan GRCA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Taiwan GRCA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\364\213\021\277\336\253\276\224\124\040\161\346\101\336\153\276
-\210\053\100\271
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\067\205\104\123\062\105\037\040\360\363\225\341\045\304\103\116
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156
-\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343
-\136\366
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Firmaprofesional Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Firmaprofesional Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123
-\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165
-\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145
-\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101
-\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164
-\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160
-\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101
-\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206
-\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155
-\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123
-\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165
-\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145
-\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101
-\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164
-\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160
-\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101
-\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206
-\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155
-\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\127\060\202\003\077\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156
-\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154
-\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165
-\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151
-\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162
-\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066
-\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110
-\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141
-\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060
-\036\027\015\060\061\061\060\062\064\062\062\060\060\060\060\132
-\027\015\061\063\061\060\062\064\062\062\060\060\060\060\132\060
-\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156
-\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154
-\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165
-\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151
-\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162
-\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066
-\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110
-\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141
-\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060
-\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001
-\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000
-\347\043\003\157\157\043\245\136\170\316\225\054\355\224\036\156
-\012\236\001\307\352\060\321\054\235\335\067\350\233\230\171\126
-\323\374\163\337\320\212\336\125\217\121\371\132\352\336\265\160
-\304\355\244\355\377\243\015\156\017\144\120\061\257\001\047\130
-\256\376\154\247\112\057\027\055\323\163\325\023\034\217\131\245
-\064\054\035\124\004\105\315\150\270\240\300\003\245\317\205\102
-\107\225\050\133\317\357\200\154\340\220\227\212\001\074\035\363
-\207\020\060\046\110\175\327\374\351\235\221\161\377\101\232\251
-\100\265\067\234\051\040\117\037\122\343\240\175\023\155\124\267
-\012\336\351\152\116\007\254\254\031\137\334\176\142\164\366\262
-\005\000\272\205\240\375\035\070\156\313\132\273\206\274\224\147
-\063\065\203\054\037\043\315\370\310\221\161\314\227\213\357\256
-\017\334\051\003\033\300\071\353\160\355\301\156\016\330\147\013
-\211\251\274\065\344\357\266\064\264\245\266\304\055\245\276\320
-\303\224\044\110\333\337\226\323\000\265\146\032\213\146\005\017
-\335\077\077\313\077\252\136\232\112\370\264\112\357\225\067\033
-\002\003\001\000\001\243\201\237\060\201\234\060\052\006\003\125
-\035\021\004\043\060\041\206\037\150\164\164\160\072\057\057\167
-\167\167\056\146\151\162\155\141\160\162\157\146\145\163\151\157
-\156\141\154\056\143\157\155\060\022\006\003\125\035\023\001\001
-\377\004\010\060\006\001\001\377\002\001\001\060\053\006\003\125
-\035\020\004\044\060\042\200\017\062\060\060\061\061\060\062\064
-\062\062\060\060\060\060\132\201\017\062\060\061\063\061\060\062
-\064\062\062\060\060\060\060\132\060\016\006\003\125\035\017\001
-\001\377\004\004\003\002\001\006\060\035\006\003\125\035\016\004
-\026\004\024\063\013\240\146\321\352\332\316\336\142\223\004\050
-\122\265\024\177\070\150\267\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\003\202\001\001\000\107\163\376\215\047
-\124\360\365\324\167\234\047\171\127\127\267\025\126\354\307\330
-\130\267\001\002\364\063\355\223\120\210\236\174\106\261\275\077
-\024\157\361\263\107\110\213\214\227\006\327\352\176\243\134\052
-\273\115\057\107\342\370\071\006\311\234\056\061\032\003\170\364
-\274\070\306\042\213\063\061\360\026\004\004\175\371\166\344\113
-\327\300\346\203\354\131\314\077\336\377\117\153\267\147\176\246
-\206\201\062\043\003\235\310\367\137\301\112\140\245\222\251\261
-\244\240\140\303\170\207\263\042\363\052\353\133\251\355\005\253
-\067\017\261\342\323\225\166\143\126\164\214\130\162\033\067\345
-\144\241\276\115\014\223\230\014\227\366\207\155\263\077\347\313
-\200\246\355\210\307\137\120\142\002\350\231\164\026\320\346\264
-\071\361\047\313\310\100\326\343\206\020\251\043\022\222\340\151
-\101\143\247\257\045\013\300\305\222\313\036\230\243\132\272\305
-\063\017\240\227\001\335\177\340\173\326\006\124\317\241\342\115
-\070\353\113\120\265\313\046\364\312\332\160\112\152\241\342\171
-\252\341\247\063\366\375\112\037\366\331\140
-END
-
-# Trust for Certificate "Firmaprofesional Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Firmaprofesional Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\251\142\217\113\230\251\033\110\065\272\322\301\106\062\206\273
-\146\144\152\214
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\021\222\171\100\074\261\203\100\345\253\146\112\147\222\200\337
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123
-\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165
-\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145
-\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101
-\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164
-\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160
-\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101
-\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206
-\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155
-\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Wells Fargo Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Wells Fargo Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163
-\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023
-\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127
-\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040
-\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163
-\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023
-\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127
-\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040
-\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\071\344\227\236
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\345\060\202\002\315\240\003\002\001\002\002\004\071
-\344\227\236\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\201\202\061\013\060\011\006\003\125\004\006\023\002
-\125\123\061\024\060\022\006\003\125\004\012\023\013\127\145\154
-\154\163\040\106\141\162\147\157\061\054\060\052\006\003\125\004
-\013\023\043\127\145\154\154\163\040\106\141\162\147\157\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\061\057\060\055\006\003\125\004\003\023
-\046\127\145\154\154\163\040\106\141\162\147\157\040\122\157\157
-\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165
-\164\150\157\162\151\164\171\060\036\027\015\060\060\061\060\061
-\061\061\066\064\061\062\070\132\027\015\062\061\060\061\061\064
-\061\066\064\061\062\070\132\060\201\202\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\024\060\022\006\003\125\004\012
-\023\013\127\145\154\154\163\040\106\141\162\147\157\061\054\060
-\052\006\003\125\004\013\023\043\127\145\154\154\163\040\106\141
-\162\147\157\040\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\101\165\164\150\157\162\151\164\171\061\057\060\055\006
-\003\125\004\003\023\046\127\145\154\154\163\040\106\141\162\147
-\157\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141
-\164\145\040\101\165\164\150\157\162\151\164\171\060\202\001\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\001\017\000\060\202\001\012\002\202\001\001\000\325\250\063
-\073\046\371\064\377\315\233\176\345\004\107\316\000\342\175\167
-\347\061\302\056\047\245\115\150\271\061\272\215\103\131\227\307
-\163\252\177\075\134\100\236\005\345\241\342\211\331\114\270\077
-\233\371\014\264\310\142\031\054\105\256\221\036\163\161\101\304
-\113\023\375\160\302\045\254\042\365\165\013\267\123\344\245\053
-\335\316\275\034\072\172\303\367\023\217\046\124\234\026\153\153
-\257\373\330\226\261\140\232\110\340\045\042\044\171\064\316\016
-\046\000\013\116\253\375\213\316\202\327\057\010\160\150\301\250
-\012\371\164\117\007\253\244\371\342\203\176\047\163\164\076\270
-\371\070\102\374\245\250\133\110\043\263\353\343\045\262\200\256
-\226\324\012\234\302\170\232\306\150\030\256\067\142\067\136\121
-\165\250\130\143\300\121\356\100\170\176\250\257\032\240\341\260
-\170\235\120\214\173\347\263\374\216\043\260\333\145\000\160\204
-\001\010\000\024\156\124\206\232\272\314\371\067\020\366\340\336
-\204\055\235\244\205\067\323\207\343\025\320\301\027\220\176\031
-\041\152\022\251\166\375\022\002\351\117\041\136\027\002\003\001
-\000\001\243\141\060\137\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\114\006\003\125\035\040\004\105
-\060\103\060\101\006\013\140\206\110\001\206\373\173\207\007\001
-\013\060\062\060\060\006\010\053\006\001\005\005\007\002\001\026
-\044\150\164\164\160\072\057\057\167\167\167\056\167\145\154\154
-\163\146\141\162\147\157\056\143\157\155\057\143\145\162\164\160
-\157\154\151\143\171\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\003\202\001\001\000\322\047\335\234\012\167\053
-\273\042\362\002\265\112\112\221\371\321\055\276\344\273\032\150
-\357\016\244\000\351\356\347\357\356\366\371\345\164\244\302\330
-\122\130\304\164\373\316\153\265\073\051\171\030\132\357\233\355
-\037\153\066\356\110\045\045\024\266\126\242\020\350\356\247\177
-\320\077\243\320\303\135\046\356\007\314\303\301\044\041\207\036
-\337\052\022\123\157\101\026\347\355\256\224\372\214\162\372\023
-\107\360\074\176\256\175\021\072\023\354\355\372\157\162\144\173
-\235\175\177\046\375\172\373\045\255\352\076\051\177\114\343\000
-\127\062\260\263\351\355\123\027\331\213\262\024\016\060\350\345
-\325\023\306\144\257\304\000\325\330\130\044\374\365\217\354\361
-\307\175\245\333\017\047\321\306\362\100\210\346\037\366\141\250
-\364\102\310\271\067\323\251\276\054\126\170\302\162\233\131\135
-\065\100\212\350\116\143\032\266\351\040\152\121\342\316\244\220
-\337\166\160\231\134\160\103\115\267\266\247\031\144\116\222\267
-\305\221\074\177\110\026\145\173\026\375\313\374\373\331\325\326
-\117\041\145\073\112\177\107\243\373
-END
-
-# Trust for Certificate "Wells Fargo Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Wells Fargo Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\223\346\253\042\003\003\265\043\050\334\332\126\236\272\344\321
-\321\314\373\145
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\040\013\112\172\210\247\251\102\206\212\137\164\126\173\210\005
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163
-\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023
-\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127
-\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040
-\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150
-\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\071\344\227\236
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Swisscom Root CA 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Swisscom Root CA 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061
-\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143
-\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147
-\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145
-\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125
-\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157
-\164\040\103\101\040\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061
-\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143
-\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147
-\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145
-\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125
-\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157
-\164\040\103\101\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235
-\250\066
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\331\060\202\003\301\240\003\002\001\002\002\020\134
-\013\205\134\013\347\131\101\337\127\314\077\177\235\250\066\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\144
-\061\013\060\011\006\003\125\004\006\023\002\143\150\061\021\060
-\017\006\003\125\004\012\023\010\123\167\151\163\163\143\157\155
-\061\045\060\043\006\003\125\004\013\023\034\104\151\147\151\164
-\141\154\040\103\145\162\164\151\146\151\143\141\164\145\040\123
-\145\162\166\151\143\145\163\061\033\060\031\006\003\125\004\003
-\023\022\123\167\151\163\163\143\157\155\040\122\157\157\164\040
-\103\101\040\061\060\036\027\015\060\065\060\070\061\070\061\062
-\060\066\062\060\132\027\015\062\065\060\070\061\070\062\062\060
-\066\062\060\132\060\144\061\013\060\011\006\003\125\004\006\023
-\002\143\150\061\021\060\017\006\003\125\004\012\023\010\123\167
-\151\163\163\143\157\155\061\045\060\043\006\003\125\004\013\023
-\034\104\151\147\151\164\141\154\040\103\145\162\164\151\146\151
-\143\141\164\145\040\123\145\162\166\151\143\145\163\061\033\060
-\031\006\003\125\004\003\023\022\123\167\151\163\163\143\157\155
-\040\122\157\157\164\040\103\101\040\061\060\202\002\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002
-\017\000\060\202\002\012\002\202\002\001\000\320\271\260\250\014
-\331\273\077\041\370\033\325\063\223\200\026\145\040\165\262\075
-\233\140\155\106\310\214\061\157\027\303\372\232\154\126\355\074
-\305\221\127\303\315\253\226\111\220\052\031\113\036\243\155\127
-\335\361\053\142\050\165\105\136\252\326\133\372\013\045\330\241
-\026\371\034\304\056\346\225\052\147\314\320\051\156\074\205\064
-\070\141\111\261\000\237\326\072\161\137\115\155\316\137\271\251
-\344\211\177\152\122\372\312\233\362\334\251\371\235\231\107\077
-\116\051\137\264\246\215\135\173\013\231\021\003\003\376\347\333
-\333\243\377\035\245\315\220\036\001\037\065\260\177\000\333\220
-\157\306\176\173\321\356\172\172\247\252\014\127\157\244\155\305
-\023\073\260\245\331\355\062\034\264\136\147\213\124\334\163\207
-\345\323\027\174\146\120\162\135\324\032\130\301\331\317\330\211
-\002\157\247\111\264\066\135\320\244\336\007\054\266\165\267\050
-\221\326\227\276\050\365\230\036\352\133\046\311\275\260\227\163
-\332\256\221\046\353\150\301\371\071\025\326\147\113\012\155\117
-\313\317\260\344\102\161\214\123\171\347\356\341\333\035\240\156
-\035\214\032\167\065\134\026\036\053\123\037\064\213\321\154\374
-\362\147\007\172\365\255\355\326\232\253\241\261\113\341\314\067
-\137\375\177\315\115\256\270\037\234\103\371\052\130\125\103\105
-\274\226\315\160\016\374\311\343\146\272\116\215\073\201\313\025
-\144\173\271\224\350\135\063\122\205\161\056\117\216\242\006\021
-\121\311\343\313\241\156\061\010\144\014\302\322\074\365\066\350
-\327\320\016\170\043\040\221\311\044\052\145\051\133\042\367\041
-\316\203\136\244\363\336\113\323\150\217\106\165\134\203\011\156
-\051\153\304\160\214\365\235\327\040\057\377\106\322\053\070\302
-\057\165\034\075\176\332\245\357\036\140\205\151\102\323\314\370
-\143\376\036\103\071\205\246\266\143\101\020\263\163\036\274\323
-\372\312\175\026\107\342\247\325\320\243\212\012\010\226\142\126
-\156\064\333\331\002\271\060\165\343\004\322\347\217\302\260\021
-\100\012\254\325\161\002\142\213\061\276\335\306\043\130\061\102
-\103\055\164\371\306\236\246\212\017\351\376\277\203\346\103\127
-\044\272\357\106\064\252\327\022\001\070\355\002\003\001\000\001
-\243\201\206\060\201\203\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\206\060\035\006\003\125\035\041\004\026\060
-\024\060\022\006\007\140\205\164\001\123\000\001\006\007\140\205
-\164\001\123\000\001\060\022\006\003\125\035\023\001\001\377\004
-\010\060\006\001\001\377\002\001\007\060\037\006\003\125\035\043
-\004\030\060\026\200\024\003\045\057\336\157\202\001\072\134\054
-\334\053\241\151\265\147\324\214\323\375\060\035\006\003\125\035
-\016\004\026\004\024\003\045\057\336\157\202\001\072\134\054\334
-\053\241\151\265\147\324\214\323\375\060\015\006\011\052\206\110
-\206\367\015\001\001\005\005\000\003\202\002\001\000\065\020\313
-\354\246\004\015\015\017\315\300\333\253\250\362\210\227\014\337
-\223\057\115\174\100\126\061\172\353\244\017\140\315\172\363\276
-\303\047\216\003\076\244\335\022\357\176\036\164\006\074\077\061
-\362\034\173\221\061\041\264\360\320\154\227\324\351\227\262\044
-\126\036\126\303\065\275\210\005\017\133\020\032\144\341\307\202
-\060\371\062\255\236\120\054\347\170\005\320\061\261\132\230\212
-\165\116\220\134\152\024\052\340\122\107\202\140\346\036\332\201
-\261\373\024\013\132\361\237\322\225\272\076\320\033\326\025\035
-\243\276\206\325\333\017\300\111\144\273\056\120\031\113\322\044
-\370\335\036\007\126\320\070\240\225\160\040\166\214\327\335\036
-\336\237\161\304\043\357\203\023\134\243\044\025\115\051\100\074
-\152\304\251\330\267\246\104\245\015\364\340\235\167\036\100\160
-\046\374\332\331\066\344\171\344\265\077\274\233\145\276\273\021
-\226\317\333\306\050\071\072\010\316\107\133\123\132\305\231\376
-\135\251\335\357\114\324\306\245\255\002\346\214\007\022\036\157
-\003\321\157\240\243\363\051\275\022\307\120\242\260\177\210\251
-\231\167\232\261\300\245\071\056\134\174\151\342\054\260\352\067
-\152\244\341\132\341\365\120\345\203\357\245\273\052\210\347\214
-\333\375\155\136\227\031\250\176\146\165\153\161\352\277\261\307
-\157\240\364\216\244\354\064\121\133\214\046\003\160\241\167\325
-\001\022\127\000\065\333\043\336\016\212\050\231\375\261\020\157
-\113\377\070\055\140\116\054\234\353\147\265\255\111\356\113\037
-\254\257\373\015\220\132\146\140\160\135\252\315\170\324\044\356
-\310\101\240\223\001\222\234\152\236\374\271\044\305\263\025\202
-\176\276\256\225\053\353\261\300\332\343\001\140\013\136\151\254
-\204\126\141\276\161\027\376\035\023\017\376\306\207\105\351\376
-\062\240\032\015\023\244\224\125\161\245\026\213\272\312\211\260
-\262\307\374\217\330\124\265\223\142\235\316\317\131\373\075\030
-\316\052\313\065\025\202\135\377\124\042\133\161\122\373\267\311
-\376\140\233\000\101\144\360\252\052\354\266\102\103\316\211\146
-\201\310\213\237\071\124\003\045\323\026\065\216\204\320\137\372
-\060\032\365\232\154\364\016\123\371\072\133\321\034
-END
-
-# Trust for Certificate "Swisscom Root CA 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Swisscom Root CA 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\137\072\374\012\213\144\366\206\147\064\164\337\176\251\242\376
-\371\372\172\121
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\370\070\174\167\210\337\054\026\150\056\302\342\122\113\270\371
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061
-\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143
-\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147
-\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145
-\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125
-\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157
-\164\040\103\101\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235
-\250\066
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "DigiCert Assured ID Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DigiCert Assured ID Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\145\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103\145
-\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013\023
-\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143\157
-\155\061\044\060\042\006\003\125\004\003\023\033\104\151\147\151
-\103\145\162\164\040\101\163\163\165\162\145\144\040\111\104\040
-\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\145\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103\145
-\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013\023
-\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143\157
-\155\061\044\060\042\006\003\125\004\003\023\033\104\151\147\151
-\103\145\162\164\040\101\163\163\165\162\145\144\040\111\104\040
-\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\014\347\340\345\027\330\106\376\217\345\140\374\033\360
-\060\071
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\267\060\202\002\237\240\003\002\001\002\002\020\014
-\347\340\345\027\330\106\376\217\345\140\374\033\360\060\071\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\145
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\025\060
-\023\006\003\125\004\012\023\014\104\151\147\151\103\145\162\164
-\040\111\156\143\061\031\060\027\006\003\125\004\013\023\020\167
-\167\167\056\144\151\147\151\143\145\162\164\056\143\157\155\061
-\044\060\042\006\003\125\004\003\023\033\104\151\147\151\103\145
-\162\164\040\101\163\163\165\162\145\144\040\111\104\040\122\157
-\157\164\040\103\101\060\036\027\015\060\066\061\061\061\060\060
-\060\060\060\060\060\132\027\015\063\061\061\061\061\060\060\060
-\060\060\060\060\132\060\145\061\013\060\011\006\003\125\004\006
-\023\002\125\123\061\025\060\023\006\003\125\004\012\023\014\104
-\151\147\151\103\145\162\164\040\111\156\143\061\031\060\027\006
-\003\125\004\013\023\020\167\167\167\056\144\151\147\151\143\145
-\162\164\056\143\157\155\061\044\060\042\006\003\125\004\003\023
-\033\104\151\147\151\103\145\162\164\040\101\163\163\165\162\145
-\144\040\111\104\040\122\157\157\164\040\103\101\060\202\001\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\001\017\000\060\202\001\012\002\202\001\001\000\255\016\025
-\316\344\103\200\134\261\207\363\267\140\371\161\022\245\256\334
-\046\224\210\252\364\316\365\040\071\050\130\140\014\370\200\332
-\251\025\225\062\141\074\265\261\050\204\212\212\334\237\012\014
-\203\027\172\217\220\254\212\347\171\123\134\061\204\052\366\017
-\230\062\066\166\314\336\335\074\250\242\357\152\373\041\362\122
-\141\337\237\040\327\037\342\261\331\376\030\144\322\022\133\137
-\371\130\030\065\274\107\315\241\066\371\153\177\324\260\070\076
-\301\033\303\214\063\331\330\057\030\376\050\017\263\247\203\326
-\303\156\104\300\141\065\226\026\376\131\234\213\166\155\327\361
-\242\113\015\053\377\013\162\332\236\140\320\216\220\065\306\170
-\125\207\040\241\317\345\155\012\310\111\174\061\230\063\154\042
-\351\207\320\062\132\242\272\023\202\021\355\071\027\235\231\072
-\162\241\346\372\244\331\325\027\061\165\256\205\175\042\256\077
-\001\106\206\366\050\171\310\261\332\344\127\027\304\176\034\016
-\260\264\222\246\126\263\275\262\227\355\252\247\360\267\305\250
-\077\225\026\320\377\241\226\353\010\137\030\167\117\002\003\001
-\000\001\243\143\060\141\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\206\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026
-\004\024\105\353\242\257\364\222\313\202\061\055\121\213\247\247
-\041\235\363\155\310\017\060\037\006\003\125\035\043\004\030\060
-\026\200\024\105\353\242\257\364\222\313\202\061\055\121\213\247
-\247\041\235\363\155\310\017\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\003\202\001\001\000\242\016\274\337\342
-\355\360\343\162\163\172\144\224\277\367\162\146\330\062\344\102
-\165\142\256\207\353\362\325\331\336\126\263\237\314\316\024\050
-\271\015\227\140\134\022\114\130\344\323\075\203\111\105\130\227
-\065\151\032\250\107\352\126\306\171\253\022\330\147\201\204\337
-\177\011\074\224\346\270\046\054\040\275\075\263\050\211\367\137
-\377\042\342\227\204\037\351\145\357\207\340\337\301\147\111\263
-\135\353\262\011\052\353\046\355\170\276\175\077\053\363\267\046
-\065\155\137\211\001\266\111\133\237\001\005\233\253\075\045\301
-\314\266\177\302\361\157\206\306\372\144\150\353\201\055\224\353
-\102\267\372\214\036\335\142\361\276\120\147\267\154\275\363\361
-\037\153\014\066\007\026\177\067\174\251\133\155\172\361\022\106
-\140\203\327\047\004\276\113\316\227\276\303\147\052\150\021\337
-\200\347\014\063\146\277\023\015\024\156\363\177\037\143\020\036
-\372\215\033\045\155\154\217\245\267\141\001\261\322\243\046\241
-\020\161\235\255\342\303\371\303\231\121\267\053\007\010\316\056
-\346\120\262\247\372\012\105\057\242\360\362
-END
-
-# Trust for Certificate "DigiCert Assured ID Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DigiCert Assured ID Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\005\143\270\143\015\142\327\132\273\310\253\036\113\337\265\250
-\231\262\115\103
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\207\316\013\173\052\016\111\000\341\130\161\233\067\250\223\162
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\145\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103\145
-\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013\023
-\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143\157
-\155\061\044\060\042\006\003\125\004\003\023\033\104\151\147\151
-\103\145\162\164\040\101\163\163\165\162\145\144\040\111\104\040
-\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\014\347\340\345\027\330\106\376\217\345\140\374\033\360
-\060\071
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "DigiCert Global Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DigiCert Global Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\141\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103\145
-\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013\023
-\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143\157
-\155\061\040\060\036\006\003\125\004\003\023\027\104\151\147\151
-\103\145\162\164\040\107\154\157\142\141\154\040\122\157\157\164
-\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\141\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103\145
-\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013\023
-\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143\157
-\155\061\040\060\036\006\003\125\004\003\023\027\104\151\147\151
-\103\145\162\164\040\107\154\157\142\141\154\040\122\157\157\164
-\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\010\073\340\126\220\102\106\261\241\165\152\311\131\221
-\307\112
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\257\060\202\002\227\240\003\002\001\002\002\020\010
-\073\340\126\220\102\106\261\241\165\152\311\131\221\307\112\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\141
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\025\060
-\023\006\003\125\004\012\023\014\104\151\147\151\103\145\162\164
-\040\111\156\143\061\031\060\027\006\003\125\004\013\023\020\167
-\167\167\056\144\151\147\151\143\145\162\164\056\143\157\155\061
-\040\060\036\006\003\125\004\003\023\027\104\151\147\151\103\145
-\162\164\040\107\154\157\142\141\154\040\122\157\157\164\040\103
-\101\060\036\027\015\060\066\061\061\061\060\060\060\060\060\060
-\060\132\027\015\063\061\061\061\061\060\060\060\060\060\060\060
-\132\060\141\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103
-\145\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013
-\023\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143
-\157\155\061\040\060\036\006\003\125\004\003\023\027\104\151\147
-\151\103\145\162\164\040\107\154\157\142\141\154\040\122\157\157
-\164\040\103\101\060\202\001\042\060\015\006\011\052\206\110\206
-\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012
-\002\202\001\001\000\342\073\341\021\162\336\250\244\323\243\127
-\252\120\242\217\013\167\220\311\242\245\356\022\316\226\133\001
-\011\040\314\001\223\247\116\060\267\123\367\103\304\151\000\127
-\235\342\215\042\335\207\006\100\000\201\011\316\316\033\203\277
-\337\315\073\161\106\342\326\146\307\005\263\166\047\026\217\173
-\236\036\225\175\356\267\110\243\010\332\326\257\172\014\071\006
-\145\177\112\135\037\274\027\370\253\276\356\050\327\164\177\172
-\170\231\131\205\150\156\134\043\062\113\277\116\300\350\132\155
-\343\160\277\167\020\277\374\001\366\205\331\250\104\020\130\062
-\251\165\030\325\321\242\276\107\342\047\152\364\232\063\370\111
-\010\140\213\324\137\264\072\204\277\241\252\112\114\175\076\317
-\117\137\154\166\136\240\113\067\221\236\334\042\346\155\316\024
-\032\216\152\313\376\315\263\024\144\027\307\133\051\236\062\277
-\362\356\372\323\013\102\324\253\267\101\062\332\014\324\357\370
-\201\325\273\215\130\077\265\033\350\111\050\242\160\332\061\004
-\335\367\262\026\362\114\012\116\007\250\355\112\075\136\265\177
-\243\220\303\257\047\002\003\001\000\001\243\143\060\141\060\016
-\006\003\125\035\017\001\001\377\004\004\003\002\001\206\060\017
-\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
-\035\006\003\125\035\016\004\026\004\024\003\336\120\065\126\321
-\114\273\146\360\243\342\033\033\303\227\262\075\321\125\060\037
-\006\003\125\035\043\004\030\060\026\200\024\003\336\120\065\126
-\321\114\273\146\360\243\342\033\033\303\227\262\075\321\125\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202
-\001\001\000\313\234\067\252\110\023\022\012\372\335\104\234\117
-\122\260\364\337\256\004\365\171\171\010\243\044\030\374\113\053
-\204\300\055\271\325\307\376\364\301\037\130\313\270\155\234\172
-\164\347\230\051\253\021\265\343\160\240\241\315\114\210\231\223
-\214\221\160\342\253\017\034\276\223\251\377\143\325\344\007\140
-\323\243\277\235\133\011\361\325\216\343\123\364\216\143\372\077
-\247\333\264\146\337\142\146\326\321\156\101\215\362\055\265\352
-\167\112\237\235\130\342\053\131\300\100\043\355\055\050\202\105
-\076\171\124\222\046\230\340\200\110\250\067\357\360\326\171\140
-\026\336\254\350\016\315\156\254\104\027\070\057\111\332\341\105
-\076\052\271\066\123\317\072\120\006\367\056\350\304\127\111\154
-\141\041\030\325\004\255\170\074\054\072\200\153\247\353\257\025
-\024\351\330\211\301\271\070\154\342\221\154\212\377\144\271\167
-\045\127\060\300\033\044\243\341\334\351\337\107\174\265\264\044
-\010\005\060\354\055\275\013\277\105\277\120\271\251\363\353\230
-\001\022\255\310\210\306\230\064\137\215\012\074\306\351\325\225
-\225\155\336
-END
-
-# Trust for Certificate "DigiCert Global Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DigiCert Global Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\250\230\135\072\145\345\345\304\262\327\326\155\100\306\335\057
-\261\234\124\066
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\171\344\251\204\015\175\072\226\327\300\117\342\103\114\211\056
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\141\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103\145
-\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013\023
-\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143\157
-\155\061\040\060\036\006\003\125\004\003\023\027\104\151\147\151
-\103\145\162\164\040\107\154\157\142\141\154\040\122\157\157\164
-\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\010\073\340\126\220\102\106\261\241\165\152\311\131\221
-\307\112
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "DigiCert High Assurance EV Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DigiCert High Assurance EV Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\154\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103\145
-\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013\023
-\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143\157
-\155\061\053\060\051\006\003\125\004\003\023\042\104\151\147\151
-\103\145\162\164\040\110\151\147\150\040\101\163\163\165\162\141
-\156\143\145\040\105\126\040\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\154\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103\145
-\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013\023
-\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143\157
-\155\061\053\060\051\006\003\125\004\003\023\042\104\151\147\151
-\103\145\162\164\040\110\151\147\150\040\101\163\163\165\162\141
-\156\143\145\040\105\126\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\002\254\134\046\152\013\100\233\217\013\171\362\256\106
-\045\167
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\305\060\202\002\255\240\003\002\001\002\002\020\002
-\254\134\046\152\013\100\233\217\013\171\362\256\106\045\167\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\154
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\025\060
-\023\006\003\125\004\012\023\014\104\151\147\151\103\145\162\164
-\040\111\156\143\061\031\060\027\006\003\125\004\013\023\020\167
-\167\167\056\144\151\147\151\143\145\162\164\056\143\157\155\061
-\053\060\051\006\003\125\004\003\023\042\104\151\147\151\103\145
-\162\164\040\110\151\147\150\040\101\163\163\165\162\141\156\143
-\145\040\105\126\040\122\157\157\164\040\103\101\060\036\027\015
-\060\066\061\061\061\060\060\060\060\060\060\060\132\027\015\063
-\061\061\061\061\060\060\060\060\060\060\060\132\060\154\061\013
-\060\011\006\003\125\004\006\023\002\125\123\061\025\060\023\006
-\003\125\004\012\023\014\104\151\147\151\103\145\162\164\040\111
-\156\143\061\031\060\027\006\003\125\004\013\023\020\167\167\167
-\056\144\151\147\151\143\145\162\164\056\143\157\155\061\053\060
-\051\006\003\125\004\003\023\042\104\151\147\151\103\145\162\164
-\040\110\151\147\150\040\101\163\163\165\162\141\156\143\145\040
-\105\126\040\122\157\157\164\040\103\101\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\306\314\345\163\346
-\373\324\273\345\055\055\062\246\337\345\201\077\311\315\045\111
-\266\161\052\303\325\224\064\147\242\012\034\260\137\151\246\100
-\261\304\267\262\217\320\230\244\251\101\131\072\323\334\224\326
-\074\333\164\070\244\112\314\115\045\202\367\112\245\123\022\070
-\356\363\111\155\161\221\176\143\266\253\246\137\303\244\204\370
-\117\142\121\276\370\305\354\333\070\222\343\006\345\010\221\014
-\304\050\101\125\373\313\132\211\025\176\161\350\065\277\115\162
-\011\075\276\072\070\120\133\167\061\033\215\263\307\044\105\232
-\247\254\155\000\024\132\004\267\272\023\353\121\012\230\101\101
-\042\116\145\141\207\201\101\120\246\171\134\211\336\031\112\127
-\325\056\346\135\034\123\054\176\230\315\032\006\026\244\150\163
-\320\064\004\023\134\241\161\323\132\174\125\333\136\144\341\067
-\207\060\126\004\345\021\264\051\200\022\361\171\071\210\242\002
-\021\174\047\146\267\210\267\170\362\312\012\250\070\253\012\144
-\302\277\146\135\225\204\301\241\045\036\207\135\032\120\013\040
-\022\314\101\273\156\013\121\070\270\113\313\002\003\001\000\001
-\243\143\060\141\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\206\060\017\006\003\125\035\023\001\001\377\004\005
-\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024
-\261\076\303\151\003\370\277\107\001\324\230\046\032\010\002\357
-\143\144\053\303\060\037\006\003\125\035\043\004\030\060\026\200
-\024\261\076\303\151\003\370\277\107\001\324\230\046\032\010\002
-\357\143\144\053\303\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\003\202\001\001\000\034\032\006\227\334\327\234
-\237\074\210\146\006\010\127\041\333\041\107\370\052\147\252\277
-\030\062\166\100\020\127\301\212\363\172\331\021\145\216\065\372
-\236\374\105\265\236\331\114\061\113\270\221\350\103\054\216\263
-\170\316\333\343\123\171\161\326\345\041\224\001\332\125\207\232
-\044\144\366\212\146\314\336\234\067\315\250\064\261\151\233\043
-\310\236\170\042\053\160\103\343\125\107\061\141\031\357\130\305
-\205\057\116\060\366\240\061\026\043\310\347\342\145\026\063\313
-\277\032\033\240\075\370\312\136\213\061\213\140\010\211\055\014
-\006\134\122\267\304\371\012\230\321\025\137\237\022\276\174\066
-\143\070\275\104\244\177\344\046\053\012\304\227\151\015\351\214
-\342\300\020\127\270\310\166\022\221\125\362\110\151\330\274\052
-\002\133\017\104\324\040\061\333\364\272\160\046\135\220\140\236
-\274\113\027\011\057\264\313\036\103\150\311\007\047\301\322\134
-\367\352\041\271\150\022\234\074\234\277\236\374\200\134\233\143
-\315\354\107\252\045\047\147\240\067\363\000\202\175\124\327\251
-\370\351\056\023\243\167\350\037\112
-END
-
-# Trust for Certificate "DigiCert High Assurance EV Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DigiCert High Assurance EV Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\137\267\356\006\063\342\131\333\255\014\114\232\346\323\217\032
-\141\307\334\045
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\324\164\336\127\134\071\262\323\234\205\203\305\300\145\111\212
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\154\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\104\151\147\151\103\145
-\162\164\040\111\156\143\061\031\060\027\006\003\125\004\013\023
-\020\167\167\167\056\144\151\147\151\143\145\162\164\056\143\157
-\155\061\053\060\051\006\003\125\004\003\023\042\104\151\147\151
-\103\145\162\164\040\110\151\147\150\040\101\163\163\165\162\141
-\156\143\145\040\105\126\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\002\254\134\046\152\013\100\233\217\013\171\362\256\106
-\045\167
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Certplus Class 2 Primary CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certplus Class 2 Primary CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\075\061\013\060\011\006\003\125\004\006\023\002\106\122\061
-\021\060\017\006\003\125\004\012\023\010\103\145\162\164\160\154
-\165\163\061\033\060\031\006\003\125\004\003\023\022\103\154\141
-\163\163\040\062\040\120\162\151\155\141\162\171\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\075\061\013\060\011\006\003\125\004\006\023\002\106\122\061
-\021\060\017\006\003\125\004\012\023\010\103\145\162\164\160\154
-\165\163\061\033\060\031\006\003\125\004\003\023\022\103\154\141
-\163\163\040\062\040\120\162\151\155\141\162\171\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\205\275\113\363\330\332\343\151\366\224\327\137\303
-\245\104\043
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\222\060\202\002\172\240\003\002\001\002\002\021\000
-\205\275\113\363\330\332\343\151\366\224\327\137\303\245\104\043
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\075\061\013\060\011\006\003\125\004\006\023\002\106\122\061\021
-\060\017\006\003\125\004\012\023\010\103\145\162\164\160\154\165
-\163\061\033\060\031\006\003\125\004\003\023\022\103\154\141\163
-\163\040\062\040\120\162\151\155\141\162\171\040\103\101\060\036
-\027\015\071\071\060\067\060\067\061\067\060\065\060\060\132\027
-\015\061\071\060\067\060\066\062\063\065\071\065\071\132\060\075
-\061\013\060\011\006\003\125\004\006\023\002\106\122\061\021\060
-\017\006\003\125\004\012\023\010\103\145\162\164\160\154\165\163
-\061\033\060\031\006\003\125\004\003\023\022\103\154\141\163\163
-\040\062\040\120\162\151\155\141\162\171\040\103\101\060\202\001
-\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\202\001\017\000\060\202\001\012\002\202\001\001\000\334\120
-\226\320\022\370\065\322\010\170\172\266\122\160\375\157\356\317
-\271\021\313\135\167\341\354\351\176\004\215\326\314\157\163\103
-\127\140\254\063\012\104\354\003\137\034\200\044\221\345\250\221
-\126\022\202\367\340\053\364\333\256\141\056\211\020\215\153\154
-\272\263\002\275\325\066\305\110\067\043\342\360\132\067\122\063
-\027\022\342\321\140\115\276\057\101\021\343\366\027\045\014\213
-\221\300\033\231\173\231\126\015\257\356\322\274\107\127\343\171
-\111\173\064\211\047\044\204\336\261\354\351\130\116\376\116\337
-\132\276\101\255\254\010\305\030\016\357\322\123\356\154\320\235
-\022\001\023\215\334\200\142\367\225\251\104\210\112\161\116\140
-\125\236\333\043\031\171\126\007\014\077\143\013\134\260\342\276
-\176\025\374\224\063\130\101\070\164\304\341\217\213\337\046\254
-\037\265\213\073\267\103\131\153\260\044\246\155\220\213\304\162
-\352\135\063\230\267\313\336\136\173\357\224\361\033\076\312\311
-\041\301\305\230\002\252\242\366\133\167\233\365\176\226\125\064
-\034\147\151\300\361\102\343\107\254\374\050\034\146\125\002\003
-\001\000\001\243\201\214\060\201\211\060\017\006\003\125\035\023
-\004\010\060\006\001\001\377\002\001\012\060\013\006\003\125\035
-\017\004\004\003\002\001\006\060\035\006\003\125\035\016\004\026
-\004\024\343\163\055\337\313\016\050\014\336\335\263\244\312\171
-\270\216\273\350\060\211\060\021\006\011\140\206\110\001\206\370
-\102\001\001\004\004\003\002\001\006\060\067\006\003\125\035\037
-\004\060\060\056\060\054\240\052\240\050\206\046\150\164\164\160
-\072\057\057\167\167\167\056\143\145\162\164\160\154\165\163\056
-\143\157\155\057\103\122\114\057\143\154\141\163\163\062\056\143
-\162\154\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\003\202\001\001\000\247\124\317\210\104\031\313\337\324\177
-\000\337\126\063\142\265\367\121\001\220\353\303\077\321\210\104
-\351\044\135\357\347\024\275\040\267\232\074\000\376\155\237\333
-\220\334\327\364\142\326\213\160\135\347\345\004\110\251\150\174
-\311\361\102\363\154\177\305\172\174\035\121\210\272\322\012\076
-\047\135\336\055\121\116\323\023\144\151\344\056\343\323\347\233
-\011\231\246\340\225\233\316\032\327\177\276\074\316\122\263\021
-\025\301\017\027\315\003\273\234\045\025\272\242\166\211\374\006
-\361\030\320\223\113\016\174\202\267\245\364\366\137\376\355\100
-\246\235\204\164\071\271\334\036\205\026\332\051\033\206\043\000
-\311\273\211\176\156\200\210\036\057\024\264\003\044\250\062\157
-\003\232\107\054\060\276\126\306\247\102\002\160\033\352\100\330
-\272\005\003\160\007\244\226\377\375\110\063\012\341\334\245\201
-\220\233\115\335\175\347\347\262\315\134\310\152\225\370\245\366
-\215\304\135\170\010\276\173\006\326\111\317\031\066\120\043\056
-\010\346\236\005\115\107\030\325\026\351\261\326\266\020\325\273
-\227\277\242\216\264\124
-END
-
-# Trust for Certificate "Certplus Class 2 Primary CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certplus Class 2 Primary CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\164\040\164\101\162\234\335\222\354\171\061\330\043\020\215\302
-\201\222\342\273
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\210\054\214\122\270\242\074\363\367\273\003\352\256\254\102\013
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\075\061\013\060\011\006\003\125\004\006\023\002\106\122\061
-\021\060\017\006\003\125\004\012\023\010\103\145\162\164\160\154
-\165\163\061\033\060\031\006\003\125\004\003\023\022\103\154\141
-\163\163\040\062\040\120\162\151\155\141\162\171\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\205\275\113\363\330\332\343\151\366\224\327\137\303
-\245\104\043
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "DST Root CA X3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DST Root CA X3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\077\061\044\060\042\006\003\125\004\012\023\033\104\151\147
-\151\164\141\154\040\123\151\147\156\141\164\165\162\145\040\124
-\162\165\163\164\040\103\157\056\061\027\060\025\006\003\125\004
-\003\023\016\104\123\124\040\122\157\157\164\040\103\101\040\130
-\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\077\061\044\060\042\006\003\125\004\012\023\033\104\151\147
-\151\164\141\154\040\123\151\147\156\141\164\165\162\145\040\124
-\162\165\163\164\040\103\157\056\061\027\060\025\006\003\125\004
-\003\023\016\104\123\124\040\122\157\157\164\040\103\101\040\130
-\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\257\260\200\326\243\047\272\211\060\071\206\056\370
-\100\153
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\112\060\202\002\062\240\003\002\001\002\002\020\104
-\257\260\200\326\243\047\272\211\060\071\206\056\370\100\153\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\077
-\061\044\060\042\006\003\125\004\012\023\033\104\151\147\151\164
-\141\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165
-\163\164\040\103\157\056\061\027\060\025\006\003\125\004\003\023
-\016\104\123\124\040\122\157\157\164\040\103\101\040\130\063\060
-\036\027\015\060\060\060\071\063\060\062\061\061\062\061\071\132
-\027\015\062\061\060\071\063\060\061\064\060\061\061\065\132\060
-\077\061\044\060\042\006\003\125\004\012\023\033\104\151\147\151
-\164\141\154\040\123\151\147\156\141\164\165\162\145\040\124\162
-\165\163\164\040\103\157\056\061\027\060\025\006\003\125\004\003
-\023\016\104\123\124\040\122\157\157\164\040\103\101\040\130\063
-\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001
-\000\337\257\351\227\120\010\203\127\264\314\142\145\366\220\202
-\354\307\323\054\153\060\312\133\354\331\303\175\307\100\301\030
-\024\213\340\350\063\166\111\052\343\077\041\111\223\254\116\016
-\257\076\110\313\145\356\374\323\041\017\145\322\052\331\062\217
-\214\345\367\167\260\022\173\265\225\300\211\243\251\272\355\163
-\056\172\014\006\062\203\242\176\212\024\060\315\021\240\341\052
-\070\271\171\012\061\375\120\275\200\145\337\267\121\143\203\310
-\342\210\141\352\113\141\201\354\122\153\271\242\342\113\032\050
-\237\110\243\236\014\332\011\216\076\027\056\036\335\040\337\133
-\306\052\212\253\056\275\160\255\305\013\032\045\220\164\162\305
-\173\152\253\064\326\060\211\377\345\150\023\173\124\013\310\326
-\256\354\132\234\222\036\075\144\263\214\306\337\277\311\101\160
-\354\026\162\325\046\354\070\125\071\103\320\374\375\030\134\100
-\361\227\353\325\232\233\215\035\272\332\045\271\306\330\337\301
-\025\002\072\253\332\156\361\076\056\365\134\010\234\074\326\203
-\151\344\020\233\031\052\266\051\127\343\345\075\233\237\360\002
-\135\002\003\001\000\001\243\102\060\100\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003\125
-\035\016\004\026\004\024\304\247\261\244\173\054\161\372\333\341
-\113\220\165\377\304\025\140\205\211\020\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\243\032
-\054\233\027\000\134\251\036\356\050\146\067\072\277\203\307\077
-\113\303\011\240\225\040\135\343\331\131\104\322\076\015\076\275
-\212\113\240\164\037\316\020\202\234\164\032\035\176\230\032\335
-\313\023\113\263\040\104\344\221\351\314\374\175\245\333\152\345
-\376\346\375\340\116\335\267\000\072\265\160\111\257\362\345\353
-\002\361\321\002\213\031\313\224\072\136\110\304\030\036\130\031
-\137\036\002\132\360\014\361\261\255\251\334\131\206\213\156\351
-\221\365\206\312\372\271\146\063\252\131\133\316\342\247\026\163
-\107\313\053\314\231\260\067\110\317\343\126\113\365\317\017\014
-\162\062\207\306\360\104\273\123\162\155\103\365\046\110\232\122
-\147\267\130\253\376\147\166\161\170\333\015\242\126\024\023\071
-\044\061\205\242\250\002\132\060\107\341\335\120\007\274\002\011
-\220\000\353\144\143\140\233\026\274\210\311\022\346\322\175\221
-\213\371\075\062\215\145\264\351\174\261\127\166\352\305\266\050
-\071\277\025\145\034\310\366\167\226\152\012\215\167\013\330\221
-\013\004\216\007\333\051\266\012\356\235\202\065\065\020
-END
-
-# Trust for Certificate "DST Root CA X3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DST Root CA X3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\332\311\002\117\124\330\366\337\224\223\137\261\163\046\070\312
-\152\327\174\023
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\101\003\122\334\017\367\120\033\026\360\002\216\272\157\105\305
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\077\061\044\060\042\006\003\125\004\012\023\033\104\151\147
-\151\164\141\154\040\123\151\147\156\141\164\165\162\145\040\124
-\162\165\163\164\040\103\157\056\061\027\060\025\006\003\125\004
-\003\023\016\104\123\124\040\122\157\157\164\040\103\101\040\130
-\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\257\260\200\326\243\047\272\211\060\071\206\056\370
-\100\153
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "DST ACES CA X6"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DST ACES CA X6"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\133\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\023\027\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\061\021\060\017\006\003\125\004\013\023\010\104\123\124\040
-\101\103\105\123\061\027\060\025\006\003\125\004\003\023\016\104
-\123\124\040\101\103\105\123\040\103\101\040\130\066
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\133\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\023\027\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\061\021\060\017\006\003\125\004\013\023\010\104\123\124\040
-\101\103\105\123\061\027\060\025\006\003\125\004\003\023\016\104
-\123\124\040\101\103\105\123\040\103\101\040\130\066
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\015\136\231\012\326\235\267\170\354\330\007\126\073\206
-\025\331
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\011\060\202\002\361\240\003\002\001\002\002\020\015
-\136\231\012\326\235\267\170\354\330\007\126\073\206\025\331\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\133
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\040\060
-\036\006\003\125\004\012\023\027\104\151\147\151\164\141\154\040
-\123\151\147\156\141\164\165\162\145\040\124\162\165\163\164\061
-\021\060\017\006\003\125\004\013\023\010\104\123\124\040\101\103
-\105\123\061\027\060\025\006\003\125\004\003\023\016\104\123\124
-\040\101\103\105\123\040\103\101\040\130\066\060\036\027\015\060
-\063\061\061\062\060\062\061\061\071\065\070\132\027\015\061\067
-\061\061\062\060\062\061\061\071\065\070\132\060\133\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\040\060\036\006\003
-\125\004\012\023\027\104\151\147\151\164\141\154\040\123\151\147
-\156\141\164\165\162\145\040\124\162\165\163\164\061\021\060\017
-\006\003\125\004\013\023\010\104\123\124\040\101\103\105\123\061
-\027\060\025\006\003\125\004\003\023\016\104\123\124\040\101\103
-\105\123\040\103\101\040\130\066\060\202\001\042\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000
-\060\202\001\012\002\202\001\001\000\271\075\365\054\311\224\334
-\165\212\225\135\143\350\204\167\166\146\271\131\221\134\106\335
-\222\076\237\371\016\003\264\075\141\222\275\043\046\265\143\356
-\222\322\236\326\074\310\015\220\137\144\201\261\250\010\015\114
-\330\371\323\005\050\122\264\001\045\305\225\034\014\176\076\020
-\204\165\317\301\031\221\143\317\350\250\221\210\271\103\122\273
-\200\261\125\211\213\061\372\320\267\166\276\101\075\060\232\244
-\042\045\027\163\350\036\342\323\254\052\275\133\070\041\325\052
-\113\327\125\175\343\072\125\275\327\155\153\002\127\153\346\107
-\174\010\310\202\272\336\247\207\075\241\155\270\060\126\302\263
-\002\201\137\055\365\342\232\060\030\050\270\146\323\313\001\226
-\157\352\212\105\125\326\340\235\377\147\053\027\002\246\116\032
-\152\021\013\176\267\173\347\230\326\214\166\157\301\073\333\120
-\223\176\345\320\216\037\067\270\275\272\306\237\154\351\174\063
-\362\062\074\046\107\372\047\044\002\311\176\035\133\210\102\023
-\152\065\174\175\065\351\056\146\221\162\223\325\062\046\304\164
-\365\123\243\263\135\232\366\011\313\002\003\001\000\001\243\201
-\310\060\201\305\060\017\006\003\125\035\023\001\001\377\004\005
-\060\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004
-\004\003\002\001\306\060\037\006\003\125\035\021\004\030\060\026
-\201\024\160\153\151\055\157\160\163\100\164\162\165\163\164\144
-\163\164\056\143\157\155\060\142\006\003\125\035\040\004\133\060
-\131\060\127\006\012\140\206\110\001\145\003\002\001\001\001\060
-\111\060\107\006\010\053\006\001\005\005\007\002\001\026\073\150
-\164\164\160\072\057\057\167\167\167\056\164\162\165\163\164\144
-\163\164\056\143\157\155\057\143\145\162\164\151\146\151\143\141
-\164\145\163\057\160\157\154\151\143\171\057\101\103\105\123\055
-\151\156\144\145\170\056\150\164\155\154\060\035\006\003\125\035
-\016\004\026\004\024\011\162\006\116\030\103\017\345\326\314\303
-\152\213\061\173\170\217\250\203\270\060\015\006\011\052\206\110
-\206\367\015\001\001\005\005\000\003\202\001\001\000\243\330\216
-\326\262\333\316\005\347\062\315\001\323\004\003\345\166\344\126
-\053\234\231\220\350\010\060\154\337\175\075\356\345\277\265\044
-\100\204\111\341\321\050\256\304\302\072\123\060\210\361\365\167
-\156\121\312\372\377\231\257\044\137\033\240\375\362\254\204\312
-\337\251\360\137\004\056\255\026\277\041\227\020\201\075\343\377
-\207\215\062\334\224\345\107\212\136\152\023\311\224\225\075\322
-\356\310\064\225\320\200\324\255\062\010\200\124\074\340\275\122
-\123\327\122\174\262\151\077\177\172\317\152\164\312\372\004\052
-\234\114\132\006\245\351\040\255\105\146\017\151\361\335\277\351
-\343\062\213\372\340\301\206\115\162\074\056\330\223\170\012\052
-\370\330\322\047\075\031\211\137\132\173\212\073\314\014\332\121
-\256\307\013\367\053\260\067\005\354\274\127\043\342\070\322\233
-\150\363\126\022\210\117\102\174\270\061\304\265\333\344\310\041
-\064\351\110\021\065\356\372\307\222\127\305\237\064\344\307\366
-\367\016\013\114\234\150\170\173\161\061\307\353\036\340\147\101
-\363\267\240\247\315\345\172\063\066\152\372\232\053
-END
-
-# Trust for Certificate "DST ACES CA X6"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "DST ACES CA X6"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\100\124\332\157\034\077\100\164\254\355\017\354\315\333\171\321
-\123\373\220\035
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\041\330\114\202\053\231\011\063\242\353\024\044\215\216\137\350
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\133\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\023\027\104\151\147\151\164\141
-\154\040\123\151\147\156\141\164\165\162\145\040\124\162\165\163
-\164\061\021\060\017\006\003\125\004\013\023\010\104\123\124\040
-\101\103\105\123\061\027\060\025\006\003\125\004\003\023\016\104
-\123\124\040\101\103\105\123\040\103\101\040\130\066
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\015\136\231\012\326\235\267\170\354\330\007\126\073\206
-\025\331
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TURKTRUST Certificate Services Provider Root 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TURKTRUST Certificate Services Provider Root 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\267\061\077\060\075\006\003\125\004\003\014\066\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151
-\172\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304
-\261\163\304\261\061\013\060\011\006\003\125\004\006\014\002\124
-\122\061\017\060\015\006\003\125\004\007\014\006\101\116\113\101
-\122\101\061\126\060\124\006\003\125\004\012\014\115\050\143\051
-\040\062\060\060\065\040\124\303\234\122\113\124\122\125\123\124
-\040\102\151\154\147\151\040\304\260\154\145\164\151\305\237\151
-\155\040\166\145\040\102\151\154\151\305\237\151\155\040\107\303
-\274\166\145\156\154\151\304\237\151\040\110\151\172\155\145\164
-\154\145\162\151\040\101\056\305\236\056
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\267\061\077\060\075\006\003\125\004\003\014\066\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151
-\172\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304
-\261\163\304\261\061\013\060\011\006\003\125\004\006\014\002\124
-\122\061\017\060\015\006\003\125\004\007\014\006\101\116\113\101
-\122\101\061\126\060\124\006\003\125\004\012\014\115\050\143\051
-\040\062\060\060\065\040\124\303\234\122\113\124\122\125\123\124
-\040\102\151\154\147\151\040\304\260\154\145\164\151\305\237\151
-\155\040\166\145\040\102\151\154\151\305\237\151\155\040\107\303
-\274\166\145\156\154\151\304\237\151\040\110\151\172\155\145\164
-\154\145\162\151\040\101\056\305\236\056
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\373\060\202\002\343\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\267\061\077\060\075\006\003\125\004\003\014\066\124\303\234
-\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157\156
-\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151\172
-\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304\261
-\163\304\261\061\013\060\011\006\003\125\004\006\014\002\124\122
-\061\017\060\015\006\003\125\004\007\014\006\101\116\113\101\122
-\101\061\126\060\124\006\003\125\004\012\014\115\050\143\051\040
-\062\060\060\065\040\124\303\234\122\113\124\122\125\123\124\040
-\102\151\154\147\151\040\304\260\154\145\164\151\305\237\151\155
-\040\166\145\040\102\151\154\151\305\237\151\155\040\107\303\274
-\166\145\156\154\151\304\237\151\040\110\151\172\155\145\164\154
-\145\162\151\040\101\056\305\236\056\060\036\027\015\060\065\060
-\065\061\063\061\060\062\067\061\067\132\027\015\061\065\060\063
-\062\062\061\060\062\067\061\067\132\060\201\267\061\077\060\075
-\006\003\125\004\003\014\066\124\303\234\122\113\124\122\125\123
-\124\040\105\154\145\153\164\162\157\156\151\153\040\123\145\162
-\164\151\146\151\153\141\040\110\151\172\155\145\164\040\123\141
-\304\237\154\141\171\304\261\143\304\261\163\304\261\061\013\060
-\011\006\003\125\004\006\014\002\124\122\061\017\060\015\006\003
-\125\004\007\014\006\101\116\113\101\122\101\061\126\060\124\006
-\003\125\004\012\014\115\050\143\051\040\062\060\060\065\040\124
-\303\234\122\113\124\122\125\123\124\040\102\151\154\147\151\040
-\304\260\154\145\164\151\305\237\151\155\040\166\145\040\102\151
-\154\151\305\237\151\155\040\107\303\274\166\145\156\154\151\304
-\237\151\040\110\151\172\155\145\164\154\145\162\151\040\101\056
-\305\236\056\060\202\001\042\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002
-\202\001\001\000\312\122\005\326\143\003\330\034\137\335\322\173
-\135\362\014\140\141\133\153\073\164\053\170\015\175\105\275\042
-\164\350\214\003\301\306\021\052\075\225\274\251\224\260\273\221
-\227\310\151\174\204\305\264\221\154\154\023\152\244\125\255\244
-\205\350\225\176\263\000\257\000\302\005\030\365\160\235\066\213
-\256\313\344\033\201\177\223\210\373\152\125\273\175\205\222\316
-\272\130\237\333\062\305\275\135\357\042\112\057\101\007\176\111
-\141\263\206\354\116\246\101\156\204\274\003\354\365\073\034\310
-\037\302\356\250\356\352\022\112\215\024\317\363\012\340\120\071
-\371\010\065\370\021\131\255\347\042\352\113\312\024\006\336\102
-\272\262\231\363\055\124\210\020\006\352\341\032\076\075\147\037
-\373\316\373\174\202\350\021\135\112\301\271\024\352\124\331\146
-\233\174\211\175\004\232\142\311\351\122\074\236\234\357\322\365
-\046\344\346\345\030\174\213\156\337\154\314\170\133\117\162\262
-\313\134\077\214\005\215\321\114\214\255\222\307\341\170\177\145
-\154\111\006\120\054\236\062\302\327\112\306\165\212\131\116\165
-\157\107\136\301\002\003\001\000\001\243\020\060\016\060\014\006
-\003\125\035\023\004\005\060\003\001\001\377\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000\025
-\365\125\377\067\226\200\131\041\244\374\241\025\114\040\366\324
-\137\332\003\044\374\317\220\032\364\041\012\232\356\072\261\152
-\357\357\370\140\321\114\066\146\105\035\363\146\002\164\004\173
-\222\060\250\336\012\166\017\357\225\156\275\311\067\346\032\015
-\254\211\110\133\314\203\066\302\365\106\134\131\202\126\264\325
-\376\043\264\330\124\034\104\253\304\247\345\024\316\074\101\141
-\174\103\346\315\304\201\011\213\044\373\124\045\326\026\250\226
-\014\147\007\157\263\120\107\343\034\044\050\335\052\230\244\141
-\376\333\352\022\067\274\001\032\064\205\275\156\117\347\221\162
-\007\104\205\036\130\312\124\104\335\367\254\271\313\211\041\162
-\333\217\300\151\051\227\052\243\256\030\043\227\034\101\052\213
-\174\052\301\174\220\350\251\050\300\323\221\306\255\050\207\100
-\150\265\377\354\247\322\323\070\030\234\323\175\151\135\360\306
-\245\036\044\033\243\107\374\151\007\150\347\344\232\264\355\017
-\241\207\207\002\316\207\322\110\116\341\274\377\313\361\162\222
-\104\144\003\045\352\336\133\156\237\311\362\116\254\335\307
-END
-
-# Trust for Certificate "TURKTRUST Certificate Services Provider Root 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TURKTRUST Certificate Services Provider Root 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\171\230\243\010\341\115\145\205\346\302\036\025\072\161\237\272
-\132\323\112\331
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\361\152\042\030\311\315\337\316\202\035\035\267\170\134\251\245
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\267\061\077\060\075\006\003\125\004\003\014\066\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151
-\172\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304
-\261\163\304\261\061\013\060\011\006\003\125\004\006\014\002\124
-\122\061\017\060\015\006\003\125\004\007\014\006\101\116\113\101
-\122\101\061\126\060\124\006\003\125\004\012\014\115\050\143\051
-\040\062\060\060\065\040\124\303\234\122\113\124\122\125\123\124
-\040\102\151\154\147\151\040\304\260\154\145\164\151\305\237\151
-\155\040\166\145\040\102\151\154\151\305\237\151\155\040\107\303
-\274\166\145\156\154\151\304\237\151\040\110\151\172\155\145\164
-\154\145\162\151\040\101\056\305\236\056
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TURKTRUST Certificate Services Provider Root 2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TURKTRUST Certificate Services Provider Root 2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\276\061\077\060\075\006\003\125\004\003\014\066\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151
-\172\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304
-\261\163\304\261\061\013\060\011\006\003\125\004\006\023\002\124
-\122\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141
-\162\141\061\135\060\133\006\003\125\004\012\014\124\124\303\234
-\122\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260
-\154\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151
-\305\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151
-\040\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236
-\056\040\050\143\051\040\113\141\163\304\261\155\040\062\060\060
-\065
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\276\061\077\060\075\006\003\125\004\003\014\066\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151
-\172\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304
-\261\163\304\261\061\013\060\011\006\003\125\004\006\023\002\124
-\122\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141
-\162\141\061\135\060\133\006\003\125\004\012\014\124\124\303\234
-\122\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260
-\154\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151
-\305\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151
-\040\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236
-\056\040\050\143\051\040\113\141\163\304\261\155\040\062\060\060
-\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\074\060\202\003\044\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\276\061\077\060\075\006\003\125\004\003\014\066\124\303\234
-\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157\156
-\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151\172
-\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304\261
-\163\304\261\061\013\060\011\006\003\125\004\006\023\002\124\122
-\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162
-\141\061\135\060\133\006\003\125\004\012\014\124\124\303\234\122
-\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154
-\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305
-\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040
-\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056
-\040\050\143\051\040\113\141\163\304\261\155\040\062\060\060\065
-\060\036\027\015\060\065\061\061\060\067\061\060\060\067\065\067
-\132\027\015\061\065\060\071\061\066\061\060\060\067\065\067\132
-\060\201\276\061\077\060\075\006\003\125\004\003\014\066\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151
-\172\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304
-\261\163\304\261\061\013\060\011\006\003\125\004\006\023\002\124
-\122\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141
-\162\141\061\135\060\133\006\003\125\004\012\014\124\124\303\234
-\122\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260
-\154\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151
-\305\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151
-\040\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236
-\056\040\050\143\051\040\113\141\163\304\261\155\040\062\060\060
-\065\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001
-\001\000\251\066\176\303\221\103\114\303\031\230\010\310\307\130
-\173\117\026\214\245\316\111\001\037\163\016\254\165\023\246\372
-\236\054\040\336\330\220\016\012\321\151\322\047\373\252\167\237
-\047\122\045\342\313\135\330\330\203\120\027\175\212\265\202\077
-\004\216\264\325\360\111\247\144\267\036\056\137\040\234\120\165
-\117\257\341\265\101\024\364\230\222\210\307\345\345\144\107\141
-\107\171\375\300\121\361\301\231\347\334\316\152\373\257\265\001
-\060\334\106\034\357\212\354\225\357\334\377\257\020\034\353\235
-\330\260\252\152\205\030\015\027\311\076\277\361\233\320\011\211
-\102\375\240\102\264\235\211\121\125\051\317\033\160\274\204\124
-\255\301\023\037\230\364\056\166\140\213\135\077\232\255\312\014
-\277\247\126\133\217\167\270\325\236\171\111\222\077\340\361\227
-\044\172\154\233\027\017\155\357\123\230\221\053\344\017\276\131
-\171\007\170\273\227\225\364\237\151\324\130\207\012\251\343\314
-\266\130\031\237\046\041\261\304\131\215\262\101\165\300\255\151
-\316\234\000\010\362\066\377\076\360\241\017\032\254\024\375\246
-\140\017\002\003\001\000\001\243\103\060\101\060\035\006\003\125
-\035\016\004\026\004\024\331\067\263\116\005\375\331\317\237\022
-\026\256\266\211\057\353\045\072\210\034\060\017\006\003\125\035
-\017\001\001\377\004\005\003\003\007\006\000\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000
-\162\140\226\267\311\334\330\051\136\043\205\137\262\263\055\166
-\373\210\327\027\376\173\155\105\270\366\205\154\237\042\374\052
-\020\042\354\252\271\060\366\253\130\326\071\020\061\231\051\000
-\275\211\146\101\373\164\336\221\301\030\013\237\265\141\313\235
-\072\276\365\250\224\243\042\125\156\027\111\377\322\051\361\070
-\046\135\357\245\252\072\371\161\173\346\332\130\035\323\164\302
-\001\372\076\151\130\137\255\313\150\276\024\056\233\154\300\266
-\334\240\046\372\167\032\342\044\332\032\067\340\147\255\321\163
-\203\015\245\032\035\156\022\222\176\204\142\000\027\275\274\045
-\030\127\362\327\251\157\131\210\274\064\267\056\205\170\235\226
-\334\024\303\054\212\122\233\226\214\122\146\075\206\026\213\107
-\270\121\011\214\352\175\315\210\162\263\140\063\261\360\012\104
-\357\017\365\011\067\210\044\016\054\153\040\072\242\372\021\362
-\100\065\234\104\150\143\073\254\063\157\143\274\054\273\362\322
-\313\166\175\175\210\330\035\310\005\035\156\274\224\251\146\214
-\167\161\307\372\221\372\057\121\236\351\071\122\266\347\004\102
-END
-
-# Trust for Certificate "TURKTRUST Certificate Services Provider Root 2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TURKTRUST Certificate Services Provider Root 2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\264\065\324\341\021\235\034\146\220\247\111\353\263\224\275\143
-\173\247\202\267
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\067\245\156\324\261\045\204\227\267\375\126\025\172\371\242\000
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\276\061\077\060\075\006\003\125\004\003\014\066\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151
-\172\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304
-\261\163\304\261\061\013\060\011\006\003\125\004\006\023\002\124
-\122\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141
-\162\141\061\135\060\133\006\003\125\004\012\014\124\124\303\234
-\122\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260
-\154\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151
-\305\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151
-\040\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236
-\056\040\050\143\051\040\113\141\163\304\261\155\040\062\060\060
-\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "SwissSign Platinum CA - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SwissSign Platinum CA - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\111\061\013\060\011\006\003\125\004\006\023\002\103\110\061
-\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
-\151\147\156\040\101\107\061\043\060\041\006\003\125\004\003\023
-\032\123\167\151\163\163\123\151\147\156\040\120\154\141\164\151
-\156\165\155\040\103\101\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\111\061\013\060\011\006\003\125\004\006\023\002\103\110\061
-\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
-\151\147\156\040\101\107\061\043\060\041\006\003\125\004\003\023
-\032\123\167\151\163\163\123\151\147\156\040\120\154\141\164\151
-\156\165\155\040\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\116\262\000\147\014\003\135\117
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\301\060\202\003\251\240\003\002\001\002\002\010\116
-\262\000\147\014\003\135\117\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\060\111\061\013\060\011\006\003\125\004
-\006\023\002\103\110\061\025\060\023\006\003\125\004\012\023\014
-\123\167\151\163\163\123\151\147\156\040\101\107\061\043\060\041
-\006\003\125\004\003\023\032\123\167\151\163\163\123\151\147\156
-\040\120\154\141\164\151\156\165\155\040\103\101\040\055\040\107
-\062\060\036\027\015\060\066\061\060\062\065\060\070\063\066\060
-\060\132\027\015\063\066\061\060\062\065\060\070\063\066\060\060
-\132\060\111\061\013\060\011\006\003\125\004\006\023\002\103\110
-\061\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163
-\123\151\147\156\040\101\107\061\043\060\041\006\003\125\004\003
-\023\032\123\167\151\163\163\123\151\147\156\040\120\154\141\164
-\151\156\165\155\040\103\101\040\055\040\107\062\060\202\002\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\002\017\000\060\202\002\012\002\202\002\001\000\312\337\242
-\002\342\332\370\374\007\026\261\336\140\252\336\226\134\144\037
-\307\057\176\317\147\372\104\102\326\166\143\225\256\353\257\162
-\040\212\105\107\206\142\170\206\326\040\071\046\364\256\243\375
-\043\347\245\234\265\042\041\031\267\067\223\042\300\120\234\202
-\173\324\325\004\104\134\313\264\302\237\222\276\044\330\173\147
-\042\342\151\137\345\005\170\324\207\331\161\160\063\045\123\264
-\207\073\051\220\050\066\232\125\104\060\150\244\203\227\177\015
-\036\234\166\377\025\235\140\227\000\215\212\205\003\354\200\276
-\352\054\156\020\121\222\314\176\325\243\063\330\326\111\336\130
-\052\257\366\026\353\113\173\220\062\227\271\272\235\130\361\370
-\127\111\004\036\242\135\006\160\335\161\333\371\335\213\232\033
-\214\317\075\243\115\316\313\174\366\273\234\240\372\011\316\043
-\142\262\351\015\037\342\162\050\217\237\254\150\040\175\157\073
-\250\205\061\011\177\013\307\350\145\351\343\170\016\011\147\060
-\213\064\202\373\135\340\314\235\201\155\142\356\010\036\004\054
-\116\233\354\376\251\117\137\375\151\170\357\011\037\241\264\277
-\372\363\357\220\036\114\005\213\036\352\172\221\172\303\327\345
-\373\060\274\154\033\020\130\230\367\032\137\320\051\062\003\023
-\106\115\141\152\205\114\122\164\057\006\037\173\021\342\204\227
-\306\231\363\155\177\327\147\203\176\023\150\330\161\050\132\330
-\316\335\350\020\024\232\376\155\043\207\156\216\132\160\074\325
-\215\011\000\247\252\274\260\061\067\155\310\204\024\036\133\275
-\105\143\040\153\113\164\214\275\333\072\016\301\317\132\026\217
-\245\230\362\166\211\262\023\022\073\013\167\167\254\273\345\074
-\051\112\222\162\312\141\032\053\136\114\342\203\164\167\372\065
-\110\172\205\115\215\232\123\304\337\170\312\227\221\110\053\105
-\053\001\367\034\032\242\355\030\272\012\275\203\372\157\274\215
-\127\223\073\324\324\246\316\036\361\240\261\316\253\375\053\050
-\232\117\033\327\303\162\333\244\304\277\135\114\365\335\173\226
-\151\356\150\200\346\347\230\272\066\267\376\156\355\053\275\040
-\370\145\031\332\125\011\176\045\334\376\141\142\162\371\176\030
-\002\357\143\264\320\373\257\345\073\143\214\147\217\002\003\001
-\000\001\243\201\254\060\201\251\060\016\006\003\125\035\017\001
-\001\377\004\004\003\002\001\006\060\017\006\003\125\035\023\001
-\001\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016
-\004\026\004\024\120\257\314\007\207\025\107\157\070\305\264\145
-\321\336\225\252\351\337\234\314\060\037\006\003\125\035\043\004
-\030\060\026\200\024\120\257\314\007\207\025\107\157\070\305\264
-\145\321\336\225\252\351\337\234\314\060\106\006\003\125\035\040
-\004\077\060\075\060\073\006\011\140\205\164\001\131\001\001\001
-\001\060\056\060\054\006\010\053\006\001\005\005\007\002\001\026
-\040\150\164\164\160\072\057\057\162\145\160\157\163\151\164\157
-\162\171\056\163\167\151\163\163\163\151\147\156\056\143\157\155
-\057\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\202\002\001\000\010\205\246\365\026\014\374\104\032\301\143
-\340\371\125\106\010\374\160\034\102\050\226\216\267\305\301\101
-\165\116\011\161\171\345\155\226\312\113\245\210\140\320\060\164
-\270\312\010\334\264\060\236\100\007\026\153\145\225\167\001\256
-\244\267\065\013\201\332\161\025\251\164\027\070\173\130\312\371
-\057\373\300\145\166\215\133\001\271\175\336\202\075\144\270\276
-\024\164\243\012\124\323\054\225\030\027\065\365\121\153\077\217
-\242\226\141\071\170\153\113\345\246\240\370\123\337\121\020\223
-\142\347\200\057\342\321\340\274\216\066\106\167\063\354\270\373
-\216\232\054\211\115\061\021\017\046\236\004\273\267\004\215\013
-\362\271\374\132\235\073\026\267\057\310\230\253\376\212\120\131
-\056\243\073\374\051\135\213\301\113\311\342\212\023\035\261\277
-\273\102\035\122\335\116\330\024\136\020\306\061\007\357\161\047
-\367\033\071\011\334\202\352\213\263\225\206\136\375\365\332\135
-\061\246\340\061\266\224\346\104\111\164\305\026\345\367\037\003
-\141\050\305\310\313\022\240\102\113\371\153\210\010\215\264\062
-\030\363\165\237\304\177\000\117\005\225\234\243\027\002\303\263
-\123\233\252\040\071\051\053\146\372\235\257\136\263\222\322\265
-\246\341\032\371\055\101\151\201\024\264\264\265\355\211\075\316
-\373\251\235\065\102\104\261\034\024\163\201\317\052\001\065\232
-\061\325\055\217\155\204\337\200\115\127\343\077\305\204\165\332
-\211\306\060\273\353\217\313\042\010\240\256\252\361\003\154\072
-\113\115\011\245\016\162\306\126\153\041\102\116\043\045\024\150
-\256\166\012\174\014\007\160\144\371\232\057\366\005\071\046\306
-\014\217\031\177\103\136\156\364\133\025\057\333\141\135\346\147
-\057\077\010\224\371\140\264\230\061\332\164\361\204\223\161\115
-\137\373\140\130\321\373\304\301\155\211\242\273\040\037\235\161
-\221\313\062\233\023\075\076\175\222\122\065\254\222\224\242\323
-\030\302\174\307\352\257\166\005\026\335\147\047\302\176\034\007
-\042\041\363\100\012\033\064\007\104\023\302\204\152\216\337\031
-\132\277\177\353\035\342\032\070\321\134\257\107\222\153\200\265
-\060\245\311\215\330\253\061\201\037\337\302\146\067\323\223\251
-\205\206\171\145\322
-END
-
-# Trust for Certificate "SwissSign Platinum CA - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SwissSign Platinum CA - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\126\340\372\300\073\217\030\043\125\030\345\323\021\312\350\302
-\103\061\253\146
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\311\230\047\167\050\036\075\016\025\074\204\000\270\205\003\346
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\111\061\013\060\011\006\003\125\004\006\023\002\103\110\061
-\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
-\151\147\156\040\101\107\061\043\060\041\006\003\125\004\003\023
-\032\123\167\151\163\163\123\151\147\156\040\120\154\141\164\151
-\156\165\155\040\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\116\262\000\147\014\003\135\117
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "SwissSign Gold CA - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SwissSign Gold CA - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\103\110\061
-\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
-\151\147\156\040\101\107\061\037\060\035\006\003\125\004\003\023
-\026\123\167\151\163\163\123\151\147\156\040\107\157\154\144\040
-\103\101\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\103\110\061
-\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
-\151\147\156\040\101\107\061\037\060\035\006\003\125\004\003\023
-\026\123\167\151\163\163\123\151\147\156\040\107\157\154\144\040
-\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\273\100\034\103\365\136\117\260
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\272\060\202\003\242\240\003\002\001\002\002\011\000
-\273\100\034\103\365\136\117\260\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\060\105\061\013\060\011\006\003\125
-\004\006\023\002\103\110\061\025\060\023\006\003\125\004\012\023
-\014\123\167\151\163\163\123\151\147\156\040\101\107\061\037\060
-\035\006\003\125\004\003\023\026\123\167\151\163\163\123\151\147
-\156\040\107\157\154\144\040\103\101\040\055\040\107\062\060\036
-\027\015\060\066\061\060\062\065\060\070\063\060\063\065\132\027
-\015\063\066\061\060\062\065\060\070\063\060\063\065\132\060\105
-\061\013\060\011\006\003\125\004\006\023\002\103\110\061\025\060
-\023\006\003\125\004\012\023\014\123\167\151\163\163\123\151\147
-\156\040\101\107\061\037\060\035\006\003\125\004\003\023\026\123
-\167\151\163\163\123\151\147\156\040\107\157\154\144\040\103\101
-\040\055\040\107\062\060\202\002\042\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202\002
-\012\002\202\002\001\000\257\344\356\176\213\044\016\022\156\251
-\120\055\026\104\073\222\222\134\312\270\135\204\222\102\023\052
-\274\145\127\202\100\076\127\044\315\120\213\045\052\267\157\374
-\357\242\320\300\037\002\044\112\023\226\217\043\023\346\050\130
-\000\243\107\307\006\247\204\043\053\273\275\226\053\177\125\314
-\213\301\127\037\016\142\145\017\335\075\126\212\163\332\256\176
-\155\272\201\034\176\102\214\040\065\331\103\115\204\372\204\333
-\122\054\363\016\047\167\013\153\277\021\057\162\170\237\056\330
-\076\346\030\067\132\052\162\371\332\142\220\222\225\312\037\234
-\351\263\074\053\313\363\001\023\277\132\317\301\265\012\140\275
-\335\265\231\144\123\270\240\226\263\157\342\046\167\221\214\340
-\142\020\002\237\064\017\244\325\222\063\121\336\276\215\272\204
-\172\140\074\152\333\237\053\354\336\336\001\077\156\115\345\120
-\206\313\264\257\355\104\100\305\312\132\214\332\322\053\174\250
-\356\276\246\345\012\252\016\245\337\005\122\267\125\307\042\135
-\062\152\227\227\143\023\333\311\333\171\066\173\205\072\112\305
-\122\211\371\044\347\235\167\251\202\377\125\034\245\161\151\053
-\321\002\044\362\263\046\324\153\332\004\125\345\301\012\307\155
-\060\067\220\052\344\236\024\063\136\026\027\125\305\133\265\313
-\064\211\222\361\235\046\217\241\007\324\306\262\170\120\333\014
-\014\013\174\013\214\101\327\271\351\335\214\210\367\243\115\262
-\062\314\330\027\332\315\267\316\146\235\324\375\136\377\275\227
-\076\051\165\347\176\247\142\130\257\045\064\245\101\307\075\274
-\015\120\312\003\003\017\010\132\037\225\163\170\142\277\257\162
-\024\151\016\245\345\003\016\170\216\046\050\102\360\007\013\142
-\040\020\147\071\106\372\251\003\314\004\070\172\146\357\040\203
-\265\214\112\126\216\221\000\374\216\134\202\336\210\240\303\342
-\150\156\175\215\357\074\335\145\364\135\254\121\357\044\200\256
-\252\126\227\157\371\255\175\332\141\077\230\167\074\245\221\266
-\034\214\046\332\145\242\011\155\301\342\124\343\271\312\114\114
-\200\217\167\173\140\232\036\337\266\362\110\036\016\272\116\124
-\155\230\340\341\242\032\242\167\120\317\304\143\222\354\107\031
-\235\353\346\153\316\301\002\003\001\000\001\243\201\254\060\201
-\251\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001
-\006\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
-\001\377\060\035\006\003\125\035\016\004\026\004\024\133\045\173
-\226\244\145\121\176\270\071\363\300\170\146\136\350\072\347\360
-\356\060\037\006\003\125\035\043\004\030\060\026\200\024\133\045
-\173\226\244\145\121\176\270\071\363\300\170\146\136\350\072\347
-\360\356\060\106\006\003\125\035\040\004\077\060\075\060\073\006
-\011\140\205\164\001\131\001\002\001\001\060\056\060\054\006\010
-\053\006\001\005\005\007\002\001\026\040\150\164\164\160\072\057
-\057\162\145\160\157\163\151\164\157\162\171\056\163\167\151\163
-\163\163\151\147\156\056\143\157\155\057\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\002\001\000\047\272
-\343\224\174\361\256\300\336\027\346\345\330\325\365\124\260\203
-\364\273\315\136\005\173\117\237\165\146\257\074\350\126\176\374
-\162\170\070\003\331\053\142\033\000\271\370\351\140\315\314\316
-\121\212\307\120\061\156\341\112\176\030\057\151\131\266\075\144
-\201\053\343\203\204\346\042\207\216\175\340\356\002\231\141\270
-\036\364\270\053\210\022\026\204\302\061\223\070\226\061\246\271
-\073\123\077\303\044\223\126\133\151\222\354\305\301\273\070\000
-\343\354\027\251\270\334\307\174\001\203\237\062\107\272\122\042
-\064\035\062\172\011\126\247\174\045\066\251\075\113\332\300\202
-\157\012\273\022\310\207\113\047\021\371\036\055\307\223\077\236
-\333\137\046\153\122\331\056\212\361\024\306\104\215\025\251\267
-\277\275\336\246\032\356\256\055\373\110\167\027\376\273\354\257
-\030\365\052\121\360\071\204\227\225\154\156\033\303\053\304\164
-\140\171\045\260\012\047\337\337\136\322\071\317\105\175\102\113
-\337\263\054\036\305\306\135\312\125\072\240\234\151\232\217\332
-\357\262\260\074\237\207\154\022\053\145\160\025\122\061\032\044
-\317\157\061\043\120\037\214\117\217\043\303\164\101\143\034\125
-\250\024\335\076\340\121\120\317\361\033\060\126\016\222\260\202
-\205\330\203\313\042\144\274\055\270\045\325\124\242\270\006\352
-\255\222\244\044\240\301\206\265\112\023\152\107\317\056\013\126
-\225\124\313\316\232\333\152\264\246\262\333\101\010\206\047\167
-\367\152\240\102\154\013\070\316\327\165\120\062\222\302\337\053
-\060\042\110\320\325\101\070\045\135\244\351\135\237\306\224\165
-\320\105\375\060\227\103\217\220\253\012\307\206\163\140\112\151
-\055\336\245\170\327\006\332\152\236\113\076\167\072\040\023\042
-\001\320\277\150\236\143\140\153\065\115\013\155\272\241\075\300
-\223\340\177\043\263\125\255\162\045\116\106\371\322\026\357\260
-\144\301\001\236\351\312\240\152\230\016\317\330\140\362\057\111
-\270\344\102\341\070\065\026\364\310\156\117\367\201\126\350\272
-\243\276\043\257\256\375\157\003\340\002\073\060\166\372\033\155
-\101\317\001\261\351\270\311\146\364\333\046\363\072\244\164\362
-\111\044\133\311\260\320\127\301\372\076\172\341\227\311
-END
-
-# Trust for Certificate "SwissSign Gold CA - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SwissSign Gold CA - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\330\305\070\212\267\060\033\033\156\324\172\346\105\045\072\157
-\237\032\047\141
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\044\167\331\250\221\321\073\372\210\055\302\377\370\315\063\223
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\103\110\061
-\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
-\151\147\156\040\101\107\061\037\060\035\006\003\125\004\003\023
-\026\123\167\151\163\163\123\151\147\156\040\107\157\154\144\040
-\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\273\100\034\103\365\136\117\260
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "SwissSign Silver CA - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SwissSign Silver CA - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061
-\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
-\151\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023
-\030\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145
-\162\040\103\101\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061
-\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
-\151\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023
-\030\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145
-\162\040\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\117\033\324\057\124\273\057\113
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\275\060\202\003\245\240\003\002\001\002\002\010\117
-\033\324\057\124\273\057\113\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\060\107\061\013\060\011\006\003\125\004
-\006\023\002\103\110\061\025\060\023\006\003\125\004\012\023\014
-\123\167\151\163\163\123\151\147\156\040\101\107\061\041\060\037
-\006\003\125\004\003\023\030\123\167\151\163\163\123\151\147\156
-\040\123\151\154\166\145\162\040\103\101\040\055\040\107\062\060
-\036\027\015\060\066\061\060\062\065\060\070\063\062\064\066\132
-\027\015\063\066\061\060\062\065\060\070\063\062\064\066\132\060
-\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061\025
-\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123\151
-\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023\030
-\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145\162
-\040\103\101\040\055\040\107\062\060\202\002\042\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017\000
-\060\202\002\012\002\202\002\001\000\304\361\207\177\323\170\061
-\367\070\311\370\303\231\103\274\307\367\274\067\347\116\161\272
-\113\217\245\163\035\134\156\230\256\003\127\256\070\067\103\057
-\027\075\037\310\316\150\020\301\170\256\031\003\053\020\372\054
-\171\203\366\350\271\150\271\125\362\004\104\247\071\371\374\004
-\213\036\361\242\115\047\371\141\173\272\267\345\242\023\266\353
-\141\076\320\154\321\346\373\372\136\355\035\264\236\240\065\133
-\241\222\313\360\111\222\376\205\012\005\076\346\331\013\342\117
-\273\334\225\067\374\221\351\062\065\042\321\037\072\116\047\205
-\235\260\025\224\062\332\141\015\107\115\140\102\256\222\107\350
-\203\132\120\130\351\212\213\271\135\241\334\335\231\112\037\066
-\147\273\110\344\203\266\067\353\110\072\257\017\147\217\027\007
-\350\004\312\357\152\061\207\324\300\266\371\224\161\173\147\144
-\270\266\221\112\102\173\145\056\060\152\014\365\220\356\225\346
-\362\315\202\354\331\241\112\354\366\262\113\345\105\205\346\155
-\170\223\004\056\234\202\155\066\251\304\061\144\037\206\203\013
-\052\364\065\012\170\311\125\317\101\260\107\351\060\237\231\276
-\141\250\006\204\271\050\172\137\070\331\033\251\070\260\203\177
-\163\301\303\073\110\052\202\017\041\233\270\314\250\065\303\204
-\033\203\263\076\276\244\225\151\001\072\211\000\170\004\331\311
-\364\231\031\253\126\176\133\213\206\071\025\221\244\020\054\011
-\062\200\140\263\223\300\052\266\030\013\235\176\215\111\362\020
-\112\177\371\325\106\057\031\222\243\231\247\046\254\273\214\074
-\346\016\274\107\007\334\163\121\361\160\144\057\010\371\264\107
-\035\060\154\104\352\051\067\205\222\150\146\274\203\070\376\173
-\071\056\323\120\360\037\373\136\140\266\251\246\372\047\101\361
-\233\030\162\362\365\204\164\112\311\147\304\124\256\110\144\337
-\214\321\156\260\035\341\007\217\010\036\231\234\161\351\114\330
-\245\367\107\022\037\164\321\121\236\206\363\302\242\043\100\013
-\163\333\113\246\347\163\006\214\301\240\351\301\131\254\106\372
-\346\057\370\317\161\234\106\155\271\304\025\215\070\171\003\105
-\110\357\304\135\327\010\356\207\071\042\206\262\015\017\130\103
-\367\161\251\110\056\375\352\326\037\002\003\001\000\001\243\201
-\254\060\201\251\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004\005
-\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024
-\027\240\315\301\344\101\266\072\133\073\313\105\235\275\034\302
-\230\372\206\130\060\037\006\003\125\035\043\004\030\060\026\200
-\024\027\240\315\301\344\101\266\072\133\073\313\105\235\275\034
-\302\230\372\206\130\060\106\006\003\125\035\040\004\077\060\075
-\060\073\006\011\140\205\164\001\131\001\003\001\001\060\056\060
-\054\006\010\053\006\001\005\005\007\002\001\026\040\150\164\164
-\160\072\057\057\162\145\160\157\163\151\164\157\162\171\056\163
-\167\151\163\163\163\151\147\156\056\143\157\155\057\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001
-\000\163\306\201\340\047\322\055\017\340\225\060\342\232\101\177
-\120\054\137\137\142\141\251\206\152\151\030\014\164\111\326\135
-\204\352\101\122\030\157\130\255\120\126\040\152\306\275\050\151
-\130\221\334\221\021\065\251\072\035\274\032\245\140\236\330\037
-\177\105\221\151\331\176\273\170\162\301\006\017\052\316\217\205
-\160\141\254\240\315\013\270\071\051\126\204\062\116\206\273\075
-\304\052\331\327\037\162\356\376\121\241\042\101\261\161\002\143
-\032\202\260\142\253\136\127\022\037\337\313\335\165\240\300\135
-\171\220\214\033\340\120\346\336\061\376\230\173\160\137\245\220
-\330\255\370\002\266\157\323\140\335\100\113\042\305\075\255\072
-\172\237\032\032\107\221\171\063\272\202\334\062\151\003\226\156
-\037\113\360\161\376\343\147\162\240\261\277\134\213\344\372\231
-\042\307\204\271\033\215\043\227\077\355\045\340\317\145\273\365
-\141\004\357\335\036\262\132\101\042\132\241\237\135\054\350\133
-\311\155\251\014\014\170\252\140\306\126\217\001\132\014\150\274
-\151\031\171\304\037\176\227\005\277\305\351\044\121\136\324\325
-\113\123\355\331\043\132\066\003\145\243\301\003\255\101\060\363
-\106\033\205\220\257\145\265\325\261\344\026\133\170\165\035\227
-\172\155\131\251\052\217\173\336\303\207\211\020\231\111\163\170
-\310\075\275\121\065\164\052\325\361\176\151\033\052\273\073\275
-\045\270\232\132\075\162\141\220\146\207\356\014\326\115\324\021
-\164\013\152\376\013\003\374\243\125\127\211\376\112\313\256\133
-\027\005\310\362\215\043\061\123\070\322\055\152\077\202\271\215
-\010\152\367\136\101\164\156\303\021\176\007\254\051\140\221\077
-\070\312\127\020\015\275\060\057\307\245\346\101\240\332\256\005
-\207\232\240\244\145\154\114\011\014\211\272\270\323\271\300\223
-\212\060\372\215\345\232\153\025\001\116\147\252\332\142\126\076
-\204\010\146\322\304\066\175\247\076\020\374\210\340\324\200\345
-\000\275\252\363\116\006\243\172\152\371\142\162\343\011\117\353
-\233\016\001\043\361\237\273\174\334\334\154\021\227\045\262\362
-\264\143\024\322\006\052\147\214\203\365\316\352\007\330\232\152
-\036\354\344\012\273\052\114\353\011\140\071\316\312\142\330\056
-\156
-END
-
-# Trust for Certificate "SwissSign Silver CA - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SwissSign Silver CA - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\233\252\345\237\126\356\041\313\103\132\276\045\223\337\247\360
-\100\321\035\313
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\340\006\241\311\175\317\311\374\015\300\126\165\226\330\142\023
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061
-\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
-\151\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023
-\030\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145
-\162\040\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\117\033\324\057\124\273\057\113
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GeoTrust Primary Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Primary Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\130\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\061\060\057\006\003\125\004\003
-\023\050\107\145\157\124\162\165\163\164\040\120\162\151\155\141
-\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\130\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\061\060\057\006\003\125\004\003
-\023\050\107\145\157\124\162\165\163\164\040\120\162\151\155\141
-\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\030\254\265\152\375\151\266\025\072\143\154\257\332\372
-\304\241
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\174\060\202\002\144\240\003\002\001\002\002\020\030
-\254\265\152\375\151\266\025\072\143\154\257\332\372\304\241\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\130
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026\060
-\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163\164
-\040\111\156\143\056\061\061\060\057\006\003\125\004\003\023\050
-\107\145\157\124\162\165\163\164\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\060\036\027\015\060\066\061\061
-\062\067\060\060\060\060\060\060\132\027\015\063\066\060\067\061
-\066\062\063\065\071\065\071\132\060\130\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\026\060\024\006\003\125\004\012
-\023\015\107\145\157\124\162\165\163\164\040\111\156\143\056\061
-\061\060\057\006\003\125\004\003\023\050\107\145\157\124\162\165
-\163\164\040\120\162\151\155\141\162\171\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\060\202\001\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202
-\001\001\000\276\270\025\173\377\324\174\175\147\255\203\144\173
-\310\102\123\055\337\366\204\010\040\141\326\001\131\152\234\104
-\021\257\357\166\375\225\176\316\141\060\273\172\203\137\002\275
-\001\146\312\356\025\215\157\241\060\234\275\241\205\236\224\072
-\363\126\210\000\061\317\330\356\152\226\002\331\355\003\214\373
-\165\155\347\352\270\125\026\005\026\232\364\340\136\261\210\300
-\144\205\134\025\115\210\307\267\272\340\165\351\255\005\075\235
-\307\211\110\340\273\050\310\003\341\060\223\144\136\122\300\131
-\160\042\065\127\210\212\361\225\012\203\327\274\061\163\001\064
-\355\357\106\161\340\153\002\250\065\162\153\227\233\146\340\313
-\034\171\137\330\032\004\150\036\107\002\346\235\140\342\066\227
-\001\337\316\065\222\337\276\147\307\155\167\131\073\217\235\326
-\220\025\224\274\102\064\020\301\071\371\261\047\076\176\326\212
-\165\305\262\257\226\323\242\336\233\344\230\276\175\341\351\201
-\255\266\157\374\327\016\332\340\064\260\015\032\167\347\343\010
-\230\357\130\372\234\204\267\066\257\302\337\254\322\364\020\006
-\160\161\065\002\003\001\000\001\243\102\060\100\060\017\006\003
-\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016\006
-\003\125\035\017\001\001\377\004\004\003\002\001\006\060\035\006
-\003\125\035\016\004\026\004\024\054\325\120\101\227\025\213\360
-\217\066\141\133\112\373\153\331\231\311\063\222\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000
-\132\160\177\054\335\267\064\117\365\206\121\251\046\276\113\270
-\252\361\161\015\334\141\307\240\352\064\036\172\167\017\004\065
-\350\047\217\154\220\277\221\026\044\106\076\112\116\316\053\026
-\325\013\122\035\374\037\147\242\002\105\061\117\316\363\372\003
-\247\171\235\123\152\331\332\143\072\370\200\327\323\231\341\245
-\341\276\324\125\161\230\065\072\276\223\352\256\255\102\262\220
-\157\340\374\041\115\065\143\063\211\111\326\233\116\312\307\347
-\116\011\000\367\332\307\357\231\142\231\167\266\225\042\136\212
-\240\253\364\270\170\230\312\070\031\231\311\162\236\170\315\113
-\254\257\031\240\163\022\055\374\302\101\272\201\221\332\026\132
-\061\267\371\264\161\200\022\110\231\162\163\132\131\123\301\143
-\122\063\355\247\311\322\071\002\160\372\340\261\102\146\051\252
-\233\121\355\060\124\042\024\137\331\253\035\301\344\224\360\370
-\365\053\367\352\312\170\106\326\270\221\375\246\015\053\032\024
-\001\076\200\360\102\240\225\007\136\155\315\314\113\244\105\215
-\253\022\350\263\336\132\345\240\174\350\017\042\035\132\351\131
-END
-
-# Trust for Certificate "GeoTrust Primary Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Primary Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\062\074\021\216\033\367\270\266\122\124\342\342\020\015\326\002
-\220\067\360\226
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\002\046\303\001\136\010\060\067\103\251\320\175\317\067\346\277
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\130\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165
-\163\164\040\111\156\143\056\061\061\060\057\006\003\125\004\003
-\023\050\107\145\157\124\162\165\163\164\040\120\162\151\155\141
-\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\030\254\265\152\375\151\266\025\072\143\154\257\332\372
-\304\241
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "thawte Primary Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "thawte Primary Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\251\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164
-\145\054\040\111\156\143\056\061\050\060\046\006\003\125\004\013
-\023\037\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\123\145\162\166\151\143\145\163\040\104\151\166\151\163\151\157
-\156\061\070\060\066\006\003\125\004\013\023\057\050\143\051\040
-\062\060\060\066\040\164\150\141\167\164\145\054\040\111\156\143
-\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151\172
-\145\144\040\165\163\145\040\157\156\154\171\061\037\060\035\006
-\003\125\004\003\023\026\164\150\141\167\164\145\040\120\162\151
-\155\141\162\171\040\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\251\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164
-\145\054\040\111\156\143\056\061\050\060\046\006\003\125\004\013
-\023\037\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\123\145\162\166\151\143\145\163\040\104\151\166\151\163\151\157
-\156\061\070\060\066\006\003\125\004\013\023\057\050\143\051\040
-\062\060\060\066\040\164\150\141\167\164\145\054\040\111\156\143
-\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151\172
-\145\144\040\165\163\145\040\157\156\154\171\061\037\060\035\006
-\003\125\004\003\023\026\164\150\141\167\164\145\040\120\162\151
-\155\141\162\171\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\064\116\325\127\040\325\355\354\111\364\057\316\067\333
-\053\155
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\040\060\202\003\010\240\003\002\001\002\002\020\064
-\116\325\127\040\325\355\354\111\364\057\316\067\333\053\155\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\251\061\013\060\011\006\003\125\004\006\023\002\125\123\061\025
-\060\023\006\003\125\004\012\023\014\164\150\141\167\164\145\054
-\040\111\156\143\056\061\050\060\046\006\003\125\004\013\023\037
-\103\145\162\164\151\146\151\143\141\164\151\157\156\040\123\145
-\162\166\151\143\145\163\040\104\151\166\151\163\151\157\156\061
-\070\060\066\006\003\125\004\013\023\057\050\143\051\040\062\060
-\060\066\040\164\150\141\167\164\145\054\040\111\156\143\056\040
-\055\040\106\157\162\040\141\165\164\150\157\162\151\172\145\144
-\040\165\163\145\040\157\156\154\171\061\037\060\035\006\003\125
-\004\003\023\026\164\150\141\167\164\145\040\120\162\151\155\141
-\162\171\040\122\157\157\164\040\103\101\060\036\027\015\060\066
-\061\061\061\067\060\060\060\060\060\060\132\027\015\063\066\060
-\067\061\066\062\063\065\071\065\071\132\060\201\251\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\025\060\023\006\003
-\125\004\012\023\014\164\150\141\167\164\145\054\040\111\156\143
-\056\061\050\060\046\006\003\125\004\013\023\037\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\123\145\162\166\151\143
-\145\163\040\104\151\166\151\163\151\157\156\061\070\060\066\006
-\003\125\004\013\023\057\050\143\051\040\062\060\060\066\040\164
-\150\141\167\164\145\054\040\111\156\143\056\040\055\040\106\157
-\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163\145
-\040\157\156\154\171\061\037\060\035\006\003\125\004\003\023\026
-\164\150\141\167\164\145\040\120\162\151\155\141\162\171\040\122
-\157\157\164\040\103\101\060\202\001\042\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202
-\001\012\002\202\001\001\000\254\240\360\373\200\131\324\234\307
-\244\317\235\241\131\163\011\020\105\014\015\054\156\150\361\154
-\133\110\150\111\131\067\374\013\063\031\302\167\177\314\020\055
-\225\064\034\346\353\115\011\247\034\322\270\311\227\066\002\267
-\211\324\044\137\006\300\314\104\224\224\215\002\142\157\353\132
-\335\021\215\050\232\134\204\220\020\172\015\275\164\146\057\152
-\070\240\342\325\124\104\353\035\007\237\007\272\157\356\351\375
-\116\013\051\365\076\204\240\001\361\234\253\370\034\176\211\244
-\350\241\330\161\145\015\243\121\173\356\274\322\042\140\015\271
-\133\235\337\272\374\121\133\013\257\230\262\351\056\351\004\350
-\142\207\336\053\310\327\116\301\114\144\036\335\317\207\130\272
-\112\117\312\150\007\035\034\235\112\306\325\057\221\314\174\161
-\162\034\305\300\147\353\062\375\311\222\134\224\332\205\300\233
-\277\123\175\053\011\364\214\235\221\037\227\152\122\313\336\011
-\066\244\167\330\173\207\120\104\325\076\156\051\151\373\071\111
-\046\036\011\245\200\173\100\055\353\350\047\205\311\376\141\375
-\176\346\174\227\035\325\235\002\003\001\000\001\243\102\060\100
-\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001
-\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001
-\006\060\035\006\003\125\035\016\004\026\004\024\173\133\105\317
-\257\316\313\172\375\061\222\032\152\266\363\106\353\127\110\120
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\001\001\000\171\021\300\113\263\221\266\374\360\351\147\324
-\015\156\105\276\125\350\223\322\316\003\077\355\332\045\260\035
-\127\313\036\072\166\240\114\354\120\166\350\144\162\014\244\251
-\361\270\213\326\326\207\204\273\062\345\101\021\300\167\331\263
-\140\235\353\033\325\321\156\104\104\251\246\001\354\125\142\035
-\167\270\134\216\110\111\174\234\073\127\021\254\255\163\067\216
-\057\170\134\220\150\107\331\140\140\346\374\007\075\042\040\027
-\304\367\026\351\304\330\162\371\310\163\174\337\026\057\025\251
-\076\375\152\047\266\241\353\132\272\230\037\325\343\115\144\012
-\235\023\310\141\272\365\071\034\207\272\270\275\173\042\177\366
-\376\254\100\171\345\254\020\157\075\217\033\171\166\213\304\067
-\263\041\030\204\345\066\000\353\143\040\231\271\351\376\063\004
-\273\101\310\301\002\371\104\143\040\236\201\316\102\323\326\077
-\054\166\323\143\234\131\335\217\246\341\016\240\056\101\367\056
-\225\107\317\274\375\063\363\366\013\141\176\176\221\053\201\107
-\302\047\060\356\247\020\135\067\217\134\071\053\344\004\360\173
-\215\126\214\150
-END
-
-# Trust for Certificate "thawte Primary Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "thawte Primary Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\221\306\326\356\076\212\310\143\204\345\110\302\231\051\134\165
-\154\201\173\201
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\214\312\334\013\042\316\365\276\162\254\101\032\021\250\330\022
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\251\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164
-\145\054\040\111\156\143\056\061\050\060\046\006\003\125\004\013
-\023\037\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\123\145\162\166\151\143\145\163\040\104\151\166\151\163\151\157
-\156\061\070\060\066\006\003\125\004\013\023\057\050\143\051\040
-\062\060\060\066\040\164\150\141\167\164\145\054\040\111\156\143
-\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151\172
-\145\144\040\165\163\145\040\157\156\154\171\061\037\060\035\006
-\003\125\004\003\023\026\164\150\141\167\164\145\040\120\162\151
-\155\141\162\171\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\064\116\325\127\040\325\355\354\111\364\057\316\067\333
-\053\155
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "VeriSign Class 3 Public Primary Certification Authority - G5"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "VeriSign Class 3 Public Primary Certification Authority - G5"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\062\060\060\066\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\065
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\062\060\060\066\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\030\332\321\236\046\175\350\273\112\041\130\315\314\153
-\073\112
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\323\060\202\003\273\240\003\002\001\002\002\020\030
-\332\321\236\046\175\350\273\112\041\130\315\314\153\073\112\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\312\061\013\060\011\006\003\125\004\006\023\002\125\123\061\027
-\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151\147
-\156\054\040\111\156\143\056\061\037\060\035\006\003\125\004\013
-\023\026\126\145\162\151\123\151\147\156\040\124\162\165\163\164
-\040\116\145\164\167\157\162\153\061\072\060\070\006\003\125\004
-\013\023\061\050\143\051\040\062\060\060\066\040\126\145\162\151
-\123\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162
-\040\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040
-\157\156\154\171\061\105\060\103\006\003\125\004\003\023\074\126
-\145\162\151\123\151\147\156\040\103\154\141\163\163\040\063\040
-\120\165\142\154\151\143\040\120\162\151\155\141\162\171\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\065\060\036\027\015\060
-\066\061\061\060\070\060\060\060\060\060\060\132\027\015\063\066
-\060\067\061\066\062\063\065\071\065\071\132\060\201\312\061\013
-\060\011\006\003\125\004\006\023\002\125\123\061\027\060\025\006
-\003\125\004\012\023\016\126\145\162\151\123\151\147\156\054\040
-\111\156\143\056\061\037\060\035\006\003\125\004\013\023\026\126
-\145\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145
-\164\167\157\162\153\061\072\060\070\006\003\125\004\013\023\061
-\050\143\051\040\062\060\060\066\040\126\145\162\151\123\151\147
-\156\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165
-\164\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154
-\171\061\105\060\103\006\003\125\004\003\023\074\126\145\162\151
-\123\151\147\156\040\103\154\141\163\163\040\063\040\120\165\142
-\154\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\040\055\040\107\065\060\202\001\042\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000
-\060\202\001\012\002\202\001\001\000\257\044\010\010\051\172\065
-\236\140\014\252\347\113\073\116\334\174\274\074\105\034\273\053
-\340\376\051\002\371\127\010\243\144\205\025\047\365\361\255\310
-\061\211\135\042\350\052\252\246\102\263\217\370\271\125\267\261
-\267\113\263\376\217\176\007\127\354\357\103\333\146\142\025\141
-\317\140\015\244\330\336\370\340\303\142\010\075\124\023\353\111
-\312\131\124\205\046\345\053\217\033\237\353\365\241\221\302\063
-\111\330\103\143\152\122\113\322\217\350\160\121\115\321\211\151
-\173\307\160\366\263\334\022\164\333\173\135\113\126\323\226\277
-\025\167\241\260\364\242\045\362\257\034\222\147\030\345\364\006
-\004\357\220\271\344\000\344\335\072\265\031\377\002\272\364\074
-\356\340\213\353\067\213\354\364\327\254\362\366\360\075\257\335
-\165\221\063\031\035\034\100\313\164\044\031\041\223\331\024\376
-\254\052\122\307\217\325\004\111\344\215\143\107\210\074\151\203
-\313\376\107\275\053\176\117\305\225\256\016\235\324\321\103\300
-\147\163\343\024\010\176\345\077\237\163\270\063\012\317\135\077
-\064\207\226\212\356\123\350\045\025\002\003\001\000\001\243\201
-\262\060\201\257\060\017\006\003\125\035\023\001\001\377\004\005
-\060\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004
-\004\003\002\001\006\060\155\006\010\053\006\001\005\005\007\001
-\014\004\141\060\137\241\135\240\133\060\131\060\127\060\125\026
-\011\151\155\141\147\145\057\147\151\146\060\041\060\037\060\007
-\006\005\053\016\003\002\032\004\024\217\345\323\032\206\254\215
-\216\153\303\317\200\152\324\110\030\054\173\031\056\060\045\026
-\043\150\164\164\160\072\057\057\154\157\147\157\056\166\145\162
-\151\163\151\147\156\056\143\157\155\057\166\163\154\157\147\157
-\056\147\151\146\060\035\006\003\125\035\016\004\026\004\024\177
-\323\145\247\302\335\354\273\360\060\011\363\103\071\372\002\257
-\063\061\063\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\003\202\001\001\000\223\044\112\060\137\142\317\330\032
-\230\057\075\352\334\231\055\275\167\366\245\171\042\070\354\304
-\247\240\170\022\255\142\016\105\160\144\305\347\227\146\055\230
-\011\176\137\257\326\314\050\145\362\001\252\010\032\107\336\371
-\371\174\222\132\010\151\040\015\331\076\155\156\074\015\156\330
-\346\006\221\100\030\271\370\301\355\337\333\101\252\340\226\040
-\311\315\144\025\070\201\311\224\356\242\204\051\013\023\157\216
-\333\014\335\045\002\333\244\213\031\104\322\101\172\005\151\112
-\130\117\140\312\176\202\152\013\002\252\045\027\071\265\333\177
-\347\204\145\052\225\212\275\206\336\136\201\026\203\055\020\314
-\336\375\250\202\052\155\050\037\015\013\304\345\347\032\046\031
-\341\364\021\157\020\265\225\374\347\102\005\062\333\316\235\121
-\136\050\266\236\205\323\133\357\245\175\105\100\162\216\267\016
-\153\016\006\373\063\065\110\161\270\235\047\213\304\145\137\015
-\206\166\234\104\172\366\225\134\366\135\062\010\063\244\124\266
-\030\077\150\134\362\102\112\205\070\124\203\137\321\350\054\362
-\254\021\326\250\355\143\152
-END
-
-# Trust for Certificate "VeriSign Class 3 Public Primary Certification Authority - G5"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "VeriSign Class 3 Public Primary Certification Authority - G5"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\116\266\325\170\111\233\034\317\137\130\036\255\126\276\075\233
-\147\104\245\345
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\313\027\344\061\147\076\342\011\376\105\127\223\363\012\372\034
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\062\060\060\066\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\030\332\321\236\046\175\350\273\112\041\130\315\314\153
-\073\112
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "SecureTrust CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SecureTrust CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\110\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\023\027\123\145\143\165\162\145
-\124\162\165\163\164\040\103\157\162\160\157\162\141\164\151\157
-\156\061\027\060\025\006\003\125\004\003\023\016\123\145\143\165
-\162\145\124\162\165\163\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\110\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\023\027\123\145\143\165\162\145
-\124\162\165\163\164\040\103\157\162\160\157\162\141\164\151\157
-\156\061\027\060\025\006\003\125\004\003\023\016\123\145\143\165
-\162\145\124\162\165\163\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\014\360\216\134\010\026\245\255\102\177\360\353\047\030
-\131\320
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\270\060\202\002\240\240\003\002\001\002\002\020\014
-\360\216\134\010\026\245\255\102\177\360\353\047\030\131\320\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\110
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\040\060
-\036\006\003\125\004\012\023\027\123\145\143\165\162\145\124\162
-\165\163\164\040\103\157\162\160\157\162\141\164\151\157\156\061
-\027\060\025\006\003\125\004\003\023\016\123\145\143\165\162\145
-\124\162\165\163\164\040\103\101\060\036\027\015\060\066\061\061
-\060\067\061\071\063\061\061\070\132\027\015\062\071\061\062\063
-\061\061\071\064\060\065\065\132\060\110\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\040\060\036\006\003\125\004\012
-\023\027\123\145\143\165\162\145\124\162\165\163\164\040\103\157
-\162\160\157\162\141\164\151\157\156\061\027\060\025\006\003\125
-\004\003\023\016\123\145\143\165\162\145\124\162\165\163\164\040
-\103\101\060\202\001\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202
-\001\001\000\253\244\201\345\225\315\365\366\024\216\302\117\312
-\324\342\170\225\130\234\101\341\015\231\100\044\027\071\221\063
-\146\351\276\341\203\257\142\134\211\321\374\044\133\141\263\340
-\021\021\101\034\035\156\360\270\273\370\336\247\201\272\246\110
-\306\237\035\275\276\216\251\101\076\270\224\355\051\032\324\216
-\322\003\035\003\357\155\015\147\034\127\327\006\255\312\310\365
-\376\016\257\146\045\110\004\226\013\135\243\272\026\303\010\117
-\321\106\370\024\134\362\310\136\001\231\155\375\210\314\206\250
-\301\157\061\102\154\122\076\150\313\363\031\064\337\273\207\030
-\126\200\046\304\320\334\300\157\337\336\240\302\221\026\240\144
-\021\113\104\274\036\366\347\372\143\336\146\254\166\244\161\243
-\354\066\224\150\172\167\244\261\347\016\057\201\172\342\265\162
-\206\357\242\153\213\360\017\333\323\131\077\272\162\274\104\044
-\234\343\163\263\367\257\127\057\102\046\235\251\164\272\000\122
-\362\113\315\123\174\107\013\066\205\016\146\251\010\227\026\064
-\127\301\146\367\200\343\355\160\124\307\223\340\056\050\025\131
-\207\272\273\002\003\001\000\001\243\201\235\060\201\232\060\023
-\006\011\053\006\001\004\001\202\067\024\002\004\006\036\004\000
-\103\000\101\060\013\006\003\125\035\017\004\004\003\002\001\206
-\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001
-\377\060\035\006\003\125\035\016\004\026\004\024\102\062\266\026
-\372\004\375\376\135\113\172\303\375\367\114\100\035\132\103\257
-\060\064\006\003\125\035\037\004\055\060\053\060\051\240\047\240
-\045\206\043\150\164\164\160\072\057\057\143\162\154\056\163\145
-\143\165\162\145\164\162\165\163\164\056\143\157\155\057\123\124
-\103\101\056\143\162\154\060\020\006\011\053\006\001\004\001\202
-\067\025\001\004\003\002\001\000\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\202\001\001\000\060\355\117\112
-\341\130\072\122\162\133\265\246\243\145\030\246\273\121\073\167
-\351\235\352\323\237\134\340\105\145\173\015\312\133\342\160\120
-\262\224\005\024\256\111\307\215\101\007\022\163\224\176\014\043
-\041\375\274\020\177\140\020\132\162\365\230\016\254\354\271\177
-\335\172\157\135\323\034\364\377\210\005\151\102\251\005\161\310
-\267\254\046\350\056\264\214\152\377\161\334\270\261\337\231\274
-\174\041\124\053\344\130\242\273\127\051\256\236\251\243\031\046
-\017\231\056\010\260\357\375\151\317\231\032\011\215\343\247\237
-\053\311\066\064\173\044\263\170\114\225\027\244\006\046\036\266
-\144\122\066\137\140\147\331\234\305\005\164\013\347\147\043\322
-\010\374\210\351\256\213\177\341\060\364\067\176\375\306\062\332
-\055\236\104\060\060\154\356\007\336\322\064\374\322\377\100\366
-\113\364\146\106\006\124\246\362\062\012\143\046\060\153\233\321
-\334\213\107\272\341\271\325\142\320\242\240\364\147\005\170\051
-\143\032\157\004\326\370\306\114\243\232\261\067\264\215\345\050
-\113\035\236\054\302\270\150\274\355\002\356\061
-END
-
-# Trust for Certificate "SecureTrust CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SecureTrust CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\207\202\306\303\004\065\073\317\322\226\222\322\131\076\175\104
-\331\064\377\021
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\334\062\303\247\155\045\127\307\150\011\235\352\055\251\242\321
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\110\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\023\027\123\145\143\165\162\145
-\124\162\165\163\164\040\103\157\162\160\157\162\141\164\151\157
-\156\061\027\060\025\006\003\125\004\003\023\016\123\145\143\165
-\162\145\124\162\165\163\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\014\360\216\134\010\026\245\255\102\177\360\353\047\030
-\131\320
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Secure Global CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Secure Global CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\023\027\123\145\143\165\162\145
-\124\162\165\163\164\040\103\157\162\160\157\162\141\164\151\157
-\156\061\031\060\027\006\003\125\004\003\023\020\123\145\143\165
-\162\145\040\107\154\157\142\141\154\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\023\027\123\145\143\165\162\145
-\124\162\165\163\164\040\103\157\162\160\157\162\141\164\151\157
-\156\061\031\060\027\006\003\125\004\003\023\020\123\145\143\165
-\162\145\040\107\154\157\142\141\154\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\007\126\042\244\350\324\212\211\115\364\023\310\360\370
-\352\245
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\274\060\202\002\244\240\003\002\001\002\002\020\007
-\126\042\244\350\324\212\211\115\364\023\310\360\370\352\245\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\112
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\040\060
-\036\006\003\125\004\012\023\027\123\145\143\165\162\145\124\162
-\165\163\164\040\103\157\162\160\157\162\141\164\151\157\156\061
-\031\060\027\006\003\125\004\003\023\020\123\145\143\165\162\145
-\040\107\154\157\142\141\154\040\103\101\060\036\027\015\060\066
-\061\061\060\067\061\071\064\062\062\070\132\027\015\062\071\061
-\062\063\061\061\071\065\062\060\066\132\060\112\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\040\060\036\006\003\125
-\004\012\023\027\123\145\143\165\162\145\124\162\165\163\164\040
-\103\157\162\160\157\162\141\164\151\157\156\061\031\060\027\006
-\003\125\004\003\023\020\123\145\143\165\162\145\040\107\154\157
-\142\141\154\040\103\101\060\202\001\042\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202
-\001\012\002\202\001\001\000\257\065\056\330\254\154\125\151\006
-\161\345\023\150\044\263\117\330\314\041\107\370\361\140\070\211
-\211\003\351\275\352\136\106\123\011\334\134\365\132\350\367\105
-\052\002\353\061\141\327\051\063\114\316\307\174\012\067\176\017
-\272\062\230\341\035\227\257\217\307\334\311\070\226\363\333\032
-\374\121\355\150\306\320\156\244\174\044\321\256\102\310\226\120
-\143\056\340\376\165\376\230\247\137\111\056\225\343\071\063\144
-\216\036\244\137\220\322\147\074\262\331\376\101\271\125\247\011
-\216\162\005\036\213\335\104\205\202\102\320\111\300\035\140\360
-\321\027\054\225\353\366\245\301\222\243\305\302\247\010\140\015
-\140\004\020\226\171\236\026\064\346\251\266\372\045\105\071\310
-\036\145\371\223\365\252\361\122\334\231\230\075\245\206\032\014
-\065\063\372\113\245\004\006\025\034\061\200\357\252\030\153\302
-\173\327\332\316\371\063\040\325\365\275\152\063\055\201\004\373
-\260\134\324\234\243\342\134\035\343\251\102\165\136\173\324\167
-\357\071\124\272\311\012\030\033\022\231\111\057\210\113\375\120
-\142\321\163\347\217\172\103\002\003\001\000\001\243\201\235\060
-\201\232\060\023\006\011\053\006\001\004\001\202\067\024\002\004
-\006\036\004\000\103\000\101\060\013\006\003\125\035\017\004\004
-\003\002\001\206\060\017\006\003\125\035\023\001\001\377\004\005
-\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024
-\257\104\004\302\101\176\110\203\333\116\071\002\354\354\204\172
-\346\316\311\244\060\064\006\003\125\035\037\004\055\060\053\060
-\051\240\047\240\045\206\043\150\164\164\160\072\057\057\143\162
-\154\056\163\145\143\165\162\145\164\162\165\163\164\056\143\157
-\155\057\123\107\103\101\056\143\162\154\060\020\006\011\053\006
-\001\004\001\202\067\025\001\004\003\002\001\000\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000
-\143\032\010\100\175\244\136\123\015\167\330\172\256\037\015\013
-\121\026\003\357\030\174\310\343\257\152\130\223\024\140\221\262
-\204\334\210\116\276\071\212\072\363\346\202\211\135\001\067\263
-\253\044\244\025\016\222\065\132\112\104\136\116\127\372\165\316
-\037\110\316\146\364\074\100\046\222\230\154\033\356\044\106\014
-\027\263\122\245\333\245\221\221\317\067\323\157\347\047\010\072
-\116\031\037\072\247\130\134\027\317\171\077\213\344\247\323\046
-\043\235\046\017\130\151\374\107\176\262\320\215\213\223\277\051
-\117\103\151\164\166\147\113\317\007\214\346\002\367\265\341\264
-\103\265\113\055\024\237\371\334\046\015\277\246\107\164\006\330
-\210\321\072\051\060\204\316\322\071\200\142\033\250\307\127\111
-\274\152\125\121\147\025\112\276\065\007\344\325\165\230\067\171
-\060\024\333\051\235\154\305\151\314\107\125\242\060\367\314\134
-\177\302\303\230\034\153\116\026\200\353\172\170\145\105\242\000
-\032\257\014\015\125\144\064\110\270\222\271\361\264\120\051\362
-\117\043\037\332\154\254\037\104\341\335\043\170\121\133\307\026
-END
-
-# Trust for Certificate "Secure Global CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Secure Global CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\072\104\163\132\345\201\220\037\044\206\141\106\036\073\234\304
-\137\365\072\033
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\317\364\047\015\324\355\334\145\026\111\155\075\332\277\156\336
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\112\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\023\027\123\145\143\165\162\145
-\124\162\165\163\164\040\103\157\162\160\157\162\141\164\151\157
-\156\061\031\060\027\006\003\125\004\003\023\020\123\145\143\165
-\162\145\040\107\154\157\142\141\154\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\007\126\042\244\350\324\212\211\115\364\023\310\360\370
-\352\245
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "COMODO Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "COMODO Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\201\061\013\060\011\006\003\125\004\006\023\002\107\102
-\061\033\060\031\006\003\125\004\010\023\022\107\162\145\141\164
-\145\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060
-\016\006\003\125\004\007\023\007\123\141\154\146\157\162\144\061
-\032\060\030\006\003\125\004\012\023\021\103\117\115\117\104\117
-\040\103\101\040\114\151\155\151\164\145\144\061\047\060\045\006
-\003\125\004\003\023\036\103\117\115\117\104\117\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\201\061\013\060\011\006\003\125\004\006\023\002\107\102
-\061\033\060\031\006\003\125\004\010\023\022\107\162\145\141\164
-\145\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060
-\016\006\003\125\004\007\023\007\123\141\154\146\157\162\144\061
-\032\060\030\006\003\125\004\012\023\021\103\117\115\117\104\117
-\040\103\101\040\114\151\155\151\164\145\144\061\047\060\045\006
-\003\125\004\003\023\036\103\117\115\117\104\117\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\116\201\055\212\202\145\340\013\002\356\076\065\002\106
-\345\075
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\035\060\202\003\005\240\003\002\001\002\002\020\116
-\201\055\212\202\145\340\013\002\356\076\065\002\106\345\075\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\201\061\013\060\011\006\003\125\004\006\023\002\107\102\061\033
-\060\031\006\003\125\004\010\023\022\107\162\145\141\164\145\162
-\040\115\141\156\143\150\145\163\164\145\162\061\020\060\016\006
-\003\125\004\007\023\007\123\141\154\146\157\162\144\061\032\060
-\030\006\003\125\004\012\023\021\103\117\115\117\104\117\040\103
-\101\040\114\151\155\151\164\145\144\061\047\060\045\006\003\125
-\004\003\023\036\103\117\115\117\104\117\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\060\036\027\015\060\066\061\062\060\061\060\060\060\060
-\060\060\132\027\015\062\071\061\062\063\061\062\063\065\071\065
-\071\132\060\201\201\061\013\060\011\006\003\125\004\006\023\002
-\107\102\061\033\060\031\006\003\125\004\010\023\022\107\162\145
-\141\164\145\162\040\115\141\156\143\150\145\163\164\145\162\061
-\020\060\016\006\003\125\004\007\023\007\123\141\154\146\157\162
-\144\061\032\060\030\006\003\125\004\012\023\021\103\117\115\117
-\104\117\040\103\101\040\114\151\155\151\164\145\144\061\047\060
-\045\006\003\125\004\003\023\036\103\117\115\117\104\117\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\060\202\001\042\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202
-\001\012\002\202\001\001\000\320\100\213\213\162\343\221\033\367
-\121\301\033\124\004\230\323\251\277\301\346\212\135\073\207\373
-\273\210\316\015\343\057\077\006\226\360\242\051\120\231\256\333
-\073\241\127\260\164\121\161\315\355\102\221\115\101\376\251\310
-\330\152\206\167\104\273\131\146\227\120\136\264\324\054\160\104
-\317\332\067\225\102\151\074\060\304\161\263\122\360\041\115\241
-\330\272\071\174\034\236\243\044\235\362\203\026\230\252\026\174
-\103\233\025\133\267\256\064\221\376\324\142\046\030\106\232\077
-\353\301\371\361\220\127\353\254\172\015\213\333\162\060\152\146
-\325\340\106\243\160\334\150\331\377\004\110\211\167\336\265\351
-\373\147\155\101\351\274\071\275\062\331\142\002\361\261\250\075
-\156\067\234\342\057\342\323\242\046\213\306\270\125\103\210\341
-\043\076\245\322\044\071\152\107\253\000\324\241\263\251\045\376
-\015\077\247\035\272\323\121\301\013\244\332\254\070\357\125\120
-\044\005\145\106\223\064\117\055\215\255\306\324\041\031\322\216
-\312\005\141\161\007\163\107\345\212\031\022\275\004\115\316\116
-\234\245\110\254\273\046\367\002\003\001\000\001\243\201\216\060
-\201\213\060\035\006\003\125\035\016\004\026\004\024\013\130\345
-\213\306\114\025\067\244\100\251\060\251\041\276\107\066\132\126
-\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001
-\006\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
-\001\377\060\111\006\003\125\035\037\004\102\060\100\060\076\240
-\074\240\072\206\070\150\164\164\160\072\057\057\143\162\154\056
-\143\157\155\157\144\157\143\141\056\143\157\155\057\103\117\115
-\117\104\117\103\145\162\164\151\146\151\143\141\164\151\157\156
-\101\165\164\150\157\162\151\164\171\056\143\162\154\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001
-\000\076\230\236\233\366\033\351\327\071\267\170\256\035\162\030
-\111\323\207\344\103\202\353\077\311\252\365\250\265\357\125\174
-\041\122\145\371\325\015\341\154\364\076\214\223\163\221\056\002
-\304\116\007\161\157\300\217\070\141\010\250\036\201\012\300\057
-\040\057\101\213\221\334\110\105\274\361\306\336\272\166\153\063
-\310\000\055\061\106\114\355\347\235\317\210\224\377\063\300\126
-\350\044\206\046\270\330\070\070\337\052\153\335\022\314\307\077
-\107\027\114\242\302\006\226\011\326\333\376\077\074\106\101\337
-\130\342\126\017\074\073\301\034\223\065\331\070\122\254\356\310
-\354\056\060\116\224\065\264\044\037\113\170\151\332\362\002\070
-\314\225\122\223\360\160\045\131\234\040\147\304\356\371\213\127
-\141\364\222\166\175\077\204\215\125\267\350\345\254\325\361\365
-\031\126\246\132\373\220\034\257\223\353\345\034\324\147\227\135
-\004\016\276\013\203\246\027\203\271\060\022\240\305\063\025\005
-\271\015\373\307\005\166\343\330\112\215\374\064\027\243\306\041
-\050\276\060\105\061\036\307\170\276\130\141\070\254\073\342\001
-\145
-END
-
-# Trust for Certificate "COMODO Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "COMODO Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\146\061\277\236\367\117\236\266\311\325\246\014\272\152\276\321
-\367\275\357\173
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\134\110\334\367\102\162\354\126\224\155\034\314\161\065\200\165
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\201\061\013\060\011\006\003\125\004\006\023\002\107\102
-\061\033\060\031\006\003\125\004\010\023\022\107\162\145\141\164
-\145\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060
-\016\006\003\125\004\007\023\007\123\141\154\146\157\162\144\061
-\032\060\030\006\003\125\004\012\023\021\103\117\115\117\104\117
-\040\103\101\040\114\151\155\151\164\145\144\061\047\060\045\006
-\003\125\004\003\023\036\103\117\115\117\104\117\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\116\201\055\212\202\145\340\013\002\356\076\065\002\106
-\345\075
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Network Solutions Certificate Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Network Solutions Certificate Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\142\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\041\060\037\006\003\125\004\012\023\030\116\145\164\167\157\162
-\153\040\123\157\154\165\164\151\157\156\163\040\114\056\114\056
-\103\056\061\060\060\056\006\003\125\004\003\023\047\116\145\164
-\167\157\162\153\040\123\157\154\165\164\151\157\156\163\040\103
-\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150\157
-\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\142\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\041\060\037\006\003\125\004\012\023\030\116\145\164\167\157\162
-\153\040\123\157\154\165\164\151\157\156\163\040\114\056\114\056
-\103\056\061\060\060\056\006\003\125\004\003\023\047\116\145\164
-\167\157\162\153\040\123\157\154\165\164\151\157\156\163\040\103
-\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150\157
-\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\127\313\063\157\302\134\026\346\107\026\027\343\220\061
-\150\340
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\346\060\202\002\316\240\003\002\001\002\002\020\127
-\313\063\157\302\134\026\346\107\026\027\343\220\061\150\340\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\142
-\061\013\060\011\006\003\125\004\006\023\002\125\123\061\041\060
-\037\006\003\125\004\012\023\030\116\145\164\167\157\162\153\040
-\123\157\154\165\164\151\157\156\163\040\114\056\114\056\103\056
-\061\060\060\056\006\003\125\004\003\023\047\116\145\164\167\157
-\162\153\040\123\157\154\165\164\151\157\156\163\040\103\145\162
-\164\151\146\151\143\141\164\145\040\101\165\164\150\157\162\151
-\164\171\060\036\027\015\060\066\061\062\060\061\060\060\060\060
-\060\060\132\027\015\062\071\061\062\063\061\062\063\065\071\065
-\071\132\060\142\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\041\060\037\006\003\125\004\012\023\030\116\145\164\167
-\157\162\153\040\123\157\154\165\164\151\157\156\163\040\114\056
-\114\056\103\056\061\060\060\056\006\003\125\004\003\023\047\116
-\145\164\167\157\162\153\040\123\157\154\165\164\151\157\156\163
-\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164
-\150\157\162\151\164\171\060\202\001\042\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202
-\001\012\002\202\001\001\000\344\274\176\222\060\155\306\330\216
-\053\013\274\106\316\340\047\226\336\336\371\372\022\323\074\063
-\163\263\004\057\274\161\214\345\237\266\042\140\076\137\135\316
-\011\377\202\014\033\232\121\120\032\046\211\335\325\141\135\031
-\334\022\017\055\012\242\103\135\027\320\064\222\040\352\163\317
-\070\054\006\046\011\172\162\367\372\120\062\370\302\223\323\151
-\242\043\316\101\261\314\344\325\037\066\321\212\072\370\214\143
-\342\024\131\151\355\015\323\177\153\350\270\003\345\117\152\345
-\230\143\151\110\005\276\056\377\063\266\351\227\131\151\370\147
-\031\256\223\141\226\104\025\323\162\260\077\274\152\175\354\110
-\177\215\303\253\252\161\053\123\151\101\123\064\265\260\271\305
-\006\012\304\260\105\365\101\135\156\211\105\173\075\073\046\214
-\164\302\345\322\321\175\262\021\324\373\130\062\042\232\200\311
-\334\375\014\351\177\136\003\227\316\073\000\024\207\047\160\070
-\251\216\156\263\047\166\230\121\340\005\343\041\253\032\325\205
-\042\074\051\265\232\026\305\200\250\364\273\153\060\217\057\106
-\002\242\261\014\042\340\323\002\003\001\000\001\243\201\227\060
-\201\224\060\035\006\003\125\035\016\004\026\004\024\041\060\311
-\373\000\327\116\230\332\207\252\052\320\247\056\261\100\061\247
-\114\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001
-\006\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
-\001\377\060\122\006\003\125\035\037\004\113\060\111\060\107\240
-\105\240\103\206\101\150\164\164\160\072\057\057\143\162\154\056
-\156\145\164\163\157\154\163\163\154\056\143\157\155\057\116\145
-\164\167\157\162\153\123\157\154\165\164\151\157\156\163\103\145
-\162\164\151\146\151\143\141\164\145\101\165\164\150\157\162\151
-\164\171\056\143\162\154\060\015\006\011\052\206\110\206\367\015
-\001\001\005\005\000\003\202\001\001\000\273\256\113\347\267\127
-\353\177\252\055\267\163\107\205\152\301\344\245\035\344\347\074
-\351\364\131\145\167\265\172\133\132\215\045\066\340\172\227\056
-\070\300\127\140\203\230\006\203\237\271\166\172\156\120\340\272
-\210\054\374\105\314\030\260\231\225\121\016\354\035\270\210\377
-\207\120\034\202\302\343\340\062\200\277\240\013\107\310\303\061
-\357\231\147\062\200\117\027\041\171\014\151\134\336\136\064\256
-\002\265\046\352\120\337\177\030\145\054\311\362\143\341\251\007
-\376\174\161\037\153\063\044\152\036\005\367\005\150\300\152\022
-\313\056\136\141\313\256\050\323\176\302\264\146\221\046\137\074
-\056\044\137\313\130\017\353\050\354\257\021\226\363\334\173\157
-\300\247\210\362\123\167\263\140\136\256\256\050\332\065\054\157
-\064\105\323\046\341\336\354\133\117\047\153\026\174\275\104\004
-\030\202\263\211\171\027\020\161\075\172\242\026\116\365\001\315
-\244\154\145\150\241\111\166\134\103\311\330\274\066\147\154\245
-\224\265\324\314\271\275\152\065\126\041\336\330\303\353\373\313
-\244\140\114\260\125\240\240\173\127\262
-END
-
-# Trust for Certificate "Network Solutions Certificate Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Network Solutions Certificate Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\164\370\243\303\357\347\263\220\006\113\203\220\074\041\144\140
-\040\345\337\316
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\323\363\246\026\300\372\153\035\131\261\055\226\115\016\021\056
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\142\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\041\060\037\006\003\125\004\012\023\030\116\145\164\167\157\162
-\153\040\123\157\154\165\164\151\157\156\163\040\114\056\114\056
-\103\056\061\060\060\056\006\003\125\004\003\023\047\116\145\164
-\167\157\162\153\040\123\157\154\165\164\151\157\156\163\040\103
-\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150\157
-\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\127\313\063\157\302\134\026\346\107\026\027\343\220\061
-\150\340
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "WellsSecure Public Root Certificate Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "WellsSecure Public Root Certificate Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163
-\040\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165
-\162\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154
-\154\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101
-\061\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163
-\123\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157
-\157\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101
-\165\164\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163
-\040\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165
-\162\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154
-\154\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101
-\061\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163
-\123\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157
-\157\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101
-\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\275\060\202\003\245\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163\040
-\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165\162
-\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154\154
-\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101\061
-\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163\123
-\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157\157
-\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165
-\164\150\157\162\151\164\171\060\036\027\015\060\067\061\062\061
-\063\061\067\060\067\065\064\132\027\015\062\062\061\062\061\064
-\060\060\060\067\065\064\132\060\201\205\061\013\060\011\006\003
-\125\004\006\023\002\125\123\061\040\060\036\006\003\125\004\012
-\014\027\127\145\154\154\163\040\106\141\162\147\157\040\127\145
-\154\154\163\123\145\143\165\162\145\061\034\060\032\006\003\125
-\004\013\014\023\127\145\154\154\163\040\106\141\162\147\157\040
-\102\141\156\153\040\116\101\061\066\060\064\006\003\125\004\003
-\014\055\127\145\154\154\163\123\145\143\165\162\145\040\120\165
-\142\154\151\143\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171\060
-\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001
-\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000
-\356\157\264\275\171\342\217\010\041\236\070\004\101\045\357\253
-\133\034\123\222\254\155\236\335\302\304\056\105\224\003\065\210
-\147\164\127\343\337\214\270\247\166\217\073\367\250\304\333\051
-\143\016\221\150\066\212\227\216\212\161\150\011\007\344\350\324
-\016\117\370\326\053\114\244\026\371\357\103\230\217\263\236\122
-\337\155\221\071\217\070\275\167\213\103\143\353\267\223\374\060
-\114\034\001\223\266\023\373\367\241\037\277\045\341\164\067\054
-\036\244\136\074\150\370\113\277\015\271\036\056\066\350\251\344
-\247\370\017\313\202\165\174\065\055\042\326\302\277\013\363\264
-\374\154\225\141\036\127\327\004\201\062\203\122\171\346\203\143
-\317\267\313\143\213\021\342\275\136\353\366\215\355\225\162\050
-\264\254\022\142\351\112\063\346\203\062\256\005\165\225\275\204
-\225\333\052\134\233\216\056\014\270\201\053\101\346\070\126\237
-\111\233\154\166\372\212\135\367\001\171\201\174\301\203\100\005
-\376\161\375\014\077\314\116\140\011\016\145\107\020\057\001\300
-\005\077\217\370\263\101\357\132\102\176\131\357\322\227\014\145
-\002\003\001\000\001\243\202\001\064\060\202\001\060\060\017\006
-\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\071
-\006\003\125\035\037\004\062\060\060\060\056\240\054\240\052\206
-\050\150\164\164\160\072\057\057\143\162\154\056\160\153\151\056
-\167\145\154\154\163\146\141\162\147\157\056\143\157\155\057\167
-\163\160\162\143\141\056\143\162\154\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\001\306\060\035\006\003\125\035\016
-\004\026\004\024\046\225\031\020\331\350\241\227\221\377\334\031
-\331\265\004\076\322\163\012\152\060\201\262\006\003\125\035\043
-\004\201\252\060\201\247\200\024\046\225\031\020\331\350\241\227
-\221\377\334\031\331\265\004\076\322\163\012\152\241\201\213\244
-\201\210\060\201\205\061\013\060\011\006\003\125\004\006\023\002
-\125\123\061\040\060\036\006\003\125\004\012\014\027\127\145\154
-\154\163\040\106\141\162\147\157\040\127\145\154\154\163\123\145
-\143\165\162\145\061\034\060\032\006\003\125\004\013\014\023\127
-\145\154\154\163\040\106\141\162\147\157\040\102\141\156\153\040
-\116\101\061\066\060\064\006\003\125\004\003\014\055\127\145\154
-\154\163\123\145\143\165\162\145\040\120\165\142\154\151\143\040
-\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\145
-\040\101\165\164\150\157\162\151\164\171\202\001\001\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001
-\000\271\025\261\104\221\314\043\310\053\115\167\343\370\232\173
-\047\015\315\162\273\231\000\312\174\146\031\120\306\325\230\355
-\253\277\003\132\345\115\345\036\310\117\161\227\206\325\343\035
-\375\220\311\074\165\167\127\172\175\370\336\364\324\325\367\225
-\346\164\156\035\074\256\174\235\333\002\003\005\054\161\113\045
-\076\007\343\136\232\365\146\027\051\210\032\070\237\317\252\101
-\003\204\227\153\223\070\172\312\060\104\033\044\104\063\320\344
-\321\334\050\070\364\023\103\065\065\051\143\250\174\242\265\255
-\070\244\355\255\375\306\232\037\377\227\163\376\373\263\065\247
-\223\206\306\166\221\000\346\254\121\026\304\047\062\134\333\163
-\332\245\223\127\216\076\155\065\046\010\131\325\347\104\327\166
-\040\143\347\254\023\147\303\155\261\160\106\174\325\226\021\075
-\211\157\135\250\241\353\215\012\332\303\035\063\154\243\352\147
-\031\232\231\177\113\075\203\121\052\035\312\057\206\014\242\176
-\020\055\053\324\026\225\013\007\252\056\024\222\111\267\051\157
-\330\155\061\175\365\374\241\020\007\207\316\057\131\334\076\130
-\333
-END
-
-# Trust for Certificate "WellsSecure Public Root Certificate Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "WellsSecure Public Root Certificate Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\347\264\366\235\141\354\220\151\333\176\220\247\100\032\074\364
-\175\117\350\356
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\025\254\245\302\222\055\171\274\350\177\313\147\355\002\317\066
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163
-\040\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165
-\162\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154
-\154\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101
-\061\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163
-\123\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157
-\157\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101
-\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "COMODO ECC Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "COMODO ECC Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\107\102
-\061\033\060\031\006\003\125\004\010\023\022\107\162\145\141\164
-\145\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060
-\016\006\003\125\004\007\023\007\123\141\154\146\157\162\144\061
-\032\060\030\006\003\125\004\012\023\021\103\117\115\117\104\117
-\040\103\101\040\114\151\155\151\164\145\144\061\053\060\051\006
-\003\125\004\003\023\042\103\117\115\117\104\117\040\105\103\103
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\107\102
-\061\033\060\031\006\003\125\004\010\023\022\107\162\145\141\164
-\145\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060
-\016\006\003\125\004\007\023\007\123\141\154\146\157\162\144\061
-\032\060\030\006\003\125\004\012\023\021\103\117\115\117\104\117
-\040\103\101\040\114\151\155\151\164\145\144\061\053\060\051\006
-\003\125\004\003\023\042\103\117\115\117\104\117\040\105\103\103
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\037\107\257\252\142\000\160\120\124\114\001\236\233\143
-\231\052
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\211\060\202\002\017\240\003\002\001\002\002\020\037
-\107\257\252\142\000\160\120\124\114\001\236\233\143\231\052\060
-\012\006\010\052\206\110\316\075\004\003\003\060\201\205\061\013
-\060\011\006\003\125\004\006\023\002\107\102\061\033\060\031\006
-\003\125\004\010\023\022\107\162\145\141\164\145\162\040\115\141
-\156\143\150\145\163\164\145\162\061\020\060\016\006\003\125\004
-\007\023\007\123\141\154\146\157\162\144\061\032\060\030\006\003
-\125\004\012\023\021\103\117\115\117\104\117\040\103\101\040\114
-\151\155\151\164\145\144\061\053\060\051\006\003\125\004\003\023
-\042\103\117\115\117\104\117\040\105\103\103\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\060\036\027\015\060\070\060\063\060\066\060\060\060
-\060\060\060\132\027\015\063\070\060\061\061\070\062\063\065\071
-\065\071\132\060\201\205\061\013\060\011\006\003\125\004\006\023
-\002\107\102\061\033\060\031\006\003\125\004\010\023\022\107\162
-\145\141\164\145\162\040\115\141\156\143\150\145\163\164\145\162
-\061\020\060\016\006\003\125\004\007\023\007\123\141\154\146\157
-\162\144\061\032\060\030\006\003\125\004\012\023\021\103\117\115
-\117\104\117\040\103\101\040\114\151\155\151\164\145\144\061\053
-\060\051\006\003\125\004\003\023\042\103\117\115\117\104\117\040
-\105\103\103\040\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\101\165\164\150\157\162\151\164\171\060\166\060\020\006
-\007\052\206\110\316\075\002\001\006\005\053\201\004\000\042\003
-\142\000\004\003\107\173\057\165\311\202\025\205\373\165\344\221
-\026\324\253\142\231\365\076\122\013\006\316\101\000\177\227\341
-\012\044\074\035\001\004\356\075\322\215\011\227\014\340\165\344
-\372\373\167\212\052\365\003\140\113\066\213\026\043\026\255\011
-\161\364\112\364\050\120\264\376\210\034\156\077\154\057\057\011
-\131\133\245\133\013\063\231\342\303\075\211\371\152\054\357\262
-\323\006\351\243\102\060\100\060\035\006\003\125\035\016\004\026
-\004\024\165\161\247\031\110\031\274\235\235\352\101\107\337\224
-\304\110\167\231\323\171\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\012\006\010\052\206\110\316\075
-\004\003\003\003\150\000\060\145\002\061\000\357\003\133\172\254
-\267\170\012\162\267\210\337\377\265\106\024\011\012\372\240\346
-\175\010\306\032\207\275\030\250\163\275\046\312\140\014\235\316
-\231\237\317\134\017\060\341\276\024\061\352\002\060\024\364\223
-\074\111\247\063\172\220\106\107\263\143\175\023\233\116\267\157
-\030\067\200\123\376\335\040\340\065\232\066\321\307\001\271\346
-\334\335\363\377\035\054\072\026\127\331\222\071\326
-END
-
-# Trust for Certificate "COMODO ECC Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "COMODO ECC Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\237\164\116\237\053\115\272\354\017\061\054\120\266\126\073\216
-\055\223\303\021
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\174\142\377\164\235\061\123\136\150\112\325\170\252\036\277\043
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\107\102
-\061\033\060\031\006\003\125\004\010\023\022\107\162\145\141\164
-\145\162\040\115\141\156\143\150\145\163\164\145\162\061\020\060
-\016\006\003\125\004\007\023\007\123\141\154\146\157\162\144\061
-\032\060\030\006\003\125\004\012\023\021\103\117\115\117\104\117
-\040\103\101\040\114\151\155\151\164\145\144\061\053\060\051\006
-\003\125\004\003\023\042\103\117\115\117\104\117\040\105\103\103
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\037\107\257\252\142\000\160\120\124\114\001\236\233\143
-\231\052
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "MD5 Collisions Forged Rogue CA 25c3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "MD5 Collisions Forged Rogue CA 25c3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\074\061\072\060\070\006\003\125\004\003\023\061\115\104\065
-\040\103\157\154\154\151\163\151\157\156\163\040\111\156\143\056
-\040\050\150\164\164\160\072\057\057\167\167\167\056\160\150\162
-\145\145\144\157\155\056\157\162\147\057\155\144\065\051
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060
-\053\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040
-\123\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102
-\165\163\151\156\145\163\163\040\103\101\055\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\102
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\062\060\202\003\233\240\003\002\001\002\002\001\102
-\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060
-\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061\034
-\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141\170
-\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060\053
-\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040\123
-\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102\165
-\163\151\156\145\163\163\040\103\101\055\061\060\036\027\015\060
-\064\060\067\063\061\060\060\060\060\060\061\132\027\015\060\064
-\060\071\060\062\060\060\060\060\060\061\132\060\074\061\072\060
-\070\006\003\125\004\003\023\061\115\104\065\040\103\157\154\154
-\151\163\151\157\156\163\040\111\156\143\056\040\050\150\164\164
-\160\072\057\057\167\167\167\056\160\150\162\145\145\144\157\155
-\056\157\162\147\057\155\144\065\051\060\201\237\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\201\215\000\060
-\201\211\002\201\201\000\272\246\131\311\054\050\326\052\260\370
-\355\237\106\244\244\067\356\016\031\150\131\321\263\003\231\121
-\326\026\232\136\067\153\025\340\016\113\365\204\144\370\243\333
-\101\157\065\325\233\025\037\333\304\070\122\160\201\227\136\217
-\240\265\367\176\071\360\062\254\036\255\104\322\263\372\110\303
-\316\221\233\354\364\234\174\341\132\365\310\067\153\232\203\336
-\347\312\040\227\061\102\163\025\221\150\364\210\257\371\050\050
-\305\351\017\163\260\027\113\023\114\231\165\320\104\346\176\010
-\154\032\362\117\033\101\002\003\001\000\001\243\202\002\044\060
-\202\002\040\060\013\006\003\125\035\017\004\004\003\002\001\306
-\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001
-\377\060\035\006\003\125\035\016\004\026\004\024\247\004\140\037
-\253\162\103\010\305\177\010\220\125\126\034\326\316\346\070\353
-\060\037\006\003\125\035\043\004\030\060\026\200\024\276\250\240
-\164\162\120\153\104\267\311\043\330\373\250\377\263\127\153\150
-\154\060\202\001\276\006\011\140\206\110\001\206\370\102\001\015
-\004\202\001\257\026\202\001\253\063\000\000\000\047\136\071\340
-\211\141\017\116\243\305\105\013\066\273\001\321\123\252\303\010
-\217\157\370\117\076\207\207\104\021\334\140\340\337\222\125\371
-\270\163\033\124\223\305\237\320\106\304\140\266\065\142\315\271
-\257\034\250\151\032\311\133\074\226\067\300\355\147\357\273\376
-\300\213\234\120\057\051\275\203\042\236\216\010\372\254\023\160
-\242\130\177\142\142\212\021\367\211\366\337\266\147\131\163\026
-\373\143\026\212\264\221\070\316\056\365\266\276\114\244\224\111
-\344\145\021\012\102\025\311\301\060\342\151\325\105\175\245\046
-\273\271\141\354\142\144\360\071\341\347\274\150\330\120\121\236
-\035\140\323\321\243\247\012\370\003\040\241\160\001\027\221\066
-\117\002\160\061\206\203\335\367\017\330\007\035\021\263\023\004
-\245\334\360\256\120\261\050\016\143\151\052\014\202\157\217\107
-\063\337\154\242\006\222\361\117\105\276\331\060\066\243\053\214
-\326\167\256\065\143\177\116\114\232\223\110\066\331\237\002\003
-\001\000\001\243\201\275\060\201\272\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\004\360\060\035\006\003\125\035\016
-\004\026\004\024\315\246\203\372\245\140\067\367\226\067\027\051
-\336\101\170\361\207\211\125\347\060\073\006\003\125\035\037\004
-\064\060\062\060\060\240\056\240\054\206\052\150\164\164\160\072
-\057\057\143\162\154\056\147\145\157\164\162\165\163\164\056\143
-\157\155\057\143\162\154\163\057\147\154\157\142\141\154\143\141
-\061\056\143\162\154\060\037\006\003\125\035\043\004\030\060\026
-\200\024\276\250\240\164\162\120\153\104\267\311\043\330\373\250
-\377\263\127\153\150\154\060\035\006\003\125\035\045\004\026\060
-\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001
-\005\005\007\003\002\060\014\006\003\125\035\023\001\001\377\004
-\002\060\000\060\015\006\011\052\206\110\206\367\015\001\001\004
-\005\000\003\201\201\000\247\041\002\215\321\016\242\200\167\045
-\375\103\140\025\217\354\357\220\107\324\204\102\025\046\021\034
-\315\302\074\020\051\251\266\337\253\127\165\221\332\345\053\263
-\220\105\034\060\143\126\077\212\331\120\372\355\130\154\300\145
-\254\146\127\336\034\306\166\073\365\000\016\216\105\316\177\114
-\220\354\053\306\315\263\264\217\142\320\376\267\305\046\162\104
-\355\366\230\133\256\313\321\225\365\332\010\276\150\106\261\165
-\310\354\035\217\036\172\224\361\252\123\170\242\105\256\124\352
-\321\236\164\310\166\147
-END
-
-# Trust for Certificate "MD5 Collisions Forged Rogue CA 25c3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "MD5 Collisions Forged Rogue CA 25c3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\144\043\023\176\134\123\326\112\246\144\205\355\066\124\365\253
-\005\132\213\212
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\026\172\023\025\271\027\071\243\361\005\152\346\076\331\072\070
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\034\060\032\006\003\125\004\012\023\023\105\161\165\151\146\141
-\170\040\123\145\143\165\162\145\040\111\156\143\056\061\055\060
-\053\006\003\125\004\003\023\044\105\161\165\151\146\141\170\040
-\123\145\143\165\162\145\040\107\154\157\142\141\154\040\145\102
-\165\163\151\156\145\163\163\040\103\101\055\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\102
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "IGC/A"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "IGC/A"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\106\122
-\061\017\060\015\006\003\125\004\010\023\006\106\162\141\156\143
-\145\061\016\060\014\006\003\125\004\007\023\005\120\141\162\151
-\163\061\020\060\016\006\003\125\004\012\023\007\120\115\057\123
-\107\104\116\061\016\060\014\006\003\125\004\013\023\005\104\103
-\123\123\111\061\016\060\014\006\003\125\004\003\023\005\111\107
-\103\057\101\061\043\060\041\006\011\052\206\110\206\367\015\001
-\011\001\026\024\151\147\143\141\100\163\147\144\156\056\160\155
-\056\147\157\165\166\056\146\162
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\106\122
-\061\017\060\015\006\003\125\004\010\023\006\106\162\141\156\143
-\145\061\016\060\014\006\003\125\004\007\023\005\120\141\162\151
-\163\061\020\060\016\006\003\125\004\012\023\007\120\115\057\123
-\107\104\116\061\016\060\014\006\003\125\004\013\023\005\104\103
-\123\123\111\061\016\060\014\006\003\125\004\003\023\005\111\107
-\103\057\101\061\043\060\041\006\011\052\206\110\206\367\015\001
-\011\001\026\024\151\147\143\141\100\163\147\144\156\056\160\155
-\056\147\157\165\166\056\146\162
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\005\071\021\105\020\224
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\002\060\202\002\352\240\003\002\001\002\002\005\071
-\021\105\020\224\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\060\201\205\061\013\060\011\006\003\125\004\006\023
-\002\106\122\061\017\060\015\006\003\125\004\010\023\006\106\162
-\141\156\143\145\061\016\060\014\006\003\125\004\007\023\005\120
-\141\162\151\163\061\020\060\016\006\003\125\004\012\023\007\120
-\115\057\123\107\104\116\061\016\060\014\006\003\125\004\013\023
-\005\104\103\123\123\111\061\016\060\014\006\003\125\004\003\023
-\005\111\107\103\057\101\061\043\060\041\006\011\052\206\110\206
-\367\015\001\011\001\026\024\151\147\143\141\100\163\147\144\156
-\056\160\155\056\147\157\165\166\056\146\162\060\036\027\015\060
-\062\061\062\061\063\061\064\062\071\062\063\132\027\015\062\060
-\061\060\061\067\061\064\062\071\062\062\132\060\201\205\061\013
-\060\011\006\003\125\004\006\023\002\106\122\061\017\060\015\006
-\003\125\004\010\023\006\106\162\141\156\143\145\061\016\060\014
-\006\003\125\004\007\023\005\120\141\162\151\163\061\020\060\016
-\006\003\125\004\012\023\007\120\115\057\123\107\104\116\061\016
-\060\014\006\003\125\004\013\023\005\104\103\123\123\111\061\016
-\060\014\006\003\125\004\003\023\005\111\107\103\057\101\061\043
-\060\041\006\011\052\206\110\206\367\015\001\011\001\026\024\151
-\147\143\141\100\163\147\144\156\056\160\155\056\147\157\165\166
-\056\146\162\060\202\001\042\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002
-\202\001\001\000\262\037\321\320\142\305\063\073\300\004\206\210
-\263\334\370\210\367\375\337\103\337\172\215\232\111\134\366\116
-\252\314\034\271\241\353\047\211\362\106\351\073\112\161\325\035
-\216\055\317\346\255\253\143\120\307\124\013\156\022\311\220\066
-\306\330\057\332\221\252\150\305\162\376\027\012\262\027\176\171
-\265\062\210\160\312\160\300\226\112\216\344\125\315\035\047\224
-\277\316\162\052\354\134\371\163\040\376\275\367\056\211\147\270
-\273\107\163\022\367\321\065\151\072\362\012\271\256\377\106\102
-\106\242\277\241\205\032\371\277\344\377\111\205\367\243\160\206
-\062\034\135\237\140\367\251\255\245\377\317\321\064\371\175\133
-\027\306\334\326\016\050\153\302\335\361\365\063\150\235\116\374
-\207\174\066\022\326\243\200\350\103\015\125\141\224\352\144\067
-\107\352\167\312\320\262\130\005\303\135\176\261\250\106\220\061
-\126\316\160\052\226\262\060\270\167\346\171\300\275\051\073\375
-\224\167\114\275\040\315\101\045\340\056\307\033\273\356\244\004
-\101\322\135\255\022\152\212\233\107\373\311\335\106\100\341\235
-\074\063\320\265\002\003\001\000\001\243\167\060\165\060\017\006
-\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\013
-\006\003\125\035\017\004\004\003\002\001\106\060\025\006\003\125
-\035\040\004\016\060\014\060\012\006\010\052\201\172\001\171\001
-\001\001\060\035\006\003\125\035\016\004\026\004\024\243\005\057
-\030\140\120\302\211\012\335\053\041\117\377\216\116\250\060\061
-\066\060\037\006\003\125\035\043\004\030\060\026\200\024\243\005
-\057\030\140\120\302\211\012\335\053\041\117\377\216\116\250\060
-\061\066\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\003\202\001\001\000\005\334\046\330\372\167\025\104\150\374
-\057\146\072\164\340\135\344\051\377\006\007\023\204\112\253\317
-\155\240\037\121\224\370\111\313\164\066\024\274\025\335\333\211
-\057\335\217\240\135\174\365\022\353\237\236\070\244\107\314\263
-\226\331\276\234\045\253\003\176\063\017\225\201\015\375\026\340
-\210\276\067\360\154\135\320\061\233\062\053\135\027\145\223\230
-\140\274\156\217\261\250\074\036\331\034\363\251\046\102\371\144
-\035\302\347\222\366\364\036\132\252\031\122\135\257\350\242\367
-\140\240\366\215\360\211\365\156\340\012\005\001\225\311\213\040
-\012\272\132\374\232\054\074\275\303\267\311\135\170\045\005\077
-\126\024\233\014\332\373\072\110\376\227\151\136\312\020\206\367
-\116\226\004\010\115\354\260\276\135\334\073\216\117\301\375\232
-\066\064\232\114\124\176\027\003\110\225\010\021\034\007\157\205
-\010\176\135\115\304\235\333\373\256\316\262\321\263\270\203\154
-\035\262\263\171\361\330\160\231\176\360\023\002\316\136\335\121
-\323\337\066\201\241\033\170\057\161\263\361\131\114\106\030\050
-\253\205\322\140\126\132
-END
-
-# Trust for Certificate "IGC/A"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "IGC/A"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\140\326\211\164\265\302\145\236\212\017\301\210\174\210\322\106
-\151\033\030\054
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\014\177\335\152\364\052\271\310\233\275\040\176\251\333\134\067
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\106\122
-\061\017\060\015\006\003\125\004\010\023\006\106\162\141\156\143
-\145\061\016\060\014\006\003\125\004\007\023\005\120\141\162\151
-\163\061\020\060\016\006\003\125\004\012\023\007\120\115\057\123
-\107\104\116\061\016\060\014\006\003\125\004\013\023\005\104\103
-\123\123\111\061\016\060\014\006\003\125\004\003\023\005\111\107
-\103\057\101\061\043\060\041\006\011\052\206\110\206\367\015\001
-\011\001\026\024\151\147\143\141\100\163\147\144\156\056\160\155
-\056\147\157\165\166\056\146\162
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\005\071\021\105\020\224
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Security Communication EV RootCA1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Security Communication EV RootCA1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\140\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040
-\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117
-\056\054\114\124\104\056\061\052\060\050\006\003\125\004\013\023
-\041\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156
-\151\143\141\164\151\157\156\040\105\126\040\122\157\157\164\103
-\101\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\140\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040
-\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117
-\056\054\114\124\104\056\061\052\060\050\006\003\125\004\013\023
-\041\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156
-\151\143\141\164\151\157\156\040\105\126\040\122\157\157\164\103
-\101\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\175\060\202\002\145\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\140\061\013\060\011\006\003\125\004\006\023\002\112\120\061\045
-\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040\124
-\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117\056
-\054\114\124\104\056\061\052\060\050\006\003\125\004\013\023\041
-\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156\151
-\143\141\164\151\157\156\040\105\126\040\122\157\157\164\103\101
-\061\060\036\027\015\060\067\060\066\060\066\060\062\061\062\063
-\062\132\027\015\063\067\060\066\060\066\060\062\061\062\063\062
-\132\060\140\061\013\060\011\006\003\125\004\006\023\002\112\120
-\061\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115
-\040\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103
-\117\056\054\114\124\104\056\061\052\060\050\006\003\125\004\013
-\023\041\123\145\143\165\162\151\164\171\040\103\157\155\155\165
-\156\151\143\141\164\151\157\156\040\105\126\040\122\157\157\164
-\103\101\061\060\202\001\042\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002
-\202\001\001\000\274\177\354\127\233\044\340\376\234\272\102\171
-\251\210\212\372\200\340\365\007\051\103\352\216\012\064\066\215
-\034\372\247\265\071\170\377\227\165\367\057\344\252\153\004\204
-\104\312\246\342\150\216\375\125\120\142\017\244\161\016\316\007
-\070\055\102\205\120\255\074\226\157\213\325\242\016\317\336\111
-\211\075\326\144\056\070\345\036\154\265\127\212\236\357\110\016
-\315\172\151\026\207\104\265\220\344\006\235\256\241\004\227\130
-\171\357\040\112\202\153\214\042\277\354\037\017\351\204\161\355
-\361\016\344\270\030\023\314\126\066\135\321\232\036\121\153\071
-\156\140\166\210\064\013\363\263\321\260\235\312\141\342\144\035
-\301\106\007\270\143\335\036\063\145\263\216\011\125\122\075\265
-\275\377\007\353\255\141\125\030\054\251\151\230\112\252\100\305
-\063\024\145\164\000\371\221\336\257\003\110\305\100\124\334\017
-\204\220\150\040\305\222\226\334\056\345\002\105\252\300\137\124
-\370\155\352\111\317\135\154\113\257\357\232\302\126\134\306\065
-\126\102\152\060\137\302\253\366\342\075\077\263\311\021\217\061
-\114\327\237\111\002\003\001\000\001\243\102\060\100\060\035\006
-\003\125\035\016\004\026\004\024\065\112\365\115\257\077\327\202
-\070\254\253\161\145\027\165\214\235\125\223\346\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\001\006\060\017\006\003
-\125\035\023\001\001\377\004\005\060\003\001\001\377\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001
-\000\250\207\351\354\370\100\147\135\303\301\146\307\100\113\227
-\374\207\023\220\132\304\357\240\312\137\213\267\247\267\361\326
-\265\144\267\212\263\270\033\314\332\373\254\146\210\101\316\350
-\374\344\333\036\210\246\355\047\120\033\002\060\044\106\171\376
-\004\207\160\227\100\163\321\300\301\127\031\232\151\245\047\231
-\253\235\142\204\366\121\301\054\311\043\025\330\050\267\253\045
-\023\265\106\341\206\002\377\046\214\304\210\222\035\126\376\031
-\147\362\125\344\200\243\153\234\253\167\341\121\161\015\040\333
-\020\232\333\275\166\171\007\167\231\050\255\232\136\332\261\117
-\104\054\065\216\245\226\307\375\203\360\130\306\171\326\230\174
-\250\215\376\206\076\007\026\222\341\173\347\035\354\063\166\176
-\102\056\112\205\371\221\211\150\204\003\201\245\233\232\276\343
-\067\305\124\253\126\073\030\055\101\244\014\370\102\333\231\240
-\340\162\157\273\135\341\026\117\123\012\144\371\116\364\277\116
-\124\275\170\154\210\352\277\234\023\044\302\160\151\242\177\017
-\310\074\255\010\311\260\230\100\243\052\347\210\203\355\167\217
-\164
-END
-
-# Trust for Certificate "Security Communication EV RootCA1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Security Communication EV RootCA1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\376\270\304\062\334\371\166\232\316\256\075\330\220\217\375\050
-\206\145\144\175
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\042\055\246\001\352\174\012\367\360\154\126\103\077\167\166\323
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\140\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040
-\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117
-\056\054\114\124\104\056\061\052\060\050\006\003\125\004\013\023
-\041\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156
-\151\143\141\164\151\157\156\040\105\126\040\122\157\157\164\103
-\101\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "OISTE WISeKey Global Root GA CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "OISTE WISeKey Global Root GA CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\212\061\013\060\011\006\003\125\004\006\023\002\103\110
-\061\020\060\016\006\003\125\004\012\023\007\127\111\123\145\113
-\145\171\061\033\060\031\006\003\125\004\013\023\022\103\157\160
-\171\162\151\147\150\164\040\050\143\051\040\062\060\060\065\061
-\042\060\040\006\003\125\004\013\023\031\117\111\123\124\105\040
-\106\157\165\156\144\141\164\151\157\156\040\105\156\144\157\162
-\163\145\144\061\050\060\046\006\003\125\004\003\023\037\117\111
-\123\124\105\040\127\111\123\145\113\145\171\040\107\154\157\142
-\141\154\040\122\157\157\164\040\107\101\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\212\061\013\060\011\006\003\125\004\006\023\002\103\110
-\061\020\060\016\006\003\125\004\012\023\007\127\111\123\145\113
-\145\171\061\033\060\031\006\003\125\004\013\023\022\103\157\160
-\171\162\151\147\150\164\040\050\143\051\040\062\060\060\065\061
-\042\060\040\006\003\125\004\013\023\031\117\111\123\124\105\040
-\106\157\165\156\144\141\164\151\157\156\040\105\156\144\157\162
-\163\145\144\061\050\060\046\006\003\125\004\003\023\037\117\111
-\123\124\105\040\127\111\123\145\113\145\171\040\107\154\157\142
-\141\154\040\122\157\157\164\040\107\101\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\101\075\162\307\364\153\037\201\103\175\361\322\050\124
-\337\232
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\361\060\202\002\331\240\003\002\001\002\002\020\101
-\075\162\307\364\153\037\201\103\175\361\322\050\124\337\232\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\212\061\013\060\011\006\003\125\004\006\023\002\103\110\061\020
-\060\016\006\003\125\004\012\023\007\127\111\123\145\113\145\171
-\061\033\060\031\006\003\125\004\013\023\022\103\157\160\171\162
-\151\147\150\164\040\050\143\051\040\062\060\060\065\061\042\060
-\040\006\003\125\004\013\023\031\117\111\123\124\105\040\106\157
-\165\156\144\141\164\151\157\156\040\105\156\144\157\162\163\145
-\144\061\050\060\046\006\003\125\004\003\023\037\117\111\123\124
-\105\040\127\111\123\145\113\145\171\040\107\154\157\142\141\154
-\040\122\157\157\164\040\107\101\040\103\101\060\036\027\015\060
-\065\061\062\061\061\061\066\060\063\064\064\132\027\015\063\067
-\061\062\061\061\061\066\060\071\065\061\132\060\201\212\061\013
-\060\011\006\003\125\004\006\023\002\103\110\061\020\060\016\006
-\003\125\004\012\023\007\127\111\123\145\113\145\171\061\033\060
-\031\006\003\125\004\013\023\022\103\157\160\171\162\151\147\150
-\164\040\050\143\051\040\062\060\060\065\061\042\060\040\006\003
-\125\004\013\023\031\117\111\123\124\105\040\106\157\165\156\144
-\141\164\151\157\156\040\105\156\144\157\162\163\145\144\061\050
-\060\046\006\003\125\004\003\023\037\117\111\123\124\105\040\127
-\111\123\145\113\145\171\040\107\154\157\142\141\154\040\122\157
-\157\164\040\107\101\040\103\101\060\202\001\042\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000
-\060\202\001\012\002\202\001\001\000\313\117\263\000\233\075\066
-\335\371\321\111\152\153\020\111\037\354\330\053\262\306\370\062
-\201\051\103\225\114\232\031\043\041\025\105\336\343\310\034\121
-\125\133\256\223\350\067\377\053\153\351\324\352\276\052\335\250
-\121\053\327\146\303\141\134\140\002\310\365\316\162\173\073\270
-\362\116\145\010\232\315\244\152\031\301\001\273\163\246\327\366
-\303\335\315\274\244\213\265\231\141\270\001\242\243\324\115\324
-\005\075\221\255\370\264\010\161\144\257\160\361\034\153\176\366
-\303\167\235\044\163\173\344\014\214\341\331\066\341\231\213\005
-\231\013\355\105\061\011\312\302\000\333\367\162\240\226\252\225
-\207\320\216\307\266\141\163\015\166\146\214\334\033\264\143\242
-\237\177\223\023\060\361\241\047\333\331\377\054\125\210\221\240
-\340\117\007\260\050\126\214\030\033\227\104\216\211\335\340\027
-\156\347\052\357\217\071\012\061\204\202\330\100\024\111\056\172
-\101\344\247\376\343\144\314\301\131\161\113\054\041\247\133\175
-\340\035\321\056\201\233\303\330\150\367\275\226\033\254\160\261
-\026\024\013\333\140\271\046\001\005\002\003\001\000\001\243\121
-\060\117\060\013\006\003\125\035\017\004\004\003\002\001\206\060
-\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377
-\060\035\006\003\125\035\016\004\026\004\024\263\003\176\256\066
-\274\260\171\321\334\224\046\266\021\276\041\262\151\206\224\060
-\020\006\011\053\006\001\004\001\202\067\025\001\004\003\002\001
-\000\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\202\001\001\000\113\241\377\013\207\156\263\371\301\103\261
-\110\363\050\300\035\056\311\011\101\372\224\000\034\244\244\253
-\111\117\217\075\036\357\115\157\275\274\244\366\362\046\060\311
-\020\312\035\210\373\164\031\037\205\105\275\260\154\121\371\066
-\176\333\365\114\062\072\101\117\133\107\317\350\013\055\266\304
-\031\235\164\305\107\306\073\152\017\254\024\333\074\364\163\234
-\251\005\337\000\334\164\170\372\370\065\140\131\002\023\030\174
-\274\373\115\260\040\155\103\273\140\060\172\147\063\134\305\231
-\321\370\055\071\122\163\373\214\252\227\045\134\162\331\010\036
-\253\116\074\343\201\061\237\003\246\373\300\376\051\210\125\332
-\204\325\120\003\266\342\204\243\246\066\252\021\072\001\341\030
-\113\326\104\150\263\075\371\123\164\204\263\106\221\106\226\000
-\267\200\054\266\341\343\020\342\333\242\347\050\217\001\226\142
-\026\076\000\343\034\245\066\201\030\242\114\122\166\300\021\243
-\156\346\035\272\343\132\276\066\123\305\076\165\217\206\151\051
-\130\123\265\234\273\157\237\134\305\030\354\335\057\341\230\311
-\374\276\337\012\015
-END
-
-# Trust for Certificate "OISTE WISeKey Global Root GA CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "OISTE WISeKey Global Root GA CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\131\042\241\341\132\352\026\065\041\370\230\071\152\106\106\260
-\104\033\017\251
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\274\154\121\063\247\351\323\146\143\124\025\162\033\041\222\223
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\212\061\013\060\011\006\003\125\004\006\023\002\103\110
-\061\020\060\016\006\003\125\004\012\023\007\127\111\123\145\113
-\145\171\061\033\060\031\006\003\125\004\013\023\022\103\157\160
-\171\162\151\147\150\164\040\050\143\051\040\062\060\060\065\061
-\042\060\040\006\003\125\004\013\023\031\117\111\123\124\105\040
-\106\157\165\156\144\141\164\151\157\156\040\105\156\144\157\162
-\163\145\144\061\050\060\046\006\003\125\004\003\023\037\117\111
-\123\124\105\040\127\111\123\145\113\145\171\040\107\154\157\142
-\141\154\040\122\157\157\164\040\107\101\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\101\075\162\307\364\153\037\201\103\175\361\322\050\124
-\337\232
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "S-TRUST Authentication and Encryption Root CA 2005 PN"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "S-TRUST Authentication and Encryption Root CA 2005 PN"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\040\060\036\006\003\125\004\010\023\027\102\141\144\145\156
-\055\127\165\145\162\164\164\145\155\142\145\162\147\040\050\102
-\127\051\061\022\060\020\006\003\125\004\007\023\011\123\164\165
-\164\164\147\141\162\164\061\051\060\047\006\003\125\004\012\023
-\040\104\145\165\164\163\143\150\145\162\040\123\160\141\162\153
-\141\163\163\145\156\040\126\145\162\154\141\147\040\107\155\142
-\110\061\076\060\074\006\003\125\004\003\023\065\123\055\124\122
-\125\123\124\040\101\165\164\150\145\156\164\151\143\141\164\151
-\157\156\040\141\156\144\040\105\156\143\162\171\160\164\151\157
-\156\040\122\157\157\164\040\103\101\040\062\060\060\065\072\120
-\116
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\040\060\036\006\003\125\004\010\023\027\102\141\144\145\156
-\055\127\165\145\162\164\164\145\155\142\145\162\147\040\050\102
-\127\051\061\022\060\020\006\003\125\004\007\023\011\123\164\165
-\164\164\147\141\162\164\061\051\060\047\006\003\125\004\012\023
-\040\104\145\165\164\163\143\150\145\162\040\123\160\141\162\153
-\141\163\163\145\156\040\126\145\162\154\141\147\040\107\155\142
-\110\061\076\060\074\006\003\125\004\003\023\065\123\055\124\122
-\125\123\124\040\101\165\164\150\145\156\164\151\143\141\164\151
-\157\156\040\141\156\144\040\105\156\143\162\171\160\164\151\157
-\156\040\122\157\157\164\040\103\101\040\062\060\060\065\072\120
-\116
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\067\031\030\346\123\124\174\032\265\270\313\131\132\333
-\065\267
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\173\060\202\003\143\240\003\002\001\002\002\020\067
-\031\030\346\123\124\174\032\265\270\313\131\132\333\065\267\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\256\061\013\060\011\006\003\125\004\006\023\002\104\105\061\040
-\060\036\006\003\125\004\010\023\027\102\141\144\145\156\055\127
-\165\145\162\164\164\145\155\142\145\162\147\040\050\102\127\051
-\061\022\060\020\006\003\125\004\007\023\011\123\164\165\164\164
-\147\141\162\164\061\051\060\047\006\003\125\004\012\023\040\104
-\145\165\164\163\143\150\145\162\040\123\160\141\162\153\141\163
-\163\145\156\040\126\145\162\154\141\147\040\107\155\142\110\061
-\076\060\074\006\003\125\004\003\023\065\123\055\124\122\125\123
-\124\040\101\165\164\150\145\156\164\151\143\141\164\151\157\156
-\040\141\156\144\040\105\156\143\162\171\160\164\151\157\156\040
-\122\157\157\164\040\103\101\040\062\060\060\065\072\120\116\060
-\036\027\015\060\065\060\066\062\062\060\060\060\060\060\060\132
-\027\015\063\060\060\066\062\061\062\063\065\071\065\071\132\060
-\201\256\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\040\060\036\006\003\125\004\010\023\027\102\141\144\145\156\055
-\127\165\145\162\164\164\145\155\142\145\162\147\040\050\102\127
-\051\061\022\060\020\006\003\125\004\007\023\011\123\164\165\164
-\164\147\141\162\164\061\051\060\047\006\003\125\004\012\023\040
-\104\145\165\164\163\143\150\145\162\040\123\160\141\162\153\141
-\163\163\145\156\040\126\145\162\154\141\147\040\107\155\142\110
-\061\076\060\074\006\003\125\004\003\023\065\123\055\124\122\125
-\123\124\040\101\165\164\150\145\156\164\151\143\141\164\151\157
-\156\040\141\156\144\040\105\156\143\162\171\160\164\151\157\156
-\040\122\157\157\164\040\103\101\040\062\060\060\065\072\120\116
-\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001
-\000\331\265\112\301\323\063\352\323\106\263\321\342\114\322\365
-\266\203\320\157\325\030\351\223\257\047\216\023\315\265\045\066
-\120\064\022\144\051\241\125\341\072\140\223\236\050\311\343\363
-\233\341\004\260\043\277\225\212\216\133\033\101\177\132\303\350
-\115\114\325\044\026\076\207\110\324\047\256\346\367\123\035\273
-\014\000\357\076\141\161\255\277\072\172\130\037\224\075\134\201
-\325\325\157\337\270\233\322\365\345\313\203\162\222\302\123\262
-\202\002\353\255\255\137\026\055\222\123\166\361\211\266\054\365
-\301\057\340\247\112\157\240\060\152\062\353\232\164\003\150\170
-\023\235\312\057\233\013\035\276\317\165\015\046\227\233\307\365
-\136\012\237\170\337\263\274\354\232\272\357\125\217\033\232\246
-\007\143\051\027\131\142\011\052\171\007\167\245\340\321\027\151
-\351\133\335\366\220\253\342\230\012\000\321\045\155\236\327\205
-\207\057\222\361\321\166\203\117\013\072\131\067\050\057\063\247
-\027\120\326\040\013\012\364\046\371\237\070\347\055\244\270\233
-\211\215\255\255\311\152\175\211\027\273\366\177\200\203\172\346
-\355\002\003\001\000\001\243\201\222\060\201\217\060\022\006\003
-\125\035\023\001\001\377\004\010\060\006\001\001\377\002\001\000
-\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006
-\060\051\006\003\125\035\021\004\042\060\040\244\036\060\034\061
-\032\060\030\006\003\125\004\003\023\021\123\124\122\157\156\154
-\151\156\145\061\055\062\060\064\070\055\065\060\035\006\003\125
-\035\016\004\026\004\024\017\312\036\134\171\340\242\363\051\266
-\322\205\263\013\112\265\145\354\153\122\060\037\006\003\125\035
-\043\004\030\060\026\200\024\017\312\036\134\171\340\242\363\051
-\266\322\205\263\013\112\265\145\354\153\122\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000\257
-\001\360\355\031\074\050\350\115\134\273\245\143\034\210\063\003
-\247\000\207\244\037\040\253\326\034\343\006\037\227\176\124\275
-\267\321\262\311\325\332\200\354\027\327\212\365\173\302\000\366
-\351\021\157\204\240\132\045\061\342\211\371\244\000\077\061\150
-\056\325\075\350\156\346\325\035\074\077\262\275\237\167\353\235
-\323\214\272\300\327\266\115\354\123\234\017\004\156\352\065\147
-\127\343\012\145\173\220\072\341\117\076\303\000\222\172\273\005
-\211\163\214\313\246\115\300\373\366\002\326\260\007\243\003\302
-\047\100\237\014\344\205\202\055\257\232\102\035\320\307\215\370
-\100\356\235\006\127\034\331\242\330\200\024\376\341\143\055\062
-\207\325\224\122\226\072\106\306\161\226\075\367\230\016\262\221
-\252\217\332\364\116\044\000\071\125\350\255\027\271\323\064\053
-\112\251\100\314\027\052\125\145\101\164\102\176\365\300\257\310
-\223\255\362\030\133\075\211\014\333\107\071\044\370\340\114\362
-\037\260\075\012\312\005\116\211\041\032\343\052\231\254\374\177
-\241\361\017\033\037\075\236\004\203\335\226\331\035\072\224
-END
-
-# Trust for Certificate "S-TRUST Authentication and Encryption Root CA 2005 PN"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "S-TRUST Authentication and Encryption Root CA 2005 PN"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\276\265\251\225\164\153\236\337\163\213\126\346\337\103\172\167
-\276\020\153\201
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\004\113\375\311\154\332\052\062\205\174\131\204\141\106\212\144
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\040\060\036\006\003\125\004\010\023\027\102\141\144\145\156
-\055\127\165\145\162\164\164\145\155\142\145\162\147\040\050\102
-\127\051\061\022\060\020\006\003\125\004\007\023\011\123\164\165
-\164\164\147\141\162\164\061\051\060\047\006\003\125\004\012\023
-\040\104\145\165\164\163\143\150\145\162\040\123\160\141\162\153
-\141\163\163\145\156\040\126\145\162\154\141\147\040\107\155\142
-\110\061\076\060\074\006\003\125\004\003\023\065\123\055\124\122
-\125\123\124\040\101\165\164\150\145\156\164\151\143\141\164\151
-\157\156\040\141\156\144\040\105\156\143\162\171\160\164\151\157
-\156\040\122\157\157\164\040\103\101\040\062\060\060\065\072\120
-\116
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\067\031\030\346\123\124\174\032\265\270\313\131\132\333
-\065\267
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Microsec e-Szigno Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Microsec e-Szigno Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061
-\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145
-\163\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143
-\162\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003
-\125\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101
-\061\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157
-\163\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157
-\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061
-\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145
-\163\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143
-\162\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003
-\125\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101
-\061\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157
-\163\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157
-\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\314\270\347\277\116\051\032\375\242\334\146\245\034
-\054\017\021
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\007\250\060\202\006\220\240\003\002\001\002\002\021\000
-\314\270\347\277\116\051\032\375\242\334\146\245\034\054\017\021
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061\021
-\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145\163
-\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143\162
-\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003\125
-\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101\061
-\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157\163
-\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157\164
-\040\103\101\060\036\027\015\060\065\060\064\060\066\061\062\062
-\070\064\064\132\027\015\061\067\060\064\060\066\061\062\062\070
-\064\064\132\060\162\061\013\060\011\006\003\125\004\006\023\002
-\110\125\061\021\060\017\006\003\125\004\007\023\010\102\165\144
-\141\160\145\163\164\061\026\060\024\006\003\125\004\012\023\015
-\115\151\143\162\157\163\145\143\040\114\164\144\056\061\024\060
-\022\006\003\125\004\013\023\013\145\055\123\172\151\147\156\157
-\040\103\101\061\042\060\040\006\003\125\004\003\023\031\115\151
-\143\162\157\163\145\143\040\145\055\123\172\151\147\156\157\040
-\122\157\157\164\040\103\101\060\202\001\042\060\015\006\011\052
-\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060
-\202\001\012\002\202\001\001\000\355\310\000\325\201\173\315\070
-\000\107\314\333\204\301\041\151\054\164\220\014\041\331\123\207
-\355\076\103\104\123\257\253\370\200\233\074\170\215\324\215\256
-\270\357\323\021\334\201\346\317\073\226\214\326\157\025\306\167
-\176\241\057\340\137\222\266\047\327\166\232\035\103\074\352\331
-\354\057\356\071\363\152\147\113\213\202\317\042\370\145\125\376
-\054\313\057\175\110\172\075\165\371\252\240\047\273\170\302\006
-\312\121\302\176\146\113\257\315\242\247\115\002\202\077\202\254
-\205\306\341\017\220\107\231\224\012\161\162\223\052\311\246\300
-\276\074\126\114\163\222\047\361\153\265\365\375\374\060\005\140
-\222\306\353\226\176\001\221\302\151\261\036\035\173\123\105\270
-\334\101\037\311\213\161\326\124\024\343\213\124\170\077\276\364
-\142\073\133\365\243\354\325\222\164\342\164\060\357\001\333\341
-\324\253\231\233\052\153\370\275\246\034\206\043\102\137\354\111
-\336\232\213\133\364\162\072\100\305\111\076\245\276\216\252\161
-\353\154\372\365\032\344\152\375\173\175\125\100\357\130\156\346
-\331\325\274\044\253\301\357\267\002\003\001\000\001\243\202\004
-\067\060\202\004\063\060\147\006\010\053\006\001\005\005\007\001
-\001\004\133\060\131\060\050\006\010\053\006\001\005\005\007\060
-\001\206\034\150\164\164\160\163\072\057\057\162\143\141\056\145
-\055\163\172\151\147\156\157\056\150\165\057\157\143\163\160\060
-\055\006\010\053\006\001\005\005\007\060\002\206\041\150\164\164
-\160\072\057\057\167\167\167\056\145\055\163\172\151\147\156\157
-\056\150\165\057\122\157\157\164\103\101\056\143\162\164\060\017
-\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
-\202\001\163\006\003\125\035\040\004\202\001\152\060\202\001\146
-\060\202\001\142\006\014\053\006\001\004\001\201\250\030\002\001
-\001\001\060\202\001\120\060\050\006\010\053\006\001\005\005\007
-\002\001\026\034\150\164\164\160\072\057\057\167\167\167\056\145
-\055\163\172\151\147\156\157\056\150\165\057\123\132\123\132\057
-\060\202\001\042\006\010\053\006\001\005\005\007\002\002\060\202
-\001\024\036\202\001\020\000\101\000\040\000\164\000\141\000\156
-\000\372\000\163\000\355\000\164\000\166\000\341\000\156\000\171
-\000\040\000\351\000\162\000\164\000\145\000\154\000\155\000\145
-\000\172\000\351\000\163\000\351\000\150\000\145\000\172\000\040
-\000\351\000\163\000\040\000\145\000\154\000\146\000\157\000\147
-\000\141\000\144\000\341\000\163\000\341\000\150\000\157\000\172
-\000\040\000\141\000\040\000\123\000\172\000\157\000\154\000\147
-\000\341\000\154\000\164\000\141\000\164\000\363\000\040\000\123
-\000\172\000\157\000\154\000\147\000\341\000\154\000\164\000\141
-\000\164\000\341\000\163\000\151\000\040\000\123\000\172\000\141
-\000\142\000\341\000\154\000\171\000\172\000\141\000\164\000\141
-\000\040\000\163\000\172\000\145\000\162\000\151\000\156\000\164
-\000\040\000\153\000\145\000\154\000\154\000\040\000\145\000\154
-\000\152\000\341\000\162\000\156\000\151\000\072\000\040\000\150
-\000\164\000\164\000\160\000\072\000\057\000\057\000\167\000\167
-\000\167\000\056\000\145\000\055\000\163\000\172\000\151\000\147
-\000\156\000\157\000\056\000\150\000\165\000\057\000\123\000\132
-\000\123\000\132\000\057\060\201\310\006\003\125\035\037\004\201
-\300\060\201\275\060\201\272\240\201\267\240\201\264\206\041\150
-\164\164\160\072\057\057\167\167\167\056\145\055\163\172\151\147
-\156\157\056\150\165\057\122\157\157\164\103\101\056\143\162\154
-\206\201\216\154\144\141\160\072\057\057\154\144\141\160\056\145
-\055\163\172\151\147\156\157\056\150\165\057\103\116\075\115\151
-\143\162\157\163\145\143\045\062\060\145\055\123\172\151\147\156
-\157\045\062\060\122\157\157\164\045\062\060\103\101\054\117\125
-\075\145\055\123\172\151\147\156\157\045\062\060\103\101\054\117
-\075\115\151\143\162\157\163\145\143\045\062\060\114\164\144\056
-\054\114\075\102\165\144\141\160\145\163\164\054\103\075\110\125
-\077\143\145\162\164\151\146\151\143\141\164\145\122\145\166\157
-\143\141\164\151\157\156\114\151\163\164\073\142\151\156\141\162
-\171\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001
-\006\060\201\226\006\003\125\035\021\004\201\216\060\201\213\201
-\020\151\156\146\157\100\145\055\163\172\151\147\156\157\056\150
-\165\244\167\060\165\061\043\060\041\006\003\125\004\003\014\032
-\115\151\143\162\157\163\145\143\040\145\055\123\172\151\147\156
-\303\263\040\122\157\157\164\040\103\101\061\026\060\024\006\003
-\125\004\013\014\015\145\055\123\172\151\147\156\303\263\040\110
-\123\132\061\026\060\024\006\003\125\004\012\023\015\115\151\143
-\162\157\163\145\143\040\113\146\164\056\061\021\060\017\006\003
-\125\004\007\023\010\102\165\144\141\160\145\163\164\061\013\060
-\011\006\003\125\004\006\023\002\110\125\060\201\254\006\003\125
-\035\043\004\201\244\060\201\241\200\024\307\240\111\165\026\141
-\204\333\061\113\204\322\361\067\100\220\357\116\334\367\241\166
-\244\164\060\162\061\013\060\011\006\003\125\004\006\023\002\110
-\125\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141
-\160\145\163\164\061\026\060\024\006\003\125\004\012\023\015\115
-\151\143\162\157\163\145\143\040\114\164\144\056\061\024\060\022
-\006\003\125\004\013\023\013\145\055\123\172\151\147\156\157\040
-\103\101\061\042\060\040\006\003\125\004\003\023\031\115\151\143
-\162\157\163\145\143\040\145\055\123\172\151\147\156\157\040\122
-\157\157\164\040\103\101\202\021\000\314\270\347\277\116\051\032
-\375\242\334\146\245\034\054\017\021\060\035\006\003\125\035\016
-\004\026\004\024\307\240\111\165\026\141\204\333\061\113\204\322
-\361\067\100\220\357\116\334\367\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\202\001\001\000\323\023\234\146
-\143\131\056\312\134\160\014\374\203\274\125\261\364\216\007\154
-\146\047\316\301\073\040\251\034\273\106\124\160\356\132\314\240
-\167\352\150\104\047\353\362\051\335\167\251\325\373\343\324\247
-\004\304\225\270\013\341\104\150\140\007\103\060\061\102\141\345
-\356\331\345\044\325\033\337\341\112\033\252\237\307\137\370\172
-\021\352\023\223\000\312\212\130\261\356\355\016\115\264\327\250
-\066\046\174\340\072\301\325\127\202\361\165\266\375\211\137\332
-\363\250\070\237\065\006\010\316\042\225\276\315\325\374\276\133
-\336\171\153\334\172\251\145\146\276\261\045\132\137\355\176\323
-\254\106\155\114\364\062\207\264\040\004\340\154\170\260\167\321
-\205\106\113\246\022\267\165\350\112\311\126\154\327\222\253\235
-\365\111\070\322\117\123\343\125\220\021\333\230\226\306\111\362
-\076\364\237\033\340\367\210\334\045\142\231\104\330\163\277\077
-\060\363\014\067\076\324\302\050\200\163\261\001\267\235\132\226
-\024\001\113\251\021\235\051\152\056\320\135\201\300\317\262\040
-\103\307\003\340\067\116\135\012\334\131\040\045
-END
-
-# Trust for Certificate "Microsec e-Szigno Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Microsec e-Szigno Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\043\210\311\323\161\314\236\226\075\377\175\074\247\316\374\326
-\045\354\031\015
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\360\226\266\057\305\020\325\147\216\203\045\062\350\136\056\345
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061
-\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145
-\163\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143
-\162\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003
-\125\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101
-\061\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157
-\163\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157
-\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\314\270\347\277\116\051\032\375\242\334\146\245\034
-\054\017\021
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Certigna"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certigna"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\064\061\013\060\011\006\003\125\004\006\023\002\106\122\061
-\022\060\020\006\003\125\004\012\014\011\104\150\151\155\171\157
-\164\151\163\061\021\060\017\006\003\125\004\003\014\010\103\145
-\162\164\151\147\156\141
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\064\061\013\060\011\006\003\125\004\006\023\002\106\122\061
-\022\060\020\006\003\125\004\012\014\011\104\150\151\155\171\157
-\164\151\163\061\021\060\017\006\003\125\004\003\014\010\103\145
-\162\164\151\147\156\141
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\376\334\343\001\017\311\110\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\250\060\202\002\220\240\003\002\001\002\002\011\000
-\376\334\343\001\017\311\110\377\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\060\064\061\013\060\011\006\003\125
-\004\006\023\002\106\122\061\022\060\020\006\003\125\004\012\014
-\011\104\150\151\155\171\157\164\151\163\061\021\060\017\006\003
-\125\004\003\014\010\103\145\162\164\151\147\156\141\060\036\027
-\015\060\067\060\066\062\071\061\065\061\063\060\065\132\027\015
-\062\067\060\066\062\071\061\065\061\063\060\065\132\060\064\061
-\013\060\011\006\003\125\004\006\023\002\106\122\061\022\060\020
-\006\003\125\004\012\014\011\104\150\151\155\171\157\164\151\163
-\061\021\060\017\006\003\125\004\003\014\010\103\145\162\164\151
-\147\156\141\060\202\001\042\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002
-\202\001\001\000\310\150\361\311\326\326\263\064\165\046\202\036
-\354\264\276\352\134\341\046\355\021\107\141\341\242\174\026\170
-\100\041\344\140\236\132\310\143\341\304\261\226\222\377\030\155
-\151\043\341\053\142\367\335\342\066\057\221\007\271\110\317\016
-\354\171\266\054\347\064\113\160\010\045\243\074\207\033\031\362
-\201\007\017\070\220\031\323\021\376\206\264\362\321\136\036\036
-\226\315\200\154\316\073\061\223\266\362\240\320\251\225\022\175
-\245\232\314\153\310\204\126\212\063\251\347\042\025\123\026\360
-\314\027\354\127\137\351\242\012\230\011\336\343\137\234\157\334
-\110\343\205\013\025\132\246\272\237\254\110\343\011\262\367\364
-\062\336\136\064\276\034\170\135\102\133\316\016\042\217\115\220
-\327\175\062\030\263\013\054\152\277\216\077\024\021\211\040\016
-\167\024\265\075\224\010\207\367\045\036\325\262\140\000\354\157
-\052\050\045\156\052\076\030\143\027\045\077\076\104\040\026\366
-\046\310\045\256\005\112\264\347\143\054\363\214\026\123\176\134
-\373\021\032\010\301\106\142\237\042\270\361\302\215\151\334\372
-\072\130\006\337\002\003\001\000\001\243\201\274\060\201\271\060
-\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377
-\060\035\006\003\125\035\016\004\026\004\024\032\355\376\101\071
-\220\264\044\131\276\001\362\122\325\105\366\132\071\334\021\060
-\144\006\003\125\035\043\004\135\060\133\200\024\032\355\376\101
-\071\220\264\044\131\276\001\362\122\325\105\366\132\071\334\021
-\241\070\244\066\060\064\061\013\060\011\006\003\125\004\006\023
-\002\106\122\061\022\060\020\006\003\125\004\012\014\011\104\150
-\151\155\171\157\164\151\163\061\021\060\017\006\003\125\004\003
-\014\010\103\145\162\164\151\147\156\141\202\011\000\376\334\343
-\001\017\311\110\377\060\016\006\003\125\035\017\001\001\377\004
-\004\003\002\001\006\060\021\006\011\140\206\110\001\206\370\102
-\001\001\004\004\003\002\000\007\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\202\001\001\000\205\003\036\222
-\161\366\102\257\341\243\141\236\353\363\300\017\362\245\324\332
-\225\346\326\276\150\066\075\176\156\037\114\212\357\321\017\041
-\155\136\245\122\143\316\022\370\357\052\332\157\353\067\376\023
-\002\307\313\073\076\042\153\332\141\056\177\324\162\075\335\060
-\341\036\114\100\031\214\017\327\234\321\203\060\173\230\131\334
-\175\306\271\014\051\114\241\063\242\353\147\072\145\204\323\226
-\342\355\166\105\160\217\265\053\336\371\043\326\111\156\074\024
-\265\306\237\065\036\120\320\301\217\152\160\104\002\142\313\256
-\035\150\101\247\252\127\350\123\252\007\322\006\366\325\024\006
-\013\221\003\165\054\154\162\265\141\225\232\015\213\271\015\347
-\365\337\124\315\336\346\330\326\011\010\227\143\345\301\056\260
-\267\104\046\300\046\300\257\125\060\236\073\325\066\052\031\004
-\364\134\036\377\317\054\267\377\320\375\207\100\021\325\021\043
-\273\110\300\041\251\244\050\055\375\025\370\260\116\053\364\060
-\133\041\374\021\221\064\276\101\357\173\235\227\165\377\227\225
-\300\226\130\057\352\273\106\327\273\344\331\056
-END
-
-# Trust for Certificate "Certigna"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certigna"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\261\056\023\143\105\206\244\157\032\262\140\150\067\130\055\304
-\254\375\224\227
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\253\127\246\133\175\102\202\031\265\330\130\046\050\136\375\377
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\064\061\013\060\011\006\003\125\004\006\023\002\106\122\061
-\022\060\020\006\003\125\004\012\014\011\104\150\151\155\171\157
-\164\151\163\061\021\060\017\006\003\125\004\003\014\010\103\145
-\162\164\151\147\156\141
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\376\334\343\001\017\311\110\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "AC Raiz Certicamara S.A."
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AC Ra\xC3\xADz Certic\xC3\xA1mara S.A."
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\173\061\013\060\011\006\003\125\004\006\023\002\103\117\061
-\107\060\105\006\003\125\004\012\014\076\123\157\143\151\145\144
-\141\144\040\103\141\155\145\162\141\154\040\144\145\040\103\145
-\162\164\151\146\151\143\141\143\151\303\263\156\040\104\151\147
-\151\164\141\154\040\055\040\103\145\162\164\151\143\303\241\155
-\141\162\141\040\123\056\101\056\061\043\060\041\006\003\125\004
-\003\014\032\101\103\040\122\141\303\255\172\040\103\145\162\164
-\151\143\303\241\155\141\162\141\040\123\056\101\056
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\173\061\013\060\011\006\003\125\004\006\023\002\103\117\061
-\107\060\105\006\003\125\004\012\014\076\123\157\143\151\145\144
-\141\144\040\103\141\155\145\162\141\154\040\144\145\040\103\145
-\162\164\151\146\151\143\141\143\151\303\263\156\040\104\151\147
-\151\164\141\154\040\055\040\103\145\162\164\151\143\303\241\155
-\141\162\141\040\123\056\101\056\061\043\060\041\006\003\125\004
-\003\014\032\101\103\040\122\141\303\255\172\040\103\145\162\164
-\151\143\303\241\155\141\162\141\040\123\056\101\056
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\017\007\176\122\223\173\340\025\343\127\360\151\214\313\354
-\014
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\006\146\060\202\004\116\240\003\002\001\002\002\017\007
-\176\122\223\173\340\025\343\127\360\151\214\313\354\014\060\015
-\006\011\052\206\110\206\367\015\001\001\005\005\000\060\173\061
-\013\060\011\006\003\125\004\006\023\002\103\117\061\107\060\105
-\006\003\125\004\012\014\076\123\157\143\151\145\144\141\144\040
-\103\141\155\145\162\141\154\040\144\145\040\103\145\162\164\151
-\146\151\143\141\143\151\303\263\156\040\104\151\147\151\164\141
-\154\040\055\040\103\145\162\164\151\143\303\241\155\141\162\141
-\040\123\056\101\056\061\043\060\041\006\003\125\004\003\014\032
-\101\103\040\122\141\303\255\172\040\103\145\162\164\151\143\303
-\241\155\141\162\141\040\123\056\101\056\060\036\027\015\060\066
-\061\061\062\067\062\060\064\066\062\071\132\027\015\063\060\060
-\064\060\062\062\061\064\062\060\062\132\060\173\061\013\060\011
-\006\003\125\004\006\023\002\103\117\061\107\060\105\006\003\125
-\004\012\014\076\123\157\143\151\145\144\141\144\040\103\141\155
-\145\162\141\154\040\144\145\040\103\145\162\164\151\146\151\143
-\141\143\151\303\263\156\040\104\151\147\151\164\141\154\040\055
-\040\103\145\162\164\151\143\303\241\155\141\162\141\040\123\056
-\101\056\061\043\060\041\006\003\125\004\003\014\032\101\103\040
-\122\141\303\255\172\040\103\145\162\164\151\143\303\241\155\141
-\162\141\040\123\056\101\056\060\202\002\042\060\015\006\011\052
-\206\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060
-\202\002\012\002\202\002\001\000\253\153\211\243\123\314\110\043
-\010\373\303\317\121\226\010\056\270\010\172\155\074\220\027\206
-\251\351\355\056\023\064\107\262\320\160\334\311\074\320\215\312
-\356\113\027\253\320\205\260\247\043\004\313\250\242\374\345\165
-\333\100\312\142\211\217\120\236\001\075\046\133\030\204\034\313
-\174\067\267\175\354\323\177\163\031\260\152\262\330\210\212\055
-\105\164\250\367\263\270\300\324\332\315\042\211\164\115\132\025
-\071\163\030\164\117\265\353\231\247\301\036\210\264\302\223\220
-\143\227\363\247\247\022\262\011\042\007\063\331\221\315\016\234
-\037\016\040\307\356\273\063\215\217\302\322\130\247\137\375\145
-\067\342\210\302\330\217\206\165\136\371\055\247\207\063\362\170
-\067\057\213\274\035\206\067\071\261\224\362\330\274\112\234\203
-\030\132\006\374\363\324\324\272\214\025\011\045\360\371\266\215
-\004\176\027\022\063\153\127\110\114\117\333\046\036\353\314\220
-\347\213\371\150\174\160\017\243\052\320\072\070\337\067\227\342
-\133\336\200\141\323\200\330\221\203\102\132\114\004\211\150\021
-\074\254\137\150\200\101\314\140\102\316\015\132\052\014\017\233
-\060\300\246\360\206\333\253\111\327\227\155\110\213\371\003\300
-\122\147\233\022\367\302\362\056\230\145\102\331\326\232\343\320
-\031\061\014\255\207\325\127\002\172\060\350\206\046\373\217\043
-\212\124\207\344\277\074\356\353\303\165\110\137\036\071\157\201
-\142\154\305\055\304\027\124\031\267\067\215\234\067\221\310\366
-\013\325\352\143\157\203\254\070\302\363\077\336\232\373\341\043
-\141\360\310\046\313\066\310\241\363\060\217\244\243\242\241\335
-\123\263\336\360\232\062\037\203\221\171\060\301\251\037\123\233
-\123\242\025\123\077\335\235\263\020\073\110\175\211\017\374\355
-\003\365\373\045\144\165\016\027\031\015\217\000\026\147\171\172
-\100\374\055\131\007\331\220\372\232\255\075\334\200\212\346\134
-\065\242\147\114\021\153\261\370\200\144\000\055\157\042\141\305
-\254\113\046\345\132\020\202\233\244\203\173\064\367\236\211\221
-\040\227\216\267\102\307\146\303\320\351\244\326\365\040\215\304
-\303\225\254\104\012\235\133\163\074\046\075\057\112\276\247\311
-\247\020\036\373\237\120\151\363\002\003\001\000\001\243\201\346
-\060\201\343\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\006\060\035\006\003\125\035\016\004\026\004\024\321
-\011\320\351\327\316\171\164\124\371\072\060\263\364\155\054\003
-\003\033\150\060\201\240\006\003\125\035\040\004\201\230\060\201
-\225\060\201\222\006\004\125\035\040\000\060\201\211\060\053\006
-\010\053\006\001\005\005\007\002\001\026\037\150\164\164\160\072
-\057\057\167\167\167\056\143\145\162\164\151\143\141\155\141\162
-\141\056\143\157\155\057\144\160\143\057\060\132\006\010\053\006
-\001\005\005\007\002\002\060\116\032\114\114\151\155\151\164\141
-\143\151\157\156\145\163\040\144\145\040\147\141\162\141\156\164
-\355\141\163\040\144\145\040\145\163\164\145\040\143\145\162\164
-\151\146\151\143\141\144\157\040\163\145\040\160\165\145\144\145
-\156\040\145\156\143\157\156\164\162\141\162\040\145\156\040\154
-\141\040\104\120\103\056\060\015\006\011\052\206\110\206\367\015
-\001\001\005\005\000\003\202\002\001\000\134\224\265\270\105\221
-\115\216\141\037\003\050\017\123\174\346\244\131\251\263\212\172
-\305\260\377\010\174\054\243\161\034\041\023\147\241\225\022\100
-\065\203\203\217\164\333\063\134\360\111\166\012\201\122\335\111
-\324\232\062\063\357\233\247\313\165\345\172\313\227\022\220\134
-\272\173\305\233\337\273\071\043\310\377\230\316\012\115\042\001
-\110\007\176\212\300\325\040\102\224\104\357\277\167\242\211\147
-\110\033\100\003\005\241\211\354\317\142\343\075\045\166\146\277
-\046\267\273\042\276\157\377\071\127\164\272\172\311\001\225\301
-\225\121\350\253\054\370\261\206\040\351\077\313\065\133\322\027
-\351\052\376\203\023\027\100\356\210\142\145\133\325\073\140\351
-\173\074\270\311\325\177\066\002\045\252\150\302\061\025\267\060
-\145\353\177\035\110\171\261\317\071\342\102\200\026\323\365\223
-\043\374\114\227\311\132\067\154\174\042\330\112\315\322\216\066
-\203\071\221\220\020\310\361\311\065\176\077\270\323\201\306\040
-\144\032\266\120\302\041\244\170\334\320\057\073\144\223\164\360
-\226\220\361\357\373\011\132\064\100\226\360\066\022\301\243\164
-\214\223\176\101\336\167\213\354\206\331\322\017\077\055\321\314
-\100\242\211\146\110\036\040\263\234\043\131\163\251\104\163\274
-\044\171\220\126\067\263\306\051\176\243\017\361\051\071\357\176
-\134\050\062\160\065\254\332\270\310\165\146\374\233\114\071\107
-\216\033\157\233\115\002\124\042\063\357\141\272\236\051\204\357
-\116\113\063\107\166\227\152\313\176\137\375\025\246\236\102\103
-\133\146\132\212\210\015\367\026\271\077\121\145\053\146\152\213
-\321\070\122\242\326\106\021\372\374\232\034\164\236\217\227\013
-\002\117\144\306\365\150\323\113\055\377\244\067\036\213\077\277
-\104\276\141\106\241\204\075\010\047\114\201\040\167\211\010\352
-\147\100\136\154\010\121\137\064\132\214\226\150\315\327\367\211
-\302\034\323\062\000\257\122\313\323\140\133\052\072\107\176\153
-\060\063\241\142\051\177\112\271\341\055\347\024\043\016\016\030
-\107\341\171\374\025\125\320\261\374\045\161\143\165\063\034\043
-\053\257\134\331\355\107\167\140\016\073\017\036\322\300\334\144
-\005\211\374\170\326\134\054\046\103\251
-END
-
-# Trust for Certificate "AC Raiz Certicamara S.A."
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AC Ra\xC3\xADz Certic\xC3\xA1mara S.A."
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\313\241\305\370\260\343\136\270\271\105\022\323\371\064\242\351
-\006\020\323\066
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\223\052\076\366\375\043\151\015\161\040\324\053\107\231\053\246
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\173\061\013\060\011\006\003\125\004\006\023\002\103\117\061
-\107\060\105\006\003\125\004\012\014\076\123\157\143\151\145\144
-\141\144\040\103\141\155\145\162\141\154\040\144\145\040\103\145
-\162\164\151\146\151\143\141\143\151\303\263\156\040\104\151\147
-\151\164\141\154\040\055\040\103\145\162\164\151\143\303\241\155
-\141\162\141\040\123\056\101\056\061\043\060\041\006\003\125\004
-\003\014\032\101\103\040\122\141\303\255\172\040\103\145\162\164
-\151\143\303\241\155\141\162\141\040\123\056\101\056
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\017\007\176\122\223\173\340\025\343\127\360\151\214\313\354
-\014
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TC TrustCenter Class 2 CA II"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Class 2 CA II"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\166\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\042\060
-\040\006\003\125\004\013\023\031\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\062\040\103
-\101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\062\040\103\101\040\111\111
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\166\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\042\060
-\040\006\003\125\004\013\023\031\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\062\040\103
-\101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\062\040\103\101\040\111\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\056\152\000\001\000\002\037\327\122\041\054\021\134\073
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\252\060\202\003\222\240\003\002\001\002\002\016\056
-\152\000\001\000\002\037\327\122\041\054\021\134\073\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\060\166\061\013
-\060\011\006\003\125\004\006\023\002\104\105\061\034\060\032\006
-\003\125\004\012\023\023\124\103\040\124\162\165\163\164\103\145
-\156\164\145\162\040\107\155\142\110\061\042\060\040\006\003\125
-\004\013\023\031\124\103\040\124\162\165\163\164\103\145\156\164
-\145\162\040\103\154\141\163\163\040\062\040\103\101\061\045\060
-\043\006\003\125\004\003\023\034\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\062\040\103
-\101\040\111\111\060\036\027\015\060\066\060\061\061\062\061\064
-\063\070\064\063\132\027\015\062\065\061\062\063\061\062\062\065
-\071\065\071\132\060\166\061\013\060\011\006\003\125\004\006\023
-\002\104\105\061\034\060\032\006\003\125\004\012\023\023\124\103
-\040\124\162\165\163\164\103\145\156\164\145\162\040\107\155\142
-\110\061\042\060\040\006\003\125\004\013\023\031\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\062\040\103\101\061\045\060\043\006\003\125\004\003\023\034
-\124\103\040\124\162\165\163\164\103\145\156\164\145\162\040\103
-\154\141\163\163\040\062\040\103\101\040\111\111\060\202\001\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\001\017\000\060\202\001\012\002\202\001\001\000\253\200\207
-\233\216\360\303\174\207\327\350\044\202\021\263\074\335\103\142
-\356\370\303\105\332\350\341\240\137\321\052\262\352\223\150\337
-\264\310\326\103\351\304\165\131\177\374\341\035\370\061\160\043
-\033\210\236\047\271\173\375\072\322\311\251\351\024\057\220\276
-\003\122\301\111\315\366\375\344\010\146\013\127\212\242\102\240
-\270\325\177\151\134\220\062\262\227\015\312\112\334\106\076\002
-\125\211\123\343\032\132\313\066\306\007\126\367\214\317\021\364
-\114\273\060\160\004\225\245\366\071\214\375\163\201\010\175\211
-\136\062\036\042\251\042\105\113\260\146\056\060\314\237\145\375
-\374\313\201\251\361\340\073\257\243\206\321\211\352\304\105\171
-\120\135\256\351\041\164\222\115\213\131\202\217\224\343\351\112
-\361\347\111\260\024\343\365\142\313\325\162\275\037\271\322\237
-\240\315\250\372\001\310\331\015\337\332\374\107\235\263\310\124
-\337\111\112\361\041\251\376\030\116\356\110\324\031\273\357\175
-\344\342\235\313\133\266\156\377\343\315\132\347\164\202\005\272
-\200\045\070\313\344\151\236\257\101\252\032\204\365\002\003\001
-\000\001\243\202\001\064\060\202\001\060\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003\125
-\035\016\004\026\004\024\343\253\124\114\200\241\333\126\103\267
-\221\112\313\363\202\172\023\134\010\253\060\201\355\006\003\125
-\035\037\004\201\345\060\201\342\060\201\337\240\201\334\240\201
-\331\206\065\150\164\164\160\072\057\057\167\167\167\056\164\162
-\165\163\164\143\145\156\164\145\162\056\144\145\057\143\162\154
-\057\166\062\057\164\143\137\143\154\141\163\163\137\062\137\143
-\141\137\111\111\056\143\162\154\206\201\237\154\144\141\160\072
-\057\057\167\167\167\056\164\162\165\163\164\143\145\156\164\145
-\162\056\144\145\057\103\116\075\124\103\045\062\060\124\162\165
-\163\164\103\145\156\164\145\162\045\062\060\103\154\141\163\163
-\045\062\060\062\045\062\060\103\101\045\062\060\111\111\054\117
-\075\124\103\045\062\060\124\162\165\163\164\103\145\156\164\145
-\162\045\062\060\107\155\142\110\054\117\125\075\162\157\157\164
-\143\145\162\164\163\054\104\103\075\164\162\165\163\164\143\145
-\156\164\145\162\054\104\103\075\144\145\077\143\145\162\164\151
-\146\151\143\141\164\145\122\145\166\157\143\141\164\151\157\156
-\114\151\163\164\077\142\141\163\145\077\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\214\327
-\337\176\356\033\200\020\263\203\365\333\021\352\153\113\250\222
-\030\331\367\007\071\365\054\276\006\165\172\150\123\025\034\352
-\112\355\136\374\043\262\023\240\323\011\377\366\366\056\153\101
-\161\171\315\342\155\375\256\131\153\205\035\270\116\042\232\355
-\146\071\156\113\224\346\125\374\013\033\213\167\301\123\023\146
-\211\331\050\326\213\363\105\112\143\267\375\173\013\141\135\270
-\155\276\303\334\133\171\322\355\206\345\242\115\276\136\164\174
-\152\355\026\070\037\177\130\201\132\032\353\062\210\055\262\363
-\071\167\200\257\136\266\141\165\051\333\043\115\210\312\120\050
-\313\205\322\323\020\242\131\156\323\223\124\000\172\242\106\225
-\206\005\234\251\031\230\345\061\162\014\000\342\147\331\100\340
-\044\063\173\157\054\271\134\253\145\235\054\254\166\352\065\231
-\365\227\271\017\044\354\307\166\041\050\145\256\127\350\007\210
-\165\112\126\240\322\005\072\244\346\215\222\210\054\363\362\341
-\301\306\141\333\101\305\307\233\367\016\032\121\105\302\141\153
-\334\144\047\027\214\132\267\332\164\050\315\227\344\275
-END
-
-# Trust for Certificate "TC TrustCenter Class 2 CA II"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Class 2 CA II"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\256\120\203\355\174\364\134\274\217\141\306\041\376\150\135\171
-\102\041\025\156
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\316\170\063\134\131\170\001\156\030\352\271\066\240\271\056\043
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\166\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\042\060
-\040\006\003\125\004\013\023\031\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\062\040\103
-\101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\062\040\103\101\040\111\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\056\152\000\001\000\002\037\327\122\041\054\021\134\073
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TC TrustCenter Class 3 CA II"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Class 3 CA II"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\166\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\042\060
-\040\006\003\125\004\013\023\031\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103
-\101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\063\040\103\101\040\111\111
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\166\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\042\060
-\040\006\003\125\004\013\023\031\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103
-\101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\063\040\103\101\040\111\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\112\107\000\001\000\002\345\240\135\326\077\000\121\277
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\252\060\202\003\222\240\003\002\001\002\002\016\112
-\107\000\001\000\002\345\240\135\326\077\000\121\277\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\060\166\061\013
-\060\011\006\003\125\004\006\023\002\104\105\061\034\060\032\006
-\003\125\004\012\023\023\124\103\040\124\162\165\163\164\103\145
-\156\164\145\162\040\107\155\142\110\061\042\060\040\006\003\125
-\004\013\023\031\124\103\040\124\162\165\163\164\103\145\156\164
-\145\162\040\103\154\141\163\163\040\063\040\103\101\061\045\060
-\043\006\003\125\004\003\023\034\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103
-\101\040\111\111\060\036\027\015\060\066\060\061\061\062\061\064
-\064\061\065\067\132\027\015\062\065\061\062\063\061\062\062\065
-\071\065\071\132\060\166\061\013\060\011\006\003\125\004\006\023
-\002\104\105\061\034\060\032\006\003\125\004\012\023\023\124\103
-\040\124\162\165\163\164\103\145\156\164\145\162\040\107\155\142
-\110\061\042\060\040\006\003\125\004\013\023\031\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\063\040\103\101\061\045\060\043\006\003\125\004\003\023\034
-\124\103\040\124\162\165\163\164\103\145\156\164\145\162\040\103
-\154\141\163\163\040\063\040\103\101\040\111\111\060\202\001\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\001\017\000\060\202\001\012\002\202\001\001\000\264\340\273
-\121\273\071\134\213\004\305\114\171\034\043\206\061\020\143\103
-\125\047\077\306\105\307\244\075\354\011\015\032\036\040\302\126
-\036\336\033\067\007\060\042\057\157\361\006\361\253\255\326\310
-\253\141\243\057\103\304\260\262\055\374\303\226\151\173\176\212
-\344\314\300\071\022\220\102\140\311\314\065\150\356\332\137\220
-\126\137\315\034\115\133\130\111\353\016\001\117\144\372\054\074
-\211\130\330\057\056\342\260\150\351\042\073\165\211\326\104\032
-\145\362\033\227\046\035\050\155\254\350\275\131\035\053\044\366
-\326\204\003\146\210\044\000\170\140\361\370\253\376\002\262\153
-\373\042\373\065\346\026\321\255\366\056\022\344\372\065\152\345
-\031\271\135\333\073\036\032\373\323\377\025\024\010\330\011\152
-\272\105\235\024\171\140\175\257\100\212\007\163\263\223\226\323
-\164\064\215\072\067\051\336\134\354\365\356\056\061\302\040\334
-\276\361\117\177\043\122\331\133\342\144\331\234\252\007\010\265
-\105\275\321\320\061\301\253\124\237\251\322\303\142\140\003\361
-\273\071\112\222\112\075\012\271\235\305\240\376\067\002\003\001
-\000\001\243\202\001\064\060\202\001\060\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003\125
-\035\016\004\026\004\024\324\242\374\237\263\303\330\003\323\127
-\134\007\244\320\044\247\300\362\000\324\060\201\355\006\003\125
-\035\037\004\201\345\060\201\342\060\201\337\240\201\334\240\201
-\331\206\065\150\164\164\160\072\057\057\167\167\167\056\164\162
-\165\163\164\143\145\156\164\145\162\056\144\145\057\143\162\154
-\057\166\062\057\164\143\137\143\154\141\163\163\137\063\137\143
-\141\137\111\111\056\143\162\154\206\201\237\154\144\141\160\072
-\057\057\167\167\167\056\164\162\165\163\164\143\145\156\164\145
-\162\056\144\145\057\103\116\075\124\103\045\062\060\124\162\165
-\163\164\103\145\156\164\145\162\045\062\060\103\154\141\163\163
-\045\062\060\063\045\062\060\103\101\045\062\060\111\111\054\117
-\075\124\103\045\062\060\124\162\165\163\164\103\145\156\164\145
-\162\045\062\060\107\155\142\110\054\117\125\075\162\157\157\164
-\143\145\162\164\163\054\104\103\075\164\162\165\163\164\143\145
-\156\164\145\162\054\104\103\075\144\145\077\143\145\162\164\151
-\146\151\143\141\164\145\122\145\166\157\143\141\164\151\157\156
-\114\151\163\164\077\142\141\163\145\077\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\066\140
-\344\160\367\006\040\103\331\043\032\102\362\370\243\262\271\115
-\212\264\363\302\232\125\061\174\304\073\147\232\264\337\115\016
-\212\223\112\027\213\033\215\312\211\341\317\072\036\254\035\361
-\234\062\264\216\131\166\242\101\205\045\067\240\023\320\365\174
-\116\325\352\226\342\156\162\301\273\052\376\154\156\370\221\230
-\106\374\311\033\127\133\352\310\032\073\077\260\121\230\074\007
-\332\054\131\001\332\213\104\350\341\164\375\247\150\335\124\272
-\203\106\354\310\106\265\370\257\227\300\073\011\034\217\316\162
-\226\075\063\126\160\274\226\313\330\325\175\040\232\203\237\032
-\334\071\361\305\162\243\021\003\375\073\102\122\051\333\350\001
-\367\233\136\214\326\215\206\116\031\372\274\034\276\305\041\245
-\207\236\170\056\066\333\011\161\243\162\064\370\154\343\006\011
-\362\136\126\245\323\335\230\372\324\346\006\364\360\266\040\143
-\113\352\051\275\252\202\146\036\373\201\252\247\067\255\023\030
-\346\222\303\201\301\063\273\210\036\241\347\342\264\275\061\154
-\016\121\075\157\373\226\126\200\342\066\027\321\334\344
-END
-
-# Trust for Certificate "TC TrustCenter Class 3 CA II"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Class 3 CA II"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\200\045\357\364\156\160\310\324\162\044\145\204\376\100\073\212
-\215\152\333\365
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\126\137\252\200\141\022\027\366\147\041\346\053\155\141\126\216
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\166\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\042\060
-\040\006\003\125\004\013\023\031\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103
-\101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\063\040\103\101\040\111\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\112\107\000\001\000\002\345\240\135\326\077\000\121\277
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TC TrustCenter Universal CA I"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Universal CA I"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\171\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\044\060
-\042\006\003\125\004\013\023\033\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\125\156\151\166\145\162\163\141\154
-\040\103\101\061\046\060\044\006\003\125\004\003\023\035\124\103
-\040\124\162\165\163\164\103\145\156\164\145\162\040\125\156\151
-\166\145\162\163\141\154\040\103\101\040\111
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\171\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\044\060
-\042\006\003\125\004\013\023\033\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\125\156\151\166\145\162\163\141\154
-\040\103\101\061\046\060\044\006\003\125\004\003\023\035\124\103
-\040\124\162\165\163\164\103\145\156\164\145\162\040\125\156\151
-\166\145\162\163\141\154\040\103\101\040\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\035\242\000\001\000\002\354\267\140\200\170\215\266\006
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\335\060\202\002\305\240\003\002\001\002\002\016\035
-\242\000\001\000\002\354\267\140\200\170\215\266\006\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\060\171\061\013
-\060\011\006\003\125\004\006\023\002\104\105\061\034\060\032\006
-\003\125\004\012\023\023\124\103\040\124\162\165\163\164\103\145
-\156\164\145\162\040\107\155\142\110\061\044\060\042\006\003\125
-\004\013\023\033\124\103\040\124\162\165\163\164\103\145\156\164
-\145\162\040\125\156\151\166\145\162\163\141\154\040\103\101\061
-\046\060\044\006\003\125\004\003\023\035\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\125\156\151\166\145\162\163
-\141\154\040\103\101\040\111\060\036\027\015\060\066\060\063\062
-\062\061\065\065\064\062\070\132\027\015\062\065\061\062\063\061
-\062\062\065\071\065\071\132\060\171\061\013\060\011\006\003\125
-\004\006\023\002\104\105\061\034\060\032\006\003\125\004\012\023
-\023\124\103\040\124\162\165\163\164\103\145\156\164\145\162\040
-\107\155\142\110\061\044\060\042\006\003\125\004\013\023\033\124
-\103\040\124\162\165\163\164\103\145\156\164\145\162\040\125\156
-\151\166\145\162\163\141\154\040\103\101\061\046\060\044\006\003
-\125\004\003\023\035\124\103\040\124\162\165\163\164\103\145\156
-\164\145\162\040\125\156\151\166\145\162\163\141\154\040\103\101
-\040\111\060\202\001\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202
-\001\001\000\244\167\043\226\104\257\220\364\061\247\020\364\046
-\207\234\363\070\331\017\136\336\317\101\350\061\255\306\164\221
-\044\226\170\036\011\240\233\232\225\112\112\365\142\174\002\250
-\312\254\373\132\004\166\071\336\137\361\371\263\277\363\003\130
-\125\322\252\267\343\004\042\321\370\224\332\042\010\000\215\323
-\174\046\135\314\167\171\347\054\170\071\250\046\163\016\242\135
-\045\151\205\117\125\016\232\357\306\271\104\341\127\075\337\037
-\124\042\345\157\145\252\063\204\072\363\316\172\276\125\227\256
-\215\022\017\024\063\342\120\160\303\111\207\023\274\121\336\327
-\230\022\132\357\072\203\063\222\006\165\213\222\174\022\150\173
-\160\152\017\265\233\266\167\133\110\131\235\344\357\132\255\363
-\301\236\324\327\105\116\312\126\064\041\274\076\027\133\157\167
-\014\110\001\103\051\260\335\077\226\156\346\225\252\014\300\040
-\266\375\076\066\047\234\343\134\317\116\201\334\031\273\221\220
-\175\354\346\227\004\036\223\314\042\111\327\227\206\266\023\012
-\074\103\043\167\176\360\334\346\315\044\037\073\203\233\064\072
-\203\064\343\002\003\001\000\001\243\143\060\141\060\037\006\003
-\125\035\043\004\030\060\026\200\024\222\244\165\054\244\236\276
-\201\104\353\171\374\212\305\225\245\353\020\165\163\060\017\006
-\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016
-\006\003\125\035\017\001\001\377\004\004\003\002\001\206\060\035
-\006\003\125\035\016\004\026\004\024\222\244\165\054\244\236\276
-\201\104\353\171\374\212\305\225\245\353\020\165\163\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001
-\000\050\322\340\206\325\346\370\173\360\227\334\042\153\073\225
-\024\126\017\021\060\245\232\117\072\260\072\340\006\313\145\365
-\355\306\227\047\376\045\362\127\346\136\225\214\076\144\140\025
-\132\177\057\015\001\305\261\140\375\105\065\317\360\262\277\006
-\331\357\132\276\263\142\041\264\327\253\065\174\123\076\246\047
-\361\241\055\332\032\043\235\314\335\354\074\055\236\047\064\135
-\017\302\066\171\274\311\112\142\055\355\153\331\175\101\103\174
-\266\252\312\355\141\261\067\202\025\011\032\212\026\060\330\354
-\311\326\107\162\170\113\020\106\024\216\137\016\257\354\307\057
-\253\020\327\266\361\156\354\206\262\302\350\015\222\163\334\242
-\364\017\072\277\141\043\020\211\234\110\100\156\160\000\263\323
-\272\067\104\130\021\172\002\152\210\360\067\064\360\031\351\254
-\324\145\163\366\151\214\144\224\072\171\205\051\260\026\053\014
-\202\077\006\234\307\375\020\053\236\017\054\266\236\343\025\277
-\331\066\034\272\045\032\122\075\032\354\042\014\034\340\244\242
-\075\360\350\071\317\201\300\173\355\135\037\157\305\320\013\327
-\230
-END
-
-# Trust for Certificate "TC TrustCenter Universal CA I"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Universal CA I"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\153\057\064\255\211\130\276\142\375\260\153\134\316\273\235\331
-\117\116\071\363
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\105\341\245\162\305\251\066\144\100\236\365\344\130\204\147\214
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\171\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\044\060
-\042\006\003\125\004\013\023\033\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\125\156\151\166\145\162\163\141\154
-\040\103\101\061\046\060\044\006\003\125\004\003\023\035\124\103
-\040\124\162\165\163\164\103\145\156\164\145\162\040\125\156\151
-\166\145\162\163\141\154\040\103\101\040\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\035\242\000\001\000\002\354\267\140\200\170\215\266\006
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Deutsche Telekom Root CA 2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Deutsche Telekom Root CA 2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\161\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\104\145\165\164\163\143
-\150\145\040\124\145\154\145\153\157\155\040\101\107\061\037\060
-\035\006\003\125\004\013\023\026\124\055\124\145\154\145\123\145
-\143\040\124\162\165\163\164\040\103\145\156\164\145\162\061\043
-\060\041\006\003\125\004\003\023\032\104\145\165\164\163\143\150
-\145\040\124\145\154\145\153\157\155\040\122\157\157\164\040\103
-\101\040\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\161\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\104\145\165\164\163\143
-\150\145\040\124\145\154\145\153\157\155\040\101\107\061\037\060
-\035\006\003\125\004\013\023\026\124\055\124\145\154\145\123\145
-\143\040\124\162\165\163\164\040\103\145\156\164\145\162\061\043
-\060\041\006\003\125\004\003\023\032\104\145\165\164\163\143\150
-\145\040\124\145\154\145\153\157\155\040\122\157\157\164\040\103
-\101\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\046
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\237\060\202\002\207\240\003\002\001\002\002\001\046
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\161\061\013\060\011\006\003\125\004\006\023\002\104\105\061\034
-\060\032\006\003\125\004\012\023\023\104\145\165\164\163\143\150
-\145\040\124\145\154\145\153\157\155\040\101\107\061\037\060\035
-\006\003\125\004\013\023\026\124\055\124\145\154\145\123\145\143
-\040\124\162\165\163\164\040\103\145\156\164\145\162\061\043\060
-\041\006\003\125\004\003\023\032\104\145\165\164\163\143\150\145
-\040\124\145\154\145\153\157\155\040\122\157\157\164\040\103\101
-\040\062\060\036\027\015\071\071\060\067\060\071\061\062\061\061
-\060\060\132\027\015\061\071\060\067\060\071\062\063\065\071\060
-\060\132\060\161\061\013\060\011\006\003\125\004\006\023\002\104
-\105\061\034\060\032\006\003\125\004\012\023\023\104\145\165\164
-\163\143\150\145\040\124\145\154\145\153\157\155\040\101\107\061
-\037\060\035\006\003\125\004\013\023\026\124\055\124\145\154\145
-\123\145\143\040\124\162\165\163\164\040\103\145\156\164\145\162
-\061\043\060\041\006\003\125\004\003\023\032\104\145\165\164\163
-\143\150\145\040\124\145\154\145\153\157\155\040\122\157\157\164
-\040\103\101\040\062\060\202\001\042\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001
-\012\002\202\001\001\000\253\013\243\065\340\213\051\024\261\024
-\205\257\074\020\344\071\157\065\135\112\256\335\352\141\215\225
-\111\364\157\144\243\032\140\146\244\251\100\042\204\331\324\245
-\345\170\223\016\150\001\255\271\115\134\072\316\323\270\250\102
-\100\337\317\243\272\202\131\152\222\033\254\034\232\332\010\053
-\045\047\371\151\043\107\361\340\353\054\172\233\365\023\002\320
-\176\064\174\302\236\074\000\131\253\365\332\014\365\062\074\053
-\254\120\332\326\303\336\203\224\312\250\014\231\062\016\010\110
-\126\133\152\373\332\341\130\130\001\111\137\162\101\074\025\006
-\001\216\135\255\252\270\223\264\315\236\353\247\350\152\055\122
-\064\333\072\357\134\165\121\332\333\363\061\371\356\161\230\062
-\304\124\025\104\014\371\233\125\355\255\337\030\010\240\243\206
-\212\111\356\123\005\217\031\114\325\336\130\171\233\322\152\034
-\102\253\305\325\247\317\150\017\226\344\341\141\230\166\141\310
-\221\174\326\076\000\342\221\120\207\341\235\012\346\255\227\322
-\035\306\072\175\313\274\332\003\064\325\216\133\001\365\152\007
-\267\026\266\156\112\177\002\003\001\000\001\243\102\060\100\060
-\035\006\003\125\035\016\004\026\004\024\061\303\171\033\272\365
-\123\327\027\340\211\172\055\027\154\012\263\053\235\063\060\017
-\006\003\125\035\023\004\010\060\006\001\001\377\002\001\005\060
-\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202
-\001\001\000\224\144\131\255\071\144\347\051\353\023\376\132\303
-\213\023\127\310\004\044\360\164\167\300\140\343\147\373\351\211
-\246\203\277\226\202\174\156\324\303\075\357\236\200\156\273\051
-\264\230\172\261\073\124\353\071\027\107\176\032\216\013\374\037
-\061\131\061\004\262\316\027\363\054\307\142\066\125\342\042\330
-\211\125\264\230\110\252\144\372\326\034\066\330\104\170\132\132
-\043\072\127\227\365\172\060\117\256\237\152\114\113\053\216\240
-\003\343\076\340\251\324\322\173\322\263\250\342\162\074\255\236
-\377\200\131\344\233\105\264\366\073\260\315\071\031\230\062\345
-\352\041\141\220\344\061\041\216\064\261\367\057\065\112\205\020
-\332\347\212\067\041\276\131\143\340\362\205\210\061\123\324\124
-\024\205\160\171\364\056\006\167\047\165\057\037\270\212\371\376
-\305\272\330\066\344\203\354\347\145\267\277\143\132\363\106\257
-\201\224\067\324\101\214\326\043\326\036\317\365\150\033\104\143
-\242\132\272\247\065\131\241\345\160\005\233\016\043\127\231\224
-\012\155\272\071\143\050\206\222\363\030\204\330\373\321\317\005
-\126\144\127
-END
-
-# Trust for Certificate "Deutsche Telekom Root CA 2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Deutsche Telekom Root CA 2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\205\244\010\300\234\031\076\135\121\130\175\315\326\023\060\375
-\214\336\067\277
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\164\001\112\221\261\010\304\130\316\107\315\360\335\021\123\010
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\161\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\104\145\165\164\163\143
-\150\145\040\124\145\154\145\153\157\155\040\101\107\061\037\060
-\035\006\003\125\004\013\023\026\124\055\124\145\154\145\123\145
-\143\040\124\162\165\163\164\040\103\145\156\164\145\162\061\043
-\060\041\006\003\125\004\003\023\032\104\145\165\164\163\143\150
-\145\040\124\145\154\145\153\157\155\040\122\157\157\164\040\103
-\101\040\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\046
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "ComSign CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ComSign CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\064\061\023\060\021\006\003\125\004\003\023\012\103\157\155
-\123\151\147\156\040\103\101\061\020\060\016\006\003\125\004\012
-\023\007\103\157\155\123\151\147\156\061\013\060\011\006\003\125
-\004\006\023\002\111\114
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\064\061\023\060\021\006\003\125\004\003\023\012\103\157\155
-\123\151\147\156\040\103\101\061\020\060\016\006\003\125\004\012
-\023\007\103\157\155\123\151\147\156\061\013\060\011\006\003\125
-\004\006\023\002\111\114
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\024\023\226\203\024\125\214\352\173\143\345\374\064\207
-\167\104
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\223\060\202\002\173\240\003\002\001\002\002\020\024
-\023\226\203\024\125\214\352\173\143\345\374\064\207\167\104\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\064
-\061\023\060\021\006\003\125\004\003\023\012\103\157\155\123\151
-\147\156\040\103\101\061\020\060\016\006\003\125\004\012\023\007
-\103\157\155\123\151\147\156\061\013\060\011\006\003\125\004\006
-\023\002\111\114\060\036\027\015\060\064\060\063\062\064\061\061
-\063\062\061\070\132\027\015\062\071\060\063\061\071\061\065\060
-\062\061\070\132\060\064\061\023\060\021\006\003\125\004\003\023
-\012\103\157\155\123\151\147\156\040\103\101\061\020\060\016\006
-\003\125\004\012\023\007\103\157\155\123\151\147\156\061\013\060
-\011\006\003\125\004\006\023\002\111\114\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\360\344\124\151\053
-\323\307\217\152\104\344\176\130\047\370\013\320\344\224\022\212
-\361\033\070\070\057\037\061\234\006\324\054\247\336\013\052\256
-\032\240\343\236\152\277\237\074\307\156\242\371\213\144\154\072
-\255\205\125\121\124\245\070\125\270\253\203\004\362\077\144\066
-\367\300\215\103\103\152\146\321\367\027\052\325\357\066\372\060
-\020\102\327\123\315\371\372\063\163\114\263\351\204\040\212\326
-\101\047\065\344\070\372\224\233\270\172\344\171\037\063\373\033
-\330\041\011\050\174\115\030\151\136\144\212\172\031\223\312\176
-\354\363\162\347\067\007\130\131\050\254\102\371\305\377\315\077
-\347\245\372\070\261\320\014\307\331\122\032\123\326\201\314\102
-\172\065\133\355\113\072\172\366\265\216\314\377\017\174\344\140
-\066\207\057\255\360\241\045\175\377\322\113\021\210\160\124\246
-\101\250\147\123\122\102\136\344\064\236\344\276\243\354\252\142
-\135\335\303\114\246\202\101\344\063\013\254\311\063\017\144\202
-\127\052\375\014\255\066\341\014\256\113\305\357\073\231\331\043
-\263\133\135\264\127\354\164\160\014\052\117\002\003\001\000\001
-\243\201\240\060\201\235\060\014\006\003\125\035\023\004\005\060
-\003\001\001\377\060\075\006\003\125\035\037\004\066\060\064\060
-\062\240\060\240\056\206\054\150\164\164\160\072\057\057\146\145
-\144\151\162\056\143\157\155\163\151\147\156\056\143\157\056\151
-\154\057\143\162\154\057\103\157\155\123\151\147\156\103\101\056
-\143\162\154\060\016\006\003\125\035\017\001\001\377\004\004\003
-\002\001\206\060\037\006\003\125\035\043\004\030\060\026\200\024
-\113\001\233\076\126\032\145\066\166\313\173\227\252\222\005\356
-\062\347\050\061\060\035\006\003\125\035\016\004\026\004\024\113
-\001\233\076\126\032\145\066\166\313\173\227\252\222\005\356\062
-\347\050\061\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\003\202\001\001\000\320\331\245\176\376\051\140\105\235
-\176\203\317\156\274\107\156\365\032\236\124\166\102\161\264\074
-\130\077\055\100\045\102\366\201\234\361\211\020\310\016\252\170
-\117\070\011\127\260\074\300\010\374\065\216\361\110\121\215\014
-\161\164\272\204\304\327\162\233\204\174\070\116\144\006\047\052
-\341\247\265\354\010\231\264\012\015\324\205\163\310\022\341\065
-\355\361\005\061\035\163\231\014\353\226\312\335\323\346\205\252
-\360\212\373\165\301\362\011\074\145\145\144\363\114\330\255\313
-\210\151\363\344\203\267\014\275\027\132\226\027\312\133\377\255
-\273\034\351\055\204\200\330\041\276\205\122\331\324\164\271\151
-\205\272\115\355\050\062\353\371\141\112\344\304\066\036\031\334
-\157\204\021\037\225\365\203\050\030\250\063\222\103\047\335\135
-\023\004\105\117\207\325\106\315\075\250\272\360\363\270\126\044
-\105\353\067\307\341\166\117\162\071\030\337\176\164\162\307\163
-\055\071\352\140\346\255\021\242\126\207\173\303\150\232\376\370
-\214\160\250\337\145\062\364\244\100\214\241\302\104\003\016\224
-\000\147\240\161\000\202\110
-END
-
-# Trust for Certificate "ComSign CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ComSign CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\341\244\133\024\032\041\332\032\171\364\032\102\251\141\326\151
-\315\006\064\301
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\315\364\071\363\265\030\120\327\076\244\305\221\240\076\041\113
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\064\061\023\060\021\006\003\125\004\003\023\012\103\157\155
-\123\151\147\156\040\103\101\061\020\060\016\006\003\125\004\012
-\023\007\103\157\155\123\151\147\156\061\013\060\011\006\003\125
-\004\006\023\002\111\114
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\024\023\226\203\024\125\214\352\173\143\345\374\064\207
-\167\104
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "ComSign Secured CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ComSign Secured CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\074\061\033\060\031\006\003\125\004\003\023\022\103\157\155
-\123\151\147\156\040\123\145\143\165\162\145\144\040\103\101\061
-\020\060\016\006\003\125\004\012\023\007\103\157\155\123\151\147
-\156\061\013\060\011\006\003\125\004\006\023\002\111\114
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\074\061\033\060\031\006\003\125\004\003\023\022\103\157\155
-\123\151\147\156\040\123\145\143\165\162\145\144\040\103\101\061
-\020\060\016\006\003\125\004\012\023\007\103\157\155\123\151\147
-\156\061\013\060\011\006\003\125\004\006\023\002\111\114
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\307\050\107\011\263\270\154\105\214\035\372\044\365
-\066\116\351
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\253\060\202\002\223\240\003\002\001\002\002\021\000
-\307\050\107\011\263\270\154\105\214\035\372\044\365\066\116\351
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\074\061\033\060\031\006\003\125\004\003\023\022\103\157\155\123
-\151\147\156\040\123\145\143\165\162\145\144\040\103\101\061\020
-\060\016\006\003\125\004\012\023\007\103\157\155\123\151\147\156
-\061\013\060\011\006\003\125\004\006\023\002\111\114\060\036\027
-\015\060\064\060\063\062\064\061\061\063\067\062\060\132\027\015
-\062\071\060\063\061\066\061\065\060\064\065\066\132\060\074\061
-\033\060\031\006\003\125\004\003\023\022\103\157\155\123\151\147
-\156\040\123\145\143\165\162\145\144\040\103\101\061\020\060\016
-\006\003\125\004\012\023\007\103\157\155\123\151\147\156\061\013
-\060\011\006\003\125\004\006\023\002\111\114\060\202\001\042\060
-\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202
-\001\017\000\060\202\001\012\002\202\001\001\000\306\265\150\137
-\035\224\025\303\244\010\125\055\343\240\127\172\357\351\164\052
-\273\271\174\127\111\032\021\136\117\051\207\014\110\326\152\347
-\217\324\176\127\044\271\006\211\344\034\074\352\254\343\332\041
-\200\163\041\012\357\171\230\154\037\010\377\241\120\175\362\230
-\033\311\124\157\076\245\050\354\041\004\017\105\273\007\075\241
-\300\372\052\230\035\116\006\223\373\365\210\073\253\137\313\026
-\277\346\363\236\112\207\355\031\352\302\237\103\344\361\201\245
-\177\020\117\076\321\112\142\255\123\033\313\203\377\007\145\245
-\222\055\146\251\133\270\132\364\035\264\041\221\112\027\173\236
-\062\376\126\044\071\262\124\204\103\365\204\302\330\274\101\220
-\314\235\326\150\332\351\202\120\251\073\150\317\265\135\002\224
-\140\026\261\103\331\103\135\335\135\207\156\352\273\263\311\153
-\366\003\224\011\160\336\026\021\172\053\350\166\217\111\020\230
-\167\271\143\134\213\063\227\165\366\013\214\262\253\133\336\164
-\040\045\077\343\363\021\371\207\150\206\065\161\303\035\214\055
-\353\345\032\254\017\163\325\202\131\100\200\323\002\003\001\000
-\001\243\201\247\060\201\244\060\014\006\003\125\035\023\004\005
-\060\003\001\001\377\060\104\006\003\125\035\037\004\075\060\073
-\060\071\240\067\240\065\206\063\150\164\164\160\072\057\057\146
-\145\144\151\162\056\143\157\155\163\151\147\156\056\143\157\056
-\151\154\057\143\162\154\057\103\157\155\123\151\147\156\123\145
-\143\165\162\145\144\103\101\056\143\162\154\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\206\060\037\006\003\125
-\035\043\004\030\060\026\200\024\301\113\355\160\266\367\076\174
-\000\073\000\217\307\076\016\105\237\036\135\354\060\035\006\003
-\125\035\016\004\026\004\024\301\113\355\160\266\367\076\174\000
-\073\000\217\307\076\016\105\237\036\135\354\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000\026
-\317\356\222\023\120\253\173\024\236\063\266\102\040\152\324\025
-\275\011\253\374\162\350\357\107\172\220\254\121\301\144\116\351
-\210\275\103\105\201\343\146\043\077\022\206\115\031\344\005\260
-\346\067\302\215\332\006\050\311\017\211\244\123\251\165\077\260
-\226\373\253\114\063\125\371\170\046\106\157\033\066\230\373\102
-\166\301\202\271\216\336\373\105\371\143\033\142\073\071\006\312
-\167\172\250\074\011\317\154\066\075\017\012\105\113\151\026\032
-\105\175\063\003\145\371\122\161\220\046\225\254\114\014\365\213
-\223\077\314\165\164\205\230\272\377\142\172\115\037\211\376\256
-\275\224\000\231\277\021\245\334\340\171\305\026\013\175\002\141
-\035\352\205\371\002\025\117\347\132\211\116\024\157\343\067\113
-\205\365\301\074\141\340\375\005\101\262\222\177\303\035\240\320
-\256\122\144\140\153\030\306\046\234\330\365\144\344\066\032\142
-\237\212\017\076\377\155\116\031\126\116\040\221\154\237\064\063
-\072\064\127\120\072\157\201\136\006\306\365\076\174\116\216\053
-\316\145\006\056\135\322\052\123\164\136\323\156\047\236\217
-END
-
-# Trust for Certificate "ComSign Secured CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ComSign Secured CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\371\315\016\054\332\166\044\301\217\275\360\360\253\266\105\270
-\367\376\325\172
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\100\001\045\006\215\041\103\152\016\103\000\234\347\103\363\325
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\074\061\033\060\031\006\003\125\004\003\023\022\103\157\155
-\123\151\147\156\040\123\145\143\165\162\145\144\040\103\101\061
-\020\060\016\006\003\125\004\012\023\007\103\157\155\123\151\147
-\156\061\013\060\011\006\003\125\004\006\023\002\111\114
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\307\050\107\011\263\270\154\105\214\035\372\044\365
-\066\116\351
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Cybertrust Global Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Cybertrust Global Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\073\061\030\060\026\006\003\125\004\012\023\017\103\171\142
-\145\162\164\162\165\163\164\054\040\111\156\143\061\037\060\035
-\006\003\125\004\003\023\026\103\171\142\145\162\164\162\165\163
-\164\040\107\154\157\142\141\154\040\122\157\157\164
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\073\061\030\060\026\006\003\125\004\012\023\017\103\171\142
-\145\162\164\162\165\163\164\054\040\111\156\143\061\037\060\035
-\006\003\125\004\003\023\026\103\171\142\145\162\164\162\165\163
-\164\040\107\154\157\142\141\154\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\013\004\000\000\000\000\001\017\205\252\055\110
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\241\060\202\002\211\240\003\002\001\002\002\013\004
-\000\000\000\000\001\017\205\252\055\110\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\060\073\061\030\060\026\006
-\003\125\004\012\023\017\103\171\142\145\162\164\162\165\163\164
-\054\040\111\156\143\061\037\060\035\006\003\125\004\003\023\026
-\103\171\142\145\162\164\162\165\163\164\040\107\154\157\142\141
-\154\040\122\157\157\164\060\036\027\015\060\066\061\062\061\065
-\060\070\060\060\060\060\132\027\015\062\061\061\062\061\065\060
-\070\060\060\060\060\132\060\073\061\030\060\026\006\003\125\004
-\012\023\017\103\171\142\145\162\164\162\165\163\164\054\040\111
-\156\143\061\037\060\035\006\003\125\004\003\023\026\103\171\142
-\145\162\164\162\165\163\164\040\107\154\157\142\141\154\040\122
-\157\157\164\060\202\001\042\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002
-\202\001\001\000\370\310\274\275\024\120\146\023\377\360\323\171
-\354\043\362\267\032\307\216\205\361\022\163\246\031\252\020\333
-\234\242\145\164\132\167\076\121\175\126\366\334\043\266\324\355
-\137\130\261\067\115\325\111\016\156\365\152\207\326\322\214\322
-\047\306\342\377\066\237\230\145\240\023\116\306\052\144\233\325
-\220\022\317\024\006\364\073\343\324\050\276\350\016\370\253\116
-\110\224\155\216\225\061\020\134\355\242\055\275\325\072\155\262
-\034\273\140\300\106\113\001\365\111\256\176\106\212\320\164\215
-\241\014\002\316\356\374\347\217\270\153\146\363\177\104\000\277
-\146\045\024\053\335\020\060\035\007\226\077\115\366\153\270\217
-\267\173\014\245\070\353\336\107\333\325\135\071\374\210\247\363
-\327\052\164\361\350\132\242\073\237\120\272\246\214\105\065\302
-\120\145\225\334\143\202\357\335\277\167\115\234\142\311\143\163
-\026\320\051\017\111\251\110\360\263\252\267\154\305\247\060\071
-\100\135\256\304\342\135\046\123\360\316\034\043\010\141\250\224
-\031\272\004\142\100\354\037\070\160\167\022\006\161\247\060\030
-\135\045\047\245\002\003\001\000\001\243\201\245\060\201\242\060
-\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060
-\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377
-\060\035\006\003\125\035\016\004\026\004\024\266\010\173\015\172
-\314\254\040\114\206\126\062\136\317\253\156\205\055\160\127\060
-\077\006\003\125\035\037\004\070\060\066\060\064\240\062\240\060
-\206\056\150\164\164\160\072\057\057\167\167\167\062\056\160\165
-\142\154\151\143\055\164\162\165\163\164\056\143\157\155\057\143
-\162\154\057\143\164\057\143\164\162\157\157\164\056\143\162\154
-\060\037\006\003\125\035\043\004\030\060\026\200\024\266\010\173
-\015\172\314\254\040\114\206\126\062\136\317\253\156\205\055\160
-\127\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\202\001\001\000\126\357\012\043\240\124\116\225\227\311\370
-\211\332\105\301\324\243\000\045\364\037\023\253\267\243\205\130
-\151\302\060\255\330\025\212\055\343\311\315\201\132\370\163\043
-\132\247\174\005\363\375\042\073\016\321\006\304\333\066\114\163
-\004\216\345\260\042\344\305\363\056\245\331\043\343\270\116\112
-\040\247\156\002\044\237\042\140\147\173\213\035\162\011\305\061
-\134\351\171\237\200\107\075\255\241\013\007\024\075\107\377\003
-\151\032\014\013\104\347\143\045\247\177\262\311\270\166\204\355
-\043\366\175\007\253\105\176\323\337\263\277\351\212\266\315\250
-\242\147\053\122\325\267\145\360\071\114\143\240\221\171\223\122
-\017\124\335\203\273\237\321\217\247\123\163\303\313\377\060\354
-\174\004\270\330\104\037\223\137\161\011\042\267\156\076\352\034
-\003\116\235\032\040\141\373\201\067\354\136\374\012\105\253\327
-\347\027\125\320\240\352\140\233\246\366\343\214\133\051\302\006
-\140\024\235\055\227\114\251\223\025\235\141\304\001\137\110\326
-\130\275\126\061\022\116\021\310\041\340\263\021\221\145\333\264
-\246\210\070\316\125
-END
-
-# Trust for Certificate "Cybertrust Global Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Cybertrust Global Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\137\103\345\261\277\370\170\214\254\034\307\312\112\232\306\042
-\053\314\064\306
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\162\344\112\207\343\151\100\200\167\352\274\343\364\377\360\341
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\073\061\030\060\026\006\003\125\004\012\023\017\103\171\142
-\145\162\164\162\165\163\164\054\040\111\156\143\061\037\060\035
-\006\003\125\004\003\023\026\103\171\142\145\162\164\162\165\163
-\164\040\107\154\157\142\141\154\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\013\004\000\000\000\000\001\017\205\252\055\110
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "ePKI Root Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ePKI Root Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\136\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\043\060\041\006\003\125\004\012\014\032\103\150\165\156\147\150
-\167\141\040\124\145\154\145\143\157\155\040\103\157\056\054\040
-\114\164\144\056\061\052\060\050\006\003\125\004\013\014\041\145
-\120\113\111\040\122\157\157\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\136\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\043\060\041\006\003\125\004\012\014\032\103\150\165\156\147\150
-\167\141\040\124\145\154\145\143\157\155\040\103\157\056\054\040
-\114\164\144\056\061\052\060\050\006\003\125\004\013\014\041\145
-\120\113\111\040\122\157\157\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\025\310\275\145\107\134\257\270\227\000\136\344\006\322
-\274\235
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\260\060\202\003\230\240\003\002\001\002\002\020\025
-\310\275\145\107\134\257\270\227\000\136\344\006\322\274\235\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\136
-\061\013\060\011\006\003\125\004\006\023\002\124\127\061\043\060
-\041\006\003\125\004\012\014\032\103\150\165\156\147\150\167\141
-\040\124\145\154\145\143\157\155\040\103\157\056\054\040\114\164
-\144\056\061\052\060\050\006\003\125\004\013\014\041\145\120\113
-\111\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141
-\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\036
-\027\015\060\064\061\062\062\060\060\062\063\061\062\067\132\027
-\015\063\064\061\062\062\060\060\062\063\061\062\067\132\060\136
-\061\013\060\011\006\003\125\004\006\023\002\124\127\061\043\060
-\041\006\003\125\004\012\014\032\103\150\165\156\147\150\167\141
-\040\124\145\154\145\143\157\155\040\103\157\056\054\040\114\164
-\144\056\061\052\060\050\006\003\125\004\013\014\041\145\120\113
-\111\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141
-\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\202
-\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
-\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000\341
-\045\017\356\215\333\210\063\165\147\315\255\037\175\072\116\155
-\235\323\057\024\363\143\164\313\001\041\152\067\352\204\120\007
-\113\046\133\011\103\154\041\236\152\310\325\003\365\140\151\217
-\314\360\042\344\037\347\367\152\042\061\267\054\025\362\340\376
-\000\152\103\377\207\145\306\265\032\301\247\114\155\042\160\041
-\212\061\362\227\164\211\011\022\046\034\236\312\331\022\242\225
-\074\332\351\147\277\010\240\144\343\326\102\267\105\357\227\364
-\366\365\327\265\112\025\002\130\175\230\130\113\140\274\315\327
-\015\232\023\063\123\321\141\371\172\325\327\170\263\232\063\367
-\000\206\316\035\115\224\070\257\250\354\170\121\160\212\134\020
-\203\121\041\367\021\075\064\206\136\345\110\315\227\201\202\065
-\114\031\354\145\366\153\305\005\241\356\107\023\326\263\041\047
-\224\020\012\331\044\073\272\276\104\023\106\060\077\227\074\330
-\327\327\152\356\073\070\343\053\324\227\016\271\033\347\007\111
-\177\067\052\371\167\170\317\124\355\133\106\235\243\200\016\221
-\103\301\326\133\137\024\272\237\246\215\044\107\100\131\277\162
-\070\262\066\154\067\377\231\321\135\016\131\012\253\151\367\300
-\262\004\105\172\124\000\256\276\123\366\265\347\341\370\074\243
-\061\322\251\376\041\122\144\305\246\147\360\165\007\006\224\024
-\201\125\306\047\344\001\217\027\301\152\161\327\276\113\373\224
-\130\175\176\021\063\261\102\367\142\154\030\326\317\011\150\076
-\177\154\366\036\217\142\255\245\143\333\011\247\037\042\102\101
-\036\157\231\212\076\327\371\077\100\172\171\260\245\001\222\322
-\235\075\010\025\245\020\001\055\263\062\166\250\225\015\263\172
-\232\373\007\020\170\021\157\341\217\307\272\017\045\032\164\052
-\345\034\230\101\231\337\041\207\350\225\006\152\012\263\152\107
-\166\145\366\072\317\217\142\027\031\173\012\050\315\032\322\203
-\036\041\307\054\277\276\377\141\150\267\147\033\273\170\115\215
-\316\147\345\344\301\216\267\043\146\342\235\220\165\064\230\251
-\066\053\212\232\224\271\235\354\314\212\261\370\045\211\134\132
-\266\057\214\037\155\171\044\247\122\150\303\204\065\342\146\215
-\143\016\045\115\325\031\262\346\171\067\247\042\235\124\061\002
-\003\001\000\001\243\152\060\150\060\035\006\003\125\035\016\004
-\026\004\024\036\014\367\266\147\362\341\222\046\011\105\300\125
-\071\056\167\077\102\112\242\060\014\006\003\125\035\023\004\005
-\060\003\001\001\377\060\071\006\004\147\052\007\000\004\061\060
-\057\060\055\002\001\000\060\011\006\005\053\016\003\002\032\005
-\000\060\007\006\005\147\052\003\000\000\004\024\105\260\302\307
-\012\126\174\356\133\170\014\225\371\030\123\301\246\034\330\020
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\002\001\000\011\263\203\123\131\001\076\225\111\271\361\201
-\272\371\166\040\043\265\047\140\164\324\152\231\064\136\154\000
-\123\331\237\362\246\261\044\007\104\152\052\306\245\216\170\022
-\350\107\331\130\033\023\052\136\171\233\237\012\052\147\246\045
-\077\006\151\126\163\303\212\146\110\373\051\201\127\164\006\312
-\234\352\050\350\070\147\046\053\361\325\265\077\145\223\370\066
-\135\216\215\215\100\040\207\031\352\357\047\300\075\264\071\017
-\045\173\150\120\164\125\234\014\131\175\132\075\101\224\045\122
-\010\340\107\054\025\061\031\325\277\007\125\306\273\022\265\227
-\364\137\203\205\272\161\301\331\154\201\021\166\012\012\260\277
-\202\227\367\352\075\372\372\354\055\251\050\224\073\126\335\322
-\121\056\256\300\275\010\025\214\167\122\064\226\326\233\254\323
-\035\216\141\017\065\173\233\256\071\151\013\142\140\100\040\066
-\217\257\373\066\356\055\010\112\035\270\277\233\134\370\352\245
-\033\240\163\246\330\370\156\340\063\004\137\150\252\047\207\355
-\331\301\220\234\355\275\343\152\065\257\143\337\253\030\331\272
-\346\351\112\352\120\212\017\141\223\036\342\055\031\342\060\224
-\065\222\135\016\266\007\257\031\200\217\107\220\121\113\056\115
-\335\205\342\322\012\122\012\027\232\374\032\260\120\002\345\001
-\243\143\067\041\114\104\304\233\121\231\021\016\163\234\006\217
-\124\056\247\050\136\104\071\207\126\055\067\275\205\104\224\341
-\014\113\054\234\303\222\205\064\141\313\017\270\233\112\103\122
-\376\064\072\175\270\351\051\334\166\251\310\060\370\024\161\200
-\306\036\066\110\164\042\101\134\207\202\350\030\161\213\101\211
-\104\347\176\130\133\250\270\215\023\351\247\154\303\107\355\263
-\032\235\142\256\215\202\352\224\236\335\131\020\303\255\335\342
-\115\343\061\325\307\354\350\362\260\376\222\036\026\012\032\374
-\331\363\370\047\266\311\276\035\264\154\144\220\177\364\344\304
-\133\327\067\256\102\016\335\244\032\157\174\210\124\305\026\156
-\341\172\150\056\370\072\277\015\244\074\211\073\170\247\116\143
-\203\004\041\010\147\215\362\202\111\320\133\375\261\315\017\203
-\204\324\076\040\205\367\112\075\053\234\375\052\012\011\115\352
-\201\370\021\234
-END
-
-# Trust for Certificate "ePKI Root Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ePKI Root Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\147\145\015\361\176\216\176\133\202\100\244\364\126\113\317\342
-\075\151\306\360
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\033\056\000\312\046\006\220\075\255\376\157\025\150\323\153\263
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\136\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\043\060\041\006\003\125\004\012\014\032\103\150\165\156\147\150
-\167\141\040\124\145\154\145\143\157\155\040\103\157\056\054\040
-\114\164\144\056\061\052\060\050\006\003\125\004\013\014\041\145
-\120\113\111\040\122\157\157\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\025\310\275\145\107\134\257\270\227\000\136\344\006\322
-\274\235
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TUBITAK UEKAE Kok Sertifika Hizmet Saglayicisi - Surum 3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\202\001\053\061\013\060\011\006\003\125\004\006\023\002\124
-\122\061\030\060\026\006\003\125\004\007\014\017\107\145\142\172
-\145\040\055\040\113\157\143\141\145\154\151\061\107\060\105\006
-\003\125\004\012\014\076\124\303\274\162\153\151\171\145\040\102
-\151\154\151\155\163\145\154\040\166\145\040\124\145\153\156\157
-\154\157\152\151\153\040\101\162\141\305\237\164\304\261\162\155
-\141\040\113\165\162\165\155\165\040\055\040\124\303\234\102\304
-\260\124\101\113\061\110\060\106\006\003\125\004\013\014\077\125
-\154\165\163\141\154\040\105\154\145\153\164\162\157\156\151\153
-\040\166\145\040\113\162\151\160\164\157\154\157\152\151\040\101
-\162\141\305\237\164\304\261\162\155\141\040\105\156\163\164\151
-\164\303\274\163\303\274\040\055\040\125\105\113\101\105\061\043
-\060\041\006\003\125\004\013\014\032\113\141\155\165\040\123\145
-\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153
-\145\172\151\061\112\060\110\006\003\125\004\003\014\101\124\303
-\234\102\304\260\124\101\113\040\125\105\113\101\105\040\113\303
-\266\153\040\123\145\162\164\151\146\151\153\141\040\110\151\172
-\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304\261
-\163\304\261\040\055\040\123\303\274\162\303\274\155\040\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\202\001\053\061\013\060\011\006\003\125\004\006\023\002\124
-\122\061\030\060\026\006\003\125\004\007\014\017\107\145\142\172
-\145\040\055\040\113\157\143\141\145\154\151\061\107\060\105\006
-\003\125\004\012\014\076\124\303\274\162\153\151\171\145\040\102
-\151\154\151\155\163\145\154\040\166\145\040\124\145\153\156\157
-\154\157\152\151\153\040\101\162\141\305\237\164\304\261\162\155
-\141\040\113\165\162\165\155\165\040\055\040\124\303\234\102\304
-\260\124\101\113\061\110\060\106\006\003\125\004\013\014\077\125
-\154\165\163\141\154\040\105\154\145\153\164\162\157\156\151\153
-\040\166\145\040\113\162\151\160\164\157\154\157\152\151\040\101
-\162\141\305\237\164\304\261\162\155\141\040\105\156\163\164\151
-\164\303\274\163\303\274\040\055\040\125\105\113\101\105\061\043
-\060\041\006\003\125\004\013\014\032\113\141\155\165\040\123\145
-\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153
-\145\172\151\061\112\060\110\006\003\125\004\003\014\101\124\303
-\234\102\304\260\124\101\113\040\125\105\113\101\105\040\113\303
-\266\153\040\123\145\162\164\151\146\151\153\141\040\110\151\172
-\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304\261
-\163\304\261\040\055\040\123\303\274\162\303\274\155\040\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\021
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\027\060\202\003\377\240\003\002\001\002\002\001\021
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\202\001\053\061\013\060\011\006\003\125\004\006\023\002\124\122
-\061\030\060\026\006\003\125\004\007\014\017\107\145\142\172\145
-\040\055\040\113\157\143\141\145\154\151\061\107\060\105\006\003
-\125\004\012\014\076\124\303\274\162\153\151\171\145\040\102\151
-\154\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154
-\157\152\151\153\040\101\162\141\305\237\164\304\261\162\155\141
-\040\113\165\162\165\155\165\040\055\040\124\303\234\102\304\260
-\124\101\113\061\110\060\106\006\003\125\004\013\014\077\125\154
-\165\163\141\154\040\105\154\145\153\164\162\157\156\151\153\040
-\166\145\040\113\162\151\160\164\157\154\157\152\151\040\101\162
-\141\305\237\164\304\261\162\155\141\040\105\156\163\164\151\164
-\303\274\163\303\274\040\055\040\125\105\113\101\105\061\043\060
-\041\006\003\125\004\013\014\032\113\141\155\165\040\123\145\162
-\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153\145
-\172\151\061\112\060\110\006\003\125\004\003\014\101\124\303\234
-\102\304\260\124\101\113\040\125\105\113\101\105\040\113\303\266
-\153\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155
-\145\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163
-\304\261\040\055\040\123\303\274\162\303\274\155\040\063\060\036
-\027\015\060\067\060\070\062\064\061\061\063\067\060\067\132\027
-\015\061\067\060\070\062\061\061\061\063\067\060\067\132\060\202
-\001\053\061\013\060\011\006\003\125\004\006\023\002\124\122\061
-\030\060\026\006\003\125\004\007\014\017\107\145\142\172\145\040
-\055\040\113\157\143\141\145\154\151\061\107\060\105\006\003\125
-\004\012\014\076\124\303\274\162\153\151\171\145\040\102\151\154
-\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157
-\152\151\153\040\101\162\141\305\237\164\304\261\162\155\141\040
-\113\165\162\165\155\165\040\055\040\124\303\234\102\304\260\124
-\101\113\061\110\060\106\006\003\125\004\013\014\077\125\154\165
-\163\141\154\040\105\154\145\153\164\162\157\156\151\153\040\166
-\145\040\113\162\151\160\164\157\154\157\152\151\040\101\162\141
-\305\237\164\304\261\162\155\141\040\105\156\163\164\151\164\303
-\274\163\303\274\040\055\040\125\105\113\101\105\061\043\060\041
-\006\003\125\004\013\014\032\113\141\155\165\040\123\145\162\164
-\151\146\151\153\141\163\171\157\156\040\115\145\162\153\145\172
-\151\061\112\060\110\006\003\125\004\003\014\101\124\303\234\102
-\304\260\124\101\113\040\125\105\113\101\105\040\113\303\266\153
-\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145
-\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304
-\261\040\055\040\123\303\274\162\303\274\155\040\063\060\202\001
-\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\202\001\017\000\060\202\001\012\002\202\001\001\000\212\155
-\113\377\020\210\072\303\366\176\224\350\352\040\144\160\256\041
-\201\276\072\173\074\333\361\035\122\177\131\372\363\042\114\225
-\240\220\274\110\116\021\253\373\267\265\215\172\203\050\214\046
-\106\330\116\225\100\207\141\237\305\236\155\201\207\127\154\212
-\073\264\146\352\314\100\374\343\252\154\262\313\001\333\062\277
-\322\353\205\317\241\015\125\303\133\070\127\160\270\165\306\171
-\321\024\060\355\033\130\133\153\357\065\362\241\041\116\305\316
-\174\231\137\154\271\270\042\223\120\247\315\114\160\152\276\152
-\005\177\023\234\053\036\352\376\107\316\004\245\157\254\223\056
-\174\053\237\236\171\023\221\350\352\236\312\070\165\216\142\260
-\225\223\052\345\337\351\136\227\156\040\137\137\204\172\104\071
-\031\100\034\272\125\053\373\060\262\201\357\204\343\334\354\230
-\070\071\003\205\010\251\124\003\005\051\360\311\217\213\352\013
-\206\145\031\021\323\351\011\043\336\150\223\003\311\066\034\041
-\156\316\214\146\361\231\060\330\327\263\303\035\370\201\056\250
-\275\202\013\146\376\202\313\341\340\032\202\303\100\201\002\003
-\001\000\001\243\102\060\100\060\035\006\003\125\035\016\004\026
-\004\024\275\210\207\311\217\366\244\012\013\252\353\305\376\221
-\043\235\253\112\212\062\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\003\202\001\001\000\035\174\372\111\217
-\064\351\267\046\222\026\232\005\164\347\113\320\155\071\154\303
-\046\366\316\270\061\274\304\337\274\052\370\067\221\030\334\004
-\310\144\231\053\030\155\200\003\131\311\256\370\130\320\076\355
-\303\043\237\151\074\206\070\034\236\357\332\047\170\321\204\067
-\161\212\074\113\071\317\176\105\006\326\055\330\212\115\170\022
-\326\255\302\323\313\322\320\101\363\046\066\112\233\225\154\014
-\356\345\321\103\047\146\301\210\367\172\263\040\154\352\260\151
-\053\307\040\350\014\003\304\101\005\231\342\077\344\153\370\240
-\206\201\307\204\306\037\325\113\201\022\262\026\041\054\023\241
-\200\262\136\014\112\023\236\040\330\142\100\253\220\352\144\112
-\057\254\015\001\022\171\105\250\057\207\031\150\310\342\205\307
-\060\262\165\371\070\077\262\300\223\264\153\342\003\104\316\147
-\240\337\211\326\255\214\166\243\023\303\224\141\053\153\331\154
-\301\007\012\042\007\205\154\205\044\106\251\276\077\213\170\204
-\202\176\044\014\235\375\201\067\343\045\250\355\066\116\225\054
-\311\234\220\332\354\251\102\074\255\266\002
-END
-
-# Trust for Certificate "TUBITAK UEKAE Kok Sertifika Hizmet Saglayicisi - Surum 3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\033\113\071\141\046\047\153\144\221\242\150\155\327\002\103\041
-\055\037\035\226
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\355\101\365\214\120\305\053\234\163\346\356\154\353\302\250\046
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\202\001\053\061\013\060\011\006\003\125\004\006\023\002\124
-\122\061\030\060\026\006\003\125\004\007\014\017\107\145\142\172
-\145\040\055\040\113\157\143\141\145\154\151\061\107\060\105\006
-\003\125\004\012\014\076\124\303\274\162\153\151\171\145\040\102
-\151\154\151\155\163\145\154\040\166\145\040\124\145\153\156\157
-\154\157\152\151\153\040\101\162\141\305\237\164\304\261\162\155
-\141\040\113\165\162\165\155\165\040\055\040\124\303\234\102\304
-\260\124\101\113\061\110\060\106\006\003\125\004\013\014\077\125
-\154\165\163\141\154\040\105\154\145\153\164\162\157\156\151\153
-\040\166\145\040\113\162\151\160\164\157\154\157\152\151\040\101
-\162\141\305\237\164\304\261\162\155\141\040\105\156\163\164\151
-\164\303\274\163\303\274\040\055\040\125\105\113\101\105\061\043
-\060\041\006\003\125\004\013\014\032\113\141\155\165\040\123\145
-\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153
-\145\172\151\061\112\060\110\006\003\125\004\003\014\101\124\303
-\234\102\304\260\124\101\113\040\125\105\113\101\105\040\113\303
-\266\153\040\123\145\162\164\151\146\151\153\141\040\110\151\172
-\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304\261
-\163\304\261\040\055\040\123\303\274\162\303\274\155\040\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\021
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Buypass Class 2 CA 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Buypass Class 2 CA 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\113\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\035
-\060\033\006\003\125\004\003\014\024\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\062\040\103\101\040\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\113\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\035
-\060\033\006\003\125\004\003\014\024\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\062\040\103\101\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\123\060\202\002\073\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\113\061\013\060\011\006\003\125\004\006\023\002\116\117\061\035
-\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163\163
-\040\101\123\055\071\070\063\061\066\063\063\062\067\061\035\060
-\033\006\003\125\004\003\014\024\102\165\171\160\141\163\163\040
-\103\154\141\163\163\040\062\040\103\101\040\061\060\036\027\015
-\060\066\061\060\061\063\061\060\062\065\060\071\132\027\015\061
-\066\061\060\061\063\061\060\062\065\060\071\132\060\113\061\013
-\060\011\006\003\125\004\006\023\002\116\117\061\035\060\033\006
-\003\125\004\012\014\024\102\165\171\160\141\163\163\040\101\123
-\055\071\070\063\061\066\063\063\062\067\061\035\060\033\006\003
-\125\004\003\014\024\102\165\171\160\141\163\163\040\103\154\141
-\163\163\040\062\040\103\101\040\061\060\202\001\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017
-\000\060\202\001\012\002\202\001\001\000\213\074\007\105\330\366
-\337\346\307\312\272\215\103\305\107\215\260\132\301\070\333\222
-\204\034\257\023\324\017\157\066\106\040\304\056\314\161\160\064
-\242\064\323\067\056\330\335\072\167\057\300\353\051\350\134\322
-\265\251\221\064\207\042\131\376\314\333\347\231\257\226\301\250
-\307\100\335\245\025\214\156\310\174\227\003\313\346\040\362\327
-\227\137\061\241\057\067\322\276\356\276\251\255\250\114\236\041
-\146\103\073\250\274\363\011\243\070\325\131\044\301\302\107\166
-\261\210\134\202\073\273\053\246\004\327\214\007\217\315\325\101
-\035\360\256\270\051\054\224\122\140\064\224\073\332\340\070\321
-\235\063\076\025\364\223\062\305\000\332\265\051\146\016\072\170
-\017\041\122\137\002\345\222\173\045\323\222\036\057\025\235\201
-\344\235\216\350\357\211\316\024\114\124\035\034\201\022\115\160
-\250\276\020\005\027\176\037\321\270\127\125\355\315\273\122\302
-\260\036\170\302\115\066\150\313\126\046\301\122\301\275\166\367
-\130\325\162\176\037\104\166\273\000\211\035\026\235\121\065\357
-\115\302\126\357\153\340\214\073\015\351\002\003\001\000\001\243
-\102\060\100\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\077
-\215\232\131\213\374\173\173\234\243\257\070\260\071\355\220\161
-\200\326\310\060\016\006\003\125\035\017\001\001\377\004\004\003
-\002\001\006\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\003\202\001\001\000\025\032\176\023\212\271\350\007\243
-\113\047\062\262\100\221\362\041\321\144\205\276\143\152\322\317
-\201\302\025\325\172\176\014\051\254\067\036\034\174\166\122\225
-\332\265\177\043\241\051\167\145\311\062\235\250\056\126\253\140
-\166\316\026\264\215\177\170\300\325\231\121\203\177\136\331\276
-\014\250\120\355\042\307\255\005\114\166\373\355\356\036\107\144
-\366\367\047\175\134\050\017\105\305\134\142\136\246\232\221\221
-\267\123\027\056\334\255\140\235\226\144\071\275\147\150\262\256
-\005\313\115\347\137\037\127\206\325\040\234\050\373\157\023\070
-\365\366\021\222\366\175\231\136\037\014\350\253\104\044\051\162
-\100\075\066\122\257\214\130\220\163\301\354\141\054\171\241\354
-\207\265\077\332\115\331\041\000\060\336\220\332\016\323\032\110
-\251\076\205\013\024\213\214\274\101\236\152\367\016\160\300\065
-\367\071\242\135\146\320\173\131\237\250\107\022\232\047\043\244
-\055\216\047\203\222\040\241\327\025\177\361\056\030\356\364\110
-\177\057\177\361\241\030\265\241\013\224\240\142\040\062\234\035
-\366\324\357\277\114\210\150
-END
-
-# Trust for Certificate "Buypass Class 2 CA 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Buypass Class 2 CA 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\240\241\253\220\311\374\204\173\073\022\141\350\227\175\137\323
-\042\141\323\314
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\270\010\232\360\003\314\033\015\310\154\013\166\241\165\144\043
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\113\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\035
-\060\033\006\003\125\004\003\014\024\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\062\040\103\101\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Buypass Class 3 CA 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Buypass Class 3 CA 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\113\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\035
-\060\033\006\003\125\004\003\014\024\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\063\040\103\101\040\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\113\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\035
-\060\033\006\003\125\004\003\014\024\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\063\040\103\101\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\002
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\123\060\202\002\073\240\003\002\001\002\002\001\002
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\113\061\013\060\011\006\003\125\004\006\023\002\116\117\061\035
-\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163\163
-\040\101\123\055\071\070\063\061\066\063\063\062\067\061\035\060
-\033\006\003\125\004\003\014\024\102\165\171\160\141\163\163\040
-\103\154\141\163\163\040\063\040\103\101\040\061\060\036\027\015
-\060\065\060\065\060\071\061\064\061\063\060\063\132\027\015\061
-\065\060\065\060\071\061\064\061\063\060\063\132\060\113\061\013
-\060\011\006\003\125\004\006\023\002\116\117\061\035\060\033\006
-\003\125\004\012\014\024\102\165\171\160\141\163\163\040\101\123
-\055\071\070\063\061\066\063\063\062\067\061\035\060\033\006\003
-\125\004\003\014\024\102\165\171\160\141\163\163\040\103\154\141
-\163\163\040\063\040\103\101\040\061\060\202\001\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017
-\000\060\202\001\012\002\202\001\001\000\244\216\327\164\331\051
-\144\336\137\037\207\200\221\352\116\071\346\031\306\104\013\200
-\325\013\257\123\007\213\022\275\346\147\360\002\261\211\366\140
-\212\304\133\260\102\321\300\041\250\313\341\233\357\144\121\266
-\247\317\025\365\164\200\150\004\220\240\130\242\346\164\246\123
-\123\125\110\143\077\222\126\335\044\116\216\370\272\053\377\363
-\064\212\236\050\327\064\237\254\057\326\017\361\244\057\275\122
-\262\111\205\155\071\065\360\104\060\223\106\044\363\266\347\123
-\373\274\141\257\251\243\024\373\302\027\027\204\154\340\174\210
-\370\311\034\127\054\360\075\176\224\274\045\223\204\350\232\000
-\232\105\005\102\127\200\364\116\316\331\256\071\366\310\123\020
-\014\145\072\107\173\140\302\326\372\221\311\306\161\154\275\221
-\207\074\221\206\111\253\363\017\240\154\046\166\136\034\254\233
-\161\345\215\274\233\041\036\234\326\070\176\044\200\025\061\202
-\226\261\111\323\142\067\133\210\014\012\142\064\376\247\110\176
-\231\261\060\213\220\067\225\034\250\037\245\054\215\364\125\310
-\333\335\131\012\302\255\170\240\364\213\002\003\001\000\001\243
-\102\060\100\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\070
-\024\346\310\360\251\244\003\364\116\076\042\243\133\362\326\340
-\255\100\164\060\016\006\003\125\035\017\001\001\377\004\004\003
-\002\001\006\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\003\202\001\001\000\001\147\243\214\311\045\075\023\143
-\135\026\157\354\241\076\011\134\221\025\052\052\331\200\041\117
-\005\334\273\245\211\253\023\063\052\236\070\267\214\157\002\162
-\143\307\163\167\036\011\006\272\073\050\173\244\107\311\141\153
-\010\010\040\374\212\005\212\037\274\272\306\302\376\317\156\354
-\023\063\161\147\056\151\372\251\054\077\146\300\022\131\115\013
-\124\002\222\204\273\333\022\357\203\160\160\170\310\123\372\337
-\306\306\377\334\210\057\007\300\111\235\062\127\140\323\362\366
-\231\051\137\347\252\001\314\254\063\250\034\012\273\221\304\003
-\240\157\266\064\371\206\323\263\166\124\230\364\112\201\263\123
-\235\115\100\354\345\167\023\105\257\133\252\037\330\057\114\202
-\173\376\052\304\130\273\117\374\236\375\003\145\032\052\016\303
-\245\040\026\224\153\171\246\242\022\264\273\032\244\043\172\137
-\360\256\204\044\344\363\053\373\212\044\243\047\230\145\332\060
-\165\166\374\031\221\350\333\353\233\077\062\277\100\227\007\046
-\272\314\363\224\205\112\172\047\223\317\220\102\324\270\133\026
-\246\347\313\100\003\335\171
-END
-
-# Trust for Certificate "Buypass Class 3 CA 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Buypass Class 3 CA 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\141\127\072\021\337\016\330\176\325\222\145\042\352\320\126\327
-\104\263\043\161
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\337\074\163\131\201\347\071\120\201\004\114\064\242\313\263\173
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\113\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\035
-\060\033\006\003\125\004\003\014\024\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\063\040\103\101\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\002
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "EBG Elektronik Sertifika Hizmet Saglayicisi"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\200\061\070\060\066\006\003\125\004\003\014\057\105\102
-\107\040\105\154\145\153\164\162\157\156\151\153\040\123\145\162
-\164\151\146\151\153\141\040\110\151\172\155\145\164\040\123\141
-\304\237\154\141\171\304\261\143\304\261\163\304\261\061\067\060
-\065\006\003\125\004\012\014\056\105\102\107\040\102\151\154\151
-\305\237\151\155\040\124\145\153\156\157\154\157\152\151\154\145
-\162\151\040\166\145\040\110\151\172\155\145\164\154\145\162\151
-\040\101\056\305\236\056\061\013\060\011\006\003\125\004\006\023
-\002\124\122
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\200\061\070\060\066\006\003\125\004\003\014\057\105\102
-\107\040\105\154\145\153\164\162\157\156\151\153\040\123\145\162
-\164\151\146\151\153\141\040\110\151\172\155\145\164\040\123\141
-\304\237\154\141\171\304\261\143\304\261\163\304\261\061\067\060
-\065\006\003\125\004\012\014\056\105\102\107\040\102\151\154\151
-\305\237\151\155\040\124\145\153\156\157\154\157\152\151\154\145
-\162\151\040\166\145\040\110\151\172\155\145\164\154\145\162\151
-\040\101\056\305\236\056\061\013\060\011\006\003\125\004\006\023
-\002\124\122
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\114\257\163\102\034\216\164\002
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\347\060\202\003\317\240\003\002\001\002\002\010\114
-\257\163\102\034\216\164\002\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\060\201\200\061\070\060\066\006\003\125
-\004\003\014\057\105\102\107\040\105\154\145\153\164\162\157\156
-\151\153\040\123\145\162\164\151\146\151\153\141\040\110\151\172
-\155\145\164\040\123\141\304\237\154\141\171\304\261\143\304\261
-\163\304\261\061\067\060\065\006\003\125\004\012\014\056\105\102
-\107\040\102\151\154\151\305\237\151\155\040\124\145\153\156\157
-\154\157\152\151\154\145\162\151\040\166\145\040\110\151\172\155
-\145\164\154\145\162\151\040\101\056\305\236\056\061\013\060\011
-\006\003\125\004\006\023\002\124\122\060\036\027\015\060\066\060
-\070\061\067\060\060\062\061\060\071\132\027\015\061\066\060\070
-\061\064\060\060\063\061\060\071\132\060\201\200\061\070\060\066
-\006\003\125\004\003\014\057\105\102\107\040\105\154\145\153\164
-\162\157\156\151\153\040\123\145\162\164\151\146\151\153\141\040
-\110\151\172\155\145\164\040\123\141\304\237\154\141\171\304\261
-\143\304\261\163\304\261\061\067\060\065\006\003\125\004\012\014
-\056\105\102\107\040\102\151\154\151\305\237\151\155\040\124\145
-\153\156\157\154\157\152\151\154\145\162\151\040\166\145\040\110
-\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056\061
-\013\060\011\006\003\125\004\006\023\002\124\122\060\202\002\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\002\017\000\060\202\002\012\002\202\002\001\000\356\240\204
-\141\320\072\152\146\020\062\330\061\070\177\247\247\345\375\241
-\341\373\227\167\270\161\226\350\023\226\106\203\117\266\362\137
-\162\126\156\023\140\245\001\221\342\133\305\315\127\037\167\143
-\121\377\057\075\333\271\077\252\251\065\347\171\320\365\320\044
-\266\041\352\353\043\224\376\051\277\373\211\221\014\144\232\005
-\112\053\314\014\356\361\075\233\202\151\244\114\370\232\157\347
-\042\332\020\272\137\222\374\030\047\012\250\252\104\372\056\054
-\264\373\106\232\010\003\203\162\253\210\344\152\162\311\345\145
-\037\156\052\017\235\263\350\073\344\014\156\172\332\127\375\327
-\353\171\213\136\040\006\323\166\013\154\002\225\243\226\344\313
-\166\121\321\050\235\241\032\374\104\242\115\314\172\166\250\015
-\075\277\027\117\042\210\120\375\256\266\354\220\120\112\133\237
-\225\101\252\312\017\262\112\376\200\231\116\243\106\025\253\370
-\163\102\152\302\146\166\261\012\046\025\335\223\222\354\333\251
-\137\124\042\122\221\160\135\023\352\110\354\156\003\154\331\335
-\154\374\353\015\003\377\246\203\022\233\361\251\223\017\305\046
-\114\061\262\143\231\141\162\347\052\144\231\322\270\351\165\342
-\174\251\251\232\032\252\303\126\333\020\232\074\203\122\266\173
-\226\267\254\207\167\250\271\362\147\013\224\103\263\257\076\163
-\372\102\066\261\045\305\012\061\046\067\126\147\272\243\013\175
-\326\367\211\315\147\241\267\072\036\146\117\366\240\125\024\045
-\114\054\063\015\246\101\214\275\004\061\152\020\162\012\235\016
-\056\166\275\136\363\121\211\213\250\077\125\163\277\333\072\306
-\044\005\226\222\110\252\113\215\052\003\345\127\221\020\364\152
-\050\025\156\107\167\204\134\121\164\237\031\351\346\036\143\026
-\071\343\021\025\343\130\032\104\275\313\304\154\146\327\204\006
-\337\060\364\067\242\103\042\171\322\020\154\337\273\346\023\021
-\374\235\204\012\023\173\360\073\320\374\243\012\327\211\352\226
-\176\215\110\205\036\144\137\333\124\242\254\325\172\002\171\153
-\322\212\360\147\332\145\162\015\024\160\344\351\216\170\217\062
-\164\174\127\362\326\326\364\066\211\033\370\051\154\213\271\366
-\227\321\244\056\252\276\013\031\302\105\351\160\135\002\003\000
-\235\331\243\143\060\141\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\016\006\003\125\035\017\001\001
-\377\004\004\003\002\001\006\060\035\006\003\125\035\016\004\026
-\004\024\347\316\306\117\374\026\147\226\372\112\243\007\301\004
-\247\313\152\336\332\107\060\037\006\003\125\035\043\004\030\060
-\026\200\024\347\316\306\117\374\026\147\226\372\112\243\007\301
-\004\247\313\152\336\332\107\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\003\202\002\001\000\233\230\232\135\276
-\363\050\043\166\306\154\367\177\346\100\236\300\066\334\225\015
-\035\255\025\305\066\330\325\071\357\362\036\042\136\263\202\264
-\135\273\114\032\312\222\015\337\107\044\036\263\044\332\221\210
-\351\203\160\335\223\327\351\272\263\337\026\132\076\336\340\310
-\373\323\375\154\051\370\025\106\240\150\046\314\223\122\256\202
-\001\223\220\312\167\312\115\111\357\342\132\331\052\275\060\316
-\114\262\201\266\060\316\131\117\332\131\035\152\172\244\105\260
-\202\046\201\206\166\365\365\020\000\270\356\263\011\350\117\207
-\002\007\256\044\134\360\137\254\012\060\314\212\100\240\163\004
-\301\373\211\044\366\232\034\134\267\074\012\147\066\005\010\061
-\263\257\330\001\150\052\340\170\217\164\336\270\121\244\214\154
-\040\075\242\373\263\324\011\375\173\302\200\252\223\154\051\230
-\041\250\273\026\363\251\022\137\164\265\207\230\362\225\046\337
-\064\357\212\123\221\210\135\032\224\243\077\174\042\370\327\210
-\272\246\214\226\250\075\122\064\142\237\000\036\124\125\102\147
-\306\115\106\217\273\024\105\075\012\226\026\216\020\241\227\231
-\325\323\060\205\314\336\264\162\267\274\212\074\030\051\150\375
-\334\161\007\356\044\071\152\372\355\245\254\070\057\371\036\020
-\016\006\161\032\020\114\376\165\176\377\036\127\071\102\312\327
-\341\025\241\126\125\131\033\321\243\257\021\330\116\303\245\053
-\357\220\277\300\354\202\023\133\215\326\162\054\223\116\217\152
-\051\337\205\074\323\015\340\242\030\022\314\125\057\107\267\247
-\233\002\376\101\366\210\114\155\332\251\001\107\203\144\047\142
-\020\202\326\022\173\136\003\037\064\251\311\221\376\257\135\155
-\206\047\267\043\252\165\030\312\040\347\260\017\327\211\016\246
-\147\042\143\364\203\101\053\006\113\273\130\325\321\327\267\271
-\020\143\330\211\112\264\252\335\026\143\365\156\276\140\241\370
-\355\350\326\220\117\032\306\305\240\051\323\247\041\250\365\132
-\074\367\307\111\242\041\232\112\225\122\040\226\162\232\146\313
-\367\322\206\103\174\042\276\226\371\275\001\250\107\335\345\073
-\100\371\165\053\233\053\106\144\206\215\036\364\217\373\007\167
-\320\352\111\242\034\215\122\024\246\012\223
-END
-
-# Trust for Certificate "EBG Elektronik Sertifika Hizmet Saglayicisi"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\214\226\272\353\335\053\007\007\110\356\060\062\146\240\363\230
-\156\174\256\130
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\054\040\046\235\313\032\112\000\205\265\267\132\256\302\001\067
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\200\061\070\060\066\006\003\125\004\003\014\057\105\102
-\107\040\105\154\145\153\164\162\157\156\151\153\040\123\145\162
-\164\151\146\151\153\141\040\110\151\172\155\145\164\040\123\141
-\304\237\154\141\171\304\261\143\304\261\163\304\261\061\067\060
-\065\006\003\125\004\012\014\056\105\102\107\040\102\151\154\151
-\305\237\151\155\040\124\145\153\156\157\154\157\152\151\154\145
-\162\151\040\166\145\040\110\151\172\155\145\164\154\145\162\151
-\040\101\056\305\236\056\061\013\060\011\006\003\125\004\006\023
-\002\124\122
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\114\257\163\102\034\216\164\002
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "certSIGN ROOT CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "certSIGN ROOT CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\073\061\013\060\011\006\003\125\004\006\023\002\122\117\061
-\021\060\017\006\003\125\004\012\023\010\143\145\162\164\123\111
-\107\116\061\031\060\027\006\003\125\004\013\023\020\143\145\162
-\164\123\111\107\116\040\122\117\117\124\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\073\061\013\060\011\006\003\125\004\006\023\002\122\117\061
-\021\060\017\006\003\125\004\012\023\010\143\145\162\164\123\111
-\107\116\061\031\060\027\006\003\125\004\013\023\020\143\145\162
-\164\123\111\107\116\040\122\117\117\124\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\006\040\006\005\026\160\002
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\070\060\202\002\040\240\003\002\001\002\002\006\040
-\006\005\026\160\002\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\060\073\061\013\060\011\006\003\125\004\006\023
-\002\122\117\061\021\060\017\006\003\125\004\012\023\010\143\145
-\162\164\123\111\107\116\061\031\060\027\006\003\125\004\013\023
-\020\143\145\162\164\123\111\107\116\040\122\117\117\124\040\103
-\101\060\036\027\015\060\066\060\067\060\064\061\067\062\060\060
-\064\132\027\015\063\061\060\067\060\064\061\067\062\060\060\064
-\132\060\073\061\013\060\011\006\003\125\004\006\023\002\122\117
-\061\021\060\017\006\003\125\004\012\023\010\143\145\162\164\123
-\111\107\116\061\031\060\027\006\003\125\004\013\023\020\143\145
-\162\164\123\111\107\116\040\122\117\117\124\040\103\101\060\202
-\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
-\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000\267
-\063\271\176\310\045\112\216\265\333\264\050\033\252\127\220\350
-\321\042\323\144\272\323\223\350\324\254\206\141\100\152\140\127
-\150\124\204\115\274\152\124\002\005\377\337\233\232\052\256\135
-\007\217\112\303\050\177\357\373\053\372\171\361\307\255\360\020
-\123\044\220\213\146\311\250\210\253\257\132\243\000\351\276\272
-\106\356\133\163\173\054\027\202\201\136\142\054\241\002\145\263
-\275\305\053\000\176\304\374\003\063\127\015\355\342\372\316\135
-\105\326\070\315\065\266\262\301\320\234\201\112\252\344\262\001
-\134\035\217\137\231\304\261\255\333\210\041\353\220\010\202\200
-\363\060\243\103\346\220\202\256\125\050\111\355\133\327\251\020
-\070\016\376\217\114\133\233\106\352\101\365\260\010\164\303\320
-\210\063\266\174\327\164\337\334\204\321\103\016\165\071\241\045
-\100\050\352\170\313\016\054\056\071\235\214\213\156\026\034\057
-\046\202\020\342\343\145\224\012\004\300\136\367\135\133\370\020
-\342\320\272\172\113\373\336\067\000\000\032\133\050\343\322\234
-\163\076\062\207\230\241\311\121\057\327\336\254\063\263\117\002
-\003\001\000\001\243\102\060\100\060\017\006\003\125\035\023\001
-\001\377\004\005\060\003\001\001\377\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\001\306\060\035\006\003\125\035\016
-\004\026\004\024\340\214\233\333\045\111\263\361\174\206\326\262
-\102\207\013\320\153\240\331\344\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\202\001\001\000\076\322\034\211
-\056\065\374\370\165\335\346\177\145\210\364\162\114\311\054\327
-\062\116\363\335\031\171\107\275\216\073\133\223\017\120\111\044
-\023\153\024\006\162\357\011\323\241\241\343\100\204\311\347\030
-\062\164\074\110\156\017\237\113\324\367\036\323\223\206\144\124
-\227\143\162\120\325\125\317\372\040\223\002\242\233\303\043\223
-\116\026\125\166\240\160\171\155\315\041\037\317\057\055\274\031
-\343\210\061\370\131\032\201\011\310\227\246\164\307\140\304\133
-\314\127\216\262\165\375\033\002\011\333\131\157\162\223\151\367
-\061\101\326\210\070\277\207\262\275\026\171\371\252\344\276\210
-\045\335\141\047\043\034\265\061\007\004\066\264\032\220\275\240
-\164\161\120\211\155\274\024\343\017\206\256\361\253\076\307\240
-\011\314\243\110\321\340\333\144\347\222\265\317\257\162\103\160
-\213\371\303\204\074\023\252\176\222\233\127\123\223\372\160\302
-\221\016\061\371\233\147\135\351\226\070\136\137\263\163\116\210
-\025\147\336\236\166\020\142\040\276\125\151\225\103\000\071\115
-\366\356\260\132\116\111\104\124\130\137\102\203
-END
-
-# Trust for Certificate "certSIGN ROOT CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "certSIGN ROOT CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\372\267\356\066\227\046\142\373\055\260\052\366\277\003\375\350
-\174\113\057\233
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\030\230\300\326\351\072\374\371\260\365\014\367\113\001\104\027
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\073\061\013\060\011\006\003\125\004\006\023\002\122\117\061
-\021\060\017\006\003\125\004\012\023\010\143\145\162\164\123\111
-\107\116\061\031\060\027\006\003\125\004\013\023\020\143\145\162
-\164\123\111\107\116\040\122\117\117\124\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\006\040\006\005\026\160\002
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "CNNIC ROOT"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "CNNIC ROOT"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\062\061\013\060\011\006\003\125\004\006\023\002\103\116\061
-\016\060\014\006\003\125\004\012\023\005\103\116\116\111\103\061
-\023\060\021\006\003\125\004\003\023\012\103\116\116\111\103\040
-\122\117\117\124
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\062\061\013\060\011\006\003\125\004\006\023\002\103\116\061
-\016\060\014\006\003\125\004\012\023\005\103\116\116\111\103\061
-\023\060\021\006\003\125\004\003\023\012\103\116\116\111\103\040
-\122\117\117\124
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\111\063\000\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\125\060\202\002\075\240\003\002\001\002\002\004\111
-\063\000\001\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\062\061\013\060\011\006\003\125\004\006\023\002\103
-\116\061\016\060\014\006\003\125\004\012\023\005\103\116\116\111
-\103\061\023\060\021\006\003\125\004\003\023\012\103\116\116\111
-\103\040\122\117\117\124\060\036\027\015\060\067\060\064\061\066
-\060\067\060\071\061\064\132\027\015\062\067\060\064\061\066\060
-\067\060\071\061\064\132\060\062\061\013\060\011\006\003\125\004
-\006\023\002\103\116\061\016\060\014\006\003\125\004\012\023\005
-\103\116\116\111\103\061\023\060\021\006\003\125\004\003\023\012
-\103\116\116\111\103\040\122\117\117\124\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\323\065\367\077\163
-\167\255\350\133\163\027\302\321\157\355\125\274\156\352\350\244
-\171\262\154\303\243\357\341\237\261\073\110\205\365\232\134\041
-\042\020\054\305\202\316\332\343\232\156\067\341\207\054\334\271
-\014\132\272\210\125\337\375\252\333\037\061\352\001\361\337\071
-\001\301\023\375\110\122\041\304\125\337\332\330\263\124\166\272
-\164\261\267\175\327\300\350\366\131\305\115\310\275\255\037\024
-\332\337\130\104\045\062\031\052\307\176\176\216\256\070\260\060
-\173\107\162\011\061\360\060\333\303\033\166\051\273\151\166\116
-\127\371\033\144\242\223\126\267\157\231\156\333\012\004\234\021
-\343\200\037\313\143\224\020\012\251\341\144\202\061\371\214\047
-\355\246\231\000\366\160\223\030\370\241\064\206\243\335\172\302
-\030\171\366\172\145\065\317\220\353\275\063\223\237\123\253\163
-\073\346\233\064\040\057\035\357\251\035\143\032\240\200\333\003
-\057\371\046\032\206\322\215\273\251\276\122\072\207\147\110\015
-\277\264\240\330\046\276\043\137\163\067\177\046\346\222\004\243
-\177\317\040\247\267\363\072\312\313\231\313\002\003\001\000\001
-\243\163\060\161\060\021\006\011\140\206\110\001\206\370\102\001
-\001\004\004\003\002\000\007\060\037\006\003\125\035\043\004\030
-\060\026\200\024\145\362\061\255\052\367\367\335\122\226\012\307
-\002\301\016\357\246\325\073\021\060\017\006\003\125\035\023\001
-\001\377\004\005\060\003\001\001\377\060\013\006\003\125\035\017
-\004\004\003\002\001\376\060\035\006\003\125\035\016\004\026\004
-\024\145\362\061\255\052\367\367\335\122\226\012\307\002\301\016
-\357\246\325\073\021\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\003\202\001\001\000\113\065\356\314\344\256\277
-\303\156\255\237\225\073\113\077\133\036\337\127\051\242\131\312
-\070\342\271\032\377\236\346\156\062\335\036\256\352\065\267\365
-\223\221\116\332\102\341\303\027\140\120\362\321\134\046\271\202
-\267\352\155\344\234\204\347\003\171\027\257\230\075\224\333\307
-\272\000\347\270\277\001\127\301\167\105\062\014\073\361\264\034
-\010\260\375\121\240\241\335\232\035\023\066\232\155\267\307\074
-\271\341\305\331\027\372\203\325\075\025\240\074\273\036\013\342
-\310\220\077\250\206\014\374\371\213\136\205\313\117\133\113\142
-\021\107\305\105\174\005\057\101\261\236\020\151\033\231\226\340
-\125\171\373\116\206\231\270\224\332\206\070\152\223\243\347\313
-\156\345\337\352\041\125\211\234\175\175\177\230\365\000\211\356
-\343\204\300\134\226\265\305\106\352\106\340\205\125\266\033\311
-\022\326\301\315\315\200\363\002\001\074\310\151\313\105\110\143
-\330\224\320\354\205\016\073\116\021\145\364\202\214\246\075\256
-\056\042\224\011\310\134\352\074\201\135\026\052\003\227\026\125
-\011\333\212\101\202\236\146\233\021
-END
-
-# Trust for Certificate "CNNIC ROOT"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "CNNIC ROOT"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\213\257\114\233\035\360\052\222\367\332\022\216\271\033\254\364
-\230\140\113\157
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\041\274\202\253\111\304\023\073\113\262\053\134\153\220\234\031
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\062\061\013\060\011\006\003\125\004\006\023\002\103\116\061
-\016\060\014\006\003\125\004\012\023\005\103\116\116\111\103\061
-\023\060\021\006\003\125\004\003\023\012\103\116\116\111\103\040
-\122\117\117\124
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\111\063\000\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "ApplicationCA - Japanese Government"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ApplicationCA - Japanese Government"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\034\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145
-\163\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060
-\024\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164
-\151\157\156\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\034\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145
-\163\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060
-\024\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164
-\151\157\156\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\061
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\240\060\202\002\210\240\003\002\001\002\002\001\061
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061\034
-\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145\163
-\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060\024
-\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164\151
-\157\156\103\101\060\036\027\015\060\067\061\062\061\062\061\065
-\060\060\060\060\132\027\015\061\067\061\062\061\062\061\065\060
-\060\060\060\132\060\103\061\013\060\011\006\003\125\004\006\023
-\002\112\120\061\034\060\032\006\003\125\004\012\023\023\112\141
-\160\141\156\145\163\145\040\107\157\166\145\162\156\155\145\156
-\164\061\026\060\024\006\003\125\004\013\023\015\101\160\160\154
-\151\143\141\164\151\157\156\103\101\060\202\001\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017
-\000\060\202\001\012\002\202\001\001\000\247\155\340\164\116\207
-\217\245\006\336\150\242\333\206\231\113\144\015\161\360\012\005
-\233\216\252\341\314\056\322\152\073\301\172\264\227\141\215\212
-\276\306\232\234\006\264\206\121\344\067\016\164\170\176\137\212
-\177\224\244\327\107\010\375\120\132\126\344\150\254\050\163\240
-\173\351\177\030\222\100\117\055\235\365\256\104\110\163\066\006
-\236\144\054\073\064\043\333\134\046\344\161\171\217\324\156\171
-\042\271\223\301\312\315\301\126\355\210\152\327\240\071\041\004
-\127\054\242\365\274\107\101\117\136\064\042\225\265\037\051\155
-\136\112\363\115\162\276\101\126\040\207\374\351\120\107\327\060
-\024\356\134\214\125\272\131\215\207\374\043\336\223\320\004\214
-\375\357\155\275\320\172\311\245\072\152\162\063\306\112\015\005
-\027\052\055\173\261\247\330\326\360\276\364\077\352\016\050\155
-\101\141\043\166\170\303\270\145\244\363\132\256\314\302\252\331
-\347\130\336\266\176\235\205\156\237\052\012\157\237\003\051\060
-\227\050\035\274\267\317\124\051\116\121\061\371\047\266\050\046
-\376\242\143\346\101\026\360\063\230\107\002\003\001\000\001\243
-\201\236\060\201\233\060\035\006\003\125\035\016\004\026\004\024
-\124\132\313\046\077\161\314\224\106\015\226\123\352\153\110\320
-\223\376\102\165\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\006\060\131\006\003\125\035\021\004\122\060\120\244
-\116\060\114\061\013\060\011\006\003\125\004\006\023\002\112\120
-\061\030\060\026\006\003\125\004\012\014\017\346\227\245\346\234
-\254\345\233\275\346\224\277\345\272\234\061\043\060\041\006\003
-\125\004\013\014\032\343\202\242\343\203\227\343\203\252\343\202
-\261\343\203\274\343\202\267\343\203\247\343\203\263\103\101\060
-\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\001\001\000\071\152\104\166\167\070\072\354\243\147\106\017
-\371\213\006\250\373\152\220\061\316\176\354\332\321\211\174\172
-\353\056\014\275\231\062\347\260\044\326\303\377\365\262\210\011
-\207\054\343\124\341\243\246\262\010\013\300\205\250\310\322\234
-\161\366\035\237\140\374\070\063\023\341\236\334\013\137\332\026
-\120\051\173\057\160\221\017\231\272\064\064\215\225\164\305\176
-\170\251\146\135\275\312\041\167\102\020\254\146\046\075\336\221
-\253\375\025\360\157\355\154\137\020\370\363\026\366\003\212\217
-\247\022\021\014\313\375\077\171\301\234\375\142\356\243\317\124
-\014\321\053\137\027\076\343\076\277\300\053\076\011\233\376\210
-\246\176\264\222\027\374\043\224\201\275\156\247\305\214\302\353
-\021\105\333\370\101\311\226\166\352\160\137\171\022\153\344\243
-\007\132\005\357\047\111\317\041\237\212\114\011\160\146\251\046
-\301\053\021\116\063\322\016\374\326\154\322\016\062\144\150\377
-\255\005\170\137\003\035\250\343\220\254\044\340\017\100\247\113
-\256\213\050\267\202\312\030\007\346\267\133\164\351\040\031\177
-\262\033\211\124
-END
-
-# Trust for Certificate "ApplicationCA - Japanese Government"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ApplicationCA - Japanese Government"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\177\212\260\317\320\121\207\152\146\363\066\017\107\310\215\214
-\323\065\374\164
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\176\043\116\133\247\245\264\045\351\000\007\164\021\142\256\326
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\034\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145
-\163\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060
-\024\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164
-\151\157\156\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\061
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GeoTrust Primary Certification Authority - G3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Primary Certification Authority - G3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162
-\165\163\164\040\111\156\143\056\061\071\060\067\006\003\125\004
-\013\023\060\050\143\051\040\062\060\060\070\040\107\145\157\124
-\162\165\163\164\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\066\060\064\006\003\125\004\003\023\055\107\145
-\157\124\162\165\163\164\040\120\162\151\155\141\162\171\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162
-\165\163\164\040\111\156\143\056\061\071\060\067\006\003\125\004
-\013\023\060\050\143\051\040\062\060\060\070\040\107\145\157\124
-\162\165\163\164\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\066\060\064\006\003\125\004\003\023\055\107\145
-\157\124\162\165\163\164\040\120\162\151\155\141\162\171\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\025\254\156\224\031\262\171\113\101\366\047\251\303\030
-\017\037
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\376\060\202\002\346\240\003\002\001\002\002\020\025
-\254\156\224\031\262\171\113\101\366\047\251\303\030\017\037\060
-\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\201
-\230\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026
-\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163
-\164\040\111\156\143\056\061\071\060\067\006\003\125\004\013\023
-\060\050\143\051\040\062\060\060\070\040\107\145\157\124\162\165
-\163\164\040\111\156\143\056\040\055\040\106\157\162\040\141\165
-\164\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154
-\171\061\066\060\064\006\003\125\004\003\023\055\107\145\157\124
-\162\165\163\164\040\120\162\151\155\141\162\171\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\040\055\040\107\063\060\036\027\015\060\070\060
-\064\060\062\060\060\060\060\060\060\132\027\015\063\067\061\062
-\060\061\062\063\065\071\065\071\132\060\201\230\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\026\060\024\006\003\125
-\004\012\023\015\107\145\157\124\162\165\163\164\040\111\156\143
-\056\061\071\060\067\006\003\125\004\013\023\060\050\143\051\040
-\062\060\060\070\040\107\145\157\124\162\165\163\164\040\111\156
-\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151
-\172\145\144\040\165\163\145\040\157\156\154\171\061\066\060\064
-\006\003\125\004\003\023\055\107\145\157\124\162\165\163\164\040
-\120\162\151\155\141\162\171\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\040
-\055\040\107\063\060\202\001\042\060\015\006\011\052\206\110\206
-\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012
-\002\202\001\001\000\334\342\136\142\130\035\063\127\071\062\063
-\372\353\313\207\214\247\324\112\335\006\210\352\144\216\061\230
-\245\070\220\036\230\317\056\143\053\360\106\274\104\262\211\241
-\300\050\014\111\160\041\225\237\144\300\246\223\022\002\145\046
-\206\306\245\211\360\372\327\204\240\160\257\117\032\227\077\006
-\104\325\311\353\162\020\175\344\061\050\373\034\141\346\050\007
-\104\163\222\042\151\247\003\210\154\235\143\310\122\332\230\047
-\347\010\114\160\076\264\311\022\301\305\147\203\135\063\363\003
-\021\354\152\320\123\342\321\272\066\140\224\200\273\141\143\154
-\133\027\176\337\100\224\036\253\015\302\041\050\160\210\377\326
-\046\154\154\140\004\045\116\125\176\175\357\277\224\110\336\267
-\035\335\160\215\005\137\210\245\233\362\302\356\352\321\100\101
-\155\142\070\035\126\006\305\003\107\121\040\031\374\173\020\013
-\016\142\256\166\125\277\137\167\276\076\111\001\123\075\230\045
-\003\166\044\132\035\264\333\211\352\171\345\266\263\073\077\272
-\114\050\101\177\006\254\152\216\301\320\366\005\035\175\346\102
-\206\343\245\325\107\002\003\001\000\001\243\102\060\100\060\017
-\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
-\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060
-\035\006\003\125\035\016\004\026\004\024\304\171\312\216\241\116
-\003\035\034\334\153\333\061\133\224\076\077\060\177\055\060\015
-\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202\001
-\001\000\055\305\023\317\126\200\173\172\170\275\237\256\054\231
-\347\357\332\337\224\136\011\151\247\347\156\150\214\275\162\276
-\107\251\016\227\022\270\112\361\144\323\071\337\045\064\324\301
-\315\116\201\360\017\004\304\044\263\064\226\306\246\252\060\337
-\150\141\163\327\371\216\205\211\357\016\136\225\050\112\052\047
-\217\020\216\056\174\206\304\002\236\332\014\167\145\016\104\015
-\222\375\375\263\026\066\372\021\015\035\214\016\007\211\152\051
-\126\367\162\364\335\025\234\167\065\146\127\253\023\123\330\216
-\301\100\305\327\023\026\132\162\307\267\151\001\304\172\261\203
-\001\150\175\215\101\241\224\030\301\045\134\374\360\376\203\002
-\207\174\015\015\317\056\010\134\112\100\015\076\354\201\141\346
-\044\333\312\340\016\055\007\262\076\126\334\215\365\101\205\007
-\110\233\014\013\313\111\077\175\354\267\375\313\215\147\211\032
-\253\355\273\036\243\000\010\010\027\052\202\134\061\135\106\212
-\055\017\206\233\164\331\105\373\324\100\261\172\252\150\055\206
-\262\231\042\341\301\053\307\234\370\363\137\250\202\022\353\031
-\021\055
-END
-
-# Trust for Certificate "GeoTrust Primary Certification Authority - G3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Primary Certification Authority - G3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\003\236\355\270\013\347\240\074\151\123\211\073\040\322\331\062
-\072\114\052\375
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\265\350\064\066\311\020\104\130\110\160\155\056\203\324\270\005
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162
-\165\163\164\040\111\156\143\056\061\071\060\067\006\003\125\004
-\013\023\060\050\143\051\040\062\060\060\070\040\107\145\157\124
-\162\165\163\164\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\066\060\064\006\003\125\004\003\023\055\107\145
-\157\124\162\165\163\164\040\120\162\151\155\141\162\171\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\025\254\156\224\031\262\171\113\101\366\047\251\303\030
-\017\037
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "thawte Primary Root CA - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "thawte Primary Root CA - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\204\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164
-\145\054\040\111\156\143\056\061\070\060\066\006\003\125\004\013
-\023\057\050\143\051\040\062\060\060\067\040\164\150\141\167\164
-\145\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165
-\164\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154
-\171\061\044\060\042\006\003\125\004\003\023\033\164\150\141\167
-\164\145\040\120\162\151\155\141\162\171\040\122\157\157\164\040
-\103\101\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\204\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164
-\145\054\040\111\156\143\056\061\070\060\066\006\003\125\004\013
-\023\057\050\143\051\040\062\060\060\067\040\164\150\141\167\164
-\145\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165
-\164\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154
-\171\061\044\060\042\006\003\125\004\003\023\033\164\150\141\167
-\164\145\040\120\162\151\155\141\162\171\040\122\157\157\164\040
-\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\065\374\046\134\331\204\117\311\075\046\075\127\233\256
-\327\126
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\210\060\202\002\015\240\003\002\001\002\002\020\065
-\374\046\134\331\204\117\311\075\046\075\127\233\256\327\126\060
-\012\006\010\052\206\110\316\075\004\003\003\060\201\204\061\013
-\060\011\006\003\125\004\006\023\002\125\123\061\025\060\023\006
-\003\125\004\012\023\014\164\150\141\167\164\145\054\040\111\156
-\143\056\061\070\060\066\006\003\125\004\013\023\057\050\143\051
-\040\062\060\060\067\040\164\150\141\167\164\145\054\040\111\156
-\143\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151
-\172\145\144\040\165\163\145\040\157\156\154\171\061\044\060\042
-\006\003\125\004\003\023\033\164\150\141\167\164\145\040\120\162
-\151\155\141\162\171\040\122\157\157\164\040\103\101\040\055\040
-\107\062\060\036\027\015\060\067\061\061\060\065\060\060\060\060
-\060\060\132\027\015\063\070\060\061\061\070\062\063\065\071\065
-\071\132\060\201\204\061\013\060\011\006\003\125\004\006\023\002
-\125\123\061\025\060\023\006\003\125\004\012\023\014\164\150\141
-\167\164\145\054\040\111\156\143\056\061\070\060\066\006\003\125
-\004\013\023\057\050\143\051\040\062\060\060\067\040\164\150\141
-\167\164\145\054\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\044\060\042\006\003\125\004\003\023\033\164\150
-\141\167\164\145\040\120\162\151\155\141\162\171\040\122\157\157
-\164\040\103\101\040\055\040\107\062\060\166\060\020\006\007\052
-\206\110\316\075\002\001\006\005\053\201\004\000\042\003\142\000
-\004\242\325\234\202\173\225\235\361\122\170\207\376\212\026\277
-\005\346\337\243\002\117\015\007\306\000\121\272\014\002\122\055
-\042\244\102\071\304\376\217\352\311\301\276\324\115\377\237\172
-\236\342\261\174\232\255\247\206\011\163\207\321\347\232\343\172
-\245\252\156\373\272\263\160\300\147\210\242\065\324\243\232\261
-\375\255\302\357\061\372\250\271\363\373\010\306\221\321\373\051
-\225\243\102\060\100\060\017\006\003\125\035\023\001\001\377\004
-\005\060\003\001\001\377\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\035\006\003\125\035\016\004\026\004
-\024\232\330\000\060\000\347\153\177\205\030\356\213\266\316\212
-\014\370\021\341\273\060\012\006\010\052\206\110\316\075\004\003
-\003\003\151\000\060\146\002\061\000\335\370\340\127\107\133\247
-\346\012\303\275\365\200\212\227\065\015\033\211\074\124\206\167
-\050\312\241\364\171\336\265\346\070\260\360\145\160\214\177\002
-\124\302\277\377\330\241\076\331\317\002\061\000\304\215\224\374
-\334\123\322\334\235\170\026\037\025\063\043\123\122\343\132\061
-\135\235\312\256\275\023\051\104\015\047\133\250\347\150\234\022
-\367\130\077\056\162\002\127\243\217\241\024\056
-END
-
-# Trust for Certificate "thawte Primary Root CA - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "thawte Primary Root CA - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\252\333\274\042\043\217\304\001\241\047\273\070\335\364\035\333
-\010\236\360\022
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\164\235\352\140\044\304\375\042\123\076\314\072\162\331\051\117
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\204\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164
-\145\054\040\111\156\143\056\061\070\060\066\006\003\125\004\013
-\023\057\050\143\051\040\062\060\060\067\040\164\150\141\167\164
-\145\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165
-\164\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154
-\171\061\044\060\042\006\003\125\004\003\023\033\164\150\141\167
-\164\145\040\120\162\151\155\141\162\171\040\122\157\157\164\040
-\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\065\374\046\134\331\204\117\311\075\046\075\127\233\256
-\327\126
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "thawte Primary Root CA - G3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "thawte Primary Root CA - G3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164
-\145\054\040\111\156\143\056\061\050\060\046\006\003\125\004\013
-\023\037\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\123\145\162\166\151\143\145\163\040\104\151\166\151\163\151\157
-\156\061\070\060\066\006\003\125\004\013\023\057\050\143\051\040
-\062\060\060\070\040\164\150\141\167\164\145\054\040\111\156\143
-\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151\172
-\145\144\040\165\163\145\040\157\156\154\171\061\044\060\042\006
-\003\125\004\003\023\033\164\150\141\167\164\145\040\120\162\151
-\155\141\162\171\040\122\157\157\164\040\103\101\040\055\040\107
-\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164
-\145\054\040\111\156\143\056\061\050\060\046\006\003\125\004\013
-\023\037\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\123\145\162\166\151\143\145\163\040\104\151\166\151\163\151\157
-\156\061\070\060\066\006\003\125\004\013\023\057\050\143\051\040
-\062\060\060\070\040\164\150\141\167\164\145\054\040\111\156\143
-\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151\172
-\145\144\040\165\163\145\040\157\156\154\171\061\044\060\042\006
-\003\125\004\003\023\033\164\150\141\167\164\145\040\120\162\151
-\155\141\162\171\040\122\157\157\164\040\103\101\040\055\040\107
-\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\140\001\227\267\106\247\352\264\264\232\326\113\057\367
-\220\373
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\052\060\202\003\022\240\003\002\001\002\002\020\140
-\001\227\267\106\247\352\264\264\232\326\113\057\367\220\373\060
-\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\201
-\256\061\013\060\011\006\003\125\004\006\023\002\125\123\061\025
-\060\023\006\003\125\004\012\023\014\164\150\141\167\164\145\054
-\040\111\156\143\056\061\050\060\046\006\003\125\004\013\023\037
-\103\145\162\164\151\146\151\143\141\164\151\157\156\040\123\145
-\162\166\151\143\145\163\040\104\151\166\151\163\151\157\156\061
-\070\060\066\006\003\125\004\013\023\057\050\143\051\040\062\060
-\060\070\040\164\150\141\167\164\145\054\040\111\156\143\056\040
-\055\040\106\157\162\040\141\165\164\150\157\162\151\172\145\144
-\040\165\163\145\040\157\156\154\171\061\044\060\042\006\003\125
-\004\003\023\033\164\150\141\167\164\145\040\120\162\151\155\141
-\162\171\040\122\157\157\164\040\103\101\040\055\040\107\063\060
-\036\027\015\060\070\060\064\060\062\060\060\060\060\060\060\132
-\027\015\063\067\061\062\060\061\062\063\065\071\065\071\132\060
-\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164\145
-\054\040\111\156\143\056\061\050\060\046\006\003\125\004\013\023
-\037\103\145\162\164\151\146\151\143\141\164\151\157\156\040\123
-\145\162\166\151\143\145\163\040\104\151\166\151\163\151\157\156
-\061\070\060\066\006\003\125\004\013\023\057\050\143\051\040\062
-\060\060\070\040\164\150\141\167\164\145\054\040\111\156\143\056
-\040\055\040\106\157\162\040\141\165\164\150\157\162\151\172\145
-\144\040\165\163\145\040\157\156\154\171\061\044\060\042\006\003
-\125\004\003\023\033\164\150\141\167\164\145\040\120\162\151\155
-\141\162\171\040\122\157\157\164\040\103\101\040\055\040\107\063
-\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001
-\000\262\277\047\054\373\333\330\133\335\170\173\033\236\167\146
-\201\313\076\274\174\256\363\246\047\232\064\243\150\061\161\070
-\063\142\344\363\161\146\171\261\251\145\243\245\213\325\217\140
-\055\077\102\314\252\153\062\300\043\313\054\101\335\344\337\374
-\141\234\342\163\262\042\225\021\103\030\137\304\266\037\127\154
-\012\005\130\042\310\066\114\072\174\245\321\317\206\257\210\247
-\104\002\023\164\161\163\012\102\131\002\370\033\024\153\102\337
-\157\137\272\153\202\242\235\133\347\112\275\036\001\162\333\113
-\164\350\073\177\177\175\037\004\264\046\233\340\264\132\254\107
-\075\125\270\327\260\046\122\050\001\061\100\146\330\331\044\275
-\366\052\330\354\041\111\134\233\366\172\351\177\125\065\176\226
-\153\215\223\223\047\313\222\273\352\254\100\300\237\302\370\200
-\317\135\364\132\334\316\164\206\246\076\154\013\123\312\275\222
-\316\031\006\162\346\014\134\070\151\307\004\326\274\154\316\133
-\366\367\150\234\334\045\025\110\210\241\351\251\370\230\234\340
-\363\325\061\050\141\021\154\147\226\215\071\231\313\302\105\044
-\071\002\003\001\000\001\243\102\060\100\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003\125
-\035\016\004\026\004\024\255\154\252\224\140\234\355\344\377\372
-\076\012\164\053\143\003\367\266\131\277\060\015\006\011\052\206
-\110\206\367\015\001\001\013\005\000\003\202\001\001\000\032\100
-\330\225\145\254\011\222\211\306\071\364\020\345\251\016\146\123
-\135\170\336\372\044\221\273\347\104\121\337\306\026\064\012\357
-\152\104\121\352\053\007\212\003\172\303\353\077\012\054\122\026
-\240\053\103\271\045\220\077\160\251\063\045\155\105\032\050\073
-\047\317\252\303\051\102\033\337\073\114\300\063\064\133\101\210
-\277\153\053\145\257\050\357\262\365\303\252\146\316\173\126\356
-\267\310\313\147\301\311\234\032\030\270\304\303\111\003\361\140
-\016\120\315\106\305\363\167\171\367\266\025\340\070\333\307\057
-\050\240\014\077\167\046\164\331\045\022\332\061\332\032\036\334
-\051\101\221\042\074\151\247\273\002\362\266\134\047\003\211\364
-\006\352\233\344\162\202\343\241\011\301\351\000\031\323\076\324
-\160\153\272\161\246\252\130\256\364\273\351\154\266\357\207\314
-\233\273\377\071\346\126\141\323\012\247\304\134\114\140\173\005
-\167\046\172\277\330\007\122\054\142\367\160\143\331\071\274\157
-\034\302\171\334\166\051\257\316\305\054\144\004\136\210\066\156
-\061\324\100\032\142\064\066\077\065\001\256\254\143\240
-END
-
-# Trust for Certificate "thawte Primary Root CA - G3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "thawte Primary Root CA - G3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\361\213\123\215\033\351\003\266\246\360\126\103\133\027\025\211
-\312\363\153\362
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\373\033\135\103\212\224\315\104\306\166\362\103\113\107\347\061
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\025\060\023\006\003\125\004\012\023\014\164\150\141\167\164
-\145\054\040\111\156\143\056\061\050\060\046\006\003\125\004\013
-\023\037\103\145\162\164\151\146\151\143\141\164\151\157\156\040
-\123\145\162\166\151\143\145\163\040\104\151\166\151\163\151\157
-\156\061\070\060\066\006\003\125\004\013\023\057\050\143\051\040
-\062\060\060\070\040\164\150\141\167\164\145\054\040\111\156\143
-\056\040\055\040\106\157\162\040\141\165\164\150\157\162\151\172
-\145\144\040\165\163\145\040\157\156\154\171\061\044\060\042\006
-\003\125\004\003\023\033\164\150\141\167\164\145\040\120\162\151
-\155\141\162\171\040\122\157\157\164\040\103\101\040\055\040\107
-\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\140\001\227\267\106\247\352\264\264\232\326\113\057\367
-\220\373
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GeoTrust Primary Certification Authority - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Primary Certification Authority - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162
-\165\163\164\040\111\156\143\056\061\071\060\067\006\003\125\004
-\013\023\060\050\143\051\040\062\060\060\067\040\107\145\157\124
-\162\165\163\164\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\066\060\064\006\003\125\004\003\023\055\107\145
-\157\124\162\165\163\164\040\120\162\151\155\141\162\171\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162
-\165\163\164\040\111\156\143\056\061\071\060\067\006\003\125\004
-\013\023\060\050\143\051\040\062\060\060\067\040\107\145\157\124
-\162\165\163\164\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\066\060\064\006\003\125\004\003\023\055\107\145
-\157\124\162\165\163\164\040\120\162\151\155\141\162\171\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\074\262\364\110\012\000\342\376\353\044\073\136\140\076
-\303\153
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\256\060\202\002\065\240\003\002\001\002\002\020\074
-\262\364\110\012\000\342\376\353\044\073\136\140\076\303\153\060
-\012\006\010\052\206\110\316\075\004\003\003\060\201\230\061\013
-\060\011\006\003\125\004\006\023\002\125\123\061\026\060\024\006
-\003\125\004\012\023\015\107\145\157\124\162\165\163\164\040\111
-\156\143\056\061\071\060\067\006\003\125\004\013\023\060\050\143
-\051\040\062\060\060\067\040\107\145\157\124\162\165\163\164\040
-\111\156\143\056\040\055\040\106\157\162\040\141\165\164\150\157
-\162\151\172\145\144\040\165\163\145\040\157\156\154\171\061\066
-\060\064\006\003\125\004\003\023\055\107\145\157\124\162\165\163
-\164\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\040\055\040\107\062\060\036\027\015\060\067\061\061\060\065
-\060\060\060\060\060\060\132\027\015\063\070\060\061\061\070\062
-\063\065\071\065\071\132\060\201\230\061\013\060\011\006\003\125
-\004\006\023\002\125\123\061\026\060\024\006\003\125\004\012\023
-\015\107\145\157\124\162\165\163\164\040\111\156\143\056\061\071
-\060\067\006\003\125\004\013\023\060\050\143\051\040\062\060\060
-\067\040\107\145\157\124\162\165\163\164\040\111\156\143\056\040
-\055\040\106\157\162\040\141\165\164\150\157\162\151\172\145\144
-\040\165\163\145\040\157\156\154\171\061\066\060\064\006\003\125
-\004\003\023\055\107\145\157\124\162\165\163\164\040\120\162\151
-\155\141\162\171\040\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\101\165\164\150\157\162\151\164\171\040\055\040\107
-\062\060\166\060\020\006\007\052\206\110\316\075\002\001\006\005
-\053\201\004\000\042\003\142\000\004\025\261\350\375\003\025\103
-\345\254\353\207\067\021\142\357\322\203\066\122\175\105\127\013
-\112\215\173\124\073\072\156\137\025\002\300\120\246\317\045\057
-\175\312\110\270\307\120\143\034\052\041\010\174\232\066\330\013
-\376\321\046\305\130\061\060\050\045\363\135\135\243\270\266\245
-\264\222\355\154\054\237\353\335\103\211\242\074\113\110\221\035
-\120\354\046\337\326\140\056\275\041\243\102\060\100\060\017\006
-\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016
-\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\035
-\006\003\125\035\016\004\026\004\024\025\137\065\127\121\125\373
-\045\262\255\003\151\374\001\243\372\276\021\125\325\060\012\006
-\010\052\206\110\316\075\004\003\003\003\147\000\060\144\002\060
-\144\226\131\246\350\011\336\213\272\372\132\210\210\360\037\221
-\323\106\250\362\112\114\002\143\373\154\137\070\333\056\101\223
-\251\016\346\235\334\061\034\262\240\247\030\034\171\341\307\066
-\002\060\072\126\257\232\164\154\366\373\203\340\063\323\010\137
-\241\234\302\133\237\106\326\266\313\221\006\143\242\006\347\063
-\254\076\250\201\022\320\313\272\320\222\013\266\236\226\252\004
-\017\212
-END
-
-# Trust for Certificate "GeoTrust Primary Certification Authority - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GeoTrust Primary Certification Authority - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\215\027\204\325\067\363\003\175\354\160\376\127\213\121\232\231
-\346\020\327\260
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\001\136\330\153\275\157\075\216\241\061\370\022\340\230\163\152
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162
-\165\163\164\040\111\156\143\056\061\071\060\067\006\003\125\004
-\013\023\060\050\143\051\040\062\060\060\067\040\107\145\157\124
-\162\165\163\164\040\111\156\143\056\040\055\040\106\157\162\040
-\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040\157
-\156\154\171\061\066\060\064\006\003\125\004\003\023\055\107\145
-\157\124\162\165\163\164\040\120\162\151\155\141\162\171\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\074\262\364\110\012\000\342\376\353\044\073\136\140\076
-\303\153
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "VeriSign Universal Root Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "VeriSign Universal Root Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\275\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\062\060\060\070\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\070\060\066\006\003\125\004\003\023
-\057\126\145\162\151\123\151\147\156\040\125\156\151\166\145\162
-\163\141\154\040\122\157\157\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\275\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\062\060\060\070\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\070\060\066\006\003\125\004\003\023
-\057\126\145\162\151\123\151\147\156\040\125\156\151\166\145\162
-\163\141\154\040\122\157\157\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\100\032\304\144\041\263\023\041\003\016\273\344\022\032
-\305\035
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\271\060\202\003\241\240\003\002\001\002\002\020\100
-\032\304\144\041\263\023\041\003\016\273\344\022\032\305\035\060
-\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\201
-\275\061\013\060\011\006\003\125\004\006\023\002\125\123\061\027
-\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151\147
-\156\054\040\111\156\143\056\061\037\060\035\006\003\125\004\013
-\023\026\126\145\162\151\123\151\147\156\040\124\162\165\163\164
-\040\116\145\164\167\157\162\153\061\072\060\070\006\003\125\004
-\013\023\061\050\143\051\040\062\060\060\070\040\126\145\162\151
-\123\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162
-\040\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040
-\157\156\154\171\061\070\060\066\006\003\125\004\003\023\057\126
-\145\162\151\123\151\147\156\040\125\156\151\166\145\162\163\141
-\154\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141
-\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\036
-\027\015\060\070\060\064\060\062\060\060\060\060\060\060\132\027
-\015\063\067\061\062\060\061\062\063\065\071\065\071\132\060\201
-\275\061\013\060\011\006\003\125\004\006\023\002\125\123\061\027
-\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151\147
-\156\054\040\111\156\143\056\061\037\060\035\006\003\125\004\013
-\023\026\126\145\162\151\123\151\147\156\040\124\162\165\163\164
-\040\116\145\164\167\157\162\153\061\072\060\070\006\003\125\004
-\013\023\061\050\143\051\040\062\060\060\070\040\126\145\162\151
-\123\151\147\156\054\040\111\156\143\056\040\055\040\106\157\162
-\040\141\165\164\150\157\162\151\172\145\144\040\165\163\145\040
-\157\156\154\171\061\070\060\066\006\003\125\004\003\023\057\126
-\145\162\151\123\151\147\156\040\125\156\151\166\145\162\163\141
-\154\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141
-\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\202
-\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
-\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000\307
-\141\067\136\261\001\064\333\142\327\025\233\377\130\132\214\043
-\043\326\140\216\221\327\220\230\203\172\346\130\031\070\214\305
-\366\345\144\205\264\242\161\373\355\275\271\332\315\115\000\264
-\310\055\163\245\307\151\161\225\037\071\074\262\104\007\234\350
-\016\372\115\112\304\041\337\051\141\217\062\042\141\202\305\207
-\037\156\214\174\137\026\040\121\104\321\160\117\127\352\343\034
-\343\314\171\356\130\330\016\302\263\105\223\300\054\347\232\027
-\053\173\000\067\172\101\063\170\341\063\342\363\020\032\177\207
-\054\276\366\365\367\102\342\345\277\207\142\211\137\000\113\337
-\305\335\344\165\104\062\101\072\036\161\156\151\313\013\165\106
-\010\321\312\322\053\225\320\317\373\271\100\153\144\214\127\115
-\374\023\021\171\204\355\136\124\366\064\237\010\001\363\020\045
-\006\027\112\332\361\035\172\146\153\230\140\146\244\331\357\322
-\056\202\361\360\357\011\352\104\311\025\152\342\003\156\063\323
-\254\237\125\000\307\366\010\152\224\271\137\334\340\063\361\204
-\140\371\133\047\021\264\374\026\362\273\126\152\200\045\215\002
-\003\001\000\001\243\201\262\060\201\257\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\155\006\010\053
-\006\001\005\005\007\001\014\004\141\060\137\241\135\240\133\060
-\131\060\127\060\125\026\011\151\155\141\147\145\057\147\151\146
-\060\041\060\037\060\007\006\005\053\016\003\002\032\004\024\217
-\345\323\032\206\254\215\216\153\303\317\200\152\324\110\030\054
-\173\031\056\060\045\026\043\150\164\164\160\072\057\057\154\157
-\147\157\056\166\145\162\151\163\151\147\156\056\143\157\155\057
-\166\163\154\157\147\157\056\147\151\146\060\035\006\003\125\035
-\016\004\026\004\024\266\167\372\151\110\107\237\123\022\325\302
-\352\007\062\166\007\321\227\007\031\060\015\006\011\052\206\110
-\206\367\015\001\001\013\005\000\003\202\001\001\000\112\370\370
-\260\003\346\054\147\173\344\224\167\143\314\156\114\371\175\016
-\015\334\310\271\065\271\160\117\143\372\044\372\154\203\214\107
-\235\073\143\363\232\371\166\062\225\221\261\167\274\254\232\276
-\261\344\061\041\306\201\225\126\132\016\261\302\324\261\246\131
-\254\361\143\313\270\114\035\131\220\112\357\220\026\050\037\132
-\256\020\373\201\120\070\014\154\314\361\075\303\365\143\343\263
-\343\041\311\044\071\351\375\025\146\106\364\033\021\320\115\163
-\243\175\106\371\075\355\250\137\142\324\361\077\370\340\164\127
-\053\030\235\201\264\304\050\332\224\227\245\160\353\254\035\276
-\007\021\360\325\333\335\345\214\360\325\062\260\203\346\127\342
-\217\277\276\241\252\277\075\035\265\324\070\352\327\260\134\072
-\117\152\077\217\300\146\154\143\252\351\331\244\026\364\201\321
-\225\024\016\175\315\225\064\331\322\217\160\163\201\173\234\176
-\275\230\141\330\105\207\230\220\305\353\206\060\306\065\277\360
-\377\303\125\210\203\113\357\005\222\006\161\362\270\230\223\267
-\354\315\202\141\361\070\346\117\227\230\052\132\215
-END
-
-# Trust for Certificate "VeriSign Universal Root Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "VeriSign Universal Root Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\066\171\312\065\146\207\162\060\115\060\245\373\207\073\017\247
-\173\267\015\124
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\216\255\265\001\252\115\201\344\214\035\321\341\024\000\225\031
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\275\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\062\060\060\070\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\070\060\066\006\003\125\004\003\023
-\057\126\145\162\151\123\151\147\156\040\125\156\151\166\145\162
-\163\141\154\040\122\157\157\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\100\032\304\144\041\263\023\041\003\016\273\344\022\032
-\305\035
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "VeriSign Class 3 Public Primary Certification Authority - G4"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "VeriSign Class 3 Public Primary Certification Authority - G4"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\062\060\060\067\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\064
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\062\060\060\067\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\064
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\057\200\376\043\214\016\042\017\110\147\022\050\221\207
-\254\263
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\204\060\202\003\012\240\003\002\001\002\002\020\057
-\200\376\043\214\016\042\017\110\147\022\050\221\207\254\263\060
-\012\006\010\052\206\110\316\075\004\003\003\060\201\312\061\013
-\060\011\006\003\125\004\006\023\002\125\123\061\027\060\025\006
-\003\125\004\012\023\016\126\145\162\151\123\151\147\156\054\040
-\111\156\143\056\061\037\060\035\006\003\125\004\013\023\026\126
-\145\162\151\123\151\147\156\040\124\162\165\163\164\040\116\145
-\164\167\157\162\153\061\072\060\070\006\003\125\004\013\023\061
-\050\143\051\040\062\060\060\067\040\126\145\162\151\123\151\147
-\156\054\040\111\156\143\056\040\055\040\106\157\162\040\141\165
-\164\150\157\162\151\172\145\144\040\165\163\145\040\157\156\154
-\171\061\105\060\103\006\003\125\004\003\023\074\126\145\162\151
-\123\151\147\156\040\103\154\141\163\163\040\063\040\120\165\142
-\154\151\143\040\120\162\151\155\141\162\171\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\040\055\040\107\064\060\036\027\015\060\067\061\061
-\060\065\060\060\060\060\060\060\132\027\015\063\070\060\061\061
-\070\062\063\065\071\065\071\132\060\201\312\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125\004
-\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156\143
-\056\061\037\060\035\006\003\125\004\013\023\026\126\145\162\151
-\123\151\147\156\040\124\162\165\163\164\040\116\145\164\167\157
-\162\153\061\072\060\070\006\003\125\004\013\023\061\050\143\051
-\040\062\060\060\067\040\126\145\162\151\123\151\147\156\054\040
-\111\156\143\056\040\055\040\106\157\162\040\141\165\164\150\157
-\162\151\172\145\144\040\165\163\145\040\157\156\154\171\061\105
-\060\103\006\003\125\004\003\023\074\126\145\162\151\123\151\147
-\156\040\103\154\141\163\163\040\063\040\120\165\142\154\151\143
-\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-\040\055\040\107\064\060\166\060\020\006\007\052\206\110\316\075
-\002\001\006\005\053\201\004\000\042\003\142\000\004\247\126\172
-\174\122\332\144\233\016\055\134\330\136\254\222\075\376\001\346
-\031\112\075\024\003\113\372\140\047\040\331\203\211\151\372\124
-\306\232\030\136\125\052\144\336\006\366\215\112\073\255\020\074
-\145\075\220\210\004\211\340\060\141\263\256\135\001\247\173\336
-\174\262\276\312\145\141\000\206\256\332\217\173\320\211\255\115
-\035\131\232\101\261\274\107\200\334\236\142\303\371\243\201\262
-\060\201\257\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\006\060\155\006\010\053\006\001\005\005\007\001\014
-\004\141\060\137\241\135\240\133\060\131\060\127\060\125\026\011
-\151\155\141\147\145\057\147\151\146\060\041\060\037\060\007\006
-\005\053\016\003\002\032\004\024\217\345\323\032\206\254\215\216
-\153\303\317\200\152\324\110\030\054\173\031\056\060\045\026\043
-\150\164\164\160\072\057\057\154\157\147\157\056\166\145\162\151
-\163\151\147\156\056\143\157\155\057\166\163\154\157\147\157\056
-\147\151\146\060\035\006\003\125\035\016\004\026\004\024\263\026
-\221\375\356\246\156\344\265\056\111\217\207\170\201\200\354\345
-\261\265\060\012\006\010\052\206\110\316\075\004\003\003\003\150
-\000\060\145\002\060\146\041\014\030\046\140\132\070\173\126\102
-\340\247\374\066\204\121\221\040\054\166\115\103\075\304\035\204
-\043\320\254\326\174\065\006\316\315\151\275\220\015\333\154\110
-\102\035\016\252\102\002\061\000\234\075\110\071\043\071\130\032
-\025\022\131\152\236\357\325\131\262\035\122\054\231\161\315\307
-\051\337\033\052\141\173\161\321\336\363\300\345\015\072\112\252
-\055\247\330\206\052\335\056\020
-END
-
-# Trust for Certificate "VeriSign Class 3 Public Primary Certification Authority - G4"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "VeriSign Class 3 Public Primary Certification Authority - G4"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\042\325\330\337\217\002\061\321\215\367\235\267\317\212\055\144
-\311\077\154\072
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\072\122\341\347\375\157\072\343\157\363\157\231\033\371\042\101
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\312\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123
-\151\147\156\054\040\111\156\143\056\061\037\060\035\006\003\125
-\004\013\023\026\126\145\162\151\123\151\147\156\040\124\162\165
-\163\164\040\116\145\164\167\157\162\153\061\072\060\070\006\003
-\125\004\013\023\061\050\143\051\040\062\060\060\067\040\126\145
-\162\151\123\151\147\156\054\040\111\156\143\056\040\055\040\106
-\157\162\040\141\165\164\150\157\162\151\172\145\144\040\165\163
-\145\040\157\156\154\171\061\105\060\103\006\003\125\004\003\023
-\074\126\145\162\151\123\151\147\156\040\103\154\141\163\163\040
-\063\040\120\165\142\154\151\143\040\120\162\151\155\141\162\171
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101
-\165\164\150\157\162\151\164\171\040\055\040\107\064
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\057\200\376\043\214\016\042\017\110\147\022\050\221\207
-\254\263
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "NetLock Arany (Class Gold) Főtanúsítvány"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Arany (Class Gold) Főtanúsítvány"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\247\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\014\010\102\165\144\141\160
-\145\163\164\061\025\060\023\006\003\125\004\012\014\014\116\145
-\164\114\157\143\153\040\113\146\164\056\061\067\060\065\006\003
-\125\004\013\014\056\124\141\156\303\272\163\303\255\164\166\303
-\241\156\171\153\151\141\144\303\263\153\040\050\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\123\145\162\166\151\143
-\145\163\051\061\065\060\063\006\003\125\004\003\014\054\116\145
-\164\114\157\143\153\040\101\162\141\156\171\040\050\103\154\141
-\163\163\040\107\157\154\144\051\040\106\305\221\164\141\156\303
-\272\163\303\255\164\166\303\241\156\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\247\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\014\010\102\165\144\141\160
-\145\163\164\061\025\060\023\006\003\125\004\012\014\014\116\145
-\164\114\157\143\153\040\113\146\164\056\061\067\060\065\006\003
-\125\004\013\014\056\124\141\156\303\272\163\303\255\164\166\303
-\241\156\171\153\151\141\144\303\263\153\040\050\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\123\145\162\166\151\143
-\145\163\051\061\065\060\063\006\003\125\004\003\014\054\116\145
-\164\114\157\143\153\040\101\162\141\156\171\040\050\103\154\141
-\163\163\040\107\157\154\144\051\040\106\305\221\164\141\156\303
-\272\163\303\255\164\166\303\241\156\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\006\111\101\054\344\000\020
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\025\060\202\002\375\240\003\002\001\002\002\006\111
-\101\054\344\000\020\060\015\006\011\052\206\110\206\367\015\001
-\001\013\005\000\060\201\247\061\013\060\011\006\003\125\004\006
-\023\002\110\125\061\021\060\017\006\003\125\004\007\014\010\102
-\165\144\141\160\145\163\164\061\025\060\023\006\003\125\004\012
-\014\014\116\145\164\114\157\143\153\040\113\146\164\056\061\067
-\060\065\006\003\125\004\013\014\056\124\141\156\303\272\163\303
-\255\164\166\303\241\156\171\153\151\141\144\303\263\153\040\050
-\103\145\162\164\151\146\151\143\141\164\151\157\156\040\123\145
-\162\166\151\143\145\163\051\061\065\060\063\006\003\125\004\003
-\014\054\116\145\164\114\157\143\153\040\101\162\141\156\171\040
-\050\103\154\141\163\163\040\107\157\154\144\051\040\106\305\221
-\164\141\156\303\272\163\303\255\164\166\303\241\156\171\060\036
-\027\015\060\070\061\062\061\061\061\065\060\070\062\061\132\027
-\015\062\070\061\062\060\066\061\065\060\070\062\061\132\060\201
-\247\061\013\060\011\006\003\125\004\006\023\002\110\125\061\021
-\060\017\006\003\125\004\007\014\010\102\165\144\141\160\145\163
-\164\061\025\060\023\006\003\125\004\012\014\014\116\145\164\114
-\157\143\153\040\113\146\164\056\061\067\060\065\006\003\125\004
-\013\014\056\124\141\156\303\272\163\303\255\164\166\303\241\156
-\171\153\151\141\144\303\263\153\040\050\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\123\145\162\166\151\143\145\163
-\051\061\065\060\063\006\003\125\004\003\014\054\116\145\164\114
-\157\143\153\040\101\162\141\156\171\040\050\103\154\141\163\163
-\040\107\157\154\144\051\040\106\305\221\164\141\156\303\272\163
-\303\255\164\166\303\241\156\171\060\202\001\042\060\015\006\011
-\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000
-\060\202\001\012\002\202\001\001\000\304\044\136\163\276\113\155
-\024\303\241\364\343\227\220\156\322\060\105\036\074\356\147\331
-\144\340\032\212\177\312\060\312\203\343\040\301\343\364\072\323
-\224\137\032\174\133\155\277\060\117\204\047\366\237\037\111\274
-\306\231\012\220\362\017\365\177\103\204\067\143\121\213\172\245
-\160\374\172\130\315\216\233\355\303\106\154\204\160\135\332\363
-\001\220\043\374\116\060\251\176\341\047\143\347\355\144\074\240
-\270\311\063\143\376\026\220\377\260\270\375\327\250\300\300\224
-\103\013\266\325\131\246\236\126\320\044\037\160\171\257\333\071
-\124\015\145\165\331\025\101\224\001\257\136\354\366\215\361\377
-\255\144\376\040\232\327\134\353\376\246\037\010\144\243\213\166
-\125\255\036\073\050\140\056\207\045\350\252\257\037\306\144\106
-\040\267\160\177\074\336\110\333\226\123\267\071\167\344\032\342
-\307\026\204\166\227\133\057\273\031\025\205\370\151\205\365\231
-\247\251\362\064\247\251\266\246\003\374\157\206\075\124\174\166
-\004\233\153\371\100\135\000\064\307\056\231\165\235\345\210\003
-\252\115\370\003\322\102\166\300\033\002\003\000\250\213\243\105
-\060\103\060\022\006\003\125\035\023\001\001\377\004\010\060\006
-\001\001\377\002\001\004\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\035\006\003\125\035\016\004\026\004
-\024\314\372\147\223\360\266\270\320\245\300\036\363\123\375\214
-\123\337\203\327\226\060\015\006\011\052\206\110\206\367\015\001
-\001\013\005\000\003\202\001\001\000\253\177\356\034\026\251\234
-\074\121\000\240\300\021\010\005\247\231\346\157\001\210\124\141
-\156\361\271\030\255\112\255\376\201\100\043\224\057\373\165\174
-\057\050\113\142\044\201\202\013\365\141\361\034\156\270\141\070
-\353\201\372\142\241\073\132\142\323\224\145\304\341\346\155\202
-\370\057\045\160\262\041\046\301\162\121\037\214\054\303\204\220
-\303\132\217\272\317\364\247\145\245\353\230\321\373\005\262\106
-\165\025\043\152\157\205\143\060\200\360\325\236\037\051\034\302
-\154\260\120\131\135\220\133\073\250\015\060\317\277\175\177\316
-\361\235\203\275\311\106\156\040\246\371\141\121\272\041\057\173
-\276\245\025\143\241\324\225\207\361\236\271\363\211\363\075\205
-\270\270\333\276\265\271\051\371\332\067\005\000\111\224\003\204
-\104\347\277\103\061\317\165\213\045\321\364\246\144\365\222\366
-\253\005\353\075\351\245\013\066\142\332\314\006\137\066\213\266
-\136\061\270\052\373\136\366\161\337\104\046\236\304\346\015\221
-\264\056\165\225\200\121\152\113\060\246\260\142\241\223\361\233
-\330\316\304\143\165\077\131\107\261
-END
-
-# Trust for Certificate "NetLock Arany (Class Gold) Főtanúsítvány"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "NetLock Arany (Class Gold) Főtanúsítvány"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\006\010\077\131\077\025\241\004\240\151\244\153\251\003\320\006
-\267\227\011\221
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\305\241\267\377\163\335\326\327\064\062\030\337\374\074\255\210
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\247\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\014\010\102\165\144\141\160
-\145\163\164\061\025\060\023\006\003\125\004\012\014\014\116\145
-\164\114\157\143\153\040\113\146\164\056\061\067\060\065\006\003
-\125\004\013\014\056\124\141\156\303\272\163\303\255\164\166\303
-\241\156\171\153\151\141\144\303\263\153\040\050\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\123\145\162\166\151\143
-\145\163\051\061\065\060\063\006\003\125\004\003\014\054\116\145
-\164\114\157\143\153\040\101\162\141\156\171\040\050\103\154\141
-\163\163\040\107\157\154\144\051\040\106\305\221\164\141\156\303
-\272\163\303\255\164\166\303\241\156\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\006\111\101\054\344\000\020
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Staat der Nederlanden Root CA - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Staat der Nederlanden Root CA - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061
-\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040
-\122\157\157\164\040\103\101\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061
-\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040
-\122\157\157\164\040\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\000\230\226\214
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\312\060\202\003\262\240\003\002\001\002\002\004\000
-\230\226\214\060\015\006\011\052\206\110\206\367\015\001\001\013
-\005\000\060\132\061\013\060\011\006\003\125\004\006\023\002\116
-\114\061\036\060\034\006\003\125\004\012\014\025\123\164\141\141
-\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145
-\156\061\053\060\051\006\003\125\004\003\014\042\123\164\141\141
-\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144\145
-\156\040\122\157\157\164\040\103\101\040\055\040\107\062\060\036
-\027\015\060\070\060\063\062\066\061\061\061\070\061\067\132\027
-\015\062\060\060\063\062\065\061\061\060\063\061\060\132\060\132
-\061\013\060\011\006\003\125\004\006\023\002\116\114\061\036\060
-\034\006\003\125\004\012\014\025\123\164\141\141\164\040\144\145
-\162\040\116\145\144\145\162\154\141\156\144\145\156\061\053\060
-\051\006\003\125\004\003\014\042\123\164\141\141\164\040\144\145
-\162\040\116\145\144\145\162\154\141\156\144\145\156\040\122\157
-\157\164\040\103\101\040\055\040\107\062\060\202\002\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002
-\017\000\060\202\002\012\002\202\002\001\000\305\131\347\157\165
-\252\076\113\234\265\270\254\236\013\344\371\331\312\253\135\217
-\265\071\020\202\327\257\121\340\073\341\000\110\152\317\332\341
-\006\103\021\231\252\024\045\022\255\042\350\000\155\103\304\251
-\270\345\037\211\113\147\275\141\110\357\375\322\340\140\210\345
-\271\030\140\050\303\167\053\255\260\067\252\067\336\144\131\052
-\106\127\344\113\271\370\067\174\325\066\347\200\301\266\363\324
-\147\233\226\350\316\327\306\012\123\320\153\111\226\363\243\013
-\005\167\110\367\045\345\160\254\060\024\040\045\343\177\165\132
-\345\110\370\116\173\003\007\004\372\202\141\207\156\360\073\304
-\244\307\320\365\164\076\245\135\032\010\362\233\045\322\366\254
-\004\046\076\125\072\142\050\245\173\262\060\257\370\067\302\321
-\272\326\070\375\364\357\111\060\067\231\046\041\110\205\001\251
-\345\026\347\334\220\125\337\017\350\070\315\231\067\041\117\135
-\365\042\157\152\305\022\026\140\027\125\362\145\146\246\247\060
-\221\070\301\070\035\206\004\204\272\032\045\170\136\235\257\314
-\120\140\326\023\207\122\355\143\037\155\145\175\302\025\030\164
-\312\341\176\144\051\214\162\330\026\023\175\013\111\112\361\050
-\033\040\164\153\305\075\335\260\252\110\011\075\056\202\224\315
-\032\145\331\053\210\232\231\274\030\176\237\356\175\146\174\076
-\275\224\270\201\316\315\230\060\170\301\157\147\320\276\137\340
-\150\355\336\342\261\311\054\131\170\222\252\337\053\140\143\362
-\345\136\271\343\312\372\177\120\206\076\242\064\030\014\011\150
-\050\021\034\344\341\271\134\076\107\272\062\077\030\314\133\204
-\365\363\153\164\304\162\164\341\343\213\240\112\275\215\146\057
-\352\255\065\332\040\323\210\202\141\360\022\042\266\274\320\325
-\244\354\257\124\210\045\044\074\247\155\261\162\051\077\076\127
-\246\177\125\257\156\046\306\376\347\314\100\134\121\104\201\012
-\170\336\112\316\125\277\035\325\331\267\126\357\360\166\377\013
-\171\265\257\275\373\251\151\221\106\227\150\200\024\066\035\263
-\177\273\051\230\066\245\040\372\202\140\142\063\244\354\326\272
-\007\247\156\305\317\024\246\347\326\222\064\330\201\365\374\035
-\135\252\134\036\366\243\115\073\270\367\071\002\003\001\000\001
-\243\201\227\060\201\224\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\122\006\003\125\035\040\004\113
-\060\111\060\107\006\004\125\035\040\000\060\077\060\075\006\010
-\053\006\001\005\005\007\002\001\026\061\150\164\164\160\072\057
-\057\167\167\167\056\160\153\151\157\166\145\162\150\145\151\144
-\056\156\154\057\160\157\154\151\143\151\145\163\057\162\157\157
-\164\055\160\157\154\151\143\171\055\107\062\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003\125
-\035\016\004\026\004\024\221\150\062\207\025\035\211\342\265\361
-\254\066\050\064\215\013\174\142\210\353\060\015\006\011\052\206
-\110\206\367\015\001\001\013\005\000\003\202\002\001\000\250\101
-\112\147\052\222\201\202\120\156\341\327\330\263\071\073\363\002
-\025\011\120\121\357\055\275\044\173\210\206\073\371\264\274\222
-\011\226\271\366\300\253\043\140\006\171\214\021\116\121\322\171
-\200\063\373\235\110\276\354\101\103\201\037\176\107\100\034\345
-\172\010\312\252\213\165\255\024\304\302\350\146\074\202\007\247
-\346\047\202\133\030\346\017\156\331\120\076\212\102\030\051\306
-\264\126\374\126\020\240\005\027\275\014\043\177\364\223\355\234
-\032\121\276\335\105\101\277\221\044\264\037\214\351\137\317\173
-\041\231\237\225\237\071\072\106\034\154\371\315\173\234\220\315
-\050\251\307\251\125\273\254\142\064\142\065\023\113\024\072\125
-\203\271\206\215\222\246\306\364\007\045\124\314\026\127\022\112
-\202\170\310\024\331\027\202\046\055\135\040\037\171\256\376\324
-\160\026\026\225\203\330\065\071\377\122\135\165\034\026\305\023
-\125\317\107\314\165\145\122\112\336\360\260\247\344\012\226\013
-\373\255\302\342\045\204\262\335\344\275\176\131\154\233\360\360
-\330\347\312\362\351\227\070\176\211\276\314\373\071\027\141\077
-\162\333\072\221\330\145\001\031\035\255\120\244\127\012\174\113
-\274\234\161\163\052\105\121\031\205\314\216\375\107\247\164\225
-\035\250\321\257\116\027\261\151\046\302\252\170\127\133\305\115
-\247\345\236\005\027\224\312\262\137\240\111\030\215\064\351\046
-\154\110\036\252\150\222\005\341\202\163\132\233\334\007\133\010
-\155\175\235\327\215\041\331\374\024\040\252\302\105\337\077\347
-\000\262\121\344\302\370\005\271\171\032\214\064\363\236\133\344
-\067\133\153\112\337\054\127\212\100\132\066\272\335\165\104\010
-\067\102\160\014\376\334\136\041\240\243\212\300\220\234\150\332
-\120\346\105\020\107\170\266\116\322\145\311\303\067\337\341\102
-\143\260\127\067\105\055\173\212\234\277\005\352\145\125\063\367
-\071\020\305\050\052\041\172\033\212\304\044\371\077\025\310\232
-\025\040\365\125\142\226\355\155\223\120\274\344\252\170\255\331
-\313\012\145\207\246\146\301\304\201\243\167\072\130\036\013\356
-\203\213\235\036\322\122\244\314\035\157\260\230\155\224\061\265
-\370\161\012\334\271\374\175\062\140\346\353\257\212\001
-END
-
-# Trust for Certificate "Staat der Nederlanden Root CA - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Staat der Nederlanden Root CA - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\131\257\202\171\221\206\307\264\165\007\313\317\003\127\106\353
-\004\335\267\026
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\174\245\017\370\133\232\175\155\060\256\124\132\343\102\242\212
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\036\060\034\006\003\125\004\012\014\025\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\061
-\053\060\051\006\003\125\004\003\014\042\123\164\141\141\164\040
-\144\145\162\040\116\145\144\145\162\154\141\156\144\145\156\040
-\122\157\157\164\040\103\101\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\000\230\226\214
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "CA Disig"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "CA Disig"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\112\061\013\060\011\006\003\125\004\006\023\002\123\113\061
-\023\060\021\006\003\125\004\007\023\012\102\162\141\164\151\163
-\154\141\166\141\061\023\060\021\006\003\125\004\012\023\012\104
-\151\163\151\147\040\141\056\163\056\061\021\060\017\006\003\125
-\004\003\023\010\103\101\040\104\151\163\151\147
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\112\061\013\060\011\006\003\125\004\006\023\002\123\113\061
-\023\060\021\006\003\125\004\007\023\012\102\162\141\164\151\163
-\154\141\166\141\061\023\060\021\006\003\125\004\012\023\012\104
-\151\163\151\147\040\141\056\163\056\061\021\060\017\006\003\125
-\004\003\023\010\103\101\040\104\151\163\151\147
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\017\060\202\002\367\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\112\061\013\060\011\006\003\125\004\006\023\002\123\113\061\023
-\060\021\006\003\125\004\007\023\012\102\162\141\164\151\163\154
-\141\166\141\061\023\060\021\006\003\125\004\012\023\012\104\151
-\163\151\147\040\141\056\163\056\061\021\060\017\006\003\125\004
-\003\023\010\103\101\040\104\151\163\151\147\060\036\027\015\060
-\066\060\063\062\062\060\061\063\071\063\064\132\027\015\061\066
-\060\063\062\062\060\061\063\071\063\064\132\060\112\061\013\060
-\011\006\003\125\004\006\023\002\123\113\061\023\060\021\006\003
-\125\004\007\023\012\102\162\141\164\151\163\154\141\166\141\061
-\023\060\021\006\003\125\004\012\023\012\104\151\163\151\147\040
-\141\056\163\056\061\021\060\017\006\003\125\004\003\023\010\103
-\101\040\104\151\163\151\147\060\202\001\042\060\015\006\011\052
-\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060
-\202\001\012\002\202\001\001\000\222\366\061\301\175\210\375\231
-\001\251\330\173\362\161\165\361\061\306\363\165\146\372\121\050
-\106\204\227\170\064\274\154\374\274\105\131\210\046\030\112\304
-\067\037\241\112\104\275\343\161\004\365\104\027\342\077\374\110
-\130\157\134\236\172\011\272\121\067\042\043\146\103\041\260\074
-\144\242\370\152\025\016\077\353\121\341\124\251\335\006\231\327
-\232\074\124\213\071\003\077\017\305\316\306\353\203\162\002\250
-\037\161\363\055\370\165\010\333\142\114\350\372\316\371\347\152
-\037\266\153\065\202\272\342\217\026\222\175\005\014\154\106\003
-\135\300\355\151\277\072\301\212\240\350\216\331\271\105\050\207
-\010\354\264\312\025\276\202\335\265\104\213\055\255\206\014\150
-\142\155\205\126\362\254\024\143\072\306\321\231\254\064\170\126
-\113\317\266\255\077\214\212\327\004\345\343\170\114\365\206\252
-\365\217\372\075\154\161\243\055\312\147\353\150\173\156\063\251
-\014\202\050\250\114\152\041\100\025\040\014\046\133\203\302\251
-\026\025\300\044\202\135\053\026\255\312\143\366\164\000\260\337
-\103\304\020\140\126\147\143\105\002\003\001\000\001\243\201\377
-\060\201\374\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024\215
-\262\111\150\235\162\010\045\271\300\047\365\120\223\126\110\106
-\161\371\217\060\016\006\003\125\035\017\001\001\377\004\004\003
-\002\001\006\060\066\006\003\125\035\021\004\057\060\055\201\023
-\143\141\157\160\145\162\141\164\157\162\100\144\151\163\151\147
-\056\163\153\206\026\150\164\164\160\072\057\057\167\167\167\056
-\144\151\163\151\147\056\163\153\057\143\141\060\146\006\003\125
-\035\037\004\137\060\135\060\055\240\053\240\051\206\047\150\164
-\164\160\072\057\057\167\167\167\056\144\151\163\151\147\056\163
-\153\057\143\141\057\143\162\154\057\143\141\137\144\151\163\151
-\147\056\143\162\154\060\054\240\052\240\050\206\046\150\164\164
-\160\072\057\057\143\141\056\144\151\163\151\147\056\163\153\057
-\143\141\057\143\162\154\057\143\141\137\144\151\163\151\147\056
-\143\162\154\060\032\006\003\125\035\040\004\023\060\021\060\017
-\006\015\053\201\036\221\223\346\012\000\000\000\001\001\001\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202
-\001\001\000\135\064\164\141\114\257\073\330\377\237\155\130\066
-\034\075\013\201\015\022\053\106\020\200\375\347\074\047\320\172
-\310\251\266\176\164\060\063\243\072\212\173\164\300\171\171\102
-\223\155\377\261\051\024\202\253\041\214\057\027\371\077\046\057
-\365\131\306\357\200\006\267\232\111\051\354\316\176\161\074\152
-\020\101\300\366\323\232\262\174\132\221\234\300\254\133\310\115
-\136\367\341\123\377\103\167\374\236\113\147\154\327\363\203\321
-\240\340\177\045\337\270\230\013\232\062\070\154\060\240\363\377
-\010\025\063\367\120\112\173\076\243\076\040\251\334\057\126\200
-\012\355\101\120\260\311\364\354\262\343\046\104\000\016\157\236
-\006\274\042\226\123\160\145\304\120\012\106\153\244\057\047\201
-\022\047\023\137\020\241\166\316\212\173\067\352\303\071\141\003
-\225\230\072\347\154\210\045\010\374\171\150\015\207\175\142\370
-\264\137\373\305\330\114\275\130\274\077\103\133\324\036\001\115
-\074\143\276\043\357\214\315\132\120\270\150\124\371\012\231\063
-\021\000\341\236\302\106\167\202\365\131\006\214\041\114\207\011
-\315\345\250
-END
-
-# Trust for Certificate "CA Disig"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "CA Disig"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\052\310\325\213\127\316\277\057\111\257\362\374\166\217\121\024
-\142\220\172\101
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\077\105\226\071\342\120\207\367\273\376\230\014\074\040\230\346
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\112\061\013\060\011\006\003\125\004\006\023\002\123\113\061
-\023\060\021\006\003\125\004\007\023\012\102\162\141\164\151\163
-\154\141\166\141\061\023\060\021\006\003\125\004\012\023\012\104
-\151\163\151\147\040\141\056\163\056\061\021\060\017\006\003\125
-\004\003\023\010\103\101\040\104\151\163\151\147
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Juur-SK"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Juur-SK"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\135\061\030\060\026\006\011\052\206\110\206\367\015\001\011
-\001\026\011\160\153\151\100\163\153\056\145\145\061\013\060\011
-\006\003\125\004\006\023\002\105\105\061\042\060\040\006\003\125
-\004\012\023\031\101\123\040\123\145\162\164\151\146\151\164\163
-\145\145\162\151\155\151\163\153\145\163\153\165\163\061\020\060
-\016\006\003\125\004\003\023\007\112\165\165\162\055\123\113
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\135\061\030\060\026\006\011\052\206\110\206\367\015\001\011
-\001\026\011\160\153\151\100\163\153\056\145\145\061\013\060\011
-\006\003\125\004\006\023\002\105\105\061\042\060\040\006\003\125
-\004\012\023\031\101\123\040\123\145\162\164\151\146\151\164\163
-\145\145\162\151\155\151\163\153\145\163\153\165\163\061\020\060
-\016\006\003\125\004\003\023\007\112\165\165\162\055\123\113
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\073\216\113\374
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\346\060\202\003\316\240\003\002\001\002\002\004\073
-\216\113\374\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\135\061\030\060\026\006\011\052\206\110\206\367\015
-\001\011\001\026\011\160\153\151\100\163\153\056\145\145\061\013
-\060\011\006\003\125\004\006\023\002\105\105\061\042\060\040\006
-\003\125\004\012\023\031\101\123\040\123\145\162\164\151\146\151
-\164\163\145\145\162\151\155\151\163\153\145\163\153\165\163\061
-\020\060\016\006\003\125\004\003\023\007\112\165\165\162\055\123
-\113\060\036\027\015\060\061\060\070\063\060\061\064\062\063\060
-\061\132\027\015\061\066\060\070\062\066\061\064\062\063\060\061
-\132\060\135\061\030\060\026\006\011\052\206\110\206\367\015\001
-\011\001\026\011\160\153\151\100\163\153\056\145\145\061\013\060
-\011\006\003\125\004\006\023\002\105\105\061\042\060\040\006\003
-\125\004\012\023\031\101\123\040\123\145\162\164\151\146\151\164
-\163\145\145\162\151\155\151\163\153\145\163\153\165\163\061\020
-\060\016\006\003\125\004\003\023\007\112\165\165\162\055\123\113
-\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001
-\000\201\161\066\076\063\007\326\343\060\215\023\176\167\062\106
-\313\317\031\262\140\061\106\227\206\364\230\106\244\302\145\105
-\317\323\100\174\343\132\042\250\020\170\063\314\210\261\323\201
-\112\366\142\027\173\137\115\012\056\320\317\213\043\356\117\002
-\116\273\353\016\312\275\030\143\350\200\034\215\341\034\215\075
-\340\377\133\137\352\144\345\227\350\077\231\177\014\012\011\063
-\000\032\123\247\041\341\070\113\326\203\033\255\257\144\302\371
-\034\172\214\146\110\115\146\037\030\012\342\076\273\037\007\145
-\223\205\271\032\260\271\304\373\015\021\366\365\326\371\033\307
-\054\053\267\030\121\376\340\173\366\250\110\257\154\073\117\057
-\357\370\321\107\036\046\127\360\121\035\063\226\377\357\131\075
-\332\115\321\025\064\307\352\077\026\110\173\221\034\200\103\017
-\075\270\005\076\321\263\225\315\330\312\017\302\103\147\333\267
-\223\340\042\202\056\276\365\150\050\203\271\301\073\151\173\040
-\332\116\234\155\341\272\315\217\172\154\260\011\042\327\213\013
-\333\034\325\132\046\133\015\300\352\345\140\320\237\376\065\337
-\077\002\003\001\000\001\243\202\001\254\060\202\001\250\060\017
-\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
-\202\001\026\006\003\125\035\040\004\202\001\015\060\202\001\011
-\060\202\001\005\006\012\053\006\001\004\001\316\037\001\001\001
-\060\201\366\060\201\320\006\010\053\006\001\005\005\007\002\002
-\060\201\303\036\201\300\000\123\000\145\000\145\000\040\000\163
-\000\145\000\162\000\164\000\151\000\146\000\151\000\153\000\141
-\000\141\000\164\000\040\000\157\000\156\000\040\000\166\000\344
-\000\154\000\152\000\141\000\163\000\164\000\141\000\164\000\165
-\000\144\000\040\000\101\000\123\000\055\000\151\000\163\000\040
-\000\123\000\145\000\162\000\164\000\151\000\146\000\151\000\164
-\000\163\000\145\000\145\000\162\000\151\000\155\000\151\000\163
-\000\153\000\145\000\163\000\153\000\165\000\163\000\040\000\141
-\000\154\000\141\000\155\000\055\000\123\000\113\000\040\000\163
-\000\145\000\162\000\164\000\151\000\146\000\151\000\153\000\141
-\000\141\000\164\000\151\000\144\000\145\000\040\000\153\000\151
-\000\156\000\156\000\151\000\164\000\141\000\155\000\151\000\163
-\000\145\000\153\000\163\060\041\006\010\053\006\001\005\005\007
-\002\001\026\025\150\164\164\160\072\057\057\167\167\167\056\163
-\153\056\145\145\057\143\160\163\057\060\053\006\003\125\035\037
-\004\044\060\042\060\040\240\036\240\034\206\032\150\164\164\160
-\072\057\057\167\167\167\056\163\153\056\145\145\057\152\165\165
-\162\057\143\162\154\057\060\035\006\003\125\035\016\004\026\004
-\024\004\252\172\107\243\344\211\257\032\317\012\100\247\030\077
-\157\357\351\175\276\060\037\006\003\125\035\043\004\030\060\026
-\200\024\004\252\172\107\243\344\211\257\032\317\012\100\247\030
-\077\157\357\351\175\276\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\346\060\015\006\011\052\206\110\206\367\015
-\001\001\005\005\000\003\202\001\001\000\173\301\030\224\123\242
-\011\363\376\046\147\232\120\344\303\005\057\053\065\170\221\114
-\174\250\021\021\171\114\111\131\254\310\367\205\145\134\106\273
-\073\020\240\002\257\315\117\265\314\066\052\354\135\376\357\240
-\221\311\266\223\157\174\200\124\354\307\010\160\015\216\373\202
-\354\052\140\170\151\066\066\321\305\234\213\151\265\100\310\224
-\145\167\362\127\041\146\073\316\205\100\266\063\143\032\277\171
-\036\374\134\035\323\035\223\033\213\014\135\205\275\231\060\062
-\030\011\221\122\351\174\241\272\377\144\222\232\354\376\065\356
-\214\057\256\374\040\206\354\112\336\033\170\062\067\246\201\322
-\235\257\132\022\026\312\231\133\374\157\155\016\305\240\036\206
-\311\221\320\134\230\202\137\143\014\212\132\253\330\225\246\314
-\313\212\326\277\144\113\216\312\212\262\260\351\041\062\236\252
-\250\205\230\064\201\071\041\073\250\072\122\062\075\366\153\067
-\206\006\132\025\230\334\360\021\146\376\064\040\267\003\364\101
-\020\175\071\204\171\226\162\143\266\226\002\345\153\271\255\031
-\115\273\306\104\333\066\313\052\234\216
-END
-
-# Trust for Certificate "Juur-SK"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Juur-SK"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\100\235\113\331\027\265\134\047\266\233\144\313\230\042\104\015
-\315\011\270\211
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\252\216\135\331\370\333\012\130\267\215\046\207\154\202\065\125
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\135\061\030\060\026\006\011\052\206\110\206\367\015\001\011
-\001\026\011\160\153\151\100\163\153\056\145\145\061\013\060\011
-\006\003\125\004\006\023\002\105\105\061\042\060\040\006\003\125
-\004\012\023\031\101\123\040\123\145\162\164\151\146\151\164\163
-\145\145\162\151\155\151\163\153\145\163\153\165\163\061\020\060
-\016\006\003\125\004\003\023\007\112\165\165\162\055\123\113
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\073\216\113\374
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Hongkong Post Root CA 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Hongkong Post Root CA 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\107\061\013\060\011\006\003\125\004\006\023\002\110\113\061
-\026\060\024\006\003\125\004\012\023\015\110\157\156\147\153\157
-\156\147\040\120\157\163\164\061\040\060\036\006\003\125\004\003
-\023\027\110\157\156\147\153\157\156\147\040\120\157\163\164\040
-\122\157\157\164\040\103\101\040\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\107\061\013\060\011\006\003\125\004\006\023\002\110\113\061
-\026\060\024\006\003\125\004\012\023\015\110\157\156\147\153\157
-\156\147\040\120\157\163\164\061\040\060\036\006\003\125\004\003
-\023\027\110\157\156\147\153\157\156\147\040\120\157\163\164\040
-\122\157\157\164\040\103\101\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\003\350
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\060\060\202\002\030\240\003\002\001\002\002\002\003
-\350\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\060\107\061\013\060\011\006\003\125\004\006\023\002\110\113\061
-\026\060\024\006\003\125\004\012\023\015\110\157\156\147\153\157
-\156\147\040\120\157\163\164\061\040\060\036\006\003\125\004\003
-\023\027\110\157\156\147\153\157\156\147\040\120\157\163\164\040
-\122\157\157\164\040\103\101\040\061\060\036\027\015\060\063\060
-\065\061\065\060\065\061\063\061\064\132\027\015\062\063\060\065
-\061\065\060\064\065\062\062\071\132\060\107\061\013\060\011\006
-\003\125\004\006\023\002\110\113\061\026\060\024\006\003\125\004
-\012\023\015\110\157\156\147\153\157\156\147\040\120\157\163\164
-\061\040\060\036\006\003\125\004\003\023\027\110\157\156\147\153
-\157\156\147\040\120\157\163\164\040\122\157\157\164\040\103\101
-\040\061\060\202\001\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202
-\001\001\000\254\377\070\266\351\146\002\111\343\242\264\341\220
-\371\100\217\171\371\342\275\171\376\002\275\356\044\222\035\042
-\366\332\205\162\151\376\327\077\011\324\335\221\265\002\234\320
-\215\132\341\125\303\120\206\271\051\046\302\343\331\240\361\151
-\003\050\040\200\105\042\055\126\247\073\124\225\126\042\131\037
-\050\337\037\040\075\155\242\066\276\043\240\261\156\265\261\047
-\077\071\123\011\352\253\152\350\164\262\302\145\134\216\277\174
-\303\170\204\315\236\026\374\365\056\117\040\052\010\237\167\363
-\305\036\304\232\122\146\036\110\136\343\020\006\217\042\230\341
-\145\216\033\135\043\146\073\270\245\062\121\310\206\252\241\251
-\236\177\166\224\302\246\154\267\101\360\325\310\006\070\346\324
-\014\342\363\073\114\155\120\214\304\203\047\301\023\204\131\075
-\236\165\164\266\330\002\136\072\220\172\300\102\066\162\354\152
-\115\334\357\304\000\337\023\030\127\137\046\170\310\326\012\171
-\167\277\367\257\267\166\271\245\013\204\027\135\020\352\157\341
-\253\225\021\137\155\074\243\134\115\203\133\362\263\031\212\200
-\213\013\207\002\003\001\000\001\243\046\060\044\060\022\006\003
-\125\035\023\001\001\377\004\010\060\006\001\001\377\002\001\003
-\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\306
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\001\001\000\016\106\325\074\256\342\207\331\136\201\213\002
-\230\101\010\214\114\274\332\333\356\047\033\202\347\152\105\354
-\026\213\117\205\240\363\262\160\275\132\226\272\312\156\155\356
-\106\213\156\347\052\056\226\263\031\063\353\264\237\250\262\067
-\356\230\250\227\266\056\266\147\047\324\246\111\375\034\223\145
-\166\236\102\057\334\042\154\232\117\362\132\025\071\261\161\327
-\053\121\350\155\034\230\300\331\052\364\241\202\173\325\311\101
-\242\043\001\164\070\125\213\017\271\056\147\242\040\004\067\332
-\234\013\323\027\041\340\217\227\171\064\157\204\110\002\040\063
-\033\346\064\104\237\221\160\364\200\136\204\103\302\051\322\154
-\022\024\344\141\215\254\020\220\236\204\120\273\360\226\157\105
-\237\212\363\312\154\117\372\021\072\025\025\106\303\315\037\203
-\133\055\101\022\355\120\147\101\023\075\041\253\224\212\252\116
-\174\301\261\373\247\326\265\047\057\227\253\156\340\035\342\321
-\034\054\037\104\342\374\276\221\241\234\373\326\051\123\163\206
-\237\123\330\103\016\135\326\143\202\161\035\200\164\312\366\342
-\002\153\331\132
-END
-
-# Trust for Certificate "Hongkong Post Root CA 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Hongkong Post Root CA 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\326\332\250\040\215\011\322\025\115\044\265\057\313\064\156\262
-\130\262\212\130
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\250\015\157\071\170\271\103\155\167\102\155\230\132\314\043\312
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\107\061\013\060\011\006\003\125\004\006\023\002\110\113\061
-\026\060\024\006\003\125\004\012\023\015\110\157\156\147\153\157
-\156\147\040\120\157\163\164\061\040\060\036\006\003\125\004\003
-\023\027\110\157\156\147\153\157\156\147\040\120\157\163\164\040
-\122\157\157\164\040\103\101\040\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\003\350
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "SecureSign RootCA11"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SecureSign RootCA11"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\130\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\053\060\051\006\003\125\004\012\023\042\112\141\160\141\156\040
-\103\145\162\164\151\146\151\143\141\164\151\157\156\040\123\145
-\162\166\151\143\145\163\054\040\111\156\143\056\061\034\060\032
-\006\003\125\004\003\023\023\123\145\143\165\162\145\123\151\147
-\156\040\122\157\157\164\103\101\061\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\130\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\053\060\051\006\003\125\004\012\023\042\112\141\160\141\156\040
-\103\145\162\164\151\146\151\143\141\164\151\157\156\040\123\145
-\162\166\151\143\145\163\054\040\111\156\143\056\061\034\060\032
-\006\003\125\004\003\023\023\123\145\143\165\162\145\123\151\147
-\156\040\122\157\157\164\103\101\061\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\155\060\202\002\125\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\130\061\013\060\011\006\003\125\004\006\023\002\112\120\061\053
-\060\051\006\003\125\004\012\023\042\112\141\160\141\156\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162
-\166\151\143\145\163\054\040\111\156\143\056\061\034\060\032\006
-\003\125\004\003\023\023\123\145\143\165\162\145\123\151\147\156
-\040\122\157\157\164\103\101\061\061\060\036\027\015\060\071\060
-\064\060\070\060\064\065\066\064\067\132\027\015\062\071\060\064
-\060\070\060\064\065\066\064\067\132\060\130\061\013\060\011\006
-\003\125\004\006\023\002\112\120\061\053\060\051\006\003\125\004
-\012\023\042\112\141\160\141\156\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\123\145\162\166\151\143\145\163\054
-\040\111\156\143\056\061\034\060\032\006\003\125\004\003\023\023
-\123\145\143\165\162\145\123\151\147\156\040\122\157\157\164\103
-\101\061\061\060\202\001\042\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002
-\202\001\001\000\375\167\252\245\034\220\005\073\313\114\233\063
-\213\132\024\105\244\347\220\026\321\337\127\322\041\020\244\027
-\375\337\254\326\037\247\344\333\174\367\354\337\270\003\332\224
-\130\375\135\162\174\214\077\137\001\147\164\025\226\343\002\074
-\207\333\256\313\001\216\302\363\146\306\205\105\364\002\306\072
-\265\142\262\257\372\234\277\244\346\324\200\060\230\363\015\266
-\223\217\251\324\330\066\362\260\374\212\312\054\241\025\063\225
-\061\332\300\033\362\356\142\231\206\143\077\277\335\223\052\203
-\250\166\271\023\037\267\316\116\102\205\217\042\347\056\032\362
-\225\011\262\005\265\104\116\167\241\040\275\251\362\116\012\175
-\120\255\365\005\015\105\117\106\161\375\050\076\123\373\004\330
-\055\327\145\035\112\033\372\317\073\260\061\232\065\156\310\213
-\006\323\000\221\362\224\010\145\114\261\064\006\000\172\211\342
-\360\307\003\131\317\325\326\350\247\062\263\346\230\100\206\305
-\315\047\022\213\314\173\316\267\021\074\142\140\007\043\076\053
-\100\156\224\200\011\155\266\263\157\167\157\065\010\120\373\002
-\207\305\076\211\002\003\001\000\001\243\102\060\100\060\035\006
-\003\125\035\016\004\026\004\024\133\370\115\117\262\245\206\324
-\072\322\361\143\232\240\276\011\366\127\267\336\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\001\006\060\017\006\003
-\125\035\023\001\001\377\004\005\060\003\001\001\377\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001
-\000\240\241\070\026\146\056\247\126\037\041\234\006\372\035\355
-\271\042\305\070\046\330\116\117\354\243\177\171\336\106\041\241
-\207\167\217\007\010\232\262\244\305\257\017\062\230\013\174\146
-\051\266\233\175\045\122\111\103\253\114\056\053\156\172\160\257
-\026\016\343\002\154\373\102\346\030\235\105\330\125\310\350\073
-\335\347\341\364\056\013\034\064\134\154\130\112\373\214\210\120
-\137\225\034\277\355\253\042\265\145\263\205\272\236\017\270\255
-\345\172\033\212\120\072\035\275\015\274\173\124\120\013\271\102
-\257\125\240\030\201\255\145\231\357\276\344\234\277\304\205\253
-\101\262\124\157\334\045\315\355\170\342\216\014\215\011\111\335
-\143\173\132\151\226\002\041\250\275\122\131\351\175\065\313\310
-\122\312\177\201\376\331\153\323\367\021\355\045\337\370\347\371
-\244\372\162\227\204\123\015\245\320\062\030\121\166\131\024\154
-\017\353\354\137\200\214\165\103\203\303\205\230\377\114\236\055
-\015\344\167\203\223\116\265\226\007\213\050\023\233\214\031\215
-\101\047\111\100\356\336\346\043\104\071\334\241\042\326\272\003
-\362
-END
-
-# Trust for Certificate "SecureSign RootCA11"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "SecureSign RootCA11"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\073\304\237\110\370\363\163\240\234\036\275\370\133\261\303\145
-\307\330\021\263
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\267\122\164\342\222\264\200\223\362\165\344\314\327\362\352\046
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\130\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\053\060\051\006\003\125\004\012\023\042\112\141\160\141\156\040
-\103\145\162\164\151\146\151\143\141\164\151\157\156\040\123\145
-\162\166\151\143\145\163\054\040\111\156\143\056\061\034\060\032
-\006\003\125\004\003\023\023\123\145\143\165\162\145\123\151\147
-\156\040\122\157\157\164\103\101\061\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "ACEDICOM Root"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ACEDICOM Root"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\104\061\026\060\024\006\003\125\004\003\014\015\101\103\105
-\104\111\103\117\115\040\122\157\157\164\061\014\060\012\006\003
-\125\004\013\014\003\120\113\111\061\017\060\015\006\003\125\004
-\012\014\006\105\104\111\103\117\115\061\013\060\011\006\003\125
-\004\006\023\002\105\123
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\104\061\026\060\024\006\003\125\004\003\014\015\101\103\105
-\104\111\103\117\115\040\122\157\157\164\061\014\060\012\006\003
-\125\004\013\014\003\120\113\111\061\017\060\015\006\003\125\004
-\012\014\006\105\104\111\103\117\115\061\013\060\011\006\003\125
-\004\006\023\002\105\123
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\141\215\307\206\073\001\202\005
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\265\060\202\003\235\240\003\002\001\002\002\010\141
-\215\307\206\073\001\202\005\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\060\104\061\026\060\024\006\003\125\004
-\003\014\015\101\103\105\104\111\103\117\115\040\122\157\157\164
-\061\014\060\012\006\003\125\004\013\014\003\120\113\111\061\017
-\060\015\006\003\125\004\012\014\006\105\104\111\103\117\115\061
-\013\060\011\006\003\125\004\006\023\002\105\123\060\036\027\015
-\060\070\060\064\061\070\061\066\062\064\062\062\132\027\015\062
-\070\060\064\061\063\061\066\062\064\062\062\132\060\104\061\026
-\060\024\006\003\125\004\003\014\015\101\103\105\104\111\103\117
-\115\040\122\157\157\164\061\014\060\012\006\003\125\004\013\014
-\003\120\113\111\061\017\060\015\006\003\125\004\012\014\006\105
-\104\111\103\117\115\061\013\060\011\006\003\125\004\006\023\002
-\105\123\060\202\002\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202
-\002\001\000\377\222\225\341\150\006\166\264\054\310\130\110\312
-\375\200\124\051\125\143\044\377\220\145\233\020\165\173\303\152
-\333\142\002\001\362\030\206\265\174\132\070\261\344\130\271\373
-\323\330\055\237\275\062\067\277\054\025\155\276\265\364\041\322
-\023\221\331\007\255\001\005\326\363\275\167\316\137\102\201\012
-\371\152\343\203\000\250\053\056\125\023\143\201\312\107\034\173
-\134\026\127\172\033\203\140\004\072\076\145\303\315\001\336\336
-\244\326\014\272\216\336\331\004\356\027\126\042\233\217\143\375
-\115\026\013\267\173\167\214\371\045\265\321\155\231\022\056\117
-\032\270\346\352\004\222\256\075\021\271\121\102\075\207\260\061
-\205\257\171\132\234\376\347\116\136\222\117\103\374\253\072\255
-\245\022\046\146\271\342\014\327\230\316\324\130\245\225\100\012
-\267\104\235\023\164\053\302\245\353\042\025\230\020\330\213\305
-\004\237\035\217\140\345\006\033\233\317\271\171\240\075\242\043
-\077\102\077\153\372\034\003\173\060\215\316\154\300\277\346\033
-\137\277\147\270\204\031\325\025\357\173\313\220\066\061\142\311
-\274\002\253\106\137\233\376\032\150\224\064\075\220\216\255\366
-\344\035\011\177\112\210\070\077\276\147\375\064\226\365\035\274
-\060\164\313\070\356\325\154\253\324\374\364\000\267\000\133\205
-\062\026\166\063\351\330\243\231\235\005\000\252\026\346\363\201
-\175\157\175\252\206\155\255\025\164\323\304\242\161\252\364\024
-\175\347\062\270\037\274\325\361\116\275\157\027\002\071\327\016
-\225\102\072\307\000\076\351\046\143\021\352\013\321\112\377\030
-\235\262\327\173\057\072\331\226\373\350\036\222\256\023\125\310
-\331\047\366\334\110\033\260\044\301\205\343\167\235\232\244\363
-\014\021\035\015\310\264\024\356\265\202\127\011\277\040\130\177
-\057\042\043\330\160\313\171\154\311\113\362\251\052\310\374\207
-\053\327\032\120\370\047\350\057\103\343\072\275\330\127\161\375
-\316\246\122\133\371\335\115\355\345\366\157\211\355\273\223\234
-\166\041\165\360\222\114\051\367\057\234\001\056\376\120\106\236
-\144\014\024\263\007\133\305\302\163\154\361\007\134\105\044\024
-\065\256\203\361\152\115\211\172\372\263\330\055\146\360\066\207
-\365\053\123\002\003\001\000\001\243\201\252\060\201\247\060\017
-\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
-\037\006\003\125\035\043\004\030\060\026\200\024\246\263\341\053
-\053\111\266\327\163\241\252\224\365\001\347\163\145\114\254\120
-\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\206
-\060\035\006\003\125\035\016\004\026\004\024\246\263\341\053\053
-\111\266\327\163\241\252\224\365\001\347\163\145\114\254\120\060
-\104\006\003\125\035\040\004\075\060\073\060\071\006\004\125\035
-\040\000\060\061\060\057\006\010\053\006\001\005\005\007\002\001
-\026\043\150\164\164\160\072\057\057\141\143\145\144\151\143\157
-\155\056\145\144\151\143\157\155\147\162\157\165\160\056\143\157
-\155\057\144\157\143\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\003\202\002\001\000\316\054\013\122\121\142\046
-\175\014\047\203\217\305\366\332\240\150\173\117\222\136\352\244
-\163\062\021\123\104\262\104\313\235\354\017\171\102\263\020\246
-\307\015\235\313\266\372\077\072\174\352\277\210\123\033\074\367
-\202\372\005\065\063\341\065\250\127\300\347\375\215\117\077\223
-\062\117\170\146\003\167\007\130\351\225\310\176\076\320\171\000
-\214\362\033\121\063\233\274\224\351\072\173\156\122\055\062\236
-\043\244\105\373\266\056\023\260\213\030\261\335\316\325\035\247
-\102\177\125\276\373\133\273\107\324\374\044\315\004\256\226\005
-\025\326\254\316\060\363\312\013\305\272\342\042\340\246\255\042
-\344\002\356\164\021\177\114\377\170\035\065\332\346\002\064\353
-\030\022\141\167\006\011\026\143\352\030\255\242\207\037\362\307
-\200\011\011\165\116\020\250\217\075\206\270\165\021\300\044\142
-\212\226\173\112\105\351\354\131\305\276\153\203\346\341\350\254
-\265\060\036\376\005\007\200\371\341\043\015\120\217\005\230\377
-\054\137\350\073\266\255\317\201\265\041\207\312\010\052\043\047
-\060\040\053\317\355\224\133\254\262\172\322\307\050\241\212\013
-\233\115\112\054\155\205\077\011\162\074\147\342\331\334\007\272
-\353\145\173\132\001\143\326\220\133\117\027\146\075\177\013\031
-\243\223\143\020\122\052\237\024\026\130\342\334\245\364\241\026
-\213\016\221\213\201\312\233\131\372\330\153\221\007\145\125\137
-\122\037\257\072\373\220\335\151\245\133\234\155\016\054\266\372
-\316\254\245\174\062\112\147\100\334\060\064\043\335\327\004\043
-\146\360\374\125\200\247\373\146\031\202\065\147\142\160\071\136
-\157\307\352\220\100\104\010\036\270\262\326\333\356\131\247\015
-\030\171\064\274\124\030\136\123\312\064\121\355\105\012\346\216
-\307\202\066\076\247\070\143\251\060\054\027\020\140\222\237\125
-\207\022\131\020\302\017\147\151\021\314\116\036\176\112\232\255
-\257\100\250\165\254\126\220\164\270\240\234\245\171\157\334\351
-\032\310\151\005\351\272\372\003\263\174\344\340\116\302\316\235
-\350\266\106\015\156\176\127\072\147\224\302\313\037\234\167\112
-\147\116\151\206\103\223\070\373\266\333\117\203\221\324\140\176
-\113\076\053\070\007\125\230\136\244
-END
-
-# Trust for Certificate "ACEDICOM Root"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "ACEDICOM Root"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\340\264\062\056\262\366\245\150\266\124\123\204\110\030\112\120
-\066\207\103\204
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\102\201\240\342\034\343\125\020\336\125\211\102\145\226\042\346
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\104\061\026\060\024\006\003\125\004\003\014\015\101\103\105
-\104\111\103\117\115\040\122\157\157\164\061\014\060\012\006\003
-\125\004\013\014\003\120\113\111\061\017\060\015\006\003\125\004
-\012\014\006\105\104\111\103\117\115\061\013\060\011\006\003\125
-\004\006\023\002\105\123
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\141\215\307\206\073\001\202\005
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-
-#
-# Certificate "Verisign Class 1 Public Primary Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 1 Public Primary Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151
-\147\156\054\040\111\156\143\056\061\067\060\065\006\003\125\004
-\013\023\056\103\154\141\163\163\040\061\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151
-\147\156\054\040\111\156\143\056\061\067\060\065\006\003\125\004
-\013\023\056\103\154\141\163\163\040\061\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\077\151\036\201\234\360\232\112\363\163\377\271\110\242
-\344\335
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\074\060\202\001\245\002\020\077\151\036\201\234\360
-\232\112\363\163\377\271\110\242\344\335\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\060\137\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125\004
-\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156\143
-\056\061\067\060\065\006\003\125\004\013\023\056\103\154\141\163
-\163\040\061\040\120\165\142\154\151\143\040\120\162\151\155\141
-\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171\060\036\027\015\071\066
-\060\061\062\071\060\060\060\060\060\060\132\027\015\062\070\060
-\070\060\062\062\063\065\071\065\071\132\060\137\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125
-\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156
-\143\056\061\067\060\065\006\003\125\004\013\023\056\103\154\141
-\163\163\040\061\040\120\165\142\154\151\143\040\120\162\151\155
-\141\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\101\165\164\150\157\162\151\164\171\060\201\237\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\201\215
-\000\060\201\211\002\201\201\000\345\031\277\155\243\126\141\055
-\231\110\161\366\147\336\271\215\353\267\236\206\200\012\221\016
-\372\070\045\257\106\210\202\345\163\250\240\233\044\135\015\037
-\314\145\156\014\260\320\126\204\030\207\232\006\233\020\241\163
-\337\264\130\071\153\156\301\366\025\325\250\250\077\252\022\006
-\215\061\254\177\260\064\327\217\064\147\210\011\315\024\021\342
-\116\105\126\151\037\170\002\200\332\334\107\221\051\273\066\311
-\143\134\305\340\327\055\207\173\241\267\062\260\173\060\272\052
-\057\061\252\356\243\147\332\333\002\003\001\000\001\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\201\201\000
-\130\025\051\071\074\167\243\332\134\045\003\174\140\372\356\011
-\231\074\047\020\160\310\014\011\346\263\207\317\012\342\030\226
-\065\142\314\277\233\047\171\211\137\311\304\011\364\316\265\035
-\337\052\275\345\333\206\234\150\045\345\060\174\266\211\025\376
-\147\321\255\341\120\254\074\174\142\113\217\272\204\327\022\025
-\033\037\312\135\017\301\122\224\052\021\231\332\173\317\014\066
-\023\325\065\334\020\031\131\352\224\301\000\277\165\217\331\372
-\375\166\004\333\142\273\220\152\003\331\106\065\331\370\174\133
-END
-
-# Trust for Certificate "Verisign Class 1 Public Primary Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 1 Public Primary Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\316\152\144\243\011\344\057\273\331\205\034\105\076\144\011\352
-\350\175\140\361
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\206\254\336\053\305\155\303\331\214\050\210\323\215\026\023\036
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151
-\147\156\054\040\111\156\143\056\061\067\060\065\006\003\125\004
-\013\023\056\103\154\141\163\163\040\061\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\077\151\036\201\234\360\232\112\363\163\377\271\110\242
-\344\335
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Verisign Class 3 Public Primary Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 3 Public Primary Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151
-\147\156\054\040\111\156\143\056\061\067\060\065\006\003\125\004
-\013\023\056\103\154\141\163\163\040\063\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151
-\147\156\054\040\111\156\143\056\061\067\060\065\006\003\125\004
-\013\023\056\103\154\141\163\163\040\063\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\074\221\061\313\037\366\320\033\016\232\270\320\104\277
-\022\276
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\002\074\060\202\001\245\002\020\074\221\061\313\037\366
-\320\033\016\232\270\320\104\277\022\276\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\060\137\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125\004
-\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156\143
-\056\061\067\060\065\006\003\125\004\013\023\056\103\154\141\163
-\163\040\063\040\120\165\142\154\151\143\040\120\162\151\155\141
-\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157\156
-\040\101\165\164\150\157\162\151\164\171\060\036\027\015\071\066
-\060\061\062\071\060\060\060\060\060\060\132\027\015\062\070\060
-\070\060\062\062\063\065\071\065\071\132\060\137\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\027\060\025\006\003\125
-\004\012\023\016\126\145\162\151\123\151\147\156\054\040\111\156
-\143\056\061\067\060\065\006\003\125\004\013\023\056\103\154\141
-\163\163\040\063\040\120\165\142\154\151\143\040\120\162\151\155
-\141\162\171\040\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\101\165\164\150\157\162\151\164\171\060\201\237\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\201\215
-\000\060\201\211\002\201\201\000\311\134\131\236\362\033\212\001
-\024\264\020\337\004\100\333\343\127\257\152\105\100\217\204\014
-\013\321\063\331\331\021\317\356\002\130\037\045\367\052\250\104
-\005\252\354\003\037\170\177\236\223\271\232\000\252\043\175\326
-\254\205\242\143\105\307\162\047\314\364\114\306\165\161\322\071
-\357\117\102\360\165\337\012\220\306\216\040\157\230\017\370\254
-\043\137\160\051\066\244\311\206\347\261\232\040\313\123\245\205
-\347\075\276\175\232\376\044\105\063\334\166\025\355\017\242\161
-\144\114\145\056\201\150\105\247\002\003\001\000\001\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\201\201\000
-\020\162\122\251\005\024\031\062\010\101\360\305\153\012\314\176
-\017\041\031\315\344\147\334\137\251\033\346\312\350\163\235\042
-\330\230\156\163\003\141\221\305\174\260\105\100\156\104\235\215
-\260\261\226\164\141\055\015\251\105\322\244\222\052\326\232\165
-\227\156\077\123\375\105\231\140\035\250\053\114\371\136\247\011
-\330\165\060\327\322\145\140\075\147\326\110\125\165\151\077\221
-\365\110\013\107\151\042\151\202\226\276\311\310\070\206\112\172
-\054\163\031\110\151\116\153\174\145\277\017\374\160\316\210\220
-END
-
-# Trust for Certificate "Verisign Class 3 Public Primary Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Verisign Class 3 Public Primary Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\241\333\143\223\221\157\027\344\030\125\011\100\004\025\307\002
-\100\260\256\153
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\357\132\361\063\357\361\315\273\121\002\356\022\024\113\226\304
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\027\060\025\006\003\125\004\012\023\016\126\145\162\151\123\151
-\147\156\054\040\111\156\143\056\061\067\060\065\006\003\125\004
-\013\023\056\103\154\141\163\163\040\063\040\120\165\142\154\151
-\143\040\120\162\151\155\141\162\171\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\074\221\061\313\037\366\320\033\016\232\270\320\104\277
-\022\276
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Microsec e-Szigno Root CA 2009"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Microsec e-Szigno Root CA 2009"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\014\010\102\165\144\141\160
-\145\163\164\061\026\060\024\006\003\125\004\012\014\015\115\151
-\143\162\157\163\145\143\040\114\164\144\056\061\047\060\045\006
-\003\125\004\003\014\036\115\151\143\162\157\163\145\143\040\145
-\055\123\172\151\147\156\157\040\122\157\157\164\040\103\101\040
-\062\060\060\071\061\037\060\035\006\011\052\206\110\206\367\015
-\001\011\001\026\020\151\156\146\157\100\145\055\163\172\151\147
-\156\157\056\150\165
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\014\010\102\165\144\141\160
-\145\163\164\061\026\060\024\006\003\125\004\012\014\015\115\151
-\143\162\157\163\145\143\040\114\164\144\056\061\047\060\045\006
-\003\125\004\003\014\036\115\151\143\162\157\163\145\143\040\145
-\055\123\172\151\147\156\157\040\122\157\157\164\040\103\101\040
-\062\060\060\071\061\037\060\035\006\011\052\206\110\206\367\015
-\001\011\001\026\020\151\156\146\157\100\145\055\163\172\151\147
-\156\157\056\150\165
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\302\176\103\004\116\107\077\031
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\012\060\202\002\362\240\003\002\001\002\002\011\000
-\302\176\103\004\116\107\077\031\060\015\006\011\052\206\110\206
-\367\015\001\001\013\005\000\060\201\202\061\013\060\011\006\003
-\125\004\006\023\002\110\125\061\021\060\017\006\003\125\004\007
-\014\010\102\165\144\141\160\145\163\164\061\026\060\024\006\003
-\125\004\012\014\015\115\151\143\162\157\163\145\143\040\114\164
-\144\056\061\047\060\045\006\003\125\004\003\014\036\115\151\143
-\162\157\163\145\143\040\145\055\123\172\151\147\156\157\040\122
-\157\157\164\040\103\101\040\062\060\060\071\061\037\060\035\006
-\011\052\206\110\206\367\015\001\011\001\026\020\151\156\146\157
-\100\145\055\163\172\151\147\156\157\056\150\165\060\036\027\015
-\060\071\060\066\061\066\061\061\063\060\061\070\132\027\015\062
-\071\061\062\063\060\061\061\063\060\061\070\132\060\201\202\061
-\013\060\011\006\003\125\004\006\023\002\110\125\061\021\060\017
-\006\003\125\004\007\014\010\102\165\144\141\160\145\163\164\061
-\026\060\024\006\003\125\004\012\014\015\115\151\143\162\157\163
-\145\143\040\114\164\144\056\061\047\060\045\006\003\125\004\003
-\014\036\115\151\143\162\157\163\145\143\040\145\055\123\172\151
-\147\156\157\040\122\157\157\164\040\103\101\040\062\060\060\071
-\061\037\060\035\006\011\052\206\110\206\367\015\001\011\001\026
-\020\151\156\146\157\100\145\055\163\172\151\147\156\157\056\150
-\165\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001
-\001\000\351\370\217\363\143\255\332\206\330\247\340\102\373\317
-\221\336\246\046\370\231\245\143\160\255\233\256\312\063\100\175
-\155\226\156\241\016\104\356\341\023\235\224\102\122\232\275\165
-\205\164\054\250\016\035\223\266\030\267\214\054\250\317\373\134
-\161\271\332\354\376\350\176\217\344\057\035\262\250\165\207\330
-\267\241\345\073\317\231\112\106\320\203\031\175\300\241\022\034
-\225\155\112\364\330\307\245\115\063\056\205\071\100\165\176\024
-\174\200\022\230\120\307\101\147\270\240\200\141\124\246\154\116
-\037\340\235\016\007\351\311\272\063\347\376\300\125\050\054\002
-\200\247\031\365\236\334\125\123\003\227\173\007\110\377\231\373
-\067\212\044\304\131\314\120\020\143\216\252\251\032\260\204\032
-\206\371\137\273\261\120\156\244\321\012\314\325\161\176\037\247
-\033\174\365\123\156\042\137\313\053\346\324\174\135\256\326\302
-\306\114\345\005\001\331\355\127\374\301\043\171\374\372\310\044
-\203\225\363\265\152\121\001\320\167\326\351\022\241\371\032\203
-\373\202\033\271\260\227\364\166\006\063\103\111\240\377\013\265
-\372\265\002\003\001\000\001\243\201\200\060\176\060\017\006\003
-\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016\006
-\003\125\035\017\001\001\377\004\004\003\002\001\006\060\035\006
-\003\125\035\016\004\026\004\024\313\017\306\337\102\103\314\075
-\313\265\110\043\241\032\172\246\052\273\064\150\060\037\006\003
-\125\035\043\004\030\060\026\200\024\313\017\306\337\102\103\314
-\075\313\265\110\043\241\032\172\246\052\273\064\150\060\033\006
-\003\125\035\021\004\024\060\022\201\020\151\156\146\157\100\145
-\055\163\172\151\147\156\157\056\150\165\060\015\006\011\052\206
-\110\206\367\015\001\001\013\005\000\003\202\001\001\000\311\321
-\016\136\056\325\314\263\174\076\313\374\075\377\015\050\225\223
-\004\310\277\332\315\171\270\103\220\360\244\276\357\362\357\041
-\230\274\324\324\135\006\366\356\102\354\060\154\240\252\251\312
-\361\257\212\372\077\013\163\152\076\352\056\100\176\037\256\124
-\141\171\353\056\010\067\327\043\363\214\237\276\035\261\341\244
-\165\333\240\342\124\024\261\272\034\051\244\030\366\022\272\242
-\024\024\343\061\065\310\100\377\267\340\005\166\127\301\034\131
-\362\370\277\344\355\045\142\134\204\360\176\176\037\263\276\371
-\267\041\021\314\003\001\126\160\247\020\222\036\033\064\201\036
-\255\234\032\303\004\074\355\002\141\326\036\006\363\137\072\207
-\362\053\361\105\207\345\075\254\321\307\127\204\275\153\256\334
-\330\371\266\033\142\160\013\075\066\311\102\362\062\327\172\141
-\346\322\333\075\317\310\251\311\233\334\333\130\104\327\157\070
-\257\177\170\323\243\255\032\165\272\034\301\066\174\217\036\155
-\034\303\165\106\256\065\005\246\366\134\075\041\356\126\360\311
-\202\042\055\172\124\253\160\303\175\042\145\202\160\226
-END
-
-# Trust for Certificate "Microsec e-Szigno Root CA 2009"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Microsec e-Szigno Root CA 2009"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\211\337\164\376\134\364\017\112\200\371\343\067\175\124\332\221
-\341\001\061\216
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\370\111\364\003\274\104\055\203\276\110\151\175\051\144\374\261
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\110\125
-\061\021\060\017\006\003\125\004\007\014\010\102\165\144\141\160
-\145\163\164\061\026\060\024\006\003\125\004\012\014\015\115\151
-\143\162\157\163\145\143\040\114\164\144\056\061\047\060\045\006
-\003\125\004\003\014\036\115\151\143\162\157\163\145\143\040\145
-\055\123\172\151\147\156\157\040\122\157\157\164\040\103\101\040
-\062\060\060\071\061\037\060\035\006\011\052\206\110\206\367\015
-\001\011\001\026\020\151\156\146\157\100\145\055\163\172\151\147
-\156\157\056\150\165
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\302\176\103\004\116\107\077\031
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\124\122\061
-\050\060\046\006\003\125\004\012\023\037\105\154\145\153\164\162
-\157\156\151\153\040\102\151\154\147\151\040\107\165\166\145\156
-\154\151\147\151\040\101\056\123\056\061\074\060\072\006\003\125
-\004\003\023\063\145\055\107\165\166\145\156\040\113\157\153\040
-\105\154\145\153\164\162\157\156\151\153\040\123\145\162\164\151
-\146\151\153\141\040\110\151\172\155\145\164\040\123\141\147\154
-\141\171\151\143\151\163\151
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\124\122\061
-\050\060\046\006\003\125\004\012\023\037\105\154\145\153\164\162
-\157\156\151\153\040\102\151\154\147\151\040\107\165\166\145\156
-\154\151\147\151\040\101\056\123\056\061\074\060\072\006\003\125
-\004\003\023\063\145\055\107\165\166\145\156\040\113\157\153\040
-\105\154\145\153\164\162\157\156\151\153\040\123\145\162\164\151
-\146\151\153\141\040\110\151\172\155\145\164\040\123\141\147\154
-\141\171\151\143\151\163\151
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\231\215\074\300\003\047\275\234\166\225\271\352\333
-\254\265
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\266\060\202\002\236\240\003\002\001\002\002\020\104
-\231\215\074\300\003\047\275\234\166\225\271\352\333\254\265\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\165
-\061\013\060\011\006\003\125\004\006\023\002\124\122\061\050\060
-\046\006\003\125\004\012\023\037\105\154\145\153\164\162\157\156
-\151\153\040\102\151\154\147\151\040\107\165\166\145\156\154\151
-\147\151\040\101\056\123\056\061\074\060\072\006\003\125\004\003
-\023\063\145\055\107\165\166\145\156\040\113\157\153\040\105\154
-\145\153\164\162\157\156\151\153\040\123\145\162\164\151\146\151
-\153\141\040\110\151\172\155\145\164\040\123\141\147\154\141\171
-\151\143\151\163\151\060\036\027\015\060\067\060\061\060\064\061
-\061\063\062\064\070\132\027\015\061\067\060\061\060\064\061\061
-\063\062\064\070\132\060\165\061\013\060\011\006\003\125\004\006
-\023\002\124\122\061\050\060\046\006\003\125\004\012\023\037\105
-\154\145\153\164\162\157\156\151\153\040\102\151\154\147\151\040
-\107\165\166\145\156\154\151\147\151\040\101\056\123\056\061\074
-\060\072\006\003\125\004\003\023\063\145\055\107\165\166\145\156
-\040\113\157\153\040\105\154\145\153\164\162\157\156\151\153\040
-\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145\164
-\040\123\141\147\154\141\171\151\143\151\163\151\060\202\001\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\001\017\000\060\202\001\012\002\202\001\001\000\303\022\040
-\236\260\136\000\145\215\116\106\273\200\134\351\054\006\227\325
-\363\162\311\160\271\347\113\145\200\301\113\276\176\074\327\124
-\061\224\336\325\022\272\123\026\002\352\130\143\357\133\330\363
-\355\052\032\252\161\110\243\334\020\055\137\137\353\134\113\234
-\226\010\102\045\050\021\314\212\132\142\001\120\325\353\011\123
-\057\370\303\217\376\263\374\375\235\242\343\137\175\276\355\013
-\340\140\353\151\354\063\355\330\215\373\022\111\203\000\311\213
-\227\214\073\163\052\062\263\022\367\271\115\362\364\115\155\307
-\346\326\046\067\010\362\331\375\153\134\243\345\110\134\130\274
-\102\276\003\132\201\272\034\065\014\000\323\365\043\176\161\060
-\010\046\070\334\045\021\107\055\363\272\043\020\245\277\274\002
-\367\103\136\307\376\260\067\120\231\173\017\223\316\346\103\054
-\303\176\015\362\034\103\146\140\313\141\061\107\207\243\117\256
-\275\126\154\114\274\274\370\005\312\144\364\351\064\241\054\265
-\163\341\302\076\350\310\311\064\045\010\134\363\355\246\307\224
-\237\255\210\103\045\327\341\071\140\376\254\071\131\002\003\001
-\000\001\243\102\060\100\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026
-\004\024\237\356\104\263\224\325\372\221\117\056\331\125\232\004
-\126\333\055\304\333\245\060\015\006\011\052\206\110\206\367\015
-\001\001\005\005\000\003\202\001\001\000\177\137\271\123\133\143
-\075\165\062\347\372\304\164\032\313\106\337\106\151\034\122\317
-\252\117\302\150\353\377\200\251\121\350\075\142\167\211\075\012
-\165\071\361\156\135\027\207\157\150\005\301\224\154\331\135\337
-\332\262\131\313\245\020\212\312\314\071\315\237\353\116\336\122
-\377\014\360\364\222\251\362\154\123\253\233\322\107\240\037\164
-\367\233\232\361\057\025\237\172\144\060\030\007\074\052\017\147
-\312\374\017\211\141\235\145\245\074\345\274\023\133\010\333\343
-\377\355\273\006\273\152\006\261\172\117\145\306\202\375\036\234
-\213\265\015\356\110\273\270\275\252\010\264\373\243\174\313\237
-\315\220\166\134\206\226\170\127\012\146\371\130\032\235\375\227
-\051\140\336\021\246\220\034\031\034\356\001\226\042\064\064\056
-\221\371\267\304\047\321\173\346\277\373\200\104\132\026\345\353
-\340\324\012\070\274\344\221\343\325\353\134\301\254\337\033\152
-\174\236\345\165\322\266\227\207\333\314\207\053\103\072\204\010
-\257\253\074\333\367\074\146\061\206\260\235\123\171\355\370\043
-\336\102\343\055\202\361\017\345\372\227
-END
-
-# Trust for Certificate "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\335\341\322\251\001\200\056\035\207\136\204\263\200\176\113\261
-\375\231\101\064
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\075\101\051\313\036\252\021\164\315\135\260\142\257\260\103\133
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\124\122\061
-\050\060\046\006\003\125\004\012\023\037\105\154\145\153\164\162
-\157\156\151\153\040\102\151\154\147\151\040\107\165\166\145\156
-\154\151\147\151\040\101\056\123\056\061\074\060\072\006\003\125
-\004\003\023\063\145\055\107\165\166\145\156\040\113\157\153\040
-\105\154\145\153\164\162\157\156\151\153\040\123\145\162\164\151
-\146\151\153\141\040\110\151\172\155\145\164\040\123\141\147\154
-\141\171\151\143\151\163\151
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\104\231\215\074\300\003\047\275\234\166\225\271\352\333
-\254\265
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "GlobalSign Root CA - R3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GlobalSign Root CA - R3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\114\061\040\060\036\006\003\125\004\013\023\027\107\154\157
-\142\141\154\123\151\147\156\040\122\157\157\164\040\103\101\040
-\055\040\122\063\061\023\060\021\006\003\125\004\012\023\012\107
-\154\157\142\141\154\123\151\147\156\061\023\060\021\006\003\125
-\004\003\023\012\107\154\157\142\141\154\123\151\147\156
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\114\061\040\060\036\006\003\125\004\013\023\027\107\154\157
-\142\141\154\123\151\147\156\040\122\157\157\164\040\103\101\040
-\055\040\122\063\061\023\060\021\006\003\125\004\012\023\012\107
-\154\157\142\141\154\123\151\147\156\061\023\060\021\006\003\125
-\004\003\023\012\107\154\157\142\141\154\123\151\147\156
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\013\004\000\000\000\000\001\041\130\123\010\242
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\137\060\202\002\107\240\003\002\001\002\002\013\004
-\000\000\000\000\001\041\130\123\010\242\060\015\006\011\052\206
-\110\206\367\015\001\001\013\005\000\060\114\061\040\060\036\006
-\003\125\004\013\023\027\107\154\157\142\141\154\123\151\147\156
-\040\122\157\157\164\040\103\101\040\055\040\122\063\061\023\060
-\021\006\003\125\004\012\023\012\107\154\157\142\141\154\123\151
-\147\156\061\023\060\021\006\003\125\004\003\023\012\107\154\157
-\142\141\154\123\151\147\156\060\036\027\015\060\071\060\063\061
-\070\061\060\060\060\060\060\132\027\015\062\071\060\063\061\070
-\061\060\060\060\060\060\132\060\114\061\040\060\036\006\003\125
-\004\013\023\027\107\154\157\142\141\154\123\151\147\156\040\122
-\157\157\164\040\103\101\040\055\040\122\063\061\023\060\021\006
-\003\125\004\012\023\012\107\154\157\142\141\154\123\151\147\156
-\061\023\060\021\006\003\125\004\003\023\012\107\154\157\142\141
-\154\123\151\147\156\060\202\001\042\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001
-\012\002\202\001\001\000\314\045\166\220\171\006\170\042\026\365
-\300\203\266\204\312\050\236\375\005\166\021\305\255\210\162\374
-\106\002\103\307\262\212\235\004\137\044\313\056\113\341\140\202
-\106\341\122\253\014\201\107\160\154\335\144\321\353\365\054\243
-\017\202\075\014\053\256\227\327\266\024\206\020\171\273\073\023
-\200\167\214\010\341\111\322\152\142\057\037\136\372\226\150\337
-\211\047\225\070\237\006\327\076\311\313\046\131\015\163\336\260
-\310\351\046\016\203\025\306\357\133\213\322\004\140\312\111\246
-\050\366\151\073\366\313\310\050\221\345\235\212\141\127\067\254
-\164\024\334\164\340\072\356\162\057\056\234\373\320\273\277\365
-\075\000\341\006\063\350\202\053\256\123\246\072\026\163\214\335
-\101\016\040\072\300\264\247\241\351\262\117\220\056\062\140\351
-\127\313\271\004\222\150\150\345\070\046\140\165\262\237\167\377
-\221\024\357\256\040\111\374\255\100\025\110\321\002\061\141\031
-\136\270\227\357\255\167\267\144\232\172\277\137\301\023\357\233
-\142\373\015\154\340\124\151\026\251\003\332\156\351\203\223\161
-\166\306\151\205\202\027\002\003\001\000\001\243\102\060\100\060
-\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060
-\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377
-\060\035\006\003\125\035\016\004\026\004\024\217\360\113\177\250
-\056\105\044\256\115\120\372\143\232\213\336\342\335\033\274\060
-\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202
-\001\001\000\113\100\333\300\120\252\376\310\014\357\367\226\124
-\105\111\273\226\000\011\101\254\263\023\206\206\050\007\063\312
-\153\346\164\271\272\000\055\256\244\012\323\365\361\361\017\212
-\277\163\147\112\203\307\104\173\170\340\257\156\154\157\003\051
-\216\063\071\105\303\216\344\271\127\154\252\374\022\226\354\123
-\306\055\344\044\154\271\224\143\373\334\123\150\147\126\076\203
-\270\317\065\041\303\311\150\376\316\332\302\123\252\314\220\212
-\351\360\135\106\214\225\335\172\130\050\032\057\035\336\315\000
-\067\101\217\355\104\155\327\123\050\227\176\363\147\004\036\025
-\327\212\226\264\323\336\114\047\244\114\033\163\163\166\364\027
-\231\302\037\172\016\343\055\010\255\012\034\054\377\074\253\125
-\016\017\221\176\066\353\303\127\111\276\341\056\055\174\140\213
-\303\101\121\023\043\235\316\367\062\153\224\001\250\231\347\054
-\063\037\072\073\045\322\206\100\316\073\054\206\170\311\141\057
-\024\272\356\333\125\157\337\204\356\005\011\115\275\050\330\162
-\316\323\142\120\145\036\353\222\227\203\061\331\263\265\312\107
-\130\077\137
-END
-
-# Trust for Certificate "GlobalSign Root CA - R3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "GlobalSign Root CA - R3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\326\233\126\021\110\360\034\167\305\105\170\301\011\046\337\133
-\205\151\166\255
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\305\337\270\111\312\005\023\125\356\055\272\032\303\076\260\050
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\114\061\040\060\036\006\003\125\004\013\023\027\107\154\157
-\142\141\154\123\151\147\156\040\122\157\157\164\040\103\101\040
-\055\040\122\063\061\023\060\021\006\003\125\004\012\023\012\107
-\154\157\142\141\154\123\151\147\156\061\023\060\021\006\003\125
-\004\003\023\012\107\154\157\142\141\154\123\151\147\156
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\013\004\000\000\000\000\001\041\130\123\010\242
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TC TrustCenter Universal CA III"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Universal CA III"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\173\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\044\060
-\042\006\003\125\004\013\023\033\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\125\156\151\166\145\162\163\141\154
-\040\103\101\061\050\060\046\006\003\125\004\003\023\037\124\103
-\040\124\162\165\163\164\103\145\156\164\145\162\040\125\156\151
-\166\145\162\163\141\154\040\103\101\040\111\111\111
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\173\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\044\060
-\042\006\003\125\004\013\023\033\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\125\156\151\166\145\162\163\141\154
-\040\103\101\061\050\060\046\006\003\125\004\003\023\037\124\103
-\040\124\162\165\163\164\103\145\156\164\145\162\040\125\156\151
-\166\145\162\163\141\154\040\103\101\040\111\111\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\143\045\000\001\000\002\024\215\063\025\002\344\154\364
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\341\060\202\002\311\240\003\002\001\002\002\016\143
-\045\000\001\000\002\024\215\063\025\002\344\154\364\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\060\173\061\013
-\060\011\006\003\125\004\006\023\002\104\105\061\034\060\032\006
-\003\125\004\012\023\023\124\103\040\124\162\165\163\164\103\145
-\156\164\145\162\040\107\155\142\110\061\044\060\042\006\003\125
-\004\013\023\033\124\103\040\124\162\165\163\164\103\145\156\164
-\145\162\040\125\156\151\166\145\162\163\141\154\040\103\101\061
-\050\060\046\006\003\125\004\003\023\037\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\125\156\151\166\145\162\163
-\141\154\040\103\101\040\111\111\111\060\036\027\015\060\071\060
-\071\060\071\060\070\061\065\062\067\132\027\015\062\071\061\062
-\063\061\062\063\065\071\065\071\132\060\173\061\013\060\011\006
-\003\125\004\006\023\002\104\105\061\034\060\032\006\003\125\004
-\012\023\023\124\103\040\124\162\165\163\164\103\145\156\164\145
-\162\040\107\155\142\110\061\044\060\042\006\003\125\004\013\023
-\033\124\103\040\124\162\165\163\164\103\145\156\164\145\162\040
-\125\156\151\166\145\162\163\141\154\040\103\101\061\050\060\046
-\006\003\125\004\003\023\037\124\103\040\124\162\165\163\164\103
-\145\156\164\145\162\040\125\156\151\166\145\162\163\141\154\040
-\103\101\040\111\111\111\060\202\001\042\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202
-\001\012\002\202\001\001\000\302\332\234\142\260\271\161\022\260
-\013\310\032\127\262\256\203\024\231\263\064\113\233\220\242\305
-\347\347\057\002\240\115\055\244\372\205\332\233\045\205\055\100
-\050\040\155\352\340\275\261\110\203\042\051\104\237\116\203\356
-\065\121\023\163\164\325\274\362\060\146\224\123\300\100\066\057
-\014\204\145\316\017\156\302\130\223\350\054\013\072\351\301\216
-\373\362\153\312\074\342\234\116\216\344\371\175\323\047\237\033
-\325\147\170\207\055\177\013\107\263\307\350\311\110\174\257\057
-\314\012\331\101\357\237\376\232\341\262\256\371\123\265\345\351
-\106\237\140\343\337\215\323\177\373\226\176\263\265\162\370\113
-\255\010\171\315\151\211\100\047\365\052\301\255\103\354\244\123
-\310\141\266\367\322\171\052\147\030\166\110\155\133\045\001\321
-\046\305\267\127\151\043\025\133\141\212\255\360\033\055\331\257
-\134\361\046\220\151\251\325\014\100\365\063\200\103\217\234\243
-\166\052\105\264\257\277\177\076\207\077\166\305\315\052\336\040
-\305\026\130\313\371\033\365\017\313\015\021\122\144\270\322\166
-\142\167\203\361\130\237\377\002\003\001\000\001\243\143\060\141
-\060\037\006\003\125\035\043\004\030\060\026\200\024\126\347\341
-\133\045\103\200\340\366\214\341\161\274\216\345\200\057\304\110
-\342\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
-\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002
-\001\006\060\035\006\003\125\035\016\004\026\004\024\126\347\341
-\133\045\103\200\340\366\214\341\161\274\216\345\200\057\304\110
-\342\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\202\001\001\000\203\307\257\352\177\115\012\074\071\261\150
-\276\173\155\211\056\351\263\011\347\030\127\215\205\232\027\363
-\166\102\120\023\017\307\220\157\063\255\305\111\140\053\154\111
-\130\031\324\342\276\267\277\253\111\274\224\310\253\276\050\154
-\026\150\340\310\227\106\040\240\150\147\140\210\071\040\121\330
-\150\001\021\316\247\366\021\007\366\354\354\254\032\037\262\146
-\156\126\147\140\172\164\136\300\155\227\066\256\265\015\135\146
-\163\300\045\062\105\330\112\006\007\217\304\267\007\261\115\006
-\015\341\245\353\364\165\312\272\234\320\275\263\323\062\044\114
-\356\176\342\166\004\113\111\123\330\362\351\124\063\374\345\161
-\037\075\024\134\226\113\361\072\362\000\273\154\264\372\226\125
-\010\210\011\301\314\221\031\051\260\040\055\377\313\070\244\100
-\341\027\276\171\141\200\377\007\003\206\114\116\173\006\237\021
-\206\215\211\356\047\304\333\342\274\031\216\013\303\303\023\307
-\055\003\143\073\323\350\344\242\052\302\202\010\224\026\124\360
-\357\037\047\220\045\270\015\016\050\033\107\167\107\275\034\250
-\045\361\224\264\146
-END
-
-# Trust for Certificate "TC TrustCenter Universal CA III"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Universal CA III"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\226\126\315\173\127\226\230\225\320\341\101\106\150\006\373\270
-\306\021\006\207
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\237\335\333\253\377\216\377\105\041\137\360\154\235\217\376\053
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\173\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\044\060
-\042\006\003\125\004\013\023\033\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\125\156\151\166\145\162\163\141\154
-\040\103\101\061\050\060\046\006\003\125\004\003\023\037\124\103
-\040\124\162\165\163\164\103\145\156\164\145\162\040\125\156\151
-\166\145\162\163\141\154\040\103\101\040\111\111\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\143\045\000\001\000\002\024\215\063\025\002\344\154\364
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Autoridad de Certificacion Firmaprofesional CIF A62634068"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Autoridad de Certificacion Firmaprofesional CIF A62634068"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\121\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\102\060\100\006\003\125\004\003\014\071\101\165\164\157\162\151
-\144\141\144\040\144\145\040\103\145\162\164\151\146\151\143\141
-\143\151\157\156\040\106\151\162\155\141\160\162\157\146\145\163
-\151\157\156\141\154\040\103\111\106\040\101\066\062\066\063\064
-\060\066\070
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\121\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\102\060\100\006\003\125\004\003\014\071\101\165\164\157\162\151
-\144\141\144\040\144\145\040\103\145\162\164\151\146\151\143\141
-\143\151\157\156\040\106\151\162\155\141\160\162\157\146\145\163
-\151\157\156\141\154\040\103\111\106\040\101\066\062\066\063\064
-\060\066\070
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\123\354\073\356\373\262\110\137
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\006\024\060\202\003\374\240\003\002\001\002\002\010\123
-\354\073\356\373\262\110\137\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\060\121\061\013\060\011\006\003\125\004
-\006\023\002\105\123\061\102\060\100\006\003\125\004\003\014\071
-\101\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162
-\164\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141
-\160\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040
-\101\066\062\066\063\064\060\066\070\060\036\027\015\060\071\060
-\065\062\060\060\070\063\070\061\065\132\027\015\063\060\061\062
-\063\061\060\070\063\070\061\065\132\060\121\061\013\060\011\006
-\003\125\004\006\023\002\105\123\061\102\060\100\006\003\125\004
-\003\014\071\101\165\164\157\162\151\144\141\144\040\144\145\040
-\103\145\162\164\151\146\151\143\141\143\151\157\156\040\106\151
-\162\155\141\160\162\157\146\145\163\151\157\156\141\154\040\103
-\111\106\040\101\066\062\066\063\064\060\066\070\060\202\002\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\002\017\000\060\202\002\012\002\202\002\001\000\312\226\153
-\216\352\370\373\361\242\065\340\177\114\332\340\303\122\327\175
-\266\020\310\002\136\263\103\052\304\117\152\262\312\034\135\050
-\232\170\021\032\151\131\127\257\265\040\102\344\213\017\346\337
-\133\246\003\222\057\365\021\344\142\327\062\161\070\331\004\014
-\161\253\075\121\176\017\007\337\143\005\134\351\277\224\157\301
-\051\202\300\264\332\121\260\301\074\273\255\067\112\134\312\361
-\113\066\016\044\253\277\303\204\167\375\250\120\364\261\347\306
-\057\322\055\131\215\172\012\116\226\151\122\002\252\066\230\354
-\374\372\024\203\014\067\037\311\222\067\177\327\201\055\345\304
-\271\340\076\064\376\147\364\076\146\321\323\364\100\317\136\142
-\064\017\160\006\076\040\030\132\316\367\162\033\045\154\223\164
-\024\223\243\163\261\016\252\207\020\043\131\137\040\005\031\107
-\355\150\216\222\022\312\135\374\326\053\262\222\074\040\317\341
-\137\257\040\276\240\166\177\166\345\354\032\206\141\063\076\347
-\173\264\077\240\017\216\242\271\152\157\271\207\046\157\101\154
-\210\246\120\375\152\143\013\365\223\026\033\031\217\262\355\233
-\233\311\220\365\001\014\337\031\075\017\076\070\043\311\057\217
-\014\321\002\376\033\125\326\116\320\215\074\257\117\244\363\376
-\257\052\323\005\235\171\010\241\313\127\061\264\234\310\220\262
-\147\364\030\026\223\072\374\107\330\321\170\226\061\037\272\053
-\014\137\135\231\255\143\211\132\044\040\166\330\337\375\253\116
-\246\042\252\235\136\346\047\212\175\150\051\243\347\212\270\332
-\021\273\027\055\231\235\023\044\106\367\305\342\330\237\216\177
-\307\217\164\155\132\262\350\162\365\254\356\044\020\255\057\024
-\332\377\055\232\106\161\107\276\102\337\273\001\333\364\177\323
-\050\217\061\131\133\323\311\002\246\264\122\312\156\227\373\103
-\305\010\046\157\212\364\273\375\237\050\252\015\325\105\363\023
-\072\035\330\300\170\217\101\147\074\036\224\144\256\173\013\305
-\350\331\001\210\071\032\227\206\144\101\325\073\207\014\156\372
-\017\306\275\110\024\277\071\115\324\236\101\266\217\226\035\143
-\226\223\331\225\006\170\061\150\236\067\006\073\200\211\105\141
-\071\043\307\033\104\243\025\345\034\370\222\060\273\002\003\001
-\000\001\243\201\357\060\201\354\060\022\006\003\125\035\023\001
-\001\377\004\010\060\006\001\001\377\002\001\001\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003
-\125\035\016\004\026\004\024\145\315\353\253\065\036\000\076\176
-\325\164\300\034\264\163\107\016\032\144\057\060\201\246\006\003
-\125\035\040\004\201\236\060\201\233\060\201\230\006\004\125\035
-\040\000\060\201\217\060\057\006\010\053\006\001\005\005\007\002
-\001\026\043\150\164\164\160\072\057\057\167\167\167\056\146\151
-\162\155\141\160\162\157\146\145\163\151\157\156\141\154\056\143
-\157\155\057\143\160\163\060\134\006\010\053\006\001\005\005\007
-\002\002\060\120\036\116\000\120\000\141\000\163\000\145\000\157
-\000\040\000\144\000\145\000\040\000\154\000\141\000\040\000\102
-\000\157\000\156\000\141\000\156\000\157\000\166\000\141\000\040
-\000\064\000\067\000\040\000\102\000\141\000\162\000\143\000\145
-\000\154\000\157\000\156\000\141\000\040\000\060\000\070\000\060
-\000\061\000\067\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\003\202\002\001\000\027\175\240\371\264\335\305\305
-\353\255\113\044\265\241\002\253\335\245\210\112\262\017\125\113
-\053\127\214\073\345\061\335\376\304\062\361\347\133\144\226\066
-\062\030\354\245\062\167\327\343\104\266\300\021\052\200\271\075
-\152\156\174\233\323\255\374\303\326\243\346\144\051\174\321\341
-\070\036\202\053\377\047\145\257\373\026\025\304\056\161\204\345
-\265\377\372\244\107\275\144\062\273\366\045\204\242\047\102\365
-\040\260\302\023\020\021\315\020\025\272\102\220\052\322\104\341
-\226\046\353\061\110\022\375\052\332\311\006\317\164\036\251\113
-\325\207\050\371\171\064\222\076\056\104\350\366\217\117\217\065
-\077\045\263\071\334\143\052\220\153\040\137\304\122\022\116\227
-\054\052\254\235\227\336\110\362\243\146\333\302\322\203\225\246
-\146\247\236\045\017\351\013\063\221\145\012\132\303\331\124\022
-\335\257\303\116\016\037\046\136\015\334\263\215\354\325\201\160
-\336\322\117\044\005\363\154\116\365\114\111\146\215\321\377\322
-\013\045\101\110\376\121\204\306\102\257\200\004\317\320\176\144
-\111\344\362\337\242\354\261\114\300\052\035\347\264\261\145\242
-\304\274\361\230\364\252\160\007\143\264\270\332\073\114\372\100
-\042\060\133\021\246\360\005\016\306\002\003\110\253\206\233\205
-\335\333\335\352\242\166\200\163\175\365\234\004\304\105\215\347
-\271\034\213\236\352\327\165\321\162\261\336\165\104\347\102\175
-\342\127\153\175\334\231\274\075\203\050\352\200\223\215\305\114
-\145\301\160\201\270\070\374\103\061\262\366\003\064\107\262\254
-\373\042\006\313\036\335\027\107\034\137\146\271\323\032\242\332
-\021\261\244\274\043\311\344\276\207\377\271\224\266\370\135\040
-\112\324\137\347\275\150\173\145\362\025\036\322\072\251\055\351
-\330\153\044\254\227\130\104\107\255\131\030\361\041\145\160\336
-\316\064\140\250\100\361\363\074\244\303\050\043\214\376\047\063
-\103\100\240\027\074\353\352\073\260\162\246\243\271\112\113\136
-\026\110\364\262\274\310\214\222\305\235\237\254\162\066\274\064
-\200\064\153\251\213\222\300\270\027\355\354\166\123\365\044\001
-\214\263\042\350\113\174\125\306\235\372\243\024\273\145\205\156
-\156\117\022\176\012\074\235\225
-END
-
-# Trust for Certificate "Autoridad de Certificacion Firmaprofesional CIF A62634068"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Autoridad de Certificacion Firmaprofesional CIF A62634068"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\256\305\373\077\310\341\277\304\345\117\003\007\132\232\350\000
-\267\367\266\372
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\163\072\164\172\354\273\243\226\246\302\344\342\310\233\300\303
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\121\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\102\060\100\006\003\125\004\003\014\071\101\165\164\157\162\151
-\144\141\144\040\144\145\040\103\145\162\164\151\146\151\143\141
-\143\151\157\156\040\106\151\162\155\141\160\162\157\146\145\163
-\151\157\156\141\154\040\103\111\106\040\101\066\062\066\063\064
-\060\066\070
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\123\354\073\356\373\262\110\137
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Izenpe.com"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Izenpe.com"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\070\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\024\060\022\006\003\125\004\012\014\013\111\132\105\116\120\105
-\040\123\056\101\056\061\023\060\021\006\003\125\004\003\014\012
-\111\172\145\156\160\145\056\143\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\070\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\024\060\022\006\003\125\004\012\014\013\111\132\105\116\120\105
-\040\123\056\101\056\061\023\060\021\006\003\125\004\003\014\012
-\111\172\145\156\160\145\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\000\260\267\132\026\110\137\277\341\313\365\213\327\031
-\346\175
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\361\060\202\003\331\240\003\002\001\002\002\020\000
-\260\267\132\026\110\137\277\341\313\365\213\327\031\346\175\060
-\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\070
-\061\013\060\011\006\003\125\004\006\023\002\105\123\061\024\060
-\022\006\003\125\004\012\014\013\111\132\105\116\120\105\040\123
-\056\101\056\061\023\060\021\006\003\125\004\003\014\012\111\172
-\145\156\160\145\056\143\157\155\060\036\027\015\060\067\061\062
-\061\063\061\063\060\070\062\070\132\027\015\063\067\061\062\061
-\063\060\070\062\067\062\065\132\060\070\061\013\060\011\006\003
-\125\004\006\023\002\105\123\061\024\060\022\006\003\125\004\012
-\014\013\111\132\105\116\120\105\040\123\056\101\056\061\023\060
-\021\006\003\125\004\003\014\012\111\172\145\156\160\145\056\143
-\157\155\060\202\002\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202
-\002\001\000\311\323\172\312\017\036\254\247\206\350\026\145\152
-\261\302\033\105\062\161\225\331\376\020\133\314\257\347\245\171
-\001\217\211\303\312\362\125\161\367\167\276\167\224\363\162\244
-\054\104\330\236\222\233\024\072\241\347\044\220\012\012\126\216
-\305\330\046\224\341\331\110\341\055\076\332\012\162\335\243\231
-\025\332\201\242\207\364\173\156\046\167\211\130\255\326\353\014
-\262\101\172\163\156\155\333\172\170\101\351\010\210\022\176\207
-\056\146\021\143\154\124\373\074\235\162\300\274\056\377\302\267
-\335\015\166\343\072\327\367\264\150\276\242\365\343\201\156\301
-\106\157\135\215\340\115\306\124\125\211\032\063\061\012\261\127
-\271\243\212\230\303\354\073\064\305\225\101\151\176\165\302\074
-\040\305\141\272\121\107\240\040\220\223\241\220\113\363\116\174
-\205\105\124\232\321\005\046\101\260\265\115\035\063\276\304\003
-\310\045\174\301\160\333\073\364\011\055\124\047\110\254\057\341
-\304\254\076\310\313\222\114\123\071\067\043\354\323\001\371\340
-\011\104\115\115\144\300\341\015\132\207\042\274\255\033\243\376
-\046\265\025\363\247\374\204\031\351\354\241\210\264\104\151\204
-\203\363\211\321\164\006\251\314\013\326\302\336\047\205\120\046
-\312\027\270\311\172\207\126\054\032\001\036\154\276\023\255\020
-\254\265\044\365\070\221\241\326\113\332\361\273\322\336\107\265
-\361\274\201\366\131\153\317\031\123\351\215\025\313\112\313\251
-\157\104\345\033\101\317\341\206\247\312\320\152\237\274\114\215
-\006\063\132\242\205\345\220\065\240\142\134\026\116\360\343\242
-\372\003\032\264\054\161\263\130\054\336\173\013\333\032\017\353
-\336\041\037\006\167\006\003\260\311\357\231\374\300\271\117\013
-\206\050\376\322\271\352\343\332\245\303\107\151\022\340\333\360
-\366\031\213\355\173\160\327\002\326\355\207\030\050\054\004\044
-\114\167\344\110\212\032\306\073\232\324\017\312\372\165\322\001
-\100\132\215\171\277\213\317\113\317\252\026\301\225\344\255\114
-\212\076\027\221\324\261\142\345\202\345\200\004\244\003\176\215
-\277\332\177\242\017\227\117\014\323\015\373\327\321\345\162\176
-\034\310\167\377\133\232\017\267\256\005\106\345\361\250\026\354
-\107\244\027\002\003\001\000\001\243\201\366\060\201\363\060\201
-\260\006\003\125\035\021\004\201\250\060\201\245\201\017\151\156
-\146\157\100\151\172\145\156\160\145\056\143\157\155\244\201\221
-\060\201\216\061\107\060\105\006\003\125\004\012\014\076\111\132
-\105\116\120\105\040\123\056\101\056\040\055\040\103\111\106\040
-\101\060\061\063\063\067\062\066\060\055\122\115\145\162\143\056
-\126\151\164\157\162\151\141\055\107\141\163\164\145\151\172\040
-\124\061\060\065\065\040\106\066\062\040\123\070\061\103\060\101
-\006\003\125\004\011\014\072\101\166\144\141\040\144\145\154\040
-\115\145\144\151\164\145\162\162\141\156\145\157\040\105\164\157
-\162\142\151\144\145\141\040\061\064\040\055\040\060\061\060\061
-\060\040\126\151\164\157\162\151\141\055\107\141\163\164\145\151
-\172\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
-\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002
-\001\006\060\035\006\003\125\035\016\004\026\004\024\035\034\145
-\016\250\362\045\173\264\221\317\344\261\261\346\275\125\164\154
-\005\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000
-\003\202\002\001\000\170\246\014\026\112\237\114\210\072\300\313
-\016\245\026\175\237\271\110\137\030\217\015\142\066\366\315\031
-\153\254\253\325\366\221\175\256\161\363\077\263\016\170\205\233
-\225\244\047\041\107\102\112\174\110\072\365\105\174\263\014\216
-\121\170\254\225\023\336\306\375\175\270\032\220\114\253\222\003
-\307\355\102\001\316\017\330\261\372\242\222\341\140\155\256\172
-\153\011\252\306\051\356\150\111\147\060\200\044\172\061\026\071
-\133\176\361\034\056\335\154\011\255\362\061\301\202\116\271\273
-\371\276\277\052\205\077\300\100\243\072\131\374\131\113\074\050
-\044\333\264\025\165\256\015\210\272\056\163\300\275\130\207\345
-\102\362\353\136\356\036\060\042\231\313\067\321\304\041\154\201
-\354\276\155\046\346\034\344\102\040\236\107\260\254\203\131\160
-\054\065\326\257\066\064\264\315\073\370\062\250\357\343\170\211
-\373\215\105\054\332\234\270\176\100\034\141\347\076\242\222\054
-\113\362\315\372\230\266\051\377\363\362\173\251\037\056\240\223
-\127\053\336\205\003\371\151\067\313\236\170\152\005\264\305\061
-\170\211\354\172\247\205\341\271\173\074\336\276\036\171\204\316
-\237\160\016\131\302\065\056\220\052\061\331\344\105\172\101\244
-\056\023\233\064\016\146\173\111\253\144\227\320\106\303\171\235
-\162\120\143\246\230\133\006\275\110\155\330\071\203\160\350\065
-\360\005\321\252\274\343\333\310\002\352\174\375\202\332\302\133
-\122\065\256\230\072\255\272\065\223\043\247\037\110\335\065\106
-\230\262\020\150\344\245\061\302\012\130\056\031\201\020\311\120
-\165\374\352\132\026\316\021\327\356\357\120\210\055\141\377\077
-\102\163\005\224\103\325\216\074\116\001\072\031\245\037\106\116
-\167\320\135\345\201\042\041\207\376\224\175\204\330\223\255\326
-\150\103\110\262\333\353\163\044\347\221\177\124\244\266\200\076
-\235\243\074\114\162\302\127\304\240\324\314\070\047\316\325\006
-\236\242\110\331\351\237\316\202\160\066\223\232\073\337\226\041
-\343\131\267\014\332\221\067\360\375\131\132\263\231\310\151\154
-\103\046\001\065\143\140\125\211\003\072\165\330\272\112\331\124
-\377\356\336\200\330\055\321\070\325\136\055\013\230\175\076\154
-\333\374\046\210\307
-END
-
-# Trust for Certificate "Izenpe.com"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Izenpe.com"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\057\170\075\045\122\030\247\112\145\071\161\265\054\242\234\105
-\025\157\351\031
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\246\260\315\205\200\332\134\120\064\243\071\220\057\125\147\163
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\070\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\024\060\022\006\003\125\004\012\014\013\111\132\105\116\120\105
-\040\123\056\101\056\061\023\060\021\006\003\125\004\003\014\012
-\111\172\145\156\160\145\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\000\260\267\132\026\110\137\277\341\313\365\213\327\031
-\346\175
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Chambers of Commerce Root - 2008"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Chambers of Commerce Root - 2008"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\105\125
-\061\103\060\101\006\003\125\004\007\023\072\115\141\144\162\151
-\144\040\050\163\145\145\040\143\165\162\162\145\156\164\040\141
-\144\144\162\145\163\163\040\141\164\040\167\167\167\056\143\141
-\155\145\162\146\151\162\155\141\056\143\157\155\057\141\144\144
-\162\145\163\163\051\061\022\060\020\006\003\125\004\005\023\011
-\101\070\062\067\064\063\062\070\067\061\033\060\031\006\003\125
-\004\012\023\022\101\103\040\103\141\155\145\162\146\151\162\155
-\141\040\123\056\101\056\061\051\060\047\006\003\125\004\003\023
-\040\103\150\141\155\142\145\162\163\040\157\146\040\103\157\155
-\155\145\162\143\145\040\122\157\157\164\040\055\040\062\060\060
-\070
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\105\125
-\061\103\060\101\006\003\125\004\007\023\072\115\141\144\162\151
-\144\040\050\163\145\145\040\143\165\162\162\145\156\164\040\141
-\144\144\162\145\163\163\040\141\164\040\167\167\167\056\143\141
-\155\145\162\146\151\162\155\141\056\143\157\155\057\141\144\144
-\162\145\163\163\051\061\022\060\020\006\003\125\004\005\023\011
-\101\070\062\067\064\063\062\070\067\061\033\060\031\006\003\125
-\004\012\023\022\101\103\040\103\141\155\145\162\146\151\162\155
-\141\040\123\056\101\056\061\051\060\047\006\003\125\004\003\023
-\040\103\150\141\155\142\145\162\163\040\157\146\040\103\157\155
-\155\145\162\143\145\040\122\157\157\164\040\055\040\062\060\060
-\070
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\243\332\102\176\244\261\256\332
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\007\117\060\202\005\067\240\003\002\001\002\002\011\000
-\243\332\102\176\244\261\256\332\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\060\201\256\061\013\060\011\006\003
-\125\004\006\023\002\105\125\061\103\060\101\006\003\125\004\007
-\023\072\115\141\144\162\151\144\040\050\163\145\145\040\143\165
-\162\162\145\156\164\040\141\144\144\162\145\163\163\040\141\164
-\040\167\167\167\056\143\141\155\145\162\146\151\162\155\141\056
-\143\157\155\057\141\144\144\162\145\163\163\051\061\022\060\020
-\006\003\125\004\005\023\011\101\070\062\067\064\063\062\070\067
-\061\033\060\031\006\003\125\004\012\023\022\101\103\040\103\141
-\155\145\162\146\151\162\155\141\040\123\056\101\056\061\051\060
-\047\006\003\125\004\003\023\040\103\150\141\155\142\145\162\163
-\040\157\146\040\103\157\155\155\145\162\143\145\040\122\157\157
-\164\040\055\040\062\060\060\070\060\036\027\015\060\070\060\070
-\060\061\061\062\062\071\065\060\132\027\015\063\070\060\067\063
-\061\061\062\062\071\065\060\132\060\201\256\061\013\060\011\006
-\003\125\004\006\023\002\105\125\061\103\060\101\006\003\125\004
-\007\023\072\115\141\144\162\151\144\040\050\163\145\145\040\143
-\165\162\162\145\156\164\040\141\144\144\162\145\163\163\040\141
-\164\040\167\167\167\056\143\141\155\145\162\146\151\162\155\141
-\056\143\157\155\057\141\144\144\162\145\163\163\051\061\022\060
-\020\006\003\125\004\005\023\011\101\070\062\067\064\063\062\070
-\067\061\033\060\031\006\003\125\004\012\023\022\101\103\040\103
-\141\155\145\162\146\151\162\155\141\040\123\056\101\056\061\051
-\060\047\006\003\125\004\003\023\040\103\150\141\155\142\145\162
-\163\040\157\146\040\103\157\155\155\145\162\143\145\040\122\157
-\157\164\040\055\040\062\060\060\070\060\202\002\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017
-\000\060\202\002\012\002\202\002\001\000\257\000\313\160\067\053
-\200\132\112\072\154\170\224\175\243\177\032\037\366\065\325\275
-\333\313\015\104\162\076\046\262\220\122\272\143\073\050\130\157
-\245\263\155\224\246\363\335\144\014\125\366\366\347\362\042\042
-\200\136\341\142\306\266\051\341\201\154\362\277\345\175\062\152
-\124\240\062\031\131\376\037\213\327\075\140\206\205\044\157\343
-\021\263\167\076\040\226\065\041\153\263\010\331\160\056\144\367
-\204\222\123\326\016\260\220\212\212\343\207\215\006\323\275\220
-\016\342\231\241\033\206\016\332\232\012\273\013\141\120\006\122
-\361\236\177\166\354\313\017\320\036\015\317\231\060\075\034\304
-\105\020\130\254\326\323\350\327\345\352\305\001\007\167\326\121
-\346\003\177\212\110\245\115\150\165\271\351\274\236\116\031\161
-\365\062\113\234\155\140\031\013\373\314\235\165\334\277\046\315
-\217\223\170\071\171\163\136\045\016\312\134\353\167\022\007\313
-\144\101\107\162\223\253\120\303\353\011\166\144\064\322\071\267
-\166\021\011\015\166\105\304\251\256\075\152\257\265\175\145\057
-\224\130\020\354\134\174\257\176\342\266\030\331\320\233\116\132
-\111\337\251\146\013\314\074\306\170\174\247\234\035\343\316\216
-\123\276\005\336\140\017\153\345\032\333\077\343\341\041\311\051
-\301\361\353\007\234\122\033\001\104\121\074\173\045\327\304\345
-\122\124\135\045\007\312\026\040\270\255\344\101\356\172\010\376
-\231\157\203\246\221\002\260\154\066\125\152\347\175\365\226\346
-\312\201\326\227\361\224\203\351\355\260\261\153\022\151\036\254
-\373\135\251\305\230\351\264\133\130\172\276\075\242\104\072\143
-\131\324\013\045\336\033\117\275\345\001\236\315\322\051\325\237
-\027\031\012\157\277\014\220\323\011\137\331\343\212\065\314\171
-\132\115\031\067\222\267\304\301\255\257\364\171\044\232\262\001
-\013\261\257\134\226\363\200\062\373\134\075\230\361\240\077\112
-\336\276\257\224\056\331\125\232\027\156\140\235\143\154\270\143
-\311\256\201\134\030\065\340\220\273\276\074\117\067\042\271\176
-\353\317\236\167\041\246\075\070\201\373\110\332\061\075\053\343
-\211\365\320\265\275\176\340\120\304\022\211\263\043\232\020\061
-\205\333\256\157\357\070\063\030\166\021\002\003\001\000\001\243
-\202\001\154\060\202\001\150\060\022\006\003\125\035\023\001\001
-\377\004\010\060\006\001\001\377\002\001\014\060\035\006\003\125
-\035\016\004\026\004\024\371\044\254\017\262\265\370\171\300\372
-\140\210\033\304\331\115\002\236\027\031\060\201\343\006\003\125
-\035\043\004\201\333\060\201\330\200\024\371\044\254\017\262\265
-\370\171\300\372\140\210\033\304\331\115\002\236\027\031\241\201
-\264\244\201\261\060\201\256\061\013\060\011\006\003\125\004\006
-\023\002\105\125\061\103\060\101\006\003\125\004\007\023\072\115
-\141\144\162\151\144\040\050\163\145\145\040\143\165\162\162\145
-\156\164\040\141\144\144\162\145\163\163\040\141\164\040\167\167
-\167\056\143\141\155\145\162\146\151\162\155\141\056\143\157\155
-\057\141\144\144\162\145\163\163\051\061\022\060\020\006\003\125
-\004\005\023\011\101\070\062\067\064\063\062\070\067\061\033\060
-\031\006\003\125\004\012\023\022\101\103\040\103\141\155\145\162
-\146\151\162\155\141\040\123\056\101\056\061\051\060\047\006\003
-\125\004\003\023\040\103\150\141\155\142\145\162\163\040\157\146
-\040\103\157\155\155\145\162\143\145\040\122\157\157\164\040\055
-\040\062\060\060\070\202\011\000\243\332\102\176\244\261\256\332
-\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006
-\060\075\006\003\125\035\040\004\066\060\064\060\062\006\004\125
-\035\040\000\060\052\060\050\006\010\053\006\001\005\005\007\002
-\001\026\034\150\164\164\160\072\057\057\160\157\154\151\143\171
-\056\143\141\155\145\162\146\151\162\155\141\056\143\157\155\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202
-\002\001\000\220\022\257\042\065\302\243\071\360\056\336\351\265
-\351\170\174\110\276\077\175\105\222\136\351\332\261\031\374\026
-\074\237\264\133\146\236\152\347\303\271\135\210\350\017\255\317
-\043\017\336\045\072\136\314\117\245\301\265\055\254\044\322\130
-\007\336\242\317\151\204\140\063\350\020\015\023\251\043\320\205
-\345\216\173\246\236\075\162\023\162\063\365\252\175\306\143\037
-\010\364\376\001\177\044\317\053\054\124\011\336\342\053\155\222
-\306\071\117\026\352\074\176\172\106\324\105\152\106\250\353\165
-\202\126\247\253\240\174\150\023\063\366\235\060\360\157\047\071
-\044\043\052\220\375\220\051\065\362\223\337\064\245\306\367\370
-\357\214\017\142\112\174\256\323\365\124\370\215\266\232\126\207
-\026\202\072\063\253\132\042\010\367\202\272\352\056\340\107\232
-\264\265\105\243\005\073\331\334\056\105\100\073\352\334\177\350
-\073\353\321\354\046\330\065\244\060\305\072\254\127\236\263\166
-\245\040\173\371\036\112\005\142\001\246\050\165\140\227\222\015
-\156\076\115\067\103\015\222\025\234\030\042\315\121\231\240\051
-\032\074\137\212\062\063\133\060\307\211\057\107\230\017\243\003
-\306\366\361\254\337\062\360\331\201\032\344\234\275\366\200\024
-\360\321\054\271\205\365\330\243\261\310\245\041\345\034\023\227
-\356\016\275\337\051\251\357\064\123\133\323\344\152\023\204\006
-\266\062\002\304\122\256\042\322\334\262\041\102\032\332\100\360
-\051\311\354\012\014\134\342\320\272\314\110\323\067\012\314\022
-\012\212\171\260\075\003\177\151\113\364\064\040\175\263\064\352
-\216\113\144\365\076\375\263\043\147\025\015\004\270\360\055\301
-\011\121\074\262\154\025\360\245\043\327\203\164\344\345\056\311
-\376\230\047\102\306\253\306\236\260\320\133\070\245\233\120\336
-\176\030\230\265\105\073\366\171\264\350\367\032\173\006\203\373
-\320\213\332\273\307\275\030\253\010\157\074\200\153\100\077\031
-\031\272\145\212\346\276\325\134\323\066\327\357\100\122\044\140
-\070\147\004\061\354\217\363\202\306\336\271\125\363\073\061\221
-\132\334\265\010\025\255\166\045\012\015\173\056\207\342\014\246
-\006\274\046\020\155\067\235\354\335\170\214\174\200\305\360\331
-\167\110\320
-END
-
-# Trust for Certificate "Chambers of Commerce Root - 2008"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Chambers of Commerce Root - 2008"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\170\152\164\254\166\253\024\177\234\152\060\120\272\236\250\176
-\376\232\316\074
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\136\200\236\204\132\016\145\013\027\002\363\125\030\052\076\327
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\256\061\013\060\011\006\003\125\004\006\023\002\105\125
-\061\103\060\101\006\003\125\004\007\023\072\115\141\144\162\151
-\144\040\050\163\145\145\040\143\165\162\162\145\156\164\040\141
-\144\144\162\145\163\163\040\141\164\040\167\167\167\056\143\141
-\155\145\162\146\151\162\155\141\056\143\157\155\057\141\144\144
-\162\145\163\163\051\061\022\060\020\006\003\125\004\005\023\011
-\101\070\062\067\064\063\062\070\067\061\033\060\031\006\003\125
-\004\012\023\022\101\103\040\103\141\155\145\162\146\151\162\155
-\141\040\123\056\101\056\061\051\060\047\006\003\125\004\003\023
-\040\103\150\141\155\142\145\162\163\040\157\146\040\103\157\155
-\155\145\162\143\145\040\122\157\157\164\040\055\040\062\060\060
-\070
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\243\332\102\176\244\261\256\332
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Global Chambersign Root - 2008"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Global Chambersign Root - 2008"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\254\061\013\060\011\006\003\125\004\006\023\002\105\125
-\061\103\060\101\006\003\125\004\007\023\072\115\141\144\162\151
-\144\040\050\163\145\145\040\143\165\162\162\145\156\164\040\141
-\144\144\162\145\163\163\040\141\164\040\167\167\167\056\143\141
-\155\145\162\146\151\162\155\141\056\143\157\155\057\141\144\144
-\162\145\163\163\051\061\022\060\020\006\003\125\004\005\023\011
-\101\070\062\067\064\063\062\070\067\061\033\060\031\006\003\125
-\004\012\023\022\101\103\040\103\141\155\145\162\146\151\162\155
-\141\040\123\056\101\056\061\047\060\045\006\003\125\004\003\023
-\036\107\154\157\142\141\154\040\103\150\141\155\142\145\162\163
-\151\147\156\040\122\157\157\164\040\055\040\062\060\060\070
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\254\061\013\060\011\006\003\125\004\006\023\002\105\125
-\061\103\060\101\006\003\125\004\007\023\072\115\141\144\162\151
-\144\040\050\163\145\145\040\143\165\162\162\145\156\164\040\141
-\144\144\162\145\163\163\040\141\164\040\167\167\167\056\143\141
-\155\145\162\146\151\162\155\141\056\143\157\155\057\141\144\144
-\162\145\163\163\051\061\022\060\020\006\003\125\004\005\023\011
-\101\070\062\067\064\063\062\070\067\061\033\060\031\006\003\125
-\004\012\023\022\101\103\040\103\141\155\145\162\146\151\162\155
-\141\040\123\056\101\056\061\047\060\045\006\003\125\004\003\023
-\036\107\154\157\142\141\154\040\103\150\141\155\142\145\162\163
-\151\147\156\040\122\157\157\164\040\055\040\062\060\060\070
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\311\315\323\351\325\175\043\316
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\007\111\060\202\005\061\240\003\002\001\002\002\011\000
-\311\315\323\351\325\175\043\316\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\060\201\254\061\013\060\011\006\003
-\125\004\006\023\002\105\125\061\103\060\101\006\003\125\004\007
-\023\072\115\141\144\162\151\144\040\050\163\145\145\040\143\165
-\162\162\145\156\164\040\141\144\144\162\145\163\163\040\141\164
-\040\167\167\167\056\143\141\155\145\162\146\151\162\155\141\056
-\143\157\155\057\141\144\144\162\145\163\163\051\061\022\060\020
-\006\003\125\004\005\023\011\101\070\062\067\064\063\062\070\067
-\061\033\060\031\006\003\125\004\012\023\022\101\103\040\103\141
-\155\145\162\146\151\162\155\141\040\123\056\101\056\061\047\060
-\045\006\003\125\004\003\023\036\107\154\157\142\141\154\040\103
-\150\141\155\142\145\162\163\151\147\156\040\122\157\157\164\040
-\055\040\062\060\060\070\060\036\027\015\060\070\060\070\060\061
-\061\062\063\061\064\060\132\027\015\063\070\060\067\063\061\061
-\062\063\061\064\060\132\060\201\254\061\013\060\011\006\003\125
-\004\006\023\002\105\125\061\103\060\101\006\003\125\004\007\023
-\072\115\141\144\162\151\144\040\050\163\145\145\040\143\165\162
-\162\145\156\164\040\141\144\144\162\145\163\163\040\141\164\040
-\167\167\167\056\143\141\155\145\162\146\151\162\155\141\056\143
-\157\155\057\141\144\144\162\145\163\163\051\061\022\060\020\006
-\003\125\004\005\023\011\101\070\062\067\064\063\062\070\067\061
-\033\060\031\006\003\125\004\012\023\022\101\103\040\103\141\155
-\145\162\146\151\162\155\141\040\123\056\101\056\061\047\060\045
-\006\003\125\004\003\023\036\107\154\157\142\141\154\040\103\150
-\141\155\142\145\162\163\151\147\156\040\122\157\157\164\040\055
-\040\062\060\060\070\060\202\002\042\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202\002
-\012\002\202\002\001\000\300\337\126\323\344\072\233\166\105\264
-\023\333\377\301\266\031\213\067\101\030\225\122\107\353\027\235
-\051\210\216\065\154\006\062\056\107\142\363\111\004\277\175\104
-\066\261\161\314\275\132\011\163\325\331\205\104\377\221\127\045
-\337\136\066\216\160\321\134\161\103\035\331\332\357\134\322\373
-\033\275\072\265\313\255\243\314\104\247\015\256\041\025\077\271
-\172\133\222\165\330\244\022\070\211\031\212\267\200\322\342\062
-\157\126\234\221\326\210\020\013\263\164\144\222\164\140\363\366
-\317\030\117\140\262\043\320\307\073\316\141\113\231\217\302\014
-\320\100\262\230\334\015\250\116\243\271\012\256\140\240\255\105
-\122\143\272\146\275\150\340\371\276\032\250\201\273\036\101\170
-\165\323\301\376\000\125\260\207\124\350\047\220\065\035\114\063
-\255\227\374\227\056\230\204\277\054\311\243\277\321\230\021\024
-\355\143\370\312\230\210\130\027\231\355\105\003\227\176\074\206
-\036\210\214\276\362\221\204\217\145\064\330\000\114\175\267\061
-\027\132\051\172\012\030\044\060\243\067\265\172\251\001\175\046
-\326\371\016\216\131\361\375\033\063\265\051\073\027\073\101\266
-\041\335\324\300\075\245\237\237\037\103\120\311\273\274\154\172
-\227\230\356\315\214\037\373\234\121\256\213\160\275\047\237\161
-\300\153\254\175\220\146\350\327\135\072\015\260\325\302\215\325
-\310\235\235\301\155\320\320\277\121\344\343\370\303\070\066\256
-\326\247\165\346\257\204\103\135\223\222\014\152\007\336\073\035
-\230\042\326\254\301\065\333\243\240\045\377\162\265\166\035\336
-\155\351\054\146\054\122\204\320\105\222\316\034\345\345\063\035
-\334\007\123\124\243\252\202\073\232\067\057\334\335\240\144\351
-\346\335\275\256\374\144\205\035\074\247\311\006\336\204\377\153
-\350\153\032\074\305\242\263\102\373\213\011\076\137\010\122\307
-\142\304\324\005\161\277\304\144\344\370\241\203\350\076\022\233
-\250\036\324\066\115\057\161\366\215\050\366\203\251\023\322\141
-\301\221\273\110\300\064\217\101\214\113\114\333\151\022\377\120
-\224\234\040\203\131\163\355\174\241\362\361\375\335\367\111\323
-\103\130\240\126\143\312\075\075\345\065\126\131\351\016\312\040
-\314\053\113\223\051\017\002\003\001\000\001\243\202\001\152\060
-\202\001\146\060\022\006\003\125\035\023\001\001\377\004\010\060
-\006\001\001\377\002\001\014\060\035\006\003\125\035\016\004\026
-\004\024\271\011\312\234\036\333\323\154\072\153\256\355\124\361
-\133\223\006\065\056\136\060\201\341\006\003\125\035\043\004\201
-\331\060\201\326\200\024\271\011\312\234\036\333\323\154\072\153
-\256\355\124\361\133\223\006\065\056\136\241\201\262\244\201\257
-\060\201\254\061\013\060\011\006\003\125\004\006\023\002\105\125
-\061\103\060\101\006\003\125\004\007\023\072\115\141\144\162\151
-\144\040\050\163\145\145\040\143\165\162\162\145\156\164\040\141
-\144\144\162\145\163\163\040\141\164\040\167\167\167\056\143\141
-\155\145\162\146\151\162\155\141\056\143\157\155\057\141\144\144
-\162\145\163\163\051\061\022\060\020\006\003\125\004\005\023\011
-\101\070\062\067\064\063\062\070\067\061\033\060\031\006\003\125
-\004\012\023\022\101\103\040\103\141\155\145\162\146\151\162\155
-\141\040\123\056\101\056\061\047\060\045\006\003\125\004\003\023
-\036\107\154\157\142\141\154\040\103\150\141\155\142\145\162\163
-\151\147\156\040\122\157\157\164\040\055\040\062\060\060\070\202
-\011\000\311\315\323\351\325\175\043\316\060\016\006\003\125\035
-\017\001\001\377\004\004\003\002\001\006\060\075\006\003\125\035
-\040\004\066\060\064\060\062\006\004\125\035\040\000\060\052\060
-\050\006\010\053\006\001\005\005\007\002\001\026\034\150\164\164
-\160\072\057\057\160\157\154\151\143\171\056\143\141\155\145\162
-\146\151\162\155\141\056\143\157\155\060\015\006\011\052\206\110
-\206\367\015\001\001\005\005\000\003\202\002\001\000\200\210\177
-\160\336\222\050\331\005\224\106\377\220\127\251\361\057\337\032
-\015\153\372\174\016\034\111\044\171\047\330\106\252\157\051\131
-\122\210\160\022\352\335\075\365\233\123\124\157\341\140\242\250
-\011\271\354\353\131\174\306\065\361\334\030\351\361\147\345\257
-\272\105\340\011\336\312\104\017\302\027\016\167\221\105\172\063
-\137\137\226\054\150\213\301\107\217\230\233\075\300\354\313\365
-\325\202\222\204\065\321\276\066\070\126\162\061\133\107\055\252
-\027\244\143\121\353\012\001\255\177\354\165\236\313\241\037\361
-\177\022\261\271\344\144\177\147\326\043\052\364\270\071\135\230
-\350\041\247\341\275\075\102\032\164\232\160\257\150\154\120\135
-\111\317\377\373\016\135\346\054\107\327\201\072\131\000\265\163
-\153\143\040\366\061\105\010\071\016\364\160\176\100\160\132\077
-\320\153\102\251\164\075\050\057\002\155\165\162\225\011\215\110
-\143\306\306\043\127\222\223\136\065\301\215\371\012\367\054\235
-\142\034\366\255\174\335\246\061\036\266\261\307\176\205\046\372
-\244\152\265\332\143\060\321\357\223\067\262\146\057\175\005\367
-\347\267\113\230\224\065\300\331\072\051\301\235\262\120\063\035
-\112\251\132\246\311\003\357\355\364\347\250\156\212\264\127\204
-\353\244\077\320\356\252\252\207\133\143\350\223\342\153\250\324
-\270\162\170\153\033\355\071\344\135\313\233\252\207\325\117\116
-\000\376\331\152\237\074\061\017\050\002\001\175\230\350\247\260
-\242\144\236\171\370\110\362\025\251\314\346\310\104\353\077\170
-\231\362\173\161\076\074\361\230\247\305\030\022\077\346\273\050
-\063\102\351\105\012\174\155\362\206\171\057\305\202\031\175\011
-\211\174\262\124\166\210\256\336\301\363\314\341\156\333\061\326
-\223\256\231\240\357\045\152\163\230\211\133\072\056\023\210\036
-\277\300\222\224\064\033\343\047\267\213\036\157\102\377\347\351
-\067\233\120\035\055\242\371\002\356\313\130\130\072\161\274\150
-\343\252\301\257\034\050\037\242\334\043\145\077\201\352\256\231
-\323\330\060\317\023\015\117\025\311\204\274\247\110\055\370\060
-\043\167\330\106\113\171\155\366\214\355\072\177\140\021\170\364
-\351\233\256\325\124\300\164\200\321\013\102\237\301
-END
-
-# Trust for Certificate "Global Chambersign Root - 2008"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Global Chambersign Root - 2008"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\112\275\356\354\225\015\065\234\211\256\307\122\241\054\133\051
-\366\326\252\014
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\236\200\377\170\001\014\056\301\066\275\376\226\220\156\010\363
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\254\061\013\060\011\006\003\125\004\006\023\002\105\125
-\061\103\060\101\006\003\125\004\007\023\072\115\141\144\162\151
-\144\040\050\163\145\145\040\143\165\162\162\145\156\164\040\141
-\144\144\162\145\163\163\040\141\164\040\167\167\167\056\143\141
-\155\145\162\146\151\162\155\141\056\143\157\155\057\141\144\144
-\162\145\163\163\051\061\022\060\020\006\003\125\004\005\023\011
-\101\070\062\067\064\063\062\070\067\061\033\060\031\006\003\125
-\004\012\023\022\101\103\040\103\141\155\145\162\146\151\162\155
-\141\040\123\056\101\056\061\047\060\045\006\003\125\004\003\023
-\036\107\154\157\142\141\154\040\103\150\141\155\142\145\162\163
-\151\147\156\040\122\157\157\164\040\055\040\062\060\060\070
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\011\000\311\315\323\351\325\175\043\316
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus Mozilla Addons"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Mozilla Addons"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\342\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067
-\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151
-\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147
-\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123
-\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060
-\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114
-\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145
-\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004
-\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111
-\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151
-\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141
-\164\151\156\165\155\123\123\114\061\033\060\031\006\003\125\004
-\003\023\022\141\144\144\157\156\163\056\155\157\172\151\154\154
-\141\056\157\162\147
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\222\071\325\064\217\100\321\151\132\164\124\160\341
-\362\077\103
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\370\060\202\004\340\240\003\002\001\002\002\021\000
-\222\071\325\064\217\100\321\151\132\164\124\160\341\362\077\103
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025
-\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145
-\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025
-\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145
-\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030
-\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164
-\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004
-\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164
-\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060
-\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063
-\061\064\062\063\065\071\065\071\132\060\201\342\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125
-\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125
-\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006
-\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060
-\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154
-\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023
-\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021
-\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164
-\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164
-\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040
-\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006
-\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123
-\114\061\033\060\031\006\003\125\004\003\023\022\141\144\144\157
-\156\163\056\155\157\172\151\154\154\141\056\157\162\147\060\202
-\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
-\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000\253
-\306\155\066\363\025\163\170\203\163\316\164\205\325\256\354\262
-\360\340\044\037\023\203\270\040\254\273\232\376\210\273\253\241
-\035\013\037\105\000\252\111\267\065\067\014\152\357\107\114\271
-\321\276\343\127\022\004\215\222\307\266\354\001\274\266\332\307
-\201\070\040\255\162\205\346\016\374\201\154\007\255\150\166\070
-\305\104\327\314\306\112\305\227\076\144\364\121\346\360\176\262
-\354\126\367\045\202\115\111\230\313\026\230\335\043\361\211\221
-\321\027\227\100\231\046\326\342\242\053\136\337\275\211\362\033
-\032\123\055\314\120\101\172\320\075\052\014\125\160\024\001\351
-\130\111\020\172\013\223\202\213\341\036\355\072\200\020\202\316
-\226\212\064\360\314\327\323\271\264\120\207\125\124\011\270\235
-\102\050\125\000\345\214\065\124\277\335\045\221\106\267\015\345
-\135\203\250\345\213\373\204\344\074\256\166\332\304\103\053\133
-\164\013\370\276\135\150\361\170\133\265\316\175\361\135\231\100
-\332\312\356\070\201\120\276\230\241\154\270\044\255\363\257\214
-\017\327\021\050\054\204\030\114\175\265\331\217\060\265\033\002
-\003\001\000\001\243\202\001\360\060\202\001\354\060\037\006\003
-\125\035\043\004\030\060\026\200\024\241\162\137\046\033\050\230
-\103\225\135\007\067\325\205\226\235\113\322\303\105\060\035\006
-\003\125\035\016\004\026\004\024\335\200\322\124\075\367\114\160
-\312\243\260\335\064\172\062\344\350\073\132\073\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\005\240\060\014\006\003
-\125\035\023\001\001\377\004\002\060\000\060\035\006\003\125\035
-\045\004\026\060\024\006\010\053\006\001\005\005\007\003\001\006
-\010\053\006\001\005\005\007\003\002\060\106\006\003\125\035\040
-\004\077\060\075\060\073\006\014\053\006\001\004\001\262\061\001
-\002\001\003\004\060\053\060\051\006\010\053\006\001\005\005\007
-\002\001\026\035\150\164\164\160\163\072\057\057\163\145\143\165
-\162\145\056\143\157\155\157\144\157\056\143\157\155\057\103\120
-\123\060\173\006\003\125\035\037\004\164\060\162\060\070\240\066
-\240\064\206\062\150\164\164\160\072\057\057\143\162\154\056\143
-\157\155\157\144\157\143\141\056\143\157\155\057\125\124\116\055
-\125\123\105\122\106\151\162\163\164\055\110\141\162\144\167\141
-\162\145\056\143\162\154\060\066\240\064\240\062\206\060\150\164
-\164\160\072\057\057\143\162\154\056\143\157\155\157\144\157\056
-\156\145\164\057\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145\056\143\162\154\060\161
-\006\010\053\006\001\005\005\007\001\001\004\145\060\143\060\073
-\006\010\053\006\001\005\005\007\060\002\206\057\150\164\164\160
-\072\057\057\143\162\164\056\143\157\155\157\144\157\143\141\056
-\143\157\155\057\125\124\116\101\144\144\124\162\165\163\164\123
-\145\162\166\145\162\103\101\056\143\162\164\060\044\006\010\053
-\006\001\005\005\007\060\001\206\030\150\164\164\160\072\057\057
-\157\143\163\160\056\143\157\155\157\144\157\143\141\056\143\157
-\155\060\065\006\003\125\035\021\004\056\060\054\202\022\141\144
-\144\157\156\163\056\155\157\172\151\154\154\141\056\157\162\147
-\202\026\167\167\167\056\141\144\144\157\156\163\056\155\157\172
-\151\154\154\141\056\157\162\147\060\015\006\011\052\206\110\206
-\367\015\001\001\005\005\000\003\202\001\001\000\063\073\143\025
-\374\261\354\024\054\223\335\165\224\336\201\132\331\116\231\276
-\373\112\244\071\125\115\241\100\172\336\023\052\207\251\067\317
-\350\325\373\255\321\173\155\157\214\040\207\202\124\346\127\111
-\274\040\050\204\315\326\001\331\223\213\027\156\043\146\345\204
-\310\200\077\306\241\160\200\344\354\115\035\371\374\221\132\163
-\142\051\232\367\040\034\141\340\213\071\237\312\274\176\215\335
-\274\331\261\343\237\236\337\025\123\221\041\122\013\331\032\043
-\017\146\066\333\254\223\226\112\243\245\042\317\051\367\242\231
-\250\366\266\331\100\256\331\176\266\366\130\056\233\254\066\312
-\144\217\145\122\334\206\234\202\253\156\120\113\332\137\372\005
-\000\210\060\016\336\215\126\277\201\107\215\075\006\342\262\142
-\222\147\217\236\310\232\262\345\006\270\160\044\270\167\174\043
-\012\070\303\171\010\330\261\121\235\254\225\021\307\100\027\236
-\243\034\217\362\021\247\150\047\332\111\005\204\030\174\130\055
-\001\147\134\345\237\241\051\273\112\071\105\057\277\021\252\171
-\242\355\264\324\265\145\103\267\223\106\212\323
-END
-
-# Trust for Certificate "Bogus Mozilla Addons"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Mozilla Addons"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\060\137\213\321\172\242\313\304\203\244\304\033\031\243\232\014
-\165\332\071\326
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\204\305\030\147\037\052\032\220\276\342\261\030\117\003\000\062
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\222\071\325\064\217\100\321\151\132\164\124\160\341
-\362\077\103
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus Global Trustee"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Global Trustee"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\343\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067
-\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151
-\144\141\061\016\060\014\006\003\125\004\007\023\005\124\141\155
-\160\141\061\027\060\025\006\003\125\004\011\023\016\123\145\141
-\040\126\151\154\154\141\147\145\040\061\060\061\027\060\025\006
-\003\125\004\012\023\016\107\154\157\142\141\154\040\124\162\165
-\163\164\145\145\061\027\060\025\006\003\125\004\013\023\016\107
-\154\157\142\141\154\040\124\162\165\163\164\145\145\061\050\060
-\046\006\003\125\004\013\023\037\110\157\163\164\145\144\040\142
-\171\040\107\124\111\040\107\162\157\165\160\040\103\157\162\160
-\157\162\141\164\151\157\156\061\024\060\022\006\003\125\004\013
-\023\013\120\154\141\164\151\156\165\155\123\123\114\061\027\060
-\025\006\003\125\004\003\023\016\147\154\157\142\141\154\040\164
-\162\165\163\164\145\145
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\330\363\137\116\267\207\053\055\253\006\222\343\025
-\070\057\260
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\006\335\060\202\005\305\240\003\002\001\002\002\021\000
-\330\363\137\116\267\207\053\055\253\006\222\343\025\070\057\260
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025
-\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145
-\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025
-\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145
-\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030
-\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164
-\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004
-\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164
-\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060
-\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063
-\061\064\062\063\065\071\065\071\132\060\201\343\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125
-\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125
-\004\010\023\007\106\154\157\162\151\144\141\061\016\060\014\006
-\003\125\004\007\023\005\124\141\155\160\141\061\027\060\025\006
-\003\125\004\011\023\016\123\145\141\040\126\151\154\154\141\147
-\145\040\061\060\061\027\060\025\006\003\125\004\012\023\016\107
-\154\157\142\141\154\040\124\162\165\163\164\145\145\061\027\060
-\025\006\003\125\004\013\023\016\107\154\157\142\141\154\040\124
-\162\165\163\164\145\145\061\050\060\046\006\003\125\004\013\023
-\037\110\157\163\164\145\144\040\142\171\040\107\124\111\040\107
-\162\157\165\160\040\103\157\162\160\157\162\141\164\151\157\156
-\061\024\060\022\006\003\125\004\013\023\013\120\154\141\164\151
-\156\165\155\123\123\114\061\027\060\025\006\003\125\004\003\023
-\016\147\154\157\142\141\154\040\164\162\165\163\164\145\145\060
-\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001
-\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000
-\331\164\362\252\101\035\337\365\302\026\103\111\134\051\277\266
-\211\164\051\274\234\215\014\106\117\131\176\262\101\027\146\064
-\014\145\211\341\154\045\343\206\012\236\042\105\042\214\335\235
-\346\243\225\336\334\210\002\125\134\343\133\221\165\353\046\151
-\143\271\056\306\312\056\047\337\210\272\002\040\156\376\271\013
-\051\327\247\326\327\110\032\034\316\335\037\251\047\016\142\117
-\241\226\036\335\124\072\064\143\112\166\365\167\175\131\147\330
-\020\324\265\017\072\103\042\230\333\364\011\304\012\160\316\335
-\220\324\057\357\164\023\303\315\302\211\071\142\025\235\346\164
-\250\350\233\360\143\156\234\211\266\016\255\233\367\314\202\350
-\350\055\270\013\332\042\354\111\205\007\210\231\230\077\364\164
-\251\011\367\201\174\227\013\131\231\030\162\213\333\224\202\053
-\247\350\252\153\227\277\210\176\165\260\213\105\105\014\307\250
-\011\352\033\101\130\060\073\137\170\145\025\064\322\344\074\064
-\015\035\330\144\074\212\245\126\111\231\050\055\113\362\317\315
-\331\156\111\144\233\251\171\220\167\125\251\010\033\255\032\164
-\236\340\003\223\012\011\267\255\247\264\134\357\203\154\267\232
-\264\306\150\100\200\035\102\321\156\171\233\251\031\041\232\234
-\371\206\055\000\321\064\376\340\266\371\125\266\365\046\305\225
-\026\245\174\163\237\012\051\211\254\072\230\367\233\164\147\267
-\220\267\135\011\043\152\152\355\054\020\356\123\012\020\360\026
-\037\127\263\261\015\171\221\031\260\353\315\060\077\240\024\137
-\263\306\375\134\063\247\260\377\230\260\125\214\271\245\362\157
-\107\044\111\041\151\314\102\242\121\000\100\205\214\202\202\253
-\062\245\313\232\334\320\331\030\015\337\031\364\257\203\015\301
-\076\061\333\044\110\266\165\200\241\341\311\167\144\036\247\345
-\213\177\025\115\113\247\302\320\355\171\225\136\221\061\354\030
-\377\116\237\110\024\352\165\272\041\316\051\166\351\037\116\121
-\207\056\263\314\004\140\272\043\037\037\145\262\012\270\325\156
-\217\113\102\211\107\251\201\220\133\053\262\266\256\346\240\160
-\173\170\220\012\172\305\345\347\305\373\012\366\057\151\214\214
-\037\127\340\006\231\377\021\325\122\062\040\227\047\230\356\145
-\002\003\001\000\001\243\202\001\324\060\202\001\320\060\037\006
-\003\125\035\043\004\030\060\026\200\024\241\162\137\046\033\050
-\230\103\225\135\007\067\325\205\226\235\113\322\303\105\060\035
-\006\003\125\035\016\004\026\004\024\267\303\336\032\103\355\101
-\227\251\217\051\170\234\003\271\254\100\102\000\254\060\016\006
-\003\125\035\017\001\001\377\004\004\003\002\005\240\060\014\006
-\003\125\035\023\001\001\377\004\002\060\000\060\035\006\003\125
-\035\045\004\026\060\024\006\010\053\006\001\005\005\007\003\001
-\006\010\053\006\001\005\005\007\003\002\060\106\006\003\125\035
-\040\004\077\060\075\060\073\006\014\053\006\001\004\001\262\061
-\001\002\001\003\004\060\053\060\051\006\010\053\006\001\005\005
-\007\002\001\026\035\150\164\164\160\163\072\057\057\163\145\143
-\165\162\145\056\143\157\155\157\144\157\056\143\157\155\057\103
-\120\123\060\173\006\003\125\035\037\004\164\060\162\060\070\240
-\066\240\064\206\062\150\164\164\160\072\057\057\143\162\154\056
-\143\157\155\157\144\157\143\141\056\143\157\155\057\125\124\116
-\055\125\123\105\122\106\151\162\163\164\055\110\141\162\144\167
-\141\162\145\056\143\162\154\060\066\240\064\240\062\206\060\150
-\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144\157
-\056\156\145\164\057\125\124\116\055\125\123\105\122\106\151\162
-\163\164\055\110\141\162\144\167\141\162\145\056\143\162\154\060
-\161\006\010\053\006\001\005\005\007\001\001\004\145\060\143\060
-\073\006\010\053\006\001\005\005\007\060\002\206\057\150\164\164
-\160\072\057\057\143\162\164\056\143\157\155\157\144\157\143\141
-\056\143\157\155\057\125\124\116\101\144\144\124\162\165\163\164
-\123\145\162\166\145\162\103\101\056\143\162\164\060\044\006\010
-\053\006\001\005\005\007\060\001\206\030\150\164\164\160\072\057
-\057\157\143\163\160\056\143\157\155\157\144\157\143\141\056\143
-\157\155\060\031\006\003\125\035\021\004\022\060\020\202\016\147
-\154\157\142\141\154\040\164\162\165\163\164\145\145\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001
-\000\217\272\165\272\071\324\046\323\160\017\304\263\002\247\305
-\022\043\161\311\376\143\351\243\142\170\044\104\117\324\271\021
-\076\037\307\050\347\125\153\356\364\341\000\221\206\212\311\011
-\153\237\056\244\105\071\321\141\142\136\223\245\005\105\170\237
-\140\022\054\364\154\145\145\015\314\106\064\213\050\272\240\306
-\364\231\161\144\363\042\166\254\117\363\142\311\247\063\132\007
-\037\075\311\206\200\334\333\004\057\207\047\350\277\110\104\201
-\300\360\111\043\156\037\345\344\003\206\044\023\242\205\142\174
-\130\004\312\346\215\023\162\012\272\126\104\242\017\274\373\240
-\075\015\052\177\373\236\251\011\075\267\132\324\212\215\341\045
-\350\244\011\204\160\255\022\104\271\317\271\063\172\272\134\346
-\113\246\273\005\006\230\377\362\230\122\173\167\200\047\112\331
-\342\372\271\122\324\373\373\346\326\055\236\217\301\025\104\215
-\233\164\057\356\224\132\116\323\304\213\212\254\103\235\163\366
-\256\014\207\211\255\207\311\311\307\335\272\024\140\172\370\265
-\065\235\302\215\306\226\201\015\251\122\212\051\100\004\351\031
-\264
-END
-
-# Trust for Certificate "Bogus Global Trustee"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Global Trustee"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\141\171\077\313\372\117\220\010\060\233\272\137\361\055\054\262
-\234\324\025\032
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\376\015\001\156\161\313\214\330\077\016\014\315\111\065\270\127
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\330\363\137\116\267\207\053\055\253\006\222\343\025
-\070\057\260
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus GMail"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus GMail"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067
-\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151
-\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147
-\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123
-\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060
-\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114
-\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145
-\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004
-\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111
-\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151
-\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141
-\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004
-\003\023\017\155\141\151\154\056\147\157\157\147\154\145\056\143
-\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\004\176\313\351\374\245\137\173\320\236\256\066\341\014
-\256\036
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\356\060\202\004\326\240\003\002\001\002\002\020\004
-\176\313\351\374\245\137\173\320\236\256\066\341\014\256\036\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004\003
-\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164\055
-\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060\063
-\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063\061
-\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125\004
-\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125\004
-\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006\003
-\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060\025
-\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154\141
-\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023\013
-\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021\006
-\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164\056
-\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164\145
-\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040\103
-\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006\003
-\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123\114
-\061\030\060\026\006\003\125\004\003\023\017\155\141\151\154\056
-\147\157\157\147\154\145\056\143\157\155\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\260\163\360\362\004
-\356\302\242\106\312\064\052\252\273\140\043\321\021\166\037\037
-\072\320\145\203\116\232\105\250\103\160\205\166\360\037\207\000
-\002\037\156\073\027\027\304\265\351\031\106\242\222\045\215\142
-\052\264\143\060\037\271\205\370\065\341\026\132\166\111\314\120
-\110\123\071\131\211\326\204\002\373\232\354\033\307\121\325\166
-\225\220\324\072\052\270\246\336\002\115\006\373\315\355\245\106
-\101\137\125\164\345\354\176\100\334\120\234\265\344\065\135\036
-\150\040\370\351\336\243\152\050\277\101\322\241\263\342\045\215
-\014\033\312\075\223\014\030\256\337\305\274\375\274\202\272\150
-\000\327\026\062\161\237\145\265\021\332\150\131\320\246\127\144
-\033\311\376\230\345\365\245\145\352\341\333\356\364\263\235\263
-\216\352\207\256\026\322\036\240\174\174\151\077\051\026\205\001
-\123\247\154\361\140\253\335\242\374\045\107\324\062\321\022\335
-\367\110\022\340\374\234\242\167\230\351\211\231\270\370\070\361
-\214\006\302\172\043\066\155\233\235\315\060\310\307\064\027\036
-\273\175\102\310\253\347\025\026\366\163\265\002\003\001\000\001
-\243\202\001\352\060\202\001\346\060\037\006\003\125\035\043\004
-\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007
-\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016
-\004\026\004\024\030\052\242\310\324\172\077\173\255\004\213\275
-\157\236\020\106\023\170\161\235\060\016\006\003\125\035\017\001
-\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001
-\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060
-\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001
-\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075
-\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004
-\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035
-\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143
-\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006
-\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062
-\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144
-\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122
-\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143
-\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057
-\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057
-\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141
-\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006
-\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006
-\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143
-\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057
-\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145
-\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005
-\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160
-\056\143\157\155\157\144\157\143\141\056\143\157\155\060\057\006
-\003\125\035\021\004\050\060\046\202\017\155\141\151\154\056\147
-\157\157\147\154\145\056\143\157\155\202\023\167\167\167\056\155
-\141\151\154\056\147\157\157\147\154\145\056\143\157\155\060\015
-\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001
-\001\000\147\006\010\012\047\305\223\156\002\362\336\027\077\320
-\323\033\174\377\265\315\172\307\167\307\276\337\022\312\031\336
-\260\023\127\014\003\221\304\171\122\317\177\267\136\125\040\204
-\111\335\365\320\051\057\016\004\332\131\236\016\023\237\364\300
-\062\233\377\241\021\044\052\227\243\362\077\075\052\153\250\255
-\214\031\165\225\016\035\045\375\117\304\172\025\303\035\307\023
-\100\310\015\276\227\140\162\246\376\045\276\217\354\325\246\206
-\303\041\134\131\122\331\152\013\134\237\113\336\265\371\354\342
-\364\305\314\142\123\166\211\145\344\051\332\267\277\226\340\140
-\215\015\267\011\125\326\100\125\035\301\362\226\041\165\257\211
-\206\037\135\201\227\051\050\036\051\327\226\301\040\003\062\173
-\000\073\152\067\027\132\243\263\032\157\062\073\156\361\243\135
-\253\253\314\052\313\060\014\037\065\043\213\151\104\134\352\254
-\050\140\355\253\153\143\236\366\222\274\275\232\132\046\114\305
-\230\270\016\031\076\374\005\061\343\026\331\375\220\005\003\206
-\306\127\001\037\177\170\240\317\063\152\252\146\153\042\320\247
-\111\043
-END
-
-# Trust for Certificate "Bogus GMail"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus GMail"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\144\061\162\060\066\375\046\336\245\002\171\057\245\225\222\044
-\223\003\017\227
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\114\167\037\353\312\061\301\051\230\351\054\020\263\257\111\034
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\004\176\313\351\374\245\137\173\320\236\256\066\341\014
-\256\036
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus Google"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Google"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\336\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067
-\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151
-\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147
-\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123
-\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060
-\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114
-\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145
-\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004
-\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111
-\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151
-\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141
-\164\151\156\165\155\123\123\114\061\027\060\025\006\003\125\004
-\003\023\016\167\167\167\056\147\157\157\147\154\145\056\143\157
-\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\365\310\152\363\141\142\361\072\144\365\117\155\311
-\130\174\006
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\344\060\202\004\314\240\003\002\001\002\002\021\000
-\365\310\152\363\141\142\361\072\144\365\117\155\311\130\174\006
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025
-\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145
-\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025
-\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145
-\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030
-\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164
-\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004
-\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164
-\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060
-\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063
-\061\064\062\063\065\071\065\071\132\060\201\336\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125
-\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125
-\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006
-\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060
-\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154
-\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023
-\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021
-\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164
-\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164
-\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040
-\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006
-\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123
-\114\061\027\060\025\006\003\125\004\003\023\016\167\167\167\056
-\147\157\157\147\154\145\056\143\157\155\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\260\163\360\362\004
-\356\302\242\106\312\064\052\252\273\140\043\321\021\166\037\037
-\072\320\145\203\116\232\105\250\103\160\205\166\360\037\207\000
-\002\037\156\073\027\027\304\265\351\031\106\242\222\045\215\142
-\052\264\143\060\037\271\205\370\065\341\026\132\166\111\314\120
-\110\123\071\131\211\326\204\002\373\232\354\033\307\121\325\166
-\225\220\324\072\052\270\246\336\002\115\006\373\315\355\245\106
-\101\137\125\164\345\354\176\100\334\120\234\265\344\065\135\036
-\150\040\370\351\336\243\152\050\277\101\322\241\263\342\045\215
-\014\033\312\075\223\014\030\256\337\305\274\375\274\202\272\150
-\000\327\026\062\161\237\145\265\021\332\150\131\320\246\127\144
-\033\311\376\230\345\365\245\145\352\341\333\356\364\263\235\263
-\216\352\207\256\026\322\036\240\174\174\151\077\051\026\205\001
-\123\247\154\361\140\253\335\242\374\045\107\324\062\321\022\335
-\367\110\022\340\374\234\242\167\230\351\211\231\270\370\070\361
-\214\006\302\172\043\066\155\233\235\315\060\310\307\064\027\036
-\273\175\102\310\253\347\025\026\366\163\265\002\003\001\000\001
-\243\202\001\340\060\202\001\334\060\037\006\003\125\035\043\004
-\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007
-\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016
-\004\026\004\024\030\052\242\310\324\172\077\173\255\004\213\275
-\157\236\020\106\023\170\161\235\060\016\006\003\125\035\017\001
-\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001
-\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060
-\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001
-\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075
-\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004
-\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035
-\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143
-\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006
-\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062
-\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144
-\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122
-\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143
-\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057
-\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057
-\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141
-\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006
-\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006
-\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143
-\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057
-\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145
-\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005
-\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160
-\056\143\157\155\157\144\157\143\141\056\143\157\155\060\045\006
-\003\125\035\021\004\036\060\034\202\016\167\167\167\056\147\157
-\157\147\154\145\056\143\157\155\202\012\147\157\157\147\154\145
-\056\143\157\155\060\015\006\011\052\206\110\206\367\015\001\001
-\005\005\000\003\202\001\001\000\161\300\231\077\136\366\275\063
-\377\236\026\313\250\277\335\160\371\322\123\073\066\256\311\027
-\310\256\136\115\335\142\367\267\323\076\167\243\376\300\173\062
-\265\311\224\005\122\120\362\137\075\171\204\111\117\135\154\260
-\327\131\275\324\154\210\372\374\305\145\206\353\050\122\242\102
-\366\174\274\152\307\007\056\045\321\220\142\040\306\215\121\302
-\054\105\071\116\003\332\367\030\350\314\012\072\331\105\330\154
-\156\064\213\142\234\116\025\371\103\356\345\227\300\077\255\065
-\023\305\053\006\307\101\375\342\367\176\105\255\233\321\341\146
-\355\370\172\113\224\071\172\057\353\350\077\103\330\065\326\126
-\372\164\347\155\346\355\254\145\204\376\320\115\006\022\336\332
-\131\000\074\011\134\317\210\113\350\075\264\025\041\222\314\155
-\246\121\342\216\227\361\364\202\106\313\304\123\136\332\134\235
-\145\222\001\145\211\000\345\266\231\377\046\100\361\057\031\061
-\010\032\261\147\125\206\015\256\065\063\206\274\227\110\222\327
-\226\140\370\316\374\226\353\207\304\163\314\224\233\130\133\363
-\172\244\047\023\326\117\364\151
-END
-
-# Trust for Certificate "Bogus Google"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Google"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\031\026\242\257\064\155\071\237\120\061\074\071\062\000\361\101
-\100\105\146\026
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\001\163\251\130\360\274\311\276\224\053\032\114\230\044\343\270
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\365\310\152\363\141\142\361\072\144\365\117\155\311
-\130\174\006
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus Skype"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Skype"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067
-\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151
-\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147
-\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123
-\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060
-\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114
-\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145
-\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004
-\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111
-\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151
-\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141
-\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004
-\003\023\017\154\157\147\151\156\056\163\153\171\160\145\056\143
-\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\351\002\213\225\170\344\025\334\032\161\012\053\210
-\025\104\107
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\357\060\202\004\327\240\003\002\001\002\002\021\000
-\351\002\213\225\170\344\025\334\032\161\012\053\210\025\104\107
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025
-\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145
-\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025
-\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145
-\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030
-\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164
-\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004
-\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164
-\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060
-\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063
-\061\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125
-\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125
-\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006
-\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060
-\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154
-\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023
-\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021
-\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164
-\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164
-\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040
-\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006
-\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123
-\114\061\030\060\026\006\003\125\004\003\023\017\154\157\147\151
-\156\056\163\153\171\160\145\056\143\157\155\060\202\001\042\060
-\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202
-\001\017\000\060\202\001\012\002\202\001\001\000\260\170\231\206
-\016\242\163\043\324\132\303\111\353\261\066\214\174\312\204\256
-\074\257\070\210\050\231\215\055\130\023\261\227\170\076\122\040
-\147\254\133\163\230\154\062\125\311\160\321\331\252\025\350\056
-\046\205\201\274\126\344\274\200\143\333\116\327\365\002\276\121
-\143\036\074\333\337\327\000\135\132\271\345\173\152\352\070\040
-\262\073\266\356\165\124\204\371\246\312\070\160\335\277\260\377
-\245\205\135\264\101\376\335\075\331\052\341\060\103\032\230\171
-\223\240\137\340\147\154\225\372\076\172\256\161\173\343\155\210
-\102\077\045\324\356\276\150\150\254\255\254\140\340\040\243\071
-\203\271\133\050\243\223\155\241\275\166\012\343\353\256\207\047
-\016\124\217\264\110\014\232\124\364\135\216\067\120\334\136\244
-\213\153\113\334\246\363\064\276\167\131\042\210\377\031\053\155
-\166\144\163\332\014\207\007\053\232\067\072\320\342\214\366\066
-\062\153\232\171\314\322\073\223\157\032\115\154\346\301\235\100
-\254\055\164\303\276\352\134\163\145\001\051\261\052\277\160\131
-\301\316\306\303\242\310\105\137\272\147\075\017\002\003\001\000
-\001\243\202\001\352\060\202\001\346\060\037\006\003\125\035\043
-\004\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135
-\007\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035
-\016\004\026\004\024\325\216\132\121\023\264\051\015\061\266\034
-\215\076\121\121\061\012\063\252\201\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023
-\001\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026
-\060\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006
-\001\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060
-\075\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003
-\004\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026
-\035\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056
-\143\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173
-\006\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206
-\062\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157
-\144\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105
-\122\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056
-\143\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072
-\057\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164
-\057\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110
-\141\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053
-\006\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053
-\006\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057
-\143\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155
-\057\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166
-\145\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005
-\005\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163
-\160\056\143\157\155\157\144\157\143\141\056\143\157\155\060\057
-\006\003\125\035\021\004\050\060\046\202\017\154\157\147\151\156
-\056\163\153\171\160\145\056\143\157\155\202\023\167\167\167\056
-\154\157\147\151\156\056\163\153\171\160\145\056\143\157\155\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202
-\001\001\000\010\362\201\165\221\273\316\022\004\030\302\115\132
-\373\106\220\012\124\104\364\362\335\007\201\360\037\246\172\157
-\237\317\270\016\054\117\234\304\232\365\250\366\272\244\311\172
-\135\261\342\132\312\074\372\140\250\150\076\313\272\055\342\315
-\326\266\344\222\074\151\255\127\352\250\057\070\020\204\162\345
-\150\161\355\276\353\156\030\357\143\172\276\347\044\377\300\143
-\375\130\073\114\201\222\330\051\253\216\065\135\327\323\011\153
-\205\323\325\163\005\104\342\345\273\203\123\020\313\362\317\267
-\156\341\151\267\241\222\144\305\317\315\202\273\066\240\070\255
-\327\044\337\123\374\077\142\267\267\325\307\127\343\223\061\160
-\216\044\211\206\312\143\053\071\272\135\331\152\140\354\241\116
-\212\376\123\370\136\222\337\057\134\046\027\155\003\175\002\017
-\017\252\103\147\155\260\142\277\176\123\335\314\354\170\163\225
-\345\245\366\000\243\004\375\077\004\052\263\230\305\267\003\034
-\333\311\120\253\260\005\035\036\276\126\264\317\076\102\023\224
-\236\371\347\001\201\245\170\157\014\172\166\254\005\206\354\254
-\302\021\254
-END
-
-# Trust for Certificate "Bogus Skype"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Skype"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\107\034\224\232\201\103\333\132\325\315\361\311\162\206\112\045
-\004\372\043\311
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\205\244\264\304\151\041\337\241\152\015\130\126\130\113\063\104
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\351\002\213\225\170\344\025\334\032\161\012\053\210
-\025\104\107
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus Yahoo 1"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Yahoo 1"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067
-\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151
-\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147
-\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123
-\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060
-\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114
-\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145
-\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004
-\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111
-\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151
-\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141
-\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004
-\003\023\017\154\157\147\151\156\056\171\141\150\157\157\056\143
-\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\327\125\217\332\365\361\020\133\262\023\050\053\160
-\167\051\243
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\357\060\202\004\327\240\003\002\001\002\002\021\000
-\327\125\217\332\365\361\020\133\262\023\050\053\160\167\051\243
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025
-\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145
-\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025
-\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145
-\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030
-\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164
-\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004
-\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164
-\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060
-\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063
-\061\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125
-\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125
-\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006
-\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060
-\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154
-\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023
-\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021
-\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164
-\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164
-\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040
-\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006
-\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123
-\114\061\030\060\026\006\003\125\004\003\023\017\154\157\147\151
-\156\056\171\141\150\157\157\056\143\157\155\060\202\001\042\060
-\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202
-\001\017\000\060\202\001\012\002\202\001\001\000\241\244\005\075
-\355\205\105\223\212\030\115\306\003\000\127\342\100\167\360\034
-\353\320\031\337\042\135\010\177\321\007\074\101\211\106\027\243
-\011\372\374\370\251\004\321\226\217\253\327\117\074\371\255\030
-\251\164\201\304\127\012\072\046\026\316\142\076\274\077\154\041
-\356\223\215\313\015\240\037\232\226\320\217\255\365\223\223\202
-\356\162\014\241\165\025\243\173\204\126\270\255\377\122\021\161
-\204\274\072\060\013\176\230\250\341\250\077\067\122\320\361\174
-\157\220\330\105\012\254\071\162\152\141\325\273\303\214\371\302
-\314\337\375\072\161\271\257\274\334\072\334\014\266\261\322\321
-\211\273\101\266\362\336\127\325\025\337\374\375\342\061\305\337
-\312\301\330\217\054\277\360\016\133\161\340\064\161\303\305\115
-\175\172\324\372\355\060\113\057\352\266\056\236\223\074\342\072
-\370\102\242\032\356\334\337\315\017\251\366\171\204\032\216\154
-\002\266\206\345\277\121\152\146\370\363\234\323\131\014\173\245
-\231\170\315\174\231\372\306\226\107\330\062\324\164\166\016\167
-\113\040\164\244\267\211\165\222\112\264\133\125\002\003\001\000
-\001\243\202\001\352\060\202\001\346\060\037\006\003\125\035\043
-\004\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135
-\007\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035
-\016\004\026\004\024\206\111\105\374\063\031\063\324\004\355\047
-\141\356\350\001\311\014\177\057\176\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023
-\001\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026
-\060\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006
-\001\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060
-\075\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003
-\004\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026
-\035\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056
-\143\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173
-\006\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206
-\062\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157
-\144\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105
-\122\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056
-\143\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072
-\057\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164
-\057\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110
-\141\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053
-\006\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053
-\006\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057
-\143\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155
-\057\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166
-\145\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005
-\005\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163
-\160\056\143\157\155\157\144\157\143\141\056\143\157\155\060\057
-\006\003\125\035\021\004\050\060\046\202\017\154\157\147\151\156
-\056\171\141\150\157\157\056\143\157\155\202\023\167\167\167\056
-\154\157\147\151\156\056\171\141\150\157\157\056\143\157\155\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202
-\001\001\000\075\127\311\110\044\134\356\144\201\365\256\276\125
-\051\026\377\052\057\204\355\331\370\243\003\310\060\146\273\310
-\324\201\055\041\367\010\367\254\226\102\232\101\165\172\272\135
-\020\043\313\222\102\141\372\212\332\155\145\064\031\345\251\326
-\055\023\170\327\201\104\222\251\156\200\143\025\313\376\065\037
-\002\321\212\024\260\250\314\224\040\073\250\032\360\135\066\120
-\333\015\256\351\144\344\366\215\151\175\060\310\024\027\000\112
-\345\246\065\373\175\015\042\235\171\166\122\054\274\227\006\210
-\232\025\364\163\346\361\365\230\245\315\007\104\221\270\247\150
-\147\105\322\162\021\140\342\161\267\120\125\342\212\251\015\326
-\222\356\004\052\213\060\240\242\005\106\064\155\222\306\073\252
-\115\240\320\253\001\031\012\062\267\350\343\317\361\322\227\111
-\173\254\244\227\367\360\127\256\143\167\232\177\226\332\115\375
-\276\334\007\066\343\045\275\211\171\216\051\022\023\213\210\007
-\373\153\333\244\315\263\055\047\351\324\312\140\327\205\123\373
-\164\306\134\065\214\160\037\371\262\267\222\047\040\307\224\325
-\147\024\060
-END
-
-# Trust for Certificate "Bogus Yahoo 1"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Yahoo 1"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\143\376\256\226\013\252\221\343\103\316\053\330\267\027\230\307
-\153\333\167\320
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\014\037\276\323\374\011\156\346\156\302\146\071\165\206\153\353
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\327\125\217\332\365\361\020\133\262\023\050\053\160
-\167\051\243
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus Yahoo 2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Yahoo 2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067
-\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151
-\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147
-\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123
-\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060
-\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114
-\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145
-\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004
-\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111
-\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151
-\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141
-\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004
-\003\023\017\154\157\147\151\156\056\171\141\150\157\157\056\143
-\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\071\052\103\117\016\007\337\037\212\243\005\336\064\340
-\302\051
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\331\060\202\004\301\240\003\002\001\002\002\020\071
-\052\103\117\016\007\337\037\212\243\005\336\064\340\302\051\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004\003
-\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164\055
-\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060\063
-\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063\061
-\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125\004
-\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125\004
-\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006\003
-\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060\025
-\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154\141
-\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023\013
-\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021\006
-\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164\056
-\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164\145
-\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040\103
-\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006\003
-\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123\114
-\061\030\060\026\006\003\125\004\003\023\017\154\157\147\151\156
-\056\171\141\150\157\157\056\143\157\155\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\241\244\005\075\355
-\205\105\223\212\030\115\306\003\000\127\342\100\167\360\034\353
-\320\031\337\042\135\010\177\321\007\074\101\211\106\027\243\011
-\372\374\370\251\004\321\226\217\253\327\117\074\371\255\030\251
-\164\201\304\127\012\072\046\026\316\142\076\274\077\154\041\356
-\223\215\313\015\240\037\232\226\320\217\255\365\223\223\202\356
-\162\014\241\165\025\243\173\204\126\270\255\377\122\021\161\204
-\274\072\060\013\176\230\250\341\250\077\067\122\320\361\174\157
-\220\330\105\012\254\071\162\152\141\325\273\303\214\371\302\314
-\337\375\072\161\271\257\274\334\072\334\014\266\261\322\321\211
-\273\101\266\362\336\127\325\025\337\374\375\342\061\305\337\312
-\301\330\217\054\277\360\016\133\161\340\064\161\303\305\115\175
-\172\324\372\355\060\113\057\352\266\056\236\223\074\342\072\370
-\102\242\032\356\334\337\315\017\251\366\171\204\032\216\154\002
-\266\206\345\277\121\152\146\370\363\234\323\131\014\173\245\231
-\170\315\174\231\372\306\226\107\330\062\324\164\166\016\167\113
-\040\164\244\267\211\165\222\112\264\133\125\002\003\001\000\001
-\243\202\001\325\060\202\001\321\060\037\006\003\125\035\043\004
-\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007
-\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016
-\004\026\004\024\206\111\105\374\063\031\063\324\004\355\047\141
-\356\350\001\311\014\177\057\176\060\016\006\003\125\035\017\001
-\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001
-\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060
-\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001
-\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075
-\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004
-\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035
-\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143
-\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006
-\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062
-\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144
-\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122
-\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143
-\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057
-\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057
-\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141
-\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006
-\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006
-\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143
-\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057
-\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145
-\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005
-\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160
-\056\143\157\155\157\144\157\143\141\056\143\157\155\060\032\006
-\003\125\035\021\004\023\060\021\202\017\154\157\147\151\156\056
-\171\141\150\157\157\056\143\157\155\060\015\006\011\052\206\110
-\206\367\015\001\001\005\005\000\003\202\001\001\000\127\142\341
-\167\353\374\037\277\210\123\257\130\323\324\326\155\147\060\027
-\100\276\340\037\144\336\207\025\314\340\244\126\251\321\237\371
-\001\376\002\261\261\352\342\137\356\161\026\061\371\010\325\302
-\327\232\233\262\132\070\327\251\177\351\207\153\061\371\013\254
-\331\375\120\161\340\333\202\222\017\201\234\215\167\351\353\056
-\352\324\043\101\207\354\055\262\170\263\216\261\147\322\356\161
-\003\010\022\231\263\002\051\157\336\213\336\301\251\003\012\132
-\063\034\075\021\003\306\110\014\230\234\025\056\331\246\205\122
-\347\005\212\256\060\043\353\355\050\154\140\351\055\177\217\107
-\213\057\320\334\346\273\017\176\137\362\110\201\216\120\004\143
-\261\121\200\165\232\251\266\020\034\020\137\157\030\157\340\016
-\226\105\316\356\361\265\040\333\357\332\156\310\225\343\366\105
-\375\312\374\245\137\111\155\006\036\322\336\141\075\025\175\067
-\345\034\065\216\006\302\153\367\264\250\050\054\061\313\252\264
-\247\227\117\235\212\366\257\176\067\271\173\075\337\222\146\213
-\217\116\235\306\066\347\134\246\253\022\017\326\317
-END
-
-# Trust for Certificate "Bogus Yahoo 2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Yahoo 2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\320\030\266\055\305\030\220\162\107\337\120\222\133\260\232\317
-\112\134\263\255
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\162\334\310\162\154\123\073\262\375\314\135\031\275\257\246\061
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\071\052\103\117\016\007\337\037\212\243\005\336\064\340
-\302\051
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus Yahoo 3"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Yahoo 3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\337\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067
-\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151
-\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147
-\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123
-\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060
-\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114
-\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145
-\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004
-\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111
-\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151
-\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141
-\164\151\156\165\155\123\123\114\061\030\060\026\006\003\125\004
-\003\023\017\154\157\147\151\156\056\171\141\150\157\157\056\143
-\157\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\076\165\316\324\153\151\060\041\041\210\060\256\206\250
-\052\161
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\331\060\202\004\301\240\003\002\001\002\002\020\076
-\165\316\324\153\151\060\041\041\210\060\256\206\250\052\161\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004\003
-\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164\055
-\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060\063
-\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063\061
-\064\062\063\065\071\065\071\132\060\201\337\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125\004
-\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125\004
-\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006\003
-\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060\025
-\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154\141
-\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023\013
-\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021\006
-\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164\056
-\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164\145
-\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040\103
-\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006\003
-\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123\114
-\061\030\060\026\006\003\125\004\003\023\017\154\157\147\151\156
-\056\171\141\150\157\157\056\143\157\155\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\241\244\005\075\355
-\205\105\223\212\030\115\306\003\000\127\342\100\167\360\034\353
-\320\031\337\042\135\010\177\321\007\074\101\211\106\027\243\011
-\372\374\370\251\004\321\226\217\253\327\117\074\371\255\030\251
-\164\201\304\127\012\072\046\026\316\142\076\274\077\154\041\356
-\223\215\313\015\240\037\232\226\320\217\255\365\223\223\202\356
-\162\014\241\165\025\243\173\204\126\270\255\377\122\021\161\204
-\274\072\060\013\176\230\250\341\250\077\067\122\320\361\174\157
-\220\330\105\012\254\071\162\152\141\325\273\303\214\371\302\314
-\337\375\072\161\271\257\274\334\072\334\014\266\261\322\321\211
-\273\101\266\362\336\127\325\025\337\374\375\342\061\305\337\312
-\301\330\217\054\277\360\016\133\161\340\064\161\303\305\115\175
-\172\324\372\355\060\113\057\352\266\056\236\223\074\342\072\370
-\102\242\032\356\334\337\315\017\251\366\171\204\032\216\154\002
-\266\206\345\277\121\152\146\370\363\234\323\131\014\173\245\231
-\170\315\174\231\372\306\226\107\330\062\324\164\166\016\167\113
-\040\164\244\267\211\165\222\112\264\133\125\002\003\001\000\001
-\243\202\001\325\060\202\001\321\060\037\006\003\125\035\043\004
-\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007
-\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016
-\004\026\004\024\206\111\105\374\063\031\063\324\004\355\047\141
-\356\350\001\311\014\177\057\176\060\016\006\003\125\035\017\001
-\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001
-\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060
-\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001
-\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075
-\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004
-\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035
-\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143
-\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006
-\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062
-\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144
-\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122
-\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143
-\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057
-\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057
-\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141
-\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006
-\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006
-\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143
-\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057
-\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145
-\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005
-\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160
-\056\143\157\155\157\144\157\143\141\056\143\157\155\060\032\006
-\003\125\035\021\004\023\060\021\202\017\154\157\147\151\156\056
-\171\141\150\157\157\056\143\157\155\060\015\006\011\052\206\110
-\206\367\015\001\001\005\005\000\003\202\001\001\000\123\151\230
-\216\050\116\234\053\133\035\314\153\167\050\075\273\372\245\116
-\176\126\051\244\352\020\342\364\346\055\006\321\204\333\043\316
-\227\363\150\266\017\072\336\025\013\044\035\221\343\154\056\060
-\267\351\160\260\303\106\200\360\323\261\121\277\117\326\170\240
-\374\254\306\317\061\004\143\342\064\125\005\112\075\366\060\272
-\363\063\345\272\322\226\363\325\261\266\223\211\032\244\150\276
-\176\355\143\264\032\110\300\123\344\243\360\071\014\062\222\307
-\103\015\032\161\355\320\106\223\277\223\142\154\063\113\315\066
-\015\151\136\273\154\226\231\041\151\304\113\147\162\333\154\152
-\270\367\150\355\305\217\255\143\145\225\012\114\340\371\017\176
-\067\075\252\324\223\272\147\011\303\245\244\015\003\132\155\325
-\013\376\360\100\024\264\366\270\151\174\155\302\062\113\237\265
-\032\347\106\256\114\132\053\252\172\136\220\127\225\372\333\146
-\002\040\036\152\151\146\025\234\302\266\365\274\120\265\375\105
-\307\037\150\264\107\131\254\304\033\050\223\116\122\123\022\003
-\130\113\161\203\237\146\346\254\171\110\376\376\107
-END
-
-# Trust for Certificate "Bogus Yahoo 3"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus Yahoo 3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\200\226\052\344\326\305\264\102\211\116\225\241\076\112\151\236
-\007\326\224\317
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\112\334\074\147\355\041\315\133\316\135\310\021\344\236\317\075
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\076\165\316\324\153\151\060\041\041\210\060\256\206\250
-\052\161
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus live.com"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus live.com"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\336\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\016\060\014\006\003\125\004\021\023\005\063\070\064\067\067
-\061\020\060\016\006\003\125\004\010\023\007\106\154\157\162\151
-\144\141\061\020\060\016\006\003\125\004\007\023\007\105\156\147
-\154\151\163\150\061\027\060\025\006\003\125\004\011\023\016\123
-\145\141\040\126\151\154\154\141\147\145\040\061\060\061\024\060
-\022\006\003\125\004\012\023\013\107\157\157\147\154\145\040\114
-\164\144\056\061\023\060\021\006\003\125\004\013\023\012\124\145
-\143\150\040\104\145\160\164\056\061\050\060\046\006\003\125\004
-\013\023\037\110\157\163\164\145\144\040\142\171\040\107\124\111
-\040\107\162\157\165\160\040\103\157\162\160\157\162\141\164\151
-\157\156\061\024\060\022\006\003\125\004\013\023\013\120\154\141
-\164\151\156\165\155\123\123\114\061\027\060\025\006\003\125\004
-\003\023\016\154\157\147\151\156\056\154\151\166\145\056\143\157
-\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\260\267\023\076\320\226\371\265\157\256\221\310\164
-\275\072\300
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\354\060\202\004\324\240\003\002\001\002\002\021\000
-\260\267\023\076\320\226\371\265\157\256\221\310\164\275\072\300
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025
-\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145
-\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025
-\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145
-\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030
-\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164
-\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004
-\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164
-\055\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060
-\063\061\065\060\060\060\060\060\060\132\027\015\061\064\060\063
-\061\064\062\063\065\071\065\071\132\060\201\336\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\016\060\014\006\003\125
-\004\021\023\005\063\070\064\067\067\061\020\060\016\006\003\125
-\004\010\023\007\106\154\157\162\151\144\141\061\020\060\016\006
-\003\125\004\007\023\007\105\156\147\154\151\163\150\061\027\060
-\025\006\003\125\004\011\023\016\123\145\141\040\126\151\154\154
-\141\147\145\040\061\060\061\024\060\022\006\003\125\004\012\023
-\013\107\157\157\147\154\145\040\114\164\144\056\061\023\060\021
-\006\003\125\004\013\023\012\124\145\143\150\040\104\145\160\164
-\056\061\050\060\046\006\003\125\004\013\023\037\110\157\163\164
-\145\144\040\142\171\040\107\124\111\040\107\162\157\165\160\040
-\103\157\162\160\157\162\141\164\151\157\156\061\024\060\022\006
-\003\125\004\013\023\013\120\154\141\164\151\156\165\155\123\123
-\114\061\027\060\025\006\003\125\004\003\023\016\154\157\147\151
-\156\056\154\151\166\145\056\143\157\155\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\363\374\053\057\357
-\341\255\131\360\102\074\302\361\202\277\054\101\223\321\366\230
-\063\225\114\274\142\361\225\130\010\266\351\173\167\110\260\323
-\334\027\077\274\156\346\354\036\354\215\027\376\034\044\306\076
-\147\075\222\225\242\060\300\247\127\040\317\160\210\227\112\005
-\223\171\223\102\227\057\076\377\304\024\024\050\242\023\066\264
-\370\356\276\035\274\170\135\141\223\137\353\210\327\321\344\053
-\232\315\130\342\007\105\237\117\270\271\100\152\063\054\133\041
-\003\132\112\224\362\172\227\131\033\250\265\102\330\203\000\252
-\064\314\247\166\320\107\003\137\005\257\073\341\271\241\064\045
-\267\154\137\232\060\204\230\302\302\327\362\270\102\112\020\125
-\275\372\123\201\135\215\150\146\105\054\122\176\345\304\004\303
-\124\347\303\071\332\172\112\305\271\230\202\040\341\054\140\127
-\277\272\362\106\000\274\137\072\334\343\063\227\370\112\230\271
-\354\063\117\055\140\154\025\222\246\201\112\013\351\354\166\160
-\064\061\027\160\346\160\113\216\213\323\165\313\170\111\253\146
-\233\206\237\217\251\304\001\350\312\033\347\002\003\001\000\001
-\243\202\001\350\060\202\001\344\060\037\006\003\125\035\043\004
-\030\060\026\200\024\241\162\137\046\033\050\230\103\225\135\007
-\067\325\205\226\235\113\322\303\105\060\035\006\003\125\035\016
-\004\026\004\024\324\144\366\251\350\245\176\327\277\143\122\003
-\203\123\333\305\101\215\352\200\060\016\006\003\125\035\017\001
-\001\377\004\004\003\002\005\240\060\014\006\003\125\035\023\001
-\001\377\004\002\060\000\060\035\006\003\125\035\045\004\026\060
-\024\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001
-\005\005\007\003\002\060\106\006\003\125\035\040\004\077\060\075
-\060\073\006\014\053\006\001\004\001\262\061\001\002\001\003\004
-\060\053\060\051\006\010\053\006\001\005\005\007\002\001\026\035
-\150\164\164\160\163\072\057\057\163\145\143\165\162\145\056\143
-\157\155\157\144\157\056\143\157\155\057\103\120\123\060\173\006
-\003\125\035\037\004\164\060\162\060\070\240\066\240\064\206\062
-\150\164\164\160\072\057\057\143\162\154\056\143\157\155\157\144
-\157\143\141\056\143\157\155\057\125\124\116\055\125\123\105\122
-\106\151\162\163\164\055\110\141\162\144\167\141\162\145\056\143
-\162\154\060\066\240\064\240\062\206\060\150\164\164\160\072\057
-\057\143\162\154\056\143\157\155\157\144\157\056\156\145\164\057
-\125\124\116\055\125\123\105\122\106\151\162\163\164\055\110\141
-\162\144\167\141\162\145\056\143\162\154\060\161\006\010\053\006
-\001\005\005\007\001\001\004\145\060\143\060\073\006\010\053\006
-\001\005\005\007\060\002\206\057\150\164\164\160\072\057\057\143
-\162\164\056\143\157\155\157\144\157\143\141\056\143\157\155\057
-\125\124\116\101\144\144\124\162\165\163\164\123\145\162\166\145
-\162\103\101\056\143\162\164\060\044\006\010\053\006\001\005\005
-\007\060\001\206\030\150\164\164\160\072\057\057\157\143\163\160
-\056\143\157\155\157\144\157\143\141\056\143\157\155\060\055\006
-\003\125\035\021\004\046\060\044\202\016\154\157\147\151\156\056
-\154\151\166\145\056\143\157\155\202\022\167\167\167\056\154\157
-\147\151\156\056\154\151\166\145\056\143\157\155\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000
-\124\343\244\232\044\322\363\035\102\255\033\360\036\253\373\332
-\325\252\351\317\132\263\036\127\173\061\362\156\127\113\061\257
-\063\273\266\015\025\307\136\131\001\316\104\265\267\277\011\311
-\325\334\151\204\351\305\032\267\360\076\324\300\044\275\051\137
-\264\351\326\130\353\105\021\211\064\064\323\021\353\064\316\052
-\117\000\075\366\162\357\151\146\300\237\232\254\176\160\120\254
-\125\107\332\276\103\133\354\213\310\305\043\204\311\237\266\122
-\010\317\221\033\057\200\151\346\064\063\346\263\237\244\345\015
-\232\025\371\127\374\013\251\101\013\365\377\130\101\222\042\047
-\146\022\006\307\052\330\131\247\306\337\104\022\117\300\250\177
-\247\101\310\310\151\377\272\005\056\227\255\073\320\353\363\025
-\155\176\033\345\272\335\064\276\042\021\354\150\230\063\201\002
-\152\013\023\125\171\061\165\116\072\310\266\023\275\227\157\067
-\012\013\055\210\016\336\147\220\302\263\312\040\312\232\121\364
-\144\076\333\364\056\105\362\307\107\027\250\364\372\220\132\177
-\200\246\202\254\344\154\201\106\273\122\205\040\044\370\200\352
-END
-
-# Trust for Certificate "Bogus live.com"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus live.com"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\316\245\206\262\316\131\076\307\331\071\211\203\067\305\170\024
-\160\212\262\276
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\320\324\071\343\314\134\122\335\010\315\351\253\350\021\131\324
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\021\000\260\267\023\076\320\226\371\265\157\256\221\310\164
-\275\072\300
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Bogus kuix.de"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus kuix.de"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\361\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\016\060\014\006\003\125\004\021\023\005\061\062\063\064\065
-\061\023\060\021\006\003\125\004\010\023\012\124\145\163\164\040
-\123\164\141\164\145\061\022\060\020\006\003\125\004\007\023\011
-\124\145\163\164\040\103\151\164\171\061\024\060\022\006\003\125
-\004\011\023\013\124\145\163\164\040\123\164\162\145\145\164\061
-\023\060\021\006\003\125\004\012\023\012\113\141\151\040\105\156
-\147\145\162\164\061\042\060\040\006\003\125\004\013\023\031\106
-\157\162\040\124\145\163\164\151\156\147\040\120\165\162\160\157
-\163\145\163\040\117\156\154\171\061\055\060\053\006\003\125\004
-\013\023\044\124\105\123\124\040\125\123\105\040\117\116\114\131
-\040\055\040\116\117\040\127\101\122\122\101\116\124\131\040\101
-\124\124\101\103\110\105\104\061\031\060\027\006\003\125\004\013
-\023\020\103\157\155\157\144\157\040\124\162\151\141\154\040\123
-\123\114\061\020\060\016\006\003\125\004\003\023\007\153\165\151
-\170\056\144\145
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\162\003\041\005\305\014\010\127\075\216\245\060\116\376
-\350\260
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\154\060\202\004\124\240\003\002\001\002\002\020\162
-\003\041\005\305\014\010\127\075\216\245\060\116\376\350\260\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\227\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013
-\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006
-\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040
-\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124
-\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164
-\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150
-\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162
-\165\163\164\056\143\157\155\061\037\060\035\006\003\125\004\003
-\023\026\125\124\116\055\125\123\105\122\106\151\162\163\164\055
-\110\141\162\144\167\141\162\145\060\036\027\015\061\061\060\063
-\061\067\060\060\060\060\060\060\132\027\015\061\061\060\064\061
-\066\062\063\065\071\065\071\132\060\201\361\061\013\060\011\006
-\003\125\004\006\023\002\104\105\061\016\060\014\006\003\125\004
-\021\023\005\061\062\063\064\065\061\023\060\021\006\003\125\004
-\010\023\012\124\145\163\164\040\123\164\141\164\145\061\022\060
-\020\006\003\125\004\007\023\011\124\145\163\164\040\103\151\164
-\171\061\024\060\022\006\003\125\004\011\023\013\124\145\163\164
-\040\123\164\162\145\145\164\061\023\060\021\006\003\125\004\012
-\023\012\113\141\151\040\105\156\147\145\162\164\061\042\060\040
-\006\003\125\004\013\023\031\106\157\162\040\124\145\163\164\151
-\156\147\040\120\165\162\160\157\163\145\163\040\117\156\154\171
-\061\055\060\053\006\003\125\004\013\023\044\124\105\123\124\040
-\125\123\105\040\117\116\114\131\040\055\040\116\117\040\127\101
-\122\122\101\116\124\131\040\101\124\124\101\103\110\105\104\061
-\031\060\027\006\003\125\004\013\023\020\103\157\155\157\144\157
-\040\124\162\151\141\154\040\123\123\114\061\020\060\016\006\003
-\125\004\003\023\007\153\165\151\170\056\144\145\060\201\237\060
-\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\201
-\215\000\060\201\211\002\201\201\000\270\252\216\365\227\107\007
-\137\345\170\166\156\223\153\216\337\113\074\333\231\057\161\123
-\051\156\245\363\044\117\110\045\043\100\001\354\012\025\013\354
-\156\310\236\046\043\146\373\351\333\330\050\205\041\117\036\337
-\173\114\345\143\301\013\262\142\126\224\123\313\277\234\241\115
-\331\207\305\151\110\074\261\277\245\150\122\041\035\172\334\224
-\117\104\156\107\045\035\237\234\222\322\067\035\371\133\133\262
-\335\076\030\327\363\207\146\255\243\364\316\217\321\157\360\271
-\264\357\261\352\025\143\012\316\201\002\003\001\000\001\243\202
-\001\332\060\202\001\326\060\037\006\003\125\035\043\004\030\060
-\026\200\024\241\162\137\046\033\050\230\103\225\135\007\067\325
-\205\226\235\113\322\303\105\060\035\006\003\125\035\016\004\026
-\004\024\100\217\071\046\234\114\206\043\231\306\121\011\246\346
-\362\301\376\247\366\267\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\005\240\060\014\006\003\125\035\023\001\001\377
-\004\002\060\000\060\035\006\003\125\035\045\004\026\060\024\006
-\010\053\006\001\005\005\007\003\001\006\010\053\006\001\005\005
-\007\003\002\060\106\006\003\125\035\040\004\077\060\075\060\073
-\006\014\053\006\001\004\001\262\061\001\002\001\003\004\060\053
-\060\051\006\010\053\006\001\005\005\007\002\001\026\035\150\164
-\164\160\163\072\057\057\163\145\143\165\162\145\056\143\157\155
-\157\144\157\056\143\157\155\057\103\120\123\060\173\006\003\125
-\035\037\004\164\060\162\060\070\240\066\240\064\206\062\150\164
-\164\160\072\057\057\143\162\154\056\143\157\155\157\144\157\143
-\141\056\143\157\155\057\125\124\116\055\125\123\105\122\106\151
-\162\163\164\055\110\141\162\144\167\141\162\145\056\143\162\154
-\060\066\240\064\240\062\206\060\150\164\164\160\072\057\057\143
-\162\154\056\143\157\155\157\144\157\056\156\145\164\057\125\124
-\116\055\125\123\105\122\106\151\162\163\164\055\110\141\162\144
-\167\141\162\145\056\143\162\154\060\161\006\010\053\006\001\005
-\005\007\001\001\004\145\060\143\060\073\006\010\053\006\001\005
-\005\007\060\002\206\057\150\164\164\160\072\057\057\143\162\164
-\056\143\157\155\157\144\157\143\141\056\143\157\155\057\125\124
-\116\101\144\144\124\162\165\163\164\123\145\162\166\145\162\103
-\101\056\143\162\164\060\044\006\010\053\006\001\005\005\007\060
-\001\206\030\150\164\164\160\072\057\057\157\143\163\160\056\143
-\157\155\157\144\157\143\141\056\143\157\155\060\037\006\003\125
-\035\021\004\030\060\026\202\007\153\165\151\170\056\144\145\202
-\013\167\167\167\056\153\165\151\170\056\144\145\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000
-\216\141\036\046\036\242\331\031\320\360\324\275\211\371\352\222
-\021\171\152\136\173\174\237\176\071\163\011\126\121\346\206\124
-\307\155\106\166\122\312\152\250\064\300\140\076\003\316\263\311
-\110\227\321\237\246\241\152\017\376\167\321\036\020\263\127\200
-\251\006\046\204\246\373\172\067\023\316\204\314\167\171\011\056
-\342\104\276\037\254\167\156\167\106\101\333\260\262\151\221\164
-\321\200\226\141\061\014\057\012\317\265\320\334\010\055\353\366
-\165\202\336\212\056\272\075\007\220\140\071\126\203\341\202\312
-\043\254\337\343\317\115\160\127\301\270\267\223\232\355\334\213
-\336\112\240\125\050\002\253\103\014\124\227\150\030\242\353\071
-\341\271\374\277\163\200\144\063\022\173\207\140\002\347\076\160
-\311\207\312\251\066\074\005\361\006\136\161\012\016\012\066\231
-\260\207\347\151\132\261\240\060\116\175\141\130\313\306\250\226
-\200\136\175\301\052\377\233\112\112\353\051\147\212\017\157\346
-\031\355\202\317\201\127\341\044\255\242\321\372\332\024\227\260
-\154\174\107\306\327\224\021\041\354\326\132\322\335\217\177\221
-END
-
-# Trust for Certificate "Bogus kuix.de"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Bogus kuix.de"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\202\141\113\354\227\110\025\336\314\232\314\156\204\041\161\171
-\262\144\040\100
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\367\137\230\274\330\144\014\026\345\256\356\252\000\366\037\007
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\227\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060
-\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153
-\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023
-\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116
-\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023
-\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162
-\164\162\165\163\164\056\143\157\155\061\037\060\035\006\003\125
-\004\003\023\026\125\124\116\055\125\123\105\122\106\151\162\163
-\164\055\110\141\162\144\167\141\162\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\162\003\041\005\305\014\010\127\075\216\245\060\116\376
-\350\260
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Go Daddy Root Certificate Authority - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Go Daddy Root Certificate Authority - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\203\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157
-\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157
-\164\164\163\144\141\154\145\061\032\060\030\006\003\125\004\012
-\023\021\107\157\104\141\144\144\171\056\143\157\155\054\040\111
-\156\143\056\061\061\060\057\006\003\125\004\003\023\050\107\157
-\040\104\141\144\144\171\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\145\040\101\165\164\150\157\162\151\164
-\171\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\203\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157
-\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157
-\164\164\163\144\141\154\145\061\032\060\030\006\003\125\004\012
-\023\021\107\157\104\141\144\144\171\056\143\157\155\054\040\111
-\156\143\056\061\061\060\057\006\003\125\004\003\023\050\107\157
-\040\104\141\144\144\171\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\145\040\101\165\164\150\157\162\151\164
-\171\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\305\060\202\002\255\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
-\201\203\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157\156
-\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157\164
-\164\163\144\141\154\145\061\032\060\030\006\003\125\004\012\023
-\021\107\157\104\141\144\144\171\056\143\157\155\054\040\111\156
-\143\056\061\061\060\057\006\003\125\004\003\023\050\107\157\040
-\104\141\144\144\171\040\122\157\157\164\040\103\145\162\164\151
-\146\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171
-\040\055\040\107\062\060\036\027\015\060\071\060\071\060\061\060
-\060\060\060\060\060\132\027\015\063\067\061\062\063\061\062\063
-\065\071\065\071\132\060\201\203\061\013\060\011\006\003\125\004
-\006\023\002\125\123\061\020\060\016\006\003\125\004\010\023\007
-\101\162\151\172\157\156\141\061\023\060\021\006\003\125\004\007
-\023\012\123\143\157\164\164\163\144\141\154\145\061\032\060\030
-\006\003\125\004\012\023\021\107\157\104\141\144\144\171\056\143
-\157\155\054\040\111\156\143\056\061\061\060\057\006\003\125\004
-\003\023\050\107\157\040\104\141\144\144\171\040\122\157\157\164
-\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\062\060\202\001\042\060
-\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202
-\001\017\000\060\202\001\012\002\202\001\001\000\277\161\142\010
-\361\372\131\064\367\033\311\030\243\367\200\111\130\351\042\203
-\023\246\305\040\103\001\073\204\361\346\205\111\237\047\352\366
-\204\033\116\240\264\333\160\230\307\062\001\261\005\076\007\116
-\356\364\372\117\057\131\060\042\347\253\031\126\153\342\200\007
-\374\363\026\165\200\071\121\173\345\371\065\266\164\116\251\215
-\202\023\344\266\077\251\003\203\372\242\276\212\025\152\177\336
-\013\303\266\031\024\005\312\352\303\250\004\224\073\106\174\062
-\015\363\000\146\042\310\215\151\155\066\214\021\030\267\323\262
-\034\140\264\070\372\002\214\316\323\335\106\007\336\012\076\353
-\135\174\310\174\373\260\053\123\244\222\142\151\121\045\005\141
-\032\104\201\214\054\251\103\226\043\337\254\072\201\232\016\051
-\305\034\251\351\135\036\266\236\236\060\012\071\316\361\210\200
-\373\113\135\314\062\354\205\142\103\045\064\002\126\047\001\221
-\264\073\160\052\077\156\261\350\234\210\001\175\237\324\371\333
-\123\155\140\235\277\054\347\130\253\270\137\106\374\316\304\033
-\003\074\011\353\111\061\134\151\106\263\340\107\002\003\001\000
-\001\243\102\060\100\060\017\006\003\125\035\023\001\001\377\004
-\005\060\003\001\001\377\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\035\006\003\125\035\016\004\026\004
-\024\072\232\205\007\020\147\050\266\357\366\275\005\101\156\040
-\301\224\332\017\336\060\015\006\011\052\206\110\206\367\015\001
-\001\013\005\000\003\202\001\001\000\231\333\135\171\325\371\227
-\131\147\003\141\361\176\073\006\061\165\055\241\040\216\117\145
-\207\264\367\246\234\274\330\351\057\320\333\132\356\317\164\214
-\163\264\070\102\332\005\173\370\002\165\270\375\245\261\327\256
-\366\327\336\023\313\123\020\176\212\106\321\227\372\267\056\053
-\021\253\220\260\047\200\371\350\237\132\351\067\237\253\344\337
-\154\263\205\027\235\075\331\044\117\171\221\065\326\137\004\353
-\200\203\253\232\002\055\265\020\364\330\220\307\004\163\100\355
-\162\045\240\251\237\354\236\253\150\022\231\127\306\217\022\072
-\011\244\275\104\375\006\025\067\301\233\344\062\243\355\070\350
-\330\144\363\054\176\024\374\002\352\237\315\377\007\150\027\333
-\042\220\070\055\172\215\321\124\361\151\343\137\063\312\172\075
-\173\012\343\312\177\137\071\345\342\165\272\305\166\030\063\316
-\054\360\057\114\255\367\261\347\316\117\250\304\233\112\124\006
-\305\177\175\325\010\017\342\034\376\176\027\270\254\136\366\324
-\026\262\103\011\014\115\366\247\153\264\231\204\145\312\172\210
-\342\342\104\276\134\367\352\034\365
-END
-
-# Trust for Certificate "Go Daddy Root Certificate Authority - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Go Daddy Root Certificate Authority - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\107\276\253\311\042\352\350\016\170\170\064\142\247\237\105\302
-\124\375\346\213
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\200\072\274\042\301\346\373\215\233\073\047\112\062\033\232\001
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\203\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157
-\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157
-\164\164\163\144\141\154\145\061\032\060\030\006\003\125\004\012
-\023\021\107\157\104\141\144\144\171\056\143\157\155\054\040\111
-\156\143\056\061\061\060\057\006\003\125\004\003\023\050\107\157
-\040\104\141\144\144\171\040\122\157\157\164\040\103\145\162\164
-\151\146\151\143\141\164\145\040\101\165\164\150\157\162\151\164
-\171\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Starfield Root Certificate Authority - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Starfield Root Certificate Authority - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\217\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157
-\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157
-\164\164\163\144\141\154\145\061\045\060\043\006\003\125\004\012
-\023\034\123\164\141\162\146\151\145\154\144\040\124\145\143\150
-\156\157\154\157\147\151\145\163\054\040\111\156\143\056\061\062
-\060\060\006\003\125\004\003\023\051\123\164\141\162\146\151\145
-\154\144\040\122\157\157\164\040\103\145\162\164\151\146\151\143
-\141\164\145\040\101\165\164\150\157\162\151\164\171\040\055\040
-\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\217\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157
-\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157
-\164\164\163\144\141\154\145\061\045\060\043\006\003\125\004\012
-\023\034\123\164\141\162\146\151\145\154\144\040\124\145\143\150
-\156\157\154\157\147\151\145\163\054\040\111\156\143\056\061\062
-\060\060\006\003\125\004\003\023\051\123\164\141\162\146\151\145
-\154\144\040\122\157\157\164\040\103\145\162\164\151\146\151\143
-\141\164\145\040\101\165\164\150\157\162\151\164\171\040\055\040
-\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\335\060\202\002\305\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
-\201\217\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157\156
-\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157\164
-\164\163\144\141\154\145\061\045\060\043\006\003\125\004\012\023
-\034\123\164\141\162\146\151\145\154\144\040\124\145\143\150\156
-\157\154\157\147\151\145\163\054\040\111\156\143\056\061\062\060
-\060\006\003\125\004\003\023\051\123\164\141\162\146\151\145\154
-\144\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141
-\164\145\040\101\165\164\150\157\162\151\164\171\040\055\040\107
-\062\060\036\027\015\060\071\060\071\060\061\060\060\060\060\060
-\060\132\027\015\063\067\061\062\063\061\062\063\065\071\065\071
-\132\060\201\217\061\013\060\011\006\003\125\004\006\023\002\125
-\123\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172
-\157\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143
-\157\164\164\163\144\141\154\145\061\045\060\043\006\003\125\004
-\012\023\034\123\164\141\162\146\151\145\154\144\040\124\145\143
-\150\156\157\154\157\147\151\145\163\054\040\111\156\143\056\061
-\062\060\060\006\003\125\004\003\023\051\123\164\141\162\146\151
-\145\154\144\040\122\157\157\164\040\103\145\162\164\151\146\151
-\143\141\164\145\040\101\165\164\150\157\162\151\164\171\040\055
-\040\107\062\060\202\001\042\060\015\006\011\052\206\110\206\367
-\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002
-\202\001\001\000\275\355\301\003\374\366\217\374\002\261\157\133
-\237\110\331\235\171\342\242\267\003\141\126\030\303\107\266\327
-\312\075\065\056\211\103\367\241\151\233\336\212\032\375\023\040
-\234\264\111\167\062\051\126\375\271\354\214\335\042\372\162\334
-\047\141\227\356\366\132\204\354\156\031\271\211\054\334\204\133
-\325\164\373\153\137\305\211\245\020\122\211\106\125\364\270\165
-\034\346\177\344\124\256\113\370\125\162\127\002\031\370\027\161
-\131\353\036\050\007\164\305\235\110\276\154\264\364\244\260\363
-\144\067\171\222\300\354\106\136\177\341\155\123\114\142\257\315
-\037\013\143\273\072\235\373\374\171\000\230\141\164\317\046\202
-\100\143\363\262\162\152\031\015\231\312\324\016\165\314\067\373
-\213\211\301\131\361\142\177\137\263\137\145\060\370\247\267\115
-\166\132\036\166\136\064\300\350\226\126\231\212\263\360\177\244
-\315\275\334\062\061\174\221\317\340\137\021\370\153\252\111\134
-\321\231\224\321\242\343\143\133\011\166\265\126\142\341\113\164
-\035\226\324\046\324\010\004\131\320\230\016\016\346\336\374\303
-\354\037\220\361\002\003\001\000\001\243\102\060\100\060\017\006
-\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016
-\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\035
-\006\003\125\035\016\004\026\004\024\174\014\062\037\247\331\060
-\177\304\175\150\243\142\250\241\316\253\007\133\047\060\015\006
-\011\052\206\110\206\367\015\001\001\013\005\000\003\202\001\001
-\000\021\131\372\045\117\003\157\224\231\073\232\037\202\205\071
-\324\166\005\224\136\341\050\223\155\142\135\011\302\240\250\324
-\260\165\070\361\064\152\235\344\237\212\206\046\121\346\054\321
-\306\055\156\225\040\112\222\001\354\270\212\147\173\061\342\147
-\056\214\225\003\046\056\103\235\112\061\366\016\265\014\273\267
-\342\067\177\042\272\000\243\016\173\122\373\153\273\073\304\323
-\171\121\116\315\220\364\147\007\031\310\074\106\172\015\001\175
-\305\130\347\155\346\205\060\027\232\044\304\020\340\004\367\340
-\362\177\324\252\012\377\102\035\067\355\224\345\144\131\022\040
-\167\070\323\062\076\070\201\165\226\163\372\150\217\261\313\316
-\037\305\354\372\234\176\317\176\261\361\007\055\266\374\277\312
-\244\277\320\227\005\112\274\352\030\050\002\220\275\124\170\011
-\041\161\323\321\175\035\331\026\260\251\141\075\320\012\000\042
-\374\307\173\313\011\144\105\013\073\100\201\367\175\174\062\365
-\230\312\130\216\175\052\356\220\131\163\144\371\066\164\136\045
-\241\365\146\005\056\177\071\025\251\052\373\120\213\216\205\151
-\364
-END
-
-# Trust for Certificate "Starfield Root Certificate Authority - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Starfield Root Certificate Authority - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\265\034\006\174\356\053\014\075\370\125\253\055\222\364\376\071
-\324\347\017\016
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\326\071\201\306\122\176\226\151\374\374\312\146\355\005\362\226
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\217\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157
-\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157
-\164\164\163\144\141\154\145\061\045\060\043\006\003\125\004\012
-\023\034\123\164\141\162\146\151\145\154\144\040\124\145\143\150
-\156\157\154\157\147\151\145\163\054\040\111\156\143\056\061\062
-\060\060\006\003\125\004\003\023\051\123\164\141\162\146\151\145
-\154\144\040\122\157\157\164\040\103\145\162\164\151\146\151\143
-\141\164\145\040\101\165\164\150\157\162\151\164\171\040\055\040
-\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Starfield Services Root Certificate Authority - G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Starfield Services Root Certificate Authority - G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157
-\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157
-\164\164\163\144\141\154\145\061\045\060\043\006\003\125\004\012
-\023\034\123\164\141\162\146\151\145\154\144\040\124\145\143\150
-\156\157\154\157\147\151\145\163\054\040\111\156\143\056\061\073
-\060\071\006\003\125\004\003\023\062\123\164\141\162\146\151\145
-\154\144\040\123\145\162\166\151\143\145\163\040\122\157\157\164
-\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157
-\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157
-\164\164\163\144\141\154\145\061\045\060\043\006\003\125\004\012
-\023\034\123\164\141\162\146\151\145\154\144\040\124\145\143\150
-\156\157\154\157\147\151\145\163\054\040\111\156\143\056\061\073
-\060\071\006\003\125\004\003\023\062\123\164\141\162\146\151\145
-\154\144\040\123\145\162\166\151\143\145\163\040\122\157\157\164
-\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\357\060\202\002\327\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
-\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157\156
-\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157\164
-\164\163\144\141\154\145\061\045\060\043\006\003\125\004\012\023
-\034\123\164\141\162\146\151\145\154\144\040\124\145\143\150\156
-\157\154\157\147\151\145\163\054\040\111\156\143\056\061\073\060
-\071\006\003\125\004\003\023\062\123\164\141\162\146\151\145\154
-\144\040\123\145\162\166\151\143\145\163\040\122\157\157\164\040
-\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150
-\157\162\151\164\171\040\055\040\107\062\060\036\027\015\060\071
-\060\071\060\061\060\060\060\060\060\060\132\027\015\063\067\061
-\062\063\061\062\063\065\071\065\071\132\060\201\230\061\013\060
-\011\006\003\125\004\006\023\002\125\123\061\020\060\016\006\003
-\125\004\010\023\007\101\162\151\172\157\156\141\061\023\060\021
-\006\003\125\004\007\023\012\123\143\157\164\164\163\144\141\154
-\145\061\045\060\043\006\003\125\004\012\023\034\123\164\141\162
-\146\151\145\154\144\040\124\145\143\150\156\157\154\157\147\151
-\145\163\054\040\111\156\143\056\061\073\060\071\006\003\125\004
-\003\023\062\123\164\141\162\146\151\145\154\144\040\123\145\162
-\166\151\143\145\163\040\122\157\157\164\040\103\145\162\164\151
-\146\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171
-\040\055\040\107\062\060\202\001\042\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001
-\012\002\202\001\001\000\325\014\072\304\052\371\116\342\365\276
-\031\227\137\216\210\123\261\037\077\313\317\237\040\023\155\051
-\072\310\017\175\074\367\153\166\070\143\331\066\140\250\233\136
-\134\000\200\262\057\131\177\366\207\371\045\103\206\347\151\033
-\122\232\220\341\161\343\330\055\015\116\157\366\310\111\331\266
-\363\032\126\256\053\266\164\024\353\317\373\046\343\032\272\035
-\226\056\152\073\130\224\211\107\126\377\045\240\223\160\123\203
-\332\204\164\024\303\147\236\004\150\072\337\216\100\132\035\112
-\116\317\103\221\073\347\126\326\000\160\313\122\356\173\175\256
-\072\347\274\061\371\105\366\302\140\317\023\131\002\053\200\314
-\064\107\337\271\336\220\145\155\002\317\054\221\246\246\347\336
-\205\030\111\174\146\116\243\072\155\251\265\356\064\056\272\015
-\003\270\063\337\107\353\261\153\215\045\331\233\316\201\321\105
-\106\062\226\160\207\336\002\016\111\103\205\266\154\163\273\144
-\352\141\101\254\311\324\124\337\207\057\307\042\262\046\314\237
-\131\124\150\237\374\276\052\057\304\125\034\165\100\140\027\205
-\002\125\071\213\177\005\002\003\001\000\001\243\102\060\100\060
-\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377
-\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006
-\060\035\006\003\125\035\016\004\026\004\024\234\137\000\337\252
-\001\327\060\053\070\210\242\270\155\112\234\362\021\221\203\060
-\015\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202
-\001\001\000\113\066\246\204\167\151\335\073\031\237\147\043\010
-\157\016\141\311\375\204\334\137\330\066\201\315\330\033\101\055
-\237\140\335\307\032\150\331\321\156\206\341\210\043\317\023\336
-\103\317\342\064\263\004\235\037\051\325\277\370\136\310\325\301
-\275\356\222\157\062\164\362\221\202\057\275\202\102\172\255\052
-\267\040\175\115\274\172\125\022\302\025\352\275\367\152\225\056
-\154\164\237\317\034\264\362\305\001\243\205\320\162\076\255\163
-\253\013\233\165\014\155\105\267\216\224\254\226\067\265\240\320
-\217\025\107\016\343\350\203\335\217\375\357\101\001\167\314\047
-\251\142\205\063\362\067\010\357\161\317\167\006\336\310\031\035
-\210\100\317\175\106\035\377\036\307\341\316\377\043\333\306\372
-\215\125\116\251\002\347\107\021\106\076\364\375\275\173\051\046
-\273\251\141\142\067\050\266\055\052\366\020\206\144\311\160\247
-\322\255\267\051\160\171\352\074\332\143\045\237\375\150\267\060
-\354\160\373\165\212\267\155\140\147\262\036\310\271\351\330\250
-\157\002\213\147\015\115\046\127\161\332\040\374\301\112\120\215
-\261\050\272
-END
-
-# Trust for Certificate "Starfield Services Root Certificate Authority - G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Starfield Services Root Certificate Authority - G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\222\132\217\215\054\155\004\340\146\137\131\152\377\042\330\143
-\350\045\157\077
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\027\065\164\257\173\141\034\353\364\371\074\342\356\100\371\242
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\230\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\020\060\016\006\003\125\004\010\023\007\101\162\151\172\157
-\156\141\061\023\060\021\006\003\125\004\007\023\012\123\143\157
-\164\164\163\144\141\154\145\061\045\060\043\006\003\125\004\012
-\023\034\123\164\141\162\146\151\145\154\144\040\124\145\143\150
-\156\157\154\157\147\151\145\163\054\040\111\156\143\056\061\073
-\060\071\006\003\125\004\003\023\062\123\164\141\162\146\151\145
-\154\144\040\123\145\162\166\151\143\145\163\040\122\157\157\164
-\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164
-\150\157\162\151\164\171\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "AffirmTrust Commercial"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AffirmTrust Commercial"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\037\060\035\006\003\125\004\003\014\026
-\101\146\146\151\162\155\124\162\165\163\164\040\103\157\155\155
-\145\162\143\151\141\154
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\037\060\035\006\003\125\004\003\014\026
-\101\146\146\151\162\155\124\162\165\163\164\040\103\157\155\155
-\145\162\143\151\141\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\167\167\006\047\046\251\261\174
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\114\060\202\002\064\240\003\002\001\002\002\010\167
-\167\006\047\046\251\261\174\060\015\006\011\052\206\110\206\367
-\015\001\001\013\005\000\060\104\061\013\060\011\006\003\125\004
-\006\023\002\125\123\061\024\060\022\006\003\125\004\012\014\013
-\101\146\146\151\162\155\124\162\165\163\164\061\037\060\035\006
-\003\125\004\003\014\026\101\146\146\151\162\155\124\162\165\163
-\164\040\103\157\155\155\145\162\143\151\141\154\060\036\027\015
-\061\060\060\061\062\071\061\064\060\066\060\066\132\027\015\063
-\060\061\062\063\061\061\064\060\066\060\066\132\060\104\061\013
-\060\011\006\003\125\004\006\023\002\125\123\061\024\060\022\006
-\003\125\004\012\014\013\101\146\146\151\162\155\124\162\165\163
-\164\061\037\060\035\006\003\125\004\003\014\026\101\146\146\151
-\162\155\124\162\165\163\164\040\103\157\155\155\145\162\143\151
-\141\154\060\202\001\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202
-\001\001\000\366\033\117\147\007\053\241\025\365\006\042\313\037
-\001\262\343\163\105\006\104\111\054\273\111\045\024\326\316\303
-\267\253\054\117\306\101\062\224\127\372\022\247\133\016\342\217
-\037\036\206\031\247\252\265\055\271\137\015\212\302\257\205\065
-\171\062\055\273\034\142\067\362\261\133\112\075\312\315\161\137
-\351\102\276\224\350\310\336\371\042\110\144\306\345\253\306\053
-\155\255\005\360\372\325\013\317\232\345\360\120\244\213\073\107
-\245\043\133\172\172\370\063\077\270\357\231\227\343\040\301\326
-\050\211\317\224\373\271\105\355\343\100\027\021\324\164\360\013
-\061\342\053\046\152\233\114\127\256\254\040\076\272\105\172\005
-\363\275\233\151\025\256\175\116\040\143\304\065\166\072\007\002
-\311\067\375\307\107\356\350\361\166\035\163\025\362\227\244\265
-\310\172\171\331\102\252\053\177\134\376\316\046\117\243\146\201
-\065\257\104\272\124\036\034\060\062\145\235\346\074\223\136\120
-\116\172\343\072\324\156\314\032\373\371\322\067\256\044\052\253
-\127\003\042\050\015\111\165\177\267\050\332\165\277\216\343\334
-\016\171\061\002\003\001\000\001\243\102\060\100\060\035\006\003
-\125\035\016\004\026\004\024\235\223\306\123\213\136\312\257\077
-\237\036\017\345\231\225\274\044\366\224\217\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\001\006\060\015\006\011
-\052\206\110\206\367\015\001\001\013\005\000\003\202\001\001\000
-\130\254\364\004\016\315\300\015\377\012\375\324\272\026\137\051
-\275\173\150\231\130\111\322\264\035\067\115\177\047\175\106\006
-\135\103\306\206\056\076\163\262\046\175\117\223\251\266\304\052
-\232\253\041\227\024\261\336\214\323\253\211\025\330\153\044\324
-\361\026\256\330\244\134\324\177\121\216\355\030\001\261\223\143
-\275\274\370\141\200\232\236\261\316\102\160\342\251\175\006\045
-\175\047\241\376\157\354\263\036\044\332\343\113\125\032\000\073
-\065\264\073\331\327\135\060\375\201\023\211\362\302\006\053\355
-\147\304\216\311\103\262\134\153\025\211\002\274\142\374\116\362
-\265\063\252\262\157\323\012\242\120\343\366\073\350\056\104\302
-\333\146\070\251\063\126\110\361\155\033\063\215\015\214\077\140
-\067\235\323\312\155\176\064\176\015\237\162\166\213\033\237\162
-\375\122\065\101\105\002\226\057\034\262\232\163\111\041\261\111
-\107\105\107\264\357\152\064\021\311\115\232\314\131\267\326\002
-\236\132\116\145\265\224\256\033\337\051\260\026\361\277\000\236
-\007\072\027\144\265\004\265\043\041\231\012\225\073\227\174\357
-END
-
-# Trust for Certificate "AffirmTrust Commercial"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AffirmTrust Commercial"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\371\265\266\062\105\137\234\276\354\127\137\200\334\351\156\054
-\307\262\170\267
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\202\222\272\133\357\315\212\157\246\075\125\371\204\366\326\267
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\037\060\035\006\003\125\004\003\014\026
-\101\146\146\151\162\155\124\162\165\163\164\040\103\157\155\155
-\145\162\143\151\141\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\167\167\006\047\046\251\261\174
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "AffirmTrust Networking"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AffirmTrust Networking"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\037\060\035\006\003\125\004\003\014\026
-\101\146\146\151\162\155\124\162\165\163\164\040\116\145\164\167
-\157\162\153\151\156\147
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\037\060\035\006\003\125\004\003\014\026
-\101\146\146\151\162\155\124\162\165\163\164\040\116\145\164\167
-\157\162\153\151\156\147
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\174\117\004\071\034\324\231\055
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\114\060\202\002\064\240\003\002\001\002\002\010\174
-\117\004\071\034\324\231\055\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\060\104\061\013\060\011\006\003\125\004
-\006\023\002\125\123\061\024\060\022\006\003\125\004\012\014\013
-\101\146\146\151\162\155\124\162\165\163\164\061\037\060\035\006
-\003\125\004\003\014\026\101\146\146\151\162\155\124\162\165\163
-\164\040\116\145\164\167\157\162\153\151\156\147\060\036\027\015
-\061\060\060\061\062\071\061\064\060\070\062\064\132\027\015\063
-\060\061\062\063\061\061\064\060\070\062\064\132\060\104\061\013
-\060\011\006\003\125\004\006\023\002\125\123\061\024\060\022\006
-\003\125\004\012\014\013\101\146\146\151\162\155\124\162\165\163
-\164\061\037\060\035\006\003\125\004\003\014\026\101\146\146\151
-\162\155\124\162\165\163\164\040\116\145\164\167\157\162\153\151
-\156\147\060\202\001\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202
-\001\001\000\264\204\314\063\027\056\153\224\154\153\141\122\240
-\353\243\317\171\224\114\345\224\200\231\313\125\144\104\145\217
-\147\144\342\006\343\134\067\111\366\057\233\204\204\036\055\362
-\140\235\060\116\314\204\205\342\054\317\036\236\376\066\253\063
-\167\065\104\330\065\226\032\075\066\350\172\016\330\325\107\241
-\152\151\213\331\374\273\072\256\171\132\325\364\326\161\273\232
-\220\043\153\232\267\210\164\207\014\036\137\271\236\055\372\253
-\123\053\334\273\166\076\223\114\010\010\214\036\242\043\034\324
-\152\255\042\272\231\001\056\155\145\313\276\044\146\125\044\113
-\100\104\261\033\327\341\302\205\300\336\020\077\075\355\270\374
-\361\361\043\123\334\277\145\227\157\331\371\100\161\215\175\275
-\225\324\316\276\240\136\047\043\336\375\246\320\046\016\000\051
-\353\074\106\360\075\140\277\077\120\322\334\046\101\121\236\024
-\067\102\004\243\160\127\250\033\207\355\055\372\173\356\214\012
-\343\251\146\211\031\313\101\371\335\104\066\141\317\342\167\106
-\310\175\366\364\222\201\066\375\333\064\361\162\176\363\014\026
-\275\264\025\002\003\001\000\001\243\102\060\100\060\035\006\003
-\125\035\016\004\026\004\024\007\037\322\347\234\332\302\156\242
-\100\264\260\172\120\020\120\164\304\310\275\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\001\006\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000
-\211\127\262\026\172\250\302\375\326\331\233\233\064\302\234\264
-\062\024\115\247\244\337\354\276\247\276\370\103\333\221\067\316
-\264\062\056\120\125\032\065\116\166\103\161\040\357\223\167\116
-\025\160\056\207\303\301\035\155\334\313\265\047\324\054\126\321
-\122\123\072\104\322\163\310\304\033\005\145\132\142\222\234\356
-\101\215\061\333\347\064\352\131\041\325\001\172\327\144\270\144
-\071\315\311\355\257\355\113\003\110\247\240\231\001\200\334\145
-\243\066\256\145\131\110\117\202\113\310\145\361\127\035\345\131
-\056\012\077\154\330\321\365\345\011\264\154\124\000\012\340\025
-\115\207\165\155\267\130\226\132\335\155\322\000\240\364\233\110
-\276\303\067\244\272\066\340\174\207\205\227\032\025\242\336\056
-\242\133\275\257\030\371\220\120\315\160\131\370\047\147\107\313
-\307\240\007\072\175\321\054\135\154\031\072\146\265\175\375\221
-\157\202\261\276\010\223\333\024\107\361\242\067\307\105\236\074
-\307\167\257\144\250\223\337\366\151\203\202\140\362\111\102\064
-\355\132\000\124\205\034\026\066\222\014\134\372\246\255\277\333
-END
-
-# Trust for Certificate "AffirmTrust Networking"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AffirmTrust Networking"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\051\066\041\002\213\040\355\002\365\146\305\062\321\326\355\220
-\237\105\000\057
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\102\145\312\276\001\232\232\114\251\214\101\111\315\300\325\177
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\037\060\035\006\003\125\004\003\014\026
-\101\146\146\151\162\155\124\162\165\163\164\040\116\145\164\167
-\157\162\153\151\156\147
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\174\117\004\071\034\324\231\055
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "AffirmTrust Premium"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AffirmTrust Premium"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\101\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\034\060\032\006\003\125\004\003\014\023
-\101\146\146\151\162\155\124\162\165\163\164\040\120\162\145\155
-\151\165\155
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\101\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\034\060\032\006\003\125\004\003\014\023
-\101\146\146\151\162\155\124\162\165\163\164\040\120\162\145\155
-\151\165\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\155\214\024\106\261\246\012\356
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\106\060\202\003\056\240\003\002\001\002\002\010\155
-\214\024\106\261\246\012\356\060\015\006\011\052\206\110\206\367
-\015\001\001\014\005\000\060\101\061\013\060\011\006\003\125\004
-\006\023\002\125\123\061\024\060\022\006\003\125\004\012\014\013
-\101\146\146\151\162\155\124\162\165\163\164\061\034\060\032\006
-\003\125\004\003\014\023\101\146\146\151\162\155\124\162\165\163
-\164\040\120\162\145\155\151\165\155\060\036\027\015\061\060\060
-\061\062\071\061\064\061\060\063\066\132\027\015\064\060\061\062
-\063\061\061\064\061\060\063\066\132\060\101\061\013\060\011\006
-\003\125\004\006\023\002\125\123\061\024\060\022\006\003\125\004
-\012\014\013\101\146\146\151\162\155\124\162\165\163\164\061\034
-\060\032\006\003\125\004\003\014\023\101\146\146\151\162\155\124
-\162\165\163\164\040\120\162\145\155\151\165\155\060\202\002\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\002\017\000\060\202\002\012\002\202\002\001\000\304\022\337
-\251\137\376\101\335\335\365\237\212\343\366\254\341\074\170\232
-\274\330\360\177\172\240\063\052\334\215\040\133\256\055\157\347
-\223\331\066\160\152\150\317\216\121\243\205\133\147\004\240\020
-\044\157\135\050\202\301\227\127\330\110\051\023\266\341\276\221
-\115\337\205\014\123\030\232\036\044\242\117\217\360\242\205\013
-\313\364\051\177\322\244\130\356\046\115\311\252\250\173\232\331
-\372\070\336\104\127\025\345\370\214\310\331\110\342\015\026\047
-\035\036\310\203\205\045\267\272\252\125\101\314\003\042\113\055
-\221\215\213\346\211\257\146\307\351\377\053\351\074\254\332\322
-\263\303\341\150\234\211\370\172\000\126\336\364\125\225\154\373
-\272\144\335\142\213\337\013\167\062\353\142\314\046\232\233\273
-\252\142\203\114\264\006\172\060\310\051\277\355\006\115\227\271
-\034\304\061\053\325\137\274\123\022\027\234\231\127\051\146\167
-\141\041\061\007\056\045\111\235\030\362\356\363\053\161\214\265
-\272\071\007\111\167\374\357\056\222\220\005\215\055\057\167\173
-\357\103\277\065\273\232\330\371\163\247\054\362\320\127\356\050
-\116\046\137\217\220\150\011\057\270\370\334\006\351\056\232\076
-\121\247\321\042\304\012\247\070\110\154\263\371\377\175\253\206
-\127\343\272\326\205\170\167\272\103\352\110\177\366\330\276\043
-\155\036\277\321\066\154\130\134\361\356\244\031\124\032\365\003
-\322\166\346\341\214\275\074\263\323\110\113\342\310\370\177\222
-\250\166\106\234\102\145\076\244\036\301\007\003\132\106\055\270
-\227\363\267\325\262\125\041\357\272\334\114\000\227\373\024\225
-\047\063\277\350\103\107\106\322\010\231\026\140\073\232\176\322
-\346\355\070\352\354\001\036\074\110\126\111\011\307\114\067\000
-\236\210\016\300\163\341\157\146\351\162\107\060\076\020\345\013
-\003\311\232\102\000\154\305\224\176\141\304\212\337\177\202\032
-\013\131\304\131\062\167\263\274\140\151\126\071\375\264\006\173
-\054\326\144\066\331\275\110\355\204\037\176\245\042\217\052\270
-\102\364\202\267\324\123\220\170\116\055\032\375\201\157\104\327
-\073\001\164\226\102\340\000\342\056\153\352\305\356\162\254\273
-\277\376\352\252\250\370\334\366\262\171\212\266\147\002\003\001
-\000\001\243\102\060\100\060\035\006\003\125\035\016\004\026\004
-\024\235\300\147\246\014\042\331\046\365\105\253\246\145\122\021
-\047\330\105\254\143\060\017\006\003\125\035\023\001\001\377\004
-\005\060\003\001\001\377\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\015\006\011\052\206\110\206\367\015
-\001\001\014\005\000\003\202\002\001\000\263\127\115\020\142\116
-\072\344\254\352\270\034\257\062\043\310\263\111\132\121\234\166
-\050\215\171\252\127\106\027\325\365\122\366\267\104\350\010\104
-\277\030\204\322\013\200\315\305\022\375\000\125\005\141\207\101
-\334\265\044\236\074\304\330\310\373\160\236\057\170\226\203\040
-\066\336\174\017\151\023\210\245\165\066\230\010\246\306\337\254
-\316\343\130\326\267\076\336\272\363\353\064\100\330\242\201\365
-\170\077\057\325\245\374\331\242\324\136\004\016\027\255\376\101
-\360\345\262\162\372\104\202\063\102\350\055\130\367\126\214\142
-\077\272\102\260\234\014\134\176\056\145\046\134\123\117\000\262
-\170\176\241\015\231\055\215\270\035\216\242\304\260\375\140\320
-\060\244\216\310\004\142\251\304\355\065\336\172\227\355\016\070
-\136\222\057\223\160\245\251\234\157\247\175\023\035\176\306\010
-\110\261\136\147\353\121\010\045\351\346\045\153\122\051\221\234
-\322\071\163\010\127\336\231\006\264\133\235\020\006\341\302\000
-\250\270\034\112\002\012\024\320\301\101\312\373\214\065\041\175
-\202\070\362\251\124\221\031\065\223\224\155\152\072\305\262\320
-\273\211\206\223\350\233\311\017\072\247\172\270\241\360\170\106
-\372\374\067\057\345\212\204\363\337\376\004\331\241\150\240\057
-\044\342\011\225\006\325\225\312\341\044\226\353\174\366\223\005
-\273\355\163\351\055\321\165\071\327\347\044\333\330\116\137\103
-\217\236\320\024\071\277\125\160\110\231\127\061\264\234\356\112
-\230\003\226\060\037\140\006\356\033\043\376\201\140\043\032\107
-\142\205\245\314\031\064\200\157\263\254\032\343\237\360\173\110
-\255\325\001\331\147\266\251\162\223\352\055\146\265\262\270\344
-\075\074\262\357\114\214\352\353\007\277\253\065\232\125\206\274
-\030\246\265\250\136\264\203\154\153\151\100\323\237\334\361\303
-\151\153\271\341\155\011\364\361\252\120\166\012\172\175\172\027
-\241\125\226\102\231\061\011\335\140\021\215\005\060\176\346\216
-\106\321\235\024\332\307\027\344\005\226\214\304\044\265\033\317
-\024\007\262\100\370\243\236\101\206\274\004\320\153\226\310\052
-\200\064\375\277\357\006\243\335\130\305\205\075\076\217\376\236
-\051\340\266\270\011\150\031\034\030\103
-END
-
-# Trust for Certificate "AffirmTrust Premium"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AffirmTrust Premium"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\330\246\063\054\340\003\157\261\205\366\143\117\175\152\006\145
-\046\062\050\047
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\304\135\016\110\266\254\050\060\116\012\274\371\070\026\207\127
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\101\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\034\060\032\006\003\125\004\003\014\023
-\101\146\146\151\162\155\124\162\165\163\164\040\120\162\145\155
-\151\165\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\155\214\024\106\261\246\012\356
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "AffirmTrust Premium ECC"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AffirmTrust Premium ECC"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\040\060\036\006\003\125\004\003\014\027
-\101\146\146\151\162\155\124\162\165\163\164\040\120\162\145\155
-\151\165\155\040\105\103\103
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\040\060\036\006\003\125\004\003\014\027
-\101\146\146\151\162\155\124\162\165\163\164\040\120\162\145\155
-\151\165\155\040\105\103\103
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\164\227\045\212\307\077\172\124
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\001\376\060\202\001\205\240\003\002\001\002\002\010\164
-\227\045\212\307\077\172\124\060\012\006\010\052\206\110\316\075
-\004\003\003\060\105\061\013\060\011\006\003\125\004\006\023\002
-\125\123\061\024\060\022\006\003\125\004\012\014\013\101\146\146
-\151\162\155\124\162\165\163\164\061\040\060\036\006\003\125\004
-\003\014\027\101\146\146\151\162\155\124\162\165\163\164\040\120
-\162\145\155\151\165\155\040\105\103\103\060\036\027\015\061\060
-\060\061\062\071\061\064\062\060\062\064\132\027\015\064\060\061
-\062\063\061\061\064\062\060\062\064\132\060\105\061\013\060\011
-\006\003\125\004\006\023\002\125\123\061\024\060\022\006\003\125
-\004\012\014\013\101\146\146\151\162\155\124\162\165\163\164\061
-\040\060\036\006\003\125\004\003\014\027\101\146\146\151\162\155
-\124\162\165\163\164\040\120\162\145\155\151\165\155\040\105\103
-\103\060\166\060\020\006\007\052\206\110\316\075\002\001\006\005
-\053\201\004\000\042\003\142\000\004\015\060\136\033\025\235\003
-\320\241\171\065\267\072\074\222\172\312\025\034\315\142\363\234
-\046\134\007\075\345\124\372\243\326\314\022\352\364\024\137\350
-\216\031\253\057\056\110\346\254\030\103\170\254\320\067\303\275
-\262\315\054\346\107\342\032\346\143\270\075\056\057\170\304\117
-\333\364\017\244\150\114\125\162\153\225\035\116\030\102\225\170
-\314\067\074\221\342\233\145\053\051\243\102\060\100\060\035\006
-\003\125\035\016\004\026\004\024\232\257\051\172\300\021\065\065
-\046\121\060\000\303\152\376\100\325\256\326\074\060\017\006\003
-\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016\006
-\003\125\035\017\001\001\377\004\004\003\002\001\006\060\012\006
-\010\052\206\110\316\075\004\003\003\003\147\000\060\144\002\060
-\027\011\363\207\210\120\132\257\310\300\102\277\107\137\365\154
-\152\206\340\304\047\164\344\070\123\327\005\177\033\064\343\306
-\057\263\312\011\074\067\235\327\347\270\106\361\375\241\342\161
-\002\060\102\131\207\103\324\121\337\272\323\011\062\132\316\210
-\176\127\075\234\137\102\153\365\007\055\265\360\202\223\371\131
-\157\256\144\372\130\345\213\036\343\143\276\265\201\315\157\002
-\214\171
-END
-
-# Trust for Certificate "AffirmTrust Premium ECC"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "AffirmTrust Premium ECC"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\270\043\153\000\057\035\026\206\123\001\125\154\021\244\067\312
-\353\377\303\273
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\144\260\011\125\317\261\325\231\342\276\023\253\246\135\352\115
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\024\060\022\006\003\125\004\012\014\013\101\146\146\151\162\155
-\124\162\165\163\164\061\040\060\036\006\003\125\004\003\014\027
-\101\146\146\151\162\155\124\162\165\163\164\040\120\162\145\155
-\151\165\155\040\105\103\103
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\164\227\045\212\307\077\172\124
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Certum Trusted Network CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certum Trusted Network CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\176\061\013\060\011\006\003\125\004\006\023\002\120\114\061
-\042\060\040\006\003\125\004\012\023\031\125\156\151\172\145\164
-\157\040\124\145\143\150\156\157\154\157\147\151\145\163\040\123
-\056\101\056\061\047\060\045\006\003\125\004\013\023\036\103\145
-\162\164\165\155\040\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\101\165\164\150\157\162\151\164\171\061\042\060\040
-\006\003\125\004\003\023\031\103\145\162\164\165\155\040\124\162
-\165\163\164\145\144\040\116\145\164\167\157\162\153\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\176\061\013\060\011\006\003\125\004\006\023\002\120\114\061
-\042\060\040\006\003\125\004\012\023\031\125\156\151\172\145\164
-\157\040\124\145\143\150\156\157\154\157\147\151\145\163\040\123
-\056\101\056\061\047\060\045\006\003\125\004\013\023\036\103\145
-\162\164\165\155\040\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\101\165\164\150\157\162\151\164\171\061\042\060\040
-\006\003\125\004\003\023\031\103\145\162\164\165\155\040\124\162
-\165\163\164\145\144\040\116\145\164\167\157\162\153\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\003\004\104\300
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\273\060\202\002\243\240\003\002\001\002\002\003\004
-\104\300\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\060\176\061\013\060\011\006\003\125\004\006\023\002\120\114
-\061\042\060\040\006\003\125\004\012\023\031\125\156\151\172\145
-\164\157\040\124\145\143\150\156\157\154\157\147\151\145\163\040
-\123\056\101\056\061\047\060\045\006\003\125\004\013\023\036\103
-\145\162\164\165\155\040\103\145\162\164\151\146\151\143\141\164
-\151\157\156\040\101\165\164\150\157\162\151\164\171\061\042\060
-\040\006\003\125\004\003\023\031\103\145\162\164\165\155\040\124
-\162\165\163\164\145\144\040\116\145\164\167\157\162\153\040\103
-\101\060\036\027\015\060\070\061\060\062\062\061\062\060\067\063
-\067\132\027\015\062\071\061\062\063\061\061\062\060\067\063\067
-\132\060\176\061\013\060\011\006\003\125\004\006\023\002\120\114
-\061\042\060\040\006\003\125\004\012\023\031\125\156\151\172\145
-\164\157\040\124\145\143\150\156\157\154\157\147\151\145\163\040
-\123\056\101\056\061\047\060\045\006\003\125\004\013\023\036\103
-\145\162\164\165\155\040\103\145\162\164\151\146\151\143\141\164
-\151\157\156\040\101\165\164\150\157\162\151\164\171\061\042\060
-\040\006\003\125\004\003\023\031\103\145\162\164\165\155\040\124
-\162\165\163\164\145\144\040\116\145\164\167\157\162\153\040\103
-\101\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001
-\001\000\343\373\175\243\162\272\302\360\311\024\207\365\153\001
-\116\341\156\100\007\272\155\047\135\177\367\133\055\263\132\307
-\121\137\253\244\062\246\141\207\266\156\017\206\322\060\002\227
-\370\327\151\127\241\030\071\135\152\144\171\306\001\131\254\074
-\061\112\070\174\322\004\322\113\050\350\040\137\073\007\242\314
-\115\163\333\363\256\117\307\126\325\132\247\226\211\372\363\253
-\150\324\043\206\131\047\317\011\047\274\254\156\162\203\034\060
-\162\337\340\242\351\322\341\164\165\031\275\052\236\173\025\124
-\004\033\327\103\071\255\125\050\305\342\032\273\364\300\344\256
-\070\111\063\314\166\205\237\071\105\322\244\236\362\022\214\121
-\370\174\344\055\177\365\254\137\353\026\237\261\055\321\272\314
-\221\102\167\114\045\311\220\070\157\333\360\314\373\216\036\227
-\131\076\325\140\116\346\005\050\355\111\171\023\113\272\110\333
-\057\371\162\323\071\312\376\037\330\064\162\365\264\100\317\061
-\001\303\354\336\021\055\027\135\037\270\120\321\136\031\247\151
-\336\007\063\050\312\120\225\371\247\124\313\124\206\120\105\251
-\371\111\002\003\001\000\001\243\102\060\100\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\035\006\003
-\125\035\016\004\026\004\024\010\166\315\313\007\377\044\366\305
-\315\355\273\220\274\342\204\067\106\165\367\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000\246
-\250\255\042\316\001\075\246\243\377\142\320\110\235\213\136\162
-\260\170\104\343\334\034\257\011\375\043\110\372\275\052\304\271
-\125\004\265\020\243\215\047\336\013\202\143\320\356\336\014\067
-\171\101\133\042\262\260\232\101\134\246\160\340\324\320\167\313
-\043\323\000\340\154\126\057\341\151\015\015\331\252\277\041\201
-\120\331\006\245\250\377\225\067\320\252\376\342\263\365\231\055
-\105\204\212\345\102\011\327\164\002\057\367\211\330\231\351\274
-\047\324\107\215\272\015\106\034\167\317\024\244\034\271\244\061
-\304\234\050\164\003\064\377\063\031\046\245\351\015\164\267\076
-\227\306\166\350\047\226\243\146\335\341\256\362\101\133\312\230
-\126\203\163\160\344\206\032\322\061\101\272\057\276\055\023\132
-\166\157\116\350\116\201\016\077\133\003\042\240\022\276\146\130
-\021\112\313\003\304\264\052\052\055\226\027\340\071\124\274\110
-\323\166\047\235\232\055\006\246\311\354\071\322\253\333\237\232
-\013\047\002\065\051\261\100\225\347\371\350\234\125\210\031\106
-\326\267\064\365\176\316\071\232\331\070\361\121\367\117\054
-END
-
-# Trust for Certificate "Certum Trusted Network CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certum Trusted Network CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\007\340\062\340\040\267\054\077\031\057\006\050\242\131\072\031
-\247\017\006\236
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\325\351\201\100\305\030\151\374\106\054\211\165\142\017\252\170
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\176\061\013\060\011\006\003\125\004\006\023\002\120\114\061
-\042\060\040\006\003\125\004\012\023\031\125\156\151\172\145\164
-\157\040\124\145\143\150\156\157\154\157\147\151\145\163\040\123
-\056\101\056\061\047\060\045\006\003\125\004\013\023\036\103\145
-\162\164\165\155\040\103\145\162\164\151\146\151\143\141\164\151
-\157\156\040\101\165\164\150\157\162\151\164\171\061\042\060\040
-\006\003\125\004\003\023\031\103\145\162\164\165\155\040\124\162
-\165\163\164\145\144\040\116\145\164\167\157\162\153\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\003\004\104\300
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Certinomis - Autorité Racine"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certinomis - Autorité Racine"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\106\122\061
-\023\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156
-\157\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060
-\060\060\062\040\064\063\063\071\071\070\071\060\063\061\046\060
-\044\006\003\125\004\003\014\035\103\145\162\164\151\156\157\155
-\151\163\040\055\040\101\165\164\157\162\151\164\303\251\040\122
-\141\143\151\156\145
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\106\122\061
-\023\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156
-\157\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060
-\060\060\062\040\064\063\063\071\071\070\071\060\063\061\046\060
-\044\006\003\125\004\003\014\035\103\145\162\164\151\156\157\155
-\151\163\040\055\040\101\165\164\157\162\151\164\303\251\040\122
-\141\143\151\156\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\234\060\202\003\204\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\143\061\013\060\011\006\003\125\004\006\023\002\106\122\061\023
-\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156\157
-\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060\060
-\060\062\040\064\063\063\071\071\070\071\060\063\061\046\060\044
-\006\003\125\004\003\014\035\103\145\162\164\151\156\157\155\151
-\163\040\055\040\101\165\164\157\162\151\164\303\251\040\122\141
-\143\151\156\145\060\036\027\015\060\070\060\071\061\067\060\070
-\062\070\065\071\132\027\015\062\070\060\071\061\067\060\070\062
-\070\065\071\132\060\143\061\013\060\011\006\003\125\004\006\023
-\002\106\122\061\023\060\021\006\003\125\004\012\023\012\103\145
-\162\164\151\156\157\155\151\163\061\027\060\025\006\003\125\004
-\013\023\016\060\060\060\062\040\064\063\063\071\071\070\071\060
-\063\061\046\060\044\006\003\125\004\003\014\035\103\145\162\164
-\151\156\157\155\151\163\040\055\040\101\165\164\157\162\151\164
-\303\251\040\122\141\143\151\156\145\060\202\002\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017
-\000\060\202\002\012\002\202\002\001\000\235\205\237\206\323\343
-\257\307\262\153\156\063\340\236\267\102\064\125\235\371\201\276
-\143\330\043\166\016\227\124\315\231\114\032\361\071\307\210\330
-\027\120\014\236\141\332\300\116\125\336\347\132\270\172\116\167
-\207\015\345\270\353\372\236\136\173\036\304\317\050\164\307\223
-\365\024\306\042\050\004\371\221\303\253\047\163\152\016\056\115
-\363\056\050\037\160\337\125\057\116\355\307\161\157\011\162\056
-\355\325\062\227\320\361\130\167\321\140\274\116\136\333\232\204
-\366\107\141\105\053\366\120\246\177\152\161\047\110\204\065\236
-\254\376\151\251\236\172\136\065\045\372\264\247\111\065\167\226
-\247\066\133\341\315\337\043\160\330\135\114\245\010\203\361\246
-\044\070\023\250\354\057\250\241\147\307\246\055\206\107\356\212
-\374\354\233\016\164\364\053\111\002\173\220\165\214\374\231\071
-\001\071\326\112\211\345\236\166\253\076\226\050\070\046\213\335
-\215\214\300\366\001\036\157\245\061\022\070\175\225\302\161\356
-\355\164\256\344\066\242\103\165\325\361\000\233\342\344\327\314
-\102\003\113\170\172\345\175\273\270\256\056\040\223\323\344\141
-\337\161\341\166\147\227\077\266\337\152\163\132\144\042\345\102
-\333\317\201\003\223\330\364\343\020\340\162\366\000\160\254\360
-\301\172\017\005\177\317\064\151\105\265\223\344\031\333\122\026
-\043\005\211\016\215\110\344\045\157\263\170\277\142\365\007\372
-\225\044\302\226\262\350\243\043\302\135\003\374\303\323\345\174
-\311\165\043\327\364\365\274\336\344\337\315\200\277\221\210\175
-\247\023\264\071\272\054\272\275\321\153\314\363\245\050\355\104
-\236\175\122\243\157\226\056\031\176\034\363\133\307\026\216\273
-\140\175\167\146\107\124\202\000\021\140\154\062\301\250\070\033
-\353\156\230\023\326\356\070\365\360\237\016\357\376\061\201\301
-\322\044\225\057\123\172\151\242\360\017\206\105\216\130\202\053
-\114\042\324\136\240\347\175\046\047\110\337\045\106\215\112\050
-\174\206\236\371\233\032\131\271\145\277\005\335\266\102\135\075
-\346\000\110\202\136\040\367\021\202\336\312\330\237\346\067\107
-\046\036\353\170\367\141\303\101\144\130\002\101\371\332\340\321
-\370\371\350\375\122\070\266\365\211\337\002\003\001\000\001\243
-\133\060\131\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\006\060\035\006\003\125\035\016\004\026\004\024\015
-\214\266\141\332\104\270\321\024\175\303\276\175\136\110\360\316
-\312\152\260\060\027\006\003\125\035\040\004\020\060\016\060\014
-\006\012\052\201\172\001\126\002\002\000\001\001\060\015\006\011
-\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001\000
-\044\076\140\006\176\035\357\072\076\333\352\257\034\232\054\001
-\013\364\305\265\331\111\061\364\135\101\215\211\014\116\377\154
-\242\375\377\342\006\310\071\237\361\132\251\335\042\130\025\250
-\212\323\261\346\062\011\202\003\154\327\077\010\307\370\271\272
-\000\155\271\326\374\122\062\135\244\177\244\061\224\273\266\114
-\070\177\050\060\065\377\237\043\123\267\266\356\024\160\000\100
-\053\332\107\253\064\176\136\247\126\060\141\053\213\103\254\375
-\266\210\050\365\153\266\076\140\112\272\102\220\064\147\215\352
-\353\137\105\124\073\027\254\213\344\306\145\017\356\320\214\135
-\146\071\316\062\247\330\020\227\300\176\064\234\237\224\363\366
-\206\037\317\033\163\255\224\171\207\150\160\303\063\245\160\347
-\330\325\070\224\157\143\171\353\277\012\016\010\347\305\057\017
-\102\240\053\024\100\377\041\340\005\305\047\341\204\021\023\272
-\326\206\035\101\013\023\043\211\323\311\013\350\212\272\172\243
-\243\163\067\065\200\175\022\270\063\167\100\070\300\372\136\060
-\322\362\266\243\261\326\242\225\227\201\233\122\355\151\114\377
-\200\344\123\333\124\133\003\155\124\137\261\270\357\044\275\157
-\237\021\303\307\144\302\017\050\142\205\146\136\032\173\262\267
-\357\256\065\311\031\063\250\270\047\333\063\125\277\150\341\165
-\110\104\126\373\315\323\110\273\107\211\072\254\151\365\200\306
-\344\104\120\057\124\304\252\103\305\061\061\130\275\226\305\352
-\165\154\232\165\261\115\370\367\227\377\226\026\362\227\115\350
-\366\363\021\371\072\175\212\070\156\004\313\341\323\105\025\252
-\245\321\035\235\135\143\350\044\346\066\024\342\207\255\033\131
-\365\104\233\373\327\167\174\037\001\160\142\241\040\032\242\305
-\032\050\364\041\003\356\056\331\301\200\352\271\331\202\326\133
-\166\302\313\073\265\322\000\360\243\016\341\255\156\100\367\333
-\240\264\320\106\256\025\327\104\302\115\065\371\322\013\362\027
-\366\254\146\325\044\262\117\321\034\231\300\156\365\175\353\164
-\004\270\371\115\167\011\327\264\317\007\060\011\361\270\000\126
-\331\027\026\026\012\053\206\337\217\001\031\032\345\273\202\143
-\377\276\013\166\026\136\067\067\346\330\164\227\242\231\105\171
-END
-
-# Trust for Certificate "Certinomis - Autorité Racine"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Certinomis - Autorité Racine"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\056\024\332\354\050\360\372\036\216\070\232\116\253\353\046\300
-\012\323\203\303
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\177\060\170\214\003\343\312\311\012\342\311\352\036\252\125\032
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\106\122\061
-\023\060\021\006\003\125\004\012\023\012\103\145\162\164\151\156
-\157\155\151\163\061\027\060\025\006\003\125\004\013\023\016\060
-\060\060\062\040\064\063\063\071\071\070\071\060\063\061\046\060
-\044\006\003\125\004\003\014\035\103\145\162\164\151\156\157\155
-\151\163\040\055\040\101\165\164\157\162\151\164\303\251\040\122
-\141\143\151\156\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Root CA Generalitat Valenciana"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Root CA Generalitat Valenciana"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\150\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\037\060\035\006\003\125\004\012\023\026\107\145\156\145\162\141
-\154\151\164\141\164\040\126\141\154\145\156\143\151\141\156\141
-\061\017\060\015\006\003\125\004\013\023\006\120\113\111\107\126
-\101\061\047\060\045\006\003\125\004\003\023\036\122\157\157\164
-\040\103\101\040\107\145\156\145\162\141\154\151\164\141\164\040
-\126\141\154\145\156\143\151\141\156\141
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\150\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\037\060\035\006\003\125\004\012\023\026\107\145\156\145\162\141
-\154\151\164\141\164\040\126\141\154\145\156\143\151\141\156\141
-\061\017\060\015\006\003\125\004\013\023\006\120\113\111\107\126
-\101\061\047\060\045\006\003\125\004\003\023\036\122\157\157\164
-\040\103\101\040\107\145\156\145\162\141\154\151\164\141\164\040
-\126\141\154\145\156\143\151\141\156\141
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\073\105\345\150
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\006\213\060\202\005\163\240\003\002\001\002\002\004\073
-\105\345\150\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\150\061\013\060\011\006\003\125\004\006\023\002\105
-\123\061\037\060\035\006\003\125\004\012\023\026\107\145\156\145
-\162\141\154\151\164\141\164\040\126\141\154\145\156\143\151\141
-\156\141\061\017\060\015\006\003\125\004\013\023\006\120\113\111
-\107\126\101\061\047\060\045\006\003\125\004\003\023\036\122\157
-\157\164\040\103\101\040\107\145\156\145\162\141\154\151\164\141
-\164\040\126\141\154\145\156\143\151\141\156\141\060\036\027\015
-\060\061\060\067\060\066\061\066\062\062\064\067\132\027\015\062
-\061\060\067\060\061\061\065\062\062\064\067\132\060\150\061\013
-\060\011\006\003\125\004\006\023\002\105\123\061\037\060\035\006
-\003\125\004\012\023\026\107\145\156\145\162\141\154\151\164\141
-\164\040\126\141\154\145\156\143\151\141\156\141\061\017\060\015
-\006\003\125\004\013\023\006\120\113\111\107\126\101\061\047\060
-\045\006\003\125\004\003\023\036\122\157\157\164\040\103\101\040
-\107\145\156\145\162\141\154\151\164\141\164\040\126\141\154\145
-\156\143\151\141\156\141\060\202\001\042\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202
-\001\012\002\202\001\001\000\306\052\253\127\021\067\057\042\212
-\312\003\164\035\312\355\055\242\013\274\063\122\100\046\107\276
-\132\151\246\073\162\066\027\114\350\337\270\273\057\166\341\100
-\106\164\145\002\220\122\010\264\377\250\214\301\340\307\211\126
-\020\071\063\357\150\264\137\137\332\155\043\241\211\136\042\243
-\112\006\360\047\360\127\271\370\351\116\062\167\012\077\101\144
-\363\353\145\356\166\376\124\252\175\035\040\256\363\327\164\302
-\012\137\365\010\050\122\010\314\125\135\322\017\333\232\201\245
-\273\241\263\301\224\315\124\340\062\165\061\221\032\142\262\336
-\165\342\317\117\211\331\221\220\017\101\033\264\132\112\167\275
-\147\203\340\223\347\136\247\014\347\201\323\364\122\254\123\262
-\003\307\104\046\373\171\345\313\064\140\120\020\173\033\333\153
-\327\107\253\137\174\150\312\156\235\101\003\020\356\153\231\173
-\136\045\250\302\253\344\300\363\134\234\343\276\316\061\114\144
-\036\136\200\242\365\203\176\014\326\312\214\125\216\276\340\276
-\111\007\017\243\044\101\172\130\035\204\352\130\022\310\341\267
-\355\357\223\336\224\010\061\002\003\001\000\001\243\202\003\073
-\060\202\003\067\060\062\006\010\053\006\001\005\005\007\001\001
-\004\046\060\044\060\042\006\010\053\006\001\005\005\007\060\001
-\206\026\150\164\164\160\072\057\057\157\143\163\160\056\160\153
-\151\056\147\166\141\056\145\163\060\022\006\003\125\035\023\001
-\001\377\004\010\060\006\001\001\377\002\001\002\060\202\002\064
-\006\003\125\035\040\004\202\002\053\060\202\002\047\060\202\002
-\043\006\012\053\006\001\004\001\277\125\002\001\000\060\202\002
-\023\060\202\001\350\006\010\053\006\001\005\005\007\002\002\060
-\202\001\332\036\202\001\326\000\101\000\165\000\164\000\157\000
-\162\000\151\000\144\000\141\000\144\000\040\000\144\000\145\000
-\040\000\103\000\145\000\162\000\164\000\151\000\146\000\151\000
-\143\000\141\000\143\000\151\000\363\000\156\000\040\000\122\000
-\141\000\355\000\172\000\040\000\144\000\145\000\040\000\154\000
-\141\000\040\000\107\000\145\000\156\000\145\000\162\000\141\000
-\154\000\151\000\164\000\141\000\164\000\040\000\126\000\141\000
-\154\000\145\000\156\000\143\000\151\000\141\000\156\000\141\000
-\056\000\015\000\012\000\114\000\141\000\040\000\104\000\145\000
-\143\000\154\000\141\000\162\000\141\000\143\000\151\000\363\000
-\156\000\040\000\144\000\145\000\040\000\120\000\162\000\341\000
-\143\000\164\000\151\000\143\000\141\000\163\000\040\000\144\000
-\145\000\040\000\103\000\145\000\162\000\164\000\151\000\146\000
-\151\000\143\000\141\000\143\000\151\000\363\000\156\000\040\000
-\161\000\165\000\145\000\040\000\162\000\151\000\147\000\145\000
-\040\000\145\000\154\000\040\000\146\000\165\000\156\000\143\000
-\151\000\157\000\156\000\141\000\155\000\151\000\145\000\156\000
-\164\000\157\000\040\000\144\000\145\000\040\000\154\000\141\000
-\040\000\160\000\162\000\145\000\163\000\145\000\156\000\164\000
-\145\000\040\000\101\000\165\000\164\000\157\000\162\000\151\000
-\144\000\141\000\144\000\040\000\144\000\145\000\040\000\103\000
-\145\000\162\000\164\000\151\000\146\000\151\000\143\000\141\000
-\143\000\151\000\363\000\156\000\040\000\163\000\145\000\040\000
-\145\000\156\000\143\000\165\000\145\000\156\000\164\000\162\000
-\141\000\040\000\145\000\156\000\040\000\154\000\141\000\040\000
-\144\000\151\000\162\000\145\000\143\000\143\000\151\000\363\000
-\156\000\040\000\167\000\145\000\142\000\040\000\150\000\164\000
-\164\000\160\000\072\000\057\000\057\000\167\000\167\000\167\000
-\056\000\160\000\153\000\151\000\056\000\147\000\166\000\141\000
-\056\000\145\000\163\000\057\000\143\000\160\000\163\060\045\006
-\010\053\006\001\005\005\007\002\001\026\031\150\164\164\160\072
-\057\057\167\167\167\056\160\153\151\056\147\166\141\056\145\163
-\057\143\160\163\060\035\006\003\125\035\016\004\026\004\024\173
-\065\323\100\322\034\170\031\146\357\164\020\050\334\076\117\262
-\170\004\374\060\201\225\006\003\125\035\043\004\201\215\060\201
-\212\200\024\173\065\323\100\322\034\170\031\146\357\164\020\050
-\334\076\117\262\170\004\374\241\154\244\152\060\150\061\013\060
-\011\006\003\125\004\006\023\002\105\123\061\037\060\035\006\003
-\125\004\012\023\026\107\145\156\145\162\141\154\151\164\141\164
-\040\126\141\154\145\156\143\151\141\156\141\061\017\060\015\006
-\003\125\004\013\023\006\120\113\111\107\126\101\061\047\060\045
-\006\003\125\004\003\023\036\122\157\157\164\040\103\101\040\107
-\145\156\145\162\141\154\151\164\141\164\040\126\141\154\145\156
-\143\151\141\156\141\202\004\073\105\345\150\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000\044
-\141\116\365\265\310\102\002\052\263\134\165\255\305\155\312\347
-\224\077\245\150\225\210\301\124\300\020\151\242\022\057\030\077
-\045\120\250\174\112\352\306\011\331\364\165\306\100\332\257\120
-\235\075\245\026\273\155\061\306\307\163\012\110\376\040\162\355
-\157\314\350\203\141\026\106\220\001\225\113\175\216\232\122\011
-\057\366\157\034\344\241\161\317\214\052\132\027\163\203\107\115
-\017\066\373\004\115\111\121\342\024\311\144\141\373\324\024\340
-\364\236\267\064\217\012\046\275\227\134\364\171\072\112\060\031
-\314\255\117\240\230\212\264\061\227\052\342\163\155\176\170\270
-\370\210\211\117\261\042\221\144\113\365\120\336\003\333\345\305
-\166\347\023\146\165\176\145\373\001\237\223\207\210\235\371\106
-\127\174\115\140\257\230\163\023\043\244\040\221\201\372\320\141
-\146\270\175\321\257\326\157\036\154\075\351\021\375\251\371\202
-\042\206\231\063\161\132\352\031\127\075\221\315\251\300\243\156
-\007\023\246\311\355\370\150\243\236\303\132\162\011\207\050\321
-\304\163\304\163\030\137\120\165\026\061\237\267\350\174\303
-END
-
-# Trust for Certificate "Root CA Generalitat Valenciana"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Root CA Generalitat Valenciana"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\240\163\345\305\275\103\141\015\206\114\041\023\012\205\130\127
-\314\234\352\106
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\054\214\027\136\261\124\253\223\027\265\066\132\333\321\306\362
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\150\061\013\060\011\006\003\125\004\006\023\002\105\123\061
-\037\060\035\006\003\125\004\012\023\026\107\145\156\145\162\141
-\154\151\164\141\164\040\126\141\154\145\156\143\151\141\156\141
-\061\017\060\015\006\003\125\004\013\023\006\120\113\111\107\126
-\101\061\047\060\045\006\003\125\004\003\023\036\122\157\157\164
-\040\103\101\040\107\145\156\145\162\141\154\151\164\141\164\040
-\126\141\154\145\156\143\151\141\156\141
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\073\105\345\150
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "A-Trust-nQual-03"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "A-Trust-nQual-03"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\215\061\013\060\011\006\003\125\004\006\023\002\101\124
-\061\110\060\106\006\003\125\004\012\014\077\101\055\124\162\165
-\163\164\040\107\145\163\056\040\146\056\040\123\151\143\150\145
-\162\150\145\151\164\163\163\171\163\164\145\155\145\040\151\155
-\040\145\154\145\153\164\162\056\040\104\141\164\145\156\166\145
-\162\153\145\150\162\040\107\155\142\110\061\031\060\027\006\003
-\125\004\013\014\020\101\055\124\162\165\163\164\055\156\121\165
-\141\154\055\060\063\061\031\060\027\006\003\125\004\003\014\020
-\101\055\124\162\165\163\164\055\156\121\165\141\154\055\060\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\215\061\013\060\011\006\003\125\004\006\023\002\101\124
-\061\110\060\106\006\003\125\004\012\014\077\101\055\124\162\165
-\163\164\040\107\145\163\056\040\146\056\040\123\151\143\150\145
-\162\150\145\151\164\163\163\171\163\164\145\155\145\040\151\155
-\040\145\154\145\153\164\162\056\040\104\141\164\145\156\166\145
-\162\153\145\150\162\040\107\155\142\110\061\031\060\027\006\003
-\125\004\013\014\020\101\055\124\162\165\163\164\055\156\121\165
-\141\154\055\060\063\061\031\060\027\006\003\125\004\003\014\020
-\101\055\124\162\165\163\164\055\156\121\165\141\154\055\060\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\003\001\154\036
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\317\060\202\002\267\240\003\002\001\002\002\003\001
-\154\036\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\060\201\215\061\013\060\011\006\003\125\004\006\023\002\101
-\124\061\110\060\106\006\003\125\004\012\014\077\101\055\124\162
-\165\163\164\040\107\145\163\056\040\146\056\040\123\151\143\150
-\145\162\150\145\151\164\163\163\171\163\164\145\155\145\040\151
-\155\040\145\154\145\153\164\162\056\040\104\141\164\145\156\166
-\145\162\153\145\150\162\040\107\155\142\110\061\031\060\027\006
-\003\125\004\013\014\020\101\055\124\162\165\163\164\055\156\121
-\165\141\154\055\060\063\061\031\060\027\006\003\125\004\003\014
-\020\101\055\124\162\165\163\164\055\156\121\165\141\154\055\060
-\063\060\036\027\015\060\065\060\070\061\067\062\062\060\060\060
-\060\132\027\015\061\065\060\070\061\067\062\062\060\060\060\060
-\132\060\201\215\061\013\060\011\006\003\125\004\006\023\002\101
-\124\061\110\060\106\006\003\125\004\012\014\077\101\055\124\162
-\165\163\164\040\107\145\163\056\040\146\056\040\123\151\143\150
-\145\162\150\145\151\164\163\163\171\163\164\145\155\145\040\151
-\155\040\145\154\145\153\164\162\056\040\104\141\164\145\156\166
-\145\162\153\145\150\162\040\107\155\142\110\061\031\060\027\006
-\003\125\004\013\014\020\101\055\124\162\165\163\164\055\156\121
-\165\141\154\055\060\063\061\031\060\027\006\003\125\004\003\014
-\020\101\055\124\162\165\163\164\055\156\121\165\141\154\055\060
-\063\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001
-\001\000\255\075\141\156\003\363\220\073\300\101\013\204\200\315
-\354\052\243\235\153\273\156\302\102\204\367\121\024\341\240\250
-\055\121\243\121\362\336\043\360\064\104\377\224\353\314\005\043
-\225\100\271\007\170\245\045\366\012\275\105\206\350\331\275\300
-\004\216\205\104\141\357\177\247\311\372\301\045\314\205\054\143
-\077\005\140\163\111\005\340\140\170\225\020\113\334\371\021\131
-\316\161\177\100\233\212\252\044\337\013\102\342\333\126\274\112
-\322\245\014\233\267\103\076\335\203\323\046\020\002\317\352\043
-\304\111\116\345\323\351\264\210\253\014\256\142\222\324\145\207
-\331\152\327\364\205\237\344\063\042\045\245\345\310\063\272\303
-\307\101\334\137\306\152\314\000\016\155\062\250\266\207\066\000
-\142\167\233\036\037\064\313\220\074\170\210\164\005\353\171\365
-\223\161\145\312\235\307\153\030\055\075\134\116\347\325\370\077
-\061\175\217\207\354\012\042\057\043\351\376\273\175\311\340\364
-\354\353\174\304\260\303\055\142\265\232\161\326\261\152\350\354
-\331\355\325\162\354\276\127\001\316\005\125\237\336\321\140\210
-\020\263\002\003\001\000\001\243\066\060\064\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\021\006\003
-\125\035\016\004\012\004\010\104\152\225\147\125\171\021\117\060
-\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202
-\001\001\000\125\324\124\321\131\110\134\263\223\205\252\277\143
-\057\344\200\316\064\243\064\142\076\366\330\356\147\210\061\004
-\003\157\013\324\007\373\116\165\017\323\056\323\300\027\307\306
-\050\354\006\015\021\044\016\016\245\135\277\214\262\023\226\161
-\334\324\316\016\015\012\150\062\154\271\101\061\031\253\261\007
-\173\115\230\323\134\260\321\360\247\102\240\265\304\216\257\376
-\361\077\364\357\117\106\000\166\353\002\373\371\235\322\100\226
-\307\210\072\270\237\021\171\363\200\145\250\275\037\323\170\201
-\240\121\114\067\264\246\135\045\160\321\146\311\150\371\056\021
-\024\150\361\124\230\010\254\046\222\017\336\211\236\324\372\263
-\171\053\322\243\171\324\354\213\254\207\123\150\102\114\121\121
-\164\036\033\047\056\343\365\037\051\164\115\355\257\367\341\222
-\231\201\350\276\072\307\027\120\366\267\306\374\233\260\212\153
-\326\210\003\221\217\006\167\072\205\002\335\230\325\103\170\077
-\306\060\025\254\233\153\313\127\267\211\121\213\072\350\311\204
-\014\333\261\120\040\012\032\112\272\152\032\275\354\033\310\305
-\204\232\315
-END
-
-# Trust for Certificate "A-Trust-nQual-03"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "A-Trust-nQual-03"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\323\300\143\362\031\355\007\076\064\255\135\165\013\062\166\051
-\377\325\232\362
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\111\143\256\047\364\325\225\075\330\333\044\206\270\234\007\123
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\215\061\013\060\011\006\003\125\004\006\023\002\101\124
-\061\110\060\106\006\003\125\004\012\014\077\101\055\124\162\165
-\163\164\040\107\145\163\056\040\146\056\040\123\151\143\150\145
-\162\150\145\151\164\163\163\171\163\164\145\155\145\040\151\155
-\040\145\154\145\153\164\162\056\040\104\141\164\145\156\166\145
-\162\153\145\150\162\040\107\155\142\110\061\031\060\027\006\003
-\125\004\013\014\020\101\055\124\162\165\163\164\055\156\121\165
-\141\154\055\060\063\061\031\060\027\006\003\125\004\003\014\020
-\101\055\124\162\165\163\164\055\156\121\165\141\154\055\060\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\003\001\154\036
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "TWCA Root Certification Authority"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TWCA Root Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\022\060\020\006\003\125\004\012\014\011\124\101\111\127\101\116
-\055\103\101\061\020\060\016\006\003\125\004\013\014\007\122\157
-\157\164\040\103\101\061\052\060\050\006\003\125\004\003\014\041
-\124\127\103\101\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\022\060\020\006\003\125\004\012\014\011\124\101\111\127\101\116
-\055\103\101\061\020\060\016\006\003\125\004\013\014\007\122\157
-\157\164\040\103\101\061\052\060\050\006\003\125\004\003\014\041
-\124\127\103\101\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\173\060\202\002\143\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\137\061\013\060\011\006\003\125\004\006\023\002\124\127\061\022
-\060\020\006\003\125\004\012\014\011\124\101\111\127\101\116\055
-\103\101\061\020\060\016\006\003\125\004\013\014\007\122\157\157
-\164\040\103\101\061\052\060\050\006\003\125\004\003\014\041\124
-\127\103\101\040\122\157\157\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-\060\036\027\015\060\070\060\070\062\070\060\067\062\064\063\063
-\132\027\015\063\060\061\062\063\061\061\065\065\071\065\071\132
-\060\137\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\022\060\020\006\003\125\004\012\014\011\124\101\111\127\101\116
-\055\103\101\061\020\060\016\006\003\125\004\013\014\007\122\157
-\157\164\040\103\101\061\052\060\050\006\003\125\004\003\014\041
-\124\127\103\101\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001
-\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001
-\001\000\260\176\162\270\244\003\224\346\247\336\011\070\221\112
-\021\100\207\247\174\131\144\024\173\265\021\020\335\376\277\325
-\300\273\126\342\205\045\364\065\162\017\370\123\320\101\341\104
-\001\302\264\034\303\061\102\026\107\205\063\042\166\262\012\157
-\017\345\045\120\117\205\206\276\277\230\056\020\147\036\276\021
-\005\206\005\220\304\131\320\174\170\020\260\200\134\267\341\307
-\053\165\313\174\237\256\265\321\235\043\067\143\247\334\102\242
-\055\222\004\033\120\301\173\270\076\033\311\126\004\213\057\122
-\233\255\251\126\351\301\377\255\251\130\207\060\266\201\367\227
-\105\374\031\127\073\053\157\344\107\364\231\105\376\035\361\370
-\227\243\210\035\067\034\134\217\340\166\045\232\120\370\240\124
-\377\104\220\166\043\322\062\306\303\253\006\277\374\373\277\363
-\255\175\222\142\002\133\051\323\065\243\223\232\103\144\140\135
-\262\372\062\377\073\004\257\115\100\152\371\307\343\357\043\375
-\153\313\345\017\213\070\015\356\012\374\376\017\230\237\060\061
-\335\154\122\145\371\213\201\276\042\341\034\130\003\272\221\033
-\211\007\002\003\001\000\001\243\102\060\100\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\035\006\003
-\125\035\016\004\026\004\024\152\070\133\046\215\336\213\132\362
-\117\172\124\203\031\030\343\010\065\246\272\060\015\006\011\052
-\206\110\206\367\015\001\001\005\005\000\003\202\001\001\000\074
-\325\167\075\332\337\211\272\207\014\010\124\152\040\120\222\276
-\260\101\075\271\046\144\203\012\057\350\100\300\227\050\047\202
-\060\112\311\223\377\152\347\246\000\177\211\102\232\326\021\345
-\123\316\057\314\362\332\005\304\376\342\120\304\072\206\175\314
-\332\176\020\011\073\222\065\052\123\262\376\353\053\005\331\154
-\135\346\320\357\323\152\146\236\025\050\205\172\350\202\000\254
-\036\247\011\151\126\102\323\150\121\030\276\124\232\277\104\101
-\272\111\276\040\272\151\134\356\270\167\315\316\154\037\255\203
-\226\030\175\016\265\024\071\204\361\050\351\055\243\236\173\036
-\172\162\132\203\263\171\157\357\264\374\320\012\245\130\117\106
-\337\373\155\171\131\362\204\042\122\256\017\314\373\174\073\347
-\152\312\107\141\303\172\370\323\222\004\037\270\040\204\341\066
-\124\026\307\100\336\073\212\163\334\337\306\011\114\337\354\332
-\377\324\123\102\241\311\362\142\035\042\203\074\227\305\371\031
-\142\047\254\145\042\327\323\074\306\345\216\262\123\314\111\316
-\274\060\376\173\016\063\220\373\355\322\024\221\037\007\257
-END
-
-# Trust for Certificate "TWCA Root Certification Authority"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TWCA Root Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\317\236\207\155\323\353\374\102\046\227\243\265\243\172\240\166
-\251\006\043\110
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\252\010\217\366\371\173\267\362\261\247\036\233\352\352\275\171
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\124\127\061
-\022\060\020\006\003\125\004\012\014\011\124\101\111\127\101\116
-\055\103\101\061\020\060\016\006\003\125\004\013\014\007\122\157
-\157\164\040\103\101\061\052\060\050\006\003\125\004\003\014\041
-\124\127\103\101\040\122\157\157\164\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Explicitly Distrust DigiNotar Root CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\032\060\030\006\003\125\004\003\023\021\104\151
-\147\151\116\157\164\141\162\040\122\157\157\164\040\103\101\061
-\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026\021
-\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056\156
-\154
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\032\060\030\006\003\125\004\003\023\021\104\151
-\147\151\116\157\164\141\162\040\122\157\157\164\040\103\101\061
-\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026\021
-\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056\156
-\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\017\377\377\377\377\377\377\377\377\377\377\377\377\377
-\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\212\060\202\003\162\240\003\002\001\002\002\020\017
-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\137
-\061\013\060\011\006\003\125\004\006\023\002\116\114\061\022\060
-\020\006\003\125\004\012\023\011\104\151\147\151\116\157\164\141
-\162\061\032\060\030\006\003\125\004\003\023\021\104\151\147\151
-\116\157\164\141\162\040\122\157\157\164\040\103\101\061\040\060
-\036\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156
-\146\157\100\144\151\147\151\156\157\164\141\162\056\156\154\060
-\036\027\015\060\067\060\067\062\067\061\067\061\071\063\067\132
-\027\015\062\065\060\063\063\061\061\070\061\071\062\062\132\060
-\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061\022
-\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157\164
-\141\162\061\032\060\030\006\003\125\004\003\023\021\104\151\147
-\151\116\157\164\141\162\040\122\157\157\164\040\103\101\061\040
-\060\036\006\011\052\206\110\206\367\015\001\011\001\026\021\151
-\156\146\157\100\144\151\147\151\156\157\164\141\162\056\156\154
-\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001
-\000\254\260\130\301\000\275\330\041\010\013\053\232\376\156\126
-\060\005\237\033\167\220\020\101\134\303\015\207\021\167\216\201
-\361\312\174\351\214\152\355\070\164\065\273\332\337\371\273\300
-\011\067\264\226\163\201\175\063\032\230\071\367\223\157\225\177
-\075\271\261\165\207\272\121\110\350\213\160\076\225\004\305\330
-\266\303\026\331\210\260\261\207\035\160\332\206\264\017\024\213
-\172\317\020\321\164\066\242\022\173\167\206\112\171\346\173\337
-\002\021\150\245\116\206\256\064\130\233\044\023\170\126\042\045
-\036\001\213\113\121\161\373\202\314\131\226\151\210\132\150\123
-\305\271\015\002\067\313\113\274\146\112\220\176\052\013\005\007
-\355\026\137\125\220\165\330\106\311\033\203\342\010\276\361\043
-\314\231\035\326\052\017\203\040\025\130\047\202\056\372\342\042
-\302\111\261\271\001\201\152\235\155\235\100\167\150\166\116\041
-\052\155\204\100\205\116\166\231\174\202\363\363\267\002\131\324
-\046\001\033\216\337\255\123\006\321\256\030\335\342\262\072\313
-\327\210\070\216\254\133\051\271\031\323\230\371\030\003\317\110
-\202\206\146\013\033\151\017\311\353\070\210\172\046\032\005\114
-\222\327\044\324\226\362\254\122\055\243\107\325\122\366\077\376
-\316\204\006\160\246\252\076\242\362\266\126\064\030\127\242\344
-\201\155\347\312\360\152\323\307\221\153\002\203\101\174\025\357
-\153\232\144\136\343\320\074\345\261\353\173\135\206\373\313\346
-\167\111\315\243\145\334\367\271\234\270\344\013\137\223\317\314
-\060\032\062\034\316\034\143\225\245\371\352\341\164\213\236\351
-\053\251\060\173\240\030\037\016\030\013\345\133\251\323\321\154
-\036\007\147\217\221\113\251\212\274\322\146\252\223\001\210\262
-\221\372\061\134\325\246\301\122\010\011\315\012\143\242\323\042
-\246\350\241\331\071\006\227\365\156\215\002\220\214\024\173\077
-\200\315\033\234\272\304\130\162\043\257\266\126\237\306\172\102
-\063\051\007\077\202\311\346\037\005\015\315\114\050\066\213\323
-\310\076\034\306\210\357\136\356\211\144\351\035\353\332\211\176
-\062\246\151\321\335\314\210\237\321\320\311\146\041\334\006\147
-\305\224\172\232\155\142\114\175\314\340\144\200\262\236\107\216
-\243\002\003\001\000\001\243\102\060\100\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003\125
-\035\016\004\026\004\024\210\150\277\340\216\065\304\073\070\153
-\142\367\050\073\204\201\310\014\327\115\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\002\001\000\073\002
-\215\313\074\060\350\156\240\255\362\163\263\137\236\045\023\004
-\005\323\366\343\213\273\013\171\316\123\336\344\226\305\321\257
-\163\274\325\303\320\100\125\174\100\177\315\033\137\011\325\362
-\174\237\150\035\273\135\316\172\071\302\214\326\230\173\305\203
-\125\250\325\175\100\312\340\036\367\211\136\143\135\241\023\302
-\135\212\266\212\174\000\363\043\303\355\205\137\161\166\360\150
-\143\252\105\041\071\110\141\170\066\334\361\103\223\324\045\307
-\362\200\145\341\123\002\165\121\374\172\072\357\067\253\204\050
-\127\014\330\324\324\231\126\154\343\242\376\131\204\264\061\350
-\063\370\144\224\224\121\227\253\071\305\113\355\332\335\200\013
-\157\174\051\015\304\216\212\162\015\347\123\024\262\140\101\075
-\204\221\061\150\075\047\104\333\345\336\364\372\143\105\310\114
-\076\230\365\077\101\272\116\313\067\015\272\146\230\361\335\313
-\237\134\367\124\066\202\153\054\274\023\141\227\102\370\170\273
-\314\310\242\237\312\360\150\275\153\035\262\337\215\157\007\235
-\332\216\147\307\107\036\312\271\277\052\102\221\267\143\123\146
-\361\102\243\341\364\132\115\130\153\265\344\244\063\255\134\160
-\035\334\340\362\353\163\024\221\232\003\301\352\000\145\274\007
-\374\317\022\021\042\054\256\240\275\072\340\242\052\330\131\351
-\051\323\030\065\244\254\021\137\031\265\265\033\377\042\112\134
-\306\172\344\027\357\040\251\247\364\077\255\212\247\232\004\045
-\235\016\312\067\346\120\375\214\102\051\004\232\354\271\317\113
-\162\275\342\010\066\257\043\057\142\345\312\001\323\160\333\174
-\202\043\054\026\061\014\306\066\007\220\172\261\037\147\130\304
-\073\130\131\211\260\214\214\120\263\330\206\313\150\243\304\012
-\347\151\113\040\316\301\036\126\113\225\251\043\150\330\060\330
-\303\353\260\125\121\315\345\375\053\270\365\273\021\237\123\124
-\366\064\031\214\171\011\066\312\141\027\045\027\013\202\230\163
-\014\167\164\303\325\015\307\250\022\114\307\247\124\161\107\056
-\054\032\175\311\343\053\073\110\336\047\204\247\143\066\263\175
-\217\240\144\071\044\015\075\173\207\257\146\134\164\033\113\163
-\262\345\214\360\206\231\270\345\305\337\204\301\267\353
-END
-
-# Trust for Certificate "Explicitly Distrust DigiNotar Root CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\301\167\313\113\340\264\046\216\365\307\317\105\231\042\271\260
-\316\272\041\057
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\012\244\325\314\272\264\373\243\131\343\346\001\335\123\331\116
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\032\060\030\006\003\125\004\003\023\021\104\151
-\147\151\116\157\164\141\162\040\122\157\157\164\040\103\101\061
-\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026\021
-\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056\156
-\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\017\377\377\377\377\377\377\377\377\377\377\377\377\377
-\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Explicitly Distrust DigiNotar Services 1024 CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Services 1024 CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\150\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\043\060\041\006\003\125\004\003\023\032\104\151
-\147\151\116\157\164\141\162\040\123\145\162\166\151\143\145\163
-\040\061\060\062\064\040\103\101\061\040\060\036\006\011\052\206
-\110\206\367\015\001\011\001\026\021\151\156\146\157\100\144\151
-\147\151\156\157\164\141\162\056\156\154
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\150\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\043\060\041\006\003\125\004\003\023\032\104\151
-\147\151\116\157\164\141\162\040\123\145\162\166\151\143\145\163
-\040\061\060\062\064\040\103\101\061\040\060\036\006\011\052\206
-\110\206\367\015\001\011\001\026\021\151\156\146\157\100\144\151
-\147\151\156\157\164\141\162\056\156\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\161\060\202\002\332\240\003\002\001\002\002\004\017
-\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\150\061\013\060\011\006\003\125\004\006\023\002\116
-\114\061\022\060\020\006\003\125\004\012\023\011\104\151\147\151
-\116\157\164\141\162\061\043\060\041\006\003\125\004\003\023\032
-\104\151\147\151\116\157\164\141\162\040\123\145\162\166\151\143
-\145\163\040\061\060\062\064\040\103\101\061\040\060\036\006\011
-\052\206\110\206\367\015\001\011\001\026\021\151\156\146\157\100
-\144\151\147\151\156\157\164\141\162\056\156\154\060\036\027\015
-\060\067\060\067\062\066\061\065\065\071\060\061\132\027\015\061
-\063\060\070\062\066\061\066\062\071\060\061\132\060\150\061\013
-\060\011\006\003\125\004\006\023\002\116\114\061\022\060\020\006
-\003\125\004\012\023\011\104\151\147\151\116\157\164\141\162\061
-\043\060\041\006\003\125\004\003\023\032\104\151\147\151\116\157
-\164\141\162\040\123\145\162\166\151\143\145\163\040\061\060\062
-\064\040\103\101\061\040\060\036\006\011\052\206\110\206\367\015
-\001\011\001\026\021\151\156\146\157\100\144\151\147\151\156\157
-\164\141\162\056\156\154\060\201\237\060\015\006\011\052\206\110
-\206\367\015\001\001\001\005\000\003\201\215\000\060\201\211\002
-\201\201\000\332\233\115\135\074\371\321\342\213\306\306\010\040
-\305\331\036\110\354\146\130\147\171\142\053\101\143\364\211\215
-\150\332\257\270\224\066\213\031\044\244\240\223\322\231\017\262
-\255\055\065\115\315\057\152\341\371\233\031\053\274\004\032\176
-\055\075\122\144\315\361\076\147\017\211\056\350\362\117\256\246
-\010\241\205\376\241\251\011\346\306\253\076\103\374\257\172\003
-\221\332\246\071\246\141\356\230\117\030\250\323\263\257\146\202
-\351\237\274\335\162\371\006\004\275\022\331\030\044\347\253\223
-\123\213\131\002\003\001\000\001\243\202\001\046\060\202\001\042
-\060\022\006\003\125\035\023\001\001\377\004\010\060\006\001\001
-\377\002\001\000\060\047\006\003\125\035\045\004\040\060\036\006
-\010\053\006\001\005\005\007\003\001\006\010\053\006\001\005\005
-\007\003\002\006\010\053\006\001\005\005\007\003\004\060\021\006
-\003\125\035\040\004\012\060\010\060\006\006\004\125\035\040\000
-\060\063\006\010\053\006\001\005\005\007\001\001\004\047\060\045
-\060\043\006\010\053\006\001\005\005\007\060\001\206\027\150\164
-\164\160\072\057\057\157\143\163\160\056\145\156\164\162\165\163
-\164\056\156\145\164\060\063\006\003\125\035\037\004\054\060\052
-\060\050\240\046\240\044\206\042\150\164\164\160\072\057\057\143
-\162\154\056\145\156\164\162\165\163\164\056\156\145\164\057\163
-\145\162\166\145\162\061\056\143\162\154\060\035\006\003\125\035
-\016\004\026\004\024\376\334\224\111\014\157\357\134\177\306\361
-\022\231\117\026\111\255\373\202\145\060\013\006\003\125\035\017
-\004\004\003\002\001\006\060\037\006\003\125\035\043\004\030\060
-\026\200\024\360\027\142\023\125\075\263\377\012\000\153\373\120
-\204\227\363\355\142\320\032\060\031\006\011\052\206\110\206\366
-\175\007\101\000\004\014\060\012\033\004\126\067\056\061\003\002
-\000\201\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\003\201\201\000\143\164\152\067\251\077\226\234\146\310\130
-\254\011\311\357\365\145\224\177\243\002\304\070\061\275\135\043
-\207\354\324\126\262\311\262\156\344\005\006\374\354\365\372\210
-\160\131\324\356\346\335\265\172\240\243\140\057\002\014\253\336
-\022\135\257\360\065\113\252\212\107\221\032\365\205\054\102\307
-\035\357\225\103\263\136\270\225\223\245\332\305\050\252\255\162
-\055\061\255\231\153\154\377\214\041\047\257\255\232\221\053\307
-\335\130\303\156\007\305\237\171\322\307\214\125\277\114\307\047
-\136\121\026\053\076
-END
-
-# Trust for Certificate "Explicitly Distrust DigiNotar Services 1024 CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Services 1024 CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\022\073\352\312\146\147\167\141\340\353\150\362\376\355\242\017
-\040\005\125\160
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\057\026\150\227\114\150\117\316\122\212\354\123\217\223\111\370
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\150\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\043\060\041\006\003\125\004\003\023\032\104\151
-\147\151\116\157\164\141\162\040\123\145\162\166\151\143\145\163
-\040\061\060\062\064\040\103\101\061\040\060\036\006\011\052\206
-\110\206\367\015\001\011\001\026\021\151\156\146\157\100\144\151
-\147\151\156\157\164\141\162\056\156\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Explicitly Distrust DigiNotar Cyber CA"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Cyber CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\140\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151
-\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101
-\061\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026
-\021\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056
-\156\154
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\140\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151
-\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101
-\061\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026
-\021\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056
-\156\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\105\060\202\004\256\240\003\002\001\002\002\004\017
-\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\140\061\013\060\011\006\003\125\004\006\023\002\116
-\114\061\022\060\020\006\003\125\004\012\023\011\104\151\147\151
-\116\157\164\141\162\061\033\060\031\006\003\125\004\003\023\022
-\104\151\147\151\116\157\164\141\162\040\103\171\142\145\162\040
-\103\101\061\040\060\036\006\011\052\206\110\206\367\015\001\011
-\001\026\021\151\156\146\157\100\144\151\147\151\156\157\164\141
-\162\056\156\154\060\036\027\015\060\066\061\060\060\064\061\060
-\065\064\061\062\132\027\015\061\061\061\060\060\064\061\060\065
-\063\061\062\132\060\140\061\013\060\011\006\003\125\004\006\023
-\002\116\114\061\022\060\020\006\003\125\004\012\023\011\104\151
-\147\151\116\157\164\141\162\061\033\060\031\006\003\125\004\003
-\023\022\104\151\147\151\116\157\164\141\162\040\103\171\142\145
-\162\040\103\101\061\040\060\036\006\011\052\206\110\206\367\015
-\001\011\001\026\021\151\156\146\157\100\144\151\147\151\156\157
-\164\141\162\056\156\154\060\202\002\042\060\015\006\011\052\206
-\110\206\367\015\001\001\001\005\000\003\202\002\017\000\060\202
-\002\012\002\202\002\001\000\322\316\025\012\055\250\136\204\147
-\255\375\276\357\106\307\310\271\317\163\374\364\064\271\371\054
-\103\347\140\023\075\172\343\262\317\073\147\154\220\255\300\271
-\077\204\122\360\065\102\334\164\334\050\073\275\122\264\247\254
-\162\105\027\306\360\211\353\264\252\045\362\135\113\136\321\331
-\207\272\326\175\174\365\316\062\237\020\063\305\261\112\273\136
-\221\061\302\320\351\101\302\221\144\176\011\101\073\333\213\010
-\067\152\252\312\122\336\265\071\036\300\210\003\245\077\213\231
-\023\141\103\265\233\202\263\356\040\157\317\241\104\242\352\057
-\153\100\237\217\053\127\255\241\123\302\205\042\151\235\240\077
-\121\337\013\101\221\015\245\341\250\252\134\111\010\135\275\336
-\160\101\261\017\311\143\153\323\177\064\164\002\057\064\132\170
-\165\034\150\172\201\147\212\363\332\100\360\140\143\364\222\040
-\327\003\246\075\243\036\147\304\204\033\101\245\311\214\346\275
-\352\110\266\005\026\010\263\067\022\132\367\141\074\367\070\157
-\056\227\340\157\126\070\124\323\050\265\255\024\156\056\113\144
-\265\047\145\267\165\045\011\266\007\075\225\126\002\012\202\140
-\262\163\105\340\063\046\121\164\232\271\324\120\034\366\115\133
-\133\122\122\023\132\246\177\247\016\341\350\101\124\147\230\214
-\207\325\311\323\154\313\323\124\222\006\011\064\101\367\201\157
-\077\236\311\174\165\125\260\347\301\263\167\350\303\304\000\065
-\225\100\160\020\112\005\336\045\273\237\131\245\144\274\107\140
-\277\140\343\166\213\023\125\335\341\164\172\271\317\044\246\152
-\177\336\144\042\104\130\150\202\152\020\371\075\345\076\033\271
-\275\374\042\364\140\004\211\273\125\155\050\125\372\336\216\215
-\033\041\024\327\067\213\064\173\115\366\262\262\020\317\063\261
-\175\034\142\231\110\313\053\154\166\226\125\277\031\015\035\037
-\273\145\252\033\216\231\265\306\050\220\345\202\055\170\120\040
-\232\375\171\057\044\177\360\211\051\151\364\175\315\163\276\263
-\355\116\301\321\355\122\136\217\367\270\327\215\207\255\262\331
-\033\121\022\377\126\263\341\257\064\175\134\244\170\210\020\236
-\235\003\306\245\252\242\044\121\367\111\024\305\261\356\131\103
-\225\337\253\150\050\060\077\002\003\001\000\001\243\202\001\206
-\060\202\001\202\060\022\006\003\125\035\023\001\001\377\004\010
-\060\006\001\001\377\002\001\001\060\123\006\003\125\035\040\004
-\114\060\112\060\110\006\011\053\006\001\004\001\261\076\001\000
-\060\073\060\071\006\010\053\006\001\005\005\007\002\001\026\055
-\150\164\164\160\072\057\057\167\167\167\056\160\165\142\154\151
-\143\055\164\162\165\163\164\056\143\157\155\057\103\120\123\057
-\117\155\156\151\122\157\157\164\056\150\164\155\154\060\016\006
-\003\125\035\017\001\001\377\004\004\003\002\001\006\060\201\240
-\006\003\125\035\043\004\201\230\060\201\225\200\024\246\014\035
-\237\141\377\007\027\265\277\070\106\333\103\060\325\216\260\122
-\006\241\171\244\167\060\165\061\013\060\011\006\003\125\004\006
-\023\002\125\123\061\030\060\026\006\003\125\004\012\023\017\107
-\124\105\040\103\157\162\160\157\162\141\164\151\157\156\061\047
-\060\045\006\003\125\004\013\023\036\107\124\105\040\103\171\142
-\145\162\124\162\165\163\164\040\123\157\154\165\164\151\157\156
-\163\054\040\111\156\143\056\061\043\060\041\006\003\125\004\003
-\023\032\107\124\105\040\103\171\142\145\162\124\162\165\163\164
-\040\107\154\157\142\141\154\040\122\157\157\164\202\002\001\245
-\060\105\006\003\125\035\037\004\076\060\074\060\072\240\070\240
-\066\206\064\150\164\164\160\072\057\057\167\167\167\056\160\165
-\142\154\151\143\055\164\162\165\163\164\056\143\157\155\057\143
-\147\151\055\142\151\156\057\103\122\114\057\062\060\061\070\057
-\143\144\160\056\143\162\154\060\035\006\003\125\035\016\004\026
-\004\024\253\371\150\337\317\112\067\327\173\105\214\137\162\336
-\100\104\303\145\273\302\060\015\006\011\052\206\110\206\367\015
-\001\001\005\005\000\003\201\201\000\217\150\153\245\133\007\272
-\104\146\016\034\250\134\060\173\063\344\012\046\004\374\357\236
-\032\070\326\056\241\037\320\231\107\302\165\144\044\375\236\073
-\050\166\271\046\050\141\221\014\155\054\370\004\237\174\120\001
-\325\343\151\257\357\025\322\105\233\044\011\052\146\005\117\045
-\201\312\135\276\252\301\131\047\256\063\216\202\367\337\164\260
-\125\263\216\370\347\067\310\156\252\126\104\366\275\123\201\043
-\226\075\264\372\062\212\123\146\104\045\242\045\306\246\074\045
-\214\360\340\050\006\042\267\046\101
-END
-
-# Trust for Certificate "Explicitly Distrust DigiNotar Cyber CA"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Cyber CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\245\216\240\354\366\104\126\065\031\035\150\133\307\240\344\034
-\260\115\171\056
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\274\275\211\022\264\377\345\371\046\107\310\140\066\133\331\124
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\140\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151
-\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101
-\061\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026
-\021\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056
-\156\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Explicitly Distrust DigiNotar Cyber CA 2nd"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Cyber CA 2nd"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\076\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151
-\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\076\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151
-\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\001\060\202\004\152\240\003\002\001\002\002\004\017
-\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\076\061\013\060\011\006\003\125\004\006\023\002\116
-\114\061\022\060\020\006\003\125\004\012\023\011\104\151\147\151
-\116\157\164\141\162\061\033\060\031\006\003\125\004\003\023\022
-\104\151\147\151\116\157\164\141\162\040\103\171\142\145\162\040
-\103\101\060\036\027\015\060\066\060\071\062\067\061\060\065\063
-\065\063\132\027\015\061\063\060\071\062\060\060\071\064\064\060
-\067\132\060\076\061\013\060\011\006\003\125\004\006\023\002\116
-\114\061\022\060\020\006\003\125\004\012\023\011\104\151\147\151
-\116\157\164\141\162\061\033\060\031\006\003\125\004\003\023\022
-\104\151\147\151\116\157\164\141\162\040\103\171\142\145\162\040
-\103\101\060\202\002\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202
-\002\001\000\322\316\025\012\055\250\136\204\147\255\375\276\357
-\106\307\310\271\317\163\374\364\064\271\371\054\103\347\140\023
-\075\172\343\262\317\073\147\154\220\255\300\271\077\204\122\360
-\065\102\334\164\334\050\073\275\122\264\247\254\162\105\027\306
-\360\211\353\264\252\045\362\135\113\136\321\331\207\272\326\175
-\174\365\316\062\237\020\063\305\261\112\273\136\221\061\302\320
-\351\101\302\221\144\176\011\101\073\333\213\010\067\152\252\312
-\122\336\265\071\036\300\210\003\245\077\213\231\023\141\103\265
-\233\202\263\356\040\157\317\241\104\242\352\057\153\100\237\217
-\053\127\255\241\123\302\205\042\151\235\240\077\121\337\013\101
-\221\015\245\341\250\252\134\111\010\135\275\336\160\101\261\017
-\311\143\153\323\177\064\164\002\057\064\132\170\165\034\150\172
-\201\147\212\363\332\100\360\140\143\364\222\040\327\003\246\075
-\243\036\147\304\204\033\101\245\311\214\346\275\352\110\266\005
-\026\010\263\067\022\132\367\141\074\367\070\157\056\227\340\157
-\126\070\124\323\050\265\255\024\156\056\113\144\265\047\145\267
-\165\045\011\266\007\075\225\126\002\012\202\140\262\163\105\340
-\063\046\121\164\232\271\324\120\034\366\115\133\133\122\122\023
-\132\246\177\247\016\341\350\101\124\147\230\214\207\325\311\323
-\154\313\323\124\222\006\011\064\101\367\201\157\077\236\311\174
-\165\125\260\347\301\263\167\350\303\304\000\065\225\100\160\020
-\112\005\336\045\273\237\131\245\144\274\107\140\277\140\343\166
-\213\023\125\335\341\164\172\271\317\044\246\152\177\336\144\042
-\104\130\150\202\152\020\371\075\345\076\033\271\275\374\042\364
-\140\004\211\273\125\155\050\125\372\336\216\215\033\041\024\327
-\067\213\064\173\115\366\262\262\020\317\063\261\175\034\142\231
-\110\313\053\154\166\226\125\277\031\015\035\037\273\145\252\033
-\216\231\265\306\050\220\345\202\055\170\120\040\232\375\171\057
-\044\177\360\211\051\151\364\175\315\163\276\263\355\116\301\321
-\355\122\136\217\367\270\327\215\207\255\262\331\033\121\022\377
-\126\263\341\257\064\175\134\244\170\210\020\236\235\003\306\245
-\252\242\044\121\367\111\024\305\261\356\131\103\225\337\253\150
-\050\060\077\002\003\001\000\001\243\202\001\206\060\202\001\202
-\060\022\006\003\125\035\023\001\001\377\004\010\060\006\001\001
-\377\002\001\001\060\123\006\003\125\035\040\004\114\060\112\060
-\110\006\011\053\006\001\004\001\261\076\001\000\060\073\060\071
-\006\010\053\006\001\005\005\007\002\001\026\055\150\164\164\160
-\072\057\057\167\167\167\056\160\165\142\154\151\143\055\164\162
-\165\163\164\056\143\157\155\057\103\120\123\057\117\155\156\151
-\122\157\157\164\056\150\164\155\154\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\001\006\060\201\240\006\003\125\035
-\043\004\201\230\060\201\225\200\024\246\014\035\237\141\377\007
-\027\265\277\070\106\333\103\060\325\216\260\122\006\241\171\244
-\167\060\165\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\030\060\026\006\003\125\004\012\023\017\107\124\105\040\103
-\157\162\160\157\162\141\164\151\157\156\061\047\060\045\006\003
-\125\004\013\023\036\107\124\105\040\103\171\142\145\162\124\162
-\165\163\164\040\123\157\154\165\164\151\157\156\163\054\040\111
-\156\143\056\061\043\060\041\006\003\125\004\003\023\032\107\124
-\105\040\103\171\142\145\162\124\162\165\163\164\040\107\154\157
-\142\141\154\040\122\157\157\164\202\002\001\245\060\105\006\003
-\125\035\037\004\076\060\074\060\072\240\070\240\066\206\064\150
-\164\164\160\072\057\057\167\167\167\056\160\165\142\154\151\143
-\055\164\162\165\163\164\056\143\157\155\057\143\147\151\055\142
-\151\156\057\103\122\114\057\062\060\061\070\057\143\144\160\056
-\143\162\154\060\035\006\003\125\035\016\004\026\004\024\253\371
-\150\337\317\112\067\327\173\105\214\137\162\336\100\104\303\145
-\273\302\060\015\006\011\052\206\110\206\367\015\001\001\005\005
-\000\003\201\201\000\011\312\142\017\215\273\112\340\324\172\065
-\053\006\055\321\050\141\266\254\001\373\203\111\274\256\324\057
-\055\206\256\031\203\245\326\035\023\342\027\276\376\062\164\351
-\172\024\070\312\224\136\367\051\001\151\161\033\221\032\375\243
-\273\252\035\312\173\342\026\375\241\243\016\363\014\137\262\341
-\040\061\224\053\136\222\166\355\372\351\265\043\246\277\012\073
-\003\251\157\122\140\124\315\137\351\267\057\174\242\047\375\101
-\203\165\266\015\373\170\046\363\261\105\351\062\225\052\032\065
-\041\225\305\242\165
-END
-
-# Trust for Certificate "Explicitly Distrust DigiNotar Cyber CA 2nd"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Cyber CA 2nd"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\210\036\105\005\017\230\331\131\373\012\065\371\114\016\050\227
-\125\026\051\263
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\360\256\251\075\362\054\210\334\174\205\033\226\175\132\034\021
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\076\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\033\060\031\006\003\125\004\003\023\022\104\151
-\147\151\116\157\164\141\162\040\103\171\142\145\162\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Explicitly Distrusted DigiNotar PKIoverheid"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted DigiNotar PKIoverheid"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\027\060\025\006\003\125\004\012\023\016\104\151\147\151\116\157
-\164\141\162\040\102\056\126\056\061\067\060\065\006\003\125\004
-\003\023\056\104\151\147\151\116\157\164\141\162\040\120\113\111
-\157\166\145\162\150\145\151\144\040\103\101\040\117\166\145\162
-\150\145\151\144\040\145\156\040\102\145\144\162\151\152\166\145
-\156
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\027\060\025\006\003\125\004\012\023\016\104\151\147\151\116\157
-\164\141\162\040\102\056\126\056\061\067\060\065\006\003\125\004
-\003\023\056\104\151\147\151\116\157\164\141\162\040\120\113\111
-\157\166\145\162\150\145\151\144\040\103\101\040\117\166\145\162
-\150\145\151\144\040\145\156\040\102\145\144\162\151\152\166\145
-\156
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\216\060\202\003\166\240\003\002\001\002\002\004\017
-\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\060\137\061\013\060\011\006\003\125\004\006\023\002\116
-\114\061\027\060\025\006\003\125\004\012\023\016\104\151\147\151
-\116\157\164\141\162\040\102\056\126\056\061\067\060\065\006\003
-\125\004\003\023\056\104\151\147\151\116\157\164\141\162\040\120
-\113\111\157\166\145\162\150\145\151\144\040\103\101\040\117\166
-\145\162\150\145\151\144\040\145\156\040\102\145\144\162\151\152
-\166\145\156\060\036\027\015\060\067\060\067\060\065\060\070\064
-\062\060\070\132\027\015\061\065\060\067\062\067\060\070\063\071
-\064\067\132\060\137\061\013\060\011\006\003\125\004\006\023\002
-\116\114\061\027\060\025\006\003\125\004\012\023\016\104\151\147
-\151\116\157\164\141\162\040\102\056\126\056\061\067\060\065\006
-\003\125\004\003\023\056\104\151\147\151\116\157\164\141\162\040
-\120\113\111\157\166\145\162\150\145\151\144\040\103\101\040\117
-\166\145\162\150\145\151\144\040\145\156\040\102\145\144\162\151
-\152\166\145\156\060\202\001\042\060\015\006\011\052\206\110\206
-\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001\012
-\002\202\001\001\000\334\275\322\247\116\152\012\273\073\242\205
-\341\177\000\255\276\264\060\150\230\007\315\240\172\304\224\317
-\161\371\212\067\344\123\353\127\166\314\213\346\154\376\356\207
-\125\310\076\273\004\071\000\247\200\170\254\133\117\176\364\275
-\270\124\270\161\073\007\061\111\071\223\124\174\040\073\171\053
-\217\273\141\220\175\261\254\346\037\220\056\235\105\001\251\144
-\055\115\303\057\271\347\120\325\116\052\134\253\166\166\067\106
-\327\171\354\102\231\367\242\354\244\211\160\334\070\053\207\246
-\252\044\346\235\222\044\033\276\366\375\324\057\031\027\172\346
-\062\007\224\124\005\123\103\351\154\274\257\107\313\274\313\375
-\275\073\104\022\201\361\153\113\273\355\264\317\253\045\117\030
-\322\314\002\374\243\117\265\102\063\313\131\315\011\334\323\120
-\375\240\166\214\254\176\146\212\102\366\255\034\222\363\266\373
-\024\106\353\115\327\057\060\340\155\356\133\066\276\104\164\267
-\040\005\127\205\115\350\000\031\242\366\014\346\256\241\300\102
-\337\247\254\202\135\307\150\267\030\346\211\113\232\153\372\316
-\171\371\363\054\247\002\003\001\000\001\243\202\001\120\060\202
-\001\114\060\110\006\003\125\035\040\004\101\060\077\060\075\006
-\004\125\035\040\000\060\065\060\063\006\010\053\006\001\005\005
-\007\002\001\026\047\150\164\164\160\072\057\057\167\167\167\056
-\144\151\147\151\156\157\164\141\162\056\156\154\057\143\160\163
-\057\160\153\151\157\166\145\162\150\145\151\144\060\017\006\003
-\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016\006
-\003\125\035\017\001\001\377\004\004\003\002\001\006\060\201\200
-\006\003\125\035\043\004\171\060\167\200\024\013\206\326\017\167
-\243\150\261\373\144\011\303\210\156\134\004\034\127\351\075\241
-\131\244\127\060\125\061\013\060\011\006\003\125\004\006\023\002
-\116\114\061\036\060\034\006\003\125\004\012\023\025\123\164\141
-\141\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144
-\145\156\061\046\060\044\006\003\125\004\003\023\035\123\164\141
-\141\164\040\144\145\162\040\116\145\144\145\162\154\141\156\144
-\145\156\040\122\157\157\164\040\103\101\202\004\000\230\232\171
-\060\075\006\003\125\035\037\004\066\060\064\060\062\240\060\240
-\056\206\054\150\164\164\160\072\057\057\143\162\154\056\160\153
-\151\157\166\145\162\150\145\151\144\056\156\154\057\104\157\155
-\117\166\114\141\164\145\163\164\103\122\114\056\143\162\154\060
-\035\006\003\125\035\016\004\026\004\024\114\010\311\215\166\361
-\230\307\076\337\074\327\057\165\015\261\166\171\227\314\060\015
-\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001
-\001\000\014\224\207\032\277\115\343\205\342\356\327\330\143\171
-\016\120\337\306\204\133\322\273\331\365\061\012\032\065\227\164
-\337\024\372\052\017\076\355\240\343\010\366\325\116\133\257\246
-\256\045\342\105\153\042\017\267\124\050\176\222\336\215\024\154
-\321\034\345\156\164\004\234\267\357\064\104\105\337\311\203\035
-\031\037\300\051\151\337\211\325\077\302\260\123\155\345\116\027
-\344\163\141\043\023\046\161\103\375\114\131\313\303\337\042\252
-\041\053\331\277\225\021\032\212\244\342\253\247\135\113\157\051
-\365\122\321\344\322\025\261\213\376\360\003\317\247\175\351\231
-\207\070\263\015\163\024\344\162\054\341\316\365\255\006\110\144
-\372\323\051\271\242\330\273\364\325\013\245\100\104\103\216\240
-\277\316\132\245\122\114\144\323\027\061\141\314\350\244\212\350
-\344\210\373\351\345\057\006\063\063\233\224\146\146\261\253\120
-\072\241\011\201\164\123\132\047\271\246\322\045\317\323\303\247
-\377\226\320\057\352\340\036\215\122\351\030\034\040\012\107\240
-\226\126\016\100\220\121\104\254\032\375\361\356\205\037\367\102
-\132\145
-END
-
-# Trust for Certificate "Explicitly Distrusted DigiNotar PKIoverheid"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted DigiNotar PKIoverheid"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\247\250\311\254\364\137\220\222\166\206\270\300\242\016\223\130
-\175\336\060\344
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\243\317\263\377\371\117\247\261\353\072\165\130\116\056\237\352
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\027\060\025\006\003\125\004\012\023\016\104\151\147\151\116\157
-\164\141\162\040\102\056\126\056\061\067\060\065\006\003\125\004
-\003\023\056\104\151\147\151\116\157\164\141\162\040\120\113\111
-\157\166\145\162\150\145\151\144\040\103\101\040\117\166\145\162
-\150\145\151\144\040\145\156\040\102\145\144\162\151\152\166\145
-\156
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Explicitly Distrusted DigiNotar PKIoverheid G2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted DigiNotar PKIoverheid G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\027\060\025\006\003\125\004\012\014\016\104\151\147\151\116\157
-\164\141\162\040\102\056\126\056\061\062\060\060\006\003\125\004
-\003\014\051\104\151\147\151\116\157\164\141\162\040\120\113\111
-\157\166\145\162\150\145\151\144\040\103\101\040\117\162\147\141
-\156\151\163\141\164\151\145\040\055\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\027\060\025\006\003\125\004\012\014\016\104\151\147\151\116\157
-\164\141\162\040\102\056\126\056\061\062\060\060\006\003\125\004
-\003\014\051\104\151\147\151\116\157\164\141\162\040\120\113\111
-\157\166\145\162\150\145\151\144\040\103\101\040\117\162\147\141
-\156\151\163\141\164\151\145\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\006\225\060\202\004\175\240\003\002\001\002\002\004\017
-\377\377\377\060\015\006\011\052\206\110\206\367\015\001\001\013
-\005\000\060\132\061\013\060\011\006\003\125\004\006\023\002\116
-\114\061\027\060\025\006\003\125\004\012\014\016\104\151\147\151
-\116\157\164\141\162\040\102\056\126\056\061\062\060\060\006\003
-\125\004\003\014\051\104\151\147\151\116\157\164\141\162\040\120
-\113\111\157\166\145\162\150\145\151\144\040\103\101\040\117\162
-\147\141\156\151\163\141\164\151\145\040\055\040\107\062\060\036
-\027\015\061\060\060\065\061\062\060\070\065\061\063\071\132\027
-\015\062\060\060\063\062\063\060\071\065\060\060\065\132\060\132
-\061\013\060\011\006\003\125\004\006\023\002\116\114\061\027\060
-\025\006\003\125\004\012\014\016\104\151\147\151\116\157\164\141
-\162\040\102\056\126\056\061\062\060\060\006\003\125\004\003\014
-\051\104\151\147\151\116\157\164\141\162\040\120\113\111\157\166
-\145\162\150\145\151\144\040\103\101\040\117\162\147\141\156\151
-\163\141\164\151\145\040\055\040\107\062\060\202\002\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002
-\017\000\060\202\002\012\002\202\002\001\000\261\023\031\017\047
-\346\154\324\125\206\113\320\354\211\212\105\221\170\254\107\275
-\107\053\344\374\105\353\117\264\046\163\133\067\323\303\177\366
-\343\336\327\243\370\055\150\305\010\076\113\224\326\344\207\045
-\066\153\204\265\030\164\363\050\130\163\057\233\152\317\274\004
-\036\366\336\335\257\374\113\252\365\333\146\142\045\001\045\202
-\336\362\227\132\020\156\335\135\251\042\261\004\251\043\163\072
-\370\161\255\035\317\204\104\353\107\321\257\155\310\174\050\253
-\307\362\067\172\164\137\137\305\002\024\212\243\132\343\033\154
-\001\343\135\216\331\150\326\364\011\033\062\334\221\265\054\365
-\040\353\214\003\155\046\111\270\223\304\205\135\330\322\233\257
-\126\152\314\005\063\314\240\102\236\064\125\104\234\153\240\324
-\022\320\053\124\315\267\211\015\345\366\353\350\373\205\001\063
-\117\172\153\361\235\162\063\226\016\367\262\204\245\245\047\304
-\047\361\121\163\051\167\272\147\156\376\114\334\264\342\241\241
-\201\057\071\111\215\103\070\023\316\320\245\134\302\207\072\000
-\147\145\102\043\361\066\131\012\035\243\121\310\274\243\224\052
-\061\337\343\074\362\235\032\074\004\260\357\261\012\060\023\163
-\266\327\363\243\114\001\165\024\205\170\300\327\212\071\130\205
-\120\372\056\346\305\276\317\213\077\257\217\066\324\045\011\055
-\322\017\254\162\223\362\277\213\324\120\263\371\025\120\233\231
-\365\024\331\373\213\221\243\062\046\046\240\370\337\073\140\201
-\206\203\171\133\053\353\023\075\051\072\301\155\335\275\236\216
-\207\326\112\256\064\227\005\356\024\246\366\334\070\176\112\351
-\044\124\007\075\227\150\067\106\153\015\307\250\041\257\023\124
-\344\011\152\361\115\106\012\311\135\373\233\117\275\336\373\267
-\124\313\270\070\234\247\071\373\152\055\300\173\215\253\245\247
-\127\354\112\222\212\063\305\341\040\134\163\330\220\222\053\200
-\325\017\206\030\151\174\071\117\204\206\274\367\114\133\363\325
-\264\312\240\302\360\067\042\312\171\122\037\123\346\252\363\220
-\260\073\335\362\050\375\254\353\305\006\044\240\311\324\057\017
-\130\375\265\236\354\017\317\262\131\320\242\004\172\070\152\256
-\162\373\275\360\045\142\224\011\247\005\013\002\003\001\000\001
-\243\202\001\141\060\202\001\135\060\110\006\003\125\035\040\004
-\101\060\077\060\075\006\004\125\035\040\000\060\065\060\063\006
-\010\053\006\001\005\005\007\002\001\026\047\150\164\164\160\072
-\057\057\167\167\167\056\144\151\147\151\156\157\164\141\162\056
-\156\154\057\143\160\163\057\160\153\151\157\166\145\162\150\145
-\151\144\060\017\006\003\125\035\023\001\001\377\004\005\060\003
-\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003
-\002\001\006\060\201\205\006\003\125\035\043\004\176\060\174\200
-\024\071\020\213\111\222\134\333\141\022\040\315\111\235\032\216
-\332\234\147\100\271\241\136\244\134\060\132\061\013\060\011\006
-\003\125\004\006\023\002\116\114\061\036\060\034\006\003\125\004
-\012\014\025\123\164\141\141\164\040\144\145\162\040\116\145\144
-\145\162\154\141\156\144\145\156\061\053\060\051\006\003\125\004
-\003\014\042\123\164\141\141\164\040\144\145\162\040\116\145\144
-\145\162\154\141\156\144\145\156\040\122\157\157\164\040\103\101
-\040\055\040\107\062\202\004\000\230\226\364\060\111\006\003\125
-\035\037\004\102\060\100\060\076\240\074\240\072\206\070\150\164
-\164\160\072\057\057\143\162\154\056\160\153\151\157\166\145\162
-\150\145\151\144\056\156\154\057\104\157\155\117\162\147\141\156
-\151\163\141\164\151\145\114\141\164\145\163\164\103\122\114\055
-\107\062\056\143\162\154\060\035\006\003\125\035\016\004\026\004
-\024\274\135\224\073\331\253\173\003\045\163\141\302\333\055\356
-\374\253\217\145\241\060\015\006\011\052\206\110\206\367\015\001
-\001\013\005\000\003\202\002\001\000\217\374\055\114\267\331\055
-\325\037\275\357\313\364\267\150\027\165\235\116\325\367\335\234
-\361\052\046\355\237\242\266\034\003\325\123\263\354\010\317\064
-\342\343\303\364\265\026\057\310\303\276\327\323\163\253\000\066
-\371\032\112\176\326\143\351\136\106\272\245\266\216\025\267\243
-\052\330\103\035\357\135\310\037\201\205\263\213\367\377\074\364
-\331\364\106\010\077\234\274\035\240\331\250\114\315\045\122\116
-\012\261\040\367\037\351\103\331\124\106\201\023\232\300\136\164
-\154\052\230\062\352\374\167\273\015\245\242\061\230\042\176\174
-\174\347\332\244\255\354\267\056\032\031\161\370\110\120\332\103
-\217\054\204\335\301\100\047\343\265\360\025\116\226\324\370\134
-\343\206\051\106\053\327\073\007\353\070\177\310\206\127\227\323
-\357\052\063\304\027\120\325\144\151\153\053\153\105\136\135\057
-\027\312\132\116\317\303\327\071\074\365\073\237\106\271\233\347
-\016\111\227\235\326\325\343\033\017\352\217\001\116\232\023\224
-\131\012\002\007\110\113\032\140\253\177\117\355\013\330\125\015
-\150\157\125\234\151\145\025\102\354\300\334\335\154\254\303\026
-\316\013\035\126\233\244\304\304\322\056\340\017\342\104\047\053
-\120\151\244\334\142\350\212\041\051\102\154\314\000\072\226\166
-\233\357\100\300\244\136\167\204\062\154\046\052\071\146\256\135
-\343\271\271\262\054\150\037\036\232\220\003\071\360\252\263\244
-\314\111\213\030\064\351\067\311\173\051\307\204\174\157\104\025
-\057\354\141\131\004\311\105\313\242\326\122\242\174\177\051\222
-\326\112\305\213\102\250\324\376\352\330\307\207\043\030\344\235
-\172\175\163\100\122\230\240\256\156\343\005\077\005\017\340\245
-\306\155\115\355\203\067\210\234\307\363\334\102\232\152\266\327
-\041\111\066\167\362\357\030\117\305\160\331\236\351\336\267\053
-\213\364\274\176\050\337\015\100\311\205\134\256\235\305\061\377
-\320\134\016\265\250\176\360\351\057\272\257\210\256\345\265\321
-\130\245\257\234\161\247\051\001\220\203\151\067\202\005\272\374
-\011\301\010\156\214\170\073\303\063\002\200\077\104\205\010\035
-\337\125\126\010\255\054\205\055\135\261\003\341\256\252\164\305
-\244\363\116\272\067\230\173\202\271
-END
-
-# Trust for Certificate "Explicitly Distrusted DigiNotar PKIoverheid G2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted DigiNotar PKIoverheid G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\325\362\127\251\277\055\320\077\213\106\127\371\053\311\244\306
-\222\341\102\102
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\056\141\242\321\170\316\356\277\131\063\260\043\024\017\224\034
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\132\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\027\060\025\006\003\125\004\012\014\016\104\151\147\151\116\157
-\164\141\162\040\102\056\126\056\061\062\060\060\006\003\125\004
-\003\014\051\104\151\147\151\116\157\164\141\162\040\120\113\111
-\157\166\145\162\150\145\151\144\040\103\101\040\117\162\147\141
-\156\151\163\141\164\151\145\040\055\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\017\377\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (cyb)"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (cyb)"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\143\061\013\060\011\006\003\125\004\006\023\002\115\131\061
-\033\060\031\006\003\125\004\012\023\022\104\151\147\151\143\145
-\162\164\040\123\144\156\056\040\102\150\144\056\061\021\060\017
-\006\003\125\004\013\023\010\064\065\067\066\060\070\055\113\061
-\044\060\042\006\003\125\004\003\023\033\104\151\147\151\163\151
-\147\156\040\123\145\162\166\145\162\040\111\104\040\050\105\156
-\162\151\143\150\051
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\030\060\026\006\003\125\004\012\023\017\107\124\105\040\103\157
-\162\160\157\162\141\164\151\157\156\061\047\060\045\006\003\125
-\004\013\023\036\107\124\105\040\103\171\142\145\162\124\162\165
-\163\164\040\123\157\154\165\164\151\157\156\163\054\040\111\156
-\143\056\061\043\060\041\006\003\125\004\003\023\032\107\124\105
-\040\103\171\142\145\162\124\162\165\163\164\040\107\154\157\142
-\141\154\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\006\007\377\377\377\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\315\060\202\003\066\240\003\002\001\002\002\006\007
-\377\377\377\377\377\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\060\165\061\013\060\011\006\003\125\004\006\023
-\002\125\123\061\030\060\026\006\003\125\004\012\023\017\107\124
-\105\040\103\157\162\160\157\162\141\164\151\157\156\061\047\060
-\045\006\003\125\004\013\023\036\107\124\105\040\103\171\142\145
-\162\124\162\165\163\164\040\123\157\154\165\164\151\157\156\163
-\054\040\111\156\143\056\061\043\060\041\006\003\125\004\003\023
-\032\107\124\105\040\103\171\142\145\162\124\162\165\163\164\040
-\107\154\157\142\141\154\040\122\157\157\164\060\036\027\015\060
-\067\060\067\061\067\061\065\061\067\064\071\132\027\015\061\062
-\060\067\061\067\061\065\061\066\065\065\132\060\143\061\013\060
-\011\006\003\125\004\006\023\002\115\131\061\033\060\031\006\003
-\125\004\012\023\022\104\151\147\151\143\145\162\164\040\123\144
-\156\056\040\102\150\144\056\061\021\060\017\006\003\125\004\013
-\023\010\064\065\067\066\060\070\055\113\061\044\060\042\006\003
-\125\004\003\023\033\104\151\147\151\163\151\147\156\040\123\145
-\162\166\145\162\040\111\104\040\050\105\156\162\151\143\150\051
-\060\201\237\060\015\006\011\052\206\110\206\367\015\001\001\001
-\005\000\003\201\215\000\060\201\211\002\201\201\000\255\250\144
-\113\115\207\307\204\131\271\373\220\106\240\246\211\300\361\376
-\325\332\124\202\067\015\231\053\105\046\012\350\126\260\177\312
-\250\364\216\107\204\001\202\051\343\263\152\265\221\363\373\225
-\205\274\162\250\144\350\012\100\234\305\364\161\256\173\173\152
-\007\352\220\024\117\215\211\257\224\253\262\006\324\002\152\173
-\230\037\131\271\072\315\124\372\040\337\262\052\012\351\270\335
-\151\220\300\051\323\116\320\227\355\146\314\305\031\111\006\177
-\372\136\054\174\173\205\033\062\102\337\173\225\045\002\003\001
-\000\001\243\202\001\170\060\202\001\164\060\022\006\003\125\035
-\023\001\001\377\004\010\060\006\001\001\377\002\001\000\060\134
-\006\003\125\035\040\004\125\060\123\060\110\006\011\053\006\001
-\004\001\261\076\001\000\060\073\060\071\006\010\053\006\001\005
-\005\007\002\001\026\055\150\164\164\160\072\057\057\143\171\142
-\145\162\164\162\165\163\164\056\157\155\156\151\162\157\157\164
-\056\143\157\155\057\162\145\160\157\163\151\164\157\162\171\056
-\143\146\155\060\007\006\005\140\203\112\001\001\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\001\346\060\201\211\006
-\003\125\035\043\004\201\201\060\177\241\171\244\167\060\165\061
-\013\060\011\006\003\125\004\006\023\002\125\123\061\030\060\026
-\006\003\125\004\012\023\017\107\124\105\040\103\157\162\160\157
-\162\141\164\151\157\156\061\047\060\045\006\003\125\004\013\023
-\036\107\124\105\040\103\171\142\145\162\124\162\165\163\164\040
-\123\157\154\165\164\151\157\156\163\054\040\111\156\143\056\061
-\043\060\041\006\003\125\004\003\023\032\107\124\105\040\103\171
-\142\145\162\124\162\165\163\164\040\107\154\157\142\141\154\040
-\122\157\157\164\202\002\001\245\060\105\006\003\125\035\037\004
-\076\060\074\060\072\240\070\240\066\206\064\150\164\164\160\072
-\057\057\167\167\167\056\160\165\142\154\151\143\055\164\162\165
-\163\164\056\143\157\155\057\143\147\151\055\142\151\156\057\103
-\122\114\057\062\060\061\070\057\143\144\160\056\143\162\154\060
-\035\006\003\125\035\016\004\026\004\024\306\026\223\116\026\027
-\354\026\256\214\224\166\363\206\155\305\164\156\204\167\060\015
-\006\011\052\206\110\206\367\015\001\001\005\005\000\003\201\201
-\000\166\000\173\246\170\053\146\035\216\136\066\306\244\216\005
-\362\043\222\174\223\147\323\364\300\012\175\213\055\331\352\325
-\157\032\363\341\112\051\132\042\204\115\120\057\113\014\362\377
-\205\302\173\125\324\104\202\276\155\254\147\216\274\264\037\222
-\234\121\200\032\024\366\156\253\141\210\013\255\034\177\367\113
-\120\121\326\145\033\246\107\161\025\136\260\161\363\065\024\362
-\067\275\143\310\325\360\223\132\064\137\330\075\350\135\367\305
-\036\300\345\317\037\206\044\251\074\007\146\315\301\322\066\143
-\131
-END
-
-# Trust for Certificate "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (cyb)"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (cyb)"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\125\120\257\354\277\350\303\255\304\013\343\255\014\247\344\025
-\214\071\131\117
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\322\336\256\120\244\230\055\157\067\267\206\122\310\055\113\152
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\125\123\061
-\030\060\026\006\003\125\004\012\023\017\107\124\105\040\103\157
-\162\160\157\162\141\164\151\157\156\061\047\060\045\006\003\125
-\004\013\023\036\107\124\105\040\103\171\142\145\162\124\162\165
-\163\164\040\123\157\154\165\164\151\157\156\163\054\040\111\156
-\143\056\061\043\060\041\006\003\125\004\003\023\032\107\124\105
-\040\103\171\142\145\162\124\162\165\163\164\040\107\154\157\142
-\141\154\040\122\157\157\164
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\006\007\377\377\377\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (en)"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (en)"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\145\061\013\060\011\006\003\125\004\006\023\002\115\131\061
-\033\060\031\006\003\125\004\012\023\022\104\151\147\151\143\145
-\162\164\040\123\144\156\056\040\102\150\144\056\061\021\060\017
-\006\003\125\004\013\023\010\064\065\067\066\060\070\055\113\061
-\046\060\044\006\003\125\004\003\023\035\104\151\147\151\163\151
-\147\156\040\123\145\162\166\145\162\040\111\104\040\055\040\050
-\105\156\162\151\143\150\051
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\264\061\024\060\022\006\003\125\004\012\023\013\105\156
-\164\162\165\163\164\056\156\145\164\061\100\060\076\006\003\125
-\004\013\024\067\167\167\167\056\145\156\164\162\165\163\164\056
-\156\145\164\057\103\120\123\137\062\060\064\070\040\151\156\143
-\157\162\160\056\040\142\171\040\162\145\146\056\040\050\154\151
-\155\151\164\163\040\154\151\141\142\056\051\061\045\060\043\006
-\003\125\004\013\023\034\050\143\051\040\061\071\071\071\040\105
-\156\164\162\165\163\164\056\156\145\164\040\114\151\155\151\164
-\145\144\061\063\060\061\006\003\125\004\003\023\052\105\156\164
-\162\165\163\164\056\156\145\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-\040\050\062\060\064\070\051
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\006\007\377\377\377\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\320\060\202\003\270\240\003\002\001\002\002\006\007
-\377\377\377\377\377\060\015\006\011\052\206\110\206\367\015\001
-\001\005\005\000\060\201\264\061\024\060\022\006\003\125\004\012
-\023\013\105\156\164\162\165\163\164\056\156\145\164\061\100\060
-\076\006\003\125\004\013\024\067\167\167\167\056\145\156\164\162
-\165\163\164\056\156\145\164\057\103\120\123\137\062\060\064\070
-\040\151\156\143\157\162\160\056\040\142\171\040\162\145\146\056
-\040\050\154\151\155\151\164\163\040\154\151\141\142\056\051\061
-\045\060\043\006\003\125\004\013\023\034\050\143\051\040\061\071
-\071\071\040\105\156\164\162\165\163\164\056\156\145\164\040\114
-\151\155\151\164\145\144\061\063\060\061\006\003\125\004\003\023
-\052\105\156\164\162\165\163\164\056\156\145\164\040\103\145\162
-\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157
-\162\151\164\171\040\050\062\060\064\070\051\060\036\027\015\061
-\060\060\067\061\066\061\067\062\063\063\070\132\027\015\061\065
-\060\067\061\066\061\067\065\063\063\070\132\060\145\061\013\060
-\011\006\003\125\004\006\023\002\115\131\061\033\060\031\006\003
-\125\004\012\023\022\104\151\147\151\143\145\162\164\040\123\144
-\156\056\040\102\150\144\056\061\021\060\017\006\003\125\004\013
-\023\010\064\065\067\066\060\070\055\113\061\046\060\044\006\003
-\125\004\003\023\035\104\151\147\151\163\151\147\156\040\123\145
-\162\166\145\162\040\111\104\040\055\040\050\105\156\162\151\143
-\150\051\060\202\001\042\060\015\006\011\052\206\110\206\367\015
-\001\001\001\005\000\003\202\001\017\000\060\202\001\012\002\202
-\001\001\000\305\211\344\364\015\006\100\222\131\307\032\263\065
-\321\016\114\052\063\371\370\257\312\236\177\356\271\247\155\140
-\364\124\350\157\325\233\363\033\143\061\004\150\162\321\064\026
-\214\264\027\054\227\336\163\305\330\220\025\240\032\053\365\313
-\263\110\206\104\360\035\210\114\316\101\102\032\357\365\014\336
-\376\100\332\071\040\367\006\125\072\152\235\106\301\322\157\245
-\262\310\127\076\051\243\234\340\351\205\167\146\350\230\247\044
-\176\276\300\131\040\345\104\157\266\127\330\276\316\302\145\167
-\130\306\141\101\321\164\004\310\177\111\102\305\162\251\162\026
-\356\214\335\022\135\264\112\324\321\257\120\267\330\252\165\166
-\150\255\076\135\252\060\155\141\250\253\020\133\076\023\277\063
-\340\257\104\235\070\042\133\357\114\057\246\161\046\025\046\312
-\050\214\331\372\216\216\251\242\024\065\342\233\044\210\264\364
-\177\205\235\203\117\007\241\266\024\220\066\304\064\034\215\046
-\141\155\023\157\170\276\350\217\047\307\113\204\226\243\206\150
-\014\043\276\013\354\214\224\000\251\004\212\023\220\367\337\205
-\154\014\261\002\003\001\000\001\243\202\001\064\060\202\001\060
-\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006
-\060\022\006\003\125\035\023\001\001\377\004\010\060\006\001\001
-\377\002\001\000\060\047\006\003\125\035\045\004\040\060\036\006
-\010\053\006\001\005\005\007\003\001\006\010\053\006\001\005\005
-\007\003\002\006\010\053\006\001\005\005\007\003\004\060\063\006
-\010\053\006\001\005\005\007\001\001\004\047\060\045\060\043\006
-\010\053\006\001\005\005\007\060\001\206\027\150\164\164\160\072
-\057\057\157\143\163\160\056\145\156\164\162\165\163\164\056\156
-\145\164\060\104\006\003\125\035\040\004\075\060\073\060\071\006
-\005\140\203\112\001\001\060\060\060\056\006\010\053\006\001\005
-\005\007\002\001\026\042\150\164\164\160\072\057\057\167\167\167
-\056\144\151\147\151\143\145\162\164\056\143\157\155\056\155\171
-\057\143\160\163\056\150\164\155\060\062\006\003\125\035\037\004
-\053\060\051\060\047\240\045\240\043\206\041\150\164\164\160\072
-\057\057\143\162\154\056\145\156\164\162\165\163\164\056\156\145
-\164\057\062\060\064\070\143\141\056\143\162\154\060\021\006\003
-\125\035\016\004\012\004\010\114\116\314\045\050\003\051\201\060
-\037\006\003\125\035\043\004\030\060\026\200\024\125\344\201\321
-\021\200\276\330\211\271\010\243\061\371\241\044\011\026\271\160
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003
-\202\001\001\000\227\114\357\112\072\111\254\162\374\060\040\153
-\264\051\133\247\305\225\004\220\371\062\325\302\205\152\336\003
-\241\067\371\211\000\260\132\254\125\176\333\103\065\377\311\001
-\370\121\276\314\046\312\310\152\244\304\124\076\046\036\347\014
-\243\315\227\147\224\335\246\102\353\134\315\217\071\171\153\063
-\171\041\006\171\372\202\104\025\231\314\301\267\071\323\106\142
-\174\262\160\353\157\316\040\252\076\031\267\351\164\202\234\264
-\245\113\115\141\000\067\344\207\322\362\024\072\144\174\270\251
-\173\141\340\223\042\347\325\237\076\107\346\066\166\240\123\330
-\000\003\072\017\265\063\376\226\312\323\322\202\072\056\335\327
-\110\341\344\247\151\314\034\351\231\112\347\312\160\105\327\013
-\007\016\232\165\033\320\057\222\157\366\244\007\303\275\034\113
-\246\204\266\175\250\232\251\322\247\051\361\013\127\151\036\227
-\127\046\354\053\103\254\324\105\203\005\000\351\343\360\106\100
-\007\372\352\261\121\163\223\034\245\335\123\021\067\310\052\247
-\025\047\035\264\252\314\177\252\061\060\374\270\105\237\110\011
-\355\020\342\305
-END
-
-# Trust for Certificate "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (en)"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrusted Malaysian Digicert Sdn. Bhd. (en)"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\153\074\073\200\255\312\246\272\212\237\124\246\172\355\022\151
-\005\155\061\046
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\327\151\141\177\065\017\234\106\243\252\353\370\125\374\204\362
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\264\061\024\060\022\006\003\125\004\012\023\013\105\156
-\164\162\165\163\164\056\156\145\164\061\100\060\076\006\003\125
-\004\013\024\067\167\167\167\056\145\156\164\162\165\163\164\056
-\156\145\164\057\103\120\123\137\062\060\064\070\040\151\156\143
-\157\162\160\056\040\142\171\040\162\145\146\056\040\050\154\151
-\155\151\164\163\040\154\151\141\142\056\051\061\045\060\043\006
-\003\125\004\013\023\034\050\143\051\040\061\071\071\071\040\105
-\156\164\162\165\163\164\056\156\145\164\040\114\151\155\151\164
-\145\144\061\063\060\061\006\003\125\004\003\023\052\105\156\164
-\162\165\163\164\056\156\145\164\040\103\145\162\164\151\146\151
-\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-\040\050\062\060\064\070\051
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\006\007\377\377\377\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-
-#
-# Certificate "Security Communication RootCA2"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Security Communication RootCA2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\135\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040
-\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117
-\056\054\114\124\104\056\061\047\060\045\006\003\125\004\013\023
-\036\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156
-\151\143\141\164\151\157\156\040\122\157\157\164\103\101\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\135\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040
-\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117
-\056\054\114\124\104\056\061\047\060\045\006\003\125\004\013\023
-\036\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156
-\151\143\141\164\151\157\156\040\122\157\157\164\103\101\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\167\060\202\002\137\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
-\135\061\013\060\011\006\003\125\004\006\023\002\112\120\061\045
-\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040\124
-\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117\056
-\054\114\124\104\056\061\047\060\045\006\003\125\004\013\023\036
-\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156\151
-\143\141\164\151\157\156\040\122\157\157\164\103\101\062\060\036
-\027\015\060\071\060\065\062\071\060\065\060\060\063\071\132\027
-\015\062\071\060\065\062\071\060\065\060\060\063\071\132\060\135
-\061\013\060\011\006\003\125\004\006\023\002\112\120\061\045\060
-\043\006\003\125\004\012\023\034\123\105\103\117\115\040\124\162
-\165\163\164\040\123\171\163\164\145\155\163\040\103\117\056\054
-\114\124\104\056\061\047\060\045\006\003\125\004\013\023\036\123
-\145\143\165\162\151\164\171\040\103\157\155\155\165\156\151\143
-\141\164\151\157\156\040\122\157\157\164\103\101\062\060\202\001
-\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\202\001\017\000\060\202\001\012\002\202\001\001\000\320\025
-\071\122\261\122\263\272\305\131\202\304\135\122\256\072\103\145
-\200\113\307\362\226\274\333\066\227\326\246\144\214\250\136\360
-\343\012\034\367\337\227\075\113\256\366\135\354\041\265\101\253
-\315\271\176\166\237\276\371\076\066\064\240\073\301\366\061\021
-\105\164\223\075\127\200\305\371\211\231\312\345\253\152\324\265
-\332\101\220\020\301\326\326\102\211\302\277\364\070\022\225\114
-\124\005\367\066\344\105\203\173\024\145\326\334\014\115\321\336
-\176\014\253\073\304\025\276\072\126\246\132\157\166\151\122\251
-\172\271\310\353\152\232\135\122\320\055\012\153\065\026\011\020
-\204\320\152\312\072\006\000\067\107\344\176\127\117\077\213\353
-\147\270\210\252\305\276\123\125\262\221\304\175\271\260\205\031
-\006\170\056\333\141\032\372\205\365\112\221\241\347\026\325\216
-\242\071\337\224\270\160\037\050\077\213\374\100\136\143\203\074
-\203\052\032\231\153\317\336\131\152\073\374\157\026\327\037\375
-\112\020\353\116\202\026\072\254\047\014\123\361\255\325\044\260
-\153\003\120\301\055\074\026\335\104\064\047\032\165\373\002\003
-\001\000\001\243\102\060\100\060\035\006\003\125\035\016\004\026
-\004\024\012\205\251\167\145\005\230\174\100\201\370\017\227\054
-\070\361\012\354\074\317\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\015\006\011\052\206\110\206\367
-\015\001\001\013\005\000\003\202\001\001\000\114\072\243\104\254
-\271\105\261\307\223\176\310\013\012\102\337\144\352\034\356\131
-\154\010\272\211\137\152\312\112\225\236\172\217\007\305\332\105
-\162\202\161\016\072\322\314\157\247\264\241\043\273\366\044\237
-\313\027\376\214\246\316\302\322\333\314\215\374\161\374\003\051
-\301\154\135\063\137\144\266\145\073\211\157\030\166\170\365\334
-\242\110\037\031\077\216\223\353\361\372\027\356\315\116\343\004
-\022\125\326\345\344\335\373\076\005\174\342\035\136\306\247\274
-\227\117\150\072\365\351\056\012\103\266\257\127\134\142\150\174
-\267\375\243\212\204\240\254\142\276\053\011\207\064\360\152\001
-\273\233\051\126\074\376\000\067\317\043\154\361\116\252\266\164
-\106\022\154\221\356\064\325\354\232\221\347\104\276\220\061\162
-\325\111\002\366\002\345\364\037\353\174\331\226\125\251\377\354
-\212\371\231\107\377\065\132\002\252\004\313\212\133\207\161\051
-\221\275\244\264\172\015\275\232\365\127\043\000\007\041\027\077
-\112\071\321\005\111\013\247\266\067\201\245\135\214\252\063\136
-\201\050\174\247\175\047\353\000\256\215\067
-END
-
-# Trust for Certificate "Security Communication RootCA2"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Security Communication RootCA2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\137\073\214\362\370\020\263\175\170\264\316\354\031\031\303\163
-\064\271\307\164
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\154\071\175\244\016\125\131\262\077\326\101\261\022\120\336\103
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\135\061\013\060\011\006\003\125\004\006\023\002\112\120\061
-\045\060\043\006\003\125\004\012\023\034\123\105\103\117\115\040
-\124\162\165\163\164\040\123\171\163\164\145\155\163\040\103\117
-\056\054\114\124\104\056\061\047\060\045\006\003\125\004\013\023
-\036\123\145\143\165\162\151\164\171\040\103\157\155\155\165\156
-\151\143\141\164\151\157\156\040\122\157\157\164\103\101\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "EC-ACC"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "EC-ACC"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\363\061\013\060\011\006\003\125\004\006\023\002\105\123
-\061\073\060\071\006\003\125\004\012\023\062\101\147\145\156\143
-\151\141\040\103\141\164\141\154\141\156\141\040\144\145\040\103
-\145\162\164\151\146\151\143\141\143\151\157\040\050\116\111\106
-\040\121\055\060\070\060\061\061\067\066\055\111\051\061\050\060
-\046\006\003\125\004\013\023\037\123\145\162\166\145\151\163\040
-\120\165\142\154\151\143\163\040\144\145\040\103\145\162\164\151
-\146\151\143\141\143\151\157\061\065\060\063\006\003\125\004\013
-\023\054\126\145\147\145\165\040\150\164\164\160\163\072\057\057
-\167\167\167\056\143\141\164\143\145\162\164\056\156\145\164\057
-\166\145\162\141\162\162\145\154\040\050\143\051\060\063\061\065
-\060\063\006\003\125\004\013\023\054\112\145\162\141\162\161\165
-\151\141\040\105\156\164\151\164\141\164\163\040\144\145\040\103
-\145\162\164\151\146\151\143\141\143\151\157\040\103\141\164\141
-\154\141\156\145\163\061\017\060\015\006\003\125\004\003\023\006
-\105\103\055\101\103\103
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\363\061\013\060\011\006\003\125\004\006\023\002\105\123
-\061\073\060\071\006\003\125\004\012\023\062\101\147\145\156\143
-\151\141\040\103\141\164\141\154\141\156\141\040\144\145\040\103
-\145\162\164\151\146\151\143\141\143\151\157\040\050\116\111\106
-\040\121\055\060\070\060\061\061\067\066\055\111\051\061\050\060
-\046\006\003\125\004\013\023\037\123\145\162\166\145\151\163\040
-\120\165\142\154\151\143\163\040\144\145\040\103\145\162\164\151
-\146\151\143\141\143\151\157\061\065\060\063\006\003\125\004\013
-\023\054\126\145\147\145\165\040\150\164\164\160\163\072\057\057
-\167\167\167\056\143\141\164\143\145\162\164\056\156\145\164\057
-\166\145\162\141\162\162\145\154\040\050\143\051\060\063\061\065
-\060\063\006\003\125\004\013\023\054\112\145\162\141\162\161\165
-\151\141\040\105\156\164\151\164\141\164\163\040\144\145\040\103
-\145\162\164\151\146\151\143\141\143\151\157\040\103\141\164\141
-\154\141\156\145\163\061\017\060\015\006\003\125\004\003\023\006
-\105\103\055\101\103\103
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\356\053\075\353\324\041\336\024\250\142\254\004\363\335
-\304\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\126\060\202\004\076\240\003\002\001\002\002\020\356
-\053\075\353\324\041\336\024\250\142\254\004\363\335\304\001\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201
-\363\061\013\060\011\006\003\125\004\006\023\002\105\123\061\073
-\060\071\006\003\125\004\012\023\062\101\147\145\156\143\151\141
-\040\103\141\164\141\154\141\156\141\040\144\145\040\103\145\162
-\164\151\146\151\143\141\143\151\157\040\050\116\111\106\040\121
-\055\060\070\060\061\061\067\066\055\111\051\061\050\060\046\006
-\003\125\004\013\023\037\123\145\162\166\145\151\163\040\120\165
-\142\154\151\143\163\040\144\145\040\103\145\162\164\151\146\151
-\143\141\143\151\157\061\065\060\063\006\003\125\004\013\023\054
-\126\145\147\145\165\040\150\164\164\160\163\072\057\057\167\167
-\167\056\143\141\164\143\145\162\164\056\156\145\164\057\166\145
-\162\141\162\162\145\154\040\050\143\051\060\063\061\065\060\063
-\006\003\125\004\013\023\054\112\145\162\141\162\161\165\151\141
-\040\105\156\164\151\164\141\164\163\040\144\145\040\103\145\162
-\164\151\146\151\143\141\143\151\157\040\103\141\164\141\154\141
-\156\145\163\061\017\060\015\006\003\125\004\003\023\006\105\103
-\055\101\103\103\060\036\027\015\060\063\060\061\060\067\062\063
-\060\060\060\060\132\027\015\063\061\060\061\060\067\062\062\065
-\071\065\071\132\060\201\363\061\013\060\011\006\003\125\004\006
-\023\002\105\123\061\073\060\071\006\003\125\004\012\023\062\101
-\147\145\156\143\151\141\040\103\141\164\141\154\141\156\141\040
-\144\145\040\103\145\162\164\151\146\151\143\141\143\151\157\040
-\050\116\111\106\040\121\055\060\070\060\061\061\067\066\055\111
-\051\061\050\060\046\006\003\125\004\013\023\037\123\145\162\166
-\145\151\163\040\120\165\142\154\151\143\163\040\144\145\040\103
-\145\162\164\151\146\151\143\141\143\151\157\061\065\060\063\006
-\003\125\004\013\023\054\126\145\147\145\165\040\150\164\164\160
-\163\072\057\057\167\167\167\056\143\141\164\143\145\162\164\056
-\156\145\164\057\166\145\162\141\162\162\145\154\040\050\143\051
-\060\063\061\065\060\063\006\003\125\004\013\023\054\112\145\162
-\141\162\161\165\151\141\040\105\156\164\151\164\141\164\163\040
-\144\145\040\103\145\162\164\151\146\151\143\141\143\151\157\040
-\103\141\164\141\154\141\156\145\163\061\017\060\015\006\003\125
-\004\003\023\006\105\103\055\101\103\103\060\202\001\042\060\015
-\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001
-\017\000\060\202\001\012\002\202\001\001\000\263\042\307\117\342
-\227\102\225\210\107\203\100\366\035\027\363\203\163\044\036\121
-\363\230\212\303\222\270\377\100\220\005\160\207\140\311\000\251
-\265\224\145\031\042\025\027\302\103\154\146\104\232\015\004\076
-\071\157\245\113\172\252\143\267\212\104\235\331\143\221\204\146
-\340\050\017\272\102\343\156\216\367\024\047\223\151\356\221\016
-\243\137\016\261\353\146\242\162\117\022\023\206\145\172\076\333
-\117\007\364\247\011\140\332\072\102\231\307\262\177\263\026\225
-\034\307\371\064\265\224\205\325\231\136\240\110\240\176\347\027
-\145\270\242\165\270\036\363\345\102\175\257\355\363\212\110\144
-\135\202\024\223\330\300\344\377\263\120\162\362\166\366\263\135
-\102\120\171\320\224\076\153\014\000\276\330\153\016\116\052\354
-\076\322\314\202\242\030\145\063\023\167\236\232\135\032\023\330
-\303\333\075\310\227\172\356\160\355\247\346\174\333\161\317\055
-\224\142\337\155\326\365\070\276\077\245\205\012\031\270\250\330
-\011\165\102\160\304\352\357\313\016\310\064\250\022\042\230\014
-\270\023\224\266\113\354\360\320\220\347\047\002\003\001\000\001
-\243\201\343\060\201\340\060\035\006\003\125\035\021\004\026\060
-\024\201\022\145\143\137\141\143\143\100\143\141\164\143\145\162
-\164\056\156\145\164\060\017\006\003\125\035\023\001\001\377\004
-\005\060\003\001\001\377\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\035\006\003\125\035\016\004\026\004
-\024\240\303\213\104\252\067\245\105\277\227\200\132\321\361\170
-\242\233\351\135\215\060\177\006\003\125\035\040\004\170\060\166
-\060\164\006\013\053\006\001\004\001\365\170\001\003\001\012\060
-\145\060\054\006\010\053\006\001\005\005\007\002\001\026\040\150
-\164\164\160\163\072\057\057\167\167\167\056\143\141\164\143\145
-\162\164\056\156\145\164\057\166\145\162\141\162\162\145\154\060
-\065\006\010\053\006\001\005\005\007\002\002\060\051\032\047\126
-\145\147\145\165\040\150\164\164\160\163\072\057\057\167\167\167
-\056\143\141\164\143\145\162\164\056\156\145\164\057\166\145\162
-\141\162\162\145\154\040\060\015\006\011\052\206\110\206\367\015
-\001\001\005\005\000\003\202\001\001\000\240\110\133\202\001\366
-\115\110\270\071\125\065\234\200\172\123\231\325\132\377\261\161
-\073\314\071\011\224\136\326\332\357\276\001\133\135\323\036\330
-\375\175\117\315\240\101\340\064\223\277\313\342\206\234\067\222
-\220\126\034\334\353\051\005\345\304\236\307\065\337\212\014\315
-\305\041\103\351\252\210\345\065\300\031\102\143\132\002\136\244
-\110\030\072\205\157\334\235\274\077\235\234\301\207\270\172\141
-\010\351\167\013\177\160\253\172\335\331\227\054\144\036\205\277
-\274\164\226\241\303\172\022\354\014\032\156\203\014\074\350\162
-\106\237\373\110\325\136\227\346\261\241\370\344\357\106\045\224
-\234\211\333\151\070\276\354\134\016\126\307\145\121\345\120\210
-\210\277\102\325\053\075\345\371\272\236\056\263\312\364\163\222
-\002\013\276\114\146\353\040\376\271\313\265\231\177\346\266\023
-\372\312\113\115\331\356\123\106\006\073\306\116\255\223\132\201
-\176\154\052\113\152\005\105\214\362\041\244\061\220\207\154\145
-\234\235\245\140\225\072\122\177\365\321\253\010\156\363\356\133
-\371\210\075\176\270\157\156\003\344\102
-END
-
-# Trust for Certificate "EC-ACC"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "EC-ACC"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\050\220\072\143\133\122\200\372\346\167\114\013\155\247\326\272
-\246\112\362\350
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\353\365\235\051\015\141\371\102\037\174\302\272\155\343\025\011
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\363\061\013\060\011\006\003\125\004\006\023\002\105\123
-\061\073\060\071\006\003\125\004\012\023\062\101\147\145\156\143
-\151\141\040\103\141\164\141\154\141\156\141\040\144\145\040\103
-\145\162\164\151\146\151\143\141\143\151\157\040\050\116\111\106
-\040\121\055\060\070\060\061\061\067\066\055\111\051\061\050\060
-\046\006\003\125\004\013\023\037\123\145\162\166\145\151\163\040
-\120\165\142\154\151\143\163\040\144\145\040\103\145\162\164\151
-\146\151\143\141\143\151\157\061\065\060\063\006\003\125\004\013
-\023\054\126\145\147\145\165\040\150\164\164\160\163\072\057\057
-\167\167\167\056\143\141\164\143\145\162\164\056\156\145\164\057
-\166\145\162\141\162\162\145\154\040\050\143\051\060\063\061\065
-\060\063\006\003\125\004\013\023\054\112\145\162\141\162\161\165
-\151\141\040\105\156\164\151\164\141\164\163\040\144\145\040\103
-\145\162\164\151\146\151\143\141\143\151\157\040\103\141\164\141
-\154\141\156\145\163\061\017\060\015\006\003\125\004\003\023\006
-\105\103\055\101\103\103
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\356\053\075\353\324\041\336\024\250\142\254\004\363\335
-\304\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Hellenic Academic and Research Institutions RootCA 2011"
-#
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Hellenic Academic and Research Institutions RootCA 2011"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\225\061\013\060\011\006\003\125\004\006\023\002\107\122
-\061\104\060\102\006\003\125\004\012\023\073\110\145\154\154\145
-\156\151\143\040\101\143\141\144\145\155\151\143\040\141\156\144
-\040\122\145\163\145\141\162\143\150\040\111\156\163\164\151\164
-\165\164\151\157\156\163\040\103\145\162\164\056\040\101\165\164
-\150\157\162\151\164\171\061\100\060\076\006\003\125\004\003\023
-\067\110\145\154\154\145\156\151\143\040\101\143\141\144\145\155
-\151\143\040\141\156\144\040\122\145\163\145\141\162\143\150\040
-\111\156\163\164\151\164\165\164\151\157\156\163\040\122\157\157
-\164\103\101\040\062\060\061\061
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\225\061\013\060\011\006\003\125\004\006\023\002\107\122
-\061\104\060\102\006\003\125\004\012\023\073\110\145\154\154\145
-\156\151\143\040\101\143\141\144\145\155\151\143\040\141\156\144
-\040\122\145\163\145\141\162\143\150\040\111\156\163\164\151\164
-\165\164\151\157\156\163\040\103\145\162\164\056\040\101\165\164
-\150\157\162\151\164\171\061\100\060\076\006\003\125\004\003\023
-\067\110\145\154\154\145\156\151\143\040\101\143\141\144\145\155
-\151\143\040\141\156\144\040\122\145\163\145\141\162\143\150\040
-\111\156\163\164\151\164\165\164\151\157\156\163\040\122\157\157
-\164\103\101\040\062\060\061\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\061\060\202\003\031\240\003\002\001\002\002\001\000
-\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060
-\201\225\061\013\060\011\006\003\125\004\006\023\002\107\122\061
-\104\060\102\006\003\125\004\012\023\073\110\145\154\154\145\156
-\151\143\040\101\143\141\144\145\155\151\143\040\141\156\144\040
-\122\145\163\145\141\162\143\150\040\111\156\163\164\151\164\165
-\164\151\157\156\163\040\103\145\162\164\056\040\101\165\164\150
-\157\162\151\164\171\061\100\060\076\006\003\125\004\003\023\067
-\110\145\154\154\145\156\151\143\040\101\143\141\144\145\155\151
-\143\040\141\156\144\040\122\145\163\145\141\162\143\150\040\111
-\156\163\164\151\164\165\164\151\157\156\163\040\122\157\157\164
-\103\101\040\062\060\061\061\060\036\027\015\061\061\061\062\060
-\066\061\063\064\071\065\062\132\027\015\063\061\061\062\060\061
-\061\063\064\071\065\062\132\060\201\225\061\013\060\011\006\003
-\125\004\006\023\002\107\122\061\104\060\102\006\003\125\004\012
-\023\073\110\145\154\154\145\156\151\143\040\101\143\141\144\145
-\155\151\143\040\141\156\144\040\122\145\163\145\141\162\143\150
-\040\111\156\163\164\151\164\165\164\151\157\156\163\040\103\145
-\162\164\056\040\101\165\164\150\157\162\151\164\171\061\100\060
-\076\006\003\125\004\003\023\067\110\145\154\154\145\156\151\143
-\040\101\143\141\144\145\155\151\143\040\141\156\144\040\122\145
-\163\145\141\162\143\150\040\111\156\163\164\151\164\165\164\151
-\157\156\163\040\122\157\157\164\103\101\040\062\060\061\061\060
-\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001
-\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000
-\251\123\000\343\056\246\366\216\372\140\330\055\225\076\370\054
-\052\124\116\315\271\204\141\224\130\117\217\075\213\344\103\363
-\165\211\215\121\344\303\067\322\212\210\115\171\036\267\022\335
-\103\170\112\212\222\346\327\110\325\017\244\072\051\104\065\270
-\007\366\150\035\125\315\070\121\360\214\044\061\205\257\203\311
-\175\351\167\257\355\032\173\235\027\371\263\235\070\120\017\246
-\132\171\221\200\257\067\256\246\323\061\373\265\046\011\235\074
-\132\357\121\305\053\337\226\135\353\062\036\002\332\160\111\354
-\156\014\310\232\067\215\367\361\066\140\113\046\054\202\236\320
-\170\363\015\017\143\244\121\060\341\371\053\047\022\007\330\352
-\275\030\142\230\260\131\067\175\276\356\363\040\121\102\132\203
-\357\223\272\151\025\361\142\235\237\231\071\202\241\267\164\056
-\213\324\305\013\173\057\360\310\012\332\075\171\012\232\223\034
-\245\050\162\163\221\103\232\247\321\115\205\204\271\251\164\217
-\024\100\307\334\336\254\101\144\154\264\031\233\002\143\155\044
-\144\217\104\262\045\352\316\135\164\014\143\062\134\215\207\345
-\002\003\001\000\001\243\201\211\060\201\206\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\013\006\003
-\125\035\017\004\004\003\002\001\006\060\035\006\003\125\035\016
-\004\026\004\024\246\221\102\375\023\141\112\043\236\010\244\051
-\345\330\023\004\043\356\101\045\060\107\006\003\125\035\036\004
-\100\060\076\240\074\060\005\202\003\056\147\162\060\005\202\003
-\056\145\165\060\006\202\004\056\145\144\165\060\006\202\004\056
-\157\162\147\060\005\201\003\056\147\162\060\005\201\003\056\145
-\165\060\006\201\004\056\145\144\165\060\006\201\004\056\157\162
-\147\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000
-\003\202\001\001\000\037\357\171\101\341\173\156\077\262\214\206
-\067\102\112\116\034\067\036\215\146\272\044\201\311\117\022\017
-\041\300\003\227\206\045\155\135\323\042\051\250\154\242\015\251
-\353\075\006\133\231\072\307\314\303\232\064\177\253\016\310\116
-\034\341\372\344\334\315\015\276\277\044\376\154\347\153\302\015
-\310\006\236\116\215\141\050\246\152\375\345\366\142\352\030\074
-\116\240\123\235\262\072\234\353\245\234\221\026\266\115\202\340
-\014\005\110\251\154\365\314\370\313\235\111\264\360\002\245\375
-\160\003\355\212\041\245\256\023\206\111\303\063\163\276\207\073
-\164\213\027\105\046\114\026\221\203\376\147\175\315\115\143\147
-\372\363\003\022\226\170\006\215\261\147\355\216\077\276\237\117
-\002\365\263\011\057\363\114\207\337\052\313\225\174\001\314\254
-\066\172\277\242\163\172\367\217\301\265\232\241\024\262\217\063
-\237\015\357\042\334\146\173\204\275\105\027\006\075\074\312\271
-\167\064\217\312\352\317\077\061\076\343\210\343\200\111\045\310
-\227\265\235\232\231\115\260\074\370\112\000\233\144\335\237\071
-\113\321\047\327\270
-END
-
-# Trust for Certificate "Hellenic Academic and Research Institutions RootCA 2011"
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Hellenic Academic and Research Institutions RootCA 2011"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\376\105\145\233\171\003\133\230\241\141\265\121\056\254\332\130
-\011\110\042\115
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\163\237\114\113\163\133\171\351\372\272\034\357\156\313\325\311
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\225\061\013\060\011\006\003\125\004\006\023\002\107\122
-\061\104\060\102\006\003\125\004\012\023\073\110\145\154\154\145
-\156\151\143\040\101\143\141\144\145\155\151\143\040\141\156\144
-\040\122\145\163\145\141\162\143\150\040\111\156\163\164\151\164
-\165\164\151\157\156\163\040\103\145\162\164\056\040\101\165\164
-\150\157\162\151\164\171\061\100\060\076\006\003\125\004\003\023
-\067\110\145\154\154\145\156\151\143\040\101\143\141\144\145\155
-\151\143\040\141\156\144\040\122\145\163\145\141\162\143\150\040
-\111\156\163\164\151\164\165\164\151\157\156\163\040\122\157\157
-\164\103\101\040\062\060\061\061
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\000
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-# Explicitly Distrust "MITM subCA 1 issued by Trustwave", Bug 724929
-# Issuer: E=ca@trustwave.com,CN="Trustwave Organization Issuing CA, Level 2",O="Trustwave Holdings, Inc.",L=Chicago,ST=Illinois,C=US
-# Serial Number: 1800000005 (0x6b49d205)
-# Not Before: Apr 7 15:37:15 2011 GMT
-# Not After : Apr 4 15:37:15 2021 GMT
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "MITM subCA 1 issued by Trustwave"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\253\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\021\060\017\006\003\125\004\010\023\010\111\154\154\151\156
-\157\151\163\061\020\060\016\006\003\125\004\007\023\007\103\150
-\151\143\141\147\157\061\041\060\037\006\003\125\004\012\023\030
-\124\162\165\163\164\167\141\166\145\040\110\157\154\144\151\156
-\147\163\054\040\111\156\143\056\061\063\060\061\006\003\125\004
-\003\023\052\124\162\165\163\164\167\141\166\145\040\117\162\147
-\141\156\151\172\141\164\151\157\156\040\111\163\163\165\151\156
-\147\040\103\101\054\040\114\145\166\145\154\040\062\061\037\060
-\035\006\011\052\206\110\206\367\015\001\011\001\026\020\143\141
-\100\164\162\165\163\164\167\141\166\145\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\153\111\322\005
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-# Explicitly Distrust "MITM subCA 2 issued by Trustwave", Bug 724929
-# Issuer: E=ca@trustwave.com,CN="Trustwave Organization Issuing CA, Level 2",O="Trustwave Holdings, Inc.",L=Chicago,ST=Illinois,C=US
-# Serial Number: 1800000006 (0x6b49d206)
-# Not Before: Apr 18 21:09:30 2011 GMT
-# Not After : Apr 15 21:09:30 2021 GMT
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "MITM subCA 2 issued by Trustwave"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\253\061\013\060\011\006\003\125\004\006\023\002\125\123
-\061\021\060\017\006\003\125\004\010\023\010\111\154\154\151\156
-\157\151\163\061\020\060\016\006\003\125\004\007\023\007\103\150
-\151\143\141\147\157\061\041\060\037\006\003\125\004\012\023\030
-\124\162\165\163\164\167\141\166\145\040\110\157\154\144\151\156
-\147\163\054\040\111\156\143\056\061\063\060\061\006\003\125\004
-\003\023\052\124\162\165\163\164\167\141\166\145\040\117\162\147
-\141\156\151\172\141\164\151\157\156\040\111\163\163\165\151\156
-\147\040\103\101\054\040\114\145\166\145\154\040\062\061\037\060
-\035\006\011\052\206\110\206\367\015\001\011\001\026\020\143\141
-\100\164\162\165\163\164\167\141\166\145\056\143\157\155
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\004\153\111\322\006
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Actalis Authentication Root CA"
-#
-# Issuer: CN=Actalis Authentication Root CA,O=Actalis S.p.A./03358520967,L=Milan,C=IT
-# Serial Number:57:0a:11:97:42:c4:e3:cc
-# Subject: CN=Actalis Authentication Root CA,O=Actalis S.p.A./03358520967,L=Milan,C=IT
-# Not Valid Before: Thu Sep 22 11:22:02 2011
-# Not Valid After : Sun Sep 22 11:22:02 2030
-# Fingerprint (MD5): 69:C1:0D:4F:07:A3:1B:C3:FE:56:3D:04:BC:11:F6:A6
-# Fingerprint (SHA1): F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Actalis Authentication Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\153\061\013\060\011\006\003\125\004\006\023\002\111\124\061
-\016\060\014\006\003\125\004\007\014\005\115\151\154\141\156\061
-\043\060\041\006\003\125\004\012\014\032\101\143\164\141\154\151
-\163\040\123\056\160\056\101\056\057\060\063\063\065\070\065\062
-\060\071\066\067\061\047\060\045\006\003\125\004\003\014\036\101
-\143\164\141\154\151\163\040\101\165\164\150\145\156\164\151\143
-\141\164\151\157\156\040\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\153\061\013\060\011\006\003\125\004\006\023\002\111\124\061
-\016\060\014\006\003\125\004\007\014\005\115\151\154\141\156\061
-\043\060\041\006\003\125\004\012\014\032\101\143\164\141\154\151
-\163\040\123\056\160\056\101\056\057\060\063\063\065\070\065\062
-\060\071\066\067\061\047\060\045\006\003\125\004\003\014\036\101
-\143\164\141\154\151\163\040\101\165\164\150\145\156\164\151\143
-\141\164\151\157\156\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\127\012\021\227\102\304\343\314
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\273\060\202\003\243\240\003\002\001\002\002\010\127
-\012\021\227\102\304\343\314\060\015\006\011\052\206\110\206\367
-\015\001\001\013\005\000\060\153\061\013\060\011\006\003\125\004
-\006\023\002\111\124\061\016\060\014\006\003\125\004\007\014\005
-\115\151\154\141\156\061\043\060\041\006\003\125\004\012\014\032
-\101\143\164\141\154\151\163\040\123\056\160\056\101\056\057\060
-\063\063\065\070\065\062\060\071\066\067\061\047\060\045\006\003
-\125\004\003\014\036\101\143\164\141\154\151\163\040\101\165\164
-\150\145\156\164\151\143\141\164\151\157\156\040\122\157\157\164
-\040\103\101\060\036\027\015\061\061\060\071\062\062\061\061\062
-\062\060\062\132\027\015\063\060\060\071\062\062\061\061\062\062
-\060\062\132\060\153\061\013\060\011\006\003\125\004\006\023\002
-\111\124\061\016\060\014\006\003\125\004\007\014\005\115\151\154
-\141\156\061\043\060\041\006\003\125\004\012\014\032\101\143\164
-\141\154\151\163\040\123\056\160\056\101\056\057\060\063\063\065
-\070\065\062\060\071\066\067\061\047\060\045\006\003\125\004\003
-\014\036\101\143\164\141\154\151\163\040\101\165\164\150\145\156
-\164\151\143\141\164\151\157\156\040\122\157\157\164\040\103\101
-\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001
-\000\247\306\304\245\051\244\054\357\345\030\305\260\120\243\157
-\121\073\237\012\132\311\302\110\070\012\302\034\240\030\177\221
-\265\207\271\100\077\335\035\150\037\010\203\325\055\036\210\240
-\370\217\126\217\155\231\002\222\220\026\325\137\010\154\211\327
-\341\254\274\040\302\261\340\203\121\212\151\115\000\226\132\157
-\057\300\104\176\243\016\344\221\315\130\356\334\373\307\036\105
-\107\335\047\271\010\001\237\246\041\035\365\101\055\057\114\375
-\050\255\340\212\255\042\264\126\145\216\206\124\217\223\103\051
-\336\071\106\170\243\060\043\272\315\360\175\023\127\300\135\322
-\203\153\110\114\304\253\237\200\132\133\072\275\311\247\042\077
-\200\047\063\133\016\267\212\014\135\007\067\010\313\154\322\172
-\107\042\104\065\305\314\314\056\216\335\052\355\267\175\146\015
-\137\141\121\042\125\033\343\106\343\343\075\320\065\142\232\333
-\257\024\310\133\241\314\211\033\341\060\046\374\240\233\037\201
-\247\107\037\004\353\243\071\222\006\237\231\323\277\323\352\117
-\120\234\031\376\226\207\036\074\145\366\243\030\044\203\206\020
-\347\124\076\250\072\166\044\117\201\041\305\343\017\002\370\223
-\224\107\040\273\376\324\016\323\150\271\335\304\172\204\202\343
-\123\124\171\335\333\234\322\362\007\233\056\266\274\076\355\205
-\155\357\045\021\362\227\032\102\141\367\112\227\350\213\261\020
-\007\372\145\201\262\242\071\317\367\074\377\030\373\306\361\132
-\213\131\342\002\254\173\222\320\116\024\117\131\105\366\014\136
-\050\137\260\350\077\105\317\317\257\233\157\373\204\323\167\132
-\225\157\254\224\204\236\356\274\300\112\217\112\223\370\104\041
-\342\061\105\141\120\116\020\330\343\065\174\114\031\264\336\005
-\277\243\006\237\310\265\315\344\037\327\027\006\015\172\225\164
-\125\015\150\032\374\020\033\142\144\235\155\340\225\240\303\224
-\007\127\015\024\346\275\005\373\270\237\346\337\213\342\306\347
-\176\226\366\123\305\200\064\120\050\130\360\022\120\161\027\060
-\272\346\170\143\274\364\262\255\233\053\262\376\341\071\214\136
-\272\013\040\224\336\173\203\270\377\343\126\215\267\021\351\073
-\214\362\261\301\135\235\244\013\114\053\331\262\030\365\265\237
-\113\002\003\001\000\001\243\143\060\141\060\035\006\003\125\035
-\016\004\026\004\024\122\330\210\072\310\237\170\146\355\211\363
-\173\070\160\224\311\002\002\066\320\060\017\006\003\125\035\023
-\001\001\377\004\005\060\003\001\001\377\060\037\006\003\125\035
-\043\004\030\060\026\200\024\122\330\210\072\310\237\170\146\355
-\211\363\173\070\160\224\311\002\002\066\320\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\015\006\011\052
-\206\110\206\367\015\001\001\013\005\000\003\202\002\001\000\013
-\173\162\207\300\140\246\111\114\210\130\346\035\210\367\024\144
-\110\246\330\130\012\016\117\023\065\337\065\035\324\355\006\061
-\310\201\076\152\325\335\073\032\062\356\220\075\021\322\056\364
-\216\303\143\056\043\146\260\147\276\157\266\300\023\071\140\252
-\242\064\045\223\165\122\336\247\235\255\016\207\211\122\161\152
-\026\074\031\035\203\370\232\051\145\276\364\077\232\331\360\363
-\132\207\041\161\200\115\313\340\070\233\077\273\372\340\060\115
-\317\206\323\145\020\031\030\321\227\002\261\053\162\102\150\254
-\240\275\116\132\332\030\277\153\230\201\320\375\232\276\136\025
-\110\315\021\025\271\300\051\134\264\350\210\367\076\066\256\267
-\142\375\036\142\336\160\170\020\034\110\133\332\274\244\070\272
-\147\355\125\076\136\127\337\324\003\100\114\201\244\322\117\143
-\247\011\102\011\024\374\000\251\302\200\163\117\056\300\100\331
-\021\173\110\352\172\002\300\323\353\050\001\046\130\164\301\300
-\163\042\155\223\225\375\071\175\273\052\343\366\202\343\054\227
-\137\116\037\221\224\372\376\054\243\330\166\032\270\115\262\070
-\117\233\372\035\110\140\171\046\342\363\375\251\320\232\350\160
-\217\111\172\326\345\275\012\016\333\055\363\215\277\353\343\244
-\175\313\307\225\161\350\332\243\174\305\302\370\164\222\004\033
-\206\254\244\042\123\100\266\254\376\114\166\317\373\224\062\300
-\065\237\166\077\156\345\220\156\240\246\046\242\270\054\276\321
-\053\205\375\247\150\310\272\001\053\261\154\164\035\270\163\225
-\347\356\267\307\045\360\000\114\000\262\176\266\013\213\034\363
-\300\120\236\045\271\340\010\336\066\146\377\067\245\321\273\124
-\144\054\311\047\265\113\222\176\145\377\323\055\341\271\116\274
-\177\244\101\041\220\101\167\246\071\037\352\236\343\237\320\146
-\157\005\354\252\166\176\277\153\026\240\353\265\307\374\222\124
-\057\053\021\047\045\067\170\114\121\152\260\363\314\130\135\024
-\361\152\110\025\377\302\007\266\261\215\017\216\134\120\106\263
-\075\277\001\230\117\262\131\124\107\076\064\173\170\155\126\223
-\056\163\352\146\050\170\315\035\024\277\240\217\057\056\270\056
-\216\362\024\212\314\351\265\174\373\154\235\014\245\341\226
-END
-
-# Trust for "Actalis Authentication Root CA"
-# Issuer: CN=Actalis Authentication Root CA,O=Actalis S.p.A./03358520967,L=Milan,C=IT
-# Serial Number:57:0a:11:97:42:c4:e3:cc
-# Subject: CN=Actalis Authentication Root CA,O=Actalis S.p.A./03358520967,L=Milan,C=IT
-# Not Valid Before: Thu Sep 22 11:22:02 2011
-# Not Valid After : Sun Sep 22 11:22:02 2030
-# Fingerprint (MD5): 69:C1:0D:4F:07:A3:1B:C3:FE:56:3D:04:BC:11:F6:A6
-# Fingerprint (SHA1): F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Actalis Authentication Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\363\163\263\207\006\132\050\204\212\362\363\112\316\031\053\335
-\307\216\234\254
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\151\301\015\117\007\243\033\303\376\126\075\004\274\021\366\246
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\153\061\013\060\011\006\003\125\004\006\023\002\111\124\061
-\016\060\014\006\003\125\004\007\014\005\115\151\154\141\156\061
-\043\060\041\006\003\125\004\012\014\032\101\143\164\141\154\151
-\163\040\123\056\160\056\101\056\057\060\063\063\065\070\065\062
-\060\071\066\067\061\047\060\045\006\003\125\004\003\014\036\101
-\143\164\141\154\151\163\040\101\165\164\150\145\156\164\151\143
-\141\164\151\157\156\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\010\127\012\021\227\102\304\343\314
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Trustis FPS Root CA"
-#
-# Issuer: OU=Trustis FPS Root CA,O=Trustis Limited,C=GB
-# Serial Number:1b:1f:ad:b6:20:f9:24:d3:36:6b:f7:c7:f1:8c:a0:59
-# Subject: OU=Trustis FPS Root CA,O=Trustis Limited,C=GB
-# Not Valid Before: Tue Dec 23 12:14:06 2003
-# Not Valid After : Sun Jan 21 11:36:54 2024
-# Fingerprint (MD5): 30:C9:E7:1E:6B:E6:14:EB:65:B2:16:69:20:31:67:4D
-# Fingerprint (SHA1): 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Trustis FPS Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\030\060\026\006\003\125\004\012\023\017\124\162\165\163\164\151
-\163\040\114\151\155\151\164\145\144\061\034\060\032\006\003\125
-\004\013\023\023\124\162\165\163\164\151\163\040\106\120\123\040
-\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\030\060\026\006\003\125\004\012\023\017\124\162\165\163\164\151
-\163\040\114\151\155\151\164\145\144\061\034\060\032\006\003\125
-\004\013\023\023\124\162\165\163\164\151\163\040\106\120\123\040
-\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\033\037\255\266\040\371\044\323\066\153\367\307\361\214
-\240\131
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\147\060\202\002\117\240\003\002\001\002\002\020\033
-\037\255\266\040\371\044\323\066\153\367\307\361\214\240\131\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\105
-\061\013\060\011\006\003\125\004\006\023\002\107\102\061\030\060
-\026\006\003\125\004\012\023\017\124\162\165\163\164\151\163\040
-\114\151\155\151\164\145\144\061\034\060\032\006\003\125\004\013
-\023\023\124\162\165\163\164\151\163\040\106\120\123\040\122\157
-\157\164\040\103\101\060\036\027\015\060\063\061\062\062\063\061
-\062\061\064\060\066\132\027\015\062\064\060\061\062\061\061\061
-\063\066\065\064\132\060\105\061\013\060\011\006\003\125\004\006
-\023\002\107\102\061\030\060\026\006\003\125\004\012\023\017\124
-\162\165\163\164\151\163\040\114\151\155\151\164\145\144\061\034
-\060\032\006\003\125\004\013\023\023\124\162\165\163\164\151\163
-\040\106\120\123\040\122\157\157\164\040\103\101\060\202\001\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\001\017\000\060\202\001\012\002\202\001\001\000\305\120\173
-\236\073\065\320\337\304\214\315\216\233\355\243\300\066\231\364
-\102\352\247\076\200\203\017\246\247\131\207\311\220\105\103\176
-\000\352\206\171\052\003\275\075\067\231\211\146\267\345\212\126
-\206\223\234\150\113\150\004\214\223\223\002\076\060\322\067\072
-\042\141\211\034\205\116\175\217\325\257\173\065\366\176\050\107
-\211\061\334\016\171\144\037\231\322\133\272\376\177\140\277\255
-\353\347\074\070\051\152\057\345\221\013\125\377\354\157\130\325
-\055\311\336\114\146\161\217\014\327\004\332\007\346\036\030\343
-\275\051\002\250\372\034\341\133\271\203\250\101\110\274\032\161
-\215\347\142\345\055\262\353\337\174\317\333\253\132\312\061\361
-\114\042\363\005\023\367\202\371\163\171\014\276\327\113\034\300
-\321\025\074\223\101\144\321\346\276\043\027\042\000\211\136\037
-\153\245\254\156\247\113\214\355\243\162\346\257\143\115\057\205
-\322\024\065\232\056\116\214\352\062\230\050\206\241\221\011\101
-\072\264\341\343\362\372\360\311\012\242\101\335\251\343\003\307
-\210\025\073\034\324\032\224\327\237\144\131\022\155\002\003\001
-\000\001\243\123\060\121\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\037\006\003\125\035\043\004\030
-\060\026\200\024\272\372\161\045\171\213\127\101\045\041\206\013
-\161\353\262\144\016\213\041\147\060\035\006\003\125\035\016\004
-\026\004\024\272\372\161\045\171\213\127\101\045\041\206\013\161
-\353\262\144\016\213\041\147\060\015\006\011\052\206\110\206\367
-\015\001\001\005\005\000\003\202\001\001\000\176\130\377\375\065
-\031\175\234\030\117\236\260\053\274\216\214\024\377\054\240\332
-\107\133\303\357\201\055\257\005\352\164\110\133\363\076\116\007
-\307\155\305\263\223\317\042\065\134\266\077\165\047\137\011\226
-\315\240\376\276\100\014\134\022\125\370\223\202\312\051\351\136
-\077\126\127\213\070\066\367\105\032\114\050\315\236\101\270\355
-\126\114\204\244\100\310\270\260\245\053\151\160\004\152\303\370
-\324\022\062\371\016\303\261\334\062\204\104\054\157\313\106\017
-\352\146\101\017\117\361\130\245\246\015\015\017\141\336\245\236
-\135\175\145\241\074\027\347\250\125\116\357\240\307\355\306\104
-\177\124\365\243\340\217\360\174\125\042\217\051\266\201\243\341
-\155\116\054\033\200\147\354\255\040\237\014\142\141\325\227\377
-\103\355\055\301\332\135\051\052\205\077\254\145\356\206\017\005
-\215\220\137\337\356\237\364\277\356\035\373\230\344\177\220\053
-\204\170\020\016\154\111\123\357\025\133\145\106\112\135\257\272
-\373\072\162\035\315\366\045\210\036\227\314\041\234\051\001\015
-\145\353\127\331\363\127\226\273\110\315\201
-END
-
-# Trust for "Trustis FPS Root CA"
-# Issuer: OU=Trustis FPS Root CA,O=Trustis Limited,C=GB
-# Serial Number:1b:1f:ad:b6:20:f9:24:d3:36:6b:f7:c7:f1:8c:a0:59
-# Subject: OU=Trustis FPS Root CA,O=Trustis Limited,C=GB
-# Not Valid Before: Tue Dec 23 12:14:06 2003
-# Not Valid After : Sun Jan 21 11:36:54 2024
-# Fingerprint (MD5): 30:C9:E7:1E:6B:E6:14:EB:65:B2:16:69:20:31:67:4D
-# Fingerprint (SHA1): 3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Trustis FPS Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\073\300\070\013\063\303\366\246\014\206\025\042\223\331\337\365
-\113\201\300\004
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\060\311\347\036\153\346\024\353\145\262\026\151\040\061\147\115
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\105\061\013\060\011\006\003\125\004\006\023\002\107\102\061
-\030\060\026\006\003\125\004\012\023\017\124\162\165\163\164\151
-\163\040\114\151\155\151\164\145\144\061\034\060\032\006\003\125
-\004\013\023\023\124\162\165\163\164\151\163\040\106\120\123\040
-\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\033\037\255\266\040\371\044\323\066\153\367\307\361\214
-\240\131
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "StartCom Certification Authority"
-#
-# Issuer: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL
-# Serial Number: 45 (0x2d)
-# Subject: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL
-# Not Valid Before: Sun Sep 17 19:46:37 2006
-# Not Valid After : Wed Sep 17 19:46:36 2036
-# Fingerprint (MD5): C9:3B:0D:84:41:FC:A4:76:79:23:08:57:DE:10:19:16
-# Fingerprint (SHA1): A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "StartCom Certification Authority"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061
-\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103
-\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013
-\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154
-\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147
-\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123
-\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061
-\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103
-\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013
-\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154
-\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147
-\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123
-\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\055
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\007\207\060\202\005\157\240\003\002\001\002\002\001\055
-\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
-\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026
-\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157
-\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013\023
-\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154\040
-\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147\156
-\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123\164
-\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143\141
-\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\036
-\027\015\060\066\060\071\061\067\061\071\064\066\063\067\132\027
-\015\063\066\060\071\061\067\061\071\064\066\063\066\132\060\175
-\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026\060
-\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157\155
-\040\114\164\144\056\061\053\060\051\006\003\125\004\013\023\042
-\123\145\143\165\162\145\040\104\151\147\151\164\141\154\040\103
-\145\162\164\151\146\151\143\141\164\145\040\123\151\147\156\151
-\156\147\061\051\060\047\006\003\125\004\003\023\040\123\164\141
-\162\164\103\157\155\040\103\145\162\164\151\146\151\143\141\164
-\151\157\156\040\101\165\164\150\157\162\151\164\171\060\202\002
-\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\202\002\017\000\060\202\002\012\002\202\002\001\000\301\210
-\333\011\274\154\106\174\170\237\225\173\265\063\220\362\162\142
-\326\301\066\040\042\044\136\316\351\167\362\103\012\242\006\144
-\244\314\216\066\370\070\346\043\360\156\155\261\074\335\162\243
-\205\034\241\323\075\264\063\053\323\057\257\376\352\260\101\131
-\147\266\304\006\175\012\236\164\205\326\171\114\200\067\172\337
-\071\005\122\131\367\364\033\106\103\244\322\205\205\322\303\161
-\363\165\142\064\272\054\212\177\036\217\356\355\064\320\021\307
-\226\315\122\075\272\063\326\335\115\336\013\073\112\113\237\302
-\046\057\372\265\026\034\162\065\167\312\074\135\346\312\341\046
-\213\032\066\166\134\001\333\164\024\045\376\355\265\240\210\017
-\335\170\312\055\037\007\227\060\001\055\162\171\372\106\326\023
-\052\250\271\246\253\203\111\035\345\362\357\335\344\001\216\030
-\012\217\143\123\026\205\142\251\016\031\072\314\265\146\246\302
-\153\164\007\344\053\341\166\076\264\155\330\366\104\341\163\142
-\037\073\304\276\240\123\126\045\154\121\011\367\252\253\312\277
-\166\375\155\233\363\235\333\277\075\146\274\014\126\252\257\230
-\110\225\072\113\337\247\130\120\331\070\165\251\133\352\103\014
-\002\377\231\353\350\154\115\160\133\051\145\234\335\252\135\314
-\257\001\061\354\014\353\322\215\350\352\234\173\346\156\367\047
-\146\014\032\110\327\156\102\343\077\336\041\076\173\341\015\160
-\373\143\252\250\154\032\124\264\134\045\172\311\242\311\213\026
-\246\273\054\176\027\136\005\115\130\156\022\035\001\356\022\020
-\015\306\062\177\030\377\374\364\372\315\156\221\350\066\111\276
-\032\110\151\213\302\226\115\032\022\262\151\027\301\012\220\326
-\372\171\042\110\277\272\173\151\370\160\307\372\172\067\330\330
-\015\322\166\117\127\377\220\267\343\221\322\335\357\302\140\267
-\147\072\335\376\252\234\360\324\213\177\162\042\316\306\237\227
-\266\370\257\212\240\020\250\331\373\030\306\266\265\134\122\074
-\211\266\031\052\163\001\012\017\003\263\022\140\362\172\057\201
-\333\243\156\377\046\060\227\365\213\335\211\127\266\255\075\263
-\257\053\305\267\166\002\360\245\326\053\232\206\024\052\162\366
-\343\063\214\135\011\113\023\337\273\214\164\023\122\113\002\003
-\001\000\001\243\202\002\020\060\202\002\014\060\017\006\003\125
-\035\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003
-\125\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003
-\125\035\016\004\026\004\024\116\013\357\032\244\100\133\245\027
-\151\207\060\312\064\150\103\320\101\256\362\060\037\006\003\125
-\035\043\004\030\060\026\200\024\116\013\357\032\244\100\133\245
-\027\151\207\060\312\064\150\103\320\101\256\362\060\202\001\132
-\006\003\125\035\040\004\202\001\121\060\202\001\115\060\202\001
-\111\006\013\053\006\001\004\001\201\265\067\001\001\001\060\202
-\001\070\060\056\006\010\053\006\001\005\005\007\002\001\026\042
-\150\164\164\160\072\057\057\167\167\167\056\163\164\141\162\164
-\163\163\154\056\143\157\155\057\160\157\154\151\143\171\056\160
-\144\146\060\064\006\010\053\006\001\005\005\007\002\001\026\050
-\150\164\164\160\072\057\057\167\167\167\056\163\164\141\162\164
-\163\163\154\056\143\157\155\057\151\156\164\145\162\155\145\144
-\151\141\164\145\056\160\144\146\060\201\317\006\010\053\006\001
-\005\005\007\002\002\060\201\302\060\047\026\040\123\164\141\162
-\164\040\103\157\155\155\145\162\143\151\141\154\040\050\123\164
-\141\162\164\103\157\155\051\040\114\164\144\056\060\003\002\001
-\001\032\201\226\114\151\155\151\164\145\144\040\114\151\141\142
-\151\154\151\164\171\054\040\162\145\141\144\040\164\150\145\040
-\163\145\143\164\151\157\156\040\052\114\145\147\141\154\040\114
-\151\155\151\164\141\164\151\157\156\163\052\040\157\146\040\164
-\150\145\040\123\164\141\162\164\103\157\155\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162
-\151\164\171\040\120\157\154\151\143\171\040\141\166\141\151\154
-\141\142\154\145\040\141\164\040\150\164\164\160\072\057\057\167
-\167\167\056\163\164\141\162\164\163\163\154\056\143\157\155\057
-\160\157\154\151\143\171\056\160\144\146\060\021\006\011\140\206
-\110\001\206\370\102\001\001\004\004\003\002\000\007\060\070\006
-\011\140\206\110\001\206\370\102\001\015\004\053\026\051\123\164
-\141\162\164\103\157\155\040\106\162\145\145\040\123\123\114\040
-\103\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165
-\164\150\157\162\151\164\171\060\015\006\011\052\206\110\206\367
-\015\001\001\013\005\000\003\202\002\001\000\216\217\347\334\224
-\171\174\361\205\177\237\111\157\153\312\135\373\214\376\004\305
-\301\142\321\175\102\212\274\123\267\224\003\146\060\077\261\347
-\012\247\120\040\125\045\177\166\172\024\015\353\004\016\100\346
-\076\330\210\253\007\047\203\251\165\246\067\163\307\375\113\322
-\115\255\027\100\310\106\276\073\177\121\374\303\266\005\061\334
-\315\205\042\116\161\267\362\161\136\260\032\306\272\223\213\170
-\222\112\205\370\170\017\203\376\057\255\054\367\344\244\273\055
-\320\347\015\072\270\076\316\366\170\366\256\107\044\312\243\065
-\066\316\307\306\207\230\332\354\373\351\262\316\047\233\210\303
-\004\241\366\013\131\150\257\311\333\020\017\115\366\144\143\134
-\245\022\157\222\262\223\224\307\210\027\016\223\266\176\142\213
-\220\177\253\116\237\374\343\165\024\117\052\062\337\133\015\340
-\365\173\223\015\253\241\317\207\341\245\004\105\350\074\022\245
-\011\305\260\321\267\123\363\140\024\272\205\151\152\041\174\037
-\165\141\027\040\027\173\154\073\101\051\134\341\254\132\321\315
-\214\233\353\140\035\031\354\367\345\260\332\371\171\030\245\105
-\077\111\103\127\322\335\044\325\054\243\375\221\215\047\265\345
-\353\024\006\232\114\173\041\273\072\255\060\006\030\300\330\301
-\153\054\177\131\134\135\221\261\160\042\127\353\212\153\110\112
-\325\017\051\354\306\100\300\057\210\114\150\001\027\167\364\044
-\031\117\275\372\341\262\040\041\113\335\032\330\051\175\252\270
-\336\124\354\041\125\200\154\036\365\060\310\243\020\345\262\346
-\052\024\061\303\205\055\214\230\261\206\132\117\211\131\055\271
-\307\367\034\310\212\177\300\235\005\112\346\102\117\142\243\155
-\051\244\037\205\253\333\345\201\310\255\052\075\114\135\133\204
-\046\161\304\205\136\161\044\312\245\033\154\330\141\323\032\340
-\124\333\316\272\251\062\265\042\366\163\101\011\135\270\027\135
-\016\017\231\220\326\107\332\157\012\072\142\050\024\147\202\331
-\361\320\200\131\233\313\061\330\233\017\214\167\116\265\150\212
-\362\154\366\044\016\055\154\160\305\163\321\336\024\320\161\217
-\266\323\173\002\366\343\270\324\011\156\153\236\165\204\071\346
-\177\045\245\362\110\000\300\244\001\332\077
-END
-
-# Trust for "StartCom Certification Authority"
-# Issuer: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL
-# Serial Number: 45 (0x2d)
-# Subject: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL
-# Not Valid Before: Sun Sep 17 19:46:37 2006
-# Not Valid After : Wed Sep 17 19:46:36 2036
-# Fingerprint (MD5): C9:3B:0D:84:41:FC:A4:76:79:23:08:57:DE:10:19:16
-# Fingerprint (SHA1): A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "StartCom Certification Authority"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\243\361\063\077\342\102\277\317\305\321\116\217\071\102\230\100
-\150\020\321\240
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\311\073\015\204\101\374\244\166\171\043\010\127\336\020\031\026
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\175\061\013\060\011\006\003\125\004\006\023\002\111\114\061
-\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103
-\157\155\040\114\164\144\056\061\053\060\051\006\003\125\004\013
-\023\042\123\145\143\165\162\145\040\104\151\147\151\164\141\154
-\040\103\145\162\164\151\146\151\143\141\164\145\040\123\151\147
-\156\151\156\147\061\051\060\047\006\003\125\004\003\023\040\123
-\164\141\162\164\103\157\155\040\103\145\162\164\151\146\151\143
-\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\055
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "StartCom Certification Authority G2"
-#
-# Issuer: CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL
-# Serial Number: 59 (0x3b)
-# Subject: CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL
-# Not Valid Before: Fri Jan 01 01:00:01 2010
-# Not Valid After : Sat Dec 31 23:59:01 2039
-# Fingerprint (MD5): 78:4B:FB:9E:64:82:0A:D3:B8:4C:62:F3:64:F2:90:64
-# Fingerprint (SHA1): 31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "StartCom Certification Authority G2"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\123\061\013\060\011\006\003\125\004\006\023\002\111\114\061
-\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103
-\157\155\040\114\164\144\056\061\054\060\052\006\003\125\004\003
-\023\043\123\164\141\162\164\103\157\155\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\107\062
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\123\061\013\060\011\006\003\125\004\006\023\002\111\114\061
-\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103
-\157\155\040\114\164\144\056\061\054\060\052\006\003\125\004\003
-\023\043\123\164\141\162\164\103\157\155\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\073
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\143\060\202\003\113\240\003\002\001\002\002\001\073
-\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
-\123\061\013\060\011\006\003\125\004\006\023\002\111\114\061\026
-\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103\157
-\155\040\114\164\144\056\061\054\060\052\006\003\125\004\003\023
-\043\123\164\141\162\164\103\157\155\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164
-\171\040\107\062\060\036\027\015\061\060\060\061\060\061\060\061
-\060\060\060\061\132\027\015\063\071\061\062\063\061\062\063\065
-\071\060\061\132\060\123\061\013\060\011\006\003\125\004\006\023
-\002\111\114\061\026\060\024\006\003\125\004\012\023\015\123\164
-\141\162\164\103\157\155\040\114\164\144\056\061\054\060\052\006
-\003\125\004\003\023\043\123\164\141\162\164\103\157\155\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164
-\150\157\162\151\164\171\040\107\062\060\202\002\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017
-\000\060\202\002\012\002\202\002\001\000\266\211\066\133\007\267
-\040\066\275\202\273\341\026\040\003\225\172\257\016\243\125\311
-\045\231\112\305\320\126\101\207\220\115\041\140\244\024\207\073
-\315\375\262\076\264\147\003\152\355\341\017\113\300\221\205\160
-\105\340\102\236\336\051\043\324\001\015\240\020\171\270\333\003
-\275\363\251\057\321\306\340\017\313\236\212\024\012\270\275\366
-\126\142\361\305\162\266\062\045\331\262\363\275\145\305\015\054
-\156\325\222\157\030\213\000\101\024\202\157\100\040\046\172\050
-\017\365\036\177\047\367\224\261\067\075\267\307\221\367\342\001
-\354\375\224\211\341\314\156\323\066\326\012\031\171\256\327\064
-\202\145\377\174\102\273\266\335\013\246\064\257\113\140\376\177
-\103\111\006\213\214\103\270\126\362\331\177\041\103\027\352\247
-\110\225\001\165\165\352\053\245\103\225\352\025\204\235\010\215
-\046\156\125\233\253\334\322\071\322\061\035\140\342\254\314\126
-\105\044\365\034\124\253\356\206\335\226\062\205\370\114\117\350
-\225\166\266\005\335\066\043\147\274\377\025\342\312\073\346\246
-\354\073\354\046\021\064\110\215\366\200\053\032\043\002\353\212
-\034\072\166\052\173\126\026\034\162\052\263\252\343\140\245\000
-\237\004\233\342\157\036\024\130\133\245\154\213\130\074\303\272
-\116\072\134\367\341\226\053\076\357\007\274\244\345\135\314\115
-\237\015\341\334\252\273\341\156\032\354\217\341\266\114\115\171
-\162\135\027\065\013\035\327\301\107\332\226\044\340\320\162\250
-\132\137\146\055\020\334\057\052\023\256\046\376\012\034\031\314
-\320\076\013\234\310\011\056\371\133\226\172\107\234\351\172\363
-\005\120\164\225\163\236\060\011\363\227\202\136\346\217\071\010
-\036\131\345\065\024\102\023\377\000\234\367\276\252\120\317\342
-\121\110\327\270\157\257\370\116\176\063\230\222\024\142\072\165
-\143\317\173\372\336\202\073\251\273\071\342\304\275\054\000\016
-\310\027\254\023\357\115\045\216\330\263\220\057\251\332\051\175
-\035\257\164\072\262\047\300\301\036\076\165\243\026\251\257\172
-\042\135\237\023\032\317\247\240\353\343\206\012\323\375\346\226
-\225\327\043\310\067\335\304\174\252\066\254\230\032\022\261\340
-\116\350\261\073\365\326\157\361\060\327\002\003\001\000\001\243
-\102\060\100\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\006\060\035\006\003\125\035\016\004\026\004\024\113
-\305\264\100\153\255\034\263\245\034\145\156\106\066\211\207\005
-\014\016\266\060\015\006\011\052\206\110\206\367\015\001\001\013
-\005\000\003\202\002\001\000\163\127\077\054\325\225\062\176\067
-\333\226\222\353\031\136\176\123\347\101\354\021\266\107\357\265
-\336\355\164\134\305\361\216\111\340\374\156\231\023\315\237\212
-\332\315\072\012\330\072\132\011\077\137\064\320\057\003\322\146
-\035\032\275\234\220\067\310\014\216\007\132\224\105\106\052\346
-\276\172\332\241\251\244\151\022\222\260\175\066\324\104\207\327
-\121\361\051\143\326\165\315\026\344\047\211\035\370\302\062\110
-\375\333\231\320\217\137\124\164\314\254\147\064\021\142\331\014
-\012\067\207\321\243\027\110\216\322\027\035\366\327\375\333\145
-\353\375\250\324\365\326\117\244\133\165\350\305\322\140\262\333
-\011\176\045\213\173\272\122\222\236\076\350\305\167\241\074\340
-\112\163\153\141\317\206\334\103\377\377\041\376\043\135\044\112
-\365\323\155\017\142\004\005\127\202\332\156\244\063\045\171\113
-\056\124\031\213\314\054\075\060\351\321\006\377\350\062\106\276
-\265\063\166\167\250\001\135\226\301\301\325\276\256\045\300\311
-\036\012\011\040\210\241\016\311\363\157\115\202\124\000\040\247
-\322\217\344\071\124\027\056\215\036\270\033\273\033\275\232\116
-\073\020\064\334\234\210\123\357\242\061\133\130\117\221\142\310
-\302\232\232\315\025\135\070\251\326\276\370\023\265\237\022\151
-\362\120\142\254\373\027\067\364\356\270\165\147\140\020\373\203
-\120\371\104\265\165\234\100\027\262\376\375\171\135\156\130\130
-\137\060\374\000\256\257\063\301\016\116\154\272\247\246\241\177
-\062\333\070\340\261\162\027\012\053\221\354\152\143\046\355\211
-\324\170\314\164\036\005\370\153\376\214\152\166\071\051\256\145
-\043\022\225\010\042\034\227\316\133\006\356\014\342\273\274\037
-\104\223\366\330\070\105\005\041\355\344\255\253\022\266\003\244
-\102\056\055\304\011\072\003\147\151\204\232\341\131\220\212\050
-\205\325\135\164\261\321\016\040\130\233\023\245\260\143\246\355
-\173\107\375\105\125\060\244\356\232\324\346\342\207\357\230\311
-\062\202\021\051\042\274\000\012\061\136\055\017\300\216\351\153
-\262\217\056\006\330\321\221\307\306\022\364\114\375\060\027\303
-\301\332\070\133\343\251\352\346\241\272\171\357\163\330\266\123
-\127\055\366\320\341\327\110
-END
-
-# Trust for "StartCom Certification Authority G2"
-# Issuer: CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL
-# Serial Number: 59 (0x3b)
-# Subject: CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL
-# Not Valid Before: Fri Jan 01 01:00:01 2010
-# Not Valid After : Sat Dec 31 23:59:01 2039
-# Fingerprint (MD5): 78:4B:FB:9E:64:82:0A:D3:B8:4C:62:F3:64:F2:90:64
-# Fingerprint (SHA1): 31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "StartCom Certification Authority G2"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\061\361\375\150\042\143\040\356\306\073\077\235\352\112\076\123
-\174\174\071\027
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\170\113\373\236\144\202\012\323\270\114\142\363\144\362\220\144
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\123\061\013\060\011\006\003\125\004\006\023\002\111\114\061
-\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164\103
-\157\155\040\114\164\144\056\061\054\060\052\006\003\125\004\003
-\023\043\123\164\141\162\164\103\157\155\040\103\145\162\164\151
-\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151
-\164\171\040\107\062
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\073
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Buypass Class 2 Root CA"
-#
-# Issuer: CN=Buypass Class 2 Root CA,O=Buypass AS-983163327,C=NO
-# Serial Number: 2 (0x2)
-# Subject: CN=Buypass Class 2 Root CA,O=Buypass AS-983163327,C=NO
-# Not Valid Before: Tue Oct 26 08:38:03 2010
-# Not Valid After : Fri Oct 26 08:38:03 2040
-# Fingerprint (MD5): 46:A7:D2:FE:45:FB:64:5A:A8:59:90:9B:78:44:9B:29
-# Fingerprint (SHA1): 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Buypass Class 2 Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040
-\060\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\062\040\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040
-\060\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\062\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\002
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\131\060\202\003\101\240\003\002\001\002\002\001\002
-\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
-\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061\035
-\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163\163
-\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040\060
-\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163\040
-\103\154\141\163\163\040\062\040\122\157\157\164\040\103\101\060
-\036\027\015\061\060\061\060\062\066\060\070\063\070\060\063\132
-\027\015\064\060\061\060\062\066\060\070\063\070\060\063\132\060
-\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061\035
-\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163\163
-\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040\060
-\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163\040
-\103\154\141\163\163\040\062\040\122\157\157\164\040\103\101\060
-\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001
-\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000
-\327\307\136\367\301\007\324\167\373\103\041\364\364\365\151\344
-\356\062\001\333\243\206\037\344\131\015\272\347\165\203\122\353
-\352\034\141\025\110\273\035\007\312\214\256\260\334\226\235\352
-\303\140\222\206\202\050\163\234\126\006\377\113\144\360\014\052
-\067\111\265\345\317\014\174\356\361\112\273\163\060\145\363\325
-\057\203\266\176\343\347\365\236\253\140\371\323\361\235\222\164
-\212\344\034\226\254\133\200\351\265\364\061\207\243\121\374\307
-\176\241\157\216\123\167\324\227\301\125\063\222\076\030\057\165
-\324\255\206\111\313\225\257\124\006\154\330\006\023\215\133\377
-\341\046\031\131\300\044\272\201\161\171\220\104\120\150\044\224
-\137\270\263\021\361\051\101\141\243\101\313\043\066\325\301\361
-\062\120\020\116\177\364\206\223\354\204\323\216\274\113\277\134
-\001\116\007\075\334\024\212\224\012\244\352\163\373\013\121\350
-\023\007\030\372\016\361\053\321\124\025\175\074\341\367\264\031
-\102\147\142\136\167\340\242\125\354\266\331\151\027\325\072\257
-\104\355\112\305\236\344\172\047\174\345\165\327\252\313\045\347
-\337\153\012\333\017\115\223\116\250\240\315\173\056\362\131\001
-\152\267\015\270\007\201\176\213\070\033\070\346\012\127\231\075
-\356\041\350\243\365\014\026\335\213\354\064\216\234\052\034\000
-\025\027\215\150\203\322\160\237\030\010\315\021\150\325\311\153
-\122\315\304\106\217\334\265\363\330\127\163\036\351\224\071\004
-\277\323\336\070\336\264\123\354\151\034\242\176\304\217\344\033
-\160\255\362\242\371\373\367\026\144\146\151\237\111\121\242\342
-\025\030\147\006\112\177\325\154\265\115\263\063\340\141\353\135
-\276\351\230\017\062\327\035\113\074\056\132\001\122\221\011\362
-\337\352\215\330\006\100\143\252\021\344\376\303\067\236\024\122
-\077\364\342\314\362\141\223\321\375\147\153\327\122\256\277\150
-\253\100\103\240\127\065\123\170\360\123\370\141\102\007\144\306
-\327\157\233\114\070\015\143\254\142\257\066\213\242\163\012\015
-\365\041\275\164\252\115\352\162\003\111\333\307\137\035\142\143
-\307\375\335\221\354\063\356\365\155\264\156\060\150\336\310\326
-\046\260\165\136\173\264\007\040\230\241\166\062\270\115\154\117
-\002\003\001\000\001\243\102\060\100\060\017\006\003\125\035\023
-\001\001\377\004\005\060\003\001\001\377\060\035\006\003\125\035
-\016\004\026\004\024\311\200\167\340\142\222\202\365\106\234\363
-\272\367\114\303\336\270\243\255\071\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\001\006\060\015\006\011\052\206\110
-\206\367\015\001\001\013\005\000\003\202\002\001\000\123\137\041
-\365\272\260\072\122\071\054\222\260\154\000\311\357\316\040\357
-\006\362\226\236\351\244\164\177\172\026\374\267\365\266\373\025
-\033\077\253\246\300\162\135\020\261\161\356\274\117\343\255\254
-\003\155\056\161\056\257\304\343\255\243\275\014\021\247\264\377
-\112\262\173\020\020\037\247\127\101\262\300\256\364\054\131\326
-\107\020\210\363\041\121\051\060\312\140\206\257\106\253\035\355
-\072\133\260\224\336\104\343\101\010\242\301\354\035\326\375\117
-\266\326\107\320\024\013\312\346\312\265\173\167\176\101\037\136
-\203\307\266\214\071\226\260\077\226\201\101\157\140\220\342\350
-\371\373\042\161\331\175\263\075\106\277\264\204\257\220\034\017
-\217\022\152\257\357\356\036\172\256\002\112\212\027\053\166\376
-\254\124\211\044\054\117\077\266\262\247\116\214\250\221\227\373
-\051\306\173\134\055\271\313\146\266\267\250\133\022\121\205\265
-\011\176\142\170\160\376\251\152\140\266\035\016\171\014\375\312
-\352\044\200\162\303\227\077\362\167\253\103\042\012\307\353\266
-\014\204\202\054\200\153\101\212\010\300\353\245\153\337\231\022
-\313\212\325\136\200\014\221\340\046\010\066\110\305\372\070\021
-\065\377\045\203\055\362\172\277\332\375\216\376\245\313\105\054
-\037\304\210\123\256\167\016\331\232\166\305\216\054\035\243\272
-\325\354\062\256\300\252\254\367\321\172\115\353\324\007\342\110
-\367\042\216\260\244\237\152\316\216\262\262\140\364\243\042\320
-\043\353\224\132\172\151\335\017\277\100\127\254\153\131\120\331
-\243\231\341\156\376\215\001\171\047\043\025\336\222\235\173\011
-\115\132\347\113\110\060\132\030\346\012\155\346\217\340\322\273
-\346\337\174\156\041\202\301\150\071\115\264\230\130\146\142\314
-\112\220\136\303\372\047\004\261\171\025\164\231\314\276\255\040
-\336\046\140\034\353\126\121\246\243\352\344\243\077\247\377\141
-\334\361\132\115\154\062\043\103\356\254\250\356\356\112\022\011
-\074\135\161\302\276\171\372\302\207\150\035\013\375\134\151\314
-\006\320\232\175\124\231\052\311\071\032\031\257\113\052\103\363
-\143\135\132\130\342\057\343\035\344\251\326\320\012\320\236\277
-\327\201\011\361\311\307\046\015\254\230\026\126\240
-END
-
-# Trust for "Buypass Class 2 Root CA"
-# Issuer: CN=Buypass Class 2 Root CA,O=Buypass AS-983163327,C=NO
-# Serial Number: 2 (0x2)
-# Subject: CN=Buypass Class 2 Root CA,O=Buypass AS-983163327,C=NO
-# Not Valid Before: Tue Oct 26 08:38:03 2010
-# Not Valid After : Fri Oct 26 08:38:03 2040
-# Fingerprint (MD5): 46:A7:D2:FE:45:FB:64:5A:A8:59:90:9B:78:44:9B:29
-# Fingerprint (SHA1): 49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Buypass Class 2 Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\111\012\165\164\336\207\012\107\376\130\356\366\307\153\353\306
-\013\022\100\231
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\106\247\322\376\105\373\144\132\250\131\220\233\170\104\233\051
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040
-\060\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\062\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\002
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "Buypass Class 3 Root CA"
-#
-# Issuer: CN=Buypass Class 3 Root CA,O=Buypass AS-983163327,C=NO
-# Serial Number: 2 (0x2)
-# Subject: CN=Buypass Class 3 Root CA,O=Buypass AS-983163327,C=NO
-# Not Valid Before: Tue Oct 26 08:28:58 2010
-# Not Valid After : Fri Oct 26 08:28:58 2040
-# Fingerprint (MD5): 3D:3B:18:9E:2C:64:5A:E8:D5:88:CE:0E:F9:37:C2:EC
-# Fingerprint (SHA1): DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Buypass Class 3 Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040
-\060\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\063\040\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040
-\060\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\063\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\002
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\131\060\202\003\101\240\003\002\001\002\002\001\002
-\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
-\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061\035
-\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163\163
-\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040\060
-\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163\040
-\103\154\141\163\163\040\063\040\122\157\157\164\040\103\101\060
-\036\027\015\061\060\061\060\062\066\060\070\062\070\065\070\132
-\027\015\064\060\061\060\062\066\060\070\062\070\065\070\132\060
-\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061\035
-\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163\163
-\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040\060
-\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163\040
-\103\154\141\163\163\040\063\040\122\157\157\164\040\103\101\060
-\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001\001
-\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001\000
-\245\332\012\225\026\120\343\225\362\136\235\166\061\006\062\172
-\233\361\020\166\270\000\232\265\122\066\315\044\107\260\237\030
-\144\274\232\366\372\325\171\330\220\142\114\042\057\336\070\075
-\326\340\250\351\034\054\333\170\021\351\216\150\121\025\162\307
-\363\063\207\344\240\135\013\134\340\127\007\052\060\365\315\304
-\067\167\050\115\030\221\346\277\325\122\375\161\055\160\076\347
-\306\304\212\343\360\050\013\364\166\230\241\213\207\125\262\072
-\023\374\267\076\047\067\216\042\343\250\117\052\357\140\273\075
-\267\071\303\016\001\107\231\135\022\117\333\103\372\127\241\355
-\371\235\276\021\107\046\133\023\230\253\135\026\212\260\067\034
-\127\235\105\377\210\226\066\277\273\312\007\173\157\207\143\327
-\320\062\152\326\135\154\014\361\263\156\071\342\153\061\056\071
-\000\047\024\336\070\300\354\031\146\206\022\350\235\162\026\023
-\144\122\307\251\067\034\375\202\060\355\204\030\035\364\256\134
-\377\160\023\000\353\261\365\063\172\113\326\125\370\005\215\113
-\151\260\365\263\050\066\134\024\304\121\163\115\153\013\361\064
-\007\333\027\071\327\334\050\173\153\365\237\363\056\301\117\027
-\052\020\363\314\312\350\353\375\153\253\056\232\237\055\202\156
-\004\324\122\001\223\055\075\206\374\176\374\337\357\102\035\246
-\153\357\271\040\306\367\275\240\247\225\375\247\346\211\044\330
-\314\214\064\154\342\043\057\331\022\032\041\271\125\221\157\013
-\221\171\031\014\255\100\210\013\160\342\172\322\016\330\150\110
-\273\202\023\071\020\130\351\330\052\007\306\022\333\130\333\322
-\073\125\020\107\005\025\147\142\176\030\143\246\106\077\011\016
-\124\062\136\277\015\142\172\047\357\200\350\333\331\113\006\132
-\067\132\045\320\010\022\167\324\157\011\120\227\075\310\035\303
-\337\214\105\060\126\306\323\144\253\146\363\300\136\226\234\303
-\304\357\303\174\153\213\072\171\177\263\111\317\075\342\211\237
-\240\060\113\205\271\234\224\044\171\217\175\153\251\105\150\017
-\053\320\361\332\034\313\151\270\312\111\142\155\310\320\143\142
-\335\140\017\130\252\217\241\274\005\245\146\242\317\033\166\262
-\204\144\261\114\071\122\300\060\272\360\214\113\002\260\266\267
-\002\003\001\000\001\243\102\060\100\060\017\006\003\125\035\023
-\001\001\377\004\005\060\003\001\001\377\060\035\006\003\125\035
-\016\004\026\004\024\107\270\315\377\345\157\356\370\262\354\057
-\116\016\371\045\260\216\074\153\303\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\001\006\060\015\006\011\052\206\110
-\206\367\015\001\001\013\005\000\003\202\002\001\000\000\040\043
-\101\065\004\220\302\100\142\140\357\342\065\114\327\077\254\342
-\064\220\270\241\157\166\372\026\026\244\110\067\054\351\220\302
-\362\074\370\012\237\330\201\345\273\133\332\045\054\244\247\125
-\161\044\062\366\310\013\362\274\152\370\223\254\262\007\302\137
-\237\333\314\310\212\252\276\152\157\341\111\020\314\061\327\200
-\273\273\310\330\242\016\144\127\352\242\365\302\251\061\025\322
-\040\152\354\374\042\001\050\317\206\270\200\036\251\314\021\245
-\074\362\026\263\107\235\374\322\200\041\304\313\320\107\160\101
-\241\312\203\031\010\054\155\362\135\167\234\212\024\023\324\066
-\034\222\360\345\006\067\334\246\346\220\233\070\217\134\153\033
-\106\206\103\102\137\076\001\007\123\124\135\145\175\367\212\163
-\241\232\124\132\037\051\103\024\047\302\205\017\265\210\173\032
-\073\224\267\035\140\247\265\234\347\051\151\127\132\233\223\172
-\103\060\033\003\327\142\310\100\246\252\374\144\344\112\327\221
-\123\001\250\040\210\156\234\137\104\271\313\140\201\064\354\157
-\323\175\332\110\137\353\264\220\274\055\251\034\013\254\034\325
-\242\150\040\200\004\326\374\261\217\057\273\112\061\015\112\206
-\034\353\342\066\051\046\365\332\330\304\362\165\141\317\176\256
-\166\143\112\172\100\145\223\207\370\036\200\214\206\345\206\326
-\217\016\374\123\054\140\350\026\141\032\242\076\103\173\315\071
-\140\124\152\365\362\211\046\001\150\203\110\242\063\350\311\004
-\221\262\021\064\021\076\352\320\103\031\037\003\223\220\014\377
-\121\075\127\364\101\156\341\313\240\276\353\311\143\315\155\314
-\344\370\066\252\150\235\355\275\135\227\160\104\015\266\016\065
-\334\341\014\135\273\240\121\224\313\176\026\353\021\057\243\222
-\105\310\114\161\331\274\311\231\122\127\106\057\120\317\275\065
-\151\364\075\025\316\006\245\054\017\076\366\201\272\224\273\303
-\273\277\145\170\322\206\171\377\111\073\032\203\014\360\336\170
-\354\310\362\115\114\032\336\202\051\370\301\132\332\355\356\346
-\047\136\350\105\320\235\034\121\250\150\253\104\343\320\213\152
-\343\370\073\273\334\115\327\144\362\121\276\346\252\253\132\351
-\061\356\006\274\163\277\023\142\012\237\307\271\227
-END
-
-# Trust for "Buypass Class 3 Root CA"
-# Issuer: CN=Buypass Class 3 Root CA,O=Buypass AS-983163327,C=NO
-# Serial Number: 2 (0x2)
-# Subject: CN=Buypass Class 3 Root CA,O=Buypass AS-983163327,C=NO
-# Not Valid Before: Tue Oct 26 08:28:58 2010
-# Not Valid After : Fri Oct 26 08:28:58 2040
-# Fingerprint (MD5): 3D:3B:18:9E:2C:64:5A:E8:D5:88:CE:0E:F9:37:C2:EC
-# Fingerprint (SHA1): DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Buypass Class 3 Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\332\372\367\372\146\204\354\006\217\024\120\275\307\302\201\245
-\274\251\144\127
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\075\073\030\236\054\144\132\350\325\210\316\016\371\067\302\354
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\116\061\013\060\011\006\003\125\004\006\023\002\116\117\061
-\035\060\033\006\003\125\004\012\014\024\102\165\171\160\141\163
-\163\040\101\123\055\071\070\063\061\066\063\063\062\067\061\040
-\060\036\006\003\125\004\003\014\027\102\165\171\160\141\163\163
-\040\103\154\141\163\163\040\063\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\002
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "T-TeleSec GlobalRoot Class 3"
-#
-# Issuer: CN=T-TeleSec GlobalRoot Class 3,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE
-# Serial Number: 1 (0x1)
-# Subject: CN=T-TeleSec GlobalRoot Class 3,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE
-# Not Valid Before: Wed Oct 01 10:29:56 2008
-# Not Valid After : Sat Oct 01 23:59:59 2033
-# Fingerprint (MD5): CA:FB:40:A8:4E:39:92:8A:1D:FE:8E:2F:C4:27:EA:EF
-# Fingerprint (SHA1): 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "T-TeleSec GlobalRoot Class 3"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\053\060\051\006\003\125\004\012\014\042\124\055\123\171\163
-\164\145\155\163\040\105\156\164\145\162\160\162\151\163\145\040
-\123\145\162\166\151\143\145\163\040\107\155\142\110\061\037\060
-\035\006\003\125\004\013\014\026\124\055\123\171\163\164\145\155
-\163\040\124\162\165\163\164\040\103\145\156\164\145\162\061\045
-\060\043\006\003\125\004\003\014\034\124\055\124\145\154\145\123
-\145\143\040\107\154\157\142\141\154\122\157\157\164\040\103\154
-\141\163\163\040\063
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\053\060\051\006\003\125\004\012\014\042\124\055\123\171\163
-\164\145\155\163\040\105\156\164\145\162\160\162\151\163\145\040
-\123\145\162\166\151\143\145\163\040\107\155\142\110\061\037\060
-\035\006\003\125\004\013\014\026\124\055\123\171\163\164\145\155
-\163\040\124\162\165\163\164\040\103\145\156\164\145\162\061\045
-\060\043\006\003\125\004\003\014\034\124\055\124\145\154\145\123
-\145\143\040\107\154\157\142\141\154\122\157\157\164\040\103\154
-\141\163\163\040\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\303\060\202\002\253\240\003\002\001\002\002\001\001
-\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060
-\201\202\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\053\060\051\006\003\125\004\012\014\042\124\055\123\171\163\164
-\145\155\163\040\105\156\164\145\162\160\162\151\163\145\040\123
-\145\162\166\151\143\145\163\040\107\155\142\110\061\037\060\035
-\006\003\125\004\013\014\026\124\055\123\171\163\164\145\155\163
-\040\124\162\165\163\164\040\103\145\156\164\145\162\061\045\060
-\043\006\003\125\004\003\014\034\124\055\124\145\154\145\123\145
-\143\040\107\154\157\142\141\154\122\157\157\164\040\103\154\141
-\163\163\040\063\060\036\027\015\060\070\061\060\060\061\061\060
-\062\071\065\066\132\027\015\063\063\061\060\060\061\062\063\065
-\071\065\071\132\060\201\202\061\013\060\011\006\003\125\004\006
-\023\002\104\105\061\053\060\051\006\003\125\004\012\014\042\124
-\055\123\171\163\164\145\155\163\040\105\156\164\145\162\160\162
-\151\163\145\040\123\145\162\166\151\143\145\163\040\107\155\142
-\110\061\037\060\035\006\003\125\004\013\014\026\124\055\123\171
-\163\164\145\155\163\040\124\162\165\163\164\040\103\145\156\164
-\145\162\061\045\060\043\006\003\125\004\003\014\034\124\055\124
-\145\154\145\123\145\143\040\107\154\157\142\141\154\122\157\157
-\164\040\103\154\141\163\163\040\063\060\202\001\042\060\015\006
-\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017
-\000\060\202\001\012\002\202\001\001\000\275\165\223\360\142\042
-\157\044\256\340\172\166\254\175\275\331\044\325\270\267\374\315
-\360\102\340\353\170\210\126\136\233\232\124\035\115\014\212\366
-\323\317\160\364\122\265\330\223\004\343\106\206\161\101\112\053
-\360\052\054\125\003\326\110\303\340\071\070\355\362\134\074\077
-\104\274\223\075\141\253\116\315\015\276\360\040\047\130\016\104
-\177\004\032\207\245\327\226\024\066\220\320\111\173\241\165\373
-\032\153\163\261\370\316\251\011\054\362\123\325\303\024\104\270
-\206\245\366\213\053\071\332\243\063\124\331\372\162\032\367\042
-\025\034\210\221\153\177\146\345\303\152\200\260\044\363\337\206
-\105\210\375\031\177\165\207\037\037\261\033\012\163\044\133\271
-\145\340\054\124\310\140\323\146\027\077\341\314\124\063\163\221
-\002\072\246\177\173\166\071\242\037\226\266\070\256\265\310\223
-\164\035\236\271\264\345\140\235\057\126\321\340\353\136\133\114
-\022\160\014\154\104\040\253\021\330\364\031\366\322\234\122\067
-\347\372\266\302\061\073\112\324\024\231\255\307\032\365\135\137
-\372\007\270\174\015\037\326\203\036\263\002\003\001\000\001\243
-\102\060\100\060\017\006\003\125\035\023\001\001\377\004\005\060
-\003\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004
-\003\002\001\006\060\035\006\003\125\035\016\004\026\004\024\265
-\003\367\166\073\141\202\152\022\252\030\123\353\003\041\224\277
-\376\316\312\060\015\006\011\052\206\110\206\367\015\001\001\013
-\005\000\003\202\001\001\000\126\075\357\224\325\275\332\163\262
-\130\276\256\220\255\230\047\227\376\001\261\260\122\000\270\115
-\344\033\041\164\033\176\300\356\136\151\052\045\257\134\326\035
-\332\322\171\311\363\227\051\340\206\207\336\004\131\017\361\131
-\324\144\205\113\231\257\045\004\036\311\106\251\227\336\202\262
-\033\160\237\234\366\257\161\061\335\173\005\245\054\323\271\312
-\107\366\312\362\366\347\255\271\110\077\274\026\267\301\155\364
-\352\011\257\354\363\265\347\005\236\246\036\212\123\121\326\223
-\201\314\164\223\366\271\332\246\045\005\164\171\132\176\100\076
-\202\113\046\021\060\156\341\077\101\307\107\000\065\325\365\323
-\367\124\076\201\075\332\111\152\232\263\357\020\075\346\353\157
-\321\310\042\107\313\314\317\001\061\222\331\030\343\042\276\011
-\036\032\076\132\262\344\153\014\124\172\175\103\116\270\211\245
-\173\327\242\075\226\206\314\362\046\064\055\152\222\235\232\032
-\320\060\342\135\116\004\260\137\213\040\176\167\301\075\225\202
-\321\106\232\073\074\170\270\157\241\320\015\144\242\170\036\051
-\116\223\303\244\124\024\133
-END
-
-# Trust for "T-TeleSec GlobalRoot Class 3"
-# Issuer: CN=T-TeleSec GlobalRoot Class 3,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE
-# Serial Number: 1 (0x1)
-# Subject: CN=T-TeleSec GlobalRoot Class 3,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE
-# Not Valid Before: Wed Oct 01 10:29:56 2008
-# Not Valid After : Sat Oct 01 23:59:59 2033
-# Fingerprint (MD5): CA:FB:40:A8:4E:39:92:8A:1D:FE:8E:2F:C4:27:EA:EF
-# Fingerprint (SHA1): 55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "T-TeleSec GlobalRoot Class 3"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\125\246\162\076\313\362\354\315\303\043\164\160\031\235\052\276
-\021\343\201\321
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\312\373\100\250\116\071\222\212\035\376\216\057\304\047\352\357
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\202\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\053\060\051\006\003\125\004\012\014\042\124\055\123\171\163
-\164\145\155\163\040\105\156\164\145\162\160\162\151\163\145\040
-\123\145\162\166\151\143\145\163\040\107\155\142\110\061\037\060
-\035\006\003\125\004\013\014\026\124\055\123\171\163\164\145\155
-\163\040\124\162\165\163\164\040\103\145\156\164\145\162\061\045
-\060\043\006\003\125\004\003\014\034\124\055\124\145\154\145\123
-\145\143\040\107\154\157\142\141\154\122\157\157\164\040\103\154
-\141\163\163\040\063
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\001\001
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
-# Certificate "EE Certification Centre Root CA"
-#
-# Issuer: E=pki@sk.ee,CN=EE Certification Centre Root CA,O=AS Sertifitseerimiskeskus,C=EE
-# Serial Number:54:80:f9:a0:73:ed:3f:00:4c:ca:89:d8:e3:71:e6:4a
-# Subject: E=pki@sk.ee,CN=EE Certification Centre Root CA,O=AS Sertifitseerimiskeskus,C=EE
-# Not Valid Before: Sat Oct 30 10:10:30 2010
-# Not Valid After : Tue Dec 17 23:59:59 2030
-# Fingerprint (MD5): 43:5E:88:D4:7D:1A:4A:7E:FD:84:2E:52:EB:01:D4:6F
-# Fingerprint (SHA1): C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "EE Certification Centre Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\105\105\061
-\042\060\040\006\003\125\004\012\014\031\101\123\040\123\145\162
-\164\151\146\151\164\163\145\145\162\151\155\151\163\153\145\163
-\153\165\163\061\050\060\046\006\003\125\004\003\014\037\105\105
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\103
-\145\156\164\162\145\040\122\157\157\164\040\103\101\061\030\060
-\026\006\011\052\206\110\206\367\015\001\011\001\026\011\160\153
-\151\100\163\153\056\145\145
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\105\105\061
-\042\060\040\006\003\125\004\012\014\031\101\123\040\123\145\162
-\164\151\146\151\164\163\145\145\162\151\155\151\163\153\145\163
-\153\165\163\061\050\060\046\006\003\125\004\003\014\037\105\105
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\103
-\145\156\164\162\145\040\122\157\157\164\040\103\101\061\030\060
-\026\006\011\052\206\110\206\367\015\001\011\001\026\011\160\153
-\151\100\163\153\056\145\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\124\200\371\240\163\355\077\000\114\312\211\330\343\161
-\346\112
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\003\060\202\002\353\240\003\002\001\002\002\020\124
-\200\371\240\163\355\077\000\114\312\211\330\343\161\346\112\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\165
-\061\013\060\011\006\003\125\004\006\023\002\105\105\061\042\060
-\040\006\003\125\004\012\014\031\101\123\040\123\145\162\164\151
-\146\151\164\163\145\145\162\151\155\151\163\153\145\163\153\165
-\163\061\050\060\046\006\003\125\004\003\014\037\105\105\040\103
-\145\162\164\151\146\151\143\141\164\151\157\156\040\103\145\156
-\164\162\145\040\122\157\157\164\040\103\101\061\030\060\026\006
-\011\052\206\110\206\367\015\001\011\001\026\011\160\153\151\100
-\163\153\056\145\145\060\042\030\017\062\060\061\060\061\060\063
-\060\061\060\061\060\063\060\132\030\017\062\060\063\060\061\062
-\061\067\062\063\065\071\065\071\132\060\165\061\013\060\011\006
-\003\125\004\006\023\002\105\105\061\042\060\040\006\003\125\004
-\012\014\031\101\123\040\123\145\162\164\151\146\151\164\163\145
-\145\162\151\155\151\163\153\145\163\153\165\163\061\050\060\046
-\006\003\125\004\003\014\037\105\105\040\103\145\162\164\151\146
-\151\143\141\164\151\157\156\040\103\145\156\164\162\145\040\122
-\157\157\164\040\103\101\061\030\060\026\006\011\052\206\110\206
-\367\015\001\011\001\026\011\160\153\151\100\163\153\056\145\145
-\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001
-\000\310\040\300\354\340\305\113\253\007\170\225\363\104\356\373
-\013\014\377\164\216\141\273\261\142\352\043\330\253\241\145\062
-\172\353\216\027\117\226\330\012\173\221\242\143\154\307\214\114
-\056\171\277\251\005\374\151\134\225\215\142\371\271\160\355\303
-\121\175\320\223\346\154\353\060\113\341\274\175\277\122\233\316
-\156\173\145\362\070\261\300\242\062\357\142\262\150\340\141\123
-\301\066\225\377\354\224\272\066\256\234\034\247\062\017\345\174
-\264\306\157\164\375\173\030\350\254\127\355\006\040\113\062\060
-\130\133\375\315\250\346\241\374\160\274\216\222\163\333\227\247
-\174\041\256\075\301\365\110\207\154\047\275\237\045\164\201\125
-\260\367\165\366\075\244\144\153\326\117\347\316\100\255\017\335
-\062\323\274\212\022\123\230\311\211\373\020\035\115\176\315\176
-\037\126\015\041\160\205\366\040\203\037\366\272\037\004\217\352
-\167\210\065\304\377\352\116\241\213\115\077\143\033\104\303\104
-\324\045\166\312\267\215\327\036\112\146\144\315\134\305\234\203
-\341\302\010\210\232\354\116\243\361\076\034\054\331\154\035\241
-\113\002\003\001\000\001\243\201\212\060\201\207\060\017\006\003
-\125\035\023\001\001\377\004\005\060\003\001\001\377\060\016\006
-\003\125\035\017\001\001\377\004\004\003\002\001\006\060\035\006
-\003\125\035\016\004\026\004\024\022\362\132\076\352\126\034\277
-\315\006\254\361\361\045\311\251\113\324\024\231\060\105\006\003
-\125\035\045\004\076\060\074\006\010\053\006\001\005\005\007\003
-\002\006\010\053\006\001\005\005\007\003\001\006\010\053\006\001
-\005\005\007\003\003\006\010\053\006\001\005\005\007\003\004\006
-\010\053\006\001\005\005\007\003\010\006\010\053\006\001\005\005
-\007\003\011\060\015\006\011\052\206\110\206\367\015\001\001\005
-\005\000\003\202\001\001\000\173\366\344\300\015\252\031\107\267
-\115\127\243\376\255\273\261\152\325\017\236\333\344\143\305\216
-\241\120\126\223\226\270\070\300\044\042\146\274\123\024\141\225
-\277\320\307\052\226\071\077\175\050\263\020\100\041\152\304\257
-\260\122\167\030\341\226\330\126\135\343\335\066\136\035\247\120
-\124\240\305\052\344\252\214\224\212\117\235\065\377\166\244\006
-\023\221\242\242\175\000\104\077\125\323\202\074\032\325\133\274
-\126\114\042\056\106\103\212\044\100\055\363\022\270\073\160\032
-\244\226\271\032\257\207\101\032\152\030\015\006\117\307\076\156
-\271\051\115\015\111\211\021\207\062\133\346\113\004\310\344\134
-\346\164\163\224\135\026\230\023\225\376\373\333\261\104\345\072
-\160\254\067\153\346\263\063\162\050\311\263\127\240\366\002\026
-\210\006\013\266\246\113\040\050\324\336\075\213\255\067\005\123
-\164\376\156\314\274\103\027\161\136\371\305\314\032\251\141\356
-\367\166\014\363\162\364\162\255\317\162\002\066\007\107\317\357
-\031\120\211\140\314\351\044\225\017\302\313\035\362\157\166\220
-\307\314\165\301\226\305\235
-END
-
-# Trust for "EE Certification Centre Root CA"
-# Issuer: E=pki@sk.ee,CN=EE Certification Centre Root CA,O=AS Sertifitseerimiskeskus,C=EE
-# Serial Number:54:80:f9:a0:73:ed:3f:00:4c:ca:89:d8:e3:71:e6:4a
-# Subject: E=pki@sk.ee,CN=EE Certification Centre Root CA,O=AS Sertifitseerimiskeskus,C=EE
-# Not Valid Before: Sat Oct 30 10:10:30 2010
-# Not Valid After : Tue Dec 17 23:59:59 2030
-# Fingerprint (MD5): 43:5E:88:D4:7D:1A:4A:7E:FD:84:2E:52:EB:01:D4:6F
-# Fingerprint (SHA1): C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "EE Certification Centre Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\311\250\271\347\125\200\136\130\343\123\167\247\045\353\257\303
-\173\047\314\327
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\103\136\210\324\175\032\112\176\375\204\056\122\353\001\324\157
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\165\061\013\060\011\006\003\125\004\006\023\002\105\105\061
-\042\060\040\006\003\125\004\012\014\031\101\123\040\123\145\162
-\164\151\146\151\164\163\145\145\162\151\155\151\163\153\145\163
-\153\165\163\061\050\060\046\006\003\125\004\003\014\037\105\105
-\040\103\145\162\164\151\146\151\143\141\164\151\157\156\040\103
-\145\156\164\162\145\040\122\157\157\164\040\103\101\061\030\060
-\026\006\011\052\206\110\206\367\015\001\011\001\026\011\160\153
-\151\100\163\153\056\145\145
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\124\200\371\240\163\355\077\000\114\312\211\330\343\161
-\346\112
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-# Explicitly Distrust "TURKTRUST Mis-issued Intermediate CA 1", Bug 825022
-# Issuer: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,C=TR,CN=T..RKTRUST Elektronik Sunucu Sertifikas.. Hizmetleri
-# Serial Number: 2087 (0x827)
-# Subject: CN=*.EGO.GOV.TR,OU=EGO BILGI ISLEM,O=EGO,L=ANKARA,ST=ANKARA,C=TR
-# Not Valid Before: Mon Aug 08 07:07:51 2011
-# Not Valid After : Tue Jul 06 07:07:51 2021
-# Fingerprint (MD5): F8:F5:25:FF:0C:31:CF:85:E1:0C:86:17:C1:CE:1F:8E
-# Fingerprint (SHA1): C6:9F:28:C8:25:13:9E:65:A6:46:C4:34:AC:A5:A1:D2:00:29:5D:B1
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TURKTRUST Mis-issued Intermediate CA 1"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\254\061\075\060\073\006\003\125\004\003\014\064\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\165\156\165\143\165\040\123\145\162\164\151
-\146\151\153\141\163\304\261\040\110\151\172\155\145\164\154\145
-\162\151\061\013\060\011\006\003\125\004\006\023\002\124\122\061
-\136\060\134\006\003\125\004\012\014\125\124\303\234\122\113\124
-\122\125\123\124\040\102\151\154\147\151\040\304\260\154\145\164
-\151\305\237\151\155\040\166\145\040\102\151\154\151\305\237\151
-\155\040\107\303\274\166\145\156\154\151\304\237\151\040\110\151
-\172\155\145\164\154\145\162\151\040\101\056\305\236\056\040\050
-\143\051\040\113\141\163\304\261\155\040\040\062\060\060\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\010\047
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-# Explicitly Distrust "TURKTRUST Mis-issued Intermediate CA 2", Bug 825022
-# Issuer: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,C=TR,CN=T..RKTRUST Elektronik Sunucu Sertifikas.. Hizmetleri
-# Serial Number: 2148 (0x864)
-# Subject: E=ileti@kktcmerkezbankasi.org,CN=e-islem.kktcmerkezbankasi.org,O=KKTC Merkez Bankasi,L=Lefkosa,ST=Lefkosa,C=TR
-# Not Valid Before: Mon Aug 08 07:07:51 2011
-# Not Valid After : Thu Aug 05 07:07:51 2021
-# Fingerprint (MD5): BF:C3:EC:AD:0F:42:4F:B4:B5:38:DB:35:BF:AD:84:A2
-# Fingerprint (SHA1): F9:2B:E5:26:6C:C0:5D:B2:DC:0D:C3:F2:DC:74:E0:2D:EF:D9:49:CB
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TURKTRUST Mis-issued Intermediate CA 2"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\254\061\075\060\073\006\003\125\004\003\014\064\124\303
-\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162\157
-\156\151\153\040\123\165\156\165\143\165\040\123\145\162\164\151
-\146\151\153\141\163\304\261\040\110\151\172\155\145\164\154\145
-\162\151\061\013\060\011\006\003\125\004\006\023\002\124\122\061
-\136\060\134\006\003\125\004\012\014\125\124\303\234\122\113\124
-\122\125\123\124\040\102\151\154\147\151\040\304\260\154\145\164
-\151\305\237\151\155\040\166\145\040\102\151\154\151\305\237\151
-\155\040\107\303\274\166\145\156\154\151\304\237\151\040\110\151
-\172\155\145\164\154\145\162\151\040\101\056\305\236\056\040\050
-\143\051\040\113\141\163\304\261\155\040\040\062\060\060\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\002\010\144
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
diff --git a/security/nss/lib/ckfw/builtins/ckbiver.c b/security/nss/lib/ckfw/builtins/ckbiver.c
deleted file mode 100644
index c8ea7a9c3..000000000
--- a/security/nss/lib/ckfw/builtins/ckbiver.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Library identity and versioning */
-
-#include "nssckbi.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_builtins_rcsid[] = "$Header: NSS Builtin Trusted Root CAs "
- NSS_BUILTINS_LIBRARY_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_builtins_sccsid[] = "@(#)NSS Builtin Trusted Root CAs "
- NSS_BUILTINS_LIBRARY_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/ckfw/builtins/config.mk b/security/nss/lib/ckfw/builtins/config.mk
deleted file mode 100644
index de256538a..000000000
--- a/security/nss/lib/ckfw/builtins/config.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-#
-# Override TARGETS variable so that only shared libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(SHARED_LIBRARY)
-LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
- SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
- RES = $(OBJDIR)/$(LIBRARY_NAME).res
- RESNAME = $(LIBRARY_NAME).rc
-endif
-
-ifdef BUILD_IDG
- DEFINES += -DNSSDEBUG
-endif
-
-# Needed for compilation of $(OBJDIR)/certdata.c
-INCLUDES += -I.
-
-#
-# To create a loadable module on Darwin, we must use -bundle.
-#
-ifeq ($(OS_TARGET),Darwin)
-ifndef USE_64
-DSO_LDOPTS = -bundle
-endif
-endif
-
diff --git a/security/nss/lib/ckfw/builtins/constants.c b/security/nss/lib/ckfw/builtins/constants.c
deleted file mode 100644
index 3e7482562..000000000
--- a/security/nss/lib/ckfw/builtins/constants.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * builtins/constants.c
- *
- * Identification and other constants, all collected here in one place.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKBI_H
-#include "nssckbi.h"
-#endif /* NSSCKBI_H */
-
-const CK_VERSION
-nss_builtins_CryptokiVersion = {
- NSS_BUILTINS_CRYPTOKI_VERSION_MAJOR,
- NSS_BUILTINS_CRYPTOKI_VERSION_MINOR };
-
-const CK_VERSION
-nss_builtins_LibraryVersion = {
- NSS_BUILTINS_LIBRARY_VERSION_MAJOR,
- NSS_BUILTINS_LIBRARY_VERSION_MINOR};
-
-const CK_VERSION
-nss_builtins_HardwareVersion = {
- NSS_BUILTINS_HARDWARE_VERSION_MAJOR,
- NSS_BUILTINS_HARDWARE_VERSION_MINOR };
-
-const CK_VERSION
-nss_builtins_FirmwareVersion = {
- NSS_BUILTINS_FIRMWARE_VERSION_MAJOR,
- NSS_BUILTINS_FIRMWARE_VERSION_MINOR };
-
-const NSSUTF8
-nss_builtins_ManufacturerID[] = { "Mozilla Foundation" };
-
-const NSSUTF8
-nss_builtins_LibraryDescription[] = { "NSS Builtin Object Cryptoki Module" };
-
-const NSSUTF8
-nss_builtins_SlotDescription[] = { "NSS Builtin Objects" };
-
-const NSSUTF8
-nss_builtins_TokenLabel[] = { "Builtin Object Token" };
-
-const NSSUTF8
-nss_builtins_TokenModel[] = { "1" };
-
-/* should this be e.g. the certdata.txt RCS revision number? */
-const NSSUTF8
-nss_builtins_TokenSerialNumber[] = { "1" };
-
diff --git a/security/nss/lib/ckfw/builtins/manifest.mn b/security/nss/lib/ckfw/builtins/manifest.mn
deleted file mode 100644
index 161b20b1d..000000000
--- a/security/nss/lib/ckfw/builtins/manifest.mn
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-CORE_DEPTH = ../../../..
-
-MODULE = nss
-MAPFILE = $(OBJDIR)/nssckbi.def
-
-EXPORTS = \
- nssckbi.h \
- $(NULL)
-
-CSRCS = \
- anchor.c \
- constants.c \
- bfind.c \
- binst.c \
- bobject.c \
- bsession.c \
- bslot.c \
- btoken.c \
- certdata.c \
- ckbiver.c \
- $(NULL)
-
-REQUIRES = nspr
-
-LIBRARY_NAME = nssckbi
diff --git a/security/nss/lib/ckfw/builtins/nssckbi.def b/security/nss/lib/ckfw/builtins/nssckbi.def
deleted file mode 100644
index 8692d4cb6..000000000
--- a/security/nss/lib/ckfw/builtins/nssckbi.def
+++ /dev/null
@@ -1,26 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+
-;+NSS_3.1 { # NSS 3.1 release
-;+ global:
-LIBRARY nssckbi ;-
-EXPORTS ;-
-C_GetFunctionList;
-;+ local:
-;+*;
-;+};
diff --git a/security/nss/lib/ckfw/builtins/nssckbi.h b/security/nss/lib/ckfw/builtins/nssckbi.h
deleted file mode 100644
index 9185e2803..000000000
--- a/security/nss/lib/ckfw/builtins/nssckbi.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSCKBI_H
-#define NSSCKBI_H
-
-/*
- * NSS BUILTINS Version numbers.
- *
- * These are the version numbers for the builtins module packaged with
- * this release on NSS. To determine the version numbers of the builtin
- * module you are using, use the appropriate PKCS #11 calls.
- *
- * These version numbers detail changes to the PKCS #11 interface. They map
- * to the PKCS #11 spec versions.
- */
-#define NSS_BUILTINS_CRYPTOKI_VERSION_MAJOR 2
-#define NSS_BUILTINS_CRYPTOKI_VERSION_MINOR 20
-
-/* These version numbers detail the changes
- * to the list of trusted certificates.
- *
- * The NSS_BUILTINS_LIBRARY_VERSION_MINOR macro needs to be bumped
- * for each NSS minor release AND whenever we change the list of
- * trusted certificates. 10 minor versions are allocated for each
- * NSS 3.x branch as follows, allowing us to change the list of
- * trusted certificates up to 9 times on each branch.
- * - NSS 3.5 branch: 3-9
- * - NSS 3.6 branch: 10-19
- * - NSS 3.7 branch: 20-29
- * - NSS 3.8 branch: 30-39
- * - NSS 3.9 branch: 40-49
- * - NSS 3.10 branch: 50-59
- * - NSS 3.11 branch: 60-69
- * ...
- * - NSS 3.12 branch: 70-89
- * - NSS 3.13 branch: 90-99
- * - NSS 3.14 branch: 100-109
- * ...
- * - NSS 3.29 branch: 250-255
- *
- * NSS_BUILTINS_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear
- * whether we may use its full range (0-255) or only 0-99 because
- * of the comment in the CK_VERSION type definition.
- */
-#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 1
-#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 93
-#define NSS_BUILTINS_LIBRARY_VERSION "1.93"
-
-/* These version numbers detail the semantic changes to the ckfw engine. */
-#define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1
-#define NSS_BUILTINS_HARDWARE_VERSION_MINOR 0
-
-/* These version numbers detail the semantic changes to ckbi itself
- * (new PKCS #11 objects), etc. */
-#define NSS_BUILTINS_FIRMWARE_VERSION_MAJOR 1
-#define NSS_BUILTINS_FIRMWARE_VERSION_MINOR 0
-
-#endif /* NSSCKBI_H */
diff --git a/security/nss/lib/ckfw/builtins/nssckbi.rc b/security/nss/lib/ckfw/builtins/nssckbi.rc
deleted file mode 100644
index 315149beb..000000000
--- a/security/nss/lib/ckfw/builtins/nssckbi.rc
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nssckbi.h"
-#include <winver.h>
-
-#define MY_LIBNAME "nssckbi"
-#define MY_FILEDESCRIPTION "NSS Builtin Trusted Root CAs"
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if NSS_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION NSS_BUILTINS_LIBRARY_VERSION_MAJOR,NSS_BUILTINS_LIBRARY_VERSION_MINOR,0,0
- PRODUCTVERSION NSS_BUILTINS_LIBRARY_VERSION_MAJOR,NSS_BUILTINS_LIBRARY_VERSION_MINOR,0,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Mozilla Foundation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", NSS_BUILTINS_LIBRARY_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", NSS_BUILTINS_LIBRARY_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/ckfw/capi/Makefile b/security/nss/lib/ckfw/capi/Makefile
deleted file mode 100644
index 71ff6ae86..000000000
--- a/security/nss/lib/ckfw/capi/Makefile
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-include manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
-
-EXTRA_LIBS = \
- $(DIST)/lib/$(LIB_PREFIX)nssckfw.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
- $(NULL)
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-ifdef NS_USE_GCC
-EXTRA_LIBS += \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- -lcrypt32 \
- -ladvapi32 \
- -lrpcrt4 \
- $(NULL)
-else
-EXTRA_SHARED_LIBS += \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- crypt32.lib \
- advapi32.lib \
- rpcrt4.lib \
- $(NULL)
-endif # NS_USE_GCC
-else
-
-EXTRA_LIBS += \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-endif
-
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-# Generate certdata.c.
-generate:
- $(PERL) certdata.perl < certdata.txt
-
-# This'll need some help from a build person.
-
-
-ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.1)
-DSO_LDOPTS = -bM:SRE -bh:4 -bnoentry
-EXTRA_DSO_LDOPTS = -lc
-MKSHLIB = xlC $(DSO_LDOPTS)
-
-$(SHARED_LIBRARY): $(OBJS)
- @$(MAKE_OBJDIR)
- rm -f $@
- $(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DSO_LDOPTS)
- chmod +x $@
-
-endif
-
-ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.2)
-LD += -G
-endif
-
-
diff --git a/security/nss/lib/ckfw/capi/README b/security/nss/lib/ckfw/capi/README
deleted file mode 100644
index 9fc5720a9..000000000
--- a/security/nss/lib/ckfw/capi/README
+++ /dev/null
@@ -1,7 +0,0 @@
-This Cryptoki module provides acces to certs and keys stored in
-Microsofts CAPI certificate store.
-
-It does not import or export CA Root trust from the CAPI.
-It does not import or export CRLs from the CAPI.
-It does not handle S/MIME objects (pkcs #7 in capi terms?).
-It does not yet handle it's own PIN. (CAPI does all the pin prompting).
diff --git a/security/nss/lib/ckfw/capi/anchor.c b/security/nss/lib/ckfw/capi/anchor.c
deleted file mode 100644
index 42d70ef4c..000000000
--- a/security/nss/lib/ckfw/capi/anchor.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * capi/canchor.c
- *
- * This file "anchors" the actual cryptoki entry points in this module's
- * shared library, which is required for dynamic loading. See the
- * comments in nssck.api for more information.
- */
-
-#include "ckcapi.h"
-
-#define MODULE_NAME ckcapi
-#define INSTANCE_NAME (NSSCKMDInstance *)&nss_ckcapi_mdInstance
-#include "nssck.api"
diff --git a/security/nss/lib/ckfw/capi/cfind.c b/security/nss/lib/ckfw/capi/cfind.c
deleted file mode 100644
index 87c993679..000000000
--- a/security/nss/lib/ckfw/capi/cfind.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef CKCAPI_H
-#include "ckcapi.h"
-#endif /* CKCAPI_H */
-
-/*
- * ckcapi/cfind.c
- *
- * This file implements the NSSCKMDFindObjects object for the
- * "capi" cryptoki module.
- */
-
-struct ckcapiFOStr {
- NSSArena *arena;
- CK_ULONG n;
- CK_ULONG i;
- ckcapiInternalObject **objs;
-};
-
-static void
-ckcapi_mdFindObjects_Final
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- struct ckcapiFOStr *fo = (struct ckcapiFOStr *)mdFindObjects->etc;
- NSSArena *arena = fo->arena;
- PRUint32 i;
-
- /* walk down an free the unused 'objs' */
- for (i=fo->i; i < fo->n ; i++) {
- nss_ckcapi_DestroyInternalObject(fo->objs[i]);
- }
-
- nss_ZFreeIf(fo->objs);
- nss_ZFreeIf(fo);
- nss_ZFreeIf(mdFindObjects);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
-
- return;
-}
-
-static NSSCKMDObject *
-ckcapi_mdFindObjects_Next
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
-{
- struct ckcapiFOStr *fo = (struct ckcapiFOStr *)mdFindObjects->etc;
- ckcapiInternalObject *io;
-
- if( fo->i == fo->n ) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
-
- io = fo->objs[ fo->i ];
- fo->i++;
-
- return nss_ckcapi_CreateMDObject(arena, io, pError);
-}
-
-static CK_BBOOL
-ckcapi_attrmatch
-(
- CK_ATTRIBUTE_PTR a,
- ckcapiInternalObject *o
-)
-{
- PRBool prb;
- const NSSItem *b;
-
- b = nss_ckcapi_FetchAttribute(o, a->type);
- if (b == NULL) {
- return CK_FALSE;
- }
-
- if( a->ulValueLen != b->size ) {
- /* match a decoded serial number */
- if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
- unsigned int len;
- unsigned char *data;
-
- data = nss_ckcapi_DERUnwrap(b->data, b->size, &len, NULL);
- if ((len == a->ulValueLen) &&
- nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
- return CK_TRUE;
- }
- }
- return CK_FALSE;
- }
-
- prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
-
- if( PR_TRUE == prb ) {
- return CK_TRUE;
- } else {
- return CK_FALSE;
- }
-}
-
-
-static CK_BBOOL
-ckcapi_match
-(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject *o
-)
-{
- CK_ULONG i;
-
- for( i = 0; i < ulAttributeCount; i++ ) {
- if (CK_FALSE == ckcapi_attrmatch(&pTemplate[i], o)) {
- return CK_FALSE;
- }
- }
-
- /* Every attribute passed */
- return CK_TRUE;
-}
-
-#define CKAPI_ITEM_CHUNK 20
-
-#define PUT_Object(obj,err) \
- { \
- if (count >= size) { \
- *listp = *listp ? \
- nss_ZREALLOCARRAY(*listp, ckcapiInternalObject *, \
- (size+CKAPI_ITEM_CHUNK) ) : \
- nss_ZNEWARRAY(NULL, ckcapiInternalObject *, \
- (size+CKAPI_ITEM_CHUNK) ) ; \
- if ((ckcapiInternalObject **)NULL == *listp) { \
- err = CKR_HOST_MEMORY; \
- goto loser; \
- } \
- size += CKAPI_ITEM_CHUNK; \
- } \
- (*listp)[ count ] = (obj); \
- count++; \
- }
-
-
-/*
- * pass parameters back through the callback.
- */
-typedef struct BareCollectParamsStr {
- CK_OBJECT_CLASS objClass;
- CK_ATTRIBUTE_PTR pTemplate;
- CK_ULONG ulAttributeCount;
- ckcapiInternalObject ***listp;
- PRUint32 size;
- PRUint32 count;
-} BareCollectParams;
-
-/* collect_bare's callback. Called for each object that
- * supposedly has a PROVINDER_INFO property */
-static BOOL WINAPI
-doBareCollect
-(
- const CRYPT_HASH_BLOB *msKeyID,
- DWORD flags,
- void *reserved,
- void *args,
- DWORD cProp,
- DWORD *propID,
- void **propData,
- DWORD *propSize
-)
-{
- BareCollectParams *bcp = (BareCollectParams *) args;
- PRUint32 size = bcp->size;
- PRUint32 count = bcp->count;
- ckcapiInternalObject ***listp = bcp->listp;
- ckcapiInternalObject *io = NULL;
- DWORD i;
- CRYPT_KEY_PROV_INFO *keyProvInfo = NULL;
- void *idData;
- CK_RV error;
-
- /* make sure there is a Key Provider Info property */
- for (i=0; i < cProp; i++) {
- if (CERT_KEY_PROV_INFO_PROP_ID == propID[i]) {
- keyProvInfo = (CRYPT_KEY_PROV_INFO *)propData[i];
- break;
- }
- }
- if ((CRYPT_KEY_PROV_INFO *)NULL == keyProvInfo) {
- return 1;
- }
-
- /* copy the key ID */
- idData = nss_ZNEWARRAY(NULL, char, msKeyID->cbData);
- if ((void *)NULL == idData) {
- goto loser;
- }
- nsslibc_memcpy(idData, msKeyID->pbData, msKeyID->cbData);
-
- /* build a bare internal object */
- io = nss_ZNEW(NULL, ckcapiInternalObject);
- if ((ckcapiInternalObject *)NULL == io) {
- goto loser;
- }
- io->type = ckcapiBareKey;
- io->objClass = bcp->objClass;
- io->u.key.provInfo = *keyProvInfo;
- io->u.key.provInfo.pwszContainerName =
- nss_ckcapi_WideDup(keyProvInfo->pwszContainerName);
- io->u.key.provInfo.pwszProvName =
- nss_ckcapi_WideDup(keyProvInfo->pwszProvName);
- io->u.key.provName = nss_ckcapi_WideToUTF8(keyProvInfo->pwszProvName);
- io->u.key.containerName =
- nss_ckcapi_WideToUTF8(keyProvInfo->pwszContainerName);
- io->u.key.hProv = 0;
- io->idData = idData;
- io->id.data = idData;
- io->id.size = msKeyID->cbData;
- idData = NULL;
-
- /* see if it matches */
- if( CK_FALSE == ckcapi_match(bcp->pTemplate, bcp->ulAttributeCount, io) ) {
- goto loser;
- }
- PUT_Object(io, error);
- bcp->size = size;
- bcp->count = count;
- return 1;
-
-loser:
- if (io) {
- nss_ckcapi_DestroyInternalObject(io);
- }
- nss_ZFreeIf(idData);
- return 1;
-}
-
-/*
- * collect the bare keys running around
- */
-static PRUint32
-collect_bare(
- CK_OBJECT_CLASS objClass,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError
-)
-{
- BOOL rc;
- BareCollectParams bareCollectParams;
-
- bareCollectParams.objClass = objClass;
- bareCollectParams.pTemplate = pTemplate;
- bareCollectParams.ulAttributeCount = ulAttributeCount;
- bareCollectParams.listp = listp;
- bareCollectParams.size = *sizep;
- bareCollectParams.count = count;
-
- rc = CryptEnumKeyIdentifierProperties(NULL, CERT_KEY_PROV_INFO_PROP_ID, 0,
- NULL, NULL, &bareCollectParams, doBareCollect);
-
- *sizep = bareCollectParams.size;
- return bareCollectParams.count;
-}
-
-/* find all the certs that represent the appropriate object (cert, priv key, or
- * pub key) in the cert store.
- */
-static PRUint32
-collect_class(
- CK_OBJECT_CLASS objClass,
- LPCSTR storeStr,
- PRBool hasID,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError
-)
-{
- PRUint32 size = *sizep;
- ckcapiInternalObject *next = NULL;
- HCERTSTORE hStore;
- PCCERT_CONTEXT certContext = NULL;
- PRBool isKey =
- (objClass == CKO_PUBLIC_KEY) | (objClass == CKO_PRIVATE_KEY);
-
- hStore = CertOpenSystemStore((HCRYPTPROV)NULL, storeStr);
- if (NULL == hStore) {
- return count; /* none found does not imply an error */
- }
-
- /* FUTURE: use CertFindCertificateInStore to filter better -- so we don't
- * have to enumerate all the certificates */
- while ((PCERT_CONTEXT) NULL !=
- (certContext= CertEnumCertificatesInStore(hStore, certContext))) {
- /* first filter out non user certs if we are looking for keys */
- if (isKey) {
- /* make sure there is a Key Provider Info property */
- CRYPT_KEY_PROV_INFO *keyProvInfo;
- DWORD size = 0;
- BOOL rv;
- rv =CertGetCertificateContextProperty(certContext,
- CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
- if (!rv) {
- int reason = GetLastError();
- /* we only care if it exists, we don't really need to fetch it yet */
- if (reason == CRYPT_E_NOT_FOUND) {
- continue;
- }
- }
- /* filter out the non-microsoft providers */
- keyProvInfo = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
- if (keyProvInfo) {
- rv =CertGetCertificateContextProperty(certContext,
- CERT_KEY_PROV_INFO_PROP_ID, keyProvInfo, &size);
- if (rv) {
- char *provName = nss_ckcapi_WideToUTF8(keyProvInfo->pwszProvName);
- nss_ZFreeIf(keyProvInfo);
-
- if (provName &&
- (strncmp(provName, "Microsoft", sizeof("Microsoft")-1) != 0)) {
- continue;
- }
- } else {
- int reason = GetLastError();
- /* we only care if it exists, we don't really need to fetch it yet */
- nss_ZFreeIf(keyProvInfo);
- if (reason == CRYPT_E_NOT_FOUND) {
- continue;
- }
-
- }
- }
- }
-
- if ((ckcapiInternalObject *)NULL == next) {
- next = nss_ZNEW(NULL, ckcapiInternalObject);
- if ((ckcapiInternalObject *)NULL == next) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- }
- next->type = ckcapiCert;
- next->objClass = objClass;
- next->u.cert.certContext = certContext;
- next->u.cert.hasID = hasID;
- next->u.cert.certStore = storeStr;
- if( CK_TRUE == ckcapi_match(pTemplate, ulAttributeCount, next) ) {
- /* clear cached values that may be dependent on our old certContext */
- memset(&next->u.cert, 0, sizeof(next->u.cert));
- /* get a 'permanent' context */
- next->u.cert.certContext = CertDuplicateCertificateContext(certContext);
- next->objClass = objClass;
- next->u.cert.certContext = certContext;
- next->u.cert.hasID = hasID;
- next->u.cert.certStore = storeStr;
- PUT_Object(next, *pError);
- next = NULL; /* need to allocate a new one now */
- } else {
- /* don't cache the values we just loaded */
- memset(&next->u.cert, 0, sizeof(next->u.cert));
- }
- }
-loser:
- CertCloseStore(hStore, 0);
- nss_ZFreeIf(next);
- *sizep = size;
- return count;
-}
-
-NSS_IMPLEMENT PRUint32
-nss_ckcapi_collect_all_certs(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError
-)
-{
- count = collect_class(CKO_CERTIFICATE, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- /*count = collect_class(CKO_CERTIFICATE, "AddressBook", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError); */
- count = collect_class(CKO_CERTIFICATE, "CA", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- count = collect_class(CKO_CERTIFICATE, "Root", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- count = collect_class(CKO_CERTIFICATE, "Trust", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- count = collect_class(CKO_CERTIFICATE, "TrustedPeople", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- count = collect_class(CKO_CERTIFICATE, "AuthRoot", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- return count;
-}
-
-CK_OBJECT_CLASS
-ckcapi_GetObjectClass(CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount)
-{
- CK_ULONG i;
-
- for (i=0; i < ulAttributeCount; i++)
- {
- if (pTemplate[i].type == CKA_CLASS) {
- return *(CK_OBJECT_CLASS *) pTemplate[i].pValue;
- }
- }
- /* need to return a value that says 'fetch them all' */
- return CK_INVALID_HANDLE;
-}
-
-static PRUint32
-collect_objects(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- CK_RV *pError
-)
-{
- PRUint32 i;
- PRUint32 count = 0;
- PRUint32 size = 0;
- CK_OBJECT_CLASS objClass;
-
- /*
- * first handle the static build in objects (if any)
- */
- for( i = 0; i < nss_ckcapi_nObjects; i++ ) {
- ckcapiInternalObject *o = (ckcapiInternalObject *)&nss_ckcapi_data[i];
-
- if( CK_TRUE == ckcapi_match(pTemplate, ulAttributeCount, o) ) {
- PUT_Object(o, *pError);
- }
- }
-
- /*
- * now handle the various object types
- */
- objClass = ckcapi_GetObjectClass(pTemplate, ulAttributeCount);
- *pError = CKR_OK;
- switch (objClass) {
- case CKO_CERTIFICATE:
- count = nss_ckcapi_collect_all_certs(pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- case CKO_PUBLIC_KEY:
- count = collect_class(objClass, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, &size, count, pError);
- count = collect_bare(objClass, pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- case CKO_PRIVATE_KEY:
- count = collect_class(objClass, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, &size, count, pError);
- count = collect_bare(objClass, pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- /* all of them */
- case CK_INVALID_HANDLE:
- count = nss_ckcapi_collect_all_certs(pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- count = collect_class(CKO_PUBLIC_KEY, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, &size, count, pError);
- count = collect_bare(CKO_PUBLIC_KEY, pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- count = collect_class(CKO_PRIVATE_KEY, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, &size, count, pError);
- count = collect_bare(CKO_PRIVATE_KEY, pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- default:
- goto done; /* no other object types we understand in this module */
- }
- if (CKR_OK != *pError) {
- goto loser;
- }
-
-
-done:
- return count;
-loser:
- nss_ZFreeIf(*listp);
- return 0;
-}
-
-
-
-NSS_IMPLEMENT NSSCKMDFindObjects *
-nss_ckcapi_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- /* This could be made more efficient. I'm rather rushed. */
- NSSArena *arena;
- NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
- struct ckcapiFOStr *fo = (struct ckcapiFOStr *)NULL;
- ckcapiInternalObject **temp = (ckcapiInternalObject **)NULL;
-
- arena = NSSArena_Create();
- if( (NSSArena *)NULL == arena ) {
- goto loser;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDFindObjects);
- if( (NSSCKMDFindObjects *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fo = nss_ZNEW(arena, struct ckcapiFOStr);
- if( (struct ckcapiFOStr *)NULL == fo ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fo->arena = arena;
- /* fo->n and fo->i are already zero */
-
- rv->etc = (void *)fo;
- rv->Final = ckcapi_mdFindObjects_Final;
- rv->Next = ckcapi_mdFindObjects_Next;
- rv->null = (void *)NULL;
-
- fo->n = collect_objects(pTemplate, ulAttributeCount, &temp, pError);
- if (*pError != CKR_OK) {
- goto loser;
- }
-
- fo->objs = nss_ZNEWARRAY(arena, ckcapiInternalObject *, fo->n);
- if( (ckcapiInternalObject **)NULL == fo->objs ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- (void)nsslibc_memcpy(fo->objs, temp, sizeof(ckcapiInternalObject *) * fo->n);
- nss_ZFreeIf(temp);
- temp = (ckcapiInternalObject **)NULL;
-
- return rv;
-
- loser:
- nss_ZFreeIf(temp);
- nss_ZFreeIf(fo);
- nss_ZFreeIf(rv);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
- return (NSSCKMDFindObjects *)NULL;
-}
-
diff --git a/security/nss/lib/ckfw/capi/cinst.c b/security/nss/lib/ckfw/capi/cinst.c
deleted file mode 100644
index 61db850b0..000000000
--- a/security/nss/lib/ckfw/capi/cinst.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckcapi.h"
-
-/*
- * ckcapi/cinstance.c
- *
- * This file implements the NSSCKMDInstance object for the
- * "capi" cryptoki module.
- */
-
-/*
- * NSSCKMDInstance methods
- */
-
-static CK_ULONG
-ckcapi_mdInstance_GetNSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (CK_ULONG)1;
-}
-
-static CK_VERSION
-ckcapi_mdInstance_GetCryptokiVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckcapi_CryptokiVersion;
-}
-
-static NSSUTF8 *
-ckcapi_mdInstance_GetManufacturerID
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
-}
-
-static NSSUTF8 *
-ckcapi_mdInstance_GetLibraryDescription
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckcapi_LibraryDescription;
-}
-
-static CK_VERSION
-ckcapi_mdInstance_GetLibraryVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckcapi_LibraryVersion;
-}
-
-static CK_RV
-ckcapi_mdInstance_GetSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[]
-)
-{
- slots[0] = (NSSCKMDSlot *)&nss_ckcapi_mdSlot;
- return CKR_OK;
-}
-
-static CK_BBOOL
-ckcapi_mdInstance_ModuleHandlesSessionObjects
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- /* we don't want to allow any session object creation, at least
- * until we can investigate whether or not we can use those objects
- */
- return CK_TRUE;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDInstance
-nss_ckcapi_mdInstance = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Finalize */
- ckcapi_mdInstance_GetNSlots,
- ckcapi_mdInstance_GetCryptokiVersion,
- ckcapi_mdInstance_GetManufacturerID,
- ckcapi_mdInstance_GetLibraryDescription,
- ckcapi_mdInstance_GetLibraryVersion,
- ckcapi_mdInstance_ModuleHandlesSessionObjects,
- /*NULL, /* HandleSessionObjects */
- ckcapi_mdInstance_GetSlots,
- NULL, /* WaitForSlotEvent */
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/capi/ckcapi.h b/security/nss/lib/ckfw/capi/ckcapi.h
deleted file mode 100644
index 2602165d5..000000000
--- a/security/nss/lib/ckfw/capi/ckcapi.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CKCAPI_H
-#define CKCAPI_H 1
-
-#ifdef DEBUG
-static const char CKCAPI_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "nssckmdt.h"
-#include "nssckfw.h"
-
-/*
- * I'm including this for access to the arena functions.
- * Looks like we should publish that API.
- */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-/*
- * This is where the Netscape extensions live, at least for now.
- */
-#ifndef CKT_H
-#include "ckt.h"
-#endif /* CKT_H */
-
-#include "wtypes.h"
-#include "wincrypt.h"
-
-/*
- * statically defined raw objects. Allows us to data description objects
- * to this PKCS #11 module.
- */
-struct ckcapiRawObjectStr {
- CK_ULONG n;
- const CK_ATTRIBUTE_TYPE *types;
- const NSSItem *items;
-};
-typedef struct ckcapiRawObjectStr ckcapiRawObject;
-
-
-/*
- * common values needed for both bare keys and cert referenced keys.
- */
-struct ckcapiKeyParamsStr {
- NSSItem modulus;
- NSSItem exponent;
- NSSItem privateExponent;
- NSSItem prime1;
- NSSItem prime2;
- NSSItem exponent1;
- NSSItem exponent2;
- NSSItem coefficient;
- unsigned char publicExponentData[sizeof(CK_ULONG)];
- void *privateKey;
- void *pubKey;
-};
-typedef struct ckcapiKeyParamsStr ckcapiKeyParams;
-
-/*
- * Key objects. Handles bare keys which do not yet have certs associated
- * with them. These are usually short lived, but may exist for several days
- * while the CA is issuing the certificate.
- */
-struct ckcapiKeyObjectStr {
- CRYPT_KEY_PROV_INFO provInfo;
- char *provName;
- char *containerName;
- HCRYPTPROV hProv;
- ckcapiKeyParams key;
-};
-typedef struct ckcapiKeyObjectStr ckcapiKeyObject;
-
-/*
- * Certificate and certificate referenced keys.
- */
-struct ckcapiCertObjectStr {
- PCCERT_CONTEXT certContext;
- PRBool hasID;
- const char *certStore;
- NSSItem label;
- NSSItem subject;
- NSSItem issuer;
- NSSItem serial;
- NSSItem derCert;
- ckcapiKeyParams key;
- unsigned char *labelData;
- /* static data: to do, make this dynamic like labelData */
- unsigned char derSerial[128];
-};
-typedef struct ckcapiCertObjectStr ckcapiCertObject;
-
-typedef enum {
- ckcapiRaw,
- ckcapiCert,
- ckcapiBareKey
-} ckcapiObjectType;
-
-/*
- * all the various types of objects are abstracted away in cobject and
- * cfind as ckcapiInternalObjects.
- */
-struct ckcapiInternalObjectStr {
- ckcapiObjectType type;
- union {
- ckcapiRawObject raw;
- ckcapiCertObject cert;
- ckcapiKeyObject key;
- } u;
- CK_OBJECT_CLASS objClass;
- NSSItem hashKey;
- NSSItem id;
- void *idData;
- unsigned char hashKeyData[128];
- NSSCKMDObject mdObject;
-};
-typedef struct ckcapiInternalObjectStr ckcapiInternalObject;
-
-/* our raw object data array */
-NSS_EXTERN_DATA ckcapiInternalObject nss_ckcapi_data[];
-NSS_EXTERN_DATA const PRUint32 nss_ckcapi_nObjects;
-
-NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_CryptokiVersion;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_ManufacturerID;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_LibraryDescription;
-NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_LibraryVersion;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_SlotDescription;
-NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_HardwareVersion;
-NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_FirmwareVersion;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_TokenLabel;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_TokenModel;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckcapi_TokenSerialNumber;
-
-NSS_EXTERN_DATA const NSSCKMDInstance nss_ckcapi_mdInstance;
-NSS_EXTERN_DATA const NSSCKMDSlot nss_ckcapi_mdSlot;
-NSS_EXTERN_DATA const NSSCKMDToken nss_ckcapi_mdToken;
-NSS_EXTERN_DATA const NSSCKMDMechanism nss_ckcapi_mdMechanismRSA;
-
-NSS_EXTERN NSSCKMDSession *
-nss_ckcapi_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDFindObjects *
-nss_ckcapi_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-/*
- * Object Utilities
- */
-NSS_EXTERN NSSCKMDObject *
-nss_ckcapi_CreateMDObject
-(
- NSSArena *arena,
- ckcapiInternalObject *io,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDObject *
-nss_ckcapi_CreateObject
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-NSS_EXTERN const NSSItem *
-nss_ckcapi_FetchAttribute
-(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type
-);
-
-NSS_EXTERN void
-nss_ckcapi_DestroyInternalObject
-(
- ckcapiInternalObject *io
-);
-
-NSS_EXTERN CK_RV
-nss_ckcapi_FetchKeyContainer
-(
- ckcapiInternalObject *iKey,
- HCRYPTPROV *hProv,
- DWORD *keySpec,
- HCRYPTKEY *hKey
-);
-
-/*
- * generic utilities
- */
-
-/*
- * So everyone else in the worlds stores their bignum data MSB first, but not
- * Microsoft, we need to byte swap everything coming into and out of CAPI.
- */
-void
-ckcapi_ReverseData
-(
- NSSItem *item
-);
-
-/*
- * unwrap a single DER value
- */
-unsigned char *
-nss_ckcapi_DERUnwrap
-(
- unsigned char *src,
- unsigned int size,
- unsigned int *outSize,
- unsigned char **next
-);
-
-/*
- * Return the size in bytes of a wide string
- */
-int
-nss_ckcapi_WideSize
-(
- LPCWSTR wide
-);
-
-/*
- * Covert a Unicode wide character string to a UTF8 string
- */
-char *
-nss_ckcapi_WideToUTF8
-(
- LPCWSTR wide
-);
-
-/*
- * Return a Wide String duplicated with nss allocated memory.
- */
-LPWSTR
-nss_ckcapi_WideDup
-(
- LPCWSTR wide
-);
-
-/*
- * Covert a UTF8 string to Unicode wide character
- */
-LPWSTR
-nss_ckcapi_UTF8ToWide
-(
- char *buf
-);
-
-
-NSS_EXTERN PRUint32
-nss_ckcapi_collect_all_certs(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError
-);
-
-#define NSS_CKCAPI_ARRAY_SIZE(x) ((sizeof (x))/(sizeof ((x)[0])))
-
-#endif
diff --git a/security/nss/lib/ckfw/capi/ckcapiver.c b/security/nss/lib/ckfw/capi/ckcapiver.c
deleted file mode 100644
index cddf6c46a..000000000
--- a/security/nss/lib/ckfw/capi/ckcapiver.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* Library identity and versioning */
-
-#include "nsscapi.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_ckcapi_rcsid[] = "$Header: NSS Access to Microsoft Certificate Store "
- NSS_CKCAPI_LIBRARY_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_ckcapi_sccsid[] = "@(#)NSS Access to Microsoft Certificate Store "
- NSS_CKCAPI_LIBRARY_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/ckfw/capi/cobject.c b/security/nss/lib/ckfw/capi/cobject.c
deleted file mode 100644
index 8f644a9d0..000000000
--- a/security/nss/lib/ckfw/capi/cobject.c
+++ /dev/null
@@ -1,2308 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckcapi.h"
-#include "nssbase.h"
-
-/*
- * ckcapi/cobject.c
- *
- * This file implements the NSSCKMDObject object for the
- * "nss to capi objects" cryptoki module.
- */
-
-const CK_ATTRIBUTE_TYPE certAttrs[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_PRIVATE,
- CKA_MODIFIABLE,
- CKA_LABEL,
- CKA_CERTIFICATE_TYPE,
- CKA_SUBJECT,
- CKA_ISSUER,
- CKA_SERIAL_NUMBER,
- CKA_VALUE
-};
-const PRUint32 certAttrsCount = NSS_CKCAPI_ARRAY_SIZE(certAttrs);
-
-/* private keys, for now only support RSA */
-const CK_ATTRIBUTE_TYPE privKeyAttrs[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_PRIVATE,
- CKA_MODIFIABLE,
- CKA_LABEL,
- CKA_KEY_TYPE,
- CKA_DERIVE,
- CKA_LOCAL,
- CKA_SUBJECT,
- CKA_SENSITIVE,
- CKA_DECRYPT,
- CKA_SIGN,
- CKA_SIGN_RECOVER,
- CKA_UNWRAP,
- CKA_EXTRACTABLE,
- CKA_ALWAYS_SENSITIVE,
- CKA_NEVER_EXTRACTABLE,
- CKA_MODULUS,
- CKA_PUBLIC_EXPONENT,
-};
-const PRUint32 privKeyAttrsCount = NSS_CKCAPI_ARRAY_SIZE(privKeyAttrs);
-
-/* public keys, for now only support RSA */
-const CK_ATTRIBUTE_TYPE pubKeyAttrs[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_PRIVATE,
- CKA_MODIFIABLE,
- CKA_LABEL,
- CKA_KEY_TYPE,
- CKA_DERIVE,
- CKA_LOCAL,
- CKA_SUBJECT,
- CKA_ENCRYPT,
- CKA_VERIFY,
- CKA_VERIFY_RECOVER,
- CKA_WRAP,
- CKA_MODULUS,
- CKA_PUBLIC_EXPONENT,
-};
-const PRUint32 pubKeyAttrsCount = NSS_CKCAPI_ARRAY_SIZE(pubKeyAttrs);
-static const CK_BBOOL ck_true = CK_TRUE;
-static const CK_BBOOL ck_false = CK_FALSE;
-static const CK_CERTIFICATE_TYPE ckc_x509 = CKC_X_509;
-static const CK_KEY_TYPE ckk_rsa = CKK_RSA;
-static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
-static const CK_OBJECT_CLASS cko_private_key = CKO_PRIVATE_KEY;
-static const CK_OBJECT_CLASS cko_public_key = CKO_PUBLIC_KEY;
-static const NSSItem ckcapi_trueItem = {
- (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) };
-static const NSSItem ckcapi_falseItem = {
- (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) };
-static const NSSItem ckcapi_x509Item = {
- (void *)&ckc_x509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) };
-static const NSSItem ckcapi_rsaItem = {
- (void *)&ckk_rsa, (PRUint32)sizeof(CK_KEY_TYPE) };
-static const NSSItem ckcapi_certClassItem = {
- (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) };
-static const NSSItem ckcapi_privKeyClassItem = {
- (void *)&cko_private_key, (PRUint32)sizeof(CK_OBJECT_CLASS) };
-static const NSSItem ckcapi_pubKeyClassItem = {
- (void *)&cko_public_key, (PRUint32)sizeof(CK_OBJECT_CLASS) };
-static const NSSItem ckcapi_emptyItem = {
- (void *)&ck_true, 0};
-
-/*
- * these are utilities. The chould be moved to a new utilities file.
- */
-
-/*
- * unwrap a single DER value
- */
-unsigned char *
-nss_ckcapi_DERUnwrap
-(
- unsigned char *src,
- unsigned int size,
- unsigned int *outSize,
- unsigned char **next
-)
-{
- unsigned char *start = src;
- unsigned char *end = src+size;
- unsigned int len = 0;
-
- /* initialize error condition return values */
- *outSize = 0;
- if (next) {
- *next = src;
- }
-
- if (size < 2) {
- return start;
- }
- src++; /* skip the tag -- should check it against an expected value! */
- len = (unsigned) *src++;
- if (len & 0x80) {
- unsigned int count = len & 0x7f;
- len = 0;
-
- if (count+2 > size) {
- return start;
- }
- while (count-- > 0) {
- len = (len << 8) | (unsigned) *src++;
- }
- }
- if (len + (src-start) > size) {
- return start;
- }
- if (next) {
- *next = src+len;
- }
- *outSize = len;
-
- return src;
-}
-
-/*
- * convert a PKCS #11 bytestrin into a CK_ULONG, the byte stream must be
- * less than sizeof (CK_ULONG).
- */
-CK_ULONG
-nss_ckcapi_DataToInt
-(
- NSSItem *data,
- CK_RV *pError
-)
-{
- CK_ULONG value = 0;
- unsigned long count = data->size;
- unsigned char *dataPtr = data->data;
- unsigned long size = 0;
-
- *pError = CKR_OK;
-
- while (count--) {
- value = value << 8;
- value = value + *dataPtr++;
- if (size || value) {
- size++;
- }
- }
- if (size > sizeof(CK_ULONG)) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- }
- return value;
-}
-
-/*
- * convert a CK_ULONG to a bytestream. Data is stored in the buffer 'buf'
- * and must be at least CK_ULONG. Caller must provide buf.
- */
-CK_ULONG
-nss_ckcapi_IntToData
-(
- CK_ULONG value,
- NSSItem *data,
- unsigned char *dataPtr,
- CK_RV *pError
-)
-{
- unsigned long count = 0;
- unsigned long i;
-#define SHIFT ((sizeof(CK_ULONG)-1)*8)
- PRBool first = 0;
-
- *pError = CKR_OK;
-
- data->data = dataPtr;
- for (i=0; i < sizeof(CK_ULONG); i++) {
- unsigned char digit = (unsigned char)((value >> SHIFT) & 0xff);
-
- value = value << 8;
-
- /* drop leading zero bytes */
- if (first && (0 == digit)) {
- continue;
- }
- *dataPtr++ = digit;
- count++;
- }
- data->size = count;
- return count;
-}
-
-/*
- * get an attribute from a template. Value is returned in NSS item.
- * data for the item is owned by the template.
- */
-CK_RV
-nss_ckcapi_GetAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- NSSItem *item
-)
-{
- CK_ULONG i;
-
- for (i=0; i < templateSize; i++) {
- if (template[i].type == type) {
- item->data = template[i].pValue;
- item->size = template[i].ulValueLen;
- return CKR_OK;
- }
- }
- return CKR_TEMPLATE_INCOMPLETE;
-}
-
-/*
- * get an attribute which is type CK_ULONG.
- */
-CK_ULONG
-nss_ckcapi_GetULongAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError
-)
-{
- NSSItem item;
-
- *pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
- if (CKR_OK != *pError) {
- return (CK_ULONG) 0;
- }
- if (item.size != sizeof(CK_ULONG)) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (CK_ULONG) 0;
- }
- return *(CK_ULONG *)item.data;
-}
-
-/*
- * get an attribute which is type CK_BBOOL.
- */
-CK_BBOOL
-nss_ckcapi_GetBoolAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError
-)
-{
- NSSItem item;
-
- *pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
- if (CKR_OK != *pError) {
- return (CK_BBOOL) 0;
- }
- if (item.size != sizeof(CK_BBOOL)) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (CK_BBOOL) 0;
- }
- return *(CK_BBOOL *)item.data;
-}
-
-/*
- * get an attribute which is type CK_BBOOL.
- */
-char *
-nss_ckcapi_GetStringAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError
-)
-{
- NSSItem item;
- char *str;
-
- /* get the attribute */
- *pError = nss_ckcapi_GetAttribute(type, template, templateSize, &item);
- if (CKR_OK != *pError) {
- return (char *)NULL;
- }
- /* make sure it is null terminated */
- str = nss_ZNEWARRAY(NULL, char, item.size+1);
- if ((char *)NULL == str) {
- *pError = CKR_HOST_MEMORY;
- return (char *)NULL;
- }
-
- nsslibc_memcpy(str, item.data, item.size);
- str[item.size] = 0;
-
- return str;
-}
-
-/*
- * Return the size in bytes of a wide string, including the terminating null
- * character
- */
-int
-nss_ckcapi_WideSize
-(
- LPCWSTR wide
-)
-{
- DWORD size;
-
- if ((LPWSTR)NULL == wide) {
- return 0;
- }
- size = wcslen(wide)+1;
- return size*sizeof(WCHAR);
-}
-
-/*
- * Covert a Unicode wide character string to a UTF8 string
- */
-char *
-nss_ckcapi_WideToUTF8
-(
- LPCWSTR wide
-)
-{
- DWORD size;
- char *buf;
-
- if ((LPWSTR)NULL == wide) {
- return (char *)NULL;
- }
-
- size = WideCharToMultiByte(CP_UTF8, 0, wide, -1, NULL, 0, NULL, 0);
- if (size == 0) {
- return (char *)NULL;
- }
- buf = nss_ZNEWARRAY(NULL, char, size);
- size = WideCharToMultiByte(CP_UTF8, 0, wide, -1, buf, size, NULL, 0);
- if (size == 0) {
- nss_ZFreeIf(buf);
- return (char *)NULL;
- }
- return buf;
-}
-
-/*
- * Return a Wide String duplicated with nss allocated memory.
- */
-LPWSTR
-nss_ckcapi_WideDup
-(
- LPCWSTR wide
-)
-{
- DWORD len;
- LPWSTR buf;
-
- if ((LPWSTR)NULL == wide) {
- return (LPWSTR)NULL;
- }
-
- len = wcslen(wide)+1;
-
- buf = nss_ZNEWARRAY(NULL, WCHAR, len);
- if ((LPWSTR) NULL == buf) {
- return buf;
- }
- nsslibc_memcpy(buf, wide, len*sizeof(WCHAR));
- return buf;
-}
-
-/*
- * Covert a UTF8 string to Unicode wide character
- */
-LPWSTR
-nss_ckcapi_UTF8ToWide
-(
- char *buf
-)
-{
- DWORD size;
- LPWSTR wide;
-
- if ((char *)NULL == buf) {
- return (LPWSTR) NULL;
- }
-
- size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
- if (size == 0) {
- return (LPWSTR) NULL;
- }
- wide = nss_ZNEWARRAY(NULL, WCHAR, size);
- size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wide, size);
- if (size == 0) {
- nss_ZFreeIf(wide);
- return (LPWSTR) NULL;
- }
- return wide;
-}
-
-
-/*
- * keep all the knowlege of how the internalObject is laid out in this function
- *
- * nss_ckcapi_FetchKeyContainer
- *
- * fetches the Provider container and info as well as a key handle for a
- * private key. If something other than a private key is passed in,
- * this function fails with CKR_KEY_TYPE_INCONSISTENT
- */
-NSS_EXTERN CK_RV
-nss_ckcapi_FetchKeyContainer
-(
- ckcapiInternalObject *iKey,
- HCRYPTPROV *hProv,
- DWORD *keySpec,
- HCRYPTKEY *hKey
-)
-{
- ckcapiCertObject *co;
- ckcapiKeyObject *ko;
- BOOL rc, dummy;
- DWORD msError;
-
-
- switch (iKey->type) {
- default:
- case ckcapiRaw:
- /* can't have raw private keys */
- return CKR_KEY_TYPE_INCONSISTENT;
- case ckcapiCert:
- if (iKey->objClass != CKO_PRIVATE_KEY) {
- /* Only private keys have private key provider handles */
- return CKR_KEY_TYPE_INCONSISTENT;
- }
- co = &iKey->u.cert;
-
- /* OK, get the Provider */
- rc = CryptAcquireCertificatePrivateKey(co->certContext,
- CRYPT_ACQUIRE_CACHE_FLAG|CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, hProv,
- keySpec, &dummy);
- if (!rc) {
- goto loser;
- }
- break;
- case ckcapiBareKey:
- if (iKey->objClass != CKO_PRIVATE_KEY) {
- /* Only private keys have private key provider handles */
- return CKR_KEY_TYPE_INCONSISTENT;
- }
- ko = &iKey->u.key;
-
- /* OK, get the Provider */
- if (0 == ko->hProv) {
- rc = CryptAcquireContext(hProv,
- ko->containerName,
- ko->provName,
- ko->provInfo.dwProvType , 0);
- if (!rc) {
- goto loser;
- }
- } else {
- *hProv = ko->hProv;
- }
- *keySpec = ko->provInfo.dwKeySpec;
- break;
- }
-
- /* and get the crypto handle */
- rc = CryptGetUserKey(*hProv, *keySpec, hKey);
- if (!rc) {
- goto loser;
- }
- return CKR_OK;
-loser:
- /* map the microsoft error before leaving */
- msError = GetLastError();
- switch (msError) {
- case ERROR_INVALID_HANDLE:
- case ERROR_INVALID_PARAMETER:
- case NTE_BAD_KEY:
- case NTE_NO_KEY:
- case NTE_BAD_PUBLIC_KEY:
- case NTE_BAD_KEYSET:
- case NTE_KEYSET_NOT_DEF:
- return CKR_KEY_TYPE_INCONSISTENT;
- case NTE_BAD_UID:
- case NTE_KEYSET_ENTRY_BAD:
- return CKR_DEVICE_ERROR;
- }
- return CKR_GENERAL_ERROR;
-}
-
-
-/*
- * take a DER PUBLIC Key block and return the modulus and exponent
- */
-static void
-ckcapi_CertPopulateModulusExponent
-(
- ckcapiInternalObject *io
-)
-{
- ckcapiKeyParams *kp = &io->u.cert.key;
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- unsigned char *pkData =
- certContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData;
- unsigned int size=
- certContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData;
- unsigned int newSize;
- unsigned char *ptr, *newptr;
-
- /* find the start of the modulus -- this will not give good results if
- * the key isn't an rsa key! */
- ptr = nss_ckcapi_DERUnwrap(pkData, size, &newSize, NULL);
- kp->modulus.data = nss_ckcapi_DERUnwrap(ptr, newSize,
- &kp->modulus.size, &newptr);
- /* changed from signed to unsigned int */
- if (0 == *(char *)kp->modulus.data) {
- kp->modulus.data = ((char *)kp->modulus.data)+1;
- kp->modulus.size = kp->modulus.size - 1;
- }
- /* changed from signed to unsigned int */
- kp->exponent.data = nss_ckcapi_DERUnwrap(newptr, (newptr-ptr)+newSize,
- &kp->exponent.size, NULL);
- if (0 == *(char *)kp->exponent.data) {
- kp->exponent.data = ((char *)kp->exponent.data)+1;
- kp->exponent.size = kp->exponent.size - 1;
- }
- return;
-}
-
-typedef struct _CAPI_RSA_KEY_BLOB {
- PUBLICKEYSTRUC header;
- RSAPUBKEY rsa;
- char data[1];
-} CAPI_RSA_KEY_BLOB;
-
-#define CAPI_MODULUS_OFFSET(modSize) 0
-#define CAPI_PRIME_1_OFFSET(modSize) (modSize)
-#define CAPI_PRIME_2_OFFSET(modSize) ((modSize)+(modSize)/2)
-#define CAPI_EXPONENT_1_OFFSET(modSize) ((modSize)*2)
-#define CAPI_EXPONENT_2_OFFSET(modSize) ((modSize)*2+(modSize)/2)
-#define CAPI_COEFFICIENT_OFFSET(modSize) ((modSize)*3)
-#define CAPI_PRIVATE_EXP_OFFSET(modSize) ((modSize)*3+(modSize)/2)
-
-void
-ckcapi_FetchPublicKey
-(
- ckcapiInternalObject *io
-)
-{
- ckcapiKeyParams *kp;
- HCRYPTPROV hProv;
- DWORD keySpec;
- HCRYPTKEY hKey = 0;
- CK_RV error;
- DWORD bufLen;
- BOOL rc;
- unsigned long modulus;
- char *buf = NULL;
- CAPI_RSA_KEY_BLOB *blob;
-
- error = nss_ckcapi_FetchKeyContainer(io, &hProv, &keySpec, &hKey);
- if (CKR_OK != error) {
- goto loser;
- }
- kp = (ckcapiCert == io->type) ? &io->u.cert.key : &io->u.key.key;
-
- rc = CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, buf, &bufLen);
- if (!rc) {
- goto loser;
- }
- buf = nss_ZNEWARRAY(NULL, char, bufLen);
- rc = CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, buf, &bufLen);
- if (!rc) {
- goto loser;
- }
- /* validate the blob */
- blob = (CAPI_RSA_KEY_BLOB *)buf;
- if ((PUBLICKEYBLOB != blob->header.bType) ||
- (0x02 != blob->header.bVersion) ||
- (0x31415352 != blob->rsa.magic)) {
- goto loser;
- }
- modulus = blob->rsa.bitlen/8;
- kp->pubKey = buf;
- buf = NULL;
-
- kp->modulus.data = &blob->data[CAPI_MODULUS_OFFSET(modulus)];
- kp->modulus.size = modulus;
- ckcapi_ReverseData(&kp->modulus);
- nss_ckcapi_IntToData(blob->rsa.pubexp, &kp->exponent,
- kp->publicExponentData, &error);
-
-loser:
- nss_ZFreeIf(buf);
- if (0 != hKey) {
- CryptDestroyKey(hKey);
- }
- return;
-}
-
-void
-ckcapi_FetchPrivateKey
-(
- ckcapiInternalObject *io
-)
-{
- ckcapiKeyParams *kp;
- HCRYPTPROV hProv;
- DWORD keySpec;
- HCRYPTKEY hKey = 0;
- CK_RV error;
- DWORD bufLen;
- BOOL rc;
- unsigned long modulus;
- char *buf = NULL;
- CAPI_RSA_KEY_BLOB *blob;
-
- error = nss_ckcapi_FetchKeyContainer(io, &hProv, &keySpec, &hKey);
- if (CKR_OK != error) {
- goto loser;
- }
- kp = (ckcapiCert == io->type) ? &io->u.cert.key : &io->u.key.key;
-
- rc = CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, buf, &bufLen);
- if (!rc) {
- goto loser;
- }
- buf = nss_ZNEWARRAY(NULL, char, bufLen);
- rc = CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, buf, &bufLen);
- if (!rc) {
- goto loser;
- }
- /* validate the blob */
- blob = (CAPI_RSA_KEY_BLOB *)buf;
- if ((PRIVATEKEYBLOB != blob->header.bType) ||
- (0x02 != blob->header.bVersion) ||
- (0x32415352 != blob->rsa.magic)) {
- goto loser;
- }
- modulus = blob->rsa.bitlen/8;
- kp->privateKey = buf;
- buf = NULL;
-
- kp->privateExponent.data = &blob->data[CAPI_PRIVATE_EXP_OFFSET(modulus)];
- kp->privateExponent.size = modulus;
- ckcapi_ReverseData(&kp->privateExponent);
- kp->prime1.data = &blob->data[CAPI_PRIME_1_OFFSET(modulus)];
- kp->prime1.size = modulus/2;
- ckcapi_ReverseData(&kp->prime1);
- kp->prime2.data = &blob->data[CAPI_PRIME_2_OFFSET(modulus)];
- kp->prime2.size = modulus/2;
- ckcapi_ReverseData(&kp->prime2);
- kp->exponent1.data = &blob->data[CAPI_EXPONENT_1_OFFSET(modulus)];
- kp->exponent1.size = modulus/2;
- ckcapi_ReverseData(&kp->exponent1);
- kp->exponent2.data = &blob->data[CAPI_EXPONENT_2_OFFSET(modulus)];
- kp->exponent2.size = modulus/2;
- ckcapi_ReverseData(&kp->exponent2);
- kp->coefficient.data = &blob->data[CAPI_COEFFICIENT_OFFSET(modulus)];
- kp->coefficient.size = modulus/2;
- ckcapi_ReverseData(&kp->coefficient);
-
-loser:
- nss_ZFreeIf(buf);
- if (0 != hKey) {
- CryptDestroyKey(hKey);
- }
- return;
-}
-
-
-void
-ckcapi_PopulateModulusExponent
-(
- ckcapiInternalObject *io
-)
-{
- if (ckcapiCert == io->type) {
- ckcapi_CertPopulateModulusExponent(io);
- } else {
- ckcapi_FetchPublicKey(io);
- }
- return;
-}
-
-/*
- * fetch the friendly name attribute.
- * can only be called with ckcapiCert type objects!
- */
-void
-ckcapi_FetchLabel
-(
- ckcapiInternalObject *io
-)
-{
- ckcapiCertObject *co = &io->u.cert;
- char *label;
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- char labelDataUTF16[128];
- DWORD size = sizeof(labelDataUTF16);
- DWORD size8 = sizeof(co->labelData);
- BOOL rv;
-
- rv = CertGetCertificateContextProperty(certContext,
- CERT_FRIENDLY_NAME_PROP_ID, labelDataUTF16, &size);
- if (rv) {
- co->labelData = nss_ckcapi_WideToUTF8((LPCWSTR)labelDataUTF16);
- if ((CHAR *)NULL == co->labelData) {
- rv = 0;
- } else {
- size = strlen(co->labelData);
- }
- }
- label = co->labelData;
- /* we are presuming a user cert, make sure it has a nickname, even if
- * Microsoft never gave it one */
- if (!rv && co->hasID) {
- DWORD mserror = GetLastError();
-#define DEFAULT_NICKNAME "no Microsoft nickname"
- label = DEFAULT_NICKNAME;
- size = sizeof(DEFAULT_NICKNAME);
- rv = 1;
- }
-
- if (rv) {
- co->label.data = label;
- co->label.size = size;
- }
- return;
-}
-
-void
-ckcapi_FetchSerial
-(
- ckcapiInternalObject *io
-)
-{
- ckcapiCertObject *co = &io->u.cert;
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- DWORD size = sizeof(co->derSerial);
-
- BOOL rc = CryptEncodeObject(X509_ASN_ENCODING,
- X509_MULTI_BYTE_INTEGER,
- &certContext->pCertInfo->SerialNumber,
- co->derSerial,
- &size);
- if (rc) {
- co->serial.data = co->derSerial;
- co->serial.size = size;
- }
- return;
-}
-
-/*
- * fetch the key ID.
- */
-void
-ckcapi_FetchID
-(
- ckcapiInternalObject *io
-)
-{
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- DWORD size = 0;
- BOOL rc;
-
- rc = CertGetCertificateContextProperty(certContext,
- CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
- if (!rc) {
- return;
- }
- io->idData = nss_ZNEWARRAY(NULL, char, size);
- if (io->idData == NULL) {
- return;
- }
-
- rc = CertGetCertificateContextProperty(certContext,
- CERT_KEY_IDENTIFIER_PROP_ID, io->idData, &size);
- if (!rc) {
- nss_ZFreeIf(io->idData);
- io->idData = NULL;
- return;
- }
- io->id.data = io->idData;
- io->id.size = size;
- return;
-}
-
-/*
- * fetch the hash key.
- */
-void
-ckcapi_CertFetchHashKey
-(
- ckcapiInternalObject *io
-)
-{
- ckcapiCertObject *co = &io->u.cert;
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- DWORD size = certContext->cbCertEncoded;
- DWORD max = sizeof(io->hashKeyData)-1;
- DWORD offset = 0;
-
- /* make sure we don't over flow. NOTE: cutting the top of a cert is
- * not a big issue because the signature for will be unique for the cert */
- if (size > max) {
- offset = size - max;
- size = max;
- }
-
- nsslibc_memcpy(io->hashKeyData,certContext->pbCertEncoded+offset, size);
- io->hashKeyData[size] = (char)(io->objClass & 0xff);
-
- io->hashKey.data = io->hashKeyData;
- io->hashKey.size = size+1;
- return;
-}
-
-/*
- * fetch the hash key.
- */
-void
-ckcapi_KeyFetchHashKey
-(
- ckcapiInternalObject *io
-)
-{
- ckcapiKeyObject *ko = &io->u.key;
- DWORD size;
- DWORD max = sizeof(io->hashKeyData)-2;
- DWORD offset = 0;
- DWORD provLen = strlen(ko->provName);
- DWORD containerLen = strlen(ko->containerName);
-
-
- size = provLen + containerLen;
-
- /* make sure we don't overflow, try to keep things unique */
- if (size > max) {
- DWORD diff = ((size - max)+1)/2;
- provLen -= diff;
- containerLen -= diff;
- size = provLen+containerLen;
- }
-
- nsslibc_memcpy(io->hashKeyData, ko->provName, provLen);
- nsslibc_memcpy(&io->hashKeyData[provLen],
- ko->containerName,
- containerLen);
- io->hashKeyData[size] = (char)(io->objClass & 0xff);
- io->hashKeyData[size+1] = (char)(ko->provInfo.dwKeySpec & 0xff);
-
- io->hashKey.data = io->hashKeyData;
- io->hashKey.size = size+2;
- return;
-}
-
-/*
- * fetch the hash key.
- */
-void
-ckcapi_FetchHashKey
-(
- ckcapiInternalObject *io
-)
-{
- if (ckcapiCert == io->type) {
- ckcapi_CertFetchHashKey(io);
- } else {
- ckcapi_KeyFetchHashKey(io);
- }
- return;
-}
-
-const NSSItem *
-ckcapi_FetchCertAttribute
-(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type
-)
-{
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- switch(type) {
- case CKA_CLASS:
- return &ckcapi_certClassItem;
- case CKA_TOKEN:
- return &ckcapi_trueItem;
- case CKA_MODIFIABLE:
- case CKA_PRIVATE:
- return &ckcapi_falseItem;
- case CKA_CERTIFICATE_TYPE:
- return &ckcapi_x509Item;
- case CKA_LABEL:
- if (0 == io->u.cert.label.size) {
- ckcapi_FetchLabel(io);
- }
- return &io->u.cert.label;
- case CKA_SUBJECT:
- if (0 == io->u.cert.subject.size) {
- io->u.cert.subject.data = certContext->pCertInfo->Subject.pbData;
- io->u.cert.subject.size = certContext->pCertInfo->Subject.cbData;
- }
- return &io->u.cert.subject;
- case CKA_ISSUER:
- if (0 == io->u.cert.issuer.size) {
- io->u.cert.issuer.data = certContext->pCertInfo->Issuer.pbData;
- io->u.cert.issuer.size = certContext->pCertInfo->Issuer.cbData;
- }
- return &io->u.cert.issuer;
- case CKA_SERIAL_NUMBER:
- if (0 == io->u.cert.serial.size) {
- /* not exactly right. This should be the encoded serial number, but
- * it's the decoded serial number! */
- ckcapi_FetchSerial(io);
- }
- return &io->u.cert.serial;
- case CKA_VALUE:
- if (0 == io->u.cert.derCert.size) {
- io->u.cert.derCert.data = io->u.cert.certContext->pbCertEncoded;
- io->u.cert.derCert.size = io->u.cert.certContext->cbCertEncoded;
- }
- return &io->u.cert.derCert;
- case CKA_ID:
- if (!io->u.cert.hasID) {
- return NULL;
- }
- if (0 == io->id.size) {
- ckcapi_FetchID(io);
- }
- return &io->id;
- default:
- break;
- }
- return NULL;
-}
-
-const NSSItem *
-ckcapi_FetchPubKeyAttribute
-(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type
-)
-{
- PRBool isCertType = (ckcapiCert == io->type);
- ckcapiKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;
-
- switch(type) {
- case CKA_CLASS:
- return &ckcapi_pubKeyClassItem;
- case CKA_TOKEN:
- case CKA_LOCAL:
- case CKA_ENCRYPT:
- case CKA_VERIFY:
- case CKA_VERIFY_RECOVER:
- return &ckcapi_trueItem;
- case CKA_PRIVATE:
- case CKA_MODIFIABLE:
- case CKA_DERIVE:
- case CKA_WRAP:
- return &ckcapi_falseItem;
- case CKA_KEY_TYPE:
- return &ckcapi_rsaItem;
- case CKA_LABEL:
- if (!isCertType) {
- return &ckcapi_emptyItem;
- }
- if (0 == io->u.cert.label.size) {
- ckcapi_FetchLabel(io);
- }
- return &io->u.cert.label;
- case CKA_SUBJECT:
- if (!isCertType) {
- return &ckcapi_emptyItem;
- }
- if (0 == io->u.cert.subject.size) {
- PCCERT_CONTEXT certContext= io->u.cert.certContext;
- io->u.cert.subject.data = certContext->pCertInfo->Subject.pbData;
- io->u.cert.subject.size = certContext->pCertInfo->Subject.cbData;
- }
- return &io->u.cert.subject;
- case CKA_MODULUS:
- if (0 == kp->modulus.size) {
- ckcapi_PopulateModulusExponent(io);
- }
- return &kp->modulus;
- case CKA_PUBLIC_EXPONENT:
- if (0 == kp->modulus.size) {
- ckcapi_PopulateModulusExponent(io);
- }
- return &kp->exponent;
- case CKA_ID:
- if (0 == io->id.size) {
- ckcapi_FetchID(io);
- }
- return &io->id;
- default:
- break;
- }
- return NULL;
-}
-
-const NSSItem *
-ckcapi_FetchPrivKeyAttribute
-(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type
-)
-{
- PRBool isCertType = (ckcapiCert == io->type);
- ckcapiKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;
-
- switch(type) {
- case CKA_CLASS:
- return &ckcapi_privKeyClassItem;
- case CKA_TOKEN:
- case CKA_LOCAL:
- case CKA_SIGN:
- case CKA_DECRYPT:
- case CKA_SIGN_RECOVER:
- return &ckcapi_trueItem;
- case CKA_SENSITIVE:
- case CKA_PRIVATE: /* should move in the future */
- case CKA_MODIFIABLE:
- case CKA_DERIVE:
- case CKA_UNWRAP:
- case CKA_EXTRACTABLE: /* will probably move in the future */
- case CKA_ALWAYS_SENSITIVE:
- case CKA_NEVER_EXTRACTABLE:
- return &ckcapi_falseItem;
- case CKA_KEY_TYPE:
- return &ckcapi_rsaItem;
- case CKA_LABEL:
- if (!isCertType) {
- return &ckcapi_emptyItem;
- }
- if (0 == io->u.cert.label.size) {
- ckcapi_FetchLabel(io);
- }
- return &io->u.cert.label;
- case CKA_SUBJECT:
- if (!isCertType) {
- return &ckcapi_emptyItem;
- }
- if (0 == io->u.cert.subject.size) {
- PCCERT_CONTEXT certContext= io->u.cert.certContext;
- io->u.cert.subject.data = certContext->pCertInfo->Subject.pbData;
- io->u.cert.subject.size = certContext->pCertInfo->Subject.cbData;
- }
- return &io->u.cert.subject;
- case CKA_MODULUS:
- if (0 == kp->modulus.size) {
- ckcapi_PopulateModulusExponent(io);
- }
- return &kp->modulus;
- case CKA_PUBLIC_EXPONENT:
- if (0 == kp->modulus.size) {
- ckcapi_PopulateModulusExponent(io);
- }
- return &kp->exponent;
- case CKA_PRIVATE_EXPONENT:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->privateExponent;
- case CKA_PRIME_1:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->prime1;
- case CKA_PRIME_2:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->prime2;
- case CKA_EXPONENT_1:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->exponent1;
- case CKA_EXPONENT_2:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->exponent2;
- case CKA_COEFFICIENT:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->coefficient;
- case CKA_ID:
- if (0 == io->id.size) {
- ckcapi_FetchID(io);
- }
- return &io->id;
- default:
- return NULL;
- }
-}
-
-const NSSItem *
-nss_ckcapi_FetchAttribute
-(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type
-)
-{
- CK_ULONG i;
-
- if (io->type == ckcapiRaw) {
- for( i = 0; i < io->u.raw.n; i++ ) {
- if( type == io->u.raw.types[i] ) {
- return &io->u.raw.items[i];
- }
- }
- return NULL;
- }
- /* deal with the common attributes */
- switch (io->objClass) {
- case CKO_CERTIFICATE:
- return ckcapi_FetchCertAttribute(io, type);
- case CKO_PRIVATE_KEY:
- return ckcapi_FetchPrivKeyAttribute(io, type);
- case CKO_PUBLIC_KEY:
- return ckcapi_FetchPubKeyAttribute(io, type);
- }
- return NULL;
-}
-
-/*
- * check to see if the certificate already exists
- */
-static PRBool
-ckcapi_cert_exists(
- NSSItem *value,
- ckcapiInternalObject **io
-)
-{
- int count,i;
- PRUint32 size = 0;
- ckcapiInternalObject **listp = NULL;
- CK_ATTRIBUTE myTemplate[2];
- CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
- CK_ULONG templateCount = 2;
- CK_RV error;
- PRBool found = PR_FALSE;
-
- myTemplate[0].type = CKA_CLASS;
- myTemplate[0].pValue = &cert_class;
- myTemplate[0].ulValueLen = sizeof(cert_class);
- myTemplate[1].type = CKA_VALUE;
- myTemplate[1].pValue = value->data;
- myTemplate[1].ulValueLen = value->size;
-
- count = nss_ckcapi_collect_all_certs(myTemplate, templateCount, &listp,
- &size, 0, &error);
-
- /* free them */
- if (count > 1) {
- *io = listp[0];
- found = PR_TRUE;
- }
-
- for (i=1; i < count; i++) {
- nss_ckcapi_DestroyInternalObject(listp[i]);
- }
- nss_ZFreeIf(listp);
- return found;
-}
-
-static PRBool
-ckcapi_cert_hasEmail
-(
- PCCERT_CONTEXT certContext
-)
-{
- int count;
-
- count = CertGetNameString(certContext, CERT_NAME_EMAIL_TYPE,
- 0, NULL, NULL, 0);
-
- return count > 1 ? PR_TRUE : PR_FALSE;
-}
-
-static PRBool
-ckcapi_cert_isRoot
-(
- PCCERT_CONTEXT certContext
-)
-{
- return CertCompareCertificateName(certContext->dwCertEncodingType,
- &certContext->pCertInfo->Issuer, &certContext->pCertInfo->Subject);
-}
-
-static PRBool
-ckcapi_cert_isCA
-(
- PCCERT_CONTEXT certContext
-)
-{
- PCERT_EXTENSION extension;
- CERT_BASIC_CONSTRAINTS2_INFO basicInfo;
- DWORD size = sizeof(basicInfo);
- BOOL rc;
-
- extension = CertFindExtension (szOID_BASIC_CONSTRAINTS,
- certContext->pCertInfo->cExtension,
- certContext->pCertInfo->rgExtension);
- if ((PCERT_EXTENSION) NULL == extension ) {
- return PR_FALSE;
- }
- rc = CryptDecodeObject(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS2,
- extension->Value.pbData, extension->Value.cbData,
- 0, &basicInfo, &size);
- if (!rc) {
- return PR_FALSE;
- }
- return (PRBool) basicInfo.fCA;
-}
-
-static CRYPT_KEY_PROV_INFO *
-ckcapi_cert_getPrivateKeyInfo
-(
- PCCERT_CONTEXT certContext,
- NSSItem *keyID
-)
-{
- BOOL rc;
- CRYPT_HASH_BLOB msKeyID;
- DWORD size = 0;
- CRYPT_KEY_PROV_INFO *prov = NULL;
-
- msKeyID.cbData = keyID->size;
- msKeyID.pbData = keyID->data;
-
- rc = CryptGetKeyIdentifierProperty(
- &msKeyID,
- CERT_KEY_PROV_INFO_PROP_ID,
- 0, NULL, NULL, NULL, &size);
- if (!rc) {
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
- prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
- if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
- return (CRYPT_KEY_PROV_INFO *) NULL;
- }
- rc = CryptGetKeyIdentifierProperty(
- &msKeyID,
- CERT_KEY_PROV_INFO_PROP_ID,
- 0, NULL, NULL, prov, &size);
- if (!rc) {
- nss_ZFreeIf(prov);
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
-
- return prov;
-}
-
-static CRYPT_KEY_PROV_INFO *
-ckcapi_cert_getProvInfo
-(
- ckcapiInternalObject *io
-)
-{
- BOOL rc;
- DWORD size = 0;
- CRYPT_KEY_PROV_INFO *prov = NULL;
-
- rc = CertGetCertificateContextProperty(
- io->u.cert.certContext,
- CERT_KEY_PROV_INFO_PROP_ID,
- NULL, &size);
- if (!rc) {
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
- prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
- if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
- return (CRYPT_KEY_PROV_INFO *) NULL;
- }
- rc = CertGetCertificateContextProperty(
- io->u.cert.certContext,
- CERT_KEY_PROV_INFO_PROP_ID,
- prov, &size);
- if (!rc) {
- nss_ZFreeIf(prov);
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
-
- return prov;
-}
-
-/* forward declaration */
-static void
-ckcapi_removeObjectFromHash
-(
- ckcapiInternalObject *io
-);
-
-/*
- * Finalize - unneeded
- * Destroy
- * IsTokenObject - CK_TRUE
- * GetAttributeCount
- * GetAttributeTypes
- * GetAttributeSize
- * GetAttribute
- * SetAttribute
- * GetObjectSize
- */
-
-static CK_RV
-ckcapi_mdObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
- CK_OBJECT_CLASS objClass;
- BOOL rc;
- DWORD provType;
- DWORD msError;
- PRBool isCertType = (PRBool)(ckcapiCert == io->type);
- HCERTSTORE hStore = 0;
-
- if (ckcapiRaw == io->type) {
- /* there is not 'object write protected' error, use the next best thing */
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- objClass = io->objClass;
- if (CKO_CERTIFICATE == objClass) {
- PCCERT_CONTEXT certContext;
-
- /* get the store */
- hStore = CertOpenSystemStore(0, io->u.cert.certStore);
- if (0 == hStore) {
- rc = 0;
- goto loser;
- }
- certContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING, 0,
- CERT_FIND_EXISTING, io->u.cert.certContext, NULL);
- if ((PCCERT_CONTEXT)NULL == certContext) {
- rc = 0;
- goto loser;
- }
- rc = CertDeleteCertificateFromStore(certContext);
- } else {
- char *provName = NULL;
- char *containerName = NULL;
- HCRYPTPROV hProv;
- CRYPT_HASH_BLOB msKeyID;
-
- if (0 == io->id.size) {
- ckcapi_FetchID(io);
- }
-
- if (isCertType) {
- CRYPT_KEY_PROV_INFO * provInfo = ckcapi_cert_getProvInfo(io);
- provName = nss_ckcapi_WideToUTF8(provInfo->pwszProvName);
- containerName = nss_ckcapi_WideToUTF8(provInfo->pwszContainerName);
- provType = provInfo->dwProvType;
- nss_ZFreeIf(provInfo);
- } else {
- provName = io->u.key.provName;
- containerName = io->u.key.containerName;
- provType = io->u.key.provInfo.dwProvType;
- io->u.key.provName = NULL;
- io->u.key.containerName = NULL;
- }
- /* first remove the key id pointer */
- msKeyID.cbData = io->id.size;
- msKeyID.pbData = io->id.data;
- rc = CryptSetKeyIdentifierProperty(&msKeyID,
- CERT_KEY_PROV_INFO_PROP_ID, CRYPT_KEYID_DELETE_FLAG, NULL, NULL, NULL);
- if (rc) {
- rc = CryptAcquireContext(&hProv, containerName, provName, provType,
- CRYPT_DELETEKEYSET);
- }
- nss_ZFreeIf(provName);
- nss_ZFreeIf(containerName);
- }
-loser:
-
- if (hStore) {
- CertCloseStore(hStore, 0);
- }
- if (!rc) {
- msError = GetLastError();
- return CKR_GENERAL_ERROR;
- }
-
- /* remove it from the hash */
- ckcapi_removeObjectFromHash(io);
-
- /* free the puppy.. */
- nss_ckcapi_DestroyInternalObject(io);
- return CKR_OK;
-}
-
-static CK_BBOOL
-ckcapi_mdObject_IsTokenObject
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_TRUE;
-}
-
-static CK_ULONG
-ckcapi_mdObject_GetAttributeCount
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
-
- if (ckcapiRaw == io->type) {
- return io->u.raw.n;
- }
- switch (io->objClass) {
- case CKO_CERTIFICATE:
- return certAttrsCount;
- case CKO_PUBLIC_KEY:
- return pubKeyAttrsCount;
- case CKO_PRIVATE_KEY:
- return privKeyAttrsCount;
- default:
- break;
- }
- return 0;
-}
-
-static CK_RV
-ckcapi_mdObject_GetAttributeTypes
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
- CK_ULONG i;
- CK_RV error = CKR_OK;
- const CK_ATTRIBUTE_TYPE *attrs = NULL;
- CK_ULONG size = ckcapi_mdObject_GetAttributeCount(
- mdObject, fwObject, mdSession, fwSession,
- mdToken, fwToken, mdInstance, fwInstance, &error);
-
- if( size != ulCount ) {
- return CKR_BUFFER_TOO_SMALL;
- }
- if (io->type == ckcapiRaw) {
- attrs = io->u.raw.types;
- } else switch(io->objClass) {
- case CKO_CERTIFICATE:
- attrs = certAttrs;
- break;
- case CKO_PUBLIC_KEY:
- attrs = pubKeyAttrs;
- break;
- case CKO_PRIVATE_KEY:
- attrs = privKeyAttrs;
- break;
- default:
- return CKR_OK;
- }
-
- for( i = 0; i < size; i++) {
- typeArray[i] = attrs[i];
- }
-
- return CKR_OK;
-}
-
-static CK_ULONG
-ckcapi_mdObject_GetAttributeSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
-
- const NSSItem *b;
-
- b = nss_ckcapi_FetchAttribute(io, attribute);
-
- if ((const NSSItem *)NULL == b) {
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return 0;
- }
- return b->size;
-}
-
-static CK_RV
-ckcapi_mdObject_SetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value
-)
-{
- return CKR_OK;
-}
-
-static NSSCKFWItem
-ckcapi_mdObject_GetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- NSSCKFWItem mdItem;
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
-
- mdItem.needsFreeing = PR_FALSE;
- mdItem.item = (NSSItem*)nss_ckcapi_FetchAttribute(io, attribute);
-
- if ((NSSItem *)NULL == mdItem.item) {
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- }
-
- return mdItem;
-}
-
-static CK_ULONG
-ckcapi_mdObject_GetObjectSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
- CK_ULONG rv = 1;
-
- /* size is irrelevant to this token */
- return rv;
-}
-
-static const NSSCKMDObject
-ckcapi_prototype_mdObject = {
- (void *)NULL, /* etc */
- NULL, /* Finalize */
- ckcapi_mdObject_Destroy,
- ckcapi_mdObject_IsTokenObject,
- ckcapi_mdObject_GetAttributeCount,
- ckcapi_mdObject_GetAttributeTypes,
- ckcapi_mdObject_GetAttributeSize,
- ckcapi_mdObject_GetAttribute,
- NULL, /* FreeAttribute */
- ckcapi_mdObject_SetAttribute,
- ckcapi_mdObject_GetObjectSize,
- (void *)NULL /* null terminator */
-};
-
-static nssHash *ckcapiInternalObjectHash = NULL;
-
-NSS_IMPLEMENT NSSCKMDObject *
-nss_ckcapi_CreateMDObject
-(
- NSSArena *arena,
- ckcapiInternalObject *io,
- CK_RV *pError
-)
-{
- if ((nssHash *)NULL == ckcapiInternalObjectHash) {
- ckcapiInternalObjectHash = nssHash_CreateItem(NULL, 10);
- }
- if (ckcapiCert == io->type) {
- /* the hash key, not a cryptographic key */
- NSSItem *key = &io->hashKey;
- ckcapiInternalObject *old_o = NULL;
-
- if (key->size == 0) {
- ckcapi_FetchHashKey(io);
- }
- old_o = (ckcapiInternalObject *)
- nssHash_Lookup(ckcapiInternalObjectHash, key);
- if (!old_o) {
- nssHash_Add(ckcapiInternalObjectHash, key, io);
- } else if (old_o != io) {
- nss_ckcapi_DestroyInternalObject(io);
- io = old_o;
- }
- }
-
- if ( (void*)NULL == io->mdObject.etc) {
- (void) nsslibc_memcpy(&io->mdObject,&ckcapi_prototype_mdObject,
- sizeof(ckcapi_prototype_mdObject));
- io->mdObject.etc = (void *)io;
- }
- return &io->mdObject;
-}
-
-static void
-ckcapi_removeObjectFromHash
-(
- ckcapiInternalObject *io
-)
-{
- NSSItem *key = &io->hashKey;
-
- if ((nssHash *)NULL == ckcapiInternalObjectHash) {
- return;
- }
- if (key->size == 0) {
- ckcapi_FetchHashKey(io);
- }
- nssHash_Remove(ckcapiInternalObjectHash, key);
- return;
-}
-
-void
-nss_ckcapi_DestroyInternalObject
-(
- ckcapiInternalObject *io
-)
-{
- switch (io->type) {
- case ckcapiRaw:
- return;
- case ckcapiCert:
- CertFreeCertificateContext(io->u.cert.certContext);
- nss_ZFreeIf(io->u.cert.labelData);
- nss_ZFreeIf(io->u.cert.key.privateKey);
- nss_ZFreeIf(io->u.cert.key.pubKey);
- nss_ZFreeIf(io->idData);
- break;
- case ckcapiBareKey:
- nss_ZFreeIf(io->u.key.provInfo.pwszContainerName);
- nss_ZFreeIf(io->u.key.provInfo.pwszProvName);
- nss_ZFreeIf(io->u.key.provName);
- nss_ZFreeIf(io->u.key.containerName);
- nss_ZFreeIf(io->u.key.key.privateKey);
- nss_ZFreeIf(io->u.key.key.pubKey);
- if (0 != io->u.key.hProv) {
- CryptReleaseContext(io->u.key.hProv, 0);
- }
- nss_ZFreeIf(io->idData);
- break;
- }
- nss_ZFreeIf(io);
- return;
-}
-
-static ckcapiInternalObject *
-nss_ckcapi_CreateCertificate
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- NSSItem value;
- NSSItem keyID;
- char *storeStr;
- ckcapiInternalObject *io = NULL;
- PCCERT_CONTEXT certContext = NULL;
- PCCERT_CONTEXT storedCertContext = NULL;
- CRYPT_KEY_PROV_INFO *prov_info = NULL;
- char *nickname = NULL;
- HCERTSTORE hStore = 0;
- DWORD msError = 0;
- PRBool hasID;
- CK_RV dummy;
- BOOL rc;
-
- *pError = nss_ckcapi_GetAttribute(CKA_VALUE, pTemplate,
- ulAttributeCount, &value);
-
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
-
- *pError = nss_ckcapi_GetAttribute(CKA_ID, pTemplate,
- ulAttributeCount, &keyID);
-
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
-
- if (ckcapi_cert_exists(&value, &io)) {
- return io;
- }
-
- /* OK, we are creating a new one, figure out what store it belongs to..
- * first get a certContext handle.. */
- certContext = CertCreateCertificateContext(X509_ASN_ENCODING,
- value.data, value.size);
- if ((PCCERT_CONTEXT) NULL == certContext) {
- msError = GetLastError();
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
-
- /* do we have a private key laying around... */
- prov_info = ckcapi_cert_getPrivateKeyInfo(certContext, &keyID);
- if (prov_info) {
- CRYPT_DATA_BLOB msKeyID;
- storeStr = "My";
- hasID = PR_TRUE;
- rc = CertSetCertificateContextProperty(certContext,
- CERT_KEY_PROV_INFO_PROP_ID,
- 0, prov_info);
- nss_ZFreeIf(prov_info);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
- msKeyID.cbData = keyID.size;
- msKeyID.pbData = keyID.data;
- rc = CertSetCertificateContextProperty(certContext,
- CERT_KEY_IDENTIFIER_PROP_ID,
- 0, &msKeyID);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- /* does it look like a CA */
- } else if (ckcapi_cert_isCA(certContext)) {
- storeStr = ckcapi_cert_isRoot(certContext) ? "CA" : "Root";
- /* does it look like an S/MIME cert */
- } else if (ckcapi_cert_hasEmail(certContext)) {
- storeStr = "AddressBook";
- } else {
- /* just pick a store */
- storeStr = "CA";
- }
-
- /* get the nickname, not an error if we can't find it */
- nickname = nss_ckcapi_GetStringAttribute(CKA_LABEL, pTemplate,
- ulAttributeCount, &dummy);
- if (nickname) {
- LPWSTR nicknameUTF16 = NULL;
- CRYPT_DATA_BLOB nicknameBlob;
-
- nicknameUTF16 = nss_ckcapi_UTF8ToWide(nickname);
- nss_ZFreeIf(nickname);
- nickname = NULL;
- if ((LPWSTR)NULL == nicknameUTF16) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- nicknameBlob.cbData = nss_ckcapi_WideSize(nicknameUTF16);
- nicknameBlob.pbData = (BYTE *)nicknameUTF16;
- rc = CertSetCertificateContextProperty(certContext,
- CERT_FRIENDLY_NAME_PROP_ID, 0, &nicknameBlob);
- nss_ZFreeIf(nicknameUTF16);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
- }
-
- hStore = CertOpenSystemStore((HCRYPTPROV) NULL, storeStr);
- if (0 == hStore) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- rc = CertAddCertificateContextToStore(hStore, certContext,
- CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, &storedCertContext);
- CertFreeCertificateContext(certContext);
- certContext = NULL;
- CertCloseStore(hStore, 0);
- hStore = 0;
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- io = nss_ZNEW(NULL, ckcapiInternalObject);
- if ((ckcapiInternalObject *)NULL == io) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- io->type = ckcapiCert;
- io->objClass = CKO_CERTIFICATE;
- io->u.cert.certContext = storedCertContext;
- io->u.cert.hasID = hasID;
- return io;
-
-loser:
- if (certContext) {
- CertFreeCertificateContext(certContext);
- certContext = NULL;
- }
- if (storedCertContext) {
- CertFreeCertificateContext(storedCertContext);
- storedCertContext = NULL;
- }
- if (0 != hStore) {
- CertCloseStore(hStore, 0);
- }
- return (ckcapiInternalObject *)NULL;
-
-}
-
-static char *
-ckcapi_getDefaultProvider
-(
- CK_RV *pError
-)
-{
- char *name = NULL;
- BOOL rc;
- DWORD nameLength = 0;
-
- rc = CryptGetDefaultProvider(PROV_RSA_FULL, NULL, CRYPT_USER_DEFAULT, NULL,
- &nameLength);
- if (!rc) {
- return (char *)NULL;
- }
-
- name = nss_ZNEWARRAY(NULL, char, nameLength);
- if ((char *)NULL == name ) {
- return (char *)NULL;
- }
- rc = CryptGetDefaultProvider(PROV_RSA_FULL, NULL, CRYPT_USER_DEFAULT, name,
- &nameLength);
- if (!rc) {
- nss_ZFreeIf(name);
- return (char *)NULL;
- }
-
- return name;
-}
-
-static char *
-ckcapi_getContainer
-(
- CK_RV *pError,
- NSSItem *id
-)
-{
- RPC_STATUS rstat;
- UUID uuid;
- char *uuidStr;
- char *container;
-
- rstat = UuidCreate(&uuid);
- rstat = UuidToString(&uuid, &uuidStr);
-
- /* convert it from rcp memory to our own */
- container = nssUTF8_Duplicate(uuidStr, NULL);
- RpcStringFree(&uuidStr);
-
- return container;
-}
-
-static CK_RV
-ckcapi_buildPrivateKeyBlob
-(
- NSSItem *keyBlob,
- NSSItem *modulus,
- NSSItem *publicExponent,
- NSSItem *privateExponent,
- NSSItem *prime1,
- NSSItem *prime2,
- NSSItem *exponent1,
- NSSItem *exponent2,
- NSSItem *coefficient,
- PRBool isKeyExchange
-)
-{
- CAPI_RSA_KEY_BLOB *keyBlobData = NULL;
- unsigned char *target;
- unsigned long modSize = modulus->size;
- unsigned long dataSize;
- CK_RV error = CKR_OK;
-
- /* validate extras */
- if (privateExponent->size != modSize) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (prime1->size != modSize/2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (prime2->size != modSize/2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (exponent1->size != modSize/2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (exponent2->size != modSize/2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (coefficient->size != modSize/2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- dataSize = (modSize*4)+(modSize/2) + sizeof(CAPI_RSA_KEY_BLOB);
- keyBlobData = (CAPI_RSA_KEY_BLOB *)nss_ZAlloc(NULL, dataSize);
- if ((CAPI_RSA_KEY_BLOB *)NULL == keyBlobData) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- keyBlobData->header.bType = PRIVATEKEYBLOB;
- keyBlobData->header.bVersion = 0x02;
- keyBlobData->header.reserved = 0x00;
- keyBlobData->header.aiKeyAlg = isKeyExchange ? CALG_RSA_KEYX:CALG_RSA_SIGN;
- keyBlobData->rsa.magic = 0x32415352;
- keyBlobData->rsa.bitlen = modSize * 8;
- keyBlobData->rsa.pubexp = nss_ckcapi_DataToInt(publicExponent,&error);
- if (CKR_OK != error) {
- goto loser;
- }
-
- target = &keyBlobData->data[CAPI_MODULUS_OFFSET(modSize)];
- nsslibc_memcpy(target, modulus->data, modulus->size);
- modulus->data = target;
- ckcapi_ReverseData(modulus);
-
- target = &keyBlobData->data[CAPI_PRIVATE_EXP_OFFSET(modSize)];
- nsslibc_memcpy(target, privateExponent->data, privateExponent->size);
- privateExponent->data = target;
- ckcapi_ReverseData(privateExponent);
-
- target = &keyBlobData->data[CAPI_PRIME_1_OFFSET(modSize)];
- nsslibc_memcpy(target, prime1->data, prime1->size);
- prime1->data = target;
- ckcapi_ReverseData(prime1);
-
- target = &keyBlobData->data[CAPI_PRIME_2_OFFSET(modSize)];
- nsslibc_memcpy(target, prime2->data, prime2->size);
- prime2->data = target;
- ckcapi_ReverseData(prime2);
-
- target = &keyBlobData->data[CAPI_EXPONENT_1_OFFSET(modSize)];
- nsslibc_memcpy(target, exponent1->data, exponent1->size);
- exponent1->data = target;
- ckcapi_ReverseData(exponent1);
-
- target = &keyBlobData->data[CAPI_EXPONENT_2_OFFSET(modSize)];
- nsslibc_memcpy(target, exponent2->data, exponent2->size);
- exponent2->data = target;
- ckcapi_ReverseData(exponent2);
-
- target = &keyBlobData->data[CAPI_COEFFICIENT_OFFSET(modSize)];
- nsslibc_memcpy(target, coefficient->data, coefficient->size);
- coefficient->data = target;
- ckcapi_ReverseData(coefficient);
-
- keyBlob->data = keyBlobData;
- keyBlob->size = dataSize;
-
- return CKR_OK;
-
-loser:
- nss_ZFreeIf(keyBlobData);
- return error;
-}
-
-static ckcapiInternalObject *
-nss_ckcapi_CreatePrivateKey
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- NSSItem modulus;
- NSSItem publicExponent;
- NSSItem privateExponent;
- NSSItem exponent1;
- NSSItem exponent2;
- NSSItem prime1;
- NSSItem prime2;
- NSSItem coefficient;
- NSSItem keyID;
- NSSItem keyBlob;
- ckcapiInternalObject *io = NULL;
- char *providerName = NULL;
- char *containerName = NULL;
- char *idData = NULL;
- CRYPT_KEY_PROV_INFO provInfo;
- CRYPT_HASH_BLOB msKeyID;
- CK_KEY_TYPE keyType;
- HCRYPTPROV hProv = 0;
- HCRYPTKEY hKey = 0;
- PRBool decrypt;
- DWORD keySpec;
- DWORD msError;
- BOOL rc;
-
- keyType = nss_ckcapi_GetULongAttribute
- (CKA_KEY_TYPE, pTemplate, ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- if (CKK_RSA != keyType) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (ckcapiInternalObject *)NULL;
- }
-
- decrypt = nss_ckcapi_GetBoolAttribute(CKA_DECRYPT,
- pTemplate, ulAttributeCount, pError);
- if (CKR_TEMPLATE_INCOMPLETE == *pError) {
- decrypt = PR_TRUE; /* default to true */
- }
- decrypt = decrypt || nss_ckcapi_GetBoolAttribute(CKA_UNWRAP,
- pTemplate, ulAttributeCount, pError);
- if (CKR_TEMPLATE_INCOMPLETE == *pError) {
- decrypt = PR_TRUE; /* default to true */
- }
- keySpec = decrypt ? AT_KEYEXCHANGE : AT_SIGNATURE;
-
- *pError = nss_ckcapi_GetAttribute(CKA_MODULUS, pTemplate,
- ulAttributeCount, &modulus);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_PUBLIC_EXPONENT, pTemplate,
- ulAttributeCount, &publicExponent);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_PRIVATE_EXPONENT, pTemplate,
- ulAttributeCount, &privateExponent);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_PRIME_1, pTemplate,
- ulAttributeCount, &prime1);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_PRIME_2, pTemplate,
- ulAttributeCount, &prime2);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_EXPONENT_1, pTemplate,
- ulAttributeCount, &exponent1);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_EXPONENT_2, pTemplate,
- ulAttributeCount, &exponent2);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_COEFFICIENT, pTemplate,
- ulAttributeCount, &coefficient);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_ID, pTemplate,
- ulAttributeCount, &keyID);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- providerName = ckcapi_getDefaultProvider(pError);
- if ((char *)NULL == providerName ) {
- return (ckcapiInternalObject *)NULL;
- }
- containerName = ckcapi_getContainer(pError, &keyID);
- if ((char *)NULL == providerName ) {
- goto loser;
- }
- rc = CryptAcquireContext(&hProv, containerName, providerName,
- PROV_RSA_FULL, CRYPT_NEWKEYSET);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- *pError = ckcapi_buildPrivateKeyBlob(
- &keyBlob,
- &modulus,
- &publicExponent,
- &privateExponent,
- &prime1,
- &prime2,
- &exponent1,
- &exponent2,
- &coefficient,
- decrypt);
- if (CKR_OK != *pError) {
- goto loser;
- }
-
- rc = CryptImportKey(hProv, keyBlob.data, keyBlob.size,
- 0, CRYPT_EXPORTABLE, &hKey);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- idData = nss_ZNEWARRAY(NULL, char, keyID.size);
- if ((void *)NULL == idData) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- nsslibc_memcpy(idData, keyID.data, keyID.size);
-
- provInfo.pwszContainerName = nss_ckcapi_UTF8ToWide(containerName);
- provInfo.pwszProvName = nss_ckcapi_UTF8ToWide(providerName);
- provInfo.dwProvType = PROV_RSA_FULL;
- provInfo.dwFlags = 0;
- provInfo.cProvParam = 0;
- provInfo.rgProvParam = NULL;
- provInfo.dwKeySpec = keySpec;
-
- msKeyID.cbData = keyID.size;
- msKeyID.pbData = keyID.data;
-
- rc = CryptSetKeyIdentifierProperty(&msKeyID, CERT_KEY_PROV_INFO_PROP_ID,
- 0, NULL, NULL, &provInfo);
- if (!rc) {
- goto loser;
- }
-
- /* handle error here */
- io = nss_ZNEW(NULL, ckcapiInternalObject);
- if ((ckcapiInternalObject *)NULL == io) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- io->type = ckcapiBareKey;
- io->objClass = CKO_PRIVATE_KEY;
- io->u.key.provInfo = provInfo;
- io->u.key.provName = providerName;
- io->u.key.containerName = containerName;
- io->u.key.hProv = hProv; /* save the handle */
- io->idData = idData;
- io->id.data = idData;
- io->id.size = keyID.size;
- /* done with the key handle */
- CryptDestroyKey(hKey);
- return io;
-
-loser:
- nss_ZFreeIf(containerName);
- nss_ZFreeIf(providerName);
- nss_ZFreeIf(idData);
- if (0 != hProv) {
- CryptReleaseContext(hProv, 0);
- }
- if (0 != hKey) {
- CryptDestroyKey(hKey);
- }
- return (ckcapiInternalObject *)NULL;
-}
-
-
-NSS_EXTERN NSSCKMDObject *
-nss_ckcapi_CreateObject
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- CK_OBJECT_CLASS objClass;
- ckcapiInternalObject *io = NULL;
- CK_BBOOL isToken;
-
- /*
- * only create token objects
- */
- isToken = nss_ckcapi_GetBoolAttribute(CKA_TOKEN, pTemplate,
- ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- return (NSSCKMDObject *) NULL;
- }
- if (!isToken) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (NSSCKMDObject *) NULL;
- }
-
- /*
- * only create keys and certs.
- */
- objClass = nss_ckcapi_GetULongAttribute(CKA_CLASS, pTemplate,
- ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- return (NSSCKMDObject *) NULL;
- }
-#ifdef notdef
- if (objClass == CKO_PUBLIC_KEY) {
- return CKR_OK; /* fake public key creation, happens as a side effect of
- * private key creation */
- }
-#endif
- if (objClass == CKO_CERTIFICATE) {
- io = nss_ckcapi_CreateCertificate(fwSession, pTemplate,
- ulAttributeCount, pError);
- } else if (objClass == CKO_PRIVATE_KEY) {
- io = nss_ckcapi_CreatePrivateKey(fwSession, pTemplate,
- ulAttributeCount, pError);
- } else {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- if ((ckcapiInternalObject *)NULL == io) {
- return (NSSCKMDObject *) NULL;
- }
- return nss_ckcapi_CreateMDObject(NULL, io, pError);
-}
diff --git a/security/nss/lib/ckfw/capi/config.mk b/security/nss/lib/ckfw/capi/config.mk
deleted file mode 100644
index 32434cb4e..000000000
--- a/security/nss/lib/ckfw/capi/config.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-#
-# Override TARGETS variable so that only shared libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(SHARED_LIBRARY)
-LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
- SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
- RES = $(OBJDIR)/$(LIBRARY_NAME).res
- RESNAME = $(LIBRARY_NAME).rc
-endif
-
-ifdef BUILD_IDG
- DEFINES += -DNSSDEBUG
-endif
-
-#
-# To create a loadable module on Darwin, we must use -bundle.
-#
-ifeq ($(OS_TARGET),Darwin)
-ifndef USE_64
-DSO_LDOPTS = -bundle
-endif
-endif
-
diff --git a/security/nss/lib/ckfw/capi/constants.c b/security/nss/lib/ckfw/capi/constants.c
deleted file mode 100644
index 3498587fc..000000000
--- a/security/nss/lib/ckfw/capi/constants.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * ckcapi/constants.c
- *
- * Identification and other constants, all collected here in one place.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCAPI_H
-#include "nsscapi.h"
-#endif /* NSSCAPI_H */
-
-NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckcapi_CryptokiVersion = {
- NSS_CKCAPI_CRYPTOKI_VERSION_MAJOR,
- NSS_CKCAPI_CRYPTOKI_VERSION_MINOR };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckcapi_ManufacturerID = (NSSUTF8 *) "Mozilla Foundation";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckcapi_LibraryDescription = (NSSUTF8 *) "NSS Access to Microsoft Certificate Store";
-
-NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckcapi_LibraryVersion = {
- NSS_CKCAPI_LIBRARY_VERSION_MAJOR,
- NSS_CKCAPI_LIBRARY_VERSION_MINOR};
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckcapi_SlotDescription = (NSSUTF8 *) "Microsoft Certificate Store";
-
-NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckcapi_HardwareVersion = {
- NSS_CKCAPI_HARDWARE_VERSION_MAJOR,
- NSS_CKCAPI_HARDWARE_VERSION_MINOR };
-
-NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckcapi_FirmwareVersion = {
- NSS_CKCAPI_FIRMWARE_VERSION_MAJOR,
- NSS_CKCAPI_FIRMWARE_VERSION_MINOR };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckcapi_TokenLabel = (NSSUTF8 *) "Microsoft Certificate Store";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckcapi_TokenModel = (NSSUTF8 *) "1";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckcapi_TokenSerialNumber = (NSSUTF8 *) "1";
-
diff --git a/security/nss/lib/ckfw/capi/crsa.c b/security/nss/lib/ckfw/capi/crsa.c
deleted file mode 100644
index 36e2b6548..000000000
--- a/security/nss/lib/ckfw/capi/crsa.c
+++ /dev/null
@@ -1,715 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckcapi.h"
-#include "secdert.h"
-
-#define SSL3_SHAMD5_HASH_SIZE 36 /* LEN_MD5 (16) + LEN_SHA1 (20) */
-
-/*
- * ckcapi/crsa.c
- *
- * This file implements the NSSCKMDMechnaism and NSSCKMDCryptoOperation objects
- * for the RSA operation on the CAPI cryptoki module.
- */
-
-/*
- * write a Decimal value to a string
- */
-
-static char *
-putDecimalString(char *cstr, unsigned long value)
-{
- unsigned long tenpower;
- int first = 1;
-
- for (tenpower=10000000; tenpower; tenpower /= 10) {
- unsigned char digit = (unsigned char )(value/tenpower);
- value = value % tenpower;
-
- /* drop leading zeros */
- if (first && (0 == digit)) {
- continue;
- }
- first = 0;
- *cstr++ = digit + '0';
- }
-
- /* if value was zero, put one of them out */
- if (first) {
- *cstr++ = '0';
- }
- return cstr;
-}
-
-
-/*
- * Create a Capi OID string value from a DER OID
- */
-static char *
-nss_ckcapi_GetOidString
-(
- unsigned char *oidTag,
- unsigned int oidTagSize,
- CK_RV *pError
-)
-{
- unsigned char *oid;
- char *oidStr;
- char *cstr;
- unsigned long value;
- unsigned int oidSize;
-
- if (DER_OBJECT_ID != *oidTag) {
- /* wasn't an oid */
- *pError = CKR_DATA_INVALID;
- return NULL;
- }
- oid = nss_ckcapi_DERUnwrap(oidTag, oidTagSize, &oidSize, NULL);
-
- if (oidSize < 2) {
- *pError = CKR_DATA_INVALID;
- return NULL;
- }
-
- oidStr = nss_ZNEWARRAY( NULL, char, oidSize*4 );
- if ((char *)NULL == oidStr) {
- *pError = CKR_HOST_MEMORY;
- return NULL;
- }
- cstr = oidStr;
- cstr = putDecimalString(cstr, (*oid) / 40);
- *cstr++ = '.';
- cstr = putDecimalString(cstr, (*oid) % 40);
- oidSize--;
-
- value = 0;
- while (oidSize--) {
- oid++;
- value = (value << 7) + (*oid & 0x7f);
- if (0 == (*oid & 0x80)) {
- *cstr++ = '.';
- cstr = putDecimalString(cstr, value);
- value = 0;
- }
- }
-
- *cstr = 0; /* NULL terminate */
-
- if (value != 0) {
- nss_ZFreeIf(oidStr);
- *pError = CKR_DATA_INVALID;
- return NULL;
- }
- return oidStr;
-}
-
-
-/*
- * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value,
- * which includes the hash OID. CAPI expects to take a Hash Context. While
- * CAPI does have the capability of setting a raw hash value, it does not
- * have the ability to sign an arbitrary value. This function tries to
- * reduce the passed in data into something that CAPI could actually sign.
- */
-static CK_RV
-ckcapi_GetRawHash
-(
- const NSSItem *input,
- NSSItem *hash,
- ALG_ID *hashAlg
-)
-{
- unsigned char *current;
- unsigned char *algid;
- unsigned char *oid;
- unsigned char *hashData;
- char *oidStr;
- CK_RV error;
- unsigned int oidSize;
- unsigned int size;
- /*
- * there are 2 types of hashes NSS typically tries to sign, regular
- * RSA signature format (with encoded DER_OIDS), and SSL3 Signed hashes.
- * CAPI knows not to add any oids to SSL3_Signed hashes, so if we have any
- * random hash that is exactly the same size as an SSL3 hash, then we can
- * just pass the data through. CAPI has know way of knowing if the value
- * is really a combined hash or some other arbitrary data, so it's safe to
- * handle this case first.
- */
- if (SSL3_SHAMD5_HASH_SIZE == input->size) {
- hash->data = input->data;
- hash->size = input->size;
- *hashAlg = CALG_SSL3_SHAMD5;
- return CKR_OK;
- }
-
- current = (unsigned char *)input->data;
-
- /* make sure we have a sequence tag */
- if ((DER_SEQUENCE|DER_CONSTRUCTED) != *current) {
- return CKR_DATA_INVALID;
- }
-
- /* parse the input block to get 1) the hash oid, and 2) the raw hash value.
- * unfortunatly CAPI doesn't have a builtin function to do this work, so
- * we go ahead and do it by hand here.
- *
- * format is:
- * SEQUENCE {
- * SECQUENCE { // algid
- * OID {} // oid
- * ANY {} // optional params
- * }
- * OCTECT {} // hash
- */
-
- /* unwrap */
- algid = nss_ckcapi_DERUnwrap(current,input->size, &size, NULL);
-
- if (algid+size != current+input->size) {
- /* make sure there is not extra data at the end */
- return CKR_DATA_INVALID;
- }
-
- if ((DER_SEQUENCE|DER_CONSTRUCTED) != *algid) {
- /* wasn't an algid */
- return CKR_DATA_INVALID;
- }
- oid = nss_ckcapi_DERUnwrap(algid, size, &oidSize, &hashData);
-
- if (DER_OCTET_STRING != *hashData) {
- /* wasn't a hash */
- return CKR_DATA_INVALID;
- }
-
- /* get the real hash */
- current = hashData;
- size = size - (hashData-algid);
- hash->data = nss_ckcapi_DERUnwrap(current, size, &hash->size, NULL);
-
- /* get the real oid as a string. Again, Microsoft does not
- * export anything that does this for us */
- oidStr = nss_ckcapi_GetOidString(oid, oidSize, &error);
- if ((char *)NULL == oidStr ) {
- return error;
- }
-
- /* look up the hash alg from the oid (fortunately CAPI does to this) */
- *hashAlg = CertOIDToAlgId(oidStr);
- nss_ZFreeIf(oidStr);
- if (0 == *hashAlg) {
- return CKR_HOST_MEMORY;
- }
-
- /* hash looks reasonably consistent, we should be able to sign it now */
- return CKR_OK;
-}
-
-/*
- * So everyone else in the worlds stores their bignum data MSB first, but not
- * Microsoft, we need to byte swap everything coming into and out of CAPI.
- */
-void
-ckcapi_ReverseData(NSSItem *item)
-{
- int end = (item->size)-1;
- int middle = (item->size)/2;
- unsigned char *buf = item->data;
- int i;
-
- for (i=0; i < middle; i++) {
- unsigned char tmp = buf[i];
- buf[i] = buf[end-i];
- buf[end-i] = tmp;
- }
- return;
-}
-
-typedef struct ckcapiInternalCryptoOperationRSAPrivStr
- ckcapiInternalCryptoOperationRSAPriv;
-struct ckcapiInternalCryptoOperationRSAPrivStr
-{
- NSSCKMDCryptoOperation mdOperation;
- NSSCKMDMechanism *mdMechanism;
- ckcapiInternalObject *iKey;
- HCRYPTPROV hProv;
- DWORD keySpec;
- HCRYPTKEY hKey;
- NSSItem *buffer;
-};
-
-/*
- * ckcapi_mdCryptoOperationRSAPriv_Create
- */
-static NSSCKMDCryptoOperation *
-ckcapi_mdCryptoOperationRSAPriv_Create
-(
- const NSSCKMDCryptoOperation *proto,
- NSSCKMDMechanism *mdMechanism,
- NSSCKMDObject *mdKey,
- CK_RV *pError
-)
-{
- ckcapiInternalObject *iKey = (ckcapiInternalObject *)mdKey->etc;
- const NSSItem *classItem = nss_ckcapi_FetchAttribute(iKey, CKA_CLASS);
- const NSSItem *keyType = nss_ckcapi_FetchAttribute(iKey, CKA_KEY_TYPE);
- ckcapiInternalCryptoOperationRSAPriv *iOperation;
- CK_RV error;
- HCRYPTPROV hProv;
- DWORD keySpec;
- HCRYPTKEY hKey;
-
- /* make sure we have the right objects */
- if (((const NSSItem *)NULL == classItem) ||
- (sizeof(CK_OBJECT_CLASS) != classItem->size) ||
- (CKO_PRIVATE_KEY != *(CK_OBJECT_CLASS *)classItem->data) ||
- ((const NSSItem *)NULL == keyType) ||
- (sizeof(CK_KEY_TYPE) != keyType->size) ||
- (CKK_RSA != *(CK_KEY_TYPE *)keyType->data)) {
- *pError = CKR_KEY_TYPE_INCONSISTENT;
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- error = nss_ckcapi_FetchKeyContainer(iKey, &hProv, &keySpec, &hKey);
- if (error != CKR_OK) {
- *pError = error;
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- iOperation = nss_ZNEW(NULL, ckcapiInternalCryptoOperationRSAPriv);
- if ((ckcapiInternalCryptoOperationRSAPriv *)NULL == iOperation) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDCryptoOperation *)NULL;
- }
- iOperation->mdMechanism = mdMechanism;
- iOperation->iKey = iKey;
- iOperation->hProv = hProv;
- iOperation->keySpec = keySpec;
- iOperation->hKey = hKey;
-
- nsslibc_memcpy(&iOperation->mdOperation,
- proto, sizeof(NSSCKMDCryptoOperation));
- iOperation->mdOperation.etc = iOperation;
-
- return &iOperation->mdOperation;
-}
-
-static CK_RV
-ckcapi_mdCryptoOperationRSAPriv_Destroy
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
-
- if (iOperation->hKey) {
- CryptDestroyKey(iOperation->hKey);
- }
- if (iOperation->buffer) {
- nssItem_Destroy(iOperation->buffer);
- }
- nss_ZFreeIf(iOperation);
- return CKR_OK;
-}
-
-static CK_ULONG
-ckcapi_mdCryptoOperationRSA_GetFinalLength
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
- const NSSItem *modulus =
- nss_ckcapi_FetchAttribute(iOperation->iKey, CKA_MODULUS);
-
- return modulus->size;
-}
-
-
-/*
- * ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength
- * we won't know the length until we actually decrypt the
- * input block. Since we go to all the work to decrypt the
- * the block, we'll save if for when the block is asked for
- */
-static CK_ULONG
-ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- CK_RV *pError
-)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
- BOOL rc;
-
- /* Microsoft's Decrypt operation works in place. Since we don't want
- * to trash our input buffer, we make a copy of it */
- iOperation->buffer = nssItem_Duplicate((NSSItem *)input, NULL, NULL);
- if ((NSSItem *) NULL == iOperation->buffer) {
- *pError = CKR_HOST_MEMORY;
- return 0;
- }
- /* Sigh, reverse it */
- ckcapi_ReverseData(iOperation->buffer);
-
- rc = CryptDecrypt(iOperation->hKey, 0, TRUE, 0,
- iOperation->buffer->data, &iOperation->buffer->size);
- if (!rc) {
- DWORD msError = GetLastError();
- switch (msError) {
- case NTE_BAD_DATA:
- *pError = CKR_ENCRYPTED_DATA_INVALID;
- break;
- case NTE_FAIL:
- case NTE_BAD_UID:
- *pError = CKR_DEVICE_ERROR;
- break;
- default:
- *pError = CKR_GENERAL_ERROR;
- }
- return 0;
- }
-
- return iOperation->buffer->size;
-}
-
-/*
- * ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal
- *
- * NOTE: ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength is presumed to
- * have been called previously.
- */
-static CK_RV
-ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- NSSItem *output
-)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
- NSSItem *buffer = iOperation->buffer;
-
- if ((NSSItem *)NULL == buffer) {
- return CKR_GENERAL_ERROR;
- }
- nsslibc_memcpy(output->data, buffer->data, buffer->size);
- output->size = buffer->size;
- return CKR_OK;
-}
-
-/*
- * ckcapi_mdCryptoOperationRSASign_UpdateFinal
- *
- */
-static CK_RV
-ckcapi_mdCryptoOperationRSASign_UpdateFinal
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- NSSItem *output
-)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
- CK_RV error = CKR_OK;
- DWORD msError;
- NSSItem hash;
- HCRYPTHASH hHash = 0;
- ALG_ID hashAlg;
- DWORD hashSize;
- DWORD len; /* temp length value we throw away */
- BOOL rc;
-
- /*
- * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value,
- * which includes the hash OID. CAPI expects to take a Hash Context. While
- * CAPI does have the capability of setting a raw hash value, it does not
- * have the ability to sign an arbitrary value. This function tries to
- * reduce the passed in data into something that CAPI could actually sign.
- */
- error = ckcapi_GetRawHash(input, &hash, &hashAlg);
- if (CKR_OK != error) {
- goto loser;
- }
-
- rc = CryptCreateHash(iOperation->hProv, hashAlg, 0, 0, &hHash);
- if (!rc) {
- goto loser;
- }
-
- /* make sure the hash lens match before we set it */
- len = sizeof(DWORD);
- rc = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize, &len, 0);
- if (!rc) {
- goto loser;
- }
-
- if (hash.size != hashSize) {
- /* The input must have been bad for this to happen */
- error = CKR_DATA_INVALID;
- goto loser;
- }
-
- /* we have an explicit hash, set it, note that the length is
- * implicit by the hashAlg used in create */
- rc = CryptSetHashParam(hHash, HP_HASHVAL, hash.data, 0);
- if (!rc) {
- goto loser;
- }
-
- /* OK, we have the data in a hash structure, sign it! */
- rc = CryptSignHash(hHash, iOperation->keySpec, NULL, 0,
- output->data, &output->size);
- if (!rc) {
- goto loser;
- }
-
- /* Don't return a signature that might have been broken because of a cosmic
- * ray, or a broken processor, verify that it is valid... */
- rc = CryptVerifySignature(hHash, output->data, output->size,
- iOperation->hKey, NULL, 0);
- if (!rc) {
- goto loser;
- }
-
- /* OK, Microsoft likes to do things completely differently than anyone
- * else. We need to reverse the data we received here */
- ckcapi_ReverseData(output);
- CryptDestroyHash(hHash);
- return CKR_OK;
-
-loser:
- /* map the microsoft error */
- if (CKR_OK == error) {
- msError = GetLastError();
- switch (msError) {
- case ERROR_NOT_ENOUGH_MEMORY:
- error = CKR_HOST_MEMORY;
- break;
- case NTE_NO_MEMORY:
- error = CKR_DEVICE_MEMORY;
- break;
- case ERROR_MORE_DATA:
- return CKR_BUFFER_TOO_SMALL;
- case ERROR_INVALID_PARAMETER: /* these params were derived from the */
- case ERROR_INVALID_HANDLE: /* inputs, so if they are bad, the input */
- case NTE_BAD_ALGID: /* data is bad */
- case NTE_BAD_HASH:
- error = CKR_DATA_INVALID;
- break;
- case ERROR_BUSY:
- case NTE_FAIL:
- case NTE_BAD_UID:
- error = CKR_DEVICE_ERROR;
- break;
- default:
- error = CKR_GENERAL_ERROR;
- break;
- }
- }
- if (hHash) {
- CryptDestroyHash(hHash);
- }
- return error;
-}
-
-
-NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
-ckcapi_mdCryptoOperationRSADecrypt_proto = {
- NULL, /* etc */
- ckcapi_mdCryptoOperationRSAPriv_Destroy,
- NULL, /* GetFinalLengh - not needed for one shot Decrypt/Encrypt */
- ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength,
- NULL, /* Final - not needed for one shot operation */
- NULL, /* Update - not needed for one shot operation */
- NULL, /* DigetUpdate - not needed for one shot operation */
- ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal,
- NULL, /* UpdateCombo - not needed for one shot operation */
- NULL, /* DigetKey - not needed for one shot operation */
- (void *)NULL /* null terminator */
-};
-
-NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
-ckcapi_mdCryptoOperationRSASign_proto = {
- NULL, /* etc */
- ckcapi_mdCryptoOperationRSAPriv_Destroy,
- ckcapi_mdCryptoOperationRSA_GetFinalLength,
- NULL, /* GetOperationLengh - not needed for one shot Sign/Verify */
- NULL, /* Final - not needed for one shot operation */
- NULL, /* Update - not needed for one shot operation */
- NULL, /* DigetUpdate - not needed for one shot operation */
- ckcapi_mdCryptoOperationRSASign_UpdateFinal,
- NULL, /* UpdateCombo - not needed for one shot operation */
- NULL, /* DigetKey - not needed for one shot operation */
- (void *)NULL /* null terminator */
-};
-
-/********** NSSCKMDMechansim functions ***********************/
-/*
- * ckcapi_mdMechanismRSA_Destroy
- */
-static void
-ckcapi_mdMechanismRSA_Destroy
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_ZFreeIf(fwMechanism);
-}
-
-/*
- * ckcapi_mdMechanismRSA_GetMinKeySize
- */
-static CK_ULONG
-ckcapi_mdMechanismRSA_GetMinKeySize
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return 384;
-}
-
-/*
- * ckcapi_mdMechanismRSA_GetMaxKeySize
- */
-static CK_ULONG
-ckcapi_mdMechanismRSA_GetMaxKeySize
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return 16384;
-}
-
-/*
- * ckcapi_mdMechanismRSA_DecryptInit
- */
-static NSSCKMDCryptoOperation *
-ckcapi_mdMechanismRSA_DecryptInit
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
-)
-{
- return ckcapi_mdCryptoOperationRSAPriv_Create(
- &ckcapi_mdCryptoOperationRSADecrypt_proto,
- mdMechanism, mdKey, pError);
-}
-
-/*
- * ckcapi_mdMechanismRSA_SignInit
- */
-static NSSCKMDCryptoOperation *
-ckcapi_mdMechanismRSA_SignInit
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
-)
-{
- return ckcapi_mdCryptoOperationRSAPriv_Create(
- &ckcapi_mdCryptoOperationRSASign_proto,
- mdMechanism, mdKey, pError);
-}
-
-
-NSS_IMPLEMENT_DATA const NSSCKMDMechanism
-nss_ckcapi_mdMechanismRSA = {
- (void *)NULL, /* etc */
- ckcapi_mdMechanismRSA_Destroy,
- ckcapi_mdMechanismRSA_GetMinKeySize,
- ckcapi_mdMechanismRSA_GetMaxKeySize,
- NULL, /* GetInHardware - default false */
- NULL, /* EncryptInit - default errs */
- ckcapi_mdMechanismRSA_DecryptInit,
- NULL, /* DigestInit - default errs*/
- ckcapi_mdMechanismRSA_SignInit,
- NULL, /* VerifyInit - default errs */
- ckcapi_mdMechanismRSA_SignInit, /* SignRecoverInit */
- NULL, /* VerifyRecoverInit - default errs */
- NULL, /* GenerateKey - default errs */
- NULL, /* GenerateKeyPair - default errs */
- NULL, /* GetWrapKeyLength - default errs */
- NULL, /* WrapKey - default errs */
- NULL, /* UnwrapKey - default errs */
- NULL, /* DeriveKey - default errs */
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/capi/csession.c b/security/nss/lib/ckfw/capi/csession.c
deleted file mode 100644
index 523449438..000000000
--- a/security/nss/lib/ckfw/capi/csession.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckcapi.h"
-
-/*
- * ckcapi/csession.c
- *
- * This file implements the NSSCKMDSession object for the
- * "nss to capi" cryptoki module.
- */
-
-static NSSCKMDFindObjects *
-ckcapi_mdSession_FindObjectsInit
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- return nss_ckcapi_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
-}
-
-static NSSCKMDObject *
-ckcapi_mdSession_CreateObject
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- return nss_ckcapi_CreateObject(fwSession, pTemplate, ulAttributeCount, pError);
-}
-
-NSS_IMPLEMENT NSSCKMDSession *
-nss_ckcapi_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
-{
- NSSArena *arena;
- NSSCKMDSession *rv;
-
- arena = NSSCKFWSession_GetArena(fwSession, pError);
- if( (NSSArena *)NULL == arena ) {
- return (NSSCKMDSession *)NULL;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDSession);
- if( (NSSCKMDSession *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDSession *)NULL;
- }
-
- /*
- * rv was zeroed when allocated, so we only
- * need to set the non-zero members.
- */
-
- rv->etc = (void *)fwSession;
- /* rv->Close */
- /* rv->GetDeviceError */
- /* rv->Login */
- /* rv->Logout */
- /* rv->InitPIN */
- /* rv->SetPIN */
- /* rv->GetOperationStateLen */
- /* rv->GetOperationState */
- /* rv->SetOperationState */
- rv->CreateObject = ckcapi_mdSession_CreateObject;
- /* rv->CopyObject */
- rv->FindObjectsInit = ckcapi_mdSession_FindObjectsInit;
- /* rv->SeedRandom */
- /* rv->GetRandom */
- /* rv->null */
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/capi/cslot.c b/security/nss/lib/ckfw/capi/cslot.c
deleted file mode 100644
index 88ed64789..000000000
--- a/security/nss/lib/ckfw/capi/cslot.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckcapi.h"
-
-/*
- * ckcapi/cslot.c
- *
- * This file implements the NSSCKMDSlot object for the
- * "nss to capi" cryptoki module.
- */
-
-static NSSUTF8 *
-ckcapi_mdSlot_GetSlotDescription
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckcapi_SlotDescription;
-}
-
-static NSSUTF8 *
-ckcapi_mdSlot_GetManufacturerID
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
-}
-
-static CK_VERSION
-ckcapi_mdSlot_GetHardwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckcapi_HardwareVersion;
-}
-
-static CK_VERSION
-ckcapi_mdSlot_GetFirmwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckcapi_FirmwareVersion;
-}
-
-static NSSCKMDToken *
-ckcapi_mdSlot_GetToken
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSCKMDToken *)&nss_ckcapi_mdToken;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDSlot
-nss_ckcapi_mdSlot = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Destroy */
- ckcapi_mdSlot_GetSlotDescription,
- ckcapi_mdSlot_GetManufacturerID,
- NULL, /* GetTokenPresent -- defaults to true */
- NULL, /* GetRemovableDevice -- defaults to false */
- NULL, /* GetHardwareSlot -- defaults to false */
- ckcapi_mdSlot_GetHardwareVersion,
- ckcapi_mdSlot_GetFirmwareVersion,
- ckcapi_mdSlot_GetToken,
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/capi/ctoken.c b/security/nss/lib/ckfw/capi/ctoken.c
deleted file mode 100644
index 14c89557b..000000000
--- a/security/nss/lib/ckfw/capi/ctoken.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckcapi.h"
-
-/*
- * ckcapi/ctoken.c
- *
- * This file implements the NSSCKMDToken object for the
- * "nss to capi" cryptoki module.
- */
-
-static NSSUTF8 *
-ckcapi_mdToken_GetLabel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckcapi_TokenLabel;
-}
-
-static NSSUTF8 *
-ckcapi_mdToken_GetManufacturerID
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
-}
-
-static NSSUTF8 *
-ckcapi_mdToken_GetModel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckcapi_TokenModel;
-}
-
-static NSSUTF8 *
-ckcapi_mdToken_GetSerialNumber
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckcapi_TokenSerialNumber;
-}
-
-static CK_BBOOL
-ckcapi_mdToken_GetIsWriteProtected
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_FALSE;
-}
-
-/* fake out Mozilla so we don't try to initialize the token */
-static CK_BBOOL
-ckcapi_mdToken_GetUserPinInitialized
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_TRUE;
-}
-
-static CK_VERSION
-ckcapi_mdToken_GetHardwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckcapi_HardwareVersion;
-}
-
-static CK_VERSION
-ckcapi_mdToken_GetFirmwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckcapi_FirmwareVersion;
-}
-
-static NSSCKMDSession *
-ckcapi_mdToken_OpenSession
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_BBOOL rw,
- CK_RV *pError
-)
-{
- return nss_ckcapi_CreateSession(fwSession, pError);
-}
-
-static CK_ULONG
-ckcapi_mdToken_GetMechanismCount
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return (CK_ULONG)1;
-}
-
-static CK_RV
-ckcapi_mdToken_GetMechanismTypes
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE types[]
-)
-{
- types[0] = CKM_RSA_PKCS;
- return CKR_OK;
-}
-
-static NSSCKMDMechanism *
-ckcapi_mdToken_GetMechanism
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE which,
- CK_RV *pError
-)
-{
- if (which != CKM_RSA_PKCS) {
- *pError = CKR_MECHANISM_INVALID;
- return (NSSCKMDMechanism *)NULL;
- }
- return (NSSCKMDMechanism *)&nss_ckcapi_mdMechanismRSA;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDToken
-nss_ckcapi_mdToken = {
- (void *)NULL, /* etc */
- NULL, /* Setup */
- NULL, /* Invalidate */
- NULL, /* InitToken -- default errs */
- ckcapi_mdToken_GetLabel,
- ckcapi_mdToken_GetManufacturerID,
- ckcapi_mdToken_GetModel,
- ckcapi_mdToken_GetSerialNumber,
- NULL, /* GetHasRNG -- default is false */
- ckcapi_mdToken_GetIsWriteProtected,
- NULL, /* GetLoginRequired -- default is false */
- ckcapi_mdToken_GetUserPinInitialized,
- NULL, /* GetRestoreKeyNotNeeded -- irrelevant */
- NULL, /* GetHasClockOnToken -- default is false */
- NULL, /* GetHasProtectedAuthenticationPath -- default is false */
- NULL, /* GetSupportsDualCryptoOperations -- default is false */
- NULL, /* GetMaxSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetMaxRwSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetMaxPinLen -- irrelevant */
- NULL, /* GetMinPinLen -- irrelevant */
- NULL, /* GetTotalPublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetFreePublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetTotalPrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetFreePrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
- ckcapi_mdToken_GetHardwareVersion,
- ckcapi_mdToken_GetFirmwareVersion,
- NULL, /* GetUTCTime -- no clock */
- ckcapi_mdToken_OpenSession,
- ckcapi_mdToken_GetMechanismCount,
- ckcapi_mdToken_GetMechanismTypes,
- ckcapi_mdToken_GetMechanism,
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/capi/manifest.mn b/security/nss/lib/ckfw/capi/manifest.mn
deleted file mode 100644
index ee19583ea..000000000
--- a/security/nss/lib/ckfw/capi/manifest.mn
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-CORE_DEPTH = ../../../..
-
-MODULE = nss
-MAPFILE = $(OBJDIR)/nsscapi.def
-
-EXPORTS = \
- nsscapi.h \
- $(NULL)
-
-CSRCS = \
- anchor.c \
- constants.c \
- cfind.c \
- cinst.c \
- cobject.c \
- crsa.c \
- csession.c \
- cslot.c \
- ctoken.c \
- ckcapiver.c \
- staticobj.c \
- $(NULL)
-
-REQUIRES = nspr
-
-LIBRARY_NAME = nsscapi
-
-#EXTRA_SHARED_LIBS = -L$(DIST)/lib -lnssckfw -lnssb -lplc4 -lplds4
diff --git a/security/nss/lib/ckfw/capi/nsscapi.def b/security/nss/lib/ckfw/capi/nsscapi.def
deleted file mode 100644
index d7e68c7f4..000000000
--- a/security/nss/lib/ckfw/capi/nsscapi.def
+++ /dev/null
@@ -1,26 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+
-;+NSS_3.1 { # NSS 3.1 release
-;+ global:
-LIBRARY nsscapi ;-
-EXPORTS ;-
-C_GetFunctionList;
-;+ local:
-;+*;
-;+};
diff --git a/security/nss/lib/ckfw/capi/nsscapi.h b/security/nss/lib/ckfw/capi/nsscapi.h
deleted file mode 100644
index d98312031..000000000
--- a/security/nss/lib/ckfw/capi/nsscapi.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSCAPI_H
-#define NSSCAPI_H
-
-/*
- * NSS CKCAPI Version numbers.
- *
- * These are the version numbers for the capi module packaged with
- * this release on NSS. To determine the version numbers of the builtin
- * module you are using, use the appropriate PKCS #11 calls.
- *
- * These version numbers detail changes to the PKCS #11 interface. They map
- * to the PKCS #11 spec versions.
- */
-#define NSS_CKCAPI_CRYPTOKI_VERSION_MAJOR 2
-#define NSS_CKCAPI_CRYPTOKI_VERSION_MINOR 20
-
-/* These version numbers detail the changes
- * to the list of trusted certificates.
- *
- * NSS_CKCAPI_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear
- * whether we may use its full range (0-255) or only 0-99 because
- * of the comment in the CK_VERSION type definition.
- */
-#define NSS_CKCAPI_LIBRARY_VERSION_MAJOR 1
-#define NSS_CKCAPI_LIBRARY_VERSION_MINOR 1
-#define NSS_CKCAPI_LIBRARY_VERSION "1.1"
-
-/* These version numbers detail the semantic changes to the ckfw engine. */
-#define NSS_CKCAPI_HARDWARE_VERSION_MAJOR 1
-#define NSS_CKCAPI_HARDWARE_VERSION_MINOR 0
-
-/* These version numbers detail the semantic changes to ckbi itself
- * (new PKCS #11 objects), etc. */
-#define NSS_CKCAPI_FIRMWARE_VERSION_MAJOR 1
-#define NSS_CKCAPI_FIRMWARE_VERSION_MINOR 0
-
-#endif /* NSSCKBI_H */
diff --git a/security/nss/lib/ckfw/capi/nsscapi.rc b/security/nss/lib/ckfw/capi/nsscapi.rc
deleted file mode 100644
index 27912009b..000000000
--- a/security/nss/lib/ckfw/capi/nsscapi.rc
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsscapi.h"
-#include <winver.h>
-
-#define MY_LIBNAME "nsscapi"
-#define MY_FILEDESCRIPTION "NSS Access to Microsoft CAPI"
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if NSS_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION NSS_CKCAPI_LIBRARY_VERSION_MAJOR,NSS_CKCAPI_LIBRARY_VERSION_MINOR,0,0
- PRODUCTVERSION NSS_CKCAPI_LIBRARY_VERSION_MAJOR,NSS_CKCAPI_LIBRARY_VERSION_MINOR,0,0
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Mozilla Foundation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", NSS_CKCAPI_LIBRARY_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", NSS_CKCAPI_LIBRARY_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/ckfw/capi/staticobj.c b/security/nss/lib/ckfw/capi/staticobj.c
deleted file mode 100644
index 3aed513cc..000000000
--- a/security/nss/lib/ckfw/capi/staticobj.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$""; @(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef CKCAPI_H
-#include "ckcapi.h"
-#endif /* CKCAPI_H */
-
-static const CK_TRUST ckt_netscape_valid = CKT_NETSCAPE_VALID;
-static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
-static const CK_TRUST ckt_netscape_trusted_delegator = CKT_NETSCAPE_TRUSTED_DELEGATOR;
-static const CK_OBJECT_CLASS cko_netscape_trust = CKO_NETSCAPE_TRUST;
-static const CK_BBOOL ck_true = CK_TRUE;
-static const CK_OBJECT_CLASS cko_data = CKO_DATA;
-static const CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509;
-static const CK_BBOOL ck_false = CK_FALSE;
-static const CK_OBJECT_CLASS cko_netscape_builtin_root_list = CKO_NETSCAPE_BUILTIN_ROOT_LIST;
-
-/* example of a static object */
-static const CK_ATTRIBUTE_TYPE nss_ckcapi_types_1 [] = {
- CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL
-};
-
-static const NSSItem nss_ckcapi_items_1 [] = {
- { (void *)&cko_data, (PRUint32)sizeof(CK_OBJECT_CLASS) },
- { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)"Mozilla CAPI Access", (PRUint32)20 }
-};
-
-ckcapiInternalObject nss_ckcapi_data[] = {
- { ckcapiRaw,
- { 5, nss_ckcapi_types_1, nss_ckcapi_items_1} ,
- },
-
-};
-
-const PRUint32 nss_ckcapi_nObjects = 1;
diff --git a/security/nss/lib/ckfw/ck.api b/security/nss/lib/ckfw/ck.api
deleted file mode 100644
index d93bcd354..000000000
--- a/security/nss/lib/ckfw/ck.api
+++ /dev/null
@@ -1,543 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# This file is in part derived from a file "pkcs11f.h" made available
-# by RSA Security at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11f.h
-
-CVS_ID "@(#) $RCSfile$ $Revision$ $Date$"
-
-# Fields
-# FUNCTION introduces a Cryptoki function
-# CK_type specifies and introduces an argument
-#
-
-# General-purpose
-
-# C_Initialize initializes the Cryptoki library.
-FUNCTION C_Initialize
-CK_VOID_PTR pInitArgs # if this is not NULL_PTR, it gets
- # cast to CK_C_INITIALIZE_ARGS_PTR
- # and dereferenced
-
-# C_Finalize indicates that an application is done with the
-# Cryptoki library.
-FUNCTION C_Finalize
-CK_VOID_PTR pReserved # reserved. Should be NULL_PTR
-
-# C_GetInfo returns general information about Cryptoki.
-FUNCTION C_GetInfo
-CK_INFO_PTR pInfo # location that receives information
-
-# C_GetFunctionList returns the function list.
-FUNCTION C_GetFunctionList
-CK_FUNCTION_LIST_PTR_PTR ppFunctionList # receives pointer to function
- # list
-
-
-# Slot and token management
-
-# C_GetSlotList obtains a list of slots in the system.
-FUNCTION C_GetSlotList
-CK_BBOOL tokenPresent # only slots with tokens?
-CK_SLOT_ID_PTR pSlotList # receives array of slot IDs
-CK_ULONG_PTR pulCount # receives number of slots
-
-# C_GetSlotInfo obtains information about a particular slot in the
-# system.
-FUNCTION C_GetSlotInfo
-CK_SLOT_ID slotID # the ID of the slot
-CK_SLOT_INFO_PTR pInfo # receives the slot information
-
-# C_GetTokenInfo obtains information about a particular token in the
-# system.
-FUNCTION C_GetTokenInfo
-CK_SLOT_ID slotID # ID of the token's slot
-CK_TOKEN_INFO_PTR pInfo # receives the token information
-
-# C_GetMechanismList obtains a list of mechanism types supported by a
-# token.
-FUNCTION C_GetMechanismList
-CK_SLOT_ID slotID # ID of token's slot
-CK_MECHANISM_TYPE_PTR pMechanismList # gets mech. array
-CK_ULONG_PTR pulCount # gets # of mechs.
-
-# C_GetMechanismInfo obtains information about a particular mechanism
-# possibly supported by a token.
-FUNCTION C_GetMechanismInfo
-CK_SLOT_ID slotID # ID of the token's slot
-CK_MECHANISM_TYPE type # type of mechanism
-CK_MECHANISM_INFO_PTR pInfo # receives mechanism info
-
-# C_InitToken initializes a token.
-FUNCTION C_InitToken
-CK_SLOT_ID slotID # ID of the token's slot
-CK_CHAR_PTR pPin # the SO's initial PIN
-CK_ULONG ulPinLen # length in bytes of the PIN
-CK_CHAR_PTR pLabel # 32-byte token label (blank padded)
-
-# C_InitPIN initializes the normal user's PIN.
-FUNCTION C_InitPIN
-CK_SESSION_HANDLE hSession # the session's handle
-CK_CHAR_PTR pPin # the normal user's PIN
-CK_ULONG ulPinLen # length in bytes of the PIN
-
-# C_SetPIN modifies the PIN of the user who is logged in.
-FUNCTION C_SetPIN
-CK_SESSION_HANDLE hSession # the session's handle
-CK_CHAR_PTR pOldPin # the old PIN
-CK_ULONG ulOldLen # length of the old PIN
-CK_CHAR_PTR pNewPin # the new PIN
-CK_ULONG ulNewLen # length of the new PIN
-
-
-# Session management
-
-# C_OpenSession opens a session between an application and a token.
-FUNCTION C_OpenSession
-CK_SLOT_ID slotID # the slot's ID
-CK_FLAGS flags # from CK_SESSION_INFO
-CK_VOID_PTR pApplication # passed to callback
-CK_NOTIFY Notify # callback function
-CK_SESSION_HANDLE_PTR phSession # gets session handle
-
-# C_CloseSession closes a session between an application and a token.
-FUNCTION C_CloseSession
-CK_SESSION_HANDLE hSession # the session's handle
-
-# C_CloseAllSessions closes all sessions with a token.
-FUNCTION C_CloseAllSessions
-CK_SLOT_ID slotID # the token's slot
-
-# C_GetSessionInfo obtains information about the session.
-FUNCTION C_GetSessionInfo
-CK_SESSION_HANDLE hSession # the session's handle
-CK_SESSION_INFO_PTR pInfo # receives session info
-
-# C_GetOperationState obtains the state of the cryptographic
-# operation in a session.
-FUNCTION C_GetOperationState
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pOperationState # gets state
-CK_ULONG_PTR pulOperationStateLen # gets state length
-
-# C_SetOperationState restores the state of the cryptographic
-# operation in a session.
-FUNCTION C_SetOperationState
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pOperationState # holds state
-CK_ULONG ulOperationStateLen # holds state length
-CK_OBJECT_HANDLE hEncryptionKey # en/decryption key
-CK_OBJECT_HANDLE hAuthenticationKey # sign/verify key
-
-# C_Login logs a user into a token.
-FUNCTION C_Login
-CK_SESSION_HANDLE hSession # the session's handle
-CK_USER_TYPE userType # the user type
-CK_CHAR_PTR pPin # the user's PIN
-CK_ULONG ulPinLen # the length of the PIN
-
-# C_Logout logs a user out from a token.
-FUNCTION C_Logout
-CK_SESSION_HANDLE hSession # the session's handle
-
-
-# Object management
-
-# C_CreateObject creates a new object.
-FUNCTION C_CreateObject
-CK_SESSION_HANDLE hSession # the session's handle
-CK_ATTRIBUTE_PTR pTemplate # the object's template
-CK_ULONG ulCount # attributes in template
-CK_OBJECT_HANDLE_PTR phObject # gets new object's handle.
-
-# C_CopyObject copies an object, creating a new object for the copy.
-FUNCTION C_CopyObject
-CK_SESSION_HANDLE hSession # the session's handle
-CK_OBJECT_HANDLE hObject # the object's handle
-CK_ATTRIBUTE_PTR pTemplate # template for new object
-CK_ULONG ulCount # attributes in template
-CK_OBJECT_HANDLE_PTR phNewObject # receives handle of copy
-
-# C_DestroyObject destroys an object.
-FUNCTION C_DestroyObject
-CK_SESSION_HANDLE hSession # the session's handle
-CK_OBJECT_HANDLE hObject # the object's handle
-
-# C_GetObjectSize gets the size of an object in bytes.
-FUNCTION C_GetObjectSize
-CK_SESSION_HANDLE hSession # the session's handle
-CK_OBJECT_HANDLE hObject # the object's handle
-CK_ULONG_PTR pulSize # receives size of object
-
-# C_GetAttributeValue obtains the value of one or more object
-# attributes.
-FUNCTION C_GetAttributeValue
-CK_SESSION_HANDLE hSession # the session's handle
-CK_OBJECT_HANDLE hObject # the object's handle
-CK_ATTRIBUTE_PTR pTemplate # specifies attrs; gets vals
-CK_ULONG ulCount # attributes in template
-
-# C_SetAttributeValue modifies the value of one or more object
-# attributes
-FUNCTION C_SetAttributeValue
-CK_SESSION_HANDLE hSession # the session's handle
-CK_OBJECT_HANDLE hObject # the object's handle
-CK_ATTRIBUTE_PTR pTemplate # specifies attrs and values
-CK_ULONG ulCount # attributes in template
-
-# C_FindObjectsInit initializes a search for token and session
-# objects that match a template.
-FUNCTION C_FindObjectsInit
-CK_SESSION_HANDLE hSession # the session's handle
-CK_ATTRIBUTE_PTR pTemplate # attribute values to match
-CK_ULONG ulCount # attrs in search template
-
-# C_FindObjects continues a search for token and session objects that
-# match a template, obtaining additional object handles.
-FUNCTION C_FindObjects
-CK_SESSION_HANDLE hSession # session's handle
-CK_OBJECT_HANDLE_PTR phObject # gets obj. handles
-CK_ULONG ulMaxObjectCount # max handles to get
-CK_ULONG_PTR pulObjectCount # actual # returned
-
-# C_FindObjectsFinal finishes a search for token and session objects.
-FUNCTION C_FindObjectsFinal
-CK_SESSION_HANDLE hSession # the session's handle
-
-
-# Encryption and decryption
-
-# C_EncryptInit initializes an encryption operation.
-FUNCTION C_EncryptInit
-CK_SESSION_HANDLE hSession # the session's handle
-CK_MECHANISM_PTR pMechanism # the encryption mechanism
-CK_OBJECT_HANDLE hKey # handle of encryption key
-
-# C_Encrypt encrypts single-part data.
-FUNCTION C_Encrypt
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pData # the plaintext data
-CK_ULONG ulDataLen # bytes of plaintext
-CK_BYTE_PTR pEncryptedData # gets ciphertext
-CK_ULONG_PTR pulEncryptedDataLen # gets c-text size
-
-# C_EncryptUpdate continues a multiple-part encryption operation.
-FUNCTION C_EncryptUpdate
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pPart # the plaintext data
-CK_ULONG ulPartLen # plaintext data len
-CK_BYTE_PTR pEncryptedPart # gets ciphertext
-CK_ULONG_PTR pulEncryptedPartLen # gets c-text size
-
-# C_EncryptFinal finishes a multiple-part encryption operation.
-FUNCTION C_EncryptFinal
-CK_SESSION_HANDLE hSession # session handle
-CK_BYTE_PTR pLastEncryptedPart # last c-text
-CK_ULONG_PTR pulLastEncryptedPartLen # gets last size
-
-# C_DecryptInit initializes a decryption operation.
-FUNCTION C_DecryptInit
-CK_SESSION_HANDLE hSession # the session's handle
-CK_MECHANISM_PTR pMechanism # the decryption mechanism
-CK_OBJECT_HANDLE hKey # handle of decryption key
-
-# C_Decrypt decrypts encrypted data in a single part.
-FUNCTION C_Decrypt
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pEncryptedData # ciphertext
-CK_ULONG ulEncryptedDataLen # ciphertext length
-CK_BYTE_PTR pData # gets plaintext
-CK_ULONG_PTR pulDataLen # gets p-text size
-
-# C_DecryptUpdate continues a multiple-part decryption operation.
-FUNCTION C_DecryptUpdate
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pEncryptedPart # encrypted data
-CK_ULONG ulEncryptedPartLen # input length
-CK_BYTE_PTR pPart # gets plaintext
-CK_ULONG_PTR pulPartLen # p-text size
-
-# C_DecryptFinal finishes a multiple-part decryption operation.
-FUNCTION C_DecryptFinal
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pLastPart # gets plaintext
-CK_ULONG_PTR pulLastPartLen # p-text size
-
-
-# Message digesting
-
-# C_DigestInit initializes a message-digesting operation.
-FUNCTION C_DigestInit
-CK_SESSION_HANDLE hSession # the session's handle
-CK_MECHANISM_PTR pMechanism # the digesting mechanism
-
-# C_Digest digests data in a single part.
-FUNCTION C_Digest
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pData # data to be digested
-CK_ULONG ulDataLen # bytes of data to digest
-CK_BYTE_PTR pDigest # gets the message digest
-CK_ULONG_PTR pulDigestLen # gets digest length
-
-# C_DigestUpdate continues a multiple-part message-digesting operation.
-FUNCTION C_DigestUpdate
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pPart # data to be digested
-CK_ULONG ulPartLen # bytes of data to be digested
-
-# C_DigestKey continues a multi-part message-digesting operation, by
-# digesting the value of a secret key as part of the data already
-# digested.
-FUNCTION C_DigestKey
-CK_SESSION_HANDLE hSession # the session's handle
-CK_OBJECT_HANDLE hKey # secret key to digest
-
-# C_DigestFinal finishes a multiple-part message-digesting operation.
-FUNCTION C_DigestFinal
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pDigest # gets the message digest
-CK_ULONG_PTR pulDigestLen # gets byte count of digest
-
-
-# Signing and MACing
-
-# C_SignInit initializes a signature (private key encryption)
-# operation, where the signature is (will be) an appendix to the
-# data, and plaintext cannot be recovered from the signature.
-FUNCTION C_SignInit
-CK_SESSION_HANDLE hSession # the session's handle
-CK_MECHANISM_PTR pMechanism # the signature mechanism
-CK_OBJECT_HANDLE hKey # handle of signature key
-
-# C_Sign signs (encrypts with private key) data in a single part,
-# where the signature is (will be) an appendix to the data, and
-# plaintext cannot be recovered from the signature.
-FUNCTION C_Sign
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pData # the data to sign
-CK_ULONG ulDataLen # count of bytes to sign
-CK_BYTE_PTR pSignature # gets the signature
-CK_ULONG_PTR pulSignatureLen # gets signature length
-
-# C_SignUpdate continues a multiple-part signature operation, where
-# the signature is (will be) an appendix to the data, and plaintext
-# cannot be recovered from the signature.
-FUNCTION C_SignUpdate
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pPart # the data to sign
-CK_ULONG ulPartLen # count of bytes to sign
-
-# C_SignFinal finishes a multiple-part signature operation, returning
-# the signature.
-FUNCTION C_SignFinal
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pSignature # gets the signature
-CK_ULONG_PTR pulSignatureLen # gets signature length
-
-# C_SignRecoverInit initializes a signature operation, where the data
-# can be recovered from the signature.
-FUNCTION C_SignRecoverInit
-CK_SESSION_HANDLE hSession # the session's handle
-CK_MECHANISM_PTR pMechanism # the signature mechanism
-CK_OBJECT_HANDLE hKey # handle of the signature key
-
-# C_SignRecover signs data in a single operation, where the data can
-# be recovered from the signature.
-FUNCTION C_SignRecover
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pData # the data to sign
-CK_ULONG ulDataLen # count of bytes to sign
-CK_BYTE_PTR pSignature # gets the signature
-CK_ULONG_PTR pulSignatureLen # gets signature length
-
-
-# Verifying signatures and MACs
-
-# C_VerifyInit initializes a verification operation, where the
-# signature is an appendix to the data, and plaintext cannot cannot
-# be recovered from the signature (e.g. DSA).
-FUNCTION C_VerifyInit
-CK_SESSION_HANDLE hSession # the session's handle
-CK_MECHANISM_PTR pMechanism # the verification mechanism
-CK_OBJECT_HANDLE hKey # verification key
-
-# C_Verify verifies a signature in a single-part operation, where the
-# signature is an appendix to the data, and plaintext cannot be
-# recovered from the signature.
-FUNCTION C_Verify
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pData # signed data
-CK_ULONG ulDataLen # length of signed data
-CK_BYTE_PTR pSignature # signature
-CK_ULONG ulSignatureLen # signature length
-
-# C_VerifyUpdate continues a multiple-part verification operation,
-# where the signature is an appendix to the data, and plaintext cannot be
-# recovered from the signature.
-FUNCTION C_VerifyUpdate
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pPart # signed data
-CK_ULONG ulPartLen # length of signed data
-
-# C_VerifyFinal finishes a multiple-part verification operation,
-# checking the signature.
-FUNCTION C_VerifyFinal
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pSignature # signature to verify
-CK_ULONG ulSignatureLen # signature length
-
-# C_VerifyRecoverInit initializes a signature verification operation,
-# where the data is recovered from the signature.
-FUNCTION C_VerifyRecoverInit
-CK_SESSION_HANDLE hSession # the session's handle
-CK_MECHANISM_PTR pMechanism # the verification mechanism
-CK_OBJECT_HANDLE hKey # verification key
-
-# C_VerifyRecover verifies a signature in a single-part operation,
-# where the data is recovered from the signature.
-FUNCTION C_VerifyRecover
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pSignature # signature to verify
-CK_ULONG ulSignatureLen # signature length
-CK_BYTE_PTR pData # gets signed data
-CK_ULONG_PTR pulDataLen # gets signed data len
-
-
-# Dual-function cryptographic operations
-
-# C_DigestEncryptUpdate continues a multiple-part digesting and
-# encryption operation.
-FUNCTION C_DigestEncryptUpdate
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pPart # the plaintext data
-CK_ULONG ulPartLen # plaintext length
-CK_BYTE_PTR pEncryptedPart # gets ciphertext
-CK_ULONG_PTR pulEncryptedPartLen # gets c-text length
-
-# C_DecryptDigestUpdate continues a multiple-part decryption and
-# digesting operation.
-FUNCTION C_DecryptDigestUpdate
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pEncryptedPart # ciphertext
-CK_ULONG ulEncryptedPartLen # ciphertext length
-CK_BYTE_PTR pPart # gets plaintext
-CK_ULONG_PTR pulPartLen # gets plaintext len
-
-# C_SignEncryptUpdate continues a multiple-part signing and
-# encryption operation.
-FUNCTION C_SignEncryptUpdate
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pPart # the plaintext data
-CK_ULONG ulPartLen # plaintext length
-CK_BYTE_PTR pEncryptedPart # gets ciphertext
-CK_ULONG_PTR pulEncryptedPartLen # gets c-text length
-
-# C_DecryptVerifyUpdate continues a multiple-part decryption and
-# verify operation.
-FUNCTION C_DecryptVerifyUpdate
-CK_SESSION_HANDLE hSession # session's handle
-CK_BYTE_PTR pEncryptedPart # ciphertext
-CK_ULONG ulEncryptedPartLen # ciphertext length
-CK_BYTE_PTR pPart # gets plaintext
-CK_ULONG_PTR pulPartLen # gets p-text length
-
-
-# Key management
-
-# C_GenerateKey generates a secret key, creating a new key object.
-FUNCTION C_GenerateKey
-CK_SESSION_HANDLE hSession # the session's handle
-CK_MECHANISM_PTR pMechanism # key generation mech.
-CK_ATTRIBUTE_PTR pTemplate # template for new key
-CK_ULONG ulCount # # of attrs in template
-CK_OBJECT_HANDLE_PTR phKey # gets handle of new key
-
-# C_GenerateKeyPair generates a public-key/private-key pair, creating
-# new key objects.
-FUNCTION C_GenerateKeyPair
-CK_SESSION_HANDLE hSession # session handle
-CK_MECHANISM_PTR pMechanism # key-gen mech.
-CK_ATTRIBUTE_PTR pPublicKeyTemplate # template for pub. key
-CK_ULONG ulPublicKeyAttributeCount # # pub. attrs.
-CK_ATTRIBUTE_PTR pPrivateKeyTemplate # template for priv. key
-CK_ULONG ulPrivateKeyAttributeCount # # priv. attrs.
-CK_OBJECT_HANDLE_PTR phPublicKey # gets pub. key handle
-CK_OBJECT_HANDLE_PTR phPrivateKey # gets priv. key handle
-
-# C_WrapKey wraps (i.e., encrypts) a key.
-FUNCTION C_WrapKey
-CK_SESSION_HANDLE hSession # the session's handle
-CK_MECHANISM_PTR pMechanism # the wrapping mechanism
-CK_OBJECT_HANDLE hWrappingKey # wrapping key
-CK_OBJECT_HANDLE hKey # key to be wrapped
-CK_BYTE_PTR pWrappedKey # gets wrapped key
-CK_ULONG_PTR pulWrappedKeyLen # gets wrapped key size
-
-# C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key
-# object.
-FUNCTION C_UnwrapKey
-CK_SESSION_HANDLE hSession # session's handle
-CK_MECHANISM_PTR pMechanism # unwrapping mech.
-CK_OBJECT_HANDLE hUnwrappingKey # unwrapping key
-CK_BYTE_PTR pWrappedKey # the wrapped key
-CK_ULONG ulWrappedKeyLen # wrapped key len
-CK_ATTRIBUTE_PTR pTemplate # new key template
-CK_ULONG ulAttributeCount # template length
-CK_OBJECT_HANDLE_PTR phKey # gets new handle
-
-# C_DeriveKey derives a key from a base key, creating a new key object.
-FUNCTION C_DeriveKey
-CK_SESSION_HANDLE hSession # session's handle
-CK_MECHANISM_PTR pMechanism # key deriv. mech.
-CK_OBJECT_HANDLE hBaseKey # base key
-CK_ATTRIBUTE_PTR pTemplate # new key template
-CK_ULONG ulAttributeCount # template length
-CK_OBJECT_HANDLE_PTR phKey # gets new handle
-
-
-# Random number generation
-
-# C_SeedRandom mixes additional seed material into the token's random
-# number generator.
-FUNCTION C_SeedRandom
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR pSeed # the seed material
-CK_ULONG ulSeedLen # length of seed material
-
-# C_GenerateRandom generates random data.
-FUNCTION C_GenerateRandom
-CK_SESSION_HANDLE hSession # the session's handle
-CK_BYTE_PTR RandomData # receives the random data
-CK_ULONG ulRandomLen # # of bytes to generate
-
-
-# Parallel function management
-
-# C_GetFunctionStatus is a legacy function; it obtains an updated
-# status of a function running in parallel with an application.
-FUNCTION C_GetFunctionStatus
-CK_SESSION_HANDLE hSession # the session's handle
-
-# C_CancelFunction is a legacy function; it cancels a function running
-# in parallel.
-FUNCTION C_CancelFunction
-CK_SESSION_HANDLE hSession # the session's handle
-
-
-# Functions added in for Cryptoki Version 2.01 or later
-
-# C_WaitForSlotEvent waits for a slot event (token insertion, removal,
-# etc.) to occur.
-FUNCTION C_WaitForSlotEvent
-CK_FLAGS flags # blocking/nonblocking flag
-CK_SLOT_ID_PTR pSlot # location that receives the slot ID
-CK_VOID_PTR pRserved # reserved. Should be NULL_PTR
-
-## C_ConfigureSlot passes an installation-specified bytestring to a
-## slot.
-#FUNCTION C_ConfigureSlot
-#CK_SLOT_ID slotID # the slot to configure
-#CK_BYTE_PTR pConfig # the configuration string
-#CK_ULONG ulConfigLen # length of the config string
diff --git a/security/nss/lib/ckfw/ck.h b/security/nss/lib/ckfw/ck.h
deleted file mode 100644
index 06aa37912..000000000
--- a/security/nss/lib/ckfw/ck.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CK_H
-#define CK_H
-
-#ifdef DEBUG
-static const char CK_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * ck.h
- *
- * This header file consolidates all header files needed by the source
- * files implementing the NSS Cryptoki Framework. This makes managing
- * the source files a bit easier.
- */
-
-/* Types */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFT_H
-#include "nssckft.h"
-#endif /* NSSCKFT_H */
-
-#ifndef NSSCKEPV_H
-#include "nssckepv.h"
-#endif /* NSSCKEPV_H */
-
-#ifndef NSSCKFWT_H
-#include "nssckfwt.h"
-#endif /* NSSCKFWT_H */
-
-#ifndef NSSCKMDT_H
-#include "nssckmdt.h"
-#endif /* NSSCKMDT_H */
-
-#ifndef CKT_H
-#include "ckt.h"
-#endif /* CKT_H */
-
-#ifndef CKFWTM_H
-#include "ckfwtm.h"
-#endif /* CKFWTM_H */
-
-/* Prototypes */
-
-#ifndef NSSBASE_H
-#include "nssbase.h"
-#endif /* NSSBASE_H */
-
-#ifndef NSSCKG_H
-#include "nssckg.h"
-#endif /* NSSCKG_H */
-
-#ifndef NSSCKFW_H
-#include "nssckfw.h"
-#endif /* NSSCKFW_H */
-
-#ifndef NSSCKFWC_H
-#include "nssckfwc.h"
-#endif /* NSSCKFWC_H */
-
-#ifndef CKFW_H
-#include "ckfw.h"
-#endif /* CKFW_H */
-
-#ifndef CKFWM_H
-#include "ckfwm.h"
-#endif /* CKFWM_H */
-
-#ifndef CKMD_H
-#include "ckmd.h"
-#endif /* CKMD_H */
-
-/* NSS-private */
-
-/* nss_ZNEW and the like. We might want to publish the memory APIs.. */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#endif /* CK_H */
diff --git a/security/nss/lib/ckfw/ckapi.perl b/security/nss/lib/ckfw/ckapi.perl
deleted file mode 100644
index d480cfb69..000000000
--- a/security/nss/lib/ckfw/ckapi.perl
+++ /dev/null
@@ -1,451 +0,0 @@
-#!perl
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-$cvs_id = '@(#) $RCSfile$ $Revision$ $Date$';
-
-$copyright = '/* THIS IS A GENERATED FILE */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-';
-
-$count = -1;
-$i = 0;
-
-open(INPUT, "<$ARGV[0]") || die "Can't open $ARGV[0]: $!";
-
-while(<INPUT>) {
- s/^((?:[^"#]+|"[^"]*")*)(\s*#.*$)/$1/;
- next if (/^\s*$/);
-
-# print;
-
- /^([\S]+)\s+([^"][\S]*|"[^"]*")/;
- $name = $1;
- $value = $2;
-
- if( ($name =~ "FUNCTION") && !($name =~ "CK_FUNCTION") ) {
- $count++;
- $x[$count]{name} = $value;
- $i = 0;
- } else {
- if( $count < 0 ) {
- $value =~ s/"//g;
- $g{$name} = $value;
- } else {
- $x[$count]{args}[$i]{type} = $name;
- $x[$count]{args}[$i]{name} = $value;
- $i++;
- $x[$count]{nargs} = $i; # rewritten each time, oh well
- }
- }
-}
-
-close INPUT;
-
-# dodump();
-doprint();
-
-sub dodump {
- for( $j = 0; $j <= $count; $j++ ) {
- print "CK_RV CK_ENTRY $x[$j]{name}\n";
- for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
- print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
- if( $i == ($x[$j]{nargs} - 1) ) {
- print "\n";
- } else {
- print ",\n";
- }
- }
- }
-}
-
-sub doprint {
-open(PROTOTYPE, ">nssckg.h") || die "Can't open nssckg.h: $!";
-open(TYPEDEF, ">nssckft.h") || die "Can't open nssckft.h: $!";
-open(EPV, ">nssckepv.h") || die "Can't open nssckepv.h: $!";
-open(API, ">nssck.api") || die "Can't open nssck.api: $!";
-
-select PROTOTYPE;
-
-print $copyright;
-print <<EOD
-#ifndef NSSCKG_H
-#define NSSCKG_H
-
-#ifdef DEBUG
-static const char NSSCKG_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
-#endif /* DEBUG */
-
-/*
- * nssckg.h
- *
- * This automatically-generated header file prototypes the Cryptoki
- * functions specified by PKCS#11.
- */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-EOD
- ;
-
-for( $j = 0; $j <= $count; $j++ ) {
- print "CK_RV CK_ENTRY $x[$j]{name}\n";
- print "(\n";
- for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
- print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
- if( $i == ($x[$j]{nargs} - 1) ) {
- print "\n";
- } else {
- print ",\n";
- }
- }
- print ");\n\n";
-}
-
-print <<EOD
-#endif /* NSSCKG_H */
-EOD
- ;
-
-select TYPEDEF;
-
-print $copyright;
-print <<EOD
-#ifndef NSSCKFT_H
-#define NSSCKFT_H
-
-#ifdef DEBUG
-static const char NSSCKFT_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
-#endif /* DEBUG */
-
-/*
- * nssckft.h
- *
- * The automatically-generated header file declares a typedef
- * each of the Cryptoki functions specified by PKCS#11.
- */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-EOD
- ;
-
-for( $j = 0; $j <= $count; $j++ ) {
-# print "typedef CK_RV (CK_ENTRY *CK_$x[$j]{name})(\n";
- print "typedef CK_CALLBACK_FUNCTION(CK_RV, CK_$x[$j]{name})(\n";
- for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
- print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
- if( $i == ($x[$j]{nargs} - 1) ) {
- print "\n";
- } else {
- print ",\n";
- }
- }
- print ");\n\n";
-}
-
-print <<EOD
-#endif /* NSSCKFT_H */
-EOD
- ;
-
-select EPV;
-
-print $copyright;
-print <<EOD
-#ifndef NSSCKEPV_H
-#define NSSCKEPV_H
-
-#ifdef DEBUG
-static const char NSSCKEPV_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
-#endif /* DEBUG */
-
-/*
- * nssckepv.h
- *
- * This automatically-generated header file defines the type
- * CK_FUNCTION_LIST specified by PKCS#11.
- */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFT_H
-#include "nssckft.h"
-#endif /* NSSCKFT_H */
-
-#include "nssckp.h"
-
-struct CK_FUNCTION_LIST {
- CK_VERSION version;
-EOD
- ;
-
-for( $j = 0; $j <= $count; $j++ ) {
- print " CK_$x[$j]{name} $x[$j]{name};\n";
-}
-
-print <<EOD
-};
-
-#include "nsscku.h"
-
-#endif /* NSSCKEPV_H */
-EOD
- ;
-
-select API;
-
-print $copyright;
-print <<EOD
-
-#ifdef DEBUG
-static const char NSSCKAPI_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
-#endif /* DEBUG */
-
-/*
- * nssck.api
- *
- * This automatically-generated file is used to generate a set of
- * Cryptoki entry points within the object space of a Module using
- * the NSS Cryptoki Framework.
- *
- * The Module should have a .c file with the following:
- *
- * #define MODULE_NAME name
- * #define INSTANCE_NAME instance
- * #include "nssck.api"
- *
- * where "name" is some module-specific name that can be used to
- * disambiguate various modules. This included file will then
- * define the actual Cryptoki routines which pass through to the
- * Framework calls. All routines, except C_GetFunctionList, will
- * be prefixed with the name; C_GetFunctionList will be generated
- * to return an entry-point vector with these routines. The
- * instance specified should be the basic instance of NSSCKMDInstance.
- *
- * If, prior to including nssck.api, the .c file also specifies
- *
- * #define DECLARE_STRICT_CRYTPOKI_NAMES
- *
- * Then a set of "stub" routines not prefixed with the name will
- * be included. This would allow the combined module and framework
- * to be used in applications which are hard-coded to use the
- * PKCS#11 names (instead of going through the EPV). Please note
- * that such applications should be careful resolving symbols when
- * more than one PKCS#11 module is loaded.
- */
-
-#ifndef MODULE_NAME
-#error "Error: MODULE_NAME must be defined."
-#endif /* MODULE_NAME */
-
-#ifndef INSTANCE_NAME
-#error "Error: INSTANCE_NAME must be defined."
-#endif /* INSTANCE_NAME */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFWT_H
-#include "nssckfwt.h"
-#endif /* NSSCKFWT_H */
-
-#ifndef NSSCKFWC_H
-#include "nssckfwc.h"
-#endif /* NSSCKFWC_H */
-
-#ifndef NSSCKEPV_H
-#include "nssckepv.h"
-#endif /* NSSCKEPV_H */
-
-#define ADJOIN(x,y) x##y
-
-#define __ADJOIN(x,y) ADJOIN(x,y)
-
-/*
- * The anchor. This object is used to store an "anchor" pointer in
- * the Module's object space, so the wrapper functions can relate
- * back to this instance.
- */
-
-static NSSCKFWInstance *fwInstance = (NSSCKFWInstance *)0;
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Initialize)
-(
- CK_VOID_PTR pInitArgs
-)
-{
- return NSSCKFWC_Initialize(&fwInstance, INSTANCE_NAME, pInitArgs);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Initialize
-(
- CK_VOID_PTR pInitArgs
-)
-{
- return __ADJOIN(MODULE_NAME,C_Initialize)(pInitArgs);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Finalize)
-(
- CK_VOID_PTR pReserved
-)
-{
- return NSSCKFWC_Finalize(&fwInstance);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Finalize
-(
- CK_VOID_PTR pReserved
-)
-{
- return __ADJOIN(MODULE_NAME,C_Finalize)(pReserved);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetInfo)
-(
- CK_INFO_PTR pInfo
-)
-{
- return NSSCKFWC_GetInfo(fwInstance, pInfo);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetInfo
-(
- CK_INFO_PTR pInfo
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetInfo)(pInfo);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-/*
- * C_GetFunctionList is defined at the end.
- */
-
-EOD
- ;
-
-for( $j = 4; $j <= $count; $j++ ) {
- print "static CK_RV CK_ENTRY\n";
- print "__ADJOIN(MODULE_NAME,$x[$j]{name})\n";
- print "(\n";
- for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
- print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
- if( $i == ($x[$j]{nargs} - 1) ) {
- print "\n";
- } else {
- print ",\n";
- }
- }
- print ")\n";
- print "{\n";
- print " return NSSCKFW$x[$j]{name}(fwInstance, ";
- for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
- print "$x[$j]{args}[$i]{name}";
- if( $i == ($x[$j]{nargs} - 1) ) {
- print ");\n";
- } else {
- print ", ";
- }
- }
- print "}\n\n";
-
- print "#ifdef DECLARE_STRICT_CRYPTOKI_NAMES\n";
- print "CK_RV CK_ENTRY\n";
- print "$x[$j]{name}\n";
- print "(\n";
- for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
- print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
- if( $i == ($x[$j]{nargs} - 1) ) {
- print "\n";
- } else {
- print ",\n";
- }
- }
- print ")\n";
- print "{\n";
- print " return __ADJOIN(MODULE_NAME,$x[$j]{name})(";
- for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
- print "$x[$j]{args}[$i]{name}";
- if( $i == ($x[$j]{nargs} - 1) ) {
- print ");\n";
- } else {
- print ", ";
- }
- }
- print "}\n";
- print "#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */\n\n";
-}
-
-print <<EOD
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetFunctionList)
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList
-);
-
-static CK_FUNCTION_LIST FunctionList = {
- { 2, 1 },
-EOD
- ;
-
-for( $j = 0; $j <= $count; $j++ ) {
- print "__ADJOIN(MODULE_NAME,$x[$j]{name})";
- if( $j < $count ) {
- print ",\n";
- } else {
- print "\n};\n\n";
- }
-}
-
-print <<EOD
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetFunctionList)
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList
-)
-{
- *ppFunctionList = &FunctionList;
- return CKR_OK;
-}
-
-/* This one is always present */
-CK_RV CK_ENTRY
-C_GetFunctionList
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetFunctionList)(ppFunctionList);
-}
-
-#undef __ADJOIN
-
-EOD
- ;
-
-select STDOUT;
-
-}
diff --git a/security/nss/lib/ckfw/ckfw.h b/security/nss/lib/ckfw/ckfw.h
deleted file mode 100644
index 1a7f7fe0b..000000000
--- a/security/nss/lib/ckfw/ckfw.h
+++ /dev/null
@@ -1,2430 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CKFW_H
-#define CKFW_H
-
-#ifdef DEBUG
-static const char CKFW_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * ckfw.h
- *
- * This file prototypes the private calls of the NSS Cryptoki Framework.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFWT_H
-#include "nssckfwt.h"
-#endif /* NSSCKFWT_H */
-
-#ifndef NSSCKMDT_H
-#include "nssckmdt.h"
-#endif /* NSSCKMDT_H */
-
-/*
- * NSSCKFWInstance
- *
- * -- create/destroy --
- * nssCKFWInstance_Create
- * nssCKFWInstance_Destroy
- *
- * -- implement public accessors --
- * nssCKFWInstance_GetMDInstance
- * nssCKFWInstance_GetArena
- * nssCKFWInstance_MayCreatePthreads
- * nssCKFWInstance_CreateMutex
- * nssCKFWInstance_GetConfigurationData
- * nssCKFWInstance_GetInitArgs
- *
- * -- private accessors --
- * nssCKFWInstance_CreateSessionHandle
- * nssCKFWInstance_ResolveSessionHandle
- * nssCKFWInstance_DestroySessionHandle
- * nssCKFWInstance_FindSessionHandle
- * nssCKFWInstance_CreateObjectHandle
- * nssCKFWInstance_ResolveObjectHandle
- * nssCKFWInstance_DestroyObjectHandle
- * nssCKFWInstance_FindObjectHandle
- *
- * -- module fronts --
- * nssCKFWInstance_GetNSlots
- * nssCKFWInstance_GetCryptokiVersion
- * nssCKFWInstance_GetManufacturerID
- * nssCKFWInstance_GetFlags
- * nssCKFWInstance_GetLibraryDescription
- * nssCKFWInstance_GetLibraryVersion
- * nssCKFWInstance_GetModuleHandlesSessionObjects
- * nssCKFWInstance_GetSlots
- * nssCKFWInstance_WaitForSlotEvent
- *
- * -- debugging versions only --
- * nssCKFWInstance_verifyPointer
- */
-
-/*
- * nssCKFWInstance_Create
- *
- */
-NSS_EXTERN NSSCKFWInstance *
-nssCKFWInstance_Create
-(
- CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState LockingState,
- NSSCKMDInstance *mdInstance,
- CK_RV *pError
-);
-
-/*
- * nssCKFWInstance_Destroy
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWInstance_Destroy
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWInstance_GetMDInstance
- *
- */
-NSS_EXTERN NSSCKMDInstance *
-nssCKFWInstance_GetMDInstance
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWInstance_GetArena
- *
- */
-NSS_EXTERN NSSArena *
-nssCKFWInstance_GetArena
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
-
-/*
- * nssCKFWInstance_MayCreatePthreads
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWInstance_MayCreatePthreads
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWInstance_CreateMutex
- *
- */
-NSS_EXTERN NSSCKFWMutex *
-nssCKFWInstance_CreateMutex
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-);
-
-/*
- * nssCKFWInstance_GetConfigurationData
- *
- */
-NSS_EXTERN NSSUTF8 *
-nssCKFWInstance_GetConfigurationData
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWInstance_GetInitArgs
- *
- */
-NSS_EXTERN CK_C_INITIALIZE_ARGS_PTR
-nssCKFWInstance_GetInitArgs
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWInstance_CreateSessionHandle
- *
- */
-NSS_EXTERN CK_SESSION_HANDLE
-nssCKFWInstance_CreateSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
-
-/*
- * nssCKFWInstance_ResolveSessionHandle
- *
- */
-NSS_EXTERN NSSCKFWSession *
-nssCKFWInstance_ResolveSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
-
-/*
- * nssCKFWInstance_DestroySessionHandle
- *
- */
-NSS_EXTERN void
-nssCKFWInstance_DestroySessionHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
-
-/*
- * nssCKFWInstance_FindSessionHandle
- *
- */
-NSS_EXTERN CK_SESSION_HANDLE
-nssCKFWInstance_FindSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWInstance_CreateObjectHandle
- *
- */
-NSS_EXTERN CK_OBJECT_HANDLE
-nssCKFWInstance_CreateObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
-
-/*
- * nssCKFWInstance_ResolveObjectHandle
- *
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWInstance_ResolveObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject
-);
-
-/*
- * nssCKFWInstance_ReassignObjectHandle
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWInstance_ReassignObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWInstance_DestroyObjectHandle
- *
- */
-NSS_EXTERN void
-nssCKFWInstance_DestroyObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject
-);
-
-/*
- * nssCKFWInstance_FindObjectHandle
- *
- */
-NSS_EXTERN CK_OBJECT_HANDLE
-nssCKFWInstance_FindObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWInstance_GetNSlots
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWInstance_GetNSlots
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
-
-/*
- * nssCKFWInstance_GetCryptokiVersion
- *
- */
-NSS_EXTERN CK_VERSION
-nssCKFWInstance_GetCryptokiVersion
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWInstance_GetManufacturerID
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWInstance_GetManufacturerID
-(
- NSSCKFWInstance *fwInstance,
- CK_CHAR manufacturerID[32]
-);
-
-/*
- * nssCKFWInstance_GetFlags
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWInstance_GetFlags
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWInstance_GetLibraryDescription
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWInstance_GetLibraryDescription
-(
- NSSCKFWInstance *fwInstance,
- CK_CHAR libraryDescription[32]
-);
-
-/*
- * nssCKFWInstance_GetLibraryVersion
- *
- */
-NSS_EXTERN CK_VERSION
-nssCKFWInstance_GetLibraryVersion
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWInstance_GetModuleHandlesSessionObjects
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWInstance_GetModuleHandlesSessionObjects
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWInstance_GetSlots
- *
- */
-NSS_EXTERN NSSCKFWSlot **
-nssCKFWInstance_GetSlots
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
-
-/*
- * nssCKFWInstance_WaitForSlotEvent
- *
- */
-NSS_EXTERN NSSCKFWSlot *
-nssCKFWInstance_WaitForSlotEvent
-(
- NSSCKFWInstance *fwInstance,
- CK_BBOOL block,
- CK_RV *pError
-);
-
-/*
- * nssCKFWInstance_verifyPointer
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWInstance_verifyPointer
-(
- const NSSCKFWInstance *fwInstance
-);
-
-
-/*
- * NSSCKFWSlot
- *
- * -- create/destroy --
- * nssCKFWSlot_Create
- * nssCKFWSlot_Destroy
- *
- * -- implement public accessors --
- * nssCKFWSlot_GetMDSlot
- * nssCKFWSlot_GetFWInstance
- * nssCKFWSlot_GetMDInstance
- *
- * -- private accessors --
- * nssCKFWSlot_GetSlotID
- *
- * -- module fronts --
- * nssCKFWSlot_GetSlotDescription
- * nssCKFWSlot_GetManufacturerID
- * nssCKFWSlot_GetTokenPresent
- * nssCKFWSlot_GetRemovableDevice
- * nssCKFWSlot_GetHardwareSlot
- * nssCKFWSlot_GetHardwareVersion
- * nssCKFWSlot_GetFirmwareVersion
- * nssCKFWSlot_GetToken
- */
-
-/*
- * nssCKFWSlot_Create
- *
- */
-NSS_EXTERN NSSCKFWSlot *
-nssCKFWSlot_Create
-(
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *mdSlot,
- CK_SLOT_ID slotID,
- CK_RV *pError
-);
-
-/*
- * nssCKFWSlot_Destroy
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSlot_Destroy
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetMDSlot
- *
- */
-NSS_EXTERN NSSCKMDSlot *
-nssCKFWSlot_GetMDSlot
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetFWInstance
- *
- */
-
-NSS_EXTERN NSSCKFWInstance *
-nssCKFWSlot_GetFWInstance
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetMDInstance
- *
- */
-
-NSS_EXTERN NSSCKMDInstance *
-nssCKFWSlot_GetMDInstance
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetSlotID
- *
- */
-NSS_EXTERN CK_SLOT_ID
-nssCKFWSlot_GetSlotID
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetSlotDescription
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSlot_GetSlotDescription
-(
- NSSCKFWSlot *fwSlot,
- CK_CHAR slotDescription[64]
-);
-
-/*
- * nssCKFWSlot_GetManufacturerID
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSlot_GetManufacturerID
-(
- NSSCKFWSlot *fwSlot,
- CK_CHAR manufacturerID[32]
-);
-
-/*
- * nssCKFWSlot_GetTokenPresent
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWSlot_GetTokenPresent
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetRemovableDevice
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWSlot_GetRemovableDevice
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetHardwareSlot
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWSlot_GetHardwareSlot
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetHardwareVersion
- *
- */
-NSS_EXTERN CK_VERSION
-nssCKFWSlot_GetHardwareVersion
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetFirmwareVersion
- *
- */
-NSS_EXTERN CK_VERSION
-nssCKFWSlot_GetFirmwareVersion
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * nssCKFWSlot_GetToken
- *
- */
-NSS_EXTERN NSSCKFWToken *
-nssCKFWSlot_GetToken
-(
- NSSCKFWSlot *fwSlot,
- CK_RV *pError
-);
-
-/*
- * nssCKFWSlot_ClearToken
- *
- */
-NSS_EXTERN void
-nssCKFWSlot_ClearToken
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * NSSCKFWToken
- *
- * -- create/destroy --
- * nssCKFWToken_Create
- * nssCKFWToken_Destroy
- *
- * -- implement public accessors --
- * nssCKFWToken_GetMDToken
- * nssCKFWToken_GetFWSlot
- * nssCKFWToken_GetMDSlot
- * nssCKFWToken_GetSessionState
- *
- * -- private accessors --
- * nssCKFWToken_SetSessionState
- * nssCKFWToken_RemoveSession
- * nssCKFWToken_CloseAllSessions
- * nssCKFWToken_GetSessionCount
- * nssCKFWToken_GetRwSessionCount
- * nssCKFWToken_GetRoSessionCount
- * nssCKFWToken_GetSessionObjectHash
- * nssCKFWToken_GetMDObjectHash
- * nssCKFWToken_GetObjectHandleHash
- *
- * -- module fronts --
- * nssCKFWToken_InitToken
- * nssCKFWToken_GetLabel
- * nssCKFWToken_GetManufacturerID
- * nssCKFWToken_GetModel
- * nssCKFWToken_GetSerialNumber
- * nssCKFWToken_GetHasRNG
- * nssCKFWToken_GetIsWriteProtected
- * nssCKFWToken_GetLoginRequired
- * nssCKFWToken_GetUserPinInitialized
- * nssCKFWToken_GetRestoreKeyNotNeeded
- * nssCKFWToken_GetHasClockOnToken
- * nssCKFWToken_GetHasProtectedAuthenticationPath
- * nssCKFWToken_GetSupportsDualCryptoOperations
- * nssCKFWToken_GetMaxSessionCount
- * nssCKFWToken_GetMaxRwSessionCount
- * nssCKFWToken_GetMaxPinLen
- * nssCKFWToken_GetMinPinLen
- * nssCKFWToken_GetTotalPublicMemory
- * nssCKFWToken_GetFreePublicMemory
- * nssCKFWToken_GetTotalPrivateMemory
- * nssCKFWToken_GetFreePrivateMemory
- * nssCKFWToken_GetHardwareVersion
- * nssCKFWToken_GetFirmwareVersion
- * nssCKFWToken_GetUTCTime
- * nssCKFWToken_OpenSession
- * nssCKFWToken_GetMechanismCount
- * nssCKFWToken_GetMechanismTypes
- * nssCKFWToken_GetMechanism
- */
-
-/*
- * nssCKFWToken_Create
- *
- */
-NSS_EXTERN NSSCKFWToken *
-nssCKFWToken_Create
-(
- NSSCKFWSlot *fwSlot,
- NSSCKMDToken *mdToken,
- CK_RV *pError
-);
-
-/*
- * nssCKFWToken_Destroy
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_Destroy
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetMDToken
- *
- */
-NSS_EXTERN NSSCKMDToken *
-nssCKFWToken_GetMDToken
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetArena
- *
- */
-NSS_EXTERN NSSArena *
-nssCKFWToken_GetArena
-(
- NSSCKFWToken *fwToken,
- CK_RV *pError
-);
-
-/*
- * nssCKFWToken_GetFWSlot
- *
- */
-NSS_EXTERN NSSCKFWSlot *
-nssCKFWToken_GetFWSlot
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetMDSlot
- *
- */
-NSS_EXTERN NSSCKMDSlot *
-nssCKFWToken_GetMDSlot
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetSessionState
- *
- */
-NSS_EXTERN CK_STATE
-nssCKFWToken_GetSessionState
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_InitToken
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_InitToken
-(
- NSSCKFWToken *fwToken,
- NSSItem *pin,
- NSSUTF8 *label
-);
-
-/*
- * nssCKFWToken_GetLabel
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_GetLabel
-(
- NSSCKFWToken *fwToken,
- CK_CHAR label[32]
-);
-
-/*
- * nssCKFWToken_GetManufacturerID
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_GetManufacturerID
-(
- NSSCKFWToken *fwToken,
- CK_CHAR manufacturerID[32]
-);
-
-/*
- * nssCKFWToken_GetModel
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_GetModel
-(
- NSSCKFWToken *fwToken,
- CK_CHAR model[16]
-);
-
-/*
- * nssCKFWToken_GetSerialNumber
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_GetSerialNumber
-(
- NSSCKFWToken *fwToken,
- CK_CHAR serialNumber[16]
-);
-
-/*
- * nssCKFWToken_GetHasRNG
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetHasRNG
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetIsWriteProtected
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetIsWriteProtected
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetLoginRequired
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetLoginRequired
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetUserPinInitialized
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetUserPinInitialized
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetRestoreKeyNotNeeded
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetRestoreKeyNotNeeded
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetHasClockOnToken
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetHasClockOnToken
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetHasProtectedAuthenticationPath
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetHasProtectedAuthenticationPath
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetSupportsDualCryptoOperations
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWToken_GetSupportsDualCryptoOperations
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetMaxSessionCount
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetMaxSessionCount
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetMaxRwSessionCount
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetMaxRwSessionCount
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetMaxPinLen
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetMaxPinLen
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetMinPinLen
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetMinPinLen
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetTotalPublicMemory
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetTotalPublicMemory
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetFreePublicMemory
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetFreePublicMemory
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetTotalPrivateMemory
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetTotalPrivateMemory
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetFreePrivateMemory
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetFreePrivateMemory
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetHardwareVersion
- *
- */
-NSS_EXTERN CK_VERSION
-nssCKFWToken_GetHardwareVersion
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetFirmwareVersion
- *
- */
-NSS_EXTERN CK_VERSION
-nssCKFWToken_GetFirmwareVersion
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetUTCTime
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_GetUTCTime
-(
- NSSCKFWToken *fwToken,
- CK_CHAR utcTime[16]
-);
-
-/*
- * nssCKFWToken_OpenSession
- *
- */
-NSS_EXTERN NSSCKFWSession *
-nssCKFWToken_OpenSession
-(
- NSSCKFWToken *fwToken,
- CK_BBOOL rw,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_RV *pError
-);
-
-/*
- * nssCKFWToken_GetMechanismCount
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetMechanismCount
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetMechanismTypes
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_GetMechanismTypes
-(
- NSSCKFWToken *fwToken,
- CK_MECHANISM_TYPE types[]
-);
-
-/*
- * nssCKFWToken_GetMechanism
- *
- */
-NSS_EXTERN NSSCKFWMechanism *
-nssCKFWToken_GetMechanism
-(
- NSSCKFWToken *fwToken,
- CK_MECHANISM_TYPE which,
- CK_RV *pError
-);
-
-/*
- * nssCKFWToken_SetSessionState
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_SetSessionState
-(
- NSSCKFWToken *fwToken,
- CK_STATE newState
-);
-
-/*
- * nssCKFWToken_RemoveSession
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_RemoveSession
-(
- NSSCKFWToken *fwToken,
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWToken_CloseAllSessions
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWToken_CloseAllSessions
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetSessionCount
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetSessionCount
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetRwSessionCount
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetRwSessionCount
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetRoSessionCount
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWToken_GetRoSessionCount
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetSessionObjectHash
- *
- */
-NSS_EXTERN nssCKFWHash *
-nssCKFWToken_GetSessionObjectHash
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetMDObjectHash
- *
- */
-NSS_EXTERN nssCKFWHash *
-nssCKFWToken_GetMDObjectHash
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * nssCKFWToken_GetObjectHandleHash
- *
- */
-NSS_EXTERN nssCKFWHash *
-nssCKFWToken_GetObjectHandleHash
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * NSSCKFWMechanism
- *
- * -- create/destroy --
- * nssCKFWMechanism_Create
- * nssCKFWMechanism_Destroy
- *
- * -- implement public accessors --
- * nssCKFWMechanism_GetMDMechanism
- *
- * -- private accessors --
- *
- * -- module fronts --
- * nssCKFWMechanism_GetMinKeySize
- * nssCKFWMechanism_GetMaxKeySize
- * nssCKFWMechanism_GetInHardware
- * nssCKFWMechanism_GetCanEncrypt
- * nssCKFWMechanism_GetCanDecrypt
- * nssCKFWMechanism_GetCanDigest
- * nssCKFWMechanism_GetCanSignRecover
- * nssCKFWMechanism_GetCanVerify
- * nssCKFWMechanism_GetCanVerifyRecover
- * nssCKFWMechanism_GetCanGenerate
- * nssCKFWMechanism_GetCanGenerateKeyPair
- * nssCKFWMechanism_GetCanWrap
- * nssCKFWMechanism_GetCanUnwrap
- * nssCKFWMechanism_GetCanDerive
- * nssCKFWMechanism_EncryptInit
- * nssCKFWMechanism_DecryptInit
- * nssCKFWMechanism_DigestInit
- * nssCKFWMechanism_SignInit
- * nssCKFWMechanism_SignRecoverInit
- * nssCKFWMechanism_VerifyInit
- * nssCKFWMechanism_VerifyRecoverInit
- * nssCKFWMechanism_GenerateKey
- * nssCKFWMechanism_GenerateKeyPair
- * nssCKFWMechanism_GetWrapKeyLength
- * nssCKFWMechanism_WrapKey
- * nssCKFWMechanism_UnwrapKey
- * nssCKFWMechanism_DeriveKey
- */
-
-/*
- * nssCKFWMechanism_Create
- *
- */
-NSS_EXTERN NSSCKFWMechanism *
-nssCKFWMechanism_Create
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * nssCKFWMechanism_Destroy
- *
- */
-NSS_EXTERN void
-nssCKFWMechanism_Destroy
-(
- NSSCKFWMechanism *fwMechanism
-);
-
-/*
- * nssCKFWMechanism_GetMDMechanism
- *
- */
-
-NSS_EXTERN NSSCKMDMechanism *
-nssCKFWMechanism_GetMDMechanism
-(
- NSSCKFWMechanism *fwMechanism
-);
-
-/*
- * nssCKFWMechanism_GetMinKeySize
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWMechanism_GetMinKeySize
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetMaxKeySize
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWMechanism_GetMaxKeySize
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetInHardware
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetInHardware
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * the following are determined automatically by which of the cryptographic
- * functions are defined for this mechanism.
- */
-/*
- * nssCKFWMechanism_GetCanEncrypt
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanEncrypt
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanDecrypt
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDecrypt
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanDigest
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDigest
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanSign
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanSign
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanSignRecover
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanSignRecover
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanVerify
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanVerify
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanVerifyRecover
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanVerifyRecover
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanGenerate
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanGenerate
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanGenerateKeyPair
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanGenerateKeyPair
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanWrap
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanWrap
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanUnwrap
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanUnwrap
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GetCanDerive
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDerive
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_EncryptInit
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_EncryptInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWMechanism_DecryptInit
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_DecryptInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWMechanism_DigestInit
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_DigestInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWMechanism_SignInit
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_SignInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWMechanism_SignRecoverInit
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_SignRecoverInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWMechanism_VerifyInit
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_VerifyInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWMechanism_VerifyRecoverInit
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_VerifyRecoverInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWMechanism_GenerateKey
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWMechanism_GenerateKey
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_GenerateKeyPair
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_GenerateKeyPair
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- NSSCKFWObject **fwPublicKeyObject,
- NSSCKFWObject **fwPrivateKeyObject
-);
-
-/*
- * nssCKFWMechanism_GetWrapKeyLength
- */
-NSS_EXTERN CK_ULONG
-nssCKFWMechanism_GetWrapKeyLength
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwWrappingKeyObject,
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_WrapKey
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_WrapKey
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwWrappingKeyObject,
- NSSCKFWObject *fwObject,
- NSSItem *wrappedKey
-);
-
-/*
- * nssCKFWMechanism_UnwrapKey
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWMechanism_UnwrapKey
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwWrappingKeyObject,
- NSSItem *wrappedKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMechanism_DeriveKey
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWMechanism_DeriveKey
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwBaseKeyObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWCryptoOperation
- *
- * -- create/destroy --
- * nssCKFWCryptoOperation_Create
- * nssCKFWCryptoOperation_Destroy
- *
- * -- implement public accessors --
- * nssCKFWCryptoOperation_GetMDCryptoOperation
- * nssCKFWCryptoOperation_GetType
- *
- * -- private accessors --
- *
- * -- module fronts --
- * nssCKFWCryptoOperation_GetFinalLength
- * nssCKFWCryptoOperation_GetOperationLength
- * nssCKFWCryptoOperation_Final
- * nssCKFWCryptoOperation_Update
- * nssCKFWCryptoOperation_DigestUpdate
- * nssCKFWCryptoOperation_DigestKey
- * nssCKFWCryptoOperation_UpdateFinal
- */
-
-/*
- * nssCKFWCrytoOperation_Create
- */
-NSS_EXTERN NSSCKFWCryptoOperation *
-nssCKFWCryptoOperation_Create
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWCryptoOperationType type,
- CK_RV *pError
-);
-
-/*
- * nssCKFWCryptoOperation_Destroy
- */
-NSS_EXTERN void
-nssCKFWCryptoOperation_Destroy
-(
- NSSCKFWCryptoOperation *fwOperation
-);
-
-/*
- * nssCKFWCryptoOperation_GetMDCryptoOperation
- */
-NSS_EXTERN NSSCKMDCryptoOperation *
-nssCKFWCryptoOperation_GetMDCryptoOperation
-(
- NSSCKFWCryptoOperation *fwOperation
-);
-
-/*
- * nssCKFWCryptoOperation_GetType
- */
-NSS_EXTERN NSSCKFWCryptoOperationType
-nssCKFWCryptoOperation_GetType
-(
- NSSCKFWCryptoOperation *fwOperation
-);
-
-/*
- * nssCKFWCryptoOperation_GetFinalLength
- */
-NSS_EXTERN CK_ULONG
-nssCKFWCryptoOperation_GetFinalLength
-(
- NSSCKFWCryptoOperation *fwOperation,
- CK_RV *pError
-);
-
-/*
- * nssCKFWCryptoOperation_GetOperationLength
- */
-NSS_EXTERN CK_ULONG
-nssCKFWCryptoOperation_GetOperationLength
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer,
- CK_RV *pError
-);
-
-/*
- * nssCKFWCryptoOperation_Final
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_Final
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *outputBuffer
-);
-
-/*
- * nssCKFWCryptoOperation_Update
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_Update
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer,
- NSSItem *outputBuffer
-);
-
-/*
- * nssCKFWCryptoOperation_DigestUpdate
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_DigestUpdate
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer
-);
-
-/*
- * nssCKFWCryptoOperation_DigestKey
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_DigestKey
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKFWObject *fwKey
-);
-
-/*
- * nssCKFWCryptoOperation_UpdateFinal
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_UpdateFinal
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer,
- NSSItem *outputBuffer
-);
-
-/*
- * nssCKFWCryptoOperation_UpdateCombo
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_UpdateCombo
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKFWCryptoOperation *fwPeerOperation,
- NSSItem *inputBuffer,
- NSSItem *outputBuffer
-);
-
-/*
- * NSSCKFWSession
- *
- * -- create/destroy --
- * nssCKFWSession_Create
- * nssCKFWSession_Destroy
- *
- * -- implement public accessors --
- * nssCKFWSession_GetMDSession
- * nssCKFWSession_GetArena
- * nssCKFWSession_CallNotification
- * nssCKFWSession_IsRWSession
- * nssCKFWSession_IsSO
- * nssCKFWSession_GetCurrentCryptoOperation
- *
- * -- private accessors --
- * nssCKFWSession_GetFWSlot
- * nssCKFWSession_GetSessionState
- * nssCKFWSession_SetFWFindObjects
- * nssCKFWSession_GetFWFindObjects
- * nssCKFWSession_SetMDSession
- * nssCKFWSession_SetHandle
- * nssCKFWSession_GetHandle
- * nssCKFWSession_RegisterSessionObject
- * nssCKFWSession_DeregisterSessionObject
- * nssCKFWSession_SetCurrentCryptoOperation
- *
- * -- module fronts --
- * nssCKFWSession_GetDeviceError
- * nssCKFWSession_Login
- * nssCKFWSession_Logout
- * nssCKFWSession_InitPIN
- * nssCKFWSession_SetPIN
- * nssCKFWSession_GetOperationStateLen
- * nssCKFWSession_GetOperationState
- * nssCKFWSession_SetOperationState
- * nssCKFWSession_CreateObject
- * nssCKFWSession_CopyObject
- * nssCKFWSession_FindObjectsInit
- * nssCKFWSession_SeedRandom
- * nssCKFWSession_GetRandom
- * nssCKFWSession_Final
- * nssCKFWSession_Update
- * nssCKFWSession_DigestUpdate
- * nssCKFWSession_DigestKey
- * nssCKFWSession_UpdateFinal
- * nssCKFWSession_UpdateCombo
- */
-
-/*
- * nssCKFWSession_Create
- *
- */
-NSS_EXTERN NSSCKFWSession *
-nssCKFWSession_Create
-(
- NSSCKFWToken *fwToken,
- CK_BBOOL rw,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_RV *pError
-);
-
-/*
- * nssCKFWSession_Destroy
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_Destroy
-(
- NSSCKFWSession *fwSession,
- CK_BBOOL removeFromTokenHash
-);
-
-/*
- * nssCKFWSession_GetMDSession
- *
- */
-NSS_EXTERN NSSCKMDSession *
-nssCKFWSession_GetMDSession
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWSession_GetArena
- *
- */
-NSS_EXTERN NSSArena *
-nssCKFWSession_GetArena
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
-
-/*
- * nssCKFWSession_CallNotification
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_CallNotification
-(
- NSSCKFWSession *fwSession,
- CK_NOTIFICATION event
-);
-
-/*
- * nssCKFWSession_IsRWSession
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWSession_IsRWSession
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWSession_IsSO
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWSession_IsSO
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWSession_GetFWSlot
- *
- */
-NSS_EXTERN NSSCKFWSlot *
-nssCKFWSession_GetFWSlot
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCFKWSession_GetSessionState
- *
- */
-NSS_EXTERN CK_STATE
-nssCKFWSession_GetSessionState
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWSession_SetFWFindObjects
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_SetFWFindObjects
-(
- NSSCKFWSession *fwSession,
- NSSCKFWFindObjects *fwFindObjects
-);
-
-/*
- * nssCKFWSession_GetFWFindObjects
- *
- */
-NSS_EXTERN NSSCKFWFindObjects *
-nssCKFWSession_GetFWFindObjects
-(
- NSSCKFWSession *fwSesssion,
- CK_RV *pError
-);
-
-/*
- * nssCKFWSession_SetMDSession
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_SetMDSession
-(
- NSSCKFWSession *fwSession,
- NSSCKMDSession *mdSession
-);
-
-/*
- * nssCKFWSession_SetHandle
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_SetHandle
-(
- NSSCKFWSession *fwSession,
- CK_SESSION_HANDLE hSession
-);
-
-/*
- * nssCKFWSession_GetHandle
- *
- */
-NSS_EXTERN CK_SESSION_HANDLE
-nssCKFWSession_GetHandle
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWSession_RegisterSessionObject
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_RegisterSessionObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWSession_DeregisterSessionObject
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_DeregisterSessionObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWSession_GetDeviceError
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWSession_GetDeviceError
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWSession_Login
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_Login
-(
- NSSCKFWSession *fwSession,
- CK_USER_TYPE userType,
- NSSItem *pin
-);
-
-/*
- * nssCKFWSession_Logout
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_Logout
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * nssCKFWSession_InitPIN
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_InitPIN
-(
- NSSCKFWSession *fwSession,
- NSSItem *pin
-);
-
-/*
- * nssCKFWSession_SetPIN
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_SetPIN
-(
- NSSCKFWSession *fwSession,
- NSSItem *newPin,
- NSSItem *oldPin
-);
-
-/*
- * nssCKFWSession_GetOperationStateLen
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWSession_GetOperationStateLen
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
-
-/*
- * nssCKFWSession_GetOperationState
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_GetOperationState
-(
- NSSCKFWSession *fwSession,
- NSSItem *buffer
-);
-
-/*
- * nssCKFWSession_SetOperationState
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_SetOperationState
-(
- NSSCKFWSession *fwSession,
- NSSItem *state,
- NSSCKFWObject *encryptionKey,
- NSSCKFWObject *authenticationKey
-);
-
-/*
- * nssCKFWSession_CreateObject
- *
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWSession_CreateObject
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-/*
- * nssCKFWSession_CopyObject
- *
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWSession_CopyObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *object,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-/*
- * nssCKFWSession_FindObjectsInit
- *
- */
-NSS_EXTERN NSSCKFWFindObjects *
-nssCKFWSession_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-/*
- * nssCKFWSession_SetCurrentCryptoOperation
- */
-NSS_IMPLEMENT void
-nssCKFWSession_SetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperation * fwOperation,
- NSSCKFWCryptoOperationState state
-);
-
-/*
- * nssCKFWSession_GetCurrentCryptoOperation
- */
-NSS_IMPLEMENT NSSCKFWCryptoOperation *
-nssCKFWSession_GetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationState state
-);
-
-/*
- * nssCKFWSession_Final
- * (terminate a cryptographic operation and get the result)
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_Final
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType type,
- NSSCKFWCryptoOperationState state,
- CK_BYTE_PTR outBuf,
- CK_ULONG_PTR outBufLen
-);
-
-/*
- * nssCKFWSession_Update
- * (get the next step of an encrypt/decrypt operation)
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_Update
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType type,
- NSSCKFWCryptoOperationState state,
- CK_BYTE_PTR inBuf,
- CK_ULONG inBufLen,
- CK_BYTE_PTR outBuf,
- CK_ULONG_PTR outBufLen
-);
-
-/*
- * nssCKFWSession_DigestUpdate
- * (do the next step of an digest/sign/verify operation)
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_DigestUpdate
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType type,
- NSSCKFWCryptoOperationState state,
- CK_BYTE_PTR inBuf,
- CK_ULONG inBufLen
-);
-
-/*
- * nssCKFWSession_DigestKey
- * (do the next step of an digest/sign/verify operation)
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_DigestKey
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwKey
-);
-
-/*
- * nssCKFWSession_UpdateFinal
- * (do a single-step of a cryptographic operation and get the result)
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_UpdateFinal
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType type,
- NSSCKFWCryptoOperationState state,
- CK_BYTE_PTR inBuf,
- CK_ULONG inBufLen,
- CK_BYTE_PTR outBuf,
- CK_ULONG_PTR outBufLen
-);
-
-/*
- * nssCKFWSession_UpdateCombo
- * (do a combination encrypt/decrypt and sign/digest/verify operation)
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_UpdateCombo
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType encryptType,
- NSSCKFWCryptoOperationType digestType,
- NSSCKFWCryptoOperationState digestState,
- CK_BYTE_PTR inBuf,
- CK_ULONG inBufLen,
- CK_BYTE_PTR outBuf,
- CK_ULONG_PTR outBufLen
-);
-
-/*
- * nssCKFWSession_SeedRandom
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_SeedRandom
-(
- NSSCKFWSession *fwSession,
- NSSItem *seed
-);
-
-/*
- * nssCKFWSession_GetRandom
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWSession_GetRandom
-(
- NSSCKFWSession *fwSession,
- NSSItem *buffer
-);
-
-/*
- * NSSCKFWObject
- *
- * -- create/destroy --
- * nssCKFWObject_Create
- * nssCKFWObject_Finalize
- * nssCKFWObject_Destroy
- *
- * -- implement public accessors --
- * nssCKFWObject_GetMDObject
- * nssCKFWObject_GetArena
- *
- * -- private accessors --
- * nssCKFWObject_SetHandle
- * nssCKFWObject_GetHandle
- *
- * -- module fronts --
- * nssCKFWObject_IsTokenObject
- * nssCKFWObject_GetAttributeCount
- * nssCKFWObject_GetAttributeTypes
- * nssCKFWObject_GetAttributeSize
- * nssCKFWObject_GetAttribute
- * nssCKFWObject_SetAttribute
- * nssCKFWObject_GetObjectSize
- */
-
-/*
- * nssCKFWObject_Create
- *
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWObject_Create
-(
- NSSArena *arena,
- NSSCKMDObject *mdObject,
- NSSCKFWSession *fwSession,
- NSSCKFWToken *fwToken,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
-
-/*
- * nssCKFWObject_Finalize
- *
- */
-NSS_EXTERN void
-nssCKFWObject_Finalize
-(
- NSSCKFWObject *fwObject,
- PRBool removeFromHash
-);
-
-/*
- * nssCKFWObject_Destroy
- *
- */
-NSS_EXTERN void
-nssCKFWObject_Destroy
-(
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWObject_GetMDObject
- *
- */
-NSS_EXTERN NSSCKMDObject *
-nssCKFWObject_GetMDObject
-(
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWObject_GetArena
- *
- */
-NSS_EXTERN NSSArena *
-nssCKFWObject_GetArena
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
-
-/*
- * nssCKFWObject_SetHandle
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWObject_SetHandle
-(
- NSSCKFWObject *fwObject,
- CK_OBJECT_HANDLE hObject
-);
-
-/*
- * nssCKFWObject_GetHandle
- *
- */
-NSS_EXTERN CK_OBJECT_HANDLE
-nssCKFWObject_GetHandle
-(
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWObject_IsTokenObject
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWObject_IsTokenObject
-(
- NSSCKFWObject *fwObject
-);
-
-/*
- * nssCKFWObject_GetAttributeCount
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWObject_GetAttributeCount
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
-
-/*
- * nssCKFWObject_GetAttributeTypes
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWObject_GetAttributeTypes
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-);
-
-/*
- * nssCKFWObject_GetAttributeSize
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWObject_GetAttributeSize
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-);
-
-/*
- * nssCKFWObject_GetAttribute
- *
- * Usual NSS allocation rules:
- * If itemOpt is not NULL, it will be returned; otherwise an NSSItem
- * will be allocated. If itemOpt is not NULL but itemOpt->data is,
- * the buffer will be allocated; otherwise, the buffer will be used.
- * Any allocations will come from the optional arena, if one is
- * specified.
- */
-NSS_EXTERN NSSItem *
-nssCKFWObject_GetAttribute
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *itemOpt,
- NSSArena *arenaOpt,
- CK_RV *pError
-);
-
-/*
- * nssCKFWObject_SetAttribute
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWObject_SetAttribute
-(
- NSSCKFWObject *fwObject,
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value
-);
-
-/*
- * nssCKFWObject_GetObjectSize
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWObject_GetObjectSize
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWFindObjects
- *
- * -- create/destroy --
- * nssCKFWFindObjects_Create
- * nssCKFWFindObjects_Destroy
- *
- * -- implement public accessors --
- * nssCKFWFindObjects_GetMDFindObjects
- *
- * -- private accessors --
- *
- * -- module fronts --
- * nssCKFWFindObjects_Next
- */
-
-/*
- * nssCKFWFindObjects_Create
- *
- */
-NSS_EXTERN NSSCKFWFindObjects *
-nssCKFWFindObjects_Create
-(
- NSSCKFWSession *fwSession,
- NSSCKFWToken *fwToken,
- NSSCKFWInstance *fwInstance,
- NSSCKMDFindObjects *mdFindObjects1,
- NSSCKMDFindObjects *mdFindObjects2,
- CK_RV *pError
-);
-
-/*
- * nssCKFWFindObjects_Destroy
- *
- */
-NSS_EXTERN void
-nssCKFWFindObjects_Destroy
-(
- NSSCKFWFindObjects *fwFindObjects
-);
-
-/*
- * nssCKFWFindObjects_GetMDFindObjects
- *
- */
-NSS_EXTERN NSSCKMDFindObjects *
-nssCKFWFindObjects_GetMDFindObjects
-(
- NSSCKFWFindObjects *fwFindObjects
-);
-
-/*
- * nssCKFWFindObjects_Next
- *
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWFindObjects_Next
-(
- NSSCKFWFindObjects *fwFindObjects,
- NSSArena *arenaOpt,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWMutex
- *
- * nssCKFWMutex_Create
- * nssCKFWMutex_Destroy
- * nssCKFWMutex_Lock
- * nssCKFWMutex_Unlock
- *
- */
-
-/*
- * nssCKFWMutex_Create
- *
- */
-NSS_EXTERN NSSCKFWMutex *
-nssCKFWMutex_Create
-(
- CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState LockingState,
- NSSArena *arena,
- CK_RV *pError
-);
-
-/*
- * nssCKFWMutex_Destroy
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWMutex_Destroy
-(
- NSSCKFWMutex *mutex
-);
-
-/*
- * nssCKFWMutex_Lock
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWMutex_Lock
-(
- NSSCKFWMutex *mutex
-);
-
-/*
- * nssCKFWMutex_Unlock
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWMutex_Unlock
-(
- NSSCKFWMutex *mutex
-);
-
-#endif /* CKFW_H */
diff --git a/security/nss/lib/ckfw/ckfwm.h b/security/nss/lib/ckfw/ckfwm.h
deleted file mode 100644
index 651435e12..000000000
--- a/security/nss/lib/ckfw/ckfwm.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CKFWM_H
-#define CKFWM_H
-
-#ifdef DEBUG
-static const char CKFWM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * ckfwm.h
- *
- * This file prototypes the module-private calls of the NSS Cryptoki Framework.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFWT_H
-#include "nssckfwt.h"
-#endif /* NSSCKFWT_H */
-
-/*
- * nssCKFWHash
- *
- * nssCKFWHash_Create
- * nssCKFWHash_Destroy
- * nssCKFWHash_Add
- * nssCKFWHash_Remove
- * nssCKFWHash_Count
- * nssCKFWHash_Exists
- * nssCKFWHash_Lookup
- * nssCKFWHash_Iterate
- */
-
-/*
- * nssCKFWHash_Create
- *
- */
-NSS_EXTERN nssCKFWHash *
-nssCKFWHash_Create
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-);
-
-/*
- * nssCKFWHash_Destroy
- *
- */
-NSS_EXTERN void
-nssCKFWHash_Destroy
-(
- nssCKFWHash *hash
-);
-
-/*
- * nssCKFWHash_Add
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWHash_Add
-(
- nssCKFWHash *hash,
- const void *key,
- const void *value
-);
-
-/*
- * nssCKFWHash_Remove
- *
- */
-NSS_EXTERN void
-nssCKFWHash_Remove
-(
- nssCKFWHash *hash,
- const void *it
-);
-
-/*
- * nssCKFWHash_Count
- *
- */
-NSS_EXTERN CK_ULONG
-nssCKFWHash_Count
-(
- nssCKFWHash *hash
-);
-
-/*
- * nssCKFWHash_Exists
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWHash_Exists
-(
- nssCKFWHash *hash,
- const void *it
-);
-
-/*
- * nssCKFWHash_Lookup
- *
- */
-NSS_EXTERN void *
-nssCKFWHash_Lookup
-(
- nssCKFWHash *hash,
- const void *it
-);
-
-/*
- * nssCKFWHash_Iterate
- *
- */
-NSS_EXTERN void
-nssCKFWHash_Iterate
-(
- nssCKFWHash *hash,
- nssCKFWHashIterator fcn,
- void *closure
-);
-
-#endif /* CKFWM_H */
diff --git a/security/nss/lib/ckfw/ckfwtm.h b/security/nss/lib/ckfw/ckfwtm.h
deleted file mode 100644
index 7891918ec..000000000
--- a/security/nss/lib/ckfw/ckfwtm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CKFWTM_H
-#define CKFWTM_H
-
-#ifdef DEBUG
-static const char CKFWTM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * ckfwtm.h
- *
- * This file declares the module-private types of the NSS Cryptoki Framework.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-struct nssCKFWHashStr;
-typedef struct nssCKFWHashStr nssCKFWHash;
-
-typedef void (PR_CALLBACK *nssCKFWHashIterator)(const void *key, void *value, void *closure);
-
-#endif /* CKFWTM_H */
diff --git a/security/nss/lib/ckfw/ckmd.h b/security/nss/lib/ckfw/ckmd.h
deleted file mode 100644
index d995f360c..000000000
--- a/security/nss/lib/ckfw/ckmd.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CKMD_H
-#define CKMD_H
-
-#ifdef DEBUG
-static const char CKMD_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * ckmd.h
- *
- */
-
-NSS_EXTERN NSSCKMDObject *
-nssCKMDSessionObject_Create
-(
- NSSCKFWToken *fwToken,
- NSSArena *arena,
- CK_ATTRIBUTE_PTR attributes,
- CK_ULONG ulCount,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDFindObjects *
-nssCKMDFindSessionObjects_Create
-(
- NSSCKFWToken *fwToken,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_RV *pError
-);
-
-#endif /* CKMD_H */
diff --git a/security/nss/lib/ckfw/ckt.h b/security/nss/lib/ckfw/ckt.h
deleted file mode 100644
index 05c43a5db..000000000
--- a/security/nss/lib/ckfw/ckt.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* get back to just one set of PKCS #11 headers. Use the onese that
- * are easiest to maintain from the RSA website */
-/* this one is the one that defines NSS specific data */
-#include "pkcs11n.h"
diff --git a/security/nss/lib/ckfw/config.mk b/security/nss/lib/ckfw/config.mk
deleted file mode 100644
index aa84677fe..000000000
--- a/security/nss/lib/ckfw/config.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-ifdef BUILD_IDG
-DEFINES += -DNSSDEBUG
-endif
-
-#
-# Hack to see if everything still builds
-#
-
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
-
diff --git a/security/nss/lib/ckfw/crypto.c b/security/nss/lib/ckfw/crypto.c
deleted file mode 100644
index 13ac0b982..000000000
--- a/security/nss/lib/ckfw/crypto.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * crypto.c
- *
- * This file implements the NSSCKFWCryptoOperation type and methods.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * NSSCKFWCryptoOperation
- *
- * -- create/destroy --
- * nssCKFWCrytoOperation_Create
- * nssCKFWCryptoOperation_Destroy
- *
- * -- implement public accessors --
- * nssCKFWCryptoOperation_GetMDCryptoOperation
- * nssCKFWCryptoOperation_GetType
- *
- * -- private accessors --
- *
- * -- module fronts --
- * nssCKFWCryptoOperation_GetFinalLength
- * nssCKFWCryptoOperation_GetOperationLength
- * nssCKFWCryptoOperation_Final
- * nssCKFWCryptoOperation_Update
- * nssCKFWCryptoOperation_DigestUpdate
- * nssCKFWCryptoOperation_UpdateFinal
- */
-
-struct NSSCKFWCryptoOperationStr {
- /* NSSArena *arena; */
- NSSCKMDCryptoOperation *mdOperation;
- NSSCKMDSession *mdSession;
- NSSCKFWSession *fwSession;
- NSSCKMDToken *mdToken;
- NSSCKFWToken *fwToken;
- NSSCKMDInstance *mdInstance;
- NSSCKFWInstance *fwInstance;
- NSSCKFWCryptoOperationType type;
-};
-
-/*
- * nssCKFWCrytoOperation_Create
- */
-NSS_EXTERN NSSCKFWCryptoOperation *
-nssCKFWCryptoOperation_Create(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWCryptoOperationType type,
- CK_RV *pError
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- fwOperation = nss_ZNEW(NULL, NSSCKFWCryptoOperation);
- if (!fwOperation) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWCryptoOperation *)NULL;
- }
- fwOperation->mdOperation = mdOperation;
- fwOperation->mdSession = mdSession;
- fwOperation->fwSession = fwSession;
- fwOperation->mdToken = mdToken;
- fwOperation->fwToken = fwToken;
- fwOperation->mdInstance = mdInstance;
- fwOperation->fwInstance = fwInstance;
- fwOperation->type = type;
- return fwOperation;
-}
-
-/*
- * nssCKFWCryptoOperation_Destroy
- */
-NSS_EXTERN void
-nssCKFWCryptoOperation_Destroy
-(
- NSSCKFWCryptoOperation *fwOperation
-)
-{
- if ((NSSCKMDCryptoOperation *) NULL != fwOperation->mdOperation) {
- if (fwOperation->mdOperation->Destroy) {
- fwOperation->mdOperation->Destroy(
- fwOperation->mdOperation,
- fwOperation,
- fwOperation->mdInstance,
- fwOperation->fwInstance);
- }
- }
- nss_ZFreeIf(fwOperation);
-}
-
-/*
- * nssCKFWCryptoOperation_GetMDCryptoOperation
- */
-NSS_EXTERN NSSCKMDCryptoOperation *
-nssCKFWCryptoOperation_GetMDCryptoOperation
-(
- NSSCKFWCryptoOperation *fwOperation
-)
-{
- return fwOperation->mdOperation;
-}
-
-/*
- * nssCKFWCryptoOperation_GetType
- */
-NSS_EXTERN NSSCKFWCryptoOperationType
-nssCKFWCryptoOperation_GetType
-(
- NSSCKFWCryptoOperation *fwOperation
-)
-{
- return fwOperation->type;
-}
-
-/*
- * nssCKFWCryptoOperation_GetFinalLength
- */
-NSS_EXTERN CK_ULONG
-nssCKFWCryptoOperation_GetFinalLength
-(
- NSSCKFWCryptoOperation *fwOperation,
- CK_RV *pError
-)
-{
- if (!fwOperation->mdOperation->GetFinalLength) {
- *pError = CKR_FUNCTION_FAILED;
- return 0;
- }
- return fwOperation->mdOperation->GetFinalLength(
- fwOperation->mdOperation,
- fwOperation,
- fwOperation->mdSession,
- fwOperation->fwSession,
- fwOperation->mdToken,
- fwOperation->fwToken,
- fwOperation->mdInstance,
- fwOperation->fwInstance,
- pError);
-}
-
-/*
- * nssCKFWCryptoOperation_GetOperationLength
- */
-NSS_EXTERN CK_ULONG
-nssCKFWCryptoOperation_GetOperationLength
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer,
- CK_RV *pError
-)
-{
- if (!fwOperation->mdOperation->GetOperationLength) {
- *pError = CKR_FUNCTION_FAILED;
- return 0;
- }
- return fwOperation->mdOperation->GetOperationLength(
- fwOperation->mdOperation,
- fwOperation,
- fwOperation->mdSession,
- fwOperation->fwSession,
- fwOperation->mdToken,
- fwOperation->fwToken,
- fwOperation->mdInstance,
- fwOperation->fwInstance,
- inputBuffer,
- pError);
-}
-
-/*
- * nssCKFWCryptoOperation_Final
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_Final
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *outputBuffer
-)
-{
- if (!fwOperation->mdOperation->Final) {
- return CKR_FUNCTION_FAILED;
- }
- return fwOperation->mdOperation->Final(
- fwOperation->mdOperation,
- fwOperation,
- fwOperation->mdSession,
- fwOperation->fwSession,
- fwOperation->mdToken,
- fwOperation->fwToken,
- fwOperation->mdInstance,
- fwOperation->fwInstance,
- outputBuffer);
-}
-
-/*
- * nssCKFWCryptoOperation_Update
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_Update
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer,
- NSSItem *outputBuffer
-)
-{
- if (!fwOperation->mdOperation->Update) {
- return CKR_FUNCTION_FAILED;
- }
- return fwOperation->mdOperation->Update(
- fwOperation->mdOperation,
- fwOperation,
- fwOperation->mdSession,
- fwOperation->fwSession,
- fwOperation->mdToken,
- fwOperation->fwToken,
- fwOperation->mdInstance,
- fwOperation->fwInstance,
- inputBuffer,
- outputBuffer);
-}
-
-/*
- * nssCKFWCryptoOperation_DigestUpdate
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_DigestUpdate
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer
-)
-{
- if (!fwOperation->mdOperation->DigestUpdate) {
- return CKR_FUNCTION_FAILED;
- }
- return fwOperation->mdOperation->DigestUpdate(
- fwOperation->mdOperation,
- fwOperation,
- fwOperation->mdSession,
- fwOperation->fwSession,
- fwOperation->mdToken,
- fwOperation->fwToken,
- fwOperation->mdInstance,
- fwOperation->fwInstance,
- inputBuffer);
-}
-
-/*
- * nssCKFWCryptoOperation_DigestKey
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_DigestKey
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKFWObject *fwObject /* Key */
-)
-{
- NSSCKMDObject *mdObject;
-
- if (!fwOperation->mdOperation->DigestKey) {
- return CKR_FUNCTION_FAILED;
- }
- mdObject = nssCKFWObject_GetMDObject(fwObject);
- return fwOperation->mdOperation->DigestKey(
- fwOperation->mdOperation,
- fwOperation,
- fwOperation->mdToken,
- fwOperation->fwToken,
- fwOperation->mdInstance,
- fwOperation->fwInstance,
- mdObject,
- fwObject);
-}
-
-/*
- * nssCKFWCryptoOperation_UpdateFinal
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_UpdateFinal
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSItem *inputBuffer,
- NSSItem *outputBuffer
-)
-{
- if (!fwOperation->mdOperation->UpdateFinal) {
- return CKR_FUNCTION_FAILED;
- }
- return fwOperation->mdOperation->UpdateFinal(
- fwOperation->mdOperation,
- fwOperation,
- fwOperation->mdSession,
- fwOperation->fwSession,
- fwOperation->mdToken,
- fwOperation->fwToken,
- fwOperation->mdInstance,
- fwOperation->fwInstance,
- inputBuffer,
- outputBuffer);
-}
-
-/*
- * nssCKFWCryptoOperation_UpdateCombo
- */
-NSS_EXTERN CK_RV
-nssCKFWCryptoOperation_UpdateCombo
-(
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKFWCryptoOperation *fwPeerOperation,
- NSSItem *inputBuffer,
- NSSItem *outputBuffer
-)
-{
- if (!fwOperation->mdOperation->UpdateCombo) {
- return CKR_FUNCTION_FAILED;
- }
- return fwOperation->mdOperation->UpdateCombo(
- fwOperation->mdOperation,
- fwOperation,
- fwPeerOperation->mdOperation,
- fwPeerOperation,
- fwOperation->mdSession,
- fwOperation->fwSession,
- fwOperation->mdToken,
- fwOperation->fwToken,
- fwOperation->mdInstance,
- fwOperation->fwInstance,
- inputBuffer,
- outputBuffer);
-}
diff --git a/security/nss/lib/ckfw/dbm/Makefile b/security/nss/lib/ckfw/dbm/Makefile
deleted file mode 100644
index 4d2af2a2a..000000000
--- a/security/nss/lib/ckfw/dbm/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-include manifest.mn
-include config.mk
-include $(CORE_DEPTH)/coreconf/config.mk
-include $(CORE_DEPTH)/coreconf/rules.mk
diff --git a/security/nss/lib/ckfw/dbm/anchor.c b/security/nss/lib/ckfw/dbm/anchor.c
deleted file mode 100644
index 08b5d1a1c..000000000
--- a/security/nss/lib/ckfw/dbm/anchor.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * dbm/anchor.c
- *
- * This file "anchors" the actual cryptoki entry points in this module's
- * shared library, which is required for dynamic loading. See the
- * comments in nssck.api for more information.
- */
-
-#include "ckdbm.h"
-
-#define MODULE_NAME dbm
-#define INSTANCE_NAME (NSSCKMDInstance *)&nss_dbm_mdInstance
-#include "nssck.api"
diff --git a/security/nss/lib/ckfw/dbm/ckdbm.h b/security/nss/lib/ckfw/dbm/ckdbm.h
deleted file mode 100644
index b30b2fcc4..000000000
--- a/security/nss/lib/ckfw/dbm/ckdbm.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CKDBM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef CKDBM_H
-#define CKDBM_H
-
-#include "nssckmdt.h"
-#include "nssckfw.h"
-
-/*
- * I'm including this for access to the arena functions.
- * Looks like we should publish that API.
- */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-/*
- * This is where the Netscape extensions live, at least for now.
- */
-#ifndef CKT_H
-#include "ckt.h"
-#endif /* CKT_H */
-
-#include "mcom_db.h"
-
-NSS_EXTERN_DATA NSSCKMDInstance nss_dbm_mdInstance;
-
-typedef struct nss_dbm_db_struct nss_dbm_db_t;
-struct nss_dbm_db_struct {
- DB *db;
- NSSCKFWMutex *crustylock;
-};
-
-typedef struct nss_dbm_dbt_struct nss_dbm_dbt_t;
-struct nss_dbm_dbt_struct {
- DBT dbt;
- nss_dbm_db_t *my_db;
-};
-
-typedef struct nss_dbm_instance_struct nss_dbm_instance_t;
-struct nss_dbm_instance_struct {
- NSSArena *arena;
- CK_ULONG nSlots;
- char **filenames;
- int *flags; /* e.g. O_RDONLY, O_RDWR */
-};
-
-typedef struct nss_dbm_slot_struct nss_dbm_slot_t;
-struct nss_dbm_slot_struct {
- nss_dbm_instance_t *instance;
- char *filename;
- int flags;
- nss_dbm_db_t *token_db;
-};
-
-typedef struct nss_dbm_token_struct nss_dbm_token_t;
-struct nss_dbm_token_struct {
- NSSArena *arena;
- nss_dbm_slot_t *slot;
- nss_dbm_db_t *session_db;
- NSSUTF8 *label;
-};
-
-struct nss_dbm_dbt_node {
- struct nss_dbm_dbt_node *next;
- nss_dbm_dbt_t *dbt;
-};
-
-typedef struct nss_dbm_session_struct nss_dbm_session_t;
-struct nss_dbm_session_struct {
- NSSArena *arena;
- nss_dbm_token_t *token;
- CK_ULONG deviceError;
- struct nss_dbm_dbt_node *session_objects;
- NSSCKFWMutex *list_lock;
-};
-
-typedef struct nss_dbm_object_struct nss_dbm_object_t;
-struct nss_dbm_object_struct {
- NSSArena *arena; /* token or session */
- nss_dbm_dbt_t *handle;
-};
-
-typedef struct nss_dbm_find_struct nss_dbm_find_t;
-struct nss_dbm_find_struct {
- NSSArena *arena;
- struct nss_dbm_dbt_node *found;
- NSSCKFWMutex *list_lock;
-};
-
-NSS_EXTERN NSSCKMDSlot *
-nss_dbm_mdSlot_factory
-(
- nss_dbm_instance_t *instance,
- char *filename,
- int flags,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDToken *
-nss_dbm_mdToken_factory
-(
- nss_dbm_slot_t *slot,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDSession *
-nss_dbm_mdSession_factory
-(
- nss_dbm_token_t *token,
- NSSCKFWSession *fwSession,
- NSSCKFWInstance *fwInstance,
- CK_BBOOL rw,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDObject *
-nss_dbm_mdObject_factory
-(
- nss_dbm_object_t *object,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDFindObjects *
-nss_dbm_mdFindObjects_factory
-(
- nss_dbm_find_t *find,
- CK_RV *pError
-);
-
-NSS_EXTERN nss_dbm_db_t *
-nss_dbm_db_open
-(
- NSSArena *arena,
- NSSCKFWInstance *fwInstance,
- char *filename,
- int flags,
- CK_RV *pError
-);
-
-NSS_EXTERN void
-nss_dbm_db_close
-(
- nss_dbm_db_t *db
-);
-
-NSS_EXTERN CK_VERSION
-nss_dbm_db_get_format_version
-(
- nss_dbm_db_t *db
-);
-
-NSS_EXTERN CK_RV
-nss_dbm_db_set_label
-(
- nss_dbm_db_t *db,
- NSSUTF8 *label
-);
-
-NSS_EXTERN NSSUTF8 *
-nss_dbm_db_get_label
-(
- nss_dbm_db_t *db,
- NSSArena *arena,
- CK_RV *pError
-);
-
-NSS_EXTERN CK_RV
-nss_dbm_db_delete_object
-(
- nss_dbm_dbt_t *dbt
-);
-
-NSS_EXTERN nss_dbm_dbt_t *
-nss_dbm_db_create_object
-(
- NSSArena *arena,
- nss_dbm_db_t *db,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError,
- CK_ULONG *pdbrv
-);
-
-NSS_EXTERN CK_RV
-nss_dbm_db_find_objects
-(
- nss_dbm_find_t *find,
- nss_dbm_db_t *db,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_ULONG *pdbrv
-);
-
-NSS_EXTERN CK_BBOOL
-nss_dbm_db_object_still_exists
-(
- nss_dbm_dbt_t *dbt
-);
-
-NSS_EXTERN CK_ULONG
-nss_dbm_db_get_object_attribute_count
-(
- nss_dbm_dbt_t *dbt,
- CK_RV *pError,
- CK_ULONG *pdbrv
-);
-
-NSS_EXTERN CK_RV
-nss_dbm_db_get_object_attribute_types
-(
- nss_dbm_dbt_t *dbt,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount,
- CK_ULONG *pdbrv
-);
-
-NSS_EXTERN CK_ULONG
-nss_dbm_db_get_object_attribute_size
-(
- nss_dbm_dbt_t *dbt,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError,
- CK_ULONG *pdbrv
-);
-
-NSS_EXTERN NSSItem *
-nss_dbm_db_get_object_attribute
-(
- nss_dbm_dbt_t *dbt,
- NSSArena *arena,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError,
- CK_ULONG *pdbrv
-);
-
-NSS_EXTERN CK_RV
-nss_dbm_db_set_object_attribute
-(
- nss_dbm_dbt_t *dbt,
- CK_ATTRIBUTE_TYPE type,
- NSSItem *value,
- CK_ULONG *pdbrv
-);
-
-#endif /* CKDBM_H */
diff --git a/security/nss/lib/ckfw/dbm/config.mk b/security/nss/lib/ckfw/dbm/config.mk
deleted file mode 100644
index 489eb9748..000000000
--- a/security/nss/lib/ckfw/dbm/config.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-ifdef BUILD_IDG
-DEFINES += -DNSSDEBUG
-endif
diff --git a/security/nss/lib/ckfw/dbm/db.c b/security/nss/lib/ckfw/dbm/db.c
deleted file mode 100644
index 7fb50077f..000000000
--- a/security/nss/lib/ckfw/dbm/db.c
+++ /dev/null
@@ -1,1036 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckdbm.h"
-
-#define PREFIX_METADATA "0000"
-#define PREFIX_OBJECT "0001"
-#define PREFIX_INDEX "0002"
-
-static CK_VERSION nss_dbm_db_format_version = { 1, 0 };
-struct handle {
- char prefix[4];
- CK_ULONG id;
-};
-
-NSS_IMPLEMENT nss_dbm_db_t *
-nss_dbm_db_open
-(
- NSSArena *arena,
- NSSCKFWInstance *fwInstance,
- char *filename,
- int flags,
- CK_RV *pError
-)
-{
- nss_dbm_db_t *rv;
- CK_VERSION db_version;
-
- rv = nss_ZNEW(arena, nss_dbm_db_t);
- if( (nss_dbm_db_t *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (nss_dbm_db_t *)NULL;
- }
-
- rv->db = dbopen(filename, flags, 0600, DB_HASH, (const void *)NULL);
- if( (DB *)NULL == rv->db ) {
- *pError = CKR_TOKEN_NOT_PRESENT;
- return (nss_dbm_db_t *)NULL;
- }
-
- rv->crustylock = NSSCKFWInstance_CreateMutex(fwInstance, arena, pError);
- if( (NSSCKFWMutex *)NULL == rv->crustylock ) {
- return (nss_dbm_db_t *)NULL;
- }
-
- db_version = nss_dbm_db_get_format_version(rv);
- if( db_version.major != nss_dbm_db_format_version.major ) {
- nss_dbm_db_close(rv);
- *pError = CKR_TOKEN_NOT_RECOGNIZED;
- return (nss_dbm_db_t *)NULL;
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT void
-nss_dbm_db_close
-(
- nss_dbm_db_t *db
-)
-{
- if( (NSSCKFWMutex *)NULL != db->crustylock ) {
- (void)NSSCKFWMutex_Destroy(db->crustylock);
- }
-
- if( (DB *)NULL != db->db ) {
- (void)db->db->close(db->db);
- }
-
- nss_ZFreeIf(db);
-}
-
-NSS_IMPLEMENT CK_VERSION
-nss_dbm_db_get_format_version
-(
- nss_dbm_db_t *db
-)
-{
- CK_VERSION rv;
- DBT k, v;
- int dbrv;
- char buffer[64];
-
- rv.major = rv.minor = 0;
-
- k.data = PREFIX_METADATA "FormatVersion";
- k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
- (void)memset(&v, 0, sizeof(v));
-
- /* Locked region */
- {
- if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) {
- return rv;
- }
-
- dbrv = db->db->get(db->db, &k, &v, 0);
- if( dbrv == 0 ) {
- CK_ULONG major = 0, minor = 0;
- (void)PR_sscanf(v.data, "%ld.%ld", &major, &minor);
- rv.major = major;
- rv.minor = minor;
- } else if( dbrv > 0 ) {
- (void)PR_snprintf(buffer, sizeof(buffer), "%ld.%ld", nss_dbm_db_format_version.major,
- nss_dbm_db_format_version.minor);
- v.data = buffer;
- v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL);
- dbrv = db->db->put(db->db, &k, &v, 0);
- (void)db->db->sync(db->db, 0);
- rv = nss_dbm_db_format_version;
- } else {
- /* No error return.. */
- ;
- }
-
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT CK_RV
-nss_dbm_db_set_label
-(
- nss_dbm_db_t *db,
- NSSUTF8 *label
-)
-{
- CK_RV rv;
- DBT k, v;
- int dbrv;
-
- k.data = PREFIX_METADATA "Label";
- k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
- v.data = label;
- v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL);
-
- /* Locked region */
- {
- if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) {
- return rv;
- }
-
- dbrv = db->db->put(db->db, &k, &v, 0);
- if( 0 != dbrv ) {
- rv = CKR_DEVICE_ERROR;
- }
-
- dbrv = db->db->sync(db->db, 0);
- if( 0 != dbrv ) {
- rv = CKR_DEVICE_ERROR;
- }
-
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT NSSUTF8 *
-nss_dbm_db_get_label
-(
- nss_dbm_db_t *db,
- NSSArena *arena,
- CK_RV *pError
-)
-{
- NSSUTF8 *rv = (NSSUTF8 *)NULL;
- DBT k, v;
- int dbrv;
-
- k.data = PREFIX_METADATA "Label";
- k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
-
- /* Locked region */
- {
- if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) {
- return rv;
- }
-
- dbrv = db->db->get(db->db, &k, &v, 0);
- if( 0 == dbrv ) {
- rv = nssUTF8_Duplicate((NSSUTF8 *)v.data, arena);
- if( (NSSUTF8 *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- }
- } else if( dbrv > 0 ) {
- /* Just return null */
- ;
- } else {
- *pError = CKR_DEVICE_ERROR;
- ;
- }
-
-
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT CK_RV
-nss_dbm_db_delete_object
-(
- nss_dbm_dbt_t *dbt
-)
-{
- CK_RV rv;
- int dbrv;
-
- /* Locked region */
- {
- rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
- if( CKR_OK != rv ) {
- return rv;
- }
-
- dbrv = dbt->my_db->db->del(dbt->my_db->db, &dbt->dbt, 0);
- if( 0 != dbrv ) {
- rv = CKR_DEVICE_ERROR;
- goto done;
- }
-
- dbrv = dbt->my_db->db->sync(dbt->my_db->db, 0);
- if( 0 != dbrv ) {
- rv = CKR_DEVICE_ERROR;
- goto done;
- }
-
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
-
- return rv;
-}
-
-static CK_ULONG
-nss_dbm_db_new_handle
-(
- nss_dbm_db_t *db,
- DBT *dbt, /* pre-allocated */
- CK_RV *pError
-)
-{
- CK_ULONG rv;
- DBT k, v;
- CK_ULONG align = 0, id, myid;
- struct handle *hp;
-
- if( sizeof(struct handle) != dbt->size ) {
- return EINVAL;
- }
-
- /* Locked region */
- {
- *pError = NSSCKFWMutex_Lock(db->crustylock);
- if( CKR_OK != *pError ) {
- return EINVAL;
- }
-
- k.data = PREFIX_METADATA "LastID";
- k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
- (void)memset(&v, 0, sizeof(v));
-
- rv = db->db->get(db->db, &k, &v, 0);
- if( 0 == rv ) {
- (void)memcpy(&align, v.data, sizeof(CK_ULONG));
- id = ntohl(align);
- } else if( rv > 0 ) {
- id = 0;
- } else {
- goto done;
- }
-
- myid = id;
- id++;
- align = htonl(id);
- v.data = &align;
- v.size = sizeof(CK_ULONG);
-
- rv = db->db->put(db->db, &k, &v, 0);
- if( 0 != rv ) {
- goto done;
- }
-
- rv = db->db->sync(db->db, 0);
- if( 0 != rv ) {
- goto done;
- }
-
- done:
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
-
- if( 0 != rv ) {
- return rv;
- }
-
- hp = (struct handle *)dbt->data;
- (void)memcpy(&hp->prefix[0], PREFIX_OBJECT, 4);
- hp->id = myid;
-
- return 0;
-}
-
-/*
- * This attribute-type-dependent swapping should probably
- * be in the Framework, because it'll be a concern of just
- * about every Module. Of course any Framework implementation
- * will have to be augmentable or overridable by a Module.
- */
-
-enum swap_type { type_byte, type_short, type_long, type_opaque };
-
-static enum swap_type
-nss_dbm_db_swap_type
-(
- CK_ATTRIBUTE_TYPE type
-)
-{
- switch( type ) {
- case CKA_CLASS: return type_long;
- case CKA_TOKEN: return type_byte;
- case CKA_PRIVATE: return type_byte;
- case CKA_LABEL: return type_opaque;
- case CKA_APPLICATION: return type_opaque;
- case CKA_VALUE: return type_opaque;
- case CKA_CERTIFICATE_TYPE: return type_long;
- case CKA_ISSUER: return type_opaque;
- case CKA_SERIAL_NUMBER: return type_opaque;
- case CKA_KEY_TYPE: return type_long;
- case CKA_SUBJECT: return type_opaque;
- case CKA_ID: return type_opaque;
- case CKA_SENSITIVE: return type_byte;
- case CKA_ENCRYPT: return type_byte;
- case CKA_DECRYPT: return type_byte;
- case CKA_WRAP: return type_byte;
- case CKA_UNWRAP: return type_byte;
- case CKA_SIGN: return type_byte;
- case CKA_SIGN_RECOVER: return type_byte;
- case CKA_VERIFY: return type_byte;
- case CKA_VERIFY_RECOVER: return type_byte;
- case CKA_DERIVE: return type_byte;
- case CKA_START_DATE: return type_opaque;
- case CKA_END_DATE: return type_opaque;
- case CKA_MODULUS: return type_opaque;
- case CKA_MODULUS_BITS: return type_long;
- case CKA_PUBLIC_EXPONENT: return type_opaque;
- case CKA_PRIVATE_EXPONENT: return type_opaque;
- case CKA_PRIME_1: return type_opaque;
- case CKA_PRIME_2: return type_opaque;
- case CKA_EXPONENT_1: return type_opaque;
- case CKA_EXPONENT_2: return type_opaque;
- case CKA_COEFFICIENT: return type_opaque;
- case CKA_PRIME: return type_opaque;
- case CKA_SUBPRIME: return type_opaque;
- case CKA_BASE: return type_opaque;
- case CKA_VALUE_BITS: return type_long;
- case CKA_VALUE_LEN: return type_long;
- case CKA_EXTRACTABLE: return type_byte;
- case CKA_LOCAL: return type_byte;
- case CKA_NEVER_EXTRACTABLE: return type_byte;
- case CKA_ALWAYS_SENSITIVE: return type_byte;
- case CKA_MODIFIABLE: return type_byte;
- case CKA_NETSCAPE_URL: return type_opaque;
- case CKA_NETSCAPE_EMAIL: return type_opaque;
- case CKA_NETSCAPE_SMIME_INFO: return type_opaque;
- case CKA_NETSCAPE_SMIME_TIMESTAMP: return type_opaque;
- case CKA_NETSCAPE_PKCS8_SALT: return type_opaque;
- case CKA_NETSCAPE_PASSWORD_CHECK: return type_opaque;
- case CKA_NETSCAPE_EXPIRES: return type_opaque;
- case CKA_TRUST_DIGITAL_SIGNATURE: return type_long;
- case CKA_TRUST_NON_REPUDIATION: return type_long;
- case CKA_TRUST_KEY_ENCIPHERMENT: return type_long;
- case CKA_TRUST_DATA_ENCIPHERMENT: return type_long;
- case CKA_TRUST_KEY_AGREEMENT: return type_long;
- case CKA_TRUST_KEY_CERT_SIGN: return type_long;
- case CKA_TRUST_CRL_SIGN: return type_long;
- case CKA_TRUST_SERVER_AUTH: return type_long;
- case CKA_TRUST_CLIENT_AUTH: return type_long;
- case CKA_TRUST_CODE_SIGNING: return type_long;
- case CKA_TRUST_EMAIL_PROTECTION: return type_long;
- case CKA_TRUST_IPSEC_END_SYSTEM: return type_long;
- case CKA_TRUST_IPSEC_TUNNEL: return type_long;
- case CKA_TRUST_IPSEC_USER: return type_long;
- case CKA_TRUST_TIME_STAMPING: return type_long;
- case CKA_NETSCAPE_DB: return type_opaque;
- case CKA_NETSCAPE_TRUST: return type_opaque;
- default: return type_opaque;
- }
-}
-
-static void
-nss_dbm_db_swap_copy
-(
- CK_ATTRIBUTE_TYPE type,
- void *dest,
- void *src,
- CK_ULONG len
-)
-{
- switch( nss_dbm_db_swap_type(type) ) {
- case type_byte:
- case type_opaque:
- (void)memcpy(dest, src, len);
- break;
- case type_short:
- {
- CK_USHORT s, d;
- (void)memcpy(&s, src, sizeof(CK_USHORT));
- d = htons(s);
- (void)memcpy(dest, &d, sizeof(CK_USHORT));
- break;
- }
- case type_long:
- {
- CK_ULONG s, d;
- (void)memcpy(&s, src, sizeof(CK_ULONG));
- d = htonl(s);
- (void)memcpy(dest, &d, sizeof(CK_ULONG));
- break;
- }
- }
-}
-
-static CK_RV
-nss_dbm_db_wrap_object
-(
- NSSArena *arena,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- DBT *object
-)
-{
- CK_ULONG object_size;
- CK_ULONG i;
- CK_ULONG *pulData;
- char *pcData;
- CK_ULONG offset;
-
- object_size = (1 + ulAttributeCount*3) * sizeof(CK_ULONG);
- offset = object_size;
- for( i = 0; i < ulAttributeCount; i++ ) {
- object_size += pTemplate[i].ulValueLen;
- }
-
- object->size = object_size;
- object->data = nss_ZAlloc(arena, object_size);
- if( (void *)NULL == object->data ) {
- return CKR_HOST_MEMORY;
- }
-
- pulData = (CK_ULONG *)object->data;
- pcData = (char *)object->data;
-
- pulData[0] = htonl(ulAttributeCount);
- for( i = 0; i < ulAttributeCount; i++ ) {
- CK_ULONG len = pTemplate[i].ulValueLen;
- pulData[1 + i*3] = htonl(pTemplate[i].type);
- pulData[2 + i*3] = htonl(len);
- pulData[3 + i*3] = htonl(offset);
- nss_dbm_db_swap_copy(pTemplate[i].type, &pcData[offset], pTemplate[i].pValue, len);
- offset += len;
- }
-
- return CKR_OK;
-}
-
-static CK_RV
-nss_dbm_db_unwrap_object
-(
- NSSArena *arena,
- DBT *object,
- CK_ATTRIBUTE_PTR *ppTemplate,
- CK_ULONG *pulAttributeCount
-)
-{
- CK_ULONG *pulData;
- char *pcData;
- CK_ULONG n, i;
- CK_ATTRIBUTE_PTR pTemplate;
-
- pulData = (CK_ULONG *)object->data;
- pcData = (char *)object->data;
-
- n = ntohl(pulData[0]);
- *pulAttributeCount = n;
- pTemplate = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, n);
- if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
- return CKR_HOST_MEMORY;
- }
-
- for( i = 0; i < n; i++ ) {
- CK_ULONG len;
- CK_ULONG offset;
- void *p;
-
- pTemplate[i].type = ntohl(pulData[1 + i*3]);
- len = ntohl(pulData[2 + i*3]);
- offset = ntohl(pulData[3 + i*3]);
-
- p = nss_ZAlloc(arena, len);
- if( (void *)NULL == p ) {
- return CKR_HOST_MEMORY;
- }
-
- nss_dbm_db_swap_copy(pTemplate[i].type, p, &pcData[offset], len);
- pTemplate[i].ulValueLen = len;
- pTemplate[i].pValue = p;
- }
-
- *ppTemplate = pTemplate;
- return CKR_OK;
-}
-
-
-NSS_IMPLEMENT nss_dbm_dbt_t *
-nss_dbm_db_create_object
-(
- NSSArena *arena,
- nss_dbm_db_t *db,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError,
- CK_ULONG *pdbrv
-)
-{
- NSSArena *tmparena = (NSSArena *)NULL;
- nss_dbm_dbt_t *rv = (nss_dbm_dbt_t *)NULL;
- DBT object;
-
- rv = nss_ZNEW(arena, nss_dbm_dbt_t);
- if( (nss_dbm_dbt_t *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (nss_dbm_dbt_t *)NULL;
- }
-
- rv->my_db = db;
- rv->dbt.size = sizeof(struct handle);
- rv->dbt.data = nss_ZAlloc(arena, rv->dbt.size);
- if( (void *)NULL == rv->dbt.data ) {
- *pError = CKR_HOST_MEMORY;
- return (nss_dbm_dbt_t *)NULL;
- }
-
- *pdbrv = nss_dbm_db_new_handle(db, &rv->dbt, pError);
- if( 0 != *pdbrv ) {
- return (nss_dbm_dbt_t *)NULL;
- }
-
- tmparena = NSSArena_Create();
- if( (NSSArena *)NULL == tmparena ) {
- *pError = CKR_HOST_MEMORY;
- return (nss_dbm_dbt_t *)NULL;
- }
-
- *pError = nss_dbm_db_wrap_object(tmparena, pTemplate, ulAttributeCount, &object);
- if( CKR_OK != *pError ) {
- return (nss_dbm_dbt_t *)NULL;
- }
-
- /* Locked region */
- {
- *pError = NSSCKFWMutex_Lock(db->crustylock);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-
- *pdbrv = db->db->put(db->db, &rv->dbt, &object, 0);
- if( 0 != *pdbrv ) {
- *pError = CKR_DEVICE_ERROR;
- }
-
- (void)db->db->sync(db->db, 0);
-
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
-
- loser:
- if( (NSSArena *)NULL != tmparena ) {
- (void)NSSArena_Destroy(tmparena);
- }
-
- return rv;
-}
-
-
-NSS_IMPLEMENT CK_RV
-nss_dbm_db_find_objects
-(
- nss_dbm_find_t *find,
- nss_dbm_db_t *db,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_ULONG *pdbrv
-)
-{
- CK_RV rv = CKR_OK;
-
- if( (nss_dbm_db_t *)NULL != db ) {
- DBT k, v;
-
- rv = NSSCKFWMutex_Lock(db->crustylock);
- if( CKR_OK != rv ) {
- return rv;
- }
-
- *pdbrv = db->db->seq(db->db, &k, &v, R_FIRST);
- while( 0 == *pdbrv ) {
- CK_ULONG i, j;
- NSSArena *tmparena = (NSSArena *)NULL;
- CK_ULONG ulac;
- CK_ATTRIBUTE_PTR pt;
-
- if( (k.size < 4) || (0 != memcmp(k.data, PREFIX_OBJECT, 4)) ) {
- goto nomatch;
- }
-
- tmparena = NSSArena_Create();
-
- rv = nss_dbm_db_unwrap_object(tmparena, &v, &pt, &ulac);
- if( CKR_OK != rv ) {
- goto loser;
- }
-
- for( i = 0; i < ulAttributeCount; i++ ) {
- for( j = 0; j < ulac; j++ ) {
- if( pTemplate[i].type == pt[j].type ) {
- if( pTemplate[i].ulValueLen != pt[j].ulValueLen ) {
- goto nomatch;
- }
- if( 0 != memcmp(pTemplate[i].pValue, pt[j].pValue, pt[j].ulValueLen) ) {
- goto nomatch;
- }
- break;
- }
- }
- if( j == ulac ) {
- goto nomatch;
- }
- }
-
- /* entire template matches */
- {
- struct nss_dbm_dbt_node *node;
-
- node = nss_ZNEW(find->arena, struct nss_dbm_dbt_node);
- if( (struct nss_dbm_dbt_node *)NULL == node ) {
- rv = CKR_HOST_MEMORY;
- goto loser;
- }
-
- node->dbt = nss_ZNEW(find->arena, nss_dbm_dbt_t);
- if( (nss_dbm_dbt_t *)NULL == node->dbt ) {
- rv = CKR_HOST_MEMORY;
- goto loser;
- }
-
- node->dbt->dbt.size = k.size;
- node->dbt->dbt.data = nss_ZAlloc(find->arena, k.size);
- if( (void *)NULL == node->dbt->dbt.data ) {
- rv = CKR_HOST_MEMORY;
- goto loser;
- }
-
- (void)memcpy(node->dbt->dbt.data, k.data, k.size);
-
- node->dbt->my_db = db;
-
- node->next = find->found;
- find->found = node;
- }
-
- nomatch:
- if( (NSSArena *)NULL != tmparena ) {
- (void)NSSArena_Destroy(tmparena);
- }
- *pdbrv = db->db->seq(db->db, &k, &v, R_NEXT);
- }
-
- if( *pdbrv < 0 ) {
- rv = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- rv = CKR_OK;
-
- loser:
- (void)NSSCKFWMutex_Unlock(db->crustylock);
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT CK_BBOOL
-nss_dbm_db_object_still_exists
-(
- nss_dbm_dbt_t *dbt
-)
-{
- CK_BBOOL rv;
- CK_RV ckrv;
- int dbrv;
- DBT object;
-
- ckrv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
- if( CKR_OK != ckrv ) {
- return CK_FALSE;
- }
-
- dbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
- if( 0 == dbrv ) {
- rv = CK_TRUE;
- } else {
- rv = CK_FALSE;
- }
-
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
-
- return rv;
-}
-
-NSS_IMPLEMENT CK_ULONG
-nss_dbm_db_get_object_attribute_count
-(
- nss_dbm_dbt_t *dbt,
- CK_RV *pError,
- CK_ULONG *pdbrv
-)
-{
- CK_ULONG rv = 0;
- DBT object;
- CK_ULONG *pulData;
-
- /* Locked region */
- {
- *pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
- if( CKR_OK != *pError ) {
- return rv;
- }
-
- *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
- if( 0 == *pdbrv ) {
- ;
- } else if( *pdbrv > 0 ) {
- *pError = CKR_OBJECT_HANDLE_INVALID;
- goto done;
- } else {
- *pError = CKR_DEVICE_ERROR;
- goto done;
- }
-
- pulData = (CK_ULONG *)object.data;
- rv = ntohl(pulData[0]);
-
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT CK_RV
-nss_dbm_db_get_object_attribute_types
-(
- nss_dbm_dbt_t *dbt,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount,
- CK_ULONG *pdbrv
-)
-{
- CK_RV rv = CKR_OK;
- DBT object;
- CK_ULONG *pulData;
- CK_ULONG n, i;
-
- /* Locked region */
- {
- rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
- if( CKR_OK != rv ) {
- return rv;
- }
-
- *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
- if( 0 == *pdbrv ) {
- ;
- } else if( *pdbrv > 0 ) {
- rv = CKR_OBJECT_HANDLE_INVALID;
- goto done;
- } else {
- rv = CKR_DEVICE_ERROR;
- goto done;
- }
-
- pulData = (CK_ULONG *)object.data;
- n = ntohl(pulData[0]);
-
- if( ulCount < n ) {
- rv = CKR_BUFFER_TOO_SMALL;
- goto done;
- }
-
- for( i = 0; i < n; i++ ) {
- typeArray[i] = ntohl(pulData[1 + i*3]);
- }
-
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT CK_ULONG
-nss_dbm_db_get_object_attribute_size
-(
- nss_dbm_dbt_t *dbt,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError,
- CK_ULONG *pdbrv
-)
-{
- CK_ULONG rv = 0;
- DBT object;
- CK_ULONG *pulData;
- CK_ULONG n, i;
-
- /* Locked region */
- {
- *pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
- if( CKR_OK != *pError ) {
- return rv;
- }
-
- *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
- if( 0 == *pdbrv ) {
- ;
- } else if( *pdbrv > 0 ) {
- *pError = CKR_OBJECT_HANDLE_INVALID;
- goto done;
- } else {
- *pError = CKR_DEVICE_ERROR;
- goto done;
- }
-
- pulData = (CK_ULONG *)object.data;
- n = ntohl(pulData[0]);
-
- for( i = 0; i < n; i++ ) {
- if( type == ntohl(pulData[1 + i*3]) ) {
- rv = ntohl(pulData[2 + i*3]);
- }
- }
-
- if( i == n ) {
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- goto done;
- }
-
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT NSSItem *
-nss_dbm_db_get_object_attribute
-(
- nss_dbm_dbt_t *dbt,
- NSSArena *arena,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError,
- CK_ULONG *pdbrv
-)
-{
- NSSItem *rv = (NSSItem *)NULL;
- DBT object;
- CK_ULONG i;
- NSSArena *tmp = NSSArena_Create();
- CK_ATTRIBUTE_PTR pTemplate;
- CK_ULONG ulAttributeCount;
-
- /* Locked region */
- {
- *pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-
- *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
- if( 0 == *pdbrv ) {
- ;
- } else if( *pdbrv > 0 ) {
- *pError = CKR_OBJECT_HANDLE_INVALID;
- goto done;
- } else {
- *pError = CKR_DEVICE_ERROR;
- goto done;
- }
-
- *pError = nss_dbm_db_unwrap_object(tmp, &object, &pTemplate, &ulAttributeCount);
- if( CKR_OK != *pError ) {
- goto done;
- }
-
- for( i = 0; i < ulAttributeCount; i++ ) {
- if( type == pTemplate[i].type ) {
- rv = nss_ZNEW(arena, NSSItem);
- if( (NSSItem *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- goto done;
- }
- rv->size = pTemplate[i].ulValueLen;
- rv->data = nss_ZAlloc(arena, rv->size);
- if( (void *)NULL == rv->data ) {
- *pError = CKR_HOST_MEMORY;
- goto done;
- }
- (void)memcpy(rv->data, pTemplate[i].pValue, rv->size);
- break;
- }
- }
- if( ulAttributeCount == i ) {
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- goto done;
- }
-
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
-
- loser:
- if( (NSSArena *)NULL != tmp ) {
- NSSArena_Destroy(tmp);
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT CK_RV
-nss_dbm_db_set_object_attribute
-(
- nss_dbm_dbt_t *dbt,
- CK_ATTRIBUTE_TYPE type,
- NSSItem *value,
- CK_ULONG *pdbrv
-)
-{
- CK_RV rv = CKR_OK;
- DBT object;
- CK_ULONG i;
- NSSArena *tmp = NSSArena_Create();
- CK_ATTRIBUTE_PTR pTemplate;
- CK_ULONG ulAttributeCount;
-
- /* Locked region */
- {
- rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
- if( CKR_OK != rv ) {
- goto loser;
- }
-
- *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
- if( 0 == *pdbrv ) {
- ;
- } else if( *pdbrv > 0 ) {
- rv = CKR_OBJECT_HANDLE_INVALID;
- goto done;
- } else {
- rv = CKR_DEVICE_ERROR;
- goto done;
- }
-
- rv = nss_dbm_db_unwrap_object(tmp, &object, &pTemplate, &ulAttributeCount);
- if( CKR_OK != rv ) {
- goto done;
- }
-
- for( i = 0; i < ulAttributeCount; i++ ) {
- if( type == pTemplate[i].type ) {
- /* Replacing an existing attribute */
- pTemplate[i].ulValueLen = value->size;
- pTemplate[i].pValue = value->data;
- break;
- }
- }
-
- if( i == ulAttributeCount ) {
- /* Adding a new attribute */
- CK_ATTRIBUTE_PTR npt = nss_ZNEWARRAY(tmp, CK_ATTRIBUTE, ulAttributeCount+1);
- if( (CK_ATTRIBUTE_PTR)NULL == npt ) {
- rv = CKR_DEVICE_ERROR;
- goto done;
- }
-
- for( i = 0; i < ulAttributeCount; i++ ) {
- npt[i] = pTemplate[i];
- }
-
- npt[ulAttributeCount].type = type;
- npt[ulAttributeCount].ulValueLen = value->size;
- npt[ulAttributeCount].pValue = value->data;
-
- pTemplate = npt;
- ulAttributeCount++;
- }
-
- rv = nss_dbm_db_wrap_object(tmp, pTemplate, ulAttributeCount, &object);
- if( CKR_OK != rv ) {
- goto done;
- }
-
- *pdbrv = dbt->my_db->db->put(dbt->my_db->db, &dbt->dbt, &object, 0);
- if( 0 != *pdbrv ) {
- rv = CKR_DEVICE_ERROR;
- goto done;
- }
-
- (void)dbt->my_db->db->sync(dbt->my_db->db, 0);
-
- done:
- (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
- }
-
- loser:
- if( (NSSArena *)NULL != tmp ) {
- NSSArena_Destroy(tmp);
- }
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/dbm/find.c b/security/nss/lib/ckfw/dbm/find.c
deleted file mode 100644
index f8757f091..000000000
--- a/security/nss/lib/ckfw/dbm/find.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckdbm.h"
-
-static void
-nss_dbm_mdFindObjects_Final
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_find_t *find = (nss_dbm_find_t *)mdFindObjects->etc;
-
- /* Locks might have system resources associated */
- (void)NSSCKFWMutex_Destroy(find->list_lock);
- (void)NSSArena_Destroy(find->arena);
-}
-
-
-static NSSCKMDObject *
-nss_dbm_mdFindObjects_Next
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
-{
- nss_dbm_find_t *find = (nss_dbm_find_t *)mdFindObjects->etc;
- struct nss_dbm_dbt_node *node;
- nss_dbm_object_t *object;
- NSSCKMDObject *rv;
-
- while(1) {
- /* Lock */
- {
- *pError = NSSCKFWMutex_Lock(find->list_lock);
- if( CKR_OK != *pError ) {
- return (NSSCKMDObject *)NULL;
- }
-
- node = find->found;
- if( (struct nss_dbm_dbt_node *)NULL != node ) {
- find->found = node->next;
- }
-
- *pError = NSSCKFWMutex_Unlock(find->list_lock);
- if( CKR_OK != *pError ) {
- /* screwed now */
- return (NSSCKMDObject *)NULL;
- }
- }
-
- if( (struct nss_dbm_dbt_node *)NULL == node ) {
- break;
- }
-
- if( nss_dbm_db_object_still_exists(node->dbt) ) {
- break;
- }
- }
-
- if( (struct nss_dbm_dbt_node *)NULL == node ) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
-
- object = nss_ZNEW(arena, nss_dbm_object_t);
- if( (nss_dbm_object_t *)NULL == object ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDObject *)NULL;
- }
-
- object->arena = arena;
- object->handle = nss_ZNEW(arena, nss_dbm_dbt_t);
- if( (nss_dbm_dbt_t *)NULL == object->handle ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDObject *)NULL;
- }
-
- object->handle->my_db = node->dbt->my_db;
- object->handle->dbt.size = node->dbt->dbt.size;
- object->handle->dbt.data = nss_ZAlloc(arena, node->dbt->dbt.size);
- if( (void *)NULL == object->handle->dbt.data ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDObject *)NULL;
- }
-
- (void)memcpy(object->handle->dbt.data, node->dbt->dbt.data, node->dbt->dbt.size);
-
- rv = nss_dbm_mdObject_factory(object, pError);
- if( (NSSCKMDObject *)NULL == rv ) {
- return (NSSCKMDObject *)NULL;
- }
-
- return rv;
-}
-
-NSS_IMPLEMENT NSSCKMDFindObjects *
-nss_dbm_mdFindObjects_factory
-(
- nss_dbm_find_t *find,
- CK_RV *pError
-)
-{
- NSSCKMDFindObjects *rv;
-
- rv = nss_ZNEW(find->arena, NSSCKMDFindObjects);
- if( (NSSCKMDFindObjects *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDFindObjects *)NULL;
- }
-
- rv->etc = (void *)find;
- rv->Final = nss_dbm_mdFindObjects_Final;
- rv->Next = nss_dbm_mdFindObjects_Next;
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/dbm/instance.c b/security/nss/lib/ckfw/dbm/instance.c
deleted file mode 100644
index f91301a04..000000000
--- a/security/nss/lib/ckfw/dbm/instance.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckdbm.h"
-
-static CK_RV
-nss_dbm_mdInstance_Initialize
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSUTF8 *configurationData
-)
-{
- CK_RV rv = CKR_OK;
- NSSArena *arena;
- nss_dbm_instance_t *instance;
-
- arena = NSSCKFWInstance_GetArena(fwInstance, &rv);
- if( ((NSSArena *)NULL == arena) && (CKR_OK != rv) ) {
- return rv;
- }
-
- instance = nss_ZNEW(arena, nss_dbm_instance_t);
- if( (nss_dbm_instance_t *)NULL == instance ) {
- return CKR_HOST_MEMORY;
- }
-
- instance->arena = arena;
-
- /*
- * This should parse the configuration data for information on
- * number and locations of databases, modes (e.g. readonly), etc.
- * But for now, we'll have one slot with a creatable read-write
- * database called "cert8.db."
- */
-
- instance->nSlots = 1;
- instance->filenames = nss_ZNEWARRAY(arena, char *, instance->nSlots);
- if( (char **)NULL == instance->filenames ) {
- return CKR_HOST_MEMORY;
- }
-
- instance->flags = nss_ZNEWARRAY(arena, int, instance->nSlots);
- if( (int *)NULL == instance->flags ) {
- return CKR_HOST_MEMORY;
- }
-
- instance->filenames[0] = "cert8.db";
- instance->flags[0] = O_RDWR|O_CREAT;
-
- mdInstance->etc = (void *)instance;
- return CKR_OK;
-}
-
-/* nss_dbm_mdInstance_Finalize is not required */
-
-static CK_ULONG
-nss_dbm_mdInstance_GetNSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- nss_dbm_instance_t *instance = (nss_dbm_instance_t *)mdInstance->etc;
- return instance->nSlots;
-}
-
-static CK_VERSION
-nss_dbm_mdInstance_GetCryptokiVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- static CK_VERSION rv = { 2, 1 };
- return rv;
-}
-
-static NSSUTF8 *
-nss_dbm_mdInstance_GetManufacturerID
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return "Mozilla Foundation";
-}
-
-static NSSUTF8 *
-nss_dbm_mdInstance_GetLibraryDescription
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return "Berkeley Database Module";
-}
-
-static CK_VERSION
-nss_dbm_mdInstance_GetLibraryVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- static CK_VERSION rv = { 1, 0 }; /* My own version number */
- return rv;
-}
-
-static CK_BBOOL
-nss_dbm_mdInstance_ModuleHandlesSessionObjects
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_TRUE;
-}
-
-static CK_RV
-nss_dbm_mdInstance_GetSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[]
-)
-{
- nss_dbm_instance_t *instance = (nss_dbm_instance_t *)mdInstance->etc;
- CK_ULONG i;
- CK_RV rv = CKR_OK;
-
- for( i = 0; i < instance->nSlots; i++ ) {
- slots[i] = nss_dbm_mdSlot_factory(instance, instance->filenames[i],
- instance->flags[i], &rv);
- if( (NSSCKMDSlot *)NULL == slots[i] ) {
- return rv;
- }
- }
-
- return rv;
-}
-
-/* nss_dbm_mdInstance_WaitForSlotEvent is not relevant */
-
-NSS_IMPLEMENT_DATA NSSCKMDInstance
-nss_dbm_mdInstance = {
- NULL, /* etc; filled in later */
- nss_dbm_mdInstance_Initialize,
- NULL, /* nss_dbm_mdInstance_Finalize */
- nss_dbm_mdInstance_GetNSlots,
- nss_dbm_mdInstance_GetCryptokiVersion,
- nss_dbm_mdInstance_GetManufacturerID,
- nss_dbm_mdInstance_GetLibraryDescription,
- nss_dbm_mdInstance_GetLibraryVersion,
- nss_dbm_mdInstance_ModuleHandlesSessionObjects,
- nss_dbm_mdInstance_GetSlots,
- NULL, /* nss_dbm_mdInstance_WaitForSlotEvent */
- NULL /* terminator */
-};
diff --git a/security/nss/lib/ckfw/dbm/manifest.mn b/security/nss/lib/ckfw/dbm/manifest.mn
deleted file mode 100644
index 0e3e5f810..000000000
--- a/security/nss/lib/ckfw/dbm/manifest.mn
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-CORE_DEPTH = ../../../..
-
-MODULE = nss
-
-CSRCS = \
- anchor.c \
- instance.c \
- slot.c \
- token.c \
- session.c \
- object.c \
- find.c \
- db.c \
- $(NULL)
-
-REQUIRES = dbm nspr
-
-LIBRARY_NAME = nssckdbm
-
-EXTRA_SHARED_LIBS = -L$(DIST)/lib -lnssckfw -lnssb -ldbm -lnspr4 -lplc4 -lplds4
diff --git a/security/nss/lib/ckfw/dbm/object.c b/security/nss/lib/ckfw/dbm/object.c
deleted file mode 100644
index 8e08fb309..000000000
--- a/security/nss/lib/ckfw/dbm/object.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckdbm.h"
-
-static void
-nss_dbm_mdObject_Finalize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- ;
-}
-
-static CK_RV
-nss_dbm_mdObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_object_t *object = (nss_dbm_object_t *)mdObject->etc;
- return nss_dbm_db_delete_object(object->handle);
-}
-
-static CK_ULONG
-nss_dbm_mdObject_GetAttributeCount
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- nss_dbm_object_t *object = (nss_dbm_object_t *)mdObject->etc;
- nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
- return nss_dbm_db_get_object_attribute_count(object->handle, pError,
- &session->deviceError);
-}
-
-static CK_RV
-nss_dbm_mdObject_GetAttributeTypes
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-)
-{
- nss_dbm_object_t *object = (nss_dbm_object_t *)mdObject->etc;
- nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
- return nss_dbm_db_get_object_attribute_types(object->handle, typeArray,
- ulCount, &session->deviceError);
-}
-
-static CK_ULONG
-nss_dbm_mdObject_GetAttributeSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- nss_dbm_object_t *object = (nss_dbm_object_t *)mdObject->etc;
- nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
- return nss_dbm_db_get_object_attribute_size(object->handle, attribute, pError,
- &session->deviceError);
-}
-
-static NSSItem *
-nss_dbm_mdObject_GetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- nss_dbm_object_t *object = (nss_dbm_object_t *)mdObject->etc;
- nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
- return nss_dbm_db_get_object_attribute(object->handle, object->arena, attribute,
- pError, &session->deviceError);
-}
-
-static CK_RV
-nss_dbm_mdObject_SetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value
-)
-{
- nss_dbm_object_t *object = (nss_dbm_object_t *)mdObject->etc;
- nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
- return nss_dbm_db_set_object_attribute(object->handle, attribute, value,
- &session->deviceError);
-}
-
-NSS_IMPLEMENT NSSCKMDObject *
-nss_dbm_mdObject_factory
-(
- nss_dbm_object_t *object,
- CK_RV *pError
-)
-{
- NSSCKMDObject *rv;
-
- rv = nss_ZNEW(object->arena, NSSCKMDObject);
- if( (NSSCKMDObject *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDObject *)NULL;
- }
-
- rv->etc = (void *)object;
- rv->Finalize = nss_dbm_mdObject_Finalize;
- rv->Destroy = nss_dbm_mdObject_Destroy;
- /* IsTokenObject can be deferred */
- rv->GetAttributeCount = nss_dbm_mdObject_GetAttributeCount;
- rv->GetAttributeTypes = nss_dbm_mdObject_GetAttributeTypes;
- rv->GetAttributeSize = nss_dbm_mdObject_GetAttributeSize;
- rv->GetAttribute = nss_dbm_mdObject_GetAttribute;
- rv->SetAttribute = nss_dbm_mdObject_SetAttribute;
- /* GetObjectSize can be deferred */
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/dbm/session.c b/security/nss/lib/ckfw/dbm/session.c
deleted file mode 100644
index b6814500e..000000000
--- a/security/nss/lib/ckfw/dbm/session.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckdbm.h"
-
-static void
-nss_dbm_mdSession_Close
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
-
- struct nss_dbm_dbt_node *w;
-
- /* Lock */
- {
- if( CKR_OK != NSSCKFWMutex_Lock(session->list_lock) ) {
- return;
- }
-
- w = session->session_objects;
- session->session_objects = (struct nss_dbm_dbt_node *)NULL; /* sanity */
-
- (void)NSSCKFWMutex_Unlock(session->list_lock);
- }
-
- for( ; (struct nss_dbm_dbt_node *)NULL != w; w = w->next ) {
- (void)nss_dbm_db_delete_object(w->dbt);
- }
-}
-
-static CK_ULONG
-nss_dbm_mdSession_GetDeviceError
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
- return session->deviceError;
-}
-
-/* Login isn't needed */
-/* Logout isn't needed */
-/* InitPIN is irrelevant */
-/* SetPIN is irrelevant */
-/* GetOperationStateLen is irrelevant */
-/* GetOperationState is irrelevant */
-/* SetOperationState is irrelevant */
-
-static NSSCKMDObject *
-nss_dbm_mdSession_CreateObject
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *handyArenaPointer,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
- CK_ULONG i;
- CK_BBOOL isToken = CK_FALSE; /* defaults to false */
- NSSCKMDObject *rv;
- struct nss_dbm_dbt_node *node = (struct nss_dbm_dbt_node *)NULL;
- nss_dbm_object_t *object;
- nss_dbm_db_t *which_db;
-
- /* This framework should really pass this to me */
- for( i = 0; i < ulAttributeCount; i++ ) {
- if( CKA_TOKEN == pTemplate[i].type ) {
- isToken = *(CK_BBOOL *)pTemplate[i].pValue;
- break;
- }
- }
-
- object = nss_ZNEW(handyArenaPointer, nss_dbm_object_t);
- if( (nss_dbm_object_t *)NULL == object ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDObject *)NULL;
- }
-
- object->arena = handyArenaPointer;
- which_db = isToken ? token->slot->token_db : token->session_db;
-
- /* Do this before the actual database call; it's easier to recover from */
- rv = nss_dbm_mdObject_factory(object, pError);
- if( (NSSCKMDObject *)NULL == rv ) {
- return (NSSCKMDObject *)NULL;
- }
-
- if( CK_FALSE == isToken ) {
- node = nss_ZNEW(session->arena, struct nss_dbm_dbt_node);
- if( (struct nss_dbm_dbt_node *)NULL == node ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDObject *)NULL;
- }
- }
-
- object->handle = nss_dbm_db_create_object(handyArenaPointer, which_db,
- pTemplate, ulAttributeCount,
- pError, &session->deviceError);
- if( (nss_dbm_dbt_t *)NULL == object->handle ) {
- return (NSSCKMDObject *)NULL;
- }
-
- if( CK_FALSE == isToken ) {
- node->dbt = object->handle;
- /* Lock */
- {
- *pError = NSSCKFWMutex_Lock(session->list_lock);
- if( CKR_OK != *pError ) {
- (void)nss_dbm_db_delete_object(object->handle);
- return (NSSCKMDObject *)NULL;
- }
-
- node->next = session->session_objects;
- session->session_objects = node;
-
- *pError = NSSCKFWMutex_Unlock(session->list_lock);
- }
- }
-
- return rv;
-}
-
-/* CopyObject isn't needed; the framework will use CreateObject */
-
-static NSSCKMDFindObjects *
-nss_dbm_mdSession_FindObjectsInit
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc;
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
- NSSArena *arena;
- nss_dbm_find_t *find;
- NSSCKMDFindObjects *rv;
-
- arena = NSSArena_Create();
- if( (NSSArena *)NULL == arena ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- find = nss_ZNEW(arena, nss_dbm_find_t);
- if( (nss_dbm_find_t *)NULL == find ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- find->arena = arena;
- find->list_lock = NSSCKFWInstance_CreateMutex(fwInstance, arena, pError);
- if( (NSSCKFWMutex *)NULL == find->list_lock ) {
- goto loser;
- }
-
- *pError = nss_dbm_db_find_objects(find, token->slot->token_db, pTemplate,
- ulAttributeCount, &session->deviceError);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-
- *pError = nss_dbm_db_find_objects(find, token->session_db, pTemplate,
- ulAttributeCount, &session->deviceError);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-
- rv = nss_dbm_mdFindObjects_factory(find, pError);
- if( (NSSCKMDFindObjects *)NULL == rv ) {
- goto loser;
- }
-
- return rv;
-
- loser:
- if( (NSSArena *)NULL != arena ) {
- (void)NSSArena_Destroy(arena);
- }
-
- return (NSSCKMDFindObjects *)NULL;
-}
-
-/* SeedRandom is irrelevant */
-/* GetRandom is irrelevant */
-
-NSS_IMPLEMENT NSSCKMDSession *
-nss_dbm_mdSession_factory
-(
- nss_dbm_token_t *token,
- NSSCKFWSession *fwSession,
- NSSCKFWInstance *fwInstance,
- CK_BBOOL rw,
- CK_RV *pError
-)
-{
- NSSArena *arena;
- nss_dbm_session_t *session;
- NSSCKMDSession *rv;
-
- arena = NSSCKFWSession_GetArena(fwSession, pError);
-
- session = nss_ZNEW(arena, nss_dbm_session_t);
- if( (nss_dbm_session_t *)NULL == session ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDSession *)NULL;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDSession);
- if( (NSSCKMDSession *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDSession *)NULL;
- }
-
- session->arena = arena;
- session->token = token;
- session->list_lock = NSSCKFWInstance_CreateMutex(fwInstance, arena, pError);
- if( (NSSCKFWMutex *)NULL == session->list_lock ) {
- return (NSSCKMDSession *)NULL;
- }
-
- rv->etc = (void *)session;
- rv->Close = nss_dbm_mdSession_Close;
- rv->GetDeviceError = nss_dbm_mdSession_GetDeviceError;
- /* Login isn't needed */
- /* Logout isn't needed */
- /* InitPIN is irrelevant */
- /* SetPIN is irrelevant */
- /* GetOperationStateLen is irrelevant */
- /* GetOperationState is irrelevant */
- /* SetOperationState is irrelevant */
- rv->CreateObject = nss_dbm_mdSession_CreateObject;
- /* CopyObject isn't needed; the framework will use CreateObject */
- rv->FindObjectsInit = nss_dbm_mdSession_FindObjectsInit;
- rv->null = NULL;
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/dbm/slot.c b/security/nss/lib/ckfw/dbm/slot.c
deleted file mode 100644
index 9df53d6f1..000000000
--- a/security/nss/lib/ckfw/dbm/slot.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckdbm.h"
-
-static CK_RV
-nss_dbm_mdSlot_Initialize
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_slot_t *slot = (nss_dbm_slot_t *)mdSlot->etc;
- nss_dbm_instance_t *instance = (nss_dbm_instance_t *)mdInstance->etc;
- CK_RV rv = CKR_OK;
-
- slot->token_db = nss_dbm_db_open(instance->arena, fwInstance, slot->filename,
- slot->flags, &rv);
- if( (nss_dbm_db_t *)NULL == slot->token_db ) {
- if( CKR_TOKEN_NOT_PRESENT == rv ) {
- /* This is not an error-- just means "the token isn't there" */
- rv = CKR_OK;
- }
- }
-
- return rv;
-}
-
-static void
-nss_dbm_mdSlot_Destroy
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_slot_t *slot = (nss_dbm_slot_t *)mdSlot->etc;
-
- if( (nss_dbm_db_t *)NULL != slot->token_db ) {
- nss_dbm_db_close(slot->token_db);
- slot->token_db = (nss_dbm_db_t *)NULL;
- }
-}
-
-static NSSUTF8 *
-nss_dbm_mdSlot_GetSlotDescription
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return "Database";
-}
-
-static NSSUTF8 *
-nss_dbm_mdSlot_GetManufacturerID
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return "Berkeley";
-}
-
-static CK_BBOOL
-nss_dbm_mdSlot_GetTokenPresent
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_slot_t *slot = (nss_dbm_slot_t *)mdSlot->etc;
-
- if( (nss_dbm_db_t *)NULL == slot->token_db ) {
- return CK_FALSE;
- } else {
- return CK_TRUE;
- }
-}
-
-static CK_BBOOL
-nss_dbm_mdSlot_GetRemovableDevice
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- /*
- * Well, this supports "tokens" (databases) that aren't there, so in
- * that sense they're removable. It'd be nice to handle databases
- * that suddenly disappear (NFS-mounted home directories and network
- * errors, for instance) but that's a harder problem. We'll say
- * we support removable devices, badly.
- */
-
- return CK_TRUE;
-}
-
-/* nss_dbm_mdSlot_GetHardwareSlot defaults to CK_FALSE */
-/*
- * nss_dbm_mdSlot_GetHardwareVersion
- * nss_dbm_mdSlot_GetFirmwareVersion
- *
- * These are kinda fuzzy concepts here. I suppose we could return the
- * Berkeley DB version for one of them, if we had an actual number we
- * were confident in. But mcom's "dbm" has been hacked enough that I
- * don't really know from what "real" version it stems..
- */
-
-static NSSCKMDToken *
-nss_dbm_mdSlot_GetToken
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- nss_dbm_slot_t *slot = (nss_dbm_slot_t *)mdSlot->etc;
- return nss_dbm_mdToken_factory(slot, pError);
-}
-
-NSS_IMPLEMENT NSSCKMDSlot *
-nss_dbm_mdSlot_factory
-(
- nss_dbm_instance_t *instance,
- char *filename,
- int flags,
- CK_RV *pError
-)
-{
- nss_dbm_slot_t *slot;
- NSSCKMDSlot *rv;
-
- slot = nss_ZNEW(instance->arena, nss_dbm_slot_t);
- if( (nss_dbm_slot_t *)NULL == slot ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDSlot *)NULL;
- }
-
- slot->instance = instance;
- slot->filename = filename;
- slot->flags = flags;
- slot->token_db = (nss_dbm_db_t *)NULL;
-
- rv = nss_ZNEW(instance->arena, NSSCKMDSlot);
- if( (NSSCKMDSlot *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDSlot *)NULL;
- }
-
- rv->etc = (void *)slot;
- rv->Initialize = nss_dbm_mdSlot_Initialize;
- rv->Destroy = nss_dbm_mdSlot_Destroy;
- rv->GetSlotDescription = nss_dbm_mdSlot_GetSlotDescription;
- rv->GetManufacturerID = nss_dbm_mdSlot_GetManufacturerID;
- rv->GetTokenPresent = nss_dbm_mdSlot_GetTokenPresent;
- rv->GetRemovableDevice = nss_dbm_mdSlot_GetRemovableDevice;
- /* GetHardwareSlot */
- /* GetHardwareVersion */
- /* GetFirmwareVersion */
- rv->GetToken = nss_dbm_mdSlot_GetToken;
- rv->null = (void *)NULL;
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/dbm/token.c b/security/nss/lib/ckfw/dbm/token.c
deleted file mode 100644
index 313162593..000000000
--- a/security/nss/lib/ckfw/dbm/token.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckdbm.h"
-
-static CK_RV
-nss_dbm_mdToken_Setup
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
- CK_RV rv = CKR_OK;
-
- token->arena = NSSCKFWToken_GetArena(fwToken, &rv);
- token->session_db = nss_dbm_db_open(token->arena, fwInstance, (char *)NULL,
- O_RDWR|O_CREAT, &rv);
- if( (nss_dbm_db_t *)NULL == token->session_db ) {
- return rv;
- }
-
- /* Add a label record if there isn't one? */
-
- return CKR_OK;
-}
-
-static void
-nss_dbm_mdToken_Invalidate
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
-
- if( (nss_dbm_db_t *)NULL != token->session_db ) {
- nss_dbm_db_close(token->session_db);
- token->session_db = (nss_dbm_db_t *)NULL;
- }
-}
-
-static CK_RV
-nss_dbm_mdToken_InitToken
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSItem *pin,
- NSSUTF8 *label
-)
-{
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
- nss_dbm_instance_t *instance = (nss_dbm_instance_t *)mdInstance->etc;
- CK_RV rv;
-
- /* Wipe the session object data */
-
- if( (nss_dbm_db_t *)NULL != token->session_db ) {
- nss_dbm_db_close(token->session_db);
- }
-
- token->session_db = nss_dbm_db_open(token->arena, fwInstance, (char *)NULL,
- O_RDWR|O_CREAT, &rv);
- if( (nss_dbm_db_t *)NULL == token->session_db ) {
- return rv;
- }
-
- /* Wipe the token object data */
-
- if( token->slot->flags & O_RDWR ) {
- if( (nss_dbm_db_t *)NULL != token->slot->token_db ) {
- nss_dbm_db_close(token->slot->token_db);
- }
-
- token->slot->token_db = nss_dbm_db_open(instance->arena, fwInstance,
- token->slot->filename,
- token->slot->flags | O_CREAT | O_TRUNC,
- &rv);
- if( (nss_dbm_db_t *)NULL == token->slot->token_db ) {
- return rv;
- }
-
- /* PIN is irrelevant */
-
- rv = nss_dbm_db_set_label(token->slot->token_db, label);
- if( CKR_OK != rv ) {
- return rv;
- }
- }
-
- return CKR_OK;
-}
-
-static NSSUTF8 *
-nss_dbm_mdToken_GetLabel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
-
- if( (NSSUTF8 *)NULL == token->label ) {
- token->label = nss_dbm_db_get_label(token->slot->token_db, token->arena, pError);
- }
-
- /* If no label has been set, return *something* */
- if( (NSSUTF8 *)NULL == token->label ) {
- return token->slot->filename;
- }
-
- return token->label;
-}
-
-static NSSUTF8 *
-nss_dbm_mdToken_GetManufacturerID
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return "mozilla.org NSS";
-}
-
-static NSSUTF8 *
-nss_dbm_mdToken_GetModel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return "dbm";
-}
-
-/* GetSerialNumber is irrelevant */
-/* GetHasRNG defaults to CK_FALSE */
-
-static CK_BBOOL
-nss_dbm_mdToken_GetIsWriteProtected
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
-
- if( token->slot->flags & O_RDWR ) {
- return CK_FALSE;
- } else {
- return CK_TRUE;
- }
-}
-
-/* GetLoginRequired defaults to CK_FALSE */
-/* GetUserPinInitialized defaults to CK_FALSE */
-/* GetRestoreKeyNotNeeded is irrelevant */
-/* GetHasClockOnToken defaults to CK_FALSE */
-/* GetHasProtectedAuthenticationPath defaults to CK_FALSE */
-/* GetSupportsDualCryptoOperations is irrelevant */
-
-static CK_ULONG
-nss_dbm_mdToken_effectively_infinite
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_EFFECTIVELY_INFINITE;
-}
-
-static CK_VERSION
-nss_dbm_mdToken_GetHardwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
- return nss_dbm_db_get_format_version(token->slot->token_db);
-}
-
-/* GetFirmwareVersion is irrelevant */
-/* GetUTCTime is irrelevant */
-
-static NSSCKMDSession *
-nss_dbm_mdToken_OpenSession
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_BBOOL rw,
- CK_RV *pError
-)
-{
- nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc;
- return nss_dbm_mdSession_factory(token, fwSession, fwInstance, rw, pError);
-}
-
-/* GetMechanismCount defaults to zero */
-/* GetMechanismTypes is irrelevant */
-/* GetMechanism is irrelevant */
-
-NSS_IMPLEMENT NSSCKMDToken *
-nss_dbm_mdToken_factory
-(
- nss_dbm_slot_t *slot,
- CK_RV *pError
-)
-{
- nss_dbm_token_t *token;
- NSSCKMDToken *rv;
-
- token = nss_ZNEW(slot->instance->arena, nss_dbm_token_t);
- if( (nss_dbm_token_t *)NULL == token ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDToken *)NULL;
- }
-
- rv = nss_ZNEW(slot->instance->arena, NSSCKMDToken);
- if( (NSSCKMDToken *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDToken *)NULL;
- }
-
- token->slot = slot;
-
- rv->etc = (void *)token;
- rv->Setup = nss_dbm_mdToken_Setup;
- rv->Invalidate = nss_dbm_mdToken_Invalidate;
- rv->InitToken = nss_dbm_mdToken_InitToken;
- rv->GetLabel = nss_dbm_mdToken_GetLabel;
- rv->GetManufacturerID = nss_dbm_mdToken_GetManufacturerID;
- rv->GetModel = nss_dbm_mdToken_GetModel;
- /* GetSerialNumber is irrelevant */
- /* GetHasRNG defaults to CK_FALSE */
- rv->GetIsWriteProtected = nss_dbm_mdToken_GetIsWriteProtected;
- /* GetLoginRequired defaults to CK_FALSE */
- /* GetUserPinInitialized defaults to CK_FALSE */
- /* GetRestoreKeyNotNeeded is irrelevant */
- /* GetHasClockOnToken defaults to CK_FALSE */
- /* GetHasProtectedAuthenticationPath defaults to CK_FALSE */
- /* GetSupportsDualCryptoOperations is irrelevant */
- rv->GetMaxSessionCount = nss_dbm_mdToken_effectively_infinite;
- rv->GetMaxRwSessionCount = nss_dbm_mdToken_effectively_infinite;
- /* GetMaxPinLen is irrelevant */
- /* GetMinPinLen is irrelevant */
- /* GetTotalPublicMemory defaults to CK_UNAVAILABLE_INFORMATION */
- /* GetFreePublicMemory defaults to CK_UNAVAILABLE_INFORMATION */
- /* GetTotalPrivateMemory defaults to CK_UNAVAILABLE_INFORMATION */
- /* GetFreePrivateMemory defaults to CK_UNAVAILABLE_INFORMATION */
- rv->GetHardwareVersion = nss_dbm_mdToken_GetHardwareVersion;
- /* GetFirmwareVersion is irrelevant */
- /* GetUTCTime is irrelevant */
- rv->OpenSession = nss_dbm_mdToken_OpenSession;
- rv->null = NULL;
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/find.c b/security/nss/lib/ckfw/find.c
deleted file mode 100644
index 0ba34d865..000000000
--- a/security/nss/lib/ckfw/find.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * find.c
- *
- * This file implements the nssCKFWFindObjects type and methods.
- */
-
-#ifndef CK_H
-#include "ck.h"
-#endif /* CK_H */
-
-/*
- * NSSCKFWFindObjects
- *
- * -- create/destroy --
- * nssCKFWFindObjects_Create
- * nssCKFWFindObjects_Destroy
- *
- * -- public accessors --
- * NSSCKFWFindObjects_GetMDFindObjects
- *
- * -- implement public accessors --
- * nssCKFWFindObjects_GetMDFindObjects
- *
- * -- private accessors --
- *
- * -- module fronts --
- * nssCKFWFindObjects_Next
- */
-
-struct NSSCKFWFindObjectsStr {
- NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */
- NSSCKMDFindObjects *mdfo1;
- NSSCKMDFindObjects *mdfo2;
- NSSCKFWSession *fwSession;
- NSSCKMDSession *mdSession;
- NSSCKFWToken *fwToken;
- NSSCKMDToken *mdToken;
- NSSCKFWInstance *fwInstance;
- NSSCKMDInstance *mdInstance;
-
- NSSCKMDFindObjects *mdFindObjects; /* varies */
-};
-
-#ifdef DEBUG
-/*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do these routines as no-ops.
- */
-
-static CK_RV
-findObjects_add_pointer
-(
- const NSSCKFWFindObjects *fwFindObjects
-)
-{
- return CKR_OK;
-}
-
-static CK_RV
-findObjects_remove_pointer
-(
- const NSSCKFWFindObjects *fwFindObjects
-)
-{
- return CKR_OK;
-}
-
-NSS_IMPLEMENT CK_RV
-nssCKFWFindObjects_verifyPointer
-(
- const NSSCKFWFindObjects *fwFindObjects
-)
-{
- return CKR_OK;
-}
-
-#endif /* DEBUG */
-
-/*
- * nssCKFWFindObjects_Create
- *
- */
-NSS_EXTERN NSSCKFWFindObjects *
-nssCKFWFindObjects_Create
-(
- NSSCKFWSession *fwSession,
- NSSCKFWToken *fwToken,
- NSSCKFWInstance *fwInstance,
- NSSCKMDFindObjects *mdFindObjects1,
- NSSCKMDFindObjects *mdFindObjects2,
- CK_RV *pError
-)
-{
- NSSCKFWFindObjects *fwFindObjects = NULL;
- NSSCKMDSession *mdSession;
- NSSCKMDToken *mdToken;
- NSSCKMDInstance *mdInstance;
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdToken = nssCKFWToken_GetMDToken(fwToken);
- mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
-
- fwFindObjects = nss_ZNEW(NULL, NSSCKFWFindObjects);
- if (!fwFindObjects) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fwFindObjects->mdfo1 = mdFindObjects1;
- fwFindObjects->mdfo2 = mdFindObjects2;
- fwFindObjects->fwSession = fwSession;
- fwFindObjects->mdSession = mdSession;
- fwFindObjects->fwToken = fwToken;
- fwFindObjects->mdToken = mdToken;
- fwFindObjects->fwInstance = fwInstance;
- fwFindObjects->mdInstance = mdInstance;
-
- fwFindObjects->mutex = nssCKFWInstance_CreateMutex(fwInstance, NULL, pError);
- if (!fwFindObjects->mutex) {
- goto loser;
- }
-
-#ifdef DEBUG
- *pError = findObjects_add_pointer(fwFindObjects);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-#endif /* DEBUG */
-
- return fwFindObjects;
-
- loser:
- if( fwFindObjects ) {
- if( NULL != mdFindObjects1 ) {
- if( NULL != mdFindObjects1->Final ) {
- fwFindObjects->mdFindObjects = mdFindObjects1;
- mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession,
- fwSession, mdToken, fwToken, mdInstance, fwInstance);
- }
- }
-
- if( NULL != mdFindObjects2 ) {
- if( NULL != mdFindObjects2->Final ) {
- fwFindObjects->mdFindObjects = mdFindObjects2;
- mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession,
- fwSession, mdToken, fwToken, mdInstance, fwInstance);
- }
- }
-
- nss_ZFreeIf(fwFindObjects);
- }
-
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
-
- return (NSSCKFWFindObjects *)NULL;
-}
-
-
-/*
- * nssCKFWFindObjects_Destroy
- *
- */
-NSS_EXTERN void
-nssCKFWFindObjects_Destroy
-(
- NSSCKFWFindObjects *fwFindObjects
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
- return;
- }
-#endif /* NSSDEBUG */
-
- (void)nssCKFWMutex_Destroy(fwFindObjects->mutex);
-
- if (fwFindObjects->mdfo1) {
- if (fwFindObjects->mdfo1->Final) {
- fwFindObjects->mdFindObjects = fwFindObjects->mdfo1;
- fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects,
- fwFindObjects->mdSession, fwFindObjects->fwSession,
- fwFindObjects->mdToken, fwFindObjects->fwToken,
- fwFindObjects->mdInstance, fwFindObjects->fwInstance);
- }
- }
-
- if (fwFindObjects->mdfo2) {
- if (fwFindObjects->mdfo2->Final) {
- fwFindObjects->mdFindObjects = fwFindObjects->mdfo2;
- fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects,
- fwFindObjects->mdSession, fwFindObjects->fwSession,
- fwFindObjects->mdToken, fwFindObjects->fwToken,
- fwFindObjects->mdInstance, fwFindObjects->fwInstance);
- }
- }
-
- nss_ZFreeIf(fwFindObjects);
-
-#ifdef DEBUG
- (void)findObjects_remove_pointer(fwFindObjects);
-#endif /* DEBUG */
-
- return;
-}
-
-/*
- * nssCKFWFindObjects_GetMDFindObjects
- *
- */
-NSS_EXTERN NSSCKMDFindObjects *
-nssCKFWFindObjects_GetMDFindObjects
-(
- NSSCKFWFindObjects *fwFindObjects
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
- return (NSSCKMDFindObjects *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwFindObjects->mdFindObjects;
-}
-
-/*
- * nssCKFWFindObjects_Next
- *
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWFindObjects_Next
-(
- NSSCKFWFindObjects *fwFindObjects,
- NSSArena *arenaOpt,
- CK_RV *pError
-)
-{
- NSSCKMDObject *mdObject;
- NSSCKFWObject *fwObject = (NSSCKFWObject *)NULL;
- NSSArena *objArena;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWObject *)NULL;
- }
-
- *pError = nssCKFWFindObjects_verifyPointer(fwFindObjects);
- if( CKR_OK != *pError ) {
- return (NSSCKFWObject *)NULL;
- }
-#endif /* NSSDEBUG */
-
- *pError = nssCKFWMutex_Lock(fwFindObjects->mutex);
- if( CKR_OK != *pError ) {
- return (NSSCKFWObject *)NULL;
- }
-
- if (fwFindObjects->mdfo1) {
- if (fwFindObjects->mdfo1->Next) {
- fwFindObjects->mdFindObjects = fwFindObjects->mdfo1;
- mdObject = fwFindObjects->mdfo1->Next(fwFindObjects->mdfo1,
- fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession,
- fwFindObjects->mdToken, fwFindObjects->fwToken,
- fwFindObjects->mdInstance, fwFindObjects->fwInstance,
- arenaOpt, pError);
- if (!mdObject) {
- if( CKR_OK != *pError ) {
- goto done;
- }
-
- /* All done. */
- fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects,
- fwFindObjects->mdSession, fwFindObjects->fwSession,
- fwFindObjects->mdToken, fwFindObjects->fwToken,
- fwFindObjects->mdInstance, fwFindObjects->fwInstance);
- fwFindObjects->mdfo1 = (NSSCKMDFindObjects *)NULL;
- } else {
- goto wrap;
- }
- }
- }
-
- if (fwFindObjects->mdfo2) {
- if (fwFindObjects->mdfo2->Next) {
- fwFindObjects->mdFindObjects = fwFindObjects->mdfo2;
- mdObject = fwFindObjects->mdfo2->Next(fwFindObjects->mdfo2,
- fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession,
- fwFindObjects->mdToken, fwFindObjects->fwToken,
- fwFindObjects->mdInstance, fwFindObjects->fwInstance,
- arenaOpt, pError);
- if (!mdObject) {
- if( CKR_OK != *pError ) {
- goto done;
- }
-
- /* All done. */
- fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects,
- fwFindObjects->mdSession, fwFindObjects->fwSession,
- fwFindObjects->mdToken, fwFindObjects->fwToken,
- fwFindObjects->mdInstance, fwFindObjects->fwInstance);
- fwFindObjects->mdfo2 = (NSSCKMDFindObjects *)NULL;
- } else {
- goto wrap;
- }
- }
- }
-
- /* No more objects */
- *pError = CKR_OK;
- goto done;
-
- wrap:
- /*
- * This seems is less than ideal-- we should determine if it's a token
- * object or a session object, and use the appropriate arena.
- * But that duplicates logic in nssCKFWObject_IsTokenObject.
- * Also we should lookup the real session the object was created on
- * if the object was a session object... however this code is actually
- * correct because nssCKFWObject_Create will return a cached version of
- * the object from it's hash. This is necessary because 1) we don't want
- * to create an arena style leak (where our arena grows with every search),
- * and 2) we want the same object to always have the same ID. This means
- * the only case the nssCKFWObject_Create() will need the objArena and the
- * Session is in the case of token objects (session objects should already
- * exist in the cache from their initial creation). So this code is correct,
- * but it depends on nssCKFWObject_Create caching all objects.
- */
- objArena = nssCKFWToken_GetArena(fwFindObjects->fwToken, pError);
- if (!objArena) {
- if( CKR_OK == *pError ) {
- *pError = CKR_HOST_MEMORY;
- }
- goto done;
- }
-
- fwObject = nssCKFWObject_Create(objArena, mdObject,
- NULL, fwFindObjects->fwToken,
- fwFindObjects->fwInstance, pError);
- if (!fwObject) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- }
-
- done:
- (void)nssCKFWMutex_Unlock(fwFindObjects->mutex);
- return fwObject;
-}
-
-/*
- * NSSCKFWFindObjects_GetMDFindObjects
- *
- */
-
-NSS_EXTERN NSSCKMDFindObjects *
-NSSCKFWFindObjects_GetMDFindObjects
-(
- NSSCKFWFindObjects *fwFindObjects
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
- return (NSSCKMDFindObjects *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWFindObjects_GetMDFindObjects(fwFindObjects);
-}
diff --git a/security/nss/lib/ckfw/hash.c b/security/nss/lib/ckfw/hash.c
deleted file mode 100644
index a7bf8ff27..000000000
--- a/security/nss/lib/ckfw/hash.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * hash.c
- *
- * This is merely a couple wrappers around NSPR's PLHashTable, using
- * the identity hash and arena-aware allocators. The reason I did
- * this is that hash tables are used in a few places throughout the
- * NSS Cryptoki Framework in a fairly stereotyped way, and this allows
- * me to pull the commonalities into one place. Should we ever want
- * to change the implementation, it's all right here.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * nssCKFWHash
- *
- * nssCKFWHash_Create
- * nssCKFWHash_Destroy
- * nssCKFWHash_Add
- * nssCKFWHash_Remove
- * nssCKFWHash_Count
- * nssCKFWHash_Exists
- * nssCKFWHash_Lookup
- * nssCKFWHash_Iterate
- */
-
-struct nssCKFWHashStr {
- NSSCKFWMutex *mutex;
-
- /*
- * The invariant that mutex protects is:
- * The count accurately reflects the hashtable state.
- */
-
- PLHashTable *plHashTable;
- CK_ULONG count;
-};
-
-static PLHashNumber
-nss_ckfw_identity_hash
-(
- const void *key
-)
-{
- PRUint32 i = (PRUint32)key;
- PR_ASSERT(sizeof(PLHashNumber) == sizeof(PRUint32));
- return (PLHashNumber)i;
-}
-
-/*
- * nssCKFWHash_Create
- *
- */
-NSS_IMPLEMENT nssCKFWHash *
-nssCKFWHash_Create
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
-{
- nssCKFWHash *rv;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (nssCKFWHash *)NULL;
- }
-
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- *pError = CKR_ARGUMENTS_BAD;
- return (nssCKFWHash *)NULL;
- }
-#endif /* NSSDEBUG */
-
- rv = nss_ZNEW(arena, nssCKFWHash);
- if (!rv) {
- *pError = CKR_HOST_MEMORY;
- return (nssCKFWHash *)NULL;
- }
-
- rv->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
- if (!rv->mutex) {
- if( CKR_OK == *pError ) {
- (void)nss_ZFreeIf(rv);
- *pError = CKR_GENERAL_ERROR;
- }
- return (nssCKFWHash *)NULL;
- }
-
- rv->plHashTable = PL_NewHashTable(0, nss_ckfw_identity_hash,
- PL_CompareValues, PL_CompareValues, &nssArenaHashAllocOps, arena);
- if (!rv->plHashTable) {
- (void)nssCKFWMutex_Destroy(rv->mutex);
- (void)nss_ZFreeIf(rv);
- *pError = CKR_HOST_MEMORY;
- return (nssCKFWHash *)NULL;
- }
-
- rv->count = 0;
-
- return rv;
-}
-
-/*
- * nssCKFWHash_Destroy
- *
- */
-NSS_IMPLEMENT void
-nssCKFWHash_Destroy
-(
- nssCKFWHash *hash
-)
-{
- (void)nssCKFWMutex_Destroy(hash->mutex);
- PL_HashTableDestroy(hash->plHashTable);
- (void)nss_ZFreeIf(hash);
-}
-
-/*
- * nssCKFWHash_Add
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWHash_Add
-(
- nssCKFWHash *hash,
- const void *key,
- const void *value
-)
-{
- CK_RV error = CKR_OK;
- PLHashEntry *he;
-
- error = nssCKFWMutex_Lock(hash->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
- if (!he) {
- error = CKR_HOST_MEMORY;
- } else {
- hash->count++;
- }
-
- (void)nssCKFWMutex_Unlock(hash->mutex);
-
- return error;
-}
-
-/*
- * nssCKFWHash_Remove
- *
- */
-NSS_IMPLEMENT void
-nssCKFWHash_Remove
-(
- nssCKFWHash *hash,
- const void *it
-)
-{
- PRBool found;
-
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return;
- }
-
- found = PL_HashTableRemove(hash->plHashTable, it);
- if( found ) {
- hash->count--;
- }
-
- (void)nssCKFWMutex_Unlock(hash->mutex);
- return;
-}
-
-/*
- * nssCKFWHash_Count
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWHash_Count
-(
- nssCKFWHash *hash
-)
-{
- CK_ULONG count;
-
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return (CK_ULONG)0;
- }
-
- count = hash->count;
-
- (void)nssCKFWMutex_Unlock(hash->mutex);
-
- return count;
-}
-
-/*
- * nssCKFWHash_Exists
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWHash_Exists
-(
- nssCKFWHash *hash,
- const void *it
-)
-{
- void *value;
-
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return CK_FALSE;
- }
-
- value = PL_HashTableLookup(hash->plHashTable, it);
-
- (void)nssCKFWMutex_Unlock(hash->mutex);
-
- if (!value) {
- return CK_FALSE;
- } else {
- return CK_TRUE;
- }
-}
-
-/*
- * nssCKFWHash_Lookup
- *
- */
-NSS_IMPLEMENT void *
-nssCKFWHash_Lookup
-(
- nssCKFWHash *hash,
- const void *it
-)
-{
- void *rv;
-
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return (void *)NULL;
- }
-
- rv = PL_HashTableLookup(hash->plHashTable, it);
-
- (void)nssCKFWMutex_Unlock(hash->mutex);
-
- return rv;
-}
-
-struct arg_str {
- nssCKFWHashIterator fcn;
- void *closure;
-};
-
-static PRIntn
-nss_ckfwhash_enumerator
-(
- PLHashEntry *he,
- PRIntn index,
- void *arg
-)
-{
- struct arg_str *as = (struct arg_str *)arg;
- as->fcn(he->key, he->value, as->closure);
- return HT_ENUMERATE_NEXT;
-}
-
-/*
- * nssCKFWHash_Iterate
- *
- * NOTE that the iteration function will be called with the hashtable locked.
- */
-NSS_IMPLEMENT void
-nssCKFWHash_Iterate
-(
- nssCKFWHash *hash,
- nssCKFWHashIterator fcn,
- void *closure
-)
-{
- struct arg_str as;
- as.fcn = fcn;
- as.closure = closure;
-
- if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
- return;
- }
-
- PL_HashTableEnumerateEntries(hash->plHashTable, nss_ckfwhash_enumerator, &as);
-
- (void)nssCKFWMutex_Unlock(hash->mutex);
-
- return;
-}
diff --git a/security/nss/lib/ckfw/instance.c b/security/nss/lib/ckfw/instance.c
deleted file mode 100644
index b40f0c5fa..000000000
--- a/security/nss/lib/ckfw/instance.c
+++ /dev/null
@@ -1,1344 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * instance.c
- *
- * This file implements the NSSCKFWInstance type and methods.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * NSSCKFWInstance
- *
- * -- create/destroy --
- * nssCKFWInstance_Create
- * nssCKFWInstance_Destroy
- *
- * -- public accessors --
- * NSSCKFWInstance_GetMDInstance
- * NSSCKFWInstance_GetArena
- * NSSCKFWInstance_MayCreatePthreads
- * NSSCKFWInstance_CreateMutex
- * NSSCKFWInstance_GetConfigurationData
- * NSSCKFWInstance_GetInitArgs
- *
- * -- implement public accessors --
- * nssCKFWInstance_GetMDInstance
- * nssCKFWInstance_GetArena
- * nssCKFWInstance_MayCreatePthreads
- * nssCKFWInstance_CreateMutex
- * nssCKFWInstance_GetConfigurationData
- * nssCKFWInstance_GetInitArgs
- *
- * -- private accessors --
- * nssCKFWInstance_CreateSessionHandle
- * nssCKFWInstance_ResolveSessionHandle
- * nssCKFWInstance_DestroySessionHandle
- * nssCKFWInstance_FindSessionHandle
- * nssCKFWInstance_CreateObjectHandle
- * nssCKFWInstance_ResolveObjectHandle
- * nssCKFWInstance_DestroyObjectHandle
- *
- * -- module fronts --
- * nssCKFWInstance_GetNSlots
- * nssCKFWInstance_GetCryptokiVersion
- * nssCKFWInstance_GetManufacturerID
- * nssCKFWInstance_GetFlags
- * nssCKFWInstance_GetLibraryDescription
- * nssCKFWInstance_GetLibraryVersion
- * nssCKFWInstance_GetModuleHandlesSessionObjects
- * nssCKFWInstance_GetSlots
- * nssCKFWInstance_WaitForSlotEvent
- *
- * -- debugging versions only --
- * nssCKFWInstance_verifyPointer
- */
-
-struct NSSCKFWInstanceStr {
- NSSCKFWMutex *mutex;
- NSSArena *arena;
- NSSCKMDInstance *mdInstance;
- CK_C_INITIALIZE_ARGS_PTR pInitArgs;
- CK_C_INITIALIZE_ARGS initArgs;
- CryptokiLockingState LockingState;
- CK_BBOOL mayCreatePthreads;
- NSSUTF8 *configurationData;
- CK_ULONG nSlots;
- NSSCKFWSlot **fwSlotList;
- NSSCKMDSlot **mdSlotList;
- CK_BBOOL moduleHandlesSessionObjects;
-
- /*
- * Everything above is set at creation time, and then not modified.
- * The invariants the mutex protects are:
- *
- * 1) Each of the cached descriptions (versions, etc.) are in an
- * internally consistant state.
- *
- * 2) The session handle hashes and count are consistant
- *
- * 3) The object handle hashes and count are consistant.
- *
- * I could use multiple locks, but let's wait to see if that's
- * really necessary.
- *
- * Note that the calls accessing the cached descriptions will
- * call the NSSCKMDInstance methods with the mutex locked. Those
- * methods may then call the public NSSCKFWInstance routines.
- * Those public routines only access the constant data above, so
- * there's no problem. But be careful if you add to this object;
- * mutexes are in general not reentrant, so don't create deadlock
- * situations.
- */
-
- CK_VERSION cryptokiVersion;
- NSSUTF8 *manufacturerID;
- NSSUTF8 *libraryDescription;
- CK_VERSION libraryVersion;
-
- CK_ULONG lastSessionHandle;
- nssCKFWHash *sessionHandleHash;
-
- CK_ULONG lastObjectHandle;
- nssCKFWHash *objectHandleHash;
-};
-
-#ifdef DEBUG
-/*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do this routines as no-ops.
- */
-
-static CK_RV
-instance_add_pointer
-(
- const NSSCKFWInstance *fwInstance
-)
-{
- return CKR_OK;
-}
-
-static CK_RV
-instance_remove_pointer
-(
- const NSSCKFWInstance *fwInstance
-)
-{
- return CKR_OK;
-}
-
-NSS_IMPLEMENT CK_RV
-nssCKFWInstance_verifyPointer
-(
- const NSSCKFWInstance *fwInstance
-)
-{
- return CKR_OK;
-}
-
-#endif /* DEBUG */
-
-/*
- * nssCKFWInstance_Create
- *
- */
-NSS_IMPLEMENT NSSCKFWInstance *
-nssCKFWInstance_Create
-(
- CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState LockingState,
- NSSCKMDInstance *mdInstance,
- CK_RV *pError
-)
-{
- NSSCKFWInstance *fwInstance;
- NSSArena *arena = (NSSArena *)NULL;
- CK_ULONG i;
- CK_BBOOL called_Initialize = CK_FALSE;
-
-#ifdef NSSDEBUG
- if( (CK_RV)NULL == pError ) {
- return (NSSCKFWInstance *)NULL;
- }
-
- if (!mdInstance) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWInstance *)NULL;
- }
-#endif /* NSSDEBUG */
-
- arena = NSSArena_Create();
- if (!arena) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWInstance *)NULL;
- }
-
- fwInstance = nss_ZNEW(arena, NSSCKFWInstance);
- if (!fwInstance) {
- goto nomem;
- }
-
- fwInstance->arena = arena;
- fwInstance->mdInstance = mdInstance;
-
- fwInstance->LockingState = LockingState;
- if( (CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs ) {
- fwInstance->initArgs = *pInitArgs;
- fwInstance->pInitArgs = &fwInstance->initArgs;
- if( pInitArgs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS ) {
- fwInstance->mayCreatePthreads = CK_FALSE;
- } else {
- fwInstance->mayCreatePthreads = CK_TRUE;
- }
- fwInstance->configurationData = (NSSUTF8 *)(pInitArgs->pReserved);
- } else {
- fwInstance->mayCreatePthreads = CK_TRUE;
- }
-
- fwInstance->mutex = nssCKFWMutex_Create(pInitArgs, LockingState, arena,
- pError);
- if (!fwInstance->mutex) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- goto loser;
- }
-
- if (mdInstance->Initialize) {
- *pError = mdInstance->Initialize(mdInstance, fwInstance, fwInstance->configurationData);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-
- called_Initialize = CK_TRUE;
- }
-
- if (mdInstance->ModuleHandlesSessionObjects) {
- fwInstance->moduleHandlesSessionObjects =
- mdInstance->ModuleHandlesSessionObjects(mdInstance, fwInstance);
- } else {
- fwInstance->moduleHandlesSessionObjects = CK_FALSE;
- }
-
- if (!mdInstance->GetNSlots) {
- /* That routine is required */
- *pError = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- fwInstance->nSlots = mdInstance->GetNSlots(mdInstance, fwInstance, pError);
- if( (CK_ULONG)0 == fwInstance->nSlots ) {
- if( CKR_OK == *pError ) {
- /* Zero is not a legitimate answer */
- *pError = CKR_GENERAL_ERROR;
- }
- goto loser;
- }
-
- fwInstance->fwSlotList = nss_ZNEWARRAY(arena, NSSCKFWSlot *, fwInstance->nSlots);
- if( (NSSCKFWSlot **)NULL == fwInstance->fwSlotList ) {
- goto nomem;
- }
-
- fwInstance->mdSlotList = nss_ZNEWARRAY(arena, NSSCKMDSlot *, fwInstance->nSlots);
- if( (NSSCKMDSlot **)NULL == fwInstance->mdSlotList ) {
- goto nomem;
- }
-
- fwInstance->sessionHandleHash = nssCKFWHash_Create(fwInstance,
- fwInstance->arena, pError);
- if (!fwInstance->sessionHandleHash) {
- goto loser;
- }
-
- fwInstance->objectHandleHash = nssCKFWHash_Create(fwInstance,
- fwInstance->arena, pError);
- if (!fwInstance->objectHandleHash) {
- goto loser;
- }
-
- if (!mdInstance->GetSlots) {
- /* That routine is required */
- *pError = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- *pError = mdInstance->GetSlots(mdInstance, fwInstance, fwInstance->mdSlotList);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-
- for( i = 0; i < fwInstance->nSlots; i++ ) {
- NSSCKMDSlot *mdSlot = fwInstance->mdSlotList[i];
-
- if (!mdSlot) {
- *pError = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- fwInstance->fwSlotList[i] = nssCKFWSlot_Create(fwInstance, mdSlot, i, pError);
- if( CKR_OK != *pError ) {
- CK_ULONG j;
-
- for( j = 0; j < i; j++ ) {
- (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[j]);
- }
-
- for( j = i; j < fwInstance->nSlots; j++ ) {
- NSSCKMDSlot *mds = fwInstance->mdSlotList[j];
- if (mds->Destroy) {
- mds->Destroy(mds, (NSSCKFWSlot *)NULL, mdInstance, fwInstance);
- }
- }
-
- goto loser;
- }
- }
-
-#ifdef DEBUG
- *pError = instance_add_pointer(fwInstance);
- if( CKR_OK != *pError ) {
- for( i = 0; i < fwInstance->nSlots; i++ ) {
- (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
- }
-
- goto loser;
- }
-#endif /* DEBUG */
-
- *pError = CKR_OK;
- return fwInstance;
-
- nomem:
- *pError = CKR_HOST_MEMORY;
- /*FALLTHROUGH*/
- loser:
-
- if( CK_TRUE == called_Initialize ) {
- if (mdInstance->Finalize) {
- mdInstance->Finalize(mdInstance, fwInstance);
- }
- }
-
- if (fwInstance && fwInstance->mutex) {
- nssCKFWMutex_Destroy(fwInstance->mutex);
- }
-
- if (arena) {
- (void)NSSArena_Destroy(arena);
- }
- return (NSSCKFWInstance *)NULL;
-}
-
-/*
- * nssCKFWInstance_Destroy
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWInstance_Destroy
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
-#endif /* NSSDEBUG */
- CK_ULONG i;
-
-#ifdef NSSDEBUG
- error = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- nssCKFWMutex_Destroy(fwInstance->mutex);
-
- for( i = 0; i < fwInstance->nSlots; i++ ) {
- (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
- }
-
- if (fwInstance->mdInstance->Finalize) {
- fwInstance->mdInstance->Finalize(fwInstance->mdInstance, fwInstance);
- }
-
- if (fwInstance->sessionHandleHash) {
- nssCKFWHash_Destroy(fwInstance->sessionHandleHash);
- }
-
- if (fwInstance->objectHandleHash) {
- nssCKFWHash_Destroy(fwInstance->objectHandleHash);
- }
-
-#ifdef DEBUG
- (void)instance_remove_pointer(fwInstance);
-#endif /* DEBUG */
-
- (void)NSSArena_Destroy(fwInstance->arena);
- return CKR_OK;
-}
-
-/*
- * nssCKFWInstance_GetMDInstance
- *
- */
-NSS_IMPLEMENT NSSCKMDInstance *
-nssCKFWInstance_GetMDInstance
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSCKMDInstance *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwInstance->mdInstance;
-}
-
-/*
- * nssCKFWInstance_GetArena
- *
- */
-NSS_IMPLEMENT NSSArena *
-nssCKFWInstance_GetArena
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSArena *)NULL;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (NSSArena *)NULL;
- }
-#endif /* NSSDEBUG */
-
- *pError = CKR_OK;
- return fwInstance->arena;
-}
-
-/*
- * nssCKFWInstance_MayCreatePthreads
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWInstance_MayCreatePthreads
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- return fwInstance->mayCreatePthreads;
-}
-
-/*
- * nssCKFWInstance_CreateMutex
- *
- */
-NSS_IMPLEMENT NSSCKFWMutex *
-nssCKFWInstance_CreateMutex
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
-{
- NSSCKFWMutex *mutex;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWMutex *)NULL;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (NSSCKFWMutex *)NULL;
- }
-#endif /* NSSDEBUG */
-
- mutex = nssCKFWMutex_Create(fwInstance->pInitArgs, fwInstance->LockingState,
- arena, pError);
- if (!mutex) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
-
- return (NSSCKFWMutex *)NULL;
- }
-
- return mutex;
-}
-
-/*
- * nssCKFWInstance_GetConfigurationData
- *
- */
-NSS_IMPLEMENT NSSUTF8 *
-nssCKFWInstance_GetConfigurationData
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSUTF8 *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwInstance->configurationData;
-}
-
-/*
- * nssCKFWInstance_GetInitArgs
- *
- */
-CK_C_INITIALIZE_ARGS_PTR
-nssCKFWInstance_GetInitArgs
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_C_INITIALIZE_ARGS_PTR)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwInstance->pInitArgs;
-}
-
-/*
- * nssCKFWInstance_CreateSessionHandle
- *
- */
-NSS_IMPLEMENT CK_SESSION_HANDLE
-nssCKFWInstance_CreateSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
-{
- CK_SESSION_HANDLE hSession;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (CK_SESSION_HANDLE)0;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (CK_SESSION_HANDLE)0;
- }
-#endif /* NSSDEBUG */
-
- *pError = nssCKFWMutex_Lock(fwInstance->mutex);
- if( CKR_OK != *pError ) {
- return (CK_SESSION_HANDLE)0;
- }
-
- hSession = ++(fwInstance->lastSessionHandle);
-
- /* Alan would say I should unlock for this call. */
-
- *pError = nssCKFWSession_SetHandle(fwSession, hSession);
- if( CKR_OK != *pError ) {
- goto done;
- }
-
- *pError = nssCKFWHash_Add(fwInstance->sessionHandleHash,
- (const void *)hSession, (const void *)fwSession);
- if( CKR_OK != *pError ) {
- hSession = (CK_SESSION_HANDLE)0;
- goto done;
- }
-
- done:
- nssCKFWMutex_Unlock(fwInstance->mutex);
- return hSession;
-}
-
-/*
- * nssCKFWInstance_ResolveSessionHandle
- *
- */
-NSS_IMPLEMENT NSSCKFWSession *
-nssCKFWInstance_ResolveSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
-{
- NSSCKFWSession *fwSession;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSCKFWSession *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
- return (NSSCKFWSession *)NULL;
- }
-
- fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
- fwInstance->sessionHandleHash, (const void *)hSession);
-
- /* Assert(hSession == nssCKFWSession_GetHandle(fwSession)) */
-
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
-
- return fwSession;
-}
-
-/*
- * nssCKFWInstance_DestroySessionHandle
- *
- */
-NSS_IMPLEMENT void
-nssCKFWInstance_DestroySessionHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
-{
- NSSCKFWSession *fwSession;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
- return;
- }
-
- fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
- fwInstance->sessionHandleHash, (const void *)hSession);
- if (fwSession) {
- nssCKFWHash_Remove(fwInstance->sessionHandleHash, (const void *)hSession);
- nssCKFWSession_SetHandle(fwSession, (CK_SESSION_HANDLE)0);
- }
-
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
-
- return;
-}
-
-/*
- * nssCKFWInstance_FindSessionHandle
- *
- */
-NSS_IMPLEMENT CK_SESSION_HANDLE
-nssCKFWInstance_FindSessionHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_SESSION_HANDLE)0;
- }
-
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return (CK_SESSION_HANDLE)0;
- }
-#endif /* NSSDEBUG */
-
- return nssCKFWSession_GetHandle(fwSession);
- /* look it up and assert? */
-}
-
-/*
- * nssCKFWInstance_CreateObjectHandle
- *
- */
-NSS_IMPLEMENT CK_OBJECT_HANDLE
-nssCKFWInstance_CreateObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
-{
- CK_OBJECT_HANDLE hObject;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (CK_OBJECT_HANDLE)0;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (CK_OBJECT_HANDLE)0;
- }
-#endif /* NSSDEBUG */
-
- *pError = nssCKFWMutex_Lock(fwInstance->mutex);
- if( CKR_OK != *pError ) {
- return (CK_OBJECT_HANDLE)0;
- }
-
- hObject = ++(fwInstance->lastObjectHandle);
-
- *pError = nssCKFWObject_SetHandle(fwObject, hObject);
- if( CKR_OK != *pError ) {
- hObject = (CK_OBJECT_HANDLE)0;
- goto done;
- }
-
- *pError = nssCKFWHash_Add(fwInstance->objectHandleHash,
- (const void *)hObject, (const void *)fwObject);
- if( CKR_OK != *pError ) {
- hObject = (CK_OBJECT_HANDLE)0;
- goto done;
- }
-
- done:
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return hObject;
-}
-
-/*
- * nssCKFWInstance_ResolveObjectHandle
- *
- */
-NSS_IMPLEMENT NSSCKFWObject *
-nssCKFWInstance_ResolveObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject
-)
-{
- NSSCKFWObject *fwObject;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSCKFWObject *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
- return (NSSCKFWObject *)NULL;
- }
-
- fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
- fwInstance->objectHandleHash, (const void *)hObject);
-
- /* Assert(hObject == nssCKFWObject_GetHandle(fwObject)) */
-
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return fwObject;
-}
-
-/*
- * nssCKFWInstance_ReassignObjectHandle
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWInstance_ReassignObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject,
- NSSCKFWObject *fwObject
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWObject *oldObject;
-
-#ifdef NSSDEBUG
- error = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwInstance->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- oldObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
- fwInstance->objectHandleHash, (const void *)hObject);
- if(oldObject) {
- /* Assert(hObject == nssCKFWObject_GetHandle(oldObject) */
- (void)nssCKFWObject_SetHandle(oldObject, (CK_SESSION_HANDLE)0);
- nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject);
- }
-
- error = nssCKFWObject_SetHandle(fwObject, hObject);
- if( CKR_OK != error ) {
- goto done;
- }
- error = nssCKFWHash_Add(fwInstance->objectHandleHash,
- (const void *)hObject, (const void *)fwObject);
-
- done:
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return error;
-}
-
-/*
- * nssCKFWInstance_DestroyObjectHandle
- *
- */
-NSS_IMPLEMENT void
-nssCKFWInstance_DestroyObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- CK_OBJECT_HANDLE hObject
-)
-{
- NSSCKFWObject *fwObject;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
- return;
- }
-
- fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
- fwInstance->objectHandleHash, (const void *)hObject);
- if (fwObject) {
- /* Assert(hObject = nssCKFWObject_GetHandle(fwObject)) */
- nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject);
- (void)nssCKFWObject_SetHandle(fwObject, (CK_SESSION_HANDLE)0);
- }
-
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return;
-}
-
-/*
- * nssCKFWInstance_FindObjectHandle
- *
- */
-NSS_IMPLEMENT CK_OBJECT_HANDLE
-nssCKFWInstance_FindObjectHandle
-(
- NSSCKFWInstance *fwInstance,
- NSSCKFWObject *fwObject
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_OBJECT_HANDLE)0;
- }
-
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return (CK_OBJECT_HANDLE)0;
- }
-#endif /* NSSDEBUG */
-
- return nssCKFWObject_GetHandle(fwObject);
-}
-
-/*
- * nssCKFWInstance_GetNSlots
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWInstance_GetNSlots
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
-#ifdef NSSDEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- *pError = CKR_OK;
- return fwInstance->nSlots;
-}
-
-/*
- * nssCKFWInstance_GetCryptokiVersion
- *
- */
-NSS_IMPLEMENT CK_VERSION
-nssCKFWInstance_GetCryptokiVersion
-(
- NSSCKFWInstance *fwInstance
-)
-{
- CK_VERSION rv;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-
- if( (0 != fwInstance->cryptokiVersion.major) ||
- (0 != fwInstance->cryptokiVersion.minor) ) {
- rv = fwInstance->cryptokiVersion;
- goto done;
- }
-
- if (fwInstance->mdInstance->GetCryptokiVersion) {
- fwInstance->cryptokiVersion = fwInstance->mdInstance->GetCryptokiVersion(
- fwInstance->mdInstance, fwInstance);
- } else {
- fwInstance->cryptokiVersion.major = 2;
- fwInstance->cryptokiVersion.minor = 1;
- }
-
- rv = fwInstance->cryptokiVersion;
-
- done:
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return rv;
-}
-
-/*
- * nssCKFWInstance_GetManufacturerID
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWInstance_GetManufacturerID
-(
- NSSCKFWInstance *fwInstance,
- CK_CHAR manufacturerID[32]
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == manufacturerID ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- error = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwInstance->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwInstance->manufacturerID) {
- if (fwInstance->mdInstance->GetManufacturerID) {
- fwInstance->manufacturerID = fwInstance->mdInstance->GetManufacturerID(
- fwInstance->mdInstance, fwInstance, &error);
- if ((!fwInstance->manufacturerID) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwInstance->manufacturerID = (NSSUTF8 *) "";
- }
- }
-
- (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->manufacturerID, (char *)manufacturerID, 32, ' ');
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return error;
-}
-
-/*
- * nssCKFWInstance_GetFlags
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWInstance_GetFlags
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- /* No "instance flags" are yet defined by Cryptoki. */
- return (CK_ULONG)0;
-}
-
-/*
- * nssCKFWInstance_GetLibraryDescription
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWInstance_GetLibraryDescription
-(
- NSSCKFWInstance *fwInstance,
- CK_CHAR libraryDescription[32]
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == libraryDescription ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- error = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwInstance->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwInstance->libraryDescription) {
- if (fwInstance->mdInstance->GetLibraryDescription) {
- fwInstance->libraryDescription = fwInstance->mdInstance->GetLibraryDescription(
- fwInstance->mdInstance, fwInstance, &error);
- if ((!fwInstance->libraryDescription) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwInstance->libraryDescription = (NSSUTF8 *) "";
- }
- }
-
- (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->libraryDescription, (char *)libraryDescription, 32, ' ');
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return error;
-}
-
-/*
- * nssCKFWInstance_GetLibraryVersion
- *
- */
-NSS_IMPLEMENT CK_VERSION
-nssCKFWInstance_GetLibraryVersion
-(
- NSSCKFWInstance *fwInstance
-)
-{
- CK_VERSION rv;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-
- if( (0 != fwInstance->libraryVersion.major) ||
- (0 != fwInstance->libraryVersion.minor) ) {
- rv = fwInstance->libraryVersion;
- goto done;
- }
-
- if (fwInstance->mdInstance->GetLibraryVersion) {
- fwInstance->libraryVersion = fwInstance->mdInstance->GetLibraryVersion(
- fwInstance->mdInstance, fwInstance);
- } else {
- fwInstance->libraryVersion.major = 0;
- fwInstance->libraryVersion.minor = 3;
- }
-
- rv = fwInstance->libraryVersion;
- done:
- (void)nssCKFWMutex_Unlock(fwInstance->mutex);
- return rv;
-}
-
-/*
- * nssCKFWInstance_GetModuleHandlesSessionObjects
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWInstance_GetModuleHandlesSessionObjects
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- return fwInstance->moduleHandlesSessionObjects;
-}
-
-/*
- * nssCKFWInstance_GetSlots
- *
- */
-NSS_IMPLEMENT NSSCKFWSlot **
-nssCKFWInstance_GetSlots
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWSlot **)NULL;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (NSSCKFWSlot **)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwInstance->fwSlotList;
-}
-
-/*
- * nssCKFWInstance_WaitForSlotEvent
- *
- */
-NSS_IMPLEMENT NSSCKFWSlot *
-nssCKFWInstance_WaitForSlotEvent
-(
- NSSCKFWInstance *fwInstance,
- CK_BBOOL block,
- CK_RV *pError
-)
-{
- NSSCKFWSlot *fwSlot = (NSSCKFWSlot *)NULL;
- NSSCKMDSlot *mdSlot;
- CK_ULONG i, n;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWSlot *)NULL;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (NSSCKFWSlot *)NULL;
- }
-
- switch( block ) {
- case CK_TRUE:
- case CK_FALSE:
- break;
- default:
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWSlot *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if (!fwInstance->mdInstance->WaitForSlotEvent) {
- *pError = CKR_NO_EVENT;
- return (NSSCKFWSlot *)NULL;
- }
-
- mdSlot = fwInstance->mdInstance->WaitForSlotEvent(
- fwInstance->mdInstance,
- fwInstance,
- block,
- pError
- );
-
- if (!mdSlot) {
- return (NSSCKFWSlot *)NULL;
- }
-
- n = nssCKFWInstance_GetNSlots(fwInstance, pError);
- if( ((CK_ULONG)0 == n) && (CKR_OK != *pError) ) {
- return (NSSCKFWSlot *)NULL;
- }
-
- for( i = 0; i < n; i++ ) {
- if( fwInstance->mdSlotList[i] == mdSlot ) {
- fwSlot = fwInstance->fwSlotList[i];
- break;
- }
- }
-
- if (!fwSlot) {
- /* Internal error */
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWSlot *)NULL;
- }
-
- return fwSlot;
-}
-
-/*
- * NSSCKFWInstance_GetMDInstance
- *
- */
-NSS_IMPLEMENT NSSCKMDInstance *
-NSSCKFWInstance_GetMDInstance
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSCKMDInstance *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWInstance_GetMDInstance(fwInstance);
-}
-
-/*
- * NSSCKFWInstance_GetArena
- *
- */
-NSS_IMPLEMENT NSSArena *
-NSSCKFWInstance_GetArena
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
-#ifdef DEBUG
- if (!pError) {
- return (NSSArena *)NULL;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (NSSArena *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWInstance_GetArena(fwInstance, pError);
-}
-
-/*
- * NSSCKFWInstance_MayCreatePthreads
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-NSSCKFWInstance_MayCreatePthreads
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return CK_FALSE;
- }
-#endif /* DEBUG */
-
- return nssCKFWInstance_MayCreatePthreads(fwInstance);
-}
-
-/*
- * NSSCKFWInstance_CreateMutex
- *
- */
-NSS_IMPLEMENT NSSCKFWMutex *
-NSSCKFWInstance_CreateMutex
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
-{
-#ifdef DEBUG
- if (!pError) {
- return (NSSCKFWMutex *)NULL;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (NSSCKFWMutex *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
-}
-
-/*
- * NSSCKFWInstance_GetConfigurationData
- *
- */
-NSS_IMPLEMENT NSSUTF8 *
-NSSCKFWInstance_GetConfigurationData
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (NSSUTF8 *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWInstance_GetConfigurationData(fwInstance);
-}
-
-/*
- * NSSCKFWInstance_GetInitArgs
- *
- */
-NSS_IMPLEMENT CK_C_INITIALIZE_ARGS_PTR
-NSSCKFWInstance_GetInitArgs
-(
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
- return (CK_C_INITIALIZE_ARGS_PTR)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWInstance_GetInitArgs(fwInstance);
-}
-
diff --git a/security/nss/lib/ckfw/manifest.mn b/security/nss/lib/ckfw/manifest.mn
deleted file mode 100644
index dcb79cb84..000000000
--- a/security/nss/lib/ckfw/manifest.mn
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-CORE_DEPTH = ../../..
-
-DIRS = builtins
-
-PRIVATE_EXPORTS = \
- ck.h \
- ckfw.h \
- ckfwm.h \
- ckfwtm.h \
- ckmd.h \
- ckt.h \
- $(NULL)
-
-EXPORTS = \
- nssck.api \
- nssckepv.h \
- nssckft.h \
- nssckfw.h \
- nssckfwc.h \
- nssckfwt.h \
- nssckg.h \
- nssckmdt.h \
- nssckt.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- crypto.c \
- find.c \
- hash.c \
- instance.c \
- mutex.c \
- object.c \
- session.c \
- sessobj.c \
- slot.c \
- token.c \
- wrap.c \
- mechanism.c \
- $(NULL)
-
-REQUIRES = nspr
-
-LIBRARY_NAME = nssckfw
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/ckfw/mechanism.c b/security/nss/lib/ckfw/mechanism.c
deleted file mode 100644
index f8fab1253..000000000
--- a/security/nss/lib/ckfw/mechanism.c
+++ /dev/null
@@ -1,1186 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * mechanism.c
- *
- * This file implements the NSSCKFWMechanism type and methods.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * NSSCKFWMechanism
- *
- * -- create/destroy --
- * nssCKFWMechanism_Create
- * nssCKFWMechanism_Destroy
- *
- * -- implement public accessors --
- * nssCKFWMechanism_GetMDMechanism
- * nssCKFWMechanism_GetParameter
- *
- * -- private accessors --
- *
- * -- module fronts --
- * nssCKFWMechanism_GetMinKeySize
- * nssCKFWMechanism_GetMaxKeySize
- * nssCKFWMechanism_GetInHardware
- * nssCKFWMechanism_GetCanEncrypt
- * nssCKFWMechanism_GetCanDecrypt
- * nssCKFWMechanism_GetCanDigest
- * nssCKFWMechanism_GetCanSign
- * nssCKFWMechanism_GetCanSignRecover
- * nssCKFWMechanism_GetCanVerify
- * nssCKFWMechanism_GetCanGenerate
- * nssCKFWMechanism_GetCanGenerateKeyPair
- * nssCKFWMechanism_GetCanUnwrap
- * nssCKFWMechanism_GetCanWrap
- * nssCKFWMechanism_GetCanDerive
- * nssCKFWMechanism_EncryptInit
- * nssCKFWMechanism_DecryptInit
- * nssCKFWMechanism_DigestInit
- * nssCKFWMechanism_SignInit
- * nssCKFWMechanism_VerifyInit
- * nssCKFWMechanism_SignRecoverInit
- * nssCKFWMechanism_VerifyRecoverInit
- * nssCKFWMechanism_GenerateKey
- * nssCKFWMechanism_GenerateKeyPair
- * nssCKFWMechanism_GetWrapKeyLength
- * nssCKFWMechanism_WrapKey
- * nssCKFWMechanism_UnwrapKey
- * nssCKFWMechanism_DeriveKey
- */
-
-
-struct NSSCKFWMechanismStr {
- NSSCKMDMechanism *mdMechanism;
- NSSCKMDToken *mdToken;
- NSSCKFWToken *fwToken;
- NSSCKMDInstance *mdInstance;
- NSSCKFWInstance *fwInstance;
-};
-
-/*
- * nssCKFWMechanism_Create
- *
- */
-NSS_IMPLEMENT NSSCKFWMechanism *
-nssCKFWMechanism_Create
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- NSSCKFWMechanism *fwMechanism;
-
-
- fwMechanism = nss_ZNEW(NULL, NSSCKFWMechanism);
- if (!fwMechanism) {
- return (NSSCKFWMechanism *)NULL;
- }
- fwMechanism->mdMechanism = mdMechanism;
- fwMechanism->mdToken = mdToken;
- fwMechanism->fwToken = fwToken;
- fwMechanism->mdInstance = mdInstance;
- fwMechanism->fwInstance = fwInstance;
- return fwMechanism;
-}
-
-/*
- * nssCKFWMechanism_Destroy
- *
- */
-NSS_IMPLEMENT void
-nssCKFWMechanism_Destroy
-(
- NSSCKFWMechanism *fwMechanism
-)
-{
- /* destroy any fw resources held by nssCKFWMechanism (currently none) */
-
- if (!fwMechanism->mdMechanism->Destroy) {
- /* destroys it's parent as well */
- fwMechanism->mdMechanism->Destroy(
- fwMechanism->mdMechanism,
- fwMechanism,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance);
- }
- /* if the Destroy function wasn't supplied, then the mechanism is 'static',
- * and there is nothing to destroy */
- return;
-}
-
-/*
- * nssCKFWMechanism_GetMDMechanism
- *
- */
-NSS_IMPLEMENT NSSCKMDMechanism *
-nssCKFWMechanism_GetMDMechanism
-(
- NSSCKFWMechanism *fwMechanism
-)
-{
- return fwMechanism->mdMechanism;
-}
-
-/*
- * nssCKFWMechanism_GetMinKeySize
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWMechanism_GetMinKeySize
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->GetMinKeySize) {
- return 0;
- }
-
- return fwMechanism->mdMechanism->GetMinKeySize(fwMechanism->mdMechanism,
- fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
-}
-
-/*
- * nssCKFWMechanism_GetMaxKeySize
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWMechanism_GetMaxKeySize
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->GetMaxKeySize) {
- return 0;
- }
-
- return fwMechanism->mdMechanism->GetMaxKeySize(fwMechanism->mdMechanism,
- fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
-}
-
-/*
- * nssCKFWMechanism_GetInHardware
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWMechanism_GetInHardware
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->GetInHardware) {
- return CK_FALSE;
- }
-
- return fwMechanism->mdMechanism->GetInHardware(fwMechanism->mdMechanism,
- fwMechanism, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance, pError);
-}
-
-
-/*
- * the following are determined automatically by which of the cryptographic
- * functions are defined for this mechanism.
- */
-/*
- * nssCKFWMechanism_GetCanEncrypt
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanEncrypt
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->EncryptInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanDecrypt
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDecrypt
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->DecryptInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanDigest
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDigest
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->DigestInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanSign
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanSign
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->SignInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanSignRecover
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanSignRecover
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->SignRecoverInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanVerify
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanVerify
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->VerifyInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanVerifyRecover
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanVerifyRecover
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->VerifyRecoverInit) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanGenerate
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanGenerate
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->GenerateKey) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanGenerateKeyPair
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanGenerateKeyPair
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->GenerateKeyPair) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanUnwrap
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanUnwrap
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->UnwrapKey) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanWrap
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanWrap
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->WrapKey) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * nssCKFWMechanism_GetCanDerive
- *
- */
-NSS_EXTERN CK_BBOOL
-nssCKFWMechanism_GetCanDerive
-(
- NSSCKFWMechanism *fwMechanism,
- CK_RV *pError
-)
-{
- if (!fwMechanism->mdMechanism->DeriveKey) {
- return CK_FALSE;
- }
- return CK_TRUE;
-}
-
-/*
- * These are the actual crypto operations
- */
-
-/*
- * nssCKFWMechanism_EncryptInit
- * Start an encryption session.
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_EncryptInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSCKMDCryptoOperation *mdOperation;
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdObject;
- CK_RV error = CKR_OK;
-
-
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- NSSCKFWCryptoOperationState_EncryptDecrypt);
- if (fwOperation) {
- return CKR_OPERATION_ACTIVE;
- }
-
- if (!fwMechanism->mdMechanism->EncryptInit) {
- return CKR_FUNCTION_FAILED;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdObject = nssCKFWObject_GetMDObject(fwObject);
- mdOperation = fwMechanism->mdMechanism->EncryptInit(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdObject,
- fwObject,
- &error
- );
- if (!mdOperation) {
- goto loser;
- }
-
- fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
- mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance,
- NSSCKFWCryptoOperationType_Encrypt, &error);
- if (fwOperation) {
- nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
- NSSCKFWCryptoOperationState_EncryptDecrypt);
- }
-
-loser:
- return error;
-}
-
-/*
- * nssCKFWMechanism_DecryptInit
- * Start an encryption session.
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_DecryptInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSCKMDCryptoOperation *mdOperation;
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdObject;
- CK_RV error = CKR_OK;
-
-
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- NSSCKFWCryptoOperationState_EncryptDecrypt);
- if (fwOperation) {
- return CKR_OPERATION_ACTIVE;
- }
-
- if (!fwMechanism->mdMechanism->DecryptInit) {
- return CKR_FUNCTION_FAILED;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdObject = nssCKFWObject_GetMDObject(fwObject);
- mdOperation = fwMechanism->mdMechanism->DecryptInit(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdObject,
- fwObject,
- &error
- );
- if (!mdOperation) {
- goto loser;
- }
-
- fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
- mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance,
- NSSCKFWCryptoOperationType_Decrypt, &error);
- if (fwOperation) {
- nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
- NSSCKFWCryptoOperationState_EncryptDecrypt);
- }
-
-loser:
- return error;
-}
-
-/*
- * nssCKFWMechanism_DigestInit
- * Start an encryption session.
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_DigestInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSCKMDCryptoOperation *mdOperation;
- NSSCKMDSession *mdSession;
- CK_RV error = CKR_OK;
-
-
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- NSSCKFWCryptoOperationState_Digest);
- if (fwOperation) {
- return CKR_OPERATION_ACTIVE;
- }
-
- if (!fwMechanism->mdMechanism->DigestInit) {
- return CKR_FUNCTION_FAILED;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdOperation = fwMechanism->mdMechanism->DigestInit(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- &error
- );
- if (!mdOperation) {
- goto loser;
- }
-
- fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
- mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance,
- NSSCKFWCryptoOperationType_Digest, &error);
- if (fwOperation) {
- nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
- NSSCKFWCryptoOperationState_Digest);
- }
-
-loser:
- return error;
-}
-
-/*
- * nssCKFWMechanism_SignInit
- * Start an encryption session.
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_SignInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSCKMDCryptoOperation *mdOperation;
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdObject;
- CK_RV error = CKR_OK;
-
-
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- NSSCKFWCryptoOperationState_SignVerify);
- if (fwOperation) {
- return CKR_OPERATION_ACTIVE;
- }
-
- if (!fwMechanism->mdMechanism->SignInit) {
- return CKR_FUNCTION_FAILED;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdObject = nssCKFWObject_GetMDObject(fwObject);
- mdOperation = fwMechanism->mdMechanism->SignInit(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdObject,
- fwObject,
- &error
- );
- if (!mdOperation) {
- goto loser;
- }
-
- fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
- mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance,
- NSSCKFWCryptoOperationType_Sign, &error);
- if (fwOperation) {
- nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
- NSSCKFWCryptoOperationState_SignVerify);
- }
-
-loser:
- return error;
-}
-
-/*
- * nssCKFWMechanism_VerifyInit
- * Start an encryption session.
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_VerifyInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSCKMDCryptoOperation *mdOperation;
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdObject;
- CK_RV error = CKR_OK;
-
-
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- NSSCKFWCryptoOperationState_SignVerify);
- if (fwOperation) {
- return CKR_OPERATION_ACTIVE;
- }
-
- if (!fwMechanism->mdMechanism->VerifyInit) {
- return CKR_FUNCTION_FAILED;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdObject = nssCKFWObject_GetMDObject(fwObject);
- mdOperation = fwMechanism->mdMechanism->VerifyInit(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdObject,
- fwObject,
- &error
- );
- if (!mdOperation) {
- goto loser;
- }
-
- fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
- mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance,
- NSSCKFWCryptoOperationType_Verify, &error);
- if (fwOperation) {
- nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
- NSSCKFWCryptoOperationState_SignVerify);
- }
-
-loser:
- return error;
-}
-
-/*
- * nssCKFWMechanism_SignRecoverInit
- * Start an encryption session.
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_SignRecoverInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSCKMDCryptoOperation *mdOperation;
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdObject;
- CK_RV error = CKR_OK;
-
-
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- NSSCKFWCryptoOperationState_SignVerify);
- if (fwOperation) {
- return CKR_OPERATION_ACTIVE;
- }
-
- if (!fwMechanism->mdMechanism->SignRecoverInit) {
- return CKR_FUNCTION_FAILED;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdObject = nssCKFWObject_GetMDObject(fwObject);
- mdOperation = fwMechanism->mdMechanism->SignRecoverInit(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdObject,
- fwObject,
- &error
- );
- if (!mdOperation) {
- goto loser;
- }
-
- fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
- mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance,
- NSSCKFWCryptoOperationType_SignRecover, &error);
- if (fwOperation) {
- nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
- NSSCKFWCryptoOperationState_SignVerify);
- }
-
-loser:
- return error;
-}
-
-/*
- * nssCKFWMechanism_VerifyRecoverInit
- * Start an encryption session.
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_VerifyRecoverInit
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSCKMDCryptoOperation *mdOperation;
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdObject;
- CK_RV error = CKR_OK;
-
-
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- NSSCKFWCryptoOperationState_SignVerify);
- if (fwOperation) {
- return CKR_OPERATION_ACTIVE;
- }
-
- if (!fwMechanism->mdMechanism->VerifyRecoverInit) {
- return CKR_FUNCTION_FAILED;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdObject = nssCKFWObject_GetMDObject(fwObject);
- mdOperation = fwMechanism->mdMechanism->VerifyRecoverInit(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdObject,
- fwObject,
- &error
- );
- if (!mdOperation) {
- goto loser;
- }
-
- fwOperation = nssCKFWCryptoOperation_Create(mdOperation,
- mdSession, fwSession, fwMechanism->mdToken, fwMechanism->fwToken,
- fwMechanism->mdInstance, fwMechanism->fwInstance,
- NSSCKFWCryptoOperationType_VerifyRecover, &error);
- if (fwOperation) {
- nssCKFWSession_SetCurrentCryptoOperation(fwSession, fwOperation,
- NSSCKFWCryptoOperationState_SignVerify);
- }
-
-loser:
- return error;
-}
-
-/*
- * nssCKFWMechanism_GenerateKey
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWMechanism_GenerateKey
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdObject;
- NSSCKFWObject *fwObject = NULL;
- NSSArena *arena;
-
- if (!fwMechanism->mdMechanism->GenerateKey) {
- *pError = CKR_FUNCTION_FAILED;
- return (NSSCKFWObject *)NULL;
- }
-
- arena = nssCKFWToken_GetArena(fwMechanism->fwToken, pError);
- if (!arena) {
- if (CKR_OK == *pError) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdObject = fwMechanism->mdMechanism->GenerateKey(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- pTemplate,
- ulAttributeCount,
- pError);
-
- if (!mdObject) {
- return (NSSCKFWObject *)NULL;
- }
-
- fwObject = nssCKFWObject_Create(arena, mdObject,
- fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
-
- return fwObject;
-}
-
-/*
- * nssCKFWMechanism_GenerateKeyPair
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_GenerateKeyPair
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- NSSCKFWObject **fwPublicKeyObject,
- NSSCKFWObject **fwPrivateKeyObject
-)
-{
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdPublicKeyObject;
- NSSCKMDObject *mdPrivateKeyObject;
- NSSArena *arena;
- CK_RV error = CKR_OK;
-
- if (!fwMechanism->mdMechanism->GenerateKeyPair) {
- return CKR_FUNCTION_FAILED;
- }
-
- arena = nssCKFWToken_GetArena(fwMechanism->fwToken, &error);
- if (!arena) {
- if (CKR_OK == error) {
- error = CKR_GENERAL_ERROR;
- }
- return error;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- error = fwMechanism->mdMechanism->GenerateKeyPair(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- pPublicKeyTemplate,
- ulPublicKeyAttributeCount,
- pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount,
- &mdPublicKeyObject,
- &mdPrivateKeyObject);
-
- if (CKR_OK != error) {
- return error;
- }
-
- *fwPublicKeyObject = nssCKFWObject_Create(arena, mdPublicKeyObject,
- fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, &error);
- if (!*fwPublicKeyObject) {
- return error;
- }
- *fwPrivateKeyObject = nssCKFWObject_Create(arena, mdPrivateKeyObject,
- fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, &error);
-
- return error;
-}
-
-/*
- * nssCKFWMechanism_GetWrapKeyLength
- */
-NSS_EXTERN CK_ULONG
-nssCKFWMechanism_GetWrapKeyLength
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwWrappingKeyObject,
- NSSCKFWObject *fwKeyObject,
- CK_RV *pError
-)
-{
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdWrappingKeyObject;
- NSSCKMDObject *mdKeyObject;
-
- if (!fwMechanism->mdMechanism->WrapKey) {
- *pError = CKR_FUNCTION_FAILED;
- return (CK_ULONG) 0;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdWrappingKeyObject = nssCKFWObject_GetMDObject(fwWrappingKeyObject);
- mdKeyObject = nssCKFWObject_GetMDObject(fwKeyObject);
- return fwMechanism->mdMechanism->GetWrapKeyLength(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdWrappingKeyObject,
- fwWrappingKeyObject,
- mdKeyObject,
- fwKeyObject,
- pError);
-}
-
-/*
- * nssCKFWMechanism_WrapKey
- */
-NSS_EXTERN CK_RV
-nssCKFWMechanism_WrapKey
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwWrappingKeyObject,
- NSSCKFWObject *fwKeyObject,
- NSSItem *wrappedKey
-)
-{
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdWrappingKeyObject;
- NSSCKMDObject *mdKeyObject;
-
- if (!fwMechanism->mdMechanism->WrapKey) {
- return CKR_FUNCTION_FAILED;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdWrappingKeyObject = nssCKFWObject_GetMDObject(fwWrappingKeyObject);
- mdKeyObject = nssCKFWObject_GetMDObject(fwKeyObject);
- return fwMechanism->mdMechanism->WrapKey(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdWrappingKeyObject,
- fwWrappingKeyObject,
- mdKeyObject,
- fwKeyObject,
- wrappedKey);
-}
-
-/*
- * nssCKFWMechanism_UnwrapKey
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWMechanism_UnwrapKey
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwWrappingKeyObject,
- NSSItem *wrappedKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdObject;
- NSSCKMDObject *mdWrappingKeyObject;
- NSSCKFWObject *fwObject = NULL;
- NSSArena *arena;
-
- if (!fwMechanism->mdMechanism->UnwrapKey) {
- /* we could simulate UnwrapKey using Decrypt and Create object, but
- * 1) it's not clear that would work well, and 2) the low level token
- * may want to restrict unwrap key for a reason, so just fail it it
- * can't be done */
- *pError = CKR_FUNCTION_FAILED;
- return (NSSCKFWObject *)NULL;
- }
-
- arena = nssCKFWToken_GetArena(fwMechanism->fwToken, pError);
- if (!arena) {
- if (CKR_OK == *pError) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdWrappingKeyObject = nssCKFWObject_GetMDObject(fwWrappingKeyObject);
- mdObject = fwMechanism->mdMechanism->UnwrapKey(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdWrappingKeyObject,
- fwWrappingKeyObject,
- wrappedKey,
- pTemplate,
- ulAttributeCount,
- pError);
-
- if (!mdObject) {
- return (NSSCKFWObject *)NULL;
- }
-
- fwObject = nssCKFWObject_Create(arena, mdObject,
- fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
-
- return fwObject;
-}
-
-/*
- * nssCKFWMechanism_DeriveKey
- */
-NSS_EXTERN NSSCKFWObject *
-nssCKFWMechanism_DeriveKey
-(
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwBaseKeyObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- NSSCKMDSession *mdSession;
- NSSCKMDObject *mdObject;
- NSSCKMDObject *mdBaseKeyObject;
- NSSCKFWObject *fwObject = NULL;
- NSSArena *arena;
-
- if (!fwMechanism->mdMechanism->DeriveKey) {
- *pError = CKR_FUNCTION_FAILED;
- return (NSSCKFWObject *)NULL;
- }
-
- arena = nssCKFWToken_GetArena(fwMechanism->fwToken, pError);
- if (!arena) {
- if (CKR_OK == *pError) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
- }
-
- mdSession = nssCKFWSession_GetMDSession(fwSession);
- mdBaseKeyObject = nssCKFWObject_GetMDObject(fwBaseKeyObject);
- mdObject = fwMechanism->mdMechanism->DeriveKey(
- fwMechanism->mdMechanism,
- fwMechanism,
- pMechanism,
- mdSession,
- fwSession,
- fwMechanism->mdToken,
- fwMechanism->fwToken,
- fwMechanism->mdInstance,
- fwMechanism->fwInstance,
- mdBaseKeyObject,
- fwBaseKeyObject,
- pTemplate,
- ulAttributeCount,
- pError);
-
- if (!mdObject) {
- return (NSSCKFWObject *)NULL;
- }
-
- fwObject = nssCKFWObject_Create(arena, mdObject,
- fwSession, fwMechanism->fwToken, fwMechanism->fwInstance, pError);
-
- return fwObject;
-}
-
diff --git a/security/nss/lib/ckfw/mutex.c b/security/nss/lib/ckfw/mutex.c
deleted file mode 100644
index c3e3c5d4b..000000000
--- a/security/nss/lib/ckfw/mutex.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * mutex.c
- *
- * This file implements a mutual-exclusion locking facility for Modules
- * using the NSS Cryptoki Framework.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * NSSCKFWMutex
- *
- * NSSCKFWMutex_Destroy
- * NSSCKFWMutex_Lock
- * NSSCKFWMutex_Unlock
- *
- * nssCKFWMutex_Create
- * nssCKFWMutex_Destroy
- * nssCKFWMutex_Lock
- * nssCKFWMutex_Unlock
- *
- * -- debugging versions only --
- * nssCKFWMutex_verifyPointer
- *
- */
-
-struct NSSCKFWMutexStr {
- PRLock *lock;
-};
-
-#ifdef DEBUG
-/*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do this routines as no-ops.
- */
-
-static CK_RV
-mutex_add_pointer
-(
- const NSSCKFWMutex *fwMutex
-)
-{
- return CKR_OK;
-}
-
-static CK_RV
-mutex_remove_pointer
-(
- const NSSCKFWMutex *fwMutex
-)
-{
- return CKR_OK;
-}
-
-NSS_IMPLEMENT CK_RV
-nssCKFWMutex_verifyPointer
-(
- const NSSCKFWMutex *fwMutex
-)
-{
- return CKR_OK;
-}
-
-#endif /* DEBUG */
-
-/*
- * nssCKFWMutex_Create
- *
- */
-NSS_EXTERN NSSCKFWMutex *
-nssCKFWMutex_Create
-(
- CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState LockingState,
- NSSArena *arena,
- CK_RV *pError
-)
-{
- NSSCKFWMutex *mutex;
-
- mutex = nss_ZNEW(arena, NSSCKFWMutex);
- if (!mutex) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWMutex *)NULL;
- }
- *pError = CKR_OK;
- mutex->lock = NULL;
- if (LockingState == MultiThreaded) {
- mutex->lock = PR_NewLock();
- if (!mutex->lock) {
- *pError = CKR_HOST_MEMORY; /* we couldn't get the resource */
- }
- }
-
- if( CKR_OK != *pError ) {
- (void)nss_ZFreeIf(mutex);
- return (NSSCKFWMutex *)NULL;
- }
-
-#ifdef DEBUG
- *pError = mutex_add_pointer(mutex);
- if( CKR_OK != *pError ) {
- if (mutex->lock) {
- PR_DestroyLock(mutex->lock);
- }
- (void)nss_ZFreeIf(mutex);
- return (NSSCKFWMutex *)NULL;
- }
-#endif /* DEBUG */
-
- return mutex;
-}
-
-/*
- * nssCKFWMutex_Destroy
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWMutex_Destroy
-(
- NSSCKFWMutex *mutex
-)
-{
- CK_RV rv = CKR_OK;
-
-#ifdef NSSDEBUG
- rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
-#endif /* NSSDEBUG */
-
- if (mutex->lock) {
- PR_DestroyLock(mutex->lock);
- }
-
-#ifdef DEBUG
- (void)mutex_remove_pointer(mutex);
-#endif /* DEBUG */
-
- (void)nss_ZFreeIf(mutex);
- return rv;
-}
-
-/*
- * nssCKFWMutex_Lock
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWMutex_Lock
-(
- NSSCKFWMutex *mutex
-)
-{
-#ifdef NSSDEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
-#endif /* NSSDEBUG */
- if (mutex->lock) {
- PR_Lock(mutex->lock);
- }
-
- return CKR_OK;
-}
-
-/*
- * nssCKFWMutex_Unlock
- *
- */
-NSS_EXTERN CK_RV
-nssCKFWMutex_Unlock
-(
- NSSCKFWMutex *mutex
-)
-{
- PRStatus nrv;
-#ifdef NSSDEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
-
- if( CKR_OK != rv ) {
- return rv;
- }
-#endif /* NSSDEBUG */
-
- if (!mutex->lock)
- return CKR_OK;
-
- nrv = PR_Unlock(mutex->lock);
-
- /* if unlock fails, either we have a programming error, or we have
- * some sort of hardware failure... in either case return CKR_DEVICE_ERROR.
- */
- return nrv == PR_SUCCESS ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-/*
- * NSSCKFWMutex_Destroy
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWMutex_Destroy
-(
- NSSCKFWMutex *mutex
-)
-{
-#ifdef DEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
-#endif /* DEBUG */
-
- return nssCKFWMutex_Destroy(mutex);
-}
-
-/*
- * NSSCKFWMutex_Lock
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWMutex_Lock
-(
- NSSCKFWMutex *mutex
-)
-{
-#ifdef DEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
-#endif /* DEBUG */
-
- return nssCKFWMutex_Lock(mutex);
-}
-
-/*
- * NSSCKFWMutex_Unlock
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWMutex_Unlock
-(
- NSSCKFWMutex *mutex
-)
-{
-#ifdef DEBUG
- CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
- if( CKR_OK != rv ) {
- return rv;
- }
-#endif /* DEBUG */
-
- return nssCKFWMutex_Unlock(mutex);
-}
-
diff --git a/security/nss/lib/ckfw/nssck.api b/security/nss/lib/ckfw/nssck.api
deleted file mode 100644
index 57ce096ea..000000000
--- a/security/nss/lib/ckfw/nssck.api
+++ /dev/null
@@ -1,1858 +0,0 @@
-/* THIS IS A GENERATED FILE */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char NSSCKAPI_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ ; @(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssck.api
- *
- * This automatically-generated file is used to generate a set of
- * Cryptoki entry points within the object space of a Module using
- * the NSS Cryptoki Framework.
- *
- * The Module should have a .c file with the following:
- *
- * #define MODULE_NAME name
- * #define INSTANCE_NAME instance
- * #include "nssck.api"
- *
- * where "name" is some module-specific name that can be used to
- * disambiguate various modules. This included file will then
- * define the actual Cryptoki routines which pass through to the
- * Framework calls. All routines, except C_GetFunctionList, will
- * be prefixed with the name; C_GetFunctionList will be generated
- * to return an entry-point vector with these routines. The
- * instance specified should be the basic instance of NSSCKMDInstance.
- *
- * If, prior to including nssck.api, the .c file also specifies
- *
- * #define DECLARE_STRICT_CRYTPOKI_NAMES
- *
- * Then a set of "stub" routines not prefixed with the name will
- * be included. This would allow the combined module and framework
- * to be used in applications which are hard-coded to use the
- * PKCS#11 names (instead of going through the EPV). Please note
- * that such applications should be careful resolving symbols when
- * more than one PKCS#11 module is loaded.
- */
-
-#ifndef MODULE_NAME
-#error "Error: MODULE_NAME must be defined."
-#endif /* MODULE_NAME */
-
-#ifndef INSTANCE_NAME
-#error "Error: INSTANCE_NAME must be defined."
-#endif /* INSTANCE_NAME */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFWT_H
-#include "nssckfwt.h"
-#endif /* NSSCKFWT_H */
-
-#ifndef NSSCKFWC_H
-#include "nssckfwc.h"
-#endif /* NSSCKFWC_H */
-
-#ifndef NSSCKEPV_H
-#include "nssckepv.h"
-#endif /* NSSCKEPV_H */
-
-#define ADJOIN(x,y) x##y
-
-#define __ADJOIN(x,y) ADJOIN(x,y)
-
-/*
- * The anchor. This object is used to store an "anchor" pointer in
- * the Module's object space, so the wrapper functions can relate
- * back to this instance.
- */
-
-static NSSCKFWInstance *fwInstance = (NSSCKFWInstance *)0;
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Initialize)
-(
- CK_VOID_PTR pInitArgs
-)
-{
- return NSSCKFWC_Initialize(&fwInstance, INSTANCE_NAME, pInitArgs);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Initialize
-(
- CK_VOID_PTR pInitArgs
-)
-{
- return __ADJOIN(MODULE_NAME,C_Initialize)(pInitArgs);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Finalize)
-(
- CK_VOID_PTR pReserved
-)
-{
- return NSSCKFWC_Finalize(&fwInstance);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Finalize
-(
- CK_VOID_PTR pReserved
-)
-{
- return __ADJOIN(MODULE_NAME,C_Finalize)(pReserved);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetInfo)
-(
- CK_INFO_PTR pInfo
-)
-{
- return NSSCKFWC_GetInfo(fwInstance, pInfo);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetInfo
-(
- CK_INFO_PTR pInfo
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetInfo)(pInfo);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-/*
- * C_GetFunctionList is defined at the end.
- */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetSlotList)
-(
- CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount
-)
-{
- return NSSCKFWC_GetSlotList(fwInstance, tokenPresent, pSlotList, pulCount);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetSlotList
-(
- CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetSlotList)(tokenPresent, pSlotList, pulCount);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetSlotInfo)
-(
- CK_SLOT_ID slotID,
- CK_SLOT_INFO_PTR pInfo
-)
-{
- return NSSCKFWC_GetSlotInfo(fwInstance, slotID, pInfo);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetSlotInfo
-(
- CK_SLOT_ID slotID,
- CK_SLOT_INFO_PTR pInfo
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetSlotInfo)(slotID, pInfo);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetTokenInfo)
-(
- CK_SLOT_ID slotID,
- CK_TOKEN_INFO_PTR pInfo
-)
-{
- return NSSCKFWC_GetTokenInfo(fwInstance, slotID, pInfo);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetTokenInfo
-(
- CK_SLOT_ID slotID,
- CK_TOKEN_INFO_PTR pInfo
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetTokenInfo)(slotID, pInfo);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetMechanismList)
-(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount
-)
-{
- return NSSCKFWC_GetMechanismList(fwInstance, slotID, pMechanismList, pulCount);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetMechanismList
-(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetMechanismList)(slotID, pMechanismList, pulCount);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetMechanismInfo)
-(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo
-)
-{
- return NSSCKFWC_GetMechanismInfo(fwInstance, slotID, type, pInfo);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetMechanismInfo
-(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetMechanismInfo)(slotID, type, pInfo);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_InitToken)
-(
- CK_SLOT_ID slotID,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,
- CK_CHAR_PTR pLabel
-)
-{
- return NSSCKFWC_InitToken(fwInstance, slotID, pPin, ulPinLen, pLabel);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_InitToken
-(
- CK_SLOT_ID slotID,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,
- CK_CHAR_PTR pLabel
-)
-{
- return __ADJOIN(MODULE_NAME,C_InitToken)(slotID, pPin, ulPinLen, pLabel);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_InitPIN)
-(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
-{
- return NSSCKFWC_InitPIN(fwInstance, hSession, pPin, ulPinLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_InitPIN
-(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_InitPIN)(hSession, pPin, ulPinLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SetPIN)
-(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen,
- CK_CHAR_PTR pNewPin,
- CK_ULONG ulNewLen
-)
-{
- return NSSCKFWC_SetPIN(fwInstance, hSession, pOldPin, ulOldLen, pNewPin, ulNewLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SetPIN
-(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen,
- CK_CHAR_PTR pNewPin,
- CK_ULONG ulNewLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_SetPIN)(hSession, pOldPin, ulOldLen, pNewPin, ulNewLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_OpenSession)
-(
- CK_SLOT_ID slotID,
- CK_FLAGS flags,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_SESSION_HANDLE_PTR phSession
-)
-{
- return NSSCKFWC_OpenSession(fwInstance, slotID, flags, pApplication, Notify, phSession);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_OpenSession
-(
- CK_SLOT_ID slotID,
- CK_FLAGS flags,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_SESSION_HANDLE_PTR phSession
-)
-{
- return __ADJOIN(MODULE_NAME,C_OpenSession)(slotID, flags, pApplication, Notify, phSession);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_CloseSession)
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return NSSCKFWC_CloseSession(fwInstance, hSession);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_CloseSession
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return __ADJOIN(MODULE_NAME,C_CloseSession)(hSession);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_CloseAllSessions)
-(
- CK_SLOT_ID slotID
-)
-{
- return NSSCKFWC_CloseAllSessions(fwInstance, slotID);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_CloseAllSessions
-(
- CK_SLOT_ID slotID
-)
-{
- return __ADJOIN(MODULE_NAME,C_CloseAllSessions)(slotID);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetSessionInfo)
-(
- CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo
-)
-{
- return NSSCKFWC_GetSessionInfo(fwInstance, hSession, pInfo);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetSessionInfo
-(
- CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetSessionInfo)(hSession, pInfo);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetOperationState)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG_PTR pulOperationStateLen
-)
-{
- return NSSCKFWC_GetOperationState(fwInstance, hSession, pOperationState, pulOperationStateLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetOperationState
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG_PTR pulOperationStateLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetOperationState)(hSession, pOperationState, pulOperationStateLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SetOperationState)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey,
- CK_OBJECT_HANDLE hAuthenticationKey
-)
-{
- return NSSCKFWC_SetOperationState(fwInstance, hSession, pOperationState, ulOperationStateLen, hEncryptionKey, hAuthenticationKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SetOperationState
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey,
- CK_OBJECT_HANDLE hAuthenticationKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_SetOperationState)(hSession, pOperationState, ulOperationStateLen, hEncryptionKey, hAuthenticationKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Login)
-(
- CK_SESSION_HANDLE hSession,
- CK_USER_TYPE userType,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
-{
- return NSSCKFWC_Login(fwInstance, hSession, userType, pPin, ulPinLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Login
-(
- CK_SESSION_HANDLE hSession,
- CK_USER_TYPE userType,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_Login)(hSession, userType, pPin, ulPinLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Logout)
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return NSSCKFWC_Logout(fwInstance, hSession);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Logout
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return __ADJOIN(MODULE_NAME,C_Logout)(hSession);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_CreateObject)
-(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject
-)
-{
- return NSSCKFWC_CreateObject(fwInstance, hSession, pTemplate, ulCount, phObject);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_CreateObject
-(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject
-)
-{
- return __ADJOIN(MODULE_NAME,C_CreateObject)(hSession, pTemplate, ulCount, phObject);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_CopyObject)
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject
-)
-{
- return NSSCKFWC_CopyObject(fwInstance, hSession, hObject, pTemplate, ulCount, phNewObject);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_CopyObject
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject
-)
-{
- return __ADJOIN(MODULE_NAME,C_CopyObject)(hSession, hObject, pTemplate, ulCount, phNewObject);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DestroyObject)
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject
-)
-{
- return NSSCKFWC_DestroyObject(fwInstance, hSession, hObject);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DestroyObject
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject
-)
-{
- return __ADJOIN(MODULE_NAME,C_DestroyObject)(hSession, hObject);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetObjectSize)
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ULONG_PTR pulSize
-)
-{
- return NSSCKFWC_GetObjectSize(fwInstance, hSession, hObject, pulSize);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetObjectSize
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ULONG_PTR pulSize
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetObjectSize)(hSession, hObject, pulSize);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetAttributeValue)
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- return NSSCKFWC_GetAttributeValue(fwInstance, hSession, hObject, pTemplate, ulCount);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetAttributeValue
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetAttributeValue)(hSession, hObject, pTemplate, ulCount);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SetAttributeValue)
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- return NSSCKFWC_SetAttributeValue(fwInstance, hSession, hObject, pTemplate, ulCount);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SetAttributeValue
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- return __ADJOIN(MODULE_NAME,C_SetAttributeValue)(hSession, hObject, pTemplate, ulCount);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_FindObjectsInit)
-(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- return NSSCKFWC_FindObjectsInit(fwInstance, hSession, pTemplate, ulCount);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_FindObjectsInit
-(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- return __ADJOIN(MODULE_NAME,C_FindObjectsInit)(hSession, pTemplate, ulCount);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_FindObjects)
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,
- CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount
-)
-{
- return NSSCKFWC_FindObjects(fwInstance, hSession, phObject, ulMaxObjectCount, pulObjectCount);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_FindObjects
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,
- CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount
-)
-{
- return __ADJOIN(MODULE_NAME,C_FindObjects)(hSession, phObject, ulMaxObjectCount, pulObjectCount);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_FindObjectsFinal)
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return NSSCKFWC_FindObjectsFinal(fwInstance, hSession);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_FindObjectsFinal
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return __ADJOIN(MODULE_NAME,C_FindObjectsFinal)(hSession);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_EncryptInit)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return NSSCKFWC_EncryptInit(fwInstance, hSession, pMechanism, hKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_EncryptInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_EncryptInit)(hSession, pMechanism, hKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Encrypt)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen
-)
-{
- return NSSCKFWC_Encrypt(fwInstance, hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Encrypt
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_Encrypt)(hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_EncryptUpdate)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- return NSSCKFWC_EncryptUpdate(fwInstance, hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_EncryptUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_EncryptUpdate)(hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_EncryptFinal)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart,
- CK_ULONG_PTR pulLastEncryptedPartLen
-)
-{
- return NSSCKFWC_EncryptFinal(fwInstance, hSession, pLastEncryptedPart, pulLastEncryptedPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_EncryptFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart,
- CK_ULONG_PTR pulLastEncryptedPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_EncryptFinal)(hSession, pLastEncryptedPart, pulLastEncryptedPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DecryptInit)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return NSSCKFWC_DecryptInit(fwInstance, hSession, pMechanism, hKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DecryptInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_DecryptInit)(hSession, pMechanism, hKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Decrypt)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-)
-{
- return NSSCKFWC_Decrypt(fwInstance, hSession, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Decrypt
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_Decrypt)(hSession, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DecryptUpdate)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- return NSSCKFWC_DecryptUpdate(fwInstance, hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DecryptUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_DecryptUpdate)(hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DecryptFinal)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart,
- CK_ULONG_PTR pulLastPartLen
-)
-{
- return NSSCKFWC_DecryptFinal(fwInstance, hSession, pLastPart, pulLastPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DecryptFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart,
- CK_ULONG_PTR pulLastPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_DecryptFinal)(hSession, pLastPart, pulLastPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DigestInit)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism
-)
-{
- return NSSCKFWC_DigestInit(fwInstance, hSession, pMechanism);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DigestInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism
-)
-{
- return __ADJOIN(MODULE_NAME,C_DigestInit)(hSession, pMechanism);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Digest)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-)
-{
- return NSSCKFWC_Digest(fwInstance, hSession, pData, ulDataLen, pDigest, pulDigestLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Digest
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_Digest)(hSession, pData, ulDataLen, pDigest, pulDigestLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DigestUpdate)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- return NSSCKFWC_DigestUpdate(fwInstance, hSession, pPart, ulPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DigestUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_DigestUpdate)(hSession, pPart, ulPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DigestKey)
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey
-)
-{
- return NSSCKFWC_DigestKey(fwInstance, hSession, hKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DigestKey
-(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_DigestKey)(hSession, hKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DigestFinal)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-)
-{
- return NSSCKFWC_DigestFinal(fwInstance, hSession, pDigest, pulDigestLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DigestFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_DigestFinal)(hSession, pDigest, pulDigestLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SignInit)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return NSSCKFWC_SignInit(fwInstance, hSession, pMechanism, hKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SignInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_SignInit)(hSession, pMechanism, hKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Sign)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- return NSSCKFWC_Sign(fwInstance, hSession, pData, ulDataLen, pSignature, pulSignatureLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Sign
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_Sign)(hSession, pData, ulDataLen, pSignature, pulSignatureLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SignUpdate)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- return NSSCKFWC_SignUpdate(fwInstance, hSession, pPart, ulPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SignUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_SignUpdate)(hSession, pPart, ulPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SignFinal)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- return NSSCKFWC_SignFinal(fwInstance, hSession, pSignature, pulSignatureLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SignFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_SignFinal)(hSession, pSignature, pulSignatureLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SignRecoverInit)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return NSSCKFWC_SignRecoverInit(fwInstance, hSession, pMechanism, hKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SignRecoverInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_SignRecoverInit)(hSession, pMechanism, hKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SignRecover)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- return NSSCKFWC_SignRecover(fwInstance, hSession, pData, ulDataLen, pSignature, pulSignatureLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SignRecover
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_SignRecover)(hSession, pData, ulDataLen, pSignature, pulSignatureLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_VerifyInit)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return NSSCKFWC_VerifyInit(fwInstance, hSession, pMechanism, hKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_VerifyInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_VerifyInit)(hSession, pMechanism, hKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_Verify)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-)
-{
- return NSSCKFWC_Verify(fwInstance, hSession, pData, ulDataLen, pSignature, ulSignatureLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_Verify
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_Verify)(hSession, pData, ulDataLen, pSignature, ulSignatureLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_VerifyUpdate)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- return NSSCKFWC_VerifyUpdate(fwInstance, hSession, pPart, ulPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_VerifyUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_VerifyUpdate)(hSession, pPart, ulPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_VerifyFinal)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-)
-{
- return NSSCKFWC_VerifyFinal(fwInstance, hSession, pSignature, ulSignatureLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_VerifyFinal
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_VerifyFinal)(hSession, pSignature, ulSignatureLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_VerifyRecoverInit)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return NSSCKFWC_VerifyRecoverInit(fwInstance, hSession, pMechanism, hKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_VerifyRecoverInit
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_VerifyRecoverInit)(hSession, pMechanism, hKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_VerifyRecover)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-)
-{
- return NSSCKFWC_VerifyRecover(fwInstance, hSession, pSignature, ulSignatureLen, pData, pulDataLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_VerifyRecover
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_VerifyRecover)(hSession, pSignature, ulSignatureLen, pData, pulDataLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DigestEncryptUpdate)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- return NSSCKFWC_DigestEncryptUpdate(fwInstance, hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DigestEncryptUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_DigestEncryptUpdate)(hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DecryptDigestUpdate)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- return NSSCKFWC_DecryptDigestUpdate(fwInstance, hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DecryptDigestUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_DecryptDigestUpdate)(hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SignEncryptUpdate)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- return NSSCKFWC_SignEncryptUpdate(fwInstance, hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SignEncryptUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_SignEncryptUpdate)(hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DecryptVerifyUpdate)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- return NSSCKFWC_DecryptVerifyUpdate(fwInstance, hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DecryptVerifyUpdate
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_DecryptVerifyUpdate)(hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GenerateKey)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- return NSSCKFWC_GenerateKey(fwInstance, hSession, pMechanism, pTemplate, ulCount, phKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GenerateKey
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_GenerateKey)(hSession, pMechanism, pTemplate, ulCount, phKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GenerateKeyPair)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey
-)
-{
- return NSSCKFWC_GenerateKeyPair(fwInstance, hSession, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GenerateKeyPair
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_GenerateKeyPair)(hSession, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_WrapKey)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen
-)
-{
- return NSSCKFWC_WrapKey(fwInstance, hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_WrapKey
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_WrapKey)(hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_UnwrapKey)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- return NSSCKFWC_UnwrapKey(fwInstance, hSession, pMechanism, hUnwrappingKey, pWrappedKey, ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_UnwrapKey
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_UnwrapKey)(hSession, pMechanism, hUnwrappingKey, pWrappedKey, ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_DeriveKey)
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- return NSSCKFWC_DeriveKey(fwInstance, hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_DeriveKey
-(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- return __ADJOIN(MODULE_NAME,C_DeriveKey)(hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phKey);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_SeedRandom)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen
-)
-{
- return NSSCKFWC_SeedRandom(fwInstance, hSession, pSeed, ulSeedLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_SeedRandom
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_SeedRandom)(hSession, pSeed, ulSeedLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GenerateRandom)
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR RandomData,
- CK_ULONG ulRandomLen
-)
-{
- return NSSCKFWC_GenerateRandom(fwInstance, hSession, RandomData, ulRandomLen);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GenerateRandom
-(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR RandomData,
- CK_ULONG ulRandomLen
-)
-{
- return __ADJOIN(MODULE_NAME,C_GenerateRandom)(hSession, RandomData, ulRandomLen);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetFunctionStatus)
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return NSSCKFWC_GetFunctionStatus(fwInstance, hSession);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_GetFunctionStatus
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetFunctionStatus)(hSession);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_CancelFunction)
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return NSSCKFWC_CancelFunction(fwInstance, hSession);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_CancelFunction
-(
- CK_SESSION_HANDLE hSession
-)
-{
- return __ADJOIN(MODULE_NAME,C_CancelFunction)(hSession);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_WaitForSlotEvent)
-(
- CK_FLAGS flags,
- CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pRserved
-)
-{
- return NSSCKFWC_WaitForSlotEvent(fwInstance, flags, pSlot, pRserved);
-}
-
-#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
-CK_RV CK_ENTRY
-C_WaitForSlotEvent
-(
- CK_FLAGS flags,
- CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pRserved
-)
-{
- return __ADJOIN(MODULE_NAME,C_WaitForSlotEvent)(flags, pSlot, pRserved);
-}
-#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetFunctionList)
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList
-);
-
-static CK_FUNCTION_LIST FunctionList = {
- { 2, 1 },
-__ADJOIN(MODULE_NAME,C_Initialize),
-__ADJOIN(MODULE_NAME,C_Finalize),
-__ADJOIN(MODULE_NAME,C_GetInfo),
-__ADJOIN(MODULE_NAME,C_GetFunctionList),
-__ADJOIN(MODULE_NAME,C_GetSlotList),
-__ADJOIN(MODULE_NAME,C_GetSlotInfo),
-__ADJOIN(MODULE_NAME,C_GetTokenInfo),
-__ADJOIN(MODULE_NAME,C_GetMechanismList),
-__ADJOIN(MODULE_NAME,C_GetMechanismInfo),
-__ADJOIN(MODULE_NAME,C_InitToken),
-__ADJOIN(MODULE_NAME,C_InitPIN),
-__ADJOIN(MODULE_NAME,C_SetPIN),
-__ADJOIN(MODULE_NAME,C_OpenSession),
-__ADJOIN(MODULE_NAME,C_CloseSession),
-__ADJOIN(MODULE_NAME,C_CloseAllSessions),
-__ADJOIN(MODULE_NAME,C_GetSessionInfo),
-__ADJOIN(MODULE_NAME,C_GetOperationState),
-__ADJOIN(MODULE_NAME,C_SetOperationState),
-__ADJOIN(MODULE_NAME,C_Login),
-__ADJOIN(MODULE_NAME,C_Logout),
-__ADJOIN(MODULE_NAME,C_CreateObject),
-__ADJOIN(MODULE_NAME,C_CopyObject),
-__ADJOIN(MODULE_NAME,C_DestroyObject),
-__ADJOIN(MODULE_NAME,C_GetObjectSize),
-__ADJOIN(MODULE_NAME,C_GetAttributeValue),
-__ADJOIN(MODULE_NAME,C_SetAttributeValue),
-__ADJOIN(MODULE_NAME,C_FindObjectsInit),
-__ADJOIN(MODULE_NAME,C_FindObjects),
-__ADJOIN(MODULE_NAME,C_FindObjectsFinal),
-__ADJOIN(MODULE_NAME,C_EncryptInit),
-__ADJOIN(MODULE_NAME,C_Encrypt),
-__ADJOIN(MODULE_NAME,C_EncryptUpdate),
-__ADJOIN(MODULE_NAME,C_EncryptFinal),
-__ADJOIN(MODULE_NAME,C_DecryptInit),
-__ADJOIN(MODULE_NAME,C_Decrypt),
-__ADJOIN(MODULE_NAME,C_DecryptUpdate),
-__ADJOIN(MODULE_NAME,C_DecryptFinal),
-__ADJOIN(MODULE_NAME,C_DigestInit),
-__ADJOIN(MODULE_NAME,C_Digest),
-__ADJOIN(MODULE_NAME,C_DigestUpdate),
-__ADJOIN(MODULE_NAME,C_DigestKey),
-__ADJOIN(MODULE_NAME,C_DigestFinal),
-__ADJOIN(MODULE_NAME,C_SignInit),
-__ADJOIN(MODULE_NAME,C_Sign),
-__ADJOIN(MODULE_NAME,C_SignUpdate),
-__ADJOIN(MODULE_NAME,C_SignFinal),
-__ADJOIN(MODULE_NAME,C_SignRecoverInit),
-__ADJOIN(MODULE_NAME,C_SignRecover),
-__ADJOIN(MODULE_NAME,C_VerifyInit),
-__ADJOIN(MODULE_NAME,C_Verify),
-__ADJOIN(MODULE_NAME,C_VerifyUpdate),
-__ADJOIN(MODULE_NAME,C_VerifyFinal),
-__ADJOIN(MODULE_NAME,C_VerifyRecoverInit),
-__ADJOIN(MODULE_NAME,C_VerifyRecover),
-__ADJOIN(MODULE_NAME,C_DigestEncryptUpdate),
-__ADJOIN(MODULE_NAME,C_DecryptDigestUpdate),
-__ADJOIN(MODULE_NAME,C_SignEncryptUpdate),
-__ADJOIN(MODULE_NAME,C_DecryptVerifyUpdate),
-__ADJOIN(MODULE_NAME,C_GenerateKey),
-__ADJOIN(MODULE_NAME,C_GenerateKeyPair),
-__ADJOIN(MODULE_NAME,C_WrapKey),
-__ADJOIN(MODULE_NAME,C_UnwrapKey),
-__ADJOIN(MODULE_NAME,C_DeriveKey),
-__ADJOIN(MODULE_NAME,C_SeedRandom),
-__ADJOIN(MODULE_NAME,C_GenerateRandom),
-__ADJOIN(MODULE_NAME,C_GetFunctionStatus),
-__ADJOIN(MODULE_NAME,C_CancelFunction),
-__ADJOIN(MODULE_NAME,C_WaitForSlotEvent)
-};
-
-static CK_RV CK_ENTRY
-__ADJOIN(MODULE_NAME,C_GetFunctionList)
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList
-)
-{
- *ppFunctionList = &FunctionList;
- return CKR_OK;
-}
-
-/* This one is always present */
-CK_RV CK_ENTRY
-C_GetFunctionList
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList
-)
-{
- return __ADJOIN(MODULE_NAME,C_GetFunctionList)(ppFunctionList);
-}
-
-#undef __ADJOIN
-
diff --git a/security/nss/lib/ckfw/nssckepv.h b/security/nss/lib/ckfw/nssckepv.h
deleted file mode 100644
index 042845d31..000000000
--- a/security/nss/lib/ckfw/nssckepv.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* THIS IS A GENERATED FILE */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef NSSCKEPV_H
-#define NSSCKEPV_H
-
-#include "pkcs11.h"
-
-#endif /* NSSCKEPV_H */
diff --git a/security/nss/lib/ckfw/nssckft.h b/security/nss/lib/ckfw/nssckft.h
deleted file mode 100644
index 80ee29245..000000000
--- a/security/nss/lib/ckfw/nssckft.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* THIS IS A GENERATED FILE */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _NSSCKFT_H_
-#define _NSSCKFT_H_ 1
-
-#include "pkcs11t.h"
-
-#endif /* _NSSCKFT_H_ */
diff --git a/security/nss/lib/ckfw/nssckfw.h b/security/nss/lib/ckfw/nssckfw.h
deleted file mode 100644
index 16b121fd0..000000000
--- a/security/nss/lib/ckfw/nssckfw.h
+++ /dev/null
@@ -1,494 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSCKFW_H
-#define NSSCKFW_H
-
-#ifdef DEBUG
-static const char NSSCKFW_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssckfw.h
- *
- * This file prototypes the publicly available calls of the
- * NSS Cryptoki Framework.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFWT_H
-#include "nssckfwt.h"
-#endif /* NSSCKFWT_H */
-
-/*
- * NSSCKFWInstance
- *
- * NSSCKFWInstance_GetMDInstance
- * NSSCKFWInstance_GetArena
- * NSSCKFWInstance_MayCreatePthreads
- * NSSCKFWInstance_CreateMutex
- * NSSCKFWInstance_GetConfigurationData
- */
-
-/*
- * NSSCKFWInstance_GetMDInstance
- *
- */
-
-NSS_EXTERN NSSCKMDInstance *
-NSSCKFWInstance_GetMDInstance
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * NSSCKFWInstance_GetArena
- *
- */
-
-NSS_EXTERN NSSArena *
-NSSCKFWInstance_GetArena
-(
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWInstance_MayCreatePthreads
- *
- */
-
-NSS_EXTERN CK_BBOOL
-NSSCKFWInstance_MayCreatePthreads
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * NSSCKFWInstance_CreateMutex
- *
- */
-
-NSS_EXTERN NSSCKFWMutex *
-NSSCKFWInstance_CreateMutex
-(
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWInstance_GetConfigurationData
- *
- */
-
-NSS_EXTERN NSSUTF8 *
-NSSCKFWInstance_GetConfigurationData
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * NSSCKFWInstance_GetInitArgs
- *
- */
-
-NSS_EXTERN CK_C_INITIALIZE_ARGS_PTR
-NSSCKFWInstance_GetInitArgs
-(
- NSSCKFWInstance *fwInstance
-);
-
-/*
- * NSSCKFWSlot
- *
- * NSSCKFWSlot_GetMDSlot
- * NSSCKFWSlot_GetFWInstance
- * NSSCKFWSlot_GetMDInstance
- *
- */
-
-/*
- * NSSCKFWSlot_GetMDSlot
- *
- */
-
-NSS_EXTERN NSSCKMDSlot *
-NSSCKFWSlot_GetMDSlot
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * NSSCKFWSlot_GetFWInstance
- *
- */
-
-NSS_EXTERN NSSCKFWInstance *
-NSSCKFWSlot_GetFWInstance
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * NSSCKFWSlot_GetMDInstance
- *
- */
-
-NSS_EXTERN NSSCKMDInstance *
-NSSCKFWSlot_GetMDInstance
-(
- NSSCKFWSlot *fwSlot
-);
-
-/*
- * NSSCKFWToken
- *
- * NSSCKFWToken_GetMDToken
- * NSSCKFWToken_GetFWSlot
- * NSSCKFWToken_GetMDSlot
- * NSSCKFWToken_GetSessionState
- *
- */
-
-/*
- * NSSCKFWToken_GetMDToken
- *
- */
-
-NSS_EXTERN NSSCKMDToken *
-NSSCKFWToken_GetMDToken
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * NSSCKFWToken_GetArena
- *
- */
-
-NSS_EXTERN NSSArena *
-NSSCKFWToken_GetArena
-(
- NSSCKFWToken *fwToken,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWToken_GetFWSlot
- *
- */
-
-NSS_EXTERN NSSCKFWSlot *
-NSSCKFWToken_GetFWSlot
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * NSSCKFWToken_GetMDSlot
- *
- */
-
-NSS_EXTERN NSSCKMDSlot *
-NSSCKFWToken_GetMDSlot
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * NSSCKFWToken_GetSessionState
- *
- */
-
-NSS_EXTERN CK_STATE
-NSSCKFWToken_GetSessionState
-(
- NSSCKFWToken *fwToken
-);
-
-/*
- * NSSCKFWMechanism
- *
- * NSSKCFWMechanism_GetMDMechanism
- * NSSCKFWMechanism_GetParameter
- *
- */
-
-/*
- * NSSKCFWMechanism_GetMDMechanism
- *
- */
-
-NSS_EXTERN NSSCKMDMechanism *
-NSSCKFWMechanism_GetMDMechanism
-(
- NSSCKFWMechanism *fwMechanism
-);
-
-/*
- * NSSCKFWMechanism_GetParameter
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCKFWMechanism_GetParameter
-(
- NSSCKFWMechanism *fwMechanism
-);
-
-/*
- * NSSCKFWSession
- *
- * NSSCKFWSession_GetMDSession
- * NSSCKFWSession_GetArena
- * NSSCKFWSession_CallNotification
- * NSSCKFWSession_IsRWSession
- * NSSCKFWSession_IsSO
- * NSSCKFWSession_GetCurrentCryptoOperation
- *
- */
-
-/*
- * NSSCKFWSession_GetMDSession
- *
- */
-
-NSS_EXTERN NSSCKMDSession *
-NSSCKFWSession_GetMDSession
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * NSSCKFWSession_GetArena
- *
- */
-
-NSS_EXTERN NSSArena *
-NSSCKFWSession_GetArena
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWSession_CallNotification
- *
- */
-
-NSS_EXTERN CK_RV
-NSSCKFWSession_CallNotification
-(
- NSSCKFWSession *fwSession,
- CK_NOTIFICATION event
-);
-
-/*
- * NSSCKFWSession_IsRWSession
- *
- */
-
-NSS_EXTERN CK_BBOOL
-NSSCKFWSession_IsRWSession
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * NSSCKFWSession_IsSO
- *
- */
-
-NSS_EXTERN CK_BBOOL
-NSSCKFWSession_IsSO
-(
- NSSCKFWSession *fwSession
-);
-
-/*
- * NSSCKFWSession_GetCurrentCryptoOperation
- *
- */
-
-NSS_EXTERN NSSCKFWCryptoOperation *
-NSSCKFWSession_GetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationState state
-);
-
-/*
- * NSSCKFWObject
- *
- * NSSCKFWObject_GetMDObject
- * NSSCKFWObject_GetArena
- * NSSCKFWObject_IsTokenObject
- * NSSCKFWObject_GetAttributeCount
- * NSSCKFWObject_GetAttributeTypes
- * NSSCKFWObject_GetAttributeSize
- * NSSCKFWObject_GetAttribute
- * NSSCKFWObject_GetObjectSize
- */
-
-/*
- * NSSCKFWObject_GetMDObject
- *
- */
-NSS_EXTERN NSSCKMDObject *
-NSSCKFWObject_GetMDObject
-(
- NSSCKFWObject *fwObject
-);
-
-/*
- * NSSCKFWObject_GetArena
- *
- */
-NSS_EXTERN NSSArena *
-NSSCKFWObject_GetArena
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWObject_IsTokenObject
- *
- */
-NSS_EXTERN CK_BBOOL
-NSSCKFWObject_IsTokenObject
-(
- NSSCKFWObject *fwObject
-);
-
-/*
- * NSSCKFWObject_GetAttributeCount
- *
- */
-NSS_EXTERN CK_ULONG
-NSSCKFWObject_GetAttributeCount
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWObject_GetAttributeTypes
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWObject_GetAttributeTypes
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-);
-
-/*
- * NSSCKFWObject_GetAttributeSize
- *
- */
-NSS_EXTERN CK_ULONG
-NSSCKFWObject_GetAttributeSize
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWObject_GetAttribute
- *
- */
-NSS_EXTERN NSSItem *
-NSSCKFWObject_GetAttribute
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *itemOpt,
- NSSArena *arenaOpt,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWObject_GetObjectSize
- *
- */
-NSS_EXTERN CK_ULONG
-NSSCKFWObject_GetObjectSize
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-);
-
-/*
- * NSSCKFWFindObjects
- *
- * NSSCKFWFindObjects_GetMDFindObjects
- *
- */
-
-/*
- * NSSCKFWFindObjects_GetMDFindObjects
- *
- */
-
-NSS_EXTERN NSSCKMDFindObjects *
-NSSCKFWFindObjects_GetMDFindObjects
-(
- NSSCKFWFindObjects *
-);
-
-/*
- * NSSCKFWMutex
- *
- * NSSCKFWMutex_Destroy
- * NSSCKFWMutex_Lock
- * NSSCKFWMutex_Unlock
- *
- */
-
-/*
- * NSSCKFWMutex_Destroy
- *
- */
-
-NSS_EXTERN CK_RV
-NSSCKFWMutex_Destroy
-(
- NSSCKFWMutex *mutex
-);
-
-/*
- * NSSCKFWMutex_Lock
- *
- */
-
-NSS_EXTERN CK_RV
-NSSCKFWMutex_Lock
-(
- NSSCKFWMutex *mutex
-);
-
-/*
- * NSSCKFWMutex_Unlock
- *
- */
-
-NSS_EXTERN CK_RV
-NSSCKFWMutex_Unlock
-(
- NSSCKFWMutex *mutex
-);
-
-#endif /* NSSCKFW_H */
-
diff --git a/security/nss/lib/ckfw/nssckfwc.h b/security/nss/lib/ckfw/nssckfwc.h
deleted file mode 100644
index c353fb267..000000000
--- a/security/nss/lib/ckfw/nssckfwc.h
+++ /dev/null
@@ -1,1017 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSCKFWC_H
-#define NSSCKFWC_H
-
-#ifdef DEBUG
-static const char NSSCKFWC_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssckfwc.h
- *
- * This file prototypes all of the NSS Cryptoki Framework "wrapper"
- * which implement the PKCS#11 API. Technically, these are public
- * routines (with capital "NSS" prefixes), since they are called
- * from (generated) code within a Module using the Framework.
- * However, they should not be called except from those generated
- * calls. Hence, the prototypes have been split out into this file.
- */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFWT_H
-#include "nssckfwt.h"
-#endif /* NSSCKFWT_H */
-
-#ifndef NSSCKMDT_H
-#include "nssckmdt.h"
-#endif /* NSSCKMDT_H */
-
-/*
- * NSSCKFWC_Initialize
- * NSSCKFWC_Finalize
- * NSSCKFWC_GetInfo
- * -- NSSCKFWC_GetFunctionList -- see the API insert file
- * NSSCKFWC_GetSlotList
- * NSSCKFWC_GetSlotInfo
- * NSSCKFWC_GetTokenInfo
- * NSSCKFWC_WaitForSlotEvent
- * NSSCKFWC_GetMechanismList
- * NSSCKFWC_GetMechanismInfo
- * NSSCKFWC_InitToken
- * NSSCKFWC_InitPIN
- * NSSCKFWC_SetPIN
- * NSSCKFWC_OpenSession
- * NSSCKFWC_CloseSession
- * NSSCKFWC_CloseAllSessions
- * NSSCKFWC_GetSessionInfo
- * NSSCKFWC_GetOperationState
- * NSSCKFWC_SetOperationState
- * NSSCKFWC_Login
- * NSSCKFWC_Logout
- * NSSCKFWC_CreateObject
- * NSSCKFWC_CopyObject
- * NSSCKFWC_DestroyObject
- * NSSCKFWC_GetObjectSize
- * NSSCKFWC_GetAttributeValue
- * NSSCKFWC_SetAttributeValue
- * NSSCKFWC_FindObjectsInit
- * NSSCKFWC_FindObjects
- * NSSCKFWC_FindObjectsFinal
- * NSSCKFWC_EncryptInit
- * NSSCKFWC_Encrypt
- * NSSCKFWC_EncryptUpdate
- * NSSCKFWC_EncryptFinal
- * NSSCKFWC_DecryptInit
- * NSSCKFWC_Decrypt
- * NSSCKFWC_DecryptUpdate
- * NSSCKFWC_DecryptFinal
- * NSSCKFWC_DigestInit
- * NSSCKFWC_Digest
- * NSSCKFWC_DigestUpdate
- * NSSCKFWC_DigestKey
- * NSSCKFWC_DigestFinal
- * NSSCKFWC_SignInit
- * NSSCKFWC_Sign
- * NSSCKFWC_SignUpdate
- * NSSCKFWC_SignFinal
- * NSSCKFWC_SignRecoverInit
- * NSSCKFWC_SignRecover
- * NSSCKFWC_VerifyInit
- * NSSCKFWC_Verify
- * NSSCKFWC_VerifyUpdate
- * NSSCKFWC_VerifyFinal
- * NSSCKFWC_VerifyRecoverInit
- * NSSCKFWC_VerifyRecover
- * NSSCKFWC_DigestEncryptUpdate
- * NSSCKFWC_DecryptDigestUpdate
- * NSSCKFWC_SignEncryptUpdate
- * NSSCKFWC_DecryptVerifyUpdate
- * NSSCKFWC_GenerateKey
- * NSSCKFWC_GenerateKeyPair
- * NSSCKFWC_WrapKey
- * NSSCKFWC_UnwrapKey
- * NSSCKFWC_DeriveKey
- * NSSCKFWC_SeedRandom
- * NSSCKFWC_GenerateRandom
- * NSSCKFWC_GetFunctionStatus
- * NSSCKFWC_CancelFunction
- */
-
-/*
- * NSSCKFWC_Initialize
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_Initialize
-(
- NSSCKFWInstance **pFwInstance,
- NSSCKMDInstance *mdInstance,
- CK_VOID_PTR pInitArgs
-);
-
-/*
- * NSSCKFWC_Finalize
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_Finalize
-(
- NSSCKFWInstance **pFwInstance
-);
-
-/*
- * NSSCKFWC_GetInfo
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_INFO_PTR pInfo
-);
-
-/*
- * C_GetFunctionList is implemented entirely in the Module's file which
- * includes the Framework API insert file. It requires no "actual"
- * NSSCKFW routine.
- */
-
-/*
- * NSSCKFWC_GetSlotList
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetSlotList
-(
- NSSCKFWInstance *fwInstance,
- CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount
-);
-
-/*
- * NSSCKFWC_GetSlotInfo
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetSlotInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_SLOT_INFO_PTR pInfo
-);
-
-/*
- * NSSCKFWC_GetTokenInfo
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetTokenInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_TOKEN_INFO_PTR pInfo
-);
-
-/*
- * NSSCKFWC_WaitForSlotEvent
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_WaitForSlotEvent
-(
- NSSCKFWInstance *fwInstance,
- CK_FLAGS flags,
- CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pReserved
-);
-
-/*
- * NSSCKFWC_GetMechanismList
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetMechanismList
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount
-);
-
-/*
- * NSSCKFWC_GetMechanismInfo
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetMechanismInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo
-);
-
-/*
- * NSSCKFWC_InitToken
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_InitToken
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,
- CK_CHAR_PTR pLabel
-);
-
-/*
- * NSSCKFWC_InitPIN
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_InitPIN
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-);
-
-/*
- * NSSCKFWC_SetPIN
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SetPIN
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen,
- CK_CHAR_PTR pNewPin,
- CK_ULONG ulNewLen
-);
-
-/*
- * NSSCKFWC_OpenSession
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_OpenSession
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_FLAGS flags,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_SESSION_HANDLE_PTR phSession
-);
-
-/*
- * NSSCKFWC_CloseSession
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_CloseSession
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
-
-/*
- * NSSCKFWC_CloseAllSessions
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_CloseAllSessions
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID
-);
-
-/*
- * NSSCKFWC_GetSessionInfo
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetSessionInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo
-);
-
-/*
- * NSSCKFWC_GetOperationState
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetOperationState
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG_PTR pulOperationStateLen
-);
-
-/*
- * NSSCKFWC_SetOperationState
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SetOperationState
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey,
- CK_OBJECT_HANDLE hAuthenticationKey
-);
-
-/*
- * NSSCKFWC_Login
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_Login
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_USER_TYPE userType,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-);
-
-/*
- * NSSCKFWC_Logout
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_Logout
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
-
-/*
- * NSSCKFWC_CreateObject
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_CreateObject
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject
-);
-
-/*
- * NSSCKFWC_CopyObject
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_CopyObject
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject
-);
-
-/*
- * NSSCKFWC_DestroyObject
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DestroyObject
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject
-);
-
-/*
- * NSSCKFWC_GetObjectSize
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetObjectSize
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ULONG_PTR pulSize
-);
-
-/*
- * NSSCKFWC_GetAttributeValue
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetAttributeValue
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-);
-
-/*
- * NSSCKFWC_SetAttributeValue
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SetAttributeValue
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-);
-
-/*
- * NSSCKFWC_FindObjectsInit
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_FindObjectsInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-);
-
-/*
- * NSSCKFWC_FindObjects
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_FindObjects
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,
- CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount
-);
-
-/*
- * NSSCKFWC_FindObjectsFinal
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_FindObjectsFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
-
-/*
- * NSSCKFWC_EncryptInit
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_EncryptInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-/*
- * NSSCKFWC_Encrypt
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_Encrypt
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen
-);
-
-/*
- * NSSCKFWC_EncryptUpdate
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_EncryptUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-);
-
-/*
- * NSSCKFWC_EncryptFinal
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_EncryptFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart,
- CK_ULONG_PTR pulLastEncryptedPartLen
-);
-
-/*
- * NSSCKFWC_DecryptInit
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DecryptInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-/*
- * NSSCKFWC_Decrypt
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_Decrypt
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-);
-
-/*
- * NSSCKFWC_DecryptUpdate
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DecryptUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-);
-
-/*
- * NSSCKFWC_DecryptFinal
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DecryptFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart,
- CK_ULONG_PTR pulLastPartLen
-);
-
-/*
- * NSSCKFWC_DigestInit
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DigestInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism
-);
-
-/*
- * NSSCKFWC_Digest
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_Digest
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-);
-
-/*
- * NSSCKFWC_DigestUpdate
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DigestUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen
-);
-
-/*
- * NSSCKFWC_DigestKey
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DigestKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey
-);
-
-/*
- * NSSCKFWC_DigestFinal
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DigestFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-);
-
-/*
- * NSSCKFWC_SignInit
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SignInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-/*
- * NSSCKFWC_Sign
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_Sign
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-);
-
-/*
- * NSSCKFWC_SignUpdate
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SignUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-);
-
-/*
- * NSSCKFWC_SignFinal
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SignFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-);
-
-/*
- * NSSCKFWC_SignRecoverInit
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SignRecoverInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-/*
- * NSSCKFWC_SignRecover
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SignRecover
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-);
-
-/*
- * NSSCKFWC_VerifyInit
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_VerifyInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-/*
- * NSSCKFWC_Verify
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_Verify
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-);
-
-/*
- * NSSCKFWC_VerifyUpdate
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_VerifyUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-);
-
-/*
- * NSSCKFWC_VerifyFinal
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_VerifyFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-);
-
-/*
- * NSSCKFWC_VerifyRecoverInit
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_VerifyRecoverInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-);
-
-/*
- * NSSCKFWC_VerifyRecover
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_VerifyRecover
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-);
-
-/*
- * NSSCKFWC_DigestEncryptUpdate
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DigestEncryptUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-);
-
-/*
- * NSSCKFWC_DecryptDigestUpdate
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DecryptDigestUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-);
-
-/*
- * NSSCKFWC_SignEncryptUpdate
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SignEncryptUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-);
-
-/*
- * NSSCKFWC_DecryptVerifyUpdate
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DecryptVerifyUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-);
-
-/*
- * NSSCKFWC_GenerateKey
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GenerateKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey
-);
-
-/*
- * NSSCKFWC_GenerateKeyPair
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GenerateKeyPair
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey
-);
-
-/*
- * NSSCKFWC_WrapKey
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_WrapKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen
-);
-
-/*
- * NSSCKFWC_UnwrapKey
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_UnwrapKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-);
-
-/*
- * NSSCKFWC_DeriveKey
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_DeriveKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-);
-
-/*
- * NSSCKFWC_SeedRandom
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_SeedRandom
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen
-);
-
-/*
- * NSSCKFWC_GenerateRandom
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GenerateRandom
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData,
- CK_ULONG ulRandomLen
-);
-
-/*
- * NSSCKFWC_GetFunctionStatus
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_GetFunctionStatus
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
-
-/*
- * NSSCKFWC_CancelFunction
- *
- */
-NSS_EXTERN CK_RV
-NSSCKFWC_CancelFunction
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-);
-
-#endif /* NSSCKFWC_H */
diff --git a/security/nss/lib/ckfw/nssckfwt.h b/security/nss/lib/ckfw/nssckfwt.h
deleted file mode 100644
index 3a7092414..000000000
--- a/security/nss/lib/ckfw/nssckfwt.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSCKFWT_H
-#define NSSCKFWT_H
-
-#ifdef DEBUG
-static const char NSSCKFWT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssckfwt.h
- *
- * This file declares the public types used by the NSS Cryptoki Framework.
- */
-
-/*
- * NSSCKFWInstance
- *
- */
-
-struct NSSCKFWInstanceStr;
-typedef struct NSSCKFWInstanceStr NSSCKFWInstance;
-
-/*
- * NSSCKFWSlot
- *
- */
-
-struct NSSCKFWSlotStr;
-typedef struct NSSCKFWSlotStr NSSCKFWSlot;
-
-/*
- * NSSCKFWToken
- *
- */
-
-struct NSSCKFWTokenStr;
-typedef struct NSSCKFWTokenStr NSSCKFWToken;
-
-/*
- * NSSCKFWMechanism
- *
- */
-
-struct NSSCKFWMechanismStr;
-typedef struct NSSCKFWMechanismStr NSSCKFWMechanism;
-
-/*
- * NSSCKFWCryptoOperation
- *
- */
-
-struct NSSCKFWCryptoOperationStr;
-typedef struct NSSCKFWCryptoOperationStr NSSCKFWCryptoOperation;
-
-
-/*
- * NSSCKFWSession
- *
- */
-
-struct NSSCKFWSessionStr;
-typedef struct NSSCKFWSessionStr NSSCKFWSession;
-
-/*
- * NSSCKFWObject
- *
- */
-
-struct NSSCKFWObjectStr;
-typedef struct NSSCKFWObjectStr NSSCKFWObject;
-
-/*
- * NSSCKFWFindObjects
- *
- */
-
-struct NSSCKFWFindObjectsStr;
-typedef struct NSSCKFWFindObjectsStr NSSCKFWFindObjects;
-
-/*
- * NSSCKFWMutex
- *
- */
-
-struct NSSCKFWMutexStr;
-typedef struct NSSCKFWMutexStr NSSCKFWMutex;
-
-typedef enum {
- SingleThreaded,
- MultiThreaded
-} CryptokiLockingState ;
-
-/* used as an index into an array, make sure it starts at '0' */
-typedef enum {
- NSSCKFWCryptoOperationState_EncryptDecrypt = 0,
- NSSCKFWCryptoOperationState_SignVerify,
- NSSCKFWCryptoOperationState_Digest,
- NSSCKFWCryptoOperationState_Max
-} NSSCKFWCryptoOperationState;
-
-typedef enum {
- NSSCKFWCryptoOperationType_Encrypt,
- NSSCKFWCryptoOperationType_Decrypt,
- NSSCKFWCryptoOperationType_Digest,
- NSSCKFWCryptoOperationType_Sign,
- NSSCKFWCryptoOperationType_Verify,
- NSSCKFWCryptoOperationType_SignRecover,
- NSSCKFWCryptoOperationType_VerifyRecover
-} NSSCKFWCryptoOperationType;
-
-#endif /* NSSCKFWT_H */
diff --git a/security/nss/lib/ckfw/nssckg.h b/security/nss/lib/ckfw/nssckg.h
deleted file mode 100644
index bf0d43fb0..000000000
--- a/security/nss/lib/ckfw/nssckg.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* THIS IS A GENERATED FILE */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef NSSCKG_H
-#define NSSCKG_H
-
-#include "pkcs11.h"
-
-#endif /* NSSCKG_H */
diff --git a/security/nss/lib/ckfw/nssckmdt.h b/security/nss/lib/ckfw/nssckmdt.h
deleted file mode 100644
index 4bbc4a84b..000000000
--- a/security/nss/lib/ckfw/nssckmdt.h
+++ /dev/null
@@ -1,1949 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSCKMDT_H
-#define NSSCKMDT_H
-
-#ifdef DEBUG
-static const char NSSCKMDT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssckmdt.h
- *
- * This file specifies the basic types that must be implemented by
- * any Module using the NSS Cryptoki Framework.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#ifndef NSSCKFWT_H
-#include "nssckfwt.h"
-#endif /* NSSCKFWT_H */
-
-typedef struct NSSCKMDInstanceStr NSSCKMDInstance;
-typedef struct NSSCKMDSlotStr NSSCKMDSlot;
-typedef struct NSSCKMDTokenStr NSSCKMDToken;
-typedef struct NSSCKMDSessionStr NSSCKMDSession;
-typedef struct NSSCKMDCryptoOperationStr NSSCKMDCryptoOperation;
-typedef struct NSSCKMDFindObjectsStr NSSCKMDFindObjects;
-typedef struct NSSCKMDMechanismStr NSSCKMDMechanism;
-typedef struct NSSCKMDObjectStr NSSCKMDObject;
-
-/*
- * NSSCKFWItem
- *
- * This is a structure used by modules to return object attributes.
- * The needsFreeing bit indicates whether the object needs to be freed.
- * If so, the framework will call the FreeAttribute function on the item
- * after it is done using it.
- *
- */
-
-typedef struct {
- PRBool needsFreeing;
- NSSItem* item;
-} NSSCKFWItem ;
-
-/*
- * NSSCKMDInstance
- *
- * This is the basic handle for an instance of a PKCS#11 Module.
- * It is returned by the Module's CreateInstance routine, and
- * may be obtained from the corresponding NSSCKFWInstance object.
- * It contains a pointer for use by the Module, to store any
- * instance-related data, and it contains the EPV for a set of
- * routines which the Module may implement for use by the Framework.
- * Some of these routines are optional; others are mandatory.
- */
-
-struct NSSCKMDInstanceStr {
- /*
- * The Module may use this pointer for its own purposes.
- */
- void *etc;
-
- /*
- * This routine is called by the Framework to initialize
- * the Module. This routine is optional; if unimplemented,
- * it won't be called. If this routine returns an error,
- * then the initialization will fail.
- */
- CK_RV (PR_CALLBACK *Initialize)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSUTF8 *configurationData
- );
-
- /*
- * This routine is called when the Framework is finalizing
- * the PKCS#11 Module. It is the last thing called before
- * the NSSCKFWInstance's NSSArena is destroyed. This routine
- * is optional; if unimplemented, it merely won't be called.
- */
- void (PR_CALLBACK *Finalize)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine gets the number of slots. This value must
- * never change, once the instance is initialized. This
- * routine must be implemented. It may return zero on error.
- */
- CK_ULONG (PR_CALLBACK *GetNSlots)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns the version of the Cryptoki standard
- * to which this Module conforms. This routine is optional;
- * if unimplemented, the Framework uses the version to which
- * ~it~ was implemented.
- */
- CK_VERSION (PR_CALLBACK *GetCryptokiVersion)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns a pointer to a UTF8-encoded string
- * containing the manufacturer ID for this Module. Only
- * the characters completely encoded in the first thirty-
- * two bytes are significant. This routine is optional.
- * The string returned is never freed; if dynamically generated,
- * the space for it should be allocated from the NSSArena
- * that may be obtained from the NSSCKFWInstance. This
- * routine may return NULL upon error; however if *pError
- * is CKR_OK, the NULL will be considered the valid response.
- */
- NSSUTF8 *(PR_CALLBACK *GetManufacturerID)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns a pointer to a UTF8-encoded string
- * containing a description of this Module library. Only
- * the characters completely encoded in the first thirty-
- * two bytes are significant. This routine is optional.
- * The string returned is never freed; if dynamically generated,
- * the space for it should be allocated from the NSSArena
- * that may be obtained from the NSSCKFWInstance. This
- * routine may return NULL upon error; however if *pError
- * is CKR_OK, the NULL will be considered the valid response.
- */
- NSSUTF8 *(PR_CALLBACK *GetLibraryDescription)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns the version of this Module library.
- * This routine is optional; if unimplemented, the Framework
- * will assume a Module library version of 0.1.
- */
- CK_VERSION (PR_CALLBACK *GetLibraryVersion)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if the Module wishes to
- * handle session objects. This routine is optional.
- * If this routine is NULL, or if it exists but returns
- * CK_FALSE, the Framework will assume responsibility
- * for managing session objects.
- */
- CK_BBOOL (PR_CALLBACK *ModuleHandlesSessionObjects)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine stuffs pointers to NSSCKMDSlot objects into
- * the specified array; one for each slot supported by this
- * instance. The Framework will determine the size needed
- * for the array by calling GetNSlots. This routine is
- * required.
- */
- CK_RV (PR_CALLBACK *GetSlots)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[]
- );
-
- /*
- * This call returns a pointer to the slot in which an event
- * has occurred. If the block argument is CK_TRUE, the call
- * should block until a slot event occurs; if CK_FALSE, it
- * should check to see if an event has occurred, occurred,
- * but return NULL (and set *pError to CK_NO_EVENT) if one
- * hasn't. This routine is optional; if unimplemented, the
- * Framework will assume that no event has happened. This
- * routine may return NULL upon error.
- */
- NSSCKMDSlot *(PR_CALLBACK *WaitForSlotEvent)(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_BBOOL block,
- CK_RV *pError
- );
-
- /*
- * This object may be extended in future versions of the
- * NSS Cryptoki Framework. To allow for some flexibility
- * in the area of binary compatibility, this field should
- * be NULL.
- */
- void *null;
-};
-
-
-/*
- * NSSCKMDSlot
- *
- * This is the basic handle for a PKCS#11 Module Slot. It is
- * created by the NSSCKMDInstance->GetSlots call, and may be
- * obtained from the Framework's corresponding NSSCKFWSlot
- * object. It contains a pointer for use by the Module, to
- * store any slot-related data, and it contains the EPV for
- * a set of routines which the Module may implement for use
- * by the Framework. Some of these routines are optional.
- */
-
-struct NSSCKMDSlotStr {
- /*
- * The Module may use this pointer for its own purposes.
- */
- void *etc;
-
- /*
- * This routine is called during the Framework initialization
- * step, after the Framework Instance has obtained the list
- * of slots (by calling NSSCKMDInstance->GetSlots). Any slot-
- * specific initialization can be done here. This routine is
- * optional; if unimplemented, it won't be called. Note that
- * if this routine returns an error, the entire Framework
- * initialization for this Module will fail.
- */
- CK_RV (PR_CALLBACK *Initialize)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine is called when the Framework is finalizing
- * the PKCS#11 Module. This call (for each of the slots)
- * is the last thing called before NSSCKMDInstance->Finalize.
- * This routine is optional; if unimplemented, it merely
- * won't be called. Note: In the rare circumstance that
- * the Framework initialization cannot complete (due to,
- * for example, memory limitations), this can be called with
- * a NULL value for fwSlot.
- */
- void (PR_CALLBACK *Destroy)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns a pointer to a UTF8-encoded string
- * containing a description of this slot. Only the characters
- * completely encoded in the first sixty-four bytes are
- * significant. This routine is optional. The string
- * returned is never freed; if dynamically generated,
- * the space for it should be allocated from the NSSArena
- * that may be obtained from the NSSCKFWInstance. This
- * routine may return NULL upon error; however if *pError
- * is CKR_OK, the NULL will be considered the valid response.
- */
- NSSUTF8 *(PR_CALLBACK *GetSlotDescription)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns a pointer to a UTF8-encoded string
- * containing a description of the manufacturer of this slot.
- * Only the characters completely encoded in the first thirty-
- * two bytes are significant. This routine is optional.
- * The string returned is never freed; if dynamically generated,
- * the space for it should be allocated from the NSSArena
- * that may be obtained from the NSSCKFWInstance. This
- * routine may return NULL upon error; however if *pError
- * is CKR_OK, the NULL will be considered the valid response.
- */
- NSSUTF8 *(PR_CALLBACK *GetManufacturerID)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns CK_TRUE if a token is present in this
- * slot. This routine is optional; if unimplemented, CK_TRUE
- * is assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetTokenPresent)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if the slot supports removable
- * tokens. This routine is optional; if unimplemented, CK_FALSE
- * is assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetRemovableDevice)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if this slot is a hardware
- * device, or CK_FALSE if this slot is a software device. This
- * routine is optional; if unimplemented, CK_FALSE is assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetHardwareSlot)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the version of this slot's hardware.
- * This routine is optional; if unimplemented, the Framework
- * will assume a hardware version of 0.1.
- */
- CK_VERSION (PR_CALLBACK *GetHardwareVersion)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the version of this slot's firmware.
- * This routine is optional; if unimplemented, the Framework
- * will assume a hardware version of 0.1.
- */
- CK_VERSION (PR_CALLBACK *GetFirmwareVersion)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine should return a pointer to an NSSCKMDToken
- * object corresponding to the token in the specified slot.
- * The NSSCKFWToken object passed in has an NSSArena
- * available which is dedicated for this token. This routine
- * must be implemented. This routine may return NULL upon
- * error.
- */
- NSSCKMDToken *(PR_CALLBACK *GetToken)(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This object may be extended in future versions of the
- * NSS Cryptoki Framework. To allow for some flexibility
- * in the area of binary compatibility, this field should
- * be NULL.
- */
- void *null;
-};
-
-/*
- * NSSCKMDToken
- *
- * This is the basic handle for a PKCS#11 Token. It is created by
- * the NSSCKMDSlot->GetToken call, and may be obtained from the
- * Framework's corresponding NSSCKFWToken object. It contains a
- * pointer for use by the Module, to store any token-related
- * data, and it contains the EPV for a set of routines which the
- * Module may implement for use by the Framework. Some of these
- * routines are optional.
- */
-
-struct NSSCKMDTokenStr {
- /*
- * The Module may use this pointer for its own purposes.
- */
- void *etc;
-
- /*
- * This routine is used to prepare a Module token object for
- * use. It is called after the NSSCKMDToken object is obtained
- * from NSSCKMDSlot->GetToken. It is named "Setup" here because
- * Cryptoki already defines "InitToken" to do the process of
- * wiping out any existing state on a token and preparing it for
- * a new use. This routine is optional; if unimplemented, it
- * merely won't be called.
- */
- CK_RV (PR_CALLBACK *Setup)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine is called by the Framework whenever it notices
- * that the token object is invalid. (Typically this is when a
- * routine indicates an error such as CKR_DEVICE_REMOVED). This
- * call is the last thing called before the NSSArena in the
- * corresponding NSSCKFWToken is destroyed. This routine is
- * optional; if unimplemented, it merely won't be called.
- */
- void (PR_CALLBACK *Invalidate)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine initialises the token in the specified slot.
- * This routine is optional; if unimplemented, the Framework
- * will fail this operation with an error of CKR_DEVICE_ERROR.
- */
-
- CK_RV (PR_CALLBACK *InitToken)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSItem *pin,
- NSSUTF8 *label
- );
-
- /*
- * This routine returns a pointer to a UTF8-encoded string
- * containing this token's label. Only the characters
- * completely encoded in the first thirty-two bytes are
- * significant. This routine is optional. The string
- * returned is never freed; if dynamically generated,
- * the space for it should be allocated from the NSSArena
- * that may be obtained from the NSSCKFWInstance. This
- * routine may return NULL upon error; however if *pError
- * is CKR_OK, the NULL will be considered the valid response.
- */
- NSSUTF8 *(PR_CALLBACK *GetLabel)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns a pointer to a UTF8-encoded string
- * containing this token's manufacturer ID. Only the characters
- * completely encoded in the first thirty-two bytes are
- * significant. This routine is optional. The string
- * returned is never freed; if dynamically generated,
- * the space for it should be allocated from the NSSArena
- * that may be obtained from the NSSCKFWInstance. This
- * routine may return NULL upon error; however if *pError
- * is CKR_OK, the NULL will be considered the valid response.
- */
- NSSUTF8 *(PR_CALLBACK *GetManufacturerID)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns a pointer to a UTF8-encoded string
- * containing this token's model name. Only the characters
- * completely encoded in the first thirty-two bytes are
- * significant. This routine is optional. The string
- * returned is never freed; if dynamically generated,
- * the space for it should be allocated from the NSSArena
- * that may be obtained from the NSSCKFWInstance. This
- * routine may return NULL upon error; however if *pError
- * is CKR_OK, the NULL will be considered the valid response.
- */
- NSSUTF8 *(PR_CALLBACK *GetModel)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns a pointer to a UTF8-encoded string
- * containing this token's serial number. Only the characters
- * completely encoded in the first thirty-two bytes are
- * significant. This routine is optional. The string
- * returned is never freed; if dynamically generated,
- * the space for it should be allocated from the NSSArena
- * that may be obtained from the NSSCKFWInstance. This
- * routine may return NULL upon error; however if *pError
- * is CKR_OK, the NULL will be considered the valid response.
- */
- NSSUTF8 *(PR_CALLBACK *GetSerialNumber)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns CK_TRUE if the token has its own
- * random number generator. This routine is optional; if
- * unimplemented, CK_FALSE is assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetHasRNG)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if this token is write-protected.
- * This routine is optional; if unimplemented, CK_FALSE is
- * assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetIsWriteProtected)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if this token requires a login.
- * This routine is optional; if unimplemented, CK_FALSE is
- * assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetLoginRequired)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if the normal user's PIN on this
- * token has been initialised. This routine is optional; if
- * unimplemented, CK_FALSE is assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetUserPinInitialized)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if a successful save of a
- * session's cryptographic operations state ~always~ contains
- * all keys needed to restore the state of the session. This
- * routine is optional; if unimplemented, CK_FALSE is assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetRestoreKeyNotNeeded)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if the token has its own
- * hardware clock. This routine is optional; if unimplemented,
- * CK_FALSE is assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetHasClockOnToken)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if the token has a protected
- * authentication path. This routine is optional; if
- * unimplemented, CK_FALSE is assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetHasProtectedAuthenticationPath)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns CK_TRUE if the token supports dual
- * cryptographic operations within a single session. This
- * routine is optional; if unimplemented, CK_FALSE is assumed.
- */
- CK_BBOOL (PR_CALLBACK *GetSupportsDualCryptoOperations)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * XXX fgmr-- should we have a call to return all the flags
- * at once, for folks who already know about Cryptoki?
- */
-
- /*
- * This routine returns the maximum number of sessions that
- * may be opened on this token. This routine is optional;
- * if unimplemented, the special value CK_UNAVAILABLE_INFORMATION
- * is assumed. XXX fgmr-- or CK_EFFECTIVELY_INFINITE?
- */
- CK_ULONG (PR_CALLBACK *GetMaxSessionCount)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the maximum number of read/write
- * sesisons that may be opened on this token. This routine
- * is optional; if unimplemented, the special value
- * CK_UNAVAILABLE_INFORMATION is assumed. XXX fgmr-- or
- * CK_EFFECTIVELY_INFINITE?
- */
- CK_ULONG (PR_CALLBACK *GetMaxRwSessionCount)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the maximum PIN code length that is
- * supported on this token. This routine is optional;
- * if unimplemented, the special value CK_UNAVAILABLE_INFORMATION
- * is assumed.
- */
- CK_ULONG (PR_CALLBACK *GetMaxPinLen)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the minimum PIN code length that is
- * supported on this token. This routine is optional; if
- * unimplemented, the special value CK_UNAVAILABLE_INFORMATION
- * is assumed. XXX fgmr-- or 0?
- */
- CK_ULONG (PR_CALLBACK *GetMinPinLen)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the total amount of memory on the token
- * in which public objects may be stored. This routine is
- * optional; if unimplemented, the special value
- * CK_UNAVAILABLE_INFORMATION is assumed.
- */
- CK_ULONG (PR_CALLBACK *GetTotalPublicMemory)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the amount of unused memory on the
- * token in which public objects may be stored. This routine
- * is optional; if unimplemented, the special value
- * CK_UNAVAILABLE_INFORMATION is assumed.
- */
- CK_ULONG (PR_CALLBACK *GetFreePublicMemory)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the total amount of memory on the token
- * in which private objects may be stored. This routine is
- * optional; if unimplemented, the special value
- * CK_UNAVAILABLE_INFORMATION is assumed.
- */
- CK_ULONG (PR_CALLBACK *GetTotalPrivateMemory)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the amount of unused memory on the
- * token in which private objects may be stored. This routine
- * is optional; if unimplemented, the special value
- * CK_UNAVAILABLE_INFORMATION is assumed.
- */
- CK_ULONG (PR_CALLBACK *GetFreePrivateMemory)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the version number of this token's
- * hardware. This routine is optional; if unimplemented,
- * the value 0.1 is assumed.
- */
- CK_VERSION (PR_CALLBACK *GetHardwareVersion)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the version number of this token's
- * firmware. This routine is optional; if unimplemented,
- * the value 0.1 is assumed.
- */
- CK_VERSION (PR_CALLBACK *GetFirmwareVersion)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine stuffs the current UTC time, as obtained from
- * the token, into the sixteen-byte buffer in the form
- * YYYYMMDDhhmmss00. This routine need only be implemented
- * by token which indicate that they have a real-time clock.
- * XXX fgmr-- think about time formats.
- */
- CK_RV (PR_CALLBACK *GetUTCTime)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_CHAR utcTime[16]
- );
-
- /*
- * This routine creates a session on the token, and returns
- * the corresponding NSSCKMDSession object. The value of
- * rw will be CK_TRUE if the session is to be a read/write
- * session, or CK_FALSE otherwise. An NSSArena dedicated to
- * the new session is available from the specified NSSCKFWSession.
- * This routine may return NULL upon error.
- */
- NSSCKMDSession *(PR_CALLBACK *OpenSession)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_BBOOL rw,
- CK_RV *pError
- );
-
- /*
- * This routine returns the number of PKCS#11 Mechanisms
- * supported by this token. This routine is optional; if
- * unimplemented, zero is assumed.
- */
- CK_ULONG (PR_CALLBACK *GetMechanismCount)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine stuffs into the specified array the types
- * of the mechanisms supported by this token. The Framework
- * determines the size of the array by calling GetMechanismCount.
- */
- CK_RV (PR_CALLBACK *GetMechanismTypes)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE types[]
- );
-
- /*
- * This routine returns a pointer to a Module mechanism
- * object corresponding to a specified type. This routine
- * need only exist for tokens implementing at least one
- * mechanism.
- */
- NSSCKMDMechanism *(PR_CALLBACK *GetMechanism)(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE which,
- CK_RV *pError
- );
-
- /*
- * This object may be extended in future versions of the
- * NSS Cryptoki Framework. To allow for some flexibility
- * in the area of binary compatibility, this field should
- * be NULL.
- */
- void *null;
-};
-
-/*
- * NSSCKMDSession
- *
- * This is the basic handle for a session on a PKCS#11 Token. It
- * is created by NSSCKMDToken->OpenSession, and may be obtained
- * from the Framework's corresponding NSSCKFWSession object. It
- * contains a pointer for use by the Module, to store any session-
- * realted data, and it contains the EPV for a set of routines
- * which the Module may implement for use by the Framework. Some
- * of these routines are optional.
- */
-
-struct NSSCKMDSessionStr {
- /*
- * The Module may use this pointer for its own purposes.
- */
- void *etc;
-
- /*
- * This routine is called by the Framework when a session is
- * closed. This call is the last thing called before the
- * NSSArena in the correspoinding NSSCKFWSession is destroyed.
- * This routine is optional; if unimplemented, it merely won't
- * be called.
- */
- void (PR_CALLBACK *Close)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine is used to get any device-specific error.
- * This routine is optional.
- */
- CK_ULONG (PR_CALLBACK *GetDeviceError)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine is used to log in a user to the token. This
- * routine is optional, since the Framework's NSSCKFWSession
- * object keeps track of the login state.
- */
- CK_RV (PR_CALLBACK *Login)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_USER_TYPE userType,
- NSSItem *pin,
- CK_STATE oldState,
- CK_STATE newState
- );
-
- /*
- * This routine is used to log out a user from the token. This
- * routine is optional, since the Framework's NSSCKFWSession
- * object keeps track of the login state.
- */
- CK_RV (PR_CALLBACK *Logout)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_STATE oldState,
- CK_STATE newState
- );
-
- /*
- * This routine is used to initialize the normal user's PIN or
- * password. This will only be called in the "read/write
- * security officer functions" state. If this token has a
- * protected authentication path, then the pin argument will
- * be NULL. This routine is optional; if unimplemented, the
- * Framework will return the error CKR_TOKEN_WRITE_PROTECTED.
- */
- CK_RV (PR_CALLBACK *InitPIN)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSItem *pin
- );
-
- /*
- * This routine is used to modify a user's PIN or password. This
- * routine will only be called in the "read/write security officer
- * functions" or "read/write user functions" state. If this token
- * has a protected authentication path, then the pin arguments
- * will be NULL. This routine is optional; if unimplemented, the
- * Framework will return the error CKR_TOKEN_WRITE_PROTECTED.
- */
- CK_RV (PR_CALLBACK *SetPIN)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSItem *oldPin,
- NSSItem *newPin
- );
-
- /*
- * This routine is used to find out how much space would be required
- * to save the current operational state. This routine is optional;
- * if unimplemented, the Framework will reject any attempts to save
- * the operational state with the error CKR_STATE_UNSAVEABLE. This
- * routine may return zero on error.
- */
- CK_ULONG (PR_CALLBACK *GetOperationStateLen)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine is used to store the current operational state. This
- * routine is only required if GetOperationStateLen is implemented
- * and can return a nonzero value. The buffer in the specified item
- * will be pre-allocated, and the length will specify the amount of
- * space available (which may be more than GetOperationStateLen
- * asked for, but which will not be smaller).
- */
- CK_RV (PR_CALLBACK *GetOperationState)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSItem *buffer
- );
-
- /*
- * This routine is used to restore an operational state previously
- * obtained with GetOperationState. The Framework will take pains
- * to be sure that the state is (or was at one point) valid; if the
- * Module notices that the state is invalid, it should return an
- * error, but it is not required to be paranoid about the issue.
- * [XXX fgmr-- should (can?) the framework verify the keys match up?]
- * This routine is required only if GetOperationState is implemented.
- */
- CK_RV (PR_CALLBACK *SetOperationState)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSItem *state,
- NSSCKMDObject *mdEncryptionKey,
- NSSCKFWObject *fwEncryptionKey,
- NSSCKMDObject *mdAuthenticationKey,
- NSSCKFWObject *fwAuthenticationKey
- );
-
- /*
- * This routine is used to create an object. The specified template
- * will only specify a session object if the Module has indicated
- * that it wishes to handle its own session objects. This routine
- * is optional; if unimplemented, the Framework will reject the
- * operation with the error CKR_TOKEN_WRITE_PROTECTED. Space for
- * token objects should come from the NSSArena available from the
- * NSSCKFWToken object; space for session objects (if supported)
- * should come from the NSSArena available from the NSSCKFWSession
- * object. The appropriate NSSArena pointer will, as a convenience,
- * be passed as the handyArenaPointer argument. This routine may
- * return NULL upon error.
- */
- NSSCKMDObject *(PR_CALLBACK *CreateObject)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *handyArenaPointer,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
- );
-
- /*
- * This routine is used to make a copy of an object. It is entirely
- * optional; if unimplemented, the Framework will try to use
- * CreateObject instead. If the Module has indicated that it does
- * not wish to handle session objects, then this routine will only
- * be called to copy a token object to another token object.
- * Otherwise, either the original object or the new may be of
- * either the token or session variety. As with CreateObject, the
- * handyArenaPointer will point to the appropriate arena for the
- * new object. This routine may return NULL upon error.
- */
- NSSCKMDObject *(PR_CALLBACK *CopyObject)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdOldObject,
- NSSCKFWObject *fwOldObject,
- NSSArena *handyArenaPointer,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
- );
-
- /*
- * This routine is used to begin an object search. This routine may
- * be unimplemented only if the Module does not handle session
- * objects, and if none of its tokens have token objects. The
- * NSSCKFWFindObjects pointer has an NSSArena that may be used for
- * storage for the life of this "find" operation. This routine may
- * return NULL upon error. If the Module can determine immediately
- * that the search will not find any matching objects, it may return
- * NULL, and specify CKR_OK as the error.
- */
- NSSCKMDFindObjects *(PR_CALLBACK *FindObjectsInit)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
- );
-
- /*
- * This routine seeds the random-number generator. It is
- * optional, even if GetRandom is implemented. If unimplemented,
- * the Framework will issue the error CKR_RANDOM_SEED_NOT_SUPPORTED.
- */
- CK_RV (PR_CALLBACK *SeedRandom)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSItem *seed
- );
-
- /*
- * This routine gets random data. It is optional. If unimplemented,
- * the Framework will issue the error CKR_RANDOM_NO_RNG.
- */
- CK_RV (PR_CALLBACK *GetRandom)(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSItem *buffer
- );
-
- /*
- * This object may be extended in future versions of the
- * NSS Cryptoki Framework. To allow for some flexibility
- * in the area of binary compatibility, this field should
- * be NULL.
- */
- void *null;
-};
-
-/*
- * NSSCKMDFindObjects
- *
- * This is the basic handle for an object search. It is
- * created by NSSCKMDSession->FindObjectsInit, and may be
- * obtained from the Framework's corresponding object.
- * It contains a pointer for use by the Module, to store
- * any search-related data, and it contains the EPV for a
- * set of routines which the Module may implement for use
- * by the Framework. Some of these routines are optional.
- */
-
-struct NSSCKMDFindObjectsStr {
- /*
- * The Module may use this pointer for its own purposes.
- */
- void *etc;
-
- /*
- * This routine is called by the Framework to finish a
- * search operation. Note that the Framework may finish
- * a search before it has completed. This routine is
- * optional; if unimplemented, it merely won't be called.
- */
- void (PR_CALLBACK *Final)(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine is used to obtain another pointer to an
- * object matching the search criteria. This routine is
- * required. If no (more) objects match the search, it
- * should return NULL and set the error to CKR_OK.
- */
- NSSCKMDObject *(PR_CALLBACK *Next)(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
- );
-
- /*
- * This object may be extended in future versions of the
- * NSS Cryptoki Framework. To allow for some flexibility
- * in the area of binary compatibility, this field should
- * be NULL.
- */
- void *null;
-};
-
-/*
- * NSSCKMDCryptoOperaion
- *
- * This is the basic handle for an encryption, decryption,
- * sign, verify, or hash opertion.
- * created by NSSCKMDMechanism->XXXXInit, and may be
- * obtained from the Framework's corresponding object.
- * It contains a pointer for use by the Module, to store
- * any intermediate data, and it contains the EPV for a
- * set of routines which the Module may implement for use
- * by the Framework. Some of these routines are optional.
- */
-
-struct NSSCKMDCryptoOperationStr {
- /*
- * The Module may use this pointer for its own purposes.
- */
- void *etc;
-
- /*
- * This routine is called by the Framework clean up the mdCryptoOperation
- * structure.
- * This routine is optional; if unimplemented, it will be ignored.
- */
- void (PR_CALLBACK *Destroy)(
- NSSCKMDCryptoOperation *mdCryptoOperation,
- NSSCKFWCryptoOperation *fwCryptoOperation,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
-
- /*
- * how many bytes do we need to finish this buffer?
- * must be implemented if Final is implemented.
- */
- CK_ULONG (PR_CALLBACK *GetFinalLength)(
- NSSCKMDCryptoOperation *mdCryptoOperation,
- NSSCKFWCryptoOperation *fwCryptoOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * how many bytes do we need to complete the next operation.
- * used in both Update and UpdateFinal.
- */
- CK_ULONG (PR_CALLBACK *GetOperationLength)(
- NSSCKMDCryptoOperation *mdCryptoOperation,
- NSSCKFWCryptoOperation *fwCryptoOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *inputBuffer,
- CK_RV *pError
- );
-
- /*
- * This routine is called by the Framework to finish a
- * search operation. Note that the Framework may finish
- * a search before it has completed. This routine is
- * optional; if unimplemented, it merely won't be called.
- * The respective final call with fail with CKR_FUNCTION_FAILED
- * Final should not free the mdCryptoOperation.
- */
- CK_RV(PR_CALLBACK *Final)(
- NSSCKMDCryptoOperation *mdCryptoOperation,
- NSSCKFWCryptoOperation *fwCryptoOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSItem *outputBuffer
- );
-
-
- /*
- * This routine is called by the Framework to complete the
- * next step in an encryption/decryption operation.
- * This routine is optional; if unimplemented, the respective
- * update call with fail with CKR_FUNCTION_FAILED.
- * Update should not be implemented for signing/verification/digest
- * mechanisms.
- */
- CK_RV(PR_CALLBACK *Update)(
- NSSCKMDCryptoOperation *mdCryptoOperation,
- NSSCKFWCryptoOperation *fwCryptoOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *inputBuffer,
- NSSItem *outputBuffer
- );
-
- /*
- * This routine is called by the Framework to complete the
- * next step in a signing/verification/digest operation.
- * This routine is optional; if unimplemented, the respective
- * update call with fail with CKR_FUNCTION_FAILED
- * Update should not be implemented for encryption/decryption
- * mechanisms.
- */
- CK_RV(PR_CALLBACK *DigestUpdate)(
- NSSCKMDCryptoOperation *mdCryptoOperation,
- NSSCKFWCryptoOperation *fwCryptoOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *inputBuffer
- );
-
- /*
- * This routine is called by the Framework to complete a
- * single step operation. This routine is optional; if unimplemented,
- * the framework will use the Update and Final functions to complete
- * the operation.
- */
- CK_RV(PR_CALLBACK *UpdateFinal)(
- NSSCKMDCryptoOperation *mdCryptoOperation,
- NSSCKFWCryptoOperation *fwCryptoOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *inputBuffer,
- NSSItem *outputBuffer
- );
-
- /*
- * This routine is called by the Framework to complete next
- * step in a combined operation. The Decrypt/Encrypt mechanism
- * should define and drive the combo step.
- * This routine is optional; if unimplemented,
- * the framework will use the appropriate Update functions to complete
- * the operation.
- */
- CK_RV(PR_CALLBACK *UpdateCombo)(
- NSSCKMDCryptoOperation *mdCryptoOperation,
- NSSCKFWCryptoOperation *fwCryptoOperation,
- NSSCKMDCryptoOperation *mdPeerCryptoOperation,
- NSSCKFWCryptoOperation *fwPeerCryptoOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *inputBuffer,
- NSSItem *outputBuffer
- );
-
- /*
- * Hash a key directly into the digest
- */
- CK_RV(PR_CALLBACK *DigestKey)(
- NSSCKMDCryptoOperation *mdCryptoOperation,
- NSSCKFWCryptoOperation *fwCryptoOperation,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey
- );
-
- /*
- * This object may be extended in future versions of the
- * NSS Cryptoki Framework. To allow for some flexibility
- * in the area of binary compatibility, this field should
- * be NULL.
- */
- void *null;
-};
-
-/*
- * NSSCKMDMechanism
- *
- */
-
-struct NSSCKMDMechanismStr {
- /*
- * The Module may use this pointer for its own purposes.
- */
- void *etc;
-
- /*
- * This also frees the fwMechanism if appropriate.
- * If it is not supplied, the Framework will assume that the Token
- * Manages a static list of mechanisms and the function will not be called.
- */
- void (PR_CALLBACK *Destroy)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
-
- /*
- * This routine returns the minimum key size allowed for
- * this mechanism. This routine is optional; if unimplemented,
- * zero will be assumed. This routine may return zero on
- * error; if the error is CKR_OK, zero will be accepted as
- * a valid response.
- */
- CK_ULONG (PR_CALLBACK *GetMinKeySize)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine returns the maximum key size allowed for
- * this mechanism. This routine is optional; if unimplemented,
- * zero will be assumed. This routine may return zero on
- * error; if the error is CKR_OK, zero will be accepted as
- * a valid response.
- */
- CK_ULONG (PR_CALLBACK *GetMaxKeySize)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine is called to determine if the mechanism is
- * implemented in hardware or software. It returns CK_TRUE
- * if it is done in hardware.
- */
- CK_BBOOL (PR_CALLBACK *GetInHardware)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * The crypto routines themselves. Most crypto operations may
- * be performed in two ways, streaming and single-part. The
- * streaming operations involve the use of (typically) three
- * calls-- an Init method to set up the operation, an Update
- * method to feed data to the operation, and a Final method to
- * obtain the final result. Single-part operations involve
- * one method, to perform the crypto operation all at once.
- *
- * The NSS Cryptoki Framework can implement the single-part
- * operations in terms of the streaming operations on behalf
- * of the Module. There are a few variances.
- *
- * Only the Init Functions are defined by the mechanism. Each
- * init function will return a NSSCKFWCryptoOperation which
- * can supply update, final, the single part updateFinal, and
- * the combo updateCombo functions.
- *
- * For simplicity, the routines are listed in summary here:
- *
- * EncryptInit,
- * DecryptInit,
- * DigestInit,
- * SignInit,
- * SignRecoverInit;
- * VerifyInit,
- * VerifyRecoverInit;
- *
- * The key-management routines are
- *
- * GenerateKey
- * GenerateKeyPair
- * WrapKey
- * UnwrapKey
- * DeriveKey
- *
- * All of these routines based on the Cryptoki API;
- * see PKCS#11 for further information.
- */
-
- /*
- */
- NSSCKMDCryptoOperation * (PR_CALLBACK *EncryptInit)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
- );
-
- /*
- */
- NSSCKMDCryptoOperation * (PR_CALLBACK *DecryptInit)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
- );
-
- /*
- */
- NSSCKMDCryptoOperation * (PR_CALLBACK *DigestInit)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
-
- /*
- */
- NSSCKMDCryptoOperation * (PR_CALLBACK *SignInit)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
- );
-
- /*
- */
- NSSCKMDCryptoOperation * (PR_CALLBACK *VerifyInit)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
- );
-
- /*
- */
- NSSCKMDCryptoOperation * (PR_CALLBACK *SignRecoverInit)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
- );
-
- /*
- */
- NSSCKMDCryptoOperation * (PR_CALLBACK *VerifyRecoverInit)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
- );
-
- /*
- * Key management operations.
- */
-
- /*
- * This routine generates a key. This routine may return NULL
- * upon error.
- */
- NSSCKMDObject *(PR_CALLBACK *GenerateKey)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
- );
-
- /*
- * This routine generates a key pair.
- */
- CK_RV (PR_CALLBACK *GenerateKeyPair)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- NSSCKMDObject **pPublicKey,
- NSSCKMDObject **pPrivateKey
- );
-
- /*
- * This routine wraps a key.
- */
- CK_ULONG (PR_CALLBACK *GetWrapKeyLength)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdWrappingKey,
- NSSCKFWObject *fwWrappingKey,
- NSSCKMDObject *mdWrappedKey,
- NSSCKFWObject *fwWrappedKey,
- CK_RV *pError
- );
-
- /*
- * This routine wraps a key.
- */
- CK_RV (PR_CALLBACK *WrapKey)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdWrappingKey,
- NSSCKFWObject *fwWrappingKey,
- NSSCKMDObject *mdKeyObject,
- NSSCKFWObject *fwKeyObject,
- NSSItem *wrappedKey
- );
-
- /*
- * This routine unwraps a key. This routine may return NULL
- * upon error.
- */
- NSSCKMDObject *(PR_CALLBACK *UnwrapKey)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdWrappingKey,
- NSSCKFWObject *fwWrappingKey,
- NSSItem *wrappedKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
- );
-
- /*
- * This routine derives a key. This routine may return NULL
- * upon error.
- */
- NSSCKMDObject *(PR_CALLBACK *DeriveKey)(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM_PTR pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdBaseKey,
- NSSCKFWObject *fwBaseKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
- );
-
- /*
- * This object may be extended in future versions of the
- * NSS Cryptoki Framework. To allow for some flexibility
- * in the area of binary compatibility, this field should
- * be NULL.
- */
- void *null;
-};
-
-/*
- * NSSCKMDObject
- *
- * This is the basic handle for any object used by a PKCS#11 Module.
- * Modules must implement it if they support their own objects, and
- * the Framework supports it for Modules that do not handle session
- * objects. This type contains a pointer for use by the implementor,
- * to store any object-specific data, and it contains an EPV for a
- * set of routines used to access the object.
- */
-
-struct NSSCKMDObjectStr {
- /*
- * The implementation my use this pointer for its own purposes.
- */
- void *etc;
-
- /*
- * This routine is called by the Framework when it is letting
- * go of an object handle. It can be used by the Module to
- * free any resources tied up by an object "in use." It is
- * optional.
- */
- void (PR_CALLBACK *Finalize)(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine is used to completely destroy an object.
- * It is optional. The parameter fwObject might be NULL
- * if the framework runs out of memory at the wrong moment.
- */
- CK_RV (PR_CALLBACK *Destroy)(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This helper routine is used by the Framework, and is especially
- * useful when it is managing session objects on behalf of the
- * Module. This routine is optional; if unimplemented, the
- * Framework will actually look up the CKA_TOKEN attribute. In the
- * event of an error, just make something up-- the Framework will
- * find out soon enough anyway.
- */
- CK_BBOOL (PR_CALLBACK *IsTokenObject)(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
- );
-
- /*
- * This routine returns the number of attributes of which this
- * object consists. It is mandatory. It can return zero on
- * error.
- */
- CK_ULONG (PR_CALLBACK *GetAttributeCount)(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This routine stuffs the attribute types into the provided array.
- * The array size (as obtained from GetAttributeCount) is passed in
- * as a check; return CKR_BUFFER_TOO_SMALL if the count is wrong
- * (either too big or too small).
- */
- CK_RV (PR_CALLBACK *GetAttributeTypes)(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
- );
-
- /*
- * This routine returns the size (in bytes) of the specified
- * attribute. It can return zero on error.
- */
- CK_ULONG (PR_CALLBACK *GetAttributeSize)(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
- );
-
- /*
- * This routine returns an NSSCKFWItem structure.
- * The item pointer points to an NSSItem containing the attribute value.
- * The needsFreeing bit tells the framework whether to call the
- * FreeAttribute function . Upon error, an NSSCKFWItem structure
- * with a NULL NSSItem item pointer will be returned
- */
- NSSCKFWItem (PR_CALLBACK *GetAttribute)(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
- );
-
- /*
- * This routine returns CKR_OK if the attribute could be freed.
- */
- CK_RV (PR_CALLBACK *FreeAttribute)(
- NSSCKFWItem * item
- );
-
- /*
- * This routine changes the specified attribute. If unimplemented,
- * the object will be considered read-only.
- */
- CK_RV (PR_CALLBACK *SetAttribute)(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value
- );
-
- /*
- * This routine returns the storage requirements of this object,
- * in bytes. Cryptoki doesn't strictly define the definition,
- * but it should relate to the values returned by the "Get Memory"
- * routines of the NSSCKMDToken. This routine is optional; if
- * unimplemented, the Framework will consider this information
- * sensitive. This routine may return zero on error. If the
- * specified error is CKR_OK, zero will be accepted as a valid
- * response.
- */
- CK_ULONG (PR_CALLBACK *GetObjectSize)(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
- );
-
- /*
- * This object may be extended in future versions of the
- * NSS Cryptoki Framework. To allow for some flexibility
- * in the area of binary compatibility, this field should
- * be NULL.
- */
- void *null;
-};
-
-
-#endif /* NSSCKMDT_H */
diff --git a/security/nss/lib/ckfw/nssckt.h b/security/nss/lib/ckfw/nssckt.h
deleted file mode 100644
index 5ed534c25..000000000
--- a/security/nss/lib/ckfw/nssckt.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _NSSCKT_H_
-#define _NSSCKT_H_ 1
-
-#include "pkcs11t.h"
-
-typedef CK_ATTRIBUTE_TYPE CK_PTR CK_ATTRIBUTE_TYPE_PTR;
-#define CK_ENTRY
-
-#endif /* _NSSCKT_H_ */
-
diff --git a/security/nss/lib/ckfw/nssmkey/Makefile b/security/nss/lib/ckfw/nssmkey/Makefile
deleted file mode 100644
index 77b50134b..000000000
--- a/security/nss/lib/ckfw/nssmkey/Makefile
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-include manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
-
-EXTRA_LIBS = \
- $(DIST)/lib/$(LIB_PREFIX)nssckfw.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
- $(NULL)
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-ifdef NS_USE_GCC
-EXTRA_LIBS += \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-else
-EXTRA_SHARED_LIBS += \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-else
-
-EXTRA_LIBS += \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- -framework Security \
- -framework CoreServices \
- $(NULL)
-endif
-
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-# Generate certdata.c.
-generate:
- perl certdata.perl < certdata.txt
-
-# This'll need some help from a build person.
-
-
-ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.1)
-DSO_LDOPTS = -bM:SRE -bh:4 -bnoentry
-EXTRA_DSO_LDOPTS = -lc
-MKSHLIB = xlC $(DSO_LDOPTS)
-
-$(SHARED_LIBRARY): $(OBJS)
- @$(MAKE_OBJDIR)
- rm -f $@
- $(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DSO_LDOPTS)
- chmod +x $@
-
-endif
-
-ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.2)
-LD += -G
-endif
-
-
diff --git a/security/nss/lib/ckfw/nssmkey/README b/security/nss/lib/ckfw/nssmkey/README
deleted file mode 100644
index c060d9c3c..000000000
--- a/security/nss/lib/ckfw/nssmkey/README
+++ /dev/null
@@ -1,21 +0,0 @@
-This Cryptoki module provides acces to certs and keys stored in
-Macintosh key Ring.
-
-- It does not yet export PKCS #12 keys. To get this to work should be
- implemented using exporting the key object in PKCS #8 wrapped format.
- PSM work needs to happen before this can be completed.
-- It does not import or export CA Root trust from the mac keychain.
-- It does not handle S/MIME objects (pkcs #7 in mac keychain terms?).
-- The AuthRoots don't show up on the default list.
-- Only RSA keys are supported currently.
-
-There are a number of things that have not been tested that other PKCS #11
-apps may need:
-- reading Modulus and Public Exponents from private keys and public keys.
-- storing public keys.
-- setting attributes other than CKA_ID and CKA_LABEL.
-
-Other TODOs:
-- Check for and plug memory leaks.
-- Need to map mac errors into something more intellegible than
- CKR_GENERAL_ERROR.
diff --git a/security/nss/lib/ckfw/nssmkey/ckmk.h b/security/nss/lib/ckfw/nssmkey/ckmk.h
deleted file mode 100644
index 50d15c2bf..000000000
--- a/security/nss/lib/ckfw/nssmkey/ckmk.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CKMK_H
-#define CKMK_H 1
-
-#ifdef DEBUG
-static const char CKMK_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include <Security/SecKeychainSearch.h>
-#include <Security/SecKeychainItem.h>
-#include <Security/SecKeychain.h>
-#include <Security/cssmtype.h>
-#include <Security/cssmapi.h>
-#include <Security/SecKey.h>
-#include <Security/SecCertificate.h>
-
-#define NTO
-
-#include "nssckmdt.h"
-#include "nssckfw.h"
-/*
- * I'm including this for access to the arena functions.
- * Looks like we should publish that API.
- */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-/*
- * This is where the Netscape extensions live, at least for now.
- */
-#ifndef CKT_H
-#include "ckt.h"
-#endif /* CKT_H */
-
-/*
- * statically defined raw objects. Allows us to data description objects
- * to this PKCS #11 module.
- */
-struct ckmkRawObjectStr {
- CK_ULONG n;
- const CK_ATTRIBUTE_TYPE *types;
- const NSSItem *items;
-};
-typedef struct ckmkRawObjectStr ckmkRawObject;
-
-/*
- * Key/Cert Items
- */
-struct ckmkItemObjectStr {
- SecKeychainItemRef itemRef;
- SecItemClass itemClass;
- PRBool hasID;
- NSSItem modify;
- NSSItem private;
- NSSItem encrypt;
- NSSItem decrypt;
- NSSItem derive;
- NSSItem sign;
- NSSItem signRecover;
- NSSItem verify;
- NSSItem verifyRecover;
- NSSItem wrap;
- NSSItem unwrap;
- NSSItem label;
- NSSItem subject;
- NSSItem issuer;
- NSSItem serial;
- NSSItem derCert;
- NSSItem id;
- NSSItem modulus;
- NSSItem exponent;
- NSSItem privateExponent;
- NSSItem prime1;
- NSSItem prime2;
- NSSItem exponent1;
- NSSItem exponent2;
- NSSItem coefficient;
-};
-typedef struct ckmkItemObjectStr ckmkItemObject;
-
-typedef enum {
- ckmkRaw,
- ckmkItem,
-} ckmkObjectType;
-
-/*
- * all the various types of objects are abstracted away in cobject and
- * cfind as ckmkInternalObjects.
- */
-struct ckmkInternalObjectStr {
- ckmkObjectType type;
- union {
- ckmkRawObject raw;
- ckmkItemObject item;
- } u;
- CK_OBJECT_CLASS objClass;
- NSSItem hashKey;
- unsigned char hashKeyData[128];
- NSSCKMDObject mdObject;
-};
-typedef struct ckmkInternalObjectStr ckmkInternalObject;
-
-/* our raw object data array */
-NSS_EXTERN_DATA ckmkInternalObject nss_ckmk_data[];
-NSS_EXTERN_DATA const PRUint32 nss_ckmk_nObjects;
-
-NSS_EXTERN_DATA const CK_VERSION nss_ckmk_CryptokiVersion;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckmk_ManufacturerID;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckmk_LibraryDescription;
-NSS_EXTERN_DATA const CK_VERSION nss_ckmk_LibraryVersion;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckmk_SlotDescription;
-NSS_EXTERN_DATA const CK_VERSION nss_ckmk_HardwareVersion;
-NSS_EXTERN_DATA const CK_VERSION nss_ckmk_FirmwareVersion;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckmk_TokenLabel;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckmk_TokenModel;
-NSS_EXTERN_DATA const NSSUTF8 * nss_ckmk_TokenSerialNumber;
-
-NSS_EXTERN_DATA const NSSCKMDInstance nss_ckmk_mdInstance;
-NSS_EXTERN_DATA const NSSCKMDSlot nss_ckmk_mdSlot;
-NSS_EXTERN_DATA const NSSCKMDToken nss_ckmk_mdToken;
-NSS_EXTERN_DATA const NSSCKMDMechanism nss_ckmk_mdMechanismRSA;
-
-NSS_EXTERN NSSCKMDSession *
-nss_ckmk_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDFindObjects *
-nss_ckmk_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-/*
- * Object Utilities
- */
-NSS_EXTERN NSSCKMDObject *
-nss_ckmk_CreateMDObject
-(
- NSSArena *arena,
- ckmkInternalObject *io,
- CK_RV *pError
-);
-
-NSS_EXTERN NSSCKMDObject *
-nss_ckmk_CreateObject
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-);
-
-NSS_EXTERN const NSSItem *
-nss_ckmk_FetchAttribute
-(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError
-);
-
-NSS_EXTERN void
-nss_ckmk_DestroyInternalObject
-(
- ckmkInternalObject *io
-);
-
-unsigned char *
-nss_ckmk_DERUnwrap
-(
- unsigned char *src,
- int size,
- int *outSize,
- unsigned char **next
-);
-
-CK_ULONG
-nss_ckmk_GetULongAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError
-);
-
-#define NSS_CKMK_ARRAY_SIZE(x) ((sizeof (x))/(sizeof ((x)[0])))
-
-#ifdef DEBUG
-#define CKMK_MACERR(str,err) cssmPerror(str,err)
-#else
-#define CKMK_MACERR(str,err)
-#endif
-
-#endif
diff --git a/security/nss/lib/ckfw/nssmkey/ckmkver.c b/security/nss/lib/ckfw/nssmkey/ckmkver.c
deleted file mode 100644
index e30fd9875..000000000
--- a/security/nss/lib/ckfw/nssmkey/ckmkver.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* Library identity and versioning */
-
-#include "nssmkey.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_ckmk_rcsid[] = "$Header: NSS Access to the MAC OS X Key Ring "
- NSS_CKMK_LIBRARY_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_ckmk_sccsid[] = "@(#)NSS Access to the MAC OS X Key Ring "
- NSS_CKMK_LIBRARY_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/ckfw/nssmkey/config.mk b/security/nss/lib/ckfw/nssmkey/config.mk
deleted file mode 100644
index 1ad4f4439..000000000
--- a/security/nss/lib/ckfw/nssmkey/config.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-ifdef BUILD_IDG
-DEFINES += -DNSSDEBUG
-endif
-
-ifdef NS_USE_CKFW_TRACE
-DEFINES += -DTRACE
-endif
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
-
diff --git a/security/nss/lib/ckfw/nssmkey/manchor.c b/security/nss/lib/ckfw/nssmkey/manchor.c
deleted file mode 100644
index 42fedeff6..000000000
--- a/security/nss/lib/ckfw/nssmkey/manchor.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssmkey/manchor.c
- *
- * This file "anchors" the actual cryptoki entry points in this module's
- * shared library, which is required for dynamic loading. See the
- * comments in nssck.api for more information.
- */
-
-#include "ckmk.h"
-
-#define MODULE_NAME ckmk
-#define INSTANCE_NAME (NSSCKMDInstance *)&nss_ckmk_mdInstance
-#include "nssck.api"
diff --git a/security/nss/lib/ckfw/nssmkey/manifest.mn b/security/nss/lib/ckfw/nssmkey/manifest.mn
deleted file mode 100644
index 4476c1ea5..000000000
--- a/security/nss/lib/ckfw/nssmkey/manifest.mn
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-CORE_DEPTH = ../../../..
-
-MODULE = nss
-MAPFILE = $(OBJDIR)/nssmkey.def
-
-EXPORTS = \
- nssmkey.h \
- $(NULL)
-
-CSRCS = \
- manchor.c \
- mconstants.c \
- mfind.c \
- minst.c \
- mobject.c \
- mrsa.c \
- msession.c \
- mslot.c \
- mtoken.c \
- ckmkver.c \
- staticobj.c \
- $(NULL)
-
-REQUIRES = nspr
-
-LIBRARY_NAME = nssmkey
-
-#EXTRA_SHARED_LIBS = -L$(DIST)/lib -lnssckfw -lnssb -lplc4 -lplds4
diff --git a/security/nss/lib/ckfw/nssmkey/mconstants.c b/security/nss/lib/ckfw/nssmkey/mconstants.c
deleted file mode 100644
index 7546b23f3..000000000
--- a/security/nss/lib/ckfw/nssmkey/mconstants.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssmkey/constants.c
- *
- * Identification and other constants, all collected here in one place.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#include "nssmkey.h"
-
-NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckmk_CryptokiVersion = {
- NSS_CKMK_CRYPTOKI_VERSION_MAJOR,
- NSS_CKMK_CRYPTOKI_VERSION_MINOR };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckmk_ManufacturerID = (NSSUTF8 *) "Mozilla Foundation";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckmk_LibraryDescription = (NSSUTF8 *) "NSS Access to Mac OS X Key Ring";
-
-NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckmk_LibraryVersion = {
- NSS_CKMK_LIBRARY_VERSION_MAJOR,
- NSS_CKMK_LIBRARY_VERSION_MINOR};
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckmk_SlotDescription = (NSSUTF8 *) "Mac OS X Key Ring";
-
-NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckmk_HardwareVersion = {
- NSS_CKMK_HARDWARE_VERSION_MAJOR,
- NSS_CKMK_HARDWARE_VERSION_MINOR };
-
-NSS_IMPLEMENT_DATA const CK_VERSION
-nss_ckmk_FirmwareVersion = {
- NSS_CKMK_FIRMWARE_VERSION_MAJOR,
- NSS_CKMK_FIRMWARE_VERSION_MINOR };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckmk_TokenLabel = (NSSUTF8 *) "Mac OS X Key Ring";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckmk_TokenModel = (NSSUTF8 *) "1";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
-nss_ckmk_TokenSerialNumber = (NSSUTF8 *) "1";
-
diff --git a/security/nss/lib/ckfw/nssmkey/mfind.c b/security/nss/lib/ckfw/nssmkey/mfind.c
deleted file mode 100644
index 79307c47d..000000000
--- a/security/nss/lib/ckfw/nssmkey/mfind.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef CKMK_H
-#include "ckmk.h"
-#endif /* CKMK_H */
-
-/*
- * nssmkey/mfind.c
- *
- * This file implements the NSSCKMDFindObjects object for the
- * "nssmkey" cryptoki module.
- */
-
-struct ckmkFOStr {
- NSSArena *arena;
- CK_ULONG n;
- CK_ULONG i;
- ckmkInternalObject **objs;
-};
-
-static void
-ckmk_mdFindObjects_Final
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- struct ckmkFOStr *fo = (struct ckmkFOStr *)mdFindObjects->etc;
- NSSArena *arena = fo->arena;
- PRUint32 i;
-
- /* walk down an free the unused 'objs' */
- for (i=fo->i; i < fo->n ; i++) {
- nss_ckmk_DestroyInternalObject(fo->objs[i]);
- }
-
- nss_ZFreeIf(fo->objs);
- nss_ZFreeIf(fo);
- nss_ZFreeIf(mdFindObjects);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
-
- return;
-}
-
-static NSSCKMDObject *
-ckmk_mdFindObjects_Next
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
-{
- struct ckmkFOStr *fo = (struct ckmkFOStr *)mdFindObjects->etc;
- ckmkInternalObject *io;
-
- if( fo->i == fo->n ) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
-
- io = fo->objs[ fo->i ];
- fo->i++;
-
- return nss_ckmk_CreateMDObject(arena, io, pError);
-}
-
-static CK_BBOOL
-ckmk_attrmatch
-(
- CK_ATTRIBUTE_PTR a,
- ckmkInternalObject *o
-)
-{
- PRBool prb;
- const NSSItem *b;
- CK_RV error;
-
- b = nss_ckmk_FetchAttribute(o, a->type, &error);
- if (b == NULL) {
- return CK_FALSE;
- }
-
- if( a->ulValueLen != b->size ) {
- /* match a decoded serial number */
- if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
- int len;
- unsigned char *data;
-
- data = nss_ckmk_DERUnwrap(b->data, b->size, &len, NULL);
- if ((len == a->ulValueLen) &&
- nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
- return CK_TRUE;
- }
- }
- return CK_FALSE;
- }
-
- prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
-
- if( PR_TRUE == prb ) {
- return CK_TRUE;
- } else {
- return CK_FALSE;
- }
-}
-
-
-static CK_BBOOL
-ckmk_match
-(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckmkInternalObject *o
-)
-{
- CK_ULONG i;
-
- for( i = 0; i < ulAttributeCount; i++ ) {
- if (CK_FALSE == ckmk_attrmatch(&pTemplate[i], o)) {
- return CK_FALSE;
- }
- }
-
- /* Every attribute passed */
- return CK_TRUE;
-}
-
-#define CKMK_ITEM_CHUNK 20
-
-#define PUT_OBJECT(obj, err, size, count, list) \
- { \
- if (count >= size) { \
- (list) = (list) ? \
- nss_ZREALLOCARRAY(list, ckmkInternalObject *, \
- ((size)+CKMK_ITEM_CHUNK) ) : \
- nss_ZNEWARRAY(NULL, ckmkInternalObject *, \
- ((size)+CKMK_ITEM_CHUNK) ) ; \
- if ((ckmkInternalObject **)NULL == list) { \
- err = CKR_HOST_MEMORY; \
- goto loser; \
- } \
- (size) += CKMK_ITEM_CHUNK; \
- } \
- (list)[ count ] = (obj); \
- count++; \
- }
-
-
-/* find all the certs that represent the appropriate object (cert, priv key, or
- * pub key) in the cert store.
- */
-static PRUint32
-collect_class(
- CK_OBJECT_CLASS objClass,
- SecItemClass itemClass,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckmkInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError
-)
-{
- ckmkInternalObject *next = NULL;
- SecKeychainSearchRef searchRef = 0;
- SecKeychainItemRef itemRef = 0;
- OSStatus error;
-
- /* future, build the attribute list based on the template
- * so we can refine the search */
- error = SecKeychainSearchCreateFromAttributes(
- NULL, itemClass, NULL, &searchRef);
-
- while (noErr == SecKeychainSearchCopyNext(searchRef, &itemRef)) {
- /* if we don't have an internal object structure, get one */
- if ((ckmkInternalObject *)NULL == next) {
- next = nss_ZNEW(NULL, ckmkInternalObject);
- if ((ckmkInternalObject *)NULL == next) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- }
- /* fill in the relevant object data */
- next->type = ckmkItem;
- next->objClass = objClass;
- next->u.item.itemRef = itemRef;
- next->u.item.itemClass = itemClass;
-
- /* see if this is one of the objects we are looking for */
- if( CK_TRUE == ckmk_match(pTemplate, ulAttributeCount, next) ) {
- /* yes, put it on the list */
- PUT_OBJECT(next, *pError, *sizep, count, *listp);
- next = NULL; /* this one is on the list, need to allocate a new one now */
- } else {
- /* no , release the current item and clear out the structure for reuse */
- CFRelease(itemRef);
- /* don't cache the values we just loaded */
- nsslibc_memset(next, 0, sizeof(*next));
- }
- }
-loser:
- if (searchRef) {
- CFRelease(searchRef);
- }
- nss_ZFreeIf(next);
- return count;
-}
-
-static PRUint32
-collect_objects(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckmkInternalObject ***listp,
- CK_RV *pError
-)
-{
- PRUint32 i;
- PRUint32 count = 0;
- PRUint32 size = 0;
- CK_OBJECT_CLASS objClass;
-
- /*
- * first handle the static build in objects (if any)
- */
- for( i = 0; i < nss_ckmk_nObjects; i++ ) {
- ckmkInternalObject *o = (ckmkInternalObject *)&nss_ckmk_data[i];
-
- if( CK_TRUE == ckmk_match(pTemplate, ulAttributeCount, o) ) {
- PUT_OBJECT(o, *pError, size, count, *listp);
- }
- }
-
- /*
- * now handle the various object types
- */
- objClass = nss_ckmk_GetULongAttribute(CKA_CLASS,
- pTemplate, ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- objClass = CK_INVALID_HANDLE;
- }
- *pError = CKR_OK;
- switch (objClass) {
- case CKO_CERTIFICATE:
- count = collect_class(objClass, kSecCertificateItemClass,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- case CKO_PUBLIC_KEY:
- count = collect_class(objClass, CSSM_DL_DB_RECORD_PUBLIC_KEY,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- case CKO_PRIVATE_KEY:
- count = collect_class(objClass, CSSM_DL_DB_RECORD_PRIVATE_KEY,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- /* all of them */
- case CK_INVALID_HANDLE:
- count = collect_class(CKO_CERTIFICATE, kSecCertificateItemClass,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- count = collect_class(CKO_PUBLIC_KEY, CSSM_DL_DB_RECORD_PUBLIC_KEY,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- count = collect_class(CKO_PUBLIC_KEY, CSSM_DL_DB_RECORD_PRIVATE_KEY,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- default:
- break;
- }
- if (CKR_OK != *pError) {
- goto loser;
- }
-
- return count;
-loser:
- nss_ZFreeIf(*listp);
- return 0;
-}
-
-
-NSS_IMPLEMENT NSSCKMDFindObjects *
-nss_ckmk_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- /* This could be made more efficient. I'm rather rushed. */
- NSSArena *arena;
- NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
- struct ckmkFOStr *fo = (struct ckmkFOStr *)NULL;
- ckmkInternalObject **temp = (ckmkInternalObject **)NULL;
-
- arena = NSSArena_Create();
- if( (NSSArena *)NULL == arena ) {
- goto loser;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDFindObjects);
- if( (NSSCKMDFindObjects *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fo = nss_ZNEW(arena, struct ckmkFOStr);
- if( (struct ckmkFOStr *)NULL == fo ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fo->arena = arena;
- /* fo->n and fo->i are already zero */
-
- rv->etc = (void *)fo;
- rv->Final = ckmk_mdFindObjects_Final;
- rv->Next = ckmk_mdFindObjects_Next;
- rv->null = (void *)NULL;
-
- fo->n = collect_objects(pTemplate, ulAttributeCount, &temp, pError);
- if (*pError != CKR_OK) {
- goto loser;
- }
-
- fo->objs = nss_ZNEWARRAY(arena, ckmkInternalObject *, fo->n);
- if( (ckmkInternalObject **)NULL == fo->objs ) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- (void)nsslibc_memcpy(fo->objs, temp, sizeof(ckmkInternalObject *) * fo->n);
- nss_ZFreeIf(temp);
- temp = (ckmkInternalObject **)NULL;
-
- return rv;
-
- loser:
- nss_ZFreeIf(temp);
- nss_ZFreeIf(fo);
- nss_ZFreeIf(rv);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
- return (NSSCKMDFindObjects *)NULL;
-}
-
diff --git a/security/nss/lib/ckfw/nssmkey/minst.c b/security/nss/lib/ckfw/nssmkey/minst.c
deleted file mode 100644
index 7a13eb8ee..000000000
--- a/security/nss/lib/ckfw/nssmkey/minst.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckmk.h"
-
-/*
- * nssmkey/minstance.c
- *
- * This file implements the NSSCKMDInstance object for the
- * "nssmkey" cryptoki module.
- */
-
-/*
- * NSSCKMDInstance methods
- */
-
-static CK_ULONG
-ckmk_mdInstance_GetNSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (CK_ULONG)1;
-}
-
-static CK_VERSION
-ckmk_mdInstance_GetCryptokiVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckmk_CryptokiVersion;
-}
-
-static NSSUTF8 *
-ckmk_mdInstance_GetManufacturerID
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckmk_ManufacturerID;
-}
-
-static NSSUTF8 *
-ckmk_mdInstance_GetLibraryDescription
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckmk_LibraryDescription;
-}
-
-static CK_VERSION
-ckmk_mdInstance_GetLibraryVersion
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckmk_LibraryVersion;
-}
-
-static CK_RV
-ckmk_mdInstance_GetSlots
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[]
-)
-{
- slots[0] = (NSSCKMDSlot *)&nss_ckmk_mdSlot;
- return CKR_OK;
-}
-
-static CK_BBOOL
-ckmk_mdInstance_ModuleHandlesSessionObjects
-(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- /* we don't want to allow any session object creation, at least
- * until we can investigate whether or not we can use those objects
- */
- return CK_TRUE;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDInstance
-nss_ckmk_mdInstance = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Finalize */
- ckmk_mdInstance_GetNSlots,
- ckmk_mdInstance_GetCryptokiVersion,
- ckmk_mdInstance_GetManufacturerID,
- ckmk_mdInstance_GetLibraryDescription,
- ckmk_mdInstance_GetLibraryVersion,
- ckmk_mdInstance_ModuleHandlesSessionObjects,
- /*NULL, /* HandleSessionObjects */
- ckmk_mdInstance_GetSlots,
- NULL, /* WaitForSlotEvent */
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/nssmkey/mobject.c b/security/nss/lib/ckfw/nssmkey/mobject.c
deleted file mode 100644
index 98cec47e2..000000000
--- a/security/nss/lib/ckfw/nssmkey/mobject.c
+++ /dev/null
@@ -1,1927 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckmk.h"
-#include "nssbase.h"
-
-#include "secdert.h" /* for DER_INTEGER */
-#include "string.h"
-
-/* asn1 encoder (to build pkcs#8 blobs) */
-#include <seccomon.h>
-#include <secitem.h>
-#include <blapit.h>
-#include <secoid.h>
-#include <secasn1.h>
-
-/* for importing the keys */
-#include <CoreFoundation/CoreFoundation.h>
-#include <security/SecImportExport.h>
-
-/*
- * nssmkey/mobject.c
- *
- * This file implements the NSSCKMDObject object for the
- * "nssmkey" cryptoki module.
- */
-
-const CK_ATTRIBUTE_TYPE certAttrs[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_PRIVATE,
- CKA_MODIFIABLE,
- CKA_LABEL,
- CKA_CERTIFICATE_TYPE,
- CKA_SUBJECT,
- CKA_ISSUER,
- CKA_SERIAL_NUMBER,
- CKA_VALUE
-};
-const PRUint32 certAttrsCount = NSS_CKMK_ARRAY_SIZE(certAttrs);
-
-/* private keys, for now only support RSA */
-const CK_ATTRIBUTE_TYPE privKeyAttrs[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_PRIVATE,
- CKA_MODIFIABLE,
- CKA_LABEL,
- CKA_KEY_TYPE,
- CKA_DERIVE,
- CKA_LOCAL,
- CKA_SUBJECT,
- CKA_SENSITIVE,
- CKA_DECRYPT,
- CKA_SIGN,
- CKA_SIGN_RECOVER,
- CKA_UNWRAP,
- CKA_EXTRACTABLE,
- CKA_ALWAYS_SENSITIVE,
- CKA_NEVER_EXTRACTABLE,
- CKA_MODULUS,
- CKA_PUBLIC_EXPONENT,
-};
-const PRUint32 privKeyAttrsCount = NSS_CKMK_ARRAY_SIZE(privKeyAttrs);
-
-/* public keys, for now only support RSA */
-const CK_ATTRIBUTE_TYPE pubKeyAttrs[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_PRIVATE,
- CKA_MODIFIABLE,
- CKA_LABEL,
- CKA_KEY_TYPE,
- CKA_DERIVE,
- CKA_LOCAL,
- CKA_SUBJECT,
- CKA_ENCRYPT,
- CKA_VERIFY,
- CKA_VERIFY_RECOVER,
- CKA_WRAP,
- CKA_MODULUS,
- CKA_PUBLIC_EXPONENT,
-};
-const PRUint32 pubKeyAttrsCount = NSS_CKMK_ARRAY_SIZE(pubKeyAttrs);
-static const CK_BBOOL ck_true = CK_TRUE;
-static const CK_BBOOL ck_false = CK_FALSE;
-static const CK_CERTIFICATE_TYPE ckc_x509 = CKC_X_509;
-static const CK_KEY_TYPE ckk_rsa = CKK_RSA;
-static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
-static const CK_OBJECT_CLASS cko_private_key = CKO_PRIVATE_KEY;
-static const CK_OBJECT_CLASS cko_public_key = CKO_PUBLIC_KEY;
-static const NSSItem ckmk_trueItem = {
- (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) };
-static const NSSItem ckmk_falseItem = {
- (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) };
-static const NSSItem ckmk_x509Item = {
- (void *)&ckc_x509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) };
-static const NSSItem ckmk_rsaItem = {
- (void *)&ckk_rsa, (PRUint32)sizeof(CK_KEY_TYPE) };
-static const NSSItem ckmk_certClassItem = {
- (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) };
-static const NSSItem ckmk_privKeyClassItem = {
- (void *)&cko_private_key, (PRUint32)sizeof(CK_OBJECT_CLASS) };
-static const NSSItem ckmk_pubKeyClassItem = {
- (void *)&cko_public_key, (PRUint32)sizeof(CK_OBJECT_CLASS) };
-static const NSSItem ckmk_emptyItem = {
- (void *)&ck_true, 0};
-
-/*
- * these are utilities. The chould be moved to a new utilities file.
- */
-#ifdef DEBUG
-static void
-itemdump(char *str, void *data, int size, CK_RV error)
-{
- unsigned char *ptr = (unsigned char *)data;
- int i;
- fprintf(stderr,str);
- for (i=0; i < size; i++) {
- fprintf(stderr,"%02x ",(unsigned int) ptr[i]);
- }
- fprintf(stderr," (error = %d)\n", (int ) error);
-}
-#endif
-
-/*
- * unwrap a single DER value
- * now that we have util linked in, we should probably use
- * the ANS1_Decoder for this work...
- */
-unsigned char *
-nss_ckmk_DERUnwrap
-(
- unsigned char *src,
- int size,
- int *outSize,
- unsigned char **next
-)
-{
- unsigned char *start = src;
- unsigned int len = 0;
-
- /* initialize error condition return values */
- *outSize = 0;
- if (next) {
- *next = src;
- }
-
- if (size < 2) {
- return start;
- }
- src ++ ; /* skip the tag -- should check it against an expected value! */
- len = (unsigned) *src++;
- if (len & 0x80) {
- int count = len & 0x7f;
- len =0;
-
- if (count+2 > size) {
- return start;
- }
- while (count-- > 0) {
- len = (len << 8) | (unsigned) *src++;
- }
- }
- if (len + (src-start) > (unsigned int)size) {
- return start;
- }
- if (next) {
- *next = src+len;
- }
- *outSize = len;
-
- return src;
-}
-
-/*
- * get an attribute from a template. Value is returned in NSS item.
- * data for the item is owned by the template.
- */
-CK_RV
-nss_ckmk_GetAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- NSSItem *item
-)
-{
- CK_ULONG i;
-
- for (i=0; i < templateSize; i++) {
- if (template[i].type == type) {
- item->data = template[i].pValue;
- item->size = template[i].ulValueLen;
- return CKR_OK;
- }
- }
- return CKR_TEMPLATE_INCOMPLETE;
-}
-
-/*
- * get an attribute which is type CK_ULONG.
- */
-CK_ULONG
-nss_ckmk_GetULongAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError
-)
-{
- NSSItem item;
-
- *pError = nss_ckmk_GetAttribute(type, template, templateSize, &item);
- if (CKR_OK != *pError) {
- return (CK_ULONG) 0;
- }
- if (item.size != sizeof(CK_ULONG)) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (CK_ULONG) 0;
- }
- return *(CK_ULONG *)item.data;
-}
-
-/*
- * get an attribute which is type CK_BBOOL.
- */
-CK_BBOOL
-nss_ckmk_GetBoolAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_BBOOL defaultBool
-)
-{
- NSSItem item;
- CK_RV error;
-
- error = nss_ckmk_GetAttribute(type, template, templateSize, &item);
- if (CKR_OK != error) {
- return defaultBool;
- }
- if (item.size != sizeof(CK_BBOOL)) {
- return defaultBool;
- }
- return *(CK_BBOOL *)item.data;
-}
-
-/*
- * get an attribute as a NULL terminated string. Caller is responsible to
- * free the string.
- */
-char *
-nss_ckmk_GetStringAttribute
-(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError
-)
-{
- NSSItem item;
- char *str;
-
- /* get the attribute */
- *pError = nss_ckmk_GetAttribute(type, template, templateSize, &item);
- if (CKR_OK != *pError) {
- return (char *)NULL;
- }
- /* make sure it is null terminated */
- str = nss_ZNEWARRAY(NULL, char, item.size+1);
- if ((char *)NULL == str) {
- *pError = CKR_HOST_MEMORY;
- return (char *)NULL;
- }
-
- nsslibc_memcpy(str, item.data, item.size);
- str[item.size] = 0;
-
- return str;
-}
-
-/*
- * Apple doesn't seem to have a public interface to the DER encoder,
- * wip out a quick one for integers only (anything more complicated,
- * we should use one of the 3 in lib/util). -- especially since we
- * now link with it.
- */
-static CK_RV
-ckmk_encodeInt(NSSItem *dest, void *src, int srcLen)
-{
- int dataLen = srcLen;
- int lenLen = 1;
- int encLen;
- int isSigned = 0;
- int offset = 0;
- unsigned char *data = NULL;
- int i;
-
- if (*(unsigned char *)src & 0x80) {
- dataLen++;
- isSigned = 1;
- }
-
- /* calculate the length of the length specifier */
- /* (NOTE: destroys dataLen value) */
- if (dataLen > 0x7f) {
- do {
- lenLen++;
- dataLen >>= 8;
- } while (dataLen);
- }
-
- /* calculate our total length */
- dataLen = isSigned + srcLen;
- encLen = 1 + lenLen + dataLen;
- data = nss_ZNEWARRAY(NULL, unsigned char, encLen);
- if ((unsigned char *)NULL == data) {
- return CKR_HOST_MEMORY;
- }
- data[0] = DER_INTEGER;
- if (1 == lenLen) {
- data[1] = dataLen;
- } else {
- data[1] = 0x80 + lenLen;
- for (i=0; i < lenLen; i++) {
- data[i+1] = ((dataLen >> ((lenLen-i-1)*8)) & 0xff);
- }
- }
- offset = lenLen+1;
-
- if (isSigned) {
- data[offset++] = 0;
- }
- nsslibc_memcpy(&data[offset], src, srcLen);
- dest->data = data;
- dest->size = encLen;
- return CKR_OK;
-}
-
-
-/*
- * Get a Keyring attribute. If content is set to true, then we get the
- * content, not the attribute.
- */
-static CK_RV
-ckmk_GetCommonAttribute
-(
- ckmkInternalObject *io,
- SecItemAttr itemAttr,
- PRBool content,
- NSSItem *item,
- char *dbString
-)
-{
- SecKeychainAttributeList *attrList = NULL;
- SecKeychainAttributeInfo attrInfo;
- PRUint32 len = 0;
- PRUint32 dataLen = 0;
- PRUint32 attrFormat = 0;
- void *dataVal = 0;
- void *out = NULL;
- CK_RV error = CKR_OK;
- OSStatus macErr;
-
- attrInfo.count = 1;
- attrInfo.tag = &itemAttr;
- attrInfo.format = &attrFormat;
-
- macErr = SecKeychainItemCopyAttributesAndData(io->u.item.itemRef,
- &attrInfo, NULL, &attrList, &len, &out);
- if (noErr != macErr) {
- CKMK_MACERR(dbString, macErr);
- return CKR_ATTRIBUTE_TYPE_INVALID;
- }
- dataLen = content ? len : attrList->attr->length;
- dataVal = content ? out : attrList->attr->data;
-
- /* Apple's documentation says this value is DER Encoded, but it clearly isn't
- * der encode it before we ship it back off to NSS
- */
- if ( kSecSerialNumberItemAttr == itemAttr ) {
- error = ckmk_encodeInt(item, dataVal, dataLen);
- goto loser; /* logically 'done' if error == CKR_OK */
- }
- item->data = nss_ZNEWARRAY(NULL, char, dataLen);
- if (NULL == item->data) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- nsslibc_memcpy(item->data, dataVal, dataLen);
- item->size = dataLen;
-
-loser:
- SecKeychainItemFreeAttributesAndData(attrList, out);
- return error;
-}
-
-/*
- * change an attribute (does not operate on the content).
- */
-static CK_RV
-ckmk_updateAttribute
-(
- SecKeychainItemRef itemRef,
- SecItemAttr itemAttr,
- void *data,
- PRUint32 len,
- char *dbString
-)
-{
- SecKeychainAttributeList attrList;
- SecKeychainAttribute attrAttr;
- OSStatus macErr;
- CK_RV error = CKR_OK;
-
- attrList.count = 1;
- attrList.attr = &attrAttr;
- attrAttr.tag = itemAttr;
- attrAttr.data = data;
- attrAttr.length = len;
- macErr = SecKeychainItemModifyAttributesAndData(itemRef, &attrList, 0, NULL);
- if (noErr != macErr) {
- CKMK_MACERR(dbString, macErr);
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- }
- return error;
-}
-
-/*
- * get an attribute (does not operate on the content)
- */
-static CK_RV
-ckmk_GetDataAttribute
-(
- ckmkInternalObject *io,
- SecItemAttr itemAttr,
- NSSItem *item,
- char *dbString
-)
-{
- return ckmk_GetCommonAttribute(io, itemAttr, PR_FALSE, item, dbString);
-}
-
-/*
- * get an attribute we know is a BOOL.
- */
-static CK_RV
-ckmk_GetBoolAttribute
-(
- ckmkInternalObject *io,
- SecItemAttr itemAttr,
- NSSItem *item,
- char *dbString
-)
-{
- SecKeychainAttribute attr;
- SecKeychainAttributeList attrList;
- CK_BBOOL *boolp = NULL;
- PRUint32 len = 0;;
- void *out = NULL;
- CK_RV error = CKR_OK;
- OSStatus macErr;
-
- attr.tag = itemAttr;
- attr.length = 0;
- attr.data = NULL;
- attrList.count = 1;
- attrList.attr = &attr;
-
- boolp = nss_ZNEW(NULL, CK_BBOOL);
- if ((CK_BBOOL *)NULL == boolp) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- macErr = SecKeychainItemCopyContent(io->u.item.itemRef, NULL,
- &attrList, &len, &out);
- if (noErr != macErr) {
- CKMK_MACERR(dbString, macErr);
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- goto loser;
- }
- if (sizeof(PRUint32) != attr.length) {
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- goto loser;
- }
- *boolp = *(PRUint32 *)attr.data ? 1 : 0;
- item->data = boolp;
- boolp = NULL;
- item->size = sizeof(CK_BBOOL);
-
-loser:
- nss_ZFreeIf(boolp);
- SecKeychainItemFreeContent(&attrList, out);
- return error;
-}
-
-
-/*
- * macros for fetching attributes into a cache and returning the
- * appropriate value. These operate inside switch statements
- */
-#define CKMK_HANDLE_ITEM(func, io, type, loc, item, error, str) \
- if (0 == (item)->loc.size) { \
- error = func(io, type, &(item)->loc, str); \
- } \
- return (CKR_OK == (error)) ? &(item)->loc : NULL;
-
-#define CKMK_HANDLE_OPT_ITEM(func, io, type, loc, item, error, str) \
- if (0 == (item)->loc.size) { \
- (void) func(io, type, &(item)->loc, str); \
- } \
- return &(item)->loc ;
-
-#define CKMK_HANDLE_BOOL_ITEM(io, type, loc, item, error, str) \
- CKMK_HANDLE_ITEM(ckmk_GetBoolAttribute, io, type, loc, item, error, str)
-#define CKMK_HANDLE_DATA_ITEM(io, type, loc, item, error, str) \
- CKMK_HANDLE_ITEM(ckmk_GetDataAttribute, io, type, loc, item, error, str)
-#define CKMK_HANDLE_OPT_DATA_ITEM(io, type, loc, item, error, str) \
- CKMK_HANDLE_OPT_ITEM(ckmk_GetDataAttribute, io, type, loc, item, error, str)
-
-/*
- * fetch the unique identifier for each object type.
- */
-static void
-ckmk_FetchHashKey
-(
- ckmkInternalObject *io
-)
-{
- NSSItem *key = &io->hashKey;
-
- if (io->objClass == CKO_CERTIFICATE) {
- ckmk_GetCommonAttribute(io, kSecCertEncodingItemAttr,
- PR_TRUE, key, "Fetching HashKey (cert)");
- } else {
- ckmk_GetCommonAttribute(io, kSecKeyLabel,
- PR_FALSE, key, "Fetching HashKey (key)");
- }
-}
-
-/*
- * Apple mucks with the actual subject and issuer, so go fetch
- * the real ones ourselves.
- */
-static void
-ckmk_fetchCert
-(
- ckmkInternalObject *io
-)
-{
- CK_RV error;
- unsigned char * cert, *next;
- int certSize, thisEntrySize;
-
- error = ckmk_GetCommonAttribute(io, kSecCertEncodingItemAttr, PR_TRUE,
- &io->u.item.derCert, "Fetching Value (cert)");
- if (CKR_OK != error) {
- return;
- }
- /* unwrap the cert bundle */
- cert = nss_ckmk_DERUnwrap((unsigned char *)io->u.item.derCert.data,
- io->u.item.derCert.size,
- &certSize, NULL);
- /* unwrap the cert itself */
- /* cert == certdata */
- cert = nss_ckmk_DERUnwrap(cert, certSize, &certSize, NULL);
-
- /* skip the optional version */
- if ((cert[0] & 0xa0) == 0xa0) {
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- certSize -= next - cert;
- cert = next;
- }
- /* skip the serial number */
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- certSize -= next - cert;
- cert = next;
-
- /* skip the OID */
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- certSize -= next - cert;
- cert = next;
-
- /* save the (wrapped) issuer */
- io->u.item.issuer.data = cert;
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- io->u.item.issuer.size = next - cert;
- certSize -= io->u.item.issuer.size;
- cert = next;
-
- /* skip the OID */
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- certSize -= next - cert;
- cert = next;
-
- /* save the (wrapped) subject */
- io->u.item.subject.data = cert;
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- io->u.item.subject.size = next - cert;
- certSize -= io->u.item.subject.size;
- cert = next;
-}
-
-static void
-ckmk_fetchModulus
-(
- ckmkInternalObject *io
-)
-{
- NSSItem item;
- PRInt32 modLen;
- CK_RV error;
-
- /* we can't reliably get the modulus for private keys through CSSM (sigh).
- * For NSS this is OK because we really only use this to get the modulus
- * length (unless we are trying to get a public key from a private keys,
- * something CSSM ALSO does not do!).
- */
- error = ckmk_GetDataAttribute(io, kSecKeyKeySizeInBits, &item,
- "Key Fetch Modulus");
- if (CKR_OK != error) {
- return;
- }
-
- modLen = *(PRInt32 *)item.data;
- modLen = modLen/8; /* convert from bits to bytes */
-
- nss_ZFreeIf(item.data);
- io->u.item.modulus.data = nss_ZNEWARRAY(NULL, char, modLen);
- if (NULL == io->u.item.modulus.data) {
- return;
- }
- *(char *)io->u.item.modulus.data = 0x80; /* fake NSS out or it will
- * drop the first byte */
- io->u.item.modulus.size = modLen;
- return;
-}
-
-const NSSItem *
-ckmk_FetchCertAttribute
-(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError
-)
-{
- ckmkItemObject *item = &io->u.item;
- *pError = CKR_OK;
- switch(type) {
- case CKA_CLASS:
- return &ckmk_certClassItem;
- case CKA_TOKEN:
- case CKA_MODIFIABLE:
- return &ckmk_trueItem;
- case CKA_PRIVATE:
- return &ckmk_falseItem;
- case CKA_CERTIFICATE_TYPE:
- return &ckmk_x509Item;
- case CKA_LABEL:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecLabelItemAttr, label, item, *pError,
- "Cert:Label attr")
- case CKA_SUBJECT:
- /* OK, well apple does provide an subject and issuer attribute, but they
- * decided to cannonicalize that value. Probably a good move for them,
- * but makes it useless for most users of PKCS #11.. Get the real subject
- * from the certificate */
- if (0 == item->derCert.size) {
- ckmk_fetchCert(io);
- }
- return &item->subject;
- case CKA_ISSUER:
- if (0 == item->derCert.size) {
- ckmk_fetchCert(io);
- }
- return &item->issuer;
- case CKA_SERIAL_NUMBER:
- CKMK_HANDLE_DATA_ITEM(io, kSecSerialNumberItemAttr, serial, item, *pError,
- "Cert:Serial Number attr")
- case CKA_VALUE:
- if (0 == item->derCert.size) {
- ckmk_fetchCert(io);
- }
- return &item->derCert;
- case CKA_ID:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecPublicKeyHashItemAttr, id, item, *pError,
- "Cert:ID attr")
- default:
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- break;
- }
- return NULL;
-}
-
-const NSSItem *
-ckmk_FetchPubKeyAttribute
-(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError
-)
-{
- ckmkItemObject *item = &io->u.item;
- *pError = CKR_OK;
-
- switch(type) {
- case CKA_CLASS:
- return &ckmk_pubKeyClassItem;
- case CKA_TOKEN:
- case CKA_LOCAL:
- return &ckmk_trueItem;
- case CKA_KEY_TYPE:
- return &ckmk_rsaItem;
- case CKA_LABEL:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecKeyPrintName, label, item, *pError,
- "PubKey:Label attr")
- case CKA_ENCRYPT:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyEncrypt, encrypt, item, *pError,
- "PubKey:Encrypt attr")
- case CKA_VERIFY:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyVerify, verify, item, *pError,
- "PubKey:Verify attr")
- case CKA_VERIFY_RECOVER:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyVerifyRecover, verifyRecover,
- item, *pError, "PubKey:VerifyRecover attr")
- case CKA_PRIVATE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyPrivate, private, item, *pError,
- "PubKey:Private attr")
- case CKA_MODIFIABLE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyModifiable, modify, item, *pError,
- "PubKey:Modify attr")
- case CKA_DERIVE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyDerive, derive, item, *pError,
- "PubKey:Derive attr")
- case CKA_WRAP:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyWrap, wrap, item, *pError,
- "PubKey:Wrap attr")
- case CKA_SUBJECT:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecSubjectItemAttr, subject, item, *pError,
- "PubKey:Subect attr")
- case CKA_MODULUS:
- return &ckmk_emptyItem;
- case CKA_PUBLIC_EXPONENT:
- return &ckmk_emptyItem;
- case CKA_ID:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecKeyLabel, id, item, *pError,
- "PubKey:ID attr")
- default:
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- break;
- }
- return NULL;
-}
-
-const NSSItem *
-ckmk_FetchPrivKeyAttribute
-(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError
-)
-{
- ckmkItemObject *item = &io->u.item;
- *pError = CKR_OK;
-
- switch(type) {
- case CKA_CLASS:
- return &ckmk_privKeyClassItem;
- case CKA_TOKEN:
- case CKA_LOCAL:
- return &ckmk_trueItem;
- case CKA_SENSITIVE:
- case CKA_EXTRACTABLE: /* will probably move in the future */
- case CKA_ALWAYS_SENSITIVE:
- case CKA_NEVER_EXTRACTABLE:
- return &ckmk_falseItem;
- case CKA_KEY_TYPE:
- return &ckmk_rsaItem;
- case CKA_LABEL:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecKeyPrintName, label, item, *pError,
- "PrivateKey:Label attr")
- case CKA_DECRYPT:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyDecrypt, decrypt, item, *pError,
- "PrivateKey:Decrypt attr")
- case CKA_SIGN:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeySign, sign, item, *pError,
- "PrivateKey:Sign attr")
- case CKA_SIGN_RECOVER:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeySignRecover, signRecover, item, *pError,
- "PrivateKey:Sign Recover attr")
- case CKA_PRIVATE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyPrivate, private, item, *pError,
- "PrivateKey:Private attr")
- case CKA_MODIFIABLE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyModifiable, modify, item, *pError,
- "PrivateKey:Modify attr")
- case CKA_DERIVE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyDerive, derive, item, *pError,
- "PrivateKey:Derive attr")
- case CKA_UNWRAP:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyUnwrap, unwrap, item, *pError,
- "PrivateKey:Unwrap attr")
- case CKA_SUBJECT:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecSubjectItemAttr, subject, item, *pError,
- "PrivateKey:Subject attr")
- case CKA_MODULUS:
- if (0 == item->modulus.size) {
- ckmk_fetchModulus(io);
- }
- return &item->modulus;
- case CKA_PUBLIC_EXPONENT:
- return &ckmk_emptyItem;
-#ifdef notdef
- /* the following are sensitive attributes. We could implement them for
- * sensitive keys using the key export function, but it's better to
- * just support wrap through this token. That will more reliably allow us
- * to export any private key that is truly exportable.
- */
- case CKA_PRIVATE_EXPONENT:
- CKMK_HANDLE_DATA_ITEM(io, kSecPrivateExponentItemAttr, privateExponent,
- item, *pError)
- case CKA_PRIME_1:
- CKMK_HANDLE_DATA_ITEM(io, kSecPrime1ItemAttr, prime1, item, *pError)
- case CKA_PRIME_2:
- CKMK_HANDLE_DATA_ITEM(io, kSecPrime2ItemAttr, prime2, item, *pError)
- case CKA_EXPONENT_1:
- CKMK_HANDLE_DATA_ITEM(io, kSecExponent1ItemAttr, exponent1, item, *pError)
- case CKA_EXPONENT_2:
- CKMK_HANDLE_DATA_ITEM(io, kSecExponent2ItemAttr, exponent2, item, *pError)
- case CKA_COEFFICIENT:
- CKMK_HANDLE_DATA_ITEM(io, kSecCoefficientItemAttr, coefficient,
- item, *pError)
-#endif
- case CKA_ID:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecKeyLabel, id, item, *pError,
- "PrivateKey:ID attr")
- default:
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return NULL;
- }
-}
-
-const NSSItem *
-nss_ckmk_FetchAttribute
-(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError
-)
-{
- CK_ULONG i;
- const NSSItem * value = NULL;
-
- if (io->type == ckmkRaw) {
- for( i = 0; i < io->u.raw.n; i++ ) {
- if( type == io->u.raw.types[i] ) {
- return &io->u.raw.items[i];
- }
- }
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return NULL;
- }
- /* deal with the common attributes */
- switch (io->objClass) {
- case CKO_CERTIFICATE:
- value = ckmk_FetchCertAttribute(io, type, pError);
- break;
- case CKO_PRIVATE_KEY:
- value = ckmk_FetchPrivKeyAttribute(io, type, pError);
- break;
- case CKO_PUBLIC_KEY:
- value = ckmk_FetchPubKeyAttribute(io, type, pError);
- break;
- default:
- *pError = CKR_OBJECT_HANDLE_INVALID;
- return NULL;
- }
-
-#ifdef DEBUG
- if (CKA_ID == type) {
- itemdump("id: ", value->data, value->size, *pError);
- }
-#endif
- return value;
-}
-
-static void
-ckmk_removeObjectFromHash
-(
- ckmkInternalObject *io
-);
-
-/*
- *
- * These are the MSObject functions we need to implement
- *
- * Finalize - unneeded (actually we should clean up the hashtables)
- * Destroy
- * IsTokenObject - CK_TRUE
- * GetAttributeCount
- * GetAttributeTypes
- * GetAttributeSize
- * GetAttribute
- * SetAttribute
- * GetObjectSize
- */
-
-static CK_RV
-ckmk_mdObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
- OSStatus macErr;
-
- if (ckmkRaw == io->type) {
- /* there is not 'object write protected' error, use the next best thing */
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* This API is done well. The following 4 lines are the complete apple
- * specific part of this implementation */
- macErr = SecKeychainItemDelete(io->u.item.itemRef);
- if (noErr != macErr) {
- CKMK_MACERR("Delete object", macErr);
- }
-
- /* remove it from the hash */
- ckmk_removeObjectFromHash(io);
-
- /* free the puppy.. */
- nss_ckmk_DestroyInternalObject(io);
-
- return CKR_OK;
-}
-
-static CK_BBOOL
-ckmk_mdObject_IsTokenObject
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_TRUE;
-}
-
-static CK_ULONG
-ckmk_mdObject_GetAttributeCount
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
-
- if (ckmkRaw == io->type) {
- return io->u.raw.n;
- }
- switch (io->objClass) {
- case CKO_CERTIFICATE:
- return certAttrsCount;
- case CKO_PUBLIC_KEY:
- return pubKeyAttrsCount;
- case CKO_PRIVATE_KEY:
- return privKeyAttrsCount;
- default:
- break;
- }
- return 0;
-}
-
-static CK_RV
-ckmk_mdObject_GetAttributeTypes
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
- CK_ULONG i;
- CK_RV error = CKR_OK;
- const CK_ATTRIBUTE_TYPE *attrs = NULL;
- CK_ULONG size = ckmk_mdObject_GetAttributeCount(
- mdObject, fwObject, mdSession, fwSession,
- mdToken, fwToken, mdInstance, fwInstance, &error);
-
- if( size != ulCount ) {
- return CKR_BUFFER_TOO_SMALL;
- }
- if (io->type == ckmkRaw) {
- attrs = io->u.raw.types;
- } else switch(io->objClass) {
- case CKO_CERTIFICATE:
- attrs = certAttrs;
- break;
- case CKO_PUBLIC_KEY:
- attrs = pubKeyAttrs;
- break;
- case CKO_PRIVATE_KEY:
- attrs = privKeyAttrs;
- break;
- default:
- return CKR_OK;
- }
-
- for( i = 0; i < size; i++) {
- typeArray[i] = attrs[i];
- }
-
- return CKR_OK;
-}
-
-static CK_ULONG
-ckmk_mdObject_GetAttributeSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
-
- const NSSItem *b;
-
- b = nss_ckmk_FetchAttribute(io, attribute, pError);
-
- if ((const NSSItem *)NULL == b) {
- return 0;
- }
- return b->size;
-}
-
-static CK_RV
-ckmk_mdObject_SetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value
-)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
- SecKeychainItemRef itemRef;
-
- if (io->type == ckmkRaw) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
- itemRef = io->u.item.itemRef;
-
- switch (io->objClass) {
- case CKO_PRIVATE_KEY:
- case CKO_PUBLIC_KEY:
- switch (attribute) {
- case CKA_ID:
- ckmk_updateAttribute(itemRef, kSecKeyLabel,
- value->data, value->size, "Set Attr Key ID");
-#ifdef DEBUG
- itemdump("key id: ", value->data, value->size, CKR_OK);
-#endif
- break;
- case CKA_LABEL:
- ckmk_updateAttribute(itemRef, kSecKeyPrintName, value->data,
- value->size, "Set Attr Key Label");
- break;
- default:
- break;
- }
- break;
-
- case CKO_CERTIFICATE:
- switch (attribute) {
- case CKA_ID:
- ckmk_updateAttribute(itemRef, kSecPublicKeyHashItemAttr,
- value->data, value->size, "Set Attr Cert ID");
- break;
- case CKA_LABEL:
- ckmk_updateAttribute(itemRef, kSecLabelItemAttr, value->data,
- value->size, "Set Attr Cert Label");
- break;
- default:
- break;
- }
- break;
-
- default:
- break;
- }
- return CKR_OK;
-}
-
-static NSSCKFWItem
-ckmk_mdObject_GetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- NSSCKFWItem mdItem;
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
-
- mdItem.needsFreeing = PR_FALSE;
- mdItem.item = (NSSItem*)nss_ckmk_FetchAttribute(io, attribute, pError);
-
-
- return mdItem;
-}
-
-static CK_ULONG
-ckmk_mdObject_GetObjectSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- CK_ULONG rv = 1;
-
- /* size is irrelevant to this token */
- return rv;
-}
-
-static const NSSCKMDObject
-ckmk_prototype_mdObject = {
- (void *)NULL, /* etc */
- NULL, /* Finalize */
- ckmk_mdObject_Destroy,
- ckmk_mdObject_IsTokenObject,
- ckmk_mdObject_GetAttributeCount,
- ckmk_mdObject_GetAttributeTypes,
- ckmk_mdObject_GetAttributeSize,
- ckmk_mdObject_GetAttribute,
- NULL, /* FreeAttribute */
- ckmk_mdObject_SetAttribute,
- ckmk_mdObject_GetObjectSize,
- (void *)NULL /* null terminator */
-};
-
-static nssHash *ckmkInternalObjectHash = NULL;
-
-NSS_IMPLEMENT NSSCKMDObject *
-nss_ckmk_CreateMDObject
-(
- NSSArena *arena,
- ckmkInternalObject *io,
- CK_RV *pError
-)
-{
- if ((nssHash *)NULL == ckmkInternalObjectHash) {
- ckmkInternalObjectHash = nssHash_CreateItem(NULL, 10);
- }
- if (ckmkItem == io->type) {
- /* the hash key, not a cryptographic key */
- NSSItem *key = &io->hashKey;
- ckmkInternalObject *old_o = NULL;
-
- if (key->size == 0) {
- ckmk_FetchHashKey(io);
- }
- old_o = (ckmkInternalObject *)
- nssHash_Lookup(ckmkInternalObjectHash, key);
- if (!old_o) {
- nssHash_Add(ckmkInternalObjectHash, key, io);
- } else if (old_o != io) {
- nss_ckmk_DestroyInternalObject(io);
- io = old_o;
- }
- }
-
- if ( (void*)NULL == io->mdObject.etc) {
- (void) nsslibc_memcpy(&io->mdObject,&ckmk_prototype_mdObject,
- sizeof(ckmk_prototype_mdObject));
- io->mdObject.etc = (void *)io;
- }
- return &io->mdObject;
-}
-
-static void
-ckmk_removeObjectFromHash
-(
- ckmkInternalObject *io
-)
-{
- NSSItem *key = &io->hashKey;
-
- if ((nssHash *)NULL == ckmkInternalObjectHash) {
- return;
- }
- if (key->size == 0) {
- ckmk_FetchHashKey(io);
- }
- nssHash_Remove(ckmkInternalObjectHash, key);
- return;
-}
-
-
-void
-nss_ckmk_DestroyInternalObject
-(
- ckmkInternalObject *io
-)
-{
- switch (io->type) {
- case ckmkRaw:
- return;
- case ckmkItem:
- nss_ZFreeIf(io->u.item.modify.data);
- nss_ZFreeIf(io->u.item.private.data);
- nss_ZFreeIf(io->u.item.encrypt.data);
- nss_ZFreeIf(io->u.item.decrypt.data);
- nss_ZFreeIf(io->u.item.derive.data);
- nss_ZFreeIf(io->u.item.sign.data);
- nss_ZFreeIf(io->u.item.signRecover.data);
- nss_ZFreeIf(io->u.item.verify.data);
- nss_ZFreeIf(io->u.item.verifyRecover.data);
- nss_ZFreeIf(io->u.item.wrap.data);
- nss_ZFreeIf(io->u.item.unwrap.data);
- nss_ZFreeIf(io->u.item.label.data);
- /*nss_ZFreeIf(io->u.item.subject.data); */
- /*nss_ZFreeIf(io->u.item.issuer.data); */
- nss_ZFreeIf(io->u.item.serial.data);
- nss_ZFreeIf(io->u.item.modulus.data);
- nss_ZFreeIf(io->u.item.exponent.data);
- nss_ZFreeIf(io->u.item.privateExponent.data);
- nss_ZFreeIf(io->u.item.prime1.data);
- nss_ZFreeIf(io->u.item.prime2.data);
- nss_ZFreeIf(io->u.item.exponent1.data);
- nss_ZFreeIf(io->u.item.exponent2.data);
- nss_ZFreeIf(io->u.item.coefficient.data);
- break;
- }
- nss_ZFreeIf(io);
- return;
-}
-
-
-static ckmkInternalObject *
-nss_ckmk_NewInternalObject
-(
- CK_OBJECT_CLASS objClass,
- SecKeychainItemRef itemRef,
- SecItemClass itemClass,
- CK_RV *pError
-)
-{
- ckmkInternalObject *io = nss_ZNEW(NULL, ckmkInternalObject);
-
- if ((ckmkInternalObject *)NULL == io) {
- *pError = CKR_HOST_MEMORY;
- return io;
- }
- io->type = ckmkItem;
- io->objClass = objClass;
- io->u.item.itemRef = itemRef;
- io->u.item.itemClass = itemClass;
- return io;
-}
-
-/*
- * Apple doesn't alway have a default keyChain set by the OS, use the
- * SearchList to try to find one.
- */
-static CK_RV
-ckmk_GetSafeDefaultKeychain
-(
- SecKeychainRef *keychainRef
-)
-{
- OSStatus macErr;
- CFArrayRef searchList = 0;
- CK_RV error = CKR_OK;
-
- macErr = SecKeychainCopyDefault(keychainRef);
- if (noErr != macErr) {
- int searchCount = 0;
- if (errSecNoDefaultKeychain != macErr) {
- CKMK_MACERR("Getting default key chain", macErr);
- error = CKR_GENERAL_ERROR;
- goto loser;
- }
- /* ok, we don't have a default key chain, find one */
- macErr = SecKeychainCopySearchList(&searchList);
- if (noErr != macErr) {
- CKMK_MACERR("failed to find a keyring searchList", macErr);
- error = CKR_DEVICE_REMOVED;
- goto loser;
- }
- searchCount = CFArrayGetCount(searchList);
- if (searchCount < 1) {
- error = CKR_DEVICE_REMOVED;
- goto loser;
- }
- *keychainRef =
- (SecKeychainRef)CFRetain(CFArrayGetValueAtIndex(searchList, 0));
- if (0 == *keychainRef) {
- error = CKR_DEVICE_REMOVED;
- goto loser;
- }
- /* should we set it as default? */
- }
-loser:
- if (0 != searchList) {
- CFRelease(searchList);
- }
- return error;
-}
-static ckmkInternalObject *
-nss_ckmk_CreateCertificate
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- NSSItem value;
- ckmkInternalObject *io = NULL;
- OSStatus macErr;
- SecCertificateRef certRef;
- SecKeychainItemRef itemRef;
- SecKeychainRef keychainRef;
- CSSM_DATA certData;
-
- *pError = nss_ckmk_GetAttribute(CKA_VALUE, pTemplate,
- ulAttributeCount, &value);
- if (CKR_OK != *pError) {
- goto loser;
- }
-
- certData.Data = value.data;
- certData.Length = value.size;
- macErr = SecCertificateCreateFromData(&certData, CSSM_CERT_X_509v3,
- CSSM_CERT_ENCODING_BER, &certRef);
- if (noErr != macErr) {
- CKMK_MACERR("Create cert from data Failed", macErr);
- *pError = CKR_GENERAL_ERROR; /* need to map macErr */
- goto loser;
- }
-
- *pError = ckmk_GetSafeDefaultKeychain(&keychainRef);
- if (CKR_OK != *pError) {
- goto loser;
- }
-
- macErr = SecCertificateAddToKeychain( certRef, keychainRef);
- itemRef = (SecKeychainItemRef) certRef;
- if (errSecDuplicateItem != macErr) {
- NSSItem keyID = { NULL, 0 };
- char *nickname = NULL;
- CK_RV dummy;
-
- if (noErr != macErr) {
- CKMK_MACERR("Add cert to keychain Failed", macErr);
- *pError = CKR_GENERAL_ERROR; /* need to map macErr */
- goto loser;
- }
- /* these two are optional */
- nickname = nss_ckmk_GetStringAttribute(CKA_LABEL, pTemplate,
- ulAttributeCount, &dummy);
- /* we've added a new one, update the attributes in the key ring */
- if (nickname) {
- ckmk_updateAttribute(itemRef, kSecLabelItemAttr, nickname,
- strlen(nickname)+1, "Modify Cert Label");
- nss_ZFreeIf(nickname);
- }
- dummy = nss_ckmk_GetAttribute(CKA_ID, pTemplate,
- ulAttributeCount, &keyID);
- if (CKR_OK == dummy) {
- dummy = ckmk_updateAttribute(itemRef, kSecPublicKeyHashItemAttr,
- keyID.data, keyID.size, "Modify Cert ID");
- }
- }
-
- io = nss_ckmk_NewInternalObject(CKO_CERTIFICATE, itemRef,
- kSecCertificateItemClass, pError);
- if ((ckmkInternalObject *)NULL != io) {
- itemRef = 0;
- }
-
-loser:
- if (0 != itemRef) {
- CFRelease(itemRef);
- }
- if (0 != keychainRef) {
- CFRelease(keychainRef);
- }
-
- return io;
-}
-
-/*
- * PKCS #8 attributes
- */
-struct ckmk_AttributeStr {
- SECItem attrType;
- SECItem *attrValue;
-};
-typedef struct ckmk_AttributeStr ckmk_Attribute;
-
-/*
-** A PKCS#8 private key info object
-*/
-struct PrivateKeyInfoStr {
- PLArenaPool *arena;
- SECItem version;
- SECAlgorithmID algorithm;
- SECItem privateKey;
- ckmk_Attribute **attributes;
-};
-typedef struct PrivateKeyInfoStr PrivateKeyInfo;
-
-const SEC_ASN1Template ckmk_RSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RSAPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey,version) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey,modulus) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey,publicExponent) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey,privateExponent) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey,prime1) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey,prime2) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey,exponent1) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey,exponent2) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey,coefficient) },
- { 0 }
-};
-
-const SEC_ASN1Template ckmk_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ckmk_Attribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(ckmk_Attribute, attrType) },
- { SEC_ASN1_SET_OF, offsetof(ckmk_Attribute, attrValue),
- SEC_AnyTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template ckmk_SetOfAttributeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, ckmk_AttributeTemplate },
-};
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-/* ASN1 Templates for new decoder/encoder */
-const SEC_ASN1Template ckmk_PrivateKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PrivateKeyInfo) },
- { SEC_ASN1_INTEGER, offsetof(PrivateKeyInfo,version) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(PrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING, offsetof(PrivateKeyInfo,privateKey) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(PrivateKeyInfo, attributes), ckmk_SetOfAttributeTemplate },
- { 0 }
-};
-
-#define CKMK_PRIVATE_KEY_INFO_VERSION 0
-static CK_RV
-ckmk_CreateRSAKeyBlob
-(
- RSAPrivateKey *lk,
- NSSItem *keyBlob
-)
-{
- PrivateKeyInfo *pki = NULL;
- PLArenaPool *arena = NULL;
- SECOidTag algorithm = SEC_OID_UNKNOWN;
- void *dummy;
- SECStatus rv;
- SECItem *encodedKey = NULL;
- CK_RV error = CKR_OK;
-
- arena = PORT_NewArena(2048); /* XXX different size? */
- if(!arena) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- pki = (PrivateKeyInfo*)PORT_ArenaZAlloc(arena, sizeof(PrivateKeyInfo));
- if(!pki) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- pki->arena = arena;
-
- dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
- ckmk_RSAPrivateKeyTemplate);
- algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
-
- if (!dummy) {
- error = CKR_DEVICE_ERROR; /* should map NSS SECError */
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm,
- (SECItem*)NULL);
- if (rv != SECSuccess) {
- error = CKR_DEVICE_ERROR; /* should map NSS SECError */
- goto loser;
- }
-
- dummy = SEC_ASN1EncodeInteger(arena, &pki->version,
- CKMK_PRIVATE_KEY_INFO_VERSION);
- if (!dummy) {
- error = CKR_DEVICE_ERROR; /* should map NSS SECError */
- goto loser;
- }
-
- encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki,
- ckmk_PrivateKeyInfoTemplate);
- if (!encodedKey) {
- error = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- keyBlob->data = nss_ZNEWARRAY(NULL, char, encodedKey->len);
- if (NULL == keyBlob->data) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- nsslibc_memcpy(keyBlob->data, encodedKey->data, encodedKey->len);
- keyBlob->size = encodedKey->len;
-
-loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
- if (encodedKey) {
- SECITEM_FreeItem(encodedKey, PR_TRUE);
- }
-
- return error;
-}
-/*
- * There MUST be a better way to do this. For now, find the key based on the
- * default name Apple gives it once we import.
- */
-#define IMPORTED_NAME "Imported Private Key"
-static CK_RV
-ckmk_FindImportedKey
-(
- SecKeychainRef keychainRef,
- SecItemClass itemClass,
- SecKeychainItemRef *outItemRef
-)
-{
- OSStatus macErr;
- SecKeychainSearchRef searchRef = 0;
- SecKeychainItemRef newItemRef;
-
- macErr = SecKeychainSearchCreateFromAttributes(keychainRef, itemClass,
- NULL, &searchRef);
- if (noErr != macErr) {
- CKMK_MACERR("Can't search for Key", macErr);
- return CKR_GENERAL_ERROR;
- }
- while (noErr == SecKeychainSearchCopyNext(searchRef, &newItemRef)) {
- SecKeychainAttributeList *attrList = NULL;
- SecKeychainAttributeInfo attrInfo;
- SecItemAttr itemAttr = kSecKeyPrintName;
- PRUint32 attrFormat = 0;
- OSStatus macErr;
-
- attrInfo.count = 1;
- attrInfo.tag = &itemAttr;
- attrInfo.format = &attrFormat;
-
- macErr = SecKeychainItemCopyAttributesAndData(newItemRef,
- &attrInfo, NULL, &attrList, NULL, NULL);
- if (noErr == macErr) {
- if (nsslibc_memcmp(attrList->attr->data, IMPORTED_NAME,
- attrList->attr->length, NULL) == 0) {
- *outItemRef = newItemRef;
- CFRelease (searchRef);
- SecKeychainItemFreeAttributesAndData(attrList, NULL);
- return CKR_OK;
- }
- SecKeychainItemFreeAttributesAndData(attrList, NULL);
- }
- CFRelease(newItemRef);
- }
- CFRelease (searchRef);
- return CKR_GENERAL_ERROR; /* we can come up with something better! */
-}
-
-static ckmkInternalObject *
-nss_ckmk_CreatePrivateKey
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- NSSItem attribute;
- RSAPrivateKey lk;
- NSSItem keyID;
- char *nickname = NULL;
- ckmkInternalObject *io = NULL;
- CK_KEY_TYPE keyType;
- OSStatus macErr;
- SecKeychainItemRef itemRef = 0;
- NSSItem keyBlob = { NULL, 0 };
- CFDataRef dataRef = 0;
- SecExternalFormat inputFormat = kSecFormatBSAFE;
- /*SecExternalFormat inputFormat = kSecFormatOpenSSL; */
- SecExternalItemType itemType = kSecItemTypePrivateKey;
- SecKeyImportExportParameters keyParams ;
- SecKeychainRef targetKeychain = 0;
- unsigned char zero = 0;
- CK_RV error;
-
- keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
- keyParams.flags = 0;
- keyParams.passphrase = 0;
- keyParams.alertTitle = 0;
- keyParams.alertPrompt = 0;
- keyParams.accessRef = 0; /* default */
- keyParams.keyUsage = 0; /* will get filled in */
- keyParams.keyAttributes = CSSM_KEYATTR_PERMANENT; /* will get filled in */
- keyType = nss_ckmk_GetULongAttribute
- (CKA_KEY_TYPE, pTemplate, ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- if (CKK_RSA != keyType) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (ckmkInternalObject *)NULL;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_DECRYPT,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyUsage |= CSSM_KEYUSE_DECRYPT;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_UNWRAP,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyUsage |= CSSM_KEYUSE_UNWRAP;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_SIGN,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyUsage |= CSSM_KEYUSE_SIGN;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_DERIVE,
- pTemplate, ulAttributeCount, CK_FALSE)) {
- keyParams.keyUsage |= CSSM_KEYUSE_DERIVE;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_SENSITIVE,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyAttributes |= CSSM_KEYATTR_SENSITIVE;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_EXTRACTABLE,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyAttributes |= CSSM_KEYATTR_EXTRACTABLE;
- }
-
- lk.version.type = siUnsignedInteger;
- lk.version.data = &zero;
- lk.version.len = 1;
-
- *pError = nss_ckmk_GetAttribute(CKA_MODULUS, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.modulus.type = siUnsignedInteger;
- lk.modulus.data = attribute.data;
- lk.modulus.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_PUBLIC_EXPONENT, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.publicExponent.type = siUnsignedInteger;
- lk.publicExponent.data = attribute.data;
- lk.publicExponent.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_PRIVATE_EXPONENT, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.privateExponent.type = siUnsignedInteger;
- lk.privateExponent.data = attribute.data;
- lk.privateExponent.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_PRIME_1, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.prime1.type = siUnsignedInteger;
- lk.prime1.data = attribute.data;
- lk.prime1.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_PRIME_2, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.prime2.type = siUnsignedInteger;
- lk.prime2.data = attribute.data;
- lk.prime2.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_EXPONENT_1, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.exponent1.type = siUnsignedInteger;
- lk.exponent1.data = attribute.data;
- lk.exponent1.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_EXPONENT_2, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.exponent2.type = siUnsignedInteger;
- lk.exponent2.data = attribute.data;
- lk.exponent2.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_COEFFICIENT, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.coefficient.type = siUnsignedInteger;
- lk.coefficient.data = attribute.data;
- lk.coefficient.len = attribute.size;
-
- /* ASN1 Encode the pkcs8 structure... look at softoken to see how this
- * is done... */
- error = ckmk_CreateRSAKeyBlob(&lk, &keyBlob);
- if (CKR_OK != error) {
- goto loser;
- }
-
- dataRef = CFDataCreate(NULL, (UInt8 *)keyBlob.data, keyBlob.size);
- if (0 == dataRef) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- *pError == ckmk_GetSafeDefaultKeychain(&targetKeychain);
- if (CKR_OK != *pError) {
- goto loser;
- }
-
-
- /* the itemArray that is returned is useless. the item does not
- * is 'not on the key chain' so none of the modify calls work on it.
- * It also has a key that isn't the same key as the one in the actual
- * key chain. In short it isn't the item we want, and it gives us zero
- * information about the item we want, so don't even bother with it...
- */
- macErr = SecKeychainItemImport(dataRef, NULL, &inputFormat, &itemType, 0,
- &keyParams, targetKeychain, NULL);
- if (noErr != macErr) {
- CKMK_MACERR("Import Private Key", macErr);
- *pError = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- *pError = ckmk_FindImportedKey(targetKeychain,
- CSSM_DL_DB_RECORD_PRIVATE_KEY,
- &itemRef);
- if (CKR_OK != *pError) {
-#ifdef DEBUG
- fprintf(stderr,"couldn't find key in keychain \n");
-#endif
- goto loser;
- }
-
-
- /* set the CKA_ID and the CKA_LABEL */
- error = nss_ckmk_GetAttribute(CKA_ID, pTemplate,
- ulAttributeCount, &keyID);
- if (CKR_OK == error) {
- error = ckmk_updateAttribute(itemRef, kSecKeyLabel,
- keyID.data, keyID.size, "Modify Key ID");
-#ifdef DEBUG
- itemdump("key id: ", keyID.data, keyID.size, error);
-#endif
- }
- nickname = nss_ckmk_GetStringAttribute(CKA_LABEL, pTemplate,
- ulAttributeCount, &error);
- if (nickname) {
- ckmk_updateAttribute(itemRef, kSecKeyPrintName, nickname,
- strlen(nickname)+1, "Modify Key Label");
- } else {
-#define DEFAULT_NICKNAME "NSS Imported Key"
- ckmk_updateAttribute(itemRef, kSecKeyPrintName, DEFAULT_NICKNAME,
- sizeof(DEFAULT_NICKNAME), "Modify Key Label");
- }
-
- io = nss_ckmk_NewInternalObject(CKO_PRIVATE_KEY, itemRef,
- CSSM_DL_DB_RECORD_PRIVATE_KEY, pError);
- if ((ckmkInternalObject *)NULL == io) {
- CFRelease(itemRef);
- }
-
- return io;
-
-loser:
- /* free the key blob */
- if (keyBlob.data) {
- nss_ZFreeIf(keyBlob.data);
- }
- if (0 != targetKeychain) {
- CFRelease(targetKeychain);
- }
- if (0 != dataRef) {
- CFRelease(dataRef);
- }
- return io;
-}
-
-
-NSS_EXTERN NSSCKMDObject *
-nss_ckmk_CreateObject
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- CK_OBJECT_CLASS objClass;
- ckmkInternalObject *io;
- CK_BBOOL isToken;
-
- /*
- * only create token objects
- */
- isToken = nss_ckmk_GetBoolAttribute(CKA_TOKEN, pTemplate,
- ulAttributeCount, CK_FALSE);
- if (!isToken) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (NSSCKMDObject *) NULL;
- }
-
- /*
- * only create keys and certs.
- */
- objClass = nss_ckmk_GetULongAttribute(CKA_CLASS, pTemplate,
- ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- return (NSSCKMDObject *) NULL;
- }
-#ifdef notdef
- if (objClass == CKO_PUBLIC_KEY) {
- return CKR_OK; /* fake public key creation, happens as a side effect of
- * private key creation */
- }
-#endif
- if (objClass == CKO_CERTIFICATE) {
- io = nss_ckmk_CreateCertificate(fwSession, pTemplate,
- ulAttributeCount, pError);
- } else if (objClass == CKO_PRIVATE_KEY) {
- io = nss_ckmk_CreatePrivateKey(fwSession, pTemplate,
- ulAttributeCount, pError);
- } else {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- if ((ckmkInternalObject *)NULL == io) {
- return (NSSCKMDObject *) NULL;
- }
- return nss_ckmk_CreateMDObject(NULL, io, pError);
-}
diff --git a/security/nss/lib/ckfw/nssmkey/mrsa.c b/security/nss/lib/ckfw/nssmkey/mrsa.c
deleted file mode 100644
index 37d698d5a..000000000
--- a/security/nss/lib/ckfw/nssmkey/mrsa.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckmk.h"
-
-/* Sigh, For all the talk about 'ease of use', apple has hidden the interfaces
- * needed to be able to truly use CSSM. These came from their modification
- * to NSS's S/MIME code. The following two functions currently are not
- * part of the SecKey.h interface.
- */
-OSStatus
-SecKeyGetCredentials
-(
- SecKeyRef keyRef,
- CSSM_ACL_AUTHORIZATION_TAG authTag,
- int type,
- const CSSM_ACCESS_CREDENTIALS **creds
-);
-
-/* this function could be implemented using 'SecKeychainItemCopyKeychain' and
- * 'SecKeychainGetCSPHandle' */
-OSStatus
-SecKeyGetCSPHandle
-(
- SecKeyRef keyRef,
- CSSM_CSP_HANDLE *cspHandle
-);
-
-
-typedef struct ckmkInternalCryptoOperationRSAPrivStr
- ckmkInternalCryptoOperationRSAPriv;
-struct ckmkInternalCryptoOperationRSAPrivStr
-{
- NSSCKMDCryptoOperation mdOperation;
- NSSCKMDMechanism *mdMechanism;
- ckmkInternalObject *iKey;
- NSSItem *buffer;
- CSSM_CC_HANDLE cssmContext;
-};
-
-typedef enum {
- CKMK_DECRYPT,
- CKMK_SIGN
-} ckmkRSAOpType;
-
-/*
- * ckmk_mdCryptoOperationRSAPriv_Create
- */
-static NSSCKMDCryptoOperation *
-ckmk_mdCryptoOperationRSAPriv_Create
-(
- const NSSCKMDCryptoOperation *proto,
- NSSCKMDMechanism *mdMechanism,
- NSSCKMDObject *mdKey,
- ckmkRSAOpType type,
- CK_RV *pError
-)
-{
- ckmkInternalObject *iKey = (ckmkInternalObject *)mdKey->etc;
- const NSSItem *classItem = nss_ckmk_FetchAttribute(iKey, CKA_CLASS, pError);
- const NSSItem *keyType = nss_ckmk_FetchAttribute(iKey, CKA_KEY_TYPE, pError);
- ckmkInternalCryptoOperationRSAPriv *iOperation;
- SecKeyRef privateKey;
- OSStatus macErr;
- CSSM_RETURN cssmErr;
- const CSSM_KEY *cssmKey;
- CSSM_CSP_HANDLE cspHandle;
- const CSSM_ACCESS_CREDENTIALS *creds = NULL;
- CSSM_CC_HANDLE cssmContext;
- CSSM_ACL_AUTHORIZATION_TAG authType;
-
- /* make sure we have the right objects */
- if (((const NSSItem *)NULL == classItem) ||
- (sizeof(CK_OBJECT_CLASS) != classItem->size) ||
- (CKO_PRIVATE_KEY != *(CK_OBJECT_CLASS *)classItem->data) ||
- ((const NSSItem *)NULL == keyType) ||
- (sizeof(CK_KEY_TYPE) != keyType->size) ||
- (CKK_RSA != *(CK_KEY_TYPE *)keyType->data)) {
- *pError = CKR_KEY_TYPE_INCONSISTENT;
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- privateKey = (SecKeyRef) iKey->u.item.itemRef;
- macErr = SecKeyGetCSSMKey(privateKey, &cssmKey);
- if (noErr != macErr) {
- CKMK_MACERR("Getting CSSM Key", macErr);
- *pError = CKR_KEY_HANDLE_INVALID;
- return (NSSCKMDCryptoOperation *)NULL;
- }
- macErr = SecKeyGetCSPHandle(privateKey, &cspHandle);
- if (noErr != macErr) {
- CKMK_MACERR("Getting CSP for Key", macErr);
- *pError = CKR_KEY_HANDLE_INVALID;
- return (NSSCKMDCryptoOperation *)NULL;
- }
- switch (type) {
- case CKMK_DECRYPT:
- authType = CSSM_ACL_AUTHORIZATION_DECRYPT;
- break;
- case CKMK_SIGN:
- authType = CSSM_ACL_AUTHORIZATION_SIGN;
- break;
- default:
- *pError = CKR_GENERAL_ERROR;
-#ifdef DEBUG
- fprintf(stderr,"RSAPriv_Create: bad type = %d\n", type);
-#endif
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- macErr = SecKeyGetCredentials(privateKey, authType, 0, &creds);
- if (noErr != macErr) {
- CKMK_MACERR("Getting Credentials for Key", macErr);
- *pError = CKR_KEY_HANDLE_INVALID;
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- switch (type) {
- case CKMK_DECRYPT:
- cssmErr = CSSM_CSP_CreateAsymmetricContext(cspHandle, CSSM_ALGID_RSA,
- creds, cssmKey, CSSM_PADDING_PKCS1, &cssmContext);
- break;
- case CKMK_SIGN:
- cssmErr = CSSM_CSP_CreateSignatureContext(cspHandle, CSSM_ALGID_RSA,
- creds, cssmKey, &cssmContext);
- break;
- default:
- *pError = CKR_GENERAL_ERROR;
-#ifdef DEBUG
- fprintf(stderr,"RSAPriv_Create: bad type = %d\n", type);
-#endif
- return (NSSCKMDCryptoOperation *)NULL;
- }
- if (noErr != cssmErr) {
- CKMK_MACERR("Getting Context for Key", cssmErr);
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- iOperation = nss_ZNEW(NULL, ckmkInternalCryptoOperationRSAPriv);
- if ((ckmkInternalCryptoOperationRSAPriv *)NULL == iOperation) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDCryptoOperation *)NULL;
- }
- iOperation->mdMechanism = mdMechanism;
- iOperation->iKey = iKey;
- iOperation->cssmContext = cssmContext;
-
- nsslibc_memcpy(&iOperation->mdOperation,
- proto, sizeof(NSSCKMDCryptoOperation));
- iOperation->mdOperation.etc = iOperation;
-
- return &iOperation->mdOperation;
-}
-
-static void
-ckmk_mdCryptoOperationRSAPriv_Destroy
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
-
- if (iOperation->buffer) {
- nssItem_Destroy(iOperation->buffer);
- }
- if (iOperation->cssmContext) {
- CSSM_DeleteContext(iOperation->cssmContext);
- }
- nss_ZFreeIf(iOperation);
- return;
-}
-
-static CK_ULONG
-ckmk_mdCryptoOperationRSA_GetFinalLength
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
- const NSSItem *modulus =
- nss_ckmk_FetchAttribute(iOperation->iKey, CKA_MODULUS, pError);
-
- return modulus->size;
-}
-
-
-/*
- * ckmk_mdCryptoOperationRSADecrypt_GetOperationLength
- * we won't know the length until we actually decrypt the
- * input block. Since we go to all the work to decrypt the
- * the block, we'll save if for when the block is asked for
- */
-static CK_ULONG
-ckmk_mdCryptoOperationRSADecrypt_GetOperationLength
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- CK_RV *pError
-)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
- CSSM_DATA cssmInput;
- CSSM_DATA cssmOutput = { 0, NULL };
- PRUint32 bytesDecrypted;
- CSSM_DATA remainder = { 0, NULL };
- NSSItem output;
- CSSM_RETURN cssmErr;
-
- if (iOperation->buffer) {
- return iOperation->buffer->size;
- }
-
- cssmInput.Data = input->data;
- cssmInput.Length = input->size;
-
- cssmErr = CSSM_DecryptData(iOperation->cssmContext,
- &cssmInput, 1, &cssmOutput, 1,
- &bytesDecrypted, &remainder);
- if (CSSM_OK != cssmErr) {
- CKMK_MACERR("Decrypt Failed", cssmErr);
- *pError = CKR_DATA_INVALID;
- return 0;
- }
- /* we didn't suppy any buffers, so it should all be in remainder */
- output.data = nss_ZNEWARRAY(NULL, char, bytesDecrypted + remainder.Length);
- if (NULL == output.data) {
- free(cssmOutput.Data);
- free(remainder.Data);
- *pError = CKR_HOST_MEMORY;
- return 0;
- }
- output.size = bytesDecrypted + remainder.Length;
-
- if (0 != bytesDecrypted) {
- nsslibc_memcpy(output.data, cssmOutput.Data, bytesDecrypted);
- free(cssmOutput.Data);
- }
- if (0 != remainder.Length) {
- nsslibc_memcpy(((char *)output.data)+bytesDecrypted,
- remainder.Data, remainder.Length);
- free(remainder.Data);
- }
-
- iOperation->buffer = nssItem_Duplicate(&output, NULL, NULL);
- nss_ZFreeIf(output.data);
- if ((NSSItem *) NULL == iOperation->buffer) {
- *pError = CKR_HOST_MEMORY;
- return 0;
- }
-
- return iOperation->buffer->size;
-}
-
-/*
- * ckmk_mdCryptoOperationRSADecrypt_UpdateFinal
- *
- * NOTE: ckmk_mdCryptoOperationRSADecrypt_GetOperationLength is presumed to
- * have been called previously.
- */
-static CK_RV
-ckmk_mdCryptoOperationRSADecrypt_UpdateFinal
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- NSSItem *output
-)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
- NSSItem *buffer = iOperation->buffer;
-
- if ((NSSItem *)NULL == buffer) {
- return CKR_GENERAL_ERROR;
- }
- nsslibc_memcpy(output->data, buffer->data, buffer->size);
- output->size = buffer->size;
- return CKR_OK;
-}
-
-/*
- * ckmk_mdCryptoOperationRSASign_UpdateFinal
- *
- */
-static CK_RV
-ckmk_mdCryptoOperationRSASign_UpdateFinal
-(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- NSSItem *output
-)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
- CSSM_DATA cssmInput;
- CSSM_DATA cssmOutput = { 0, NULL };
- CSSM_RETURN cssmErr;
-
- cssmInput.Data = input->data;
- cssmInput.Length = input->size;
-
- cssmErr = CSSM_SignData(iOperation->cssmContext, &cssmInput, 1,
- CSSM_ALGID_NONE, &cssmOutput);
- if (CSSM_OK != cssmErr) {
- CKMK_MACERR("Signed Failed", cssmErr);
- return CKR_FUNCTION_FAILED;
- }
- if (cssmOutput.Length > output->size) {
- free(cssmOutput.Data);
- return CKR_BUFFER_TOO_SMALL;
- }
- nsslibc_memcpy(output->data, cssmOutput.Data, cssmOutput.Length);
- free(cssmOutput.Data);
- output->size = cssmOutput.Length;
-
- return CKR_OK;
-}
-
-
-NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
-ckmk_mdCryptoOperationRSADecrypt_proto = {
- NULL, /* etc */
- ckmk_mdCryptoOperationRSAPriv_Destroy,
- NULL, /* GetFinalLengh - not needed for one shot Decrypt/Encrypt */
- ckmk_mdCryptoOperationRSADecrypt_GetOperationLength,
- NULL, /* Final - not needed for one shot operation */
- NULL, /* Update - not needed for one shot operation */
- NULL, /* DigetUpdate - not needed for one shot operation */
- ckmk_mdCryptoOperationRSADecrypt_UpdateFinal,
- NULL, /* UpdateCombo - not needed for one shot operation */
- NULL, /* DigetKey - not needed for one shot operation */
- (void *)NULL /* null terminator */
-};
-
-NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
-ckmk_mdCryptoOperationRSASign_proto = {
- NULL, /* etc */
- ckmk_mdCryptoOperationRSAPriv_Destroy,
- ckmk_mdCryptoOperationRSA_GetFinalLength,
- NULL, /* GetOperationLengh - not needed for one shot Sign/Verify */
- NULL, /* Final - not needed for one shot operation */
- NULL, /* Update - not needed for one shot operation */
- NULL, /* DigetUpdate - not needed for one shot operation */
- ckmk_mdCryptoOperationRSASign_UpdateFinal,
- NULL, /* UpdateCombo - not needed for one shot operation */
- NULL, /* DigetKey - not needed for one shot operation */
- (void *)NULL /* null terminator */
-};
-
-/********** NSSCKMDMechansim functions ***********************/
-/*
- * ckmk_mdMechanismRSA_Destroy
- */
-static void
-ckmk_mdMechanismRSA_Destroy
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nss_ZFreeIf(fwMechanism);
-}
-
-/*
- * ckmk_mdMechanismRSA_GetMinKeySize
- */
-static CK_ULONG
-ckmk_mdMechanismRSA_GetMinKeySize
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return 384;
-}
-
-/*
- * ckmk_mdMechanismRSA_GetMaxKeySize
- */
-static CK_ULONG
-ckmk_mdMechanismRSA_GetMaxKeySize
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return 16384;
-}
-
-/*
- * ckmk_mdMechanismRSA_DecryptInit
- */
-static NSSCKMDCryptoOperation *
-ckmk_mdMechanismRSA_DecryptInit
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
-)
-{
- return ckmk_mdCryptoOperationRSAPriv_Create(
- &ckmk_mdCryptoOperationRSADecrypt_proto,
- mdMechanism, mdKey, CKMK_DECRYPT, pError);
-}
-
-/*
- * ckmk_mdMechanismRSA_SignInit
- */
-static NSSCKMDCryptoOperation *
-ckmk_mdMechanismRSA_SignInit
-(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError
-)
-{
- return ckmk_mdCryptoOperationRSAPriv_Create(
- &ckmk_mdCryptoOperationRSASign_proto,
- mdMechanism, mdKey, CKMK_SIGN, pError);
-}
-
-
-NSS_IMPLEMENT_DATA const NSSCKMDMechanism
-nss_ckmk_mdMechanismRSA = {
- (void *)NULL, /* etc */
- ckmk_mdMechanismRSA_Destroy,
- ckmk_mdMechanismRSA_GetMinKeySize,
- ckmk_mdMechanismRSA_GetMaxKeySize,
- NULL, /* GetInHardware - default false */
- NULL, /* EncryptInit - default errs */
- ckmk_mdMechanismRSA_DecryptInit,
- NULL, /* DigestInit - default errs*/
- ckmk_mdMechanismRSA_SignInit,
- NULL, /* VerifyInit - default errs */
- ckmk_mdMechanismRSA_SignInit, /* SignRecoverInit */
- NULL, /* VerifyRecoverInit - default errs */
- NULL, /* GenerateKey - default errs */
- NULL, /* GenerateKeyPair - default errs */
- NULL, /* GetWrapKeyLength - default errs */
- NULL, /* WrapKey - default errs */
- NULL, /* UnwrapKey - default errs */
- NULL, /* DeriveKey - default errs */
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/nssmkey/msession.c b/security/nss/lib/ckfw/nssmkey/msession.c
deleted file mode 100644
index 2b28712ec..000000000
--- a/security/nss/lib/ckfw/nssmkey/msession.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckmk.h"
-
-/*
- * nssmkey/msession.c
- *
- * This file implements the NSSCKMDSession object for the
- * "nssmkey" cryptoki module.
- */
-
-static NSSCKMDFindObjects *
-ckmk_mdSession_FindObjectsInit
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- return nss_ckmk_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
-}
-
-static NSSCKMDObject *
-ckmk_mdSession_CreateObject
-(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- return nss_ckmk_CreateObject(fwSession, pTemplate, ulAttributeCount, pError);
-}
-
-NSS_IMPLEMENT NSSCKMDSession *
-nss_ckmk_CreateSession
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
-{
- NSSArena *arena;
- NSSCKMDSession *rv;
-
- arena = NSSCKFWSession_GetArena(fwSession, pError);
- if( (NSSArena *)NULL == arena ) {
- return (NSSCKMDSession *)NULL;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDSession);
- if( (NSSCKMDSession *)NULL == rv ) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDSession *)NULL;
- }
-
- /*
- * rv was zeroed when allocated, so we only
- * need to set the non-zero members.
- */
-
- rv->etc = (void *)fwSession;
- /* rv->Close */
- /* rv->GetDeviceError */
- /* rv->Login */
- /* rv->Logout */
- /* rv->InitPIN */
- /* rv->SetPIN */
- /* rv->GetOperationStateLen */
- /* rv->GetOperationState */
- /* rv->SetOperationState */
- rv->CreateObject = ckmk_mdSession_CreateObject;
- /* rv->CopyObject */
- rv->FindObjectsInit = ckmk_mdSession_FindObjectsInit;
- /* rv->SeedRandom */
- /* rv->GetRandom */
- /* rv->null */
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/nssmkey/mslot.c b/security/nss/lib/ckfw/nssmkey/mslot.c
deleted file mode 100644
index 042357c78..000000000
--- a/security/nss/lib/ckfw/nssmkey/mslot.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckmk.h"
-
-/*
- * nssmkey/mslot.c
- *
- * This file implements the NSSCKMDSlot object for the
- * "nssmkey" cryptoki module.
- */
-
-static NSSUTF8 *
-ckmk_mdSlot_GetSlotDescription
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckmk_SlotDescription;
-}
-
-static NSSUTF8 *
-ckmk_mdSlot_GetManufacturerID
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckmk_ManufacturerID;
-}
-
-static CK_VERSION
-ckmk_mdSlot_GetHardwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckmk_HardwareVersion;
-}
-
-static CK_VERSION
-ckmk_mdSlot_GetFirmwareVersion
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckmk_FirmwareVersion;
-}
-
-static NSSCKMDToken *
-ckmk_mdSlot_GetToken
-(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSCKMDToken *)&nss_ckmk_mdToken;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDSlot
-nss_ckmk_mdSlot = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Destroy */
- ckmk_mdSlot_GetSlotDescription,
- ckmk_mdSlot_GetManufacturerID,
- NULL, /* GetTokenPresent -- defaults to true */
- NULL, /* GetRemovableDevice -- defaults to false */
- NULL, /* GetHardwareSlot -- defaults to false */
- ckmk_mdSlot_GetHardwareVersion,
- ckmk_mdSlot_GetFirmwareVersion,
- ckmk_mdSlot_GetToken,
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/nssmkey/mtoken.c b/security/nss/lib/ckfw/nssmkey/mtoken.c
deleted file mode 100644
index ffff34322..000000000
--- a/security/nss/lib/ckfw/nssmkey/mtoken.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "ckmk.h"
-
-/*
- * nssmkey/mtoken.c
- *
- * This file implements the NSSCKMDToken object for the
- * "nssmkey" cryptoki module.
- */
-
-static NSSUTF8 *
-ckmk_mdToken_GetLabel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckmk_TokenLabel;
-}
-
-static NSSUTF8 *
-ckmk_mdToken_GetManufacturerID
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckmk_ManufacturerID;
-}
-
-static NSSUTF8 *
-ckmk_mdToken_GetModel
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckmk_TokenModel;
-}
-
-static NSSUTF8 *
-ckmk_mdToken_GetSerialNumber
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- return (NSSUTF8 *)nss_ckmk_TokenSerialNumber;
-}
-
-static CK_BBOOL
-ckmk_mdToken_GetIsWriteProtected
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_FALSE;
-}
-
-/* fake out Mozilla so we don't try to initialize the token */
-static CK_BBOOL
-ckmk_mdToken_GetUserPinInitialized
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return CK_TRUE;
-}
-
-static CK_VERSION
-ckmk_mdToken_GetHardwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckmk_HardwareVersion;
-}
-
-static CK_VERSION
-ckmk_mdToken_GetFirmwareVersion
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return nss_ckmk_FirmwareVersion;
-}
-
-static NSSCKMDSession *
-ckmk_mdToken_OpenSession
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_BBOOL rw,
- CK_RV *pError
-)
-{
- return nss_ckmk_CreateSession(fwSession, pError);
-}
-
-static CK_ULONG
-ckmk_mdToken_GetMechanismCount
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- return (CK_ULONG)1;
-}
-
-static CK_RV
-ckmk_mdToken_GetMechanismTypes
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE types[]
-)
-{
- types[0] = CKM_RSA_PKCS;
- return CKR_OK;
-}
-
-static NSSCKMDMechanism *
-ckmk_mdToken_GetMechanism
-(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE which,
- CK_RV *pError
-)
-{
- if (which != CKM_RSA_PKCS) {
- *pError = CKR_MECHANISM_INVALID;
- return (NSSCKMDMechanism *)NULL;
- }
- return (NSSCKMDMechanism *)&nss_ckmk_mdMechanismRSA;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDToken
-nss_ckmk_mdToken = {
- (void *)NULL, /* etc */
- NULL, /* Setup */
- NULL, /* Invalidate */
- NULL, /* InitToken -- default errs */
- ckmk_mdToken_GetLabel,
- ckmk_mdToken_GetManufacturerID,
- ckmk_mdToken_GetModel,
- ckmk_mdToken_GetSerialNumber,
- NULL, /* GetHasRNG -- default is false */
- ckmk_mdToken_GetIsWriteProtected,
- NULL, /* GetLoginRequired -- default is false */
- ckmk_mdToken_GetUserPinInitialized,
- NULL, /* GetRestoreKeyNotNeeded -- irrelevant */
- NULL, /* GetHasClockOnToken -- default is false */
- NULL, /* GetHasProtectedAuthenticationPath -- default is false */
- NULL, /* GetSupportsDualCryptoOperations -- default is false */
- NULL, /* GetMaxSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetMaxRwSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetMaxPinLen -- irrelevant */
- NULL, /* GetMinPinLen -- irrelevant */
- NULL, /* GetTotalPublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetFreePublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetTotalPrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetFreePrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
- ckmk_mdToken_GetHardwareVersion,
- ckmk_mdToken_GetFirmwareVersion,
- NULL, /* GetUTCTime -- no clock */
- ckmk_mdToken_OpenSession,
- ckmk_mdToken_GetMechanismCount,
- ckmk_mdToken_GetMechanismTypes,
- ckmk_mdToken_GetMechanism,
- (void *)NULL /* null terminator */
-};
diff --git a/security/nss/lib/ckfw/nssmkey/nssmkey.def b/security/nss/lib/ckfw/nssmkey/nssmkey.def
deleted file mode 100644
index 45d307ff0..000000000
--- a/security/nss/lib/ckfw/nssmkey/nssmkey.def
+++ /dev/null
@@ -1,26 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+
-;+NSSMKEY_3.0 { # First release of nssmkey
-;+ global:
-LIBRARY nssmkey ;-
-EXPORTS ;-
-C_GetFunctionList;
-;+ local:
-;+*;
-;+};
diff --git a/security/nss/lib/ckfw/nssmkey/nssmkey.h b/security/nss/lib/ckfw/nssmkey/nssmkey.h
deleted file mode 100644
index bce77bf13..000000000
--- a/security/nss/lib/ckfw/nssmkey/nssmkey.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSMKEY_H
-#define NSSMKEY_H
-
-/*
- * NSS CKMK Version numbers.
- *
- * These are the version numbers for the nssmkey module packaged with
- * this release on NSS. To determine the version numbers of the builtin
- * module you are using, use the appropriate PKCS #11 calls.
- *
- * These version numbers detail changes to the PKCS #11 interface. They map
- * to the PKCS #11 spec versions.
- */
-#define NSS_CKMK_CRYPTOKI_VERSION_MAJOR 2
-#define NSS_CKMK_CRYPTOKI_VERSION_MINOR 20
-
-/* These version numbers detail the changes
- * to the list of trusted certificates.
- *
- * NSS_CKMK_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear
- * whether we may use its full range (0-255) or only 0-99 because
- * of the comment in the CK_VERSION type definition.
- */
-#define NSS_CKMK_LIBRARY_VERSION_MAJOR 1
-#define NSS_CKMK_LIBRARY_VERSION_MINOR 1
-#define NSS_CKMK_LIBRARY_VERSION "1.1"
-
-/* These version numbers detail the semantic changes to the ckfw engine. */
-#define NSS_CKMK_HARDWARE_VERSION_MAJOR 1
-#define NSS_CKMK_HARDWARE_VERSION_MINOR 0
-
-/* These version numbers detail the semantic changes to ckbi itself
- * (new PKCS #11 objects), etc. */
-#define NSS_CKMK_FIRMWARE_VERSION_MAJOR 1
-#define NSS_CKMK_FIRMWARE_VERSION_MINOR 0
-
-#endif /* NSSMKEY_H */
diff --git a/security/nss/lib/ckfw/nssmkey/staticobj.c b/security/nss/lib/ckfw/nssmkey/staticobj.c
deleted file mode 100644
index db57e4173..000000000
--- a/security/nss/lib/ckfw/nssmkey/staticobj.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$""; @(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef CKMK_H
-#include "ckmk.h"
-#endif /* CKMK_H */
-
-static const CK_TRUST ckt_netscape_valid = CKT_NETSCAPE_VALID;
-static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
-static const CK_TRUST ckt_netscape_trusted_delegator = CKT_NETSCAPE_TRUSTED_DELEGATOR;
-static const CK_OBJECT_CLASS cko_netscape_trust = CKO_NETSCAPE_TRUST;
-static const CK_BBOOL ck_true = CK_TRUE;
-static const CK_OBJECT_CLASS cko_data = CKO_DATA;
-static const CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509;
-static const CK_BBOOL ck_false = CK_FALSE;
-static const CK_OBJECT_CLASS cko_netscape_builtin_root_list = CKO_NETSCAPE_BUILTIN_ROOT_LIST;
-
-/* example of a static object */
-static const CK_ATTRIBUTE_TYPE nss_ckmk_types_1 [] = {
- CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL
-};
-
-static const NSSItem nss_ckmk_items_1 [] = {
- { (void *)&cko_data, (PRUint32)sizeof(CK_OBJECT_CLASS) },
- { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)"Mozilla Mac Key Ring Access", (PRUint32)28 }
-};
-
-ckmkInternalObject nss_ckmk_data[] = {
- { ckmkRaw, {{ 5, nss_ckmk_types_1, nss_ckmk_items_1}} , CKO_DATA, {NULL} },
-};
-
-const PRUint32 nss_ckmk_nObjects = 1;
diff --git a/security/nss/lib/ckfw/object.c b/security/nss/lib/ckfw/object.c
deleted file mode 100644
index 722979837..000000000
--- a/security/nss/lib/ckfw/object.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * object.c
- *
- * This file implements the NSSCKFWObject type and methods.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * NSSCKFWObject
- *
- * -- create/destroy --
- * nssCKFWObject_Create
- * nssCKFWObject_Finalize
- * nssCKFWObject_Destroy
- *
- * -- public accessors --
- * NSSCKFWObject_GetMDObject
- * NSSCKFWObject_GetArena
- * NSSCKFWObject_IsTokenObject
- * NSSCKFWObject_GetAttributeCount
- * NSSCKFWObject_GetAttributeTypes
- * NSSCKFWObject_GetAttributeSize
- * NSSCKFWObject_GetAttribute
- * NSSCKFWObject_SetAttribute
- * NSSCKFWObject_GetObjectSize
- *
- * -- implement public accessors --
- * nssCKFWObject_GetMDObject
- * nssCKFWObject_GetArena
- *
- * -- private accessors --
- * nssCKFWObject_SetHandle
- * nssCKFWObject_GetHandle
- *
- * -- module fronts --
- * nssCKFWObject_IsTokenObject
- * nssCKFWObject_GetAttributeCount
- * nssCKFWObject_GetAttributeTypes
- * nssCKFWObject_GetAttributeSize
- * nssCKFWObject_GetAttribute
- * nssCKFWObject_SetAttribute
- * nssCKFWObject_GetObjectSize
- */
-
-struct NSSCKFWObjectStr {
- NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */
- NSSArena *arena;
- NSSCKMDObject *mdObject;
- NSSCKMDSession *mdSession;
- NSSCKFWSession *fwSession;
- NSSCKMDToken *mdToken;
- NSSCKFWToken *fwToken;
- NSSCKMDInstance *mdInstance;
- NSSCKFWInstance *fwInstance;
- CK_OBJECT_HANDLE hObject;
-};
-
-#ifdef DEBUG
-/*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do this routines as no-ops.
- */
-
-static CK_RV
-object_add_pointer
-(
- const NSSCKFWObject *fwObject
-)
-{
- return CKR_OK;
-}
-
-static CK_RV
-object_remove_pointer
-(
- const NSSCKFWObject *fwObject
-)
-{
- return CKR_OK;
-}
-
-NSS_IMPLEMENT CK_RV
-nssCKFWObject_verifyPointer
-(
- const NSSCKFWObject *fwObject
-)
-{
- return CKR_OK;
-}
-
-#endif /* DEBUG */
-
-
-/*
- * nssCKFWObject_Create
- *
- */
-NSS_IMPLEMENT NSSCKFWObject *
-nssCKFWObject_Create
-(
- NSSArena *arena,
- NSSCKMDObject *mdObject,
- NSSCKFWSession *fwSession,
- NSSCKFWToken *fwToken,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- NSSCKFWObject *fwObject;
- nssCKFWHash *mdObjectHash;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWObject *)NULL;
- }
-
- if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWObject *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWObject *)NULL;
- }
- mdObjectHash = nssCKFWToken_GetMDObjectHash(fwToken);
- if (!mdObjectHash) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWObject *)NULL;
- }
-
- if( nssCKFWHash_Exists(mdObjectHash, mdObject) ) {
- fwObject = nssCKFWHash_Lookup(mdObjectHash, mdObject);
- return fwObject;
- }
-
- fwObject = nss_ZNEW(arena, NSSCKFWObject);
- if (!fwObject) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWObject *)NULL;
- }
-
- fwObject->arena = arena;
- fwObject->mdObject = mdObject;
- fwObject->fwSession = fwSession;
-
- if (fwSession) {
- fwObject->mdSession = nssCKFWSession_GetMDSession(fwSession);
- }
-
- fwObject->fwToken = fwToken;
- fwObject->mdToken = nssCKFWToken_GetMDToken(fwToken);
- fwObject->fwInstance = fwInstance;
- fwObject->mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
- fwObject->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
- if (!fwObject->mutex) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
- }
-
- *pError = nssCKFWHash_Add(mdObjectHash, mdObject, fwObject);
- if( CKR_OK != *pError ) {
- nss_ZFreeIf(fwObject);
- return (NSSCKFWObject *)NULL;
- }
-
-#ifdef DEBUG
- *pError = object_add_pointer(fwObject);
- if( CKR_OK != *pError ) {
- nssCKFWHash_Remove(mdObjectHash, mdObject);
- nss_ZFreeIf(fwObject);
- return (NSSCKFWObject *)NULL;
- }
-#endif /* DEBUG */
-
- *pError = CKR_OK;
- return fwObject;
-}
-
-/*
- * nssCKFWObject_Finalize
- *
- */
-NSS_IMPLEMENT void
-nssCKFWObject_Finalize
-(
- NSSCKFWObject *fwObject,
- PRBool removeFromHash
-)
-{
- nssCKFWHash *mdObjectHash;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return;
- }
-#endif /* NSSDEBUG */
-
- (void)nssCKFWMutex_Destroy(fwObject->mutex);
-
- if (fwObject->mdObject->Finalize) {
- fwObject->mdObject->Finalize(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
- }
-
- if (removeFromHash) {
- mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
- if (mdObjectHash) {
- nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
- }
- }
-
- if (fwObject->fwSession) {
- nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
- }
- nss_ZFreeIf(fwObject);
-
-#ifdef DEBUG
- (void)object_remove_pointer(fwObject);
-#endif /* DEBUG */
-
- return;
-}
-
-/*
- * nssCKFWObject_Destroy
- *
- */
-NSS_IMPLEMENT void
-nssCKFWObject_Destroy
-(
- NSSCKFWObject *fwObject
-)
-{
- nssCKFWHash *mdObjectHash;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return;
- }
-#endif /* NSSDEBUG */
-
- (void)nssCKFWMutex_Destroy(fwObject->mutex);
-
- if (fwObject->mdObject->Destroy) {
- fwObject->mdObject->Destroy(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
- }
-
- mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
- if (mdObjectHash) {
- nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
- }
-
- if (fwObject->fwSession) {
- nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
- }
- nss_ZFreeIf(fwObject);
-
-#ifdef DEBUG
- (void)object_remove_pointer(fwObject);
-#endif /* DEBUG */
-
- return;
-}
-
-/*
- * nssCKFWObject_GetMDObject
- *
- */
-NSS_IMPLEMENT NSSCKMDObject *
-nssCKFWObject_GetMDObject
-(
- NSSCKFWObject *fwObject
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return (NSSCKMDObject *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwObject->mdObject;
-}
-
-/*
- * nssCKFWObject_GetArena
- *
- */
-NSS_IMPLEMENT NSSArena *
-nssCKFWObject_GetArena
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
-{
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSArena *)NULL;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (NSSArena *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwObject->arena;
-}
-
-/*
- * nssCKFWObject_SetHandle
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWObject_SetHandle
-(
- NSSCKFWObject *fwObject,
- CK_OBJECT_HANDLE hObject
-)
-{
-#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
-#endif /* NSSDEBUG */
-
-#ifdef NSSDEBUG
- error = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- if( (CK_OBJECT_HANDLE)0 != fwObject->hObject ) {
- return CKR_GENERAL_ERROR;
- }
-
- fwObject->hObject = hObject;
-
- return CKR_OK;
-}
-
-/*
- * nssCKFWObject_GetHandle
- *
- */
-NSS_IMPLEMENT CK_OBJECT_HANDLE
-nssCKFWObject_GetHandle
-(
- NSSCKFWObject *fwObject
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return (CK_OBJECT_HANDLE)0;
- }
-#endif /* NSSDEBUG */
-
- return fwObject->hObject;
-}
-
-/*
- * nssCKFWObject_IsTokenObject
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWObject_IsTokenObject
-(
- NSSCKFWObject *fwObject
-)
-{
- CK_BBOOL b = CK_FALSE;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwObject->mdObject->IsTokenObject) {
- NSSItem item;
- NSSItem *pItem;
- CK_RV rv = CKR_OK;
-
- item.data = (void *)&b;
- item.size = sizeof(b);
-
- pItem = nssCKFWObject_GetAttribute(fwObject, CKA_TOKEN, &item,
- (NSSArena *)NULL, &rv);
- if (!pItem) {
- /* Error of some type */
- b = CK_FALSE;
- goto done;
- }
-
- goto done;
- }
-
- b = fwObject->mdObject->IsTokenObject(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
-
- done:
- return b;
-}
-
-/*
- * nssCKFWObject_GetAttributeCount
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWObject_GetAttributeCount
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
-{
- CK_ULONG rv;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- if (!fwObject->mdObject->GetAttributeCount) {
- *pError = CKR_GENERAL_ERROR;
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWMutex_Lock(fwObject->mutex);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-
- rv = fwObject->mdObject->GetAttributeCount(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
- pError);
-
- (void)nssCKFWMutex_Unlock(fwObject->mutex);
- return rv;
-}
-
-/*
- * nssCKFWObject_GetAttributeTypes
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWObject_GetAttributeTypes
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != error ) {
- return error;
- }
-
- if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) {
- return CKR_ARGUMENTS_BAD;
- }
-#endif /* NSSDEBUG */
-
- if (!fwObject->mdObject->GetAttributeTypes) {
- return CKR_GENERAL_ERROR;
- }
-
- error = nssCKFWMutex_Lock(fwObject->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- error = fwObject->mdObject->GetAttributeTypes(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
- typeArray, ulCount);
-
- (void)nssCKFWMutex_Unlock(fwObject->mutex);
- return error;
-}
-
-/*
- * nssCKFWObject_GetAttributeSize
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWObject_GetAttributeSize
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- CK_ULONG rv;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- if (!fwObject->mdObject->GetAttributeSize) {
- *pError = CKR_GENERAL_ERROR;
- return (CK_ULONG )0;
- }
-
- *pError = nssCKFWMutex_Lock(fwObject->mutex);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-
- rv = fwObject->mdObject->GetAttributeSize(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
- attribute, pError);
-
- (void)nssCKFWMutex_Unlock(fwObject->mutex);
- return rv;
-}
-
-/*
- * nssCKFWObject_GetAttribute
- *
- * Usual NSS allocation rules:
- * If itemOpt is not NULL, it will be returned; otherwise an NSSItem
- * will be allocated. If itemOpt is not NULL but itemOpt->data is,
- * the buffer will be allocated; otherwise, the buffer will be used.
- * Any allocations will come from the optional arena, if one is
- * specified.
- */
-NSS_IMPLEMENT NSSItem *
-nssCKFWObject_GetAttribute
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *itemOpt,
- NSSArena *arenaOpt,
- CK_RV *pError
-)
-{
- NSSItem *rv = (NSSItem *)NULL;
- NSSCKFWItem mdItem;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSItem *)NULL;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (NSSItem *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if (!fwObject->mdObject->GetAttribute) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSItem *)NULL;
- }
-
- *pError = nssCKFWMutex_Lock(fwObject->mutex);
- if( CKR_OK != *pError ) {
- return (NSSItem *)NULL;
- }
-
- mdItem = fwObject->mdObject->GetAttribute(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
- attribute, pError);
-
- if (!mdItem.item) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
-
- goto done;
- }
-
- if (!itemOpt) {
- rv = nss_ZNEW(arenaOpt, NSSItem);
- if (!rv) {
- *pError = CKR_HOST_MEMORY;
- goto done;
- }
- } else {
- rv = itemOpt;
- }
-
- if (!rv->data) {
- rv->size = mdItem.item->size;
- rv->data = nss_ZAlloc(arenaOpt, rv->size);
- if (!rv->data) {
- *pError = CKR_HOST_MEMORY;
- if (!itemOpt) {
- nss_ZFreeIf(rv);
- }
- rv = (NSSItem *)NULL;
- goto done;
- }
- } else {
- if( rv->size >= mdItem.item->size ) {
- rv->size = mdItem.item->size;
- } else {
- *pError = CKR_BUFFER_TOO_SMALL;
- /* Should we set rv->size to mdItem->size? */
- /* rv can't have been allocated */
- rv = (NSSItem *)NULL;
- goto done;
- }
- }
-
- (void)nsslibc_memcpy(rv->data, mdItem.item->data, rv->size);
-
- if (PR_TRUE == mdItem.needsFreeing) {
- PR_ASSERT(fwObject->mdObject->FreeAttribute);
- if (fwObject->mdObject->FreeAttribute) {
- *pError = fwObject->mdObject->FreeAttribute(&mdItem);
- }
- }
-
- done:
- (void)nssCKFWMutex_Unlock(fwObject->mutex);
- return rv;
-}
-
-/*
- * nssCKFWObject_SetAttribute
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWObject_SetAttribute
-(
- NSSCKFWObject *fwObject,
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- if( CKA_TOKEN == attribute ) {
- /*
- * We're changing from a session object to a token object or
- * vice-versa.
- */
-
- CK_ATTRIBUTE a;
- NSSCKFWObject *newFwObject;
- NSSCKFWObject swab;
-
- a.type = CKA_TOKEN;
- a.pValue = value->data;
- a.ulValueLen = value->size;
-
- newFwObject = nssCKFWSession_CopyObject(fwSession, fwObject,
- &a, 1, &error);
- if (!newFwObject) {
- if( CKR_OK == error ) {
- error = CKR_GENERAL_ERROR;
- }
- return error;
- }
-
- /*
- * Actually, I bet the locking is worse than this.. this part of
- * the code could probably use some scrutiny and reworking.
- */
- error = nssCKFWMutex_Lock(fwObject->mutex);
- if( CKR_OK != error ) {
- nssCKFWObject_Destroy(newFwObject);
- return error;
- }
-
- error = nssCKFWMutex_Lock(newFwObject->mutex);
- if( CKR_OK != error ) {
- nssCKFWMutex_Unlock(fwObject->mutex);
- nssCKFWObject_Destroy(newFwObject);
- return error;
- }
-
- /*
- * Now, we have our new object, but it has a new fwObject pointer,
- * while we have to keep the existing one. So quick swap the contents.
- */
- swab = *fwObject;
- *fwObject = *newFwObject;
- *newFwObject = swab;
-
- /* But keep the mutexes the same */
- swab.mutex = fwObject->mutex;
- fwObject->mutex = newFwObject->mutex;
- newFwObject->mutex = swab.mutex;
-
- (void)nssCKFWMutex_Unlock(newFwObject->mutex);
- (void)nssCKFWMutex_Unlock(fwObject->mutex);
-
- /*
- * Either remove or add this to the list of session objects
- */
-
- if( CK_FALSE == *(CK_BBOOL *)value->data ) {
- /*
- * New one is a session object, except since we "stole" the fwObject, it's
- * not in the list. Add it.
- */
- nssCKFWSession_RegisterSessionObject(fwSession, fwObject);
- } else {
- /*
- * New one is a token object, except since we "stole" the fwObject, it's
- * in the list. Remove it.
- */
- if (fwObject->fwSession) {
- nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
- }
- }
-
- /*
- * Now delete the old object. Remember the names have changed.
- */
- nssCKFWObject_Destroy(newFwObject);
-
- return CKR_OK;
- } else {
- /*
- * An "ordinary" change.
- */
- if (!fwObject->mdObject->SetAttribute) {
- /* We could fake it with copying, like above.. later */
- return CKR_ATTRIBUTE_READ_ONLY;
- }
-
- error = nssCKFWMutex_Lock(fwObject->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- error = fwObject->mdObject->SetAttribute(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
- attribute, value);
-
- (void)nssCKFWMutex_Unlock(fwObject->mutex);
-
- return error;
- }
-}
-
-/*
- * nssCKFWObject_GetObjectSize
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWObject_GetObjectSize
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
-{
- CK_ULONG rv;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- if (!fwObject->mdObject->GetObjectSize) {
- *pError = CKR_INFORMATION_SENSITIVE;
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWMutex_Lock(fwObject->mutex);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-
- rv = fwObject->mdObject->GetObjectSize(fwObject->mdObject, fwObject,
- fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
- fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
- pError);
-
- (void)nssCKFWMutex_Unlock(fwObject->mutex);
- return rv;
-}
-
-/*
- * NSSCKFWObject_GetMDObject
- *
- */
-NSS_IMPLEMENT NSSCKMDObject *
-NSSCKFWObject_GetMDObject
-(
- NSSCKFWObject *fwObject
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return (NSSCKMDObject *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWObject_GetMDObject(fwObject);
-}
-
-/*
- * NSSCKFWObject_GetArena
- *
- */
-NSS_IMPLEMENT NSSArena *
-NSSCKFWObject_GetArena
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
-{
-#ifdef DEBUG
- if (!pError) {
- return (NSSArena *)NULL;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (NSSArena *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWObject_GetArena(fwObject, pError);
-}
-
-/*
- * NSSCKFWObject_IsTokenObject
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-NSSCKFWObject_IsTokenObject
-(
- NSSCKFWObject *fwObject
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
- return CK_FALSE;
- }
-#endif /* DEBUG */
-
- return nssCKFWObject_IsTokenObject(fwObject);
-}
-
-/*
- * NSSCKFWObject_GetAttributeCount
- *
- */
-NSS_IMPLEMENT CK_ULONG
-NSSCKFWObject_GetAttributeCount
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
-{
-#ifdef DEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-#endif /* DEBUG */
-
- return nssCKFWObject_GetAttributeCount(fwObject, pError);
-}
-
-/*
- * NSSCKFWObject_GetAttributeTypes
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWObject_GetAttributeTypes
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-)
-{
-#ifdef DEBUG
- CK_RV error = CKR_OK;
-
- error = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != error ) {
- return error;
- }
-
- if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) {
- return CKR_ARGUMENTS_BAD;
- }
-#endif /* DEBUG */
-
- return nssCKFWObject_GetAttributeTypes(fwObject, typeArray, ulCount);
-}
-
-/*
- * NSSCKFWObject_GetAttributeSize
- *
- */
-NSS_IMPLEMENT CK_ULONG
-NSSCKFWObject_GetAttributeSize
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
-#ifdef DEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-#endif /* DEBUG */
-
- return nssCKFWObject_GetAttributeSize(fwObject, attribute, pError);
-}
-
-/*
- * NSSCKFWObject_GetAttribute
- *
- */
-NSS_IMPLEMENT NSSItem *
-NSSCKFWObject_GetAttribute
-(
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *itemOpt,
- NSSArena *arenaOpt,
- CK_RV *pError
-)
-{
-#ifdef DEBUG
- if (!pError) {
- return (NSSItem *)NULL;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (NSSItem *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWObject_GetAttribute(fwObject, attribute, itemOpt, arenaOpt, pError);
-}
-
-/*
- * NSSCKFWObject_GetObjectSize
- *
- */
-NSS_IMPLEMENT CK_ULONG
-NSSCKFWObject_GetObjectSize
-(
- NSSCKFWObject *fwObject,
- CK_RV *pError
-)
-{
-#ifdef DEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-#endif /* DEBUG */
-
- return nssCKFWObject_GetObjectSize(fwObject, pError);
-}
diff --git a/security/nss/lib/ckfw/session.c b/security/nss/lib/ckfw/session.c
deleted file mode 100644
index f352afc6a..000000000
--- a/security/nss/lib/ckfw/session.c
+++ /dev/null
@@ -1,2464 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * session.c
- *
- * This file implements the NSSCKFWSession type and methods.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * NSSCKFWSession
- *
- * -- create/destroy --
- * nssCKFWSession_Create
- * nssCKFWSession_Destroy
- *
- * -- public accessors --
- * NSSCKFWSession_GetMDSession
- * NSSCKFWSession_GetArena
- * NSSCKFWSession_CallNotification
- * NSSCKFWSession_IsRWSession
- * NSSCKFWSession_IsSO
- *
- * -- implement public accessors --
- * nssCKFWSession_GetMDSession
- * nssCKFWSession_GetArena
- * nssCKFWSession_CallNotification
- * nssCKFWSession_IsRWSession
- * nssCKFWSession_IsSO
- *
- * -- private accessors --
- * nssCKFWSession_GetSlot
- * nssCKFWSession_GetSessionState
- * nssCKFWSession_SetFWFindObjects
- * nssCKFWSession_GetFWFindObjects
- * nssCKFWSession_SetMDSession
- * nssCKFWSession_SetHandle
- * nssCKFWSession_GetHandle
- * nssCKFWSession_RegisterSessionObject
- * nssCKFWSession_DeegisterSessionObject
- *
- * -- module fronts --
- * nssCKFWSession_GetDeviceError
- * nssCKFWSession_Login
- * nssCKFWSession_Logout
- * nssCKFWSession_InitPIN
- * nssCKFWSession_SetPIN
- * nssCKFWSession_GetOperationStateLen
- * nssCKFWSession_GetOperationState
- * nssCKFWSession_SetOperationState
- * nssCKFWSession_CreateObject
- * nssCKFWSession_CopyObject
- * nssCKFWSession_FindObjectsInit
- * nssCKFWSession_SeedRandom
- * nssCKFWSession_GetRandom
- */
-
-struct NSSCKFWSessionStr {
- NSSArena *arena;
- NSSCKMDSession *mdSession;
- NSSCKFWToken *fwToken;
- NSSCKMDToken *mdToken;
- NSSCKFWInstance *fwInstance;
- NSSCKMDInstance *mdInstance;
- CK_VOID_PTR pApplication;
- CK_NOTIFY Notify;
-
- /*
- * Everything above is set at creation time, and then not modified.
- * The items below are atomic. No locking required. If we fear
- * about pointer-copies being nonatomic, we'll lock fwFindObjects.
- */
-
- CK_BBOOL rw;
- NSSCKFWFindObjects *fwFindObjects;
- NSSCKFWCryptoOperation *fwOperationArray[NSSCKFWCryptoOperationState_Max];
- nssCKFWHash *sessionObjectHash;
- CK_SESSION_HANDLE hSession;
-};
-
-#ifdef DEBUG
-/*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do this routines as no-ops.
- */
-
-static CK_RV
-session_add_pointer
-(
- const NSSCKFWSession *fwSession
-)
-{
- return CKR_OK;
-}
-
-static CK_RV
-session_remove_pointer
-(
- const NSSCKFWSession *fwSession
-)
-{
- return CKR_OK;
-}
-
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_verifyPointer
-(
- const NSSCKFWSession *fwSession
-)
-{
- return CKR_OK;
-}
-
-#endif /* DEBUG */
-
-/*
- * nssCKFWSession_Create
- *
- */
-NSS_IMPLEMENT NSSCKFWSession *
-nssCKFWSession_Create
-(
- NSSCKFWToken *fwToken,
- CK_BBOOL rw,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_RV *pError
-)
-{
- NSSArena *arena = (NSSArena *)NULL;
- NSSCKFWSession *fwSession;
- NSSCKFWSlot *fwSlot;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWSession *)NULL;
- }
-
- *pError = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != *pError ) {
- return (NSSCKFWSession *)NULL;
- }
-#endif /* NSSDEBUG */
-
- arena = NSSArena_Create();
- if (!arena) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWSession *)NULL;
- }
-
- fwSession = nss_ZNEW(arena, NSSCKFWSession);
- if (!fwSession) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fwSession->arena = arena;
- fwSession->mdSession = (NSSCKMDSession *)NULL; /* set later */
- fwSession->fwToken = fwToken;
- fwSession->mdToken = nssCKFWToken_GetMDToken(fwToken);
-
- fwSlot = nssCKFWToken_GetFWSlot(fwToken);
- fwSession->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
- fwSession->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
-
- fwSession->rw = rw;
- fwSession->pApplication = pApplication;
- fwSession->Notify = Notify;
-
- fwSession->fwFindObjects = (NSSCKFWFindObjects *)NULL;
-
- fwSession->sessionObjectHash = nssCKFWHash_Create(fwSession->fwInstance, arena, pError);
- if (!fwSession->sessionObjectHash) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- goto loser;
- }
-
-#ifdef DEBUG
- *pError = session_add_pointer(fwSession);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-#endif /* DEBUG */
-
- return fwSession;
-
- loser:
- if (arena) {
- if (fwSession && fwSession->sessionObjectHash) {
- (void)nssCKFWHash_Destroy(fwSession->sessionObjectHash);
- }
- NSSArena_Destroy(arena);
- }
-
- return (NSSCKFWSession *)NULL;
-}
-
-static void
-nss_ckfw_session_object_destroy_iterator
-(
- const void *key,
- void *value,
- void *closure
-)
-{
- NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
- nssCKFWObject_Finalize(fwObject, PR_TRUE);
-}
-
-/*
- * nssCKFWSession_Destroy
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_Destroy
-(
- NSSCKFWSession *fwSession,
- CK_BBOOL removeFromTokenHash
-)
-{
- CK_RV error = CKR_OK;
- nssCKFWHash *sessionObjectHash;
- NSSCKFWCryptoOperationState i;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- if( removeFromTokenHash ) {
- error = nssCKFWToken_RemoveSession(fwSession->fwToken, fwSession);
- }
-
- /*
- * Invalidate session objects
- */
-
- sessionObjectHash = fwSession->sessionObjectHash;
- fwSession->sessionObjectHash = (nssCKFWHash *)NULL;
-
- nssCKFWHash_Iterate(sessionObjectHash,
- nss_ckfw_session_object_destroy_iterator,
- (void *)NULL);
-
- for (i=0; i < NSSCKFWCryptoOperationState_Max; i++) {
- if (fwSession->fwOperationArray[i]) {
- nssCKFWCryptoOperation_Destroy(fwSession->fwOperationArray[i]);
- }
- }
-
-#ifdef DEBUG
- (void)session_remove_pointer(fwSession);
-#endif /* DEBUG */
- (void)nssCKFWHash_Destroy(sessionObjectHash);
- NSSArena_Destroy(fwSession->arena);
-
- return error;
-}
-
-/*
- * nssCKFWSession_GetMDSession
- *
- */
-NSS_IMPLEMENT NSSCKMDSession *
-nssCKFWSession_GetMDSession
-(
- NSSCKFWSession *fwSession
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return (NSSCKMDSession *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwSession->mdSession;
-}
-
-/*
- * nssCKFWSession_GetArena
- *
- */
-NSS_IMPLEMENT NSSArena *
-nssCKFWSession_GetArena
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
-{
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSArena *)NULL;
- }
-
- *pError = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != *pError ) {
- return (NSSArena *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwSession->arena;
-}
-
-/*
- * nssCKFWSession_CallNotification
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_CallNotification
-(
- NSSCKFWSession *fwSession,
- CK_NOTIFICATION event
-)
-{
- CK_RV error = CKR_OK;
- CK_SESSION_HANDLE handle;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- if( (CK_NOTIFY)NULL == fwSession->Notify ) {
- return CKR_OK;
- }
-
- handle = nssCKFWInstance_FindSessionHandle(fwSession->fwInstance, fwSession);
- if( (CK_SESSION_HANDLE)0 == handle ) {
- return CKR_GENERAL_ERROR;
- }
-
- error = fwSession->Notify(handle, event, fwSession->pApplication);
-
- return error;
-}
-
-/*
- * nssCKFWSession_IsRWSession
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWSession_IsRWSession
-(
- NSSCKFWSession *fwSession
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- return fwSession->rw;
-}
-
-/*
- * nssCKFWSession_IsSO
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWSession_IsSO
-(
- NSSCKFWSession *fwSession
-)
-{
- CK_STATE state;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- state = nssCKFWToken_GetSessionState(fwSession->fwToken);
- switch( state ) {
- case CKS_RO_PUBLIC_SESSION:
- case CKS_RO_USER_FUNCTIONS:
- case CKS_RW_PUBLIC_SESSION:
- case CKS_RW_USER_FUNCTIONS:
- return CK_FALSE;
- case CKS_RW_SO_FUNCTIONS:
- return CK_TRUE;
- default:
- return CK_FALSE;
- }
-}
-
-/*
- * nssCKFWSession_GetFWSlot
- *
- */
-NSS_IMPLEMENT NSSCKFWSlot *
-nssCKFWSession_GetFWSlot
-(
- NSSCKFWSession *fwSession
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return (NSSCKFWSlot *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return nssCKFWToken_GetFWSlot(fwSession->fwToken);
-}
-
-/*
- * nssCFKWSession_GetSessionState
- *
- */
-NSS_IMPLEMENT CK_STATE
-nssCKFWSession_GetSessionState
-(
- NSSCKFWSession *fwSession
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CKS_RO_PUBLIC_SESSION; /* whatever */
- }
-#endif /* NSSDEBUG */
-
- return nssCKFWToken_GetSessionState(fwSession->fwToken);
-}
-
-/*
- * nssCKFWSession_SetFWFindObjects
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetFWFindObjects
-(
- NSSCKFWSession *fwSession,
- NSSCKFWFindObjects *fwFindObjects
-)
-{
-#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
-#endif /* NSSDEBUG */
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- /* fwFindObjects may be null */
-#endif /* NSSDEBUG */
-
- if ((fwSession->fwFindObjects) &&
- (fwFindObjects)) {
- return CKR_OPERATION_ACTIVE;
- }
-
- fwSession->fwFindObjects = fwFindObjects;
-
- return CKR_OK;
-}
-
-/*
- * nssCKFWSession_GetFWFindObjects
- *
- */
-NSS_IMPLEMENT NSSCKFWFindObjects *
-nssCKFWSession_GetFWFindObjects
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
-{
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWFindObjects *)NULL;
- }
-
- *pError = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != *pError ) {
- return (NSSCKFWFindObjects *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if (!fwSession->fwFindObjects) {
- *pError = CKR_OPERATION_NOT_INITIALIZED;
- return (NSSCKFWFindObjects *)NULL;
- }
-
- return fwSession->fwFindObjects;
-}
-
-/*
- * nssCKFWSession_SetMDSession
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetMDSession
-(
- NSSCKFWSession *fwSession,
- NSSCKMDSession *mdSession
-)
-{
-#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
-#endif /* NSSDEBUG */
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!mdSession) {
- return CKR_ARGUMENTS_BAD;
- }
-#endif /* NSSDEBUG */
-
- if (fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-
- fwSession->mdSession = mdSession;
-
- return CKR_OK;
-}
-
-/*
- * nssCKFWSession_SetHandle
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetHandle
-(
- NSSCKFWSession *fwSession,
- CK_SESSION_HANDLE hSession
-)
-{
-#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
-#endif /* NSSDEBUG */
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- if( (CK_SESSION_HANDLE)0 != fwSession->hSession ) {
- return CKR_GENERAL_ERROR;
- }
-
- fwSession->hSession = hSession;
-
- return CKR_OK;
-}
-
-/*
- * nssCKFWSession_GetHandle
- *
- */
-NSS_IMPLEMENT CK_SESSION_HANDLE
-nssCKFWSession_GetHandle
-(
- NSSCKFWSession *fwSession
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwSession->hSession;
-}
-
-/*
- * nssCKFWSession_RegisterSessionObject
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_RegisterSessionObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
-{
- CK_RV rv = CKR_OK;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- if (fwSession->sessionObjectHash) {
- rv = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
- }
-
- return rv;
-}
-
-/*
- * nssCKFWSession_DeregisterSessionObject
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_DeregisterSessionObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- if (fwSession->sessionObjectHash) {
- nssCKFWHash_Remove(fwSession->sessionObjectHash, fwObject);
- }
-
- return CKR_OK;
-}
-
-/*
- * nssCKFWSession_GetDeviceError
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWSession_GetDeviceError
-(
- NSSCKFWSession *fwSession
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return (CK_ULONG)0;
- }
-
- if (!fwSession->mdSession) {
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- if (!fwSession->mdSession->GetDeviceError) {
- return (CK_ULONG)0;
- }
-
- return fwSession->mdSession->GetDeviceError(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken,
- fwSession->mdInstance, fwSession->fwInstance);
-}
-
-/*
- * nssCKFWSession_Login
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_Login
-(
- NSSCKFWSession *fwSession,
- CK_USER_TYPE userType,
- NSSItem *pin
-)
-{
- CK_RV error = CKR_OK;
- CK_STATE oldState;
- CK_STATE newState;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- switch( userType ) {
- case CKU_SO:
- case CKU_USER:
- break;
- default:
- return CKR_USER_TYPE_INVALID;
- }
-
- if (!pin) {
- if( CK_TRUE != nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken) ) {
- return CKR_ARGUMENTS_BAD;
- }
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
-
- /*
- * It's not clear what happens when you're already logged in.
- * I'll just fail; but if we decide to change, the logic is
- * all right here.
- */
-
- if( CKU_SO == userType ) {
- switch( oldState ) {
- case CKS_RO_PUBLIC_SESSION:
- /*
- * There's no such thing as a read-only security officer
- * session, so fail. The error should be CKR_SESSION_READ_ONLY,
- * except that C_Login isn't defined to return that. So we'll
- * do CKR_SESSION_READ_ONLY_EXISTS, which is what is documented.
- */
- return CKR_SESSION_READ_ONLY_EXISTS;
- case CKS_RO_USER_FUNCTIONS:
- return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
- case CKS_RW_PUBLIC_SESSION:
- newState = CKS_RW_SO_FUNCTIONS;
- break;
- case CKS_RW_USER_FUNCTIONS:
- return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
- case CKS_RW_SO_FUNCTIONS:
- return CKR_USER_ALREADY_LOGGED_IN;
- default:
- return CKR_GENERAL_ERROR;
- }
- } else /* CKU_USER == userType */ {
- switch( oldState ) {
- case CKS_RO_PUBLIC_SESSION:
- newState = CKS_RO_USER_FUNCTIONS;
- break;
- case CKS_RO_USER_FUNCTIONS:
- return CKR_USER_ALREADY_LOGGED_IN;
- case CKS_RW_PUBLIC_SESSION:
- newState = CKS_RW_USER_FUNCTIONS;
- break;
- case CKS_RW_USER_FUNCTIONS:
- return CKR_USER_ALREADY_LOGGED_IN;
- case CKS_RW_SO_FUNCTIONS:
- return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
- default:
- return CKR_GENERAL_ERROR;
- }
- }
-
- /*
- * So now we're in one of three cases:
- *
- * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_SO_FUNCTIONS;
- * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_USER_FUNCTIONS;
- * Old == CKS_RO_PUBLIC_SESSION, New == CKS_RO_USER_FUNCTIONS;
- */
-
- if (!fwSession->mdSession->Login) {
- /*
- * The Module doesn't want to be informed (or check the pin)
- * it'll just rely on the Framework as needed.
- */
- ;
- } else {
- error = fwSession->mdSession->Login(fwSession->mdSession, fwSession,
- fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
- fwSession->fwInstance, userType, pin, oldState, newState);
- if( CKR_OK != error ) {
- return error;
- }
- }
-
- (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
- return CKR_OK;
-}
-
-/*
- * nssCKFWSession_Logout
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_Logout
-(
- NSSCKFWSession *fwSession
-)
-{
- CK_RV error = CKR_OK;
- CK_STATE oldState;
- CK_STATE newState;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
-
- switch( oldState ) {
- case CKS_RO_PUBLIC_SESSION:
- return CKR_USER_NOT_LOGGED_IN;
- case CKS_RO_USER_FUNCTIONS:
- newState = CKS_RO_PUBLIC_SESSION;
- break;
- case CKS_RW_PUBLIC_SESSION:
- return CKR_USER_NOT_LOGGED_IN;
- case CKS_RW_USER_FUNCTIONS:
- newState = CKS_RW_PUBLIC_SESSION;
- break;
- case CKS_RW_SO_FUNCTIONS:
- newState = CKS_RW_PUBLIC_SESSION;
- break;
- default:
- return CKR_GENERAL_ERROR;
- }
-
- /*
- * So now we're in one of three cases:
- *
- * Old == CKS_RW_SO_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;
- * Old == CKS_RW_USER_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;
- * Old == CKS_RO_USER_FUNCTIONS, New == CKS_RO_PUBLIC_SESSION;
- */
-
- if (!fwSession->mdSession->Logout) {
- /*
- * The Module doesn't want to be informed. Okay.
- */
- ;
- } else {
- error = fwSession->mdSession->Logout(fwSession->mdSession, fwSession,
- fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
- fwSession->fwInstance, oldState, newState);
- if( CKR_OK != error ) {
- /*
- * Now what?! A failure really should end up with the Framework
- * considering it logged out, right?
- */
- ;
- }
- }
-
- (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
- return error;
-}
-
-/*
- * nssCKFWSession_InitPIN
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_InitPIN
-(
- NSSCKFWSession *fwSession,
- NSSItem *pin
-)
-{
- CK_RV error = CKR_OK;
- CK_STATE state;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- state = nssCKFWToken_GetSessionState(fwSession->fwToken);
- if( CKS_RW_SO_FUNCTIONS != state ) {
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- if (!pin) {
- CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
- if( CK_TRUE != has ) {
- return CKR_ARGUMENTS_BAD;
- }
- }
-
- if (!fwSession->mdSession->InitPIN) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- error = fwSession->mdSession->InitPIN(fwSession->mdSession, fwSession,
- fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
- fwSession->fwInstance, pin);
-
- return error;
-}
-
-/*
- * nssCKFWSession_SetPIN
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetPIN
-(
- NSSCKFWSession *fwSession,
- NSSItem *newPin,
- NSSItem *oldPin
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- if (!newPin) {
- CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
- if( CK_TRUE != has ) {
- return CKR_ARGUMENTS_BAD;
- }
- }
-
- if (!oldPin) {
- CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
- if( CK_TRUE != has ) {
- return CKR_ARGUMENTS_BAD;
- }
- }
-
- if (!fwSession->mdSession->SetPIN) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- error = fwSession->mdSession->SetPIN(fwSession->mdSession, fwSession,
- fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
- fwSession->fwInstance, newPin, oldPin);
-
- return error;
-}
-
-/*
- * nssCKFWSession_GetOperationStateLen
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWSession_GetOperationStateLen
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
-{
- CK_ULONG mdAmt;
- CK_ULONG fwAmt;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (CK_ULONG)0;
- }
-
- *pError = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != *pError ) {
- return (CK_ULONG)0;
- }
-
- if (!fwSession->mdSession) {
- *pError = CKR_GENERAL_ERROR;
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- if (!fwSession->mdSession->GetOperationStateLen) {
- *pError = CKR_STATE_UNSAVEABLE;
- return (CK_ULONG)0;
- }
-
- /*
- * We could check that the session is actually in some state..
- */
-
- mdAmt = fwSession->mdSession->GetOperationStateLen(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
- fwSession->fwInstance, pError);
-
- if( ((CK_ULONG)0 == mdAmt) && (CKR_OK != *pError) ) {
- return (CK_ULONG)0;
- }
-
- /*
- * Add a bit of sanity-checking
- */
- fwAmt = mdAmt + 2*sizeof(CK_ULONG);
-
- return fwAmt;
-}
-
-/*
- * nssCKFWSession_GetOperationState
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_GetOperationState
-(
- NSSCKFWSession *fwSession,
- NSSItem *buffer
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG fwAmt;
- CK_ULONG *ulBuffer;
- NSSItem i2;
- CK_ULONG n, i;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!buffer) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if (!buffer->data) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- if (!fwSession->mdSession->GetOperationState) {
- return CKR_STATE_UNSAVEABLE;
- }
-
- /*
- * Sanity-check the caller's buffer.
- */
-
- error = CKR_OK;
- fwAmt = nssCKFWSession_GetOperationStateLen(fwSession, &error);
- if( ((CK_ULONG)0 == fwAmt) && (CKR_OK != error) ) {
- return error;
- }
-
- if( buffer->size < fwAmt ) {
- return CKR_BUFFER_TOO_SMALL;
- }
-
- ulBuffer = (CK_ULONG *)buffer->data;
-
- i2.size = buffer->size - 2*sizeof(CK_ULONG);
- i2.data = (void *)&ulBuffer[2];
-
- error = fwSession->mdSession->GetOperationState(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken,
- fwSession->mdInstance, fwSession->fwInstance, &i2);
-
- if( CKR_OK != error ) {
- return error;
- }
-
- /*
- * Add a little integrety/identity check.
- * NOTE: right now, it's pretty stupid.
- * A CRC or something would be better.
- */
-
- ulBuffer[0] = 0x434b4657; /* CKFW */
- ulBuffer[1] = 0;
- n = i2.size/sizeof(CK_ULONG);
- for( i = 0; i < n; i++ ) {
- ulBuffer[1] ^= ulBuffer[2+i];
- }
-
- return CKR_OK;
-}
-
-/*
- * nssCKFWSession_SetOperationState
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_SetOperationState
-(
- NSSCKFWSession *fwSession,
- NSSItem *state,
- NSSCKFWObject *encryptionKey,
- NSSCKFWObject *authenticationKey
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG *ulBuffer;
- CK_ULONG n, i;
- CK_ULONG x;
- NSSItem s;
- NSSCKMDObject *mdek;
- NSSCKMDObject *mdak;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!state) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if (!state->data) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if (encryptionKey) {
- error = nssCKFWObject_verifyPointer(encryptionKey);
- if( CKR_OK != error ) {
- return error;
- }
- }
-
- if (authenticationKey) {
- error = nssCKFWObject_verifyPointer(authenticationKey);
- if( CKR_OK != error ) {
- return error;
- }
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- ulBuffer = (CK_ULONG *)state->data;
- if( 0x43b4657 != ulBuffer[0] ) {
- return CKR_SAVED_STATE_INVALID;
- }
- n = (state->size / sizeof(CK_ULONG)) - 2;
- x = (CK_ULONG)0;
- for( i = 0; i < n; i++ ) {
- x ^= ulBuffer[2+i];
- }
-
- if( x != ulBuffer[1] ) {
- return CKR_SAVED_STATE_INVALID;
- }
-
- if (!fwSession->mdSession->SetOperationState) {
- return CKR_GENERAL_ERROR;
- }
-
- s.size = state->size - 2*sizeof(CK_ULONG);
- s.data = (void *)&ulBuffer[2];
-
- if (encryptionKey) {
- mdek = nssCKFWObject_GetMDObject(encryptionKey);
- } else {
- mdek = (NSSCKMDObject *)NULL;
- }
-
- if (authenticationKey) {
- mdak = nssCKFWObject_GetMDObject(authenticationKey);
- } else {
- mdak = (NSSCKMDObject *)NULL;
- }
-
- error = fwSession->mdSession->SetOperationState(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
- fwSession->fwInstance, &s, mdek, encryptionKey, mdak, authenticationKey);
-
- if( CKR_OK != error ) {
- return error;
- }
-
- /*
- * Here'd we restore any session data
- */
-
- return CKR_OK;
-}
-
-static CK_BBOOL
-nss_attributes_form_token_object
-(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount
-)
-{
- CK_ULONG i;
- CK_BBOOL rv;
-
- for( i = 0; i < ulAttributeCount; i++ ) {
- if( CKA_TOKEN == pTemplate[i].type ) {
- /* If we sanity-check, we can remove this sizeof check */
- if( sizeof(CK_BBOOL) == pTemplate[i].ulValueLen ) {
- (void)nsslibc_memcpy(&rv, pTemplate[i].pValue, sizeof(CK_BBOOL));
- return rv;
- } else {
- return CK_FALSE;
- }
- }
- }
-
- return CK_FALSE;
-}
-
-/*
- * nssCKFWSession_CreateObject
- *
- */
-NSS_IMPLEMENT NSSCKFWObject *
-nssCKFWSession_CreateObject
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- NSSArena *arena;
- NSSCKMDObject *mdObject;
- NSSCKFWObject *fwObject;
- CK_BBOOL isTokenObject;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWObject *)NULL;
- }
-
- *pError = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != pError ) {
- return (NSSCKFWObject *)NULL;
- }
-
- if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWObject *)NULL;
- }
-
- if (!fwSession->mdSession) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWObject *)NULL;
- }
-#endif /* NSSDEBUG */
-
- /*
- * Here would be an excellent place to sanity-check the object.
- */
-
- isTokenObject = nss_attributes_form_token_object(pTemplate, ulAttributeCount);
- if( CK_TRUE == isTokenObject ) {
- /* === TOKEN OBJECT === */
-
- if (!fwSession->mdSession->CreateObject) {
- *pError = CKR_TOKEN_WRITE_PROTECTED;
- return (NSSCKFWObject *)NULL;
- }
-
- arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
- if (!arena) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
- }
-
- goto callmdcreateobject;
- } else {
- /* === SESSION OBJECT === */
-
- arena = nssCKFWSession_GetArena(fwSession, pError);
- if (!arena) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
- }
-
- if( CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
- fwSession->fwInstance) ) {
- /* --- module handles the session object -- */
-
- if (!fwSession->mdSession->CreateObject) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWObject *)NULL;
- }
-
- goto callmdcreateobject;
- } else {
- /* --- framework handles the session object -- */
- mdObject = nssCKMDSessionObject_Create(fwSession->fwToken,
- arena, pTemplate, ulAttributeCount, pError);
- goto gotmdobject;
- }
- }
-
- callmdcreateobject:
- mdObject = fwSession->mdSession->CreateObject(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken,
- fwSession->mdInstance, fwSession->fwInstance, arena, pTemplate,
- ulAttributeCount, pError);
-
- gotmdobject:
- if (!mdObject) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
- }
-
- fwObject = nssCKFWObject_Create(arena, mdObject,
- isTokenObject ? NULL : fwSession,
- fwSession->fwToken, fwSession->fwInstance, pError);
- if (!fwObject) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
-
- if (mdObject->Destroy) {
- (void)mdObject->Destroy(mdObject, (NSSCKFWObject *)NULL,
- fwSession->mdSession, fwSession, fwSession->mdToken,
- fwSession->fwToken, fwSession->mdInstance, fwSession->fwInstance);
- }
-
- return (NSSCKFWObject *)NULL;
- }
-
- if( CK_FALSE == isTokenObject ) {
- if( CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, fwObject) ) {
- *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
- if( CKR_OK != *pError ) {
- nssCKFWObject_Finalize(fwObject, PR_TRUE);
- return (NSSCKFWObject *)NULL;
- }
- }
- }
-
- return fwObject;
-}
-
-/*
- * nssCKFWSession_CopyObject
- *
- */
-NSS_IMPLEMENT NSSCKFWObject *
-nssCKFWSession_CopyObject
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- CK_BBOOL oldIsToken;
- CK_BBOOL newIsToken;
- CK_ULONG i;
- NSSCKFWObject *rv;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWObject *)NULL;
- }
-
- *pError = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != *pError ) {
- return (NSSCKFWObject *)NULL;
- }
-
- *pError = nssCKFWObject_verifyPointer(fwObject);
- if( CKR_OK != *pError ) {
- return (NSSCKFWObject *)NULL;
- }
-
- if (!fwSession->mdSession) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWObject *)NULL;
- }
-#endif /* NSSDEBUG */
-
- /*
- * Sanity-check object
- */
-
- if (!fwObject) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWObject *)NULL;
- }
-
- oldIsToken = nssCKFWObject_IsTokenObject(fwObject);
-
- newIsToken = oldIsToken;
- for( i = 0; i < ulAttributeCount; i++ ) {
- if( CKA_TOKEN == pTemplate[i].type ) {
- /* Since we sanity-checked the object, we know this is the right size. */
- (void)nsslibc_memcpy(&newIsToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
- break;
- }
- }
-
- /*
- * If the Module handles its session objects, or if both the new
- * and old object are token objects, use CopyObject if it exists.
- */
-
- if ((fwSession->mdSession->CopyObject) &&
- (((CK_TRUE == oldIsToken) && (CK_TRUE == newIsToken)) ||
- (CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
- fwSession->fwInstance))) ) {
- /* use copy object */
- NSSArena *arena;
- NSSCKMDObject *mdOldObject;
- NSSCKMDObject *mdObject;
-
- mdOldObject = nssCKFWObject_GetMDObject(fwObject);
-
- if( CK_TRUE == newIsToken ) {
- arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
- } else {
- arena = nssCKFWSession_GetArena(fwSession, pError);
- }
- if (!arena) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
- }
-
- mdObject = fwSession->mdSession->CopyObject(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken,
- fwSession->mdInstance, fwSession->fwInstance, mdOldObject,
- fwObject, arena, pTemplate, ulAttributeCount, pError);
- if (!mdObject) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWObject *)NULL;
- }
-
- rv = nssCKFWObject_Create(arena, mdObject,
- newIsToken ? NULL : fwSession,
- fwSession->fwToken, fwSession->fwInstance, pError);
-
- if( CK_FALSE == newIsToken ) {
- if( CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, rv) ) {
- *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, rv, rv);
- if( CKR_OK != *pError ) {
- nssCKFWObject_Finalize(rv, PR_TRUE);
- return (NSSCKFWObject *)NULL;
- }
- }
- }
-
- return rv;
- } else {
- /* use create object */
- NSSArena *tmpArena;
- CK_ATTRIBUTE_PTR newTemplate;
- CK_ULONG i, j, n, newLength, k;
- CK_ATTRIBUTE_TYPE_PTR oldTypes;
- NSSCKFWObject *rv;
-
- n = nssCKFWObject_GetAttributeCount(fwObject, pError);
- if( (0 == n) && (CKR_OK != *pError) ) {
- return (NSSCKFWObject *)NULL;
- }
-
- tmpArena = NSSArena_Create();
- if (!tmpArena) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWObject *)NULL;
- }
-
- oldTypes = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE_TYPE, n);
- if( (CK_ATTRIBUTE_TYPE_PTR)NULL == oldTypes ) {
- NSSArena_Destroy(tmpArena);
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWObject *)NULL;
- }
-
- *pError = nssCKFWObject_GetAttributeTypes(fwObject, oldTypes, n);
- if( CKR_OK != *pError ) {
- NSSArena_Destroy(tmpArena);
- return (NSSCKFWObject *)NULL;
- }
-
- newLength = n;
- for( i = 0; i < ulAttributeCount; i++ ) {
- for( j = 0; j < n; j++ ) {
- if( oldTypes[j] == pTemplate[i].type ) {
- if( (CK_VOID_PTR)NULL == pTemplate[i].pValue ) {
- /* Removing the attribute */
- newLength--;
- }
- break;
- }
- }
- if( j == n ) {
- /* Not found */
- newLength++;
- }
- }
-
- newTemplate = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE, newLength);
- if( (CK_ATTRIBUTE_PTR)NULL == newTemplate ) {
- NSSArena_Destroy(tmpArena);
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWObject *)NULL;
- }
-
- k = 0;
- for( j = 0; j < n; j++ ) {
- for( i = 0; i < ulAttributeCount; i++ ) {
- if( oldTypes[j] == pTemplate[i].type ) {
- if( (CK_VOID_PTR)NULL == pTemplate[i].pValue ) {
- /* This attribute is being deleted */
- ;
- } else {
- /* This attribute is being replaced */
- newTemplate[k].type = pTemplate[i].type;
- newTemplate[k].pValue = pTemplate[i].pValue;
- newTemplate[k].ulValueLen = pTemplate[i].ulValueLen;
- k++;
- }
- break;
- }
- }
- if( i == ulAttributeCount ) {
- /* This attribute is being copied over from the old object */
- NSSItem item, *it;
- item.size = 0;
- item.data = (void *)NULL;
- it = nssCKFWObject_GetAttribute(fwObject, oldTypes[j],
- &item, tmpArena, pError);
- if (!it) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- NSSArena_Destroy(tmpArena);
- return (NSSCKFWObject *)NULL;
- }
- newTemplate[k].type = oldTypes[j];
- newTemplate[k].pValue = it->data;
- newTemplate[k].ulValueLen = it->size;
- k++;
- }
- }
- /* assert that k == newLength */
-
- rv = nssCKFWSession_CreateObject(fwSession, newTemplate, newLength, pError);
- if (!rv) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- NSSArena_Destroy(tmpArena);
- return (NSSCKFWObject *)NULL;
- }
-
- NSSArena_Destroy(tmpArena);
- return rv;
- }
-}
-
-/*
- * nssCKFWSession_FindObjectsInit
- *
- */
-NSS_IMPLEMENT NSSCKFWFindObjects *
-nssCKFWSession_FindObjectsInit
-(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError
-)
-{
- NSSCKMDFindObjects *mdfo1 = (NSSCKMDFindObjects *)NULL;
- NSSCKMDFindObjects *mdfo2 = (NSSCKMDFindObjects *)NULL;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWFindObjects *)NULL;
- }
-
- *pError = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != *pError ) {
- return (NSSCKFWFindObjects *)NULL;
- }
-
- if( ((CK_ATTRIBUTE_PTR)NULL == pTemplate) && (ulAttributeCount != 0) ) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWFindObjects *)NULL;
- }
-
- if (!fwSession->mdSession) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWFindObjects *)NULL;
- }
-#endif /* NSSDEBUG */
-
- if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
- fwSession->fwInstance) ) {
- CK_ULONG i;
-
- /*
- * Does the search criteria restrict us to token or session
- * objects?
- */
-
- for( i = 0; i < ulAttributeCount; i++ ) {
- if( CKA_TOKEN == pTemplate[i].type ) {
- /* Yes, it does. */
- CK_BBOOL isToken;
- if( sizeof(CK_BBOOL) != pTemplate[i].ulValueLen ) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (NSSCKFWFindObjects *)NULL;
- }
- (void)nsslibc_memcpy(&isToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
-
- if( CK_TRUE == isToken ) {
- /* Pass it on to the module's search routine */
- if (!fwSession->mdSession->FindObjectsInit) {
- goto wrap;
- }
-
- mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken,
- fwSession->mdInstance, fwSession->fwInstance,
- pTemplate, ulAttributeCount, pError);
- } else {
- /* Do the search ourselves */
- mdfo1 = nssCKMDFindSessionObjects_Create(fwSession->fwToken,
- pTemplate, ulAttributeCount, pError);
- }
-
- if (!mdfo1) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWFindObjects *)NULL;
- }
-
- goto wrap;
- }
- }
-
- if( i == ulAttributeCount ) {
- /* No, it doesn't. Do a hybrid search. */
- mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken,
- fwSession->mdInstance, fwSession->fwInstance,
- pTemplate, ulAttributeCount, pError);
-
- if (!mdfo1) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWFindObjects *)NULL;
- }
-
- mdfo2 = nssCKMDFindSessionObjects_Create(fwSession->fwToken,
- pTemplate, ulAttributeCount, pError);
- if (!mdfo2) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- if (mdfo1->Final) {
- mdfo1->Final(mdfo1, (NSSCKFWFindObjects *)NULL, fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken,
- fwSession->mdInstance, fwSession->fwInstance);
- }
- return (NSSCKFWFindObjects *)NULL;
- }
-
- goto wrap;
- }
- /*NOTREACHED*/
- } else {
- /* Module handles all its own objects. Pass on to module's search */
- mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
- fwSession, fwSession->mdToken, fwSession->fwToken,
- fwSession->mdInstance, fwSession->fwInstance,
- pTemplate, ulAttributeCount, pError);
-
- if (!mdfo1) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWFindObjects *)NULL;
- }
-
- goto wrap;
- }
-
- wrap:
- return nssCKFWFindObjects_Create(fwSession, fwSession->fwToken,
- fwSession->fwInstance, mdfo1, mdfo2, pError);
-}
-
-/*
- * nssCKFWSession_SeedRandom
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_SeedRandom
-(
- NSSCKFWSession *fwSession,
- NSSItem *seed
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!seed) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if (!seed->data) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if( 0 == seed->size ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- if (!fwSession->mdSession->SeedRandom) {
- return CKR_RANDOM_SEED_NOT_SUPPORTED;
- }
-
- error = fwSession->mdSession->SeedRandom(fwSession->mdSession, fwSession,
- fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
- fwSession->fwInstance, seed);
-
- return error;
-}
-
-/*
- * nssCKFWSession_GetRandom
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_GetRandom
-(
- NSSCKFWSession *fwSession,
- NSSItem *buffer
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!buffer) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if (!buffer->data) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- if (!fwSession->mdSession->GetRandom) {
- if( CK_TRUE == nssCKFWToken_GetHasRNG(fwSession->fwToken) ) {
- return CKR_GENERAL_ERROR;
- } else {
- return CKR_RANDOM_NO_RNG;
- }
- }
-
- if( 0 == buffer->size ) {
- return CKR_OK;
- }
-
- error = fwSession->mdSession->GetRandom(fwSession->mdSession, fwSession,
- fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
- fwSession->fwInstance, buffer);
-
- return error;
-}
-
-
-/*
- * nssCKFWSession_SetCurrentCryptoOperation
- */
-NSS_IMPLEMENT void
-nssCKFWSession_SetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperation * fwOperation,
- NSSCKFWCryptoOperationState state
-)
-{
-#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return;
- }
-
- if ( state >= NSSCKFWCryptoOperationState_Max) {
- return;
- }
-
- if (!fwSession->mdSession) {
- return;
- }
-#endif /* NSSDEBUG */
- fwSession->fwOperationArray[state] = fwOperation;
- return;
-}
-
-/*
- * nssCKFWSession_GetCurrentCryptoOperation
- */
-NSS_IMPLEMENT NSSCKFWCryptoOperation *
-nssCKFWSession_GetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationState state
-)
-{
-#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return (NSSCKFWCryptoOperation *)NULL;
- }
-
- if ( state >= NSSCKFWCryptoOperationState_Max) {
- return (NSSCKFWCryptoOperation *)NULL;
- }
-
- if (!fwSession->mdSession) {
- return (NSSCKFWCryptoOperation *)NULL;
- }
-#endif /* NSSDEBUG */
- return fwSession->fwOperationArray[state];
-}
-
-/*
- * nssCKFWSession_Final
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_Final
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType type,
- NSSCKFWCryptoOperationState state,
- CK_BYTE_PTR outBuf,
- CK_ULONG_PTR outBufLen
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSItem outputBuffer;
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- /* make sure we have a valid operation initialized */
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
- if (!fwOperation) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- /* make sure it's the correct type */
- if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- /* handle buffer issues, note for Verify, the type is an input buffer. */
- if (NSSCKFWCryptoOperationType_Verify == type) {
- if ((CK_BYTE_PTR)NULL == outBuf) {
- error = CKR_ARGUMENTS_BAD;
- goto done;
- }
- } else {
- CK_ULONG len = nssCKFWCryptoOperation_GetFinalLength(fwOperation, &error);
- CK_ULONG maxBufLen = *outBufLen;
-
- if (CKR_OK != error) {
- goto done;
- }
- *outBufLen = len;
- if ((CK_BYTE_PTR)NULL == outBuf) {
- return CKR_OK;
- }
-
- if (len > maxBufLen) {
- return CKR_BUFFER_TOO_SMALL;
- }
- }
- outputBuffer.data = outBuf;
- outputBuffer.size = *outBufLen;
-
- error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer);
-done:
- if (CKR_BUFFER_TOO_SMALL == error) {
- return error;
- }
- /* clean up our state */
- nssCKFWCryptoOperation_Destroy(fwOperation);
- nssCKFWSession_SetCurrentCryptoOperation(fwSession, NULL, state);
- return error;
-}
-
-/*
- * nssCKFWSession_Update
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_Update
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType type,
- NSSCKFWCryptoOperationState state,
- CK_BYTE_PTR inBuf,
- CK_ULONG inBufLen,
- CK_BYTE_PTR outBuf,
- CK_ULONG_PTR outBufLen
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSItem inputBuffer;
- NSSItem outputBuffer;
- CK_ULONG len;
- CK_ULONG maxBufLen;
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- /* make sure we have a valid operation initialized */
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
- if (!fwOperation) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- /* make sure it's the correct type */
- if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- inputBuffer.data = inBuf;
- inputBuffer.size = inBufLen;
-
- /* handle buffer issues, note for Verify, the type is an input buffer. */
- len = nssCKFWCryptoOperation_GetOperationLength(fwOperation, &inputBuffer,
- &error);
- if (CKR_OK != error) {
- return error;
- }
- maxBufLen = *outBufLen;
-
- *outBufLen = len;
- if ((CK_BYTE_PTR)NULL == outBuf) {
- return CKR_OK;
- }
-
- if (len > maxBufLen) {
- return CKR_BUFFER_TOO_SMALL;
- }
- outputBuffer.data = outBuf;
- outputBuffer.size = *outBufLen;
-
- return nssCKFWCryptoOperation_Update(fwOperation,
- &inputBuffer, &outputBuffer);
-}
-
-/*
- * nssCKFWSession_DigestUpdate
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_DigestUpdate
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType type,
- NSSCKFWCryptoOperationState state,
- CK_BYTE_PTR inBuf,
- CK_ULONG inBufLen
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSItem inputBuffer;
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- /* make sure we have a valid operation initialized */
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
- if (!fwOperation) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- /* make sure it's the correct type */
- if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- inputBuffer.data = inBuf;
- inputBuffer.size = inBufLen;
-
-
- error = nssCKFWCryptoOperation_DigestUpdate(fwOperation, &inputBuffer);
- return error;
-}
-
-/*
- * nssCKFWSession_DigestUpdate
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_DigestKey
-(
- NSSCKFWSession *fwSession,
- NSSCKFWObject *fwKey
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSItem *inputBuffer;
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- /* make sure we have a valid operation initialized */
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- NSSCKFWCryptoOperationState_Digest);
- if (!fwOperation) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- /* make sure it's the correct type */
- if (NSSCKFWCryptoOperationType_Digest !=
- nssCKFWCryptoOperation_GetType(fwOperation)) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- error = nssCKFWCryptoOperation_DigestKey(fwOperation, fwKey);
- if (CKR_FUNCTION_FAILED != error) {
- return error;
- }
-
- /* no machine depended way for this to happen, do it by hand */
- inputBuffer=nssCKFWObject_GetAttribute(fwKey, CKA_VALUE, NULL, NULL, &error);
- if (!inputBuffer) {
- /* couldn't get the value, just fail then */
- return error;
- }
- error = nssCKFWCryptoOperation_DigestUpdate(fwOperation, inputBuffer);
- nssItem_Destroy(inputBuffer);
- return error;
-}
-
-/*
- * nssCKFWSession_UpdateFinal
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_UpdateFinal
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType type,
- NSSCKFWCryptoOperationState state,
- CK_BYTE_PTR inBuf,
- CK_ULONG inBufLen,
- CK_BYTE_PTR outBuf,
- CK_ULONG_PTR outBufLen
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSItem inputBuffer;
- NSSItem outputBuffer;
- PRBool isEncryptDecrypt;
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- /* make sure we have a valid operation initialized */
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
- if (!fwOperation) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- /* make sure it's the correct type */
- if (type != nssCKFWCryptoOperation_GetType(fwOperation)) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- inputBuffer.data = inBuf;
- inputBuffer.size = inBufLen;
- isEncryptDecrypt = (PRBool) ((NSSCKFWCryptoOperationType_Encrypt == type) ||
- (NSSCKFWCryptoOperationType_Decrypt == type)) ;
-
- /* handle buffer issues, note for Verify, the type is an input buffer. */
- if (NSSCKFWCryptoOperationType_Verify == type) {
- if ((CK_BYTE_PTR)NULL == outBuf) {
- error = CKR_ARGUMENTS_BAD;
- goto done;
- }
- } else {
- CK_ULONG maxBufLen = *outBufLen;
- CK_ULONG len;
-
- len = (isEncryptDecrypt) ?
- nssCKFWCryptoOperation_GetOperationLength(fwOperation,
- &inputBuffer, &error) :
- nssCKFWCryptoOperation_GetFinalLength(fwOperation, &error);
-
- if (CKR_OK != error) {
- goto done;
- }
-
- *outBufLen = len;
- if ((CK_BYTE_PTR)NULL == outBuf) {
- return CKR_OK;
- }
-
- if (len > maxBufLen) {
- return CKR_BUFFER_TOO_SMALL;
- }
- }
- outputBuffer.data = outBuf;
- outputBuffer.size = *outBufLen;
-
- error = nssCKFWCryptoOperation_UpdateFinal(fwOperation,
- &inputBuffer, &outputBuffer);
-
- /* UpdateFinal isn't support, manually use Update and Final */
- if (CKR_FUNCTION_FAILED == error) {
- error = isEncryptDecrypt ?
- nssCKFWCryptoOperation_Update(fwOperation, &inputBuffer, &outputBuffer) :
- nssCKFWCryptoOperation_DigestUpdate(fwOperation, &inputBuffer);
-
- if (CKR_OK == error) {
- error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer);
- }
- }
-
-
-done:
- if (CKR_BUFFER_TOO_SMALL == error) {
- /* if we return CKR_BUFFER_TOO_SMALL, we the caller is not expecting.
- * the crypto state to be freed */
- return error;
- }
-
- /* clean up our state */
- nssCKFWCryptoOperation_Destroy(fwOperation);
- nssCKFWSession_SetCurrentCryptoOperation(fwSession, NULL, state);
- return error;
-}
-
-NSS_IMPLEMENT CK_RV
-nssCKFWSession_UpdateCombo
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationType encryptType,
- NSSCKFWCryptoOperationType digestType,
- NSSCKFWCryptoOperationState digestState,
- CK_BYTE_PTR inBuf,
- CK_ULONG inBufLen,
- CK_BYTE_PTR outBuf,
- CK_ULONG_PTR outBufLen
-)
-{
- NSSCKFWCryptoOperation *fwOperation;
- NSSCKFWCryptoOperation *fwPeerOperation;
- NSSItem inputBuffer;
- NSSItem outputBuffer;
- CK_ULONG maxBufLen = *outBufLen;
- CK_ULONG len;
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSession->mdSession) {
- return CKR_GENERAL_ERROR;
- }
-#endif /* NSSDEBUG */
-
- /* make sure we have a valid operation initialized */
- fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- NSSCKFWCryptoOperationState_EncryptDecrypt);
- if (!fwOperation) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- /* make sure it's the correct type */
- if (encryptType != nssCKFWCryptoOperation_GetType(fwOperation)) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
- /* make sure we have a valid operation initialized */
- fwPeerOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession,
- digestState);
- if (!fwPeerOperation) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- /* make sure it's the correct type */
- if (digestType != nssCKFWCryptoOperation_GetType(fwOperation)) {
- return CKR_OPERATION_NOT_INITIALIZED;
- }
-
- inputBuffer.data = inBuf;
- inputBuffer.size = inBufLen;
- len = nssCKFWCryptoOperation_GetOperationLength(fwOperation,
- &inputBuffer, &error);
- if (CKR_OK != error) {
- return error;
- }
-
- *outBufLen = len;
- if ((CK_BYTE_PTR)NULL == outBuf) {
- return CKR_OK;
- }
-
- if (len > maxBufLen) {
- return CKR_BUFFER_TOO_SMALL;
- }
-
- outputBuffer.data = outBuf;
- outputBuffer.size = *outBufLen;
-
- error = nssCKFWCryptoOperation_UpdateCombo(fwOperation, fwPeerOperation,
- &inputBuffer, &outputBuffer);
- if (CKR_FUNCTION_FAILED == error) {
- PRBool isEncrypt =
- (PRBool) (NSSCKFWCryptoOperationType_Encrypt == encryptType);
-
- if (isEncrypt) {
- error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation,
- &inputBuffer);
- if (CKR_OK != error) {
- return error;
- }
- }
- error = nssCKFWCryptoOperation_Update(fwOperation,
- &inputBuffer, &outputBuffer);
- if (CKR_OK != error) {
- return error;
- }
- if (!isEncrypt) {
- error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation,
- &outputBuffer);
- }
- }
- return error;
-}
-
-
-/*
- * NSSCKFWSession_GetMDSession
- *
- */
-
-NSS_IMPLEMENT NSSCKMDSession *
-NSSCKFWSession_GetMDSession
-(
- NSSCKFWSession *fwSession
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return (NSSCKMDSession *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWSession_GetMDSession(fwSession);
-}
-
-/*
- * NSSCKFWSession_GetArena
- *
- */
-
-NSS_IMPLEMENT NSSArena *
-NSSCKFWSession_GetArena
-(
- NSSCKFWSession *fwSession,
- CK_RV *pError
-)
-{
-#ifdef DEBUG
- if (!pError) {
- return (NSSArena *)NULL;
- }
-
- *pError = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != *pError ) {
- return (NSSArena *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWSession_GetArena(fwSession, pError);
-}
-
-/*
- * NSSCKFWSession_CallNotification
- *
- */
-
-NSS_IMPLEMENT CK_RV
-NSSCKFWSession_CallNotification
-(
- NSSCKFWSession *fwSession,
- CK_NOTIFICATION event
-)
-{
-#ifdef DEBUG
- CK_RV error = CKR_OK;
-
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* DEBUG */
-
- return nssCKFWSession_CallNotification(fwSession, event);
-}
-
-/*
- * NSSCKFWSession_IsRWSession
- *
- */
-
-NSS_IMPLEMENT CK_BBOOL
-NSSCKFWSession_IsRWSession
-(
- NSSCKFWSession *fwSession
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CK_FALSE;
- }
-#endif /* DEBUG */
-
- return nssCKFWSession_IsRWSession(fwSession);
-}
-
-/*
- * NSSCKFWSession_IsSO
- *
- */
-
-NSS_IMPLEMENT CK_BBOOL
-NSSCKFWSession_IsSO
-(
- NSSCKFWSession *fwSession
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
- return CK_FALSE;
- }
-#endif /* DEBUG */
-
- return nssCKFWSession_IsSO(fwSession);
-}
-
-NSS_IMPLEMENT NSSCKFWCryptoOperation *
-NSSCKFWSession_GetCurrentCryptoOperation
-(
- NSSCKFWSession *fwSession,
- NSSCKFWCryptoOperationState state
-)
-{
-#ifdef DEBUG
- CK_RV error = CKR_OK;
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return (NSSCKFWCryptoOperation *)NULL;
- }
-
- if ( state >= NSSCKFWCryptoOperationState_Max) {
- return (NSSCKFWCryptoOperation *)NULL;
- }
-#endif /* DEBUG */
- return nssCKFWSession_GetCurrentCryptoOperation(fwSession, state);
-}
diff --git a/security/nss/lib/ckfw/sessobj.c b/security/nss/lib/ckfw/sessobj.c
deleted file mode 100644
index d94ed7e87..000000000
--- a/security/nss/lib/ckfw/sessobj.c
+++ /dev/null
@@ -1,1079 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * sessobj.c
- *
- * This file contains an NSSCKMDObject implementation for session
- * objects. The framework uses this implementation to manage
- * session objects when a Module doesn't wish to be bothered.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * nssCKMDSessionObject
- *
- * -- create --
- * nssCKMDSessionObject_Create
- *
- * -- EPV calls --
- * nss_ckmdSessionObject_Finalize
- * nss_ckmdSessionObject_IsTokenObject
- * nss_ckmdSessionObject_GetAttributeCount
- * nss_ckmdSessionObject_GetAttributeTypes
- * nss_ckmdSessionObject_GetAttributeSize
- * nss_ckmdSessionObject_GetAttribute
- * nss_ckmdSessionObject_SetAttribute
- * nss_ckmdSessionObject_GetObjectSize
- */
-
-struct nssCKMDSessionObjectStr {
- CK_ULONG n;
- NSSArena *arena;
- NSSItem *attributes;
- CK_ATTRIBUTE_TYPE_PTR types;
- nssCKFWHash *hash;
-};
-typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject;
-
-#ifdef DEBUG
-/*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do this routines as no-ops.
- */
-
-static CK_RV
-nss_ckmdSessionObject_add_pointer
-(
- const NSSCKMDObject *mdObject
-)
-{
- return CKR_OK;
-}
-
-static CK_RV
-nss_ckmdSessionObject_remove_pointer
-(
- const NSSCKMDObject *mdObject
-)
-{
- return CKR_OK;
-}
-
-#ifdef NSS_DEBUG
-static CK_RV
-nss_ckmdSessionObject_verifyPointer
-(
- const NSSCKMDObject *mdObject
-)
-{
- return CKR_OK;
-}
-#endif
-
-#endif /* DEBUG */
-
-/*
- * We must forward-declare these routines
- */
-static void
-nss_ckmdSessionObject_Finalize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-);
-
-static CK_RV
-nss_ckmdSessionObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-);
-
-static CK_BBOOL
-nss_ckmdSessionObject_IsTokenObject
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-);
-
-static CK_ULONG
-nss_ckmdSessionObject_GetAttributeCount
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
-
-static CK_RV
-nss_ckmdSessionObject_GetAttributeTypes
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-);
-
-static CK_ULONG
-nss_ckmdSessionObject_GetAttributeSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-);
-
-static NSSCKFWItem
-nss_ckmdSessionObject_GetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-);
-
-static CK_RV
-nss_ckmdSessionObject_SetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value
-);
-
-static CK_ULONG
-nss_ckmdSessionObject_GetObjectSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-);
-
-/*
- * nssCKMDSessionObject_Create
- *
- */
-NSS_IMPLEMENT NSSCKMDObject *
-nssCKMDSessionObject_Create
-(
- NSSCKFWToken *fwToken,
- NSSArena *arena,
- CK_ATTRIBUTE_PTR attributes,
- CK_ULONG ulCount,
- CK_RV *pError
-)
-{
- NSSCKMDObject *mdObject = (NSSCKMDObject *)NULL;
- nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)NULL;
- CK_ULONG i;
- nssCKFWHash *hash;
-
- *pError = CKR_OK;
-
- mdso = nss_ZNEW(arena, nssCKMDSessionObject);
- if (!mdso) {
- goto loser;
- }
-
- mdso->arena = arena;
- mdso->n = ulCount;
- mdso->attributes = nss_ZNEWARRAY(arena, NSSItem, ulCount);
- if (!mdso->attributes) {
- goto loser;
- }
-
- mdso->types = nss_ZNEWARRAY(arena, CK_ATTRIBUTE_TYPE, ulCount);
- if (!mdso->types) {
- goto loser;
- }
- for( i = 0; i < ulCount; i++ ) {
- mdso->types[i] = attributes[i].type;
- mdso->attributes[i].size = attributes[i].ulValueLen;
- mdso->attributes[i].data = nss_ZAlloc(arena, attributes[i].ulValueLen);
- if (!mdso->attributes[i].data) {
- goto loser;
- }
- (void)nsslibc_memcpy(mdso->attributes[i].data, attributes[i].pValue,
- attributes[i].ulValueLen);
- }
-
- mdObject = nss_ZNEW(arena, NSSCKMDObject);
- if (!mdObject) {
- goto loser;
- }
-
- mdObject->etc = (void *)mdso;
- mdObject->Finalize = nss_ckmdSessionObject_Finalize;
- mdObject->Destroy = nss_ckmdSessionObject_Destroy;
- mdObject->IsTokenObject = nss_ckmdSessionObject_IsTokenObject;
- mdObject->GetAttributeCount = nss_ckmdSessionObject_GetAttributeCount;
- mdObject->GetAttributeTypes = nss_ckmdSessionObject_GetAttributeTypes;
- mdObject->GetAttributeSize = nss_ckmdSessionObject_GetAttributeSize;
- mdObject->GetAttribute = nss_ckmdSessionObject_GetAttribute;
- mdObject->SetAttribute = nss_ckmdSessionObject_SetAttribute;
- mdObject->GetObjectSize = nss_ckmdSessionObject_GetObjectSize;
-
- hash = nssCKFWToken_GetSessionObjectHash(fwToken);
- if (!hash) {
- *pError = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- mdso->hash = hash;
-
- *pError = nssCKFWHash_Add(hash, mdObject, mdObject);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-
-#ifdef DEBUG
- if(( *pError = nss_ckmdSessionObject_add_pointer(mdObject)) != CKR_OK ) {
- goto loser;
- }
-#endif /* DEBUG */
-
- return mdObject;
-
- loser:
- if (mdso) {
- if (mdso->attributes) {
- for( i = 0; i < ulCount; i++ ) {
- nss_ZFreeIf(mdso->attributes[i].data);
- }
- nss_ZFreeIf(mdso->attributes);
- }
- nss_ZFreeIf(mdso->types);
- nss_ZFreeIf(mdso);
- }
-
- nss_ZFreeIf(mdObject);
- if (*pError == CKR_OK) {
- *pError = CKR_HOST_MEMORY;
- }
- return (NSSCKMDObject *)NULL;
-}
-
-/*
- * nss_ckmdSessionObject_Finalize
- *
- */
-static void
-nss_ckmdSessionObject_Finalize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- /* This shouldn't ever be called */
- return;
-}
-
-/*
- * nss_ckmdSessionObject_Destroy
- *
- */
-
-static CK_RV
-nss_ckmdSessionObject_Destroy
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
-#endif /* NSSDEBUG */
- nssCKMDSessionObject *mdso;
- CK_ULONG i;
-
-#ifdef NSSDEBUG
- error = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- mdso = (nssCKMDSessionObject *)mdObject->etc;
-
- nssCKFWHash_Remove(mdso->hash, mdObject);
-
- for( i = 0; i < mdso->n; i++ ) {
- nss_ZFreeIf(mdso->attributes[i].data);
- }
- nss_ZFreeIf(mdso->attributes);
- nss_ZFreeIf(mdso->types);
- nss_ZFreeIf(mdso);
- nss_ZFreeIf(mdObject);
-
-#ifdef DEBUG
- (void)nss_ckmdSessionObject_remove_pointer(mdObject);
-#endif /* DEBUG */
-
- return CKR_OK;
-}
-
-/*
- * nss_ckmdSessionObject_IsTokenObject
- *
- */
-
-static CK_BBOOL
-nss_ckmdSessionObject_IsTokenObject
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nss_ckmdSessionObject_verifyPointer(mdObject) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- /*
- * This implementation is only ever used for session objects.
- */
- return CK_FALSE;
-}
-
-/*
- * nss_ckmdSessionObject_GetAttributeCount
- *
- */
-static CK_ULONG
-nss_ckmdSessionObject_GetAttributeCount
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- nssCKMDSessionObject *obj;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return 0;
- }
-
- *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != *pError ) {
- return 0;
- }
-
- /* We could even check all the other arguments, for sanity. */
-#endif /* NSSDEBUG */
-
- obj = (nssCKMDSessionObject *)mdObject->etc;
-
- return obj->n;
-}
-
-/*
- * nss_ckmdSessionObject_GetAttributeTypes
- *
- */
-static CK_RV
-nss_ckmdSessionObject_GetAttributeTypes
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount
-)
-{
-#ifdef NSSDEBUG
- CK_RV error = CKR_OK;
-#endif /* NSSDEBUG */
- nssCKMDSessionObject *obj;
-
-#ifdef NSSDEBUG
- error = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != error ) {
- return error;
- }
-
- /* We could even check all the other arguments, for sanity. */
-#endif /* NSSDEBUG */
-
- obj = (nssCKMDSessionObject *)mdObject->etc;
-
- if( ulCount < obj->n ) {
- return CKR_BUFFER_TOO_SMALL;
- }
-
- (void)nsslibc_memcpy(typeArray, obj->types,
- sizeof(CK_ATTRIBUTE_TYPE) * obj->n);
-
- return CKR_OK;
-}
-
-/*
- * nss_ckmdSessionObject_GetAttributeSize
- *
- */
-static CK_ULONG
-nss_ckmdSessionObject_GetAttributeSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- nssCKMDSessionObject *obj;
- CK_ULONG i;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return 0;
- }
-
- *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != *pError ) {
- return 0;
- }
-
- /* We could even check all the other arguments, for sanity. */
-#endif /* NSSDEBUG */
-
- obj = (nssCKMDSessionObject *)mdObject->etc;
-
- for( i = 0; i < obj->n; i++ ) {
- if( attribute == obj->types[i] ) {
- return (CK_ULONG)(obj->attributes[i].size);
- }
- }
-
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return 0;
-}
-
-/*
- * nss_ckmdSessionObject_GetAttribute
- *
- */
-static NSSCKFWItem
-nss_ckmdSessionObject_GetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError
-)
-{
- NSSCKFWItem item;
- nssCKMDSessionObject *obj;
- CK_ULONG i;
-
- item.needsFreeing = PR_FALSE;
- item.item = NULL;
-#ifdef NSSDEBUG
- if (!pError) {
- return item;
- }
-
- *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != *pError ) {
- return item;
- }
-
- /* We could even check all the other arguments, for sanity. */
-#endif /* NSSDEBUG */
-
- obj = (nssCKMDSessionObject *)mdObject->etc;
-
- for( i = 0; i < obj->n; i++ ) {
- if( attribute == obj->types[i] ) {
- item.item = &obj->attributes[i];
- return item;
- }
- }
-
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return item;
-}
-
-/*
- * nss_ckmdSessionObject_SetAttribute
- *
- */
-
-/*
- * Okay, so this implementation sucks. It doesn't support removing
- * an attribute (if value == NULL), and could be more graceful about
- * memory. It should allow "blank" slots in the arrays, with some
- * invalid attribute type, and then it could support removal much
- * more easily. Do this later.
- */
-static CK_RV
-nss_ckmdSessionObject_SetAttribute
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value
-)
-{
- nssCKMDSessionObject *obj;
- CK_ULONG i;
- NSSItem n;
- NSSItem *ra;
- CK_ATTRIBUTE_TYPE_PTR rt;
-#ifdef NSSDEBUG
- CK_RV error;
-#endif /* NSSDEBUG */
-
-#ifdef NSSDEBUG
- error = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != error ) {
- return 0;
- }
-
- /* We could even check all the other arguments, for sanity. */
-#endif /* NSSDEBUG */
-
- obj = (nssCKMDSessionObject *)mdObject->etc;
-
- n.size = value->size;
- n.data = nss_ZAlloc(obj->arena, n.size);
- if (!n.data) {
- return CKR_HOST_MEMORY;
- }
- (void)nsslibc_memcpy(n.data, value->data, n.size);
-
- for( i = 0; i < obj->n; i++ ) {
- if( attribute == obj->types[i] ) {
- nss_ZFreeIf(obj->attributes[i].data);
- obj->attributes[i] = n;
- return CKR_OK;
- }
- }
-
- /*
- * It's new.
- */
-
- ra = (NSSItem *)nss_ZRealloc(obj->attributes, sizeof(NSSItem) * (obj->n + 1));
- if (!ra) {
- nss_ZFreeIf(n.data);
- return CKR_HOST_MEMORY;
- }
- obj->attributes = ra;
-
- rt = (CK_ATTRIBUTE_TYPE_PTR)nss_ZRealloc(obj->types,
- sizeof(CK_ATTRIBUTE_TYPE) * (obj->n + 1));
- if (!rt) {
- nss_ZFreeIf(n.data);
- return CKR_HOST_MEMORY;
- }
-
- obj->types = rt;
- obj->attributes[obj->n] = n;
- obj->types[obj->n] = attribute;
- obj->n++;
-
- return CKR_OK;
-}
-
-/*
- * nss_ckmdSessionObject_GetObjectSize
- *
- */
-static CK_ULONG
-nss_ckmdSessionObject_GetObjectSize
-(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError
-)
-{
- nssCKMDSessionObject *obj;
- CK_ULONG i;
- CK_ULONG rv = (CK_ULONG)0;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return 0;
- }
-
- *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
- if( CKR_OK != *pError ) {
- return 0;
- }
-
- /* We could even check all the other arguments, for sanity. */
-#endif /* NSSDEBUG */
-
- obj = (nssCKMDSessionObject *)mdObject->etc;
-
- for( i = 0; i < obj->n; i++ ) {
- rv += obj->attributes[i].size;
- }
-
- rv += sizeof(NSSItem) * obj->n;
- rv += sizeof(CK_ATTRIBUTE_TYPE) * obj->n;
- rv += sizeof(nssCKMDSessionObject);
-
- return rv;
-}
-
-/*
- * nssCKMDFindSessionObjects
- *
- * -- create --
- * nssCKMDFindSessionObjects_Create
- *
- * -- EPV calls --
- * nss_ckmdFindSessionObjects_Final
- * nss_ckmdFindSessionObjects_Next
- */
-
-struct nodeStr {
- struct nodeStr *next;
- NSSCKMDObject *mdObject;
-};
-
-struct nssCKMDFindSessionObjectsStr {
- NSSArena *arena;
- CK_RV error;
- CK_ATTRIBUTE_PTR pTemplate;
- CK_ULONG ulCount;
- struct nodeStr *list;
- nssCKFWHash *hash;
-
-};
-typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects;
-
-#ifdef DEBUG
-/*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do this routines as no-ops.
- */
-
-static CK_RV
-nss_ckmdFindSessionObjects_add_pointer
-(
- const NSSCKMDFindObjects *mdFindObjects
-)
-{
- return CKR_OK;
-}
-
-static CK_RV
-nss_ckmdFindSessionObjects_remove_pointer
-(
- const NSSCKMDFindObjects *mdFindObjects
-)
-{
- return CKR_OK;
-}
-
-#ifdef NSS_DEBUG
-static CK_RV
-nss_ckmdFindSessionObjects_verifyPointer
-(
- const NSSCKMDFindObjects *mdFindObjects
-)
-{
- return CKR_OK;
-}
-#endif
-
-#endif /* DEBUG */
-
-/*
- * We must forward-declare these routines.
- */
-static void
-nss_ckmdFindSessionObjects_Final
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-);
-
-static NSSCKMDObject *
-nss_ckmdFindSessionObjects_Next
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-);
-
-static CK_BBOOL
-items_match
-(
- NSSItem *a,
- CK_VOID_PTR pValue,
- CK_ULONG ulValueLen
-)
-{
- if( a->size != ulValueLen ) {
- return CK_FALSE;
- }
-
- if( PR_TRUE == nsslibc_memequal(a->data, pValue, ulValueLen, (PRStatus *)NULL) ) {
- return CK_TRUE;
- } else {
- return CK_FALSE;
- }
-}
-
-/*
- * Our hashtable iterator
- */
-static void
-findfcn
-(
- const void *key,
- void *value,
- void *closure
-)
-{
- NSSCKMDObject *mdObject = (NSSCKMDObject *)value;
- nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)mdObject->etc;
- nssCKMDFindSessionObjects *mdfso = (nssCKMDFindSessionObjects *)closure;
- CK_ULONG i, j;
- struct nodeStr *node;
-
- if( CKR_OK != mdfso->error ) {
- return;
- }
-
- for( i = 0; i < mdfso->ulCount; i++ ) {
- CK_ATTRIBUTE_PTR p = &mdfso->pTemplate[i];
-
- for( j = 0; j < mdso->n; j++ ) {
- if( mdso->types[j] == p->type ) {
- if( !items_match(&mdso->attributes[j], p->pValue, p->ulValueLen) ) {
- return;
- } else {
- break;
- }
- }
- }
-
- if( j == mdso->n ) {
- /* Attribute not found */
- return;
- }
- }
-
- /* Matches */
- node = nss_ZNEW(mdfso->arena, struct nodeStr);
- if( (struct nodeStr *)NULL == node ) {
- mdfso->error = CKR_HOST_MEMORY;
- return;
- }
-
- node->mdObject = mdObject;
- node->next = mdfso->list;
- mdfso->list = node;
-
- return;
-}
-
-/*
- * nssCKMDFindSessionObjects_Create
- *
- */
-NSS_IMPLEMENT NSSCKMDFindObjects *
-nssCKMDFindSessionObjects_Create
-(
- NSSCKFWToken *fwToken,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_RV *pError
-)
-{
- NSSArena *arena;
- nssCKMDFindSessionObjects *mdfso;
- nssCKFWHash *hash;
- NSSCKMDFindObjects *rv;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKMDFindObjects *)NULL;
- }
-
- *pError = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != *pError ) {
- return (NSSCKMDFindObjects *)NULL;
- }
-
- if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKMDFindObjects *)NULL;
- }
-#endif /* NSSDEBUG */
-
- *pError = CKR_OK;
-
- hash = nssCKFWToken_GetSessionObjectHash(fwToken);
- if (!hash) {
- *pError= CKR_GENERAL_ERROR;
- return (NSSCKMDFindObjects *)NULL;
- }
-
- arena = NSSArena_Create();
- if (!arena) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDFindObjects *)NULL;
- }
-
- mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects);
- if (!mdfso) {
- goto loser;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDFindObjects);
- if(rv == NULL) {
- goto loser;
- }
-
- mdfso->error = CKR_OK;
- mdfso->pTemplate = pTemplate;
- mdfso->ulCount = ulCount;
- mdfso->hash = hash;
-
- nssCKFWHash_Iterate(hash, findfcn, mdfso);
-
- if( CKR_OK != mdfso->error ) {
- goto loser;
- }
-
- rv->etc = (void *)mdfso;
- rv->Final = nss_ckmdFindSessionObjects_Final;
- rv->Next = nss_ckmdFindSessionObjects_Next;
-
-#ifdef DEBUG
- if( (*pError = nss_ckmdFindSessionObjects_add_pointer(rv)) != CKR_OK ) {
- goto loser;
- }
-#endif /* DEBUG */
- mdfso->arena = arena;
-
- return rv;
-
-loser:
- if (arena) {
- NSSArena_Destroy(arena);
- }
- if (*pError == CKR_OK) {
- *pError = CKR_HOST_MEMORY;
- }
- return NULL;
-}
-
-static void
-nss_ckmdFindSessionObjects_Final
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance
-)
-{
- nssCKMDFindSessionObjects *mdfso;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
- return;
- }
-#endif /* NSSDEBUG */
-
- mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
- if (mdfso->arena) NSSArena_Destroy(mdfso->arena);
-
-#ifdef DEBUG
- (void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects);
-#endif /* DEBUG */
-
- return;
-}
-
-static NSSCKMDObject *
-nss_ckmdFindSessionObjects_Next
-(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError
-)
-{
- nssCKMDFindSessionObjects *mdfso;
- NSSCKMDObject *rv = (NSSCKMDObject *)NULL;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
- return (NSSCKMDObject *)NULL;
- }
-#endif /* NSSDEBUG */
-
- mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
-
- while (!rv) {
- if( (struct nodeStr *)NULL == mdfso->list ) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
-
- if( nssCKFWHash_Exists(mdfso->hash, mdfso->list->mdObject) ) {
- rv = mdfso->list->mdObject;
- }
-
- mdfso->list = mdfso->list->next;
- }
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/slot.c b/security/nss/lib/ckfw/slot.c
deleted file mode 100644
index fbdefddfd..000000000
--- a/security/nss/lib/ckfw/slot.c
+++ /dev/null
@@ -1,727 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * slot.c
- *
- * This file implements the NSSCKFWSlot type and methods.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * NSSCKFWSlot
- *
- * -- create/destroy --
- * nssCKFWSlot_Create
- * nssCKFWSlot_Destroy
- *
- * -- public accessors --
- * NSSCKFWSlot_GetMDSlot
- * NSSCKFWSlot_GetFWInstance
- * NSSCKFWSlot_GetMDInstance
- *
- * -- implement public accessors --
- * nssCKFWSlot_GetMDSlot
- * nssCKFWSlot_GetFWInstance
- * nssCKFWSlot_GetMDInstance
- *
- * -- private accessors --
- * nssCKFWSlot_GetSlotID
- * nssCKFWSlot_ClearToken
- *
- * -- module fronts --
- * nssCKFWSlot_GetSlotDescription
- * nssCKFWSlot_GetManufacturerID
- * nssCKFWSlot_GetTokenPresent
- * nssCKFWSlot_GetRemovableDevice
- * nssCKFWSlot_GetHardwareSlot
- * nssCKFWSlot_GetHardwareVersion
- * nssCKFWSlot_GetFirmwareVersion
- * nssCKFWSlot_InitToken
- * nssCKFWSlot_GetToken
- */
-
-struct NSSCKFWSlotStr {
- NSSCKFWMutex *mutex;
- NSSCKMDSlot *mdSlot;
- NSSCKFWInstance *fwInstance;
- NSSCKMDInstance *mdInstance;
- CK_SLOT_ID slotID;
-
- /*
- * Everything above is set at creation time, and then not modified.
- * The invariants the mutex protects are:
- *
- * 1) Each of the cached descriptions (versions, etc.) are in an
- * internally consistant state.
- *
- * 2) The fwToken points to the token currently in the slot, and
- * it is in a consistant state.
- *
- * Note that the calls accessing the cached descriptions will
- * call the NSSCKMDSlot methods with the mutex locked. Those
- * methods may then call the public NSSCKFWSlot routines. Those
- * public routines only access the constant data above, so there's
- * no problem. But be careful if you add to this object; mutexes
- * are in general not reentrant, so don't create deadlock situations.
- */
-
- NSSUTF8 *slotDescription;
- NSSUTF8 *manufacturerID;
- CK_VERSION hardwareVersion;
- CK_VERSION firmwareVersion;
- NSSCKFWToken *fwToken;
-};
-
-#ifdef DEBUG
-/*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do this routines as no-ops.
- */
-
-static CK_RV
-slot_add_pointer
-(
- const NSSCKFWSlot *fwSlot
-)
-{
- return CKR_OK;
-}
-
-static CK_RV
-slot_remove_pointer
-(
- const NSSCKFWSlot *fwSlot
-)
-{
- return CKR_OK;
-}
-
-NSS_IMPLEMENT CK_RV
-nssCKFWSlot_verifyPointer
-(
- const NSSCKFWSlot *fwSlot
-)
-{
- return CKR_OK;
-}
-
-#endif /* DEBUG */
-
-/*
- * nssCKFWSlot_Create
- *
- */
-NSS_IMPLEMENT NSSCKFWSlot *
-nssCKFWSlot_Create
-(
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *mdSlot,
- CK_SLOT_ID slotID,
- CK_RV *pError
-)
-{
- NSSCKFWSlot *fwSlot;
- NSSCKMDInstance *mdInstance;
- NSSArena *arena;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWSlot *)NULL;
- }
-
- *pError = nssCKFWInstance_verifyPointer(fwInstance);
- if( CKR_OK != *pError ) {
- return (NSSCKFWSlot *)NULL;
- }
-#endif /* NSSDEBUG */
-
- mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
- if (!mdInstance) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWSlot *)NULL;
- }
-
- arena = nssCKFWInstance_GetArena(fwInstance, pError);
- if (!arena) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- }
-
- fwSlot = nss_ZNEW(arena, NSSCKFWSlot);
- if (!fwSlot) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKFWSlot *)NULL;
- }
-
- fwSlot->mdSlot = mdSlot;
- fwSlot->fwInstance = fwInstance;
- fwSlot->mdInstance = mdInstance;
- fwSlot->slotID = slotID;
-
- fwSlot->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
- if (!fwSlot->mutex) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- (void)nss_ZFreeIf(fwSlot);
- return (NSSCKFWSlot *)NULL;
- }
-
- if (mdSlot->Initialize) {
- *pError = CKR_OK;
- *pError = mdSlot->Initialize(mdSlot, fwSlot, mdInstance, fwInstance);
- if( CKR_OK != *pError ) {
- (void)nssCKFWMutex_Destroy(fwSlot->mutex);
- (void)nss_ZFreeIf(fwSlot);
- return (NSSCKFWSlot *)NULL;
- }
- }
-
-#ifdef DEBUG
- *pError = slot_add_pointer(fwSlot);
- if( CKR_OK != *pError ) {
- if (mdSlot->Destroy) {
- mdSlot->Destroy(mdSlot, fwSlot, mdInstance, fwInstance);
- }
-
- (void)nssCKFWMutex_Destroy(fwSlot->mutex);
- (void)nss_ZFreeIf(fwSlot);
- return (NSSCKFWSlot *)NULL;
- }
-#endif /* DEBUG */
-
- return fwSlot;
-}
-
-/*
- * nssCKFWSlot_Destroy
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSlot_Destroy
-(
- NSSCKFWSlot *fwSlot
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWSlot_verifyPointer(fwSlot);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
- if (fwSlot->fwToken) {
- nssCKFWToken_Destroy(fwSlot->fwToken);
- }
-
- (void)nssCKFWMutex_Destroy(fwSlot->mutex);
-
- if (fwSlot->mdSlot->Destroy) {
- fwSlot->mdSlot->Destroy(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
- }
-
-#ifdef DEBUG
- error = slot_remove_pointer(fwSlot);
-#endif /* DEBUG */
- (void)nss_ZFreeIf(fwSlot);
- return error;
-}
-
-/*
- * nssCKFWSlot_GetMDSlot
- *
- */
-NSS_IMPLEMENT NSSCKMDSlot *
-nssCKFWSlot_GetMDSlot
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKMDSlot *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwSlot->mdSlot;
-}
-
-/*
- * nssCKFWSlot_GetFWInstance
- *
- */
-
-NSS_IMPLEMENT NSSCKFWInstance *
-nssCKFWSlot_GetFWInstance
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKFWInstance *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwSlot->fwInstance;
-}
-
-/*
- * nssCKFWSlot_GetMDInstance
- *
- */
-
-NSS_IMPLEMENT NSSCKMDInstance *
-nssCKFWSlot_GetMDInstance
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKMDInstance *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwSlot->mdInstance;
-}
-
-/*
- * nssCKFWSlot_GetSlotID
- *
- */
-NSS_IMPLEMENT CK_SLOT_ID
-nssCKFWSlot_GetSlotID
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (CK_SLOT_ID)0;
- }
-#endif /* NSSDEBUG */
-
- return fwSlot->slotID;
-}
-
-/*
- * nssCKFWSlot_GetSlotDescription
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSlot_GetSlotDescription
-(
- NSSCKFWSlot *fwSlot,
- CK_CHAR slotDescription[64]
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == slotDescription ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- error = nssCKFWSlot_verifyPointer(fwSlot);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwSlot->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSlot->slotDescription) {
- if (fwSlot->mdSlot->GetSlotDescription) {
- fwSlot->slotDescription = fwSlot->mdSlot->GetSlotDescription(
- fwSlot->mdSlot, fwSlot, fwSlot->mdInstance,
- fwSlot->fwInstance, &error);
- if ((!fwSlot->slotDescription) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwSlot->slotDescription = (NSSUTF8 *) "";
- }
- }
-
- (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->slotDescription, (char *)slotDescription, 64, ' ');
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return error;
-}
-
-/*
- * nssCKFWSlot_GetManufacturerID
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWSlot_GetManufacturerID
-(
- NSSCKFWSlot *fwSlot,
- CK_CHAR manufacturerID[32]
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == manufacturerID ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- error = nssCKFWSlot_verifyPointer(fwSlot);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwSlot->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwSlot->manufacturerID) {
- if (fwSlot->mdSlot->GetManufacturerID) {
- fwSlot->manufacturerID = fwSlot->mdSlot->GetManufacturerID(
- fwSlot->mdSlot, fwSlot, fwSlot->mdInstance,
- fwSlot->fwInstance, &error);
- if ((!fwSlot->manufacturerID) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwSlot->manufacturerID = (NSSUTF8 *) "";
- }
- }
-
- (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->manufacturerID, (char *)manufacturerID, 32, ' ');
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return error;
-}
-
-/*
- * nssCKFWSlot_GetTokenPresent
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWSlot_GetTokenPresent
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwSlot->mdSlot->GetTokenPresent) {
- return CK_TRUE;
- }
-
- return fwSlot->mdSlot->GetTokenPresent(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
-}
-
-/*
- * nssCKFWSlot_GetRemovableDevice
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWSlot_GetRemovableDevice
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwSlot->mdSlot->GetRemovableDevice) {
- return CK_FALSE;
- }
-
- return fwSlot->mdSlot->GetRemovableDevice(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
-}
-
-/*
- * nssCKFWSlot_GetHardwareSlot
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWSlot_GetHardwareSlot
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwSlot->mdSlot->GetHardwareSlot) {
- return CK_FALSE;
- }
-
- return fwSlot->mdSlot->GetHardwareSlot(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance);
-}
-
-/*
- * nssCKFWSlot_GetHardwareVersion
- *
- */
-NSS_IMPLEMENT CK_VERSION
-nssCKFWSlot_GetHardwareVersion
-(
- NSSCKFWSlot *fwSlot
-)
-{
- CK_VERSION rv;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-
- if( (0 != fwSlot->hardwareVersion.major) ||
- (0 != fwSlot->hardwareVersion.minor) ) {
- rv = fwSlot->hardwareVersion;
- goto done;
- }
-
- if (fwSlot->mdSlot->GetHardwareVersion) {
- fwSlot->hardwareVersion = fwSlot->mdSlot->GetHardwareVersion(
- fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
- } else {
- fwSlot->hardwareVersion.major = 0;
- fwSlot->hardwareVersion.minor = 1;
- }
-
- rv = fwSlot->hardwareVersion;
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return rv;
-}
-
-/*
- * nssCKFWSlot_GetFirmwareVersion
- *
- */
-NSS_IMPLEMENT CK_VERSION
-nssCKFWSlot_GetFirmwareVersion
-(
- NSSCKFWSlot *fwSlot
-)
-{
- CK_VERSION rv;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-
- if( (0 != fwSlot->firmwareVersion.major) ||
- (0 != fwSlot->firmwareVersion.minor) ) {
- rv = fwSlot->firmwareVersion;
- goto done;
- }
-
- if (fwSlot->mdSlot->GetFirmwareVersion) {
- fwSlot->firmwareVersion = fwSlot->mdSlot->GetFirmwareVersion(
- fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
- } else {
- fwSlot->firmwareVersion.major = 0;
- fwSlot->firmwareVersion.minor = 1;
- }
-
- rv = fwSlot->firmwareVersion;
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return rv;
-}
-
-/*
- * nssCKFWSlot_GetToken
- *
- */
-NSS_IMPLEMENT NSSCKFWToken *
-nssCKFWSlot_GetToken
-(
- NSSCKFWSlot *fwSlot,
- CK_RV *pError
-)
-{
- NSSCKMDToken *mdToken;
- NSSCKFWToken *fwToken;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWToken *)NULL;
- }
-
- *pError = nssCKFWSlot_verifyPointer(fwSlot);
- if( CKR_OK != *pError ) {
- return (NSSCKFWToken *)NULL;
- }
-#endif /* NSSDEBUG */
-
- *pError = nssCKFWMutex_Lock(fwSlot->mutex);
- if( CKR_OK != *pError ) {
- return (NSSCKFWToken *)NULL;
- }
-
- if (!fwSlot->fwToken) {
- if (!fwSlot->mdSlot->GetToken) {
- *pError = CKR_GENERAL_ERROR;
- fwToken = (NSSCKFWToken *)NULL;
- goto done;
- }
-
- mdToken = fwSlot->mdSlot->GetToken(fwSlot->mdSlot, fwSlot,
- fwSlot->mdInstance, fwSlot->fwInstance, pError);
- if (!mdToken) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- return (NSSCKFWToken *)NULL;
- }
-
- fwToken = nssCKFWToken_Create(fwSlot, mdToken, pError);
- fwSlot->fwToken = fwToken;
- } else {
- fwToken = fwSlot->fwToken;
- }
-
- done:
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return fwToken;
-}
-
-/*
- * nssCKFWSlot_ClearToken
- *
- */
-NSS_IMPLEMENT void
-nssCKFWSlot_ClearToken
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
- /* Now what? */
- return;
- }
-
- fwSlot->fwToken = (NSSCKFWToken *)NULL;
- (void)nssCKFWMutex_Unlock(fwSlot->mutex);
- return;
-}
-
-/*
- * NSSCKFWSlot_GetMDSlot
- *
- */
-
-NSS_IMPLEMENT NSSCKMDSlot *
-NSSCKFWSlot_GetMDSlot
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKMDSlot *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWSlot_GetMDSlot(fwSlot);
-}
-
-/*
- * NSSCKFWSlot_GetFWInstance
- *
- */
-
-NSS_IMPLEMENT NSSCKFWInstance *
-NSSCKFWSlot_GetFWInstance
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKFWInstance *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWSlot_GetFWInstance(fwSlot);
-}
-
-/*
- * NSSCKFWSlot_GetMDInstance
- *
- */
-
-NSS_IMPLEMENT NSSCKMDInstance *
-NSSCKFWSlot_GetMDInstance
-(
- NSSCKFWSlot *fwSlot
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
- return (NSSCKMDInstance *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWSlot_GetMDInstance(fwSlot);
-}
diff --git a/security/nss/lib/ckfw/token.c b/security/nss/lib/ckfw/token.c
deleted file mode 100644
index ab133484b..000000000
--- a/security/nss/lib/ckfw/token.c
+++ /dev/null
@@ -1,1896 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * token.c
- *
- * This file implements the NSSCKFWToken type and methods.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * NSSCKFWToken
- *
- * -- create/destroy --
- * nssCKFWToken_Create
- * nssCKFWToken_Destroy
- *
- * -- public accessors --
- * NSSCKFWToken_GetMDToken
- * NSSCKFWToken_GetFWSlot
- * NSSCKFWToken_GetMDSlot
- * NSSCKFWToken_GetSessionState
- *
- * -- implement public accessors --
- * nssCKFWToken_GetMDToken
- * nssCKFWToken_GetFWSlot
- * nssCKFWToken_GetMDSlot
- * nssCKFWToken_GetSessionState
- * nssCKFWToken_SetSessionState
- *
- * -- private accessors --
- * nssCKFWToken_SetSessionState
- * nssCKFWToken_RemoveSession
- * nssCKFWToken_CloseAllSessions
- * nssCKFWToken_GetSessionCount
- * nssCKFWToken_GetRwSessionCount
- * nssCKFWToken_GetRoSessionCount
- * nssCKFWToken_GetSessionObjectHash
- * nssCKFWToken_GetMDObjectHash
- * nssCKFWToken_GetObjectHandleHash
- *
- * -- module fronts --
- * nssCKFWToken_InitToken
- * nssCKFWToken_GetLabel
- * nssCKFWToken_GetManufacturerID
- * nssCKFWToken_GetModel
- * nssCKFWToken_GetSerialNumber
- * nssCKFWToken_GetHasRNG
- * nssCKFWToken_GetIsWriteProtected
- * nssCKFWToken_GetLoginRequired
- * nssCKFWToken_GetUserPinInitialized
- * nssCKFWToken_GetRestoreKeyNotNeeded
- * nssCKFWToken_GetHasClockOnToken
- * nssCKFWToken_GetHasProtectedAuthenticationPath
- * nssCKFWToken_GetSupportsDualCryptoOperations
- * nssCKFWToken_GetMaxSessionCount
- * nssCKFWToken_GetMaxRwSessionCount
- * nssCKFWToken_GetMaxPinLen
- * nssCKFWToken_GetMinPinLen
- * nssCKFWToken_GetTotalPublicMemory
- * nssCKFWToken_GetFreePublicMemory
- * nssCKFWToken_GetTotalPrivateMemory
- * nssCKFWToken_GetFreePrivateMemory
- * nssCKFWToken_GetHardwareVersion
- * nssCKFWToken_GetFirmwareVersion
- * nssCKFWToken_GetUTCTime
- * nssCKFWToken_OpenSession
- * nssCKFWToken_GetMechanismCount
- * nssCKFWToken_GetMechanismTypes
- * nssCKFWToken_GetMechanism
- */
-
-struct NSSCKFWTokenStr {
- NSSCKFWMutex *mutex;
- NSSArena *arena;
- NSSCKMDToken *mdToken;
- NSSCKFWSlot *fwSlot;
- NSSCKMDSlot *mdSlot;
- NSSCKFWInstance *fwInstance;
- NSSCKMDInstance *mdInstance;
-
- /*
- * Everything above is set at creation time, and then not modified.
- * The invariants the mutex protects are:
- *
- * 1) Each of the cached descriptions (versions, etc.) are in an
- * internally consistant state.
- *
- * 2) The session counts and hashes are consistant.
- *
- * 3) The object hashes are consistant.
- *
- * Note that the calls accessing the cached descriptions will call
- * the NSSCKMDToken methods with the mutex locked. Those methods
- * may then call the public NSSCKFWToken routines. Those public
- * routines only access the constant data above and the atomic
- * CK_STATE session state variable below, so there's no problem.
- * But be careful if you add to this object; mutexes are in
- * general not reentrant, so don't create deadlock situations.
- */
-
- NSSUTF8 *label;
- NSSUTF8 *manufacturerID;
- NSSUTF8 *model;
- NSSUTF8 *serialNumber;
- CK_VERSION hardwareVersion;
- CK_VERSION firmwareVersion;
-
- CK_ULONG sessionCount;
- CK_ULONG rwSessionCount;
- nssCKFWHash *sessions;
- nssCKFWHash *sessionObjectHash;
- nssCKFWHash *mdObjectHash;
- nssCKFWHash *mdMechanismHash;
-
- CK_STATE state;
-};
-
-#ifdef DEBUG
-/*
- * But first, the pointer-tracking stuff.
- *
- * NOTE: the pointer-tracking support in NSS/base currently relies
- * upon NSPR's CallOnce support. That, however, relies upon NSPR's
- * locking, which is tied into the runtime. We need a pointer-tracker
- * implementation that uses the locks supplied through C_Initialize.
- * That support, however, can be filled in later. So for now, I'll
- * just do this routines as no-ops.
- */
-
-static CK_RV
-token_add_pointer
-(
- const NSSCKFWToken *fwToken
-)
-{
- return CKR_OK;
-}
-
-static CK_RV
-token_remove_pointer
-(
- const NSSCKFWToken *fwToken
-)
-{
- return CKR_OK;
-}
-
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_verifyPointer
-(
- const NSSCKFWToken *fwToken
-)
-{
- return CKR_OK;
-}
-
-#endif /* DEBUG */
-
-/*
- * nssCKFWToken_Create
- *
- */
-NSS_IMPLEMENT NSSCKFWToken *
-nssCKFWToken_Create
-(
- NSSCKFWSlot *fwSlot,
- NSSCKMDToken *mdToken,
- CK_RV *pError
-)
-{
- NSSArena *arena = (NSSArena *)NULL;
- NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
- CK_BBOOL called_setup = CK_FALSE;
-
- /*
- * We have already verified the arguments in nssCKFWSlot_GetToken.
- */
-
- arena = NSSArena_Create();
- if (!arena) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fwToken = nss_ZNEW(arena, NSSCKFWToken);
- if (!fwToken) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fwToken->arena = arena;
- fwToken->mdToken = mdToken;
- fwToken->fwSlot = fwSlot;
- fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
- fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
- fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
- fwToken->sessionCount = 0;
- fwToken->rwSessionCount = 0;
-
- fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pError);
- if (!fwToken->mutex) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- goto loser;
- }
-
- fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError);
- if (!fwToken->sessions) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
- fwToken->fwInstance) ) {
- fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
- arena, pError);
- if (!fwToken->sessionObjectHash) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- goto loser;
- }
- }
-
- fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
- arena, pError);
- if (!fwToken->mdObjectHash) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- goto loser;
- }
-
- fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance,
- arena, pError);
- if (!fwToken->mdMechanismHash) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- goto loser;
- }
-
- /* More here */
-
- if (mdToken->Setup) {
- *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
- if( CKR_OK != *pError ) {
- goto loser;
- }
- }
-
- called_setup = CK_TRUE;
-
-#ifdef DEBUG
- *pError = token_add_pointer(fwToken);
- if( CKR_OK != *pError ) {
- goto loser;
- }
-#endif /* DEBUG */
-
- *pError = CKR_OK;
- return fwToken;
-
- loser:
-
- if( CK_TRUE == called_setup ) {
- if (mdToken->Invalidate) {
- mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
- }
- }
-
- if (arena) {
- (void)NSSArena_Destroy(arena);
- }
-
- return (NSSCKFWToken *)NULL;
-}
-
-static void
-nss_ckfwtoken_session_iterator
-(
- const void *key,
- void *value,
- void *closure
-)
-{
- /*
- * Remember that the fwToken->mutex is locked
- */
- NSSCKFWSession *fwSession = (NSSCKFWSession *)value;
- (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
- return;
-}
-
-static void
-nss_ckfwtoken_object_iterator
-(
- const void *key,
- void *value,
- void *closure
-)
-{
- /*
- * Remember that the fwToken->mutex is locked
- */
- NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
- (void)nssCKFWObject_Finalize(fwObject, CK_FALSE);
- return;
-}
-
-/*
- * nssCKFWToken_Destroy
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_Destroy
-(
- NSSCKFWToken *fwToken
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- (void)nssCKFWMutex_Destroy(fwToken->mutex);
-
- if (fwToken->mdToken->Invalidate) {
- fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
- }
- /* we can destroy the list without locking now because no one else is
- * referencing us (or _Destroy was invalidly called!)
- */
- nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator,
- (void *)NULL);
- nssCKFWHash_Destroy(fwToken->sessions);
-
- /* session objects go away when their sessions are removed */
- if (fwToken->sessionObjectHash) {
- nssCKFWHash_Destroy(fwToken->sessionObjectHash);
- }
-
- /* free up the token objects */
- if (fwToken->mdObjectHash) {
- nssCKFWHash_Iterate(fwToken->mdObjectHash, nss_ckfwtoken_object_iterator,
- (void *)NULL);
- nssCKFWHash_Destroy(fwToken->mdObjectHash);
- }
- if (fwToken->mdMechanismHash) {
- nssCKFWHash_Destroy(fwToken->mdMechanismHash);
- }
-
- nssCKFWSlot_ClearToken(fwToken->fwSlot);
-
-#ifdef DEBUG
- error = token_remove_pointer(fwToken);
-#endif /* DEBUG */
-
- (void)NSSArena_Destroy(fwToken->arena);
- return error;
-}
-
-/*
- * nssCKFWToken_GetMDToken
- *
- */
-NSS_IMPLEMENT NSSCKMDToken *
-nssCKFWToken_GetMDToken
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKMDToken *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwToken->mdToken;
-}
-
-/*
- * nssCKFWToken_GetArena
- *
- */
-NSS_IMPLEMENT NSSArena *
-nssCKFWToken_GetArena
-(
- NSSCKFWToken *fwToken,
- CK_RV *pError
-)
-{
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSArena *)NULL;
- }
-
- *pError = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != *pError ) {
- return (NSSArena *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwToken->arena;
-}
-
-/*
- * nssCKFWToken_GetFWSlot
- *
- */
-NSS_IMPLEMENT NSSCKFWSlot *
-nssCKFWToken_GetFWSlot
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKFWSlot *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwToken->fwSlot;
-}
-
-/*
- * nssCKFWToken_GetMDSlot
- *
- */
-NSS_IMPLEMENT NSSCKMDSlot *
-nssCKFWToken_GetMDSlot
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKMDSlot *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwToken->mdSlot;
-}
-
-/*
- * nssCKFWToken_GetSessionState
- *
- */
-NSS_IMPLEMENT CK_STATE
-nssCKFWToken_GetSessionState
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CKS_RO_PUBLIC_SESSION; /* whatever */
- }
-#endif /* NSSDEBUG */
-
- /*
- * BTW, do not lock the token in this method.
- */
-
- /*
- * Theoretically, there is no state if there aren't any
- * sessions open. But then we'd need to worry about
- * reporting an error, etc. What the heck-- let's just
- * revert to CKR_RO_PUBLIC_SESSION as the "default."
- */
-
- return fwToken->state;
-}
-
-/*
- * nssCKFWToken_InitToken
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_InitToken
-(
- NSSCKFWToken *fwToken,
- NSSItem *pin,
- NSSUTF8 *label
-)
-{
- CK_RV error;
-
-#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return CKR_ARGUMENTS_BAD;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if( fwToken->sessionCount > 0 ) {
- error = CKR_SESSION_EXISTS;
- goto done;
- }
-
- if (!fwToken->mdToken->InitToken) {
- error = CKR_DEVICE_ERROR;
- goto done;
- }
-
- if (!pin) {
- if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
- ; /* okay */
- } else {
- error = CKR_PIN_INCORRECT;
- goto done;
- }
- }
-
- if (!label) {
- label = (NSSUTF8 *) "";
- }
-
- error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance, pin, label);
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
-}
-
-/*
- * nssCKFWToken_GetLabel
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetLabel
-(
- NSSCKFWToken *fwToken,
- CK_CHAR label[32]
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == label ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwToken->label) {
- if (fwToken->mdToken->GetLabel) {
- fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance, &error);
- if ((!fwToken->label) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwToken->label = (NSSUTF8 *) "";
- }
- }
-
- (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' ');
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
-}
-
-/*
- * nssCKFWToken_GetManufacturerID
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetManufacturerID
-(
- NSSCKFWToken *fwToken,
- CK_CHAR manufacturerID[32]
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == manufacturerID ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwToken->manufacturerID) {
- if (fwToken->mdToken->GetManufacturerID) {
- fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken,
- fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
- if ((!fwToken->manufacturerID) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwToken->manufacturerID = (NSSUTF8 *)"";
- }
- }
-
- (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacturerID, 32, ' ');
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
-}
-
-/*
- * nssCKFWToken_GetModel
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetModel
-(
- NSSCKFWToken *fwToken,
- CK_CHAR model[16]
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == model ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwToken->model) {
- if (fwToken->mdToken->GetModel) {
- fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance, &error);
- if ((!fwToken->model) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwToken->model = (NSSUTF8 *)"";
- }
- }
-
- (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' ');
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
-}
-
-/*
- * nssCKFWToken_GetSerialNumber
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetSerialNumber
-(
- NSSCKFWToken *fwToken,
- CK_CHAR serialNumber[16]
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- if( (CK_CHAR_PTR)NULL == serialNumber ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if (!fwToken->serialNumber) {
- if (fwToken->mdToken->GetSerialNumber) {
- fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken,
- fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
- if ((!fwToken->serialNumber) && (CKR_OK != error)) {
- goto done;
- }
- } else {
- fwToken->serialNumber = (NSSUTF8 *)"";
- }
- }
-
- (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber, 16, ' ');
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
-}
-
-
-/*
- * nssCKFWToken_GetHasRNG
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetHasRNG
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetHasRNG) {
- return CK_FALSE;
- }
-
- return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetIsWriteProtected
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetIsWriteProtected
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetIsWriteProtected) {
- return CK_FALSE;
- }
-
- return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetLoginRequired
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetLoginRequired
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetLoginRequired) {
- return CK_FALSE;
- }
-
- return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetUserPinInitialized
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetUserPinInitialized
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetUserPinInitialized) {
- return CK_FALSE;
- }
-
- return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetRestoreKeyNotNeeded
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetRestoreKeyNotNeeded
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetRestoreKeyNotNeeded) {
- return CK_FALSE;
- }
-
- return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetHasClockOnToken
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetHasClockOnToken
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetHasClockOnToken) {
- return CK_FALSE;
- }
-
- return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetHasProtectedAuthenticationPath
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetHasProtectedAuthenticationPath
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) {
- return CK_FALSE;
- }
-
- return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken,
- fwToken, fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetSupportsDualCryptoOperations
- *
- */
-NSS_IMPLEMENT CK_BBOOL
-nssCKFWToken_GetSupportsDualCryptoOperations
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_FALSE;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetSupportsDualCryptoOperations) {
- return CK_FALSE;
- }
-
- return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken,
- fwToken, fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetMaxSessionCount
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMaxSessionCount
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetMaxSessionCount) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-
- return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetMaxRwSessionCount
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMaxRwSessionCount
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetMaxRwSessionCount) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-
- return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetMaxPinLen
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMaxPinLen
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetMaxPinLen) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-
- return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetMinPinLen
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMinPinLen
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetMinPinLen) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-
- return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetTotalPublicMemory
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetTotalPublicMemory
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetTotalPublicMemory) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-
- return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetFreePublicMemory
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetFreePublicMemory
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetFreePublicMemory) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-
- return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetTotalPrivateMemory
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetTotalPrivateMemory
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetTotalPrivateMemory) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-
- return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetFreePrivateMemory
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetFreePrivateMemory
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetFreePrivateMemory) {
- return CK_UNAVAILABLE_INFORMATION;
- }
-
- return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetHardwareVersion
- *
- */
-NSS_IMPLEMENT CK_VERSION
-nssCKFWToken_GetHardwareVersion
-(
- NSSCKFWToken *fwToken
-)
-{
- CK_VERSION rv;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-
- if( (0 != fwToken->hardwareVersion.major) ||
- (0 != fwToken->hardwareVersion.minor) ) {
- rv = fwToken->hardwareVersion;
- goto done;
- }
-
- if (fwToken->mdToken->GetHardwareVersion) {
- fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion(
- fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
- } else {
- fwToken->hardwareVersion.major = 0;
- fwToken->hardwareVersion.minor = 1;
- }
-
- rv = fwToken->hardwareVersion;
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return rv;
-}
-
-/*
- * nssCKFWToken_GetFirmwareVersion
- *
- */
-NSS_IMPLEMENT CK_VERSION
-nssCKFWToken_GetFirmwareVersion
-(
- NSSCKFWToken *fwToken
-)
-{
- CK_VERSION rv;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
- rv.major = rv.minor = 0;
- return rv;
- }
-
- if( (0 != fwToken->firmwareVersion.major) ||
- (0 != fwToken->firmwareVersion.minor) ) {
- rv = fwToken->firmwareVersion;
- goto done;
- }
-
- if (fwToken->mdToken->GetFirmwareVersion) {
- fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion(
- fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
- } else {
- fwToken->firmwareVersion.major = 0;
- fwToken->firmwareVersion.minor = 1;
- }
-
- rv = fwToken->firmwareVersion;
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return rv;
-}
-
-/*
- * nssCKFWToken_GetUTCTime
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetUTCTime
-(
- NSSCKFWToken *fwToken,
- CK_CHAR utcTime[16]
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
-
- if( (CK_CHAR_PTR)NULL == utcTime ) {
- return CKR_ARGUMENTS_BAD;
- }
-#endif /* DEBUG */
-
- if( CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken) ) {
- /* return CKR_DEVICE_ERROR; */
- (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' ');
- return CKR_OK;
- }
-
- if (!fwToken->mdToken->GetUTCTime) {
- /* It said it had one! */
- return CKR_GENERAL_ERROR;
- }
-
- error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance, utcTime);
- if( CKR_OK != error ) {
- return error;
- }
-
- /* Sanity-check the data */
- {
- /* Format is YYYYMMDDhhmmss00 */
- int i;
- int Y, M, D, h, m, s, z;
- static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
- for( i = 0; i < 16; i++ ) {
- if( (utcTime[i] < '0') || (utcTime[i] > '9') ) {
- goto badtime;
- }
- }
-
- Y = ((utcTime[ 0] - '0') * 1000) + ((utcTime[1] - '0') * 100) +
- ((utcTime[ 2] - '0') * 10) + (utcTime[ 3] - '0');
- M = ((utcTime[ 4] - '0') * 10) + (utcTime[ 5] - '0');
- D = ((utcTime[ 6] - '0') * 10) + (utcTime[ 7] - '0');
- h = ((utcTime[ 8] - '0') * 10) + (utcTime[ 9] - '0');
- m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0');
- s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0');
- z = ((utcTime[14] - '0') * 10) + (utcTime[15] - '0');
-
- if( (Y < 1990) || (Y > 3000) ) goto badtime; /* Y3K problem. heh heh heh */
- if( (M < 1) || (M > 12) ) goto badtime;
- if( (D < 1) || (D > 31) ) goto badtime;
-
- if( D > dims[M-1] ) goto badtime; /* per-month check */
- if( (2 == M) && (((Y%4)||!(Y%100))&&(Y%400)) && (D > 28) ) goto badtime; /* leap years */
-
- if( (h < 0) || (h > 23) ) goto badtime;
- if( (m < 0) || (m > 60) ) goto badtime;
- if( (s < 0) || (s > 61) ) goto badtime;
-
- /* 60m and 60 or 61s is only allowed for leap seconds. */
- if( (60 == m) || (s >= 60) ) {
- if( (23 != h) || (60 != m) || (s < 60) ) goto badtime;
- /* leap seconds can only happen on June 30 or Dec 31.. I think */
- /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime; */
- }
- }
-
- return CKR_OK;
-
- badtime:
- return CKR_GENERAL_ERROR;
-}
-
-/*
- * nssCKFWToken_OpenSession
- *
- */
-NSS_IMPLEMENT NSSCKFWSession *
-nssCKFWToken_OpenSession
-(
- NSSCKFWToken *fwToken,
- CK_BBOOL rw,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_RV *pError
-)
-{
- NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL;
- NSSCKMDSession *mdSession;
-
-#ifdef NSSDEBUG
- if (!pError) {
- return (NSSCKFWSession *)NULL;
- }
-
- *pError = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != *pError ) {
- return (NSSCKFWSession *)NULL;
- }
-
- switch( rw ) {
- case CK_TRUE:
- case CK_FALSE:
- break;
- default:
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSCKFWSession *)NULL;
- }
-#endif /* NSSDEBUG */
-
- *pError = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != *pError ) {
- return (NSSCKFWSession *)NULL;
- }
-
- if( CK_TRUE == rw ) {
- /* Read-write session desired */
- if( CK_TRUE == nssCKFWToken_GetIsWriteProtected(fwToken) ) {
- *pError = CKR_TOKEN_WRITE_PROTECTED;
- goto done;
- }
- } else {
- /* Read-only session desired */
- if( CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken) ) {
- *pError = CKR_SESSION_READ_WRITE_SO_EXISTS;
- goto done;
- }
- }
-
- /* We could compare sesion counts to any limits we know of, I guess.. */
-
- if (!fwToken->mdToken->OpenSession) {
- /*
- * I'm not sure that the Module actually needs to implement
- * mdSessions -- the Framework can keep track of everything
- * needed, really. But I'll sort out that detail later..
- */
- *pError = CKR_GENERAL_ERROR;
- goto done;
- }
-
- fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError);
- if (!fwSession) {
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- goto done;
- }
-
- mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance, fwSession,
- rw, pError);
- if (!mdSession) {
- (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
- if( CKR_OK == *pError ) {
- *pError = CKR_GENERAL_ERROR;
- }
- goto done;
- }
-
- *pError = nssCKFWSession_SetMDSession(fwSession, mdSession);
- if( CKR_OK != *pError ) {
- if (mdSession->Close) {
- mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
- }
- (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
- goto done;
- }
-
- *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession);
- if( CKR_OK != *pError ) {
- (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
- fwSession = (NSSCKFWSession *)NULL;
- goto done;
- }
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return fwSession;
-}
-
-/*
- * nssCKFWToken_GetMechanismCount
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetMechanismCount
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return 0;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetMechanismCount) {
- return 0;
- }
-
- return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-/*
- * nssCKFWToken_GetMechanismTypes
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_GetMechanismTypes
-(
- NSSCKFWToken *fwToken,
- CK_MECHANISM_TYPE types[]
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CKR_ARGUMENTS_BAD;
- }
-
- if (!types) {
- return CKR_ARGUMENTS_BAD;
- }
-#endif /* NSSDEBUG */
-
- if (!fwToken->mdToken->GetMechanismTypes) {
- /*
- * This should only be called with a sufficiently-large
- * "types" array, which can only be done if GetMechanismCount
- * is implemented. If that's implemented (and returns nonzero),
- * then this should be too. So return an error.
- */
- return CKR_GENERAL_ERROR;
- }
-
- return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance, types);
-}
-
-
-/*
- * nssCKFWToken_GetMechanism
- *
- */
-NSS_IMPLEMENT NSSCKFWMechanism *
-nssCKFWToken_GetMechanism
-(
- NSSCKFWToken *fwToken,
- CK_MECHANISM_TYPE which,
- CK_RV *pError
-)
-{
- NSSCKMDMechanism *mdMechanism;
- if (!fwToken->mdMechanismHash) {
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKFWMechanism *)NULL;
- }
-
- if (!fwToken->mdToken->GetMechanism) {
- /*
- * If we don't implement any GetMechanism function, then we must
- * not support any.
- */
- *pError = CKR_MECHANISM_INVALID;
- return (NSSCKFWMechanism *)NULL;
- }
-
- /* lookup in hash table */
- mdMechanism = fwToken->mdToken->GetMechanism(fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance, which, pError);
- if (!mdMechanism) {
- return (NSSCKFWMechanism *) NULL;
- }
- /* store in hash table */
- return nssCKFWMechanism_Create(mdMechanism, fwToken->mdToken, fwToken,
- fwToken->mdInstance, fwToken->fwInstance);
-}
-
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_SetSessionState
-(
- NSSCKFWToken *fwToken,
- CK_STATE newState
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
-
- switch( newState ) {
- case CKS_RO_PUBLIC_SESSION:
- case CKS_RO_USER_FUNCTIONS:
- case CKS_RW_PUBLIC_SESSION:
- case CKS_RW_USER_FUNCTIONS:
- case CKS_RW_SO_FUNCTIONS:
- break;
- default:
- return CKR_ARGUMENTS_BAD;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- fwToken->state = newState;
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return CKR_OK;
-}
-
-/*
- * nssCKFWToken_RemoveSession
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_RemoveSession
-(
- NSSCKFWToken *fwToken,
- NSSCKFWSession *fwSession
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
-
- error = nssCKFWSession_verifyPointer(fwSession);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- if( CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession) ) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto done;
- }
-
- nssCKFWHash_Remove(fwToken->sessions, fwSession);
- fwToken->sessionCount--;
-
- if( nssCKFWSession_IsRWSession(fwSession) ) {
- fwToken->rwSessionCount--;
- }
-
- if( 0 == fwToken->sessionCount ) {
- fwToken->rwSessionCount = 0; /* sanity */
- fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
- }
-
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
-}
-
-
-/*
- * nssCKFWToken_CloseAllSessions
- *
- */
-NSS_IMPLEMENT CK_RV
-nssCKFWToken_CloseAllSessions
-(
- NSSCKFWToken *fwToken
-)
-{
- CK_RV error = CKR_OK;
-
-#ifdef NSSDEBUG
- error = nssCKFWToken_verifyPointer(fwToken);
- if( CKR_OK != error ) {
- return error;
- }
-#endif /* NSSDEBUG */
-
- error = nssCKFWMutex_Lock(fwToken->mutex);
- if( CKR_OK != error ) {
- return error;
- }
-
- nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL);
-
- nssCKFWHash_Destroy(fwToken->sessions);
-
- fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error);
- if (!fwToken->sessions) {
- if( CKR_OK == error ) {
- error = CKR_GENERAL_ERROR;
- }
- goto done;
- }
-
- fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
- fwToken->sessionCount = 0;
- fwToken->rwSessionCount = 0;
-
- error = CKR_OK;
-
- done:
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return error;
-}
-
-/*
- * nssCKFWToken_GetSessionCount
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetSessionCount
-(
- NSSCKFWToken *fwToken
-)
-{
- CK_ULONG rv;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
- return (CK_ULONG)0;
- }
-
- rv = fwToken->sessionCount;
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return rv;
-}
-
-/*
- * nssCKFWToken_GetRwSessionCount
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetRwSessionCount
-(
- NSSCKFWToken *fwToken
-)
-{
- CK_ULONG rv;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
- return (CK_ULONG)0;
- }
-
- rv = fwToken->rwSessionCount;
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return rv;
-}
-
-/*
- * nssCKFWToken_GetRoSessionCount
- *
- */
-NSS_IMPLEMENT CK_ULONG
-nssCKFWToken_GetRoSessionCount
-(
- NSSCKFWToken *fwToken
-)
-{
- CK_ULONG rv;
-
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (CK_ULONG)0;
- }
-#endif /* NSSDEBUG */
-
- if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
- return (CK_ULONG)0;
- }
-
- rv = fwToken->sessionCount - fwToken->rwSessionCount;
- (void)nssCKFWMutex_Unlock(fwToken->mutex);
- return rv;
-}
-
-/*
- * nssCKFWToken_GetSessionObjectHash
- *
- */
-NSS_IMPLEMENT nssCKFWHash *
-nssCKFWToken_GetSessionObjectHash
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (nssCKFWHash *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwToken->sessionObjectHash;
-}
-
-/*
- * nssCKFWToken_GetMDObjectHash
- *
- */
-NSS_IMPLEMENT nssCKFWHash *
-nssCKFWToken_GetMDObjectHash
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (nssCKFWHash *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwToken->mdObjectHash;
-}
-
-/*
- * nssCKFWToken_GetObjectHandleHash
- *
- */
-NSS_IMPLEMENT nssCKFWHash *
-nssCKFWToken_GetObjectHandleHash
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef NSSDEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (nssCKFWHash *)NULL;
- }
-#endif /* NSSDEBUG */
-
- return fwToken->mdObjectHash;
-}
-
-/*
- * NSSCKFWToken_GetMDToken
- *
- */
-
-NSS_IMPLEMENT NSSCKMDToken *
-NSSCKFWToken_GetMDToken
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKMDToken *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWToken_GetMDToken(fwToken);
-}
-
-/*
- * NSSCKFWToken_GetArena
- *
- */
-
-NSS_IMPLEMENT NSSArena *
-NSSCKFWToken_GetArena
-(
- NSSCKFWToken *fwToken,
- CK_RV *pError
-)
-{
-#ifdef DEBUG
- if (!pError) {
- return (NSSArena *)NULL;
- }
-
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- *pError = CKR_ARGUMENTS_BAD;
- return (NSSArena *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWToken_GetArena(fwToken, pError);
-}
-
-/*
- * NSSCKFWToken_GetFWSlot
- *
- */
-
-NSS_IMPLEMENT NSSCKFWSlot *
-NSSCKFWToken_GetFWSlot
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKFWSlot *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWToken_GetFWSlot(fwToken);
-}
-
-/*
- * NSSCKFWToken_GetMDSlot
- *
- */
-
-NSS_IMPLEMENT NSSCKMDSlot *
-NSSCKFWToken_GetMDSlot
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return (NSSCKMDSlot *)NULL;
- }
-#endif /* DEBUG */
-
- return nssCKFWToken_GetMDSlot(fwToken);
-}
-
-/*
- * NSSCKFWToken_GetSessionState
- *
- */
-
-NSS_IMPLEMENT CK_STATE
-NSSCKFWSession_GetSessionState
-(
- NSSCKFWToken *fwToken
-)
-{
-#ifdef DEBUG
- if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
- return CKS_RO_PUBLIC_SESSION;
- }
-#endif /* DEBUG */
-
- return nssCKFWToken_GetSessionState(fwToken);
-}
diff --git a/security/nss/lib/ckfw/wrap.c b/security/nss/lib/ckfw/wrap.c
deleted file mode 100644
index b55b5feb0..000000000
--- a/security/nss/lib/ckfw/wrap.c
+++ /dev/null
@@ -1,5676 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * wrap.c
- *
- * This file contains the routines that actually implement the cryptoki
- * API, using the internal APIs of the NSS Cryptoki Framework. There is
- * one routine here for every cryptoki routine. For linking reasons
- * the actual entry points passed back with C_GetFunctionList have to
- * exist in one of the Module's source files; however, those are merely
- * simple wrappers that call these routines. The intelligence of the
- * implementations is here.
- */
-
-#ifndef CK_T
-#include "ck.h"
-#endif /* CK_T */
-
-/*
- * NSSCKFWC_Initialize
- * NSSCKFWC_Finalize
- * NSSCKFWC_GetInfo
- * -- NSSCKFWC_GetFunctionList -- see the API insert file
- * NSSCKFWC_GetSlotList
- * NSSCKFWC_GetSlotInfo
- * NSSCKFWC_GetTokenInfo
- * NSSCKFWC_WaitForSlotEvent
- * NSSCKFWC_GetMechanismList
- * NSSCKFWC_GetMechanismInfo
- * NSSCKFWC_InitToken
- * NSSCKFWC_InitPIN
- * NSSCKFWC_SetPIN
- * NSSCKFWC_OpenSession
- * NSSCKFWC_CloseSession
- * NSSCKFWC_CloseAllSessions
- * NSSCKFWC_GetSessionInfo
- * NSSCKFWC_GetOperationState
- * NSSCKFWC_SetOperationState
- * NSSCKFWC_Login
- * NSSCKFWC_Logout
- * NSSCKFWC_CreateObject
- * NSSCKFWC_CopyObject
- * NSSCKFWC_DestroyObject
- * NSSCKFWC_GetObjectSize
- * NSSCKFWC_GetAttributeValue
- * NSSCKFWC_SetAttributeValue
- * NSSCKFWC_FindObjectsInit
- * NSSCKFWC_FindObjects
- * NSSCKFWC_FindObjectsFinal
- * NSSCKFWC_EncryptInit
- * NSSCKFWC_Encrypt
- * NSSCKFWC_EncryptUpdate
- * NSSCKFWC_EncryptFinal
- * NSSCKFWC_DecryptInit
- * NSSCKFWC_Decrypt
- * NSSCKFWC_DecryptUpdate
- * NSSCKFWC_DecryptFinal
- * NSSCKFWC_DigestInit
- * NSSCKFWC_Digest
- * NSSCKFWC_DigestUpdate
- * NSSCKFWC_DigestKey
- * NSSCKFWC_DigestFinal
- * NSSCKFWC_SignInit
- * NSSCKFWC_Sign
- * NSSCKFWC_SignUpdate
- * NSSCKFWC_SignFinal
- * NSSCKFWC_SignRecoverInit
- * NSSCKFWC_SignRecover
- * NSSCKFWC_VerifyInit
- * NSSCKFWC_Verify
- * NSSCKFWC_VerifyUpdate
- * NSSCKFWC_VerifyFinal
- * NSSCKFWC_VerifyRecoverInit
- * NSSCKFWC_VerifyRecover
- * NSSCKFWC_DigestEncryptUpdate
- * NSSCKFWC_DecryptDigestUpdate
- * NSSCKFWC_SignEncryptUpdate
- * NSSCKFWC_DecryptVerifyUpdate
- * NSSCKFWC_GenerateKey
- * NSSCKFWC_GenerateKeyPair
- * NSSCKFWC_WrapKey
- * NSSCKFWC_UnwrapKey
- * NSSCKFWC_DeriveKey
- * NSSCKFWC_SeedRandom
- * NSSCKFWC_GenerateRandom
- * NSSCKFWC_GetFunctionStatus
- * NSSCKFWC_CancelFunction
- */
-
-/* figure out out locking semantics */
-static CK_RV
-nssCKFW_GetThreadSafeState(CK_C_INITIALIZE_ARGS_PTR pInitArgs,
- CryptokiLockingState *pLocking_state) {
- int functionCount = 0;
-
- /* parsed according to (PKCS #11 Section 11.4) */
- /* no args, the degenerate version of case 1 */
- if (!pInitArgs) {
- *pLocking_state = SingleThreaded;
- return CKR_OK;
- }
-
- /* CKF_OS_LOCKING_OK set, Cases 2 and 4 */
- if (pInitArgs->flags & CKF_OS_LOCKING_OK) {
- *pLocking_state = MultiThreaded;
- return CKR_OK;
- }
- if ((CK_CREATEMUTEX) NULL != pInitArgs->CreateMutex) functionCount++;
- if ((CK_DESTROYMUTEX) NULL != pInitArgs->DestroyMutex) functionCount++;
- if ((CK_LOCKMUTEX) NULL != pInitArgs->LockMutex) functionCount++;
- if ((CK_UNLOCKMUTEX) NULL != pInitArgs->UnlockMutex) functionCount++;
-
- /* CKF_OS_LOCKING_OK is not set, and not functions supplied,
- * explicit case 1 */
- if (0 == functionCount) {
- *pLocking_state = SingleThreaded;
- return CKR_OK;
- }
-
- /* OS_LOCKING_OK is not set and functions have been supplied. Since
- * ckfw uses nssbase library which explicitly calls NSPR, and since
- * there is no way to reliably override these explicit calls to NSPR,
- * therefore we can't support applications which have their own threading
- * module. Return CKR_CANT_LOCK if they supplied the correct number of
- * arguments, or CKR_ARGUMENTS_BAD if they did not in either case we will
- * fail the initialize */
- return (4 == functionCount) ? CKR_CANT_LOCK : CKR_ARGUMENTS_BAD;
-}
-
-static PRInt32 liveInstances;
-
-/*
- * NSSCKFWC_Initialize
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_Initialize
-(
- NSSCKFWInstance **pFwInstance,
- NSSCKMDInstance *mdInstance,
- CK_VOID_PTR pInitArgs
-)
-{
- CK_RV error = CKR_OK;
- CryptokiLockingState locking_state;
-
- if( (NSSCKFWInstance **)NULL == pFwInstance ) {
- error = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- if (*pFwInstance) {
- error = CKR_CRYPTOKI_ALREADY_INITIALIZED;
- goto loser;
- }
-
- if (!mdInstance) {
- error = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- error = nssCKFW_GetThreadSafeState(pInitArgs,&locking_state);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- *pFwInstance = nssCKFWInstance_Create(pInitArgs, locking_state, mdInstance, &error);
- if (!*pFwInstance) {
- goto loser;
- }
- PR_ATOMIC_INCREMENT(&liveInstances);
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CANT_LOCK:
- case CKR_CRYPTOKI_ALREADY_INITIALIZED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_NEED_TO_CREATE_THREADS:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_Finalize
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_Finalize
-(
- NSSCKFWInstance **pFwInstance
-)
-{
- CK_RV error = CKR_OK;
-
- if( (NSSCKFWInstance **)NULL == pFwInstance ) {
- error = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- if (!*pFwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- error = nssCKFWInstance_Destroy(*pFwInstance);
-
- /* In any case */
- *pFwInstance = (NSSCKFWInstance *)NULL;
-
- loser:
- switch( error ) {
- PRInt32 remainingInstances;
- case CKR_OK:
- remainingInstances = PR_ATOMIC_DECREMENT(&liveInstances);
- if (!remainingInstances) {
- nssArena_Shutdown();
- }
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- break;
- default:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- /*
- * A thread's error stack is automatically destroyed when the thread
- * terminates or, for the primordial thread, by PR_Cleanup. On
- * Windows with MinGW, the thread private data destructor PR_Free
- * registered by this module is actually a thunk for PR_Free defined
- * in this module. When the thread that unloads this module terminates
- * or calls PR_Cleanup, the thunk for PR_Free is already gone with the
- * module. Therefore we need to destroy the error stack before the
- * module is unloaded.
- */
- nss_DestroyErrorStack();
- return error;
-}
-
-/*
- * NSSCKFWC_GetInfo
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_INFO_PTR pInfo
-)
-{
- CK_RV error = CKR_OK;
-
- if( (CK_INFO_PTR)CK_NULL_PTR == pInfo ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here means a caller error
- */
- (void)nsslibc_memset(pInfo, 0, sizeof(CK_INFO));
-
- pInfo->cryptokiVersion = nssCKFWInstance_GetCryptokiVersion(fwInstance);
-
- error = nssCKFWInstance_GetManufacturerID(fwInstance, pInfo->manufacturerID);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- pInfo->flags = nssCKFWInstance_GetFlags(fwInstance);
-
- error = nssCKFWInstance_GetLibraryDescription(fwInstance, pInfo->libraryDescription);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- pInfo->libraryVersion = nssCKFWInstance_GetLibraryVersion(fwInstance);
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- break;
- default:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * C_GetFunctionList is implemented entirely in the Module's file which
- * includes the Framework API insert file. It requires no "actual"
- * NSSCKFW routine.
- */
-
-/*
- * NSSCKFWC_GetSlotList
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetSlotList
-(
- NSSCKFWInstance *fwInstance,
- CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG nSlots;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- switch( tokenPresent ) {
- case CK_TRUE:
- case CK_FALSE:
- break;
- default:
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
- if( (CK_ULONG)0 == nSlots ) {
- goto loser;
- }
-
- if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlotList ) {
- *pulCount = nSlots;
- return CKR_OK;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- (void)nsslibc_memset(pSlotList, 0, *pulCount * sizeof(CK_SLOT_ID));
-
- if( *pulCount < nSlots ) {
- *pulCount = nSlots;
- error = CKR_BUFFER_TOO_SMALL;
- goto loser;
- } else {
- CK_ULONG i;
- *pulCount = nSlots;
-
- /*
- * Our secret "mapping": CK_SLOT_IDs are integers [1,N], and we
- * just index one when we need it.
- */
-
- for( i = 0; i < nSlots; i++ ) {
- pSlotList[i] = i+1;
- }
-
- return CKR_OK;
- }
-
- loser:
- switch( error ) {
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GetSlotInfo
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetSlotInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_SLOT_INFO_PTR pInfo
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG nSlots;
- NSSCKFWSlot **slots;
- NSSCKFWSlot *fwSlot;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
- if( (CK_ULONG)0 == nSlots ) {
- goto loser;
- }
-
- if( (slotID < 1) || (slotID > nSlots) ) {
- error = CKR_SLOT_ID_INVALID;
- goto loser;
- }
-
- if( (CK_SLOT_INFO_PTR)CK_NULL_PTR == pInfo ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- (void)nsslibc_memset(pInfo, 0, sizeof(CK_SLOT_INFO));
-
- slots = nssCKFWInstance_GetSlots(fwInstance, &error);
- if( (NSSCKFWSlot **)NULL == slots ) {
- goto loser;
- }
-
- fwSlot = slots[ slotID-1 ];
-
- error = nssCKFWSlot_GetSlotDescription(fwSlot, pInfo->slotDescription);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- error = nssCKFWSlot_GetManufacturerID(fwSlot, pInfo->manufacturerID);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- if( nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- pInfo->flags |= CKF_TOKEN_PRESENT;
- }
-
- if( nssCKFWSlot_GetRemovableDevice(fwSlot) ) {
- pInfo->flags |= CKF_REMOVABLE_DEVICE;
- }
-
- if( nssCKFWSlot_GetHardwareSlot(fwSlot) ) {
- pInfo->flags |= CKF_HW_SLOT;
- }
-
- pInfo->hardwareVersion = nssCKFWSlot_GetHardwareVersion(fwSlot);
- pInfo->firmwareVersion = nssCKFWSlot_GetFirmwareVersion(fwSlot);
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_SLOT_ID_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GetTokenInfo
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetTokenInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_TOKEN_INFO_PTR pInfo
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG nSlots;
- NSSCKFWSlot **slots;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
- if( (CK_ULONG)0 == nSlots ) {
- goto loser;
- }
-
- if( (slotID < 1) || (slotID > nSlots) ) {
- error = CKR_SLOT_ID_INVALID;
- goto loser;
- }
-
- if( (CK_TOKEN_INFO_PTR)CK_NULL_PTR == pInfo ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- (void)nsslibc_memset(pInfo, 0, sizeof(CK_TOKEN_INFO));
-
- slots = nssCKFWInstance_GetSlots(fwInstance, &error);
- if( (NSSCKFWSlot **)NULL == slots ) {
- goto loser;
- }
-
- fwSlot = slots[ slotID-1 ];
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- error = nssCKFWToken_GetLabel(fwToken, pInfo->label);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- error = nssCKFWToken_GetManufacturerID(fwToken, pInfo->manufacturerID);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- error = nssCKFWToken_GetModel(fwToken, pInfo->model);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- error = nssCKFWToken_GetSerialNumber(fwToken, pInfo->serialNumber);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- if( nssCKFWToken_GetHasRNG(fwToken) ) {
- pInfo->flags |= CKF_RNG;
- }
-
- if( nssCKFWToken_GetIsWriteProtected(fwToken) ) {
- pInfo->flags |= CKF_WRITE_PROTECTED;
- }
-
- if( nssCKFWToken_GetLoginRequired(fwToken) ) {
- pInfo->flags |= CKF_LOGIN_REQUIRED;
- }
-
- if( nssCKFWToken_GetUserPinInitialized(fwToken) ) {
- pInfo->flags |= CKF_USER_PIN_INITIALIZED;
- }
-
- if( nssCKFWToken_GetRestoreKeyNotNeeded(fwToken) ) {
- pInfo->flags |= CKF_RESTORE_KEY_NOT_NEEDED;
- }
-
- if( nssCKFWToken_GetHasClockOnToken(fwToken) ) {
- pInfo->flags |= CKF_CLOCK_ON_TOKEN;
- }
-
- if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
- pInfo->flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
- }
-
- if( nssCKFWToken_GetSupportsDualCryptoOperations(fwToken) ) {
- pInfo->flags |= CKF_DUAL_CRYPTO_OPERATIONS;
- }
-
- pInfo->ulMaxSessionCount = nssCKFWToken_GetMaxSessionCount(fwToken);
- pInfo->ulSessionCount = nssCKFWToken_GetSessionCount(fwToken);
- pInfo->ulMaxRwSessionCount = nssCKFWToken_GetMaxRwSessionCount(fwToken);
- pInfo->ulRwSessionCount= nssCKFWToken_GetRwSessionCount(fwToken);
- pInfo->ulMaxPinLen = nssCKFWToken_GetMaxPinLen(fwToken);
- pInfo->ulMinPinLen = nssCKFWToken_GetMinPinLen(fwToken);
- pInfo->ulTotalPublicMemory = nssCKFWToken_GetTotalPublicMemory(fwToken);
- pInfo->ulFreePublicMemory = nssCKFWToken_GetFreePublicMemory(fwToken);
- pInfo->ulTotalPrivateMemory = nssCKFWToken_GetTotalPrivateMemory(fwToken);
- pInfo->ulFreePrivateMemory = nssCKFWToken_GetFreePrivateMemory(fwToken);
- pInfo->hardwareVersion = nssCKFWToken_GetHardwareVersion(fwToken);
- pInfo->firmwareVersion = nssCKFWToken_GetFirmwareVersion(fwToken);
-
- error = nssCKFWToken_GetUTCTime(fwToken, pInfo->utcTime);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_DEVICE_REMOVED:
- case CKR_TOKEN_NOT_PRESENT:
- if (fwToken)
- nssCKFWToken_Destroy(fwToken);
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_SLOT_ID_INVALID:
- case CKR_TOKEN_NOT_RECOGNIZED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_WaitForSlotEvent
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_WaitForSlotEvent
-(
- NSSCKFWInstance *fwInstance,
- CK_FLAGS flags,
- CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pReserved
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG nSlots;
- CK_BBOOL block;
- NSSCKFWSlot **slots;
- NSSCKFWSlot *fwSlot;
- CK_ULONG i;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- if( flags & ~CKF_DONT_BLOCK ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- block = (flags & CKF_DONT_BLOCK) ? CK_TRUE : CK_FALSE;
-
- nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
- if( (CK_ULONG)0 == nSlots ) {
- goto loser;
- }
-
- if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlot ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- if( (CK_VOID_PTR)CK_NULL_PTR != pReserved ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- slots = nssCKFWInstance_GetSlots(fwInstance, &error);
- if( (NSSCKFWSlot **)NULL == slots ) {
- goto loser;
- }
-
- fwSlot = nssCKFWInstance_WaitForSlotEvent(fwInstance, block, &error);
- if (!fwSlot) {
- goto loser;
- }
-
- for( i = 0; i < nSlots; i++ ) {
- if( fwSlot == slots[i] ) {
- *pSlot = (CK_SLOT_ID)(CK_ULONG)(i+1);
- return CKR_OK;
- }
- }
-
- error = CKR_GENERAL_ERROR; /* returned something not in the slot list */
-
- loser:
- switch( error ) {
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_NO_EVENT:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GetMechanismList
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetMechanismList
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG nSlots;
- NSSCKFWSlot **slots;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
- CK_ULONG count;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
- if( (CK_ULONG)0 == nSlots ) {
- goto loser;
- }
-
- if( (slotID < 1) || (slotID > nSlots) ) {
- error = CKR_SLOT_ID_INVALID;
- goto loser;
- }
-
- if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- slots = nssCKFWInstance_GetSlots(fwInstance, &error);
- if( (NSSCKFWSlot **)NULL == slots ) {
- goto loser;
- }
-
- fwSlot = slots[ slotID-1 ];
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- count = nssCKFWToken_GetMechanismCount(fwToken);
-
- if( (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR == pMechanismList ) {
- *pulCount = count;
- return CKR_OK;
- }
-
- if( *pulCount < count ) {
- *pulCount = count;
- error = CKR_BUFFER_TOO_SMALL;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- (void)nsslibc_memset(pMechanismList, 0, *pulCount * sizeof(CK_MECHANISM_TYPE));
-
- *pulCount = count;
-
- if( 0 != count ) {
- error = nssCKFWToken_GetMechanismTypes(fwToken, pMechanismList);
- } else {
- error = CKR_OK;
- }
-
- if( CKR_OK == error ) {
- return CKR_OK;
- }
-
- loser:
- switch( error ) {
- case CKR_DEVICE_REMOVED:
- case CKR_TOKEN_NOT_PRESENT:
- if (fwToken)
- nssCKFWToken_Destroy(fwToken);
- break;
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_SLOT_ID_INVALID:
- case CKR_TOKEN_NOT_RECOGNIZED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GetMechanismInfo
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetMechanismInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG nSlots;
- NSSCKFWSlot **slots;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
- if( (CK_ULONG)0 == nSlots ) {
- goto loser;
- }
-
- if( (slotID < 1) || (slotID > nSlots) ) {
- error = CKR_SLOT_ID_INVALID;
- goto loser;
- }
-
- slots = nssCKFWInstance_GetSlots(fwInstance, &error);
- if( (NSSCKFWSlot **)NULL == slots ) {
- goto loser;
- }
-
- fwSlot = slots[ slotID-1 ];
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- if( (CK_MECHANISM_INFO_PTR)CK_NULL_PTR == pInfo ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- (void)nsslibc_memset(pInfo, 0, sizeof(CK_MECHANISM_INFO));
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, type, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- pInfo->ulMinKeySize = nssCKFWMechanism_GetMinKeySize(fwMechanism, &error);
- pInfo->ulMaxKeySize = nssCKFWMechanism_GetMaxKeySize(fwMechanism, &error);
-
- if( nssCKFWMechanism_GetInHardware(fwMechanism, &error) ) {
- pInfo->flags |= CKF_HW;
- }
- if( nssCKFWMechanism_GetCanEncrypt(fwMechanism, &error) ) {
- pInfo->flags |= CKF_ENCRYPT;
- }
- if( nssCKFWMechanism_GetCanDecrypt(fwMechanism, &error) ) {
- pInfo->flags |= CKF_DECRYPT;
- }
- if( nssCKFWMechanism_GetCanDigest(fwMechanism, &error) ) {
- pInfo->flags |= CKF_DIGEST;
- }
- if( nssCKFWMechanism_GetCanSign(fwMechanism, &error) ) {
- pInfo->flags |= CKF_SIGN;
- }
- if( nssCKFWMechanism_GetCanSignRecover(fwMechanism, &error) ) {
- pInfo->flags |= CKF_SIGN_RECOVER;
- }
- if( nssCKFWMechanism_GetCanVerify(fwMechanism, &error) ) {
- pInfo->flags |= CKF_VERIFY;
- }
- if( nssCKFWMechanism_GetCanVerifyRecover(fwMechanism, &error) ) {
- pInfo->flags |= CKF_VERIFY_RECOVER;
- }
- if( nssCKFWMechanism_GetCanGenerate(fwMechanism, &error) ) {
- pInfo->flags |= CKF_GENERATE;
- }
- if( nssCKFWMechanism_GetCanGenerateKeyPair(fwMechanism, &error) ) {
- pInfo->flags |= CKF_GENERATE_KEY_PAIR;
- }
- if( nssCKFWMechanism_GetCanWrap(fwMechanism, &error) ) {
- pInfo->flags |= CKF_WRAP;
- }
- if( nssCKFWMechanism_GetCanUnwrap(fwMechanism, &error) ) {
- pInfo->flags |= CKF_UNWRAP;
- }
- if( nssCKFWMechanism_GetCanDerive(fwMechanism, &error) ) {
- pInfo->flags |= CKF_DERIVE;
- }
- nssCKFWMechanism_Destroy(fwMechanism);
-
- return error;
-
- loser:
- switch( error ) {
- case CKR_DEVICE_REMOVED:
- case CKR_TOKEN_NOT_PRESENT:
- if (fwToken)
- nssCKFWToken_Destroy(fwToken);
- break;
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_MECHANISM_INVALID:
- case CKR_SLOT_ID_INVALID:
- case CKR_TOKEN_NOT_RECOGNIZED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_InitToken
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_InitToken
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,
- CK_CHAR_PTR pLabel
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG nSlots;
- NSSCKFWSlot **slots;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
- NSSItem pin;
- NSSUTF8 *label;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
- if( (CK_ULONG)0 == nSlots ) {
- goto loser;
- }
-
- if( (slotID < 1) || (slotID > nSlots) ) {
- error = CKR_SLOT_ID_INVALID;
- goto loser;
- }
-
- slots = nssCKFWInstance_GetSlots(fwInstance, &error);
- if( (NSSCKFWSlot **)NULL == slots ) {
- goto loser;
- }
-
- fwSlot = slots[ slotID-1 ];
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- pin.size = (PRUint32)ulPinLen;
- pin.data = (void *)pPin;
- label = (NSSUTF8 *)pLabel; /* identity conversion */
-
- error = nssCKFWToken_InitToken(fwToken, &pin, label);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_DEVICE_REMOVED:
- case CKR_TOKEN_NOT_PRESENT:
- if (fwToken)
- nssCKFWToken_Destroy(fwToken);
- break;
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_PIN_INCORRECT:
- case CKR_PIN_LOCKED:
- case CKR_SESSION_EXISTS:
- case CKR_SLOT_ID_INVALID:
- case CKR_TOKEN_NOT_RECOGNIZED:
- case CKR_TOKEN_WRITE_PROTECTED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_InitPIN
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_InitPIN
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSItem pin, *arg;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) {
- arg = (NSSItem *)NULL;
- } else {
- arg = &pin;
- pin.size = (PRUint32)ulPinLen;
- pin.data = (void *)pPin;
- }
-
- error = nssCKFWSession_InitPIN(fwSession, arg);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_PIN_INVALID:
- case CKR_PIN_LEN_RANGE:
- case CKR_SESSION_READ_ONLY:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_TOKEN_WRITE_PROTECTED:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_SetPIN
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SetPIN
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen,
- CK_CHAR_PTR pNewPin,
- CK_ULONG ulNewLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSItem oldPin, newPin, *oldArg, *newArg;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_CHAR_PTR)CK_NULL_PTR == pOldPin ) {
- oldArg = (NSSItem *)NULL;
- } else {
- oldArg = &oldPin;
- oldPin.size = (PRUint32)ulOldLen;
- oldPin.data = (void *)pOldPin;
- }
-
- if( (CK_CHAR_PTR)CK_NULL_PTR == pNewPin ) {
- newArg = (NSSItem *)NULL;
- } else {
- newArg = &newPin;
- newPin.size = (PRUint32)ulNewLen;
- newPin.data = (void *)pNewPin;
- }
-
- error = nssCKFWSession_SetPIN(fwSession, oldArg, newArg);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_PIN_INCORRECT:
- case CKR_PIN_INVALID:
- case CKR_PIN_LEN_RANGE:
- case CKR_PIN_LOCKED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY:
- case CKR_TOKEN_WRITE_PROTECTED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_OpenSession
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_OpenSession
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID,
- CK_FLAGS flags,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_SESSION_HANDLE_PTR phSession
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG nSlots;
- NSSCKFWSlot **slots;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
- NSSCKFWSession *fwSession;
- CK_BBOOL rw;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
- if( (CK_ULONG)0 == nSlots ) {
- goto loser;
- }
-
- if( (slotID < 1) || (slotID > nSlots) ) {
- error = CKR_SLOT_ID_INVALID;
- goto loser;
- }
-
- if( flags & CKF_RW_SESSION ) {
- rw = CK_TRUE;
- } else {
- rw = CK_FALSE;
- }
-
- if( flags & CKF_SERIAL_SESSION ) {
- ;
- } else {
- error = CKR_SESSION_PARALLEL_NOT_SUPPORTED;
- goto loser;
- }
-
- if( flags & ~(CKF_RW_SESSION|CKF_SERIAL_SESSION) ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- if( (CK_SESSION_HANDLE_PTR)CK_NULL_PTR == phSession ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- *phSession = (CK_SESSION_HANDLE)0;
-
- slots = nssCKFWInstance_GetSlots(fwInstance, &error);
- if( (NSSCKFWSlot **)NULL == slots ) {
- goto loser;
- }
-
- fwSlot = slots[ slotID-1 ];
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwSession = nssCKFWToken_OpenSession(fwToken, rw, pApplication,
- Notify, &error);
- if (!fwSession) {
- goto loser;
- }
-
- *phSession = nssCKFWInstance_CreateSessionHandle(fwInstance,
- fwSession, &error);
- if( (CK_SESSION_HANDLE)0 == *phSession ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_SESSION_COUNT:
- case CKR_SESSION_EXISTS:
- case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
- case CKR_SESSION_READ_WRITE_SO_EXISTS:
- case CKR_SLOT_ID_INVALID:
- case CKR_TOKEN_NOT_PRESENT:
- case CKR_TOKEN_NOT_RECOGNIZED:
- case CKR_TOKEN_WRITE_PROTECTED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_CloseSession
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_CloseSession
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- nssCKFWInstance_DestroySessionHandle(fwInstance, hSession);
- error = nssCKFWSession_Destroy(fwSession, CK_TRUE);
-
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_CloseAllSessions
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_CloseAllSessions
-(
- NSSCKFWInstance *fwInstance,
- CK_SLOT_ID slotID
-)
-{
- CK_RV error = CKR_OK;
- CK_ULONG nSlots;
- NSSCKFWSlot **slots;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
- if( (CK_ULONG)0 == nSlots ) {
- goto loser;
- }
-
- if( (slotID < 1) || (slotID > nSlots) ) {
- error = CKR_SLOT_ID_INVALID;
- goto loser;
- }
-
- slots = nssCKFWInstance_GetSlots(fwInstance, &error);
- if( (NSSCKFWSlot **)NULL == slots ) {
- goto loser;
- }
-
- fwSlot = slots[ slotID-1 ];
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- error = nssCKFWToken_CloseAllSessions(fwToken);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_SLOT_ID_INVALID:
- case CKR_TOKEN_NOT_PRESENT:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GetSessionInfo
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetSessionInfo
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWSlot *fwSlot;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_SESSION_INFO_PTR)CK_NULL_PTR == pInfo ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- (void)nsslibc_memset(pInfo, 0, sizeof(CK_SESSION_INFO));
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- pInfo->slotID = nssCKFWSlot_GetSlotID(fwSlot);
- pInfo->state = nssCKFWSession_GetSessionState(fwSession);
-
- if( CK_TRUE == nssCKFWSession_IsRWSession(fwSession) ) {
- pInfo->flags |= CKF_RW_SESSION;
- }
-
- pInfo->flags |= CKF_SERIAL_SESSION; /* Always true */
-
- pInfo->ulDeviceError = nssCKFWSession_GetDeviceError(fwSession);
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GetOperationState
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetOperationState
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG_PTR pulOperationStateLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- CK_ULONG len;
- NSSItem buf;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_ULONG_PTR)CK_NULL_PTR == pulOperationStateLen ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- len = nssCKFWSession_GetOperationStateLen(fwSession, &error);
- if( ((CK_ULONG)0 == len) && (CKR_OK != error) ) {
- goto loser;
- }
-
- if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) {
- *pulOperationStateLen = len;
- return CKR_OK;
- }
-
- if( *pulOperationStateLen < len ) {
- *pulOperationStateLen = len;
- error = CKR_BUFFER_TOO_SMALL;
- goto loser;
- }
-
- buf.size = (PRUint32)*pulOperationStateLen;
- buf.data = (void *)pOperationState;
- *pulOperationStateLen = len;
- error = nssCKFWSession_GetOperationState(fwSession, &buf);
-
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_STATE_UNSAVEABLE:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_SetOperationState
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SetOperationState
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey,
- CK_OBJECT_HANDLE hAuthenticationKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *eKey;
- NSSCKFWObject *aKey;
- NSSItem state;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * We could loop through the buffer, to catch any purify errors
- * in a place with a "user error" note.
- */
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_OBJECT_HANDLE)0 == hEncryptionKey ) {
- eKey = (NSSCKFWObject *)NULL;
- } else {
- eKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hEncryptionKey);
- if (!eKey) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
- }
-
- if( (CK_OBJECT_HANDLE)0 == hAuthenticationKey ) {
- aKey = (NSSCKFWObject *)NULL;
- } else {
- aKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hAuthenticationKey);
- if (!aKey) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
- }
-
- state.data = pOperationState;
- state.size = ulOperationStateLen;
-
- error = nssCKFWSession_SetOperationState(fwSession, &state, eKey, aKey);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_CHANGED:
- case CKR_KEY_NEEDED:
- case CKR_KEY_NOT_NEEDED:
- case CKR_SAVED_STATE_INVALID:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_Login
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_Login
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_USER_TYPE userType,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSItem pin, *arg;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) {
- arg = (NSSItem *)NULL;
- } else {
- arg = &pin;
- pin.size = (PRUint32)ulPinLen;
- pin.data = (void *)pPin;
- }
-
- error = nssCKFWSession_Login(fwSession, userType, arg);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_PIN_EXPIRED:
- case CKR_PIN_INCORRECT:
- case CKR_PIN_LOCKED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY_EXISTS:
- case CKR_USER_ALREADY_LOGGED_IN:
- case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
- case CKR_USER_PIN_NOT_INITIALIZED:
- case CKR_USER_TOO_MANY_TYPES:
- case CKR_USER_TYPE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_Logout
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_Logout
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_Logout(fwSession);
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_CreateObject
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_CreateObject
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- *phObject = (CK_OBJECT_HANDLE)0;
-
- fwObject = nssCKFWSession_CreateObject(fwSession, pTemplate,
- ulCount, &error);
- if (!fwObject) {
- goto loser;
- }
-
- *phObject = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
- if( (CK_OBJECT_HANDLE)0 == *phObject ) {
- nssCKFWObject_Destroy(fwObject);
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_ATTRIBUTE_READ_ONLY:
- case CKR_ATTRIBUTE_TYPE_INVALID:
- case CKR_ATTRIBUTE_VALUE_INVALID:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY:
- case CKR_TEMPLATE_INCOMPLETE:
- case CKR_TEMPLATE_INCONSISTENT:
- case CKR_TOKEN_WRITE_PROTECTED:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_CopyObject
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_CopyObject
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWObject *fwNewObject;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phNewObject ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- *phNewObject = (CK_OBJECT_HANDLE)0;
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
- if (!fwObject) {
- error = CKR_OBJECT_HANDLE_INVALID;
- goto loser;
- }
-
- fwNewObject = nssCKFWSession_CopyObject(fwSession, fwObject,
- pTemplate, ulCount, &error);
- if (!fwNewObject) {
- goto loser;
- }
-
- *phNewObject = nssCKFWInstance_CreateObjectHandle(fwInstance,
- fwNewObject, &error);
- if( (CK_OBJECT_HANDLE)0 == *phNewObject ) {
- nssCKFWObject_Destroy(fwNewObject);
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_ATTRIBUTE_READ_ONLY:
- case CKR_ATTRIBUTE_TYPE_INVALID:
- case CKR_ATTRIBUTE_VALUE_INVALID:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OBJECT_HANDLE_INVALID:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY:
- case CKR_TEMPLATE_INCONSISTENT:
- case CKR_TOKEN_WRITE_PROTECTED:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_DestroyObject
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DestroyObject
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
- if (!fwObject) {
- error = CKR_OBJECT_HANDLE_INVALID;
- goto loser;
- }
-
- nssCKFWInstance_DestroyObjectHandle(fwInstance, hObject);
- nssCKFWObject_Destroy(fwObject);
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OBJECT_HANDLE_INVALID:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY:
- case CKR_TOKEN_WRITE_PROTECTED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GetObjectSize
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetObjectSize
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ULONG_PTR pulSize
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
- if (!fwObject) {
- error = CKR_OBJECT_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_ULONG_PTR)CK_NULL_PTR == pulSize ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- *pulSize = (CK_ULONG)0;
-
- *pulSize = nssCKFWObject_GetObjectSize(fwObject, &error);
- if( ((CK_ULONG)0 == *pulSize) && (CKR_OK != error) ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_INFORMATION_SENSITIVE:
- case CKR_OBJECT_HANDLE_INVALID:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GetAttributeValue
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetAttributeValue
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- CK_BBOOL sensitive = CK_FALSE;
- CK_BBOOL invalid = CK_FALSE;
- CK_BBOOL tooSmall = CK_FALSE;
- CK_ULONG i;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
- if (!fwObject) {
- error = CKR_OBJECT_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- for( i = 0; i < ulCount; i++ ) {
- CK_ULONG size = nssCKFWObject_GetAttributeSize(fwObject,
- pTemplate[i].type, &error);
- if( (CK_ULONG)0 == size ) {
- switch( error ) {
- case CKR_ATTRIBUTE_SENSITIVE:
- case CKR_INFORMATION_SENSITIVE:
- sensitive = CK_TRUE;
- pTemplate[i].ulValueLen = (CK_ULONG)(-1);
- continue;
- case CKR_ATTRIBUTE_TYPE_INVALID:
- invalid = CK_TRUE;
- pTemplate[i].ulValueLen = (CK_ULONG)(-1);
- continue;
- case CKR_OK:
- break;
- default:
- goto loser;
- }
- }
-
- if( (CK_VOID_PTR)CK_NULL_PTR == pTemplate[i].pValue ) {
- pTemplate[i].ulValueLen = size;
- } else {
- NSSItem it, *p;
-
- if( pTemplate[i].ulValueLen < size ) {
- tooSmall = CK_TRUE;
- continue;
- }
-
- it.size = (PRUint32)pTemplate[i].ulValueLen;
- it.data = (void *)pTemplate[i].pValue;
- p = nssCKFWObject_GetAttribute(fwObject, pTemplate[i].type, &it,
- (NSSArena *)NULL, &error);
- if (!p) {
- switch( error ) {
- case CKR_ATTRIBUTE_SENSITIVE:
- case CKR_INFORMATION_SENSITIVE:
- sensitive = CK_TRUE;
- pTemplate[i].ulValueLen = (CK_ULONG)(-1);
- continue;
- case CKR_ATTRIBUTE_TYPE_INVALID:
- invalid = CK_TRUE;
- pTemplate[i].ulValueLen = (CK_ULONG)(-1);
- continue;
- default:
- goto loser;
- }
- }
-
- pTemplate[i].ulValueLen = size;
- }
- }
-
- if( sensitive ) {
- error = CKR_ATTRIBUTE_SENSITIVE;
- goto loser;
- } else if( invalid ) {
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- goto loser;
- } else if( tooSmall ) {
- error = CKR_BUFFER_TOO_SMALL;
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_ATTRIBUTE_SENSITIVE:
- case CKR_ATTRIBUTE_TYPE_INVALID:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OBJECT_HANDLE_INVALID:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_SetAttributeValue
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SetAttributeValue
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- CK_ULONG i;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
- if (!fwObject) {
- error = CKR_OBJECT_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- for (i=0; i < ulCount; i++) {
- NSSItem value;
-
- value.data = pTemplate[i].pValue;
- value.size = pTemplate[i].ulValueLen;
-
- error = nssCKFWObject_SetAttribute(fwObject, fwSession,
- pTemplate[i].type, &value);
-
- if( CKR_OK != error ) {
- goto loser;
- }
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_ATTRIBUTE_READ_ONLY:
- case CKR_ATTRIBUTE_TYPE_INVALID:
- case CKR_ATTRIBUTE_VALUE_INVALID:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OBJECT_HANDLE_INVALID:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY:
- case CKR_TEMPLATE_INCONSISTENT:
- case CKR_TOKEN_WRITE_PROTECTED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_FindObjectsInit
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_FindObjectsInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWFindObjects *fwFindObjects;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( ((CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate) && (ulCount != 0) ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
- if (fwFindObjects) {
- error = CKR_OPERATION_ACTIVE;
- goto loser;
- }
-
- if( CKR_OPERATION_NOT_INITIALIZED != error ) {
- goto loser;
- }
-
- fwFindObjects = nssCKFWSession_FindObjectsInit(fwSession,
- pTemplate, ulCount, &error);
- if (!fwFindObjects) {
- goto loser;
- }
-
- error = nssCKFWSession_SetFWFindObjects(fwSession, fwFindObjects);
-
- if( CKR_OK != error ) {
- nssCKFWFindObjects_Destroy(fwFindObjects);
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_ATTRIBUTE_TYPE_INVALID:
- case CKR_ATTRIBUTE_VALUE_INVALID:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_ACTIVE:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_FindObjects
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_FindObjects
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,
- CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWFindObjects *fwFindObjects;
- CK_ULONG i;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- (void)nsslibc_memset(phObject, 0, sizeof(CK_OBJECT_HANDLE) * ulMaxObjectCount);
- *pulObjectCount = (CK_ULONG)0;
-
- fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
- if (!fwFindObjects) {
- goto loser;
- }
-
- for( i = 0; i < ulMaxObjectCount; i++ ) {
- NSSCKFWObject *fwObject = nssCKFWFindObjects_Next(fwFindObjects,
- NULL, &error);
- if (!fwObject) {
- break;
- }
-
- phObject[i] = nssCKFWInstance_FindObjectHandle(fwInstance, fwObject);
- if( (CK_OBJECT_HANDLE)0 == phObject[i] ) {
- phObject[i] = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
- }
- if( (CK_OBJECT_HANDLE)0 == phObject[i] ) {
- /* This isn't right either, is it? */
- nssCKFWObject_Destroy(fwObject);
- goto loser;
- }
- }
-
- *pulObjectCount = i;
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_FindObjectsFinal
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_FindObjectsFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWFindObjects *fwFindObjects;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
- if (!fwFindObjects) {
- error = CKR_OPERATION_NOT_INITIALIZED;
- goto loser;
- }
-
- nssCKFWFindObjects_Destroy(fwFindObjects);
- error = nssCKFWSession_SetFWFindObjects(fwSession,
- (NSSCKFWFindObjects *)NULL);
-
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_EncryptInit
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_EncryptInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
- if (!fwObject) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- error = nssCKFWMechanism_EncryptInit(fwMechanism, pMechanism,
- fwSession, fwObject);
-
- nssCKFWMechanism_Destroy(fwMechanism);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_FUNCTION_NOT_PERMITTED:
- case CKR_KEY_HANDLE_INVALID:
- case CKR_KEY_SIZE_RANGE:
- case CKR_KEY_TYPE_INCONSISTENT:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_Encrypt
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_Encrypt
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateFinal(fwSession,
- NSSCKFWCryptoOperationType_Encrypt,
- NSSCKFWCryptoOperationState_EncryptDecrypt,
- pData, ulDataLen, pEncryptedData, pulEncryptedDataLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_INVALID:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_CLOSED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_EncryptUpdate
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_EncryptUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_Update(fwSession,
- NSSCKFWCryptoOperationType_Encrypt,
- NSSCKFWCryptoOperationState_EncryptDecrypt,
- pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_EncryptFinal
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_EncryptFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart,
- CK_ULONG_PTR pulLastEncryptedPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_Final(fwSession,
- NSSCKFWCryptoOperationType_Encrypt,
- NSSCKFWCryptoOperationState_EncryptDecrypt,
- pLastEncryptedPart, pulLastEncryptedPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DecryptInit
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DecryptInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
- if (!fwObject) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- error = nssCKFWMechanism_DecryptInit(fwMechanism, pMechanism,
- fwSession, fwObject);
- nssCKFWMechanism_Destroy(fwMechanism);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_FUNCTION_NOT_PERMITTED:
- case CKR_KEY_HANDLE_INVALID:
- case CKR_KEY_SIZE_RANGE:
- case CKR_KEY_TYPE_INCONSISTENT:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_Decrypt
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_Decrypt
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateFinal(fwSession,
- NSSCKFWCryptoOperationType_Decrypt,
- NSSCKFWCryptoOperationState_EncryptDecrypt,
- pEncryptedData, ulEncryptedDataLen, pData, pulDataLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_ENCRYPTED_DATA_INVALID:
- case CKR_ENCRYPTED_DATA_LEN_RANGE:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- case CKR_DATA_LEN_RANGE:
- error = CKR_ENCRYPTED_DATA_LEN_RANGE;
- break;
- case CKR_DATA_INVALID:
- error = CKR_ENCRYPTED_DATA_INVALID;
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DecryptUpdate
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DecryptUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_Update(fwSession,
- NSSCKFWCryptoOperationType_Decrypt,
- NSSCKFWCryptoOperationState_EncryptDecrypt,
- pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_ENCRYPTED_DATA_INVALID:
- case CKR_ENCRYPTED_DATA_LEN_RANGE:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- case CKR_DATA_LEN_RANGE:
- error = CKR_ENCRYPTED_DATA_LEN_RANGE;
- break;
- case CKR_DATA_INVALID:
- error = CKR_ENCRYPTED_DATA_INVALID;
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DecryptFinal
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DecryptFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart,
- CK_ULONG_PTR pulLastPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_Final(fwSession,
- NSSCKFWCryptoOperationType_Decrypt,
- NSSCKFWCryptoOperationState_EncryptDecrypt,
- pLastPart, pulLastPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_FAILED:
- case CKR_FUNCTION_CANCELED:
- case CKR_ENCRYPTED_DATA_INVALID:
- case CKR_ENCRYPTED_DATA_LEN_RANGE:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- case CKR_DATA_LEN_RANGE:
- error = CKR_ENCRYPTED_DATA_LEN_RANGE;
- break;
- case CKR_DATA_INVALID:
- error = CKR_ENCRYPTED_DATA_INVALID;
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DigestInit
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DigestInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- error = nssCKFWMechanism_DigestInit(fwMechanism, pMechanism, fwSession);
-
- nssCKFWMechanism_Destroy(fwMechanism);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_Digest
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_Digest
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateFinal(fwSession,
- NSSCKFWCryptoOperationType_Digest,
- NSSCKFWCryptoOperationState_Digest,
- pData, ulDataLen, pDigest, pulDigestLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DigestUpdate
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DigestUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_DigestUpdate(fwSession,
- NSSCKFWCryptoOperationType_Digest,
- NSSCKFWCryptoOperationState_Digest,
- pData, ulDataLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DigestKey
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DigestKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
- if (!fwObject) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_DigestKey(fwSession, fwObject);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_HANDLE_INVALID:
- case CKR_KEY_INDIGESTIBLE:
- case CKR_KEY_SIZE_RANGE:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DigestFinal
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DigestFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_Final(fwSession,
- NSSCKFWCryptoOperationType_Digest,
- NSSCKFWCryptoOperationState_Digest,
- pDigest, pulDigestLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_SignInit
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
- if (!fwObject) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- error = nssCKFWMechanism_SignInit(fwMechanism, pMechanism, fwSession,
- fwObject);
-
- nssCKFWMechanism_Destroy(fwMechanism);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_FUNCTION_NOT_PERMITTED:
- case CKR_KEY_HANDLE_INVALID:
- case CKR_KEY_SIZE_RANGE:
- case CKR_KEY_TYPE_INCONSISTENT:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_Sign
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_Sign
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateFinal(fwSession,
- NSSCKFWCryptoOperationType_Sign,
- NSSCKFWCryptoOperationState_SignVerify,
- pData, ulDataLen, pSignature, pulSignatureLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_INVALID:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- case CKR_FUNCTION_REJECTED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_SignUpdate
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_DigestUpdate(fwSession,
- NSSCKFWCryptoOperationType_Sign,
- NSSCKFWCryptoOperationState_SignVerify,
- pPart, ulPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_SignFinal
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_Final(fwSession,
- NSSCKFWCryptoOperationType_Sign,
- NSSCKFWCryptoOperationState_SignVerify,
- pSignature, pulSignatureLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- case CKR_FUNCTION_REJECTED:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_SignRecoverInit
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignRecoverInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
- if (!fwObject) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- error = nssCKFWMechanism_SignRecoverInit(fwMechanism, pMechanism, fwSession,
- fwObject);
-
- nssCKFWMechanism_Destroy(fwMechanism);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_FUNCTION_NOT_PERMITTED:
- case CKR_KEY_HANDLE_INVALID:
- case CKR_KEY_SIZE_RANGE:
- case CKR_KEY_TYPE_INCONSISTENT:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_SignRecover
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignRecover
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateFinal(fwSession,
- NSSCKFWCryptoOperationType_SignRecover,
- NSSCKFWCryptoOperationState_SignVerify,
- pData, ulDataLen, pSignature, pulSignatureLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_INVALID:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_VerifyInit
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_VerifyInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
- if (!fwObject) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- error = nssCKFWMechanism_VerifyInit(fwMechanism, pMechanism, fwSession,
- fwObject);
-
- nssCKFWMechanism_Destroy(fwMechanism);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_FUNCTION_NOT_PERMITTED:
- case CKR_KEY_HANDLE_INVALID:
- case CKR_KEY_SIZE_RANGE:
- case CKR_KEY_TYPE_INCONSISTENT:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_Verify
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_Verify
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateFinal(fwSession,
- NSSCKFWCryptoOperationType_Verify,
- NSSCKFWCryptoOperationState_SignVerify,
- pData, ulDataLen, pSignature, &ulSignatureLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_INVALID:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SIGNATURE_INVALID:
- case CKR_SIGNATURE_LEN_RANGE:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_VerifyUpdate
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_VerifyUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_DigestUpdate(fwSession,
- NSSCKFWCryptoOperationType_Verify,
- NSSCKFWCryptoOperationState_SignVerify,
- pPart, ulPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_VerifyFinal
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_VerifyFinal
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_Final(fwSession,
- NSSCKFWCryptoOperationType_Verify,
- NSSCKFWCryptoOperationState_SignVerify,
- pSignature, &ulSignatureLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SIGNATURE_INVALID:
- case CKR_SIGNATURE_LEN_RANGE:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_VerifyRecoverInit
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_VerifyRecoverInit
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
- if (!fwObject) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- error = nssCKFWMechanism_VerifyRecoverInit(fwMechanism, pMechanism,
- fwSession, fwObject);
-
- nssCKFWMechanism_Destroy(fwMechanism);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_FUNCTION_NOT_PERMITTED:
- case CKR_KEY_HANDLE_INVALID:
- case CKR_KEY_SIZE_RANGE:
- case CKR_KEY_TYPE_INCONSISTENT:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_CLOSED:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_VerifyRecover
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_VerifyRecover
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateFinal(fwSession,
- NSSCKFWCryptoOperationType_VerifyRecover,
- NSSCKFWCryptoOperationState_SignVerify,
- pSignature, ulSignatureLen, pData, pulDataLen);
- if (CKR_OK == error) {
- return CKR_OK;
- }
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_INVALID:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SIGNATURE_INVALID:
- case CKR_SIGNATURE_LEN_RANGE:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DigestEncryptUpdate
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DigestEncryptUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateCombo(fwSession,
- NSSCKFWCryptoOperationType_Encrypt,
- NSSCKFWCryptoOperationType_Digest,
- NSSCKFWCryptoOperationState_Digest,
- pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DecryptDigestUpdate
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DecryptDigestUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateCombo(fwSession,
- NSSCKFWCryptoOperationType_Decrypt,
- NSSCKFWCryptoOperationType_Digest,
- NSSCKFWCryptoOperationState_Digest,
- pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_ENCRYPTED_DATA_INVALID:
- case CKR_ENCRYPTED_DATA_LEN_RANGE:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- case CKR_DATA_INVALID:
- error = CKR_ENCRYPTED_DATA_INVALID;
- break;
- case CKR_DATA_LEN_RANGE:
- error = CKR_ENCRYPTED_DATA_LEN_RANGE;
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_SignEncryptUpdate
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SignEncryptUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateCombo(fwSession,
- NSSCKFWCryptoOperationType_Encrypt,
- NSSCKFWCryptoOperationType_Sign,
- NSSCKFWCryptoOperationState_SignVerify,
- pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DecryptVerifyUpdate
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DecryptVerifyUpdate
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- error = nssCKFWSession_UpdateCombo(fwSession,
- NSSCKFWCryptoOperationType_Decrypt,
- NSSCKFWCryptoOperationType_Verify,
- NSSCKFWCryptoOperationState_SignVerify,
- pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DATA_LEN_RANGE:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_ENCRYPTED_DATA_INVALID:
- case CKR_ENCRYPTED_DATA_LEN_RANGE:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_NOT_INITIALIZED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- break;
- case CKR_DATA_INVALID:
- error = CKR_ENCRYPTED_DATA_INVALID;
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_GenerateKey
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GenerateKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- fwObject = nssCKFWMechanism_GenerateKey(
- fwMechanism,
- pMechanism,
- fwSession,
- pTemplate,
- ulCount,
- &error);
-
- nssCKFWMechanism_Destroy(fwMechanism);
- if (!fwObject) {
- goto loser;
- }
- *phKey= nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_ATTRIBUTE_READ_ONLY:
- case CKR_ATTRIBUTE_TYPE_INVALID:
- case CKR_ATTRIBUTE_VALUE_INVALID:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY:
- case CKR_TEMPLATE_INCOMPLETE:
- case CKR_TEMPLATE_INCONSISTENT:
- case CKR_TOKEN_WRITE_PROTECTED:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_GenerateKeyPair
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GenerateKeyPair
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwPrivateKeyObject;
- NSSCKFWObject *fwPublicKeyObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- error= nssCKFWMechanism_GenerateKeyPair(
- fwMechanism,
- pMechanism,
- fwSession,
- pPublicKeyTemplate,
- ulPublicKeyAttributeCount,
- pPublicKeyTemplate,
- ulPublicKeyAttributeCount,
- &fwPublicKeyObject,
- &fwPrivateKeyObject);
-
- nssCKFWMechanism_Destroy(fwMechanism);
- if (CKR_OK != error) {
- goto loser;
- }
- *phPublicKey = nssCKFWInstance_CreateObjectHandle(fwInstance,
- fwPublicKeyObject,
- &error);
- if (CKR_OK != error) {
- goto loser;
- }
- *phPrivateKey = nssCKFWInstance_CreateObjectHandle(fwInstance,
- fwPrivateKeyObject,
- &error);
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_ATTRIBUTE_READ_ONLY:
- case CKR_ATTRIBUTE_TYPE_INVALID:
- case CKR_ATTRIBUTE_VALUE_INVALID:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_DOMAIN_PARAMS_INVALID:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY:
- case CKR_TEMPLATE_INCOMPLETE:
- case CKR_TEMPLATE_INCONSISTENT:
- case CKR_TOKEN_WRITE_PROTECTED:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_WrapKey
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_WrapKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwKeyObject;
- NSSCKFWObject *fwWrappingKeyObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
- NSSItem wrappedKey;
- CK_ULONG wrappedKeyLength = 0;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwWrappingKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance,
- hWrappingKey);
- if (!fwWrappingKeyObject) {
- error = CKR_WRAPPING_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey);
- if (!fwKeyObject) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- /*
- * first get the length...
- */
- wrappedKeyLength = nssCKFWMechanism_GetWrapKeyLength(
- fwMechanism,
- pMechanism,
- fwSession,
- fwWrappingKeyObject,
- fwKeyObject,
- &error);
- if ((CK_ULONG) 0 == wrappedKeyLength) {
- nssCKFWMechanism_Destroy(fwMechanism);
- goto loser;
- }
- if ((CK_BYTE_PTR)NULL == pWrappedKey) {
- *pulWrappedKeyLen = wrappedKeyLength;
- nssCKFWMechanism_Destroy(fwMechanism);
- return CKR_OK;
- }
- if (wrappedKeyLength > *pulWrappedKeyLen) {
- *pulWrappedKeyLen = wrappedKeyLength;
- nssCKFWMechanism_Destroy(fwMechanism);
- error = CKR_BUFFER_TOO_SMALL;
- goto loser;
- }
-
-
- wrappedKey.data = pWrappedKey;
- wrappedKey.size = wrappedKeyLength;
-
- error = nssCKFWMechanism_WrapKey(
- fwMechanism,
- pMechanism,
- fwSession,
- fwWrappingKeyObject,
- fwKeyObject,
- &wrappedKey);
-
- nssCKFWMechanism_Destroy(fwMechanism);
- *pulWrappedKeyLen = wrappedKey.size;
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_HANDLE_INVALID:
- case CKR_KEY_NOT_WRAPPABLE:
- case CKR_KEY_SIZE_RANGE:
- case CKR_KEY_UNEXTRACTABLE:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_WRAPPING_KEY_HANDLE_INVALID:
- case CKR_WRAPPING_KEY_SIZE_RANGE:
- case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
- break;
- case CKR_KEY_TYPE_INCONSISTENT:
- error = CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_UnwrapKey
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_UnwrapKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWObject *fwWrappingKeyObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
- NSSItem wrappedKey;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwWrappingKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance,
- hUnwrappingKey);
- if (!fwWrappingKeyObject) {
- error = CKR_WRAPPING_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- wrappedKey.data = pWrappedKey;
- wrappedKey.size = ulWrappedKeyLen;
-
- fwObject = nssCKFWMechanism_UnwrapKey(
- fwMechanism,
- pMechanism,
- fwSession,
- fwWrappingKeyObject,
- &wrappedKey,
- pTemplate,
- ulAttributeCount,
- &error);
-
- nssCKFWMechanism_Destroy(fwMechanism);
- if (!fwObject) {
- goto loser;
- }
- *phKey = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_ATTRIBUTE_READ_ONLY:
- case CKR_ATTRIBUTE_TYPE_INVALID:
- case CKR_ATTRIBUTE_VALUE_INVALID:
- case CKR_BUFFER_TOO_SMALL:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_DOMAIN_PARAMS_INVALID:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY:
- case CKR_TEMPLATE_INCOMPLETE:
- case CKR_TEMPLATE_INCONSISTENT:
- case CKR_TOKEN_WRITE_PROTECTED:
- case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
- case CKR_UNWRAPPING_KEY_SIZE_RANGE:
- case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
- case CKR_USER_NOT_LOGGED_IN:
- case CKR_WRAPPED_KEY_INVALID:
- case CKR_WRAPPED_KEY_LEN_RANGE:
- break;
- case CKR_KEY_HANDLE_INVALID:
- error = CKR_UNWRAPPING_KEY_HANDLE_INVALID;
- break;
- case CKR_KEY_SIZE_RANGE:
- error = CKR_UNWRAPPING_KEY_SIZE_RANGE;
- break;
- case CKR_KEY_TYPE_INCONSISTENT:
- error = CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
- break;
- case CKR_ENCRYPTED_DATA_INVALID:
- error = CKR_WRAPPED_KEY_INVALID;
- break;
- case CKR_ENCRYPTED_DATA_LEN_RANGE:
- error = CKR_WRAPPED_KEY_LEN_RANGE;
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_DeriveKey
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_DeriveKey
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSCKFWObject *fwObject;
- NSSCKFWObject *fwBaseKeyObject;
- NSSCKFWSlot *fwSlot;
- NSSCKFWToken *fwToken;
- NSSCKFWMechanism *fwMechanism;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- fwBaseKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hBaseKey);
- if (!fwBaseKeyObject) {
- error = CKR_KEY_HANDLE_INVALID;
- goto loser;
- }
-
- fwSlot = nssCKFWSession_GetFWSlot(fwSession);
- if (!fwSlot) {
- error = CKR_GENERAL_ERROR; /* should never happen! */
- goto loser;
- }
-
- if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
- error = CKR_TOKEN_NOT_PRESENT;
- goto loser;
- }
-
- fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
- if (!fwToken) {
- goto loser;
- }
-
- fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error);
- if (!fwMechanism) {
- goto loser;
- }
-
- fwObject = nssCKFWMechanism_DeriveKey(
- fwMechanism,
- pMechanism,
- fwSession,
- fwBaseKeyObject,
- pTemplate,
- ulAttributeCount,
- &error);
-
- nssCKFWMechanism_Destroy(fwMechanism);
- if (!fwObject) {
- goto loser;
- }
- *phKey = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
-
- if (CKR_OK == error) {
- return CKR_OK;
- }
-
-loser:
- /* verify error */
- switch( error ) {
- case CKR_ARGUMENTS_BAD:
- case CKR_ATTRIBUTE_READ_ONLY:
- case CKR_ATTRIBUTE_TYPE_INVALID:
- case CKR_ATTRIBUTE_VALUE_INVALID:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_DEVICE_REMOVED:
- case CKR_DOMAIN_PARAMS_INVALID:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_KEY_HANDLE_INVALID:
- case CKR_KEY_SIZE_RANGE:
- case CKR_KEY_TYPE_INCONSISTENT:
- case CKR_MECHANISM_INVALID:
- case CKR_MECHANISM_PARAM_INVALID:
- case CKR_OPERATION_ACTIVE:
- case CKR_PIN_EXPIRED:
- case CKR_SESSION_CLOSED:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_READ_ONLY:
- case CKR_TEMPLATE_INCOMPLETE:
- case CKR_TEMPLATE_INCONSISTENT:
- case CKR_TOKEN_WRITE_PROTECTED:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
- return error;
-}
-
-/*
- * NSSCKFWC_SeedRandom
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_SeedRandom
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSItem seed;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_BYTE_PTR)CK_NULL_PTR == pSeed ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /* We could read through the buffer in a Purify trap */
-
- seed.size = (PRUint32)ulSeedLen;
- seed.data = (void *)pSeed;
-
- error = nssCKFWSession_SeedRandom(fwSession, &seed);
-
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_ACTIVE:
- case CKR_RANDOM_SEED_NOT_SUPPORTED:
- case CKR_RANDOM_NO_RNG:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GenerateRandom
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GenerateRandom
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData,
- CK_ULONG ulRandomLen
-)
-{
- CK_RV error = CKR_OK;
- NSSCKFWSession *fwSession;
- NSSItem buffer;
-
- if (!fwInstance) {
- error = CKR_CRYPTOKI_NOT_INITIALIZED;
- goto loser;
- }
-
- fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
- if (!fwSession) {
- error = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- if( (CK_BYTE_PTR)CK_NULL_PTR == pRandomData ) {
- error = CKR_ARGUMENTS_BAD;
- goto loser;
- }
-
- /*
- * A purify error here indicates caller error.
- */
- (void)nsslibc_memset(pRandomData, 0, ulRandomLen);
-
- buffer.size = (PRUint32)ulRandomLen;
- buffer.data = (void *)pRandomData;
-
- error = nssCKFWSession_GetRandom(fwSession, &buffer);
-
- if( CKR_OK != error ) {
- goto loser;
- }
-
- return CKR_OK;
-
- loser:
- switch( error ) {
- case CKR_SESSION_CLOSED:
- /* destroy session? */
- break;
- case CKR_DEVICE_REMOVED:
- /* (void)nssCKFWToken_Destroy(fwToken); */
- break;
- case CKR_ARGUMENTS_BAD:
- case CKR_CRYPTOKI_NOT_INITIALIZED:
- case CKR_DEVICE_ERROR:
- case CKR_DEVICE_MEMORY:
- case CKR_FUNCTION_CANCELED:
- case CKR_FUNCTION_FAILED:
- case CKR_GENERAL_ERROR:
- case CKR_HOST_MEMORY:
- case CKR_OPERATION_ACTIVE:
- case CKR_RANDOM_NO_RNG:
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_USER_NOT_LOGGED_IN:
- break;
- default:
- case CKR_OK:
- error = CKR_GENERAL_ERROR;
- break;
- }
-
- return error;
-}
-
-/*
- * NSSCKFWC_GetFunctionStatus
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_GetFunctionStatus
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
-{
- return CKR_FUNCTION_NOT_PARALLEL;
-}
-
-/*
- * NSSCKFWC_CancelFunction
- *
- */
-NSS_IMPLEMENT CK_RV
-NSSCKFWC_CancelFunction
-(
- NSSCKFWInstance *fwInstance,
- CK_SESSION_HANDLE hSession
-)
-{
- return CKR_FUNCTION_NOT_PARALLEL;
-}
diff --git a/security/nss/lib/crmf/Makefile b/security/nss/lib/crmf/Makefile
deleted file mode 100644
index a774a9566..000000000
--- a/security/nss/lib/crmf/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-
-export:: private_export
diff --git a/security/nss/lib/crmf/asn1cmn.c b/security/nss/lib/crmf/asn1cmn.c
deleted file mode 100644
index 763bbbb2c..000000000
--- a/security/nss/lib/crmf/asn1cmn.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "cmmf.h"
-#include "cmmfi.h"
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(SEC_IntegerTemplate)
-SEC_ASN1_MKSUB(SEC_SignedCertificateTemplate)
-
-static const SEC_ASN1Template CMMFCertResponseTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertResponse)},
- { SEC_ASN1_INTEGER, offsetof(CMMFCertResponse, certReqId)},
- { SEC_ASN1_INLINE, offsetof(CMMFCertResponse, status),
- CMMFPKIStatusInfoTemplate},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER,
- offsetof(CMMFCertResponse, certifiedKeyPair),
- CMMFCertifiedKeyPairTemplate},
- { 0 }
-};
-
-static const SEC_ASN1Template CMMFCertOrEncCertTemplate[] = {
- { SEC_ASN1_ANY, offsetof(CMMFCertOrEncCert, derValue), NULL,
- sizeof(CMMFCertOrEncCert)},
- { 0 }
-};
-
-const SEC_ASN1Template CMMFCertifiedKeyPairTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertifiedKeyPair)},
- { SEC_ASN1_INLINE, offsetof(CMMFCertifiedKeyPair, certOrEncCert),
- CMMFCertOrEncCertTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 0,
- offsetof(CMMFCertifiedKeyPair, privateKey),
- CRMFEncryptedValueTemplate},
- { SEC_ASN1_NO_STREAM | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
- offsetof (CMMFCertifiedKeyPair, derPublicationInfo),
- SEC_ASN1_SUB(SEC_AnyTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CMMFPKIStatusInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFPKIStatusInfo)},
- { SEC_ASN1_INTEGER, offsetof(CMMFPKIStatusInfo, status)},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_UTF8_STRING,
- offsetof(CMMFPKIStatusInfo, statusString)},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BIT_STRING,
- offsetof(CMMFPKIStatusInfo, failInfo)},
- { 0 }
-};
-
-const SEC_ASN1Template CMMFSequenceOfCertsTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF| SEC_ASN1_XTRN, 0,
- SEC_ASN1_SUB(SEC_SignedCertificateTemplate)}
-};
-
-const SEC_ASN1Template CMMFRandTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFRand)},
- { SEC_ASN1_INTEGER, offsetof(CMMFRand, integer)},
- { SEC_ASN1_OCTET_STRING, offsetof(CMMFRand, senderHash)},
- { 0 }
-};
-
-const SEC_ASN1Template CMMFPOPODecKeyRespContentTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
- offsetof(CMMFPOPODecKeyRespContent, responses),
- SEC_ASN1_SUB(SEC_IntegerTemplate),
- sizeof(CMMFPOPODecKeyRespContent)},
- { 0 }
-};
-
-const SEC_ASN1Template CMMFCertOrEncCertEncryptedCertTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | 1,
- 0,
- CRMFEncryptedValueTemplate},
- { 0 }
-};
-
-const SEC_ASN1Template CMMFCertOrEncCertCertificateTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- 0,
- SEC_ASN1_SUB(SEC_SignedCertificateTemplate)},
- { 0 }
-};
-
-const SEC_ASN1Template CMMFCertRepContentTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFCertRepContent)},
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL |
- SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(CMMFCertRepContent, caPubs),
- CMMFSequenceOfCertsTemplate },
- { SEC_ASN1_SEQUENCE_OF, offsetof(CMMFCertRepContent, response),
- CMMFCertResponseTemplate},
- { 0 }
-};
-
-static const SEC_ASN1Template CMMFChallengeTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFChallenge)},
- { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN,
- offsetof(CMMFChallenge, owf),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, witness) },
- { SEC_ASN1_ANY, offsetof(CMMFChallenge, senderDER) },
- { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, key) },
- { SEC_ASN1_OCTET_STRING, offsetof(CMMFChallenge, challenge) },
- { 0 }
-};
-
-const SEC_ASN1Template CMMFPOPODecKeyChallContentTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF,offsetof(CMMFPOPODecKeyChallContent, challenges),
- CMMFChallengeTemplate, sizeof(CMMFPOPODecKeyChallContent) },
- { 0 }
-};
-
-SECStatus
-cmmf_decode_process_cert_response(PRArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertResponse *inCertResp)
-{
- SECStatus rv = SECSuccess;
-
- if (inCertResp->certifiedKeyPair != NULL) {
- rv = cmmf_decode_process_certified_key_pair(poolp,
- db,
- inCertResp->certifiedKeyPair);
- }
- return rv;
-}
-
-static CERTCertificate*
-cmmf_DecodeDERCertificate(CERTCertDBHandle *db, SECItem *derCert)
-{
- CERTCertificate *newCert;
-
- newCert = CERT_NewTempCertificate(db, derCert, NULL, PR_FALSE, PR_TRUE);
- return newCert;
-}
-
-static CMMFCertOrEncCertChoice
-cmmf_get_certorenccertchoice_from_der(SECItem *der)
-{
- CMMFCertOrEncCertChoice retChoice;
-
- switch(der->data[0] & 0x0f) {
- case 0:
- retChoice = cmmfCertificate;
- break;
- case 1:
- retChoice = cmmfEncryptedCert;
- break;
- default:
- retChoice = cmmfNoCertOrEncCert;
- break;
- }
- return retChoice;
-}
-
-static SECStatus
-cmmf_decode_process_certorenccert(PRArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertOrEncCert *inCertOrEncCert)
-{
- SECStatus rv = SECSuccess;
-
- inCertOrEncCert->choice =
- cmmf_get_certorenccertchoice_from_der(&inCertOrEncCert->derValue);
-
- switch (inCertOrEncCert->choice) {
- case cmmfCertificate:
- {
- /* The DER has implicit tagging, so we gotta switch it to
- * un-tagged in order for the ASN1 parser to understand it.
- * Saving the bits that were changed.
- */
- inCertOrEncCert->derValue.data[0] = 0x30;
- inCertOrEncCert->cert.certificate =
- cmmf_DecodeDERCertificate(db, &inCertOrEncCert->derValue);
- if (inCertOrEncCert->cert.certificate == NULL) {
- rv = SECFailure;
- }
-
- }
- break;
- case cmmfEncryptedCert:
- PORT_Assert(poolp);
- if (!poolp) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- break;
- }
- inCertOrEncCert->cert.encryptedCert =
- PORT_ArenaZNew(poolp, CRMFEncryptedValue);
- if (inCertOrEncCert->cert.encryptedCert == NULL) {
- rv = SECFailure;
- break;
- }
- rv = SEC_ASN1Decode(poolp, inCertOrEncCert->cert.encryptedCert,
- CMMFCertOrEncCertEncryptedCertTemplate,
- (const char*)inCertOrEncCert->derValue.data,
- inCertOrEncCert->derValue.len);
- break;
- default:
- rv = SECFailure;
- }
- return rv;
-}
-
-SECStatus
-cmmf_decode_process_certified_key_pair(PRArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertifiedKeyPair *inCertKeyPair)
-{
- return cmmf_decode_process_certorenccert (poolp,
- db,
- &inCertKeyPair->certOrEncCert);
-}
-
-
diff --git a/security/nss/lib/crmf/challcli.c b/security/nss/lib/crmf/challcli.c
deleted file mode 100644
index c38362160..000000000
--- a/security/nss/lib/crmf/challcli.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "cmmf.h"
-#include "cmmfi.h"
-#include "secitem.h"
-#include "pk11func.h"
-#include "secder.h"
-#include "sechash.h"
-
-CMMFPOPODecKeyChallContent*
-CMMF_CreatePOPODecKeyChallContentFromDER(const char *buf, long len)
-{
- PRArenaPool *poolp;
- CMMFPOPODecKeyChallContent *challContent;
- SECStatus rv;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return NULL;
- }
- challContent = PORT_ArenaZNew(poolp, CMMFPOPODecKeyChallContent);
- if (challContent == NULL) {
- goto loser;
- }
- challContent->poolp = poolp;
- rv = SEC_ASN1Decode(poolp, challContent,
- CMMFPOPODecKeyChallContentTemplate, buf, len);
- if (rv != SECSuccess) {
- goto loser;
- }
- if (challContent->challenges) {
- while (challContent->challenges[challContent->numChallenges] != NULL) {
- challContent->numChallenges++;
- }
- challContent->numAllocated = challContent->numChallenges;
- }
- return challContent;
- loser:
- if (poolp != NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return NULL;
-}
-
-int
-CMMF_POPODecKeyChallContentGetNumChallenges
- (CMMFPOPODecKeyChallContent *inKeyChallCont)
-{
- PORT_Assert(inKeyChallCont != NULL);
- if (inKeyChallCont == NULL) {
- return 0;
- }
- return inKeyChallCont->numChallenges;
-}
-
-SECItem*
-CMMF_POPODecKeyChallContentGetPublicValue
- (CMMFPOPODecKeyChallContent *inKeyChallCont,
- int inIndex)
-{
- PORT_Assert(inKeyChallCont != NULL);
- if (inKeyChallCont == NULL || (inIndex > inKeyChallCont->numChallenges-1)||
- inIndex < 0) {
- return NULL;
- }
- return SECITEM_DupItem(&inKeyChallCont->challenges[inIndex]->key);
-}
-
-static SECAlgorithmID*
-cmmf_get_owf(CMMFPOPODecKeyChallContent *inChalCont,
- int inIndex)
-{
- int i;
-
- for (i=inIndex; i >= 0; i--) {
- if (inChalCont->challenges[i]->owf != NULL) {
- return inChalCont->challenges[i]->owf;
- }
- }
- return NULL;
-}
-
-SECStatus
-CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont,
- int inIndex,
- SECKEYPrivateKey *inPrivKey)
-{
- CMMFChallenge *challenge;
- SECItem *decryptedRand=NULL;
- PRArenaPool *poolp = NULL;
- SECAlgorithmID *owf;
- SECStatus rv = SECFailure;
- SECOidTag tag;
- CMMFRand randStr;
- SECItem hashItem;
- unsigned char hash[HASH_LENGTH_MAX];
-
- PORT_Assert(inChalCont != NULL && inPrivKey != NULL);
- if (inChalCont == NULL || inIndex <0 || inIndex > inChalCont->numChallenges
- || inPrivKey == NULL){
- return SECFailure;
- }
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- goto loser;
- }
-
- challenge = inChalCont->challenges[inIndex];
- decryptedRand = SECITEM_AllocItem(poolp, NULL, challenge->challenge.len);
- if (decryptedRand == NULL) {
- goto loser;
- }
- rv = PK11_PrivDecryptPKCS1(inPrivKey, decryptedRand->data,
- &decryptedRand->len, decryptedRand->len,
- challenge->challenge.data, challenge->challenge.len);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = SEC_ASN1DecodeItem(poolp, &randStr, CMMFRandTemplate,
- decryptedRand);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECFailure; /* Just so that when we do go to loser,
- * I won't have to set it again.
- */
- owf = cmmf_get_owf(inChalCont, inIndex);
- if (owf == NULL) {
- /* No hashing algorithm came with the challenges. Can't verify */
- goto loser;
- }
- /* Verify the hashes in the challenge */
- tag = SECOID_FindOIDTag(&owf->algorithm);
- hashItem.len = HASH_ResultLenByOidTag(tag);
- if (!hashItem.len)
- goto loser; /* error code has been set */
-
- rv = PK11_HashBuf(tag, hash, randStr.integer.data, randStr.integer.len);
- if (rv != SECSuccess) {
- goto loser;
- }
- hashItem.data = hash;
- if (SECITEM_CompareItem(&hashItem, &challenge->witness) != SECEqual) {
- /* The hash for the data we decrypted doesn't match the hash provided
- * in the challenge. Bail out.
- */
- PORT_SetError(SEC_ERROR_BAD_DATA);
- rv = SECFailure;
- goto loser;
- }
- rv = PK11_HashBuf(tag, hash, challenge->senderDER.data,
- challenge->senderDER.len);
- if (rv != SECSuccess) {
- goto loser;
- }
- if (SECITEM_CompareItem(&hashItem, &randStr.senderHash) != SECEqual) {
- /* The hash for the data we decrypted doesn't match the hash provided
- * in the challenge. Bail out.
- */
- PORT_SetError(SEC_ERROR_BAD_DATA);
- rv = SECFailure;
- goto loser;
- }
- /* All of the hashes have verified, so we can now store the integer away.*/
- rv = SECITEM_CopyItem(inChalCont->poolp, &challenge->randomNumber,
- &randStr.integer);
- loser:
- if (poolp) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return rv;
-}
-
-SECStatus
-CMMF_POPODecKeyChallContentGetRandomNumber
- (CMMFPOPODecKeyChallContent *inKeyChallCont,
- int inIndex,
- long *inDest)
-{
- CMMFChallenge *challenge;
-
- PORT_Assert(inKeyChallCont != NULL);
- if (inKeyChallCont == NULL || inIndex > 0 || inIndex >=
- inKeyChallCont->numChallenges) {
- return SECFailure;
- }
- challenge = inKeyChallCont->challenges[inIndex];
- if (challenge->randomNumber.data == NULL) {
- /* There is no random number here, nothing to see. */
- return SECFailure;
- }
- *inDest = DER_GetInteger(&challenge->randomNumber);
- return (*inDest == -1) ? SECFailure : SECSuccess;
-}
-
-SECStatus
-CMMF_EncodePOPODecKeyRespContent(long *inDecodedRand,
- int inNumRand,
- CRMFEncoderOutputCallback inCallback,
- void *inArg)
-{
- PRArenaPool *poolp;
- CMMFPOPODecKeyRespContent *response;
- SECItem *currItem;
- SECStatus rv=SECFailure;
- int i;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return SECFailure;
- }
- response = PORT_ArenaZNew(poolp, CMMFPOPODecKeyRespContent);
- if (response == NULL) {
- goto loser;
- }
- response->responses = PORT_ArenaZNewArray(poolp, SECItem*, inNumRand+1);
- if (response->responses == NULL) {
- goto loser;
- }
- for (i=0; i<inNumRand; i++) {
- currItem = response->responses[i] = PORT_ArenaZNew(poolp,SECItem);
- if (currItem == NULL) {
- goto loser;
- }
- currItem = SEC_ASN1EncodeInteger(poolp, currItem, inDecodedRand[i]);
- if (currItem == NULL) {
- goto loser;
- }
- }
- rv = cmmf_user_encode(response, inCallback, inArg,
- CMMFPOPODecKeyRespContentTemplate);
- loser:
- if (poolp != NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return rv;
-}
diff --git a/security/nss/lib/crmf/cmmf.h b/security/nss/lib/crmf/cmmf.h
deleted file mode 100644
index b5b29a697..000000000
--- a/security/nss/lib/crmf/cmmf.h
+++ /dev/null
@@ -1,1090 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _CMMF_H_
-#define _CMMF_H_
-/*
- * These are the functions exported by the security library for
- * implementing Certificate Management Message Formats (CMMF).
- *
- * This API is designed against July 1998 CMMF draft. Please read this
- * draft before trying to use this API in an application that use CMMF.
- */
-#include "seccomon.h"
-#include "cmmft.h"
-#include "crmf.h"
-
-SEC_BEGIN_PROTOS
-
-/******************* Creation Functions *************************/
-
-/*
- * FUNCTION: CMMF_CreateCertRepContent
- * INPUTS:
- * NONE
- * NOTES:
- * This function will create an empty CMMFCertRepContent Structure.
- * The client of the library must set the CMMFCertResponses.
- * Call CMMF_CertRepContentSetCertResponse to accomplish this task.
- * If the client of the library also wants to include the chain of
- * CA certs required to make the certificates in CMMFCertResponse valid,
- * then the user must also set the caPubs field of CMMFCertRepContent.
- * Call CMMF_CertRepContentSetCAPubs to accomplish this. After setting
- * the desired fields, the user can then call CMMF_EncodeCertRepContent
- * to DER-encode the CertRepContent.
- * RETURN:
- * A pointer to the CMMFCertRepContent. A NULL return value indicates
- * an error in allocating memory or failure to initialize the structure.
- */
-extern CMMFCertRepContent* CMMF_CreateCertRepContent(void);
-
-/*
- * FUNCTION: CMMF_CreateCertRepContentFromDER
- * INPUTS
- * db
- * The certificate database where the certificates will be placed.
- * The certificates will be placed in the temporary database associated
- * with the handle.
- * buf
- * A buffer to the DER-encoded CMMFCertRepContent
- * len
- * The length in bytes of the buffer 'buf'
- * NOTES:
- * This function passes the buffer to the ASN1 decoder and creates a
- * CMMFCertRepContent structure. The user must call
- * CMMF_DestroyCertRepContent after the return value is no longer needed.
- *
- * RETURN:
- * A pointer to the CMMFCertRepContent structure. A NULL return
- * value indicates the library was unable to parse the DER.
- */
-extern CMMFCertRepContent*
- CMMF_CreateCertRepContentFromDER(CERTCertDBHandle *db,
- const char *buf,
- long len);
-
-/*
- * FUNCTION: CMMF_CreateCertResponse
- * INPUTS:
- * inCertReqId
- * The Certificate Request Id this response is for.
- * NOTES:
- * This creates a CMMFCertResponse. This response should correspond
- * to a request that was received via CRMF. From the CRMF message you
- * can get the Request Id to pass in as inCertReqId, in essence binding
- * a CMRFCertRequest message to the CMMFCertResponse created by this
- * function. If no requuest id is associated with the response to create
- * then the user should pass in -1 for 'inCertReqId'.
- *
- * RETURN:
- * A pointer to the new CMMFCertResponse corresponding to the request id
- * passed in. A NULL return value indicates an error while trying to
- * create the CMMFCertResponse.
- */
-extern CMMFCertResponse* CMMF_CreateCertResponse(long inCertReqId);
-
-/*
- * FUNCTION: CMMF_CreateKeyRecRepContent
- * INPUTS:
- * NONE
- * NOTES:
- * This function creates a new empty CMMFKeyRecRepContent structure.
- * At the very minimum, the user must call
- * CMMF_KeyRecRepContentSetPKIStatusInfoStatus field to have an
- * encodable structure. Depending on what the response is, the user may
- * have to set other fields as well to properly build up the structure so
- * that it can be encoded. Refer to the CMMF draft for how to properly
- * set up a CMMFKeyRecRepContent. This is the structure that an RA returns
- * to an end entity when doing key recovery.
-
- * The user must call CMMF_DestroyKeyRecRepContent when the return value
- * is no longer needed.
- * RETURN:
- * A pointer to the empty CMMFKeyRecRepContent. A return value of NULL
- * indicates an error in allocating memory or initializing the structure.
- */
-extern CMMFKeyRecRepContent *CMMF_CreateKeyRecRepContent(void);
-
-/*
- * FUNCTION: CMMF_CreateKeyRecRepContentFromDER
- * INPUTS:
- * db
- * The handle for the certificate database where the decoded
- * certificates will be placed. The decoded certificates will
- * be placed in the temporary database associated with the
- * handle.
- * buf
- * A buffer contatining the DER-encoded CMMFKeyRecRepContent
- * len
- * The length in bytes of the buffer 'buf'
- * NOTES
- * This function passes the buffer to the ASN1 decoder and creates a
- * CMMFKeyRecRepContent structure.
- *
- * RETURN:
- * A pointer to the CMMFKeyRecRepContent structure. A NULL return
- * value indicates the library was unable to parse the DER.
- */
-extern CMMFKeyRecRepContent*
- CMMF_CreateKeyRecRepContentFromDER(CERTCertDBHandle *db,
- const char *buf,
- long len);
-
-/*
- * FUNCTION: CMMF_CreatePOPODecKeyChallContent
- * INPUTS:
- * NONE
- * NOTES:
- * This function creates an empty CMMFPOPODecKeyChallContent. The user
- * must add the challenges individually specifying the random number to
- * be used and the public key to be used when creating each individual
- * challenge. User can accomplish this by calling the function
- * CMMF_POPODecKeyChallContentSetNextChallenge.
- * RETURN:
- * A pointer to a CMMFPOPODecKeyChallContent structure. Ther user can
- * then call CMMF_EncodePOPODecKeyChallContent passing in the return
- * value from this function after setting all of the challenges. A
- * return value of NULL indicates an error while creating the
- * CMMFPOPODecKeyChallContent structure.
- */
-extern CMMFPOPODecKeyChallContent*
- CMMF_CreatePOPODecKeyChallContent(void);
-
-/*
- * FUNCTION: CMMF_CreatePOPODecKeyChallContentFromDER
- * INPUTS
- * buf
- * A buffer containing the DER-encoded CMMFPOPODecKeyChallContent
- * len
- * The length in bytes of the buffer 'buf'
- * NOTES:
- * This function passes the buffer to the ASN1 decoder and creates a
- * CMMFPOPODecKeyChallContent structure.
- *
- * RETURN:
- * A pointer to the CMMFPOPODecKeyChallContent structure. A NULL return
- * value indicates the library was unable to parse the DER.
- */
-extern CMMFPOPODecKeyChallContent*
- CMMF_CreatePOPODecKeyChallContentFromDER(const char *buf, long len);
-
-/*
- * FUNCTION: CMMF_CreatePOPODecKeyRespContentFromDER
- * INPUTS:
- * buf
- * A buffer contatining the DER-encoded CMMFPOPODecKeyRespContent
- * len
- * The length in bytes of the buffer 'buf'
- * NOTES
- * This function passes the buffer to the ASN1 decoder and creates a
- * CMMFPOPODecKeyRespContent structure.
- *
- * RETURN:
- * A pointer to the CMMFPOPODecKeyRespContent structure. A NULL return
- * value indicates the library was unable to parse the DER.
- */
-extern CMMFPOPODecKeyRespContent*
- CMMF_CreatePOPODecKeyRespContentFromDER(const char *buf, long len);
-
-/************************** Set Functions *************************/
-
-/*
- * FUNCTION: CMMF_CertRepContentSetCertResponses
- * INPUTS:
- * inCertRepContent
- * The CMMFCertRepContent to operate on.
- * inCertResponses
- * An array of pointers to CMMFCertResponse structures to
- * add to the CMMFCertRepContent structure.
- * inNumResponses
- * The length of the array 'inCertResponses'
- * NOTES:
- * This function will add the CMMFCertResponse structure to the
- * CMMFCertRepContent passed in. The CMMFCertResponse field of
- * CMMFCertRepContent is required, so the client must call this function
- * before calling CMMF_EncodeCertRepContent. If the user calls
- * CMMF_EncodeCertRepContent before calling this function,
- * CMMF_EncodeCertRepContent will fail.
- *
- * RETURN:
- * SECSuccess if adding the CMMFCertResponses to the CMMFCertRepContent
- * structure was successful. Any other return value indicates an error
- * while trying to add the CMMFCertResponses.
- */
-extern SECStatus
- CMMF_CertRepContentSetCertResponses(CMMFCertRepContent *inCertRepContent,
- CMMFCertResponse **inCertResponses,
- int inNumResponses);
-
-/*
- * FUNCTION: CMMF_CertRepContentSetCAPubs
- * INPUTS:
- * inCertRepContent
- * The CMMFCertRepContent to operate on.
- * inCAPubs
- * The certificate list which makes up the chain of CA certificates
- * required to make the issued cert valid.
- * NOTES:
- * This function will set the the certificates in the CA chain as part
- * of the CMMFCertRepContent. This field is an optional member of the
- * CMMFCertRepContent structure, so the client is not required to call
- * this function before calling CMMF_EncodeCertRepContent.
- *
- * RETURN:
- * SECSuccess if adding the 'inCAPubs' to the CERTRepContent was successful.
- * Any other return value indicates an error while adding 'inCAPubs' to the
- * CMMFCertRepContent structure.
- *
- */
-extern SECStatus
- CMMF_CertRepContentSetCAPubs (CMMFCertRepContent *inCertRepContent,
- CERTCertList *inCAPubs);
-
-/*
- * FUNCTION: CMMF_CertResponseSetPKIStatusInfoStatus
- * INPUTS:
- * inCertResp
- * The CMMFCertResponse to operate on.
- * inPKIStatus
- * The value to set for the PKIStatusInfo.status field.
- * NOTES:
- * This function will set the CertResponse.status.status field of
- * the CMMFCertResponse structure. (View the definition of CertResponse
- * in the CMMF draft to see exactly which value this talks about.) This
- * field is a required member of the structure, so the user must call this
- * function in order to have a CMMFCertResponse that can be encoded.
- *
- * RETURN:
- * SECSuccess if setting the field with the passed in value was successful.
- * Any other return value indicates an error while trying to set the field.
- */
-extern SECStatus
- CMMF_CertResponseSetPKIStatusInfoStatus (CMMFCertResponse *inCertResp,
- CMMFPKIStatus inPKIStatus);
-
-/*
- * FUNCTION: CMMF_CertResponseSetCertificate
- * INPUTS:
- * inCertResp
- * The CMMFCertResponse to operate on.
- * inCertificate
- * The certificate to add to the
- * CertResponse.CertifiedKeyPair.certOrEncCert.certificate field.
- * NOTES:
- * This function will take the certificate and make it a member of the
- * CMMFCertResponse. The certificate should be the actual certificate
- * being issued via the response.
- *
- * RETURN:
- * SECSuccess if adding the certificate to the response was successful.
- * Any other return value indicates an error in adding the certificate to
- * the CertResponse.
- */
-extern SECStatus
- CMMF_CertResponseSetCertificate (CMMFCertResponse *inCertResp,
- CERTCertificate *inCertificate);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentSetPKIStatusInfoStatus
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRecRepContent to operate on.
- * inPKIStatus
- * The value to set the PKIStatusInfo.status field to.
- * NOTES:
- * This function sets the only required field for the KeyRecRepContent.
- * In most cases, the user will set this field and other fields of the
- * structure to properly create the CMMFKeyRecRepContent structure.
- * Refer to the CMMF draft to see which fields need to be set in order
- * to create the desired CMMFKeyRecRepContent.
- *
- * RETURN:
- * SECSuccess if setting the PKIStatusInfo.status field was successful.
- * Any other return value indicates an error in setting the field.
- */
-extern SECStatus
-CMMF_KeyRecRepContentSetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep,
- CMMFPKIStatus inPKIStatus);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentSetNewSignCert
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRecRepContent to operate on.
- * inNewSignCert
- * The new signing cert to add to the CMMFKeyRecRepContent structure.
- * NOTES:
- * This function sets the new signeing cert in the CMMFKeyRecRepContent
- * structure.
- *
- * RETURN:
- * SECSuccess if setting the new signing cert was successful. Any other
- * return value indicates an error occurred while trying to add the
- * new signing certificate.
- */
-extern SECStatus
- CMMF_KeyRecRepContentSetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertificate *inNewSignCert);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentSetCACerts
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRecRepContent to operate on.
- * inCACerts
- * The list of CA certificates required to construct a valid
- * certificate chain with the certificates that will be returned
- * to the end user via this KeyRecRepContent.
- * NOTES:
- * This function sets the caCerts that are required to form a chain with the
- * end entity certificates that are being re-issued in this
- * CMMFKeyRecRepContent structure.
- *
- * RETURN:
- * SECSuccess if adding the caCerts was successful. Any other return value
- * indicates an error while tring to add the caCerts.
- */
-extern SECStatus
- CMMF_KeyRecRepContentSetCACerts(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertList *inCACerts);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentSetCertifiedKeyPair
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRecRepContent to operate on.
- * inCert
- * The certificate to add to the CMMFKeyRecRepContent structure.
- * inPrivKey
- * The private key associated with the certificate above passed in.
- * inPubKey
- * The public key to use for wrapping the private key.
- * NOTES:
- * This function adds another certificate-key pair to the
- * CMMFKeyRecRepcontent structure. There may be more than one
- * certificate-key pair in the structure, so the user must call this
- * function multiple times to add more than one cert-key pair.
- *
- * RETURN:
- * SECSuccess if adding the certified key pair was successful. Any other
- * return value indicates an error in adding certified key pair to
- * CMMFKeyRecRepContent structure.
- */
-extern SECStatus
- CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertificate *inCert,
- SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inPubKey);
-
-/*
- * FUNCTION: CMMF_POPODecKeyChallContentSetNextChallenge
- * INPUTS:
- * inDecKeyChall
- * The CMMFPOPODecKeyChallContent to operate on.
- * inRandom
- * The random number to use when generating the challenge,
- * inSender
- * The GeneralName representation of the sender of the challenge.
- * inPubKey
- * The public key to use when encrypting the challenge.
- * passwdArg
- * This value will be passed to the function used for getting a
- * password. The password for getting a password should be registered
- * by calling PK11_SetPasswordFunc before this function is called.
- * If no password callback is registered and the library needs to
- * authenticate to the slot for any reason, this function will fail.
- * NOTES:
- * This function adds a challenge to the end of the list of challenges
- * contained by 'inDecKeyChall'. Refer to the CMMF draft on how the
- * the random number passed in and the sender's GeneralName are used
- * to generate the challenge and witness fields of the challenge. This
- * library will use SHA1 as the one-way function for generating the
- * witess field of the challenge.
- *
- * RETURN:
- * SECSuccess if generating the challenge and adding to the end of list
- * of challenges was successful. Any other return value indicates an error
- * while trying to generate the challenge.
- */
-extern SECStatus
-CMMF_POPODecKeyChallContentSetNextChallenge
- (CMMFPOPODecKeyChallContent *inDecKeyChall,
- long inRandom,
- CERTGeneralName *inSender,
- SECKEYPublicKey *inPubKey,
- void *passwdArg);
-
-
-/************************** Encoding Functions *************************/
-
-/*
- * FUNCTION: CMMF_EncodeCertRepContent
- * INPUTS:
- * inCertRepContent
- * The CMMFCertRepContent to DER-encode.
- * inCallback
- * A callback function that the ASN1 encoder will call whenever it
- * wants to write out DER-encoded bytes. Look at the defintion of
- * CRMFEncoderOutputCallback in crmft.h for a description of the
- * parameters to the function.
- * inArg
- * An opaque pointer to a user-supplied argument that will be passed
- * to the callback funtion whenever the function is called.
- * NOTES:
- * The CMMF library will use the same DER-encoding scheme as the CRMF
- * library. In other words, when reading CRMF comments that pertain to
- * encoding, those comments apply to the CMMF libray as well.
- * The callback function will be called multiple times, each time supplying
- * the next chunk of DER-encoded bytes. The user must concatenate the
- * output of each successive call to the callback in order to get the
- * entire DER-encoded CMMFCertRepContent structure.
- *
- * RETURN:
- * SECSuccess if encoding the CMMFCertRepContent was successful. Any
- * other return value indicates an error while decoding the structure.
- */
-extern SECStatus
- CMMF_EncodeCertRepContent (CMMFCertRepContent *inCertRepContent,
- CRMFEncoderOutputCallback inCallback,
- void *inArg);
-
-/*
- * FUNCTION: CMMF_EncodeKeyRecRepContent
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRepContent to DER-encode.
- * inCallback
- * A callback function that the ASN1 encoder will call whenever it
- * wants to write out DER-encoded bytes. Look at the defintion of
- * CRMFEncoderOutputCallback in crmft.h for a description of the
- * parameters to the function.
- * inArg
- * An opaque pointer to a user-supplied argument that will be passed
- * to the callback funtion whenever the function is called.
- * NOTES:
- * The CMMF library will use the same DER-encoding scheme as the CRMF
- * library. In other words, when reading CRMF comments that pertain to
- * encoding, those comments apply to the CMMF libray as well.
- * The callback function will be called multiple times, each time supplying
- * the next chunk of DER-encoded bytes. The user must concatenate the
- * output of each successive call to the callback in order to get the
- * entire DER-encoded CMMFCertRepContent structure.
- *
- * RETURN:
- * SECSuccess if encoding the CMMFKeyRecRepContent was successful. Any
- * other return value indicates an error while decoding the structure.
- */
-extern SECStatus
- CMMF_EncodeKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep,
- CRMFEncoderOutputCallback inCallback,
- void *inArg);
-
-/*
- * FUNCTION: CMMF_EncodePOPODecKeyChallContent
- * INPUTS:
- * inDecKeyChall
- * The CMMFDecKeyChallContent to operate on.
- * inCallback
- * A callback function that the ASN1 encoder will call whenever it
- * wants to write out DER-encoded bytes. Look at the defintion of
- * CRMFEncoderOutputCallback in crmft.h for a description of the
- * parameters to the function.
- * inArg
- * An opaque pointer to a user-supplied argument that will be passed
- * to the callback function whenever the function is called.
- * NOTES:
- * The CMMF library will use the same DER-encoding scheme as the CRMF
- * library. In other words, when reading CRMF comments that pertain to
- * encoding, those comments apply to the CMMF libray as well.
- * The callback function will be called multiple times, each time supplying
- * the next chunk of DER-encoded bytes. The user must concatenate the
- * output of each successive call to the callback in order to get the
- * entire DER-encoded CMMFCertRepContent structure.
- * The DER will be an encoding of the type POPODecKeyChallContents, which
- * is just a sequence of challenges.
- *
- * RETURN:
- * SECSuccess if encoding was successful. Any other return value indicates
- * an error in trying to encode the Challenges.
- */
-extern SECStatus
-CMMF_EncodePOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyChall,
- CRMFEncoderOutputCallback inCallback,
- void *inArg);
-
-/*
- * FUNCTION: CMMF_EncodePOPODecKeyRespContent
- * INPUTS:
- * inDecodedRand
- * An array of integers to encode as the responses to
- * CMMFPOPODecKeyChallContent. The integers must be in the same order
- * as the challenges extracted from CMMFPOPODecKeyChallContent.
- * inNumRand
- * The number of random integers contained in the array 'inDecodedRand'
- * inCallback
- * A callback function that the ASN1 encoder will call whenever it
- * wants to write out DER-encoded bytes. Look at the defintion of
- * CRMFEncoderOutputCallback in crmft.h for a description of the
- * parameters to the function.
- * inArg
- * An opaque pointer to a user-supplied argument that will be passed
- * to the callback funtion whenever the function is called.
- * NOTES:
- * The CMMF library will use the same DER-encoding scheme as the CRMF
- * library. In other words, when reading CRMF comments that pertain to
- * encoding, those comments apply to the CMMF libray as well.
- * The callback function will be called multiple times, each time supplying
- * the next chunk of DER-encoded bytes. The user must concatenate the
- * output of each successive call to the callback in order to get the
- * entire DER-encoded POPODecKeyRespContent.
- *
- * RETURN:
- * SECSuccess if encoding was successful. Any other return value indicates
- * an error in trying to encode the Challenges.
- */
-extern SECStatus
- CMMF_EncodePOPODecKeyRespContent(long *inDecodedRand,
- int inNumRand,
- CRMFEncoderOutputCallback inCallback,
- void *inArg);
-
-/*************** Accessor function ***********************************/
-
-/*
- * FUNCTION: CMMF_CertRepContentGetCAPubs
- * INPUTS:
- * inCertRepContent
- * The CMMFCertRepContent to extract the caPubs from.
- * NOTES:
- * This function will return a copy of the list of certificates that
- * make up the chain of CA's required to make the cert issued valid.
- * The user must call CERT_DestroyCertList on the return value when
- * done using the return value.
- *
- * Only call this function on a CertRepContent that has been decoded.
- * The client must call CERT_DestroyCertList when the certificate list
- * is no longer needed.
- *
- * The certs in the list will not be in the temporary database. In order
- * to make these certificates a part of the permanent CA internal database,
- * the user must collect the der for all of these certs and call
- * CERT_ImportCAChain. Afterwards the certs will be part of the permanent
- * database.
- *
- * RETURN:
- * A pointer to the CERTCertList representing the CA chain associated
- * with the issued cert. A NULL return value indicates that no CA Pubs
- * were available in the CMMFCertRepContent structure.
- */
-extern CERTCertList*
- CMMF_CertRepContentGetCAPubs (CMMFCertRepContent *inCertRepContent);
-
-
-/*
- * FUNCTION: CMMF_CertRepContentGetNumResponses
- * INPUTS:
- * inCertRepContent
- * The CMMFCertRepContent to operate on.
- * NOTES:
- * This function will return the number of CertResponses that are contained
- * by the CMMFCertRepContent passed in.
- *
- * RETURN:
- * The number of CMMFCertResponses contained in the structure passed in.
- */
-extern int
- CMMF_CertRepContentGetNumResponses (CMMFCertRepContent *inCertRepContent);
-
-/*
- * FUNCTION: CMMF_CertRepContentGetResponseAtIndex
- * INPUTS:
- * inCertRepContent
- * The CMMFCertRepContent to operate on.
- * inIndex
- * The index of the CMMFCertResponse the user wants a copy of.
- * NOTES:
- * This function creates a copy of the CMMFCertResponse at the index
- * corresponding to the parameter 'inIndex'. Indexing is done like a
- * traditional C array, ie the valid indexes are (0...numResponses-1).
- * The user must call CMMF_DestroyCertResponse after the return value is
- * no longer needed.
- *
- * RETURN:
- * A pointer to the CMMFCertResponse at the index corresponding to
- * 'inIndex'. A return value of NULL indicates an error in copying
- * the CMMFCertResponse.
- */
-extern CMMFCertResponse*
-CMMF_CertRepContentGetResponseAtIndex (CMMFCertRepContent *inCertRepContent,
- int inIndex);
-
-/*
- * FUNCTION: CMMF_CertResponseGetCertReqId
- * INPUTS:
- * inCertResp
- * The CMMFCertResponse to operate on.
- * NOTES:
- * This function returns the CertResponse.certReqId from the
- * CMMFCertResponse structure passed in. If the return value is -1, that
- * means there is no associated certificate request with the CertResponse.
- * RETURN:
- * A long representing the id of the certificate request this
- * CMMFCertResponse corresponds to. A return value of -1 indicates an
- * error in extracting the value of the integer.
- */
-extern long CMMF_CertResponseGetCertReqId(CMMFCertResponse *inCertResp);
-
-/*
- * FUNCTION: CMMF_CertResponseGetPKIStatusInfoStatus
- * INPUTS:
- * inCertResp
- * The CMMFCertResponse to operate on.
- * NOTES:
- * This function returns the CertResponse.status.status field of the
- * CMMFCertResponse structure.
- *
- * RETURN:
- * The enumerated value corresponding to the PKIStatus defined in the CMMF
- * draft. See the CMMF draft for the definition of PKIStatus. See crmft.h
- * for the definition of CMMFPKIStatus.
- */
-extern CMMFPKIStatus
- CMMF_CertResponseGetPKIStatusInfoStatus(CMMFCertResponse *inCertResp);
-
-/*
- * FUNCTION: CMMF_CertResponseGetCertificate
- * INPUTS:
- * inCertResp
- * The Certificate Response to operate on.
- * inCertdb
- * This is the certificate database where the function will place the
- * newly issued certificate.
- * NOTES:
- * This function retrieves the CertResponse.certifiedKeyPair.certificate
- * from the CMMFCertResponse. The user will get a copy of that certificate
- * so the user must call CERT_DestroyCertificate when the return value is
- * no longer needed. The certificate returned will be in the temporary
- * certificate database.
- *
- * RETURN:
- * A pointer to a copy of the certificate contained within the
- * CMMFCertResponse. A return value of NULL indicates an error while trying
- * to make a copy of the certificate.
- */
-extern CERTCertificate*
- CMMF_CertResponseGetCertificate(CMMFCertResponse *inCertResp,
- CERTCertDBHandle *inCertdb);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentGetPKIStatusInfoStatus
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRecRepContent structure to operate on.
- * NOTES:
- * This function retrieves the KeyRecRepContent.status.status field of
- * the CMMFKeyRecRepContent structure.
- * RETURN:
- * The CMMFPKIStatus corresponding to the value held in the
- * CMMFKeyRecRepContent structure.
- */
-extern CMMFPKIStatus
-CMMF_KeyRecRepContentGetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentGetNewSignCert
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRecRepContent to operate on.
- * NOTES:
- * This function retrieves the KeyRecRepContent.newSignCert field of the
- * CMMFKeyRecRepContent structure. The user must call
- * CERT_DestroyCertificate when the return value is no longer needed. The
- * returned certificate will be in the temporary database. The user
- * must then place the certificate permanently in whatever token the
- * user determines is the proper destination. A return value of NULL
- * indicates the newSigCert field was not present.
- */
-extern CERTCertificate*
- CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentGetCACerts
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRecRepContent to operate on.
- * NOTES:
- * This function returns a CERTCertList which contains all of the
- * certficates that are in the sequence KeyRecRepContent.caCerts
- * User must call CERT_DestroyCertList when the return value is no longer
- * needed. All of these certificates will be placed in the tempoaray
- * database.
- *
- * RETURN:
- * A pointer to the list of caCerts contained in the CMMFKeyRecRepContent
- * structure. A return value of NULL indicates the library was not able to
- * make a copy of the certifcates. This may be because there are no caCerts
- * included in the CMMFKeyRecRepContent strucure or an internal error. Call
- * CMMF_KeyRecRepContentHasCACerts to find out if there are any caCerts
- * included in 'inKeyRecRep'.
- */
-extern CERTCertList*
- CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentGetNumKeyPairs
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRecRepContent to operate on.
- * RETURN:
- * This function returns the number of CMMFCertifiedKeyPair structures that
- * that are stored in the KeyRecRepContent structure.
- */
-extern int
- CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentGetCertKeyAtIndex
- * INPUTS:
- * inKeyRecRepContent
- * The CMMFKeyRecRepContent to operate on.
- * inIndex
- * The index of the desired CMMFCertifiedKeyPair
- * NOTES:
- * This function retrieves the CMMFCertifiedKeyPair structure at the index
- * 'inIndex'. Valid indexes are 0...(numKeyPairs-1) The user must call
- * CMMF_DestroyCertifiedKeyPair when the return value is no longer needed.
- *
- * RETURN:
- * A pointer to the Certified Key Pair at the desired index. A return value
- * of NULL indicates an error in extracting the Certified Key Pair at the
- * desired index.
- */
-extern CMMFCertifiedKeyPair*
- CMMF_KeyRecRepContentGetCertKeyAtIndex(CMMFKeyRecRepContent *inKeyRecRep,
- int inIndex);
-
-/*
- * FUNCTION: CMMF_CertifiedKeyPairGetCertificate
- * INPUTS:
- * inCertKeyPair
- * The CMMFCertifiedKeyPair to operate on.
- * inCertdb
- * The database handle for the database you want this certificate
- * to wind up in.
- * NOTES:
- * This function retrieves the certificate at
- * CertifiedKeyPair.certOrEncCert.certificate
- * The user must call CERT_DestroyCertificate when the return value is no
- * longer needed. The user must import this certificate as a token object
- * onto PKCS#11 slot in order to make it a permanent object. The returned
- * certificate will be in the temporary database.
- *
- * RETURN:
- * A pointer to the certificate contained within the certified key pair.
- * A return value of NULL indicates an error in creating the copy of the
- * certificate.
- */
-extern CERTCertificate*
- CMMF_CertifiedKeyPairGetCertificate(CMMFCertifiedKeyPair *inCertKeyPair,
- CERTCertDBHandle *inCertdb);
-
-/*
- * FUNCTION: CMMF_POPODecKeyChallContentGetNumChallenges
- * INPUTS:
- * inKeyChallCont
- * The CMMFPOPODecKeyChallContent to operate on.
- * RETURN:
- * This function returns the number of CMMFChallenges are contained in
- * the CMMFPOPODecKeyChallContent structure.
- */
-extern int CMMF_POPODecKeyChallContentGetNumChallenges
- (CMMFPOPODecKeyChallContent *inKeyChallCont);
-
-/*
- * FUNCTION: CMMF_POPODecKeyChallContentGetPublicValue
- * ---------------------------------------------------
- * INPUTS:
- * inKeyChallCont
- * The CMMFPOPODecKeyChallContent to operate on.
- * inIndex
- * The index of the Challenge within inKeyChallCont to operate on.
- * Indexes start from 0, ie the Nth Challenge corresponds to index
- * N-1.
- * NOTES:
- * This function retrieves the public value stored away in the Challenge at
- * index inIndex of inKeyChallCont.
- * RETURN:
- * A pointer to a SECItem containing the public value. User must call
- * SECITEM_FreeItem on the return value when the value is no longer necessary.
- * A return value of NULL indicates an error while retrieving the public value.
- */
-extern SECItem* CMMF_POPODecKeyChallContentGetPublicValue
- (CMMFPOPODecKeyChallContent *inKeyChallCont,
- int inIndex);
-
-
-/*
- * FUNCTION: CMMF_POPODecKeyChallContentGetRandomNumber
- * INPUTS:
- * inChallContent
- * The CMMFPOPODecKeyChallContent to operate on.
- * inIndex
- * The index of the challenge to look at. Valid indexes are 0 through
- * (CMMF_POPODecKeyChallContentGetNumChallenges(inChallContent) - 1).
- * inDest
- * A pointer to a user supplied buffer where the library
- * can place a copy of the random integer contatained in the
- * challenge.
- * NOTES:
- * This function returns the value held in the decrypted Rand structure
- * corresponding to the random integer. The user must call
- * CMMF_POPODecKeyChallContentDecryptChallenge before calling this function. Call
- * CMMF_ChallengeIsDecrypted to find out if the challenge has been
- * decrypted.
- *
- * RETURN:
- * SECSuccess indicates the witness field has been previously decrypted
- * and the value for the random integer was successfully placed at *inDest.
- * Any other return value indicates an error and that the value at *inDest
- * is not a valid value.
- */
-extern SECStatus CMMF_POPODecKeyChallContentGetRandomNumber
- (CMMFPOPODecKeyChallContent *inKeyChallCont,
- int inIndex,
- long *inDest);
-
-/*
- * FUNCTION: CMMF_POPODecKeyRespContentGetNumResponses
- * INPUTS:
- * inRespCont
- * The POPODecKeyRespContent to operate on.
- * RETURN:
- * This function returns the number of responses contained in inRespContent.
- */
-extern int
- CMMF_POPODecKeyRespContentGetNumResponses(CMMFPOPODecKeyRespContent *inRespCont);
-
-/*
- * FUNCTION: CMMF_POPODecKeyRespContentGetResponse
- * INPUTS:
- * inRespCont
- * The POPODecKeyRespContent to operate on.
- * inIndex
- * The index of the response to retrieve.
- * The Nth response is at index N-1, ie the 1st response is at index 0,
- * the 2nd response is at index 1, and so on.
- * inDest
- * A pointer to a pre-allocated buffer where the library can put the
- * value of the response located at inIndex.
- * NOTES:
- * The function returns the response contained at index inIndex.
- * CMMFPOPODecKeyRespContent is a structure that the server will generally
- * get in response to a CMMFPOPODecKeyChallContent. The server will expect
- * to see the responses in the same order as it constructed them in
- * the CMMFPOPODecKeyChallContent structure.
- * RETURN:
- * SECSuccess if getting the response at the desired index was successful. Any
- * other return value indicates an errror.
- */
-extern SECStatus
- CMMF_POPODecKeyRespContentGetResponse (CMMFPOPODecKeyRespContent *inRespCont,
- int inIndex,
- long *inDest);
-
-/************************* Destructor Functions ******************************/
-
-/*
- * FUNCTION: CMMF_DestroyCertResponse
- * INPUTS:
- * inCertResp
- * The CMMFCertResponse to destroy.
- * NOTES:
- * This function frees all the memory associated with the CMMFCertResponse
- * passed in.
- * RETURN:
- * SECSuccess if freeing the memory was successful. Any other return value
- * indicates an error while freeing the memory.
- */
-extern SECStatus CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp);
-
-/*
- * FUNCTION: CMMF_DestroyCertRepContent
- * INPUTS:
- * inCertRepContent
- * The CMMFCertRepContent to destroy
- * NOTES:
- * This function frees the memory associated with the CMMFCertRepContent
- * passed in.
- * RETURN:
- * SECSuccess if freeing all the memory associated with the
- * CMMFCertRepContent passed in is successful. Any other return value
- * indicates an error while freeing the memory.
- */
-extern SECStatus
- CMMF_DestroyCertRepContent (CMMFCertRepContent *inCertRepContent);
-
-/*
- * FUNCTION: CMMF_DestroyKeyRecRepContent
- * INPUTS:
- * inKeyRecRep
- * The CMMFKeyRecRepContent to destroy.
- * NOTES:
- * This function destroys all the memory associated with the
- * CMMFKeyRecRepContent passed in.
- *
- * RETURN:
- * SECSuccess if freeing all the memory is successful. Any other return
- * value indicates an error in freeing the memory.
- */
-extern SECStatus
- CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep);
-
-/*
- * FUNCTION: CMMF_DestroyCertifiedKeyPair
- * INPUTS:
- * inCertKeyPair
- * The CMMFCertifiedKeyPair to operate on.
- * NOTES:
- * This function frees up all the memory associated with 'inCertKeyPair'
- *
- * RETURN:
- * SECSuccess if freeing all the memory associated with 'inCertKeyPair'
- * is successful. Any other return value indicates an error while trying
- * to free the memory.
- */
-extern SECStatus
- CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair);
-
-/*
- * FUNCTION: CMMF_DestroyPOPODecKeyRespContent
- * INPUTS:
- * inDecKeyResp
- * The CMMFPOPODecKeyRespContent structure to free.
- * NOTES:
- * This function frees up all the memory associate with the
- * CMMFPOPODecKeyRespContent.
- *
- * RETURN:
- * SECSuccess if freeing up all the memory associated with the
- * CMMFPOPODecKeyRespContent structure is successful. Any other
- * return value indicates an error while freeing the memory.
- */
-extern SECStatus
- CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp);
-
-
-/************************** Miscellaneous Functions *************************/
-
-/*
- * FUNCTION: CMMF_CertifiedKeyPairUnwrapPrivKey
- * INPUTS:
- * inCertKeyPair
- * The CMMFCertifiedKeyPair to operate on.
- * inPrivKey
- * The private key to use to un-wrap the private key
- * inNickName
- * This is the nickname that will be associated with the private key
- * to be unwrapped.
- * inSlot
- * The PKCS11 slot where the unwrapped private key should end up.
- * inCertdb
- * The Certificate database with which the new key will be associated.
- * destPrivKey
- * A pointer to memory where the library can place a pointer to the
- * private key after importing the key onto the specified slot.
- * wincx
- * An opaque pointer that the library will use in a callback function
- * to get the password if necessary.
- *
- * NOTES:
- * This function uses the private key passed in to unwrap the private key
- * contained within the CMMFCertifiedKeyPair structure. After this
- * function successfully returns, the private key has been unwrapped and
- * placed in the specified slot.
- *
- * RETURN:
- * SECSuccess if unwrapping the private key was successful. Any other
- * return value indicates an error while trying to un-wrap the private key.
- */
-extern SECStatus
- CMMF_CertifiedKeyPairUnwrapPrivKey(CMMFCertifiedKeyPair *inKeyPair,
- SECKEYPrivateKey *inPrivKey,
- SECItem *inNickName,
- PK11SlotInfo *inSlot,
- CERTCertDBHandle *inCertdb,
- SECKEYPrivateKey **destPrivKey,
- void *wincx);
-
-/*
- * FUNCTION: CMMF_KeyRecRepContentHasCACerts
- * INPUTS:
- * inKeyRecRecp
- * The CMMFKeyRecRepContent to operate on.
- * RETURN:
- * This function returns PR_TRUE if there are one or more certificates in
- * the sequence KeyRecRepContent.caCerts within the CMMFKeyRecRepContent
- * structure. The function will return PR_FALSE if there are 0 certificate
- * in the above mentioned sequence.
- */
-extern PRBool
- CMMF_KeyRecRepContentHasCACerts(CMMFKeyRecRepContent *inKeyRecRep);
-
-/*
- * FUNCTION: CMMF_POPODecKeyChallContDecryptChallenge
- * INPUTS:
- * inChalCont
- * The CMMFPOPODecKeyChallContent to operate on.
- * inIndex
- * The index of the Challenge to operate on. The 1st Challenge is
- * at index 0, the second at index 1 and so forth.
- * inPrivKey
- * The private key to use to decrypt the witness field.
- * NOTES:
- * This function uses the private key to decrypt the challenge field
- * contained in the appropriate challenge. Make sure the private key matches
- * the public key that was used to encrypt the witness. Use
- * CMMF_POPODecKeyChallContentGetPublicValue to get the public value of
- * the key used to encrypt the witness and then use that to determine the
- * appropriate private key. This can be done by calling PK11_MakeIDFromPubKey
- * and then passing that return value to PK11_FindKeyByKeyID. The creator of
- * the challenge will most likely be an RA that has the public key
- * from a Cert request. So the private key should be the private key
- * associated with public key in that request. This function will also
- * verify the witness field of the challenge. This function also verifies
- * that the sender and witness hashes match within the challenge.
- *
- * RETURN:
- * SECSuccess if decrypting the witness field was successful. This does
- * not indicate that the decrypted data is valid, since the private key
- * passed in may not be the actual key needed to properly decrypt the
- * witness field. Meaning that there is a decrypted structure now, but
- * may be garbage because the private key was incorrect.
- * Any other return value indicates the function could not complete the
- * decryption process.
- */
-extern SECStatus
- CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont,
- int inIndex,
- SECKEYPrivateKey *inPrivKey);
-
-/*
- * FUNCTION: CMMF_DestroyPOPODecKeyChallContent
- * INPUTS:
- * inDecKeyCont
- * The CMMFPOPODecKeyChallContent to free
- * NOTES:
- * This function frees up all the memory associated with the
- * CMMFPOPODecKeyChallContent
- * RETURN:
- * SECSuccess if freeing up all the memory associatd with the
- * CMMFPOPODecKeyChallContent is successful. Any other return value
- * indicates an error while freeing the memory.
- *
- */
-extern SECStatus
- CMMF_DestroyPOPODecKeyChallContent (CMMFPOPODecKeyChallContent *inDecKeyCont);
-
-SEC_END_PROTOS
-#endif /* _CMMF_H_ */
diff --git a/security/nss/lib/crmf/cmmfasn1.c b/security/nss/lib/crmf/cmmfasn1.c
deleted file mode 100644
index e1890799c..000000000
--- a/security/nss/lib/crmf/cmmfasn1.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "cmmf.h"
-#include "cmmfi.h"
-#include "secasn1.h"
-#include "secitem.h"
-
-SEC_ASN1_MKSUB(SEC_SignedCertificateTemplate)
-
-static const SEC_ASN1Template CMMFSequenceOfCertifiedKeyPairsTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, CMMFCertifiedKeyPairTemplate}
-};
-
-static const SEC_ASN1Template CMMFKeyRecRepContentTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CMMFKeyRecRepContent)},
- { SEC_ASN1_INLINE, offsetof(CMMFKeyRecRepContent, status),
- CMMFPKIStatusInfoTemplate},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER |
- SEC_ASN1_XTRN | 0,
- offsetof(CMMFKeyRecRepContent, newSigCert),
- SEC_ASN1_SUB(SEC_SignedCertificateTemplate)},
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(CMMFKeyRecRepContent, caCerts),
- CMMFSequenceOfCertsTemplate},
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 2,
- offsetof(CMMFKeyRecRepContent, keyPairHist),
- CMMFSequenceOfCertifiedKeyPairsTemplate},
- { 0 }
-};
-
-SECStatus
-CMMF_EncodeCertRepContent (CMMFCertRepContent *inCertRepContent,
- CRMFEncoderOutputCallback inCallback,
- void *inArg)
-{
- return cmmf_user_encode(inCertRepContent, inCallback, inArg,
- CMMFCertRepContentTemplate);
-}
-
-SECStatus
-CMMF_EncodePOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyChall,
- CRMFEncoderOutputCallback inCallback,
- void *inArg)
-{
- return cmmf_user_encode(inDecKeyChall, inCallback, inArg,
- CMMFPOPODecKeyChallContentTemplate);
-}
-
-CMMFPOPODecKeyRespContent*
-CMMF_CreatePOPODecKeyRespContentFromDER(const char *buf, long len)
-{
- PRArenaPool *poolp;
- CMMFPOPODecKeyRespContent *decKeyResp;
- SECStatus rv;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return NULL;
- }
- decKeyResp = PORT_ArenaZNew(poolp, CMMFPOPODecKeyRespContent);
- if (decKeyResp == NULL) {
- goto loser;
- }
- decKeyResp->poolp = poolp;
- rv = SEC_ASN1Decode(poolp, decKeyResp, CMMFPOPODecKeyRespContentTemplate,
- buf, len);
- if (rv != SECSuccess) {
- goto loser;
- }
- return decKeyResp;
-
- loser:
- if (poolp != NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return NULL;
-}
-
-SECStatus
-CMMF_EncodeKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep,
- CRMFEncoderOutputCallback inCallback,
- void *inArg)
-{
- return cmmf_user_encode(inKeyRecRep, inCallback, inArg,
- CMMFKeyRecRepContentTemplate);
-}
-
-CMMFKeyRecRepContent*
-CMMF_CreateKeyRecRepContentFromDER(CERTCertDBHandle *db, const char *buf,
- long len)
-{
- PRArenaPool *poolp;
- CMMFKeyRecRepContent *keyRecContent;
- SECStatus rv;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return NULL;
- }
- keyRecContent = PORT_ArenaZNew(poolp, CMMFKeyRecRepContent);
- if (keyRecContent == NULL) {
- goto loser;
- }
- keyRecContent->poolp = poolp;
- rv = SEC_ASN1Decode(poolp, keyRecContent, CMMFKeyRecRepContentTemplate,
- buf, len);
- if (rv != SECSuccess) {
- goto loser;
- }
- if (keyRecContent->keyPairHist != NULL) {
- while(keyRecContent->keyPairHist[keyRecContent->numKeyPairs] != NULL) {
- rv = cmmf_decode_process_certified_key_pair(poolp, db,
- keyRecContent->keyPairHist[keyRecContent->numKeyPairs]);
- if (rv != SECSuccess) {
- goto loser;
- }
- keyRecContent->numKeyPairs++;
- }
- keyRecContent->allocKeyPairs = keyRecContent->numKeyPairs;
- }
- keyRecContent->isDecoded = PR_TRUE;
- return keyRecContent;
- loser:
- if (poolp != NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return NULL;
-}
-
diff --git a/security/nss/lib/crmf/cmmfchal.c b/security/nss/lib/crmf/cmmfchal.c
deleted file mode 100644
index 4e75ea51f..000000000
--- a/security/nss/lib/crmf/cmmfchal.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "cmmf.h"
-#include "cmmfi.h"
-#include "sechash.h"
-#include "genname.h"
-#include "pk11func.h"
-#include "cert.h"
-#include "secitem.h"
-#include "secmod.h"
-#include "keyhi.h"
-
-static int
-cmmf_create_witness_and_challenge(PRArenaPool *poolp,
- CMMFChallenge *challenge,
- long inRandom,
- SECItem *senderDER,
- SECKEYPublicKey *inPubKey,
- void *passwdArg)
-{
- SECItem *encodedRandNum;
- SECItem encodedRandStr = {siBuffer, NULL, 0};
- SECItem *dummy;
- unsigned char *randHash, *senderHash, *encChal=NULL;
- unsigned modulusLen = 0;
- SECStatus rv = SECFailure;
- CMMFRand randStr= { {siBuffer, NULL, 0}, {siBuffer, NULL, 0}};
- PK11SlotInfo *slot;
- PK11SymKey *symKey = NULL;
- CK_OBJECT_HANDLE id;
- CERTSubjectPublicKeyInfo *spki = NULL;
-
-
- encodedRandNum = SEC_ASN1EncodeInteger(poolp, &challenge->randomNumber,
- inRandom);
- encodedRandNum = &challenge->randomNumber;
- randHash = PORT_ArenaNewArray(poolp, unsigned char, SHA1_LENGTH);
- senderHash = PORT_ArenaNewArray(poolp, unsigned char, SHA1_LENGTH);
- if (randHash == NULL) {
- goto loser;
- }
- rv = PK11_HashBuf(SEC_OID_SHA1, randHash, encodedRandNum->data,
- (PRUint32)encodedRandNum->len);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = PK11_HashBuf(SEC_OID_SHA1, senderHash, senderDER->data,
- (PRUint32)senderDER->len);
- if (rv != SECSuccess) {
- goto loser;
- }
- challenge->witness.data = randHash;
- challenge->witness.len = SHA1_LENGTH;
-
- randStr.integer = *encodedRandNum;
- randStr.senderHash.data = senderHash;
- randStr.senderHash.len = SHA1_LENGTH;
- dummy = SEC_ASN1EncodeItem(NULL, &encodedRandStr, &randStr,
- CMMFRandTemplate);
- if (dummy != &encodedRandStr) {
- rv = SECFailure;
- goto loser;
- }
- /* XXXX Now I have to encrypt encodedRandStr and stash it away. */
- modulusLen = SECKEY_PublicKeyStrength(inPubKey);
- encChal = PORT_ArenaNewArray(poolp, unsigned char, modulusLen);
- if (encChal == NULL) {
- rv = SECFailure;
- goto loser;
- }
- slot =PK11_GetBestSlotWithAttributes(CKM_RSA_PKCS, CKF_WRAP, 0, passwdArg);
- if (slot == NULL) {
- rv = SECFailure;
- goto loser;
- }
- id = PK11_ImportPublicKey(slot, inPubKey, PR_FALSE);
- /* In order to properly encrypt the data, we import as a symmetric
- * key, and then wrap that key. That in essence encrypts the data.
- * This is the method recommended in the PK11 world in order
- * to prevent threading issues as well as breaking any other semantics
- * the PK11 libraries depend on.
- */
- symKey = PK11_ImportSymKey(slot, CKM_RSA_PKCS, PK11_OriginGenerated,
- CKA_VALUE, &encodedRandStr, passwdArg);
- if (symKey == NULL) {
- rv = SECFailure;
- goto loser;
- }
- challenge->challenge.data = encChal;
- challenge->challenge.len = modulusLen;
- rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, inPubKey, symKey,
- &challenge->challenge);
- PK11_FreeSlot(slot);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECITEM_CopyItem(poolp, &challenge->senderDER, senderDER);
- crmf_get_public_value(inPubKey, &challenge->key);
- /* Fall through */
- loser:
- if (spki != NULL) {
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- }
- if (encodedRandStr.data != NULL) {
- PORT_Free(encodedRandStr.data);
- }
- if (encodedRandNum != NULL) {
- SECITEM_FreeItem(encodedRandNum, PR_TRUE);
- }
- if (symKey != NULL) {
- PK11_FreeSymKey(symKey);
- }
- return rv;
-}
-
-static SECStatus
-cmmf_create_first_challenge(CMMFPOPODecKeyChallContent *challContent,
- long inRandom,
- SECItem *senderDER,
- SECKEYPublicKey *inPubKey,
- void *passwdArg)
-{
- SECOidData *oidData;
- CMMFChallenge *challenge;
- SECAlgorithmID *algId;
- PRArenaPool *poolp;
- SECStatus rv;
-
- oidData = SECOID_FindOIDByTag(SEC_OID_SHA1);
- if (oidData == NULL) {
- return SECFailure;
- }
- poolp = challContent->poolp;
- challenge = PORT_ArenaZNew(poolp, CMMFChallenge);
- if (challenge == NULL) {
- return SECFailure;
- }
- algId = challenge->owf = PORT_ArenaZNew(poolp, SECAlgorithmID);
- if (algId == NULL) {
- return SECFailure;
- }
- rv = SECITEM_CopyItem(poolp, &algId->algorithm, &oidData->oid);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- rv = cmmf_create_witness_and_challenge(poolp, challenge, inRandom,
- senderDER, inPubKey, passwdArg);
- challContent->challenges[0] = (rv == SECSuccess) ? challenge : NULL;
- challContent->numChallenges++;
- return rv ;
-}
-
-CMMFPOPODecKeyChallContent*
-CMMF_CreatePOPODecKeyChallContent (void)
-{
- PRArenaPool *poolp;
- CMMFPOPODecKeyChallContent *challContent;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return NULL;
- }
- challContent = PORT_ArenaZNew(poolp, CMMFPOPODecKeyChallContent);
- if (challContent == NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
- challContent->poolp = poolp;
- return challContent;
-}
-
-SECStatus
-CMMF_POPODecKeyChallContentSetNextChallenge
- (CMMFPOPODecKeyChallContent *inDecKeyChall,
- long inRandom,
- CERTGeneralName *inSender,
- SECKEYPublicKey *inPubKey,
- void *passwdArg)
-{
- CMMFChallenge *curChallenge;
- PRArenaPool *genNamePool = NULL, *poolp;
- SECStatus rv;
- SECItem *genNameDER;
- void *mark;
-
- PORT_Assert (inDecKeyChall != NULL &&
- inSender != NULL &&
- inPubKey != NULL);
-
- if (inDecKeyChall == NULL ||
- inSender == NULL || inPubKey == NULL) {
- return SECFailure;
- }
- poolp = inDecKeyChall->poolp;
- mark = PORT_ArenaMark(poolp);
-
- genNamePool = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- genNameDER = CERT_EncodeGeneralName(inSender, NULL, genNamePool);
- if (genNameDER == NULL) {
- rv = SECFailure;
- goto loser;
- }
- if (inDecKeyChall->challenges == NULL) {
- inDecKeyChall->challenges =
- PORT_ArenaZNewArray(poolp, CMMFChallenge*,(CMMF_MAX_CHALLENGES+1));
- inDecKeyChall->numAllocated = CMMF_MAX_CHALLENGES;
- }
-
- if (inDecKeyChall->numChallenges >= inDecKeyChall->numAllocated) {
- rv = SECFailure;
- goto loser;
- }
-
- if (inDecKeyChall->numChallenges == 0) {
- rv = cmmf_create_first_challenge(inDecKeyChall, inRandom,
- genNameDER, inPubKey, passwdArg);
- } else {
- curChallenge = PORT_ArenaZNew(poolp, CMMFChallenge);
- if (curChallenge == NULL) {
- rv = SECFailure;
- goto loser;
- }
- rv = cmmf_create_witness_and_challenge(poolp, curChallenge, inRandom,
- genNameDER, inPubKey,
- passwdArg);
- if (rv == SECSuccess) {
- inDecKeyChall->challenges[inDecKeyChall->numChallenges] =
- curChallenge;
- inDecKeyChall->numChallenges++;
- }
- }
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_ArenaUnmark(poolp, mark);
- PORT_FreeArena(genNamePool, PR_FALSE);
- return SECSuccess;
-
- loser:
- PORT_ArenaRelease(poolp, mark);
- if (genNamePool != NULL) {
- PORT_FreeArena(genNamePool, PR_FALSE);
- }
- PORT_Assert(rv != SECSuccess);
- return rv;
-}
-
-SECStatus
-CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp)
-{
- PORT_Assert(inDecKeyResp != NULL);
- if (inDecKeyResp != NULL && inDecKeyResp->poolp != NULL) {
- PORT_FreeArena(inDecKeyResp->poolp, PR_FALSE);
- }
- return SECSuccess;
-}
-
-int
-CMMF_POPODecKeyRespContentGetNumResponses(CMMFPOPODecKeyRespContent *inRespCont)
-{
- int numResponses = 0;
-
- PORT_Assert(inRespCont != NULL);
- if (inRespCont == NULL) {
- return 0;
- }
-
- while (inRespCont->responses[numResponses] != NULL) {
- numResponses ++;
- }
- return numResponses;
-}
-
-SECStatus
-CMMF_POPODecKeyRespContentGetResponse (CMMFPOPODecKeyRespContent *inRespCont,
- int inIndex,
- long *inDest)
-{
- PORT_Assert(inRespCont != NULL);
-
- if (inRespCont == NULL || inIndex < 0 ||
- inIndex >= CMMF_POPODecKeyRespContentGetNumResponses(inRespCont)) {
- return SECFailure;
- }
- *inDest = DER_GetInteger(inRespCont->responses[inIndex]);
- return (*inDest == -1) ? SECFailure : SECSuccess;
-}
diff --git a/security/nss/lib/crmf/cmmfi.h b/security/nss/lib/crmf/cmmfi.h
deleted file mode 100644
index 90fb55663..000000000
--- a/security/nss/lib/crmf/cmmfi.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * These are the definitions needed by the library internally to implement
- * CMMF. Most of these will be helper utilities for manipulating internal
- * data strucures.
- */
-#ifndef _CMMFI_H_
-#define _CMMFI_H_
-#include "cmmfit.h"
-#include "crmfi.h"
-
-#define CMMF_MAX_CHALLENGES 10
-#define CMMF_MAX_KEY_PAIRS 50
-
-/*
- * Some templates that the code will need to implement CMMF.
- */
-extern const SEC_ASN1Template CMMFCertOrEncCertCertificateTemplate[];
-extern const SEC_ASN1Template CMMFCertOrEncCertEncryptedCertTemplate[];
-extern const SEC_ASN1Template CMMFPOPODecKeyRespContentTemplate[];
-extern const SEC_ASN1Template CMMFRandTemplate[];
-extern const SEC_ASN1Template CMMFSequenceOfCertsTemplate[];
-extern const SEC_ASN1Template CMMFPKIStatusInfoTemplate[];
-extern const SEC_ASN1Template CMMFCertifiedKeyPairTemplate[];
-
-
-/*
- * Some utility functions that are shared by multiple files in this
- * implementation.
- */
-
-extern SECStatus cmmf_CopyCertResponse (PRArenaPool *poolp,
- CMMFCertResponse *dest,
- CMMFCertResponse *src);
-
-extern SECStatus cmmf_CopyPKIStatusInfo (PRArenaPool *poolp,
- CMMFPKIStatusInfo *dest,
- CMMFPKIStatusInfo *src);
-
-extern SECStatus cmmf_CopyCertifiedKeyPair(PRArenaPool *poolp,
- CMMFCertifiedKeyPair *dest,
- CMMFCertifiedKeyPair *src);
-
-extern SECStatus cmmf_DestroyPKIStatusInfo(CMMFPKIStatusInfo *info,
- PRBool freeit);
-
-extern SECStatus cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert,
- PRBool freeit);
-
-extern SECStatus cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo,
- PRArenaPool *poolp,
- CMMFPKIStatus inStatus);
-
-extern SECStatus cmmf_ExtractCertsFromList(CERTCertList *inCertList,
- PRArenaPool *poolp,
- CERTCertificate ***certArray);
-
-extern SECStatus
- cmmf_CertOrEncCertSetCertificate(CMMFCertOrEncCert *certOrEncCert,
- PRArenaPool *poolp,
- CERTCertificate *inCert);
-
-extern CMMFPKIStatus
- cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus);
-
-extern CERTCertList*
- cmmf_MakeCertList(CERTCertificate **inCerts);
-
-extern CERTCertificate*
-cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert,
- CERTCertDBHandle *certdb);
-
-extern SECStatus
-cmmf_decode_process_cert_response(PRArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertResponse *inCertResp);
-
-extern SECStatus
-cmmf_decode_process_certified_key_pair(PRArenaPool *poolp,
- CERTCertDBHandle *db,
- CMMFCertifiedKeyPair *inCertKeyPair);
-
-extern SECStatus
-cmmf_user_encode(void *src, CRMFEncoderOutputCallback inCallback, void *inArg,
- const SEC_ASN1Template *inTemplate);
-
-extern SECStatus
-cmmf_copy_secitem (PRArenaPool *poolp, SECItem *dest, SECItem *src);
-#endif /*_CMMFI_H_*/
-
-
-
-
-
diff --git a/security/nss/lib/crmf/cmmfit.h b/security/nss/lib/crmf/cmmfit.h
deleted file mode 100644
index 8a166764e..000000000
--- a/security/nss/lib/crmf/cmmfit.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _CMMFIT_H_
-#define _CMMFIT_H_
-
-/*
- * All fields marked by a PKIStausInfo in comments is an integer
- * with the following possible values.
- *
- * Integer Value Meaning
- * ------------- -------
- * 0 granted- got exactly what you asked for.
- *
- * 1 grantedWithMods-got something like what you asked
- * for;requester is responsible for ascertainging the
- * differences.
- *
- * 2 rejection-you don't get what you asked for; more
- * information elsewhere in the message
- *
- * 3 waiting-the request body part has not yet been
- * processed, expect to hear more later.
- *
- * 4 revocationWarning-this message contains a warning
- * that a revocation is imminent.
- *
- * 5 revocationNotification-notification that a
- * revocation has occurred.
- *
- * 6 keyUpdateWarning-update already done for the
- * oldCertId specified in FullCertTemplate.
- */
-
-struct CMMFPKIStatusInfoStr {
- SECItem status;
- SECItem statusString;
- SECItem failInfo;
-};
-
-struct CMMFCertOrEncCertStr {
- union {
- CERTCertificate *certificate;
- CRMFEncryptedValue *encryptedCert;
- } cert;
- CMMFCertOrEncCertChoice choice;
- SECItem derValue;
-};
-
-struct CMMFCertifiedKeyPairStr {
- CMMFCertOrEncCert certOrEncCert;
- CRMFEncryptedValue *privateKey;
- SECItem derPublicationInfo; /* We aren't creating
- * PKIPublicationInfo's, so
- * we'll store away the der
- * here if we decode one that
- * does have pubInfo.
- */
- SECItem unwrappedPrivKey;
-};
-
-struct CMMFCertResponseStr {
- SECItem certReqId;
- CMMFPKIStatusInfo status; /*PKIStatusInfo*/
- CMMFCertifiedKeyPair *certifiedKeyPair;
-};
-
-struct CMMFCertRepContentStr {
- CERTCertificate **caPubs;
- CMMFCertResponse **response;
- PRArenaPool *poolp;
- PRBool isDecoded;
-};
-
-struct CMMFChallengeStr {
- SECAlgorithmID *owf;
- SECItem witness;
- SECItem senderDER;
- SECItem key;
- SECItem challenge;
- SECItem randomNumber;
-};
-
-struct CMMFRandStr {
- SECItem integer;
- SECItem senderHash;
- CERTGeneralName *sender;
-};
-
-struct CMMFPOPODecKeyChallContentStr {
- CMMFChallenge **challenges;
- PRArenaPool *poolp;
- int numChallenges;
- int numAllocated;
-};
-
-struct CMMFPOPODecKeyRespContentStr {
- SECItem **responses;
- PRArenaPool *poolp;
-};
-
-struct CMMFKeyRecRepContentStr {
- CMMFPKIStatusInfo status; /* PKIStatusInfo */
- CERTCertificate *newSigCert;
- CERTCertificate **caCerts;
- CMMFCertifiedKeyPair **keyPairHist;
- PRArenaPool *poolp;
- int numKeyPairs;
- int allocKeyPairs;
- PRBool isDecoded;
-};
-
-#endif /* _CMMFIT_H_ */
-
diff --git a/security/nss/lib/crmf/cmmfrec.c b/security/nss/lib/crmf/cmmfrec.c
deleted file mode 100644
index fab289b8e..000000000
--- a/security/nss/lib/crmf/cmmfrec.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * This file will implement the functions related to key recovery in
- * CMMF
- */
-
-#include "cmmf.h"
-#include "cmmfi.h"
-#include "secitem.h"
-#include "keyhi.h"
-
-CMMFKeyRecRepContent*
-CMMF_CreateKeyRecRepContent(void)
-{
- PRArenaPool *poolp;
- CMMFKeyRecRepContent *keyRecContent;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return NULL;
- }
- keyRecContent = PORT_ArenaZNew(poolp, CMMFKeyRecRepContent);
- if (keyRecContent == NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
- keyRecContent->poolp = poolp;
- return keyRecContent;
-}
-
-SECStatus
-CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep)
-{
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep != NULL && inKeyRecRep->poolp != NULL) {
- int i;
-
- if (!inKeyRecRep->isDecoded && inKeyRecRep->newSigCert != NULL) {
- CERT_DestroyCertificate(inKeyRecRep->newSigCert);
- }
- if (inKeyRecRep->caCerts != NULL) {
- for (i=0; inKeyRecRep->caCerts[i] != NULL; i++) {
- CERT_DestroyCertificate(inKeyRecRep->caCerts[i]);
- }
- }
- if (inKeyRecRep->keyPairHist != NULL) {
- for (i=0; inKeyRecRep->keyPairHist[i] != NULL; i++) {
- if (inKeyRecRep->keyPairHist[i]->certOrEncCert.choice ==
- cmmfCertificate) {
- CERT_DestroyCertificate(inKeyRecRep->keyPairHist[i]->
- certOrEncCert.cert.certificate);
- }
- }
- }
- PORT_FreeArena(inKeyRecRep->poolp, PR_TRUE);
- }
- return SECSuccess;
-}
-
-SECStatus
-CMMF_KeyRecRepContentSetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep,
- CMMFPKIStatus inPKIStatus)
-{
- PORT_Assert(inKeyRecRep != NULL && inPKIStatus >= cmmfGranted &&
- inPKIStatus < cmmfNumPKIStatus);
- if (inKeyRecRep == NULL) {
- return SECFailure;
- }
-
- return cmmf_PKIStatusInfoSetStatus(&inKeyRecRep->status,
- inKeyRecRep->poolp,
- inPKIStatus);
-}
-
-SECStatus
-CMMF_KeyRecRepContentSetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertificate *inNewSignCert)
-{
- PORT_Assert (inKeyRecRep != NULL && inNewSignCert != NULL);
- if (inKeyRecRep == NULL || inNewSignCert == NULL) {
- return SECFailure;
- }
- if (!inKeyRecRep->isDecoded && inKeyRecRep->newSigCert) {
- CERT_DestroyCertificate(inKeyRecRep->newSigCert);
- }
- inKeyRecRep->isDecoded = PR_FALSE;
- inKeyRecRep->newSigCert = CERT_DupCertificate(inNewSignCert);
- return (inKeyRecRep->newSigCert == NULL) ? SECFailure : SECSuccess;
-}
-
-SECStatus
-CMMF_KeyRecRepContentSetCACerts(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertList *inCACerts)
-{
- SECStatus rv;
- void *mark;
-
- PORT_Assert (inKeyRecRep != NULL && inCACerts != NULL);
- if (inKeyRecRep == NULL || inCACerts == NULL) {
- return SECFailure;
- }
- mark = PORT_ArenaMark(inKeyRecRep->poolp);
- rv = cmmf_ExtractCertsFromList(inCACerts, inKeyRecRep->poolp,
- &inKeyRecRep->caCerts);
- if (rv != SECSuccess) {
- PORT_ArenaRelease(inKeyRecRep->poolp, mark);
- } else {
- PORT_ArenaUnmark(inKeyRecRep->poolp, mark);
- }
- return rv;
-}
-
-SECStatus
-CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertificate *inCert,
- SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inPubKey)
-{
- CMMFCertifiedKeyPair *keyPair;
- CRMFEncryptedValue *dummy;
- PRArenaPool *poolp;
- void *mark;
- SECStatus rv;
-
- PORT_Assert (inKeyRecRep != NULL &&
- inCert != NULL &&
- inPrivKey != NULL &&
- inPubKey != NULL);
- if (inKeyRecRep == NULL ||
- inCert == NULL ||
- inPrivKey == NULL ||
- inPubKey == NULL) {
- return SECFailure;
- }
- poolp = inKeyRecRep->poolp;
- mark = PORT_ArenaMark(poolp);
- if (inKeyRecRep->keyPairHist == NULL) {
- inKeyRecRep->keyPairHist = PORT_ArenaNewArray(poolp,
- CMMFCertifiedKeyPair*,
- (CMMF_MAX_KEY_PAIRS+1));
- if (inKeyRecRep->keyPairHist == NULL) {
- goto loser;
- }
- inKeyRecRep->allocKeyPairs = CMMF_MAX_KEY_PAIRS;
- inKeyRecRep->numKeyPairs = 0;
- }
-
- if (inKeyRecRep->allocKeyPairs == inKeyRecRep->numKeyPairs) {
- goto loser;
- }
-
- keyPair = PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair);
- if (keyPair == NULL) {
- goto loser;
- }
- rv = cmmf_CertOrEncCertSetCertificate(&keyPair->certOrEncCert,
- poolp, inCert);
- if (rv != SECSuccess) {
- goto loser;
- }
- keyPair->privateKey = PORT_ArenaZNew(poolp, CRMFEncryptedValue);
- if (keyPair->privateKey == NULL) {
- goto loser;
- }
- dummy = crmf_create_encrypted_value_wrapped_privkey(inPrivKey, inPubKey,
- keyPair->privateKey);
- PORT_Assert(dummy == keyPair->privateKey);
- if (dummy != keyPair->privateKey) {
- crmf_destroy_encrypted_value(dummy, PR_TRUE);
- goto loser;
- }
- inKeyRecRep->keyPairHist[inKeyRecRep->numKeyPairs] = keyPair;
- inKeyRecRep->numKeyPairs++;
- inKeyRecRep->keyPairHist[inKeyRecRep->numKeyPairs] = NULL;
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
- loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-CMMFPKIStatus
-CMMF_KeyRecRepContentGetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep)
-{
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep == NULL) {
- return cmmfNoPKIStatus;
- }
- return cmmf_PKIStatusInfoGetStatus(&inKeyRecRep->status);
-}
-
-CERTCertificate*
-CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep)
-{
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep == NULL ||
- inKeyRecRep->newSigCert == NULL) {
- return NULL;
- }
- /* newSigCert may not be a real certificate, it may be a hand decoded
- * cert structure. This code makes sure we hand off a real, fully formed
- * CERTCertificate to the caller. TODO: This should move into the decode
- * portion so that we never wind up with a half formed CERTCertificate
- * here. In this case the call would be to CERT_DupCertificate.
- */
- return CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- &inKeyRecRep->newSigCert->signatureWrap.data,
- NULL, PR_FALSE, PR_TRUE);
-}
-
-CERTCertList*
-CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep)
-{
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep == NULL || inKeyRecRep->caCerts == NULL) {
- return NULL;
- }
- return cmmf_MakeCertList(inKeyRecRep->caCerts);
-}
-
-int
-CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep)
-{
- PORT_Assert(inKeyRecRep != NULL);
- return (inKeyRecRep == NULL) ? 0 : inKeyRecRep->numKeyPairs;
-}
-
-PRBool
-cmmf_KeyRecRepContentIsValidIndex(CMMFKeyRecRepContent *inKeyRecRep,
- int inIndex)
-{
- int numKeyPairs = CMMF_KeyRecRepContentGetNumKeyPairs(inKeyRecRep);
-
- return (PRBool)(inIndex >= 0 && inIndex < numKeyPairs);
-}
-
-CMMFCertifiedKeyPair*
-CMMF_KeyRecRepContentGetCertKeyAtIndex(CMMFKeyRecRepContent *inKeyRecRep,
- int inIndex)
-{
- CMMFCertifiedKeyPair *newKeyPair;
- SECStatus rv;
-
- PORT_Assert(inKeyRecRep != NULL &&
- cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex));
- if (inKeyRecRep == NULL ||
- !cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex)) {
- return NULL;
- }
- newKeyPair = PORT_ZNew(CMMFCertifiedKeyPair);
- if (newKeyPair == NULL) {
- return NULL;
- }
- rv = cmmf_CopyCertifiedKeyPair(NULL, newKeyPair,
- inKeyRecRep->keyPairHist[inIndex]);
- if (rv != SECSuccess) {
- CMMF_DestroyCertifiedKeyPair(newKeyPair);
- newKeyPair = NULL;
- }
- return newKeyPair;
-}
-
-SECStatus
-CMMF_CertifiedKeyPairUnwrapPrivKey(CMMFCertifiedKeyPair *inKeyPair,
- SECKEYPrivateKey *inPrivKey,
- SECItem *inNickName,
- PK11SlotInfo *inSlot,
- CERTCertDBHandle *inCertdb,
- SECKEYPrivateKey **destPrivKey,
- void *wincx)
-{
- CERTCertificate *cert;
- SECItem keyUsageValue = {siBuffer, NULL, 0};
- unsigned char keyUsage = 0x0;
- SECKEYPublicKey *pubKey;
- SECStatus rv;
-
- PORT_Assert(inKeyPair != NULL &&
- inPrivKey != NULL && inCertdb != NULL);
- if (inKeyPair == NULL ||
- inPrivKey == NULL ||
- inKeyPair->privateKey == NULL ||
- inCertdb == NULL) {
- return SECFailure;
- }
-
- cert = CMMF_CertifiedKeyPairGetCertificate(inKeyPair, inCertdb);
- CERT_FindKeyUsageExtension(cert, &keyUsageValue);
- if (keyUsageValue.data != NULL) {
- keyUsage = keyUsageValue.data[3];
- PORT_Free(keyUsageValue.data);
- }
- pubKey = CERT_ExtractPublicKey(cert);
- rv = crmf_encrypted_value_unwrap_priv_key(NULL, inKeyPair->privateKey,
- inPrivKey, pubKey,
- inNickName, inSlot, keyUsage,
- destPrivKey, wincx);
- SECKEY_DestroyPublicKey(pubKey);
- CERT_DestroyCertificate(cert);
- return rv;
-}
-
-
-PRBool
-CMMF_KeyRecRepContentHasCACerts(CMMFKeyRecRepContent *inKeyRecRep)
-{
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep == NULL) {
- return PR_FALSE;
- }
- return (PRBool)(inKeyRecRep->caCerts != NULL &&
- inKeyRecRep->caCerts[0] != NULL);
-}
diff --git a/security/nss/lib/crmf/cmmfresp.c b/security/nss/lib/crmf/cmmfresp.c
deleted file mode 100644
index a0ec49903..000000000
--- a/security/nss/lib/crmf/cmmfresp.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * This file will contain all routines dealing with creating a
- * CMMFCertRepContent structure through Create/Set functions.
- */
-
-#include "cmmf.h"
-#include "cmmfi.h"
-#include "crmf.h"
-#include "crmfi.h"
-#include "secitem.h"
-#include "secder.h"
-
-CMMFCertRepContent*
-CMMF_CreateCertRepContent(void)
-{
- CMMFCertRepContent *retCertRep;
- PRArenaPool *poolp;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- goto loser;
- }
- retCertRep = PORT_ArenaZNew(poolp, CMMFCertRepContent);
- if (retCertRep == NULL) {
- goto loser;
- }
- retCertRep->poolp = poolp;
- return retCertRep;
- loser:
- if (poolp != NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return NULL;
-}
-
-SECStatus
-cmmf_CertOrEncCertSetCertificate(CMMFCertOrEncCert *certOrEncCert,
- PRArenaPool *poolp,
- CERTCertificate *inCert)
-{
- SECItem *derDest = NULL;
- SECStatus rv = SECFailure;
-
- if (inCert->derCert.data == NULL) {
- derDest = SEC_ASN1EncodeItem(NULL, NULL, inCert,
- CMMFCertOrEncCertCertificateTemplate);
- if (derDest == NULL) {
- goto loser;
- }
- } else {
- derDest = SECITEM_DupItem(&inCert->derCert);
- if (derDest == NULL) {
- goto loser;
- }
- }
- PORT_Assert(certOrEncCert->cert.certificate == NULL);
- certOrEncCert->cert.certificate = CERT_DupCertificate(inCert);
- certOrEncCert->choice = cmmfCertificate;
- if (poolp != NULL) {
- rv = SECITEM_CopyItem(poolp, &certOrEncCert->derValue, derDest);
- if (rv != SECSuccess) {
- goto loser;
- }
- } else {
- certOrEncCert->derValue = *derDest;
- }
- PORT_Free(derDest);
- return SECSuccess;
- loser:
- if (derDest != NULL) {
- SECITEM_FreeItem(derDest, PR_TRUE);
- }
- return rv;
-}
-
-SECStatus
-cmmf_ExtractCertsFromList(CERTCertList *inCertList,
- PRArenaPool *poolp,
- CERTCertificate ***certArray)
-{
- CERTCertificate **arrayLocalCopy;
- CERTCertListNode *node;
- int numNodes = 0, i;
-
- for (node = CERT_LIST_HEAD(inCertList); !CERT_LIST_END(node, inCertList);
- node = CERT_LIST_NEXT(node)) {
- numNodes++;
- }
-
- arrayLocalCopy = *certArray = (poolp == NULL) ?
- PORT_NewArray(CERTCertificate*, (numNodes+1)) :
- PORT_ArenaNewArray(poolp, CERTCertificate*, (numNodes+1));
- if (arrayLocalCopy == NULL) {
- return SECFailure;
- }
- for (node = CERT_LIST_HEAD(inCertList), i=0;
- !CERT_LIST_END(node, inCertList);
- node = CERT_LIST_NEXT(node), i++) {
- arrayLocalCopy[i] = CERT_DupCertificate(node->cert);
- if (arrayLocalCopy[i] == NULL) {
- int j;
-
- for (j=0; j<i; j++) {
- CERT_DestroyCertificate(arrayLocalCopy[j]);
- }
- if (poolp == NULL) {
- PORT_Free(arrayLocalCopy);
- }
- *certArray = NULL;
- return SECFailure;
- }
- }
- arrayLocalCopy[numNodes] = NULL;
- return SECSuccess;
-}
-
-SECStatus
-CMMF_CertRepContentSetCertResponses(CMMFCertRepContent *inCertRepContent,
- CMMFCertResponse **inCertResponses,
- int inNumResponses)
-{
- PRArenaPool *poolp;
- CMMFCertResponse **respArr, *newResp;
- void *mark;
- SECStatus rv;
- int i;
-
- PORT_Assert (inCertRepContent != NULL &&
- inCertResponses != NULL &&
- inNumResponses > 0);
- if (inCertRepContent == NULL ||
- inCertResponses == NULL ||
- inCertRepContent->response != NULL) {
- return SECFailure;
- }
- poolp = inCertRepContent->poolp;
- mark = PORT_ArenaMark(poolp);
- respArr = inCertRepContent->response =
- PORT_ArenaZNewArray(poolp, CMMFCertResponse*, (inNumResponses+1));
- if (respArr == NULL) {
- goto loser;
- }
- for (i=0; i<inNumResponses; i++) {
- newResp = PORT_ArenaZNew(poolp, CMMFCertResponse);
- if (newResp == NULL) {
- goto loser;
- }
- rv = cmmf_CopyCertResponse(poolp, newResp, inCertResponses[i]);
- if (rv != SECSuccess) {
- goto loser;
- }
- respArr[i] = newResp;
- }
- respArr[inNumResponses] = NULL;
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
- loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-CMMFCertResponse*
-CMMF_CreateCertResponse(long inCertReqId)
-{
- SECItem *dummy;
- CMMFCertResponse *newResp;
-
- newResp = PORT_ZNew(CMMFCertResponse);
- if (newResp == NULL) {
- goto loser;
- }
- dummy = SEC_ASN1EncodeInteger(NULL, &newResp->certReqId, inCertReqId);
- if (dummy != &newResp->certReqId) {
- goto loser;
- }
- return newResp;
-
- loser:
- if (newResp != NULL) {
- CMMF_DestroyCertResponse(newResp);
- }
- return NULL;
-}
-
-SECStatus
-CMMF_CertResponseSetPKIStatusInfoStatus(CMMFCertResponse *inCertResp,
- CMMFPKIStatus inPKIStatus)
-{
- PORT_Assert (inCertResp != NULL && inPKIStatus >= cmmfGranted
- && inPKIStatus < cmmfNumPKIStatus);
-
- if (inCertResp == NULL) {
- return SECFailure;
- }
- return cmmf_PKIStatusInfoSetStatus(&inCertResp->status, NULL,
- inPKIStatus);
-}
-
-SECStatus
-CMMF_CertResponseSetCertificate (CMMFCertResponse *inCertResp,
- CERTCertificate *inCertificate)
-{
- CMMFCertifiedKeyPair *keyPair = NULL;
- SECStatus rv = SECFailure;
-
- PORT_Assert(inCertResp != NULL && inCertificate != NULL);
- if (inCertResp == NULL || inCertificate == NULL) {
- return SECFailure;
- }
- if (inCertResp->certifiedKeyPair == NULL) {
- keyPair = inCertResp->certifiedKeyPair =
- PORT_ZNew(CMMFCertifiedKeyPair);
- } else {
- keyPair = inCertResp->certifiedKeyPair;
- }
- if (keyPair == NULL) {
- goto loser;
- }
- rv = cmmf_CertOrEncCertSetCertificate(&keyPair->certOrEncCert, NULL,
- inCertificate);
- if (rv != SECSuccess) {
- goto loser;
- }
- return SECSuccess;
- loser:
- if (keyPair) {
- if (keyPair->certOrEncCert.derValue.data) {
- PORT_Free(keyPair->certOrEncCert.derValue.data);
- }
- PORT_Free(keyPair);
- }
- return rv;
-}
-
-
-SECStatus
-CMMF_CertRepContentSetCAPubs(CMMFCertRepContent *inCertRepContent,
- CERTCertList *inCAPubs)
-{
- PRArenaPool *poolp;
- void *mark;
- SECStatus rv;
-
- PORT_Assert(inCertRepContent != NULL &&
- inCAPubs != NULL &&
- inCertRepContent->caPubs == NULL);
-
- if (inCertRepContent == NULL ||
- inCAPubs == NULL || inCertRepContent == NULL) {
- return SECFailure;
- }
-
- poolp = inCertRepContent->poolp;
- mark = PORT_ArenaMark(poolp);
-
- rv = cmmf_ExtractCertsFromList(inCAPubs, poolp,
- &inCertRepContent->caPubs);
-
- if (rv != SECSuccess) {
- PORT_ArenaRelease(poolp, mark);
- } else {
- PORT_ArenaUnmark(poolp, mark);
- }
- return rv;
-}
-
-CERTCertificate*
-CMMF_CertifiedKeyPairGetCertificate(CMMFCertifiedKeyPair *inCertKeyPair,
- CERTCertDBHandle *inCertdb)
-{
- PORT_Assert(inCertKeyPair != NULL);
- if (inCertKeyPair == NULL) {
- return NULL;
- }
- return cmmf_CertOrEncCertGetCertificate(&inCertKeyPair->certOrEncCert,
- inCertdb);
-}
diff --git a/security/nss/lib/crmf/cmmft.h b/security/nss/lib/crmf/cmmft.h
deleted file mode 100644
index aea64b0f4..000000000
--- a/security/nss/lib/crmf/cmmft.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _CMMFT_H_
-#define _CMMFT_H_
-
-#include "secasn1.h"
-
-/*
- * These are the enumerations used to distinguish between the different
- * choices available for the CMMFCertOrEncCert structure.
- */
-typedef enum {
- cmmfNoCertOrEncCert = 0,
- cmmfCertificate = 1,
- cmmfEncryptedCert = 2
-} CMMFCertOrEncCertChoice;
-
-/*
- * This is the enumeration and the corresponding values used to
- * represent the CMMF type PKIStatus
- */
-typedef enum {
- cmmfNoPKIStatus = -1,
- cmmfGranted = 0,
- cmmfGrantedWithMods = 1,
- cmmfRejection = 2,
- cmmfWaiting = 3,
- cmmfRevocationWarning = 4,
- cmmfRevocationNotification = 5,
- cmmfKeyUpdateWarning = 6,
- cmmfNumPKIStatus
-} CMMFPKIStatus;
-
-/*
- * These enumerations are used to represent the corresponding values
- * in PKIFailureInfo defined in CMMF.
- */
-typedef enum {
- cmmfBadAlg = 0,
- cmmfBadMessageCheck = 1,
- cmmfBadRequest = 2,
- cmmfBadTime = 3,
- cmmfBadCertId = 4,
- cmmfBadDataFormat = 5,
- cmmfWrongAuthority = 6,
- cmmfIncorrectData = 7,
- cmmfMissingTimeStamp = 8,
- cmmfNoFailureInfo = 9
-} CMMFPKIFailureInfo;
-
-typedef struct CMMFPKIStatusInfoStr CMMFPKIStatusInfo;
-typedef struct CMMFCertOrEncCertStr CMMFCertOrEncCert;
-typedef struct CMMFCertifiedKeyPairStr CMMFCertifiedKeyPair;
-typedef struct CMMFCertResponseStr CMMFCertResponse;
-typedef struct CMMFCertResponseSeqStr CMMFCertResponseSeq;
-typedef struct CMMFPOPODecKeyChallContentStr CMMFPOPODecKeyChallContent;
-typedef struct CMMFChallengeStr CMMFChallenge;
-typedef struct CMMFRandStr CMMFRand;
-typedef struct CMMFPOPODecKeyRespContentStr CMMFPOPODecKeyRespContent;
-typedef struct CMMFKeyRecRepContentStr CMMFKeyRecRepContent;
-typedef struct CMMFCertRepContentStr CMMFCertRepContent;
-
-/* Export this so people can call SEC_ASN1EncodeItem instead of having to
- * write callbacks that are passed in to the high level encode function
- * for CMMFCertRepContent.
- */
-extern const SEC_ASN1Template CMMFCertRepContentTemplate[];
-extern const SEC_ASN1Template CMMFPOPODecKeyChallContentTemplate[];
-
-#endif /*_CMMFT_H_*/
diff --git a/security/nss/lib/crmf/config.mk b/security/nss/lib/crmf/config.mk
deleted file mode 100644
index dc39ee4d6..000000000
--- a/security/nss/lib/crmf/config.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/crmf/crmf.h b/security/nss/lib/crmf/crmf.h
deleted file mode 100644
index 9f36c2884..000000000
--- a/security/nss/lib/crmf/crmf.h
+++ /dev/null
@@ -1,1750 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#ifndef _CRMF_H_
-#define _CRMF_H_
-
-#include "seccomon.h"
-#include "cert.h"
-#include "crmft.h"
-#include "secoid.h"
-#include "secpkcs7.h"
-
-SEC_BEGIN_PROTOS
-
-/*
- * FUNCTION: CRMF_EncodeCertReqMsg
- * INPUTS:
- * inCertReqMsg
- * The Certificate Request Message to be encoded.
- * fn
- * A Callback function that the ASN1 encoder calls whenever
- * the encoder wants to write out some DER encoded bytes.
- * arg
- * An opaque pointer that gets passed to the function fn
- * OUTPUT:
- * The function fn will be called multiple times. Look at the
- * comments in crmft.h where the CRMFEncoderOutputCallback type is
- * defined for information on proper behavior of the function fn.
- * RETURN:
- * SECSuccess if encoding was successful. Any other return value
- * indicates an error occurred during encoding.
- */
-extern SECStatus
- CRMF_EncodeCertReqMsg (CRMFCertReqMsg *inCertReqMsg,
- CRMFEncoderOutputCallback fn,
- void *arg);
-
-/*
- * FUNCTION: CRMF_EncoderCertRequest
- * INPUTS:
- * inCertReq
- * The Certificate Request to be encoded.
- * fn
- * A Callback function that the ASN1 encoder calls whenever
- * the encoder wants to write out some DER encoded bytes.
- * arg
- * An opaque pointer that gets passed to the function fn.
- * OUTPUT:
- * The function fn will be called, probably multiple times whenever
- * the ASN1 encoder wants to write out DER-encoded bytes. Look at the
- * comments in crmft.h where the CRMFEncoderOutputCallback type is
- * defined for information on proper behavior of the function fn.
- * RETURN:
- * SECSuccess if encoding was successful. Any other return value
- * indicates an error occurred during encoding.
- */
-extern SECStatus CRMF_EncodeCertRequest (CRMFCertRequest *inCertReq,
- CRMFEncoderOutputCallback fn,
- void *arg);
-/*
- * FUNCTION: CRMF_EncodeCertReqMessages
- * INPUTS:
- * inCertReqMsgs
- * An array of pointers to the Certificate Request Messages
- * to encode. The user must place a NULL pointer in the index
- * after the last message to be encoded. When the library runs
- * into the NULL pointer, the library assumes there are no more
- * messages to encode.
- * fn
- * A Callback function that the ASN1 encoder calls whenever
- * the encoder wants to write out some DER encoded byts.
- * arg
- * An opaque pointer that gets passed to the function fn.
- *
- * NOTES:
- * The parameter inCertReqMsgs needs to be an array with a NULL pointer
- * to signal the end of messages. An array in the form of
- * {m1, m2, m3, NULL, m4, ...} will only encode the messages m1, m2, and
- * m3. All messages from m4 on will not be looked at by the library.
- *
- * OUTPUT:
- * The function fn will be called, probably multiple times. Look at the
- * comments in crmft.h where the CRMFEncoderOutputCallback type is
- * defined for information on proper behavior of the function fn.
- *
- * RETURN:
- * SECSuccess if encoding the Certificate Request Messages was successful.
- * Any other return value indicates an error occurred while encoding the
- * certificate request messages.
- */
-extern SECStatus
- CRMF_EncodeCertReqMessages(CRMFCertReqMsg **inCertReqMsgs,
- CRMFEncoderOutputCallback fn,
- void *arg);
-
-
-/*
- * FUNCTION: CRMF_CreateCertReqMsg
- * INPUTS:
- * NONE
- * OUTPUT:
- * An empty CRMF Certificate Request Message.
- * Before encoding this message, the user must set
- * the ProofOfPossession field and the certificate
- * request which are necessary for the full message.
- * After the user no longer needs this CertReqMsg,
- * the user must call CRMF_DestroyCertReqMsg to free
- * all memory associated with the Certificate Request
- * Message.
- * RETURN:
- * A pointer to a Certificate Request Message. The user
- * must pass the return value of this function to
- * CRMF_DestroyCertReqMsg after the Certificate Request
- * Message is no longer necessary.
- */
-extern CRMFCertReqMsg* CRMF_CreateCertReqMsg(void);
-
-/*
- * FUNCTION: CRMF_DestroyCertReqMsg
- * INPUTS:
- * inCertReqMsg
- * The Certificate Request Message to destroy.
- * NOTES:
- * This function frees all the memory used for the Certificate
- * Request Message and all the memory used in making copies of
- * fields of elelments of the message, eg. the Proof Of Possession
- * filed and the Cetificate Request.
- * RETURN:
- * SECSuccess if destruction was successful. Any other return value
- * indicates an error while trying to free the memory associated
- * with inCertReqMsg.
- *
- */
-extern SECStatus CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg);
-
-/*
- * FUNCTION: CRMF_CertReqMsgSetCertRequest
- * INPUTS:
- * inCertReqMsg
- * The Certificate Request Message that the function will set
- * the certificate request for.
- * inCertReq
- * The Certificate Request that will be added to the Certificate
- * Request Message.
- * NOTES:
- * This function will make a copy of the Certificate Request passed in
- * and store it as part of the Certificate Request Message. Therefore,
- * the user must not call this function until the Certificate Request
- * has been fully built and is ready to be encoded.
- * RETURN:
- * SECSuccess
- * If copying the Certificate as a member of the Certificate
- * request message was successful.
- * Any other return value indicates a failure to copy the Certificate
- * Request and make it a part of the Certificate Request Message.
- */
-extern SECStatus CRMF_CertReqMsgSetCertRequest(CRMFCertReqMsg *inCertReqMsg,
- CRMFCertRequest *inCertReq);
-
-/*
- * FUNCTION: CRMF_CreateCertRequest
- * INPUTS:
- * inRequestID
- * The ID that will be associated with this certificate request.
- * OUTPUTS:
- * A certificate request which only has the requestID set.
- * NOTES:
- * The user must call the function CRMF_DestroyCertRequest when
- * the returned value is no longer needed. This is usually the
- * case after fully constructing the Certificate Request and then
- * calling the function CRMF_CertReqMsgSetCertRequest.
- * RETURN:
- * A pointer to the new Certificate Request. A NULL return value
- * indicates an error in creating the Certificate Request.
- */
-extern CRMFCertRequest *CRMF_CreateCertRequest (PRUint32 inRequestID);
-
-/*
- * FUNCTION: CRMF_DestroyCertRequest
- * INPUTS:
- * inCertReq
- * The Certificate Request that will be destroyed.
- * RETURN:
- * SECSuccess
- * If freeing the memory associated with the certificate request
- * was successful.
- * Any other return value indicates an error while trying to free the
- * memory.
- */
-extern SECStatus CRMF_DestroyCertRequest (CRMFCertRequest *inCertReq);
-
-/*
- * FUNCTION: CRMF_CreateCertExtension
- * INPUTS:
- * id
- * The SECOidTag to associate with this CertExtension. This must
- * correspond to a valid Certificate Extension, if not the function
- * will fail.
- * isCritical
- * A boolean value stating if the extension value is crtical. PR_TRUE
- * means the value is crtical. PR_FALSE indicates the value is not
- * critical.
- * data
- * This is the data associated with the extension. The user of the
- * library is responsible for making sure the value passed in is a
- * valid interpretation of the certificate extension.
- * NOTES:
- * Use this function to create CRMFCertExtension Structures which will
- * then be passed to CRMF_AddFieldToCertTemplate as part of the
- * CRMFCertCreationInfo.extensions The user must call
- * CRMF_DestroyCertExtension after the extension has been added to a certifcate
- * and the extension is no longer needed.
- *
- * RETURN:
- * A pointer to a newly created CertExtension. A return value of NULL
- * indicates the id passed in was an invalid certificate extension.
- */
-extern CRMFCertExtension *CRMF_CreateCertExtension(SECOidTag id,
- PRBool isCritical,
- SECItem *data);
-
-/*
- * FUNCTION: CMRF_DestroyCertExtension
- * INPUTS:
- * inExtension
- * The Cert Extension to destroy
- * NOTES:
- * Destroy a structure allocated by CRMF_CreateCertExtension.
- *
- * RETURN:
- * SECSuccess if freeing the memory associated with the certificate extension
- * was successful. Any other error indicates an error while freeing the
- * memory.
- */
-extern SECStatus CRMF_DestroyCertExtension(CRMFCertExtension *inExtension);
-
-/*
- * FUNCTION: CRMF_CertRequestSetTemplateField
- * INPUTS:
- * inCertReq
- * The Certificate Request to operate on.
- * inTemplateField
- * An enumeration that indicates which field of the Certificate
- * template to add.
- * data
- * A generic pointer that will be type cast according to the
- * table under NOTES and used as the key for adding to the
- * certificate template;
- * NOTES:
- *
- * Below is a table that tells what type to pass in as data
- * depending on the template field one wants to set.
- *
- * Look in crmft.h for the definition of CRMFCertTemplateField.
- *
- * In all cases, the library makes copies of the data passed in.
- *
- * CRMFCertTemplateField Type of data What data means
- * --------------------- ------------ ---------------
- * crmfVersion long * The version of
- * the certificate
- * to be created.
- *
- * crmfSerialNumber long * The serial number
- * for the cert to be
- * created.
- *
- * crmfSigningAlg SECAlgorithm * The ASN.1 object ID for
- * the algorithm used in encoding
- * the certificate.
- *
- * crmfIssuer CERTName * Certificate Library
- * representation of the ASN1 type
- * Name from X.509
- *
- * crmfValidity CRMFValidityCreationInfo * At least one of the two
- * fields in the structure must
- * be present. A NULL pointer
- * in the structure indicates
- * that member should not be
- * added.
- *
- * crmfSubject CERTName * Certificate Library
- * representation of the ASN1 type
- * Name from X.509
- *
- * crmfPublicKey CERTSubjectPublicKeyInfo * The public key info for the
- * certificate being requested.
- *
- * crmfIssuerUID SECItem * A bit string representation
- * of the issuer UID. NOTE: The
- * length is the number of bits
- * and not the number of bytes.
- *
- * crmfSubjectUID SECItem* A bit string representation
- * of the subject UID. NOTE: The
- * length is the number of bits
- * and not the number of bytes.
- *
- * crmfExtension CRMFCertExtCreationInfo * A pointer to the structure
- * populated with an array of
- * of certificate extensions
- * and an integer that tells
- * how many elements are in the
- * array. Look in crmft.h for
- * the definition of
- * CRMFCertExtCreationInfo
- * RETURN:
- * SECSuccess if adding the desired field to the template was successful.
- * Any other return value indicates failure when trying to add the field
- * to the template.
- *
- */
-extern SECStatus
- CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inTemplateField,
- void *data);
-
-/*
- * FUNCTION: CRMF_CertRequestIsFieldPresent
- * INPUTS:
- * inCertReq
- * The certificate request to operate on.
- * inTemplateField
- * The enumeration for the template field the user wants to query
- * about.
- * NOTES:
- * This function checks to see if the the field associated with inTemplateField
- * enumeration is already present in the certificate request passed in.
- *
- * RETURN:
- * The function returns PR_TRUE if the field associated with inTemplateField
- * is already present in the certificate request. If the field is not present
- * the function returns PR_FALSE.
- */
-extern PRBool
- CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inTemplateField);
-
-/*
- * FUNCTION: CRMF_CertRequestIsControlPresent
- * INPUTS:
- * inCertReq
- * The certificate request to operate on.
- * inControlType
- * The type of control to look for.
- * NOTES:
- * This function looks at the control present in the certificate request
- * and returns PR_TRUE iff a control of type inControlType already exists.
- * The CRMF draft does not explicitly state that two controls of the same
- * type can not exist within the same request. So the library will not
- * cause an error if you try to add a control and one of the same type
- * already exists. It is up to the application to ensure that multiple
- * controls of the same type do not exist, if that is the desired behavior
- * by the application.
- *
- * RETURN:
- * The function returns PR_TRUE if a control of type inControlType already
- * exists in the certificate request. If a control of type inControlType
- * does not exist, the function will return PR_FALSE.
- */
-extern PRBool
- CRMF_CertRequestIsControlPresent(CRMFCertRequest *inCertReq,
- CRMFControlType inControlType);
-
-
-/*
- * FUNCTION: CRMF_CertRequestSetRegTokenControl
- * INPUTS:
- * inCertReq
- * The Certificate Request to operate on.
- * value
- * The UTF8 value which will be the Registration Token Control
- * for this Certificate Request.
- * NOTES:
- * The library does no verification that the value passed in is
- * a valid UTF8 value. The caller must make sure of this in order
- * to get an encoding that is valid. The library will ultimately
- * encode this value as it was passed in.
- * RETURN:
- * SECSucces on successful addition of the Registration Token Control.
- * Any other return value indicates an unsuccessful attempt to add the
- * control.
- *
- */
-extern SECStatus CRMF_CertRequestSetRegTokenControl(CRMFCertRequest *inCertReq,
- SECItem *value);
-
-/*
- * FUNCTION: CRMF_CertRequestSetAuthenticatorControl
- * INPUTS:
- * inCertReq
- * The Certificate Request to operate on.
- * value
- * The UTF8 value that will become the Authenticator Control
- * for the passed in Certificate Request.
- * NOTES:
- * The library does no verification that the value passed in is
- * a valid UTF8 value. The caller must make sure of this in order
- * to get an encoding that is valid. The library will ultimately
- * encode this value as it was passed in.
- * RETURN:
- * SECSucces on successful addition of the Authenticator Control.
- * Any other return value indicates an unsuccessful attempt to add the
- * control.
- */
-extern SECStatus
- CRMF_CertRequestSetAuthenticatorControl (CRMFCertRequest *inCertReq,
- SECItem *value);
-
-/*
- * FUNCTION: CRMF_CreateEncryptedKeyWithencryptedValue
- * INPUTS:
- * inPrivKey
- * This is the private key associated with a certificate that is
- * being requested. This structure will eventually wind up as
- * a part of the PKIArchiveOptions Control.
- * inCACert
- * This is the certificate for the CA that will be receiving the
- * certificate request for the private key passed in.
- * OUTPUT:
- * A CRMFEncryptedKey that can ultimately be used as part of the
- * PKIArchiveOptions Control.
- *
- * RETURN:
- * A pointer to a CRMFEncyptedKey. A NULL return value indicates an erro
- * during the creation of the encrypted key.
- */
-extern CRMFEncryptedKey*
- CRMF_CreateEncryptedKeyWithEncryptedValue(SECKEYPrivateKey *inPrivKey,
- CERTCertificate *inCACert);
-
-/*
- * FUNCTION: CRMF_DestroyEncryptedKey
- * INPUTS:
- * inEncrKey
- * The CRMFEncryptedKey to be destroyed.
- * NOTES:
- * Frees all memory associated with the CRMFEncryptedKey passed in.
- * RETURN:
- * SECSuccess if freeing the memory was successful. Any other return
- * value indicates an error while freeig the memroy.
- */
-extern SECStatus CRMF_DestroyEncryptedKey(CRMFEncryptedKey *inEncrKey);
-
-/*
- * FUNCTION: CRMF_CreatePKIArchiveOptions
- * INPUTS:
- * inType
- * An enumeration value indicating which option for
- * PKIArchiveOptions to use.
- * data
- * A pointer that will be type-cast and de-referenced according
- * to the table under NOTES.
- * NOTES:
- * A table listing what should be passed in as data
- * ------------------------------------------------
- *
- * inType data
- * ------ ----
- * crmfEncryptedPrivateKey CRMFEncryptedKey*
- * crmfKeyGenParameters SECItem*(This needs to be an octet string)
- * crmfArchiveRemGenPrivKey PRBool*
- *
- * RETURN:
- * A pointer the a CRMFPKIArchiveOptions that can be added to a Certificate
- * Request. A NULL pointer indicates an error occurred while creating
- * the CRMFPKIArchiveOptions Structure.
- */
-extern CRMFPKIArchiveOptions*
- CRMF_CreatePKIArchiveOptions(CRMFPKIArchiveOptionsType inType,
- void *data);
-/*
- * FUNCTION: CRMF_DestroyPKIArchiveOptions
- * INPUTS:
- * inArchOpt
- * A pointer to the CRMFPKIArchiveOptions structure to free.
- * NOTES:
- * Will free all memory associated with 'inArchOpt'.
- * RETURN:
- * SECSuccess if successful in freeing the memory used by 'inArchOpt'
- * Any other return value indicates an error while freeing the memory.
- */
-extern SECStatus
- CRMF_DestroyPKIArchiveOptions(CRMFPKIArchiveOptions *inArchOpt);
-
-/*
- * FUNCTION: CRMF_CertRequestSetPKIArchiveOptions
- * INPUTS:
- * inCertReq
- * The Certificate Request to add the the options to.
- * inOptions
- * The Archive Options to add to the Certificate Request.
- * NOTES:
- * Adds the PKIArchiveOption to the Certificate Request. This is what
- * enables Key Escrow to take place through CRMF. The library makes
- * its own copy of the information.
- * RETURN:
- * SECSuccess if successful in adding the ArchiveOptions to the Certificate
- * request. Any other return value indicates an error when trying to add
- * the Archive Options to the Certificate Request.
- */
-extern SECStatus
- CRMF_CertRequestSetPKIArchiveOptions(CRMFCertRequest *inCertReq,
- CRMFPKIArchiveOptions *inOptions);
-
-/*
- * FUNCTION: CRMF_CertReqMsgGetPOPType
- * INPUTS:
- * inCertReqMsg
- * The Certificate Request Message to operate on.
- * NOTES:
- * Returns an enumeration value indicating the method of Proof
- * of Possession that was used for the passed in Certificate Request
- * Message.
- * RETURN:
- * An enumeration indicating what method for Proof Of Possession is
- * being used in this Certificate Request Message. Look in the file
- * crmft.h for the definition of CRMFPOPChoice for the possible return
- * values.
- */
-extern CRMFPOPChoice CRMF_CertReqMsgGetPOPType(CRMFCertReqMsg *inCertReqMsg);
-
-/*
- * FUNCTION: CRMF_CertReqMsgSetRAVerifiedPOP
- * INPUT:
- * InCertReqMsg
- * The Certificate Request Message to operate on.
- * NOTES:
- * This function will set the method of Proof Of Possession to
- * crmfRAVerified which means the RA has already verified the
- * requester does possess the private key.
- * RETURN:
- * SECSuccess if adding RAVerified to the message is successful.
- * Any other message indicates an error while trying to add RAVerified
- * as the Proof of Possession.
- */
-extern SECStatus CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg);
-
-/*
- * FUNCTION: CRMF_CertReqMsgSetSignaturePOP
- * INPUT:
- * inCertReqMsg
- * The Certificate Request Message to add the SignaturePOP to.
- * inPrivKey
- * The Private Key which corresponds to the the Certificate Request
- * Message.
- * inPubKey
- * The Public Key which corresponds to the Private Key passed in.
- * inCertForInput
- * A Certificate that in the future may be used to create
- * POPOSigningKeyInput.
- * fn
- * A callback for retrieving a password which may be used in the
- * future to generate POPOSigningKeyInput.
- * arg
- * An opaque pointer that would be passed to fn whenever it is
- * called.
- * NOTES:
- * Adds Proof Of Possession to the CertRequest using the signature field
- * of the ProofOfPossession field. NOTE: In order to use this option,
- * the certificate template must contain the publicKey at the very minimum.
- *
- * If you don't want the function to generate POPOSigningKeyInput, then
- * make sure the cert template already contains the subject and public key
- * values. Currently creating POPOSigningKeyInput is not supported, so
- * a Message passed to this function must have the publicKey and the subject
- * as part of the template
- *
- * This will take care of creating the entire POPOSigningKey structure
- * that will become part of the message.
- *
- * inPrivKey is the key to be used in the signing operation when creating
- * POPOSigningKey structure. This should be the key corresponding to
- * the certificate being requested.
- *
- * inCertForInput will be used if POPOSigningKeyInput needs to be generated.
- * It will be used in generating the authInfo.sender field. If the parameter
- * is not passed in then authInfo.publicKeyMAC will be generated instead.
- * If passed in, this certificate needs to be a valid certificate.
- *
- * The last 3 arguments are for future compatibility in case we ever want to
- * support generating POPOSigningKeyInput. Pass in NULL for all 3 if you
- * definitely don't want the function to even try to generate
- * POPOSigningKeyInput. If you try to use POPOSigningKeyInput, the function
- * will fail.
- *
- * RETURN:
- * SECSuccess if adding the Signature Proof Of Possession worked.
- * Any other return value indicates an error in trying to add
- * the Signature Proof Of Possession.
- */
-extern SECStatus
- CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
- SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inPubKey,
- CERTCertificate *inCertForInput,
- CRMFMACPasswordCallback fn,
- void *arg);
-
-/*
- * FUNCTION: CRMF_CertReqMsgSetKeyEnciphermentPOP
- * INPUTS:
- * inCertReqMsg
- * The Certificate Request Message to operate on.
- * inKeyChoice
- * An enumeration indicating which POPOPrivKey Choice to use
- * in constructing the KeyEnciphermentPOP.
- * subseqMess
- * This parameter must be provided iff inKeyChoice is
- * crmfSubsequentMessage. This details how the RA is to respond
- * in order to perform Proof Of Possession. Look in crmft.h under
- * the definition of CRMFSubseqMessOptions for possible values.
- * encPrivKey
- * This parameter only needs to be provided if inKeyChoice is
- * crmfThisMessage. The item should contain the encrypted private
- * key.
- *
- * NOTES:
- * Adds Proof Of Possession using the keyEncipherment field of
- * ProofOfPossession.
- *
- * The function looks at the the inKeyChoice parameter and interprets it in
- * in the following manner.
- *
- * If a parameter is not mentioned under interpretation, the function will not
- * look at its value when implementing that case.
- *
- * inKeyChoice Interpretation
- * ----------- --------------
- * crmfThisMessage This options requires that the encrypted private key
- * be included in the thisMessage field of POPOPrivKey.
- * We don't support this yet, so any clients who want
- * to use this feature have to implement a wrapping
- * function and agree with the server on how to properly
- * wrap the key. That encrypted key must be passed in
- * as the encPrivKey parameter.
- *
- * crmfSubequentMessage Must pass in a value for subseqMess. The value must
- * be either CRMFEncrCert or CRMFChallengeResp. The
- * parameter encPrivKey will not be looked at in this
- * case.
- *
- * crmfDHMAC This is not a valid option for this function. Passing
- * in this value will result in the function returning
- * SECFailure.
- * RETURN:
- * SECSuccess if adding KeyEnciphermentPOP was successful. Any other return
- * value indicates an error in adding KeyEnciphermentPOP.
- */
-extern SECStatus
- CRMF_CertReqMsgSetKeyEnciphermentPOP(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKeyChoice inKeyChoice,
- CRMFSubseqMessOptions subseqMess,
- SECItem *encPrivKey);
-
-/*
- * FUNCTION: CRMF_CertReqMsgSetKeyAgreementPOP
- * INPUTS:
- * inCertReqMsg
- * The Certificate Request Message to operate on.
- * inKeyChoice
- * An enumeration indicating which POPOPrivKey Choice to use
- * in constructing the KeyAgreementPOP.
- * subseqMess
- * This parameter must be provided iff inKeyChoice is
- * crmfSubsequentMessage. This details how the RA is to respond
- * in order to perform Proof Of Possession. Look in crmft.h under
- * the definition of CRMFSubseqMessOptions for possible values.
- * encPrivKey
- * This parameter only needs to be provided if inKeyChoice is
- * crmfThisMessage. The item should contain the encrypted private
- * key.
- * Adds Proof Of Possession using the keyAgreement field of
- * ProofOfPossession.
- *
- * The function looks at the the inKeyChoice parameter and interprets it in
- * in the following manner.
- *
- * If a parameter is not mentioned under interpretation, the function will not
- * look at its value when implementing that case.
- *
- * inKeyChoice Interpretation
- * ----------- --------------
- * crmfThisMessage This options requires that the encrypted private key
- * be included in the thisMessage field of POPOPrivKey.
- * We don't support this yet, so any clients who want
- * to use this feature have to implement a wrapping
- * function and agree with the server on how to properly
- * wrap the key. That encrypted key must be passed in
- * as the encPrivKey parameter.
- *
- * crmfSubequentMessage Must pass in a value for subseqMess. The value must
- * be either crmfEncrCert or crmfChallengeResp. The
- * parameter encPrivKey will not be looked at in this
- * case.
- *
- * crmfDHMAC This option is not supported.
- */
-extern SECStatus
- CRMF_CertReqMsgSetKeyAgreementPOP(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKeyChoice inKeyChoice,
- CRMFSubseqMessOptions subseqMess,
- SECItem *encPrivKey);
-
-/*
- * FUNCTION: CRMF_CreateCertReqMsgFromDER
- * INPUTS:
- * buf
- * A buffer to the DER-encoded Certificate Request Message.
- * len
- * The length in bytes of the buffer 'buf'
- * NOTES:
- * This function passes the buffer to the ASN1 decoder and creates a
- * CRMFCertReqMsg structure. Do not try adding any fields to a message
- * returned from this function. Specifically adding more Controls or
- * Extensions may cause your program to crash.
- *
- * RETURN:
- * A pointer to the Certificate Request Message structure. A NULL return
- * value indicates the library was unable to parse the DER.
- */
-extern CRMFCertReqMsg* CRMF_CreateCertReqMsgFromDER(const char *buf, long len);
-
-/*
- * FUNCTION: CRMF_CreateCertReqMessagesFromDER
- * INPUTS:
- * buf
- * A buffer to the DER-encoded Certificate Request Messages.
- * len
- * The length in bytes of buf
- * NOTES:
- * This function passes the buffer to the ASN1 decoder and creates a
- * CRMFCertReqMessages structure. Do not try adding any fields to a message
- * derived from this function. Specifically adding more Controls or
- * Extensions may cause your program to crash.
- * The user must call CRMF_DestroyCertReqMessages after the return value is
- * no longer needed, ie when all individual messages have been extracted.
- *
- * RETURN:
- * A pointer to the Certificate Request Messages structure. A NULL return
- * value indicates the library was unable to parse the DER.
- */
-extern CRMFCertReqMessages*
- CRMF_CreateCertReqMessagesFromDER(const char *buf, long len);
-
-/*
- * FUNCTION: CRMF_DestroyCertReqMessages
- * INPUTS
- * inCertReqMsgs
- * The Messages to destroy.
- * RETURN:
- * SECSuccess if freeing the memory was done successfully. Any other
- * return value indicates an error in freeing up memory.
- */
-extern SECStatus
- CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs);
-
-/*
- * FUNCTION: CRMF_CertReqMessagesGetNumMessages
- * INPUTS:
- * inCertReqMsgs
- * The Request Messages to operate on.
- * RETURN:
- * The number of messages contained in the in the Request Messages
- * strucure.
- */
-extern int
- CRMF_CertReqMessagesGetNumMessages(CRMFCertReqMessages *inCertReqMsgs);
-
-/*
- * FUNCTION: CRMF_CertReqMessagesGetCertReqMsgAtIndex
- * INPUTS:
- * inReqMsgs
- * The Certificate Request Messages to operate on.
- * index
- * The index of the single message the user wants a copy of.
- * NOTES:
- * This function returns a copy of the request messages stored at the
- * index corresponding to the parameter 'index'. Indexing of the messages
- * is done in the same manner as a C array. Meaning the valid index are
- * 0...numMessages-1. User must call CRMF_DestroyCertReqMsg when done using
- * the return value of this function.
- *
- * RETURN:
- * SECSuccess if copying the message at the requested index was successful.
- * Any other return value indicates an invalid index or error while copying
- * the single request message.
- */
-extern CRMFCertReqMsg*
- CRMF_CertReqMessagesGetCertReqMsgAtIndex(CRMFCertReqMessages *inReqMsgs,
- int index);
-
-
-/*
- * FUNCTION: CRMF_CertReqMsgGetID
- * INPUTS:
- * inCertReqMsg
- * The Certificate Request Message to get the ID from.
- * destID
- * A pointer to where the library can place the ID of the Message.
- * RETURN:
- * SECSuccess if the function was able to retrieve the ID and place it
- * at *destID. Any other return value indicates an error meaning the value
- * in *destId is un-reliable and should not be used by the caller of this
- * function.
- *
- */
-extern SECStatus CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg,
- long *destID);
-
-/*
- * FUNCTION: CRMF_DoesRequestHaveField
- * INPUTS:
- * inCertReq
- * The Certificate Request to operate on.
- * inField
- * An enumeration indicating which filed of the certificate template
- * to look for.
- * NOTES:
- * All the fields in a certificate template are optional. This function
- * checks to see if the requested field is present. Look in crmft.h at the
- * definition of CRMFCertTemplateField for possible values for possible
- * querying.
- *
- * RETURN:
- * PR_TRUE iff the field corresponding to 'inField' has been specified as part
- * of 'inCertReq'
- * PR_FALSE iff the field corresponding to 'inField' has not been speicified
- * as part of 'inCertReq'
- *
- */
-extern PRBool CRMF_DoesRequestHaveField(CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inField);
-
-/*
- * FUNCTION: CRMF_CertReqMsgGetCertRequest
- * INPUTS:
- * inCertReqMsg
- * The Certificate Request Message to operate on.
- * NOTES:
- * This function returns a copy of the Certificate Request to the user.
- * The user can keep adding to this request and then making it a part
- * of another message. After the user no longer wants to use the
- * returned request, the user must call CRMF_DestroyCertRequest and
- * pass it the request returned by this function.
- * RETURN:
- * A pointer to a copy of the certificate request contained by the message.
- * A NULL return value indicates an error occurred while copying the
- * certificate request.
- */
-extern CRMFCertRequest *
- CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg *inCertReqMsg);
-
-/*
- * FUNCTION: CRMF_CertRequestGetCertTemplateVersion
- * INPUTS:
- * inCertReq
- * The Certificate Request to operate on.
- * version
- * A pointer to where the library can store the version contatined
- * in the certificate template within the certifcate request.
- * RETURN:
- * SECSuccess if the Certificate template contains the version field. In
- * this case, *version will hold the value of the certificate template
- * version.
- * SECFailure indicates that version field was not present as part of
- * of the certificate template.
- */
-extern SECStatus
- CRMF_CertRequestGetCertTemplateVersion(CRMFCertRequest *inCertReq,
- long *version);
-
-/*
- * FUNCTION: CRMF_CertRequestGetCertTemplateSerialNumber
- * INPUTS:
- * inCertReq
- * The certificate request to operate on.
- * serialNumber
- * A pointer where the library can put the serial number contained
- * in the certificate request's certificate template.
- * RETURN:
- * If a serial number exists in the CertTemplate of the request, the function
- * returns SECSuccess and the value at *serialNumber contains the serial
- * number.
- * If no serial number is present, then the function returns SECFailure and
- * the value at *serialNumber is un-changed.
- */
-extern SECStatus
- CRMF_CertRequestGetCertTemplateSerialNumber(CRMFCertRequest *inCertReq,
- long *serialNumber);
-
-/*
- * FUNCTION: CRMF_CertRequestGetCertTemplateSigningAlg
- * INPUT:
- * inCertReq
- * The Certificate Request to operate on.
- * destAlg
- * A Pointer to where the library can place a copy of the signing alg
- * used in the cert request's cert template.
- * RETURN:
- * If the signingAlg is present in the CertRequest's CertTemplate, then
- * the function returns SECSuccess and places a copy of sigingAlg in
- * *destAlg.
- * If no signingAlg is present, then the function returns SECFailure and
- * the value at *destAlg is un-changed
- */
-extern SECStatus
- CRMF_CertRequestGetCertTemplateSigningAlg(CRMFCertRequest *inCertReq,
- SECAlgorithmID *destAlg);
-/*
- * FUNCTION: CRMF_CertRequestGetCertTemplateIssuer
- * INPUTS:
- * inCertReq
- * The Certificate Request to operate on.
- * destIssuer
- * A pointer to where the library can place a copy of the cert
- * request's cert template issuer field.
- * RETURN:
- * If the issuer is present in the cert request cert template, the function
- * returns SECSuccess and places a copy of the issuer in *destIssuer.
- * If there is no issuer present, the function returns SECFailure and the
- * value at *destIssuer is unchanged.
- */
-extern SECStatus
- CRMF_CertRequestGetCertTemplateIssuer(CRMFCertRequest *inCertReq,
- CERTName *destIssuer);
-
-/*
- * FUNCTION: CRMF_CertRequestGetCertTemplateValidity
- * INPUTS:
- * inCertReq
- * The Certificate Request to operate on.
- * destValdity
- * A pointer to where the library can place a copy of the validity
- * info in the cert request cert template.
- * NOTES:
- * Pass the pointer to
- * RETURN:
- * If there is an OptionalValidity field, the function will return SECSuccess
- * and place the appropriate values in *destValidity->notBefore and
- * *destValidity->notAfter. (Each field is optional, but at least one will
- * be present if the function returns SECSuccess)
- *
- * If there is no OptionalValidity field, the function will return SECFailure
- * and the values at *destValidity will be un-changed.
- */
-extern SECStatus
- CRMF_CertRequestGetCertTemplateValidity(CRMFCertRequest *inCertReq,
- CRMFGetValidity *destValidity);
-/*
- * FUNCTION: CRMF_DestroyGetValidity
- * INPUTS:
- * inValidity
- * A pointer to the memroy to be freed.
- * NOTES:
- * The function will free the memory allocated by the function
- * CRMF_CertRequestGetCertTemplateValidity. That means only memory pointed
- * to within the CRMFGetValidity structure. Since
- * CRMF_CertRequestGetCertTemplateValidity does not allocate memory for the
- * structure passed into it, it will not free it. Meaning this function will
- * free the memory at inValidity->notBefore and inValidity->notAfter, but not
- * the memory directly at inValdity.
- *
- * RETURN:
- * SECSuccess if freeing the memory was successful. Any other return value
- * indicates an error while freeing the memory.
- */
-extern SECStatus
- CRMF_DestroyGetValidity(CRMFGetValidity *inValidity);
-
-/*
- * FUNCTION: CRMF_CertRequestGetCertTemplateSubject
- * INPUTS:
- * inCertReq
- * The Certificate Request to operate on.
- * destSubject
- * A pointer to where the library can place a copy of the subject
- * contained in the request's cert template.
- * RETURN:
- * If there is a subject in the CertTemplate, then the function returns
- * SECSuccess and a copy of the subject is placed in *destSubject.
- *
- * If there is no subject, the function returns SECFailure and the values at
- * *destSubject is unchanged.
- */
-extern SECStatus
- CRMF_CertRequestGetCertTemplateSubject (CRMFCertRequest *inCertReq,
- CERTName *destSubject);
-
-/*
- * FUNCTION: CRMF_CertRequestGetCertTemplatePublicKey
- * INPUTS:
- * inCertReq
- * The Cert request to operate on.
- * destPublicKey
- * A pointer to where the library can place a copy of the request's
- * cert template public key.
- * RETURN:
- * If there is a publicKey parameter in the CertRequest, the function returns
- * SECSuccess, and places a copy of the publicKey in *destPublicKey.
- *
- * If there is no publicKey, the function returns SECFailure and the value
- * at *destPublicKey is un-changed.
- */
-extern SECStatus
- CRMF_CertRequestGetCertTemplatePublicKey(CRMFCertRequest *inCertReq,
- CERTSubjectPublicKeyInfo *destPublicKey);
-
-/*
- * FUNCTION: CRMF_CertRequestGetCertTemplateIssuerUID
- * INPUTS:
- * inCertReq
- * The Cert request to operate on.
- * destIssuerUID
- * A pointer to where the library can store a copy of the request's
- * cert template destIssuerUID.
- *
- * NOTES:
- * destIssuerUID is a bit string and will be returned in a SECItem as
- * a bit string. Meaning the len field contains the number of valid bits as
- * opposed to the number of bytes allocated.
- *
- * RETURN:
- * If the CertTemplate has an issuerUID, the function returns SECSuccess and
- * places a copy of the issuerUID in *destIssuerUID.
- *
- * If there is no issuerUID, the function returns SECFailure and the value
- * *destIssuerUID is unchanged.
- */
-extern SECStatus
- CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest *inCertReq,
- SECItem *destIssuerUID);
-
-/*
- * FUNCTION: CRMF_CertRequestGetCertTemplateSubjectUID
- * inCertReq
- * The Cert request to operate on.
- * destSubjectUID
- * A pointer to where the library can store a copy of the request's
- * cert template destIssuerUID.
- *
- * NOTES:
- * destSubjectUID is a bit string and will be returned in a SECItem as
- * a bit string. Meaning the len field contains the number of valid bits as
- * opposed to the number of bytes allocated.
- *
- * RETURN:
- * If the CertTemplate has an issuerUID, the function returns SECSuccess and
- * places a copy of the issuerUID in *destIssuerUID.
- *
- * If there is no issuerUID, the function returns SECSuccess and the value
- * *destIssuerUID is unchanged.
- */
-extern SECStatus CRMF_GetCertTemplateSubjectUID(CRMFCertRequest *inCertReq,
- SECItem *destSubjectUID);
-
-/*
- * FUNCTION: CRMF_CertRequestGetNumberOfExtensions
- * INPUTS:
- * inCertReq
- * The cert request to operate on.
- * RETURN:
- * Returns the number of extensions contained by the Cert Request.
- */
-extern int CRMF_CertRequestGetNumberOfExtensions(CRMFCertRequest *inCertReq);
-
-/*
- * FUNCTION: CRMF_CertRequestGetExtensionAtIndex
- * INPUTS:
- * inCertReq
- * The Certificate request to operate on.
- * index
- * The index of the extension array whihc the user wants to access.
- * NOTES:
- * This function retrieves the extension at the index corresponding to the
- * parameter "index" indicates. Indexing is done like a C array.
- * (0 ... numElements-1)
- *
- * Call CRMF_DestroyCertExtension when done using the return value.
- *
- * RETURN:
- * A pointer to a copy of the extension at the desired index. A NULL
- * return value indicates an invalid index or an error while copying
- * the extension.
- */
-extern CRMFCertExtension *
- CRMF_CertRequestGetExtensionAtIndex(CRMFCertRequest *inCertReq,
- int index);
-/*
- * FUNCTION: CRMF_CertExtensionGetOidTag
- * INPUTS:
- * inExtension
-
- * The extension to operate on.
- * RETURN:
- * Returns the SECOidTag associated with the cert extension passed in.
- */
-extern SECOidTag CRMF_CertExtensionGetOidTag(CRMFCertExtension *inExtension);
-
-/*
- * FUNCTION: CRMF_CertExtensionGetIsCritical
- * INPUT:
- * inExt
- * The cert extension to operate on.
- *
- * RETURN:
- * PR_TRUE if the extension is critical.
- * PR_FALSE if the extension is not critical.
- */
-extern PRBool CRMF_CertExtensionGetIsCritical(CRMFCertExtension *inExt);
-
-/*
- * FUNCTION: CRMF_CertExtensionGetValue
- * INPUT:
- * inExtension
- * The extension to operate on.
- * NOTES:
- * Caller is responsible for freeing the memory associated with the return
- * value. Call SECITEM_FreeItem(retVal, PR_TRUE) when done using the return
- * value.
- *
- * RETURN:
- * A pointer to an item containig the value for the certificate extension.
- * A NULL return value indicates an error in copying the information.
- */
-extern SECItem* CRMF_CertExtensionGetValue(CRMFCertExtension *inExtension);
-
-/*
- * FUNCTION: CRMF_CertReqMsgGetPOPOSigningKey
- * INPUTS:
- * inCertReqMsg
- * The certificate request message to operate on.
- * destKey
- * A pointer to where the library can place a pointer to
- * a copy of the Proof Of Possession Signing Key used
- * by the message.
- *
- * RETURN:
- * Get the POPOSigningKey associated with this CRMFCertReqMsg.
- * If the CertReqMsg does not have a pop, the function returns
- * SECFailure and the value at *destKey is un-changed..
- *
- * If the CertReqMsg does have a pop, then the CertReqMsg's
- * POPOSigningKey will be placed at *destKey.
- */
-extern SECStatus
- CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOSigningKey **destKey);
-
-/*
- * FUNCTION: CRMF_DestroyPOPOSigningKey
- * INPUTS:
- * inKey
- * The signing key to free.
- *
- * RETURN:
- * SECSuccess if freeing the memory was successful. Any other return value
- * indicates an error while freeing memory.
- */
-extern SECStatus CRMF_DestroyPOPOSigningKey (CRMFPOPOSigningKey *inKey);
-
-/*
- * FUNCTION: CRMF_POPOSigningKeyGetAlgID
- * INPUTS:
- * inSignKey
- * The Signing Key to operate on.
- * RETURN:
- * Return the algorithmID used by the CRMFPOPOSigningKey. User must
- * call SECOID_DestroyAlgorithmID(destID, PR_TRUE) when done using the
- * return value.
- */
-extern SECAlgorithmID*
- CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey *inSignKey);
-
-/*
- * FUNCTION: CRMF_POPOSigningKeyGetSignature
- * INPUTS:
- * inSignKey
- * The Signing Key to operate on.
- *
- * RETURN:
- * Get the actual signature stored away in the CRMFPOPOSigningKey. SECItem
- * returned is a BIT STRING, so the len field is the number of bits as opposed
- * to the total number of bytes allocatd. User must call
- * SECITEM_FreeItem(retVal,PR_TRUE) when done using the return value.
- */
-extern SECItem* CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey);
-
-/*
- * FUNCTION: CRMF_POPOSigningKeyGetInput
- * INPUTS:
- * inSignKey
- * The Signing Key to operate on.
- * NOTES:
- * This function will return the der encoded input that was read in while
- * decoding. The API does not support this option when creating, so you
- * cannot add this field.
- *
- * RETURN:
- * Get the poposkInput that is part of the of the POPOSigningKey. If the
- * optional field is not part of the POPOSigningKey, the function returns
- * NULL.
- *
- * If the optional field is part of the POPOSingingKey, the function will
- * return a copy of the der encoded poposkInput.
- */
-extern SECItem* CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey);
-
-/*
- * FUNCTION: CRMF_CertReqMsgGetPOPKeyEncipherment
- * INPUTS:
- * inCertReqMsg
- * The certificate request message to operate on.
- * destKey
- * A pointer to where the library can place a pointer to a
- * copy of the POPOPrivKey representing Key Encipherment
- * Proof of Possession.
- *NOTES:
- * This function gets the POPOPrivKey associated with this CRMFCertReqMsg
- * for Key Encipherment.
- *
- * RETURN:
- * If the CertReqMsg did not use Key Encipherment for Proof Of Possession, the
- * function returns SECFailure and the value at *destKey is un-changed.
- *
- * If the CertReqMsg did use Key Encipherment for ProofOfPossession, the
- * function returns SECSuccess and places the POPOPrivKey representing the
- * Key Encipherment Proof Of Possessin at *destKey.
- */
-extern SECStatus
- CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKey **destKey);
-
-/*
- * FUNCTION: CRMF_CertReqMsgGetPOPKeyAgreement
- * INPUTS:
- * inCertReqMsg
- * The certificate request message to operate on.
- * destKey
- * A pointer to where the library can place a pointer to a
- * copy of the POPOPrivKey representing Key Agreement
- * Proof of Possession.
- * NOTES:
- * This function gets the POPOPrivKey associated with this CRMFCertReqMsg for
- * Key Agreement.
- *
- * RETURN:
- * If the CertReqMsg used Key Agreement for Proof Of Possession, the
- * function returns SECSuccess and the POPOPrivKey for Key Agreement
- * is placed at *destKey.
- *
- * If the CertReqMsg did not use Key Agreement for Proof Of Possession, the
- * function return SECFailure and the value at *destKey is unchanged.
- */
-extern SECStatus
- CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKey **destKey);
-
-/*
- * FUNCTION: CRMF_DestroyPOPOPrivKey
- * INPUTS:
- * inPrivKey
- * The POPOPrivKey to destroy.
- * NOTES:
- * Destroy a structure allocated by CRMF_GetPOPKeyEncipherment or
- * CRMF_GetPOPKeyAgreement.
- *
- * RETURN:
- * SECSuccess on successful destruction of the POPOPrivKey.
- * Any other return value indicates an error in freeing the
- * memory.
- */
-extern SECStatus CRMF_DestroyPOPOPrivKey(CRMFPOPOPrivKey *inPrivKey);
-
-/*
- * FUNCTION: CRMF_POPOPrivKeyGetChoice
- * INPUT:
- * inKey
- * The POPOPrivKey to operate on.
- * RETURN:
- * Returns which choice was used in constructing the POPPOPrivKey. Look at
- * the definition of CRMFPOPOPrivKeyChoice in crmft.h for the possible return
- * values.
- */
-extern CRMFPOPOPrivKeyChoice CRMF_POPOPrivKeyGetChoice(CRMFPOPOPrivKey *inKey);
-
-/*
- * FUNCTION: CRMF_POPOPrivKeyGetThisMessage
- * INPUTS:
- * inKey
- * The POPOPrivKey to operate on.
- * destString
- * A pointer to where the library can place a copy of the This Message
- * field stored in the POPOPrivKey
- *
- * RETURN:
- * Returns the field thisMessage from the POPOPrivKey.
- * If the POPOPrivKey did not use the field thisMessage, the function
- * returns SECFailure and the value at *destString is unchanged.
- *
- * If the POPOPrivKey did use the field thisMessage, the function returns
- * SECSuccess and the BIT STRING representing thisMessage is placed
- * at *destString. BIT STRING representation means the len field is the
- * number of valid bits as opposed to the total number of bytes.
- */
-extern SECStatus CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey *inKey,
- SECItem *destString);
-
-/*
- * FUNCTION: CRMF_POPOPrivKeyGetSubseqMess
- * INPUTS:
- * inKey
- * The POPOPrivKey to operate on.
- * destOpt
- * A pointer to where the library can place the value of the
- * Subsequent Message option used by POPOPrivKey.
- *
- * RETURN:
- * Retrieves the field subsequentMessage from the POPOPrivKey.
- * If the POPOPrivKey used the subsequentMessage option, the function
- * returns SECSuccess and places the appropriate enumerated value at
- * *destMessageOption.
- *
- * If the POPOPrivKey did not use the subsequenMessage option, the function
- * returns SECFailure and the value at *destOpt is un-changed.
- */
-extern SECStatus CRMF_POPOPrivKeyGetSubseqMess(CRMFPOPOPrivKey *inKey,
- CRMFSubseqMessOptions *destOpt);
-
-/*
- * FUNCTION: CRMF_POPOPrivKeyGetDHMAC
- * INPUTS:
- * inKey
- * The POPOPrivKey to operate on.
- * destMAC
- * A pointer to where the library can place a copy of the dhMAC
- * field of the POPOPrivKey.
- *
- * NOTES:
- * Returns the field dhMAC from the POPOPrivKey. The populated SECItem
- * is in BIT STRING format.
- *
- * RETURN:
- * If the POPOPrivKey used the dhMAC option, the function returns SECSuccess
- * and the BIT STRING for dhMAC will be placed at *destMAC. The len field in
- * destMAC (ie destMAC->len) will be the valid number of bits as opposed to
- * the number of allocated bytes.
- *
- * If the POPOPrivKey did not use the dhMAC option, the function returns
- * SECFailure and the value at *destMAC is unchanged.
- *
- */
-extern SECStatus CRMF_POPOPrivKeyGetDHMAC(CRMFPOPOPrivKey *inKey,
- SECItem *destMAC);
-
-/*
- * FUNCTION: CRMF_CertRequestGetNumControls
- * INPUTS:
- * inCertReq
- * The Certificate Request to operate on.
- * RETURN:
- * Returns the number of Controls registered with this CertRequest.
- */
-extern int CRMF_CertRequestGetNumControls (CRMFCertRequest *inCertReq);
-
-/*
- * FUNCTION: CRMF_CertRequestGetControlAtIndex
- * INPUTS:
- * inCertReq
- * The certificate request to operate on.
- * index
- * The index of the control the user wants a copy of.
- * NOTES:
- * Function retrieves the Control at located at index. The Controls
- * are numbered like a traditional C array (0 ... numElements-1)
- *
- * RETURN:
- * Returns a copy of the control at the index specified. This is a copy
- * so the user must call CRMF_DestroyControl after the return value is no
- * longer needed. A return value of NULL indicates an error while copying
- * the control or that the index was invalid.
- */
-extern CRMFControl*
- CRMF_CertRequestGetControlAtIndex(CRMFCertRequest *inCertReq,
- int index);
-
-/*
- * FUNCTION: CRMF_DestroyControl
- * INPUTS:
- * inControl
- * The Control to destroy.
- * NOTES:
- * Destroy a CRMFControl allocated by CRMF_GetControlAtIndex.
- *
- * RETURN:
- * SECSuccess if freeing the memory was successful. Any other return
- * value indicates an error while freeing the memory.
- */
-extern SECStatus CRMF_DestroyControl(CRMFControl *inControl);
-
-/*
- * FUNCTION: CRMF_ControlGetControlType
- * INPUTS:
- * inControl
- * The control to operate on.
- * NOTES:
- * The function returns an enumertion which indicates the type of control
- * 'inControl'.
- *
- * RETURN:
- * Look in crmft.h at the definition of the enumerated type CRMFControlType
- * for the possible return values.
- */
-extern CRMFControlType CRMF_ControlGetControlType(CRMFControl *inControl);
-
-/*
- * FUNCTION: CRMF_ControlGetRegTokenControlValue
- * INPUTS:
- * inControl
- * The Control to operate on.
- * NOTES:
- * The user must call SECITEM_FreeItem passing in the return value
- * after the returnvalue is no longer needed.
-
- * RETURN:
- * Return the value for a Registration Token Control.
- * The SECItem returned should be in UTF8 format. A NULL
- * return value indicates there was no Registration Control associated
- * with the Control.
- * (This library will not verify format. It assumes the client properly
- * formatted the strings when adding it or the message decoded was properly
- * formatted. The library will just give back the bytes it was given.)
- */
-extern SECItem* CRMF_ControlGetRegTokenControlValue(CRMFControl *inControl);
-
-/*
- * FUNCTION: CRMF_ControlGetAuthenticatorControlValue
- * INPUTS:
- * inControl
- * The Control to operate on.
- * NOTES:
- * The user must call SECITEM_FreeItem passing in the return value
- * after the returnvalue is no longer needed.
- *
- * RETURN:
- * Return the value for the Authenticator Control.
- * The SECItem returned should be in UTF8 format. A NULL
- * return value indicates there was no Authenticator Control associated
- * with the CRMFControl..
- * (This library will not verify format. It assumes the client properly
- * formatted the strings when adding it or the message decoded was properly
- * formatted. The library will just give back the bytes it was given.)
- */
-extern SECItem* CRMF_ControlGetAuthicatorControlValue(CRMFControl *inControl);
-
-/*
- * FUNCTION: CRMF_ControlGetPKIArchiveOptions
- * INPUTS:inControl
- * The Control tooperate on.
- * NOTES:
- * This function returns a copy of the PKIArchiveOptions. The user must call
- * the function CRMF_DestroyPKIArchiveOptions when the return value is no
- * longer needed.
- *
- * RETURN:
- * Get the PKIArchiveOptions associated with the Control. A return
- * value of NULL indicates the Control was not a PKIArchiveOptions
- * Control.
- */
-extern CRMFPKIArchiveOptions*
- CRMF_ControlGetPKIArchiveOptions(CRMFControl *inControl);
-
-/*
- * FUNCTION: CMRF_DestroyPKIArchiveOptions
- * INPUTS:
- * inOptions
- * The ArchiveOptions to destroy.
- * NOTE:
- * Destroy the CRMFPKIArchiveOptions structure.
- *
- * RETURN:
- * SECSuccess if successful in freeing all the memory associated with
- * the PKIArchiveOptions. Any other return value indicates an error while
- * freeing the PKIArchiveOptions.
- */
-extern SECStatus
- CRMF_DestroyPKIArchiveOptions(CRMFPKIArchiveOptions *inOptions);
-
-/*
- * FUNCTION: CRMF_PKIArchiveOptionsGetOptionType
- * INPUTS:
- * inOptions
- * The PKIArchiveOptions to operate on.
- * RETURN:
- * Returns the choice used for the PKIArchiveOptions. Look at the definition
- * of CRMFPKIArchiveOptionsType in crmft.h for possible return values.
- */
-extern CRMFPKIArchiveOptionsType
- CRMF_PKIArchiveOptionsGetOptionType(CRMFPKIArchiveOptions *inOptions);
-
-/*
- * FUNCTION: CRMF_PKIArchiveOptionsGetEncryptedPrivKey
- * INPUTS:
- * inOpts
- * The PKIArchiveOptions to operate on.
- *
- * NOTES:
- * The user must call CRMF_DestroyEncryptedKey when done using this return
- * value.
- *
- * RETURN:
- * Get the encryptedPrivKey field of the PKIArchiveOptions structure.
- * A return value of NULL indicates that encryptedPrivKey was not used as
- * the choice for this PKIArchiveOptions.
- */
-extern CRMFEncryptedKey*
- CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions *inOpts);
-
-/*
- * FUNCTION: CRMF_EncryptedKeyGetChoice
- * INPUTS:
- * inEncrKey
- * The EncryptedKey to operate on.
- *
- * NOTES:
- * Get the choice used for representing the EncryptedKey.
- *
- * RETURN:
- * Returns the Choice used in representing the EncryptedKey. Look in
- * crmft.h at the definition of CRMFEncryptedKeyChoice for possible return
- * values.
- */
-extern CRMFEncryptedKeyChoice
- CRMF_EncryptedKeyGetChoice(CRMFEncryptedKey *inEncrKey);
-
-
-/*
- * FUNCTION: CRMF_EncryptedKeyGetEncryptedValue
- * INPUTS:
- * inKey
- * The EncryptedKey to operate on.
- *
- * NOTES:
- * The user must call CRMF_DestroyEncryptedValue passing in
- * CRMF_GetEncryptedValue's return value.
- *
- * RETURN:
- * A pointer to a copy of the EncryptedValue contained as a member of
- * the EncryptedKey.
- */
-extern CRMFEncryptedValue*
- CRMF_EncryptedKeyGetEncryptedValue(CRMFEncryptedKey *inKey);
-
-/*
- * FUNCTION: CRMF_DestroyEncryptedValue
- * INPUTS:
- * inEncrValue
- * The EncryptedValue to destroy.
- *
- * NOTES:
- * Free up all memory associated with 'inEncrValue'.
- *
- * RETURN:
- * SECSuccess if freeing up the memory associated with the EncryptedValue
- * is successful. Any other return value indicates an error while freeing the
- * memory.
- */
-extern SECStatus CRMF_DestroyEncryptedValue(CRMFEncryptedValue *inEncrValue);
-
-/*
- * FUNCTION: CRMF_EncryptedValueGetEncValue
- * INPUTS:
- * inEncValue
- * The EncryptedValue to operate on.
- * NOTES:
- * Function retrieves the encValue from an EncryptedValue structure.
- *
- * RETURN:
- * A poiner to a SECItem containing the encValue of the EncryptedValue
- * structure. The return value is in BIT STRING format, meaning the
- * len field of the return structure represents the number of valid bits
- * as opposed to the allocated number of bytes.
- * ANULL return value indicates an error in copying the encValue field.
- */
-extern SECItem* CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue *inEncValue);
-
-/*
- * FUNCTION: CRMF_EncryptedValueGetIntendedAlg
- * INPUTS
- * inEncValue
- * The EncryptedValue to operate on.
- * NOTES:
- * Retrieve the IntendedAlg field from the EncryptedValue structure.
- * Call SECOID_DestroyAlgorithmID (destAlgID, PR_TRUE) after done using
- * the return value. When present, this alogorithm is the alogrithm for
- * which the private key will be used.
- *
- * RETURN:
- * A Copy of the intendedAlg field. A NULL return value indicates the
- * optional field was not present in the structure.
- */
-extern SECAlgorithmID*
- CRMF_EncryptedValueGetIntendedAlg(CRMFEncryptedValue *inEncValue);
-
-
-/*
- * FUNCTION: CRMF_EncryptedValueGetSymmAlg
- * INPUTS
- * inEncValue
- * The EncryptedValue to operate on.
- * NOTES:
- * Retrieve the symmAlg field from the EncryptedValue structure.
- * Call SECOID_DestroyAlgorithmID (destAlgID, PR_TRUE) after done using
- * the return value. When present, this is algorithm used to
- * encrypt the encValue of the EncryptedValue.
- *
- * RETURN:
- * A Copy of the symmAlg field. A NULL return value indicates the
- * optional field was not present in the structure.
- */
-extern SECAlgorithmID*
- CRMF_EncryptedValueGetSymmAlg(CRMFEncryptedValue *inEncValue);
-
-
-/*
- * FUNCTION: CRMF_EncryptedValueGetKeyAlg
- * INPUTS
- * inEncValue
- * The EncryptedValue to operate on.
- * NOTES:
- * Retrieve the keyAlg field from the EncryptedValue structure.
- * Call SECOID_DestroyAlgorithmID (destAlgID, PR_TRUE) after done using
- * the return value. When present, this is the algorithm used to encrypt
- * the symmetric key in the encSymmKey field of the EncryptedValue structure.
- *
- * RETURN:
- * A Copy of the keyAlg field. A NULL return value indicates the
- * optional field was not present in the structure.
- */
-extern SECAlgorithmID*
- CRMF_EncryptedValueGetKeyAlg(CRMFEncryptedValue *inEncValue);
-
-/*
- * FUNCTION: CRMF_EncryptedValueGetValueHint
- * INPUTS:
- * inEncValue
- * The EncryptedValue to operate on.
- *
- * NOTES:
- * Return a copy of the der-encoded value hint.
- * User must call SECITEM_FreeItem(retVal, PR_TRUE) when done using the
- * return value. When, present, this is a value that the client which
- * originally issued a certificate request can use to reproduce any data
- * it wants. The RA does not know how to interpret this data.
- *
- * RETURN:
- * A copy of the valueHint field of the EncryptedValue. A NULL return
- * value indicates the optional valueHint field is not present in the
- * EncryptedValue.
- */
-extern SECItem*
- CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue *inEncValue);
-
-/*
- * FUNCTION: CRMF_EncrypteValueGetEncSymmKey
- * INPUTS:
- * inEncValue
- * The EncryptedValue to operate on.
- *
- * NOTES:
- * Return a copy of the encSymmKey field. This field is the encrypted
- * symmetric key that the client uses in doing Public Key wrap of a private
- * key. When present, this is the symmetric key that was used to wrap the
- * private key. (The encrypted private key will be stored in encValue
- * of the same EncryptedValue structure.) The user must call
- * SECITEM_FreeItem(retVal, PR_TRUE) when the return value is no longer
- * needed.
- *
- * RETURN:
- * A copy of the optional encSymmKey field of the EncryptedValue structure.
- * The return value will be in BIT STRING format, meaning the len field will
- * be the number of valid bits as opposed to the number of bytes. A return
- * value of NULL means the optional encSymmKey field was not present in
- * the EncryptedValue structure.
- */
-extern SECItem*
- CRMF_EncryptedValueGetEncSymmKey(CRMFEncryptedValue *inEncValue);
-
-/*
- * FUNCTION: CRMF_PKIArchiveOptionsGetKeyGenParameters
- * INPUTS:
- * inOptions
- * The PKiArchiveOptions to operate on.
- *
- * NOTES:
- * User must call SECITEM_FreeItem(retVal, PR_TRUE) after the return
- * value is no longer needed.
- *
- * RETURN:
- * Get the keyGenParameters field of the PKIArchiveOptions.
- * A NULL return value indicates that keyGenParameters was not
- * used as the choice for this PKIArchiveOptions.
- *
- * The SECItem returned is in BIT STRING format (ie, the len field indicates
- * number of valid bits as opposed to allocated number of bytes.)
- */
-extern SECItem*
- CRMF_PKIArchiveOptionsGetKeyGenParameters(CRMFPKIArchiveOptions *inOptions);
-
-/*
- * FUNCTION: CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey
- * INPUTS:
- * inOpt
- * The PKIArchiveOptions to operate on.
- * destVal
- * A pointer to where the library can place the value for
- * arciveRemGenPrivKey
- * RETURN:
- * If the PKIArchiveOptions used the archiveRemGenPrivKey field, the
- * function returns SECSuccess and fills the value at *destValue with either
- * PR_TRUE or PR_FALSE, depending on what the PKIArchiveOptions has as a
- * value.
- *
- * If the PKIArchiveOptions does not use the archiveRemGenPrivKey field, the
- * function returns SECFailure and the value at *destValue is unchanged.
- */
-extern SECStatus
- CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey(CRMFPKIArchiveOptions *inOpt,
- PRBool *destVal);
-
-/* Helper functions that can be used by other libraries. */
-/*
- * A quick helper function to get the best wrap mechanism.
- */
-extern CK_MECHANISM_TYPE CRMF_GetBestWrapPadMechanism(PK11SlotInfo *slot);
-
-/*
- * A helper function to get a randomly generated IV from a mechanism
- * type.
- */
-extern SECItem* CRMF_GetIVFromMechanism(CK_MECHANISM_TYPE mechType);
-
-SEC_END_PROTOS
-#endif /*_CRMF_H_*/
-
-
diff --git a/security/nss/lib/crmf/crmfcont.c b/security/nss/lib/crmf/crmfcont.c
deleted file mode 100644
index c5ba5a897..000000000
--- a/security/nss/lib/crmf/crmfcont.c
+++ /dev/null
@@ -1,1158 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "crmf.h"
-#include "crmfi.h"
-#include "pk11func.h"
-#include "keyhi.h"
-#include "secoid.h"
-
-static SECStatus
-crmf_modify_control_array (CRMFCertRequest *inCertReq, int count)
-{
- if (count > 0) {
- void *dummy = PORT_Realloc(inCertReq->controls,
- sizeof(CRMFControl*)*(count+2));
- if (dummy == NULL) {
- return SECFailure;
- }
- inCertReq->controls = dummy;
- } else {
- inCertReq->controls = PORT_ZNewArray(CRMFControl*, 2);
- }
- return (inCertReq->controls == NULL) ? SECFailure : SECSuccess ;
-}
-
-static SECStatus
-crmf_add_new_control(CRMFCertRequest *inCertReq,SECOidTag inTag,
- CRMFControl **destControl)
-{
- SECOidData *oidData;
- SECStatus rv;
- PRArenaPool *poolp;
- int numControls = 0;
- CRMFControl *newControl;
- CRMFControl **controls;
- void *mark;
-
- poolp = inCertReq->poolp;
- if (poolp == NULL) {
- return SECFailure;
- }
- mark = PORT_ArenaMark(poolp);
- if (inCertReq->controls != NULL) {
- while (inCertReq->controls[numControls] != NULL)
- numControls++;
- }
- rv = crmf_modify_control_array(inCertReq, numControls);
- if (rv != SECSuccess) {
- goto loser;
- }
- controls = inCertReq->controls;
- oidData = SECOID_FindOIDByTag(inTag);
- newControl = *destControl = PORT_ArenaZNew(poolp,CRMFControl);
- if (newControl == NULL) {
- goto loser;
- }
- rv = SECITEM_CopyItem(poolp, &newControl->derTag, &oidData->oid);
- if (rv != SECSuccess) {
- goto loser;
- }
- newControl->tag = inTag;
- controls[numControls] = newControl;
- controls[numControls+1] = NULL;
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
- loser:
- PORT_ArenaRelease(poolp, mark);
- *destControl = NULL;
- return SECFailure;
-
-}
-
-static SECStatus
-crmf_add_secitem_control(CRMFCertRequest *inCertReq, SECItem *value,
- SECOidTag inTag)
-{
- SECStatus rv;
- CRMFControl *newControl;
- void *mark;
-
- rv = crmf_add_new_control(inCertReq, inTag, &newControl);
- if (rv != SECSuccess) {
- return rv;
- }
- mark = PORT_ArenaMark(inCertReq->poolp);
- rv = SECITEM_CopyItem(inCertReq->poolp, &newControl->derValue, value);
- if (rv != SECSuccess) {
- PORT_ArenaRelease(inCertReq->poolp, mark);
- return rv;
- }
- PORT_ArenaUnmark(inCertReq->poolp, mark);
- return SECSuccess;
-}
-
-SECStatus
-CRMF_CertRequestSetRegTokenControl(CRMFCertRequest *inCertReq, SECItem *value)
-{
- return crmf_add_secitem_control(inCertReq, value,
- SEC_OID_PKIX_REGCTRL_REGTOKEN);
-}
-
-SECStatus
-CRMF_CertRequestSetAuthenticatorControl (CRMFCertRequest *inCertReq,
- SECItem *value)
-{
- return crmf_add_secitem_control(inCertReq, value,
- SEC_OID_PKIX_REGCTRL_AUTHENTICATOR);
-}
-
-SECStatus
-crmf_destroy_encrypted_value(CRMFEncryptedValue *inEncrValue, PRBool freeit)
-{
- if (inEncrValue != NULL) {
- if (inEncrValue->intendedAlg) {
- SECOID_DestroyAlgorithmID(inEncrValue->intendedAlg, PR_TRUE);
- inEncrValue->intendedAlg = NULL;
- }
- if (inEncrValue->symmAlg) {
- SECOID_DestroyAlgorithmID(inEncrValue->symmAlg, PR_TRUE);
- inEncrValue->symmAlg = NULL;
- }
- if (inEncrValue->encSymmKey.data) {
- PORT_Free(inEncrValue->encSymmKey.data);
- inEncrValue->encSymmKey.data = NULL;
- }
- if (inEncrValue->keyAlg) {
- SECOID_DestroyAlgorithmID(inEncrValue->keyAlg, PR_TRUE);
- inEncrValue->keyAlg = NULL;
- }
- if (inEncrValue->valueHint.data) {
- PORT_Free(inEncrValue->valueHint.data);
- inEncrValue->valueHint.data = NULL;
- }
- if (inEncrValue->encValue.data) {
- PORT_Free(inEncrValue->encValue.data);
- inEncrValue->encValue.data = NULL;
- }
- if (freeit) {
- PORT_Free(inEncrValue);
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-CRMF_DestroyEncryptedValue(CRMFEncryptedValue *inEncrValue)
-{
- return crmf_destroy_encrypted_value(inEncrValue, PR_TRUE);
-}
-
-SECStatus
-crmf_copy_encryptedvalue_secalg(PRArenaPool *poolp,
- SECAlgorithmID *srcAlgId,
- SECAlgorithmID **destAlgId)
-{
- SECAlgorithmID *newAlgId;
- SECStatus rv;
-
- newAlgId = (poolp != NULL) ? PORT_ArenaZNew(poolp, SECAlgorithmID) :
- PORT_ZNew(SECAlgorithmID);
- if (newAlgId == NULL) {
- return SECFailure;
- }
-
- rv = SECOID_CopyAlgorithmID(poolp, newAlgId, srcAlgId);
- if (rv != SECSuccess) {
- if (!poolp) {
- SECOID_DestroyAlgorithmID(newAlgId, PR_TRUE);
- }
- return rv;
- }
- *destAlgId = newAlgId;
-
- return rv;
-}
-
-SECStatus
-crmf_copy_encryptedvalue(PRArenaPool *poolp,
- CRMFEncryptedValue *srcValue,
- CRMFEncryptedValue *destValue)
-{
- SECStatus rv;
-
- if (srcValue->intendedAlg != NULL) {
- rv = crmf_copy_encryptedvalue_secalg(poolp,
- srcValue->intendedAlg,
- &destValue->intendedAlg);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcValue->symmAlg != NULL) {
- rv = crmf_copy_encryptedvalue_secalg(poolp,
- srcValue->symmAlg,
- &destValue->symmAlg);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcValue->encSymmKey.data != NULL) {
- rv = crmf_make_bitstring_copy(poolp,
- &destValue->encSymmKey,
- &srcValue->encSymmKey);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcValue->keyAlg != NULL) {
- rv = crmf_copy_encryptedvalue_secalg(poolp,
- srcValue->keyAlg,
- &destValue->keyAlg);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcValue->valueHint.data != NULL) {
- rv = SECITEM_CopyItem(poolp,
- &destValue->valueHint,
- &srcValue->valueHint);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcValue->encValue.data != NULL) {
- rv = crmf_make_bitstring_copy(poolp,
- &destValue->encValue,
- &srcValue->encValue);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- return SECSuccess;
- loser:
- if (poolp == NULL && destValue != NULL) {
- crmf_destroy_encrypted_value(destValue, PR_FALSE);
- }
- return SECFailure;
-}
-
-SECStatus
-crmf_copy_encryptedkey(PRArenaPool *poolp,
- CRMFEncryptedKey *srcEncrKey,
- CRMFEncryptedKey *destEncrKey)
-{
- SECStatus rv;
- void *mark = NULL;
-
- if (poolp != NULL) {
- mark = PORT_ArenaMark(poolp);
- }
-
- switch (srcEncrKey->encKeyChoice) {
- case crmfEncryptedValueChoice:
- rv = crmf_copy_encryptedvalue(poolp,
- &srcEncrKey->value.encryptedValue,
- &destEncrKey->value.encryptedValue);
- break;
- case crmfEnvelopedDataChoice:
- destEncrKey->value.envelopedData =
- SEC_PKCS7CopyContentInfo(srcEncrKey->value.envelopedData);
- rv = (destEncrKey->value.envelopedData != NULL) ? SECSuccess:
- SECFailure;
- break;
- default:
- rv = SECFailure;
- }
- if (rv != SECSuccess) {
- goto loser;
- }
- destEncrKey->encKeyChoice = srcEncrKey->encKeyChoice;
- if (mark) {
- PORT_ArenaUnmark(poolp, mark);
- }
- return SECSuccess;
-
- loser:
- if (mark) {
- PORT_ArenaRelease(poolp, mark);
- }
- return SECFailure;
-}
-
-static CRMFPKIArchiveOptions*
-crmf_create_encr_pivkey_option(CRMFEncryptedKey *inEncryptedKey)
-{
- CRMFPKIArchiveOptions *newArchOpt;
- SECStatus rv;
-
- newArchOpt = PORT_ZNew(CRMFPKIArchiveOptions);
- if (newArchOpt == NULL) {
- goto loser;
- }
-
- rv = crmf_copy_encryptedkey(NULL, inEncryptedKey,
- &newArchOpt->option.encryptedKey);
-
- if (rv != SECSuccess) {
- goto loser;
- }
- newArchOpt->archOption = crmfEncryptedPrivateKey;
- return newArchOpt;
- loser:
- if (newArchOpt != NULL) {
- CRMF_DestroyPKIArchiveOptions(newArchOpt);
- }
- return NULL;
-}
-
-static CRMFPKIArchiveOptions*
-crmf_create_keygen_param_option(SECItem *inKeyGenParams)
-{
- CRMFPKIArchiveOptions *newArchOptions;
- SECStatus rv;
-
- newArchOptions = PORT_ZNew(CRMFPKIArchiveOptions);
- if (newArchOptions == NULL) {
- goto loser;
- }
- newArchOptions->archOption = crmfKeyGenParameters;
- rv = SECITEM_CopyItem(NULL, &newArchOptions->option.keyGenParameters,
- inKeyGenParams);
- if (rv != SECSuccess) {
- goto loser;
- }
- return newArchOptions;
- loser:
- if (newArchOptions != NULL) {
- CRMF_DestroyPKIArchiveOptions(newArchOptions);
- }
- return NULL;
-}
-
-static CRMFPKIArchiveOptions*
-crmf_create_arch_rem_gen_privkey(PRBool archiveRemGenPrivKey)
-{
- unsigned char value;
- SECItem *dummy;
- CRMFPKIArchiveOptions *newArchOptions;
-
- value = (archiveRemGenPrivKey) ? hexTrue : hexFalse;
- newArchOptions = PORT_ZNew(CRMFPKIArchiveOptions);
- if (newArchOptions == NULL) {
- goto loser;
- }
- dummy = SEC_ASN1EncodeItem(NULL,
- &newArchOptions->option.archiveRemGenPrivKey,
- &value, SEC_ASN1_GET(SEC_BooleanTemplate));
- PORT_Assert (dummy == &newArchOptions->option.archiveRemGenPrivKey);
- if (dummy != &newArchOptions->option.archiveRemGenPrivKey) {
- SECITEM_FreeItem (dummy, PR_TRUE);
- goto loser;
- }
- newArchOptions->archOption = crmfArchiveRemGenPrivKey;
- return newArchOptions;
- loser:
- if (newArchOptions != NULL) {
- CRMF_DestroyPKIArchiveOptions(newArchOptions);
- }
- return NULL;
-}
-
-CRMFPKIArchiveOptions*
-CRMF_CreatePKIArchiveOptions(CRMFPKIArchiveOptionsType inType, void *data)
-{
- CRMFPKIArchiveOptions* retOptions;
-
- PORT_Assert(data != NULL);
- if (data == NULL) {
- return NULL;
- }
- switch(inType) {
- case crmfEncryptedPrivateKey:
- retOptions = crmf_create_encr_pivkey_option((CRMFEncryptedKey*)data);
- break;
- case crmfKeyGenParameters:
- retOptions = crmf_create_keygen_param_option((SECItem*)data);
- break;
- case crmfArchiveRemGenPrivKey:
- retOptions = crmf_create_arch_rem_gen_privkey(*(PRBool*)data);
- break;
- default:
- retOptions = NULL;
- }
- return retOptions;
-}
-
-static SECStatus
-crmf_destroy_encrypted_key(CRMFEncryptedKey *inEncrKey, PRBool freeit)
-{
- PORT_Assert(inEncrKey != NULL);
- if (inEncrKey != NULL) {
- switch (inEncrKey->encKeyChoice){
- case crmfEncryptedValueChoice:
- crmf_destroy_encrypted_value(&inEncrKey->value.encryptedValue,
- PR_FALSE);
- break;
- case crmfEnvelopedDataChoice:
- SEC_PKCS7DestroyContentInfo(inEncrKey->value.envelopedData);
- break;
- default:
- break;
- }
- if (freeit) {
- PORT_Free(inEncrKey);
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-crmf_destroy_pkiarchiveoptions(CRMFPKIArchiveOptions *inArchOptions,
- PRBool freeit)
-{
- PORT_Assert(inArchOptions != NULL);
- if (inArchOptions != NULL) {
- switch (inArchOptions->archOption) {
- case crmfEncryptedPrivateKey:
- crmf_destroy_encrypted_key(&inArchOptions->option.encryptedKey,
- PR_FALSE);
- break;
- case crmfKeyGenParameters:
- case crmfArchiveRemGenPrivKey:
- /* This is a union, so having a pointer to one is like
- * having a pointer to both.
- */
- SECITEM_FreeItem(&inArchOptions->option.keyGenParameters,
- PR_FALSE);
- break;
- case crmfNoArchiveOptions:
- break;
- }
- if (freeit) {
- PORT_Free(inArchOptions);
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-CRMF_DestroyPKIArchiveOptions(CRMFPKIArchiveOptions *inArchOptions)
-{
- return crmf_destroy_pkiarchiveoptions(inArchOptions, PR_TRUE);
-}
-
-static CK_MECHANISM_TYPE
-crmf_get_non_pad_mechanism(CK_MECHANISM_TYPE type)
-{
- switch (type) {
- case CKM_DES3_CBC_PAD:
- return CKM_DES3_CBC;
- case CKM_CAST5_CBC_PAD:
- return CKM_CAST5_CBC;
- case CKM_DES_CBC_PAD:
- return CKM_DES_CBC;
- case CKM_IDEA_CBC_PAD:
- return CKM_IDEA_CBC;
- case CKM_CAST3_CBC_PAD:
- return CKM_CAST3_CBC;
- case CKM_CAST_CBC_PAD:
- return CKM_CAST_CBC;
- case CKM_RC5_CBC_PAD:
- return CKM_RC5_CBC;
- case CKM_RC2_CBC_PAD:
- return CKM_RC2_CBC;
- case CKM_CDMF_CBC_PAD:
- return CKM_CDMF_CBC;
- }
- return type;
-}
-
-static CK_MECHANISM_TYPE
-crmf_get_pad_mech_from_tag(SECOidTag oidTag)
-{
- CK_MECHANISM_TYPE mechType;
- SECOidData *oidData;
-
- oidData = SECOID_FindOIDByTag(oidTag);
- mechType = (CK_MECHANISM_TYPE)oidData->mechanism;
- return PK11_GetPadMechanism(mechType);
-}
-
-static CK_MECHANISM_TYPE
-crmf_get_best_privkey_wrap_mechanism(PK11SlotInfo *slot)
-{
- CK_MECHANISM_TYPE privKeyPadMechs[] = { CKM_DES3_CBC_PAD,
- CKM_CAST5_CBC_PAD,
- CKM_DES_CBC_PAD,
- CKM_IDEA_CBC_PAD,
- CKM_CAST3_CBC_PAD,
- CKM_CAST_CBC_PAD,
- CKM_RC5_CBC_PAD,
- CKM_RC2_CBC_PAD,
- CKM_CDMF_CBC_PAD };
- int mechCount = sizeof(privKeyPadMechs)/sizeof(privKeyPadMechs[0]);
- int i;
-
- for (i=0; i < mechCount; i++) {
- if (PK11_DoesMechanism(slot, privKeyPadMechs[i])) {
- return privKeyPadMechs[i];
- }
- }
- return CKM_INVALID_MECHANISM;
-}
-
-CK_MECHANISM_TYPE
-CRMF_GetBestWrapPadMechanism(PK11SlotInfo *slot)
-{
- return crmf_get_best_privkey_wrap_mechanism(slot);
-}
-
-static SECItem*
-crmf_get_iv(CK_MECHANISM_TYPE mechType)
-{
- int iv_size = PK11_GetIVLength(mechType);
- SECItem *iv;
- SECStatus rv;
-
- iv = PORT_ZNew(SECItem);
- if (iv == NULL) {
- return NULL;
- }
- if (iv_size == 0) {
- iv->data = NULL;
- iv->len = 0;
- return iv;
- }
- iv->data = PORT_NewArray(unsigned char, iv_size);
- if (iv->data == NULL) {
- iv->len = 0;
- return iv;
- }
- iv->len = iv_size;
- rv = PK11_GenerateRandom(iv->data, iv->len);
- if (rv != SECSuccess) {
- PORT_Free(iv->data);
- iv->data = NULL;
- iv->len = 0;
- }
- return iv;
-}
-
-SECItem*
-CRMF_GetIVFromMechanism(CK_MECHANISM_TYPE mechType)
-{
- return crmf_get_iv(mechType);
-}
-
-CK_MECHANISM_TYPE
-crmf_get_mechanism_from_public_key(SECKEYPublicKey *inPubKey)
-{
- CERTSubjectPublicKeyInfo *spki = NULL;
- SECOidTag tag;
-
-
- spki = SECKEY_CreateSubjectPublicKeyInfo(inPubKey);
- if (spki == NULL) {
- return CKM_INVALID_MECHANISM;
- }
- tag = SECOID_FindOIDTag(&spki->algorithm.algorithm);
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- spki = NULL;
- return PK11_AlgtagToMechanism(tag);
-}
-
-SECItem*
-crmf_get_public_value(SECKEYPublicKey *pubKey, SECItem *dest)
-{
- SECItem *src;
-
- switch(pubKey->keyType) {
- case dsaKey:
- src = &pubKey->u.dsa.publicValue;
- break;
- case rsaKey:
- src = &pubKey->u.rsa.modulus;
- break;
- case dhKey:
- src = &pubKey->u.dh.publicValue;
- break;
- default:
- src = NULL;
- break;
- }
- if (!src) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- if (dest != NULL) {
- SECStatus rv = SECITEM_CopyItem(NULL, dest, src);
- if (rv != SECSuccess) {
- dest = NULL;
- }
- } else {
- dest = SECITEM_ArenaDupItem(NULL, src);
- }
- return dest;
-}
-
-static SECItem*
-crmf_decode_params(SECItem *inParams)
-{
- SECItem *params;
- SECStatus rv = SECFailure;
- PRArenaPool *poolp;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return NULL;
- }
-
- params = PORT_ArenaZNew(poolp, SECItem);
- if (params) {
- rv = SEC_ASN1DecodeItem(poolp, params,
- SEC_ASN1_GET(SEC_OctetStringTemplate),
- inParams);
- }
- params = (rv == SECSuccess) ? SECITEM_ArenaDupItem(NULL, params) : NULL;
- PORT_FreeArena(poolp, PR_FALSE);
- return params;
-}
-
-static int
-crmf_get_key_size_from_mech(CK_MECHANISM_TYPE mechType)
-{
- CK_MECHANISM_TYPE keyGen = PK11_GetKeyGen(mechType);
-
- switch (keyGen) {
- case CKM_CDMF_KEY_GEN:
- case CKM_DES_KEY_GEN:
- return 8;
- case CKM_DES2_KEY_GEN:
- return 16;
- case CKM_DES3_KEY_GEN:
- return 24;
- }
- return 0;
-}
-
-SECStatus
-crmf_encrypted_value_unwrap_priv_key(PRArenaPool *poolp,
- CRMFEncryptedValue *encValue,
- SECKEYPrivateKey *privKey,
- SECKEYPublicKey *newPubKey,
- SECItem *nickname,
- PK11SlotInfo *slot,
- unsigned char keyUsage,
- SECKEYPrivateKey **unWrappedKey,
- void *wincx)
-{
- PK11SymKey *wrappingKey = NULL;
- CK_MECHANISM_TYPE wrapMechType;
- SECOidTag oidTag;
- SECItem *params = NULL, *publicValue = NULL;
- int keySize, origLen;
- CK_KEY_TYPE keyType;
- CK_ATTRIBUTE_TYPE *usage = NULL;
- CK_ATTRIBUTE_TYPE rsaUsage[] = {
- CKA_UNWRAP, CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER };
- CK_ATTRIBUTE_TYPE dsaUsage[] = { CKA_SIGN };
- CK_ATTRIBUTE_TYPE dhUsage[] = { CKA_DERIVE };
- int usageCount = 0;
-
- oidTag = SECOID_GetAlgorithmTag(encValue->symmAlg);
- wrapMechType = crmf_get_pad_mech_from_tag(oidTag);
- keySize = crmf_get_key_size_from_mech(wrapMechType);
- wrappingKey = PK11_PubUnwrapSymKey(privKey, &encValue->encSymmKey,
- wrapMechType, CKA_UNWRAP, keySize);
- if (wrappingKey == NULL) {
- goto loser;
- }/* Make the length a byte length instead of bit length*/
- params = (encValue->symmAlg != NULL) ?
- crmf_decode_params(&encValue->symmAlg->parameters) : NULL;
- origLen = encValue->encValue.len;
- encValue->encValue.len = CRMF_BITS_TO_BYTES(origLen);
- publicValue = crmf_get_public_value(newPubKey, NULL);
- switch(newPubKey->keyType) {
- default:
- case rsaKey:
- keyType = CKK_RSA;
- switch (keyUsage & (KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE)) {
- case KU_KEY_ENCIPHERMENT:
- usage = rsaUsage;
- usageCount = 2;
- break;
- case KU_DIGITAL_SIGNATURE:
- usage = &rsaUsage[2];
- usageCount = 2;
- break;
- case KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE:
- case 0: /* default to everything */
- usage = rsaUsage;
- usageCount = 4;
- break;
- }
- break;
- case dhKey:
- keyType = CKK_DH;
- usage = dhUsage;
- usageCount = sizeof(dhUsage)/sizeof(dhUsage[0]);
- break;
- case dsaKey:
- keyType = CKK_DSA;
- usage = dsaUsage;
- usageCount = sizeof(dsaUsage)/sizeof(dsaUsage[0]);
- break;
- }
- PORT_Assert(usage != NULL);
- PORT_Assert(usageCount != 0);
- *unWrappedKey = PK11_UnwrapPrivKey(slot, wrappingKey, wrapMechType, params,
- &encValue->encValue, nickname,
- publicValue, PR_TRUE,PR_TRUE,
- keyType, usage, usageCount, wincx);
- encValue->encValue.len = origLen;
- if (*unWrappedKey == NULL) {
- goto loser;
- }
- SECITEM_FreeItem (publicValue, PR_TRUE);
- if (params!= NULL) {
- SECITEM_FreeItem(params, PR_TRUE);
- }
- PK11_FreeSymKey(wrappingKey);
- return SECSuccess;
- loser:
- *unWrappedKey = NULL;
- return SECFailure;
-}
-
-CRMFEncryptedValue *
-crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inCAKey,
- CRMFEncryptedValue *destValue)
-{
- SECItem wrappedPrivKey, wrappedSymKey;
- SECItem encodedParam, *dummy;
- SECStatus rv;
- CK_MECHANISM_TYPE pubMechType, symKeyType;
- unsigned char *wrappedSymKeyBits;
- unsigned char *wrappedPrivKeyBits;
- SECItem *iv = NULL;
- SECOidTag tag;
- PK11SymKey *symKey;
- PK11SlotInfo *slot;
- SECAlgorithmID *symmAlg;
- CRMFEncryptedValue *myEncrValue = NULL;
-
- encodedParam.data = NULL;
- wrappedSymKeyBits = PORT_NewArray(unsigned char, MAX_WRAPPED_KEY_LEN);
- wrappedPrivKeyBits = PORT_NewArray(unsigned char, MAX_WRAPPED_KEY_LEN);
- if (wrappedSymKeyBits == NULL || wrappedPrivKeyBits == NULL) {
- goto loser;
- }
- if (destValue == NULL) {
- myEncrValue = destValue = PORT_ZNew(CRMFEncryptedValue);
- if (destValue == NULL) {
- goto loser;
- }
- }
-
- pubMechType = crmf_get_mechanism_from_public_key(inCAKey);
- if (pubMechType == CKM_INVALID_MECHANISM) {
- /* XXX I should probably do something here for non-RSA
- * keys that are in certs. (ie DSA)
- * XXX or at least SET AN ERROR CODE.
- */
- goto loser;
- }
- slot = inPrivKey->pkcs11Slot;
- PORT_Assert(slot != NULL);
- symKeyType = crmf_get_best_privkey_wrap_mechanism(slot);
- symKey = PK11_KeyGen(slot, symKeyType, NULL, 0, NULL);
- if (symKey == NULL) {
- goto loser;
- }
-
- wrappedSymKey.data = wrappedSymKeyBits;
- wrappedSymKey.len = MAX_WRAPPED_KEY_LEN;
- rv = PK11_PubWrapSymKey(pubMechType, inCAKey, symKey, &wrappedSymKey);
- if (rv != SECSuccess) {
- goto loser;
- }
- /* Make the length of the result a Bit String length. */
- wrappedSymKey.len <<= 3;
-
- wrappedPrivKey.data = wrappedPrivKeyBits;
- wrappedPrivKey.len = MAX_WRAPPED_KEY_LEN;
- iv = crmf_get_iv(symKeyType);
- rv = PK11_WrapPrivKey(slot, symKey, inPrivKey, symKeyType, iv,
- &wrappedPrivKey, NULL);
- PK11_FreeSymKey(symKey);
- if (rv != SECSuccess) {
- goto loser;
- }
- /* Make the length of the result a Bit String length. */
- wrappedPrivKey.len <<= 3;
- rv = crmf_make_bitstring_copy(NULL,
- &destValue->encValue,
- &wrappedPrivKey);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = crmf_make_bitstring_copy(NULL,
- &destValue->encSymmKey,
- &wrappedSymKey);
- if (rv != SECSuccess) {
- goto loser;
- }
- destValue->symmAlg = symmAlg = PORT_ZNew(SECAlgorithmID);
- if (symmAlg == NULL) {
- goto loser;
- }
-
- dummy = SEC_ASN1EncodeItem(NULL, &encodedParam, iv,
- SEC_ASN1_GET(SEC_OctetStringTemplate));
- if (dummy != &encodedParam) {
- SECITEM_FreeItem(dummy, PR_TRUE);
- goto loser;
- }
-
- symKeyType = crmf_get_non_pad_mechanism(symKeyType);
- tag = PK11_MechanismToAlgtag(symKeyType);
- rv = SECOID_SetAlgorithmID(NULL, symmAlg, tag, &encodedParam);
- if (rv != SECSuccess) {
- goto loser;
- }
- SECITEM_FreeItem(&encodedParam, PR_FALSE);
- PORT_Free(wrappedPrivKeyBits);
- PORT_Free(wrappedSymKeyBits);
- SECITEM_FreeItem(iv, PR_TRUE);
- return destValue;
- loser:
- if (iv != NULL) {
- SECITEM_FreeItem(iv, PR_TRUE);
- }
- if (myEncrValue != NULL) {
- crmf_destroy_encrypted_value(myEncrValue, PR_TRUE);
- }
- if (wrappedSymKeyBits != NULL) {
- PORT_Free(wrappedSymKeyBits);
- }
- if (wrappedPrivKeyBits != NULL) {
- PORT_Free(wrappedPrivKeyBits);
- }
- if (encodedParam.data != NULL) {
- SECITEM_FreeItem(&encodedParam, PR_FALSE);
- }
- return NULL;
-}
-
-CRMFEncryptedKey*
-CRMF_CreateEncryptedKeyWithEncryptedValue (SECKEYPrivateKey *inPrivKey,
- CERTCertificate *inCACert)
-{
- SECKEYPublicKey *caPubKey = NULL;
- CRMFEncryptedKey *encKey = NULL;
- CRMFEncryptedValue *dummy;
-
- PORT_Assert(inPrivKey != NULL && inCACert != NULL);
- if (inPrivKey == NULL || inCACert == NULL) {
- return NULL;
- }
-
- caPubKey = CERT_ExtractPublicKey(inCACert);
- if (caPubKey == NULL) {
- goto loser;
- }
-
- encKey = PORT_ZNew(CRMFEncryptedKey);
- if (encKey == NULL) {
- goto loser;
- }
- dummy = crmf_create_encrypted_value_wrapped_privkey(inPrivKey,
- caPubKey,
- &encKey->value.encryptedValue);
- PORT_Assert(dummy == &encKey->value.encryptedValue);
- /* We won't add the der value here, but rather when it
- * becomes part of a certificate request.
- */
- SECKEY_DestroyPublicKey(caPubKey);
- encKey->encKeyChoice = crmfEncryptedValueChoice;
- return encKey;
- loser:
- if (encKey != NULL) {
- CRMF_DestroyEncryptedKey(encKey);
- }
- if (caPubKey != NULL) {
- SECKEY_DestroyPublicKey(caPubKey);
- }
- return NULL;
-}
-
-SECStatus
-CRMF_DestroyEncryptedKey(CRMFEncryptedKey *inEncrKey)
-{
- return crmf_destroy_encrypted_key(inEncrKey, PR_TRUE);
-}
-
-SECStatus
-crmf_copy_pkiarchiveoptions(PRArenaPool *poolp,
- CRMFPKIArchiveOptions *destOpt,
- CRMFPKIArchiveOptions *srcOpt)
-{
- SECStatus rv;
- destOpt->archOption = srcOpt->archOption;
- switch (srcOpt->archOption) {
- case crmfEncryptedPrivateKey:
- rv = crmf_copy_encryptedkey(poolp,
- &srcOpt->option.encryptedKey,
- &destOpt->option.encryptedKey);
- break;
- case crmfKeyGenParameters:
- case crmfArchiveRemGenPrivKey:
- /* We've got a union, so having a pointer to one is just
- * like having a pointer to the other one.
- */
- rv = SECITEM_CopyItem(poolp,
- &destOpt->option.keyGenParameters,
- &srcOpt->option.keyGenParameters);
- break;
- default:
- rv = SECFailure;
- }
- return rv;
-}
-
-static SECStatus
-crmf_check_and_adjust_archoption(CRMFControl *inControl)
-{
- CRMFPKIArchiveOptions *options;
-
- options = &inControl->value.archiveOptions;
- if (options->archOption == crmfNoArchiveOptions) {
- /* It hasn't been set, so figure it out from the
- * der.
- */
- switch (inControl->derValue.data[0] & 0x0f) {
- case 0:
- options->archOption = crmfEncryptedPrivateKey;
- break;
- case 1:
- options->archOption = crmfKeyGenParameters;
- break;
- case 2:
- options->archOption = crmfArchiveRemGenPrivKey;
- break;
- default:
- /* We've got bad DER. Return an error. */
- return SECFailure;
- }
- }
- return SECSuccess;
-}
-
-static const SEC_ASN1Template *
-crmf_get_pkiarchive_subtemplate(CRMFControl *inControl)
-{
- const SEC_ASN1Template *retTemplate;
- SECStatus rv;
- /*
- * We could be in the process of decoding, in which case the
- * archOption field will not be set. Let's check it and set
- * it accordingly.
- */
-
- rv = crmf_check_and_adjust_archoption(inControl);
- if (rv != SECSuccess) {
- return NULL;
- }
-
- switch (inControl->value.archiveOptions.archOption) {
- case crmfEncryptedPrivateKey:
- retTemplate = CRMFEncryptedKeyWithEncryptedValueTemplate;
- inControl->value.archiveOptions.option.encryptedKey.encKeyChoice =
- crmfEncryptedValueChoice;
- break;
- default:
- retTemplate = NULL;
- }
- return retTemplate;
-}
-
-const SEC_ASN1Template*
-crmf_get_pkiarchiveoptions_subtemplate(CRMFControl *inControl)
-{
- const SEC_ASN1Template *retTemplate;
-
- switch (inControl->tag) {
- case SEC_OID_PKIX_REGCTRL_REGTOKEN:
- case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
- retTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate);
- break;
- case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
- retTemplate = crmf_get_pkiarchive_subtemplate(inControl);
- break;
- case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
- case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
- case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
- /* We don't support these controls, so we fail for now.*/
- retTemplate = NULL;
- break;
- default:
- retTemplate = NULL;
- }
- return retTemplate;
-}
-
-static SECStatus
-crmf_encode_pkiarchiveoptions(PRArenaPool *poolp, CRMFControl *inControl)
-{
- const SEC_ASN1Template *asn1Template;
-
- asn1Template = crmf_get_pkiarchiveoptions_subtemplate(inControl);
- /* We've got a union, so passing a pointer to one element of the
- * union, is the same as passing a pointer to any of the other
- * members of the union.
- */
- SEC_ASN1EncodeItem(poolp, &inControl->derValue,
- &inControl->value.archiveOptions, asn1Template);
-
- if (inControl->derValue.data == NULL) {
- goto loser;
- }
- return SECSuccess;
- loser:
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertRequestSetPKIArchiveOptions(CRMFCertRequest *inCertReq,
- CRMFPKIArchiveOptions *inOptions)
-{
- CRMFControl *newControl;
- PRArenaPool *poolp;
- SECStatus rv;
- void *mark;
-
- PORT_Assert(inCertReq != NULL && inOptions != NULL);
- if (inCertReq == NULL || inOptions == NULL) {
- return SECFailure;
- }
- poolp = inCertReq->poolp;
- mark = PORT_ArenaMark(poolp);
- rv = crmf_add_new_control(inCertReq,
- SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS,
- &newControl);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = crmf_copy_pkiarchiveoptions(poolp,
- &newControl->value.archiveOptions,
- inOptions);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = crmf_encode_pkiarchiveoptions(poolp, newControl);
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-static SECStatus
-crmf_destroy_control(CRMFControl *inControl, PRBool freeit)
-{
- PORT_Assert(inControl != NULL);
- if (inControl != NULL) {
- SECITEM_FreeItem(&inControl->derTag, PR_FALSE);
- SECITEM_FreeItem(&inControl->derValue, PR_FALSE);
- /* None of the other tags require special processing at
- * the moment when freeing because they are not supported,
- * but if/when they are, add the necessary routines here.
- * If all controls are supported, then every member of the
- * union inControl->value will have a case that deals with
- * it in the following switch statement.
- */
- switch (inControl->tag) {
- case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
- crmf_destroy_pkiarchiveoptions(&inControl->value.archiveOptions,
- PR_FALSE);
- break;
- default:
- /* Put this here to get rid of all those annoying warnings.*/
- break;
- }
- if (freeit) {
- PORT_Free(inControl);
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-CRMF_DestroyControl(CRMFControl *inControl)
-{
- return crmf_destroy_control(inControl, PR_TRUE);
-}
-
-static SECOidTag
-crmf_controltype_to_tag(CRMFControlType inControlType)
-{
- SECOidTag retVal;
-
- switch(inControlType) {
- case crmfRegTokenControl:
- retVal = SEC_OID_PKIX_REGCTRL_REGTOKEN;
- break;
- case crmfAuthenticatorControl:
- retVal = SEC_OID_PKIX_REGCTRL_AUTHENTICATOR;
- break;
- case crmfPKIPublicationInfoControl:
- retVal = SEC_OID_PKIX_REGCTRL_PKIPUBINFO;
- break;
- case crmfPKIArchiveOptionsControl:
- retVal = SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS;
- break;
- case crmfOldCertIDControl:
- retVal = SEC_OID_PKIX_REGCTRL_OLD_CERT_ID;
- break;
- case crmfProtocolEncrKeyControl:
- retVal = SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY;
- break;
- default:
- retVal = SEC_OID_UNKNOWN;
- break;
- }
- return retVal;
-}
-
-PRBool
-CRMF_CertRequestIsControlPresent(CRMFCertRequest *inCertReq,
- CRMFControlType inControlType)
-{
- SECOidTag controlTag;
- int i;
-
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL || inCertReq->controls == NULL) {
- return PR_FALSE;
- }
- controlTag = crmf_controltype_to_tag(inControlType);
- for (i=0; inCertReq->controls[i] != NULL; i++) {
- if (inCertReq->controls[i]->tag == controlTag) {
- return PR_TRUE;
- }
- }
- return PR_FALSE;
-}
-
diff --git a/security/nss/lib/crmf/crmfdec.c b/security/nss/lib/crmf/crmfdec.c
deleted file mode 100644
index cfc2fbfdc..000000000
--- a/security/nss/lib/crmf/crmfdec.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#include "crmf.h"
-#include "crmfi.h"
-#include "secitem.h"
-
-static CRMFPOPChoice
-crmf_get_popchoice_from_der(SECItem *derPOP)
-{
- CRMFPOPChoice retChoice;
-
- switch (derPOP->data[0] & 0x0f) {
- case 0:
- retChoice = crmfRAVerified;
- break;
- case 1:
- retChoice = crmfSignature;
- break;
- case 2:
- retChoice = crmfKeyEncipherment;
- break;
- case 3:
- retChoice = crmfKeyAgreement;
- break;
- default:
- retChoice = crmfNoPOPChoice;
- break;
- }
- return retChoice;
-}
-
-static SECStatus
-crmf_decode_process_raverified(CRMFCertReqMsg *inCertReqMsg)
-{
- CRMFProofOfPossession *pop;
- /* Just set up the structure so that the message structure
- * looks like one that was created using the API
- */
- pop = inCertReqMsg->pop;
- pop->popChoice.raVerified.data = NULL;
- pop->popChoice.raVerified.len = 0;
- return SECSuccess;
-}
-
-static SECStatus
-crmf_decode_process_signature(CRMFCertReqMsg *inCertReqMsg)
-{
- PORT_Assert(inCertReqMsg->poolp);
- if (!inCertReqMsg->poolp) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- return SEC_ASN1Decode(inCertReqMsg->poolp,
- &inCertReqMsg->pop->popChoice.signature,
- CRMFPOPOSigningKeyTemplate,
- (const char*)inCertReqMsg->derPOP.data,
- inCertReqMsg->derPOP.len);
-}
-
-static CRMFPOPOPrivKeyChoice
-crmf_get_messagechoice_from_der(SECItem *derPOP)
-{
- CRMFPOPOPrivKeyChoice retChoice;
-
- switch (derPOP->data[2] & 0x0f) {
- case 0:
- retChoice = crmfThisMessage;
- break;
- case 1:
- retChoice = crmfSubsequentMessage;
- break;
- case 2:
- retChoice = crmfDHMAC;
- break;
- default:
- retChoice = crmfNoMessage;
- }
- return retChoice;
-}
-
-static SECStatus
-crmf_decode_process_popoprivkey(CRMFCertReqMsg *inCertReqMsg)
-{
- /* We've got a union, so a pointer to one POPOPrivKey
- * struct is the same as having a pointer to the other
- * one.
- */
- CRMFPOPOPrivKey *popoPrivKey =
- &inCertReqMsg->pop->popChoice.keyEncipherment;
- SECItem *derPOP, privKeyDer;
- SECStatus rv;
-
- derPOP = &inCertReqMsg->derPOP;
- popoPrivKey->messageChoice = crmf_get_messagechoice_from_der(derPOP);
- if (popoPrivKey->messageChoice == crmfNoMessage) {
- return SECFailure;
- }
- /* If we ever encounter BER encodings of this, we'll get in trouble*/
- switch (popoPrivKey->messageChoice) {
- case crmfThisMessage:
- case crmfDHMAC:
- privKeyDer.type = derPOP->type;
- privKeyDer.data = &derPOP->data[5];
- privKeyDer.len = derPOP->len - 5;
- break;
- case crmfSubsequentMessage:
- privKeyDer.type = derPOP->type;
- privKeyDer.data = &derPOP->data[4];
- privKeyDer.len = derPOP->len - 4;
- break;
- default:
- return SECFailure;
- }
-
- rv = SECITEM_CopyItem(inCertReqMsg->poolp,
- &popoPrivKey->message.subsequentMessage,
- &privKeyDer);
-
- if (rv != SECSuccess) {
- return rv;
- }
-
- if (popoPrivKey->messageChoice == crmfThisMessage ||
- popoPrivKey->messageChoice == crmfDHMAC) {
-
- popoPrivKey->message.thisMessage.len =
- CRMF_BYTES_TO_BITS(privKeyDer.len) - (int)derPOP->data[4];
-
- }
- return SECSuccess;
-}
-
-static SECStatus
-crmf_decode_process_keyagreement(CRMFCertReqMsg *inCertReqMsg)
-{
- return crmf_decode_process_popoprivkey(inCertReqMsg);
-}
-
-static SECStatus
-crmf_decode_process_keyencipherment(CRMFCertReqMsg *inCertReqMsg)
-{
- SECStatus rv;
-
- rv = crmf_decode_process_popoprivkey(inCertReqMsg);
- if (rv != SECSuccess) {
- return rv;
- }
- if (inCertReqMsg->pop->popChoice.keyEncipherment.messageChoice ==
- crmfDHMAC) {
- /* Key Encipherment can not use the dhMAC option for
- * POPOPrivKey.
- */
- return SECFailure;
- }
- return SECSuccess;
-}
-
-static SECStatus
-crmf_decode_process_pop(CRMFCertReqMsg *inCertReqMsg)
-{
- SECItem *derPOP;
- PRArenaPool *poolp;
- CRMFProofOfPossession *pop;
- void *mark;
- SECStatus rv;
-
- derPOP = &inCertReqMsg->derPOP;
- poolp = inCertReqMsg->poolp;
- if (derPOP->data == NULL) {
- /* There is no Proof of Possession field in this message. */
- return SECSuccess;
- }
- mark = PORT_ArenaMark(poolp);
- pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
- if (pop == NULL) {
- goto loser;
- }
- pop->popUsed = crmf_get_popchoice_from_der(derPOP);
- if (pop->popUsed == crmfNoPOPChoice) {
- /* A bad encoding of CRMF. Not a valid tag was given to the
- * Proof Of Possession field.
- */
- goto loser;
- }
- inCertReqMsg->pop = pop;
- switch (pop->popUsed) {
- case crmfRAVerified:
- rv = crmf_decode_process_raverified(inCertReqMsg);
- break;
- case crmfSignature:
- rv = crmf_decode_process_signature(inCertReqMsg);
- break;
- case crmfKeyEncipherment:
- rv = crmf_decode_process_keyencipherment(inCertReqMsg);
- break;
- case crmfKeyAgreement:
- rv = crmf_decode_process_keyagreement(inCertReqMsg);
- break;
- default:
- rv = SECFailure;
- }
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
- loser:
- PORT_ArenaRelease(poolp, mark);
- inCertReqMsg->pop = NULL;
- return SECFailure;
-
-}
-
-static SECStatus
-crmf_decode_process_single_control(PRArenaPool *poolp,
- CRMFControl *inControl)
-{
- const SEC_ASN1Template *asn1Template = NULL;
-
- inControl->tag = SECOID_FindOIDTag(&inControl->derTag);
- asn1Template = crmf_get_pkiarchiveoptions_subtemplate(inControl);
-
- PORT_Assert (asn1Template != NULL);
- PORT_Assert (poolp != NULL);
- if (!asn1Template || !poolp) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* We've got a union, so passing a pointer to one element of the
- * union is the same as passing a pointer to any of the other
- * members of the union.
- */
- return SEC_ASN1Decode(poolp, &inControl->value.archiveOptions,
- asn1Template, (const char*)inControl->derValue.data,
- inControl->derValue.len);
-}
-
-static SECStatus
-crmf_decode_process_controls(CRMFCertReqMsg *inCertReqMsg)
-{
- int i, numControls;
- SECStatus rv;
- PRArenaPool *poolp;
- CRMFControl **controls;
-
- numControls = CRMF_CertRequestGetNumControls(inCertReqMsg->certReq);
- controls = inCertReqMsg->certReq->controls;
- poolp = inCertReqMsg->poolp;
- for (i=0; i < numControls; i++) {
- rv = crmf_decode_process_single_control(poolp, controls[i]);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- }
- return SECSuccess;
-}
-
-static SECStatus
-crmf_decode_process_single_reqmsg(CRMFCertReqMsg *inCertReqMsg)
-{
- SECStatus rv;
-
- rv = crmf_decode_process_pop(inCertReqMsg);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = crmf_decode_process_controls(inCertReqMsg);
- if (rv != SECSuccess) {
- goto loser;
- }
- inCertReqMsg->certReq->certTemplate.numExtensions =
- CRMF_CertRequestGetNumberOfExtensions(inCertReqMsg->certReq);
- inCertReqMsg->isDecoded = PR_TRUE;
- rv = SECSuccess;
- loser:
- return rv;
-}
-
-CRMFCertReqMsg*
-CRMF_CreateCertReqMsgFromDER (const char * buf, long len)
-{
- PRArenaPool *poolp;
- CRMFCertReqMsg *certReqMsg;
- SECStatus rv;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- goto loser;
- }
- certReqMsg = PORT_ArenaZNew (poolp, CRMFCertReqMsg);
- if (certReqMsg == NULL) {
- goto loser;
- }
- certReqMsg->poolp = poolp;
- rv = SEC_ASN1Decode(poolp, certReqMsg, CRMFCertReqMsgTemplate, buf, len);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = crmf_decode_process_single_reqmsg(certReqMsg);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- return certReqMsg;
- loser:
- if (poolp != NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return NULL;
-}
-
-CRMFCertReqMessages*
-CRMF_CreateCertReqMessagesFromDER(const char *buf, long len)
-{
- long arenaSize;
- int i;
- SECStatus rv;
- PRArenaPool *poolp;
- CRMFCertReqMessages *certReqMsgs;
-
- PORT_Assert (buf != NULL);
- /* Wanna make sure the arena is big enough to store all of the requests
- * coming in. We'll guestimate according to the length of the buffer.
- */
- arenaSize = len + len/2;
- poolp = PORT_NewArena(arenaSize);
- if (poolp == NULL) {
- return NULL;
- }
- certReqMsgs = PORT_ArenaZNew(poolp, CRMFCertReqMessages);
- if (certReqMsgs == NULL) {
- goto loser;
- }
- certReqMsgs->poolp = poolp;
- rv = SEC_ASN1Decode(poolp, certReqMsgs, CRMFCertReqMessagesTemplate,
- buf, len);
- if (rv != SECSuccess) {
- goto loser;
- }
- for (i=0; certReqMsgs->messages[i] != NULL; i++) {
- /* The sub-routines expect the individual messages to have
- * an arena. We'll give them one temporarily.
- */
- certReqMsgs->messages[i]->poolp = poolp;
- rv = crmf_decode_process_single_reqmsg(certReqMsgs->messages[i]);
- if (rv != SECSuccess) {
- goto loser;
- }
- certReqMsgs->messages[i]->poolp = NULL;
- }
- return certReqMsgs;
-
- loser:
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
-}
diff --git a/security/nss/lib/crmf/crmfenc.c b/security/nss/lib/crmf/crmfenc.c
deleted file mode 100644
index bf3601836..000000000
--- a/security/nss/lib/crmf/crmfenc.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#include "crmf.h"
-#include "crmfi.h"
-
-SECStatus
-CRMF_EncodeCertReqMsg(CRMFCertReqMsg *inCertReqMsg,
- CRMFEncoderOutputCallback fn,
- void *arg)
-{
- struct crmfEncoderOutput output;
-
- output.fn = fn;
- output.outputArg = arg;
- return SEC_ASN1Encode(inCertReqMsg,CRMFCertReqMsgTemplate,
- crmf_encoder_out, &output);
-
-}
-
-
-SECStatus
-CRMF_EncodeCertRequest(CRMFCertRequest *inCertReq,
- CRMFEncoderOutputCallback fn,
- void *arg)
-{
- struct crmfEncoderOutput output;
-
- output.fn = fn;
- output.outputArg = arg;
- return SEC_ASN1Encode(inCertReq, CRMFCertRequestTemplate,
- crmf_encoder_out, &output);
-}
-
-SECStatus
-CRMF_EncodeCertReqMessages(CRMFCertReqMsg **inCertReqMsgs,
- CRMFEncoderOutputCallback fn,
- void *arg)
-{
- struct crmfEncoderOutput output;
- CRMFCertReqMessages msgs;
-
- output.fn = fn;
- output.outputArg = arg;
- msgs.messages = inCertReqMsgs;
- return SEC_ASN1Encode(&msgs, CRMFCertReqMessagesTemplate,
- crmf_encoder_out, &output);
-}
-
-
-
-
diff --git a/security/nss/lib/crmf/crmffut.h b/security/nss/lib/crmf/crmffut.h
deleted file mode 100644
index bde8241f0..000000000
--- a/security/nss/lib/crmf/crmffut.h
+++ /dev/null
@@ -1,361 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * These functions to be implemented in the future if the features
- * which these functions would implement wind up being needed.
- */
-
-/*
- * Use this function to create the CRMFSinglePubInfo* variables that will
- * populate the inPubInfoArray parameter for the function
- * CRMF_CreatePKIPublicationInfo.
- *
- * "inPubMethod" specifies which publication method will be used
- * "pubLocation" is a representation of the location where
- */
-extern CRMFSinglePubInfo*
- CRMF_CreateSinglePubInfo(CRMFPublicationMethod inPubMethod,
- CRMFGeneralName *pubLocation);
-
-/*
- * Create a PKIPublicationInfo that can later be passed to the function
- * CRMFAddPubInfoControl.
- */
-extern CRMFPKIPublicationInfo *
- CRMF_CreatePKIPublicationInfo(CRMFPublicationAction inAction,
- CRMFSinglePubInfo **inPubInfoArray,
- int numPubInfo);
-
-/*
- * Only call this function on a CRMFPublicationInfo that was created by
- * CRMF_CreatePKIPublicationInfo that was passed in NULL for arena.
- */
-
-extern SECStatus
- CRMF_DestroyPKIPublicationInfo(CRMFPKIPublicationInfo *inPubInfo);
-
-extern SECStatus CRMF_AddPubInfoControl(CRMFCertRequest *inCertReq,
- CRMFPKIPublicationInfo *inPubInfo);
-
-/*
- * This is to create a Cert ID Control which can later be added to
- * a certificate request.
- */
-extern CRMFCertID* CRMF_CreateCertID(CRMFGeneralName *issuer,
- long serialNumber);
-
-extern SECStatus CRMF_DestroyCertID(CRMFCertID* certID);
-
-extern SECStatus CRMF_AddCertIDControl(CRMFCertRequest *inCertReq,
- CRMFCertID *certID);
-
-extern SECStatus
- CRMF_AddProtocolEncryptioKeyControl(CRMFCertRequest *inCertReq,
- CERTSubjectPublicKeyInfo *spki);
-
-/*
- * Add the ASCII Pairs Registration Info to the Certificate Request.
- * The SECItem must be an OCTET string representation.
- */
-extern SECStatus
- CRMF_AddUTF8PairsRegInfo(CRMFCertRequest *inCertReq,
- SECItem *asciiPairs);
-
-/*
- * This takes a CertRequest and adds it to another CertRequest.
- */
-extern SECStatus
- CRMF_AddCertReqToRegInfo(CRMFCertRequest *certReqToAddTo,
- CRMFCertRequest *certReqBeingAdded);
-
-/*
- * Returns which option was used for the authInfo field of POPOSigningKeyInput
- */
-extern CRMFPOPOSkiInputAuthChoice
- CRMF_GetSignKeyInputAuthChoice(CRMFPOPOSigningKeyInput *inKeyInput);
-
-/*
- * Gets the PKMACValue associated with the POPOSigningKeyInput.
- * If the POPOSigningKeyInput did not use authInfo.publicKeyMAC
- * the function returns SECFailure and the value at *destValue is unchanged.
- *
- * If the POPOSigningKeyInput did use authInfo.publicKeyMAC, the function
- * returns SECSuccess and places the PKMACValue at *destValue.
- */
-extern SECStatus
- CRMF_GetSignKeyInputPKMACValue(CRMFPOPOSigningKeyInput *inKeyInput,
- CRMFPKMACValue **destValue);
-/*
- * Gets the SubjectPublicKeyInfo from the POPOSigningKeyInput
- */
-extern CERTSubjectPublicKeyInfo *
- CRMF_GetSignKeyInputPublicKey(CRMFPOPOSigningKeyInput *inKeyInput);
-
-
-/*
- * Return the value for the PKIPublicationInfo Control.
- * A return value of NULL indicates that the Control was
- * not a PKIPublicationInfo Control. Call
- * CRMF_DestroyPKIPublicationInfo on the return value when done
- * using the pointer.
- */
-extern CRMFPKIPublicationInfo* CRMF_GetPKIPubInfo(CRMFControl *inControl);
-
-/*
- * Free up a CRMFPKIPublicationInfo structure.
- */
-extern SECStatus
- CRMF_DestroyPKIPublicationInfo(CRMFPKIPublicationInfo *inPubInfo);
-
-/*
- * Get the choice used for action in this PKIPublicationInfo.
- */
-extern CRMFPublicationAction
- CRMF_GetPublicationAction(CRMFPKIPublicationInfo *inPubInfo);
-
-/*
- * Get the number of pubInfos are stored in the PKIPubicationInfo.
- */
-extern int CRMF_GetNumPubInfos(CRMFPKIPublicationInfo *inPubInfo);
-
-/*
- * Get the pubInfo at index for the given PKIPubicationInfo.
- * Indexing is done like a traditional C Array. (0 .. numElements-1)
- */
-extern CRMFSinglePubInfo*
- CRMF_GetPubInfoAtIndex(CRMFPKIPublicationInfo *inPubInfo,
- int index);
-
-/*
- * Destroy the CRMFSinglePubInfo.
- */
-extern SECStatus CRMF_DestroySinglePubInfo(CRMFSinglePubInfo *inPubInfo);
-
-/*
- * Get the pubMethod used by the SinglePubInfo.
- */
-extern CRMFPublicationMethod
- CRMF_GetPublicationMethod(CRMFSinglePubInfo *inPubInfo);
-
-/*
- * Get the pubLocation associated with the SinglePubInfo.
- * A NULL return value indicates there was no pubLocation associated
- * with the SinglePuInfo.
- */
-extern CRMFGeneralName* CRMF_GetPubLocation(CRMFSinglePubInfo *inPubInfo);
-
-/*
- * Get the authInfo.sender field out of the POPOSigningKeyInput.
- * If the POPOSigningKeyInput did not use the authInfo the function
- * returns SECFailure and the value at *destName is unchanged.
- *
- * If the POPOSigningKeyInput did use authInfo.sender, the function returns
- * SECSuccess and puts the authInfo.sender at *destName/
- */
-extern SECStatus CRMF_GetSignKeyInputSender(CRMFPOPOSigningKeyInput *keyInput,
- CRMFGeneralName **destName);
-
-/**************** CMMF Functions that need to be added. **********************/
-
-/*
- * FUNCTION: CMMF_POPODecKeyChallContentSetNextChallenge
- * INPUTS:
- * inDecKeyChall
- * The CMMFPOPODecKeyChallContent to operate on.
- * inRandom
- * The random number to use when generating the challenge,
- * inSender
- * The GeneralName representation of the sender of the challenge.
- * inPubKey
- * The public key to use when encrypting the challenge.
- * NOTES:
- * This function adds a challenge to the end of the list of challenges
- * contained by 'inDecKeyChall'. Refer to the CMMF draft on how the
- * the random number passed in and the sender's GeneralName are used
- * to generate the challenge and witness fields of the challenge. This
- * library will use SHA1 as the one-way function for generating the
- * witess field of the challenge.
- *
- * RETURN:
- * SECSuccess if generating the challenge and adding to the end of list
- * of challenges was successful. Any other return value indicates an error
- * while trying to generate the challenge.
- */
-extern SECStatus
-CMMF_POPODecKeyChallContentSetNextChallenge
- (CMMFPOPODecKeyChallContent *inDecKeyChall,
- long inRandom,
- CERTGeneralName *inSender,
- SECKEYPublicKey *inPubKey);
-
-/*
- * FUNCTION: CMMF_POPODecKeyChallContentGetNumChallenges
- * INPUTS:
- * inKeyChallCont
- * The CMMFPOPODecKeyChallContent to operate on.
- * RETURN:
- * This function returns the number of CMMFChallenges are contained in
- * the CMMFPOPODecKeyChallContent structure.
- */
-extern int CMMF_POPODecKeyChallContentGetNumChallenges
- (CMMFPOPODecKeyChallContent *inKeyChallCont);
-
-/*
- * FUNCTION: CMMF_ChallengeGetRandomNumber
- * INPUTS:
- * inChallenge
- * The CMMFChallenge to operate on.
- * inDest
- * A pointer to a user supplied buffer where the library
- * can place a copy of the random integer contatained in the
- * challenge.
- * NOTES:
- * This function returns the value held in the decrypted Rand structure
- * corresponding to the random integer. The user must call
- * CMMF_ChallengeDecryptWitness before calling this function. Call
- * CMMF_ChallengeIsDecrypted to find out if the challenge has been
- * decrypted.
- *
- * RETURN:
- * SECSuccess indicates the witness field has been previously decrypted
- * and the value for the random integer was successfully placed at *inDest.
- * Any other return value indicates an error and that the value at *inDest
- * is not a valid value.
- */
-extern SECStatus CMMF_ChallengeGetRandomNumber(CMMFChallenge *inChallenge,
- long *inDest);
-
-/*
- * FUNCTION: CMMF_ChallengeGetSender
- * INPUTS:
- * inChallenge
- * the CMMFChallenge to operate on.
- * NOTES:
- * This function returns the value held in the decrypted Rand structure
- * corresponding to the sender. The user must call
- * CMMF_ChallengeDecryptWitness before calling this function. Call
- * CMMF_ChallengeIsDecrypted to find out if the witness field has been
- * decrypted. The user must call CERT_DestroyGeneralName after the return
- * value is no longer needed.
- *
- * RETURN:
- * A pointer to a copy of the sender CERTGeneralName. A return value of
- * NULL indicates an error in trying to copy the information or that the
- * witness field has not been decrypted.
- */
-extern CERTGeneralName* CMMF_ChallengeGetSender(CMMFChallenge *inChallenge);
-
-/*
- * FUNCTION: CMMF_ChallengeGetAlgId
- * INPUTS:
- * inChallenge
- * The CMMFChallenge to operate on.
- * inDestAlgId
- * A pointer to memory where a pointer to a copy of the algorithm
- * id can be placed.
- * NOTES:
- * This function retrieves the one way function algorithm identifier
- * contained within the CMMFChallenge if the optional field is present.
- *
- * RETURN:
- * SECSucces indicates the function was able to place a pointer to a copy of
- * the alogrithm id at *inAlgId. If the value at *inDestAlgId is NULL,
- * that means there was no algorithm identifier present in the
- * CMMFChallenge. Any other return value indicates the function was not
- * able to make a copy of the algorithm identifier. In this case the value
- * at *inDestAlgId is not valid.
- */
-extern SECStatus CMMF_ChallengeGetAlgId(CMMFChallenge *inChallenge,
- SECAlgorithmID *inAlgId);
-
-/*
- * FUNCTION: CMMF_DestroyChallenge
- * INPUTS:
- * inChallenge
- * The CMMFChallenge to free up.
- * NOTES:
- * This function frees up all the memory associated with the CMMFChallenge
- * passed in.
- * RETURN:
- * SECSuccess if freeing all the memory associated with the CMMFChallenge
- * passed in is successful. Any other return value indicates an error
- * while freeing the memory.
- */
-extern SECStatus CMMF_DestroyChallenge (CMMFChallenge *inChallenge);
-
-/*
- * FUNCTION: CMMF_DestroyPOPODecKeyRespContent
- * INPUTS:
- * inDecKeyResp
- * The CMMFPOPODecKeyRespContent structure to free.
- * NOTES:
- * This function frees up all the memory associate with the
- * CMMFPOPODecKeyRespContent.
- *
- * RETURN:
- * SECSuccess if freeint up all the memory associated with the
- * CMMFPOPODecKeyRespContent structure is successful. Any other
- * return value indicates an error while freeing the memory.
- */
-extern SECStatus
- CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp);
-
-/*
- * FUNCTION: CMMF_ChallengeDecryptWitness
- * INPUTS:
- * inChallenge
- * The CMMFChallenge to operate on.
- * inPrivKey
- * The private key to use to decrypt the witness field.
- * NOTES:
- * This function uses the private key to decrypt the challenge field
- * contained in the CMMFChallenge. Make sure the private key matches the
- * public key that was used to encrypt the witness. The creator of
- * the challenge will most likely be an RA that has the public key
- * from a Cert request. So the private key should be the private key
- * associated with public key in that request. This function will also
- * verify the witness field of the challenge.
- *
- * RETURN:
- * SECSuccess if decrypting the witness field was successful. This does
- * not indicate that the decrypted data is valid, since the private key
- * passed in may not be the actual key needed to properly decrypt the
- * witness field. Meaning that there is a decrypted structure now, but
- * may be garbage because the private key was incorrect.
- * Any other return value indicates the function could not complete the
- * decryption process.
- */
-extern SECStatus CMMF_ChallengeDecryptWitness(CMMFChallenge *inChallenge,
- SECKEYPrivateKey *inPrivKey);
-
-/*
- * FUNCTION: CMMF_ChallengeIsDecrypted
- * INPUTS:
- * inChallenge
- * The CMMFChallenge to operate on.
- * RETURN:
- * This is a predicate function that returns PR_TRUE if the decryption
- * process has already been performed. The function return PR_FALSE if
- * the decryption process has not been performed yet.
- */
-extern PRBool CMMF_ChallengeIsDecrypted(CMMFChallenge *inChallenge);
-
-/*
- * FUNCTION: CMMF_DestroyPOPODecKeyChallContent
- * INPUTS:
- * inDecKeyCont
- * The CMMFPOPODecKeyChallContent to free
- * NOTES:
- * This function frees up all the memory associated with the
- * CMMFPOPODecKeyChallContent
- * RETURN:
- * SECSuccess if freeing up all the memory associatd with the
- * CMMFPOPODecKeyChallContent is successful. Any other return value
- * indicates an error while freeing the memory.
- *
- */
-extern SECStatus
- CMMF_DestroyPOPODecKeyChallContent (CMMFPOPODecKeyChallContent *inDecKeyCont);
-
diff --git a/security/nss/lib/crmf/crmfget.c b/security/nss/lib/crmf/crmfget.c
deleted file mode 100644
index a2d1dd28e..000000000
--- a/security/nss/lib/crmf/crmfget.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "crmf.h"
-#include "crmfi.h"
-#include "keyhi.h"
-#include "secder.h"
-
-
-CRMFPOPChoice
-CRMF_CertReqMsgGetPOPType(CRMFCertReqMsg *inCertReqMsg)
-{
- PORT_Assert(inCertReqMsg != NULL);
- if (inCertReqMsg != NULL && inCertReqMsg->pop != NULL) {
- return inCertReqMsg->pop->popUsed;
- }
- return crmfNoPOPChoice;
-}
-
-static SECStatus
-crmf_destroy_validity(CRMFOptionalValidity *inValidity, PRBool freeit)
-{
- if (inValidity != NULL){
- if (inValidity->notBefore.data != NULL) {
- PORT_Free(inValidity->notBefore.data);
- }
- if (inValidity->notAfter.data != NULL) {
- PORT_Free(inValidity->notAfter.data);
- }
- if (freeit) {
- PORT_Free(inValidity);
- }
- }
- return SECSuccess;
-}
-
-static SECStatus
-crmf_copy_cert_request_validity(PRArenaPool *poolp,
- CRMFOptionalValidity **destValidity,
- CRMFOptionalValidity *srcValidity)
-{
- CRMFOptionalValidity *myValidity = NULL;
- SECStatus rv;
-
- *destValidity = myValidity = (poolp == NULL) ?
- PORT_ZNew(CRMFOptionalValidity) :
- PORT_ArenaZNew(poolp, CRMFOptionalValidity);
- if (myValidity == NULL) {
- goto loser;
- }
- if (srcValidity->notBefore.data != NULL) {
- rv = SECITEM_CopyItem(poolp, &myValidity->notBefore,
- &srcValidity->notBefore);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcValidity->notAfter.data != NULL) {
- rv = SECITEM_CopyItem(poolp, &myValidity->notAfter,
- &srcValidity->notAfter);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- return SECSuccess;
- loser:
- if (myValidity != NULL && poolp == NULL) {
- crmf_destroy_validity(myValidity, PR_TRUE);
- }
- return SECFailure;
-}
-
-static SECStatus
-crmf_copy_extensions(PRArenaPool *poolp,
- CRMFCertTemplate *destTemplate,
- CRMFCertExtension **srcExt)
-{
- int numExt = 0, i;
- CRMFCertExtension **myExtArray = NULL;
-
- while (srcExt[numExt] != NULL) {
- numExt++;
- }
- if (numExt == 0) {
- /*No extensions to copy.*/
- destTemplate->extensions = NULL;
- destTemplate->numExtensions = 0;
- return SECSuccess;
- }
- destTemplate->extensions = myExtArray =
- PORT_NewArray(CRMFCertExtension*, numExt+1);
- if (myExtArray == NULL) {
- goto loser;
- }
-
- for (i=0; i<numExt; i++) {
- myExtArray[i] = crmf_copy_cert_extension(poolp, srcExt[i]);
- if (myExtArray[i] == NULL) {
- goto loser;
- }
- }
- destTemplate->numExtensions = numExt;
- myExtArray[numExt] = NULL;
- return SECSuccess;
- loser:
- if (myExtArray != NULL) {
- if (poolp == NULL) {
- for (i=0; myExtArray[i] != NULL; i++) {
- CRMF_DestroyCertExtension(myExtArray[i]);
- }
- }
- PORT_Free(myExtArray);
- }
- destTemplate->extensions = NULL;
- destTemplate->numExtensions = 0;
- return SECFailure;
-}
-
-static SECStatus
-crmf_copy_cert_request_template(PRArenaPool *poolp,
- CRMFCertTemplate *destTemplate,
- CRMFCertTemplate *srcTemplate)
-{
- SECStatus rv;
-
- if (srcTemplate->version.data != NULL) {
- rv = SECITEM_CopyItem(poolp, &destTemplate->version,
- &srcTemplate->version);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcTemplate->serialNumber.data != NULL) {
- rv = SECITEM_CopyItem(poolp, &destTemplate->serialNumber,
- &srcTemplate->serialNumber);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcTemplate->signingAlg != NULL) {
- rv = crmf_template_copy_secalg(poolp, &destTemplate->signingAlg,
- srcTemplate->signingAlg);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcTemplate->issuer != NULL) {
- rv = crmf_copy_cert_name(poolp, &destTemplate->issuer,
- srcTemplate->issuer);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcTemplate->validity != NULL) {
- rv = crmf_copy_cert_request_validity(poolp, &destTemplate->validity,
- srcTemplate->validity);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcTemplate->subject != NULL) {
- rv = crmf_copy_cert_name(poolp, &destTemplate->subject,
- srcTemplate->subject);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcTemplate->publicKey != NULL) {
- rv = crmf_template_add_public_key(poolp, &destTemplate->publicKey,
- srcTemplate->publicKey);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcTemplate->issuerUID.data != NULL) {
- rv = crmf_make_bitstring_copy(poolp, &destTemplate->issuerUID,
- &srcTemplate->issuerUID);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcTemplate->subjectUID.data != NULL) {
- rv = crmf_make_bitstring_copy(poolp, &destTemplate->subjectUID,
- &srcTemplate->subjectUID);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (srcTemplate->extensions != NULL) {
- rv = crmf_copy_extensions(poolp, destTemplate,
- srcTemplate->extensions);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- return SECSuccess;
- loser:
- return SECFailure;
-}
-
-static CRMFControl*
-crmf_copy_control(PRArenaPool *poolp, CRMFControl *srcControl)
-{
- CRMFControl *newControl;
- SECStatus rv;
-
- newControl = (poolp == NULL) ? PORT_ZNew(CRMFControl) :
- PORT_ArenaZNew(poolp, CRMFControl);
- if (newControl == NULL) {
- goto loser;
- }
- newControl->tag = srcControl->tag;
- rv = SECITEM_CopyItem(poolp, &newControl->derTag, &srcControl->derTag);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECITEM_CopyItem(poolp, &newControl->derValue, &srcControl->derValue);
- if (rv != SECSuccess) {
- goto loser;
- }
- /* We only handle PKIArchiveOptions Control right now. But if in
- * the future, more controls that are part of the union are added,
- * then they need to be handled here as well.
- */
- switch (newControl->tag) {
- case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
- rv = crmf_copy_pkiarchiveoptions(poolp,
- &newControl->value.archiveOptions,
- &srcControl->value.archiveOptions);
- break;
- default:
- rv = SECSuccess;
- }
- if (rv != SECSuccess) {
- goto loser;
- }
- return newControl;
-
- loser:
- if (poolp == NULL && newControl != NULL) {
- CRMF_DestroyControl(newControl);
- }
- return NULL;
-}
-
-static SECStatus
-crmf_copy_cert_request_controls(PRArenaPool *poolp,
- CRMFCertRequest *destReq,
- CRMFCertRequest *srcReq)
-{
- int numControls, i;
- CRMFControl **myControls = NULL;
-
- numControls = CRMF_CertRequestGetNumControls(srcReq);
- if (numControls == 0) {
- /* No Controls To Copy*/
- return SECSuccess;
- }
- myControls = destReq->controls = PORT_NewArray(CRMFControl*,
- numControls+1);
- if (myControls == NULL) {
- goto loser;
- }
- for (i=0; i<numControls; i++) {
- myControls[i] = crmf_copy_control(poolp, srcReq->controls[i]);
- if (myControls[i] == NULL) {
- goto loser;
- }
- }
- myControls[numControls] = NULL;
- return SECSuccess;
- loser:
- if (myControls != NULL) {
- if (poolp == NULL) {
- for (i=0; myControls[i] != NULL; i++) {
- CRMF_DestroyControl(myControls[i]);
- }
- }
- PORT_Free(myControls);
- }
- return SECFailure;
-}
-
-
-CRMFCertRequest*
-crmf_copy_cert_request(PRArenaPool *poolp, CRMFCertRequest *srcReq)
-{
- CRMFCertRequest *newReq = NULL;
- SECStatus rv;
-
- if (srcReq == NULL) {
- return NULL;
- }
- newReq = (poolp == NULL) ? PORT_ZNew(CRMFCertRequest) :
- PORT_ArenaZNew(poolp, CRMFCertRequest);
- if (newReq == NULL) {
- goto loser;
- }
- rv = SECITEM_CopyItem(poolp, &newReq->certReqId, &srcReq->certReqId);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = crmf_copy_cert_request_template(poolp, &newReq->certTemplate,
- &srcReq->certTemplate);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = crmf_copy_cert_request_controls(poolp, newReq, srcReq);
- if (rv != SECSuccess) {
- goto loser;
- }
- return newReq;
- loser:
- if (newReq != NULL && poolp == NULL) {
- CRMF_DestroyCertRequest(newReq);
- PORT_Free(newReq);
- }
- return NULL;
-}
-
-SECStatus
-CRMF_DestroyGetValidity(CRMFGetValidity *inValidity)
-{
- PORT_Assert(inValidity != NULL);
- if (inValidity != NULL) {
- if (inValidity->notAfter) {
- PORT_Free(inValidity->notAfter);
- inValidity->notAfter = NULL;
- }
- if (inValidity->notBefore) {
- PORT_Free(inValidity->notBefore);
- inValidity->notBefore = NULL;
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-crmf_make_bitstring_copy(PRArenaPool *arena, SECItem *dest, SECItem *src)
-{
- int origLenBits;
- int bytesToCopy;
- SECStatus rv;
-
- origLenBits = src->len;
- bytesToCopy = CRMF_BITS_TO_BYTES(origLenBits);
- src->len = bytesToCopy;
- rv = SECITEM_CopyItem(arena, dest, src);
- src->len = origLenBits;
- if (rv != SECSuccess) {
- return rv;
- }
- dest->len = origLenBits;
- return SECSuccess;
-}
-
-int
-CRMF_CertRequestGetNumberOfExtensions(CRMFCertRequest *inCertReq)
-{
- CRMFCertTemplate *certTemplate;
- int count = 0;
-
- certTemplate = &inCertReq->certTemplate;
- if (certTemplate->extensions) {
- while (certTemplate->extensions[count] != NULL)
- count++;
- }
- return count;
-}
-
-SECOidTag
-CRMF_CertExtensionGetOidTag(CRMFCertExtension *inExtension)
-{
- PORT_Assert(inExtension != NULL);
- if (inExtension == NULL) {
- return SEC_OID_UNKNOWN;
- }
- return SECOID_FindOIDTag(&inExtension->id);
-}
-
-PRBool
-CRMF_CertExtensionGetIsCritical(CRMFCertExtension *inExt)
-{
- PORT_Assert(inExt != NULL);
- if (inExt == NULL) {
- return PR_FALSE;
- }
- return inExt->critical.data != NULL;
-}
-
-SECItem*
-CRMF_CertExtensionGetValue(CRMFCertExtension *inExtension)
-{
- PORT_Assert(inExtension != NULL);
- if (inExtension == NULL) {
- return NULL;
- }
-
- return SECITEM_DupItem(&inExtension->value);
-}
-
-
-SECStatus
-CRMF_DestroyPOPOSigningKey(CRMFPOPOSigningKey *inKey)
-{
- PORT_Assert(inKey != NULL);
- if (inKey != NULL) {
- if (inKey->derInput.data != NULL) {
- SECITEM_FreeItem(&inKey->derInput, PR_FALSE);
- }
- if (inKey->algorithmIdentifier != NULL) {
- SECOID_DestroyAlgorithmID(inKey->algorithmIdentifier, PR_TRUE);
- }
- if (inKey->signature.data != NULL) {
- SECITEM_FreeItem(&inKey->signature, PR_FALSE);
- }
- PORT_Free(inKey);
- }
- return SECSuccess;
-}
-
-SECStatus
-CRMF_DestroyPOPOPrivKey(CRMFPOPOPrivKey *inPrivKey)
-{
- PORT_Assert(inPrivKey != NULL);
- if (inPrivKey != NULL) {
- SECITEM_FreeItem(&inPrivKey->message.thisMessage, PR_FALSE);
- PORT_Free(inPrivKey);
- }
- return SECSuccess;
-}
-
-int
-CRMF_CertRequestGetNumControls(CRMFCertRequest *inCertReq)
-{
- int count = 0;
-
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return 0;
- }
- if (inCertReq->controls) {
- while (inCertReq->controls[count] != NULL)
- count++;
- }
- return count;
-}
-
diff --git a/security/nss/lib/crmf/crmfi.h b/security/nss/lib/crmf/crmfi.h
deleted file mode 100644
index fcde0aca1..000000000
--- a/security/nss/lib/crmf/crmfi.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#ifndef _CRMFI_H_
-#define _CRMFI_H_
-/* This file will contain all declarations common to both
- * encoding and decoding of CRMF Cert Requests. This header
- * file should only be included internally by CRMF implementation
- * files.
- */
-#include "secasn1.h"
-#include "crmfit.h"
-#include "secerr.h"
-#include "blapit.h"
-
-#define CRMF_DEFAULT_ARENA_SIZE 1024
-
-/*
- * Explanation for the definition of MAX_WRAPPED_KEY_LEN:
- *
- * It's used for internal buffers to transport a wrapped private key.
- * The value is in BYTES.
- * We want to define a reasonable upper bound for this value.
- * Ideally this could be calculated, but in order to simplify the code
- * we want to estimate the maximum requires size.
- * See also bug 655850 for the full explanation.
- *
- * We know the largest wrapped keys are RSA keys.
- * We'll estimate the maximum size needed for wrapped RSA keys,
- * and assume it's sufficient for wrapped keys of any type we support.
- *
- * The maximum size of RSA keys in bits is defined elsewhere as
- * RSA_MAX_MODULUS_BITS
- *
- * The idea is to define MAX_WRAPPED_KEY_LEN based on the above.
- *
- * A wrapped RSA key requires about
- * ( ( RSA_MAX_MODULUS_BITS / 8 ) * 5.5) + 65
- * bytes.
- *
- * Therefore, a safe upper bound is:
- * ( ( RSA_MAX_MODULUS_BITS / 8 ) *8 ) = RSA_MAX_MODULUS_BITS
- *
- */
-#define MAX_WRAPPED_KEY_LEN RSA_MAX_MODULUS_BITS
-
-#define CRMF_BITS_TO_BYTES(bits) (((bits)+7)/8)
-#define CRMF_BYTES_TO_BITS(bytes) ((bytes)*8)
-
-struct crmfEncoderArg {
- SECItem *buffer;
- long allocatedLen;
-};
-
-struct crmfEncoderOutput {
- CRMFEncoderOutputCallback fn;
- void *outputArg;
-};
-
-/*
- * This function is used by the API for encoding functions that are
- * exposed through the API, ie all of the CMMF_Encode* and CRMF_Encode*
- * functions.
- */
-extern void
- crmf_encoder_out(void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind);
-
-/*
- * This function is used when we want to encode something locally within
- * the library, ie the CertRequest so that we can produce its signature.
- */
-extern SECStatus
- crmf_init_encoder_callback_arg (struct crmfEncoderArg *encoderArg,
- SECItem *derDest);
-
-/*
- * This is the callback function we feed to the ASN1 encoder when doing
- * internal DER-encodings. ie, encoding the cert request so we can
- * produce a signature.
- */
-extern void
-crmf_generic_encoder_callback(void *arg, const char* buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind);
-
-/* The ASN1 templates that need to be seen by internal files
- * in order to implement CRMF.
- */
-extern const SEC_ASN1Template CRMFCertReqMsgTemplate[];
-extern const SEC_ASN1Template CRMFRAVerifiedTemplate[];
-extern const SEC_ASN1Template CRMFPOPOSigningKeyTemplate[];
-extern const SEC_ASN1Template CRMFPOPOKeyEnciphermentTemplate[];
-extern const SEC_ASN1Template CRMFPOPOKeyAgreementTemplate[];
-extern const SEC_ASN1Template CRMFThisMessageTemplate[];
-extern const SEC_ASN1Template CRMFSubsequentMessageTemplate[];
-extern const SEC_ASN1Template CRMFDHMACTemplate[];
-extern const SEC_ASN1Template CRMFEncryptedKeyWithEncryptedValueTemplate[];
-extern const SEC_ASN1Template CRMFEncryptedValueTemplate[];
-
-/*
- * Use these two values for encoding Boolean values.
- */
-extern const unsigned char hexTrue;
-extern const unsigned char hexFalse;
-/*
- * Prototypes for helper routines used internally by multiple files.
- */
-extern SECStatus crmf_encode_integer(PRArenaPool *poolp, SECItem *dest,
- long value);
-extern SECStatus crmf_make_bitstring_copy(PRArenaPool *arena, SECItem *dest,
- SECItem *src);
-
-extern SECStatus crmf_copy_pkiarchiveoptions(PRArenaPool *poolp,
- CRMFPKIArchiveOptions *destOpt,
- CRMFPKIArchiveOptions *srcOpt);
-extern SECStatus
- crmf_destroy_pkiarchiveoptions(CRMFPKIArchiveOptions *inArchOptions,
- PRBool freeit);
-extern const SEC_ASN1Template*
- crmf_get_pkiarchiveoptions_subtemplate(CRMFControl *inControl);
-
-extern SECStatus crmf_copy_encryptedkey(PRArenaPool *poolp,
- CRMFEncryptedKey *srcEncrKey,
- CRMFEncryptedKey *destEncrKey);
-extern SECStatus
-crmf_copy_encryptedvalue(PRArenaPool *poolp,
- CRMFEncryptedValue *srcValue,
- CRMFEncryptedValue *destValue);
-
-extern SECStatus
-crmf_copy_encryptedvalue_secalg(PRArenaPool *poolp,
- SECAlgorithmID *srcAlgId,
- SECAlgorithmID **destAlgId);
-
-extern SECStatus crmf_template_copy_secalg(PRArenaPool *poolp,
- SECAlgorithmID **dest,
- SECAlgorithmID *src);
-
-extern SECStatus crmf_copy_cert_name(PRArenaPool *poolp, CERTName **dest,
- CERTName *src);
-
-extern SECStatus crmf_template_add_public_key(PRArenaPool *poolp,
- CERTSubjectPublicKeyInfo **dest,
- CERTSubjectPublicKeyInfo *pubKey);
-
-extern CRMFCertExtension* crmf_create_cert_extension(PRArenaPool *poolp,
- SECOidTag tag,
- PRBool isCritical,
- SECItem *data);
-extern CRMFCertRequest*
-crmf_copy_cert_request(PRArenaPool *poolp, CRMFCertRequest *srcReq);
-
-extern SECStatus crmf_destroy_encrypted_value(CRMFEncryptedValue *inEncrValue,
- PRBool freeit);
-
-extern CRMFEncryptedValue *
-crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inPubKey,
- CRMFEncryptedValue *destValue);
-
-extern CK_MECHANISM_TYPE
- crmf_get_mechanism_from_public_key(SECKEYPublicKey *inPubKey);
-
-extern SECStatus
-crmf_encrypted_value_unwrap_priv_key(PRArenaPool *poolp,
- CRMFEncryptedValue *encValue,
- SECKEYPrivateKey *privKey,
- SECKEYPublicKey *newPubKey,
- SECItem *nickname,
- PK11SlotInfo *slot,
- unsigned char keyUsage,
- SECKEYPrivateKey **unWrappedKey,
- void *wincx);
-
-extern SECItem*
-crmf_get_public_value(SECKEYPublicKey *pubKey, SECItem *dest);
-
-extern CRMFCertExtension*
-crmf_copy_cert_extension(PRArenaPool *poolp, CRMFCertExtension *inExtension);
-
-extern SECStatus
-crmf_create_prtime(SECItem *src, PRTime **dest);
-#endif /*_CRMFI_H_*/
diff --git a/security/nss/lib/crmf/crmfit.h b/security/nss/lib/crmf/crmfit.h
deleted file mode 100644
index 531d4467d..000000000
--- a/security/nss/lib/crmf/crmfit.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#ifndef _CRMFIT_H_
-#define _CRMFIT_H_
-
-struct CRMFCertReqMessagesStr {
- CRMFCertReqMsg **messages;
- PRArenaPool *poolp;
-};
-
-struct CRMFCertExtensionStr {
- SECItem id;
- SECItem critical;
- SECItem value;
-};
-
-
-struct CRMFOptionalValidityStr {
- SECItem notBefore;
- SECItem notAfter;
-};
-
-struct CRMFCertTemplateStr {
- SECItem version;
- SECItem serialNumber;
- SECAlgorithmID *signingAlg;
- CERTName *issuer;
- CRMFOptionalValidity *validity;
- CERTName *subject;
- CERTSubjectPublicKeyInfo *publicKey;
- SECItem issuerUID;
- SECItem subjectUID;
- CRMFCertExtension **extensions;
- int numExtensions;
-};
-
-struct CRMFCertIDStr {
- SECItem issuer; /* General Name */
- SECItem serialNumber; /*INTEGER*/
-};
-
-struct CRMFEncryptedValueStr {
- SECAlgorithmID *intendedAlg;
- SECAlgorithmID *symmAlg;
- SECItem encSymmKey; /*BIT STRING */
- SECAlgorithmID *keyAlg;
- SECItem valueHint; /*OCTET STRING */
- SECItem encValue; /*BIT STRING */
-};
-
-/*
- * The field derValue will contain the actual der
- * to include in the encoding or that was read in
- * from a der blob.
- */
-struct CRMFEncryptedKeyStr {
- union {
- SEC_PKCS7ContentInfo *envelopedData;
- CRMFEncryptedValue encryptedValue;
- } value;
- CRMFEncryptedKeyChoice encKeyChoice;
- SECItem derValue;
-};
-
-/* ASN1 must only have one of the following 3 options. */
-struct CRMFPKIArchiveOptionsStr {
- union {
- CRMFEncryptedKey encryptedKey;
- SECItem keyGenParameters;
- SECItem archiveRemGenPrivKey; /* BOOLEAN */
- } option;
- CRMFPKIArchiveOptionsType archOption;
-};
-
-struct CRMFPKIPublicationInfoStr {
- SECItem action; /* Possible values */
- /* dontPublish (0), pleasePublish (1) */
- CRMFSinglePubInfo **pubInfos;
-};
-
-struct CRMFControlStr {
- SECOidTag tag;
- SECItem derTag;
- SECItem derValue;
- /* These will be C structures used to represent the various
- * options. Values that can't be stored as der right away.
- * After creating these structures, we'll place their der
- * encoding in derValue so the encoder knows how to get to
- * it.
- */
- union {
- CRMFCertID oldCertId;
- CRMFPKIArchiveOptions archiveOptions;
- CRMFPKIPublicationInfo pubInfo;
- CRMFProtocolEncrKey protEncrKey;
- } value;
-};
-
-struct CRMFCertRequestStr {
- SECItem certReqId;
- CRMFCertTemplate certTemplate;
- CRMFControl **controls;
- /* The following members are used by the internal implementation, but
- * are not part of the encoding.
- */
- PRArenaPool *poolp;
- PRUint32 requestID; /* This is the value that will be encoded into
- * the certReqId field.
- */
-};
-
-struct CRMFAttributeStr {
- SECItem derTag;
- SECItem derValue;
-};
-
-struct CRMFCertReqMsgStr {
- CRMFCertRequest *certReq;
- CRMFProofOfPossession *pop;
- CRMFAttribute **regInfo;
- SECItem derPOP;
- /* This arena will be used for allocating memory when decoding.
- */
- PRArenaPool *poolp;
- PRBool isDecoded;
-};
-
-struct CRMFPOPOSigningKeyInputStr {
- /* ASN1 must have only one of the next 2 options */
- union {
- SECItem sender; /*General Name*/
- CRMFPKMACValue *publicKeyMAC;
- }authInfo;
- CERTSubjectPublicKeyInfo publicKey;
-};
-
-struct CRMFPOPOSigningKeyStr {
- SECItem derInput; /*If in the future we support
- *POPOSigningKeyInput, this will
- *a C structure representation
- *instead.
- */
- SECAlgorithmID *algorithmIdentifier;
- SECItem signature; /* This is a BIT STRING. Remember */
-}; /* that when interpreting. */
-
-/* ASN1 must only choose one of these members */
-struct CRMFPOPOPrivKeyStr {
- union {
- SECItem thisMessage; /* BIT STRING */
- SECItem subsequentMessage; /*INTEGER*/
- SECItem dhMAC; /*BIT STRING*/
- } message;
- CRMFPOPOPrivKeyChoice messageChoice;
-};
-
-/* ASN1 must only have one of these options. */
-struct CRMFProofOfPossessionStr {
- union {
- SECItem raVerified;
- CRMFPOPOSigningKey signature;
- CRMFPOPOPrivKey keyEncipherment;
- CRMFPOPOPrivKey keyAgreement;
- } popChoice;
- CRMFPOPChoice popUsed; /*Not part of encoding*/
-};
-
-struct CRMFPKMACValueStr {
- SECAlgorithmID algID;
- SECItem value; /*BIT STRING*/
-};
-
-struct CRMFSinglePubInfoStr {
- SECItem pubMethod; /* Possible Values:
- * dontCare (0)
- * x500 (1)
- * web (2)
- * ldap (3)
- */
- CERTGeneralName *pubLocation; /* General Name */
-};
-
-#endif /* _CRMFIT_H_ */
diff --git a/security/nss/lib/crmf/crmfpop.c b/security/nss/lib/crmf/crmfpop.c
deleted file mode 100644
index 1ffb03bdb..000000000
--- a/security/nss/lib/crmf/crmfpop.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#include "crmf.h"
-#include "crmfi.h"
-#include "secasn1.h"
-#include "keyhi.h"
-#include "cryptohi.h"
-
-#define CRMF_DEFAULT_ALLOC_SIZE 1024
-
-SECStatus
-crmf_init_encoder_callback_arg (struct crmfEncoderArg *encoderArg,
- SECItem *derDest)
-{
- derDest->data = PORT_ZNewArray(unsigned char, CRMF_DEFAULT_ALLOC_SIZE);
- if (derDest->data == NULL) {
- return SECFailure;
- }
- derDest->len = 0;
- encoderArg->allocatedLen = CRMF_DEFAULT_ALLOC_SIZE;
- encoderArg->buffer = derDest;
- return SECSuccess;
-
-}
-
-/* Caller should release or unmark the pool, instead of doing it here.
-** But there are NO callers of this function at present...
-*/
-SECStatus
-CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg)
-{
- SECItem *dummy;
- CRMFProofOfPossession *pop;
- PRArenaPool *poolp;
- void *mark;
-
- PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL);
- poolp = inCertReqMsg->poolp;
- mark = PORT_ArenaMark(poolp);
- if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice) {
- return SECFailure;
- }
- pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
- if (pop == NULL) {
- goto loser;
- }
- pop->popUsed = crmfRAVerified;
- pop->popChoice.raVerified.data = NULL;
- pop->popChoice.raVerified.len = 0;
- inCertReqMsg->pop = pop;
- dummy = SEC_ASN1EncodeItem(poolp, &(inCertReqMsg->derPOP),
- &(pop->popChoice.raVerified),
- CRMFRAVerifiedTemplate);
- return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-static SECOidTag
-crmf_get_key_sign_tag(SECKEYPublicKey *inPubKey)
-{
- /* maintain backward compatibility with older
- * implementations */
- if (inPubKey->keyType == rsaKey) {
- return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
- }
- return SEC_GetSignatureAlgorithmOidTag(inPubKey->keyType, SEC_OID_UNKNOWN);
-}
-
-static SECAlgorithmID*
-crmf_create_poposignkey_algid(PRArenaPool *poolp,
- SECKEYPublicKey *inPubKey)
-{
- SECAlgorithmID *algID;
- SECOidTag tag;
- SECStatus rv;
- void *mark;
-
- mark = PORT_ArenaMark(poolp);
- algID = PORT_ArenaZNew(poolp, SECAlgorithmID);
- if (algID == NULL) {
- goto loser;
- }
- tag = crmf_get_key_sign_tag(inPubKey);
- if (tag == SEC_OID_UNKNOWN) {
- goto loser;
- }
- rv = SECOID_SetAlgorithmID(poolp, algID, tag, NULL);
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_ArenaUnmark(poolp, mark);
- return algID;
- loser:
- PORT_ArenaRelease(poolp, mark);
- return NULL;
-}
-
-static CRMFPOPOSigningKeyInput*
-crmf_create_poposigningkeyinput(PRArenaPool *poolp, CERTCertificate *inCert,
- CRMFMACPasswordCallback fn, void *arg)
-{
- /* PSM isn't going to do this, so we'll fail here for now.*/
- return NULL;
-}
-
-void
-crmf_generic_encoder_callback(void *arg, const char* buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
-{
- struct crmfEncoderArg *encoderArg = (struct crmfEncoderArg*)arg;
- unsigned char *cursor;
-
- if (encoderArg->buffer->len + len > encoderArg->allocatedLen) {
- int newSize = encoderArg->buffer->len+CRMF_DEFAULT_ALLOC_SIZE;
- void *dummy = PORT_Realloc(encoderArg->buffer->data, newSize);
- if (dummy == NULL) {
- /* I really want to return an error code here */
- PORT_Assert(0);
- return;
- }
- encoderArg->buffer->data = dummy;
- encoderArg->allocatedLen = newSize;
- }
- cursor = &(encoderArg->buffer->data[encoderArg->buffer->len]);
- PORT_Memcpy (cursor, buf, len);
- encoderArg->buffer->len += len;
-}
-
-static SECStatus
-crmf_encode_certreq(CRMFCertRequest *inCertReq, SECItem *derDest)
-{
- struct crmfEncoderArg encoderArg;
- SECStatus rv;
-
- rv = crmf_init_encoder_callback_arg (&encoderArg, derDest);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- return SEC_ASN1Encode(inCertReq, CRMFCertRequestTemplate,
- crmf_generic_encoder_callback, &encoderArg);
-}
-
-static SECStatus
-crmf_sign_certreq(PRArenaPool *poolp,
- CRMFPOPOSigningKey *crmfSignKey,
- CRMFCertRequest *certReq,
- SECKEYPrivateKey *inKey,
- SECAlgorithmID *inAlgId)
-{
- SECItem derCertReq = { siBuffer, NULL, 0 };
- SECItem certReqSig = { siBuffer, NULL, 0 };
- SECStatus rv = SECSuccess;
-
- rv = crmf_encode_certreq(certReq, &derCertReq);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SEC_SignData(&certReqSig, derCertReq.data, derCertReq.len,
- inKey,SECOID_GetAlgorithmTag(inAlgId));
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* Now make it a part of the POPOSigningKey */
- rv = SECITEM_CopyItem(poolp, &(crmfSignKey->signature), &certReqSig);
- /* Convert this length to number of bits */
- crmfSignKey->signature.len <<= 3;
-
- loser:
- if (derCertReq.data != NULL) {
- PORT_Free(derCertReq.data);
- }
- if (certReqSig.data != NULL) {
- PORT_Free(certReqSig.data);
- }
- return rv;
-}
-
-static SECStatus
-crmf_create_poposignkey(PRArenaPool *poolp,
- CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOSigningKeyInput *signKeyInput,
- SECKEYPrivateKey *inPrivKey,
- SECAlgorithmID *inAlgID,
- CRMFPOPOSigningKey *signKey)
-{
- CRMFCertRequest *certReq;
- void *mark;
- PRBool useSignKeyInput;
- SECStatus rv;
-
- PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL);
- mark = PORT_ArenaMark(poolp);
- if (signKey == NULL) {
- goto loser;
- }
- certReq = inCertReqMsg->certReq;
- useSignKeyInput = !(CRMF_DoesRequestHaveField(certReq,crmfSubject) &&
- CRMF_DoesRequestHaveField(certReq,crmfPublicKey));
-
- if (useSignKeyInput) {
- goto loser;
- } else {
- rv = crmf_sign_certreq(poolp, signKey, certReq,inPrivKey, inAlgID);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- PORT_ArenaUnmark(poolp,mark);
- return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp,mark);
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
- SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inPubKey,
- CERTCertificate *inCertForInput,
- CRMFMACPasswordCallback fn,
- void *arg)
-{
- SECAlgorithmID *algID;
- PRArenaPool *poolp;
- SECItem derTemp = {siBuffer, NULL, 0};
- void *mark;
- SECStatus rv;
- CRMFPOPOSigningKeyInput *signKeyInput = NULL;
- CRMFCertRequest *certReq;
- CRMFProofOfPossession *pop;
- struct crmfEncoderArg encoderArg;
-
- PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL &&
- inCertReqMsg->pop == NULL);
- certReq = inCertReqMsg->certReq;
- if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice ||
- !CRMF_DoesRequestHaveField(certReq, crmfPublicKey)) {
- return SECFailure;
- }
- poolp = inCertReqMsg->poolp;
- mark = PORT_ArenaMark(poolp);
- algID = crmf_create_poposignkey_algid(poolp, inPubKey);
-
- if(!CRMF_DoesRequestHaveField(certReq,crmfSubject)) {
- signKeyInput = crmf_create_poposigningkeyinput(poolp, inCertForInput,
- fn, arg);
- if (signKeyInput == NULL) {
- goto loser;
- }
- }
-
- pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
- if (pop == NULL) {
- goto loser;
- }
-
- rv = crmf_create_poposignkey(poolp, inCertReqMsg,
- signKeyInput, inPrivKey, algID,
- &(pop->popChoice.signature));
- if (rv != SECSuccess) {
- goto loser;
- }
-
- pop->popUsed = crmfSignature;
- pop->popChoice.signature.algorithmIdentifier = algID;
- inCertReqMsg->pop = pop;
-
- rv = crmf_init_encoder_callback_arg (&encoderArg, &derTemp);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SEC_ASN1Encode(&pop->popChoice.signature,
- CRMFPOPOSigningKeyTemplate,
- crmf_generic_encoder_callback, &encoderArg);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derTemp);
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_Free (derTemp.data);
- PORT_ArenaUnmark(poolp,mark);
- return SECSuccess;
-
- loser:
- PORT_ArenaRelease(poolp,mark);
- if (derTemp.data != NULL) {
- PORT_Free(derTemp.data);
- }
- return SECFailure;
-}
-
-static const SEC_ASN1Template*
-crmf_get_popoprivkey_subtemplate(CRMFPOPOPrivKey *inPrivKey)
-{
- const SEC_ASN1Template *retTemplate = NULL;
-
- switch (inPrivKey->messageChoice) {
- case crmfThisMessage:
- retTemplate = CRMFThisMessageTemplate;
- break;
- case crmfSubsequentMessage:
- retTemplate = CRMFSubsequentMessageTemplate;
- break;
- case crmfDHMAC:
- retTemplate = CRMFDHMACTemplate;
- break;
- default:
- retTemplate = NULL;
- }
- return retTemplate;
-}
-
-static SECStatus
-crmf_encode_popoprivkey(PRArenaPool *poolp,
- CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKey *popoPrivKey,
- const SEC_ASN1Template *privKeyTemplate)
-{
- struct crmfEncoderArg encoderArg;
- SECItem derTemp = { siBuffer, NULL, 0 };
- SECStatus rv;
- void *mark;
- const SEC_ASN1Template *subDerTemplate;
-
- mark = PORT_ArenaMark(poolp);
- rv = crmf_init_encoder_callback_arg(&encoderArg, &derTemp);
- if (rv != SECSuccess) {
- goto loser;
- }
- subDerTemplate = crmf_get_popoprivkey_subtemplate(popoPrivKey);
- /* We've got a union, so a pointer to one item is a pointer to
- * all the items in the union.
- */
- rv = SEC_ASN1Encode(&popoPrivKey->message.thisMessage,
- subDerTemplate,
- crmf_generic_encoder_callback, &encoderArg);
- if (rv != SECSuccess) {
- goto loser;
- }
- if (encoderArg.allocatedLen > derTemp.len+2) {
- void *dummy = PORT_Realloc(derTemp.data, derTemp.len+2);
- if (dummy == NULL) {
- goto loser;
- }
- derTemp.data = dummy;
- }
- PORT_Memmove(&derTemp.data[2], &derTemp.data[0], derTemp.len);
- /* I couldn't figure out how to get the ASN1 encoder to implicitly
- * tag an implicitly tagged der blob. So I'm putting in the outter-
- * most tag myself. -javi
- */
- derTemp.data[0] = (unsigned char)privKeyTemplate->kind;
- derTemp.data[1] = (unsigned char)derTemp.len;
- derTemp.len += 2;
- rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derTemp);
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_Free(derTemp.data);
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp, mark);
- if (derTemp.data) {
- PORT_Free(derTemp.data);
- }
- return SECFailure;
-}
-
-static const SEC_ASN1Template*
-crmf_get_template_for_privkey(CRMFPOPChoice inChoice)
-{
- switch (inChoice) {
- case crmfKeyAgreement:
- return CRMFPOPOKeyAgreementTemplate;
- case crmfKeyEncipherment:
- return CRMFPOPOKeyEnciphermentTemplate;
- default:
- break;
- }
- return NULL;
-}
-
-static SECStatus
-crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey,
- CRMFPOPChoice inChoice)
-{
- PRArenaPool *poolp;
- void *mark;
- CRMFPOPOPrivKey *popoPrivKey;
- CRMFProofOfPossession *pop;
- SECStatus rv;
-
- PORT_Assert(inCertReqMsg != NULL && encPrivKey != NULL);
- poolp = inCertReqMsg->poolp;
- mark = PORT_ArenaMark(poolp);
- pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
- if (pop == NULL) {
- goto loser;
- }
- pop->popUsed = inChoice;
- /* popChoice is a union, so getting a pointer to one
- * field gives me a pointer to the other fields as
- * well. This in essence points to both
- * pop->popChoice.keyEncipherment and
- * pop->popChoice.keyAgreement
- */
- popoPrivKey = &pop->popChoice.keyEncipherment;
-
- rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.thisMessage),
- encPrivKey);
- if (rv != SECSuccess) {
- goto loser;
- }
- popoPrivKey->message.thisMessage.len <<= 3;
- popoPrivKey->messageChoice = crmfThisMessage;
- inCertReqMsg->pop = pop;
- rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey,
- crmf_get_template_for_privkey(inChoice));
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
- loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-static SECStatus
-crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac,
- CRMFPOPChoice inChoice)
-{
- PRArenaPool *poolp;
- void *mark;
- CRMFPOPOPrivKey *popoPrivKey;
- CRMFProofOfPossession *pop;
- SECStatus rv;
-
- PORT_Assert(inCertReqMsg != NULL && dhmac != NULL);
- poolp = inCertReqMsg->poolp;
- mark = PORT_ArenaMark(poolp);
- pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
- if (pop == NULL) {
- goto loser;
- }
- pop->popUsed = inChoice;
- popoPrivKey = &pop->popChoice.keyAgreement;
-
- rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.dhMAC),
- dhmac);
- if (rv != SECSuccess) {
- goto loser;
- }
- popoPrivKey->message.dhMAC.len <<= 3;
- popoPrivKey->messageChoice = crmfDHMAC;
- inCertReqMsg->pop = pop;
- rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey,
- crmf_get_template_for_privkey(inChoice));
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
- loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-static SECStatus
-crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg,
- CRMFSubseqMessOptions subsequentMessage,
- CRMFPOPChoice inChoice)
-{
- void *mark;
- PRArenaPool *poolp;
- CRMFProofOfPossession *pop;
- CRMFPOPOPrivKey *popoPrivKey;
- SECStatus rv;
- const SEC_ASN1Template *privKeyTemplate;
-
- if (subsequentMessage == crmfNoSubseqMess) {
- return SECFailure;
- }
- poolp = inCertReqMsg->poolp;
- mark = PORT_ArenaMark(poolp);
- pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
- if (pop == NULL) {
- goto loser;
- }
-
- pop->popUsed = inChoice;
- /*
- * We have a union, so a pointer to one member of the union
- * is also a member to another member of that same union.
- */
- popoPrivKey = &pop->popChoice.keyEncipherment;
-
- switch (subsequentMessage) {
- case crmfEncrCert:
- rv = crmf_encode_integer(poolp,
- &(popoPrivKey->message.subsequentMessage),
- 0);
- break;
- case crmfChallengeResp:
- rv = crmf_encode_integer(poolp,
- &(popoPrivKey->message.subsequentMessage),
- 1);
- break;
- default:
- goto loser;
- }
- if (rv != SECSuccess) {
- goto loser;
- }
- popoPrivKey->messageChoice = crmfSubsequentMessage;
- privKeyTemplate = crmf_get_template_for_privkey(inChoice);
- inCertReqMsg->pop = pop;
- rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey,
- privKeyTemplate);
-
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertReqMsgSetKeyEnciphermentPOP(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKeyChoice inKeyChoice,
- CRMFSubseqMessOptions subseqMess,
- SECItem *encPrivKey)
-{
- SECStatus rv;
-
- PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL);
- if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice) {
- return SECFailure;
- }
- switch (inKeyChoice) {
- case crmfThisMessage:
- rv = crmf_add_privkey_thismessage(inCertReqMsg, encPrivKey,
- crmfKeyEncipherment);
- break;
- case crmfSubsequentMessage:
- rv = crmf_add_privkey_subseqmessage(inCertReqMsg, subseqMess,
- crmfKeyEncipherment);
- break;
- case crmfDHMAC:
- default:
- rv = SECFailure;
- }
- return rv;
-}
-
-SECStatus
-CRMF_CertReqMsgSetKeyAgreementPOP (CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKeyChoice inKeyChoice,
- CRMFSubseqMessOptions subseqMess,
- SECItem *encPrivKey)
-{
- SECStatus rv;
-
- PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL);
- switch (inKeyChoice) {
- case crmfThisMessage:
- rv = crmf_add_privkey_thismessage(inCertReqMsg, encPrivKey,
- crmfKeyAgreement);
- break;
- case crmfSubsequentMessage:
- rv = crmf_add_privkey_subseqmessage(inCertReqMsg, subseqMess,
- crmfKeyAgreement);
- break;
- case crmfDHMAC:
- /* In this case encPrivKey should be the calculated dhMac
- * as specified in RFC 2511 */
- rv = crmf_add_privkey_dhmac(inCertReqMsg, encPrivKey,
- crmfKeyAgreement);
- break;
- default:
- rv = SECFailure;
- }
- return rv;
-}
-
diff --git a/security/nss/lib/crmf/crmfreq.c b/security/nss/lib/crmf/crmfreq.c
deleted file mode 100644
index 5ccc7a0a5..000000000
--- a/security/nss/lib/crmf/crmfreq.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "crmf.h"
-#include "crmfi.h"
-#include "keyhi.h"
-#include "secder.h"
-
-/*
- * Macro that returns PR_TRUE if the pointer is not NULL.
- * If the pointer is NULL, then the macro will return PR_FALSE.
- */
-#define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE
-
-const unsigned char hexTrue = 0xff;
-const unsigned char hexFalse = 0x00;
-
-
-SECStatus
-crmf_encode_integer(PRArenaPool *poolp, SECItem *dest, long value)
-{
- SECItem *dummy;
-
- dummy = SEC_ASN1EncodeInteger(poolp, dest, value);
- PORT_Assert (dummy == dest);
- if (dummy == NULL) {
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-crmf_encode_unsigned_integer(PRArenaPool *poolp, SECItem *dest,
- unsigned long value)
-{
- SECItem *dummy;
-
- dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value);
- PORT_Assert (dummy == dest);
- if (dummy != dest) {
- return SECFailure;
- }
- return SECSuccess;
-}
-
-static SECStatus
-crmf_copy_secitem (PRArenaPool *poolp, SECItem *dest, SECItem *src)
-{
- return SECITEM_CopyItem (poolp, dest, src);
-}
-
-PRBool
-CRMF_DoesRequestHaveField (CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inField)
-{
-
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return PR_FALSE;
- }
- switch (inField) {
- case crmfVersion:
- return inCertReq->certTemplate.version.data != NULL;
- case crmfSerialNumber:
- return inCertReq->certTemplate.serialNumber.data != NULL;
- case crmfSigningAlg:
- return inCertReq->certTemplate.signingAlg != NULL;
- case crmfIssuer:
- return inCertReq->certTemplate.issuer != NULL;
- case crmfValidity:
- return inCertReq->certTemplate.validity != NULL;
- case crmfSubject:
- return inCertReq->certTemplate.subject != NULL;
- case crmfPublicKey:
- return inCertReq->certTemplate.publicKey != NULL;
- case crmfIssuerUID:
- return inCertReq->certTemplate.issuerUID.data != NULL;
- case crmfSubjectUID:
- return inCertReq->certTemplate.subjectUID.data != NULL;
- case crmfExtension:
- return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0;
- }
- return PR_FALSE;
-}
-
-CRMFCertRequest *
-CRMF_CreateCertRequest (PRUint32 inRequestID)
-{
- PRArenaPool *poolp;
- CRMFCertRequest *certReq;
- SECStatus rv;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- goto loser;
- }
-
- certReq=PORT_ArenaZNew(poolp,CRMFCertRequest);
- if (certReq == NULL) {
- goto loser;
- }
-
- certReq->poolp = poolp;
- certReq->requestID = inRequestID;
-
- rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId),
- inRequestID);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- return certReq;
- loser:
- if (poolp) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return NULL;
-}
-
-SECStatus
-CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq)
-{
- PORT_Assert(inCertReq != NULL);
- if (inCertReq != NULL) {
- if (inCertReq->certTemplate.extensions) {
- PORT_Free(inCertReq->certTemplate.extensions);
- }
- if (inCertReq->controls) {
- /* Right now we don't support EnveloppedData option,
- * so we won't go through and delete each occurrence of
- * an EnveloppedData in the control.
- */
- PORT_Free(inCertReq->controls);
- }
- if (inCertReq->poolp) {
- PORT_FreeArena(inCertReq->poolp, PR_TRUE);
- }
- }
- return SECSuccess;
-}
-
-static SECStatus
-crmf_template_add_version(PRArenaPool *poolp, SECItem *dest, long version)
-{
- return (crmf_encode_integer(poolp, dest, version));
-}
-
-static SECStatus
-crmf_template_add_serialnumber(PRArenaPool *poolp, SECItem *dest, long serial)
-{
- return (crmf_encode_integer(poolp, dest, serial));
-}
-
-SECStatus
-crmf_template_copy_secalg (PRArenaPool *poolp, SECAlgorithmID **dest,
- SECAlgorithmID* src)
-{
- SECStatus rv;
- void *mark = NULL;
- SECAlgorithmID *mySecAlg;
-
- if (!poolp) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(poolp);
- *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID);
- if (mySecAlg == NULL) {
- goto loser;
- }
- rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src);
- if (rv != SECSuccess) {
- goto loser;
- }
- if (mark) {
- PORT_ArenaUnmark(poolp, mark);
- }
- return SECSuccess;
-
- loser:
- *dest = NULL;
- if (mark) {
- PORT_ArenaRelease(poolp, mark);
- }
- return SECFailure;
-}
-
-SECStatus
-crmf_copy_cert_name(PRArenaPool *poolp, CERTName **dest,
- CERTName *src)
-{
- CERTName *newName;
- SECStatus rv;
- void *mark;
-
- mark = PORT_ArenaMark(poolp);
- *dest = newName = PORT_ArenaZNew(poolp, CERTName);
- if (newName == NULL) {
- goto loser;
- }
-
- rv = CERT_CopyName(poolp, newName, src);
- if (rv != SECSuccess) {
- goto loser;
- }
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp, mark);
- *dest = NULL;
- return SECFailure;
-}
-
-static SECStatus
-crmf_template_add_issuer (PRArenaPool *poolp, CERTName **dest,
- CERTName* issuerName)
-{
- return crmf_copy_cert_name(poolp, dest, issuerName);
-}
-
-
-static SECStatus
-crmf_template_add_validity (PRArenaPool *poolp, CRMFOptionalValidity **dest,
- CRMFValidityCreationInfo *info)
-{
- SECStatus rv;
- void *mark;
- CRMFOptionalValidity *myValidity;
-
- /*First off, let's make sure at least one of the two fields is present*/
- if (!info || (!info->notBefore && !info->notAfter)) {
- return SECFailure;
- }
- mark = PORT_ArenaMark (poolp);
- *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity);
- if (myValidity == NULL) {
- goto loser;
- }
-
- if (info->notBefore) {
- rv = DER_EncodeTimeChoice (poolp, &myValidity->notBefore,
- *info->notBefore);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- if (info->notAfter) {
- rv = DER_EncodeTimeChoice (poolp, &myValidity->notAfter,
- *info->notAfter);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp, mark);
- *dest = NULL;
- return SECFailure;
-}
-
-static SECStatus
-crmf_template_add_subject (PRArenaPool *poolp, CERTName **dest,
- CERTName *subject)
-{
- return crmf_copy_cert_name(poolp, dest, subject);
-}
-
-SECStatus
-crmf_template_add_public_key(PRArenaPool *poolp,
- CERTSubjectPublicKeyInfo **dest,
- CERTSubjectPublicKeyInfo *pubKey)
-{
- CERTSubjectPublicKeyInfo *spki;
- SECStatus rv;
-
- *dest = spki = (poolp == NULL) ?
- PORT_ZNew(CERTSubjectPublicKeyInfo) :
- PORT_ArenaZNew (poolp, CERTSubjectPublicKeyInfo);
- if (spki == NULL) {
- goto loser;
- }
- rv = SECKEY_CopySubjectPublicKeyInfo (poolp, spki, pubKey);
- if (rv != SECSuccess) {
- goto loser;
- }
- return SECSuccess;
- loser:
- if (poolp == NULL && spki != NULL) {
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- }
- *dest = NULL;
- return SECFailure;
-}
-
-static SECStatus
-crmf_copy_bitstring (PRArenaPool *poolp, SECItem *dest, const SECItem *src)
-{
- SECStatus rv;
- SECItem byteSrc;
-
- byteSrc = *src;
- byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len);
- rv = crmf_copy_secitem(poolp, dest, &byteSrc);
- dest->len = src->len;
- return rv;
-}
-
-static SECStatus
-crmf_template_add_issuer_uid(PRArenaPool *poolp, SECItem *dest,
- const SECItem *issuerUID)
-{
- return crmf_copy_bitstring (poolp, dest, issuerUID);
-}
-
-static SECStatus
-crmf_template_add_subject_uid(PRArenaPool *poolp, SECItem *dest,
- const SECItem *subjectUID)
-{
- return crmf_copy_bitstring (poolp, dest, subjectUID);
-}
-
-static void
-crmf_zeroize_new_extensions (CRMFCertExtension **extensions,
- int numToZeroize)
-{
- PORT_Memset((void*)extensions, 0, sizeof(CERTCertExtension*)*numToZeroize);
-}
-
-/*
- * The strategy for adding templates will differ from all the other
- * attributes in the template. First, we want to allow the client
- * of this API to set extensions more than just once. So we will
- * need the ability grow the array of extensions. Since arenas don't
- * give us the realloc function, we'll use the generic PORT_* functions
- * to allocate the array of pointers *ONLY*. Then we will allocate each
- * individual extension from the arena that comes along with the certReq
- * structure that owns this template.
- */
-static SECStatus
-crmf_template_add_extensions(PRArenaPool *poolp, CRMFCertTemplate *inTemplate,
- CRMFCertExtCreationInfo *extensions)
-{
- void *mark;
- int newSize, oldSize, i;
- SECStatus rv;
- CRMFCertExtension **extArray;
- CRMFCertExtension *newExt, *currExt;
-
- mark = PORT_ArenaMark(poolp);
- if (inTemplate->extensions == NULL) {
- newSize = extensions->numExtensions;
- extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1);
- } else {
- newSize = inTemplate->numExtensions + extensions->numExtensions;
- extArray = PORT_Realloc(inTemplate->extensions,
- sizeof(CRMFCertExtension*)*(newSize+1));
- }
- if (extArray == NULL) {
- goto loser;
- }
- oldSize = inTemplate->numExtensions;
- inTemplate->extensions = extArray;
- inTemplate->numExtensions = newSize;
- for (i=oldSize; i < newSize; i++) {
- newExt = PORT_ArenaZNew(poolp, CRMFCertExtension);
- if (newExt == NULL) {
- goto loser2;
- }
- currExt = extensions->extensions[i-oldSize];
- rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id));
- if (rv != SECSuccess) {
- goto loser2;
- }
- rv = crmf_copy_secitem(poolp, &(newExt->critical),
- &(currExt->critical));
- if (rv != SECSuccess) {
- goto loser2;
- }
- rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value));
- if (rv != SECSuccess) {
- goto loser2;
- }
- extArray[i] = newExt;
- }
- extArray[newSize] = NULL;
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
- loser2:
- crmf_zeroize_new_extensions (&(inTemplate->extensions[oldSize]),
- extensions->numExtensions);
- inTemplate->numExtensions = oldSize;
- loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inTemplateField,
- void *data)
-{
- CRMFCertTemplate *certTemplate;
- PRArenaPool *poolp;
- SECStatus rv = SECFailure;
- void *mark;
-
-
- if (inCertReq == NULL) {
- return SECFailure;
- }
-
- certTemplate = &(inCertReq->certTemplate);
-
- poolp = inCertReq->poolp;
- mark = PORT_ArenaMark(poolp);
- switch (inTemplateField) {
- case crmfVersion:
- rv = crmf_template_add_version(poolp,&(certTemplate->version),
- *(long*)data);
- break;
- case crmfSerialNumber:
- rv = crmf_template_add_serialnumber(poolp,
- &(certTemplate->serialNumber),
- *(long*)data);
- break;
- case crmfSigningAlg:
- rv = crmf_template_copy_secalg (poolp, &(certTemplate->signingAlg),
- (SECAlgorithmID*)data);
- break;
- case crmfIssuer:
- rv = crmf_template_add_issuer (poolp, &(certTemplate->issuer),
- (CERTName*)data);
- break;
- case crmfValidity:
- rv = crmf_template_add_validity (poolp, &(certTemplate->validity),
- (CRMFValidityCreationInfo*)data);
- break;
- case crmfSubject:
- rv = crmf_template_add_subject (poolp, &(certTemplate->subject),
- (CERTName*)data);
- break;
- case crmfPublicKey:
- rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey),
- (CERTSubjectPublicKeyInfo*)data);
- break;
- case crmfIssuerUID:
- rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID),
- (SECItem*)data);
- break;
- case crmfSubjectUID:
- rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID),
- (SECItem*)data);
- break;
- case crmfExtension:
- rv = crmf_template_add_extensions(poolp, certTemplate,
- (CRMFCertExtCreationInfo*)data);
- break;
- }
- if (rv != SECSuccess) {
- PORT_ArenaRelease(poolp, mark);
- } else {
- PORT_ArenaUnmark(poolp, mark);
- }
- return rv;
-}
-
-SECStatus
-CRMF_CertReqMsgSetCertRequest (CRMFCertReqMsg *inCertReqMsg,
- CRMFCertRequest *inCertReq)
-{
- PORT_Assert (inCertReqMsg != NULL && inCertReq != NULL);
- if (inCertReqMsg == NULL || inCertReq == NULL) {
- return SECFailure;
- }
- inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp,
- inCertReq);
- return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess;
-}
-
-CRMFCertReqMsg*
-CRMF_CreateCertReqMsg(void)
-{
- PRArenaPool *poolp;
- CRMFCertReqMsg *reqMsg;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- goto loser;
- }
- reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
- if (reqMsg == NULL) {
- goto loser;
- }
- reqMsg->poolp = poolp;
- return reqMsg;
-
- loser:
- if (poolp) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return NULL;
-}
-
-SECStatus
-CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg)
-{
- PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL);
- if (!inCertReqMsg->isDecoded) {
- if (inCertReqMsg->certReq->certTemplate.extensions != NULL) {
- PORT_Free(inCertReqMsg->certReq->certTemplate.extensions);
- }
- if (inCertReqMsg->certReq->controls != NULL) {
- PORT_Free(inCertReqMsg->certReq->controls);
- }
- }
- PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE);
- return SECSuccess;
-}
-
-CRMFCertExtension*
-crmf_create_cert_extension(PRArenaPool *poolp,
- SECOidTag id,
- PRBool isCritical,
- SECItem *data)
-{
- CRMFCertExtension *newExt;
- SECOidData *oidData;
- SECStatus rv;
-
- newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) :
- PORT_ArenaZNew(poolp, CRMFCertExtension);
- if (newExt == NULL) {
- goto loser;
- }
- oidData = SECOID_FindOIDByTag(id);
- if (oidData == NULL ||
- oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) {
- goto loser;
- }
-
- rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid));
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = SECITEM_CopyItem(poolp, &(newExt->value), data);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- if (isCritical) {
- newExt->critical.data = (poolp == NULL) ?
- PORT_New(unsigned char) :
- PORT_ArenaNew(poolp, unsigned char);
- if (newExt->critical.data == NULL) {
- goto loser;
- }
- newExt->critical.data[0] = hexTrue;
- newExt->critical.len = 1;
- }
- return newExt;
- loser:
- if (newExt != NULL && poolp == NULL) {
- CRMF_DestroyCertExtension(newExt);
- }
- return NULL;
-}
-
-CRMFCertExtension *
-CRMF_CreateCertExtension(SECOidTag id,
- PRBool isCritical,
- SECItem *data)
-{
- return crmf_create_cert_extension(NULL, id, isCritical, data);
-}
-
-static SECStatus
-crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit)
-{
- if (inExtension != NULL) {
- SECITEM_FreeItem (&(inExtension->id), PR_FALSE);
- SECITEM_FreeItem (&(inExtension->value), PR_FALSE);
- SECITEM_FreeItem (&(inExtension->critical), PR_FALSE);
- if (freeit) {
- PORT_Free(inExtension);
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-CRMF_DestroyCertExtension(CRMFCertExtension *inExtension)
-{
- return crmf_destroy_cert_extension(inExtension, PR_TRUE);
-}
-
-SECStatus
-CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs)
-{
- PORT_Assert (inCertReqMsgs != NULL);
- if (inCertReqMsgs != NULL) {
- PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE);
- }
- return SECSuccess;
-}
-
-static PRBool
-crmf_item_has_data(SECItem *item)
-{
- if (item != NULL && item->data != NULL) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-PRBool
-CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq,
- CRMFCertTemplateField inTemplateField)
-{
- PRBool retVal;
- CRMFCertTemplate *certTemplate;
-
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- /* This is probably some kind of error, but this is
- * the safest return value for this function.
- */
- return PR_FALSE;
- }
- certTemplate = &inCertReq->certTemplate;
- switch (inTemplateField) {
- case crmfVersion:
- retVal = crmf_item_has_data(&certTemplate->version);
- break;
- case crmfSerialNumber:
- retVal = crmf_item_has_data(&certTemplate->serialNumber);
- break;
- case crmfSigningAlg:
- retVal = IS_NOT_NULL(certTemplate->signingAlg);
- break;
- case crmfIssuer:
- retVal = IS_NOT_NULL(certTemplate->issuer);
- break;
- case crmfValidity:
- retVal = IS_NOT_NULL(certTemplate->validity);
- break;
- case crmfSubject:
- retVal = IS_NOT_NULL(certTemplate->subject);
- break;
- case crmfPublicKey:
- retVal = IS_NOT_NULL(certTemplate->publicKey);
- break;
- case crmfIssuerUID:
- retVal = crmf_item_has_data(&certTemplate->issuerUID);
- break;
- case crmfSubjectUID:
- retVal = crmf_item_has_data(&certTemplate->subjectUID);
- break;
- case crmfExtension:
- retVal = IS_NOT_NULL(certTemplate->extensions);
- break;
- default:
- retVal = PR_FALSE;
- }
- return retVal;
-}
diff --git a/security/nss/lib/crmf/crmft.h b/security/nss/lib/crmf/crmft.h
deleted file mode 100644
index e12aa02c8..000000000
--- a/security/nss/lib/crmf/crmft.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-/* Header file with all of the structures and types that will be exported
- * by the security library for implementation of CRMF.
- */
-
-#ifndef _CRMFT_H_
-#define _CRMFT_H_
-
-/* Use these enumerated values for adding fields to the certificate request */
-typedef enum {
- crmfVersion = 0,
- crmfSerialNumber = 1,
- crmfSigningAlg = 2,
- crmfIssuer = 3,
- crmfValidity = 4,
- crmfSubject = 5,
- crmfPublicKey = 6,
- crmfIssuerUID = 7,
- crmfSubjectUID = 8,
- crmfExtension = 9
-} CRMFCertTemplateField;
-
-/*
- * An enumeration for the different types of controls.
- */
-typedef enum {
- crmfNoControl = 0,
- crmfRegTokenControl = 1,
- crmfAuthenticatorControl = 2,
- crmfPKIPublicationInfoControl = 3,
- crmfPKIArchiveOptionsControl = 4,
- crmfOldCertIDControl = 5,
- crmfProtocolEncrKeyControl = 6
-} CRMFControlType;
-
-/*
- * The possible values that are passed into CRMF_CreatePKIPublicationInfo
- */
-typedef enum {
- crmfDontPublish = 0,
- crmfPleasePublish = 1
-} CRMFPublicationAction;
-
-/*
- * An enumeration for the possible for pubMethod which is a part of
- * the SinglePubInfo ASN1 type.
- */
-typedef enum {
- crmfDontCare = 0,
- crmfX500 = 1,
- crmfWeb = 2,
- crmfLdap = 3
-} CRMFPublicationMethod;
-
-/*
- * An enumeration for the different options for PKIArchiveOptions type.
- */
-typedef enum {
- crmfNoArchiveOptions = 0,
- crmfEncryptedPrivateKey = 1,
- crmfKeyGenParameters = 2,
- crmfArchiveRemGenPrivKey = 3
-} CRMFPKIArchiveOptionsType;
-
-/*
- * An enumeration for the different options for ProofOfPossession
- */
-typedef enum {
- crmfNoPOPChoice = 0,
- crmfRAVerified = 1,
- crmfSignature = 2,
- crmfKeyEncipherment = 3,
- crmfKeyAgreement = 4
-} CRMFPOPChoice;
-
-/*
- * An enumertion type for options for the authInfo field of the
- * CRMFPOPOSigningKeyInput structure.
- */
-typedef enum {
- crmfSender = 0,
- crmfPublicKeyMAC = 1
-} CRMFPOPOSkiInputAuthChoice;
-
-/*
- * An enumeration for the SubsequentMessage Options.
- */
-typedef enum {
- crmfNoSubseqMess = 0,
- crmfEncrCert = 1,
- crmfChallengeResp = 2
-} CRMFSubseqMessOptions;
-
-/*
- * An enumeration for the choice used by POPOPrivKey.
- */
-typedef enum {
- crmfNoMessage = 0,
- crmfThisMessage = 1,
- crmfSubsequentMessage = 2,
- crmfDHMAC = 3
-} CRMFPOPOPrivKeyChoice;
-
-/*
- * An enumeration for the choices for the EncryptedKey type.
- */
-typedef enum {
- crmfNoEncryptedKeyChoice = 0,
- crmfEncryptedValueChoice = 1,
- crmfEnvelopedDataChoice = 2
-} CRMFEncryptedKeyChoice;
-
-/*
- * TYPE: CRMFEncoderOutputCallback
- * This function type defines a prototype for a function that the CRMF
- * library expects when encoding is performed.
- *
- * ARGUMENTS:
- * arg
- * This will be a pointer the user passed into an encoding function.
- * The user of the library is free to use this pointer in any way.
- * The most common use is to keep around a buffer for writing out
- * the DER encoded bytes.
- * buf
- * The DER encoded bytes that should be written out.
- * len
- * The number of DER encoded bytes to write out.
- *
- */
-typedef void (*CRMFEncoderOutputCallback) (void *arg,
- const char *buf,
- unsigned long len);
-
-/*
- * Type for the function that gets a password. Just in case we ever
- * need to support publicKeyMAC for POPOSigningKeyInput
- */
-typedef SECItem* (*CRMFMACPasswordCallback) (void *arg);
-
-typedef struct CRMFOptionalValidityStr CRMFOptionalValidity;
-typedef struct CRMFValidityCreationInfoStr CRMFGetValidity;
-typedef struct CRMFCertTemplateStr CRMFCertTemplate;
-typedef struct CRMFCertRequestStr CRMFCertRequest;
-typedef struct CRMFCertReqMsgStr CRMFCertReqMsg;
-typedef struct CRMFCertReqMessagesStr CRMFCertReqMessages;
-typedef struct CRMFProofOfPossessionStr CRMFProofOfPossession;
-typedef struct CRMFPOPOSigningKeyStr CRMFPOPOSigningKey;
-typedef struct CRMFPOPOSigningKeyInputStr CRMFPOPOSigningKeyInput;
-typedef struct CRMFPOPOPrivKeyStr CRMFPOPOPrivKey;
-typedef struct CRMFPKIPublicationInfoStr CRMFPKIPublicationInfo;
-typedef struct CRMFSinglePubInfoStr CRMFSinglePubInfo;
-typedef struct CRMFPKIArchiveOptionsStr CRMFPKIArchiveOptions;
-typedef struct CRMFEncryptedKeyStr CRMFEncryptedKey;
-typedef struct CRMFEncryptedValueStr CRMFEncryptedValue;
-typedef struct CRMFCertIDStr CRMFCertID;
-typedef struct CRMFCertIDStr CRMFOldCertID;
-typedef CERTSubjectPublicKeyInfo CRMFProtocolEncrKey;
-typedef struct CRMFValidityCreationInfoStr CRMFValidityCreationInfo;
-typedef struct CRMFCertExtCreationInfoStr CRMFCertExtCreationInfo;
-typedef struct CRMFPKMACValueStr CRMFPKMACValue;
-typedef struct CRMFAttributeStr CRMFAttribute;
-typedef struct CRMFControlStr CRMFControl;
-typedef CERTGeneralName CRMFGeneralName;
-typedef struct CRMFCertExtensionStr CRMFCertExtension;
-
-struct CRMFValidityCreationInfoStr {
- PRTime *notBefore;
- PRTime *notAfter;
-};
-
-struct CRMFCertExtCreationInfoStr {
- CRMFCertExtension **extensions;
- int numExtensions;
-};
-
-/*
- * Some ASN1 Templates that may be needed.
- */
-extern const SEC_ASN1Template CRMFCertReqMessagesTemplate[];
-extern const SEC_ASN1Template CRMFCertRequestTemplate[];
-
-
-#endif /*_CRMFT_H_*/
diff --git a/security/nss/lib/crmf/crmftmpl.c b/security/nss/lib/crmf/crmftmpl.c
deleted file mode 100644
index 73d75f8b7..000000000
--- a/security/nss/lib/crmf/crmftmpl.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "crmf.h"
-#include "crmfi.h"
-#include "secoid.h"
-#include "secasn1.h"
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(SEC_NullTemplate)
-SEC_ASN1_MKSUB(SEC_BitStringTemplate)
-SEC_ASN1_MKSUB(SEC_IntegerTemplate)
-SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
-SEC_ASN1_MKSUB(CERT_TimeChoiceTemplate)
-SEC_ASN1_MKSUB(CERT_SubjectPublicKeyInfoTemplate)
-SEC_ASN1_MKSUB(CERT_NameTemplate)
-
-/*
- * It's all implicit tagging.
- */
-
-const SEC_ASN1Template CRMFControlTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRMFControl)},
- { SEC_ASN1_OBJECT_ID, offsetof(CRMFControl, derTag)},
- { SEC_ASN1_ANY, offsetof(CRMFControl, derValue) },
- { 0 }
-};
-
-static const SEC_ASN1Template CRMFCertExtensionTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CRMFCertExtension) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(CRMFCertExtension,id) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN,
- offsetof(CRMFCertExtension,critical) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(CRMFCertExtension,value) },
- { 0, }
-};
-
-static const SEC_ASN1Template CRMFSequenceOfCertExtensionTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, CRMFCertExtensionTemplate }
-};
-
-static const SEC_ASN1Template CRMFOptionalValidityTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (CRMFOptionalValidity) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_NO_STREAM |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN | 0,
- offsetof (CRMFOptionalValidity, notBefore),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_NO_STREAM |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN | 1,
- offsetof (CRMFOptionalValidity, notAfter),
- SEC_ASN1_SUB(CERT_TimeChoiceTemplate) },
- { 0 }
-};
-
-static const SEC_ASN1Template crmfPointerToNameTemplate[] = {
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(CERT_NameTemplate)},
- { 0 }
-};
-
-static const SEC_ASN1Template CRMFCertTemplateTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRMFCertTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(CRMFCertTemplate, version),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_OPTIONAL | SEC_ASN1_XTRN | 1 ,
- offsetof (CRMFCertTemplate, serialNumber),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER |
- SEC_ASN1_XTRN | 2,
- offsetof (CRMFCertTemplate, signingAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | 3,
- offsetof (CRMFCertTemplate, issuer), crmfPointerToNameTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 4,
- offsetof (CRMFCertTemplate, validity),
- CRMFOptionalValidityTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | 5,
- offsetof (CRMFCertTemplate, subject), crmfPointerToNameTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER |
- SEC_ASN1_XTRN | 6,
- offsetof (CRMFCertTemplate, publicKey),
- SEC_ASN1_SUB(CERT_SubjectPublicKeyInfoTemplate) },
- { SEC_ASN1_NO_STREAM | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_OPTIONAL |
- SEC_ASN1_XTRN | 7,
- offsetof (CRMFCertTemplate, issuerUID),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { SEC_ASN1_NO_STREAM | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_OPTIONAL |
- SEC_ASN1_XTRN | 8,
- offsetof (CRMFCertTemplate, subjectUID),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_OPTIONAL |
- SEC_ASN1_CONTEXT_SPECIFIC | 9,
- offsetof (CRMFCertTemplate, extensions),
- CRMFSequenceOfCertExtensionTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template CRMFAttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRMFAttribute)},
- { SEC_ASN1_OBJECT_ID, offsetof(CRMFAttribute, derTag)},
- { SEC_ASN1_ANY, offsetof(CRMFAttribute, derValue) },
- { 0 }
-};
-
-const SEC_ASN1Template CRMFCertRequestTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (CRMFCertRequest) },
- { SEC_ASN1_INTEGER, offsetof(CRMFCertRequest, certReqId)},
- { SEC_ASN1_INLINE, offsetof(CRMFCertRequest, certTemplate),
- CRMFCertTemplateTemplate},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF,
- offsetof(CRMFCertRequest,controls),
- CRMFControlTemplate}, /* SEQUENCE SIZE (1...MAX)*/
- { 0 }
-};
-
-const SEC_ASN1Template CRMFCertReqMsgTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRMFCertReqMsg) },
- { SEC_ASN1_POINTER, offsetof(CRMFCertReqMsg, certReq),
- CRMFCertRequestTemplate },
- { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
- offsetof(CRMFCertReqMsg, derPOP) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF,
- offsetof(CRMFCertReqMsg, regInfo),
- CRMFAttributeTemplate}, /* SEQUENCE SIZE (1...MAX)*/
- { 0 }
-};
-
-const SEC_ASN1Template CRMFCertReqMessagesTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, offsetof(CRMFCertReqMessages, messages),
- CRMFCertReqMsgTemplate, sizeof (CRMFCertReqMessages)}
-};
-
-static const SEC_ASN1Template CRMFPOPOSigningKeyInputTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL,sizeof(CRMFPOPOSigningKeyInput) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(CRMFPOPOSigningKeyInput, authInfo.sender) },
- { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL | 1,
- offsetof (CRMFPOPOSigningKeyInput, authInfo.publicKeyMAC) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CRMFPOPOSigningKeyInput, publicKey),
- SEC_ASN1_SUB(CERT_SubjectPublicKeyInfoTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CRMFRAVerifiedTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | 0 | SEC_ASN1_XTRN,
- 0,
- SEC_ASN1_SUB(SEC_NullTemplate) },
- { 0 }
-};
-
-
-/* This template will need to add POPOSigningKeyInput eventually, maybe*/
-static const SEC_ASN1Template crmfPOPOSigningKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRMFPOPOSigningKey) },
- { SEC_ASN1_NO_STREAM | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 0,
- offsetof(CRMFPOPOSigningKey, derInput),
- SEC_ASN1_SUB(SEC_AnyTemplate) },
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(CRMFPOPOSigningKey, algorithmIdentifier),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_BIT_STRING | SEC_ASN1_XTRN,
- offsetof(CRMFPOPOSigningKey, signature),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CRMFPOPOSigningKeyTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | 1,
- 0,
- crmfPOPOSigningKeyTemplate},
- { 0 }
-};
-
-const SEC_ASN1Template CRMFThisMessageTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- 0,
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CRMFSubsequentMessageTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- 0,
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CRMFDHMACTemplate[] = {
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
- 0,
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CRMFPOPOKeyEnciphermentTemplate[] = {
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
- 0,
- SEC_ASN1_SUB(SEC_AnyTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template CRMFPOPOKeyAgreementTemplate[] = {
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 3,
- 0,
- SEC_ASN1_SUB(SEC_AnyTemplate)},
- { 0 }
-};
-
-const SEC_ASN1Template CRMFEncryptedValueTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRMFEncryptedValue)},
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER |
- SEC_ASN1_XTRN | 0,
- offsetof(CRMFEncryptedValue, intendedAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER |
- SEC_ASN1_XTRN | 1,
- offsetof (CRMFEncryptedValue, symmAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_NO_STREAM | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_OPTIONAL |
- SEC_ASN1_XTRN | 2,
- offsetof(CRMFEncryptedValue, encSymmKey),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER |
- SEC_ASN1_XTRN | 3,
- offsetof(CRMFEncryptedValue, keyAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_NO_STREAM | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 4,
- offsetof(CRMFEncryptedValue, valueHint),
- SEC_ASN1_SUB(SEC_OctetStringTemplate) },
- { SEC_ASN1_BIT_STRING, offsetof(CRMFEncryptedValue, encValue) },
- { 0 }
-};
-
-const SEC_ASN1Template CRMFEncryptedKeyWithEncryptedValueTemplate [] = {
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | 0,
- 0,
- CRMFEncryptedValueTemplate},
- { 0 }
-};
-
-static const SEC_ASN1Template CRMFSinglePubInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (CRMFSinglePubInfo)},
- { SEC_ASN1_INTEGER, offsetof(CRMFSinglePubInfo, pubMethod) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC,
- offsetof(CRMFSinglePubInfo, pubLocation) },
- { 0 }
-};
-
-static const SEC_ASN1Template CRMFPublicationInfoTemplate[] ={
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRMFPKIPublicationInfo) },
- { SEC_ASN1_INTEGER, offsetof(CRMFPKIPublicationInfo, action) },
- { SEC_ASN1_POINTER, offsetof(CRMFPKIPublicationInfo, pubInfos),
- CRMFSinglePubInfoTemplate},
- { 0 }
-};
diff --git a/security/nss/lib/crmf/encutil.c b/security/nss/lib/crmf/encutil.c
deleted file mode 100644
index ffa99edcc..000000000
--- a/security/nss/lib/crmf/encutil.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secasn1.h"
-#include "crmf.h"
-#include "crmfi.h"
-
-void
-crmf_encoder_out(void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
-{
- struct crmfEncoderOutput *output;
-
- output = (struct crmfEncoderOutput*) arg;
- output->fn (output->outputArg, buf, len);
-}
-
-SECStatus
-cmmf_user_encode(void *src, CRMFEncoderOutputCallback inCallback, void *inArg,
- const SEC_ASN1Template *inTemplate)
-{
- struct crmfEncoderOutput output;
-
- PORT_Assert(src != NULL);
- if (src == NULL) {
- return SECFailure;
- }
- output.fn = inCallback;
- output.outputArg = inArg;
- return SEC_ASN1Encode(src, inTemplate, crmf_encoder_out, &output);
-}
-
diff --git a/security/nss/lib/crmf/manifest.mn b/security/nss/lib/crmf/manifest.mn
deleted file mode 100644
index 182291a3a..000000000
--- a/security/nss/lib/crmf/manifest.mn
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-CORE_DEPTH = ../../..
-
-MODULE = nss
-
-EXPORTS = \
- crmf.h \
- crmft.h \
- cmmf.h \
- cmmft.h \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- crmfi.h \
- crmfit.h \
- cmmfi.h \
- cmmfit.h \
- $(NULL)
-
-CSRCS = crmfenc.c \
- crmftmpl.c \
- crmfreq.c \
- crmfpop.c \
- crmfdec.c \
- crmfget.c \
- crmfcont.c \
- cmmfasn1.c \
- cmmfresp.c \
- cmmfrec.c \
- cmmfchal.c \
- servget.c \
- encutil.c \
- respcli.c \
- respcmn.c \
- challcli.c \
- asn1cmn.c \
- $(NULL)
-
-LIBRARY_NAME = crmf
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/crmf/respcli.c b/security/nss/lib/crmf/respcli.c
deleted file mode 100644
index f6c94931c..000000000
--- a/security/nss/lib/crmf/respcli.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-/*
- * This file will contain all routines needed by a client that has
- * to parse a CMMFCertRepContent structure and retirieve the appropriate
- * data.
- */
-
-#include "cmmf.h"
-#include "cmmfi.h"
-#include "crmf.h"
-#include "crmfi.h"
-#include "secitem.h"
-#include "secder.h"
-#include "secasn1.h"
-
-CMMFCertRepContent*
-CMMF_CreateCertRepContentFromDER(CERTCertDBHandle *db, const char *buf,
- long len)
-{
- PRArenaPool *poolp;
- CMMFCertRepContent *certRepContent;
- SECStatus rv;
- int i;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return NULL;
- }
- certRepContent = PORT_ArenaZNew(poolp, CMMFCertRepContent);
- if (certRepContent == NULL) {
- goto loser;
- }
- certRepContent->poolp = poolp;
- rv = SEC_ASN1Decode(poolp, certRepContent, CMMFCertRepContentTemplate,
- buf, len);
- if (rv != SECSuccess) {
- goto loser;
- }
- if (certRepContent->response != NULL) {
- for (i=0; certRepContent->response[i] != NULL; i++) {
- rv = cmmf_decode_process_cert_response(poolp, db,
- certRepContent->response[i]);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- }
- certRepContent->isDecoded = PR_TRUE;
- return certRepContent;
- loser:
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
-}
-
-long
-CMMF_CertResponseGetCertReqId(CMMFCertResponse *inCertResp)
-{
- PORT_Assert(inCertResp != NULL);
- if (inCertResp == NULL) {
- return -1;
- }
- return DER_GetInteger(&inCertResp->certReqId);
-}
-
-PRBool
-cmmf_CertRepContentIsIndexValid(CMMFCertRepContent *inCertRepContent,
- int inIndex)
-{
- int numResponses;
-
- PORT_Assert(inCertRepContent != NULL);
- numResponses = CMMF_CertRepContentGetNumResponses(inCertRepContent);
- return (PRBool)(inIndex >= 0 && inIndex < numResponses);
-}
-
-CMMFCertResponse*
-CMMF_CertRepContentGetResponseAtIndex(CMMFCertRepContent *inCertRepContent,
- int inIndex)
-{
- CMMFCertResponse *certResponse;
- SECStatus rv;
-
- PORT_Assert(inCertRepContent != NULL &&
- cmmf_CertRepContentIsIndexValid(inCertRepContent, inIndex));
- if (inCertRepContent == NULL ||
- !cmmf_CertRepContentIsIndexValid(inCertRepContent, inIndex)) {
- return NULL;
- }
- certResponse = PORT_ZNew(CMMFCertResponse);
- rv = cmmf_CopyCertResponse(NULL, certResponse,
- inCertRepContent->response[inIndex]);
- if (rv != SECSuccess) {
- CMMF_DestroyCertResponse(certResponse);
- certResponse = NULL;
- }
- return certResponse;
-}
-
-CMMFPKIStatus
-CMMF_CertResponseGetPKIStatusInfoStatus(CMMFCertResponse *inCertResp)
-{
- PORT_Assert(inCertResp != NULL);
- if (inCertResp == NULL) {
- return cmmfNoPKIStatus;
- }
- return cmmf_PKIStatusInfoGetStatus(&inCertResp->status);
-}
-
-CERTCertificate*
-CMMF_CertResponseGetCertificate(CMMFCertResponse *inCertResp,
- CERTCertDBHandle *inCertdb)
-{
- PORT_Assert(inCertResp != NULL);
- if (inCertResp == NULL || inCertResp->certifiedKeyPair == NULL) {
- return NULL;
- }
-
- return cmmf_CertOrEncCertGetCertificate(
- &inCertResp->certifiedKeyPair->certOrEncCert, inCertdb);
-
-}
-
-CERTCertList*
-CMMF_CertRepContentGetCAPubs (CMMFCertRepContent *inCertRepContent)
-{
- PORT_Assert (inCertRepContent != NULL);
- if (inCertRepContent == NULL || inCertRepContent->caPubs == NULL) {
- return NULL;
- }
- return cmmf_MakeCertList(inCertRepContent->caPubs);
-}
-
diff --git a/security/nss/lib/crmf/respcmn.c b/security/nss/lib/crmf/respcmn.c
deleted file mode 100644
index c9be9cf49..000000000
--- a/security/nss/lib/crmf/respcmn.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "cmmf.h"
-#include "cmmfi.h"
-#include "secitem.h"
-#include "secder.h"
-
-SECStatus
-cmmf_DestroyPKIStatusInfo (CMMFPKIStatusInfo *info, PRBool freeit)
-{
- if (info->status.data != NULL) {
- PORT_Free(info->status.data);
- info->status.data = NULL;
- }
- if (info->statusString.data != NULL) {
- PORT_Free(info->statusString.data);
- info->statusString.data = NULL;
- }
- if (info->failInfo.data != NULL) {
- PORT_Free(info->failInfo.data);
- info->failInfo.data = NULL;
- }
- if (freeit) {
- PORT_Free(info);
- }
- return SECSuccess;
-}
-
-SECStatus
-CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp)
-{
- PORT_Assert(inCertResp != NULL);
- if (inCertResp != NULL) {
- if (inCertResp->certReqId.data != NULL) {
- PORT_Free(inCertResp->certReqId.data);
- }
- cmmf_DestroyPKIStatusInfo(&inCertResp->status, PR_FALSE);
- if (inCertResp->certifiedKeyPair != NULL) {
- CMMF_DestroyCertifiedKeyPair(inCertResp->certifiedKeyPair);
- }
- PORT_Free(inCertResp);
- }
- return SECSuccess;
-}
-
-SECStatus
-CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent)
-{
- PORT_Assert(inCertRepContent != NULL);
- if (inCertRepContent != NULL) {
- CMMFCertResponse **pResponse = inCertRepContent->response;
- if (pResponse != NULL) {
- for (; *pResponse != NULL; pResponse++) {
- CMMFCertifiedKeyPair *certKeyPair = (*pResponse)->certifiedKeyPair;
- /* XXX Why not call CMMF_DestroyCertifiedKeyPair or
- ** XXX cmmf_DestroyCertOrEncCert ?
- */
- if (certKeyPair != NULL &&
- certKeyPair->certOrEncCert.choice == cmmfCertificate &&
- certKeyPair->certOrEncCert.cert.certificate != NULL) {
- CERT_DestroyCertificate
- (certKeyPair->certOrEncCert.cert.certificate);
- certKeyPair->certOrEncCert.cert.certificate = NULL;
- }
- }
- }
- if (inCertRepContent->caPubs) {
- CERTCertificate **caPubs = inCertRepContent->caPubs;
- for (; *caPubs; ++caPubs) {
- CERT_DestroyCertificate(*caPubs);
- *caPubs = NULL;
- }
- }
- if (inCertRepContent->poolp != NULL) {
- PORT_FreeArena(inCertRepContent->poolp, PR_TRUE);
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont)
-{
- PORT_Assert(inDecKeyCont != NULL);
- if (inDecKeyCont != NULL && inDecKeyCont->poolp) {
- PORT_FreeArena(inDecKeyCont->poolp, PR_FALSE);
- }
- return SECSuccess;
-}
-
-SECStatus
-crmf_create_prtime(SECItem *src, PRTime **dest)
-{
- *dest = PORT_ZNew(PRTime);
- return DER_DecodeTimeChoice(*dest, src);
-}
-
-CRMFCertExtension*
-crmf_copy_cert_extension(PRArenaPool *poolp, CRMFCertExtension *inExtension)
-{
- PRBool isCritical;
- SECOidTag id;
- SECItem *data;
- CRMFCertExtension *newExt;
-
- PORT_Assert(inExtension != NULL);
- if (inExtension == NULL) {
- return NULL;
- }
- id = CRMF_CertExtensionGetOidTag(inExtension);
- isCritical = CRMF_CertExtensionGetIsCritical(inExtension);
- data = CRMF_CertExtensionGetValue(inExtension);
- newExt = crmf_create_cert_extension(poolp, id,
- isCritical,
- data);
- SECITEM_FreeItem(data, PR_TRUE);
- return newExt;
-}
-
-static SECItem*
-cmmf_encode_certificate(CERTCertificate *inCert)
-{
- return SEC_ASN1EncodeItem(NULL, NULL, inCert,
- SEC_ASN1_GET(SEC_SignedCertificateTemplate));
-}
-
-CERTCertList*
-cmmf_MakeCertList(CERTCertificate **inCerts)
-{
- CERTCertList *certList;
- CERTCertificate *currCert;
- SECItem *derCert, *freeCert = NULL;
- SECStatus rv;
- int i;
-
- certList = CERT_NewCertList();
- if (certList == NULL) {
- return NULL;
- }
- for (i=0; inCerts[i] != NULL; i++) {
- derCert = &inCerts[i]->derCert;
- if (derCert->data == NULL) {
- derCert = freeCert = cmmf_encode_certificate(inCerts[i]);
- }
- currCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- derCert, NULL, PR_FALSE, PR_TRUE);
- if (freeCert != NULL) {
- SECITEM_FreeItem(freeCert, PR_TRUE);
- freeCert = NULL;
- }
- if (currCert == NULL) {
- goto loser;
- }
- rv = CERT_AddCertToListTail(certList, currCert);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- return certList;
- loser:
- CERT_DestroyCertList(certList);
- return NULL;
-}
-
-CMMFPKIStatus
-cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus)
-{
- long derVal;
-
- derVal = DER_GetInteger(&inStatus->status);
- if (derVal == -1 || derVal < cmmfGranted || derVal >= cmmfNumPKIStatus) {
- return cmmfNoPKIStatus;
- }
- return (CMMFPKIStatus)derVal;
-}
-
-int
-CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent)
-{
- int numResponses = 0;
- PORT_Assert (inCertRepContent != NULL);
- if (inCertRepContent != NULL && inCertRepContent->response != NULL) {
- while (inCertRepContent->response[numResponses] != NULL) {
- numResponses++;
- }
- }
- return numResponses;
-}
-
-
-SECStatus
-cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit)
-{
- switch (certOrEncCert->choice) {
- case cmmfCertificate:
- CERT_DestroyCertificate(certOrEncCert->cert.certificate);
- certOrEncCert->cert.certificate = NULL;
- break;
- case cmmfEncryptedCert:
- crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert,
- PR_TRUE);
- certOrEncCert->cert.encryptedCert = NULL;
- break;
- default:
- break;
- }
- if (freeit) {
- PORT_Free(certOrEncCert);
- }
- return SECSuccess;
-}
-
-SECStatus
-cmmf_copy_secitem (PRArenaPool *poolp, SECItem *dest, SECItem *src)
-{
- SECStatus rv;
-
- if (src->data != NULL) {
- rv = SECITEM_CopyItem(poolp, dest, src);
- } else {
- dest->data = NULL;
- dest->len = 0;
- rv = SECSuccess;
- }
- return rv;
-}
-
-SECStatus
-CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair)
-{
- PORT_Assert(inCertKeyPair != NULL);
- if (inCertKeyPair != NULL) {
- cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE);
- if (inCertKeyPair->privateKey) {
- crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE);
- }
- if (inCertKeyPair->derPublicationInfo.data) {
- PORT_Free(inCertKeyPair->derPublicationInfo.data);
- }
- PORT_Free(inCertKeyPair);
- }
- return SECSuccess;
-}
-
-SECStatus
-cmmf_CopyCertResponse(PRArenaPool *poolp,
- CMMFCertResponse *dest,
- CMMFCertResponse *src)
-{
- SECStatus rv;
-
- if (src->certReqId.data != NULL) {
- rv = SECITEM_CopyItem(poolp, &dest->certReqId, &src->certReqId);
- if (rv != SECSuccess) {
- return rv;
- }
- }
- rv = cmmf_CopyPKIStatusInfo(poolp, &dest->status, &src->status);
- if (rv != SECSuccess) {
- return rv;
- }
- if (src->certifiedKeyPair != NULL) {
- CMMFCertifiedKeyPair *destKeyPair;
-
- destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) :
- PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair);
- if (!destKeyPair) {
- return SECFailure;
- }
- rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair,
- src->certifiedKeyPair);
- if (rv != SECSuccess) {
- if (!poolp) {
- CMMF_DestroyCertifiedKeyPair(destKeyPair);
- }
- return rv;
- }
- dest->certifiedKeyPair = destKeyPair;
- }
- return SECSuccess;
-}
-
-static SECStatus
-cmmf_CopyCertOrEncCert(PRArenaPool *poolp, CMMFCertOrEncCert *dest,
- CMMFCertOrEncCert *src)
-{
- SECStatus rv = SECSuccess;
- CRMFEncryptedValue *encVal;
-
- dest->choice = src->choice;
- rv = cmmf_copy_secitem(poolp, &dest->derValue, &src->derValue);
- switch (src->choice) {
- case cmmfCertificate:
- dest->cert.certificate = CERT_DupCertificate(src->cert.certificate);
- break;
- case cmmfEncryptedCert:
- encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) :
- PORT_ArenaZNew(poolp, CRMFEncryptedValue);
- if (encVal == NULL) {
- return SECFailure;
- }
- rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal);
- if (rv != SECSuccess) {
- if (!poolp) {
- crmf_destroy_encrypted_value(encVal, PR_TRUE);
- }
- return rv;
- }
- dest->cert.encryptedCert = encVal;
- break;
- default:
- rv = SECFailure;
- }
- return rv;
-}
-
-SECStatus
-cmmf_CopyCertifiedKeyPair(PRArenaPool *poolp, CMMFCertifiedKeyPair *dest,
- CMMFCertifiedKeyPair *src)
-{
- SECStatus rv;
-
- rv = cmmf_CopyCertOrEncCert(poolp, &dest->certOrEncCert,
- &src->certOrEncCert);
- if (rv != SECSuccess) {
- return rv;
- }
-
- if (src->privateKey != NULL) {
- CRMFEncryptedValue *encVal;
-
- encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) :
- PORT_ArenaZNew(poolp, CRMFEncryptedValue);
- if (encVal == NULL) {
- return SECFailure;
- }
- rv = crmf_copy_encryptedvalue(poolp, src->privateKey,
- encVal);
- if (rv != SECSuccess) {
- if (!poolp) {
- crmf_destroy_encrypted_value(encVal, PR_TRUE);
- }
- return rv;
- }
- dest->privateKey = encVal;
- }
- rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo,
- &src->derPublicationInfo);
- return rv;
-}
-
-SECStatus
-cmmf_CopyPKIStatusInfo(PRArenaPool *poolp, CMMFPKIStatusInfo *dest,
- CMMFPKIStatusInfo *src)
-{
- SECStatus rv;
-
- rv = cmmf_copy_secitem (poolp, &dest->status, &src->status);
- if (rv != SECSuccess) {
- return rv;
- }
- rv = cmmf_copy_secitem (poolp, &dest->statusString, &src->statusString);
- if (rv != SECSuccess) {
- return rv;
- }
- rv = cmmf_copy_secitem (poolp, &dest->failInfo, &src->failInfo);
- return rv;
-}
-
-CERTCertificate*
-cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert,
- CERTCertDBHandle *certdb)
-{
- if (certOrEncCert->choice != cmmfCertificate ||
- certOrEncCert->cert.certificate == NULL) {
- return NULL;
- }
- return CERT_NewTempCertificate(certdb,
- &certOrEncCert->cert.certificate->derCert,
- NULL, PR_FALSE, PR_TRUE);
-}
-
-SECStatus
-cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo,
- PRArenaPool *poolp,
- CMMFPKIStatus inStatus)
-{
- SECItem *dummy;
-
- if (inStatus <cmmfGranted || inStatus >= cmmfNumPKIStatus) {
- return SECFailure;
- }
-
- dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus);
- PORT_Assert(dummy == &statusInfo->status);
- if (dummy != &statusInfo->status) {
- SECITEM_FreeItem(dummy, PR_TRUE);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-
diff --git a/security/nss/lib/crmf/servget.c b/security/nss/lib/crmf/servget.c
deleted file mode 100644
index d748d86f8..000000000
--- a/security/nss/lib/crmf/servget.c
+++ /dev/null
@@ -1,978 +0,0 @@
-/* -*- Mode: C; tab-width: 8 -*-*/
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#include "cmmf.h"
-#include "cmmfi.h"
-#include "secitem.h"
-#include "keyhi.h"
-#include "secder.h"
-
-CRMFEncryptedKeyChoice
-CRMF_EncryptedKeyGetChoice(CRMFEncryptedKey *inEncrKey)
-{
- PORT_Assert(inEncrKey != NULL);
- if (inEncrKey == NULL) {
- return crmfNoEncryptedKeyChoice;
- }
- return inEncrKey->encKeyChoice;
-}
-
-CRMFEncryptedValue*
-CRMF_EncryptedKeyGetEncryptedValue(CRMFEncryptedKey *inEncrKey)
-{
- CRMFEncryptedValue *newEncrValue = NULL;
- SECStatus rv;
-
- PORT_Assert(inEncrKey != NULL);
- if (inEncrKey == NULL ||
- CRMF_EncryptedKeyGetChoice(inEncrKey) != crmfEncryptedValueChoice) {
- goto loser;
- }
- newEncrValue = PORT_ZNew(CRMFEncryptedValue);
- if (newEncrValue == NULL) {
- goto loser;
- }
- rv = crmf_copy_encryptedvalue(NULL, &inEncrKey->value.encryptedValue,
- newEncrValue);
- if (rv != SECSuccess) {
- goto loser;
- }
- return newEncrValue;
- loser:
- if (newEncrValue != NULL) {
- CRMF_DestroyEncryptedValue(newEncrValue);
- }
- return NULL;
-}
-
-static SECItem*
-crmf_get_encvalue_bitstring(SECItem *srcItem)
-{
- SECItem *newItem = NULL;
- SECStatus rv;
-
- if (srcItem->data == NULL) {
- return NULL;
- }
- newItem = PORT_ZNew(SECItem);
- if (newItem == NULL) {
- goto loser;
- }
- rv = crmf_make_bitstring_copy(NULL, newItem, srcItem);
- if (rv != SECSuccess) {
- goto loser;
- }
- return newItem;
- loser:
- if (newItem != NULL) {
- SECITEM_FreeItem(newItem, PR_TRUE);
- }
- return NULL;
-}
-
-SECItem*
-CRMF_EncryptedValueGetEncSymmKey(CRMFEncryptedValue *inEncValue)
-{
- if (inEncValue == NULL) {
- return NULL;
- }
- return crmf_get_encvalue_bitstring(&inEncValue->encSymmKey);
-}
-
-SECItem*
-CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue *inEncrValue)
-{
- if (inEncrValue == NULL || inEncrValue->encValue.data == NULL) {
- return NULL;
- }
- return crmf_get_encvalue_bitstring(&inEncrValue->encValue);
-}
-
-static SECAlgorithmID*
-crmf_get_encvalue_algid(SECAlgorithmID *srcAlg)
-{
- SECStatus rv;
- SECAlgorithmID *newAlgID;
-
- if (srcAlg == NULL) {
- return NULL;
- }
- rv = crmf_copy_encryptedvalue_secalg(NULL, srcAlg, &newAlgID);
- if (rv != SECSuccess) {
- return NULL;
- }
- return newAlgID;
-}
-
-SECAlgorithmID*
-CRMF_EncryptedValueGetIntendedAlg(CRMFEncryptedValue *inEncValue)
-{
- if (inEncValue == NULL) {
- return NULL;
- }
- return crmf_get_encvalue_algid(inEncValue->intendedAlg);
-}
-
-SECAlgorithmID*
-CRMF_EncryptedValueGetKeyAlg(CRMFEncryptedValue *inEncValue)
-{
- if (inEncValue == NULL) {
- return NULL;
- }
- return crmf_get_encvalue_algid(inEncValue->keyAlg);
-}
-
-SECAlgorithmID*
-CRMF_EncryptedValueGetSymmAlg(CRMFEncryptedValue *inEncValue)
-{
- if (inEncValue == NULL) {
- return NULL;
- }
- return crmf_get_encvalue_algid(inEncValue->symmAlg);
-}
-
-SECItem*
-CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue *inEncValue)
-{
- if (inEncValue == NULL || inEncValue->valueHint.data == NULL) {
- return NULL;
- }
- return SECITEM_DupItem(&inEncValue->valueHint);
-}
-
-SECStatus
-CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey(CRMFPKIArchiveOptions *inOpt,
- PRBool *destVal)
-{
- if (inOpt == NULL || destVal == NULL ||
- CRMF_PKIArchiveOptionsGetOptionType(inOpt) != crmfArchiveRemGenPrivKey){
- return SECFailure;
- }
- *destVal = (inOpt->option.archiveRemGenPrivKey.data[0] == hexFalse)
- ? PR_FALSE:
- PR_TRUE;
- return SECSuccess;
-}
-
-CRMFEncryptedKey*
-CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions *inOpts)
-{
- CRMFEncryptedKey *newEncrKey = NULL;
- SECStatus rv;
-
- PORT_Assert(inOpts != NULL);
- if (inOpts == NULL ||
- CRMF_PKIArchiveOptionsGetOptionType(inOpts) != crmfEncryptedPrivateKey){
- return NULL;
- }
- newEncrKey = PORT_ZNew(CRMFEncryptedKey);
- if (newEncrKey == NULL) {
- goto loser;
- }
- rv = crmf_copy_encryptedkey(NULL, &inOpts->option.encryptedKey,
- newEncrKey);
- if (rv != SECSuccess) {
- goto loser;
- }
- return newEncrKey;
- loser:
- if (newEncrKey != NULL) {
- CRMF_DestroyEncryptedKey(newEncrKey);
- }
- return NULL;
-}
-
-SECItem*
-CRMF_PKIArchiveOptionsGetKeyGenParameters(CRMFPKIArchiveOptions *inOptions)
-{
- if (inOptions == NULL ||
- CRMF_PKIArchiveOptionsGetOptionType(inOptions) != crmfKeyGenParameters ||
- inOptions->option.keyGenParameters.data == NULL) {
- return NULL;
- }
- return SECITEM_DupItem(&inOptions->option.keyGenParameters);
-}
-
-CRMFPKIArchiveOptionsType
-CRMF_PKIArchiveOptionsGetOptionType(CRMFPKIArchiveOptions *inOptions)
-{
- PORT_Assert (inOptions != NULL);
- if (inOptions == NULL) {
- return crmfNoArchiveOptions;
- }
- return inOptions->archOption;
-}
-
-static SECStatus
-crmf_extract_long_from_item(SECItem *intItem, long *destLong)
-{
- *destLong = DER_GetInteger(intItem);
- return (*destLong == -1) ? SECFailure : SECSuccess;
-}
-
-SECStatus
-CRMF_POPOPrivGetKeySubseqMess(CRMFPOPOPrivKey *inKey,
- CRMFSubseqMessOptions *destOpt)
-{
- long value;
- SECStatus rv;
-
- PORT_Assert(inKey != NULL);
- if (inKey == NULL ||
- inKey->messageChoice != crmfSubsequentMessage) {
- return SECFailure;
- }
- rv = crmf_extract_long_from_item(&inKey->message.subsequentMessage,&value);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- switch (value) {
- case 0:
- *destOpt = crmfEncrCert;
- break;
- case 1:
- *destOpt = crmfChallengeResp;
- break;
- default:
- rv = SECFailure;
- }
- if (rv != SECSuccess) {
- return rv;
- }
- return SECSuccess;
-}
-
-CRMFPOPOPrivKeyChoice
-CRMF_POPOPrivKeyGetChoice(CRMFPOPOPrivKey *inPrivKey)
-{
- PORT_Assert(inPrivKey != NULL);
- if (inPrivKey != NULL) {
- return inPrivKey->messageChoice;
- }
- return crmfNoMessage;
-}
-
-SECStatus
-CRMF_POPOPrivKeyGetDHMAC(CRMFPOPOPrivKey *inKey, SECItem *destMAC)
-{
- PORT_Assert(inKey != NULL);
- if (inKey == NULL || inKey->message.dhMAC.data == NULL) {
- return SECFailure;
- }
- return crmf_make_bitstring_copy(NULL, destMAC, &inKey->message.dhMAC);
-}
-
-SECStatus
-CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey *inKey,
- SECItem *destString)
-{
- PORT_Assert(inKey != NULL);
- if (inKey == NULL ||
- inKey->messageChoice != crmfThisMessage) {
- return SECFailure;
- }
-
- return crmf_make_bitstring_copy(NULL, destString,
- &inKey->message.thisMessage);
-}
-
-SECAlgorithmID*
-CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey *inSignKey)
-{
- SECAlgorithmID *newAlgId = NULL;
- SECStatus rv;
-
- PORT_Assert(inSignKey != NULL);
- if (inSignKey == NULL) {
- return NULL;
- }
- newAlgId = PORT_ZNew(SECAlgorithmID);
- if (newAlgId == NULL) {
- goto loser;
- }
- rv = SECOID_CopyAlgorithmID(NULL, newAlgId,
- inSignKey->algorithmIdentifier);
- if (rv != SECSuccess) {
- goto loser;
- }
- return newAlgId;
-
- loser:
- if (newAlgId != NULL) {
- SECOID_DestroyAlgorithmID(newAlgId, PR_TRUE);
- }
- return NULL;
-}
-
-SECItem*
-CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey)
-{
- PORT_Assert(inSignKey != NULL);
- if (inSignKey == NULL || inSignKey->derInput.data == NULL) {
- return NULL;
- }
- return SECITEM_DupItem(&inSignKey->derInput);
-}
-
-SECItem*
-CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey)
-{
- SECItem *newSig = NULL;
- SECStatus rv;
-
- PORT_Assert(inSignKey != NULL);
- if (inSignKey == NULL) {
- return NULL;
- }
- newSig = PORT_ZNew(SECItem);
- if (newSig == NULL) {
- goto loser;
- }
- rv = crmf_make_bitstring_copy(NULL, newSig, &inSignKey->signature);
- if (rv != SECSuccess) {
- goto loser;
- }
- return newSig;
- loser:
- if (newSig != NULL) {
- SECITEM_FreeItem(newSig, PR_TRUE);
- }
- return NULL;
-}
-
-static SECStatus
-crmf_copy_poposigningkey(PRArenaPool *poolp,
- CRMFPOPOSigningKey *inPopoSignKey,
- CRMFPOPOSigningKey *destPopoSignKey)
-{
- SECStatus rv;
-
- /* We don't support use of the POPOSigningKeyInput, so we'll only
- * store away the DER encoding.
- */
- if (inPopoSignKey->derInput.data != NULL) {
- rv = SECITEM_CopyItem(poolp, &destPopoSignKey->derInput,
- &inPopoSignKey->derInput);
- }
- destPopoSignKey->algorithmIdentifier = (poolp == NULL) ?
- PORT_ZNew(SECAlgorithmID) :
- PORT_ArenaZNew(poolp, SECAlgorithmID);
-
- if (destPopoSignKey->algorithmIdentifier == NULL) {
- goto loser;
- }
- rv = SECOID_CopyAlgorithmID(poolp, destPopoSignKey->algorithmIdentifier,
- inPopoSignKey->algorithmIdentifier);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = crmf_make_bitstring_copy(poolp, &destPopoSignKey->signature,
- &inPopoSignKey->signature);
- if (rv != SECSuccess) {
- goto loser;
- }
- return SECSuccess;
- loser:
- if (poolp == NULL) {
- CRMF_DestroyPOPOSigningKey(destPopoSignKey);
- }
- return SECFailure;
-}
-
-static SECStatus
-crmf_copy_popoprivkey(PRArenaPool *poolp,
- CRMFPOPOPrivKey *srcPrivKey,
- CRMFPOPOPrivKey *destPrivKey)
-{
- SECStatus rv;
-
- destPrivKey->messageChoice = srcPrivKey->messageChoice;
- switch (destPrivKey->messageChoice) {
- case crmfThisMessage:
- case crmfDHMAC:
- /* I've got a union, so taking the address of one, will also give
- * me a pointer to the other (eg, message.dhMAC)
- */
- rv = crmf_make_bitstring_copy(poolp, &destPrivKey->message.thisMessage,
- &srcPrivKey->message.thisMessage);
- break;
- case crmfSubsequentMessage:
- rv = SECITEM_CopyItem(poolp, &destPrivKey->message.subsequentMessage,
- &srcPrivKey->message.subsequentMessage);
- break;
- default:
- rv = SECFailure;
- }
-
- if (rv != SECSuccess && poolp == NULL) {
- CRMF_DestroyPOPOPrivKey(destPrivKey);
- }
- return rv;
-}
-
-static CRMFProofOfPossession*
-crmf_copy_pop(PRArenaPool *poolp, CRMFProofOfPossession *srcPOP)
-{
- CRMFProofOfPossession *newPOP;
- SECStatus rv;
-
- /*
- * Proof Of Possession structures are always part of the Request
- * message, so there will always be an arena for allocating memory.
- */
- if (poolp == NULL) {
- return NULL;
- }
- newPOP = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
- if (newPOP == NULL) {
- return NULL;
- }
- switch (srcPOP->popUsed) {
- case crmfRAVerified:
- newPOP->popChoice.raVerified.data = NULL;
- newPOP->popChoice.raVerified.len = 0;
- break;
- case crmfSignature:
- rv = crmf_copy_poposigningkey(poolp, &srcPOP->popChoice.signature,
- &newPOP->popChoice.signature);
- if (rv != SECSuccess) {
- goto loser;
- }
- break;
- case crmfKeyEncipherment:
- case crmfKeyAgreement:
- /* We've got a union, so a pointer to one, is a pointer to the
- * other one.
- */
- rv = crmf_copy_popoprivkey(poolp, &srcPOP->popChoice.keyEncipherment,
- &newPOP->popChoice.keyEncipherment);
- if (rv != SECSuccess) {
- goto loser;
- }
- break;
- default:
- goto loser;
- }
- newPOP->popUsed = srcPOP->popUsed;
- return newPOP;
-
- loser:
- return NULL;
-}
-
-static CRMFCertReqMsg*
-crmf_copy_cert_req_msg(CRMFCertReqMsg *srcReqMsg)
-{
- CRMFCertReqMsg *newReqMsg;
- PRArenaPool *poolp;
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return NULL;
- }
- newReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
- if (newReqMsg == NULL) {
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
- }
-
- newReqMsg->poolp = poolp;
- newReqMsg->certReq = crmf_copy_cert_request(poolp, srcReqMsg->certReq);
- if (newReqMsg->certReq == NULL) {
- goto loser;
- }
- newReqMsg->pop = crmf_copy_pop(poolp, srcReqMsg->pop);
- if (newReqMsg->pop == NULL) {
- goto loser;
- }
- /* None of my set/get routines operate on the regInfo field, so
- * for now, that won't get copied over.
- */
- return newReqMsg;
-
- loser:
- if (newReqMsg != NULL) {
- CRMF_DestroyCertReqMsg(newReqMsg);
- }
- return NULL;
-}
-
-CRMFCertReqMsg*
-CRMF_CertReqMessagesGetCertReqMsgAtIndex(CRMFCertReqMessages *inReqMsgs,
- int index)
-{
- int numMsgs;
-
- PORT_Assert(inReqMsgs != NULL && index >= 0);
- if (inReqMsgs == NULL) {
- return NULL;
- }
- numMsgs = CRMF_CertReqMessagesGetNumMessages(inReqMsgs);
- if (index < 0 || index >= numMsgs) {
- return NULL;
- }
- return crmf_copy_cert_req_msg(inReqMsgs->messages[index]);
-}
-
-int
-CRMF_CertReqMessagesGetNumMessages(CRMFCertReqMessages *inCertReqMsgs)
-{
- int numMessages = 0;
-
- PORT_Assert(inCertReqMsgs != NULL);
- if (inCertReqMsgs == NULL) {
- return 0;
- }
- while (inCertReqMsgs->messages[numMessages] != NULL) {
- numMessages++;
- }
- return numMessages;
-}
-
-CRMFCertRequest*
-CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg *inCertReqMsg)
-{
- PRArenaPool *poolp = NULL;
- CRMFCertRequest *newCertReq = NULL;
-
- PORT_Assert(inCertReqMsg != NULL);
-
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- goto loser;
- }
- newCertReq = crmf_copy_cert_request(poolp, inCertReqMsg->certReq);
- if (newCertReq == NULL) {
- goto loser;
- }
- newCertReq->poolp = poolp;
- return newCertReq;
- loser:
- if (poolp != NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- }
- return NULL;
-}
-
-SECStatus
-CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg, long *destID)
-{
- PORT_Assert(inCertReqMsg != NULL && destID != NULL);
- if (inCertReqMsg == NULL || inCertReqMsg->certReq == NULL) {
- return SECFailure;
- }
- return crmf_extract_long_from_item(&inCertReqMsg->certReq->certReqId,
- destID);
-}
-
-SECStatus
-CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKey **destKey)
-{
- PORT_Assert(inCertReqMsg != NULL && destKey != NULL);
- if (inCertReqMsg == NULL || destKey == NULL ||
- CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyAgreement) {
- return SECFailure;
- }
- *destKey = PORT_ZNew(CRMFPOPOPrivKey);
- if (*destKey == NULL) {
- return SECFailure;
- }
- return crmf_copy_popoprivkey(NULL,
- &inCertReqMsg->pop->popChoice.keyAgreement,
- *destKey);
-}
-
-SECStatus
-CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOPrivKey **destKey)
-{
- PORT_Assert(inCertReqMsg != NULL && destKey != NULL);
- if (inCertReqMsg == NULL || destKey == NULL ||
- CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyEncipherment) {
- return SECFailure;
- }
- *destKey = PORT_ZNew(CRMFPOPOPrivKey);
- if (destKey == NULL) {
- return SECFailure;
- }
- return crmf_copy_popoprivkey(NULL,
- &inCertReqMsg->pop->popChoice.keyEncipherment,
- *destKey);
-}
-
-SECStatus
-CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg *inCertReqMsg,
- CRMFPOPOSigningKey **destKey)
-{
- CRMFProofOfPossession *pop;
- PORT_Assert(inCertReqMsg != NULL);
- if (inCertReqMsg == NULL) {
- return SECFailure;
- }
- pop = inCertReqMsg->pop;;
- if (pop->popUsed != crmfSignature) {
- return SECFailure;
- }
- *destKey = PORT_ZNew(CRMFPOPOSigningKey);
- if (*destKey == NULL) {
- return SECFailure;
- }
- return crmf_copy_poposigningkey(NULL,&pop->popChoice.signature, *destKey);
-}
-
-static SECStatus
-crmf_copy_name(CERTName *destName, CERTName *srcName)
-{
- PRArenaPool *poolp = NULL;
- SECStatus rv;
-
- if (destName->arena != NULL) {
- poolp = destName->arena;
- } else {
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- }
- if (poolp == NULL) {
- return SECFailure;
- }
- /* Need to do this so that CERT_CopyName doesn't free out
- * the arena from underneath us.
- */
- destName->arena = NULL;
- rv = CERT_CopyName(poolp, destName, srcName);
- destName->arena = poolp;
- return rv;
-}
-
-SECStatus
-CRMF_CertRequestGetCertTemplateIssuer(CRMFCertRequest *inCertReq,
- CERTName *destIssuer)
-{
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return SECFailure;
- }
- if (CRMF_DoesRequestHaveField(inCertReq, crmfIssuer)) {
- return crmf_copy_name(destIssuer,
- inCertReq->certTemplate.issuer);
- }
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest *inCertReq,
- SECItem *destIssuerUID)
-{
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return SECFailure;
- }
- if (CRMF_DoesRequestHaveField(inCertReq, crmfIssuerUID)) {
- return crmf_make_bitstring_copy(NULL, destIssuerUID,
- &inCertReq->certTemplate.issuerUID);
- }
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertRequestGetCertTemplatePublicKey(CRMFCertRequest *inCertReq,
- CERTSubjectPublicKeyInfo *destPublicKey)
-{
- PORT_Assert (inCertReq != NULL);
- if (inCertReq == NULL) {
- return SECFailure;
- }
- if (CRMF_DoesRequestHaveField(inCertReq, crmfPublicKey)) {
- return SECKEY_CopySubjectPublicKeyInfo(NULL, destPublicKey,
- inCertReq->certTemplate.publicKey);
- }
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertRequestGetCertTemplateSerialNumber(CRMFCertRequest *inCertReq,
- long *serialNumber)
-{
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return SECFailure;
- }
- if (CRMF_DoesRequestHaveField(inCertReq, crmfSerialNumber)) {
- return
- crmf_extract_long_from_item(&inCertReq->certTemplate.serialNumber,
- serialNumber);
- }
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertRequestGetCertTemplateSigningAlg(CRMFCertRequest *inCertReq,
- SECAlgorithmID *destAlg)
-{
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return SECFailure;
- }
- if (CRMF_DoesRequestHaveField(inCertReq, crmfSigningAlg)) {
- return SECOID_CopyAlgorithmID(NULL, destAlg,
- inCertReq->certTemplate.signingAlg);
- }
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertRequestGetCertTemplateSubject(CRMFCertRequest *inCertReq,
- CERTName *destSubject)
-{
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return SECFailure;
- }
- if (CRMF_DoesRequestHaveField(inCertReq, crmfSubject)) {
- return crmf_copy_name(destSubject, inCertReq->certTemplate.subject);
- }
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertRequestGetCertTemplateSubjectUID(CRMFCertRequest *inCertReq,
- SECItem *destSubjectUID)
-{
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return SECFailure;
- }
- if (CRMF_DoesRequestHaveField(inCertReq, crmfSubjectUID)) {
- return crmf_make_bitstring_copy(NULL, destSubjectUID,
- &inCertReq->certTemplate.subjectUID);
- }
- return SECFailure;
-}
-
-SECStatus
-CRMF_CertRequestGetCertTemplateVersion(CRMFCertRequest *inCertReq,
- long *version)
-{
- PORT_Assert (inCertReq != NULL);
- if (inCertReq == NULL) {
- return SECFailure;
- }
- if (CRMF_DoesRequestHaveField(inCertReq, crmfVersion)) {
- return crmf_extract_long_from_item(&inCertReq->certTemplate.version,
- version);
- }
- return SECFailure;
-}
-
-static SECStatus
-crmf_copy_validity(CRMFGetValidity *destValidity,
- CRMFOptionalValidity *src)
-{
- SECStatus rv;
-
- destValidity->notBefore = destValidity->notAfter = NULL;
- if (src->notBefore.data != NULL) {
- rv = crmf_create_prtime(&src->notBefore,
- &destValidity->notBefore);
- if (rv != SECSuccess) {
- return rv;
- }
- }
- if (src->notAfter.data != NULL) {
- rv = crmf_create_prtime(&src->notAfter,
- &destValidity->notAfter);
- if (rv != SECSuccess) {
- return rv;
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-CRMF_CertRequestGetCertTemplateValidity(CRMFCertRequest *inCertReq,
- CRMFGetValidity *destValidity)
-{
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return SECFailure;
- }
- if (CRMF_DoesRequestHaveField(inCertReq, crmfValidity)) {
- return crmf_copy_validity(destValidity,
- inCertReq->certTemplate.validity);
- }
- return SECFailure;
-}
-
-CRMFControl*
-CRMF_CertRequestGetControlAtIndex(CRMFCertRequest *inCertReq, int index)
-{
- CRMFControl *newControl, *srcControl;
- int numControls;
- SECStatus rv;
-
- PORT_Assert(inCertReq != NULL);
- if (inCertReq == NULL) {
- return NULL;
- }
- numControls = CRMF_CertRequestGetNumControls(inCertReq);
- if (index >= numControls || index < 0) {
- return NULL;
- }
- newControl = PORT_ZNew(CRMFControl);
- if (newControl == NULL) {
- return NULL;
- }
- srcControl = inCertReq->controls[index];
- newControl->tag = srcControl->tag;
- rv = SECITEM_CopyItem (NULL, &newControl->derTag, &srcControl->derTag);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = SECITEM_CopyItem(NULL, &newControl->derValue,
- &srcControl->derValue);
- if (rv != SECSuccess) {
- goto loser;
- }
- /* Copy over the PKIArchiveOptions stuff */
- switch (srcControl->tag) {
- case SEC_OID_PKIX_REGCTRL_REGTOKEN:
- case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
- /* No further processing necessary for these types. */
- rv = SECSuccess;
- break;
- case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
- case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
- case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
- /* These aren't supported yet, so no post-processing will
- * be done at this time. But we don't want to fail in case
- * we read in DER that has one of these options.
- */
- rv = SECSuccess;
- break;
- case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
- rv = crmf_copy_pkiarchiveoptions(NULL,
- &newControl->value.archiveOptions,
- &srcControl->value.archiveOptions);
- break;
- default:
- rv = SECFailure;
- }
- if (rv != SECSuccess) {
- goto loser;
- }
- return newControl;
- loser:
- if (newControl != NULL) {
- CRMF_DestroyControl(newControl);
- }
- return NULL;
-}
-
-static SECItem*
-crmf_copy_control_value(CRMFControl *inControl)
-{
- return SECITEM_DupItem(&inControl->derValue);
-}
-
-SECItem*
-CRMF_ControlGetAuthenticatorControlValue(CRMFControl *inControl)
-{
- PORT_Assert (inControl!= NULL);
- if (inControl == NULL ||
- CRMF_ControlGetControlType(inControl) != crmfAuthenticatorControl) {
- return NULL;
- }
- return crmf_copy_control_value(inControl);
-}
-
-CRMFControlType
-CRMF_ControlGetControlType(CRMFControl *inControl)
-{
- CRMFControlType retType;
-
- PORT_Assert(inControl != NULL);
- switch (inControl->tag) {
- case SEC_OID_PKIX_REGCTRL_REGTOKEN:
- retType = crmfRegTokenControl;
- break;
- case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
- retType = crmfAuthenticatorControl;
- break;
- case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
- retType = crmfPKIPublicationInfoControl;
- break;
- case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
- retType = crmfPKIArchiveOptionsControl;
- break;
- case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
- retType = crmfOldCertIDControl;
- break;
- case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
- retType = crmfProtocolEncrKeyControl;
- break;
- default:
- retType = crmfNoControl;
- }
- return retType;
-}
-
-CRMFPKIArchiveOptions*
-CRMF_ControlGetPKIArchiveOptions(CRMFControl *inControl)
-{
- CRMFPKIArchiveOptions *newOpt = NULL;
- SECStatus rv;
-
- PORT_Assert(inControl != NULL);
- if (inControl == NULL ||
- CRMF_ControlGetControlType(inControl) != crmfPKIArchiveOptionsControl){
- goto loser;
- }
- newOpt = PORT_ZNew(CRMFPKIArchiveOptions);
- if (newOpt == NULL) {
- goto loser;
- }
- rv = crmf_copy_pkiarchiveoptions(NULL, newOpt,
- &inControl->value.archiveOptions);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- loser:
- if (newOpt != NULL) {
- CRMF_DestroyPKIArchiveOptions(newOpt);
- }
- return NULL;
-}
-
-SECItem*
-CRMF_ControlGetRegTokenControlValue(CRMFControl *inControl)
-{
- PORT_Assert(inControl != NULL);
- if (inControl == NULL ||
- CRMF_ControlGetControlType(inControl) != crmfRegTokenControl) {
- return NULL;
- }
- return crmf_copy_control_value(inControl);;
-}
-
-CRMFCertExtension*
-CRMF_CertRequestGetExtensionAtIndex(CRMFCertRequest *inCertReq,
- int index)
-{
- int numExtensions;
-
- PORT_Assert(inCertReq != NULL);
- numExtensions = CRMF_CertRequestGetNumberOfExtensions(inCertReq);
- if (index >= numExtensions || index < 0) {
- return NULL;
- }
- return
- crmf_copy_cert_extension(NULL,
- inCertReq->certTemplate.extensions[index]);
-}
-
diff --git a/security/nss/lib/cryptohi/Makefile b/security/nss/lib/cryptohi/Makefile
deleted file mode 100644
index 71ae761e4..000000000
--- a/security/nss/lib/cryptohi/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
--include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-
-export:: private_export
-
diff --git a/security/nss/lib/cryptohi/config.mk b/security/nss/lib/cryptohi/config.mk
deleted file mode 100644
index b8c03de79..000000000
--- a/security/nss/lib/cryptohi/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/cryptohi/cryptohi.h b/security/nss/lib/cryptohi/cryptohi.h
deleted file mode 100644
index 3fe7e5dc3..000000000
--- a/security/nss/lib/cryptohi/cryptohi.h
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * crypto.h - public data structures and prototypes for the crypto library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _CRYPTOHI_H_
-#define _CRYPTOHI_H_
-
-#include "blapit.h"
-
-#include "seccomon.h"
-#include "secoidt.h"
-#include "secdert.h"
-#include "cryptoht.h"
-#include "keyt.h"
-#include "certt.h"
-
-
-SEC_BEGIN_PROTOS
-
-
-/****************************************/
-/*
-** DER encode/decode (EC)DSA signatures
-*/
-
-/* ANSI X9.57 defines DSA signatures as DER encoded data. Our DSA1 code (and
- * most of the rest of the world) just generates 40 bytes of raw data. These
- * functions convert between formats.
- */
-extern SECStatus DSAU_EncodeDerSig(SECItem *dest, SECItem *src);
-extern SECItem *DSAU_DecodeDerSig(const SECItem *item);
-
-/*
- * Unlike DSA1, raw DSA2 and ECDSA signatures do not have a fixed length.
- * Rather they contain two integers r and s whose length depends
- * on the size of q or the EC key used for signing.
- *
- * We can reuse the DSAU_EncodeDerSig interface to DER encode
- * raw ECDSA signature keeping in mind that the length of r
- * is the same as that of s and exactly half of src->len.
- *
- * For decoding, we need to pass the length of the desired
- * raw signature (twice the key size) explicitly.
- */
-extern SECStatus DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src,
- unsigned int len);
-extern SECItem *DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len);
-
-/****************************************/
-/*
-** Signature creation operations
-*/
-
-/*
-** Create a new signature context used for signing a data stream.
-** "alg" the signature algorithm to use (e.g. SEC_OID_RSA_WITH_MD5)
-** "privKey" the private key to use
-*/
-extern SGNContext *SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *privKey);
-
-/*
-** Destroy a signature-context object
-** "key" the object
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void SGN_DestroyContext(SGNContext *cx, PRBool freeit);
-
-/*
-** Reset the signing context "cx" to its initial state, preparing it for
-** another stream of data.
-*/
-extern SECStatus SGN_Begin(SGNContext *cx);
-
-/*
-** Update the signing context with more data to sign.
-** "cx" the context
-** "input" the input data to sign
-** "inputLen" the length of the input data
-*/
-extern SECStatus SGN_Update(SGNContext *cx, const unsigned char *input,
- unsigned int inputLen);
-
-/*
-** Finish the signature process. Use either k0 or k1 to sign the data
-** stream that was input using SGN_Update. The resulting signature is
-** formatted using PKCS#1 and then encrypted using RSA private or public
-** encryption.
-** "cx" the context
-** "result" the final signature data (memory is allocated)
-*/
-extern SECStatus SGN_End(SGNContext *cx, SECItem *result);
-
-/*
-** Sign a single block of data using private key encryption and given
-** signature/hash algorithm.
-** "result" the final signature data (memory is allocated)
-** "buf" the input data to sign
-** "len" the amount of data to sign
-** "pk" the private key to encrypt with
-** "algid" the signature/hash algorithm to sign with
-** (must be compatible with the key type).
-*/
-extern SECStatus SEC_SignData(SECItem *result,
- const unsigned char *buf, int len,
- SECKEYPrivateKey *pk, SECOidTag algid);
-
-/*
-** Sign a pre-digested block of data using private key encryption, encoding
-** The given signature/hash algorithm.
-** "result" the final signature data (memory is allocated)
-** "digest" the digest to sign
-** "pk" the private key to encrypt with
-** "algtag" The algorithm tag to encode (need for RSA only)
-*/
-extern SECStatus SGN_Digest(SECKEYPrivateKey *privKey,
- SECOidTag algtag, SECItem *result, SECItem *digest);
-
-/*
-** DER sign a single block of data using private key encryption and the
-** MD5 hashing algorithm. This routine first computes a digital signature
-** using SEC_SignData, then wraps it with an CERTSignedData and then der
-** encodes the result.
-** "arena" is the memory arena to use to allocate data from
-** "result" the final der encoded data (memory is allocated)
-** "buf" the input data to sign
-** "len" the amount of data to sign
-** "pk" the private key to encrypt with
-*/
-extern SECStatus SEC_DerSignData(PLArenaPool *arena, SECItem *result,
- const unsigned char *buf, int len,
- SECKEYPrivateKey *pk, SECOidTag algid);
-
-/*
-** Destroy a signed-data object.
-** "sd" the object
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void SEC_DestroySignedData(CERTSignedData *sd, PRBool freeit);
-
-/*
-** Get the signature algorithm tag number for the given key type and hash
-** algorithm tag. Returns SEC_OID_UNKNOWN if key type and hash algorithm
-** do not match or are not supported.
-*/
-extern SECOidTag SEC_GetSignatureAlgorithmOidTag(KeyType keyType,
- SECOidTag hashAlgTag);
-
-/****************************************/
-/*
-** Signature verification operations
-*/
-
-/*
-** Create a signature verification context. This version is deprecated,
-** This function is deprecated. Use VFY_CreateContextDirect or
-** VFY_CreateContextWithAlgorithmID instead.
-** "key" the public key to verify with
-** "sig" the encrypted signature data if sig is NULL then
-** VFY_EndWithSignature must be called with the correct signature at
-** the end of the processing.
-** "sigAlg" specifies the signing algorithm to use (including the
-** hash algorthim). This must match the key type.
-** "wincx" void pointer to the window context
-*/
-extern VFYContext *VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig,
- SECOidTag sigAlg, void *wincx);
-/*
-** Create a signature verification context.
-** "key" the public key to verify with
-** "sig" the encrypted signature data if sig is NULL then
-** VFY_EndWithSignature must be called with the correct signature at
-** the end of the processing.
-** "pubkAlg" specifies the cryptographic signing algorithm to use (the
-** raw algorithm without any hash specified. This must match the key
-** type.
-** "hashAlg" specifies the hashing algorithm used. If the key is an
-** RSA key, and sig is not NULL, then hashAlg can be SEC_OID_UNKNOWN.
-** the hash is selected from data in the sig.
-** "hash" optional pointer to return the actual hash algorithm used.
-** in practice this should always match the passed in hashAlg (the
-** exception is the case where hashAlg is SEC_OID_UNKNOWN above).
-** If this value is NULL no, hash oid is returned.
-** "wincx" void pointer to the window context
-*/
-extern VFYContext *VFY_CreateContextDirect(const SECKEYPublicKey *key,
- const SECItem *sig,
- SECOidTag pubkAlg,
- SECOidTag hashAlg,
- SECOidTag *hash, void *wincx);
-/*
-** Create a signature verification context from a algorithm ID.
-** "key" the public key to verify with
-** "sig" the encrypted signature data if sig is NULL then
-** VFY_EndWithSignature must be called with the correct signature at
-** the end of the processing.
-** "algid" specifies the signing algorithm and parameters to use.
-** This must match the key type.
-** "hash" optional pointer to return the oid of the actual hash used in
-** the signature. If this value is NULL no, hash oid is returned.
-** "wincx" void pointer to the window context
-*/
-extern VFYContext *VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key,
- const SECItem *sig,
- const SECAlgorithmID *algid,
- SECOidTag *hash,
- void *wincx);
-
-/*
-** Destroy a verification-context object.
-** "cx" the context to destroy
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void VFY_DestroyContext(VFYContext *cx, PRBool freeit);
-
-extern SECStatus VFY_Begin(VFYContext *cx);
-
-/*
-** Update a verification context with more input data. The input data
-** is fed to a secure hash function (depending on what was in the
-** encrypted signature data).
-** "cx" the context
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus VFY_Update(VFYContext *cx, const unsigned char *input,
- unsigned int inputLen);
-
-/*
-** Finish the verification process. The return value is a status which
-** indicates success or failure. On success, the SECSuccess value is
-** returned. Otherwise, SECFailure is returned and the error code found
-** using PORT_GetError() indicates what failure occurred.
-** "cx" the context
-*/
-extern SECStatus VFY_End(VFYContext *cx);
-
-/*
-** Finish the verification process. The return value is a status which
-** indicates success or failure. On success, the SECSuccess value is
-** returned. Otherwise, SECFailure is returned and the error code found
-** using PORT_GetError() indicates what failure occurred. If signature is
-** supplied the verification uses this signature to verify, otherwise the
-** signature passed in VFY_CreateContext() is used.
-** VFY_EndWithSignature(cx,NULL); is identical to VFY_End(cx);.
-** "cx" the context
-** "sig" the encrypted signature data
-*/
-extern SECStatus VFY_EndWithSignature(VFYContext *cx, SECItem *sig);
-
-
-/*
-** Verify the signature on a block of data for which we already have
-** the digest. The signature data is an RSA private key encrypted
-** block of data formatted according to PKCS#1.
-** This function is deprecated. Use VFY_VerifyDigestDirect or
-** VFY_VerifyDigestWithAlgorithmID instead.
-** "dig" the digest
-** "key" the public key to check the signature with
-** "sig" the encrypted signature data
-** "sigAlg" specifies the signing algorithm to use. This must match
-** the key type.
-** "wincx" void pointer to the window context
-**/
-extern SECStatus VFY_VerifyDigest(SECItem *dig, SECKEYPublicKey *key,
- SECItem *sig, SECOidTag sigAlg, void *wincx);
-/*
-** Verify the signature on a block of data for which we already have
-** the digest. The signature data is an RSA private key encrypted
-** block of data formatted according to PKCS#1.
-** "dig" the digest
-** "key" the public key to check the signature with
-** "sig" the encrypted signature data
-** "pubkAlg" specifies the cryptographic signing algorithm to use (the
-** raw algorithm without any hash specified. This must match the key
-** type.
-** "hashAlg" specifies the hashing algorithm used.
-** "wincx" void pointer to the window context
-**/
-extern SECStatus VFY_VerifyDigestDirect(const SECItem *dig,
- const SECKEYPublicKey *key,
- const SECItem *sig, SECOidTag pubkAlg,
- SECOidTag hashAlg, void *wincx);
-/*
-** Verify the signature on a block of data for which we already have
-** the digest. The signature data is an RSA private key encrypted
-** block of data formatted according to PKCS#1.
-** "key" the public key to verify with
-** "sig" the encrypted signature data if sig is NULL then
-** VFY_EndWithSignature must be called with the correct signature at
-** the end of the processing.
-** "algid" specifies the signing algorithm and parameters to use.
-** This must match the key type.
-** "hash" oid of the actual hash used to create digest. If this value is
-** not set to SEC_OID_UNKNOWN, it must match the hash of the signature.
-** "wincx" void pointer to the window context
-*/
-extern SECStatus VFY_VerifyDigestWithAlgorithmID(const SECItem *dig,
- const SECKEYPublicKey *key, const SECItem *sig,
- const SECAlgorithmID *algid, SECOidTag hash,
- void *wincx);
-
-/*
-** Verify the signature on a block of data. The signature data is an RSA
-** private key encrypted block of data formatted according to PKCS#1.
-** This function is deprecated. Use VFY_VerifyDataDirect or
-** VFY_VerifyDataWithAlgorithmID instead.
-** "buf" the input data
-** "len" the length of the input data
-** "key" the public key to check the signature with
-** "sig" the encrypted signature data
-** "sigAlg" specifies the signing algorithm to use. This must match
-** the key type.
-** "wincx" void pointer to the window context
-*/
-extern SECStatus VFY_VerifyData(const unsigned char *buf, int len,
- const SECKEYPublicKey *key, const SECItem *sig,
- SECOidTag sigAlg, void *wincx);
-/*
-** Verify the signature on a block of data. The signature data is an RSA
-** private key encrypted block of data formatted according to PKCS#1.
-** "buf" the input data
-** "len" the length of the input data
-** "key" the public key to check the signature with
-** "sig" the encrypted signature data
-** "pubkAlg" specifies the cryptographic signing algorithm to use (the
-** raw algorithm without any hash specified. This must match the key
-** type.
-** "hashAlg" specifies the hashing algorithm used. If the key is an
-** RSA key, and sig is not NULL, then hashAlg can be SEC_OID_UNKNOWN.
-** the hash is selected from data in the sig.
-** "hash" optional pointer to return the actual hash algorithm used.
-** in practice this should always match the passed in hashAlg (the
-** exception is the case where hashAlg is SEC_OID_UNKNOWN above).
-** If this value is NULL no, hash oid is returned.
-** "wincx" void pointer to the window context
-*/
-extern SECStatus VFY_VerifyDataDirect(const unsigned char *buf, int len,
- const SECKEYPublicKey *key,
- const SECItem *sig,
- SECOidTag pubkAlg, SECOidTag hashAlg,
- SECOidTag *hash, void *wincx);
-
-/*
-** Verify the signature on a block of data. The signature data is an RSA
-** private key encrypted block of data formatted according to PKCS#1.
-** "buf" the input data
-** "len" the length of the input data
-** "key" the public key to check the signature with
-** "sig" the encrypted signature data
-** "algid" specifies the signing algorithm and parameters to use.
-** This must match the key type.
-** "hash" optional pointer to return the oid of the actual hash used in
-** the signature. If this value is NULL no, hash oid is returned.
-** "wincx" void pointer to the window context
-*/
-extern SECStatus VFY_VerifyDataWithAlgorithmID(const unsigned char *buf,
- int len, const SECKEYPublicKey *key,
- const SECItem *sig,
- const SECAlgorithmID *algid, SECOidTag *hash,
- void *wincx);
-
-
-SEC_END_PROTOS
-
-#endif /* _CRYPTOHI_H_ */
diff --git a/security/nss/lib/cryptohi/cryptoht.h b/security/nss/lib/cryptohi/cryptoht.h
deleted file mode 100644
index 3f871851d..000000000
--- a/security/nss/lib/cryptohi/cryptoht.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * cryptoht.h - public data structures for the crypto library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _CRYPTOHT_H_
-#define _CRYPTOHT_H_
-
-typedef struct SGNContextStr SGNContext;
-typedef struct VFYContextStr VFYContext;
-
-
-#endif /* _CRYPTOHT_H_ */
diff --git a/security/nss/lib/cryptohi/dsautil.c b/security/nss/lib/cryptohi/dsautil.c
deleted file mode 100644
index 5606379df..000000000
--- a/security/nss/lib/cryptohi/dsautil.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "cryptohi.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "prerr.h"
-
-#ifndef DSA1_SUBPRIME_LEN
-#define DSA1_SUBPRIME_LEN 20 /* bytes */
-#endif
-
-typedef struct {
- SECItem r;
- SECItem s;
-} DSA_ASN1Signature;
-
-const SEC_ASN1Template DSA_SignatureTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(DSA_ASN1Signature) },
- { SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature,r) },
- { SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature,s) },
- { 0, }
-};
-
-/* Input is variable length multi-byte integer, MSB first (big endian).
-** Most signficant bit of first byte is NOT treated as a sign bit.
-** May be one or more leading bytes of zeros.
-** Output is variable length multi-byte integer, MSB first (big endian).
-** Most significant bit of first byte will be zero (positive sign bit)
-** No more than one leading zero byte.
-** Caller supplies dest buffer, and assures that it is long enough,
-** e.g. at least one byte longer that src's buffer.
-*/
-void
-DSAU_ConvertUnsignedToSigned(SECItem *dest, SECItem *src)
-{
- unsigned char *pSrc = src->data;
- unsigned char *pDst = dest->data;
- unsigned int cntSrc = src->len;
-
- /* skip any leading zeros. */
- while (cntSrc && !(*pSrc)) {
- pSrc++;
- cntSrc--;
- }
- if (!cntSrc) {
- *pDst = 0;
- dest->len = 1;
- return;
- }
-
- if (*pSrc & 0x80)
- *pDst++ = 0;
-
- PORT_Memcpy(pDst, pSrc, cntSrc);
- dest->len = (pDst - dest->data) + cntSrc;
-}
-
-/*
-** src is a buffer holding a signed variable length integer.
-** dest is a buffer which will be filled with an unsigned integer,
-** MSB first (big endian) with leading zeros, so that the last byte
-** of src will be the LSB of the integer. The result will be exactly
-** the length specified by the caller in dest->len.
-** src can be shorter than dest. src can be longer than dst, but only
-** if the extra leading bytes are zeros.
-*/
-SECStatus
-DSAU_ConvertSignedToFixedUnsigned(SECItem *dest, SECItem *src)
-{
- unsigned char *pSrc = src->data;
- unsigned char *pDst = dest->data;
- unsigned int cntSrc = src->len;
- unsigned int cntDst = dest->len;
- int zCount = cntDst - cntSrc;
-
- if (zCount > 0) {
- PORT_Memset(pDst, 0, zCount);
- PORT_Memcpy(pDst + zCount, pSrc, cntSrc);
- return SECSuccess;
- }
- if (zCount <= 0) {
- /* Source is longer than destination. Check for leading zeros. */
- while (zCount++ < 0) {
- if (*pSrc++ != 0)
- goto loser;
- }
- }
- PORT_Memcpy(pDst, pSrc, cntDst);
- return SECSuccess;
-
-loser:
- PORT_SetError( PR_INVALID_ARGUMENT_ERROR );
- return SECFailure;
-}
-
-/* src is a "raw" ECDSA or DSA signature, the first half contains r
- * and the second half contains s. dest is the DER encoded signature.
-*/
-static SECStatus
-common_EncodeDerSig(SECItem *dest, SECItem *src)
-{
- SECItem * item;
- SECItem srcItem;
- DSA_ASN1Signature sig;
- unsigned char *signedR;
- unsigned char *signedS;
- unsigned int len;
-
- /* Allocate memory with room for an extra byte that
- * may be required if the top bit in the first byte
- * is already set.
- */
- len = src->len/2;
- signedR = (unsigned char *) PORT_Alloc(len + 1);
- if (!signedR) return SECFailure;
- signedS = (unsigned char *) PORT_ZAlloc(len + 1);
- if (!signedS) {
- if (signedR) PORT_Free(signedR);
- return SECFailure;
- }
-
- PORT_Memset(&sig, 0, sizeof(sig));
-
- /* Must convert r and s from "unsigned" integers to "signed" integers.
- ** If the high order bit of the first byte (MSB) is 1, then must
- ** prepend with leading zero.
- ** Must remove all but one leading zero byte from numbers.
- */
- sig.r.type = siUnsignedInteger;
- sig.r.data = signedR;
- sig.r.len = sizeof signedR;
- sig.s.type = siUnsignedInteger;
- sig.s.data = signedS;
- sig.s.len = sizeof signedR;
-
- srcItem.data = src->data;
- srcItem.len = len;
-
- DSAU_ConvertUnsignedToSigned(&sig.r, &srcItem);
- srcItem.data += len;
- DSAU_ConvertUnsignedToSigned(&sig.s, &srcItem);
-
- item = SEC_ASN1EncodeItem(NULL, dest, &sig, DSA_SignatureTemplate);
- if (signedR) PORT_Free(signedR);
- if (signedS) PORT_Free(signedS);
- if (item == NULL)
- return SECFailure;
-
- /* XXX leak item? */
- return SECSuccess;
-}
-
-/* src is a DER-encoded ECDSA or DSA signature.
-** Returns a newly-allocated SECItem structure, pointing at a newly allocated
-** buffer containing the "raw" signature, which is len bytes of r,
-** followed by len bytes of s. For DSA, len is the length of q.
-** For ECDSA, len depends on the key size used to create the signature.
-*/
-static SECItem *
-common_DecodeDerSig(const SECItem *item, unsigned int len)
-{
- SECItem * result = NULL;
- SECStatus status;
- DSA_ASN1Signature sig;
- SECItem dst;
-
- PORT_Memset(&sig, 0, sizeof(sig));
-
- result = PORT_ZNew(SECItem);
- if (result == NULL)
- goto loser;
-
- result->len = 2 * len;
- result->data = (unsigned char*)PORT_Alloc(2 * len);
- if (result->data == NULL)
- goto loser;
-
- sig.r.type = siUnsignedInteger;
- sig.s.type = siUnsignedInteger;
- status = SEC_ASN1DecodeItem(NULL, &sig, DSA_SignatureTemplate, item);
- if (status != SECSuccess)
- goto loser;
-
- /* Convert sig.r and sig.s from variable length signed integers to
- ** fixed length unsigned integers.
- */
- dst.data = result->data;
- dst.len = len;
- status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.r);
- if (status != SECSuccess)
- goto loser;
-
- dst.data += len;
- status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.s);
- if (status != SECSuccess)
- goto loser;
-
-done:
- if (sig.r.data != NULL)
- PORT_Free(sig.r.data);
- if (sig.s.data != NULL)
- PORT_Free(sig.s.data);
-
- return result;
-
-loser:
- if (result != NULL) {
- SECITEM_FreeItem(result, PR_TRUE);
- result = NULL;
- }
- goto done;
-}
-
-/* src is a "raw" DSA1 signature, 20 bytes of r followed by 20 bytes of s.
-** dest is the signature DER encoded. ?
-*/
-SECStatus
-DSAU_EncodeDerSig(SECItem *dest, SECItem *src)
-{
- PORT_Assert(src->len == 2 * DSA1_SUBPRIME_LEN);
- if (src->len != 2 * DSA1_SUBPRIME_LEN) {
- PORT_SetError( PR_INVALID_ARGUMENT_ERROR );
- return SECFailure;
- }
-
- return common_EncodeDerSig(dest, src);
-}
-
-/* src is a "raw" DSA signature of length len (len/2 bytes of r followed
-** by len/2 bytes of s). dest is the signature DER encoded.
-*/
-SECStatus
-DSAU_EncodeDerSigWithLen(SECItem *dest, SECItem *src, unsigned int len)
-{
-
- PORT_Assert((src->len == len) && (len % 2 == 0));
- if ((src->len != len) || (src->len % 2 != 0)) {
- PORT_SetError( PR_INVALID_ARGUMENT_ERROR );
- return SECFailure;
- }
-
- return common_EncodeDerSig(dest, src);
-}
-
-/* src is a DER-encoded DSA signature.
-** Returns a newly-allocated SECItem structure, pointing at a newly allocated
-** buffer containing the "raw" DSA1 signature, which is 20 bytes of r,
-** followed by 20 bytes of s.
-*/
-SECItem *
-DSAU_DecodeDerSig(const SECItem *item)
-{
- return common_DecodeDerSig(item, DSA1_SUBPRIME_LEN);
-}
-
-/* src is a DER-encoded ECDSA signature.
-** Returns a newly-allocated SECItem structure, pointing at a newly allocated
-** buffer containing the "raw" ECDSA signature of length len containing
-** r followed by s (both padded to take up exactly len/2 bytes).
-*/
-SECItem *
-DSAU_DecodeDerSigToLen(const SECItem *item, unsigned int len)
-{
- return common_DecodeDerSig(item, len/2);
-}
diff --git a/security/nss/lib/cryptohi/key.h b/security/nss/lib/cryptohi/key.h
deleted file mode 100644
index db94e25c7..000000000
--- a/security/nss/lib/cryptohi/key.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* This header is deprecated. Please include keyhi.h instead. */
-
-#ifndef _KEY_H_
-#define _KEY_H_
-
-#include "keyhi.h"
-
-#endif /* _KEY_H_ */
diff --git a/security/nss/lib/cryptohi/keyhi.h b/security/nss/lib/cryptohi/keyhi.h
deleted file mode 100644
index 6741209d2..000000000
--- a/security/nss/lib/cryptohi/keyhi.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _KEYHI_H_
-#define _KEYHI_H_
-
-#include "plarena.h"
-
-#include "seccomon.h"
-#include "secoidt.h"
-#include "secdert.h"
-#include "keythi.h"
-#include "certt.h"
-/*#include "secpkcs5.h" */
-
-SEC_BEGIN_PROTOS
-
-
-/*
-** Destroy a subject-public-key-info object.
-*/
-extern void SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki);
-
-/*
-** Copy subject-public-key-info "src" to "dst". "dst" is filled in
-** appropriately (memory is allocated for each of the sub objects).
-*/
-extern SECStatus SECKEY_CopySubjectPublicKeyInfo(PLArenaPool *arena,
- CERTSubjectPublicKeyInfo *dst,
- CERTSubjectPublicKeyInfo *src);
-
-/*
-** Update the PQG parameters for a cert's public key.
-** Only done for DSA certs
-*/
-extern SECStatus
-SECKEY_UpdateCertPQG(CERTCertificate * subjectCert);
-
-
-/*
-** Return the strength of the public key in bytes
-*/
-extern unsigned SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk);
-
-/*
-** Return the strength of the public key in bits
-*/
-extern unsigned SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk);
-
-/*
-** Return the length of the signature in bytes
-*/
-extern unsigned SECKEY_SignatureLen(const SECKEYPublicKey *pubk);
-
-/*
-** Make a copy of the private key "privKey"
-*/
-extern SECKEYPrivateKey *SECKEY_CopyPrivateKey(const SECKEYPrivateKey *privKey);
-
-/*
-** Make a copy of the public key "pubKey"
-*/
-extern SECKEYPublicKey *SECKEY_CopyPublicKey(const SECKEYPublicKey *pubKey);
-
-/*
-** Convert a private key "privateKey" into a public key
-*/
-extern SECKEYPublicKey *SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privateKey);
-
-/*
- * create a new RSA key pair. The private Key is returned...
- */
-SECKEYPrivateKey *SECKEY_CreateRSAPrivateKey(int keySizeInBits,
- SECKEYPublicKey **pubk, void *cx);
-
-/*
- * create a new DH key pair. The private Key is returned...
- */
-SECKEYPrivateKey *SECKEY_CreateDHPrivateKey(SECKEYDHParams *param,
- SECKEYPublicKey **pubk, void *cx);
-
-/*
- * create a new EC key pair. The private Key is returned...
- */
-SECKEYPrivateKey *SECKEY_CreateECPrivateKey(SECKEYECParams *param,
- SECKEYPublicKey **pubk, void *cx);
-
-/*
-** Create a subject-public-key-info based on a public key.
-*/
-extern CERTSubjectPublicKeyInfo *
-SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *k);
-
-/*
-** Decode a DER encoded public key into an SECKEYPublicKey structure.
-*/
-extern SECKEYPublicKey *SECKEY_DecodeDERPublicKey(SECItem *pubkder);
-
-/*
-** Convert a base64 ascii encoded DER public key to our internal format.
-*/
-extern SECKEYPublicKey *SECKEY_ConvertAndDecodePublicKey(char *pubkstr);
-
-/*
-** Convert a base64 ascii encoded DER public key and challenge to spki,
-** and verify the signature and challenge data are correct
-*/
-extern CERTSubjectPublicKeyInfo *
-SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
- void *cx);
-
-/*
-** Encode a CERTSubjectPublicKeyInfo structure. into a
-** DER encoded subject public key info.
-*/
-SECItem *
-SECKEY_EncodeDERSubjectPublicKeyInfo(SECKEYPublicKey *pubk);
-
-/*
-** Decode a DER encoded subject public key info into a
-** CERTSubjectPublicKeyInfo structure.
-*/
-extern CERTSubjectPublicKeyInfo *
-SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider);
-
-/*
-** Convert a base64 ascii encoded DER subject public key info to our
-** internal format.
-*/
-extern CERTSubjectPublicKeyInfo *
-SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(char *spkistr);
-
-/*
- * extract the public key from a subject Public Key info structure.
- * (used by JSS).
- */
-extern SECKEYPublicKey *
-SECKEY_ExtractPublicKey(CERTSubjectPublicKeyInfo *);
-
-/*
-** Destroy a private key object.
-** "key" the object
-*/
-extern void SECKEY_DestroyPrivateKey(SECKEYPrivateKey *key);
-
-
-/*
-** Destroy a public key object.
-** "key" the object
-*/
-extern void SECKEY_DestroyPublicKey(SECKEYPublicKey *key);
-
-/* Destroy and zero out a private key info structure. for now this
- * function zero's out memory allocated in an arena for the key
- * since PORT_FreeArena does not currently do this.
- *
- * NOTE -- If a private key info is allocated in an arena, one should
- * not call this function with freeit = PR_FALSE. The function should
- * destroy the arena.
- */
-extern void
-SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk, PRBool freeit);
-
-/* Destroy and zero out an encrypted private key info.
- *
- * NOTE -- If a encrypted private key info is allocated in an arena, one should
- * not call this function with freeit = PR_FALSE. The function should
- * destroy the arena.
- */
-extern void
-SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki,
- PRBool freeit);
-
-/* Copy private key info structure.
- * poolp is the arena into which the contents of from is to be copied.
- * NULL is a valid entry.
- * to is the destination private key info
- * from is the source private key info
- * if either from or to is NULL or an error occurs, SECFailure is
- * returned. otherwise, SECSuccess is returned.
- */
-extern SECStatus
-SECKEY_CopyPrivateKeyInfo(PLArenaPool *poolp,
- SECKEYPrivateKeyInfo *to,
- SECKEYPrivateKeyInfo *from);
-
-extern SECStatus
-SECKEY_CacheStaticFlags(SECKEYPrivateKey* key);
-
-/* Copy encrypted private key info structure.
- * poolp is the arena into which the contents of from is to be copied.
- * NULL is a valid entry.
- * to is the destination encrypted private key info
- * from is the source encrypted private key info
- * if either from or to is NULL or an error occurs, SECFailure is
- * returned. otherwise, SECSuccess is returned.
- */
-extern SECStatus
-SECKEY_CopyEncryptedPrivateKeyInfo(PLArenaPool *poolp,
- SECKEYEncryptedPrivateKeyInfo *to,
- SECKEYEncryptedPrivateKeyInfo *from);
-/*
- * Accessor functions for key type of public and private keys.
- */
-KeyType SECKEY_GetPrivateKeyType(SECKEYPrivateKey *privKey);
-KeyType SECKEY_GetPublicKeyType(SECKEYPublicKey *pubKey);
-
-/*
- * Creates a PublicKey from its DER encoding.
- * Currently only supports RSA and DSA keys.
- */
-SECKEYPublicKey*
-SECKEY_ImportDERPublicKey(SECItem *derKey, CK_KEY_TYPE type);
-
-SECKEYPrivateKeyList*
-SECKEY_NewPrivateKeyList(void);
-
-void
-SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys);
-
-void
-SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node);
-
-SECStatus
-SECKEY_AddPrivateKeyToListTail( SECKEYPrivateKeyList *list,
- SECKEYPrivateKey *key);
-
-#define PRIVKEY_LIST_HEAD(l) ((SECKEYPrivateKeyListNode*)PR_LIST_HEAD(&l->list))
-#define PRIVKEY_LIST_NEXT(n) ((SECKEYPrivateKeyListNode *)n->links.next)
-#define PRIVKEY_LIST_END(n,l) (((void *)n) == ((void *)&l->list))
-
-SECKEYPublicKeyList*
-SECKEY_NewPublicKeyList(void);
-
-void
-SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys);
-
-void
-SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node);
-
-SECStatus
-SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list,
- SECKEYPublicKey *key);
-
-#define PUBKEY_LIST_HEAD(l) ((SECKEYPublicKeyListNode*)PR_LIST_HEAD(&l->list))
-#define PUBKEY_LIST_NEXT(n) ((SECKEYPublicKeyListNode *)n->links.next)
-#define PUBKEY_LIST_END(n,l) (((void *)n) == ((void *)&l->list))
-
-/*
- * Length in bits of the EC's field size. This is also the length of
- * the x and y coordinates of EC points, such as EC public keys and
- * base points.
- *
- * Return 0 on failure (unknown EC domain parameters).
- */
-extern int SECKEY_ECParamsToKeySize(const SECItem *params);
-
-/*
- * Length in bits of the EC base point order, usually denoted n. This
- * is also the length of EC private keys and ECDSA signature components
- * r and s.
- *
- * Return 0 on failure (unknown EC domain parameters).
- */
-extern int SECKEY_ECParamsToBasePointOrderLen(const SECItem *params);
-
-SEC_END_PROTOS
-
-#endif /* _KEYHI_H_ */
diff --git a/security/nss/lib/cryptohi/keyi.h b/security/nss/lib/cryptohi/keyi.h
deleted file mode 100644
index 8e0634b93..000000000
--- a/security/nss/lib/cryptohi/keyi.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _KEYI_H_
-#define _KEYI_H_
-
-
-SEC_BEGIN_PROTOS
-/* NSS private functions */
-/* map an oid to a keytype... actually this function and it's converse
- * are good candidates for public functions.. */
-KeyType seckey_GetKeyType(SECOidTag pubKeyOid);
-
-/* extract the 'encryption' (could be signing) and hash oids from and
- * algorithm, key and parameters (parameters is the parameters field
- * of a algorithm ID structure (SECAlgorithmID)*/
-SECStatus sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
- const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg);
-
-SEC_END_PROTOS
-
-#endif /* _KEYHI_H_ */
diff --git a/security/nss/lib/cryptohi/keyt.h b/security/nss/lib/cryptohi/keyt.h
deleted file mode 100644
index 3bdcbba37..000000000
--- a/security/nss/lib/cryptohi/keyt.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _KEYT_H_
-#define _KEYT_H_
-
-#include "keythi.h"
-
-#endif /* _KEYT_H_ */
diff --git a/security/nss/lib/cryptohi/keythi.h b/security/nss/lib/cryptohi/keythi.h
deleted file mode 100644
index 9b9a27855..000000000
--- a/security/nss/lib/cryptohi/keythi.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _KEYTHI_H_
-#define _KEYTHI_H_ 1
-
-#include "plarena.h"
-#include "pkcs11t.h"
-#include "secmodt.h"
-#include "prclist.h"
-
-/*
-** RFC 4055 Section 1.2 specifies three different RSA key types.
-**
-** rsaKey maps to keys with SEC_OID_PKCS1_RSA_ENCRYPTION and can be used for
-** both encryption and signatures with old (PKCS #1 v1.5) and new (PKCS #1
-** v2.1) padding schemes.
-**
-** rsaPssKey maps to keys with SEC_OID_PKCS1_RSA_PSS_SIGNATURE and may only
-** be used for signatures with PSS padding (PKCS #1 v2.1).
-**
-** rsaOaepKey maps to keys with SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION and may only
-** be used for encryption with OAEP padding (PKCS #1 v2.1).
-*/
-
-typedef enum {
- nullKey = 0,
- rsaKey = 1,
- dsaKey = 2,
- fortezzaKey = 3, /* deprecated */
- dhKey = 4,
- keaKey = 5, /* deprecated */
- ecKey = 6,
- rsaPssKey = 7,
- rsaOaepKey = 8
-} KeyType;
-
-/*
-** Template Definitions
-**/
-
-SEC_BEGIN_PROTOS
-extern const SEC_ASN1Template SECKEY_RSAPublicKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_RSAPSSParamsTemplate[];
-extern const SEC_ASN1Template SECKEY_DSAPublicKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_DHPublicKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_DHParamKeyTemplate[];
-extern const SEC_ASN1Template SECKEY_PQGParamsTemplate[];
-extern const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[];
-
-/* Windows DLL accessor functions */
-SEC_ASN1_CHOOSER_DECLARE(SECKEY_DSAPublicKeyTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SECKEY_RSAPublicKeyTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SECKEY_RSAPSSParamsTemplate)
-SEC_END_PROTOS
-
-
-/*
-** RSA Public Key structures
-** member names from PKCS#1, section 7.1
-*/
-
-struct SECKEYRSAPublicKeyStr {
- PLArenaPool * arena;
- SECItem modulus;
- SECItem publicExponent;
-};
-typedef struct SECKEYRSAPublicKeyStr SECKEYRSAPublicKey;
-
-/*
-** RSA-PSS parameters
-*/
-struct SECKEYRSAPSSParamsStr {
- SECAlgorithmID *hashAlg;
- SECAlgorithmID *maskAlg;
- SECItem saltLength;
- SECItem trailerField;
-};
-typedef struct SECKEYRSAPSSParamsStr SECKEYRSAPSSParams;
-
-/*
-** DSA Public Key and related structures
-*/
-
-struct SECKEYPQGParamsStr {
- PLArenaPool *arena;
- SECItem prime; /* p */
- SECItem subPrime; /* q */
- SECItem base; /* g */
- /* XXX chrisk: this needs to be expanded to hold j and validationParms (RFC2459 7.3.2) */
-};
-typedef struct SECKEYPQGParamsStr SECKEYPQGParams;
-
-struct SECKEYDSAPublicKeyStr {
- SECKEYPQGParams params;
- SECItem publicValue;
-};
-typedef struct SECKEYDSAPublicKeyStr SECKEYDSAPublicKey;
-
-
-/*
-** Diffie-Hellman Public Key structure
-** Structure member names suggested by PKCS#3.
-*/
-struct SECKEYDHParamsStr {
- PLArenaPool * arena;
- SECItem prime; /* p */
- SECItem base; /* g */
-};
-typedef struct SECKEYDHParamsStr SECKEYDHParams;
-
-struct SECKEYDHPublicKeyStr {
- PLArenaPool * arena;
- SECItem prime;
- SECItem base;
- SECItem publicValue;
-};
-typedef struct SECKEYDHPublicKeyStr SECKEYDHPublicKey;
-
-/*
-** Elliptic curve Public Key structure
-** The PKCS#11 layer needs DER encoding of ANSI X9.62
-** parameters value
-*/
-typedef SECItem SECKEYECParams;
-
-struct SECKEYECPublicKeyStr {
- SECKEYECParams DEREncodedParams;
- int size; /* size in bits */
- SECItem publicValue; /* encoded point */
- /* XXX Even though the PKCS#11 interface takes encoded parameters,
- * we may still wish to decode them above PKCS#11 for things like
- * printing key information. For named curves, which is what
- * we initially support, we ought to have the curve name at the
- * very least.
- */
-};
-typedef struct SECKEYECPublicKeyStr SECKEYECPublicKey;
-
-/*
-** FORTEZZA Public Key structures
-*/
-struct SECKEYFortezzaPublicKeyStr {
- int KEAversion;
- int DSSversion;
- unsigned char KMID[8];
- SECItem clearance;
- SECItem KEApriviledge;
- SECItem DSSpriviledge;
- SECItem KEAKey;
- SECItem DSSKey;
- SECKEYPQGParams params;
- SECKEYPQGParams keaParams;
-};
-typedef struct SECKEYFortezzaPublicKeyStr SECKEYFortezzaPublicKey;
-#define KEAprivilege KEApriviledge /* corrected spelling */
-#define DSSprivilege DSSpriviledge /* corrected spelling */
-
-struct SECKEYDiffPQGParamsStr {
- SECKEYPQGParams DiffKEAParams;
- SECKEYPQGParams DiffDSAParams;
-};
-typedef struct SECKEYDiffPQGParamsStr SECKEYDiffPQGParams;
-
-struct SECKEYPQGDualParamsStr {
- SECKEYPQGParams CommParams;
- SECKEYDiffPQGParams DiffParams;
-};
-typedef struct SECKEYPQGDualParamsStr SECKEYPQGDualParams;
-
-struct SECKEYKEAParamsStr {
- PLArenaPool *arena;
- SECItem hash;
-};
-typedef struct SECKEYKEAParamsStr SECKEYKEAParams;
-
-struct SECKEYKEAPublicKeyStr {
- SECKEYKEAParams params;
- SECItem publicValue;
-};
-typedef struct SECKEYKEAPublicKeyStr SECKEYKEAPublicKey;
-
-/*
-** A Generic public key object.
-*/
-struct SECKEYPublicKeyStr {
- PLArenaPool *arena;
- KeyType keyType;
- PK11SlotInfo *pkcs11Slot;
- CK_OBJECT_HANDLE pkcs11ID;
- union {
- SECKEYRSAPublicKey rsa;
- SECKEYDSAPublicKey dsa;
- SECKEYDHPublicKey dh;
- SECKEYKEAPublicKey kea;
- SECKEYFortezzaPublicKey fortezza;
- SECKEYECPublicKey ec;
- } u;
-};
-typedef struct SECKEYPublicKeyStr SECKEYPublicKey;
-
-/* bit flag definitions for staticflags */
-#define SECKEY_Attributes_Cached 0x1 /* bit 0 states
- whether attributes are cached */
-#define SECKEY_CKA_PRIVATE (1U << 1) /* bit 1 is the value of CKA_PRIVATE */
-#define SECKEY_CKA_ALWAYS_AUTHENTICATE (1U << 2)
-
-#define SECKEY_ATTRIBUTES_CACHED(key) \
- (0 != (key->staticflags & SECKEY_Attributes_Cached))
-
-#define SECKEY_ATTRIBUTE_VALUE(key,attribute) \
- (0 != (key->staticflags & SECKEY_##attribute))
-
-#define SECKEY_HAS_ATTRIBUTE_SET(key,attribute) \
- (0 != (key->staticflags & SECKEY_Attributes_Cached)) ? \
- (0 != (key->staticflags & SECKEY_##attribute)) : \
- PK11_HasAttributeSet(key->pkcs11Slot,key->pkcs11ID,attribute, PR_FALSE)
-
-#define SECKEY_HAS_ATTRIBUTE_SET_LOCK(key,attribute, haslock) \
- (0 != (key->staticflags & SECKEY_Attributes_Cached)) ? \
- (0 != (key->staticflags & SECKEY_##attribute)) : \
- PK11_HasAttributeSet(key->pkcs11Slot,key->pkcs11ID,attribute, haslock)
-
-/*
-** A generic key structure
-*/
-struct SECKEYPrivateKeyStr {
- PLArenaPool *arena;
- KeyType keyType;
- PK11SlotInfo *pkcs11Slot; /* pkcs11 slot this key lives in */
- CK_OBJECT_HANDLE pkcs11ID; /* ID of pkcs11 object */
- PRBool pkcs11IsTemp; /* temp pkcs11 object, delete it when done */
- void *wincx; /* context for errors and pw prompts */
- PRUint32 staticflags; /* bit flag of cached PKCS#11 attributes */
-};
-typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey;
-
-typedef struct {
- PRCList links;
- SECKEYPrivateKey *key;
-} SECKEYPrivateKeyListNode;
-
-typedef struct {
- PRCList list;
- PLArenaPool *arena;
-} SECKEYPrivateKeyList;
-
-typedef struct {
- PRCList links;
- SECKEYPublicKey *key;
-} SECKEYPublicKeyListNode;
-
-typedef struct {
- PRCList list;
- PLArenaPool *arena;
-} SECKEYPublicKeyList;
-#endif /* _KEYTHI_H_ */
-
diff --git a/security/nss/lib/cryptohi/manifest.mn b/security/nss/lib/cryptohi/manifest.mn
deleted file mode 100644
index a3955924a..000000000
--- a/security/nss/lib/cryptohi/manifest.mn
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-
-MODULE = nss
-
-LIBRARY_NAME = cryptohi
-
-EXPORTS = \
- cryptohi.h \
- cryptoht.h \
- key.h \
- keyhi.h \
- keyt.h \
- keythi.h \
- sechash.h \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- $(NULL)
-
-CSRCS = \
- sechash.c \
- seckey.c \
- secsign.c \
- secvfy.c \
- dsautil.c \
- $(NULL)
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/cryptohi/sechash.c b/security/nss/lib/cryptohi/sechash.c
deleted file mode 100644
index b9476c478..000000000
--- a/security/nss/lib/cryptohi/sechash.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "sechash.h"
-#include "secoidt.h"
-#include "secerr.h"
-#include "blapi.h"
-#include "pk11func.h" /* for the PK11_ calls below. */
-
-static void *
-null_hash_new_context(void)
-{
- return NULL;
-}
-
-static void *
-null_hash_clone_context(void *v)
-{
- PORT_Assert(v == NULL);
- return NULL;
-}
-
-static void
-null_hash_begin(void *v)
-{
-}
-
-static void
-null_hash_update(void *v, const unsigned char *input, unsigned int length)
-{
-}
-
-static void
-null_hash_end(void *v, unsigned char *output, unsigned int *outLen,
- unsigned int maxOut)
-{
- *outLen = 0;
-}
-
-static void
-null_hash_destroy_context(void *v, PRBool b)
-{
- PORT_Assert(v == NULL);
-}
-
-
-static void *
-md2_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_MD2);
-}
-
-static void *
-md5_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_MD5);
-}
-
-static void *
-sha1_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA1);
-}
-
-static void *
-sha224_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA224);
-}
-
-static void *
-sha256_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA256);
-}
-
-static void *
-sha384_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA384);
-}
-
-static void *
-sha512_NewContext(void) {
- return (void *) PK11_CreateDigestContext(SEC_OID_SHA512);
-}
-
-const SECHashObject SECHashObjects[] = {
- { 0,
- (void * (*)(void)) null_hash_new_context,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) null_hash_destroy_context,
- (void (*)(void *)) null_hash_begin,
- (void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) null_hash_end,
- 0,
- HASH_AlgNULL
- },
- { MD2_LENGTH,
- (void * (*)(void)) md2_NewContext,
- (void * (*)(void *)) PK11_CloneContext,
- (void (*)(void *, PRBool)) PK11_DestroyContext,
- (void (*)(void *)) PK11_DigestBegin,
- (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal,
- MD2_BLOCK_LENGTH,
- HASH_AlgMD2
- },
- { MD5_LENGTH,
- (void * (*)(void)) md5_NewContext,
- (void * (*)(void *)) PK11_CloneContext,
- (void (*)(void *, PRBool)) PK11_DestroyContext,
- (void (*)(void *)) PK11_DigestBegin,
- (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal,
- MD5_BLOCK_LENGTH,
- HASH_AlgMD5
- },
- { SHA1_LENGTH,
- (void * (*)(void)) sha1_NewContext,
- (void * (*)(void *)) PK11_CloneContext,
- (void (*)(void *, PRBool)) PK11_DestroyContext,
- (void (*)(void *)) PK11_DigestBegin,
- (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal,
- SHA1_BLOCK_LENGTH,
- HASH_AlgSHA1
- },
- { SHA256_LENGTH,
- (void * (*)(void)) sha256_NewContext,
- (void * (*)(void *)) PK11_CloneContext,
- (void (*)(void *, PRBool)) PK11_DestroyContext,
- (void (*)(void *)) PK11_DigestBegin,
- (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal,
- SHA256_BLOCK_LENGTH,
- HASH_AlgSHA256
- },
- { SHA384_LENGTH,
- (void * (*)(void)) sha384_NewContext,
- (void * (*)(void *)) PK11_CloneContext,
- (void (*)(void *, PRBool)) PK11_DestroyContext,
- (void (*)(void *)) PK11_DigestBegin,
- (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal,
- SHA384_BLOCK_LENGTH,
- HASH_AlgSHA384
- },
- { SHA512_LENGTH,
- (void * (*)(void)) sha512_NewContext,
- (void * (*)(void *)) PK11_CloneContext,
- (void (*)(void *, PRBool)) PK11_DestroyContext,
- (void (*)(void *)) PK11_DigestBegin,
- (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal,
- SHA512_BLOCK_LENGTH,
- HASH_AlgSHA512
- },
- { SHA224_LENGTH,
- (void * (*)(void)) sha224_NewContext,
- (void * (*)(void *)) PK11_CloneContext,
- (void (*)(void *, PRBool)) PK11_DestroyContext,
- (void (*)(void *)) PK11_DigestBegin,
- (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- PK11_DigestFinal,
- SHA224_BLOCK_LENGTH,
- HASH_AlgSHA224
- },
-};
-
-const SECHashObject *
-HASH_GetHashObject(HASH_HashType type)
-{
- return &SECHashObjects[type];
-}
-
-HASH_HashType
-HASH_GetHashTypeByOidTag(SECOidTag hashOid)
-{
- HASH_HashType ht = HASH_AlgNULL;
-
- switch(hashOid) {
- case SEC_OID_MD2: ht = HASH_AlgMD2; break;
- case SEC_OID_MD5: ht = HASH_AlgMD5; break;
- case SEC_OID_SHA1: ht = HASH_AlgSHA1; break;
- case SEC_OID_SHA224: ht = HASH_AlgSHA224; break;
- case SEC_OID_SHA256: ht = HASH_AlgSHA256; break;
- case SEC_OID_SHA384: ht = HASH_AlgSHA384; break;
- case SEC_OID_SHA512: ht = HASH_AlgSHA512; break;
- default: ht = HASH_AlgNULL;
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- break;
- }
- return ht;
-}
-
-SECOidTag
-HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid)
-{
- SECOidTag hashOid = SEC_OID_UNKNOWN;
-
- switch(hmacOid) {
- /* no oid exists for HMAC_MD2 */
- /* NSS does not define a oid for HMAC_MD4 */
- case SEC_OID_HMAC_SHA1: hashOid = SEC_OID_SHA1; break;
- case SEC_OID_HMAC_SHA224: hashOid = SEC_OID_SHA224; break;
- case SEC_OID_HMAC_SHA256: hashOid = SEC_OID_SHA256; break;
- case SEC_OID_HMAC_SHA384: hashOid = SEC_OID_SHA384; break;
- case SEC_OID_HMAC_SHA512: hashOid = SEC_OID_SHA512; break;
- default: hashOid = SEC_OID_UNKNOWN;
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- break;
- }
- return hashOid;
-}
-
-SECOidTag
-HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid)
-{
- SECOidTag hmacOid = SEC_OID_UNKNOWN;
-
- switch(hashOid) {
- /* no oid exists for HMAC_MD2 */
- /* NSS does not define a oid for HMAC_MD4 */
- case SEC_OID_SHA1: hmacOid = SEC_OID_HMAC_SHA1; break;
- case SEC_OID_SHA224: hmacOid = SEC_OID_HMAC_SHA224; break;
- case SEC_OID_SHA256: hmacOid = SEC_OID_HMAC_SHA256; break;
- case SEC_OID_SHA384: hmacOid = SEC_OID_HMAC_SHA384; break;
- case SEC_OID_SHA512: hmacOid = SEC_OID_HMAC_SHA512; break;
- default: hmacOid = SEC_OID_UNKNOWN;
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- break;
- }
- return hmacOid;
-}
-
-const SECHashObject *
-HASH_GetHashObjectByOidTag(SECOidTag hashOid)
-{
- HASH_HashType ht = HASH_GetHashTypeByOidTag(hashOid);
-
- return (ht == HASH_AlgNULL) ? NULL : &SECHashObjects[ht];
-}
-
-/* returns zero for unknown hash OID */
-unsigned int
-HASH_ResultLenByOidTag(SECOidTag hashOid)
-{
- const SECHashObject * hashObject = HASH_GetHashObjectByOidTag(hashOid);
- unsigned int resultLen = 0;
-
- if (hashObject)
- resultLen = hashObject->length;
- return resultLen;
-}
-
-/* returns zero if hash type invalid. */
-unsigned int
-HASH_ResultLen(HASH_HashType type)
-{
- if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return(0);
- }
-
- return(SECHashObjects[type].length);
-}
-
-unsigned int
-HASH_ResultLenContext(HASHContext *context)
-{
- return(context->hashobj->length);
-}
-
-
-
-SECStatus
-HASH_HashBuf(HASH_HashType type,
- unsigned char *dest,
- const unsigned char *src,
- PRUint32 src_len)
-{
- HASHContext *cx;
- unsigned int part;
-
- if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
- return(SECFailure);
- }
-
- cx = HASH_Create(type);
- if ( cx == NULL ) {
- return(SECFailure);
- }
- HASH_Begin(cx);
- HASH_Update(cx, src, src_len);
- HASH_End(cx, dest, &part, HASH_ResultLenContext(cx));
- HASH_Destroy(cx);
-
- return(SECSuccess);
-}
-
-HASHContext *
-HASH_Create(HASH_HashType type)
-{
- void *hash_context = NULL;
- HASHContext *ret = NULL;
-
- if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) {
- return(NULL);
- }
-
- hash_context = (* SECHashObjects[type].create)();
- if ( hash_context == NULL ) {
- goto loser;
- }
-
- ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
- if ( ret == NULL ) {
- goto loser;
- }
-
- ret->hash_context = hash_context;
- ret->hashobj = &SECHashObjects[type];
-
- return(ret);
-
-loser:
- if ( hash_context != NULL ) {
- (* SECHashObjects[type].destroy)(hash_context, PR_TRUE);
- }
-
- return(NULL);
-}
-
-
-HASHContext *
-HASH_Clone(HASHContext *context)
-{
- void *hash_context = NULL;
- HASHContext *ret = NULL;
-
- hash_context = (* context->hashobj->clone)(context->hash_context);
- if ( hash_context == NULL ) {
- goto loser;
- }
-
- ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext));
- if ( ret == NULL ) {
- goto loser;
- }
-
- ret->hash_context = hash_context;
- ret->hashobj = context->hashobj;
-
- return(ret);
-
-loser:
- if ( hash_context != NULL ) {
- (* context->hashobj->destroy)(hash_context, PR_TRUE);
- }
-
- return(NULL);
-
-}
-
-void
-HASH_Destroy(HASHContext *context)
-{
- (* context->hashobj->destroy)(context->hash_context, PR_TRUE);
- PORT_Free(context);
- return;
-}
-
-
-void
-HASH_Begin(HASHContext *context)
-{
- (* context->hashobj->begin)(context->hash_context);
- return;
-}
-
-
-void
-HASH_Update(HASHContext *context,
- const unsigned char *src,
- unsigned int len)
-{
- (* context->hashobj->update)(context->hash_context, src, len);
- return;
-}
-
-void
-HASH_End(HASHContext *context,
- unsigned char *result,
- unsigned int *result_len,
- unsigned int max_result_len)
-{
- (* context->hashobj->end)(context->hash_context, result, result_len,
- max_result_len);
- return;
-}
-
-HASH_HashType
-HASH_GetType(HASHContext *context)
-{
- return(context->hashobj->type);
-}
diff --git a/security/nss/lib/cryptohi/sechash.h b/security/nss/lib/cryptohi/sechash.h
deleted file mode 100644
index d234af1d3..000000000
--- a/security/nss/lib/cryptohi/sechash.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _HASH_H_
-#define _HASH_H_
-
-#include "seccomon.h"
-#include "hasht.h"
-#include "secoidt.h"
-
-SEC_BEGIN_PROTOS
-
-/*
-** Generic hash api.
-*/
-
-extern unsigned int HASH_ResultLen(HASH_HashType type);
-
-extern unsigned int HASH_ResultLenContext(HASHContext *context);
-
-extern unsigned int HASH_ResultLenByOidTag(SECOidTag hashOid);
-
-extern SECStatus HASH_HashBuf(HASH_HashType type,
- unsigned char *dest,
- const unsigned char *src,
- PRUint32 src_len);
-
-extern HASHContext * HASH_Create(HASH_HashType type);
-
-extern HASHContext * HASH_Clone(HASHContext *context);
-
-extern void HASH_Destroy(HASHContext *context);
-
-extern void HASH_Begin(HASHContext *context);
-
-extern void HASH_Update(HASHContext *context,
- const unsigned char *src,
- unsigned int len);
-
-extern void HASH_End(HASHContext *context,
- unsigned char *result,
- unsigned int *result_len,
- unsigned int max_result_len);
-
-extern HASH_HashType HASH_GetType(HASHContext *context);
-
-extern const SECHashObject * HASH_GetHashObject(HASH_HashType type);
-
-extern const SECHashObject * HASH_GetHashObjectByOidTag(SECOidTag hashOid);
-
-extern HASH_HashType HASH_GetHashTypeByOidTag(SECOidTag hashOid);
-extern SECOidTag HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid);
-extern SECOidTag HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid);
-
-SEC_END_PROTOS
-
-#endif /* _HASH_H_ */
diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c
deleted file mode 100644
index 34e26bc9d..000000000
--- a/security/nss/lib/cryptohi/seckey.c
+++ /dev/null
@@ -1,1937 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "cryptohi.h"
-#include "keyhi.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "secder.h"
-#include "base64.h"
-#include "secasn1.h"
-#include "cert.h"
-#include "pk11func.h"
-#include "secerr.h"
-#include "secdig.h"
-#include "prtime.h"
-#include "keyi.h"
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(SEC_IntegerTemplate)
-
-const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTSubjectPublicKeyInfo) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTSubjectPublicKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_BIT_STRING,
- offsetof(CERTSubjectPublicKeyInfo,subjectPublicKey), },
- { 0, }
-};
-
-const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPublicKeyAndChallenge) },
- { SEC_ASN1_ANY, offsetof(CERTPublicKeyAndChallenge,spki) },
- { SEC_ASN1_IA5_STRING, offsetof(CERTPublicKeyAndChallenge,challenge) },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_RSAPublicKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.rsa.modulus), },
- { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.rsa.publicExponent), },
- { 0, }
-};
-
-static const SEC_ASN1Template seckey_PointerToAlgorithmIDTemplate[] = {
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN, 0,
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }
-};
-
-/* Parameters for SEC_OID_PKCS1_RSA_PSS_SIGNATURE */
-const SEC_ASN1Template SECKEY_RSAPSSParamsTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRSAPSSParams) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SECKEYRSAPSSParams, hashAlg),
- seckey_PointerToAlgorithmIDTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(SECKEYRSAPSSParams, maskAlg),
- seckey_PointerToAlgorithmIDTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
- SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 2,
- offsetof(SECKEYRSAPSSParams, saltLength),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
- SEC_ASN1_XTRN | SEC_ASN1_CONTEXT_SPECIFIC | 3,
- offsetof(SECKEYRSAPSSParams, trailerField),
- SEC_ASN1_SUB(SEC_IntegerTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_DSAPublicKeyTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.dsa.publicValue), },
- { 0, }
-};
-
-const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
- { 0, }
-};
-
-const SEC_ASN1Template SECKEY_DHPublicKeyTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.dh.publicValue), },
- { 0, }
-};
-
-const SEC_ASN1Template SECKEY_DHParamKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.dh.prime), },
- { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.dh.base), },
- /* XXX chrisk: this needs to be expanded for decoding of j and validationParms (RFC2459 7.3.2) */
- { SEC_ASN1_SKIP_REST },
- { 0, }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_DSAPublicKeyTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPublicKeyTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPSSParamsTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SubjectPublicKeyInfoTemplate)
-
-/*
- * See bugzilla bug 125359
- * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
- * all of the templates above that en/decode into integers must be converted
- * from ASN.1's signed integer type. This is done by marking either the
- * source or destination (encoding or decoding, respectively) type as
- * siUnsignedInteger.
- */
-static void
-prepare_rsa_pub_key_for_asn1(SECKEYPublicKey *pubk)
-{
- pubk->u.rsa.modulus.type = siUnsignedInteger;
- pubk->u.rsa.publicExponent.type = siUnsignedInteger;
-}
-
-static void
-prepare_dsa_pub_key_for_asn1(SECKEYPublicKey *pubk)
-{
- pubk->u.dsa.publicValue.type = siUnsignedInteger;
-}
-
-static void
-prepare_pqg_params_for_asn1(SECKEYPQGParams *params)
-{
- params->prime.type = siUnsignedInteger;
- params->subPrime.type = siUnsignedInteger;
- params->base.type = siUnsignedInteger;
-}
-
-static void
-prepare_dh_pub_key_for_asn1(SECKEYPublicKey *pubk)
-{
- pubk->u.dh.prime.type = siUnsignedInteger;
- pubk->u.dh.base.type = siUnsignedInteger;
- pubk->u.dh.publicValue.type = siUnsignedInteger;
-}
-
-/* Create an RSA key pair is any slot able to do so.
-** The created keys are "session" (temporary), not "token" (permanent),
-** and they are "sensitive", which makes them costly to move to another token.
-*/
-SECKEYPrivateKey *
-SECKEY_CreateRSAPrivateKey(int keySizeInBits,SECKEYPublicKey **pubk, void *cx)
-{
- SECKEYPrivateKey *privk;
- PK11RSAGenParams param;
- PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN,cx);
- if (!slot) {
- return NULL;
- }
-
- param.keySizeInBits = keySizeInBits;
- param.pe = 65537L;
-
- privk = PK11_GenerateKeyPair(slot,CKM_RSA_PKCS_KEY_PAIR_GEN,&param,pubk,
- PR_FALSE, PR_TRUE, cx);
- PK11_FreeSlot(slot);
- return(privk);
-}
-
-/* Create a DH key pair in any slot able to do so,
-** This is a "session" (temporary), not "token" (permanent) key.
-** Because of the high probability that this key will need to be moved to
-** another token, and the high cost of moving "sensitive" keys, we attempt
-** to create this key pair without the "sensitive" attribute, but revert to
-** creating a "sensitive" key if necessary.
-*/
-SECKEYPrivateKey *
-SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *cx)
-{
- SECKEYPrivateKey *privk;
- PK11SlotInfo *slot;
-
- if (!param || !param->base.data || !param->prime.data ||
- param->prime.len < 512/8 || param->base.len == 0 ||
- param->base.len > param->prime.len + 1 ||
- (param->base.len == 1 && param->base.data[0] == 0)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,cx);
- if (!slot) {
- return NULL;
- }
-
- privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
- pubk, PR_FALSE, PR_FALSE, cx);
- if (!privk)
- privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param,
- pubk, PR_FALSE, PR_TRUE, cx);
-
- PK11_FreeSlot(slot);
- return(privk);
-}
-
-/* Create an EC key pair in any slot able to do so,
-** This is a "session" (temporary), not "token" (permanent) key.
-** Because of the high probability that this key will need to be moved to
-** another token, and the high cost of moving "sensitive" keys, we attempt
-** to create this key pair without the "sensitive" attribute, but revert to
-** creating a "sensitive" key if necessary.
-*/
-SECKEYPrivateKey *
-SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *cx)
-{
- SECKEYPrivateKey *privk;
- PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_KEY_PAIR_GEN,cx);
- if (!slot) {
- return NULL;
- }
-
- privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_KEY_PAIR_GEN,
- param, pubk,
- PK11_ATTR_SESSION | PK11_ATTR_INSENSITIVE |
- PK11_ATTR_PUBLIC,
- CKF_DERIVE, CKF_DERIVE|CKF_SIGN,cx);
- if (!privk)
- privk = PK11_GenerateKeyPairWithOpFlags(slot, CKM_EC_KEY_PAIR_GEN,
- param, pubk,
- PK11_ATTR_SESSION | PK11_ATTR_SENSITIVE |
- PK11_ATTR_PRIVATE,
- CKF_DERIVE, CKF_DERIVE|CKF_SIGN,cx);
-
- PK11_FreeSlot(slot);
- return(privk);
-}
-
-void
-SECKEY_DestroyPrivateKey(SECKEYPrivateKey *privk)
-{
- if (privk) {
- if (privk->pkcs11Slot) {
- if (privk->pkcs11IsTemp) {
- PK11_DestroyObject(privk->pkcs11Slot,privk->pkcs11ID);
- }
- PK11_FreeSlot(privk->pkcs11Slot);
-
- }
- if (privk->arena) {
- PORT_FreeArena(privk->arena, PR_TRUE);
- }
- }
-}
-
-void
-SECKEY_DestroyPublicKey(SECKEYPublicKey *pubk)
-{
- if (pubk) {
- if (pubk->pkcs11Slot) {
- if (!PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) {
- PK11_DestroyObject(pubk->pkcs11Slot,pubk->pkcs11ID);
- }
- PK11_FreeSlot(pubk->pkcs11Slot);
- }
- if (pubk->arena) {
- PORT_FreeArena(pubk->arena, PR_FALSE);
- }
- }
-}
-
-SECStatus
-SECKEY_CopySubjectPublicKeyInfo(PRArenaPool *arena,
- CERTSubjectPublicKeyInfo *to,
- CERTSubjectPublicKeyInfo *from)
-{
- SECStatus rv;
- SECItem spk;
-
- rv = SECOID_CopyAlgorithmID(arena, &to->algorithm, &from->algorithm);
- if (rv == SECSuccess) {
- /*
- * subjectPublicKey is a bit string, whose length is in bits.
- * Convert the length from bits to bytes for SECITEM_CopyItem.
- */
- spk = from->subjectPublicKey;
- DER_ConvertBitString(&spk);
- rv = SECITEM_CopyItem(arena, &to->subjectPublicKey, &spk);
- /* Set the length back to bits. */
- if (rv == SECSuccess) {
- to->subjectPublicKey.len = from->subjectPublicKey.len;
- }
- }
-
- return rv;
-}
-
-/* Procedure to update the pqg parameters for a cert's public key.
- * pqg parameters only need to be updated for DSA certificates.
- * The procedure uses calls to itself recursively to update a certificate
- * issuer's pqg parameters. Some important rules are:
- * - Do nothing if the cert already has PQG parameters.
- * - If the cert does not have PQG parameters, obtain them from the issuer.
- * - A valid cert chain cannot have a DSA cert without
- * pqg parameters that has a parent that is not a DSA cert. */
-
-static SECStatus
-seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count)
-{
- SECStatus rv;
- SECOidData *oid=NULL;
- int tag;
- CERTSubjectPublicKeyInfo * subjectSpki=NULL;
- CERTSubjectPublicKeyInfo * issuerSpki=NULL;
- CERTCertificate *issuerCert = NULL;
-
- rv = SECSuccess;
-
- /* increment cert chain length counter*/
- count++;
-
- /* check if cert chain length exceeds the maximum length*/
- if (count > CERT_MAX_CERT_CHAIN) {
- return SECFailure;
- }
-
- oid = SECOID_FindOID(&subjectCert->subjectPublicKeyInfo.algorithm.algorithm);
- if (oid != NULL) {
- tag = oid->offset;
-
- /* Check if cert has a DSA or EC public key. If not, return
- * success since no PQG params need to be updated.
- *
- * Question: do we really need to do this for EC keys. They don't have
- * PQG parameters, but they do have parameters. The question is does
- * the child cert inherit thost parameters for EC from the parent, or
- * do we always include those parameters in each cert.
- */
-
- if ( (tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
- (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
- (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) &&
- (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) &&
- (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
- (tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
- (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) {
-
- return SECSuccess;
- }
- } else {
- return SECFailure; /* return failure if oid is NULL */
- }
-
- /* if cert has PQG parameters, return success */
-
- subjectSpki=&subjectCert->subjectPublicKeyInfo;
-
- if (subjectSpki->algorithm.parameters.len != 0) {
- return SECSuccess;
- }
-
- /* check if the cert is self-signed */
- if (subjectCert->isRoot) {
- /* fail since cert is self-signed and has no pqg params. */
- return SECFailure;
- }
-
- /* get issuer cert */
- issuerCert = CERT_FindCertIssuer(subjectCert, PR_Now(), certUsageAnyCA);
- if ( ! issuerCert ) {
- return SECFailure;
- }
-
- /* if parent is not DSA, return failure since
- we don't allow this case. */
-
- oid = SECOID_FindOID(&issuerCert->subjectPublicKeyInfo.algorithm.algorithm);
- if (oid != NULL) {
- tag = oid->offset;
-
- /* Check if issuer cert has a DSA public key. If not,
- * return failure. */
-
- if ( (tag != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
- (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
- (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST) &&
- (tag != SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST) &&
- (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) &&
- (tag != SEC_OID_SDN702_DSA_SIGNATURE) &&
- (tag != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) {
- rv = SECFailure;
- goto loser;
- }
- } else {
- rv = SECFailure; /* return failure if oid is NULL */
- goto loser;
- }
-
-
- /* at this point the subject cert has no pqg parameters and the
- * issuer cert has a DSA public key. Update the issuer's
- * pqg parameters with a recursive call to this same function. */
-
- rv = seckey_UpdateCertPQGChain(issuerCert, count);
- if (rv != SECSuccess) {
- rv = SECFailure;
- goto loser;
- }
-
- /* ensure issuer has pqg parameters */
-
- issuerSpki=&issuerCert->subjectPublicKeyInfo;
- if (issuerSpki->algorithm.parameters.len == 0) {
- rv = SECFailure;
- }
-
- /* if update was successful and pqg params present, then copy the
- * parameters to the subject cert's key. */
-
- if (rv == SECSuccess) {
- rv = SECITEM_CopyItem(subjectCert->arena,
- &subjectSpki->algorithm.parameters,
- &issuerSpki->algorithm.parameters);
- }
-
-loser:
- if (issuerCert) {
- CERT_DestroyCertificate(issuerCert);
- }
- return rv;
-
-}
-
-
-SECStatus
-SECKEY_UpdateCertPQG(CERTCertificate * subjectCert)
-{
- if (!subjectCert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- return seckey_UpdateCertPQGChain(subjectCert,0);
-}
-
-
-/* Decode the DSA PQG parameters. The params could be stored in two
- * possible formats, the old fortezza-only wrapped format or
- * the normal standard format. Store the decoded parameters in
- * a V3 certificate data structure. */
-
-SECStatus
-SECKEY_DSADecodePQG(PRArenaPool *arena, SECKEYPublicKey *pubk, SECItem *params) {
- SECStatus rv;
- SECItem newparams;
-
- if (params == NULL) return SECFailure;
-
- if (params->data == NULL) return SECFailure;
-
- PORT_Assert(arena);
-
- /* make a copy of the data into the arena so QuickDER output is valid */
- rv = SECITEM_CopyItem(arena, &newparams, params);
-
- /* Check if params use the standard format.
- * The value 0xa1 will appear in the first byte of the parameter data
- * if the PQG parameters are not using the standard format. This
- * code should be changed to use a better method to detect non-standard
- * parameters. */
-
- if ((newparams.data[0] != 0xa1) &&
- (newparams.data[0] != 0xa0)) {
-
- if (SECSuccess == rv) {
- /* PQG params are in the standard format */
- prepare_pqg_params_for_asn1(&pubk->u.dsa.params);
- rv = SEC_QuickDERDecodeItem(arena, &pubk->u.dsa.params,
- SECKEY_PQGParamsTemplate,
- &newparams);
- }
- } else {
-
- if (SECSuccess == rv) {
- /* else the old fortezza-only wrapped format is used. */
- PORT_SetError(SEC_ERROR_BAD_DER);
- rv = SECFailure;
- }
- }
- return rv;
-}
-
-
-/* Function used to make an oid tag to a key type */
-KeyType
-seckey_GetKeyType (SECOidTag tag) {
- KeyType keyType;
-
- switch (tag) {
- case SEC_OID_X500_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- keyType = rsaKey;
- break;
- case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
- keyType = rsaPssKey;
- break;
- case SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION:
- keyType = rsaOaepKey;
- break;
- case SEC_OID_ANSIX9_DSA_SIGNATURE:
- keyType = dsaKey;
- break;
- case SEC_OID_MISSI_KEA_DSS_OLD:
- case SEC_OID_MISSI_KEA_DSS:
- case SEC_OID_MISSI_DSS_OLD:
- case SEC_OID_MISSI_DSS:
- keyType = fortezzaKey;
- break;
- case SEC_OID_MISSI_KEA:
- case SEC_OID_MISSI_ALT_KEA:
- keyType = keaKey;
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- keyType = dhKey;
- break;
- case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
- keyType = ecKey;
- break;
- /* accommodate applications that hand us a signature type when they
- * should be handing us a cipher type */
- case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
- keyType = rsaKey;
- break;
- default:
- keyType = nullKey;
- }
- return keyType;
-}
-
-/* Function used to determine what kind of cert we are dealing with. */
-KeyType
-CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki)
-{
- return seckey_GetKeyType(SECOID_GetAlgorithmTag(&spki->algorithm));
-}
-
-static SECKEYPublicKey *
-seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
-{
- SECKEYPublicKey *pubk;
- SECItem os, newOs, newParms;
- SECStatus rv;
- PRArenaPool *arena;
- SECOidTag tag;
-
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- return NULL;
-
- pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
- if (pubk == NULL) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
- }
-
- pubk->arena = arena;
- pubk->pkcs11Slot = 0;
- pubk->pkcs11ID = CK_INVALID_HANDLE;
-
-
- /* Convert bit string length from bits to bytes */
- os = spki->subjectPublicKey;
- DER_ConvertBitString (&os);
-
- tag = SECOID_GetAlgorithmTag(&spki->algorithm);
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newOs, &os);
- if ( rv == SECSuccess )
- switch ( tag ) {
- case SEC_OID_X500_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- pubk->keyType = rsaKey;
- prepare_rsa_pub_key_for_asn1(pubk);
- rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &newOs);
- if (rv == SECSuccess)
- return pubk;
- break;
- case SEC_OID_ANSIX9_DSA_SIGNATURE:
- case SEC_OID_SDN702_DSA_SIGNATURE:
- pubk->keyType = dsaKey;
- prepare_dsa_pub_key_for_asn1(pubk);
- rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &newOs);
- if (rv != SECSuccess) break;
-
- rv = SECKEY_DSADecodePQG(arena, pubk,
- &spki->algorithm.parameters);
-
- if (rv == SECSuccess) return pubk;
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- pubk->keyType = dhKey;
- prepare_dh_pub_key_for_asn1(pubk);
- rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &newOs);
- if (rv != SECSuccess) break;
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newParms, &spki->algorithm.parameters);
- if ( rv != SECSuccess )
- break;
-
- rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHParamKeyTemplate,
- &newParms);
-
- if (rv == SECSuccess) return pubk;
- break;
- case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
- pubk->keyType = ecKey;
- pubk->u.ec.size = 0;
-
- /* Since PKCS#11 directly takes the DER encoding of EC params
- * and public value, we don't need any decoding here.
- */
- rv = SECITEM_CopyItem(arena, &pubk->u.ec.DEREncodedParams,
- &spki->algorithm.parameters);
- if ( rv != SECSuccess )
- break;
- rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &newOs);
- if (rv == SECSuccess) return pubk;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- rv = SECFailure;
- break;
- }
-
- SECKEY_DestroyPublicKey (pubk);
- return NULL;
-}
-
-
-/* required for JSS */
-SECKEYPublicKey *
-SECKEY_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
-{
- return seckey_ExtractPublicKey(spki);
-}
-
-SECKEYPublicKey *
-CERT_ExtractPublicKey(CERTCertificate *cert)
-{
- SECStatus rv;
-
- if (!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- rv = SECKEY_UpdateCertPQG(cert);
- if (rv != SECSuccess) return NULL;
-
- return seckey_ExtractPublicKey(&cert->subjectPublicKeyInfo);
-}
-
-int
-SECKEY_ECParamsToKeySize(const SECItem *encodedParams)
-{
- SECOidTag tag;
- SECItem oid = { siBuffer, NULL, 0};
-
- /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID),
- * followed by the length of the curve oid and the curve oid.
- */
- oid.len = encodedParams->data[1];
- oid.data = encodedParams->data + 2;
- if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)
- return 0;
-
- switch (tag) {
- case SEC_OID_SECG_EC_SECP112R1:
- case SEC_OID_SECG_EC_SECP112R2:
- return 112;
-
- case SEC_OID_SECG_EC_SECT113R1:
- case SEC_OID_SECG_EC_SECT113R2:
- return 113;
-
- case SEC_OID_SECG_EC_SECP128R1:
- case SEC_OID_SECG_EC_SECP128R2:
- return 128;
-
- case SEC_OID_SECG_EC_SECT131R1:
- case SEC_OID_SECG_EC_SECT131R2:
- return 131;
-
- case SEC_OID_SECG_EC_SECP160K1:
- case SEC_OID_SECG_EC_SECP160R1:
- case SEC_OID_SECG_EC_SECP160R2:
- return 160;
-
- case SEC_OID_SECG_EC_SECT163K1:
- case SEC_OID_SECG_EC_SECT163R1:
- case SEC_OID_SECG_EC_SECT163R2:
- case SEC_OID_ANSIX962_EC_C2PNB163V1:
- case SEC_OID_ANSIX962_EC_C2PNB163V2:
- case SEC_OID_ANSIX962_EC_C2PNB163V3:
- return 163;
-
- case SEC_OID_ANSIX962_EC_C2PNB176V1:
- return 176;
-
- case SEC_OID_ANSIX962_EC_C2TNB191V1:
- case SEC_OID_ANSIX962_EC_C2TNB191V2:
- case SEC_OID_ANSIX962_EC_C2TNB191V3:
- case SEC_OID_ANSIX962_EC_C2ONB191V4:
- case SEC_OID_ANSIX962_EC_C2ONB191V5:
- return 191;
-
- case SEC_OID_SECG_EC_SECP192K1:
- case SEC_OID_ANSIX962_EC_PRIME192V1:
- case SEC_OID_ANSIX962_EC_PRIME192V2:
- case SEC_OID_ANSIX962_EC_PRIME192V3:
- return 192;
-
- case SEC_OID_SECG_EC_SECT193R1:
- case SEC_OID_SECG_EC_SECT193R2:
- return 193;
-
- case SEC_OID_ANSIX962_EC_C2PNB208W1:
- return 208;
-
- case SEC_OID_SECG_EC_SECP224K1:
- case SEC_OID_SECG_EC_SECP224R1:
- return 224;
-
- case SEC_OID_SECG_EC_SECT233K1:
- case SEC_OID_SECG_EC_SECT233R1:
- return 233;
-
- case SEC_OID_SECG_EC_SECT239K1:
- case SEC_OID_ANSIX962_EC_C2TNB239V1:
- case SEC_OID_ANSIX962_EC_C2TNB239V2:
- case SEC_OID_ANSIX962_EC_C2TNB239V3:
- case SEC_OID_ANSIX962_EC_C2ONB239V4:
- case SEC_OID_ANSIX962_EC_C2ONB239V5:
- case SEC_OID_ANSIX962_EC_PRIME239V1:
- case SEC_OID_ANSIX962_EC_PRIME239V2:
- case SEC_OID_ANSIX962_EC_PRIME239V3:
- return 239;
-
- case SEC_OID_SECG_EC_SECP256K1:
- case SEC_OID_ANSIX962_EC_PRIME256V1:
- return 256;
-
- case SEC_OID_ANSIX962_EC_C2PNB272W1:
- return 272;
-
- case SEC_OID_SECG_EC_SECT283K1:
- case SEC_OID_SECG_EC_SECT283R1:
- return 283;
-
- case SEC_OID_ANSIX962_EC_C2PNB304W1:
- return 304;
-
- case SEC_OID_ANSIX962_EC_C2TNB359V1:
- return 359;
-
- case SEC_OID_ANSIX962_EC_C2PNB368W1:
- return 368;
-
- case SEC_OID_SECG_EC_SECP384R1:
- return 384;
-
- case SEC_OID_SECG_EC_SECT409K1:
- case SEC_OID_SECG_EC_SECT409R1:
- return 409;
-
- case SEC_OID_ANSIX962_EC_C2TNB431R1:
- return 431;
-
- case SEC_OID_SECG_EC_SECP521R1:
- return 521;
-
- case SEC_OID_SECG_EC_SECT571K1:
- case SEC_OID_SECG_EC_SECT571R1:
- return 571;
-
- default:
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- return 0;
- }
-}
-
-int
-SECKEY_ECParamsToBasePointOrderLen(const SECItem *encodedParams)
-{
- SECOidTag tag;
- SECItem oid = { siBuffer, NULL, 0};
-
- /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID),
- * followed by the length of the curve oid and the curve oid.
- */
- oid.len = encodedParams->data[1];
- oid.data = encodedParams->data + 2;
- if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)
- return 0;
-
- switch (tag) {
- case SEC_OID_SECG_EC_SECP112R1:
- return 112;
- case SEC_OID_SECG_EC_SECP112R2:
- return 110;
-
- case SEC_OID_SECG_EC_SECT113R1:
- case SEC_OID_SECG_EC_SECT113R2:
- return 113;
-
- case SEC_OID_SECG_EC_SECP128R1:
- return 128;
- case SEC_OID_SECG_EC_SECP128R2:
- return 126;
-
- case SEC_OID_SECG_EC_SECT131R1:
- case SEC_OID_SECG_EC_SECT131R2:
- return 131;
-
- case SEC_OID_SECG_EC_SECP160K1:
- case SEC_OID_SECG_EC_SECP160R1:
- case SEC_OID_SECG_EC_SECP160R2:
- return 161;
-
- case SEC_OID_SECG_EC_SECT163K1:
- return 163;
- case SEC_OID_SECG_EC_SECT163R1:
- return 162;
- case SEC_OID_SECG_EC_SECT163R2:
- case SEC_OID_ANSIX962_EC_C2PNB163V1:
- return 163;
- case SEC_OID_ANSIX962_EC_C2PNB163V2:
- case SEC_OID_ANSIX962_EC_C2PNB163V3:
- return 162;
-
- case SEC_OID_ANSIX962_EC_C2PNB176V1:
- return 161;
-
- case SEC_OID_ANSIX962_EC_C2TNB191V1:
- return 191;
- case SEC_OID_ANSIX962_EC_C2TNB191V2:
- return 190;
- case SEC_OID_ANSIX962_EC_C2TNB191V3:
- return 189;
- case SEC_OID_ANSIX962_EC_C2ONB191V4:
- return 191;
- case SEC_OID_ANSIX962_EC_C2ONB191V5:
- return 188;
-
- case SEC_OID_SECG_EC_SECP192K1:
- case SEC_OID_ANSIX962_EC_PRIME192V1:
- case SEC_OID_ANSIX962_EC_PRIME192V2:
- case SEC_OID_ANSIX962_EC_PRIME192V3:
- return 192;
-
- case SEC_OID_SECG_EC_SECT193R1:
- case SEC_OID_SECG_EC_SECT193R2:
- return 193;
-
- case SEC_OID_ANSIX962_EC_C2PNB208W1:
- return 193;
-
- case SEC_OID_SECG_EC_SECP224K1:
- return 225;
- case SEC_OID_SECG_EC_SECP224R1:
- return 224;
-
- case SEC_OID_SECG_EC_SECT233K1:
- return 232;
- case SEC_OID_SECG_EC_SECT233R1:
- return 233;
-
- case SEC_OID_SECG_EC_SECT239K1:
- case SEC_OID_ANSIX962_EC_C2TNB239V1:
- return 238;
- case SEC_OID_ANSIX962_EC_C2TNB239V2:
- return 237;
- case SEC_OID_ANSIX962_EC_C2TNB239V3:
- return 236;
- case SEC_OID_ANSIX962_EC_C2ONB239V4:
- return 238;
- case SEC_OID_ANSIX962_EC_C2ONB239V5:
- return 237;
- case SEC_OID_ANSIX962_EC_PRIME239V1:
- case SEC_OID_ANSIX962_EC_PRIME239V2:
- case SEC_OID_ANSIX962_EC_PRIME239V3:
- return 239;
-
- case SEC_OID_SECG_EC_SECP256K1:
- case SEC_OID_ANSIX962_EC_PRIME256V1:
- return 256;
-
- case SEC_OID_ANSIX962_EC_C2PNB272W1:
- return 257;
-
- case SEC_OID_SECG_EC_SECT283K1:
- return 281;
- case SEC_OID_SECG_EC_SECT283R1:
- return 282;
-
- case SEC_OID_ANSIX962_EC_C2PNB304W1:
- return 289;
-
- case SEC_OID_ANSIX962_EC_C2TNB359V1:
- return 353;
-
- case SEC_OID_ANSIX962_EC_C2PNB368W1:
- return 353;
-
- case SEC_OID_SECG_EC_SECP384R1:
- return 384;
-
- case SEC_OID_SECG_EC_SECT409K1:
- return 407;
- case SEC_OID_SECG_EC_SECT409R1:
- return 409;
-
- case SEC_OID_ANSIX962_EC_C2TNB431R1:
- return 418;
-
- case SEC_OID_SECG_EC_SECP521R1:
- return 521;
-
- case SEC_OID_SECG_EC_SECT571K1:
- case SEC_OID_SECG_EC_SECT571R1:
- return 570;
-
- default:
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- return 0;
- }
-}
-
-/* returns key strength in bytes (not bits) */
-unsigned
-SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk)
-{
- unsigned char b0;
- unsigned size;
-
- /* interpret modulus length as key strength */
- if (!pubk)
- goto loser;
- switch (pubk->keyType) {
- case rsaKey:
- if (!pubk->u.rsa.modulus.data) break;
- b0 = pubk->u.rsa.modulus.data[0];
- return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
- case dsaKey:
- if (!pubk->u.dsa.publicValue.data) break;
- b0 = pubk->u.dsa.publicValue.data[0];
- return b0 ? pubk->u.dsa.publicValue.len :
- pubk->u.dsa.publicValue.len - 1;
- case dhKey:
- if (!pubk->u.dh.publicValue.data) break;
- b0 = pubk->u.dh.publicValue.data[0];
- return b0 ? pubk->u.dh.publicValue.len :
- pubk->u.dh.publicValue.len - 1;
- case ecKey:
- /* Get the key size in bits and adjust */
- size = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
- return (size + 7)/8;
- default:
- break;
- }
-loser:
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return 0;
-}
-
-/* returns key strength in bits */
-unsigned
-SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk)
-{
- unsigned size;
- switch (pubk->keyType) {
- case rsaKey:
- case dsaKey:
- case dhKey:
- return SECKEY_PublicKeyStrength(pubk) * 8; /* 1 byte = 8 bits */
- case ecKey:
- size = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
- return size;
- default:
- break;
- }
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return 0;
-}
-
-/* returns signature length in bytes (not bits) */
-unsigned
-SECKEY_SignatureLen(const SECKEYPublicKey *pubk)
-{
- unsigned char b0;
- unsigned size;
-
- switch (pubk->keyType) {
- case rsaKey:
- b0 = pubk->u.rsa.modulus.data[0];
- return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
- case dsaKey:
- return pubk->u.dsa.params.subPrime.len * 2;
- case ecKey:
- /* Get the base point order length in bits and adjust */
- size = SECKEY_ECParamsToBasePointOrderLen(
- &pubk->u.ec.DEREncodedParams);
- return ((size + 7)/8) * 2;
- default:
- break;
- }
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return 0;
-}
-
-SECKEYPrivateKey *
-SECKEY_CopyPrivateKey(const SECKEYPrivateKey *privk)
-{
- SECKEYPrivateKey *copyk;
- PRArenaPool *arena;
-
- if (!privk || !privk->pkcs11Slot) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return NULL;
- }
-
- copyk = (SECKEYPrivateKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPrivateKey));
- if (copyk) {
- copyk->arena = arena;
- copyk->keyType = privk->keyType;
-
- /* copy the PKCS #11 parameters */
- copyk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);
- /* if the key we're referencing was a temparary key we have just
- * created, that we want to go away when we're through, we need
- * to make a copy of it */
- if (privk->pkcs11IsTemp) {
- copyk->pkcs11ID =
- PK11_CopyKey(privk->pkcs11Slot,privk->pkcs11ID);
- if (copyk->pkcs11ID == CK_INVALID_HANDLE) goto fail;
- } else {
- copyk->pkcs11ID = privk->pkcs11ID;
- }
- copyk->pkcs11IsTemp = privk->pkcs11IsTemp;
- copyk->wincx = privk->wincx;
- copyk->staticflags = privk->staticflags;
- return copyk;
- } else {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- }
-
-fail:
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
-}
-
-SECKEYPublicKey *
-SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk)
-{
- SECKEYPublicKey *copyk;
- PRArenaPool *arena;
- SECStatus rv = SECSuccess;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- copyk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey));
- if (!copyk) {
- PORT_FreeArena (arena, PR_FALSE);
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- copyk->arena = arena;
- copyk->keyType = pubk->keyType;
- if (pubk->pkcs11Slot &&
- PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) {
- copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot);
- copyk->pkcs11ID = pubk->pkcs11ID;
- } else {
- copyk->pkcs11Slot = NULL; /* go get own reference */
- copyk->pkcs11ID = CK_INVALID_HANDLE;
- }
- switch (pubk->keyType) {
- case rsaKey:
- rv = SECITEM_CopyItem(arena, &copyk->u.rsa.modulus,
- &pubk->u.rsa.modulus);
- if (rv == SECSuccess) {
- rv = SECITEM_CopyItem (arena, &copyk->u.rsa.publicExponent,
- &pubk->u.rsa.publicExponent);
- if (rv == SECSuccess)
- return copyk;
- }
- break;
- case dsaKey:
- rv = SECITEM_CopyItem(arena, &copyk->u.dsa.publicValue,
- &pubk->u.dsa.publicValue);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.prime,
- &pubk->u.dsa.params.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.subPrime,
- &pubk->u.dsa.params.subPrime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.base,
- &pubk->u.dsa.params.base);
- break;
- case dhKey:
- rv = SECITEM_CopyItem(arena,&copyk->u.dh.prime,&pubk->u.dh.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena,&copyk->u.dh.base,&pubk->u.dh.base);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &copyk->u.dh.publicValue,
- &pubk->u.dh.publicValue);
- break;
- case ecKey:
- copyk->u.ec.size = pubk->u.ec.size;
- rv = SECITEM_CopyItem(arena,&copyk->u.ec.DEREncodedParams,
- &pubk->u.ec.DEREncodedParams);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena,&copyk->u.ec.publicValue,
- &pubk->u.ec.publicValue);
- break;
- case nullKey:
- return copyk;
- default:
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- rv = SECFailure;
- break;
- }
- if (rv == SECSuccess)
- return copyk;
-
- SECKEY_DestroyPublicKey (copyk);
- return NULL;
-}
-
-
-SECKEYPublicKey *
-SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
-{
- SECKEYPublicKey *pubk;
- PRArenaPool *arena;
- CERTCertificate *cert;
- SECStatus rv;
-
- /*
- * First try to look up the cert.
- */
- cert = PK11_GetCertFromPrivateKey(privk);
- if (cert) {
- pubk = CERT_ExtractPublicKey(cert);
- CERT_DestroyCertificate(cert);
- return pubk;
- }
-
- /* couldn't find the cert, build pub key by hand */
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
- pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof (SECKEYPublicKey));
- if (pubk == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
- pubk->keyType = privk->keyType;
- pubk->pkcs11Slot = NULL;
- pubk->pkcs11ID = CK_INVALID_HANDLE;
- pubk->arena = arena;
-
- switch(privk->keyType) {
- case nullKey:
- case dhKey:
- case dsaKey:
- /* Nothing to query, if the cert isn't there, we're done -- no way
- * to get the public key */
- break;
- case rsaKey:
- rv = PK11_ReadAttribute(privk->pkcs11Slot,privk->pkcs11ID,
- CKA_MODULUS,arena,&pubk->u.rsa.modulus);
- if (rv != SECSuccess) break;
- rv = PK11_ReadAttribute(privk->pkcs11Slot,privk->pkcs11ID,
- CKA_PUBLIC_EXPONENT,arena,&pubk->u.rsa.publicExponent);
- if (rv != SECSuccess) break;
- return pubk;
- break;
- default:
- break;
- }
-
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
-}
-
-CERTSubjectPublicKeyInfo *
-SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
-{
- CERTSubjectPublicKeyInfo *spki;
- PRArenaPool *arena;
- SECItem params = { siBuffer, NULL, 0 };
-
- if (!pubk) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- spki = (CERTSubjectPublicKeyInfo *) PORT_ArenaZAlloc(arena, sizeof (*spki));
- if (spki != NULL) {
- SECStatus rv;
- SECItem *rv_item;
-
- spki->arena = arena;
- switch(pubk->keyType) {
- case rsaKey:
- rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
- SEC_OID_PKCS1_RSA_ENCRYPTION, 0);
- if (rv == SECSuccess) {
- /*
- * DER encode the public key into the subjectPublicKeyInfo.
- */
- prepare_rsa_pub_key_for_asn1(pubk);
- rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
- pubk, SECKEY_RSAPublicKeyTemplate);
- if (rv_item != NULL) {
- /*
- * The stored value is supposed to be a BIT_STRING,
- * so convert the length.
- */
- spki->subjectPublicKey.len <<= 3;
- /*
- * We got a good one; return it.
- */
- return spki;
- }
- }
- break;
- case dsaKey:
- /* DER encode the params. */
- prepare_pqg_params_for_asn1(&pubk->u.dsa.params);
- rv_item = SEC_ASN1EncodeItem(arena, &params, &pubk->u.dsa.params,
- SECKEY_PQGParamsTemplate);
- if (rv_item != NULL) {
- rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
- SEC_OID_ANSIX9_DSA_SIGNATURE,
- &params);
- if (rv == SECSuccess) {
- /*
- * DER encode the public key into the subjectPublicKeyInfo.
- */
- prepare_dsa_pub_key_for_asn1(pubk);
- rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,
- pubk,
- SECKEY_DSAPublicKeyTemplate);
- if (rv_item != NULL) {
- /*
- * The stored value is supposed to be a BIT_STRING,
- * so convert the length.
- */
- spki->subjectPublicKey.len <<= 3;
- /*
- * We got a good one; return it.
- */
- return spki;
- }
- }
- }
- SECITEM_FreeItem(&params, PR_FALSE);
- break;
- case ecKey:
- rv = SECITEM_CopyItem(arena, &params,
- &pubk->u.ec.DEREncodedParams);
- if (rv != SECSuccess) break;
-
- rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,
- SEC_OID_ANSIX962_EC_PUBLIC_KEY,
- &params);
- if (rv != SECSuccess) break;
-
- rv = SECITEM_CopyItem(arena, &spki->subjectPublicKey,
- &pubk->u.ec.publicValue);
-
- if (rv == SECSuccess) {
- /*
- * The stored value is supposed to be a BIT_STRING,
- * so convert the length.
- */
- spki->subjectPublicKey.len <<= 3;
- /*
- * We got a good one; return it.
- */
- return spki;
- }
- break;
- case dhKey: /* later... */
-
- break;
- default:
- break;
- }
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
-}
-
-void
-SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki)
-{
- if (spki && spki->arena) {
- PORT_FreeArena(spki->arena, PR_FALSE);
- }
-}
-
-/*
- * this only works for RSA keys... need to do something
- * similiar to CERT_ExtractPublicKey for other key times.
- */
-SECKEYPublicKey *
-SECKEY_DecodeDERPublicKey(SECItem *pubkder)
-{
- PRArenaPool *arena;
- SECKEYPublicKey *pubk;
- SECStatus rv;
- SECItem newPubkder;
-
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey));
- if (pubk != NULL) {
- pubk->arena = arena;
- pubk->pkcs11Slot = NULL;
- pubk->pkcs11ID = 0;
- prepare_rsa_pub_key_for_asn1(pubk);
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newPubkder, pubkder);
- if ( rv == SECSuccess ) {
- rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate,
- &newPubkder);
- }
- if (rv == SECSuccess)
- return pubk;
- SECKEY_DestroyPublicKey (pubk);
- } else {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- }
-
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
-}
-
-/*
- * Decode a base64 ascii encoded DER encoded public key.
- */
-SECKEYPublicKey *
-SECKEY_ConvertAndDecodePublicKey(char *pubkstr)
-{
- SECKEYPublicKey *pubk;
- SECStatus rv;
- SECItem der;
-
- rv = ATOB_ConvertAsciiToItem (&der, pubkstr);
- if (rv != SECSuccess)
- return NULL;
-
- pubk = SECKEY_DecodeDERPublicKey (&der);
-
- PORT_Free (der.data);
- return pubk;
-}
-
-SECItem *
-SECKEY_EncodeDERSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
-{
- CERTSubjectPublicKeyInfo *spki=NULL;
- SECItem *spkiDER=NULL;
-
- /* get the subjectpublickeyinfo */
- spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
- if( spki == NULL ) {
- goto finish;
- }
-
- /* DER-encode the subjectpublickeyinfo */
- spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL/*dest*/, spki,
- CERT_SubjectPublicKeyInfoTemplate);
-
- SECKEY_DestroySubjectPublicKeyInfo(spki);
-
-finish:
- return spkiDER;
-}
-
-
-CERTSubjectPublicKeyInfo *
-SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider)
-{
- PRArenaPool *arena;
- CERTSubjectPublicKeyInfo *spki;
- SECStatus rv;
- SECItem newSpkider;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- spki = (CERTSubjectPublicKeyInfo *)
- PORT_ArenaZAlloc(arena, sizeof (CERTSubjectPublicKeyInfo));
- if (spki != NULL) {
- spki->arena = arena;
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newSpkider, spkider);
- if ( rv == SECSuccess ) {
- rv = SEC_QuickDERDecodeItem(arena,spki,
- CERT_SubjectPublicKeyInfoTemplate, &newSpkider);
- }
- if (rv == SECSuccess)
- return spki;
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
-}
-
-/*
- * Decode a base64 ascii encoded DER encoded subject public key info.
- */
-CERTSubjectPublicKeyInfo *
-SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(char *spkistr)
-{
- CERTSubjectPublicKeyInfo *spki;
- SECStatus rv;
- SECItem der;
-
- rv = ATOB_ConvertAsciiToItem(&der, spkistr);
- if (rv != SECSuccess)
- return NULL;
-
- spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
-
- PORT_Free(der.data);
- return spki;
-}
-
-/*
- * Decode a base64 ascii encoded DER encoded public key and challenge
- * Verify digital signature and make sure challenge matches
- */
-CERTSubjectPublicKeyInfo *
-SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
- void *wincx)
-{
- CERTSubjectPublicKeyInfo *spki = NULL;
- CERTPublicKeyAndChallenge pkac;
- SECStatus rv;
- SECItem signedItem;
- PRArenaPool *arena = NULL;
- CERTSignedData sd;
- SECItem sig;
- SECKEYPublicKey *pubKey = NULL;
- unsigned int len;
-
- signedItem.data = NULL;
-
- /* convert the base64 encoded data to binary */
- rv = ATOB_ConvertAsciiToItem(&signedItem, pkacstr);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* create an arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto loser;
- }
-
- /* decode the outer wrapping of signed data */
- PORT_Memset(&sd, 0, sizeof(CERTSignedData));
- rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem );
- if ( rv ) {
- goto loser;
- }
-
- /* decode the public key and challenge wrapper */
- PORT_Memset(&pkac, 0, sizeof(CERTPublicKeyAndChallenge));
- rv = SEC_QuickDERDecodeItem(arena, &pkac, CERT_PublicKeyAndChallengeTemplate,
- &sd.data);
- if ( rv ) {
- goto loser;
- }
-
- /* decode the subject public key info */
- spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&pkac.spki);
- if ( spki == NULL ) {
- goto loser;
- }
-
- /* get the public key */
- pubKey = seckey_ExtractPublicKey(spki);
- if ( pubKey == NULL ) {
- goto loser;
- }
-
- /* check the signature */
- sig = sd.signature;
- DER_ConvertBitString(&sig);
- rv = VFY_VerifyDataWithAlgorithmID(sd.data.data, sd.data.len, pubKey, &sig,
- &(sd.signatureAlgorithm), NULL, wincx);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* check the challenge */
- if ( challenge ) {
- len = PORT_Strlen(challenge);
- /* length is right */
- if ( len != pkac.challenge.len ) {
- goto loser;
- }
- /* actual data is right */
- if ( PORT_Memcmp(challenge, pkac.challenge.data, len) != 0 ) {
- goto loser;
- }
- }
- goto done;
-
-loser:
- /* make sure that we return null if we got an error */
- if ( spki ) {
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- }
- spki = NULL;
-
-done:
- if ( signedItem.data ) {
- PORT_Free(signedItem.data);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- if ( pubKey ) {
- SECKEY_DestroyPublicKey(pubKey);
- }
-
- return spki;
-}
-
-void
-SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk,
- PRBool freeit)
-{
- PRArenaPool *poolp;
-
- if(pvk != NULL) {
- if(pvk->arena) {
- poolp = pvk->arena;
- /* zero structure since PORT_FreeArena does not support
- * this yet.
- */
- PORT_Memset(pvk->privateKey.data, 0, pvk->privateKey.len);
- PORT_Memset((char *)pvk, 0, sizeof(*pvk));
- if(freeit == PR_TRUE) {
- PORT_FreeArena(poolp, PR_TRUE);
- } else {
- pvk->arena = poolp;
- }
- } else {
- SECITEM_ZfreeItem(&pvk->version, PR_FALSE);
- SECITEM_ZfreeItem(&pvk->privateKey, PR_FALSE);
- SECOID_DestroyAlgorithmID(&pvk->algorithm, PR_FALSE);
- PORT_Memset((char *)pvk, 0, sizeof(*pvk));
- if(freeit == PR_TRUE) {
- PORT_Free(pvk);
- }
- }
- }
-}
-
-void
-SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki,
- PRBool freeit)
-{
- PRArenaPool *poolp;
-
- if(epki != NULL) {
- if(epki->arena) {
- poolp = epki->arena;
- /* zero structure since PORT_FreeArena does not support
- * this yet.
- */
- PORT_Memset(epki->encryptedData.data, 0, epki->encryptedData.len);
- PORT_Memset((char *)epki, 0, sizeof(*epki));
- if(freeit == PR_TRUE) {
- PORT_FreeArena(poolp, PR_TRUE);
- } else {
- epki->arena = poolp;
- }
- } else {
- SECITEM_ZfreeItem(&epki->encryptedData, PR_FALSE);
- SECOID_DestroyAlgorithmID(&epki->algorithm, PR_FALSE);
- PORT_Memset((char *)epki, 0, sizeof(*epki));
- if(freeit == PR_TRUE) {
- PORT_Free(epki);
- }
- }
- }
-}
-
-SECStatus
-SECKEY_CopyPrivateKeyInfo(PRArenaPool *poolp,
- SECKEYPrivateKeyInfo *to,
- SECKEYPrivateKeyInfo *from)
-{
- SECStatus rv = SECFailure;
-
- if((to == NULL) || (from == NULL)) {
- return SECFailure;
- }
-
- rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
- if(rv != SECSuccess) {
- return SECFailure;
- }
- rv = SECITEM_CopyItem(poolp, &to->privateKey, &from->privateKey);
- if(rv != SECSuccess) {
- return SECFailure;
- }
- rv = SECITEM_CopyItem(poolp, &to->version, &from->version);
-
- return rv;
-}
-
-SECStatus
-SECKEY_CopyEncryptedPrivateKeyInfo(PRArenaPool *poolp,
- SECKEYEncryptedPrivateKeyInfo *to,
- SECKEYEncryptedPrivateKeyInfo *from)
-{
- SECStatus rv = SECFailure;
-
- if((to == NULL) || (from == NULL)) {
- return SECFailure;
- }
-
- rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm);
- if(rv != SECSuccess) {
- return SECFailure;
- }
- rv = SECITEM_CopyItem(poolp, &to->encryptedData, &from->encryptedData);
-
- return rv;
-}
-
-KeyType
-SECKEY_GetPrivateKeyType(SECKEYPrivateKey *privKey)
-{
- return privKey->keyType;
-}
-
-KeyType
-SECKEY_GetPublicKeyType(SECKEYPublicKey *pubKey)
-{
- return pubKey->keyType;
-}
-
-SECKEYPublicKey*
-SECKEY_ImportDERPublicKey(SECItem *derKey, CK_KEY_TYPE type)
-{
- SECKEYPublicKey *pubk = NULL;
- SECStatus rv = SECFailure;
- SECItem newDerKey;
- PRArenaPool *arena = NULL;
-
- if (!derKey) {
- return NULL;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto finish;
- }
-
- pubk = PORT_ArenaZNew(arena, SECKEYPublicKey);
- if (pubk == NULL) {
- goto finish;
- }
- pubk->arena = arena;
-
- rv = SECITEM_CopyItem(pubk->arena, &newDerKey, derKey);
- if (SECSuccess != rv) {
- goto finish;
- }
-
- pubk->pkcs11Slot = NULL;
- pubk->pkcs11ID = CK_INVALID_HANDLE;
-
- switch( type ) {
- case CKK_RSA:
- prepare_rsa_pub_key_for_asn1(pubk);
- rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_RSAPublicKeyTemplate, &newDerKey);
- pubk->keyType = rsaKey;
- break;
- case CKK_DSA:
- prepare_dsa_pub_key_for_asn1(pubk);
- rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DSAPublicKeyTemplate, &newDerKey);
- pubk->keyType = dsaKey;
- break;
- case CKK_DH:
- prepare_dh_pub_key_for_asn1(pubk);
- rv = SEC_QuickDERDecodeItem(pubk->arena, pubk, SECKEY_DHPublicKeyTemplate, &newDerKey);
- pubk->keyType = dhKey;
- break;
- default:
- rv = SECFailure;
- break;
- }
-
-finish:
- if (rv != SECSuccess) {
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_TRUE);
- }
- pubk = NULL;
- }
- return pubk;
-}
-
-SECKEYPrivateKeyList*
-SECKEY_NewPrivateKeyList(void)
-{
- PRArenaPool *arena = NULL;
- SECKEYPrivateKeyList *ret = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- ret = (SECKEYPrivateKeyList *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYPrivateKeyList));
- if ( ret == NULL ) {
- goto loser;
- }
-
- ret->arena = arena;
-
- PR_INIT_CLIST(&ret->list);
-
- return(ret);
-
-loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-void
-SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys)
-{
- while( !PR_CLIST_IS_EMPTY(&keys->list) ) {
- SECKEY_RemovePrivateKeyListNode(
- (SECKEYPrivateKeyListNode*)(PR_LIST_HEAD(&keys->list)) );
- }
-
- PORT_FreeArena(keys->arena, PR_FALSE);
-
- return;
-}
-
-
-void
-SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node)
-{
- PR_ASSERT(node->key);
- SECKEY_DestroyPrivateKey(node->key);
- node->key = NULL;
- PR_REMOVE_LINK(&node->links);
- return;
-
-}
-
-SECStatus
-SECKEY_AddPrivateKeyToListTail( SECKEYPrivateKeyList *list,
- SECKEYPrivateKey *key)
-{
- SECKEYPrivateKeyListNode *node;
-
- node = (SECKEYPrivateKeyListNode *)PORT_ArenaZAlloc(list->arena,
- sizeof(SECKEYPrivateKeyListNode));
- if ( node == NULL ) {
- goto loser;
- }
-
- PR_INSERT_BEFORE(&node->links, &list->list);
- node->key = key;
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-
-SECKEYPublicKeyList*
-SECKEY_NewPublicKeyList(void)
-{
- PRArenaPool *arena = NULL;
- SECKEYPublicKeyList *ret = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- ret = (SECKEYPublicKeyList *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYPublicKeyList));
- if ( ret == NULL ) {
- goto loser;
- }
-
- ret->arena = arena;
-
- PR_INIT_CLIST(&ret->list);
-
- return(ret);
-
-loser:
- if ( arena != NULL ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-void
-SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys)
-{
- while( !PR_CLIST_IS_EMPTY(&keys->list) ) {
- SECKEY_RemovePublicKeyListNode(
- (SECKEYPublicKeyListNode*)(PR_LIST_HEAD(&keys->list)) );
- }
-
- PORT_FreeArena(keys->arena, PR_FALSE);
-
- return;
-}
-
-
-void
-SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node)
-{
- PR_ASSERT(node->key);
- SECKEY_DestroyPublicKey(node->key);
- node->key = NULL;
- PR_REMOVE_LINK(&node->links);
- return;
-
-}
-
-SECStatus
-SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list,
- SECKEYPublicKey *key)
-{
- SECKEYPublicKeyListNode *node;
-
- node = (SECKEYPublicKeyListNode *)PORT_ArenaZAlloc(list->arena,
- sizeof(SECKEYPublicKeyListNode));
- if ( node == NULL ) {
- goto loser;
- }
-
- PR_INSERT_BEFORE(&node->links, &list->list);
- node->key = key;
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-#define SECKEY_CacheAttribute(key, attribute) \
- if (CK_TRUE == PK11_HasAttributeSet(key->pkcs11Slot, key->pkcs11ID, attribute, PR_FALSE)) { \
- key->staticflags |= SECKEY_##attribute; \
- } else { \
- key->staticflags &= (~SECKEY_##attribute); \
- }
-
-SECStatus
-SECKEY_CacheStaticFlags(SECKEYPrivateKey* key)
-{
- SECStatus rv = SECFailure;
- if (key && key->pkcs11Slot && key->pkcs11ID) {
- key->staticflags |= SECKEY_Attributes_Cached;
- SECKEY_CacheAttribute(key, CKA_PRIVATE);
- SECKEY_CacheAttribute(key, CKA_ALWAYS_AUTHENTICATE);
- rv = SECSuccess;
- }
- return rv;
-}
diff --git a/security/nss/lib/cryptohi/secsign.c b/security/nss/lib/cryptohi/secsign.c
deleted file mode 100644
index 25ace4d4d..000000000
--- a/security/nss/lib/cryptohi/secsign.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Signature stuff.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include "cryptohi.h"
-#include "sechash.h"
-#include "secder.h"
-#include "keyhi.h"
-#include "secoid.h"
-#include "secdig.h"
-#include "pk11func.h"
-#include "secerr.h"
-#include "keyi.h"
-
-struct SGNContextStr {
- SECOidTag signalg;
- SECOidTag hashalg;
- void *hashcx;
- const SECHashObject *hashobj;
- SECKEYPrivateKey *key;
-};
-
-SGNContext *
-SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key)
-{
- SGNContext *cx;
- SECOidTag hashalg, signalg;
- KeyType keyType;
- SECStatus rv;
-
- /* OK, map a PKCS #7 hash and encrypt algorithm into
- * a standard hashing algorithm. Why did we pass in the whole
- * PKCS #7 algTag if we were just going to change here you might
- * ask. Well the answer is for some cards we may have to do the
- * hashing on card. It may not support CKM_RSA_PKCS sign algorithm,
- * it may just support CKM_RSA_PKCS_WITH_SHA1 and/or CKM_RSA_PKCS_WITH_MD5.
- */
- /* we have a private key, not a public key, so don't pass it in */
- rv = sec_DecodeSigAlg(NULL, alg, NULL, &signalg, &hashalg);
- if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return 0;
- }
- keyType = seckey_GetKeyType(signalg);
-
- /* verify our key type */
- if (key->keyType != keyType &&
- !((key->keyType == dsaKey) && (keyType == fortezzaKey)) ) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return 0;
- }
-
-#ifndef NSS_ECC_MORE_THAN_SUITE_B
- if (key->keyType == ecKey) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return 0;
- }
-#endif
-
- cx = (SGNContext*) PORT_ZAlloc(sizeof(SGNContext));
- if (cx) {
- cx->hashalg = hashalg;
- cx->signalg = signalg;
- cx->key = key;
- }
- return cx;
-}
-
-void
-SGN_DestroyContext(SGNContext *cx, PRBool freeit)
-{
- if (cx) {
- if (cx->hashcx != NULL) {
- (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
- cx->hashcx = NULL;
- }
- if (freeit) {
- PORT_ZFree(cx, sizeof(SGNContext));
- }
- }
-}
-
-SECStatus
-SGN_Begin(SGNContext *cx)
-{
- if (cx->hashcx != NULL) {
- (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
- cx->hashcx = NULL;
- }
-
- cx->hashobj = HASH_GetHashObjectByOidTag(cx->hashalg);
- if (!cx->hashobj)
- return SECFailure; /* error code is already set */
-
- cx->hashcx = (*cx->hashobj->create)();
- if (cx->hashcx == NULL)
- return SECFailure;
-
- (*cx->hashobj->begin)(cx->hashcx);
- return SECSuccess;
-}
-
-SECStatus
-SGN_Update(SGNContext *cx, const unsigned char *input, unsigned int inputLen)
-{
- if (cx->hashcx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- (*cx->hashobj->update)(cx->hashcx, input, inputLen);
- return SECSuccess;
-}
-
-/* XXX Old template; want to expunge it eventually. */
-static DERTemplate SECAlgorithmIDTemplate[] = {
- { DER_SEQUENCE,
- 0, NULL, sizeof(SECAlgorithmID) },
- { DER_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
- { DER_OPTIONAL | DER_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
-};
-
-/*
- * XXX OLD Template. Once all uses have been switched over to new one,
- * remove this.
- */
-static DERTemplate SGNDigestInfoTemplate[] = {
- { DER_SEQUENCE,
- 0, NULL, sizeof(SGNDigestInfo) },
- { DER_INLINE,
- offsetof(SGNDigestInfo,digestAlgorithm),
- SECAlgorithmIDTemplate, },
- { DER_OCTET_STRING,
- offsetof(SGNDigestInfo,digest), },
- { 0, }
-};
-
-SECStatus
-SGN_End(SGNContext *cx, SECItem *result)
-{
- unsigned char digest[HASH_LENGTH_MAX];
- unsigned part1;
- int signatureLen;
- SECStatus rv;
- SECItem digder, sigitem;
- PRArenaPool *arena = 0;
- SECKEYPrivateKey *privKey = cx->key;
- SGNDigestInfo *di = 0;
-
- result->data = 0;
- digder.data = 0;
-
- /* Finish up digest function */
- if (cx->hashcx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- (*cx->hashobj->end)(cx->hashcx, digest, &part1, sizeof(digest));
-
-
- if (privKey->keyType == rsaKey) {
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- rv = SECFailure;
- goto loser;
- }
-
- /* Construct digest info */
- di = SGN_CreateDigestInfo(cx->hashalg, digest, part1);
- if (!di) {
- rv = SECFailure;
- goto loser;
- }
-
- /* Der encode the digest as a DigestInfo */
- rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate,
- di);
- if (rv != SECSuccess) {
- goto loser;
- }
- } else {
- digder.data = digest;
- digder.len = part1;
- }
-
- /*
- ** Encrypt signature after constructing appropriate PKCS#1 signature
- ** block
- */
- signatureLen = PK11_SignatureLen(privKey);
- if (signatureLen <= 0) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- rv = SECFailure;
- goto loser;
- }
- sigitem.len = signatureLen;
- sigitem.data = (unsigned char*) PORT_Alloc(signatureLen);
-
- if (sigitem.data == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = PK11_Sign(privKey, &sigitem, &digder);
- if (rv != SECSuccess) {
- PORT_Free(sigitem.data);
- sigitem.data = NULL;
- goto loser;
- }
-
- if ((cx->signalg == SEC_OID_ANSIX9_DSA_SIGNATURE) ||
- (cx->signalg == SEC_OID_ANSIX962_EC_PUBLIC_KEY)) {
- /* DSAU_EncodeDerSigWithLen works for DSA and ECDSA */
- rv = DSAU_EncodeDerSigWithLen(result, &sigitem, sigitem.len);
- PORT_Free(sigitem.data);
- if (rv != SECSuccess)
- goto loser;
- } else {
- result->len = sigitem.len;
- result->data = sigitem.data;
- }
-
- loser:
- SGN_DestroyDigestInfo(di);
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return rv;
-}
-
-/************************************************************************/
-
-/*
-** Sign a block of data returning in result a bunch of bytes that are the
-** signature. Returns zero on success, an error code on failure.
-*/
-SECStatus
-SEC_SignData(SECItem *res, const unsigned char *buf, int len,
- SECKEYPrivateKey *pk, SECOidTag algid)
-{
- SECStatus rv;
- SGNContext *sgn;
-
-
- sgn = SGN_NewContext(algid, pk);
-
- if (sgn == NULL)
- return SECFailure;
-
- rv = SGN_Begin(sgn);
- if (rv != SECSuccess)
- goto loser;
-
- rv = SGN_Update(sgn, buf, len);
- if (rv != SECSuccess)
- goto loser;
-
- rv = SGN_End(sgn, res);
-
- loser:
- SGN_DestroyContext(sgn, PR_TRUE);
- return rv;
-}
-
-/************************************************************************/
-
-DERTemplate CERTSignedDataTemplate[] =
-{
- { DER_SEQUENCE,
- 0, NULL, sizeof(CERTSignedData) },
- { DER_ANY,
- offsetof(CERTSignedData,data), },
- { DER_INLINE,
- offsetof(CERTSignedData,signatureAlgorithm),
- SECAlgorithmIDTemplate, },
- { DER_BIT_STRING,
- offsetof(CERTSignedData,signature), },
- { 0, }
-};
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-const SEC_ASN1Template CERT_SignedDataTemplate[] =
-{
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTSignedData) },
- { SEC_ASN1_ANY,
- offsetof(CERTSignedData,data), },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(CERTSignedData,signatureAlgorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate), },
- { SEC_ASN1_BIT_STRING,
- offsetof(CERTSignedData,signature), },
- { 0, }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SignedDataTemplate)
-
-
-SECStatus
-SEC_DerSignData(PRArenaPool *arena, SECItem *result,
- const unsigned char *buf, int len, SECKEYPrivateKey *pk,
- SECOidTag algID)
-{
- SECItem it;
- CERTSignedData sd;
- SECStatus rv;
-
- it.data = 0;
-
- /* XXX We should probably have some asserts here to make sure the key type
- * and algID match
- */
-
- if (algID == SEC_OID_UNKNOWN) {
- switch(pk->keyType) {
- case rsaKey:
- algID = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
- break;
- case dsaKey:
- /* get Signature length (= q_len*2) and work from there */
- switch (PK11_SignatureLen(pk)) {
- case 448:
- algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST;
- break;
- case 512:
- algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST;
- break;
- default:
- algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
- break;
- }
- break;
- case ecKey:
- algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return SECFailure;
- }
- }
-
- /* Sign input buffer */
- rv = SEC_SignData(&it, buf, len, pk, algID);
- if (rv) goto loser;
-
- /* Fill out SignedData object */
- PORT_Memset(&sd, 0, sizeof(sd));
- sd.data.data = (unsigned char*) buf;
- sd.data.len = len;
- sd.signature.data = it.data;
- sd.signature.len = it.len << 3; /* convert to bit string */
- rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0);
- if (rv) goto loser;
-
- /* DER encode the signed data object */
- rv = DER_Encode(arena, result, CERTSignedDataTemplate, &sd);
- /* FALL THROUGH */
-
- loser:
- PORT_Free(it.data);
- return rv;
-}
-
-SECStatus
-SGN_Digest(SECKEYPrivateKey *privKey,
- SECOidTag algtag, SECItem *result, SECItem *digest)
-{
- int modulusLen;
- SECStatus rv;
- SECItem digder;
- PRArenaPool *arena = 0;
- SGNDigestInfo *di = 0;
-
-
- result->data = 0;
-
- if (privKey->keyType == rsaKey) {
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- rv = SECFailure;
- goto loser;
- }
-
- /* Construct digest info */
- di = SGN_CreateDigestInfo(algtag, digest->data, digest->len);
- if (!di) {
- rv = SECFailure;
- goto loser;
- }
-
- /* Der encode the digest as a DigestInfo */
- rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate,
- di);
- if (rv != SECSuccess) {
- goto loser;
- }
- } else {
- digder.data = digest->data;
- digder.len = digest->len;
- }
-
- /*
- ** Encrypt signature after constructing appropriate PKCS#1 signature
- ** block
- */
- modulusLen = PK11_SignatureLen(privKey);
- if (modulusLen <= 0) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- rv = SECFailure;
- goto loser;
- }
- result->len = modulusLen;
- result->data = (unsigned char*) PORT_Alloc(modulusLen);
-
- if (result->data == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = PK11_Sign(privKey, result, &digder);
- if (rv != SECSuccess) {
- PORT_Free(result->data);
- result->data = NULL;
- }
-
- loser:
- SGN_DestroyDigestInfo(di);
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return rv;
-}
-
-SECOidTag
-SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag)
-{
- SECOidTag sigTag = SEC_OID_UNKNOWN;
-
- switch (keyType) {
- case rsaKey:
- switch (hashAlgTag) {
- case SEC_OID_MD2:
- sigTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; break;
- case SEC_OID_MD5:
- sigTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; break;
- case SEC_OID_UNKNOWN: /* default for RSA if not specified */
- case SEC_OID_SHA1:
- sigTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; break;
- case SEC_OID_SHA224:
- sigTag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION; break;
- case SEC_OID_SHA256:
- sigTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; break;
- case SEC_OID_SHA384:
- sigTag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; break;
- case SEC_OID_SHA512:
- sigTag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; break;
- default:
- break;
- }
- break;
- case dsaKey:
- switch (hashAlgTag) {
- case SEC_OID_UNKNOWN: /* default for DSA if not specified */
- case SEC_OID_SHA1:
- sigTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break;
- case SEC_OID_SHA224:
- sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; break;
- case SEC_OID_SHA256:
- sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; break;
- default:
- break;
- }
- break;
- case ecKey:
- switch (hashAlgTag) {
- case SEC_OID_UNKNOWN: /* default for ECDSA if not specified */
- case SEC_OID_SHA1:
- sigTag = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break;
- case SEC_OID_SHA224:
- sigTag = SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE; break;
- case SEC_OID_SHA256:
- sigTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; break;
- case SEC_OID_SHA384:
- sigTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; break;
- case SEC_OID_SHA512:
- sigTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; break;
- default:
- break;
- }
- default:
- break;
- }
- return sigTag;
-}
diff --git a/security/nss/lib/cryptohi/secvfy.c b/security/nss/lib/cryptohi/secvfy.c
deleted file mode 100644
index 97c7bafbe..000000000
--- a/security/nss/lib/cryptohi/secvfy.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- * Verification stuff.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include "cryptohi.h"
-#include "sechash.h"
-#include "keyhi.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "secdig.h"
-#include "secerr.h"
-#include "keyi.h"
-
-/*
-** Decrypt signature block using public key
-** Store the hash algorithm oid tag in *tagp
-** Store the digest in the digest buffer
-** Store the digest length in *digestlen
-** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION
-*/
-static SECStatus
-DecryptSigBlock(SECOidTag *tagp, unsigned char *digest,
- unsigned int *digestlen, unsigned int maxdigestlen,
- SECKEYPublicKey *key, const SECItem *sig, char *wincx)
-{
- SGNDigestInfo *di = NULL;
- unsigned char *buf = NULL;
- SECStatus rv;
- SECOidTag tag;
- SECItem it;
-
- if (key == NULL) goto loser;
-
- it.len = SECKEY_PublicKeyStrength(key);
- if (!it.len) goto loser;
- it.data = buf = (unsigned char *)PORT_Alloc(it.len);
- if (!buf) goto loser;
-
- /* decrypt the block */
- rv = PK11_VerifyRecover(key, (SECItem *)sig, &it, wincx);
- if (rv != SECSuccess) goto loser;
-
- di = SGN_DecodeDigestInfo(&it);
- if (di == NULL) goto sigloser;
-
- /*
- ** Finally we have the digest info; now we can extract the algorithm
- ** ID and the signature block
- */
- tag = SECOID_GetAlgorithmTag(&di->digestAlgorithm);
- /* Check that tag is an appropriate algorithm */
- if (tag == SEC_OID_UNKNOWN) {
- goto sigloser;
- }
- /* make sure the "parameters" are not too bogus. */
- if (di->digestAlgorithm.parameters.len > 2) {
- goto sigloser;
- }
- if (di->digest.len > maxdigestlen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- goto loser;
- }
- PORT_Memcpy(digest, di->digest.data, di->digest.len);
- *tagp = tag;
- *digestlen = di->digest.len;
- goto done;
-
- sigloser:
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
-
- loser:
- rv = SECFailure;
-
- done:
- if (di != NULL) SGN_DestroyDigestInfo(di);
- if (buf != NULL) PORT_Free(buf);
-
- return rv;
-}
-
-
-struct VFYContextStr {
- SECOidTag hashAlg; /* the hash algorithm */
- SECKEYPublicKey *key;
- /*
- * This buffer holds either the digest or the full signature
- * depending on the type of the signature (key->keyType). It is
- * defined as a union to make sure it always has enough space.
- *
- * Use the "buffer" union member to reference the buffer.
- * Note: do not take the size of the "buffer" union member. Take
- * the size of the union or some other union member instead.
- */
- union {
- unsigned char buffer[1];
-
- /* the digest in the decrypted RSA signature */
- unsigned char rsadigest[HASH_LENGTH_MAX];
- /* the full DSA signature... 40 bytes */
- unsigned char dsasig[DSA_MAX_SIGNATURE_LEN];
- /* the full ECDSA signature */
- unsigned char ecdsasig[2 * MAX_ECKEY_LEN];
- } u;
- unsigned int rsadigestlen;
- void * wincx;
- void *hashcx;
- const SECHashObject *hashobj;
- SECOidTag encAlg; /* enc alg */
- PRBool hasSignature; /* true if the signature was provided in the
- * VFY_CreateContext call. If false, the
- * signature must be provided with a
- * VFY_EndWithSignature call. */
-};
-
-/*
- * decode the ECDSA or DSA signature from it's DER wrapping.
- * The unwrapped/raw signature is placed in the buffer pointed
- * to by dsig and has enough room for len bytes.
- */
-static SECStatus
-decodeECorDSASignature(SECOidTag algid, const SECItem *sig, unsigned char *dsig,
- unsigned int len) {
- SECItem *dsasig = NULL; /* also used for ECDSA */
- SECStatus rv=SECSuccess;
-
- if ((algid != SEC_OID_ANSIX9_DSA_SIGNATURE) &&
- (algid != SEC_OID_ANSIX962_EC_PUBLIC_KEY) ) {
- if (sig->len != len) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECFailure;
- }
-
- PORT_Memcpy(dsig, sig->data, sig->len);
- return SECSuccess;
- }
-
- if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
- if (len > MAX_ECKEY_LEN * 2) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECFailure;
- }
- }
- dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len);
-
- if ((dsasig == NULL) || (dsasig->len != len)) {
- rv = SECFailure;
- } else {
- PORT_Memcpy(dsig, dsasig->data, dsasig->len);
- }
-
- if (dsasig != NULL) SECITEM_FreeItem(dsasig, PR_TRUE);
- if (rv == SECFailure) PORT_SetError(SEC_ERROR_BAD_DER);
- return rv;
-}
-
-const SEC_ASN1Template hashParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) },
- { SEC_ASN1_OBJECT_ID, 0 },
- { SEC_ASN1_SKIP_REST },
- { 0, }
-};
-
-/*
- * Pulls the hash algorithm, signing algorithm, and key type out of a
- * composite algorithm.
- *
- * sigAlg: the composite algorithm to dissect.
- * hashalg: address of a SECOidTag which will be set with the hash algorithm.
- * encalg: address of a SECOidTag which will be set with the signing alg.
- *
- * Returns: SECSuccess if the algorithm was acceptable, SECFailure if the
- * algorithm was not found or was not a signing algorithm.
- */
-SECStatus
-sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg,
- const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg)
-{
- int len;
- PRArenaPool *arena;
- SECStatus rv;
- SECItem oid;
-
- PR_ASSERT(hashalg!=NULL);
- PR_ASSERT(encalg!=NULL);
-
- switch (sigAlg) {
- /* We probably shouldn't be generating MD2 signatures either */
- case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
- *hashalg = SEC_OID_MD2;
- break;
- case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
- *hashalg = SEC_OID_MD5;
- break;
- case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
- case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
- case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
- *hashalg = SEC_OID_SHA1;
- break;
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
- *hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */
- break;
-
- case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
- case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
- case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
- *hashalg = SEC_OID_SHA224;
- break;
- case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
- case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
- case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
- *hashalg = SEC_OID_SHA256;
- break;
- case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
- case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
- *hashalg = SEC_OID_SHA384;
- break;
- case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
- case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
- *hashalg = SEC_OID_SHA512;
- break;
-
- /* what about normal DSA? */
- case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
- case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
- case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
- *hashalg = SEC_OID_SHA1;
- break;
- case SEC_OID_MISSI_DSS:
- case SEC_OID_MISSI_KEA_DSS:
- case SEC_OID_MISSI_KEA_DSS_OLD:
- case SEC_OID_MISSI_DSS_OLD:
- *hashalg = SEC_OID_SHA1;
- break;
- case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
- /* This is an EC algorithm. Recommended means the largest
- * hash algorithm that is not reduced by the keysize of
- * the EC algorithm. Note that key strength is in bytes and
- * algorithms are specified in bits. Never use an algorithm
- * weaker than sha1. */
- len = SECKEY_PublicKeyStrength(key);
- if (len < 28) { /* 28 bytes == 224 bits */
- *hashalg = SEC_OID_SHA1;
- } else if (len < 32) { /* 32 bytes == 256 bits */
- *hashalg = SEC_OID_SHA224;
- } else if (len < 48) { /* 48 bytes == 384 bits */
- *hashalg = SEC_OID_SHA256;
- } else if (len < 64) { /* 48 bytes == 512 bits */
- *hashalg = SEC_OID_SHA384;
- } else {
- /* use the largest in this case */
- *hashalg = SEC_OID_SHA512;
- }
- break;
- case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
- if (param == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return SECFailure;
- }
- rv = SEC_QuickDERDecodeItem(arena, &oid, hashParameterTemplate, param);
- if (rv == SECSuccess) {
- *hashalg = SECOID_FindOIDTag(&oid);
- }
- PORT_FreeArena(arena, PR_FALSE);
- if (rv != SECSuccess) {
- return rv;
- }
- /* only accept hash algorithms */
- if (HASH_GetHashTypeByOidTag(*hashalg) == HASH_AlgNULL) {
- /* error set by HASH_GetHashTypeByOidTag */
- return SECFailure;
- }
- break;
- /* we don't implement MD4 hashes */
- case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
- default:
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
- /* get the "encryption" algorithm */
- switch (sigAlg) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
- case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
- case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
- case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
- *encalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
- break;
- case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
- *encalg = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
- break;
-
- /* what about normal DSA? */
- case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
- case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
- case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST:
- case SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST:
- *encalg = SEC_OID_ANSIX9_DSA_SIGNATURE;
- break;
- case SEC_OID_MISSI_DSS:
- case SEC_OID_MISSI_KEA_DSS:
- case SEC_OID_MISSI_KEA_DSS_OLD:
- case SEC_OID_MISSI_DSS_OLD:
- *encalg = SEC_OID_MISSI_DSS;
- break;
- case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
- case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
- *encalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
- break;
- /* we don't implement MD4 hashes */
- case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
- default:
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * we can verify signatures that come from 2 different sources:
- * one in with the signature contains a signature oid, and the other
- * in which the signature is managed by a Public key (encAlg) oid
- * and a hash oid. The latter is the more basic, so that's what
- * our base vfyCreate function takes.
- *
- * There is one noteworthy corner case, if we are using an RSA key, and the
- * signature block is provided, then the hashAlg can be specified as
- * SEC_OID_UNKNOWN. In this case, verify will use the hash oid supplied
- * in the RSA signature block.
- */
-static VFYContext *
-vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig,
- SECOidTag encAlg, SECOidTag hashAlg, SECOidTag *hash, void *wincx)
-{
- VFYContext *cx;
- SECStatus rv;
- unsigned int sigLen;
- KeyType type;
-
- /* make sure the encryption algorithm matches the key type */
- /* RSA-PSS algorithm can be used with both rsaKey and rsaPssKey */
- type = seckey_GetKeyType(encAlg);
- if ((key->keyType != type) &&
- ((key->keyType != rsaKey) || (type != rsaPssKey))) {
- PORT_SetError(SEC_ERROR_PKCS7_KEYALG_MISMATCH);
- return NULL;
- }
-
- cx = (VFYContext*) PORT_ZAlloc(sizeof(VFYContext));
- if (cx == NULL) {
- goto loser;
- }
-
- cx->wincx = wincx;
- cx->hasSignature = (sig != NULL);
- cx->encAlg = encAlg;
- cx->hashAlg = hashAlg;
- cx->key = SECKEY_CopyPublicKey(key);
- rv = SECSuccess;
- if (sig) {
- switch (type) {
- case rsaKey:
- rv = DecryptSigBlock(&cx->hashAlg, cx->u.buffer, &cx->rsadigestlen,
- HASH_LENGTH_MAX, cx->key, sig, (char*)wincx);
- if (cx->hashAlg != hashAlg && hashAlg != SEC_OID_UNKNOWN) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- rv = SECFailure;
- }
- break;
- case dsaKey:
- case ecKey:
- sigLen = SECKEY_SignatureLen(key);
- if (sigLen == 0) {
- /* error set by SECKEY_SignatureLen */
- rv = SECFailure;
- break;
- }
- rv = decodeECorDSASignature(encAlg, sig, cx->u.buffer, sigLen);
- break;
- default:
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- break;
- }
- }
-
- if (rv) goto loser;
-
- /* check hash alg again, RSA may have changed it.*/
- if (HASH_GetHashTypeByOidTag(cx->hashAlg) == HASH_AlgNULL) {
- /* error set by HASH_GetHashTypeByOidTag */
- goto loser;
- }
-
- if (hash) {
- *hash = cx->hashAlg;
- }
- return cx;
-
- loser:
- if (cx) {
- VFY_DestroyContext(cx, PR_TRUE);
- }
- return 0;
-}
-
-VFYContext *
-VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag sigAlg,
- void *wincx)
-{
- SECOidTag encAlg, hashAlg;
- SECStatus rv = sec_DecodeSigAlg(key, sigAlg, NULL, &encAlg, &hashAlg);
- if (rv != SECSuccess) {
- return NULL;
- }
- return vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx);
-}
-
-VFYContext *
-VFY_CreateContextDirect(const SECKEYPublicKey *key, const SECItem *sig,
- SECOidTag encAlg, SECOidTag hashAlg,
- SECOidTag *hash, void *wincx)
-{
- return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
-}
-
-VFYContext *
-VFY_CreateContextWithAlgorithmID(const SECKEYPublicKey *key, const SECItem *sig,
- const SECAlgorithmID *sigAlgorithm, SECOidTag *hash, void *wincx)
-{
- SECOidTag encAlg, hashAlg;
- SECStatus rv = sec_DecodeSigAlg(key,
- SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm),
- &sigAlgorithm->parameters, &encAlg, &hashAlg);
- if (rv != SECSuccess) {
- return NULL;
- }
- return vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
-}
-
-void
-VFY_DestroyContext(VFYContext *cx, PRBool freeit)
-{
- if (cx) {
- if (cx->hashcx != NULL) {
- (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
- cx->hashcx = NULL;
- }
- if (cx->key) {
- SECKEY_DestroyPublicKey(cx->key);
- }
- if (freeit) {
- PORT_ZFree(cx, sizeof(VFYContext));
- }
- }
-}
-
-SECStatus
-VFY_Begin(VFYContext *cx)
-{
- if (cx->hashcx != NULL) {
- (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
- cx->hashcx = NULL;
- }
-
- cx->hashobj = HASH_GetHashObjectByOidTag(cx->hashAlg);
- if (!cx->hashobj)
- return SECFailure; /* error code is set */
-
- cx->hashcx = (*cx->hashobj->create)();
- if (cx->hashcx == NULL)
- return SECFailure;
-
- (*cx->hashobj->begin)(cx->hashcx);
- return SECSuccess;
-}
-
-SECStatus
-VFY_Update(VFYContext *cx, const unsigned char *input, unsigned inputLen)
-{
- if (cx->hashcx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- (*cx->hashobj->update)(cx->hashcx, input, inputLen);
- return SECSuccess;
-}
-
-SECStatus
-VFY_EndWithSignature(VFYContext *cx, SECItem *sig)
-{
- unsigned char final[HASH_LENGTH_MAX];
- unsigned part;
- SECItem hash,dsasig; /* dsasig is also used for ECDSA */
- SECStatus rv;
-
- if ((cx->hasSignature == PR_FALSE) && (sig == NULL)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (cx->hashcx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- (*cx->hashobj->end)(cx->hashcx, final, &part, sizeof(final));
- switch (cx->key->keyType) {
- case ecKey:
- case dsaKey:
- dsasig.data = cx->u.buffer;
- dsasig.len = SECKEY_SignatureLen(cx->key);
- if (dsasig.len == 0) {
- return SECFailure;
- }
- if (sig) {
- rv = decodeECorDSASignature(cx->encAlg, sig, dsasig.data,
- dsasig.len);
- if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
- }
- hash.data = final;
- hash.len = part;
- if (PK11_Verify(cx->key,&dsasig,&hash,cx->wincx) != SECSuccess) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
- break;
- case rsaKey:
- if (sig) {
- SECOidTag hashid = SEC_OID_UNKNOWN;
- rv = DecryptSigBlock(&hashid, cx->u.buffer, &cx->rsadigestlen,
- HASH_LENGTH_MAX, cx->key, sig, (char*)cx->wincx);
- if ((rv != SECSuccess) || (hashid != cx->hashAlg)) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
- }
- if ((part != cx->rsadigestlen) ||
- PORT_Memcmp(final, cx->u.buffer, part)) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
- break;
- default:
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure; /* shouldn't happen */
- }
- return SECSuccess;
-}
-
-SECStatus
-VFY_End(VFYContext *cx)
-{
- return VFY_EndWithSignature(cx,NULL);
-}
-
-/************************************************************************/
-/*
- * Verify that a previously-computed digest matches a signature.
- */
-static SECStatus
-vfy_VerifyDigest(const SECItem *digest, const SECKEYPublicKey *key,
- const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg,
- void *wincx)
-{
- SECStatus rv;
- VFYContext *cx;
- SECItem dsasig; /* also used for ECDSA */
-
- rv = SECFailure;
-
- cx = vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx);
- if (cx != NULL) {
- switch (key->keyType) {
- case rsaKey:
- if ((digest->len != cx->rsadigestlen) ||
- PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- } else {
- rv = SECSuccess;
- }
- break;
- case dsaKey:
- case ecKey:
- dsasig.data = cx->u.buffer;
- dsasig.len = SECKEY_SignatureLen(cx->key);
- if (dsasig.len == 0) {
- break;
- }
- if (PK11_Verify(cx->key, &dsasig, (SECItem *)digest, cx->wincx)
- != SECSuccess) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- } else {
- rv = SECSuccess;
- }
- break;
- default:
- break;
- }
- VFY_DestroyContext(cx, PR_TRUE);
- }
- return rv;
-}
-
-SECStatus
-VFY_VerifyDigestDirect(const SECItem *digest, const SECKEYPublicKey *key,
- const SECItem *sig, SECOidTag encAlg,
- SECOidTag hashAlg, void *wincx)
-{
- return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx);
-}
-
-SECStatus
-VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig,
- SECOidTag algid, void *wincx)
-{
- SECOidTag encAlg, hashAlg;
- SECStatus rv = sec_DecodeSigAlg(key, algid, NULL, &encAlg, &hashAlg);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx);
-}
-
-/*
- * this function takes an optional hash oid, which the digest function
- * will be compared with our target hash value.
- */
-SECStatus
-VFY_VerifyDigestWithAlgorithmID(const SECItem *digest,
- const SECKEYPublicKey *key, const SECItem *sig,
- const SECAlgorithmID *sigAlgorithm,
- SECOidTag hashCmp, void *wincx)
-{
- SECOidTag encAlg, hashAlg;
- SECStatus rv = sec_DecodeSigAlg(key,
- SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm),
- &sigAlgorithm->parameters, &encAlg, &hashAlg);
- if (rv != SECSuccess) {
- return rv;
- }
- if ( hashCmp != SEC_OID_UNKNOWN &&
- hashAlg != SEC_OID_UNKNOWN &&
- hashCmp != hashAlg) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
- return vfy_VerifyDigest(digest, key, sig, encAlg, hashAlg, wincx);
-}
-
-static SECStatus
-vfy_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key,
- const SECItem *sig, SECOidTag encAlg, SECOidTag hashAlg,
- SECOidTag *hash, void *wincx)
-{
- SECStatus rv;
- VFYContext *cx;
-
- cx = vfy_CreateContext(key, sig, encAlg, hashAlg, hash, wincx);
- if (cx == NULL)
- return SECFailure;
-
- rv = VFY_Begin(cx);
- if (rv == SECSuccess) {
- rv = VFY_Update(cx, (unsigned char *)buf, len);
- if (rv == SECSuccess)
- rv = VFY_End(cx);
- }
-
- VFY_DestroyContext(cx, PR_TRUE);
- return rv;
-}
-
-SECStatus
-VFY_VerifyDataDirect(const unsigned char *buf, int len,
- const SECKEYPublicKey *key, const SECItem *sig,
- SECOidTag encAlg, SECOidTag hashAlg,
- SECOidTag *hash, void *wincx)
-{
- return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx);
-}
-
-SECStatus
-VFY_VerifyData(const unsigned char *buf, int len, const SECKEYPublicKey *key,
- const SECItem *sig, SECOidTag algid, void *wincx)
-{
- SECOidTag encAlg, hashAlg;
- SECStatus rv = sec_DecodeSigAlg(key, algid, NULL, &encAlg, &hashAlg);
- if (rv != SECSuccess) {
- return rv;
- }
- return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, NULL, wincx);
-}
-
-SECStatus
-VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, int len,
- const SECKEYPublicKey *key,
- const SECItem *sig,
- const SECAlgorithmID *sigAlgorithm,
- SECOidTag *hash, void *wincx)
-{
- SECOidTag encAlg, hashAlg;
- SECOidTag sigAlg = SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm);
- SECStatus rv = sec_DecodeSigAlg(key, sigAlg,
- &sigAlgorithm->parameters, &encAlg, &hashAlg);
- if (rv != SECSuccess) {
- return rv;
- }
- return vfy_VerifyData(buf, len, key, sig, encAlg, hashAlg, hash, wincx);
-}
diff --git a/security/nss/lib/dev/Makefile b/security/nss/lib/dev/Makefile
deleted file mode 100644
index f7f3255ae..000000000
--- a/security/nss/lib/dev/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-include manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-# On AIX 4.3, IBM xlC_r compiler (version 3.6.6) cannot compile
-# ckhelper.c in 64-bit mode for unknown reasons. A workaround is
-# to compile it with optimizations turned on. (Bugzilla bug #63815)
-ifeq ($(OS_TARGET)$(OS_RELEASE),AIX4.3)
-ifeq ($(USE_64),1)
-ifndef BUILD_OPT
-$(OBJDIR)/ckhelper.o: ckhelper.c
- @$(MAKE_OBJDIR)
- $(CC) -o $@ -c -O2 $(CFLAGS) $<
-endif
-endif
-endif
-
-export:: private_export
diff --git a/security/nss/lib/dev/ckhelper.c b/security/nss/lib/dev/ckhelper.c
deleted file mode 100644
index 8129b8f78..000000000
--- a/security/nss/lib/dev/ckhelper.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "pkcs11.h"
-
-#ifndef DEVM_H
-#include "devm.h"
-#endif /* DEVM_H */
-
-#ifndef CKHELPER_H
-#include "ckhelper.h"
-#endif /* CKHELPER_H */
-
-extern const NSSError NSS_ERROR_DEVICE_ERROR;
-
-static const CK_BBOOL s_true = CK_TRUE;
-NSS_IMPLEMENT_DATA const NSSItem
-g_ck_true = { (CK_VOID_PTR)&s_true, sizeof(s_true) };
-
-static const CK_BBOOL s_false = CK_FALSE;
-NSS_IMPLEMENT_DATA const NSSItem
-g_ck_false = { (CK_VOID_PTR)&s_false, sizeof(s_false) };
-
-static const CK_OBJECT_CLASS s_class_cert = CKO_CERTIFICATE;
-NSS_IMPLEMENT_DATA const NSSItem
-g_ck_class_cert = { (CK_VOID_PTR)&s_class_cert, sizeof(s_class_cert) };
-
-static const CK_OBJECT_CLASS s_class_pubkey = CKO_PUBLIC_KEY;
-NSS_IMPLEMENT_DATA const NSSItem
-g_ck_class_pubkey = { (CK_VOID_PTR)&s_class_pubkey, sizeof(s_class_pubkey) };
-
-static const CK_OBJECT_CLASS s_class_privkey = CKO_PRIVATE_KEY;
-NSS_IMPLEMENT_DATA const NSSItem
-g_ck_class_privkey = { (CK_VOID_PTR)&s_class_privkey, sizeof(s_class_privkey) };
-
-static PRBool
-is_string_attribute (
- CK_ATTRIBUTE_TYPE aType
-)
-{
- PRBool isString;
- switch (aType) {
- case CKA_LABEL:
- case CKA_NSS_EMAIL:
- isString = PR_TRUE;
- break;
- default:
- isString = PR_FALSE;
- break;
- }
- return isString;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCKObject_GetAttributes (
- CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_PTR obj_template,
- CK_ULONG count,
- NSSArena *arenaOpt,
- nssSession *session,
- NSSSlot *slot
-)
-{
- nssArenaMark *mark = NULL;
- CK_SESSION_HANDLE hSession;
- CK_ULONG i = 0;
- CK_RV ckrv;
- PRStatus nssrv;
- PRBool alloced = PR_FALSE;
- void *epv = nssSlot_GetCryptokiEPV(slot);
- hSession = session->handle;
- if (arenaOpt) {
- mark = nssArena_Mark(arenaOpt);
- if (!mark) {
- goto loser;
- }
- }
- nssSession_EnterMonitor(session);
- /* XXX kinda hacky, if the storage size is already in the first template
- * item, then skip the alloc portion
- */
- if (obj_template[0].ulValueLen == 0) {
- /* Get the storage size needed for each attribute */
- ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
- object, obj_template, count);
- if (ckrv != CKR_OK &&
- ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
- ckrv != CKR_ATTRIBUTE_SENSITIVE)
- {
- nssSession_ExitMonitor(session);
- nss_SetError(NSS_ERROR_DEVICE_ERROR);
- goto loser;
- }
- /* Allocate memory for each attribute. */
- for (i=0; i<count; i++) {
- CK_ULONG ulValueLen = obj_template[i].ulValueLen;
- if (ulValueLen == 0 || ulValueLen == (CK_ULONG) -1) {
- obj_template[i].pValue = NULL;
- obj_template[i].ulValueLen = 0;
- continue;
- }
- if (is_string_attribute(obj_template[i].type)) {
- ulValueLen++;
- }
- obj_template[i].pValue = nss_ZAlloc(arenaOpt, ulValueLen);
- if (!obj_template[i].pValue) {
- nssSession_ExitMonitor(session);
- goto loser;
- }
- }
- alloced = PR_TRUE;
- }
- /* Obtain the actual attribute values. */
- ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
- object, obj_template, count);
- nssSession_ExitMonitor(session);
- if (ckrv != CKR_OK &&
- ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
- ckrv != CKR_ATTRIBUTE_SENSITIVE)
- {
- nss_SetError(NSS_ERROR_DEVICE_ERROR);
- goto loser;
- }
- if (alloced && arenaOpt) {
- nssrv = nssArena_Unmark(arenaOpt, mark);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
- }
-
- if (count > 1 && ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) ||
- (ckrv == CKR_ATTRIBUTE_SENSITIVE))) {
- /* old tokens would keep the length of '0' and not deal with any
- * of the attributes we passed. For those tokens read them one at
- * a time */
- for (i=0; i < count; i++) {
- if ((obj_template[i].ulValueLen == 0)
- || (obj_template[i].ulValueLen == -1)) {
- obj_template[i].ulValueLen=0;
- (void) nssCKObject_GetAttributes(object,&obj_template[i], 1,
- arenaOpt, session, slot);
- }
- }
- }
- return PR_SUCCESS;
-loser:
- if (alloced) {
- if (arenaOpt) {
- /* release all arena memory allocated before the failure. */
- (void)nssArena_Release(arenaOpt, mark);
- } else {
- CK_ULONG j;
- /* free each heap object that was allocated before the failure. */
- for (j=0; j<i; j++) {
- nss_ZFreeIf(obj_template[j].pValue);
- }
- }
- }
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCKObject_GetAttributeItem (
- CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_TYPE attribute,
- NSSArena *arenaOpt,
- nssSession *session,
- NSSSlot *slot,
- NSSItem *rvItem
-)
-{
- CK_ATTRIBUTE attr = { 0, NULL, 0 };
- PRStatus nssrv;
- attr.type = attribute;
- nssrv = nssCKObject_GetAttributes(object, &attr, 1,
- arenaOpt, session, slot);
- if (nssrv != PR_SUCCESS) {
- return nssrv;
- }
- rvItem->data = (void *)attr.pValue;
- rvItem->size = (PRUint32)attr.ulValueLen;
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRBool
-nssCKObject_IsAttributeTrue (
- CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_TYPE attribute,
- nssSession *session,
- NSSSlot *slot,
- PRStatus *rvStatus
-)
-{
- CK_BBOOL bool;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE atemplate = { 0, NULL, 0 };
- CK_RV ckrv;
- void *epv = nssSlot_GetCryptokiEPV(slot);
- attr = &atemplate;
- NSS_CK_SET_ATTRIBUTE_VAR(attr, attribute, bool);
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_GetAttributeValue(session->handle, object,
- &atemplate, 1);
- nssSession_ExitMonitor(session);
- if (ckrv != CKR_OK) {
- *rvStatus = PR_FAILURE;
- return PR_FALSE;
- }
- *rvStatus = PR_SUCCESS;
- return (PRBool)(bool == CK_TRUE);
-}
-
-NSS_IMPLEMENT PRStatus
-nssCKObject_SetAttributes (
- CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_PTR obj_template,
- CK_ULONG count,
- nssSession *session,
- NSSSlot *slot
-)
-{
- CK_RV ckrv;
- void *epv = nssSlot_GetCryptokiEPV(slot);
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, object,
- obj_template, count);
- nssSession_ExitMonitor(session);
- if (ckrv == CKR_OK) {
- return PR_SUCCESS;
- } else {
- return PR_FAILURE;
- }
-}
-
-NSS_IMPLEMENT PRBool
-nssCKObject_IsTokenObjectTemplate (
- CK_ATTRIBUTE_PTR objectTemplate,
- CK_ULONG otsize
-)
-{
- CK_ULONG ul;
- for (ul=0; ul<otsize; ul++) {
- if (objectTemplate[ul].type == CKA_TOKEN) {
- return (*((CK_BBOOL*)objectTemplate[ul].pValue) == CK_TRUE);
- }
- }
- return PR_FALSE;
-}
-
-static NSSCertificateType
-nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
-{
- CK_CERTIFICATE_TYPE ckCertType;
- if (!attrib->pValue) {
- /* default to PKIX */
- return NSSCertificateType_PKIX;
- }
- ckCertType = *((CK_ULONG *)attrib->pValue);
- switch (ckCertType) {
- case CKC_X_509:
- return NSSCertificateType_PKIX;
- default:
- break;
- }
- return NSSCertificateType_Unknown;
-}
-
-/* incoming pointers must be valid */
-NSS_IMPLEMENT PRStatus
-nssCryptokiCertificate_GetAttributes (
- nssCryptokiObject *certObject,
- nssSession *sessionOpt,
- NSSArena *arenaOpt,
- NSSCertificateType *certTypeOpt,
- NSSItem *idOpt,
- NSSDER *encodingOpt,
- NSSDER *issuerOpt,
- NSSDER *serialOpt,
- NSSDER *subjectOpt
-)
-{
- PRStatus status;
- PRUint32 i;
- nssSession *session;
- NSSSlot *slot;
- CK_ULONG template_size;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE cert_template[6];
- /* Set up a template of all options chosen by caller */
- NSS_CK_TEMPLATE_START(cert_template, attr, template_size);
- if (certTypeOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CERTIFICATE_TYPE);
- }
- if (idOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
- }
- if (encodingOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
- }
- if (issuerOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER);
- }
- if (serialOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER);
- }
- if (subjectOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
- }
- NSS_CK_TEMPLATE_FINISH(cert_template, attr, template_size);
- if (template_size == 0) {
- /* caller didn't want anything */
- return PR_SUCCESS;
- }
-
- status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt,
- certObject, CKO_CERTIFICATE,
- cert_template, template_size);
- if (status != PR_SUCCESS) {
-
- session = sessionOpt ?
- sessionOpt :
- nssToken_GetDefaultSession(certObject->token);
- if (!session) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return PR_FAILURE;
- }
-
- slot = nssToken_GetSlot(certObject->token);
- status = nssCKObject_GetAttributes(certObject->handle,
- cert_template, template_size,
- arenaOpt, session, slot);
- nssSlot_Destroy(slot);
- if (status != PR_SUCCESS) {
- return status;
- }
- }
-
- i=0;
- if (certTypeOpt) {
- *certTypeOpt = nss_cert_type_from_ck_attrib(&cert_template[i]); i++;
- }
- if (idOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt); i++;
- }
- if (encodingOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt); i++;
- }
- if (issuerOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt); i++;
- }
- if (serialOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt); i++;
- }
- if (subjectOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt); i++;
- }
- return PR_SUCCESS;
-}
-
-static nssTrustLevel
-get_nss_trust (
- CK_TRUST ckt
-)
-{
- nssTrustLevel t;
- switch (ckt) {
- case CKT_NSS_NOT_TRUSTED: t = nssTrustLevel_NotTrusted; break;
- case CKT_NSS_TRUSTED_DELEGATOR: t = nssTrustLevel_TrustedDelegator;
- break;
- case CKT_NSS_VALID_DELEGATOR: t = nssTrustLevel_ValidDelegator; break;
- case CKT_NSS_TRUSTED: t = nssTrustLevel_Trusted; break;
- case CKT_NSS_MUST_VERIFY_TRUST: t = nssTrustLevel_MustVerify; break;
- case CKT_NSS_TRUST_UNKNOWN:
- default:
- t = nssTrustLevel_Unknown; break;
- }
- return t;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCryptokiTrust_GetAttributes (
- nssCryptokiObject *trustObject,
- nssSession *sessionOpt,
- NSSItem *sha1_hash,
- nssTrustLevel *serverAuth,
- nssTrustLevel *clientAuth,
- nssTrustLevel *codeSigning,
- nssTrustLevel *emailProtection,
- PRBool *stepUpApproved
-)
-{
- PRStatus status;
- NSSSlot *slot;
- nssSession *session;
- CK_BBOOL isToken = PR_FALSE;
- CK_BBOOL stepUp = PR_FALSE;
- CK_TRUST saTrust = CKT_NSS_TRUST_UNKNOWN;
- CK_TRUST caTrust = CKT_NSS_TRUST_UNKNOWN;
- CK_TRUST epTrust = CKT_NSS_TRUST_UNKNOWN;
- CK_TRUST csTrust = CKT_NSS_TRUST_UNKNOWN;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE trust_template[7];
- CK_ATTRIBUTE_PTR sha1_hash_attr;
- CK_ULONG trust_size;
-
- /* Use the trust object to find the trust settings */
- NSS_CK_TEMPLATE_START(trust_template, attr, trust_size);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, saTrust);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, caTrust);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_STEP_UP_APPROVED, stepUp);
- sha1_hash_attr = attr;
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, sha1_hash);
- NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size);
-
- status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL,
- trustObject,
- CKO_NSS_TRUST,
- trust_template, trust_size);
- if (status != PR_SUCCESS) {
- session = sessionOpt ?
- sessionOpt :
- nssToken_GetDefaultSession(trustObject->token);
- if (!session) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return PR_FAILURE;
- }
-
- slot = nssToken_GetSlot(trustObject->token);
- status = nssCKObject_GetAttributes(trustObject->handle,
- trust_template, trust_size,
- NULL, session, slot);
- nssSlot_Destroy(slot);
- if (status != PR_SUCCESS) {
- return status;
- }
- }
-
- if (sha1_hash_attr->ulValueLen == -1) {
- /* The trust object does not have the CKA_CERT_SHA1_HASH attribute. */
- sha1_hash_attr->ulValueLen = 0;
- }
- sha1_hash->size = sha1_hash_attr->ulValueLen;
- *serverAuth = get_nss_trust(saTrust);
- *clientAuth = get_nss_trust(caTrust);
- *emailProtection = get_nss_trust(epTrust);
- *codeSigning = get_nss_trust(csTrust);
- *stepUpApproved = stepUp;
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCryptokiCRL_GetAttributes (
- nssCryptokiObject *crlObject,
- nssSession *sessionOpt,
- NSSArena *arenaOpt,
- NSSItem *encodingOpt,
- NSSItem *subjectOpt,
- CK_ULONG* crl_class,
- NSSUTF8 **urlOpt,
- PRBool *isKRLOpt
-)
-{
- PRStatus status;
- NSSSlot *slot;
- nssSession *session;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE crl_template[7];
- CK_ULONG crl_size;
- PRUint32 i;
-
- NSS_CK_TEMPLATE_START(crl_template, attr, crl_size);
- if (crl_class) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CLASS);
- }
- if (encodingOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
- }
- if (urlOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_URL);
- }
- if (isKRLOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NSS_KRL);
- }
- if (subjectOpt) {
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
- }
- NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size);
-
- status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL,
- crlObject,
- CKO_NSS_CRL,
- crl_template, crl_size);
- if (status != PR_SUCCESS) {
- session = sessionOpt ?
- sessionOpt :
- nssToken_GetDefaultSession(crlObject->token);
- if (session == NULL) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return PR_FAILURE;
- }
-
- slot = nssToken_GetSlot(crlObject->token);
- status = nssCKObject_GetAttributes(crlObject->handle,
- crl_template, crl_size,
- arenaOpt, session, slot);
- nssSlot_Destroy(slot);
- if (status != PR_SUCCESS) {
- return status;
- }
- }
-
- i=0;
- if (crl_class) {
- NSS_CK_ATTRIBUTE_TO_ULONG(&crl_template[i], *crl_class); i++;
- }
- if (encodingOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); i++;
- }
- if (urlOpt) {
- NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt); i++;
- }
- if (isKRLOpt) {
- NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); i++;
- }
- if (subjectOpt) {
- NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], subjectOpt); i++;
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCryptokiPrivateKey_SetCertificate (
- nssCryptokiObject *keyObject,
- nssSession *sessionOpt,
- const NSSUTF8 *nickname,
- NSSItem *id,
- NSSDER *subject
-)
-{
- CK_RV ckrv;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE key_template[3];
- CK_ULONG key_size;
- void *epv = nssToken_GetCryptokiEPV(keyObject->token);
- nssSession *session;
- NSSToken *token = keyObject->token;
- nssSession *defaultSession = nssToken_GetDefaultSession(token);
- PRBool createdSession = PR_FALSE;
-
- NSS_CK_TEMPLATE_START(key_template, attr, key_size);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
- NSS_CK_TEMPLATE_FINISH(key_template, attr, key_size);
-
- if (sessionOpt) {
- if (!nssSession_IsReadWrite(sessionOpt)) {
- return PR_FAILURE;
- }
- session = sessionOpt;
- } else if (defaultSession && nssSession_IsReadWrite(defaultSession)) {
- session = defaultSession;
- } else {
- NSSSlot *slot = nssToken_GetSlot(token);
- session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
- nssSlot_Destroy(slot);
- if (!session) {
- return PR_FAILURE;
- }
- createdSession = PR_TRUE;
- }
-
- ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle,
- keyObject->handle,
- key_template,
- key_size);
-
- if (createdSession) {
- nssSession_Destroy(session);
- }
-
- return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
-}
-
diff --git a/security/nss/lib/dev/ckhelper.h b/security/nss/lib/dev/ckhelper.h
deleted file mode 100644
index 91379ad83..000000000
--- a/security/nss/lib/dev/ckhelper.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * ckhelper.h
- *
- * This file contains some helper utilities for interaction with cryptoki.
- */
-
-#ifndef CKHELPER_H
-#define CKHELPER_H
-
-#ifdef DEBUG
-static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-PR_BEGIN_EXTERN_C
-
-/* Some globals to keep from constantly redeclaring common cryptoki
- * attribute types on the stack.
- */
-
-/* Boolean values */
-NSS_EXTERN_DATA const NSSItem g_ck_true;
-NSS_EXTERN_DATA const NSSItem g_ck_false;
-
-/* Object classes */
-NSS_EXTERN_DATA const NSSItem g_ck_class_cert;
-NSS_EXTERN_DATA const NSSItem g_ck_class_pubkey;
-NSS_EXTERN_DATA const NSSItem g_ck_class_privkey;
-
-#define NSS_CK_TEMPLATE_START(_template, attr, size) \
- attr = _template; \
- size = 0;
-
-#define NSS_CK_SET_ATTRIBUTE_ITEM(pattr, kind, item) \
- (pattr)->type = kind; \
- (pattr)->pValue = (CK_VOID_PTR)(item)->data; \
- (pattr)->ulValueLen = (CK_ULONG)(item)->size; \
- (pattr)++;
-
-#define NSS_CK_SET_ATTRIBUTE_UTF8(pattr, kind, utf8) \
- (pattr)->type = kind; \
- (pattr)->pValue = (CK_VOID_PTR)utf8; \
- (pattr)->ulValueLen = (CK_ULONG)nssUTF8_Size(utf8, NULL); \
- if ((pattr)->ulValueLen) ((pattr)->ulValueLen)--; \
- (pattr)++;
-
-#define NSS_CK_SET_ATTRIBUTE_VAR(pattr, kind, var) \
- (pattr)->type = kind; \
- (pattr)->pValue = (CK_VOID_PTR)&var; \
- (pattr)->ulValueLen = (CK_ULONG)sizeof(var); \
- (pattr)++;
-
-#define NSS_CK_SET_ATTRIBUTE_NULL(pattr, kind) \
- (pattr)->type = kind; \
- (pattr)->pValue = (CK_VOID_PTR)NULL; \
- (pattr)->ulValueLen = 0; \
- (pattr)++;
-
-#define NSS_CK_TEMPLATE_FINISH(_template, attr, size) \
- size = (attr) - (_template); \
- PR_ASSERT(size <= sizeof(_template)/sizeof(_template[0]));
-
-/* NSS_CK_ATTRIBUTE_TO_ITEM(attrib, item)
- *
- * Convert a CK_ATTRIBUTE to an NSSItem.
- */
-#define NSS_CK_ATTRIBUTE_TO_ITEM(attrib, item) \
- if ((CK_LONG)(attrib)->ulValueLen > 0) { \
- (item)->data = (void *)(attrib)->pValue; \
- (item)->size = (PRUint32)(attrib)->ulValueLen; \
- } else { \
- (item)->data = 0; \
- (item)->size = 0; \
- }
-
-#define NSS_CK_ATTRIBUTE_TO_BOOL(attrib, boolvar) \
- if ((attrib)->ulValueLen > 0) { \
- if (*((CK_BBOOL*)(attrib)->pValue) == CK_TRUE) { \
- boolvar = PR_TRUE; \
- } else { \
- boolvar = PR_FALSE; \
- } \
- }
-
-#define NSS_CK_ATTRIBUTE_TO_ULONG(attrib, ulongvar) \
- if ((attrib)->ulValueLen > 0) { \
- ulongvar = *((CK_ULONG*)(attrib)->pValue); \
- }
-
-/* NSS_CK_ATTRIBUTE_TO_UTF8(attrib, str)
- *
- * Convert a CK_ATTRIBUTE to a string.
- */
-#define NSS_CK_ATTRIBUTE_TO_UTF8(attrib, str) \
- str = (NSSUTF8 *)((attrib)->pValue);
-
-/* NSS_CK_ITEM_TO_ATTRIBUTE(item, attrib)
- *
- * Convert an NSSItem to a CK_ATTRIBUTE.
- */
-#define NSS_CK_ITEM_TO_ATTRIBUTE(item, attrib) \
- (attrib)->pValue = (CK_VOID_PTR)(item)->data; \
- (attrib)->ulValueLen = (CK_ULONG)(item)->size; \
-
-/* Get an array of attributes from an object. */
-NSS_EXTERN PRStatus
-nssCKObject_GetAttributes
-(
- CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_PTR obj_template,
- CK_ULONG count,
- NSSArena *arenaOpt,
- nssSession *session,
- NSSSlot *slot
-);
-
-/* Get a single attribute as an item. */
-NSS_EXTERN PRStatus
-nssCKObject_GetAttributeItem
-(
- CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_TYPE attribute,
- NSSArena *arenaOpt,
- nssSession *session,
- NSSSlot *slot,
- NSSItem *rvItem
-);
-
-NSS_EXTERN PRBool
-nssCKObject_IsAttributeTrue
-(
- CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_TYPE attribute,
- nssSession *session,
- NSSSlot *slot,
- PRStatus *rvStatus
-);
-
-NSS_EXTERN PRStatus
-nssCKObject_SetAttributes
-(
- CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_PTR obj_template,
- CK_ULONG count,
- nssSession *session,
- NSSSlot *slot
-);
-
-NSS_EXTERN PRBool
-nssCKObject_IsTokenObjectTemplate
-(
- CK_ATTRIBUTE_PTR objectTemplate,
- CK_ULONG otsize
-);
-
-PR_END_EXTERN_C
-
-#endif /* CKHELPER_H */
diff --git a/security/nss/lib/dev/config.mk b/security/nss/lib/dev/config.mk
deleted file mode 100644
index f2758950c..000000000
--- a/security/nss/lib/dev/config.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-ifdef BUILD_IDG
-DEFINES += -DNSSDEBUG
-endif
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h
deleted file mode 100644
index 23be253e3..000000000
--- a/security/nss/lib/dev/dev.h
+++ /dev/null
@@ -1,942 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef DEV_H
-#define DEV_H
-
-/*
- * dev.h
- *
- * Low-level methods for interaction with cryptoki devices
- */
-
-#ifdef DEBUG
-static const char DEV_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef NSSDEV_H
-#include "nssdev.h"
-#endif /* NSSDEV_H */
-
-#ifndef DEVT_H
-#include "devt.h"
-#endif /* DEVT_H */
-
-PR_BEGIN_EXTERN_C
-
-/* the global module list
- *
- * These functions are for managing the global set of modules. Trust Domains,
- * etc., will draw from this set. These functions are completely internal
- * and only invoked when there are changes to the global module state
- * (load or unload).
- *
- * nss_InitializeGlobalModuleList
- * nss_DestroyGlobalModuleList
- * nss_GetLoadedModules
- *
- * nssGlobalModuleList_Add
- * nssGlobalModuleList_Remove
- * nssGlobalModuleList_FindModuleByName
- * nssGlobalModuleList_FindSlotByName
- * nssGlobalModuleList_FindTokenByName
- */
-
-NSS_EXTERN PRStatus
-nss_InitializeGlobalModuleList
-(
- void
-);
-
-NSS_EXTERN PRStatus
-nss_DestroyGlobalModuleList
-(
- void
-);
-
-NSS_EXTERN NSSModule **
-nss_GetLoadedModules
-(
- void
-);
-
-NSS_EXTERN PRStatus
-nssGlobalModuleList_Add
-(
- NSSModule *module
-);
-
-NSS_EXTERN PRStatus
-nssGlobalModuleList_Remove
-(
- NSSModule *module
-);
-
-NSS_EXTERN NSSModule *
-nssGlobalModuleList_FindModuleByName
-(
- NSSUTF8 *moduleName
-);
-
-NSS_EXTERN NSSSlot *
-nssGlobalModuleList_FindSlotByName
-(
- NSSUTF8 *slotName
-);
-
-NSS_EXTERN NSSToken *
-nssGlobalModuleList_FindTokenByName
-(
- NSSUTF8 *tokenName
-);
-
-NSS_EXTERN NSSToken *
-nss_GetDefaultCryptoToken
-(
- void
-);
-
-NSS_EXTERN NSSToken *
-nss_GetDefaultDatabaseToken
-(
- void
-);
-
-/*
- * |-----------|<---> NSSSlot <--> NSSToken
- * | NSSModule |<---> NSSSlot <--> NSSToken
- * |-----------|<---> NSSSlot <--> NSSToken
- */
-
-/* NSSModule
- *
- * nssModule_Create
- * nssModule_CreateFromSpec
- * nssModule_AddRef
- * nssModule_GetName
- * nssModule_GetSlots
- * nssModule_FindSlotByName
- * nssModule_FindTokenByName
- * nssModule_GetCertOrder
- */
-
-NSS_EXTERN NSSModule *
-nssModule_Create
-(
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-);
-
-/* This is to use the new loading mechanism. */
-NSS_EXTERN NSSModule *
-nssModule_CreateFromSpec
-(
- NSSUTF8 *moduleSpec,
- NSSModule *parent,
- PRBool loadSubModules
-);
-
-NSS_EXTERN PRStatus
-nssModule_Destroy
-(
- NSSModule *mod
-);
-
-NSS_EXTERN NSSModule *
-nssModule_AddRef
-(
- NSSModule *mod
-);
-
-NSS_EXTERN NSSUTF8 *
-nssModule_GetName
-(
- NSSModule *mod
-);
-
-NSS_EXTERN NSSSlot **
-nssModule_GetSlots
-(
- NSSModule *mod
-);
-
-NSS_EXTERN NSSSlot *
-nssModule_FindSlotByName
-(
- NSSModule *mod,
- NSSUTF8 *slotName
-);
-
-NSS_EXTERN NSSToken *
-nssModule_FindTokenByName
-(
- NSSModule *mod,
- NSSUTF8 *tokenName
-);
-
-NSS_EXTERN PRInt32
-nssModule_GetCertOrder
-(
- NSSModule *module
-);
-
-/* NSSSlot
- *
- * nssSlot_Destroy
- * nssSlot_AddRef
- * nssSlot_GetName
- * nssSlot_GetTokenName
- * nssSlot_IsTokenPresent
- * nssSlot_IsPermanent
- * nssSlot_IsFriendly
- * nssSlot_IsHardware
- * nssSlot_Refresh
- * nssSlot_GetModule
- * nssSlot_GetToken
- * nssSlot_Login
- * nssSlot_Logout
- * nssSlot_SetPassword
- * nssSlot_CreateSession
- */
-
-NSS_EXTERN PRStatus
-nssSlot_Destroy
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN NSSSlot *
-nssSlot_AddRef
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN void
-nssSlot_ResetDelay
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN NSSUTF8 *
-nssSlot_GetName
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN NSSUTF8 *
-nssSlot_GetTokenName
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN NSSModule *
-nssSlot_GetModule
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN NSSToken *
-nssSlot_GetToken
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN PRBool
-nssSlot_IsTokenPresent
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN PRBool
-nssSlot_IsPermanent
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN PRBool
-nssSlot_IsFriendly
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN PRBool
-nssSlot_IsHardware
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN PRBool
-nssSlot_IsLoggedIn
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN PRStatus
-nssSlot_Refresh
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN PRStatus
-nssSlot_Login
-(
- NSSSlot *slot,
- NSSCallback *pwcb
-);
-extern const NSSError NSS_ERROR_INVALID_PASSWORD;
-extern const NSSError NSS_ERROR_USER_CANCELED;
-
-NSS_EXTERN PRStatus
-nssSlot_Logout
-(
- NSSSlot *slot,
- nssSession *sessionOpt
-);
-
-NSS_EXTERN void
-nssSlot_EnterMonitor
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN void
-nssSlot_ExitMonitor
-(
- NSSSlot *slot
-);
-
-#define NSSSLOT_ASK_PASSWORD_FIRST_TIME -1
-#define NSSSLOT_ASK_PASSWORD_EVERY_TIME 0
-NSS_EXTERN void
-nssSlot_SetPasswordDefaults
-(
- NSSSlot *slot,
- PRInt32 askPasswordTimeout
-);
-
-NSS_EXTERN PRStatus
-nssSlot_SetPassword
-(
- NSSSlot *slot,
- NSSUTF8 *oldPasswordOpt,
- NSSUTF8 *newPassword
-);
-extern const NSSError NSS_ERROR_INVALID_PASSWORD;
-extern const NSSError NSS_ERROR_USER_CANCELED;
-
-/*
- * nssSlot_IsLoggedIn
- */
-
-NSS_EXTERN nssSession *
-nssSlot_CreateSession
-(
- NSSSlot *slot,
- NSSArena *arenaOpt,
- PRBool readWrite /* so far, this is the only flag used */
-);
-
-/* NSSToken
- *
- * nssToken_Destroy
- * nssToken_AddRef
- * nssToken_GetName
- * nssToken_GetModule
- * nssToken_GetSlot
- * nssToken_NeedsPINInitialization
- * nssToken_ImportCertificate
- * nssToken_ImportTrust
- * nssToken_ImportCRL
- * nssToken_GenerateKeyPair
- * nssToken_GenerateSymmetricKey
- * nssToken_DeleteStoredObject
- * nssToken_FindObjects
- * nssToken_FindCertificatesBySubject
- * nssToken_FindCertificatesByNickname
- * nssToken_FindCertificatesByEmail
- * nssToken_FindCertificateByIssuerAndSerialNumber
- * nssToken_FindCertificateByEncodedCertificate
- * nssToken_FindTrustForCertificate
- * nssToken_FindCRLsBySubject
- * nssToken_FindPrivateKeys
- * nssToken_FindPrivateKeyByID
- * nssToken_Digest
- * nssToken_BeginDigest
- * nssToken_ContinueDigest
- * nssToken_FinishDigest
- */
-
-NSS_EXTERN PRStatus
-nssToken_Destroy
-(
- NSSToken *tok
-);
-
-NSS_EXTERN NSSToken *
-nssToken_AddRef
-(
- NSSToken *tok
-);
-
-NSS_EXTERN NSSUTF8 *
-nssToken_GetName
-(
- NSSToken *tok
-);
-
-NSS_EXTERN NSSModule *
-nssToken_GetModule
-(
- NSSToken *token
-);
-
-NSS_EXTERN NSSSlot *
-nssToken_GetSlot
-(
- NSSToken *tok
-);
-
-NSS_EXTERN PRBool
-nssToken_NeedsPINInitialization
-(
- NSSToken *token
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_ImportCertificate
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSCertificateType certType,
- NSSItem *id,
- const NSSUTF8 *nickname,
- NSSDER *encoding,
- NSSDER *issuer,
- NSSDER *subject,
- NSSDER *serial,
- NSSASCII7 *emailAddr,
- PRBool asTokenObject
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_ImportTrust
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSDER *certEncoding,
- NSSDER *certIssuer,
- NSSDER *certSerial,
- nssTrustLevel serverAuth,
- nssTrustLevel clientAuth,
- nssTrustLevel codeSigning,
- nssTrustLevel emailProtection,
- PRBool stepUpApproved,
- PRBool asTokenObject
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_ImportCRL
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *subject,
- NSSDER *encoding,
- PRBool isKRL,
- NSSUTF8 *url,
- PRBool asTokenObject
-);
-
-/* Permanently remove an object from the token. */
-NSS_EXTERN PRStatus
-nssToken_DeleteStoredObject
-(
- nssCryptokiObject *instance
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssToken_FindObjects
-(
- NSSToken *token,
- nssSession *sessionOpt,
- CK_OBJECT_CLASS objclass,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssToken_FindCertificatesBySubject
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *subject,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssToken_FindCertificatesByNickname
-(
- NSSToken *token,
- nssSession *sessionOpt,
- const NSSUTF8 *name,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssToken_FindCertificatesByEmail
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSASCII7 *email,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssToken_FindCertificatesByID
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSItem *id,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_FindCertificateByIssuerAndSerialNumber
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *issuer,
- NSSDER *serial,
- nssTokenSearchType searchType,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_FindCertificateByEncodedCertificate
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSBER *encodedCertificate,
- nssTokenSearchType searchType,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_FindTrustForCertificate
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *certEncoding,
- NSSDER *certIssuer,
- NSSDER *certSerial,
- nssTokenSearchType searchType
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssToken_FindCRLsBySubject
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *subject,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssToken_FindPrivateKeys
-(
- NSSToken *token,
- nssSession *sessionOpt,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_FindPrivateKeyByID
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSItem *keyID
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssToken_FindPublicKeyByID
-(
- NSSToken *token,
- nssSession *sessionOpt,
- NSSItem *keyID
-);
-
-NSS_EXTERN NSSItem *
-nssToken_Digest
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSAlgorithmAndParameters *ap,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN PRStatus
-nssToken_BeginDigest
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSAlgorithmAndParameters *ap
-);
-
-NSS_EXTERN PRStatus
-nssToken_ContinueDigest
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSItem *item
-);
-
-NSS_EXTERN NSSItem *
-nssToken_FinishDigest
-(
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/* nssSession
- *
- * nssSession_Destroy
- * nssSession_EnterMonitor
- * nssSession_ExitMonitor
- * nssSession_IsReadWrite
- */
-
-NSS_EXTERN PRStatus
-nssSession_Destroy
-(
- nssSession *s
-);
-
-/* would like to inline */
-NSS_EXTERN PRStatus
-nssSession_EnterMonitor
-(
- nssSession *s
-);
-
-/* would like to inline */
-NSS_EXTERN PRStatus
-nssSession_ExitMonitor
-(
- nssSession *s
-);
-
-/* would like to inline */
-NSS_EXTERN PRBool
-nssSession_IsReadWrite
-(
- nssSession *s
-);
-
-/* nssCryptokiObject
- *
- * An object living on a cryptoki token.
- * Not really proper to mix up the object types just because
- * nssCryptokiObject itself is generic, but doing so anyway.
- *
- * nssCryptokiObject_Destroy
- * nssCryptokiObject_Equal
- * nssCryptokiObject_Clone
- * nssCryptokiCertificate_GetAttributes
- * nssCryptokiPrivateKey_GetAttributes
- * nssCryptokiPublicKey_GetAttributes
- * nssCryptokiTrust_GetAttributes
- * nssCryptokiCRL_GetAttributes
- */
-
-NSS_EXTERN void
-nssCryptokiObject_Destroy
-(
- nssCryptokiObject *object
-);
-
-NSS_EXTERN PRBool
-nssCryptokiObject_Equal
-(
- nssCryptokiObject *object1,
- nssCryptokiObject *object2
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssCryptokiObject_Clone
-(
- nssCryptokiObject *object
-);
-
-NSS_EXTERN PRStatus
-nssCryptokiCertificate_GetAttributes
-(
- nssCryptokiObject *object,
- nssSession *sessionOpt,
- NSSArena *arenaOpt,
- NSSCertificateType *certTypeOpt,
- NSSItem *idOpt,
- NSSDER *encodingOpt,
- NSSDER *issuerOpt,
- NSSDER *serialOpt,
- NSSDER *subjectOpt
-);
-
-NSS_EXTERN PRStatus
-nssCryptokiTrust_GetAttributes
-(
- nssCryptokiObject *trustObject,
- nssSession *sessionOpt,
- NSSItem *sha1_hash,
- nssTrustLevel *serverAuth,
- nssTrustLevel *clientAuth,
- nssTrustLevel *codeSigning,
- nssTrustLevel *emailProtection,
- PRBool *stepUpApproved
-);
-
-NSS_EXTERN PRStatus
-nssCryptokiCRL_GetAttributes
-(
- nssCryptokiObject *crlObject,
- nssSession *sessionOpt,
- NSSArena *arenaOpt,
- NSSItem *encodingOpt,
- NSSItem * subjectOpt,
- CK_ULONG * crl_class,
- NSSUTF8 **urlOpt,
- PRBool *isKRLOpt
-);
-
-/* I'm including this to handle import of certificates in NSS 3.5. This
- * function will set the cert-related attributes of a key, in order to
- * associate it with a cert. Does it stay like this for 4.0?
- */
-NSS_EXTERN PRStatus
-nssCryptokiPrivateKey_SetCertificate
-(
- nssCryptokiObject *keyObject,
- nssSession *sessionOpt,
- const NSSUTF8 *nickname,
- NSSItem *id,
- NSSDER *subject
-);
-
-NSS_EXTERN void
-nssModuleArray_Destroy
-(
- NSSModule **modules
-);
-
-/* nssSlotArray
- *
- * nssSlotArray_Destroy
- */
-
-NSS_EXTERN void
-nssSlotArray_Destroy
-(
- NSSSlot **slots
-);
-
-/* nssTokenArray
- *
- * nssTokenArray_Destroy
- */
-
-NSS_EXTERN void
-nssTokenArray_Destroy
-(
- NSSToken **tokens
-);
-
-/* nssCryptokiObjectArray
- *
- * nssCryptokiObjectArray_Destroy
- */
-NSS_EXTERN void
-nssCryptokiObjectArray_Destroy
-(
- nssCryptokiObject **object
-);
-
-/* nssSlotList
-*
- * An ordered list of slots. The order can be anything, it is set in the
- * Add methods. Perhaps it should be CreateInCertOrder, ...?
- *
- * nssSlotList_Create
- * nssSlotList_Destroy
- * nssSlotList_Add
- * nssSlotList_AddModuleSlots
- * nssSlotList_GetSlots
- * nssSlotList_FindSlotByName
- * nssSlotList_FindTokenByName
- * nssSlotList_GetBestSlot
- * nssSlotList_GetBestSlotForAlgorithmAndParameters
- * nssSlotList_GetBestSlotForAlgorithmsAndParameters
- */
-
-/* nssSlotList_Create
- */
-NSS_EXTERN nssSlotList *
-nssSlotList_Create
-(
- NSSArena *arenaOpt
-);
-
-/* nssSlotList_Destroy
- */
-NSS_EXTERN void
-nssSlotList_Destroy
-(
- nssSlotList *slotList
-);
-
-/* nssSlotList_Add
- *
- * Add the given slot in the given order.
- */
-NSS_EXTERN PRStatus
-nssSlotList_Add
-(
- nssSlotList *slotList,
- NSSSlot *slot,
- PRUint32 order
-);
-
-/* nssSlotList_AddModuleSlots
- *
- * Add all slots in the module, in the given order (the slots will have
- * equal weight).
- */
-NSS_EXTERN PRStatus
-nssSlotList_AddModuleSlots
-(
- nssSlotList *slotList,
- NSSModule *module,
- PRUint32 order
-);
-
-/* nssSlotList_GetSlots
- */
-NSS_EXTERN NSSSlot **
-nssSlotList_GetSlots
-(
- nssSlotList *slotList
-);
-
-/* nssSlotList_FindSlotByName
- */
-NSS_EXTERN NSSSlot *
-nssSlotList_FindSlotByName
-(
- nssSlotList *slotList,
- NSSUTF8 *slotName
-);
-
-/* nssSlotList_FindTokenByName
- */
-NSS_EXTERN NSSToken *
-nssSlotList_FindTokenByName
-(
- nssSlotList *slotList,
- NSSUTF8 *tokenName
-);
-
-/* nssSlotList_GetBestSlot
- *
- * The best slot is the highest ranking in order, i.e., the first in the
- * list.
- */
-NSS_EXTERN NSSSlot *
-nssSlotList_GetBestSlot
-(
- nssSlotList *slotList
-);
-
-/* nssSlotList_GetBestSlotForAlgorithmAndParameters
- *
- * Highest-ranking slot than can handle algorithm/parameters.
- */
-NSS_EXTERN NSSSlot *
-nssSlotList_GetBestSlotForAlgorithmAndParameters
-(
- nssSlotList *slotList,
- NSSAlgorithmAndParameters *ap
-);
-
-/* nssSlotList_GetBestSlotForAlgorithmsAndParameters
- *
- * Highest-ranking slot than can handle all algorithms/parameters.
- */
-NSS_EXTERN NSSSlot *
-nssSlotList_GetBestSlotForAlgorithmsAndParameters
-(
- nssSlotList *slotList,
- NSSAlgorithmAndParameters **ap
-);
-
-NSS_EXTERN PRBool
-nssToken_IsPresent
-(
- NSSToken *token
-);
-
-NSS_EXTERN nssSession *
-nssToken_GetDefaultSession
-(
- NSSToken *token
-);
-
-NSS_EXTERN PRStatus
-nssToken_GetTrustOrder
-(
- NSSToken *tok
-);
-
-NSS_EXTERN PRStatus
-nssToken_NotifyCertsNotVisible
-(
- NSSToken *tok
-);
-
-NSS_EXTERN PRStatus
-nssToken_TraverseCertificates
-(
- NSSToken *token,
- nssSession *sessionOpt,
- nssTokenSearchType searchType,
- PRStatus (* callback)(nssCryptokiObject *instance, void *arg),
- void *arg
-);
-
-NSS_EXTERN PRBool
-nssToken_IsPrivateKeyAvailable
-(
- NSSToken *token,
- NSSCertificate *c,
- nssCryptokiObject *instance
-);
-
-PR_END_EXTERN_C
-
-#endif /* DEV_H */
diff --git a/security/nss/lib/dev/devm.h b/security/nss/lib/dev/devm.h
deleted file mode 100644
index f0c91e888..000000000
--- a/security/nss/lib/dev/devm.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef DEVM_H
-#define DEVM_H
-
-#ifdef DEBUG
-static const char DEVM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
-#ifndef DEVTM_H
-#include "devtm.h"
-#endif /* DEVTM_H */
-
-PR_BEGIN_EXTERN_C
-
-/* Shortcut to cryptoki API functions. */
-#define CKAPI(epv) \
- ((CK_FUNCTION_LIST_PTR)(epv))
-
-NSS_EXTERN void
-nssDevice_AddRef
-(
- struct nssDeviceBaseStr *device
-);
-
-NSS_EXTERN PRBool
-nssDevice_Destroy
-(
- struct nssDeviceBaseStr *device
-);
-
-NSS_EXTERN PRBool
-nssModule_IsThreadSafe
-(
- NSSModule *module
-);
-
-NSS_EXTERN PRBool
-nssModule_IsInternal
-(
- NSSModule *mod
-);
-
-NSS_EXTERN PRBool
-nssModule_IsModuleDBOnly
-(
- NSSModule *mod
-);
-
-NSS_EXTERN void *
-nssModule_GetCryptokiEPV
-(
- NSSModule *mod
-);
-
-NSS_EXTERN NSSSlot *
-nssSlot_Create
-(
- CK_SLOT_ID slotId,
- NSSModule *parent
-);
-
-NSS_EXTERN void *
-nssSlot_GetCryptokiEPV
-(
- NSSSlot *slot
-);
-
-NSS_EXTERN NSSToken *
-nssToken_Create
-(
- CK_SLOT_ID slotID,
- NSSSlot *peer
-);
-
-NSS_EXTERN void *
-nssToken_GetCryptokiEPV
-(
- NSSToken *token
-);
-
-NSS_EXTERN nssSession *
-nssToken_GetDefaultSession
-(
- NSSToken *token
-);
-
-NSS_EXTERN PRBool
-nssToken_IsLoginRequired
-(
- NSSToken *token
-);
-
-NSS_EXTERN void
-nssToken_Remove
-(
- NSSToken *token
-);
-
-NSS_EXTERN nssCryptokiObject *
-nssCryptokiObject_Create
-(
- NSSToken *t,
- nssSession *session,
- CK_OBJECT_HANDLE h
-);
-
-NSS_EXTERN nssTokenObjectCache *
-nssTokenObjectCache_Create
-(
- NSSToken *token,
- PRBool cacheCerts,
- PRBool cacheTrust,
- PRBool cacheCRLs
-);
-
-NSS_EXTERN void
-nssTokenObjectCache_Destroy
-(
- nssTokenObjectCache *cache
-);
-
-NSS_EXTERN void
-nssTokenObjectCache_Clear
-(
- nssTokenObjectCache *cache
-);
-
-NSS_EXTERN PRBool
-nssTokenObjectCache_HaveObjectClass
-(
- nssTokenObjectCache *cache,
- CK_OBJECT_CLASS objclass
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssTokenObjectCache_FindObjectsByTemplate
-(
- nssTokenObjectCache *cache,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR otemplate,
- CK_ULONG otlen,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN PRStatus
-nssTokenObjectCache_GetObjectAttributes
-(
- nssTokenObjectCache *cache,
- NSSArena *arenaOpt,
- nssCryptokiObject *object,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR atemplate,
- CK_ULONG atlen
-);
-
-NSS_EXTERN PRStatus
-nssTokenObjectCache_ImportObject
-(
- nssTokenObjectCache *cache,
- nssCryptokiObject *object,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR ot,
- CK_ULONG otlen
-);
-
-NSS_EXTERN void
-nssTokenObjectCache_RemoveObject
-(
- nssTokenObjectCache *cache,
- nssCryptokiObject *object
-);
-
-/* XXX allows peek back into token */
-NSS_EXTERN PRStatus
-nssToken_GetCachedObjectAttributes
-(
- NSSToken *token,
- NSSArena *arenaOpt,
- nssCryptokiObject *object,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR atemplate,
- CK_ULONG atlen
-);
-
-/* PKCS#11 stores strings in a fixed-length buffer padded with spaces. This
- * function gets the length of the actual string.
- */
-NSS_EXTERN PRUint32
-nssPKCS11String_Length
-(
- CK_CHAR *pkcs11str,
- PRUint32 bufLen
-);
-
-PR_END_EXTERN_C
-
-#endif /* DEV_H */
diff --git a/security/nss/lib/dev/devslot.c b/security/nss/lib/dev/devslot.c
deleted file mode 100644
index 418aef6e5..000000000
--- a/security/nss/lib/dev/devslot.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "pkcs11.h"
-
-#ifndef DEVM_H
-#include "devm.h"
-#endif /* DEVM_H */
-
-#ifndef CKHELPER_H
-#include "ckhelper.h"
-#endif /* CKHELPER_H */
-
-#include "pk11pub.h"
-
-/* measured in seconds */
-#define NSSSLOT_TOKEN_DELAY_TIME 1
-
-/* this should track global and per-transaction login information */
-
-#define NSSSLOT_IS_FRIENDLY(slot) \
- (slot->base.flags & NSSSLOT_FLAGS_FRIENDLY)
-
-/* measured as interval */
-static PRIntervalTime s_token_delay_time = 0;
-
-/* The flags needed to open a read-only session. */
-static const CK_FLAGS s_ck_readonly_flags = CKF_SERIAL_SESSION;
-
-NSS_IMPLEMENT PRStatus
-nssSlot_Destroy (
- NSSSlot *slot
-)
-{
- if (slot) {
- if (PR_ATOMIC_DECREMENT(&slot->base.refCount) == 0) {
- PZ_DestroyLock(slot->base.lock);
- return nssArena_Destroy(slot->base.arena);
- }
- }
- return PR_SUCCESS;
-}
-
-void
-nssSlot_EnterMonitor(NSSSlot *slot)
-{
- if (slot->lock) {
- PZ_Lock(slot->lock);
- }
-}
-
-void
-nssSlot_ExitMonitor(NSSSlot *slot)
-{
- if (slot->lock) {
- PZ_Unlock(slot->lock);
- }
-}
-
-NSS_IMPLEMENT void
-NSSSlot_Destroy (
- NSSSlot *slot
-)
-{
- (void)nssSlot_Destroy(slot);
-}
-
-NSS_IMPLEMENT NSSSlot *
-nssSlot_AddRef (
- NSSSlot *slot
-)
-{
- PR_ATOMIC_INCREMENT(&slot->base.refCount);
- return slot;
-}
-
-NSS_IMPLEMENT NSSUTF8 *
-nssSlot_GetName (
- NSSSlot *slot
-)
-{
- return slot->base.name;
-}
-
-NSS_IMPLEMENT NSSUTF8 *
-nssSlot_GetTokenName (
- NSSSlot *slot
-)
-{
- return nssToken_GetName(slot->token);
-}
-
-NSS_IMPLEMENT void
-nssSlot_ResetDelay (
- NSSSlot *slot
-)
-{
- slot->lastTokenPing = 0;
-}
-
-static PRBool
-within_token_delay_period(NSSSlot *slot)
-{
- PRIntervalTime time, lastTime;
- /* Set the delay time for checking the token presence */
- if (s_token_delay_time == 0) {
- s_token_delay_time = PR_SecondsToInterval(NSSSLOT_TOKEN_DELAY_TIME);
- }
- time = PR_IntervalNow();
- lastTime = slot->lastTokenPing;
- if ((lastTime) && ((time - lastTime) < s_token_delay_time)) {
- return PR_TRUE;
- }
- slot->lastTokenPing = time;
- return PR_FALSE;
-}
-
-NSS_IMPLEMENT PRBool
-nssSlot_IsTokenPresent (
- NSSSlot *slot
-)
-{
- CK_RV ckrv;
- PRStatus nssrv;
- /* XXX */
- nssSession *session;
- CK_SLOT_INFO slotInfo;
- void *epv;
- /* permanent slots are always present unless they're disabled */
- if (nssSlot_IsPermanent(slot)) {
- return !PK11_IsDisabled(slot->pk11slot);
- }
- /* avoid repeated calls to check token status within set interval */
- if (within_token_delay_period(slot)) {
- return ((slot->ckFlags & CKF_TOKEN_PRESENT) != 0);
- }
-
- /* First obtain the slot info */
- epv = slot->epv;
- if (!epv) {
- return PR_FALSE;
- }
- nssSlot_EnterMonitor(slot);
- ckrv = CKAPI(epv)->C_GetSlotInfo(slot->slotID, &slotInfo);
- nssSlot_ExitMonitor(slot);
- if (ckrv != CKR_OK) {
- slot->token->base.name[0] = 0; /* XXX */
- return PR_FALSE;
- }
- slot->ckFlags = slotInfo.flags;
- /* check for the presence of the token */
- if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) {
- if (!slot->token) {
- /* token was never present */
- return PR_FALSE;
- }
- session = nssToken_GetDefaultSession(slot->token);
- if (session) {
- nssSession_EnterMonitor(session);
- /* token is not present */
- if (session->handle != CK_INVALID_SESSION) {
- /* session is valid, close and invalidate it */
- CKAPI(epv)->C_CloseSession(session->handle);
- session->handle = CK_INVALID_SESSION;
- }
- nssSession_ExitMonitor(session);
- }
- if (slot->token->base.name[0] != 0) {
- /* notify the high-level cache that the token is removed */
- slot->token->base.name[0] = 0; /* XXX */
- nssToken_NotifyCertsNotVisible(slot->token);
- }
- slot->token->base.name[0] = 0; /* XXX */
- /* clear the token cache */
- nssToken_Remove(slot->token);
- return PR_FALSE;
- }
- /* token is present, use the session info to determine if the card
- * has been removed and reinserted.
- */
- session = nssToken_GetDefaultSession(slot->token);
- if (session) {
- PRBool isPresent = PR_FALSE;
- nssSession_EnterMonitor(session);
- if (session->handle != CK_INVALID_SESSION) {
- CK_SESSION_INFO sessionInfo;
- ckrv = CKAPI(epv)->C_GetSessionInfo(session->handle, &sessionInfo);
- if (ckrv != CKR_OK) {
- /* session is screwy, close and invalidate it */
- CKAPI(epv)->C_CloseSession(session->handle);
- session->handle = CK_INVALID_SESSION;
- }
- }
- isPresent = session->handle != CK_INVALID_SESSION;
- nssSession_ExitMonitor(session);
- /* token not removed, finished */
- if (isPresent)
- return PR_TRUE;
- }
- /* the token has been removed, and reinserted, or the slot contains
- * a token it doesn't recognize. invalidate all the old
- * information we had on this token, if we can't refresh, clear
- * the present flag */
- nssToken_NotifyCertsNotVisible(slot->token);
- nssToken_Remove(slot->token);
- /* token has been removed, need to refresh with new session */
- nssrv = nssSlot_Refresh(slot);
- if (nssrv != PR_SUCCESS) {
- slot->token->base.name[0] = 0; /* XXX */
- slot->ckFlags &= ~CKF_TOKEN_PRESENT;
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-NSS_IMPLEMENT void *
-nssSlot_GetCryptokiEPV (
- NSSSlot *slot
-)
-{
- return slot->epv;
-}
-
-NSS_IMPLEMENT NSSToken *
-nssSlot_GetToken (
- NSSSlot *slot
-)
-{
- if (nssSlot_IsTokenPresent(slot)) {
- return nssToken_AddRef(slot->token);
- }
- return (NSSToken *)NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-nssSession_EnterMonitor (
- nssSession *s
-)
-{
- if (s->lock) PZ_Lock(s->lock);
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssSession_ExitMonitor (
- nssSession *s
-)
-{
- return (s->lock) ? PZ_Unlock(s->lock) : PR_SUCCESS;
-}
-
-NSS_EXTERN PRBool
-nssSession_IsReadWrite (
- nssSession *s
-)
-{
- return s->isRW;
-}
-
diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h
deleted file mode 100644
index cd9fbfe61..000000000
--- a/security/nss/lib/dev/devt.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef DEVT_H
-#define DEVT_H
-
-#ifdef DEBUG
-static const char DEVT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * devt.h
- *
- * This file contains definitions for the low-level cryptoki devices.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSPKIT_H
-#include "nsspkit.h"
-#endif /* NSSPKIT_H */
-
-#ifndef NSSDEVT_H
-#include "nssdevt.h"
-#endif /* NSSDEVT_H */
-
-#ifndef BASET_H
-#include "baset.h"
-#endif /* BASET_H */
-
-#include "secmodt.h"
-
-PR_BEGIN_EXTERN_C
-
-typedef struct nssSessionStr nssSession;
-
-/* XXX until NSSTokenStr is moved */
-struct nssDeviceBaseStr
-{
- NSSArena *arena;
- PZLock *lock;
- PRInt32 refCount;
- NSSUTF8 *name;
- PRUint32 flags;
-};
-
-typedef struct nssTokenObjectCacheStr nssTokenObjectCache;
-
-/* XXX until devobject.c goes away */
-struct NSSTokenStr
-{
- struct nssDeviceBaseStr base;
- NSSSlot *slot; /* Parent (or peer, if you will) */
- CK_FLAGS ckFlags; /* from CK_TOKEN_INFO.flags */
- PRUint32 flags;
- void *epv;
- nssSession *defaultSession;
- NSSTrustDomain *trustDomain;
- PRIntervalTime lastTime;
- nssTokenObjectCache *cache;
- PK11SlotInfo *pk11slot;
-};
-
-typedef enum {
- nssSlotAskPasswordTimes_FirstTime = 0,
- nssSlotAskPasswordTimes_EveryTime = 1,
- nssSlotAskPasswordTimes_Timeout = 2
-}
-nssSlotAskPasswordTimes;
-
-struct nssSlotAuthInfoStr
-{
- PRTime lastLogin;
- nssSlotAskPasswordTimes askTimes;
- PRIntervalTime askPasswordTimeout;
-};
-
-struct NSSSlotStr
-{
- struct nssDeviceBaseStr base;
- NSSModule *module; /* Parent */
- NSSToken *token; /* Peer */
- CK_SLOT_ID slotID;
- CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
- struct nssSlotAuthInfoStr authInfo;
- PRIntervalTime lastTokenPing;
- PZLock *lock;
- void *epv;
- PK11SlotInfo *pk11slot;
-};
-
-struct nssSessionStr
-{
- PZLock *lock;
- CK_SESSION_HANDLE handle;
- NSSSlot *slot;
- PRBool isRW;
- PRBool ownLock;
-};
-
-typedef enum {
- NSSCertificateType_Unknown = 0,
- NSSCertificateType_PKIX = 1
-} NSSCertificateType;
-
-typedef enum {
- nssTrustLevel_Unknown = 0,
- nssTrustLevel_NotTrusted = 1,
- nssTrustLevel_Trusted = 2,
- nssTrustLevel_TrustedDelegator = 3,
- nssTrustLevel_MustVerify = 4,
- nssTrustLevel_ValidDelegator = 5
-} nssTrustLevel;
-
-typedef struct nssCryptokiInstanceStr nssCryptokiInstance;
-
-struct nssCryptokiInstanceStr
-{
- CK_OBJECT_HANDLE handle;
- NSSToken *token;
- PRBool isTokenObject;
- NSSUTF8 *label;
-};
-
-typedef struct nssCryptokiInstanceStr nssCryptokiObject;
-
-typedef struct nssTokenCertSearchStr nssTokenCertSearch;
-
-typedef enum {
- nssTokenSearchType_AllObjects = 0,
- nssTokenSearchType_SessionOnly = 1,
- nssTokenSearchType_TokenOnly = 2,
- nssTokenSearchType_TokenForced = 3
-} nssTokenSearchType;
-
-struct nssTokenCertSearchStr
-{
- nssTokenSearchType searchType;
- PRStatus (* callback)(NSSCertificate *c, void *arg);
- void *cbarg;
- nssList *cached;
- /* TODO: add a cache query callback if the list would be large
- * (traversal)
- */
-};
-
-struct nssSlotListStr;
-typedef struct nssSlotListStr nssSlotList;
-
-struct NSSAlgorithmAndParametersStr
-{
- CK_MECHANISM mechanism;
-};
-
-PR_END_EXTERN_C
-
-#endif /* DEVT_H */
diff --git a/security/nss/lib/dev/devtm.h b/security/nss/lib/dev/devtm.h
deleted file mode 100644
index 423203dae..000000000
--- a/security/nss/lib/dev/devtm.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef DEVTM_H
-#define DEVTM_H
-
-#ifdef DEBUG
-static const char DEVTM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * devtm.h
- *
- * This file contains module-private definitions for the low-level
- * cryptoki devices.
- */
-
-#ifndef DEVT_H
-#include "devt.h"
-#endif /* DEVT_H */
-
-PR_BEGIN_EXTERN_C
-
-#define MAX_LOCAL_CACHE_OBJECTS 10
-
-PR_END_EXTERN_C
-
-#endif /* DEVTM_H */
diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c
deleted file mode 100644
index eeac71b37..000000000
--- a/security/nss/lib/dev/devtoken.c
+++ /dev/null
@@ -1,1584 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "pkcs11.h"
-
-#ifndef DEVM_H
-#include "devm.h"
-#endif /* DEVM_H */
-
-#ifndef CKHELPER_H
-#include "ckhelper.h"
-#endif /* CKHELPER_H */
-
-#include "pk11func.h"
-#include "dev3hack.h"
-#include "secerr.h"
-
-extern const NSSError NSS_ERROR_NOT_FOUND;
-extern const NSSError NSS_ERROR_INVALID_ARGUMENT;
-extern const NSSError NSS_ERROR_PKCS11;
-
-/* The number of object handles to grab during each call to C_FindObjects */
-#define OBJECT_STACK_SIZE 16
-
-NSS_IMPLEMENT PRStatus
-nssToken_Destroy (
- NSSToken *tok
-)
-{
- if (tok) {
- if (PR_ATOMIC_DECREMENT(&tok->base.refCount) == 0) {
- PZ_DestroyLock(tok->base.lock);
- nssTokenObjectCache_Destroy(tok->cache);
- /* The token holds the first/last reference to the slot.
- * When the token is actually destroyed, that ref must go too.
- */
- (void)nssSlot_Destroy(tok->slot);
- return nssArena_Destroy(tok->base.arena);
- }
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT void
-nssToken_Remove (
- NSSToken *tok
-)
-{
- nssTokenObjectCache_Clear(tok->cache);
-}
-
-NSS_IMPLEMENT void
-NSSToken_Destroy (
- NSSToken *tok
-)
-{
- (void)nssToken_Destroy(tok);
-}
-
-NSS_IMPLEMENT NSSToken *
-nssToken_AddRef (
- NSSToken *tok
-)
-{
- PR_ATOMIC_INCREMENT(&tok->base.refCount);
- return tok;
-}
-
-NSS_IMPLEMENT NSSSlot *
-nssToken_GetSlot (
- NSSToken *tok
-)
-{
- return nssSlot_AddRef(tok->slot);
-}
-
-NSS_IMPLEMENT void *
-nssToken_GetCryptokiEPV (
- NSSToken *token
-)
-{
- return nssSlot_GetCryptokiEPV(token->slot);
-}
-
-NSS_IMPLEMENT nssSession *
-nssToken_GetDefaultSession (
- NSSToken *token
-)
-{
- return token->defaultSession;
-}
-
-NSS_IMPLEMENT NSSUTF8 *
-nssToken_GetName (
- NSSToken *tok
-)
-{
- if (tok == NULL) {
- return "";
- }
- if (tok->base.name[0] == 0) {
- (void) nssSlot_IsTokenPresent(tok->slot);
- }
- return tok->base.name;
-}
-
-NSS_IMPLEMENT NSSUTF8 *
-NSSToken_GetName (
- NSSToken *token
-)
-{
- return nssToken_GetName(token);
-}
-
-NSS_IMPLEMENT PRBool
-nssToken_IsLoginRequired (
- NSSToken *token
-)
-{
- return (token->ckFlags & CKF_LOGIN_REQUIRED);
-}
-
-NSS_IMPLEMENT PRBool
-nssToken_NeedsPINInitialization (
- NSSToken *token
-)
-{
- return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED));
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_DeleteStoredObject (
- nssCryptokiObject *instance
-)
-{
- CK_RV ckrv;
- PRStatus status;
- PRBool createdSession = PR_FALSE;
- NSSToken *token = instance->token;
- nssSession *session = NULL;
- void *epv = nssToken_GetCryptokiEPV(instance->token);
- if (token->cache) {
- nssTokenObjectCache_RemoveObject(token->cache, instance);
- }
- if (instance->isTokenObject) {
- if (token->defaultSession &&
- nssSession_IsReadWrite(token->defaultSession)) {
- session = token->defaultSession;
- } else {
- session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
- createdSession = PR_TRUE;
- }
- }
- if (session == NULL) {
- return PR_FAILURE;
- }
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle);
- nssSession_ExitMonitor(session);
- if (createdSession) {
- nssSession_Destroy(session);
- }
- status = PR_SUCCESS;
- if (ckrv != CKR_OK) {
- status = PR_FAILURE;
- /* use the error stack to pass the PKCS #11 error out */
- nss_SetError(ckrv);
- nss_SetError(NSS_ERROR_PKCS11);
- }
- return status;
-}
-
-static nssCryptokiObject *
-import_object (
- NSSToken *tok,
- nssSession *sessionOpt,
- CK_ATTRIBUTE_PTR objectTemplate,
- CK_ULONG otsize
-)
-{
- nssSession *session = NULL;
- PRBool createdSession = PR_FALSE;
- nssCryptokiObject *object = NULL;
- CK_OBJECT_HANDLE handle;
- CK_RV ckrv;
- void *epv = nssToken_GetCryptokiEPV(tok);
- if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) {
- if (sessionOpt) {
- if (!nssSession_IsReadWrite(sessionOpt)) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return NULL;
- }
- session = sessionOpt;
- } else if (tok->defaultSession &&
- nssSession_IsReadWrite(tok->defaultSession)) {
- session = tok->defaultSession;
- } else {
- session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
- createdSession = PR_TRUE;
- }
- } else {
- session = (sessionOpt) ? sessionOpt : tok->defaultSession;
- }
- if (session == NULL) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return NULL;
- }
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_CreateObject(session->handle,
- objectTemplate, otsize,
- &handle);
- nssSession_ExitMonitor(session);
- if (ckrv == CKR_OK) {
- object = nssCryptokiObject_Create(tok, session, handle);
- } else {
- nss_SetError(ckrv);
- nss_SetError(NSS_ERROR_PKCS11);
- }
- if (createdSession) {
- nssSession_Destroy(session);
- }
- return object;
-}
-
-static nssCryptokiObject **
-create_objects_from_handles (
- NSSToken *tok,
- nssSession *session,
- CK_OBJECT_HANDLE *handles,
- PRUint32 numH
-)
-{
- nssCryptokiObject **objects;
- objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numH + 1);
- if (objects) {
- PRInt32 i;
- for (i=0; i<(PRInt32)numH; i++) {
- objects[i] = nssCryptokiObject_Create(tok, session, handles[i]);
- if (!objects[i]) {
- for (--i; i>0; --i) {
- nssCryptokiObject_Destroy(objects[i]);
- }
- nss_ZFreeIf(objects);
- objects = NULL;
- break;
- }
- }
- }
- return objects;
-}
-
-static nssCryptokiObject **
-find_objects (
- NSSToken *tok,
- nssSession *sessionOpt,
- CK_ATTRIBUTE_PTR obj_template,
- CK_ULONG otsize,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_RV ckrv = CKR_OK;
- CK_ULONG count;
- CK_OBJECT_HANDLE *objectHandles = NULL;
- CK_OBJECT_HANDLE staticObjects[OBJECT_STACK_SIZE];
- PRUint32 arraySize, numHandles;
- void *epv = nssToken_GetCryptokiEPV(tok);
- nssCryptokiObject **objects;
- nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;
-
- /* Don't ask the module to use an invalid session handle. */
- if (!session || session->handle == CK_INVALID_SESSION) {
- ckrv = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- /* the arena is only for the array of object handles */
- if (maximumOpt > 0) {
- arraySize = maximumOpt;
- } else {
- arraySize = OBJECT_STACK_SIZE;
- }
- numHandles = 0;
- if (arraySize <= OBJECT_STACK_SIZE) {
- objectHandles = staticObjects;
- } else {
- objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize);
- }
- if (!objectHandles) {
- ckrv = CKR_HOST_MEMORY;
- goto loser;
- }
- nssSession_EnterMonitor(session); /* ==== session lock === */
- /* Initialize the find with the template */
- ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
- obj_template, otsize);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- goto loser;
- }
- while (PR_TRUE) {
- /* Issue the find for up to arraySize - numHandles objects */
- ckrv = CKAPI(epv)->C_FindObjects(session->handle,
- objectHandles + numHandles,
- arraySize - numHandles,
- &count);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- goto loser;
- }
- /* bump the number of found objects */
- numHandles += count;
- if (maximumOpt > 0 || numHandles < arraySize) {
- /* When a maximum is provided, the search is done all at once,
- * so the search is finished. If the number returned was less
- * than the number sought, the search is finished.
- */
- break;
- }
- /* the array is filled, double it and continue */
- arraySize *= 2;
- if (objectHandles == staticObjects) {
- objectHandles = nss_ZNEWARRAY(NULL,CK_OBJECT_HANDLE, arraySize);
- if (objectHandles) {
- PORT_Memcpy(objectHandles, staticObjects,
- OBJECT_STACK_SIZE * sizeof(objectHandles[1]));
- }
- } else {
- objectHandles = nss_ZREALLOCARRAY(objectHandles,
- CK_OBJECT_HANDLE,
- arraySize);
- }
- if (!objectHandles) {
- nssSession_ExitMonitor(session);
- ckrv = CKR_HOST_MEMORY;
- goto loser;
- }
- }
- ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle);
- nssSession_ExitMonitor(session); /* ==== end session lock === */
- if (ckrv != CKR_OK) {
- goto loser;
- }
- if (numHandles > 0) {
- objects = create_objects_from_handles(tok, session,
- objectHandles, numHandles);
- } else {
- nss_SetError(NSS_ERROR_NOT_FOUND);
- objects = NULL;
- }
- if (objectHandles && objectHandles != staticObjects) {
- nss_ZFreeIf(objectHandles);
- }
- if (statusOpt) *statusOpt = PR_SUCCESS;
- return objects;
-loser:
- if (objectHandles && objectHandles != staticObjects) {
- nss_ZFreeIf(objectHandles);
- }
- /*
- * These errors should be treated the same as if the objects just weren't
- * found..
- */
- if ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) ||
- (ckrv == CKR_ATTRIBUTE_VALUE_INVALID) ||
- (ckrv == CKR_DATA_INVALID) ||
- (ckrv == CKR_DATA_LEN_RANGE) ||
- (ckrv == CKR_FUNCTION_NOT_SUPPORTED) ||
- (ckrv == CKR_TEMPLATE_INCOMPLETE) ||
- (ckrv == CKR_TEMPLATE_INCONSISTENT)) {
-
- nss_SetError(NSS_ERROR_NOT_FOUND);
- if (statusOpt) *statusOpt = PR_SUCCESS;
- } else {
- nss_SetError(ckrv);
- nss_SetError(NSS_ERROR_PKCS11);
- if (statusOpt) *statusOpt = PR_FAILURE;
- }
- return (nssCryptokiObject **)NULL;
-}
-
-static nssCryptokiObject **
-find_objects_by_template (
- NSSToken *token,
- nssSession *sessionOpt,
- CK_ATTRIBUTE_PTR obj_template,
- CK_ULONG otsize,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1;
- nssCryptokiObject **objects = NULL;
- PRUint32 i;
-
- if (!token) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- if (statusOpt)
- *statusOpt = PR_FAILURE;
- return NULL;
- }
- for (i=0; i<otsize; i++) {
- if (obj_template[i].type == CKA_CLASS) {
- objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue;
- break;
- }
- }
- PR_ASSERT(i < otsize);
- if (i == otsize) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- if (statusOpt) *statusOpt = PR_FAILURE;
- return NULL;
- }
- /* If these objects are being cached, try looking there first */
- if (token->cache &&
- nssTokenObjectCache_HaveObjectClass(token->cache, objclass))
- {
- PRStatus status;
- objects = nssTokenObjectCache_FindObjectsByTemplate(token->cache,
- objclass,
- obj_template,
- otsize,
- maximumOpt,
- &status);
- if (status == PR_SUCCESS) {
- if (statusOpt) *statusOpt = status;
- return objects;
- }
- }
- /* Either they are not cached, or cache failed; look on token. */
- objects = find_objects(token, sessionOpt,
- obj_template, otsize,
- maximumOpt, statusOpt);
- return objects;
-}
-
-extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
-
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_ImportCertificate (
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSCertificateType certType,
- NSSItem *id,
- const NSSUTF8 *nickname,
- NSSDER *encoding,
- NSSDER *issuer,
- NSSDER *subject,
- NSSDER *serial,
- NSSASCII7 *email,
- PRBool asTokenObject
-)
-{
- PRStatus status;
- CK_CERTIFICATE_TYPE cert_type;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE cert_tmpl[10];
- CK_ULONG ctsize;
- nssTokenSearchType searchType;
- nssCryptokiObject *rvObject = NULL;
-
- if (!tok) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return NULL;
- }
- if (certType == NSSCertificateType_PKIX) {
- cert_type = CKC_X_509;
- } else {
- return (nssCryptokiObject *)NULL;
- }
- NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
- if (asTokenObject) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- searchType = nssTokenSearchType_TokenOnly;
- } else {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- searchType = nssTokenSearchType_SessionOnly;
- }
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial);
- if (email) {
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email);
- }
- NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
- /* see if the cert is already there */
- rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok,
- sessionOpt,
- issuer,
- serial,
- searchType,
- NULL);
- if (rvObject) {
- NSSItem existingDER;
- NSSSlot *slot = nssToken_GetSlot(tok);
- nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE);
- if (!session) {
- nssCryptokiObject_Destroy(rvObject);
- nssSlot_Destroy(slot);
- return (nssCryptokiObject *)NULL;
- }
- /* Reject any attempt to import a new cert that has the same
- * issuer/serial as an existing cert, but does not have the
- * same encoding
- */
- NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
- NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
- status = nssCKObject_GetAttributes(rvObject->handle,
- cert_tmpl, ctsize, NULL,
- session, slot);
- NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER);
- if (status == PR_SUCCESS) {
- if (!nssItem_Equal(encoding, &existingDER, NULL)) {
- nss_SetError(NSS_ERROR_INVALID_CERTIFICATE);
- status = PR_FAILURE;
- }
- nss_ZFreeIf(existingDER.data);
- }
- if (status == PR_FAILURE) {
- nssCryptokiObject_Destroy(rvObject);
- nssSession_Destroy(session);
- nssSlot_Destroy(slot);
- return (nssCryptokiObject *)NULL;
- }
- /* according to PKCS#11, label, ID, issuer, and serial number
- * may change after the object has been created. For PKIX, the
- * last two attributes can't change, so for now we'll only worry
- * about the first two.
- */
- NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
- NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
- /* reset the mutable attributes on the token */
- nssCKObject_SetAttributes(rvObject->handle,
- cert_tmpl, ctsize,
- session, slot);
- if (!rvObject->label && nickname) {
- rvObject->label = nssUTF8_Duplicate(nickname, NULL);
- }
- nssSession_Destroy(session);
- nssSlot_Destroy(slot);
- } else {
- /* Import the certificate onto the token */
- rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize);
- }
- if (rvObject && tok->cache) {
- /* The cache will overwrite the attributes if the object already
- * exists.
- */
- nssTokenObjectCache_ImportObject(tok->cache, rvObject,
- CKO_CERTIFICATE,
- cert_tmpl, ctsize);
- }
- return rvObject;
-}
-
-/* traverse all objects of the given class - this should only happen
- * if the token has been marked as "traversable"
- */
-NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindObjects (
- NSSToken *token,
- nssSession *sessionOpt,
- CK_OBJECT_CLASS objclass,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE obj_template[2];
- CK_ULONG obj_size;
- nssCryptokiObject **objects;
- NSS_CK_TEMPLATE_START(obj_template, attr, obj_size);
- /* Set the search to token/session only if provided */
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly ||
- searchType == nssTokenSearchType_TokenForced) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, objclass);
- NSS_CK_TEMPLATE_FINISH(obj_template, attr, obj_size);
-
- if (searchType == nssTokenSearchType_TokenForced) {
- objects = find_objects(token, sessionOpt,
- obj_template, obj_size,
- maximumOpt, statusOpt);
- } else {
- objects = find_objects_by_template(token, sessionOpt,
- obj_template, obj_size,
- maximumOpt, statusOpt);
- }
- return objects;
-}
-
-NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindCertificatesBySubject (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *subject,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE subj_template[3];
- CK_ULONG stsize;
- nssCryptokiObject **objects;
- NSS_CK_TEMPLATE_START(subj_template, attr, stsize);
- /* Set the search to token/session only if provided */
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
- NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize);
- /* now locate the token certs matching this template */
- objects = find_objects_by_template(token, sessionOpt,
- subj_template, stsize,
- maximumOpt, statusOpt);
- return objects;
-}
-
-NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindCertificatesByNickname (
- NSSToken *token,
- nssSession *sessionOpt,
- const NSSUTF8 *name,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE nick_template[3];
- CK_ULONG ntsize;
- nssCryptokiObject **objects;
- NSS_CK_TEMPLATE_START(nick_template, attr, ntsize);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name);
- /* Set the search to token/session only if provided */
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize);
- /* now locate the token certs matching this template */
- objects = find_objects_by_template(token, sessionOpt,
- nick_template, ntsize,
- maximumOpt, statusOpt);
- if (!objects) {
- /* This is to workaround the fact that PKCS#11 doesn't specify
- * whether the '\0' should be included. XXX Is that still true?
- * im - this is not needed by the current softoken. However, I'm
- * leaving it in until I have surveyed more tokens to see if it needed.
- * well, its needed by the builtin token...
- */
- nick_template[0].ulValueLen++;
- objects = find_objects_by_template(token, sessionOpt,
- nick_template, ntsize,
- maximumOpt, statusOpt);
- }
- return objects;
-}
-
-/* XXX
- * This function *does not* use the token object cache, because not even
- * the softoken will return a value for CKA_NSS_EMAIL from a call
- * to GetAttributes. The softoken does allow searches with that attribute,
- * it just won't return a value for it.
- */
-NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindCertificatesByEmail (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSASCII7 *email,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE email_template[3];
- CK_ULONG etsize;
- nssCryptokiObject **objects;
- NSS_CK_TEMPLATE_START(email_template, attr, etsize);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email);
- /* Set the search to token/session only if provided */
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize);
- /* now locate the token certs matching this template */
- objects = find_objects(token, sessionOpt,
- email_template, etsize,
- maximumOpt, statusOpt);
- if (!objects) {
- /* This is to workaround the fact that PKCS#11 doesn't specify
- * whether the '\0' should be included. XXX Is that still true?
- * im - this is not needed by the current softoken. However, I'm
- * leaving it in until I have surveyed more tokens to see if it needed.
- * well, its needed by the builtin token...
- */
- email_template[0].ulValueLen++;
- objects = find_objects(token, sessionOpt,
- email_template, etsize,
- maximumOpt, statusOpt);
- }
- return objects;
-}
-
-NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindCertificatesByID (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSItem *id,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE id_template[3];
- CK_ULONG idtsize;
- nssCryptokiObject **objects;
- NSS_CK_TEMPLATE_START(id_template, attr, idtsize);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
- /* Set the search to token/session only if provided */
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize);
- /* now locate the token certs matching this template */
- objects = find_objects_by_template(token, sessionOpt,
- id_template, idtsize,
- maximumOpt, statusOpt);
- return objects;
-}
-
-/*
- * decode the serial item and return our result.
- * NOTE serialDecode's data is really stored in serial. Don't free it.
- */
-static PRStatus
-nssToken_decodeSerialItem(NSSItem *serial, NSSItem *serialDecode)
-{
- unsigned char *data = (unsigned char *)serial->data;
- int data_left, data_len, index;
-
- if ((serial->size >= 3) && (data[0] == 0x2)) {
- /* remove the der encoding of the serial number before generating the
- * key.. */
- data_left = serial->size-2;
- data_len = data[1];
- index = 2;
-
- /* extended length ? (not very likely for a serial number) */
- if (data_len & 0x80) {
- int len_count = data_len & 0x7f;
-
- data_len = 0;
- data_left -= len_count;
- if (data_left > 0) {
- while (len_count --) {
- data_len = (data_len << 8) | data[index++];
- }
- }
- }
- /* XXX leaving any leading zeros on the serial number for backwards
- * compatibility
- */
- /* not a valid der, must be just an unlucky serial number value */
- if (data_len == data_left) {
- serialDecode->size = data_len;
- serialDecode->data = &data[index];
- return PR_SUCCESS;
- }
- }
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_FindCertificateByIssuerAndSerialNumber (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *issuer,
- NSSDER *serial,
- nssTokenSearchType searchType,
- PRStatus *statusOpt
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE_PTR serialAttr;
- CK_ATTRIBUTE cert_template[4];
- CK_ULONG ctsize;
- nssCryptokiObject **objects;
- nssCryptokiObject *rvObject = NULL;
- NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
-
- if (!token) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- if (statusOpt)
- *statusOpt = PR_FAILURE;
- return NULL;
- }
- /* Set the search to token/session only if provided */
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if ((searchType == nssTokenSearchType_TokenOnly) ||
- (searchType == nssTokenSearchType_TokenForced)) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- /* Set the unique id */
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer);
- serialAttr = attr;
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial);
- NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
- /* get the object handle */
- if (searchType == nssTokenSearchType_TokenForced) {
- objects = find_objects(token, sessionOpt,
- cert_template, ctsize,
- 1, statusOpt);
- } else {
- objects = find_objects_by_template(token, sessionOpt,
- cert_template, ctsize,
- 1, statusOpt);
- }
- if (objects) {
- rvObject = objects[0];
- nss_ZFreeIf(objects);
- }
-
- /*
- * NSS used to incorrectly store serial numbers in their decoded form.
- * because of this old tokens have decoded serial numbers.
- */
- if (!objects) {
- NSSItem serialDecode;
- PRStatus status;
-
- status = nssToken_decodeSerialItem(serial, &serialDecode);
- if (status != PR_SUCCESS) {
- return NULL;
- }
- NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr,CKA_SERIAL_NUMBER,&serialDecode);
- if (searchType == nssTokenSearchType_TokenForced) {
- objects = find_objects(token, sessionOpt,
- cert_template, ctsize,
- 1, statusOpt);
- } else {
- objects = find_objects_by_template(token, sessionOpt,
- cert_template, ctsize,
- 1, statusOpt);
- }
- if (objects) {
- rvObject = objects[0];
- nss_ZFreeIf(objects);
- }
- }
- return rvObject;
-}
-
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_FindCertificateByEncodedCertificate (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSBER *encodedCertificate,
- nssTokenSearchType searchType,
- PRStatus *statusOpt
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE cert_template[3];
- CK_ULONG ctsize;
- nssCryptokiObject **objects;
- nssCryptokiObject *rvObject = NULL;
- NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
- /* Set the search to token/session only if provided */
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate);
- NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
- /* get the object handle */
- objects = find_objects_by_template(token, sessionOpt,
- cert_template, ctsize,
- 1, statusOpt);
- if (objects) {
- rvObject = objects[0];
- nss_ZFreeIf(objects);
- }
- return rvObject;
-}
-
-NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindPrivateKeys (
- NSSToken *token,
- nssSession *sessionOpt,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE key_template[2];
- CK_ULONG ktsize;
- nssCryptokiObject **objects;
-
- NSS_CK_TEMPLATE_START(key_template, attr, ktsize);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey);
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);
-
- objects = find_objects_by_template(token, sessionOpt,
- key_template, ktsize,
- maximumOpt, statusOpt);
- return objects;
-}
-
-/* XXX ?there are no session cert objects, so only search token objects */
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_FindPrivateKeyByID (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSItem *keyID
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE key_template[3];
- CK_ULONG ktsize;
- nssCryptokiObject **objects;
- nssCryptokiObject *rvKey = NULL;
-
- NSS_CK_TEMPLATE_START(key_template, attr, ktsize);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID);
- NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);
-
- objects = find_objects_by_template(token, sessionOpt,
- key_template, ktsize,
- 1, NULL);
- if (objects) {
- rvKey = objects[0];
- nss_ZFreeIf(objects);
- }
- return rvKey;
-}
-
-/* XXX ?there are no session cert objects, so only search token objects */
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_FindPublicKeyByID (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSItem *keyID
-)
-{
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE key_template[3];
- CK_ULONG ktsize;
- nssCryptokiObject **objects;
- nssCryptokiObject *rvKey = NULL;
-
- NSS_CK_TEMPLATE_START(key_template, attr, ktsize);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_pubkey);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID);
- NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);
-
- objects = find_objects_by_template(token, sessionOpt,
- key_template, ktsize,
- 1, NULL);
- if (objects) {
- rvKey = objects[0];
- nss_ZFreeIf(objects);
- }
- return rvKey;
-}
-
-static void
-sha1_hash(NSSItem *input, NSSItem *output)
-{
- NSSAlgorithmAndParameters *ap;
- PK11SlotInfo *internal = PK11_GetInternalSlot();
- NSSToken *token = PK11Slot_GetNSSToken(internal);
- ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL);
- (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
- PK11_FreeSlot(token->pk11slot);
- nss_ZFreeIf(ap);
-}
-
-static void
-md5_hash(NSSItem *input, NSSItem *output)
-{
- NSSAlgorithmAndParameters *ap;
- PK11SlotInfo *internal = PK11_GetInternalSlot();
- NSSToken *token = PK11Slot_GetNSSToken(internal);
- ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL);
- (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
- PK11_FreeSlot(token->pk11slot);
- nss_ZFreeIf(ap);
-}
-
-static CK_TRUST
-get_ck_trust (
- nssTrustLevel nssTrust
-)
-{
- CK_TRUST t;
- switch (nssTrust) {
- case nssTrustLevel_NotTrusted: t = CKT_NSS_NOT_TRUSTED; break;
- case nssTrustLevel_TrustedDelegator: t = CKT_NSS_TRUSTED_DELEGATOR;
- break;
- case nssTrustLevel_ValidDelegator: t = CKT_NSS_VALID_DELEGATOR; break;
- case nssTrustLevel_Trusted: t = CKT_NSS_TRUSTED; break;
- case nssTrustLevel_MustVerify: t = CKT_NSS_MUST_VERIFY_TRUST; break;
- case nssTrustLevel_Unknown:
- default: t = CKT_NSS_TRUST_UNKNOWN; break;
- }
- return t;
-}
-
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_ImportTrust (
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSDER *certEncoding,
- NSSDER *certIssuer,
- NSSDER *certSerial,
- nssTrustLevel serverAuth,
- nssTrustLevel clientAuth,
- nssTrustLevel codeSigning,
- nssTrustLevel emailProtection,
- PRBool stepUpApproved,
- PRBool asTokenObject
-)
-{
- nssCryptokiObject *object;
- CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST;
- CK_TRUST ckSA, ckCA, ckCS, ckEP;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE trust_tmpl[11];
- CK_ULONG tsize;
- PRUint8 sha1[20]; /* this is cheating... */
- PRUint8 md5[16];
- NSSItem sha1_result, md5_result;
- sha1_result.data = sha1; sha1_result.size = sizeof sha1;
- md5_result.data = md5; md5_result.size = sizeof md5;
- sha1_hash(certEncoding, &sha1_result);
- md5_hash(certEncoding, &md5_result);
- ckSA = get_ck_trust(serverAuth);
- ckCA = get_ck_trust(clientAuth);
- ckCS = get_ck_trust(codeSigning);
- ckEP = get_ck_trust(emailProtection);
- NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize);
- if (asTokenObject) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- } else {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- }
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result);
- /* now set the trust values */
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, ckSA);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, ckCA);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, ckCS);
- NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, ckEP);
- if (stepUpApproved) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED,
- &g_ck_true);
- } else {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED,
- &g_ck_false);
- }
- NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize);
- /* import the trust object onto the token */
- object = import_object(tok, sessionOpt, trust_tmpl, tsize);
- if (object && tok->cache) {
- nssTokenObjectCache_ImportObject(tok->cache, object, tobjc,
- trust_tmpl, tsize);
- }
- return object;
-}
-
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_FindTrustForCertificate (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *certEncoding,
- NSSDER *certIssuer,
- NSSDER *certSerial,
- nssTokenSearchType searchType
-)
-{
- CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE tobj_template[5];
- CK_ULONG tobj_size;
- nssSession *session = sessionOpt ? sessionOpt : token->defaultSession;
- nssCryptokiObject *object = NULL, **objects;
-
- /* Don't ask the module to use an invalid session handle. */
- if (!session || session->handle == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return object;
- }
-
- NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size);
- if (searchType == nssTokenSearchType_TokenOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER , certSerial);
- NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size);
- objects = find_objects_by_template(token, session,
- tobj_template, tobj_size,
- 1, NULL);
- if (objects) {
- object = objects[0];
- nss_ZFreeIf(objects);
- }
- return object;
-}
-
-NSS_IMPLEMENT nssCryptokiObject *
-nssToken_ImportCRL (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *subject,
- NSSDER *encoding,
- PRBool isKRL,
- NSSUTF8 *url,
- PRBool asTokenObject
-)
-{
- nssCryptokiObject *object;
- CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE crl_tmpl[6];
- CK_ULONG crlsize;
-
- NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize);
- if (asTokenObject) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- } else {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- }
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_URL, url);
- if (isKRL) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_true);
- } else {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_false);
- }
- NSS_CK_TEMPLATE_FINISH(crl_tmpl, attr, crlsize);
-
- /* import the crl object onto the token */
- object = import_object(token, sessionOpt, crl_tmpl, crlsize);
- if (object && token->cache) {
- nssTokenObjectCache_ImportObject(token->cache, object, crlobjc,
- crl_tmpl, crlsize);
- }
- return object;
-}
-
-NSS_IMPLEMENT nssCryptokiObject **
-nssToken_FindCRLsBySubject (
- NSSToken *token,
- nssSession *sessionOpt,
- NSSDER *subject,
- nssTokenSearchType searchType,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE crlobj_template[3];
- CK_ULONG crlobj_size;
- nssCryptokiObject **objects = NULL;
- nssSession *session = sessionOpt ? sessionOpt : token->defaultSession;
-
- /* Don't ask the module to use an invalid session handle. */
- if (!session || session->handle == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return objects;
- }
-
- NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size);
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly ||
- searchType == nssTokenSearchType_TokenForced) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc);
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
- NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size);
-
- objects = find_objects_by_template(token, session,
- crlobj_template, crlobj_size,
- maximumOpt, statusOpt);
- return objects;
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_GetCachedObjectAttributes (
- NSSToken *token,
- NSSArena *arenaOpt,
- nssCryptokiObject *object,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR atemplate,
- CK_ULONG atlen
-)
-{
- if (!token->cache) {
- return PR_FAILURE;
- }
- return nssTokenObjectCache_GetObjectAttributes(token->cache, arenaOpt,
- object, objclass,
- atemplate, atlen);
-}
-
-NSS_IMPLEMENT NSSItem *
-nssToken_Digest (
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSAlgorithmAndParameters *ap,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- CK_RV ckrv;
- CK_ULONG digestLen;
- CK_BYTE_PTR digest;
- NSSItem *rvItem = NULL;
- void *epv = nssToken_GetCryptokiEPV(tok);
- nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;
-
- /* Don't ask the module to use an invalid session handle. */
- if (!session || session->handle == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return rvItem;
- }
-
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- return NULL;
- }
-#if 0
- /* XXX the standard says this should work, but it doesn't */
- ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- return NULL;
- }
-#endif
- digestLen = 0; /* XXX for now */
- digest = NULL;
- if (rvOpt) {
- if (rvOpt->size > 0 && rvOpt->size < digestLen) {
- nssSession_ExitMonitor(session);
- /* the error should be bad args */
- return NULL;
- }
- if (rvOpt->data) {
- digest = rvOpt->data;
- }
- digestLen = rvOpt->size;
- }
- if (!digest) {
- digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen);
- if (!digest) {
- nssSession_ExitMonitor(session);
- return NULL;
- }
- }
- ckrv = CKAPI(epv)->C_Digest(session->handle,
- (CK_BYTE_PTR)data->data,
- (CK_ULONG)data->size,
- (CK_BYTE_PTR)digest,
- &digestLen);
- nssSession_ExitMonitor(session);
- if (ckrv != CKR_OK) {
- nss_ZFreeIf(digest);
- return NULL;
- }
- if (!rvOpt) {
- rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
- }
- return rvItem;
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_BeginDigest (
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSAlgorithmAndParameters *ap
-)
-{
- CK_RV ckrv;
- void *epv = nssToken_GetCryptokiEPV(tok);
- nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;
-
- /* Don't ask the module to use an invalid session handle. */
- if (!session || session->handle == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return PR_FAILURE;
- }
-
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism);
- nssSession_ExitMonitor(session);
- return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_ContinueDigest (
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSItem *item
-)
-{
- CK_RV ckrv;
- void *epv = nssToken_GetCryptokiEPV(tok);
- nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;
-
- /* Don't ask the module to use an invalid session handle. */
- if (!session || session->handle == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return PR_FAILURE;
- }
-
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_DigestUpdate(session->handle,
- (CK_BYTE_PTR)item->data,
- (CK_ULONG)item->size);
- nssSession_ExitMonitor(session);
- return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-nssToken_FinishDigest (
- NSSToken *tok,
- nssSession *sessionOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- CK_RV ckrv;
- CK_ULONG digestLen;
- CK_BYTE_PTR digest;
- NSSItem *rvItem = NULL;
- void *epv = nssToken_GetCryptokiEPV(tok);
- nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;
-
- /* Don't ask the module to use an invalid session handle. */
- if (!session || session->handle == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return NULL;
- }
-
- nssSession_EnterMonitor(session);
- ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen);
- if (ckrv != CKR_OK || digestLen == 0) {
- nssSession_ExitMonitor(session);
- return NULL;
- }
- digest = NULL;
- if (rvOpt) {
- if (rvOpt->size > 0 && rvOpt->size < digestLen) {
- nssSession_ExitMonitor(session);
- /* the error should be bad args */
- return NULL;
- }
- if (rvOpt->data) {
- digest = rvOpt->data;
- }
- digestLen = rvOpt->size;
- }
- if (!digest) {
- digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen);
- if (!digest) {
- nssSession_ExitMonitor(session);
- return NULL;
- }
- }
- ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen);
- nssSession_ExitMonitor(session);
- if (ckrv != CKR_OK) {
- nss_ZFreeIf(digest);
- return NULL;
- }
- if (!rvOpt) {
- rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
- }
- return rvItem;
-}
-
-NSS_IMPLEMENT PRBool
-nssToken_IsPresent (
- NSSToken *token
-)
-{
- return nssSlot_IsTokenPresent(token->slot);
-}
-
-/* Sigh. The methods to find objects declared above cause problems with
- * the low-level object cache in the softoken -- the objects are found in
- * toto, then one wave of GetAttributes is done, then another. Having a
- * large number of objects causes the cache to be thrashed, as the objects
- * are gone before there's any chance to ask for their attributes.
- * So, for now, bringing back traversal methods for certs. This way all of
- * the cert's attributes can be grabbed immediately after finding it,
- * increasing the likelihood that the cache takes care of it.
- */
-NSS_IMPLEMENT PRStatus
-nssToken_TraverseCertificates (
- NSSToken *token,
- nssSession *sessionOpt,
- nssTokenSearchType searchType,
- PRStatus (* callback)(nssCryptokiObject *instance, void *arg),
- void *arg
-)
-{
- CK_RV ckrv;
- CK_ULONG count;
- CK_OBJECT_HANDLE *objectHandles;
- CK_ATTRIBUTE_PTR attr;
- CK_ATTRIBUTE cert_template[2];
- CK_ULONG ctsize;
- NSSArena *arena;
- PRStatus status;
- PRUint32 arraySize, numHandles;
- nssCryptokiObject **objects;
- void *epv = nssToken_GetCryptokiEPV(token);
- nssSession *session = (sessionOpt) ? sessionOpt : token->defaultSession;
-
- /* Don't ask the module to use an invalid session handle. */
- if (!session || session->handle == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return PR_FAILURE;
- }
-
- /* template for all certs */
- NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
- if (searchType == nssTokenSearchType_SessionOnly) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly ||
- searchType == nssTokenSearchType_TokenForced) {
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
- }
- NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
- NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
-
- /* the arena is only for the array of object handles */
- arena = nssArena_Create();
- if (!arena) {
- return PR_FAILURE;
- }
- arraySize = OBJECT_STACK_SIZE;
- numHandles = 0;
- objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize);
- if (!objectHandles) {
- goto loser;
- }
- nssSession_EnterMonitor(session); /* ==== session lock === */
- /* Initialize the find with the template */
- ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
- cert_template, ctsize);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- goto loser;
- }
- while (PR_TRUE) {
- /* Issue the find for up to arraySize - numHandles objects */
- ckrv = CKAPI(epv)->C_FindObjects(session->handle,
- objectHandles + numHandles,
- arraySize - numHandles,
- &count);
- if (ckrv != CKR_OK) {
- nssSession_ExitMonitor(session);
- goto loser;
- }
- /* bump the number of found objects */
- numHandles += count;
- if (numHandles < arraySize) {
- break;
- }
- /* the array is filled, double it and continue */
- arraySize *= 2;
- objectHandles = nss_ZREALLOCARRAY(objectHandles,
- CK_OBJECT_HANDLE,
- arraySize);
- if (!objectHandles) {
- nssSession_ExitMonitor(session);
- goto loser;
- }
- }
- ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle);
- nssSession_ExitMonitor(session); /* ==== end session lock === */
- if (ckrv != CKR_OK) {
- goto loser;
- }
- if (numHandles > 0) {
- objects = create_objects_from_handles(token, session,
- objectHandles, numHandles);
- if (objects) {
- nssCryptokiObject **op;
- for (op = objects; *op; op++) {
- status = (*callback)(*op, arg);
- }
- nss_ZFreeIf(objects);
- }
- }
- nssArena_Destroy(arena);
- return PR_SUCCESS;
-loser:
- nssArena_Destroy(arena);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRBool
-nssToken_IsPrivateKeyAvailable (
- NSSToken *token,
- NSSCertificate *c,
- nssCryptokiObject *instance
-)
-{
- CK_OBJECT_CLASS theClass;
-
- if (token == NULL) return PR_FALSE;
- if (c == NULL) return PR_FALSE;
-
- theClass = CKO_PRIVATE_KEY;
- if (!nssSlot_IsLoggedIn(token->slot)) {
- theClass = CKO_PUBLIC_KEY;
- }
- if (PK11_MatchItem(token->pk11slot, instance->handle, theClass)
- != CK_INVALID_HANDLE) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
diff --git a/security/nss/lib/dev/devutil.c b/security/nss/lib/dev/devutil.c
deleted file mode 100644
index 981d9172f..000000000
--- a/security/nss/lib/dev/devutil.c
+++ /dev/null
@@ -1,1010 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef DEVM_H
-#include "devm.h"
-#endif /* DEVM_H */
-
-#ifndef CKHELPER_H
-#include "ckhelper.h"
-#endif /* CKHELPER_H */
-
-NSS_IMPLEMENT nssCryptokiObject *
-nssCryptokiObject_Create (
- NSSToken *t,
- nssSession *session,
- CK_OBJECT_HANDLE h
-)
-{
- PRStatus status;
- NSSSlot *slot;
- nssCryptokiObject *object;
- CK_BBOOL *isTokenObject;
- CK_ATTRIBUTE cert_template[] = {
- { CKA_TOKEN, NULL, 0 },
- { CKA_LABEL, NULL, 0 }
- };
- slot = nssToken_GetSlot(t);
- status = nssCKObject_GetAttributes(h, cert_template, 2,
- NULL, session, slot);
- nssSlot_Destroy(slot);
- if (status != PR_SUCCESS) {
- /* a failure here indicates a device error */
- return (nssCryptokiObject *)NULL;
- }
- object = nss_ZNEW(NULL, nssCryptokiObject);
- if (!object) {
- return (nssCryptokiObject *)NULL;
- }
- object->handle = h;
- object->token = nssToken_AddRef(t);
- isTokenObject = (CK_BBOOL *)cert_template[0].pValue;
- object->isTokenObject = *isTokenObject;
- nss_ZFreeIf(isTokenObject);
- NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[1], object->label);
- return object;
-}
-
-NSS_IMPLEMENT void
-nssCryptokiObject_Destroy (
- nssCryptokiObject *object
-)
-{
- if (object) {
- nssToken_Destroy(object->token);
- nss_ZFreeIf(object->label);
- nss_ZFreeIf(object);
- }
-}
-
-NSS_IMPLEMENT nssCryptokiObject *
-nssCryptokiObject_Clone (
- nssCryptokiObject *object
-)
-{
- nssCryptokiObject *rvObject;
- rvObject = nss_ZNEW(NULL, nssCryptokiObject);
- if (rvObject) {
- rvObject->handle = object->handle;
- rvObject->token = nssToken_AddRef(object->token);
- rvObject->isTokenObject = object->isTokenObject;
- if (object->label) {
- rvObject->label = nssUTF8_Duplicate(object->label, NULL);
- }
- }
- return rvObject;
-}
-
-NSS_EXTERN PRBool
-nssCryptokiObject_Equal (
- nssCryptokiObject *o1,
- nssCryptokiObject *o2
-)
-{
- return (o1->token == o2->token && o1->handle == o2->handle);
-}
-
-NSS_IMPLEMENT PRUint32
-nssPKCS11String_Length(CK_CHAR *pkcs11Str, PRUint32 bufLen)
-{
- PRInt32 i;
- for (i = bufLen - 1; i>=0; ) {
- if (pkcs11Str[i] != ' ' && pkcs11Str[i] != '\0') break;
- --i;
- }
- return (PRUint32)(i + 1);
-}
-
-/*
- * Slot arrays
- */
-
-NSS_IMPLEMENT NSSSlot **
-nssSlotArray_Clone (
- NSSSlot **slots
-)
-{
- NSSSlot **rvSlots = NULL;
- NSSSlot **sp = slots;
- PRUint32 count = 0;
- while (sp && *sp) count++;
- if (count > 0) {
- rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
- if (rvSlots) {
- for (sp = slots, count = 0; *sp; sp++) {
- rvSlots[count++] = nssSlot_AddRef(*sp);
- }
- }
- }
- return rvSlots;
-}
-
-NSS_IMPLEMENT void
-nssSlotArray_Destroy (
- NSSSlot **slots
-)
-{
- if (slots) {
- NSSSlot **slotp;
- for (slotp = slots; *slotp; slotp++) {
- nssSlot_Destroy(*slotp);
- }
- nss_ZFreeIf(slots);
- }
-}
-
-NSS_IMPLEMENT void
-NSSSlotArray_Destroy (
- NSSSlot **slots
-)
-{
- nssSlotArray_Destroy(slots);
-}
-
-NSS_IMPLEMENT void
-nssTokenArray_Destroy (
- NSSToken **tokens
-)
-{
- if (tokens) {
- NSSToken **tokenp;
- for (tokenp = tokens; *tokenp; tokenp++) {
- nssToken_Destroy(*tokenp);
- }
- nss_ZFreeIf(tokens);
- }
-}
-
-NSS_IMPLEMENT void
-NSSTokenArray_Destroy (
- NSSToken **tokens
-)
-{
- nssTokenArray_Destroy(tokens);
-}
-
-NSS_IMPLEMENT void
-nssCryptokiObjectArray_Destroy (
- nssCryptokiObject **objects
-)
-{
- if (objects) {
- nssCryptokiObject **op;
- for (op = objects; *op; op++) {
- nssCryptokiObject_Destroy(*op);
- }
- nss_ZFreeIf(objects);
- }
-}
-
-/* object cache for token */
-
-typedef struct
-{
- NSSArena *arena;
- nssCryptokiObject *object;
- CK_ATTRIBUTE_PTR attributes;
- CK_ULONG numAttributes;
-}
-nssCryptokiObjectAndAttributes;
-
-enum {
- cachedCerts = 0,
- cachedTrust = 1,
- cachedCRLs = 2
-} cachedObjectType;
-
-struct nssTokenObjectCacheStr
-{
- NSSToken *token;
- PZLock *lock;
- PRBool loggedIn;
- PRBool doObjectType[3];
- PRBool searchedObjectType[3];
- nssCryptokiObjectAndAttributes **objects[3];
-};
-
-NSS_IMPLEMENT nssTokenObjectCache *
-nssTokenObjectCache_Create (
- NSSToken *token,
- PRBool cacheCerts,
- PRBool cacheTrust,
- PRBool cacheCRLs
-)
-{
- nssTokenObjectCache *rvCache;
- rvCache = nss_ZNEW(NULL, nssTokenObjectCache);
- if (!rvCache) {
- goto loser;
- }
- rvCache->lock = PZ_NewLock(nssILockOther); /* XXX */
- if (!rvCache->lock) {
- goto loser;
- }
- rvCache->doObjectType[cachedCerts] = cacheCerts;
- rvCache->doObjectType[cachedTrust] = cacheTrust;
- rvCache->doObjectType[cachedCRLs] = cacheCRLs;
- rvCache->token = token; /* cache goes away with token */
- return rvCache;
-loser:
- nssTokenObjectCache_Destroy(rvCache);
- return (nssTokenObjectCache *)NULL;
-}
-
-static void
-clear_cache (
- nssTokenObjectCache *cache
-)
-{
- nssCryptokiObjectAndAttributes **oa;
- PRUint32 objectType;
- for (objectType = cachedCerts; objectType <= cachedCRLs; objectType++) {
- cache->searchedObjectType[objectType] = PR_FALSE;
- if (!cache->objects[objectType]) {
- continue;
- }
- for (oa = cache->objects[objectType]; *oa; oa++) {
- /* prevent the token from being destroyed */
- (*oa)->object->token = NULL;
- nssCryptokiObject_Destroy((*oa)->object);
- nssArena_Destroy((*oa)->arena);
- }
- nss_ZFreeIf(cache->objects[objectType]);
- cache->objects[objectType] = NULL;
- }
-}
-
-NSS_IMPLEMENT void
-nssTokenObjectCache_Clear (
- nssTokenObjectCache *cache
-)
-{
- if (cache) {
- PZ_Lock(cache->lock);
- clear_cache(cache);
- PZ_Unlock(cache->lock);
- }
-}
-
-NSS_IMPLEMENT void
-nssTokenObjectCache_Destroy (
- nssTokenObjectCache *cache
-)
-{
- if (cache) {
- clear_cache(cache);
- if (cache->lock) {
- PZ_DestroyLock(cache->lock);
- }
- nss_ZFreeIf(cache);
- }
-}
-
-NSS_IMPLEMENT PRBool
-nssTokenObjectCache_HaveObjectClass (
- nssTokenObjectCache *cache,
- CK_OBJECT_CLASS objclass
-)
-{
- PRBool haveIt;
- PZ_Lock(cache->lock);
- switch (objclass) {
- case CKO_CERTIFICATE: haveIt = cache->doObjectType[cachedCerts]; break;
- case CKO_NETSCAPE_TRUST: haveIt = cache->doObjectType[cachedTrust]; break;
- case CKO_NETSCAPE_CRL: haveIt = cache->doObjectType[cachedCRLs]; break;
- default: haveIt = PR_FALSE;
- }
- PZ_Unlock(cache->lock);
- return haveIt;
-}
-
-static nssCryptokiObjectAndAttributes **
-create_object_array (
- nssCryptokiObject **objects,
- PRBool *doObjects,
- PRUint32 *numObjects,
- PRStatus *status
-)
-{
- nssCryptokiObjectAndAttributes **rvOandA = NULL;
- *numObjects = 0;
- /* There are no objects for this type */
- if (!objects || !*objects) {
- *status = PR_SUCCESS;
- return rvOandA;
- }
- while (*objects++) (*numObjects)++;
- if (*numObjects >= MAX_LOCAL_CACHE_OBJECTS) {
- /* Hit the maximum allowed, so don't use a cache (there are
- * too many objects to make caching worthwhile, presumably, if
- * the token can handle that many objects, it can handle searching.
- */
- *doObjects = PR_FALSE;
- *status = PR_FAILURE;
- *numObjects = 0;
- } else {
- rvOandA = nss_ZNEWARRAY(NULL,
- nssCryptokiObjectAndAttributes *,
- *numObjects + 1);
- *status = rvOandA ? PR_SUCCESS : PR_FAILURE;
- }
- return rvOandA;
-}
-
-static nssCryptokiObjectAndAttributes *
-create_object (
- nssCryptokiObject *object,
- const CK_ATTRIBUTE_TYPE *types,
- PRUint32 numTypes,
- PRStatus *status
-)
-{
- PRUint32 j;
- NSSArena *arena = NULL;
- NSSSlot *slot = NULL;
- nssSession *session = NULL;
- nssCryptokiObjectAndAttributes *rvCachedObject = NULL;
-
- slot = nssToken_GetSlot(object->token);
- if (!slot) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- goto loser;
- }
- session = nssToken_GetDefaultSession(object->token);
- if (!session) {
- nss_SetError(NSS_ERROR_INVALID_POINTER);
- goto loser;
- }
- arena = nssArena_Create();
- if (!arena) {
- goto loser;
- }
- rvCachedObject = nss_ZNEW(arena, nssCryptokiObjectAndAttributes);
- if (!rvCachedObject) {
- goto loser;
- }
- rvCachedObject->arena = arena;
- /* The cache is tied to the token, and therefore the objects
- * in it should not hold references to the token.
- */
- nssToken_Destroy(object->token);
- rvCachedObject->object = object;
- rvCachedObject->attributes = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, numTypes);
- if (!rvCachedObject->attributes) {
- goto loser;
- }
- for (j=0; j<numTypes; j++) {
- rvCachedObject->attributes[j].type = types[j];
- }
- *status = nssCKObject_GetAttributes(object->handle,
- rvCachedObject->attributes,
- numTypes,
- arena,
- session,
- slot);
- if (*status != PR_SUCCESS) {
- goto loser;
- }
- rvCachedObject->numAttributes = numTypes;
- *status = PR_SUCCESS;
- nssSlot_Destroy(slot);
-
- return rvCachedObject;
-loser:
- *status = PR_FAILURE;
- if (slot) {
- nssSlot_Destroy(slot);
- }
- if (arena)
- nssArena_Destroy(arena);
- return (nssCryptokiObjectAndAttributes *)NULL;
-}
-
-/*
- *
- * State diagram for cache:
- *
- * token !present token removed
- * +-------------------------+<----------------------+
- * | ^ |
- * v | |
- * +----------+ slot friendly | token present +----------+
- * | cache | -----------------> % ---------------> | cache |
- * | unloaded | | loaded |
- * +----------+ +----------+
- * ^ | ^ |
- * | | slot !friendly slot logged in | |
- * | +-----------------------> % ----------------------+ |
- * | | |
- * | slot logged out v slot !friendly |
- * +-----------------------------+<--------------------------+
- *
- */
-
-/* This function must not be called with cache->lock locked. */
-static PRBool
-token_is_present (
- nssTokenObjectCache *cache
-)
-{
- NSSSlot *slot = nssToken_GetSlot(cache->token);
- PRBool tokenPresent = nssSlot_IsTokenPresent(slot);
- nssSlot_Destroy(slot);
- return tokenPresent;
-}
-
-static PRBool
-search_for_objects (
- nssTokenObjectCache *cache
-)
-{
- PRBool doSearch = PR_FALSE;
- NSSSlot *slot = nssToken_GetSlot(cache->token);
- /* Handle non-friendly slots (slots which require login for objects) */
- if (!nssSlot_IsFriendly(slot)) {
- if (nssSlot_IsLoggedIn(slot)) {
- /* Either no state change, or went from !logged in -> logged in */
- cache->loggedIn = PR_TRUE;
- doSearch = PR_TRUE;
- } else {
- if (cache->loggedIn) {
- /* went from logged in -> !logged in, destroy cached objects */
- clear_cache(cache);
- cache->loggedIn = PR_FALSE;
- } /* else no state change, still not logged in, so exit */
- }
- } else {
- /* slot is friendly, thus always available for search */
- doSearch = PR_TRUE;
- }
- nssSlot_Destroy(slot);
- return doSearch;
-}
-
-static nssCryptokiObjectAndAttributes *
-create_cert (
- nssCryptokiObject *object,
- PRStatus *status
-)
-{
- static const CK_ATTRIBUTE_TYPE certAttr[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_LABEL,
- CKA_CERTIFICATE_TYPE,
- CKA_ID,
- CKA_VALUE,
- CKA_ISSUER,
- CKA_SERIAL_NUMBER,
- CKA_SUBJECT,
- CKA_NETSCAPE_EMAIL
- };
- static const PRUint32 numCertAttr = sizeof(certAttr) / sizeof(certAttr[0]);
- return create_object(object, certAttr, numCertAttr, status);
-}
-
-static nssCryptokiObjectAndAttributes *
-create_trust (
- nssCryptokiObject *object,
- PRStatus *status
-)
-{
- static const CK_ATTRIBUTE_TYPE trustAttr[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_LABEL,
- CKA_CERT_SHA1_HASH,
- CKA_CERT_MD5_HASH,
- CKA_ISSUER,
- CKA_SUBJECT,
- CKA_TRUST_SERVER_AUTH,
- CKA_TRUST_CLIENT_AUTH,
- CKA_TRUST_EMAIL_PROTECTION,
- CKA_TRUST_CODE_SIGNING
- };
- static const PRUint32 numTrustAttr = sizeof(trustAttr) / sizeof(trustAttr[0]);
- return create_object(object, trustAttr, numTrustAttr, status);
-}
-
-static nssCryptokiObjectAndAttributes *
-create_crl (
- nssCryptokiObject *object,
- PRStatus *status
-)
-{
- static const CK_ATTRIBUTE_TYPE crlAttr[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_LABEL,
- CKA_VALUE,
- CKA_SUBJECT,
- CKA_NETSCAPE_KRL,
- CKA_NETSCAPE_URL
- };
- static const PRUint32 numCRLAttr = sizeof(crlAttr) / sizeof(crlAttr[0]);
- return create_object(object, crlAttr, numCRLAttr, status);
-}
-
-/* Dispatch to the create function for the object type */
-static nssCryptokiObjectAndAttributes *
-create_object_of_type (
- nssCryptokiObject *object,
- PRUint32 objectType,
- PRStatus *status
-)
-{
- if (objectType == cachedCerts) {
- return create_cert(object, status);
- }
- if (objectType == cachedTrust) {
- return create_trust(object, status);
- }
- if (objectType == cachedCRLs) {
- return create_crl(object, status);
- }
- return (nssCryptokiObjectAndAttributes *)NULL;
-}
-
-static PRStatus
-get_token_objects_for_cache (
- nssTokenObjectCache *cache,
- PRUint32 objectType,
- CK_OBJECT_CLASS objclass
-)
-{
- PRStatus status;
- nssCryptokiObject **objects;
- PRBool *doIt = &cache->doObjectType[objectType];
- PRUint32 i, numObjects;
-
- if (!search_for_objects(cache) ||
- cache->searchedObjectType[objectType] ||
- !cache->doObjectType[objectType])
- {
- /* Either there was a state change that prevents a search
- * (token logged out), or the search was already done,
- * or objects of this type are not being cached.
- */
- return PR_SUCCESS;
- }
- objects = nssToken_FindObjects(cache->token, NULL, objclass,
- nssTokenSearchType_TokenForced,
- MAX_LOCAL_CACHE_OBJECTS, &status);
- if (status != PR_SUCCESS) {
- return status;
- }
- cache->objects[objectType] = create_object_array(objects,
- doIt,
- &numObjects,
- &status);
- if (status != PR_SUCCESS) {
- return status;
- }
- for (i=0; i<numObjects; i++) {
- cache->objects[objectType][i] = create_object_of_type(objects[i],
- objectType,
- &status);
- if (status != PR_SUCCESS) {
- break;
- }
- }
- if (status == PR_SUCCESS) {
- nss_ZFreeIf(objects);
- } else {
- PRUint32 j;
- for (j=0; j<i; j++) {
- /* sigh */
- nssToken_AddRef(cache->objects[objectType][j]->object->token);
- nssArena_Destroy(cache->objects[objectType][j]->arena);
- }
- nss_ZFreeIf(cache->objects[objectType]);
- cache->objects[objectType] = NULL;
- nssCryptokiObjectArray_Destroy(objects);
- }
- cache->searchedObjectType[objectType] = PR_TRUE;
- return status;
-}
-
-static CK_ATTRIBUTE_PTR
-find_attribute_in_object (
- nssCryptokiObjectAndAttributes *obj,
- CK_ATTRIBUTE_TYPE attrType
-)
-{
- PRUint32 j;
- for (j=0; j<obj->numAttributes; j++) {
- if (attrType == obj->attributes[j].type) {
- return &obj->attributes[j];
- }
- }
- return (CK_ATTRIBUTE_PTR)NULL;
-}
-
-/* Find all objects in the array that match the supplied template */
-static nssCryptokiObject **
-find_objects_in_array (
- nssCryptokiObjectAndAttributes **objArray,
- CK_ATTRIBUTE_PTR ot,
- CK_ULONG otlen,
- PRUint32 maximumOpt
-)
-{
- PRIntn oi = 0;
- PRUint32 i;
- NSSArena *arena;
- PRUint32 size = 8;
- PRUint32 numMatches = 0;
- nssCryptokiObject **objects = NULL;
- nssCryptokiObjectAndAttributes **matches = NULL;
- CK_ATTRIBUTE_PTR attr;
-
- if (!objArray) {
- return (nssCryptokiObject **)NULL;
- }
- arena = nssArena_Create();
- if (!arena) {
- return (nssCryptokiObject **)NULL;
- }
- matches = nss_ZNEWARRAY(arena, nssCryptokiObjectAndAttributes *, size);
- if (!matches) {
- goto loser;
- }
- if (maximumOpt == 0) maximumOpt = ~0;
- /* loop over the cached objects */
- for (; *objArray && numMatches < maximumOpt; objArray++) {
- nssCryptokiObjectAndAttributes *obj = *objArray;
- /* loop over the test template */
- for (i=0; i<otlen; i++) {
- /* see if the object has the attribute */
- attr = find_attribute_in_object(obj, ot[i].type);
- if (!attr) {
- /* nope, match failed */
- break;
- }
- /* compare the attribute against the test value */
- if (ot[i].ulValueLen != attr->ulValueLen ||
- !nsslibc_memequal(ot[i].pValue,
- attr->pValue,
- attr->ulValueLen, NULL))
- {
- /* nope, match failed */
- break;
- }
- }
- if (i == otlen) {
- /* all of the attributes in the test template were found
- * in the object's template, and they all matched
- */
- matches[numMatches++] = obj;
- if (numMatches == size) {
- size *= 2;
- matches = nss_ZREALLOCARRAY(matches,
- nssCryptokiObjectAndAttributes *,
- size);
- if (!matches) {
- goto loser;
- }
- }
- }
- }
- if (numMatches > 0) {
- objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numMatches + 1);
- if (!objects) {
- goto loser;
- }
- for (oi=0; oi<(PRIntn)numMatches; oi++) {
- objects[oi] = nssCryptokiObject_Clone(matches[oi]->object);
- if (!objects[oi]) {
- goto loser;
- }
- }
- }
- nssArena_Destroy(arena);
- return objects;
-loser:
- nssCryptokiObjectArray_Destroy(objects);
- nssArena_Destroy(arena);
- return (nssCryptokiObject **)NULL;
-}
-
-NSS_IMPLEMENT nssCryptokiObject **
-nssTokenObjectCache_FindObjectsByTemplate (
- nssTokenObjectCache *cache,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR otemplate,
- CK_ULONG otlen,
- PRUint32 maximumOpt,
- PRStatus *statusOpt
-)
-{
- PRStatus status = PR_FAILURE;
- nssCryptokiObject **rvObjects = NULL;
- PRUint32 objectType;
- if (!token_is_present(cache)) {
- status = PR_SUCCESS;
- goto finish;
- }
- switch (objclass) {
- case CKO_CERTIFICATE: objectType = cachedCerts; break;
- case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break;
- case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break;
- default: goto finish;
- }
- PZ_Lock(cache->lock);
- if (cache->doObjectType[objectType]) {
- status = get_token_objects_for_cache(cache, objectType, objclass);
- if (status == PR_SUCCESS) {
- rvObjects = find_objects_in_array(cache->objects[objectType],
- otemplate, otlen, maximumOpt);
- }
- }
- PZ_Unlock(cache->lock);
-finish:
- if (statusOpt) {
- *statusOpt = status;
- }
- return rvObjects;
-}
-
-static PRBool
-cache_available_for_object_type (
- nssTokenObjectCache *cache,
- PRUint32 objectType
-)
-{
- if (!cache->doObjectType[objectType]) {
- /* not caching this object kind */
- return PR_FALSE;
- }
- if (!cache->searchedObjectType[objectType]) {
- /* objects are not cached yet */
- return PR_FALSE;
- }
- if (!search_for_objects(cache)) {
- /* not logged in */
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-NSS_IMPLEMENT PRStatus
-nssTokenObjectCache_GetObjectAttributes (
- nssTokenObjectCache *cache,
- NSSArena *arenaOpt,
- nssCryptokiObject *object,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR atemplate,
- CK_ULONG atlen
-)
-{
- PRUint32 i, j;
- NSSArena *arena = NULL;
- nssArenaMark *mark = NULL;
- nssCryptokiObjectAndAttributes *cachedOA = NULL;
- nssCryptokiObjectAndAttributes **oa = NULL;
- PRUint32 objectType;
- if (!token_is_present(cache)) {
- return PR_FAILURE;
- }
- PZ_Lock(cache->lock);
- switch (objclass) {
- case CKO_CERTIFICATE: objectType = cachedCerts; break;
- case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break;
- case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break;
- default: goto loser;
- }
- if (!cache_available_for_object_type(cache, objectType)) {
- goto loser;
- }
- oa = cache->objects[objectType];
- if (!oa) {
- goto loser;
- }
- for (; *oa; oa++) {
- if (nssCryptokiObject_Equal((*oa)->object, object)) {
- cachedOA = *oa;
- break;
- }
- }
- if (!cachedOA) {
- goto loser; /* don't have this object */
- }
- if (arenaOpt) {
- arena = arenaOpt;
- mark = nssArena_Mark(arena);
- }
- for (i=0; i<atlen; i++) {
- for (j=0; j<cachedOA->numAttributes; j++) {
- if (atemplate[i].type == cachedOA->attributes[j].type) {
- CK_ATTRIBUTE_PTR attr = &cachedOA->attributes[j];
- if (cachedOA->attributes[j].ulValueLen == 0 ||
- cachedOA->attributes[j].ulValueLen == (CK_ULONG)-1)
- {
- break; /* invalid attribute */
- }
- if (atemplate[i].ulValueLen > 0) {
- if (atemplate[i].pValue == NULL ||
- atemplate[i].ulValueLen < attr->ulValueLen)
- {
- goto loser;
- }
- } else {
- atemplate[i].pValue = nss_ZAlloc(arena, attr->ulValueLen);
- if (!atemplate[i].pValue) {
- goto loser;
- }
- }
- nsslibc_memcpy(atemplate[i].pValue,
- attr->pValue, attr->ulValueLen);
- atemplate[i].ulValueLen = attr->ulValueLen;
- break;
- }
- }
- if (j == cachedOA->numAttributes) {
- atemplate[i].ulValueLen = (CK_ULONG)-1;
- }
- }
- PZ_Unlock(cache->lock);
- if (mark) {
- nssArena_Unmark(arena, mark);
- }
- return PR_SUCCESS;
-loser:
- PZ_Unlock(cache->lock);
- if (mark) {
- nssArena_Release(arena, mark);
- }
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-nssTokenObjectCache_ImportObject (
- nssTokenObjectCache *cache,
- nssCryptokiObject *object,
- CK_OBJECT_CLASS objclass,
- CK_ATTRIBUTE_PTR ot,
- CK_ULONG otlen
-)
-{
- PRStatus status = PR_SUCCESS;
- PRUint32 count;
- nssCryptokiObjectAndAttributes **oa, ***otype;
- PRUint32 objectType;
- PRBool haveIt = PR_FALSE;
-
- if (!token_is_present(cache)) {
- return PR_SUCCESS; /* cache not active, ignored */
- }
- PZ_Lock(cache->lock);
- switch (objclass) {
- case CKO_CERTIFICATE: objectType = cachedCerts; break;
- case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break;
- case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break;
- default:
- PZ_Unlock(cache->lock);
- return PR_SUCCESS; /* don't need to import it here */
- }
- if (!cache_available_for_object_type(cache, objectType)) {
- PZ_Unlock(cache->lock);
- return PR_SUCCESS; /* cache not active, ignored */
- }
- count = 0;
- otype = &cache->objects[objectType]; /* index into array of types */
- oa = *otype; /* the array of objects for this type */
- while (oa && *oa) {
- if (nssCryptokiObject_Equal((*oa)->object, object)) {
- haveIt = PR_TRUE;
- break;
- }
- count++;
- oa++;
- }
- if (haveIt) {
- /* Destroy the old entry */
- (*oa)->object->token = NULL;
- nssCryptokiObject_Destroy((*oa)->object);
- nssArena_Destroy((*oa)->arena);
- } else {
- /* Create space for a new entry */
- if (count > 0) {
- *otype = nss_ZREALLOCARRAY(*otype,
- nssCryptokiObjectAndAttributes *,
- count + 2);
- } else {
- *otype = nss_ZNEWARRAY(NULL, nssCryptokiObjectAndAttributes *, 2);
- }
- }
- if (*otype) {
- nssCryptokiObject *copyObject = nssCryptokiObject_Clone(object);
- (*otype)[count] = create_object_of_type(copyObject, objectType,
- &status);
- } else {
- status = PR_FAILURE;
- }
- PZ_Unlock(cache->lock);
- return status;
-}
-
-NSS_IMPLEMENT void
-nssTokenObjectCache_RemoveObject (
- nssTokenObjectCache *cache,
- nssCryptokiObject *object
-)
-{
- PRUint32 oType;
- nssCryptokiObjectAndAttributes **oa, **swp = NULL;
- if (!token_is_present(cache)) {
- return;
- }
- PZ_Lock(cache->lock);
- for (oType=0; oType<3; oType++) {
- if (!cache_available_for_object_type(cache, oType) ||
- !cache->objects[oType])
- {
- continue;
- }
- for (oa = cache->objects[oType]; *oa; oa++) {
- if (nssCryptokiObject_Equal((*oa)->object, object)) {
- swp = oa; /* the entry to remove */
- while (oa[1]) oa++; /* go to the tail */
- (*swp)->object->token = NULL;
- nssCryptokiObject_Destroy((*swp)->object);
- nssArena_Destroy((*swp)->arena); /* destroy it */
- *swp = *oa; /* swap the last with the removed */
- *oa = NULL; /* null-terminate the array */
- break;
- }
- }
- if (swp) {
- break;
- }
- }
- if ((oType <3) &&
- cache->objects[oType] && cache->objects[oType][0] == NULL) {
- nss_ZFreeIf(cache->objects[oType]); /* no entries remaining */
- cache->objects[oType] = NULL;
- }
- PZ_Unlock(cache->lock);
-}
-
-/* These two hash algorithms are presently sufficient.
-** They are used for fingerprints of certs which are stored as the
-** CKA_CERT_SHA1_HASH and CKA_CERT_MD5_HASH attributes.
-** We don't need to add SHAxxx to these now.
-*/
-/* XXX of course this doesn't belong here */
-NSS_IMPLEMENT NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateSHA1Digest (
- NSSArena *arenaOpt
-)
-{
- NSSAlgorithmAndParameters *rvAP = NULL;
- rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
- if (rvAP) {
- rvAP->mechanism.mechanism = CKM_SHA_1;
- rvAP->mechanism.pParameter = NULL;
- rvAP->mechanism.ulParameterLen = 0;
- }
- return rvAP;
-}
-
-NSS_IMPLEMENT NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateMD5Digest (
- NSSArena *arenaOpt
-)
-{
- NSSAlgorithmAndParameters *rvAP = NULL;
- rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters);
- if (rvAP) {
- rvAP->mechanism.mechanism = CKM_MD5;
- rvAP->mechanism.pParameter = NULL;
- rvAP->mechanism.ulParameterLen = 0;
- }
- return rvAP;
-}
-
diff --git a/security/nss/lib/dev/manifest.mn b/security/nss/lib/dev/manifest.mn
deleted file mode 100644
index 651eabd18..000000000
--- a/security/nss/lib/dev/manifest.mn
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-CORE_DEPTH = ../../..
-
-PRIVATE_EXPORTS = \
- ckhelper.h \
- devm.h \
- devtm.h \
- devt.h \
- dev.h \
- nssdevt.h \
- nssdev.h \
- $(NULL)
-
-EXPORTS = \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- devslot.c \
- devtoken.c \
- devutil.c \
- ckhelper.c \
- $(NULL)
-
-REQUIRES = nspr
-
-LIBRARY_NAME = nssdev
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/dev/nssdev.h b/security/nss/lib/dev/nssdev.h
deleted file mode 100644
index 22845f013..000000000
--- a/security/nss/lib/dev/nssdev.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSDEV_H
-#define NSSDEV_H
-
-#ifdef DEBUG
-static const char NSSDEV_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-/*
- * nssdev.h
- *
- * High-level methods for interaction with cryptoki devices
- */
-
-#ifndef NSSDEVT_H
-#include "nssdevt.h"
-#endif /* NSSDEVT_H */
-
-PR_BEGIN_EXTERN_C
-
-/* NSSAlgorithmAndParameters
- *
- * NSSAlgorithmAndParameters_CreateSHA1Digest
- * NSSAlgorithmAndParameters_CreateMD5Digest
- */
-
-NSS_EXTERN NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateSHA1Digest
-(
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSAlgorithmAndParameters *
-NSSAlgorithmAndParameters_CreateMD5Digest
-(
- NSSArena *arenaOpt
-);
-
-PR_END_EXTERN_C
-
-#endif /* DEV_H */
diff --git a/security/nss/lib/dev/nssdevt.h b/security/nss/lib/dev/nssdevt.h
deleted file mode 100644
index b4eb106bf..000000000
--- a/security/nss/lib/dev/nssdevt.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSDEVT_H
-#define NSSDEVT_H
-
-#ifdef DEBUG
-static const char NSSDEVT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nssdevt.h
- *
- * This file contains definitions for the low-level cryptoki devices.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSPKIT_H
-#include "nsspkit.h"
-#endif /* NSSPKIT_H */
-
-PR_BEGIN_EXTERN_C
-
-/*
- * NSSModule and NSSSlot -- placeholders for the PKCS#11 types
- */
-
-typedef struct NSSModuleStr NSSModule;
-
-typedef struct NSSSlotStr NSSSlot;
-
-typedef struct NSSTokenStr NSSToken;
-
-PR_END_EXTERN_C
-
-#endif /* NSSDEVT_H */
diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile
deleted file mode 100644
index 0d293f14e..000000000
--- a/security/nss/lib/freebl/Makefile
+++ /dev/null
@@ -1,652 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-# default for all platforms
-# unset this on those that have multiple freebl libraries
-FREEBL_BUILD_SINGLE_SHLIB = 1
-
-ifdef USE_64
- DEFINES += -DNSS_USE_64
-endif
-
-ifdef USE_ABI32_FPU
- DEFINES += -DNSS_USE_ABI32_FPU
-endif
-
-ifeq ($(FREEBL_NO_DEPEND),1)
- DEFINES += -DFREEBL_NO_DEPEND
- STUBS_SRCS = stubs.c
-endif
-
-ifeq ($(FREEBL_LOWHASH),1)
- LOWHASH_SRCS = nsslowhash.c
- LOWHASH_EXPORTS = nsslowhash.h
- MAPFILE_SOURCE = freebl_hash.def
-else
- MAPFILE_SOURCE = freebl.def
-endif
-
-# FREEBL_USE_PRELINK
-#
-# Most modern version of Linux support a speed optimization scheme where an
-# application called prelink modifies programs and shared libraries to quickly
-# load if they fit into an already designed address space. In short, prelink
-# scans the list of programs and libraries on your system, assigns them a
-# predefined space in the the address space, then provides the fixups to the
-# library.
-#
-# The modification of the shared library is correctly detected by the freebl
-# FIPS checksum scheme where we check a signed hash of the library against the
-# library itself.
-#
-# The prelink command itself can reverse the process of modification and output
-# the prestine shared library as it was before prelink made it's changes.
-# This option tells Freebl could use prelink to output the original copy of
-# the shared library before prelink modified it.
-#
-# FREEBL_PRELINK_COMMAND
-#
-# This is an optional environment variable which can override the default
-# prelink command. It could be used on systems that did something similiar to
-# prelink but used a different command and syntax. The only requirement is the
-# program must take the library as the last argument, the program must output
-# the original library to standard out, and the program does not need to take
-# any quoted or imbedded spaces in its arguments (except the path to the
-# library itself, which can have imbedded spaces or special characters).
-#
-ifdef FREEBL_USE_PRELINK
- DEFINES += -DFREEBL_USE_PRELINK
-ifdef LINUX
- DEFINES += -D__GNU_SOURCE=1
-endif
-endif
-ifdef FREEBL_PRELINK_COMMAND
- DEFINES +=-DFREEBL_PRELINK_COMMAND=\"$(FREEBL_PRELINK_COMMAND)\"
-endif
-# NSS_X86 means the target is a 32-bits x86 CPU architecture
-# NSS_X64 means the target is a 64-bits 64 CPU architecture
-# NSS_X86_OR_X64 means the target is either x86 or x64
-ifeq (,$(filter-out i386 x386 x86 x86_64,$(CPU_ARCH)))
- DEFINES += -DNSS_X86_OR_X64
-ifdef USE_64
- DEFINES += -DNSS_X64
-else
- DEFINES += -DNSS_X86
-endif
-endif
-
-ifeq ($(OS_TARGET),OSF1)
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_NO_MP_WORD
- MPI_SRCS += mpvalpha.c
-endif
-
-ifeq (OS2,$(OS_TARGET))
- ASFILES = mpi_x86_os2.s
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
- DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
- DEFINES += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
- DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
-endif
-
-ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
-ifndef USE_64
-# 32-bit Windows
-ifdef NS_USE_GCC
-# Ideally, we want to use assembler
-# ASFILES = mpi_x86.s
-# DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE \
-# -DMP_ASSEMBLY_DIV_2DX1D
-# but we haven't figured out how to make it work, so we are not
-# using assembler right now.
- ASFILES =
- DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT
-else
-# MSVC
- MPI_SRCS += mpi_x86_asm.c
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
- DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
- ifdef BUILD_OPT
- OPTIMIZER += -Ox # maximum optimization for freebl
- endif
-endif
-else
- # -DMP_NO_MP_WORD
- DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
-ifdef NS_USE_GCC
-# Ideally, we should use amd64 assembly code, but it's not yet mingw-w64
-# compatible.
-else
-# MSVC
- ifdef BUILD_OPT
- OPTIMIZER += -Ox # maximum optimization for freebl
- endif
- ASFILES = arcfour-amd64-masm.asm mpi_amd64_masm.asm mp_comba_amd64_masm.asm
- DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
- DEFINES += -DNSS_USE_COMBA
- MPI_SRCS += mpi_amd64.c
-endif
-endif
-endif
-
-ifeq ($(OS_TARGET),IRIX)
-ifeq ($(USE_N32),1)
- ASFILES = mpi_mips.s
- ifeq ($(NS_USE_GCC),1)
- ASFLAGS = -Wp,-P -Wp,-traditional -O -mips3
- else
- ASFLAGS = -O -OPT:Olimit=4000 -dollar -fullwarn -xansi -n32 -mips3
- endif
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
- DEFINES += -DMP_USE_UINT_DIGIT
-endif
-endif
-
-ifeq ($(OS_TARGET),Darwin)
-ifeq ($(CPU_ARCH),x86)
- ASFILES = mpi_sse2.s
- DEFINES += -DMP_USE_UINT_DIGIT
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
- DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
-endif
-endif # Darwin
-
-ifeq ($(OS_TARGET),Linux)
-ifeq ($(CPU_ARCH),x86_64)
- ASFILES = arcfour-amd64-gas.s mpi_amd64_gas.s
- ASFLAGS += -m64 -fPIC -Wa,--noexecstack
- DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
- DEFINES += -DNSS_USE_COMBA
- DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
-# DEFINES += -DMPI_AMD64_ADD
- # comment the next two lines to turn off intel HW accelleration
- DEFINES += -DUSE_HW_AES
- ASFILES += intel-aes.s intel-gcm.s
- EXTRA_SRCS += intel-gcm-wrap.c
- INTEL_GCM = 1
- MPI_SRCS += mpi_amd64.c mp_comba.c
-endif
-ifeq ($(CPU_ARCH),x86)
- ASFILES = mpi_x86.s
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
- DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
- DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
- # The floating point ECC code doesn't work on Linux x86 (bug 311432).
- #ECL_USE_FP = 1
-endif
-ifeq ($(CPU_ARCH),arm)
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
- DEFINES += -DMP_USE_UINT_DIGIT
- DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
- MPI_SRCS += mpi_arm.c
-endif
-endif # Linux
-
-ifeq ($(OS_TARGET),AIX)
- DEFINES += -DMP_USE_UINT_DIGIT
- ifndef USE_64
- DEFINES += -DMP_NO_DIV_WORD -DMP_NO_ADD_WORD -DMP_NO_SUB_WORD
- endif
-endif # AIX
-
-ifeq ($(OS_TARGET), HP-UX)
-ifneq ($(OS_TEST), ia64)
-# PA-RISC
-ASFILES += ret_cr16.s
-ifndef USE_64
- FREEBL_BUILD_SINGLE_SHLIB =
- HAVE_ABI32_INT32 = 1
- HAVE_ABI32_FPU = 1
-endif
-ifdef FREEBL_CHILD_BUILD
-ifdef USE_ABI32_INT32
-# build for DA1.1 (HP PA 1.1) 32-bit ABI build with 32-bit arithmetic
- DEFINES += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
- DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
-else
-ifdef USE_64
-# this builds for DA2.0W (HP PA 2.0 Wide), the LP64 ABI, using 64-bit digits
- MPI_SRCS += mpi_hp.c
- ASFILES += hpma512.s hppa20.s
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
-else
-# this builds for DA2.0 (HP PA 2.0 Narrow) ABI32_FPU model
-# (the 32-bit ABI with 64-bit registers) using 64-bit digits
- MPI_SRCS += mpi_hp.c
- ASFILES += hpma512.s hppa20.s
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
-ifndef NS_USE_GCC
- ARCHFLAG = -Aa +e +DA2.0 +DS2.0
-endif
-endif
-endif
-endif
-endif
-endif
-
-# The blapi functions are defined not only in the freebl shared
-# libraries but also in the shared libraries linked with loader.c
-# (libsoftokn3.so and libssl3.so). We need to use GNU ld's
-# -Bsymbolic option or the equivalent option for other linkers
-# to bind the blapi function references in FREEBLVector vector
-# (ldvector.c) to the blapi functions defined in the freebl
-# shared libraries.
-ifeq (,$(filter-out BSD_OS FreeBSD Linux NetBSD OpenBSD, $(OS_TARGET)))
- MKSHLIB += -Wl,-Bsymbolic
-endif
-
-ifeq ($(OS_TARGET),SunOS)
-
-ifdef NS_USE_GCC
- ifdef GCC_USE_GNU_LD
- MKSHLIB += -Wl,-Bsymbolic,-z,now,-z,text
- else
- MKSHLIB += -Wl,-B,symbolic,-z,now,-z,text
- endif # GCC_USE_GNU_LD
-else
- MKSHLIB += -B symbolic -z now -z text
-endif # NS_USE_GCC
-
-# Sun's WorkShop defines v8, v8plus and v9 architectures.
-# gcc on Solaris defines v8 and v9 "cpus".
-# gcc's v9 is equivalent to Workshop's v8plus.
-# gcc's -m64 is equivalent to Workshop's v9
-# We always use Sun's assembler, which uses Sun's naming convention.
-ifeq ($(CPU_ARCH),sparc)
- FREEBL_BUILD_SINGLE_SHLIB=
- ifdef USE_64
- HAVE_ABI64_INT = 1
- HAVE_ABI64_FPU = 1
- else
- HAVE_ABI32_FPU = 1
- HAVE_ABI32_INT64 = 1
- endif
- SYSV_SPARC = 1
- SOLARIS_AS = /usr/ccs/bin/as
- #### set arch, asm, c flags
- ifdef NS_USE_GCC
- ifdef USE_ABI32_INT64
- ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plus
- SOLARIS_AS_FLAGS = -xarch=v8plus -K PIC
- endif
- ifdef USE_ABI32_FPU
- ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plusa
- SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC
- endif # USE_ABI32_FPU
- ifdef USE_ABI64_INT
- # this builds for Sparc v9a pure 64-bit architecture
- ARCHFLAG += -mcpu=v9 -Wa,-xarch=v9
- SOLARIS_AS_FLAGS = -xarch=v9 -K PIC
- endif
- ifdef USE_ABI64_FPU
- # this builds for Sparc v9a pure 64-bit architecture
- # It uses floating point, and 32-bit word size
- ARCHFLAG += -mcpu=v9 -Wa,-xarch=v9a
- SOLARIS_AS_FLAGS = -xarch=v9a -K PIC
- endif
- else # NS_USE_GCC
- # FPU_TARGET_OPTIMIZER specifies the target processor and cache
- # properties of the ABI32_FPU and ABI64_FPU architectures for use
- # by the optimizer.
- ifeq (,$(findstring Sun WorkShop 6,$(shell $(CC) -V 2>&1)))
- # if the compiler is not Forte 6
- FPU_TARGET_OPTIMIZER = -xcache=64/32/4:1024/64/4 -xchip=ultra3
- else
- # Forte 6 C compiler generates incorrect code for rijndael.c
- # if -xchip=ultra3 is used (Bugzilla bug 333925). So we revert
- # to what we used in NSS 3.10.
- FPU_TARGET_OPTIMIZER = -xchip=ultra2
- endif
- ifdef USE_ABI32_INT64
- # this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
- # 32-bit ABI, it uses 64-bit words, integer arithmetic,
- # no FPU (non-VIS cpus).
- # These flags were suggested by the compiler group for building
- # with SunStudio 10.
- ifdef BUILD_OPT
- SOL_CFLAGS += -xO4
- endif
- SOL_CFLAGS += -xtarget=generic
- ARCHFLAG = -xarch=v8plus
- SOLARIS_AS_FLAGS = -xarch=v8plus -K PIC
- endif
- ifdef USE_ABI32_FPU
- # this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
- # 32-bit ABI, it uses FPU code, and 32-bit word size.
- # these flags were determined by running cc -### -fast and copying
- # the generated flag settings
- SOL_CFLAGS += -fsingle -xmemalign=8s
- ifdef BUILD_OPT
- SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fsimple=1
- SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all
- SOL_CFLAGS += $(FPU_TARGET_OPTIMIZER) -xdepend
- SOL_CFLAGS += -xlibmil -xO5
- endif
- ARCHFLAG = -xarch=v8plusa
- SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC
- endif
- ifdef USE_ABI64_INT
- # this builds for Sparc v9a pure 64-bit architecture,
- # no FPU (non-VIS cpus). For building with SunStudio 10.
- ifdef BUILD_OPT
- SOL_CFLAGS += -xO4
- endif
- SOL_CFLAGS += -xtarget=generic
- ARCHFLAG = -xarch=v9
- SOLARIS_AS_FLAGS = -xarch=v9 -K PIC
- endif
- ifdef USE_ABI64_FPU
- # this builds for Sparc v9a pure 64-bit architecture
- # It uses floating point, and 32-bit word size.
- # See comment for USE_ABI32_FPU.
- SOL_CFLAGS += -fsingle -xmemalign=8s
- ifdef BUILD_OPT
- SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fsimple=1
- SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all
- SOL_CFLAGS += $(FPU_TARGET_OPTIMIZER) -xdepend
- SOL_CFLAGS += -xlibmil -xO5
- endif
- ARCHFLAG = -xarch=v9a
- SOLARIS_AS_FLAGS = -xarch=v9a -K PIC
- endif
- endif # NS_USE_GCC
-
- ### set flags for both GCC and Sun cc
- ifdef USE_ABI32_INT64
- # this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
- # 32-bit ABI, it uses 64-bit words, integer arithmetic, no FPU
- # best times are with no MP_ flags specified
- endif
- ifdef USE_ABI32_FPU
- # this builds for Sparc v8+a ABI32_FPU architecture, 64-bit registers,
- # 32-bit ABI, it uses FPU code, and 32-bit word size
- MPI_SRCS += mpi_sparc.c
- ASFILES = mpv_sparcv8.s montmulfv8.s
- DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY
- DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL
- ECL_USE_FP = 1
- endif
- ifdef USE_ABI64_INT
- # this builds for Sparc v9a pure 64-bit architecture
- # best times are with no MP_ flags specified
- endif
- ifdef USE_ABI64_FPU
- # this builds for Sparc v9a pure 64-bit architecture
- # It uses floating point, and 32-bit word size
- MPI_SRCS += mpi_sparc.c
- ASFILES = mpv_sparcv9.s montmulfv9.s
- DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY
- DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL
- ECL_USE_FP = 1
- endif
-
-else
- # Solaris for non-sparc family CPUs
- ifdef NS_USE_GCC
- LD = gcc
- AS = gcc
- ASFLAGS = -x assembler-with-cpp
- endif
- ifeq ($(USE_64),1)
- # Solaris for AMD64
- ifdef NS_USE_GCC
- ASFILES = arcfour-amd64-gas.s mpi_amd64_gas.s
- ASFLAGS += -march=opteron -m64 -fPIC
- MPI_SRCS += mp_comba.c
- else
- ASFILES = arcfour-amd64-sun.s mpi_amd64_sun.s sha-fast-amd64-sun.s
- ASFILES += mp_comba_amd64_sun.s mpcpucache_amd64.s
- ASFLAGS += -xarch=generic64 -K PIC
- SOL_CFLAGS += -xprefetch=no
- SHA_SRCS =
- MPCPU_SRCS =
- endif
- DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
- DEFINES += -DNSS_USE_COMBA -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
- # comment the next two lines to turn off intel HW accelleration
- DEFINES += -DUSE_HW_AES
- ASFILES += intel-aes.s intel-gcm.s
- EXTRA_SRCS += intel-gcm-wrap.c
- INTEL_GCM = 1
- MPI_SRCS += mpi_amd64.c
- else
- # Solaris x86
- DEFINES += -DMP_USE_UINT_DIGIT
- DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
- DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
- ASFILES = mpi_i86pc.s
- ifndef NS_USE_GCC
- MPCPU_SRCS =
- ASFILES += mpcpucache_x86.s
- endif
- endif
-endif # Solaris for non-sparc family CPUs
-endif # target == SunOS
-
-ifdef NSS_ENABLE_ECC
- ifdef ECL_USE_FP
- #enable floating point ECC code
- DEFINES += -DECL_USE_FP
- ECL_SRCS += ecp_fp160.c ecp_fp192.c ecp_fp224.c ecp_fp.c
- ECL_HDRS += ecp_fp.h
- endif
-endif # NSS_ENABLE_ECC
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
-rijndael_tables:
- $(CC) -o $(OBJDIR)/make_rijndael_tab rijndael_tables.c \
- $(DEFINES) $(INCLUDES) $(OBJDIR)/libfreebl.a
- $(OBJDIR)/make_rijndael_tab
-
-vpath %.h mpi ecl
-vpath %.c mpi ecl
-vpath %.S mpi ecl
-vpath %.s mpi ecl
-vpath %.asm mpi ecl
-INCLUDES += -Impi -Iecl
-
-
-DEFINES += -DMP_API_COMPATIBLE
-
-MPI_USERS = dh.c pqg.c dsa.c rsa.c ec.c
-
-MPI_OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_SRCS:.c=$(OBJ_SUFFIX)))
-MPI_OBJS += $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(MPI_USERS:.c=$(OBJ_SUFFIX)))
-
-$(MPI_OBJS): $(MPI_HDRS)
-
-ECL_USERS = ec.c
-
-ECL_OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(ECL_SRCS:.c=$(OBJ_SUFFIX)) $(ECL_ASM_SRCS:$(ASM_SUFFIX)=$(OBJ_SUFFIX)))
-ECL_OBJS += $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(ECL_USERS:.c=$(OBJ_SUFFIX)))
-
-$(ECL_OBJS): $(ECL_HDRS)
-
-
-
-$(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c os2_rand.c
-
-$(OBJDIR)/$(PROG_PREFIX)mpprime$(OBJ_SUFFIX): primes.c
-
-$(OBJDIR)/ldvector$(OBJ_SUFFIX) $(OBJDIR)/loader$(OBJ_SUFFIX) : loader.h
-
-ifeq ($(SYSV_SPARC),1)
-
-$(OBJDIR)/mpv_sparcv8.o $(OBJDIR)/mpv_sparcv8x.o $(OBJDIR)/montmulfv8.o : $(OBJDIR)/%.o : %.s
- @$(MAKE_OBJDIR)
- $(SOLARIS_AS) -o $@ $(SOLARIS_AS_FLAGS) $<
-
-$(OBJDIR)/mpv_sparcv9.o $(OBJDIR)/montmulfv9.o : $(OBJDIR)/%.o : %.s
- @$(MAKE_OBJDIR)
- $(SOLARIS_AS) -o $@ $(SOLARIS_AS_FLAGS) $<
-
-$(OBJDIR)/mpmontg.o: mpmontg.c montmulf.h
-
-endif
-
-ifndef FREEBL_CHILD_BUILD
-
-# Parent build. This is where we decide which shared libraries to build
-
-ifdef FREEBL_BUILD_SINGLE_SHLIB
-
-################### Single shared lib stuff #########################
-SINGLE_SHLIB_DIR = $(OBJDIR)/$(OS_TARGET)_SINGLE_SHLIB
-ALL_TRASH += $(SINGLE_SHLIB_DIR)
-
-$(SINGLE_SHLIB_DIR):
- -mkdir $(SINGLE_SHLIB_DIR)
-
-release_md libs:: $(SINGLE_SHLIB_DIR)
- $(MAKE) FREEBL_CHILD_BUILD=1 \
- OBJDIR=$(SINGLE_SHLIB_DIR) $@
-######################## common stuff #########################
-
-endif
-
-# multiple shared libraries
-
-######################## ABI32_FPU stuff #########################
-ifdef HAVE_ABI32_FPU
-ABI32_FPU_DIR = $(OBJDIR)/$(OS_TARGET)_ABI32_FPU
-ALL_TRASH += $(ABI32_FPU_DIR)
-
-$(ABI32_FPU_DIR):
- -mkdir $(ABI32_FPU_DIR)
-
-release_md libs:: $(ABI32_FPU_DIR)
- $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI32_FPU=1 \
- OBJDIR=$(ABI32_FPU_DIR) $@
-endif
-
-######################## ABI32_INT32 stuff #########################
-ifdef HAVE_ABI32_INT32
-ABI32_INT32_DIR = $(OBJDIR)/$(OS_TARGET)_ABI32_INT32
-ALL_TRASH += $(ABI32_INT32_DIR)
-
-$(ABI32_INT32_DIR):
- -mkdir $(ABI32_INT32_DIR)
-
-release_md libs:: $(ABI32_INT32_DIR)
- $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI32_INT32=1 \
- OBJDIR=$(ABI32_INT32_DIR) $@
-endif
-
-######################## ABI32_INT64 stuff #########################
-ifdef HAVE_ABI32_INT64
-ABI32_INT64_DIR = $(OBJDIR)/$(OS_TARGET)_ABI32_INT64
-ALL_TRASH += $(ABI32_INT64_DIR)
-
-$(ABI32_INT64_DIR):
- -mkdir $(ABI32_INT64_DIR)
-
-release_md libs:: $(ABI32_INT64_DIR)
- $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI32_INT64=1\
- OBJDIR=$(ABI32_INT64_DIR) $@
-endif
-
-######################## END of 32-bit stuff #########################
-
-# above is 32-bit builds, below is 64-bit builds
-
-######################## ABI64_FPU stuff #########################
-ifdef HAVE_ABI64_FPU
-ABI64_FPU_DIR = $(OBJDIR)/$(OS_TARGET)_ABI64_FPU
-ALL_TRASH += $(ABI64_FPU_DIR)
-
-$(ABI64_FPU_DIR):
- -mkdir $(ABI64_FPU_DIR)
-
-release_md libs:: $(ABI64_FPU_DIR)
- $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI64_FPU=1 \
- OBJDIR=$(ABI64_FPU_DIR) $@
-endif
-
-######################## ABI64_INT stuff #########################
-ifdef HAVE_ABI64_INT
-ABI64_INT_DIR = $(OBJDIR)/$(OS_TARGET)_ABI64_INT
-ALL_TRASH += $(ABI64_INT_DIR)
-
-$(ABI64_INT_DIR):
- -mkdir $(ABI64_INT_DIR)
-
-release_md libs:: $(ABI64_INT_DIR)
- $(MAKE) FREEBL_CHILD_BUILD=1 USE_ABI64_INT=1 \
- OBJDIR=$(ABI64_INT_DIR) $@
-endif
-
-endif # FREEBL_CHILD_BUILD
-
-
-# Bugzilla Bug 333917: the non-x86 code in desblapi.c seems to violate
-# ANSI C's strict aliasing rules.
-ifeq ($(OS_TARGET),Linux)
-ifneq ($(CPU_ARCH),x86)
-$(OBJDIR)/$(PROG_PREFIX)desblapi$(OBJ_SUFFIX): desblapi.c
- @$(MAKE_OBJDIR)
-ifdef NEED_ABSOLUTE_PATH
- $(CC) -o $@ -c $(CFLAGS) -fno-strict-aliasing $(call core_abspath,$<)
-else
- $(CC) -o $@ -c $(CFLAGS) -fno-strict-aliasing $<
-endif
-endif
-endif
-
-ifdef INTEL_GCM
-#
-# GCM binary needs -mssse3
-#
-$(OBJDIR)/$(PROG_PREFIX)intel-gcm-wrap$(OBJ_SUFFIX): CFLAGS += -mssse3
-
-# The integrated assembler in Clang 3.2 does not support % in the
-# expression of a .set directive. intel-gcm.s uses .set to give
-# symbolic names to registers, for example,
-# .set Htbl, %rdi
-# So we can't use Clang's integrated assembler with intel-gcm.s.
-ifneq (,$(findstring clang,$(AS)))
-$(OBJDIR)/$(PROG_PREFIX)intel-gcm$(OBJ_SUFFIX): ASFLAGS += -no-integrated-as
-endif
-endif
diff --git a/security/nss/lib/freebl/aeskeywrap.c b/security/nss/lib/freebl/aeskeywrap.c
deleted file mode 100644
index 983da4ddb..000000000
--- a/security/nss/lib/freebl/aeskeywrap.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * aeskeywrap.c - implement AES Key Wrap algorithm from RFC 3394
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prcpucfg.h"
-#if defined(IS_LITTLE_ENDIAN) || defined(SHA_NO_LONG_LONG)
-#define BIG_ENDIAN_WITH_64_BIT_REGISTERS 0
-#else
-#define BIG_ENDIAN_WITH_64_BIT_REGISTERS 1
-#endif
-#include "prtypes.h" /* for PRUintXX */
-#include "secport.h" /* for PORT_XXX */
-#include "secerr.h"
-#include "blapi.h" /* for AES_ functions */
-#include "rijndael.h"
-
-struct AESKeyWrapContextStr {
- unsigned char iv[AES_KEY_WRAP_IV_BYTES];
- AESContext aescx;
-};
-
-/******************************************/
-/*
-** AES key wrap algorithm, RFC 3394
-*/
-
-AESKeyWrapContext *
-AESKeyWrap_AllocateContext(void)
-{
- AESKeyWrapContext * cx = PORT_New(AESKeyWrapContext);
- return cx;
-}
-
-SECStatus
-AESKeyWrap_InitContext(AESKeyWrapContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int x1,
- unsigned int encrypt,
- unsigned int x2)
-{
- SECStatus rv = SECFailure;
- if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (iv) {
- memcpy(cx->iv, iv, sizeof cx->iv);
- } else {
- memset(cx->iv, 0xA6, sizeof cx->iv);
- }
- rv = AES_InitContext(&cx->aescx, key, keylen, NULL, NSS_AES, encrypt,
- AES_BLOCK_SIZE);
- return rv;
-}
-
-/*
-** Create a new AES context suitable for AES encryption/decryption.
-** "key" raw key data
-** "keylen" the number of bytes of key data (16, 24, or 32)
-*/
-extern AESKeyWrapContext *
-AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv,
- int encrypt, unsigned int keylen)
-{
- SECStatus rv;
- AESKeyWrapContext * cx = AESKeyWrap_AllocateContext();
- if (!cx)
- return NULL; /* error is already set */
- rv = AESKeyWrap_InitContext(cx, key, keylen, iv, 0, encrypt, 0);
- if (rv != SECSuccess) {
- PORT_Free(cx);
- cx = NULL; /* error should already be set */
- }
- return cx;
-}
-
-/*
-** Destroy a AES KeyWrap context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void
-AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit)
-{
- if (cx) {
- AES_DestroyContext(&cx->aescx, PR_FALSE);
-/* memset(cx, 0, sizeof *cx); */
- if (freeit)
- PORT_Free(cx);
- }
-}
-
-#if !BIG_ENDIAN_WITH_64_BIT_REGISTERS
-
-/* The AES Key Wrap algorithm has 64-bit values that are ALWAYS big-endian
-** (Most significant byte first) in memory. The only ALU operations done
-** on them are increment, decrement, and XOR. So, on little-endian CPUs,
-** and on CPUs that lack 64-bit registers, these big-endian 64-bit operations
-** are simulated in the following code. This is thought to be faster and
-** simpler than trying to convert the data to little-endian and back.
-*/
-
-/* A and T point to two 64-bit values stored most signficant byte first
-** (big endian). This function increments the 64-bit value T, and then
-** XORs it with A, changing A.
-*/
-static void
-increment_and_xor(unsigned char *A, unsigned char *T)
-{
- if (!++T[7])
- if (!++T[6])
- if (!++T[5])
- if (!++T[4])
- if (!++T[3])
- if (!++T[2])
- if (!++T[1])
- ++T[0];
-
- A[0] ^= T[0];
- A[1] ^= T[1];
- A[2] ^= T[2];
- A[3] ^= T[3];
- A[4] ^= T[4];
- A[5] ^= T[5];
- A[6] ^= T[6];
- A[7] ^= T[7];
-}
-
-/* A and T point to two 64-bit values stored most signficant byte first
-** (big endian). This function XORs T with A, giving a new A, then
-** decrements the 64-bit value T.
-*/
-static void
-xor_and_decrement(unsigned char *A, unsigned char *T)
-{
- A[0] ^= T[0];
- A[1] ^= T[1];
- A[2] ^= T[2];
- A[3] ^= T[3];
- A[4] ^= T[4];
- A[5] ^= T[5];
- A[6] ^= T[6];
- A[7] ^= T[7];
-
- if (!T[7]--)
- if (!T[6]--)
- if (!T[5]--)
- if (!T[4]--)
- if (!T[3]--)
- if (!T[2]--)
- if (!T[1]--)
- T[0]--;
-
-}
-
-/* Given an unsigned long t (in host byte order), store this value as a
-** 64-bit big-endian value (MSB first) in *pt.
-*/
-static void
-set_t(unsigned char *pt, unsigned long t)
-{
- pt[7] = (unsigned char)t; t >>= 8;
- pt[6] = (unsigned char)t; t >>= 8;
- pt[5] = (unsigned char)t; t >>= 8;
- pt[4] = (unsigned char)t; t >>= 8;
- pt[3] = (unsigned char)t; t >>= 8;
- pt[2] = (unsigned char)t; t >>= 8;
- pt[1] = (unsigned char)t; t >>= 8;
- pt[0] = (unsigned char)t;
-}
-
-#endif
-
-/*
-** Perform AES key wrap.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus
-AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *pOutputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- PRUint64 * R = NULL;
- unsigned int nBlocks;
- unsigned int i, j;
- unsigned int aesLen = AES_BLOCK_SIZE;
- unsigned int outLen = inputLen + AES_KEY_WRAP_BLOCK_SIZE;
- SECStatus s = SECFailure;
- /* These PRUint64s are ALWAYS big endian, regardless of CPU orientation. */
- PRUint64 t;
- PRUint64 B[2];
-
-#define A B[0]
-
- /* Check args */
- if (!inputLen || 0 != inputLen % AES_KEY_WRAP_BLOCK_SIZE) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return s;
- }
-#ifdef maybe
- if (!output && pOutputLen) { /* caller is asking for output size */
- *pOutputLen = outLen;
- return SECSuccess;
- }
-#endif
- if (maxOutputLen < outLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return s;
- }
- if (cx == NULL || output == NULL || input == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return s;
- }
- nBlocks = inputLen / AES_KEY_WRAP_BLOCK_SIZE;
- R = PORT_NewArray(PRUint64, nBlocks + 1);
- if (!R)
- return s; /* error is already set. */
- /*
- ** 1) Initialize variables.
- */
- memcpy(&A, cx->iv, AES_KEY_WRAP_IV_BYTES);
- memcpy(&R[1], input, inputLen);
-#if BIG_ENDIAN_WITH_64_BIT_REGISTERS
- t = 0;
-#else
- memset(&t, 0, sizeof t);
-#endif
- /*
- ** 2) Calculate intermediate values.
- */
- for (j = 0; j < 6; ++j) {
- for (i = 1; i <= nBlocks; ++i) {
- B[1] = R[i];
- s = AES_Encrypt(&cx->aescx, (unsigned char *)B, &aesLen,
- sizeof B, (unsigned char *)B, sizeof B);
- if (s != SECSuccess)
- break;
- R[i] = B[1];
- /* here, increment t and XOR A with t (in big endian order); */
-#if BIG_ENDIAN_WITH_64_BIT_REGISTERS
- A ^= ++t;
-#else
- increment_and_xor((unsigned char *)&A, (unsigned char *)&t);
-#endif
- }
- }
- /*
- ** 3) Output the results.
- */
- if (s == SECSuccess) {
- R[0] = A;
- memcpy(output, &R[0], outLen);
- if (pOutputLen)
- *pOutputLen = outLen;
- } else if (pOutputLen) {
- *pOutputLen = 0;
- }
- PORT_ZFree(R, outLen);
- return s;
-}
-#undef A
-
-/*
-** Perform AES key unwrap.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus
-AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *pOutputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- PRUint64 * R = NULL;
- unsigned int nBlocks;
- unsigned int i, j;
- unsigned int aesLen = AES_BLOCK_SIZE;
- unsigned int outLen;
- SECStatus s = SECFailure;
- /* These PRUint64s are ALWAYS big endian, regardless of CPU orientation. */
- PRUint64 t;
- PRUint64 B[2];
-
-#define A B[0]
-
- /* Check args */
- if (inputLen < 3 * AES_KEY_WRAP_BLOCK_SIZE ||
- 0 != inputLen % AES_KEY_WRAP_BLOCK_SIZE) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return s;
- }
- outLen = inputLen - AES_KEY_WRAP_BLOCK_SIZE;
-#ifdef maybe
- if (!output && pOutputLen) { /* caller is asking for output size */
- *pOutputLen = outLen;
- return SECSuccess;
- }
-#endif
- if (maxOutputLen < outLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return s;
- }
- if (cx == NULL || output == NULL || input == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return s;
- }
- nBlocks = inputLen / AES_KEY_WRAP_BLOCK_SIZE;
- R = PORT_NewArray(PRUint64, nBlocks);
- if (!R)
- return s; /* error is already set. */
- nBlocks--;
- /*
- ** 1) Initialize variables.
- */
- memcpy(&R[0], input, inputLen);
- A = R[0];
-#if BIG_ENDIAN_WITH_64_BIT_REGISTERS
- t = 6UL * nBlocks;
-#else
- set_t((unsigned char *)&t, 6UL * nBlocks);
-#endif
- /*
- ** 2) Calculate intermediate values.
- */
- for (j = 0; j < 6; ++j) {
- for (i = nBlocks; i; --i) {
- /* here, XOR A with t (in big endian order) and decrement t; */
-#if BIG_ENDIAN_WITH_64_BIT_REGISTERS
- A ^= t--;
-#else
- xor_and_decrement((unsigned char *)&A, (unsigned char *)&t);
-#endif
- B[1] = R[i];
- s = AES_Decrypt(&cx->aescx, (unsigned char *)B, &aesLen,
- sizeof B, (unsigned char *)B, sizeof B);
- if (s != SECSuccess)
- break;
- R[i] = B[1];
- }
- }
- /*
- ** 3) Output the results.
- */
- if (s == SECSuccess) {
- int bad = memcmp(&A, cx->iv, AES_KEY_WRAP_IV_BYTES);
- if (!bad) {
- memcpy(output, &R[1], outLen);
- if (pOutputLen)
- *pOutputLen = outLen;
- } else {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- if (pOutputLen)
- *pOutputLen = 0;
- }
- } else if (pOutputLen) {
- *pOutputLen = 0;
- }
- PORT_ZFree(R, inputLen);
- return s;
-}
-#undef A
diff --git a/security/nss/lib/freebl/alg2268.c b/security/nss/lib/freebl/alg2268.c
deleted file mode 100644
index b607ec74c..000000000
--- a/security/nss/lib/freebl/alg2268.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * alg2268.c - implementation of the algorithm in RFC 2268
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "blapi.h"
-#include "secerr.h"
-#ifdef XP_UNIX_XXX
-#include <stddef.h> /* for ptrdiff_t */
-#endif
-
-/*
-** RC2 symmetric block cypher
-*/
-
-typedef SECStatus (rc2Func)(RC2Context *cx, unsigned char *output,
- const unsigned char *input, unsigned int inputLen);
-
-/* forward declarations */
-static rc2Func rc2_EncryptECB;
-static rc2Func rc2_DecryptECB;
-static rc2Func rc2_EncryptCBC;
-static rc2Func rc2_DecryptCBC;
-
-typedef union {
- PRUint32 l[2];
- PRUint16 s[4];
- PRUint8 b[8];
-} RC2Block;
-
-struct RC2ContextStr {
- union {
- PRUint8 Kb[128];
- PRUint16 Kw[64];
- } u;
- RC2Block iv;
- rc2Func *enc;
- rc2Func *dec;
-};
-
-#define B u.Kb
-#define K u.Kw
-#define BYTESWAP(x) ((x) << 8 | (x) >> 8)
-#define SWAPK(i) cx->K[i] = (tmpS = cx->K[i], BYTESWAP(tmpS))
-#define RC2_BLOCK_SIZE 8
-
-#define LOAD_HARD(R) \
- R[0] = (PRUint16)input[1] << 8 | input[0]; \
- R[1] = (PRUint16)input[3] << 8 | input[2]; \
- R[2] = (PRUint16)input[5] << 8 | input[4]; \
- R[3] = (PRUint16)input[7] << 8 | input[6];
-#define LOAD_EASY(R) \
- R[0] = ((PRUint16 *)input)[0]; \
- R[1] = ((PRUint16 *)input)[1]; \
- R[2] = ((PRUint16 *)input)[2]; \
- R[3] = ((PRUint16 *)input)[3];
-#define STORE_HARD(R) \
- output[0] = (PRUint8)(R[0]); output[1] = (PRUint8)(R[0] >> 8); \
- output[2] = (PRUint8)(R[1]); output[3] = (PRUint8)(R[1] >> 8); \
- output[4] = (PRUint8)(R[2]); output[5] = (PRUint8)(R[2] >> 8); \
- output[6] = (PRUint8)(R[3]); output[7] = (PRUint8)(R[3] >> 8);
-#define STORE_EASY(R) \
- ((PRUint16 *)output)[0] = R[0]; \
- ((PRUint16 *)output)[1] = R[1]; \
- ((PRUint16 *)output)[2] = R[2]; \
- ((PRUint16 *)output)[3] = R[3];
-
-#if defined (NSS_X86_OR_X64)
-#define LOAD(R) LOAD_EASY(R)
-#define STORE(R) STORE_EASY(R)
-#elif !defined(IS_LITTLE_ENDIAN)
-#define LOAD(R) LOAD_HARD(R)
-#define STORE(R) STORE_HARD(R)
-#else
-#define LOAD(R) if ((ptrdiff_t)input & 1) { LOAD_HARD(R) } else { LOAD_EASY(R) }
-#define STORE(R) if ((ptrdiff_t)input & 1) { STORE_HARD(R) } else { STORE_EASY(R) }
-#endif
-
-static const PRUint8 S[256] = {
-0331,0170,0371,0304,0031,0335,0265,0355,0050,0351,0375,0171,0112,0240,0330,0235,
-0306,0176,0067,0203,0053,0166,0123,0216,0142,0114,0144,0210,0104,0213,0373,0242,
-0027,0232,0131,0365,0207,0263,0117,0023,0141,0105,0155,0215,0011,0201,0175,0062,
-0275,0217,0100,0353,0206,0267,0173,0013,0360,0225,0041,0042,0134,0153,0116,0202,
-0124,0326,0145,0223,0316,0140,0262,0034,0163,0126,0300,0024,0247,0214,0361,0334,
-0022,0165,0312,0037,0073,0276,0344,0321,0102,0075,0324,0060,0243,0074,0266,0046,
-0157,0277,0016,0332,0106,0151,0007,0127,0047,0362,0035,0233,0274,0224,0103,0003,
-0370,0021,0307,0366,0220,0357,0076,0347,0006,0303,0325,0057,0310,0146,0036,0327,
-0010,0350,0352,0336,0200,0122,0356,0367,0204,0252,0162,0254,0065,0115,0152,0052,
-0226,0032,0322,0161,0132,0025,0111,0164,0113,0237,0320,0136,0004,0030,0244,0354,
-0302,0340,0101,0156,0017,0121,0313,0314,0044,0221,0257,0120,0241,0364,0160,0071,
-0231,0174,0072,0205,0043,0270,0264,0172,0374,0002,0066,0133,0045,0125,0227,0061,
-0055,0135,0372,0230,0343,0212,0222,0256,0005,0337,0051,0020,0147,0154,0272,0311,
-0323,0000,0346,0317,0341,0236,0250,0054,0143,0026,0001,0077,0130,0342,0211,0251,
-0015,0070,0064,0033,0253,0063,0377,0260,0273,0110,0014,0137,0271,0261,0315,0056,
-0305,0363,0333,0107,0345,0245,0234,0167,0012,0246,0040,0150,0376,0177,0301,0255
-};
-
-RC2Context * RC2_AllocateContext(void)
-{
- return PORT_ZNew(RC2Context);
-}
-SECStatus
-RC2_InitContext(RC2Context *cx, const unsigned char *key, unsigned int len,
- const unsigned char *input, int mode, unsigned int efLen8,
- unsigned int unused)
-{
- PRUint8 *L,*L2;
- int i;
-#if !defined(IS_LITTLE_ENDIAN)
- PRUint16 tmpS;
-#endif
- PRUint8 tmpB;
-
- if (!key || !cx || !len || len > (sizeof cx->B) ||
- efLen8 > (sizeof cx->B)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (mode == NSS_RC2) {
- /* groovy */
- } else if (mode == NSS_RC2_CBC) {
- if (!input) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- } else {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (mode == NSS_RC2_CBC) {
- cx->enc = & rc2_EncryptCBC;
- cx->dec = & rc2_DecryptCBC;
- LOAD(cx->iv.s);
- } else {
- cx->enc = & rc2_EncryptECB;
- cx->dec = & rc2_DecryptECB;
- }
-
- /* Step 0. Copy key into table. */
- memcpy(cx->B, key, len);
-
- /* Step 1. Compute all values to the right of the key. */
- L2 = cx->B;
- L = L2 + len;
- tmpB = L[-1];
- for (i = (sizeof cx->B) - len; i > 0; --i) {
- *L++ = tmpB = S[ (PRUint8)(tmpB + *L2++) ];
- }
-
- /* step 2. Adjust left most byte of effective key. */
- i = (sizeof cx->B) - efLen8;
- L = cx->B + i;
- *L = tmpB = S[*L]; /* mask is always 0xff */
-
- /* step 3. Recompute all values to the left of effective key. */
- L2 = --L + efLen8;
- while(L >= cx->B) {
- *L-- = tmpB = S[ tmpB ^ *L2-- ];
- }
-
-#if !defined(IS_LITTLE_ENDIAN)
- for (i = 63; i >= 0; --i) {
- SWAPK(i); /* candidate for unrolling */
- }
-#endif
- return SECSuccess;
-}
-
-/*
-** Create a new RC2 context suitable for RC2 encryption/decryption.
-** "key" raw key data
-** "len" the number of bytes of key data
-** "iv" is the CBC initialization vector (if mode is NSS_RC2_CBC)
-** "mode" one of NSS_RC2 or NSS_RC2_CBC
-** "effectiveKeyLen" in bytes, not bits.
-**
-** When mode is set to NSS_RC2_CBC the RC2 cipher is run in "cipher block
-** chaining" mode.
-*/
-RC2Context *
-RC2_CreateContext(const unsigned char *key, unsigned int len,
- const unsigned char *iv, int mode, unsigned efLen8)
-{
- RC2Context *cx = PORT_ZNew(RC2Context);
- if (cx) {
- SECStatus rv = RC2_InitContext(cx, key, len, iv, mode, efLen8, 0);
- if (rv != SECSuccess) {
- RC2_DestroyContext(cx, PR_TRUE);
- cx = NULL;
- }
- }
- return cx;
-}
-
-/*
-** Destroy an RC2 encryption/decryption context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-void
-RC2_DestroyContext(RC2Context *cx, PRBool freeit)
-{
- if (cx) {
- memset(cx, 0, sizeof *cx);
- if (freeit) {
- PORT_Free(cx);
- }
- }
-}
-
-#define ROL(x,k) (x << k | x >> (16-k))
-#define MIX(j) \
- R0 = R0 + cx->K[ 4*j+0] + (R3 & R2) + (~R3 & R1); R0 = ROL(R0,1);\
- R1 = R1 + cx->K[ 4*j+1] + (R0 & R3) + (~R0 & R2); R1 = ROL(R1,2);\
- R2 = R2 + cx->K[ 4*j+2] + (R1 & R0) + (~R1 & R3); R2 = ROL(R2,3);\
- R3 = R3 + cx->K[ 4*j+3] + (R2 & R1) + (~R2 & R0); R3 = ROL(R3,5)
-#define MASH \
- R0 = R0 + cx->K[R3 & 63];\
- R1 = R1 + cx->K[R0 & 63];\
- R2 = R2 + cx->K[R1 & 63];\
- R3 = R3 + cx->K[R2 & 63]
-
-/* Encrypt one block */
-static void
-rc2_Encrypt1Block(RC2Context *cx, RC2Block *output, RC2Block *input)
-{
- register PRUint16 R0, R1, R2, R3;
-
- /* step 1. Initialize input. */
- R0 = input->s[0];
- R1 = input->s[1];
- R2 = input->s[2];
- R3 = input->s[3];
-
- /* step 2. Expand Key (already done, in context) */
- /* step 3. j = 0 */
- /* step 4. Perform 5 mixing rounds. */
-
- MIX(0);
- MIX(1);
- MIX(2);
- MIX(3);
- MIX(4);
-
- /* step 5. Perform 1 mashing round. */
- MASH;
-
- /* step 6. Perform 6 mixing rounds. */
-
- MIX(5);
- MIX(6);
- MIX(7);
- MIX(8);
- MIX(9);
- MIX(10);
-
- /* step 7. Perform 1 mashing round. */
- MASH;
-
- /* step 8. Perform 5 mixing rounds. */
-
- MIX(11);
- MIX(12);
- MIX(13);
- MIX(14);
- MIX(15);
-
- /* output results */
- output->s[0] = R0;
- output->s[1] = R1;
- output->s[2] = R2;
- output->s[3] = R3;
-}
-
-#define ROR(x,k) (x >> k | x << (16-k))
-#define R_MIX(j) \
- R3 = ROR(R3,5); R3 = R3 - cx->K[ 4*j+3] - (R2 & R1) - (~R2 & R0); \
- R2 = ROR(R2,3); R2 = R2 - cx->K[ 4*j+2] - (R1 & R0) - (~R1 & R3); \
- R1 = ROR(R1,2); R1 = R1 - cx->K[ 4*j+1] - (R0 & R3) - (~R0 & R2); \
- R0 = ROR(R0,1); R0 = R0 - cx->K[ 4*j+0] - (R3 & R2) - (~R3 & R1)
-#define R_MASH \
- R3 = R3 - cx->K[R2 & 63];\
- R2 = R2 - cx->K[R1 & 63];\
- R1 = R1 - cx->K[R0 & 63];\
- R0 = R0 - cx->K[R3 & 63]
-
-/* Encrypt one block */
-static void
-rc2_Decrypt1Block(RC2Context *cx, RC2Block *output, RC2Block *input)
-{
- register PRUint16 R0, R1, R2, R3;
-
- /* step 1. Initialize input. */
- R0 = input->s[0];
- R1 = input->s[1];
- R2 = input->s[2];
- R3 = input->s[3];
-
- /* step 2. Expand Key (already done, in context) */
- /* step 3. j = 63 */
- /* step 4. Perform 5 r_mixing rounds. */
- R_MIX(15);
- R_MIX(14);
- R_MIX(13);
- R_MIX(12);
- R_MIX(11);
-
- /* step 5. Perform 1 r_mashing round. */
- R_MASH;
-
- /* step 6. Perform 6 r_mixing rounds. */
- R_MIX(10);
- R_MIX(9);
- R_MIX(8);
- R_MIX(7);
- R_MIX(6);
- R_MIX(5);
-
- /* step 7. Perform 1 r_mashing round. */
- R_MASH;
-
- /* step 8. Perform 5 r_mixing rounds. */
- R_MIX(4);
- R_MIX(3);
- R_MIX(2);
- R_MIX(1);
- R_MIX(0);
-
- /* output results */
- output->s[0] = R0;
- output->s[1] = R1;
- output->s[2] = R2;
- output->s[3] = R3;
-}
-
-static SECStatus
-rc2_EncryptECB(RC2Context *cx, unsigned char *output,
- const unsigned char *input, unsigned int inputLen)
-{
- RC2Block iBlock;
-
- while (inputLen > 0) {
- LOAD(iBlock.s)
- rc2_Encrypt1Block(cx, &iBlock, &iBlock);
- STORE(iBlock.s)
- output += RC2_BLOCK_SIZE;
- input += RC2_BLOCK_SIZE;
- inputLen -= RC2_BLOCK_SIZE;
- }
- return SECSuccess;
-}
-
-static SECStatus
-rc2_DecryptECB(RC2Context *cx, unsigned char *output,
- const unsigned char *input, unsigned int inputLen)
-{
- RC2Block iBlock;
-
- while (inputLen > 0) {
- LOAD(iBlock.s)
- rc2_Decrypt1Block(cx, &iBlock, &iBlock);
- STORE(iBlock.s)
- output += RC2_BLOCK_SIZE;
- input += RC2_BLOCK_SIZE;
- inputLen -= RC2_BLOCK_SIZE;
- }
- return SECSuccess;
-}
-
-static SECStatus
-rc2_EncryptCBC(RC2Context *cx, unsigned char *output,
- const unsigned char *input, unsigned int inputLen)
-{
- RC2Block iBlock;
-
- while (inputLen > 0) {
-
- LOAD(iBlock.s)
- iBlock.l[0] ^= cx->iv.l[0];
- iBlock.l[1] ^= cx->iv.l[1];
- rc2_Encrypt1Block(cx, &iBlock, &iBlock);
- cx->iv = iBlock;
- STORE(iBlock.s)
- output += RC2_BLOCK_SIZE;
- input += RC2_BLOCK_SIZE;
- inputLen -= RC2_BLOCK_SIZE;
- }
- return SECSuccess;
-}
-
-static SECStatus
-rc2_DecryptCBC(RC2Context *cx, unsigned char *output,
- const unsigned char *input, unsigned int inputLen)
-{
- RC2Block iBlock;
- RC2Block oBlock;
-
- while (inputLen > 0) {
- LOAD(iBlock.s)
- rc2_Decrypt1Block(cx, &oBlock, &iBlock);
- oBlock.l[0] ^= cx->iv.l[0];
- oBlock.l[1] ^= cx->iv.l[1];
- cx->iv = iBlock;
- STORE(oBlock.s)
- output += RC2_BLOCK_SIZE;
- input += RC2_BLOCK_SIZE;
- inputLen -= RC2_BLOCK_SIZE;
- }
- return SECSuccess;
-}
-
-
-/*
-** Perform RC2 encryption.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-SECStatus RC2_Encrypt(RC2Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- SECStatus rv = SECSuccess;
- if (inputLen) {
- if (inputLen % RC2_BLOCK_SIZE) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- rv = (*cx->enc)(cx, output, input, inputLen);
- }
- if (rv == SECSuccess) {
- *outputLen = inputLen;
- }
- return rv;
-}
-
-/*
-** Perform RC2 decryption.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-SECStatus RC2_Decrypt(RC2Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- SECStatus rv = SECSuccess;
- if (inputLen) {
- if (inputLen % RC2_BLOCK_SIZE) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- rv = (*cx->dec)(cx, output, input, inputLen);
- }
- if (rv == SECSuccess) {
- *outputLen = inputLen;
- }
- return rv;
-}
-
diff --git a/security/nss/lib/freebl/alghmac.c b/security/nss/lib/freebl/alghmac.c
deleted file mode 100644
index 9b845cff1..000000000
--- a/security/nss/lib/freebl/alghmac.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "secport.h"
-#include "hasht.h"
-#include "blapit.h"
-#include "alghmac.h"
-#include "secerr.h"
-
-#define HMAC_PAD_SIZE HASH_BLOCK_LENGTH_MAX
-
-struct HMACContextStr {
- void *hash;
- const SECHashObject *hashobj;
- PRBool wasAllocated;
- unsigned char ipad[HMAC_PAD_SIZE];
- unsigned char opad[HMAC_PAD_SIZE];
-};
-
-void
-HMAC_Destroy(HMACContext *cx, PRBool freeit)
-{
- if (cx == NULL)
- return;
-
- PORT_Assert(!freeit == !cx->wasAllocated);
- if (cx->hash != NULL) {
- cx->hashobj->destroy(cx->hash, PR_TRUE);
- PORT_Memset(cx, 0, sizeof *cx);
- }
- if (freeit)
- PORT_Free(cx);
-}
-
-SECStatus
-HMAC_Init( HMACContext * cx, const SECHashObject *hash_obj,
- const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
-{
- unsigned int i;
- unsigned char hashed_secret[HASH_LENGTH_MAX];
-
- /* required by FIPS 198 Section 3 */
- if (isFIPS && secret_len < hash_obj->length/2) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (cx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- cx->wasAllocated = PR_FALSE;
- cx->hashobj = hash_obj;
- cx->hash = cx->hashobj->create();
- if (cx->hash == NULL)
- goto loser;
-
- if (secret_len > cx->hashobj->blocklength) {
- cx->hashobj->begin( cx->hash);
- cx->hashobj->update(cx->hash, secret, secret_len);
- PORT_Assert(cx->hashobj->length <= sizeof hashed_secret);
- cx->hashobj->end( cx->hash, hashed_secret, &secret_len,
- sizeof hashed_secret);
- if (secret_len != cx->hashobj->length) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- goto loser;
- }
- secret = (const unsigned char *)&hashed_secret[0];
- }
-
- PORT_Memset(cx->ipad, 0x36, cx->hashobj->blocklength);
- PORT_Memset(cx->opad, 0x5c, cx->hashobj->blocklength);
-
- /* fold secret into padding */
- for (i = 0; i < secret_len; i++) {
- cx->ipad[i] ^= secret[i];
- cx->opad[i] ^= secret[i];
- }
- PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
- return SECSuccess;
-
-loser:
- PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
- if (cx->hash != NULL)
- cx->hashobj->destroy(cx->hash, PR_TRUE);
- return SECFailure;
-}
-
-HMACContext *
-HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
- unsigned int secret_len, PRBool isFIPS)
-{
- SECStatus rv;
- HMACContext * cx = PORT_ZNew(HMACContext);
- if (cx == NULL)
- return NULL;
- rv = HMAC_Init(cx, hash_obj, secret, secret_len, isFIPS);
- cx->wasAllocated = PR_TRUE;
- if (rv != SECSuccess) {
- PORT_Free(cx); /* contains no secret info */
- cx = NULL;
- }
- return cx;
-}
-
-void
-HMAC_Begin(HMACContext *cx)
-{
- /* start inner hash */
- cx->hashobj->begin(cx->hash);
- cx->hashobj->update(cx->hash, cx->ipad, cx->hashobj->blocklength);
-}
-
-void
-HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len)
-{
- cx->hashobj->update(cx->hash, data, data_len);
-}
-
-SECStatus
-HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
- unsigned int max_result_len)
-{
- if (max_result_len < cx->hashobj->length) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- cx->hashobj->end(cx->hash, result, result_len, max_result_len);
- if (*result_len != cx->hashobj->length)
- return SECFailure;
-
- cx->hashobj->begin(cx->hash);
- cx->hashobj->update(cx->hash, cx->opad, cx->hashobj->blocklength);
- cx->hashobj->update(cx->hash, result, *result_len);
- cx->hashobj->end(cx->hash, result, result_len, max_result_len);
- return SECSuccess;
-}
-
-HMACContext *
-HMAC_Clone(HMACContext *cx)
-{
- HMACContext *newcx;
-
- newcx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
- if (newcx == NULL)
- goto loser;
-
- newcx->wasAllocated = PR_TRUE;
- newcx->hashobj = cx->hashobj;
- newcx->hash = cx->hashobj->clone(cx->hash);
- if (newcx->hash == NULL)
- goto loser;
- PORT_Memcpy(newcx->ipad, cx->ipad, cx->hashobj->blocklength);
- PORT_Memcpy(newcx->opad, cx->opad, cx->hashobj->blocklength);
- return newcx;
-
-loser:
- HMAC_Destroy(newcx, PR_TRUE);
- return NULL;
-}
diff --git a/security/nss/lib/freebl/alghmac.h b/security/nss/lib/freebl/alghmac.h
deleted file mode 100644
index e77b3118d..000000000
--- a/security/nss/lib/freebl/alghmac.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _ALGHMAC_H_
-#define _ALGHMAC_H_
-
-typedef struct HMACContextStr HMACContext;
-
-SEC_BEGIN_PROTOS
-
-/* destroy HMAC context */
-extern void
-HMAC_Destroy(HMACContext *cx, PRBool freeit);
-
-/* create HMAC context
- * hash_obj hash object from SECRawHashObjects[]
- * secret the secret with which the HMAC is performed.
- * secret_len the length of the secret.
- * isFIPS true if conforming to FIPS 198.
- *
- * NULL is returned if an error occurs.
- */
-extern HMACContext *
-HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
- unsigned int secret_len, PRBool isFIPS);
-
-/* like HMAC_Create, except caller allocates HMACContext. */
-SECStatus
-HMAC_Init(HMACContext *cx, const SECHashObject *hash_obj,
- const unsigned char *secret, unsigned int secret_len, PRBool isFIPS);
-
-/* reset HMAC for a fresh round */
-extern void
-HMAC_Begin(HMACContext *cx);
-
-/* update HMAC
- * cx HMAC Context
- * data the data to perform HMAC on
- * data_len the length of the data to process
- */
-extern void
-HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len);
-
-/* Finish HMAC -- place the results within result
- * cx HMAC context
- * result buffer for resulting hmac'd data
- * result_len where the resultant hmac length is stored
- * max_result_len maximum possible length that can be stored in result
- */
-extern SECStatus
-HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
- unsigned int max_result_len);
-
-/* clone a copy of the HMAC state. this is usefult when you would
- * need to keep a running hmac but also need to extract portions
- * partway through the process.
- */
-extern HMACContext *
-HMAC_Clone(HMACContext *cx);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/freebl/arcfive.c b/security/nss/lib/freebl/arcfive.c
deleted file mode 100644
index 69d7f3aec..000000000
--- a/security/nss/lib/freebl/arcfive.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * arcfive.c - stubs for RC5 - NOT a working implementation!
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "blapi.h"
-#include "prerror.h"
-
-/******************************************/
-/*
-** RC5 symmetric block cypher -- 64-bit block size
-*/
-
-/*
-** Create a new RC5 context suitable for RC5 encryption/decryption.
-** "key" raw key data
-** "len" the number of bytes of key data
-** "iv" is the CBC initialization vector (if mode is NSS_RC5_CBC)
-** "mode" one of NSS_RC5 or NSS_RC5_CBC
-**
-** When mode is set to NSS_RC5_CBC the RC5 cipher is run in "cipher block
-** chaining" mode.
-*/
-RC5Context *
-RC5_CreateContext(const SECItem *key, unsigned int rounds,
- unsigned int wordSize, const unsigned char *iv, int mode)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
-}
-
-/*
-** Destroy an RC5 encryption/decryption context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-void
-RC5_DestroyContext(RC5Context *cx, PRBool freeit)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
-}
-
-/*
-** Perform RC5 encryption.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-SECStatus
-RC5_Encrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-/*
-** Perform RC5 decryption.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-SECStatus
-RC5_Decrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
diff --git a/security/nss/lib/freebl/arcfour-amd64-gas.s b/security/nss/lib/freebl/arcfour-amd64-gas.s
deleted file mode 100644
index 7c4f5358f..000000000
--- a/security/nss/lib/freebl/arcfour-amd64-gas.s
+++ /dev/null
@@ -1,88 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# ** ARCFOUR implementation optimized for AMD64.
-# **
-# ** The throughput achieved by this code is about 320 MBytes/sec, on
-# ** a 1.8 GHz AMD Opteron (rev C0) processor.
-
-.text
-.align 16
-.globl ARCFOUR
-.type ARCFOUR,@function
-ARCFOUR:
- pushq %rbp
- pushq %rbx
- movq %rdi, %rbp # key = ARG(key)
- movq %rsi, %rbx # rbx = ARG(len)
- movq %rdx, %rsi # in = ARG(in)
- movq %rcx, %rdi # out = ARG(out)
- movq (%rbp), %rcx # x = key->x
- movq 8(%rbp), %rdx # y = key->y
- addq $16, %rbp # d = key->data
- incq %rcx # x++
- andq $255, %rcx # x &= 0xff
- leaq -8(%rbx,%rsi), %rbx # rbx = in+len-8
- movq %rbx, %r9 # tmp = in+len-8
- movq 0(%rbp,%rcx,8), %rax # tx = d[x]
- cmpq %rsi, %rbx # cmp in with in+len-8
- jl .Lend # jump if (in+len-8 < in)
-
-.Lstart:
- addq $8, %rsi # increment in
- addq $8, %rdi # increment out
-
- # generate the next 8 bytes of the rc4 stream into %r8
- movq $8, %r11 # byte counter
-1: addb %al, %dl # y += tx
- movl 0(%rbp,%rdx,8), %ebx # ty = d[y]
- movl %ebx, 0(%rbp,%rcx,8) # d[x] = ty
- addb %al, %bl # val = ty + tx
- movl %eax, 0(%rbp,%rdx,8) # d[y] = tx
- incb %cl # x++ (NEXT ROUND)
- movl 0(%rbp,%rcx,8), %eax # tx = d[x] (NEXT ROUND)
- movb 0(%rbp,%rbx,8), %r8b # val = d[val]
- decb %r11b
- rorq $8, %r8 # (ror does not change ZF)
- jnz 1b
-
- # xor 8 bytes
- xorq -8(%rsi), %r8
- cmpq %r9, %rsi # cmp in+len-8 with in
- movq %r8, -8(%rdi)
- jle .Lstart # jump if (in <= in+len-8)
-
-.Lend:
- addq $8, %r9 # tmp = in+len
-
- # handle the last bytes, one by one
-1: cmpq %rsi, %r9 # cmp in with in+len
- jle .Lfinished # jump if (in+len <= in)
- addb %al, %dl # y += tx
- movl 0(%rbp,%rdx,8), %ebx # ty = d[y]
- movl %ebx, 0(%rbp,%rcx,8) # d[x] = ty
- addb %al, %bl # val = ty + tx
- movl %eax, 0(%rbp,%rdx,8) # d[y] = tx
- incb %cl # x++ (NEXT ROUND)
- movl 0(%rbp,%rcx,8), %eax # tx = d[x] (NEXT ROUND)
- movb 0(%rbp,%rbx,8), %r8b # val = d[val]
- xorb (%rsi), %r8b # xor 1 byte
- movb %r8b, (%rdi)
- incq %rsi # in++
- incq %rdi # out++
- jmp 1b
-
-.Lfinished:
- decq %rcx # x--
- movb %dl, -8(%rbp) # key->y = y
- movb %cl, -16(%rbp) # key->x = x
- popq %rbx
- popq %rbp
- ret
-.L_ARCFOUR_end:
-.size ARCFOUR,.L_ARCFOUR_end-ARCFOUR
-
-# Magic indicating no need for an executable stack
-.section .note.GNU-stack,"",@progbits
-.previous
diff --git a/security/nss/lib/freebl/arcfour-amd64-masm.asm b/security/nss/lib/freebl/arcfour-amd64-masm.asm
deleted file mode 100644
index 1601c4f89..000000000
--- a/security/nss/lib/freebl/arcfour-amd64-masm.asm
+++ /dev/null
@@ -1,107 +0,0 @@
-; This Source Code Form is subject to the terms of the Mozilla Public
-; License, v. 2.0. If a copy of the MPL was not distributed with this
-; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-; ** ARCFOUR implementation optimized for AMD64.
-; **
-; ** The throughput achieved by this code is about 320 MBytes/sec, on
-; ** a 1.8 GHz AMD Opteron (rev C0) processor.
-
-.CODE
-
-; extern void ARCFOUR(RC4Context *cx, unsigned long long inputLen,
-; const unsigned char *input, unsigned char *output);
-
-
-ARCFOUR PROC
-
- push rbp
- push rbx
- push rsi
- push rdi
-
- mov rbp, rcx ; key = ARG(key)
- mov rbx, rdx ; rbx = ARG(len)
- mov rsi, r8 ; in = ARG(in)
- mov rdi, r9 ; out = ARG(out)
- mov rcx, [rbp] ; x = key->x
- mov rdx, [rbp+8] ; y = key->y
- add rbp, 16 ; d = key->data
- inc rcx ; x++
- and rcx, 0ffh ; x &= 0xff
- lea rbx, [rbx+rsi-8] ; rbx = in+len-8
- mov r9, rbx ; tmp = in+len-8
- mov rax, [rbp+rcx*8] ; tx = d[x]
- cmp rbx, rsi ; cmp in with in+len-8
- jl Lend ; jump if (in+len-8 < in)
-
-Lstart:
- add rsi, 8 ; increment in
- add rdi, 8 ; increment out
-
- ;
- ; generate the next 8 bytes of the rc4 stream into r8
- ;
-
- mov r11, 8 ; byte counter
-
-@@:
- add dl, al ; y += tx
- mov ebx, [rbp+rdx*8] ; ty = d[y]
- mov [rbp+rcx*8], ebx ; d[x] = ty
- add bl, al ; val = ty + tx
- mov [rbp+rdx*8], eax ; d[y] = tx
- inc cl ; x++ (NEXT ROUND)
- mov eax, [rbp+rcx*8] ; tx = d[x] (NEXT ROUND)
- mov r8b, [rbp+rbx*8] ; val = d[val]
- dec r11b
- ror r8, 8 ; (ror does not change ZF)
- jnz @b
-
- ;
- ; xor 8 bytes
- ;
-
- xor r8, [rsi-8]
- cmp rsi, r9 ; cmp in+len-8 with in
- mov [rdi-8], r8
- jle Lstart
-
-Lend:
- add r9, 8 ; tmp = in+len
-
- ;
- ; handle the last bytes, one by one
- ;
-
-@@:
- cmp r9, rsi ; cmp in with in+len
- jle Lfinished ; jump if (in+len <= in)
- add dl, al ; y += tx
- mov ebx, [rbp+rdx*8] ; ty = d[y]
- mov [rbp+rcx*8], ebx ; d[x] = ty
- add bl, al ; val = ty + tx
- mov [rbp+rdx*8], eax ; d[y] = tx
- inc cl ; x++ (NEXT ROUND)
- mov eax, [rbp+rcx*8] ; tx = d[x] (NEXT ROUND)
- mov r8b, [rbp+rbx*8] ; val = d[val]
- xor r8b, [rsi] ; xor 1 byte
- mov [rdi], r8b
- inc rsi ; in++
- inc rdi
- jmp @b
-
-Lfinished:
- dec rcx ; x--
- mov [rbp-8], dl ; key->y = y
- mov [rbp-16], cl ; key->x = x
-
- pop rdi
- pop rsi
- pop rbx
- pop rbp
- ret
-
-ARCFOUR ENDP
-
-END
diff --git a/security/nss/lib/freebl/arcfour-amd64-sun.s b/security/nss/lib/freebl/arcfour-amd64-sun.s
deleted file mode 100644
index 8b649f901..000000000
--- a/security/nss/lib/freebl/arcfour-amd64-sun.s
+++ /dev/null
@@ -1,84 +0,0 @@
-/ This Source Code Form is subject to the terms of the Mozilla Public
-/ License, v. 2.0. If a copy of the MPL was not distributed with this
-/ file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-/ ** ARCFOUR implementation optimized for AMD64.
-/ **
-/ ** The throughput achieved by this code is about 320 MBytes/sec, on
-/ ** a 1.8 GHz AMD Opteron (rev C0) processor.
-
-.text
-.align 16
-.globl ARCFOUR
-.type ARCFOUR,@function
-ARCFOUR:
- pushq %rbp
- pushq %rbx
- movq %rdi, %rbp / key = ARG(key)
- movq %rsi, %rbx / rbx = ARG(len)
- movq %rdx, %rsi / in = ARG(in)
- movq %rcx, %rdi / out = ARG(out)
- movq (%rbp), %rcx / x = key->x
- movq 8(%rbp), %rdx / y = key->y
- addq $16, %rbp / d = key->data
- incq %rcx / x++
- andq $255, %rcx / x &= 0xff
- leaq -8(%rbx,%rsi), %rbx / rbx = in+len-8
- movq %rbx, %r9 / tmp = in+len-8
- movq 0(%rbp,%rcx,8), %rax / tx = d[x]
- cmpq %rsi, %rbx / cmp in with in+len-8
- jl .Lend / jump if (in+len-8 < in)
-
-.Lstart:
- addq $8, %rsi / increment in
- addq $8, %rdi / increment out
-
- / generate the next 8 bytes of the rc4 stream into %r8
- movq $8, %r11 / byte counter
-1: addb %al, %dl / y += tx
- movl 0(%rbp,%rdx,8), %ebx / ty = d[y]
- movl %ebx, 0(%rbp,%rcx,8) / d[x] = ty
- addb %al, %bl / val = ty + tx
- movl %eax, 0(%rbp,%rdx,8) / d[y] = tx
- incb %cl / x++ (NEXT ROUND)
- movl 0(%rbp,%rcx,8), %eax / tx = d[x] (NEXT ROUND)
- movb 0(%rbp,%rbx,8), %r8b / val = d[val]
- decb %r11b
- rorq $8, %r8 / (ror does not change ZF)
- jnz 1b
-
- / xor 8 bytes
- xorq -8(%rsi), %r8
- cmpq %r9, %rsi / cmp in+len-8 with in
- movq %r8, -8(%rdi)
- jle .Lstart / jump if (in <= in+len-8)
-
-.Lend:
- addq $8, %r9 / tmp = in+len
-
- / handle the last bytes, one by one
-1: cmpq %rsi, %r9 / cmp in with in+len
- jle .Lfinished / jump if (in+len <= in)
- addb %al, %dl / y += tx
- movl 0(%rbp,%rdx,8), %ebx / ty = d[y]
- movl %ebx, 0(%rbp,%rcx,8) / d[x] = ty
- addb %al, %bl / val = ty + tx
- movl %eax, 0(%rbp,%rdx,8) / d[y] = tx
- incb %cl / x++ (NEXT ROUND)
- movl 0(%rbp,%rcx,8), %eax / tx = d[x] (NEXT ROUND)
- movb 0(%rbp,%rbx,8), %r8b / val = d[val]
- xorb (%rsi), %r8b / xor 1 byte
- movb %r8b, (%rdi)
- incq %rsi / in++
- incq %rdi / out++
- jmp 1b
-
-.Lfinished:
- decq %rcx / x--
- movb %dl, -8(%rbp) / key->y = y
- movb %cl, -16(%rbp) / key->x = x
- popq %rbx
- popq %rbp
- ret
-.L_ARCFOUR_end:
-.size ARCFOUR,.L_ARCFOUR_end-ARCFOUR
diff --git a/security/nss/lib/freebl/arcfour.c b/security/nss/lib/freebl/arcfour.c
deleted file mode 100644
index 103ff5938..000000000
--- a/security/nss/lib/freebl/arcfour.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/* arcfour.c - the arc four algorithm.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prerr.h"
-#include "secerr.h"
-
-#include "prtypes.h"
-#include "blapi.h"
-
-/* Architecture-dependent defines */
-
-#if defined(SOLARIS) || defined(HPUX) || defined(NSS_X86) || \
- defined(_WIN64)
-/* Convert the byte-stream to a word-stream */
-#define CONVERT_TO_WORDS
-#endif
-
-#if defined(AIX) || defined(OSF1) || defined(NSS_BEVAND_ARCFOUR)
-/* Treat array variables as words, not bytes, on CPUs that take
- * much longer to write bytes than to write words, or when using
- * assembler code that required it.
- */
-#define USE_WORD
-#endif
-
-#if (defined(IS_64))
-typedef PRUint64 WORD;
-#else
-typedef PRUint32 WORD;
-#endif
-#define WORDSIZE sizeof(WORD)
-
-#if defined(USE_WORD)
-typedef WORD Stype;
-#else
-typedef PRUint8 Stype;
-#endif
-
-#define ARCFOUR_STATE_SIZE 256
-
-#define MASK1BYTE (WORD)(0xff)
-
-#define SWAP(a, b) \
- tmp = a; \
- a = b; \
- b = tmp;
-
-/*
- * State information for stream cipher.
- */
-struct RC4ContextStr
-{
-#if defined(NSS_ARCFOUR_IJ_B4_S) || defined(NSS_BEVAND_ARCFOUR)
- Stype i;
- Stype j;
- Stype S[ARCFOUR_STATE_SIZE];
-#else
- Stype S[ARCFOUR_STATE_SIZE];
- Stype i;
- Stype j;
-#endif
-};
-
-/*
- * array indices [0..255] to initialize cx->S array (faster than loop).
- */
-static const Stype Kinit[256] = {
- 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,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
-};
-
-RC4Context *
-RC4_AllocateContext(void)
-{
- return PORT_ZNew(RC4Context);
-}
-
-SECStatus
-RC4_InitContext(RC4Context *cx, const unsigned char *key, unsigned int len,
- const unsigned char * unused1, int unused2,
- unsigned int unused3, unsigned int unused4)
-{
- unsigned int i;
- PRUint8 j, tmp;
- PRUint8 K[256];
- PRUint8 *L;
-
- /* verify the key length. */
- PORT_Assert(len > 0 && len < ARCFOUR_STATE_SIZE);
- if (len == 0 || len >= ARCFOUR_STATE_SIZE) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- return SECFailure;
- }
- if (cx == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* Initialize the state using array indices. */
- memcpy(cx->S, Kinit, sizeof cx->S);
- /* Fill in K repeatedly with values from key. */
- L = K;
- for (i = sizeof K; i > len; i-= len) {
- memcpy(L, key, len);
- L += len;
- }
- memcpy(L, key, i);
- /* Stir the state of the generator. At this point it is assumed
- * that the key is the size of the state buffer. If this is not
- * the case, the key bytes are repeated to fill the buffer.
- */
- j = 0;
-#define ARCFOUR_STATE_STIR(ii) \
- j = j + cx->S[ii] + K[ii]; \
- SWAP(cx->S[ii], cx->S[j]);
- for (i=0; i<ARCFOUR_STATE_SIZE; i++) {
- ARCFOUR_STATE_STIR(i);
- }
- cx->i = 0;
- cx->j = 0;
- return SECSuccess;
-}
-
-
-/*
- * Initialize a new generator.
- */
-RC4Context *
-RC4_CreateContext(const unsigned char *key, int len)
-{
- RC4Context *cx = RC4_AllocateContext();
- if (cx) {
- SECStatus rv = RC4_InitContext(cx, key, len, NULL, 0, 0, 0);
- if (rv != SECSuccess) {
- PORT_ZFree(cx, sizeof(*cx));
- cx = NULL;
- }
- }
- return cx;
-}
-
-void
-RC4_DestroyContext(RC4Context *cx, PRBool freeit)
-{
- if (freeit)
- PORT_ZFree(cx, sizeof(*cx));
-}
-
-#if defined(NSS_BEVAND_ARCFOUR)
-extern void ARCFOUR(RC4Context *cx, WORD inputLen,
- const unsigned char *input, unsigned char *output);
-#else
-/*
- * Generate the next byte in the stream.
- */
-#define ARCFOUR_NEXT_BYTE() \
- tmpSi = cx->S[++tmpi]; \
- tmpj += tmpSi; \
- tmpSj = cx->S[tmpj]; \
- cx->S[tmpi] = tmpSj; \
- cx->S[tmpj] = tmpSi; \
- t = tmpSi + tmpSj;
-
-#ifdef CONVERT_TO_WORDS
-/*
- * Straight ARCFOUR op. No optimization.
- */
-static SECStatus
-rc4_no_opt(RC4Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- PRUint8 t;
- Stype tmpSi, tmpSj;
- register PRUint8 tmpi = cx->i;
- register PRUint8 tmpj = cx->j;
- unsigned int index;
- PORT_Assert(maxOutputLen >= inputLen);
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- for (index=0; index < inputLen; index++) {
- /* Generate next byte from stream. */
- ARCFOUR_NEXT_BYTE();
- /* output = next stream byte XOR next input byte */
- output[index] = cx->S[t] ^ input[index];
- }
- *outputLen = inputLen;
- cx->i = tmpi;
- cx->j = tmpj;
- return SECSuccess;
-}
-
-#else
-/* !CONVERT_TO_WORDS */
-
-/*
- * Byte-at-a-time ARCFOUR, unrolling the loop into 8 pieces.
- */
-static SECStatus
-rc4_unrolled(RC4Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- PRUint8 t;
- Stype tmpSi, tmpSj;
- register PRUint8 tmpi = cx->i;
- register PRUint8 tmpj = cx->j;
- int index;
- PORT_Assert(maxOutputLen >= inputLen);
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- for (index = inputLen / 8; index-- > 0; input += 8, output += 8) {
- ARCFOUR_NEXT_BYTE();
- output[0] = cx->S[t] ^ input[0];
- ARCFOUR_NEXT_BYTE();
- output[1] = cx->S[t] ^ input[1];
- ARCFOUR_NEXT_BYTE();
- output[2] = cx->S[t] ^ input[2];
- ARCFOUR_NEXT_BYTE();
- output[3] = cx->S[t] ^ input[3];
- ARCFOUR_NEXT_BYTE();
- output[4] = cx->S[t] ^ input[4];
- ARCFOUR_NEXT_BYTE();
- output[5] = cx->S[t] ^ input[5];
- ARCFOUR_NEXT_BYTE();
- output[6] = cx->S[t] ^ input[6];
- ARCFOUR_NEXT_BYTE();
- output[7] = cx->S[t] ^ input[7];
- }
- index = inputLen % 8;
- if (index) {
- input += index;
- output += index;
- switch (index) {
- case 7:
- ARCFOUR_NEXT_BYTE();
- output[-7] = cx->S[t] ^ input[-7]; /* FALLTHRU */
- case 6:
- ARCFOUR_NEXT_BYTE();
- output[-6] = cx->S[t] ^ input[-6]; /* FALLTHRU */
- case 5:
- ARCFOUR_NEXT_BYTE();
- output[-5] = cx->S[t] ^ input[-5]; /* FALLTHRU */
- case 4:
- ARCFOUR_NEXT_BYTE();
- output[-4] = cx->S[t] ^ input[-4]; /* FALLTHRU */
- case 3:
- ARCFOUR_NEXT_BYTE();
- output[-3] = cx->S[t] ^ input[-3]; /* FALLTHRU */
- case 2:
- ARCFOUR_NEXT_BYTE();
- output[-2] = cx->S[t] ^ input[-2]; /* FALLTHRU */
- case 1:
- ARCFOUR_NEXT_BYTE();
- output[-1] = cx->S[t] ^ input[-1]; /* FALLTHRU */
- default:
- /* FALLTHRU */
- ; /* hp-ux build breaks without this */
- }
- }
- cx->i = tmpi;
- cx->j = tmpj;
- *outputLen = inputLen;
- return SECSuccess;
-}
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-#define ARCFOUR_NEXT4BYTES_L(n) \
- ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n ); \
- ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 8); \
- ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 16); \
- ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 24);
-#else
-#define ARCFOUR_NEXT4BYTES_B(n) \
- ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 24); \
- ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 16); \
- ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n + 8); \
- ARCFOUR_NEXT_BYTE(); streamWord |= (WORD)cx->S[t] << (n );
-#endif
-
-#if (defined(IS_64) && !defined(__sparc)) || defined(NSS_USE_64)
-/* 64-bit wordsize */
-#ifdef IS_LITTLE_ENDIAN
-#define ARCFOUR_NEXT_WORD() \
- { streamWord = 0; ARCFOUR_NEXT4BYTES_L(0); ARCFOUR_NEXT4BYTES_L(32); }
-#else
-#define ARCFOUR_NEXT_WORD() \
- { streamWord = 0; ARCFOUR_NEXT4BYTES_B(32); ARCFOUR_NEXT4BYTES_B(0); }
-#endif
-#else
-/* 32-bit wordsize */
-#ifdef IS_LITTLE_ENDIAN
-#define ARCFOUR_NEXT_WORD() \
- { streamWord = 0; ARCFOUR_NEXT4BYTES_L(0); }
-#else
-#define ARCFOUR_NEXT_WORD() \
- { streamWord = 0; ARCFOUR_NEXT4BYTES_B(0); }
-#endif
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-#define RSH <<
-#define LSH >>
-#else
-#define RSH >>
-#define LSH <<
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-#define LEFTMOST_BYTE_SHIFT 0
-#define NEXT_BYTE_SHIFT(shift) shift + 8
-#else
-#define LEFTMOST_BYTE_SHIFT 8*(WORDSIZE - 1)
-#define NEXT_BYTE_SHIFT(shift) shift - 8
-#endif
-
-#ifdef CONVERT_TO_WORDS
-static SECStatus
-rc4_wordconv(RC4Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- PR_STATIC_ASSERT(sizeof(PRUword) == sizeof(ptrdiff_t));
- unsigned int inOffset = (PRUword)input % WORDSIZE;
- unsigned int outOffset = (PRUword)output % WORDSIZE;
- register WORD streamWord;
- register const WORD *pInWord;
- register WORD *pOutWord;
- register WORD inWord, nextInWord;
- PRUint8 t;
- register Stype tmpSi, tmpSj;
- register PRUint8 tmpi = cx->i;
- register PRUint8 tmpj = cx->j;
- unsigned int byteCount;
- unsigned int bufShift, invBufShift;
- unsigned int i;
- const unsigned char *finalIn;
- unsigned char *finalOut;
-
- PORT_Assert(maxOutputLen >= inputLen);
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- if (inputLen < 2*WORDSIZE) {
- /* Ignore word conversion, do byte-at-a-time */
- return rc4_no_opt(cx, output, outputLen, maxOutputLen, input, inputLen);
- }
- *outputLen = inputLen;
- pInWord = (const WORD *)(input - inOffset);
- pOutWord = (WORD *)(output - outOffset);
- if (inOffset < outOffset) {
- bufShift = 8*(outOffset - inOffset);
- invBufShift = 8*WORDSIZE - bufShift;
- } else {
- invBufShift = 8*(inOffset - outOffset);
- bufShift = 8*WORDSIZE - invBufShift;
- }
- /*****************************************************************/
- /* Step 1: */
- /* If the first output word is partial, consume the bytes in the */
- /* first partial output word by loading one or two words of */
- /* input and shifting them accordingly. Otherwise, just load */
- /* in the first word of input. At the end of this block, at */
- /* least one partial word of input should ALWAYS be loaded. */
- /*****************************************************************/
- if (outOffset) {
- byteCount = WORDSIZE - outOffset;
- for (i = 0; i < byteCount; i++) {
- ARCFOUR_NEXT_BYTE();
- output[i] = cx->S[t] ^ input[i];
- }
- /* Consumed byteCount bytes of input */
- inputLen -= byteCount;
- pInWord++;
-
- /* move to next word of output */
- pOutWord++;
-
- /* If buffers are relatively misaligned, shift the bytes in inWord
- * to be aligned to the output buffer.
- */
- if (inOffset < outOffset) {
- /* The first input word (which may be partial) has more bytes
- * than needed. Copy the remainder to inWord.
- */
- unsigned int shift = LEFTMOST_BYTE_SHIFT;
- inWord = 0;
- for (i = 0; i < outOffset - inOffset; i++) {
- inWord |= (WORD)input[byteCount + i] << shift;
- shift = NEXT_BYTE_SHIFT(shift);
- }
- } else if (inOffset > outOffset) {
- /* Consumed some bytes in the second input word. Copy the
- * remainder to inWord.
- */
- inWord = *pInWord++;
- inWord = inWord LSH invBufShift;
- } else {
- inWord = 0;
- }
- } else {
- /* output is word-aligned */
- if (inOffset) {
- /* Input is not word-aligned. The first word load of input
- * will not produce a full word of input bytes, so one word
- * must be pre-loaded. The main loop below will load in the
- * next input word and shift some of its bytes into inWord
- * in order to create a full input word. Note that the main
- * loop must execute at least once because the input must
- * be at least two words.
- */
- unsigned int shift = LEFTMOST_BYTE_SHIFT;
- inWord = 0;
- for (i = 0; i < WORDSIZE - inOffset; i++) {
- inWord |= (WORD)input[i] << shift;
- shift = NEXT_BYTE_SHIFT(shift);
- }
- pInWord++;
- } else {
- /* Input is word-aligned. The first word load of input
- * will produce a full word of input bytes, so nothing
- * needs to be loaded here.
- */
- inWord = 0;
- }
- }
- /* Output buffer is aligned, inOffset is now measured relative to
- * outOffset (and not a word boundary).
- */
- inOffset = (inOffset + WORDSIZE - outOffset) % WORDSIZE;
- /*****************************************************************/
- /* Step 2: main loop */
- /* At this point the output buffer is word-aligned. Any unused */
- /* bytes from above will be in inWord (shifted correctly). If */
- /* the input buffer is unaligned relative to the output buffer, */
- /* shifting has to be done. */
- /*****************************************************************/
- if (inOffset) {
- for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) {
- nextInWord = *pInWord++;
- inWord |= nextInWord RSH bufShift;
- nextInWord = nextInWord LSH invBufShift;
- ARCFOUR_NEXT_WORD();
- *pOutWord++ = inWord ^ streamWord;
- inWord = nextInWord;
- }
- if (inputLen == 0) {
- /* Nothing left to do. */
- cx->i = tmpi;
- cx->j = tmpj;
- return SECSuccess;
- }
- finalIn = (const unsigned char *)pInWord - WORDSIZE + inOffset;
- } else {
- for (; inputLen >= WORDSIZE; inputLen -= WORDSIZE) {
- inWord = *pInWord++;
- ARCFOUR_NEXT_WORD();
- *pOutWord++ = inWord ^ streamWord;
- }
- if (inputLen == 0) {
- /* Nothing left to do. */
- cx->i = tmpi;
- cx->j = tmpj;
- return SECSuccess;
- }
- finalIn = (const unsigned char *)pInWord;
- }
- /*****************************************************************/
- /* Step 3: */
- /* Do the remaining partial word of input one byte at a time. */
- /*****************************************************************/
- finalOut = (unsigned char *)pOutWord;
- for (i = 0; i < inputLen; i++) {
- ARCFOUR_NEXT_BYTE();
- finalOut[i] = cx->S[t] ^ finalIn[i];
- }
- cx->i = tmpi;
- cx->j = tmpj;
- return SECSuccess;
-}
-#endif
-#endif /* NSS_BEVAND_ARCFOUR */
-
-SECStatus
-RC4_Encrypt(RC4Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- PORT_Assert(maxOutputLen >= inputLen);
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
-#if defined(NSS_BEVAND_ARCFOUR)
- ARCFOUR(cx, inputLen, input, output);
- *outputLen = inputLen;
- return SECSuccess;
-#elif defined( CONVERT_TO_WORDS )
- /* Convert the byte-stream to a word-stream */
- return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen);
-#else
- /* Operate on bytes, but unroll the main loop */
- return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen);
-#endif
-}
-
-SECStatus RC4_Decrypt(RC4Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- PORT_Assert(maxOutputLen >= inputLen);
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- /* decrypt and encrypt are same operation. */
-#if defined(NSS_BEVAND_ARCFOUR)
- ARCFOUR(cx, inputLen, input, output);
- *outputLen = inputLen;
- return SECSuccess;
-#elif defined( CONVERT_TO_WORDS )
- /* Convert the byte-stream to a word-stream */
- return rc4_wordconv(cx, output, outputLen, maxOutputLen, input, inputLen);
-#else
- /* Operate on bytes, but unroll the main loop */
- return rc4_unrolled(cx, output, outputLen, maxOutputLen, input, inputLen);
-#endif
-}
-
-#undef CONVERT_TO_WORDS
-#undef USE_WORD
diff --git a/security/nss/lib/freebl/blapi.h b/security/nss/lib/freebl/blapi.h
deleted file mode 100644
index 40f05f9dc..000000000
--- a/security/nss/lib/freebl/blapi.h
+++ /dev/null
@@ -1,1414 +0,0 @@
-/*
- * crypto.h - public data structures and prototypes for the crypto library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _BLAPI_H_
-#define _BLAPI_H_
-
-#include "blapit.h"
-#include "hasht.h"
-#include "alghmac.h"
-
-SEC_BEGIN_PROTOS
-
-/*
-** RSA encryption/decryption. When encrypting/decrypting the output
-** buffer must be at least the size of the public key modulus.
-*/
-
-extern SECStatus BL_Init(void);
-
-/*
-** Generate and return a new RSA public and private key.
-** Both keys are encoded in a single RSAPrivateKey structure.
-** "cx" is the random number generator context
-** "keySizeInBits" is the size of the key to be generated, in bits.
-** 512, 1024, etc.
-** "publicExponent" when not NULL is a pointer to some data that
-** represents the public exponent to use. The data is a byte
-** encoded integer, in "big endian" order.
-*/
-extern RSAPrivateKey *RSA_NewKey(int keySizeInBits,
- SECItem * publicExponent);
-
-/*
-** Perform a raw public-key operation
-** Length of input and output buffers are equal to key's modulus len.
-*/
-extern SECStatus RSA_PublicKeyOp(RSAPublicKey * key,
- unsigned char * output,
- const unsigned char * input);
-
-/*
-** Perform a raw private-key operation
-** Length of input and output buffers are equal to key's modulus len.
-*/
-extern SECStatus RSA_PrivateKeyOp(RSAPrivateKey * key,
- unsigned char * output,
- const unsigned char * input);
-
-/*
-** Perform a raw private-key operation, and check the parameters used in
-** the operation for validity by performing a test operation first.
-** Length of input and output buffers are equal to key's modulus len.
-*/
-extern SECStatus RSA_PrivateKeyOpDoubleChecked(RSAPrivateKey * key,
- unsigned char * output,
- const unsigned char * input);
-
-/*
-** Perform a check of private key parameters for consistency.
-*/
-extern SECStatus RSA_PrivateKeyCheck(RSAPrivateKey *key);
-
-/*
-** Given only minimal private key parameters, fill in the rest of the
-** parameters.
-**
-**
-** All the entries, including those supplied by the caller, will be
-** overwritten with data alocated out of the arena.
-**
-** If no arena is supplied, one will be created.
-**
-** The following fields must be supplied in order for this function
-** to succeed:
-** one of either publicExponent or privateExponent
-** two more of the following 5 parameters (not counting the above).
-** modulus (n)
-** prime1 (p)
-** prime2 (q)
-** publicExponent (e)
-** privateExponent (d)
-**
-** NOTE: if only the publicExponent, privateExponent, and one prime is given,
-** then there may be more than one RSA key that matches that combination. If
-** we find 2 possible valid keys that meet this criteria, we return an error.
-** If we return the wrong key, and the original modulus is compared to the
-** new modulus, both can be factored by calculateing gcd(n_old,n_new) to get
-** the common prime.
-**
-** NOTE: in some cases the publicExponent must be less than 2^23 for this
-** function to work correctly. (The case where we have only one of: modulus
-** prime1 and prime2).
-**
-** All parameters will be replaced in the key structure with new parameters
-** allocated out of the arena. There is no attempt to free the old structures.
-** prime1 will always be greater than prime2 (even if the caller supplies the
-** smaller prime as prime1 or the larger prime as prime2). The parameters are
-** not overwritten on failure.
-**
-** While the remaining Chinese remainder theorem parameters (dp,dp, and qinv)
-** can also be used in reconstructing the private key, they are currently
-** ignored in this implementation.
-*/
-extern SECStatus RSA_PopulatePrivateKey(RSAPrivateKey *key);
-
-/********************************************************************
-** DSA signing algorithm
-*/
-
-/* Generate a new random value within the interval [2, q-1].
-*/
-extern SECStatus DSA_NewRandom(PLArenaPool * arena, const SECItem * q,
- SECItem * random);
-
-/*
-** Generate and return a new DSA public and private key pair,
-** both of which are encoded into a single DSAPrivateKey struct.
-** "params" is a pointer to the PQG parameters for the domain
-** Uses a random seed.
-*/
-extern SECStatus DSA_NewKey(const PQGParams * params,
- DSAPrivateKey ** privKey);
-
-/* signature is caller-supplied buffer of at least 20 bytes.
-** On input, signature->len == size of buffer to hold signature.
-** digest->len == size of digest.
-** On output, signature->len == size of signature in buffer.
-** Uses a random seed.
-*/
-extern SECStatus DSA_SignDigest(DSAPrivateKey * key,
- SECItem * signature,
- const SECItem * digest);
-
-/* signature is caller-supplied buffer of at least 20 bytes.
-** On input, signature->len == size of buffer to hold signature.
-** digest->len == size of digest.
-*/
-extern SECStatus DSA_VerifyDigest(DSAPublicKey * key,
- const SECItem * signature,
- const SECItem * digest);
-
-/* For FIPS compliance testing. Seed must be exactly 20 bytes long */
-extern SECStatus DSA_NewKeyFromSeed(const PQGParams *params,
- const unsigned char * seed,
- DSAPrivateKey **privKey);
-
-/* For FIPS compliance testing. Seed must be exactly 20 bytes. */
-extern SECStatus DSA_SignDigestWithSeed(DSAPrivateKey * key,
- SECItem * signature,
- const SECItem * digest,
- const unsigned char * seed);
-
-/******************************************************
-** Diffie Helman key exchange algorithm
-*/
-
-/* Generates parameters for Diffie-Helman key generation.
-** primeLen is the length in bytes of prime P to be generated.
-*/
-extern SECStatus DH_GenParam(int primeLen, DHParams ** params);
-
-/* Generates a public and private key, both of which are encoded in a single
-** DHPrivateKey struct. Params is input, privKey are output.
-** This is Phase 1 of Diffie Hellman.
-*/
-extern SECStatus DH_NewKey(DHParams * params,
- DHPrivateKey ** privKey);
-
-/*
-** DH_Derive does the Diffie-Hellman phase 2 calculation, using the
-** other party's publicValue, and the prime and our privateValue.
-** maxOutBytes is the requested length of the generated secret in bytes.
-** A zero value means produce a value of any length up to the size of
-** the prime. If successful, derivedSecret->data is set
-** to the address of the newly allocated buffer containing the derived
-** secret, and derivedSecret->len is the size of the secret produced.
-** The size of the secret produced will depend on the value of outBytes.
-** If outBytes is 0, the key length will be all the significant bytes of
-** the derived secret (leading zeros are dropped). This length could be less
-** than the length of the prime. If outBytes is nonzero, the length of the
-** produced key will be outBytes long. If the key is truncated, the most
-** significant bytes are truncated. If it is expanded, zero bytes are added
-** at the beginning.
-** It is the caller's responsibility to free the allocated buffer
-** containing the derived secret.
-*/
-extern SECStatus DH_Derive(SECItem * publicValue,
- SECItem * prime,
- SECItem * privateValue,
- SECItem * derivedSecret,
- unsigned int outBytes);
-
-/*
-** KEA_CalcKey returns octet string with the private key for a dual
-** Diffie-Helman key generation as specified for government key exchange.
-*/
-extern SECStatus KEA_Derive(SECItem *prime,
- SECItem *public1,
- SECItem *public2,
- SECItem *private1,
- SECItem *private2,
- SECItem *derivedSecret);
-
-/*
- * verify that a KEA or DSA public key is a valid key for this prime and
- * subprime domain.
- */
-extern PRBool KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime);
-
-/****************************************
- * J-PAKE key transport
- */
-
-/* Given gx == g^x, create a Schnorr zero-knowledge proof for the value x
- * using the specified hash algorithm and signer ID. The signature is
- * returned in the values gv and r. testRandom must be NULL for a PRNG
- * generated random committment to be used in the sigature. When testRandom
- * is non-NULL, that value must contain a value in the subgroup q; that
- * value will be used instead of a PRNG-generated committment in order to
- * facilitate known-answer tests.
- *
- * If gxIn is non-NULL then it must contain a pre-computed value of g^x that
- * will be used by the function; in this case, the gxOut parameter must be NULL.
- * If the gxIn parameter is NULL then gxOut must be non-NULL; in this case
- * gxOut will contain the value g^x on output.
- *
- * gx (if not supplied by the caller), gv, and r will be allocated in the arena.
- * The arena is *not* optional so do not pass NULL for the arena parameter.
- * The arena should be zeroed when it is freed.
- */
-SECStatus
-JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
- const SECItem * signerID, const SECItem * x,
- const SECItem * testRandom, const SECItem * gxIn, SECItem * gxOut,
- SECItem * gv, SECItem * r);
-
-/* Given gx == g^x, verify the Schnorr zero-knowledge proof (gv, r) for the
- * value x using the specified hash algorithm and signer ID.
- *
- * The arena is *not* optional so do not pass NULL for the arena parameter.
- */
-SECStatus
-JPAKE_Verify(PLArenaPool * arena, const PQGParams * pqg,
- HASH_HashType hashType, const SECItem * signerID,
- const SECItem * peerID, const SECItem * gx,
- const SECItem * gv, const SECItem * r);
-
-/* Call before round 2 with x2, s, and x2s all non-NULL. This will calculate
- * base = g^(x1+x3+x4) (mod p) and x2s = x2*s (mod q). The values to send in
- * round 2 (A and the proof of knowledge of x2s) can then be calculated with
- * JPAKE_Sign using pqg->base = base and x = x2s.
- *
- * Call after round 2 with x2, s, and x2s all NULL, and passing (gx1, gx2, gx3)
- * instead of (gx1, gx3, gx4). This will calculate base = g^(x1+x2+x3). Then call
- * JPAKE_Verify with pqg->base = base and then JPAKE_Final.
- *
- * base and x2s will be allocated in the arena. The arena is *not* optional so
- * do not pass NULL for the arena parameter. The arena should be zeroed when it
- * is freed.
-*/
-SECStatus
-JPAKE_Round2(PLArenaPool * arena, const SECItem * p, const SECItem *q,
- const SECItem * gx1, const SECItem * gx3, const SECItem * gx4,
- SECItem * base, const SECItem * x2, const SECItem * s, SECItem * x2s);
-
-/* K = (B/g^(x2*x4*s))^x2 (mod p)
- *
- * K will be allocated in the arena. The arena is *not* optional so do not pass
- * NULL for the arena parameter. The arena should be zeroed when it is freed.
- */
-SECStatus
-JPAKE_Final(PLArenaPool * arena, const SECItem * p, const SECItem *q,
- const SECItem * x2, const SECItem * gx4, const SECItem * x2s,
- const SECItem * B, SECItem * K);
-
-/******************************************************
-** Elliptic Curve algorithms
-*/
-
-/* Generates a public and private key, both of which are encoded
-** in a single ECPrivateKey struct. Params is input, privKey are
-** output.
-*/
-extern SECStatus EC_NewKey(ECParams * params,
- ECPrivateKey ** privKey);
-
-extern SECStatus EC_NewKeyFromSeed(ECParams * params,
- ECPrivateKey ** privKey,
- const unsigned char* seed,
- int seedlen);
-
-/* Validates an EC public key as described in Section 5.2.2 of
- * X9.62. Such validation prevents against small subgroup attacks
- * when the ECDH primitive is used with the cofactor.
- */
-extern SECStatus EC_ValidatePublicKey(ECParams * params,
- SECItem * publicValue);
-
-/*
-** ECDH_Derive performs a scalar point multiplication of a point
-** representing a (peer's) public key and a large integer representing
-** a private key (its own). Both keys must use the same elliptic curve
-** parameters. If the withCofactor parameter is true, the
-** multiplication also uses the cofactor associated with the curve
-** parameters. The output of this scheme is the x-coordinate of the
-** resulting point. If successful, derivedSecret->data is set to the
-** address of the newly allocated buffer containing the derived
-** secret, and derivedSecret->len is the size of the secret
-** produced. It is the caller's responsibility to free the allocated
-** buffer containing the derived secret.
-*/
-extern SECStatus ECDH_Derive(SECItem * publicValue,
- ECParams * params,
- SECItem * privateValue,
- PRBool withCofactor,
- SECItem * derivedSecret);
-
-/* On input, signature->len == size of buffer to hold signature.
-** digest->len == size of digest.
-** On output, signature->len == size of signature in buffer.
-** Uses a random seed.
-*/
-extern SECStatus ECDSA_SignDigest(ECPrivateKey *key,
- SECItem *signature,
- const SECItem *digest);
-
-/* On input, signature->len == size of buffer to hold signature.
-** digest->len == size of digest.
-*/
-extern SECStatus ECDSA_VerifyDigest(ECPublicKey *key,
- const SECItem *signature,
- const SECItem *digest);
-
-/* Uses the provided seed. */
-extern SECStatus ECDSA_SignDigestWithSeed(ECPrivateKey *key,
- SECItem *signature,
- const SECItem *digest,
- const unsigned char *seed,
- const int seedlen);
-
-/******************************************/
-/*
-** RC4 symmetric stream cypher
-*/
-
-/*
-** Create a new RC4 context suitable for RC4 encryption/decryption.
-** "key" raw key data
-** "len" the number of bytes of key data
-*/
-extern RC4Context *RC4_CreateContext(const unsigned char *key, int len);
-
-extern RC4Context *RC4_AllocateContext(void);
-extern SECStatus RC4_InitContext(RC4Context *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *,
- int,
- unsigned int ,
- unsigned int );
-
-/*
-** Destroy an RC4 encryption/decryption context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void RC4_DestroyContext(RC4Context *cx, PRBool freeit);
-
-/*
-** Perform RC4 encryption.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus RC4_Encrypt(RC4Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/*
-** Perform RC4 decryption.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus RC4_Decrypt(RC4Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/******************************************/
-/*
-** RC2 symmetric block cypher
-*/
-
-/*
-** Create a new RC2 context suitable for RC2 encryption/decryption.
-** "key" raw key data
-** "len" the number of bytes of key data
-** "iv" is the CBC initialization vector (if mode is NSS_RC2_CBC)
-** "mode" one of NSS_RC2 or NSS_RC2_CBC
-** "effectiveKeyLen" is the effective key length (as specified in
-** RFC 2268) in bytes (not bits).
-**
-** When mode is set to NSS_RC2_CBC the RC2 cipher is run in "cipher block
-** chaining" mode.
-*/
-extern RC2Context *RC2_CreateContext(const unsigned char *key, unsigned int len,
- const unsigned char *iv, int mode,
- unsigned effectiveKeyLen);
-extern RC2Context *RC2_AllocateContext(void);
-extern SECStatus RC2_InitContext(RC2Context *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int effectiveKeyLen,
- unsigned int );
-
-/*
-** Destroy an RC2 encryption/decryption context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void RC2_DestroyContext(RC2Context *cx, PRBool freeit);
-
-/*
-** Perform RC2 encryption.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus RC2_Encrypt(RC2Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/*
-** Perform RC2 decryption.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus RC2_Decrypt(RC2Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/******************************************/
-/*
-** RC5 symmetric block cypher -- 64-bit block size
-*/
-
-/*
-** Create a new RC5 context suitable for RC5 encryption/decryption.
-** "key" raw key data
-** "len" the number of bytes of key data
-** "iv" is the CBC initialization vector (if mode is NSS_RC5_CBC)
-** "mode" one of NSS_RC5 or NSS_RC5_CBC
-**
-** When mode is set to NSS_RC5_CBC the RC5 cipher is run in "cipher block
-** chaining" mode.
-*/
-extern RC5Context *RC5_CreateContext(const SECItem *key, unsigned int rounds,
- unsigned int wordSize, const unsigned char *iv, int mode);
-extern RC5Context *RC5_AllocateContext(void);
-extern SECStatus RC5_InitContext(RC5Context *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int rounds,
- unsigned int wordSize);
-
-/*
-** Destroy an RC5 encryption/decryption context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void RC5_DestroyContext(RC5Context *cx, PRBool freeit);
-
-/*
-** Perform RC5 encryption.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus RC5_Encrypt(RC5Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/*
-** Perform RC5 decryption.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-
-extern SECStatus RC5_Decrypt(RC5Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-
-
-/******************************************/
-/*
-** DES symmetric block cypher
-*/
-
-/*
-** Create a new DES context suitable for DES encryption/decryption.
-** "key" raw key data
-** "len" the number of bytes of key data
-** "iv" is the CBC initialization vector (if mode is NSS_DES_CBC or
-** mode is DES_EDE3_CBC)
-** "mode" one of NSS_DES, NSS_DES_CBC, NSS_DES_EDE3 or NSS_DES_EDE3_CBC
-** "encrypt" is PR_TRUE if the context will be used for encryption
-**
-** When mode is set to NSS_DES_CBC or NSS_DES_EDE3_CBC then the DES
-** cipher is run in "cipher block chaining" mode.
-*/
-extern DESContext *DES_CreateContext(const unsigned char *key,
- const unsigned char *iv,
- int mode, PRBool encrypt);
-extern DESContext *DES_AllocateContext(void);
-extern SECStatus DES_InitContext(DESContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int encrypt,
- unsigned int );
-
-/*
-** Destroy an DES encryption/decryption context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void DES_DestroyContext(DESContext *cx, PRBool freeit);
-
-/*
-** Perform DES encryption.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-**
-** NOTE: the inputLen must be a multiple of DES_KEY_LENGTH
-*/
-extern SECStatus DES_Encrypt(DESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/*
-** Perform DES decryption.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-**
-** NOTE: the inputLen must be a multiple of DES_KEY_LENGTH
-*/
-extern SECStatus DES_Decrypt(DESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/******************************************/
-/*
-** SEED symmetric block cypher
-*/
-extern SEEDContext *
-SEED_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, PRBool encrypt);
-extern SEEDContext *SEED_AllocateContext(void);
-extern SECStatus SEED_InitContext(SEEDContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode, unsigned int encrypt,
- unsigned int );
-extern void SEED_DestroyContext(SEEDContext *cx, PRBool freeit);
-extern SECStatus
-SEED_Encrypt(SEEDContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-extern SECStatus
-SEED_Decrypt(SEEDContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/******************************************/
-/*
-** AES symmetric block cypher (Rijndael)
-*/
-
-/*
-** Create a new AES context suitable for AES encryption/decryption.
-** "key" raw key data
-** "keylen" the number of bytes of key data (16, 24, or 32)
-** "blocklen" is the blocksize to use (16, 24, or 32)
-** XXX currently only blocksize==16 has been tested!
-*/
-extern AESContext *
-AES_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, int encrypt,
- unsigned int keylen, unsigned int blocklen);
-extern AESContext *AES_AllocateContext(void);
-extern SECStatus AES_InitContext(AESContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int encrypt,
- unsigned int blocklen);
-
-/*
-** Destroy a AES encryption/decryption context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void
-AES_DestroyContext(AESContext *cx, PRBool freeit);
-
-/*
-** Perform AES encryption.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus
-AES_Encrypt(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/*
-** Perform AES decryption.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus
-AES_Decrypt(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/******************************************/
-/*
-** AES key wrap algorithm, RFC 3394
-*/
-
-/*
-** Create a new AES context suitable for AES encryption/decryption.
-** "key" raw key data
-** "iv" The 8 byte "initial value"
-** "encrypt", a boolean, true for key wrapping, false for unwrapping.
-** "keylen" the number of bytes of key data (16, 24, or 32)
-*/
-extern AESKeyWrapContext *
-AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv,
- int encrypt, unsigned int keylen);
-extern AESKeyWrapContext * AESKeyWrap_AllocateContext(void);
-extern SECStatus
- AESKeyWrap_InitContext(AESKeyWrapContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int ,
- unsigned int encrypt,
- unsigned int );
-
-/*
-** Destroy a AES KeyWrap context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void
-AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit);
-
-/*
-** Perform AES key wrap.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus
-AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/*
-** Perform AES key unwrap.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus
-AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- /******************************************/
-/*
-** Camellia symmetric block cypher
-*/
-
-/*
-** Create a new Camellia context suitable for Camellia encryption/decryption.
-** "key" raw key data
-** "keylen" the number of bytes of key data (16, 24, or 32)
-*/
-extern CamelliaContext *
-Camellia_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, int encrypt, unsigned int keylen);
-
-extern CamelliaContext *Camellia_AllocateContext(void);
-extern SECStatus Camellia_InitContext(CamelliaContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int encrypt,
- unsigned int unused);
-/*
-** Destroy a Camellia encryption/decryption context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void
-Camellia_DestroyContext(CamelliaContext *cx, PRBool freeit);
-
-/*
-** Perform Camellia encryption.
-** "cx" the context
-** "output" the output buffer to store the encrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus
-Camellia_Encrypt(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/*
-** Perform Camellia decryption.
-** "cx" the context
-** "output" the output buffer to store the decrypted data.
-** "outputLen" how much data is stored in "output". Set by the routine
-** after some data is stored in output.
-** "maxOutputLen" the maximum amount of data that can ever be
-** stored in "output"
-** "input" the input data
-** "inputLen" the amount of input data
-*/
-extern SECStatus
-Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-
-/******************************************/
-/*
-** MD5 secure hash function
-*/
-
-/*
-** Hash a null terminated string "src" into "dest" using MD5
-*/
-extern SECStatus MD5_Hash(unsigned char *dest, const char *src);
-
-/*
-** Hash a non-null terminated string "src" into "dest" using MD5
-*/
-extern SECStatus MD5_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
-
-/*
-** Create a new MD5 context
-*/
-extern MD5Context *MD5_NewContext(void);
-
-
-/*
-** Destroy an MD5 secure hash context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void MD5_DestroyContext(MD5Context *cx, PRBool freeit);
-
-/*
-** Reset an MD5 context, preparing it for a fresh round of hashing
-*/
-extern void MD5_Begin(MD5Context *cx);
-
-/*
-** Update the MD5 hash function with more data.
-** "cx" the context
-** "input" the data to hash
-** "inputLen" the amount of data to hash
-*/
-extern void MD5_Update(MD5Context *cx,
- const unsigned char *input, unsigned int inputLen);
-
-/*
-** Finish the MD5 hash function. Produce the digested results in "digest"
-** "cx" the context
-** "digest" where the 16 bytes of digest data are stored
-** "digestLen" where the digest length (16) is stored
-** "maxDigestLen" the maximum amount of data that can ever be
-** stored in "digest"
-*/
-extern void MD5_End(MD5Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-
-/*
-** Export the current state of the MD5 hash without appending the standard
-** padding and length bytes. Produce the digested results in "digest"
-** "cx" the context
-** "digest" where the 16 bytes of digest data are stored
-** "digestLen" where the digest length (16) is stored (optional)
-** "maxDigestLen" the maximum amount of data that can ever be
-** stored in "digest"
-*/
-extern void MD5_EndRaw(MD5Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-
-/*
- * Return the the size of a buffer needed to flatten the MD5 Context into
- * "cx" the context
- * returns size;
- */
-extern unsigned int MD5_FlattenSize(MD5Context *cx);
-
-/*
- * Flatten the MD5 Context into a buffer:
- * "cx" the context
- * "space" the buffer to flatten to
- * returns status;
- */
-extern SECStatus MD5_Flatten(MD5Context *cx,unsigned char *space);
-
-/*
- * Resurrect a flattened context into a MD5 Context
- * "space" the buffer of the flattend buffer
- * "arg" ptr to void used by cryptographic resurrect
- * returns resurected context;
- */
-extern MD5Context * MD5_Resurrect(unsigned char *space, void *arg);
-extern void MD5_Clone(MD5Context *dest, MD5Context *src);
-
-/*
-** trace the intermediate state info of the MD5 hash.
-*/
-extern void MD5_TraceState(MD5Context *cx);
-
-
-/******************************************/
-/*
-** MD2 secure hash function
-*/
-
-/*
-** Hash a null terminated string "src" into "dest" using MD2
-*/
-extern SECStatus MD2_Hash(unsigned char *dest, const char *src);
-
-/*
-** Create a new MD2 context
-*/
-extern MD2Context *MD2_NewContext(void);
-
-
-/*
-** Destroy an MD2 secure hash context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void MD2_DestroyContext(MD2Context *cx, PRBool freeit);
-
-/*
-** Reset an MD2 context, preparing it for a fresh round of hashing
-*/
-extern void MD2_Begin(MD2Context *cx);
-
-/*
-** Update the MD2 hash function with more data.
-** "cx" the context
-** "input" the data to hash
-** "inputLen" the amount of data to hash
-*/
-extern void MD2_Update(MD2Context *cx,
- const unsigned char *input, unsigned int inputLen);
-
-/*
-** Finish the MD2 hash function. Produce the digested results in "digest"
-** "cx" the context
-** "digest" where the 16 bytes of digest data are stored
-** "digestLen" where the digest length (16) is stored
-** "maxDigestLen" the maximum amount of data that can ever be
-** stored in "digest"
-*/
-extern void MD2_End(MD2Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-
-/*
- * Return the the size of a buffer needed to flatten the MD2 Context into
- * "cx" the context
- * returns size;
- */
-extern unsigned int MD2_FlattenSize(MD2Context *cx);
-
-/*
- * Flatten the MD2 Context into a buffer:
- * "cx" the context
- * "space" the buffer to flatten to
- * returns status;
- */
-extern SECStatus MD2_Flatten(MD2Context *cx,unsigned char *space);
-
-/*
- * Resurrect a flattened context into a MD2 Context
- * "space" the buffer of the flattend buffer
- * "arg" ptr to void used by cryptographic resurrect
- * returns resurected context;
- */
-extern MD2Context * MD2_Resurrect(unsigned char *space, void *arg);
-extern void MD2_Clone(MD2Context *dest, MD2Context *src);
-
-/******************************************/
-/*
-** SHA-1 secure hash function
-*/
-
-/*
-** Hash a null terminated string "src" into "dest" using SHA-1
-*/
-extern SECStatus SHA1_Hash(unsigned char *dest, const char *src);
-
-/*
-** Hash a non-null terminated string "src" into "dest" using SHA-1
-*/
-extern SECStatus SHA1_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
-
-/*
-** Create a new SHA-1 context
-*/
-extern SHA1Context *SHA1_NewContext(void);
-
-
-/*
-** Destroy a SHA-1 secure hash context.
-** "cx" the context
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void SHA1_DestroyContext(SHA1Context *cx, PRBool freeit);
-
-/*
-** Reset a SHA-1 context, preparing it for a fresh round of hashing
-*/
-extern void SHA1_Begin(SHA1Context *cx);
-
-/*
-** Update the SHA-1 hash function with more data.
-** "cx" the context
-** "input" the data to hash
-** "inputLen" the amount of data to hash
-*/
-extern void SHA1_Update(SHA1Context *cx, const unsigned char *input,
- unsigned int inputLen);
-
-/*
-** Finish the SHA-1 hash function. Produce the digested results in "digest"
-** "cx" the context
-** "digest" where the 16 bytes of digest data are stored
-** "digestLen" where the digest length (20) is stored
-** "maxDigestLen" the maximum amount of data that can ever be
-** stored in "digest"
-*/
-extern void SHA1_End(SHA1Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-
-/*
-** Export the current state of the SHA-1 hash without appending the standard
-** padding and length bytes. Produce the digested results in "digest"
-** "cx" the context
-** "digest" where the 20 bytes of digest data are stored
-** "digestLen" where the digest length (20) is stored (optional)
-** "maxDigestLen" the maximum amount of data that can ever be
-** stored in "digest"
-*/
-extern void SHA1_EndRaw(SHA1Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-
-/*
-** trace the intermediate state info of the SHA1 hash.
-*/
-extern void SHA1_TraceState(SHA1Context *cx);
-
-/*
- * Return the the size of a buffer needed to flatten the SHA-1 Context into
- * "cx" the context
- * returns size;
- */
-extern unsigned int SHA1_FlattenSize(SHA1Context *cx);
-
-/*
- * Flatten the SHA-1 Context into a buffer:
- * "cx" the context
- * "space" the buffer to flatten to
- * returns status;
- */
-extern SECStatus SHA1_Flatten(SHA1Context *cx,unsigned char *space);
-
-/*
- * Resurrect a flattened context into a SHA-1 Context
- * "space" the buffer of the flattend buffer
- * "arg" ptr to void used by cryptographic resurrect
- * returns resurected context;
- */
-extern SHA1Context * SHA1_Resurrect(unsigned char *space, void *arg);
-extern void SHA1_Clone(SHA1Context *dest, SHA1Context *src);
-
-/******************************************/
-
-extern SHA224Context *SHA224_NewContext(void);
-extern void SHA224_DestroyContext(SHA224Context *cx, PRBool freeit);
-extern void SHA224_Begin(SHA224Context *cx);
-extern void SHA224_Update(SHA224Context *cx, const unsigned char *input,
- unsigned int inputLen);
-extern void SHA224_End(SHA224Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-/*
-** Export the current state of the SHA-224 hash without appending the standard
-** padding and length bytes. Produce the digested results in "digest"
-** "cx" the context
-** "digest" where the 28 bytes of digest data are stored
-** "digestLen" where the digest length (28) is stored (optional)
-** "maxDigestLen" the maximum amount of data that can ever be
-** stored in "digest"
-*/
-extern void SHA224_EndRaw(SHA224Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-extern SECStatus SHA224_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
-extern SECStatus SHA224_Hash(unsigned char *dest, const char *src);
-extern void SHA224_TraceState(SHA224Context *cx);
-extern unsigned int SHA224_FlattenSize(SHA224Context *cx);
-extern SECStatus SHA224_Flatten(SHA224Context *cx,unsigned char *space);
-extern SHA224Context * SHA224_Resurrect(unsigned char *space, void *arg);
-extern void SHA224_Clone(SHA224Context *dest, SHA224Context *src);
-
-/******************************************/
-
-extern SHA256Context *SHA256_NewContext(void);
-extern void SHA256_DestroyContext(SHA256Context *cx, PRBool freeit);
-extern void SHA256_Begin(SHA256Context *cx);
-extern void SHA256_Update(SHA256Context *cx, const unsigned char *input,
- unsigned int inputLen);
-extern void SHA256_End(SHA256Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-/*
-** Export the current state of the SHA-256 hash without appending the standard
-** padding and length bytes. Produce the digested results in "digest"
-** "cx" the context
-** "digest" where the 32 bytes of digest data are stored
-** "digestLen" where the digest length (32) is stored (optional)
-** "maxDigestLen" the maximum amount of data that can ever be
-** stored in "digest"
-*/
-extern void SHA256_EndRaw(SHA256Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-extern SECStatus SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
-extern SECStatus SHA256_Hash(unsigned char *dest, const char *src);
-extern void SHA256_TraceState(SHA256Context *cx);
-extern unsigned int SHA256_FlattenSize(SHA256Context *cx);
-extern SECStatus SHA256_Flatten(SHA256Context *cx,unsigned char *space);
-extern SHA256Context * SHA256_Resurrect(unsigned char *space, void *arg);
-extern void SHA256_Clone(SHA256Context *dest, SHA256Context *src);
-
-/******************************************/
-
-extern SHA512Context *SHA512_NewContext(void);
-extern void SHA512_DestroyContext(SHA512Context *cx, PRBool freeit);
-extern void SHA512_Begin(SHA512Context *cx);
-extern void SHA512_Update(SHA512Context *cx, const unsigned char *input,
- unsigned int inputLen);
-/*
-** Export the current state of the SHA-512 hash without appending the standard
-** padding and length bytes. Produce the digested results in "digest"
-** "cx" the context
-** "digest" where the 64 bytes of digest data are stored
-** "digestLen" where the digest length (64) is stored (optional)
-** "maxDigestLen" the maximum amount of data that can ever be
-** stored in "digest"
-*/
-extern void SHA512_EndRaw(SHA512Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-extern void SHA512_End(SHA512Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-extern SECStatus SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
-extern SECStatus SHA512_Hash(unsigned char *dest, const char *src);
-extern void SHA512_TraceState(SHA512Context *cx);
-extern unsigned int SHA512_FlattenSize(SHA512Context *cx);
-extern SECStatus SHA512_Flatten(SHA512Context *cx,unsigned char *space);
-extern SHA512Context * SHA512_Resurrect(unsigned char *space, void *arg);
-extern void SHA512_Clone(SHA512Context *dest, SHA512Context *src);
-
-/******************************************/
-
-extern SHA384Context *SHA384_NewContext(void);
-extern void SHA384_DestroyContext(SHA384Context *cx, PRBool freeit);
-extern void SHA384_Begin(SHA384Context *cx);
-extern void SHA384_Update(SHA384Context *cx, const unsigned char *input,
- unsigned int inputLen);
-extern void SHA384_End(SHA384Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-/*
-** Export the current state of the SHA-384 hash without appending the standard
-** padding and length bytes. Produce the digested results in "digest"
-** "cx" the context
-** "digest" where the 48 bytes of digest data are stored
-** "digestLen" where the digest length (48) is stored (optional)
-** "maxDigestLen" the maximum amount of data that can ever be
-** stored in "digest"
-*/
-extern void SHA384_EndRaw(SHA384Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-extern SECStatus SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
-extern SECStatus SHA384_Hash(unsigned char *dest, const char *src);
-extern void SHA384_TraceState(SHA384Context *cx);
-extern unsigned int SHA384_FlattenSize(SHA384Context *cx);
-extern SECStatus SHA384_Flatten(SHA384Context *cx,unsigned char *space);
-extern SHA384Context * SHA384_Resurrect(unsigned char *space, void *arg);
-extern void SHA384_Clone(SHA384Context *dest, SHA384Context *src);
-
-/****************************************
- * implement TLS 1.0 Pseudo Random Function (PRF) and TLS P_hash function
- */
-
-extern SECStatus
-TLS_PRF(const SECItem *secret, const char *label, SECItem *seed,
- SECItem *result, PRBool isFIPS);
-
-extern SECStatus
-TLS_P_hash(HASH_HashType hashAlg, const SECItem *secret, const char *label,
- SECItem *seed, SECItem *result, PRBool isFIPS);
-
-/******************************************/
-/*
-** Pseudo Random Number Generation. FIPS compliance desirable.
-*/
-
-/*
-** Initialize the global RNG context and give it some seed input taken
-** from the system. This function is thread-safe and will only allow
-** the global context to be initialized once. The seed input is likely
-** small, so it is imperative that RNG_RandomUpdate() be called with
-** additional seed data before the generator is used. A good way to
-** provide the generator with additional entropy is to call
-** RNG_SystemInfoForRNG(). Note that NSS_Init() does exactly that.
-*/
-extern SECStatus RNG_RNGInit(void);
-
-/*
-** Update the global random number generator with more seeding
-** material
-*/
-extern SECStatus RNG_RandomUpdate(const void *data, size_t bytes);
-
-/*
-** Generate some random bytes, using the global random number generator
-** object.
-*/
-extern SECStatus RNG_GenerateGlobalRandomBytes(void *dest, size_t len);
-
-/* Destroy the global RNG context. After a call to RNG_RNGShutdown()
-** a call to RNG_RNGInit() is required in order to use the generator again,
-** along with seed data (see the comment above RNG_RNGInit()).
-*/
-extern void RNG_RNGShutdown(void);
-
-extern void RNG_SystemInfoForRNG(void);
-
-/*
- * FIPS 186-2 Change Notice 1 RNG Algorithm 1, used both to
- * generate the DSA X parameter and as a generic purpose RNG.
- *
- * The following two FIPS186Change functions are needed for
- * NIST RNG Validation System.
- */
-
-/*
- * FIPS186Change_GenerateX is now deprecated. It will return SECFailure with
- * the error set to PR_NOT_IMPLEMENTED_ERROR.
- */
-extern SECStatus
-FIPS186Change_GenerateX(unsigned char *XKEY,
- const unsigned char *XSEEDj,
- unsigned char *x_j);
-
-/*
- * When generating the DSA X parameter, we generate 2*GSIZE bytes
- * of random output and reduce it mod q.
- *
- * Input: w, 2*GSIZE bytes
- * q, DSA_SUBPRIME_LEN bytes
- * Output: xj, DSA_SUBPRIME_LEN bytes
- */
-extern SECStatus
-FIPS186Change_ReduceModQForDSA(const unsigned char *w,
- const unsigned char *q,
- unsigned char *xj);
-
-/*
- * The following functions are for FIPS poweron self test and FIPS algorithm
- * testing.
- */
-extern SECStatus
-PRNGTEST_Instantiate(const PRUint8 *entropy, unsigned int entropy_len,
- const PRUint8 *nonce, unsigned int nonce_len,
- const PRUint8 *personal_string, unsigned int ps_len);
-
-extern SECStatus
-PRNGTEST_Reseed(const PRUint8 *entropy, unsigned int entropy_len,
- const PRUint8 *additional, unsigned int additional_len);
-
-extern SECStatus
-PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
- const PRUint8 *additional, unsigned int additional_len);
-
-extern SECStatus
-PRNGTEST_Uninstantiate(void);
-
-extern SECStatus
-PRNGTEST_RunHealthTests(void);
-
-/* Generate PQGParams and PQGVerify structs.
- * Length of seed and length of h both equal length of P.
- * All lengths are specified by "j", according to the table above.
- *
- * The verify parameters will conform to FIPS186-1.
- */
-extern SECStatus
-PQG_ParamGen(unsigned int j, /* input : determines length of P. */
- PQGParams **pParams, /* output: P Q and G returned here */
- PQGVerify **pVfy); /* output: counter and seed. */
-
-/* Generate PQGParams and PQGVerify structs.
- * Length of P specified by j. Length of h will match length of P.
- * Length of SEED in bytes specified in seedBytes.
- * seedBbytes must be in the range [20..255] or an error will result.
- *
- * The verify parameters will conform to FIPS186-1.
- */
-extern SECStatus
-PQG_ParamGenSeedLen(
- unsigned int j, /* input : determines length of P. */
- unsigned int seedBytes, /* input : length of seed in bytes.*/
- PQGParams **pParams, /* output: P Q and G returned here */
- PQGVerify **pVfy); /* output: counter and seed. */
-
-/* Generate PQGParams and PQGVerify structs.
- * Length of P specified by L in bits.
- * Length of Q specified by N in bits.
- * Length of SEED in bytes specified in seedBytes.
- * seedBbytes must be in the range [N..L*2] or an error will result.
- *
- * Not that J uses the above table, L is the length exact. L and N must
- * match the table below or an error will result:
- *
- * L N
- * 1024 160
- * 2048 224
- * 2048 256
- * 3072 256
- *
- * If N or seedBytes are set to zero, then PQG_ParamGenSeedLen will
- * pick a default value (typically the smallest secure value for these
- * variables).
- *
- * The verify parameters will conform to FIPS186-3 using the smallest
- * permissible hash for the key strength.
- */
-extern SECStatus
-PQG_ParamGenV2(
- unsigned int L, /* input : determines length of P. */
- unsigned int N, /* input : determines length of Q. */
- unsigned int seedBytes, /* input : length of seed in bytes.*/
- PQGParams **pParams, /* output: P Q and G returned here */
- PQGVerify **pVfy); /* output: counter and seed. */
-
-
-/* Test PQGParams for validity as DSS PQG values.
- * If vfy is non-NULL, test PQGParams to make sure they were generated
- * using the specified seed, counter, and h values.
- *
- * Return value indicates whether Verification operation ran successfully
- * to completion, but does not indicate if PQGParams are valid or not.
- * If return value is SECSuccess, then *pResult has these meanings:
- * SECSuccess: PQGParams are valid.
- * SECFailure: PQGParams are invalid.
- *
- * Verify the PQG againts the counter, SEED and h.
- * These tests are specified in FIPS 186-3 Appendix A.1.1.1, A.1.1.3, and A.2.2
- * PQG_VerifyParams will automatically choose the appropriate test.
- */
-
-extern SECStatus PQG_VerifyParams(const PQGParams *params,
- const PQGVerify *vfy, SECStatus *result);
-
-extern void PQG_DestroyParams(PQGParams *params);
-
-extern void PQG_DestroyVerify(PQGVerify *vfy);
-
-
-/*
- * clean-up any global tables freebl may have allocated after it starts up.
- * This function is not thread safe and should be called only after the
- * library has been quiessed.
- */
-extern void BL_Cleanup(void);
-
-/* unload freebl shared library from memory */
-extern void BL_Unload(void);
-
-/**************************************************************************
- * Verify a given Shared library signature *
- **************************************************************************/
-PRBool BLAPI_SHVerify(const char *name, PRFuncPtr addr);
-
-/**************************************************************************
- * Verify a given filename's signature *
- **************************************************************************/
-PRBool BLAPI_SHVerifyFile(const char *shName);
-
-/**************************************************************************
- * Verify Are Own Shared library signature *
- **************************************************************************/
-PRBool BLAPI_VerifySelf(const char *name);
-
-/*********************************************************************/
-extern const SECHashObject * HASH_GetRawHashObject(HASH_HashType hashType);
-
-extern void BL_SetForkState(PRBool forked);
-
-SEC_END_PROTOS
-
-#endif /* _BLAPI_H_ */
diff --git a/security/nss/lib/freebl/blapii.h b/security/nss/lib/freebl/blapii.h
deleted file mode 100644
index 3ba7b7c22..000000000
--- a/security/nss/lib/freebl/blapii.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * blapii.h - private data structures and prototypes for the crypto library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _BLAPII_H_
-#define _BLAPII_H_
-
-#include "blapit.h"
-
-/* max block size of supported block ciphers */
-#define MAX_BLOCK_SIZE 16
-
-typedef SECStatus (*freeblCipherFunc)(void *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
- unsigned int blocksize);
-typedef void (*freeblDestroyFunc)(void *cx, PRBool freeit);
-
-SEC_BEGIN_PROTOS
-
-#if defined(XP_UNIX) && !defined(NO_FORK_CHECK)
-
-extern PRBool bl_parentForkedAfterC_Initialize;
-
-#define SKIP_AFTER_FORK(x) if (!bl_parentForkedAfterC_Initialize) x
-
-#else
-
-#define SKIP_AFTER_FORK(x) x
-
-#endif
-
-SEC_END_PROTOS
-
-#endif /* _BLAPII_H_ */
-
diff --git a/security/nss/lib/freebl/blapit.h b/security/nss/lib/freebl/blapit.h
deleted file mode 100644
index fc08dd246..000000000
--- a/security/nss/lib/freebl/blapit.h
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * blapit.h - public data structures for the crypto library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _BLAPIT_H_
-#define _BLAPIT_H_
-
-#include "seccomon.h"
-#include "prlink.h"
-#include "plarena.h"
-#include "ecl-exp.h"
-
-
-/* RC2 operation modes */
-#define NSS_RC2 0
-#define NSS_RC2_CBC 1
-
-/* RC5 operation modes */
-#define NSS_RC5 0
-#define NSS_RC5_CBC 1
-
-/* DES operation modes */
-#define NSS_DES 0
-#define NSS_DES_CBC 1
-#define NSS_DES_EDE3 2
-#define NSS_DES_EDE3_CBC 3
-
-#define DES_KEY_LENGTH 8 /* Bytes */
-
-/* AES operation modes */
-#define NSS_AES 0
-#define NSS_AES_CBC 1
-#define NSS_AES_CTS 2
-#define NSS_AES_CTR 3
-#define NSS_AES_GCM 4
-
-/* Camellia operation modes */
-#define NSS_CAMELLIA 0
-#define NSS_CAMELLIA_CBC 1
-
-/* SEED operation modes */
-#define NSS_SEED 0
-#define NSS_SEED_CBC 1
-
-#define DSA1_SUBPRIME_LEN 20 /* Bytes */
-#define DSA1_SIGNATURE_LEN (DSA1_SUBPRIME_LEN*2) /* Bytes */
-#define DSA_MAX_SUBPRIME_LEN 32 /* Bytes */
-#define DSA_MAX_SIGNATURE_LEN (DSA_MAX_SUBPRIME_LEN*2)/* Bytes */
-
-/*
- * Mark the old defines as deprecated. This will warn code that expected
- * DSA1 only that they need to change if the are to support DSA2.
- */
-#if defined(__GNUC__) && (__GNUC__ > 3)
-/* make GCC warn when we use these #defines */
-typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
-#define DSA_SUBPRIME_LEN ((__BLAPI_DEPRECATED)DSA1_SUBPRIME_LEN)
-#define DSA_SIGNATURE_LEN ((__BLAPI_DEPRECATED)DSA1_SIGNATURE_LEN)
-#define DSA_Q_BITS ((__BLAPI_DEPRECATED)(DSA1_SUBPRIME_LEN*8))
-#else
-#ifdef _WIN32
-/* This magic gets the windows compiler to give us a deprecation
- * warning */
-#pragma deprecated(DSA_SUBPRIME_LEN, DSA_SIGNATURE_LEN, DSA_QBITS)
-#endif
-#define DSA_SUBPRIME_LEN DSA1_SUBPRIME_LEN
-#define DSA_SIGNATURE_LEN DSA1_SIGNATURE_LEN
-#define DSA_Q_BITS (DSA1_SUBPRIME_LEN*8)
-#endif
-
-
-/* XXX We shouldn't have to hard code this limit. For
- * now, this is the quickest way to support ECDSA signature
- * processing (ECDSA signature lengths depend on curve
- * size). This limit is sufficient for curves upto
- * 576 bits.
- */
-#define MAX_ECKEY_LEN 72 /* Bytes */
-
-/* EC point compression format */
-#define EC_POINT_FORM_COMPRESSED_Y0 0x02
-#define EC_POINT_FORM_COMPRESSED_Y1 0x03
-#define EC_POINT_FORM_UNCOMPRESSED 0x04
-#define EC_POINT_FORM_HYBRID_Y0 0x06
-#define EC_POINT_FORM_HYBRID_Y1 0x07
-
-/*
- * Number of bytes each hash algorithm produces
- */
-#define MD2_LENGTH 16 /* Bytes */
-#define MD5_LENGTH 16 /* Bytes */
-#define SHA1_LENGTH 20 /* Bytes */
-#define SHA256_LENGTH 32 /* bytes */
-#define SHA384_LENGTH 48 /* bytes */
-#define SHA512_LENGTH 64 /* bytes */
-#define HASH_LENGTH_MAX SHA512_LENGTH
-
-/*
- * Input block size for each hash algorithm.
- */
-
-#define MD2_BLOCK_LENGTH 64 /* bytes */
-#define MD5_BLOCK_LENGTH 64 /* bytes */
-#define SHA1_BLOCK_LENGTH 64 /* bytes */
-#define SHA224_BLOCK_LENGTH 64 /* bytes */
-#define SHA256_BLOCK_LENGTH 64 /* bytes */
-#define SHA384_BLOCK_LENGTH 128 /* bytes */
-#define SHA512_BLOCK_LENGTH 128 /* bytes */
-#define HASH_BLOCK_LENGTH_MAX SHA512_BLOCK_LENGTH
-
-#define AES_KEY_WRAP_IV_BYTES 8
-#define AES_KEY_WRAP_BLOCK_SIZE 8 /* bytes */
-#define AES_BLOCK_SIZE 16 /* bytes */
-
-#define AES_128_KEY_LENGTH 16 /* bytes */
-#define AES_192_KEY_LENGTH 24 /* bytes */
-#define AES_256_KEY_LENGTH 32 /* bytes */
-
-#define CAMELLIA_BLOCK_SIZE 16 /* bytes */
-
-#define SEED_BLOCK_SIZE 16 /* bytes */
-#define SEED_KEY_LENGTH 16 /* bytes */
-
-#define NSS_FREEBL_DEFAULT_CHUNKSIZE 2048
-
-/*
- * These values come from the initial key size limits from the PKCS #11
- * module. They may be arbitrarily adjusted to any value freebl supports.
- */
-#define RSA_MIN_MODULUS_BITS 128
-#define RSA_MAX_MODULUS_BITS 16384
-#define RSA_MAX_EXPONENT_BITS 64
-#define DH_MIN_P_BITS 128
-#define DH_MAX_P_BITS 16384
-
-/*
- * The FIPS 186-1 algorithm for generating primes P and Q allows only 9
- * distinct values for the length of P, and only one value for the
- * length of Q.
- * The algorithm uses a variable j to indicate which of the 9 lengths
- * of P is to be used.
- * The following table relates j to the lengths of P and Q in bits.
- *
- * j bits in P bits in Q
- * _ _________ _________
- * 0 512 160
- * 1 576 160
- * 2 640 160
- * 3 704 160
- * 4 768 160
- * 5 832 160
- * 6 896 160
- * 7 960 160
- * 8 1024 160
- *
- * The FIPS-186-1 compliant PQG generator takes j as an input parameter.
- *
- * FIPS 186-3 algorithm specifies 4 distinct P and Q sizes:
- *
- * bits in P bits in Q
- * _________ _________
- * 1024 160
- * 2048 224
- * 2048 256
- * 3072 256
- *
- * The FIPS-186-3 complaiant PQG generator (PQG V2) takes arbitrary p and q
- * lengths as input and returns an error if they aren't in this list.
- */
-
-#define DSA1_Q_BITS 160
-#define DSA_MAX_P_BITS 3072
-#define DSA_MIN_P_BITS 512
-#define DSA_MAX_Q_BITS 256
-#define DSA_MIN_Q_BITS 160
-
-#if DSA_MAX_Q_BITS != DSA_MAX_SUBPRIME_LEN*8
-#error "Inconsistent declaration of DSA SUBPRIME/Q parameters in blapit.h"
-#endif
-
-
-/*
- * function takes desired number of bits in P,
- * returns index (0..8) or -1 if number of bits is invalid.
- */
-#define PQG_PBITS_TO_INDEX(bits) \
- (((bits) < 512 || (bits) > 1024 || (bits) % 64) ? \
- -1 : (int)((bits)-512)/64)
-
-/*
- * function takes index (0-8)
- * returns number of bits in P for that index, or -1 if index is invalid.
- */
-#define PQG_INDEX_TO_PBITS(j) (((unsigned)(j) > 8) ? -1 : (512 + 64 * (j)))
-
-
-/***************************************************************************
-** Opaque objects
-*/
-
-struct DESContextStr ;
-struct RC2ContextStr ;
-struct RC4ContextStr ;
-struct RC5ContextStr ;
-struct AESContextStr ;
-struct CamelliaContextStr ;
-struct MD2ContextStr ;
-struct MD5ContextStr ;
-struct SHA1ContextStr ;
-struct SHA256ContextStr ;
-struct SHA512ContextStr ;
-struct AESKeyWrapContextStr ;
-struct SEEDContextStr ;
-
-typedef struct DESContextStr DESContext;
-typedef struct RC2ContextStr RC2Context;
-typedef struct RC4ContextStr RC4Context;
-typedef struct RC5ContextStr RC5Context;
-typedef struct AESContextStr AESContext;
-typedef struct CamelliaContextStr CamelliaContext;
-typedef struct MD2ContextStr MD2Context;
-typedef struct MD5ContextStr MD5Context;
-typedef struct SHA1ContextStr SHA1Context;
-typedef struct SHA256ContextStr SHA256Context;
-/* SHA224Context is really a SHA256ContextStr. This is not a mistake. */
-typedef struct SHA256ContextStr SHA224Context;
-typedef struct SHA512ContextStr SHA512Context;
-/* SHA384Context is really a SHA512ContextStr. This is not a mistake. */
-typedef struct SHA512ContextStr SHA384Context;
-typedef struct AESKeyWrapContextStr AESKeyWrapContext;
-typedef struct SEEDContextStr SEEDContext;
-
-/***************************************************************************
-** RSA Public and Private Key structures
-*/
-
-/* member names from PKCS#1, section 7.1 */
-struct RSAPublicKeyStr {
- PLArenaPool * arena;
- SECItem modulus;
- SECItem publicExponent;
-};
-typedef struct RSAPublicKeyStr RSAPublicKey;
-
-/* member names from PKCS#1, section 7.2 */
-struct RSAPrivateKeyStr {
- PLArenaPool * arena;
- SECItem version;
- SECItem modulus;
- SECItem publicExponent;
- SECItem privateExponent;
- SECItem prime1;
- SECItem prime2;
- SECItem exponent1;
- SECItem exponent2;
- SECItem coefficient;
-};
-typedef struct RSAPrivateKeyStr RSAPrivateKey;
-
-
-/***************************************************************************
-** DSA Public and Private Key and related structures
-*/
-
-struct PQGParamsStr {
- PLArenaPool *arena;
- SECItem prime; /* p */
- SECItem subPrime; /* q */
- SECItem base; /* g */
- /* XXX chrisk: this needs to be expanded to hold j and validationParms (RFC2459 7.3.2) */
-};
-typedef struct PQGParamsStr PQGParams;
-
-struct PQGVerifyStr {
- PLArenaPool * arena; /* includes this struct, seed, & h. */
- unsigned int counter;
- SECItem seed;
- SECItem h;
-};
-typedef struct PQGVerifyStr PQGVerify;
-
-struct DSAPublicKeyStr {
- PQGParams params;
- SECItem publicValue;
-};
-typedef struct DSAPublicKeyStr DSAPublicKey;
-
-struct DSAPrivateKeyStr {
- PQGParams params;
- SECItem publicValue;
- SECItem privateValue;
-};
-typedef struct DSAPrivateKeyStr DSAPrivateKey;
-
-/***************************************************************************
-** Diffie-Hellman Public and Private Key and related structures
-** Structure member names suggested by PKCS#3.
-*/
-
-struct DHParamsStr {
- PLArenaPool * arena;
- SECItem prime; /* p */
- SECItem base; /* g */
-};
-typedef struct DHParamsStr DHParams;
-
-struct DHPublicKeyStr {
- PLArenaPool * arena;
- SECItem prime;
- SECItem base;
- SECItem publicValue;
-};
-typedef struct DHPublicKeyStr DHPublicKey;
-
-struct DHPrivateKeyStr {
- PLArenaPool * arena;
- SECItem prime;
- SECItem base;
- SECItem publicValue;
- SECItem privateValue;
-};
-typedef struct DHPrivateKeyStr DHPrivateKey;
-
-/***************************************************************************
-** Data structures used for elliptic curve parameters and
-** public and private keys.
-*/
-
-/*
-** The ECParams data structures can encode elliptic curve
-** parameters for both GFp and GF2m curves.
-*/
-
-typedef enum { ec_params_explicit,
- ec_params_named
-} ECParamsType;
-
-typedef enum { ec_field_GFp = 1,
- ec_field_GF2m
-} ECFieldType;
-
-struct ECFieldIDStr {
- int size; /* field size in bits */
- ECFieldType type;
- union {
- SECItem prime; /* prime p for (GFp) */
- SECItem poly; /* irreducible binary polynomial for (GF2m) */
- } u;
- int k1; /* first coefficient of pentanomial or
- * the only coefficient of trinomial
- */
- int k2; /* two remaining coefficients of pentanomial */
- int k3;
-};
-typedef struct ECFieldIDStr ECFieldID;
-
-struct ECCurveStr {
- SECItem a; /* contains octet stream encoding of
- * field element (X9.62 section 4.3.3)
- */
- SECItem b;
- SECItem seed;
-};
-typedef struct ECCurveStr ECCurve;
-
-struct ECParamsStr {
- PLArenaPool * arena;
- ECParamsType type;
- ECFieldID fieldID;
- ECCurve curve;
- SECItem base;
- SECItem order;
- int cofactor;
- SECItem DEREncoding;
- ECCurveName name;
- SECItem curveOID;
-};
-typedef struct ECParamsStr ECParams;
-
-struct ECPublicKeyStr {
- ECParams ecParams;
- SECItem publicValue; /* elliptic curve point encoded as
- * octet stream.
- */
-};
-typedef struct ECPublicKeyStr ECPublicKey;
-
-struct ECPrivateKeyStr {
- ECParams ecParams;
- SECItem publicValue; /* encoded ec point */
- SECItem privateValue; /* private big integer */
- SECItem version; /* As per SEC 1, Appendix C, Section C.4 */
-};
-typedef struct ECPrivateKeyStr ECPrivateKey;
-
-typedef void * (*BLapiAllocateFunc)(void);
-typedef void (*BLapiDestroyContextFunc)(void *cx, PRBool freeit);
-typedef SECStatus (*BLapiInitContextFunc)(void *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *,
- int,
- unsigned int ,
- unsigned int );
-typedef SECStatus (*BLapiEncrypt)(void *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
-
-#endif /* _BLAPIT_H_ */
diff --git a/security/nss/lib/freebl/camellia.c b/security/nss/lib/freebl/camellia.c
deleted file mode 100644
index bde84a55a..000000000
--- a/security/nss/lib/freebl/camellia.c
+++ /dev/null
@@ -1,1786 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * $Id$
- */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prinit.h"
-#include "prerr.h"
-#include "secerr.h"
-
-#include "prtypes.h"
-#include "blapi.h"
-#include "camellia.h"
-#include "sha_fast.h" /* for SHA_HTONL and related configuration macros */
-
-
-/* key constants */
-
-#define CAMELLIA_SIGMA1L (0xA09E667FL)
-#define CAMELLIA_SIGMA1R (0x3BCC908BL)
-#define CAMELLIA_SIGMA2L (0xB67AE858L)
-#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
-#define CAMELLIA_SIGMA3L (0xC6EF372FL)
-#define CAMELLIA_SIGMA3R (0xE94F82BEL)
-#define CAMELLIA_SIGMA4L (0x54FF53A5L)
-#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
-#define CAMELLIA_SIGMA5L (0x10E527FAL)
-#define CAMELLIA_SIGMA5R (0xDE682D1DL)
-#define CAMELLIA_SIGMA6L (0xB05688C2L)
-#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
-
-/*
- * macros
- */
-
-
-#if defined(SHA_ALLOW_UNALIGNED_ACCESS)
-
-/* require a CPU that allows unaligned access */
-
-#if defined(SHA_NEED_TMP_VARIABLE)
-#define CAMELLIA_NEED_TMP_VARIABLE 1
-#endif
-
-# define GETU32(p) SHA_HTONL(*((PRUint32 *)(p)))
-# define PUTU32(ct, st) {*((PRUint32 *)(ct)) = SHA_HTONL(st);}
-
-#else /* no unaligned access */
-
-# define GETU32(pt) \
- (((PRUint32)(pt)[0] << 24) \
- ^ ((PRUint32)(pt)[1] << 16) \
- ^ ((PRUint32)(pt)[2] << 8) \
- ^ ((PRUint32)(pt)[3]))
-
-# define PUTU32(ct, st) { \
- (ct)[0] = (PRUint8)((st) >> 24); \
- (ct)[1] = (PRUint8)((st) >> 16); \
- (ct)[2] = (PRUint8)((st) >> 8); \
- (ct)[3] = (PRUint8)(st); }
-
-#endif
-
-#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
-#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
-
-/* rotation right shift 1byte */
-#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
-/* rotation left shift 1bit */
-#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
-/* rotation left shift 1byte */
-#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
-
-#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
- do { \
- w0 = ll; \
- ll = (ll << bits) + (lr >> (32 - bits)); \
- lr = (lr << bits) + (rl >> (32 - bits)); \
- rl = (rl << bits) + (rr >> (32 - bits)); \
- rr = (rr << bits) + (w0 >> (32 - bits)); \
- } while(0)
-
-#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
- do { \
- w0 = ll; \
- w1 = lr; \
- ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
- lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
- rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
- rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
- } while(0)
-
-#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
-#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
-#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
-#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
-
-#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
- do { \
- il = xl ^ kl; \
- ir = xr ^ kr; \
- t0 = il >> 16; \
- t1 = ir >> 16; \
- yl = CAMELLIA_SP1110(ir & 0xff) \
- ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \
- ^ CAMELLIA_SP3033(t1 & 0xff) \
- ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \
- yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \
- ^ CAMELLIA_SP0222(t0 & 0xff) \
- ^ CAMELLIA_SP3033((il >> 8) & 0xff) \
- ^ CAMELLIA_SP4404(il & 0xff); \
- yl ^= yr; \
- yr = CAMELLIA_RR8(yr); \
- yr ^= yl; \
- } while(0)
-
-
-/*
- * for speed up
- *
- */
-#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
- do { \
- t0 = kll; \
- t0 &= ll; \
- lr ^= CAMELLIA_RL1(t0); \
- t1 = klr; \
- t1 |= lr; \
- ll ^= t1; \
- \
- t2 = krr; \
- t2 |= rr; \
- rl ^= t2; \
- t3 = krl; \
- t3 &= rl; \
- rr ^= CAMELLIA_RL1(t3); \
- } while(0)
-
-#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
- do { \
- ir = CAMELLIA_SP1110(xr & 0xff) \
- ^ CAMELLIA_SP0222((xr >> 24) & 0xff) \
- ^ CAMELLIA_SP3033((xr >> 16) & 0xff) \
- ^ CAMELLIA_SP4404((xr >> 8) & 0xff); \
- il = CAMELLIA_SP1110((xl >> 24) & 0xff) \
- ^ CAMELLIA_SP0222((xl >> 16) & 0xff) \
- ^ CAMELLIA_SP3033((xl >> 8) & 0xff) \
- ^ CAMELLIA_SP4404(xl & 0xff); \
- il ^= kl; \
- ir ^= kr; \
- ir ^= il; \
- il = CAMELLIA_RR8(il); \
- il ^= ir; \
- yl ^= ir; \
- yr ^= il; \
- } while(0)
-
-
-static const PRUint32 camellia_sp1110[256] = {
- 0x70707000,0x82828200,0x2c2c2c00,0xececec00,
- 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
- 0xe4e4e400,0x85858500,0x57575700,0x35353500,
- 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
- 0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
- 0x45454500,0x19191900,0xa5a5a500,0x21212100,
- 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
- 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
- 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
- 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
- 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
- 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
- 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
- 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
- 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
- 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
- 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
- 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
- 0x74747400,0x12121200,0x2b2b2b00,0x20202000,
- 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
- 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
- 0x34343400,0x7e7e7e00,0x76767600,0x05050500,
- 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
- 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
- 0x14141400,0x58585800,0x3a3a3a00,0x61616100,
- 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
- 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
- 0x53535300,0x18181800,0xf2f2f200,0x22222200,
- 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
- 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
- 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
- 0x60606000,0xfcfcfc00,0x69696900,0x50505000,
- 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
- 0xa1a1a100,0x89898900,0x62626200,0x97979700,
- 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
- 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
- 0x10101000,0xc4c4c400,0x00000000,0x48484800,
- 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
- 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
- 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
- 0x87878700,0x5c5c5c00,0x83838300,0x02020200,
- 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
- 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
- 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
- 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
- 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
- 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
- 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
- 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
- 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
- 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
- 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
- 0x78787800,0x98989800,0x06060600,0x6a6a6a00,
- 0xe7e7e700,0x46464600,0x71717100,0xbababa00,
- 0xd4d4d400,0x25252500,0xababab00,0x42424200,
- 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
- 0x72727200,0x07070700,0xb9b9b900,0x55555500,
- 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
- 0x36363600,0x49494900,0x2a2a2a00,0x68686800,
- 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
- 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
- 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
- 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
- 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
-};
-
-static const PRUint32 camellia_sp0222[256] = {
- 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
- 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
- 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
- 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
- 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
- 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
- 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
- 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
- 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
- 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
- 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
- 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
- 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
- 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
- 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
- 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
- 0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
- 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
- 0x00e8e8e8,0x00242424,0x00565656,0x00404040,
- 0x00e1e1e1,0x00636363,0x00090909,0x00333333,
- 0x00bfbfbf,0x00989898,0x00979797,0x00858585,
- 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
- 0x00dadada,0x006f6f6f,0x00535353,0x00626262,
- 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
- 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
- 0x00bdbdbd,0x00363636,0x00222222,0x00383838,
- 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
- 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
- 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
- 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
- 0x00484848,0x00101010,0x00d1d1d1,0x00515151,
- 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
- 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
- 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
- 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
- 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
- 0x00202020,0x00898989,0x00000000,0x00909090,
- 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
- 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
- 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
- 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
- 0x009b9b9b,0x00949494,0x00212121,0x00666666,
- 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
- 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
- 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
- 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
- 0x00030303,0x002d2d2d,0x00dedede,0x00969696,
- 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
- 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
- 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
- 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
- 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
- 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
- 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
- 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
- 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
- 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
- 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
- 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
- 0x00787878,0x00707070,0x00e3e3e3,0x00494949,
- 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
- 0x00777777,0x00939393,0x00868686,0x00838383,
- 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
- 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
-};
-
-static const PRUint32 camellia_sp3033[256] = {
- 0x38003838,0x41004141,0x16001616,0x76007676,
- 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
- 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
- 0x75007575,0x06000606,0x57005757,0xa000a0a0,
- 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
- 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
- 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
- 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
- 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
- 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
- 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
- 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
- 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
- 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
- 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
- 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
- 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
- 0xfd00fdfd,0x66006666,0x58005858,0x96009696,
- 0x3a003a3a,0x09000909,0x95009595,0x10001010,
- 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
- 0xef00efef,0x26002626,0xe500e5e5,0x61006161,
- 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
- 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
- 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
- 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
- 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
- 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
- 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
- 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
- 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
- 0x12001212,0x04000404,0x74007474,0x54005454,
- 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
- 0x55005555,0x68006868,0x50005050,0xbe00bebe,
- 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
- 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
- 0x70007070,0xff00ffff,0x32003232,0x69006969,
- 0x08000808,0x62006262,0x00000000,0x24002424,
- 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
- 0x45004545,0x81008181,0x73007373,0x6d006d6d,
- 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
- 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
- 0xe600e6e6,0x25002525,0x48004848,0x99009999,
- 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
- 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
- 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
- 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
- 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
- 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
- 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
- 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
- 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
- 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
- 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
- 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
- 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
- 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
- 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
- 0x7c007c7c,0x77007777,0x56005656,0x05000505,
- 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
- 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
- 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
- 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
- 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
- 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
-};
-
-static const PRUint32 camellia_sp4404[256] = {
- 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
- 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
- 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
- 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
- 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
- 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
- 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
- 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
- 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
- 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
- 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
- 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
- 0x14140014,0x3a3a003a,0xdede00de,0x11110011,
- 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
- 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
- 0x24240024,0xe8e800e8,0x60600060,0x69690069,
- 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
- 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
- 0x10100010,0x00000000,0xa3a300a3,0x75750075,
- 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
- 0x87870087,0x83830083,0xcdcd00cd,0x90900090,
- 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
- 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
- 0x81810081,0x6f6f006f,0x13130013,0x63630063,
- 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
- 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
- 0x78780078,0x06060006,0xe7e700e7,0x71710071,
- 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
- 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
- 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
- 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
- 0x15150015,0xadad00ad,0x77770077,0x80800080,
- 0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
- 0x85850085,0x35350035,0x0c0c000c,0x41410041,
- 0xefef00ef,0x93930093,0x19190019,0x21210021,
- 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
- 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
- 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
- 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
- 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
- 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
- 0x12120012,0x20200020,0xb1b100b1,0x99990099,
- 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
- 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
- 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
- 0x0f0f000f,0x16160016,0x18180018,0x22220022,
- 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
- 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
- 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
- 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
- 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
- 0x03030003,0xdada00da,0x3f3f003f,0x94940094,
- 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
- 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
- 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
- 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
- 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
- 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
- 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
- 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
- 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
- 0x49490049,0x68680068,0x38380038,0xa4a400a4,
- 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
- 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
-};
-
-
-/**
- * Stuff related to the Camellia key schedule
- */
-#define subl(x) subL[(x)]
-#define subr(x) subR[(x)]
-
-void camellia_setup128(const unsigned char *key, PRUint32 *subkey)
-{
- PRUint32 kll, klr, krl, krr;
- PRUint32 il, ir, t0, t1, w0, w1;
- PRUint32 kw4l, kw4r, dw, tl, tr;
- PRUint32 subL[26];
- PRUint32 subR[26];
-#if defined(CAMELLIA_NEED_TMP_VARIABLE)
- PRUint32 tmp;
-#endif
-
- /**
- * k == kll || klr || krl || krr (|| is concatination)
- */
- kll = GETU32(key );
- klr = GETU32(key + 4);
- krl = GETU32(key + 8);
- krr = GETU32(key + 12);
- /**
- * generate KL dependent subkeys
- */
- subl(0) = kll; subr(0) = klr;
- subl(1) = krl; subr(1) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
- subl(4) = kll; subr(4) = klr;
- subl(5) = krl; subr(5) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
- subl(10) = kll; subr(10) = klr;
- subl(11) = krl; subr(11) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
- subl(13) = krl; subr(13) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
- subl(16) = kll; subr(16) = klr;
- subl(17) = krl; subr(17) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
- subl(18) = kll; subr(18) = klr;
- subl(19) = krl; subr(19) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
- subl(22) = kll; subr(22) = klr;
- subl(23) = krl; subr(23) = krr;
-
- /* generate KA */
- kll = subl(0); klr = subr(0);
- krl = subl(1); krr = subr(1);
- CAMELLIA_F(kll, klr,
- CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
- w0, w1, il, ir, t0, t1);
- krl ^= w0; krr ^= w1;
- CAMELLIA_F(krl, krr,
- CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
- kll, klr, il, ir, t0, t1);
- CAMELLIA_F(kll, klr,
- CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
- krl, krr, il, ir, t0, t1);
- krl ^= w0; krr ^= w1;
- CAMELLIA_F(krl, krr,
- CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
- w0, w1, il, ir, t0, t1);
- kll ^= w0; klr ^= w1;
-
- /* generate KA dependent subkeys */
- subl(2) = kll; subr(2) = klr;
- subl(3) = krl; subr(3) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
- subl(6) = kll; subr(6) = klr;
- subl(7) = krl; subr(7) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
- subl(8) = kll; subr(8) = klr;
- subl(9) = krl; subr(9) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
- subl(12) = kll; subr(12) = klr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
- subl(14) = kll; subr(14) = klr;
- subl(15) = krl; subr(15) = krr;
- CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
- subl(20) = kll; subr(20) = klr;
- subl(21) = krl; subr(21) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
- subl(24) = kll; subr(24) = klr;
- subl(25) = krl; subr(25) = krr;
-
-
- /* absorb kw2 to other subkeys */
- subl(3) ^= subl(1); subr(3) ^= subr(1);
- subl(5) ^= subl(1); subr(5) ^= subr(1);
- subl(7) ^= subl(1); subr(7) ^= subr(1);
- subl(1) ^= subr(1) & ~subr(9);
- dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
- subl(11) ^= subl(1); subr(11) ^= subr(1);
- subl(13) ^= subl(1); subr(13) ^= subr(1);
- subl(15) ^= subl(1); subr(15) ^= subr(1);
- subl(1) ^= subr(1) & ~subr(17);
- dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
- subl(19) ^= subl(1); subr(19) ^= subr(1);
- subl(21) ^= subl(1); subr(21) ^= subr(1);
- subl(23) ^= subl(1); subr(23) ^= subr(1);
- subl(24) ^= subl(1); subr(24) ^= subr(1);
-
- /* absorb kw4 to other subkeys */
- kw4l = subl(25); kw4r = subr(25);
- subl(22) ^= kw4l; subr(22) ^= kw4r;
- subl(20) ^= kw4l; subr(20) ^= kw4r;
- subl(18) ^= kw4l; subr(18) ^= kw4r;
- kw4l ^= kw4r & ~subr(16);
- dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
- subl(14) ^= kw4l; subr(14) ^= kw4r;
- subl(12) ^= kw4l; subr(12) ^= kw4r;
- subl(10) ^= kw4l; subr(10) ^= kw4r;
- kw4l ^= kw4r & ~subr(8);
- dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
- subl(6) ^= kw4l; subr(6) ^= kw4r;
- subl(4) ^= kw4l; subr(4) ^= kw4r;
- subl(2) ^= kw4l; subr(2) ^= kw4r;
- subl(0) ^= kw4l; subr(0) ^= kw4r;
-
- /* key XOR is end of F-function */
- CamelliaSubkeyL(0) = subl(0) ^ subl(2);
- CamelliaSubkeyR(0) = subr(0) ^ subr(2);
- CamelliaSubkeyL(2) = subl(3);
- CamelliaSubkeyR(2) = subr(3);
- CamelliaSubkeyL(3) = subl(2) ^ subl(4);
- CamelliaSubkeyR(3) = subr(2) ^ subr(4);
- CamelliaSubkeyL(4) = subl(3) ^ subl(5);
- CamelliaSubkeyR(4) = subr(3) ^ subr(5);
- CamelliaSubkeyL(5) = subl(4) ^ subl(6);
- CamelliaSubkeyR(5) = subr(4) ^ subr(6);
- CamelliaSubkeyL(6) = subl(5) ^ subl(7);
- CamelliaSubkeyR(6) = subr(5) ^ subr(7);
- tl = subl(10) ^ (subr(10) & ~subr(8));
- dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(7) = subl(6) ^ tl;
- CamelliaSubkeyR(7) = subr(6) ^ tr;
- CamelliaSubkeyL(8) = subl(8);
- CamelliaSubkeyR(8) = subr(8);
- CamelliaSubkeyL(9) = subl(9);
- CamelliaSubkeyR(9) = subr(9);
- tl = subl(7) ^ (subr(7) & ~subr(9));
- dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(10) = tl ^ subl(11);
- CamelliaSubkeyR(10) = tr ^ subr(11);
- CamelliaSubkeyL(11) = subl(10) ^ subl(12);
- CamelliaSubkeyR(11) = subr(10) ^ subr(12);
- CamelliaSubkeyL(12) = subl(11) ^ subl(13);
- CamelliaSubkeyR(12) = subr(11) ^ subr(13);
- CamelliaSubkeyL(13) = subl(12) ^ subl(14);
- CamelliaSubkeyR(13) = subr(12) ^ subr(14);
- CamelliaSubkeyL(14) = subl(13) ^ subl(15);
- CamelliaSubkeyR(14) = subr(13) ^ subr(15);
- tl = subl(18) ^ (subr(18) & ~subr(16));
- dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(15) = subl(14) ^ tl;
- CamelliaSubkeyR(15) = subr(14) ^ tr;
- CamelliaSubkeyL(16) = subl(16);
- CamelliaSubkeyR(16) = subr(16);
- CamelliaSubkeyL(17) = subl(17);
- CamelliaSubkeyR(17) = subr(17);
- tl = subl(15) ^ (subr(15) & ~subr(17));
- dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(18) = tl ^ subl(19);
- CamelliaSubkeyR(18) = tr ^ subr(19);
- CamelliaSubkeyL(19) = subl(18) ^ subl(20);
- CamelliaSubkeyR(19) = subr(18) ^ subr(20);
- CamelliaSubkeyL(20) = subl(19) ^ subl(21);
- CamelliaSubkeyR(20) = subr(19) ^ subr(21);
- CamelliaSubkeyL(21) = subl(20) ^ subl(22);
- CamelliaSubkeyR(21) = subr(20) ^ subr(22);
- CamelliaSubkeyL(22) = subl(21) ^ subl(23);
- CamelliaSubkeyR(22) = subr(21) ^ subr(23);
- CamelliaSubkeyL(23) = subl(22);
- CamelliaSubkeyR(23) = subr(22);
- CamelliaSubkeyL(24) = subl(24) ^ subl(23);
- CamelliaSubkeyR(24) = subr(24) ^ subr(23);
-
- /* apply the inverse of the last half of P-function */
- dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
- dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
- dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
- dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
- dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
- dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
- dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
- dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
- dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
- dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
- dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
- dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
- dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
- dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
- dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
- dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
- dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
- dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
-
- return;
-}
-
-void camellia_setup256(const unsigned char *key, PRUint32 *subkey)
-{
- PRUint32 kll,klr,krl,krr; /* left half of key */
- PRUint32 krll,krlr,krrl,krrr; /* right half of key */
- PRUint32 il, ir, t0, t1, w0, w1; /* temporary variables */
- PRUint32 kw4l, kw4r, dw, tl, tr;
- PRUint32 subL[34];
- PRUint32 subR[34];
-#if defined(CAMELLIA_NEED_TMP_VARIABLE)
- PRUint32 tmp;
-#endif
-
- /**
- * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
- * (|| is concatination)
- */
-
- kll = GETU32(key );
- klr = GETU32(key + 4);
- krl = GETU32(key + 8);
- krr = GETU32(key + 12);
- krll = GETU32(key + 16);
- krlr = GETU32(key + 20);
- krrl = GETU32(key + 24);
- krrr = GETU32(key + 28);
-
- /* generate KL dependent subkeys */
- subl(0) = kll; subr(0) = klr;
- subl(1) = krl; subr(1) = krr;
- CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
- subl(12) = kll; subr(12) = klr;
- subl(13) = krl; subr(13) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
- subl(16) = kll; subr(16) = klr;
- subl(17) = krl; subr(17) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
- subl(22) = kll; subr(22) = klr;
- subl(23) = krl; subr(23) = krr;
- CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
- subl(30) = kll; subr(30) = klr;
- subl(31) = krl; subr(31) = krr;
-
- /* generate KR dependent subkeys */
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
- subl(4) = krll; subr(4) = krlr;
- subl(5) = krrl; subr(5) = krrr;
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
- subl(8) = krll; subr(8) = krlr;
- subl(9) = krrl; subr(9) = krrr;
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
- subl(18) = krll; subr(18) = krlr;
- subl(19) = krrl; subr(19) = krrr;
- CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
- subl(26) = krll; subr(26) = krlr;
- subl(27) = krrl; subr(27) = krrr;
- CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
-
- /* generate KA */
- kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
- krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
- CAMELLIA_F(kll, klr,
- CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
- w0, w1, il, ir, t0, t1);
- krl ^= w0; krr ^= w1;
- CAMELLIA_F(krl, krr,
- CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
- kll, klr, il, ir, t0, t1);
- kll ^= krll; klr ^= krlr;
- CAMELLIA_F(kll, klr,
- CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
- krl, krr, il, ir, t0, t1);
- krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
- CAMELLIA_F(krl, krr,
- CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
- w0, w1, il, ir, t0, t1);
- kll ^= w0; klr ^= w1;
-
- /* generate KB */
- krll ^= kll; krlr ^= klr;
- krrl ^= krl; krrr ^= krr;
- CAMELLIA_F(krll, krlr,
- CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
- w0, w1, il, ir, t0, t1);
- krrl ^= w0; krrr ^= w1;
- CAMELLIA_F(krrl, krrr,
- CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
- w0, w1, il, ir, t0, t1);
- krll ^= w0; krlr ^= w1;
-
- /* generate KA dependent subkeys */
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
- subl(6) = kll; subr(6) = klr;
- subl(7) = krl; subr(7) = krr;
- CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
- subl(14) = kll; subr(14) = klr;
- subl(15) = krl; subr(15) = krr;
- subl(24) = klr; subr(24) = krl;
- subl(25) = krr; subr(25) = kll;
- CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
- subl(28) = kll; subr(28) = klr;
- subl(29) = krl; subr(29) = krr;
-
- /* generate KB dependent subkeys */
- subl(2) = krll; subr(2) = krlr;
- subl(3) = krrl; subr(3) = krrr;
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
- subl(10) = krll; subr(10) = krlr;
- subl(11) = krrl; subr(11) = krrr;
- CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
- subl(20) = krll; subr(20) = krlr;
- subl(21) = krrl; subr(21) = krrr;
- CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
- subl(32) = krll; subr(32) = krlr;
- subl(33) = krrl; subr(33) = krrr;
-
- /* absorb kw2 to other subkeys */
- subl(3) ^= subl(1); subr(3) ^= subr(1);
- subl(5) ^= subl(1); subr(5) ^= subr(1);
- subl(7) ^= subl(1); subr(7) ^= subr(1);
- subl(1) ^= subr(1) & ~subr(9);
- dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
- subl(11) ^= subl(1); subr(11) ^= subr(1);
- subl(13) ^= subl(1); subr(13) ^= subr(1);
- subl(15) ^= subl(1); subr(15) ^= subr(1);
- subl(1) ^= subr(1) & ~subr(17);
- dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
- subl(19) ^= subl(1); subr(19) ^= subr(1);
- subl(21) ^= subl(1); subr(21) ^= subr(1);
- subl(23) ^= subl(1); subr(23) ^= subr(1);
- subl(1) ^= subr(1) & ~subr(25);
- dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
- subl(27) ^= subl(1); subr(27) ^= subr(1);
- subl(29) ^= subl(1); subr(29) ^= subr(1);
- subl(31) ^= subl(1); subr(31) ^= subr(1);
- subl(32) ^= subl(1); subr(32) ^= subr(1);
-
- /* absorb kw4 to other subkeys */
- kw4l = subl(33); kw4r = subr(33);
- subl(30) ^= kw4l; subr(30) ^= kw4r;
- subl(28) ^= kw4l; subr(28) ^= kw4r;
- subl(26) ^= kw4l; subr(26) ^= kw4r;
- kw4l ^= kw4r & ~subr(24);
- dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
- subl(22) ^= kw4l; subr(22) ^= kw4r;
- subl(20) ^= kw4l; subr(20) ^= kw4r;
- subl(18) ^= kw4l; subr(18) ^= kw4r;
- kw4l ^= kw4r & ~subr(16);
- dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
- subl(14) ^= kw4l; subr(14) ^= kw4r;
- subl(12) ^= kw4l; subr(12) ^= kw4r;
- subl(10) ^= kw4l; subr(10) ^= kw4r;
- kw4l ^= kw4r & ~subr(8);
- dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
- subl(6) ^= kw4l; subr(6) ^= kw4r;
- subl(4) ^= kw4l; subr(4) ^= kw4r;
- subl(2) ^= kw4l; subr(2) ^= kw4r;
- subl(0) ^= kw4l; subr(0) ^= kw4r;
-
- /* key XOR is end of F-function */
- CamelliaSubkeyL(0) = subl(0) ^ subl(2);
- CamelliaSubkeyR(0) = subr(0) ^ subr(2);
- CamelliaSubkeyL(2) = subl(3);
- CamelliaSubkeyR(2) = subr(3);
- CamelliaSubkeyL(3) = subl(2) ^ subl(4);
- CamelliaSubkeyR(3) = subr(2) ^ subr(4);
- CamelliaSubkeyL(4) = subl(3) ^ subl(5);
- CamelliaSubkeyR(4) = subr(3) ^ subr(5);
- CamelliaSubkeyL(5) = subl(4) ^ subl(6);
- CamelliaSubkeyR(5) = subr(4) ^ subr(6);
- CamelliaSubkeyL(6) = subl(5) ^ subl(7);
- CamelliaSubkeyR(6) = subr(5) ^ subr(7);
- tl = subl(10) ^ (subr(10) & ~subr(8));
- dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(7) = subl(6) ^ tl;
- CamelliaSubkeyR(7) = subr(6) ^ tr;
- CamelliaSubkeyL(8) = subl(8);
- CamelliaSubkeyR(8) = subr(8);
- CamelliaSubkeyL(9) = subl(9);
- CamelliaSubkeyR(9) = subr(9);
- tl = subl(7) ^ (subr(7) & ~subr(9));
- dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(10) = tl ^ subl(11);
- CamelliaSubkeyR(10) = tr ^ subr(11);
- CamelliaSubkeyL(11) = subl(10) ^ subl(12);
- CamelliaSubkeyR(11) = subr(10) ^ subr(12);
- CamelliaSubkeyL(12) = subl(11) ^ subl(13);
- CamelliaSubkeyR(12) = subr(11) ^ subr(13);
- CamelliaSubkeyL(13) = subl(12) ^ subl(14);
- CamelliaSubkeyR(13) = subr(12) ^ subr(14);
- CamelliaSubkeyL(14) = subl(13) ^ subl(15);
- CamelliaSubkeyR(14) = subr(13) ^ subr(15);
- tl = subl(18) ^ (subr(18) & ~subr(16));
- dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(15) = subl(14) ^ tl;
- CamelliaSubkeyR(15) = subr(14) ^ tr;
- CamelliaSubkeyL(16) = subl(16);
- CamelliaSubkeyR(16) = subr(16);
- CamelliaSubkeyL(17) = subl(17);
- CamelliaSubkeyR(17) = subr(17);
- tl = subl(15) ^ (subr(15) & ~subr(17));
- dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(18) = tl ^ subl(19);
- CamelliaSubkeyR(18) = tr ^ subr(19);
- CamelliaSubkeyL(19) = subl(18) ^ subl(20);
- CamelliaSubkeyR(19) = subr(18) ^ subr(20);
- CamelliaSubkeyL(20) = subl(19) ^ subl(21);
- CamelliaSubkeyR(20) = subr(19) ^ subr(21);
- CamelliaSubkeyL(21) = subl(20) ^ subl(22);
- CamelliaSubkeyR(21) = subr(20) ^ subr(22);
- CamelliaSubkeyL(22) = subl(21) ^ subl(23);
- CamelliaSubkeyR(22) = subr(21) ^ subr(23);
- tl = subl(26) ^ (subr(26) & ~subr(24));
- dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(23) = subl(22) ^ tl;
- CamelliaSubkeyR(23) = subr(22) ^ tr;
- CamelliaSubkeyL(24) = subl(24);
- CamelliaSubkeyR(24) = subr(24);
- CamelliaSubkeyL(25) = subl(25);
- CamelliaSubkeyR(25) = subr(25);
- tl = subl(23) ^ (subr(23) & ~subr(25));
- dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
- CamelliaSubkeyL(26) = tl ^ subl(27);
- CamelliaSubkeyR(26) = tr ^ subr(27);
- CamelliaSubkeyL(27) = subl(26) ^ subl(28);
- CamelliaSubkeyR(27) = subr(26) ^ subr(28);
- CamelliaSubkeyL(28) = subl(27) ^ subl(29);
- CamelliaSubkeyR(28) = subr(27) ^ subr(29);
- CamelliaSubkeyL(29) = subl(28) ^ subl(30);
- CamelliaSubkeyR(29) = subr(28) ^ subr(30);
- CamelliaSubkeyL(30) = subl(29) ^ subl(31);
- CamelliaSubkeyR(30) = subr(29) ^ subr(31);
- CamelliaSubkeyL(31) = subl(30);
- CamelliaSubkeyR(31) = subr(30);
- CamelliaSubkeyL(32) = subl(32) ^ subl(31);
- CamelliaSubkeyR(32) = subr(32) ^ subr(31);
-
- /* apply the inverse of the last half of P-function */
- dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
- dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
- dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
- dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
- dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
- dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
- dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
- dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
- dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
- dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
- dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
- dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
- dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
- dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
- dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
- dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
- dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
- dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
- dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
- dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
- dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
- dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
- dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
- dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
- CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
-
- return;
-}
-
-void camellia_setup192(const unsigned char *key, PRUint32 *subkey)
-{
- unsigned char kk[32];
- PRUint32 krll, krlr, krrl,krrr;
-
- memcpy(kk, key, 24);
- memcpy((unsigned char *)&krll, key+16,4);
- memcpy((unsigned char *)&krlr, key+20,4);
- krrl = ~krll;
- krrr = ~krlr;
- memcpy(kk+24, (unsigned char *)&krrl, 4);
- memcpy(kk+28, (unsigned char *)&krrr, 4);
- camellia_setup256(kk, subkey);
- return;
-}
-
-
-/**
- * Stuff related to camellia encryption/decryption
- *
- */
-SECStatus
-camellia_encrypt128(const PRUint32 *subkey,
- unsigned char *output,
- const unsigned char *input)
-{
- PRUint32 il, ir, t0, t1;
- PRUint32 io[4];
-#if defined(CAMELLIA_NEED_TMP_VARIABLE)
- PRUint32 tmp;
-#endif
-
- io[0] = GETU32(input);
- io[1] = GETU32(input+4);
- io[2] = GETU32(input+8);
- io[3] = GETU32(input+12);
-
- /* pre whitening but absorb kw2*/
- io[0] ^= CamelliaSubkeyL(0);
- io[1] ^= CamelliaSubkeyR(0);
- /* main iteration */
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(2),CamelliaSubkeyR(2),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(3),CamelliaSubkeyR(3),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(4),CamelliaSubkeyR(4),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(5),CamelliaSubkeyR(5),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(6),CamelliaSubkeyR(6),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(7),CamelliaSubkeyR(7),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(8),CamelliaSubkeyR(8),
- CamelliaSubkeyL(9),CamelliaSubkeyR(9),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(10),CamelliaSubkeyR(10),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(11),CamelliaSubkeyR(11),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(12),CamelliaSubkeyR(12),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(13),CamelliaSubkeyR(13),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(14),CamelliaSubkeyR(14),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(15),CamelliaSubkeyR(15),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(16),CamelliaSubkeyR(16),
- CamelliaSubkeyL(17),CamelliaSubkeyR(17),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(18),CamelliaSubkeyR(18),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(19),CamelliaSubkeyR(19),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(20),CamelliaSubkeyR(20),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(21),CamelliaSubkeyR(21),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(22),CamelliaSubkeyR(22),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(23),CamelliaSubkeyR(23),
- io[0],io[1],il,ir,t0,t1);
-
- /* post whitening but kw4 */
- io[2] ^= CamelliaSubkeyL(24);
- io[3] ^= CamelliaSubkeyR(24);
-
- t0 = io[0];
- t1 = io[1];
- io[0] = io[2];
- io[1] = io[3];
- io[2] = t0;
- io[3] = t1;
-
- PUTU32(output, io[0]);
- PUTU32(output+4, io[1]);
- PUTU32(output+8, io[2]);
- PUTU32(output+12, io[3]);
-
- return SECSuccess;
-}
-
-SECStatus
-camellia_decrypt128(const PRUint32 *subkey,
- unsigned char *output,
- const unsigned char *input)
-{
- PRUint32 il,ir,t0,t1; /* temporary valiables */
- PRUint32 io[4];
-#if defined(CAMELLIA_NEED_TMP_VARIABLE)
- PRUint32 tmp;
-#endif
-
- io[0] = GETU32(input);
- io[1] = GETU32(input+4);
- io[2] = GETU32(input+8);
- io[3] = GETU32(input+12);
-
- /* pre whitening but absorb kw2*/
- io[0] ^= CamelliaSubkeyL(24);
- io[1] ^= CamelliaSubkeyR(24);
-
- /* main iteration */
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(23),CamelliaSubkeyR(23),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(22),CamelliaSubkeyR(22),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(21),CamelliaSubkeyR(21),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(20),CamelliaSubkeyR(20),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(19),CamelliaSubkeyR(19),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(18),CamelliaSubkeyR(18),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(17),CamelliaSubkeyR(17),
- CamelliaSubkeyL(16),CamelliaSubkeyR(16),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(15),CamelliaSubkeyR(15),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(14),CamelliaSubkeyR(14),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(13),CamelliaSubkeyR(13),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(12),CamelliaSubkeyR(12),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(11),CamelliaSubkeyR(11),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(10),CamelliaSubkeyR(10),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(9),CamelliaSubkeyR(9),
- CamelliaSubkeyL(8),CamelliaSubkeyR(8),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(7),CamelliaSubkeyR(7),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(6),CamelliaSubkeyR(6),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(5),CamelliaSubkeyR(5),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(4),CamelliaSubkeyR(4),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(3),CamelliaSubkeyR(3),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(2),CamelliaSubkeyR(2),
- io[0],io[1],il,ir,t0,t1);
-
- /* post whitening but kw4 */
- io[2] ^= CamelliaSubkeyL(0);
- io[3] ^= CamelliaSubkeyR(0);
-
- t0 = io[0];
- t1 = io[1];
- io[0] = io[2];
- io[1] = io[3];
- io[2] = t0;
- io[3] = t1;
-
- PUTU32(output, io[0]);
- PUTU32(output+4, io[1]);
- PUTU32(output+8, io[2]);
- PUTU32(output+12, io[3]);
-
- return SECSuccess;
-}
-
-/**
- * stuff for 192 and 256bit encryption/decryption
- */
-SECStatus
-camellia_encrypt256(const PRUint32 *subkey,
- unsigned char *output,
- const unsigned char *input)
-{
- PRUint32 il,ir,t0,t1; /* temporary valiables */
- PRUint32 io[4];
-#if defined(CAMELLIA_NEED_TMP_VARIABLE)
- PRUint32 tmp;
-#endif
-
- io[0] = GETU32(input);
- io[1] = GETU32(input+4);
- io[2] = GETU32(input+8);
- io[3] = GETU32(input+12);
-
- /* pre whitening but absorb kw2*/
- io[0] ^= CamelliaSubkeyL(0);
- io[1] ^= CamelliaSubkeyR(0);
-
- /* main iteration */
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(2),CamelliaSubkeyR(2),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(3),CamelliaSubkeyR(3),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(4),CamelliaSubkeyR(4),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(5),CamelliaSubkeyR(5),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(6),CamelliaSubkeyR(6),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(7),CamelliaSubkeyR(7),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(8),CamelliaSubkeyR(8),
- CamelliaSubkeyL(9),CamelliaSubkeyR(9),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(10),CamelliaSubkeyR(10),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(11),CamelliaSubkeyR(11),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(12),CamelliaSubkeyR(12),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(13),CamelliaSubkeyR(13),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(14),CamelliaSubkeyR(14),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(15),CamelliaSubkeyR(15),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(16),CamelliaSubkeyR(16),
- CamelliaSubkeyL(17),CamelliaSubkeyR(17),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(18),CamelliaSubkeyR(18),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(19),CamelliaSubkeyR(19),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(20),CamelliaSubkeyR(20),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(21),CamelliaSubkeyR(21),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(22),CamelliaSubkeyR(22),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(23),CamelliaSubkeyR(23),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(24),CamelliaSubkeyR(24),
- CamelliaSubkeyL(25),CamelliaSubkeyR(25),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(26),CamelliaSubkeyR(26),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(27),CamelliaSubkeyR(27),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(28),CamelliaSubkeyR(28),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(29),CamelliaSubkeyR(29),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(30),CamelliaSubkeyR(30),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(31),CamelliaSubkeyR(31),
- io[0],io[1],il,ir,t0,t1);
-
- /* post whitening but kw4 */
- io[2] ^= CamelliaSubkeyL(32);
- io[3] ^= CamelliaSubkeyR(32);
-
- t0 = io[0];
- t1 = io[1];
- io[0] = io[2];
- io[1] = io[3];
- io[2] = t0;
- io[3] = t1;
-
- PUTU32(output, io[0]);
- PUTU32(output+4, io[1]);
- PUTU32(output+8, io[2]);
- PUTU32(output+12, io[3]);
-
- return SECSuccess;
-}
-
-SECStatus
-camellia_decrypt256(const PRUint32 *subkey,
- unsigned char *output,
- const unsigned char *input)
-{
- PRUint32 il,ir,t0,t1; /* temporary valiables */
- PRUint32 io[4];
-#if defined(CAMELLIA_NEED_TMP_VARIABLE)
- PRUint32 tmp;
-#endif
-
- io[0] = GETU32(input);
- io[1] = GETU32(input+4);
- io[2] = GETU32(input+8);
- io[3] = GETU32(input+12);
-
- /* pre whitening but absorb kw2*/
- io[0] ^= CamelliaSubkeyL(32);
- io[1] ^= CamelliaSubkeyR(32);
-
- /* main iteration */
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(31),CamelliaSubkeyR(31),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(30),CamelliaSubkeyR(30),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(29),CamelliaSubkeyR(29),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(28),CamelliaSubkeyR(28),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(27),CamelliaSubkeyR(27),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(26),CamelliaSubkeyR(26),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(25),CamelliaSubkeyR(25),
- CamelliaSubkeyL(24),CamelliaSubkeyR(24),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(23),CamelliaSubkeyR(23),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(22),CamelliaSubkeyR(22),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(21),CamelliaSubkeyR(21),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(20),CamelliaSubkeyR(20),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(19),CamelliaSubkeyR(19),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(18),CamelliaSubkeyR(18),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(17),CamelliaSubkeyR(17),
- CamelliaSubkeyL(16),CamelliaSubkeyR(16),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(15),CamelliaSubkeyR(15),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(14),CamelliaSubkeyR(14),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(13),CamelliaSubkeyR(13),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(12),CamelliaSubkeyR(12),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(11),CamelliaSubkeyR(11),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(10),CamelliaSubkeyR(10),
- io[0],io[1],il,ir,t0,t1);
-
- CAMELLIA_FLS(io[0],io[1],io[2],io[3],
- CamelliaSubkeyL(9),CamelliaSubkeyR(9),
- CamelliaSubkeyL(8),CamelliaSubkeyR(8),
- t0,t1,il,ir);
-
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(7),CamelliaSubkeyR(7),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(6),CamelliaSubkeyR(6),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(5),CamelliaSubkeyR(5),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(4),CamelliaSubkeyR(4),
- io[0],io[1],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[0],io[1],
- CamelliaSubkeyL(3),CamelliaSubkeyR(3),
- io[2],io[3],il,ir,t0,t1);
- CAMELLIA_ROUNDSM(io[2],io[3],
- CamelliaSubkeyL(2),CamelliaSubkeyR(2),
- io[0],io[1],il,ir,t0,t1);
-
- /* post whitening but kw4 */
- io[2] ^= CamelliaSubkeyL(0);
- io[3] ^= CamelliaSubkeyR(0);
-
- t0 = io[0];
- t1 = io[1];
- io[0] = io[2];
- io[1] = io[3];
- io[2] = t0;
- io[3] = t1;
-
- PUTU32(output, io[0]);
- PUTU32(output+4, io[1]);
- PUTU32(output+8, io[2]);
- PUTU32(output+12, io[3]);
-
- return SECSuccess;
-}
-
-
-/**************************************************************************
- *
- * Stuff related to the Camellia key schedule
- *
- *************************************************************************/
-
-SECStatus
-camellia_key_expansion(CamelliaContext *cx,
- const unsigned char *key,
- const unsigned int keysize)
-{
- cx->keysize = keysize;
-
- switch(keysize) {
- case 16:
- camellia_setup128(key, cx->expandedKey);
- break;
- case 24:
- camellia_setup192(key, cx->expandedKey);
- break;
- case 32:
- camellia_setup256(key, cx->expandedKey);
- break;
- default:
- break;
- }
- return SECSuccess;
-}
-
-
-/**************************************************************************
- *
- * Camellia modes of operation (ECB and CBC)
- *
- *************************************************************************/
-
-SECStatus
-camellia_encryptECB(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- CamelliaBlockFunc *encryptor;
-
- encryptor = (cx->keysize == 16)
- ? &camellia_encrypt128
- : &camellia_encrypt256;
-
- while (inputLen > 0) {
- (*encryptor)(cx->expandedKey, output, input);
-
- output += CAMELLIA_BLOCK_SIZE;
- input += CAMELLIA_BLOCK_SIZE;
- inputLen -= CAMELLIA_BLOCK_SIZE;
- }
- return SECSuccess;
-}
-
-SECStatus
-camellia_encryptCBC(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- unsigned int j;
- unsigned char *lastblock;
- unsigned char inblock[CAMELLIA_BLOCK_SIZE];
- CamelliaBlockFunc *encryptor;
-
- if (!inputLen)
- return SECSuccess;
- lastblock = cx->iv;
-
- encryptor = (cx->keysize == 16)
- ? &camellia_encrypt128
- : &camellia_encrypt256;
-
- while (inputLen > 0) {
- /* XOR with the last block (IV if first block) */
- for (j=0; j<CAMELLIA_BLOCK_SIZE; ++j)
- inblock[j] = input[j] ^ lastblock[j];
- /* encrypt */
- (*encryptor)(cx->expandedKey, output, inblock);
-
- /* move to the next block */
- lastblock = output;
- output += CAMELLIA_BLOCK_SIZE;
- input += CAMELLIA_BLOCK_SIZE;
- inputLen -= CAMELLIA_BLOCK_SIZE;
- }
- memcpy(cx->iv, lastblock, CAMELLIA_BLOCK_SIZE);
- return SECSuccess;
-}
-
-SECStatus
-camellia_decryptECB(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- CamelliaBlockFunc *decryptor;
-
- decryptor = (cx->keysize == 16)
- ? &camellia_decrypt128
- : &camellia_decrypt256;
-
-
- while (inputLen > 0) {
-
- (*decryptor)(cx->expandedKey, output, input);
-
- output += CAMELLIA_BLOCK_SIZE;
- input += CAMELLIA_BLOCK_SIZE;
- inputLen -= CAMELLIA_BLOCK_SIZE;
- }
- return SECSuccess;
-}
-
-SECStatus
-camellia_decryptCBC(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- const unsigned char *in;
- unsigned char *out;
- unsigned int j;
- unsigned char newIV[CAMELLIA_BLOCK_SIZE];
- CamelliaBlockFunc *decryptor;
-
-
-
- if (!inputLen)
- return SECSuccess;
-
- PORT_Assert(output - input >= 0 || input - output >= (int)inputLen );
-
- in = input + (inputLen - CAMELLIA_BLOCK_SIZE);
- memcpy(newIV, in, CAMELLIA_BLOCK_SIZE);
- out = output + (inputLen - CAMELLIA_BLOCK_SIZE);
-
- decryptor = (cx->keysize == 16)
- ? &camellia_decrypt128
- : &camellia_decrypt256;
-
- while (inputLen > CAMELLIA_BLOCK_SIZE) {
- (*decryptor)(cx->expandedKey, out, in);
-
- for (j=0; j<CAMELLIA_BLOCK_SIZE; ++j)
- out[j] ^= in[(int)(j - CAMELLIA_BLOCK_SIZE)];
-
- out -= CAMELLIA_BLOCK_SIZE;
- in -= CAMELLIA_BLOCK_SIZE;
- inputLen -= CAMELLIA_BLOCK_SIZE;
- }
- if (in == input) {
- (*decryptor)(cx->expandedKey, out, in);
-
- for (j=0; j<CAMELLIA_BLOCK_SIZE; ++j)
- out[j] ^= cx->iv[j];
- }
- memcpy(cx->iv, newIV, CAMELLIA_BLOCK_SIZE);
- return SECSuccess;
-}
-
-/**************************************************************************
- *
- * BLAPI Interface functions
- *
- *************************************************************************/
-
-CamelliaContext *
-Camellia_AllocateContext(void)
-{
- return PORT_ZNew(CamelliaContext);
-}
-
-SECStatus
-Camellia_InitContext(CamelliaContext *cx, const unsigned char *key,
- unsigned int keysize,
- const unsigned char *iv, int mode, unsigned int encrypt,
- unsigned int unused)
-{
- if (key == NULL ||
- (keysize != 16 && keysize != 24 && keysize != 32)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (mode != NSS_CAMELLIA && mode != NSS_CAMELLIA_CBC) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (mode == NSS_CAMELLIA_CBC && iv == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (mode == NSS_CAMELLIA_CBC) {
- memcpy(cx->iv, iv, CAMELLIA_BLOCK_SIZE);
- cx->worker = (encrypt) ? &camellia_encryptCBC : &camellia_decryptCBC;
- } else {
- cx->worker = (encrypt) ? &camellia_encryptECB : &camellia_decryptECB;
- }
-
- /* Generate expanded key */
- if (camellia_key_expansion(cx, key, keysize) != SECSuccess)
- goto cleanup;
-
- return SECSuccess;
-cleanup:
- return SECFailure;
-}
-
-/*
- * Camellia_CreateContext
- * create a new context for Camellia operations
- */
-
-
-CamelliaContext *
-Camellia_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, int encrypt,
- unsigned int keysize)
-{
- CamelliaContext *cx;
-
- if (key == NULL ||
- (keysize != 16 && keysize != 24 && keysize != 32)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- if (mode != NSS_CAMELLIA && mode != NSS_CAMELLIA_CBC) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- if (mode == NSS_CAMELLIA_CBC && iv == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- cx = PORT_ZNew(CamelliaContext);
- if (!cx) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- /* copy in the iv, if neccessary */
- if (mode == NSS_CAMELLIA_CBC) {
- memcpy(cx->iv, iv, CAMELLIA_BLOCK_SIZE);
- cx->worker = (encrypt) ? &camellia_encryptCBC : &camellia_decryptCBC;
- } else {
- cx->worker = (encrypt) ? &camellia_encryptECB : &camellia_decryptECB;
- }
- /* copy keysize */
- cx->keysize = keysize;
-
- /* Generate expanded key */
- if (camellia_key_expansion(cx, key, keysize) != SECSuccess)
- goto cleanup;
-
- return cx;
- cleanup:
- PORT_ZFree(cx, sizeof *cx);
- return NULL;
-}
-
-/*
- * Camellia_DestroyContext
- *
- * Zero an Camellia cipher context. If freeit is true, also free the pointer
- * to the context.
- */
-void
-Camellia_DestroyContext(CamelliaContext *cx, PRBool freeit)
-{
- if (cx)
- memset(cx, 0, sizeof *cx);
- if (freeit)
- PORT_Free(cx);
-}
-
-/*
- * Camellia_Encrypt
- *
- * Encrypt an arbitrary-length buffer. The output buffer must already be
- * allocated to at least inputLen.
- */
-SECStatus
-Camellia_Encrypt(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
-
- /* Check args */
- if (cx == NULL || output == NULL || input == NULL ||
- outputLen == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (inputLen % CAMELLIA_BLOCK_SIZE != 0) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- *outputLen = inputLen;
-
- return (*cx->worker)(cx, output, outputLen, maxOutputLen,
- input, inputLen);
-}
-
-/*
- * Camellia_Decrypt
- *
- * Decrypt and arbitrary-length buffer. The output buffer must already be
- * allocated to at least inputLen.
- */
-SECStatus
-Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
-
- /* Check args */
- if (cx == NULL || output == NULL || input == NULL
- || outputLen == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (inputLen % CAMELLIA_BLOCK_SIZE != 0) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- *outputLen = inputLen;
-
- return (*cx->worker)(cx, output, outputLen, maxOutputLen,
- input, inputLen);
-}
diff --git a/security/nss/lib/freebl/camellia.h b/security/nss/lib/freebl/camellia.h
deleted file mode 100644
index d8d7681ca..000000000
--- a/security/nss/lib/freebl/camellia.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * $Id$
- */
-
-#ifndef _CAMELLIA_H_
-#define _CAMELLIA_H_ 1
-
-#define CAMELLIA_BLOCK_SIZE 16 /* bytes */
-#define CAMELLIA_MIN_KEYSIZE 16 /* bytes */
-#define CAMELLIA_MAX_KEYSIZE 32 /* bytes */
-
-#define CAMELLIA_MAX_EXPANDEDKEY (34*2) /* 32bit unit */
-
-typedef PRUint32 KEY_TABLE_TYPE[CAMELLIA_MAX_EXPANDEDKEY];
-
-typedef SECStatus CamelliaFunc(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
-
-typedef SECStatus CamelliaBlockFunc(const PRUint32 *subkey,
- unsigned char *output,
- const unsigned char *input);
-
-/* CamelliaContextStr
- *
- * Values which maintain the state for Camellia encryption/decryption.
- *
- * keysize - the number of key bits
- * worker - the encryption/decryption function to use with this context
- * iv - initialization vector for CBC mode
- * expandedKey - the round keys in 4-byte words
- */
-struct CamelliaContextStr
-{
- PRUint32 keysize; /* bytes */
- CamelliaFunc *worker;
- PRUint32 expandedKey[CAMELLIA_MAX_EXPANDEDKEY];
- PRUint8 iv[CAMELLIA_BLOCK_SIZE];
-};
-
-#endif /* _CAMELLIA_H_ */
diff --git a/security/nss/lib/freebl/config.mk b/security/nss/lib/freebl/config.mk
deleted file mode 100644
index cf76b4989..000000000
--- a/security/nss/lib/freebl/config.mk
+++ /dev/null
@@ -1,97 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# only do this in the outermost freebl build.
-ifndef FREEBL_CHILD_BUILD
-
-# We're going to change this build so that it builds libfreebl.a with
-# just loader.c. Then we have to build this directory twice again to
-# build the two DSOs.
-# To build libfreebl.a with just loader.c, we must now override many
-# of the make variables setup by the prior inclusion of CORECONF's config.mk
-
-CSRCS = loader.c
-SIMPLE_OBJS = $(CSRCS:.c=$(OBJ_SUFFIX))
-OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(SIMPLE_OBJS))
-ALL_TRASH := $(TARGETS) $(OBJS) $(OBJDIR) LOGS TAGS $(GARBAGE) \
- $(NOSUCHFILE) so_locations
-
-# this is not a recursive child make. We make a static lib. (archive)
-
-# Override the values defined in coreconf's ruleset.mk.
-#
-# - (1) LIBRARY: a static (archival) library
-# - (2) SHARED_LIBRARY: a shared (dynamic link) library
-# - (3) IMPORT_LIBRARY: an import library, used only on Windows
-# - (4) PROGRAM: an executable binary
-#
-# override these variables to prevent building a DSO/DLL.
- TARGETS = $(LIBRARY)
- SHARED_LIBRARY =
- IMPORT_LIBRARY =
- PROGRAM =
-
-else
-
-# This is a recursive child make. We build the shared lib.
-
-TARGETS = $(SHARED_LIBRARY)
-LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
-ifeq ($(OS_TARGET), SunOS)
-OS_LIBS += -lkstat
-endif
-
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-
-RES = $(OBJDIR)/$(LIBRARY_NAME).res
-RESNAME = freebl.rc
-
-ifdef NS_USE_GCC
-OS_LIBS += -lshell32
-else
-OS_LIBS += shell32.lib
-endif
-
-ifdef NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lnspr4 \
- $(NULL)
-else # ! NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- $(DIST)/lib/nssutil3.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-
-else
-
-ifeq ($(FREEBL_NO_DEPEND),1)
-#drop pthreads as well
-OS_PTHREAD=
-else
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lnspr4 \
- $(NULL)
-endif
-endif
-
-ifeq ($(OS_ARCH), Darwin)
-EXTRA_SHARED_LIBS += -dylib_file @executable_path/libplc4.dylib:$(DIST)/lib/libplc4.dylib -dylib_file @executable_path/libplds4.dylib:$(DIST)/lib/libplds4.dylib
-endif
-
-endif
diff --git a/security/nss/lib/freebl/ctr.c b/security/nss/lib/freebl/ctr.c
deleted file mode 100644
index 3a2f1a6b8..000000000
--- a/security/nss/lib/freebl/ctr.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-#include "prtypes.h"
-#include "blapit.h"
-#include "blapii.h"
-#include "ctr.h"
-#include "pkcs11t.h"
-#include "secerr.h"
-
-SECStatus
-CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
- const unsigned char *param, unsigned int blocksize)
-{
- const CK_AES_CTR_PARAMS *ctrParams = (const CK_AES_CTR_PARAMS *)param;
-
- if (ctrParams->ulCounterBits == 0 ||
- ctrParams->ulCounterBits > blocksize * PR_BITS_PER_BYTE) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* Invariant: 0 < ctr->bufPtr <= blocksize */
- ctr->bufPtr = blocksize; /* no unused data in the buffer */
- ctr->cipher = cipher;
- ctr->context = context;
- ctr->counterBits = ctrParams->ulCounterBits;
- if (blocksize > sizeof(ctr->counter) ||
- blocksize > sizeof(ctrParams->cb)) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize);
- return SECSuccess;
-}
-
-CTRContext *
-CTR_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *param, unsigned int blocksize)
-{
- CTRContext *ctr;
- SECStatus rv;
-
- /* first fill in the Counter context */
- ctr = PORT_ZNew(CTRContext);
- if (ctr == NULL) {
- return NULL;
- }
- rv = CTR_InitContext(ctr, context, cipher, param, blocksize);
- if (rv != SECSuccess) {
- CTR_DestroyContext(ctr, PR_TRUE);
- ctr = NULL;
- }
- return ctr;
-}
-
-void
-CTR_DestroyContext(CTRContext *ctr, PRBool freeit)
-{
- PORT_Memset(ctr, 0, sizeof(CTRContext));
- if (freeit) {
- PORT_Free(ctr);
- }
-}
-
-/*
- * Used by counter mode. Increment the counter block. Not all bits in the
- * counter block are part of the counter, counterBits tells how many bits
- * are part of the counter. The counter block is blocksize long. It's a
- * big endian value.
- *
- * XXX Does not handle counter rollover.
- */
-static void
-ctr_GetNextCtr(unsigned char *counter, unsigned int counterBits,
- unsigned int blocksize)
-{
- unsigned char *counterPtr = counter + blocksize - 1;
- unsigned char mask, count;
-
- PORT_Assert(counterBits <= blocksize*PR_BITS_PER_BYTE);
- while (counterBits >= PR_BITS_PER_BYTE) {
- if (++(*(counterPtr--))) {
- return;
- }
- counterBits -= PR_BITS_PER_BYTE;
- }
- if (counterBits == 0) {
- return;
- }
- /* increment the final partial byte */
- mask = (1 << counterBits)-1;
- count = ++(*counterPtr) & mask;
- *counterPtr = ((*counterPtr) & ~mask) | count;
- return;
-}
-
-static void
-ctr_xor(unsigned char *target, const unsigned char *x,
- const unsigned char *y, unsigned int count)
-{
- unsigned int i;
- for (i=0; i < count; i++) {
- *target++ = *x++ ^ *y++;
- }
-}
-
-SECStatus
-CTR_Update(CTRContext *ctr, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
-{
- unsigned int tmp;
- SECStatus rv;
-
- if (maxout < inlen) {
- *outlen = inlen;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- *outlen = 0;
- if (ctr->bufPtr != blocksize) {
- unsigned int needed = PR_MIN(blocksize-ctr->bufPtr, inlen);
- ctr_xor(outbuf, inbuf, ctr->buffer+ctr->bufPtr, needed);
- ctr->bufPtr += needed;
- outbuf += needed;
- inbuf += needed;
- *outlen += needed;
- inlen -= needed;
- if (inlen == 0) {
- return SECSuccess;
- }
- PORT_Assert(ctr->bufPtr == blocksize);
- }
-
- while (inlen >= blocksize) {
- rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
- ctr->counter, blocksize, blocksize);
- ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- ctr_xor(outbuf, inbuf, ctr->buffer, blocksize);
- outbuf += blocksize;
- inbuf += blocksize;
- *outlen += blocksize;
- inlen -= blocksize;
- }
- if (inlen == 0) {
- return SECSuccess;
- }
- rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
- ctr->counter, blocksize, blocksize);
- ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- ctr_xor(outbuf, inbuf, ctr->buffer, inlen);
- ctr->bufPtr = inlen;
- *outlen += inlen;
- return SECSuccess;
-}
diff --git a/security/nss/lib/freebl/ctr.h b/security/nss/lib/freebl/ctr.h
deleted file mode 100644
index 69ef150b0..000000000
--- a/security/nss/lib/freebl/ctr.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CTR_H
-#define CTR_H 1
-
-#include "blapii.h"
-
-/* This structure is defined in this header because both ctr.c and gcm.c
- * need it. */
-struct CTRContextStr {
- freeblCipherFunc cipher;
- void *context;
- unsigned char counter[MAX_BLOCK_SIZE];
- unsigned char buffer[MAX_BLOCK_SIZE];
- unsigned long counterBits;
- unsigned int bufPtr;
-};
-
-typedef struct CTRContextStr CTRContext;
-
-SECStatus CTR_InitContext(CTRContext *ctr, void *context,
- freeblCipherFunc cipher, const unsigned char *param,
- unsigned int blocksize);
-
-/*
- * The context argument is the inner cipher context to use with cipher. The
- * CTRContext does not own context. context needs to remain valid for as long
- * as the CTRContext is valid.
- *
- * The cipher argument is a block cipher in the ECB encrypt mode.
- */
-CTRContext * CTR_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *param, unsigned int blocksize);
-
-void CTR_DestroyContext(CTRContext *ctr, PRBool freeit);
-
-SECStatus CTR_Update(CTRContext *ctr, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize);
-
-#endif
diff --git a/security/nss/lib/freebl/cts.c b/security/nss/lib/freebl/cts.c
deleted file mode 100644
index 74cdc0bea..000000000
--- a/security/nss/lib/freebl/cts.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-#include "blapit.h"
-#include "blapii.h"
-#include "cts.h"
-#include "secerr.h"
-
-struct CTSContextStr {
- freeblCipherFunc cipher;
- void *context;
- /* iv stores the last ciphertext block of the previous message.
- * Only used by decrypt. */
- unsigned char iv[MAX_BLOCK_SIZE];
-};
-
-CTSContext *
-CTS_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *iv, unsigned int blocksize)
-{
- CTSContext *cts;
-
- if (blocksize > MAX_BLOCK_SIZE) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
- cts = PORT_ZNew(CTSContext);
- if (cts == NULL) {
- return NULL;
- }
- PORT_Memcpy(cts->iv, iv, blocksize);
- cts->cipher = cipher;
- cts->context = context;
- return cts;
-}
-
-void
-CTS_DestroyContext(CTSContext *cts, PRBool freeit)
-{
- if (freeit) {
- PORT_Free(cts);
- }
-}
-
-/*
- * See addemdum to NIST SP 800-38A
- * Generically handle cipher text stealing. Basically this is doing CBC
- * operations except someone can pass us a partial block.
- *
- * Output Order:
- * CS-1: C1||C2||C3..Cn-1(could be partial)||Cn (NIST)
- * CS-2: pad == 0 C1||C2||C3...Cn-1(is full)||Cn (Schneier)
- * CS-2: pad != 0 C1||C2||C3...Cn||Cn-1(is partial)(Schneier)
- * CS-3: C1||C2||C3...Cn||Cn-1(could be partial) (Kerberos)
- *
- * The characteristics of these three options:
- * - NIST & Schneier (CS-1 & CS-2) are identical to CBC if there are no
- * partial blocks on input.
- * - Scheier and Kerberos (CS-2 and CS-3) have no embedded partial blocks,
- * which make decoding easier.
- * - NIST & Kerberos (CS-1 and CS-3) have consistent block order independent
- * of padding.
- *
- * PKCS #11 did not specify which version to implement, but points to the NIST
- * spec, so this code implements CTS-CS-1 from NIST.
- *
- * To convert the returned buffer to:
- * CS-2 (Schneier): do
- * unsigned char tmp[MAX_BLOCK_SIZE];
- * pad = *outlen % blocksize;
- * if (pad) {
- * memcpy(tmp, outbuf+*outlen-blocksize, blocksize);
- * memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad);
- * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize);
- * }
- * CS-3 (Kerberos): do
- * unsigned char tmp[MAX_BLOCK_SIZE];
- * pad = *outlen % blocksize;
- * if (pad == 0) {
- * pad = blocksize;
- * }
- * memcpy(tmp, outbuf+*outlen-blocksize, blocksize);
- * memcpy(outbuf+*outlen-pad,outbuf+*outlen-blocksize-pad, pad);
- * memcpy(outbuf+*outlen-blocksize-pad, tmp, blocksize);
- */
-SECStatus
-CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
-{
- unsigned char lastBlock[MAX_BLOCK_SIZE];
- unsigned int tmp;
- int fullblocks;
- int written;
- SECStatus rv;
-
- if (inlen < blocksize) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
-
- if (maxout < inlen) {
- *outlen = inlen;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- fullblocks = (inlen/blocksize)*blocksize;
- rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf,
- fullblocks, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- *outlen = fullblocks; /* AES low level doesn't set outlen */
- inbuf += fullblocks;
- inlen -= fullblocks;
- if (inlen == 0) {
- return SECSuccess;
- }
- written = *outlen - (blocksize - inlen);
- outbuf += written;
- maxout -= written;
-
- /*
- * here's the CTS magic, we pad our final block with zeros,
- * then do a CBC encrypt. CBC will xor our plain text with
- * the previous block (Cn-1), capturing part of that block (Cn-1**) as it
- * xors with the zero pad. We then write this full block, overwritting
- * (Cn-1**) in our buffer. This allows us to have input data == output
- * data since Cn contains enough information to reconver Cn-1** when
- * we decrypt (at the cost of some complexity as you can see in decrypt
- * below */
- PORT_Memcpy(lastBlock, inbuf, inlen);
- PORT_Memset(lastBlock + inlen, 0, blocksize - inlen);
- rv = (*cts->cipher)(cts->context, outbuf, &tmp, maxout, lastBlock,
- blocksize, blocksize);
- PORT_Memset(lastBlock, 0, blocksize);
- if (rv == SECSuccess) {
- *outlen = written + blocksize;
- }
- return rv;
-}
-
-
-#define XOR_BLOCK(x,y,count) for(i=0; i < count; i++) x[i] = x[i] ^ y[i]
-
-/*
- * See addemdum to NIST SP 800-38A
- * Decrypt, Expect CS-1: input. See the comment on the encrypt side
- * to understand what CS-2 and CS-3 mean.
- *
- * To convert the input buffer to CS-1 from ...
- * CS-2 (Schneier): do
- * unsigned char tmp[MAX_BLOCK_SIZE];
- * pad = inlen % blocksize;
- * if (pad) {
- * memcpy(tmp, inbuf+inlen-blocksize-pad, blocksize);
- * memcpy(inbuf+inlen-blocksize-pad,inbuf+inlen-pad, pad);
- * memcpy(inbuf+inlen-blocksize, tmp, blocksize);
- * }
- * CS-3 (Kerberos): do
- * unsigned char tmp[MAX_BLOCK_SIZE];
- * pad = inlen % blocksize;
- * if (pad == 0) {
- * pad = blocksize;
- * }
- * memcpy(tmp, inbuf+inlen-blocksize-pad, blocksize);
- * memcpy(inbuf+inlen-blocksize-pad,inbuf+inlen-pad, pad);
- * memcpy(inbuf+inlen-blocksize, tmp, blocksize);
- */
-SECStatus
-CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
-{
- unsigned char *Pn;
- unsigned char Cn_2[MAX_BLOCK_SIZE]; /* block Cn-2 */
- unsigned char Cn_1[MAX_BLOCK_SIZE]; /* block Cn-1 */
- unsigned char Cn[MAX_BLOCK_SIZE]; /* block Cn */
- unsigned char lastBlock[MAX_BLOCK_SIZE];
- const unsigned char *tmp;
- unsigned int tmpLen;
- int fullblocks, pad;
- unsigned int i;
- SECStatus rv;
-
- if (inlen < blocksize) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
-
- if (maxout < inlen) {
- *outlen = inlen;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
-
- fullblocks = (inlen/blocksize)*blocksize;
-
- /* even though we expect the input to be CS-1, CS-2 is easier to parse,
- * so convert to CS-2 immediately. NOTE: this is the same code as in
- * the comment for encrypt. NOTE2: since we can't modify inbuf unless
- * inbuf and outbuf overlap, just copy inbuf to outbuf and modify it there
- */
- pad = inlen - fullblocks;
- if (pad != 0) {
- if (inbuf != outbuf) {
- memcpy(outbuf, inbuf, inlen);
- /* keep the names so we logically know how we are using the
- * buffers */
- inbuf = outbuf;
- }
- memcpy(lastBlock, inbuf+inlen-blocksize, blocksize);
- /* we know inbuf == outbuf now, inbuf is declared const and can't
- * be the target, so use outbuf for the target here */
- memcpy(outbuf+inlen-pad, inbuf+inlen-blocksize-pad, pad);
- memcpy(outbuf+inlen-blocksize-pad, lastBlock, blocksize);
- }
- /* save the previous to last block so we can undo the misordered
- * chaining */
- tmp = (fullblocks < blocksize*2) ? cts->iv :
- inbuf+fullblocks-blocksize*2;
- PORT_Memcpy(Cn_2, tmp, blocksize);
- PORT_Memcpy(Cn, inbuf+fullblocks-blocksize, blocksize);
- rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf,
- fullblocks, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- *outlen = fullblocks; /* AES low level doesn't set outlen */
- inbuf += fullblocks;
- inlen -= fullblocks;
- if (inlen == 0) {
- return SECSuccess;
- }
- outbuf += fullblocks;
- maxout -= fullblocks;
-
- /* recover the stolen text */
- PORT_Memset(lastBlock, 0, blocksize);
- PORT_Memcpy(lastBlock, inbuf, inlen);
- PORT_Memcpy(Cn_1, inbuf, inlen);
- Pn = outbuf-blocksize;
- /* inbuf points to Cn-1* in the input buffer */
- /* NOTE: below there are 2 sections marked "make up for the out of order
- * cbc decryption". You may ask, what is going on here.
- * Short answer: CBC automatically xors the plain text with the previous
- * encrypted block. We are decrypting the last 2 blocks out of order, so
- * we have to 'back out' the decrypt xor and 'add back' the encrypt xor.
- * Long answer: When we encrypted, we encrypted as follows:
- * Pn-2, Pn-1, (Pn || 0), but on decryption we can't
- * decrypt Cn-1 until we decrypt Cn because part of Cn-1 is stored in
- * Cn (see below). So above we decrypted all the full blocks:
- * Cn-2, Cn,
- * to get:
- * Pn-2, Pn, Except that Pn is not yet corect. On encrypt, we
- * xor'd Pn || 0 with Cn-1, but on decrypt we xor'd it with Cn-2
- * To recover Pn, we xor the block with Cn-1* || 0 (in last block) and
- * Cn-2 to get Pn || Cn-1**. Pn can then be written to the output buffer
- * and we can now reunite Cn-1. With the full Cn-1 we can decrypt it,
- * but now decrypt is going to xor the decrypted data with Cn instead of
- * Cn-2. xoring Cn and Cn-2 restores the original Pn-1 and we can now
- * write that oout to the buffer */
-
- /* make up for the out of order CBC decryption */
- XOR_BLOCK(lastBlock, Cn_2, blocksize);
- XOR_BLOCK(lastBlock, Pn, blocksize);
- /* last buf now has Pn || Cn-1**, copy out Pn */
- PORT_Memcpy(outbuf, lastBlock, inlen);
- *outlen += inlen;
- /* copy Cn-1* into last buf to recover Cn-1 */
- PORT_Memcpy(lastBlock, Cn_1, inlen);
- /* note: because Cn and Cn-1 were out of order, our pointer to Pn also
- * points to where Pn-1 needs to reside. From here on out read Pn in
- * the code as really Pn-1. */
- rv = (*cts->cipher)(cts->context, Pn, &tmpLen, blocksize, lastBlock,
- blocksize, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* make up for the out of order CBC decryption */
- XOR_BLOCK(Pn, Cn_2, blocksize);
- XOR_BLOCK(Pn, Cn, blocksize);
- /* reset iv to Cn */
- PORT_Memcpy(cts->iv, Cn, blocksize);
- /* This makes Cn the last block for the next decrypt operation, which
- * matches the encrypt. We don't care about the contexts of last block,
- * only the side effect of setting the internal IV */
- (void) (*cts->cipher)(cts->context, lastBlock, &tmpLen, blocksize, Cn,
- blocksize, blocksize);
- /* clear last block. At this point last block contains Pn xor Cn_1 xor
- * Cn_2, both of with an attacker would know, so we need to clear this
- * buffer out */
- PORT_Memset(lastBlock, 0, blocksize);
- /* Cn, Cn_1, and Cn_2 have encrypted data, so no need to clear them */
- return SECSuccess;
-}
diff --git a/security/nss/lib/freebl/cts.h b/security/nss/lib/freebl/cts.h
deleted file mode 100644
index 97b385f4a..000000000
--- a/security/nss/lib/freebl/cts.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CTS_H
-#define CTS_H 1
-
-#include "blapii.h"
-
-typedef struct CTSContextStr CTSContext;
-
-/*
- * The context argument is the inner cipher context to use with cipher. The
- * CTSContext does not own context. context needs to remain valid for as long
- * as the CTSContext is valid.
- *
- * The cipher argument is a block cipher in the CBC mode.
- */
-CTSContext *CTS_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *iv, unsigned int blocksize);
-
-void CTS_DestroyContext(CTSContext *cts, PRBool freeit);
-
-SECStatus CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize);
-SECStatus CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize);
-
-#endif
diff --git a/security/nss/lib/freebl/des.c b/security/nss/lib/freebl/des.c
deleted file mode 100644
index 63a56acba..000000000
--- a/security/nss/lib/freebl/des.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- * des.c
- *
- * core source file for DES-150 library
- * Make key schedule from DES key.
- * Encrypt/Decrypt one 8-byte block.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "des.h"
-#include <stddef.h> /* for ptrdiff_t */
-/* #define USE_INDEXING 1 */
-
-/*
- * The tables below are the 8 sbox functions, with the 6-bit input permutation
- * and the 32-bit output permutation pre-computed.
- * They are shifted circularly to the left 3 bits, which removes 2 shifts
- * and an or from each round by reducing the number of sboxes whose
- * indices cross word broundaries from 2 to 1.
- */
-
-static const HALF SP[8][64] = {
-/* Box S1 */ {
- 0x04041000, 0x00000000, 0x00040000, 0x04041010,
- 0x04040010, 0x00041010, 0x00000010, 0x00040000,
- 0x00001000, 0x04041000, 0x04041010, 0x00001000,
- 0x04001010, 0x04040010, 0x04000000, 0x00000010,
- 0x00001010, 0x04001000, 0x04001000, 0x00041000,
- 0x00041000, 0x04040000, 0x04040000, 0x04001010,
- 0x00040010, 0x04000010, 0x04000010, 0x00040010,
- 0x00000000, 0x00001010, 0x00041010, 0x04000000,
- 0x00040000, 0x04041010, 0x00000010, 0x04040000,
- 0x04041000, 0x04000000, 0x04000000, 0x00001000,
- 0x04040010, 0x00040000, 0x00041000, 0x04000010,
- 0x00001000, 0x00000010, 0x04001010, 0x00041010,
- 0x04041010, 0x00040010, 0x04040000, 0x04001010,
- 0x04000010, 0x00001010, 0x00041010, 0x04041000,
- 0x00001010, 0x04001000, 0x04001000, 0x00000000,
- 0x00040010, 0x00041000, 0x00000000, 0x04040010
- },
-/* Box S2 */ {
- 0x00420082, 0x00020002, 0x00020000, 0x00420080,
- 0x00400000, 0x00000080, 0x00400082, 0x00020082,
- 0x00000082, 0x00420082, 0x00420002, 0x00000002,
- 0x00020002, 0x00400000, 0x00000080, 0x00400082,
- 0x00420000, 0x00400080, 0x00020082, 0x00000000,
- 0x00000002, 0x00020000, 0x00420080, 0x00400002,
- 0x00400080, 0x00000082, 0x00000000, 0x00420000,
- 0x00020080, 0x00420002, 0x00400002, 0x00020080,
- 0x00000000, 0x00420080, 0x00400082, 0x00400000,
- 0x00020082, 0x00400002, 0x00420002, 0x00020000,
- 0x00400002, 0x00020002, 0x00000080, 0x00420082,
- 0x00420080, 0x00000080, 0x00020000, 0x00000002,
- 0x00020080, 0x00420002, 0x00400000, 0x00000082,
- 0x00400080, 0x00020082, 0x00000082, 0x00400080,
- 0x00420000, 0x00000000, 0x00020002, 0x00020080,
- 0x00000002, 0x00400082, 0x00420082, 0x00420000
- },
-/* Box S3 */ {
- 0x00000820, 0x20080800, 0x00000000, 0x20080020,
- 0x20000800, 0x00000000, 0x00080820, 0x20000800,
- 0x00080020, 0x20000020, 0x20000020, 0x00080000,
- 0x20080820, 0x00080020, 0x20080000, 0x00000820,
- 0x20000000, 0x00000020, 0x20080800, 0x00000800,
- 0x00080800, 0x20080000, 0x20080020, 0x00080820,
- 0x20000820, 0x00080800, 0x00080000, 0x20000820,
- 0x00000020, 0x20080820, 0x00000800, 0x20000000,
- 0x20080800, 0x20000000, 0x00080020, 0x00000820,
- 0x00080000, 0x20080800, 0x20000800, 0x00000000,
- 0x00000800, 0x00080020, 0x20080820, 0x20000800,
- 0x20000020, 0x00000800, 0x00000000, 0x20080020,
- 0x20000820, 0x00080000, 0x20000000, 0x20080820,
- 0x00000020, 0x00080820, 0x00080800, 0x20000020,
- 0x20080000, 0x20000820, 0x00000820, 0x20080000,
- 0x00080820, 0x00000020, 0x20080020, 0x00080800
- },
-/* Box S4 */ {
- 0x02008004, 0x00008204, 0x00008204, 0x00000200,
- 0x02008200, 0x02000204, 0x02000004, 0x00008004,
- 0x00000000, 0x02008000, 0x02008000, 0x02008204,
- 0x00000204, 0x00000000, 0x02000200, 0x02000004,
- 0x00000004, 0x00008000, 0x02000000, 0x02008004,
- 0x00000200, 0x02000000, 0x00008004, 0x00008200,
- 0x02000204, 0x00000004, 0x00008200, 0x02000200,
- 0x00008000, 0x02008200, 0x02008204, 0x00000204,
- 0x02000200, 0x02000004, 0x02008000, 0x02008204,
- 0x00000204, 0x00000000, 0x00000000, 0x02008000,
- 0x00008200, 0x02000200, 0x02000204, 0x00000004,
- 0x02008004, 0x00008204, 0x00008204, 0x00000200,
- 0x02008204, 0x00000204, 0x00000004, 0x00008000,
- 0x02000004, 0x00008004, 0x02008200, 0x02000204,
- 0x00008004, 0x00008200, 0x02000000, 0x02008004,
- 0x00000200, 0x02000000, 0x00008000, 0x02008200
- },
-/* Box S5 */ {
- 0x00000400, 0x08200400, 0x08200000, 0x08000401,
- 0x00200000, 0x00000400, 0x00000001, 0x08200000,
- 0x00200401, 0x00200000, 0x08000400, 0x00200401,
- 0x08000401, 0x08200001, 0x00200400, 0x00000001,
- 0x08000000, 0x00200001, 0x00200001, 0x00000000,
- 0x00000401, 0x08200401, 0x08200401, 0x08000400,
- 0x08200001, 0x00000401, 0x00000000, 0x08000001,
- 0x08200400, 0x08000000, 0x08000001, 0x00200400,
- 0x00200000, 0x08000401, 0x00000400, 0x08000000,
- 0x00000001, 0x08200000, 0x08000401, 0x00200401,
- 0x08000400, 0x00000001, 0x08200001, 0x08200400,
- 0x00200401, 0x00000400, 0x08000000, 0x08200001,
- 0x08200401, 0x00200400, 0x08000001, 0x08200401,
- 0x08200000, 0x00000000, 0x00200001, 0x08000001,
- 0x00200400, 0x08000400, 0x00000401, 0x00200000,
- 0x00000000, 0x00200001, 0x08200400, 0x00000401
- },
-/* Box S6 */ {
- 0x80000040, 0x81000000, 0x00010000, 0x81010040,
- 0x81000000, 0x00000040, 0x81010040, 0x01000000,
- 0x80010000, 0x01010040, 0x01000000, 0x80000040,
- 0x01000040, 0x80010000, 0x80000000, 0x00010040,
- 0x00000000, 0x01000040, 0x80010040, 0x00010000,
- 0x01010000, 0x80010040, 0x00000040, 0x81000040,
- 0x81000040, 0x00000000, 0x01010040, 0x81010000,
- 0x00010040, 0x01010000, 0x81010000, 0x80000000,
- 0x80010000, 0x00000040, 0x81000040, 0x01010000,
- 0x81010040, 0x01000000, 0x00010040, 0x80000040,
- 0x01000000, 0x80010000, 0x80000000, 0x00010040,
- 0x80000040, 0x81010040, 0x01010000, 0x81000000,
- 0x01010040, 0x81010000, 0x00000000, 0x81000040,
- 0x00000040, 0x00010000, 0x81000000, 0x01010040,
- 0x00010000, 0x01000040, 0x80010040, 0x00000000,
- 0x81010000, 0x80000000, 0x01000040, 0x80010040
- },
-/* Box S7 */ {
- 0x00800000, 0x10800008, 0x10002008, 0x00000000,
- 0x00002000, 0x10002008, 0x00802008, 0x10802000,
- 0x10802008, 0x00800000, 0x00000000, 0x10000008,
- 0x00000008, 0x10000000, 0x10800008, 0x00002008,
- 0x10002000, 0x00802008, 0x00800008, 0x10002000,
- 0x10000008, 0x10800000, 0x10802000, 0x00800008,
- 0x10800000, 0x00002000, 0x00002008, 0x10802008,
- 0x00802000, 0x00000008, 0x10000000, 0x00802000,
- 0x10000000, 0x00802000, 0x00800000, 0x10002008,
- 0x10002008, 0x10800008, 0x10800008, 0x00000008,
- 0x00800008, 0x10000000, 0x10002000, 0x00800000,
- 0x10802000, 0x00002008, 0x00802008, 0x10802000,
- 0x00002008, 0x10000008, 0x10802008, 0x10800000,
- 0x00802000, 0x00000000, 0x00000008, 0x10802008,
- 0x00000000, 0x00802008, 0x10800000, 0x00002000,
- 0x10000008, 0x10002000, 0x00002000, 0x00800008
- },
-/* Box S8 */ {
- 0x40004100, 0x00004000, 0x00100000, 0x40104100,
- 0x40000000, 0x40004100, 0x00000100, 0x40000000,
- 0x00100100, 0x40100000, 0x40104100, 0x00104000,
- 0x40104000, 0x00104100, 0x00004000, 0x00000100,
- 0x40100000, 0x40000100, 0x40004000, 0x00004100,
- 0x00104000, 0x00100100, 0x40100100, 0x40104000,
- 0x00004100, 0x00000000, 0x00000000, 0x40100100,
- 0x40000100, 0x40004000, 0x00104100, 0x00100000,
- 0x00104100, 0x00100000, 0x40104000, 0x00004000,
- 0x00000100, 0x40100100, 0x00004000, 0x00104100,
- 0x40004000, 0x00000100, 0x40000100, 0x40100000,
- 0x40100100, 0x40000000, 0x00100000, 0x40004100,
- 0x00000000, 0x40104100, 0x00100100, 0x40000100,
- 0x40100000, 0x40004000, 0x40004100, 0x00000000,
- 0x40104100, 0x00104000, 0x00104000, 0x00004100,
- 0x00004100, 0x00100100, 0x40000000, 0x40104000
- }
-};
-
-static const HALF PC2[8][64] = {
-/* table 0 */ {
- 0x00000000, 0x00001000, 0x04000000, 0x04001000,
- 0x00100000, 0x00101000, 0x04100000, 0x04101000,
- 0x00008000, 0x00009000, 0x04008000, 0x04009000,
- 0x00108000, 0x00109000, 0x04108000, 0x04109000,
- 0x00000004, 0x00001004, 0x04000004, 0x04001004,
- 0x00100004, 0x00101004, 0x04100004, 0x04101004,
- 0x00008004, 0x00009004, 0x04008004, 0x04009004,
- 0x00108004, 0x00109004, 0x04108004, 0x04109004,
- 0x08000000, 0x08001000, 0x0c000000, 0x0c001000,
- 0x08100000, 0x08101000, 0x0c100000, 0x0c101000,
- 0x08008000, 0x08009000, 0x0c008000, 0x0c009000,
- 0x08108000, 0x08109000, 0x0c108000, 0x0c109000,
- 0x08000004, 0x08001004, 0x0c000004, 0x0c001004,
- 0x08100004, 0x08101004, 0x0c100004, 0x0c101004,
- 0x08008004, 0x08009004, 0x0c008004, 0x0c009004,
- 0x08108004, 0x08109004, 0x0c108004, 0x0c109004
- },
-/* table 1 */ {
- 0x00000000, 0x00002000, 0x80000000, 0x80002000,
- 0x00000008, 0x00002008, 0x80000008, 0x80002008,
- 0x00200000, 0x00202000, 0x80200000, 0x80202000,
- 0x00200008, 0x00202008, 0x80200008, 0x80202008,
- 0x20000000, 0x20002000, 0xa0000000, 0xa0002000,
- 0x20000008, 0x20002008, 0xa0000008, 0xa0002008,
- 0x20200000, 0x20202000, 0xa0200000, 0xa0202000,
- 0x20200008, 0x20202008, 0xa0200008, 0xa0202008,
- 0x00000400, 0x00002400, 0x80000400, 0x80002400,
- 0x00000408, 0x00002408, 0x80000408, 0x80002408,
- 0x00200400, 0x00202400, 0x80200400, 0x80202400,
- 0x00200408, 0x00202408, 0x80200408, 0x80202408,
- 0x20000400, 0x20002400, 0xa0000400, 0xa0002400,
- 0x20000408, 0x20002408, 0xa0000408, 0xa0002408,
- 0x20200400, 0x20202400, 0xa0200400, 0xa0202400,
- 0x20200408, 0x20202408, 0xa0200408, 0xa0202408
- },
-/* table 2 */ {
- 0x00000000, 0x00004000, 0x00000020, 0x00004020,
- 0x00080000, 0x00084000, 0x00080020, 0x00084020,
- 0x00000800, 0x00004800, 0x00000820, 0x00004820,
- 0x00080800, 0x00084800, 0x00080820, 0x00084820,
- 0x00000010, 0x00004010, 0x00000030, 0x00004030,
- 0x00080010, 0x00084010, 0x00080030, 0x00084030,
- 0x00000810, 0x00004810, 0x00000830, 0x00004830,
- 0x00080810, 0x00084810, 0x00080830, 0x00084830,
- 0x00400000, 0x00404000, 0x00400020, 0x00404020,
- 0x00480000, 0x00484000, 0x00480020, 0x00484020,
- 0x00400800, 0x00404800, 0x00400820, 0x00404820,
- 0x00480800, 0x00484800, 0x00480820, 0x00484820,
- 0x00400010, 0x00404010, 0x00400030, 0x00404030,
- 0x00480010, 0x00484010, 0x00480030, 0x00484030,
- 0x00400810, 0x00404810, 0x00400830, 0x00404830,
- 0x00480810, 0x00484810, 0x00480830, 0x00484830
- },
-/* table 3 */ {
- 0x00000000, 0x40000000, 0x00000080, 0x40000080,
- 0x00040000, 0x40040000, 0x00040080, 0x40040080,
- 0x00000040, 0x40000040, 0x000000c0, 0x400000c0,
- 0x00040040, 0x40040040, 0x000400c0, 0x400400c0,
- 0x10000000, 0x50000000, 0x10000080, 0x50000080,
- 0x10040000, 0x50040000, 0x10040080, 0x50040080,
- 0x10000040, 0x50000040, 0x100000c0, 0x500000c0,
- 0x10040040, 0x50040040, 0x100400c0, 0x500400c0,
- 0x00800000, 0x40800000, 0x00800080, 0x40800080,
- 0x00840000, 0x40840000, 0x00840080, 0x40840080,
- 0x00800040, 0x40800040, 0x008000c0, 0x408000c0,
- 0x00840040, 0x40840040, 0x008400c0, 0x408400c0,
- 0x10800000, 0x50800000, 0x10800080, 0x50800080,
- 0x10840000, 0x50840000, 0x10840080, 0x50840080,
- 0x10800040, 0x50800040, 0x108000c0, 0x508000c0,
- 0x10840040, 0x50840040, 0x108400c0, 0x508400c0
- },
-/* table 4 */ {
- 0x00000000, 0x00000008, 0x08000000, 0x08000008,
- 0x00040000, 0x00040008, 0x08040000, 0x08040008,
- 0x00002000, 0x00002008, 0x08002000, 0x08002008,
- 0x00042000, 0x00042008, 0x08042000, 0x08042008,
- 0x80000000, 0x80000008, 0x88000000, 0x88000008,
- 0x80040000, 0x80040008, 0x88040000, 0x88040008,
- 0x80002000, 0x80002008, 0x88002000, 0x88002008,
- 0x80042000, 0x80042008, 0x88042000, 0x88042008,
- 0x00080000, 0x00080008, 0x08080000, 0x08080008,
- 0x000c0000, 0x000c0008, 0x080c0000, 0x080c0008,
- 0x00082000, 0x00082008, 0x08082000, 0x08082008,
- 0x000c2000, 0x000c2008, 0x080c2000, 0x080c2008,
- 0x80080000, 0x80080008, 0x88080000, 0x88080008,
- 0x800c0000, 0x800c0008, 0x880c0000, 0x880c0008,
- 0x80082000, 0x80082008, 0x88082000, 0x88082008,
- 0x800c2000, 0x800c2008, 0x880c2000, 0x880c2008
- },
-/* table 5 */ {
- 0x00000000, 0x00400000, 0x00008000, 0x00408000,
- 0x40000000, 0x40400000, 0x40008000, 0x40408000,
- 0x00000020, 0x00400020, 0x00008020, 0x00408020,
- 0x40000020, 0x40400020, 0x40008020, 0x40408020,
- 0x00001000, 0x00401000, 0x00009000, 0x00409000,
- 0x40001000, 0x40401000, 0x40009000, 0x40409000,
- 0x00001020, 0x00401020, 0x00009020, 0x00409020,
- 0x40001020, 0x40401020, 0x40009020, 0x40409020,
- 0x00100000, 0x00500000, 0x00108000, 0x00508000,
- 0x40100000, 0x40500000, 0x40108000, 0x40508000,
- 0x00100020, 0x00500020, 0x00108020, 0x00508020,
- 0x40100020, 0x40500020, 0x40108020, 0x40508020,
- 0x00101000, 0x00501000, 0x00109000, 0x00509000,
- 0x40101000, 0x40501000, 0x40109000, 0x40509000,
- 0x00101020, 0x00501020, 0x00109020, 0x00509020,
- 0x40101020, 0x40501020, 0x40109020, 0x40509020
- },
-/* table 6 */ {
- 0x00000000, 0x00000040, 0x04000000, 0x04000040,
- 0x00000800, 0x00000840, 0x04000800, 0x04000840,
- 0x00800000, 0x00800040, 0x04800000, 0x04800040,
- 0x00800800, 0x00800840, 0x04800800, 0x04800840,
- 0x10000000, 0x10000040, 0x14000000, 0x14000040,
- 0x10000800, 0x10000840, 0x14000800, 0x14000840,
- 0x10800000, 0x10800040, 0x14800000, 0x14800040,
- 0x10800800, 0x10800840, 0x14800800, 0x14800840,
- 0x00000080, 0x000000c0, 0x04000080, 0x040000c0,
- 0x00000880, 0x000008c0, 0x04000880, 0x040008c0,
- 0x00800080, 0x008000c0, 0x04800080, 0x048000c0,
- 0x00800880, 0x008008c0, 0x04800880, 0x048008c0,
- 0x10000080, 0x100000c0, 0x14000080, 0x140000c0,
- 0x10000880, 0x100008c0, 0x14000880, 0x140008c0,
- 0x10800080, 0x108000c0, 0x14800080, 0x148000c0,
- 0x10800880, 0x108008c0, 0x14800880, 0x148008c0
- },
-/* table 7 */ {
- 0x00000000, 0x00000010, 0x00000400, 0x00000410,
- 0x00000004, 0x00000014, 0x00000404, 0x00000414,
- 0x00004000, 0x00004010, 0x00004400, 0x00004410,
- 0x00004004, 0x00004014, 0x00004404, 0x00004414,
- 0x20000000, 0x20000010, 0x20000400, 0x20000410,
- 0x20000004, 0x20000014, 0x20000404, 0x20000414,
- 0x20004000, 0x20004010, 0x20004400, 0x20004410,
- 0x20004004, 0x20004014, 0x20004404, 0x20004414,
- 0x00200000, 0x00200010, 0x00200400, 0x00200410,
- 0x00200004, 0x00200014, 0x00200404, 0x00200414,
- 0x00204000, 0x00204010, 0x00204400, 0x00204410,
- 0x00204004, 0x00204014, 0x00204404, 0x00204414,
- 0x20200000, 0x20200010, 0x20200400, 0x20200410,
- 0x20200004, 0x20200014, 0x20200404, 0x20200414,
- 0x20204000, 0x20204010, 0x20204400, 0x20204410,
- 0x20204004, 0x20204014, 0x20204404, 0x20204414
- }
-};
-
-/*
- * The PC-1 Permutation
- * If we number the bits of the 8 bytes of key input like this (in octal):
- * 00 01 02 03 04 05 06 07
- * 10 11 12 13 14 15 16 17
- * 20 21 22 23 24 25 26 27
- * 30 31 32 33 34 35 36 37
- * 40 41 42 43 44 45 46 47
- * 50 51 52 53 54 55 56 57
- * 60 61 62 63 64 65 66 67
- * 70 71 72 73 74 75 76 77
- * then after the PC-1 permutation,
- * C0 is
- * 70 60 50 40 30 20 10 00
- * 71 61 51 41 31 21 11 01
- * 72 62 52 42 32 22 12 02
- * 73 63 53 43
- * D0 is
- * 76 66 56 46 36 26 16 06
- * 75 65 55 45 35 25 15 05
- * 74 64 54 44 34 24 14 04
- * 33 23 13 03
- * and these parity bits have been discarded:
- * 77 67 57 47 37 27 17 07
- *
- * We achieve this by flipping the input matrix about the diagonal from 70-07,
- * getting left =
- * 77 67 57 47 37 27 17 07 (these are the parity bits)
- * 76 66 56 46 36 26 16 06
- * 75 65 55 45 35 25 15 05
- * 74 64 54 44 34 24 14 04
- * right =
- * 73 63 53 43 33 23 13 03
- * 72 62 52 42 32 22 12 02
- * 71 61 51 41 31 21 11 01
- * 70 60 50 40 30 20 10 00
- * then byte swap right, ala htonl() on a little endian machine.
- * right =
- * 70 60 50 40 30 20 10 00
- * 71 67 57 47 37 27 11 07
- * 72 62 52 42 32 22 12 02
- * 73 63 53 43 33 23 13 03
- * then
- * c0 = right >> 4;
- * d0 = ((left & 0x00ffffff) << 4) | (right & 0xf);
-*/
-
-#define FLIP_RIGHT_DIAGONAL(word, temp) \
- temp = (word ^ (word >> 18)) & 0x00003333; \
- word ^= temp | (temp << 18); \
- temp = (word ^ (word >> 9)) & 0x00550055; \
- word ^= temp | (temp << 9);
-
-#if defined(__GNUC__) && defined(NSS_X86_OR_X64)
-#define BYTESWAP(word, temp) \
- __asm("bswap %0" : "+r" (word));
-#elif (_MSC_VER >= 1300) && defined(NSS_X86_OR_X64)
-#include <stdlib.h>
-#pragma intrinsic(_byteswap_ulong)
-#define BYTESWAP(word, temp) \
- word = _byteswap_ulong(word);
-#elif defined(__GNUC__) && (defined(__thumb2__) || \
- (!defined(__thumb__) && \
- (defined(__ARM_ARCH_6__) || \
- defined(__ARM_ARCH_6J__) || \
- defined(__ARM_ARCH_6K__) || \
- defined(__ARM_ARCH_6Z__) || \
- defined(__ARM_ARCH_6ZK__) || \
- defined(__ARM_ARCH_6T2__) || \
- defined(__ARM_ARCH_7__) || \
- defined(__ARM_ARCH_7A__) || \
- defined(__ARM_ARCH_7R__))))
-#define BYTESWAP(word, temp) \
- __asm("rev %0, %0" : "+r" (word));
-#else
-#define BYTESWAP(word, temp) \
- word = (word >> 16) | (word << 16); \
- temp = 0x00ff00ff; \
- word = ((word & temp) << 8) | ((word >> 8) & temp);
-#endif
-
-#define PC1(left, right, c0, d0, temp) \
- right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
- left ^= temp << 4; \
- FLIP_RIGHT_DIAGONAL(left, temp); \
- FLIP_RIGHT_DIAGONAL(right, temp); \
- BYTESWAP(right, temp); \
- c0 = right >> 4; \
- d0 = ((left & 0x00ffffff) << 4) | (right & 0xf);
-
-#define LEFT_SHIFT_1( reg ) (((reg << 1) | (reg >> 27)) & 0x0FFFFFFF)
-#define LEFT_SHIFT_2( reg ) (((reg << 2) | (reg >> 26)) & 0x0FFFFFFF)
-
-/*
- * setup key schedules from key
- */
-
-void
-DES_MakeSchedule( HALF * ks, const BYTE * key, DESDirection direction)
-{
- register HALF left, right;
- register HALF c0, d0;
- register HALF temp;
- int delta;
- unsigned int ls;
-
-#if defined(NSS_X86_OR_X64)
- left = HALFPTR(key)[0];
- right = HALFPTR(key)[1];
- BYTESWAP(left, temp);
- BYTESWAP(right, temp);
-#else
- if (((ptrdiff_t)key & 0x03) == 0) {
- left = HALFPTR(key)[0];
- right = HALFPTR(key)[1];
-#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP(left, temp);
- BYTESWAP(right, temp);
-#endif
- } else {
- left = ((HALF)key[0] << 24) | ((HALF)key[1] << 16) |
- ((HALF)key[2] << 8) | key[3];
- right = ((HALF)key[4] << 24) | ((HALF)key[5] << 16) |
- ((HALF)key[6] << 8) | key[7];
- }
-#endif
-
- PC1(left, right, c0, d0, temp);
-
- if (direction == DES_ENCRYPT) {
- delta = 2 * (int)sizeof(HALF);
- } else {
- ks += 30;
- delta = (-2) * (int)sizeof(HALF);
- }
-
- for (ls = 0x8103; ls; ls >>= 1) {
- if ( ls & 1 ) {
- c0 = LEFT_SHIFT_1( c0 );
- d0 = LEFT_SHIFT_1( d0 );
- } else {
- c0 = LEFT_SHIFT_2( c0 );
- d0 = LEFT_SHIFT_2( d0 );
- }
-
-#ifdef USE_INDEXING
-#define PC2LOOKUP(b,c) PC2[b][c]
-
- left = PC2LOOKUP(0, ((c0 >> 22) & 0x3F) );
- left |= PC2LOOKUP(1, ((c0 >> 13) & 0x3F) );
- left |= PC2LOOKUP(2, ((c0 >> 4) & 0x38) | (c0 & 0x7) );
- left |= PC2LOOKUP(3, ((c0>>18)&0xC) | ((c0>>11)&0x3) | (c0&0x30));
-
- right = PC2LOOKUP(4, ((d0 >> 22) & 0x3F) );
- right |= PC2LOOKUP(5, ((d0 >> 15) & 0x30) | ((d0 >> 14) & 0xf) );
- right |= PC2LOOKUP(6, ((d0 >> 7) & 0x3F) );
- right |= PC2LOOKUP(7, ((d0 >> 1) & 0x3C) | (d0 & 0x3));
-#else
-#define PC2LOOKUP(b,c) *(HALF *)((BYTE *)&PC2[b][0]+(c))
-
- left = PC2LOOKUP(0, ((c0 >> 20) & 0xFC) );
- left |= PC2LOOKUP(1, ((c0 >> 11) & 0xFC) );
- left |= PC2LOOKUP(2, ((c0 >> 2) & 0xE0) | ((c0 << 2) & 0x1C) );
- left |= PC2LOOKUP(3, ((c0>>16)&0x30)|((c0>>9)&0xC)|((c0<<2)&0xC0));
-
- right = PC2LOOKUP(4, ((d0 >> 20) & 0xFC) );
- right |= PC2LOOKUP(5, ((d0 >> 13) & 0xC0) | ((d0 >> 12) & 0x3C) );
- right |= PC2LOOKUP(6, ((d0 >> 5) & 0xFC) );
- right |= PC2LOOKUP(7, ((d0 << 1) & 0xF0) | ((d0 << 2) & 0x0C));
-#endif
- /* left contains key bits for S1 S3 S2 S4 */
- /* right contains key bits for S6 S8 S5 S7 */
- temp = (left << 16) /* S2 S4 XX XX */
- | (right >> 16); /* XX XX S6 S8 */
- ks[0] = temp;
-
- temp = (left & 0xffff0000) /* S1 S3 XX XX */
- | (right & 0x0000ffff);/* XX XX S5 S7 */
- ks[1] = temp;
-
- ks = (HALF*)((BYTE *)ks + delta);
- }
-}
-
-/*
- * The DES Initial Permutation
- * if we number the bits of the 8 bytes of input like this (in octal):
- * 00 01 02 03 04 05 06 07
- * 10 11 12 13 14 15 16 17
- * 20 21 22 23 24 25 26 27
- * 30 31 32 33 34 35 36 37
- * 40 41 42 43 44 45 46 47
- * 50 51 52 53 54 55 56 57
- * 60 61 62 63 64 65 66 67
- * 70 71 72 73 74 75 76 77
- * then after the initial permutation, they will be in this order.
- * 71 61 51 41 31 21 11 01
- * 73 63 53 43 33 23 13 03
- * 75 65 55 45 35 25 15 05
- * 77 67 57 47 37 27 17 07
- * 70 60 50 40 30 20 10 00
- * 72 62 52 42 32 22 12 02
- * 74 64 54 44 34 24 14 04
- * 76 66 56 46 36 26 16 06
- *
- * One way to do this is in two steps:
- * 1. Flip this matrix about the diagonal from 70-07 as done for PC1.
- * 2. Rearrange the bytes (rows in the matrix above) with the following code.
- *
- * #define swapHiLo(word, temp) \
- * temp = (word ^ (word >> 24)) & 0x000000ff; \
- * word ^= temp | (temp << 24);
- *
- * right ^= temp = ((left << 8) ^ right) & 0xff00ff00;
- * left ^= temp >> 8;
- * swapHiLo(left, temp);
- * swapHiLo(right,temp);
- *
- * However, the two steps can be combined, so that the rows are rearranged
- * while the matrix is being flipped, reducing the number of bit exchange
- * operations from 8 ot 5.
- *
- * Initial Permutation */
-#define IP(left, right, temp) \
- right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
- left ^= temp << 4; \
- right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
- left ^= temp << 16; \
- right ^= temp = ((left << 2) ^ right) & 0xcccccccc; \
- left ^= temp >> 2; \
- right ^= temp = ((left << 8) ^ right) & 0xff00ff00; \
- left ^= temp >> 8; \
- right ^= temp = ((left >> 1) ^ right) & 0x55555555; \
- left ^= temp << 1;
-
-/* The Final (Inverse Initial) permutation is done by reversing the
-** steps of the Initital Permutation
-*/
-
-#define FP(left, right, temp) \
- right ^= temp = ((left >> 1) ^ right) & 0x55555555; \
- left ^= temp << 1; \
- right ^= temp = ((left << 8) ^ right) & 0xff00ff00; \
- left ^= temp >> 8; \
- right ^= temp = ((left << 2) ^ right) & 0xcccccccc; \
- left ^= temp >> 2; \
- right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
- left ^= temp << 16; \
- right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
- left ^= temp << 4;
-
-void
-DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf)
-{
- register HALF left, right;
- register HALF temp;
-
-#if defined(NSS_X86_OR_X64)
- left = HALFPTR(inbuf)[0];
- right = HALFPTR(inbuf)[1];
- BYTESWAP(left, temp);
- BYTESWAP(right, temp);
-#else
- if (((ptrdiff_t)inbuf & 0x03) == 0) {
- left = HALFPTR(inbuf)[0];
- right = HALFPTR(inbuf)[1];
-#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP(left, temp);
- BYTESWAP(right, temp);
-#endif
- } else {
- left = ((HALF)inbuf[0] << 24) | ((HALF)inbuf[1] << 16) |
- ((HALF)inbuf[2] << 8) | inbuf[3];
- right = ((HALF)inbuf[4] << 24) | ((HALF)inbuf[5] << 16) |
- ((HALF)inbuf[6] << 8) | inbuf[7];
- }
-#endif
-
- IP(left, right, temp);
-
- /* shift the values left circularly 3 bits. */
- left = (left << 3) | (left >> 29);
- right = (right << 3) | (right >> 29);
-
-#ifdef USE_INDEXING
-#define KSLOOKUP(s,b) SP[s][((temp >> (b+2)) & 0x3f)]
-#else
-#define KSLOOKUP(s,b) *(HALF*)((BYTE*)&SP[s][0]+((temp >> b) & 0xFC))
-#endif
-#define ROUND(out, in, r) \
- temp = in ^ ks[2*r]; \
- out ^= KSLOOKUP( 1, 24 ); \
- out ^= KSLOOKUP( 3, 16 ); \
- out ^= KSLOOKUP( 5, 8 ); \
- out ^= KSLOOKUP( 7, 0 ); \
- temp = ((in >> 4) | (in << 28)) ^ ks[2*r+1]; \
- out ^= KSLOOKUP( 0, 24 ); \
- out ^= KSLOOKUP( 2, 16 ); \
- out ^= KSLOOKUP( 4, 8 ); \
- out ^= KSLOOKUP( 6, 0 );
-
- /* Do the 16 Feistel rounds */
- ROUND(left, right, 0)
- ROUND(right, left, 1)
- ROUND(left, right, 2)
- ROUND(right, left, 3)
- ROUND(left, right, 4)
- ROUND(right, left, 5)
- ROUND(left, right, 6)
- ROUND(right, left, 7)
- ROUND(left, right, 8)
- ROUND(right, left, 9)
- ROUND(left, right, 10)
- ROUND(right, left, 11)
- ROUND(left, right, 12)
- ROUND(right, left, 13)
- ROUND(left, right, 14)
- ROUND(right, left, 15)
-
- /* now shift circularly right 3 bits to undo the shifting done
- ** above. switch left and right here.
- */
- temp = (left >> 3) | (left << 29);
- left = (right >> 3) | (right << 29);
- right = temp;
-
- FP(left, right, temp);
-
-#if defined(NSS_X86_OR_X64)
- BYTESWAP(left, temp);
- BYTESWAP(right, temp);
- HALFPTR(outbuf)[0] = left;
- HALFPTR(outbuf)[1] = right;
-#else
- if (((ptrdiff_t)outbuf & 0x03) == 0) {
-#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP(left, temp);
- BYTESWAP(right, temp);
-#endif
- HALFPTR(outbuf)[0] = left;
- HALFPTR(outbuf)[1] = right;
- } else {
- outbuf[0] = (BYTE)(left >> 24);
- outbuf[1] = (BYTE)(left >> 16);
- outbuf[2] = (BYTE)(left >> 8);
- outbuf[3] = (BYTE)(left );
-
- outbuf[4] = (BYTE)(right >> 24);
- outbuf[5] = (BYTE)(right >> 16);
- outbuf[6] = (BYTE)(right >> 8);
- outbuf[7] = (BYTE)(right );
- }
-#endif
-
-}
-
-/* Ackowledgements:
-** Two ideas used in this implementation were shown to me by Dennis Ferguson
-** in 1990. He credits them to Richard Outerbridge and Dan Hoey. They were:
-** 1. The method of computing the Initial and Final permutations.
-** 2. Circularly rotating the SP tables and the initial values of left and
-** right to reduce the number of shifts required during the 16 rounds.
-*/
diff --git a/security/nss/lib/freebl/des.h b/security/nss/lib/freebl/des.h
deleted file mode 100644
index 10dba12d0..000000000
--- a/security/nss/lib/freebl/des.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * des.h
- *
- * header file for DES-150 library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _DES_H_
-#define _DES_H_ 1
-
-#include "blapi.h"
-
-typedef unsigned char BYTE;
-typedef unsigned int HALF;
-
-#define HALFPTR(x) ((HALF *)(x))
-#define SHORTPTR(x) ((unsigned short *)(x))
-#define BYTEPTR(x) ((BYTE *)(x))
-
-typedef enum {
- DES_ENCRYPT = 0x5555,
- DES_DECRYPT = 0xAAAA
-} DESDirection;
-
-typedef void DESFunc(struct DESContextStr *cx, BYTE *out, const BYTE *in,
- unsigned int len);
-
-struct DESContextStr {
- /* key schedule, 16 internal keys, each with 8 6-bit parts */
- HALF ks0 [32];
- HALF ks1 [32];
- HALF ks2 [32];
- HALF iv [2];
- DESDirection direction;
- DESFunc *worker;
-};
-
-void DES_MakeSchedule( HALF * ks, const BYTE * key, DESDirection direction);
-void DES_Do1Block( HALF * ks, const BYTE * inbuf, BYTE * outbuf);
-
-#endif
diff --git a/security/nss/lib/freebl/desblapi.c b/security/nss/lib/freebl/desblapi.c
deleted file mode 100644
index 6a547af67..000000000
--- a/security/nss/lib/freebl/desblapi.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * desblapi.c
- *
- * core source file for DES-150 library
- * Implement DES Modes of Operation and Triple-DES.
- * Adapt DES-150 to blapi API.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "des.h"
-#include <stddef.h>
-#include "secerr.h"
-
-#if defined(NSS_X86_OR_X64)
-/* Intel X86 CPUs do unaligned loads and stores without complaint. */
-#define COPY8B(to, from, ptr) \
- HALFPTR(to)[0] = HALFPTR(from)[0]; \
- HALFPTR(to)[1] = HALFPTR(from)[1];
-#elif defined(USE_MEMCPY)
-#define COPY8B(to, from, ptr) memcpy(to, from, 8)
-#else
-#define COPY8B(to, from, ptr) \
- if (((ptrdiff_t)(ptr) & 0x3) == 0) { \
- HALFPTR(to)[0] = HALFPTR(from)[0]; \
- HALFPTR(to)[1] = HALFPTR(from)[1]; \
- } else if (((ptrdiff_t)(ptr) & 0x1) == 0) { \
- SHORTPTR(to)[0] = SHORTPTR(from)[0]; \
- SHORTPTR(to)[1] = SHORTPTR(from)[1]; \
- SHORTPTR(to)[2] = SHORTPTR(from)[2]; \
- SHORTPTR(to)[3] = SHORTPTR(from)[3]; \
- } else { \
- BYTEPTR(to)[0] = BYTEPTR(from)[0]; \
- BYTEPTR(to)[1] = BYTEPTR(from)[1]; \
- BYTEPTR(to)[2] = BYTEPTR(from)[2]; \
- BYTEPTR(to)[3] = BYTEPTR(from)[3]; \
- BYTEPTR(to)[4] = BYTEPTR(from)[4]; \
- BYTEPTR(to)[5] = BYTEPTR(from)[5]; \
- BYTEPTR(to)[6] = BYTEPTR(from)[6]; \
- BYTEPTR(to)[7] = BYTEPTR(from)[7]; \
- }
-#endif
-#define COPY8BTOHALF(to, from) COPY8B(to, from, from)
-#define COPY8BFROMHALF(to, from) COPY8B(to, from, to)
-
-static void
-DES_ECB(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
-{
- while (len) {
- DES_Do1Block(cx->ks0, in, out);
- len -= 8;
- in += 8;
- out += 8;
- }
-}
-
-static void
-DES_EDE3_ECB(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
-{
- while (len) {
- DES_Do1Block(cx->ks0, in, out);
- len -= 8;
- in += 8;
- DES_Do1Block(cx->ks1, out, out);
- DES_Do1Block(cx->ks2, out, out);
- out += 8;
- }
-}
-
-static void
-DES_CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
-{
- const BYTE * bufend = in + len;
- HALF vec[2];
-
- while (in != bufend) {
- COPY8BTOHALF(vec, in);
- in += 8;
- vec[0] ^= cx->iv[0];
- vec[1] ^= cx->iv[1];
- DES_Do1Block( cx->ks0, (BYTE *)vec, (BYTE *)cx->iv);
- COPY8BFROMHALF(out, cx->iv);
- out += 8;
- }
-}
-
-static void
-DES_CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
-{
- const BYTE * bufend;
- HALF oldciphertext[2];
- HALF plaintext [2];
-
- for (bufend = in + len; in != bufend; ) {
- oldciphertext[0] = cx->iv[0];
- oldciphertext[1] = cx->iv[1];
- COPY8BTOHALF(cx->iv, in);
- in += 8;
- DES_Do1Block(cx->ks0, (BYTE *)cx->iv, (BYTE *)plaintext);
- plaintext[0] ^= oldciphertext[0];
- plaintext[1] ^= oldciphertext[1];
- COPY8BFROMHALF(out, plaintext);
- out += 8;
- }
-}
-
-static void
-DES_EDE3CBCEn(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
-{
- const BYTE * bufend = in + len;
- HALF vec[2];
-
- while (in != bufend) {
- COPY8BTOHALF(vec, in);
- in += 8;
- vec[0] ^= cx->iv[0];
- vec[1] ^= cx->iv[1];
- DES_Do1Block( cx->ks0, (BYTE *)vec, (BYTE *)cx->iv);
- DES_Do1Block( cx->ks1, (BYTE *)cx->iv, (BYTE *)cx->iv);
- DES_Do1Block( cx->ks2, (BYTE *)cx->iv, (BYTE *)cx->iv);
- COPY8BFROMHALF(out, cx->iv);
- out += 8;
- }
-}
-
-static void
-DES_EDE3CBCDe(DESContext *cx, BYTE *out, const BYTE *in, unsigned int len)
-{
- const BYTE * bufend;
- HALF oldciphertext[2];
- HALF plaintext [2];
-
- for (bufend = in + len; in != bufend; ) {
- oldciphertext[0] = cx->iv[0];
- oldciphertext[1] = cx->iv[1];
- COPY8BTOHALF(cx->iv, in);
- in += 8;
- DES_Do1Block(cx->ks0, (BYTE *)cx->iv, (BYTE *)plaintext);
- DES_Do1Block(cx->ks1, (BYTE *)plaintext, (BYTE *)plaintext);
- DES_Do1Block(cx->ks2, (BYTE *)plaintext, (BYTE *)plaintext);
- plaintext[0] ^= oldciphertext[0];
- plaintext[1] ^= oldciphertext[1];
- COPY8BFROMHALF(out, plaintext);
- out += 8;
- }
-}
-
-DESContext *
-DES_AllocateContext(void)
-{
- return PORT_ZNew(DESContext);
-}
-
-SECStatus
-DES_InitContext(DESContext *cx, const unsigned char *key, unsigned int keylen,
- const unsigned char *iv, int mode, unsigned int encrypt,
- unsigned int unused)
-{
- DESDirection opposite;
- if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- cx->direction = encrypt ? DES_ENCRYPT : DES_DECRYPT;
- opposite = encrypt ? DES_DECRYPT : DES_ENCRYPT;
- switch (mode) {
- case NSS_DES: /* DES ECB */
- DES_MakeSchedule( cx->ks0, key, cx->direction);
- cx->worker = &DES_ECB;
- break;
-
- case NSS_DES_EDE3: /* DES EDE ECB */
- cx->worker = &DES_EDE3_ECB;
- if (encrypt) {
- DES_MakeSchedule(cx->ks0, key, cx->direction);
- DES_MakeSchedule(cx->ks1, key + 8, opposite);
- DES_MakeSchedule(cx->ks2, key + 16, cx->direction);
- } else {
- DES_MakeSchedule(cx->ks2, key, cx->direction);
- DES_MakeSchedule(cx->ks1, key + 8, opposite);
- DES_MakeSchedule(cx->ks0, key + 16, cx->direction);
- }
- break;
-
- case NSS_DES_CBC: /* DES CBC */
- COPY8BTOHALF(cx->iv, iv);
- cx->worker = encrypt ? &DES_CBCEn : &DES_CBCDe;
- DES_MakeSchedule(cx->ks0, key, cx->direction);
- break;
-
- case NSS_DES_EDE3_CBC: /* DES EDE CBC */
- COPY8BTOHALF(cx->iv, iv);
- if (encrypt) {
- cx->worker = &DES_EDE3CBCEn;
- DES_MakeSchedule(cx->ks0, key, cx->direction);
- DES_MakeSchedule(cx->ks1, key + 8, opposite);
- DES_MakeSchedule(cx->ks2, key + 16, cx->direction);
- } else {
- cx->worker = &DES_EDE3CBCDe;
- DES_MakeSchedule(cx->ks2, key, cx->direction);
- DES_MakeSchedule(cx->ks1, key + 8, opposite);
- DES_MakeSchedule(cx->ks0, key + 16, cx->direction);
- }
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-DESContext *
-DES_CreateContext(const BYTE * key, const BYTE *iv, int mode, PRBool encrypt)
-{
- DESContext *cx = PORT_ZNew(DESContext);
- SECStatus rv = DES_InitContext(cx, key, 0, iv, mode, encrypt, 0);
-
- if (rv != SECSuccess) {
- PORT_ZFree(cx, sizeof *cx);
- cx = NULL;
- }
- return cx;
-}
-
-void
-DES_DestroyContext(DESContext *cx, PRBool freeit)
-{
- if (cx) {
- memset(cx, 0, sizeof *cx);
- if (freeit)
- PORT_Free(cx);
- }
-}
-
-SECStatus
-DES_Encrypt(DESContext *cx, BYTE *out, unsigned int *outLen,
- unsigned int maxOutLen, const BYTE *in, unsigned int inLen)
-{
-
- if ((inLen % 8) != 0 || maxOutLen < inLen || !cx ||
- cx->direction != DES_ENCRYPT) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- cx->worker(cx, out, in, inLen);
- if (outLen)
- *outLen = inLen;
- return SECSuccess;
-}
-
-SECStatus
-DES_Decrypt(DESContext *cx, BYTE *out, unsigned int *outLen,
- unsigned int maxOutLen, const BYTE *in, unsigned int inLen)
-{
-
- if ((inLen % 8) != 0 || maxOutLen < inLen || !cx ||
- cx->direction != DES_DECRYPT) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- cx->worker(cx, out, in, inLen);
- if (outLen)
- *outLen = inLen;
- return SECSuccess;
-}
diff --git a/security/nss/lib/freebl/dh.c b/security/nss/lib/freebl/dh.c
deleted file mode 100644
index 827bb4f76..000000000
--- a/security/nss/lib/freebl/dh.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Diffie-Hellman parameter generation, key generation, and secret derivation.
- * KEA secret generation and verification.
- *
- * $Id$
- */
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prerr.h"
-#include "secerr.h"
-
-#include "blapi.h"
-#include "secitem.h"
-#include "mpi.h"
-#include "mpprime.h"
-#include "secmpi.h"
-
-#define KEA_DERIVED_SECRET_LEN 128
-
-/* Lengths are in bytes. */
-static unsigned int
-dh_GetSecretKeyLen(unsigned int primeLen)
-{
- /* Based on Table 2 in NIST SP 800-57. */
- if (primeLen >= 1920) { /* 15360 bits */
- return 64; /* 512 bits */
- }
- if (primeLen >= 960) { /* 7680 bits */
- return 48; /* 384 bits */
- }
- if (primeLen >= 384) { /* 3072 bits */
- return 32; /* 256 bits */
- }
- if (primeLen >= 256) { /* 2048 bits */
- return 28; /* 224 bits */
- }
- return 20; /* 160 bits */
-}
-
-SECStatus
-DH_GenParam(int primeLen, DHParams **params)
-{
- PRArenaPool *arena;
- DHParams *dhparams;
- unsigned char *pb = NULL;
- unsigned char *ab = NULL;
- unsigned long counter = 0;
- mp_int p, q, a, h, psub1, test;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- if (!params || primeLen < 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
- if (!arena) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- dhparams = (DHParams *)PORT_ArenaZAlloc(arena, sizeof(DHParams));
- if (!dhparams) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
- }
- dhparams->arena = arena;
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&a) = 0;
- MP_DIGITS(&h) = 0;
- MP_DIGITS(&psub1) = 0;
- MP_DIGITS(&test) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&a) );
- CHECK_MPI_OK( mp_init(&h) );
- CHECK_MPI_OK( mp_init(&psub1) );
- CHECK_MPI_OK( mp_init(&test) );
- /* generate prime with MPI, uses Miller-Rabin to generate strong prime. */
- pb = PORT_Alloc(primeLen);
- CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(pb, primeLen) );
- pb[0] |= 0x80; /* set high-order bit */
- pb[primeLen-1] |= 0x01; /* set low-order bit */
- CHECK_MPI_OK( mp_read_unsigned_octets(&p, pb, primeLen) );
- CHECK_MPI_OK( mpp_make_prime(&p, primeLen * 8, PR_TRUE, &counter) );
- /* construct Sophie-Germain prime q = (p-1)/2. */
- CHECK_MPI_OK( mp_sub_d(&p, 1, &psub1) );
- CHECK_MPI_OK( mp_div_2(&psub1, &q) );
- /* construct a generator from the prime. */
- ab = PORT_Alloc(primeLen);
- /* generate a candidate number a in p's field */
- CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(ab, primeLen) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&a, ab, primeLen) );
- /* force a < p (note that quot(a/p) <= 1) */
- if ( mp_cmp(&a, &p) > 0 )
- CHECK_MPI_OK( mp_sub(&a, &p, &a) );
- do {
- /* check that a is in the range [2..p-1] */
- if ( mp_cmp_d(&a, 2) < 0 || mp_cmp(&a, &psub1) >= 0) {
- /* a is outside of the allowed range. Set a=3 and keep going. */
- mp_set(&a, 3);
- }
- /* if a**q mod p != 1 then a is a generator */
- CHECK_MPI_OK( mp_exptmod(&a, &q, &p, &test) );
- if ( mp_cmp_d(&test, 1) != 0 )
- break;
- /* increment the candidate and try again. */
- CHECK_MPI_OK( mp_add_d(&a, 1, &a) );
- } while (PR_TRUE);
- MPINT_TO_SECITEM(&p, &dhparams->prime, arena);
- MPINT_TO_SECITEM(&a, &dhparams->base, arena);
- *params = dhparams;
-cleanup:
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&a);
- mp_clear(&h);
- mp_clear(&psub1);
- mp_clear(&test);
- if (pb) PORT_ZFree(pb, primeLen);
- if (ab) PORT_ZFree(ab, primeLen);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- if (rv)
- PORT_FreeArena(arena, PR_TRUE);
- return rv;
-}
-
-SECStatus
-DH_NewKey(DHParams *params, DHPrivateKey **privKey)
-{
- PRArenaPool *arena;
- DHPrivateKey *key;
- mp_int g, xa, p, Ya;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- if (!params || !privKey) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
- if (!arena) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- key = (DHPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DHPrivateKey));
- if (!key) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
- }
- key->arena = arena;
- MP_DIGITS(&g) = 0;
- MP_DIGITS(&xa) = 0;
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&Ya) = 0;
- CHECK_MPI_OK( mp_init(&g) );
- CHECK_MPI_OK( mp_init(&xa) );
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&Ya) );
- /* Set private key's p */
- CHECK_SEC_OK( SECITEM_CopyItem(arena, &key->prime, &params->prime) );
- SECITEM_TO_MPINT(key->prime, &p);
- /* Set private key's g */
- CHECK_SEC_OK( SECITEM_CopyItem(arena, &key->base, &params->base) );
- SECITEM_TO_MPINT(key->base, &g);
- /* Generate private key xa */
- SECITEM_AllocItem(arena, &key->privateValue,
- dh_GetSecretKeyLen(params->prime.len));
- RNG_GenerateGlobalRandomBytes(key->privateValue.data,
- key->privateValue.len);
- SECITEM_TO_MPINT( key->privateValue, &xa );
- /* xa < p */
- CHECK_MPI_OK( mp_mod(&xa, &p, &xa) );
- /* Compute public key Ya = g ** xa mod p */
- CHECK_MPI_OK( mp_exptmod(&g, &xa, &p, &Ya) );
- MPINT_TO_SECITEM(&Ya, &key->publicValue, key->arena);
- *privKey = key;
-cleanup:
- mp_clear(&g);
- mp_clear(&xa);
- mp_clear(&p);
- mp_clear(&Ya);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- if (rv)
- PORT_FreeArena(arena, PR_TRUE);
- return rv;
-}
-
-SECStatus
-DH_Derive(SECItem *publicValue,
- SECItem *prime,
- SECItem *privateValue,
- SECItem *derivedSecret,
- unsigned int outBytes)
-{
- mp_int p, Xa, Yb, ZZ;
- mp_err err = MP_OKAY;
- int len = 0;
- unsigned int nb;
- unsigned char *secret = NULL;
- if (!publicValue || !prime || !privateValue || !derivedSecret) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- memset(derivedSecret, 0, sizeof *derivedSecret);
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&Xa) = 0;
- MP_DIGITS(&Yb) = 0;
- MP_DIGITS(&ZZ) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&Xa) );
- CHECK_MPI_OK( mp_init(&Yb) );
- CHECK_MPI_OK( mp_init(&ZZ) );
- SECITEM_TO_MPINT(*publicValue, &Yb);
- SECITEM_TO_MPINT(*privateValue, &Xa);
- SECITEM_TO_MPINT(*prime, &p);
- /* ZZ = (Yb)**Xa mod p */
- CHECK_MPI_OK( mp_exptmod(&Yb, &Xa, &p, &ZZ) );
- /* number of bytes in the derived secret */
- len = mp_unsigned_octet_size(&ZZ);
- if (len <= 0) {
- err = MP_BADARG;
- goto cleanup;
- }
- /* allocate a buffer which can hold the entire derived secret. */
- secret = PORT_Alloc(len);
- /* grab the derived secret */
- err = mp_to_unsigned_octets(&ZZ, secret, len);
- if (err >= 0) err = MP_OKAY;
- /*
- ** if outBytes is 0 take all of the bytes from the derived secret.
- ** if outBytes is not 0 take exactly outBytes from the derived secret, zero
- ** pad at the beginning if necessary, and truncate beginning bytes
- ** if necessary.
- */
- if (outBytes > 0)
- nb = outBytes;
- else
- nb = len;
- SECITEM_AllocItem(NULL, derivedSecret, nb);
- if (len < nb) {
- unsigned int offset = nb - len;
- memset(derivedSecret->data, 0, offset);
- memcpy(derivedSecret->data + offset, secret, len);
- } else {
- memcpy(derivedSecret->data, secret + len - nb, nb);
- }
-cleanup:
- mp_clear(&p);
- mp_clear(&Xa);
- mp_clear(&Yb);
- mp_clear(&ZZ);
- if (secret) {
- /* free the buffer allocated for the full secret. */
- PORT_ZFree(secret, len);
- }
- if (err) {
- MP_TO_SEC_ERROR(err);
- if (derivedSecret->data)
- PORT_ZFree(derivedSecret->data, derivedSecret->len);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-KEA_Derive(SECItem *prime,
- SECItem *public1,
- SECItem *public2,
- SECItem *private1,
- SECItem *private2,
- SECItem *derivedSecret)
-{
- mp_int p, Y, R, r, x, t, u, w;
- mp_err err;
- unsigned char *secret = NULL;
- unsigned int len = 0, offset;
- if (!prime || !public1 || !public2 || !private1 || !private2 ||
- !derivedSecret) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- memset(derivedSecret, 0, sizeof *derivedSecret);
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&Y) = 0;
- MP_DIGITS(&R) = 0;
- MP_DIGITS(&r) = 0;
- MP_DIGITS(&x) = 0;
- MP_DIGITS(&t) = 0;
- MP_DIGITS(&u) = 0;
- MP_DIGITS(&w) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&Y) );
- CHECK_MPI_OK( mp_init(&R) );
- CHECK_MPI_OK( mp_init(&r) );
- CHECK_MPI_OK( mp_init(&x) );
- CHECK_MPI_OK( mp_init(&t) );
- CHECK_MPI_OK( mp_init(&u) );
- CHECK_MPI_OK( mp_init(&w) );
- SECITEM_TO_MPINT(*prime, &p);
- SECITEM_TO_MPINT(*public1, &Y);
- SECITEM_TO_MPINT(*public2, &R);
- SECITEM_TO_MPINT(*private1, &r);
- SECITEM_TO_MPINT(*private2, &x);
- /* t = DH(Y, r, p) = Y ** r mod p */
- CHECK_MPI_OK( mp_exptmod(&Y, &r, &p, &t) );
- /* u = DH(R, x, p) = R ** x mod p */
- CHECK_MPI_OK( mp_exptmod(&R, &x, &p, &u) );
- /* w = (t + u) mod p */
- CHECK_MPI_OK( mp_addmod(&t, &u, &p, &w) );
- /* allocate a buffer for the full derived secret */
- len = mp_unsigned_octet_size(&w);
- secret = PORT_Alloc(len);
- /* grab the secret */
- err = mp_to_unsigned_octets(&w, secret, len);
- if (err > 0) err = MP_OKAY;
- /* allocate output buffer */
- SECITEM_AllocItem(NULL, derivedSecret, KEA_DERIVED_SECRET_LEN);
- memset(derivedSecret->data, 0, derivedSecret->len);
- /* copy in the 128 lsb of the secret */
- if (len >= KEA_DERIVED_SECRET_LEN) {
- memcpy(derivedSecret->data, secret + (len - KEA_DERIVED_SECRET_LEN),
- KEA_DERIVED_SECRET_LEN);
- } else {
- offset = KEA_DERIVED_SECRET_LEN - len;
- memcpy(derivedSecret->data + offset, secret, len);
- }
-cleanup:
- mp_clear(&p);
- mp_clear(&Y);
- mp_clear(&R);
- mp_clear(&r);
- mp_clear(&x);
- mp_clear(&t);
- mp_clear(&u);
- mp_clear(&w);
- if (secret)
- PORT_ZFree(secret, len);
- if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-PRBool
-KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
-{
- mp_int p, q, y, r;
- mp_err err;
- int cmp = 1; /* default is false */
- if (!Y || !prime || !subPrime) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&y) = 0;
- MP_DIGITS(&r) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&y) );
- CHECK_MPI_OK( mp_init(&r) );
- SECITEM_TO_MPINT(*prime, &p);
- SECITEM_TO_MPINT(*subPrime, &q);
- SECITEM_TO_MPINT(*Y, &y);
- /* compute r = y**q mod p */
- CHECK_MPI_OK( mp_exptmod(&y, &q, &p, &r) );
- /* compare to 1 */
- cmp = mp_cmp_d(&r, 1);
-cleanup:
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&y);
- mp_clear(&r);
- if (err) {
- MP_TO_SEC_ERROR(err);
- return PR_FALSE;
- }
- return (cmp == 0) ? PR_TRUE : PR_FALSE;
-}
diff --git a/security/nss/lib/freebl/drbg.c b/security/nss/lib/freebl/drbg.c
deleted file mode 100644
index 386fde0d0..000000000
--- a/security/nss/lib/freebl/drbg.c
+++ /dev/null
@@ -1,915 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prerror.h"
-#include "secerr.h"
-
-#include "prtypes.h"
-#include "prinit.h"
-#include "blapi.h"
-#include "blapii.h"
-#include "nssilock.h"
-#include "secitem.h"
-#include "sha_fast.h"
-#include "sha256.h"
-#include "secrng.h" /* for RNG_SystemRNG() */
-#include "secmpi.h"
-
-/* PRNG_SEEDLEN defined in NIST SP 800-90 section 10.1
- * for SHA-1, SHA-224, and SHA-256 it's 440 bits.
- * for SHA-384 and SHA-512 it's 888 bits */
-#define PRNG_SEEDLEN (440/PR_BITS_PER_BYTE)
-static const PRInt64 PRNG_MAX_ADDITIONAL_BYTES = LL_INIT(0x1, 0x0);
- /* 2^35 bits or 2^32 bytes */
-#define PRNG_MAX_REQUEST_SIZE 0x10000 /* 2^19 bits or 2^16 bytes */
-#define PRNG_ADDITONAL_DATA_CACHE_SIZE (8*1024) /* must be less than
- * PRNG_MAX_ADDITIONAL_BYTES
- */
-
-/* RESEED_COUNT is how many calls to the prng before we need to reseed
- * under normal NIST rules, you must return an error. In the NSS case, we
- * self-reseed with RNG_SystemRNG(). Count can be a large number. For code
- * simplicity, we specify count with 2 components: RESEED_BYTE (which is
- * the same as LOG256(RESEED_COUNT)) and RESEED_VALUE (which is the same as
- * RESEED_COUNT / (256 ^ RESEED_BYTE)). Another way to look at this is
- * RESEED_COUNT = RESEED_VALUE * (256 ^ RESEED_BYTE). For Hash based DRBG
- * we use the maximum count value, 2^48, or RESEED_BYTE=6 and RESEED_VALUE=1
- */
-#define RESEED_BYTE 6
-#define RESEED_VALUE 1
-
-#define PRNG_RESET_RESEED_COUNT(rng) \
- PORT_Memset((rng)->reseed_counter, 0, sizeof (rng)->reseed_counter); \
- (rng)->reseed_counter[RESEED_BYTE] = 1;
-
-
-/*
- * The actual values of this enum are specified in SP 800-90, 10.1.1.*
- * The spec does not name the types, it only uses bare values
- */
-typedef enum {
- prngCGenerateType = 0, /* used when creating a new 'C' */
- prngReseedType = 1, /* used in reseeding */
- prngAdditionalDataType = 2, /* used in mixing additional data */
- prngGenerateByteType = 3 /* used when mixing internal state while
- * generating bytes */
-} prngVTypes;
-
-/*
- * Global RNG context
- */
-struct RNGContextStr {
- PZLock *lock; /* Lock to serialize access to global rng */
- /*
- * NOTE, a number of steps in the drbg algorithm need to hash
- * V_type || V. The code, therefore, depends on the V array following
- * immediately after V_type to avoid extra copies. To accomplish this
- * in a way that compiliers can't perturb, we declare V_type and V
- * as a V_Data array and reference them by macros */
- PRUint8 V_Data[PRNG_SEEDLEN+1]; /* internal state variables */
-#define V_type V_Data[0]
-#define V(rng) (((rng)->V_Data)+1)
-#define VSize(rng) ((sizeof (rng)->V_Data) -1)
- PRUint8 C[PRNG_SEEDLEN]; /* internal state variables */
- PRUint8 oldV[PRNG_SEEDLEN]; /* for continuous rng checking */
- /* If we get calls for the PRNG to return less than the length of our
- * hash, we extend the request for a full hash (since we'll be doing
- * the full hash anyway). Future requests for random numbers are fulfilled
- * from the remainder of the bytes we generated. Requests for bytes longer
- * than the hash size are fulfilled directly from the HashGen function
- * of the random number generator. */
- PRUint8 reseed_counter[RESEED_BYTE+1]; /* number of requests since the
- * last reseed. Need only be
- * big enough to hold the whole
- * reseed count */
- PRUint8 data[SHA256_LENGTH]; /* when we request less than a block
- * save the rest of the rng output for
- * another partial block */
- PRUint8 dataAvail; /* # bytes of output available in our cache,
- * [0...SHA256_LENGTH] */
- /* store additional data that has been shovelled off to us by
- * RNG_RandomUpdate. */
- PRUint8 additionalDataCache[PRNG_ADDITONAL_DATA_CACHE_SIZE];
- PRUint32 additionalAvail;
- PRBool isValid; /* false if RNG reaches an invalid state */
-};
-
-typedef struct RNGContextStr RNGContext;
-static RNGContext *globalrng = NULL;
-static RNGContext theGlobalRng;
-
-
-/*
- * The next several functions are derived from the NIST SP 800-90
- * spec. In these functions, an attempt was made to use names consistent
- * with the names in the spec, even if they differ from normal NSS usage.
- */
-
-/*
- * Hash Derive function defined in NISP SP 800-90 Section 10.4.1.
- * This function is used in the Instantiate and Reseed functions.
- *
- * NOTE: requested_bytes cannot overlap with input_string_1 or input_string_2.
- * input_string_1 and input_string_2 are logically concatentated.
- * input_string_1 must be supplied.
- * if input_string_2 is not supplied, NULL should be passed for this parameter.
- */
-static SECStatus
-prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
- const PRUint8 *input_string_1, unsigned int input_string_1_len,
- const PRUint8 *input_string_2, unsigned int input_string_2_len)
-{
- SHA256Context ctx;
- PRUint32 tmp;
- PRUint8 counter;
-
- tmp=SHA_HTONL(no_of_bytes_to_return*8);
-
- for (counter = 1 ; no_of_bytes_to_return > 0; counter++) {
- unsigned int hash_return_len;
- SHA256_Begin(&ctx);
- SHA256_Update(&ctx, &counter, 1);
- SHA256_Update(&ctx, (unsigned char *)&tmp, sizeof tmp);
- SHA256_Update(&ctx, input_string_1, input_string_1_len);
- if (input_string_2) {
- SHA256_Update(&ctx, input_string_2, input_string_2_len);
- }
- SHA256_End(&ctx, requested_bytes, &hash_return_len,
- no_of_bytes_to_return);
- requested_bytes += hash_return_len;
- no_of_bytes_to_return -= hash_return_len;
- }
- return SECSuccess;
-}
-
-
-/*
- * Hash_DRBG Instantiate NIST SP 800-80 10.1.1.2
- *
- * NOTE: bytes & len are entropy || nonce || personalization_string. In
- * normal operation, NSS calculates them all together in a single call.
- */
-static SECStatus
-prng_instantiate(RNGContext *rng, const PRUint8 *bytes, unsigned int len)
-{
- if (len < PRNG_SEEDLEN) {
- /* if the seedlen is to small, it's probably because we failed to get
- * enough random data */
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- return SECFailure;
- }
- prng_Hash_df(V(rng), VSize(rng), bytes, len, NULL, 0);
- rng->V_type = prngCGenerateType;
- prng_Hash_df(rng->C,sizeof rng->C,rng->V_Data,sizeof rng->V_Data,NULL,0);
- PRNG_RESET_RESEED_COUNT(rng)
- return SECSuccess;
-}
-
-
-/*
- * Update the global random number generator with more seeding
- * material. Use the Hash_DRBG reseed algorithm from NIST SP-800-90
- * section 10.1.1.3
- *
- * If entropy is NULL, it is fetched from the noise generator.
- */
-static SECStatus
-prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
- const PRUint8 *additional_input, unsigned int additional_input_len)
-{
- PRUint8 noiseData[(sizeof rng->V_Data)+PRNG_SEEDLEN];
- PRUint8 *noise = &noiseData[0];
-
- /* if entropy wasn't supplied, fetch it. (normal operation case) */
- if (entropy == NULL) {
- entropy_len = (unsigned int) RNG_SystemRNG(
- &noiseData[sizeof rng->V_Data], PRNG_SEEDLEN);
- } else {
- /* NOTE: this code is only available for testing, not to applications */
- /* if entropy was too big for the stack variable, get it from malloc */
- if (entropy_len > PRNG_SEEDLEN) {
- noise = PORT_Alloc(entropy_len + (sizeof rng->V_Data));
- if (noise == NULL) {
- return SECFailure;
- }
- }
- PORT_Memcpy(&noise[sizeof rng->V_Data],entropy, entropy_len);
- }
-
- if (entropy_len < 256/PR_BITS_PER_BYTE) {
- /* noise == &noiseData[0] at this point, so nothing to free */
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- return SECFailure;
- }
-
- rng->V_type = prngReseedType;
- PORT_Memcpy(noise, rng->V_Data, sizeof rng->V_Data);
- prng_Hash_df(V(rng), VSize(rng), noise, (sizeof rng->V_Data) + entropy_len,
- additional_input, additional_input_len);
- /* clear potential CSP */
- PORT_Memset(noise, 0, (sizeof rng->V_Data) + entropy_len);
- rng->V_type = prngCGenerateType;
- prng_Hash_df(rng->C,sizeof rng->C,rng->V_Data,sizeof rng->V_Data,NULL,0);
- PRNG_RESET_RESEED_COUNT(rng)
-
- if (noise != &noiseData[0]) {
- PORT_Free(noise);
- }
- return SECSuccess;
-}
-
-/*
- * SP 800-90 requires we rerun our health tests on reseed
- */
-static SECStatus
-prng_reseed_test(RNGContext *rng, const PRUint8 *entropy,
- unsigned int entropy_len, const PRUint8 *additional_input,
- unsigned int additional_input_len)
-{
- SECStatus rv;
-
- /* do health checks in FIPS mode */
- rv = PRNGTEST_RunHealthTests();
- if (rv != SECSuccess) {
- /* error set by PRNGTEST_RunHealTests() */
- rng->isValid = PR_FALSE;
- return SECFailure;
- }
- return prng_reseed(rng, entropy, entropy_len,
- additional_input, additional_input_len);
-}
-
-/*
- * build some fast inline functions for adding.
- */
-#define PRNG_ADD_CARRY_ONLY(dest, start, cy) \
- carry = cy; \
- for (k1=start; carry && k1 >=0 ; k1--) { \
- carry = !(++dest[k1]); \
- }
-
-/*
- * NOTE: dest must be an array for the following to work.
- */
-#define PRNG_ADD_BITS(dest, dest_len, add, len) \
- carry = 0; \
- for (k1=dest_len -1, k2=len-1; k2 >= 0; --k1, --k2) { \
- carry += dest[k1]+ add[k2]; \
- dest[k1] = (PRUint8) carry; \
- carry >>= 8; \
- }
-
-#define PRNG_ADD_BITS_AND_CARRY(dest, dest_len, add, len) \
- PRNG_ADD_BITS(dest, dest_len, add, len) \
- PRNG_ADD_CARRY_ONLY(dest, k1, carry)
-
-/*
- * This function expands the internal state of the prng to fulfill any number
- * of bytes we need for this request. We only use this call if we need more
- * than can be supplied by a single call to SHA256_HashBuf.
- *
- * This function is specified in NIST SP 800-90 section 10.1.1.4, Hashgen
- */
-static void
-prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
- unsigned int no_of_returned_bytes)
-{
- PRUint8 data[VSize(rng)];
-
- PORT_Memcpy(data, V(rng), VSize(rng));
- while (no_of_returned_bytes) {
- SHA256Context ctx;
- unsigned int len;
- unsigned int carry;
- int k1;
-
- SHA256_Begin(&ctx);
- SHA256_Update(&ctx, data, sizeof data);
- SHA256_End(&ctx, returned_bytes, &len, no_of_returned_bytes);
- returned_bytes += len;
- no_of_returned_bytes -= len;
- /* The carry parameter is a bool (increment or not).
- * This increments data if no_of_returned_bytes is not zero */
- PRNG_ADD_CARRY_ONLY(data, (sizeof data)- 1, no_of_returned_bytes);
- }
- PORT_Memset(data, 0, sizeof data);
-}
-
-/*
- * Generates new random bytes and advances the internal prng state.
- * additional bytes are only used in algorithm testing.
- *
- * This function is specified in NIST SP 800-90 section 10.1.1.4
- */
-static SECStatus
-prng_generateNewBytes(RNGContext *rng,
- PRUint8 *returned_bytes, unsigned int no_of_returned_bytes,
- const PRUint8 *additional_input,
- unsigned int additional_input_len)
-{
- PRUint8 H[SHA256_LENGTH]; /* both H and w since they
- * aren't used concurrently */
- unsigned int carry;
- int k1, k2;
-
- if (!rng->isValid) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* This code only triggers during tests, normal
- * prng operation does not use additional_input */
- if (additional_input){
- SHA256Context ctx;
- /* NIST SP 800-90 defines two temporaries in their calculations,
- * w and H. These temporaries are the same lengths, and used
- * at different times, so we use the following macro to collapse
- * them to the same variable, but keeping their unique names for
- * easy comparison to the spec */
-#define w H
- rng->V_type = prngAdditionalDataType;
- SHA256_Begin(&ctx);
- SHA256_Update(&ctx, rng->V_Data, sizeof rng->V_Data);
- SHA256_Update(&ctx, additional_input, additional_input_len);
- SHA256_End(&ctx, w, NULL, sizeof w);
- PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w)
- PORT_Memset(w, 0, sizeof w);
-#undef w
- }
-
- if (no_of_returned_bytes == SHA256_LENGTH) {
- /* short_cut to hashbuf and save a copy and a clear */
- SHA256_HashBuf(returned_bytes, V(rng), VSize(rng) );
- } else {
- prng_Hashgen(rng, returned_bytes, no_of_returned_bytes);
- }
- /* advance our internal state... */
- rng->V_type = prngGenerateByteType;
- SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data);
- PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof H)
- PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C);
- PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter,
- sizeof rng->reseed_counter)
- PRNG_ADD_CARRY_ONLY(rng->reseed_counter,(sizeof rng->reseed_counter)-1, 1);
-
- /* continuous rng check */
- if (memcmp(V(rng), rng->oldV, sizeof rng->oldV) == 0) {
- rng->isValid = PR_FALSE;
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- PORT_Memcpy(rng->oldV, V(rng), sizeof rng->oldV);
- return SECSuccess;
-}
-
-/* Use NSPR to prevent RNG_RNGInit from being called from separate
- * threads, creating a race condition.
- */
-static const PRCallOnceType pristineCallOnce;
-static PRCallOnceType coRNGInit;
-static PRStatus rng_init(void)
-{
- PRUint8 bytes[PRNG_SEEDLEN*2]; /* entropy + nonce */
- unsigned int numBytes;
- SECStatus rv = SECSuccess;
-
- if (globalrng == NULL) {
- /* bytes needs to have enough space to hold
- * a SHA256 hash value. Blow up at compile time if this isn't true */
- PR_STATIC_ASSERT(sizeof(bytes) >= SHA256_LENGTH);
- /* create a new global RNG context */
- globalrng = &theGlobalRng;
- PORT_Assert(NULL == globalrng->lock);
- /* create a lock for it */
- globalrng->lock = PZ_NewLock(nssILockOther);
- if (globalrng->lock == NULL) {
- globalrng = NULL;
- PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
- return PR_FAILURE;
- }
-
- /* Try to get some seed data for the RNG */
- numBytes = (unsigned int) RNG_SystemRNG(bytes, sizeof bytes);
- PORT_Assert(numBytes == 0 || numBytes == sizeof bytes);
- if (numBytes != 0) {
- /* if this is our first call, instantiate, otherwise reseed
- * prng_instantiate gets a new clean state, we want to mix
- * any previous entropy we may have collected */
- if (V(globalrng)[0] == 0) {
- rv = prng_instantiate(globalrng, bytes, numBytes);
- } else {
- rv = prng_reseed_test(globalrng, bytes, numBytes, NULL, 0);
- }
- memset(bytes, 0, numBytes);
- } else {
- PZ_DestroyLock(globalrng->lock);
- globalrng->lock = NULL;
- globalrng = NULL;
- return PR_FAILURE;
- }
-
- if (rv != SECSuccess) {
- return PR_FAILURE;
- }
- /* the RNG is in a valid state */
- globalrng->isValid = PR_TRUE;
-
- /* fetch one random value so that we can populate rng->oldV for our
- * continous random number test. */
- prng_generateNewBytes(globalrng, bytes, SHA256_LENGTH, NULL, 0);
-
- /* Fetch more entropy into the PRNG */
- RNG_SystemInfoForRNG();
- }
- return PR_SUCCESS;
-}
-
-/*
- * Clean up the global RNG context
- */
-static void
-prng_freeRNGContext(RNGContext *rng)
-{
- PRUint8 inputhash[VSize(rng) + (sizeof rng->C)];
-
- /* destroy context lock */
- SKIP_AFTER_FORK(PZ_DestroyLock(globalrng->lock));
-
- /* zero global RNG context except for C & V to preserve entropy */
- prng_Hash_df(inputhash, sizeof rng->C, rng->C, sizeof rng->C, NULL, 0);
- prng_Hash_df(&inputhash[sizeof rng->C], VSize(rng), V(rng), VSize(rng),
- NULL, 0);
- memset(rng, 0, sizeof *rng);
- memcpy(rng->C, inputhash, sizeof rng->C);
- memcpy(V(rng), &inputhash[sizeof rng->C], VSize(rng));
-
- memset(inputhash, 0, sizeof inputhash);
-}
-
-/*
- * Public functions
- */
-
-/*
- * Initialize the global RNG context and give it some seed input taken
- * from the system. This function is thread-safe and will only allow
- * the global context to be initialized once. The seed input is likely
- * small, so it is imperative that RNG_RandomUpdate() be called with
- * additional seed data before the generator is used. A good way to
- * provide the generator with additional entropy is to call
- * RNG_SystemInfoForRNG(). Note that C_Initialize() does exactly that.
- */
-SECStatus
-RNG_RNGInit(void)
-{
- /* Allow only one call to initialize the context */
- PR_CallOnce(&coRNGInit, rng_init);
- /* Make sure there is a context */
- return (globalrng != NULL) ? SECSuccess : SECFailure;
-}
-
-/*
-** Update the global random number generator with more seeding
-** material.
-*/
-SECStatus
-RNG_RandomUpdate(const void *data, size_t bytes)
-{
- SECStatus rv;
-
- /* Make sure our assumption that size_t is unsigned is true */
- PR_STATIC_ASSERT(((size_t)-1) > (size_t)1);
-
-#if defined(NS_PTR_GT_32) || (defined(NSS_USE_64) && !defined(NS_PTR_LE_32))
- /*
- * NIST 800-90 requires us to verify our inputs. This value can
- * come from the application, so we need to make sure it's within the
- * spec. The spec says it must be less than 2^32 bytes (2^35 bits).
- * This can only happen if size_t is greater than 32 bits (i.e. on
- * most 64 bit platforms). The 90% case (perhaps 100% case), size_t
- * is less than or equal to 32 bits if the platform is not 64 bits, and
- * greater than 32 bits if it is a 64 bit platform. The corner
- * cases are handled with explicit defines NS_PTR_GT_32 and NS_PTR_LE_32.
- *
- * In general, neither NS_PTR_GT_32 nor NS_PTR_LE_32 will need to be
- * defined. If you trip over the next two size ASSERTS at compile time,
- * you will need to define them for your platform.
- *
- * if 'sizeof(size_t) > 4' is triggered it means that we were expecting
- * sizeof(size_t) to be greater than 4, but it wasn't. Setting
- * NS_PTR_LE_32 will correct that mistake.
- *
- * if 'sizeof(size_t) <= 4' is triggered, it means that we were expecting
- * sizeof(size_t) to be less than or equal to 4, but it wasn't. Setting
- * NS_PTR_GT_32 will correct that mistake.
- */
-
- PR_STATIC_ASSERT(sizeof(size_t) > 4);
-
- if (bytes > PRNG_MAX_ADDITIONAL_BYTES) {
- bytes = PRNG_MAX_ADDITIONAL_BYTES;
- }
-#else
- PR_STATIC_ASSERT(sizeof(size_t) <= 4);
-#endif
-
- PZ_Lock(globalrng->lock);
- /* if we're passed more than our additionalDataCache, simply
- * call reseed with that data */
- if (bytes > sizeof (globalrng->additionalDataCache)) {
- rv = prng_reseed_test(globalrng, NULL, 0, data, (unsigned int) bytes);
- /* if we aren't going to fill or overflow the buffer, just cache it */
- } else if (bytes < ((sizeof globalrng->additionalDataCache)
- - globalrng->additionalAvail)) {
- PORT_Memcpy(globalrng->additionalDataCache+globalrng->additionalAvail,
- data, bytes);
- globalrng->additionalAvail += (PRUint32) bytes;
- rv = SECSuccess;
- } else {
- /* we are going to fill or overflow the buffer. In this case we will
- * fill the entropy buffer, reseed with it, start a new buffer with the
- * remainder. We know the remainder will fit in the buffer because
- * we already handled the case where bytes > the size of the buffer.
- */
- size_t bufRemain = (sizeof globalrng->additionalDataCache)
- - globalrng->additionalAvail;
- /* fill the rest of the buffer */
- if (bufRemain) {
- PORT_Memcpy(globalrng->additionalDataCache
- +globalrng->additionalAvail,
- data, bufRemain);
- data = ((unsigned char *)data) + bufRemain;
- bytes -= bufRemain;
- }
- /* reseed from buffer */
- rv = prng_reseed_test(globalrng, NULL, 0,
- globalrng->additionalDataCache,
- sizeof globalrng->additionalDataCache);
-
- /* copy the rest into the cache */
- PORT_Memcpy(globalrng->additionalDataCache, data, bytes);
- globalrng->additionalAvail = (PRUint32) bytes;
- }
-
- PZ_Unlock(globalrng->lock);
- return rv;
-}
-
-/*
-** Generate some random bytes, using the global random number generator
-** object.
-*/
-static SECStatus
-prng_GenerateGlobalRandomBytes(RNGContext *rng,
- void *dest, size_t len)
-{
- SECStatus rv = SECSuccess;
- PRUint8 *output = dest;
- /* check for a valid global RNG context */
- PORT_Assert(rng != NULL);
- if (rng == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* FIPS limits the amount of entropy available in a single request */
- if (len > PRNG_MAX_REQUEST_SIZE) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* --- LOCKED --- */
- PZ_Lock(rng->lock);
- /* Check the amount of seed data in the generator. If not enough,
- * don't produce any data.
- */
- if (rng->reseed_counter[0] >= RESEED_VALUE) {
- rv = prng_reseed_test(rng, NULL, 0, NULL, 0);
- PZ_Unlock(rng->lock);
- if (rv != SECSuccess) {
- return rv;
- }
- RNG_SystemInfoForRNG();
- PZ_Lock(rng->lock);
- }
- /*
- * see if we have enough bytes to fulfill the request.
- */
- if (len <= rng->dataAvail) {
- memcpy(output, rng->data + ((sizeof rng->data) - rng->dataAvail), len);
- memset(rng->data + ((sizeof rng->data) - rng->dataAvail), 0, len);
- rng->dataAvail -= len;
- rv = SECSuccess;
- /* if we are asking for a small number of bytes, cache the rest of
- * the bytes */
- } else if (len < sizeof rng->data) {
- rv = prng_generateNewBytes(rng, rng->data, sizeof rng->data,
- rng->additionalAvail ? rng->additionalDataCache : NULL,
- rng->additionalAvail);
- rng->additionalAvail = 0;
- if (rv == SECSuccess) {
- memcpy(output, rng->data, len);
- memset(rng->data, 0, len);
- rng->dataAvail = (sizeof rng->data) - len;
- }
- /* we are asking for lots of bytes, just ask the generator to pass them */
- } else {
- rv = prng_generateNewBytes(rng, output, len,
- rng->additionalAvail ? rng->additionalDataCache : NULL,
- rng->additionalAvail);
- rng->additionalAvail = 0;
- }
- PZ_Unlock(rng->lock);
- /* --- UNLOCKED --- */
- return rv;
-}
-
-/*
-** Generate some random bytes, using the global random number generator
-** object.
-*/
-SECStatus
-RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
-{
- return prng_GenerateGlobalRandomBytes(globalrng, dest, len);
-}
-
-void
-RNG_RNGShutdown(void)
-{
- /* check for a valid global RNG context */
- PORT_Assert(globalrng != NULL);
- if (globalrng == NULL) {
- /* Should set a "not initialized" error code. */
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return;
- }
- /* clear */
- prng_freeRNGContext(globalrng);
- globalrng = NULL;
- /* reset the callonce struct to allow a new call to RNG_RNGInit() */
- coRNGInit = pristineCallOnce;
-}
-
-/*
- * Test case interface. used by fips testing and power on self test
- */
- /* make sure the test context is separate from the global context, This
- * allows us to test the internal random number generator without losing
- * entropy we may have previously collected. */
-RNGContext testContext;
-
-/*
- * Test vector API. Use NIST SP 800-90 general interface so one of the
- * other NIST SP 800-90 algorithms may be used in the future.
- */
-SECStatus
-PRNGTEST_Instantiate(const PRUint8 *entropy, unsigned int entropy_len,
- const PRUint8 *nonce, unsigned int nonce_len,
- const PRUint8 *personal_string, unsigned int ps_len)
-{
- int bytes_len = entropy_len + nonce_len + ps_len;
- PRUint8 *bytes = NULL;
- SECStatus rv;
-
- if (entropy_len < 256/PR_BITS_PER_BYTE) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- return SECFailure;
- }
-
- bytes = PORT_Alloc(bytes_len);
- if (bytes == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- /* concatenate the various inputs, internally NSS only instantiates with
- * a single long string */
- PORT_Memcpy(bytes, entropy, entropy_len);
- if (nonce) {
- PORT_Memcpy(&bytes[entropy_len], nonce, nonce_len);
- } else {
- PORT_Assert(nonce_len == 0);
- }
- if (personal_string) {
- PORT_Memcpy(&bytes[entropy_len+nonce_len], personal_string, ps_len);
- } else {
- PORT_Assert(ps_len == 0);
- }
- rv = prng_instantiate(&testContext, bytes, bytes_len);
- PORT_ZFree(bytes, bytes_len);
- if (rv == SECFailure) {
- return SECFailure;
- }
- testContext.isValid = PR_TRUE;
- return SECSuccess;
-}
-
-SECStatus
-PRNGTEST_Reseed(const PRUint8 *entropy, unsigned int entropy_len,
- const PRUint8 *additional, unsigned int additional_len)
-{
- if (!testContext.isValid) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* This magic input tells us to set the reseed count to it's max count,
- * so we can simulate PRNGTEST_Generate reaching max reseed count */
- if ((entropy == NULL) && (entropy_len == 0) &&
- (additional == NULL) && (additional_len == 0)) {
- testContext.reseed_counter[0] = RESEED_VALUE;
- return SECSuccess;
- }
- return prng_reseed(&testContext, entropy, entropy_len, additional,
- additional_len);
-
-}
-
-SECStatus
-PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
- const PRUint8 *additional, unsigned int additional_len)
-{
- SECStatus rv;
- if (!testContext.isValid) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* replicate reseed test from prng_GenerateGlobalRandomBytes */
- if (testContext.reseed_counter[0] >= RESEED_VALUE) {
- rv = prng_reseed(&testContext, NULL, 0, NULL, 0);
- if (rv != SECSuccess) {
- return rv;
- }
- }
- return prng_generateNewBytes(&testContext, bytes, bytes_len,
- additional, additional_len);
-
-}
-
-SECStatus
-PRNGTEST_Uninstantiate()
-{
- if (!testContext.isValid) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- PORT_Memset(&testContext, 0, sizeof testContext);
- return SECSuccess;
-}
-
-SECStatus
-PRNGTEST_RunHealthTests()
-{
- static const PRUint8 entropy[] = {
- 0x8e,0x9c,0x0d,0x25,0x75,0x22,0x04,0xf9,
- 0xc5,0x79,0x10,0x8b,0x23,0x79,0x37,0x14,
- 0x9f,0x2c,0xc7,0x0b,0x39,0xf8,0xee,0xef,
- 0x95,0x0c,0x97,0x59,0xfc,0x0a,0x85,0x41,
- 0x76,0x9d,0x6d,0x67,0x00,0x4e,0x19,0x12,
- 0x02,0x16,0x53,0xea,0xf2,0x73,0xd7,0xd6,
- 0x7f,0x7e,0xc8,0xae,0x9c,0x09,0x99,0x7d,
- 0xbb,0x9e,0x48,0x7f,0xbb,0x96,0x46,0xb3,
- 0x03,0x75,0xf8,0xc8,0x69,0x45,0x3f,0x97,
- 0x5e,0x2e,0x48,0xe1,0x5d,0x58,0x97,0x4c };
- static const PRUint8 rng_known_result[] = {
- 0x16,0xe1,0x8c,0x57,0x21,0xd8,0xf1,0x7e,
- 0x5a,0xa0,0x16,0x0b,0x7e,0xa6,0x25,0xb4,
- 0x24,0x19,0xdb,0x54,0xfa,0x35,0x13,0x66,
- 0xbb,0xaa,0x2a,0x1b,0x22,0x33,0x2e,0x4a,
- 0x14,0x07,0x9d,0x52,0xfc,0x73,0x61,0x48,
- 0xac,0xc1,0x22,0xfc,0xa4,0xfc,0xac,0xa4,
- 0xdb,0xda,0x5b,0x27,0x33,0xc4,0xb3 };
- static const PRUint8 reseed_entropy[] = {
- 0xc6,0x0b,0x0a,0x30,0x67,0x07,0xf4,0xe2,
- 0x24,0xa7,0x51,0x6f,0x5f,0x85,0x3e,0x5d,
- 0x67,0x97,0xb8,0x3b,0x30,0x9c,0x7a,0xb1,
- 0x52,0xc6,0x1b,0xc9,0x46,0xa8,0x62,0x79 };
- static const PRUint8 additional_input[] = {
- 0x86,0x82,0x28,0x98,0xe7,0xcb,0x01,0x14,
- 0xae,0x87,0x4b,0x1d,0x99,0x1b,0xc7,0x41,
- 0x33,0xff,0x33,0x66,0x40,0x95,0x54,0xc6,
- 0x67,0x4d,0x40,0x2a,0x1f,0xf9,0xeb,0x65 };
- static const PRUint8 rng_reseed_result[] = {
- 0x02,0x0c,0xc6,0x17,0x86,0x49,0xba,0xc4,
- 0x7b,0x71,0x35,0x05,0xf0,0xdb,0x4a,0xc2,
- 0x2c,0x38,0xc1,0xa4,0x42,0xe5,0x46,0x4a,
- 0x7d,0xf0,0xbe,0x47,0x88,0xb8,0x0e,0xc6,
- 0x25,0x2b,0x1d,0x13,0xef,0xa6,0x87,0x96,
- 0xa3,0x7d,0x5b,0x80,0xc2,0x38,0x76,0x61,
- 0xc7,0x80,0x5d,0x0f,0x05,0x76,0x85 };
- static const PRUint8 rng_no_reseed_result[] = {
- 0xc4,0x40,0x41,0x8c,0xbf,0x2f,0x70,0x23,
- 0x88,0xf2,0x7b,0x30,0xc3,0xca,0x1e,0xf3,
- 0xef,0x53,0x81,0x5d,0x30,0xed,0x4c,0xf1,
- 0xff,0x89,0xa5,0xee,0x92,0xf8,0xc0,0x0f,
- 0x88,0x53,0xdf,0xb6,0x76,0xf0,0xaa,0xd3,
- 0x2e,0x1d,0x64,0x37,0x3e,0xe8,0x4a,0x02,
- 0xff,0x0a,0x7f,0xe5,0xe9,0x2b,0x6d };
-
- SECStatus rng_status = SECSuccess;
- PR_STATIC_ASSERT(sizeof(rng_known_result) >= sizeof(rng_reseed_result));
- PRUint8 result[sizeof(rng_known_result)];
-
- /********************************************/
- /* First test instantiate error path. */
- /* In this case we supply enough entropy, */
- /* but not enough seed. This will trigger */
- /* the code that checks for a entropy */
- /* source failure. */
- /********************************************/
- rng_status = PRNGTEST_Instantiate(entropy, 256/PR_BITS_PER_BYTE,
- NULL, 0, NULL, 0);
- if (rng_status == SECSuccess) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (PORT_GetError() != SEC_ERROR_NEED_RANDOM) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* we failed with the proper error code, we can continue */
-
- /********************************************/
- /* Generate random bytes with a known seed. */
- /********************************************/
- rng_status = PRNGTEST_Instantiate(entropy, sizeof entropy,
- NULL, 0, NULL, 0);
- if (rng_status != SECSuccess) {
- /* Error set by PRNGTEST_Instantiate */
- return SECFailure;
- }
- rng_status = PRNGTEST_Generate(result, sizeof rng_known_result, NULL, 0);
- if ( ( rng_status != SECSuccess) ||
- ( PORT_Memcmp( result, rng_known_result,
- sizeof rng_known_result ) != 0 ) ) {
- PRNGTEST_Uninstantiate();
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- rng_status = PRNGTEST_Reseed(reseed_entropy, sizeof reseed_entropy,
- additional_input, sizeof additional_input);
- if (rng_status != SECSuccess) {
- /* Error set by PRNG_Reseed */
- PRNGTEST_Uninstantiate();
- return SECFailure;
- }
- rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0);
- if ( ( rng_status != SECSuccess) ||
- ( PORT_Memcmp( result, rng_reseed_result,
- sizeof rng_reseed_result ) != 0 ) ) {
- PRNGTEST_Uninstantiate();
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* This magic forces the reseed count to it's max count, so we can see if
- * PRNGTEST_Generate will actually when it reaches it's count */
- rng_status = PRNGTEST_Reseed(NULL, 0, NULL, 0);
- if (rng_status != SECSuccess) {
- PRNGTEST_Uninstantiate();
- /* Error set by PRNG_Reseed */
- return SECFailure;
- }
- /* This generate should now reseed */
- rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0);
- if ( ( rng_status != SECSuccess) ||
- /* NOTE we fail if the result is equal to the no_reseed_result.
- * no_reseed_result is the value we would have gotten if we didn't
- * do an automatic reseed in PRNGTEST_Generate */
- ( PORT_Memcmp( result, rng_no_reseed_result,
- sizeof rng_no_reseed_result ) == 0 ) ) {
- PRNGTEST_Uninstantiate();
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* make sure reseed fails when we don't supply enough entropy */
- rng_status = PRNGTEST_Reseed(reseed_entropy, 4, NULL, 0);
- if (rng_status == SECSuccess) {
- PRNGTEST_Uninstantiate();
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (PORT_GetError() != SEC_ERROR_NEED_RANDOM) {
- PRNGTEST_Uninstantiate();
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- rng_status = PRNGTEST_Uninstantiate();
- if (rng_status != SECSuccess) {
- /* Error set by PRNG_Uninstantiate */
- return rng_status;
- }
- /* make sure uninstantiate fails if the contest is not initiated (also tests
- * if the context was cleared in the previous Uninstantiate) */
- rng_status = PRNGTEST_Uninstantiate();
- if (rng_status == SECSuccess) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (PORT_GetError() != SEC_ERROR_LIBRARY_FAILURE) {
- return rng_status;
- }
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/freebl/dsa.c b/security/nss/lib/freebl/dsa.c
deleted file mode 100644
index a17b5c6eb..000000000
--- a/security/nss/lib/freebl/dsa.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prerror.h"
-#include "secerr.h"
-
-#include "prtypes.h"
-#include "prinit.h"
-#include "blapi.h"
-#include "nssilock.h"
-#include "secitem.h"
-#include "blapi.h"
-#include "mpi.h"
-#include "secmpi.h"
-#include "pqg.h"
-
- /* XXX to be replaced by define in blapit.h */
-#define NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE 2048
-
-/*
- * FIPS 186-2 requires result from random output to be reduced mod q when
- * generating random numbers for DSA.
- *
- * Input: w, 2*qLen bytes
- * q, qLen bytes
- * Output: xj, qLen bytes
- */
-static SECStatus
-fips186Change_ReduceModQForDSA(const PRUint8 *w, const PRUint8 *q,
- unsigned int qLen, PRUint8 * xj)
-{
- mp_int W, Q, Xj;
- mp_err err;
- SECStatus rv = SECSuccess;
-
- /* Initialize MPI integers. */
- MP_DIGITS(&W) = 0;
- MP_DIGITS(&Q) = 0;
- MP_DIGITS(&Xj) = 0;
- CHECK_MPI_OK( mp_init(&W) );
- CHECK_MPI_OK( mp_init(&Q) );
- CHECK_MPI_OK( mp_init(&Xj) );
- /*
- * Convert input arguments into MPI integers.
- */
- CHECK_MPI_OK( mp_read_unsigned_octets(&W, w, 2*qLen) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&Q, q, qLen) );
-
- /*
- * Algorithm 1 of FIPS 186-2 Change Notice 1, Step 3.3
- *
- * xj = (w0 || w1) mod q
- */
- CHECK_MPI_OK( mp_mod(&W, &Q, &Xj) );
- CHECK_MPI_OK( mp_to_fixlen_octets(&Xj, xj, qLen) );
-cleanup:
- mp_clear(&W);
- mp_clear(&Q);
- mp_clear(&Xj);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/*
- * FIPS 186-2 requires result from random output to be reduced mod q when
- * generating random numbers for DSA.
- */
-SECStatus
-FIPS186Change_ReduceModQForDSA(const unsigned char *w,
- const unsigned char *q,
- unsigned char *xj) {
- return fips186Change_ReduceModQForDSA(w, q, DSA1_SUBPRIME_LEN, xj);
-}
-
-/*
- * The core of Algorithm 1 of FIPS 186-2 Change Notice 1.
- *
- * We no longer support FIPS 186-2 RNG. This function was exported
- * for power-up self tests and FIPS tests. Keep this stub, which fails,
- * to prevent crashes, but also to signal to test code that FIPS 186-2
- * RNG is no longer supported.
- */
-SECStatus
-FIPS186Change_GenerateX(PRUint8 *XKEY, const PRUint8 *XSEEDj,
- PRUint8 *x_j)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-/*
- * Specialized RNG for DSA
- *
- * As per Algorithm 1 of FIPS 186-2 Change Notice 1, in step 3.3 the value
- * Xj should be reduced mod q, a 160-bit prime number. Since this parameter
- * is only meaningful in the context of DSA, the above RNG functions
- * were implemented without it. They are re-implemented below for use
- * with DSA.
- */
-
-/*
-** Generate some random bytes, using the global random number generator
-** object. In DSA mode, so there is a q.
-*/
-static SECStatus
-dsa_GenerateGlobalRandomBytes(const SECItem * qItem, PRUint8 * dest,
- unsigned int * destLen, unsigned int maxDestLen)
-{
- SECStatus rv;
- SECItem w;
- const PRUint8 * q = qItem->data;
- unsigned int qLen = qItem->len;
-
- if (*q == 0) {
- ++q;
- --qLen;
- }
- if (maxDestLen < qLen) {
- /* This condition can occur when DSA_SignDigest is passed a group
- with a subprime that is larger than DSA_MAX_SUBPRIME_LEN. */
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- w.data = NULL; /* otherwise SECITEM_AllocItem asserts */
- if (!SECITEM_AllocItem(NULL, &w, 2*qLen)) {
- return SECFailure;
- }
- *destLen = qLen;
-
- rv = RNG_GenerateGlobalRandomBytes(w.data, w.len);
- if (rv == SECSuccess) {
- rv = fips186Change_ReduceModQForDSA(w.data, q, qLen, dest);
- }
-
- SECITEM_FreeItem(&w, PR_FALSE);
- return rv;
-}
-
-static void translate_mpi_error(mp_err err)
-{
- MP_TO_SEC_ERROR(err);
-}
-
-static SECStatus
-dsa_NewKeyExtended(const PQGParams *params, const SECItem * seed,
- DSAPrivateKey **privKey)
-{
- mp_int p, g;
- mp_int x, y;
- mp_err err;
- PRArenaPool *arena;
- DSAPrivateKey *key;
- /* Check args. */
- if (!params || !privKey || !seed || !seed->data) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* Initialize an arena for the DSA key. */
- arena = PORT_NewArena(NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE);
- if (!arena) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
- if (!key) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
- }
- key->params.arena = arena;
- /* Initialize MPI integers. */
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&g) = 0;
- MP_DIGITS(&x) = 0;
- MP_DIGITS(&y) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&g) );
- CHECK_MPI_OK( mp_init(&x) );
- CHECK_MPI_OK( mp_init(&y) );
- /* Copy over the PQG params */
- CHECK_MPI_OK( SECITEM_CopyItem(arena, &key->params.prime,
- &params->prime) );
- CHECK_MPI_OK( SECITEM_CopyItem(arena, &key->params.subPrime,
- &params->subPrime) );
- CHECK_MPI_OK( SECITEM_CopyItem(arena, &key->params.base, &params->base) );
- /* Convert stored p, g, and received x into MPI integers. */
- SECITEM_TO_MPINT(params->prime, &p);
- SECITEM_TO_MPINT(params->base, &g);
- OCTETS_TO_MPINT(seed->data, &x, seed->len);
- /* Store x in private key */
- SECITEM_AllocItem(arena, &key->privateValue, seed->len);
- PORT_Memcpy(key->privateValue.data, seed->data, seed->len);
- /* Compute public key y = g**x mod p */
- CHECK_MPI_OK( mp_exptmod(&g, &x, &p, &y) );
- /* Store y in public key */
- MPINT_TO_SECITEM(&y, &key->publicValue, arena);
- *privKey = key;
- key = NULL;
-cleanup:
- mp_clear(&p);
- mp_clear(&g);
- mp_clear(&x);
- mp_clear(&y);
- if (key)
- PORT_FreeArena(key->params.arena, PR_TRUE);
- if (err) {
- translate_mpi_error(err);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-DSA_NewRandom(PLArenaPool * arena, const SECItem * q, SECItem * seed)
-{
- int retries = 10;
- unsigned int i;
- PRBool good;
-
- if (q == NULL || q->data == NULL || q->len == 0 ||
- (q->data[0] == 0 && q->len == 1)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (!SECITEM_AllocItem(arena, seed, q->len)) {
- return SECFailure;
- }
-
- do {
- /* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
- if (dsa_GenerateGlobalRandomBytes(q, seed->data, &seed->len,
- seed->len)) {
- goto loser;
- }
- /* Disallow values of 0 and 1 for x. */
- good = PR_FALSE;
- for (i = 0; i < seed->len-1; i++) {
- if (seed->data[i] != 0) {
- good = PR_TRUE;
- break;
- }
- }
- if (!good && seed->data[i] > 1) {
- good = PR_TRUE;
- }
- } while (!good && --retries > 0);
-
- if (!good) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
-loser: if (arena != NULL) {
- SECITEM_FreeItem(seed, PR_FALSE);
- }
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-/*
-** Generate and return a new DSA public and private key pair,
-** both of which are encoded into a single DSAPrivateKey struct.
-** "params" is a pointer to the PQG parameters for the domain
-** Uses a random seed.
-*/
-SECStatus
-DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
-{
- SECItem seed;
- SECStatus rv;
-
- rv = PQG_Check(params);
- if (rv != SECSuccess) {
- return rv;
- }
- seed.data = NULL;
-
- rv = DSA_NewRandom(NULL, &params->subPrime, &seed);
- if (rv == SECSuccess) {
- if (seed.len != PQG_GetLength(&params->subPrime)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- } else {
- rv = dsa_NewKeyExtended(params, &seed, privKey);
- }
- }
- SECITEM_FreeItem(&seed, PR_FALSE);
- return rv;
-}
-
-/* For FIPS compliance testing. Seed must be exactly the size of subPrime */
-SECStatus
-DSA_NewKeyFromSeed(const PQGParams *params,
- const unsigned char *seed,
- DSAPrivateKey **privKey)
-{
- SECItem seedItem;
- seedItem.data = (unsigned char*) seed;
- seedItem.len = PQG_GetLength(&params->subPrime);
- return dsa_NewKeyExtended(params, &seedItem, privKey);
-}
-
-static SECStatus
-dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
- const unsigned char *kb)
-{
- mp_int p, q, g; /* PQG parameters */
- mp_int x, k; /* private key & pseudo-random integer */
- mp_int r, s; /* tuple (r, s) is signature) */
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- unsigned int dsa_subprime_len, dsa_signature_len, offset;
- SECItem localDigest;
- unsigned char localDigestData[DSA_MAX_SUBPRIME_LEN];
-
-
- /* FIPS-compliance dictates that digest is a SHA hash. */
- /* Check args. */
- if (!key || !signature || !digest) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
- dsa_signature_len = dsa_subprime_len*2;
- if ((signature->len < dsa_signature_len) ||
- (digest->len > HASH_LENGTH_MAX) ||
- (digest->len < SHA1_LENGTH)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* DSA accepts digests not equal to dsa_subprime_len, if the
- * digests are greater, then they are truncated to the size of
- * dsa_subprime_len, using the left most bits. If they are less
- * then they are padded on the left.*/
- PORT_Memset(localDigestData, 0, dsa_subprime_len);
- offset = (digest->len < dsa_subprime_len) ?
- (dsa_subprime_len - digest->len) : 0;
- PORT_Memcpy(localDigestData+offset, digest->data,
- dsa_subprime_len - offset);
- localDigest.data = localDigestData;
- localDigest.len = dsa_subprime_len;
-
- /* Initialize MPI integers. */
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&g) = 0;
- MP_DIGITS(&x) = 0;
- MP_DIGITS(&k) = 0;
- MP_DIGITS(&r) = 0;
- MP_DIGITS(&s) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&g) );
- CHECK_MPI_OK( mp_init(&x) );
- CHECK_MPI_OK( mp_init(&k) );
- CHECK_MPI_OK( mp_init(&r) );
- CHECK_MPI_OK( mp_init(&s) );
- /*
- ** Convert stored PQG and private key into MPI integers.
- */
- SECITEM_TO_MPINT(key->params.prime, &p);
- SECITEM_TO_MPINT(key->params.subPrime, &q);
- SECITEM_TO_MPINT(key->params.base, &g);
- SECITEM_TO_MPINT(key->privateValue, &x);
- OCTETS_TO_MPINT(kb, &k, dsa_subprime_len);
- /*
- ** FIPS 186-1, Section 5, Step 1
- **
- ** r = (g**k mod p) mod q
- */
- CHECK_MPI_OK( mp_exptmod(&g, &k, &p, &r) ); /* r = g**k mod p */
- CHECK_MPI_OK( mp_mod(&r, &q, &r) ); /* r = r mod q */
- /*
- ** FIPS 186-1, Section 5, Step 2
- **
- ** s = (k**-1 * (HASH(M) + x*r)) mod q
- */
- SECITEM_TO_MPINT(localDigest, &s); /* s = HASH(M) */
- CHECK_MPI_OK( mp_invmod(&k, &q, &k) ); /* k = k**-1 mod q */
- CHECK_MPI_OK( mp_mulmod(&x, &r, &q, &x) ); /* x = x * r mod q */
- CHECK_MPI_OK( mp_addmod(&s, &x, &q, &s) ); /* s = s + x mod q */
- CHECK_MPI_OK( mp_mulmod(&s, &k, &q, &s) ); /* s = s * k mod q */
- /*
- ** verify r != 0 and s != 0
- ** mentioned as optional in FIPS 186-1.
- */
- if (mp_cmp_z(&r) == 0 || mp_cmp_z(&s) == 0) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- rv = SECFailure;
- goto cleanup;
- }
- /*
- ** Step 4
- **
- ** Signature is tuple (r, s)
- */
- err = mp_to_fixlen_octets(&r, signature->data, dsa_subprime_len);
- if (err < 0) goto cleanup;
- err = mp_to_fixlen_octets(&s, signature->data + dsa_subprime_len,
- dsa_subprime_len);
- if (err < 0) goto cleanup;
- err = MP_OKAY;
- signature->len = dsa_signature_len;
-cleanup:
- PORT_Memset(localDigestData, 0, DSA_MAX_SUBPRIME_LEN);
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&g);
- mp_clear(&x);
- mp_clear(&k);
- mp_clear(&r);
- mp_clear(&s);
- if (err) {
- translate_mpi_error(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/* signature is caller-supplied buffer of at least 40 bytes.
-** On input, signature->len == size of buffer to hold signature.
-** digest->len == size of digest.
-** On output, signature->len == size of signature in buffer.
-** Uses a random seed.
-*/
-SECStatus
-DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
-{
- SECStatus rv;
- int retries = 10;
- unsigned char kSeed[DSA_MAX_SUBPRIME_LEN];
- unsigned int kSeedLen = 0;
- unsigned int i;
- unsigned int dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
- PRBool good;
-
- PORT_SetError(0);
- do {
- rv = dsa_GenerateGlobalRandomBytes(&key->params.subPrime,
- kSeed, &kSeedLen, sizeof kSeed);
- if (rv != SECSuccess)
- break;
- if (kSeedLen != dsa_subprime_len) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- break;
- }
- /* Disallow a value of 0 for k. */
- good = PR_FALSE;
- for (i = 0; i < kSeedLen; i++) {
- if (kSeed[i] != 0) {
- good = PR_TRUE;
- break;
- }
- }
- if (!good) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- rv = SECFailure;
- continue;
- }
- rv = dsa_SignDigest(key, signature, digest, kSeed);
- } while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
- --retries > 0);
- return rv;
-}
-
-/* For FIPS compliance testing. Seed must be exactly 20 bytes. */
-SECStatus
-DSA_SignDigestWithSeed(DSAPrivateKey * key,
- SECItem * signature,
- const SECItem * digest,
- const unsigned char * seed)
-{
- SECStatus rv;
- rv = dsa_SignDigest(key, signature, digest, seed);
- return rv;
-}
-
-/* signature is caller-supplied buffer of at least 20 bytes.
-** On input, signature->len == size of buffer to hold signature.
-** digest->len == size of digest.
-*/
-SECStatus
-DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
- const SECItem *digest)
-{
- /* FIPS-compliance dictates that digest is a SHA hash. */
- mp_int p, q, g; /* PQG parameters */
- mp_int r_, s_; /* tuple (r', s') is received signature) */
- mp_int u1, u2, v, w; /* intermediate values used in verification */
- mp_int y; /* public key */
- mp_err err;
- int dsa_subprime_len, dsa_signature_len, offset;
- SECItem localDigest;
- unsigned char localDigestData[DSA_MAX_SUBPRIME_LEN];
- SECStatus verified = SECFailure;
-
- /* Check args. */
- if (!key || !signature || !digest ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
- dsa_signature_len = dsa_subprime_len*2;
- if ((signature->len != dsa_signature_len) ||
- (digest->len > HASH_LENGTH_MAX) ||
- (digest->len < SHA1_LENGTH)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* DSA accepts digests not equal to dsa_subprime_len, if the
- * digests are greater, than they are truncated to the size of
- * dsa_subprime_len, using the left most bits. If they are less
- * then they are padded on the left.*/
- PORT_Memset(localDigestData, 0, dsa_subprime_len);
- offset = (digest->len < dsa_subprime_len) ?
- (dsa_subprime_len - digest->len) : 0;
- PORT_Memcpy(localDigestData+offset, digest->data,
- dsa_subprime_len - offset);
- localDigest.data = localDigestData;
- localDigest.len = dsa_subprime_len;
-
- /* Initialize MPI integers. */
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&g) = 0;
- MP_DIGITS(&y) = 0;
- MP_DIGITS(&r_) = 0;
- MP_DIGITS(&s_) = 0;
- MP_DIGITS(&u1) = 0;
- MP_DIGITS(&u2) = 0;
- MP_DIGITS(&v) = 0;
- MP_DIGITS(&w) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&g) );
- CHECK_MPI_OK( mp_init(&y) );
- CHECK_MPI_OK( mp_init(&r_) );
- CHECK_MPI_OK( mp_init(&s_) );
- CHECK_MPI_OK( mp_init(&u1) );
- CHECK_MPI_OK( mp_init(&u2) );
- CHECK_MPI_OK( mp_init(&v) );
- CHECK_MPI_OK( mp_init(&w) );
- /*
- ** Convert stored PQG and public key into MPI integers.
- */
- SECITEM_TO_MPINT(key->params.prime, &p);
- SECITEM_TO_MPINT(key->params.subPrime, &q);
- SECITEM_TO_MPINT(key->params.base, &g);
- SECITEM_TO_MPINT(key->publicValue, &y);
- /*
- ** Convert received signature (r', s') into MPI integers.
- */
- OCTETS_TO_MPINT(signature->data, &r_, dsa_subprime_len);
- OCTETS_TO_MPINT(signature->data + dsa_subprime_len, &s_, dsa_subprime_len);
- /*
- ** Verify that 0 < r' < q and 0 < s' < q
- */
- if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
- mp_cmp(&r_, &q) >= 0 || mp_cmp(&s_, &q) >= 0) {
- /* err is zero here. */
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- goto cleanup; /* will return verified == SECFailure */
- }
- /*
- ** FIPS 186-1, Section 6, Step 1
- **
- ** w = (s')**-1 mod q
- */
- CHECK_MPI_OK( mp_invmod(&s_, &q, &w) ); /* w = (s')**-1 mod q */
- /*
- ** FIPS 186-1, Section 6, Step 2
- **
- ** u1 = ((Hash(M')) * w) mod q
- */
- SECITEM_TO_MPINT(localDigest, &u1); /* u1 = HASH(M') */
- CHECK_MPI_OK( mp_mulmod(&u1, &w, &q, &u1) ); /* u1 = u1 * w mod q */
- /*
- ** FIPS 186-1, Section 6, Step 3
- **
- ** u2 = ((r') * w) mod q
- */
- CHECK_MPI_OK( mp_mulmod(&r_, &w, &q, &u2) );
- /*
- ** FIPS 186-1, Section 6, Step 4
- **
- ** v = ((g**u1 * y**u2) mod p) mod q
- */
- CHECK_MPI_OK( mp_exptmod(&g, &u1, &p, &g) ); /* g = g**u1 mod p */
- CHECK_MPI_OK( mp_exptmod(&y, &u2, &p, &y) ); /* y = y**u2 mod p */
- CHECK_MPI_OK( mp_mulmod(&g, &y, &p, &v) ); /* v = g * y mod p */
- CHECK_MPI_OK( mp_mod(&v, &q, &v) ); /* v = v mod q */
- /*
- ** Verification: v == r'
- */
- if (mp_cmp(&v, &r_)) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- verified = SECFailure; /* Signature failed to verify. */
- } else {
- verified = SECSuccess; /* Signature verified. */
- }
-cleanup:
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&g);
- mp_clear(&y);
- mp_clear(&r_);
- mp_clear(&s_);
- mp_clear(&u1);
- mp_clear(&u2);
- mp_clear(&v);
- mp_clear(&w);
- if (err) {
- translate_mpi_error(err);
- }
- return verified;
-}
diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c
deleted file mode 100644
index e1d1ac74c..000000000
--- a/security/nss/lib/freebl/ec.c
+++ /dev/null
@@ -1,1080 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-
-#include "blapi.h"
-#include "prerr.h"
-#include "secerr.h"
-#include "secmpi.h"
-#include "secitem.h"
-#include "mplogic.h"
-#include "ec.h"
-#include "ecl.h"
-
-#ifdef NSS_ENABLE_ECC
-
-/*
- * Returns true if pointP is the point at infinity, false otherwise
- */
-PRBool
-ec_point_at_infinity(SECItem *pointP)
-{
- unsigned int i;
-
- for (i = 1; i < pointP->len; i++) {
- if (pointP->data[i] != 0x00) return PR_FALSE;
- }
-
- return PR_TRUE;
-}
-
-/*
- * Computes scalar point multiplication pointQ = k1 * G + k2 * pointP for
- * the curve whose parameters are encoded in params with base point G.
- */
-SECStatus
-ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
- const SECItem *pointP, SECItem *pointQ)
-{
- mp_int Px, Py, Qx, Qy;
- mp_int Gx, Gy, order, irreducible, a, b;
-#if 0 /* currently don't support non-named curves */
- unsigned int irr_arr[5];
-#endif
- ECGroup *group = NULL;
- SECStatus rv = SECFailure;
- mp_err err = MP_OKAY;
- int len;
-
-#if EC_DEBUG
- int i;
- char mpstr[256];
-
- printf("ec_points_mul: params [len=%d]:", params->DEREncoding.len);
- for (i = 0; i < params->DEREncoding.len; i++)
- printf("%02x:", params->DEREncoding.data[i]);
- printf("\n");
-
- if (k1 != NULL) {
- mp_tohex(k1, mpstr);
- printf("ec_points_mul: scalar k1: %s\n", mpstr);
- mp_todecimal(k1, mpstr);
- printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
- }
-
- if (k2 != NULL) {
- mp_tohex(k2, mpstr);
- printf("ec_points_mul: scalar k2: %s\n", mpstr);
- mp_todecimal(k2, mpstr);
- printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
- }
-
- if (pointP != NULL) {
- printf("ec_points_mul: pointP [len=%d]:", pointP->len);
- for (i = 0; i < pointP->len; i++)
- printf("%02x:", pointP->data[i]);
- printf("\n");
- }
-#endif
-
- /* NOTE: We only support uncompressed points for now */
- len = (params->fieldID.size + 7) >> 3;
- if (pointP != NULL) {
- if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
- (pointP->len != (2 * len + 1))) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
- return SECFailure;
- };
- }
-
- MP_DIGITS(&Px) = 0;
- MP_DIGITS(&Py) = 0;
- MP_DIGITS(&Qx) = 0;
- MP_DIGITS(&Qy) = 0;
- MP_DIGITS(&Gx) = 0;
- MP_DIGITS(&Gy) = 0;
- MP_DIGITS(&order) = 0;
- MP_DIGITS(&irreducible) = 0;
- MP_DIGITS(&a) = 0;
- MP_DIGITS(&b) = 0;
- CHECK_MPI_OK( mp_init(&Px) );
- CHECK_MPI_OK( mp_init(&Py) );
- CHECK_MPI_OK( mp_init(&Qx) );
- CHECK_MPI_OK( mp_init(&Qy) );
- CHECK_MPI_OK( mp_init(&Gx) );
- CHECK_MPI_OK( mp_init(&Gy) );
- CHECK_MPI_OK( mp_init(&order) );
- CHECK_MPI_OK( mp_init(&irreducible) );
- CHECK_MPI_OK( mp_init(&a) );
- CHECK_MPI_OK( mp_init(&b) );
-
- if ((k2 != NULL) && (pointP != NULL)) {
- /* Initialize Px and Py */
- CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1, (mp_size) len) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len, (mp_size) len) );
- }
-
- /* construct from named params, if possible */
- if (params->name != ECCurve_noName) {
- group = ECGroup_fromName(params->name);
- }
-
-#if 0 /* currently don't support non-named curves */
- if (group == NULL) {
- /* Set up mp_ints containing the curve coefficients */
- CHECK_MPI_OK( mp_read_unsigned_octets(&Gx, params->base.data + 1,
- (mp_size) len) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&Gy, params->base.data + 1 + len,
- (mp_size) len) );
- SECITEM_TO_MPINT( params->order, &order );
- SECITEM_TO_MPINT( params->curve.a, &a );
- SECITEM_TO_MPINT( params->curve.b, &b );
- if (params->fieldID.type == ec_field_GFp) {
- SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible );
- group = ECGroup_consGFp(&irreducible, &a, &b, &Gx, &Gy, &order, params->cofactor);
- } else {
- SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible );
- irr_arr[0] = params->fieldID.size;
- irr_arr[1] = params->fieldID.k1;
- irr_arr[2] = params->fieldID.k2;
- irr_arr[3] = params->fieldID.k3;
- irr_arr[4] = 0;
- group = ECGroup_consGF2m(&irreducible, irr_arr, &a, &b, &Gx, &Gy, &order, params->cofactor);
- }
- }
-#endif
- if (group == NULL)
- goto cleanup;
-
- if ((k2 != NULL) && (pointP != NULL)) {
- CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy) );
- } else {
- CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy) );
- }
-
- /* Construct the SECItem representation of point Q */
- pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
- CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
- (mp_size) len) );
- CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
- (mp_size) len) );
-
- rv = SECSuccess;
-
-#if EC_DEBUG
- printf("ec_points_mul: pointQ [len=%d]:", pointQ->len);
- for (i = 0; i < pointQ->len; i++)
- printf("%02x:", pointQ->data[i]);
- printf("\n");
-#endif
-
-cleanup:
- ECGroup_free(group);
- mp_clear(&Px);
- mp_clear(&Py);
- mp_clear(&Qx);
- mp_clear(&Qy);
- mp_clear(&Gx);
- mp_clear(&Gy);
- mp_clear(&order);
- mp_clear(&irreducible);
- mp_clear(&a);
- mp_clear(&b);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
-
- return rv;
-}
-#endif /* NSS_ENABLE_ECC */
-
-/* Generates a new EC key pair. The private key is a supplied
- * value and the public key is the result of performing a scalar
- * point multiplication of that value with the curve's base point.
- */
-SECStatus
-ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
- const unsigned char *privKeyBytes, int privKeyLen)
-{
- SECStatus rv = SECFailure;
-#ifdef NSS_ENABLE_ECC
- PRArenaPool *arena;
- ECPrivateKey *key;
- mp_int k;
- mp_err err = MP_OKAY;
- int len;
-
-#if EC_DEBUG
- printf("ec_NewKey called\n");
-#endif
- MP_DIGITS(&k) = 0;
-
- if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* Initialize an arena for the EC key. */
- if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
- return SECFailure;
-
- key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
- if (!key) {
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
- }
-
- /* Set the version number (SEC 1 section C.4 says it should be 1) */
- SECITEM_AllocItem(arena, &key->version, 1);
- key->version.data[0] = 1;
-
- /* Copy all of the fields from the ECParams argument to the
- * ECParams structure within the private key.
- */
- key->ecParams.arena = arena;
- key->ecParams.type = ecParams->type;
- key->ecParams.fieldID.size = ecParams->fieldID.size;
- key->ecParams.fieldID.type = ecParams->fieldID.type;
- if (ecParams->fieldID.type == ec_field_GFp) {
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime,
- &ecParams->fieldID.u.prime));
- } else {
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.poly,
- &ecParams->fieldID.u.poly));
- }
- key->ecParams.fieldID.k1 = ecParams->fieldID.k1;
- key->ecParams.fieldID.k2 = ecParams->fieldID.k2;
- key->ecParams.fieldID.k3 = ecParams->fieldID.k3;
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.a,
- &ecParams->curve.a));
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b,
- &ecParams->curve.b));
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed,
- &ecParams->curve.seed));
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base,
- &ecParams->base));
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order,
- &ecParams->order));
- key->ecParams.cofactor = ecParams->cofactor;
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
- &ecParams->DEREncoding));
- key->ecParams.name = ecParams->name;
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID,
- &ecParams->curveOID));
-
- len = (ecParams->fieldID.size + 7) >> 3;
- SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1);
- len = ecParams->order.len;
- SECITEM_AllocItem(arena, &key->privateValue, len);
-
- /* Copy private key */
- if (privKeyLen >= len) {
- memcpy(key->privateValue.data, privKeyBytes, len);
- } else {
- memset(key->privateValue.data, 0, (len - privKeyLen));
- memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen);
- }
-
- /* Compute corresponding public key */
- CHECK_MPI_OK( mp_init(&k) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data,
- (mp_size) len) );
-
- rv = ec_points_mul(ecParams, &k, NULL, NULL, &(key->publicValue));
- if (rv != SECSuccess) goto cleanup;
- *privKey = key;
-
-cleanup:
- mp_clear(&k);
- if (rv)
- PORT_FreeArena(arena, PR_TRUE);
-
-#if EC_DEBUG
- printf("ec_NewKey returning %s\n",
- (rv == SECSuccess) ? "success" : "failure");
-#endif
-#else
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
-#endif /* NSS_ENABLE_ECC */
-
- return rv;
-
-}
-
-/* Generates a new EC key pair. The private key is a supplied
- * random value (in seed) and the public key is the result of
- * performing a scalar point multiplication of that value with
- * the curve's base point.
- */
-SECStatus
-EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
- const unsigned char *seed, int seedlen)
-{
- SECStatus rv = SECFailure;
-#ifdef NSS_ENABLE_ECC
- rv = ec_NewKey(ecParams, privKey, seed, seedlen);
-#else
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
-#endif /* NSS_ENABLE_ECC */
- return rv;
-}
-
-#ifdef NSS_ENABLE_ECC
-/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62,
- * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the
- * random number generator.
- *
- * Parameters
- * - order: a buffer that holds the curve's group order
- * - len: the length in octets of the order buffer
- *
- * Return Value
- * Returns a buffer of len octets that holds the private key. The caller
- * is responsible for freeing the buffer with PORT_ZFree.
- */
-static unsigned char *
-ec_GenerateRandomPrivateKey(const unsigned char *order, int len)
-{
- SECStatus rv = SECSuccess;
- mp_err err;
- unsigned char *privKeyBytes = NULL;
- mp_int privKeyVal, order_1, one;
-
- MP_DIGITS(&privKeyVal) = 0;
- MP_DIGITS(&order_1) = 0;
- MP_DIGITS(&one) = 0;
- CHECK_MPI_OK( mp_init(&privKeyVal) );
- CHECK_MPI_OK( mp_init(&order_1) );
- CHECK_MPI_OK( mp_init(&one) );
-
- /* Generates 2*len random bytes using the global random bit generator
- * (which implements Algorithm 1 of FIPS 186-2 Change Notice 1) then
- * reduces modulo the group order.
- */
- if ((privKeyBytes = PORT_Alloc(2*len)) == NULL) goto cleanup;
- CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) );
- CHECK_MPI_OK( mp_set_int(&one, 1) );
- CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) );
- CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) );
- CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) );
- CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) );
- memset(privKeyBytes+len, 0, len);
-cleanup:
- mp_clear(&privKeyVal);
- mp_clear(&order_1);
- mp_clear(&one);
- if (err < MP_OKAY) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- if (rv != SECSuccess && privKeyBytes) {
- PORT_Free(privKeyBytes);
- privKeyBytes = NULL;
- }
- return privKeyBytes;
-}
-#endif /* NSS_ENABLE_ECC */
-
-/* Generates a new EC key pair. The private key is a random value and
- * the public key is the result of performing a scalar point multiplication
- * of that value with the curve's base point.
- */
-SECStatus
-EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey)
-{
- SECStatus rv = SECFailure;
-#ifdef NSS_ENABLE_ECC
- int len;
- unsigned char *privKeyBytes = NULL;
-
- if (!ecParams) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- len = ecParams->order.len;
- privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len);
- if (privKeyBytes == NULL) goto cleanup;
- /* generate public key */
- CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len) );
-
-cleanup:
- if (privKeyBytes) {
- PORT_ZFree(privKeyBytes, len);
- }
-#if EC_DEBUG
- printf("EC_NewKey returning %s\n",
- (rv == SECSuccess) ? "success" : "failure");
-#endif
-#else
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
-#endif /* NSS_ENABLE_ECC */
-
- return rv;
-}
-
-/* Validates an EC public key as described in Section 5.2.2 of
- * X9.62. The ECDH primitive when used without the cofactor does
- * not address small subgroup attacks, which may occur when the
- * public key is not valid. These attacks can be prevented by
- * validating the public key before using ECDH.
- */
-SECStatus
-EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
-{
-#ifdef NSS_ENABLE_ECC
- mp_int Px, Py;
- ECGroup *group = NULL;
- SECStatus rv = SECFailure;
- mp_err err = MP_OKAY;
- int len;
-
- if (!ecParams || !publicValue) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* NOTE: We only support uncompressed points for now */
- len = (ecParams->fieldID.size + 7) >> 3;
- if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
- return SECFailure;
- } else if (publicValue->len != (2 * len + 1)) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- return SECFailure;
- }
-
- MP_DIGITS(&Px) = 0;
- MP_DIGITS(&Py) = 0;
- CHECK_MPI_OK( mp_init(&Px) );
- CHECK_MPI_OK( mp_init(&Py) );
-
- /* Initialize Px and Py */
- CHECK_MPI_OK( mp_read_unsigned_octets(&Px, publicValue->data + 1, (mp_size) len) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&Py, publicValue->data + 1 + len, (mp_size) len) );
-
- /* construct from named params */
- group = ECGroup_fromName(ecParams->name);
- if (group == NULL) {
- /*
- * ECGroup_fromName fails if ecParams->name is not a valid
- * ECCurveName value, or if we run out of memory, or perhaps
- * for other reasons. Unfortunately if ecParams->name is a
- * valid ECCurveName value, we don't know what the right error
- * code should be because ECGroup_fromName doesn't return an
- * error code to the caller. Set err to MP_UNDEF because
- * that's what ECGroup_fromName uses internally.
- */
- if ((ecParams->name <= ECCurve_noName) ||
- (ecParams->name >= ECCurve_pastLastCurve)) {
- err = MP_BADARG;
- } else {
- err = MP_UNDEF;
- }
- goto cleanup;
- }
-
- /* validate public point */
- if ((err = ECPoint_validate(group, &Px, &Py)) < MP_YES) {
- if (err == MP_NO) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- rv = SECFailure;
- err = MP_OKAY; /* don't change the error code */
- }
- goto cleanup;
- }
-
- rv = SECSuccess;
-
-cleanup:
- ECGroup_free(group);
- mp_clear(&Px);
- mp_clear(&Py);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-#else
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
-#endif /* NSS_ENABLE_ECC */
-}
-
-/*
-** Performs an ECDH key derivation by computing the scalar point
-** multiplication of privateValue and publicValue (with or without the
-** cofactor) and returns the x-coordinate of the resulting elliptic
-** curve point in derived secret. If successful, derivedSecret->data
-** is set to the address of the newly allocated buffer containing the
-** derived secret, and derivedSecret->len is the size of the secret
-** produced. It is the caller's responsibility to free the allocated
-** buffer containing the derived secret.
-*/
-SECStatus
-ECDH_Derive(SECItem *publicValue,
- ECParams *ecParams,
- SECItem *privateValue,
- PRBool withCofactor,
- SECItem *derivedSecret)
-{
- SECStatus rv = SECFailure;
-#ifdef NSS_ENABLE_ECC
- unsigned int len = 0;
- SECItem pointQ = {siBuffer, NULL, 0};
- mp_int k; /* to hold the private value */
- mp_int cofactor;
- mp_err err = MP_OKAY;
-#if EC_DEBUG
- int i;
-#endif
-
- if (!publicValue || !ecParams || !privateValue ||
- !derivedSecret) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- MP_DIGITS(&k) = 0;
- memset(derivedSecret, 0, sizeof *derivedSecret);
- len = (ecParams->fieldID.size + 7) >> 3;
- pointQ.len = 2*len + 1;
- if ((pointQ.data = PORT_Alloc(2*len + 1)) == NULL) goto cleanup;
-
- CHECK_MPI_OK( mp_init(&k) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data,
- (mp_size) privateValue->len) );
-
- if (withCofactor && (ecParams->cofactor != 1)) {
- /* multiply k with the cofactor */
- MP_DIGITS(&cofactor) = 0;
- CHECK_MPI_OK( mp_init(&cofactor) );
- mp_set(&cofactor, ecParams->cofactor);
- CHECK_MPI_OK( mp_mul(&k, &cofactor, &k) );
- }
-
- /* Multiply our private key and peer's public point */
- if (ec_points_mul(ecParams, NULL, &k, publicValue, &pointQ) != SECSuccess)
- goto cleanup;
- if (ec_point_at_infinity(&pointQ)) {
- PORT_SetError(SEC_ERROR_BAD_KEY); /* XXX better error code? */
- goto cleanup;
- }
-
- /* Allocate memory for the derived secret and copy
- * the x co-ordinate of pointQ into it.
- */
- SECITEM_AllocItem(NULL, derivedSecret, len);
- memcpy(derivedSecret->data, pointQ.data + 1, len);
-
- rv = SECSuccess;
-
-#if EC_DEBUG
- printf("derived_secret:\n");
- for (i = 0; i < derivedSecret->len; i++)
- printf("%02x:", derivedSecret->data[i]);
- printf("\n");
-#endif
-
-cleanup:
- mp_clear(&k);
-
- if (err) {
- MP_TO_SEC_ERROR(err);
- }
-
- if (pointQ.data) {
- PORT_ZFree(pointQ.data, 2*len + 1);
- }
-#else
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
-#endif /* NSS_ENABLE_ECC */
-
- return rv;
-}
-
-/* Computes the ECDSA signature (a concatenation of two values r and s)
- * on the digest using the given key and the random value kb (used in
- * computing s).
- */
-SECStatus
-ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
- const SECItem *digest, const unsigned char *kb, const int kblen)
-{
- SECStatus rv = SECFailure;
-#ifdef NSS_ENABLE_ECC
- mp_int x1;
- mp_int d, k; /* private key, random integer */
- mp_int r, s; /* tuple (r, s) is the signature */
- mp_int n;
- mp_err err = MP_OKAY;
- ECParams *ecParams = NULL;
- SECItem kGpoint = { siBuffer, NULL, 0};
- int flen = 0; /* length in bytes of the field size */
- unsigned olen; /* length in bytes of the base point order */
- unsigned obits; /* length in bits of the base point order */
-
-#if EC_DEBUG
- char mpstr[256];
-#endif
-
- /* Initialize MPI integers. */
- /* must happen before the first potential call to cleanup */
- MP_DIGITS(&x1) = 0;
- MP_DIGITS(&d) = 0;
- MP_DIGITS(&k) = 0;
- MP_DIGITS(&r) = 0;
- MP_DIGITS(&s) = 0;
- MP_DIGITS(&n) = 0;
-
- /* Check args */
- if (!key || !signature || !digest || !kb || (kblen < 0)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
-
- ecParams = &(key->ecParams);
- flen = (ecParams->fieldID.size + 7) >> 3;
- olen = ecParams->order.len;
- if (signature->data == NULL) {
- /* a call to get the signature length only */
- goto finish;
- }
- if (signature->len < 2*olen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- goto cleanup;
- }
-
-
- CHECK_MPI_OK( mp_init(&x1) );
- CHECK_MPI_OK( mp_init(&d) );
- CHECK_MPI_OK( mp_init(&k) );
- CHECK_MPI_OK( mp_init(&r) );
- CHECK_MPI_OK( mp_init(&s) );
- CHECK_MPI_OK( mp_init(&n) );
-
- SECITEM_TO_MPINT( ecParams->order, &n );
- SECITEM_TO_MPINT( key->privateValue, &d );
-
- CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) );
- /* Make sure k is in the interval [1, n-1] */
- if ((mp_cmp_z(&k) <= 0) || (mp_cmp(&k, &n) >= 0)) {
-#if EC_DEBUG
- printf("k is outside [1, n-1]\n");
- mp_tohex(&k, mpstr);
- printf("k : %s \n", mpstr);
- mp_tohex(&n, mpstr);
- printf("n : %s \n", mpstr);
-#endif
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- goto cleanup;
- }
-
- /*
- ** We do not want timing information to leak the length of k,
- ** so we compute k*G using an equivalent scalar of fixed
- ** bit-length.
- ** Fix based on patch for ECDSA timing attack in the paper
- ** by Billy Bob Brumley and Nicola Tuveri at
- ** http://eprint.iacr.org/2011/232
- **
- ** How do we convert k to a value of a fixed bit-length?
- ** k starts off as an integer satisfying 0 <= k < n. Hence,
- ** n <= k+n < 2n, which means k+n has either the same number
- ** of bits as n or one more bit than n. If k+n has the same
- ** number of bits as n, the second addition ensures that the
- ** final value has exactly one more bit than n. Thus, we
- ** always end up with a value that exactly one more bit than n.
- */
- CHECK_MPI_OK( mp_add(&k, &n, &k) );
- if (mpl_significant_bits(&k) <= mpl_significant_bits(&n)) {
- CHECK_MPI_OK( mp_add(&k, &n, &k) );
- }
-
- /*
- ** ANSI X9.62, Section 5.3.2, Step 2
- **
- ** Compute kG
- */
- kGpoint.len = 2*flen + 1;
- kGpoint.data = PORT_Alloc(2*flen + 1);
- if ((kGpoint.data == NULL) ||
- (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint)
- != SECSuccess))
- goto cleanup;
-
- /*
- ** ANSI X9.62, Section 5.3.3, Step 1
- **
- ** Extract the x co-ordinate of kG into x1
- */
- CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1,
- (mp_size) flen) );
-
- /*
- ** ANSI X9.62, Section 5.3.3, Step 2
- **
- ** r = x1 mod n NOTE: n is the order of the curve
- */
- CHECK_MPI_OK( mp_mod(&x1, &n, &r) );
-
- /*
- ** ANSI X9.62, Section 5.3.3, Step 3
- **
- ** verify r != 0
- */
- if (mp_cmp_z(&r) == 0) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- goto cleanup;
- }
-
- /*
- ** ANSI X9.62, Section 5.3.3, Step 4
- **
- ** s = (k**-1 * (HASH(M) + d*r)) mod n
- */
- SECITEM_TO_MPINT(*digest, &s); /* s = HASH(M) */
-
- /* In the definition of EC signing, digests are truncated
- * to the length of n in bits.
- * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
- CHECK_MPI_OK( (obits = mpl_significant_bits(&n)) );
- if (digest->len*8 > obits) {
- mpl_rsh(&s,&s,digest->len*8 - obits);
- }
-
-#if EC_DEBUG
- mp_todecimal(&n, mpstr);
- printf("n : %s (dec)\n", mpstr);
- mp_todecimal(&d, mpstr);
- printf("d : %s (dec)\n", mpstr);
- mp_tohex(&x1, mpstr);
- printf("x1: %s\n", mpstr);
- mp_todecimal(&s, mpstr);
- printf("digest: %s (decimal)\n", mpstr);
- mp_todecimal(&r, mpstr);
- printf("r : %s (dec)\n", mpstr);
- mp_tohex(&r, mpstr);
- printf("r : %s\n", mpstr);
-#endif
-
- CHECK_MPI_OK( mp_invmod(&k, &n, &k) ); /* k = k**-1 mod n */
- CHECK_MPI_OK( mp_mulmod(&d, &r, &n, &d) ); /* d = d * r mod n */
- CHECK_MPI_OK( mp_addmod(&s, &d, &n, &s) ); /* s = s + d mod n */
- CHECK_MPI_OK( mp_mulmod(&s, &k, &n, &s) ); /* s = s * k mod n */
-
-#if EC_DEBUG
- mp_todecimal(&s, mpstr);
- printf("s : %s (dec)\n", mpstr);
- mp_tohex(&s, mpstr);
- printf("s : %s\n", mpstr);
-#endif
-
- /*
- ** ANSI X9.62, Section 5.3.3, Step 5
- **
- ** verify s != 0
- */
- if (mp_cmp_z(&s) == 0) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- goto cleanup;
- }
-
- /*
- **
- ** Signature is tuple (r, s)
- */
- CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, olen) );
- CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + olen, olen) );
-finish:
- signature->len = 2*olen;
-
- rv = SECSuccess;
- err = MP_OKAY;
-cleanup:
- mp_clear(&x1);
- mp_clear(&d);
- mp_clear(&k);
- mp_clear(&r);
- mp_clear(&s);
- mp_clear(&n);
-
- if (kGpoint.data) {
- PORT_ZFree(kGpoint.data, 2*flen + 1);
- }
-
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
-
-#if EC_DEBUG
- printf("ECDSA signing with seed %s\n",
- (rv == SECSuccess) ? "succeeded" : "failed");
-#endif
-#else
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
-#endif /* NSS_ENABLE_ECC */
-
- return rv;
-}
-
-/*
-** Computes the ECDSA signature on the digest using the given key
-** and a random seed.
-*/
-SECStatus
-ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest)
-{
- SECStatus rv = SECFailure;
-#ifdef NSS_ENABLE_ECC
- int len;
- unsigned char *kBytes= NULL;
-
- if (!key) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* Generate random value k */
- len = key->ecParams.order.len;
- kBytes = ec_GenerateRandomPrivateKey(key->ecParams.order.data, len);
- if (kBytes == NULL) goto cleanup;
-
- /* Generate ECDSA signature with the specified k value */
- rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len);
-
-cleanup:
- if (kBytes) {
- PORT_ZFree(kBytes, len);
- }
-
-#if EC_DEBUG
- printf("ECDSA signing %s\n",
- (rv == SECSuccess) ? "succeeded" : "failed");
-#endif
-#else
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
-#endif /* NSS_ENABLE_ECC */
-
- return rv;
-}
-
-/*
-** Checks the signature on the given digest using the key provided.
-*/
-SECStatus
-ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
- const SECItem *digest)
-{
- SECStatus rv = SECFailure;
-#ifdef NSS_ENABLE_ECC
- mp_int r_, s_; /* tuple (r', s') is received signature) */
- mp_int c, u1, u2, v; /* intermediate values used in verification */
- mp_int x1;
- mp_int n;
- mp_err err = MP_OKAY;
- ECParams *ecParams = NULL;
- SECItem pointC = { siBuffer, NULL, 0 };
- int slen; /* length in bytes of a half signature (r or s) */
- int flen; /* length in bytes of the field size */
- unsigned olen; /* length in bytes of the base point order */
- unsigned obits; /* length in bits of the base point order */
-
-#if EC_DEBUG
- char mpstr[256];
- printf("ECDSA verification called\n");
-#endif
-
- /* Initialize MPI integers. */
- /* must happen before the first potential call to cleanup */
- MP_DIGITS(&r_) = 0;
- MP_DIGITS(&s_) = 0;
- MP_DIGITS(&c) = 0;
- MP_DIGITS(&u1) = 0;
- MP_DIGITS(&u2) = 0;
- MP_DIGITS(&x1) = 0;
- MP_DIGITS(&v) = 0;
- MP_DIGITS(&n) = 0;
-
- /* Check args */
- if (!key || !signature || !digest) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
-
- ecParams = &(key->ecParams);
- flen = (ecParams->fieldID.size + 7) >> 3;
- olen = ecParams->order.len;
- if (signature->len == 0 || signature->len%2 != 0 ||
- signature->len > 2*olen) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- goto cleanup;
- }
- slen = signature->len/2;
-
- SECITEM_AllocItem(NULL, &pointC, 2*flen + 1);
- if (pointC.data == NULL)
- goto cleanup;
-
- CHECK_MPI_OK( mp_init(&r_) );
- CHECK_MPI_OK( mp_init(&s_) );
- CHECK_MPI_OK( mp_init(&c) );
- CHECK_MPI_OK( mp_init(&u1) );
- CHECK_MPI_OK( mp_init(&u2) );
- CHECK_MPI_OK( mp_init(&x1) );
- CHECK_MPI_OK( mp_init(&v) );
- CHECK_MPI_OK( mp_init(&n) );
-
- /*
- ** Convert received signature (r', s') into MPI integers.
- */
- CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, slen) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + slen, slen) );
-
- /*
- ** ANSI X9.62, Section 5.4.2, Steps 1 and 2
- **
- ** Verify that 0 < r' < n and 0 < s' < n
- */
- SECITEM_TO_MPINT(ecParams->order, &n);
- if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
- mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- goto cleanup; /* will return rv == SECFailure */
- }
-
- /*
- ** ANSI X9.62, Section 5.4.2, Step 3
- **
- ** c = (s')**-1 mod n
- */
- CHECK_MPI_OK( mp_invmod(&s_, &n, &c) ); /* c = (s')**-1 mod n */
-
- /*
- ** ANSI X9.62, Section 5.4.2, Step 4
- **
- ** u1 = ((HASH(M')) * c) mod n
- */
- SECITEM_TO_MPINT(*digest, &u1); /* u1 = HASH(M) */
-
- /* In the definition of EC signing, digests are truncated
- * to the length of n in bits.
- * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
- CHECK_MPI_OK( (obits = mpl_significant_bits(&n)) );
- if (digest->len*8 > obits) { /* u1 = HASH(M') */
- mpl_rsh(&u1,&u1,digest->len*8 - obits);
- }
-
-#if EC_DEBUG
- mp_todecimal(&r_, mpstr);
- printf("r_: %s (dec)\n", mpstr);
- mp_todecimal(&s_, mpstr);
- printf("s_: %s (dec)\n", mpstr);
- mp_todecimal(&c, mpstr);
- printf("c : %s (dec)\n", mpstr);
- mp_todecimal(&u1, mpstr);
- printf("digest: %s (dec)\n", mpstr);
-#endif
-
- CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) ); /* u1 = u1 * c mod n */
-
- /*
- ** ANSI X9.62, Section 5.4.2, Step 4
- **
- ** u2 = ((r') * c) mod n
- */
- CHECK_MPI_OK( mp_mulmod(&r_, &c, &n, &u2) );
-
- /*
- ** ANSI X9.62, Section 5.4.3, Step 1
- **
- ** Compute u1*G + u2*Q
- ** Here, A = u1.G B = u2.Q and C = A + B
- ** If the result, C, is the point at infinity, reject the signature
- */
- if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC)
- != SECSuccess) {
- rv = SECFailure;
- goto cleanup;
- }
- if (ec_point_at_infinity(&pointC)) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- rv = SECFailure;
- goto cleanup;
- }
-
- CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) );
-
- /*
- ** ANSI X9.62, Section 5.4.4, Step 2
- **
- ** v = x1 mod n
- */
- CHECK_MPI_OK( mp_mod(&x1, &n, &v) );
-
-#if EC_DEBUG
- mp_todecimal(&r_, mpstr);
- printf("r_: %s (dec)\n", mpstr);
- mp_todecimal(&v, mpstr);
- printf("v : %s (dec)\n", mpstr);
-#endif
-
- /*
- ** ANSI X9.62, Section 5.4.4, Step 3
- **
- ** Verification: v == r'
- */
- if (mp_cmp(&v, &r_)) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- rv = SECFailure; /* Signature failed to verify. */
- } else {
- rv = SECSuccess; /* Signature verified. */
- }
-
-#if EC_DEBUG
- mp_todecimal(&u1, mpstr);
- printf("u1: %s (dec)\n", mpstr);
- mp_todecimal(&u2, mpstr);
- printf("u2: %s (dec)\n", mpstr);
- mp_tohex(&x1, mpstr);
- printf("x1: %s\n", mpstr);
- mp_todecimal(&v, mpstr);
- printf("v : %s (dec)\n", mpstr);
-#endif
-
-cleanup:
- mp_clear(&r_);
- mp_clear(&s_);
- mp_clear(&c);
- mp_clear(&u1);
- mp_clear(&u2);
- mp_clear(&x1);
- mp_clear(&v);
- mp_clear(&n);
-
- if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
-
-#if EC_DEBUG
- printf("ECDSA verification %s\n",
- (rv == SECSuccess) ? "succeeded" : "failed");
-#endif
-#else
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
-#endif /* NSS_ENABLE_ECC */
-
- return rv;
-}
-
diff --git a/security/nss/lib/freebl/ec.h b/security/nss/lib/freebl/ec.h
deleted file mode 100644
index 5a694d3ed..000000000
--- a/security/nss/lib/freebl/ec.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __ec_h_
-#define __ec_h_
-
-#define EC_DEBUG 0
-
-#define ANSI_X962_CURVE_OID_TOTAL_LEN 10
-#define SECG_CURVE_OID_TOTAL_LEN 7
-
-#endif /* __ec_h_ */
diff --git a/security/nss/lib/freebl/ecl/Makefile b/security/nss/lib/freebl/ecl/Makefile
deleted file mode 100644
index 6c86c25d8..000000000
--- a/security/nss/lib/freebl/ecl/Makefile
+++ /dev/null
@@ -1,194 +0,0 @@
-#
-# Makefile for elliptic curve library
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-## Define CC to be the C compiler you wish to use. The GNU cc
-## compiler (gcc) should work, at the very least
-#CC=cc
-#CC=gcc
-
-##
-## Define PERL to point to your local Perl interpreter. It
-## should be Perl 5.x, although it's conceivable that Perl 4
-## might work ... I haven't tested it.
-##
-#PERL=/usr/bin/perl
-#PERL=perl
-
-include ../mpi/target.mk
-
-##
-## Define platform-dependent variables for use of floating-point code.
-##
-ifeq ($(TARGET),v9SOLARIS)
-ECL_USE_FP=1
-else
-ifeq ($(TARGET),v8plusSOLARIS)
-ECL_USE_FP=1
-else
-ifeq ($(TARGET),v8SOLARIS)
-ECL_USE_FP=1
-else
-ifeq ($(TARGET),x86LINUX)
-ECL_USE_FP=1
-endif
-endif
-endif
-endif
-
-##
-## Add to definition of CFLAGS depending on use of floating-point code.
-##
-ifeq ($(ECL_USE_FP),1)
-CFLAGS+= -DECL_USE_FP
-endif
-
-##
-## Define LIBS to include any libraries you need to link against.
-## If NO_TABLE is define, LIBS should include '-lm' or whatever is
-## necessary to bring in the math library. Otherwise, it can be
-## left alone, unless your system has other peculiar requirements.
-##
-LIBS=-L../mpi -lmpi -lm#-lmalloc#-lefence
-
-##
-## Define INCLUDES to include any include directories you need to
-## compile with.
-##
-INCLUDES=-I../mpi
-CFLAGS+= $(INCLUDES) $(XCFLAGS)
-
-##
-## Define RANLIB to be the library header randomizer; you might not
-## need this on some systems (just set it to 'echo' on these systems,
-## such as IRIX)
-##
-RANLIB=echo
-
-##
-## Define LIBOBJS to be the object files that will be created during
-## the build process.
-##
-LIBOBJS = ecl.o ecl_curve.o ecl_mult.o ecl_gf.o \
- ec2_aff.o ec2_mont.o ec2_proj.o \
- ec2_163.o ec2_193.o ec2_233.o \
- ecp_aff.o ecp_jac.o ecp_mont.o \
- ec_naf.o ecp_jm.o \
- ecp_192.o ecp_224.o ecp_256.o ecp_384.o ecp_521.o
-ifeq ($(ECL_USE_FP),1)
-LIBOBJS+= ecp_fp160.o ecp_fp192.o ecp_fp224.o ecp_fp.o
-endif
-
-## The headers contained in this library.
-LIBHDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h ecl-curve.h
-APPHDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h ecl-curve.h
-ifeq ($(ECL_GFP_ASSEMBLY_FP),1)
-LIBHDRS += ecp_fp.h
-APPHDRS += ecp_fp.h
-endif
-
-
-help:
- @ echo ""
- @ echo "The following targets can be built with this Makefile:"
- @ echo ""
- @ echo "libecl.a - elliptic curve library"
- @ echo "tests - build command line tests"
- @ echo "test - run command line tests"
- @ echo "clean - clean up objects and such"
- @ echo ""
-
-.SUFFIXES: .c .o .i
-
-.c.i:
- $(CC) $(CFLAGS) -E $< > $@
-
-#---------------------------------------
-
-$(LIBOBJS): $(LIBHDRS)
-
-ecl.o: ecl.c $(LIBHDRS)
-ecl_curve.o: ecl_curve.c $(LIBHDRS)
-ecl_mult.o: ecl_mult.c $(LIBHDRS)
-ecl_gf.o: ecl_gf.c $(LIBHDRS)
-ec2_aff.o: ec2_aff.c $(LIBHDRS)
-ec2_mont.o: ec2_mont.c $(LIBHDRS)
-ec2_proj.o: ec2_proj.c $(LIBHDRS)
-ec2_163.o: ec2_163.c $(LIBHDRS)
-ec2_193.o: ec2_193.c $(LIBHDRS)
-ec2_233.o: ec2_233.c $(LIBHDRS)
-ecp_aff.o: ecp_aff.c $(LIBHDRS)
-ecp_jac.o: ecp_jac.c $(LIBHDRS)
-ecp_jm.o: ecp_jm.c $(LIBHDRS)
-ecp_mont.o: ecp_mont.c $(LIBHDRS)
-ecp_192.o: ecp_192.c $(LIBHDRS)
-ecp_224.o: ecp_224.c $(LIBHDRS)
-ecp_256.o: ecp_256.c $(LIBHDRS)
-ecp_384.o: ecp_384.c $(LIBHDRS)
-ecp_521.o: ecp_521.c $(LIBHDRS)
-ecp_fp.o: ecp_fp.c $(LIBHDRS)
-ifeq ($(ECL_USE_FP),1)
-ecp_fp160.o: ecp_fp160.c ecp_fpinc.c $(LIBHDRS)
-ecp_fp192.o: ecp_fp192.c ecp_fpinc.c $(LIBHDRS)
-ecp_fp224.o: ecp_fp224.c ecp_fpinc.c $(LIBHDRS)
-endif
-
-libecl.a: $(LIBOBJS)
- ar -cvr libecl.a $(LIBOBJS)
- $(RANLIB) libecl.a
-
-lib libs: libecl.a
-
-ecl.i: ecl.h
-
-#---------------------------------------
-
-ECLTESTOBJS = ec2_test.o ecp_test.o ec_naft.o
-ifeq ($(ECL_USE_FP),1)
-ECLTESTOBJS+= ecp_fpt.o
-endif
-ECLTESTS = $(ECLTESTOBJS:.o=)
-
-$(ECLTESTOBJS): %.o: tests/%.c $(LIBHDRS)
- $(CC) $(CFLAGS) -o $@ -c $< $(INCLUDES)
-
-$(ECLTESTS): %: %.o libecl.a
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
-
-ifeq ($(ECL_USE_FP),1)
-tests: ec2_test ecp_test ec_naft ecp_fpt
-else
-tests: ec2_test ecp_test ec_naft
-endif
-
-#---------------------------------------
-
-ifeq ($(ECL_USE_FP),1)
-test: tests
- ./ecp_test
- ./ec2_test
- ./ec_naft
- ./ecp_fpt
-else
-test: tests
- ./ecp_test
- ./ec_naft
- ./ec2_test
-endif
-
-#---------------------------------------
-
-alltests: tests
-
-clean:
- rm -f *.o *.a *.i
- rm -f core
- rm -f *~ .*~
- rm -f $(ECLTESTS)
-
-clobber: clean
-
-# END
diff --git a/security/nss/lib/freebl/ecl/README b/security/nss/lib/freebl/ecl/README
deleted file mode 100644
index b4c92400d..000000000
--- a/security/nss/lib/freebl/ecl/README
+++ /dev/null
@@ -1,330 +0,0 @@
-***** BEGIN LICENSE BLOCK *****
-Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
-The contents of this file are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-The Original Code is the elliptic curve math library.
-
-The Initial Developer of the Original Code is Sun Microsystems, Inc.
-Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
-Sun Microsystems, Inc. All Rights Reserved.
-
-Contributor(s):
- Stephen Fung <fungstep@hotmail.com> and
- Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
-
-Alternatively, the contents of this file may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of this file only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of this file under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of this file under
-the terms of any one of the MPL, the GPL or the LGPL.
-
-***** END LICENSE BLOCK *****
-
-The ECL exposes routines for constructing and converting curve
-parameters for internal use.
-
-
-HEADER FILES
-============
-
-ecl-exp.h - Exports data structures and curve names. For use by code
-that does not have access to mp_ints.
-
-ecl-curve.h - Provides hex encodings (in the form of ECCurveParams
-structs) of standardizes elliptic curve domain parameters and mappings
-from ECCurveName to ECCurveParams. For use by code that does not have
-access to mp_ints.
-
-ecl.h - Interface to constructors for curve parameters and group object,
-and point multiplication operations. Used by higher level algorithms
-(like ECDH and ECDSA) to actually perform elliptic curve cryptography.
-
-ecl-priv.h - Data structures and functions for internal use within the
-library.
-
-ec2.h - Internal header file that contains all functions for point
-arithmetic over binary polynomial fields.
-
-ecp.h - Internal header file that contains all functions for point
-arithmetic over prime fields.
-
-DATA STRUCTURES AND TYPES
-=========================
-
-ECCurveName (from ecl-exp.h) - Opaque name for standardized elliptic
-curve domain parameters.
-
-ECCurveParams (from ecl-exp.h) - Provides hexadecimal encoding
-of elliptic curve domain parameters. Can be generated by a user
-and passed to ECGroup_fromHex or can be generated from a name by
-EC_GetNamedCurveParams. ecl-curve.h contains ECCurveParams structs for
-the standardized curves defined by ECCurveName.
-
-ECGroup (from ecl.h and ecl-priv.h) - Opaque data structure that
-represents a group of elliptic curve points for a particular set of
-elliptic curve domain parameters. Contains all domain parameters (curve
-a and b, field, base point) as well as pointers to the functions that
-should be used for point arithmetic and the underlying field GFMethod.
-Generated by either ECGroup_fromHex or ECGroup_fromName.
-
-GFMethod (from ecl-priv.h) - Represents a field underlying a set of
-elliptic curve domain parameters. Contains the irreducible that defines
-the field (either the prime or the binary polynomial) as well as
-pointers to the functions that should be used for field arithmetic.
-
-ARITHMETIC FUNCTIONS
-====================
-
-Higher-level algorithms (like ECDH and ECDSA) should call ECPoint_mul
-or ECPoints_mul (from ecl.h) to do point arithmetic. These functions
-will choose which underlying algorithms to use, based on the ECGroup
-structure.
-
-Point Multiplication
---------------------
-
-ecl_mult.c provides the ECPoints_mul and ECPoint_mul wrappers.
-It also provides two implementations for the pts_mul operation -
-ec_pts_mul_basic (which computes kP, lQ, and then adds kP + lQ) and
-ec_pts_mul_simul_w2 (which does a simultaneous point multiplication
-using a table with window size 2*2).
-
-ec_naf.c provides an implementation of an algorithm to calculate a
-non-adjacent form of a scalar, minimizing the number of point
-additions that need to be done in a point multiplication.
-
-Point Arithmetic over Prime Fields
-----------------------------------
-
-ecp_aff.c provides point arithmetic using affine coordinates.
-
-ecp_jac.c provides point arithmetic using Jacobian projective
-coordinates and mixed Jacobian-affine coordinates. (Jacobian projective
-coordinates represent a point (x, y) as (X, Y, Z), where x=X/Z^2,
-y=Y/Z^3).
-
-ecp_jm.c provides point arithmetic using Modified Jacobian
-coordinates and mixed Modified_Jacobian-affine coordinates.
-(Modified Jacobian coordinates represent a point (x, y)
-as (X, Y, Z, a*Z^4), where x=X/Z^2, y=Y/Z^3, and a is
-the linear coefficient in the curve defining equation).
-
-ecp_192.c and ecp_224.c provide optimized field arithmetic.
-
-Point Arithmetic over Binary Polynomial Fields
-----------------------------------------------
-
-ec2_aff.c provides point arithmetic using affine coordinates.
-
-ec2_proj.c provides point arithmetic using projective coordinates.
-(Projective coordinates represent a point (x, y) as (X, Y, Z), where
-x=X/Z, y=Y/Z^2).
-
-ec2_mont.c provides point multiplication using Montgomery projective
-coordinates.
-
-ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field arithmetic.
-
-Field Arithmetic
-----------------
-
-ecl_gf.c provides constructors for field objects (GFMethod) with the
-functions GFMethod_cons*. It also provides wrappers around the basic
-field operations.
-
-Prime Field Arithmetic
-----------------------
-
-The mpi library provides the basic prime field arithmetic.
-
-ecp_mont.c provides wrappers around the Montgomery multiplication
-functions from the mpi library and adds encoding and decoding functions.
-It also provides the function to construct a GFMethod object using
-Montgomery multiplication.
-
-ecp_192.c and ecp_224.c provide optimized modular reduction for the
-fields defined by nistp192 and nistp224 primes.
-
-ecl_gf.c provides wrappers around the basic field operations.
-
-Binary Polynomial Field Arithmetic
-----------------------------------
-
-../mpi/mp_gf2m.c provides basic binary polynomial field arithmetic,
-including addition, multiplication, squaring, mod, and division, as well
-as conversion ob polynomial representations between bitstring and int[].
-
-ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field mod, mul,
-and sqr operations.
-
-ecl_gf.c provides wrappers around the basic field operations.
-
-Field Encoding
---------------
-
-By default, field elements are encoded in their basic form. It is
-possible to use an alternative encoding, however. For example, it is
-possible to Montgomery representation of prime field elements and
-take advantage of the fast modular multiplication that Montgomery
-representation provides. The process of converting from basic form to
-Montgomery representation is called field encoding, and the opposite
-process would be field decoding. All internal point operations assume
-that the operands are field encoded as appropriate. By rewiring the
-underlying field arithmetic to perform operations on these encoded
-values, the same overlying point arithmetic operations can be used
-regardless of field representation.
-
-ALGORITHM WIRING
-================
-
-The EC library allows point and field arithmetic algorithms to be
-substituted ("wired-in") on a fine-grained basis. This allows for
-generic algorithms and algorithms that are optimized for a particular
-curve, field, or architecture, to coexist and to be automatically
-selected at runtime.
-
-Wiring Mechanism
-----------------
-
-The ECGroup and GFMethod structure contain pointers to the point and
-field arithmetic functions, respectively, that are to be used in
-operations.
-
-The selection of algorithms to use is handled in the function
-ecgroup_fromNameAndHex in ecl.c.
-
-Default Wiring
---------------
-
-Curves over prime fields by default use montgomery field arithmetic,
-point multiplication using 5-bit window non-adjacent-form with
-Modified Jacobian coordinates, and 2*2-bit simultaneous point
-multiplication using Jacobian coordinates.
-(Wiring in function ECGroup_consGFp_mont in ecl.c.)
-
-Curves over prime fields that have optimized modular reduction (i.e.,
-secp160r1, nistp192, and nistp224) do not use Montgomery field
-arithmetic. Instead, they use basic field arithmetic with their
-optimized reduction (as in ecp_192.c and ecp_224.c). They
-use the same point multiplication and simultaneous point multiplication
-algorithms as other curves over prime fields.
-
-Curves over binary polynomial fields by default use generic field
-arithmetic with montgomery point multiplication and basic kP + lQ
-computation (multiply, multiply, and add). (Wiring in function
-ECGroup_cons_GF2m in ecl.c.)
-
-Curves over binary polynomial fields that have optimized field
-arithmetic (i.e., any 163-, 193, or 233-bit field) use their optimized
-field arithmetic. They use the same point multiplication and
-simultaneous point multiplication algorithms as other curves over binary
-fields.
-
-Example
--------
-
-We provide an example for plugging in an optimized implementation for
-the Koblitz curve nistk163.
-
-Suppose the file ec2_k163.c contains the optimized implementation. In
-particular it contains a point multiplication function:
-
- mp_err ec_GF2m_nistk163_pt_mul(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry, const ECGroup *group);
-
-Since only a pt_mul function is provided, the generic pt_add function
-will be used.
-
-There are two options for handling the optimized field arithmetic used
-by the ..._pt_mul function. Say the optimized field arithmetic includes
-the following functions:
-
- mp_err ec_GF2m_nistk163_add(const mp_int *a, const mp_int *b,
- mp_int *r, const GFMethod *meth);
- mp_err ec_GF2m_nistk163_mul(const mp_int *a, const mp_int *b,
- mp_int *r, const GFMethod *meth);
- mp_err ec_GF2m_nistk163_sqr(const mp_int *a, const mp_int *b,
- mp_int *r, const GFMethod *meth);
- mp_err ec_GF2m_nistk163_div(const mp_int *a, const mp_int *b,
- mp_int *r, const GFMethod *meth);
-
-First, the optimized field arithmetic could simply be called directly
-by the ..._pt_mul function. This would be accomplished by changing
-the ecgroup_fromNameAndHex function in ecl.c to include the following
-statements:
-
- if (name == ECCurve_NIST_K163) {
- group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx,
- &geny, &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
- MP_CHECKOK( ec_group_set_nistk163(group) );
- }
-
-and including in ec2_k163.c the following function:
-
- mp_err ec_group_set_nistk163(ECGroup *group) {
- group->point_mul = &ec_GF2m_nistk163_pt_mul;
- return MP_OKAY;
- }
-
-As a result, ec_GF2m_pt_add and similar functions would use the
-basic binary polynomial field arithmetic ec_GF2m_add, ec_GF2m_mul,
-ec_GF2m_sqr, and ec_GF2m_div.
-
-Alternatively, the optimized field arithmetic could be wired into the
-group's GFMethod. This would be accomplished by putting the following
-function in ec2_k163.c:
-
- mp_err ec_group_set_nistk163(ECGroup *group) {
- group->meth->field_add = &ec_GF2m_nistk163_add;
- group->meth->field_mul = &ec_GF2m_nistk163_mul;
- group->meth->field_sqr = &ec_GF2m_nistk163_sqr;
- group->meth->field_div = &ec_GF2m_nistk163_div;
- group->point_mul = &ec_GF2m_nistk163_pt_mul;
- return MP_OKAY;
- }
-
-For an example of functions that use special field encodings, take a
-look at ecp_mont.c.
-
-TESTING
-=======
-
-The ecl/tests directory contains a collection of standalone tests that
-verify the correctness of the elliptic curve library.
-
-Both ecp_test and ec2_test take the following arguments:
-
- --print Print out results of each point arithmetic test.
- --time Benchmark point operations and print results.
-
-The set of curves over which ecp_test and ec2_test run is coded into the
-program, but can be changed by editing the source files.
-
-BUILDING
-========
-
-The ecl can be built as a standalone library, separate from NSS,
-dependent only on the mpi library. To build the library:
-
- > cd ../mpi
- > make libs
- > cd ../ecl
- > make libs
- > make tests # to build test files
- > make test # to run automated tests
diff --git a/security/nss/lib/freebl/ecl/README.FP b/security/nss/lib/freebl/ecl/README.FP
deleted file mode 100644
index 833f42eb3..000000000
--- a/security/nss/lib/freebl/ecl/README.FP
+++ /dev/null
@@ -1,284 +0,0 @@
-This Source Code Form is subject to the terms of the Mozilla Public
-License, v. 2.0. If a copy of the MPL was not distributed with this
-file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-The ECL exposes routines for constructing and converting curve
-parameters for internal use.
-
-The floating point code of the ECL provides algorithms for performing
-elliptic-curve point multiplications in floating point.
-
-The point multiplication algorithms perform calculations almost
-exclusively in floating point for efficiency, but have the same
-(integer) interface as the ECL for compatibility and to be easily
-wired-in to the ECL. Please see README file (not this README.FP file)
-for information on wiring-in.
-
-This has been implemented for 3 curves as specified in [1]:
- secp160r1
- secp192r1
- secp224r1
-
-RATIONALE
-=========
-Calculations are done in the floating-point unit (FPU) since it
-gives better performance on the UltraSPARC III chips. This is
-because the FPU allows for faster multiplication than the integer unit.
-The integer unit has a longer multiplication instruction latency, and
-does not allow full pipelining, as described in [2].
-Since performance is an important selling feature of Elliptic Curve
-Cryptography (ECC), this implementation was created.
-
-DATA REPRESENTATION
-===================
-Data is primarily represented in an array of double-precision floating
-point numbers. Generally, each array element has 24 bits of precision
-(i.e. be x * 2^y, where x is an integer of at most 24 bits, y some positive
-integer), although the actual implementation details are more complicated.
-
-e.g. a way to store an 80 bit number might be:
-double p[4] = { 632613 * 2^0, 329841 * 2^24, 9961 * 2^48, 51 * 2^64 };
-See section ARITHMETIC OPERATIONS for more details.
-
-This implementation assumes that the floating-point unit rounding mode
-is round-to-even as specified in IEEE 754
-(as opposed to chopping, rounding up, or rounding down).
-When subtracting integers represented as arrays of floating point
-numbers, some coefficients (array elements) may become negative.
-This effectively gives an extra bit of precision that is important
-for correctness in some cases.
-
-The described number presentation limits the size of integers to 1023 bits.
-This is due to an upper bound of 1024 for the exponent of a double precision
-floating point number as specified in IEEE-754.
-However, this is acceptable for ECC key sizes of the foreseeable future.
-
-DATA STRUCTURES
-===============
-For more information on coordinate representations, see [3].
-
-ecfp_aff_pt
------------
-Affine EC Point Representation. This is the basic
-representation (x, y) of an elliptic curve point.
-
-ecfp_jac_pt
------------
-Jacobian EC Point. This stores a point as (X, Y, Z), where
-the affine point corresponds to (X/Z^2, Y/Z^3). This allows
-for fewer inversions in calculations.
-
-ecfp_chud_pt
-------------
-Chudnovsky Jacobian Point. This representation stores a point
-as (X, Y, Z, Z^2, Z^3), the same as a Jacobian representation
-but also storing Z^2 and Z^3 for faster point additions.
-
-ecfp_jm_pt
-----------
-Modified Jacobian Point. This representation stores a point
-as (X, Y, Z, a*Z^4), the same as Jacobian representation but
-also storing a*Z^4 for faster point doublings. Here "a" represents
-the linear coefficient of x defining the curve.
-
-EC_group_fp
------------
-Stores information on the elliptic curve group for floating
-point calculations. Contains curve specific information, as
-well as function pointers to routines, allowing different
-optimizations to be easily wired in.
-This should be made accessible from an ECGroup for the floating
-point implementations of point multiplication.
-
-POINT MULTIPLICATION ALGORITHMS
-===============================
-Elliptic Curve Point multiplication can be done at a higher level orthogonal
-to the implementation of point additions and point doublings. There
-are a variety of algorithms that can be used.
-
-The following algorithms have been implemented:
-
-4-bit Window (Jacobian Coordinates)
-Double & Add (Jacobian & Affine Coordinates)
-5-bit Non-Adjacent Form (Modified Jacobian & Chudnovsky Jacobian)
-
-Currently, the fastest algorithm for multiplying a generic point
-is the 5-bit Non-Adjacent Form.
-
-See comments in ecp_fp.c for more details and references.
-
-SOURCE / HEADER FILES
-=====================
-
-ecp_fp.c
---------
-Main source file for floating point calculations. Contains routines
-to convert from floating-point to integer (mp_int format), point
-multiplication algorithms, and several other routines.
-
-ecp_fp.h
---------
-Main header file. Contains most constants used and function prototypes.
-
-ecp_fp[160, 192, 224].c
------------------------
-Source files for specific curves. Contains curve specific code such
-as specialized reduction based on the field defining prime. Contains
-code wiring-in different algorithms and optimizations.
-
-ecp_fpinc.c
------------
-Source file that is included by ecp_fp[160, 192, 224].c. This generates
-functions with different preprocessor-defined names and loop iterations,
-allowing for static linking and strong compiler optimizations without
-code duplication.
-
-TESTING
-=======
-The test suite can be found in ecl/tests/ecp_fpt. This tests and gets
-timings of the different algorithms for the curves implemented.
-
-ARITHMETIC OPERATIONS
----------------------
-The primary operations in ECC over the prime fields are modular arithmetic:
-i.e. n * m (mod p) and n + m (mod p). In this implementation, multiplication,
-addition, and reduction are implemented as separate functions. This
-enables computation of formulae with fewer reductions, e.g.
-(a * b) + (c * d) (mod p) rather than:
-((a * b) (mod p)) + ((c * d) (mod p)) (mod p)
-This takes advantage of the fact that the double precision mantissa in
-floating point can hold numbers up to 2^53, i.e. it has some leeway to
-store larger intermediate numbers. See further detail in the section on
-FLOATING POINT PRECISION.
-
-Multiplication
---------------
-Multiplication is implemented in a standard polynomial multiplication
-fashion. The terms in opposite factors are pairwise multiplied and
-added together appropriately. Note that the result requires twice
-as many doubles for storage, as the bit size of the product is twice
-that of the multiplicands.
-e.g. suppose we have double n[3], m[3], r[6], and want to calculate r = n * m
-r[0] = n[0] * m[0]
-r[1] = n[0] * m[1] + n[1] * m[0]
-r[2] = n[0] * m[2] + n[1] * m[1] + n[2] * m[0]
-r[3] = n[1] * m[2] + n[2] * m[1]
-r[4] = n[2] * m[2]
-r[5] = 0 (This is used later to hold spillover from r[4], see tidying in
-the reduction section.)
-
-Addition
---------
-Addition is done term by term. The only caveat is to be careful with
-the number of terms that need to be added. When adding results of
-multiplication (before reduction), twice as many terms need to be added
-together. This is done in the addLong function.
-e.g. for double n[4], m[4], r[4]: r = n + m
-r[0] = n[0] + m[0]
-r[1] = n[1] + m[1]
-r[2] = n[2] + m[2]
-r[3] = n[3] + m[3]
-
-Modular Reduction
------------------
-For the curves implemented, reduction is possible by fast reduction
-for Generalized Mersenne Primes, as described in [4]. For the
-floating point implementation, a significant step of the reduction
-process is tidying: that is, the propagation of carry bits from
-low-order to high-order coefficients to reduce the precision of each
-coefficient to 24 bits.
-This is done by adding and then subtracting
-ecfp_alpha, a large floating point number that induces precision roundoff.
-See [5] for more details on tidying using floating point arithmetic.
-e.g. suppose we have r = 961838 * 2^24 + 519308
-then if we set alpha = 3 * 2^51 * 2^24,
-FP(FP(r + alpha) - alpha) = 961838 * 2^24, because the precision for
-the intermediate results is limited. Our values of alpha are chosen
-to truncate to a desired number of bits.
-
-The reduction is then performed as in [4], adding multiples of prime p.
-e.g. suppose we are working over a polynomial of 10^2. Take the number
-2 * 10^8 + 11 * 10^6 + 53 * 10^4 + 23 * 10^2 + 95, stored in 5 elements
-for coefficients of 10^0, 10^2, ..., 10^8.
-We wish to reduce modulo p = 10^6 - 2 * 10^4 + 1
-We can subtract off from the higher terms
-(2 * 10^8 + 11 * 10^6 + 53 * 10^4 + 23 * 10^2 + 95) - (2 * 10^2) * (10^6 - 2 * 10^4 + 1)
-= 15 * 10^6 + 53 * 10^4 + 21 * 10^2 + 95
-= 15 * 10^6 + 53 * 10^4 + 21 * 10^2 + 95 - (15) * (10^6 - 2 * 10^4 + 1)
-= 83 * 10^4 + 21 * 10^2 + 80
-
-Integrated Example
-------------------
-This example shows how multiplication, addition, tidying, and reduction
-work together in our modular arithmetic. This is simplified from the
-actual implementation, but should convey the main concepts.
-Working over polynomials of 10^2 and with p as in the prior example,
-Let a = 16 * 10^4 + 53 * 10^2 + 33
-let b = 81 * 10^4 + 31 * 10^2 + 49
-let c = 22 * 10^4 + 0 * 10^2 + 95
-And suppose we want to compute a * b + c mod p.
-We first do a multiplication: then a * b =
-0 * 10^10 + 1296 * 10^8 + 4789 * 10^6 + 5100 * 10^4 + 3620 * 10^2 + 1617
-Then we add in c before doing reduction, allowing us to get a * b + c =
-0 * 10^10 + 1296 * 10^8 + 4789 * 10^6 + 5122 * 10^4 + 3620 * 10^2 + 1712
-We then perform a tidying on the upper half of the terms:
-0 * 10^10 + 1296 * 10^8 + 4789 * 10^6
-0 * 10^10 + (1296 + 47) * 10^8 + 89 * 10^6
-0 * 10^10 + 1343 * 10^8 + 89 * 10^6
-13 * 10^10 + 43 * 10^8 + 89 * 10^6
-which then gives us
-13 * 10^10 + 43 * 10^8 + 89 * 10^6 + 5122 * 10^4 + 3620 * 10^2 + 1712
-we then reduce modulo p similar to the reduction example above:
-13 * 10^10 + 43 * 10^8 + 89 * 10^6 + 5122 * 10^4 + 3620 * 10^2 + 1712
- - (13 * 10^4 * p)
-69 * 10^8 + 89 * 10^6 + 5109 * 10^4 + 3620 * 10^2 + 1712
- - (69 * 10^2 * p)
-227 * 10^6 + 5109 * 10^4 + 3551 * 10^2 + 1712
- - (227 * p)
-5563 * 10^4 + 3551 * 10^2 + 1485
-finally, we do tidying to get the precision of each term down to 2 digits
-5563 * 10^4 + 3565 * 10^2 + 85
-5598 * 10^4 + 65 * 10^2 + 85
-55 * 10^6 + 98 * 10^4 + 65 * 10^2 + 85
-and perform another reduction step
- - (55 * p)
-208 * 10^4 + 65 * 10^2 + 30
-There may be a small number of further reductions that could be done at
-this point, but this is typically done only at the end when converting
-from floating point to an integer unit representation.
-
-FLOATING POINT PRECISION
-========================
-This section discusses the precision of floating point numbers, which
-one writing new formulae or a larger bit size should be aware of. The
-danger is that an intermediate result may be required to store a
-mantissa larger than 53 bits, which would cause error by rounding off.
-
-Note that the tidying with IEEE rounding mode set to round-to-even
-allows negative numbers, which actually reduces the size of the double
-mantissa to 23 bits - since it rounds the mantissa to the nearest number
-modulo 2^24, i.e. roughly between -2^23 and 2^23.
-A multiplication increases the bit size to 2^46 * n, where n is the number
-of doubles to store a number. For the 224 bit curve, n = 10. This gives
-doubles of size 5 * 2^47. Adding two of these doubles gives a result
-of size 5 * 2^48, which is less than 2^53, so this is safe.
-Similar analysis can be done for other formulae to ensure numbers remain
-below 2^53.
-
-Extended-Precision Floating Point
----------------------------------
-Some platforms, notably x86 Linux, may use an extended-precision floating
-point representation that has a 64-bit mantissa. [6] Although this
-implementation is optimized for the IEEE standard 53-bit mantissa,
-it should work with the 64-bit mantissa. A check is done at run-time
-in the function ec_set_fp_precision that detects if the precision is
-greater than 53 bits, and runs code for the 64-bit mantissa accordingly.
-
-REFERENCES
-==========
-[1] Certicom Corp., "SEC 2: Recommended Elliptic Curve Domain Parameters", Sept. 20, 2000. www.secg.org
-[2] Sun Microsystems Inc. UltraSPARC III Cu User's Manual, Version 1.0, May 2002, Table 4.4
-[3] H. Cohen, A. Miyaji, and T. Ono, "Efficient Elliptic Curve Exponentiation Using Mixed Coordinates".
-[4] Henk C.A. van Tilborg, Generalized Mersenne Prime. http://www.win.tue.nl/~henkvt/GenMersenne.pdf
-[5] Daniel J. Bernstein, Floating-Point Arithmetic and Message Authentication, Journal of Cryptology, March 2000, Section 2.
-[6] Daniel J. Bernstein, Floating-Point Arithmetic and Message Authentication, Journal of Cryptology, March 2000, Section 2 Notes.
diff --git a/security/nss/lib/freebl/ecl/ec2.h b/security/nss/lib/freebl/ecl/ec2.h
deleted file mode 100644
index 5d75d48dd..000000000
--- a/security/nss/lib/freebl/ecl/ec2.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __ec2_h_
-#define __ec2_h_
-
-#include "ecl-priv.h"
-
-/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
-mp_err ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py);
-
-/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
-mp_err ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py);
-
-/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
- * qy). Uses affine coordinates. */
-mp_err ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py,
- const mp_int *qx, const mp_int *qy, mp_int *rx,
- mp_int *ry, const ECGroup *group);
-
-/* Computes R = P - Q. Uses affine coordinates. */
-mp_err ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py,
- const mp_int *qx, const mp_int *qy, mp_int *rx,
- mp_int *ry, const ECGroup *group);
-
-/* Computes R = 2P. Uses affine coordinates. */
-mp_err ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, const ECGroup *group);
-
-/* Validates a point on a GF2m curve. */
-mp_err ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group);
-
-/* by default, this routine is unused and thus doesn't need to be compiled */
-#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
-/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
- * a, b and p are the elliptic curve coefficients and the irreducible that
- * determines the field GF2m. Uses affine coordinates. */
-mp_err ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group);
-#endif
-
-/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
- * a, b and p are the elliptic curve coefficients and the irreducible that
- * determines the field GF2m. Uses Montgomery projective coordinates. */
-mp_err ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group);
-
-#ifdef ECL_ENABLE_GF2M_PROJ
-/* Converts a point P(px, py) from affine coordinates to projective
- * coordinates R(rx, ry, rz). */
-mp_err ec_GF2m_pt_aff2proj(const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, mp_int *rz, const ECGroup *group);
-
-/* Converts a point P(px, py, pz) from projective coordinates to affine
- * coordinates R(rx, ry). */
-mp_err ec_GF2m_pt_proj2aff(const mp_int *px, const mp_int *py,
- const mp_int *pz, mp_int *rx, mp_int *ry,
- const ECGroup *group);
-
-/* Checks if point P(px, py, pz) is at infinity. Uses projective
- * coordinates. */
-mp_err ec_GF2m_pt_is_inf_proj(const mp_int *px, const mp_int *py,
- const mp_int *pz);
-
-/* Sets P(px, py, pz) to be the point at infinity. Uses projective
- * coordinates. */
-mp_err ec_GF2m_pt_set_inf_proj(mp_int *px, mp_int *py, mp_int *pz);
-
-/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
- * (qx, qy, qz). Uses projective coordinates. */
-mp_err ec_GF2m_pt_add_proj(const mp_int *px, const mp_int *py,
- const mp_int *pz, const mp_int *qx,
- const mp_int *qy, mp_int *rx, mp_int *ry,
- mp_int *rz, const ECGroup *group);
-
-/* Computes R = 2P. Uses projective coordinates. */
-mp_err ec_GF2m_pt_dbl_proj(const mp_int *px, const mp_int *py,
- const mp_int *pz, mp_int *rx, mp_int *ry,
- mp_int *rz, const ECGroup *group);
-
-/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
- * a, b and p are the elliptic curve coefficients and the prime that
- * determines the field GF2m. Uses projective coordinates. */
-mp_err ec_GF2m_pt_mul_proj(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group);
-#endif
-
-#endif /* __ec2_h_ */
diff --git a/security/nss/lib/freebl/ecl/ec2_163.c b/security/nss/lib/freebl/ecl/ec2_163.c
deleted file mode 100644
index 8ed40a4c8..000000000
--- a/security/nss/lib/freebl/ecl/ec2_163.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ec2.h"
-#include "mp_gf2m.h"
-#include "mp_gf2m-priv.h"
-#include "mpi.h"
-#include "mpi-priv.h"
-#include <stdlib.h>
-
-/* Fast reduction for polynomials over a 163-bit curve. Assumes reduction
- * polynomial with terms {163, 7, 6, 3, 0}. */
-mp_err
-ec_GF2m_163_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit *u, z;
-
- if (a != r) {
- MP_CHECKOK(mp_copy(a, r));
- }
-#ifdef ECL_SIXTY_FOUR_BIT
- if (MP_USED(r) < 6) {
- MP_CHECKOK(s_mp_pad(r, 6));
- }
- u = MP_DIGITS(r);
- MP_USED(r) = 6;
-
- /* u[5] only has 6 significant bits */
- z = u[5];
- u[2] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
- z = u[4];
- u[2] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
- u[1] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
- z = u[3];
- u[1] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
- u[0] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
- z = u[2] >> 35; /* z only has 29 significant bits */
- u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
- /* clear bits above 163 */
- u[5] = u[4] = u[3] = 0;
- u[2] ^= z << 35;
-#else
- if (MP_USED(r) < 11) {
- MP_CHECKOK(s_mp_pad(r, 11));
- }
- u = MP_DIGITS(r);
- MP_USED(r) = 11;
-
- /* u[11] only has 6 significant bits */
- z = u[10];
- u[5] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
- u[4] ^= (z << 29);
- z = u[9];
- u[5] ^= (z >> 28) ^ (z >> 29);
- u[4] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
- u[3] ^= (z << 29);
- z = u[8];
- u[4] ^= (z >> 28) ^ (z >> 29);
- u[3] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
- u[2] ^= (z << 29);
- z = u[7];
- u[3] ^= (z >> 28) ^ (z >> 29);
- u[2] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
- u[1] ^= (z << 29);
- z = u[6];
- u[2] ^= (z >> 28) ^ (z >> 29);
- u[1] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
- u[0] ^= (z << 29);
- z = u[5] >> 3; /* z only has 29 significant bits */
- u[1] ^= (z >> 25) ^ (z >> 26);
- u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
- /* clear bits above 163 */
- u[11] = u[10] = u[9] = u[8] = u[7] = u[6] = 0;
- u[5] ^= z << 3;
-#endif
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* Fast squaring for polynomials over a 163-bit curve. Assumes reduction
- * polynomial with terms {163, 7, 6, 3, 0}. */
-mp_err
-ec_GF2m_163_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit *u, *v;
-
- v = MP_DIGITS(a);
-
-#ifdef ECL_SIXTY_FOUR_BIT
- if (MP_USED(a) < 3) {
- return mp_bsqrmod(a, meth->irr_arr, r);
- }
- if (MP_USED(r) < 6) {
- MP_CHECKOK(s_mp_pad(r, 6));
- }
- MP_USED(r) = 6;
-#else
- if (MP_USED(a) < 6) {
- return mp_bsqrmod(a, meth->irr_arr, r);
- }
- if (MP_USED(r) < 12) {
- MP_CHECKOK(s_mp_pad(r, 12));
- }
- MP_USED(r) = 12;
-#endif
- u = MP_DIGITS(r);
-
-#ifdef ECL_THIRTY_TWO_BIT
- u[11] = gf2m_SQR1(v[5]);
- u[10] = gf2m_SQR0(v[5]);
- u[9] = gf2m_SQR1(v[4]);
- u[8] = gf2m_SQR0(v[4]);
- u[7] = gf2m_SQR1(v[3]);
- u[6] = gf2m_SQR0(v[3]);
-#endif
- u[5] = gf2m_SQR1(v[2]);
- u[4] = gf2m_SQR0(v[2]);
- u[3] = gf2m_SQR1(v[1]);
- u[2] = gf2m_SQR0(v[1]);
- u[1] = gf2m_SQR1(v[0]);
- u[0] = gf2m_SQR0(v[0]);
- return ec_GF2m_163_mod(r, r, meth);
-
- CLEANUP:
- return res;
-}
-
-/* Fast multiplication for polynomials over a 163-bit curve. Assumes
- * reduction polynomial with terms {163, 7, 6, 3, 0}. */
-mp_err
-ec_GF2m_163_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit a2 = 0, a1 = 0, a0, b2 = 0, b1 = 0, b0;
-
-#ifdef ECL_THIRTY_TWO_BIT
- mp_digit a5 = 0, a4 = 0, a3 = 0, b5 = 0, b4 = 0, b3 = 0;
- mp_digit rm[6];
-#endif
-
- if (a == b) {
- return ec_GF2m_163_sqr(a, r, meth);
- } else {
- switch (MP_USED(a)) {
-#ifdef ECL_THIRTY_TWO_BIT
- case 6:
- a5 = MP_DIGIT(a, 5);
- case 5:
- a4 = MP_DIGIT(a, 4);
- case 4:
- a3 = MP_DIGIT(a, 3);
-#endif
- case 3:
- a2 = MP_DIGIT(a, 2);
- case 2:
- a1 = MP_DIGIT(a, 1);
- default:
- a0 = MP_DIGIT(a, 0);
- }
- switch (MP_USED(b)) {
-#ifdef ECL_THIRTY_TWO_BIT
- case 6:
- b5 = MP_DIGIT(b, 5);
- case 5:
- b4 = MP_DIGIT(b, 4);
- case 4:
- b3 = MP_DIGIT(b, 3);
-#endif
- case 3:
- b2 = MP_DIGIT(b, 2);
- case 2:
- b1 = MP_DIGIT(b, 1);
- default:
- b0 = MP_DIGIT(b, 0);
- }
-#ifdef ECL_SIXTY_FOUR_BIT
- MP_CHECKOK(s_mp_pad(r, 6));
- s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
- MP_USED(r) = 6;
- s_mp_clamp(r);
-#else
- MP_CHECKOK(s_mp_pad(r, 12));
- s_bmul_3x3(MP_DIGITS(r) + 6, a5, a4, a3, b5, b4, b3);
- s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
- s_bmul_3x3(rm, a5 ^ a2, a4 ^ a1, a3 ^ a0, b5 ^ b2, b4 ^ b1,
- b3 ^ b0);
- rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 11);
- rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 10);
- rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 9);
- rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 8);
- rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 7);
- rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 6);
- MP_DIGIT(r, 8) ^= rm[5];
- MP_DIGIT(r, 7) ^= rm[4];
- MP_DIGIT(r, 6) ^= rm[3];
- MP_DIGIT(r, 5) ^= rm[2];
- MP_DIGIT(r, 4) ^= rm[1];
- MP_DIGIT(r, 3) ^= rm[0];
- MP_USED(r) = 12;
- s_mp_clamp(r);
-#endif
- return ec_GF2m_163_mod(r, r, meth);
- }
-
- CLEANUP:
- return res;
-}
-
-/* Wire in fast field arithmetic for 163-bit curves. */
-mp_err
-ec_group_set_gf2m163(ECGroup *group, ECCurveName name)
-{
- group->meth->field_mod = &ec_GF2m_163_mod;
- group->meth->field_mul = &ec_GF2m_163_mul;
- group->meth->field_sqr = &ec_GF2m_163_sqr;
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ec2_193.c b/security/nss/lib/freebl/ecl/ec2_193.c
deleted file mode 100644
index edb38a67a..000000000
--- a/security/nss/lib/freebl/ecl/ec2_193.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ec2.h"
-#include "mp_gf2m.h"
-#include "mp_gf2m-priv.h"
-#include "mpi.h"
-#include "mpi-priv.h"
-#include <stdlib.h>
-
-/* Fast reduction for polynomials over a 193-bit curve. Assumes reduction
- * polynomial with terms {193, 15, 0}. */
-mp_err
-ec_GF2m_193_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit *u, z;
-
- if (a != r) {
- MP_CHECKOK(mp_copy(a, r));
- }
-#ifdef ECL_SIXTY_FOUR_BIT
- if (MP_USED(r) < 7) {
- MP_CHECKOK(s_mp_pad(r, 7));
- }
- u = MP_DIGITS(r);
- MP_USED(r) = 7;
-
- /* u[6] only has 2 significant bits */
- z = u[6];
- u[3] ^= (z << 14) ^ (z >> 1);
- u[2] ^= (z << 63);
- z = u[5];
- u[3] ^= (z >> 50);
- u[2] ^= (z << 14) ^ (z >> 1);
- u[1] ^= (z << 63);
- z = u[4];
- u[2] ^= (z >> 50);
- u[1] ^= (z << 14) ^ (z >> 1);
- u[0] ^= (z << 63);
- z = u[3] >> 1; /* z only has 63 significant bits */
- u[1] ^= (z >> 49);
- u[0] ^= (z << 15) ^ z;
- /* clear bits above 193 */
- u[6] = u[5] = u[4] = 0;
- u[3] ^= z << 1;
-#else
- if (MP_USED(r) < 13) {
- MP_CHECKOK(s_mp_pad(r, 13));
- }
- u = MP_DIGITS(r);
- MP_USED(r) = 13;
-
- /* u[12] only has 2 significant bits */
- z = u[12];
- u[6] ^= (z << 14) ^ (z >> 1);
- u[5] ^= (z << 31);
- z = u[11];
- u[6] ^= (z >> 18);
- u[5] ^= (z << 14) ^ (z >> 1);
- u[4] ^= (z << 31);
- z = u[10];
- u[5] ^= (z >> 18);
- u[4] ^= (z << 14) ^ (z >> 1);
- u[3] ^= (z << 31);
- z = u[9];
- u[4] ^= (z >> 18);
- u[3] ^= (z << 14) ^ (z >> 1);
- u[2] ^= (z << 31);
- z = u[8];
- u[3] ^= (z >> 18);
- u[2] ^= (z << 14) ^ (z >> 1);
- u[1] ^= (z << 31);
- z = u[7];
- u[2] ^= (z >> 18);
- u[1] ^= (z << 14) ^ (z >> 1);
- u[0] ^= (z << 31);
- z = u[6] >> 1; /* z only has 31 significant bits */
- u[1] ^= (z >> 17);
- u[0] ^= (z << 15) ^ z;
- /* clear bits above 193 */
- u[12] = u[11] = u[10] = u[9] = u[8] = u[7] = 0;
- u[6] ^= z << 1;
-#endif
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* Fast squaring for polynomials over a 193-bit curve. Assumes reduction
- * polynomial with terms {193, 15, 0}. */
-mp_err
-ec_GF2m_193_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit *u, *v;
-
- v = MP_DIGITS(a);
-
-#ifdef ECL_SIXTY_FOUR_BIT
- if (MP_USED(a) < 4) {
- return mp_bsqrmod(a, meth->irr_arr, r);
- }
- if (MP_USED(r) < 7) {
- MP_CHECKOK(s_mp_pad(r, 7));
- }
- MP_USED(r) = 7;
-#else
- if (MP_USED(a) < 7) {
- return mp_bsqrmod(a, meth->irr_arr, r);
- }
- if (MP_USED(r) < 13) {
- MP_CHECKOK(s_mp_pad(r, 13));
- }
- MP_USED(r) = 13;
-#endif
- u = MP_DIGITS(r);
-
-#ifdef ECL_THIRTY_TWO_BIT
- u[12] = gf2m_SQR0(v[6]);
- u[11] = gf2m_SQR1(v[5]);
- u[10] = gf2m_SQR0(v[5]);
- u[9] = gf2m_SQR1(v[4]);
- u[8] = gf2m_SQR0(v[4]);
- u[7] = gf2m_SQR1(v[3]);
-#endif
- u[6] = gf2m_SQR0(v[3]);
- u[5] = gf2m_SQR1(v[2]);
- u[4] = gf2m_SQR0(v[2]);
- u[3] = gf2m_SQR1(v[1]);
- u[2] = gf2m_SQR0(v[1]);
- u[1] = gf2m_SQR1(v[0]);
- u[0] = gf2m_SQR0(v[0]);
- return ec_GF2m_193_mod(r, r, meth);
-
- CLEANUP:
- return res;
-}
-
-/* Fast multiplication for polynomials over a 193-bit curve. Assumes
- * reduction polynomial with terms {193, 15, 0}. */
-mp_err
-ec_GF2m_193_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
-
-#ifdef ECL_THIRTY_TWO_BIT
- mp_digit a6 = 0, a5 = 0, a4 = 0, b6 = 0, b5 = 0, b4 = 0;
- mp_digit rm[8];
-#endif
-
- if (a == b) {
- return ec_GF2m_193_sqr(a, r, meth);
- } else {
- switch (MP_USED(a)) {
-#ifdef ECL_THIRTY_TWO_BIT
- case 7:
- a6 = MP_DIGIT(a, 6);
- case 6:
- a5 = MP_DIGIT(a, 5);
- case 5:
- a4 = MP_DIGIT(a, 4);
-#endif
- case 4:
- a3 = MP_DIGIT(a, 3);
- case 3:
- a2 = MP_DIGIT(a, 2);
- case 2:
- a1 = MP_DIGIT(a, 1);
- default:
- a0 = MP_DIGIT(a, 0);
- }
- switch (MP_USED(b)) {
-#ifdef ECL_THIRTY_TWO_BIT
- case 7:
- b6 = MP_DIGIT(b, 6);
- case 6:
- b5 = MP_DIGIT(b, 5);
- case 5:
- b4 = MP_DIGIT(b, 4);
-#endif
- case 4:
- b3 = MP_DIGIT(b, 3);
- case 3:
- b2 = MP_DIGIT(b, 2);
- case 2:
- b1 = MP_DIGIT(b, 1);
- default:
- b0 = MP_DIGIT(b, 0);
- }
-#ifdef ECL_SIXTY_FOUR_BIT
- MP_CHECKOK(s_mp_pad(r, 8));
- s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
- MP_USED(r) = 8;
- s_mp_clamp(r);
-#else
- MP_CHECKOK(s_mp_pad(r, 14));
- s_bmul_3x3(MP_DIGITS(r) + 8, a6, a5, a4, b6, b5, b4);
- s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
- s_bmul_4x4(rm, a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b3, b6 ^ b2, b5 ^ b1,
- b4 ^ b0);
- rm[7] ^= MP_DIGIT(r, 7);
- rm[6] ^= MP_DIGIT(r, 6);
- rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
- rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
- rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
- rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
- rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
- rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
- MP_DIGIT(r, 11) ^= rm[7];
- MP_DIGIT(r, 10) ^= rm[6];
- MP_DIGIT(r, 9) ^= rm[5];
- MP_DIGIT(r, 8) ^= rm[4];
- MP_DIGIT(r, 7) ^= rm[3];
- MP_DIGIT(r, 6) ^= rm[2];
- MP_DIGIT(r, 5) ^= rm[1];
- MP_DIGIT(r, 4) ^= rm[0];
- MP_USED(r) = 14;
- s_mp_clamp(r);
-#endif
- return ec_GF2m_193_mod(r, r, meth);
- }
-
- CLEANUP:
- return res;
-}
-
-/* Wire in fast field arithmetic for 193-bit curves. */
-mp_err
-ec_group_set_gf2m193(ECGroup *group, ECCurveName name)
-{
- group->meth->field_mod = &ec_GF2m_193_mod;
- group->meth->field_mul = &ec_GF2m_193_mul;
- group->meth->field_sqr = &ec_GF2m_193_sqr;
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ec2_233.c b/security/nss/lib/freebl/ecl/ec2_233.c
deleted file mode 100644
index f73673cae..000000000
--- a/security/nss/lib/freebl/ecl/ec2_233.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ec2.h"
-#include "mp_gf2m.h"
-#include "mp_gf2m-priv.h"
-#include "mpi.h"
-#include "mpi-priv.h"
-#include <stdlib.h>
-
-/* Fast reduction for polynomials over a 233-bit curve. Assumes reduction
- * polynomial with terms {233, 74, 0}. */
-mp_err
-ec_GF2m_233_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit *u, z;
-
- if (a != r) {
- MP_CHECKOK(mp_copy(a, r));
- }
-#ifdef ECL_SIXTY_FOUR_BIT
- if (MP_USED(r) < 8) {
- MP_CHECKOK(s_mp_pad(r, 8));
- }
- u = MP_DIGITS(r);
- MP_USED(r) = 8;
-
- /* u[7] only has 18 significant bits */
- z = u[7];
- u[4] ^= (z << 33) ^ (z >> 41);
- u[3] ^= (z << 23);
- z = u[6];
- u[4] ^= (z >> 31);
- u[3] ^= (z << 33) ^ (z >> 41);
- u[2] ^= (z << 23);
- z = u[5];
- u[3] ^= (z >> 31);
- u[2] ^= (z << 33) ^ (z >> 41);
- u[1] ^= (z << 23);
- z = u[4];
- u[2] ^= (z >> 31);
- u[1] ^= (z << 33) ^ (z >> 41);
- u[0] ^= (z << 23);
- z = u[3] >> 41; /* z only has 23 significant bits */
- u[1] ^= (z << 10);
- u[0] ^= z;
- /* clear bits above 233 */
- u[7] = u[6] = u[5] = u[4] = 0;
- u[3] ^= z << 41;
-#else
- if (MP_USED(r) < 15) {
- MP_CHECKOK(s_mp_pad(r, 15));
- }
- u = MP_DIGITS(r);
- MP_USED(r) = 15;
-
- /* u[14] only has 18 significant bits */
- z = u[14];
- u[9] ^= (z << 1);
- u[7] ^= (z >> 9);
- u[6] ^= (z << 23);
- z = u[13];
- u[9] ^= (z >> 31);
- u[8] ^= (z << 1);
- u[6] ^= (z >> 9);
- u[5] ^= (z << 23);
- z = u[12];
- u[8] ^= (z >> 31);
- u[7] ^= (z << 1);
- u[5] ^= (z >> 9);
- u[4] ^= (z << 23);
- z = u[11];
- u[7] ^= (z >> 31);
- u[6] ^= (z << 1);
- u[4] ^= (z >> 9);
- u[3] ^= (z << 23);
- z = u[10];
- u[6] ^= (z >> 31);
- u[5] ^= (z << 1);
- u[3] ^= (z >> 9);
- u[2] ^= (z << 23);
- z = u[9];
- u[5] ^= (z >> 31);
- u[4] ^= (z << 1);
- u[2] ^= (z >> 9);
- u[1] ^= (z << 23);
- z = u[8];
- u[4] ^= (z >> 31);
- u[3] ^= (z << 1);
- u[1] ^= (z >> 9);
- u[0] ^= (z << 23);
- z = u[7] >> 9; /* z only has 23 significant bits */
- u[3] ^= (z >> 22);
- u[2] ^= (z << 10);
- u[0] ^= z;
- /* clear bits above 233 */
- u[14] = u[13] = u[12] = u[11] = u[10] = u[9] = u[8] = 0;
- u[7] ^= z << 9;
-#endif
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* Fast squaring for polynomials over a 233-bit curve. Assumes reduction
- * polynomial with terms {233, 74, 0}. */
-mp_err
-ec_GF2m_233_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit *u, *v;
-
- v = MP_DIGITS(a);
-
-#ifdef ECL_SIXTY_FOUR_BIT
- if (MP_USED(a) < 4) {
- return mp_bsqrmod(a, meth->irr_arr, r);
- }
- if (MP_USED(r) < 8) {
- MP_CHECKOK(s_mp_pad(r, 8));
- }
- MP_USED(r) = 8;
-#else
- if (MP_USED(a) < 8) {
- return mp_bsqrmod(a, meth->irr_arr, r);
- }
- if (MP_USED(r) < 15) {
- MP_CHECKOK(s_mp_pad(r, 15));
- }
- MP_USED(r) = 15;
-#endif
- u = MP_DIGITS(r);
-
-#ifdef ECL_THIRTY_TWO_BIT
- u[14] = gf2m_SQR0(v[7]);
- u[13] = gf2m_SQR1(v[6]);
- u[12] = gf2m_SQR0(v[6]);
- u[11] = gf2m_SQR1(v[5]);
- u[10] = gf2m_SQR0(v[5]);
- u[9] = gf2m_SQR1(v[4]);
- u[8] = gf2m_SQR0(v[4]);
-#endif
- u[7] = gf2m_SQR1(v[3]);
- u[6] = gf2m_SQR0(v[3]);
- u[5] = gf2m_SQR1(v[2]);
- u[4] = gf2m_SQR0(v[2]);
- u[3] = gf2m_SQR1(v[1]);
- u[2] = gf2m_SQR0(v[1]);
- u[1] = gf2m_SQR1(v[0]);
- u[0] = gf2m_SQR0(v[0]);
- return ec_GF2m_233_mod(r, r, meth);
-
- CLEANUP:
- return res;
-}
-
-/* Fast multiplication for polynomials over a 233-bit curve. Assumes
- * reduction polynomial with terms {233, 74, 0}. */
-mp_err
-ec_GF2m_233_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
-
-#ifdef ECL_THIRTY_TWO_BIT
- mp_digit a7 = 0, a6 = 0, a5 = 0, a4 = 0, b7 = 0, b6 = 0, b5 = 0, b4 =
- 0;
- mp_digit rm[8];
-#endif
-
- if (a == b) {
- return ec_GF2m_233_sqr(a, r, meth);
- } else {
- switch (MP_USED(a)) {
-#ifdef ECL_THIRTY_TWO_BIT
- case 8:
- a7 = MP_DIGIT(a, 7);
- case 7:
- a6 = MP_DIGIT(a, 6);
- case 6:
- a5 = MP_DIGIT(a, 5);
- case 5:
- a4 = MP_DIGIT(a, 4);
-#endif
- case 4:
- a3 = MP_DIGIT(a, 3);
- case 3:
- a2 = MP_DIGIT(a, 2);
- case 2:
- a1 = MP_DIGIT(a, 1);
- default:
- a0 = MP_DIGIT(a, 0);
- }
- switch (MP_USED(b)) {
-#ifdef ECL_THIRTY_TWO_BIT
- case 8:
- b7 = MP_DIGIT(b, 7);
- case 7:
- b6 = MP_DIGIT(b, 6);
- case 6:
- b5 = MP_DIGIT(b, 5);
- case 5:
- b4 = MP_DIGIT(b, 4);
-#endif
- case 4:
- b3 = MP_DIGIT(b, 3);
- case 3:
- b2 = MP_DIGIT(b, 2);
- case 2:
- b1 = MP_DIGIT(b, 1);
- default:
- b0 = MP_DIGIT(b, 0);
- }
-#ifdef ECL_SIXTY_FOUR_BIT
- MP_CHECKOK(s_mp_pad(r, 8));
- s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
- MP_USED(r) = 8;
- s_mp_clamp(r);
-#else
- MP_CHECKOK(s_mp_pad(r, 16));
- s_bmul_4x4(MP_DIGITS(r) + 8, a7, a6, a5, a4, b7, b6, b5, b4);
- s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
- s_bmul_4x4(rm, a7 ^ a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b7 ^ b3,
- b6 ^ b2, b5 ^ b1, b4 ^ b0);
- rm[7] ^= MP_DIGIT(r, 7) ^ MP_DIGIT(r, 15);
- rm[6] ^= MP_DIGIT(r, 6) ^ MP_DIGIT(r, 14);
- rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
- rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
- rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
- rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
- rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
- rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
- MP_DIGIT(r, 11) ^= rm[7];
- MP_DIGIT(r, 10) ^= rm[6];
- MP_DIGIT(r, 9) ^= rm[5];
- MP_DIGIT(r, 8) ^= rm[4];
- MP_DIGIT(r, 7) ^= rm[3];
- MP_DIGIT(r, 6) ^= rm[2];
- MP_DIGIT(r, 5) ^= rm[1];
- MP_DIGIT(r, 4) ^= rm[0];
- MP_USED(r) = 16;
- s_mp_clamp(r);
-#endif
- return ec_GF2m_233_mod(r, r, meth);
- }
-
- CLEANUP:
- return res;
-}
-
-/* Wire in fast field arithmetic for 233-bit curves. */
-mp_err
-ec_group_set_gf2m233(ECGroup *group, ECCurveName name)
-{
- group->meth->field_mod = &ec_GF2m_233_mod;
- group->meth->field_mul = &ec_GF2m_233_mul;
- group->meth->field_sqr = &ec_GF2m_233_sqr;
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ec2_aff.c b/security/nss/lib/freebl/ecl/ec2_aff.c
deleted file mode 100644
index 50edc54bb..000000000
--- a/security/nss/lib/freebl/ecl/ec2_aff.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ec2.h"
-#include "mplogic.h"
-#include "mp_gf2m.h"
-#include <stdlib.h>
-
-/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
-mp_err
-ec_GF2m_pt_is_inf_aff(const mp_int *px, const mp_int *py)
-{
-
- if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
- return MP_YES;
- } else {
- return MP_NO;
- }
-
-}
-
-/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
-mp_err
-ec_GF2m_pt_set_inf_aff(mp_int *px, mp_int *py)
-{
- mp_zero(px);
- mp_zero(py);
- return MP_OKAY;
-}
-
-/* Computes R = P + Q based on IEEE P1363 A.10.2. Elliptic curve points P,
- * Q, and R can all be identical. Uses affine coordinates. */
-mp_err
-ec_GF2m_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
- const mp_int *qy, mp_int *rx, mp_int *ry,
- const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int lambda, tempx, tempy;
-
- MP_DIGITS(&lambda) = 0;
- MP_DIGITS(&tempx) = 0;
- MP_DIGITS(&tempy) = 0;
- MP_CHECKOK(mp_init(&lambda));
- MP_CHECKOK(mp_init(&tempx));
- MP_CHECKOK(mp_init(&tempy));
- /* if P = inf, then R = Q */
- if (ec_GF2m_pt_is_inf_aff(px, py) == 0) {
- MP_CHECKOK(mp_copy(qx, rx));
- MP_CHECKOK(mp_copy(qy, ry));
- res = MP_OKAY;
- goto CLEANUP;
- }
- /* if Q = inf, then R = P */
- if (ec_GF2m_pt_is_inf_aff(qx, qy) == 0) {
- MP_CHECKOK(mp_copy(px, rx));
- MP_CHECKOK(mp_copy(py, ry));
- res = MP_OKAY;
- goto CLEANUP;
- }
- /* if px != qx, then lambda = (py+qy) / (px+qx), tempx = a + lambda^2
- * + lambda + px + qx */
- if (mp_cmp(px, qx) != 0) {
- MP_CHECKOK(group->meth->field_add(py, qy, &tempy, group->meth));
- MP_CHECKOK(group->meth->field_add(px, qx, &tempx, group->meth));
- MP_CHECKOK(group->meth->
- field_div(&tempy, &tempx, &lambda, group->meth));
- MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&tempx, &lambda, &tempx, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&tempx, &group->curvea, &tempx, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&tempx, px, &tempx, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&tempx, qx, &tempx, group->meth));
- } else {
- /* if py != qy or qx = 0, then R = inf */
- if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qx) == 0)) {
- mp_zero(rx);
- mp_zero(ry);
- res = MP_OKAY;
- goto CLEANUP;
- }
- /* lambda = qx + qy / qx */
- MP_CHECKOK(group->meth->field_div(qy, qx, &lambda, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&lambda, qx, &lambda, group->meth));
- /* tempx = a + lambda^2 + lambda */
- MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&tempx, &lambda, &tempx, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&tempx, &group->curvea, &tempx, group->meth));
- }
- /* ry = (qx + tempx) * lambda + tempx + qy */
- MP_CHECKOK(group->meth->field_add(qx, &tempx, &tempy, group->meth));
- MP_CHECKOK(group->meth->
- field_mul(&tempy, &lambda, &tempy, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&tempy, &tempx, &tempy, group->meth));
- MP_CHECKOK(group->meth->field_add(&tempy, qy, ry, group->meth));
- /* rx = tempx */
- MP_CHECKOK(mp_copy(&tempx, rx));
-
- CLEANUP:
- mp_clear(&lambda);
- mp_clear(&tempx);
- mp_clear(&tempy);
- return res;
-}
-
-/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
- * identical. Uses affine coordinates. */
-mp_err
-ec_GF2m_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
- const mp_int *qy, mp_int *rx, mp_int *ry,
- const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int nqy;
-
- MP_DIGITS(&nqy) = 0;
- MP_CHECKOK(mp_init(&nqy));
- /* nqy = qx+qy */
- MP_CHECKOK(group->meth->field_add(qx, qy, &nqy, group->meth));
- MP_CHECKOK(group->point_add(px, py, qx, &nqy, rx, ry, group));
- CLEANUP:
- mp_clear(&nqy);
- return res;
-}
-
-/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
- * affine coordinates. */
-mp_err
-ec_GF2m_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, const ECGroup *group)
-{
- return group->point_add(px, py, px, py, rx, ry, group);
-}
-
-/* by default, this routine is unused and thus doesn't need to be compiled */
-#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
-/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
- * R can be identical. Uses affine coordinates. */
-mp_err
-ec_GF2m_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
- mp_int *rx, mp_int *ry, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int k, k3, qx, qy, sx, sy;
- int b1, b3, i, l;
-
- MP_DIGITS(&k) = 0;
- MP_DIGITS(&k3) = 0;
- MP_DIGITS(&qx) = 0;
- MP_DIGITS(&qy) = 0;
- MP_DIGITS(&sx) = 0;
- MP_DIGITS(&sy) = 0;
- MP_CHECKOK(mp_init(&k));
- MP_CHECKOK(mp_init(&k3));
- MP_CHECKOK(mp_init(&qx));
- MP_CHECKOK(mp_init(&qy));
- MP_CHECKOK(mp_init(&sx));
- MP_CHECKOK(mp_init(&sy));
-
- /* if n = 0 then r = inf */
- if (mp_cmp_z(n) == 0) {
- mp_zero(rx);
- mp_zero(ry);
- res = MP_OKAY;
- goto CLEANUP;
- }
- /* Q = P, k = n */
- MP_CHECKOK(mp_copy(px, &qx));
- MP_CHECKOK(mp_copy(py, &qy));
- MP_CHECKOK(mp_copy(n, &k));
- /* if n < 0 then Q = -Q, k = -k */
- if (mp_cmp_z(n) < 0) {
- MP_CHECKOK(group->meth->field_add(&qx, &qy, &qy, group->meth));
- MP_CHECKOK(mp_neg(&k, &k));
- }
-#ifdef ECL_DEBUG /* basic double and add method */
- l = mpl_significant_bits(&k) - 1;
- MP_CHECKOK(mp_copy(&qx, &sx));
- MP_CHECKOK(mp_copy(&qy, &sy));
- for (i = l - 1; i >= 0; i--) {
- /* S = 2S */
- MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
- /* if k_i = 1, then S = S + Q */
- if (mpl_get_bit(&k, i) != 0) {
- MP_CHECKOK(group->
- point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
- }
- }
-#else /* double and add/subtract method from
- * standard */
- /* k3 = 3 * k */
- MP_CHECKOK(mp_set_int(&k3, 3));
- MP_CHECKOK(mp_mul(&k, &k3, &k3));
- /* S = Q */
- MP_CHECKOK(mp_copy(&qx, &sx));
- MP_CHECKOK(mp_copy(&qy, &sy));
- /* l = index of high order bit in binary representation of 3*k */
- l = mpl_significant_bits(&k3) - 1;
- /* for i = l-1 downto 1 */
- for (i = l - 1; i >= 1; i--) {
- /* S = 2S */
- MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
- b3 = MP_GET_BIT(&k3, i);
- b1 = MP_GET_BIT(&k, i);
- /* if k3_i = 1 and k_i = 0, then S = S + Q */
- if ((b3 == 1) && (b1 == 0)) {
- MP_CHECKOK(group->
- point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
- /* if k3_i = 0 and k_i = 1, then S = S - Q */
- } else if ((b3 == 0) && (b1 == 1)) {
- MP_CHECKOK(group->
- point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
- }
- }
-#endif
- /* output S */
- MP_CHECKOK(mp_copy(&sx, rx));
- MP_CHECKOK(mp_copy(&sy, ry));
-
- CLEANUP:
- mp_clear(&k);
- mp_clear(&k3);
- mp_clear(&qx);
- mp_clear(&qy);
- mp_clear(&sx);
- mp_clear(&sy);
- return res;
-}
-#endif
-
-/* Validates a point on a GF2m curve. */
-mp_err
-ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
-{
- mp_err res = MP_NO;
- mp_int accl, accr, tmp, pxt, pyt;
-
- MP_DIGITS(&accl) = 0;
- MP_DIGITS(&accr) = 0;
- MP_DIGITS(&tmp) = 0;
- MP_DIGITS(&pxt) = 0;
- MP_DIGITS(&pyt) = 0;
- MP_CHECKOK(mp_init(&accl));
- MP_CHECKOK(mp_init(&accr));
- MP_CHECKOK(mp_init(&tmp));
- MP_CHECKOK(mp_init(&pxt));
- MP_CHECKOK(mp_init(&pyt));
-
- /* 1: Verify that publicValue is not the point at infinity */
- if (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES) {
- res = MP_NO;
- goto CLEANUP;
- }
- /* 2: Verify that the coordinates of publicValue are elements
- * of the field.
- */
- if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
- (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
- res = MP_NO;
- goto CLEANUP;
- }
- /* 3: Verify that publicValue is on the curve. */
- if (group->meth->field_enc) {
- group->meth->field_enc(px, &pxt, group->meth);
- group->meth->field_enc(py, &pyt, group->meth);
- } else {
- mp_copy(px, &pxt);
- mp_copy(py, &pyt);
- }
- /* left-hand side: y^2 + x*y */
- MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
- MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) );
- MP_CHECKOK( group->meth->field_add(&accl, &tmp, &accl, group->meth) );
- /* right-hand side: x^3 + a*x^2 + b */
- MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
- MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
- MP_CHECKOK( group->meth->field_mul(&group->curvea, &tmp, &tmp, group->meth) );
- MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
- MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
- /* check LHS - RHS == 0 */
- MP_CHECKOK( group->meth->field_add(&accl, &accr, &accr, group->meth) );
- if (mp_cmp_z(&accr) != 0) {
- res = MP_NO;
- goto CLEANUP;
- }
- /* 4: Verify that the order of the curve times the publicValue
- * is the point at infinity.
- */
- MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
- if (ec_GF2m_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
- res = MP_NO;
- goto CLEANUP;
- }
-
- res = MP_YES;
-
-CLEANUP:
- mp_clear(&accl);
- mp_clear(&accr);
- mp_clear(&tmp);
- mp_clear(&pxt);
- mp_clear(&pyt);
- return res;
-}
diff --git a/security/nss/lib/freebl/ecl/ec2_mont.c b/security/nss/lib/freebl/ecl/ec2_mont.c
deleted file mode 100644
index 8d35f259b..000000000
--- a/security/nss/lib/freebl/ecl/ec2_mont.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ec2.h"
-#include "mplogic.h"
-#include "mp_gf2m.h"
-#include <stdlib.h>
-
-/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery
- * projective coordinates. Uses algorithm Mdouble in appendix of Lopez, J.
- * and Dahab, R. "Fast multiplication on elliptic curves over GF(2^m)
- * without precomputation". modified to not require precomputation of
- * c=b^{2^{m-1}}. */
-static mp_err
-gf2m_Mdouble(mp_int *x, mp_int *z, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int t1;
-
- MP_DIGITS(&t1) = 0;
- MP_CHECKOK(mp_init(&t1));
-
- MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
- MP_CHECKOK(group->meth->field_sqr(z, &t1, group->meth));
- MP_CHECKOK(group->meth->field_mul(x, &t1, z, group->meth));
- MP_CHECKOK(group->meth->field_sqr(x, x, group->meth));
- MP_CHECKOK(group->meth->field_sqr(&t1, &t1, group->meth));
- MP_CHECKOK(group->meth->
- field_mul(&group->curveb, &t1, &t1, group->meth));
- MP_CHECKOK(group->meth->field_add(x, &t1, x, group->meth));
-
- CLEANUP:
- mp_clear(&t1);
- return res;
-}
-
-/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in
- * Montgomery projective coordinates. Uses algorithm Madd in appendix of
- * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
- * GF(2^m) without precomputation". */
-static mp_err
-gf2m_Madd(const mp_int *x, mp_int *x1, mp_int *z1, mp_int *x2, mp_int *z2,
- const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int t1, t2;
-
- MP_DIGITS(&t1) = 0;
- MP_DIGITS(&t2) = 0;
- MP_CHECKOK(mp_init(&t1));
- MP_CHECKOK(mp_init(&t2));
-
- MP_CHECKOK(mp_copy(x, &t1));
- MP_CHECKOK(group->meth->field_mul(x1, z2, x1, group->meth));
- MP_CHECKOK(group->meth->field_mul(z1, x2, z1, group->meth));
- MP_CHECKOK(group->meth->field_mul(x1, z1, &t2, group->meth));
- MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
- MP_CHECKOK(group->meth->field_sqr(z1, z1, group->meth));
- MP_CHECKOK(group->meth->field_mul(z1, &t1, x1, group->meth));
- MP_CHECKOK(group->meth->field_add(x1, &t2, x1, group->meth));
-
- CLEANUP:
- mp_clear(&t1);
- mp_clear(&t2);
- return res;
-}
-
-/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
- * using Montgomery point multiplication algorithm Mxy() in appendix of
- * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
- * GF(2^m) without precomputation". Returns: 0 on error 1 if return value
- * should be the point at infinity 2 otherwise */
-static int
-gf2m_Mxy(const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1,
- mp_int *x2, mp_int *z2, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- int ret = 0;
- mp_int t3, t4, t5;
-
- MP_DIGITS(&t3) = 0;
- MP_DIGITS(&t4) = 0;
- MP_DIGITS(&t5) = 0;
- MP_CHECKOK(mp_init(&t3));
- MP_CHECKOK(mp_init(&t4));
- MP_CHECKOK(mp_init(&t5));
-
- if (mp_cmp_z(z1) == 0) {
- mp_zero(x2);
- mp_zero(z2);
- ret = 1;
- goto CLEANUP;
- }
-
- if (mp_cmp_z(z2) == 0) {
- MP_CHECKOK(mp_copy(x, x2));
- MP_CHECKOK(group->meth->field_add(x, y, z2, group->meth));
- ret = 2;
- goto CLEANUP;
- }
-
- MP_CHECKOK(mp_set_int(&t5, 1));
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->field_enc(&t5, &t5, group->meth));
- }
-
- MP_CHECKOK(group->meth->field_mul(z1, z2, &t3, group->meth));
-
- MP_CHECKOK(group->meth->field_mul(z1, x, z1, group->meth));
- MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
- MP_CHECKOK(group->meth->field_mul(z2, x, z2, group->meth));
- MP_CHECKOK(group->meth->field_mul(z2, x1, x1, group->meth));
- MP_CHECKOK(group->meth->field_add(z2, x2, z2, group->meth));
-
- MP_CHECKOK(group->meth->field_mul(z2, z1, z2, group->meth));
- MP_CHECKOK(group->meth->field_sqr(x, &t4, group->meth));
- MP_CHECKOK(group->meth->field_add(&t4, y, &t4, group->meth));
- MP_CHECKOK(group->meth->field_mul(&t4, &t3, &t4, group->meth));
- MP_CHECKOK(group->meth->field_add(&t4, z2, &t4, group->meth));
-
- MP_CHECKOK(group->meth->field_mul(&t3, x, &t3, group->meth));
- MP_CHECKOK(group->meth->field_div(&t5, &t3, &t3, group->meth));
- MP_CHECKOK(group->meth->field_mul(&t3, &t4, &t4, group->meth));
- MP_CHECKOK(group->meth->field_mul(x1, &t3, x2, group->meth));
- MP_CHECKOK(group->meth->field_add(x2, x, z2, group->meth));
-
- MP_CHECKOK(group->meth->field_mul(z2, &t4, z2, group->meth));
- MP_CHECKOK(group->meth->field_add(z2, y, z2, group->meth));
-
- ret = 2;
-
- CLEANUP:
- mp_clear(&t3);
- mp_clear(&t4);
- mp_clear(&t5);
- if (res == MP_OKAY) {
- return ret;
- } else {
- return 0;
- }
-}
-
-/* Computes R = nP based on algorithm 2P of Lopex, J. and Dahab, R. "Fast
- * multiplication on elliptic curves over GF(2^m) without
- * precomputation". Elliptic curve points P and R can be identical. Uses
- * Montgomery projective coordinates. */
-mp_err
-ec_GF2m_pt_mul_mont(const mp_int *n, const mp_int *px, const mp_int *py,
- mp_int *rx, mp_int *ry, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int x1, x2, z1, z2;
- int i, j;
- mp_digit top_bit, mask;
-
- MP_DIGITS(&x1) = 0;
- MP_DIGITS(&x2) = 0;
- MP_DIGITS(&z1) = 0;
- MP_DIGITS(&z2) = 0;
- MP_CHECKOK(mp_init(&x1));
- MP_CHECKOK(mp_init(&x2));
- MP_CHECKOK(mp_init(&z1));
- MP_CHECKOK(mp_init(&z2));
-
- /* if result should be point at infinity */
- if ((mp_cmp_z(n) == 0) || (ec_GF2m_pt_is_inf_aff(px, py) == MP_YES)) {
- MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
- goto CLEANUP;
- }
-
- MP_CHECKOK(mp_copy(px, &x1)); /* x1 = px */
- MP_CHECKOK(mp_set_int(&z1, 1)); /* z1 = 1 */
- MP_CHECKOK(group->meth->field_sqr(&x1, &z2, group->meth)); /* z2 =
- * x1^2 =
- * px^2 */
- MP_CHECKOK(group->meth->field_sqr(&z2, &x2, group->meth));
- MP_CHECKOK(group->meth->field_add(&x2, &group->curveb, &x2, group->meth)); /* x2
- * =
- * px^4
- * +
- * b
- */
-
- /* find top-most bit and go one past it */
- i = MP_USED(n) - 1;
- j = MP_DIGIT_BIT - 1;
- top_bit = 1;
- top_bit <<= MP_DIGIT_BIT - 1;
- mask = top_bit;
- while (!(MP_DIGITS(n)[i] & mask)) {
- mask >>= 1;
- j--;
- }
- mask >>= 1;
- j--;
-
- /* if top most bit was at word break, go to next word */
- if (!mask) {
- i--;
- j = MP_DIGIT_BIT - 1;
- mask = top_bit;
- }
-
- for (; i >= 0; i--) {
- for (; j >= 0; j--) {
- if (MP_DIGITS(n)[i] & mask) {
- MP_CHECKOK(gf2m_Madd(px, &x1, &z1, &x2, &z2, group));
- MP_CHECKOK(gf2m_Mdouble(&x2, &z2, group));
- } else {
- MP_CHECKOK(gf2m_Madd(px, &x2, &z2, &x1, &z1, group));
- MP_CHECKOK(gf2m_Mdouble(&x1, &z1, group));
- }
- mask >>= 1;
- }
- j = MP_DIGIT_BIT - 1;
- mask = top_bit;
- }
-
- /* convert out of "projective" coordinates */
- i = gf2m_Mxy(px, py, &x1, &z1, &x2, &z2, group);
- if (i == 0) {
- res = MP_BADARG;
- goto CLEANUP;
- } else if (i == 1) {
- MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
- } else {
- MP_CHECKOK(mp_copy(&x2, rx));
- MP_CHECKOK(mp_copy(&z2, ry));
- }
-
- CLEANUP:
- mp_clear(&x1);
- mp_clear(&x2);
- mp_clear(&z1);
- mp_clear(&z2);
- return res;
-}
diff --git a/security/nss/lib/freebl/ecl/ec2_proj.c b/security/nss/lib/freebl/ecl/ec2_proj.c
deleted file mode 100644
index 937898244..000000000
--- a/security/nss/lib/freebl/ecl/ec2_proj.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ec2.h"
-#include "mplogic.h"
-#include "mp_gf2m.h"
-#include <stdlib.h>
-#ifdef ECL_DEBUG
-#include <assert.h>
-#endif
-
-/* by default, these routines are unused and thus don't need to be compiled */
-#ifdef ECL_ENABLE_GF2M_PROJ
-/* Converts a point P(px, py) from affine coordinates to projective
- * coordinates R(rx, ry, rz). Assumes input is already field-encoded using
- * field_enc, and returns output that is still field-encoded. */
-mp_err
-ec_GF2m_pt_aff2proj(const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, mp_int *rz, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_copy(px, rx));
- MP_CHECKOK(mp_copy(py, ry));
- MP_CHECKOK(mp_set_int(rz, 1));
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
- }
- CLEANUP:
- return res;
-}
-
-/* Converts a point P(px, py, pz) from projective coordinates to affine
- * coordinates R(rx, ry). P and R can share x and y coordinates. Assumes
- * input is already field-encoded using field_enc, and returns output that
- * is still field-encoded. */
-mp_err
-ec_GF2m_pt_proj2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
- mp_int *rx, mp_int *ry, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int z1, z2;
-
- MP_DIGITS(&z1) = 0;
- MP_DIGITS(&z2) = 0;
- MP_CHECKOK(mp_init(&z1));
- MP_CHECKOK(mp_init(&z2));
-
- /* if point at infinity, then set point at infinity and exit */
- if (ec_GF2m_pt_is_inf_proj(px, py, pz) == MP_YES) {
- MP_CHECKOK(ec_GF2m_pt_set_inf_aff(rx, ry));
- goto CLEANUP;
- }
-
- /* transform (px, py, pz) into (px / pz, py / pz^2) */
- if (mp_cmp_d(pz, 1) == 0) {
- MP_CHECKOK(mp_copy(px, rx));
- MP_CHECKOK(mp_copy(py, ry));
- } else {
- MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
- MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
- MP_CHECKOK(group->meth->field_mul(px, &z1, rx, group->meth));
- MP_CHECKOK(group->meth->field_mul(py, &z2, ry, group->meth));
- }
-
- CLEANUP:
- mp_clear(&z1);
- mp_clear(&z2);
- return res;
-}
-
-/* Checks if point P(px, py, pz) is at infinity. Uses projective
- * coordinates. */
-mp_err
-ec_GF2m_pt_is_inf_proj(const mp_int *px, const mp_int *py,
- const mp_int *pz)
-{
- return mp_cmp_z(pz);
-}
-
-/* Sets P(px, py, pz) to be the point at infinity. Uses projective
- * coordinates. */
-mp_err
-ec_GF2m_pt_set_inf_proj(mp_int *px, mp_int *py, mp_int *pz)
-{
- mp_zero(pz);
- return MP_OKAY;
-}
-
-/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
- * (qx, qy, 1). Elliptic curve points P, Q, and R can all be identical.
- * Uses mixed projective-affine coordinates. Assumes input is already
- * field-encoded using field_enc, and returns output that is still
- * field-encoded. Uses equation (3) from Hankerson, Hernandez, Menezes.
- * Software Implementation of Elliptic Curve Cryptography Over Binary
- * Fields. */
-mp_err
-ec_GF2m_pt_add_proj(const mp_int *px, const mp_int *py, const mp_int *pz,
- const mp_int *qx, const mp_int *qy, mp_int *rx,
- mp_int *ry, mp_int *rz, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int A, B, C, D, E, F, G;
-
- /* If either P or Q is the point at infinity, then return the other
- * point */
- if (ec_GF2m_pt_is_inf_proj(px, py, pz) == MP_YES) {
- return ec_GF2m_pt_aff2proj(qx, qy, rx, ry, rz, group);
- }
- if (ec_GF2m_pt_is_inf_aff(qx, qy) == MP_YES) {
- MP_CHECKOK(mp_copy(px, rx));
- MP_CHECKOK(mp_copy(py, ry));
- return mp_copy(pz, rz);
- }
-
- MP_DIGITS(&A) = 0;
- MP_DIGITS(&B) = 0;
- MP_DIGITS(&C) = 0;
- MP_DIGITS(&D) = 0;
- MP_DIGITS(&E) = 0;
- MP_DIGITS(&F) = 0;
- MP_DIGITS(&G) = 0;
- MP_CHECKOK(mp_init(&A));
- MP_CHECKOK(mp_init(&B));
- MP_CHECKOK(mp_init(&C));
- MP_CHECKOK(mp_init(&D));
- MP_CHECKOK(mp_init(&E));
- MP_CHECKOK(mp_init(&F));
- MP_CHECKOK(mp_init(&G));
-
- /* D = pz^2 */
- MP_CHECKOK(group->meth->field_sqr(pz, &D, group->meth));
-
- /* A = qy * pz^2 + py */
- MP_CHECKOK(group->meth->field_mul(qy, &D, &A, group->meth));
- MP_CHECKOK(group->meth->field_add(&A, py, &A, group->meth));
-
- /* B = qx * pz + px */
- MP_CHECKOK(group->meth->field_mul(qx, pz, &B, group->meth));
- MP_CHECKOK(group->meth->field_add(&B, px, &B, group->meth));
-
- /* C = pz * B */
- MP_CHECKOK(group->meth->field_mul(pz, &B, &C, group->meth));
-
- /* D = B^2 * (C + a * pz^2) (using E as a temporary variable) */
- MP_CHECKOK(group->meth->
- field_mul(&group->curvea, &D, &D, group->meth));
- MP_CHECKOK(group->meth->field_add(&C, &D, &D, group->meth));
- MP_CHECKOK(group->meth->field_sqr(&B, &E, group->meth));
- MP_CHECKOK(group->meth->field_mul(&E, &D, &D, group->meth));
-
- /* rz = C^2 */
- MP_CHECKOK(group->meth->field_sqr(&C, rz, group->meth));
-
- /* E = A * C */
- MP_CHECKOK(group->meth->field_mul(&A, &C, &E, group->meth));
-
- /* rx = A^2 + D + E */
- MP_CHECKOK(group->meth->field_sqr(&A, rx, group->meth));
- MP_CHECKOK(group->meth->field_add(rx, &D, rx, group->meth));
- MP_CHECKOK(group->meth->field_add(rx, &E, rx, group->meth));
-
- /* F = rx + qx * rz */
- MP_CHECKOK(group->meth->field_mul(qx, rz, &F, group->meth));
- MP_CHECKOK(group->meth->field_add(rx, &F, &F, group->meth));
-
- /* G = rx + qy * rz */
- MP_CHECKOK(group->meth->field_mul(qy, rz, &G, group->meth));
- MP_CHECKOK(group->meth->field_add(rx, &G, &G, group->meth));
-
- /* ry = E * F + rz * G (using G as a temporary variable) */
- MP_CHECKOK(group->meth->field_mul(rz, &G, &G, group->meth));
- MP_CHECKOK(group->meth->field_mul(&E, &F, ry, group->meth));
- MP_CHECKOK(group->meth->field_add(ry, &G, ry, group->meth));
-
- CLEANUP:
- mp_clear(&A);
- mp_clear(&B);
- mp_clear(&C);
- mp_clear(&D);
- mp_clear(&E);
- mp_clear(&F);
- mp_clear(&G);
- return res;
-}
-
-/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
- * projective coordinates.
- *
- * Assumes input is already field-encoded using field_enc, and returns
- * output that is still field-encoded.
- *
- * Uses equation (3) from Hankerson, Hernandez, Menezes. Software
- * Implementation of Elliptic Curve Cryptography Over Binary Fields.
- */
-mp_err
-ec_GF2m_pt_dbl_proj(const mp_int *px, const mp_int *py, const mp_int *pz,
- mp_int *rx, mp_int *ry, mp_int *rz,
- const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int t0, t1;
-
- if (ec_GF2m_pt_is_inf_proj(px, py, pz) == MP_YES) {
- return ec_GF2m_pt_set_inf_proj(rx, ry, rz);
- }
-
- MP_DIGITS(&t0) = 0;
- MP_DIGITS(&t1) = 0;
- MP_CHECKOK(mp_init(&t0));
- MP_CHECKOK(mp_init(&t1));
-
- /* t0 = px^2 */
- /* t1 = pz^2 */
- MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
- MP_CHECKOK(group->meth->field_sqr(pz, &t1, group->meth));
-
- /* rz = px^2 * pz^2 */
- MP_CHECKOK(group->meth->field_mul(&t0, &t1, rz, group->meth));
-
- /* t0 = px^4 */
- /* t1 = b * pz^4 */
- MP_CHECKOK(group->meth->field_sqr(&t0, &t0, group->meth));
- MP_CHECKOK(group->meth->field_sqr(&t1, &t1, group->meth));
- MP_CHECKOK(group->meth->
- field_mul(&group->curveb, &t1, &t1, group->meth));
-
- /* rx = px^4 + b * pz^4 */
- MP_CHECKOK(group->meth->field_add(&t0, &t1, rx, group->meth));
-
- /* ry = b * pz^4 * rz + rx * (a * rz + py^2 + b * pz^4) */
- MP_CHECKOK(group->meth->field_sqr(py, ry, group->meth));
- MP_CHECKOK(group->meth->field_add(ry, &t1, ry, group->meth));
- /* t0 = a * rz */
- MP_CHECKOK(group->meth->
- field_mul(&group->curvea, rz, &t0, group->meth));
- MP_CHECKOK(group->meth->field_add(&t0, ry, ry, group->meth));
- MP_CHECKOK(group->meth->field_mul(rx, ry, ry, group->meth));
- /* t1 = b * pz^4 * rz */
- MP_CHECKOK(group->meth->field_mul(&t1, rz, &t1, group->meth));
- MP_CHECKOK(group->meth->field_add(&t1, ry, ry, group->meth));
-
- CLEANUP:
- mp_clear(&t0);
- mp_clear(&t1);
- return res;
-}
-
-/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
- * a, b and p are the elliptic curve coefficients and the prime that
- * determines the field GF2m. Elliptic curve points P and R can be
- * identical. Uses mixed projective-affine coordinates. Assumes input is
- * already field-encoded using field_enc, and returns output that is still
- * field-encoded. Uses 4-bit window method. */
-mp_err
-ec_GF2m_pt_mul_proj(const mp_int *n, const mp_int *px, const mp_int *py,
- mp_int *rx, mp_int *ry, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int precomp[16][2], rz;
- mp_digit precomp_arr[ECL_MAX_FIELD_SIZE_DIGITS * 16 * 2], *t;
- int i, ni, d;
-
- ARGCHK(group != NULL, MP_BADARG);
- ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
-
- /* initialize precomputation table */
- t = precomp_arr;
- for (i = 0; i < 16; i++) {
- /* x co-ord */
- MP_SIGN(&precomp[i][0]) = MP_ZPOS;
- MP_ALLOC(&precomp[i][0]) = ECL_MAX_FIELD_SIZE_DIGITS;
- MP_USED(&precomp[i][0]) = 1;
- *t = 0;
- MP_DIGITS(&precomp[i][0]) = t;
- t += ECL_MAX_FIELD_SIZE_DIGITS;
- /* y co-ord */
- MP_SIGN(&precomp[i][1]) = MP_ZPOS;
- MP_ALLOC(&precomp[i][1]) = ECL_MAX_FIELD_SIZE_DIGITS;
- MP_USED(&precomp[i][1]) = 1;
- *t = 0;
- MP_DIGITS(&precomp[i][1]) = t;
- t += ECL_MAX_FIELD_SIZE_DIGITS;
- }
-
- /* fill precomputation table */
- mp_zero(&precomp[0][0]);
- mp_zero(&precomp[0][1]);
- MP_CHECKOK(mp_copy(px, &precomp[1][0]));
- MP_CHECKOK(mp_copy(py, &precomp[1][1]));
- for (i = 2; i < 16; i++) {
- MP_CHECKOK(group->
- point_add(&precomp[1][0], &precomp[1][1],
- &precomp[i - 1][0], &precomp[i - 1][1],
- &precomp[i][0], &precomp[i][1], group));
- }
-
- d = (mpl_significant_bits(n) + 3) / 4;
-
- /* R = inf */
- MP_DIGITS(&rz) = 0;
- MP_CHECKOK(mp_init(&rz));
- MP_CHECKOK(ec_GF2m_pt_set_inf_proj(rx, ry, &rz));
-
- for (i = d - 1; i >= 0; i--) {
- /* compute window ni */
- ni = MP_GET_BIT(n, 4 * i + 3);
- ni <<= 1;
- ni |= MP_GET_BIT(n, 4 * i + 2);
- ni <<= 1;
- ni |= MP_GET_BIT(n, 4 * i + 1);
- ni <<= 1;
- ni |= MP_GET_BIT(n, 4 * i);
- /* R = 2^4 * R */
- MP_CHECKOK(ec_GF2m_pt_dbl_proj(rx, ry, &rz, rx, ry, &rz, group));
- MP_CHECKOK(ec_GF2m_pt_dbl_proj(rx, ry, &rz, rx, ry, &rz, group));
- MP_CHECKOK(ec_GF2m_pt_dbl_proj(rx, ry, &rz, rx, ry, &rz, group));
- MP_CHECKOK(ec_GF2m_pt_dbl_proj(rx, ry, &rz, rx, ry, &rz, group));
- /* R = R + (ni * P) */
- MP_CHECKOK(ec_GF2m_pt_add_proj
- (rx, ry, &rz, &precomp[ni][0], &precomp[ni][1], rx, ry,
- &rz, group));
- }
-
- /* convert result S to affine coordinates */
- MP_CHECKOK(ec_GF2m_pt_proj2aff(rx, ry, &rz, rx, ry, group));
-
- CLEANUP:
- mp_clear(&rz);
- return res;
-}
-#endif
diff --git a/security/nss/lib/freebl/ecl/ec_naf.c b/security/nss/lib/freebl/ecl/ec_naf.c
deleted file mode 100644
index 3db6f300f..000000000
--- a/security/nss/lib/freebl/ecl/ec_naf.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecl-priv.h"
-
-/* Returns 2^e as an integer. This is meant to be used for small powers of
- * two. */
-int
-ec_twoTo(int e)
-{
- int a = 1;
- int i;
-
- for (i = 0; i < e; i++) {
- a *= 2;
- }
- return a;
-}
-
-/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
- * be an array of signed char's to output to, bitsize should be the number
- * of bits of out, in is the original scalar, and w is the window size.
- * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
- * Menezes, "Software implementation of elliptic curve cryptography over
- * binary fields", Proc. CHES 2000. */
-mp_err
-ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in, int w)
-{
- mp_int k;
- mp_err res = MP_OKAY;
- int i, twowm1, mask;
-
- twowm1 = ec_twoTo(w - 1);
- mask = 2 * twowm1 - 1;
-
- MP_DIGITS(&k) = 0;
- MP_CHECKOK(mp_init_copy(&k, in));
-
- i = 0;
- /* Compute wNAF form */
- while (mp_cmp_z(&k) > 0) {
- if (mp_isodd(&k)) {
- out[i] = MP_DIGIT(&k, 0) & mask;
- if (out[i] >= twowm1)
- out[i] -= 2 * twowm1;
-
- /* Subtract off out[i]. Note mp_sub_d only works with
- * unsigned digits */
- if (out[i] >= 0) {
- mp_sub_d(&k, out[i], &k);
- } else {
- mp_add_d(&k, -(out[i]), &k);
- }
- } else {
- out[i] = 0;
- }
- mp_div_2(&k, &k);
- i++;
- }
- /* Zero out the remaining elements of the out array. */
- for (; i < bitsize + 1; i++) {
- out[i] = 0;
- }
- CLEANUP:
- mp_clear(&k);
- return res;
-
-}
diff --git a/security/nss/lib/freebl/ecl/ecl-curve.h b/security/nss/lib/freebl/ecl/ecl-curve.h
deleted file mode 100644
index d81d6dfdc..000000000
--- a/security/nss/lib/freebl/ecl/ecl-curve.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecl-exp.h"
-#include <stdlib.h>
-
-#ifndef __ecl_curve_h_
-#define __ecl_curve_h_
-
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
-#error This source file is for Basic ECC only .
-#endif
-
-static const ECCurveParams ecCurve_NIST_P256 = {
- "NIST-P256", ECField_GFp, 256,
- "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
- "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
- "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
- "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
- "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
- "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 1
-};
-
-static const ECCurveParams ecCurve_NIST_P384 = {
- "NIST-P384", ECField_GFp, 384,
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
- "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
- "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
- "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
- "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
- 1
-};
-
-static const ECCurveParams ecCurve_NIST_P521 = {
- "NIST-P521", ECField_GFp, 521,
- "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
- "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
- "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
- "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
- "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
- "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
- 1
-};
-
-/* mapping between ECCurveName enum and pointers to ECCurveParams */
-static const ECCurveParams *ecCurve_map[] = {
- NULL, /* ECCurve_noName */
- NULL, /* ECCurve_NIST_P192 */
- NULL, /* ECCurve_NIST_P224 */
- &ecCurve_NIST_P256, /* ECCurve_NIST_P256 */
- &ecCurve_NIST_P384, /* ECCurve_NIST_P384 */
- &ecCurve_NIST_P521, /* ECCurve_NIST_P521 */
- NULL, /* ECCurve_NIST_K163 */
- NULL, /* ECCurve_NIST_B163 */
- NULL, /* ECCurve_NIST_K233 */
- NULL, /* ECCurve_NIST_B233 */
- NULL, /* ECCurve_NIST_K283 */
- NULL, /* ECCurve_NIST_B283 */
- NULL, /* ECCurve_NIST_K409 */
- NULL, /* ECCurve_NIST_B409 */
- NULL, /* ECCurve_NIST_K571 */
- NULL, /* ECCurve_NIST_B571 */
- NULL, /* ECCurve_X9_62_PRIME_192V2 */
- NULL, /* ECCurve_X9_62_PRIME_192V3 */
- NULL, /* ECCurve_X9_62_PRIME_239V1 */
- NULL, /* ECCurve_X9_62_PRIME_239V2 */
- NULL, /* ECCurve_X9_62_PRIME_239V3 */
- NULL, /* ECCurve_X9_62_CHAR2_PNB163V1 */
- NULL, /* ECCurve_X9_62_CHAR2_PNB163V2 */
- NULL, /* ECCurve_X9_62_CHAR2_PNB163V3 */
- NULL, /* ECCurve_X9_62_CHAR2_PNB176V1 */
- NULL, /* ECCurve_X9_62_CHAR2_TNB191V1 */
- NULL, /* ECCurve_X9_62_CHAR2_TNB191V2 */
- NULL, /* ECCurve_X9_62_CHAR2_TNB191V3 */
- NULL, /* ECCurve_X9_62_CHAR2_PNB208W1 */
- NULL, /* ECCurve_X9_62_CHAR2_TNB239V1 */
- NULL, /* ECCurve_X9_62_CHAR2_TNB239V2 */
- NULL, /* ECCurve_X9_62_CHAR2_TNB239V3 */
- NULL, /* ECCurve_X9_62_CHAR2_PNB272W1 */
- NULL, /* ECCurve_X9_62_CHAR2_PNB304W1 */
- NULL, /* ECCurve_X9_62_CHAR2_TNB359V1 */
- NULL, /* ECCurve_X9_62_CHAR2_PNB368W1 */
- NULL, /* ECCurve_X9_62_CHAR2_TNB431R1 */
- NULL, /* ECCurve_SECG_PRIME_112R1 */
- NULL, /* ECCurve_SECG_PRIME_112R2 */
- NULL, /* ECCurve_SECG_PRIME_128R1 */
- NULL, /* ECCurve_SECG_PRIME_128R2 */
- NULL, /* ECCurve_SECG_PRIME_160K1 */
- NULL, /* ECCurve_SECG_PRIME_160R1 */
- NULL, /* ECCurve_SECG_PRIME_160R2 */
- NULL, /* ECCurve_SECG_PRIME_192K1 */
- NULL, /* ECCurve_SECG_PRIME_224K1 */
- NULL, /* ECCurve_SECG_PRIME_256K1 */
- NULL, /* ECCurve_SECG_CHAR2_113R1 */
- NULL, /* ECCurve_SECG_CHAR2_113R2 */
- NULL, /* ECCurve_SECG_CHAR2_131R1 */
- NULL, /* ECCurve_SECG_CHAR2_131R2 */
- NULL, /* ECCurve_SECG_CHAR2_163R1 */
- NULL, /* ECCurve_SECG_CHAR2_193R1 */
- NULL, /* ECCurve_SECG_CHAR2_193R2 */
- NULL, /* ECCurve_SECG_CHAR2_239K1 */
- NULL, /* ECCurve_WTLS_1 */
- NULL, /* ECCurve_WTLS_8 */
- NULL, /* ECCurve_WTLS_9 */
- NULL /* ECCurve_pastLastCurve */
-};
-
-#endif
diff --git a/security/nss/lib/freebl/ecl/ecl-exp.h b/security/nss/lib/freebl/ecl/ecl-exp.h
deleted file mode 100644
index b79eb3087..000000000
--- a/security/nss/lib/freebl/ecl/ecl-exp.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __ecl_exp_h_
-#define __ecl_exp_h_
-
-/* Curve field type */
-typedef enum {
- ECField_GFp,
- ECField_GF2m
-} ECField;
-
-/* Hexadecimal encoding of curve parameters */
-struct ECCurveParamsStr {
- char *text;
- ECField field;
- unsigned int size;
- char *irr;
- char *curvea;
- char *curveb;
- char *genx;
- char *geny;
- char *order;
- int cofactor;
-};
-typedef struct ECCurveParamsStr ECCurveParams;
-
-/* Named curve parameters */
-typedef enum {
-
- ECCurve_noName = 0,
-
- /* NIST prime curves */
- ECCurve_NIST_P192,
- ECCurve_NIST_P224,
- ECCurve_NIST_P256,
- ECCurve_NIST_P384,
- ECCurve_NIST_P521,
-
- /* NIST binary curves */
- ECCurve_NIST_K163,
- ECCurve_NIST_B163,
- ECCurve_NIST_K233,
- ECCurve_NIST_B233,
- ECCurve_NIST_K283,
- ECCurve_NIST_B283,
- ECCurve_NIST_K409,
- ECCurve_NIST_B409,
- ECCurve_NIST_K571,
- ECCurve_NIST_B571,
-
- /* ANSI X9.62 prime curves */
- /* ECCurve_X9_62_PRIME_192V1 == ECCurve_NIST_P192 */
- ECCurve_X9_62_PRIME_192V2,
- ECCurve_X9_62_PRIME_192V3,
- ECCurve_X9_62_PRIME_239V1,
- ECCurve_X9_62_PRIME_239V2,
- ECCurve_X9_62_PRIME_239V3,
- /* ECCurve_X9_62_PRIME_256V1 == ECCurve_NIST_P256 */
-
- /* ANSI X9.62 binary curves */
- ECCurve_X9_62_CHAR2_PNB163V1,
- ECCurve_X9_62_CHAR2_PNB163V2,
- ECCurve_X9_62_CHAR2_PNB163V3,
- ECCurve_X9_62_CHAR2_PNB176V1,
- ECCurve_X9_62_CHAR2_TNB191V1,
- ECCurve_X9_62_CHAR2_TNB191V2,
- ECCurve_X9_62_CHAR2_TNB191V3,
- ECCurve_X9_62_CHAR2_PNB208W1,
- ECCurve_X9_62_CHAR2_TNB239V1,
- ECCurve_X9_62_CHAR2_TNB239V2,
- ECCurve_X9_62_CHAR2_TNB239V3,
- ECCurve_X9_62_CHAR2_PNB272W1,
- ECCurve_X9_62_CHAR2_PNB304W1,
- ECCurve_X9_62_CHAR2_TNB359V1,
- ECCurve_X9_62_CHAR2_PNB368W1,
- ECCurve_X9_62_CHAR2_TNB431R1,
-
- /* SEC2 prime curves */
- ECCurve_SECG_PRIME_112R1,
- ECCurve_SECG_PRIME_112R2,
- ECCurve_SECG_PRIME_128R1,
- ECCurve_SECG_PRIME_128R2,
- ECCurve_SECG_PRIME_160K1,
- ECCurve_SECG_PRIME_160R1,
- ECCurve_SECG_PRIME_160R2,
- ECCurve_SECG_PRIME_192K1,
- /* ECCurve_SECG_PRIME_192R1 == ECCurve_NIST_P192 */
- ECCurve_SECG_PRIME_224K1,
- /* ECCurve_SECG_PRIME_224R1 == ECCurve_NIST_P224 */
- ECCurve_SECG_PRIME_256K1,
- /* ECCurve_SECG_PRIME_256R1 == ECCurve_NIST_P256 */
- /* ECCurve_SECG_PRIME_384R1 == ECCurve_NIST_P384 */
- /* ECCurve_SECG_PRIME_521R1 == ECCurve_NIST_P521 */
-
- /* SEC2 binary curves */
- ECCurve_SECG_CHAR2_113R1,
- ECCurve_SECG_CHAR2_113R2,
- ECCurve_SECG_CHAR2_131R1,
- ECCurve_SECG_CHAR2_131R2,
- /* ECCurve_SECG_CHAR2_163K1 == ECCurve_NIST_K163 */
- ECCurve_SECG_CHAR2_163R1,
- /* ECCurve_SECG_CHAR2_163R2 == ECCurve_NIST_B163 */
- ECCurve_SECG_CHAR2_193R1,
- ECCurve_SECG_CHAR2_193R2,
- /* ECCurve_SECG_CHAR2_233K1 == ECCurve_NIST_K233 */
- /* ECCurve_SECG_CHAR2_233R1 == ECCurve_NIST_B233 */
- ECCurve_SECG_CHAR2_239K1,
- /* ECCurve_SECG_CHAR2_283K1 == ECCurve_NIST_K283 */
- /* ECCurve_SECG_CHAR2_283R1 == ECCurve_NIST_B283 */
- /* ECCurve_SECG_CHAR2_409K1 == ECCurve_NIST_K409 */
- /* ECCurve_SECG_CHAR2_409R1 == ECCurve_NIST_B409 */
- /* ECCurve_SECG_CHAR2_571K1 == ECCurve_NIST_K571 */
- /* ECCurve_SECG_CHAR2_571R1 == ECCurve_NIST_B571 */
-
- /* WTLS curves */
- ECCurve_WTLS_1,
- /* there is no WTLS 2 curve */
- /* ECCurve_WTLS_3 == ECCurve_NIST_K163 */
- /* ECCurve_WTLS_4 == ECCurve_SECG_CHAR2_113R1 */
- /* ECCurve_WTLS_5 == ECCurve_X9_62_CHAR2_PNB163V1 */
- /* ECCurve_WTLS_6 == ECCurve_SECG_PRIME_112R1 */
- /* ECCurve_WTLS_7 == ECCurve_SECG_PRIME_160R1 */
- ECCurve_WTLS_8,
- ECCurve_WTLS_9,
- /* ECCurve_WTLS_10 == ECCurve_NIST_K233 */
- /* ECCurve_WTLS_11 == ECCurve_NIST_B233 */
- /* ECCurve_WTLS_12 == ECCurve_NIST_P224 */
-
- ECCurve_pastLastCurve
-} ECCurveName;
-
-/* Aliased named curves */
-
-#define ECCurve_X9_62_PRIME_192V1 ECCurve_NIST_P192
-#define ECCurve_X9_62_PRIME_256V1 ECCurve_NIST_P256
-#define ECCurve_SECG_PRIME_192R1 ECCurve_NIST_P192
-#define ECCurve_SECG_PRIME_224R1 ECCurve_NIST_P224
-#define ECCurve_SECG_PRIME_256R1 ECCurve_NIST_P256
-#define ECCurve_SECG_PRIME_384R1 ECCurve_NIST_P384
-#define ECCurve_SECG_PRIME_521R1 ECCurve_NIST_P521
-#define ECCurve_SECG_CHAR2_163K1 ECCurve_NIST_K163
-#define ECCurve_SECG_CHAR2_163R2 ECCurve_NIST_B163
-#define ECCurve_SECG_CHAR2_233K1 ECCurve_NIST_K233
-#define ECCurve_SECG_CHAR2_233R1 ECCurve_NIST_B233
-#define ECCurve_SECG_CHAR2_283K1 ECCurve_NIST_K283
-#define ECCurve_SECG_CHAR2_283R1 ECCurve_NIST_B283
-#define ECCurve_SECG_CHAR2_409K1 ECCurve_NIST_K409
-#define ECCurve_SECG_CHAR2_409R1 ECCurve_NIST_B409
-#define ECCurve_SECG_CHAR2_571K1 ECCurve_NIST_K571
-#define ECCurve_SECG_CHAR2_571R1 ECCurve_NIST_B571
-#define ECCurve_WTLS_3 ECCurve_NIST_K163
-#define ECCurve_WTLS_4 ECCurve_SECG_CHAR2_113R1
-#define ECCurve_WTLS_5 ECCurve_X9_62_CHAR2_PNB163V1
-#define ECCurve_WTLS_6 ECCurve_SECG_PRIME_112R1
-#define ECCurve_WTLS_7 ECCurve_SECG_PRIME_160R1
-#define ECCurve_WTLS_10 ECCurve_NIST_K233
-#define ECCurve_WTLS_11 ECCurve_NIST_B233
-#define ECCurve_WTLS_12 ECCurve_NIST_P224
-
-#endif /* __ecl_exp_h_ */
diff --git a/security/nss/lib/freebl/ecl/ecl-priv.h b/security/nss/lib/freebl/ecl/ecl-priv.h
deleted file mode 100644
index 41843a7d3..000000000
--- a/security/nss/lib/freebl/ecl/ecl-priv.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __ecl_priv_h_
-#define __ecl_priv_h_
-
-#include "ecl.h"
-#include "mpi.h"
-#include "mplogic.h"
-
-/* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */
-/* the following needs to go away... */
-#if defined(MP_USE_LONG_LONG_DIGIT) || defined(MP_USE_LONG_DIGIT)
-#define ECL_SIXTY_FOUR_BIT
-#else
-#define ECL_THIRTY_TWO_BIT
-#endif
-
-#define ECL_CURVE_DIGITS(curve_size_in_bits) \
- (((curve_size_in_bits)+(sizeof(mp_digit)*8-1))/(sizeof(mp_digit)*8))
-#define ECL_BITS (sizeof(mp_digit)*8)
-#define ECL_MAX_FIELD_SIZE_DIGITS (80/sizeof(mp_digit))
-
-/* Gets the i'th bit in the binary representation of a. If i >= length(a),
- * then return 0. (The above behaviour differs from mpl_get_bit, which
- * causes an error if i >= length(a).) */
-#define MP_GET_BIT(a, i) \
- ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
-
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
-#define MP_ADD_CARRY(a1, a2, s, cin, cout) \
- { mp_word w; \
- w = ((mp_word)(cin)) + (a1) + (a2); \
- s = ACCUM(w); \
- cout = CARRYOUT(w); }
-
-#define MP_SUB_BORROW(a1, a2, s, bin, bout) \
- { mp_word w; \
- w = ((mp_word)(a1)) - (a2) - (bin); \
- s = ACCUM(w); \
- bout = (w >> MP_DIGIT_BIT) & 1; }
-
-#else
-/* NOTE,
- * cin and cout could be the same variable.
- * bin and bout could be the same variable.
- * a1 or a2 and s could be the same variable.
- * don't trash those outputs until their respective inputs have
- * been read. */
-#define MP_ADD_CARRY(a1, a2, s, cin, cout) \
- { mp_digit tmp,sum; \
- tmp = (a1); \
- sum = tmp + (a2); \
- tmp = (sum < tmp); /* detect overflow */ \
- s = sum += (cin); \
- cout = tmp + (sum < (cin)); }
-
-#define MP_SUB_BORROW(a1, a2, s, bin, bout) \
- { mp_digit tmp; \
- tmp = (a1); \
- s = tmp - (a2); \
- tmp = (s > tmp); /* detect borrow */ \
- if ((bin) && !s--) tmp++; \
- bout = tmp; }
-#endif
-
-
-struct GFMethodStr;
-typedef struct GFMethodStr GFMethod;
-struct GFMethodStr {
- /* Indicates whether the structure was constructed from dynamic memory
- * or statically created. */
- int constructed;
- /* Irreducible that defines the field. For prime fields, this is the
- * prime p. For binary polynomial fields, this is the bitstring
- * representation of the irreducible polynomial. */
- mp_int irr;
- /* For prime fields, the value irr_arr[0] is the number of bits in the
- * field. For binary polynomial fields, the irreducible polynomial
- * f(t) is represented as an array of unsigned int[], where f(t) is
- * of the form: f(t) = t^p[0] + t^p[1] + ... + t^p[4] where m = p[0]
- * > p[1] > ... > p[4] = 0. */
- unsigned int irr_arr[5];
- /* Field arithmetic methods. All methods (except field_enc and
- * field_dec) are assumed to take field-encoded parameters and return
- * field-encoded values. All methods (except field_enc and field_dec)
- * are required to be implemented. */
- mp_err (*field_add) (const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
- mp_err (*field_neg) (const mp_int *a, mp_int *r, const GFMethod *meth);
- mp_err (*field_sub) (const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
- mp_err (*field_mod) (const mp_int *a, mp_int *r, const GFMethod *meth);
- mp_err (*field_mul) (const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
- mp_err (*field_sqr) (const mp_int *a, mp_int *r, const GFMethod *meth);
- mp_err (*field_div) (const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
- mp_err (*field_enc) (const mp_int *a, mp_int *r, const GFMethod *meth);
- mp_err (*field_dec) (const mp_int *a, mp_int *r, const GFMethod *meth);
- /* Extra storage for implementation-specific data. Any memory
- * allocated to these extra fields will be cleared by extra_free. */
- void *extra1;
- void *extra2;
- void (*extra_free) (GFMethod *meth);
-};
-
-/* Construct generic GFMethods. */
-GFMethod *GFMethod_consGFp(const mp_int *irr);
-GFMethod *GFMethod_consGFp_mont(const mp_int *irr);
-GFMethod *GFMethod_consGF2m(const mp_int *irr,
- const unsigned int irr_arr[5]);
-/* Free the memory allocated (if any) to a GFMethod object. */
-void GFMethod_free(GFMethod *meth);
-
-struct ECGroupStr {
- /* Indicates whether the structure was constructed from dynamic memory
- * or statically created. */
- int constructed;
- /* Field definition and arithmetic. */
- GFMethod *meth;
- /* Textual representation of curve name, if any. */
- char *text;
- /* Curve parameters, field-encoded. */
- mp_int curvea, curveb;
- /* x and y coordinates of the base point, field-encoded. */
- mp_int genx, geny;
- /* Order and cofactor of the base point. */
- mp_int order;
- int cofactor;
- /* Point arithmetic methods. All methods are assumed to take
- * field-encoded parameters and return field-encoded values. All
- * methods (except base_point_mul and points_mul) are required to be
- * implemented. */
- mp_err (*point_add) (const mp_int *px, const mp_int *py,
- const mp_int *qx, const mp_int *qy, mp_int *rx,
- mp_int *ry, const ECGroup *group);
- mp_err (*point_sub) (const mp_int *px, const mp_int *py,
- const mp_int *qx, const mp_int *qy, mp_int *rx,
- mp_int *ry, const ECGroup *group);
- mp_err (*point_dbl) (const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, const ECGroup *group);
- mp_err (*point_mul) (const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group);
- mp_err (*base_point_mul) (const mp_int *n, mp_int *rx, mp_int *ry,
- const ECGroup *group);
- mp_err (*points_mul) (const mp_int *k1, const mp_int *k2,
- const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, const ECGroup *group);
- mp_err (*validate_point) (const mp_int *px, const mp_int *py, const ECGroup *group);
- /* Extra storage for implementation-specific data. Any memory
- * allocated to these extra fields will be cleared by extra_free. */
- void *extra1;
- void *extra2;
- void (*extra_free) (ECGroup *group);
-};
-
-/* Wrapper functions for generic prime field arithmetic. */
-mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
-mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-
-/* fixed length in-line adds. Count is in words */
-mp_err ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-
-mp_err ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
-mp_err ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
-mp_err ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-/* Wrapper functions for generic binary polynomial field arithmetic. */
-mp_err ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
-mp_err ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
-mp_err ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
-mp_err ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-
-/* Montgomery prime field arithmetic. */
-mp_err ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
-mp_err ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth);
-mp_err ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
-mp_err ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
-void ec_GFp_extra_free_mont(GFMethod *meth);
-
-/* point multiplication */
-mp_err ec_pts_mul_basic(const mp_int *k1, const mp_int *k2,
- const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, const ECGroup *group);
-mp_err ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2,
- const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, const ECGroup *group);
-
-/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
- * be an array of signed char's to output to, bitsize should be the number
- * of bits of out, in is the original scalar, and w is the window size.
- * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
- * Menezes, "Software implementation of elliptic curve cryptography over
- * binary fields", Proc. CHES 2000. */
-mp_err ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in,
- int w);
-
-/* Optimized field arithmetic */
-mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName);
-mp_err ec_group_set_gfp224(ECGroup *group, ECCurveName);
-mp_err ec_group_set_gfp256(ECGroup *group, ECCurveName);
-mp_err ec_group_set_gfp384(ECGroup *group, ECCurveName);
-mp_err ec_group_set_gfp521(ECGroup *group, ECCurveName);
-mp_err ec_group_set_gf2m163(ECGroup *group, ECCurveName name);
-mp_err ec_group_set_gf2m193(ECGroup *group, ECCurveName name);
-mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name);
-
-/* Optimized floating-point arithmetic */
-#ifdef ECL_USE_FP
-mp_err ec_group_set_secp160r1_fp(ECGroup *group);
-mp_err ec_group_set_nistp192_fp(ECGroup *group);
-mp_err ec_group_set_nistp224_fp(ECGroup *group);
-#endif
-
-#endif /* __ecl_priv_h_ */
diff --git a/security/nss/lib/freebl/ecl/ecl.c b/security/nss/lib/freebl/ecl/ecl.c
deleted file mode 100644
index 962e0ad1d..000000000
--- a/security/nss/lib/freebl/ecl/ecl.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi.h"
-#include "mplogic.h"
-#include "ecl.h"
-#include "ecl-priv.h"
-#include "ec2.h"
-#include "ecp.h"
-#include <stdlib.h>
-#include <string.h>
-
-/* Allocate memory for a new ECGroup object. */
-ECGroup *
-ECGroup_new()
-{
- mp_err res = MP_OKAY;
- ECGroup *group;
- group = (ECGroup *) malloc(sizeof(ECGroup));
- if (group == NULL)
- return NULL;
- group->constructed = MP_YES;
- group->meth = NULL;
- group->text = NULL;
- MP_DIGITS(&group->curvea) = 0;
- MP_DIGITS(&group->curveb) = 0;
- MP_DIGITS(&group->genx) = 0;
- MP_DIGITS(&group->geny) = 0;
- MP_DIGITS(&group->order) = 0;
- group->base_point_mul = NULL;
- group->points_mul = NULL;
- group->validate_point = NULL;
- group->extra1 = NULL;
- group->extra2 = NULL;
- group->extra_free = NULL;
- MP_CHECKOK(mp_init(&group->curvea));
- MP_CHECKOK(mp_init(&group->curveb));
- MP_CHECKOK(mp_init(&group->genx));
- MP_CHECKOK(mp_init(&group->geny));
- MP_CHECKOK(mp_init(&group->order));
-
- CLEANUP:
- if (res != MP_OKAY) {
- ECGroup_free(group);
- return NULL;
- }
- return group;
-}
-
-/* Construct a generic ECGroup for elliptic curves over prime fields. */
-ECGroup *
-ECGroup_consGFp(const mp_int *irr, const mp_int *curvea,
- const mp_int *curveb, const mp_int *genx,
- const mp_int *geny, const mp_int *order, int cofactor)
-{
- mp_err res = MP_OKAY;
- ECGroup *group = NULL;
-
- group = ECGroup_new();
- if (group == NULL)
- return NULL;
-
- group->meth = GFMethod_consGFp(irr);
- if (group->meth == NULL) {
- res = MP_MEM;
- goto CLEANUP;
- }
- MP_CHECKOK(mp_copy(curvea, &group->curvea));
- MP_CHECKOK(mp_copy(curveb, &group->curveb));
- MP_CHECKOK(mp_copy(genx, &group->genx));
- MP_CHECKOK(mp_copy(geny, &group->geny));
- MP_CHECKOK(mp_copy(order, &group->order));
- group->cofactor = cofactor;
- group->point_add = &ec_GFp_pt_add_aff;
- group->point_sub = &ec_GFp_pt_sub_aff;
- group->point_dbl = &ec_GFp_pt_dbl_aff;
- group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
- group->base_point_mul = NULL;
- group->points_mul = &ec_GFp_pts_mul_jac;
- group->validate_point = &ec_GFp_validate_point;
-
- CLEANUP:
- if (res != MP_OKAY) {
- ECGroup_free(group);
- return NULL;
- }
- return group;
-}
-
-/* Construct a generic ECGroup for elliptic curves over prime fields with
- * field arithmetic implemented in Montgomery coordinates. */
-ECGroup *
-ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea,
- const mp_int *curveb, const mp_int *genx,
- const mp_int *geny, const mp_int *order, int cofactor)
-{
- mp_err res = MP_OKAY;
- ECGroup *group = NULL;
-
- group = ECGroup_new();
- if (group == NULL)
- return NULL;
-
- group->meth = GFMethod_consGFp_mont(irr);
- if (group->meth == NULL) {
- res = MP_MEM;
- goto CLEANUP;
- }
- MP_CHECKOK(group->meth->
- field_enc(curvea, &group->curvea, group->meth));
- MP_CHECKOK(group->meth->
- field_enc(curveb, &group->curveb, group->meth));
- MP_CHECKOK(group->meth->field_enc(genx, &group->genx, group->meth));
- MP_CHECKOK(group->meth->field_enc(geny, &group->geny, group->meth));
- MP_CHECKOK(mp_copy(order, &group->order));
- group->cofactor = cofactor;
- group->point_add = &ec_GFp_pt_add_aff;
- group->point_sub = &ec_GFp_pt_sub_aff;
- group->point_dbl = &ec_GFp_pt_dbl_aff;
- group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
- group->base_point_mul = NULL;
- group->points_mul = &ec_GFp_pts_mul_jac;
- group->validate_point = &ec_GFp_validate_point;
-
- CLEANUP:
- if (res != MP_OKAY) {
- ECGroup_free(group);
- return NULL;
- }
- return group;
-}
-
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
-/* Construct a generic ECGroup for elliptic curves over binary polynomial
- * fields. */
-ECGroup *
-ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5],
- const mp_int *curvea, const mp_int *curveb,
- const mp_int *genx, const mp_int *geny,
- const mp_int *order, int cofactor)
-{
- mp_err res = MP_OKAY;
- ECGroup *group = NULL;
-
- group = ECGroup_new();
- if (group == NULL)
- return NULL;
-
- group->meth = GFMethod_consGF2m(irr, irr_arr);
- if (group->meth == NULL) {
- res = MP_MEM;
- goto CLEANUP;
- }
- MP_CHECKOK(mp_copy(curvea, &group->curvea));
- MP_CHECKOK(mp_copy(curveb, &group->curveb));
- MP_CHECKOK(mp_copy(genx, &group->genx));
- MP_CHECKOK(mp_copy(geny, &group->geny));
- MP_CHECKOK(mp_copy(order, &group->order));
- group->cofactor = cofactor;
- group->point_add = &ec_GF2m_pt_add_aff;
- group->point_sub = &ec_GF2m_pt_sub_aff;
- group->point_dbl = &ec_GF2m_pt_dbl_aff;
- group->point_mul = &ec_GF2m_pt_mul_mont;
- group->base_point_mul = NULL;
- group->points_mul = &ec_pts_mul_basic;
- group->validate_point = &ec_GF2m_validate_point;
-
- CLEANUP:
- if (res != MP_OKAY) {
- ECGroup_free(group);
- return NULL;
- }
- return group;
-}
-#endif
-
-/* Construct ECGroup from hex parameters and name, if any. Called by
- * ECGroup_fromHex and ECGroup_fromName. */
-ECGroup *
-ecgroup_fromNameAndHex(const ECCurveName name,
- const ECCurveParams * params)
-{
- mp_int irr, curvea, curveb, genx, geny, order;
- int bits;
- ECGroup *group = NULL;
- mp_err res = MP_OKAY;
-
- /* initialize values */
- MP_DIGITS(&irr) = 0;
- MP_DIGITS(&curvea) = 0;
- MP_DIGITS(&curveb) = 0;
- MP_DIGITS(&genx) = 0;
- MP_DIGITS(&geny) = 0;
- MP_DIGITS(&order) = 0;
- MP_CHECKOK(mp_init(&irr));
- MP_CHECKOK(mp_init(&curvea));
- MP_CHECKOK(mp_init(&curveb));
- MP_CHECKOK(mp_init(&genx));
- MP_CHECKOK(mp_init(&geny));
- MP_CHECKOK(mp_init(&order));
- MP_CHECKOK(mp_read_radix(&irr, params->irr, 16));
- MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16));
- MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16));
- MP_CHECKOK(mp_read_radix(&genx, params->genx, 16));
- MP_CHECKOK(mp_read_radix(&geny, params->geny, 16));
- MP_CHECKOK(mp_read_radix(&order, params->order, 16));
-
- /* determine number of bits */
- bits = mpl_significant_bits(&irr) - 1;
- if (bits < MP_OKAY) {
- res = bits;
- goto CLEANUP;
- }
-
- /* determine which optimizations (if any) to use */
- if (params->field == ECField_GFp) {
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
- switch (name) {
-#ifdef ECL_USE_FP
- case ECCurve_SECG_PRIME_160R1:
- group =
- ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
- &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
- MP_CHECKOK(ec_group_set_secp160r1_fp(group));
- break;
-#endif
- case ECCurve_SECG_PRIME_192R1:
-#ifdef ECL_USE_FP
- group =
- ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
- &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
- MP_CHECKOK(ec_group_set_nistp192_fp(group));
-#else
- group =
- ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
- &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
- MP_CHECKOK(ec_group_set_gfp192(group, name));
-#endif
- break;
- case ECCurve_SECG_PRIME_224R1:
-#ifdef ECL_USE_FP
- group =
- ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
- &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
- MP_CHECKOK(ec_group_set_nistp224_fp(group));
-#else
- group =
- ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
- &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
- MP_CHECKOK(ec_group_set_gfp224(group, name));
-#endif
- break;
- case ECCurve_SECG_PRIME_256R1:
- group =
- ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
- &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
- MP_CHECKOK(ec_group_set_gfp256(group, name));
- break;
- case ECCurve_SECG_PRIME_521R1:
- group =
- ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
- &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
- MP_CHECKOK(ec_group_set_gfp521(group, name));
- break;
- default:
- /* use generic arithmetic */
-#endif
- group =
- ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
- &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
- }
- } else if (params->field == ECField_GF2m) {
- group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor);
- if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
- if ((name == ECCurve_NIST_K163) ||
- (name == ECCurve_NIST_B163) ||
- (name == ECCurve_SECG_CHAR2_163R1)) {
- MP_CHECKOK(ec_group_set_gf2m163(group, name));
- } else if ((name == ECCurve_SECG_CHAR2_193R1) ||
- (name == ECCurve_SECG_CHAR2_193R2)) {
- MP_CHECKOK(ec_group_set_gf2m193(group, name));
- } else if ((name == ECCurve_NIST_K233) ||
- (name == ECCurve_NIST_B233)) {
- MP_CHECKOK(ec_group_set_gf2m233(group, name));
- }
-#endif
- } else {
- res = MP_UNDEF;
- goto CLEANUP;
- }
-
- /* set name, if any */
- if ((group != NULL) && (params->text != NULL)) {
- group->text = strdup(params->text);
- if (group->text == NULL) {
- res = MP_MEM;
- }
- }
-
- CLEANUP:
- mp_clear(&irr);
- mp_clear(&curvea);
- mp_clear(&curveb);
- mp_clear(&genx);
- mp_clear(&geny);
- mp_clear(&order);
- if (res != MP_OKAY) {
- ECGroup_free(group);
- return NULL;
- }
- return group;
-}
-
-/* Construct ECGroup from hexadecimal representations of parameters. */
-ECGroup *
-ECGroup_fromHex(const ECCurveParams * params)
-{
- return ecgroup_fromNameAndHex(ECCurve_noName, params);
-}
-
-/* Construct ECGroup from named parameters. */
-ECGroup *
-ECGroup_fromName(const ECCurveName name)
-{
- ECGroup *group = NULL;
- ECCurveParams *params = NULL;
- mp_err res = MP_OKAY;
-
- params = EC_GetNamedCurveParams(name);
- if (params == NULL) {
- res = MP_UNDEF;
- goto CLEANUP;
- }
-
- /* construct actual group */
- group = ecgroup_fromNameAndHex(name, params);
- if (group == NULL) {
- res = MP_UNDEF;
- goto CLEANUP;
- }
-
- CLEANUP:
- EC_FreeCurveParams(params);
- if (res != MP_OKAY) {
- ECGroup_free(group);
- return NULL;
- }
- return group;
-}
-
-/* Validates an EC public key as described in Section 5.2.2 of X9.62. */
-mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
- mp_int *py)
-{
- /* 1: Verify that publicValue is not the point at infinity */
- /* 2: Verify that the coordinates of publicValue are elements
- * of the field.
- */
- /* 3: Verify that publicValue is on the curve. */
- /* 4: Verify that the order of the curve times the publicValue
- * is the point at infinity.
- */
- return group->validate_point(px, py, group);
-}
-
-/* Free the memory allocated (if any) to an ECGroup object. */
-void
-ECGroup_free(ECGroup *group)
-{
- if (group == NULL)
- return;
- GFMethod_free(group->meth);
- if (group->constructed == MP_NO)
- return;
- mp_clear(&group->curvea);
- mp_clear(&group->curveb);
- mp_clear(&group->genx);
- mp_clear(&group->geny);
- mp_clear(&group->order);
- if (group->text != NULL)
- free(group->text);
- if (group->extra_free != NULL)
- group->extra_free(group);
- free(group);
-}
diff --git a/security/nss/lib/freebl/ecl/ecl.h b/security/nss/lib/freebl/ecl/ecl.h
deleted file mode 100644
index 3e4480327..000000000
--- a/security/nss/lib/freebl/ecl/ecl.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Although this is not an exported header file, code which uses elliptic
- * curve point operations will need to include it. */
-
-#ifndef __ecl_h_
-#define __ecl_h_
-
-#include "ecl-exp.h"
-#include "mpi.h"
-
-struct ECGroupStr;
-typedef struct ECGroupStr ECGroup;
-
-/* Construct ECGroup from hexadecimal representations of parameters. */
-ECGroup *ECGroup_fromHex(const ECCurveParams * params);
-
-/* Construct ECGroup from named parameters. */
-ECGroup *ECGroup_fromName(const ECCurveName name);
-
-/* Free an allocated ECGroup. */
-void ECGroup_free(ECGroup *group);
-
-/* Construct ECCurveParams from an ECCurveName */
-ECCurveParams *EC_GetNamedCurveParams(const ECCurveName name);
-
-/* Duplicates an ECCurveParams */
-ECCurveParams *ECCurveParams_dup(const ECCurveParams * params);
-
-/* Free an allocated ECCurveParams */
-void EC_FreeCurveParams(ECCurveParams * params);
-
-/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k * P(x,
- * y). If x, y = NULL, then P is assumed to be the generator (base point)
- * of the group of points on the elliptic curve. Input and output values
- * are assumed to be NOT field-encoded. */
-mp_err ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
- const mp_int *py, mp_int *qx, mp_int *qy);
-
-/* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k1 * G +
- * k2 * P(x, y), where G is the generator (base point) of the group of
- * points on the elliptic curve. Input and output values are assumed to
- * be NOT field-encoded. */
-mp_err ECPoints_mul(const ECGroup *group, const mp_int *k1,
- const mp_int *k2, const mp_int *px, const mp_int *py,
- mp_int *qx, mp_int *qy);
-
-/* Validates an EC public key as described in Section 5.2.2 of X9.62.
- * Returns MP_YES if the public key is valid, MP_NO if the public key
- * is invalid, or an error code if the validation could not be
- * performed. */
-mp_err ECPoint_validate(const ECGroup *group, const mp_int *px, const
- mp_int *py);
-
-#endif /* __ecl_h_ */
diff --git a/security/nss/lib/freebl/ecl/ecl_curve.c b/security/nss/lib/freebl/ecl/ecl_curve.c
deleted file mode 100644
index 192dab126..000000000
--- a/security/nss/lib/freebl/ecl/ecl_curve.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecl.h"
-#include "ecl-curve.h"
-#include "ecl-priv.h"
-#include <stdlib.h>
-#include <string.h>
-
-#define CHECK(func) if ((func) == NULL) { res = 0; goto CLEANUP; }
-
-/* Duplicates an ECCurveParams */
-ECCurveParams *
-ECCurveParams_dup(const ECCurveParams * params)
-{
- int res = 1;
- ECCurveParams *ret = NULL;
-
- CHECK(ret = (ECCurveParams *) calloc(1, sizeof(ECCurveParams)));
- if (params->text != NULL) {
- CHECK(ret->text = strdup(params->text));
- }
- ret->field = params->field;
- ret->size = params->size;
- if (params->irr != NULL) {
- CHECK(ret->irr = strdup(params->irr));
- }
- if (params->curvea != NULL) {
- CHECK(ret->curvea = strdup(params->curvea));
- }
- if (params->curveb != NULL) {
- CHECK(ret->curveb = strdup(params->curveb));
- }
- if (params->genx != NULL) {
- CHECK(ret->genx = strdup(params->genx));
- }
- if (params->geny != NULL) {
- CHECK(ret->geny = strdup(params->geny));
- }
- if (params->order != NULL) {
- CHECK(ret->order = strdup(params->order));
- }
- ret->cofactor = params->cofactor;
-
- CLEANUP:
- if (res != 1) {
- EC_FreeCurveParams(ret);
- return NULL;
- }
- return ret;
-}
-
-#undef CHECK
-
-/* Construct ECCurveParams from an ECCurveName */
-ECCurveParams *
-EC_GetNamedCurveParams(const ECCurveName name)
-{
- if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) ||
- (ecCurve_map[name] == NULL)) {
- return NULL;
- } else {
- return ECCurveParams_dup(ecCurve_map[name]);
- }
-}
-
-/* Free the memory allocated (if any) to an ECCurveParams object. */
-void
-EC_FreeCurveParams(ECCurveParams * params)
-{
- if (params == NULL)
- return;
- if (params->text != NULL)
- free(params->text);
- if (params->irr != NULL)
- free(params->irr);
- if (params->curvea != NULL)
- free(params->curvea);
- if (params->curveb != NULL)
- free(params->curveb);
- if (params->genx != NULL)
- free(params->genx);
- if (params->geny != NULL)
- free(params->geny);
- if (params->order != NULL)
- free(params->order);
- free(params);
-}
diff --git a/security/nss/lib/freebl/ecl/ecl_gf.c b/security/nss/lib/freebl/ecl/ecl_gf.c
deleted file mode 100644
index 22047d519..000000000
--- a/security/nss/lib/freebl/ecl/ecl_gf.c
+++ /dev/null
@@ -1,997 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi.h"
-#include "mp_gf2m.h"
-#include "ecl-priv.h"
-#include "mpi-priv.h"
-#include <stdlib.h>
-
-/* Allocate memory for a new GFMethod object. */
-GFMethod *
-GFMethod_new()
-{
- mp_err res = MP_OKAY;
- GFMethod *meth;
- meth = (GFMethod *) malloc(sizeof(GFMethod));
- if (meth == NULL)
- return NULL;
- meth->constructed = MP_YES;
- MP_DIGITS(&meth->irr) = 0;
- meth->extra_free = NULL;
- MP_CHECKOK(mp_init(&meth->irr));
-
- CLEANUP:
- if (res != MP_OKAY) {
- GFMethod_free(meth);
- return NULL;
- }
- return meth;
-}
-
-/* Construct a generic GFMethod for arithmetic over prime fields with
- * irreducible irr. */
-GFMethod *
-GFMethod_consGFp(const mp_int *irr)
-{
- mp_err res = MP_OKAY;
- GFMethod *meth = NULL;
-
- meth = GFMethod_new();
- if (meth == NULL)
- return NULL;
-
- MP_CHECKOK(mp_copy(irr, &meth->irr));
- meth->irr_arr[0] = mpl_significant_bits(irr);
- meth->irr_arr[1] = meth->irr_arr[2] = meth->irr_arr[3] =
- meth->irr_arr[4] = 0;
- switch(MP_USED(&meth->irr)) {
- /* maybe we need 1 and 2 words here as well?*/
- case 3:
- meth->field_add = &ec_GFp_add_3;
- meth->field_sub = &ec_GFp_sub_3;
- break;
- case 4:
- meth->field_add = &ec_GFp_add_4;
- meth->field_sub = &ec_GFp_sub_4;
- break;
- case 5:
- meth->field_add = &ec_GFp_add_5;
- meth->field_sub = &ec_GFp_sub_5;
- break;
- case 6:
- meth->field_add = &ec_GFp_add_6;
- meth->field_sub = &ec_GFp_sub_6;
- break;
- default:
- meth->field_add = &ec_GFp_add;
- meth->field_sub = &ec_GFp_sub;
- }
- meth->field_neg = &ec_GFp_neg;
- meth->field_mod = &ec_GFp_mod;
- meth->field_mul = &ec_GFp_mul;
- meth->field_sqr = &ec_GFp_sqr;
- meth->field_div = &ec_GFp_div;
- meth->field_enc = NULL;
- meth->field_dec = NULL;
- meth->extra1 = NULL;
- meth->extra2 = NULL;
- meth->extra_free = NULL;
-
- CLEANUP:
- if (res != MP_OKAY) {
- GFMethod_free(meth);
- return NULL;
- }
- return meth;
-}
-
-/* Construct a generic GFMethod for arithmetic over binary polynomial
- * fields with irreducible irr that has array representation irr_arr (see
- * ecl-priv.h for description of the representation). If irr_arr is NULL,
- * then it is constructed from the bitstring representation. */
-GFMethod *
-GFMethod_consGF2m(const mp_int *irr, const unsigned int irr_arr[5])
-{
- mp_err res = MP_OKAY;
- int ret;
- GFMethod *meth = NULL;
-
- meth = GFMethod_new();
- if (meth == NULL)
- return NULL;
-
- MP_CHECKOK(mp_copy(irr, &meth->irr));
- if (irr_arr != NULL) {
- /* Irreducible polynomials are either trinomials or pentanomials. */
- meth->irr_arr[0] = irr_arr[0];
- meth->irr_arr[1] = irr_arr[1];
- meth->irr_arr[2] = irr_arr[2];
- if (irr_arr[2] > 0) {
- meth->irr_arr[3] = irr_arr[3];
- meth->irr_arr[4] = irr_arr[4];
- } else {
- meth->irr_arr[3] = meth->irr_arr[4] = 0;
- }
- } else {
- ret = mp_bpoly2arr(irr, meth->irr_arr, 5);
- /* Irreducible polynomials are either trinomials or pentanomials. */
- if ((ret != 5) && (ret != 3)) {
- res = MP_UNDEF;
- goto CLEANUP;
- }
- }
- meth->field_add = &ec_GF2m_add;
- meth->field_neg = &ec_GF2m_neg;
- meth->field_sub = &ec_GF2m_add;
- meth->field_mod = &ec_GF2m_mod;
- meth->field_mul = &ec_GF2m_mul;
- meth->field_sqr = &ec_GF2m_sqr;
- meth->field_div = &ec_GF2m_div;
- meth->field_enc = NULL;
- meth->field_dec = NULL;
- meth->extra1 = NULL;
- meth->extra2 = NULL;
- meth->extra_free = NULL;
-
- CLEANUP:
- if (res != MP_OKAY) {
- GFMethod_free(meth);
- return NULL;
- }
- return meth;
-}
-
-/* Free the memory allocated (if any) to a GFMethod object. */
-void
-GFMethod_free(GFMethod *meth)
-{
- if (meth == NULL)
- return;
- if (meth->constructed == MP_NO)
- return;
- mp_clear(&meth->irr);
- if (meth->extra_free != NULL)
- meth->extra_free(meth);
- free(meth);
-}
-
-/* Wrapper functions for generic prime field arithmetic. */
-
-/* Add two field elements. Assumes that 0 <= a, b < meth->irr */
-mp_err
-ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a + b (mod p) */
- mp_err res;
-
- if ((res = mp_add(a, b, r)) != MP_OKAY) {
- return res;
- }
- if (mp_cmp(r, &meth->irr) >= 0) {
- return mp_sub(r, &meth->irr, r);
- }
- return res;
-}
-
-/* Negates a field element. Assumes that 0 <= a < meth->irr */
-mp_err
-ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- /* PRE: 0 <= a < p = meth->irr POST: 0 <= r < p, r = -a (mod p) */
-
- if (mp_cmp_z(a) == 0) {
- mp_zero(r);
- return MP_OKAY;
- }
- return mp_sub(&meth->irr, a, r);
-}
-
-/* Subtracts two field elements. Assumes that 0 <= a, b < meth->irr */
-mp_err
-ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a - b (mod p) */
- res = mp_sub(a, b, r);
- if (res == MP_RANGE) {
- MP_CHECKOK(mp_sub(b, a, r));
- if (mp_cmp_z(r) < 0) {
- MP_CHECKOK(mp_add(r, &meth->irr, r));
- }
- MP_CHECKOK(ec_GFp_neg(r, r, meth));
- }
- if (mp_cmp_z(r) < 0) {
- MP_CHECKOK(mp_add(r, &meth->irr, r));
- }
- CLEANUP:
- return res;
-}
-/*
- * Inline adds for small curve lengths.
- */
-/* 3 words */
-mp_err
-ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit a0 = 0, a1 = 0, a2 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0;
- mp_digit carry;
-
- switch(MP_USED(a)) {
- case 3:
- a2 = MP_DIGIT(a,2);
- case 2:
- a1 = MP_DIGIT(a,1);
- case 1:
- a0 = MP_DIGIT(a,0);
- }
- switch(MP_USED(b)) {
- case 3:
- r2 = MP_DIGIT(b,2);
- case 2:
- r1 = MP_DIGIT(b,1);
- case 1:
- r0 = MP_DIGIT(b,0);
- }
-
-#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry, carry);
- MP_ADD_CARRY(a2, r2, r2, carry, carry);
-#else
- __asm__ (
- "xorq %3,%3 \n\t"
- "addq %4,%0 \n\t"
- "adcq %5,%1 \n\t"
- "adcq %6,%2 \n\t"
- "adcq $0,%3 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry)
- : "r" (a0), "r" (a1), "r" (a2),
- "0" (r0), "1" (r1), "2" (r2)
- : "%cc" );
-#endif
-
- MP_CHECKOK(s_mp_pad(r, 3));
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 3;
-
- /* Do quick 'subract' if we've gone over
- * (add the 2's complement of the curve field) */
- a2 = MP_DIGIT(&meth->irr,2);
- if (carry || r2 > a2 ||
- ((r2 == a2) && mp_cmp(r,&meth->irr) != MP_LT)) {
- a1 = MP_DIGIT(&meth->irr,1);
- a0 = MP_DIGIT(&meth->irr,0);
-#ifndef MPI_AMD64_ADD
- MP_SUB_BORROW(r0, a0, r0, 0, carry);
- MP_SUB_BORROW(r1, a1, r1, carry, carry);
- MP_SUB_BORROW(r2, a2, r2, carry, carry);
-#else
- __asm__ (
- "subq %3,%0 \n\t"
- "sbbq %4,%1 \n\t"
- "sbbq %5,%2 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2)
- : "r" (a0), "r" (a1), "r" (a2),
- "0" (r0), "1" (r1), "2" (r2)
- : "%cc" );
-#endif
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- }
-
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* 4 words */
-mp_err
-ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0;
- mp_digit carry;
-
- switch(MP_USED(a)) {
- case 4:
- a3 = MP_DIGIT(a,3);
- case 3:
- a2 = MP_DIGIT(a,2);
- case 2:
- a1 = MP_DIGIT(a,1);
- case 1:
- a0 = MP_DIGIT(a,0);
- }
- switch(MP_USED(b)) {
- case 4:
- r3 = MP_DIGIT(b,3);
- case 3:
- r2 = MP_DIGIT(b,2);
- case 2:
- r1 = MP_DIGIT(b,1);
- case 1:
- r0 = MP_DIGIT(b,0);
- }
-
-#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry, carry);
- MP_ADD_CARRY(a2, r2, r2, carry, carry);
- MP_ADD_CARRY(a3, r3, r3, carry, carry);
-#else
- __asm__ (
- "xorq %4,%4 \n\t"
- "addq %5,%0 \n\t"
- "adcq %6,%1 \n\t"
- "adcq %7,%2 \n\t"
- "adcq %8,%3 \n\t"
- "adcq $0,%4 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(carry)
- : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
- "0" (r0), "1" (r1), "2" (r2), "3" (r3)
- : "%cc" );
-#endif
-
- MP_CHECKOK(s_mp_pad(r, 4));
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 4;
-
- /* Do quick 'subract' if we've gone over
- * (add the 2's complement of the curve field) */
- a3 = MP_DIGIT(&meth->irr,3);
- if (carry || r3 > a3 ||
- ((r3 == a3) && mp_cmp(r,&meth->irr) != MP_LT)) {
- a2 = MP_DIGIT(&meth->irr,2);
- a1 = MP_DIGIT(&meth->irr,1);
- a0 = MP_DIGIT(&meth->irr,0);
-#ifndef MPI_AMD64_ADD
- MP_SUB_BORROW(r0, a0, r0, 0, carry);
- MP_SUB_BORROW(r1, a1, r1, carry, carry);
- MP_SUB_BORROW(r2, a2, r2, carry, carry);
- MP_SUB_BORROW(r3, a3, r3, carry, carry);
-#else
- __asm__ (
- "subq %4,%0 \n\t"
- "sbbq %5,%1 \n\t"
- "sbbq %6,%2 \n\t"
- "sbbq %7,%3 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3)
- : "r" (a0), "r" (a1), "r" (a2), "r" (a3),
- "0" (r0), "1" (r1), "2" (r2), "3" (r3)
- : "%cc" );
-#endif
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- }
-
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* 5 words */
-mp_err
-ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0;
- mp_digit carry;
-
- switch(MP_USED(a)) {
- case 5:
- a4 = MP_DIGIT(a,4);
- case 4:
- a3 = MP_DIGIT(a,3);
- case 3:
- a2 = MP_DIGIT(a,2);
- case 2:
- a1 = MP_DIGIT(a,1);
- case 1:
- a0 = MP_DIGIT(a,0);
- }
- switch(MP_USED(b)) {
- case 5:
- r4 = MP_DIGIT(b,4);
- case 4:
- r3 = MP_DIGIT(b,3);
- case 3:
- r2 = MP_DIGIT(b,2);
- case 2:
- r1 = MP_DIGIT(b,1);
- case 1:
- r0 = MP_DIGIT(b,0);
- }
-
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry, carry);
- MP_ADD_CARRY(a2, r2, r2, carry, carry);
- MP_ADD_CARRY(a3, r3, r3, carry, carry);
- MP_ADD_CARRY(a4, r4, r4, carry, carry);
-
- MP_CHECKOK(s_mp_pad(r, 5));
- MP_DIGIT(r, 4) = r4;
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 5;
-
- /* Do quick 'subract' if we've gone over
- * (add the 2's complement of the curve field) */
- a4 = MP_DIGIT(&meth->irr,4);
- if (carry || r4 > a4 ||
- ((r4 == a4) && mp_cmp(r,&meth->irr) != MP_LT)) {
- a3 = MP_DIGIT(&meth->irr,3);
- a2 = MP_DIGIT(&meth->irr,2);
- a1 = MP_DIGIT(&meth->irr,1);
- a0 = MP_DIGIT(&meth->irr,0);
- MP_SUB_BORROW(r0, a0, r0, 0, carry);
- MP_SUB_BORROW(r1, a1, r1, carry, carry);
- MP_SUB_BORROW(r2, a2, r2, carry, carry);
- MP_SUB_BORROW(r3, a3, r3, carry, carry);
- MP_SUB_BORROW(r4, a4, r4, carry, carry);
- MP_DIGIT(r, 4) = r4;
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- }
-
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* 6 words */
-mp_err
-ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0;
- mp_digit carry;
-
- switch(MP_USED(a)) {
- case 6:
- a5 = MP_DIGIT(a,5);
- case 5:
- a4 = MP_DIGIT(a,4);
- case 4:
- a3 = MP_DIGIT(a,3);
- case 3:
- a2 = MP_DIGIT(a,2);
- case 2:
- a1 = MP_DIGIT(a,1);
- case 1:
- a0 = MP_DIGIT(a,0);
- }
- switch(MP_USED(b)) {
- case 6:
- r5 = MP_DIGIT(b,5);
- case 5:
- r4 = MP_DIGIT(b,4);
- case 4:
- r3 = MP_DIGIT(b,3);
- case 3:
- r2 = MP_DIGIT(b,2);
- case 2:
- r1 = MP_DIGIT(b,1);
- case 1:
- r0 = MP_DIGIT(b,0);
- }
-
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry, carry);
- MP_ADD_CARRY(a2, r2, r2, carry, carry);
- MP_ADD_CARRY(a3, r3, r3, carry, carry);
- MP_ADD_CARRY(a4, r4, r4, carry, carry);
- MP_ADD_CARRY(a5, r5, r5, carry, carry);
-
- MP_CHECKOK(s_mp_pad(r, 6));
- MP_DIGIT(r, 5) = r5;
- MP_DIGIT(r, 4) = r4;
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 6;
-
- /* Do quick 'subract' if we've gone over
- * (add the 2's complement of the curve field) */
- a5 = MP_DIGIT(&meth->irr,5);
- if (carry || r5 > a5 ||
- ((r5 == a5) && mp_cmp(r,&meth->irr) != MP_LT)) {
- a4 = MP_DIGIT(&meth->irr,4);
- a3 = MP_DIGIT(&meth->irr,3);
- a2 = MP_DIGIT(&meth->irr,2);
- a1 = MP_DIGIT(&meth->irr,1);
- a0 = MP_DIGIT(&meth->irr,0);
- MP_SUB_BORROW(r0, a0, r0, 0, carry);
- MP_SUB_BORROW(r1, a1, r1, carry, carry);
- MP_SUB_BORROW(r2, a2, r2, carry, carry);
- MP_SUB_BORROW(r3, a3, r3, carry, carry);
- MP_SUB_BORROW(r4, a4, r4, carry, carry);
- MP_SUB_BORROW(r5, a5, r5, carry, carry);
- MP_DIGIT(r, 5) = r5;
- MP_DIGIT(r, 4) = r4;
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- }
-
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/*
- * The following subraction functions do in-line subractions based
- * on our curve size.
- *
- * ... 3 words
- */
-mp_err
-ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit b0 = 0, b1 = 0, b2 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0;
- mp_digit borrow;
-
- switch(MP_USED(a)) {
- case 3:
- r2 = MP_DIGIT(a,2);
- case 2:
- r1 = MP_DIGIT(a,1);
- case 1:
- r0 = MP_DIGIT(a,0);
- }
- switch(MP_USED(b)) {
- case 3:
- b2 = MP_DIGIT(b,2);
- case 2:
- b1 = MP_DIGIT(b,1);
- case 1:
- b0 = MP_DIGIT(b,0);
- }
-
-#ifndef MPI_AMD64_ADD
- MP_SUB_BORROW(r0, b0, r0, 0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
- MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
-#else
- __asm__ (
- "xorq %3,%3 \n\t"
- "subq %4,%0 \n\t"
- "sbbq %5,%1 \n\t"
- "sbbq %6,%2 \n\t"
- "adcq $0,%3 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r" (borrow)
- : "r" (b0), "r" (b1), "r" (b2),
- "0" (r0), "1" (r1), "2" (r2)
- : "%cc" );
-#endif
-
- /* Do quick 'add' if we've gone under 0
- * (subtract the 2's complement of the curve field) */
- if (borrow) {
- b2 = MP_DIGIT(&meth->irr,2);
- b1 = MP_DIGIT(&meth->irr,1);
- b0 = MP_DIGIT(&meth->irr,0);
-#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
- MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
- MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
-#else
- __asm__ (
- "addq %3,%0 \n\t"
- "adcq %4,%1 \n\t"
- "adcq %5,%2 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2)
- : "r" (b0), "r" (b1), "r" (b2),
- "0" (r0), "1" (r1), "2" (r2)
- : "%cc" );
-#endif
- }
-
-#ifdef MPI_AMD64_ADD
- /* compiler fakeout? */
- if ((r2 == b0) && (r1 == b0) && (r0 == b0)) {
- MP_CHECKOK(s_mp_pad(r, 4));
- }
-#endif
- MP_CHECKOK(s_mp_pad(r, 3));
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 3;
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* 4 words */
-mp_err
-ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0;
- mp_digit borrow;
-
- switch(MP_USED(a)) {
- case 4:
- r3 = MP_DIGIT(a,3);
- case 3:
- r2 = MP_DIGIT(a,2);
- case 2:
- r1 = MP_DIGIT(a,1);
- case 1:
- r0 = MP_DIGIT(a,0);
- }
- switch(MP_USED(b)) {
- case 4:
- b3 = MP_DIGIT(b,3);
- case 3:
- b2 = MP_DIGIT(b,2);
- case 2:
- b1 = MP_DIGIT(b,1);
- case 1:
- b0 = MP_DIGIT(b,0);
- }
-
-#ifndef MPI_AMD64_ADD
- MP_SUB_BORROW(r0, b0, r0, 0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
- MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
- MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
-#else
- __asm__ (
- "xorq %4,%4 \n\t"
- "subq %5,%0 \n\t"
- "sbbq %6,%1 \n\t"
- "sbbq %7,%2 \n\t"
- "sbbq %8,%3 \n\t"
- "adcq $0,%4 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r" (borrow)
- : "r" (b0), "r" (b1), "r" (b2), "r" (b3),
- "0" (r0), "1" (r1), "2" (r2), "3" (r3)
- : "%cc" );
-#endif
-
- /* Do quick 'add' if we've gone under 0
- * (subtract the 2's complement of the curve field) */
- if (borrow) {
- b3 = MP_DIGIT(&meth->irr,3);
- b2 = MP_DIGIT(&meth->irr,2);
- b1 = MP_DIGIT(&meth->irr,1);
- b0 = MP_DIGIT(&meth->irr,0);
-#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
- MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
- MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
- MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
-#else
- __asm__ (
- "addq %4,%0 \n\t"
- "adcq %5,%1 \n\t"
- "adcq %6,%2 \n\t"
- "adcq %7,%3 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3)
- : "r" (b0), "r" (b1), "r" (b2), "r" (b3),
- "0" (r0), "1" (r1), "2" (r2), "3" (r3)
- : "%cc" );
-#endif
- }
-#ifdef MPI_AMD64_ADD
- /* compiler fakeout? */
- if ((r3 == b0) && (r1 == b0) && (r0 == b0)) {
- MP_CHECKOK(s_mp_pad(r, 4));
- }
-#endif
- MP_CHECKOK(s_mp_pad(r, 4));
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 4;
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* 5 words */
-mp_err
-ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0;
- mp_digit borrow;
-
- switch(MP_USED(a)) {
- case 5:
- r4 = MP_DIGIT(a,4);
- case 4:
- r3 = MP_DIGIT(a,3);
- case 3:
- r2 = MP_DIGIT(a,2);
- case 2:
- r1 = MP_DIGIT(a,1);
- case 1:
- r0 = MP_DIGIT(a,0);
- }
- switch(MP_USED(b)) {
- case 5:
- b4 = MP_DIGIT(b,4);
- case 4:
- b3 = MP_DIGIT(b,3);
- case 3:
- b2 = MP_DIGIT(b,2);
- case 2:
- b1 = MP_DIGIT(b,1);
- case 1:
- b0 = MP_DIGIT(b,0);
- }
-
- MP_SUB_BORROW(r0, b0, r0, 0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
- MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
- MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
- MP_SUB_BORROW(r4, b4, r4, borrow, borrow);
-
- /* Do quick 'add' if we've gone under 0
- * (subtract the 2's complement of the curve field) */
- if (borrow) {
- b4 = MP_DIGIT(&meth->irr,4);
- b3 = MP_DIGIT(&meth->irr,3);
- b2 = MP_DIGIT(&meth->irr,2);
- b1 = MP_DIGIT(&meth->irr,1);
- b0 = MP_DIGIT(&meth->irr,0);
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
- MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
- MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
- MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
- }
- MP_CHECKOK(s_mp_pad(r, 5));
- MP_DIGIT(r, 4) = r4;
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 5;
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* 6 words */
-mp_err
-ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0;
- mp_digit borrow;
-
- switch(MP_USED(a)) {
- case 6:
- r5 = MP_DIGIT(a,5);
- case 5:
- r4 = MP_DIGIT(a,4);
- case 4:
- r3 = MP_DIGIT(a,3);
- case 3:
- r2 = MP_DIGIT(a,2);
- case 2:
- r1 = MP_DIGIT(a,1);
- case 1:
- r0 = MP_DIGIT(a,0);
- }
- switch(MP_USED(b)) {
- case 6:
- b5 = MP_DIGIT(b,5);
- case 5:
- b4 = MP_DIGIT(b,4);
- case 4:
- b3 = MP_DIGIT(b,3);
- case 3:
- b2 = MP_DIGIT(b,2);
- case 2:
- b1 = MP_DIGIT(b,1);
- case 1:
- b0 = MP_DIGIT(b,0);
- }
-
- MP_SUB_BORROW(r0, b0, r0, 0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
- MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
- MP_SUB_BORROW(r3, b3, r3, borrow, borrow);
- MP_SUB_BORROW(r4, b4, r4, borrow, borrow);
- MP_SUB_BORROW(r5, b5, r5, borrow, borrow);
-
- /* Do quick 'add' if we've gone under 0
- * (subtract the 2's complement of the curve field) */
- if (borrow) {
- b5 = MP_DIGIT(&meth->irr,5);
- b4 = MP_DIGIT(&meth->irr,4);
- b3 = MP_DIGIT(&meth->irr,3);
- b2 = MP_DIGIT(&meth->irr,2);
- b1 = MP_DIGIT(&meth->irr,1);
- b0 = MP_DIGIT(&meth->irr,0);
- MP_ADD_CARRY(b0, r0, r0, 0, borrow);
- MP_ADD_CARRY(b1, r1, r1, borrow, borrow);
- MP_ADD_CARRY(b2, r2, r2, borrow, borrow);
- MP_ADD_CARRY(b3, r3, r3, borrow, borrow);
- MP_ADD_CARRY(b4, r4, r4, borrow, borrow);
- }
-
- MP_CHECKOK(s_mp_pad(r, 6));
- MP_DIGIT(r, 5) = r5;
- MP_DIGIT(r, 4) = r4;
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 6;
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-
-/* Reduces an integer to a field element. */
-mp_err
-ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- return mp_mod(a, &meth->irr, r);
-}
-
-/* Multiplies two field elements. */
-mp_err
-ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- return mp_mulmod(a, b, &meth->irr, r);
-}
-
-/* Squares a field element. */
-mp_err
-ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- return mp_sqrmod(a, &meth->irr, r);
-}
-
-/* Divides two field elements. If a is NULL, then returns the inverse of
- * b. */
-mp_err
-ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_int t;
-
- /* If a is NULL, then return the inverse of b, otherwise return a/b. */
- if (a == NULL) {
- return mp_invmod(b, &meth->irr, r);
- } else {
- /* MPI doesn't support divmod, so we implement it using invmod and
- * mulmod. */
- MP_CHECKOK(mp_init(&t));
- MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
- MP_CHECKOK(mp_mulmod(a, &t, &meth->irr, r));
- CLEANUP:
- mp_clear(&t);
- return res;
- }
-}
-
-/* Wrapper functions for generic binary polynomial field arithmetic. */
-
-/* Adds two field elements. */
-mp_err
-ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- return mp_badd(a, b, r);
-}
-
-/* Negates a field element. Note that for binary polynomial fields, the
- * negation of a field element is the field element itself. */
-mp_err
-ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- if (a == r) {
- return MP_OKAY;
- } else {
- return mp_copy(a, r);
- }
-}
-
-/* Reduces a binary polynomial to a field element. */
-mp_err
-ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- return mp_bmod(a, meth->irr_arr, r);
-}
-
-/* Multiplies two field elements. */
-mp_err
-ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- return mp_bmulmod(a, b, meth->irr_arr, r);
-}
-
-/* Squares a field element. */
-mp_err
-ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- return mp_bsqrmod(a, meth->irr_arr, r);
-}
-
-/* Divides two field elements. If a is NULL, then returns the inverse of
- * b. */
-mp_err
-ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_int t;
-
- /* If a is NULL, then return the inverse of b, otherwise return a/b. */
- if (a == NULL) {
- /* The GF(2^m) portion of MPI doesn't support invmod, so we
- * compute 1/b. */
- MP_CHECKOK(mp_init(&t));
- MP_CHECKOK(mp_set_int(&t, 1));
- MP_CHECKOK(mp_bdivmod(&t, b, &meth->irr, meth->irr_arr, r));
- CLEANUP:
- mp_clear(&t);
- return res;
- } else {
- return mp_bdivmod(a, b, &meth->irr, meth->irr_arr, r);
- }
-}
diff --git a/security/nss/lib/freebl/ecl/ecl_mult.c b/security/nss/lib/freebl/ecl/ecl_mult.c
deleted file mode 100644
index a99ca8250..000000000
--- a/security/nss/lib/freebl/ecl/ecl_mult.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi.h"
-#include "mplogic.h"
-#include "ecl.h"
-#include "ecl-priv.h"
-#include <stdlib.h>
-
-/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k * P(x,
- * y). If x, y = NULL, then P is assumed to be the generator (base point)
- * of the group of points on the elliptic curve. Input and output values
- * are assumed to be NOT field-encoded. */
-mp_err
-ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry)
-{
- mp_err res = MP_OKAY;
- mp_int kt;
-
- ARGCHK((k != NULL) && (group != NULL), MP_BADARG);
- MP_DIGITS(&kt) = 0;
-
- /* want scalar to be less than or equal to group order */
- if (mp_cmp(k, &group->order) > 0) {
- MP_CHECKOK(mp_init(&kt));
- MP_CHECKOK(mp_mod(k, &group->order, &kt));
- } else {
- MP_SIGN(&kt) = MP_ZPOS;
- MP_USED(&kt) = MP_USED(k);
- MP_ALLOC(&kt) = MP_ALLOC(k);
- MP_DIGITS(&kt) = MP_DIGITS(k);
- }
-
- if ((px == NULL) || (py == NULL)) {
- if (group->base_point_mul) {
- MP_CHECKOK(group->base_point_mul(&kt, rx, ry, group));
- } else {
- MP_CHECKOK(group->
- point_mul(&kt, &group->genx, &group->geny, rx, ry,
- group));
- }
- } else {
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
- MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
- MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group));
- } else {
- MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group));
- }
- }
- if (group->meth->field_dec) {
- MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
- MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
- }
-
- CLEANUP:
- if (MP_DIGITS(&kt) != MP_DIGITS(k)) {
- mp_clear(&kt);
- }
- return res;
-}
-
-/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
- * k2 * P(x, y), where G is the generator (base point) of the group of
- * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
- * Input and output values are assumed to be NOT field-encoded. */
-mp_err
-ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int sx, sy;
-
- ARGCHK(group != NULL, MP_BADARG);
- ARGCHK(!((k1 == NULL)
- && ((k2 == NULL) || (px == NULL)
- || (py == NULL))), MP_BADARG);
-
- /* if some arguments are not defined used ECPoint_mul */
- if (k1 == NULL) {
- return ECPoint_mul(group, k2, px, py, rx, ry);
- } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
- return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
- }
-
- MP_DIGITS(&sx) = 0;
- MP_DIGITS(&sy) = 0;
- MP_CHECKOK(mp_init(&sx));
- MP_CHECKOK(mp_init(&sy));
-
- MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy));
- MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry));
-
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->field_enc(&sx, &sx, group->meth));
- MP_CHECKOK(group->meth->field_enc(&sy, &sy, group->meth));
- MP_CHECKOK(group->meth->field_enc(rx, rx, group->meth));
- MP_CHECKOK(group->meth->field_enc(ry, ry, group->meth));
- }
-
- MP_CHECKOK(group->point_add(&sx, &sy, rx, ry, rx, ry, group));
-
- if (group->meth->field_dec) {
- MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
- MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
- }
-
- CLEANUP:
- mp_clear(&sx);
- mp_clear(&sy);
- return res;
-}
-
-/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
- * k2 * P(x, y), where G is the generator (base point) of the group of
- * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
- * Input and output values are assumed to be NOT field-encoded. Uses
- * algorithm 15 (simultaneous multiple point multiplication) from Brown,
- * Hankerson, Lopez, Menezes. Software Implementation of the NIST
- * Elliptic Curves over Prime Fields. */
-mp_err
-ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int precomp[4][4][2];
- const mp_int *a, *b;
- int i, j;
- int ai, bi, d;
-
- ARGCHK(group != NULL, MP_BADARG);
- ARGCHK(!((k1 == NULL)
- && ((k2 == NULL) || (px == NULL)
- || (py == NULL))), MP_BADARG);
-
- /* if some arguments are not defined used ECPoint_mul */
- if (k1 == NULL) {
- return ECPoint_mul(group, k2, px, py, rx, ry);
- } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
- return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
- }
-
- /* initialize precomputation table */
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- MP_DIGITS(&precomp[i][j][0]) = 0;
- MP_DIGITS(&precomp[i][j][1]) = 0;
- }
- }
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- MP_CHECKOK( mp_init_size(&precomp[i][j][0],
- ECL_MAX_FIELD_SIZE_DIGITS) );
- MP_CHECKOK( mp_init_size(&precomp[i][j][1],
- ECL_MAX_FIELD_SIZE_DIGITS) );
- }
- }
-
- /* fill precomputation table */
- /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
- if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
- a = k2;
- b = k1;
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->
- field_enc(px, &precomp[1][0][0], group->meth));
- MP_CHECKOK(group->meth->
- field_enc(py, &precomp[1][0][1], group->meth));
- } else {
- MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
- MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
- }
- MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
- MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
- } else {
- a = k1;
- b = k2;
- MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
- MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->
- field_enc(px, &precomp[0][1][0], group->meth));
- MP_CHECKOK(group->meth->
- field_enc(py, &precomp[0][1][1], group->meth));
- } else {
- MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
- MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
- }
- }
- /* precompute [*][0][*] */
- mp_zero(&precomp[0][0][0]);
- mp_zero(&precomp[0][0][1]);
- MP_CHECKOK(group->
- point_dbl(&precomp[1][0][0], &precomp[1][0][1],
- &precomp[2][0][0], &precomp[2][0][1], group));
- MP_CHECKOK(group->
- point_add(&precomp[1][0][0], &precomp[1][0][1],
- &precomp[2][0][0], &precomp[2][0][1],
- &precomp[3][0][0], &precomp[3][0][1], group));
- /* precompute [*][1][*] */
- for (i = 1; i < 4; i++) {
- MP_CHECKOK(group->
- point_add(&precomp[0][1][0], &precomp[0][1][1],
- &precomp[i][0][0], &precomp[i][0][1],
- &precomp[i][1][0], &precomp[i][1][1], group));
- }
- /* precompute [*][2][*] */
- MP_CHECKOK(group->
- point_dbl(&precomp[0][1][0], &precomp[0][1][1],
- &precomp[0][2][0], &precomp[0][2][1], group));
- for (i = 1; i < 4; i++) {
- MP_CHECKOK(group->
- point_add(&precomp[0][2][0], &precomp[0][2][1],
- &precomp[i][0][0], &precomp[i][0][1],
- &precomp[i][2][0], &precomp[i][2][1], group));
- }
- /* precompute [*][3][*] */
- MP_CHECKOK(group->
- point_add(&precomp[0][1][0], &precomp[0][1][1],
- &precomp[0][2][0], &precomp[0][2][1],
- &precomp[0][3][0], &precomp[0][3][1], group));
- for (i = 1; i < 4; i++) {
- MP_CHECKOK(group->
- point_add(&precomp[0][3][0], &precomp[0][3][1],
- &precomp[i][0][0], &precomp[i][0][1],
- &precomp[i][3][0], &precomp[i][3][1], group));
- }
-
- d = (mpl_significant_bits(a) + 1) / 2;
-
- /* R = inf */
- mp_zero(rx);
- mp_zero(ry);
-
- for (i = d - 1; i >= 0; i--) {
- ai = MP_GET_BIT(a, 2 * i + 1);
- ai <<= 1;
- ai |= MP_GET_BIT(a, 2 * i);
- bi = MP_GET_BIT(b, 2 * i + 1);
- bi <<= 1;
- bi |= MP_GET_BIT(b, 2 * i);
- /* R = 2^2 * R */
- MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
- MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group));
- /* R = R + (ai * A + bi * B) */
- MP_CHECKOK(group->
- point_add(rx, ry, &precomp[ai][bi][0],
- &precomp[ai][bi][1], rx, ry, group));
- }
-
- if (group->meth->field_dec) {
- MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
- MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
- }
-
- CLEANUP:
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- mp_clear(&precomp[i][j][0]);
- mp_clear(&precomp[i][j][1]);
- }
- }
- return res;
-}
-
-/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
- * k2 * P(x, y), where G is the generator (base point) of the group of
- * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
- * Input and output values are assumed to be NOT field-encoded. */
-mp_err
-ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2,
- const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry)
-{
- mp_err res = MP_OKAY;
- mp_int k1t, k2t;
- const mp_int *k1p, *k2p;
-
- MP_DIGITS(&k1t) = 0;
- MP_DIGITS(&k2t) = 0;
-
- ARGCHK(group != NULL, MP_BADARG);
-
- /* want scalar to be less than or equal to group order */
- if (k1 != NULL) {
- if (mp_cmp(k1, &group->order) >= 0) {
- MP_CHECKOK(mp_init(&k1t));
- MP_CHECKOK(mp_mod(k1, &group->order, &k1t));
- k1p = &k1t;
- } else {
- k1p = k1;
- }
- } else {
- k1p = k1;
- }
- if (k2 != NULL) {
- if (mp_cmp(k2, &group->order) >= 0) {
- MP_CHECKOK(mp_init(&k2t));
- MP_CHECKOK(mp_mod(k2, &group->order, &k2t));
- k2p = &k2t;
- } else {
- k2p = k2;
- }
- } else {
- k2p = k2;
- }
-
- /* if points_mul is defined, then use it */
- if (group->points_mul) {
- res = group->points_mul(k1p, k2p, px, py, rx, ry, group);
- } else {
- res = ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group);
- }
-
- CLEANUP:
- mp_clear(&k1t);
- mp_clear(&k2t);
- return res;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp.h b/security/nss/lib/freebl/ecl/ecp.h
deleted file mode 100644
index 4784b022f..000000000
--- a/security/nss/lib/freebl/ecl/ecp.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __ecp_h_
-#define __ecp_h_
-
-#include "ecl-priv.h"
-
-/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
-mp_err ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py);
-
-/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
-mp_err ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py);
-
-/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx,
- * qy). Uses affine coordinates. */
-mp_err ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py,
- const mp_int *qx, const mp_int *qy, mp_int *rx,
- mp_int *ry, const ECGroup *group);
-
-/* Computes R = P - Q. Uses affine coordinates. */
-mp_err ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py,
- const mp_int *qx, const mp_int *qy, mp_int *rx,
- mp_int *ry, const ECGroup *group);
-
-/* Computes R = 2P. Uses affine coordinates. */
-mp_err ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, const ECGroup *group);
-
-/* Validates a point on a GFp curve. */
-mp_err ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group);
-
-#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
-/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
- * a, b and p are the elliptic curve coefficients and the prime that
- * determines the field GFp. Uses affine coordinates. */
-mp_err ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group);
-#endif
-
-/* Converts a point P(px, py) from affine coordinates to Jacobian
- * projective coordinates R(rx, ry, rz). */
-mp_err ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, mp_int *rz, const ECGroup *group);
-
-/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
- * affine coordinates R(rx, ry). */
-mp_err ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py,
- const mp_int *pz, mp_int *rx, mp_int *ry,
- const ECGroup *group);
-
-/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
- * coordinates. */
-mp_err ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py,
- const mp_int *pz);
-
-/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
- * coordinates. */
-mp_err ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz);
-
-/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
- * (qx, qy, qz). Uses Jacobian coordinates. */
-mp_err ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py,
- const mp_int *pz, const mp_int *qx,
- const mp_int *qy, mp_int *rx, mp_int *ry,
- mp_int *rz, const ECGroup *group);
-
-/* Computes R = 2P. Uses Jacobian coordinates. */
-mp_err ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py,
- const mp_int *pz, mp_int *rx, mp_int *ry,
- mp_int *rz, const ECGroup *group);
-
-#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
-/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
- * a, b and p are the elliptic curve coefficients and the prime that
- * determines the field GFp. Uses Jacobian coordinates. */
-mp_err ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group);
-#endif
-
-/* Computes R(x, y) = k1 * G + k2 * P(x, y), where G is the generator
- * (base point) of the group of points on the elliptic curve. Allows k1 =
- * NULL or { k2, P } = NULL. Implemented using mixed Jacobian-affine
- * coordinates. Input and output values are assumed to be NOT
- * field-encoded and are in affine form. */
-mp_err
- ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group);
-
-/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
- * curve points P and R can be identical. Uses mixed Modified-Jacobian
- * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
- * additions. Assumes input is already field-encoded using field_enc, and
- * returns output that is still field-encoded. Uses 5-bit window NAF
- * method (algorithm 11) for scalar-point multiplication from Brown,
- * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
- * Curves Over Prime Fields. */
-mp_err
- ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
- mp_int *rx, mp_int *ry, const ECGroup *group);
-
-#endif /* __ecp_h_ */
diff --git a/security/nss/lib/freebl/ecl/ecp_192.c b/security/nss/lib/freebl/ecl/ecp_192.c
deleted file mode 100644
index 9a71cd894..000000000
--- a/security/nss/lib/freebl/ecl/ecp_192.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp.h"
-#include "mpi.h"
-#include "mplogic.h"
-#include "mpi-priv.h"
-#include <stdlib.h>
-
-#define ECP192_DIGITS ECL_CURVE_DIGITS(192)
-
-/* Fast modular reduction for p192 = 2^192 - 2^64 - 1. a can be r. Uses
- * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
- * Implementation of the NIST Elliptic Curves over Prime Fields. */
-mp_err
-ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_size a_used = MP_USED(a);
- mp_digit r3;
-#ifndef MPI_AMD64_ADD
- mp_digit carry;
-#endif
-#ifdef ECL_THIRTY_TWO_BIT
- mp_digit a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
- mp_digit r0a, r0b, r1a, r1b, r2a, r2b;
-#else
- mp_digit a5 = 0, a4 = 0, a3 = 0;
- mp_digit r0, r1, r2;
-#endif
-
- /* reduction not needed if a is not larger than field size */
- if (a_used < ECP192_DIGITS) {
- if (a == r) {
- return MP_OKAY;
- }
- return mp_copy(a, r);
- }
-
- /* for polynomials larger than twice the field size, use regular
- * reduction */
- if (a_used > ECP192_DIGITS*2) {
- MP_CHECKOK(mp_mod(a, &meth->irr, r));
- } else {
- /* copy out upper words of a */
-
-#ifdef ECL_THIRTY_TWO_BIT
-
- /* in all the math below,
- * nXb is most signifiant, nXa is least significant */
- switch (a_used) {
- case 12:
- a5b = MP_DIGIT(a, 11);
- case 11:
- a5a = MP_DIGIT(a, 10);
- case 10:
- a4b = MP_DIGIT(a, 9);
- case 9:
- a4a = MP_DIGIT(a, 8);
- case 8:
- a3b = MP_DIGIT(a, 7);
- case 7:
- a3a = MP_DIGIT(a, 6);
- }
-
-
- r2b= MP_DIGIT(a, 5);
- r2a= MP_DIGIT(a, 4);
- r1b = MP_DIGIT(a, 3);
- r1a = MP_DIGIT(a, 2);
- r0b = MP_DIGIT(a, 1);
- r0a = MP_DIGIT(a, 0);
-
- /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
- MP_ADD_CARRY(r0a, a3a, r0a, 0, carry);
- MP_ADD_CARRY(r0b, a3b, r0b, carry, carry);
- MP_ADD_CARRY(r1a, a3a, r1a, carry, carry);
- MP_ADD_CARRY(r1b, a3b, r1b, carry, carry);
- MP_ADD_CARRY(r2a, a4a, r2a, carry, carry);
- MP_ADD_CARRY(r2b, a4b, r2b, carry, carry);
- r3 = carry; carry = 0;
- MP_ADD_CARRY(r0a, a5a, r0a, 0, carry);
- MP_ADD_CARRY(r0b, a5b, r0b, carry, carry);
- MP_ADD_CARRY(r1a, a5a, r1a, carry, carry);
- MP_ADD_CARRY(r1b, a5b, r1b, carry, carry);
- MP_ADD_CARRY(r2a, a5a, r2a, carry, carry);
- MP_ADD_CARRY(r2b, a5b, r2b, carry, carry);
- r3 += carry;
- MP_ADD_CARRY(r1a, a4a, r1a, 0, carry);
- MP_ADD_CARRY(r1b, a4b, r1b, carry, carry);
- MP_ADD_CARRY(r2a, 0, r2a, carry, carry);
- MP_ADD_CARRY(r2b, 0, r2b, carry, carry);
- r3 += carry;
-
- /* reduce out the carry */
- while (r3) {
- MP_ADD_CARRY(r0a, r3, r0a, 0, carry);
- MP_ADD_CARRY(r0b, 0, r0b, carry, carry);
- MP_ADD_CARRY(r1a, r3, r1a, carry, carry);
- MP_ADD_CARRY(r1b, 0, r1b, carry, carry);
- MP_ADD_CARRY(r2a, 0, r2a, carry, carry);
- MP_ADD_CARRY(r2b, 0, r2b, carry, carry);
- r3 = carry;
- }
-
- /* check for final reduction */
- /*
- * our field is 0xffffffffffffffff, 0xfffffffffffffffe,
- * 0xffffffffffffffff. That means we can only be over and need
- * one more reduction
- * if r2 == 0xffffffffffffffffff (same as r2+1 == 0)
- * and
- * r1 == 0xffffffffffffffffff or
- * r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff
- * In all cases, we subtract the field (or add the 2's
- * complement value (1,1,0)). (r0, r1, r2)
- */
- if (((r2b == 0xffffffff) && (r2a == 0xffffffff)
- && (r1b == 0xffffffff) ) &&
- ((r1a == 0xffffffff) ||
- (r1a == 0xfffffffe) && (r0a == 0xffffffff) &&
- (r0b == 0xffffffff)) ) {
- /* do a quick subtract */
- MP_ADD_CARRY(r0a, 1, r0a, 0, carry);
- MP_ADD_CARRY(r0b, carry, r0a, 0, carry);
- r1a += 1+carry;
- r1b = r2a = r2b = 0;
- }
-
- /* set the lower words of r */
- if (a != r) {
- MP_CHECKOK(s_mp_pad(r, 6));
- }
- MP_DIGIT(r, 5) = r2b;
- MP_DIGIT(r, 4) = r2a;
- MP_DIGIT(r, 3) = r1b;
- MP_DIGIT(r, 2) = r1a;
- MP_DIGIT(r, 1) = r0b;
- MP_DIGIT(r, 0) = r0a;
- MP_USED(r) = 6;
-#else
- switch (a_used) {
- case 6:
- a5 = MP_DIGIT(a, 5);
- case 5:
- a4 = MP_DIGIT(a, 4);
- case 4:
- a3 = MP_DIGIT(a, 3);
- }
-
- r2 = MP_DIGIT(a, 2);
- r1 = MP_DIGIT(a, 1);
- r0 = MP_DIGIT(a, 0);
-
- /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */
-#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(r0, a3, r0, 0, carry);
- MP_ADD_CARRY(r1, a3, r1, carry, carry);
- MP_ADD_CARRY(r2, a4, r2, carry, carry);
- r3 = carry;
- MP_ADD_CARRY(r0, a5, r0, 0, carry);
- MP_ADD_CARRY(r1, a5, r1, carry, carry);
- MP_ADD_CARRY(r2, a5, r2, carry, carry);
- r3 += carry;
- MP_ADD_CARRY(r1, a4, r1, 0, carry);
- MP_ADD_CARRY(r2, 0, r2, carry, carry);
- r3 += carry;
-
-#else
- r2 = MP_DIGIT(a, 2);
- r1 = MP_DIGIT(a, 1);
- r0 = MP_DIGIT(a, 0);
-
- /* set the lower words of r */
- __asm__ (
- "xorq %3,%3 \n\t"
- "addq %4,%0 \n\t"
- "adcq %4,%1 \n\t"
- "adcq %5,%2 \n\t"
- "adcq $0,%3 \n\t"
- "addq %6,%0 \n\t"
- "adcq %6,%1 \n\t"
- "adcq %6,%2 \n\t"
- "adcq $0,%3 \n\t"
- "addq %5,%1 \n\t"
- "adcq $0,%2 \n\t"
- "adcq $0,%3 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3),
- "=r"(a4), "=r"(a5)
- : "0" (r0), "1" (r1), "2" (r2), "3" (r3),
- "4" (a3), "5" (a4), "6"(a5)
- : "%cc" );
-#endif
-
- /* reduce out the carry */
- while (r3) {
-#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(r0, r3, r0, 0, carry);
- MP_ADD_CARRY(r1, r3, r1, carry, carry);
- MP_ADD_CARRY(r2, 0, r2, carry, carry);
- r3 = carry;
-#else
- a3=r3;
- __asm__ (
- "xorq %3,%3 \n\t"
- "addq %4,%0 \n\t"
- "adcq %4,%1 \n\t"
- "adcq $0,%2 \n\t"
- "adcq $0,%3 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3)
- : "0" (r0), "1" (r1), "2" (r2), "3" (r3), "4"(a3)
- : "%cc" );
-#endif
- }
-
- /* check for final reduction */
- /*
- * our field is 0xffffffffffffffff, 0xfffffffffffffffe,
- * 0xffffffffffffffff. That means we can only be over and need
- * one more reduction
- * if r2 == 0xffffffffffffffffff (same as r2+1 == 0)
- * and
- * r1 == 0xffffffffffffffffff or
- * r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff
- * In all cases, we subtract the field (or add the 2's
- * complement value (1,1,0)). (r0, r1, r2)
- */
- if (r3 || ((r2 == MP_DIGIT_MAX) &&
- ((r1 == MP_DIGIT_MAX) ||
- ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
- /* do a quick subtract */
- MP_ADD_CARRY(r0, 1, r0, 0, carry);
- r1 += 1+carry;
- r2 = 0;
- }
- /* set the lower words of r */
- if (a != r) {
- MP_CHECKOK(s_mp_pad(r, 3));
- }
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_USED(r) = 3;
-#endif
- }
- s_mp_clamp(r);
- CLEANUP:
- return res;
-}
-
-#ifndef ECL_THIRTY_TWO_BIT
-/* Compute the sum of 192 bit curves. Do the work in-line since the
- * number of words are so small, we don't want to overhead of mp function
- * calls. Uses optimized modular reduction for p192.
- */
-mp_err
-ec_GFp_nistp192_add(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit a0 = 0, a1 = 0, a2 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0;
- mp_digit carry;
-
- switch(MP_USED(a)) {
- case 3:
- a2 = MP_DIGIT(a,2);
- case 2:
- a1 = MP_DIGIT(a,1);
- case 1:
- a0 = MP_DIGIT(a,0);
- }
- switch(MP_USED(b)) {
- case 3:
- r2 = MP_DIGIT(b,2);
- case 2:
- r1 = MP_DIGIT(b,1);
- case 1:
- r0 = MP_DIGIT(b,0);
- }
-
-#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(a0, r0, r0, 0, carry);
- MP_ADD_CARRY(a1, r1, r1, carry, carry);
- MP_ADD_CARRY(a2, r2, r2, carry, carry);
-#else
- __asm__ (
- "xorq %3,%3 \n\t"
- "addq %4,%0 \n\t"
- "adcq %5,%1 \n\t"
- "adcq %6,%2 \n\t"
- "adcq $0,%3 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry)
- : "r" (a0), "r" (a1), "r" (a2), "0" (r0),
- "1" (r1), "2" (r2)
- : "%cc" );
-#endif
-
- /* Do quick 'subract' if we've gone over
- * (add the 2's complement of the curve field) */
- if (carry || ((r2 == MP_DIGIT_MAX) &&
- ((r1 == MP_DIGIT_MAX) ||
- ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) {
-#ifndef MPI_AMD64_ADD
- MP_ADD_CARRY(r0, 1, r0, 0, carry);
- MP_ADD_CARRY(r1, 1, r1, carry, carry);
- MP_ADD_CARRY(r2, 0, r2, carry, carry);
-#else
- __asm__ (
- "addq $1,%0 \n\t"
- "adcq $1,%1 \n\t"
- "adcq $0,%2 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2)
- : "0" (r0), "1" (r1), "2" (r2)
- : "%cc" );
-#endif
- }
-
-
- MP_CHECKOK(s_mp_pad(r, 3));
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 3;
- s_mp_clamp(r);
-
-
- CLEANUP:
- return res;
-}
-
-/* Compute the diff of 192 bit curves. Do the work in-line since the
- * number of words are so small, we don't want to overhead of mp function
- * calls. Uses optimized modular reduction for p192.
- */
-mp_err
-ec_GFp_nistp192_sub(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_digit b0 = 0, b1 = 0, b2 = 0;
- mp_digit r0 = 0, r1 = 0, r2 = 0;
- mp_digit borrow;
-
- switch(MP_USED(a)) {
- case 3:
- r2 = MP_DIGIT(a,2);
- case 2:
- r1 = MP_DIGIT(a,1);
- case 1:
- r0 = MP_DIGIT(a,0);
- }
-
- switch(MP_USED(b)) {
- case 3:
- b2 = MP_DIGIT(b,2);
- case 2:
- b1 = MP_DIGIT(b,1);
- case 1:
- b0 = MP_DIGIT(b,0);
- }
-
-#ifndef MPI_AMD64_ADD
- MP_SUB_BORROW(r0, b0, r0, 0, borrow);
- MP_SUB_BORROW(r1, b1, r1, borrow, borrow);
- MP_SUB_BORROW(r2, b2, r2, borrow, borrow);
-#else
- __asm__ (
- "xorq %3,%3 \n\t"
- "subq %4,%0 \n\t"
- "sbbq %5,%1 \n\t"
- "sbbq %6,%2 \n\t"
- "adcq $0,%3 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(borrow)
- : "r" (b0), "r" (b1), "r" (b2), "0" (r0),
- "1" (r1), "2" (r2)
- : "%cc" );
-#endif
-
- /* Do quick 'add' if we've gone under 0
- * (subtract the 2's complement of the curve field) */
- if (borrow) {
-#ifndef MPI_AMD64_ADD
- MP_SUB_BORROW(r0, 1, r0, 0, borrow);
- MP_SUB_BORROW(r1, 1, r1, borrow, borrow);
- MP_SUB_BORROW(r2, 0, r2, borrow, borrow);
-#else
- __asm__ (
- "subq $1,%0 \n\t"
- "sbbq $1,%1 \n\t"
- "sbbq $0,%2 \n\t"
- : "=r"(r0), "=r"(r1), "=r"(r2)
- : "0" (r0), "1" (r1), "2" (r2)
- : "%cc" );
-#endif
- }
-
- MP_CHECKOK(s_mp_pad(r, 3));
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 3;
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-#endif
-
-/* Compute the square of polynomial a, reduce modulo p192. Store the
- * result in r. r could be a. Uses optimized modular reduction for p192.
- */
-mp_err
-ec_GFp_nistp192_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_sqr(a, r));
- MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Compute the product of two polynomials a and b, reduce modulo p192.
- * Store the result in r. r could be a or b; a could be b. Uses
- * optimized modular reduction for p192. */
-mp_err
-ec_GFp_nistp192_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_mul(a, b, r));
- MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Divides two field elements. If a is NULL, then returns the inverse of
- * b. */
-mp_err
-ec_GFp_nistp192_div(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_int t;
-
- /* If a is NULL, then return the inverse of b, otherwise return a/b. */
- if (a == NULL) {
- return mp_invmod(b, &meth->irr, r);
- } else {
- /* MPI doesn't support divmod, so we implement it using invmod and
- * mulmod. */
- MP_CHECKOK(mp_init(&t));
- MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
- MP_CHECKOK(mp_mul(a, &t, r));
- MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth));
- CLEANUP:
- mp_clear(&t);
- return res;
- }
-}
-
-/* Wire in fast field arithmetic and precomputation of base point for
- * named curves. */
-mp_err
-ec_group_set_gfp192(ECGroup *group, ECCurveName name)
-{
- if (name == ECCurve_NIST_P192) {
- group->meth->field_mod = &ec_GFp_nistp192_mod;
- group->meth->field_mul = &ec_GFp_nistp192_mul;
- group->meth->field_sqr = &ec_GFp_nistp192_sqr;
- group->meth->field_div = &ec_GFp_nistp192_div;
-#ifndef ECL_THIRTY_TWO_BIT
- group->meth->field_add = &ec_GFp_nistp192_add;
- group->meth->field_sub = &ec_GFp_nistp192_sub;
-#endif
- }
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_224.c b/security/nss/lib/freebl/ecl/ecp_224.c
deleted file mode 100644
index b1a3e4d72..000000000
--- a/security/nss/lib/freebl/ecl/ecp_224.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp.h"
-#include "mpi.h"
-#include "mplogic.h"
-#include "mpi-priv.h"
-#include <stdlib.h>
-
-#define ECP224_DIGITS ECL_CURVE_DIGITS(224)
-
-/* Fast modular reduction for p224 = 2^224 - 2^96 + 1. a can be r. Uses
- * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software
- * Implementation of the NIST Elliptic Curves over Prime Fields. */
-mp_err
-ec_GFp_nistp224_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_size a_used = MP_USED(a);
-
- int r3b;
- mp_digit carry;
-#ifdef ECL_THIRTY_TWO_BIT
- mp_digit a6a = 0, a6b = 0,
- a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0;
- mp_digit r0a, r0b, r1a, r1b, r2a, r2b, r3a;
-#else
- mp_digit a6 = 0, a5 = 0, a4 = 0, a3b = 0, a5a = 0;
- mp_digit a6b = 0, a6a_a5b = 0, a5b = 0, a5a_a4b = 0, a4a_a3b = 0;
- mp_digit r0, r1, r2, r3;
-#endif
-
- /* reduction not needed if a is not larger than field size */
- if (a_used < ECP224_DIGITS) {
- if (a == r) return MP_OKAY;
- return mp_copy(a, r);
- }
- /* for polynomials larger than twice the field size, use regular
- * reduction */
- if (a_used > ECL_CURVE_DIGITS(224*2)) {
- MP_CHECKOK(mp_mod(a, &meth->irr, r));
- } else {
-#ifdef ECL_THIRTY_TWO_BIT
- /* copy out upper words of a */
- switch (a_used) {
- case 14:
- a6b = MP_DIGIT(a, 13);
- case 13:
- a6a = MP_DIGIT(a, 12);
- case 12:
- a5b = MP_DIGIT(a, 11);
- case 11:
- a5a = MP_DIGIT(a, 10);
- case 10:
- a4b = MP_DIGIT(a, 9);
- case 9:
- a4a = MP_DIGIT(a, 8);
- case 8:
- a3b = MP_DIGIT(a, 7);
- }
- r3a = MP_DIGIT(a, 6);
- r2b= MP_DIGIT(a, 5);
- r2a= MP_DIGIT(a, 4);
- r1b = MP_DIGIT(a, 3);
- r1a = MP_DIGIT(a, 2);
- r0b = MP_DIGIT(a, 1);
- r0a = MP_DIGIT(a, 0);
-
-
- /* implement r = (a3a,a2,a1,a0)
- +(a5a, a4,a3b, 0)
- +( 0, a6,a5b, 0)
- -( 0 0, 0|a6b, a6a|a5b )
- -( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
- MP_ADD_CARRY (r1b, a3b, r1b, 0, carry);
- MP_ADD_CARRY (r2a, a4a, r2a, carry, carry);
- MP_ADD_CARRY (r2b, a4b, r2b, carry, carry);
- MP_ADD_CARRY (r3a, a5a, r3a, carry, carry);
- r3b = carry;
- MP_ADD_CARRY (r1b, a5b, r1b, 0, carry);
- MP_ADD_CARRY (r2a, a6a, r2a, carry, carry);
- MP_ADD_CARRY (r2b, a6b, r2b, carry, carry);
- MP_ADD_CARRY (r3a, 0, r3a, carry, carry);
- r3b += carry;
- MP_SUB_BORROW(r0a, a3b, r0a, 0, carry);
- MP_SUB_BORROW(r0b, a4a, r0b, carry, carry);
- MP_SUB_BORROW(r1a, a4b, r1a, carry, carry);
- MP_SUB_BORROW(r1b, a5a, r1b, carry, carry);
- MP_SUB_BORROW(r2a, a5b, r2a, carry, carry);
- MP_SUB_BORROW(r2b, a6a, r2b, carry, carry);
- MP_SUB_BORROW(r3a, a6b, r3a, carry, carry);
- r3b -= carry;
- MP_SUB_BORROW(r0a, a5b, r0a, 0, carry);
- MP_SUB_BORROW(r0b, a6a, r0b, carry, carry);
- MP_SUB_BORROW(r1a, a6b, r1a, carry, carry);
- if (carry) {
- MP_SUB_BORROW(r1b, 0, r1b, carry, carry);
- MP_SUB_BORROW(r2a, 0, r2a, carry, carry);
- MP_SUB_BORROW(r2b, 0, r2b, carry, carry);
- MP_SUB_BORROW(r3a, 0, r3a, carry, carry);
- r3b -= carry;
- }
-
- while (r3b > 0) {
- int tmp;
- MP_ADD_CARRY(r1b, r3b, r1b, 0, carry);
- if (carry) {
- MP_ADD_CARRY(r2a, 0, r2a, carry, carry);
- MP_ADD_CARRY(r2b, 0, r2b, carry, carry);
- MP_ADD_CARRY(r3a, 0, r3a, carry, carry);
- }
- tmp = carry;
- MP_SUB_BORROW(r0a, r3b, r0a, 0, carry);
- if (carry) {
- MP_SUB_BORROW(r0b, 0, r0b, carry, carry);
- MP_SUB_BORROW(r1a, 0, r1a, carry, carry);
- MP_SUB_BORROW(r1b, 0, r1b, carry, carry);
- MP_SUB_BORROW(r2a, 0, r2a, carry, carry);
- MP_SUB_BORROW(r2b, 0, r2b, carry, carry);
- MP_SUB_BORROW(r3a, 0, r3a, carry, carry);
- tmp -= carry;
- }
- r3b = tmp;
- }
-
- while (r3b < 0) {
- mp_digit maxInt = MP_DIGIT_MAX;
- MP_ADD_CARRY (r0a, 1, r0a, 0, carry);
- MP_ADD_CARRY (r0b, 0, r0b, carry, carry);
- MP_ADD_CARRY (r1a, 0, r1a, carry, carry);
- MP_ADD_CARRY (r1b, maxInt, r1b, carry, carry);
- MP_ADD_CARRY (r2a, maxInt, r2a, carry, carry);
- MP_ADD_CARRY (r2b, maxInt, r2b, carry, carry);
- MP_ADD_CARRY (r3a, maxInt, r3a, carry, carry);
- r3b += carry;
- }
- /* check for final reduction */
- /* now the only way we are over is if the top 4 words are all ones */
- if ((r3a == MP_DIGIT_MAX) && (r2b == MP_DIGIT_MAX)
- && (r2a == MP_DIGIT_MAX) && (r1b == MP_DIGIT_MAX) &&
- ((r1a != 0) || (r0b != 0) || (r0a != 0)) ) {
- /* one last subraction */
- MP_SUB_BORROW(r0a, 1, r0a, 0, carry);
- MP_SUB_BORROW(r0b, 0, r0b, carry, carry);
- MP_SUB_BORROW(r1a, 0, r1a, carry, carry);
- r1b = r2a = r2b = r3a = 0;
- }
-
-
- if (a != r) {
- MP_CHECKOK(s_mp_pad(r, 7));
- }
- /* set the lower words of r */
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 7;
- MP_DIGIT(r, 6) = r3a;
- MP_DIGIT(r, 5) = r2b;
- MP_DIGIT(r, 4) = r2a;
- MP_DIGIT(r, 3) = r1b;
- MP_DIGIT(r, 2) = r1a;
- MP_DIGIT(r, 1) = r0b;
- MP_DIGIT(r, 0) = r0a;
-#else
- /* copy out upper words of a */
- switch (a_used) {
- case 7:
- a6 = MP_DIGIT(a, 6);
- a6b = a6 >> 32;
- a6a_a5b = a6 << 32;
- case 6:
- a5 = MP_DIGIT(a, 5);
- a5b = a5 >> 32;
- a6a_a5b |= a5b;
- a5b = a5b << 32;
- a5a_a4b = a5 << 32;
- a5a = a5 & 0xffffffff;
- case 5:
- a4 = MP_DIGIT(a, 4);
- a5a_a4b |= a4 >> 32;
- a4a_a3b = a4 << 32;
- case 4:
- a3b = MP_DIGIT(a, 3) >> 32;
- a4a_a3b |= a3b;
- a3b = a3b << 32;
- }
-
- r3 = MP_DIGIT(a, 3) & 0xffffffff;
- r2 = MP_DIGIT(a, 2);
- r1 = MP_DIGIT(a, 1);
- r0 = MP_DIGIT(a, 0);
-
- /* implement r = (a3a,a2,a1,a0)
- +(a5a, a4,a3b, 0)
- +( 0, a6,a5b, 0)
- -( 0 0, 0|a6b, a6a|a5b )
- -( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */
- MP_ADD_CARRY (r1, a3b, r1, 0, carry);
- MP_ADD_CARRY (r2, a4 , r2, carry, carry);
- MP_ADD_CARRY (r3, a5a, r3, carry, carry);
- MP_ADD_CARRY (r1, a5b, r1, 0, carry);
- MP_ADD_CARRY (r2, a6 , r2, carry, carry);
- MP_ADD_CARRY (r3, 0, r3, carry, carry);
-
- MP_SUB_BORROW(r0, a4a_a3b, r0, 0, carry);
- MP_SUB_BORROW(r1, a5a_a4b, r1, carry, carry);
- MP_SUB_BORROW(r2, a6a_a5b, r2, carry, carry);
- MP_SUB_BORROW(r3, a6b , r3, carry, carry);
- MP_SUB_BORROW(r0, a6a_a5b, r0, 0, carry);
- MP_SUB_BORROW(r1, a6b , r1, carry, carry);
- if (carry) {
- MP_SUB_BORROW(r2, 0, r2, carry, carry);
- MP_SUB_BORROW(r3, 0, r3, carry, carry);
- }
-
-
- /* if the value is negative, r3 has a 2's complement
- * high value */
- r3b = (int)(r3 >>32);
- while (r3b > 0) {
- r3 &= 0xffffffff;
- MP_ADD_CARRY(r1,((mp_digit)r3b) << 32, r1, 0, carry);
- if (carry) {
- MP_ADD_CARRY(r2, 0, r2, carry, carry);
- MP_ADD_CARRY(r3, 0, r3, carry, carry);
- }
- MP_SUB_BORROW(r0, r3b, r0, 0, carry);
- if (carry) {
- MP_SUB_BORROW(r1, 0, r1, carry, carry);
- MP_SUB_BORROW(r2, 0, r2, carry, carry);
- MP_SUB_BORROW(r3, 0, r3, carry, carry);
- }
- r3b = (int)(r3 >>32);
- }
-
- while (r3b < 0) {
- MP_ADD_CARRY (r0, 1, r0, 0, carry);
- MP_ADD_CARRY (r1, MP_DIGIT_MAX <<32, r1, carry, carry);
- MP_ADD_CARRY (r2, MP_DIGIT_MAX, r2, carry, carry);
- MP_ADD_CARRY (r3, MP_DIGIT_MAX >> 32, r3, carry, carry);
- r3b = (int)(r3 >>32);
- }
- /* check for final reduction */
- /* now the only way we are over is if the top 4 words are
- * all ones. Subtract the curve. (curve is 2^224 - 2^96 +1)
- */
- if ((r3 == (MP_DIGIT_MAX >> 32)) && (r2 == MP_DIGIT_MAX)
- && ((r1 & MP_DIGIT_MAX << 32)== MP_DIGIT_MAX << 32) &&
- ((r1 != MP_DIGIT_MAX << 32 ) || (r0 != 0)) ) {
- /* one last subraction */
- MP_SUB_BORROW(r0, 1, r0, 0, carry);
- MP_SUB_BORROW(r1, MP_DIGIT_MAX << 32, r1, carry, carry);
- r2 = r3 = 0;
- }
-
-
- if (a != r) {
- MP_CHECKOK(s_mp_pad(r, 4));
- }
- /* set the lower words of r */
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 4;
- MP_DIGIT(r, 3) = r3;
- MP_DIGIT(r, 2) = r2;
- MP_DIGIT(r, 1) = r1;
- MP_DIGIT(r, 0) = r0;
-#endif
- }
- s_mp_clamp(r);
-
- CLEANUP:
- return res;
-}
-
-/* Compute the square of polynomial a, reduce modulo p224. Store the
- * result in r. r could be a. Uses optimized modular reduction for p224.
- */
-mp_err
-ec_GFp_nistp224_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_sqr(a, r));
- MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Compute the product of two polynomials a and b, reduce modulo p224.
- * Store the result in r. r could be a or b; a could be b. Uses
- * optimized modular reduction for p224. */
-mp_err
-ec_GFp_nistp224_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_mul(a, b, r));
- MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Divides two field elements. If a is NULL, then returns the inverse of
- * b. */
-mp_err
-ec_GFp_nistp224_div(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_int t;
-
- /* If a is NULL, then return the inverse of b, otherwise return a/b. */
- if (a == NULL) {
- return mp_invmod(b, &meth->irr, r);
- } else {
- /* MPI doesn't support divmod, so we implement it using invmod and
- * mulmod. */
- MP_CHECKOK(mp_init(&t));
- MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
- MP_CHECKOK(mp_mul(a, &t, r));
- MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth));
- CLEANUP:
- mp_clear(&t);
- return res;
- }
-}
-
-/* Wire in fast field arithmetic and precomputation of base point for
- * named curves. */
-mp_err
-ec_group_set_gfp224(ECGroup *group, ECCurveName name)
-{
- if (name == ECCurve_NIST_P224) {
- group->meth->field_mod = &ec_GFp_nistp224_mod;
- group->meth->field_mul = &ec_GFp_nistp224_mul;
- group->meth->field_sqr = &ec_GFp_nistp224_sqr;
- group->meth->field_div = &ec_GFp_nistp224_div;
- }
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_256.c b/security/nss/lib/freebl/ecl/ecp_256.c
deleted file mode 100644
index a834d15d4..000000000
--- a/security/nss/lib/freebl/ecl/ecp_256.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp.h"
-#include "mpi.h"
-#include "mplogic.h"
-#include "mpi-priv.h"
-
-/* Fast modular reduction for p256 = 2^256 - 2^224 + 2^192+ 2^96 - 1. a can be r.
- * Uses algorithm 2.29 from Hankerson, Menezes, Vanstone. Guide to
- * Elliptic Curve Cryptography. */
-static mp_err
-ec_GFp_nistp256_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_size a_used = MP_USED(a);
- int a_bits = mpl_significant_bits(a);
- mp_digit carry;
-
-#ifdef ECL_THIRTY_TWO_BIT
- mp_digit a8=0, a9=0, a10=0, a11=0, a12=0, a13=0, a14=0, a15=0;
- mp_digit r0, r1, r2, r3, r4, r5, r6, r7;
- int r8; /* must be a signed value ! */
-#else
- mp_digit a4=0, a5=0, a6=0, a7=0;
- mp_digit a4h, a4l, a5h, a5l, a6h, a6l, a7h, a7l;
- mp_digit r0, r1, r2, r3;
- int r4; /* must be a signed value ! */
-#endif
- /* for polynomials larger than twice the field size
- * use regular reduction */
- if (a_bits < 256) {
- if (a == r) return MP_OKAY;
- return mp_copy(a,r);
- }
- if (a_bits > 512) {
- MP_CHECKOK(mp_mod(a, &meth->irr, r));
- } else {
-
-#ifdef ECL_THIRTY_TWO_BIT
- switch (a_used) {
- case 16:
- a15 = MP_DIGIT(a,15);
- case 15:
- a14 = MP_DIGIT(a,14);
- case 14:
- a13 = MP_DIGIT(a,13);
- case 13:
- a12 = MP_DIGIT(a,12);
- case 12:
- a11 = MP_DIGIT(a,11);
- case 11:
- a10 = MP_DIGIT(a,10);
- case 10:
- a9 = MP_DIGIT(a,9);
- case 9:
- a8 = MP_DIGIT(a,8);
- }
-
- r0 = MP_DIGIT(a,0);
- r1 = MP_DIGIT(a,1);
- r2 = MP_DIGIT(a,2);
- r3 = MP_DIGIT(a,3);
- r4 = MP_DIGIT(a,4);
- r5 = MP_DIGIT(a,5);
- r6 = MP_DIGIT(a,6);
- r7 = MP_DIGIT(a,7);
-
- /* sum 1 */
- MP_ADD_CARRY(r3, a11, r3, 0, carry);
- MP_ADD_CARRY(r4, a12, r4, carry, carry);
- MP_ADD_CARRY(r5, a13, r5, carry, carry);
- MP_ADD_CARRY(r6, a14, r6, carry, carry);
- MP_ADD_CARRY(r7, a15, r7, carry, carry);
- r8 = carry;
- MP_ADD_CARRY(r3, a11, r3, 0, carry);
- MP_ADD_CARRY(r4, a12, r4, carry, carry);
- MP_ADD_CARRY(r5, a13, r5, carry, carry);
- MP_ADD_CARRY(r6, a14, r6, carry, carry);
- MP_ADD_CARRY(r7, a15, r7, carry, carry);
- r8 += carry;
- /* sum 2 */
- MP_ADD_CARRY(r3, a12, r3, 0, carry);
- MP_ADD_CARRY(r4, a13, r4, carry, carry);
- MP_ADD_CARRY(r5, a14, r5, carry, carry);
- MP_ADD_CARRY(r6, a15, r6, carry, carry);
- MP_ADD_CARRY(r7, 0, r7, carry, carry);
- r8 += carry;
- /* combine last bottom of sum 3 with second sum 2 */
- MP_ADD_CARRY(r0, a8, r0, 0, carry);
- MP_ADD_CARRY(r1, a9, r1, carry, carry);
- MP_ADD_CARRY(r2, a10, r2, carry, carry);
- MP_ADD_CARRY(r3, a12, r3, carry, carry);
- MP_ADD_CARRY(r4, a13, r4, carry, carry);
- MP_ADD_CARRY(r5, a14, r5, carry, carry);
- MP_ADD_CARRY(r6, a15, r6, carry, carry);
- MP_ADD_CARRY(r7, a15, r7, carry, carry); /* from sum 3 */
- r8 += carry;
- /* sum 3 (rest of it)*/
- MP_ADD_CARRY(r6, a14, r6, 0, carry);
- MP_ADD_CARRY(r7, 0, r7, carry, carry);
- r8 += carry;
- /* sum 4 (rest of it)*/
- MP_ADD_CARRY(r0, a9, r0, 0, carry);
- MP_ADD_CARRY(r1, a10, r1, carry, carry);
- MP_ADD_CARRY(r2, a11, r2, carry, carry);
- MP_ADD_CARRY(r3, a13, r3, carry, carry);
- MP_ADD_CARRY(r4, a14, r4, carry, carry);
- MP_ADD_CARRY(r5, a15, r5, carry, carry);
- MP_ADD_CARRY(r6, a13, r6, carry, carry);
- MP_ADD_CARRY(r7, a8, r7, carry, carry);
- r8 += carry;
- /* diff 5 */
- MP_SUB_BORROW(r0, a11, r0, 0, carry);
- MP_SUB_BORROW(r1, a12, r1, carry, carry);
- MP_SUB_BORROW(r2, a13, r2, carry, carry);
- MP_SUB_BORROW(r3, 0, r3, carry, carry);
- MP_SUB_BORROW(r4, 0, r4, carry, carry);
- MP_SUB_BORROW(r5, 0, r5, carry, carry);
- MP_SUB_BORROW(r6, a8, r6, carry, carry);
- MP_SUB_BORROW(r7, a10, r7, carry, carry);
- r8 -= carry;
- /* diff 6 */
- MP_SUB_BORROW(r0, a12, r0, 0, carry);
- MP_SUB_BORROW(r1, a13, r1, carry, carry);
- MP_SUB_BORROW(r2, a14, r2, carry, carry);
- MP_SUB_BORROW(r3, a15, r3, carry, carry);
- MP_SUB_BORROW(r4, 0, r4, carry, carry);
- MP_SUB_BORROW(r5, 0, r5, carry, carry);
- MP_SUB_BORROW(r6, a9, r6, carry, carry);
- MP_SUB_BORROW(r7, a11, r7, carry, carry);
- r8 -= carry;
- /* diff 7 */
- MP_SUB_BORROW(r0, a13, r0, 0, carry);
- MP_SUB_BORROW(r1, a14, r1, carry, carry);
- MP_SUB_BORROW(r2, a15, r2, carry, carry);
- MP_SUB_BORROW(r3, a8, r3, carry, carry);
- MP_SUB_BORROW(r4, a9, r4, carry, carry);
- MP_SUB_BORROW(r5, a10, r5, carry, carry);
- MP_SUB_BORROW(r6, 0, r6, carry, carry);
- MP_SUB_BORROW(r7, a12, r7, carry, carry);
- r8 -= carry;
- /* diff 8 */
- MP_SUB_BORROW(r0, a14, r0, 0, carry);
- MP_SUB_BORROW(r1, a15, r1, carry, carry);
- MP_SUB_BORROW(r2, 0, r2, carry, carry);
- MP_SUB_BORROW(r3, a9, r3, carry, carry);
- MP_SUB_BORROW(r4, a10, r4, carry, carry);
- MP_SUB_BORROW(r5, a11, r5, carry, carry);
- MP_SUB_BORROW(r6, 0, r6, carry, carry);
- MP_SUB_BORROW(r7, a13, r7, carry, carry);
- r8 -= carry;
-
- /* reduce the overflows */
- while (r8 > 0) {
- mp_digit r8_d = r8;
- MP_ADD_CARRY(r0, r8_d, r0, 0, carry);
- MP_ADD_CARRY(r1, 0, r1, carry, carry);
- MP_ADD_CARRY(r2, 0, r2, carry, carry);
- MP_ADD_CARRY(r3, 0-r8_d, r3, carry, carry);
- MP_ADD_CARRY(r4, MP_DIGIT_MAX, r4, carry, carry);
- MP_ADD_CARRY(r5, MP_DIGIT_MAX, r5, carry, carry);
- MP_ADD_CARRY(r6, 0-(r8_d+1), r6, carry, carry);
- MP_ADD_CARRY(r7, (r8_d-1), r7, carry, carry);
- r8 = carry;
- }
-
- /* reduce the underflows */
- while (r8 < 0) {
- mp_digit r8_d = -r8;
- MP_SUB_BORROW(r0, r8_d, r0, 0, carry);
- MP_SUB_BORROW(r1, 0, r1, carry, carry);
- MP_SUB_BORROW(r2, 0, r2, carry, carry);
- MP_SUB_BORROW(r3, 0-r8_d, r3, carry, carry);
- MP_SUB_BORROW(r4, MP_DIGIT_MAX, r4, carry, carry);
- MP_SUB_BORROW(r5, MP_DIGIT_MAX, r5, carry, carry);
- MP_SUB_BORROW(r6, 0-(r8_d+1), r6, carry, carry);
- MP_SUB_BORROW(r7, (r8_d-1), r7, carry, carry);
- r8 = 0-carry;
- }
- if (a != r) {
- MP_CHECKOK(s_mp_pad(r,8));
- }
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 8;
-
- MP_DIGIT(r,7) = r7;
- MP_DIGIT(r,6) = r6;
- MP_DIGIT(r,5) = r5;
- MP_DIGIT(r,4) = r4;
- MP_DIGIT(r,3) = r3;
- MP_DIGIT(r,2) = r2;
- MP_DIGIT(r,1) = r1;
- MP_DIGIT(r,0) = r0;
-
- /* final reduction if necessary */
- if ((r7 == MP_DIGIT_MAX) &&
- ((r6 > 1) || ((r6 == 1) &&
- (r5 || r4 || r3 ||
- ((r2 == MP_DIGIT_MAX) && (r1 == MP_DIGIT_MAX)
- && (r0 == MP_DIGIT_MAX)))))) {
- MP_CHECKOK(mp_sub(r, &meth->irr, r));
- }
-
- s_mp_clamp(r);
-#else
- switch (a_used) {
- case 8:
- a7 = MP_DIGIT(a,7);
- case 7:
- a6 = MP_DIGIT(a,6);
- case 6:
- a5 = MP_DIGIT(a,5);
- case 5:
- a4 = MP_DIGIT(a,4);
- }
- a7l = a7 << 32;
- a7h = a7 >> 32;
- a6l = a6 << 32;
- a6h = a6 >> 32;
- a5l = a5 << 32;
- a5h = a5 >> 32;
- a4l = a4 << 32;
- a4h = a4 >> 32;
- r3 = MP_DIGIT(a,3);
- r2 = MP_DIGIT(a,2);
- r1 = MP_DIGIT(a,1);
- r0 = MP_DIGIT(a,0);
-
- /* sum 1 */
- MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry);
- MP_ADD_CARRY(r2, a6, r2, carry, carry);
- MP_ADD_CARRY(r3, a7, r3, carry, carry);
- r4 = carry;
- MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry);
- MP_ADD_CARRY(r2, a6, r2, carry, carry);
- MP_ADD_CARRY(r3, a7, r3, carry, carry);
- r4 += carry;
- /* sum 2 */
- MP_ADD_CARRY(r1, a6l, r1, 0, carry);
- MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
- MP_ADD_CARRY(r3, a7h, r3, carry, carry);
- r4 += carry;
- MP_ADD_CARRY(r1, a6l, r1, 0, carry);
- MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
- MP_ADD_CARRY(r3, a7h, r3, carry, carry);
- r4 += carry;
-
- /* sum 3 */
- MP_ADD_CARRY(r0, a4, r0, 0, carry);
- MP_ADD_CARRY(r1, a5l >> 32, r1, carry, carry);
- MP_ADD_CARRY(r2, 0, r2, carry, carry);
- MP_ADD_CARRY(r3, a7, r3, carry, carry);
- r4 += carry;
- /* sum 4 */
- MP_ADD_CARRY(r0, a4h | a5l, r0, 0, carry);
- MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry, carry);
- MP_ADD_CARRY(r2, a7, r2, carry, carry);
- MP_ADD_CARRY(r3, a6h | a4l, r3, carry, carry);
- r4 += carry;
- /* diff 5 */
- MP_SUB_BORROW(r0, a5h | a6l, r0, 0, carry);
- MP_SUB_BORROW(r1, a6h, r1, carry, carry);
- MP_SUB_BORROW(r2, 0, r2, carry, carry);
- MP_SUB_BORROW(r3, (a4l>>32)|a5l,r3, carry, carry);
- r4 -= carry;
- /* diff 6 */
- MP_SUB_BORROW(r0, a6, r0, 0, carry);
- MP_SUB_BORROW(r1, a7, r1, carry, carry);
- MP_SUB_BORROW(r2, 0, r2, carry, carry);
- MP_SUB_BORROW(r3, a4h|(a5h<<32),r3, carry, carry);
- r4 -= carry;
- /* diff 7 */
- MP_SUB_BORROW(r0, a6h|a7l, r0, 0, carry);
- MP_SUB_BORROW(r1, a7h|a4l, r1, carry, carry);
- MP_SUB_BORROW(r2, a4h|a5l, r2, carry, carry);
- MP_SUB_BORROW(r3, a6l, r3, carry, carry);
- r4 -= carry;
- /* diff 8 */
- MP_SUB_BORROW(r0, a7, r0, 0, carry);
- MP_SUB_BORROW(r1, a4h<<32, r1, carry, carry);
- MP_SUB_BORROW(r2, a5, r2, carry, carry);
- MP_SUB_BORROW(r3, a6h<<32, r3, carry, carry);
- r4 -= carry;
-
- /* reduce the overflows */
- while (r4 > 0) {
- mp_digit r4_long = r4;
- mp_digit r4l = (r4_long << 32);
- MP_ADD_CARRY(r0, r4_long, r0, 0, carry);
- MP_ADD_CARRY(r1, 0-r4l, r1, carry, carry);
- MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry, carry);
- MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry, carry);
- r4 = carry;
- }
-
- /* reduce the underflows */
- while (r4 < 0) {
- mp_digit r4_long = -r4;
- mp_digit r4l = (r4_long << 32);
- MP_SUB_BORROW(r0, r4_long, r0, 0, carry);
- MP_SUB_BORROW(r1, 0-r4l, r1, carry, carry);
- MP_SUB_BORROW(r2, MP_DIGIT_MAX, r2, carry, carry);
- MP_SUB_BORROW(r3, r4l-r4_long-1,r3, carry, carry);
- r4 = 0-carry;
- }
-
- if (a != r) {
- MP_CHECKOK(s_mp_pad(r,4));
- }
- MP_SIGN(r) = MP_ZPOS;
- MP_USED(r) = 4;
-
- MP_DIGIT(r,3) = r3;
- MP_DIGIT(r,2) = r2;
- MP_DIGIT(r,1) = r1;
- MP_DIGIT(r,0) = r0;
-
- /* final reduction if necessary */
- if ((r3 > 0xFFFFFFFF00000001ULL) ||
- ((r3 == 0xFFFFFFFF00000001ULL) &&
- (r2 || (r1 >> 32)||
- (r1 == 0xFFFFFFFFULL && r0 == MP_DIGIT_MAX)))) {
- /* very rare, just use mp_sub */
- MP_CHECKOK(mp_sub(r, &meth->irr, r));
- }
-
- s_mp_clamp(r);
-#endif
- }
-
- CLEANUP:
- return res;
-}
-
-/* Compute the square of polynomial a, reduce modulo p256. Store the
- * result in r. r could be a. Uses optimized modular reduction for p256.
- */
-static mp_err
-ec_GFp_nistp256_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_sqr(a, r));
- MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Compute the product of two polynomials a and b, reduce modulo p256.
- * Store the result in r. r could be a or b; a could be b. Uses
- * optimized modular reduction for p256. */
-static mp_err
-ec_GFp_nistp256_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_mul(a, b, r));
- MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Wire in fast field arithmetic and precomputation of base point for
- * named curves. */
-mp_err
-ec_group_set_gfp256(ECGroup *group, ECCurveName name)
-{
- if (name == ECCurve_NIST_P256) {
- group->meth->field_mod = &ec_GFp_nistp256_mod;
- group->meth->field_mul = &ec_GFp_nistp256_mul;
- group->meth->field_sqr = &ec_GFp_nistp256_sqr;
- }
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_384.c b/security/nss/lib/freebl/ecl/ecp_384.c
deleted file mode 100644
index 5494d4ea3..000000000
--- a/security/nss/lib/freebl/ecl/ecp_384.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp.h"
-#include "mpi.h"
-#include "mplogic.h"
-#include "mpi-priv.h"
-#include <stdlib.h>
-
-/* Fast modular reduction for p384 = 2^384 - 2^128 - 2^96 + 2^32 - 1. a can be r.
- * Uses algorithm 2.30 from Hankerson, Menezes, Vanstone. Guide to
- * Elliptic Curve Cryptography. */
-mp_err
-ec_GFp_nistp384_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- int a_bits = mpl_significant_bits(a);
- int i;
-
- /* m1, m2 are statically-allocated mp_int of exactly the size we need */
- mp_int m[10];
-
-#ifdef ECL_THIRTY_TWO_BIT
- mp_digit s[10][12];
- for (i = 0; i < 10; i++) {
- MP_SIGN(&m[i]) = MP_ZPOS;
- MP_ALLOC(&m[i]) = 12;
- MP_USED(&m[i]) = 12;
- MP_DIGITS(&m[i]) = s[i];
- }
-#else
- mp_digit s[10][6];
- for (i = 0; i < 10; i++) {
- MP_SIGN(&m[i]) = MP_ZPOS;
- MP_ALLOC(&m[i]) = 6;
- MP_USED(&m[i]) = 6;
- MP_DIGITS(&m[i]) = s[i];
- }
-#endif
-
-#ifdef ECL_THIRTY_TWO_BIT
- /* for polynomials larger than twice the field size or polynomials
- * not using all words, use regular reduction */
- if ((a_bits > 768) || (a_bits <= 736)) {
- MP_CHECKOK(mp_mod(a, &meth->irr, r));
- } else {
- for (i = 0; i < 12; i++) {
- s[0][i] = MP_DIGIT(a, i);
- }
- s[1][0] = 0;
- s[1][1] = 0;
- s[1][2] = 0;
- s[1][3] = 0;
- s[1][4] = MP_DIGIT(a, 21);
- s[1][5] = MP_DIGIT(a, 22);
- s[1][6] = MP_DIGIT(a, 23);
- s[1][7] = 0;
- s[1][8] = 0;
- s[1][9] = 0;
- s[1][10] = 0;
- s[1][11] = 0;
- for (i = 0; i < 12; i++) {
- s[2][i] = MP_DIGIT(a, i+12);
- }
- s[3][0] = MP_DIGIT(a, 21);
- s[3][1] = MP_DIGIT(a, 22);
- s[3][2] = MP_DIGIT(a, 23);
- for (i = 3; i < 12; i++) {
- s[3][i] = MP_DIGIT(a, i+9);
- }
- s[4][0] = 0;
- s[4][1] = MP_DIGIT(a, 23);
- s[4][2] = 0;
- s[4][3] = MP_DIGIT(a, 20);
- for (i = 4; i < 12; i++) {
- s[4][i] = MP_DIGIT(a, i+8);
- }
- s[5][0] = 0;
- s[5][1] = 0;
- s[5][2] = 0;
- s[5][3] = 0;
- s[5][4] = MP_DIGIT(a, 20);
- s[5][5] = MP_DIGIT(a, 21);
- s[5][6] = MP_DIGIT(a, 22);
- s[5][7] = MP_DIGIT(a, 23);
- s[5][8] = 0;
- s[5][9] = 0;
- s[5][10] = 0;
- s[5][11] = 0;
- s[6][0] = MP_DIGIT(a, 20);
- s[6][1] = 0;
- s[6][2] = 0;
- s[6][3] = MP_DIGIT(a, 21);
- s[6][4] = MP_DIGIT(a, 22);
- s[6][5] = MP_DIGIT(a, 23);
- s[6][6] = 0;
- s[6][7] = 0;
- s[6][8] = 0;
- s[6][9] = 0;
- s[6][10] = 0;
- s[6][11] = 0;
- s[7][0] = MP_DIGIT(a, 23);
- for (i = 1; i < 12; i++) {
- s[7][i] = MP_DIGIT(a, i+11);
- }
- s[8][0] = 0;
- s[8][1] = MP_DIGIT(a, 20);
- s[8][2] = MP_DIGIT(a, 21);
- s[8][3] = MP_DIGIT(a, 22);
- s[8][4] = MP_DIGIT(a, 23);
- s[8][5] = 0;
- s[8][6] = 0;
- s[8][7] = 0;
- s[8][8] = 0;
- s[8][9] = 0;
- s[8][10] = 0;
- s[8][11] = 0;
- s[9][0] = 0;
- s[9][1] = 0;
- s[9][2] = 0;
- s[9][3] = MP_DIGIT(a, 23);
- s[9][4] = MP_DIGIT(a, 23);
- s[9][5] = 0;
- s[9][6] = 0;
- s[9][7] = 0;
- s[9][8] = 0;
- s[9][9] = 0;
- s[9][10] = 0;
- s[9][11] = 0;
-
- MP_CHECKOK(mp_add(&m[0], &m[1], r));
- MP_CHECKOK(mp_add(r, &m[1], r));
- MP_CHECKOK(mp_add(r, &m[2], r));
- MP_CHECKOK(mp_add(r, &m[3], r));
- MP_CHECKOK(mp_add(r, &m[4], r));
- MP_CHECKOK(mp_add(r, &m[5], r));
- MP_CHECKOK(mp_add(r, &m[6], r));
- MP_CHECKOK(mp_sub(r, &m[7], r));
- MP_CHECKOK(mp_sub(r, &m[8], r));
- MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
- s_mp_clamp(r);
- }
-#else
- /* for polynomials larger than twice the field size or polynomials
- * not using all words, use regular reduction */
- if ((a_bits > 768) || (a_bits <= 736)) {
- MP_CHECKOK(mp_mod(a, &meth->irr, r));
- } else {
- for (i = 0; i < 6; i++) {
- s[0][i] = MP_DIGIT(a, i);
- }
- s[1][0] = 0;
- s[1][1] = 0;
- s[1][2] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
- s[1][3] = MP_DIGIT(a, 11) >> 32;
- s[1][4] = 0;
- s[1][5] = 0;
- for (i = 0; i < 6; i++) {
- s[2][i] = MP_DIGIT(a, i+6);
- }
- s[3][0] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
- s[3][1] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
- for (i = 2; i < 6; i++) {
- s[3][i] = (MP_DIGIT(a, i+4) >> 32) | (MP_DIGIT(a, i+5) << 32);
- }
- s[4][0] = (MP_DIGIT(a, 11) >> 32) << 32;
- s[4][1] = MP_DIGIT(a, 10) << 32;
- for (i = 2; i < 6; i++) {
- s[4][i] = MP_DIGIT(a, i+4);
- }
- s[5][0] = 0;
- s[5][1] = 0;
- s[5][2] = MP_DIGIT(a, 10);
- s[5][3] = MP_DIGIT(a, 11);
- s[5][4] = 0;
- s[5][5] = 0;
- s[6][0] = (MP_DIGIT(a, 10) << 32) >> 32;
- s[6][1] = (MP_DIGIT(a, 10) >> 32) << 32;
- s[6][2] = MP_DIGIT(a, 11);
- s[6][3] = 0;
- s[6][4] = 0;
- s[6][5] = 0;
- s[7][0] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
- for (i = 1; i < 6; i++) {
- s[7][i] = (MP_DIGIT(a, i+5) >> 32) | (MP_DIGIT(a, i+6) << 32);
- }
- s[8][0] = MP_DIGIT(a, 10) << 32;
- s[8][1] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
- s[8][2] = MP_DIGIT(a, 11) >> 32;
- s[8][3] = 0;
- s[8][4] = 0;
- s[8][5] = 0;
- s[9][0] = 0;
- s[9][1] = (MP_DIGIT(a, 11) >> 32) << 32;
- s[9][2] = MP_DIGIT(a, 11) >> 32;
- s[9][3] = 0;
- s[9][4] = 0;
- s[9][5] = 0;
-
- MP_CHECKOK(mp_add(&m[0], &m[1], r));
- MP_CHECKOK(mp_add(r, &m[1], r));
- MP_CHECKOK(mp_add(r, &m[2], r));
- MP_CHECKOK(mp_add(r, &m[3], r));
- MP_CHECKOK(mp_add(r, &m[4], r));
- MP_CHECKOK(mp_add(r, &m[5], r));
- MP_CHECKOK(mp_add(r, &m[6], r));
- MP_CHECKOK(mp_sub(r, &m[7], r));
- MP_CHECKOK(mp_sub(r, &m[8], r));
- MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
- s_mp_clamp(r);
- }
-#endif
-
- CLEANUP:
- return res;
-}
-
-/* Compute the square of polynomial a, reduce modulo p384. Store the
- * result in r. r could be a. Uses optimized modular reduction for p384.
- */
-mp_err
-ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_sqr(a, r));
- MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Compute the product of two polynomials a and b, reduce modulo p384.
- * Store the result in r. r could be a or b; a could be b. Uses
- * optimized modular reduction for p384. */
-mp_err
-ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_mul(a, b, r));
- MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Wire in fast field arithmetic and precomputation of base point for
- * named curves. */
-mp_err
-ec_group_set_gfp384(ECGroup *group, ECCurveName name)
-{
- if (name == ECCurve_NIST_P384) {
- group->meth->field_mod = &ec_GFp_nistp384_mod;
- group->meth->field_mul = &ec_GFp_nistp384_mul;
- group->meth->field_sqr = &ec_GFp_nistp384_sqr;
- }
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_521.c b/security/nss/lib/freebl/ecl/ecp_521.c
deleted file mode 100644
index b0aba377a..000000000
--- a/security/nss/lib/freebl/ecl/ecp_521.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp.h"
-#include "mpi.h"
-#include "mplogic.h"
-#include "mpi-priv.h"
-#include <stdlib.h>
-
-#define ECP521_DIGITS ECL_CURVE_DIGITS(521)
-
-/* Fast modular reduction for p521 = 2^521 - 1. a can be r. Uses
- * algorithm 2.31 from Hankerson, Menezes, Vanstone. Guide to
- * Elliptic Curve Cryptography. */
-mp_err
-ec_GFp_nistp521_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- int a_bits = mpl_significant_bits(a);
- int i;
-
- /* m1, m2 are statically-allocated mp_int of exactly the size we need */
- mp_int m1;
-
- mp_digit s1[ECP521_DIGITS] = { 0 };
-
- MP_SIGN(&m1) = MP_ZPOS;
- MP_ALLOC(&m1) = ECP521_DIGITS;
- MP_USED(&m1) = ECP521_DIGITS;
- MP_DIGITS(&m1) = s1;
-
- if (a_bits < 521) {
- if (a==r) return MP_OKAY;
- return mp_copy(a, r);
- }
- /* for polynomials larger than twice the field size or polynomials
- * not using all words, use regular reduction */
- if (a_bits > (521*2)) {
- MP_CHECKOK(mp_mod(a, &meth->irr, r));
- } else {
-#define FIRST_DIGIT (ECP521_DIGITS-1)
- for (i = FIRST_DIGIT; i < MP_USED(a)-1; i++) {
- s1[i-FIRST_DIGIT] = (MP_DIGIT(a, i) >> 9)
- | (MP_DIGIT(a, 1+i) << (MP_DIGIT_BIT-9));
- }
- s1[i-FIRST_DIGIT] = MP_DIGIT(a, i) >> 9;
-
- if ( a != r ) {
- MP_CHECKOK(s_mp_pad(r,ECP521_DIGITS));
- for (i = 0; i < ECP521_DIGITS; i++) {
- MP_DIGIT(r,i) = MP_DIGIT(a, i);
- }
- }
- MP_USED(r) = ECP521_DIGITS;
- MP_DIGIT(r,FIRST_DIGIT) &= 0x1FF;
-
- MP_CHECKOK(s_mp_add(r, &m1));
- if (MP_DIGIT(r, FIRST_DIGIT) & 0x200) {
- MP_CHECKOK(s_mp_add_d(r,1));
- MP_DIGIT(r,FIRST_DIGIT) &= 0x1FF;
- } else if (s_mp_cmp(r, &meth->irr) == 0) {
- mp_zero(r);
- }
- s_mp_clamp(r);
- }
-
- CLEANUP:
- return res;
-}
-
-/* Compute the square of polynomial a, reduce modulo p521. Store the
- * result in r. r could be a. Uses optimized modular reduction for p521.
- */
-mp_err
-ec_GFp_nistp521_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_sqr(a, r));
- MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Compute the product of two polynomials a and b, reduce modulo p521.
- * Store the result in r. r could be a or b; a could be b. Uses
- * optimized modular reduction for p521. */
-mp_err
-ec_GFp_nistp521_mul(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- MP_CHECKOK(mp_mul(a, b, r));
- MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
- CLEANUP:
- return res;
-}
-
-/* Divides two field elements. If a is NULL, then returns the inverse of
- * b. */
-mp_err
-ec_GFp_nistp521_div(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
- mp_int t;
-
- /* If a is NULL, then return the inverse of b, otherwise return a/b. */
- if (a == NULL) {
- return mp_invmod(b, &meth->irr, r);
- } else {
- /* MPI doesn't support divmod, so we implement it using invmod and
- * mulmod. */
- MP_CHECKOK(mp_init(&t));
- MP_CHECKOK(mp_invmod(b, &meth->irr, &t));
- MP_CHECKOK(mp_mul(a, &t, r));
- MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth));
- CLEANUP:
- mp_clear(&t);
- return res;
- }
-}
-
-/* Wire in fast field arithmetic and precomputation of base point for
- * named curves. */
-mp_err
-ec_group_set_gfp521(ECGroup *group, ECCurveName name)
-{
- if (name == ECCurve_NIST_P521) {
- group->meth->field_mod = &ec_GFp_nistp521_mod;
- group->meth->field_mul = &ec_GFp_nistp521_mul;
- group->meth->field_sqr = &ec_GFp_nistp521_sqr;
- group->meth->field_div = &ec_GFp_nistp521_div;
- }
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_aff.c b/security/nss/lib/freebl/ecl/ecp_aff.c
deleted file mode 100644
index 92e860448..000000000
--- a/security/nss/lib/freebl/ecl/ecp_aff.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp.h"
-#include "mplogic.h"
-#include <stdlib.h>
-
-/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */
-mp_err
-ec_GFp_pt_is_inf_aff(const mp_int *px, const mp_int *py)
-{
-
- if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
- return MP_YES;
- } else {
- return MP_NO;
- }
-
-}
-
-/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */
-mp_err
-ec_GFp_pt_set_inf_aff(mp_int *px, mp_int *py)
-{
- mp_zero(px);
- mp_zero(py);
- return MP_OKAY;
-}
-
-/* Computes R = P + Q based on IEEE P1363 A.10.1. Elliptic curve points P,
- * Q, and R can all be identical. Uses affine coordinates. Assumes input
- * is already field-encoded using field_enc, and returns output that is
- * still field-encoded. */
-mp_err
-ec_GFp_pt_add_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
- const mp_int *qy, mp_int *rx, mp_int *ry,
- const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int lambda, temp, tempx, tempy;
-
- MP_DIGITS(&lambda) = 0;
- MP_DIGITS(&temp) = 0;
- MP_DIGITS(&tempx) = 0;
- MP_DIGITS(&tempy) = 0;
- MP_CHECKOK(mp_init(&lambda));
- MP_CHECKOK(mp_init(&temp));
- MP_CHECKOK(mp_init(&tempx));
- MP_CHECKOK(mp_init(&tempy));
- /* if P = inf, then R = Q */
- if (ec_GFp_pt_is_inf_aff(px, py) == 0) {
- MP_CHECKOK(mp_copy(qx, rx));
- MP_CHECKOK(mp_copy(qy, ry));
- res = MP_OKAY;
- goto CLEANUP;
- }
- /* if Q = inf, then R = P */
- if (ec_GFp_pt_is_inf_aff(qx, qy) == 0) {
- MP_CHECKOK(mp_copy(px, rx));
- MP_CHECKOK(mp_copy(py, ry));
- res = MP_OKAY;
- goto CLEANUP;
- }
- /* if px != qx, then lambda = (py-qy) / (px-qx) */
- if (mp_cmp(px, qx) != 0) {
- MP_CHECKOK(group->meth->field_sub(py, qy, &tempy, group->meth));
- MP_CHECKOK(group->meth->field_sub(px, qx, &tempx, group->meth));
- MP_CHECKOK(group->meth->
- field_div(&tempy, &tempx, &lambda, group->meth));
- } else {
- /* if py != qy or qy = 0, then R = inf */
- if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) {
- mp_zero(rx);
- mp_zero(ry);
- res = MP_OKAY;
- goto CLEANUP;
- }
- /* lambda = (3qx^2+a) / (2qy) */
- MP_CHECKOK(group->meth->field_sqr(qx, &tempx, group->meth));
- MP_CHECKOK(mp_set_int(&temp, 3));
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
- }
- MP_CHECKOK(group->meth->
- field_mul(&tempx, &temp, &tempx, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&tempx, &group->curvea, &tempx, group->meth));
- MP_CHECKOK(mp_set_int(&temp, 2));
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
- }
- MP_CHECKOK(group->meth->field_mul(qy, &temp, &tempy, group->meth));
- MP_CHECKOK(group->meth->
- field_div(&tempx, &tempy, &lambda, group->meth));
- }
- /* rx = lambda^2 - px - qx */
- MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
- MP_CHECKOK(group->meth->field_sub(&tempx, px, &tempx, group->meth));
- MP_CHECKOK(group->meth->field_sub(&tempx, qx, &tempx, group->meth));
- /* ry = (x1-x2) * lambda - y1 */
- MP_CHECKOK(group->meth->field_sub(qx, &tempx, &tempy, group->meth));
- MP_CHECKOK(group->meth->
- field_mul(&tempy, &lambda, &tempy, group->meth));
- MP_CHECKOK(group->meth->field_sub(&tempy, qy, &tempy, group->meth));
- MP_CHECKOK(mp_copy(&tempx, rx));
- MP_CHECKOK(mp_copy(&tempy, ry));
-
- CLEANUP:
- mp_clear(&lambda);
- mp_clear(&temp);
- mp_clear(&tempx);
- mp_clear(&tempy);
- return res;
-}
-
-/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
- * identical. Uses affine coordinates. Assumes input is already
- * field-encoded using field_enc, and returns output that is still
- * field-encoded. */
-mp_err
-ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
- const mp_int *qy, mp_int *rx, mp_int *ry,
- const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int nqy;
-
- MP_DIGITS(&nqy) = 0;
- MP_CHECKOK(mp_init(&nqy));
- /* nqy = -qy */
- MP_CHECKOK(group->meth->field_neg(qy, &nqy, group->meth));
- res = group->point_add(px, py, qx, &nqy, rx, ry, group);
- CLEANUP:
- mp_clear(&nqy);
- return res;
-}
-
-/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
- * affine coordinates. Assumes input is already field-encoded using
- * field_enc, and returns output that is still field-encoded. */
-mp_err
-ec_GFp_pt_dbl_aff(const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, const ECGroup *group)
-{
- return ec_GFp_pt_add_aff(px, py, px, py, rx, ry, group);
-}
-
-/* by default, this routine is unused and thus doesn't need to be compiled */
-#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
-/* Computes R = nP based on IEEE P1363 A.10.3. Elliptic curve points P and
- * R can be identical. Uses affine coordinates. Assumes input is already
- * field-encoded using field_enc, and returns output that is still
- * field-encoded. */
-mp_err
-ec_GFp_pt_mul_aff(const mp_int *n, const mp_int *px, const mp_int *py,
- mp_int *rx, mp_int *ry, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int k, k3, qx, qy, sx, sy;
- int b1, b3, i, l;
-
- MP_DIGITS(&k) = 0;
- MP_DIGITS(&k3) = 0;
- MP_DIGITS(&qx) = 0;
- MP_DIGITS(&qy) = 0;
- MP_DIGITS(&sx) = 0;
- MP_DIGITS(&sy) = 0;
- MP_CHECKOK(mp_init(&k));
- MP_CHECKOK(mp_init(&k3));
- MP_CHECKOK(mp_init(&qx));
- MP_CHECKOK(mp_init(&qy));
- MP_CHECKOK(mp_init(&sx));
- MP_CHECKOK(mp_init(&sy));
-
- /* if n = 0 then r = inf */
- if (mp_cmp_z(n) == 0) {
- mp_zero(rx);
- mp_zero(ry);
- res = MP_OKAY;
- goto CLEANUP;
- }
- /* Q = P, k = n */
- MP_CHECKOK(mp_copy(px, &qx));
- MP_CHECKOK(mp_copy(py, &qy));
- MP_CHECKOK(mp_copy(n, &k));
- /* if n < 0 then Q = -Q, k = -k */
- if (mp_cmp_z(n) < 0) {
- MP_CHECKOK(group->meth->field_neg(&qy, &qy, group->meth));
- MP_CHECKOK(mp_neg(&k, &k));
- }
-#ifdef ECL_DEBUG /* basic double and add method */
- l = mpl_significant_bits(&k) - 1;
- MP_CHECKOK(mp_copy(&qx, &sx));
- MP_CHECKOK(mp_copy(&qy, &sy));
- for (i = l - 1; i >= 0; i--) {
- /* S = 2S */
- MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
- /* if k_i = 1, then S = S + Q */
- if (mpl_get_bit(&k, i) != 0) {
- MP_CHECKOK(group->
- point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
- }
- }
-#else /* double and add/subtract method from
- * standard */
- /* k3 = 3 * k */
- MP_CHECKOK(mp_set_int(&k3, 3));
- MP_CHECKOK(mp_mul(&k, &k3, &k3));
- /* S = Q */
- MP_CHECKOK(mp_copy(&qx, &sx));
- MP_CHECKOK(mp_copy(&qy, &sy));
- /* l = index of high order bit in binary representation of 3*k */
- l = mpl_significant_bits(&k3) - 1;
- /* for i = l-1 downto 1 */
- for (i = l - 1; i >= 1; i--) {
- /* S = 2S */
- MP_CHECKOK(group->point_dbl(&sx, &sy, &sx, &sy, group));
- b3 = MP_GET_BIT(&k3, i);
- b1 = MP_GET_BIT(&k, i);
- /* if k3_i = 1 and k_i = 0, then S = S + Q */
- if ((b3 == 1) && (b1 == 0)) {
- MP_CHECKOK(group->
- point_add(&sx, &sy, &qx, &qy, &sx, &sy, group));
- /* if k3_i = 0 and k_i = 1, then S = S - Q */
- } else if ((b3 == 0) && (b1 == 1)) {
- MP_CHECKOK(group->
- point_sub(&sx, &sy, &qx, &qy, &sx, &sy, group));
- }
- }
-#endif
- /* output S */
- MP_CHECKOK(mp_copy(&sx, rx));
- MP_CHECKOK(mp_copy(&sy, ry));
-
- CLEANUP:
- mp_clear(&k);
- mp_clear(&k3);
- mp_clear(&qx);
- mp_clear(&qy);
- mp_clear(&sx);
- mp_clear(&sy);
- return res;
-}
-#endif
-
-/* Validates a point on a GFp curve. */
-mp_err
-ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
-{
- mp_err res = MP_NO;
- mp_int accl, accr, tmp, pxt, pyt;
-
- MP_DIGITS(&accl) = 0;
- MP_DIGITS(&accr) = 0;
- MP_DIGITS(&tmp) = 0;
- MP_DIGITS(&pxt) = 0;
- MP_DIGITS(&pyt) = 0;
- MP_CHECKOK(mp_init(&accl));
- MP_CHECKOK(mp_init(&accr));
- MP_CHECKOK(mp_init(&tmp));
- MP_CHECKOK(mp_init(&pxt));
- MP_CHECKOK(mp_init(&pyt));
-
- /* 1: Verify that publicValue is not the point at infinity */
- if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
- res = MP_NO;
- goto CLEANUP;
- }
- /* 2: Verify that the coordinates of publicValue are elements
- * of the field.
- */
- if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) ||
- (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
- res = MP_NO;
- goto CLEANUP;
- }
- /* 3: Verify that publicValue is on the curve. */
- if (group->meth->field_enc) {
- group->meth->field_enc(px, &pxt, group->meth);
- group->meth->field_enc(py, &pyt, group->meth);
- } else {
- mp_copy(px, &pxt);
- mp_copy(py, &pyt);
- }
- /* left-hand side: y^2 */
- MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
- /* right-hand side: x^3 + a*x + b = (x^2 + a)*x + b by Horner's rule */
- MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
- MP_CHECKOK( group->meth->field_add(&tmp, &group->curvea, &tmp, group->meth) );
- MP_CHECKOK( group->meth->field_mul(&tmp, &pxt, &accr, group->meth) );
- MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
- /* check LHS - RHS == 0 */
- MP_CHECKOK( group->meth->field_sub(&accl, &accr, &accr, group->meth) );
- if (mp_cmp_z(&accr) != 0) {
- res = MP_NO;
- goto CLEANUP;
- }
- /* 4: Verify that the order of the curve times the publicValue
- * is the point at infinity.
- */
- MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
- if (ec_GFp_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
- res = MP_NO;
- goto CLEANUP;
- }
-
- res = MP_YES;
-
-CLEANUP:
- mp_clear(&accl);
- mp_clear(&accr);
- mp_clear(&tmp);
- mp_clear(&pxt);
- mp_clear(&pyt);
- return res;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_fp.c b/security/nss/lib/freebl/ecl/ecp_fp.c
deleted file mode 100644
index 46dc123ca..000000000
--- a/security/nss/lib/freebl/ecl/ecp_fp.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp_fp.h"
-#include "ecl-priv.h"
-#include <stdlib.h>
-
-/* Performs tidying on a short multi-precision floating point integer (the
- * lower group->numDoubles floats). */
-void
-ecfp_tidyShort(double *t, const EC_group_fp * group)
-{
- group->ecfp_tidy(t, group->alpha, group);
-}
-
-/* Performs tidying on only the upper float digits of a multi-precision
- * floating point integer, i.e. the digits beyond the regular length which
- * are removed in the reduction step. */
-void
-ecfp_tidyUpper(double *t, const EC_group_fp * group)
-{
- group->ecfp_tidy(t + group->numDoubles,
- group->alpha + group->numDoubles, group);
-}
-
-/* Performs a "tidy" operation, which performs carrying, moving excess
- * bits from one double to the next double, so that the precision of the
- * doubles is reduced to the regular precision group->doubleBitSize. This
- * might result in some float digits being negative. Alternative C version
- * for portability. */
-void
-ecfp_tidy(double *t, const double *alpha, const EC_group_fp * group)
-{
- double q;
- int i;
-
- /* Do carrying */
- for (i = 0; i < group->numDoubles - 1; i++) {
- q = t[i] + alpha[i + 1];
- q -= alpha[i + 1];
- t[i] -= q;
- t[i + 1] += q;
-
- /* If we don't assume that truncation rounding is used, then q
- * might be 2^n bigger than expected (if it rounds up), then t[0]
- * could be negative and t[1] 2^n larger than expected. */
- }
-}
-
-/* Performs a more mathematically precise "tidying" so that each term is
- * positive. This is slower than the regular tidying, and is used for
- * conversion from floating point to integer. */
-void
-ecfp_positiveTidy(double *t, const EC_group_fp * group)
-{
- double q;
- int i;
-
- /* Do carrying */
- for (i = 0; i < group->numDoubles - 1; i++) {
- /* Subtract beta to force rounding down */
- q = t[i] - ecfp_beta[i + 1];
- q += group->alpha[i + 1];
- q -= group->alpha[i + 1];
- t[i] -= q;
- t[i + 1] += q;
-
- /* Due to subtracting ecfp_beta, we should have each term a
- * non-negative int */
- ECFP_ASSERT(t[i] / ecfp_exp[i] ==
- (unsigned long long) (t[i] / ecfp_exp[i]));
- ECFP_ASSERT(t[i] >= 0);
- }
-}
-
-/* Converts from a floating point representation into an mp_int. Expects
- * that d is already reduced. */
-void
-ecfp_fp2i(mp_int *mpout, double *d, const ECGroup *ecgroup)
-{
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
- unsigned short i16[(group->primeBitSize + 15) / 16];
- double q = 1;
-
-#ifdef ECL_THIRTY_TWO_BIT
- /* TEST uint32_t z = 0; */
- unsigned int z = 0;
-#else
- uint64_t z = 0;
-#endif
- int zBits = 0;
- int copiedBits = 0;
- int i = 0;
- int j = 0;
-
- mp_digit *out;
-
- /* Result should always be >= 0, so set sign accordingly */
- MP_SIGN(mpout) = MP_ZPOS;
-
- /* Tidy up so we're just dealing with positive numbers */
- ecfp_positiveTidy(d, group);
-
- /* We might need to do this reduction step more than once if the
- * reduction adds smaller terms which carry-over to cause another
- * reduction. However, this should happen very rarely, if ever,
- * depending on the elliptic curve. */
- do {
- /* Init loop data */
- z = 0;
- zBits = 0;
- q = 1;
- i = 0;
- j = 0;
- copiedBits = 0;
-
- /* Might have to do a bit more reduction */
- group->ecfp_singleReduce(d, group);
-
- /* Grow the size of the mpint if it's too small */
- s_mp_grow(mpout, group->numInts);
- MP_USED(mpout) = group->numInts;
- out = MP_DIGITS(mpout);
-
- /* Convert double to 16 bit integers */
- while (copiedBits < group->primeBitSize) {
- if (zBits < 16) {
- z += d[i] * q;
- i++;
- ECFP_ASSERT(i < (group->primeBitSize + 15) / 16);
- zBits += group->doubleBitSize;
- }
- i16[j] = z;
- j++;
- z >>= 16;
- zBits -= 16;
- q *= ecfp_twom16;
- copiedBits += 16;
- }
- } while (z != 0);
-
- /* Convert 16 bit integers to mp_digit */
-#ifdef ECL_THIRTY_TWO_BIT
- for (i = 0; i < (group->primeBitSize + 15) / 16; i += 2) {
- *out = 0;
- if (i + 1 < (group->primeBitSize + 15) / 16) {
- *out = i16[i + 1];
- *out <<= 16;
- }
- *out++ += i16[i];
- }
-#else /* 64 bit */
- for (i = 0; i < (group->primeBitSize + 15) / 16; i += 4) {
- *out = 0;
- if (i + 3 < (group->primeBitSize + 15) / 16) {
- *out = i16[i + 3];
- *out <<= 16;
- }
- if (i + 2 < (group->primeBitSize + 15) / 16) {
- *out += i16[i + 2];
- *out <<= 16;
- }
- if (i + 1 < (group->primeBitSize + 15) / 16) {
- *out += i16[i + 1];
- *out <<= 16;
- }
- *out++ += i16[i];
- }
-#endif
-
- /* Perform final reduction. mpout should already be the same number
- * of bits as p, but might not be less than p. Make it so. Since
- * mpout has the same number of bits as p, and 2p has a larger bit
- * size, then mpout < 2p, so a single subtraction of p will suffice. */
- if (mp_cmp(mpout, &ecgroup->meth->irr) >= 0) {
- mp_sub(mpout, &ecgroup->meth->irr, mpout);
- }
-
- /* Shrink the size of the mp_int to the actual used size (required for
- * mp_cmp_z == 0) */
- out = MP_DIGITS(mpout);
- for (i = group->numInts - 1; i > 0; i--) {
- if (out[i] != 0)
- break;
- }
- MP_USED(mpout) = i + 1;
-
- /* Should be between 0 and p-1 */
- ECFP_ASSERT(mp_cmp(mpout, &ecgroup->meth->irr) < 0);
- ECFP_ASSERT(mp_cmp_z(mpout) >= 0);
-}
-
-/* Converts from an mpint into a floating point representation. */
-void
-ecfp_i2fp(double *out, const mp_int *x, const ECGroup *ecgroup)
-{
- int i;
- int j = 0;
- int size;
- double shift = 1;
- mp_digit *in;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
-#ifdef ECL_DEBUG
- /* if debug mode, convert result back using ecfp_fp2i into cmp, then
- * compare to x. */
- mp_int cmp;
-
- MP_DIGITS(&cmp) = NULL;
- mp_init(&cmp);
-#endif
-
- ECFP_ASSERT(group != NULL);
-
- /* init output to 0 (since we skip over some terms) */
- for (i = 0; i < group->numDoubles; i++)
- out[i] = 0;
- i = 0;
-
- size = MP_USED(x);
- in = MP_DIGITS(x);
-
- /* Copy from int into doubles */
-#ifdef ECL_THIRTY_TWO_BIT
- while (j < size) {
- while (group->doubleBitSize * (i + 1) <= 32 * j) {
- i++;
- }
- ECFP_ASSERT(group->doubleBitSize * i <= 32 * j);
- out[i] = in[j];
- out[i] *= shift;
- shift *= ecfp_two32;
- j++;
- }
-#else
- while (j < size) {
- while (group->doubleBitSize * (i + 1) <= 64 * j) {
- i++;
- }
- ECFP_ASSERT(group->doubleBitSize * i <= 64 * j);
- out[i] = (in[j] & 0x00000000FFFFFFFF) * shift;
-
- while (group->doubleBitSize * (i + 1) <= 64 * j + 32) {
- i++;
- }
- ECFP_ASSERT(24 * i <= 64 * j + 32);
- out[i] = (in[j] & 0xFFFFFFFF00000000) * shift;
-
- shift *= ecfp_two64;
- j++;
- }
-#endif
- /* Realign bits to match double boundaries */
- ecfp_tidyShort(out, group);
-
-#ifdef ECL_DEBUG
- /* Convert result back to mp_int, compare to original */
- ecfp_fp2i(&cmp, out, ecgroup);
- ECFP_ASSERT(mp_cmp(&cmp, x) == 0);
- mp_clear(&cmp);
-#endif
-}
-
-/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
- * a, b and p are the elliptic curve coefficients and the prime that
- * determines the field GFp. Elliptic curve points P and R can be
- * identical. Uses Jacobian coordinates. Uses 4-bit window method. */
-mp_err
-ec_GFp_point_mul_jac_4w_fp(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *ecgroup)
-{
- mp_err res = MP_OKAY;
- ecfp_jac_pt precomp[16], r;
- ecfp_aff_pt p;
- EC_group_fp *group;
-
- mp_int rz;
- int i, ni, d;
-
- ARGCHK(ecgroup != NULL, MP_BADARG);
- ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
-
- group = (EC_group_fp *) ecgroup->extra1;
- MP_DIGITS(&rz) = 0;
- MP_CHECKOK(mp_init(&rz));
-
- /* init p, da */
- ecfp_i2fp(p.x, px, ecgroup);
- ecfp_i2fp(p.y, py, ecgroup);
- ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
-
- /* Do precomputation */
- group->precompute_jac(precomp, &p, group);
-
- /* Do main body of calculations */
- d = (mpl_significant_bits(n) + 3) / 4;
-
- /* R = inf */
- for (i = 0; i < group->numDoubles; i++) {
- r.z[i] = 0;
- }
-
- for (i = d - 1; i >= 0; i--) {
- /* compute window ni */
- ni = MP_GET_BIT(n, 4 * i + 3);
- ni <<= 1;
- ni |= MP_GET_BIT(n, 4 * i + 2);
- ni <<= 1;
- ni |= MP_GET_BIT(n, 4 * i + 1);
- ni <<= 1;
- ni |= MP_GET_BIT(n, 4 * i);
-
- /* R = 2^4 * R */
- group->pt_dbl_jac(&r, &r, group);
- group->pt_dbl_jac(&r, &r, group);
- group->pt_dbl_jac(&r, &r, group);
- group->pt_dbl_jac(&r, &r, group);
-
- /* R = R + (ni * P) */
- group->pt_add_jac(&r, &precomp[ni], &r, group);
- }
-
- /* Convert back to integer */
- ecfp_fp2i(rx, r.x, ecgroup);
- ecfp_fp2i(ry, r.y, ecgroup);
- ecfp_fp2i(&rz, r.z, ecgroup);
-
- /* convert result S to affine coordinates */
- MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, ecgroup));
-
- CLEANUP:
- mp_clear(&rz);
- return res;
-}
-
-/* Uses mixed Jacobian-affine coordinates to perform a point
- * multiplication: R = n * P, n scalar. Uses mixed Jacobian-affine
- * coordinates (Jacobian coordinates for doubles and affine coordinates
- * for additions; based on recommendation from Brown et al.). Not very
- * time efficient but quite space efficient, no precomputation needed.
- * group contains the elliptic curve coefficients and the prime that
- * determines the field GFp. Elliptic curve points P and R can be
- * identical. Performs calculations in floating point number format, since
- * this is faster than the integer operations on the ULTRASPARC III.
- * Uses left-to-right binary method (double & add) (algorithm 9) for
- * scalar-point multiplication from Brown, Hankerson, Lopez, Menezes.
- * Software Implementation of the NIST Elliptic Curves Over Prime Fields. */
-mp_err
-ec_GFp_pt_mul_jac_fp(const mp_int *n, const mp_int *px, const mp_int *py,
- mp_int *rx, mp_int *ry, const ECGroup *ecgroup)
-{
- mp_err res;
- mp_int sx, sy, sz;
-
- ecfp_aff_pt p;
- ecfp_jac_pt r;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
- int i, l;
-
- MP_DIGITS(&sx) = 0;
- MP_DIGITS(&sy) = 0;
- MP_DIGITS(&sz) = 0;
- MP_CHECKOK(mp_init(&sx));
- MP_CHECKOK(mp_init(&sy));
- MP_CHECKOK(mp_init(&sz));
-
- /* if n = 0 then r = inf */
- if (mp_cmp_z(n) == 0) {
- mp_zero(rx);
- mp_zero(ry);
- res = MP_OKAY;
- goto CLEANUP;
- /* if n < 0 then out of range error */
- } else if (mp_cmp_z(n) < 0) {
- res = MP_RANGE;
- goto CLEANUP;
- }
-
- /* Convert from integer to floating point */
- ecfp_i2fp(p.x, px, ecgroup);
- ecfp_i2fp(p.y, py, ecgroup);
- ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
-
- /* Init r to point at infinity */
- for (i = 0; i < group->numDoubles; i++) {
- r.z[i] = 0;
- }
-
- /* double and add method */
- l = mpl_significant_bits(n) - 1;
-
- for (i = l; i >= 0; i--) {
- /* R = 2R */
- group->pt_dbl_jac(&r, &r, group);
-
- /* if n_i = 1, then R = R + Q */
- if (MP_GET_BIT(n, i) != 0) {
- group->pt_add_jac_aff(&r, &p, &r, group);
- }
- }
-
- /* Convert from floating point to integer */
- ecfp_fp2i(&sx, r.x, ecgroup);
- ecfp_fp2i(&sy, r.y, ecgroup);
- ecfp_fp2i(&sz, r.z, ecgroup);
-
- /* convert result R to affine coordinates */
- MP_CHECKOK(ec_GFp_pt_jac2aff(&sx, &sy, &sz, rx, ry, ecgroup));
-
- CLEANUP:
- mp_clear(&sx);
- mp_clear(&sy);
- mp_clear(&sz);
- return res;
-}
-
-/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
- * curve points P and R can be identical. Uses mixed Modified-Jacobian
- * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
- * additions. Uses 5-bit window NAF method (algorithm 11) for scalar-point
- * multiplication from Brown, Hankerson, Lopez, Menezes. Software
- * Implementation of the NIST Elliptic Curves Over Prime Fields. */
-mp_err
-ec_GFp_point_mul_wNAF_fp(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *ecgroup)
-{
- mp_err res = MP_OKAY;
- mp_int sx, sy, sz;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
- ecfp_chud_pt precomp[16];
-
- ecfp_aff_pt p;
- ecfp_jm_pt r;
-
- signed char naf[group->orderBitSize + 1];
- int i;
-
- MP_DIGITS(&sx) = 0;
- MP_DIGITS(&sy) = 0;
- MP_DIGITS(&sz) = 0;
- MP_CHECKOK(mp_init(&sx));
- MP_CHECKOK(mp_init(&sy));
- MP_CHECKOK(mp_init(&sz));
-
- /* if n = 0 then r = inf */
- if (mp_cmp_z(n) == 0) {
- mp_zero(rx);
- mp_zero(ry);
- res = MP_OKAY;
- goto CLEANUP;
- /* if n < 0 then out of range error */
- } else if (mp_cmp_z(n) < 0) {
- res = MP_RANGE;
- goto CLEANUP;
- }
-
- /* Convert from integer to floating point */
- ecfp_i2fp(p.x, px, ecgroup);
- ecfp_i2fp(p.y, py, ecgroup);
- ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
-
- /* Perform precomputation */
- group->precompute_chud(precomp, &p, group);
-
- /* Compute 5NAF */
- ec_compute_wNAF(naf, group->orderBitSize, n, 5);
-
- /* Init R = pt at infinity */
- for (i = 0; i < group->numDoubles; i++) {
- r.z[i] = 0;
- }
-
- /* wNAF method */
- for (i = group->orderBitSize; i >= 0; i--) {
- /* R = 2R */
- group->pt_dbl_jm(&r, &r, group);
-
- if (naf[i] != 0) {
- group->pt_add_jm_chud(&r, &precomp[(naf[i] + 15) / 2], &r,
- group);
- }
- }
-
- /* Convert from floating point to integer */
- ecfp_fp2i(&sx, r.x, ecgroup);
- ecfp_fp2i(&sy, r.y, ecgroup);
- ecfp_fp2i(&sz, r.z, ecgroup);
-
- /* convert result R to affine coordinates */
- MP_CHECKOK(ec_GFp_pt_jac2aff(&sx, &sy, &sz, rx, ry, ecgroup));
-
- CLEANUP:
- mp_clear(&sx);
- mp_clear(&sy);
- mp_clear(&sz);
- return res;
-}
-
-/* Cleans up extra memory allocated in ECGroup for this implementation. */
-void
-ec_GFp_extra_free_fp(ECGroup *group)
-{
- if (group->extra1 != NULL) {
- free(group->extra1);
- group->extra1 = NULL;
- }
-}
-
-/* Tests what precision floating point arithmetic is set to. This should
- * be either a 53-bit mantissa (IEEE standard) or a 64-bit mantissa
- * (extended precision on x86) and sets it into the EC_group_fp. Returns
- * either 53 or 64 accordingly. */
-int
-ec_set_fp_precision(EC_group_fp * group)
-{
- double a = 9007199254740992.0; /* 2^53 */
- double b = a + 1;
-
- if (a == b) {
- group->fpPrecision = 53;
- group->alpha = ecfp_alpha_53;
- return 53;
- }
- group->fpPrecision = 64;
- group->alpha = ecfp_alpha_64;
- return 64;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_fp.h b/security/nss/lib/freebl/ecl/ecp_fp.h
deleted file mode 100644
index a5a676913..000000000
--- a/security/nss/lib/freebl/ecl/ecp_fp.h
+++ /dev/null
@@ -1,372 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __ecp_fp_h_
-#define __ecp_fp_h_
-
-#include "mpi.h"
-#include "ecl.h"
-#include "ecp.h"
-
-#include <sys/types.h>
-#include "mpi-priv.h"
-
-#ifdef ECL_DEBUG
-#include <assert.h>
-#endif
-
-/* Largest number of doubles to store one reduced number in floating
- * point. Used for memory allocation on the stack. */
-#define ECFP_MAXDOUBLES 10
-
-/* For debugging purposes */
-#ifndef ECL_DEBUG
-#define ECFP_ASSERT(x)
-#else
-#define ECFP_ASSERT(x) assert(x)
-#endif
-
-/* ECFP_Ti = 2^(i*24) Define as preprocessor constants so we can use in
- * multiple static constants */
-#define ECFP_T0 1.0
-#define ECFP_T1 16777216.0
-#define ECFP_T2 281474976710656.0
-#define ECFP_T3 4722366482869645213696.0
-#define ECFP_T4 79228162514264337593543950336.0
-#define ECFP_T5 1329227995784915872903807060280344576.0
-#define ECFP_T6 22300745198530623141535718272648361505980416.0
-#define ECFP_T7 374144419156711147060143317175368453031918731001856.0
-#define ECFP_T8 6277101735386680763835789423207666416102355444464034512896.0
-#define ECFP_T9 105312291668557186697918027683670432318895095400549111254310977536.0
-#define ECFP_T10 1766847064778384329583297500742918515827483896875618958121606201292619776.0
-#define ECFP_T11 29642774844752946028434172162224104410437116074403984394101141506025761187823616.0
-#define ECFP_T12 497323236409786642155382248146820840100456150797347717440463976893159497012533375533056.0
-#define ECFP_T13 8343699359066055009355553539724812947666814540455674882605631280555545803830627148527195652096.0
-#define ECFP_T14 139984046386112763159840142535527767382602843577165595931249318810236991948760059086304843329475444736.0
-#define ECFP_T15 2348542582773833227889480596789337027375682548908319870707290971532209025114608443463698998384768703031934976.0
-#define ECFP_T16 39402006196394479212279040100143613805079739270465446667948293404245\
-721771497210611414266254884915640806627990306816.0
-#define ECFP_T17 66105596879024859895191530803277103982840468296428121928464879527440\
-5791236311345825189210439715284847591212025023358304256.0
-#define ECFP_T18 11090678776483259438313656736572334813745748301503266300681918322458\
-485231222502492159897624416558312389564843845614287315896631296.0
-#define ECFP_T19 18607071341967536398062689481932916079453218833595342343206149099024\
-36577570298683715049089827234727835552055312041415509848580169253519\
-36.0
-
-#define ECFP_TWO160 1461501637330902918203684832716283019655932542976.0
-#define ECFP_TWO192 6277101735386680763835789423207666416102355444464034512896.0
-#define ECFP_TWO224 26959946667150639794667015087019630673637144422540572481103610249216.0
-
-/* Multiplicative constants */
-static const double ecfp_two32 = 4294967296.0;
-static const double ecfp_two64 = 18446744073709551616.0;
-static const double ecfp_twom16 = .0000152587890625;
-static const double ecfp_twom128 =
- .00000000000000000000000000000000000000293873587705571876992184134305561419454666389193021880377187926569604314863681793212890625;
-static const double ecfp_twom129 =
- .000000000000000000000000000000000000001469367938527859384960920671527807097273331945965109401885939632848021574318408966064453125;
-static const double ecfp_twom160 =
- .0000000000000000000000000000000000000000000000006842277657836020854119773355907793609766904013068924666782559979930620520927053718196475529111921787261962890625;
-static const double ecfp_twom192 =
- .000000000000000000000000000000000000000000000000000000000159309191113245227702888039776771180559110455519261878607388585338616290151305816094308987472018268594098344692611135542392730712890625;
-static const double ecfp_twom224 =
- .00000000000000000000000000000000000000000000000000000000000000000003709206150687421385731735261547639513367564778757791002453039058917581340095629358997312082723208437536338919136001159027049567384892725385725498199462890625;
-
-/* ecfp_exp[i] = 2^(i*ECFP_DSIZE) */
-static const double ecfp_exp[2 * ECFP_MAXDOUBLES] = {
- ECFP_T0, ECFP_T1, ECFP_T2, ECFP_T3, ECFP_T4, ECFP_T5,
- ECFP_T6, ECFP_T7, ECFP_T8, ECFP_T9, ECFP_T10, ECFP_T11,
- ECFP_T12, ECFP_T13, ECFP_T14, ECFP_T15, ECFP_T16, ECFP_T17, ECFP_T18,
- ECFP_T19
-};
-
-/* 1.1 * 2^52 Uses 2^52 to truncate, the .1 is an extra 2^51 to protect
- * the 2^52 bit, so that adding alphas to a negative number won't borrow
- * and empty the important 2^52 bit */
-#define ECFP_ALPHABASE_53 6755399441055744.0
-/* Special case: On some platforms, notably x86 Linux, there is an
- * extended-precision floating point representation with 64-bits of
- * precision in the mantissa. These extra bits of precision require a
- * larger value of alpha to truncate, i.e. 1.1 * 2^63. */
-#define ECFP_ALPHABASE_64 13835058055282163712.0
-
-/*
- * ecfp_alpha[i] = 1.5 * 2^(52 + i*ECFP_DSIZE) we add and subtract alpha
- * to truncate floating point numbers to a certain number of bits for
- * tidying */
-static const double ecfp_alpha_53[2 * ECFP_MAXDOUBLES] = {
- ECFP_ALPHABASE_53 * ECFP_T0,
- ECFP_ALPHABASE_53 * ECFP_T1,
- ECFP_ALPHABASE_53 * ECFP_T2,
- ECFP_ALPHABASE_53 * ECFP_T3,
- ECFP_ALPHABASE_53 * ECFP_T4,
- ECFP_ALPHABASE_53 * ECFP_T5,
- ECFP_ALPHABASE_53 * ECFP_T6,
- ECFP_ALPHABASE_53 * ECFP_T7,
- ECFP_ALPHABASE_53 * ECFP_T8,
- ECFP_ALPHABASE_53 * ECFP_T9,
- ECFP_ALPHABASE_53 * ECFP_T10,
- ECFP_ALPHABASE_53 * ECFP_T11,
- ECFP_ALPHABASE_53 * ECFP_T12,
- ECFP_ALPHABASE_53 * ECFP_T13,
- ECFP_ALPHABASE_53 * ECFP_T14,
- ECFP_ALPHABASE_53 * ECFP_T15,
- ECFP_ALPHABASE_53 * ECFP_T16,
- ECFP_ALPHABASE_53 * ECFP_T17,
- ECFP_ALPHABASE_53 * ECFP_T18,
- ECFP_ALPHABASE_53 * ECFP_T19
-};
-
-/*
- * ecfp_alpha[i] = 1.5 * 2^(63 + i*ECFP_DSIZE) we add and subtract alpha
- * to truncate floating point numbers to a certain number of bits for
- * tidying */
-static const double ecfp_alpha_64[2 * ECFP_MAXDOUBLES] = {
- ECFP_ALPHABASE_64 * ECFP_T0,
- ECFP_ALPHABASE_64 * ECFP_T1,
- ECFP_ALPHABASE_64 * ECFP_T2,
- ECFP_ALPHABASE_64 * ECFP_T3,
- ECFP_ALPHABASE_64 * ECFP_T4,
- ECFP_ALPHABASE_64 * ECFP_T5,
- ECFP_ALPHABASE_64 * ECFP_T6,
- ECFP_ALPHABASE_64 * ECFP_T7,
- ECFP_ALPHABASE_64 * ECFP_T8,
- ECFP_ALPHABASE_64 * ECFP_T9,
- ECFP_ALPHABASE_64 * ECFP_T10,
- ECFP_ALPHABASE_64 * ECFP_T11,
- ECFP_ALPHABASE_64 * ECFP_T12,
- ECFP_ALPHABASE_64 * ECFP_T13,
- ECFP_ALPHABASE_64 * ECFP_T14,
- ECFP_ALPHABASE_64 * ECFP_T15,
- ECFP_ALPHABASE_64 * ECFP_T16,
- ECFP_ALPHABASE_64 * ECFP_T17,
- ECFP_ALPHABASE_64 * ECFP_T18,
- ECFP_ALPHABASE_64 * ECFP_T19
-};
-
-/* 0.011111111111111111111111 (binary) = 0.5 - 2^25 (24 ones) */
-#define ECFP_BETABASE 0.4999999701976776123046875
-
-/*
- * We subtract beta prior to using alpha to simulate rounding down. We
- * make this close to 0.5 to round almost everything down, but exactly 0.5
- * would cause some incorrect rounding. */
-static const double ecfp_beta[2 * ECFP_MAXDOUBLES] = {
- ECFP_BETABASE * ECFP_T0,
- ECFP_BETABASE * ECFP_T1,
- ECFP_BETABASE * ECFP_T2,
- ECFP_BETABASE * ECFP_T3,
- ECFP_BETABASE * ECFP_T4,
- ECFP_BETABASE * ECFP_T5,
- ECFP_BETABASE * ECFP_T6,
- ECFP_BETABASE * ECFP_T7,
- ECFP_BETABASE * ECFP_T8,
- ECFP_BETABASE * ECFP_T9,
- ECFP_BETABASE * ECFP_T10,
- ECFP_BETABASE * ECFP_T11,
- ECFP_BETABASE * ECFP_T12,
- ECFP_BETABASE * ECFP_T13,
- ECFP_BETABASE * ECFP_T14,
- ECFP_BETABASE * ECFP_T15,
- ECFP_BETABASE * ECFP_T16,
- ECFP_BETABASE * ECFP_T17,
- ECFP_BETABASE * ECFP_T18,
- ECFP_BETABASE * ECFP_T19
-};
-
-static const double ecfp_beta_160 = ECFP_BETABASE * ECFP_TWO160;
-static const double ecfp_beta_192 = ECFP_BETABASE * ECFP_TWO192;
-static const double ecfp_beta_224 = ECFP_BETABASE * ECFP_TWO224;
-
-/* Affine EC Point. This is the basic representation (x, y) of an elliptic
- * curve point. */
-typedef struct {
- double x[ECFP_MAXDOUBLES];
- double y[ECFP_MAXDOUBLES];
-} ecfp_aff_pt;
-
-/* Jacobian EC Point. This coordinate system uses X = x/z^2, Y = y/z^3,
- * which enables calculations with fewer inversions than affine
- * coordinates. */
-typedef struct {
- double x[ECFP_MAXDOUBLES];
- double y[ECFP_MAXDOUBLES];
- double z[ECFP_MAXDOUBLES];
-} ecfp_jac_pt;
-
-/* Chudnovsky Jacobian EC Point. This coordinate system is the same as
- * Jacobian, except it keeps z^2, z^3 for faster additions. */
-typedef struct {
- double x[ECFP_MAXDOUBLES];
- double y[ECFP_MAXDOUBLES];
- double z[ECFP_MAXDOUBLES];
- double z2[ECFP_MAXDOUBLES];
- double z3[ECFP_MAXDOUBLES];
-} ecfp_chud_pt;
-
-/* Modified Jacobian EC Point. This coordinate system is the same as
- * Jacobian, except it keeps a*z^4 for faster doublings. */
-typedef struct {
- double x[ECFP_MAXDOUBLES];
- double y[ECFP_MAXDOUBLES];
- double z[ECFP_MAXDOUBLES];
- double az4[ECFP_MAXDOUBLES];
-} ecfp_jm_pt;
-
-struct EC_group_fp_str;
-
-typedef struct EC_group_fp_str EC_group_fp;
-struct EC_group_fp_str {
- int fpPrecision; /* Set to number of bits in mantissa, 53
- * or 64 */
- int numDoubles;
- int primeBitSize;
- int orderBitSize;
- int doubleBitSize;
- int numInts;
- int aIsM3; /* True if curvea == -3 (mod p), then we
- * can optimize doubling */
- double curvea[ECFP_MAXDOUBLES];
- /* Used to truncate a double to the number of bits in the curve */
- double bitSize_alpha;
- /* Pointer to either ecfp_alpha_53 or ecfp_alpha_64 */
- const double *alpha;
-
- void (*ecfp_singleReduce) (double *r, const EC_group_fp * group);
- void (*ecfp_reduce) (double *r, double *x, const EC_group_fp * group);
- /* Performs a "tidy" operation, which performs carrying, moving excess
- * bits from one double to the next double, so that the precision of
- * the doubles is reduced to the regular precision ECFP_DSIZE. This
- * might result in some float digits being negative. */
- void (*ecfp_tidy) (double *t, const double *alpha,
- const EC_group_fp * group);
- /* Perform a point addition using coordinate system Jacobian + Affine
- * -> Jacobian. Input and output should be multi-precision floating
- * point integers. */
- void (*pt_add_jac_aff) (const ecfp_jac_pt * p, const ecfp_aff_pt * q,
- ecfp_jac_pt * r, const EC_group_fp * group);
- /* Perform a point doubling in Jacobian coordinates. Input and output
- * should be multi-precision floating point integers. */
- void (*pt_dbl_jac) (const ecfp_jac_pt * dp, ecfp_jac_pt * dr,
- const EC_group_fp * group);
- /* Perform a point addition using Jacobian coordinate system. Input
- * and output should be multi-precision floating point integers. */
- void (*pt_add_jac) (const ecfp_jac_pt * p, const ecfp_jac_pt * q,
- ecfp_jac_pt * r, const EC_group_fp * group);
- /* Perform a point doubling in Modified Jacobian coordinates. Input
- * and output should be multi-precision floating point integers. */
- void (*pt_dbl_jm) (const ecfp_jm_pt * p, ecfp_jm_pt * r,
- const EC_group_fp * group);
- /* Perform a point doubling using coordinates Affine -> Chudnovsky
- * Jacobian. Input and output should be multi-precision floating point
- * integers. */
- void (*pt_dbl_aff2chud) (const ecfp_aff_pt * p, ecfp_chud_pt * r,
- const EC_group_fp * group);
- /* Perform a point addition using coordinates: Modified Jacobian +
- * Chudnovsky Jacobian -> Modified Jacobian. Input and output should
- * be multi-precision floating point integers. */
- void (*pt_add_jm_chud) (ecfp_jm_pt * p, ecfp_chud_pt * q,
- ecfp_jm_pt * r, const EC_group_fp * group);
- /* Perform a point addition using Chudnovsky Jacobian coordinates.
- * Input and output should be multi-precision floating point integers.
- */
- void (*pt_add_chud) (const ecfp_chud_pt * p, const ecfp_chud_pt * q,
- ecfp_chud_pt * r, const EC_group_fp * group);
- /* Expects out to be an array of size 16 of Chudnovsky Jacobian
- * points. Fills in Chudnovsky Jacobian form (x, y, z, z^2, z^3), for
- * -15P, -13P, -11P, -9P, -7P, -5P, -3P, -P, P, 3P, 5P, 7P, 9P, 11P,
- * 13P, 15P */
- void (*precompute_chud) (ecfp_chud_pt * out, const ecfp_aff_pt * p,
- const EC_group_fp * group);
- /* Expects out to be an array of size 16 of Jacobian points. Fills in
- * Chudnovsky Jacobian form (x, y, z), for O, P, 2P, ... 15P */
- void (*precompute_jac) (ecfp_jac_pt * out, const ecfp_aff_pt * p,
- const EC_group_fp * group);
-
-};
-
-/* Computes r = x*y.
- * r must be different (point to different memory) than x and y.
- * Does not tidy or reduce. */
-void ecfp_multiply(double *r, const double *x, const double *y);
-
-/* Performs a "tidy" operation, which performs carrying, moving excess
- * bits from one double to the next double, so that the precision of the
- * doubles is reduced to the regular precision group->doubleBitSize. This
- * might result in some float digits being negative. */
-void ecfp_tidy(double *t, const double *alpha, const EC_group_fp * group);
-
-/* Performs tidying on only the upper float digits of a multi-precision
- * floating point integer, i.e. the digits beyond the regular length which
- * are removed in the reduction step. */
-void ecfp_tidyUpper(double *t, const EC_group_fp * group);
-
-/* Performs tidying on a short multi-precision floating point integer (the
- * lower group->numDoubles floats). */
-void ecfp_tidyShort(double *t, const EC_group_fp * group);
-
-/* Performs a more mathematically precise "tidying" so that each term is
- * positive. This is slower than the regular tidying, and is used for
- * conversion from floating point to integer. */
-void ecfp_positiveTidy(double *t, const EC_group_fp * group);
-
-/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
- * a, b and p are the elliptic curve coefficients and the prime that
- * determines the field GFp. Elliptic curve points P and R can be
- * identical. Uses mixed Jacobian-affine coordinates. Uses 4-bit window
- * method. */
-mp_err
- ec_GFp_point_mul_jac_4w_fp(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *ecgroup);
-
-/* Computes R = nP where R is (rx, ry) and P is the base point. The
- * parameters a, b and p are the elliptic curve coefficients and the prime
- * that determines the field GFp. Elliptic curve points P and R can be
- * identical. Uses mixed Jacobian-affine coordinates (Jacobian
- * coordinates for doubles and affine coordinates for additions; based on
- * recommendation from Brown et al.). Uses window NAF method (algorithm
- * 11) for scalar-point multiplication from Brown, Hankerson, Lopez,
- * Menezes. Software Implementation of the NIST Elliptic Curves Over Prime
- * Fields. */
-mp_err ec_GFp_point_mul_wNAF_fp(const mp_int *n, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *ecgroup);
-
-/* Uses mixed Jacobian-affine coordinates to perform a point
- * multiplication: R = n * P, n scalar. Uses mixed Jacobian-affine
- * coordinates (Jacobian coordinates for doubles and affine coordinates
- * for additions; based on recommendation from Brown et al.). Not very
- * time efficient but quite space efficient, no precomputation needed.
- * group contains the elliptic curve coefficients and the prime that
- * determines the field GFp. Elliptic curve points P and R can be
- * identical. Performs calculations in floating point number format, since
- * this is faster than the integer operations on the ULTRASPARC III.
- * Uses left-to-right binary method (double & add) (algorithm 9) for
- * scalar-point multiplication from Brown, Hankerson, Lopez, Menezes.
- * Software Implementation of the NIST Elliptic Curves Over Prime Fields. */
-mp_err
- ec_GFp_pt_mul_jac_fp(const mp_int *n, const mp_int *px, const mp_int *py,
- mp_int *rx, mp_int *ry, const ECGroup *ecgroup);
-
-/* Cleans up extra memory allocated in ECGroup for this implementation. */
-void ec_GFp_extra_free_fp(ECGroup *group);
-
-/* Converts from a floating point representation into an mp_int. Expects
- * that d is already reduced. */
-void
- ecfp_fp2i(mp_int *mpout, double *d, const ECGroup *ecgroup);
-
-/* Converts from an mpint into a floating point representation. */
-void
- ecfp_i2fp(double *out, const mp_int *x, const ECGroup *ecgroup);
-
-/* Tests what precision floating point arithmetic is set to. This should
- * be either a 53-bit mantissa (IEEE standard) or a 64-bit mantissa
- * (extended precision on x86) and sets it into the EC_group_fp. Returns
- * either 53 or 64 accordingly. */
-int ec_set_fp_precision(EC_group_fp * group);
-
-#endif
diff --git a/security/nss/lib/freebl/ecl/ecp_fp160.c b/security/nss/lib/freebl/ecl/ecp_fp160.c
deleted file mode 100644
index f462f3ba1..000000000
--- a/security/nss/lib/freebl/ecl/ecp_fp160.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp_fp.h"
-#include <stdlib.h>
-
-#define ECFP_BSIZE 160
-#define ECFP_NUMDOUBLES 7
-
-#include "ecp_fpinc.c"
-
-/* Performs a single step of reduction, just on the uppermost float
- * (assumes already tidied), and then retidies. Note, this does not
- * guarantee that the result will be less than p, but truncates the number
- * of bits. */
-void
-ecfp160_singleReduce(double *d, const EC_group_fp * group)
-{
- double q;
-
- ECFP_ASSERT(group->doubleBitSize == 24);
- ECFP_ASSERT(group->primeBitSize == 160);
- ECFP_ASSERT(ECFP_NUMDOUBLES == 7);
-
- q = d[ECFP_NUMDOUBLES - 1] - ecfp_beta_160;
- q += group->bitSize_alpha;
- q -= group->bitSize_alpha;
-
- d[ECFP_NUMDOUBLES - 1] -= q;
- d[0] += q * ecfp_twom160;
- d[1] += q * ecfp_twom129;
- ecfp_positiveTidy(d, group);
-
- /* Assertions for the highest order term */
- ECFP_ASSERT(d[ECFP_NUMDOUBLES - 1] / ecfp_exp[ECFP_NUMDOUBLES - 1] ==
- (unsigned long long) (d[ECFP_NUMDOUBLES - 1] /
- ecfp_exp[ECFP_NUMDOUBLES - 1]));
- ECFP_ASSERT(d[ECFP_NUMDOUBLES - 1] >= 0);
-}
-
-/* Performs imperfect reduction. This might leave some negative terms,
- * and one more reduction might be required for the result to be between 0
- * and p-1. x should not already be reduced, i.e. should have
- * 2*ECFP_NUMDOUBLES significant terms. x and r can be the same, but then
- * the upper parts of r are not zeroed */
-void
-ecfp160_reduce(double *r, double *x, const EC_group_fp * group)
-{
-
- double x7, x8, q;
-
- ECFP_ASSERT(group->doubleBitSize == 24);
- ECFP_ASSERT(group->primeBitSize == 160);
- ECFP_ASSERT(ECFP_NUMDOUBLES == 7);
-
- /* Tidy just the upper bits, the lower bits can wait. */
- ecfp_tidyUpper(x, group);
-
- /* Assume that this is already tidied so that we have enough extra
- * bits */
- x7 = x[7] + x[13] * ecfp_twom129; /* adds bits 15-39 */
-
- /* Tidy x7, or we won't have enough bits later to add it in */
- q = x7 + group->alpha[8];
- q -= group->alpha[8];
- x7 -= q; /* holds bits 0-24 */
- x8 = x[8] + q; /* holds bits 0-25 */
-
- r[6] = x[6] + x[13] * ecfp_twom160 + x[12] * ecfp_twom129; /* adds
- * bits
- * 8-39 */
- r[5] = x[5] + x[12] * ecfp_twom160 + x[11] * ecfp_twom129;
- r[4] = x[4] + x[11] * ecfp_twom160 + x[10] * ecfp_twom129;
- r[3] = x[3] + x[10] * ecfp_twom160 + x[9] * ecfp_twom129;
- r[2] = x[2] + x[9] * ecfp_twom160 + x8 * ecfp_twom129; /* adds bits
- * 8-40 */
- r[1] = x[1] + x8 * ecfp_twom160 + x7 * ecfp_twom129; /* adds bits
- * 8-39 */
- r[0] = x[0] + x7 * ecfp_twom160;
-
- /* Tidy up just r[ECFP_NUMDOUBLES-2] so that the number of reductions
- * is accurate plus or minus one. (Rather than tidy all to make it
- * totally accurate, which is more costly.) */
- q = r[ECFP_NUMDOUBLES - 2] + group->alpha[ECFP_NUMDOUBLES - 1];
- q -= group->alpha[ECFP_NUMDOUBLES - 1];
- r[ECFP_NUMDOUBLES - 2] -= q;
- r[ECFP_NUMDOUBLES - 1] += q;
-
- /* Tidy up the excess bits on r[ECFP_NUMDOUBLES-1] using reduction */
- /* Use ecfp_beta so we get a positive result */
- q = r[ECFP_NUMDOUBLES - 1] - ecfp_beta_160;
- q += group->bitSize_alpha;
- q -= group->bitSize_alpha;
-
- r[ECFP_NUMDOUBLES - 1] -= q;
- r[0] += q * ecfp_twom160;
- r[1] += q * ecfp_twom129;
-
- /* Tidy the result */
- ecfp_tidyShort(r, group);
-}
-
-/* Sets group to use optimized calculations in this file */
-mp_err
-ec_group_set_secp160r1_fp(ECGroup *group)
-{
-
- EC_group_fp *fpg = NULL;
-
- /* Allocate memory for floating point group data */
- fpg = (EC_group_fp *) malloc(sizeof(EC_group_fp));
- if (fpg == NULL) {
- return MP_MEM;
- }
-
- fpg->numDoubles = ECFP_NUMDOUBLES;
- fpg->primeBitSize = ECFP_BSIZE;
- fpg->orderBitSize = 161;
- fpg->doubleBitSize = 24;
- fpg->numInts = (ECFP_BSIZE + ECL_BITS - 1) / ECL_BITS;
- fpg->aIsM3 = 1;
- fpg->ecfp_singleReduce = &ecfp160_singleReduce;
- fpg->ecfp_reduce = &ecfp160_reduce;
- fpg->ecfp_tidy = &ecfp_tidy;
-
- fpg->pt_add_jac_aff = &ecfp160_pt_add_jac_aff;
- fpg->pt_add_jac = &ecfp160_pt_add_jac;
- fpg->pt_add_jm_chud = &ecfp160_pt_add_jm_chud;
- fpg->pt_add_chud = &ecfp160_pt_add_chud;
- fpg->pt_dbl_jac = &ecfp160_pt_dbl_jac;
- fpg->pt_dbl_jm = &ecfp160_pt_dbl_jm;
- fpg->pt_dbl_aff2chud = &ecfp160_pt_dbl_aff2chud;
- fpg->precompute_chud = &ecfp160_precompute_chud;
- fpg->precompute_jac = &ecfp160_precompute_jac;
-
- group->point_mul = &ec_GFp_point_mul_wNAF_fp;
- group->points_mul = &ec_pts_mul_basic;
- group->extra1 = fpg;
- group->extra_free = &ec_GFp_extra_free_fp;
-
- ec_set_fp_precision(fpg);
- fpg->bitSize_alpha = ECFP_TWO160 * fpg->alpha[0];
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_fp192.c b/security/nss/lib/freebl/ecl/ecp_fp192.c
deleted file mode 100644
index a415bcd05..000000000
--- a/security/nss/lib/freebl/ecl/ecp_fp192.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp_fp.h"
-#include <stdlib.h>
-
-#define ECFP_BSIZE 192
-#define ECFP_NUMDOUBLES 8
-
-#include "ecp_fpinc.c"
-
-/* Performs a single step of reduction, just on the uppermost float
- * (assumes already tidied), and then retidies. Note, this does not
- * guarantee that the result will be less than p. */
-void
-ecfp192_singleReduce(double *d, const EC_group_fp * group)
-{
- double q;
-
- ECFP_ASSERT(group->doubleBitSize == 24);
- ECFP_ASSERT(group->primeBitSize == 192);
- ECFP_ASSERT(group->numDoubles == 8);
-
- q = d[ECFP_NUMDOUBLES - 1] - ecfp_beta_192;
- q += group->bitSize_alpha;
- q -= group->bitSize_alpha;
-
- d[ECFP_NUMDOUBLES - 1] -= q;
- d[0] += q * ecfp_twom192;
- d[2] += q * ecfp_twom128;
- ecfp_positiveTidy(d, group);
-}
-
-/*
- * Performs imperfect reduction. This might leave some negative terms,
- * and one more reduction might be required for the result to be between 0
- * and p-1. x should be be an array of at least 16, and r at least 8 x and
- * r can be the same, but then the upper parts of r are not zeroed */
-void
-ecfp_reduce_192(double *r, double *x, const EC_group_fp * group)
-{
- double x8, x9, x10, q;
-
- ECFP_ASSERT(group->doubleBitSize == 24);
- ECFP_ASSERT(group->primeBitSize == 192);
- ECFP_ASSERT(group->numDoubles == 8);
-
- /* Tidy just the upper portion, the lower part can wait */
- ecfp_tidyUpper(x, group);
-
- x8 = x[8] + x[14] * ecfp_twom128; /* adds bits 16-40 */
- x9 = x[9] + x[15] * ecfp_twom128; /* adds bits 16-40 */
-
- /* Tidy up, or we won't have enough bits later to add it in */
-
- q = x8 + group->alpha[9];
- q -= group->alpha[9];
- x8 -= q;
- x9 += q;
-
- q = x9 + group->alpha[10];
- q -= group->alpha[10];
- x9 -= q;
- x10 = x[10] + q;
-
- r[7] = x[7] + x[15] * ecfp_twom192 + x[13] * ecfp_twom128; /* adds
- * bits
- * 0-40 */
- r[6] = x[6] + x[14] * ecfp_twom192 + x[12] * ecfp_twom128;
- r[5] = x[5] + x[13] * ecfp_twom192 + x[11] * ecfp_twom128;
- r[4] = x[4] + x[12] * ecfp_twom192 + x10 * ecfp_twom128;
- r[3] = x[3] + x[11] * ecfp_twom192 + x9 * ecfp_twom128; /* adds bits
- * 0-40 */
- r[2] = x[2] + x10 * ecfp_twom192 + x8 * ecfp_twom128;
- r[1] = x[1] + x9 * ecfp_twom192; /* adds bits 16-40 */
- r[0] = x[0] + x8 * ecfp_twom192;
-
- /*
- * Tidy up just r[group->numDoubles-2] so that the number of
- * reductions is accurate plus or minus one. (Rather than tidy all to
- * make it totally accurate) */
- q = r[ECFP_NUMDOUBLES - 2] + group->alpha[ECFP_NUMDOUBLES - 1];
- q -= group->alpha[ECFP_NUMDOUBLES - 1];
- r[ECFP_NUMDOUBLES - 2] -= q;
- r[ECFP_NUMDOUBLES - 1] += q;
-
- /* Tidy up the excess bits on r[group->numDoubles-1] using reduction */
- /* Use ecfp_beta so we get a positive res */
- q = r[ECFP_NUMDOUBLES - 1] - ecfp_beta_192;
- q += group->bitSize_alpha;
- q -= group->bitSize_alpha;
-
- r[ECFP_NUMDOUBLES - 1] -= q;
- r[0] += q * ecfp_twom192;
- r[2] += q * ecfp_twom128;
-
- /* Tidy the result */
- ecfp_tidyShort(r, group);
-}
-
-/* Sets group to use optimized calculations in this file */
-mp_err
-ec_group_set_nistp192_fp(ECGroup *group)
-{
- EC_group_fp *fpg;
-
- /* Allocate memory for floating point group data */
- fpg = (EC_group_fp *) malloc(sizeof(EC_group_fp));
- if (fpg == NULL) {
- return MP_MEM;
- }
-
- fpg->numDoubles = ECFP_NUMDOUBLES;
- fpg->primeBitSize = ECFP_BSIZE;
- fpg->orderBitSize = 192;
- fpg->doubleBitSize = 24;
- fpg->numInts = (ECFP_BSIZE + ECL_BITS - 1) / ECL_BITS;
- fpg->aIsM3 = 1;
- fpg->ecfp_singleReduce = &ecfp192_singleReduce;
- fpg->ecfp_reduce = &ecfp_reduce_192;
- fpg->ecfp_tidy = &ecfp_tidy;
-
- fpg->pt_add_jac_aff = &ecfp192_pt_add_jac_aff;
- fpg->pt_add_jac = &ecfp192_pt_add_jac;
- fpg->pt_add_jm_chud = &ecfp192_pt_add_jm_chud;
- fpg->pt_add_chud = &ecfp192_pt_add_chud;
- fpg->pt_dbl_jac = &ecfp192_pt_dbl_jac;
- fpg->pt_dbl_jm = &ecfp192_pt_dbl_jm;
- fpg->pt_dbl_aff2chud = &ecfp192_pt_dbl_aff2chud;
- fpg->precompute_chud = &ecfp192_precompute_chud;
- fpg->precompute_jac = &ecfp192_precompute_jac;
-
- group->point_mul = &ec_GFp_point_mul_wNAF_fp;
- group->points_mul = &ec_pts_mul_basic;
- group->extra1 = fpg;
- group->extra_free = &ec_GFp_extra_free_fp;
-
- ec_set_fp_precision(fpg);
- fpg->bitSize_alpha = ECFP_TWO192 * fpg->alpha[0];
-
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_fp224.c b/security/nss/lib/freebl/ecl/ecp_fp224.c
deleted file mode 100644
index 71b6a6dcd..000000000
--- a/security/nss/lib/freebl/ecl/ecp_fp224.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp_fp.h"
-#include <stdlib.h>
-
-#define ECFP_BSIZE 224
-#define ECFP_NUMDOUBLES 10
-
-#include "ecp_fpinc.c"
-
-/* Performs a single step of reduction, just on the uppermost float
- * (assumes already tidied), and then retidies. Note, this does not
- * guarantee that the result will be less than p. */
-void
-ecfp224_singleReduce(double *r, const EC_group_fp * group)
-{
- double q;
-
- ECFP_ASSERT(group->doubleBitSize == 24);
- ECFP_ASSERT(group->primeBitSize == 224);
- ECFP_ASSERT(group->numDoubles == 10);
-
- q = r[ECFP_NUMDOUBLES - 1] - ecfp_beta_224;
- q += group->bitSize_alpha;
- q -= group->bitSize_alpha;
-
- r[ECFP_NUMDOUBLES - 1] -= q;
- r[0] -= q * ecfp_twom224;
- r[4] += q * ecfp_twom128;
-
- ecfp_positiveTidy(r, group);
-}
-
-/*
- * Performs imperfect reduction. This might leave some negative terms,
- * and one more reduction might be required for the result to be between 0
- * and p-1. x should be be an array of at least 20, and r at least 10 x
- * and r can be the same, but then the upper parts of r are not zeroed */
-void
-ecfp224_reduce(double *r, double *x, const EC_group_fp * group)
-{
-
- double x10, x11, x12, x13, x14, q;
-
- ECFP_ASSERT(group->doubleBitSize == 24);
- ECFP_ASSERT(group->primeBitSize == 224);
- ECFP_ASSERT(group->numDoubles == 10);
-
- /* Tidy just the upper bits of x. Don't need to tidy the lower ones
- * yet. */
- ecfp_tidyUpper(x, group);
-
- x10 = x[10] + x[16] * ecfp_twom128;
- x11 = x[11] + x[17] * ecfp_twom128;
- x12 = x[12] + x[18] * ecfp_twom128;
- x13 = x[13] + x[19] * ecfp_twom128;
-
- /* Tidy up, or we won't have enough bits later to add it in */
- q = x10 + group->alpha[11];
- q -= group->alpha[11];
- x10 -= q;
- x11 = x11 + q;
-
- q = x11 + group->alpha[12];
- q -= group->alpha[12];
- x11 -= q;
- x12 = x12 + q;
-
- q = x12 + group->alpha[13];
- q -= group->alpha[13];
- x12 -= q;
- x13 = x13 + q;
-
- q = x13 + group->alpha[14];
- q -= group->alpha[14];
- x13 -= q;
- x14 = x[14] + q;
-
- r[9] = x[9] + x[15] * ecfp_twom128 - x[19] * ecfp_twom224;
- r[8] = x[8] + x14 * ecfp_twom128 - x[18] * ecfp_twom224;
- r[7] = x[7] + x13 * ecfp_twom128 - x[17] * ecfp_twom224;
- r[6] = x[6] + x12 * ecfp_twom128 - x[16] * ecfp_twom224;
- r[5] = x[5] + x11 * ecfp_twom128 - x[15] * ecfp_twom224;
- r[4] = x[4] + x10 * ecfp_twom128 - x14 * ecfp_twom224;
- r[3] = x[3] - x13 * ecfp_twom224;
- r[2] = x[2] - x12 * ecfp_twom224;
- r[1] = x[1] - x11 * ecfp_twom224;
- r[0] = x[0] - x10 * ecfp_twom224;
-
- /*
- * Tidy up just r[ECFP_NUMDOUBLES-2] so that the number of reductions
- * is accurate plus or minus one. (Rather than tidy all to make it
- * totally accurate) */
- q = r[ECFP_NUMDOUBLES - 2] + group->alpha[ECFP_NUMDOUBLES - 1];
- q -= group->alpha[ECFP_NUMDOUBLES - 1];
- r[ECFP_NUMDOUBLES - 2] -= q;
- r[ECFP_NUMDOUBLES - 1] += q;
-
- /* Tidy up the excess bits on r[ECFP_NUMDOUBLES-1] using reduction */
- /* Use ecfp_beta so we get a positive res */
- q = r[ECFP_NUMDOUBLES - 1] - ecfp_beta_224;
- q += group->bitSize_alpha;
- q -= group->bitSize_alpha;
-
- r[ECFP_NUMDOUBLES - 1] -= q;
- r[0] -= q * ecfp_twom224;
- r[4] += q * ecfp_twom128;
-
- ecfp_tidyShort(r, group);
-}
-
-/* Sets group to use optimized calculations in this file */
-mp_err
-ec_group_set_nistp224_fp(ECGroup *group)
-{
-
- EC_group_fp *fpg;
-
- /* Allocate memory for floating point group data */
- fpg = (EC_group_fp *) malloc(sizeof(EC_group_fp));
- if (fpg == NULL) {
- return MP_MEM;
- }
-
- fpg->numDoubles = ECFP_NUMDOUBLES;
- fpg->primeBitSize = ECFP_BSIZE;
- fpg->orderBitSize = 224;
- fpg->doubleBitSize = 24;
- fpg->numInts = (ECFP_BSIZE + ECL_BITS - 1) / ECL_BITS;
- fpg->aIsM3 = 1;
- fpg->ecfp_singleReduce = &ecfp224_singleReduce;
- fpg->ecfp_reduce = &ecfp224_reduce;
- fpg->ecfp_tidy = &ecfp_tidy;
-
- fpg->pt_add_jac_aff = &ecfp224_pt_add_jac_aff;
- fpg->pt_add_jac = &ecfp224_pt_add_jac;
- fpg->pt_add_jm_chud = &ecfp224_pt_add_jm_chud;
- fpg->pt_add_chud = &ecfp224_pt_add_chud;
- fpg->pt_dbl_jac = &ecfp224_pt_dbl_jac;
- fpg->pt_dbl_jm = &ecfp224_pt_dbl_jm;
- fpg->pt_dbl_aff2chud = &ecfp224_pt_dbl_aff2chud;
- fpg->precompute_chud = &ecfp224_precompute_chud;
- fpg->precompute_jac = &ecfp224_precompute_jac;
-
- group->point_mul = &ec_GFp_point_mul_wNAF_fp;
- group->points_mul = &ec_pts_mul_basic;
- group->extra1 = fpg;
- group->extra_free = &ec_GFp_extra_free_fp;
-
- ec_set_fp_precision(fpg);
- fpg->bitSize_alpha = ECFP_TWO224 * fpg->alpha[0];
-
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_fpinc.c b/security/nss/lib/freebl/ecl/ecp_fpinc.c
deleted file mode 100644
index be0f9667b..000000000
--- a/security/nss/lib/freebl/ecl/ecp_fpinc.c
+++ /dev/null
@@ -1,821 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* This source file is meant to be included by other source files
- * (ecp_fp###.c, where ### is one of 160, 192, 224) and should not
- * constitute an independent compilation unit. It requires the following
- * preprocessor definitions be made: ECFP_BSIZE - the number of bits in
- * the field's prime
- * ECFP_NUMDOUBLES - the number of doubles to store one
- * multi-precision integer in floating point
-
-/* Adds a prefix to a given token to give a unique token name. Prefixes
- * with "ecfp" + ECFP_BSIZE + "_". e.g. if ECFP_BSIZE = 160, then
- * PREFIX(hello) = ecfp160_hello This optimization allows static function
- * linking and compiler loop unrolling without code duplication. */
-#ifndef PREFIX
-#define PREFIX(b) PREFIX1(ECFP_BSIZE, b)
-#define PREFIX1(bsize, b) PREFIX2(bsize, b)
-#define PREFIX2(bsize, b) ecfp ## bsize ## _ ## b
-#endif
-
-/* Returns true iff every double in d is 0. (If d == 0 and it is tidied,
- * this will be true.) */
-mp_err PREFIX(isZero) (const double *d) {
- int i;
-
- for (i = 0; i < ECFP_NUMDOUBLES; i++) {
- if (d[i] != 0)
- return MP_NO;
- }
- return MP_YES;
-}
-
-/* Sets the multi-precision floating point number at t = 0 */
-void PREFIX(zero) (double *t) {
- int i;
-
- for (i = 0; i < ECFP_NUMDOUBLES; i++) {
- t[i] = 0;
- }
-}
-
-/* Sets the multi-precision floating point number at t = 1 */
-void PREFIX(one) (double *t) {
- int i;
-
- t[0] = 1;
- for (i = 1; i < ECFP_NUMDOUBLES; i++) {
- t[i] = 0;
- }
-}
-
-/* Checks if point P(x, y, z) is at infinity. Uses Jacobian coordinates. */
-mp_err PREFIX(pt_is_inf_jac) (const ecfp_jac_pt * p) {
- return PREFIX(isZero) (p->z);
-}
-
-/* Sets the Jacobian point P to be at infinity. */
-void PREFIX(set_pt_inf_jac) (ecfp_jac_pt * p) {
- PREFIX(zero) (p->z);
-}
-
-/* Checks if point P(x, y) is at infinity. Uses Affine coordinates. */
-mp_err PREFIX(pt_is_inf_aff) (const ecfp_aff_pt * p) {
- if (PREFIX(isZero) (p->x) == MP_YES && PREFIX(isZero) (p->y) == MP_YES)
- return MP_YES;
- return MP_NO;
-}
-
-/* Sets the affine point P to be at infinity. */
-void PREFIX(set_pt_inf_aff) (ecfp_aff_pt * p) {
- PREFIX(zero) (p->x);
- PREFIX(zero) (p->y);
-}
-
-/* Checks if point P(x, y, z, a*z^4) is at infinity. Uses Modified
- * Jacobian coordinates. */
-mp_err PREFIX(pt_is_inf_jm) (const ecfp_jm_pt * p) {
- return PREFIX(isZero) (p->z);
-}
-
-/* Sets the Modified Jacobian point P to be at infinity. */
-void PREFIX(set_pt_inf_jm) (ecfp_jm_pt * p) {
- PREFIX(zero) (p->z);
-}
-
-/* Checks if point P(x, y, z, z^2, z^3) is at infinity. Uses Chudnovsky
- * Jacobian coordinates */
-mp_err PREFIX(pt_is_inf_chud) (const ecfp_chud_pt * p) {
- return PREFIX(isZero) (p->z);
-}
-
-/* Sets the Chudnovsky Jacobian point P to be at infinity. */
-void PREFIX(set_pt_inf_chud) (ecfp_chud_pt * p) {
- PREFIX(zero) (p->z);
-}
-
-/* Copies a multi-precision floating point number, Setting dest = src */
-void PREFIX(copy) (double *dest, const double *src) {
- int i;
-
- for (i = 0; i < ECFP_NUMDOUBLES; i++) {
- dest[i] = src[i];
- }
-}
-
-/* Sets dest = -src */
-void PREFIX(negLong) (double *dest, const double *src) {
- int i;
-
- for (i = 0; i < 2 * ECFP_NUMDOUBLES; i++) {
- dest[i] = -src[i];
- }
-}
-
-/* Sets r = -p p = (x, y, z, z2, z3) r = (x, -y, z, z2, z3) Uses
- * Chudnovsky Jacobian coordinates. */
-/* TODO reverse order */
-void PREFIX(pt_neg_chud) (const ecfp_chud_pt * p, ecfp_chud_pt * r) {
- int i;
-
- PREFIX(copy) (r->x, p->x);
- PREFIX(copy) (r->z, p->z);
- PREFIX(copy) (r->z2, p->z2);
- PREFIX(copy) (r->z3, p->z3);
- for (i = 0; i < ECFP_NUMDOUBLES; i++) {
- r->y[i] = -p->y[i];
- }
-}
-
-/* Computes r = x + y. Does not tidy or reduce. Any combinations of r, x,
- * y can point to the same data. Componentwise adds first ECFP_NUMDOUBLES
- * doubles of x and y and stores the result in r. */
-void PREFIX(addShort) (double *r, const double *x, const double *y) {
- int i;
-
- for (i = 0; i < ECFP_NUMDOUBLES; i++) {
- *r++ = *x++ + *y++;
- }
-}
-
-/* Computes r = x + y. Does not tidy or reduce. Any combinations of r, x,
- * y can point to the same data. Componentwise adds first
- * 2*ECFP_NUMDOUBLES doubles of x and y and stores the result in r. */
-void PREFIX(addLong) (double *r, const double *x, const double *y) {
- int i;
-
- for (i = 0; i < 2 * ECFP_NUMDOUBLES; i++) {
- *r++ = *x++ + *y++;
- }
-}
-
-/* Computes r = x - y. Does not tidy or reduce. Any combinations of r, x,
- * y can point to the same data. Componentwise subtracts first
- * ECFP_NUMDOUBLES doubles of x and y and stores the result in r. */
-void PREFIX(subtractShort) (double *r, const double *x, const double *y) {
- int i;
-
- for (i = 0; i < ECFP_NUMDOUBLES; i++) {
- *r++ = *x++ - *y++;
- }
-}
-
-/* Computes r = x - y. Does not tidy or reduce. Any combinations of r, x,
- * y can point to the same data. Componentwise subtracts first
- * 2*ECFP_NUMDOUBLES doubles of x and y and stores the result in r. */
-void PREFIX(subtractLong) (double *r, const double *x, const double *y) {
- int i;
-
- for (i = 0; i < 2 * ECFP_NUMDOUBLES; i++) {
- *r++ = *x++ - *y++;
- }
-}
-
-/* Computes r = x*y. Both x and y should be tidied and reduced,
- * r must be different (point to different memory) than x and y.
- * Does not tidy or reduce. */
-void PREFIX(multiply)(double *r, const double *x, const double *y) {
- int i, j;
-
- for(j=0;j<ECFP_NUMDOUBLES-1;j++) {
- r[j] = x[0] * y[j];
- r[j+(ECFP_NUMDOUBLES-1)] = x[ECFP_NUMDOUBLES-1] * y[j];
- }
- r[ECFP_NUMDOUBLES-1] = x[0] * y[ECFP_NUMDOUBLES-1];
- r[ECFP_NUMDOUBLES-1] += x[ECFP_NUMDOUBLES-1] * y[0];
- r[2*ECFP_NUMDOUBLES-2] = x[ECFP_NUMDOUBLES-1] * y[ECFP_NUMDOUBLES-1];
- r[2*ECFP_NUMDOUBLES-1] = 0;
-
- for(i=1;i<ECFP_NUMDOUBLES-1;i++) {
- for(j=0;j<ECFP_NUMDOUBLES;j++) {
- r[i+j] += (x[i] * y[j]);
- }
- }
-}
-
-/* Computes the square of x and stores the result in r. x should be
- * tidied & reduced, r will be neither tidied nor reduced.
- * r should point to different memory than x */
-void PREFIX(square) (double *r, const double *x) {
- PREFIX(multiply) (r, x, x);
-}
-
-/* Perform a point doubling in Jacobian coordinates. Input and output
- * should be multi-precision floating point integers. */
-void PREFIX(pt_dbl_jac) (const ecfp_jac_pt * dp, ecfp_jac_pt * dr,
- const EC_group_fp * group) {
- double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
- M[2 * ECFP_NUMDOUBLES], S[2 * ECFP_NUMDOUBLES];
-
- /* Check for point at infinity */
- if (PREFIX(pt_is_inf_jac) (dp) == MP_YES) {
- /* Set r = pt at infinity */
- PREFIX(set_pt_inf_jac) (dr);
- goto CLEANUP;
- }
-
- /* Perform typical point doubling operations */
-
- /* TODO? is it worthwhile to do optimizations for when pz = 1? */
-
- if (group->aIsM3) {
- /* When a = -3, M = 3(px - pz^2)(px + pz^2) */
- PREFIX(square) (t1, dp->z);
- group->ecfp_reduce(t1, t1, group); /* 2^23 since the negative
- * rounding buys another bit */
- PREFIX(addShort) (t0, dp->x, t1); /* 2*2^23 */
- PREFIX(subtractShort) (t1, dp->x, t1); /* 2 * 2^23 */
- PREFIX(multiply) (M, t0, t1); /* 40 * 2^46 */
- PREFIX(addLong) (t0, M, M); /* 80 * 2^46 */
- PREFIX(addLong) (M, t0, M); /* 120 * 2^46 < 2^53 */
- group->ecfp_reduce(M, M, group);
- } else {
- /* Generic case */
- /* M = 3 (px^2) + a*(pz^4) */
- PREFIX(square) (t0, dp->x);
- PREFIX(addLong) (M, t0, t0);
- PREFIX(addLong) (t0, t0, M); /* t0 = 3(px^2) */
- PREFIX(square) (M, dp->z);
- group->ecfp_reduce(M, M, group);
- PREFIX(square) (t1, M);
- group->ecfp_reduce(t1, t1, group);
- PREFIX(multiply) (M, t1, group->curvea); /* M = a(pz^4) */
- PREFIX(addLong) (M, M, t0);
- group->ecfp_reduce(M, M, group);
- }
-
- /* rz = 2 * py * pz */
- PREFIX(multiply) (t1, dp->y, dp->z);
- PREFIX(addLong) (t1, t1, t1);
- group->ecfp_reduce(dr->z, t1, group);
-
- /* t0 = 2y^2 */
- PREFIX(square) (t0, dp->y);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(addShort) (t0, t0, t0);
-
- /* S = 4 * px * py^2 = 2 * px * t0 */
- PREFIX(multiply) (S, dp->x, t0);
- PREFIX(addLong) (S, S, S);
- group->ecfp_reduce(S, S, group);
-
- /* rx = M^2 - 2 * S */
- PREFIX(square) (t1, M);
- PREFIX(subtractShort) (t1, t1, S);
- PREFIX(subtractShort) (t1, t1, S);
- group->ecfp_reduce(dr->x, t1, group);
-
- /* ry = M * (S - rx) - 8 * py^4 */
- PREFIX(square) (t1, t0); /* t1 = 4y^4 */
- PREFIX(subtractShort) (S, S, dr->x);
- PREFIX(multiply) (t0, M, S);
- PREFIX(subtractLong) (t0, t0, t1);
- PREFIX(subtractLong) (t0, t0, t1);
- group->ecfp_reduce(dr->y, t0, group);
-
- CLEANUP:
- return;
-}
-
-/* Perform a point addition using coordinate system Jacobian + Affine ->
- * Jacobian. Input and output should be multi-precision floating point
- * integers. */
-void PREFIX(pt_add_jac_aff) (const ecfp_jac_pt * p, const ecfp_aff_pt * q,
- ecfp_jac_pt * r, const EC_group_fp * group) {
- /* Temporary storage */
- double A[2 * ECFP_NUMDOUBLES], B[2 * ECFP_NUMDOUBLES],
- C[2 * ECFP_NUMDOUBLES], C2[2 * ECFP_NUMDOUBLES],
- D[2 * ECFP_NUMDOUBLES], C3[2 * ECFP_NUMDOUBLES];
-
- /* Check for point at infinity for p or q */
- if (PREFIX(pt_is_inf_aff) (q) == MP_YES) {
- PREFIX(copy) (r->x, p->x);
- PREFIX(copy) (r->y, p->y);
- PREFIX(copy) (r->z, p->z);
- goto CLEANUP;
- } else if (PREFIX(pt_is_inf_jac) (p) == MP_YES) {
- PREFIX(copy) (r->x, q->x);
- PREFIX(copy) (r->y, q->y);
- /* Since the affine point is not infinity, we can set r->z = 1 */
- PREFIX(one) (r->z);
- goto CLEANUP;
- }
-
- /* Calculates c = qx * pz^2 - px d = (qy * b - py) rx = d^2 - c^3 + 2
- * (px * c^2) ry = d * (c-rx) - py*c^3 rz = c * pz */
-
- /* A = pz^2, B = pz^3 */
- PREFIX(square) (A, p->z);
- group->ecfp_reduce(A, A, group);
- PREFIX(multiply) (B, A, p->z);
- group->ecfp_reduce(B, B, group);
-
- /* C = qx * A - px */
- PREFIX(multiply) (C, q->x, A);
- PREFIX(subtractShort) (C, C, p->x);
- group->ecfp_reduce(C, C, group);
-
- /* D = qy * B - py */
- PREFIX(multiply) (D, q->y, B);
- PREFIX(subtractShort) (D, D, p->y);
- group->ecfp_reduce(D, D, group);
-
- /* C2 = C^2, C3 = C^3 */
- PREFIX(square) (C2, C);
- group->ecfp_reduce(C2, C2, group);
- PREFIX(multiply) (C3, C2, C);
- group->ecfp_reduce(C3, C3, group);
-
- /* rz = A = pz * C */
- PREFIX(multiply) (A, p->z, C);
- group->ecfp_reduce(r->z, A, group);
-
- /* C = px * C^2, untidied, unreduced */
- PREFIX(multiply) (C, p->x, C2);
-
- /* A = D^2, untidied, unreduced */
- PREFIX(square) (A, D);
-
- /* rx = B = A - C3 - C - C = D^2 - (C^3 + 2 * (px * C^2) */
- PREFIX(subtractShort) (A, A, C3);
- PREFIX(subtractLong) (A, A, C);
- PREFIX(subtractLong) (A, A, C);
- group->ecfp_reduce(r->x, A, group);
-
- /* B = py * C3, untidied, unreduced */
- PREFIX(multiply) (B, p->y, C3);
-
- /* C = px * C^2 - rx */
- PREFIX(subtractShort) (C, C, r->x);
- group->ecfp_reduce(C, C, group);
-
- /* ry = A = D * C - py * C^3 */
- PREFIX(multiply) (A, D, C);
- PREFIX(subtractLong) (A, A, B);
- group->ecfp_reduce(r->y, A, group);
-
- CLEANUP:
- return;
-}
-
-/* Perform a point addition using Jacobian coordinate system. Input and
- * output should be multi-precision floating point integers. */
-void PREFIX(pt_add_jac) (const ecfp_jac_pt * p, const ecfp_jac_pt * q,
- ecfp_jac_pt * r, const EC_group_fp * group) {
-
- /* Temporary Storage */
- double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
- U[2 * ECFP_NUMDOUBLES], R[2 * ECFP_NUMDOUBLES],
- S[2 * ECFP_NUMDOUBLES], H[2 * ECFP_NUMDOUBLES],
- H3[2 * ECFP_NUMDOUBLES];
-
- /* Check for point at infinity for p, if so set r = q */
- if (PREFIX(pt_is_inf_jac) (p) == MP_YES) {
- PREFIX(copy) (r->x, q->x);
- PREFIX(copy) (r->y, q->y);
- PREFIX(copy) (r->z, q->z);
- goto CLEANUP;
- }
-
- /* Check for point at infinity for p, if so set r = q */
- if (PREFIX(pt_is_inf_jac) (q) == MP_YES) {
- PREFIX(copy) (r->x, p->x);
- PREFIX(copy) (r->y, p->y);
- PREFIX(copy) (r->z, p->z);
- goto CLEANUP;
- }
-
- /* U = px * qz^2 , S = py * qz^3 */
- PREFIX(square) (t0, q->z);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(multiply) (U, p->x, t0);
- group->ecfp_reduce(U, U, group);
- PREFIX(multiply) (t1, t0, q->z);
- group->ecfp_reduce(t1, t1, group);
- PREFIX(multiply) (t0, p->y, t1);
- group->ecfp_reduce(S, t0, group);
-
- /* H = qx*(pz)^2 - U , R = (qy * pz^3 - S) */
- PREFIX(square) (t0, p->z);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(multiply) (H, q->x, t0);
- PREFIX(subtractShort) (H, H, U);
- group->ecfp_reduce(H, H, group);
- PREFIX(multiply) (t1, t0, p->z); /* t1 = pz^3 */
- group->ecfp_reduce(t1, t1, group);
- PREFIX(multiply) (t0, t1, q->y); /* t0 = qy * pz^3 */
- PREFIX(subtractShort) (t0, t0, S);
- group->ecfp_reduce(R, t0, group);
-
- /* U = U*H^2, H3 = H^3 */
- PREFIX(square) (t0, H);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(multiply) (t1, U, t0);
- group->ecfp_reduce(U, t1, group);
- PREFIX(multiply) (H3, t0, H);
- group->ecfp_reduce(H3, H3, group);
-
- /* rz = pz * qz * H */
- PREFIX(multiply) (t0, q->z, H);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(multiply) (t1, t0, p->z);
- group->ecfp_reduce(r->z, t1, group);
-
- /* rx = R^2 - H^3 - 2 * U */
- PREFIX(square) (t0, R);
- PREFIX(subtractShort) (t0, t0, H3);
- PREFIX(subtractShort) (t0, t0, U);
- PREFIX(subtractShort) (t0, t0, U);
- group->ecfp_reduce(r->x, t0, group);
-
- /* ry = R(U - rx) - S*H3 */
- PREFIX(subtractShort) (t1, U, r->x);
- PREFIX(multiply) (t0, t1, R);
- PREFIX(multiply) (t1, S, H3);
- PREFIX(subtractLong) (t1, t0, t1);
- group->ecfp_reduce(r->y, t1, group);
-
- CLEANUP:
- return;
-}
-
-/* Perform a point doubling in Modified Jacobian coordinates. Input and
- * output should be multi-precision floating point integers. */
-void PREFIX(pt_dbl_jm) (const ecfp_jm_pt * p, ecfp_jm_pt * r,
- const EC_group_fp * group) {
-
- /* Temporary storage */
- double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
- M[2 * ECFP_NUMDOUBLES], S[2 * ECFP_NUMDOUBLES],
- U[2 * ECFP_NUMDOUBLES], T[2 * ECFP_NUMDOUBLES];
-
- /* Check for point at infinity */
- if (PREFIX(pt_is_inf_jm) (p) == MP_YES) {
- /* Set r = pt at infinity by setting rz = 0 */
- PREFIX(set_pt_inf_jm) (r);
- goto CLEANUP;
- }
-
- /* M = 3 (px^2) + a*(pz^4) */
- PREFIX(square) (t0, p->x);
- PREFIX(addLong) (M, t0, t0);
- PREFIX(addLong) (t0, t0, M); /* t0 = 3(px^2) */
- PREFIX(addShort) (t0, t0, p->az4);
- group->ecfp_reduce(M, t0, group);
-
- /* rz = 2 * py * pz */
- PREFIX(multiply) (t1, p->y, p->z);
- PREFIX(addLong) (t1, t1, t1);
- group->ecfp_reduce(r->z, t1, group);
-
- /* t0 = 2y^2, U = 8y^4 */
- PREFIX(square) (t0, p->y);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(addShort) (t0, t0, t0);
- PREFIX(square) (U, t0);
- group->ecfp_reduce(U, U, group);
- PREFIX(addShort) (U, U, U);
-
- /* S = 4 * px * py^2 = 2 * px * t0 */
- PREFIX(multiply) (S, p->x, t0);
- group->ecfp_reduce(S, S, group);
- PREFIX(addShort) (S, S, S);
-
- /* rx = M^2 - 2S */
- PREFIX(square) (T, M);
- PREFIX(subtractShort) (T, T, S);
- PREFIX(subtractShort) (T, T, S);
- group->ecfp_reduce(r->x, T, group);
-
- /* ry = M * (S - rx) - U */
- PREFIX(subtractShort) (S, S, r->x);
- PREFIX(multiply) (t0, M, S);
- PREFIX(subtractShort) (t0, t0, U);
- group->ecfp_reduce(r->y, t0, group);
-
- /* ra*z^4 = 2*U*(apz4) */
- PREFIX(multiply) (t1, U, p->az4);
- PREFIX(addLong) (t1, t1, t1);
- group->ecfp_reduce(r->az4, t1, group);
-
- CLEANUP:
- return;
-}
-
-/* Perform a point doubling using coordinates Affine -> Chudnovsky
- * Jacobian. Input and output should be multi-precision floating point
- * integers. */
-void PREFIX(pt_dbl_aff2chud) (const ecfp_aff_pt * p, ecfp_chud_pt * r,
- const EC_group_fp * group) {
- double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
- M[2 * ECFP_NUMDOUBLES], twoY2[2 * ECFP_NUMDOUBLES],
- S[2 * ECFP_NUMDOUBLES];
-
- /* Check for point at infinity for p, if so set r = O */
- if (PREFIX(pt_is_inf_aff) (p) == MP_YES) {
- PREFIX(set_pt_inf_chud) (r);
- goto CLEANUP;
- }
-
- /* M = 3(px)^2 + a */
- PREFIX(square) (t0, p->x);
- PREFIX(addLong) (t1, t0, t0);
- PREFIX(addLong) (t1, t1, t0);
- PREFIX(addShort) (t1, t1, group->curvea);
- group->ecfp_reduce(M, t1, group);
-
- /* twoY2 = 2*(py)^2, S = 4(px)(py)^2 */
- PREFIX(square) (twoY2, p->y);
- PREFIX(addLong) (twoY2, twoY2, twoY2);
- group->ecfp_reduce(twoY2, twoY2, group);
- PREFIX(multiply) (S, p->x, twoY2);
- PREFIX(addLong) (S, S, S);
- group->ecfp_reduce(S, S, group);
-
- /* rx = M^2 - 2S */
- PREFIX(square) (t0, M);
- PREFIX(subtractShort) (t0, t0, S);
- PREFIX(subtractShort) (t0, t0, S);
- group->ecfp_reduce(r->x, t0, group);
-
- /* ry = M(S-rx) - 8y^4 */
- PREFIX(subtractShort) (t0, S, r->x);
- PREFIX(multiply) (t1, t0, M);
- PREFIX(square) (t0, twoY2);
- PREFIX(subtractLong) (t1, t1, t0);
- PREFIX(subtractLong) (t1, t1, t0);
- group->ecfp_reduce(r->y, t1, group);
-
- /* rz = 2py */
- PREFIX(addShort) (r->z, p->y, p->y);
-
- /* rz2 = rz^2 */
- PREFIX(square) (t0, r->z);
- group->ecfp_reduce(r->z2, t0, group);
-
- /* rz3 = rz^3 */
- PREFIX(multiply) (t0, r->z, r->z2);
- group->ecfp_reduce(r->z3, t0, group);
-
- CLEANUP:
- return;
-}
-
-/* Perform a point addition using coordinates: Modified Jacobian +
- * Chudnovsky Jacobian -> Modified Jacobian. Input and output should be
- * multi-precision floating point integers. */
-void PREFIX(pt_add_jm_chud) (ecfp_jm_pt * p, ecfp_chud_pt * q,
- ecfp_jm_pt * r, const EC_group_fp * group) {
-
- double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
- U[2 * ECFP_NUMDOUBLES], R[2 * ECFP_NUMDOUBLES],
- S[2 * ECFP_NUMDOUBLES], H[2 * ECFP_NUMDOUBLES],
- H3[2 * ECFP_NUMDOUBLES], pz2[2 * ECFP_NUMDOUBLES];
-
- /* Check for point at infinity for p, if so set r = q need to convert
- * from Chudnovsky form to Modified Jacobian form */
- if (PREFIX(pt_is_inf_jm) (p) == MP_YES) {
- PREFIX(copy) (r->x, q->x);
- PREFIX(copy) (r->y, q->y);
- PREFIX(copy) (r->z, q->z);
- PREFIX(square) (t0, q->z2);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(multiply) (t1, t0, group->curvea);
- group->ecfp_reduce(r->az4, t1, group);
- goto CLEANUP;
- }
- /* Check for point at infinity for q, if so set r = p */
- if (PREFIX(pt_is_inf_chud) (q) == MP_YES) {
- PREFIX(copy) (r->x, p->x);
- PREFIX(copy) (r->y, p->y);
- PREFIX(copy) (r->z, p->z);
- PREFIX(copy) (r->az4, p->az4);
- goto CLEANUP;
- }
-
- /* U = px * qz^2 */
- PREFIX(multiply) (U, p->x, q->z2);
- group->ecfp_reduce(U, U, group);
-
- /* H = qx*(pz)^2 - U */
- PREFIX(square) (t0, p->z);
- group->ecfp_reduce(pz2, t0, group);
- PREFIX(multiply) (H, pz2, q->x);
- group->ecfp_reduce(H, H, group);
- PREFIX(subtractShort) (H, H, U);
-
- /* U = U*H^2, H3 = H^3 */
- PREFIX(square) (t0, H);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(multiply) (t1, U, t0);
- group->ecfp_reduce(U, t1, group);
- PREFIX(multiply) (H3, t0, H);
- group->ecfp_reduce(H3, H3, group);
-
- /* S = py * qz^3 */
- PREFIX(multiply) (S, p->y, q->z3);
- group->ecfp_reduce(S, S, group);
-
- /* R = (qy * z1^3 - s) */
- PREFIX(multiply) (t0, pz2, p->z);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(multiply) (R, t0, q->y);
- PREFIX(subtractShort) (R, R, S);
- group->ecfp_reduce(R, R, group);
-
- /* rz = pz * qz * H */
- PREFIX(multiply) (t1, q->z, H);
- group->ecfp_reduce(t1, t1, group);
- PREFIX(multiply) (t0, p->z, t1);
- group->ecfp_reduce(r->z, t0, group);
-
- /* rx = R^2 - H^3 - 2 * U */
- PREFIX(square) (t0, R);
- PREFIX(subtractShort) (t0, t0, H3);
- PREFIX(subtractShort) (t0, t0, U);
- PREFIX(subtractShort) (t0, t0, U);
- group->ecfp_reduce(r->x, t0, group);
-
- /* ry = R(U - rx) - S*H3 */
- PREFIX(subtractShort) (t1, U, r->x);
- PREFIX(multiply) (t0, t1, R);
- PREFIX(multiply) (t1, S, H3);
- PREFIX(subtractLong) (t1, t0, t1);
- group->ecfp_reduce(r->y, t1, group);
-
- if (group->aIsM3) { /* a == -3 */
- /* a(rz^4) = -3 * ((rz^2)^2) */
- PREFIX(square) (t0, r->z);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(square) (t1, t0);
- PREFIX(addLong) (t0, t1, t1);
- PREFIX(addLong) (t0, t0, t1);
- PREFIX(negLong) (t0, t0);
- group->ecfp_reduce(r->az4, t0, group);
- } else { /* Generic case */
- /* a(rz^4) = a * ((rz^2)^2) */
- PREFIX(square) (t0, r->z);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(square) (t1, t0);
- group->ecfp_reduce(t1, t1, group);
- PREFIX(multiply) (t0, group->curvea, t1);
- group->ecfp_reduce(r->az4, t0, group);
- }
- CLEANUP:
- return;
-}
-
-/* Perform a point addition using Chudnovsky Jacobian coordinates. Input
- * and output should be multi-precision floating point integers. */
-void PREFIX(pt_add_chud) (const ecfp_chud_pt * p, const ecfp_chud_pt * q,
- ecfp_chud_pt * r, const EC_group_fp * group) {
-
- /* Temporary Storage */
- double t0[2 * ECFP_NUMDOUBLES], t1[2 * ECFP_NUMDOUBLES],
- U[2 * ECFP_NUMDOUBLES], R[2 * ECFP_NUMDOUBLES],
- S[2 * ECFP_NUMDOUBLES], H[2 * ECFP_NUMDOUBLES],
- H3[2 * ECFP_NUMDOUBLES];
-
- /* Check for point at infinity for p, if so set r = q */
- if (PREFIX(pt_is_inf_chud) (p) == MP_YES) {
- PREFIX(copy) (r->x, q->x);
- PREFIX(copy) (r->y, q->y);
- PREFIX(copy) (r->z, q->z);
- PREFIX(copy) (r->z2, q->z2);
- PREFIX(copy) (r->z3, q->z3);
- goto CLEANUP;
- }
-
- /* Check for point at infinity for p, if so set r = q */
- if (PREFIX(pt_is_inf_chud) (q) == MP_YES) {
- PREFIX(copy) (r->x, p->x);
- PREFIX(copy) (r->y, p->y);
- PREFIX(copy) (r->z, p->z);
- PREFIX(copy) (r->z2, p->z2);
- PREFIX(copy) (r->z3, p->z3);
- goto CLEANUP;
- }
-
- /* U = px * qz^2 */
- PREFIX(multiply) (U, p->x, q->z2);
- group->ecfp_reduce(U, U, group);
-
- /* H = qx*(pz)^2 - U */
- PREFIX(multiply) (H, q->x, p->z2);
- PREFIX(subtractShort) (H, H, U);
- group->ecfp_reduce(H, H, group);
-
- /* U = U*H^2, H3 = H^3 */
- PREFIX(square) (t0, H);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(multiply) (t1, U, t0);
- group->ecfp_reduce(U, t1, group);
- PREFIX(multiply) (H3, t0, H);
- group->ecfp_reduce(H3, H3, group);
-
- /* S = py * qz^3 */
- PREFIX(multiply) (S, p->y, q->z3);
- group->ecfp_reduce(S, S, group);
-
- /* rz = pz * qz * H */
- PREFIX(multiply) (t0, q->z, H);
- group->ecfp_reduce(t0, t0, group);
- PREFIX(multiply) (t1, t0, p->z);
- group->ecfp_reduce(r->z, t1, group);
-
- /* R = (qy * z1^3 - s) */
- PREFIX(multiply) (t0, q->y, p->z3);
- PREFIX(subtractShort) (t0, t0, S);
- group->ecfp_reduce(R, t0, group);
-
- /* rx = R^2 - H^3 - 2 * U */
- PREFIX(square) (t0, R);
- PREFIX(subtractShort) (t0, t0, H3);
- PREFIX(subtractShort) (t0, t0, U);
- PREFIX(subtractShort) (t0, t0, U);
- group->ecfp_reduce(r->x, t0, group);
-
- /* ry = R(U - rx) - S*H3 */
- PREFIX(subtractShort) (t1, U, r->x);
- PREFIX(multiply) (t0, t1, R);
- PREFIX(multiply) (t1, S, H3);
- PREFIX(subtractLong) (t1, t0, t1);
- group->ecfp_reduce(r->y, t1, group);
-
- /* rz2 = rz^2 */
- PREFIX(square) (t0, r->z);
- group->ecfp_reduce(r->z2, t0, group);
-
- /* rz3 = rz^3 */
- PREFIX(multiply) (t0, r->z, r->z2);
- group->ecfp_reduce(r->z3, t0, group);
-
- CLEANUP:
- return;
-}
-
-/* Expects out to be an array of size 16 of Chudnovsky Jacobian points.
- * Fills in Chudnovsky Jacobian form (x, y, z, z^2, z^3), for -15P, -13P,
- * -11P, -9P, -7P, -5P, -3P, -P, P, 3P, 5P, 7P, 9P, 11P, 13P, 15P */
-void PREFIX(precompute_chud) (ecfp_chud_pt * out, const ecfp_aff_pt * p,
- const EC_group_fp * group) {
-
- ecfp_chud_pt p2;
-
- /* Set out[8] = P */
- PREFIX(copy) (out[8].x, p->x);
- PREFIX(copy) (out[8].y, p->y);
- PREFIX(one) (out[8].z);
- PREFIX(one) (out[8].z2);
- PREFIX(one) (out[8].z3);
-
- /* Set p2 = 2P */
- PREFIX(pt_dbl_aff2chud) (p, &p2, group);
-
- /* Set 3P, 5P, ..., 15P */
- PREFIX(pt_add_chud) (&out[8], &p2, &out[9], group);
- PREFIX(pt_add_chud) (&out[9], &p2, &out[10], group);
- PREFIX(pt_add_chud) (&out[10], &p2, &out[11], group);
- PREFIX(pt_add_chud) (&out[11], &p2, &out[12], group);
- PREFIX(pt_add_chud) (&out[12], &p2, &out[13], group);
- PREFIX(pt_add_chud) (&out[13], &p2, &out[14], group);
- PREFIX(pt_add_chud) (&out[14], &p2, &out[15], group);
-
- /* Set -15P, -13P, ..., -P */
- PREFIX(pt_neg_chud) (&out[8], &out[7]);
- PREFIX(pt_neg_chud) (&out[9], &out[6]);
- PREFIX(pt_neg_chud) (&out[10], &out[5]);
- PREFIX(pt_neg_chud) (&out[11], &out[4]);
- PREFIX(pt_neg_chud) (&out[12], &out[3]);
- PREFIX(pt_neg_chud) (&out[13], &out[2]);
- PREFIX(pt_neg_chud) (&out[14], &out[1]);
- PREFIX(pt_neg_chud) (&out[15], &out[0]);
-}
-
-/* Expects out to be an array of size 16 of Jacobian points. Fills in
- * Jacobian form (x, y, z), for O, P, 2P, ... 15P */
-void PREFIX(precompute_jac) (ecfp_jac_pt * precomp, const ecfp_aff_pt * p,
- const EC_group_fp * group) {
- int i;
-
- /* fill precomputation table */
- /* set precomp[0] */
- PREFIX(set_pt_inf_jac) (&precomp[0]);
- /* set precomp[1] */
- PREFIX(copy) (precomp[1].x, p->x);
- PREFIX(copy) (precomp[1].y, p->y);
- if (PREFIX(pt_is_inf_aff) (p) == MP_YES) {
- PREFIX(zero) (precomp[1].z);
- } else {
- PREFIX(one) (precomp[1].z);
- }
- /* set precomp[2] */
- group->pt_dbl_jac(&precomp[1], &precomp[2], group);
-
- /* set rest of precomp */
- for (i = 3; i < 16; i++) {
- group->pt_add_jac_aff(&precomp[i - 1], p, &precomp[i], group);
- }
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_jac.c b/security/nss/lib/freebl/ecl/ecp_jac.c
deleted file mode 100644
index c7bb239c9..000000000
--- a/security/nss/lib/freebl/ecl/ecp_jac.c
+++ /dev/null
@@ -1,514 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp.h"
-#include "mplogic.h"
-#include <stdlib.h>
-#ifdef ECL_DEBUG
-#include <assert.h>
-#endif
-
-/* Converts a point P(px, py) from affine coordinates to Jacobian
- * projective coordinates R(rx, ry, rz). Assumes input is already
- * field-encoded using field_enc, and returns output that is still
- * field-encoded. */
-mp_err
-ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
- mp_int *ry, mp_int *rz, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
-
- if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
- MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
- } else {
- MP_CHECKOK(mp_copy(px, rx));
- MP_CHECKOK(mp_copy(py, ry));
- MP_CHECKOK(mp_set_int(rz, 1));
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
- }
- }
- CLEANUP:
- return res;
-}
-
-/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
- * affine coordinates R(rx, ry). P and R can share x and y coordinates.
- * Assumes input is already field-encoded using field_enc, and returns
- * output that is still field-encoded. */
-mp_err
-ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
- mp_int *rx, mp_int *ry, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int z1, z2, z3;
-
- MP_DIGITS(&z1) = 0;
- MP_DIGITS(&z2) = 0;
- MP_DIGITS(&z3) = 0;
- MP_CHECKOK(mp_init(&z1));
- MP_CHECKOK(mp_init(&z2));
- MP_CHECKOK(mp_init(&z3));
-
- /* if point at infinity, then set point at infinity and exit */
- if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
- MP_CHECKOK(ec_GFp_pt_set_inf_aff(rx, ry));
- goto CLEANUP;
- }
-
- /* transform (px, py, pz) into (px / pz^2, py / pz^3) */
- if (mp_cmp_d(pz, 1) == 0) {
- MP_CHECKOK(mp_copy(px, rx));
- MP_CHECKOK(mp_copy(py, ry));
- } else {
- MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
- MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
- MP_CHECKOK(group->meth->field_mul(&z1, &z2, &z3, group->meth));
- MP_CHECKOK(group->meth->field_mul(px, &z2, rx, group->meth));
- MP_CHECKOK(group->meth->field_mul(py, &z3, ry, group->meth));
- }
-
- CLEANUP:
- mp_clear(&z1);
- mp_clear(&z2);
- mp_clear(&z3);
- return res;
-}
-
-/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian
- * coordinates. */
-mp_err
-ec_GFp_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz)
-{
- return mp_cmp_z(pz);
-}
-
-/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian
- * coordinates. */
-mp_err
-ec_GFp_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz)
-{
- mp_zero(pz);
- return MP_OKAY;
-}
-
-/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
- * (qx, qy, 1). Elliptic curve points P, Q, and R can all be identical.
- * Uses mixed Jacobian-affine coordinates. Assumes input is already
- * field-encoded using field_enc, and returns output that is still
- * field-encoded. Uses equation (2) from Brown, Hankerson, Lopez, and
- * Menezes. Software Implementation of the NIST Elliptic Curves Over Prime
- * Fields. */
-mp_err
-ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
- const mp_int *qx, const mp_int *qy, mp_int *rx,
- mp_int *ry, mp_int *rz, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int A, B, C, D, C2, C3;
-
- MP_DIGITS(&A) = 0;
- MP_DIGITS(&B) = 0;
- MP_DIGITS(&C) = 0;
- MP_DIGITS(&D) = 0;
- MP_DIGITS(&C2) = 0;
- MP_DIGITS(&C3) = 0;
- MP_CHECKOK(mp_init(&A));
- MP_CHECKOK(mp_init(&B));
- MP_CHECKOK(mp_init(&C));
- MP_CHECKOK(mp_init(&D));
- MP_CHECKOK(mp_init(&C2));
- MP_CHECKOK(mp_init(&C3));
-
- /* If either P or Q is the point at infinity, then return the other
- * point */
- if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
- MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
- goto CLEANUP;
- }
- if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
- MP_CHECKOK(mp_copy(px, rx));
- MP_CHECKOK(mp_copy(py, ry));
- MP_CHECKOK(mp_copy(pz, rz));
- goto CLEANUP;
- }
-
- /* A = qx * pz^2, B = qy * pz^3 */
- MP_CHECKOK(group->meth->field_sqr(pz, &A, group->meth));
- MP_CHECKOK(group->meth->field_mul(&A, pz, &B, group->meth));
- MP_CHECKOK(group->meth->field_mul(&A, qx, &A, group->meth));
- MP_CHECKOK(group->meth->field_mul(&B, qy, &B, group->meth));
-
- /* C = A - px, D = B - py */
- MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
- MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));
-
- /* C2 = C^2, C3 = C^3 */
- MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
- MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));
-
- /* rz = pz * C */
- MP_CHECKOK(group->meth->field_mul(pz, &C, rz, group->meth));
-
- /* C = px * C^2 */
- MP_CHECKOK(group->meth->field_mul(px, &C2, &C, group->meth));
- /* A = D^2 */
- MP_CHECKOK(group->meth->field_sqr(&D, &A, group->meth));
-
- /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
- MP_CHECKOK(group->meth->field_add(&C, &C, rx, group->meth));
- MP_CHECKOK(group->meth->field_add(&C3, rx, rx, group->meth));
- MP_CHECKOK(group->meth->field_sub(&A, rx, rx, group->meth));
-
- /* C3 = py * C^3 */
- MP_CHECKOK(group->meth->field_mul(py, &C3, &C3, group->meth));
-
- /* ry = D * (px * C^2 - rx) - py * C^3 */
- MP_CHECKOK(group->meth->field_sub(&C, rx, ry, group->meth));
- MP_CHECKOK(group->meth->field_mul(&D, ry, ry, group->meth));
- MP_CHECKOK(group->meth->field_sub(ry, &C3, ry, group->meth));
-
- CLEANUP:
- mp_clear(&A);
- mp_clear(&B);
- mp_clear(&C);
- mp_clear(&D);
- mp_clear(&C2);
- mp_clear(&C3);
- return res;
-}
-
-/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
- * Jacobian coordinates.
- *
- * Assumes input is already field-encoded using field_enc, and returns
- * output that is still field-encoded.
- *
- * This routine implements Point Doubling in the Jacobian Projective
- * space as described in the paper "Efficient elliptic curve exponentiation
- * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono.
- */
-mp_err
-ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py, const mp_int *pz,
- mp_int *rx, mp_int *ry, mp_int *rz, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int t0, t1, M, S;
-
- MP_DIGITS(&t0) = 0;
- MP_DIGITS(&t1) = 0;
- MP_DIGITS(&M) = 0;
- MP_DIGITS(&S) = 0;
- MP_CHECKOK(mp_init(&t0));
- MP_CHECKOK(mp_init(&t1));
- MP_CHECKOK(mp_init(&M));
- MP_CHECKOK(mp_init(&S));
-
- if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
- MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
- goto CLEANUP;
- }
-
- if (mp_cmp_d(pz, 1) == 0) {
- /* M = 3 * px^2 + a */
- MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
- MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
- MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
- MP_CHECKOK(group->meth->
- field_add(&t0, &group->curvea, &M, group->meth));
- } else if (mp_cmp_int(&group->curvea, -3) == 0) {
- /* M = 3 * (px + pz^2) * (px - pz^2) */
- MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
- MP_CHECKOK(group->meth->field_add(px, &M, &t0, group->meth));
- MP_CHECKOK(group->meth->field_sub(px, &M, &t1, group->meth));
- MP_CHECKOK(group->meth->field_mul(&t0, &t1, &M, group->meth));
- MP_CHECKOK(group->meth->field_add(&M, &M, &t0, group->meth));
- MP_CHECKOK(group->meth->field_add(&t0, &M, &M, group->meth));
- } else {
- /* M = 3 * (px^2) + a * (pz^4) */
- MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
- MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
- MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
- MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
- MP_CHECKOK(group->meth->field_sqr(&M, &M, group->meth));
- MP_CHECKOK(group->meth->
- field_mul(&M, &group->curvea, &M, group->meth));
- MP_CHECKOK(group->meth->field_add(&M, &t0, &M, group->meth));
- }
-
- /* rz = 2 * py * pz */
- /* t0 = 4 * py^2 */
- if (mp_cmp_d(pz, 1) == 0) {
- MP_CHECKOK(group->meth->field_add(py, py, rz, group->meth));
- MP_CHECKOK(group->meth->field_sqr(rz, &t0, group->meth));
- } else {
- MP_CHECKOK(group->meth->field_add(py, py, &t0, group->meth));
- MP_CHECKOK(group->meth->field_mul(&t0, pz, rz, group->meth));
- MP_CHECKOK(group->meth->field_sqr(&t0, &t0, group->meth));
- }
-
- /* S = 4 * px * py^2 = px * (2 * py)^2 */
- MP_CHECKOK(group->meth->field_mul(px, &t0, &S, group->meth));
-
- /* rx = M^2 - 2 * S */
- MP_CHECKOK(group->meth->field_add(&S, &S, &t1, group->meth));
- MP_CHECKOK(group->meth->field_sqr(&M, rx, group->meth));
- MP_CHECKOK(group->meth->field_sub(rx, &t1, rx, group->meth));
-
- /* ry = M * (S - rx) - 8 * py^4 */
- MP_CHECKOK(group->meth->field_sqr(&t0, &t1, group->meth));
- if (mp_isodd(&t1)) {
- MP_CHECKOK(mp_add(&t1, &group->meth->irr, &t1));
- }
- MP_CHECKOK(mp_div_2(&t1, &t1));
- MP_CHECKOK(group->meth->field_sub(&S, rx, &S, group->meth));
- MP_CHECKOK(group->meth->field_mul(&M, &S, &M, group->meth));
- MP_CHECKOK(group->meth->field_sub(&M, &t1, ry, group->meth));
-
- CLEANUP:
- mp_clear(&t0);
- mp_clear(&t1);
- mp_clear(&M);
- mp_clear(&S);
- return res;
-}
-
-/* by default, this routine is unused and thus doesn't need to be compiled */
-#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
-/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters
- * a, b and p are the elliptic curve coefficients and the prime that
- * determines the field GFp. Elliptic curve points P and R can be
- * identical. Uses mixed Jacobian-affine coordinates. Assumes input is
- * already field-encoded using field_enc, and returns output that is still
- * field-encoded. Uses 4-bit window method. */
-mp_err
-ec_GFp_pt_mul_jac(const mp_int *n, const mp_int *px, const mp_int *py,
- mp_int *rx, mp_int *ry, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int precomp[16][2], rz;
- int i, ni, d;
-
- MP_DIGITS(&rz) = 0;
- for (i = 0; i < 16; i++) {
- MP_DIGITS(&precomp[i][0]) = 0;
- MP_DIGITS(&precomp[i][1]) = 0;
- }
-
- ARGCHK(group != NULL, MP_BADARG);
- ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
-
- /* initialize precomputation table */
- for (i = 0; i < 16; i++) {
- MP_CHECKOK(mp_init(&precomp[i][0]));
- MP_CHECKOK(mp_init(&precomp[i][1]));
- }
-
- /* fill precomputation table */
- mp_zero(&precomp[0][0]);
- mp_zero(&precomp[0][1]);
- MP_CHECKOK(mp_copy(px, &precomp[1][0]));
- MP_CHECKOK(mp_copy(py, &precomp[1][1]));
- for (i = 2; i < 16; i++) {
- MP_CHECKOK(group->
- point_add(&precomp[1][0], &precomp[1][1],
- &precomp[i - 1][0], &precomp[i - 1][1],
- &precomp[i][0], &precomp[i][1], group));
- }
-
- d = (mpl_significant_bits(n) + 3) / 4;
-
- /* R = inf */
- MP_CHECKOK(mp_init(&rz));
- MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
-
- for (i = d - 1; i >= 0; i--) {
- /* compute window ni */
- ni = MP_GET_BIT(n, 4 * i + 3);
- ni <<= 1;
- ni |= MP_GET_BIT(n, 4 * i + 2);
- ni <<= 1;
- ni |= MP_GET_BIT(n, 4 * i + 1);
- ni <<= 1;
- ni |= MP_GET_BIT(n, 4 * i);
- /* R = 2^4 * R */
- MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
- MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
- MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
- MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
- /* R = R + (ni * P) */
- MP_CHECKOK(ec_GFp_pt_add_jac_aff
- (rx, ry, &rz, &precomp[ni][0], &precomp[ni][1], rx, ry,
- &rz, group));
- }
-
- /* convert result S to affine coordinates */
- MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
-
- CLEANUP:
- mp_clear(&rz);
- for (i = 0; i < 16; i++) {
- mp_clear(&precomp[i][0]);
- mp_clear(&precomp[i][1]);
- }
- return res;
-}
-#endif
-
-/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
- * k2 * P(x, y), where G is the generator (base point) of the group of
- * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
- * Uses mixed Jacobian-affine coordinates. Input and output values are
- * assumed to be NOT field-encoded. Uses algorithm 15 (simultaneous
- * multiple point multiplication) from Brown, Hankerson, Lopez, Menezes.
- * Software Implementation of the NIST Elliptic Curves over Prime Fields. */
-mp_err
-ec_GFp_pts_mul_jac(const mp_int *k1, const mp_int *k2, const mp_int *px,
- const mp_int *py, mp_int *rx, mp_int *ry,
- const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int precomp[4][4][2];
- mp_int rz;
- const mp_int *a, *b;
- int i, j;
- int ai, bi, d;
-
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- MP_DIGITS(&precomp[i][j][0]) = 0;
- MP_DIGITS(&precomp[i][j][1]) = 0;
- }
- }
- MP_DIGITS(&rz) = 0;
-
- ARGCHK(group != NULL, MP_BADARG);
- ARGCHK(!((k1 == NULL)
- && ((k2 == NULL) || (px == NULL)
- || (py == NULL))), MP_BADARG);
-
- /* if some arguments are not defined used ECPoint_mul */
- if (k1 == NULL) {
- return ECPoint_mul(group, k2, px, py, rx, ry);
- } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
- return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
- }
-
- /* initialize precomputation table */
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- MP_CHECKOK(mp_init(&precomp[i][j][0]));
- MP_CHECKOK(mp_init(&precomp[i][j][1]));
- }
- }
-
- /* fill precomputation table */
- /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
- if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
- a = k2;
- b = k1;
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->
- field_enc(px, &precomp[1][0][0], group->meth));
- MP_CHECKOK(group->meth->
- field_enc(py, &precomp[1][0][1], group->meth));
- } else {
- MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
- MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
- }
- MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
- MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
- } else {
- a = k1;
- b = k2;
- MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
- MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
- if (group->meth->field_enc) {
- MP_CHECKOK(group->meth->
- field_enc(px, &precomp[0][1][0], group->meth));
- MP_CHECKOK(group->meth->
- field_enc(py, &precomp[0][1][1], group->meth));
- } else {
- MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
- MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
- }
- }
- /* precompute [*][0][*] */
- mp_zero(&precomp[0][0][0]);
- mp_zero(&precomp[0][0][1]);
- MP_CHECKOK(group->
- point_dbl(&precomp[1][0][0], &precomp[1][0][1],
- &precomp[2][0][0], &precomp[2][0][1], group));
- MP_CHECKOK(group->
- point_add(&precomp[1][0][0], &precomp[1][0][1],
- &precomp[2][0][0], &precomp[2][0][1],
- &precomp[3][0][0], &precomp[3][0][1], group));
- /* precompute [*][1][*] */
- for (i = 1; i < 4; i++) {
- MP_CHECKOK(group->
- point_add(&precomp[0][1][0], &precomp[0][1][1],
- &precomp[i][0][0], &precomp[i][0][1],
- &precomp[i][1][0], &precomp[i][1][1], group));
- }
- /* precompute [*][2][*] */
- MP_CHECKOK(group->
- point_dbl(&precomp[0][1][0], &precomp[0][1][1],
- &precomp[0][2][0], &precomp[0][2][1], group));
- for (i = 1; i < 4; i++) {
- MP_CHECKOK(group->
- point_add(&precomp[0][2][0], &precomp[0][2][1],
- &precomp[i][0][0], &precomp[i][0][1],
- &precomp[i][2][0], &precomp[i][2][1], group));
- }
- /* precompute [*][3][*] */
- MP_CHECKOK(group->
- point_add(&precomp[0][1][0], &precomp[0][1][1],
- &precomp[0][2][0], &precomp[0][2][1],
- &precomp[0][3][0], &precomp[0][3][1], group));
- for (i = 1; i < 4; i++) {
- MP_CHECKOK(group->
- point_add(&precomp[0][3][0], &precomp[0][3][1],
- &precomp[i][0][0], &precomp[i][0][1],
- &precomp[i][3][0], &precomp[i][3][1], group));
- }
-
- d = (mpl_significant_bits(a) + 1) / 2;
-
- /* R = inf */
- MP_CHECKOK(mp_init(&rz));
- MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
-
- for (i = d - 1; i >= 0; i--) {
- ai = MP_GET_BIT(a, 2 * i + 1);
- ai <<= 1;
- ai |= MP_GET_BIT(a, 2 * i);
- bi = MP_GET_BIT(b, 2 * i + 1);
- bi <<= 1;
- bi |= MP_GET_BIT(b, 2 * i);
- /* R = 2^2 * R */
- MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
- MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
- /* R = R + (ai * A + bi * B) */
- MP_CHECKOK(ec_GFp_pt_add_jac_aff
- (rx, ry, &rz, &precomp[ai][bi][0], &precomp[ai][bi][1],
- rx, ry, &rz, group));
- }
-
- MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
-
- if (group->meth->field_dec) {
- MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
- MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
- }
-
- CLEANUP:
- mp_clear(&rz);
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- mp_clear(&precomp[i][j][0]);
- mp_clear(&precomp[i][j][1]);
- }
- }
- return res;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_jm.c b/security/nss/lib/freebl/ecl/ecp_jm.c
deleted file mode 100644
index b1a3dc89f..000000000
--- a/security/nss/lib/freebl/ecl/ecp_jm.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp.h"
-#include "ecl-priv.h"
-#include "mplogic.h"
-#include <stdlib.h>
-
-#define MAX_SCRATCH 6
-
-/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses
- * Modified Jacobian coordinates.
- *
- * Assumes input is already field-encoded using field_enc, and returns
- * output that is still field-encoded.
- *
- */
-mp_err
-ec_GFp_pt_dbl_jm(const mp_int *px, const mp_int *py, const mp_int *pz,
- const mp_int *paz4, mp_int *rx, mp_int *ry, mp_int *rz,
- mp_int *raz4, mp_int scratch[], const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int *t0, *t1, *M, *S;
-
- t0 = &scratch[0];
- t1 = &scratch[1];
- M = &scratch[2];
- S = &scratch[3];
-
-#if MAX_SCRATCH < 4
-#error "Scratch array defined too small "
-#endif
-
- /* Check for point at infinity */
- if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
- /* Set r = pt at infinity by setting rz = 0 */
-
- MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
- goto CLEANUP;
- }
-
- /* M = 3 (px^2) + a*(pz^4) */
- MP_CHECKOK(group->meth->field_sqr(px, t0, group->meth));
- MP_CHECKOK(group->meth->field_add(t0, t0, M, group->meth));
- MP_CHECKOK(group->meth->field_add(t0, M, t0, group->meth));
- MP_CHECKOK(group->meth->field_add(t0, paz4, M, group->meth));
-
- /* rz = 2 * py * pz */
- MP_CHECKOK(group->meth->field_mul(py, pz, S, group->meth));
- MP_CHECKOK(group->meth->field_add(S, S, rz, group->meth));
-
- /* t0 = 2y^2 , t1 = 8y^4 */
- MP_CHECKOK(group->meth->field_sqr(py, t0, group->meth));
- MP_CHECKOK(group->meth->field_add(t0, t0, t0, group->meth));
- MP_CHECKOK(group->meth->field_sqr(t0, t1, group->meth));
- MP_CHECKOK(group->meth->field_add(t1, t1, t1, group->meth));
-
- /* S = 4 * px * py^2 = 2 * px * t0 */
- MP_CHECKOK(group->meth->field_mul(px, t0, S, group->meth));
- MP_CHECKOK(group->meth->field_add(S, S, S, group->meth));
-
-
- /* rx = M^2 - 2S */
- MP_CHECKOK(group->meth->field_sqr(M, rx, group->meth));
- MP_CHECKOK(group->meth->field_sub(rx, S, rx, group->meth));
- MP_CHECKOK(group->meth->field_sub(rx, S, rx, group->meth));
-
- /* ry = M * (S - rx) - t1 */
- MP_CHECKOK(group->meth->field_sub(S, rx, S, group->meth));
- MP_CHECKOK(group->meth->field_mul(S, M, ry, group->meth));
- MP_CHECKOK(group->meth->field_sub(ry, t1, ry, group->meth));
-
- /* ra*z^4 = 2*t1*(apz4) */
- MP_CHECKOK(group->meth->field_mul(paz4, t1, raz4, group->meth));
- MP_CHECKOK(group->meth->field_add(raz4, raz4, raz4, group->meth));
-
-
- CLEANUP:
- return res;
-}
-
-/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and Q is
- * (qx, qy, 1). Elliptic curve points P, Q, and R can all be identical.
- * Uses mixed Modified_Jacobian-affine coordinates. Assumes input is
- * already field-encoded using field_enc, and returns output that is still
- * field-encoded. */
-mp_err
-ec_GFp_pt_add_jm_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
- const mp_int *paz4, const mp_int *qx,
- const mp_int *qy, mp_int *rx, mp_int *ry, mp_int *rz,
- mp_int *raz4, mp_int scratch[], const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int *A, *B, *C, *D, *C2, *C3;
-
- A = &scratch[0];
- B = &scratch[1];
- C = &scratch[2];
- D = &scratch[3];
- C2 = &scratch[4];
- C3 = &scratch[5];
-
-#if MAX_SCRATCH < 6
-#error "Scratch array defined too small "
-#endif
-
- /* If either P or Q is the point at infinity, then return the other
- * point */
- if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
- MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
- MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
- MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
- MP_CHECKOK(group->meth->
- field_mul(raz4, &group->curvea, raz4, group->meth));
- goto CLEANUP;
- }
- if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
- MP_CHECKOK(mp_copy(px, rx));
- MP_CHECKOK(mp_copy(py, ry));
- MP_CHECKOK(mp_copy(pz, rz));
- MP_CHECKOK(mp_copy(paz4, raz4));
- goto CLEANUP;
- }
-
- /* A = qx * pz^2, B = qy * pz^3 */
- MP_CHECKOK(group->meth->field_sqr(pz, A, group->meth));
- MP_CHECKOK(group->meth->field_mul(A, pz, B, group->meth));
- MP_CHECKOK(group->meth->field_mul(A, qx, A, group->meth));
- MP_CHECKOK(group->meth->field_mul(B, qy, B, group->meth));
-
- /* C = A - px, D = B - py */
- MP_CHECKOK(group->meth->field_sub(A, px, C, group->meth));
- MP_CHECKOK(group->meth->field_sub(B, py, D, group->meth));
-
- /* C2 = C^2, C3 = C^3 */
- MP_CHECKOK(group->meth->field_sqr(C, C2, group->meth));
- MP_CHECKOK(group->meth->field_mul(C, C2, C3, group->meth));
-
- /* rz = pz * C */
- MP_CHECKOK(group->meth->field_mul(pz, C, rz, group->meth));
-
- /* C = px * C^2 */
- MP_CHECKOK(group->meth->field_mul(px, C2, C, group->meth));
- /* A = D^2 */
- MP_CHECKOK(group->meth->field_sqr(D, A, group->meth));
-
- /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
- MP_CHECKOK(group->meth->field_add(C, C, rx, group->meth));
- MP_CHECKOK(group->meth->field_add(C3, rx, rx, group->meth));
- MP_CHECKOK(group->meth->field_sub(A, rx, rx, group->meth));
-
- /* C3 = py * C^3 */
- MP_CHECKOK(group->meth->field_mul(py, C3, C3, group->meth));
-
- /* ry = D * (px * C^2 - rx) - py * C^3 */
- MP_CHECKOK(group->meth->field_sub(C, rx, ry, group->meth));
- MP_CHECKOK(group->meth->field_mul(D, ry, ry, group->meth));
- MP_CHECKOK(group->meth->field_sub(ry, C3, ry, group->meth));
-
- /* raz4 = a * rz^4 */
- MP_CHECKOK(group->meth->field_sqr(rz, raz4, group->meth));
- MP_CHECKOK(group->meth->field_sqr(raz4, raz4, group->meth));
- MP_CHECKOK(group->meth->
- field_mul(raz4, &group->curvea, raz4, group->meth));
-CLEANUP:
- return res;
-}
-
-/* Computes R = nP where R is (rx, ry) and P is the base point. Elliptic
- * curve points P and R can be identical. Uses mixed Modified-Jacobian
- * co-ordinates for doubling and Chudnovsky Jacobian coordinates for
- * additions. Assumes input is already field-encoded using field_enc, and
- * returns output that is still field-encoded. Uses 5-bit window NAF
- * method (algorithm 11) for scalar-point multiplication from Brown,
- * Hankerson, Lopez, Menezes. Software Implementation of the NIST Elliptic
- * Curves Over Prime Fields. */
-mp_err
-ec_GFp_pt_mul_jm_wNAF(const mp_int *n, const mp_int *px, const mp_int *py,
- mp_int *rx, mp_int *ry, const ECGroup *group)
-{
- mp_err res = MP_OKAY;
- mp_int precomp[16][2], rz, tpx, tpy;
- mp_int raz4;
- mp_int scratch[MAX_SCRATCH];
- signed char *naf = NULL;
- int i, orderBitSize;
-
- MP_DIGITS(&rz) = 0;
- MP_DIGITS(&raz4) = 0;
- MP_DIGITS(&tpx) = 0;
- MP_DIGITS(&tpy) = 0;
- for (i = 0; i < 16; i++) {
- MP_DIGITS(&precomp[i][0]) = 0;
- MP_DIGITS(&precomp[i][1]) = 0;
- }
- for (i = 0; i < MAX_SCRATCH; i++) {
- MP_DIGITS(&scratch[i]) = 0;
- }
-
- ARGCHK(group != NULL, MP_BADARG);
- ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);
-
- /* initialize precomputation table */
- MP_CHECKOK(mp_init(&tpx));
- MP_CHECKOK(mp_init(&tpy));;
- MP_CHECKOK(mp_init(&rz));
- MP_CHECKOK(mp_init(&raz4));
-
- for (i = 0; i < 16; i++) {
- MP_CHECKOK(mp_init(&precomp[i][0]));
- MP_CHECKOK(mp_init(&precomp[i][1]));
- }
- for (i = 0; i < MAX_SCRATCH; i++) {
- MP_CHECKOK(mp_init(&scratch[i]));
- }
-
- /* Set out[8] = P */
- MP_CHECKOK(mp_copy(px, &precomp[8][0]));
- MP_CHECKOK(mp_copy(py, &precomp[8][1]));
-
- /* Set (tpx, tpy) = 2P */
- MP_CHECKOK(group->
- point_dbl(&precomp[8][0], &precomp[8][1], &tpx, &tpy,
- group));
-
- /* Set 3P, 5P, ..., 15P */
- for (i = 8; i < 15; i++) {
- MP_CHECKOK(group->
- point_add(&precomp[i][0], &precomp[i][1], &tpx, &tpy,
- &precomp[i + 1][0], &precomp[i + 1][1],
- group));
- }
-
- /* Set -15P, -13P, ..., -P */
- for (i = 0; i < 8; i++) {
- MP_CHECKOK(mp_copy(&precomp[15 - i][0], &precomp[i][0]));
- MP_CHECKOK(group->meth->
- field_neg(&precomp[15 - i][1], &precomp[i][1],
- group->meth));
- }
-
- /* R = inf */
- MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));
-
- orderBitSize = mpl_significant_bits(&group->order);
-
- /* Allocate memory for NAF */
- naf = (signed char *) malloc(sizeof(signed char) * (orderBitSize + 1));
- if (naf == NULL) {
- res = MP_MEM;
- goto CLEANUP;
- }
-
- /* Compute 5NAF */
- ec_compute_wNAF(naf, orderBitSize, n, 5);
-
- /* wNAF method */
- for (i = orderBitSize; i >= 0; i--) {
- /* R = 2R */
- ec_GFp_pt_dbl_jm(rx, ry, &rz, &raz4, rx, ry, &rz,
- &raz4, scratch, group);
- if (naf[i] != 0) {
- ec_GFp_pt_add_jm_aff(rx, ry, &rz, &raz4,
- &precomp[(naf[i] + 15) / 2][0],
- &precomp[(naf[i] + 15) / 2][1], rx, ry,
- &rz, &raz4, scratch, group);
- }
- }
-
- /* convert result S to affine coordinates */
- MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));
-
- CLEANUP:
- for (i = 0; i < MAX_SCRATCH; i++) {
- mp_clear(&scratch[i]);
- }
- for (i = 0; i < 16; i++) {
- mp_clear(&precomp[i][0]);
- mp_clear(&precomp[i][1]);
- }
- mp_clear(&tpx);
- mp_clear(&tpy);
- mp_clear(&rz);
- mp_clear(&raz4);
- free(naf);
- return res;
-}
diff --git a/security/nss/lib/freebl/ecl/ecp_mont.c b/security/nss/lib/freebl/ecl/ecp_mont.c
deleted file mode 100644
index 6b8462e9e..000000000
--- a/security/nss/lib/freebl/ecl/ecp_mont.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Uses Montgomery reduction for field arithmetic. See mpi/mpmontg.c for
- * code implementation. */
-
-#include "mpi.h"
-#include "mplogic.h"
-#include "mpi-priv.h"
-#include "ecl-priv.h"
-#include "ecp.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-/* Construct a generic GFMethod for arithmetic over prime fields with
- * irreducible irr. */
-GFMethod *
-GFMethod_consGFp_mont(const mp_int *irr)
-{
- mp_err res = MP_OKAY;
- GFMethod *meth = NULL;
- mp_mont_modulus *mmm;
-
- meth = GFMethod_consGFp(irr);
- if (meth == NULL)
- return NULL;
-
- mmm = (mp_mont_modulus *) malloc(sizeof(mp_mont_modulus));
- if (mmm == NULL) {
- res = MP_MEM;
- goto CLEANUP;
- }
-
- meth->field_mul = &ec_GFp_mul_mont;
- meth->field_sqr = &ec_GFp_sqr_mont;
- meth->field_div = &ec_GFp_div_mont;
- meth->field_enc = &ec_GFp_enc_mont;
- meth->field_dec = &ec_GFp_dec_mont;
- meth->extra1 = mmm;
- meth->extra2 = NULL;
- meth->extra_free = &ec_GFp_extra_free_mont;
-
- mmm->N = meth->irr;
- mmm->n0prime = 0 - s_mp_invmod_radix(MP_DIGIT(&meth->irr, 0));
-
- CLEANUP:
- if (res != MP_OKAY) {
- GFMethod_free(meth);
- return NULL;
- }
- return meth;
-}
-
-/* Wrapper functions for generic prime field arithmetic. */
-
-/* Field multiplication using Montgomery reduction. */
-mp_err
-ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
-#ifdef MP_MONT_USE_MP_MUL
- /* if MP_MONT_USE_MP_MUL is defined, then the function s_mp_mul_mont
- * is not implemented and we have to use mp_mul and s_mp_redc directly
- */
- MP_CHECKOK(mp_mul(a, b, r));
- MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
-#else
- mp_int s;
-
- MP_DIGITS(&s) = 0;
- /* s_mp_mul_mont doesn't allow source and destination to be the same */
- if ((a == r) || (b == r)) {
- MP_CHECKOK(mp_init(&s));
- MP_CHECKOK(s_mp_mul_mont
- (a, b, &s, (mp_mont_modulus *) meth->extra1));
- MP_CHECKOK(mp_copy(&s, r));
- mp_clear(&s);
- } else {
- return s_mp_mul_mont(a, b, r, (mp_mont_modulus *) meth->extra1);
- }
-#endif
- CLEANUP:
- return res;
-}
-
-/* Field squaring using Montgomery reduction. */
-mp_err
-ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- return ec_GFp_mul_mont(a, a, r, meth);
-}
-
-/* Field division using Montgomery reduction. */
-mp_err
-ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
- const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- /* if A=aZ represents a encoded in montgomery coordinates with Z and #
- * and \ respectively represent multiplication and division in
- * montgomery coordinates, then A\B = (a/b)Z = (A/B)Z and Binv =
- * (1/b)Z = (1/B)(Z^2) where B # Binv = Z */
- MP_CHECKOK(ec_GFp_div(a, b, r, meth));
- MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
- if (a == NULL) {
- MP_CHECKOK(ec_GFp_enc_mont(r, r, meth));
- }
- CLEANUP:
- return res;
-}
-
-/* Encode a field element in Montgomery form. See s_mp_to_mont in
- * mpi/mpmontg.c */
-mp_err
-ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_mont_modulus *mmm;
- mp_err res = MP_OKAY;
-
- mmm = (mp_mont_modulus *) meth->extra1;
- MP_CHECKOK(mp_copy(a, r));
- MP_CHECKOK(s_mp_lshd(r, MP_USED(&mmm->N)));
- MP_CHECKOK(mp_mod(r, &mmm->N, r));
- CLEANUP:
- return res;
-}
-
-/* Decode a field element from Montgomery form. */
-mp_err
-ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
-{
- mp_err res = MP_OKAY;
-
- if (a != r) {
- MP_CHECKOK(mp_copy(a, r));
- }
- MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
- CLEANUP:
- return res;
-}
-
-/* Free the memory allocated to the extra fields of Montgomery GFMethod
- * object. */
-void
-ec_GFp_extra_free_mont(GFMethod *meth)
-{
- if (meth->extra1 != NULL) {
- free(meth->extra1);
- meth->extra1 = NULL;
- }
-}
diff --git a/security/nss/lib/freebl/ecl/tests/ec2_test.c b/security/nss/lib/freebl/ecl/tests/ec2_test.c
deleted file mode 100644
index 1b4d8c3d5..000000000
--- a/security/nss/lib/freebl/ecl/tests/ec2_test.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi.h"
-#include "mplogic.h"
-#include "mpprime.h"
-#include "mp_gf2m.h"
-#include "ecl.h"
-#include "ecl-curve.h"
-#include "ec2.h"
-#include <stdio.h>
-#include <strings.h>
-#include <assert.h>
-
-#include <time.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-/* Time k repetitions of operation op. */
-#define M_TimeOperation(op, k) { \
- double dStart, dNow, dUserTime; \
- struct rusage ru; \
- int i; \
- getrusage(RUSAGE_SELF, &ru); \
- dStart = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
- for (i = 0; i < k; i++) { \
- { op; } \
- }; \
- getrusage(RUSAGE_SELF, &ru); \
- dNow = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
- dUserTime = dNow-dStart; \
- if (dUserTime) printf(" %-45s k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \
-}
-
-/* Test curve using generic field arithmetic. */
-#define ECTEST_GENERIC_GF2M(name_c, name) \
- printf("Testing %s using generic implementation...\n", name_c); \
- params = EC_GetNamedCurveParams(name); \
- if (params == NULL) { \
- printf(" Error: could not construct params.\n"); \
- res = MP_NO; \
- goto CLEANUP; \
- } \
- ECGroup_free(group); \
- group = ECGroup_fromHex(params); \
- if (group == NULL) { \
- printf(" Error: could not construct group.\n"); \
- res = MP_NO; \
- goto CLEANUP; \
- } \
- MP_CHECKOK( ectest_curve_GF2m(group, ectestPrint, ectestTime, 1) ); \
- printf("... okay.\n");
-
-/* Test curve using specific field arithmetic. */
-#define ECTEST_NAMED_GF2M(name_c, name) \
- printf("Testing %s using specific implementation...\n", name_c); \
- ECGroup_free(group); \
- group = ECGroup_fromName(name); \
- if (group == NULL) { \
- printf(" Warning: could not construct group.\n"); \
- printf("... failed; continuing with remaining tests.\n"); \
- } else { \
- MP_CHECKOK( ectest_curve_GF2m(group, ectestPrint, ectestTime, 0) ); \
- printf("... okay.\n"); \
- }
-
-/* Performs basic tests of elliptic curve cryptography over binary
- * polynomial fields. If tests fail, then it prints an error message,
- * aborts, and returns an error code. Otherwise, returns 0. */
-int
-ectest_curve_GF2m(ECGroup *group, int ectestPrint, int ectestTime,
- int generic)
-{
-
- mp_int one, order_1, gx, gy, rx, ry, n;
- int size;
- mp_err res;
- char s[1000];
-
- /* initialize values */
- MP_CHECKOK(mp_init(&one));
- MP_CHECKOK(mp_init(&order_1));
- MP_CHECKOK(mp_init(&gx));
- MP_CHECKOK(mp_init(&gy));
- MP_CHECKOK(mp_init(&rx));
- MP_CHECKOK(mp_init(&ry));
- MP_CHECKOK(mp_init(&n));
-
- MP_CHECKOK(mp_set_int(&one, 1));
- MP_CHECKOK(mp_sub(&group->order, &one, &order_1));
-
- /* encode base point */
- if (group->meth->field_dec) {
- MP_CHECKOK(group->meth->field_dec(&group->genx, &gx, group->meth));
- MP_CHECKOK(group->meth->field_dec(&group->geny, &gy, group->meth));
- } else {
- MP_CHECKOK(mp_copy(&group->genx, &gx));
- MP_CHECKOK(mp_copy(&group->geny, &gy));
- }
-
- if (ectestPrint) {
- /* output base point */
- printf(" base point P:\n");
- MP_CHECKOK(mp_toradix(&gx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&gy, s, 16));
- printf(" %s\n", s);
- if (group->meth->field_enc) {
- printf(" base point P (encoded):\n");
- MP_CHECKOK(mp_toradix(&group->genx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&group->geny, s, 16));
- printf(" %s\n", s);
- }
- }
-
-#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
- /* multiply base point by order - 1 and check for negative of base
- * point */
- MP_CHECKOK(ec_GF2m_pt_mul_aff
- (&order_1, &group->genx, &group->geny, &rx, &ry, group));
- if (ectestPrint) {
- printf(" (order-1)*P (affine):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(group->meth->field_add(&ry, &rx, &ry, group->meth));
- if ((mp_cmp(&rx, &group->genx) != 0)
- || (mp_cmp(&ry, &group->geny) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-#endif
-
- /* multiply base point by order - 1 and check for negative of base
- * point */
- MP_CHECKOK(ec_GF2m_pt_mul_mont
- (&order_1, &group->genx, &group->geny, &rx, &ry, group));
- if (ectestPrint) {
- printf(" (order-1)*P (montgomery):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(group->meth->field_add(&ry, &rx, &ry, group->meth));
- if ((mp_cmp(&rx, &group->genx) != 0)
- || (mp_cmp(&ry, &group->geny) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
-#ifdef ECL_ENABLE_GF2M_PROJ
- /* multiply base point by order - 1 and check for negative of base
- * point */
- MP_CHECKOK(ec_GF2m_pt_mul_proj
- (&order_1, &group->genx, &group->geny, &rx, &ry, group));
- if (ectestPrint) {
- printf(" (order-1)*P (projective):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(group->meth->field_add(&ry, &rx, &ry, group->meth));
- if ((mp_cmp(&rx, &group->genx) != 0)
- || (mp_cmp(&ry, &group->geny) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-#endif
-
- /* multiply base point by order - 1 and check for negative of base
- * point */
- MP_CHECKOK(ECPoint_mul(group, &order_1, NULL, NULL, &rx, &ry));
- if (ectestPrint) {
- printf(" (order-1)*P (ECPoint_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(ec_GF2m_add(&ry, &rx, &ry, group->meth));
- if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* multiply base point by order - 1 and check for negative of base
- * point */
- MP_CHECKOK(ECPoint_mul(group, &order_1, &gx, &gy, &rx, &ry));
- if (ectestPrint) {
- printf(" (order-1)*P (ECPoint_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(ec_GF2m_add(&ry, &rx, &ry, group->meth));
- if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
-#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
- /* multiply base point by order and check for point at infinity */
- MP_CHECKOK(ec_GF2m_pt_mul_aff
- (&group->order, &group->genx, &group->geny, &rx, &ry,
- group));
- if (ectestPrint) {
- printf(" (order)*P (affine):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf(" Error: invalid result (expected point at infinity).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-#endif
-
- /* multiply base point by order and check for point at infinity */
- MP_CHECKOK(ec_GF2m_pt_mul_mont
- (&group->order, &group->genx, &group->geny, &rx, &ry,
- group));
- if (ectestPrint) {
- printf(" (order)*P (montgomery):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf(" Error: invalid result (expected point at infinity).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
-#ifdef ECL_ENABLE_GF2M_PROJ
- /* multiply base point by order and check for point at infinity */
- MP_CHECKOK(ec_GF2m_pt_mul_proj
- (&group->order, &group->genx, &group->geny, &rx, &ry,
- group));
- if (ectestPrint) {
- printf(" (order)*P (projective):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf(" Error: invalid result (expected point at infinity).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-#endif
-
- /* multiply base point by order and check for point at infinity */
- MP_CHECKOK(ECPoint_mul(group, &group->order, NULL, NULL, &rx, &ry));
- if (ectestPrint) {
- printf(" (order)*P (ECPoint_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf(" Error: invalid result (expected point at infinity).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* multiply base point by order and check for point at infinity */
- MP_CHECKOK(ECPoint_mul(group, &group->order, &gx, &gy, &rx, &ry));
- if (ectestPrint) {
- printf(" (order)*P (ECPoint_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- if (ec_GF2m_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf(" Error: invalid result (expected point at infinity).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* check that (order-1)P + (order-1)P + P == (order-1)P */
- MP_CHECKOK(ECPoints_mul
- (group, &order_1, &order_1, &gx, &gy, &rx, &ry));
- MP_CHECKOK(ECPoints_mul(group, &one, &one, &rx, &ry, &rx, &ry));
- if (ectestPrint) {
- printf
- (" (order-1)*P + (order-1)*P + P == (order-1)*P (ECPoints_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(ec_GF2m_add(&ry, &rx, &ry, group->meth));
- if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* test validate_point function */
- if (ECPoint_validate(group, &gx, &gy) != MP_YES) {
- printf(" Error: validate point on base point failed.\n");
- res = MP_NO;
- goto CLEANUP;
- }
- MP_CHECKOK(mp_add_d(&gy, 1, &ry));
- if (ECPoint_validate(group, &gx, &ry) != MP_NO) {
- printf(" Error: validate point on invalid point passed.\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- if (ectestTime) {
- /* compute random scalar */
- size = mpl_significant_bits(&group->meth->irr);
- if (size < MP_OKAY) {
- goto CLEANUP;
- }
- MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS));
- MP_CHECKOK(group->meth->field_mod(&n, &n, group->meth));
- /* timed test */
- if (generic) {
-#ifdef ECL_ENABLE_GF2M_PT_MUL_AFF
- M_TimeOperation(MP_CHECKOK
- (ec_GF2m_pt_mul_aff
- (&n, &group->genx, &group->geny, &rx, &ry,
- group)), 100);
-#endif
- M_TimeOperation(MP_CHECKOK
- (ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)),
- 100);
- M_TimeOperation(MP_CHECKOK
- (ECPoints_mul
- (group, &n, &n, &gx, &gy, &rx, &ry)), 100);
- } else {
- M_TimeOperation(MP_CHECKOK
- (ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)),
- 100);
- M_TimeOperation(MP_CHECKOK
- (ECPoint_mul(group, &n, &gx, &gy, &rx, &ry)),
- 100);
- M_TimeOperation(MP_CHECKOK
- (ECPoints_mul
- (group, &n, &n, &gx, &gy, &rx, &ry)), 100);
- }
- }
-
- CLEANUP:
- mp_clear(&one);
- mp_clear(&order_1);
- mp_clear(&gx);
- mp_clear(&gy);
- mp_clear(&rx);
- mp_clear(&ry);
- mp_clear(&n);
- if (res != MP_OKAY) {
- printf(" Error: exiting with error value %i\n", res);
- }
- return res;
-}
-
-/* Prints help information. */
-void
-printUsage()
-{
- printf("Usage: ecp_test [--print] [--time]\n");
- printf
- (" --print Print out results of each point arithmetic test.\n");
- printf
- (" --time Benchmark point operations and print results.\n");
-}
-
-/* Performs tests of elliptic curve cryptography over binary polynomial
- * fields. If tests fail, then it prints an error message, aborts, and
- * returns an error code. Otherwise, returns 0. */
-int
-main(int argv, char **argc)
-{
-
- int ectestTime = 0;
- int ectestPrint = 0;
- int i;
- ECGroup *group = NULL;
- ECCurveParams *params = NULL;
- mp_err res;
-
- /* read command-line arguments */
- for (i = 1; i < argv; i++) {
- if ((strcasecmp(argc[i], "time") == 0)
- || (strcasecmp(argc[i], "-time") == 0)
- || (strcasecmp(argc[i], "--time") == 0)) {
- ectestTime = 1;
- } else if ((strcasecmp(argc[i], "print") == 0)
- || (strcasecmp(argc[i], "-print") == 0)
- || (strcasecmp(argc[i], "--print") == 0)) {
- ectestPrint = 1;
- } else {
- printUsage();
- return 0;
- }
- }
-
- /* generic arithmetic tests */
- ECTEST_GENERIC_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1);
-
- /* specific arithmetic tests */
- ECTEST_NAMED_GF2M("NIST-K163", ECCurve_NIST_K163);
- ECTEST_NAMED_GF2M("NIST-B163", ECCurve_NIST_B163);
- ECTEST_NAMED_GF2M("NIST-K233", ECCurve_NIST_K233);
- ECTEST_NAMED_GF2M("NIST-B233", ECCurve_NIST_B233);
- ECTEST_NAMED_GF2M("NIST-K283", ECCurve_NIST_K283);
- ECTEST_NAMED_GF2M("NIST-B283", ECCurve_NIST_B283);
- ECTEST_NAMED_GF2M("NIST-K409", ECCurve_NIST_K409);
- ECTEST_NAMED_GF2M("NIST-B409", ECCurve_NIST_B409);
- ECTEST_NAMED_GF2M("NIST-K571", ECCurve_NIST_K571);
- ECTEST_NAMED_GF2M("NIST-B571", ECCurve_NIST_B571);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V1", ECCurve_X9_62_CHAR2_PNB163V1);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V2", ECCurve_X9_62_CHAR2_PNB163V2);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V3", ECCurve_X9_62_CHAR2_PNB163V3);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB176V1", ECCurve_X9_62_CHAR2_PNB176V1);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V1", ECCurve_X9_62_CHAR2_TNB191V1);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V2", ECCurve_X9_62_CHAR2_TNB191V2);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V3", ECCurve_X9_62_CHAR2_TNB191V3);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB208W1", ECCurve_X9_62_CHAR2_PNB208W1);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V1", ECCurve_X9_62_CHAR2_TNB239V1);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V2", ECCurve_X9_62_CHAR2_TNB239V2);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V3", ECCurve_X9_62_CHAR2_TNB239V3);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB272W1", ECCurve_X9_62_CHAR2_PNB272W1);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB304W1", ECCurve_X9_62_CHAR2_PNB304W1);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB359V1", ECCurve_X9_62_CHAR2_TNB359V1);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB368W1", ECCurve_X9_62_CHAR2_PNB368W1);
- ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB431R1", ECCurve_X9_62_CHAR2_TNB431R1);
- ECTEST_NAMED_GF2M("SECT-113R1", ECCurve_SECG_CHAR2_113R1);
- ECTEST_NAMED_GF2M("SECT-113R2", ECCurve_SECG_CHAR2_113R2);
- ECTEST_NAMED_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1);
- ECTEST_NAMED_GF2M("SECT-131R2", ECCurve_SECG_CHAR2_131R2);
- ECTEST_NAMED_GF2M("SECT-163K1", ECCurve_SECG_CHAR2_163K1);
- ECTEST_NAMED_GF2M("SECT-163R1", ECCurve_SECG_CHAR2_163R1);
- ECTEST_NAMED_GF2M("SECT-163R2", ECCurve_SECG_CHAR2_163R2);
- ECTEST_NAMED_GF2M("SECT-193R1", ECCurve_SECG_CHAR2_193R1);
- ECTEST_NAMED_GF2M("SECT-193R2", ECCurve_SECG_CHAR2_193R2);
- ECTEST_NAMED_GF2M("SECT-233K1", ECCurve_SECG_CHAR2_233K1);
- ECTEST_NAMED_GF2M("SECT-233R1", ECCurve_SECG_CHAR2_233R1);
- ECTEST_NAMED_GF2M("SECT-239K1", ECCurve_SECG_CHAR2_239K1);
- ECTEST_NAMED_GF2M("SECT-283K1", ECCurve_SECG_CHAR2_283K1);
- ECTEST_NAMED_GF2M("SECT-283R1", ECCurve_SECG_CHAR2_283R1);
- ECTEST_NAMED_GF2M("SECT-409K1", ECCurve_SECG_CHAR2_409K1);
- ECTEST_NAMED_GF2M("SECT-409R1", ECCurve_SECG_CHAR2_409R1);
- ECTEST_NAMED_GF2M("SECT-571K1", ECCurve_SECG_CHAR2_571K1);
- ECTEST_NAMED_GF2M("SECT-571R1", ECCurve_SECG_CHAR2_571R1);
- ECTEST_NAMED_GF2M("WTLS-1 (113)", ECCurve_WTLS_1);
- ECTEST_NAMED_GF2M("WTLS-3 (163)", ECCurve_WTLS_3);
- ECTEST_NAMED_GF2M("WTLS-4 (113)", ECCurve_WTLS_4);
- ECTEST_NAMED_GF2M("WTLS-5 (163)", ECCurve_WTLS_5);
- ECTEST_NAMED_GF2M("WTLS-10 (233)", ECCurve_WTLS_10);
- ECTEST_NAMED_GF2M("WTLS-11 (233)", ECCurve_WTLS_11);
-
- CLEANUP:
- EC_FreeCurveParams(params);
- ECGroup_free(group);
- if (res != MP_OKAY) {
- printf("Error: exiting with error value %i\n", res);
- }
- return res;
-}
diff --git a/security/nss/lib/freebl/ecl/tests/ec_naft.c b/security/nss/lib/freebl/ecl/tests/ec_naft.c
deleted file mode 100644
index 833daeaca..000000000
--- a/security/nss/lib/freebl/ecl/tests/ec_naft.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi.h"
-#include "mplogic.h"
-#include "ecl.h"
-#include "ecp.h"
-#include "ecl-priv.h"
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-/* Returns 2^e as an integer. This is meant to be used for small powers of
- * two. */
-int ec_twoTo(int e);
-
-/* Number of bits of scalar to test */
-#define BITSIZE 160
-
-/* Time k repetitions of operation op. */
-#define M_TimeOperation(op, k) { \
- double dStart, dNow, dUserTime; \
- struct rusage ru; \
- int i; \
- getrusage(RUSAGE_SELF, &ru); \
- dStart = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
- for (i = 0; i < k; i++) { \
- { op; } \
- }; \
- getrusage(RUSAGE_SELF, &ru); \
- dNow = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
- dUserTime = dNow-dStart; \
- if (dUserTime) printf(" %-45s\n k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \
-}
-
-/* Tests wNAF computation. Non-adjacent-form is discussed in the paper: D.
- * Hankerson, J. Hernandez and A. Menezes, "Software implementation of
- * elliptic curve cryptography over binary fields", Proc. CHES 2000. */
-
-mp_err
-main(void)
-{
- signed char naf[BITSIZE + 1];
- ECGroup *group = NULL;
- mp_int k;
- mp_int *scalar;
- int i, count;
- int res;
- int w = 5;
- char s[1000];
-
- /* Get a 160 bit scalar to compute wNAF from */
- group = ECGroup_fromName(ECCurve_SECG_PRIME_160R1);
- scalar = &group->genx;
-
- /* Compute wNAF representation of scalar */
- ec_compute_wNAF(naf, BITSIZE, scalar, w);
-
- /* Verify correctness of representation */
- mp_init(&k); /* init k to 0 */
-
- for (i = BITSIZE; i >= 0; i--) {
- mp_add(&k, &k, &k);
- /* digits in mp_???_d are unsigned */
- if (naf[i] >= 0) {
- mp_add_d(&k, naf[i], &k);
- } else {
- mp_sub_d(&k, -naf[i], &k);
- }
- }
-
- if (mp_cmp(&k, scalar) != 0) {
- printf("Error: incorrect NAF value.\n");
- MP_CHECKOK(mp_toradix(&k, s, 16));
- printf("NAF value %s\n", s);
- MP_CHECKOK(mp_toradix(scalar, s, 16));
- printf("original value %s\n", s);
- goto CLEANUP;
- }
-
- /* Verify digits of representation are valid */
- for (i = 0; i <= BITSIZE; i++) {
- if (naf[i] % 2 == 0 && naf[i] != 0) {
- printf("Error: Even non-zero digit found.\n");
- goto CLEANUP;
- }
- if (naf[i] < -(ec_twoTo(w - 1)) || naf[i] >= ec_twoTo(w - 1)) {
- printf("Error: Magnitude of naf digit too large.\n");
- goto CLEANUP;
- }
- }
-
- /* Verify sparsity of representation */
- count = w - 1;
- for (i = 0; i <= BITSIZE; i++) {
- if (naf[i] != 0) {
- if (count < w - 1) {
- printf("Error: Sparsity failed.\n");
- goto CLEANUP;
- }
- count = 0;
- } else
- count++;
- }
-
- /* Check timing */
- M_TimeOperation(ec_compute_wNAF(naf, BITSIZE, scalar, w), 10000);
-
- printf("Test passed.\n");
- CLEANUP:
- ECGroup_free(group);
- return MP_OKAY;
-}
diff --git a/security/nss/lib/freebl/ecl/tests/ecp_fpt.c b/security/nss/lib/freebl/ecl/tests/ecp_fpt.c
deleted file mode 100644
index 3c9179665..000000000
--- a/security/nss/lib/freebl/ecl/tests/ecp_fpt.c
+++ /dev/null
@@ -1,1088 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ecp_fp.h"
-#include "mpprime.h"
-
-#include <stdio.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-/* Time k repetitions of operation op. */
-#define M_TimeOperation(op, k) { \
- double dStart, dNow, dUserTime; \
- struct rusage ru; \
- int i; \
- getrusage(RUSAGE_SELF, &ru); \
- dStart = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
- for (i = 0; i < k; i++) { \
- { op; } \
- }; \
- getrusage(RUSAGE_SELF, &ru); \
- dNow = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
- dUserTime = dNow-dStart; \
- if (dUserTime) printf(" %-45s\n k: %6i, t: %6.2f sec, k/t: %6.2f ops/sec\n", #op, k, dUserTime, k/dUserTime); \
-}
-
-/* Test curve using specific floating point field arithmetic. */
-#define M_TestCurve(name_c, name) { \
- printf("Testing %s using specific floating point implementation...\n", name_c); \
- ECGroup_free(ecgroup); \
- ecgroup = ECGroup_fromName(name); \
- if (ecgroup == NULL) { \
- printf(" Warning: could not construct group.\n"); \
- printf("%s failed.\n", name_c); \
- res = MP_NO; \
- goto CLEANUP; \
- } else { \
- MP_CHECKOK( testCurve(ecgroup)); \
- printf("%s passed.\n", name_c); \
- } \
-}
-
-/* Outputs a floating point double (currently not used) */
-void
-d_output(const double *u, int len, char *name, const EC_group_fp * group)
-{
- int i;
-
- printf("%s: ", name);
- for (i = 0; i < len; i++) {
- printf("+ %.2f * 2^%i ", u[i] / ecfp_exp[i],
- group->doubleBitSize * i);
- }
- printf("\n");
-}
-
-/* Tests a point p in Jacobian coordinates, comparing against the
- * expected affine result (x, y). */
-mp_err
-testJacPoint(ecfp_jac_pt * p, mp_int *x, mp_int *y, ECGroup *ecgroup)
-{
- char s[1000];
- mp_int rx, ry, rz;
- mp_err res = MP_OKAY;
-
- MP_DIGITS(&rx) = 0;
- MP_DIGITS(&ry) = 0;
- MP_DIGITS(&rz) = 0;
-
- MP_CHECKOK(mp_init(&rx));
- MP_CHECKOK(mp_init(&ry));
- MP_CHECKOK(mp_init(&rz));
-
- ecfp_fp2i(&rx, p->x, ecgroup);
- ecfp_fp2i(&ry, p->y, ecgroup);
- ecfp_fp2i(&rz, p->z, ecgroup);
-
- /* convert result R to affine coordinates */
- ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup);
-
- /* Compare to expected result */
- if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) {
- printf(" Error: Jacobian Floating Point Incorrect.\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf("floating point result\nrx %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf("ry %s\n", s);
- MP_CHECKOK(mp_toradix(x, s, 16));
- printf("integer result\nx %s\n", s);
- MP_CHECKOK(mp_toradix(y, s, 16));
- printf("y %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
-
- CLEANUP:
- mp_clear(&rx);
- mp_clear(&ry);
- mp_clear(&rz);
-
- return res;
-}
-
-/* Tests a point p in Chudnovsky Jacobian coordinates, comparing against
- * the expected affine result (x, y). */
-mp_err
-testChudPoint(ecfp_chud_pt * p, mp_int *x, mp_int *y, ECGroup *ecgroup)
-{
-
- char s[1000];
- mp_int rx, ry, rz, rz2, rz3, test;
- mp_err res = MP_OKAY;
-
- /* Initialization */
- MP_DIGITS(&rx) = 0;
- MP_DIGITS(&ry) = 0;
- MP_DIGITS(&rz) = 0;
- MP_DIGITS(&rz2) = 0;
- MP_DIGITS(&rz3) = 0;
- MP_DIGITS(&test) = 0;
-
- MP_CHECKOK(mp_init(&rx));
- MP_CHECKOK(mp_init(&ry));
- MP_CHECKOK(mp_init(&rz));
- MP_CHECKOK(mp_init(&rz2));
- MP_CHECKOK(mp_init(&rz3));
- MP_CHECKOK(mp_init(&test));
-
- /* Convert to integers */
- ecfp_fp2i(&rx, p->x, ecgroup);
- ecfp_fp2i(&ry, p->y, ecgroup);
- ecfp_fp2i(&rz, p->z, ecgroup);
- ecfp_fp2i(&rz2, p->z2, ecgroup);
- ecfp_fp2i(&rz3, p->z3, ecgroup);
-
- /* Verify z2, z3 are valid */
- mp_sqrmod(&rz, &ecgroup->meth->irr, &test);
- if (mp_cmp(&test, &rz2) != 0) {
- printf(" Error: rzp2 not valid\n");
- res = MP_NO;
- goto CLEANUP;
- }
- mp_mulmod(&test, &rz, &ecgroup->meth->irr, &test);
- if (mp_cmp(&test, &rz3) != 0) {
- printf(" Error: rzp2 not valid\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* convert result R to affine coordinates */
- ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup);
-
- /* Compare against expected result */
- if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) {
- printf(" Error: Chudnovsky Floating Point Incorrect.\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf("floating point result\nrx %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf("ry %s\n", s);
- MP_CHECKOK(mp_toradix(x, s, 16));
- printf("integer result\nx %s\n", s);
- MP_CHECKOK(mp_toradix(y, s, 16));
- printf("y %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
-
- CLEANUP:
- mp_clear(&rx);
- mp_clear(&ry);
- mp_clear(&rz);
- mp_clear(&rz2);
- mp_clear(&rz3);
- mp_clear(&test);
-
- return res;
-}
-
-/* Tests a point p in Modified Jacobian coordinates, comparing against the
- * expected affine result (x, y). */
-mp_err
-testJmPoint(ecfp_jm_pt * r, mp_int *x, mp_int *y, ECGroup *ecgroup)
-{
-
- char s[1000];
- mp_int rx, ry, rz, raz4, test;
- mp_err res = MP_OKAY;
-
- /* Initialization */
- MP_DIGITS(&rx) = 0;
- MP_DIGITS(&ry) = 0;
- MP_DIGITS(&rz) = 0;
- MP_DIGITS(&raz4) = 0;
- MP_DIGITS(&test) = 0;
-
- MP_CHECKOK(mp_init(&rx));
- MP_CHECKOK(mp_init(&ry));
- MP_CHECKOK(mp_init(&rz));
- MP_CHECKOK(mp_init(&raz4));
- MP_CHECKOK(mp_init(&test));
-
- /* Convert to integer */
- ecfp_fp2i(&rx, r->x, ecgroup);
- ecfp_fp2i(&ry, r->y, ecgroup);
- ecfp_fp2i(&rz, r->z, ecgroup);
- ecfp_fp2i(&raz4, r->az4, ecgroup);
-
- /* Verify raz4 = rz^4 * a */
- mp_sqrmod(&rz, &ecgroup->meth->irr, &test);
- mp_sqrmod(&test, &ecgroup->meth->irr, &test);
- mp_mulmod(&test, &ecgroup->curvea, &ecgroup->meth->irr, &test);
- if (mp_cmp(&test, &raz4) != 0) {
- printf(" Error: a*z^4 not valid\n");
- MP_CHECKOK(mp_toradix(&ecgroup->curvea, s, 16));
- printf("a %s\n", s);
- MP_CHECKOK(mp_toradix(&rz, s, 16));
- printf("rz %s\n", s);
- MP_CHECKOK(mp_toradix(&raz4, s, 16));
- printf("raz4 %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* convert result R to affine coordinates */
- ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup);
-
- /* Compare against expected result */
- if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) {
- printf(" Error: Modified Jacobian Floating Point Incorrect.\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf("floating point result\nrx %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf("ry %s\n", s);
- MP_CHECKOK(mp_toradix(x, s, 16));
- printf("integer result\nx %s\n", s);
- MP_CHECKOK(mp_toradix(y, s, 16));
- printf("y %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
- CLEANUP:
- mp_clear(&rx);
- mp_clear(&ry);
- mp_clear(&rz);
- mp_clear(&raz4);
- mp_clear(&test);
-
- return res;
-}
-
-/* Tests point addition of Jacobian + Affine -> Jacobian */
-mp_err
-testPointAddJacAff(ECGroup *ecgroup)
-{
- mp_err res;
- mp_int pz, rx2, ry2, rz2;
- ecfp_jac_pt p, r;
- ecfp_aff_pt q;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
- /* Init */
- MP_DIGITS(&pz) = 0;
- MP_DIGITS(&rx2) = 0;
- MP_DIGITS(&ry2) = 0;
- MP_DIGITS(&rz2) = 0;
- MP_CHECKOK(mp_init(&pz));
- MP_CHECKOK(mp_init(&rx2));
- MP_CHECKOK(mp_init(&ry2));
- MP_CHECKOK(mp_init(&rz2));
-
- MP_CHECKOK(mp_set_int(&pz, 5));
-
- /* Set p */
- ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
- ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
- ecfp_i2fp(p.z, &pz, ecgroup);
- /* Set q */
- ecfp_i2fp(q.x, &ecgroup->geny, ecgroup);
- ecfp_i2fp(q.y, &ecgroup->genx, ecgroup);
-
- /* Do calculations */
- group->pt_add_jac_aff(&p, &q, &r, group);
-
- /* Do calculation in integer to compare against */
- MP_CHECKOK(ec_GFp_pt_add_jac_aff
- (&ecgroup->genx, &ecgroup->geny, &pz, &ecgroup->geny,
- &ecgroup->genx, &rx2, &ry2, &rz2, ecgroup));
- /* convert result R to affine coordinates */
- ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
-
- MP_CHECKOK(testJacPoint(&r, &rx2, &ry2, ecgroup));
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Point Addition - Jacobian & Affine\n");
- else
- printf("TEST FAILED - Point Addition - Jacobian & Affine\n");
-
- mp_clear(&pz);
- mp_clear(&rx2);
- mp_clear(&ry2);
- mp_clear(&rz2);
-
- return res;
-}
-
-/* Tests point addition in Jacobian coordinates */
-mp_err
-testPointAddJac(ECGroup *ecgroup)
-{
- mp_err res;
- mp_int pz, qz, qx, qy, rx2, ry2, rz2;
- ecfp_jac_pt p, q, r;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
- /* Init */
- MP_DIGITS(&pz) = 0;
- MP_DIGITS(&qx) = 0;
- MP_DIGITS(&qy) = 0;
- MP_DIGITS(&qz) = 0;
- MP_DIGITS(&rx2) = 0;
- MP_DIGITS(&ry2) = 0;
- MP_DIGITS(&rz2) = 0;
- MP_CHECKOK(mp_init(&pz));
- MP_CHECKOK(mp_init(&qx));
- MP_CHECKOK(mp_init(&qy));
- MP_CHECKOK(mp_init(&qz));
- MP_CHECKOK(mp_init(&rx2));
- MP_CHECKOK(mp_init(&ry2));
- MP_CHECKOK(mp_init(&rz2));
-
- MP_CHECKOK(mp_set_int(&pz, 5));
- MP_CHECKOK(mp_set_int(&qz, 105));
-
- /* Set p */
- ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
- ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
- ecfp_i2fp(p.z, &pz, ecgroup);
- /* Set q */
- ecfp_i2fp(q.x, &ecgroup->geny, ecgroup);
- ecfp_i2fp(q.y, &ecgroup->genx, ecgroup);
- ecfp_i2fp(q.z, &qz, ecgroup);
-
- /* Do calculations */
- group->pt_add_jac(&p, &q, &r, group);
-
- /* Do calculation in integer to compare against */
- ec_GFp_pt_jac2aff(&ecgroup->geny, &ecgroup->genx, &qz, &qx, &qy,
- ecgroup);
- MP_CHECKOK(ec_GFp_pt_add_jac_aff
- (&ecgroup->genx, &ecgroup->geny, &pz, &qx, &qy, &rx2, &ry2,
- &rz2, ecgroup));
- /* convert result R to affine coordinates */
- ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
-
- MP_CHECKOK(testJacPoint(&r, &rx2, &ry2, ecgroup));
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Point Addition - Jacobian\n");
- else
- printf("TEST FAILED - Point Addition - Jacobian\n");
-
- mp_clear(&pz);
- mp_clear(&qx);
- mp_clear(&qy);
- mp_clear(&qz);
- mp_clear(&rx2);
- mp_clear(&ry2);
- mp_clear(&rz2);
-
- return res;
-}
-
-/* Tests point addition in Chudnovsky Jacobian Coordinates */
-mp_err
-testPointAddChud(ECGroup *ecgroup)
-{
- mp_err res;
- mp_int rx2, ry2, ix, iy, iz, test, pz, qx, qy, qz;
- ecfp_chud_pt p, q, r;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
- MP_DIGITS(&qx) = 0;
- MP_DIGITS(&qy) = 0;
- MP_DIGITS(&qz) = 0;
- MP_DIGITS(&pz) = 0;
- MP_DIGITS(&rx2) = 0;
- MP_DIGITS(&ry2) = 0;
- MP_DIGITS(&ix) = 0;
- MP_DIGITS(&iy) = 0;
- MP_DIGITS(&iz) = 0;
- MP_DIGITS(&test) = 0;
-
- MP_CHECKOK(mp_init(&qx));
- MP_CHECKOK(mp_init(&qy));
- MP_CHECKOK(mp_init(&qz));
- MP_CHECKOK(mp_init(&pz));
- MP_CHECKOK(mp_init(&rx2));
- MP_CHECKOK(mp_init(&ry2));
- MP_CHECKOK(mp_init(&ix));
- MP_CHECKOK(mp_init(&iy));
- MP_CHECKOK(mp_init(&iz));
- MP_CHECKOK(mp_init(&test));
-
- /* Test Chudnovsky form addition */
- /* Set p */
- MP_CHECKOK(mp_set_int(&pz, 5));
- ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
- ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
- ecfp_i2fp(p.z, &pz, ecgroup);
- mp_sqrmod(&pz, &ecgroup->meth->irr, &test);
- ecfp_i2fp(p.z2, &test, ecgroup);
- mp_mulmod(&test, &pz, &ecgroup->meth->irr, &test);
- ecfp_i2fp(p.z3, &test, ecgroup);
-
- /* Set q */
- MP_CHECKOK(mp_set_int(&qz, 105));
- ecfp_i2fp(q.x, &ecgroup->geny, ecgroup);
- ecfp_i2fp(q.y, &ecgroup->genx, ecgroup);
- ecfp_i2fp(q.z, &qz, ecgroup);
- mp_sqrmod(&qz, &ecgroup->meth->irr, &test);
- ecfp_i2fp(q.z2, &test, ecgroup);
- mp_mulmod(&test, &qz, &ecgroup->meth->irr, &test);
- ecfp_i2fp(q.z3, &test, ecgroup);
-
- group->pt_add_chud(&p, &q, &r, group);
-
- /* Calculate addition to compare against */
- ec_GFp_pt_jac2aff(&ecgroup->geny, &ecgroup->genx, &qz, &qx, &qy,
- ecgroup);
- ec_GFp_pt_add_jac_aff(&ecgroup->genx, &ecgroup->geny, &pz, &qx, &qy,
- &ix, &iy, &iz, ecgroup);
- ec_GFp_pt_jac2aff(&ix, &iy, &iz, &rx2, &ry2, ecgroup);
-
- MP_CHECKOK(testChudPoint(&r, &rx2, &ry2, ecgroup));
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Point Addition - Chudnovsky Jacobian\n");
- else
- printf("TEST FAILED - Point Addition - Chudnovsky Jacobian\n");
-
- mp_clear(&qx);
- mp_clear(&qy);
- mp_clear(&qz);
- mp_clear(&pz);
- mp_clear(&rx2);
- mp_clear(&ry2);
- mp_clear(&ix);
- mp_clear(&iy);
- mp_clear(&iz);
- mp_clear(&test);
-
- return res;
-}
-
-/* Tests point addition in Modified Jacobian + Chudnovsky Jacobian ->
- * Modified Jacobian coordinates. */
-mp_err
-testPointAddJmChud(ECGroup *ecgroup)
-{
- mp_err res;
- mp_int rx2, ry2, ix, iy, iz, test, pz, paz4, qx, qy, qz;
- ecfp_chud_pt q;
- ecfp_jm_pt p, r;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
- MP_DIGITS(&qx) = 0;
- MP_DIGITS(&qy) = 0;
- MP_DIGITS(&qz) = 0;
- MP_DIGITS(&pz) = 0;
- MP_DIGITS(&paz4) = 0;
- MP_DIGITS(&iz) = 0;
- MP_DIGITS(&rx2) = 0;
- MP_DIGITS(&ry2) = 0;
- MP_DIGITS(&ix) = 0;
- MP_DIGITS(&iy) = 0;
- MP_DIGITS(&iz) = 0;
- MP_DIGITS(&test) = 0;
-
- MP_CHECKOK(mp_init(&qx));
- MP_CHECKOK(mp_init(&qy));
- MP_CHECKOK(mp_init(&qz));
- MP_CHECKOK(mp_init(&pz));
- MP_CHECKOK(mp_init(&paz4));
- MP_CHECKOK(mp_init(&rx2));
- MP_CHECKOK(mp_init(&ry2));
- MP_CHECKOK(mp_init(&ix));
- MP_CHECKOK(mp_init(&iy));
- MP_CHECKOK(mp_init(&iz));
- MP_CHECKOK(mp_init(&test));
-
- /* Test Modified Jacobian form addition */
- /* Set p */
- ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
- ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
- ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
- /* paz4 = az^4 */
- MP_CHECKOK(mp_set_int(&pz, 5));
- mp_sqrmod(&pz, &ecgroup->meth->irr, &paz4);
- mp_sqrmod(&paz4, &ecgroup->meth->irr, &paz4);
- mp_mulmod(&paz4, &ecgroup->curvea, &ecgroup->meth->irr, &paz4);
- ecfp_i2fp(p.z, &pz, ecgroup);
- ecfp_i2fp(p.az4, &paz4, ecgroup);
-
- /* Set q */
- MP_CHECKOK(mp_set_int(&qz, 105));
- ecfp_i2fp(q.x, &ecgroup->geny, ecgroup);
- ecfp_i2fp(q.y, &ecgroup->genx, ecgroup);
- ecfp_i2fp(q.z, &qz, ecgroup);
- mp_sqrmod(&qz, &ecgroup->meth->irr, &test);
- ecfp_i2fp(q.z2, &test, ecgroup);
- mp_mulmod(&test, &qz, &ecgroup->meth->irr, &test);
- ecfp_i2fp(q.z3, &test, ecgroup);
-
- /* Do calculation */
- group->pt_add_jm_chud(&p, &q, &r, group);
-
- /* Calculate addition to compare against */
- ec_GFp_pt_jac2aff(&ecgroup->geny, &ecgroup->genx, &qz, &qx, &qy,
- ecgroup);
- ec_GFp_pt_add_jac_aff(&ecgroup->genx, &ecgroup->geny, &pz, &qx, &qy,
- &ix, &iy, &iz, ecgroup);
- ec_GFp_pt_jac2aff(&ix, &iy, &iz, &rx2, &ry2, ecgroup);
-
- MP_CHECKOK(testJmPoint(&r, &rx2, &ry2, ecgroup));
-
- CLEANUP:
- if (res == MP_OKAY)
- printf
- (" Test Passed - Point Addition - Modified & Chudnovsky Jacobian\n");
- else
- printf
- ("TEST FAILED - Point Addition - Modified & Chudnovsky Jacobian\n");
-
- mp_clear(&qx);
- mp_clear(&qy);
- mp_clear(&qz);
- mp_clear(&pz);
- mp_clear(&paz4);
- mp_clear(&rx2);
- mp_clear(&ry2);
- mp_clear(&ix);
- mp_clear(&iy);
- mp_clear(&iz);
- mp_clear(&test);
-
- return res;
-}
-
-/* Tests point doubling in Modified Jacobian coordinates */
-mp_err
-testPointDoubleJm(ECGroup *ecgroup)
-{
- mp_err res;
- mp_int pz, paz4, rx2, ry2, rz2, raz4;
- ecfp_jm_pt p, r;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
- MP_DIGITS(&pz) = 0;
- MP_DIGITS(&paz4) = 0;
- MP_DIGITS(&rx2) = 0;
- MP_DIGITS(&ry2) = 0;
- MP_DIGITS(&rz2) = 0;
- MP_DIGITS(&raz4) = 0;
-
- MP_CHECKOK(mp_init(&pz));
- MP_CHECKOK(mp_init(&paz4));
- MP_CHECKOK(mp_init(&rx2));
- MP_CHECKOK(mp_init(&ry2));
- MP_CHECKOK(mp_init(&rz2));
- MP_CHECKOK(mp_init(&raz4));
-
- /* Set p */
- ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
- ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
- ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
-
- /* paz4 = az^4 */
- MP_CHECKOK(mp_set_int(&pz, 5));
- mp_sqrmod(&pz, &ecgroup->meth->irr, &paz4);
- mp_sqrmod(&paz4, &ecgroup->meth->irr, &paz4);
- mp_mulmod(&paz4, &ecgroup->curvea, &ecgroup->meth->irr, &paz4);
-
- ecfp_i2fp(p.z, &pz, ecgroup);
- ecfp_i2fp(p.az4, &paz4, ecgroup);
-
- group->pt_dbl_jm(&p, &r, group);
-
- M_TimeOperation(group->pt_dbl_jm(&p, &r, group), 100000);
-
- /* Calculate doubling to compare against */
- ec_GFp_pt_dbl_jac(&ecgroup->genx, &ecgroup->geny, &pz, &rx2, &ry2,
- &rz2, ecgroup);
- ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
-
- /* Do comparison and check az^4 */
- MP_CHECKOK(testJmPoint(&r, &rx2, &ry2, ecgroup));
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Point Doubling - Modified Jacobian\n");
- else
- printf("TEST FAILED - Point Doubling - Modified Jacobian\n");
- mp_clear(&pz);
- mp_clear(&paz4);
- mp_clear(&rx2);
- mp_clear(&ry2);
- mp_clear(&rz2);
- mp_clear(&raz4);
-
- return res;
-
-}
-
-/* Tests point doubling in Chudnovsky Jacobian coordinates */
-mp_err
-testPointDoubleChud(ECGroup *ecgroup)
-{
- mp_err res;
- mp_int px, py, pz, rx2, ry2, rz2;
- ecfp_aff_pt p;
- ecfp_chud_pt p2;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
- MP_DIGITS(&rx2) = 0;
- MP_DIGITS(&ry2) = 0;
- MP_DIGITS(&rz2) = 0;
- MP_DIGITS(&px) = 0;
- MP_DIGITS(&py) = 0;
- MP_DIGITS(&pz) = 0;
-
- MP_CHECKOK(mp_init(&rx2));
- MP_CHECKOK(mp_init(&ry2));
- MP_CHECKOK(mp_init(&rz2));
- MP_CHECKOK(mp_init(&px));
- MP_CHECKOK(mp_init(&py));
- MP_CHECKOK(mp_init(&pz));
-
- /* Set p2 = 2P */
- ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
- ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
- ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
-
- group->pt_dbl_aff2chud(&p, &p2, group);
-
- /* Calculate doubling to compare against */
- MP_CHECKOK(mp_set_int(&pz, 1));
- ec_GFp_pt_dbl_jac(&ecgroup->genx, &ecgroup->geny, &pz, &rx2, &ry2,
- &rz2, ecgroup);
- ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
-
- /* Do comparison and check az^4 */
- MP_CHECKOK(testChudPoint(&p2, &rx2, &ry2, ecgroup));
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Point Doubling - Chudnovsky Jacobian\n");
- else
- printf("TEST FAILED - Point Doubling - Chudnovsky Jacobian\n");
-
- mp_clear(&rx2);
- mp_clear(&ry2);
- mp_clear(&rz2);
- mp_clear(&px);
- mp_clear(&py);
- mp_clear(&pz);
-
- return res;
-}
-
-/* Test point doubling in Jacobian coordinates */
-mp_err
-testPointDoubleJac(ECGroup *ecgroup)
-{
- mp_err res;
- mp_int pz, rx, ry, rz, rx2, ry2, rz2;
- ecfp_jac_pt p, p2;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
- MP_DIGITS(&pz) = 0;
- MP_DIGITS(&rx) = 0;
- MP_DIGITS(&ry) = 0;
- MP_DIGITS(&rz) = 0;
- MP_DIGITS(&rx2) = 0;
- MP_DIGITS(&ry2) = 0;
- MP_DIGITS(&rz2) = 0;
-
- MP_CHECKOK(mp_init(&pz));
- MP_CHECKOK(mp_init(&rx));
- MP_CHECKOK(mp_init(&ry));
- MP_CHECKOK(mp_init(&rz));
- MP_CHECKOK(mp_init(&rx2));
- MP_CHECKOK(mp_init(&ry2));
- MP_CHECKOK(mp_init(&rz2));
-
- MP_CHECKOK(mp_set_int(&pz, 5));
-
- /* Set p2 = 2P */
- ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
- ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
- ecfp_i2fp(p.z, &pz, ecgroup);
- ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);
-
- group->pt_dbl_jac(&p, &p2, group);
- M_TimeOperation(group->pt_dbl_jac(&p, &p2, group), 100000);
-
- /* Calculate doubling to compare against */
- ec_GFp_pt_dbl_jac(&ecgroup->genx, &ecgroup->geny, &pz, &rx2, &ry2,
- &rz2, ecgroup);
- ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);
-
- /* Do comparison */
- MP_CHECKOK(testJacPoint(&p2, &rx2, &ry2, ecgroup));
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Point Doubling - Jacobian\n");
- else
- printf("TEST FAILED - Point Doubling - Jacobian\n");
-
- mp_clear(&pz);
- mp_clear(&rx);
- mp_clear(&ry);
- mp_clear(&rz);
- mp_clear(&rx2);
- mp_clear(&ry2);
- mp_clear(&rz2);
-
- return res;
-}
-
-/* Tests a point multiplication (various algorithms) */
-mp_err
-testPointMul(ECGroup *ecgroup)
-{
- mp_err res;
- char s[1000];
- mp_int rx, ry, order_1;
-
- /* Init */
- MP_DIGITS(&rx) = 0;
- MP_DIGITS(&ry) = 0;
- MP_DIGITS(&order_1) = 0;
-
- MP_CHECKOK(mp_init(&rx));
- MP_CHECKOK(mp_init(&ry));
- MP_CHECKOK(mp_init(&order_1));
-
- MP_CHECKOK(mp_set_int(&order_1, 1));
- MP_CHECKOK(mp_sub(&ecgroup->order, &order_1, &order_1));
-
- /* Test Algorithm 1: Jacobian-Affine Double & Add */
- ec_GFp_pt_mul_jac_fp(&order_1, &ecgroup->genx, &ecgroup->geny, &rx,
- &ry, ecgroup);
- MP_CHECKOK(ecgroup->meth->field_neg(&ry, &ry, ecgroup->meth));
- if ((mp_cmp(&rx, &ecgroup->genx) != 0)
- || (mp_cmp(&ry, &ecgroup->geny) != 0)) {
- printf
- (" Error: ec_GFp_pt_mul_jac_fp invalid result (expected (- base point)).\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf("rx %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf("ry %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
-
- ec_GFp_pt_mul_jac_fp(&ecgroup->order, &ecgroup->genx, &ecgroup->geny,
- &rx, &ry, ecgroup);
- if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf
- (" Error: ec_GFp_pt_mul_jac_fp invalid result (expected point at infinity.\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf("rx %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf("ry %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* Test Algorithm 2: 4-bit Window in Jacobian */
- ec_GFp_point_mul_jac_4w_fp(&order_1, &ecgroup->genx, &ecgroup->geny,
- &rx, &ry, ecgroup);
- MP_CHECKOK(ecgroup->meth->field_neg(&ry, &ry, ecgroup->meth));
- if ((mp_cmp(&rx, &ecgroup->genx) != 0)
- || (mp_cmp(&ry, &ecgroup->geny) != 0)) {
- printf
- (" Error: ec_GFp_point_mul_jac_4w_fp invalid result (expected (- base point)).\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf("rx %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf("ry %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
-
- ec_GFp_point_mul_jac_4w_fp(&ecgroup->order, &ecgroup->genx,
- &ecgroup->geny, &rx, &ry, ecgroup);
- if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf
- (" Error: ec_GFp_point_mul_jac_4w_fp invalid result (expected point at infinity.\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf("rx %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf("ry %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* Test Algorithm 3: wNAF with modified Jacobian coordinates */
- ec_GFp_point_mul_wNAF_fp(&order_1, &ecgroup->genx, &ecgroup->geny, &rx,
- &ry, ecgroup);
- MP_CHECKOK(ecgroup->meth->field_neg(&ry, &ry, ecgroup->meth));
- if ((mp_cmp(&rx, &ecgroup->genx) != 0)
- || (mp_cmp(&ry, &ecgroup->geny) != 0)) {
- printf
- (" Error: ec_GFp_pt_mul_wNAF_fp invalid result (expected (- base point)).\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf("rx %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf("ry %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
-
- ec_GFp_point_mul_wNAF_fp(&ecgroup->order, &ecgroup->genx,
- &ecgroup->geny, &rx, &ry, ecgroup);
- if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf
- (" Error: ec_GFp_pt_mul_wNAF_fp invalid result (expected point at infinity.\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf("rx %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf("ry %s\n", s);
- res = MP_NO;
- goto CLEANUP;
- }
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Point Multiplication\n");
- else
- printf("TEST FAILED - Point Multiplication\n");
- mp_clear(&rx);
- mp_clear(&ry);
- mp_clear(&order_1);
-
- return res;
-}
-
-/* Tests point multiplication with a random scalar repeatedly, comparing
- * for consistency within different algorithms. */
-mp_err
-testPointMulRandom(ECGroup *ecgroup)
-{
- mp_err res;
- mp_int rx, ry, rx2, ry2, n;
- int i, size;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
-
- MP_DIGITS(&rx) = 0;
- MP_DIGITS(&ry) = 0;
- MP_DIGITS(&rx2) = 0;
- MP_DIGITS(&ry2) = 0;
- MP_DIGITS(&n) = 0;
-
- MP_CHECKOK(mp_init(&rx));
- MP_CHECKOK(mp_init(&ry));
- MP_CHECKOK(mp_init(&rx2));
- MP_CHECKOK(mp_init(&ry2));
- MP_CHECKOK(mp_init(&n));
-
- for (i = 0; i < 100; i++) {
- /* compute random scalar */
- size = mpl_significant_bits(&ecgroup->meth->irr);
- if (size < MP_OKAY) {
- res = MP_NO;
- goto CLEANUP;
- }
- MP_CHECKOK(mpp_random_size(&n, group->orderBitSize));
- MP_CHECKOK(mp_mod(&n, &ecgroup->order, &n));
-
- ec_GFp_pt_mul_jac(&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
- ecgroup);
- ec_GFp_pt_mul_jac_fp(&n, &ecgroup->genx, &ecgroup->geny, &rx2,
- &ry2, ecgroup);
-
- if ((mp_cmp(&rx, &rx2) != 0) || (mp_cmp(&ry, &ry2) != 0)) {
- printf
- (" Error: different results for Point Multiplication - Double & Add.\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- ec_GFp_point_mul_wNAF_fp(&n, &ecgroup->genx, &ecgroup->geny, &rx,
- &ry, ecgroup);
- if ((mp_cmp(&rx, &rx2) != 0) || (mp_cmp(&ry, &ry2) != 0)) {
- printf
- (" Error: different results for Point Multiplication - wNAF.\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- ec_GFp_point_mul_jac_4w_fp(&n, &ecgroup->genx, &ecgroup->geny, &rx,
- &ry, ecgroup);
- if ((mp_cmp(&rx, &rx2) != 0) || (mp_cmp(&ry, &ry2) != 0)) {
- printf
- (" Error: different results for Point Multiplication - 4 bit window.\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- }
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Point Random Multiplication\n");
- else
- printf("TEST FAILED - Point Random Multiplication\n");
- mp_clear(&rx);
- mp_clear(&ry);
- mp_clear(&rx2);
- mp_clear(&ry2);
- mp_clear(&n);
-
- return res;
-}
-
-/* Tests the time required for a point multiplication */
-mp_err
-testPointMulTime(ECGroup *ecgroup)
-{
- mp_err res = MP_OKAY;
- mp_int rx, ry, n;
- int size;
-
- MP_DIGITS(&rx) = 0;
- MP_DIGITS(&ry) = 0;
- MP_DIGITS(&n) = 0;
-
- MP_CHECKOK(mp_init(&rx));
- MP_CHECKOK(mp_init(&ry));
- MP_CHECKOK(mp_init(&n));
-
- /* compute random scalar */
- size = mpl_significant_bits(&ecgroup->meth->irr);
- if (size < MP_OKAY) {
- res = MP_NO;
- goto CLEANUP;
- }
-
- MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS));
- MP_CHECKOK(ecgroup->meth->field_mod(&n, &n, ecgroup->meth));
-
- M_TimeOperation(ec_GFp_pt_mul_jac_fp
- (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
- ecgroup), 1000);
-
- M_TimeOperation(ec_GFp_point_mul_jac_4w_fp
- (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
- ecgroup), 1000);
-
- M_TimeOperation(ec_GFp_point_mul_wNAF_fp
- (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
- ecgroup), 1000);
-
- M_TimeOperation(ec_GFp_pt_mul_jac
- (&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
- ecgroup), 100);
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Point Multiplication Timing\n");
- else
- printf("TEST FAILED - Point Multiplication Timing\n");
- mp_clear(&rx);
- mp_clear(&ry);
- mp_clear(&n);
-
- return res;
-}
-
-/* Tests pre computation of Chudnovsky Jacobian points used in wNAF form */
-mp_err
-testPreCompute(ECGroup *ecgroup)
-{
- ecfp_chud_pt precomp[16];
- ecfp_aff_pt p;
- EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
- int i;
- mp_err res;
-
- mp_int x, y, ny, x2, y2;
-
- MP_DIGITS(&x) = 0;
- MP_DIGITS(&y) = 0;
- MP_DIGITS(&ny) = 0;
- MP_DIGITS(&x2) = 0;
- MP_DIGITS(&y2) = 0;
-
- MP_CHECKOK(mp_init(&x));
- MP_CHECKOK(mp_init(&y));
- MP_CHECKOK(mp_init(&ny));
- MP_CHECKOK(mp_init(&x2));
- MP_CHECKOK(mp_init(&y2));
-
- ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
- ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
- ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);
-
- /* Perform precomputation */
- group->precompute_chud(precomp, &p, group);
-
- M_TimeOperation(group->precompute_chud(precomp, &p, group), 10000);
-
- /* Calculate addition to compare against */
- MP_CHECKOK(mp_copy(&ecgroup->genx, &x));
- MP_CHECKOK(mp_copy(&ecgroup->geny, &y));
- MP_CHECKOK(ecgroup->meth->field_neg(&y, &ny, ecgroup->meth));
-
- ec_GFp_pt_dbl_aff(&x, &y, &x2, &y2, ecgroup);
-
- for (i = 0; i < 8; i++) {
- MP_CHECKOK(testChudPoint(&precomp[8 + i], &x, &y, ecgroup));
- MP_CHECKOK(testChudPoint(&precomp[7 - i], &x, &ny, ecgroup));
- ec_GFp_pt_add_aff(&x, &y, &x2, &y2, &x, &y, ecgroup);
- MP_CHECKOK(ecgroup->meth->field_neg(&y, &ny, ecgroup->meth));
- }
-
- CLEANUP:
- if (res == MP_OKAY)
- printf(" Test Passed - Precomputation\n");
- else
- printf("TEST FAILED - Precomputation\n");
-
- mp_clear(&x);
- mp_clear(&y);
- mp_clear(&ny);
- mp_clear(&x2);
- mp_clear(&y2);
- return res;
-}
-
-/* Given a curve using floating point arithmetic, test it. This method
- * specifies which of the above tests to run. */
-mp_err
-testCurve(ECGroup *ecgroup)
-{
- int res = MP_OKAY;
-
- MP_CHECKOK(testPointAddJacAff(ecgroup));
- MP_CHECKOK(testPointAddJac(ecgroup));
- MP_CHECKOK(testPointAddChud(ecgroup));
- MP_CHECKOK(testPointAddJmChud(ecgroup));
- MP_CHECKOK(testPointDoubleJac(ecgroup));
- MP_CHECKOK(testPointDoubleChud(ecgroup));
- MP_CHECKOK(testPointDoubleJm(ecgroup));
- MP_CHECKOK(testPreCompute(ecgroup));
- MP_CHECKOK(testPointMul(ecgroup));
- MP_CHECKOK(testPointMulRandom(ecgroup));
- MP_CHECKOK(testPointMulTime(ecgroup));
- CLEANUP:
- return res;
-}
-
-/* Tests a number of curves optimized using floating point arithmetic */
-int
-main(void)
-{
- mp_err res = MP_OKAY;
- ECGroup *ecgroup = NULL;
-
- /* specific arithmetic tests */
- M_TestCurve("SECG-160R1", ECCurve_SECG_PRIME_160R1);
- M_TestCurve("SECG-192R1", ECCurve_SECG_PRIME_192R1);
- M_TestCurve("SEGC-224R1", ECCurve_SECG_PRIME_224R1);
-
- CLEANUP:
- ECGroup_free(ecgroup);
- if (res != MP_OKAY) {
- printf("Error: exiting with error value %i\n", res);
- }
- return res;
-}
diff --git a/security/nss/lib/freebl/ecl/tests/ecp_test.c b/security/nss/lib/freebl/ecl/tests/ecp_test.c
deleted file mode 100644
index e9a448e00..000000000
--- a/security/nss/lib/freebl/ecl/tests/ecp_test.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi.h"
-#include "mplogic.h"
-#include "mpprime.h"
-#include "ecl.h"
-#include "ecl-curve.h"
-#include "ecp.h"
-#include <stdio.h>
-#include <strings.h>
-#include <assert.h>
-
-#include <time.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-/* Time k repetitions of operation op. */
-#define M_TimeOperation(op, k) { \
- double dStart, dNow, dUserTime; \
- struct rusage ru; \
- int i; \
- getrusage(RUSAGE_SELF, &ru); \
- dStart = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
- for (i = 0; i < k; i++) { \
- { op; } \
- }; \
- getrusage(RUSAGE_SELF, &ru); \
- dNow = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
- dUserTime = dNow-dStart; \
- if (dUserTime) printf(" %-45s k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \
-}
-
-/* Test curve using generic field arithmetic. */
-#define ECTEST_GENERIC_GFP(name_c, name) \
- printf("Testing %s using generic implementation...\n", name_c); \
- params = EC_GetNamedCurveParams(name); \
- if (params == NULL) { \
- printf(" Error: could not construct params.\n"); \
- res = MP_NO; \
- goto CLEANUP; \
- } \
- ECGroup_free(group); \
- group = ECGroup_fromHex(params); \
- if (group == NULL) { \
- printf(" Error: could not construct group.\n"); \
- res = MP_NO; \
- goto CLEANUP; \
- } \
- MP_CHECKOK( ectest_curve_GFp(group, ectestPrint, ectestTime, 1) ); \
- printf("... okay.\n");
-
-/* Test curve using specific field arithmetic. */
-#define ECTEST_NAMED_GFP(name_c, name) \
- printf("Testing %s using specific implementation...\n", name_c); \
- ECGroup_free(group); \
- group = ECGroup_fromName(name); \
- if (group == NULL) { \
- printf(" Warning: could not construct group.\n"); \
- printf("... failed; continuing with remaining tests.\n"); \
- } else { \
- MP_CHECKOK( ectest_curve_GFp(group, ectestPrint, ectestTime, 0) ); \
- printf("... okay.\n"); \
- }
-
-/* Performs basic tests of elliptic curve cryptography over prime fields.
- * If tests fail, then it prints an error message, aborts, and returns an
- * error code. Otherwise, returns 0. */
-int
-ectest_curve_GFp(ECGroup *group, int ectestPrint, int ectestTime,
- int generic)
-{
-
- mp_int one, order_1, gx, gy, rx, ry, n;
- int size;
- mp_err res;
- char s[1000];
-
- /* initialize values */
- MP_CHECKOK(mp_init(&one));
- MP_CHECKOK(mp_init(&order_1));
- MP_CHECKOK(mp_init(&gx));
- MP_CHECKOK(mp_init(&gy));
- MP_CHECKOK(mp_init(&rx));
- MP_CHECKOK(mp_init(&ry));
- MP_CHECKOK(mp_init(&n));
-
- MP_CHECKOK(mp_set_int(&one, 1));
- MP_CHECKOK(mp_sub(&group->order, &one, &order_1));
-
- /* encode base point */
- if (group->meth->field_dec) {
- MP_CHECKOK(group->meth->field_dec(&group->genx, &gx, group->meth));
- MP_CHECKOK(group->meth->field_dec(&group->geny, &gy, group->meth));
- } else {
- MP_CHECKOK(mp_copy(&group->genx, &gx));
- MP_CHECKOK(mp_copy(&group->geny, &gy));
- }
- if (ectestPrint) {
- /* output base point */
- printf(" base point P:\n");
- MP_CHECKOK(mp_toradix(&gx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&gy, s, 16));
- printf(" %s\n", s);
- if (group->meth->field_enc) {
- printf(" base point P (encoded):\n");
- MP_CHECKOK(mp_toradix(&group->genx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&group->geny, s, 16));
- printf(" %s\n", s);
- }
- }
-
-#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
- /* multiply base point by order - 1 and check for negative of base
- * point */
- MP_CHECKOK(ec_GFp_pt_mul_aff
- (&order_1, &group->genx, &group->geny, &rx, &ry, group));
- if (ectestPrint) {
- printf(" (order-1)*P (affine):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(group->meth->field_neg(&ry, &ry, group->meth));
- if ((mp_cmp(&rx, &group->genx) != 0)
- || (mp_cmp(&ry, &group->geny) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-#endif
-
-#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
- /* multiply base point by order - 1 and check for negative of base
- * point */
- MP_CHECKOK(ec_GFp_pt_mul_jac
- (&order_1, &group->genx, &group->geny, &rx, &ry, group));
- if (ectestPrint) {
- printf(" (order-1)*P (jacobian):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(group->meth->field_neg(&ry, &ry, group->meth));
- if ((mp_cmp(&rx, &group->genx) != 0)
- || (mp_cmp(&ry, &group->geny) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-#endif
-
- /* multiply base point by order - 1 and check for negative of base
- * point */
- MP_CHECKOK(ECPoint_mul(group, &order_1, NULL, NULL, &rx, &ry));
- if (ectestPrint) {
- printf(" (order-1)*P (ECPoint_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry));
- if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* multiply base point by order - 1 and check for negative of base
- * point */
- MP_CHECKOK(ECPoint_mul(group, &order_1, &gx, &gy, &rx, &ry));
- if (ectestPrint) {
- printf(" (order-1)*P (ECPoint_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry));
- if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
-#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
- /* multiply base point by order and check for point at infinity */
- MP_CHECKOK(ec_GFp_pt_mul_aff
- (&group->order, &group->genx, &group->geny, &rx, &ry,
- group));
- if (ectestPrint) {
- printf(" (order)*P (affine):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf(" Error: invalid result (expected point at infinity).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-#endif
-
-#ifdef ECL_ENABLE_GFP_PT_MUL_JAC
- /* multiply base point by order and check for point at infinity */
- MP_CHECKOK(ec_GFp_pt_mul_jac
- (&group->order, &group->genx, &group->geny, &rx, &ry,
- group));
- if (ectestPrint) {
- printf(" (order)*P (jacobian):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf(" Error: invalid result (expected point at infinity).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-#endif
-
- /* multiply base point by order and check for point at infinity */
- MP_CHECKOK(ECPoint_mul(group, &group->order, NULL, NULL, &rx, &ry));
- if (ectestPrint) {
- printf(" (order)*P (ECPoint_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf(" Error: invalid result (expected point at infinity).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* multiply base point by order and check for point at infinity */
- MP_CHECKOK(ECPoint_mul(group, &group->order, &gx, &gy, &rx, &ry));
- if (ectestPrint) {
- printf(" (order)*P (ECPoint_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) {
- printf(" Error: invalid result (expected point at infinity).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* check that (order-1)P + (order-1)P + P == (order-1)P */
- MP_CHECKOK(ECPoints_mul
- (group, &order_1, &order_1, &gx, &gy, &rx, &ry));
- MP_CHECKOK(ECPoints_mul(group, &one, &one, &rx, &ry, &rx, &ry));
- if (ectestPrint) {
- printf
- (" (order-1)*P + (order-1)*P + P == (order-1)*P (ECPoints_mul):\n");
- MP_CHECKOK(mp_toradix(&rx, s, 16));
- printf(" %s\n", s);
- MP_CHECKOK(mp_toradix(&ry, s, 16));
- printf(" %s\n", s);
- }
- MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry));
- if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) {
- printf(" Error: invalid result (expected (- base point)).\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- /* test validate_point function */
- if (ECPoint_validate(group, &gx, &gy) != MP_YES) {
- printf(" Error: validate point on base point failed.\n");
- res = MP_NO;
- goto CLEANUP;
- }
- MP_CHECKOK(mp_add_d(&gy, 1, &ry));
- if (ECPoint_validate(group, &gx, &ry) != MP_NO) {
- printf(" Error: validate point on invalid point passed.\n");
- res = MP_NO;
- goto CLEANUP;
- }
-
- if (ectestTime) {
- /* compute random scalar */
- size = mpl_significant_bits(&group->meth->irr);
- if (size < MP_OKAY) {
- goto CLEANUP;
- }
- MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS));
- MP_CHECKOK(group->meth->field_mod(&n, &n, group->meth));
- /* timed test */
- if (generic) {
-#ifdef ECL_ENABLE_GFP_PT_MUL_AFF
- M_TimeOperation(MP_CHECKOK
- (ec_GFp_pt_mul_aff
- (&n, &group->genx, &group->geny, &rx, &ry,
- group)), 100);
-#endif
- M_TimeOperation(MP_CHECKOK
- (ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)),
- 100);
- M_TimeOperation(MP_CHECKOK
- (ECPoints_mul
- (group, &n, &n, &gx, &gy, &rx, &ry)), 100);
- } else {
- M_TimeOperation(MP_CHECKOK
- (ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)),
- 100);
- M_TimeOperation(MP_CHECKOK
- (ECPoint_mul(group, &n, &gx, &gy, &rx, &ry)),
- 100);
- M_TimeOperation(MP_CHECKOK
- (ECPoints_mul
- (group, &n, &n, &gx, &gy, &rx, &ry)), 100);
- }
- }
-
- CLEANUP:
- mp_clear(&one);
- mp_clear(&order_1);
- mp_clear(&gx);
- mp_clear(&gy);
- mp_clear(&rx);
- mp_clear(&ry);
- mp_clear(&n);
- if (res != MP_OKAY) {
- printf(" Error: exiting with error value %i\n", res);
- }
- return res;
-}
-
-/* Prints help information. */
-void
-printUsage()
-{
- printf("Usage: ecp_test [--print] [--time]\n");
- printf
- (" --print Print out results of each point arithmetic test.\n");
- printf
- (" --time Benchmark point operations and print results.\n");
-}
-
-/* Performs tests of elliptic curve cryptography over prime fields If
- * tests fail, then it prints an error message, aborts, and returns an
- * error code. Otherwise, returns 0. */
-int
-main(int argv, char **argc)
-{
-
- int ectestTime = 0;
- int ectestPrint = 0;
- int i;
- ECGroup *group = NULL;
- ECCurveParams *params = NULL;
- mp_err res;
-
- /* read command-line arguments */
- for (i = 1; i < argv; i++) {
- if ((strcasecmp(argc[i], "time") == 0)
- || (strcasecmp(argc[i], "-time") == 0)
- || (strcasecmp(argc[i], "--time") == 0)) {
- ectestTime = 1;
- } else if ((strcasecmp(argc[i], "print") == 0)
- || (strcasecmp(argc[i], "-print") == 0)
- || (strcasecmp(argc[i], "--print") == 0)) {
- ectestPrint = 1;
- } else {
- printUsage();
- return 0;
- }
- }
-
- /* generic arithmetic tests */
- ECTEST_GENERIC_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1);
-
- /* specific arithmetic tests */
- ECTEST_NAMED_GFP("NIST-P192", ECCurve_NIST_P192);
- ECTEST_NAMED_GFP("NIST-P224", ECCurve_NIST_P224);
- ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256);
- ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384);
- ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521);
- ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v1", ECCurve_X9_62_PRIME_192V1);
- ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v2", ECCurve_X9_62_PRIME_192V2);
- ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v3", ECCurve_X9_62_PRIME_192V3);
- ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v1", ECCurve_X9_62_PRIME_239V1);
- ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v2", ECCurve_X9_62_PRIME_239V2);
- ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v3", ECCurve_X9_62_PRIME_239V3);
- ECTEST_NAMED_GFP("ANSI X9.62 PRIME256v1", ECCurve_X9_62_PRIME_256V1);
- ECTEST_NAMED_GFP("SECP-112R1", ECCurve_SECG_PRIME_112R1);
- ECTEST_NAMED_GFP("SECP-112R2", ECCurve_SECG_PRIME_112R2);
- ECTEST_NAMED_GFP("SECP-128R1", ECCurve_SECG_PRIME_128R1);
- ECTEST_NAMED_GFP("SECP-128R2", ECCurve_SECG_PRIME_128R2);
- ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1);
- ECTEST_NAMED_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1);
- ECTEST_NAMED_GFP("SECP-160R2", ECCurve_SECG_PRIME_160R2);
- ECTEST_NAMED_GFP("SECP-192K1", ECCurve_SECG_PRIME_192K1);
- ECTEST_NAMED_GFP("SECP-192R1", ECCurve_SECG_PRIME_192R1);
- ECTEST_NAMED_GFP("SECP-224K1", ECCurve_SECG_PRIME_224K1);
- ECTEST_NAMED_GFP("SECP-224R1", ECCurve_SECG_PRIME_224R1);
- ECTEST_NAMED_GFP("SECP-256K1", ECCurve_SECG_PRIME_256K1);
- ECTEST_NAMED_GFP("SECP-256R1", ECCurve_SECG_PRIME_256R1);
- ECTEST_NAMED_GFP("SECP-384R1", ECCurve_SECG_PRIME_384R1);
- ECTEST_NAMED_GFP("SECP-521R1", ECCurve_SECG_PRIME_521R1);
- ECTEST_NAMED_GFP("WTLS-6 (112)", ECCurve_WTLS_6);
- ECTEST_NAMED_GFP("WTLS-7 (160)", ECCurve_WTLS_7);
- ECTEST_NAMED_GFP("WTLS-8 (112)", ECCurve_WTLS_8);
- ECTEST_NAMED_GFP("WTLS-9 (160)", ECCurve_WTLS_9);
- ECTEST_NAMED_GFP("WTLS-12 (224)", ECCurve_WTLS_12);
-
- CLEANUP:
- EC_FreeCurveParams(params);
- ECGroup_free(group);
- if (res != MP_OKAY) {
- printf("Error: exiting with error value %i\n", res);
- }
- return res;
-}
diff --git a/security/nss/lib/freebl/freebl.def b/security/nss/lib/freebl/freebl.def
deleted file mode 100644
index 164c843fd..000000000
--- a/security/nss/lib/freebl/freebl.def
+++ /dev/null
@@ -1,26 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+
-;+NSSprivate_3.11 { # NSS 3.11 release
-;+ global:
-LIBRARY freebl3 ;-
-EXPORTS ;-
-FREEBL_GetVector;
-;+ local:
-;+ *;
-;+};
diff --git a/security/nss/lib/freebl/freebl.rc b/security/nss/lib/freebl/freebl.rc
deleted file mode 100644
index 444ae5d03..000000000
--- a/security/nss/lib/freebl/freebl.rc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "softkver.h"
-#include <winver.h>
-
-#define MY_LIBNAME "freebl"
-#define MY_FILEDESCRIPTION "NSS freebl Library"
-
-#define STRINGIZE(x) #x
-#define STRINGIZE2(x) STRINGIZE(x)
-#define SOFTOKEN_VMAJOR_STR STRINGIZE2(SOFTOKEN_VMAJOR)
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if SOFTOKEN_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME SOFTOKEN_VMAJOR_STR
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,SOFTOKEN_VBUILD
- PRODUCTVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,SOFTOKEN_VBUILD
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Mozilla Foundation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", SOFTOKEN_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", SOFTOKEN_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/freebl/freebl_hash.def b/security/nss/lib/freebl/freebl_hash.def
deleted file mode 100644
index 9fd27367e..000000000
--- a/security/nss/lib/freebl/freebl_hash.def
+++ /dev/null
@@ -1,39 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+
-;+NSSprivate_3.11 { # NSS 3.11 release
-;+ global:
-LIBRARY freebl3 ;-
-EXPORTS ;-
-FREEBL_GetVector;
-;+ local:
-;+ *;
-;+};
-;+NSSRAWHASH_3.12.3 { # NSS 3.12.3 release
-;+ global:
-NSSLOW_Init;
-NSSLOW_Shutdown;
-NSSLOWHASH_Length;
-NSSLOWHASH_Begin;
-NSSLOWHASH_Destroy;
-NSSLOWHASH_End;
-NSSLOWHASH_NewContext;
-NSSLOWHASH_Update;
-;+ local:
-;+ *;
-;+};
diff --git a/security/nss/lib/freebl/freeblver.c b/security/nss/lib/freebl/freeblver.c
deleted file mode 100644
index c288b41ad..000000000
--- a/security/nss/lib/freebl/freeblver.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Library identity and versioning */
-
-#include "softkver.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_freebl_rcsid[] = "$Header: NSS " SOFTOKEN_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_freebl_sccsid[] = "@(#)NSS " SOFTOKEN_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/freebl/gcm.c b/security/nss/lib/freebl/gcm.c
deleted file mode 100644
index 638cd2281..000000000
--- a/security/nss/lib/freebl/gcm.c
+++ /dev/null
@@ -1,844 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-#include "blapii.h"
-#include "blapit.h"
-#include "gcm.h"
-#include "ctr.h"
-#include "secerr.h"
-#include "prtypes.h"
-#include "pkcs11t.h"
-
-#include <limits.h>
-
-/**************************************************************************
- * First implement the Galois hash function of GCM (gcmHash) *
- **************************************************************************/
-#define GCM_HASH_LEN_LEN 8 /* gcm hash defines lengths to be 64 bits */
-
-typedef struct gcmHashContextStr gcmHashContext;
-
-static SECStatus gcmHash_InitContext(gcmHashContext *hash,
- const unsigned char *H,
- unsigned int blocksize);
-static void gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit);
-static SECStatus gcmHash_Update(gcmHashContext *ghash,
- const unsigned char *buf, unsigned int len,
- unsigned int blocksize);
-static SECStatus gcmHash_Sync(gcmHashContext *ghash, unsigned int blocksize);
-static SECStatus gcmHash_Final(gcmHashContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- unsigned int blocksize);
-static SECStatus gcmHash_Reset(gcmHashContext *ghash,
- const unsigned char *inbuf,
- unsigned int inbufLen, unsigned int blocksize);
-
-/* compile time defines to select how the GF2 multiply is calculated.
- * There are currently 2 algorithms implemented here: MPI and ALGORITHM_1.
- *
- * MPI uses the GF2m implemented in mpi to support GF2 ECC.
- * ALGORITHM_1 is the Algorithm 1 in both NIST SP 800-38D and
- * "The Galois/Counter Mode of Operation (GCM)", McGrew & Viega.
- */
-#if !defined(GCM_USE_ALGORITHM_1) && !defined(GCM_USE_MPI)
-#define GCM_USE_MPI 1 /* MPI is about 5x faster with the
- * same or less complexity. It's possible to use
- * tables to speed things up even more */
-#endif
-
-/* GCM defines the bit string to be LSB first, which is exactly
- * opposite everyone else, including hardware. build array
- * to reverse everything. */
-static const unsigned char gcm_byte_rev[256] = {
- 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
- 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
- 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
- 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
- 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
- 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
- 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
- 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
- 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
- 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
- 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
- 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
- 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
- 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
- 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
- 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
- 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
- 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
- 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
- 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
- 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
- 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
- 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
- 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
- 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
- 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
- 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
- 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
- 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
- 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
- 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
- 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
-};
-
-
-#ifdef GCM_TRACE
-#include <stdio.h>
-
-#define GCM_TRACE_X(ghash,label) { \
- unsigned char _X[MAX_BLOCK_SIZE]; int i; \
- gcm_getX(ghash, _X, blocksize); \
- printf(label,(ghash)->m); \
- for (i=0; i < blocksize; i++) printf("%02x",_X[i]); \
- printf("\n"); }
-#define GCM_TRACE_BLOCK(label,buf,blocksize) {\
- printf(label); \
- for (i=0; i < blocksize; i++) printf("%02x",buf[i]); \
- printf("\n"); }
-#else
-#define GCM_TRACE_X(ghash,label)
-#define GCM_TRACE_BLOCK(label,buf,blocksize)
-#endif
-
-#ifdef GCM_USE_MPI
-
-#ifdef GCM_USE_ALGORITHM_1
-#error "Only define one of GCM_USE_MPI, GCM_USE_ALGORITHM_1"
-#endif
-/* use the MPI functions to calculate Xn = (Xn-1^C_i)*H mod poly */
-#include "mpi.h"
-#include "secmpi.h"
-#include "mplogic.h"
-#include "mp_gf2m.h"
-
-/* state needed to handle GCM Hash function */
-struct gcmHashContextStr {
- mp_int H;
- mp_int X;
- mp_int C_i;
- const unsigned int *poly;
- unsigned char buffer[MAX_BLOCK_SIZE];
- unsigned int bufLen;
- int m; /* XXX what is m? */
- unsigned char counterBuf[2*GCM_HASH_LEN_LEN];
- PRUint64 cLen;
-};
-
-/* f = x^128 + x^7 + x^2 + x + 1 */
-static const unsigned int poly_128[] = { 128, 7, 2, 1, 0 };
-
-/* sigh, GCM defines the bit strings exactly backwards from everything else */
-static void
-gcm_reverse(unsigned char *target, const unsigned char *src,
- unsigned int blocksize)
-{
- unsigned int i;
- for (i=0; i < blocksize; i++) {
- target[blocksize-i-1] = gcm_byte_rev[src[i]];
- }
-}
-
-/* Initialize a gcmHashContext */
-static SECStatus
-gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H,
- unsigned int blocksize)
-{
- mp_err err = MP_OKAY;
- unsigned char H_rev[MAX_BLOCK_SIZE];
-
- MP_DIGITS(&ghash->H) = 0;
- MP_DIGITS(&ghash->X) = 0;
- MP_DIGITS(&ghash->C_i) = 0;
- CHECK_MPI_OK( mp_init(&ghash->H) );
- CHECK_MPI_OK( mp_init(&ghash->X) );
- CHECK_MPI_OK( mp_init(&ghash->C_i) );
-
- mp_zero(&ghash->X);
- gcm_reverse(H_rev, H, blocksize);
- CHECK_MPI_OK( mp_read_unsigned_octets(&ghash->H, H_rev, blocksize) );
-
- /* set the irreducible polynomial. Each blocksize has its own polynomial.
- * for now only blocksize 16 (=128 bits) is defined */
- switch (blocksize) {
- case 16: /* 128 bits */
- ghash->poly = poly_128;
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
- ghash->cLen = 0;
- ghash->bufLen = 0;
- ghash->m = 0;
- PORT_Memset(ghash->counterBuf, 0, sizeof(ghash->counterBuf));
- return SECSuccess;
-cleanup:
- gcmHash_DestroyContext(ghash, PR_FALSE);
- return SECFailure;
-}
-
-/* Destroy a HashContext (Note we zero the digits so this function
- * is idempotent if called with freeit == PR_FALSE */
-static void
-gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit)
-{
- mp_clear(&ghash->H);
- mp_clear(&ghash->X);
- mp_clear(&ghash->C_i);
- MP_DIGITS(&ghash->H) = 0;
- MP_DIGITS(&ghash->X) = 0;
- MP_DIGITS(&ghash->C_i) = 0;
- if (freeit) {
- PORT_Free(ghash);
- }
-}
-
-static SECStatus
-gcm_getX(gcmHashContext *ghash, unsigned char *T, unsigned int blocksize)
-{
- int len;
- mp_err err;
- unsigned char tmp_buf[MAX_BLOCK_SIZE];
- unsigned char *X;
-
- len = mp_unsigned_octet_size(&ghash->X);
- if (len <= 0) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- X = tmp_buf;
- PORT_Assert((unsigned int)len <= blocksize);
- if ((unsigned int)len > blocksize) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* zero pad the result */
- if (len != blocksize) {
- PORT_Memset(X,0,blocksize-len);
- X += blocksize-len;
- }
-
- err = mp_to_unsigned_octets(&ghash->X, X, len);
- if (err < 0) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- gcm_reverse(T, X, blocksize);
- return SECSuccess;
-}
-
-static SECStatus
-gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf,
- unsigned int count, unsigned int blocksize)
-{
- SECStatus rv = SECFailure;
- mp_err err = MP_OKAY;
- unsigned char tmp_buf[MAX_BLOCK_SIZE];
- unsigned int i;
-
- for (i=0; i < count; i++, buf += blocksize) {
- ghash->m++;
- gcm_reverse(tmp_buf, buf, blocksize);
- CHECK_MPI_OK(mp_read_unsigned_octets(&ghash->C_i, tmp_buf, blocksize));
- CHECK_MPI_OK(mp_badd(&ghash->X, &ghash->C_i, &ghash->C_i));
- /*
- * Looking to speed up GCM, this the the place to do it.
- * There are two areas that can be exploited to speed up this code.
- *
- * 1) H is a constant in this multiply. We can precompute H * (0 - 255)
- * at init time and this becomes an blockize xors of our table lookup.
- *
- * 2) poly is a constant for each blocksize. We can calculate the
- * modulo reduction by a series of adds and shifts.
- *
- * For now we are after functionality, so we will go ahead and use
- * the builtin bmulmod from mpi
- */
- CHECK_MPI_OK(mp_bmulmod(&ghash->C_i, &ghash->H,
- ghash->poly, &ghash->X));
- GCM_TRACE_X(ghash, "X%d = ")
- }
- rv = SECSuccess;
-cleanup:
- if (rv != SECSuccess) {
- MP_TO_SEC_ERROR(err);
- }
- return rv;
-}
-
-static void
-gcm_zeroX(gcmHashContext *ghash)
-{
- mp_zero(&ghash->X);
- ghash->m = 0;
-}
-
-#endif
-
-#ifdef GCM_USE_ALGORITHM_1
-/* use algorithm 1 of McGrew & Viega "The Galois/Counter Mode of Operation" */
-
-#define GCM_ARRAY_SIZE (MAX_BLOCK_SIZE/sizeof(unsigned long))
-
-struct gcmHashContextStr {
- unsigned long H[GCM_ARRAY_SIZE];
- unsigned long X[GCM_ARRAY_SIZE];
- unsigned long R;
- unsigned char buffer[MAX_BLOCK_SIZE];
- unsigned int bufLen;
- int m;
- unsigned char counterBuf[2*GCM_HASH_LEN_LEN];
- PRUint64 cLen;
-};
-
-static void
-gcm_bytes_to_longs(unsigned long *l, const unsigned char *c, unsigned int len)
-{
- int i,j;
- int array_size = len/sizeof(unsigned long);
-
- PORT_Assert(len % sizeof(unsigned long) == 0);
- for (i=0; i < array_size; i++) {
- unsigned long tmp = 0;
- int byte_offset = i * sizeof(unsigned long);
- for (j=sizeof(unsigned long)-1; j >= 0; j--) {
- tmp = (tmp << PR_BITS_PER_BYTE) | gcm_byte_rev[c[byte_offset+j]];
- }
- l[i] = tmp;
- }
-}
-
-static void
-gcm_longs_to_bytes(const unsigned long *l, unsigned char *c, unsigned int len)
-{
- int i,j;
- int array_size = len/sizeof(unsigned long);
-
- PORT_Assert(len % sizeof(unsigned long) == 0);
- for (i=0; i < array_size; i++) {
- unsigned long tmp = l[i];
- int byte_offset = i * sizeof(unsigned long);
- for (j=0; j < sizeof(unsigned long); j++) {
- c[byte_offset+j] = gcm_byte_rev[tmp & 0xff];
- tmp = (tmp >> PR_BITS_PER_BYTE);
- }
- }
-}
-
-
-/* Initialize a gcmHashContext */
-static SECStatus
-gcmHash_InitContext(gcmHashContext *ghash, const unsigned char *H,
- unsigned int blocksize)
-{
- PORT_Memset(ghash->X, 0, sizeof(ghash->X));
- PORT_Memset(ghash->H, 0, sizeof(ghash->H));
- gcm_bytes_to_longs(ghash->H, H, blocksize);
-
- /* set the irreducible polynomial. Each blocksize has its own polynommial
- * for now only blocksize 16 (=128 bits) is defined */
- switch (blocksize) {
- case 16: /* 128 bits */
- ghash->R = (unsigned long) 0x87; /* x^7 + x^2 + x +1 */
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
- }
- ghash->cLen = 0;
- ghash->bufLen = 0;
- ghash->m = 0;
- PORT_Memset(ghash->counterBuf, 0, sizeof(ghash->counterBuf));
- return SECSuccess;
-cleanup:
- return SECFailure;
-}
-
-/* Destroy a HashContext (Note we zero the digits so this function
- * is idempotent if called with freeit == PR_FALSE */
-static void
-gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit)
-{
- if (freeit) {
- PORT_Free(ghash);
- }
-}
-
-static unsigned long
-gcm_shift_one(unsigned long *t, unsigned int count)
-{
- unsigned long carry = 0;
- unsigned long nextcarry = 0;
- unsigned int i;
- for (i=0; i < count; i++) {
- nextcarry = t[i] >> ((sizeof(unsigned long)*PR_BITS_PER_BYTE)-1);
- t[i] = (t[i] << 1) | carry;
- carry = nextcarry;
- }
- return carry;
-}
-
-static SECStatus
-gcm_getX(gcmHashContext *ghash, unsigned char *T, unsigned int blocksize)
-{
- gcm_longs_to_bytes(ghash->X, T, blocksize);
- return SECSuccess;
-}
-
-#define GCM_XOR(t, s, len) \
- for (l=0; l < len; l++) t[l] ^= s[l]
-
-static SECStatus
-gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf,
- unsigned int count, unsigned int blocksize)
-{
- unsigned long C_i[GCM_ARRAY_SIZE];
- unsigned int arraysize = blocksize/sizeof(unsigned long);
- unsigned int i, j, k, l;
-
- for (i=0; i < count; i++, buf += blocksize) {
- ghash->m++;
- gcm_bytes_to_longs(C_i, buf, blocksize);
- GCM_XOR(C_i, ghash->X, arraysize);
- /* multiply X = C_i * H */
- PORT_Memset(ghash->X, 0, sizeof(ghash->X));
- for (j=0; j < arraysize; j++) {
- unsigned long H = ghash->H[j];
- for (k=0; k < sizeof(unsigned long)*PR_BITS_PER_BYTE; k++) {
- if (H & 1) {
- GCM_XOR(ghash->X, C_i, arraysize);
- }
- if (gcm_shift_one(C_i, arraysize)) {
- C_i[0] = C_i[0] ^ ghash->R;
- }
- H = H >> 1;
- }
- }
- GCM_TRACE_X(ghash, "X%d = ")
- }
- return SECSuccess;
-}
-
-
-static void
-gcm_zeroX(gcmHashContext *ghash)
-{
- PORT_Memset(ghash->X, 0, sizeof(ghash->X));
- ghash->m = 0;
-}
-#endif
-
-/*
- * implement GCM GHASH using the freebl GHASH function. The gcm_HashMult
- * function always takes blocksize lengths of data. gcmHash_Update will
- * format the data properly.
- */
-static SECStatus
-gcmHash_Update(gcmHashContext *ghash, const unsigned char *buf,
- unsigned int len, unsigned int blocksize)
-{
- unsigned int blocks;
- SECStatus rv;
-
- ghash->cLen += (len*PR_BITS_PER_BYTE);
-
- /* first deal with the current buffer of data. Try to fill it out so
- * we can hash it */
- if (ghash->bufLen) {
- unsigned int needed = PR_MIN(len, blocksize - ghash->bufLen);
- PORT_Memcpy(ghash->buffer+ghash->bufLen, buf, needed);
- buf += needed;
- len -= needed;
- ghash->bufLen += needed;
- if (len == 0) {
- /* didn't add enough to hash the data, nothing more do do */
- return SECSuccess;
- }
- PORT_Assert(ghash->bufLen == blocksize);
- /* hash the buffer and clear it */
- rv = gcm_HashMult(ghash, ghash->buffer, 1, blocksize);
- PORT_Memset(ghash->buffer, 0, blocksize);
- ghash->bufLen = 0;
- if (rv != SECSuccess) {
- return SECFailure;
- }
- }
- /* now hash any full blocks remaining in the data stream */
- blocks = len/blocksize;
- if (blocks) {
- rv = gcm_HashMult(ghash, buf, blocks, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- buf += blocks*blocksize;
- len -= blocks*blocksize;
- }
-
- /* save any remainder in the buffer to be hashed with the next call */
- if (len != 0) {
- PORT_Memcpy(ghash->buffer, buf, len);
- ghash->bufLen = len;
- }
- return SECSuccess;
-}
-
-/*
- * write out any partial blocks zero padded through the GHASH engine,
- * save the lengths for the final completion of the hash
- */
-static SECStatus
-gcmHash_Sync(gcmHashContext *ghash, unsigned int blocksize)
-{
- int i;
- SECStatus rv;
-
- /* copy the previous counter to the upper block */
- PORT_Memcpy(ghash->counterBuf, &ghash->counterBuf[GCM_HASH_LEN_LEN],
- GCM_HASH_LEN_LEN);
- /* copy the current counter in the lower block */
- for (i=0; i < GCM_HASH_LEN_LEN; i++) {
- ghash->counterBuf[GCM_HASH_LEN_LEN+i] =
- (ghash->cLen >> ((GCM_HASH_LEN_LEN-1-i)*PR_BITS_PER_BYTE)) & 0xff;
- }
- ghash->cLen = 0;
-
- /* now zero fill the buffer and hash the last block */
- if (ghash->bufLen) {
- PORT_Memset(ghash->buffer+ghash->bufLen, 0, blocksize - ghash->bufLen);
- rv = gcm_HashMult(ghash, ghash->buffer, 1, blocksize);
- PORT_Memset(ghash->buffer, 0, blocksize);
- ghash->bufLen = 0;
- if (rv != SECSuccess) {
- return SECFailure;
- }
- }
- return SECSuccess;
-}
-
-/*
- * This does the final sync, hashes the lengths, then returns
- * "T", the hashed output.
- */
-static SECStatus
-gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- unsigned int blocksize)
-{
- unsigned char T[MAX_BLOCK_SIZE];
- SECStatus rv;
-
- rv = gcmHash_Sync(ghash, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
- rv = gcm_HashMult(ghash, ghash->counterBuf, (GCM_HASH_LEN_LEN*2)/blocksize,
- blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
- GCM_TRACE_X(ghash, "GHASH(H,A,C) = ")
-
- rv = gcm_getX(ghash, T, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
- if (maxout > blocksize) maxout = blocksize;
- PORT_Memcpy(outbuf, T, maxout);
- *outlen = maxout;
- return SECSuccess;
-}
-
-SECStatus
-gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD,
- unsigned int AADLen, unsigned int blocksize)
-{
- SECStatus rv;
-
- ghash->cLen = 0;
- PORT_Memset(ghash->counterBuf, 0, GCM_HASH_LEN_LEN*2);
- ghash->bufLen = 0;
- gcm_zeroX(ghash);
-
- /* now kick things off by hashing the Additional Authenticated Data */
- if (AADLen != 0) {
- rv = gcmHash_Update(ghash, AAD, AADLen, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- rv = gcmHash_Sync(ghash, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- }
- return SECSuccess;
-}
-
-/**************************************************************************
- * Now implement the GCM using gcmHash and CTR *
- **************************************************************************/
-
-/* state to handle the full GCM operation (hash and counter) */
-struct GCMContextStr {
- gcmHashContext ghash_context;
- CTRContext ctr_context;
- unsigned long tagBits;
- unsigned char tagKey[MAX_BLOCK_SIZE];
-};
-
-GCMContext *
-GCM_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *params, unsigned int blocksize)
-{
- GCMContext *gcm = NULL;
- gcmHashContext *ghash;
- unsigned char H[MAX_BLOCK_SIZE];
- unsigned int tmp;
- PRBool freeCtr = PR_FALSE;
- PRBool freeHash = PR_FALSE;
- const CK_GCM_PARAMS *gcmParams = (const CK_GCM_PARAMS *)params;
- CK_AES_CTR_PARAMS ctrParams;
- SECStatus rv;
-
- if (blocksize > MAX_BLOCK_SIZE || blocksize > sizeof(ctrParams.cb)) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
- gcm = PORT_ZNew(GCMContext);
- if (gcm == NULL) {
- return NULL;
- }
- /* first fill in the ghash context */
- ghash = &gcm->ghash_context;
- PORT_Memset(H, 0, blocksize);
- rv = (*cipher)(context, H, &tmp, blocksize, H, blocksize, blocksize);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = gcmHash_InitContext(ghash, H, blocksize);
- if (rv != SECSuccess) {
- goto loser;
- }
- freeHash = PR_TRUE;
-
- /* fill in the Counter context */
- ctrParams.ulCounterBits = 32;
- PORT_Memset(ctrParams.cb, 0, sizeof(ctrParams.cb));
- if ((blocksize == 16) && (gcmParams->ulIvLen == 12)) {
- PORT_Memcpy(ctrParams.cb, gcmParams->pIv, gcmParams->ulIvLen);
- ctrParams.cb[blocksize-1] = 1;
- } else {
- rv = gcmHash_Update(ghash, gcmParams->pIv, gcmParams->ulIvLen,
- blocksize);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = gcmHash_Final(ghash, ctrParams.cb, &tmp, blocksize, blocksize);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- rv = CTR_InitContext(&gcm->ctr_context, context, cipher,
- (unsigned char *)&ctrParams, blocksize);
- if (rv != SECSuccess) {
- goto loser;
- }
- freeCtr = PR_TRUE;
-
- /* fill in the gcm structure */
- gcm->tagBits = gcmParams->ulTagBits; /* save for final step */
- /* calculate the final tag key. NOTE: gcm->tagKey is zero to start with.
- * if this assumption changes, we would need to explicitly clear it here */
- rv = CTR_Update(&gcm->ctr_context, gcm->tagKey, &tmp, blocksize,
- gcm->tagKey, blocksize, blocksize);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* finally mix in the AAD data */
- rv = gcmHash_Reset(ghash, gcmParams->pAAD, gcmParams->ulAADLen, blocksize);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- return gcm;
-
-loser:
- if (freeCtr) {
- CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
- }
- if (freeHash) {
- gcmHash_DestroyContext(&gcm->ghash_context, PR_FALSE);
- }
- if (gcm) {
- PORT_Free(gcm);
- }
- return NULL;
-}
-
-void
-GCM_DestroyContext(GCMContext *gcm, PRBool freeit)
-{
- /* these two are statically allocated and will be freed when we free
- * gcm. call their destroy functions to free up any locally
- * allocated data (like mp_int's) */
- CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
- gcmHash_DestroyContext(&gcm->ghash_context, PR_FALSE);
- if (freeit) {
- PORT_Free(gcm);
- }
-}
-
-static SECStatus
-gcm_GetTag(GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- unsigned int blocksize)
-{
- unsigned int tagBytes;
- unsigned int extra;
- unsigned int i;
- SECStatus rv;
-
- tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE;
- extra = tagBytes*PR_BITS_PER_BYTE - gcm->tagBits;
-
- if (outbuf == NULL) {
- *outlen = tagBytes;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
-
- if (maxout < tagBytes) {
- *outlen = tagBytes;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- maxout = tagBytes;
- rv = gcmHash_Final(&gcm->ghash_context, outbuf, outlen, maxout, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
- GCM_TRACE_BLOCK("GHASH=", outbuf, blocksize);
- GCM_TRACE_BLOCK("Y0=", gcm->tagKey, blocksize);
- for (i=0; i < *outlen; i++) {
- outbuf[i] ^= gcm->tagKey[i];
- }
- GCM_TRACE_BLOCK("Y0=", gcm->tagKey, blocksize);
- GCM_TRACE_BLOCK("T=", outbuf, blocksize);
- /* mask off any extra bits we got */
- if (extra) {
- outbuf[tagBytes-1] &= ~((1 << extra)-1);
- }
- return SECSuccess;
-}
-
-
-/*
- * See The Galois/Counter Mode of Operation, McGrew and Viega.
- * GCM is basically counter mode with a specific initialization and
- * built in macing operation.
- */
-SECStatus
-GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
-{
- SECStatus rv;
- unsigned int tagBytes;
- unsigned int len;
-
- tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE;
- if (UINT_MAX - inlen < tagBytes) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- if (maxout < inlen + tagBytes) {
- *outlen = inlen + tagBytes;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
-
- rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
- inbuf, inlen, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- rv = gcmHash_Update(&gcm->ghash_context, outbuf, *outlen, blocksize);
- if (rv != SECSuccess) {
- PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */
- *outlen = 0;
- return SECFailure;
- }
- rv = gcm_GetTag(gcm, outbuf + *outlen, &len, maxout - *outlen, blocksize);
- if (rv != SECSuccess) {
- PORT_Memset(outbuf, 0, *outlen); /* clear the output buffer */
- *outlen = 0;
- return SECFailure;
- };
- *outlen += len;
- return SECSuccess;
-}
-
-/*
- * See The Galois/Counter Mode of Operation, McGrew and Viega.
- * GCM is basically counter mode with a specific initialization and
- * built in macing operation. NOTE: the only difference between Encrypt
- * and Decrypt is when we calculate the mac. That is because the mac must
- * always be calculated on the cipher text, not the plain text, so for
- * encrypt, we do the CTR update first and for decrypt we do the mac first.
- */
-SECStatus
-GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
-{
- SECStatus rv;
- unsigned int tagBytes;
- unsigned char tag[MAX_BLOCK_SIZE];
- const unsigned char *intag;
- unsigned int len;
-
- tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE;
-
- /* get the authentication block */
- if (inlen < tagBytes) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- inlen -= tagBytes;
- intag = inbuf + inlen;
-
- /* verify the block */
- rv = gcmHash_Update(&gcm->ghash_context, inbuf, inlen, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- rv = gcm_GetTag(gcm, tag, &len, blocksize, blocksize);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* Don't decrypt if we can't authenticate the encrypted data!
- * This assumes that if tagBits is not a multiple of 8, intag will
- * preserve the masked off missing bits. */
- if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
- /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- /* finish the decryption */
- return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
- inbuf, inlen, blocksize);
-}
diff --git a/security/nss/lib/freebl/gcm.h b/security/nss/lib/freebl/gcm.h
deleted file mode 100644
index 4dd71b4c8..000000000
--- a/security/nss/lib/freebl/gcm.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef GCM_H
-#define GCM_H 1
-
-#include "blapii.h"
-
-typedef struct GCMContextStr GCMContext;
-
-/*
- * The context argument is the inner cipher context to use with cipher. The
- * GCMContext does not own context. context needs to remain valid for as long
- * as the GCMContext is valid.
- *
- * The cipher argument is a block cipher in the ECB encrypt mode.
- */
-GCMContext * GCM_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *params, unsigned int blocksize);
-void GCM_DestroyContext(GCMContext *gcm, PRBool freeit);
-SECStatus GCM_EncryptUpdate(GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize);
-SECStatus GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize);
-
-#endif
diff --git a/security/nss/lib/freebl/genload.c b/security/nss/lib/freebl/genload.c
deleted file mode 100644
index 63b97dbdf..000000000
--- a/security/nss/lib/freebl/genload.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * This file is meant to be included by other .c files.
- * This file takes a "parameter", the scope which includes this
- * code shall declare this variable:
- * const char *NameOfThisSharedLib;
- *
- * NameOfThisSharedLib:
- * The file name of the shared library that shall be used as the
- * "reference library". The loader will attempt to load the requested
- * library from the same directory as the reference library.
- */
-
-#ifdef XP_UNIX
-#include <unistd.h>
-#define BL_MAXSYMLINKS 20
-
-/*
- * If 'link' is a symbolic link, this function follows the symbolic links
- * and returns the pathname of the ultimate source of the symbolic links.
- * If 'link' is not a symbolic link, this function returns NULL.
- * The caller should call PR_Free to free the string returned by this
- * function.
- */
-static char* loader_GetOriginalPathname(const char* link)
-{
-#ifdef __GLIBC__
- char* tmp = realpath(link, NULL);
- char* resolved;
- if (! tmp)
- return NULL;
- resolved = PR_Malloc(strlen(tmp) + 1);
- strcpy(resolved, tmp); /* This is necessary because PR_Free might not be using free() */
- free(tmp);
- return resolved;
-#else
- char* resolved = NULL;
- char* input = NULL;
- PRUint32 iterations = 0;
- PRInt32 len = 0, retlen = 0;
- if (!link) {
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return NULL;
- }
- len = PR_MAX(1024, strlen(link) + 1);
- resolved = PR_Malloc(len);
- input = PR_Malloc(len);
- if (!resolved || !input) {
- if (resolved) {
- PR_Free(resolved);
- }
- if (input) {
- PR_Free(input);
- }
- return NULL;
- }
- strcpy(input, link);
- while ( (iterations++ < BL_MAXSYMLINKS) &&
- ( (retlen = readlink(input, resolved, len - 1)) > 0) ) {
- char* tmp = input;
- resolved[retlen] = '\0'; /* NULL termination */
- input = resolved;
- resolved = tmp;
- }
- PR_Free(resolved);
- if (iterations == 1 && retlen < 0) {
- PR_Free(input);
- input = NULL;
- }
- return input;
-#endif
-}
-#endif /* XP_UNIX */
-
-/*
- * Load the library with the file name 'name' residing in the same
- * directory as the reference library, whose pathname is 'referencePath'.
- */
-static PRLibrary *
-loader_LoadLibInReferenceDir(const char *referencePath, const char *name)
-{
- PRLibrary *dlh = NULL;
- char *fullName = NULL;
- char* c;
- PRLibSpec libSpec;
-
- /* Remove the trailing filename from referencePath and add the new one */
- c = strrchr(referencePath, PR_GetDirectorySeparator());
- if (c) {
- size_t referencePathSize = 1 + c - referencePath;
- fullName = (char*) PORT_Alloc(strlen(name) + referencePathSize + 1);
- if (fullName) {
- memcpy(fullName, referencePath, referencePathSize);
- strcpy(fullName + referencePathSize, name);
-#ifdef DEBUG_LOADER
- PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n",
- fullName);
-#endif
- libSpec.type = PR_LibSpec_Pathname;
- libSpec.value.pathname = fullName;
- dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
- PORT_Free(fullName);
- }
- }
- return dlh;
-}
-
-/*
- * We use PR_GetLibraryFilePathname to get the pathname of the loaded
- * shared lib that contains this function, and then do a PR_LoadLibrary
- * with an absolute pathname for the softoken shared library.
- */
-
-static PRLibrary *
-loader_LoadLibrary(const char *nameToLoad)
-{
- PRLibrary *lib = NULL;
- char* fullPath = NULL;
- PRLibSpec libSpec;
-
- /* Get the pathname for nameOfAlreadyLoadedLib, i.e. /usr/lib/libnss3.so
- * PR_GetLibraryFilePathname works with either the base library name or a
- * function pointer, depending on the platform. We can't query an exported
- * symbol such as NSC_GetFunctionList, because on some platforms we can't
- * find symbols in loaded implicit dependencies.
- * But we can just get the address of this function !
- */
- fullPath = PR_GetLibraryFilePathname(NameOfThisSharedLib,
- (PRFuncPtr)&loader_LoadLibrary);
-
- if (fullPath) {
- lib = loader_LoadLibInReferenceDir(fullPath, nameToLoad);
-#ifdef XP_UNIX
- if (!lib) {
- /*
- * If fullPath is a symbolic link, resolve the symbolic
- * link and try again.
- */
- char* originalfullPath = loader_GetOriginalPathname(fullPath);
- if (originalfullPath) {
- PR_Free(fullPath);
- fullPath = originalfullPath;
- lib = loader_LoadLibInReferenceDir(fullPath, nameToLoad);
- }
- }
-#endif
- PR_Free(fullPath);
- }
- if (!lib) {
-#ifdef DEBUG_LOADER
- PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", nameToLoad);
-#endif
- libSpec.type = PR_LibSpec_Pathname;
- libSpec.value.pathname = nameToLoad;
- lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
- }
- if (NULL == lib) {
-#ifdef DEBUG_LOADER
- PR_fprintf(PR_STDOUT, "\nLoading failed : %s.\n", nameToLoad);
-#endif
- }
- return lib;
-}
-
diff --git a/security/nss/lib/freebl/hmacct.c b/security/nss/lib/freebl/hmacct.c
deleted file mode 100644
index 0c3ba41de..000000000
--- a/security/nss/lib/freebl/hmacct.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "secport.h"
-#include "hasht.h"
-#include "blapit.h"
-#include "hmacct.h"
-#include "secerr.h"
-
-/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
- * field. (SHA-384/512 have 128-bit length.) */
-#define MAX_HASH_BIT_COUNT_BYTES 16
-
-/* Some utility functions are needed:
- *
- * These macros return the given value with the MSB copied to all the other
- * bits. They use the fact that an arithmetic shift shifts-in the sign bit.
- * However, this is not ensured by the C standard so you may need to replace
- * them with something else on odd CPUs.
- *
- * Note: the argument to these macros must be an unsigned int.
- * */
-#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned int)( (int)(x) >> (sizeof(int)*8-1) ) )
-#define DUPLICATE_MSB_TO_ALL_8(x) ( (unsigned char)(DUPLICATE_MSB_TO_ALL(x)) )
-
-/* constantTimeGE returns 0xff if a>=b and 0x00 otherwise, where a, b <
- * MAX_UINT/2. */
-static unsigned char
-constantTimeGE(unsigned int a, unsigned int b)
-{
- a -= b;
- return DUPLICATE_MSB_TO_ALL(~a);
-}
-
-/* constantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
-static unsigned char
-constantTimeEQ8(unsigned char a, unsigned char b)
-{
- unsigned int c = a ^ b;
- c--;
- return DUPLICATE_MSB_TO_ALL_8(c);
-}
-
-/* MAC performs a constant time SSLv3/TLS MAC of |dataLen| bytes of |data|,
- * where |dataLen| includes both the authenticated bytes and the MAC tag from
- * the sender. |dataLen| must be >= the length of the MAC tag.
- *
- * |dataTotalLen| is >= |dataLen| and also accounts for any padding bytes
- * that may follow the sender's MAC. (Only a single block of padding may
- * follow in SSLv3, or up to 255 bytes in TLS.)
- *
- * Since the results of decryption are secret information (otherwise a
- * padding-oracle is created), this function is constant-time with respect to
- * |dataLen|.
- *
- * |header| contains either the 13-byte TLS header (containing the sequence
- * number, record type etc), or it contains the SSLv3 header with the SSLv3
- * padding bytes etc. */
-static SECStatus
-MAC(unsigned char *mdOut,
- unsigned int *mdOutLen,
- unsigned int mdOutMax,
- const SECHashObject *hashObj,
- const unsigned char *macSecret,
- unsigned int macSecretLen,
- const unsigned char *header,
- unsigned int headerLen,
- const unsigned char *data,
- unsigned int dataLen,
- unsigned int dataTotalLen,
- unsigned char isSSLv3)
-{
- void *mdState = hashObj->create();
- const unsigned int mdSize = hashObj->length;
- const unsigned int mdBlockSize = hashObj->blocklength;
- /* mdLengthSize is the number of bytes in the length field that terminates
- * the hash.
- *
- * This assumes that hash functions with a 64 byte block size use a 64-bit
- * length, and otherwise they use a 128-bit length. This is true of {MD5,
- * SHA*} (which are all of the hash functions specified for use with TLS
- * today). */
- const unsigned int mdLengthSize = mdBlockSize == 64 ? 8 : 16;
-
- const unsigned int sslv3PadLen = hashObj->type == HASH_AlgMD5 ? 48 : 40;
-
- /* varianceBlocks is the number of blocks of the hash that we have to
- * calculate in constant time because they could be altered by the
- * padding value.
- *
- * In SSLv3, the padding must be minimal so the end of the plaintext
- * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
- * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
- * termination (0x80 + 64-bit length) don't fit in the final block, we
- * say that the final two blocks can vary based on the padding.
- *
- * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
- * required to be minimal. Therefore we say that the final six blocks
- * can vary based on the padding.
- *
- * Later in the function, if the message is short and there obviously
- * cannot be this many blocks then varianceBlocks can be reduced. */
- unsigned int varianceBlocks = isSSLv3 ? 2 : 6;
- /* From now on we're dealing with the MAC, which conceptually has 13
- * bytes of `header' before the start of the data (TLS) or 71/75 bytes
- * (SSLv3) */
- const unsigned int len = dataTotalLen + headerLen;
- /* maxMACBytes contains the maximum bytes of bytes in the MAC, including
- * |header|, assuming that there's no padding. */
- const unsigned int maxMACBytes = len - mdSize - 1;
- /* numBlocks is the maximum number of hash blocks. */
- const unsigned int numBlocks =
- (maxMACBytes + 1 + mdLengthSize + mdBlockSize - 1) / mdBlockSize;
- /* macEndOffset is the index just past the end of the data to be
- * MACed. */
- const unsigned int macEndOffset = dataLen + headerLen - mdSize;
- /* c is the index of the 0x80 byte in the final hash block that
- * contains application data. */
- const unsigned int c = macEndOffset % mdBlockSize;
- /* indexA is the hash block number that contains the 0x80 terminating
- * value. */
- const unsigned int indexA = macEndOffset / mdBlockSize;
- /* indexB is the hash block number that contains the 64-bit hash
- * length, in bits. */
- const unsigned int indexB = (macEndOffset + mdLengthSize) / mdBlockSize;
- /* bits is the hash-length in bits. It includes the additional hash
- * block for the masked HMAC key, or whole of |header| in the case of
- * SSLv3. */
- unsigned int bits;
- /* In order to calculate the MAC in constant time we have to handle
- * the final blocks specially because the padding value could cause the
- * end to appear somewhere in the final |varianceBlocks| blocks and we
- * can't leak where. However, |numStartingBlocks| worth of data can
- * be hashed right away because no padding value can affect whether
- * they are plaintext. */
- unsigned int numStartingBlocks = 0;
- /* k is the starting byte offset into the conceptual header||data where
- * we start processing. */
- unsigned int k = 0;
- unsigned char lengthBytes[MAX_HASH_BIT_COUNT_BYTES];
- /* hmacPad is the masked HMAC key. */
- unsigned char hmacPad[HASH_BLOCK_LENGTH_MAX];
- unsigned char firstBlock[HASH_BLOCK_LENGTH_MAX];
- unsigned char macOut[HASH_LENGTH_MAX];
- unsigned i, j;
-
- /* For SSLv3, if we're going to have any starting blocks then we need
- * at least two because the header is larger than a single block. */
- if (numBlocks > varianceBlocks + (isSSLv3 ? 1 : 0)) {
- numStartingBlocks = numBlocks - varianceBlocks;
- k = mdBlockSize*numStartingBlocks;
- }
-
- bits = 8*macEndOffset;
- hashObj->begin(mdState);
- if (!isSSLv3) {
- /* Compute the initial HMAC block. For SSLv3, the padding and
- * secret bytes are included in |header| because they take more
- * than a single block. */
- bits += 8*mdBlockSize;
- memset(hmacPad, 0, mdBlockSize);
- PORT_Assert(macSecretLen <= sizeof(hmacPad));
- memcpy(hmacPad, macSecret, macSecretLen);
- for (i = 0; i < mdBlockSize; i++)
- hmacPad[i] ^= 0x36;
- hashObj->update(mdState, hmacPad, mdBlockSize);
- }
-
- j = 0;
- memset(lengthBytes, 0, sizeof(lengthBytes));
- if (mdLengthSize == 16) {
- j = 8;
- }
- if (hashObj->type == HASH_AlgMD5) {
- /* MD5 appends a little-endian length. */
- for (i = 0; i < 4; i++) {
- lengthBytes[i+j] = bits >> (8*i);
- }
- } else {
- /* All other TLS hash functions use a big-endian length. */
- for (i = 0; i < 4; i++) {
- lengthBytes[4+i+j] = bits >> (8*(3-i));
- }
- }
-
- if (k > 0) {
- if (isSSLv3) {
- /* The SSLv3 header is larger than a single block.
- * overhang is the number of bytes beyond a single
- * block that the header consumes: either 7 bytes
- * (SHA1) or 11 bytes (MD5). */
- const unsigned int overhang = headerLen-mdBlockSize;
- hashObj->update(mdState, header, mdBlockSize);
- memcpy(firstBlock, header + mdBlockSize, overhang);
- memcpy(firstBlock + overhang, data, mdBlockSize-overhang);
- hashObj->update(mdState, firstBlock, mdBlockSize);
- for (i = 1; i < k/mdBlockSize - 1; i++) {
- hashObj->update(mdState, data + mdBlockSize*i - overhang,
- mdBlockSize);
- }
- } else {
- /* k is a multiple of mdBlockSize. */
- memcpy(firstBlock, header, 13);
- memcpy(firstBlock+13, data, mdBlockSize-13);
- hashObj->update(mdState, firstBlock, mdBlockSize);
- for (i = 1; i < k/mdBlockSize; i++) {
- hashObj->update(mdState, data + mdBlockSize*i - 13,
- mdBlockSize);
- }
- }
- }
-
- memset(macOut, 0, sizeof(macOut));
-
- /* We now process the final hash blocks. For each block, we construct
- * it in constant time. If i == indexA then we'll include the 0x80
- * bytes and zero pad etc. For each block we selectively copy it, in
- * constant time, to |macOut|. */
- for (i = numStartingBlocks; i <= numStartingBlocks+varianceBlocks; i++) {
- unsigned char block[HASH_BLOCK_LENGTH_MAX];
- unsigned char isBlockA = constantTimeEQ8(i, indexA);
- unsigned char isBlockB = constantTimeEQ8(i, indexB);
- for (j = 0; j < mdBlockSize; j++) {
- unsigned char isPastC = isBlockA & constantTimeGE(j, c);
- unsigned char isPastCPlus1 = isBlockA & constantTimeGE(j, c+1);
- unsigned char b = 0;
- if (k < headerLen) {
- b = header[k];
- } else if (k < dataTotalLen + headerLen) {
- b = data[k-headerLen];
- }
- k++;
-
- /* If this is the block containing the end of the
- * application data, and we are at the offset for the
- * 0x80 value, then overwrite b with 0x80. */
- b = (b&~isPastC) | (0x80&isPastC);
- /* If this the the block containing the end of the
- * application data and we're past the 0x80 value then
- * just write zero. */
- b = b&~isPastCPlus1;
- /* If this is indexB (the final block), but not
- * indexA (the end of the data), then the 64-bit
- * length didn't fit into indexA and we're having to
- * add an extra block of zeros. */
- b &= ~isBlockB | isBlockA;
-
- /* The final bytes of one of the blocks contains the length. */
- if (j >= mdBlockSize - mdLengthSize) {
- /* If this is indexB, write a length byte. */
- b = (b&~isBlockB) |
- (isBlockB&lengthBytes[j-(mdBlockSize-mdLengthSize)]);
- }
- block[j] = b;
- }
-
- hashObj->update(mdState, block, mdBlockSize);
- hashObj->end_raw(mdState, block, NULL, mdSize);
- /* If this is indexB, copy the hash value to |macOut|. */
- for (j = 0; j < mdSize; j++) {
- macOut[j] |= block[j]&isBlockB;
- }
- }
-
- hashObj->begin(mdState);
-
- if (isSSLv3) {
- /* We repurpose |hmacPad| to contain the SSLv3 pad2 block. */
- for (i = 0; i < sslv3PadLen; i++)
- hmacPad[i] = 0x5c;
-
- hashObj->update(mdState, macSecret, macSecretLen);
- hashObj->update(mdState, hmacPad, sslv3PadLen);
- hashObj->update(mdState, macOut, mdSize);
- } else {
- /* Complete the HMAC in the standard manner. */
- for (i = 0; i < mdBlockSize; i++)
- hmacPad[i] ^= 0x6a;
-
- hashObj->update(mdState, hmacPad, mdBlockSize);
- hashObj->update(mdState, macOut, mdSize);
- }
-
- hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
- hashObj->destroy(mdState, PR_TRUE);
-
- return SECSuccess;
-}
-
-SECStatus
-HMAC_ConstantTime(
- unsigned char *result,
- unsigned int *resultLen,
- unsigned int maxResultLen,
- const SECHashObject *hashObj,
- const unsigned char *secret,
- unsigned int secretLen,
- const unsigned char *header,
- unsigned int headerLen,
- const unsigned char *body,
- unsigned int bodyLen,
- unsigned int bodyTotalLen)
-{
- if (hashObj->end_raw == NULL)
- return SECFailure;
- return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
- header, headerLen, body, bodyLen, bodyTotalLen,
- 0 /* not SSLv3 */);
-}
-
-SECStatus
-SSLv3_MAC_ConstantTime(
- unsigned char *result,
- unsigned int *resultLen,
- unsigned int maxResultLen,
- const SECHashObject *hashObj,
- const unsigned char *secret,
- unsigned int secretLen,
- const unsigned char *header,
- unsigned int headerLen,
- const unsigned char *body,
- unsigned int bodyLen,
- unsigned int bodyTotalLen)
-{
- if (hashObj->end_raw == NULL)
- return SECFailure;
- return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
- header, headerLen, body, bodyLen, bodyTotalLen,
- 1 /* SSLv3 */);
-}
-
diff --git a/security/nss/lib/freebl/hmacct.h b/security/nss/lib/freebl/hmacct.h
deleted file mode 100644
index a773ea89c..000000000
--- a/security/nss/lib/freebl/hmacct.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _HMACCT_H_
-#define _HMACCT_H_
-
-SEC_BEGIN_PROTOS
-
-extern SECStatus HMAC_ConstantTime(
- unsigned char *result,
- unsigned int *resultLen,
- unsigned int maxResultLen,
- const SECHashObject *hashObj,
- const unsigned char *secret,
- unsigned int secretLen,
- const unsigned char *header,
- unsigned int headerLen,
- const unsigned char *body,
- unsigned int bodyLen,
- unsigned int bodyTotalLen);
-
-extern SECStatus SSLv3_MAC_ConstantTime(
- unsigned char *result,
- unsigned int *resultLen,
- unsigned int maxResultLen,
- const SECHashObject *hashObj,
- const unsigned char *secret,
- unsigned int secretLen,
- const unsigned char *header,
- unsigned int headerLen,
- const unsigned char *body,
- unsigned int bodyLen,
- unsigned int bodyTotalLen);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/freebl/intel-aes.h b/security/nss/lib/freebl/intel-aes.h
deleted file mode 100644
index 1e180072a..000000000
--- a/security/nss/lib/freebl/intel-aes.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Prototypes of the functions defined in the assembler file. */
-void intel_aes_encrypt_init_128(const unsigned char *key, PRUint32 *expanded);
-void intel_aes_encrypt_init_192(const unsigned char *key, PRUint32 *expanded);
-void intel_aes_encrypt_init_256(const unsigned char *key, PRUint32 *expanded);
-void intel_aes_decrypt_init_128(const unsigned char *key, PRUint32 *expanded);
-void intel_aes_decrypt_init_192(const unsigned char *key, PRUint32 *expanded);
-void intel_aes_decrypt_init_256(const unsigned char *key, PRUint32 *expanded);
-SECStatus intel_aes_encrypt_ecb_128(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_decrypt_ecb_128(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_encrypt_cbc_128(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_decrypt_cbc_128(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_encrypt_ecb_192(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_decrypt_ecb_192(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_encrypt_cbc_192(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_decrypt_cbc_192(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_encrypt_ecb_256(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_decrypt_ecb_256(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_encrypt_cbc_256(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-SECStatus intel_aes_decrypt_cbc_256(AESContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen,
- unsigned int blocksize);
-
-
-#define intel_aes_ecb_worker(encrypt, keysize) \
- ((encrypt) \
- ? ((keysize) == 16 ? intel_aes_encrypt_ecb_128 : \
- (keysize) == 24 ? intel_aes_encrypt_ecb_192 : \
- intel_aes_encrypt_ecb_256) \
- : ((keysize) == 16 ? intel_aes_decrypt_ecb_128 : \
- (keysize) == 24 ? intel_aes_decrypt_ecb_192 : \
- intel_aes_decrypt_ecb_256))
-
-
-#define intel_aes_cbc_worker(encrypt, keysize) \
- ((encrypt) \
- ? ((keysize) == 16 ? intel_aes_encrypt_cbc_128 : \
- (keysize) == 24 ? intel_aes_encrypt_cbc_192 : \
- intel_aes_encrypt_cbc_256) \
- : ((keysize) == 16 ? intel_aes_decrypt_cbc_128 : \
- (keysize) == 24 ? intel_aes_decrypt_cbc_192 : \
- intel_aes_decrypt_cbc_256))
-
-
-#define intel_aes_init(encrypt, keysize) \
- do { \
- if (encrypt) { \
- if (keysize == 16) \
- intel_aes_encrypt_init_128(key, cx->expandedKey); \
- else if (keysize == 24) \
- intel_aes_encrypt_init_192(key, cx->expandedKey); \
- else \
- intel_aes_encrypt_init_256(key, cx->expandedKey); \
- } else { \
- if (keysize == 16) \
- intel_aes_decrypt_init_128(key, cx->expandedKey); \
- else if (keysize == 24) \
- intel_aes_decrypt_init_192(key, cx->expandedKey); \
- else \
- intel_aes_decrypt_init_256(key, cx->expandedKey); \
- } \
- } while (0)
diff --git a/security/nss/lib/freebl/intel-aes.s b/security/nss/lib/freebl/intel-aes.s
deleted file mode 100644
index a83529a48..000000000
--- a/security/nss/lib/freebl/intel-aes.s
+++ /dev/null
@@ -1,2488 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
- .text
-
-#define IV_OFFSET 16
-#define EXPANDED_KEY_OFFSET 48
-
-
-/* in %rdi : the key
- in %rsi : buffer for expanded key
-*/
- .type intel_aes_encrypt_init_128,@function
- .globl intel_aes_encrypt_init_128
- .align 16
-intel_aes_encrypt_init_128:
- movups (%rdi), %xmm1
- movups %xmm1, (%rsi)
- leaq 16(%rsi), %rsi
- xorl %eax, %eax
-
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x01 /* aeskeygenassist $0x01, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x02 /* aeskeygenassist $0x02, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x04 /* aeskeygenassist $0x04, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x08 /* aeskeygenassist $0x08, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x10 /* aeskeygenassist $0x10, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x20 /* aeskeygenassist $0x20, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x40 /* aeskeygenassist $0x40, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x80 /* aeskeygenassist $0x80, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x1b /* aeskeygenassist $0x1b, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x36 /* aeskeygenassist $0x36, %xmm1, %xmm2 */
- call key_expansion128
-
- ret
- .size intel_aes_encrypt_init_128, .-intel_aes_encrypt_init_128
-
-
-/* in %rdi : the key
- in %rsi : buffer for expanded key
-*/
- .type intel_aes_decrypt_init_128,@function
- .globl intel_aes_decrypt_init_128
- .align 16
-intel_aes_decrypt_init_128:
- movups (%rdi), %xmm1
- movups %xmm1, (%rsi)
- leaq 16(%rsi), %rsi
- xorl %eax, %eax
-
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x01 /* aeskeygenassist $0x01, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x02 /* aeskeygenassist $0x02, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x04 /* aeskeygenassist $0x04, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x08 /* aeskeygenassist $0x08, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x10 /* aeskeygenassist $0x10, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x20 /* aeskeygenassist $0x20, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x40 /* aeskeygenassist $0x40, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x80 /* aeskeygenassist $0x80, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x1b /* aeskeygenassist $0x1b, %xmm1, %xmm2 */
- call key_expansion128
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd1,0x36 /* aeskeygenassist $0x36, %xmm1, %xmm2 */
- call key_expansion128
-
- ret
- .size intel_aes_decrypt_init_128, .-intel_aes_decrypt_init_128
-
-
- .type key_expansion128,@function
- .align 16
-key_expansion128:
- movd %eax, %xmm3
- pshufd $0xff, %xmm2, %xmm2
- shufps $0x10, %xmm1, %xmm3
- pxor %xmm3, %xmm1
- shufps $0x8c, %xmm1, %xmm3
- pxor %xmm2, %xmm1
- pxor %xmm3, %xmm1
- movdqu %xmm1, (%rsi)
- addq $16, %rsi
- ret
- .size key_expansion128, .-key_expansion128
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_encrypt_ecb_128,@function
- .globl intel_aes_encrypt_ecb_128
- .align 16
-intel_aes_encrypt_ecb_128:
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 48(%rdi), %rdi
-
- movdqu (%rdi), %xmm2
- movdqu 160(%rdi), %xmm12
- xor %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
- jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
-2: movdqu (%r8, %rax), %xmm3
- movdqu 16(%r8, %rax), %xmm4
- movdqu 32(%r8, %rax), %xmm5
- movdqu 48(%r8, %rax), %xmm6
- movdqu 64(%r8, %rax), %xmm7
- movdqu 80(%r8, %rax), %xmm8
- movdqu 96(%r8, %rax), %xmm9
- movdqu 112(%r8, %rax), %xmm10
- pxor %xmm2, %xmm3
- pxor %xmm2, %xmm4
- pxor %xmm2, %xmm5
- pxor %xmm2, %xmm6
- pxor %xmm2, %xmm7
- pxor %xmm2, %xmm8
- pxor %xmm2, %xmm9
- pxor %xmm2, %xmm10
-
-// complete loop unrolling
- movdqu 16(%rdi), %xmm1
- movdqu 32(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 48(%rdi), %xmm1
- movdqu 64(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 80(%rdi), %xmm1
- movdqu 96(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 112(%rdi), %xmm1
- movdqu 128(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 144(%rdi), %xmm1
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xdc /* aesenclast %xmm12, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xe4 /* aesenclast %xmm12, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xec /* aesenclast %xmm12, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xf4 /* aesenclast %xmm12, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xfc /* aesenclast %xmm12, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdd,0xc4 /* aesenclast %xmm12, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdd,0xcc /* aesenclast %xmm12, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdd,0xd4 /* aesenclast %xmm12, %xmm10 */
-
- movdqu %xmm3, (%rsi, %rax)
- movdqu %xmm4, 16(%rsi, %rax)
- movdqu %xmm5, 32(%rsi, %rax)
- movdqu %xmm6, 48(%rsi, %rax)
- movdqu %xmm7, 64(%rsi, %rax)
- movdqu %xmm8, 80(%rsi, %rax)
- movdqu %xmm9, 96(%rsi, %rax)
- movdqu %xmm10, 112(%rsi, %rax)
-// addq $8*16, %rax
- addq $128, %rax
- cmpq %r11, %rax
- jbe 2b
-1: cmpq %rax, %r9
- je 5f
-
- movdqu 16(%rdi), %xmm3
- movdqu 32(%rdi), %xmm4
- movdqu 48(%rdi), %xmm5
- movdqu 64(%rdi), %xmm6
- movdqu 80(%rdi), %xmm7
- movdqu 96(%rdi), %xmm8
- movdqu 112(%rdi), %xmm9
- movdqu 128(%rdi), %xmm10
- movdqu 144(%rdi), %xmm11
-
-4: movdqu (%r8, %rax), %xmm1
- pxor %xmm2, %xmm1
- .byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcd /* aesenc %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xcc /* aesenclast %xmm12, %xmm1 */
- movdqu %xmm1, (%rsi, %rax)
- addq $16, %rax
- cmpq %rax, %r9
- jne 4b
-
-5: xor %eax, %eax
- ret
- .size intel_aes_encrypt_ecb_128, .-intel_aes_encrypt_ecb_128
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_decrypt_ecb_128,@function
- .globl intel_aes_decrypt_ecb_128
- .align 16
-intel_aes_decrypt_ecb_128:
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 48(%rdi), %rdi
-
- movdqu (%rdi), %xmm2
- movdqu 160(%rdi), %xmm12
- xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
- jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
-2: movdqu (%r8, %rax), %xmm3
- movdqu 16(%r8, %rax), %xmm4
- movdqu 32(%r8, %rax), %xmm5
- movdqu 48(%r8, %rax), %xmm6
- movdqu 64(%r8, %rax), %xmm7
- movdqu 80(%r8, %rax), %xmm8
- movdqu 96(%r8, %rax), %xmm9
- movdqu 112(%r8, %rax), %xmm10
- pxor %xmm12, %xmm3
- pxor %xmm12, %xmm4
- pxor %xmm12, %xmm5
- pxor %xmm12, %xmm6
- pxor %xmm12, %xmm7
- pxor %xmm12, %xmm8
- pxor %xmm12, %xmm9
- pxor %xmm12, %xmm10
-
-// complete loop unrolling
- movdqu 144(%rdi), %xmm1
- movdqu 128(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 112(%rdi), %xmm1
- movdqu 96(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 80(%rdi), %xmm1
- movdqu 64(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 48(%rdi), %xmm1
- movdqu 32(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 16(%rdi), %xmm1
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x0f,0x38,0xdf,0xda /* aesdeclast %xmm2, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdf,0xe2 /* aesdeclast %xmm2, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdf,0xea /* aesdeclast %xmm2, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdf,0xf2 /* aesdeclast %xmm2, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdf,0xfa /* aesdeclast %xmm2, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */
-
- movdqu %xmm3, (%rsi, %rax)
- movdqu %xmm4, 16(%rsi, %rax)
- movdqu %xmm5, 32(%rsi, %rax)
- movdqu %xmm6, 48(%rsi, %rax)
- movdqu %xmm7, 64(%rsi, %rax)
- movdqu %xmm8, 80(%rsi, %rax)
- movdqu %xmm9, 96(%rsi, %rax)
- movdqu %xmm10, 112(%rsi, %rax)
-// addq $8*16, %rax
- addq $128, %rax
- cmpq %r11, %rax
- jbe 2b
-1: cmpq %rax, %r9
- je 5f
-
- movdqu 16(%rdi), %xmm3
- movdqu 32(%rdi), %xmm4
- movdqu 48(%rdi), %xmm5
- movdqu 64(%rdi), %xmm6
- movdqu 80(%rdi), %xmm7
- movdqu 96(%rdi), %xmm8
- movdqu 112(%rdi), %xmm9
- movdqu 128(%rdi), %xmm10
- movdqu 144(%rdi), %xmm11
-
-4: movdqu (%r8, %rax), %xmm1
- pxor %xmm12, %xmm1
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm1 */
- movdqu %xmm1, (%rsi, %rax)
- addq $16, %rax
- cmpq %rax, %r9
- jne 4b
-
-5: xor %eax, %eax
- ret
- .size intel_aes_decrypt_ecb_128, .-intel_aes_decrypt_ecb_128
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_encrypt_cbc_128,@function
- .globl intel_aes_encrypt_cbc_128
- .align 16
-intel_aes_encrypt_cbc_128:
- testq %r9, %r9
- je 2f
-
-// leaq IV_OFFSET(%rdi), %rdx
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 16(%rdi), %rdx
- leaq 48(%rdi), %rdi
-
- movdqu (%rdx), %xmm0
- movdqu (%rdi), %xmm2
- movdqu 16(%rdi), %xmm3
- movdqu 32(%rdi), %xmm4
- movdqu 48(%rdi), %xmm5
- movdqu 64(%rdi), %xmm6
- movdqu 80(%rdi), %xmm7
- movdqu 96(%rdi), %xmm8
- movdqu 112(%rdi), %xmm9
- movdqu 128(%rdi), %xmm10
- movdqu 144(%rdi), %xmm11
- movdqu 160(%rdi), %xmm12
-
- xorl %eax, %eax
-1: movdqu (%r8, %rax), %xmm1
- pxor %xmm0, %xmm1
- pxor %xmm2, %xmm1
- .byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcd /* aesenc %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmma, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmmb, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xcc /* aesenclast %xmm12, %xmm1 */
- movdqu %xmm1, (%rsi, %rax)
- movdqa %xmm1, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
- jne 1b
-
- movdqu %xmm0, (%rdx)
-
-2: xor %eax, %eax
- ret
- .size intel_aes_encrypt_cbc_128, .-intel_aes_encrypt_cbc_128
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_decrypt_cbc_128,@function
- .globl intel_aes_decrypt_cbc_128
- .align 16
-intel_aes_decrypt_cbc_128:
-// leaq IV_OFFSET(%rdi), %rdx
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 16(%rdi), %rdx
- leaq 48(%rdi), %rdi
-
- movdqu (%rdx), %xmm0 /* iv */
- movdqu (%rdi), %xmm2 /* first key block */
- movdqu 160(%rdi), %xmm12 /* last key block */
- xorl %eax, %eax
- cmpq $128, %r9
- jb 1f
- leaq -128(%r9), %r11
-2: movdqu (%r8, %rax), %xmm3 /* 1st data block */
- movdqu 16(%r8, %rax), %xmm4 /* 2d data block */
- movdqu 32(%r8, %rax), %xmm5
- movdqu 48(%r8, %rax), %xmm6
- movdqu 64(%r8, %rax), %xmm7
- movdqu 80(%r8, %rax), %xmm8
- movdqu 96(%r8, %rax), %xmm9
- movdqu 112(%r8, %rax), %xmm10
- pxor %xmm12, %xmm3
- pxor %xmm12, %xmm4
- pxor %xmm12, %xmm5
- pxor %xmm12, %xmm6
- pxor %xmm12, %xmm7
- pxor %xmm12, %xmm8
- pxor %xmm12, %xmm9
- pxor %xmm12, %xmm10
-
-// complete loop unrolling
- movdqu 144(%rdi), %xmm1
- movdqu 128(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 112(%rdi), %xmm1
- movdqu 96(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 80(%rdi), %xmm1
- movdqu 64(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 48(%rdi), %xmm1
- movdqu 32(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 16(%rdi), %xmm1
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x0f,0x38,0xdf,0xda /* aesdeclast %xmm2, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdf,0xe2 /* aesdeclast %xmm2, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdf,0xea /* aesdeclast %xmm2, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdf,0xf2 /* aesdeclast %xmm2, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdf,0xfa /* aesdeclast %xmm2, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */
-
- pxor %xmm0, %xmm3
- movdqu (%r8, %rax), %xmm0
- pxor %xmm0, %xmm4
- movdqu 16(%r8, %rax), %xmm0
- pxor %xmm0, %xmm5
- movdqu 32(%r8, %rax), %xmm0
- pxor %xmm0, %xmm6
- movdqu 48(%r8, %rax), %xmm0
- pxor %xmm0, %xmm7
- movdqu 64(%r8, %rax), %xmm0
- pxor %xmm0, %xmm8
- movdqu 80(%r8, %rax), %xmm0
- pxor %xmm0, %xmm9
- movdqu 96(%r8, %rax), %xmm0
- pxor %xmm0, %xmm10
- movdqu 112(%r8, %rax), %xmm0
- movdqu %xmm3, (%rsi, %rax)
- movdqu %xmm4, 16(%rsi, %rax)
- movdqu %xmm5, 32(%rsi, %rax)
- movdqu %xmm6, 48(%rsi, %rax)
- movdqu %xmm7, 64(%rsi, %rax)
- movdqu %xmm8, 80(%rsi, %rax)
- movdqu %xmm9, 96(%rsi, %rax)
- movdqu %xmm10, 112(%rsi, %rax)
- addq $128, %rax
- cmpq %r11, %rax
- jbe 2b
-1: cmpq %rax, %r9
- je 5f
-
- movdqu 16(%rdi), %xmm3
- movdqu 32(%rdi), %xmm4
- movdqu 48(%rdi), %xmm5
- movdqu 64(%rdi), %xmm6
- movdqu 80(%rdi), %xmm7
- movdqu 96(%rdi), %xmm8
- movdqu 112(%rdi), %xmm9
- movdqu 128(%rdi), %xmm10
- movdqu 144(%rdi), %xmm11
-
-4: movdqu (%r8, %rax), %xmm1
- movdqa %xmm1, %xmm13
- pxor %xmm12, %xmm1
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm1 */
- pxor %xmm0, %xmm1
- movdqu %xmm1, (%rsi, %rax)
- movdqa %xmm13, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
- jne 4b
-
-5: movdqu %xmm0, (%rdx)
-
- xor %eax, %eax
- ret
- .size intel_aes_decrypt_cbc_128, .-intel_aes_decrypt_cbc_128
-
-/* in %rdi : the key
- in %rsi : buffer for expanded key
-*/
- .type intel_aes_encrypt_init_192,@function
- .globl intel_aes_encrypt_init_192
- .align 16
-intel_aes_encrypt_init_192:
- movdqu (%rdi), %xmm1
- movq 16(%rdi), %xmm3
- movdqu %xmm1, (%rsi)
- movq %xmm3, 16(%rsi)
- leaq 24(%rsi), %rsi
-
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x01 /* aeskeygenassist $0x01, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x02 /* aeskeygenassist $0x02, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x04 /* aeskeygenassist $0x04, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x08 /* aeskeygenassist $0x08, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x10 /* aeskeygenassist $0x10, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x20 /* aeskeygenassist $0x20, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x40 /* aeskeygenassist $0x40, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x80 /* aeskeygenassist $0x80, %xmm3, %xmm2 */
- call key_expansion192
-
- ret
- .size intel_aes_encrypt_init_192, .-intel_aes_encrypt_init_192
-
-
-/* in %rdi : the key
- in %rsi : buffer for expanded key
-*/
- .type intel_aes_decrypt_init_192,@function
- .globl intel_aes_decrypt_init_192
- .align 16
-intel_aes_decrypt_init_192:
- movdqu (%rdi), %xmm1
- movq 16(%rdi), %xmm3
- movdqu %xmm1, (%rsi)
- movq %xmm3, 16(%rsi)
- leaq 24(%rsi), %rsi
-
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x01 /* aeskeygenassist $0x01, %xmm3, %xmm2 */
- call key_expansion192
- movups -32(%rsi), %xmm2
- movups -16(%rsi), %xmm4
- .byte 0x66,0x0f,0x38,0xdb,0xd2 /* aesimc %xmm2, %xmm2 */
- .byte 0x66,0x0f,0x38,0xdb,0xe4 /* aesimc %xmm4, %xmm4 */
- movups %xmm2, -32(%rsi)
- movups %xmm4, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x02 /* aeskeygenassist $0x02, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -24(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x04 /* aeskeygenassist $0x04, %xmm3, %xmm2 */
- call key_expansion192
- movups -32(%rsi), %xmm2
- movups -16(%rsi), %xmm4
- .byte 0x66,0x0f,0x38,0xdb,0xd2 /* aesimc %xmm2, %xmm2 */
- .byte 0x66,0x0f,0x38,0xdb,0xe4 /* aesimc %xmm4, %xmm4 */
- movups %xmm2, -32(%rsi)
- movups %xmm4, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x08 /* aeskeygenassist $0x08, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -24(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x10 /* aeskeygenassist $0x10, %xmm3, %xmm2 */
- call key_expansion192
- movups -32(%rsi), %xmm2
- movups -16(%rsi), %xmm4
- .byte 0x66,0x0f,0x38,0xdb,0xd2 /* aesimc %xmm2, %xmm2 */
- .byte 0x66,0x0f,0x38,0xdb,0xe4 /* aesimc %xmm4, %xmm4 */
- movups %xmm2, -32(%rsi)
- movups %xmm4, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x20 /* aeskeygenassist $0x20, %xmm3, %xmm2 */
- call key_expansion192
- .byte 0x66,0x0f,0x38,0xdb,0xd1 /* aesimc %xmm1, %xmm2 */
- movups %xmm2, -24(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x40 /* aeskeygenassist $0x40, %xmm3, %xmm2 */
- call key_expansion192
- movups -32(%rsi), %xmm2
- movups -16(%rsi), %xmm4
- .byte 0x66,0x0f,0x38,0xdb,0xd2 /* aesimc %xmm2, %xmm2 */
- .byte 0x66,0x0f,0x38,0xdb,0xe4 /* aesimc %xmm4, %xmm4 */
- movups %xmm2, -32(%rsi)
- movups %xmm4, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x80 /* aeskeygenassist $0x80, %xmm3, %xmm2 */
- call key_expansion192
-
- ret
- .size intel_aes_decrypt_init_192, .-intel_aes_decrypt_init_192
-
-
- .type key_expansion192,@function
- .align 16
-key_expansion192:
- pshufd $0x55, %xmm2, %xmm2
- xor %eax, %eax
- movd %eax, %xmm4
- shufps $0x10, %xmm1, %xmm4
- pxor %xmm4, %xmm1
- shufps $0x8c, %xmm1, %xmm4
- pxor %xmm2, %xmm1
- pxor %xmm4, %xmm1
- movdqu %xmm1, (%rsi)
- addq $16, %rsi
-
- pshufd $0xff, %xmm1, %xmm4
- movd %eax, %xmm5
- shufps $0x00, %xmm3, %xmm5
- shufps $0x08, %xmm3, %xmm5
- pxor %xmm4, %xmm3
- pxor %xmm5, %xmm3
- movq %xmm3, (%rsi)
- addq $8, %rsi
- ret
- .size key_expansion192, .-key_expansion192
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_encrypt_ecb_192,@function
- .globl intel_aes_encrypt_ecb_192
- .align 16
-intel_aes_encrypt_ecb_192:
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 48(%rdi), %rdi
-
- movdqu (%rdi), %xmm2
- movdqu 192(%rdi), %xmm14
- xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
- jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
-2: movdqu (%r8, %rax), %xmm3
- movdqu 16(%r8, %rax), %xmm4
- movdqu 32(%r8, %rax), %xmm5
- movdqu 48(%r8, %rax), %xmm6
- movdqu 64(%r8, %rax), %xmm7
- movdqu 80(%r8, %rax), %xmm8
- movdqu 96(%r8, %rax), %xmm9
- movdqu 112(%r8, %rax), %xmm10
- pxor %xmm2, %xmm3
- pxor %xmm2, %xmm4
- pxor %xmm2, %xmm5
- pxor %xmm2, %xmm6
- pxor %xmm2, %xmm7
- pxor %xmm2, %xmm8
- pxor %xmm2, %xmm9
- pxor %xmm2, %xmm10
-
-// complete loop unrolling
- movdqu 16(%rdi), %xmm1
- movdqu 32(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 48(%rdi), %xmm1
- movdqu 64(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 80(%rdi), %xmm1
- movdqu 96(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 112(%rdi), %xmm1
- movdqu 128(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 144(%rdi), %xmm1
- movdqu 160(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 176(%rdi), %xmm1
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xde /* aesenclast %xmm14, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xe6 /* aesenclast %xmm14, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xee /* aesenclast %xmm14, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xf6 /* aesenclast %xmm14, %xmm7 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xfe /* aesenclast %xmm14, %xmm3 */
- .byte 0x66,0x45,0x0f,0x38,0xdd,0xc6 /* aesenclast %xmm14, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdd,0xce /* aesenclast %xmm14, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdd,0xd6 /* aesenclast %xmm14, %xmm10 */
-
- movdqu %xmm3, (%rsi, %rax)
- movdqu %xmm4, 16(%rsi, %rax)
- movdqu %xmm5, 32(%rsi, %rax)
- movdqu %xmm6, 48(%rsi, %rax)
- movdqu %xmm7, 64(%rsi, %rax)
- movdqu %xmm8, 80(%rsi, %rax)
- movdqu %xmm9, 96(%rsi, %rax)
- movdqu %xmm10, 112(%rsi, %rax)
-// addq $8*16, %rax
- addq $128, %rax
- cmpq %r11, %rax
- jbe 2b
-1: cmpq %rax, %r9
- je 5f
-
- movdqu 16(%rdi), %xmm3
- movdqu 32(%rdi), %xmm4
- movdqu 48(%rdi), %xmm5
- movdqu 64(%rdi), %xmm6
- movdqu 80(%rdi), %xmm7
- movdqu 96(%rdi), %xmm8
- movdqu 112(%rdi), %xmm9
- movdqu 128(%rdi), %xmm10
- movdqu 144(%rdi), %xmm11
- movdqu 160(%rdi), %xmm12
- movdqu 176(%rdi), %xmm13
-
-4: movdqu (%r8, %rax), %xmm1
- pxor %xmm2, %xmm1
- .byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcd /* aesenc %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcc /* aesenc %xmm12, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcd /* aesenc %xmm13, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xce /* aesenclast %xmm14, %xmm1 */
- movdqu %xmm1, (%rsi, %rax)
- addq $16, %rax
- cmpq %rax, %r9
- jne 4b
-
-5: xor %eax, %eax
- ret
- .size intel_aes_encrypt_ecb_192, .-intel_aes_encrypt_ecb_192
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_decrypt_ecb_192,@function
- .globl intel_aes_decrypt_ecb_192
- .align 16
-intel_aes_decrypt_ecb_192:
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 48(%rdi), %rdi
-
- movdqu (%rdi), %xmm2
- movdqu 192(%rdi), %xmm14
- xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
- jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
-2: movdqu (%r8, %rax), %xmm3
- movdqu 16(%r8, %rax), %xmm4
- movdqu 32(%r8, %rax), %xmm5
- movdqu 48(%r8, %rax), %xmm6
- movdqu 64(%r8, %rax), %xmm7
- movdqu 80(%r8, %rax), %xmm8
- movdqu 96(%r8, %rax), %xmm9
- movdqu 112(%r8, %rax), %xmm10
- pxor %xmm14, %xmm3
- pxor %xmm14, %xmm4
- pxor %xmm14, %xmm5
- pxor %xmm14, %xmm6
- pxor %xmm14, %xmm7
- pxor %xmm14, %xmm8
- pxor %xmm14, %xmm9
- pxor %xmm14, %xmm10
-
-// complete loop unrolling
- movdqu 176(%rdi), %xmm1
- movdqu 160(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 144(%rdi), %xmm1
- movdqu 128(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 112(%rdi), %xmm1
- movdqu 96(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 80(%rdi), %xmm1
- movdqu 64(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 48(%rdi), %xmm1
- movdqu 32(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 16(%rdi), %xmm1
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x0f,0x38,0xdf,0xda /* aesdeclast %xmm2, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdf,0xe2 /* aesdeclast %xmm2, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdf,0xea /* aesdeclast %xmm2, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdf,0xf2 /* aesdeclast %xmm2, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdf,0xfa /* aesdeclast %xmm2, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */
-
- movdqu %xmm3, (%rsi, %rax)
- movdqu %xmm4, 16(%rsi, %rax)
- movdqu %xmm5, 32(%rsi, %rax)
- movdqu %xmm6, 48(%rsi, %rax)
- movdqu %xmm7, 64(%rsi, %rax)
- movdqu %xmm8, 80(%rsi, %rax)
- movdqu %xmm9, 96(%rsi, %rax)
- movdqu %xmm10, 112(%rsi, %rax)
-// addq $8*16, %rax
- addq $128, %rax
- cmpq %r11, %rax
- jbe 2b
-1: cmpq %rax, %r9
- je 5f
-
- movdqu 16(%rdi), %xmm3
- movdqu 32(%rdi), %xmm4
- movdqu 48(%rdi), %xmm5
- movdqu 64(%rdi), %xmm6
- movdqu 80(%rdi), %xmm7
- movdqu 96(%rdi), %xmm8
- movdqu 112(%rdi), %xmm9
- movdqu 128(%rdi), %xmm10
- movdqu 144(%rdi), %xmm11
- movdqu 160(%rdi), %xmm12
- movdqu 176(%rdi), %xmm13
-
-4: movdqu (%r8, %rax), %xmm1
- pxor %xmm14, %xmm1
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcd /* aesdec %xmm13, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcc /* aesdec %xmm12, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm1 */
- movdqu %xmm1, (%rsi, %rax)
- addq $16, %rax
- cmpq %rax, %r9
- jne 4b
-
-5: xor %eax, %eax
- ret
- .size intel_aes_decrypt_ecb_192, .-intel_aes_decrypt_ecb_192
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_encrypt_cbc_192,@function
- .globl intel_aes_encrypt_cbc_192
- .align 16
-intel_aes_encrypt_cbc_192:
- testq %r9, %r9
- je 2f
-
-// leaq IV_OFFSET(%rdi), %rdx
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 16(%rdi), %rdx
- leaq 48(%rdi), %rdi
-
- movdqu (%rdx), %xmm0
- movdqu (%rdi), %xmm2
- movdqu 16(%rdi), %xmm3
- movdqu 32(%rdi), %xmm4
- movdqu 48(%rdi), %xmm5
- movdqu 64(%rdi), %xmm6
- movdqu 80(%rdi), %xmm7
- movdqu 96(%rdi), %xmm8
- movdqu 112(%rdi), %xmm9
- movdqu 128(%rdi), %xmm10
- movdqu 144(%rdi), %xmm11
- movdqu 160(%rdi), %xmm12
- movdqu 176(%rdi), %xmm13
- movdqu 192(%rdi), %xmm14
-
- xorl %eax, %eax
-1: movdqu (%r8, %rax), %xmm1
- pxor %xmm0, %xmm1
- pxor %xmm2, %xmm1
- .byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcd /* aesenc %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcc /* aesenc %xmm12, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcd /* aesenc %xmm13, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xce /* aesenclast %xmm14, %xmm1 */
- movdqu %xmm1, (%rsi, %rax)
- movdqa %xmm1, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
- jne 1b
-
- movdqu %xmm0, (%rdx)
-
-2: xor %eax, %eax
- ret
- .size intel_aes_encrypt_cbc_192, .-intel_aes_encrypt_cbc_192
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_decrypt_cbc_192,@function
- .globl intel_aes_decrypt_cbc_192
- .align 16
-intel_aes_decrypt_cbc_192:
- leaq 16(%rdi), %rdx
- leaq 48(%rdi), %rdi
-
- movdqu (%rdx), %xmm0
- movdqu (%rdi), %xmm2
- movdqu 192(%rdi), %xmm14
- xorl %eax, %eax
- cmpq $128, %r9
- jb 1f
- leaq -128(%r9), %r11
-2: movdqu (%r8, %rax), %xmm3
- movdqu 16(%r8, %rax), %xmm4
- movdqu 32(%r8, %rax), %xmm5
- movdqu 48(%r8, %rax), %xmm6
- movdqu 64(%r8, %rax), %xmm7
- movdqu 80(%r8, %rax), %xmm8
- movdqu 96(%r8, %rax), %xmm9
- movdqu 112(%r8, %rax), %xmm10
- pxor %xmm14, %xmm3
- pxor %xmm14, %xmm4
- pxor %xmm14, %xmm5
- pxor %xmm14, %xmm6
- pxor %xmm14, %xmm7
- pxor %xmm14, %xmm8
- pxor %xmm14, %xmm9
- pxor %xmm14, %xmm10
-
-// complete loop unrolling
- movdqu 176(%rdi), %xmm1
- movdqu 160(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 144(%rdi), %xmm1
- movdqu 128(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 112(%rdi), %xmm1
- movdqu 96(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 80(%rdi), %xmm1
- movdqu 64(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 48(%rdi), %xmm1
- movdqu 32(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 16(%rdi), %xmm1
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x0f,0x38,0xdf,0xda /* aesdeclast %xmm2, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdf,0xe2 /* aesdeclast %xmm2, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdf,0xea /* aesdeclast %xmm2, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdf,0xf2 /* aesdeclast %xmm2, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdf,0xfa /* aesdeclast %xmm2, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */
-
- pxor %xmm0, %xmm3
- movdqu (%r8, %rax), %xmm0
- pxor %xmm0, %xmm4
- movdqu 16(%r8, %rax), %xmm0
- pxor %xmm0, %xmm5
- movdqu 32(%r8, %rax), %xmm0
- pxor %xmm0, %xmm6
- movdqu 48(%r8, %rax), %xmm0
- pxor %xmm0, %xmm7
- movdqu 64(%r8, %rax), %xmm0
- pxor %xmm0, %xmm8
- movdqu 80(%r8, %rax), %xmm0
- pxor %xmm0, %xmm9
- movdqu 96(%r8, %rax), %xmm0
- pxor %xmm0, %xmm10
- movdqu 112(%r8, %rax), %xmm0
- movdqu %xmm3, (%rsi, %rax)
- movdqu %xmm4, 16(%rsi, %rax)
- movdqu %xmm5, 32(%rsi, %rax)
- movdqu %xmm6, 48(%rsi, %rax)
- movdqu %xmm7, 64(%rsi, %rax)
- movdqu %xmm8, 80(%rsi, %rax)
- movdqu %xmm9, 96(%rsi, %rax)
- movdqu %xmm10, 112(%rsi, %rax)
- addq $128, %rax
- cmpq %r11, %rax
- jbe 2b
-1: cmpq %rax, %r9
- je 5f
-
- movdqu 16(%rdi), %xmm3
- movdqu 32(%rdi), %xmm4
- movdqu 48(%rdi), %xmm5
- movdqu 64(%rdi), %xmm6
- movdqu 80(%rdi), %xmm7
- movdqu 96(%rdi), %xmm8
- movdqu 112(%rdi), %xmm9
- movdqu 128(%rdi), %xmm10
- movdqu 144(%rdi), %xmm11
- movdqu 160(%rdi), %xmm12
- movdqu 176(%rdi), %xmm13
-
-4: movdqu (%r8, %rax), %xmm1
- movdqa %xmm1, %xmm15
- pxor %xmm14, %xmm1
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcd /* aesdec %xmm13, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcc /* aesdec %xmm12, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm1 */
- pxor %xmm0, %xmm1
- movdqu %xmm1, (%rsi, %rax)
- movdqa %xmm15, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
- jne 4b
-
-5: movdqu %xmm0, (%rdx)
-
- xor %eax, %eax
- ret
- .size intel_aes_decrypt_cbc_192, .-intel_aes_decrypt_cbc_192
-
-/* in %rdi : the key
- in %rsi : buffer for expanded key
-*/
- .type intel_aes_encrypt_init_256,@function
- .globl intel_aes_encrypt_init_256
- .align 16
-intel_aes_encrypt_init_256:
- movdqu (%rdi), %xmm1
- movdqu 16(%rdi), %xmm3
- movdqu %xmm1, (%rsi)
- movdqu %xmm3, 16(%rsi)
- leaq 32(%rsi), %rsi
- xor %eax, %eax
-
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x01 /* aeskeygenassist $0x01, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x02 /* aeskeygenassist $0x02, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x04 /* aeskeygenassist $0x04, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x08 /* aeskeygenassist $0x08, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x10 /* aeskeygenassist $0x10, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x20 /* aeskeygenassist $0x20, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x40 /* aeskeygenassist $0x40, %xmm3, %xmm2 */
- pxor %xmm6, %xmm6
- pshufd $0xff, %xmm2, %xmm2
- shufps $0x10, %xmm1, %xmm6
- pxor %xmm6, %xmm1
- shufps $0x8c, %xmm1, %xmm6
- pxor %xmm2, %xmm1
- pxor %xmm6, %xmm1
- movdqu %xmm1, (%rsi)
-
- ret
- .size intel_aes_encrypt_init_256, .-intel_aes_encrypt_init_256
-
-
-/* in %rdi : the key
- in %rsi : buffer for expanded key
-*/
- .type intel_aes_decrypt_init_256,@function
- .globl intel_aes_decrypt_init_256
- .align 16
-intel_aes_decrypt_init_256:
- movdqu (%rdi), %xmm1
- movdqu 16(%rdi), %xmm3
- movdqu %xmm1, (%rsi)
- .byte 0x66,0x0f,0x38,0xdb,0xe3 /* aesimc %xmm3, %xmm4 */
- movdqu %xmm4, 16(%rsi)
- leaq 32(%rsi), %rsi
- xor %eax, %eax
-
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x01 /* aeskeygenassist $0x01, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x38,0xdb,0xe1 /* aesimc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdb,0xeb /* aesimc %xmm3, %xmm5 */
- movdqu %xmm4, -32(%rsi)
- movdqu %xmm5, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x02 /* aeskeygenassist $0x02, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x38,0xdb,0xe1 /* aesimc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdb,0xeb /* aesimc %xmm3, %xmm5 */
- movdqu %xmm4, -32(%rsi)
- movdqu %xmm5, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x04 /* aeskeygenassist $0x04, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x38,0xdb,0xe1 /* aesimc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdb,0xeb /* aesimc %xmm3, %xmm5 */
- movdqu %xmm4, -32(%rsi)
- movdqu %xmm5, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x08 /* aeskeygenassist $0x08, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x38,0xdb,0xe1 /* aesimc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdb,0xeb /* aesimc %xmm3, %xmm5 */
- movdqu %xmm4, -32(%rsi)
- movdqu %xmm5, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x10 /* aeskeygenassist $0x10, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x38,0xdb,0xe1 /* aesimc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdb,0xeb /* aesimc %xmm3, %xmm5 */
- movdqu %xmm4, -32(%rsi)
- movdqu %xmm5, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x20 /* aeskeygenassist $0x20, %xmm3, %xmm2 */
- call key_expansion256
- .byte 0x66,0x0f,0x38,0xdb,0xe1 /* aesimc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdb,0xeb /* aesimc %xmm3, %xmm5 */
- movdqu %xmm4, -32(%rsi)
- movdqu %xmm5, -16(%rsi)
- .byte 0x66,0x0f,0x3a,0xdf,0xd3,0x40 /* aeskeygenassist $0x40, %xmm3, %xmm2 */
- pxor %xmm6, %xmm6
- pshufd $0xff, %xmm2, %xmm2
- shufps $0x10, %xmm1, %xmm6
- pxor %xmm6, %xmm1
- shufps $0x8c, %xmm1, %xmm6
- pxor %xmm2, %xmm1
- pxor %xmm6, %xmm1
- movdqu %xmm1, (%rsi)
-
- ret
- .size intel_aes_decrypt_init_256, .-intel_aes_decrypt_init_256
-
-
- .type key_expansion256,@function
- .align 16
-key_expansion256:
- movd %eax, %xmm6
- pshufd $0xff, %xmm2, %xmm2
- shufps $0x10, %xmm1, %xmm6
- pxor %xmm6, %xmm1
- shufps $0x8c, %xmm1, %xmm6
- pxor %xmm2, %xmm1
- pxor %xmm6, %xmm1
- movdqu %xmm1, (%rsi)
-
- addq $16, %rsi
- .byte 0x66,0x0f,0x3a,0xdf,0xe1,0x00 /* aeskeygenassist $0, %xmm1, %xmm4 */
- pshufd $0xaa, %xmm4, %xmm4
- shufps $0x10, %xmm3, %xmm6
- pxor %xmm6, %xmm3
- shufps $0x8c, %xmm3, %xmm6
- pxor %xmm4, %xmm3
- pxor %xmm6, %xmm3
- movdqu %xmm3, (%rsi)
- addq $16, %rsi
- ret
- .size key_expansion256, .-key_expansion256
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_encrypt_ecb_256,@function
- .globl intel_aes_encrypt_ecb_256
- .align 16
-intel_aes_encrypt_ecb_256:
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 48(%rdi), %rdi
-
- movdqu (%rdi), %xmm2
- movdqu 224(%rdi), %xmm15
- xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
- jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
-2: movdqu (%r8, %rax), %xmm3
- movdqu 16(%r8, %rax), %xmm4
- movdqu 32(%r8, %rax), %xmm5
- movdqu 48(%r8, %rax), %xmm6
- movdqu 64(%r8, %rax), %xmm7
- movdqu 80(%r8, %rax), %xmm8
- movdqu 96(%r8, %rax), %xmm9
- movdqu 112(%r8, %rax), %xmm10
- pxor %xmm2, %xmm3
- pxor %xmm2, %xmm4
- pxor %xmm2, %xmm5
- pxor %xmm2, %xmm6
- pxor %xmm2, %xmm7
- pxor %xmm2, %xmm8
- pxor %xmm2, %xmm9
- pxor %xmm2, %xmm10
-
-// complete loop unrolling
- movdqu 16(%rdi), %xmm1
- movdqu 32(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 48(%rdi), %xmm1
- movdqu 64(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 80(%rdi), %xmm1
- movdqu 96(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 112(%rdi), %xmm1
- movdqu 128(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 144(%rdi), %xmm1
- movdqu 160(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 176(%rdi), %xmm1
- movdqu 192(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xdb /* aesenc %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xe3 /* aesenc %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xeb /* aesenc %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xf3 /* aesenc %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xfb /* aesenc %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xc3 /* aesenc %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdc,0xd3 /* aesenc %xmm11, %xmm10 */
-
- movdqu 208(%rdi), %xmm1
- .byte 0x66,0x0f,0x38,0xdc,0xd9 /* aesenc %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdc,0xe1 /* aesenc %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdc,0xe9 /* aesenc %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdc,0xf1 /* aesenc %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdc,0xf9 /* aesenc %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc1 /* aesenc %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdc,0xd1 /* aesenc %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xdf /* aesenclast %xmm15, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xe7 /* aesenclast %xmm15, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xef /* aesenclast %xmm15, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xf7 /* aesenclast %xmm15, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xff /* aesenclast %xmm15, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xdd,0xc7 /* aesenclast %xmm15, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xdd,0xcf /* aesenclast %xmm15, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xdd,0xd7 /* aesenclast %xmm15, %xmm10 */
-
- movdqu %xmm3, (%rsi, %rax)
- movdqu %xmm4, 16(%rsi, %rax)
- movdqu %xmm5, 32(%rsi, %rax)
- movdqu %xmm6, 48(%rsi, %rax)
- movdqu %xmm7, 64(%rsi, %rax)
- movdqu %xmm8, 80(%rsi, %rax)
- movdqu %xmm9, 96(%rsi, %rax)
- movdqu %xmm10, 112(%rsi, %rax)
-// addq $8*16, %rax
- addq $128, %rax
- cmpq %r11, %rax
- jbe 2b
-1: cmpq %rax, %r9
- je 5f
-
- movdqu (%rdi), %xmm8
- movdqu 16(%rdi), %xmm2
- movdqu 32(%rdi), %xmm3
- movdqu 48(%rdi), %xmm4
- movdqu 64(%rdi), %xmm5
- movdqu 80(%rdi), %xmm6
- movdqu 96(%rdi), %xmm7
- movdqu 128(%rdi), %xmm9
- movdqu 144(%rdi), %xmm10
- movdqu 160(%rdi), %xmm11
- movdqu 176(%rdi), %xmm12
- movdqu 192(%rdi), %xmm13
- movdqu 208(%rdi), %xmm14
-
-4: movdqu (%r8, %rax), %xmm1
- pxor %xmm8, %xmm1
- movdqu 112(%rdi), %xmm8
- .byte 0x66,0x0f,0x38,0xdc,0xca /* aesenc %xmm2, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcd /* aesenc %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */
- movdqu (%rdi), %xmm8
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcc /* aesenc %xmm12, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcd /* aesenc %xmm13, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xce /* aesenc %xmm14, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xcf /* aesenclast %xmm15, %xmm1 */
- movdqu %xmm1, (%rsi, %rax)
- addq $16, %rax
- cmpq %rax, %r9
- jne 4b
-
-5: xor %eax, %eax
- ret
- .size intel_aes_encrypt_ecb_256, .-intel_aes_encrypt_ecb_256
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_decrypt_ecb_256,@function
- .globl intel_aes_decrypt_ecb_256
- .align 16
-intel_aes_decrypt_ecb_256:
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 48(%rdi), %rdi
-
- movdqu (%rdi), %xmm2
- movdqu 224(%rdi), %xmm15
- xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
- jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
-2: movdqu (%r8, %rax), %xmm3
- movdqu 16(%r8, %rax), %xmm4
- movdqu 32(%r8, %rax), %xmm5
- movdqu 48(%r8, %rax), %xmm6
- movdqu 64(%r8, %rax), %xmm7
- movdqu 80(%r8, %rax), %xmm8
- movdqu 96(%r8, %rax), %xmm9
- movdqu 112(%r8, %rax), %xmm10
- pxor %xmm15, %xmm3
- pxor %xmm15, %xmm4
- pxor %xmm15, %xmm5
- pxor %xmm15, %xmm6
- pxor %xmm15, %xmm7
- pxor %xmm15, %xmm8
- pxor %xmm15, %xmm9
- pxor %xmm15, %xmm10
-
-// complete loop unrolling
- movdqu 208(%rdi), %xmm1
- movdqu 192(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 176(%rdi), %xmm1
- movdqu 160(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 144(%rdi), %xmm1
- movdqu 128(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 112(%rdi), %xmm1
- movdqu 96(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 80(%rdi), %xmm1
- movdqu 64(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 48(%rdi), %xmm1
- movdqu 32(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 16(%rdi), %xmm1
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x0f,0x38,0xdf,0xda /* aesdeclast %xmm2, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdf,0xe2 /* aesdeclast %xmm2, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdf,0xea /* aesdeclast %xmm2, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdf,0xf2 /* aesdeclast %xmm2, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdf,0xfa /* aesdeclast %xmm2, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */
-
- movdqu %xmm3, (%rsi, %rax)
- movdqu %xmm4, 16(%rsi, %rax)
- movdqu %xmm5, 32(%rsi, %rax)
- movdqu %xmm6, 48(%rsi, %rax)
- movdqu %xmm7, 64(%rsi, %rax)
- movdqu %xmm8, 80(%rsi, %rax)
- movdqu %xmm9, 96(%rsi, %rax)
- movdqu %xmm10, 112(%rsi, %rax)
-// addq $8*16, %rax
- addq $128, %rax
- cmpq %r11, %rax
- jbe 2b
-1: cmpq %rax, %r9
- je 5f
-
- movdqu 16(%rdi), %xmm2
- movdqu 32(%rdi), %xmm3
- movdqu 48(%rdi), %xmm4
- movdqu 64(%rdi), %xmm5
- movdqu 80(%rdi), %xmm6
- movdqu 96(%rdi), %xmm7
- movdqu 112(%rdi), %xmm8
- movdqu 128(%rdi), %xmm9
- movdqu 144(%rdi), %xmm10
- movdqu 160(%rdi), %xmm11
- movdqu 176(%rdi), %xmm12
- movdqu 192(%rdi), %xmm13
- movdqu 208(%rdi), %xmm14
-
-4: movdqu (%r8, %rax), %xmm1
- pxor %xmm15, %xmm1
- .byte 0x66,0x41,0x0f,0x38,0xde,0xce /* aesdec %xmm14, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcd /* aesdec %xmm13, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcc /* aesdec %xmm12, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */
- movdqu (%rdi), %xmm8
- .byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xca /* aesdec %xmm2, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdf,0xc8 /* aesdeclast %xmm8, %xmm1 */
- movdqu 112(%rdi), %xmm8
- movdqu %xmm1, (%rsi, %rax)
- addq $16, %rax
- cmpq %rax, %r9
- jne 4b
-
-5: xor %eax, %eax
- ret
- .size intel_aes_decrypt_ecb_256, .-intel_aes_decrypt_ecb_256
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_encrypt_cbc_256,@function
- .globl intel_aes_encrypt_cbc_256
- .align 16
-intel_aes_encrypt_cbc_256:
- testq %r9, %r9
- je 2f
-
-// leaq IV_OFFSET(%rdi), %rdx
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 16(%rdi), %rdx
- leaq 48(%rdi), %rdi
-
- movdqu (%rdx), %xmm0
- movdqu (%rdi), %xmm8
- movdqu 16(%rdi), %xmm2
- movdqu 32(%rdi), %xmm3
- movdqu 48(%rdi), %xmm4
- movdqu 64(%rdi), %xmm5
- movdqu 80(%rdi), %xmm6
- movdqu 96(%rdi), %xmm7
- movdqu 128(%rdi), %xmm9
- movdqu 144(%rdi), %xmm10
- movdqu 160(%rdi), %xmm11
- movdqu 176(%rdi), %xmm12
- movdqu 192(%rdi), %xmm13
- movdqu 208(%rdi), %xmm14
- movdqu 224(%rdi), %xmm15
-
- xorl %eax, %eax
-1: movdqu (%r8, %rax), %xmm1
- pxor %xmm0, %xmm1
- pxor %xmm8, %xmm1
- movdqu 112(%rdi), %xmm8
- .byte 0x66,0x0f,0x38,0xdc,0xca /* aesenc %xmm2, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcb /* aesenc %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcc /* aesenc %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcd /* aesenc %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xce /* aesenc %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xdc,0xcf /* aesenc %xmm7, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc8 /* aesenc %xmm8, %xmm1 */
- movdqu (%rdi), %xmm8
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xc9 /* aesenc %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xca /* aesenc %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcc /* aesenc %xmm12, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xcd /* aesenc %xmm13, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdc,0xce /* aesenc %xmm14, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdd,0xcf /* aesenclast %xmm15, %xmm1 */
- movdqu %xmm1, (%rsi, %rax)
- movdqa %xmm1, %xmm0
- addq $16, %rax
- cmpq %rax, %r9
- jne 1b
-
- movdqu %xmm0, (%rdx)
-
-2: xor %eax, %eax
- ret
- .size intel_aes_encrypt_cbc_256, .-intel_aes_encrypt_cbc_256
-
-
-/* in %rdi : cx - context
- in %rsi : output - pointer to output buffer
- in %rdx : outputLen - pointer to variable for length of output
- (filled by caller)
- in %rcx : maxOutputLen - length of output buffer
- in %r8 : input - pointer to input buffer
- in %r9 : inputLen - length of input buffer
- on stack: blocksize - AES blocksize (always 16, unused)
-*/
- .type intel_aes_decrypt_cbc_256,@function
- .globl intel_aes_decrypt_cbc_256
- .align 16
-intel_aes_decrypt_cbc_256:
-// leaq IV_OFFSET(%rdi), %rdx
-// leaq EXPANDED_KEY_OFFSET(%rdi), %rdi
- leaq 16(%rdi), %rdx
- leaq 48(%rdi), %rdi
-
- movdqu (%rdx), %xmm0
- movdqu (%rdi), %xmm2
- movdqu 224(%rdi), %xmm15
- xorl %eax, %eax
-// cmpq $8*16, %r9
- cmpq $128, %r9
- jb 1f
-// leaq -8*16(%r9), %r11
- leaq -128(%r9), %r11
-2: movdqu (%r8, %rax), %xmm3
- movdqu 16(%r8, %rax), %xmm4
- movdqu 32(%r8, %rax), %xmm5
- movdqu 48(%r8, %rax), %xmm6
- movdqu 64(%r8, %rax), %xmm7
- movdqu 80(%r8, %rax), %xmm8
- movdqu 96(%r8, %rax), %xmm9
- movdqu 112(%r8, %rax), %xmm10
- pxor %xmm15, %xmm3
- pxor %xmm15, %xmm4
- pxor %xmm15, %xmm5
- pxor %xmm15, %xmm6
- pxor %xmm15, %xmm7
- pxor %xmm15, %xmm8
- pxor %xmm15, %xmm9
- pxor %xmm15, %xmm10
-
-// complete loop unrolling
- movdqu 208(%rdi), %xmm1
- movdqu 192(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 176(%rdi), %xmm1
- movdqu 160(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 144(%rdi), %xmm1
- movdqu 128(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 112(%rdi), %xmm1
- movdqu 96(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 80(%rdi), %xmm1
- movdqu 64(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 48(%rdi), %xmm1
- movdqu 32(%rdi), %xmm11
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xdb /* aesdec %xmm11, %xmm3 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xe3 /* aesdec %xmm11, %xmm4 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xeb /* aesdec %xmm11, %xmm5 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xf3 /* aesdec %xmm11, %xmm6 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xfb /* aesdec %xmm11, %xmm7 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xc3 /* aesdec %xmm11, %xmm8 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm9 */
- .byte 0x66,0x45,0x0f,0x38,0xde,0xd3 /* aesdec %xmm11, %xmm10 */
-
- movdqu 16(%rdi), %xmm1
- .byte 0x66,0x0f,0x38,0xde,0xd9 /* aesdec %xmm1, %xmm3 */
- .byte 0x66,0x0f,0x38,0xde,0xe1 /* aesdec %xmm1, %xmm4 */
- .byte 0x66,0x0f,0x38,0xde,0xe9 /* aesdec %xmm1, %xmm5 */
- .byte 0x66,0x0f,0x38,0xde,0xf1 /* aesdec %xmm1, %xmm6 */
- .byte 0x66,0x0f,0x38,0xde,0xf9 /* aesdec %xmm1, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc1 /* aesdec %xmm1, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xc9 /* aesdec %xmm1, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xde,0xd1 /* aesdec %xmm1, %xmm10 */
- .byte 0x66,0x0f,0x38,0xdf,0xda /* aesdeclast %xmm2, %xmm3 */
- .byte 0x66,0x0f,0x38,0xdf,0xe2 /* aesdeclast %xmm2, %xmm4 */
- .byte 0x66,0x0f,0x38,0xdf,0xea /* aesdeclast %xmm2, %xmm5 */
- .byte 0x66,0x0f,0x38,0xdf,0xf2 /* aesdeclast %xmm2, %xmm6 */
- .byte 0x66,0x0f,0x38,0xdf,0xfa /* aesdeclast %xmm2, %xmm7 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xc2 /* aesdeclast %xmm2, %xmm8 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm9 */
- .byte 0x66,0x44,0x0f,0x38,0xdf,0xd2 /* aesdeclast %xmm2, %xmm10 */
-
- pxor %xmm0, %xmm3
- movdqu (%r8, %rax), %xmm0
- pxor %xmm0, %xmm4
- movdqu 16(%r8, %rax), %xmm0
- pxor %xmm0, %xmm5
- movdqu 32(%r8, %rax), %xmm0
- pxor %xmm0, %xmm6
- movdqu 48(%r8, %rax), %xmm0
- pxor %xmm0, %xmm7
- movdqu 64(%r8, %rax), %xmm0
- pxor %xmm0, %xmm8
- movdqu 80(%r8, %rax), %xmm0
- pxor %xmm0, %xmm9
- movdqu 96(%r8, %rax), %xmm0
- pxor %xmm0, %xmm10
- movdqu 112(%r8, %rax), %xmm0
- movdqu %xmm3, (%rsi, %rax)
- movdqu %xmm4, 16(%rsi, %rax)
- movdqu %xmm5, 32(%rsi, %rax)
- movdqu %xmm6, 48(%rsi, %rax)
- movdqu %xmm7, 64(%rsi, %rax)
- movdqu %xmm8, 80(%rsi, %rax)
- movdqu %xmm9, 96(%rsi, %rax)
- movdqu %xmm10, 112(%rsi, %rax)
-// addq $8*16, %rax
- addq $128, %rax
- cmpq %r11, %rax
- jbe 2b
-1: cmpq %rax, %r9
- je 5f
-
- movdqu 16(%rdi), %xmm2
- movdqu 32(%rdi), %xmm3
- movdqu 48(%rdi), %xmm4
- movdqu 64(%rdi), %xmm5
- movdqu 80(%rdi), %xmm6
- movdqu 96(%rdi), %xmm7
- movdqu 112(%rdi), %xmm8
- movdqu 128(%rdi), %xmm9
- movdqu 144(%rdi), %xmm10
- movdqu 160(%rdi), %xmm11
- movdqu 176(%rdi), %xmm12
- movdqu 192(%rdi), %xmm13
- movdqu 208(%rdi), %xmm14
-
-4: movdqu (%r8, %rax), %xmm1
- pxor %xmm15, %xmm1
- .byte 0x66,0x41,0x0f,0x38,0xde,0xce /* aesdec %xmm14, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcd /* aesdec %xmm13, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcc /* aesdec %xmm12, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xcb /* aesdec %xmm11, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xca /* aesdec %xmm10, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc9 /* aesdec %xmm9, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xde,0xc8 /* aesdec %xmm8, %xmm1 */
- movdqu (%rdi), %xmm8
- .byte 0x66,0x0f,0x38,0xde,0xcf /* aesdec %xmm7, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xce /* aesdec %xmm6, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcd /* aesdec %xmm5, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcc /* aesdec %xmm4, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */
- .byte 0x66,0x0f,0x38,0xde,0xca /* aesdec %xmm2, %xmm1 */
- .byte 0x66,0x41,0x0f,0x38,0xdf,0xc8 /* aesdeclast %xmm8, %xmm1 */
- movdqu 112(%rdi), %xmm8
- pxor %xmm0, %xmm1
- movdqu (%r8, %rax), %xmm0 /* fetch the IV before we store the block */
- movdqu %xmm1, (%rsi, %rax) /* in case input buf = output buf */
- addq $16, %rax
- cmpq %rax, %r9
- jne 4b
-
-5: movdqu %xmm0, (%rdx)
-
- xor %eax, %eax
- ret
- .size intel_aes_decrypt_cbc_256, .-intel_aes_decrypt_cbc_256
diff --git a/security/nss/lib/freebl/intel-gcm-wrap.c b/security/nss/lib/freebl/intel-gcm-wrap.c
deleted file mode 100644
index b2f6f5e4b..000000000
--- a/security/nss/lib/freebl/intel-gcm-wrap.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* Copyright(c) 2013, Intel Corp. */
-
-/* Wrapper funcions for Intel optimized implementation of AES-GCM */
-
-#ifdef USE_HW_AES
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "blapii.h"
-#include "blapit.h"
-#include "gcm.h"
-#include "ctr.h"
-#include "secerr.h"
-#include "prtypes.h"
-#include "pkcs11t.h"
-
-#include <limits.h>
-
-#include "intel-gcm.h"
-#include "rijndael.h"
-
-#if defined(__INTEL_COMPILER)
-#include <ia32intrin.h>
-#elif defined(__GNUC__)
-#include <emmintrin.h>
-#include <tmmintrin.h>
-#endif
-
-
-struct intel_AES_GCMContextStr{
- unsigned char Htbl[16*AES_BLOCK_SIZE];
- unsigned char X0[AES_BLOCK_SIZE];
- unsigned char T[AES_BLOCK_SIZE];
- unsigned char CTR[AES_BLOCK_SIZE];
- AESContext *aes_context;
- unsigned long tagBits;
- unsigned long Alen;
- unsigned long Mlen;
-};
-
-intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context,
- freeblCipherFunc cipher,
- const unsigned char *params,
- unsigned int blocksize)
-{
- intel_AES_GCMContext *gcm = NULL;
- AESContext *aes = (AESContext*)context;
- const CK_GCM_PARAMS *gcmParams = (const CK_GCM_PARAMS *)params;
- unsigned char buff[AES_BLOCK_SIZE]; /* aux buffer */
-
- int IV_whole_len = gcmParams->ulIvLen&(~0xf);
- int IV_remainder_len = gcmParams->ulIvLen&0xf;
- int AAD_whole_len = gcmParams->ulAADLen&(~0xf);
- int AAD_remainder_len = gcmParams->ulAADLen&0xf;
-
- __m128i BSWAP_MASK = _mm_setr_epi8(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0);
- __m128i ONE = _mm_set_epi32(0,0,0,1);
- unsigned int j;
- SECStatus rv;
-
- if (blocksize != AES_BLOCK_SIZE) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
- gcm = PORT_ZNew(intel_AES_GCMContext);
-
- if (gcm == NULL) {
- return NULL;
- }
- /* initialize context fields */
- gcm->aes_context = aes;
- gcm->tagBits = gcmParams->ulTagBits;
- gcm->Alen = 0;
- gcm->Mlen = 0;
- /* first prepare H and its derivatives for ghash */
- intel_aes_gcmINIT(gcm->Htbl, (unsigned char*)aes->expandedKey, aes->Nr);
- /* Initial TAG value is zero*/
- _mm_storeu_si128((__m128i*)gcm->T, _mm_setzero_si128());
- _mm_storeu_si128((__m128i*)gcm->X0, _mm_setzero_si128());
- /* Init the counter */
- if(gcmParams->ulIvLen == 12) {
- _mm_storeu_si128((__m128i*)gcm->CTR, _mm_setr_epi32(((unsigned int*)gcmParams->pIv)[0], ((unsigned int*)gcmParams->pIv)[1], ((unsigned int*)gcmParams->pIv)[2], 0x01000000));
- } else {
- /* If IV size is not 96 bits, then the initial counter value is GHASH of the IV */
- intel_aes_gcmAAD(gcm->Htbl, gcmParams->pIv, IV_whole_len, gcm->T);
- /* Partial block */
- if(IV_remainder_len) {
- PORT_Memset(buff, 0, AES_BLOCK_SIZE);
- PORT_Memcpy(buff, gcmParams->pIv + IV_whole_len, IV_remainder_len);
- intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T);
- }
-
- intel_aes_gcmTAG
- (
- gcm->Htbl,
- gcm->T,
- gcmParams->ulIvLen,
- 0,
- gcm->X0,
- gcm->CTR
- );
- /* TAG should be zero again */
- _mm_storeu_si128((__m128i*)gcm->T, _mm_setzero_si128());
- }
- /* Encrypt the initial counter, will be used to encrypt the GHASH value, in the end */
- rv = (*cipher)(context, gcm->X0, &j, AES_BLOCK_SIZE, gcm->CTR, AES_BLOCK_SIZE, AES_BLOCK_SIZE);
- if (rv != SECSuccess) {
- goto loser;
- }
- /* Promote the counter by 1 */
- _mm_storeu_si128((__m128i*)gcm->CTR, _mm_shuffle_epi8(_mm_add_epi32(ONE, _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)gcm->CTR), BSWAP_MASK)), BSWAP_MASK));
-
-/* Now hash AAD - it would actually make sense to seperate the context creation from the AAD,
- * because that would allow to reuse the H, which only changes when the AES key changes,
- * and not every package, like the IV and AAD */
- intel_aes_gcmAAD(gcm->Htbl, gcmParams->pAAD, AAD_whole_len, gcm->T);
- if(AAD_remainder_len) {
- PORT_Memset(buff, 0, AES_BLOCK_SIZE);
- PORT_Memcpy(buff, gcmParams->pAAD + AAD_whole_len, AAD_remainder_len);
- intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T);
- }
- gcm->Alen += gcmParams->ulAADLen;
- return gcm;
-
- loser:
- if (gcm) {
- PORT_Free(gcm);
- }
- return NULL;
-}
-
-void intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
-{
- if (freeit) {
- PORT_Free(gcm);
- }
-}
-
-SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm,
- unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
-{
- unsigned int tagBytes;
- unsigned char T[AES_BLOCK_SIZE];
- int j;
-
- tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE;
- if (UINT_MAX - inlen < tagBytes) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- if (maxout < inlen + tagBytes) {
- *outlen = inlen + tagBytes;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
-
- intel_aes_gcmENC(
- inbuf,
- outbuf,
- gcm,
- inlen);
-
- gcm->Mlen += inlen;
-
- intel_aes_gcmTAG(
- gcm->Htbl,
- gcm->T,
- gcm->Mlen,
- gcm->Alen,
- gcm->X0,
- T);
-
- *outlen = inlen + tagBytes;
-
- for(j=0; j<tagBytes; j++)
- {
- outbuf[inlen+j] = T[j];
- }
- return SECSuccess;
-}
-
-SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm,
- unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize)
-{
- unsigned int tagBytes;
- unsigned char T[AES_BLOCK_SIZE];
- const unsigned char *intag;
-
- tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE;
-
- /* get the authentication block */
- if (inlen < tagBytes) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- inlen -= tagBytes;
- intag = inbuf + inlen;
-
- intel_aes_gcmDEC(
- inbuf,
- outbuf,
- gcm,
- inlen);
-
- gcm->Mlen += inlen;
- intel_aes_gcmTAG(
- gcm->Htbl,
- gcm->T,
- gcm->Mlen,
- gcm->Alen,
- gcm->X0,
- T);
-
- if (NSS_SecureMemcmp(T, intag, tagBytes) != 0) {
- /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- *outlen = inlen;
-
- return SECSuccess;
-}
-
-#endif
diff --git a/security/nss/lib/freebl/intel-gcm.h b/security/nss/lib/freebl/intel-gcm.h
deleted file mode 100644
index 9360ff148..000000000
--- a/security/nss/lib/freebl/intel-gcm.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/******************************************************************************/
-/* LICENSE: */
-/* This submission to NSS is to be made available under the terms of the */
-/* Mozilla Public License, v. 2.0. You can obtain one at http: */
-/* //mozilla.org/MPL/2.0/. */
-/******************************************************************************/
-/* Copyright(c) 2013, Intel Corp. */
-/******************************************************************************/
-/* Reference: */
-/* [1] Shay Gueron, Michael E. Kounavis: Intel® Carry-Less Multiplication */
-/* Instruction and its Usage for Computing the GCM Mode (Rev. 2.01) */
-/* http://software.intel.com/sites/default/files/article/165685/clmul-wp-r*/
-/*ev-2.01-2012-09-21.pdf */
-/* [2] S. Gueron, M. E. Kounavis: Efficient Implementation of the Galois */
-/* Counter Mode Using a Carry-less Multiplier and a Fast Reduction */
-/* Algorithm. Information Processing Letters 110: 549–553 (2010). */
-/* [3] S. Gueron: AES Performance on the 2nd Generation Intel® Core™ Processor*/
-/* Family (to be posted) (2012). */
-/* [4] S. Gueron: Fast GHASH computations for speeding up AES-GCM (to be */
-/* published) (2012). */
-
-#ifndef INTEL_GCM_H
-#define INTEL_GCM_H 1
-
-#include "blapii.h"
-
-typedef struct intel_AES_GCMContextStr intel_AES_GCMContext;
-
-intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context, freeblCipherFunc cipher,
- const unsigned char *params, unsigned int blocksize);
-
-void intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit);
-
-SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize);
-
-SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm, unsigned char *outbuf,
- unsigned int *outlen, unsigned int maxout,
- const unsigned char *inbuf, unsigned int inlen,
- unsigned int blocksize);
-
-/* Prorotypes of functions in the assembler file for fast AES-GCM, using
- Intel AES-NI and CLMUL-NI, as described in [1]
- [1] Shay Gueron, Michael E. Kounavis: Intel® Carry-Less Multiplication
- Instruction and its Usage for Computing the GCM Mode */
-
-/* Prepares the constants used in the aggregated reduction method */
-void intel_aes_gcmINIT(unsigned char Htbl[16*16],
- unsigned char *KS,
- int NR);
-
-/* Produces the final GHASH value */
-void intel_aes_gcmTAG(unsigned char Htbl[16*16],
- unsigned char *Tp,
- unsigned long Mlen,
- unsigned long Alen,
- unsigned char* X0,
- unsigned char* TAG);
-
-/* Hashes the Additional Authenticated Data, should be used before enc/dec.
- Operates on whole blocks only. Partial blocks should be padded externally. */
-void intel_aes_gcmAAD(unsigned char Htbl[16*16],
- unsigned char *AAD,
- unsigned long Alen,
- unsigned char *Tp);
-
-/* Encrypts and hashes the Plaintext.
- Operates on any length of data, however partial block should only be encrypted
- at the last call, otherwise the result will be incorrect. */
-void intel_aes_gcmENC(const unsigned char* PT,
- unsigned char* CT,
- void *Gctx,
- unsigned long len);
-
-/* Similar to ENC, but decrypts the Ciphertext. */
-void intel_aes_gcmDEC(const unsigned char* CT,
- unsigned char* PT,
- void *Gctx,
- unsigned long len);
-
-#endif
diff --git a/security/nss/lib/freebl/intel-gcm.s b/security/nss/lib/freebl/intel-gcm.s
deleted file mode 100644
index 1a3106091..000000000
--- a/security/nss/lib/freebl/intel-gcm.s
+++ /dev/null
@@ -1,1340 +0,0 @@
-# LICENSE:
-# This submission to NSS is to be made available under the terms of the
-# Mozilla Public License, v. 2.0. You can obtain one at http:
-# //mozilla.org/MPL/2.0/.
-################################################################################
-# Copyright(c) 2012, Intel Corp.
-
-.align 16
-.Lone:
-.quad 1,0
-.Ltwo:
-.quad 2,0
-.Lbswap_mask:
-.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
-.Lshuff_mask:
-.quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f
-.Lpoly:
-.quad 0x1, 0xc200000000000000
-
-
-################################################################################
-# Generates the final GCM tag
-# void intel_aes_gcmTAG(uint8_t Htbl[16*16], uint8_t *Tp, uint64_t Mlen, uint64_t Alen, uint8_t* X0, uint8_t* TAG);
-.type intel_aes_gcmTAG,@function
-.globl intel_aes_gcmTAG
-.align 16
-intel_aes_gcmTAG:
-
-.set Htbl, %rdi
-.set Tp, %rsi
-.set Mlen, %rdx
-.set Alen, %rcx
-.set X0, %r8
-.set TAG, %r9
-
-.set T,%xmm0
-.set TMP0,%xmm1
-
- vmovdqu (Tp), T
- vpshufb .Lbswap_mask(%rip), T, T
- vpxor TMP0, TMP0, TMP0
- shl $3, Mlen
- shl $3, Alen
- vpinsrq $0, Mlen, TMP0, TMP0
- vpinsrq $1, Alen, TMP0, TMP0
- vpxor TMP0, T, T
- vmovdqu (Htbl), TMP0
- call GFMUL
- vpshufb .Lbswap_mask(%rip), T, T
- vpxor (X0), T, T
- vmovdqu T, (TAG)
-
-ret
-.size intel_aes_gcmTAG, .-intel_aes_gcmTAG
-################################################################################
-# Generates the H table
-# void intel_aes_gcmINIT(uint8_t Htbl[16*16], uint8_t *KS, int NR);
-.type intel_aes_gcmINIT,@function
-.globl intel_aes_gcmINIT
-.align 16
-intel_aes_gcmINIT:
-
-.set Htbl, %rdi
-.set KS, %rsi
-.set NR, %edx
-
-.set T,%xmm0
-.set TMP0,%xmm1
-
-CALCULATE_POWERS_OF_H:
- vmovdqu 16*0(KS), T
- vaesenc 16*1(KS), T, T
- vaesenc 16*2(KS), T, T
- vaesenc 16*3(KS), T, T
- vaesenc 16*4(KS), T, T
- vaesenc 16*5(KS), T, T
- vaesenc 16*6(KS), T, T
- vaesenc 16*7(KS), T, T
- vaesenc 16*8(KS), T, T
- vaesenc 16*9(KS), T, T
- vmovdqu 16*10(KS), TMP0
- cmp $10, NR
- je .LH0done
- vaesenc 16*10(KS), T, T
- vaesenc 16*11(KS), T, T
- vmovdqu 16*12(KS), TMP0
- cmp $12, NR
- je .LH0done
- vaesenc 16*12(KS), T, T
- vaesenc 16*13(KS), T, T
- vmovdqu 16*14(KS), TMP0
-
-.LH0done:
- vaesenclast TMP0, T, T
-
- vpshufb .Lbswap_mask(%rip), T, T
-
- vmovdqu T, TMP0
- # Calculate H` = GFMUL(H, 2)
- vpsrld $7 , T , %xmm3
- vmovdqu .Lshuff_mask(%rip), %xmm4
- vpshufb %xmm4, %xmm3 , %xmm3
- movq $0xff00 , %rax
- vmovq %rax, %xmm4
- vpshufb %xmm3, %xmm4 , %xmm4
- vmovdqu .Lpoly(%rip), %xmm5
- vpand %xmm4, %xmm5, %xmm5
- vpsrld $31, T, %xmm3
- vpslld $1, T, %xmm4
- vpslldq $4, %xmm3, %xmm3
- vpxor %xmm3, %xmm4, T #xmm1 holds now p(x)<<1
-
- #adding p(x)<<1 to xmm5
- vpxor %xmm5, T , T
- vmovdqu T, TMP0
- vmovdqu T, (Htbl) # H * 2
- call GFMUL
- vmovdqu T, 16(Htbl) # H^2 * 2
- call GFMUL
- vmovdqu T, 32(Htbl) # H^3 * 2
- call GFMUL
- vmovdqu T, 48(Htbl) # H^4 * 2
- call GFMUL
- vmovdqu T, 64(Htbl) # H^5 * 2
- call GFMUL
- vmovdqu T, 80(Htbl) # H^6 * 2
- call GFMUL
- vmovdqu T, 96(Htbl) # H^7 * 2
- call GFMUL
- vmovdqu T, 112(Htbl) # H^8 * 2
-
- # Precalculations for the reduce 4 step
- vpshufd $78, (Htbl), %xmm8
- vpshufd $78, 16(Htbl), %xmm9
- vpshufd $78, 32(Htbl), %xmm10
- vpshufd $78, 48(Htbl), %xmm11
- vpshufd $78, 64(Htbl), %xmm12
- vpshufd $78, 80(Htbl), %xmm13
- vpshufd $78, 96(Htbl), %xmm14
- vpshufd $78, 112(Htbl), %xmm15
-
- vpxor (Htbl), %xmm8, %xmm8
- vpxor 16(Htbl), %xmm9, %xmm9
- vpxor 32(Htbl), %xmm10, %xmm10
- vpxor 48(Htbl), %xmm11, %xmm11
- vpxor 64(Htbl), %xmm12, %xmm12
- vpxor 80(Htbl), %xmm13, %xmm13
- vpxor 96(Htbl), %xmm14, %xmm14
- vpxor 112(Htbl), %xmm15, %xmm15
-
- vmovdqu %xmm8, 128(Htbl)
- vmovdqu %xmm9, 144(Htbl)
- vmovdqu %xmm10, 160(Htbl)
- vmovdqu %xmm11, 176(Htbl)
- vmovdqu %xmm12, 192(Htbl)
- vmovdqu %xmm13, 208(Htbl)
- vmovdqu %xmm14, 224(Htbl)
- vmovdqu %xmm15, 240(Htbl)
-
- ret
-.size intel_aes_gcmINIT, .-intel_aes_gcmINIT
-################################################################################
-# Authenticate only
-# void intel_aes_gcmAAD(uint8_t Htbl[16*16], uint8_t *AAD, uint64_t Alen, uint8_t *Tp);
-
-.globl intel_aes_gcmAAD
-.type intel_aes_gcmAAD,@function
-.align 16
-intel_aes_gcmAAD:
-
-.set DATA, %xmm0
-.set T, %xmm1
-.set BSWAP_MASK, %xmm2
-.set TMP0, %xmm3
-.set TMP1, %xmm4
-.set TMP2, %xmm5
-.set TMP3, %xmm6
-.set TMP4, %xmm7
-.set Xhi, %xmm9
-
-.set Htbl, %rdi
-.set inp, %rsi
-.set len, %rdx
-.set Tp, %rcx
-
-.set hlp0, %r11
-
-.macro KARATSUBA_AAD i
- vpclmulqdq $0x00, 16*\i(Htbl), DATA, TMP3
- vpxor TMP3, TMP0, TMP0
- vpclmulqdq $0x11, 16*\i(Htbl), DATA, TMP3
- vpxor TMP3, TMP1, TMP1
- vpshufd $78, DATA, TMP3
- vpxor DATA, TMP3, TMP3
- vpclmulqdq $0x00, 16*(\i+8)(Htbl), TMP3, TMP3
- vpxor TMP3, TMP2, TMP2
-.endm
-
- test len, len
- jnz .LbeginAAD
- ret
-
-.LbeginAAD:
-
- push hlp0
- vzeroupper
-
- vmovdqa .Lbswap_mask(%rip), BSWAP_MASK
-
- vpxor Xhi, Xhi, Xhi
-
- vmovdqu (Tp),T
- vpshufb BSWAP_MASK,T,T
-
- # we hash 8 block each iteration, if the total amount of blocks is not a multiple of 8, we hash the first n%8 blocks first
- mov len, hlp0
- and $~-128, hlp0
-
- jz .Lmod_loop
-
- sub hlp0, len
- sub $16, hlp0
-
- #hash first prefix block
- vmovdqu (inp), DATA
- vpshufb BSWAP_MASK, DATA, DATA
- vpxor T, DATA, DATA
-
- vpclmulqdq $0x00, (Htbl, hlp0), DATA, TMP0
- vpclmulqdq $0x11, (Htbl, hlp0), DATA, TMP1
- vpshufd $78, DATA, TMP2
- vpxor DATA, TMP2, TMP2
- vpclmulqdq $0x00, 16*8(Htbl, hlp0), TMP2, TMP2
-
- lea 16(inp), inp
- test hlp0, hlp0
- jnz .Lpre_loop
- jmp .Lred1
-
- #hash remaining prefix bocks (up to 7 total prefix blocks)
-.align 64
-.Lpre_loop:
-
- sub $16, hlp0
-
- vmovdqu (inp),DATA # next data block
- vpshufb BSWAP_MASK,DATA,DATA
-
- vpclmulqdq $0x00, (Htbl,hlp0), DATA, TMP3
- vpxor TMP3, TMP0, TMP0
- vpclmulqdq $0x11, (Htbl,hlp0), DATA, TMP3
- vpxor TMP3, TMP1, TMP1
- vpshufd $78, DATA, TMP3
- vpxor DATA, TMP3, TMP3
- vpclmulqdq $0x00, 16*8(Htbl,hlp0), TMP3, TMP3
- vpxor TMP3, TMP2, TMP2
-
- test hlp0, hlp0
-
- lea 16(inp), inp
-
- jnz .Lpre_loop
-
-.Lred1:
- vpxor TMP0, TMP2, TMP2
- vpxor TMP1, TMP2, TMP2
- vpsrldq $8, TMP2, TMP3
- vpslldq $8, TMP2, TMP2
-
- vpxor TMP3, TMP1, Xhi
- vpxor TMP2, TMP0, T
-
-.align 64
-.Lmod_loop:
- sub $0x80, len
- jb .Ldone
-
- vmovdqu 16*7(inp),DATA # Ii
- vpshufb BSWAP_MASK,DATA,DATA
-
- vpclmulqdq $0x00, (Htbl), DATA, TMP0
- vpclmulqdq $0x11, (Htbl), DATA, TMP1
- vpshufd $78, DATA, TMP2
- vpxor DATA, TMP2, TMP2
- vpclmulqdq $0x00, 16*8(Htbl), TMP2, TMP2
- #########################################################
- vmovdqu 16*6(inp),DATA
- vpshufb BSWAP_MASK,DATA,DATA
- KARATSUBA_AAD 1
- #########################################################
- vmovdqu 16*5(inp),DATA
- vpshufb BSWAP_MASK,DATA,DATA
-
- vpclmulqdq $0x10, .Lpoly(%rip), T, TMP4 #reduction stage 1a
- vpalignr $8, T, T, T
-
- KARATSUBA_AAD 2
-
- vpxor TMP4, T, T #reduction stage 1b
- #########################################################
- vmovdqu 16*4(inp),DATA
- vpshufb BSWAP_MASK,DATA,DATA
-
- KARATSUBA_AAD 3
- #########################################################
- vmovdqu 16*3(inp),DATA
- vpshufb BSWAP_MASK,DATA,DATA
-
- vpclmulqdq $0x10, .Lpoly(%rip), T, TMP4 #reduction stage 2a
- vpalignr $8, T, T, T
-
- KARATSUBA_AAD 4
-
- vpxor TMP4, T, T #reduction stage 2b
- #########################################################
- vmovdqu 16*2(inp),DATA
- vpshufb BSWAP_MASK,DATA,DATA
-
- KARATSUBA_AAD 5
-
- vpxor Xhi, T, T #reduction finalize
- #########################################################
- vmovdqu 16*1(inp),DATA
- vpshufb BSWAP_MASK,DATA,DATA
-
- KARATSUBA_AAD 6
- #########################################################
- vmovdqu 16*0(inp),DATA
- vpshufb BSWAP_MASK,DATA,DATA
- vpxor T,DATA,DATA
-
- KARATSUBA_AAD 7
- #########################################################
- vpxor TMP0, TMP2, TMP2 # karatsuba fixup
- vpxor TMP1, TMP2, TMP2
- vpsrldq $8, TMP2, TMP3
- vpslldq $8, TMP2, TMP2
-
- vpxor TMP3, TMP1, Xhi
- vpxor TMP2, TMP0, T
-
- lea 16*8(inp), inp
- jmp .Lmod_loop
- #########################################################
-
-.Ldone:
- vpclmulqdq $0x10, .Lpoly(%rip), T, TMP3
- vpalignr $8, T, T, T
- vpxor TMP3, T, T
-
- vpclmulqdq $0x10, .Lpoly(%rip), T, TMP3
- vpalignr $8, T, T, T
- vpxor TMP3, T, T
-
- vpxor Xhi, T, T
-
-.Lsave:
- vpshufb BSWAP_MASK,T, T
- vmovdqu T,(Tp)
- vzeroupper
-
- pop hlp0
- ret
-.size intel_aes_gcmAAD,.-intel_aes_gcmAAD
-
-################################################################################
-# Encrypt and Authenticate
-# void intel_aes_gcmENC(uint8_t* PT, uint8_t* CT, void *Gctx,uint64_t len);
-.type intel_aes_gcmENC,@function
-.globl intel_aes_gcmENC
-.align 16
-intel_aes_gcmENC:
-
-.set PT,%rdi
-.set CT,%rsi
-.set Htbl, %rdx
-.set len, %rcx
-.set KS,%r9
-.set NR,%r10d
-
-.set Gctx, %rdx
-
-.set T,%xmm0
-.set TMP0,%xmm1
-.set TMP1,%xmm2
-.set TMP2,%xmm3
-.set TMP3,%xmm4
-.set TMP4,%xmm5
-.set TMP5,%xmm6
-.set CTR0,%xmm7
-.set CTR1,%xmm8
-.set CTR2,%xmm9
-.set CTR3,%xmm10
-.set CTR4,%xmm11
-.set CTR5,%xmm12
-.set CTR6,%xmm13
-.set CTR7,%xmm14
-.set CTR,%xmm15
-
-.macro ROUND i
- vmovdqu \i*16(KS), TMP3
- vaesenc TMP3, CTR0, CTR0
- vaesenc TMP3, CTR1, CTR1
- vaesenc TMP3, CTR2, CTR2
- vaesenc TMP3, CTR3, CTR3
- vaesenc TMP3, CTR4, CTR4
- vaesenc TMP3, CTR5, CTR5
- vaesenc TMP3, CTR6, CTR6
- vaesenc TMP3, CTR7, CTR7
-.endm
-
-.macro ROUNDMUL i
-
- vmovdqu \i*16(%rsp), TMP5
- vmovdqu \i*16(KS), TMP3
-
- vaesenc TMP3, CTR0, CTR0
- vaesenc TMP3, CTR1, CTR1
- vaesenc TMP3, CTR2, CTR2
- vaesenc TMP3, CTR3, CTR3
-
- vpshufd $78, TMP5, TMP4
- vpxor TMP5, TMP4, TMP4
-
- vaesenc TMP3, CTR4, CTR4
- vaesenc TMP3, CTR5, CTR5
- vaesenc TMP3, CTR6, CTR6
- vaesenc TMP3, CTR7, CTR7
-
- vpclmulqdq $0x00, 128+\i*16(Htbl), TMP4, TMP3
- vpxor TMP3, TMP0, TMP0
- vmovdqa \i*16(Htbl), TMP4
- vpclmulqdq $0x11, TMP4, TMP5, TMP3
- vpxor TMP3, TMP1, TMP1
- vpclmulqdq $0x00, TMP4, TMP5, TMP3
- vpxor TMP3, TMP2, TMP2
-
-.endm
-
-.macro KARATSUBA i
- vmovdqu \i*16(%rsp), TMP5
-
- vpclmulqdq $0x11, 16*\i(Htbl), TMP5, TMP3
- vpxor TMP3, TMP1, TMP1
- vpclmulqdq $0x00, 16*\i(Htbl), TMP5, TMP3
- vpxor TMP3, TMP2, TMP2
- vpshufd $78, TMP5, TMP3
- vpxor TMP5, TMP3, TMP5
- vpclmulqdq $0x00, 128+\i*16(Htbl), TMP5, TMP3
- vpxor TMP3, TMP0, TMP0
-.endm
-
- test len, len
- jnz .Lbegin
- ret
-
-.Lbegin:
-
- vzeroupper
- push %rbp
- push %rbx
-
- movq %rsp, %rbp
- sub $128, %rsp
- andq $-16, %rsp
-
- vmovdqu 288(Gctx), CTR
- vmovdqu 272(Gctx), T
- mov 304(Gctx), KS
- mov 4(KS), NR
- lea 48(KS), KS
-
- vpshufb .Lbswap_mask(%rip), CTR, CTR
- vpshufb .Lbswap_mask(%rip), T, T
-
- cmp $128, len
- jb .LDataSingles
-
-# Encrypt the first eight blocks
- sub $128, len
- vmovdqa CTR, CTR0
- vpaddd .Lone(%rip), CTR0, CTR1
- vpaddd .Ltwo(%rip), CTR0, CTR2
- vpaddd .Lone(%rip), CTR2, CTR3
- vpaddd .Ltwo(%rip), CTR2, CTR4
- vpaddd .Lone(%rip), CTR4, CTR5
- vpaddd .Ltwo(%rip), CTR4, CTR6
- vpaddd .Lone(%rip), CTR6, CTR7
- vpaddd .Ltwo(%rip), CTR6, CTR
-
- vpshufb .Lbswap_mask(%rip), CTR0, CTR0
- vpshufb .Lbswap_mask(%rip), CTR1, CTR1
- vpshufb .Lbswap_mask(%rip), CTR2, CTR2
- vpshufb .Lbswap_mask(%rip), CTR3, CTR3
- vpshufb .Lbswap_mask(%rip), CTR4, CTR4
- vpshufb .Lbswap_mask(%rip), CTR5, CTR5
- vpshufb .Lbswap_mask(%rip), CTR6, CTR6
- vpshufb .Lbswap_mask(%rip), CTR7, CTR7
-
- vpxor (KS), CTR0, CTR0
- vpxor (KS), CTR1, CTR1
- vpxor (KS), CTR2, CTR2
- vpxor (KS), CTR3, CTR3
- vpxor (KS), CTR4, CTR4
- vpxor (KS), CTR5, CTR5
- vpxor (KS), CTR6, CTR6
- vpxor (KS), CTR7, CTR7
-
- ROUND 1
- ROUND 2
- ROUND 3
- ROUND 4
- ROUND 5
- ROUND 6
- ROUND 7
- ROUND 8
- ROUND 9
-
- vmovdqu 160(KS), TMP5
- cmp $12, NR
- jb .LLast1
-
- ROUND 10
- ROUND 11
-
- vmovdqu 192(KS), TMP5
- cmp $14, NR
- jb .LLast1
-
- ROUND 12
- ROUND 13
-
- vmovdqu 224(KS), TMP5
-
-.LLast1:
-
- vpxor (PT), TMP5, TMP3
- vaesenclast TMP3, CTR0, CTR0
- vpxor 16(PT), TMP5, TMP3
- vaesenclast TMP3, CTR1, CTR1
- vpxor 32(PT), TMP5, TMP3
- vaesenclast TMP3, CTR2, CTR2
- vpxor 48(PT), TMP5, TMP3
- vaesenclast TMP3, CTR3, CTR3
- vpxor 64(PT), TMP5, TMP3
- vaesenclast TMP3, CTR4, CTR4
- vpxor 80(PT), TMP5, TMP3
- vaesenclast TMP3, CTR5, CTR5
- vpxor 96(PT), TMP5, TMP3
- vaesenclast TMP3, CTR6, CTR6
- vpxor 112(PT), TMP5, TMP3
- vaesenclast TMP3, CTR7, CTR7
-
- vmovdqu .Lbswap_mask(%rip), TMP3
-
- vmovdqu CTR0, (CT)
- vpshufb TMP3, CTR0, CTR0
- vmovdqu CTR1, 16(CT)
- vpshufb TMP3, CTR1, CTR1
- vmovdqu CTR2, 32(CT)
- vpshufb TMP3, CTR2, CTR2
- vmovdqu CTR3, 48(CT)
- vpshufb TMP3, CTR3, CTR3
- vmovdqu CTR4, 64(CT)
- vpshufb TMP3, CTR4, CTR4
- vmovdqu CTR5, 80(CT)
- vpshufb TMP3, CTR5, CTR5
- vmovdqu CTR6, 96(CT)
- vpshufb TMP3, CTR6, CTR6
- vmovdqu CTR7, 112(CT)
- vpshufb TMP3, CTR7, CTR7
-
- lea 128(CT), CT
- lea 128(PT), PT
- jmp .LDataOctets
-
-# Encrypt 8 blocks each time while hashing previous 8 blocks
-.align 64
-.LDataOctets:
- cmp $128, len
- jb .LEndOctets
- sub $128, len
-
- vmovdqa CTR7, TMP5
- vmovdqa CTR6, 1*16(%rsp)
- vmovdqa CTR5, 2*16(%rsp)
- vmovdqa CTR4, 3*16(%rsp)
- vmovdqa CTR3, 4*16(%rsp)
- vmovdqa CTR2, 5*16(%rsp)
- vmovdqa CTR1, 6*16(%rsp)
- vmovdqa CTR0, 7*16(%rsp)
-
- vmovdqa CTR, CTR0
- vpaddd .Lone(%rip), CTR0, CTR1
- vpaddd .Ltwo(%rip), CTR0, CTR2
- vpaddd .Lone(%rip), CTR2, CTR3
- vpaddd .Ltwo(%rip), CTR2, CTR4
- vpaddd .Lone(%rip), CTR4, CTR5
- vpaddd .Ltwo(%rip), CTR4, CTR6
- vpaddd .Lone(%rip), CTR6, CTR7
- vpaddd .Ltwo(%rip), CTR6, CTR
-
- vmovdqu (KS), TMP4
- vpshufb TMP3, CTR0, CTR0
- vpxor TMP4, CTR0, CTR0
- vpshufb TMP3, CTR1, CTR1
- vpxor TMP4, CTR1, CTR1
- vpshufb TMP3, CTR2, CTR2
- vpxor TMP4, CTR2, CTR2
- vpshufb TMP3, CTR3, CTR3
- vpxor TMP4, CTR3, CTR3
- vpshufb TMP3, CTR4, CTR4
- vpxor TMP4, CTR4, CTR4
- vpshufb TMP3, CTR5, CTR5
- vpxor TMP4, CTR5, CTR5
- vpshufb TMP3, CTR6, CTR6
- vpxor TMP4, CTR6, CTR6
- vpshufb TMP3, CTR7, CTR7
- vpxor TMP4, CTR7, CTR7
-
- vmovdqu 16*0(Htbl), TMP3
- vpclmulqdq $0x11, TMP3, TMP5, TMP1
- vpclmulqdq $0x00, TMP3, TMP5, TMP2
- vpshufd $78, TMP5, TMP3
- vpxor TMP5, TMP3, TMP5
- vmovdqu 128+0*16(Htbl), TMP3
- vpclmulqdq $0x00, TMP3, TMP5, TMP0
-
- ROUNDMUL 1
-
- ROUNDMUL 2
-
- ROUNDMUL 3
-
- ROUNDMUL 4
-
- ROUNDMUL 5
-
- ROUNDMUL 6
-
- vpxor 7*16(%rsp), T, TMP5
- vmovdqu 7*16(KS), TMP3
-
- vaesenc TMP3, CTR0, CTR0
- vaesenc TMP3, CTR1, CTR1
- vaesenc TMP3, CTR2, CTR2
- vaesenc TMP3, CTR3, CTR3
-
- vpshufd $78, TMP5, TMP4
- vpxor TMP5, TMP4, TMP4
-
- vaesenc TMP3, CTR4, CTR4
- vaesenc TMP3, CTR5, CTR5
- vaesenc TMP3, CTR6, CTR6
- vaesenc TMP3, CTR7, CTR7
-
- vpclmulqdq $0x11, 7*16(Htbl), TMP5, TMP3
- vpxor TMP3, TMP1, TMP1
- vpclmulqdq $0x00, 7*16(Htbl), TMP5, TMP3
- vpxor TMP3, TMP2, TMP2
- vpclmulqdq $0x00, 128+7*16(Htbl), TMP4, TMP3
- vpxor TMP3, TMP0, TMP0
-
- ROUND 8
- vmovdqa .Lpoly(%rip), TMP5
-
- vpxor TMP1, TMP0, TMP0
- vpxor TMP2, TMP0, TMP0
- vpsrldq $8, TMP0, TMP3
- vpxor TMP3, TMP1, TMP4
- vpslldq $8, TMP0, TMP3
- vpxor TMP3, TMP2, T
-
- vpclmulqdq $0x10, TMP5, T, TMP1
- vpalignr $8, T, T, T
- vpxor T, TMP1, T
-
- ROUND 9
-
- vpclmulqdq $0x10, TMP5, T, TMP1
- vpalignr $8, T, T, T
- vpxor T, TMP1, T
-
- vmovdqu 160(KS), TMP5
- cmp $10, NR
- jbe .LLast2
-
- ROUND 10
- ROUND 11
-
- vmovdqu 192(KS), TMP5
- cmp $12, NR
- jbe .LLast2
-
- ROUND 12
- ROUND 13
-
- vmovdqu 224(KS), TMP5
-
-.LLast2:
-
- vpxor (PT), TMP5, TMP3
- vaesenclast TMP3, CTR0, CTR0
- vpxor 16(PT), TMP5, TMP3
- vaesenclast TMP3, CTR1, CTR1
- vpxor 32(PT), TMP5, TMP3
- vaesenclast TMP3, CTR2, CTR2
- vpxor 48(PT), TMP5, TMP3
- vaesenclast TMP3, CTR3, CTR3
- vpxor 64(PT), TMP5, TMP3
- vaesenclast TMP3, CTR4, CTR4
- vpxor 80(PT), TMP5, TMP3
- vaesenclast TMP3, CTR5, CTR5
- vpxor 96(PT), TMP5, TMP3
- vaesenclast TMP3, CTR6, CTR6
- vpxor 112(PT), TMP5, TMP3
- vaesenclast TMP3, CTR7, CTR7
-
- vmovdqu .Lbswap_mask(%rip), TMP3
-
- vmovdqu CTR0, (CT)
- vpshufb TMP3, CTR0, CTR0
- vmovdqu CTR1, 16(CT)
- vpshufb TMP3, CTR1, CTR1
- vmovdqu CTR2, 32(CT)
- vpshufb TMP3, CTR2, CTR2
- vmovdqu CTR3, 48(CT)
- vpshufb TMP3, CTR3, CTR3
- vmovdqu CTR4, 64(CT)
- vpshufb TMP3, CTR4, CTR4
- vmovdqu CTR5, 80(CT)
- vpshufb TMP3, CTR5, CTR5
- vmovdqu CTR6, 96(CT)
- vpshufb TMP3, CTR6, CTR6
- vmovdqu CTR7,112(CT)
- vpshufb TMP3, CTR7, CTR7
-
- vpxor TMP4, T, T
-
- lea 128(CT), CT
- lea 128(PT), PT
- jmp .LDataOctets
-
-.LEndOctets:
-
- vmovdqa CTR7, TMP5
- vmovdqa CTR6, 1*16(%rsp)
- vmovdqa CTR5, 2*16(%rsp)
- vmovdqa CTR4, 3*16(%rsp)
- vmovdqa CTR3, 4*16(%rsp)
- vmovdqa CTR2, 5*16(%rsp)
- vmovdqa CTR1, 6*16(%rsp)
- vmovdqa CTR0, 7*16(%rsp)
-
- vmovdqu 16*0(Htbl), TMP3
- vpclmulqdq $0x11, TMP3, TMP5, TMP1
- vpclmulqdq $0x00, TMP3, TMP5, TMP2
- vpshufd $78, TMP5, TMP3
- vpxor TMP5, TMP3, TMP5
- vmovdqu 128+0*16(Htbl), TMP3
- vpclmulqdq $0x00, TMP3, TMP5, TMP0
-
- KARATSUBA 1
- KARATSUBA 2
- KARATSUBA 3
- KARATSUBA 4
- KARATSUBA 5
- KARATSUBA 6
-
- vmovdqu 7*16(%rsp), TMP5
- vpxor T, TMP5, TMP5
- vmovdqu 16*7(Htbl), TMP4
- vpclmulqdq $0x11, TMP4, TMP5, TMP3
- vpxor TMP3, TMP1, TMP1
- vpclmulqdq $0x00, TMP4, TMP5, TMP3
- vpxor TMP3, TMP2, TMP2
- vpshufd $78, TMP5, TMP3
- vpxor TMP5, TMP3, TMP5
- vmovdqu 128+7*16(Htbl), TMP4
- vpclmulqdq $0x00, TMP4, TMP5, TMP3
- vpxor TMP3, TMP0, TMP0
-
- vpxor TMP1, TMP0, TMP0
- vpxor TMP2, TMP0, TMP0
-
- vpsrldq $8, TMP0, TMP3
- vpxor TMP3, TMP1, TMP4
- vpslldq $8, TMP0, TMP3
- vpxor TMP3, TMP2, T
-
- vmovdqa .Lpoly(%rip), TMP2
-
- vpalignr $8, T, T, TMP1
- vpclmulqdq $0x10, TMP2, T, T
- vpxor T, TMP1, T
-
- vpalignr $8, T, T, TMP1
- vpclmulqdq $0x10, TMP2, T, T
- vpxor T, TMP1, T
-
- vpxor TMP4, T, T
-
-#Here we encrypt any remaining whole block
-.LDataSingles:
-
- cmp $16, len
- jb .LDataTail
- sub $16, len
-
- vpshufb .Lbswap_mask(%rip), CTR, TMP1
- vpaddd .Lone(%rip), CTR, CTR
-
- vpxor (KS), TMP1, TMP1
- vaesenc 16*1(KS), TMP1, TMP1
- vaesenc 16*2(KS), TMP1, TMP1
- vaesenc 16*3(KS), TMP1, TMP1
- vaesenc 16*4(KS), TMP1, TMP1
- vaesenc 16*5(KS), TMP1, TMP1
- vaesenc 16*6(KS), TMP1, TMP1
- vaesenc 16*7(KS), TMP1, TMP1
- vaesenc 16*8(KS), TMP1, TMP1
- vaesenc 16*9(KS), TMP1, TMP1
- vmovdqu 16*10(KS), TMP2
- cmp $10, NR
- je .LLast3
- vaesenc 16*10(KS), TMP1, TMP1
- vaesenc 16*11(KS), TMP1, TMP1
- vmovdqu 16*12(KS), TMP2
- cmp $12, NR
- je .LLast3
- vaesenc 16*12(KS), TMP1, TMP1
- vaesenc 16*13(KS), TMP1, TMP1
- vmovdqu 16*14(KS), TMP2
-
-.LLast3:
- vaesenclast TMP2, TMP1, TMP1
-
- vpxor (PT), TMP1, TMP1
- vmovdqu TMP1, (CT)
- addq $16, CT
- addq $16, PT
-
- vpshufb .Lbswap_mask(%rip), TMP1, TMP1
- vpxor TMP1, T, T
- vmovdqu (Htbl), TMP0
- call GFMUL
-
- jmp .LDataSingles
-
-#Here we encypt the final partial block, if there is one
-.LDataTail:
-
- test len, len
- jz DATA_END
-# First prepare the counter block
- vpshufb .Lbswap_mask(%rip), CTR, TMP1
- vpaddd .Lone(%rip), CTR, CTR
-
- vpxor (KS), TMP1, TMP1
- vaesenc 16*1(KS), TMP1, TMP1
- vaesenc 16*2(KS), TMP1, TMP1
- vaesenc 16*3(KS), TMP1, TMP1
- vaesenc 16*4(KS), TMP1, TMP1
- vaesenc 16*5(KS), TMP1, TMP1
- vaesenc 16*6(KS), TMP1, TMP1
- vaesenc 16*7(KS), TMP1, TMP1
- vaesenc 16*8(KS), TMP1, TMP1
- vaesenc 16*9(KS), TMP1, TMP1
- vmovdqu 16*10(KS), TMP2
- cmp $10, NR
- je .LLast4
- vaesenc 16*10(KS), TMP1, TMP1
- vaesenc 16*11(KS), TMP1, TMP1
- vmovdqu 16*12(KS), TMP2
- cmp $12, NR
- je .LLast4
- vaesenc 16*12(KS), TMP1, TMP1
- vaesenc 16*13(KS), TMP1, TMP1
- vmovdqu 16*14(KS), TMP2
-
-.LLast4:
- vaesenclast TMP2, TMP1, TMP1
-#Zero a temp location
- vpxor TMP2, TMP2, TMP2
- vmovdqa TMP2, (%rsp)
-
-# Copy the required bytes only (could probably use rep movsb)
- xor KS, KS
-.LEncCpy:
- cmp KS, len
- je .LEncCpyEnd
- movb (PT, KS, 1), %r8b
- movb %r8b, (%rsp, KS, 1)
- inc KS
- jmp .LEncCpy
-.LEncCpyEnd:
-# Xor with the counter block
- vpxor (%rsp), TMP1, TMP0
-# Again, store at temp location
- vmovdqa TMP0, (%rsp)
-# Copy only the required bytes to CT, and zero the rest for the hash
- xor KS, KS
-.LEncCpy2:
- cmp KS, len
- je .LEncCpy3
- movb (%rsp, KS, 1), %r8b
- movb %r8b, (CT, KS, 1)
- inc KS
- jmp .LEncCpy2
-.LEncCpy3:
- cmp $16, KS
- je .LEndCpy3
- movb $0, (%rsp, KS, 1)
- inc KS
- jmp .LEncCpy3
-.LEndCpy3:
- vmovdqa (%rsp), TMP0
-
- vpshufb .Lbswap_mask(%rip), TMP0, TMP0
- vpxor TMP0, T, T
- vmovdqu (Htbl), TMP0
- call GFMUL
-
-DATA_END:
-
- vpshufb .Lbswap_mask(%rip), T, T
- vpshufb .Lbswap_mask(%rip), CTR, CTR
- vmovdqu T, 272(Gctx)
- vmovdqu CTR, 288(Gctx)
-
- movq %rbp, %rsp
-
- popq %rbx
- popq %rbp
- ret
- .size intel_aes_gcmENC, .-intel_aes_gcmENC
-
-#########################
-# Decrypt and Authenticate
-# void intel_aes_gcmDEC(uint8_t* PT, uint8_t* CT, void *Gctx,uint64_t len);
-.type intel_aes_gcmDEC,@function
-.globl intel_aes_gcmDEC
-.align 16
-intel_aes_gcmDEC:
-# parameter 1: CT # input
-# parameter 2: PT # output
-# parameter 3: %rdx # Gctx
-# parameter 4: %rcx # len
-
-.macro DEC_KARATSUBA i
- vmovdqu (7-\i)*16(CT), TMP5
- vpshufb .Lbswap_mask(%rip), TMP5, TMP5
-
- vpclmulqdq $0x11, 16*\i(Htbl), TMP5, TMP3
- vpxor TMP3, TMP1, TMP1
- vpclmulqdq $0x00, 16*\i(Htbl), TMP5, TMP3
- vpxor TMP3, TMP2, TMP2
- vpshufd $78, TMP5, TMP3
- vpxor TMP5, TMP3, TMP5
- vpclmulqdq $0x00, 128+\i*16(Htbl), TMP5, TMP3
- vpxor TMP3, TMP0, TMP0
-.endm
-
-.set PT,%rsi
-.set CT,%rdi
-.set Htbl, %rdx
-.set len, %rcx
-.set KS,%r9
-.set NR,%r10d
-
-.set Gctx, %rdx
-
-.set T,%xmm0
-.set TMP0,%xmm1
-.set TMP1,%xmm2
-.set TMP2,%xmm3
-.set TMP3,%xmm4
-.set TMP4,%xmm5
-.set TMP5,%xmm6
-.set CTR0,%xmm7
-.set CTR1,%xmm8
-.set CTR2,%xmm9
-.set CTR3,%xmm10
-.set CTR4,%xmm11
-.set CTR5,%xmm12
-.set CTR6,%xmm13
-.set CTR7,%xmm14
-.set CTR,%xmm15
-
- test len, len
- jnz .LbeginDec
- ret
-
-.LbeginDec:
-
- pushq %rbp
- pushq %rbx
- movq %rsp, %rbp
- sub $128, %rsp
- andq $-16, %rsp
- vmovdqu 288(Gctx), CTR
- vmovdqu 272(Gctx), T
- mov 304(Gctx), KS
- mov 4(KS), NR
- lea 48(KS), KS
-
- vpshufb .Lbswap_mask(%rip), CTR, CTR
- vpshufb .Lbswap_mask(%rip), T, T
-
- vmovdqu .Lbswap_mask(%rip), TMP3
- jmp .LDECOctets
-
-# Decrypt 8 blocks each time while hashing them at the same time
-.align 64
-.LDECOctets:
-
- cmp $128, len
- jb .LDECSingles
- sub $128, len
-
- vmovdqa CTR, CTR0
- vpaddd .Lone(%rip), CTR0, CTR1
- vpaddd .Ltwo(%rip), CTR0, CTR2
- vpaddd .Lone(%rip), CTR2, CTR3
- vpaddd .Ltwo(%rip), CTR2, CTR4
- vpaddd .Lone(%rip), CTR4, CTR5
- vpaddd .Ltwo(%rip), CTR4, CTR6
- vpaddd .Lone(%rip), CTR6, CTR7
- vpaddd .Ltwo(%rip), CTR6, CTR
-
- vpshufb TMP3, CTR0, CTR0
- vpshufb TMP3, CTR1, CTR1
- vpshufb TMP3, CTR2, CTR2
- vpshufb TMP3, CTR3, CTR3
- vpshufb TMP3, CTR4, CTR4
- vpshufb TMP3, CTR5, CTR5
- vpshufb TMP3, CTR6, CTR6
- vpshufb TMP3, CTR7, CTR7
-
- vmovdqu (KS), TMP3
- vpxor TMP3, CTR0, CTR0
- vpxor TMP3, CTR1, CTR1
- vpxor TMP3, CTR2, CTR2
- vpxor TMP3, CTR3, CTR3
- vpxor TMP3, CTR4, CTR4
- vpxor TMP3, CTR5, CTR5
- vpxor TMP3, CTR6, CTR6
- vpxor TMP3, CTR7, CTR7
-
- vmovdqu 7*16(CT), TMP5
- vpshufb .Lbswap_mask(%rip), TMP5, TMP5
- vmovdqu 16*0(Htbl), TMP3
- vpclmulqdq $0x11, TMP3, TMP5, TMP1
- vpclmulqdq $0x00, TMP3, TMP5, TMP2
- vpshufd $78, TMP5, TMP3
- vpxor TMP5, TMP3, TMP5
- vmovdqu 128+0*16(Htbl), TMP3
- vpclmulqdq $0x00, TMP3, TMP5, TMP0
-
- ROUND 1
- DEC_KARATSUBA 1
-
- ROUND 2
- DEC_KARATSUBA 2
-
- ROUND 3
- DEC_KARATSUBA 3
-
- ROUND 4
- DEC_KARATSUBA 4
-
- ROUND 5
- DEC_KARATSUBA 5
-
- ROUND 6
- DEC_KARATSUBA 6
-
- ROUND 7
-
- vmovdqu 0*16(CT), TMP5
- vpshufb .Lbswap_mask(%rip), TMP5, TMP5
- vpxor T, TMP5, TMP5
- vmovdqu 16*7(Htbl), TMP4
-
- vpclmulqdq $0x11, TMP4, TMP5, TMP3
- vpxor TMP3, TMP1, TMP1
- vpclmulqdq $0x00, TMP4, TMP5, TMP3
- vpxor TMP3, TMP2, TMP2
-
- vpshufd $78, TMP5, TMP3
- vpxor TMP5, TMP3, TMP5
- vmovdqu 128+7*16(Htbl), TMP4
-
- vpclmulqdq $0x00, TMP4, TMP5, TMP3
- vpxor TMP3, TMP0, TMP0
-
- ROUND 8
-
- vpxor TMP1, TMP0, TMP0
- vpxor TMP2, TMP0, TMP0
-
- vpsrldq $8, TMP0, TMP3
- vpxor TMP3, TMP1, TMP4
- vpslldq $8, TMP0, TMP3
- vpxor TMP3, TMP2, T
- vmovdqa .Lpoly(%rip), TMP2
-
- vpalignr $8, T, T, TMP1
- vpclmulqdq $0x10, TMP2, T, T
- vpxor T, TMP1, T
-
- ROUND 9
-
- vpalignr $8, T, T, TMP1
- vpclmulqdq $0x10, TMP2, T, T
- vpxor T, TMP1, T
-
- vmovdqu 160(KS), TMP5
- cmp $10, NR
-
- jbe .LDECLast1
-
- ROUND 10
- ROUND 11
-
- vmovdqu 192(KS), TMP5
- cmp $12, NR
-
- jbe .LDECLast1
-
- ROUND 12
- ROUND 13
-
- vmovdqu 224(KS), TMP5
-
-.LDECLast1:
-
- vpxor (CT), TMP5, TMP3
- vaesenclast TMP3, CTR0, CTR0
- vpxor 16(CT), TMP5, TMP3
- vaesenclast TMP3, CTR1, CTR1
- vpxor 32(CT), TMP5, TMP3
- vaesenclast TMP3, CTR2, CTR2
- vpxor 48(CT), TMP5, TMP3
- vaesenclast TMP3, CTR3, CTR3
- vpxor 64(CT), TMP5, TMP3
- vaesenclast TMP3, CTR4, CTR4
- vpxor 80(CT), TMP5, TMP3
- vaesenclast TMP3, CTR5, CTR5
- vpxor 96(CT), TMP5, TMP3
- vaesenclast TMP3, CTR6, CTR6
- vpxor 112(CT), TMP5, TMP3
- vaesenclast TMP3, CTR7, CTR7
-
- vmovdqu .Lbswap_mask(%rip), TMP3
-
- vmovdqu CTR0, (PT)
- vmovdqu CTR1, 16(PT)
- vmovdqu CTR2, 32(PT)
- vmovdqu CTR3, 48(PT)
- vmovdqu CTR4, 64(PT)
- vmovdqu CTR5, 80(PT)
- vmovdqu CTR6, 96(PT)
- vmovdqu CTR7,112(PT)
-
- vpxor TMP4, T, T
-
- lea 128(CT), CT
- lea 128(PT), PT
- jmp .LDECOctets
-
-#Here we decrypt and hash any remaining whole block
-.LDECSingles:
-
- cmp $16, len
- jb .LDECTail
- sub $16, len
-
- vmovdqu (CT), TMP1
- vpshufb .Lbswap_mask(%rip), TMP1, TMP1
- vpxor TMP1, T, T
- vmovdqu (Htbl), TMP0
- call GFMUL
-
-
- vpshufb .Lbswap_mask(%rip), CTR, TMP1
- vpaddd .Lone(%rip), CTR, CTR
-
- vpxor (KS), TMP1, TMP1
- vaesenc 16*1(KS), TMP1, TMP1
- vaesenc 16*2(KS), TMP1, TMP1
- vaesenc 16*3(KS), TMP1, TMP1
- vaesenc 16*4(KS), TMP1, TMP1
- vaesenc 16*5(KS), TMP1, TMP1
- vaesenc 16*6(KS), TMP1, TMP1
- vaesenc 16*7(KS), TMP1, TMP1
- vaesenc 16*8(KS), TMP1, TMP1
- vaesenc 16*9(KS), TMP1, TMP1
- vmovdqu 16*10(KS), TMP2
- cmp $10, NR
- je .LDECLast2
- vaesenc 16*10(KS), TMP1, TMP1
- vaesenc 16*11(KS), TMP1, TMP1
- vmovdqu 16*12(KS), TMP2
- cmp $12, NR
- je .LDECLast2
- vaesenc 16*12(KS), TMP1, TMP1
- vaesenc 16*13(KS), TMP1, TMP1
- vmovdqu 16*14(KS), TMP2
-.LDECLast2:
- vaesenclast TMP2, TMP1, TMP1
-
- vpxor (CT), TMP1, TMP1
- vmovdqu TMP1, (PT)
- addq $16, CT
- addq $16, PT
- jmp .LDECSingles
-
-#Here we decrypt the final partial block, if there is one
-.LDECTail:
- test len, len
- jz .LDEC_END
-
- vpshufb .Lbswap_mask(%rip), CTR, TMP1
- vpaddd .Lone(%rip), CTR, CTR
-
- vpxor (KS), TMP1, TMP1
- vaesenc 16*1(KS), TMP1, TMP1
- vaesenc 16*2(KS), TMP1, TMP1
- vaesenc 16*3(KS), TMP1, TMP1
- vaesenc 16*4(KS), TMP1, TMP1
- vaesenc 16*5(KS), TMP1, TMP1
- vaesenc 16*6(KS), TMP1, TMP1
- vaesenc 16*7(KS), TMP1, TMP1
- vaesenc 16*8(KS), TMP1, TMP1
- vaesenc 16*9(KS), TMP1, TMP1
- vmovdqu 16*10(KS), TMP2
- cmp $10, NR
- je .LDECLast3
- vaesenc 16*10(KS), TMP1, TMP1
- vaesenc 16*11(KS), TMP1, TMP1
- vmovdqu 16*12(KS), TMP2
- cmp $12, NR
- je .LDECLast3
- vaesenc 16*12(KS), TMP1, TMP1
- vaesenc 16*13(KS), TMP1, TMP1
- vmovdqu 16*14(KS), TMP2
-
-.LDECLast3:
- vaesenclast TMP2, TMP1, TMP1
-
- vpxor TMP2, TMP2, TMP2
- vmovdqa TMP2, (%rsp)
-# Copy the required bytes only (could probably use rep movsb)
- xor KS, KS
-.LDecCpy:
- cmp KS, len
- je .LDecCpy2
- movb (CT, KS, 1), %r8b
- movb %r8b, (%rsp, KS, 1)
- inc KS
- jmp .LDecCpy
-.LDecCpy2:
- cmp $16, KS
- je .LDecCpyEnd
- movb $0, (%rsp, KS, 1)
- inc KS
- jmp .LDecCpy2
-.LDecCpyEnd:
-# Xor with the counter block
- vmovdqa (%rsp), TMP0
- vpxor TMP0, TMP1, TMP1
-# Again, store at temp location
- vmovdqa TMP1, (%rsp)
-# Copy only the required bytes to PT, and zero the rest for the hash
- xor KS, KS
-.LDecCpy3:
- cmp KS, len
- je .LDecCpyEnd3
- movb (%rsp, KS, 1), %r8b
- movb %r8b, (PT, KS, 1)
- inc KS
- jmp .LDecCpy3
-.LDecCpyEnd3:
- vpshufb .Lbswap_mask(%rip), TMP0, TMP0
- vpxor TMP0, T, T
- vmovdqu (Htbl), TMP0
- call GFMUL
-.LDEC_END:
-
- vpshufb .Lbswap_mask(%rip), T, T
- vpshufb .Lbswap_mask(%rip), CTR, CTR
- vmovdqu T, 272(Gctx)
- vmovdqu CTR, 288(Gctx)
-
- movq %rbp, %rsp
-
- popq %rbx
- popq %rbp
- ret
- .size intel_aes_gcmDEC, .-intel_aes_gcmDEC
-#########################
-# a = T
-# b = TMP0 - remains unchanged
-# res = T
-# uses also TMP1,TMP2,TMP3,TMP4
-# __m128i GFMUL(__m128i A, __m128i B);
-.type GFMUL,@function
-.globl GFMUL
-GFMUL:
- vpclmulqdq $0x00, TMP0, T, TMP1
- vpclmulqdq $0x11, TMP0, T, TMP4
-
- vpshufd $78, T, TMP2
- vpshufd $78, TMP0, TMP3
- vpxor T, TMP2, TMP2
- vpxor TMP0, TMP3, TMP3
-
- vpclmulqdq $0x00, TMP3, TMP2, TMP2
- vpxor TMP1, TMP2, TMP2
- vpxor TMP4, TMP2, TMP2
-
- vpslldq $8, TMP2, TMP3
- vpsrldq $8, TMP2, TMP2
-
- vpxor TMP3, TMP1, TMP1
- vpxor TMP2, TMP4, TMP4
-
- vpclmulqdq $0x10, .Lpoly(%rip), TMP1, TMP2
- vpshufd $78, TMP1, TMP3
- vpxor TMP3, TMP2, TMP1
-
- vpclmulqdq $0x10, .Lpoly(%rip), TMP1, TMP2
- vpshufd $78, TMP1, TMP3
- vpxor TMP3, TMP2, TMP1
-
- vpxor TMP4, TMP1, T
- ret
-.size GFMUL, .-GFMUL
-
diff --git a/security/nss/lib/freebl/jpake.c b/security/nss/lib/freebl/jpake.c
deleted file mode 100644
index 88cdc6edd..000000000
--- a/security/nss/lib/freebl/jpake.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "blapi.h"
-#include "secerr.h"
-#include "secitem.h"
-#include "secmpi.h"
-
-/* Hash an item's length and then its value. Only items smaller than 2^16 bytes
- * are allowed. Lengths are hashed in network byte order. This is designed
- * to match the OpenSSL J-PAKE implementation.
- */
-static mp_err
-hashSECItem(HASHContext * hash, const SECItem * it)
-{
- unsigned char length[2];
-
- if (it->len > 0xffff)
- return MP_BADARG;
-
- length[0] = (unsigned char) (it->len >> 8);
- length[1] = (unsigned char) (it->len);
- hash->hashobj->update(hash->hash_context, length, 2);
- hash->hashobj->update(hash->hash_context, it->data, it->len);
- return MP_OKAY;
-}
-
-/* Hash all public components of the signature, each prefixed with its
- length, and then convert the hash to an mp_int. */
-static mp_err
-hashPublicParams(HASH_HashType hashType, const SECItem * g,
- const SECItem * gv, const SECItem * gx,
- const SECItem * signerID, mp_int * h)
-{
- mp_err err;
- unsigned char hBuf[HASH_LENGTH_MAX];
- SECItem hItem;
- HASHContext hash;
-
- hash.hashobj = HASH_GetRawHashObject(hashType);
- if (hash.hashobj == NULL || hash.hashobj->length > sizeof hBuf) {
- return MP_BADARG;
- }
- hash.hash_context = hash.hashobj->create();
- if (hash.hash_context == NULL) {
- return MP_MEM;
- }
-
- hItem.data = hBuf;
- hItem.len = hash.hashobj->length;
-
- hash.hashobj->begin(hash.hash_context);
- CHECK_MPI_OK( hashSECItem(&hash, g) );
- CHECK_MPI_OK( hashSECItem(&hash, gv) );
- CHECK_MPI_OK( hashSECItem(&hash, gx) );
- CHECK_MPI_OK( hashSECItem(&hash, signerID) );
- hash.hashobj->end(hash.hash_context, hItem.data, &hItem.len,
- sizeof hBuf);
- SECITEM_TO_MPINT(hItem, h);
-
-cleanup:
- if (hash.hash_context != NULL) {
- hash.hashobj->destroy(hash.hash_context, PR_TRUE);
- }
-
- return err;
-}
-
-/* Generate a Schnorr signature for round 1 or round 2 */
-SECStatus
-JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
- const SECItem * signerID, const SECItem * x,
- const SECItem * testRandom, const SECItem * gxIn, SECItem * gxOut,
- SECItem * gv, SECItem * r)
-{
- SECStatus rv = SECSuccess;
- mp_err err;
- mp_int p;
- mp_int q;
- mp_int g;
- mp_int X;
- mp_int GX;
- mp_int V;
- mp_int GV;
- mp_int h;
- mp_int tmp;
- mp_int R;
- SECItem v;
-
- if (!arena ||
- !pqg || !pqg->prime.data || pqg->prime.len == 0 ||
- !pqg->subPrime.data || pqg->subPrime.len == 0 ||
- !pqg->base.data || pqg->base.len == 0 ||
- !signerID || !signerID->data || signerID->len == 0 ||
- !x || !x->data || x->len == 0 ||
- (testRandom && (!testRandom->data || testRandom->len == 0)) ||
- (gxIn == NULL && (!gxOut || gxOut->data != NULL)) ||
- (gxIn != NULL && (!gxIn->data || gxIn->len == 0 || gxOut != NULL)) ||
- !gv || gv->data != NULL ||
- !r || r->data != NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
-
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&g) = 0;
- MP_DIGITS(&X) = 0;
- MP_DIGITS(&GX) = 0;
- MP_DIGITS(&V) = 0;
- MP_DIGITS(&GV) = 0;
- MP_DIGITS(&h) = 0;
- MP_DIGITS(&tmp) = 0;
- MP_DIGITS(&R) = 0;
-
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&g) );
- CHECK_MPI_OK( mp_init(&X) );
- CHECK_MPI_OK( mp_init(&GX) );
- CHECK_MPI_OK( mp_init(&V) );
- CHECK_MPI_OK( mp_init(&GV) );
- CHECK_MPI_OK( mp_init(&h) );
- CHECK_MPI_OK( mp_init(&tmp) );
- CHECK_MPI_OK( mp_init(&R) );
-
- SECITEM_TO_MPINT(pqg->prime, &p);
- SECITEM_TO_MPINT(pqg->subPrime, &q);
- SECITEM_TO_MPINT(pqg->base, &g);
- SECITEM_TO_MPINT(*x, &X);
-
- /* gx = g^x */
- if (gxIn == NULL) {
- CHECK_MPI_OK( mp_exptmod(&g, &X, &p, &GX) );
- MPINT_TO_SECITEM(&GX, gxOut, arena);
- gxIn = gxOut;
- } else {
- SECITEM_TO_MPINT(*gxIn, &GX);
- }
-
- /* v is a random value in the q subgroup */
- if (testRandom == NULL) {
- v.data = NULL;
- rv = DSA_NewRandom(arena, &pqg->subPrime, &v);
- if (rv != SECSuccess) {
- goto cleanup;
- }
- } else {
- v.data = testRandom->data;
- v.len = testRandom->len;
- }
- SECITEM_TO_MPINT(v, &V);
-
- /* gv = g^v (mod q), random v, 1 <= v < q */
- CHECK_MPI_OK( mp_exptmod(&g, &V, &p, &GV) );
- MPINT_TO_SECITEM(&GV, gv, arena);
-
- /* h = H(g, gv, gx, signerID) */
- CHECK_MPI_OK( hashPublicParams(hashType, &pqg->base, gv, gxIn, signerID,
- &h) );
-
- /* r = v - x*h (mod q) */
- CHECK_MPI_OK( mp_mulmod(&X, &h, &q, &tmp) );
- CHECK_MPI_OK( mp_submod(&V, &tmp, &q, &R) );
- MPINT_TO_SECITEM(&R, r, arena);
-
-cleanup:
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&g);
- mp_clear(&X);
- mp_clear(&GX);
- mp_clear(&V);
- mp_clear(&GV);
- mp_clear(&h);
- mp_clear(&tmp);
- mp_clear(&R);
-
- if (rv == SECSuccess && err != MP_OKAY) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/* Verify a Schnorr signature generated by the peer in round 1 or round 2. */
-SECStatus
-JPAKE_Verify(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
- const SECItem * signerID, const SECItem * peerID,
- const SECItem * gx, const SECItem * gv, const SECItem * r)
-{
- SECStatus rv = SECSuccess;
- mp_err err;
- mp_int p;
- mp_int q;
- mp_int g;
- mp_int p_minus_1;
- mp_int GX;
- mp_int h;
- mp_int one;
- mp_int R;
- mp_int gr;
- mp_int gxh;
- mp_int gr_gxh;
- SECItem calculated;
-
- if (!arena ||
- !pqg || !pqg->prime.data || pqg->prime.len == 0 ||
- !pqg->subPrime.data || pqg->subPrime.len == 0 ||
- !pqg->base.data || pqg->base.len == 0 ||
- !signerID || !signerID->data || signerID->len == 0 ||
- !peerID || !peerID->data || peerID->len == 0 ||
- !gx || !gx->data || gx->len == 0 ||
- !gv || !gv->data || gv->len == 0 ||
- !r || !r->data || r->len == 0 ||
- SECITEM_CompareItem(signerID, peerID) == SECEqual) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&g) = 0;
- MP_DIGITS(&p_minus_1) = 0;
- MP_DIGITS(&GX) = 0;
- MP_DIGITS(&h) = 0;
- MP_DIGITS(&one) = 0;
- MP_DIGITS(&R) = 0;
- MP_DIGITS(&gr) = 0;
- MP_DIGITS(&gxh) = 0;
- MP_DIGITS(&gr_gxh) = 0;
- calculated.data = NULL;
-
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&g) );
- CHECK_MPI_OK( mp_init(&p_minus_1) );
- CHECK_MPI_OK( mp_init(&GX) );
- CHECK_MPI_OK( mp_init(&h) );
- CHECK_MPI_OK( mp_init(&one) );
- CHECK_MPI_OK( mp_init(&R) );
- CHECK_MPI_OK( mp_init(&gr) );
- CHECK_MPI_OK( mp_init(&gxh) );
- CHECK_MPI_OK( mp_init(&gr_gxh) );
-
- SECITEM_TO_MPINT(pqg->prime, &p);
- SECITEM_TO_MPINT(pqg->subPrime, &q);
- SECITEM_TO_MPINT(pqg->base, &g);
- SECITEM_TO_MPINT(*gx, &GX);
- SECITEM_TO_MPINT(*r, &R);
-
- CHECK_MPI_OK( mp_sub_d(&p, 1, &p_minus_1) );
- CHECK_MPI_OK( mp_exptmod(&GX, &q, &p, &one) );
- /* Check g^x is in [1, p-2], R is in [0, q-1], and (g^x)^q mod p == 1 */
- if (!(mp_cmp_z(&GX) > 0 &&
- mp_cmp(&GX, &p_minus_1) < 0 &&
- mp_cmp(&R, &q) < 0 &&
- mp_cmp_d(&one, 1) == 0)) {
- goto badSig;
- }
-
- CHECK_MPI_OK( hashPublicParams(hashType, &pqg->base, gv, gx, peerID,
- &h) );
-
- /* Calculate g^v = g^r * g^x^h */
- CHECK_MPI_OK( mp_exptmod(&g, &R, &p, &gr) );
- CHECK_MPI_OK( mp_exptmod(&GX, &h, &p, &gxh) );
- CHECK_MPI_OK( mp_mulmod(&gr, &gxh, &p, &gr_gxh) );
-
- /* Compare calculated g^v to given g^v */
- MPINT_TO_SECITEM(&gr_gxh, &calculated, arena);
- if (calculated.len == gv->len &&
- NSS_SecureMemcmp(calculated.data, gv->data, calculated.len) == 0) {
- rv = SECSuccess;
- } else {
-badSig: PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- rv = SECFailure;
- }
-
-cleanup:
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&g);
- mp_clear(&p_minus_1);
- mp_clear(&GX);
- mp_clear(&h);
- mp_clear(&one);
- mp_clear(&R);
- mp_clear(&gr);
- mp_clear(&gxh);
- mp_clear(&gr_gxh);
-
- if (rv == SECSuccess && err != MP_OKAY) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/* Calculate base = gx1*gx3*gx4 (mod p), i.e. g^(x1+x3+x4) (mod p) */
-static mp_err
-jpake_Round2Base(const SECItem * gx1, const SECItem * gx3,
- const SECItem * gx4, const mp_int * p, mp_int * base)
-{
- mp_err err;
- mp_int GX1;
- mp_int GX3;
- mp_int GX4;
- mp_int tmp;
-
- MP_DIGITS(&GX1) = 0;
- MP_DIGITS(&GX3) = 0;
- MP_DIGITS(&GX4) = 0;
- MP_DIGITS(&tmp) = 0;
-
- CHECK_MPI_OK( mp_init(&GX1) );
- CHECK_MPI_OK( mp_init(&GX3) );
- CHECK_MPI_OK( mp_init(&GX4) );
- CHECK_MPI_OK( mp_init(&tmp) );
-
- SECITEM_TO_MPINT(*gx1, &GX1);
- SECITEM_TO_MPINT(*gx3, &GX3);
- SECITEM_TO_MPINT(*gx4, &GX4);
-
- /* In round 2, the peer/attacker sends us g^x3 and g^x4 and the protocol
- requires that these values are distinct. */
- if (mp_cmp(&GX3, &GX4) == 0) {
- return MP_BADARG;
- }
-
- CHECK_MPI_OK( mp_mul(&GX1, &GX3, &tmp) );
- CHECK_MPI_OK( mp_mul(&tmp, &GX4, &tmp) );
- CHECK_MPI_OK( mp_mod(&tmp, p, base) );
-
-cleanup:
- mp_clear(&GX1);
- mp_clear(&GX3);
- mp_clear(&GX4);
- mp_clear(&tmp);
- return err;
-}
-
-SECStatus
-JPAKE_Round2(PLArenaPool * arena,
- const SECItem * p, const SECItem *q, const SECItem * gx1,
- const SECItem * gx3, const SECItem * gx4, SECItem * base,
- const SECItem * x2, const SECItem * s, SECItem * x2s)
-{
- mp_err err;
- mp_int P;
- mp_int Q;
- mp_int X2;
- mp_int S;
- mp_int result;
-
- if (!arena ||
- !p || !p->data || p->len == 0 ||
- !q || !q->data || q->len == 0 ||
- !gx1 || !gx1->data || gx1->len == 0 ||
- !gx3 || !gx3->data || gx3->len == 0 ||
- !gx4 || !gx4->data || gx4->len == 0 ||
- !base || base->data != NULL ||
- (x2s != NULL && (x2s->data != NULL ||
- !x2 || !x2->data || x2->len == 0 ||
- !s || !s->data || s->len == 0))) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- MP_DIGITS(&P) = 0;
- MP_DIGITS(&Q) = 0;
- MP_DIGITS(&X2) = 0;
- MP_DIGITS(&S) = 0;
- MP_DIGITS(&result) = 0;
-
- CHECK_MPI_OK( mp_init(&P) );
- CHECK_MPI_OK( mp_init(&Q) );
- CHECK_MPI_OK( mp_init(&result) );
-
- if (x2s != NULL) {
- CHECK_MPI_OK( mp_init(&X2) );
- CHECK_MPI_OK( mp_init(&S) );
-
- SECITEM_TO_MPINT(*q, &Q);
- SECITEM_TO_MPINT(*x2, &X2);
-
- SECITEM_TO_MPINT(*s, &S);
- /* S must be in [1, Q-1] */
- if (mp_cmp_z(&S) <= 0 || mp_cmp(&S, &Q) >= 0) {
- err = MP_BADARG;
- goto cleanup;
- }
-
- CHECK_MPI_OK( mp_mulmod(&X2, &S, &Q, &result) );
- MPINT_TO_SECITEM(&result, x2s, arena);
- }
-
- SECITEM_TO_MPINT(*p, &P);
- CHECK_MPI_OK( jpake_Round2Base(gx1, gx3, gx4, &P, &result) );
- MPINT_TO_SECITEM(&result, base, arena);
-
-cleanup:
- mp_clear(&P);
- mp_clear(&Q);
- mp_clear(&X2);
- mp_clear(&S);
- mp_clear(&result);
-
- if (err != MP_OKAY) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-JPAKE_Final(PLArenaPool * arena, const SECItem * p, const SECItem * q,
- const SECItem * x2, const SECItem * gx4, const SECItem * x2s,
- const SECItem * B, SECItem * K)
-{
- mp_err err;
- mp_int P;
- mp_int Q;
- mp_int tmp;
- mp_int exponent;
- mp_int divisor;
- mp_int base;
-
- if (!arena ||
- !p || !p->data || p->len == 0 ||
- !q || !q->data || q->len == 0 ||
- !x2 || !x2->data || x2->len == 0 ||
- !gx4 || !gx4->data || gx4->len == 0 ||
- !x2s || !x2s->data || x2s->len == 0 ||
- !B || !B->data || B->len == 0 ||
- !K || K->data != NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- MP_DIGITS(&P) = 0;
- MP_DIGITS(&Q) = 0;
- MP_DIGITS(&tmp) = 0;
- MP_DIGITS(&exponent) = 0;
- MP_DIGITS(&divisor) = 0;
- MP_DIGITS(&base) = 0;
-
- CHECK_MPI_OK( mp_init(&P) );
- CHECK_MPI_OK( mp_init(&Q) );
- CHECK_MPI_OK( mp_init(&tmp) );
- CHECK_MPI_OK( mp_init(&exponent) );
- CHECK_MPI_OK( mp_init(&divisor) );
- CHECK_MPI_OK( mp_init(&base) );
-
- /* exponent = -x2s (mod q) */
- SECITEM_TO_MPINT(*q, &Q);
- SECITEM_TO_MPINT(*x2s, &tmp);
- /* q == 0 (mod q), so q - x2s == -x2s (mod q) */
- CHECK_MPI_OK( mp_sub(&Q, &tmp, &exponent) );
-
- /* divisor = gx4^-x2s = 1/(gx4^x2s) (mod p) */
- SECITEM_TO_MPINT(*p, &P);
- SECITEM_TO_MPINT(*gx4, &tmp);
- CHECK_MPI_OK( mp_exptmod(&tmp, &exponent, &P, &divisor) );
-
- /* base = B*divisor = B/(gx4^x2s) (mod p) */
- SECITEM_TO_MPINT(*B, &tmp);
- CHECK_MPI_OK( mp_mulmod(&divisor, &tmp, &P, &base) );
-
- /* tmp = base^x2 (mod p) */
- SECITEM_TO_MPINT(*x2, &exponent);
- CHECK_MPI_OK( mp_exptmod(&base, &exponent, &P, &tmp) );
-
- MPINT_TO_SECITEM(&tmp, K, arena);
-
-cleanup:
- mp_clear(&P);
- mp_clear(&Q);
- mp_clear(&tmp);
- mp_clear(&exponent);
- mp_clear(&divisor);
- mp_clear(&base);
-
- if (err != MP_OKAY) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
- }
- return SECSuccess;
-}
diff --git a/security/nss/lib/freebl/ldvector.c b/security/nss/lib/freebl/ldvector.c
deleted file mode 100644
index 186ae2f5e..000000000
--- a/security/nss/lib/freebl/ldvector.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * ldvector.c - platform dependent DSO containing freebl implementation.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-extern int FREEBL_InitStubs(void);
-#endif
-
-#include "loader.h"
-#include "alghmac.h"
-#include "hmacct.h"
-
-
-static const struct FREEBLVectorStr vector =
-{
-
- sizeof vector,
- FREEBL_VERSION,
-
- RSA_NewKey,
- RSA_PublicKeyOp,
- RSA_PrivateKeyOp,
- DSA_NewKey,
- DSA_SignDigest,
- DSA_VerifyDigest,
- DSA_NewKeyFromSeed,
- DSA_SignDigestWithSeed,
- DH_GenParam,
- DH_NewKey,
- DH_Derive,
- KEA_Derive,
- KEA_Verify,
- RC4_CreateContext,
- RC4_DestroyContext,
- RC4_Encrypt,
- RC4_Decrypt,
- RC2_CreateContext,
- RC2_DestroyContext,
- RC2_Encrypt,
- RC2_Decrypt,
- RC5_CreateContext,
- RC5_DestroyContext,
- RC5_Encrypt,
- RC5_Decrypt,
- DES_CreateContext,
- DES_DestroyContext,
- DES_Encrypt,
- DES_Decrypt,
- AES_CreateContext,
- AES_DestroyContext,
- AES_Encrypt,
- AES_Decrypt,
- MD5_Hash,
- MD5_HashBuf,
- MD5_NewContext,
- MD5_DestroyContext,
- MD5_Begin,
- MD5_Update,
- MD5_End,
- MD5_FlattenSize,
- MD5_Flatten,
- MD5_Resurrect,
- MD5_TraceState,
- MD2_Hash,
- MD2_NewContext,
- MD2_DestroyContext,
- MD2_Begin,
- MD2_Update,
- MD2_End,
- MD2_FlattenSize,
- MD2_Flatten,
- MD2_Resurrect,
- SHA1_Hash,
- SHA1_HashBuf,
- SHA1_NewContext,
- SHA1_DestroyContext,
- SHA1_Begin,
- SHA1_Update,
- SHA1_End,
- SHA1_TraceState,
- SHA1_FlattenSize,
- SHA1_Flatten,
- SHA1_Resurrect,
- RNG_RNGInit,
- RNG_RandomUpdate,
- RNG_GenerateGlobalRandomBytes,
- RNG_RNGShutdown,
- PQG_ParamGen,
- PQG_ParamGenSeedLen,
- PQG_VerifyParams,
-
- /* End of Version 3.001. */
-
- RSA_PrivateKeyOpDoubleChecked,
- RSA_PrivateKeyCheck,
- BL_Cleanup,
-
- /* End of Version 3.002. */
-
- SHA256_NewContext,
- SHA256_DestroyContext,
- SHA256_Begin,
- SHA256_Update,
- SHA256_End,
- SHA256_HashBuf,
- SHA256_Hash,
- SHA256_TraceState,
- SHA256_FlattenSize,
- SHA256_Flatten,
- SHA256_Resurrect,
-
- SHA512_NewContext,
- SHA512_DestroyContext,
- SHA512_Begin,
- SHA512_Update,
- SHA512_End,
- SHA512_HashBuf,
- SHA512_Hash,
- SHA512_TraceState,
- SHA512_FlattenSize,
- SHA512_Flatten,
- SHA512_Resurrect,
-
- SHA384_NewContext,
- SHA384_DestroyContext,
- SHA384_Begin,
- SHA384_Update,
- SHA384_End,
- SHA384_HashBuf,
- SHA384_Hash,
- SHA384_TraceState,
- SHA384_FlattenSize,
- SHA384_Flatten,
- SHA384_Resurrect,
-
- /* End of Version 3.003. */
-
- AESKeyWrap_CreateContext,
- AESKeyWrap_DestroyContext,
- AESKeyWrap_Encrypt,
- AESKeyWrap_Decrypt,
-
- /* End of Version 3.004. */
-
- BLAPI_SHVerify,
- BLAPI_VerifySelf,
-
- /* End of Version 3.005. */
-
- EC_NewKey,
- EC_NewKeyFromSeed,
- EC_ValidatePublicKey,
- ECDH_Derive,
- ECDSA_SignDigest,
- ECDSA_VerifyDigest,
- ECDSA_SignDigestWithSeed,
-
- /* End of Version 3.006. */
- /* End of Version 3.007. */
-
- AES_InitContext,
- AESKeyWrap_InitContext,
- DES_InitContext,
- RC2_InitContext,
- RC4_InitContext,
-
- AES_AllocateContext,
- AESKeyWrap_AllocateContext,
- DES_AllocateContext,
- RC2_AllocateContext,
- RC4_AllocateContext,
-
- MD2_Clone,
- MD5_Clone,
- SHA1_Clone,
- SHA256_Clone,
- SHA384_Clone,
- SHA512_Clone,
-
- TLS_PRF,
- HASH_GetRawHashObject,
-
- HMAC_Create,
- HMAC_Init,
- HMAC_Begin,
- HMAC_Update,
- HMAC_Clone,
- HMAC_Finish,
- HMAC_Destroy,
-
- RNG_SystemInfoForRNG,
-
- /* End of Version 3.008. */
-
- FIPS186Change_GenerateX,
- FIPS186Change_ReduceModQForDSA,
-
- /* End of Version 3.009. */
- Camellia_InitContext,
- Camellia_AllocateContext,
- Camellia_CreateContext,
- Camellia_DestroyContext,
- Camellia_Encrypt,
- Camellia_Decrypt,
-
- PQG_DestroyParams,
- PQG_DestroyVerify,
-
- /* End of Version 3.010. */
-
- SEED_InitContext,
- SEED_AllocateContext,
- SEED_CreateContext,
- SEED_DestroyContext,
- SEED_Encrypt,
- SEED_Decrypt,
-
- BL_Init,
- BL_SetForkState,
-
- PRNGTEST_Instantiate,
- PRNGTEST_Reseed,
- PRNGTEST_Generate,
-
- PRNGTEST_Uninstantiate,
-
- /* End of Version 3.011. */
-
- RSA_PopulatePrivateKey,
-
- DSA_NewRandom,
-
- JPAKE_Sign,
- JPAKE_Verify,
- JPAKE_Round2,
- JPAKE_Final,
-
- /* End of Version 3.012 */
-
- TLS_P_hash,
- SHA224_NewContext,
- SHA224_DestroyContext,
- SHA224_Begin,
- SHA224_Update,
- SHA224_End,
- SHA224_HashBuf,
- SHA224_Hash,
- SHA224_TraceState,
- SHA224_FlattenSize,
- SHA224_Flatten,
- SHA224_Resurrect,
- SHA224_Clone,
- BLAPI_SHVerifyFile,
-
- /* End of Version 3.013 */
-
- PQG_ParamGenV2,
- PRNGTEST_RunHealthTests,
-
- /* End of Version 3.014 */
-
- HMAC_ConstantTime,
- SSLv3_MAC_ConstantTime
-
- /* End of Version 3.015 */
-};
-
-const FREEBLVector *
-FREEBL_GetVector(void)
-{
- extern const char __nss_freebl_rcsid[];
- extern const char __nss_freebl_sccsid[];
-
- /* force a reference that won't get optimized away */
- volatile char c;
-
- c = __nss_freebl_rcsid[0] + __nss_freebl_sccsid[0];
-#ifdef FREEBL_NO_DEPEND
- FREEBL_InitStubs();
-#endif
- return &vector;
-}
-
diff --git a/security/nss/lib/freebl/loader.c b/security/nss/lib/freebl/loader.c
deleted file mode 100644
index e76a69676..000000000
--- a/security/nss/lib/freebl/loader.c
+++ /dev/null
@@ -1,1909 +0,0 @@
-/*
- * loader.c - load platform dependent DSO containing freebl implementation.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "loader.h"
-#include "prmem.h"
-#include "prerror.h"
-#include "prinit.h"
-#include "prenv.h"
-
-static const char* default_name =
- SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX;
-
-/* getLibName() returns the name of the library to load. */
-
-#if defined(SOLARIS) && defined(__sparc)
-#include <stddef.h>
-#include <strings.h>
-#include <sys/systeminfo.h>
-
-
-#if defined(NSS_USE_64)
-
-const static char fpu_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
-const static char int_hybrid_shared_lib[] = "libfreebl_64int_3.so";
-const static char non_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
-
-const static char int_hybrid_isa[] = "sparcv9";
-const static char fpu_hybrid_isa[] = "sparcv9+vis";
-
-#else
-
-const static char fpu_hybrid_shared_lib[] = "libfreebl_32fpu_3.so";
-const static char int_hybrid_shared_lib[] = "libfreebl_32int64_3.so";
-/* This was for SPARC V8, now obsolete. */
-const static char *const non_hybrid_shared_lib = NULL;
-
-const static char int_hybrid_isa[] = "sparcv8plus";
-const static char fpu_hybrid_isa[] = "sparcv8plus+vis";
-
-#endif
-
-static const char *
-getLibName(void)
-{
- char * found_int_hybrid;
- char * found_fpu_hybrid;
- long buflen;
- char buf[256];
-
- buflen = sysinfo(SI_ISALIST, buf, sizeof buf);
- if (buflen <= 0)
- return NULL;
- /* sysinfo output is always supposed to be NUL terminated, but ... */
- if (buflen < sizeof buf)
- buf[buflen] = '\0';
- else
- buf[(sizeof buf) - 1] = '\0';
- /* The ISA list is a space separated string of names of ISAs and
- * ISA extensions, in order of decreasing performance.
- * There are two different ISAs with which NSS's crypto code can be
- * accelerated. If both are in the list, we take the first one.
- * If one is in the list, we use it, and if neither then we use
- * the base unaccelerated code.
- */
- found_int_hybrid = strstr(buf, int_hybrid_isa);
- found_fpu_hybrid = strstr(buf, fpu_hybrid_isa);
- if (found_fpu_hybrid &&
- (!found_int_hybrid ||
- (found_int_hybrid - found_fpu_hybrid) >= 0)) {
- return fpu_hybrid_shared_lib;
- }
- if (found_int_hybrid) {
- return int_hybrid_shared_lib;
- }
- return non_hybrid_shared_lib;
-}
-
-#elif defined(HPUX) && !defined(NSS_USE_64) && !defined(__ia64)
-/* This code tests to see if we're running on a PA2.x CPU.
-** It returns true (1) if so, and false (0) otherwise.
-*/
-static const char *
-getLibName(void)
-{
- long cpu = sysconf(_SC_CPU_VERSION);
- return (cpu == CPU_PA_RISC2_0)
- ? "libfreebl_32fpu_3.sl"
- : "libfreebl_32int_3.sl" ;
-}
-#else
-/* default case, for platforms/ABIs that have only one freebl shared lib. */
-static const char * getLibName(void) { return default_name; }
-#endif
-
-#include "prio.h"
-#include "prprf.h"
-#include <stdio.h>
-#include "prsystem.h"
-
-static const char *NameOfThisSharedLib =
- SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX;
-
-static PRLibrary* blLib;
-
-#define LSB(x) ((x)&0xff)
-#define MSB(x) ((x)>>8)
-
-static const FREEBLVector *vector;
-static const char *libraryName = NULL;
-
-#include "genload.c"
-
-/* This function must be run only once. */
-/* determine if hybrid platform, then actually load the DSO. */
-static PRStatus
-freebl_LoadDSO( void )
-{
- PRLibrary * handle;
- const char * name = getLibName();
-
- if (!name) {
- PR_SetError(PR_LOAD_LIBRARY_ERROR, 0);
- return PR_FAILURE;
- }
-
- handle = loader_LoadLibrary(name);
- if (handle) {
- PRFuncPtr address = PR_FindFunctionSymbol(handle, "FREEBL_GetVector");
- PRStatus status;
- if (address) {
- FREEBLGetVectorFn * getVector = (FREEBLGetVectorFn *)address;
- const FREEBLVector * dsoVector = getVector();
- if (dsoVector) {
- unsigned short dsoVersion = dsoVector->version;
- unsigned short myVersion = FREEBL_VERSION;
- if (MSB(dsoVersion) == MSB(myVersion) &&
- LSB(dsoVersion) >= LSB(myVersion) &&
- dsoVector->length >= sizeof(FREEBLVector)) {
- vector = dsoVector;
- libraryName = name;
- blLib = handle;
- return PR_SUCCESS;
- }
- }
- }
- status = PR_UnloadLibrary(handle);
- PORT_Assert(PR_SUCCESS == status);
- }
- return PR_FAILURE;
-}
-
-static const PRCallOnceType pristineCallOnce;
-static PRCallOnceType loadFreeBLOnce;
-
-static PRStatus
-freebl_RunLoaderOnce( void )
-{
- PRStatus status;
-
- status = PR_CallOnce(&loadFreeBLOnce, &freebl_LoadDSO);
- return status;
-}
-
-SECStatus
-BL_Init(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_BL_Init)();
-}
-
-RSAPrivateKey *
-RSA_NewKey(int keySizeInBits, SECItem * publicExponent)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_RSA_NewKey)(keySizeInBits, publicExponent);
-}
-
-SECStatus
-RSA_PublicKeyOp(RSAPublicKey * key,
- unsigned char * output,
- const unsigned char * input)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_PublicKeyOp)(key, output, input);
-}
-
-SECStatus
-RSA_PrivateKeyOp(RSAPrivateKey * key,
- unsigned char * output,
- const unsigned char * input)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_PrivateKeyOp)(key, output, input);
-}
-
-SECStatus
-RSA_PrivateKeyOpDoubleChecked(RSAPrivateKey *key,
- unsigned char *output,
- const unsigned char *input)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_PrivateKeyOpDoubleChecked)(key, output, input);
-}
-
-SECStatus
-RSA_PrivateKeyCheck(RSAPrivateKey *key)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_PrivateKeyCheck)(key);
-}
-
-SECStatus
-DSA_NewKey(const PQGParams * params, DSAPrivateKey ** privKey)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DSA_NewKey)(params, privKey);
-}
-
-SECStatus
-DSA_SignDigest(DSAPrivateKey * key, SECItem * signature, const SECItem * digest)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DSA_SignDigest)( key, signature, digest);
-}
-
-SECStatus
-DSA_VerifyDigest(DSAPublicKey * key, const SECItem * signature,
- const SECItem * digest)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DSA_VerifyDigest)( key, signature, digest);
-}
-
-SECStatus
-DSA_NewKeyFromSeed(const PQGParams *params, const unsigned char * seed,
- DSAPrivateKey **privKey)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DSA_NewKeyFromSeed)(params, seed, privKey);
-}
-
-SECStatus
-DSA_SignDigestWithSeed(DSAPrivateKey * key, SECItem * signature,
- const SECItem * digest, const unsigned char * seed)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DSA_SignDigestWithSeed)( key, signature, digest, seed);
-}
-
-SECStatus
-DSA_NewRandom(PLArenaPool * arena, const SECItem * q, SECItem * seed)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DSA_NewRandom)(arena, q, seed);
-}
-
-SECStatus
-DH_GenParam(int primeLen, DHParams ** params)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DH_GenParam)(primeLen, params);
-}
-
-SECStatus
-DH_NewKey(DHParams * params, DHPrivateKey ** privKey)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DH_NewKey)( params, privKey);
-}
-
-SECStatus
-DH_Derive(SECItem * publicValue, SECItem * prime, SECItem * privateValue,
- SECItem * derivedSecret, unsigned int maxOutBytes)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DH_Derive)( publicValue, prime, privateValue,
- derivedSecret, maxOutBytes);
-}
-
-SECStatus
-KEA_Derive(SECItem *prime, SECItem *public1, SECItem *public2,
- SECItem *private1, SECItem *private2, SECItem *derivedSecret)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_KEA_Derive)(prime, public1, public2,
- private1, private2, derivedSecret);
-}
-
-PRBool
-KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return PR_FALSE;
- return (vector->p_KEA_Verify)(Y, prime, subPrime);
-}
-
-RC4Context *
-RC4_CreateContext(const unsigned char *key, int len)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_RC4_CreateContext)(key, len);
-}
-
-void
-RC4_DestroyContext(RC4Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_RC4_DestroyContext)(cx, freeit);
-}
-
-SECStatus
-RC4_Encrypt(RC4Context *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RC4_Encrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-SECStatus
-RC4_Decrypt(RC4Context *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RC4_Decrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-RC2Context *
-RC2_CreateContext(const unsigned char *key, unsigned int len,
- const unsigned char *iv, int mode, unsigned effectiveKeyLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_RC2_CreateContext)(key, len, iv, mode, effectiveKeyLen);
-}
-
-void
-RC2_DestroyContext(RC2Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_RC2_DestroyContext)(cx, freeit);
-}
-
-SECStatus
-RC2_Encrypt(RC2Context *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RC2_Encrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-SECStatus
-RC2_Decrypt(RC2Context *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RC2_Decrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-RC5Context *
-RC5_CreateContext(const SECItem *key, unsigned int rounds,
- unsigned int wordSize, const unsigned char *iv, int mode)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_RC5_CreateContext)(key, rounds, wordSize, iv, mode);
-}
-
-void
-RC5_DestroyContext(RC5Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_RC5_DestroyContext)(cx, freeit);
-}
-
-SECStatus
-RC5_Encrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RC5_Encrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-SECStatus
-RC5_Decrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RC5_Decrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-DESContext *
-DES_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, PRBool encrypt)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_DES_CreateContext)(key, iv, mode, encrypt);
-}
-
-void
-DES_DestroyContext(DESContext *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_DES_DestroyContext)(cx, freeit);
-}
-
-SECStatus
-DES_Encrypt(DESContext *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DES_Encrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-SECStatus
-DES_Decrypt(DESContext *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DES_Decrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-SEEDContext *
-SEED_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, PRBool encrypt)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SEED_CreateContext)(key, iv, mode, encrypt);
-}
-
-void
-SEED_DestroyContext(SEEDContext *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SEED_DestroyContext)(cx, freeit);
-}
-
-SECStatus
-SEED_Encrypt(SEEDContext *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SEED_Encrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-SECStatus
-SEED_Decrypt(SEEDContext *cx, unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SEED_Decrypt)(cx, output, outputLen, maxOutputLen, input,
- inputLen);
-}
-
-AESContext *
-AES_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, int encrypt,
- unsigned int keylen, unsigned int blocklen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_AES_CreateContext)(key, iv, mode, encrypt, keylen,
- blocklen);
-}
-
-void
-AES_DestroyContext(AESContext *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_AES_DestroyContext)(cx, freeit);
-}
-
-SECStatus
-AES_Encrypt(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_AES_Encrypt)(cx, output, outputLen, maxOutputLen,
- input, inputLen);
-}
-
-SECStatus
-AES_Decrypt(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_AES_Decrypt)(cx, output, outputLen, maxOutputLen,
- input, inputLen);
-}
-
-SECStatus
-MD5_Hash(unsigned char *dest, const char *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD5_Hash)(dest, src);
-}
-
-SECStatus
-MD5_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD5_HashBuf)(dest, src, src_length);
-}
-
-MD5Context *
-MD5_NewContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_MD5_NewContext)();
-}
-
-void
-MD5_DestroyContext(MD5Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD5_DestroyContext)(cx, freeit);
-}
-
-void
-MD5_Begin(MD5Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD5_Begin)(cx);
-}
-
-void
-MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD5_Update)(cx, input, inputLen);
-}
-
-void
-MD5_End(MD5Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD5_End)(cx, digest, digestLen, maxDigestLen);
-}
-
-unsigned int
-MD5_FlattenSize(MD5Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_MD5_FlattenSize)(cx);
-}
-
-SECStatus
-MD5_Flatten(MD5Context *cx,unsigned char *space)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD5_Flatten)(cx, space);
-}
-
-MD5Context *
-MD5_Resurrect(unsigned char *space, void *arg)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_MD5_Resurrect)(space, arg);
-}
-
-void
-MD5_TraceState(MD5Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_MD5_TraceState)(cx);
-}
-
-SECStatus
-MD2_Hash(unsigned char *dest, const char *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD2_Hash)(dest, src);
-}
-
-MD2Context *
-MD2_NewContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_MD2_NewContext)();
-}
-
-void
-MD2_DestroyContext(MD2Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_MD2_DestroyContext)(cx, freeit);
-}
-
-void
-MD2_Begin(MD2Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_MD2_Begin)(cx);
-}
-
-void
-MD2_Update(MD2Context *cx, const unsigned char *input, unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_MD2_Update)(cx, input, inputLen);
-}
-
-void
-MD2_End(MD2Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_MD2_End)(cx, digest, digestLen, maxDigestLen);
-}
-
-unsigned int
-MD2_FlattenSize(MD2Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_MD2_FlattenSize)(cx);
-}
-
-SECStatus
-MD2_Flatten(MD2Context *cx,unsigned char *space)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_MD2_Flatten)(cx, space);
-}
-
-MD2Context *
-MD2_Resurrect(unsigned char *space, void *arg)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_MD2_Resurrect)(space, arg);
-}
-
-
-SECStatus
-SHA1_Hash(unsigned char *dest, const char *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA1_Hash)(dest, src);
-}
-
-SECStatus
-SHA1_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA1_HashBuf)(dest, src, src_length);
-}
-
-SHA1Context *
-SHA1_NewContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA1_NewContext)();
-}
-
-void
-SHA1_DestroyContext(SHA1Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_DestroyContext)(cx, freeit);
-}
-
-void
-SHA1_Begin(SHA1Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_Begin)(cx);
-}
-
-void
-SHA1_Update(SHA1Context *cx, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_Update)(cx, input, inputLen);
-}
-
-void
-SHA1_End(SHA1Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_End)(cx, digest, digestLen, maxDigestLen);
-}
-
-void
-SHA1_TraceState(SHA1Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA1_TraceState)(cx);
-}
-
-unsigned int
-SHA1_FlattenSize(SHA1Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_SHA1_FlattenSize)(cx);
-}
-
-SECStatus
-SHA1_Flatten(SHA1Context *cx,unsigned char *space)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA1_Flatten)(cx, space);
-}
-
-SHA1Context *
-SHA1_Resurrect(unsigned char *space, void *arg)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA1_Resurrect)(space, arg);
-}
-
-SECStatus
-RNG_RNGInit(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RNG_RNGInit)();
-}
-
-SECStatus
-RNG_RandomUpdate(const void *data, size_t bytes)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RNG_RandomUpdate)(data, bytes);
-}
-
-SECStatus
-RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RNG_GenerateGlobalRandomBytes)(dest, len);
-}
-
-void
-RNG_RNGShutdown(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_RNG_RNGShutdown)();
-}
-
-SECStatus
-PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_PQG_ParamGen)(j, pParams, pVfy);
-}
-
-SECStatus
-PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_PQG_ParamGenSeedLen)(j, seedBytes, pParams, pVfy);
-}
-
-
-SECStatus
-PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy,
- SECStatus *result)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_PQG_VerifyParams)(params, vfy, result);
-}
-
-void
-PQG_DestroyParams(PQGParams *params)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_PQG_DestroyParams)(params);
-}
-
-void
-PQG_DestroyVerify(PQGVerify *vfy)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_PQG_DestroyVerify)(vfy);
-}
-
-void
-BL_Cleanup(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_BL_Cleanup)();
-}
-
-void
-BL_Unload(void)
-{
- /* This function is not thread-safe, but doesn't need to be, because it is
- * only called from functions that are also defined as not thread-safe,
- * namely C_Finalize in softoken, and the SSL bypass shutdown callback called
- * from NSS_Shutdown. */
- char *disableUnload = NULL;
- vector = NULL;
- /* If an SSL socket is configured with SSL_BYPASS_PKCS11, but the application
- * never does a handshake on it, BL_Unload will be called even though freebl
- * was never loaded. So, don't assert blLib. */
- if (blLib) {
- disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
- if (!disableUnload) {
- PRStatus status = PR_UnloadLibrary(blLib);
- PORT_Assert(PR_SUCCESS == status);
- }
- blLib = NULL;
- }
- loadFreeBLOnce = pristineCallOnce;
-}
-
-/* ============== New for 3.003 =============================== */
-
-SECStatus
-SHA256_Hash(unsigned char *dest, const char *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA256_Hash)(dest, src);
-}
-
-SECStatus
-SHA256_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA256_HashBuf)(dest, src, src_length);
-}
-
-SHA256Context *
-SHA256_NewContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA256_NewContext)();
-}
-
-void
-SHA256_DestroyContext(SHA256Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_DestroyContext)(cx, freeit);
-}
-
-void
-SHA256_Begin(SHA256Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_Begin)(cx);
-}
-
-void
-SHA256_Update(SHA256Context *cx, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_Update)(cx, input, inputLen);
-}
-
-void
-SHA256_End(SHA256Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_End)(cx, digest, digestLen, maxDigestLen);
-}
-
-void
-SHA256_TraceState(SHA256Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA256_TraceState)(cx);
-}
-
-unsigned int
-SHA256_FlattenSize(SHA256Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_SHA256_FlattenSize)(cx);
-}
-
-SECStatus
-SHA256_Flatten(SHA256Context *cx,unsigned char *space)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA256_Flatten)(cx, space);
-}
-
-SHA256Context *
-SHA256_Resurrect(unsigned char *space, void *arg)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA256_Resurrect)(space, arg);
-}
-
-SECStatus
-SHA512_Hash(unsigned char *dest, const char *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA512_Hash)(dest, src);
-}
-
-SECStatus
-SHA512_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA512_HashBuf)(dest, src, src_length);
-}
-
-SHA512Context *
-SHA512_NewContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA512_NewContext)();
-}
-
-void
-SHA512_DestroyContext(SHA512Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_DestroyContext)(cx, freeit);
-}
-
-void
-SHA512_Begin(SHA512Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_Begin)(cx);
-}
-
-void
-SHA512_Update(SHA512Context *cx, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_Update)(cx, input, inputLen);
-}
-
-void
-SHA512_End(SHA512Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_End)(cx, digest, digestLen, maxDigestLen);
-}
-
-void
-SHA512_TraceState(SHA512Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA512_TraceState)(cx);
-}
-
-unsigned int
-SHA512_FlattenSize(SHA512Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_SHA512_FlattenSize)(cx);
-}
-
-SECStatus
-SHA512_Flatten(SHA512Context *cx,unsigned char *space)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA512_Flatten)(cx, space);
-}
-
-SHA512Context *
-SHA512_Resurrect(unsigned char *space, void *arg)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA512_Resurrect)(space, arg);
-}
-
-
-SECStatus
-SHA384_Hash(unsigned char *dest, const char *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA384_Hash)(dest, src);
-}
-
-SECStatus
-SHA384_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA384_HashBuf)(dest, src, src_length);
-}
-
-SHA384Context *
-SHA384_NewContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA384_NewContext)();
-}
-
-void
-SHA384_DestroyContext(SHA384Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_DestroyContext)(cx, freeit);
-}
-
-void
-SHA384_Begin(SHA384Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_Begin)(cx);
-}
-
-void
-SHA384_Update(SHA384Context *cx, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_Update)(cx, input, inputLen);
-}
-
-void
-SHA384_End(SHA384Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_End)(cx, digest, digestLen, maxDigestLen);
-}
-
-void
-SHA384_TraceState(SHA384Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_SHA384_TraceState)(cx);
-}
-
-unsigned int
-SHA384_FlattenSize(SHA384Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_SHA384_FlattenSize)(cx);
-}
-
-SECStatus
-SHA384_Flatten(SHA384Context *cx,unsigned char *space)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA384_Flatten)(cx, space);
-}
-
-SHA384Context *
-SHA384_Resurrect(unsigned char *space, void *arg)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA384_Resurrect)(space, arg);
-}
-
-
-AESKeyWrapContext *
-AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv,
- int encrypt, unsigned int keylen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return vector->p_AESKeyWrap_CreateContext(key, iv, encrypt, keylen);
-}
-
-void
-AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- vector->p_AESKeyWrap_DestroyContext(cx, freeit);
-}
-
-SECStatus
-AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return vector->p_AESKeyWrap_Encrypt(cx, output, outputLen, maxOutputLen,
- input, inputLen);
-}
-SECStatus
-AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return vector->p_AESKeyWrap_Decrypt(cx, output, outputLen, maxOutputLen,
- input, inputLen);
-}
-
-PRBool
-BLAPI_SHVerify(const char *name, PRFuncPtr addr)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return PR_FALSE;
- return vector->p_BLAPI_SHVerify(name, addr);
-}
-
-/*
- * The Caller is expected to pass NULL as the name, which will
- * trigger the p_BLAPI_VerifySelf() to return 'TRUE'. Pass the real
- * name of the shared library we loaded (the static libraryName set
- * in freebl_LoadDSO) to p_BLAPI_VerifySelf.
- */
-PRBool
-BLAPI_VerifySelf(const char *name)
-{
- PORT_Assert(!name);
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return PR_FALSE;
- return vector->p_BLAPI_VerifySelf(libraryName);
-}
-
-/* ============== New for 3.006 =============================== */
-
-SECStatus
-EC_NewKey(ECParams * params, ECPrivateKey ** privKey)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_EC_NewKey)( params, privKey );
-}
-
-SECStatus
-EC_NewKeyFromSeed(ECParams * params, ECPrivateKey ** privKey,
- const unsigned char *seed, int seedlen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_EC_NewKeyFromSeed)( params, privKey, seed, seedlen );
-}
-
-SECStatus
-EC_ValidatePublicKey(ECParams * params, SECItem * publicValue)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_EC_ValidatePublicKey)( params, publicValue );
-}
-
-SECStatus
-ECDH_Derive(SECItem * publicValue, ECParams * params, SECItem * privateValue,
- PRBool withCofactor, SECItem * derivedSecret)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_ECDH_Derive)( publicValue, params, privateValue,
- withCofactor, derivedSecret );
-}
-
-SECStatus
-ECDSA_SignDigest(ECPrivateKey * key, SECItem * signature,
- const SECItem * digest)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_ECDSA_SignDigest)( key, signature, digest );
-}
-
-SECStatus
-ECDSA_VerifyDigest(ECPublicKey * key, const SECItem * signature,
- const SECItem * digest)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_ECDSA_VerifyDigest)( key, signature, digest );
-}
-
-SECStatus
-ECDSA_SignDigestWithSeed(ECPrivateKey * key, SECItem * signature,
- const SECItem * digest, const unsigned char *seed, const int seedlen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_ECDSA_SignDigestWithSeed)( key, signature, digest,
- seed, seedlen );
-}
-
-/* ============== New for 3.008 =============================== */
-
-AESContext *
-AES_AllocateContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_AES_AllocateContext)();
-}
-
-AESKeyWrapContext *
-AESKeyWrap_AllocateContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_AESKeyWrap_AllocateContext)();
-}
-
-DESContext *
-DES_AllocateContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_DES_AllocateContext)();
-}
-
-RC2Context *
-RC2_AllocateContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_RC2_AllocateContext)();
-}
-
-RC4Context *
-RC4_AllocateContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_RC4_AllocateContext)();
-}
-
-SECStatus
-AES_InitContext(AESContext *cx, const unsigned char *key,
- unsigned int keylen, const unsigned char *iv, int mode,
- unsigned int encrypt, unsigned int blocklen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_AES_InitContext)(cx, key, keylen, iv, mode, encrypt,
- blocklen);
-}
-
-SECStatus
-AESKeyWrap_InitContext(AESKeyWrapContext *cx, const unsigned char *key,
- unsigned int keylen, const unsigned char *iv, int mode,
- unsigned int encrypt, unsigned int blocklen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_AESKeyWrap_InitContext)(cx, key, keylen, iv, mode,
- encrypt, blocklen);
-}
-
-SECStatus
-DES_InitContext(DESContext *cx, const unsigned char *key,
- unsigned int keylen, const unsigned char *iv, int mode,
- unsigned int encrypt, unsigned int xtra)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_DES_InitContext)(cx, key, keylen, iv, mode, encrypt, xtra);
-}
-
-SECStatus
-SEED_InitContext(SEEDContext *cx, const unsigned char *key,
- unsigned int keylen, const unsigned char *iv, int mode,
- unsigned int encrypt, unsigned int xtra)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SEED_InitContext)(cx, key, keylen, iv, mode, encrypt, xtra);
-}
-
-SECStatus
-RC2_InitContext(RC2Context *cx, const unsigned char *key,
- unsigned int keylen, const unsigned char *iv, int mode,
- unsigned int effectiveKeyLen, unsigned int xtra)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RC2_InitContext)(cx, key, keylen, iv, mode,
- effectiveKeyLen, xtra);
-}
-
-SECStatus
-RC4_InitContext(RC4Context *cx, const unsigned char *key,
- unsigned int keylen, const unsigned char *x1, int x2,
- unsigned int x3, unsigned int x4)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RC4_InitContext)(cx, key, keylen, x1, x2, x3, x4);
-}
-
-void
-MD2_Clone(MD2Context *dest, MD2Context *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD2_Clone)(dest, src);
-}
-
-void
-MD5_Clone(MD5Context *dest, MD5Context *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_MD5_Clone)(dest, src);
-}
-
-void
-SHA1_Clone(SHA1Context *dest, SHA1Context *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA1_Clone)(dest, src);
-}
-
-void
-SHA256_Clone(SHA256Context *dest, SHA256Context *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA256_Clone)(dest, src);
-}
-
-void
-SHA384_Clone(SHA384Context *dest, SHA384Context *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA384_Clone)(dest, src);
-}
-
-void
-SHA512_Clone(SHA512Context *dest, SHA512Context *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA512_Clone)(dest, src);
-}
-
-SECStatus
-TLS_PRF(const SECItem *secret, const char *label,
- SECItem *seed, SECItem *result, PRBool isFIPS)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_TLS_PRF)(secret, label, seed, result, isFIPS);
-}
-
-const SECHashObject *
-HASH_GetRawHashObject(HASH_HashType hashType)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_HASH_GetRawHashObject)(hashType);
-}
-
-
-void
-HMAC_Destroy(HMACContext *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_HMAC_Destroy)(cx, freeit);
-}
-
-HMACContext *
-HMAC_Create(const SECHashObject *hashObj, const unsigned char *secret,
- unsigned int secret_len, PRBool isFIPS)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_HMAC_Create)(hashObj, secret, secret_len, isFIPS);
-}
-
-SECStatus
-HMAC_Init(HMACContext *cx, const SECHashObject *hashObj,
- const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_HMAC_Init)(cx, hashObj, secret, secret_len, isFIPS);
-}
-
-void
-HMAC_Begin(HMACContext *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_HMAC_Begin)(cx);
-}
-
-void
-HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_HMAC_Update)(cx, data, data_len);
-}
-
-SECStatus
-HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
- unsigned int max_result_len)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_HMAC_Finish)(cx, result, result_len, max_result_len);
-}
-
-HMACContext *
-HMAC_Clone(HMACContext *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_HMAC_Clone)(cx);
-}
-
-void
-RNG_SystemInfoForRNG(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_RNG_SystemInfoForRNG)();
-
-}
-
-SECStatus
-FIPS186Change_GenerateX(unsigned char *XKEY, const unsigned char *XSEEDj,
- unsigned char *x_j)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_FIPS186Change_GenerateX)(XKEY, XSEEDj, x_j);
-}
-
-SECStatus
-FIPS186Change_ReduceModQForDSA(const unsigned char *w,
- const unsigned char *q,
- unsigned char *xj)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_FIPS186Change_ReduceModQForDSA)(w, q, xj);
-}
-
-/* === new for Camellia === */
-SECStatus
-Camellia_InitContext(CamelliaContext *cx, const unsigned char *key,
- unsigned int keylen, const unsigned char *iv, int mode,
- unsigned int encrypt, unsigned int unused)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_Camellia_InitContext)(cx, key, keylen, iv, mode, encrypt,
- unused);
-}
-
-CamelliaContext *
-Camellia_AllocateContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_Camellia_AllocateContext)();
-}
-
-
-CamelliaContext *
-Camellia_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, int encrypt,
- unsigned int keylen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_Camellia_CreateContext)(key, iv, mode, encrypt, keylen);
-}
-
-void
-Camellia_DestroyContext(CamelliaContext *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return ;
- (vector->p_Camellia_DestroyContext)(cx, freeit);
-}
-
-SECStatus
-Camellia_Encrypt(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_Camellia_Encrypt)(cx, output, outputLen, maxOutputLen,
- input, inputLen);
-}
-
-SECStatus
-Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_Camellia_Decrypt)(cx, output, outputLen, maxOutputLen,
- input, inputLen);
-}
-
-void BL_SetForkState(PRBool forked)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_BL_SetForkState)(forked);
-}
-
-SECStatus
-PRNGTEST_Instantiate(const PRUint8 *entropy, unsigned int entropy_len,
- const PRUint8 *nonce, unsigned int nonce_len,
- const PRUint8 *personal_string, unsigned int ps_len)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_PRNGTEST_Instantiate)(entropy, entropy_len,
- nonce, nonce_len,
- personal_string, ps_len);
-}
-
-SECStatus
-PRNGTEST_Reseed(const PRUint8 *entropy, unsigned int entropy_len,
- const PRUint8 *additional, unsigned int additional_len)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_PRNGTEST_Reseed)(entropy, entropy_len,
- additional, additional_len);
-}
-
-SECStatus
-PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
- const PRUint8 *additional, unsigned int additional_len)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_PRNGTEST_Generate)(bytes, bytes_len,
- additional, additional_len);
-}
-
-SECStatus
-PRNGTEST_Uninstantiate()
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_PRNGTEST_Uninstantiate)();
-}
-
-SECStatus
-RSA_PopulatePrivateKey(RSAPrivateKey *key)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_RSA_PopulatePrivateKey)(key);
-}
-
-
-SECStatus
-JPAKE_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
- const SECItem * signerID, const SECItem * x,
- const SECItem * testRandom, const SECItem * gxIn, SECItem * gxOut,
- SECItem * gv, SECItem * r)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_JPAKE_Sign)(arena, pqg, hashType, signerID, x,
- testRandom, gxIn, gxOut, gv, r);
-}
-
-SECStatus
-JPAKE_Verify(PLArenaPool * arena, const PQGParams * pqg,
- HASH_HashType hashType, const SECItem * signerID,
- const SECItem * peerID, const SECItem * gx,
- const SECItem * gv, const SECItem * r)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_JPAKE_Verify)(arena, pqg, hashType, signerID, peerID,
- gx, gv, r);
-}
-
-SECStatus
-JPAKE_Round2(PLArenaPool * arena, const SECItem * p, const SECItem *q,
- const SECItem * gx1, const SECItem * gx3, const SECItem * gx4,
- SECItem * base, const SECItem * x2, const SECItem * s, SECItem * x2s)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_JPAKE_Round2)(arena, p, q, gx1, gx3, gx4, base, x2, s, x2s);
-}
-
-SECStatus
-JPAKE_Final(PLArenaPool * arena, const SECItem * p, const SECItem *q,
- const SECItem * x2, const SECItem * gx4, const SECItem * x2s,
- const SECItem * B, SECItem * K)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_JPAKE_Final)(arena, p, q, x2, gx4, x2s, B, K);
-}
-
-SECStatus
-TLS_P_hash(HASH_HashType hashAlg, const SECItem *secret, const char *label,
- SECItem *seed, SECItem *result, PRBool isFIPS)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_TLS_P_hash)(hashAlg, secret, label, seed, result, isFIPS);
-}
-
-SECStatus
-SHA224_Hash(unsigned char *dest, const char *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA224_Hash)(dest, src);
-}
-
-SECStatus
-SHA224_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA224_HashBuf)(dest, src, src_length);
-}
-
-SHA224Context *
-SHA224_NewContext(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA224_NewContext)();
-}
-
-void
-SHA224_DestroyContext(SHA224Context *cx, PRBool freeit)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA224_DestroyContext)(cx, freeit);
-}
-
-void
-SHA224_Begin(SHA256Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA224_Begin)(cx);
-}
-
-void
-SHA224_Update(SHA224Context *cx, const unsigned char *input,
- unsigned int inputLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA224_Update)(cx, input, inputLen);
-}
-
-void
-SHA224_End(SHA224Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA224_End)(cx, digest, digestLen, maxDigestLen);
-}
-
-void
-SHA224_TraceState(SHA224Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA224_TraceState)(cx);
-}
-
-unsigned int
-SHA224_FlattenSize(SHA224Context *cx)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return 0;
- return (vector->p_SHA224_FlattenSize)(cx);
-}
-
-SECStatus
-SHA224_Flatten(SHA224Context *cx,unsigned char *space)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SHA224_Flatten)(cx, space);
-}
-
-SHA224Context *
-SHA224_Resurrect(unsigned char *space, void *arg)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return NULL;
- return (vector->p_SHA224_Resurrect)(space, arg);
-}
-
-void
-SHA224_Clone(SHA224Context *dest, SHA224Context *src)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return;
- (vector->p_SHA224_Clone)(dest, src);
-}
-
-PRBool
-BLAPI_SHVerifyFile(const char *name)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return PR_FALSE;
- return vector->p_BLAPI_SHVerifyFile(name);
-}
-
-/* === new for DSA-2 === */
-SECStatus
-PQG_ParamGenV2( unsigned int L, unsigned int N, unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_PQG_ParamGenV2)(L, N, seedBytes, pParams, pVfy);
-}
-
-SECStatus
-PRNGTEST_RunHealthTests(void)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return vector->p_PRNGTEST_RunHealthTests();
-}
-
-SECStatus
-SSLv3_MAC_ConstantTime(
- unsigned char *result,
- unsigned int *resultLen,
- unsigned int maxResultLen,
- const SECHashObject *hashObj,
- const unsigned char *secret,
- unsigned int secretLen,
- const unsigned char *header,
- unsigned int headerLen,
- const unsigned char *body,
- unsigned int bodyLen,
- unsigned int bodyTotalLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_SSLv3_MAC_ConstantTime)(
- result, resultLen, maxResultLen,
- hashObj,
- secret, secretLen,
- header, headerLen,
- body, bodyLen, bodyTotalLen);
-}
-
-SECStatus
-HMAC_ConstantTime(
- unsigned char *result,
- unsigned int *resultLen,
- unsigned int maxResultLen,
- const SECHashObject *hashObj,
- const unsigned char *secret,
- unsigned int secretLen,
- const unsigned char *header,
- unsigned int headerLen,
- const unsigned char *body,
- unsigned int bodyLen,
- unsigned int bodyTotalLen)
-{
- if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
- return SECFailure;
- return (vector->p_HMAC_ConstantTime)(
- result, resultLen, maxResultLen,
- hashObj,
- secret, secretLen,
- header, headerLen,
- body, bodyLen, bodyTotalLen);
-}
diff --git a/security/nss/lib/freebl/loader.h b/security/nss/lib/freebl/loader.h
deleted file mode 100644
index 4ea2afda7..000000000
--- a/security/nss/lib/freebl/loader.h
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * loader.h - load platform dependent DSO containing freebl implementation.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _LOADER_H_
-#define _LOADER_H_ 1
-
-#include "blapi.h"
-
-#define FREEBL_VERSION 0x030F
-
-struct FREEBLVectorStr {
-
- unsigned short length; /* of this struct in bytes */
- unsigned short version; /* of this struct. */
-
- RSAPrivateKey * (* p_RSA_NewKey)(int keySizeInBits,
- SECItem * publicExponent);
-
- SECStatus (* p_RSA_PublicKeyOp) (RSAPublicKey * key,
- unsigned char * output,
- const unsigned char * input);
-
- SECStatus (* p_RSA_PrivateKeyOp)(RSAPrivateKey * key,
- unsigned char * output,
- const unsigned char * input);
-
- SECStatus (* p_DSA_NewKey)(const PQGParams * params,
- DSAPrivateKey ** privKey);
-
- SECStatus (* p_DSA_SignDigest)(DSAPrivateKey * key,
- SECItem * signature,
- const SECItem * digest);
-
- SECStatus (* p_DSA_VerifyDigest)(DSAPublicKey * key,
- const SECItem * signature,
- const SECItem * digest);
-
- SECStatus (* p_DSA_NewKeyFromSeed)(const PQGParams *params,
- const unsigned char * seed,
- DSAPrivateKey **privKey);
-
- SECStatus (* p_DSA_SignDigestWithSeed)(DSAPrivateKey * key,
- SECItem * signature,
- const SECItem * digest,
- const unsigned char * seed);
-
- SECStatus (* p_DH_GenParam)(int primeLen, DHParams ** params);
-
- SECStatus (* p_DH_NewKey)(DHParams * params,
- DHPrivateKey ** privKey);
-
- SECStatus (* p_DH_Derive)(SECItem * publicValue,
- SECItem * prime,
- SECItem * privateValue,
- SECItem * derivedSecret,
- unsigned int maxOutBytes);
-
- SECStatus (* p_KEA_Derive)(SECItem *prime,
- SECItem *public1,
- SECItem *public2,
- SECItem *private1,
- SECItem *private2,
- SECItem *derivedSecret);
-
- PRBool (* p_KEA_Verify)(SECItem *Y, SECItem *prime, SECItem *subPrime);
-
- RC4Context * (* p_RC4_CreateContext)(const unsigned char *key, int len);
-
- void (* p_RC4_DestroyContext)(RC4Context *cx, PRBool freeit);
-
- SECStatus (* p_RC4_Encrypt)(RC4Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- SECStatus (* p_RC4_Decrypt)(RC4Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- RC2Context * (* p_RC2_CreateContext)(const unsigned char *key,
- unsigned int len, const unsigned char *iv,
- int mode, unsigned effectiveKeyLen);
-
- void (* p_RC2_DestroyContext)(RC2Context *cx, PRBool freeit);
-
- SECStatus (* p_RC2_Encrypt)(RC2Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- SECStatus (* p_RC2_Decrypt)(RC2Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- RC5Context *(* p_RC5_CreateContext)(const SECItem *key, unsigned int rounds,
- unsigned int wordSize, const unsigned char *iv, int mode);
-
- void (* p_RC5_DestroyContext)(RC5Context *cx, PRBool freeit);
-
- SECStatus (* p_RC5_Encrypt)(RC5Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- SECStatus (* p_RC5_Decrypt)(RC5Context *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- DESContext *(* p_DES_CreateContext)(const unsigned char *key,
- const unsigned char *iv,
- int mode, PRBool encrypt);
-
- void (* p_DES_DestroyContext)(DESContext *cx, PRBool freeit);
-
- SECStatus (* p_DES_Encrypt)(DESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- SECStatus (* p_DES_Decrypt)(DESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- AESContext * (* p_AES_CreateContext)(const unsigned char *key,
- const unsigned char *iv,
- int mode, int encrypt, unsigned int keylen,
- unsigned int blocklen);
-
- void (* p_AES_DestroyContext)(AESContext *cx, PRBool freeit);
-
- SECStatus (* p_AES_Encrypt)(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- SECStatus (* p_AES_Decrypt)(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- SECStatus (* p_MD5_Hash)(unsigned char *dest, const char *src);
-
- SECStatus (* p_MD5_HashBuf)(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
-
- MD5Context *(* p_MD5_NewContext)(void);
-
- void (* p_MD5_DestroyContext)(MD5Context *cx, PRBool freeit);
-
- void (* p_MD5_Begin)(MD5Context *cx);
-
- void (* p_MD5_Update)(MD5Context *cx,
- const unsigned char *input, unsigned int inputLen);
-
- void (* p_MD5_End)(MD5Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-
- unsigned int (* p_MD5_FlattenSize)(MD5Context *cx);
-
- SECStatus (* p_MD5_Flatten)(MD5Context *cx,unsigned char *space);
-
- MD5Context * (* p_MD5_Resurrect)(unsigned char *space, void *arg);
-
- void (* p_MD5_TraceState)(MD5Context *cx);
-
- SECStatus (* p_MD2_Hash)(unsigned char *dest, const char *src);
-
- MD2Context *(* p_MD2_NewContext)(void);
-
- void (* p_MD2_DestroyContext)(MD2Context *cx, PRBool freeit);
-
- void (* p_MD2_Begin)(MD2Context *cx);
-
- void (* p_MD2_Update)(MD2Context *cx,
- const unsigned char *input, unsigned int inputLen);
-
- void (* p_MD2_End)(MD2Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-
- unsigned int (* p_MD2_FlattenSize)(MD2Context *cx);
-
- SECStatus (* p_MD2_Flatten)(MD2Context *cx,unsigned char *space);
-
- MD2Context * (* p_MD2_Resurrect)(unsigned char *space, void *arg);
-
- SECStatus (* p_SHA1_Hash)(unsigned char *dest, const char *src);
-
- SECStatus (* p_SHA1_HashBuf)(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
-
- SHA1Context *(* p_SHA1_NewContext)(void);
-
- void (* p_SHA1_DestroyContext)(SHA1Context *cx, PRBool freeit);
-
- void (* p_SHA1_Begin)(SHA1Context *cx);
-
- void (* p_SHA1_Update)(SHA1Context *cx, const unsigned char *input,
- unsigned int inputLen);
-
- void (* p_SHA1_End)(SHA1Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
-
- void (* p_SHA1_TraceState)(SHA1Context *cx);
-
- unsigned int (* p_SHA1_FlattenSize)(SHA1Context *cx);
-
- SECStatus (* p_SHA1_Flatten)(SHA1Context *cx,unsigned char *space);
-
- SHA1Context * (* p_SHA1_Resurrect)(unsigned char *space, void *arg);
-
- SECStatus (* p_RNG_RNGInit)(void);
-
- SECStatus (* p_RNG_RandomUpdate)(const void *data, size_t bytes);
-
- SECStatus (* p_RNG_GenerateGlobalRandomBytes)(void *dest, size_t len);
-
- void (* p_RNG_RNGShutdown)(void);
-
- SECStatus (* p_PQG_ParamGen)(unsigned int j, PQGParams **pParams,
- PQGVerify **pVfy);
-
- SECStatus (* p_PQG_ParamGenSeedLen)( unsigned int j, unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy);
-
- SECStatus (* p_PQG_VerifyParams)(const PQGParams *params,
- const PQGVerify *vfy, SECStatus *result);
-
- /* Version 3.001 came to here */
-
- SECStatus (* p_RSA_PrivateKeyOpDoubleChecked)(RSAPrivateKey *key,
- unsigned char *output,
- const unsigned char *input);
-
- SECStatus (* p_RSA_PrivateKeyCheck)(RSAPrivateKey *key);
-
- void (* p_BL_Cleanup)(void);
-
- /* Version 3.002 came to here */
-
- SHA256Context *(* p_SHA256_NewContext)(void);
- void (* p_SHA256_DestroyContext)(SHA256Context *cx, PRBool freeit);
- void (* p_SHA256_Begin)(SHA256Context *cx);
- void (* p_SHA256_Update)(SHA256Context *cx, const unsigned char *input,
- unsigned int inputLen);
- void (* p_SHA256_End)(SHA256Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
- SECStatus (* p_SHA256_HashBuf)(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
- SECStatus (* p_SHA256_Hash)(unsigned char *dest, const char *src);
- void (* p_SHA256_TraceState)(SHA256Context *cx);
- unsigned int (* p_SHA256_FlattenSize)(SHA256Context *cx);
- SECStatus (* p_SHA256_Flatten)(SHA256Context *cx,unsigned char *space);
- SHA256Context * (* p_SHA256_Resurrect)(unsigned char *space, void *arg);
-
- SHA512Context *(* p_SHA512_NewContext)(void);
- void (* p_SHA512_DestroyContext)(SHA512Context *cx, PRBool freeit);
- void (* p_SHA512_Begin)(SHA512Context *cx);
- void (* p_SHA512_Update)(SHA512Context *cx, const unsigned char *input,
- unsigned int inputLen);
- void (* p_SHA512_End)(SHA512Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
- SECStatus (* p_SHA512_HashBuf)(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
- SECStatus (* p_SHA512_Hash)(unsigned char *dest, const char *src);
- void (* p_SHA512_TraceState)(SHA512Context *cx);
- unsigned int (* p_SHA512_FlattenSize)(SHA512Context *cx);
- SECStatus (* p_SHA512_Flatten)(SHA512Context *cx,unsigned char *space);
- SHA512Context * (* p_SHA512_Resurrect)(unsigned char *space, void *arg);
-
- SHA384Context *(* p_SHA384_NewContext)(void);
- void (* p_SHA384_DestroyContext)(SHA384Context *cx, PRBool freeit);
- void (* p_SHA384_Begin)(SHA384Context *cx);
- void (* p_SHA384_Update)(SHA384Context *cx, const unsigned char *input,
- unsigned int inputLen);
- void (* p_SHA384_End)(SHA384Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
- SECStatus (* p_SHA384_HashBuf)(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
- SECStatus (* p_SHA384_Hash)(unsigned char *dest, const char *src);
- void (* p_SHA384_TraceState)(SHA384Context *cx);
- unsigned int (* p_SHA384_FlattenSize)(SHA384Context *cx);
- SECStatus (* p_SHA384_Flatten)(SHA384Context *cx,unsigned char *space);
- SHA384Context * (* p_SHA384_Resurrect)(unsigned char *space, void *arg);
-
- /* Version 3.003 came to here */
-
- AESKeyWrapContext * (* p_AESKeyWrap_CreateContext)(const unsigned char *key,
- const unsigned char *iv, int encrypt, unsigned int keylen);
-
- void (* p_AESKeyWrap_DestroyContext)(AESKeyWrapContext *cx, PRBool freeit);
-
- SECStatus (* p_AESKeyWrap_Encrypt)(AESKeyWrapContext *cx,
- unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- SECStatus (* p_AESKeyWrap_Decrypt)(AESKeyWrapContext *cx,
- unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- /* Version 3.004 came to here */
-
- PRBool (*p_BLAPI_SHVerify)(const char *name, PRFuncPtr addr);
- PRBool (*p_BLAPI_VerifySelf)(const char *name);
-
- /* Version 3.005 came to here */
-
- SECStatus (* p_EC_NewKey)(ECParams * params,
- ECPrivateKey ** privKey);
-
- SECStatus (* p_EC_NewKeyFromSeed)(ECParams * params,
- ECPrivateKey ** privKey,
- const unsigned char * seed,
- int seedlen);
-
- SECStatus (* p_EC_ValidatePublicKey)(ECParams * params,
- SECItem * publicValue);
-
- SECStatus (* p_ECDH_Derive)(SECItem * publicValue,
- ECParams * params,
- SECItem * privateValue,
- PRBool withCofactor,
- SECItem * derivedSecret);
-
- SECStatus (* p_ECDSA_SignDigest)(ECPrivateKey * key,
- SECItem * signature,
- const SECItem * digest);
-
- SECStatus (* p_ECDSA_VerifyDigest)(ECPublicKey * key,
- const SECItem * signature,
- const SECItem * digest);
-
- SECStatus (* p_ECDSA_SignDigestWithSeed)(ECPrivateKey * key,
- SECItem * signature,
- const SECItem * digest,
- const unsigned char * seed,
- const int seedlen);
-
- /* Version 3.006 came to here */
-
- /* no modification to FREEBLVectorStr itself
- * but ECParamStr was modified
- */
-
- /* Version 3.007 came to here */
-
- SECStatus (* p_AES_InitContext)(AESContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int encrypt,
- unsigned int blocklen);
- SECStatus (* p_AESKeyWrap_InitContext)(AESKeyWrapContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int encrypt,
- unsigned int blocklen);
- SECStatus (* p_DES_InitContext)(DESContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int encrypt,
- unsigned int );
- SECStatus (* p_RC2_InitContext)(RC2Context *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int effectiveKeyLen,
- unsigned int );
- SECStatus (* p_RC4_InitContext)(RC4Context *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *,
- int,
- unsigned int ,
- unsigned int );
-
- AESContext *(*p_AES_AllocateContext)(void);
- AESKeyWrapContext *(*p_AESKeyWrap_AllocateContext)(void);
- DESContext *(*p_DES_AllocateContext)(void);
- RC2Context *(*p_RC2_AllocateContext)(void);
- RC4Context *(*p_RC4_AllocateContext)(void);
-
- void (* p_MD2_Clone)(MD2Context *dest, MD2Context *src);
- void (* p_MD5_Clone)(MD5Context *dest, MD5Context *src);
- void (* p_SHA1_Clone)(SHA1Context *dest, SHA1Context *src);
- void (* p_SHA256_Clone)(SHA256Context *dest, SHA256Context *src);
- void (* p_SHA384_Clone)(SHA384Context *dest, SHA384Context *src);
- void (* p_SHA512_Clone)(SHA512Context *dest, SHA512Context *src);
-
- SECStatus (* p_TLS_PRF)(const SECItem *secret, const char *label,
- SECItem *seed, SECItem *result, PRBool isFIPS);
-
- const SECHashObject *(* p_HASH_GetRawHashObject)(HASH_HashType hashType);
-
- HMACContext * (* p_HMAC_Create)(const SECHashObject *hashObj,
- const unsigned char *secret,
- unsigned int secret_len, PRBool isFIPS);
- SECStatus (* p_HMAC_Init)(HMACContext *cx, const SECHashObject *hash_obj,
- const unsigned char *secret,
- unsigned int secret_len, PRBool isFIPS);
- void (* p_HMAC_Begin)(HMACContext *cx);
- void (* p_HMAC_Update)(HMACContext *cx, const unsigned char *data,
- unsigned int data_len);
- HMACContext * (* p_HMAC_Clone)(HMACContext *cx);
- SECStatus (* p_HMAC_Finish)(HMACContext *cx, unsigned char *result,
- unsigned int *result_len,
- unsigned int max_result_len);
- void (* p_HMAC_Destroy)(HMACContext *cx, PRBool freeit);
-
- void (* p_RNG_SystemInfoForRNG)(void);
-
- /* Version 3.008 came to here */
-
- SECStatus (* p_FIPS186Change_GenerateX)(unsigned char *XKEY,
- const unsigned char *XSEEDj,
- unsigned char *x_j);
- SECStatus (* p_FIPS186Change_ReduceModQForDSA)(const unsigned char *w,
- const unsigned char *q,
- unsigned char *xj);
-
- /* Version 3.009 came to here */
-
- SECStatus (* p_Camellia_InitContext)(CamelliaContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int encrypt,
- unsigned int unused);
-
- CamelliaContext *(*p_Camellia_AllocateContext)(void);
- CamelliaContext * (* p_Camellia_CreateContext)(const unsigned char *key,
- const unsigned char *iv,
- int mode, int encrypt,
- unsigned int keylen);
- void (* p_Camellia_DestroyContext)(CamelliaContext *cx, PRBool freeit);
-
- SECStatus (* p_Camellia_Encrypt)(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
-
- SECStatus (* p_Camellia_Decrypt)(CamelliaContext *cx, unsigned char *output,
- unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input,
- unsigned int inputLen);
-
- void (* p_PQG_DestroyParams)(PQGParams *params);
-
- void (* p_PQG_DestroyVerify)(PQGVerify *vfy);
-
- /* Version 3.010 came to here */
-
- SECStatus (* p_SEED_InitContext)(SEEDContext *cx,
- const unsigned char *key,
- unsigned int keylen,
- const unsigned char *iv,
- int mode,
- unsigned int encrypt,
- unsigned int );
-
- SEEDContext *(*p_SEED_AllocateContext)(void);
-
- SEEDContext *(* p_SEED_CreateContext)(const unsigned char *key,
- const unsigned char *iv,
- int mode, PRBool encrypt);
-
- void (* p_SEED_DestroyContext)(SEEDContext *cx, PRBool freeit);
-
- SECStatus (* p_SEED_Encrypt)(SEEDContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
- SECStatus (* p_SEED_Decrypt)(SEEDContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-
-
- SECStatus (* p_BL_Init)(void);
- void ( * p_BL_SetForkState)(PRBool);
-
- SECStatus (* p_PRNGTEST_Instantiate)(const PRUint8 *entropy,
- unsigned int entropy_len,
- const PRUint8 *nonce,
- unsigned int nonce_len,
- const PRUint8 *personal_string,
- unsigned int ps_len);
-
- SECStatus (* p_PRNGTEST_Reseed)(const PRUint8 *entropy,
- unsigned int entropy_len,
- const PRUint8 *additional,
- unsigned int additional_len);
-
- SECStatus (* p_PRNGTEST_Generate)(PRUint8 *bytes,
- unsigned int bytes_len,
- const PRUint8 *additional,
- unsigned int additional_len);
-
- SECStatus (* p_PRNGTEST_Uninstantiate)(void);
- /* Version 3.011 came to here */
-
- SECStatus (*p_RSA_PopulatePrivateKey)(RSAPrivateKey *key);
-
- SECStatus (*p_DSA_NewRandom)(PLArenaPool * arena, const SECItem * q,
- SECItem * seed);
-
- SECStatus (*p_JPAKE_Sign)(PLArenaPool * arena, const PQGParams * pqg,
- HASH_HashType hashType, const SECItem * signerID,
- const SECItem * x, const SECItem * testRandom,
- const SECItem * gxIn, SECItem * gxOut,
- SECItem * gv, SECItem * r);
-
- SECStatus (*p_JPAKE_Verify)(PLArenaPool * arena, const PQGParams * pqg,
- HASH_HashType hashType, const SECItem * signerID,
- const SECItem * peerID, const SECItem * gx,
- const SECItem * gv, const SECItem * r);
-
- SECStatus (*p_JPAKE_Round2)(PLArenaPool * arena, const SECItem * p,
- const SECItem *q, const SECItem * gx1,
- const SECItem * gx3, const SECItem * gx4,
- SECItem * base, const SECItem * x2,
- const SECItem * s, SECItem * x2s);
-
- SECStatus (*p_JPAKE_Final)(PLArenaPool * arena, const SECItem * p,
- const SECItem *q, const SECItem * x2,
- const SECItem * gx4, const SECItem * x2s,
- const SECItem * B, SECItem * K);
-
- /* Version 3.012 came to here */
-
- SECStatus (* p_TLS_P_hash)(HASH_HashType hashAlg,
- const SECItem *secret,
- const char *label,
- SECItem *seed,
- SECItem *result,
- PRBool isFIPS);
-
- SHA224Context *(*p_SHA224_NewContext)(void);
- void (* p_SHA224_DestroyContext)(SHA224Context *cx, PRBool freeit);
- void (* p_SHA224_Begin)(SHA224Context *cx);
- void (* p_SHA224_Update)(SHA224Context *cx, const unsigned char *input,
- unsigned int inputLen);
- void (* p_SHA224_End)(SHA224Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen);
- SECStatus (*p_SHA224_HashBuf)(unsigned char *dest, const unsigned char *src,
- uint32 src_length);
- SECStatus (*p_SHA224_Hash)(unsigned char *dest, const char *src);
- void (*p_SHA224_TraceState)(SHA224Context *cx);
- unsigned int (* p_SHA224_FlattenSize)(SHA224Context *cx);
- SECStatus (* p_SHA224_Flatten)(SHA224Context *cx,unsigned char *space);
- SHA224Context * (* p_SHA224_Resurrect)(unsigned char *space, void *arg);
- void (* p_SHA224_Clone)(SHA224Context *dest, SHA224Context *src);
- PRBool (*p_BLAPI_SHVerifyFile)(const char *name);
-
- /* Version 3.013 came to here */
-
- SECStatus (* p_PQG_ParamGenV2)( unsigned int L, unsigned int N,
- unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy);
- SECStatus (*p_PRNGTEST_RunHealthTests)(void);
-
- /* Version 3.014 came to here */
-
- SECStatus (* p_HMAC_ConstantTime)(
- unsigned char *result,
- unsigned int *resultLen,
- unsigned int maxResultLen,
- const SECHashObject *hashObj,
- const unsigned char *secret,
- unsigned int secretLen,
- const unsigned char *header,
- unsigned int headerLen,
- const unsigned char *body,
- unsigned int bodyLen,
- unsigned int bodyTotalLen);
-
- SECStatus (* p_SSLv3_MAC_ConstantTime)(
- unsigned char *result,
- unsigned int *resultLen,
- unsigned int maxResultLen,
- const SECHashObject *hashObj,
- const unsigned char *secret,
- unsigned int secretLen,
- const unsigned char *header,
- unsigned int headerLen,
- const unsigned char *body,
- unsigned int bodyLen,
- unsigned int bodyTotalLen);
-
- /* Version 3.015 came to here */
- };
-
-typedef struct FREEBLVectorStr FREEBLVector;
-
-SEC_BEGIN_PROTOS
-
-typedef const FREEBLVector * FREEBLGetVectorFn(void);
-
-extern FREEBLGetVectorFn FREEBL_GetVector;
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/freebl/manifest.mn b/security/nss/lib/freebl/manifest.mn
deleted file mode 100644
index f7f98c15b..000000000
--- a/security/nss/lib/freebl/manifest.mn
+++ /dev/null
@@ -1,163 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# NOTE: any ifdefs in this file must be defined on the gmake command line
-# (if anywhere). They cannot come from Makefile or config.mk
-
-CORE_DEPTH = ../../..
-
-MODULE = nss
-
-LIBRARY_NAME = freebl
-LIBRARY_VERSION = 3
-
-ifdef FREEBL_CHILD_BUILD
- ifdef USE_ABI32_INT32
- LIBRARY_NAME = freebl_32int
- endif
- ifdef USE_ABI32_INT64
- LIBRARY_NAME = freebl_32int64
- endif
- ifdef USE_ABI32_FPU
- LIBRARY_NAME = freebl_32fpu
- endif
- ifdef USE_ABI64_INT
- LIBRARY_NAME = freebl_64int
- endif
- ifdef USE_ABI64_FPU
- LIBRARY_NAME = freebl_64fpu
- endif
-endif
-
-# if the library name contains _, we prefix the version with _
-ifneq (,$(findstring _,$(LIBRARY_NAME)))
- LIBRARY_VERSION := _$(LIBRARY_VERSION)
-endif
-
-MAPFILE = $(OBJDIR)/$(LIBRARY_NAME).def
-
-SOFTOKEN_LIBRARY_VERSION = 3
-
-DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" \
- -DSHLIB_VERSION=\"$(LIBRARY_VERSION)\" \
- -DSOFTOKEN_SHLIB_VERSION=\"$(SOFTOKEN_LIBRARY_VERSION)\"
-
-REQUIRES =
-
-EXPORTS = \
- blapit.h \
- shsign.h \
- ecl-exp.h \
- $(LOWHASH_EXPORTS) \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- alghmac.h \
- blapi.h \
- hmacct.h \
- secmpi.h \
- secrng.h \
- ec.h \
- ecl.h \
- ecl-curve.h \
- $(NULL)
-
-MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h
-MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c
-
-
-ECL_HDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h
-ifdef NSS_ENABLE_ECC
-ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \
- ecp_aff.c ecp_jac.c ecp_mont.c \
- ec_naf.c ecp_jm.c
-ifdef NSS_ECC_MORE_THAN_SUITE_B
-ECL_SRCS += ec2_aff.c ec2_mont.c ec2_proj.c \
- ec2_163.c ec2_193.c ec2_233.c \
- ecp_192.c ecp_224.c ecp_256.c ecp_384.c ecp_521.c
-endif
-else
-ECL_SRCS = $(NULL)
-endif
-SHA_SRCS = sha_fast.c
-MPCPU_SRCS = mpcpucache.c
-
-CSRCS = \
- freeblver.c \
- ldvector.c \
- sysrand.c \
- $(SHA_SRCS) \
- md2.c \
- md5.c \
- sha512.c \
- alghmac.c \
- rawhash.c \
- alg2268.c \
- arcfour.c \
- arcfive.c \
- desblapi.c \
- des.c \
- drbg.c \
- cts.c \
- ctr.c \
- gcm.c \
- hmacct.c \
- rijndael.c \
- aeskeywrap.c \
- camellia.c \
- dh.c \
- ec.c \
- pqg.c \
- dsa.c \
- rsa.c \
- shvfy.c \
- tlsprfalg.c \
- seed.c \
- jpake.c \
- $(MPI_SRCS) \
- $(MPCPU_SRCS) \
- $(ECL_SRCS) \
- $(STUBS_SRCS) \
- $(LOWHASH_SRCS) \
- $(EXTRA_SRCS) \
- $(NULL)
-
-ALL_CSRCS := $(CSRCS)
-
-ALL_HDRS = \
- alghmac.h \
- blapi.h \
- blapit.h \
- des.h \
- ec.h \
- loader.h \
- rijndael.h \
- camellia.h \
- secmpi.h \
- sha_fast.h \
- sha256.h \
- shsign.h \
- vis_proto.h \
- seed.h \
- $(NULL)
-
-
-ifdef AES_GEN_TBL
-DEFINES += -DRIJNDAEL_GENERATE_TABLES
-else
-ifdef AES_GEN_TBL_M
-DEFINES += -DRIJNDAEL_GENERATE_TABLES_MACRO
-else
-ifdef AES_GEN_VAL
-DEFINES += -DRIJNDAEL_GENERATE_VALUES
-else
-ifdef AES_GEN_VAL_M
-DEFINES += -DRIJNDAEL_GENERATE_VALUES_MACRO
-else
-DEFINES += -DRIJNDAEL_INCLUDE_TABLES
-endif
-endif
-endif
-endif
diff --git a/security/nss/lib/freebl/md2.c b/security/nss/lib/freebl/md2.c
deleted file mode 100644
index d069ecaaa..000000000
--- a/security/nss/lib/freebl/md2.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prerr.h"
-#include "secerr.h"
-
-#include "prtypes.h"
-
-#include "blapi.h"
-
-#define MD2_DIGEST_LEN 16
-#define MD2_BUFSIZE 16
-#define MD2_X_SIZE 48 /* The X array, [CV | INPUT | TMP VARS] */
-#define MD2_CV 0 /* index into X for chaining variables */
-#define MD2_INPUT 16 /* index into X for input */
-#define MD2_TMPVARS 32 /* index into X for temporary variables */
-#define MD2_CHECKSUM_SIZE 16
-
-struct MD2ContextStr {
- unsigned char checksum[MD2_BUFSIZE];
- unsigned char X[MD2_X_SIZE];
- PRUint8 unusedBuffer;
-};
-
-static const PRUint8 MD2S[256] = {
- 0051, 0056, 0103, 0311, 0242, 0330, 0174, 0001,
- 0075, 0066, 0124, 0241, 0354, 0360, 0006, 0023,
- 0142, 0247, 0005, 0363, 0300, 0307, 0163, 0214,
- 0230, 0223, 0053, 0331, 0274, 0114, 0202, 0312,
- 0036, 0233, 0127, 0074, 0375, 0324, 0340, 0026,
- 0147, 0102, 0157, 0030, 0212, 0027, 0345, 0022,
- 0276, 0116, 0304, 0326, 0332, 0236, 0336, 0111,
- 0240, 0373, 0365, 0216, 0273, 0057, 0356, 0172,
- 0251, 0150, 0171, 0221, 0025, 0262, 0007, 0077,
- 0224, 0302, 0020, 0211, 0013, 0042, 0137, 0041,
- 0200, 0177, 0135, 0232, 0132, 0220, 0062, 0047,
- 0065, 0076, 0314, 0347, 0277, 0367, 0227, 0003,
- 0377, 0031, 0060, 0263, 0110, 0245, 0265, 0321,
- 0327, 0136, 0222, 0052, 0254, 0126, 0252, 0306,
- 0117, 0270, 0070, 0322, 0226, 0244, 0175, 0266,
- 0166, 0374, 0153, 0342, 0234, 0164, 0004, 0361,
- 0105, 0235, 0160, 0131, 0144, 0161, 0207, 0040,
- 0206, 0133, 0317, 0145, 0346, 0055, 0250, 0002,
- 0033, 0140, 0045, 0255, 0256, 0260, 0271, 0366,
- 0034, 0106, 0141, 0151, 0064, 0100, 0176, 0017,
- 0125, 0107, 0243, 0043, 0335, 0121, 0257, 0072,
- 0303, 0134, 0371, 0316, 0272, 0305, 0352, 0046,
- 0054, 0123, 0015, 0156, 0205, 0050, 0204, 0011,
- 0323, 0337, 0315, 0364, 0101, 0201, 0115, 0122,
- 0152, 0334, 0067, 0310, 0154, 0301, 0253, 0372,
- 0044, 0341, 0173, 0010, 0014, 0275, 0261, 0112,
- 0170, 0210, 0225, 0213, 0343, 0143, 0350, 0155,
- 0351, 0313, 0325, 0376, 0073, 0000, 0035, 0071,
- 0362, 0357, 0267, 0016, 0146, 0130, 0320, 0344,
- 0246, 0167, 0162, 0370, 0353, 0165, 0113, 0012,
- 0061, 0104, 0120, 0264, 0217, 0355, 0037, 0032,
- 0333, 0231, 0215, 0063, 0237, 0021, 0203, 0024
-};
-
-SECStatus
-MD2_Hash(unsigned char *dest, const char *src)
-{
- unsigned int len;
- MD2Context *cx = MD2_NewContext();
- if (!cx) {
- PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
- return SECFailure;
- }
- MD2_Begin(cx);
- MD2_Update(cx, (const unsigned char *)src, PORT_Strlen(src));
- MD2_End(cx, dest, &len, MD2_DIGEST_LEN);
- MD2_DestroyContext(cx, PR_TRUE);
- return SECSuccess;
-}
-
-MD2Context *
-MD2_NewContext(void)
-{
- MD2Context *cx = (MD2Context *)PORT_ZAlloc(sizeof(MD2Context));
- if (cx == NULL) {
- PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
- return NULL;
- }
- return cx;
-}
-
-void
-MD2_DestroyContext(MD2Context *cx, PRBool freeit)
-{
- if (freeit)
- PORT_ZFree(cx, sizeof(*cx));
-}
-
-void
-MD2_Begin(MD2Context *cx)
-{
- memset(cx, 0, sizeof(*cx));
- cx->unusedBuffer = MD2_BUFSIZE;
-}
-
-static void
-md2_compress(MD2Context *cx)
-{
- int j;
- unsigned char P;
- P = cx->checksum[MD2_CHECKSUM_SIZE-1];
- /* Compute the running checksum, and set the tmp variables to be
- * CV[i] XOR input[i]
- */
-#define CKSUMFN(n) \
- P = cx->checksum[n] ^ MD2S[cx->X[MD2_INPUT+n] ^ P]; \
- cx->checksum[n] = P; \
- cx->X[MD2_TMPVARS+n] = cx->X[n] ^ cx->X[MD2_INPUT+n];
- CKSUMFN(0);
- CKSUMFN(1);
- CKSUMFN(2);
- CKSUMFN(3);
- CKSUMFN(4);
- CKSUMFN(5);
- CKSUMFN(6);
- CKSUMFN(7);
- CKSUMFN(8);
- CKSUMFN(9);
- CKSUMFN(10);
- CKSUMFN(11);
- CKSUMFN(12);
- CKSUMFN(13);
- CKSUMFN(14);
- CKSUMFN(15);
- /* The compression function. */
-#define COMPRESS(n) \
- P = cx->X[n] ^ MD2S[P]; \
- cx->X[n] = P;
- P = 0x00;
- for (j=0; j<18; j++) {
- COMPRESS(0);
- COMPRESS(1);
- COMPRESS(2);
- COMPRESS(3);
- COMPRESS(4);
- COMPRESS(5);
- COMPRESS(6);
- COMPRESS(7);
- COMPRESS(8);
- COMPRESS(9);
- COMPRESS(10);
- COMPRESS(11);
- COMPRESS(12);
- COMPRESS(13);
- COMPRESS(14);
- COMPRESS(15);
- COMPRESS(16);
- COMPRESS(17);
- COMPRESS(18);
- COMPRESS(19);
- COMPRESS(20);
- COMPRESS(21);
- COMPRESS(22);
- COMPRESS(23);
- COMPRESS(24);
- COMPRESS(25);
- COMPRESS(26);
- COMPRESS(27);
- COMPRESS(28);
- COMPRESS(29);
- COMPRESS(30);
- COMPRESS(31);
- COMPRESS(32);
- COMPRESS(33);
- COMPRESS(34);
- COMPRESS(35);
- COMPRESS(36);
- COMPRESS(37);
- COMPRESS(38);
- COMPRESS(39);
- COMPRESS(40);
- COMPRESS(41);
- COMPRESS(42);
- COMPRESS(43);
- COMPRESS(44);
- COMPRESS(45);
- COMPRESS(46);
- COMPRESS(47);
- P = (P + j) % 256;
- }
- cx->unusedBuffer = MD2_BUFSIZE;
-}
-
-void
-MD2_Update(MD2Context *cx, const unsigned char *input, unsigned int inputLen)
-{
- PRUint32 bytesToConsume;
-
- /* Fill the remaining input buffer. */
- if (cx->unusedBuffer != MD2_BUFSIZE) {
- bytesToConsume = PR_MIN(inputLen, cx->unusedBuffer);
- memcpy(&cx->X[MD2_INPUT + (MD2_BUFSIZE - cx->unusedBuffer)],
- input, bytesToConsume);
- if (cx->unusedBuffer + bytesToConsume >= MD2_BUFSIZE)
- md2_compress(cx);
- inputLen -= bytesToConsume;
- input += bytesToConsume;
- }
-
- /* Iterate over 16-byte chunks of the input. */
- while (inputLen >= MD2_BUFSIZE) {
- memcpy(&cx->X[MD2_INPUT], input, MD2_BUFSIZE);
- md2_compress(cx);
- inputLen -= MD2_BUFSIZE;
- input += MD2_BUFSIZE;
- }
-
- /* Copy any input that remains into the buffer. */
- if (inputLen)
- memcpy(&cx->X[MD2_INPUT], input, inputLen);
- cx->unusedBuffer = MD2_BUFSIZE - inputLen;
-}
-
-void
-MD2_End(MD2Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- PRUint8 padStart;
- if (maxDigestLen < MD2_BUFSIZE) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
- padStart = MD2_BUFSIZE - cx->unusedBuffer;
- memset(&cx->X[MD2_INPUT + padStart], cx->unusedBuffer,
- cx->unusedBuffer);
- md2_compress(cx);
- memcpy(&cx->X[MD2_INPUT], cx->checksum, MD2_BUFSIZE);
- md2_compress(cx);
- *digestLen = MD2_DIGEST_LEN;
- memcpy(digest, &cx->X[MD2_CV], MD2_DIGEST_LEN);
-}
-
-unsigned int
-MD2_FlattenSize(MD2Context *cx)
-{
- return sizeof(*cx);
-}
-
-SECStatus
-MD2_Flatten(MD2Context *cx, unsigned char *space)
-{
- memcpy(space, cx, sizeof(*cx));
- return SECSuccess;
-}
-
-MD2Context *
-MD2_Resurrect(unsigned char *space, void *arg)
-{
- MD2Context *cx = MD2_NewContext();
- if (cx)
- memcpy(cx, space, sizeof(*cx));
- return cx;
-}
-
-void MD2_Clone(MD2Context *dest, MD2Context *src)
-{
- memcpy(dest, src, sizeof *dest);
-}
diff --git a/security/nss/lib/freebl/md5.c b/security/nss/lib/freebl/md5.c
deleted file mode 100644
index 2929a633d..000000000
--- a/security/nss/lib/freebl/md5.c
+++ /dev/null
@@ -1,594 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prerr.h"
-#include "secerr.h"
-
-#include "prtypes.h"
-#include "prlong.h"
-
-#include "blapi.h"
-
-#define MD5_HASH_LEN 16
-#define MD5_BUFFER_SIZE 64
-#define MD5_END_BUFFER (MD5_BUFFER_SIZE - 8)
-
-#define CV0_1 0x67452301
-#define CV0_2 0xefcdab89
-#define CV0_3 0x98badcfe
-#define CV0_4 0x10325476
-
-#define T1_0 0xd76aa478
-#define T1_1 0xe8c7b756
-#define T1_2 0x242070db
-#define T1_3 0xc1bdceee
-#define T1_4 0xf57c0faf
-#define T1_5 0x4787c62a
-#define T1_6 0xa8304613
-#define T1_7 0xfd469501
-#define T1_8 0x698098d8
-#define T1_9 0x8b44f7af
-#define T1_10 0xffff5bb1
-#define T1_11 0x895cd7be
-#define T1_12 0x6b901122
-#define T1_13 0xfd987193
-#define T1_14 0xa679438e
-#define T1_15 0x49b40821
-
-#define T2_0 0xf61e2562
-#define T2_1 0xc040b340
-#define T2_2 0x265e5a51
-#define T2_3 0xe9b6c7aa
-#define T2_4 0xd62f105d
-#define T2_5 0x02441453
-#define T2_6 0xd8a1e681
-#define T2_7 0xe7d3fbc8
-#define T2_8 0x21e1cde6
-#define T2_9 0xc33707d6
-#define T2_10 0xf4d50d87
-#define T2_11 0x455a14ed
-#define T2_12 0xa9e3e905
-#define T2_13 0xfcefa3f8
-#define T2_14 0x676f02d9
-#define T2_15 0x8d2a4c8a
-
-#define T3_0 0xfffa3942
-#define T3_1 0x8771f681
-#define T3_2 0x6d9d6122
-#define T3_3 0xfde5380c
-#define T3_4 0xa4beea44
-#define T3_5 0x4bdecfa9
-#define T3_6 0xf6bb4b60
-#define T3_7 0xbebfbc70
-#define T3_8 0x289b7ec6
-#define T3_9 0xeaa127fa
-#define T3_10 0xd4ef3085
-#define T3_11 0x04881d05
-#define T3_12 0xd9d4d039
-#define T3_13 0xe6db99e5
-#define T3_14 0x1fa27cf8
-#define T3_15 0xc4ac5665
-
-#define T4_0 0xf4292244
-#define T4_1 0x432aff97
-#define T4_2 0xab9423a7
-#define T4_3 0xfc93a039
-#define T4_4 0x655b59c3
-#define T4_5 0x8f0ccc92
-#define T4_6 0xffeff47d
-#define T4_7 0x85845dd1
-#define T4_8 0x6fa87e4f
-#define T4_9 0xfe2ce6e0
-#define T4_10 0xa3014314
-#define T4_11 0x4e0811a1
-#define T4_12 0xf7537e82
-#define T4_13 0xbd3af235
-#define T4_14 0x2ad7d2bb
-#define T4_15 0xeb86d391
-
-#define R1B0 0
-#define R1B1 1
-#define R1B2 2
-#define R1B3 3
-#define R1B4 4
-#define R1B5 5
-#define R1B6 6
-#define R1B7 7
-#define R1B8 8
-#define R1B9 9
-#define R1B10 10
-#define R1B11 11
-#define R1B12 12
-#define R1B13 13
-#define R1B14 14
-#define R1B15 15
-
-#define R2B0 1
-#define R2B1 6
-#define R2B2 11
-#define R2B3 0
-#define R2B4 5
-#define R2B5 10
-#define R2B6 15
-#define R2B7 4
-#define R2B8 9
-#define R2B9 14
-#define R2B10 3
-#define R2B11 8
-#define R2B12 13
-#define R2B13 2
-#define R2B14 7
-#define R2B15 12
-
-#define R3B0 5
-#define R3B1 8
-#define R3B2 11
-#define R3B3 14
-#define R3B4 1
-#define R3B5 4
-#define R3B6 7
-#define R3B7 10
-#define R3B8 13
-#define R3B9 0
-#define R3B10 3
-#define R3B11 6
-#define R3B12 9
-#define R3B13 12
-#define R3B14 15
-#define R3B15 2
-
-#define R4B0 0
-#define R4B1 7
-#define R4B2 14
-#define R4B3 5
-#define R4B4 12
-#define R4B5 3
-#define R4B6 10
-#define R4B7 1
-#define R4B8 8
-#define R4B9 15
-#define R4B10 6
-#define R4B11 13
-#define R4B12 4
-#define R4B13 11
-#define R4B14 2
-#define R4B15 9
-
-#define S1_0 7
-#define S1_1 12
-#define S1_2 17
-#define S1_3 22
-
-#define S2_0 5
-#define S2_1 9
-#define S2_2 14
-#define S2_3 20
-
-#define S3_0 4
-#define S3_1 11
-#define S3_2 16
-#define S3_3 23
-
-#define S4_0 6
-#define S4_1 10
-#define S4_2 15
-#define S4_3 21
-
-struct MD5ContextStr {
- PRUint32 lsbInput;
- PRUint32 msbInput;
- PRUint32 cv[4];
- union {
- PRUint8 b[64];
- PRUint32 w[16];
- } u;
-};
-
-#define inBuf u.b
-
-SECStatus
-MD5_Hash(unsigned char *dest, const char *src)
-{
- return MD5_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
-}
-
-SECStatus
-MD5_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
-{
- unsigned int len;
- MD5Context cx;
-
- MD5_Begin(&cx);
- MD5_Update(&cx, src, src_length);
- MD5_End(&cx, dest, &len, MD5_HASH_LEN);
- memset(&cx, 0, sizeof cx);
- return SECSuccess;
-}
-
-MD5Context *
-MD5_NewContext(void)
-{
- /* no need to ZAlloc, MD5_Begin will init the context */
- MD5Context *cx = (MD5Context *)PORT_Alloc(sizeof(MD5Context));
- if (cx == NULL) {
- PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
- return NULL;
- }
- return cx;
-}
-
-void
-MD5_DestroyContext(MD5Context *cx, PRBool freeit)
-{
- memset(cx, 0, sizeof *cx);
- if (freeit) {
- PORT_Free(cx);
- }
-}
-
-void
-MD5_Begin(MD5Context *cx)
-{
- cx->lsbInput = 0;
- cx->msbInput = 0;
-/* memset(cx->inBuf, 0, sizeof(cx->inBuf)); */
- cx->cv[0] = CV0_1;
- cx->cv[1] = CV0_2;
- cx->cv[2] = CV0_3;
- cx->cv[3] = CV0_4;
-}
-
-#define cls(i32, s) (tmp = i32, tmp << s | tmp >> (32 - s))
-
-#if defined(SOLARIS) || defined(HPUX)
-#define addto64(sumhigh, sumlow, addend) \
- sumlow += addend; sumhigh += (sumlow < addend);
-#else
-#define addto64(sumhigh, sumlow, addend) \
- sumlow += addend; if (sumlow < addend) ++sumhigh;
-#endif
-
-#define MASK 0x00ff00ff
-#ifdef IS_LITTLE_ENDIAN
-#define lendian(i32) \
- (i32)
-#else
-#define lendian(i32) \
- (tmp = i32 >> 16 | i32 << 16, (tmp & MASK) << 8 | tmp >> 8 & MASK)
-#endif
-
-#ifndef IS_LITTLE_ENDIAN
-
-#define lebytes(b4) \
- ((b4)[3] << 24 | (b4)[2] << 16 | (b4)[1] << 8 | (b4)[0])
-
-static void
-md5_prep_state_le(MD5Context *cx)
-{
- PRUint32 tmp;
- cx->u.w[0] = lendian(cx->u.w[0]);
- cx->u.w[1] = lendian(cx->u.w[1]);
- cx->u.w[2] = lendian(cx->u.w[2]);
- cx->u.w[3] = lendian(cx->u.w[3]);
- cx->u.w[4] = lendian(cx->u.w[4]);
- cx->u.w[5] = lendian(cx->u.w[5]);
- cx->u.w[6] = lendian(cx->u.w[6]);
- cx->u.w[7] = lendian(cx->u.w[7]);
- cx->u.w[8] = lendian(cx->u.w[8]);
- cx->u.w[9] = lendian(cx->u.w[9]);
- cx->u.w[10] = lendian(cx->u.w[10]);
- cx->u.w[11] = lendian(cx->u.w[11]);
- cx->u.w[12] = lendian(cx->u.w[12]);
- cx->u.w[13] = lendian(cx->u.w[13]);
- cx->u.w[14] = lendian(cx->u.w[14]);
- cx->u.w[15] = lendian(cx->u.w[15]);
-}
-
-static void
-md5_prep_buffer_le(MD5Context *cx, const PRUint8 *beBuf)
-{
- cx->u.w[0] = lebytes(&beBuf[0]);
- cx->u.w[1] = lebytes(&beBuf[4]);
- cx->u.w[2] = lebytes(&beBuf[8]);
- cx->u.w[3] = lebytes(&beBuf[12]);
- cx->u.w[4] = lebytes(&beBuf[16]);
- cx->u.w[5] = lebytes(&beBuf[20]);
- cx->u.w[6] = lebytes(&beBuf[24]);
- cx->u.w[7] = lebytes(&beBuf[28]);
- cx->u.w[8] = lebytes(&beBuf[32]);
- cx->u.w[9] = lebytes(&beBuf[36]);
- cx->u.w[10] = lebytes(&beBuf[40]);
- cx->u.w[11] = lebytes(&beBuf[44]);
- cx->u.w[12] = lebytes(&beBuf[48]);
- cx->u.w[13] = lebytes(&beBuf[52]);
- cx->u.w[14] = lebytes(&beBuf[56]);
- cx->u.w[15] = lebytes(&beBuf[60]);
-}
-#endif
-
-
-#define F(X, Y, Z) \
- ((X & Y) | ((~X) & Z))
-
-#define G(X, Y, Z) \
- ((X & Z) | (Y & (~Z)))
-
-#define H(X, Y, Z) \
- (X ^ Y ^ Z)
-
-#define I(X, Y, Z) \
- (Y ^ (X | (~Z)))
-
-#define FF(a, b, c, d, bufint, s, ti) \
- a = b + cls(a + F(b, c, d) + bufint + ti, s)
-
-#define GG(a, b, c, d, bufint, s, ti) \
- a = b + cls(a + G(b, c, d) + bufint + ti, s)
-
-#define HH(a, b, c, d, bufint, s, ti) \
- a = b + cls(a + H(b, c, d) + bufint + ti, s)
-
-#define II(a, b, c, d, bufint, s, ti) \
- a = b + cls(a + I(b, c, d) + bufint + ti, s)
-
-static void
-md5_compress(MD5Context *cx, const PRUint32 *wBuf)
-{
- PRUint32 a, b, c, d;
- PRUint32 tmp;
- a = cx->cv[0];
- b = cx->cv[1];
- c = cx->cv[2];
- d = cx->cv[3];
- FF(a, b, c, d, wBuf[R1B0 ], S1_0, T1_0);
- FF(d, a, b, c, wBuf[R1B1 ], S1_1, T1_1);
- FF(c, d, a, b, wBuf[R1B2 ], S1_2, T1_2);
- FF(b, c, d, a, wBuf[R1B3 ], S1_3, T1_3);
- FF(a, b, c, d, wBuf[R1B4 ], S1_0, T1_4);
- FF(d, a, b, c, wBuf[R1B5 ], S1_1, T1_5);
- FF(c, d, a, b, wBuf[R1B6 ], S1_2, T1_6);
- FF(b, c, d, a, wBuf[R1B7 ], S1_3, T1_7);
- FF(a, b, c, d, wBuf[R1B8 ], S1_0, T1_8);
- FF(d, a, b, c, wBuf[R1B9 ], S1_1, T1_9);
- FF(c, d, a, b, wBuf[R1B10], S1_2, T1_10);
- FF(b, c, d, a, wBuf[R1B11], S1_3, T1_11);
- FF(a, b, c, d, wBuf[R1B12], S1_0, T1_12);
- FF(d, a, b, c, wBuf[R1B13], S1_1, T1_13);
- FF(c, d, a, b, wBuf[R1B14], S1_2, T1_14);
- FF(b, c, d, a, wBuf[R1B15], S1_3, T1_15);
- GG(a, b, c, d, wBuf[R2B0 ], S2_0, T2_0);
- GG(d, a, b, c, wBuf[R2B1 ], S2_1, T2_1);
- GG(c, d, a, b, wBuf[R2B2 ], S2_2, T2_2);
- GG(b, c, d, a, wBuf[R2B3 ], S2_3, T2_3);
- GG(a, b, c, d, wBuf[R2B4 ], S2_0, T2_4);
- GG(d, a, b, c, wBuf[R2B5 ], S2_1, T2_5);
- GG(c, d, a, b, wBuf[R2B6 ], S2_2, T2_6);
- GG(b, c, d, a, wBuf[R2B7 ], S2_3, T2_7);
- GG(a, b, c, d, wBuf[R2B8 ], S2_0, T2_8);
- GG(d, a, b, c, wBuf[R2B9 ], S2_1, T2_9);
- GG(c, d, a, b, wBuf[R2B10], S2_2, T2_10);
- GG(b, c, d, a, wBuf[R2B11], S2_3, T2_11);
- GG(a, b, c, d, wBuf[R2B12], S2_0, T2_12);
- GG(d, a, b, c, wBuf[R2B13], S2_1, T2_13);
- GG(c, d, a, b, wBuf[R2B14], S2_2, T2_14);
- GG(b, c, d, a, wBuf[R2B15], S2_3, T2_15);
- HH(a, b, c, d, wBuf[R3B0 ], S3_0, T3_0);
- HH(d, a, b, c, wBuf[R3B1 ], S3_1, T3_1);
- HH(c, d, a, b, wBuf[R3B2 ], S3_2, T3_2);
- HH(b, c, d, a, wBuf[R3B3 ], S3_3, T3_3);
- HH(a, b, c, d, wBuf[R3B4 ], S3_0, T3_4);
- HH(d, a, b, c, wBuf[R3B5 ], S3_1, T3_5);
- HH(c, d, a, b, wBuf[R3B6 ], S3_2, T3_6);
- HH(b, c, d, a, wBuf[R3B7 ], S3_3, T3_7);
- HH(a, b, c, d, wBuf[R3B8 ], S3_0, T3_8);
- HH(d, a, b, c, wBuf[R3B9 ], S3_1, T3_9);
- HH(c, d, a, b, wBuf[R3B10], S3_2, T3_10);
- HH(b, c, d, a, wBuf[R3B11], S3_3, T3_11);
- HH(a, b, c, d, wBuf[R3B12], S3_0, T3_12);
- HH(d, a, b, c, wBuf[R3B13], S3_1, T3_13);
- HH(c, d, a, b, wBuf[R3B14], S3_2, T3_14);
- HH(b, c, d, a, wBuf[R3B15], S3_3, T3_15);
- II(a, b, c, d, wBuf[R4B0 ], S4_0, T4_0);
- II(d, a, b, c, wBuf[R4B1 ], S4_1, T4_1);
- II(c, d, a, b, wBuf[R4B2 ], S4_2, T4_2);
- II(b, c, d, a, wBuf[R4B3 ], S4_3, T4_3);
- II(a, b, c, d, wBuf[R4B4 ], S4_0, T4_4);
- II(d, a, b, c, wBuf[R4B5 ], S4_1, T4_5);
- II(c, d, a, b, wBuf[R4B6 ], S4_2, T4_6);
- II(b, c, d, a, wBuf[R4B7 ], S4_3, T4_7);
- II(a, b, c, d, wBuf[R4B8 ], S4_0, T4_8);
- II(d, a, b, c, wBuf[R4B9 ], S4_1, T4_9);
- II(c, d, a, b, wBuf[R4B10], S4_2, T4_10);
- II(b, c, d, a, wBuf[R4B11], S4_3, T4_11);
- II(a, b, c, d, wBuf[R4B12], S4_0, T4_12);
- II(d, a, b, c, wBuf[R4B13], S4_1, T4_13);
- II(c, d, a, b, wBuf[R4B14], S4_2, T4_14);
- II(b, c, d, a, wBuf[R4B15], S4_3, T4_15);
- cx->cv[0] += a;
- cx->cv[1] += b;
- cx->cv[2] += c;
- cx->cv[3] += d;
-}
-
-void
-MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen)
-{
- PRUint32 bytesToConsume;
- PRUint32 inBufIndex = cx->lsbInput & 63;
- const PRUint32 *wBuf;
-
- /* Add the number of input bytes to the 64-bit input counter. */
- addto64(cx->msbInput, cx->lsbInput, inputLen);
- if (inBufIndex) {
- /* There is already data in the buffer. Fill with input. */
- bytesToConsume = PR_MIN(inputLen, MD5_BUFFER_SIZE - inBufIndex);
- memcpy(&cx->inBuf[inBufIndex], input, bytesToConsume);
- if (inBufIndex + bytesToConsume >= MD5_BUFFER_SIZE) {
- /* The buffer is filled. Run the compression function. */
-#ifndef IS_LITTLE_ENDIAN
- md5_prep_state_le(cx);
-#endif
- md5_compress(cx, cx->u.w);
- }
- /* Remaining input. */
- inputLen -= bytesToConsume;
- input += bytesToConsume;
- }
-
- /* Iterate over 64-byte chunks of the message. */
- while (inputLen >= MD5_BUFFER_SIZE) {
-#ifdef IS_LITTLE_ENDIAN
-#ifdef NSS_X86_OR_X64
- /* x86 can handle arithmetic on non-word-aligned buffers */
- wBuf = (PRUint32 *)input;
-#else
- if ((ptrdiff_t)input & 0x3) {
- /* buffer not aligned, copy it to force alignment */
- memcpy(cx->inBuf, input, MD5_BUFFER_SIZE);
- wBuf = cx->u.w;
- } else {
- /* buffer is aligned */
- wBuf = (PRUint32 *)input;
- }
-#endif
-#else
- md5_prep_buffer_le(cx, input);
- wBuf = cx->u.w;
-#endif
- md5_compress(cx, wBuf);
- inputLen -= MD5_BUFFER_SIZE;
- input += MD5_BUFFER_SIZE;
- }
-
- /* Tail of message (message bytes mod 64). */
- if (inputLen)
- memcpy(cx->inBuf, input, inputLen);
-}
-
-static const unsigned char padbytes[] = {
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-void
-MD5_End(MD5Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
-#ifndef IS_LITTLE_ENDIAN
- PRUint32 tmp;
-#endif
- PRUint32 lowInput, highInput;
- PRUint32 inBufIndex = cx->lsbInput & 63;
-
- if (maxDigestLen < MD5_HASH_LEN) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
-
- /* Copy out the length of bits input before padding. */
- lowInput = cx->lsbInput;
- highInput = (cx->msbInput << 3) | (lowInput >> 29);
- lowInput <<= 3;
-
- if (inBufIndex < MD5_END_BUFFER) {
- MD5_Update(cx, padbytes, MD5_END_BUFFER - inBufIndex);
- } else {
- MD5_Update(cx, padbytes,
- MD5_END_BUFFER + MD5_BUFFER_SIZE - inBufIndex);
- }
-
- /* Store the number of bytes input (before padding) in final 64 bits. */
- cx->u.w[14] = lendian(lowInput);
- cx->u.w[15] = lendian(highInput);
-
- /* Final call to compress. */
-#ifndef IS_LITTLE_ENDIAN
- md5_prep_state_le(cx);
-#endif
- md5_compress(cx, cx->u.w);
-
- /* Copy the resulting values out of the chain variables into return buf. */
- if (digestLen)
- *digestLen = MD5_HASH_LEN;
-#ifndef IS_LITTLE_ENDIAN
- cx->cv[0] = lendian(cx->cv[0]);
- cx->cv[1] = lendian(cx->cv[1]);
- cx->cv[2] = lendian(cx->cv[2]);
- cx->cv[3] = lendian(cx->cv[3]);
-#endif
- memcpy(digest, cx->cv, MD5_HASH_LEN);
-}
-
-void
-MD5_EndRaw(MD5Context *cx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
-#ifndef IS_LITTLE_ENDIAN
- PRUint32 tmp;
-#endif
- PRUint32 cv[4];
-
- if (maxDigestLen < MD5_HASH_LEN) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
-
- memcpy(cv, cx->cv, sizeof(cv));
-#ifndef IS_LITTLE_ENDIAN
- cv[0] = lendian(cv[0]);
- cv[1] = lendian(cv[1]);
- cv[2] = lendian(cv[2]);
- cv[3] = lendian(cv[3]);
-#endif
- memcpy(digest, cv, MD5_HASH_LEN);
- if (digestLen)
- *digestLen = MD5_HASH_LEN;
-}
-
-unsigned int
-MD5_FlattenSize(MD5Context *cx)
-{
- return sizeof(*cx);
-}
-
-SECStatus
-MD5_Flatten(MD5Context *cx, unsigned char *space)
-{
- memcpy(space, cx, sizeof(*cx));
- return SECSuccess;
-}
-
-MD5Context *
-MD5_Resurrect(unsigned char *space, void *arg)
-{
- MD5Context *cx = MD5_NewContext();
- if (cx)
- memcpy(cx, space, sizeof(*cx));
- return cx;
-}
-
-void MD5_Clone(MD5Context *dest, MD5Context *src)
-{
- memcpy(dest, src, sizeof *dest);
-}
-
-void
-MD5_TraceState(MD5Context *cx)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
-}
diff --git a/security/nss/lib/freebl/mknewpc2.c b/security/nss/lib/freebl/mknewpc2.c
deleted file mode 100644
index b0957fa99..000000000
--- a/security/nss/lib/freebl/mknewpc2.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * mknewpc2.c
- *
- * Generate PC-2 tables for DES-150 library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-typedef unsigned char BYTE;
-typedef unsigned int HALF;
-
-#define DES_ENCRYPT 0
-#define DES_DECRYPT 1
-
-/* two 28-bit registers defined in key schedule production process */
-static HALF C0, D0;
-
-static HALF L0, R0;
-
-/* key schedule, 16 internal keys, each with 8 6-bit parts */
-static BYTE KS [8] [16];
-
-
-/*
- * This table takes the 56 bits in C0 and D0 and shows show they are
- * permuted into the 8 6-bit parts of the key in the key schedule.
- * The bits of C0 are numbered left to right, 1-28.
- * The bits of D0 are numbered left to right, 29-56.
- * Zeros in this table represent bits that are always zero.
- * Note that all the bits in the first 4 rows come from C0,
- * and all the bits in the second 4 rows come from D0.
- */
-static const BYTE PC2[64] = {
- 14, 17, 11, 24, 1, 5, 0, 0, /* S1 */
- 3, 28, 15, 6, 21, 10, 0, 0, /* S2 */
- 23, 19, 12, 4, 26, 8, 0, 0, /* S3 */
- 16, 7, 27, 20, 13, 2, 0, 0, /* S4 */
-
- 41, 52, 31, 37, 47, 55, 0, 0, /* S5 */
- 30, 40, 51, 45, 33, 48, 0, 0, /* S6 */
- 44, 49, 39, 56, 34, 53, 0, 0, /* S7 */
- 46, 42, 50, 36, 29, 32, 0, 0 /* S8 */
-};
-
-/* This table represents the same info as PC2, except that
- * The bits of C0 and D0 are each numbered right to left, 0-27.
- * -1 values indicate bits that are always zero.
- * As before all the bits in the first 4 rows come from C0,
- * and all the bits in the second 4 rows come from D0.
- */
-static signed char PC2a[64] = {
-/* bits of C0 */
- 14, 11, 17, 4, 27, 23, -1, -1, /* S1 */
- 25, 0, 13, 22, 7, 18, -1, -1, /* S2 */
- 5, 9, 16, 24, 2, 20, -1, -1, /* S3 */
- 12, 21, 1, 8, 15, 26, -1, -1, /* S4 */
-/* bits of D0 */
- 15, 4, 25, 19, 9, 1, -1, -1, /* S5 */
- 26, 16, 5, 11, 23, 8, -1, -1, /* S6 */
- 12, 7, 17, 0, 22, 3, -1, -1, /* S7 */
- 10, 14, 6, 20, 27, 24, -1, -1 /* S8 */
-};
-
-/* This table represents the same info as PC2a, except that
- * The order of of the rows has been changed to increase the efficiency
- * with which the key sechedule is created.
- * Fewer shifts and ANDs are required to make the KS from these.
- */
-static const signed char PC2b[64] = {
-/* bits of C0 */
- 14, 11, 17, 4, 27, 23, -1, -1, /* S1 */
- 5, 9, 16, 24, 2, 20, -1, -1, /* S3 */
- 25, 0, 13, 22, 7, 18, -1, -1, /* S2 */
- 12, 21, 1, 8, 15, 26, -1, -1, /* S4 */
-/* bits of D0 */
- 26, 16, 5, 11, 23, 8, -1, -1, /* S6 */
- 10, 14, 6, 20, 27, 24, -1, -1, /* S8 */
- 15, 4, 25, 19, 9, 1, -1, -1, /* S5 */
- 12, 7, 17, 0, 22, 3, -1, -1 /* S7 */
-};
-
-/* Only 24 of the 28 bits in C0 and D0 are used in PC2.
- * The used bits of C0 and D0 are grouped into 4 groups of 6,
- * so that the PC2 permutation can be accomplished with 4 lookups
- * in tables of 64 entries.
- * The following table shows how the bits of C0 and D0 are grouped
- * into indexes for the respective table lookups.
- * Bits are numbered right-to-left, 0-27, as in PC2b.
- */
-static BYTE NDX[48] = {
-/* Bits of C0 */
- 27, 26, 25, 24, 23, 22, /* C0 table 0 */
- 18, 17, 16, 15, 14, 13, /* C0 table 1 */
- 9, 8, 7, 2, 1, 0, /* C0 table 2 */
- 5, 4, 21, 20, 12, 11, /* C0 table 3 */
-/* bits of D0 */
- 27, 26, 25, 24, 23, 22, /* D0 table 0 */
- 20, 19, 17, 16, 15, 14, /* D0 table 1 */
- 12, 11, 10, 9, 8, 7, /* D0 table 2 */
- 6, 5, 4, 3, 1, 0 /* D0 table 3 */
-};
-
-/* Here's the code that does that grouping.
- left = PC2LOOKUP(0, 0, ((c0 >> 22) & 0x3F) );
- left |= PC2LOOKUP(0, 1, ((c0 >> 13) & 0x3F) );
- left |= PC2LOOKUP(0, 2, ((c0 >> 4) & 0x38) | (c0 & 0x7) );
- left |= PC2LOOKUP(0, 3, ((c0>>18)&0xC) | ((c0>>11)&0x3) | (c0&0x30));
-
- right = PC2LOOKUP(1, 0, ((d0 >> 22) & 0x3F) );
- right |= PC2LOOKUP(1, 1, ((d0 >> 15) & 0x30) | ((d0 >> 14) & 0xf) );
- right |= PC2LOOKUP(1, 2, ((d0 >> 7) & 0x3F) );
- right |= PC2LOOKUP(1, 3, ((d0 >> 1) & 0x3C) | (d0 & 0x3));
-*/
-
-void
-make_pc2a( void )
-{
-
- int i, j;
-
- for ( i = 0; i < 64; ++i ) {
- j = PC2[i];
- if (j == 0)
- j = -1;
- else if ( j < 29 )
- j = 28 - j ;
- else
- j = 56 - j;
- PC2a[i] = j;
- }
- for ( i = 0; i < 64; i += 8 ) {
- printf("%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,\n",
- PC2a[i+0],PC2a[i+1],PC2a[i+2],PC2a[i+3],
- PC2a[i+4],PC2a[i+5],PC2a[i+6],PC2a[i+7] );
- }
-}
-
-HALF PC2cd0[64];
-
-HALF PC_2H[8][64];
-
-void
-mktable( )
-{
- int i;
- int table;
- const BYTE * ndx = NDX;
- HALF mask;
-
- mask = 0x80000000;
- for (i = 0; i < 32; ++i, mask >>= 1) {
- int bit = PC2b[i];
- if (bit < 0)
- continue;
- PC2cd0[bit + 32] = mask;
- }
-
- mask = 0x80000000;
- for (i = 32; i < 64; ++i, mask >>= 1) {
- int bit = PC2b[i];
- if (bit < 0)
- continue;
- PC2cd0[bit] = mask;
- }
-
-#if DEBUG
- for (i = 0; i < 64; ++i) {
- printf("0x%08x,\n", PC2cd0[i]);
- }
-#endif
- for (i = 0; i < 24; ++i) {
- NDX[i] += 32; /* because c0 is the upper half */
- }
-
- for (table = 0; table < 8; ++table) {
- HALF bitvals[6];
- for (i = 0; i < 6; ++i) {
- bitvals[5-i] = PC2cd0[*ndx++];
- }
- for (i = 0; i < 64; ++i) {
- int j;
- int k = 0;
- HALF value = 0;
-
- for (j = i; j; j >>= 1, ++k) {
- if (j & 1) {
- value |= bitvals[k];
- }
- }
- PC_2H[table][i] = value;
- }
- printf("/* table %d */ {\n", table );
- for (i = 0; i < 64; i += 4) {
- printf(" 0x%08x, 0x%08x, 0x%08x, 0x%08x, \n",
- PC_2H[table][i], PC_2H[table][i+1],
- PC_2H[table][i+2], PC_2H[table][i+3]);
- }
- printf(" },\n");
- }
-}
-
-
-int
-main(void)
-{
-/* make_pc2a(); */
- mktable();
- return 0;
-}
diff --git a/security/nss/lib/freebl/mksp.c b/security/nss/lib/freebl/mksp.c
deleted file mode 100644
index 99b9917b8..000000000
--- a/security/nss/lib/freebl/mksp.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * mksp.c
- *
- * Generate SP tables for DES-150 library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdio.h>
-
-/*
- * sboxes - the tables for the s-box functions
- * from FIPS 46, pages 15-16.
- */
-unsigned char S[8][64] = {
-/* Func S1 = */ {
- 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
- 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
- 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
- 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
- },
-/* Func S2 = */ {
- 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
- 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
- 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
- 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
- },
-/* Func S3 = */ {
- 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
- 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
- 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
- 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
- },
-/* Func S4 = */ {
- 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
- 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
- 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
- 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
- },
-/* Func S5 = */ {
- 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
- 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
- 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
- 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
- },
-/* Func S6 = */ {
- 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
- 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
- 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
- 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
- },
-/* Func S7 = */ {
- 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
- 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
- 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
- 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
- },
-/* Func S8 = */ {
- 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
- 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
- 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
- 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
- }
-};
-
-/*
- * Permutation function for results from s-boxes
- * from FIPS 46 pages 12 and 16.
- * P =
- */
-unsigned char P[32] = {
- 16, 7, 20, 21, 29, 12, 28, 17,
- 1, 15, 23, 26, 5, 18, 31, 10,
- 2, 8, 24, 14, 32, 27, 3, 9,
- 19, 13, 30, 6, 22, 11, 4, 25
-};
-
-unsigned int Pinv[32];
-unsigned int SP[8][64];
-
-void
-makePinv(void)
-{
- int i;
- unsigned int Pi = 0x80000000;
- for (i = 0; i < 32; ++i) {
- int j = 32 - P[i];
- Pinv[j] = Pi;
- Pi >>= 1;
- }
-}
-
-void
-makeSP(void)
-{
- int box;
- for (box = 0; box < 8; ++box) {
- int item;
- printf("/* box S%d */ {\n", box + 1);
- for (item = 0; item < 64; ++item ) {
- unsigned int s = S[box][item];
- unsigned int val = 0;
- unsigned int bitnum = (7-box) * 4;
- for (; s; s >>= 1, ++bitnum) {
- if (s & 1) {
- val |= Pinv[bitnum];
- }
- }
- val = (val << 3) | (val >> 29);
- SP[box][item] = val;
- }
- for (item = 0; item < 64; item += 4) {
- printf("\t0x%08x, 0x%08x, 0x%08x, 0x%08x,\n",
- SP[box][item], SP[box][item+1], SP[box][item+2], SP[box][item+3]);
- }
- printf(" },\n");
- }
-}
-
-int
-main()
-{
- makePinv();
- makeSP();
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/Makefile b/security/nss/lib/freebl/mpi/Makefile
deleted file mode 100644
index 4f6cd7583..000000000
--- a/security/nss/lib/freebl/mpi/Makefile
+++ /dev/null
@@ -1,248 +0,0 @@
-#
-# Makefile for MPI library
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# $Id$
-#
-
-## Define CC to be the C compiler you wish to use. The GNU cc
-## compiler (gcc) should work, at the very least
-#CC=cc
-#CC=gcc
-
-##
-## Define PERL to point to your local Perl interpreter. It
-## should be Perl 5.x, although it's conceivable that Perl 4
-## might work ... I haven't tested it.
-##
-#PERL=/usr/bin/perl
-#PERL=perl
-
-include target.mk
-
-CFLAGS+= $(XCFLAGS)
-
-##
-## Define LIBS to include any libraries you need to link against.
-## If NO_TABLE is define, LIBS should include '-lm' or whatever is
-## necessary to bring in the math library. Otherwise, it can be
-## left alone, unless your system has other peculiar requirements.
-##
-LIBS=#-lmalloc#-lefence#-lm
-
-##
-## Define RANLIB to be the library header randomizer; you might not
-## need this on some systems (just set it to 'echo' on these systems,
-## such as IRIX)
-##
-RANLIB=echo
-
-##
-## This is the version string used for the documentation and
-## building the distribution tarball. Don't mess with it unless
-## you are releasing a new version
-VERS=1.7p6
-
-## ----------------------------------------------------------------------
-## You probably don't need to change anything below this line...
-##
-
-##
-## This is the list of source files that need to be packed into
-## the distribution file
-SRCS= mpi.c mpprime.c mplogic.c mp_gf2m.c mpmontg.c mpi-test.c primes.c \
- mpcpucache.c tests/ \
- utils/gcd.c utils/invmod.c utils/lap.c \
- utils/ptab.pl utils/sieve.c utils/isprime.c\
- utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \
- utils/bbsrand.c utils/prng.c utils/primegen.c \
- utils/basecvt.c utils/makeprime.c\
- utils/fact.c utils/exptmod.c utils/pi.c utils/metime.c \
- utils/mpi.h utils/mpprime.h mulsqr.c \
- make-test-arrays test-arrays.txt all-tests make-logtab \
- types.pl stats timetest multest
-
-## These are the header files that go into the distribution file
-HDRS=mpi.h mpi-config.h utils/mpi.h utils/mpi-config.h mpprime.h mplogic.h mp_gf2m.h \
- mp_gf2m-priv.h utils/bbs_rand.h tests/mpi.h tests/mpprime.h
-
-## These are the documentation files that go into the distribution file
-DOCS=README doc utils/README utils/PRIMES
-
-## This is the list of tools built by 'make tools'
-TOOLS=gcd invmod isprime lap dec2hex hex2dec primegen prng \
- basecvt fact exptmod pi makeprime identest
-
-LIBOBJS = mpprime.o mpmontg.o mplogic.o mp_gf2m.o mpi.o mpcpucache.o $(AS_OBJS)
-LIBHDRS = mpi-config.h mpi-priv.h mpi.h
-APPHDRS = mpi-config.h mpi.h mplogic.h mp_gf2m.h mpprime.h
-
-help:
- @ echo ""
- @ echo "The following targets can be built with this Makefile:"
- @ echo ""
- @ echo "libmpi.a - arithmetic and prime testing library"
- @ echo "mpi-test - test driver (requires MP_IOFUNC)"
- @ echo "tools - command line tools"
- @ echo "doc - manual pages for tools"
- @ echo "clean - clean up objects and such"
- @ echo "distclean - get ready for distribution"
- @ echo "dist - distribution tarball"
- @ echo ""
-
-.SUFFIXES: .c .o .i
-
-.c.i:
- $(CC) $(CFLAGS) -E $< > $@
-
-#.c.o: $*.h $*.c
-# $(CC) $(CFLAGS) -c $<
-
-#---------------------------------------
-
-$(LIBOBJS): $(LIBHDRS)
-
-logtab.h: make-logtab
- $(PERL) make-logtab > logtab.h
-
-mpi.o: mpi.c logtab.h $(LIBHDRS)
-
-mplogic.o: mplogic.c mpi-priv.h mplogic.h $(LIBHDRS)
-
-mp_gf2m.o: mp_gf2m.c mpi-priv.h mp_gf2m.h mp_gf2m-priv.h $(LIBHDRS)
-
-mpmontg.o: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS)
-
-mpprime.o: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS)
-
-mpcpucache.o: mpcpucache.c $(LIBHDRS)
-
-mpi_mips.o: mpi_mips.s
- $(CC) -o $@ $(ASFLAGS) -c mpi_mips.s
-
-mpi_sparc.o : montmulf.h
-
-mpv_sparcv9.s: vis_64.il mpv_sparc.c
- $(CC) -o $@ $(SOLARIS_FPU_FLAGS) -S vis_64.il mpv_sparc.c
-
-mpv_sparcv8.s: vis_64.il mpv_sparc.c
- $(CC) -o $@ $(SOLARIS_FPU_FLAGS) -S vis_32.il mpv_sparc.c
-
-montmulfv8.o montmulfv9.o mpv_sparcv8.o mpv_sparcv9.o : %.o : %.s
- $(CC) -o $@ $(SOLARIS_ASM_FLAGS) -c $<
-
-mpi_arm.o: mpi_arm.c $(LIBHDRS)
-
-# This rule is used to build the .s sources, which are then hand optimized.
-#montmulfv8.s montmulfv9.s : montmulf%.s : montmulf%.il montmulf.c montmulf.h
-# $(CC) -o $@ $(SOLARIS_ASM_FLAGS) -S montmulf$*.il montmulf.c
-
-
-libmpi.a: $(LIBOBJS)
- ar -cvr libmpi.a $(LIBOBJS)
- $(RANLIB) libmpi.a
-
-lib libs: libmpi.a
-
-mpi.i: mpi.h
-
-#---------------------------------------
-
-MPTESTOBJS = mptest1.o mptest2.o mptest3.o mptest3a.o mptest4.o mptest4a.o \
- mptest4b.o mptest6.o mptest7.o mptest8.o mptest9.o mptestb.o
-MPTESTS = $(MPTESTOBJS:.o=)
-
-$(MPTESTOBJS): mptest%.o: tests/mptest-%.c $(LIBHDRS)
- $(CC) $(CFLAGS) -o $@ -c $<
-
-$(MPTESTS): mptest%: mptest%.o libmpi.a
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
-
-tests: mptest1 mptest2 mptest3 mptest3a mptest4 mptest4a mptest4b mptest6 \
- mptestb bbsrand
-
-utests: mptest7 mptest8 mptest9
-
-#---------------------------------------
-
-EXTRAOBJS = bbsrand.o bbs_rand.o prng.o
-UTILOBJS = primegen.o metime.o identest.o basecvt.o fact.o exptmod.o pi.o \
- makeprime.o gcd.o invmod.o lap.o isprime.o \
- dec2hex.o hex2dec.o
-UTILS = $(UTILOBJS:.o=)
-
-$(UTILS): % : %.o libmpi.a
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
-
-$(UTILOBJS) $(EXTRAOBJS): %.o : utils/%.c $(LIBHDRS)
- $(CC) $(CFLAGS) -o $@ -c $<
-
-prng: prng.o bbs_rand.o libmpi.a
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
-
-bbsrand: bbsrand.o bbs_rand.o libmpi.a
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
-
-utils: $(UTILS) prng bbsrand
-
-#---------------------------------------
-
-test-info.c: test-arrays.txt
- $(PERL) make-test-arrays test-arrays.txt > test-info.c
-
-mpi-test.o: mpi-test.c test-info.c $(LIBHDRS)
- $(CC) $(CFLAGS) -o $@ -c $<
-
-mpi-test: mpi-test.o libmpi.a
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
-
-mdxptest.o: mdxptest.c $(LIBHDRS) mpi-priv.h
-
-mdxptest: mdxptest.o libmpi.a
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
-
-mulsqr.o: mulsqr.c logtab.h mpi.h mpi-config.h mpprime.h
- $(CC) $(CFLAGS) -DMP_SQUARE=1 -o $@ -c mulsqr.c
-
-mulsqr: mulsqr.o libmpi.a
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
-
-#---------------------------------------
-
-alltests: tests utests mpi-test
-
-tools: $(TOOLS)
-
-doc:
- (cd doc; ./build)
-
-clean:
- rm -f *.o *.a *.i
- rm -f core
- rm -f *~ .*~
- rm -f utils/*.o
- rm -f utils/core
- rm -f utils/*~ utils/.*~
-
-clobber: clean
- rm -f $(TOOLS) $(UTILS)
-
-distclean: clean
- rm -f mptest? mpi-test metime mulsqr karatsuba
- rm -f mptest?a mptest?b
- rm -f utils/mptest?
- rm -f test-info.c logtab.h
- rm -f libmpi.a
- rm -f $(TOOLS)
-
-dist: Makefile $(HDRS) $(SRCS) $(DOCS)
- tar -cvf mpi-$(VERS).tar Makefile $(HDRS) $(SRCS) $(DOCS)
- pgps -ab mpi-$(VERS).tar
- chmod +r mpi-$(VERS).tar.asc
- gzip -9 mpi-$(VERS).tar
-
-# END
diff --git a/security/nss/lib/freebl/mpi/Makefile.os2 b/security/nss/lib/freebl/mpi/Makefile.os2
deleted file mode 100644
index 8094af598..000000000
--- a/security/nss/lib/freebl/mpi/Makefile.os2
+++ /dev/null
@@ -1,247 +0,0 @@
-#
-# Makefile.win - gmake Makefile for building MPI with VACPP on OS/2
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# $Id$
-#
-
-## Define CC to be the C compiler you wish to use. The GNU cc
-## compiler (gcc) should work, at the very least
-#CC=cc
-#CC=gcc
-CC=icc.exe
-AS=alp.exe
-
-##
-## Define PERL to point to your local Perl interpreter. It
-## should be Perl 5.x, although it's conceivable that Perl 4
-## might work ... I haven't tested it.
-##
-#PERL=/usr/bin/perl
-#PERL=perl
-
-##
-## Define CFLAGS to contain any local options your compiler
-## setup requires.
-##
-## Conditional compilation options are no longer here; see
-## the file 'mpi-config.h' instead.
-##
-MPICMN = -I. -DMP_API_COMPATIBLE -DMP_IOFUNC -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
-
-#OS/2
-AS_SRCS = mpi_x86.asm
-MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
-#CFLAGS= -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC \
- -DDEBUG -D_DEBUG -UNDEBUG -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
-#CFLAGS = -O2 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
- -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
-#CFLAGS = -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
- -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
-CFLAGS = /Ti+ -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
- $(MPICMN)
-ASFLAGS =
-
-##
-## Define LIBS to include any libraries you need to link against.
-## If NO_TABLE is define, LIBS should include '-lm' or whatever is
-## necessary to bring in the math library. Otherwise, it can be
-## left alone, unless your system has other peculiar requirements.
-##
-LIBS=#-lmalloc#-lefence#-lm
-
-##
-## Define RANLIB to be the library header randomizer; you might not
-## need this on some systems (just set it to 'echo' on these systems,
-## such as IRIX)
-##
-RANLIB=echo
-
-##
-## This is the version string used for the documentation and
-## building the distribution tarball. Don't mess with it unless
-## you are releasing a new version
-VERS=1.7p6
-
-## ----------------------------------------------------------------------
-## You probably don't need to change anything below this line...
-##
-
-##
-## This is the list of source files that need to be packed into
-## the distribution file
-SRCS= mpi.c mpprime.c mplogic.c mpmontg.c mpi-test.c primes.c tests/ \
- utils/gcd.c utils/invmod.c utils/lap.c \
- utils/ptab.pl utils/sieve.c utils/isprime.c\
- utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \
- utils/bbsrand.c utils/prng.c utils/primegen.c \
- utils/basecvt.c utils/makeprime.c\
- utils/fact.c utils/exptmod.c utils/pi.c utils/metime.c \
- utils/mpi.h utils/mpprime.h mulsqr.c \
- make-test-arrays test-arrays.txt all-tests make-logtab \
- types.pl stats timetest multest
-
-## These are the header files that go into the distribution file
-HDRS=mpi.h mpi-config.h utils/mpi.h utils/mpi-config.h mpprime.h mplogic.h \
- utils/bbs_rand.h tests/mpi.h tests/mpprime.h
-
-## These are the documentation files that go into the distribution file
-DOCS=README doc utils/README utils/PRIMES
-
-## This is the list of tools built by 'make tools'
-TOOLS=gcd.exe invmod.exe isprime.exe lap.exe dec2hex.exe hex2dec.exe \
- primegen.exe prng.exe basecvt.exe fact.exe exptmod.exe pi.exe makeprime.exe
-
-AS_OBJS = $(AS_SRCS:.asm=.obj)
-LIBOBJS = mpprime.obj mpmontg.obj mplogic.obj mpi.obj $(AS_OBJS)
-LIBHDRS = mpi-config.h mpi-priv.h mpi.h
-APPHDRS = mpi-config.h mpi.h mplogic.h mpprime.h
-
-
-help:
- @ echo ""
- @ echo "The following targets can be built with this Makefile:"
- @ echo ""
- @ echo "mpi.lib - arithmetic and prime testing library"
- @ echo "mpi-test.exe - test driver (requires MP_IOFUNC)"
- @ echo "tools - command line tools"
- @ echo "doc - manual pages for tools"
- @ echo "clean - clean up objects and such"
- @ echo "distclean - get ready for distribution"
- @ echo "dist - distribution tarball"
- @ echo ""
-
-.SUFFIXES: .c .obj .i .lib .exe .asm
-
-.c.i:
- $(CC) $(CFLAGS) -E $< > $@
-
-.c.obj:
- $(CC) $(CFLAGS) -c $<
-
-.asm.obj:
- $(AS) $(ASFLAGS) $<
-
-.obj.exe:
- $(CC) $(CFLAGS) -Fo$@ $<
-
-#---------------------------------------
-
-$(LIBOBJS): $(LIBHDRS)
-
-logtab.h: make-logtab
- $(PERL) make-logtab > logtab.h
-
-mpi.obj: mpi.c logtab.h $(LIBHDRS)
-
-mplogic.obj: mplogic.c mpi-priv.h mplogic.h $(LIBHDRS)
-
-mpmontg.obj: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS)
-
-mpprime.obj: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS)
-
-mpi_mips.obj: mpi_mips.s
- $(CC) -Fo$@ $(ASFLAGS) -c mpi_mips.s
-
-mpi.lib: $(LIBOBJS)
- ilib /out:mpi.lib $(LIBOBJS)
- $(RANLIB) mpi.lib
-
-lib libs: mpi.lib
-
-#---------------------------------------
-
-MPTESTOBJS = mptest1.obj mptest2.obj mptest3.obj mptest3a.obj mptest4.obj \
- mptest4a.obj mptest4b.obj mptest6.obj mptest7.obj mptest8.obj mptest9.obj
-MPTESTS = $(MPTESTOBJS:.obj=.exe)
-
-$(MPTESTOBJS): mptest%.obj: tests/mptest-%.c $(LIBHDRS)
- $(CC) $(CFLAGS) -Fo$@ -c $<
-
-$(MPTESTS): mptest%.exe: mptest%.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-tests: mptest1.exe mptest2.exe mptest3.exe mptest3a.exe mptest4.exe \
- mptest4a.exe mptest4b.exe mptest6.exe bbsrand.exe
-
-utests: mptest7.exe mptest8.exe mptest9.exe
-
-#---------------------------------------
-
-EXTRAOBJS = bbsrand.obj bbs_rand.obj prng.obj
-UTILOBJS = primegen.obj metime.obj identest.obj basecvt.obj fact.obj \
- exptmod.obj pi.obj makeprime.obj karatsuba.obj gcd.obj invmod.obj lap.obj \
- isprime.obj dec2hex.obj hex2dec.obj
-UTILS = $(UTILOBJS:.obj=.exe)
-
-$(UTILS): %.exe : %.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-$(UTILOBJS) $(EXTRAOBJS): %.obj : utils/%.c $(LIBHDRS)
- $(CC) $(CFLAGS) -Fo$@ -c $<
-
-prng.exe: prng.obj bbs_rand.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-bbsrand.exe: bbsrand.obj bbs_rand.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-utils: $(UTILS) prng.exe bbsrand.exe
-
-#---------------------------------------
-
-test-info.c: test-arrays.txt
- $(PERL) make-test-arrays test-arrays.txt > test-info.c
-
-mpi-test.obj: mpi-test.c test-info.c $(LIBHDRS)
- $(CC) $(CFLAGS) -Fo$@ -c $<
-
-mpi-test.exe: mpi-test.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-mdxptest.obj: mdxptest.c $(LIBHDRS) mpi-priv.h
-
-mdxptest.exe: mdxptest.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-mulsqr.obj: mulsqr.c logtab.h mpi.h mpi-config.h mpprime.h
- $(CC) $(CFLAGS) -DMP_SQUARE=1 -Fo$@ -c mulsqr.c
-
-mulsqr.exe: mulsqr.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-#---------------------------------------
-
-alltests: tests utests mpi-test.exe
-
-tools: $(TOOLS)
-
-doc:
- (cd doc; ./build)
-
-clean:
- rm -f *.obj *.lib *.pdb *.ilk
- cd utils; rm -f *.obj *.lib *.pdb *.ilk
-
-distclean: clean
- rm -f mptest? mpi-test metime mulsqr karatsuba
- rm -f mptest?a mptest?b
- rm -f utils/mptest?
- rm -f test-info.c logtab.h
- rm -f mpi.lib
- rm -f $(TOOLS)
-
-dist: Makefile $(HDRS) $(SRCS) $(DOCS)
- tar -cvf mpi-$(VERS).tar Makefile $(HDRS) $(SRCS) $(DOCS)
- pgps -ab mpi-$(VERS).tar
- chmod +r mpi-$(VERS).tar.asc
- gzip -9 mpi-$(VERS).tar
-
-
-print:
- @echo LIBOBJS = $(LIBOBJS)
-# END
diff --git a/security/nss/lib/freebl/mpi/Makefile.win b/security/nss/lib/freebl/mpi/Makefile.win
deleted file mode 100644
index 5e2d941b2..000000000
--- a/security/nss/lib/freebl/mpi/Makefile.win
+++ /dev/null
@@ -1,258 +0,0 @@
-#
-# Makefile.win - gmake Makefile for building MPI with MSVC on NT
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# $Id$
-#
-
-## Define CC to be the C compiler you wish to use. The GNU cc
-## compiler (gcc) should work, at the very least
-#CC=cc
-#CC=gcc
-CC=cl.exe
-ifeq ($(CPU_ARCH),x86_64)
-AS=ml64.exe
-else
-AS=ml.exe
-endif
-
-##
-## Define PERL to point to your local Perl interpreter. It
-## should be Perl 5.x, although it's conceivable that Perl 4
-## might work ... I haven't tested it.
-##
-#PERL=/usr/bin/perl
-#PERL=perl
-
-##
-## Define CFLAGS to contain any local options your compiler
-## setup requires.
-##
-## Conditional compilation options are no longer here; see
-## the file 'mpi-config.h' instead.
-##
-MPICMN = -I. -DMP_API_COMPATIBLE -DMP_IOFUNC
-
-ifeq ($(CPU_ARCH),x86_64)
-AS_SRCS = mpi_x86_64.asm
-CFLAGS = -O2 -Z7 -MD -W3 -nologo -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
- -DWIN32 -D_WIN64 -D_AMD64_ -D_M_AMD64 -D_WINDOWS -DWIN95 $(MPICMN)
-ASFLAGS = -Cp -Sn -Zi -I.
-else
-#NT
-AS_SRCS = mpi_x86.asm
-MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
-#CFLAGS= -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC \
- -DDEBUG -D_DEBUG -UNDEBUG -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
-#CFLAGS = -O2 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
- -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
-#CFLAGS = -Od -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
- -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
-CFLAGS = -O2 -Z7 -MD -W3 -nologo -D_X86_ -DXP_PC -UDEBUG -U_DEBUG -DNDEBUG \
- -DWIN32 -D_WINDOWS -DWIN95 $(MPICMN)
-ASFLAGS = -Cp -Sn -Zi -coff -I.
-endif
-
-##
-## Define LIBS to include any libraries you need to link against.
-## If NO_TABLE is define, LIBS should include '-lm' or whatever is
-## necessary to bring in the math library. Otherwise, it can be
-## left alone, unless your system has other peculiar requirements.
-##
-LIBS=#-lmalloc#-lefence#-lm
-
-##
-## Define RANLIB to be the library header randomizer; you might not
-## need this on some systems (just set it to 'echo' on these systems,
-## such as IRIX)
-##
-RANLIB=echo
-
-##
-## This is the version string used for the documentation and
-## building the distribution tarball. Don't mess with it unless
-## you are releasing a new version
-VERS=1.7p6
-
-## ----------------------------------------------------------------------
-## You probably don't need to change anything below this line...
-##
-
-##
-## This is the list of source files that need to be packed into
-## the distribution file
-SRCS= mpi.c mpprime.c mplogic.c mpmontg.c mpi-test.c primes.c tests/ \
- utils/gcd.c utils/invmod.c utils/lap.c \
- utils/ptab.pl utils/sieve.c utils/isprime.c\
- utils/dec2hex.c utils/hex2dec.c utils/bbs_rand.c \
- utils/bbsrand.c utils/prng.c utils/primegen.c \
- utils/basecvt.c utils/makeprime.c\
- utils/fact.c utils/exptmod.c utils/pi.c utils/metime.c \
- utils/mpi.h utils/mpprime.h mulsqr.c \
- make-test-arrays test-arrays.txt all-tests make-logtab \
- types.pl stats timetest multest
-
-## These are the header files that go into the distribution file
-HDRS=mpi.h mpi-config.h utils/mpi.h utils/mpi-config.h mpprime.h mplogic.h \
- utils/bbs_rand.h tests/mpi.h tests/mpprime.h
-
-## These are the documentation files that go into the distribution file
-DOCS=README doc utils/README utils/PRIMES
-
-## This is the list of tools built by 'make tools'
-TOOLS=gcd.exe invmod.exe isprime.exe lap.exe dec2hex.exe hex2dec.exe \
- primegen.exe prng.exe basecvt.exe fact.exe exptmod.exe pi.exe makeprime.exe
-
-AS_OBJS = $(AS_SRCS:.asm=.obj)
-LIBOBJS = mpprime.obj mpmontg.obj mplogic.obj mpi.obj $(AS_OBJS)
-LIBHDRS = mpi-config.h mpi-priv.h mpi.h
-APPHDRS = mpi-config.h mpi.h mplogic.h mpprime.h
-
-
-help:
- @ echo ""
- @ echo "The following targets can be built with this Makefile:"
- @ echo ""
- @ echo "mpi.lib - arithmetic and prime testing library"
- @ echo "mpi-test - test driver (requires MP_IOFUNC)"
- @ echo "tools - command line tools"
- @ echo "doc - manual pages for tools"
- @ echo "clean - clean up objects and such"
- @ echo "distclean - get ready for distribution"
- @ echo "dist - distribution tarball"
- @ echo ""
-
-.SUFFIXES: .c .obj .i .lib .exe .asm
-
-.c.i:
- $(CC) $(CFLAGS) -E $< > $@
-
-.c.obj:
- $(CC) $(CFLAGS) -c $<
-
-.asm.obj:
- $(AS) $(ASFLAGS) -c $<
-
-.obj.exe:
- $(CC) $(CFLAGS) -Fo$@ $<
-
-#---------------------------------------
-
-$(LIBOBJS): $(LIBHDRS)
-
-logtab.h: make-logtab
- $(PERL) make-logtab > logtab.h
-
-mpi.obj: mpi.c logtab.h $(LIBHDRS)
-
-mplogic.obj: mplogic.c mpi-priv.h mplogic.h $(LIBHDRS)
-
-mpmontg.obj: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS)
-
-mpprime.obj: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS)
-
-mpi_mips.obj: mpi_mips.s
- $(CC) -Fo$@ $(ASFLAGS) -c mpi_mips.s
-
-mpi.lib: $(LIBOBJS)
- ar -cvr mpi.lib $(LIBOBJS)
- $(RANLIB) mpi.lib
-
-lib libs: mpi.lib
-
-#---------------------------------------
-
-MPTESTOBJS = mptest1.obj mptest2.obj mptest3.obj mptest3a.obj mptest4.obj \
- mptest4a.obj mptest4b.obj mptest6.obj mptest7.obj mptest8.obj mptest9.obj
-MPTESTS = $(MPTESTOBJS:.obj=.exe)
-
-$(MPTESTOBJS): mptest%.obj: tests/mptest-%.c $(LIBHDRS)
- $(CC) $(CFLAGS) -Fo$@ -c $<
-
-$(MPTESTS): mptest%.exe: mptest%.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-tests: mptest1.exe mptest2.exe mptest3.exe mptest3a.exe mptest4.exe \
- mptest4a.exe mptest4b.exe mptest6.exe bbsrand.exe
-
-utests: mptest7.exe mptest8.exe mptest9.exe
-
-#---------------------------------------
-
-EXTRAOBJS = bbsrand.obj bbs_rand.obj prng.obj
-UTILOBJS = primegen.obj metime.obj identest.obj basecvt.obj fact.obj \
- exptmod.obj pi.obj makeprime.obj karatsuba.obj gcd.obj invmod.obj lap.obj \
- isprime.obj dec2hex.obj hex2dec.obj
-UTILS = $(UTILOBJS:.obj=.exe)
-
-$(UTILS): %.exe : %.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-$(UTILOBJS) $(EXTRAOBJS): %.obj : utils/%.c $(LIBHDRS)
- $(CC) $(CFLAGS) -Fo$@ -c $<
-
-prng.exe: prng.obj bbs_rand.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-bbsrand.exe: bbsrand.obj bbs_rand.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-utils: $(UTILS) prng.exe bbsrand.exe
-
-#---------------------------------------
-
-test-info.c: test-arrays.txt
- $(PERL) make-test-arrays test-arrays.txt > test-info.c
-
-mpi-test.obj: mpi-test.c test-info.c $(LIBHDRS)
- $(CC) $(CFLAGS) -Fo$@ -c $<
-
-mpi-test.exe: mpi-test.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-mdxptest.obj: mdxptest.c $(LIBHDRS) mpi-priv.h
-
-mdxptest.exe: mdxptest.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-mulsqr.obj: mulsqr.c logtab.h mpi.h mpi-config.h mpprime.h
- $(CC) $(CFLAGS) -DMP_SQUARE=1 -Fo$@ -c mulsqr.c
-
-mulsqr.exe: mulsqr.obj mpi.lib $(LIBS)
- $(CC) $(CFLAGS) -Fo$@ $^
-
-#---------------------------------------
-
-alltests: tests utests mpi-test.exe
-
-tools: $(TOOLS)
-
-doc:
- (cd doc; ./build)
-
-clean:
- rm -f *.obj *.lib *.pdb *.ilk
- cd utils; rm -f *.obj *.lib *.pdb *.ilk
-
-distclean: clean
- rm -f mptest? mpi-test metime mulsqr karatsuba
- rm -f mptest?a mptest?b
- rm -f utils/mptest?
- rm -f test-info.c logtab.h
- rm -f mpi.lib
- rm -f $(TOOLS)
-
-dist: Makefile $(HDRS) $(SRCS) $(DOCS)
- tar -cvf mpi-$(VERS).tar Makefile $(HDRS) $(SRCS) $(DOCS)
- pgps -ab mpi-$(VERS).tar
- chmod +r mpi-$(VERS).tar.asc
- gzip -9 mpi-$(VERS).tar
-
-
-print:
- @echo LIBOBJS = $(LIBOBJS)
-# END
diff --git a/security/nss/lib/freebl/mpi/README b/security/nss/lib/freebl/mpi/README
deleted file mode 100644
index 1de002a9b..000000000
--- a/security/nss/lib/freebl/mpi/README
+++ /dev/null
@@ -1,795 +0,0 @@
-***** BEGIN LICENSE BLOCK *****
-Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
-The contents of this file are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-The Original Code is the MPI Arbitrary Precision Integer Arithmetic
-library.
-
-The Initial Developer of the Original Code is
-Michael J. Fromberger <sting@linguist.dartmouth.edu>
-Portions created by the Initial Developer are Copyright (C) 1997-2000
-the Initial Developer. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of this file only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of this file under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of this file under
-the terms of any one of the MPL, the GPL or the LGPL.
-
-***** END LICENSE BLOCK *****
-
-About the MPI Library
----------------------
-
-The files 'mpi.h' and 'mpi.c' define a simple, arbitrary precision
-signed integer arithmetic package. The implementation is not the most
-efficient possible, but the code is small and should be fairly easily
-portable to just about any machine that supports an ANSI C compiler,
-as long as it is capable of at least 16-bit arithmetic (but also see
-below for more on this).
-
-This library was written with an eye to cryptographic applications;
-thus, some care is taken to make sure that temporary values are not
-left lying around in memory when they are no longer in use. This adds
-some overhead for zeroing buffers before they are released back into
-the free pool; however, it gives you the assurance that there is only
-one copy of your important values residing in your process's address
-space at a time. Obviously, it is difficult to guarantee anything, in
-a pre-emptive multitasking environment, but this at least helps you
-keep a lid on the more obvious ways your data can get spread around in
-memory.
-
-
-Using the Library
------------------
-
-To use the MPI library in your program, you must include the header:
-
-#include "mpi.h"
-
-This header provides all the type and function declarations you'll
-need to use the library. Almost all the names defined by the library
-begin with the prefix 'mp_', so it should be easy to keep them from
-clashing with your program's namespace (he says, glibly, knowing full
-well there are always pathological cases).
-
-There are a few things you may want to configure about the library.
-By default, the MPI library uses an unsigned short for its digit type,
-and an unsigned int for its word type. The word type must be big
-enough to contain at least two digits, for the primitive arithmetic to
-work out. On my machine, a short is 2 bytes and an int is 4 bytes --
-but if you have 64-bit ints, you might want to use a 4-byte digit and
-an 8-byte word. I have tested the library using 1-byte digits and
-2-byte words, as well. Whatever you choose to do, the things you need
-to change are:
-
-(1) The type definitions for mp_digit and mp_word.
-
-(2) The macro DIGIT_FMT which tells mp_print() how to display a
- single digit. This is just a printf() format string, so you
- can adjust it appropriately.
-
-(3) The macros DIGIT_MAX and MP_WORD_MAX, which specify the
- largest value expressible in an mp_digit and an mp_word,
- respectively.
-
-Both the mp_digit and mp_word should be UNSIGNED integer types. The
-code relies on having the full positive precision of the type used for
-digits and words.
-
-The remaining type definitions should be left alone, for the most
-part. The code in the library does not make any significant
-assumptions about the sizes of things, but there is little if any
-reason to change the other parameters, so I would recommend you leave
-them as you found them.
-
-The library comes with a Perl script, 'types.pl', which will scan your
-current Makefile settings, and attempt to find good definitions for
-these types. It relies on a Unix sort of build environment, so it
-probably won't work under MacOS or Windows, but it can be convenient
-if you're porting to a new flavour of Unix. Just run 'types.pl' at
-the command line, and it will spit out its results to the standard
-output.
-
-
-Conventions
------------
-
-Most functions in the library return a value of type mp_err. This
-permits the library to communicate success or various kinds of failure
-to the calling program. The return values currently defined are:
-
- MP_OKAY - okay, operation succeeded, all's well
- MP_YES - okay, the answer is yes (same as MP_OKAY)
- MP_NO - okay, but answer is no (not MP_OKAY)
- MP_MEM - operation ran out of memory
- MP_RANGE - input parameter was out of range
- MP_BADARG - an invalid input parameter was provided
- MP_UNDEF - no output value is defined for this input
-
-The only function which currently uses MP_UNDEF is mp_invmod().
-Division by zero is undefined, but the division functions will return
-MP_RANGE for a zero divisor. MP_BADARG usually means you passed a
-bogus mp_int structure to the function. MP_YES and MP_NO are not used
-by the library itself; they're defined so you can use them in your own
-extensions.
-
-If you need a readable interpretation of these error codes in your
-program, you may also use the mp_strerror() function. This function
-takes an mp_err as input, and returns a pointer to a human-readable
-string describing the meaning of the error. These strings are stored
-as constants within the library, so the caller should not attempt to
-modify or free the memory associated with these strings.
-
-The library represents values in signed-magnitude format. Values
-strictly less than zero are negative, all others are considered
-positive (zero is positive by fiat). You can access the 'sign' member
-of the mp_int structure directly, but better is to use the mp_cmp_z()
-function, to find out which side of zero the value lies on.
-
-Most arithmetic functions have a single-digit variant, as well as the
-full arbitrary-precision. An mp_digit is an unsigned value between 0
-and DIGIT_MAX inclusive. The radix is available as RADIX. The number
-of bits in a given digit is given as DIGIT_BIT.
-
-Generally, input parameters are given before output parameters.
-Unless otherwise specified, any input parameter can be re-used as an
-output parameter, without confusing anything.
-
-The basic numeric type defined by the library is an mp_int. Virtually
-all the functions in the library take a pointer to an mp_int as one of
-their parameters. An explanation of how to create and use these
-<HR>
-<A NAME="p23">
-<H3>Problem 23:</H3>
-
-structures follows. And so, without further ado...
-
-
-Initialization and Cleanup
---------------------------
-
-The basic numeric type defined by the library is an 'mp_int'.
-However, it is not sufficient to simply declare a variable of type
-mp_int in your program. These variables also need to be initialized
-before they can be used, to allocate the internal storage they require
-for computation.
-
-This is done using one of the following functions:
-
- mp_init(mp_int *mp);
- mp_init_copy(mp_int *mp, mp_int *from);
- mp_init_size(mp_int *mp, mp_size p);
-
-Each of these requires a pointer to a structure of type mp_int. The
-basic mp_init() simply initializes the mp_int to a default size, and
-sets its value to zero. If you would like to initialize a copy of an
-existing mp_int, use mp_init_copy(), where the 'from' parameter is the
-mp_int you'd like to make a copy of. The third function,
-mp_init_size(), permits you to specify how many digits of precision
-should be preallocated for your mp_int. This can help the library
-avoid unnecessary re-allocations later on.
-
-The default precision used by mp_init() can be retrieved using:
-
- precision = mp_get_prec();
-
-This returns the number of digits that will be allocated. You can
-change this value by using:
-
- mp_set_prec(unsigned int prec);
-
-Any positive value is acceptable -- if you pass zero, the default
-precision will be re-set to the compiled-in library default (this is
-specified in the header file 'mpi-config.h', and typically defaults to
-8 or 16).
-
-Just as you must allocate an mp_int before you can use it, you must
-clean up the structure when you are done with it. This is performed
-using the mp_clear() function. Remember that any mp_int that you
-create as a local variable in a function must be mp_clear()'d before
-that function exits, or else the memory allocated to that mp_int will
-be orphaned and unrecoverable.
-
-To set an mp_int to a given value, the following functions are given:
-
- mp_set(mp_int *mp, mp_digit d);
- mp_set_int(mp_int *mp, long z);
-
-The mp_set() function sets the mp_int to a single digit value, while
-mp_set_int() sets the mp_int to a signed long integer value.
-
-To set an mp_int to zero, use:
-
- mp_zero(mp_int *mp);
-
-
-Copying and Moving
-------------------
-
-If you have two initialized mp_int's, and you want to copy the value
-of one into the other, use:
-
- mp_copy(from, to)
-
-This takes care of clearing the old value of 'to', and copies the new
-value into it. If 'to' is not yet initialized, use mp_init_copy()
-instead (see above).
-
-Note: The library tries, whenever possible, to avoid allocating
----- new memory. Thus, mp_copy() tries first to satisfy the needs
- of the copy by re-using the memory already allocated to 'to'.
- Only if this proves insufficient will mp_copy() actually
- allocate new memory.
-
- For this reason, if you know a priori that 'to' has enough
- available space to hold 'from', you don't need to check the
- return value of mp_copy() for memory failure. The USED()
- macro tells you how many digits are used by an mp_int, and
- the ALLOC() macro tells you how many are allocated.
-
-If you have two initialized mp_int's, and you want to exchange their
-values, use:
-
- mp_exch(a, b)
-
-This is better than using mp_copy() with a temporary, since it will
-not (ever) touch the memory allocator -- it just swaps the exact
-contents of the two structures. The mp_exch() function cannot fail;
-if you pass it an invalid structure, it just ignores it, and does
-nothing.
-
-
-Basic Arithmetic
-----------------
-
-Once you have initialized your integers, you can operate on them. The
-basic arithmetic functions on full mp_int values are:
-
-mp_add(a, b, c) - computes c = a + b
-mp_sub(a, b, c) - computes c = a - b
-mp_mul(a, b, c) - computes c = a * b
-mp_sqr(a, b) - computes b = a * a
-mp_div(a, b, q, r) - computes q, r such that a = bq + r
-mp_div_2d(a, d, q, r) - computes q = a / 2^d, r = a % 2^d
-mp_expt(a, b, c) - computes c = a ** b
-mp_2expt(a, k) - computes a = 2^k
-mp_sqrt(a, c) - computes c = floor(sqrt(a))
-
-The mp_div_2d() function efficiently computes division by powers of
-two. Either the q or r parameter may be NULL, in which case that
-portion of the computation will be discarded.
-
-The algorithms used for some of the computations here are described in
-the following files which are included with this distribution:
-
-mul.txt Describes the multiplication algorithm
-div.txt Describes the division algorithm
-expt.txt Describes the exponentiation algorithm
-sqrt.txt Describes the square-root algorithm
-square.txt Describes the squaring algorithm
-
-There are single-digit versions of most of these routines, as well.
-In the following prototypes, 'd' is a single mp_digit:
-
-mp_add_d(a, d, c) - computes c = a + d
-mp_sub_d(a, d, c) - computes c = a - d
-mp_mul_d(a, d, c) - computes c = a * d
-mp_mul_2(a, c) - computes c = a * 2
-mp_div_d(a, d, q, r) - computes q, r such that a = bq + r
-mp_div_2(a, c) - computes c = a / 2
-mp_expt_d(a, d, c) - computes c = a ** d
-
-The mp_mul_2() and mp_div_2() functions take advantage of the internal
-representation of an mp_int to do multiplication by two more quickly
-than mp_mul_d() would. Other basic functions of an arithmetic variety
-include:
-
-mp_zero(a) - assign 0 to a
-mp_neg(a, c) - negate a: c = -a
-mp_abs(a, c) - absolute value: c = |a|
-
-
-Comparisons
------------
-
-Several comparison functions are provided. Each of these, unless
-otherwise specified, returns zero if the comparands are equal, < 0 if
-the first is less than the second, and > 0 if the first is greater
-than the second:
-
-mp_cmp_z(a) - compare a <=> 0
-mp_cmp_d(a, d) - compare a <=> d, d is a single digit
-mp_cmp(a, b) - compare a <=> b
-mp_cmp_mag(a, b) - compare |a| <=> |b|
-mp_cmp_int(a, z) - compare a <=> z, z is a signed long integer
-mp_isodd(a) - return nonzero if odd, zero otherwise
-mp_iseven(a) - return nonzero if even, zero otherwise
-
-
-Modular Arithmetic
-------------------
-
-Modular variations of the basic arithmetic functions are also
-supported. These are available if the MP_MODARITH parameter in
-mpi-config.h is turned on (it is by default). The modular arithmetic
-functions are:
-
-mp_mod(a, m, c) - compute c = a (mod m), 0 <= c < m
-mp_mod_d(a, d, c) - compute c = a (mod d), 0 <= c < d (see below)
-mp_addmod(a, b, m, c) - compute c = (a + b) mod m
-mp_submod(a, b, m, c) - compute c = (a - b) mod m
-mp_mulmod(a, b, m, c) - compute c = (a * b) mod m
-mp_sqrmod(a, m, c) - compute c = (a * a) mod m
-mp_exptmod(a, b, m, c) - compute c = (a ** b) mod m
-mp_exptmod_d(a, d, m, c)- compute c = (a ** d) mod m
-
-The mp_sqr() function squares its input argument. A call to mp_sqr(a,
-c) is identical in meaning to mp_mul(a, a, c); however, if the
-MP_SQUARE variable is set true in mpi-config.h (see below), then it
-will be implemented with a different algorithm, that is supposed to
-take advantage of the redundant computation that takes place during
-squaring. Unfortunately, some compilers result in worse performance
-on this code, so you can change the behaviour at will. There is a
-utility program "mulsqr.c" that lets you test which does better on
-your system.
-
-The mp_sqrmod() function is analogous to the mp_sqr() function; it
-uses the mp_sqr() function rather than mp_mul(), and then performs the
-modular reduction. This probably won't help much unless you are doing
-a lot of them.
-
-See the file 'square.txt' for a synopsis of the algorithm used.
-
-Note: The mp_mod_d() function computes a modular reduction around
----- a single digit d. The result is a single digit c.
-
-Because an inverse is defined for a (mod m) if and only if (a, m) = 1
-(that is, if a and m are relatively prime), mp_invmod() may not be
-able to compute an inverse for the arguments. In this case, it
-returns the value MP_UNDEF, and does not modify c. If an inverse is
-defined, however, it returns MP_OKAY, and sets c to the value of the
-inverse (mod m).
-
-See the file 'redux.txt' for a description of the modular reduction
-algorithm used by mp_exptmod().
-
-
-Greatest Common Divisor
------------------------
-
-If The greates common divisor of two values can be found using one of the
-following functions:
-
-mp_gcd(a, b, c) - compute c = (a, b) using binary algorithm
-mp_lcm(a, b, c) - compute c = [a, b] = ab / (a, b)
-mp_xgcd(a, b, g, x, y) - compute g, x, y so that ax + by = g = (a, b)
-
-Also provided is a function to compute modular inverses, if they
-exist:
-
-mp_invmod(a, m, c) - compute c = a^-1 (mod m), if it exists
-
-The function mp_xgcd() computes the greatest common divisor, and also
-returns values of x and y satisfying Bezout's identity. This is used
-by mp_invmod() to find modular inverses. However, if you do not need
-these values, you will find that mp_gcd() is MUCH more efficient,
-since it doesn't need all the intermediate values that mp_xgcd()
-requires in order to compute x and y.
-
-The mp_gcd() (and mp_xgcd()) functions use the binary (extended) GCD
-algorithm due to Josef Stein.
-
-
-Input & Output Functions
-------------------------
-
-The following basic I/O routines are provided. These are present at
-all times:
-
-mp_read_radix(mp, str, r) - convert a string in radix r to an mp_int
-mp_read_raw(mp, s, len) - convert a string of bytes to an mp_int
-mp_radix_size(mp, r) - return length of buffer needed by mp_toradix()
-mp_raw_size(mp) - return length of buffer needed by mp_toraw()
-mp_toradix(mp, str, r) - convert an mp_int to a string of radix r
- digits
-mp_toraw(mp, str) - convert an mp_int to a string of bytes
-mp_tovalue(ch, r) - convert ch to its value when taken as
- a radix r digit, or -1 if invalid
-mp_strerror(err) - get a string describing mp_err value 'err'
-
-If you compile the MPI library with MP_IOFUNC defined, you will also
-have access to the following additional I/O function:
-
-mp_print(mp, ofp) - print an mp_int as text to output stream ofp
-
-Note that mp_radix_size() returns a size in bytes guaranteed to be AT
-LEAST big enough for the digits output by mp_toradix(). Because it
-uses an approximation technique to figure out how many digits will be
-needed, it may return a figure which is larger than necessary. Thus,
-the caller should not rely on the value to determine how many bytes
-will actually be written by mp_toradix(). The string mp_toradix()
-creates will be NUL terminated, so the standard C library function
-strlen() should be able to ascertain this for you, if you need it.
-
-The mp_read_radix() and mp_toradix() functions support bases from 2 to
-64 inclusive. If you require more general radix conversion facilities
-than this, you will need to write them yourself (that's why mp_div_d()
-is provided, after all).
-
-Note: mp_read_radix() will accept as digits either capital or
----- lower-case letters. However, the current implementation of
- mp_toradix() only outputs upper-case letters, when writing
- bases betwee 10 and 36. The underlying code supports using
- lower-case letters, but the interface stub does not have a
- selector for it. You can add one yourself if you think it
- is worthwhile -- I do not. Bases from 36 to 64 use lower-
- case letters as distinct from upper-case. Bases 63 and
- 64 use the characters '+' and '/' as digits.
-
- Note also that compiling with MP_IOFUNC defined will cause
- inclusion of <stdio.h>, so if you are trying to write code
- which does not depend on the standard C library, you will
- probably want to avoid this option. This is needed because
- the mp_print() function takes a standard library FILE * as
- one of its parameters, and uses the fprintf() function.
-
-The mp_toraw() function converts the integer to a sequence of bytes,
-in big-endian ordering (most-significant byte first). Assuming your
-bytes are 8 bits wide, this corresponds to base 256. The sign is
-encoded as a single leading byte, whose value is 0 for zero or
-positive values, or 1 for negative values. The mp_read_raw() function
-reverses this process -- it takes a buffer of bytes, interprets the
-first as a sign indicator (0 = zero/positive, nonzero = negative), and
-the rest as a sequence of 1-byte digits in big-endian ordering.
-
-The mp_raw_size() function returns the exact number of bytes required
-to store the given integer in "raw" format (as described in the
-previous paragraph). Zero is returned in case of error; a valid
-integer will require at least three bytes of storage.
-
-In previous versions of the MPI library, an "external representation
-format" was supported. This was removed, however, because I found I
-was never using it, it was not as portable as I would have liked, and
-I decided it was a waste of space.
-
-
-Other Functions
----------------
-
-The files 'mpprime.h' and 'mpprime.c' define some routines which are
-useful for divisibility testing and probabilistic primality testing.
-The routines defined are:
-
-mpp_divis(a, b) - is a divisible by b?
-mpp_divis_d(a, d) - is a divisible by digit d?
-mpp_random(a) - set a to random value at current precision
-mpp_random_size(a, prec) - set a to random value at given precision
-
-Note: The mpp_random() and mpp_random_size() functions use the C
----- library's rand() function to generate random values. It is
- up to the caller to seed this generator before it is called.
- These functions are not suitable for generating quantities
- requiring cryptographic-quality randomness; they are intended
- primarily for use in primality testing.
-
- Note too that the MPI library does not call srand(), so your
- application should do this, if you ever want the sequence
- to change.
-
-mpp_divis_vector(a, v, s, w) - is a divisible by any of the s digits
- in v? If so, let w be the index of
- that digit
-
-mpp_divis_primes(a, np) - is a divisible by any of the first np
- primes? If so, set np to the prime
- which divided a.
-
-mpp_fermat(a, d) - test if w^a = w (mod a). If so,
- returns MP_YES, otherwise MP_NO.
-
-mpp_pprime(a, nt) - perform nt iterations of the Rabin-
- Miller probabilistic primality test
- on a. Returns MP_YES if all tests
- passed, or MP_NO if any test fails.
-
-The mpp_fermat() function works based on Fermat's little theorem, a
-consequence of which is that if p is a prime, and (w, p) = 1, then:
-
- w^p = w (mod p)
-
-Put another way, if w^p != w (mod p), then p is not prime. The test
-is expensive to compute, but it helps to quickly eliminate an enormous
-class of composite numbers prior to Rabin-Miller testing.
-
-Building the Library
---------------------
-
-The MPI library is designed to be as self-contained as possible. You
-should be able to compile it with your favourite ANSI C compiler, and
-link it into your program directly. If you are on a Unix system using
-the GNU C compiler (gcc), the following should work:
-
-% gcc -ansi -pedantic -Wall -O2 -c mpi.c
-
-The file 'mpi-config.h' defines several configurable parameters for
-the library, which you can adjust to suit your application. At the
-time of this writing, the available options are:
-
-MP_IOFUNC - Define true to include the mp_print() function,
- which is moderately useful for debugging. This
- implicitly includes <stdio.h>.
-
-MP_MODARITH - Define true to include the modular arithmetic
- functions. If you don't need modular arithmetic
- in your application, you can set this to zero to
- leave out all the modular routines.
-
-MP_NUMTH - Define true to include number theoretic functions
- such as mp_gcd(), mp_lcm(), and mp_invmod().
-
-MP_LOGTAB - If true, the file "logtab.h" is included, which
- is basically a static table of base 2 logarithms.
- These are used to compute how big the buffers for
- radix conversion need to be. If you set this false,
- the library includes <math.h> and uses log(). This
- typically forces you to link against math libraries.
-
-MP_MEMSET - If true, use memset() to zero buffers. If you run
- into weird alignment related bugs, set this to zero
- and an explicit loop will be used.
-
-MP_MEMCPY - If true, use memcpy() to copy buffers. If you run
- into weird alignment bugs, set this to zero and an
- explicit loop will be used.
-
-MP_CRYPTO - If true, whenever arrays of digits are free'd, they
- are zeroed first. This is useful if you're using
- the library in a cryptographic environment; however,
- it does add overhead to each free operation. For
- performance, if you don't care about zeroing your
- buffers, set this to false.
-
-MP_ARGCHK - Set to 0, 1, or 2. This defines how the argument
- checking macro, ARGCHK(), gets expanded. If this
- is set to zero, ARGCHK() expands to nothing; no
- argument checks are performed. If this is 1, the
- ARGCHK() macro expands to code that returns MP_BADARG
- or similar at runtime. If it is 2, ARGCHK() expands
- to an assert() call that aborts the program on a
- bad input.
-
-MP_DEBUG - Turns on debugging output. This is probably not at
- all useful unless you are debugging the library. It
- tends to spit out a LOT of output.
-
-MP_DEFPREC - The default precision of a newly-created mp_int, in
- digits. The precision can be changed at runtime by
- the mp_set_prec() function, but this is its initial
- value.
-
-MP_SQUARE - If this is set to a nonzero value, the mp_sqr()
- function will use an alternate algorithm that takes
- advantage of the redundant inner product computation
- when both multiplicands are identical. Unfortunately,
- with some compilers this is actually SLOWER than just
- calling mp_mul() with the same argument twice. So
- if you set MP_SQUARE to zero, mp_sqr() will be expan-
- ded into a call to mp_mul(). This applies to all
- the uses of mp_sqr(), including mp_sqrmod() and the
- internal calls to s_mp_sqr() inside mpi.c
-
- The program 'mulsqr' (mulsqr.c) can be used to test
- which works best for your configuration. Set up the
- CC and CFLAGS variables in the Makefile, then type:
-
- make mulsqr
-
- Invoke it with arguments similar to the following:
-
- mulsqr 25000 1024
-
- That is, 25000 products computed on 1024-bit values.
- The output will compare the two timings, and recommend
- a setting for MP_SQUARE. It is off by default.
-
-If you would like to use the mp_print() function (see above), be sure
-to define MP_IOFUNC in mpi-config.h. Many of the test drivers in the
-'tests' subdirectory expect this to be defined (although the test
-driver 'mpi-test' doesn't need it)
-
-The Makefile which comes with the library should take care of building
-the library for you, if you have set the CC and CFLAGS variables at
-the top of the file appropriately. By default, they are set up to
-use the GNU C compiler:
-
-CC=gcc
-CFLAGS=-ansi -pedantic -Wall -O2
-
-If all goes well, the library should compile without warnings using
-this combination. You should, of course, make whatever adjustments
-you find necessary.
-
-The MPI library distribution comes with several additional programs
-which are intended to demonstrate the use of the library, and provide
-a framework for testing it. There are a handful of test driver
-programs, in the files named 'mptest-X.c', where X is a digit. Also,
-there are some simple command-line utilities (in the 'utils'
-directory) for manipulating large numbers. These include:
-
-basecvt.c A radix-conversion program, supporting bases from
- 2 to 64 inclusive.
-
-bbsrand.c A BBS (quadratic residue) pseudo-random number
- generator. The file 'bbsrand.c' is just the driver
- for the program; the real code lives in the files
- 'bbs_rand.h' and 'bbs_rand.c'
-
-dec2hex.c Converts decimal to hexadecimal
-
-gcd.c Computes the greatest common divisor of two values.
- If invoked as 'xgcd', also computes constants x and
- y such that (a, b) = ax + by, in accordance with
- Bezout's identity.
-
-hex2dec.c Converts hexadecimal to decimal
-
-invmod.c Computes modular inverses
-
-isprime.c Performs the Rabin-Miller probabilistic primality
- test on a number. Values which fail this test are
- definitely composite, and those which pass are very
- likely to be prime (although there are no guarantees)
-
-lap.c Computes the order (least annihilating power) of
- a value v modulo m. Very dumb algorithm.
-
-primegen.c Generates large (probable) primes.
-
-prng.c A pseudo-random number generator based on the
- BBS generator code in 'bbs_rand.c'
-
-sieve.c Implements the Sieve of Eratosthenes, using a big
- bitmap, to generate a list of prime numbers.
-
-fact.c Computes the factorial of an arbitrary precision
- integer (iterative).
-
-exptmod.c Computes arbitrary precision modular exponentiation
- from the command line (exptmod a b m -> a^b (mod m))
-
-Most of these can be built from the Makefile that comes with the
-library. Try 'make tools', if your environment supports it.
-
-
-Testing the Library
--------------------
-
-Automatic test vectors are included, in the form of a program called
-'mpi-test'. To build this program and run all the tests, simply
-invoke the shell script 'all-tests'. If all the tests pass, you
-should see a message:
-
- All tests passed
-
-If something went wrong, you'll get:
-
- One or more tests failed.
-
-If this happens, scan back through the preceding lines, to see which
-test failed. Any failure indicates a bug in the library, which needs
-to be fixed before it will give accurate results. If you get any such
-thing, please let me know, and I'll try to fix it. Please let me know
-what platform and compiler you were using, as well as which test
-failed. If a reason for failure was given, please send me that text
-as well.
-
-If you're on a system where the standard Unix build tools don't work,
-you can build the 'mpi-test' program manually, and run it by hand.
-This is tedious and obnoxious, sorry.
-
-Further manual testing can be performed by building the manual testing
-programs, whose source is found in the 'tests' subdirectory. Each
-test is in a source file called 'mptest-X.c'. The Makefile contains a
-target to build all of them at once:
-
- make tests
-
-Read the comments at the top of each source file to see what the
-driver is supposed to test. You probably don't need to do this; these
-programs were only written to help me as I was developing the library.
-
-The relevant files are:
-
-mpi-test.c The source for the test driver
-
-make-test-arrays A Perl script to generate some of the internal
- data structures used by mpi-test.c
-
-test-arrays.txt The source file for make-test-arrays
-
-all-tests A Bourne shell script which runs all the
- tests in the mpi-test suite
-
-Running 'make mpi-test' should build the mpi-test program. If you
-cannot use make, here is what needs to be done:
-
-(1) Use 'make-test-arrays' to generate the file 'test-info.c' from
- the 'test-arrays.txt' file. Since Perl can be found everywhere,
- this should be no trouble. Under Unix, this looks like:
-
- make-test-arrays test-arrays.txt > test-info.c
-
-(2) Build the MPI library:
-
- gcc -ansi -pedantic -Wall -c mpi.c
-
-(3) Build the mpi-test program:
-
- gcc -ansi -pedantic -Wall -o mpi-test mpi.o mpi-test.c
-
-When you've got mpi-test, you can use 'all-tests' to run all the tests
-made available by mpi-test. If any of them fail, there should be a
-diagnostic indicating what went wrong. These are fairly high-level
-diagnostics, and won't really help you debug the problem; they're
-simply intended to help you isolate which function caused the problem.
-If you encounter a problem of this sort, feel free to e-mail me, and I
-will certainly attempt to help you debug it.
-
-Note: Several of the tests hard-wired into 'mpi-test' operate under
----- the assumption that you are using at least a 16-bit mp_digit
- type. If that is not true, several tests might fail, because
- of range problems with the maximum digit value.
-
- If you are using an 8-bit digit, you will also need to
- modify the code for mp_read_raw(), which assumes that
- multiplication by 256 can be done with mp_mul_d(), a
- fact that fails when DIGIT_MAX is 255. You can replace
- the call with s_mp_lshd(), which will give you the same
- effect, and without doing as much work. :)
-
-Acknowledgements:
-----------------
-
-The algorithms used in this library were drawn primarily from Volume
-2 of Donald Knuth's magnum opus, _The Art of Computer Programming_,
-"Semi-Numerical Methods". Barrett's algorithm for modular reduction
-came from Menezes, Oorschot, and Vanstone's _Handbook of Applied
-Cryptography_, Chapter 14.
-
-Thanks are due to Tom St. Denis, for finding an obnoxious sign-related
-bug in mp_read_raw() that made things break on platforms which use
-signed chars.
-
-About the Author
-----------------
-
-This software was written by Michael J. Fromberger. You can contact
-the author as follows:
-
-E-mail: <sting@linguist.dartmouth.edu>
-
-Postal: 8000 Cummings Hall, Thayer School of Engineering
- Dartmouth College, Hanover, New Hampshire, USA
-
-PGP key: http://linguist.dartmouth.edu/~sting/keys/mjf.html
- 9736 188B 5AFA 23D6 D6AA BE0D 5856 4525 289D 9907
-
-Last updated: 16-Jan-2000
diff --git a/security/nss/lib/freebl/mpi/all-tests b/security/nss/lib/freebl/mpi/all-tests
deleted file mode 100755
index 3429a15c0..000000000
--- a/security/nss/lib/freebl/mpi/all-tests
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/bin/sh
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-ECHO=/bin/echo
-MAKE=gmake
-
-$ECHO "\n** Running unit tests for MPI library\n"
-
-# Build the mpi-test program, which comprises all the unit tests for
-# the MPI library...
-
-$ECHO "Bringing mpi-test up to date ... "
-if $MAKE mpi-test ; then
- :
-else
- $ECHO " "
- $ECHO "Make failed to build mpi-test."
- $ECHO " "
- exit 1
-fi
-
-if [ ! -x mpi-test ] ; then
- $ECHO " "
- $ECHO "Cannot find 'mpi-test' program, testing cannot continue."
- $ECHO " "
- exit 1
-fi
-
-# Get the list of available test suites...
-tests=`./mpi-test list | awk '{print $1}'`
-errs=0
-
-# Run each test suite and check the result code of mpi-test
-for test in $tests ; do
- $ECHO "$test ... \c"
- if ./mpi-test $test ; then
- $ECHO "passed"
- else
- $ECHO "FAILED"
- errs=1
- fi
-done
-
-# If any tests failed, we'll stop at this point
-if [ "$errs" = "0" ] ; then
- $ECHO "All unit tests passed"
-else
- $ECHO "One or more tests failed"
- exit 1
-fi
-
-# Now try to build the 'pi' program, and see if it can compute the
-# first thousand digits of pi correctly
-$ECHO "\n** Running other tests\n"
-
-$ECHO "Bringing 'pi' up to date ... "
-if $MAKE pi ; then
- :
-else
- $ECHO "\nMake failed to build pi.\n"
- exit 1
-fi
-
-if [ ! -x pi ] ; then
- $ECHO "\nCannot find 'pi' program; testing cannot continue.\n"
- exit 1
-fi
-
-./pi 2000 > /tmp/pi.tmp.$$
-if cmp tests/pi2k.txt /tmp/pi.tmp.$$ ; then
- $ECHO "Okay! The pi test passes."
-else
- $ECHO "Oops! The pi test failed. :("
- exit 1
-fi
-
-rm -f /tmp/pi.tmp.$$
-
-exit 0
-
-# Here there be dragons
diff --git a/security/nss/lib/freebl/mpi/doc/LICENSE b/security/nss/lib/freebl/mpi/doc/LICENSE
deleted file mode 100644
index 35cca68ce..000000000
--- a/security/nss/lib/freebl/mpi/doc/LICENSE
+++ /dev/null
@@ -1,11 +0,0 @@
-Within this directory, each of the file listed below is licensed under
-the terms given in the file LICENSE-MPL, also in this directory.
-
-basecvt.pod
-gcd.pod
-invmod.pod
-isprime.pod
-lap.pod
-mpi-test.pod
-prime.txt
-prng.pod
diff --git a/security/nss/lib/freebl/mpi/doc/LICENSE-MPL b/security/nss/lib/freebl/mpi/doc/LICENSE-MPL
deleted file mode 100644
index d1f78f522..000000000
--- a/security/nss/lib/freebl/mpi/doc/LICENSE-MPL
+++ /dev/null
@@ -1,35 +0,0 @@
-***** BEGIN LICENSE BLOCK *****
-Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
-The contents of this file are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-The Original Code is the Netscape security libraries.
-
-The Initial Developer of the Original Code is Netscape
-Communications Corporation. Portions created by Netscape are
-Copyright (C) 1994-2000 Netscape Communications Corporation. All
-Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of this file only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of this file under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of this file under
-the terms of any one of the MPL, the GPL or the LGPL.
-
-***** END LICENSE BLOCK *****
diff --git a/security/nss/lib/freebl/mpi/doc/basecvt.pod b/security/nss/lib/freebl/mpi/doc/basecvt.pod
deleted file mode 100644
index b5bd15a51..000000000
--- a/security/nss/lib/freebl/mpi/doc/basecvt.pod
+++ /dev/null
@@ -1,67 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-=head1 NAME
-
- basecvt - radix conversion for arbitrary precision integers
-
-=head1 SYNOPSIS
-
- basecvt <ibase> <obase> [values]
-
-=head1 DESCRIPTION
-
-The B<basecvt> program is a command-line tool for converting integers
-of arbitrary precision from one radix to another. The current version
-supports radix values from 2 (binary) to 64, inclusive. The first two
-command line arguments specify the input and output radix, in base 10.
-Any further arguments are taken to be integers notated in the input
-radix, and these are converted to the output radix. The output is
-written, one integer per line, to standard output.
-
-When reading integers, only digits considered "valid" for the input
-radix are considered. Processing of an integer terminates when an
-invalid input digit is encountered. So, for example, if you set the
-input radix to 10 and enter '10ACF', B<basecvt> would assume that you
-had entered '10' and ignore the rest of the string.
-
-If no values are provided, no output is written, but the program
-simply terminates with a zero exit status. Error diagnostics are
-written to standard error in the event of out-of-range radix
-specifications. Regardless of the actual values of the input and
-output radix, the radix arguments are taken to be in base 10 (decimal)
-notation.
-
-=head1 DIGITS
-
-For radices from 2-10, standard ASCII decimal digits 0-9 are used for
-both input and output. For radices from 11-36, the ASCII letters A-Z
-are also included, following the convention used in hexadecimal. In
-this range, input is accepted in either upper or lower case, although
-on output only lower-case letters are used.
-
-For radices from 37-62, the output includes both upper- and lower-case
-ASCII letters, and case matters. In this range, case is distinguished
-both for input and for output values.
-
-For radices 63 and 64, the characters '+' (plus) and '/' (forward
-solidus) are also used. These are derived from the MIME base64
-encoding scheme. The overall encoding is not the same as base64,
-because the ASCII digits are used for the bottom of the range, and the
-letters are shifted upward; however, the output will consist of the
-same character set.
-
-This input and output behaviour is inherited from the MPI library used
-by B<basecvt>, and so is not configurable at runtime.
-
-=head1 SEE ALSO
-
- dec2hex(1), hex2dec(1)
-
-=head1 AUTHOR
-
- Michael J. Fromberger <sting@linguist.dartmouth.edu>
- Thayer School of Engineering, Hanover, New Hampshire, USA
-
- $Date$
diff --git a/security/nss/lib/freebl/mpi/doc/build b/security/nss/lib/freebl/mpi/doc/build
deleted file mode 100755
index 2de8cb0c5..000000000
--- a/security/nss/lib/freebl/mpi/doc/build
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-#
-
-VERS="1.7p6"
-SECT="1"
-NAME="MPI Tools"
-
-echo "Building manual pages ..."
-case $# in
- 0)
- files=`ls *.pod`
- ;;
- *)
- files=$*
- ;;
-esac
-
-for name in $files
-do
- echo -n "$name ... "
-# sname=`noext $name`
- sname=`basename $name .pod`
- pod2man --section="$SECT" --center="$NAME" --release="$VERS" $name > $sname.$SECT
- echo "(done)"
-done
-
-echo "Finished building."
-
diff --git a/security/nss/lib/freebl/mpi/doc/div.txt b/security/nss/lib/freebl/mpi/doc/div.txt
deleted file mode 100644
index d8c365fdf..000000000
--- a/security/nss/lib/freebl/mpi/doc/div.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-Division
-
-This describes the division algorithm used by the MPI library.
-
-Input: a, b; a > b
-Compute: Q, R; a = Qb + R
-
-The input numbers are normalized so that the high-order digit of b is
-at least half the radix. This guarantees that we have a reasonable
-way to guess at the digits of the quotient (this method was taken from
-Knuth, vol. 2, with adaptations).
-
-To normalize, test the high-order digit of b. If it is less than half
-the radix, multiply both a and b by d, where:
-
- radix - 1
- d = -----------
- bmax + 1
-
-...where bmax is the high-order digit of b. Otherwise, set d = 1.
-
-Given normalize values for a and b, let the notation a[n] denote the
-nth digit of a. Let #a be the number of significant figures of a (not
-including any leading zeroes).
-
- Let R = 0
- Let p = #a - 1
-
- while(p >= 0)
- do
- R = (R * radix) + a[p]
- p = p - 1
- while(R < b and p >= 0)
-
- if(R < b)
- break
-
- q = (R[#R - 1] * radix) + R[#R - 2]
- q = q / b[#b - 1]
-
- T = b * q
-
- while(T > L)
- q = q - 1
- T = T - b
- endwhile
-
- L = L - T
-
- Q = (Q * radix) + q
-
- endwhile
-
-At this point, Q is the quotient, and R is the normalized remainder.
-To denormalize R, compute:
-
- R = (R / d)
-
-At this point, you are finished.
-
-------------------------------------------------------------------
- This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-$Id$
-
-
diff --git a/security/nss/lib/freebl/mpi/doc/expt.txt b/security/nss/lib/freebl/mpi/doc/expt.txt
deleted file mode 100644
index f5b0ac04a..000000000
--- a/security/nss/lib/freebl/mpi/doc/expt.txt
+++ /dev/null
@@ -1,99 +0,0 @@
-Exponentiation
-
-For exponentiation, the MPI library uses a simple and fairly standard
-square-and-multiply method. The algorithm is this:
-
-Input: a, b
-Output: a ** b
-
- s = 1
-
- while(b != 0)
- if(b is odd)
- s = s * a
- endif
-
- b = b / 2
-
- x = x * x
- endwhile
-
- return s
-
-The modular exponentiation is done the same way, except replacing:
-
- s = s * a
-
-with
- s = (s * a) mod m
-
-and replacing
-
- x = x * x
-
-with
-
- x = (x * x) mod m
-
-Here is a sample exponentiation using the MPI library, as compared to
-the same problem solved by the Unix 'bc' program on my system:
-
-Computation of 2,381,283 ** 235
-
-'bc' says:
-
-4385CA4A804D199FBEAD95FAD0796FAD0D0B51FC9C16743C45568C789666985DB719\
-4D90E393522F74C9601262C0514145A49F3B53D00983F95FDFCEA3D0043ECEF6227E\
-6FB59C924C3EE74447B359B5BF12A555D46CB819809EF423F004B55C587D6F0E8A55\
-4988036A42ACEF9F71459F97CEF6E574BD7373657111648626B1FF8EE15F663B2C0E\
-6BBE5082D4CDE8E14F263635AE8F35DB2C280819517BE388B5573B84C5A19C871685\
-FD408A6471F9D6AFAF5129A7548EAE926B40874B340285F44765BF5468CE20A13267\
-CD88CE6BC786ACED36EC7EA50F67FF27622575319068A332C3C0CB23E26FB55E26F4\
-5F732753A52B8E2FB4D4F42D894242613CA912A25486C3DEC9C66E5DB6182F6C1761\
-CF8CD0D255BE64B93836B27D452AE38F950EB98B517D4CF50D48F0165EF0CCCE1F5C\
-49BF18219FDBA0EEDD1A7E8B187B70C2BAED5EC5C6821EF27FAFB1CFF70111C52235\
-5E948B93A015AA1AE152B110BB5658CB14D3E45A48BFE7F082C1182672A455A695CD\
-A1855E8781E625F25B41B516E77F589FA420C3B058861EA138CF7A2C58DB3C7504FD\
-D29554D78237834CC5AE710D403CC4F6973D5012B7E117A8976B14A0B5AFA889BD47\
-92C461F0F96116F00A97AE9E83DC5203680CAF9A18A062566C145650AB86BE4F907F\
-A9F7AB4A700B29E1E5BACCD6DCBFA513E10832815F710807EED2E279081FEC61D619\
-AB270BEB3D3A1787B35A9DD41A8766CF21F3B5C693B3BAB1C2FA14A4ED202BC35743\
-E5CBE2391624D4F8C9BFBBC78D69764E7C6C5B11BF005677BFAD17D9278FFC1F158F\
-1B3683FF7960FA0608103792C4163DC0AF3E06287BB8624F8FE3A0FFBDF82ACECA2F\
-CFFF2E1AC93F3CA264A1B
-
-MPI says:
-
-4385CA4A804D199FBEAD95FAD0796FAD0D0B51FC9C16743C45568C789666985DB719\
-4D90E393522F74C9601262C0514145A49F3B53D00983F95FDFCEA3D0043ECEF6227E\
-6FB59C924C3EE74447B359B5BF12A555D46CB819809EF423F004B55C587D6F0E8A55\
-4988036A42ACEF9F71459F97CEF6E574BD7373657111648626B1FF8EE15F663B2C0E\
-6BBE5082D4CDE8E14F263635AE8F35DB2C280819517BE388B5573B84C5A19C871685\
-FD408A6471F9D6AFAF5129A7548EAE926B40874B340285F44765BF5468CE20A13267\
-CD88CE6BC786ACED36EC7EA50F67FF27622575319068A332C3C0CB23E26FB55E26F4\
-5F732753A52B8E2FB4D4F42D894242613CA912A25486C3DEC9C66E5DB6182F6C1761\
-CF8CD0D255BE64B93836B27D452AE38F950EB98B517D4CF50D48F0165EF0CCCE1F5C\
-49BF18219FDBA0EEDD1A7E8B187B70C2BAED5EC5C6821EF27FAFB1CFF70111C52235\
-5E948B93A015AA1AE152B110BB5658CB14D3E45A48BFE7F082C1182672A455A695CD\
-A1855E8781E625F25B41B516E77F589FA420C3B058861EA138CF7A2C58DB3C7504FD\
-D29554D78237834CC5AE710D403CC4F6973D5012B7E117A8976B14A0B5AFA889BD47\
-92C461F0F96116F00A97AE9E83DC5203680CAF9A18A062566C145650AB86BE4F907F\
-A9F7AB4A700B29E1E5BACCD6DCBFA513E10832815F710807EED2E279081FEC61D619\
-AB270BEB3D3A1787B35A9DD41A8766CF21F3B5C693B3BAB1C2FA14A4ED202BC35743\
-E5CBE2391624D4F8C9BFBBC78D69764E7C6C5B11BF005677BFAD17D9278FFC1F158F\
-1B3683FF7960FA0608103792C4163DC0AF3E06287BB8624F8FE3A0FFBDF82ACECA2F\
-CFFF2E1AC93F3CA264A1B
-
-Diff says:
-% diff bc.txt mp.txt
-%
-
-------------------------------------------------------------------
- This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-$Id$
-
-
-
diff --git a/security/nss/lib/freebl/mpi/doc/gcd.pod b/security/nss/lib/freebl/mpi/doc/gcd.pod
deleted file mode 100644
index df5a8da80..000000000
--- a/security/nss/lib/freebl/mpi/doc/gcd.pod
+++ /dev/null
@@ -1,31 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-=head1 NAME
-
- gcd - compute greatest common divisor of two integers
-
-=head1 SYNOPSIS
-
- gcd <a> <b>
-
-=head1 DESCRIPTION
-
-The B<gcd> program computes the greatest common divisor of two
-arbitrary-precision integers I<a> and I<b>. The result is written in
-standard decimal notation to the standard output.
-
-If I<b> is zero, B<gcd> will print an error message and exit.
-
-=head1 SEE ALSO
-
-invmod(1), isprime(1), lap(1)
-
-=head1 AUTHOR
-
- Michael J. Fromberger <sting@linguist.dartmouth.edu>
- Thayer School of Engineering, Hanover, New Hampshire, USA
-
- $Date$
-
diff --git a/security/nss/lib/freebl/mpi/doc/invmod.pod b/security/nss/lib/freebl/mpi/doc/invmod.pod
deleted file mode 100644
index d23b8f7bc..000000000
--- a/security/nss/lib/freebl/mpi/doc/invmod.pod
+++ /dev/null
@@ -1,37 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-=head1 NAME
-
- invmod - compute modular inverse of an integer
-
-=head1 SYNOPSIS
-
- invmod <a> <m>
-
-=head1 DESCRIPTION
-
-The B<invmod> program computes the inverse of I<a>, modulo I<m>, if
-that inverse exists. Both I<a> and I<m> are arbitrary-precision
-integers in decimal notation. The result is written in standard
-decimal notation to the standard output.
-
-If there is no inverse, the message:
-
- No inverse
-
-...will be printed to the standard output (an inverse exists if and
-only if the greatest common divisor of I<a> and I<m> is 1).
-
-=head1 SEE ALSO
-
-gcd(1), isprime(1), lap(1)
-
-=head1 AUTHOR
-
- Michael J. Fromberger <sting@linguist.dartmouth.edu>
- Thayer School of Engineering, Hanover, New Hampshire, USA
-
- $Date$
-
diff --git a/security/nss/lib/freebl/mpi/doc/isprime.pod b/security/nss/lib/freebl/mpi/doc/isprime.pod
deleted file mode 100644
index 6eae31d89..000000000
--- a/security/nss/lib/freebl/mpi/doc/isprime.pod
+++ /dev/null
@@ -1,66 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-=head1 NAME
-
- isprime - probabilistic primality testing
-
-=head1 SYNOPSIS
-
- isprime <a>
-
-=head1 DESCRIPTION
-
-The B<isprime> program attempts to determine whether the arbitrary
-precision integer I<a> is prime. It first tests I<a> for divisibility
-by the first 170 or so small primes, and assuming I<a> is not
-divisible by any of these, applies 15 iterations of the Rabin-Miller
-probabilistic primality test.
-
-If the program discovers that the number is composite, it will print:
-
- Not prime (reason)
-
-Where I<reason> is either:
-
- divisible by small prime x
-
-Or:
-
- failed nth pseudoprime test
-
-In the first case, I<x> indicates the first small prime factor that
-was found. In the second case, I<n> indicates which of the
-pseudoprime tests failed (numbered from 1)
-
-If this happens, the number is definitely not prime. However, if the
-number succeeds, this message results:
-
- Probably prime, 1 in 4^15 chance of false positive
-
-If this happens, the number is prime with very high probability, but
-its primality has not been absolutely proven, only demonstrated to a
-very convincing degree.
-
-The value I<a> can be input in standard decimal notation, or, if it is
-prefixed with I<Ox>, it will be read as hexadecimal.
-
-=head1 ENVIRONMENT
-
-You can control how many iterations of Rabin-Miller are performed on
-the candidate number by setting the I<RM_TESTS> environment variable
-to an integer value before starting up B<isprime>. This will change
-the output slightly if the number passes all the tests.
-
-=head1 SEE ALSO
-
-gcd(1), invmod(1), lap(1)
-
-=head1 AUTHOR
-
- Michael J. Fromberger <sting@linguist.dartmouth.edu>
- Thayer School of Engineering, Hanover, New Hampshire, USA
-
- $Date$
-
diff --git a/security/nss/lib/freebl/mpi/doc/lap.pod b/security/nss/lib/freebl/mpi/doc/lap.pod
deleted file mode 100644
index c38c4abe0..000000000
--- a/security/nss/lib/freebl/mpi/doc/lap.pod
+++ /dev/null
@@ -1,39 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-=head1 NAME
-
- lap - compute least annihilating power of a number
-
-=head1 SYNOPSIS
-
- lap <a> <m>
-
-=head1 DESCRIPTION
-
-The B<lap> program computes the order of I<a> modulo I<m>, for
-arbitrary precision integers I<a> and I<m>. The B<order> of I<a>
-modulo I<m> is defined as the smallest positive value I<n> for which
-I<a> raised to the I<n>th power, modulo I<m>, is equal to 1. The
-order may not exist, if I<m> is composite.
-
-=head1 RESTRICTIONS
-
-This program is very slow, especially for large moduli. It is
-intended as a way to help find primitive elements in a modular field,
-but it does not do so in a particularly inefficient manner. It was
-written simply to help verify that a particular candidate does not
-have an obviously short cycle mod I<m>.
-
-=head1 SEE ALSO
-
-gcd(1), invmod(1), isprime(1)
-
-=head1 AUTHOR
-
- Michael J. Fromberger <sting@linguist.dartmouth.edu>
- Thayer School of Engineering, Hanover, New Hampshire, USA
-
- $Date$
-
diff --git a/security/nss/lib/freebl/mpi/doc/mpi-test.pod b/security/nss/lib/freebl/mpi/doc/mpi-test.pod
deleted file mode 100644
index e9c9d3e5e..000000000
--- a/security/nss/lib/freebl/mpi/doc/mpi-test.pod
+++ /dev/null
@@ -1,53 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-=head1 NAME
-
- mpi-test - automated test program for MPI library
-
-=head1 SYNOPSIS
-
- mpi-test <suite-name> [quiet]
- mpi-test list
- mpi-test help
-
-=head1 DESCRIPTION
-
-The B<mpi-test> program is a general unit test driver for the MPI
-library. It is used to verify that the library works as it is
-supposed to on your architecture. As with most such things, passing
-all the tests in B<mpi-test> does not guarantee the code is correct,
-but if any of them fail, there are certainly problems.
-
-Each major function of the library can be tested individually. For a
-list of the test suites understood by B<mpi-test>, run it with the
-I<list> command line option:
-
- mpi-test list
-
-This will display a list of the available test suites and a brief
-synopsis of what each one does. For a brief overview of this
-document, run B<mpi-test> I<help>.
-
-B<mpi-test> exits with a zero status if the selected test succeeds, or
-a nonzero status if it fails. If a I<suite-name> which is not
-understood by B<mpi-test> is given, a diagnostic is printed to the
-standard error, and the program exits with a result code of 2. If a
-test fails, the result code will be 1, and a diagnostic is ordinarily
-printed to the standard error. However, if the I<quiet> option is
-provided, these diagnostics will be suppressed.
-
-=head1 RESTRICTIONS
-
-Only a few canned test cases are provided. The solutions have been
-verified using the GNU bc(1) program, so bugs there may cause problems
-here; however, this is very unlikely, so if a test fails, it is almost
-certainly my fault, not bc(1)'s.
-
-=head1 AUTHOR
-
- Michael J. Fromberger <sting@linguist.dartmouth.edu>
- Thayer School of Engineering, Hanover, New Hampshire, USA
-
- $Date$
diff --git a/security/nss/lib/freebl/mpi/doc/mul.txt b/security/nss/lib/freebl/mpi/doc/mul.txt
deleted file mode 100644
index 1543f935b..000000000
--- a/security/nss/lib/freebl/mpi/doc/mul.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-Multiplication
-
-This describes the multiplication algorithm used by the MPI library.
-
-This is basically a standard "schoolbook" algorithm. It is slow --
-O(mn) for m = #a, n = #b -- but easy to implement and verify.
-Basically, we run two nested loops, as illustrated here (R is the
-radix):
-
-k = 0
-for j <- 0 to (#b - 1)
- for i <- 0 to (#a - 1)
- w = (a[j] * b[i]) + k + c[i+j]
- c[i+j] = w mod R
- k = w div R
- endfor
- c[i+j] = k;
- k = 0;
-endfor
-
-It is necessary that 'w' have room for at least two radix R digits.
-The product of any two digits in radix R is at most:
-
- (R - 1)(R - 1) = R^2 - 2R + 1
-
-Since a two-digit radix-R number can hold R^2 - 1 distinct values,
-this insures that the product will fit into the two-digit register.
-
-To insure that two digits is enough for w, we must also show that
-there is room for the carry-in from the previous multiplication, and
-the current value of the product digit that is being recomputed.
-Assuming each of these may be as big as R - 1 (and no larger,
-certainly), two digits will be enough if and only if:
-
- (R^2 - 2R + 1) + 2(R - 1) <= R^2 - 1
-
-Solving this equation shows that, indeed, this is the case:
-
- R^2 - 2R + 1 + 2R - 2 <= R^2 - 1
-
- R^2 - 1 <= R^2 - 1
-
-This suggests that a good radix would be one more than the largest
-value that can be held in half a machine word -- so, for example, as
-in this implementation, where we used a radix of 65536 on a machine
-with 4-byte words. Another advantage of a radix of this sort is that
-binary-level operations are easy on numbers in this representation.
-
-Here's an example multiplication worked out longhand in radix-10,
-using the above algorithm:
-
- a = 999
- b = x 999
- -------------
- p = 98001
-
-w = (a[jx] * b[ix]) + kin + c[ix + jx]
-c[ix+jx] = w % RADIX
-k = w / RADIX
- product
-ix jx a[jx] b[ix] kin w c[i+j] kout 000000
-0 0 9 9 0 81+0+0 1 8 000001
-0 1 9 9 8 81+8+0 9 8 000091
-0 2 9 9 8 81+8+0 9 8 000991
- 8 0 008991
-1 0 9 9 0 81+0+9 0 9 008901
-1 1 9 9 9 81+9+9 9 9 008901
-1 2 9 9 9 81+9+8 8 9 008901
- 9 0 098901
-2 0 9 9 0 81+0+9 0 9 098001
-2 1 9 9 9 81+9+8 8 9 098001
-2 2 9 9 9 81+9+9 9 9 098001
-
-------------------------------------------------------------------
- This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-$Id$
-
-
diff --git a/security/nss/lib/freebl/mpi/doc/pi.txt b/security/nss/lib/freebl/mpi/doc/pi.txt
deleted file mode 100644
index a96cd09e1..000000000
--- a/security/nss/lib/freebl/mpi/doc/pi.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-This file describes how pi is computed by the program in 'pi.c' (see
-the utils subdirectory).
-
-Basically, we use Machin's formula, which is what everyone in the
-world uses as a simple method for computing approximations to pi.
-This works for up to a few thousand digits without too much effort.
-Beyond that, though, it gets too slow.
-
-Machin's formula states:
-
- pi := 16 * arctan(1/5) - 4 * arctan(1/239)
-
-We compute this in integer arithmetic by first multiplying everything
-through by 10^d, where 'd' is the number of digits of pi we wanted to
-compute. It turns out, the last few digits will be wrong, but the
-number that are wrong is usually very small (ordinarly only 2-3).
-Having done this, we compute the arctan() function using the formula:
-
- 1 1 1 1 1
- arctan(1/x) := --- - ----- + ----- - ----- + ----- - ...
- x 3 x^3 5 x^5 7 x^7 9 x^9
-
-This is done iteratively by computing the first term manually, and
-then iteratively dividing x^2 and k, where k = 3, 5, 7, ... out of the
-current figure. This is then added to (or subtracted from) a running
-sum, as appropriate. The iteration continues until we overflow our
-available precision and the current figure goes to zero under integer
-division. At that point, we're finished.
-
-Actually, we get a couple extra bits of precision out of the fact that
-we know we're computing y * arctan(1/x), by setting up the multiplier
-as:
-
- y * 10^d
-
-... instead of just 10^d. There is also a bit of cleverness in how
-the loop is constructed, to avoid special-casing the first term.
-Check out the code for arctan() in 'pi.c', if you are interested in
-seeing how it is set up.
-
-Thanks to Jason P. for this algorithm, which I assembled from notes
-and programs found on his cool "Pile of Pi Programs" page, at:
-
- http://www.isr.umd.edu/~jasonp/pipage.html
-
-Thanks also to Henrik Johansson <Henrik.Johansson@Nexus.Comm.SE>, from
-whose pi program I borrowed the clever idea of pre-multiplying by x in
-order to avoid a special case on the loop iteration.
-
-------------------------------------------------------------------
- This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-$Id$
-
-
diff --git a/security/nss/lib/freebl/mpi/doc/prime.txt b/security/nss/lib/freebl/mpi/doc/prime.txt
deleted file mode 100644
index 694797d5f..000000000
--- a/security/nss/lib/freebl/mpi/doc/prime.txt
+++ /dev/null
@@ -1,6542 +0,0 @@
-2
-3
-5
-7
-11
-13
-17
-19
-23
-29
-31
-37
-41
-43
-47
-53
-59
-61
-67
-71
-73
-79
-83
-89
-97
-101
-103
-107
-109
-113
-127
-131
-137
-139
-149
-151
-157
-163
-167
-173
-179
-181
-191
-193
-197
-199
-211
-223
-227
-229
-233
-239
-241
-251
-257
-263
-269
-271
-277
-281
-283
-293
-307
-311
-313
-317
-331
-337
-347
-349
-353
-359
-367
-373
-379
-383
-389
-397
-401
-409
-419
-421
-431
-433
-439
-443
-449
-457
-461
-463
-467
-479
-487
-491
-499
-503
-509
-521
-523
-541
-547
-557
-563
-569
-571
-577
-587
-593
-599
-601
-607
-613
-617
-619
-631
-641
-643
-647
-653
-659
-661
-673
-677
-683
-691
-701
-709
-719
-727
-733
-739
-743
-751
-757
-761
-769
-773
-787
-797
-809
-811
-821
-823
-827
-829
-839
-853
-857
-859
-863
-877
-881
-883
-887
-907
-911
-919
-929
-937
-941
-947
-953
-967
-971
-977
-983
-991
-997
-1009
-1013
-1019
-1021
-1031
-1033
-1039
-1049
-1051
-1061
-1063
-1069
-1087
-1091
-1093
-1097
-1103
-1109
-1117
-1123
-1129
-1151
-1153
-1163
-1171
-1181
-1187
-1193
-1201
-1213
-1217
-1223
-1229
-1231
-1237
-1249
-1259
-1277
-1279
-1283
-1289
-1291
-1297
-1301
-1303
-1307
-1319
-1321
-1327
-1361
-1367
-1373
-1381
-1399
-1409
-1423
-1427
-1429
-1433
-1439
-1447
-1451
-1453
-1459
-1471
-1481
-1483
-1487
-1489
-1493
-1499
-1511
-1523
-1531
-1543
-1549
-1553
-1559
-1567
-1571
-1579
-1583
-1597
-1601
-1607
-1609
-1613
-1619
-1621
-1627
-1637
-1657
-1663
-1667
-1669
-1693
-1697
-1699
-1709
-1721
-1723
-1733
-1741
-1747
-1753
-1759
-1777
-1783
-1787
-1789
-1801
-1811
-1823
-1831
-1847
-1861
-1867
-1871
-1873
-1877
-1879
-1889
-1901
-1907
-1913
-1931
-1933
-1949
-1951
-1973
-1979
-1987
-1993
-1997
-1999
-2003
-2011
-2017
-2027
-2029
-2039
-2053
-2063
-2069
-2081
-2083
-2087
-2089
-2099
-2111
-2113
-2129
-2131
-2137
-2141
-2143
-2153
-2161
-2179
-2203
-2207
-2213
-2221
-2237
-2239
-2243
-2251
-2267
-2269
-2273
-2281
-2287
-2293
-2297
-2309
-2311
-2333
-2339
-2341
-2347
-2351
-2357
-2371
-2377
-2381
-2383
-2389
-2393
-2399
-2411
-2417
-2423
-2437
-2441
-2447
-2459
-2467
-2473
-2477
-2503
-2521
-2531
-2539
-2543
-2549
-2551
-2557
-2579
-2591
-2593
-2609
-2617
-2621
-2633
-2647
-2657
-2659
-2663
-2671
-2677
-2683
-2687
-2689
-2693
-2699
-2707
-2711
-2713
-2719
-2729
-2731
-2741
-2749
-2753
-2767
-2777
-2789
-2791
-2797
-2801
-2803
-2819
-2833
-2837
-2843
-2851
-2857
-2861
-2879
-2887
-2897
-2903
-2909
-2917
-2927
-2939
-2953
-2957
-2963
-2969
-2971
-2999
-3001
-3011
-3019
-3023
-3037
-3041
-3049
-3061
-3067
-3079
-3083
-3089
-3109
-3119
-3121
-3137
-3163
-3167
-3169
-3181
-3187
-3191
-3203
-3209
-3217
-3221
-3229
-3251
-3253
-3257
-3259
-3271
-3299
-3301
-3307
-3313
-3319
-3323
-3329
-3331
-3343
-3347
-3359
-3361
-3371
-3373
-3389
-3391
-3407
-3413
-3433
-3449
-3457
-3461
-3463
-3467
-3469
-3491
-3499
-3511
-3517
-3527
-3529
-3533
-3539
-3541
-3547
-3557
-3559
-3571
-3581
-3583
-3593
-3607
-3613
-3617
-3623
-3631
-3637
-3643
-3659
-3671
-3673
-3677
-3691
-3697
-3701
-3709
-3719
-3727
-3733
-3739
-3761
-3767
-3769
-3779
-3793
-3797
-3803
-3821
-3823
-3833
-3847
-3851
-3853
-3863
-3877
-3881
-3889
-3907
-3911
-3917
-3919
-3923
-3929
-3931
-3943
-3947
-3967
-3989
-4001
-4003
-4007
-4013
-4019
-4021
-4027
-4049
-4051
-4057
-4073
-4079
-4091
-4093
-4099
-4111
-4127
-4129
-4133
-4139
-4153
-4157
-4159
-4177
-4201
-4211
-4217
-4219
-4229
-4231
-4241
-4243
-4253
-4259
-4261
-4271
-4273
-4283
-4289
-4297
-4327
-4337
-4339
-4349
-4357
-4363
-4373
-4391
-4397
-4409
-4421
-4423
-4441
-4447
-4451
-4457
-4463
-4481
-4483
-4493
-4507
-4513
-4517
-4519
-4523
-4547
-4549
-4561
-4567
-4583
-4591
-4597
-4603
-4621
-4637
-4639
-4643
-4649
-4651
-4657
-4663
-4673
-4679
-4691
-4703
-4721
-4723
-4729
-4733
-4751
-4759
-4783
-4787
-4789
-4793
-4799
-4801
-4813
-4817
-4831
-4861
-4871
-4877
-4889
-4903
-4909
-4919
-4931
-4933
-4937
-4943
-4951
-4957
-4967
-4969
-4973
-4987
-4993
-4999
-5003
-5009
-5011
-5021
-5023
-5039
-5051
-5059
-5077
-5081
-5087
-5099
-5101
-5107
-5113
-5119
-5147
-5153
-5167
-5171
-5179
-5189
-5197
-5209
-5227
-5231
-5233
-5237
-5261
-5273
-5279
-5281
-5297
-5303
-5309
-5323
-5333
-5347
-5351
-5381
-5387
-5393
-5399
-5407
-5413
-5417
-5419
-5431
-5437
-5441
-5443
-5449
-5471
-5477
-5479
-5483
-5501
-5503
-5507
-5519
-5521
-5527
-5531
-5557
-5563
-5569
-5573
-5581
-5591
-5623
-5639
-5641
-5647
-5651
-5653
-5657
-5659
-5669
-5683
-5689
-5693
-5701
-5711
-5717
-5737
-5741
-5743
-5749
-5779
-5783
-5791
-5801
-5807
-5813
-5821
-5827
-5839
-5843
-5849
-5851
-5857
-5861
-5867
-5869
-5879
-5881
-5897
-5903
-5923
-5927
-5939
-5953
-5981
-5987
-6007
-6011
-6029
-6037
-6043
-6047
-6053
-6067
-6073
-6079
-6089
-6091
-6101
-6113
-6121
-6131
-6133
-6143
-6151
-6163
-6173
-6197
-6199
-6203
-6211
-6217
-6221
-6229
-6247
-6257
-6263
-6269
-6271
-6277
-6287
-6299
-6301
-6311
-6317
-6323
-6329
-6337
-6343
-6353
-6359
-6361
-6367
-6373
-6379
-6389
-6397
-6421
-6427
-6449
-6451
-6469
-6473
-6481
-6491
-6521
-6529
-6547
-6551
-6553
-6563
-6569
-6571
-6577
-6581
-6599
-6607
-6619
-6637
-6653
-6659
-6661
-6673
-6679
-6689
-6691
-6701
-6703
-6709
-6719
-6733
-6737
-6761
-6763
-6779
-6781
-6791
-6793
-6803
-6823
-6827
-6829
-6833
-6841
-6857
-6863
-6869
-6871
-6883
-6899
-6907
-6911
-6917
-6947
-6949
-6959
-6961
-6967
-6971
-6977
-6983
-6991
-6997
-7001
-7013
-7019
-7027
-7039
-7043
-7057
-7069
-7079
-7103
-7109
-7121
-7127
-7129
-7151
-7159
-7177
-7187
-7193
-7207
-7211
-7213
-7219
-7229
-7237
-7243
-7247
-7253
-7283
-7297
-7307
-7309
-7321
-7331
-7333
-7349
-7351
-7369
-7393
-7411
-7417
-7433
-7451
-7457
-7459
-7477
-7481
-7487
-7489
-7499
-7507
-7517
-7523
-7529
-7537
-7541
-7547
-7549
-7559
-7561
-7573
-7577
-7583
-7589
-7591
-7603
-7607
-7621
-7639
-7643
-7649
-7669
-7673
-7681
-7687
-7691
-7699
-7703
-7717
-7723
-7727
-7741
-7753
-7757
-7759
-7789
-7793
-7817
-7823
-7829
-7841
-7853
-7867
-7873
-7877
-7879
-7883
-7901
-7907
-7919
-7927
-7933
-7937
-7949
-7951
-7963
-7993
-8009
-8011
-8017
-8039
-8053
-8059
-8069
-8081
-8087
-8089
-8093
-8101
-8111
-8117
-8123
-8147
-8161
-8167
-8171
-8179
-8191
-8209
-8219
-8221
-8231
-8233
-8237
-8243
-8263
-8269
-8273
-8287
-8291
-8293
-8297
-8311
-8317
-8329
-8353
-8363
-8369
-8377
-8387
-8389
-8419
-8423
-8429
-8431
-8443
-8447
-8461
-8467
-8501
-8513
-8521
-8527
-8537
-8539
-8543
-8563
-8573
-8581
-8597
-8599
-8609
-8623
-8627
-8629
-8641
-8647
-8663
-8669
-8677
-8681
-8689
-8693
-8699
-8707
-8713
-8719
-8731
-8737
-8741
-8747
-8753
-8761
-8779
-8783
-8803
-8807
-8819
-8821
-8831
-8837
-8839
-8849
-8861
-8863
-8867
-8887
-8893
-8923
-8929
-8933
-8941
-8951
-8963
-8969
-8971
-8999
-9001
-9007
-9011
-9013
-9029
-9041
-9043
-9049
-9059
-9067
-9091
-9103
-9109
-9127
-9133
-9137
-9151
-9157
-9161
-9173
-9181
-9187
-9199
-9203
-9209
-9221
-9227
-9239
-9241
-9257
-9277
-9281
-9283
-9293
-9311
-9319
-9323
-9337
-9341
-9343
-9349
-9371
-9377
-9391
-9397
-9403
-9413
-9419
-9421
-9431
-9433
-9437
-9439
-9461
-9463
-9467
-9473
-9479
-9491
-9497
-9511
-9521
-9533
-9539
-9547
-9551
-9587
-9601
-9613
-9619
-9623
-9629
-9631
-9643
-9649
-9661
-9677
-9679
-9689
-9697
-9719
-9721
-9733
-9739
-9743
-9749
-9767
-9769
-9781
-9787
-9791
-9803
-9811
-9817
-9829
-9833
-9839
-9851
-9857
-9859
-9871
-9883
-9887
-9901
-9907
-9923
-9929
-9931
-9941
-9949
-9967
-9973
-10007
-10009
-10037
-10039
-10061
-10067
-10069
-10079
-10091
-10093
-10099
-10103
-10111
-10133
-10139
-10141
-10151
-10159
-10163
-10169
-10177
-10181
-10193
-10211
-10223
-10243
-10247
-10253
-10259
-10267
-10271
-10273
-10289
-10301
-10303
-10313
-10321
-10331
-10333
-10337
-10343
-10357
-10369
-10391
-10399
-10427
-10429
-10433
-10453
-10457
-10459
-10463
-10477
-10487
-10499
-10501
-10513
-10529
-10531
-10559
-10567
-10589
-10597
-10601
-10607
-10613
-10627
-10631
-10639
-10651
-10657
-10663
-10667
-10687
-10691
-10709
-10711
-10723
-10729
-10733
-10739
-10753
-10771
-10781
-10789
-10799
-10831
-10837
-10847
-10853
-10859
-10861
-10867
-10883
-10889
-10891
-10903
-10909
-10937
-10939
-10949
-10957
-10973
-10979
-10987
-10993
-11003
-11027
-11047
-11057
-11059
-11069
-11071
-11083
-11087
-11093
-11113
-11117
-11119
-11131
-11149
-11159
-11161
-11171
-11173
-11177
-11197
-11213
-11239
-11243
-11251
-11257
-11261
-11273
-11279
-11287
-11299
-11311
-11317
-11321
-11329
-11351
-11353
-11369
-11383
-11393
-11399
-11411
-11423
-11437
-11443
-11447
-11467
-11471
-11483
-11489
-11491
-11497
-11503
-11519
-11527
-11549
-11551
-11579
-11587
-11593
-11597
-11617
-11621
-11633
-11657
-11677
-11681
-11689
-11699
-11701
-11717
-11719
-11731
-11743
-11777
-11779
-11783
-11789
-11801
-11807
-11813
-11821
-11827
-11831
-11833
-11839
-11863
-11867
-11887
-11897
-11903
-11909
-11923
-11927
-11933
-11939
-11941
-11953
-11959
-11969
-11971
-11981
-11987
-12007
-12011
-12037
-12041
-12043
-12049
-12071
-12073
-12097
-12101
-12107
-12109
-12113
-12119
-12143
-12149
-12157
-12161
-12163
-12197
-12203
-12211
-12227
-12239
-12241
-12251
-12253
-12263
-12269
-12277
-12281
-12289
-12301
-12323
-12329
-12343
-12347
-12373
-12377
-12379
-12391
-12401
-12409
-12413
-12421
-12433
-12437
-12451
-12457
-12473
-12479
-12487
-12491
-12497
-12503
-12511
-12517
-12527
-12539
-12541
-12547
-12553
-12569
-12577
-12583
-12589
-12601
-12611
-12613
-12619
-12637
-12641
-12647
-12653
-12659
-12671
-12689
-12697
-12703
-12713
-12721
-12739
-12743
-12757
-12763
-12781
-12791
-12799
-12809
-12821
-12823
-12829
-12841
-12853
-12889
-12893
-12899
-12907
-12911
-12917
-12919
-12923
-12941
-12953
-12959
-12967
-12973
-12979
-12983
-13001
-13003
-13007
-13009
-13033
-13037
-13043
-13049
-13063
-13093
-13099
-13103
-13109
-13121
-13127
-13147
-13151
-13159
-13163
-13171
-13177
-13183
-13187
-13217
-13219
-13229
-13241
-13249
-13259
-13267
-13291
-13297
-13309
-13313
-13327
-13331
-13337
-13339
-13367
-13381
-13397
-13399
-13411
-13417
-13421
-13441
-13451
-13457
-13463
-13469
-13477
-13487
-13499
-13513
-13523
-13537
-13553
-13567
-13577
-13591
-13597
-13613
-13619
-13627
-13633
-13649
-13669
-13679
-13681
-13687
-13691
-13693
-13697
-13709
-13711
-13721
-13723
-13729
-13751
-13757
-13759
-13763
-13781
-13789
-13799
-13807
-13829
-13831
-13841
-13859
-13873
-13877
-13879
-13883
-13901
-13903
-13907
-13913
-13921
-13931
-13933
-13963
-13967
-13997
-13999
-14009
-14011
-14029
-14033
-14051
-14057
-14071
-14081
-14083
-14087
-14107
-14143
-14149
-14153
-14159
-14173
-14177
-14197
-14207
-14221
-14243
-14249
-14251
-14281
-14293
-14303
-14321
-14323
-14327
-14341
-14347
-14369
-14387
-14389
-14401
-14407
-14411
-14419
-14423
-14431
-14437
-14447
-14449
-14461
-14479
-14489
-14503
-14519
-14533
-14537
-14543
-14549
-14551
-14557
-14561
-14563
-14591
-14593
-14621
-14627
-14629
-14633
-14639
-14653
-14657
-14669
-14683
-14699
-14713
-14717
-14723
-14731
-14737
-14741
-14747
-14753
-14759
-14767
-14771
-14779
-14783
-14797
-14813
-14821
-14827
-14831
-14843
-14851
-14867
-14869
-14879
-14887
-14891
-14897
-14923
-14929
-14939
-14947
-14951
-14957
-14969
-14983
-15013
-15017
-15031
-15053
-15061
-15073
-15077
-15083
-15091
-15101
-15107
-15121
-15131
-15137
-15139
-15149
-15161
-15173
-15187
-15193
-15199
-15217
-15227
-15233
-15241
-15259
-15263
-15269
-15271
-15277
-15287
-15289
-15299
-15307
-15313
-15319
-15329
-15331
-15349
-15359
-15361
-15373
-15377
-15383
-15391
-15401
-15413
-15427
-15439
-15443
-15451
-15461
-15467
-15473
-15493
-15497
-15511
-15527
-15541
-15551
-15559
-15569
-15581
-15583
-15601
-15607
-15619
-15629
-15641
-15643
-15647
-15649
-15661
-15667
-15671
-15679
-15683
-15727
-15731
-15733
-15737
-15739
-15749
-15761
-15767
-15773
-15787
-15791
-15797
-15803
-15809
-15817
-15823
-15859
-15877
-15881
-15887
-15889
-15901
-15907
-15913
-15919
-15923
-15937
-15959
-15971
-15973
-15991
-16001
-16007
-16033
-16057
-16061
-16063
-16067
-16069
-16073
-16087
-16091
-16097
-16103
-16111
-16127
-16139
-16141
-16183
-16187
-16189
-16193
-16217
-16223
-16229
-16231
-16249
-16253
-16267
-16273
-16301
-16319
-16333
-16339
-16349
-16361
-16363
-16369
-16381
-16411
-16417
-16421
-16427
-16433
-16447
-16451
-16453
-16477
-16481
-16487
-16493
-16519
-16529
-16547
-16553
-16561
-16567
-16573
-16603
-16607
-16619
-16631
-16633
-16649
-16651
-16657
-16661
-16673
-16691
-16693
-16699
-16703
-16729
-16741
-16747
-16759
-16763
-16787
-16811
-16823
-16829
-16831
-16843
-16871
-16879
-16883
-16889
-16901
-16903
-16921
-16927
-16931
-16937
-16943
-16963
-16979
-16981
-16987
-16993
-17011
-17021
-17027
-17029
-17033
-17041
-17047
-17053
-17077
-17093
-17099
-17107
-17117
-17123
-17137
-17159
-17167
-17183
-17189
-17191
-17203
-17207
-17209
-17231
-17239
-17257
-17291
-17293
-17299
-17317
-17321
-17327
-17333
-17341
-17351
-17359
-17377
-17383
-17387
-17389
-17393
-17401
-17417
-17419
-17431
-17443
-17449
-17467
-17471
-17477
-17483
-17489
-17491
-17497
-17509
-17519
-17539
-17551
-17569
-17573
-17579
-17581
-17597
-17599
-17609
-17623
-17627
-17657
-17659
-17669
-17681
-17683
-17707
-17713
-17729
-17737
-17747
-17749
-17761
-17783
-17789
-17791
-17807
-17827
-17837
-17839
-17851
-17863
-17881
-17891
-17903
-17909
-17911
-17921
-17923
-17929
-17939
-17957
-17959
-17971
-17977
-17981
-17987
-17989
-18013
-18041
-18043
-18047
-18049
-18059
-18061
-18077
-18089
-18097
-18119
-18121
-18127
-18131
-18133
-18143
-18149
-18169
-18181
-18191
-18199
-18211
-18217
-18223
-18229
-18233
-18251
-18253
-18257
-18269
-18287
-18289
-18301
-18307
-18311
-18313
-18329
-18341
-18353
-18367
-18371
-18379
-18397
-18401
-18413
-18427
-18433
-18439
-18443
-18451
-18457
-18461
-18481
-18493
-18503
-18517
-18521
-18523
-18539
-18541
-18553
-18583
-18587
-18593
-18617
-18637
-18661
-18671
-18679
-18691
-18701
-18713
-18719
-18731
-18743
-18749
-18757
-18773
-18787
-18793
-18797
-18803
-18839
-18859
-18869
-18899
-18911
-18913
-18917
-18919
-18947
-18959
-18973
-18979
-19001
-19009
-19013
-19031
-19037
-19051
-19069
-19073
-19079
-19081
-19087
-19121
-19139
-19141
-19157
-19163
-19181
-19183
-19207
-19211
-19213
-19219
-19231
-19237
-19249
-19259
-19267
-19273
-19289
-19301
-19309
-19319
-19333
-19373
-19379
-19381
-19387
-19391
-19403
-19417
-19421
-19423
-19427
-19429
-19433
-19441
-19447
-19457
-19463
-19469
-19471
-19477
-19483
-19489
-19501
-19507
-19531
-19541
-19543
-19553
-19559
-19571
-19577
-19583
-19597
-19603
-19609
-19661
-19681
-19687
-19697
-19699
-19709
-19717
-19727
-19739
-19751
-19753
-19759
-19763
-19777
-19793
-19801
-19813
-19819
-19841
-19843
-19853
-19861
-19867
-19889
-19891
-19913
-19919
-19927
-19937
-19949
-19961
-19963
-19973
-19979
-19991
-19993
-19997
-20011
-20021
-20023
-20029
-20047
-20051
-20063
-20071
-20089
-20101
-20107
-20113
-20117
-20123
-20129
-20143
-20147
-20149
-20161
-20173
-20177
-20183
-20201
-20219
-20231
-20233
-20249
-20261
-20269
-20287
-20297
-20323
-20327
-20333
-20341
-20347
-20353
-20357
-20359
-20369
-20389
-20393
-20399
-20407
-20411
-20431
-20441
-20443
-20477
-20479
-20483
-20507
-20509
-20521
-20533
-20543
-20549
-20551
-20563
-20593
-20599
-20611
-20627
-20639
-20641
-20663
-20681
-20693
-20707
-20717
-20719
-20731
-20743
-20747
-20749
-20753
-20759
-20771
-20773
-20789
-20807
-20809
-20849
-20857
-20873
-20879
-20887
-20897
-20899
-20903
-20921
-20929
-20939
-20947
-20959
-20963
-20981
-20983
-21001
-21011
-21013
-21017
-21019
-21023
-21031
-21059
-21061
-21067
-21089
-21101
-21107
-21121
-21139
-21143
-21149
-21157
-21163
-21169
-21179
-21187
-21191
-21193
-21211
-21221
-21227
-21247
-21269
-21277
-21283
-21313
-21317
-21319
-21323
-21341
-21347
-21377
-21379
-21383
-21391
-21397
-21401
-21407
-21419
-21433
-21467
-21481
-21487
-21491
-21493
-21499
-21503
-21517
-21521
-21523
-21529
-21557
-21559
-21563
-21569
-21577
-21587
-21589
-21599
-21601
-21611
-21613
-21617
-21647
-21649
-21661
-21673
-21683
-21701
-21713
-21727
-21737
-21739
-21751
-21757
-21767
-21773
-21787
-21799
-21803
-21817
-21821
-21839
-21841
-21851
-21859
-21863
-21871
-21881
-21893
-21911
-21929
-21937
-21943
-21961
-21977
-21991
-21997
-22003
-22013
-22027
-22031
-22037
-22039
-22051
-22063
-22067
-22073
-22079
-22091
-22093
-22109
-22111
-22123
-22129
-22133
-22147
-22153
-22157
-22159
-22171
-22189
-22193
-22229
-22247
-22259
-22271
-22273
-22277
-22279
-22283
-22291
-22303
-22307
-22343
-22349
-22367
-22369
-22381
-22391
-22397
-22409
-22433
-22441
-22447
-22453
-22469
-22481
-22483
-22501
-22511
-22531
-22541
-22543
-22549
-22567
-22571
-22573
-22613
-22619
-22621
-22637
-22639
-22643
-22651
-22669
-22679
-22691
-22697
-22699
-22709
-22717
-22721
-22727
-22739
-22741
-22751
-22769
-22777
-22783
-22787
-22807
-22811
-22817
-22853
-22859
-22861
-22871
-22877
-22901
-22907
-22921
-22937
-22943
-22961
-22963
-22973
-22993
-23003
-23011
-23017
-23021
-23027
-23029
-23039
-23041
-23053
-23057
-23059
-23063
-23071
-23081
-23087
-23099
-23117
-23131
-23143
-23159
-23167
-23173
-23189
-23197
-23201
-23203
-23209
-23227
-23251
-23269
-23279
-23291
-23293
-23297
-23311
-23321
-23327
-23333
-23339
-23357
-23369
-23371
-23399
-23417
-23431
-23447
-23459
-23473
-23497
-23509
-23531
-23537
-23539
-23549
-23557
-23561
-23563
-23567
-23581
-23593
-23599
-23603
-23609
-23623
-23627
-23629
-23633
-23663
-23669
-23671
-23677
-23687
-23689
-23719
-23741
-23743
-23747
-23753
-23761
-23767
-23773
-23789
-23801
-23813
-23819
-23827
-23831
-23833
-23857
-23869
-23873
-23879
-23887
-23893
-23899
-23909
-23911
-23917
-23929
-23957
-23971
-23977
-23981
-23993
-24001
-24007
-24019
-24023
-24029
-24043
-24049
-24061
-24071
-24077
-24083
-24091
-24097
-24103
-24107
-24109
-24113
-24121
-24133
-24137
-24151
-24169
-24179
-24181
-24197
-24203
-24223
-24229
-24239
-24247
-24251
-24281
-24317
-24329
-24337
-24359
-24371
-24373
-24379
-24391
-24407
-24413
-24419
-24421
-24439
-24443
-24469
-24473
-24481
-24499
-24509
-24517
-24527
-24533
-24547
-24551
-24571
-24593
-24611
-24623
-24631
-24659
-24671
-24677
-24683
-24691
-24697
-24709
-24733
-24749
-24763
-24767
-24781
-24793
-24799
-24809
-24821
-24841
-24847
-24851
-24859
-24877
-24889
-24907
-24917
-24919
-24923
-24943
-24953
-24967
-24971
-24977
-24979
-24989
-25013
-25031
-25033
-25037
-25057
-25073
-25087
-25097
-25111
-25117
-25121
-25127
-25147
-25153
-25163
-25169
-25171
-25183
-25189
-25219
-25229
-25237
-25243
-25247
-25253
-25261
-25301
-25303
-25307
-25309
-25321
-25339
-25343
-25349
-25357
-25367
-25373
-25391
-25409
-25411
-25423
-25439
-25447
-25453
-25457
-25463
-25469
-25471
-25523
-25537
-25541
-25561
-25577
-25579
-25583
-25589
-25601
-25603
-25609
-25621
-25633
-25639
-25643
-25657
-25667
-25673
-25679
-25693
-25703
-25717
-25733
-25741
-25747
-25759
-25763
-25771
-25793
-25799
-25801
-25819
-25841
-25847
-25849
-25867
-25873
-25889
-25903
-25913
-25919
-25931
-25933
-25939
-25943
-25951
-25969
-25981
-25997
-25999
-26003
-26017
-26021
-26029
-26041
-26053
-26083
-26099
-26107
-26111
-26113
-26119
-26141
-26153
-26161
-26171
-26177
-26183
-26189
-26203
-26209
-26227
-26237
-26249
-26251
-26261
-26263
-26267
-26293
-26297
-26309
-26317
-26321
-26339
-26347
-26357
-26371
-26387
-26393
-26399
-26407
-26417
-26423
-26431
-26437
-26449
-26459
-26479
-26489
-26497
-26501
-26513
-26539
-26557
-26561
-26573
-26591
-26597
-26627
-26633
-26641
-26647
-26669
-26681
-26683
-26687
-26693
-26699
-26701
-26711
-26713
-26717
-26723
-26729
-26731
-26737
-26759
-26777
-26783
-26801
-26813
-26821
-26833
-26839
-26849
-26861
-26863
-26879
-26881
-26891
-26893
-26903
-26921
-26927
-26947
-26951
-26953
-26959
-26981
-26987
-26993
-27011
-27017
-27031
-27043
-27059
-27061
-27067
-27073
-27077
-27091
-27103
-27107
-27109
-27127
-27143
-27179
-27191
-27197
-27211
-27239
-27241
-27253
-27259
-27271
-27277
-27281
-27283
-27299
-27329
-27337
-27361
-27367
-27397
-27407
-27409
-27427
-27431
-27437
-27449
-27457
-27479
-27481
-27487
-27509
-27527
-27529
-27539
-27541
-27551
-27581
-27583
-27611
-27617
-27631
-27647
-27653
-27673
-27689
-27691
-27697
-27701
-27733
-27737
-27739
-27743
-27749
-27751
-27763
-27767
-27773
-27779
-27791
-27793
-27799
-27803
-27809
-27817
-27823
-27827
-27847
-27851
-27883
-27893
-27901
-27917
-27919
-27941
-27943
-27947
-27953
-27961
-27967
-27983
-27997
-28001
-28019
-28027
-28031
-28051
-28057
-28069
-28081
-28087
-28097
-28099
-28109
-28111
-28123
-28151
-28163
-28181
-28183
-28201
-28211
-28219
-28229
-28277
-28279
-28283
-28289
-28297
-28307
-28309
-28319
-28349
-28351
-28387
-28393
-28403
-28409
-28411
-28429
-28433
-28439
-28447
-28463
-28477
-28493
-28499
-28513
-28517
-28537
-28541
-28547
-28549
-28559
-28571
-28573
-28579
-28591
-28597
-28603
-28607
-28619
-28621
-28627
-28631
-28643
-28649
-28657
-28661
-28663
-28669
-28687
-28697
-28703
-28711
-28723
-28729
-28751
-28753
-28759
-28771
-28789
-28793
-28807
-28813
-28817
-28837
-28843
-28859
-28867
-28871
-28879
-28901
-28909
-28921
-28927
-28933
-28949
-28961
-28979
-29009
-29017
-29021
-29023
-29027
-29033
-29059
-29063
-29077
-29101
-29123
-29129
-29131
-29137
-29147
-29153
-29167
-29173
-29179
-29191
-29201
-29207
-29209
-29221
-29231
-29243
-29251
-29269
-29287
-29297
-29303
-29311
-29327
-29333
-29339
-29347
-29363
-29383
-29387
-29389
-29399
-29401
-29411
-29423
-29429
-29437
-29443
-29453
-29473
-29483
-29501
-29527
-29531
-29537
-29567
-29569
-29573
-29581
-29587
-29599
-29611
-29629
-29633
-29641
-29663
-29669
-29671
-29683
-29717
-29723
-29741
-29753
-29759
-29761
-29789
-29803
-29819
-29833
-29837
-29851
-29863
-29867
-29873
-29879
-29881
-29917
-29921
-29927
-29947
-29959
-29983
-29989
-30011
-30013
-30029
-30047
-30059
-30071
-30089
-30091
-30097
-30103
-30109
-30113
-30119
-30133
-30137
-30139
-30161
-30169
-30181
-30187
-30197
-30203
-30211
-30223
-30241
-30253
-30259
-30269
-30271
-30293
-30307
-30313
-30319
-30323
-30341
-30347
-30367
-30389
-30391
-30403
-30427
-30431
-30449
-30467
-30469
-30491
-30493
-30497
-30509
-30517
-30529
-30539
-30553
-30557
-30559
-30577
-30593
-30631
-30637
-30643
-30649
-30661
-30671
-30677
-30689
-30697
-30703
-30707
-30713
-30727
-30757
-30763
-30773
-30781
-30803
-30809
-30817
-30829
-30839
-30841
-30851
-30853
-30859
-30869
-30871
-30881
-30893
-30911
-30931
-30937
-30941
-30949
-30971
-30977
-30983
-31013
-31019
-31033
-31039
-31051
-31063
-31069
-31079
-31081
-31091
-31121
-31123
-31139
-31147
-31151
-31153
-31159
-31177
-31181
-31183
-31189
-31193
-31219
-31223
-31231
-31237
-31247
-31249
-31253
-31259
-31267
-31271
-31277
-31307
-31319
-31321
-31327
-31333
-31337
-31357
-31379
-31387
-31391
-31393
-31397
-31469
-31477
-31481
-31489
-31511
-31513
-31517
-31531
-31541
-31543
-31547
-31567
-31573
-31583
-31601
-31607
-31627
-31643
-31649
-31657
-31663
-31667
-31687
-31699
-31721
-31723
-31727
-31729
-31741
-31751
-31769
-31771
-31793
-31799
-31817
-31847
-31849
-31859
-31873
-31883
-31891
-31907
-31957
-31963
-31973
-31981
-31991
-32003
-32009
-32027
-32029
-32051
-32057
-32059
-32063
-32069
-32077
-32083
-32089
-32099
-32117
-32119
-32141
-32143
-32159
-32173
-32183
-32189
-32191
-32203
-32213
-32233
-32237
-32251
-32257
-32261
-32297
-32299
-32303
-32309
-32321
-32323
-32327
-32341
-32353
-32359
-32363
-32369
-32371
-32377
-32381
-32401
-32411
-32413
-32423
-32429
-32441
-32443
-32467
-32479
-32491
-32497
-32503
-32507
-32531
-32533
-32537
-32561
-32563
-32569
-32573
-32579
-32587
-32603
-32609
-32611
-32621
-32633
-32647
-32653
-32687
-32693
-32707
-32713
-32717
-32719
-32749
-32771
-32779
-32783
-32789
-32797
-32801
-32803
-32831
-32833
-32839
-32843
-32869
-32887
-32909
-32911
-32917
-32933
-32939
-32941
-32957
-32969
-32971
-32983
-32987
-32993
-32999
-33013
-33023
-33029
-33037
-33049
-33053
-33071
-33073
-33083
-33091
-33107
-33113
-33119
-33149
-33151
-33161
-33179
-33181
-33191
-33199
-33203
-33211
-33223
-33247
-33287
-33289
-33301
-33311
-33317
-33329
-33331
-33343
-33347
-33349
-33353
-33359
-33377
-33391
-33403
-33409
-33413
-33427
-33457
-33461
-33469
-33479
-33487
-33493
-33503
-33521
-33529
-33533
-33547
-33563
-33569
-33577
-33581
-33587
-33589
-33599
-33601
-33613
-33617
-33619
-33623
-33629
-33637
-33641
-33647
-33679
-33703
-33713
-33721
-33739
-33749
-33751
-33757
-33767
-33769
-33773
-33791
-33797
-33809
-33811
-33827
-33829
-33851
-33857
-33863
-33871
-33889
-33893
-33911
-33923
-33931
-33937
-33941
-33961
-33967
-33997
-34019
-34031
-34033
-34039
-34057
-34061
-34123
-34127
-34129
-34141
-34147
-34157
-34159
-34171
-34183
-34211
-34213
-34217
-34231
-34253
-34259
-34261
-34267
-34273
-34283
-34297
-34301
-34303
-34313
-34319
-34327
-34337
-34351
-34361
-34367
-34369
-34381
-34403
-34421
-34429
-34439
-34457
-34469
-34471
-34483
-34487
-34499
-34501
-34511
-34513
-34519
-34537
-34543
-34549
-34583
-34589
-34591
-34603
-34607
-34613
-34631
-34649
-34651
-34667
-34673
-34679
-34687
-34693
-34703
-34721
-34729
-34739
-34747
-34757
-34759
-34763
-34781
-34807
-34819
-34841
-34843
-34847
-34849
-34871
-34877
-34883
-34897
-34913
-34919
-34939
-34949
-34961
-34963
-34981
-35023
-35027
-35051
-35053
-35059
-35069
-35081
-35083
-35089
-35099
-35107
-35111
-35117
-35129
-35141
-35149
-35153
-35159
-35171
-35201
-35221
-35227
-35251
-35257
-35267
-35279
-35281
-35291
-35311
-35317
-35323
-35327
-35339
-35353
-35363
-35381
-35393
-35401
-35407
-35419
-35423
-35437
-35447
-35449
-35461
-35491
-35507
-35509
-35521
-35527
-35531
-35533
-35537
-35543
-35569
-35573
-35591
-35593
-35597
-35603
-35617
-35671
-35677
-35729
-35731
-35747
-35753
-35759
-35771
-35797
-35801
-35803
-35809
-35831
-35837
-35839
-35851
-35863
-35869
-35879
-35897
-35899
-35911
-35923
-35933
-35951
-35963
-35969
-35977
-35983
-35993
-35999
-36007
-36011
-36013
-36017
-36037
-36061
-36067
-36073
-36083
-36097
-36107
-36109
-36131
-36137
-36151
-36161
-36187
-36191
-36209
-36217
-36229
-36241
-36251
-36263
-36269
-36277
-36293
-36299
-36307
-36313
-36319
-36341
-36343
-36353
-36373
-36383
-36389
-36433
-36451
-36457
-36467
-36469
-36473
-36479
-36493
-36497
-36523
-36527
-36529
-36541
-36551
-36559
-36563
-36571
-36583
-36587
-36599
-36607
-36629
-36637
-36643
-36653
-36671
-36677
-36683
-36691
-36697
-36709
-36713
-36721
-36739
-36749
-36761
-36767
-36779
-36781
-36787
-36791
-36793
-36809
-36821
-36833
-36847
-36857
-36871
-36877
-36887
-36899
-36901
-36913
-36919
-36923
-36929
-36931
-36943
-36947
-36973
-36979
-36997
-37003
-37013
-37019
-37021
-37039
-37049
-37057
-37061
-37087
-37097
-37117
-37123
-37139
-37159
-37171
-37181
-37189
-37199
-37201
-37217
-37223
-37243
-37253
-37273
-37277
-37307
-37309
-37313
-37321
-37337
-37339
-37357
-37361
-37363
-37369
-37379
-37397
-37409
-37423
-37441
-37447
-37463
-37483
-37489
-37493
-37501
-37507
-37511
-37517
-37529
-37537
-37547
-37549
-37561
-37567
-37571
-37573
-37579
-37589
-37591
-37607
-37619
-37633
-37643
-37649
-37657
-37663
-37691
-37693
-37699
-37717
-37747
-37781
-37783
-37799
-37811
-37813
-37831
-37847
-37853
-37861
-37871
-37879
-37889
-37897
-37907
-37951
-37957
-37963
-37967
-37987
-37991
-37993
-37997
-38011
-38039
-38047
-38053
-38069
-38083
-38113
-38119
-38149
-38153
-38167
-38177
-38183
-38189
-38197
-38201
-38219
-38231
-38237
-38239
-38261
-38273
-38281
-38287
-38299
-38303
-38317
-38321
-38327
-38329
-38333
-38351
-38371
-38377
-38393
-38431
-38447
-38449
-38453
-38459
-38461
-38501
-38543
-38557
-38561
-38567
-38569
-38593
-38603
-38609
-38611
-38629
-38639
-38651
-38653
-38669
-38671
-38677
-38693
-38699
-38707
-38711
-38713
-38723
-38729
-38737
-38747
-38749
-38767
-38783
-38791
-38803
-38821
-38833
-38839
-38851
-38861
-38867
-38873
-38891
-38903
-38917
-38921
-38923
-38933
-38953
-38959
-38971
-38977
-38993
-39019
-39023
-39041
-39043
-39047
-39079
-39089
-39097
-39103
-39107
-39113
-39119
-39133
-39139
-39157
-39161
-39163
-39181
-39191
-39199
-39209
-39217
-39227
-39229
-39233
-39239
-39241
-39251
-39293
-39301
-39313
-39317
-39323
-39341
-39343
-39359
-39367
-39371
-39373
-39383
-39397
-39409
-39419
-39439
-39443
-39451
-39461
-39499
-39503
-39509
-39511
-39521
-39541
-39551
-39563
-39569
-39581
-39607
-39619
-39623
-39631
-39659
-39667
-39671
-39679
-39703
-39709
-39719
-39727
-39733
-39749
-39761
-39769
-39779
-39791
-39799
-39821
-39827
-39829
-39839
-39841
-39847
-39857
-39863
-39869
-39877
-39883
-39887
-39901
-39929
-39937
-39953
-39971
-39979
-39983
-39989
-40009
-40013
-40031
-40037
-40039
-40063
-40087
-40093
-40099
-40111
-40123
-40127
-40129
-40151
-40153
-40163
-40169
-40177
-40189
-40193
-40213
-40231
-40237
-40241
-40253
-40277
-40283
-40289
-40343
-40351
-40357
-40361
-40387
-40423
-40427
-40429
-40433
-40459
-40471
-40483
-40487
-40493
-40499
-40507
-40519
-40529
-40531
-40543
-40559
-40577
-40583
-40591
-40597
-40609
-40627
-40637
-40639
-40693
-40697
-40699
-40709
-40739
-40751
-40759
-40763
-40771
-40787
-40801
-40813
-40819
-40823
-40829
-40841
-40847
-40849
-40853
-40867
-40879
-40883
-40897
-40903
-40927
-40933
-40939
-40949
-40961
-40973
-40993
-41011
-41017
-41023
-41039
-41047
-41051
-41057
-41077
-41081
-41113
-41117
-41131
-41141
-41143
-41149
-41161
-41177
-41179
-41183
-41189
-41201
-41203
-41213
-41221
-41227
-41231
-41233
-41243
-41257
-41263
-41269
-41281
-41299
-41333
-41341
-41351
-41357
-41381
-41387
-41389
-41399
-41411
-41413
-41443
-41453
-41467
-41479
-41491
-41507
-41513
-41519
-41521
-41539
-41543
-41549
-41579
-41593
-41597
-41603
-41609
-41611
-41617
-41621
-41627
-41641
-41647
-41651
-41659
-41669
-41681
-41687
-41719
-41729
-41737
-41759
-41761
-41771
-41777
-41801
-41809
-41813
-41843
-41849
-41851
-41863
-41879
-41887
-41893
-41897
-41903
-41911
-41927
-41941
-41947
-41953
-41957
-41959
-41969
-41981
-41983
-41999
-42013
-42017
-42019
-42023
-42043
-42061
-42071
-42073
-42083
-42089
-42101
-42131
-42139
-42157
-42169
-42179
-42181
-42187
-42193
-42197
-42209
-42221
-42223
-42227
-42239
-42257
-42281
-42283
-42293
-42299
-42307
-42323
-42331
-42337
-42349
-42359
-42373
-42379
-42391
-42397
-42403
-42407
-42409
-42433
-42437
-42443
-42451
-42457
-42461
-42463
-42467
-42473
-42487
-42491
-42499
-42509
-42533
-42557
-42569
-42571
-42577
-42589
-42611
-42641
-42643
-42649
-42667
-42677
-42683
-42689
-42697
-42701
-42703
-42709
-42719
-42727
-42737
-42743
-42751
-42767
-42773
-42787
-42793
-42797
-42821
-42829
-42839
-42841
-42853
-42859
-42863
-42899
-42901
-42923
-42929
-42937
-42943
-42953
-42961
-42967
-42979
-42989
-43003
-43013
-43019
-43037
-43049
-43051
-43063
-43067
-43093
-43103
-43117
-43133
-43151
-43159
-43177
-43189
-43201
-43207
-43223
-43237
-43261
-43271
-43283
-43291
-43313
-43319
-43321
-43331
-43391
-43397
-43399
-43403
-43411
-43427
-43441
-43451
-43457
-43481
-43487
-43499
-43517
-43541
-43543
-43573
-43577
-43579
-43591
-43597
-43607
-43609
-43613
-43627
-43633
-43649
-43651
-43661
-43669
-43691
-43711
-43717
-43721
-43753
-43759
-43777
-43781
-43783
-43787
-43789
-43793
-43801
-43853
-43867
-43889
-43891
-43913
-43933
-43943
-43951
-43961
-43963
-43969
-43973
-43987
-43991
-43997
-44017
-44021
-44027
-44029
-44041
-44053
-44059
-44071
-44087
-44089
-44101
-44111
-44119
-44123
-44129
-44131
-44159
-44171
-44179
-44189
-44201
-44203
-44207
-44221
-44249
-44257
-44263
-44267
-44269
-44273
-44279
-44281
-44293
-44351
-44357
-44371
-44381
-44383
-44389
-44417
-44449
-44453
-44483
-44491
-44497
-44501
-44507
-44519
-44531
-44533
-44537
-44543
-44549
-44563
-44579
-44587
-44617
-44621
-44623
-44633
-44641
-44647
-44651
-44657
-44683
-44687
-44699
-44701
-44711
-44729
-44741
-44753
-44771
-44773
-44777
-44789
-44797
-44809
-44819
-44839
-44843
-44851
-44867
-44879
-44887
-44893
-44909
-44917
-44927
-44939
-44953
-44959
-44963
-44971
-44983
-44987
-45007
-45013
-45053
-45061
-45077
-45083
-45119
-45121
-45127
-45131
-45137
-45139
-45161
-45179
-45181
-45191
-45197
-45233
-45247
-45259
-45263
-45281
-45289
-45293
-45307
-45317
-45319
-45329
-45337
-45341
-45343
-45361
-45377
-45389
-45403
-45413
-45427
-45433
-45439
-45481
-45491
-45497
-45503
-45523
-45533
-45541
-45553
-45557
-45569
-45587
-45589
-45599
-45613
-45631
-45641
-45659
-45667
-45673
-45677
-45691
-45697
-45707
-45737
-45751
-45757
-45763
-45767
-45779
-45817
-45821
-45823
-45827
-45833
-45841
-45853
-45863
-45869
-45887
-45893
-45943
-45949
-45953
-45959
-45971
-45979
-45989
-46021
-46027
-46049
-46051
-46061
-46073
-46091
-46093
-46099
-46103
-46133
-46141
-46147
-46153
-46171
-46181
-46183
-46187
-46199
-46219
-46229
-46237
-46261
-46271
-46273
-46279
-46301
-46307
-46309
-46327
-46337
-46349
-46351
-46381
-46399
-46411
-46439
-46441
-46447
-46451
-46457
-46471
-46477
-46489
-46499
-46507
-46511
-46523
-46549
-46559
-46567
-46573
-46589
-46591
-46601
-46619
-46633
-46639
-46643
-46649
-46663
-46679
-46681
-46687
-46691
-46703
-46723
-46727
-46747
-46751
-46757
-46769
-46771
-46807
-46811
-46817
-46819
-46829
-46831
-46853
-46861
-46867
-46877
-46889
-46901
-46919
-46933
-46957
-46993
-46997
-47017
-47041
-47051
-47057
-47059
-47087
-47093
-47111
-47119
-47123
-47129
-47137
-47143
-47147
-47149
-47161
-47189
-47207
-47221
-47237
-47251
-47269
-47279
-47287
-47293
-47297
-47303
-47309
-47317
-47339
-47351
-47353
-47363
-47381
-47387
-47389
-47407
-47417
-47419
-47431
-47441
-47459
-47491
-47497
-47501
-47507
-47513
-47521
-47527
-47533
-47543
-47563
-47569
-47581
-47591
-47599
-47609
-47623
-47629
-47639
-47653
-47657
-47659
-47681
-47699
-47701
-47711
-47713
-47717
-47737
-47741
-47743
-47777
-47779
-47791
-47797
-47807
-47809
-47819
-47837
-47843
-47857
-47869
-47881
-47903
-47911
-47917
-47933
-47939
-47947
-47951
-47963
-47969
-47977
-47981
-48017
-48023
-48029
-48049
-48073
-48079
-48091
-48109
-48119
-48121
-48131
-48157
-48163
-48179
-48187
-48193
-48197
-48221
-48239
-48247
-48259
-48271
-48281
-48299
-48311
-48313
-48337
-48341
-48353
-48371
-48383
-48397
-48407
-48409
-48413
-48437
-48449
-48463
-48473
-48479
-48481
-48487
-48491
-48497
-48523
-48527
-48533
-48539
-48541
-48563
-48571
-48589
-48593
-48611
-48619
-48623
-48647
-48649
-48661
-48673
-48677
-48679
-48731
-48733
-48751
-48757
-48761
-48767
-48779
-48781
-48787
-48799
-48809
-48817
-48821
-48823
-48847
-48857
-48859
-48869
-48871
-48883
-48889
-48907
-48947
-48953
-48973
-48989
-48991
-49003
-49009
-49019
-49031
-49033
-49037
-49043
-49057
-49069
-49081
-49103
-49109
-49117
-49121
-49123
-49139
-49157
-49169
-49171
-49177
-49193
-49199
-49201
-49207
-49211
-49223
-49253
-49261
-49277
-49279
-49297
-49307
-49331
-49333
-49339
-49363
-49367
-49369
-49391
-49393
-49409
-49411
-49417
-49429
-49433
-49451
-49459
-49463
-49477
-49481
-49499
-49523
-49529
-49531
-49537
-49547
-49549
-49559
-49597
-49603
-49613
-49627
-49633
-49639
-49663
-49667
-49669
-49681
-49697
-49711
-49727
-49739
-49741
-49747
-49757
-49783
-49787
-49789
-49801
-49807
-49811
-49823
-49831
-49843
-49853
-49871
-49877
-49891
-49919
-49921
-49927
-49937
-49939
-49943
-49957
-49991
-49993
-49999
-50021
-50023
-50033
-50047
-50051
-50053
-50069
-50077
-50087
-50093
-50101
-50111
-50119
-50123
-50129
-50131
-50147
-50153
-50159
-50177
-50207
-50221
-50227
-50231
-50261
-50263
-50273
-50287
-50291
-50311
-50321
-50329
-50333
-50341
-50359
-50363
-50377
-50383
-50387
-50411
-50417
-50423
-50441
-50459
-50461
-50497
-50503
-50513
-50527
-50539
-50543
-50549
-50551
-50581
-50587
-50591
-50593
-50599
-50627
-50647
-50651
-50671
-50683
-50707
-50723
-50741
-50753
-50767
-50773
-50777
-50789
-50821
-50833
-50839
-50849
-50857
-50867
-50873
-50891
-50893
-50909
-50923
-50929
-50951
-50957
-50969
-50971
-50989
-50993
-51001
-51031
-51043
-51047
-51059
-51061
-51071
-51109
-51131
-51133
-51137
-51151
-51157
-51169
-51193
-51197
-51199
-51203
-51217
-51229
-51239
-51241
-51257
-51263
-51283
-51287
-51307
-51329
-51341
-51343
-51347
-51349
-51361
-51383
-51407
-51413
-51419
-51421
-51427
-51431
-51437
-51439
-51449
-51461
-51473
-51479
-51481
-51487
-51503
-51511
-51517
-51521
-51539
-51551
-51563
-51577
-51581
-51593
-51599
-51607
-51613
-51631
-51637
-51647
-51659
-51673
-51679
-51683
-51691
-51713
-51719
-51721
-51749
-51767
-51769
-51787
-51797
-51803
-51817
-51827
-51829
-51839
-51853
-51859
-51869
-51871
-51893
-51899
-51907
-51913
-51929
-51941
-51949
-51971
-51973
-51977
-51991
-52009
-52021
-52027
-52051
-52057
-52067
-52069
-52081
-52103
-52121
-52127
-52147
-52153
-52163
-52177
-52181
-52183
-52189
-52201
-52223
-52237
-52249
-52253
-52259
-52267
-52289
-52291
-52301
-52313
-52321
-52361
-52363
-52369
-52379
-52387
-52391
-52433
-52453
-52457
-52489
-52501
-52511
-52517
-52529
-52541
-52543
-52553
-52561
-52567
-52571
-52579
-52583
-52609
-52627
-52631
-52639
-52667
-52673
-52691
-52697
-52709
-52711
-52721
-52727
-52733
-52747
-52757
-52769
-52783
-52807
-52813
-52817
-52837
-52859
-52861
-52879
-52883
-52889
-52901
-52903
-52919
-52937
-52951
-52957
-52963
-52967
-52973
-52981
-52999
-53003
-53017
-53047
-53051
-53069
-53077
-53087
-53089
-53093
-53101
-53113
-53117
-53129
-53147
-53149
-53161
-53171
-53173
-53189
-53197
-53201
-53231
-53233
-53239
-53267
-53269
-53279
-53281
-53299
-53309
-53323
-53327
-53353
-53359
-53377
-53381
-53401
-53407
-53411
-53419
-53437
-53441
-53453
-53479
-53503
-53507
-53527
-53549
-53551
-53569
-53591
-53593
-53597
-53609
-53611
-53617
-53623
-53629
-53633
-53639
-53653
-53657
-53681
-53693
-53699
-53717
-53719
-53731
-53759
-53773
-53777
-53783
-53791
-53813
-53819
-53831
-53849
-53857
-53861
-53881
-53887
-53891
-53897
-53899
-53917
-53923
-53927
-53939
-53951
-53959
-53987
-53993
-54001
-54011
-54013
-54037
-54049
-54059
-54083
-54091
-54101
-54121
-54133
-54139
-54151
-54163
-54167
-54181
-54193
-54217
-54251
-54269
-54277
-54287
-54293
-54311
-54319
-54323
-54331
-54347
-54361
-54367
-54371
-54377
-54401
-54403
-54409
-54413
-54419
-54421
-54437
-54443
-54449
-54469
-54493
-54497
-54499
-54503
-54517
-54521
-54539
-54541
-54547
-54559
-54563
-54577
-54581
-54583
-54601
-54617
-54623
-54629
-54631
-54647
-54667
-54673
-54679
-54709
-54713
-54721
-54727
-54751
-54767
-54773
-54779
-54787
-54799
-54829
-54833
-54851
-54869
-54877
-54881
-54907
-54917
-54919
-54941
-54949
-54959
-54973
-54979
-54983
-55001
-55009
-55021
-55049
-55051
-55057
-55061
-55073
-55079
-55103
-55109
-55117
-55127
-55147
-55163
-55171
-55201
-55207
-55213
-55217
-55219
-55229
-55243
-55249
-55259
-55291
-55313
-55331
-55333
-55337
-55339
-55343
-55351
-55373
-55381
-55399
-55411
-55439
-55441
-55457
-55469
-55487
-55501
-55511
-55529
-55541
-55547
-55579
-55589
-55603
-55609
-55619
-55621
-55631
-55633
-55639
-55661
-55663
-55667
-55673
-55681
-55691
-55697
-55711
-55717
-55721
-55733
-55763
-55787
-55793
-55799
-55807
-55813
-55817
-55819
-55823
-55829
-55837
-55843
-55849
-55871
-55889
-55897
-55901
-55903
-55921
-55927
-55931
-55933
-55949
-55967
-55987
-55997
-56003
-56009
-56039
-56041
-56053
-56081
-56087
-56093
-56099
-56101
-56113
-56123
-56131
-56149
-56167
-56171
-56179
-56197
-56207
-56209
-56237
-56239
-56249
-56263
-56267
-56269
-56299
-56311
-56333
-56359
-56369
-56377
-56383
-56393
-56401
-56417
-56431
-56437
-56443
-56453
-56467
-56473
-56477
-56479
-56489
-56501
-56503
-56509
-56519
-56527
-56531
-56533
-56543
-56569
-56591
-56597
-56599
-56611
-56629
-56633
-56659
-56663
-56671
-56681
-56687
-56701
-56711
-56713
-56731
-56737
-56747
-56767
-56773
-56779
-56783
-56807
-56809
-56813
-56821
-56827
-56843
-56857
-56873
-56891
-56893
-56897
-56909
-56911
-56921
-56923
-56929
-56941
-56951
-56957
-56963
-56983
-56989
-56993
-56999
-57037
-57041
-57047
-57059
-57073
-57077
-57089
-57097
-57107
-57119
-57131
-57139
-57143
-57149
-57163
-57173
-57179
-57191
-57193
-57203
-57221
-57223
-57241
-57251
-57259
-57269
-57271
-57283
-57287
-57301
-57329
-57331
-57347
-57349
-57367
-57373
-57383
-57389
-57397
-57413
-57427
-57457
-57467
-57487
-57493
-57503
-57527
-57529
-57557
-57559
-57571
-57587
-57593
-57601
-57637
-57641
-57649
-57653
-57667
-57679
-57689
-57697
-57709
-57713
-57719
-57727
-57731
-57737
-57751
-57773
-57781
-57787
-57791
-57793
-57803
-57809
-57829
-57839
-57847
-57853
-57859
-57881
-57899
-57901
-57917
-57923
-57943
-57947
-57973
-57977
-57991
-58013
-58027
-58031
-58043
-58049
-58057
-58061
-58067
-58073
-58099
-58109
-58111
-58129
-58147
-58151
-58153
-58169
-58171
-58189
-58193
-58199
-58207
-58211
-58217
-58229
-58231
-58237
-58243
-58271
-58309
-58313
-58321
-58337
-58363
-58367
-58369
-58379
-58391
-58393
-58403
-58411
-58417
-58427
-58439
-58441
-58451
-58453
-58477
-58481
-58511
-58537
-58543
-58549
-58567
-58573
-58579
-58601
-58603
-58613
-58631
-58657
-58661
-58679
-58687
-58693
-58699
-58711
-58727
-58733
-58741
-58757
-58763
-58771
-58787
-58789
-58831
-58889
-58897
-58901
-58907
-58909
-58913
-58921
-58937
-58943
-58963
-58967
-58979
-58991
-58997
-59009
-59011
-59021
-59023
-59029
-59051
-59053
-59063
-59069
-59077
-59083
-59093
-59107
-59113
-59119
-59123
-59141
-59149
-59159
-59167
-59183
-59197
-59207
-59209
-59219
-59221
-59233
-59239
-59243
-59263
-59273
-59281
-59333
-59341
-59351
-59357
-59359
-59369
-59377
-59387
-59393
-59399
-59407
-59417
-59419
-59441
-59443
-59447
-59453
-59467
-59471
-59473
-59497
-59509
-59513
-59539
-59557
-59561
-59567
-59581
-59611
-59617
-59621
-59627
-59629
-59651
-59659
-59663
-59669
-59671
-59693
-59699
-59707
-59723
-59729
-59743
-59747
-59753
-59771
-59779
-59791
-59797
-59809
-59833
-59863
-59879
-59887
-59921
-59929
-59951
-59957
-59971
-59981
-59999
-60013
-60017
-60029
-60037
-60041
-60077
-60083
-60089
-60091
-60101
-60103
-60107
-60127
-60133
-60139
-60149
-60161
-60167
-60169
-60209
-60217
-60223
-60251
-60257
-60259
-60271
-60289
-60293
-60317
-60331
-60337
-60343
-60353
-60373
-60383
-60397
-60413
-60427
-60443
-60449
-60457
-60493
-60497
-60509
-60521
-60527
-60539
-60589
-60601
-60607
-60611
-60617
-60623
-60631
-60637
-60647
-60649
-60659
-60661
-60679
-60689
-60703
-60719
-60727
-60733
-60737
-60757
-60761
-60763
-60773
-60779
-60793
-60811
-60821
-60859
-60869
-60887
-60889
-60899
-60901
-60913
-60917
-60919
-60923
-60937
-60943
-60953
-60961
-61001
-61007
-61027
-61031
-61043
-61051
-61057
-61091
-61099
-61121
-61129
-61141
-61151
-61153
-61169
-61211
-61223
-61231
-61253
-61261
-61283
-61291
-61297
-61331
-61333
-61339
-61343
-61357
-61363
-61379
-61381
-61403
-61409
-61417
-61441
-61463
-61469
-61471
-61483
-61487
-61493
-61507
-61511
-61519
-61543
-61547
-61553
-61559
-61561
-61583
-61603
-61609
-61613
-61627
-61631
-61637
-61643
-61651
-61657
-61667
-61673
-61681
-61687
-61703
-61717
-61723
-61729
-61751
-61757
-61781
-61813
-61819
-61837
-61843
-61861
-61871
-61879
-61909
-61927
-61933
-61949
-61961
-61967
-61979
-61981
-61987
-61991
-62003
-62011
-62017
-62039
-62047
-62053
-62057
-62071
-62081
-62099
-62119
-62129
-62131
-62137
-62141
-62143
-62171
-62189
-62191
-62201
-62207
-62213
-62219
-62233
-62273
-62297
-62299
-62303
-62311
-62323
-62327
-62347
-62351
-62383
-62401
-62417
-62423
-62459
-62467
-62473
-62477
-62483
-62497
-62501
-62507
-62533
-62539
-62549
-62563
-62581
-62591
-62597
-62603
-62617
-62627
-62633
-62639
-62653
-62659
-62683
-62687
-62701
-62723
-62731
-62743
-62753
-62761
-62773
-62791
-62801
-62819
-62827
-62851
-62861
-62869
-62873
-62897
-62903
-62921
-62927
-62929
-62939
-62969
-62971
-62981
-62983
-62987
-62989
-63029
-63031
-63059
-63067
-63073
-63079
-63097
-63103
-63113
-63127
-63131
-63149
-63179
-63197
-63199
-63211
-63241
-63247
-63277
-63281
-63299
-63311
-63313
-63317
-63331
-63337
-63347
-63353
-63361
-63367
-63377
-63389
-63391
-63397
-63409
-63419
-63421
-63439
-63443
-63463
-63467
-63473
-63487
-63493
-63499
-63521
-63527
-63533
-63541
-63559
-63577
-63587
-63589
-63599
-63601
-63607
-63611
-63617
-63629
-63647
-63649
-63659
-63667
-63671
-63689
-63691
-63697
-63703
-63709
-63719
-63727
-63737
-63743
-63761
-63773
-63781
-63793
-63799
-63803
-63809
-63823
-63839
-63841
-63853
-63857
-63863
-63901
-63907
-63913
-63929
-63949
-63977
-63997
-64007
-64013
-64019
-64033
-64037
-64063
-64067
-64081
-64091
-64109
-64123
-64151
-64153
-64157
-64171
-64187
-64189
-64217
-64223
-64231
-64237
-64271
-64279
-64283
-64301
-64303
-64319
-64327
-64333
-64373
-64381
-64399
-64403
-64433
-64439
-64451
-64453
-64483
-64489
-64499
-64513
-64553
-64567
-64577
-64579
-64591
-64601
-64609
-64613
-64621
-64627
-64633
-64661
-64663
-64667
-64679
-64693
-64709
-64717
-64747
-64763
-64781
-64783
-64793
-64811
-64817
-64849
-64853
-64871
-64877
-64879
-64891
-64901
-64919
-64921
-64927
-64937
-64951
-64969
-64997
-65003
-65011
-65027
-65029
-65033
-65053
-65063
-65071
-65089
-65099
-65101
-65111
-65119
-65123
-65129
-65141
-65147
-65167
-65171
-65173
-65179
-65183
-65203
-65213
-65239
-65257
-65267
-65269
-65287
-65293
-65309
-65323
-65327
-65353
-65357
-65371
-65381
-65393
-65407
-65413
-65419
-65423
-65437
-65447
-65449
-65479
-65497
-65519
-65521
diff --git a/security/nss/lib/freebl/mpi/doc/prng.pod b/security/nss/lib/freebl/mpi/doc/prng.pod
deleted file mode 100644
index 1ae75da82..000000000
--- a/security/nss/lib/freebl/mpi/doc/prng.pod
+++ /dev/null
@@ -1,41 +0,0 @@
-=head1 NAME
-
- prng - pseudo-random number generator
-
-=head1 SYNOPSIS
-
- prng [count]
-
-=head1 DESCRIPTION
-
-B<Prng> generates 32-bit pseudo-random integers using the
-Blum-Blum-Shub (BBS) quadratic residue generator. It is seeded using
-the standard C library's rand() function, which itself seeded from the
-system clock and the process ID number. Thus, the values generated
-are not particularly useful for cryptographic applications, but they
-are in general much better than the typical output of the usual
-multiplicative congruency generator used by most runtime libraries.
-
-You may optionally specify how many random values should be generated
-by giving a I<count> argument on the command line. If you do not
-specify a count, only one random value will be generated. The results
-are output to the standard output in decimal notation, one value per
-line.
-
-=head1 RESTRICTIONS
-
-As stated above, B<prng> uses the C library's rand() function to seed
-the generator, so it is not terribly suitable for cryptographic
-applications. Also note that each time you run the program, a new
-seed is generated, so it is better to run it once with a I<count>
-parameter than it is to run it multiple times to generate several
-values.
-
-=head1 AUTHOR
-
- Michael J. Fromberger <sting@linguist.dartmouth.edu>
- Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
- Thayer School of Engineering, Dartmouth College, Hanover, NH USA
-
- $Date$
-
diff --git a/security/nss/lib/freebl/mpi/doc/redux.txt b/security/nss/lib/freebl/mpi/doc/redux.txt
deleted file mode 100644
index bf73e763c..000000000
--- a/security/nss/lib/freebl/mpi/doc/redux.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-Modular Reduction
-
-Usually, modular reduction is accomplished by long division, using the
-mp_div() or mp_mod() functions. However, when performing modular
-exponentiation, you spend a lot of time reducing by the same modulus
-again and again. For this purpose, doing a full division for each
-multiplication is quite inefficient.
-
-For this reason, the mp_exptmod() function does not perform modular
-reductions in the usual way, but instead takes advantage of an
-algorithm due to Barrett, as described by Menezes, Oorschot and
-VanStone in their book _Handbook of Applied Cryptography_, published
-by the CRC Press (see Chapter 14 for details). This method reduces
-most of the computation of reduction to efficient shifting and masking
-operations, and avoids the multiple-precision division entirely.
-
-Here is a brief synopsis of Barrett reduction, as it is implemented in
-this library.
-
-Let b denote the radix of the computation (one more than the maximum
-value that can be denoted by an mp_digit). Let m be the modulus, and
-let k be the number of significant digits of m. Let x be the value to
-be reduced modulo m. By the Division Theorem, there exist unique
-integers Q and R such that:
-
- x = Qm + R, 0 <= R < m
-
-Barrett reduction takes advantage of the fact that you can easily
-approximate Q to within two, given a value M such that:
-
- 2k
- b
- M = floor( ----- )
- m
-
-Computation of M requires a full-precision division step, so if you
-are only doing a single reduction by m, you gain no advantage.
-However, when multiple reductions by the same m are required, this
-division need only be done once, beforehand. Using this, we can use
-the following equation to compute Q', an approximation of Q:
-
- x
- floor( ------ ) M
- k-1
- b
-Q' = floor( ----------------- )
- k+1
- b
-
-The divisions by b^(k-1) and b^(k+1) and the floor() functions can be
-efficiently implemented with shifts and masks, leaving only a single
-multiplication to be performed to get this approximation. It can be
-shown that Q - 2 <= Q' <= Q, so in the worst case, we can get out with
-two additional subtractions to bring the value into line with the
-actual value of Q.
-
-Once we've got Q', we basically multiply that by m and subtract from
-x, yielding:
-
- x - Q'm = Qm + R - Q'm
-
-Since we know the constraint on Q', this is one of:
-
- R
- m + R
- 2m + R
-
-Since R < m by the Division Theorem, we can simply subtract off m
-until we get a value in the correct range, which will happen with no
-more than 2 subtractions:
-
- v = x - Q'm
-
- while(v >= m)
- v = v - m
- endwhile
-
-
-In random performance trials, modular exponentiation using this method
-of reduction gave around a 40% speedup over using the division for
-reduction.
-
-------------------------------------------------------------------
- This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-$Id$
diff --git a/security/nss/lib/freebl/mpi/doc/sqrt.txt b/security/nss/lib/freebl/mpi/doc/sqrt.txt
deleted file mode 100644
index e18da829b..000000000
--- a/security/nss/lib/freebl/mpi/doc/sqrt.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-Square Root
-
-A simple iterative algorithm is used to compute the greatest integer
-less than or equal to the square root. Essentially, this is Newton's
-linear approximation, computed by finding successive values of the
-equation:
-
- x[k]^2 - V
-x[k+1] = x[k] - ------------
- 2 x[k]
-
-...where V is the value for which the square root is being sought. In
-essence, what is happening here is that we guess a value for the
-square root, then figure out how far off we were by squaring our guess
-and subtracting the target. Using this value, we compute a linear
-approximation for the error, and adjust the "guess". We keep doing
-this until the precision gets low enough that the above equation
-yields a quotient of zero. At this point, our last guess is one
-greater than the square root we're seeking.
-
-The initial guess is computed by dividing V by 4, which is a heuristic
-I have found to be fairly good on average. This also has the
-advantage of being very easy to compute efficiently, even for large
-values.
-
-So, the resulting algorithm works as follows:
-
- x = V / 4 /* compute initial guess */
-
- loop
- t = (x * x) - V /* Compute absolute error */
- u = 2 * x /* Adjust by tangent slope */
- t = t / u
-
- /* Loop is done if error is zero */
- if(t == 0)
- break
-
- /* Adjust guess by error term */
- x = x - t
- end
-
- x = x - 1
-
-The result of the computation is the value of x.
-
-------------------------------------------------------------------
- This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-$Id$
-
-
diff --git a/security/nss/lib/freebl/mpi/doc/square.txt b/security/nss/lib/freebl/mpi/doc/square.txt
deleted file mode 100644
index 5da5c575d..000000000
--- a/security/nss/lib/freebl/mpi/doc/square.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-Squaring Algorithm
-
-When you are squaring a value, you can take advantage of the fact that
-half the multiplications performed by the more general multiplication
-algorithm (see 'mul.txt' for a description) are redundant when the
-multiplicand equals the multiplier.
-
-In particular, the modified algorithm is:
-
-k = 0
-for j <- 0 to (#a - 1)
- w = c[2*j] + (a[j] ^ 2);
- k = w div R
-
- for i <- j+1 to (#a - 1)
- w = (2 * a[j] * a[i]) + k + c[i+j]
- c[i+j] = w mod R
- k = w div R
- endfor
- c[i+j] = k;
- k = 0;
-endfor
-
-On the surface, this looks identical to the multiplication algorithm;
-however, note the following differences:
-
- - precomputation of the leading term in the outer loop
-
- - i runs from j+1 instead of from zero
-
- - doubling of a[i] * a[j] in the inner product
-
-Unfortunately, the construction of the inner product is such that we
-need more than two digits to represent the inner product, in some
-cases. In a C implementation, this means that some gymnastics must be
-performed in order to handle overflow, for which C has no direct
-abstraction. We do this by observing the following:
-
-If we have multiplied a[i] and a[j], and the product is more than half
-the maximum value expressible in two digits, then doubling this result
-will overflow into a third digit. If this occurs, we take note of the
-overflow, and double it anyway -- C integer arithmetic ignores
-overflow, so the two digits we get back should still be valid, modulo
-the overflow.
-
-Having doubled this value, we now have to add in the remainders and
-the digits already computed by earlier steps. If we did not overflow
-in the previous step, we might still cause an overflow here. That
-will happen whenever the maximum value expressible in two digits, less
-the amount we have to add, is greater than the result of the previous
-step. Thus, the overflow computation is:
-
-
- u = 0
- w = a[i] * a[j]
-
- if(w > (R - 1)/ 2)
- u = 1;
-
- w = w * 2
- v = c[i + j] + k
-
- if(u == 0 && (R - 1 - v) < w)
- u = 1
-
-If there is an overflow, u will be 1, otherwise u will be 0. The rest
-of the parameters are the same as they are in the above description.
-
-------------------------------------------------------------------
- This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-$Id$
-
-
diff --git a/security/nss/lib/freebl/mpi/doc/timing.txt b/security/nss/lib/freebl/mpi/doc/timing.txt
deleted file mode 100644
index 3ce32899a..000000000
--- a/security/nss/lib/freebl/mpi/doc/timing.txt
+++ /dev/null
@@ -1,217 +0,0 @@
-MPI Library Timing Tests
-
-Hardware/OS
-(A) SGI O2 1 x MIPS R10000 250MHz IRIX 6.5.3
-(B) IBM RS/6000 43P-240 1 x PowerPC 603e 223MHz AIX 4.3
-(C) Dell GX1/L+ 1 x Pentium III 550MHz Linux 2.2.12-20
-(D) PowerBook G3 1 x PowerPC 750 266MHz LinuxPPC 2.2.6-15apmac
-(E) PowerBook G3 1 x PowerPC 750 266MHz MacOS 8.5.1
-(F) PowerBook G3 1 x PowerPC 750 400MHz MacOS 9.0.2
-
-Compiler
-(1) MIPSpro C 7.2.1 -O3 optimizations
-(2) GCC 2.95.1 -O3 optimizations
-(3) IBM AIX xlc -O3 optimizations (version unknown)
-(4) EGCS 2.91.66 -O3 optimizations
-(5) Metrowerks CodeWarrior 5.0 C, all optimizations
-(6) MIPSpro C 7.30 -O3 optimizations
-(7) same as (6), with optimized libmalloc.so
-
-Timings are given in seconds, computed using the C library's clock()
-function. The first column gives the hardware and compiler
-configuration used for the test. The second column indicates the
-number of tests that were aggregated to get the statistics for that
-size. These were compiled using 16 bit digits.
-
-Source data were generated randomly using a fixed seed, so they should
-be internally consistent, but may vary on different systems depending
-on the C library. Also, since the resolution of the timer accessed by
-clock() varies, there may be some variance in the precision of these
-measurements.
-
-Prime Generation (primegen)
-
-128 bits:
-A1 200 min=0.03, avg=0.19, max=0.72, sum=38.46
-A2 200 min=0.02, avg=0.16, max=0.62, sum=32.55
-B3 200 min=0.01, avg=0.07, max=0.22, sum=13.29
-C4 200 min=0.00, avg=0.03, max=0.20, sum=6.14
-D4 200 min=0.00, avg=0.05, max=0.33, sum=9.70
-A6 200 min=0.01, avg=0.09, max=0.36, sum=17.48
-A7 200 min=0.00, avg=0.05, max=0.24, sum=10.07
-
-192 bits:
-A1 200 min=0.05, avg=0.45, max=3.13, sum=89.96
-A2 200 min=0.04, avg=0.39, max=2.61, sum=77.55
-B3 200 min=0.02, avg=0.18, max=1.25, sum=36.97
-C4 200 min=0.01, avg=0.09, max=0.33, sum=18.24
-D4 200 min=0.02, avg=0.15, max=0.54, sum=29.63
-A6 200 min=0.02, avg=0.24, max=1.70, sum=47.84
-A7 200 min=0.01, avg=0.15, max=1.05, sum=30.88
-
-256 bits:
-A1 200 min=0.08, avg=0.92, max=6.13, sum=184.79
-A2 200 min=0.06, avg=0.76, max=5.03, sum=151.11
-B3 200 min=0.04, avg=0.41, max=2.68, sum=82.35
-C4 200 min=0.02, avg=0.19, max=0.69, sum=37.91
-D4 200 min=0.03, avg=0.31, max=1.15, sum=63.00
-A6 200 min=0.04, avg=0.48, max=3.13, sum=95.46
-A7 200 min=0.03, avg=0.37, max=2.36, sum=73.60
-
-320 bits:
-A1 200 min=0.11, avg=1.59, max=6.14, sum=318.81
-A2 200 min=0.09, avg=1.27, max=4.93, sum=254.03
-B3 200 min=0.07, avg=0.82, max=3.13, sum=163.80
-C4 200 min=0.04, avg=0.44, max=1.91, sum=87.59
-D4 200 min=0.06, avg=0.73, max=3.22, sum=146.73
-A6 200 min=0.07, avg=0.93, max=3.50, sum=185.01
-A7 200 min=0.05, avg=0.76, max=2.94, sum=151.78
-
-384 bits:
-A1 200 min=0.16, avg=2.69, max=11.41, sum=537.89
-A2 200 min=0.13, avg=2.15, max=9.03, sum=429.14
-B3 200 min=0.11, avg=1.54, max=6.49, sum=307.78
-C4 200 min=0.06, avg=0.81, max=4.84, sum=161.13
-D4 200 min=0.10, avg=1.38, max=8.31, sum=276.81
-A6 200 min=0.11, avg=1.73, max=7.36, sum=345.55
-A7 200 min=0.09, avg=1.46, max=6.12, sum=292.02
-
-448 bits:
-A1 200 min=0.23, avg=3.36, max=15.92, sum=672.63
-A2 200 min=0.17, avg=2.61, max=12.25, sum=522.86
-B3 200 min=0.16, avg=2.10, max=9.83, sum=420.86
-C4 200 min=0.09, avg=1.44, max=7.64, sum=288.36
-D4 200 min=0.16, avg=2.50, max=13.29, sum=500.17
-A6 200 min=0.15, avg=2.31, max=10.81, sum=461.58
-A7 200 min=0.14, avg=2.03, max=9.53, sum=405.16
-
-512 bits:
-A1 200 min=0.30, avg=6.12, max=22.18, sum=1223.35
-A2 200 min=0.25, avg=4.67, max=16.90, sum=933.18
-B3 200 min=0.23, avg=4.13, max=14.94, sum=825.45
-C4 200 min=0.13, avg=2.08, max=9.75, sum=415.22
-D4 200 min=0.24, avg=4.04, max=20.18, sum=808.11
-A6 200 min=0.22, avg=4.47, max=16.19, sum=893.83
-A7 200 min=0.20, avg=4.03, max=14.65, sum=806.02
-
-Modular Exponentation (metime)
-
-The following results are aggregated from 200 pseudo-randomly
-generated tests, based on a fixed seed.
-
- base, exponent, and modulus size (bits)
-P/C 128 192 256 320 384 448 512 640 768 896 1024
-------- -----------------------------------------------------------------
-A1 0.015 0.027 0.047 0.069 0.098 0.133 0.176 0.294 0.458 0.680 1.040
-A2 0.013 0.024 0.037 0.053 0.077 0.102 0.133 0.214 0.326 0.476 0.668
-B3 0.005 0.011 0.021 0.036 0.056 0.084 0.121 0.222 0.370 0.573 0.840
-C4 0.002 0.006 0.011 0.020 0.032 0.048 0.069 0.129 0.223 0.344 0.507
-D4 0.004 0.010 0.019 0.034 0.056 0.085 0.123 0.232 0.390 0.609 0.899
-E5 0.007 0.015 0.031 0.055 0.088 0.133 0.183 0.342 0.574 0.893 1.317
-A6 0.008 0.016 0.038 0.042 0.064 0.093 0.133 0.239 0.393 0.604 0.880
-A7 0.005 0.011 0.020 0.036 0.056 0.083 0.121 0.223 0.374 0.583 0.855
-
-Multiplication and Squaring tests, (mulsqr)
-
-The following results are aggregated from 500000 pseudo-randomly
-generated tests, based on a per-run wall-clock seed. Times are given
-in seconds, except where indicated in microseconds (us).
-
-(A1)
-
-bits multiply square ad percent time/mult time/square
-64 9.33 9.15 > 1.9 18.7us 18.3us
-128 10.88 10.44 > 4.0 21.8us 20.9us
-192 13.30 11.89 > 10.6 26.7us 23.8us
-256 14.88 12.64 > 15.1 29.8us 25.3us
-320 18.64 15.01 > 19.5 37.3us 30.0us
-384 23.11 17.70 > 23.4 46.2us 35.4us
-448 28.28 20.88 > 26.2 56.6us 41.8us
-512 34.09 24.51 > 28.1 68.2us 49.0us
-640 47.86 33.25 > 30.5 95.7us 66.5us
-768 64.91 43.54 > 32.9 129.8us 87.1us
-896 84.49 55.48 > 34.3 169.0us 111.0us
-1024 107.25 69.21 > 35.5 214.5us 138.4us
-1536 227.97 141.91 > 37.8 456.0us 283.8us
-2048 394.05 242.15 > 38.5 788.1us 484.3us
-
-(A2)
-
-bits multiply square ad percent time/mult time/square
-64 7.87 7.95 < 1.0 15.7us 15.9us
-128 9.40 9.19 > 2.2 18.8us 18.4us
-192 11.15 10.59 > 5.0 22.3us 21.2us
-256 12.02 11.16 > 7.2 24.0us 22.3us
-320 14.62 13.43 > 8.1 29.2us 26.9us
-384 17.72 15.80 > 10.8 35.4us 31.6us
-448 21.24 18.51 > 12.9 42.5us 37.0us
-512 25.36 21.78 > 14.1 50.7us 43.6us
-640 34.57 29.00 > 16.1 69.1us 58.0us
-768 46.10 37.60 > 18.4 92.2us 75.2us
-896 58.94 47.72 > 19.0 117.9us 95.4us
-1024 73.76 59.12 > 19.8 147.5us 118.2us
-1536 152.00 118.80 > 21.8 304.0us 237.6us
-2048 259.41 199.57 > 23.1 518.8us 399.1us
-
-(B3)
-
-bits multiply square ad percent time/mult time/square
-64 2.60 2.47 > 5.0 5.20us 4.94us
-128 4.43 4.06 > 8.4 8.86us 8.12us
-192 7.03 6.10 > 13.2 14.1us 12.2us
-256 10.44 8.59 > 17.7 20.9us 17.2us
-320 14.44 11.64 > 19.4 28.9us 23.3us
-384 19.12 15.08 > 21.1 38.2us 30.2us
-448 24.55 19.09 > 22.2 49.1us 38.2us
-512 31.03 23.53 > 24.2 62.1us 47.1us
-640 45.05 33.80 > 25.0 90.1us 67.6us
-768 63.02 46.05 > 26.9 126.0us 92.1us
-896 83.74 60.29 > 28.0 167.5us 120.6us
-1024 106.73 76.65 > 28.2 213.5us 153.3us
-1536 228.94 160.98 > 29.7 457.9us 322.0us
-2048 398.08 275.93 > 30.7 796.2us 551.9us
-
-(C4)
-
-bits multiply square ad percent time/mult time/square
-64 1.34 1.28 > 4.5 2.68us 2.56us
-128 2.76 2.59 > 6.2 5.52us 5.18us
-192 4.52 4.16 > 8.0 9.04us 8.32us
-256 6.64 5.99 > 9.8 13.3us 12.0us
-320 9.20 8.13 > 11.6 18.4us 16.3us
-384 12.01 10.58 > 11.9 24.0us 21.2us
-448 15.24 13.33 > 12.5 30.5us 26.7us
-512 19.02 16.46 > 13.5 38.0us 32.9us
-640 27.56 23.54 > 14.6 55.1us 47.1us
-768 37.89 31.78 > 16.1 75.8us 63.6us
-896 49.24 41.42 > 15.9 98.5us 82.8us
-1024 62.59 52.18 > 16.6 125.2us 104.3us
-1536 131.66 107.72 > 18.2 263.3us 215.4us
-2048 226.45 182.95 > 19.2 453.0us 365.9us
-
-(A7)
-
-bits multiply square ad percent time/mult time/square
-64 1.74 1.71 > 1.7 3.48us 3.42us
-128 3.48 2.96 > 14.9 6.96us 5.92us
-192 5.74 4.60 > 19.9 11.5us 9.20us
-256 8.75 6.61 > 24.5 17.5us 13.2us
-320 12.5 8.99 > 28.1 25.0us 18.0us
-384 16.9 11.9 > 29.6 33.8us 23.8us
-448 22.2 15.2 > 31.7 44.4us 30.4us
-512 28.3 19.0 > 32.7 56.6us 38.0us
-640 42.4 28.0 > 34.0 84.8us 56.0us
-768 59.4 38.5 > 35.2 118.8us 77.0us
-896 79.5 51.2 > 35.6 159.0us 102.4us
-1024 102.6 65.5 > 36.2 205.2us 131.0us
-1536 224.3 140.6 > 37.3 448.6us 281.2us
-2048 393.4 244.3 > 37.9 786.8us 488.6us
-
-------------------------------------------------------------------
- This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-$Id$
-
-
diff --git a/security/nss/lib/freebl/mpi/hpma512.s b/security/nss/lib/freebl/mpi/hpma512.s
deleted file mode 100644
index ae9da630d..000000000
--- a/security/nss/lib/freebl/mpi/hpma512.s
+++ /dev/null
@@ -1,615 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- *
- * This PA-RISC 2.0 function computes the product of two unsigned integers,
- * and adds the result to a previously computed integer. The multiplicand
- * is a 512-bit (64-byte, eight doubleword) unsigned integer, stored in
- * memory in little-double-wordian order. The multiplier is an unsigned
- * 64-bit integer. The previously computed integer to which the product is
- * added is located in the result ("res") area, and is assumed to be a
- * 576-bit (72-byte, nine doubleword) unsigned integer, stored in memory
- * in little-double-wordian order. This value normally will be the result
- * of a previously computed nine doubleword result. It is not necessary
- * to pad the multiplicand with an additional 64-bit zero doubleword.
- *
- * Multiplicand, multiplier, and addend ideally should be aligned at
- * 16-byte boundaries for best performance. The code will function
- * correctly for alignment at eight-byte boundaries which are not 16-byte
- * boundaries, but the execution may be slightly slower due to even/odd
- * bank conflicts on PA-RISC 8000 processors.
- *
- * This function is designed to accept the same calling sequence as Bill
- * Ackerman's "maxpy_little" function. The carry from the ninth doubleword
- * of the result is written to the tenth word of the result, as is done by
- * Bill Ackerman's function. The final carry also is returned as an
- * integer, which may be ignored. The function prototype may be either
- * of the following:
- *
- * void multacc512( int l, chunk* m, const chunk* a, chunk* res );
- * or
- * int multacc512( int l, chunk* m, const chunk* a, chunk* res );
- *
- * where: "l" originally denoted vector lengths. This parameter is
- * ignored. This function always assumes a multiplicand length of
- * 512 bits (eight doublewords), and addend and result lengths of
- * 576 bits (nine doublewords).
- *
- * "m" is a pointer to the doubleword multiplier, ideally aligned
- * on a 16-byte boundary.
- *
- * "a" is a pointer to the eight-doubleword multiplicand, stored
- * in little-double-wordian order, and ideally aligned on a 16-byte
- * boundary.
- *
- * "res" is a pointer to the nine doubleword addend, and to the
- * nine-doubleword product computed by this function. The result
- * also is stored in little-double-wordian order, and ideally is
- * aligned on a 16-byte boundary. It is expected that the alignment
- * of the "res" area may alternate between even/odd doubleword
- * boundaries for successive calls for 512-bit x 512-bit
- * multiplications.
- *
- * The code for this function has been scheduled to use the parallelism
- * of the PA-RISC 8000 series microprocessors as well as the author was
- * able. Comments and/or suggestions for improvement are welcomed.
- *
- * The code is "64-bit safe". This means it may be called in either
- * the 32ILP context or the 64LP context. All 64-bits of registers are
- * saved and restored.
- *
- * This code is self-contained. It requires no other header files in order
- * to compile and to be linkable on a PA-RISC 2.0 machine. Symbolic
- * definitions for registers and stack offsets are included within this
- * one source file.
- *
- * This is a leaf routine. As such, minimal use is made of the stack area.
- * Of the 192 bytes allocated, 64 bytes are used for saving/restoring eight
- * general registers, and 128 bytes are used to move intermediate products
- * from the floating-point registers to the general registers. Stack
- * protocols assure proper alignment of these areas.
- *
- */
-
-
-/* ====================================================================*/
-/* symbolic definitions for PA-RISC registers */
-/* in the MIPS style, avoids lots of case shifts */
-/* assigments (except t4) preserve register number parity */
-/* ====================================================================*/
-
-#define zero %r0 /* permanent zero */
-#define t5 %r1 /* temp register, altered by addil */
-
-#define rp %r2 /* return pointer */
-
-#define s1 %r3 /* callee saves register*/
-#define s0 %r4 /* callee saves register*/
-#define s3 %r5 /* callee saves register*/
-#define s2 %r6 /* callee saves register*/
-#define s5 %r7 /* callee saves register*/
-#define s4 %r8 /* callee saves register*/
-#define s7 %r9 /* callee saves register*/
-#define s6 %r10 /* callee saves register*/
-
-#define t1 %r19 /* caller saves register*/
-#define t0 %r20 /* caller saves register*/
-#define t3 %r21 /* caller saves register*/
-#define t2 %r22 /* caller saves register*/
-
-#define a3 %r23 /* fourth argument register, high word */
-#define a2 %r24 /* third argument register, low word*/
-#define a1 %r25 /* second argument register, high word*/
-#define a0 %r26 /* first argument register, low word*/
-
-#define v0 %r28 /* high order return value*/
-#define v1 %r29 /* low order return value*/
-
-#define sp %r30 /* stack pointer*/
-#define t4 %r31 /* temporary register */
-
-#define fa0 %fr4 /* first argument register*/
-#define fa1 %fr5 /* second argument register*/
-#define fa2 %fr6 /* third argument register*/
-#define fa3 %fr7 /* fourth argument register*/
-
-#define fa0r %fr4R /* first argument register*/
-#define fa1r %fr5R /* second argument register*/
-#define fa2r %fr6R /* third argument register*/
-#define fa3r %fr7R /* fourth argument register*/
-
-#define ft0 %fr8 /* caller saves register*/
-#define ft1 %fr9 /* caller saves register*/
-#define ft2 %fr10 /* caller saves register*/
-#define ft3 %fr11 /* caller saves register*/
-
-#define ft0r %fr8R /* caller saves register*/
-#define ft1r %fr9R /* caller saves register*/
-#define ft2r %fr10R /* caller saves register*/
-#define ft3r %fr11R /* caller saves register*/
-
-#define ft4 %fr22 /* caller saves register*/
-#define ft5 %fr23 /* caller saves register*/
-#define ft6 %fr24 /* caller saves register*/
-#define ft7 %fr25 /* caller saves register*/
-#define ft8 %fr26 /* caller saves register*/
-#define ft9 %fr27 /* caller saves register*/
-#define ft10 %fr28 /* caller saves register*/
-#define ft11 %fr29 /* caller saves register*/
-#define ft12 %fr30 /* caller saves register*/
-#define ft13 %fr31 /* caller saves register*/
-
-#define ft4r %fr22R /* caller saves register*/
-#define ft5r %fr23R /* caller saves register*/
-#define ft6r %fr24R /* caller saves register*/
-#define ft7r %fr25R /* caller saves register*/
-#define ft8r %fr26R /* caller saves register*/
-#define ft9r %fr27R /* caller saves register*/
-#define ft10r %fr28R /* caller saves register*/
-#define ft11r %fr29R /* caller saves register*/
-#define ft12r %fr30R /* caller saves register*/
-#define ft13r %fr31R /* caller saves register*/
-
-
-
-/* ================================================================== */
-/* functional definitions for PA-RISC registers */
-/* ================================================================== */
-
-/* general registers */
-
-#define T1 a0 /* temp, (length parameter ignored) */
-
-#define pM a1 /* -> 64-bit multiplier */
-#define T2 a1 /* temp, (after fetching multiplier) */
-
-#define pA a2 /* -> multiplicand vector (8 64-bit words) */
-#define T3 a2 /* temp, (after fetching multiplicand) */
-
-#define pR a3 /* -> addend vector (8 64-bit doublewords,
- result vector (9 64-bit words) */
-
-#define S0 s0 /* callee saves summand registers */
-#define S1 s1
-#define S2 s2
-#define S3 s3
-#define S4 s4
-#define S5 s5
-#define S6 s6
-#define S7 s7
-
-#define S8 v0 /* caller saves summand registers */
-#define S9 v1
-#define S10 t0
-#define S11 t1
-#define S12 t2
-#define S13 t3
-#define S14 t4
-#define S15 t5
-
-
-
-/* floating-point registers */
-
-#define M fa0 /* multiplier double word */
-#define MR fa0r /* low order half of multiplier double word */
-#define ML fa0 /* high order half of multiplier double word */
-
-#define A0 fa2 /* multiplicand double word 0 */
-#define A0R fa2r /* low order half of multiplicand double word */
-#define A0L fa2 /* high order half of multiplicand double word */
-
-#define A1 fa3 /* multiplicand double word 1 */
-#define A1R fa3r /* low order half of multiplicand double word */
-#define A1L fa3 /* high order half of multiplicand double word */
-
-#define A2 ft0 /* multiplicand double word 2 */
-#define A2R ft0r /* low order half of multiplicand double word */
-#define A2L ft0 /* high order half of multiplicand double word */
-
-#define A3 ft1 /* multiplicand double word 3 */
-#define A3R ft1r /* low order half of multiplicand double word */
-#define A3L ft1 /* high order half of multiplicand double word */
-
-#define A4 ft2 /* multiplicand double word 4 */
-#define A4R ft2r /* low order half of multiplicand double word */
-#define A4L ft2 /* high order half of multiplicand double word */
-
-#define A5 ft3 /* multiplicand double word 5 */
-#define A5R ft3r /* low order half of multiplicand double word */
-#define A5L ft3 /* high order half of multiplicand double word */
-
-#define A6 ft4 /* multiplicand double word 6 */
-#define A6R ft4r /* low order half of multiplicand double word */
-#define A6L ft4 /* high order half of multiplicand double word */
-
-#define A7 ft5 /* multiplicand double word 7 */
-#define A7R ft5r /* low order half of multiplicand double word */
-#define A7L ft5 /* high order half of multiplicand double word */
-
-#define P0 ft6 /* product word 0 */
-#define P1 ft7 /* product word 0 */
-#define P2 ft8 /* product word 0 */
-#define P3 ft9 /* product word 0 */
-#define P4 ft10 /* product word 0 */
-#define P5 ft11 /* product word 0 */
-#define P6 ft12 /* product word 0 */
-#define P7 ft13 /* product word 0 */
-
-
-
-
-/* ====================================================================== */
-/* symbolic definitions for HP-UX stack offsets */
-/* symbolic definitions for memory NOPs */
-/* ====================================================================== */
-
-#define ST_SZ 192 /* stack area total size */
-
-#define SV0 -192(sp) /* general register save area */
-#define SV1 -184(sp)
-#define SV2 -176(sp)
-#define SV3 -168(sp)
-#define SV4 -160(sp)
-#define SV5 -152(sp)
-#define SV6 -144(sp)
-#define SV7 -136(sp)
-
-#define XF0 -128(sp) /* data transfer area */
-#define XF1 -120(sp) /* for floating-pt to integer regs */
-#define XF2 -112(sp)
-#define XF3 -104(sp)
-#define XF4 -96(sp)
-#define XF5 -88(sp)
-#define XF6 -80(sp)
-#define XF7 -72(sp)
-#define XF8 -64(sp)
-#define XF9 -56(sp)
-#define XF10 -48(sp)
-#define XF11 -40(sp)
-#define XF12 -32(sp)
-#define XF13 -24(sp)
-#define XF14 -16(sp)
-#define XF15 -8(sp)
-
-#define mnop proberi (sp),3,zero /* memory NOP */
-
-
-
-
-/* ====================================================================== */
-/* assembler formalities */
-/* ====================================================================== */
-
-#ifdef __LP64__
- .level 2.0W
-#else
- .level 2.0
-#endif
- .space $TEXT$
- .subspa $CODE$
- .align 16
-
-/* ====================================================================== */
-/* here to compute 64-bit x 512-bit product + 512-bit addend */
-/* ====================================================================== */
-
-multacc512
- .PROC
- .CALLINFO
- .ENTRY
- fldd 0(pM),M ; multiplier double word
- ldo ST_SZ(sp),sp ; push stack
-
- fldd 0(pA),A0 ; multiplicand double word 0
- std S1,SV1 ; save s1
-
- fldd 16(pA),A2 ; multiplicand double word 2
- std S3,SV3 ; save s3
-
- fldd 32(pA),A4 ; multiplicand double word 4
- std S5,SV5 ; save s5
-
- fldd 48(pA),A6 ; multiplicand double word 6
- std S7,SV7 ; save s7
-
-
- std S0,SV0 ; save s0
- fldd 8(pA),A1 ; multiplicand double word 1
- xmpyu MR,A0L,P0 ; A0 cross 32-bit word products
- xmpyu ML,A0R,P2
-
- std S2,SV2 ; save s2
- fldd 24(pA),A3 ; multiplicand double word 3
- xmpyu MR,A2L,P4 ; A2 cross 32-bit word products
- xmpyu ML,A2R,P6
-
- std S4,SV4 ; save s4
- fldd 40(pA),A5 ; multiplicand double word 5
-
- std S6,SV6 ; save s6
- fldd 56(pA),A7 ; multiplicand double word 7
-
-
- fstd P0,XF0 ; MR * A0L
- xmpyu MR,A0R,P0 ; A0 right 32-bit word product
- xmpyu MR,A1L,P1 ; A1 cross 32-bit word product
-
- fstd P2,XF2 ; ML * A0R
- xmpyu ML,A0L,P2 ; A0 left 32-bit word product
- xmpyu ML,A1R,P3 ; A1 cross 32-bit word product
-
- fstd P4,XF4 ; MR * A2L
- xmpyu MR,A2R,P4 ; A2 right 32-bit word product
- xmpyu MR,A3L,P5 ; A3 cross 32-bit word product
-
- fstd P6,XF6 ; ML * A2R
- xmpyu ML,A2L,P6 ; A2 parallel 32-bit word product
- xmpyu ML,A3R,P7 ; A3 cross 32-bit word product
-
-
- ldd XF0,S0 ; MR * A0L
- fstd P1,XF1 ; MR * A1L
-
- ldd XF2,S2 ; ML * A0R
- fstd P3,XF3 ; ML * A1R
-
- ldd XF4,S4 ; MR * A2L
- fstd P5,XF5 ; MR * A3L
- xmpyu MR,A1R,P1 ; A1 parallel 32-bit word products
- xmpyu ML,A1L,P3
-
- ldd XF6,S6 ; ML * A2R
- fstd P7,XF7 ; ML * A3R
- xmpyu MR,A3R,P5 ; A3 parallel 32-bit word products
- xmpyu ML,A3L,P7
-
-
- fstd P0,XF0 ; MR * A0R
- ldd XF1,S1 ; MR * A1L
- nop
- add S0,S2,T1 ; A0 cross product sum
-
- fstd P2,XF2 ; ML * A0L
- ldd XF3,S3 ; ML * A1R
- add,dc zero,zero,S0 ; A0 cross product sum carry
- depd,z T1,31,32,S2 ; A0 cross product sum << 32
-
- fstd P4,XF4 ; MR * A2R
- ldd XF5,S5 ; MR * A3L
- shrpd S0,T1,32,S0 ; A0 carry | cross product sum >> 32
- add S4,S6,T3 ; A2 cross product sum
-
- fstd P6,XF6 ; ML * A2L
- ldd XF7,S7 ; ML * A3R
- add,dc zero,zero,S4 ; A2 cross product sum carry
- depd,z T3,31,32,S6 ; A2 cross product sum << 32
-
-
- ldd XF0,S8 ; MR * A0R
- fstd P1,XF1 ; MR * A1R
- xmpyu MR,A4L,P0 ; A4 cross 32-bit word product
- xmpyu MR,A5L,P1 ; A5 cross 32-bit word product
-
- ldd XF2,S10 ; ML * A0L
- fstd P3,XF3 ; ML * A1L
- xmpyu ML,A4R,P2 ; A4 cross 32-bit word product
- xmpyu ML,A5R,P3 ; A5 cross 32-bit word product
-
- ldd XF4,S12 ; MR * A2R
- fstd P5,XF5 ; MR * A3L
- xmpyu MR,A6L,P4 ; A6 cross 32-bit word product
- xmpyu MR,A7L,P5 ; A7 cross 32-bit word product
-
- ldd XF6,S14 ; ML * A2L
- fstd P7,XF7 ; ML * A3L
- xmpyu ML,A6R,P6 ; A6 cross 32-bit word product
- xmpyu ML,A7R,P7 ; A7 cross 32-bit word product
-
-
- fstd P0,XF0 ; MR * A4L
- ldd XF1,S9 ; MR * A1R
- shrpd S4,T3,32,S4 ; A2 carry | cross product sum >> 32
- add S1,S3,T1 ; A1 cross product sum
-
- fstd P2,XF2 ; ML * A4R
- ldd XF3,S11 ; ML * A1L
- add,dc zero,zero,S1 ; A1 cross product sum carry
- depd,z T1,31,32,S3 ; A1 cross product sum << 32
-
- fstd P4,XF4 ; MR * A6L
- ldd XF5,S13 ; MR * A3R
- shrpd S1,T1,32,S1 ; A1 carry | cross product sum >> 32
- add S5,S7,T3 ; A3 cross product sum
-
- fstd P6,XF6 ; ML * A6R
- ldd XF7,S15 ; ML * A3L
- add,dc zero,zero,S5 ; A3 cross product sum carry
- depd,z T3,31,32,S7 ; A3 cross product sum << 32
-
-
- shrpd S5,T3,32,S5 ; A3 carry | cross product sum >> 32
- add S2,S8,S8 ; M * A0 right doubleword, P0 doubleword
-
- add,dc S0,S10,S10 ; M * A0 left doubleword
- add S3,S9,S9 ; M * A1 right doubleword
-
- add,dc S1,S11,S11 ; M * A1 left doubleword
- add S6,S12,S12 ; M * A2 right doubleword
-
-
- ldd 24(pR),S3 ; Addend word 3
- fstd P1,XF1 ; MR * A5L
- add,dc S4,S14,S14 ; M * A2 left doubleword
- xmpyu MR,A5R,P1 ; A5 right 32-bit word product
-
- ldd 8(pR),S1 ; Addend word 1
- fstd P3,XF3 ; ML * A5R
- add S7,S13,S13 ; M * A3 right doubleword
- xmpyu ML,A5L,P3 ; A5 left 32-bit word product
-
- ldd 0(pR),S7 ; Addend word 0
- fstd P5,XF5 ; MR * A7L
- add,dc S5,S15,S15 ; M * A3 left doubleword
- xmpyu MR,A7R,P5 ; A7 right 32-bit word product
-
- ldd 16(pR),S5 ; Addend word 2
- fstd P7,XF7 ; ML * A7R
- add S10,S9,S9 ; P1 doubleword
- xmpyu ML,A7L,P7 ; A7 left 32-bit word products
-
-
- ldd XF0,S0 ; MR * A4L
- fstd P1,XF9 ; MR * A5R
- add,dc S11,S12,S12 ; P2 doubleword
- xmpyu MR,A4R,P0 ; A4 right 32-bit word product
-
- ldd XF2,S2 ; ML * A4R
- fstd P3,XF11 ; ML * A5L
- add,dc S14,S13,S13 ; P3 doubleword
- xmpyu ML,A4L,P2 ; A4 left 32-bit word product
-
- ldd XF6,S6 ; ML * A6R
- fstd P5,XF13 ; MR * A7R
- add,dc zero,S15,T2 ; P4 partial doubleword
- xmpyu MR,A6R,P4 ; A6 right 32-bit word product
-
- ldd XF4,S4 ; MR * A6L
- fstd P7,XF15 ; ML * A7L
- add S7,S8,S8 ; R0 + P0, new R0 doubleword
- xmpyu ML,A6L,P6 ; A6 left 32-bit word product
-
-
- fstd P0,XF0 ; MR * A4R
- ldd XF7,S7 ; ML * A7R
- add,dc S1,S9,S9 ; c + R1 + P1, new R1 doubleword
-
- fstd P2,XF2 ; ML * A4L
- ldd XF1,S1 ; MR * A5L
- add,dc S5,S12,S12 ; c + R2 + P2, new R2 doubleword
-
- fstd P4,XF4 ; MR * A6R
- ldd XF5,S5 ; MR * A7L
- add,dc S3,S13,S13 ; c + R3 + P3, new R3 doubleword
-
- fstd P6,XF6 ; ML * A6L
- ldd XF3,S3 ; ML * A5R
- add,dc zero,T2,T2 ; c + partial P4
- add S0,S2,T1 ; A4 cross product sum
-
-
- std S8,0(pR) ; save R0
- add,dc zero,zero,S0 ; A4 cross product sum carry
- depd,z T1,31,32,S2 ; A4 cross product sum << 32
-
- std S9,8(pR) ; save R1
- shrpd S0,T1,32,S0 ; A4 carry | cross product sum >> 32
- add S4,S6,T3 ; A6 cross product sum
-
- std S12,16(pR) ; save R2
- add,dc zero,zero,S4 ; A6 cross product sum carry
- depd,z T3,31,32,S6 ; A6 cross product sum << 32
-
-
- std S13,24(pR) ; save R3
- shrpd S4,T3,32,S4 ; A6 carry | cross product sum >> 32
- add S1,S3,T1 ; A5 cross product sum
-
- ldd XF0,S8 ; MR * A4R
- add,dc zero,zero,S1 ; A5 cross product sum carry
- depd,z T1,31,32,S3 ; A5 cross product sum << 32
-
- ldd XF2,S10 ; ML * A4L
- ldd XF9,S9 ; MR * A5R
- shrpd S1,T1,32,S1 ; A5 carry | cross product sum >> 32
- add S5,S7,T3 ; A7 cross product sum
-
- ldd XF4,S12 ; MR * A6R
- ldd XF11,S11 ; ML * A5L
- add,dc zero,zero,S5 ; A7 cross product sum carry
- depd,z T3,31,32,S7 ; A7 cross product sum << 32
-
- ldd XF6,S14 ; ML * A6L
- ldd XF13,S13 ; MR * A7R
- shrpd S5,T3,32,S5 ; A7 carry | cross product sum >> 32
- add S2,S8,S8 ; M * A4 right doubleword
-
-
- ldd XF15,S15 ; ML * A7L
- add,dc S0,S10,S10 ; M * A4 left doubleword
- add S3,S9,S9 ; M * A5 right doubleword
-
- add,dc S1,S11,S11 ; M * A5 left doubleword
- add S6,S12,S12 ; M * A6 right doubleword
-
- ldd 32(pR),S0 ; Addend word 4
- ldd 40(pR),S1 ; Addend word 5
- add,dc S4,S14,S14 ; M * A6 left doubleword
- add S7,S13,S13 ; M * A7 right doubleword
-
- ldd 48(pR),S2 ; Addend word 6
- ldd 56(pR),S3 ; Addend word 7
- add,dc S5,S15,S15 ; M * A7 left doubleword
- add S8,T2,S8 ; P4 doubleword
-
- ldd 64(pR),S4 ; Addend word 8
- ldd SV5,s5 ; restore s5
- add,dc S10,S9,S9 ; P5 doubleword
- add,dc S11,S12,S12 ; P6 doubleword
-
-
- ldd SV6,s6 ; restore s6
- ldd SV7,s7 ; restore s7
- add,dc S14,S13,S13 ; P7 doubleword
- add,dc zero,S15,S15 ; P8 doubleword
-
- add S0,S8,S8 ; new R4 doubleword
-
- ldd SV0,s0 ; restore s0
- std S8,32(pR) ; save R4
- add,dc S1,S9,S9 ; new R5 doubleword
-
- ldd SV1,s1 ; restore s1
- std S9,40(pR) ; save R5
- add,dc S2,S12,S12 ; new R6 doubleword
-
- ldd SV2,s2 ; restore s2
- std S12,48(pR) ; save R6
- add,dc S3,S13,S13 ; new R7 doubleword
-
- ldd SV3,s3 ; restore s3
- std S13,56(pR) ; save R7
- add,dc S4,S15,S15 ; new R8 doubleword
-
- ldd SV4,s4 ; restore s4
- std S15,64(pR) ; save result[8]
- add,dc zero,zero,v0 ; return carry from R8
-
- CMPIB,*= 0,v0,$L0 ; if no overflow, exit
- LDO 8(pR),pR
-
-$FINAL1 ; Final carry propagation
- LDD 64(pR),v0
- LDO 8(pR),pR
- ADDI 1,v0,v0
- CMPIB,*= 0,v0,$FINAL1 ; Keep looping if there is a carry.
- STD v0,56(pR)
-$L0
- bv zero(rp) ; -> caller
- ldo -ST_SZ(sp),sp ; pop stack
-
-/* ====================================================================== */
-/* end of module */
-/* ====================================================================== */
-
-
- bve (rp)
- .EXIT
- nop
- .PROCEND
- .SPACE $TEXT$
- .SUBSPA $CODE$
- .EXPORT multacc512,ENTRY
-
- .end
diff --git a/security/nss/lib/freebl/mpi/hppa20.s b/security/nss/lib/freebl/mpi/hppa20.s
deleted file mode 100644
index c72de8a12..000000000
--- a/security/nss/lib/freebl/mpi/hppa20.s
+++ /dev/null
@@ -1,904 +0,0 @@
-; This Source Code Form is subject to the terms of the Mozilla Public
-; License, v. 2.0. If a copy of the MPL was not distributed with this
-; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifdef __LP64__
- .LEVEL 2.0W
-#else
-; .LEVEL 1.1
-; .ALLOW 2.0N
- .LEVEL 2.0
-#endif
- .SPACE $TEXT$,SORT=8
- .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24
-
-; ***************************************************************
-;
-; maxpy_[little/big]
-;
-; ***************************************************************
-
-; There is no default -- you must specify one or the other.
-#define LITTLE_WORDIAN 1
-
-#ifdef LITTLE_WORDIAN
-#define EIGHT 8
-#define SIXTEEN 16
-#define THIRTY_TWO 32
-#define UN_EIGHT -8
-#define UN_SIXTEEN -16
-#define UN_TWENTY_FOUR -24
-#endif
-
-#ifdef BIG_WORDIAN
-#define EIGHT -8
-#define SIXTEEN -16
-#define THIRTY_TWO -32
-#define UN_EIGHT 8
-#define UN_SIXTEEN 16
-#define UN_TWENTY_FOUR 24
-#endif
-
-; This performs a multiple-precision integer version of "daxpy",
-; Using the selected addressing direction. "Little-wordian" means that
-; the least significant word of a number is stored at the lowest address.
-; "Big-wordian" means that the most significant word is at the lowest
-; address. Either way, the incoming address of the vector is that
-; of the least significant word. That means that, for little-wordian
-; addressing, we move the address upward as we propagate carries
-; from the least significant word to the most significant. For
-; big-wordian we move the address downward.
-
-; We use the following registers:
-;
-; r2 return PC, of course
-; r26 = arg1 = length
-; r25 = arg2 = address of scalar
-; r24 = arg3 = multiplicand vector
-; r23 = arg4 = result vector
-;
-; fr9 = scalar loaded once only from r25
-
-; The cycle counts shown in the bodies below are simply the result of a
-; scheduling by hand. The actual PCX-U hardware does it differently.
-; The intention is that the overall speed is the same.
-
-; The pipeline startup and shutdown code is constructed in the usual way,
-; by taking the loop bodies and removing unnecessary instructions.
-; We have left the comments describing cycle numbers in the code.
-; These are intended for reference when comparing with the main loop,
-; and have no particular relationship to actual cycle numbers.
-
-#ifdef LITTLE_WORDIAN
-maxpy_little
-#else
-maxpy_big
-#endif
- .PROC
- .CALLINFO FRAME=120,ENTRY_GR=4
- .ENTRY
- STW,MA %r3,128(%sp)
- STW %r4,-124(%sp)
-
- ADDIB,< -1,%r26,$L0 ; If N = 0, exit immediately.
- FLDD 0(%r25),%fr9 ; fr9 = scalar
-
-; First startup
-
- FLDD 0(%r24),%fr24 ; Cycle 1
- XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
- XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
- XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
- CMPIB,> 3,%r26,$N_IS_SMALL ; Pick out cases N = 1, 2, or 3
- XMPYU %fr9L,%fr24R,%fr24 ; Cycle 6
- FLDD EIGHT(%r24),%fr28 ; Cycle 8
- XMPYU %fr9L,%fr28R,%fr31 ; Cycle 10
- FSTD %fr24,-96(%sp)
- XMPYU %fr9R,%fr28L,%fr30 ; Cycle 11
- FSTD %fr25,-80(%sp)
- LDO SIXTEEN(%r24),%r24 ; Cycle 12
- FSTD %fr31,-64(%sp)
- XMPYU %fr9R,%fr28R,%fr29 ; Cycle 13
- FSTD %fr27,-48(%sp)
-
-; Second startup
-
- XMPYU %fr9L,%fr28L,%fr28 ; Cycle 1
- FSTD %fr30,-56(%sp)
- FLDD 0(%r24),%fr24
-
- FSTD %fr26,-88(%sp) ; Cycle 2
-
- XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
- FSTD %fr28,-104(%sp)
-
- XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
- LDD -96(%sp),%r3
- FSTD %fr29,-72(%sp)
-
- XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
- LDD -64(%sp),%r19
- LDD -80(%sp),%r21
-
- XMPYU %fr9L,%fr24R,%fr24 ; Cycle 6
- LDD -56(%sp),%r20
- ADD %r21,%r3,%r3
-
- ADD,DC %r20,%r19,%r19 ; Cycle 7
- LDD -88(%sp),%r4
- SHRPD %r3,%r0,32,%r21
- LDD -48(%sp),%r1
-
- FLDD EIGHT(%r24),%fr28 ; Cycle 8
- LDD -104(%sp),%r31
- ADD,DC %r0,%r0,%r20
- SHRPD %r19,%r3,32,%r3
-
- LDD -72(%sp),%r29 ; Cycle 9
- SHRPD %r20,%r19,32,%r20
- ADD %r21,%r1,%r1
-
- XMPYU %fr9L,%fr28R,%fr31 ; Cycle 10
- ADD,DC %r3,%r4,%r4
- FSTD %fr24,-96(%sp)
-
- XMPYU %fr9R,%fr28L,%fr30 ; Cycle 11
- ADD,DC %r0,%r20,%r20
- LDD 0(%r23),%r3
- FSTD %fr25,-80(%sp)
-
- LDO SIXTEEN(%r24),%r24 ; Cycle 12
- FSTD %fr31,-64(%sp)
-
- XMPYU %fr9R,%fr28R,%fr29 ; Cycle 13
- ADD %r0,%r0,%r0 ; clear the carry bit
- ADDIB,<= -4,%r26,$ENDLOOP ; actually happens in cycle 12
- FSTD %fr27,-48(%sp)
-; MFCTL %cr16,%r21 ; for timing
-; STD %r21,-112(%sp)
-
-; Here is the loop.
-
-$LOOP XMPYU %fr9L,%fr28L,%fr28 ; Cycle 1
- ADD,DC %r29,%r4,%r4
- FSTD %fr30,-56(%sp)
- FLDD 0(%r24),%fr24
-
- LDO SIXTEEN(%r23),%r23 ; Cycle 2
- ADD,DC %r0,%r20,%r20
- FSTD %fr26,-88(%sp)
-
- XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
- ADD %r3,%r1,%r1
- FSTD %fr28,-104(%sp)
- LDD UN_EIGHT(%r23),%r21
-
- XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
- ADD,DC %r21,%r4,%r28
- FSTD %fr29,-72(%sp)
- LDD -96(%sp),%r3
-
- XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
- ADD,DC %r20,%r31,%r22
- LDD -64(%sp),%r19
- LDD -80(%sp),%r21
-
- XMPYU %fr9L,%fr24R,%fr24 ; Cycle 6
- ADD %r21,%r3,%r3
- LDD -56(%sp),%r20
- STD %r1,UN_SIXTEEN(%r23)
-
- ADD,DC %r20,%r19,%r19 ; Cycle 7
- SHRPD %r3,%r0,32,%r21
- LDD -88(%sp),%r4
- LDD -48(%sp),%r1
-
- ADD,DC %r0,%r0,%r20 ; Cycle 8
- SHRPD %r19,%r3,32,%r3
- FLDD EIGHT(%r24),%fr28
- LDD -104(%sp),%r31
-
- SHRPD %r20,%r19,32,%r20 ; Cycle 9
- ADD %r21,%r1,%r1
- STD %r28,UN_EIGHT(%r23)
- LDD -72(%sp),%r29
-
- XMPYU %fr9L,%fr28R,%fr31 ; Cycle 10
- ADD,DC %r3,%r4,%r4
- FSTD %fr24,-96(%sp)
-
- XMPYU %fr9R,%fr28L,%fr30 ; Cycle 11
- ADD,DC %r0,%r20,%r20
- FSTD %fr25,-80(%sp)
- LDD 0(%r23),%r3
-
- LDO SIXTEEN(%r24),%r24 ; Cycle 12
- FSTD %fr31,-64(%sp)
-
- XMPYU %fr9R,%fr28R,%fr29 ; Cycle 13
- ADD %r22,%r1,%r1
- ADDIB,> -2,%r26,$LOOP ; actually happens in cycle 12
- FSTD %fr27,-48(%sp)
-
-$ENDLOOP
-
-; Shutdown code, first stage.
-
-; MFCTL %cr16,%r21 ; for timing
-; STD %r21,UN_SIXTEEN(%r23)
-; LDD -112(%sp),%r21
-; STD %r21,UN_EIGHT(%r23)
-
- XMPYU %fr9L,%fr28L,%fr28 ; Cycle 1
- ADD,DC %r29,%r4,%r4
- CMPIB,= 0,%r26,$ONEMORE
- FSTD %fr30,-56(%sp)
-
- LDO SIXTEEN(%r23),%r23 ; Cycle 2
- ADD,DC %r0,%r20,%r20
- FSTD %fr26,-88(%sp)
-
- ADD %r3,%r1,%r1 ; Cycle 3
- FSTD %fr28,-104(%sp)
- LDD UN_EIGHT(%r23),%r21
-
- ADD,DC %r21,%r4,%r28 ; Cycle 4
- FSTD %fr29,-72(%sp)
- STD %r28,UN_EIGHT(%r23) ; moved up from cycle 9
- LDD -96(%sp),%r3
-
- ADD,DC %r20,%r31,%r22 ; Cycle 5
- STD %r1,UN_SIXTEEN(%r23)
-$JOIN4
- LDD -64(%sp),%r19
- LDD -80(%sp),%r21
-
- ADD %r21,%r3,%r3 ; Cycle 6
- LDD -56(%sp),%r20
-
- ADD,DC %r20,%r19,%r19 ; Cycle 7
- SHRPD %r3,%r0,32,%r21
- LDD -88(%sp),%r4
- LDD -48(%sp),%r1
-
- ADD,DC %r0,%r0,%r20 ; Cycle 8
- SHRPD %r19,%r3,32,%r3
- LDD -104(%sp),%r31
-
- SHRPD %r20,%r19,32,%r20 ; Cycle 9
- ADD %r21,%r1,%r1
- LDD -72(%sp),%r29
-
- ADD,DC %r3,%r4,%r4 ; Cycle 10
-
- ADD,DC %r0,%r20,%r20 ; Cycle 11
- LDD 0(%r23),%r3
-
- ADD %r22,%r1,%r1 ; Cycle 13
-
-; Shutdown code, second stage.
-
- ADD,DC %r29,%r4,%r4 ; Cycle 1
-
- LDO SIXTEEN(%r23),%r23 ; Cycle 2
- ADD,DC %r0,%r20,%r20
-
- LDD UN_EIGHT(%r23),%r21 ; Cycle 3
- ADD %r3,%r1,%r1
-
- ADD,DC %r21,%r4,%r28 ; Cycle 4
-
- ADD,DC %r20,%r31,%r22 ; Cycle 5
-
- STD %r1,UN_SIXTEEN(%r23); Cycle 6
-
- STD %r28,UN_EIGHT(%r23) ; Cycle 9
-
- LDD 0(%r23),%r3 ; Cycle 11
-
-; Shutdown code, third stage.
-
- LDO SIXTEEN(%r23),%r23
- ADD %r3,%r22,%r1
-$JOIN1 ADD,DC %r0,%r0,%r21
- CMPIB,*= 0,%r21,$L0 ; if no overflow, exit
- STD %r1,UN_SIXTEEN(%r23)
-
-; Final carry propagation
-
-$FINAL1 LDO EIGHT(%r23),%r23
- LDD UN_SIXTEEN(%r23),%r21
- ADDI 1,%r21,%r21
- CMPIB,*= 0,%r21,$FINAL1 ; Keep looping if there is a carry.
- STD %r21,UN_SIXTEEN(%r23)
- B $L0
- NOP
-
-; Here is the code that handles the difficult cases N=1, N=2, and N=3.
-; We do the usual trick -- branch out of the startup code at appropriate
-; points, and branch into the shutdown code.
-
-$N_IS_SMALL
- CMPIB,= 0,%r26,$N_IS_ONE
- FSTD %fr24,-96(%sp) ; Cycle 10
- FLDD EIGHT(%r24),%fr28 ; Cycle 8
- XMPYU %fr9L,%fr28R,%fr31 ; Cycle 10
- XMPYU %fr9R,%fr28L,%fr30 ; Cycle 11
- FSTD %fr25,-80(%sp)
- FSTD %fr31,-64(%sp) ; Cycle 12
- XMPYU %fr9R,%fr28R,%fr29 ; Cycle 13
- FSTD %fr27,-48(%sp)
- XMPYU %fr9L,%fr28L,%fr28 ; Cycle 1
- CMPIB,= 2,%r26,$N_IS_THREE
- FSTD %fr30,-56(%sp)
-
-; N = 2
- FSTD %fr26,-88(%sp) ; Cycle 2
- FSTD %fr28,-104(%sp) ; Cycle 3
- LDD -96(%sp),%r3 ; Cycle 4
- FSTD %fr29,-72(%sp)
- B $JOIN4
- ADD %r0,%r0,%r22
-
-$N_IS_THREE
- FLDD SIXTEEN(%r24),%fr24
- FSTD %fr26,-88(%sp) ; Cycle 2
- XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
- FSTD %fr28,-104(%sp)
- XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
- LDD -96(%sp),%r3
- FSTD %fr29,-72(%sp)
- XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
- LDD -64(%sp),%r19
- LDD -80(%sp),%r21
- B $JOIN3
- ADD %r0,%r0,%r22
-
-$N_IS_ONE
- FSTD %fr25,-80(%sp)
- FSTD %fr27,-48(%sp)
- FSTD %fr26,-88(%sp) ; Cycle 2
- B $JOIN5
- ADD %r0,%r0,%r22
-
-; We came out of the unrolled loop with wrong parity. Do one more
-; single cycle. This is quite tricky, because of the way the
-; carry chains and SHRPD chains have been chopped up.
-
-$ONEMORE
-
- FLDD 0(%r24),%fr24
-
- LDO SIXTEEN(%r23),%r23 ; Cycle 2
- ADD,DC %r0,%r20,%r20
- FSTD %fr26,-88(%sp)
-
- XMPYU %fr9R,%fr24R,%fr27 ; Cycle 3
- FSTD %fr28,-104(%sp)
- LDD UN_EIGHT(%r23),%r21
- ADD %r3,%r1,%r1
-
- XMPYU %fr9R,%fr24L,%fr25 ; Cycle 4
- ADD,DC %r21,%r4,%r28
- STD %r28,UN_EIGHT(%r23) ; moved from cycle 9
- LDD -96(%sp),%r3
- FSTD %fr29,-72(%sp)
-
- XMPYU %fr9L,%fr24L,%fr26 ; Cycle 5
- ADD,DC %r20,%r31,%r22
- LDD -64(%sp),%r19
- LDD -80(%sp),%r21
-
- STD %r1,UN_SIXTEEN(%r23); Cycle 6
-$JOIN3
- XMPYU %fr9L,%fr24R,%fr24
- LDD -56(%sp),%r20
- ADD %r21,%r3,%r3
-
- ADD,DC %r20,%r19,%r19 ; Cycle 7
- LDD -88(%sp),%r4
- SHRPD %r3,%r0,32,%r21
- LDD -48(%sp),%r1
-
- LDD -104(%sp),%r31 ; Cycle 8
- ADD,DC %r0,%r0,%r20
- SHRPD %r19,%r3,32,%r3
-
- LDD -72(%sp),%r29 ; Cycle 9
- SHRPD %r20,%r19,32,%r20
- ADD %r21,%r1,%r1
-
- ADD,DC %r3,%r4,%r4 ; Cycle 10
- FSTD %fr24,-96(%sp)
-
- ADD,DC %r0,%r20,%r20 ; Cycle 11
- LDD 0(%r23),%r3
- FSTD %fr25,-80(%sp)
-
- ADD %r22,%r1,%r1 ; Cycle 13
- FSTD %fr27,-48(%sp)
-
-; Shutdown code, stage 1-1/2.
-
- ADD,DC %r29,%r4,%r4 ; Cycle 1
-
- LDO SIXTEEN(%r23),%r23 ; Cycle 2
- ADD,DC %r0,%r20,%r20
- FSTD %fr26,-88(%sp)
-
- LDD UN_EIGHT(%r23),%r21 ; Cycle 3
- ADD %r3,%r1,%r1
-
- ADD,DC %r21,%r4,%r28 ; Cycle 4
- STD %r28,UN_EIGHT(%r23) ; moved from cycle 9
-
- ADD,DC %r20,%r31,%r22 ; Cycle 5
- STD %r1,UN_SIXTEEN(%r23)
-$JOIN5
- LDD -96(%sp),%r3 ; moved from cycle 4
- LDD -80(%sp),%r21
- ADD %r21,%r3,%r3 ; Cycle 6
- ADD,DC %r0,%r0,%r19 ; Cycle 7
- LDD -88(%sp),%r4
- SHRPD %r3,%r0,32,%r21
- LDD -48(%sp),%r1
- SHRPD %r19,%r3,32,%r3 ; Cycle 8
- ADD %r21,%r1,%r1 ; Cycle 9
- ADD,DC %r3,%r4,%r4 ; Cycle 10
- LDD 0(%r23),%r3 ; Cycle 11
- ADD %r22,%r1,%r1 ; Cycle 13
-
-; Shutdown code, stage 2-1/2.
-
- ADD,DC %r0,%r4,%r4 ; Cycle 1
- LDO SIXTEEN(%r23),%r23 ; Cycle 2
- LDD UN_EIGHT(%r23),%r21 ; Cycle 3
- ADD %r3,%r1,%r1
- STD %r1,UN_SIXTEEN(%r23)
- ADD,DC %r21,%r4,%r1
- B $JOIN1
- LDO EIGHT(%r23),%r23
-
-; exit
-
-$L0
- LDW -124(%sp),%r4
- BVE (%r2)
- .EXIT
- LDW,MB -128(%sp),%r3
-
- .PROCEND
-
-; ***************************************************************
-;
-; add_diag_[little/big]
-;
-; ***************************************************************
-
-; The arguments are as follows:
-; r2 return PC, of course
-; r26 = arg1 = length
-; r25 = arg2 = vector to square
-; r24 = arg3 = result vector
-
-#ifdef LITTLE_WORDIAN
-add_diag_little
-#else
-add_diag_big
-#endif
- .PROC
- .CALLINFO FRAME=120,ENTRY_GR=4
- .ENTRY
- STW,MA %r3,128(%sp)
- STW %r4,-124(%sp)
-
- ADDIB,< -1,%r26,$Z0 ; If N=0, exit immediately.
- NOP
-
-; Startup code
-
- FLDD 0(%r25),%fr7 ; Cycle 2 (alternate body)
- XMPYU %fr7R,%fr7R,%fr29 ; Cycle 4
- XMPYU %fr7L,%fr7R,%fr27 ; Cycle 5
- XMPYU %fr7L,%fr7L,%fr30
- LDO SIXTEEN(%r25),%r25 ; Cycle 6
- FSTD %fr29,-88(%sp)
- FSTD %fr27,-72(%sp) ; Cycle 7
- CMPIB,= 0,%r26,$DIAG_N_IS_ONE ; Cycle 1 (main body)
- FSTD %fr30,-96(%sp)
- FLDD UN_EIGHT(%r25),%fr7 ; Cycle 2
- LDD -88(%sp),%r22 ; Cycle 3
- LDD -72(%sp),%r31 ; Cycle 4
- XMPYU %fr7R,%fr7R,%fr28
- XMPYU %fr7L,%fr7R,%fr24 ; Cycle 5
- XMPYU %fr7L,%fr7L,%fr31
- LDD -96(%sp),%r20 ; Cycle 6
- FSTD %fr28,-80(%sp)
- ADD %r0,%r0,%r0 ; clear the carry bit
- ADDIB,<= -2,%r26,$ENDDIAGLOOP ; Cycle 7
- FSTD %fr24,-64(%sp)
-
-; Here is the loop. It is unrolled twice, modelled after the "alternate body" and then the "main body".
-
-$DIAGLOOP
- SHRPD %r31,%r0,31,%r3 ; Cycle 1 (alternate body)
- LDO SIXTEEN(%r25),%r25
- LDD 0(%r24),%r1
- FSTD %fr31,-104(%sp)
- SHRPD %r0,%r31,31,%r4 ; Cycle 2
- ADD,DC %r22,%r3,%r3
- FLDD UN_SIXTEEN(%r25),%fr7
- ADD,DC %r0,%r20,%r20 ; Cycle 3
- ADD %r1,%r3,%r3
- XMPYU %fr7R,%fr7R,%fr29 ; Cycle 4
- LDD -80(%sp),%r21
- STD %r3,0(%r24)
- XMPYU %fr7L,%fr7R,%fr27 ; Cycle 5
- XMPYU %fr7L,%fr7L,%fr30
- LDD -64(%sp),%r29
- LDD EIGHT(%r24),%r1
- ADD,DC %r4,%r20,%r20 ; Cycle 6
- LDD -104(%sp),%r19
- FSTD %fr29,-88(%sp)
- ADD %r20,%r1,%r1 ; Cycle 7
- FSTD %fr27,-72(%sp)
- SHRPD %r29,%r0,31,%r4 ; Cycle 1 (main body)
- LDO THIRTY_TWO(%r24),%r24
- LDD UN_SIXTEEN(%r24),%r28
- FSTD %fr30,-96(%sp)
- SHRPD %r0,%r29,31,%r3 ; Cycle 2
- ADD,DC %r21,%r4,%r4
- FLDD UN_EIGHT(%r25),%fr7
- STD %r1,UN_TWENTY_FOUR(%r24)
- ADD,DC %r0,%r19,%r19 ; Cycle 3
- ADD %r28,%r4,%r4
- XMPYU %fr7R,%fr7R,%fr28 ; Cycle 4
- LDD -88(%sp),%r22
- STD %r4,UN_SIXTEEN(%r24)
- XMPYU %fr7L,%fr7R,%fr24 ; Cycle 5
- XMPYU %fr7L,%fr7L,%fr31
- LDD -72(%sp),%r31
- LDD UN_EIGHT(%r24),%r28
- ADD,DC %r3,%r19,%r19 ; Cycle 6
- LDD -96(%sp),%r20
- FSTD %fr28,-80(%sp)
- ADD %r19,%r28,%r28 ; Cycle 7
- FSTD %fr24,-64(%sp)
- ADDIB,> -2,%r26,$DIAGLOOP ; Cycle 8
- STD %r28,UN_EIGHT(%r24)
-
-$ENDDIAGLOOP
-
- ADD,DC %r0,%r22,%r22
- CMPIB,= 0,%r26,$ONEMOREDIAG
- SHRPD %r31,%r0,31,%r3
-
-; Shutdown code, first stage.
-
- FSTD %fr31,-104(%sp) ; Cycle 1 (alternate body)
- LDD 0(%r24),%r28
- SHRPD %r0,%r31,31,%r4 ; Cycle 2
- ADD %r3,%r22,%r3
- ADD,DC %r0,%r20,%r20 ; Cycle 3
- LDD -80(%sp),%r21
- ADD %r3,%r28,%r3
- LDD -64(%sp),%r29 ; Cycle 4
- STD %r3,0(%r24)
- LDD EIGHT(%r24),%r1 ; Cycle 5
- LDO SIXTEEN(%r25),%r25 ; Cycle 6
- LDD -104(%sp),%r19
- ADD,DC %r4,%r20,%r20
- ADD %r20,%r1,%r1 ; Cycle 7
- ADD,DC %r0,%r21,%r21 ; Cycle 8
- STD %r1,EIGHT(%r24)
-
-; Shutdown code, second stage.
-
- SHRPD %r29,%r0,31,%r4 ; Cycle 1 (main body)
- LDO THIRTY_TWO(%r24),%r24
- LDD UN_SIXTEEN(%r24),%r1
- SHRPD %r0,%r29,31,%r3 ; Cycle 2
- ADD %r4,%r21,%r4
- ADD,DC %r0,%r19,%r19 ; Cycle 3
- ADD %r4,%r1,%r4
- STD %r4,UN_SIXTEEN(%r24); Cycle 4
- LDD UN_EIGHT(%r24),%r28 ; Cycle 5
- ADD,DC %r3,%r19,%r19 ; Cycle 6
- ADD %r19,%r28,%r28 ; Cycle 7
- ADD,DC %r0,%r0,%r22 ; Cycle 8
- CMPIB,*= 0,%r22,$Z0 ; if no overflow, exit
- STD %r28,UN_EIGHT(%r24)
-
-; Final carry propagation
-
-$FDIAG2
- LDO EIGHT(%r24),%r24
- LDD UN_EIGHT(%r24),%r26
- ADDI 1,%r26,%r26
- CMPIB,*= 0,%r26,$FDIAG2 ; Keep looping if there is a carry.
- STD %r26,UN_EIGHT(%r24)
-
- B $Z0
- NOP
-
-; Here is the code that handles the difficult case N=1.
-; We do the usual trick -- branch out of the startup code at appropriate
-; points, and branch into the shutdown code.
-
-$DIAG_N_IS_ONE
-
- LDD -88(%sp),%r22
- LDD -72(%sp),%r31
- B $JOINDIAG
- LDD -96(%sp),%r20
-
-; We came out of the unrolled loop with wrong parity. Do one more
-; single cycle. This is the "alternate body". It will, of course,
-; give us opposite registers from the other case, so we need
-; completely different shutdown code.
-
-$ONEMOREDIAG
- FSTD %fr31,-104(%sp) ; Cycle 1 (alternate body)
- LDD 0(%r24),%r28
- FLDD 0(%r25),%fr7 ; Cycle 2
- SHRPD %r0,%r31,31,%r4
- ADD %r3,%r22,%r3
- ADD,DC %r0,%r20,%r20 ; Cycle 3
- LDD -80(%sp),%r21
- ADD %r3,%r28,%r3
- LDD -64(%sp),%r29 ; Cycle 4
- STD %r3,0(%r24)
- XMPYU %fr7R,%fr7R,%fr29
- LDD EIGHT(%r24),%r1 ; Cycle 5
- XMPYU %fr7L,%fr7R,%fr27
- XMPYU %fr7L,%fr7L,%fr30
- LDD -104(%sp),%r19 ; Cycle 6
- FSTD %fr29,-88(%sp)
- ADD,DC %r4,%r20,%r20
- FSTD %fr27,-72(%sp) ; Cycle 7
- ADD %r20,%r1,%r1
- ADD,DC %r0,%r21,%r21 ; Cycle 8
- STD %r1,EIGHT(%r24)
-
-; Shutdown code, first stage.
-
- SHRPD %r29,%r0,31,%r4 ; Cycle 1 (main body)
- LDO THIRTY_TWO(%r24),%r24
- FSTD %fr30,-96(%sp)
- LDD UN_SIXTEEN(%r24),%r1
- SHRPD %r0,%r29,31,%r3 ; Cycle 2
- ADD %r4,%r21,%r4
- ADD,DC %r0,%r19,%r19 ; Cycle 3
- LDD -88(%sp),%r22
- ADD %r4,%r1,%r4
- LDD -72(%sp),%r31 ; Cycle 4
- STD %r4,UN_SIXTEEN(%r24)
- LDD UN_EIGHT(%r24),%r28 ; Cycle 5
- LDD -96(%sp),%r20 ; Cycle 6
- ADD,DC %r3,%r19,%r19
- ADD %r19,%r28,%r28 ; Cycle 7
- ADD,DC %r0,%r22,%r22 ; Cycle 8
- STD %r28,UN_EIGHT(%r24)
-
-; Shutdown code, second stage.
-
-$JOINDIAG
- SHRPD %r31,%r0,31,%r3 ; Cycle 1 (alternate body)
- LDD 0(%r24),%r28
- SHRPD %r0,%r31,31,%r4 ; Cycle 2
- ADD %r3,%r22,%r3
- ADD,DC %r0,%r20,%r20 ; Cycle 3
- ADD %r3,%r28,%r3
- STD %r3,0(%r24) ; Cycle 4
- LDD EIGHT(%r24),%r1 ; Cycle 5
- ADD,DC %r4,%r20,%r20
- ADD %r20,%r1,%r1 ; Cycle 7
- ADD,DC %r0,%r0,%r21 ; Cycle 8
- CMPIB,*= 0,%r21,$Z0 ; if no overflow, exit
- STD %r1,EIGHT(%r24)
-
-; Final carry propagation
-
-$FDIAG1
- LDO EIGHT(%r24),%r24
- LDD EIGHT(%r24),%r26
- ADDI 1,%r26,%r26
- CMPIB,*= 0,%r26,$FDIAG1 ; Keep looping if there is a carry.
- STD %r26,EIGHT(%r24)
-
-$Z0
- LDW -124(%sp),%r4
- BVE (%r2)
- .EXIT
- LDW,MB -128(%sp),%r3
- .PROCEND
-; .ALLOW
-
- .SPACE $TEXT$
- .SUBSPA $CODE$
-#ifdef LITTLE_WORDIAN
-#ifdef __GNUC__
-; GNU-as (as of 2.19) does not support LONG_RETURN
- .EXPORT maxpy_little,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
- .EXPORT add_diag_little,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR
-#else
- .EXPORT maxpy_little,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,LONG_RETURN
- .EXPORT add_diag_little,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,LONG_RETURN
-#endif
-#else
- .EXPORT maxpy_big,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,LONG_RETURN
- .EXPORT add_diag_big,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,LONG_RETURN
-#endif
- .END
-
-
-; How to use "maxpy_PA20_little" and "maxpy_PA20_big"
-;
-; The routine "maxpy_PA20_little" or "maxpy_PA20_big"
-; performs a 64-bit x any-size multiply, and adds the
-; result to an area of memory. That is, it performs
-; something like
-;
-; A B C D
-; * Z
-; __________
-; P Q R S T
-;
-; and then adds the "PQRST" vector into an area of memory,
-; handling all carries.
-;
-; Digression on nomenclature and endian-ness:
-;
-; Each of the capital letters in the above represents a 64-bit
-; quantity. That is, you could think of the discussion as
-; being in terms of radix-16-quintillion arithmetic. The data
-; type being manipulated is "unsigned long long int". This
-; requires the 64-bit extension of the HP-UX C compiler,
-; available at release 10. You need these compiler flags to
-; enable these extensions:
-;
-; -Aa +e +DA2.0 +DS2.0
-;
-; (The first specifies ANSI C, the second enables the
-; extensions, which are beyond ANSI C, and the third and
-; fourth tell the compiler to use whatever features of the
-; PA2.0 architecture it wishes, in order to made the code more
-; efficient. Since the presence of the assembly code will
-; make the program unable to run on anything less than PA2.0,
-; you might as well gain the performance enhancements in the C
-; code as well.)
-;
-; Questions of "endian-ness" often come up, usually in the
-; context of byte ordering in a word. These routines have a
-; similar issue, that could be called "wordian-ness".
-; Independent of byte ordering (PA is always big-endian), one
-; can make two choices when representing extremely large
-; numbers as arrays of 64-bit doublewords in memory.
-;
-; "Little-wordian" layout means that the least significant
-; word of a number is stored at the lowest address.
-;
-; MSW LSW
-; | |
-; V V
-;
-; A B C D E
-;
-; ^ ^ ^
-; | | |____ address 0
-; | |
-; | |_______address 8
-; |
-; address 32
-;
-; "Big-wordian" means that the most significant word is at the
-; lowest address.
-;
-; MSW LSW
-; | |
-; V V
-;
-; A B C D E
-;
-; ^ ^ ^
-; | | |____ address 32
-; | |
-; | |_______address 24
-; |
-; address 0
-;
-; When you compile the file, you must specify one or the other, with
-; a switch "-DLITTLE_WORDIAN" or "-DBIG_WORDIAN".
-;
-; Incidentally, you assemble this file as part of your
-; project with the same C compiler as the rest of the program.
-; My "makefile" for a superprecision arithmetic package has
-; the following stuff:
-;
-; # definitions:
-; CC = cc -Aa +e -z +DA2.0 +DS2.0 +w1
-; CFLAGS = +O3
-; LDFLAGS = -L /usr/lib -Wl,-aarchive
-;
-; # general build rule for ".s" files:
-; .s.o:
-; $(CC) $(CFLAGS) -c $< -DBIG_WORDIAN
-;
-; # Now any bind step that calls for pa20.o will assemble pa20.s
-;
-; End of digression, back to arithmetic:
-;
-; The way we multiply two huge numbers is, of course, to multiply
-; the "ABCD" vector by each of the "WXYZ" doublewords, adding
-; the result vectors with increasing offsets, the way we learned
-; in school, back before we all used calculators:
-;
-; A B C D
-; * W X Y Z
-; __________
-; P Q R S T
-; E F G H I
-; M N O P Q
-; + R S T U V
-; _______________
-; F I N A L S U M
-;
-; So we call maxpy_PA20_big (in my case; my package is
-; big-wordian) repeatedly, giving the W, X, Y, and Z arguments
-; in turn as the "scalar", and giving the "ABCD" vector each
-; time. We direct it to add its result into an area of memory
-; that we have cleared at the start. We skew the exact
-; location into that area with each call.
-;
-; The prototype for the function is
-;
-; extern void maxpy_PA20_big(
-; int length, /* Number of doublewords in the multiplicand vector. */
-; const long long int *scalaraddr, /* Address to fetch the scalar. */
-; const long long int *multiplicand, /* The multiplicand vector. */
-; long long int *result); /* Where to accumulate the result. */
-;
-; (You should place a copy of this prototype in an include file
-; or in your C file.)
-;
-; Now, IN ALL CASES, the given address for the multiplicand or
-; the result is that of the LEAST SIGNIFICANT DOUBLEWORD.
-; That word is, of course, the word at which the routine
-; starts processing. "maxpy_PA20_little" then increases the
-; addresses as it computes. "maxpy_PA20_big" decreases them.
-;
-; In our example above, "length" would be 4 in each case.
-; "multiplicand" would be the "ABCD" vector. Specifically,
-; the address of the element "D". "scalaraddr" would be the
-; address of "W", "X", "Y", or "Z" on the four calls that we
-; would make. (The order doesn't matter, of course.)
-; "result" would be the appropriate address in the result
-; area. When multiplying by "Z", that would be the least
-; significant word. When multiplying by "Y", it would be the
-; next higher word (8 bytes higher if little-wordian; 8 bytes
-; lower if big-wordian), and so on. The size of the result
-; area must be the the sum of the sizes of the multiplicand
-; and multiplier vectors, and must be initialized to zero
-; before we start.
-;
-; Whenever the routine adds its partial product into the result
-; vector, it follows carry chains as far as they need to go.
-;
-; Here is the super-precision multiply routine that I use for
-; my package. The package is big-wordian. I have taken out
-; handling of exponents (it's a floating point package):
-;
-; static void mul_PA20(
-; int size,
-; const long long int *arg1,
-; const long long int *arg2,
-; long long int *result)
-; {
-; int i;
-;
-; for (i=0 ; i<2*size ; i++) result[i] = 0ULL;
-;
-; for (i=0 ; i<size ; i++) {
-; maxpy_PA20_big(size, &arg2[i], &arg1[size-1], &result[size+i]);
-; }
-; }
diff --git a/security/nss/lib/freebl/mpi/hppatch.adb b/security/nss/lib/freebl/mpi/hppatch.adb
deleted file mode 100644
index 6875032ef..000000000
--- a/security/nss/lib/freebl/mpi/hppatch.adb
+++ /dev/null
@@ -1,21 +0,0 @@
-#/bin/sh
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# script to change the system id in an object file from PA-RISC 2.0 to 1.1
-
-adb -w $1 << EOF
-?m 0 -1 0
-0x0?X
-0x0?W (@0x0&~0x40000)|(~@0x0&0x40000)
-
-0?"change checksum"
-0x7c?X
-0x7c?W (@0x7c&~0x40000)|(~@0x7c&0x40000)
-$q
-EOF
-
-exit 0
-
diff --git a/security/nss/lib/freebl/mpi/logtab.h b/security/nss/lib/freebl/mpi/logtab.h
deleted file mode 100644
index 247c11e5a..000000000
--- a/security/nss/lib/freebl/mpi/logtab.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * logtab.h
- *
- * Arbitrary precision integer arithmetic library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-const float s_logv_2[] = {
- 0.000000000f, 0.000000000f, 1.000000000f, 0.630929754f, /* 0 1 2 3 */
- 0.500000000f, 0.430676558f, 0.386852807f, 0.356207187f, /* 4 5 6 7 */
- 0.333333333f, 0.315464877f, 0.301029996f, 0.289064826f, /* 8 9 10 11 */
- 0.278942946f, 0.270238154f, 0.262649535f, 0.255958025f, /* 12 13 14 15 */
- 0.250000000f, 0.244650542f, 0.239812467f, 0.235408913f, /* 16 17 18 19 */
- 0.231378213f, 0.227670249f, 0.224243824f, 0.221064729f, /* 20 21 22 23 */
- 0.218104292f, 0.215338279f, 0.212746054f, 0.210309918f, /* 24 25 26 27 */
- 0.208014598f, 0.205846832f, 0.203795047f, 0.201849087f, /* 28 29 30 31 */
- 0.200000000f, 0.198239863f, 0.196561632f, 0.194959022f, /* 32 33 34 35 */
- 0.193426404f, 0.191958720f, 0.190551412f, 0.189200360f, /* 36 37 38 39 */
- 0.187901825f, 0.186652411f, 0.185449023f, 0.184288833f, /* 40 41 42 43 */
- 0.183169251f, 0.182087900f, 0.181042597f, 0.180031327f, /* 44 45 46 47 */
- 0.179052232f, 0.178103594f, 0.177183820f, 0.176291434f, /* 48 49 50 51 */
- 0.175425064f, 0.174583430f, 0.173765343f, 0.172969690f, /* 52 53 54 55 */
- 0.172195434f, 0.171441601f, 0.170707280f, 0.169991616f, /* 56 57 58 59 */
- 0.169293808f, 0.168613099f, 0.167948779f, 0.167300179f, /* 60 61 62 63 */
- 0.166666667f
-};
-
diff --git a/security/nss/lib/freebl/mpi/make-logtab b/security/nss/lib/freebl/mpi/make-logtab
deleted file mode 100755
index d1fd2a3aa..000000000
--- a/security/nss/lib/freebl/mpi/make-logtab
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/perl
-
-#
-# make-logtab
-#
-# Generate a table of logarithms of 2 in various bases, for use in
-# estimating the output sizes of various bases.
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-
-$ARRAYNAME = $ENV{'ARRAYNAME'} || "s_logv_2";
-$ARRAYTYPE = $ENV{'ARRAYTYPE'} || "float";
-
-printf("const %s %s[] = {\n %0.9ff, %0.9ff, ",
- $ARRAYTYPE, $ARRAYNAME, 0, 0);
-$brk = 2;
-for($ix = 2; $ix < 64; $ix++) {
- printf("%0.9ff, ", (log(2)/log($ix)));
- $brk = ($brk + 1) & 3;
- if(!$brk) {
- printf(" /* %2d %2d %2d %2d */\n ",
- $ix - 3, $ix - 2, $ix - 1, $ix);
- }
-}
-printf("%0.9ff\n};\n\n", (log(2)/log($ix)));
-
-exit 0;
diff --git a/security/nss/lib/freebl/mpi/make-test-arrays b/security/nss/lib/freebl/mpi/make-test-arrays
deleted file mode 100755
index c4f3f6b06..000000000
--- a/security/nss/lib/freebl/mpi/make-test-arrays
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/perl
-
-#
-# make-test-arrays
-#
-# Given a test-arrays file, which specifies the test suite names, the
-# names of the functions which perform those test suites, and
-# descriptive comments, this script generates C structures for the
-# mpi-test program. The input consists of lines of the form:
-#
-# suite-name:function-name:comment
-#
-# The output is written to the standard output. Blank lines are
-# ignored, and comments beginning with '#' are stripped.
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-#
-
-# Read parameters from the environment, if available
-$NAMEVAR = $ENV{'NAMEVAR'} || "g_names";
-$COUNTVAR = $ENV{'COUNTVAR'} || "g_count";
-$FUNCVAR = $ENV{'FUNCVAR'} || "g_tests";
-$DESCVAR = $ENV{'DESCVAR'} || "g_descs";
-$FUNCLEN = 13;
-$NAMELEN = 18;
-$DESCLEN = 45;
-
-#------------------------------------------------------------------------
-# Suck in input from the files on the command line, or standard input
-while(<>) {
- chomp;
- s/\#.*$//;
- next if /^\s*$/;
-
- ($suite, $func, $desc) = split(/:/, $_);
-
- $tmp = { "suite" => $suite,
- "func" => $func,
- "desc" => $desc };
-
- push(@item, $tmp);
-}
-$count = scalar(@item);
-$last = pop(@item);
-
-#------------------------------------------------------------------------
-# Output the table of names
-print "/* Table mapping test suite names to index numbers */\n";
-printf("const int %s = %d;\n", $COUNTVAR, $count);
-printf("const char *%s[] = {\n", $NAMEVAR);
-
-foreach $elt (@item) {
- printf(" \"%s\",%s/* %s%s */\n", $elt->{"suite"},
- " " x ($NAMELEN - length($elt->{"suite"})),
- $elt->{"desc"},
- " " x ($DESCLEN - length($elt->{"desc"})));
-}
-printf(" \"%s\" %s/* %s%s */\n", $last->{"suite"},
- " " x ($NAMELEN - length($last->{"suite"})),
- $last->{"desc"},
- " " x ($DESCLEN - length($last->{"desc"})));
-print "};\n\n";
-
-#------------------------------------------------------------------------
-# Output the driver function prototypes
-print "/* Test function prototypes */\n";
-foreach $elt (@item, $last) {
- printf("int %s(void);\n", $elt->{"func"});
-}
-print "\n";
-
-#------------------------------------------------------------------------
-# Output the table of functions
-print "/* Table mapping index numbers to functions */\n";
-printf("int (*%s[])(void) = {\n ", $FUNCVAR);
-$brk = 0;
-
-foreach $elt (@item) {
- print($elt->{"func"}, ", ",
- " " x ($FUNCLEN - length($elt->{"func"})));
- $brk = ($brk + 1) & 3;
- print "\n " unless($brk);
-}
-print $last->{"func"}, "\n};\n\n";
-
-#------------------------------------------------------------------------
-# Output the table of descriptions
-print "/* Table mapping index numbers to descriptions */\n";
-printf("const char *%s[] = {\n", $DESCVAR);
-
-foreach $elt (@item) {
- printf(" \"%s\",\n", $elt->{"desc"});
-}
-printf(" \"%s\"\n};\n\n", $last->{"desc"});
-
-exit 0;
-
diff --git a/security/nss/lib/freebl/mpi/mdxptest.c b/security/nss/lib/freebl/mpi/mdxptest.c
deleted file mode 100644
index 28b05f046..000000000
--- a/security/nss/lib/freebl/mpi/mdxptest.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <malloc.h>
-#include <time.h>
-#include "mpi.h"
-#include "mpi-priv.h"
-
-/* #define OLD_WAY 1 */
-
-/* This key is the 1024-bit test key used for speed testing of RSA private
-** key ops.
-*/
-
-#define CONST const
-
-static CONST unsigned char default_n[128] = {
-0xc2,0xae,0x96,0x89,0xaf,0xce,0xd0,0x7b,0x3b,0x35,0xfd,0x0f,0xb1,0xf4,0x7a,0xd1,
-0x3c,0x7d,0xb5,0x86,0xf2,0x68,0x36,0xc9,0x97,0xe6,0x82,0x94,0x86,0xaa,0x05,0x39,
-0xec,0x11,0x51,0xcc,0x5c,0xa1,0x59,0xba,0x29,0x18,0xf3,0x28,0xf1,0x9d,0xe3,0xae,
-0x96,0x5d,0x6d,0x87,0x73,0xf6,0xf6,0x1f,0xd0,0x2d,0xfb,0x2f,0x7a,0x13,0x7f,0xc8,
-0x0c,0x7a,0xe9,0x85,0xfb,0xce,0x74,0x86,0xf8,0xef,0x2f,0x85,0x37,0x73,0x0f,0x62,
-0x4e,0x93,0x17,0xb7,0x7e,0x84,0x9a,0x94,0x11,0x05,0xca,0x0d,0x31,0x4b,0x2a,0xc8,
-0xdf,0xfe,0xe9,0x0c,0x13,0xc7,0xf2,0xad,0x19,0x64,0x28,0x3c,0xb5,0x6a,0xc8,0x4b,
-0x79,0xea,0x7c,0xce,0x75,0x92,0x45,0x3e,0xa3,0x9d,0x64,0x6f,0x04,0x69,0x19,0x17
-};
-
-static CONST unsigned char default_d[128] = {
-0x13,0xcb,0xbc,0xf2,0xf3,0x35,0x8c,0x6d,0x7b,0x6f,0xd9,0xf3,0xa6,0x9c,0xbd,0x80,
-0x59,0x2e,0x4f,0x2f,0x11,0xa7,0x17,0x2b,0x18,0x8f,0x0f,0xe8,0x1a,0x69,0x5f,0x6e,
-0xac,0x5a,0x76,0x7e,0xd9,0x4c,0x6e,0xdb,0x47,0x22,0x8a,0x57,0x37,0x7a,0x5e,0x94,
-0x7a,0x25,0xb5,0xe5,0x78,0x1d,0x3c,0x99,0xaf,0x89,0x7d,0x69,0x2e,0x78,0x9d,0x1d,
-0x84,0xc8,0xc1,0xd7,0x1a,0xb2,0x6d,0x2d,0x8a,0xd9,0xab,0x6b,0xce,0xae,0xb0,0xa0,
-0x58,0x55,0xad,0x5c,0x40,0x8a,0xd6,0x96,0x08,0x8a,0xe8,0x63,0xe6,0x3d,0x6c,0x20,
-0x49,0xc7,0xaf,0x0f,0x25,0x73,0xd3,0x69,0x43,0x3b,0xf2,0x32,0xf8,0x3d,0x5e,0xee,
-0x7a,0xca,0xd6,0x94,0x55,0xe5,0xbd,0x25,0x34,0x8d,0x63,0x40,0xb5,0x8a,0xc3,0x01
-};
-
-
-#define DEFAULT_ITERS 50
-
-typedef clock_t timetype;
-#define gettime(x) *(x) = clock()
-#define subtime(a, b) a -= b
-#define msec(x) ((clock_t)((double)x * 1000.0 / CLOCKS_PER_SEC))
-#define sec(x) (x / CLOCKS_PER_SEC)
-
-struct TimingContextStr {
- timetype start;
- timetype end;
- timetype interval;
-
- int minutes;
- int seconds;
- int millisecs;
-};
-
-typedef struct TimingContextStr TimingContext;
-
-TimingContext *CreateTimingContext(void)
-{
- return (TimingContext *)malloc(sizeof(TimingContext));
-}
-
-void DestroyTimingContext(TimingContext *ctx)
-{
- free(ctx);
-}
-
-void TimingBegin(TimingContext *ctx)
-{
- gettime(&ctx->start);
-}
-
-static void timingUpdate(TimingContext *ctx)
-{
-
- ctx->millisecs = msec(ctx->interval) % 1000;
- ctx->seconds = sec(ctx->interval);
- ctx->minutes = ctx->seconds / 60;
- ctx->seconds %= 60;
-
-}
-
-void TimingEnd(TimingContext *ctx)
-{
- gettime(&ctx->end);
- ctx->interval = ctx->end;
- subtime(ctx->interval, ctx->start);
- timingUpdate(ctx);
-}
-
-char *TimingGenerateString(TimingContext *ctx)
-{
- static char sBuf[4096];
-
- sprintf(sBuf, "%d minutes, %d.%03d seconds", ctx->minutes,
- ctx->seconds, ctx->millisecs);
- return sBuf;
-}
-
-static void
-dumpBytes( unsigned char * b, int l)
-{
- int i;
- if (l <= 0)
- return;
- for (i = 0; i < l; ++i) {
- if (i % 16 == 0)
- printf("\t");
- printf(" %02x", b[i]);
- if (i % 16 == 15)
- printf("\n");
- }
- if ((i % 16) != 0)
- printf("\n");
- printf("\n");
-}
-
-static mp_err
-testNewFuncs(const unsigned char * modulusBytes, int modulus_len)
-{
- mp_err mperr = MP_OKAY;
- mp_int modulus;
- unsigned char buf[512];
-
- mperr = mp_init(&modulus);
- mperr = mp_read_unsigned_octets(&modulus, modulusBytes, modulus_len );
- mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len);
- mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+1);
- mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+4);
- mperr = mp_to_unsigned_octets(&modulus, buf, modulus_len);
- mperr = mp_to_signed_octets(&modulus, buf, modulus_len + 1);
- mp_clear(&modulus);
- return mperr;
-}
-
-int
-testModExp( const unsigned char * modulusBytes,
- const unsigned int expo,
- const unsigned char * input,
- unsigned char * output,
- int modulus_len)
-{
- mp_err mperr = MP_OKAY;
- mp_int modulus;
- mp_int base;
- mp_int exponent;
- mp_int result;
-
- mperr = mp_init(&modulus);
- mperr += mp_init(&base);
- mperr += mp_init(&exponent);
- mperr += mp_init(&result);
- /* we initialize all mp_ints unconditionally, even if some fail.
- ** This guarantees that the DIGITS pointer is valid (even if null).
- ** So, mp_clear will do the right thing below.
- */
- if (mperr == MP_OKAY) {
- mperr = mp_read_unsigned_octets(&modulus,
- modulusBytes + (sizeof default_n - modulus_len), modulus_len );
- mperr += mp_read_unsigned_octets(&base, input, modulus_len );
- mp_set(&exponent, expo);
- if (mperr == MP_OKAY) {
-#if OLD_WAY
- mperr = s_mp_exptmod(&base, &exponent, &modulus, &result);
-#else
- mperr = mp_exptmod(&base, &exponent, &modulus, &result);
-#endif
- if (mperr == MP_OKAY) {
- mperr = mp_to_fixlen_octets(&result, output, modulus_len);
- }
- }
- }
- mp_clear(&base);
- mp_clear(&result);
-
- mp_clear(&modulus);
- mp_clear(&exponent);
-
- return (int)mperr;
-}
-
-int
-doModExp( const unsigned char * modulusBytes,
- const unsigned char * exponentBytes,
- const unsigned char * input,
- unsigned char * output,
- int modulus_len)
-{
- mp_err mperr = MP_OKAY;
- mp_int modulus;
- mp_int base;
- mp_int exponent;
- mp_int result;
-
- mperr = mp_init(&modulus);
- mperr += mp_init(&base);
- mperr += mp_init(&exponent);
- mperr += mp_init(&result);
- /* we initialize all mp_ints unconditionally, even if some fail.
- ** This guarantees that the DIGITS pointer is valid (even if null).
- ** So, mp_clear will do the right thing below.
- */
- if (mperr == MP_OKAY) {
- mperr = mp_read_unsigned_octets(&modulus,
- modulusBytes + (sizeof default_n - modulus_len), modulus_len );
- mperr += mp_read_unsigned_octets(&exponent, exponentBytes, modulus_len );
- mperr += mp_read_unsigned_octets(&base, input, modulus_len );
- if (mperr == MP_OKAY) {
-#if OLD_WAY
- mperr = s_mp_exptmod(&base, &exponent, &modulus, &result);
-#else
- mperr = mp_exptmod(&base, &exponent, &modulus, &result);
-#endif
- if (mperr == MP_OKAY) {
- mperr = mp_to_fixlen_octets(&result, output, modulus_len);
- }
- }
- }
- mp_clear(&base);
- mp_clear(&result);
-
- mp_clear(&modulus);
- mp_clear(&exponent);
-
- return (int)mperr;
-}
-
-int
-main(int argc, char **argv)
-{
- TimingContext * timeCtx;
- char * progName;
- long iters = DEFAULT_ITERS;
- unsigned int modulus_len;
- int i;
- int rv;
- unsigned char buf [1024];
- unsigned char buf2[1024];
-
- progName = strrchr(argv[0], '/');
- if (!progName)
- progName = strrchr(argv[0], '\\');
- progName = progName ? progName+1 : argv[0];
-
- if (argc >= 2) {
- iters = atol(argv[1]);
- }
-
- if (argc >= 3) {
- modulus_len = atol(argv[2]);
- } else
- modulus_len = sizeof default_n;
-
- /* no library init function !? */
-
- memset(buf, 0x41, sizeof buf);
-
- if (iters < 2) {
- testNewFuncs( default_n, modulus_len);
- testNewFuncs( default_n+1, modulus_len - 1);
- testNewFuncs( default_n+2, modulus_len - 2);
- testNewFuncs( default_n+3, modulus_len - 3);
-
- printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
- rv = testModExp(default_n, 0, buf, buf2, modulus_len);
- dumpBytes((unsigned char *)buf2, modulus_len);
-
- printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
- rv = testModExp(default_n, 1, buf, buf2, modulus_len);
- dumpBytes((unsigned char *)buf2, modulus_len);
-
- printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
- rv = testModExp(default_n, 2, buf, buf2, modulus_len);
- dumpBytes((unsigned char *)buf2, modulus_len);
-
- printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
- rv = testModExp(default_n, 3, buf, buf2, modulus_len);
- dumpBytes((unsigned char *)buf2, modulus_len);
- }
- printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
- rv = doModExp(default_n, default_d, buf, buf2, modulus_len);
- if (rv != 0) {
- fprintf(stderr, "Error in modexp operation:\n");
- exit(1);
- }
- dumpBytes((unsigned char *)buf2, modulus_len);
- printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
-
- timeCtx = CreateTimingContext();
- TimingBegin(timeCtx);
- i = iters;
- while (i--) {
- rv = doModExp(default_n, default_d, buf, buf2, modulus_len);
- if (rv != 0) {
- fprintf(stderr, "Error in modexp operation\n");
- exit(1);
- }
- }
- TimingEnd(timeCtx);
- printf("%ld iterations in %s\n", iters, TimingGenerateString(timeCtx));
- printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/montmulf.c b/security/nss/lib/freebl/mpi/montmulf.c
deleted file mode 100644
index 8c76b66c7..000000000
--- a/security/nss/lib/freebl/mpi/montmulf.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef SOLARIS
-#define RF_INLINE_MACROS 1
-#endif
-
-static const double TwoTo16=65536.0;
-static const double TwoToMinus16=1.0/65536.0;
-static const double Zero=0.0;
-static const double TwoTo32=65536.0*65536.0;
-static const double TwoToMinus32=1.0/(65536.0*65536.0);
-
-#ifdef RF_INLINE_MACROS
-
-double upper32(double);
-double lower32(double, double);
-double mod(double, double, double);
-
-void i16_to_d16_and_d32x4(const double * /*1/(2^16)*/,
- const double * /* 2^16*/,
- const double * /* 0 */,
- double * /*result16*/,
- double * /* result32 */,
- float * /*source - should be unsigned int*
- converted to float* */);
-
-#else
-#ifdef MP_USE_FLOOR
-#include <math.h>
-#else
-#define floor(d) ((double)((unsigned long long)(d)))
-#endif
-
-static double upper32(double x)
-{
- return floor(x*TwoToMinus32);
-}
-
-static double lower32(double x, double y)
-{
- return x-TwoTo32*floor(x*TwoToMinus32);
-}
-
-static double mod(double x, double oneoverm, double m)
-{
- return x-m*floor(x*oneoverm);
-}
-
-#endif
-
-
-static void cleanup(double *dt, int from, int tlen)
-{
- int i;
- double tmp,tmp1,x,x1;
-
- tmp=tmp1=Zero;
- /* original code **
- for(i=2*from;i<2*tlen-2;i++)
- {
- x=dt[i];
- dt[i]=lower32(x,Zero)+tmp1;
- tmp1=tmp;
- tmp=upper32(x);
- }
- dt[tlen-2]+=tmp1;
- dt[tlen-1]+=tmp;
- **end original code ***/
- /* new code ***/
- for(i=2*from;i<2*tlen;i+=2)
- {
- x=dt[i];
- x1=dt[i+1];
- dt[i]=lower32(x,Zero)+tmp;
- dt[i+1]=lower32(x1,Zero)+tmp1;
- tmp=upper32(x);
- tmp1=upper32(x1);
- }
- /** end new code **/
-}
-
-
-void conv_d16_to_i32(unsigned int *i32, double *d16, long long *tmp, int ilen)
-{
-int i;
-long long t, t1, a, b, c, d;
-
- t1=0;
- a=(long long)d16[0];
- b=(long long)d16[1];
- for(i=0; i<ilen-1; i++)
- {
- c=(long long)d16[2*i+2];
- t1+=(unsigned int)a;
- t=(a>>32);
- d=(long long)d16[2*i+3];
- t1+=(b&0xffff)<<16;
- t+=(b>>16)+(t1>>32);
- i32[i]=(unsigned int)t1;
- t1=t;
- a=c;
- b=d;
- }
- t1+=(unsigned int)a;
- t=(a>>32);
- t1+=(b&0xffff)<<16;
- i32[i]=(unsigned int)t1;
-}
-
-void conv_i32_to_d32(double *d32, unsigned int *i32, int len)
-{
-int i;
-
-#pragma pipeloop(0)
- for(i=0;i<len;i++) d32[i]=(double)(i32[i]);
-}
-
-
-void conv_i32_to_d16(double *d16, unsigned int *i32, int len)
-{
-int i;
-unsigned int a;
-
-#pragma pipeloop(0)
- for(i=0;i<len;i++)
- {
- a=i32[i];
- d16[2*i]=(double)(a&0xffff);
- d16[2*i+1]=(double)(a>>16);
- }
-}
-
-
-void conv_i32_to_d32_and_d16(double *d32, double *d16,
- unsigned int *i32, int len)
-{
-int i = 0;
-unsigned int a;
-
-#pragma pipeloop(0)
-#ifdef RF_INLINE_MACROS
- for(;i<len-3;i+=4)
- {
- i16_to_d16_and_d32x4(&TwoToMinus16, &TwoTo16, &Zero,
- &(d16[2*i]), &(d32[i]), (float *)(&(i32[i])));
- }
-#endif
- for(;i<len;i++)
- {
- a=i32[i];
- d32[i]=(double)(i32[i]);
- d16[2*i]=(double)(a&0xffff);
- d16[2*i+1]=(double)(a>>16);
- }
-}
-
-
-void adjust_montf_result(unsigned int *i32, unsigned int *nint, int len)
-{
-long long acc;
-int i;
-
- if(i32[len]>0) i=-1;
- else
- {
- for(i=len-1; i>=0; i--)
- {
- if(i32[i]!=nint[i]) break;
- }
- }
- if((i<0)||(i32[i]>nint[i]))
- {
- acc=0;
- for(i=0;i<len;i++)
- {
- acc=acc+(unsigned long long)(i32[i])-(unsigned long long)(nint[i]);
- i32[i]=(unsigned int)acc;
- acc=acc>>32;
- }
- }
-}
-
-
-
-
-/*
-** the lengths of the input arrays should be at least the following:
-** result[nlen+1], dm1[nlen], dm2[2*nlen+1], dt[4*nlen+2], dn[nlen], nint[nlen]
-** all of them should be different from one another
-**
-*/
-void mont_mulf_noconv(unsigned int *result,
- double *dm1, double *dm2, double *dt,
- double *dn, unsigned int *nint,
- int nlen, double dn0)
-{
- int i, j, jj;
- int tmp;
- double digit, m2j, nextm2j, a, b;
- double *dptmp, *pdm1, *pdm2, *pdn, *pdtj, pdn_0, pdm1_0;
-
- pdm1=&(dm1[0]);
- pdm2=&(dm2[0]);
- pdn=&(dn[0]);
- pdm2[2*nlen]=Zero;
-
- if (nlen!=16)
- {
- for(i=0;i<4*nlen+2;i++) dt[i]=Zero;
-
- a=dt[0]=pdm1[0]*pdm2[0];
- digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16);
-
- pdtj=&(dt[0]);
- for(j=jj=0;j<2*nlen;j++,jj++,pdtj++)
- {
- m2j=pdm2[j];
- a=pdtj[0]+pdn[0]*digit;
- b=pdtj[1]+pdm1[0]*pdm2[j+1]+a*TwoToMinus16;
- pdtj[1]=b;
-
-#pragma pipeloop(0)
- for(i=1;i<nlen;i++)
- {
- pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit;
- }
- if((jj==30)) {cleanup(dt,j/2+1,2*nlen+1); jj=0;}
-
- digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16);
- }
- }
- else
- {
- a=dt[0]=pdm1[0]*pdm2[0];
-
- dt[65]= dt[64]= dt[63]= dt[62]= dt[61]= dt[60]=
- dt[59]= dt[58]= dt[57]= dt[56]= dt[55]= dt[54]=
- dt[53]= dt[52]= dt[51]= dt[50]= dt[49]= dt[48]=
- dt[47]= dt[46]= dt[45]= dt[44]= dt[43]= dt[42]=
- dt[41]= dt[40]= dt[39]= dt[38]= dt[37]= dt[36]=
- dt[35]= dt[34]= dt[33]= dt[32]= dt[31]= dt[30]=
- dt[29]= dt[28]= dt[27]= dt[26]= dt[25]= dt[24]=
- dt[23]= dt[22]= dt[21]= dt[20]= dt[19]= dt[18]=
- dt[17]= dt[16]= dt[15]= dt[14]= dt[13]= dt[12]=
- dt[11]= dt[10]= dt[ 9]= dt[ 8]= dt[ 7]= dt[ 6]=
- dt[ 5]= dt[ 4]= dt[ 3]= dt[ 2]= dt[ 1]=Zero;
-
- pdn_0=pdn[0];
- pdm1_0=pdm1[0];
-
- digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16);
- pdtj=&(dt[0]);
-
- for(j=0;j<32;j++,pdtj++)
- {
-
- m2j=pdm2[j];
- a=pdtj[0]+pdn_0*digit;
- b=pdtj[1]+pdm1_0*pdm2[j+1]+a*TwoToMinus16;
- pdtj[1]=b;
-
- /**** this loop will be fully unrolled:
- for(i=1;i<16;i++)
- {
- pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit;
- }
- *************************************/
- pdtj[2]+=pdm1[1]*m2j+pdn[1]*digit;
- pdtj[4]+=pdm1[2]*m2j+pdn[2]*digit;
- pdtj[6]+=pdm1[3]*m2j+pdn[3]*digit;
- pdtj[8]+=pdm1[4]*m2j+pdn[4]*digit;
- pdtj[10]+=pdm1[5]*m2j+pdn[5]*digit;
- pdtj[12]+=pdm1[6]*m2j+pdn[6]*digit;
- pdtj[14]+=pdm1[7]*m2j+pdn[7]*digit;
- pdtj[16]+=pdm1[8]*m2j+pdn[8]*digit;
- pdtj[18]+=pdm1[9]*m2j+pdn[9]*digit;
- pdtj[20]+=pdm1[10]*m2j+pdn[10]*digit;
- pdtj[22]+=pdm1[11]*m2j+pdn[11]*digit;
- pdtj[24]+=pdm1[12]*m2j+pdn[12]*digit;
- pdtj[26]+=pdm1[13]*m2j+pdn[13]*digit;
- pdtj[28]+=pdm1[14]*m2j+pdn[14]*digit;
- pdtj[30]+=pdm1[15]*m2j+pdn[15]*digit;
- /* no need for cleenup, cannot overflow */
- digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16);
- }
- }
-
- conv_d16_to_i32(result,dt+2*nlen,(long long *)dt,nlen+1);
-
- adjust_montf_result(result,nint,nlen);
-
-}
-
diff --git a/security/nss/lib/freebl/mpi/montmulf.h b/security/nss/lib/freebl/mpi/montmulf.h
deleted file mode 100644
index 21c34cb4d..000000000
--- a/security/nss/lib/freebl/mpi/montmulf.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* The functions that are to be called from outside of the .s file have the
- * following interfaces and array size requirements:
- */
-
-
-void conv_i32_to_d32(double *d32, unsigned int *i32, int len);
-
-/* Converts an array of int's to an array of doubles, so that each double
- * corresponds to an int. len is the number of items converted.
- * Does not allocate the output array.
- * The pointers d32 and i32 should point to arrays of size at least len
- * (doubles and unsigned ints, respectively)
- */
-
-
-void conv_i32_to_d16(double *d16, unsigned int *i32, int len);
-
-/* Converts an array of int's to an array of doubles so that each element
- * of the int array is converted to a pair of doubles, the first one
- * corresponding to the lower (least significant) 16 bits of the int and
- * the second one corresponding to the upper (most significant) 16 bits of
- * the 32-bit int. len is the number of ints converted.
- * Does not allocate the output array.
- * The pointer d16 should point to an array of doubles of size at least
- * 2*len and i32 should point an array of ints of size at least len
- */
-
-
-void conv_i32_to_d32_and_d16(double *d32, double *d16,
- unsigned int *i32, int len);
-
-/* Does the above two conversions together, it is much faster than doing
- * both of those in succession
- */
-
-
-void mont_mulf_noconv(unsigned int *result,
- double *dm1, double *dm2, double *dt,
- double *dn, unsigned int *nint,
- int nlen, double dn0);
-
-/* Does the Montgomery multiplication of the numbers stored in the arrays
- * pointed to by dm1 and dm2, writing the result to the array pointed to by
- * result. It uses the array pointed to by dt as a temporary work area.
- * nint should point to the modulus in the array-of-integers representation,
- * dn should point to its array-of-doubles as obtained as a result of the
- * function call conv_i32_to_d32(dn, nint, nlen);
- * nlen is the length of the array containing the modulus.
- * The representation used for dm1 is the one that is a result of the function
- * call conv_i32_to_d32(dm1, m1, nlen), the representation for dm2 is the
- * result of the function call conv_i32_to_d16(dm2, m2, nlen).
- * Note that m1 and m2 should both be of length nlen, so they should be
- * padded with 0's if necessary before the conversion. The result comes in
- * this form (int representation, padded with 0's).
- * dn0 is the value of the 16 least significant bits of n0'.
- * The function does not allocate memory for any of the arrays, so the
- * pointers should point to arrays with the following minimal sizes:
- * result - nlen+1
- * dm1 - nlen
- * dm2 - 2*nlen+1 ( the +1 is necessary for technical reasons )
- * dt - 4*nlen+2
- * dn - nlen
- * nint - nlen
- * No two arrays should point to overlapping areas of memory.
- */
diff --git a/security/nss/lib/freebl/mpi/montmulf.il b/security/nss/lib/freebl/mpi/montmulf.il
deleted file mode 100644
index 2d051f426..000000000
--- a/security/nss/lib/freebl/mpi/montmulf.il
+++ /dev/null
@@ -1,109 +0,0 @@
-!
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-! $Id$
-
-!
-! double upper32(double /*frs1*/);
-!
- .inline upper32,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f10
-
- fdtox %f10,%f10
- fitod %f10,%f0
- .end
-
-!
-! double lower32(double /*frs1*/, double /* Zero */);
-!
- .inline lower32,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f10
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f12
-
- fdtox %f10,%f10
- fmovs %f12,%f10
- fxtod %f10,%f0
- .end
-
-!
-! double mod(double /*x*/, double /*1/m*/, double /*m*/);
-!
- .inline mod,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f2
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o4,[%sp+0x48]
- ldd [%sp+0x48],%f6
-
- fmuld %f2,%f4,%f4
- fdtox %f4,%f4
- fxtod %f4,%f4
- fmuld %f4,%f6,%f4
- fsubd %f2,%f4,%f0
- .end
-
-
-!
-! void i16_to_d16_and_d32x4(double * /*1/(2^16)*/, double * /* 2^16*/,
-! double * /* 0 */,
-! double * /*result16*/, double * /* result32 */
-! float * /*source - should be unsigned int*
-! converted to float* */);
-!
- .inline i16_to_d16_and_d32x4,24
- ldd [%o0],%f2 ! 1/(2^16)
- ldd [%o1],%f4 ! 2^16
- ldd [%o2],%f22
-
- fmovd %f22,%f6
- ld [%o5],%f7
- fmovd %f22,%f10
- ld [%o5+4],%f11
- fmovd %f22,%f14
- ld [%o5+8],%f15
- fmovd %f22,%f18
- ld [%o5+12],%f19
- fxtod %f6,%f6
- std %f6,[%o4]
- fxtod %f10,%f10
- std %f10,[%o4+8]
- fxtod %f14,%f14
- std %f14,[%o4+16]
- fxtod %f18,%f18
- std %f18,[%o4+24]
- fmuld %f2,%f6,%f8
- fmuld %f2,%f10,%f12
- fmuld %f2,%f14,%f16
- fmuld %f2,%f18,%f20
- fdtox %f8,%f8
- fdtox %f12,%f12
- fdtox %f16,%f16
- fdtox %f20,%f20
- fxtod %f8,%f8
- std %f8,[%o3+8]
- fxtod %f12,%f12
- std %f12,[%o3+24]
- fxtod %f16,%f16
- std %f16,[%o3+40]
- fxtod %f20,%f20
- std %f20,[%o3+56]
- fmuld %f8,%f4,%f8
- fmuld %f12,%f4,%f12
- fmuld %f16,%f4,%f16
- fmuld %f20,%f4,%f20
- fsubd %f6,%f8,%f8
- std %f8,[%o3]
- fsubd %f10,%f12,%f12
- std %f12,[%o3+16]
- fsubd %f14,%f16,%f16
- std %f16,[%o3+32]
- fsubd %f18,%f20,%f20
- std %f20,[%o3+48]
- .end
-
-
diff --git a/security/nss/lib/freebl/mpi/montmulf.s b/security/nss/lib/freebl/mpi/montmulf.s
deleted file mode 100644
index 69d2a3c51..000000000
--- a/security/nss/lib/freebl/mpi/montmulf.s
+++ /dev/null
@@ -1,1938 +0,0 @@
-!
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
- .section ".text",#alloc,#execinstr
- .file "montmulf.c"
-
- .section ".data",#alloc,#write
- .align 8
-TwoTo16: /* frequency 1.0 confidence 0.0 */
- .word 1089470464
- .word 0
- .type TwoTo16,#object
- .size TwoTo16,8
-TwoToMinus16: /* frequency 1.0 confidence 0.0 */
- .word 1055916032
- .word 0
- .type TwoToMinus16,#object
- .size TwoToMinus16,8
-Zero: /* frequency 1.0 confidence 0.0 */
- .word 0
- .word 0
- .type Zero,#object
- .size Zero,8
-TwoTo32: /* frequency 1.0 confidence 0.0 */
- .word 1106247680
- .word 0
- .type TwoTo32,#object
- .size TwoTo32,8
-TwoToMinus32: /* frequency 1.0 confidence 0.0 */
- .word 1039138816
- .word 0
- .type TwoToMinus32,#object
- .size TwoToMinus32,8
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 ( 0 0) */ .align 4
-!
-! SUBROUTINE cleanup
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
-
- .global cleanup
- cleanup: /* frequency 1.0 confidence 0.0 */
-! FILE montmulf.c
-
-! 1 !#define RF_INLINE_MACROS
-! 3 !static double TwoTo16=65536.0;
-! 4 !static double TwoToMinus16=1.0/65536.0;
-! 5 !static double Zero=0.0;
-! 6 !static double TwoTo32=65536.0*65536.0;
-! 7 !static double TwoToMinus32=1.0/(65536.0*65536.0);
-! 9 !#ifdef RF_INLINE_MACROS
-! 11 !double upper32(double);
-! 12 !double lower32(double, double);
-! 13 !double mod(double, double, double);
-! 15 !#else
-! 17 !static double upper32(double x)
-! 18 !{
-! 19 ! return floor(x*TwoToMinus32);
-! 20 !}
-! 22 !static double lower32(double x, double y)
-! 23 !{
-! 24 ! return x-TwoTo32*floor(x*TwoToMinus32);
-! 25 !}
-! 27 !static double mod(double x, double oneoverm, double m)
-! 28 !{
-! 29 ! return x-m*floor(x*oneoverm);
-! 30 !}
-! 32 !#endif
-! 35 !void cleanup(double *dt, int from, int tlen)
-! 36 !{
-! 37 ! int i;
-! 38 ! double tmp,tmp1,x,x1;
-! 40 ! tmp=tmp1=Zero;
-
-/* 000000 40 ( 0 1) */ sethi %hi(Zero),%g2
-
-! 41 ! /* original code **
-! 42 ! for(i=2*from;i<2*tlen-2;i++)
-! 43 ! {
-! 44 ! x=dt[i];
-! 45 ! dt[i]=lower32(x,Zero)+tmp1;
-! 46 ! tmp1=tmp;
-! 47 ! tmp=upper32(x);
-! 48 ! }
-! 49 ! dt[tlen-2]+=tmp1;
-! 50 ! dt[tlen-1]+=tmp;
-! 51 ! **end original code ***/
-! 52 ! /* new code ***/
-! 53 ! for(i=2*from;i<2*tlen;i+=2)
-
-/* 0x0004 53 ( 1 2) */ sll %o2,1,%g3
-/* 0x0008 40 ( 1 4) */ ldd [%g2+%lo(Zero)],%f0
-/* 0x000c ( 1 2) */ add %g2,%lo(Zero),%g2
-/* 0x0010 53 ( 2 3) */ sll %o1,1,%g4
-/* 0x0014 36 ( 3 4) */ sll %o1,4,%g1
-/* 0x0018 40 ( 3 4) */ fmovd %f0,%f4
-/* 0x001c 53 ( 3 4) */ cmp %g4,%g3
-/* 0x0020 ( 3 4) */ bge,pt %icc,.L77000116 ! tprob=0.56
-/* 0x0024 ( 4 5) */ fmovd %f0,%f2
-/* 0x0028 36 ( 4 5) */ add %o0,%g1,%g1
-/* 0x002c ( 4 5) */ sub %g3,1,%g3
-
-! 54 ! {
-! 55 ! x=dt[i];
-
-/* 0x0030 55 ( 5 8) */ ldd [%g1],%f8
- .L900000114: /* frequency 6.4 confidence 0.0 */
-/* 0x0034 ( 0 3) */ fdtox %f8,%f6
-
-! 56 ! x1=dt[i+1];
-
-/* 0x0038 56 ( 0 3) */ ldd [%g1+8],%f10
-
-! 57 ! dt[i]=lower32(x,Zero)+tmp;
-! 58 ! dt[i+1]=lower32(x1,Zero)+tmp1;
-! 59 ! tmp=upper32(x);
-! 60 ! tmp1=upper32(x1);
-
-/* 0x003c 60 ( 0 1) */ add %g4,2,%g4
-/* 0x0040 ( 1 4) */ fdtox %f8,%f8
-/* 0x0044 ( 1 2) */ cmp %g4,%g3
-/* 0x0048 ( 5 6) */ fmovs %f0,%f6
-/* 0x004c ( 7 10) */ fxtod %f6,%f6
-/* 0x0050 ( 8 11) */ fdtox %f10,%f0
-/* 0x0054 57 (10 13) */ faddd %f6,%f2,%f2
-/* 0x0058 (10 11) */ std %f2,[%g1]
-/* 0x005c (12 15) */ ldd [%g2],%f2
-/* 0x0060 (14 15) */ fmovs %f2,%f0
-/* 0x0064 (16 19) */ fxtod %f0,%f6
-/* 0x0068 (17 20) */ fdtox %f10,%f0
-/* 0x006c (18 21) */ fitod %f8,%f2
-/* 0x0070 58 (19 22) */ faddd %f6,%f4,%f4
-/* 0x0074 (19 20) */ std %f4,[%g1+8]
-/* 0x0078 60 (19 20) */ add %g1,16,%g1
-/* 0x007c (20 23) */ fitod %f0,%f4
-/* 0x0080 (20 23) */ ldd [%g2],%f0
-/* 0x0084 (20 21) */ ble,a,pt %icc,.L900000114 ! tprob=0.86
-/* 0x0088 (21 24) */ ldd [%g1],%f8
- .L77000116: /* frequency 1.0 confidence 0.0 */
-/* 0x008c ( 0 2) */ retl ! Result =
-/* 0x0090 ( 1 2) */ nop
-/* 0x0094 0 ( 0 0) */ .type cleanup,2
-/* 0x0094 ( 0 0) */ .size cleanup,(.-cleanup)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 ( 0 0) */ .align 4
-!
-! SUBROUTINE conv_d16_to_i32
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
-
- .global conv_d16_to_i32
- conv_d16_to_i32: /* frequency 1.0 confidence 0.0 */
-/* 000000 ( 0 1) */ save %sp,-136,%sp
-
-! 61 ! }
-! 62 ! /** end new code **/
-! 63 !}
-! 66 !void conv_d16_to_i32(unsigned int *i32, double *d16, long long *tmp, int ilen)
-! 67 !{
-! 68 !int i;
-! 69 !long long t, t1, a, b, c, d;
-! 71 ! t1=0;
-! 72 ! a=(long long)d16[0];
-
-/* 0x0004 72 ( 1 4) */ ldd [%i1],%f0
-
-! 73 ! b=(long long)d16[1];
-! 74 ! for(i=0; i<ilen-1; i++)
-
-/* 0x0008 74 ( 1 2) */ sub %i3,1,%g2
-/* 0x000c 67 ( 1 2) */ or %g0,%i0,%g5
-/* 0x0010 74 ( 2 3) */ cmp %g2,0
-/* 0x0014 71 ( 2 3) */ or %g0,0,%o4
-/* 0x0018 72 ( 3 6) */ fdtox %f0,%f0
-/* 0x001c ( 3 4) */ std %f0,[%sp+120]
-/* 0x0020 74 ( 3 4) */ or %g0,0,%o7
-/* 0x0024 67 ( 4 5) */ or %g0,%i3,%o0
-/* 0x0028 ( 4 5) */ sub %i3,2,%o2
-/* 0x002c 73 ( 5 8) */ ldd [%i1+8],%f0
-/* 0x0030 67 ( 5 6) */ sethi %hi(0xfc00),%o0
-/* 0x0034 ( 5 6) */ add %o2,1,%g3
-/* 0x0038 ( 6 7) */ add %o0,1023,%o1
-/* 0x003c ( 6 7) */ or %g0,%g5,%o5
-/* 0x0040 73 ( 7 10) */ fdtox %f0,%f0
-/* 0x0044 ( 7 8) */ std %f0,[%sp+112]
-/* 0x0048 72 (11 13) */ ldx [%sp+120],%g4
-/* 0x004c 73 (12 14) */ ldx [%sp+112],%g1
-/* 0x0050 74 (12 13) */ ble,pt %icc,.L900000214 ! tprob=0.56
-/* 0x0054 (12 13) */ sethi %hi(0xfc00),%g2
-/* 0x0058 67 (13 14) */ or %g0,-1,%g2
-/* 0x005c 74 (13 14) */ cmp %g3,3
-/* 0x0060 67 (14 15) */ srl %g2,0,%o3
-/* 0x0064 (14 15) */ or %g0,%i1,%g2
-/* 0x0068 74 (14 15) */ bl,pn %icc,.L77000134 ! tprob=0.44
-/* 0x006c (15 18) */ ldd [%g2+16],%f0
-
-! 75 ! {
-! 76 ! c=(long long)d16[2*i+2];
-! 77 ! t1+=a&0xffffffff;
-! 78 ! t=(a>>32);
-! 79 ! d=(long long)d16[2*i+3];
-! 80 ! t1+=(b&0xffff)<<16;
-
-/* 0x0070 80 (15 16) */ and %g1,%o1,%o0
-
-! 81 ! t+=(b>>16)+(t1>>32);
-! 82 ! i32[i]=t1&0xffffffff;
-! 83 ! t1=t;
-! 84 ! a=c;
-! 85 ! b=d;
-
-/* 0x0074 85 (15 16) */ add %g2,16,%g2
-/* 0x0078 80 (16 17) */ sllx %o0,16,%g3
-/* 0x007c 77 (16 17) */ and %g4,%o3,%o0
-/* 0x0080 76 (17 20) */ fdtox %f0,%f0
-/* 0x0084 (17 18) */ std %f0,[%sp+104]
-/* 0x0088 74 (17 18) */ add %o0,%g3,%o4
-/* 0x008c 79 (18 21) */ ldd [%g2+8],%f2
-/* 0x0090 81 (18 19) */ srax %g1,16,%o0
-/* 0x0094 82 (18 19) */ and %o4,%o3,%o7
-/* 0x0098 81 (19 20) */ stx %o0,[%sp+112]
-/* 0x009c (19 20) */ srax %o4,32,%o0
-/* 0x00a0 85 (19 20) */ add %g5,4,%o5
-/* 0x00a4 81 (20 21) */ stx %o0,[%sp+120]
-/* 0x00a8 78 (20 21) */ srax %g4,32,%o4
-/* 0x00ac 79 (20 23) */ fdtox %f2,%f0
-/* 0x00b0 (21 22) */ std %f0,[%sp+96]
-/* 0x00b4 81 (22 24) */ ldx [%sp+112],%o0
-/* 0x00b8 (23 25) */ ldx [%sp+120],%g4
-/* 0x00bc 76 (25 27) */ ldx [%sp+104],%g3
-/* 0x00c0 81 (25 26) */ add %o0,%g4,%g4
-/* 0x00c4 79 (26 28) */ ldx [%sp+96],%g1
-/* 0x00c8 81 (26 27) */ add %o4,%g4,%o4
-/* 0x00cc 82 (27 28) */ st %o7,[%g5]
-/* 0x00d0 (27 28) */ or %g0,1,%o7
-/* 0x00d4 84 (27 28) */ or %g0,%g3,%g4
- .L900000209: /* frequency 64.0 confidence 0.0 */
-/* 0x00d8 76 (17 19) */ ldd [%g2+16],%f0
-/* 0x00dc 85 (17 18) */ add %o7,1,%o7
-/* 0x00e0 (17 18) */ add %o5,4,%o5
-/* 0x00e4 (18 18) */ cmp %o7,%o2
-/* 0x00e8 (18 19) */ add %g2,16,%g2
-/* 0x00ec 76 (19 22) */ fdtox %f0,%f0
-/* 0x00f0 (20 21) */ std %f0,[%sp+104]
-/* 0x00f4 79 (21 23) */ ldd [%g2+8],%f0
-/* 0x00f8 (23 26) */ fdtox %f0,%f0
-/* 0x00fc (24 25) */ std %f0,[%sp+96]
-/* 0x0100 80 (25 26) */ and %g1,%o1,%g3
-/* 0x0104 (26 27) */ sllx %g3,16,%g3
-/* 0x0108 ( 0 0) */ stx %g3,[%sp+120]
-/* 0x010c 77 (26 27) */ and %g4,%o3,%g3
-/* 0x0110 74 ( 0 0) */ stx %o7,[%sp+128]
-/* 0x0114 ( 0 0) */ ldx [%sp+120],%o7
-/* 0x0118 (27 27) */ add %g3,%o7,%g3
-/* 0x011c ( 0 0) */ ldx [%sp+128],%o7
-/* 0x0120 81 (28 29) */ srax %g1,16,%g1
-/* 0x0124 74 (28 28) */ add %g3,%o4,%g3
-/* 0x0128 81 (29 30) */ srax %g3,32,%o4
-/* 0x012c ( 0 0) */ stx %o4,[%sp+112]
-/* 0x0130 78 (30 31) */ srax %g4,32,%o4
-/* 0x0134 81 ( 0 0) */ ldx [%sp+112],%g4
-/* 0x0138 (30 31) */ add %g1,%g4,%g4
-/* 0x013c 79 (31 33) */ ldx [%sp+96],%g1
-/* 0x0140 81 (31 32) */ add %o4,%g4,%o4
-/* 0x0144 82 (32 33) */ and %g3,%o3,%g3
-/* 0x0148 84 ( 0 0) */ ldx [%sp+104],%g4
-/* 0x014c 85 (33 34) */ ble,pt %icc,.L900000209 ! tprob=0.50
-/* 0x0150 (33 34) */ st %g3,[%o5-4]
- .L900000212: /* frequency 8.0 confidence 0.0 */
-/* 0x0154 85 ( 0 1) */ ba .L900000214 ! tprob=1.00
-/* 0x0158 ( 0 1) */ sethi %hi(0xfc00),%g2
- .L77000134: /* frequency 0.7 confidence 0.0 */
- .L900000213: /* frequency 6.4 confidence 0.0 */
-/* 0x015c 77 ( 0 1) */ and %g4,%o3,%o0
-/* 0x0160 80 ( 0 1) */ and %g1,%o1,%g3
-/* 0x0164 76 ( 0 3) */ fdtox %f0,%f0
-/* 0x0168 77 ( 1 2) */ add %o4,%o0,%o0
-/* 0x016c 76 ( 1 2) */ std %f0,[%sp+104]
-/* 0x0170 85 ( 1 2) */ add %o7,1,%o7
-/* 0x0174 80 ( 2 3) */ sllx %g3,16,%o4
-/* 0x0178 79 ( 2 5) */ ldd [%g2+24],%f2
-/* 0x017c 85 ( 2 3) */ add %g2,16,%g2
-/* 0x0180 80 ( 3 4) */ add %o0,%o4,%o4
-/* 0x0184 81 ( 3 4) */ stx %o7,[%sp+128]
-/* 0x0188 ( 4 5) */ srax %g1,16,%o0
-/* 0x018c ( 4 5) */ stx %o0,[%sp+112]
-/* 0x0190 82 ( 4 5) */ and %o4,%o3,%g3
-/* 0x0194 81 ( 5 6) */ srax %o4,32,%o0
-/* 0x0198 ( 5 6) */ stx %o0,[%sp+120]
-/* 0x019c 79 ( 5 8) */ fdtox %f2,%f0
-/* 0x01a0 ( 6 7) */ std %f0,[%sp+96]
-/* 0x01a4 78 ( 6 7) */ srax %g4,32,%o4
-/* 0x01a8 81 ( 7 9) */ ldx [%sp+120],%o7
-/* 0x01ac ( 8 10) */ ldx [%sp+112],%g4
-/* 0x01b0 76 (10 12) */ ldx [%sp+104],%g1
-/* 0x01b4 81 (10 11) */ add %g4,%o7,%g4
-/* 0x01b8 (11 13) */ ldx [%sp+128],%o7
-/* 0x01bc (11 12) */ add %o4,%g4,%o4
-/* 0x01c0 79 (12 14) */ ldx [%sp+96],%o0
-/* 0x01c4 84 (12 13) */ or %g0,%g1,%g4
-/* 0x01c8 82 (13 14) */ st %g3,[%o5]
-/* 0x01cc 85 (13 14) */ add %o5,4,%o5
-/* 0x01d0 (13 14) */ cmp %o7,%o2
-/* 0x01d4 (14 15) */ or %g0,%o0,%g1
-/* 0x01d8 (14 15) */ ble,a,pt %icc,.L900000213 ! tprob=0.86
-/* 0x01dc (14 17) */ ldd [%g2+16],%f0
- .L77000127: /* frequency 1.0 confidence 0.0 */
-
-! 86 ! }
-! 87 ! t1+=a&0xffffffff;
-! 88 ! t=(a>>32);
-! 89 ! t1+=(b&0xffff)<<16;
-! 90 ! i32[i]=t1&0xffffffff;
-
-/* 0x01e0 90 ( 0 1) */ sethi %hi(0xfc00),%g2
- .L900000214: /* frequency 1.0 confidence 0.0 */
-/* 0x01e4 90 ( 0 1) */ or %g0,-1,%g3
-/* 0x01e8 ( 0 1) */ add %g2,1023,%g2
-/* 0x01ec ( 1 2) */ srl %g3,0,%g3
-/* 0x01f0 ( 1 2) */ and %g1,%g2,%g2
-/* 0x01f4 ( 2 3) */ and %g4,%g3,%g4
-/* 0x01f8 ( 3 4) */ sllx %g2,16,%g2
-/* 0x01fc ( 3 4) */ add %o4,%g4,%g4
-/* 0x0200 ( 4 5) */ add %g4,%g2,%g2
-/* 0x0204 ( 5 6) */ sll %o7,2,%g4
-/* 0x0208 ( 5 6) */ and %g2,%g3,%g2
-/* 0x020c ( 6 7) */ st %g2,[%g5+%g4]
-/* 0x0210 ( 7 9) */ ret ! Result =
-/* 0x0214 ( 9 10) */ restore %g0,%g0,%g0
-/* 0x0218 0 ( 0 0) */ .type conv_d16_to_i32,2
-/* 0x0218 ( 0 0) */ .size conv_d16_to_i32,(.-conv_d16_to_i32)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 ( 0 0) */ .align 8
-!
-! CONSTANT POOL
-!
- .L_const_seg_900000301: /* frequency 1.0 confidence 0.0 */
-/* 000000 0 ( 0 0) */ .word 1127219200,0
-/* 0x0008 0 ( 0 0) */ .align 4
-!
-! SUBROUTINE conv_i32_to_d32
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
-
- .global conv_i32_to_d32
- conv_i32_to_d32: /* frequency 1.0 confidence 0.0 */
-/* 000000 ( 0 1) */ orcc %g0,%o2,%g1
-
-! 92 !}
-! 94 !void conv_i32_to_d32(double *d32, unsigned int *i32, int len)
-! 95 !{
-! 96 !int i;
-! 98 !#pragma pipeloop(0)
-! 99 ! for(i=0;i<len;i++) d32[i]=(double)(i32[i]);
-
-/* 0x0004 99 ( 0 1) */ ble,pt %icc,.L77000140 ! tprob=0.56
-/* 0x0008 ( 0 1) */ nop
-/* 0x000c ( 1 2) */ sethi %hi(.L_const_seg_900000301),%g2
-/* 0x0010 95 ( 1 2) */ or %g0,%o1,%g4
-/* 0x0014 99 ( 2 3) */ add %g2,%lo(.L_const_seg_900000301),%g2
-/* 0x0018 ( 2 3) */ or %g0,0,%o5
-/* 0x001c 95 ( 3 4) */ or %g0,%o0,%g5
-/* 0x0020 99 ( 3 4) */ sub %o2,1,%g3
-/* 0x0024 ( 4 5) */ cmp %o2,9
-/* 0x0028 ( 4 5) */ bl,pn %icc,.L77000144 ! tprob=0.44
-/* 0x002c ( 4 7) */ ldd [%g2],%f8
-/* 0x0030 ( 5 8) */ ld [%o1],%f7
-/* 0x0034 ( 5 6) */ add %o1,16,%g4
-/* 0x0038 ( 5 6) */ sub %o2,5,%g1
-/* 0x003c ( 6 9) */ ld [%o1+4],%f5
-/* 0x0040 ( 6 7) */ or %g0,4,%o5
-/* 0x0044 ( 7 10) */ ld [%o1+8],%f3
-/* 0x0048 ( 7 8) */ fmovs %f8,%f6
-/* 0x004c ( 8 11) */ ld [%o1+12],%f1
- .L900000305: /* frequency 64.0 confidence 0.0 */
-/* 0x0050 ( 8 16) */ ld [%g4],%f11
-/* 0x0054 ( 8 9) */ add %o5,5,%o5
-/* 0x0058 ( 8 9) */ add %g4,20,%g4
-/* 0x005c ( 8 11) */ fsubd %f6,%f8,%f6
-/* 0x0060 ( 9 10) */ std %f6,[%g5]
-/* 0x0064 ( 9 9) */ cmp %o5,%g1
-/* 0x0068 ( 9 10) */ add %g5,40,%g5
-/* 0x006c ( 0 0) */ fmovs %f8,%f4
-/* 0x0070 (10 18) */ ld [%g4-16],%f7
-/* 0x0074 (10 13) */ fsubd %f4,%f8,%f12
-/* 0x0078 ( 0 0) */ fmovs %f8,%f2
-/* 0x007c (11 12) */ std %f12,[%g5-32]
-/* 0x0080 (12 20) */ ld [%g4-12],%f5
-/* 0x0084 (12 15) */ fsubd %f2,%f8,%f12
-/* 0x0088 ( 0 0) */ fmovs %f8,%f0
-/* 0x008c (13 14) */ std %f12,[%g5-24]
-/* 0x0090 (14 22) */ ld [%g4-8],%f3
-/* 0x0094 (14 17) */ fsubd %f0,%f8,%f12
-/* 0x0098 ( 0 0) */ fmovs %f8,%f10
-/* 0x009c (15 16) */ std %f12,[%g5-16]
-/* 0x00a0 (16 24) */ ld [%g4-4],%f1
-/* 0x00a4 (16 19) */ fsubd %f10,%f8,%f10
-/* 0x00a8 ( 0 0) */ fmovs %f8,%f6
-/* 0x00ac (17 18) */ ble,pt %icc,.L900000305 ! tprob=0.50
-/* 0x00b0 (17 18) */ std %f10,[%g5-8]
- .L900000308: /* frequency 8.0 confidence 0.0 */
-/* 0x00b4 ( 0 1) */ fmovs %f8,%f4
-/* 0x00b8 ( 0 1) */ add %g5,32,%g5
-/* 0x00bc ( 0 1) */ cmp %o5,%g3
-/* 0x00c0 ( 1 2) */ fmovs %f8,%f2
-/* 0x00c4 ( 2 3) */ fmovs %f8,%f0
-/* 0x00c8 ( 4 7) */ fsubd %f6,%f8,%f6
-/* 0x00cc ( 4 5) */ std %f6,[%g5-32]
-/* 0x00d0 ( 5 8) */ fsubd %f4,%f8,%f4
-/* 0x00d4 ( 5 6) */ std %f4,[%g5-24]
-/* 0x00d8 ( 6 9) */ fsubd %f2,%f8,%f2
-/* 0x00dc ( 6 7) */ std %f2,[%g5-16]
-/* 0x00e0 ( 7 10) */ fsubd %f0,%f8,%f0
-/* 0x00e4 ( 7 8) */ bg,pn %icc,.L77000140 ! tprob=0.14
-/* 0x00e8 ( 7 8) */ std %f0,[%g5-8]
- .L77000144: /* frequency 0.7 confidence 0.0 */
-/* 0x00ec ( 0 3) */ ld [%g4],%f1
- .L900000309: /* frequency 6.4 confidence 0.0 */
-/* 0x00f0 ( 0 3) */ ldd [%g2],%f8
-/* 0x00f4 ( 0 1) */ add %o5,1,%o5
-/* 0x00f8 ( 0 1) */ add %g4,4,%g4
-/* 0x00fc ( 1 2) */ cmp %o5,%g3
-/* 0x0100 ( 2 3) */ fmovs %f8,%f0
-/* 0x0104 ( 4 7) */ fsubd %f0,%f8,%f0
-/* 0x0108 ( 4 5) */ std %f0,[%g5]
-/* 0x010c ( 4 5) */ add %g5,8,%g5
-/* 0x0110 ( 4 5) */ ble,a,pt %icc,.L900000309 ! tprob=0.86
-/* 0x0114 ( 6 9) */ ld [%g4],%f1
- .L77000140: /* frequency 1.0 confidence 0.0 */
-/* 0x0118 ( 0 2) */ retl ! Result =
-/* 0x011c ( 1 2) */ nop
-/* 0x0120 0 ( 0 0) */ .type conv_i32_to_d32,2
-/* 0x0120 ( 0 0) */ .size conv_i32_to_d32,(.-conv_i32_to_d32)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 ( 0 0) */ .align 8
-!
-! CONSTANT POOL
-!
- .L_const_seg_900000401: /* frequency 1.0 confidence 0.0 */
-/* 000000 0 ( 0 0) */ .word 1127219200,0
-/* 0x0008 0 ( 0 0) */ .align 4
-!
-! SUBROUTINE conv_i32_to_d16
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
-
- .global conv_i32_to_d16
- conv_i32_to_d16: /* frequency 1.0 confidence 0.0 */
-/* 000000 ( 0 1) */ save %sp,-104,%sp
-/* 0x0004 ( 1 2) */ orcc %g0,%i2,%o0
-
-! 100 !}
-! 103 !void conv_i32_to_d16(double *d16, unsigned int *i32, int len)
-! 104 !{
-! 105 !int i;
-! 106 !unsigned int a;
-! 108 !#pragma pipeloop(0)
-! 109 ! for(i=0;i<len;i++)
-
-/* 0x0008 109 ( 1 2) */ ble,pt %icc,.L77000150 ! tprob=0.56
-/* 0x000c ( 1 2) */ nop
-/* 0x0010 ( 2 3) */ sub %o0,1,%o5
-/* 0x0014 ( 2 3) */ sethi %hi(0xfc00),%g2
-
-! 110 ! {
-! 111 ! a=i32[i];
-! 112 ! d16[2*i]=(double)(a&0xffff);
-! 113 ! d16[2*i+1]=(double)(a>>16);
-
-/* 0x0018 113 ( 3 4) */ sethi %hi(.L_const_seg_900000401),%o0
-/* 0x001c ( 3 4) */ add %o5,1,%g3
-/* 0x0020 ( 4 5) */ add %g2,1023,%o4
-/* 0x0024 109 ( 4 5) */ or %g0,0,%g1
-/* 0x0028 ( 5 6) */ cmp %g3,3
-/* 0x002c ( 5 6) */ or %g0,%i1,%o7
-/* 0x0030 ( 6 7) */ add %o0,%lo(.L_const_seg_900000401),%o3
-/* 0x0034 ( 6 7) */ or %g0,%i0,%g2
-/* 0x0038 ( 6 7) */ bl,pn %icc,.L77000154 ! tprob=0.44
-/* 0x003c ( 7 8) */ add %o7,4,%o0
-/* 0x0040 112 ( 7 10) */ ldd [%o3],%f0
-/* 0x0044 113 ( 7 8) */ or %g0,1,%g1
-/* 0x0048 111 ( 8 11) */ ld [%o0-4],%o1
-/* 0x004c 0 ( 8 9) */ or %g0,%o0,%o7
-/* 0x0050 112 (10 11) */ and %o1,%o4,%o0
- .L900000406: /* frequency 64.0 confidence 0.0 */
-/* 0x0054 112 (22 23) */ st %o0,[%sp+96]
-/* 0x0058 113 (22 23) */ add %g1,1,%g1
-/* 0x005c (22 23) */ add %g2,16,%g2
-/* 0x0060 (23 23) */ cmp %g1,%o5
-/* 0x0064 (23 24) */ add %o7,4,%o7
-/* 0x0068 112 (29 31) */ ld [%sp+96],%f3
-/* 0x006c ( 0 0) */ fmovs %f0,%f2
-/* 0x0070 (31 34) */ fsubd %f2,%f0,%f2
-/* 0x0074 113 (32 33) */ srl %o1,16,%o0
-/* 0x0078 112 (32 33) */ std %f2,[%g2-16]
-/* 0x007c 113 (33 34) */ st %o0,[%sp+92]
-/* 0x0080 (40 42) */ ld [%sp+92],%f3
-/* 0x0084 111 (41 43) */ ld [%o7-4],%o1
-/* 0x0088 113 ( 0 0) */ fmovs %f0,%f2
-/* 0x008c (42 45) */ fsubd %f2,%f0,%f2
-/* 0x0090 112 (43 44) */ and %o1,%o4,%o0
-/* 0x0094 113 (43 44) */ ble,pt %icc,.L900000406 ! tprob=0.50
-/* 0x0098 (43 44) */ std %f2,[%g2-8]
- .L900000409: /* frequency 8.0 confidence 0.0 */
-/* 0x009c 112 ( 0 1) */ st %o0,[%sp+96]
-/* 0x00a0 ( 0 1) */ fmovs %f0,%f2
-/* 0x00a4 113 ( 0 1) */ add %g2,16,%g2
-/* 0x00a8 ( 1 2) */ srl %o1,16,%o0
-/* 0x00ac 112 ( 4 7) */ ld [%sp+96],%f3
-/* 0x00b0 ( 6 9) */ fsubd %f2,%f0,%f2
-/* 0x00b4 ( 6 7) */ std %f2,[%g2-16]
-/* 0x00b8 113 ( 7 8) */ st %o0,[%sp+92]
-/* 0x00bc (10 11) */ fmovs %f0,%f2
-/* 0x00c0 (11 14) */ ld [%sp+92],%f3
-/* 0x00c4 (13 16) */ fsubd %f2,%f0,%f0
-/* 0x00c8 (13 14) */ std %f0,[%g2-8]
-/* 0x00cc (14 16) */ ret ! Result =
-/* 0x00d0 (16 17) */ restore %g0,%g0,%g0
- .L77000154: /* frequency 0.7 confidence 0.0 */
-/* 0x00d4 111 ( 0 3) */ ld [%o7],%o0
- .L900000410: /* frequency 6.4 confidence 0.0 */
-/* 0x00d8 112 ( 0 1) */ and %o0,%o4,%o1
-/* 0x00dc ( 0 1) */ st %o1,[%sp+96]
-/* 0x00e0 113 ( 0 1) */ add %g1,1,%g1
-/* 0x00e4 112 ( 1 4) */ ldd [%o3],%f0
-/* 0x00e8 113 ( 1 2) */ srl %o0,16,%o0
-/* 0x00ec ( 1 2) */ add %o7,4,%o7
-/* 0x00f0 ( 2 3) */ cmp %g1,%o5
-/* 0x00f4 112 ( 3 4) */ fmovs %f0,%f2
-/* 0x00f8 ( 4 7) */ ld [%sp+96],%f3
-/* 0x00fc ( 6 9) */ fsubd %f2,%f0,%f2
-/* 0x0100 ( 6 7) */ std %f2,[%g2]
-/* 0x0104 113 ( 7 8) */ st %o0,[%sp+92]
-/* 0x0108 (10 11) */ fmovs %f0,%f2
-/* 0x010c (11 14) */ ld [%sp+92],%f3
-/* 0x0110 (13 16) */ fsubd %f2,%f0,%f0
-/* 0x0114 (13 14) */ std %f0,[%g2+8]
-/* 0x0118 (13 14) */ add %g2,16,%g2
-/* 0x011c (13 14) */ ble,a,pt %icc,.L900000410 ! tprob=0.86
-/* 0x0120 (14 17) */ ld [%o7],%o0
- .L77000150: /* frequency 1.0 confidence 0.0 */
-/* 0x0124 ( 0 2) */ ret ! Result =
-/* 0x0128 ( 2 3) */ restore %g0,%g0,%g0
-/* 0x012c 0 ( 0 0) */ .type conv_i32_to_d16,2
-/* 0x012c ( 0 0) */ .size conv_i32_to_d16,(.-conv_i32_to_d16)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 ( 0 0) */ .align 8
-!
-! CONSTANT POOL
-!
- .L_const_seg_900000501: /* frequency 1.0 confidence 0.0 */
-/* 000000 0 ( 0 0) */ .word 1127219200,0
-/* 0x0008 0 ( 0 0) */ .align 4
-!
-! SUBROUTINE conv_i32_to_d32_and_d16
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
-
- .global conv_i32_to_d32_and_d16
- conv_i32_to_d32_and_d16: /* frequency 1.0 confidence 0.0 */
-/* 000000 ( 0 1) */ save %sp,-104,%sp
-/* 0x0004 ( 1 2) */ or %g0,%i3,%i4
-/* 0x0008 ( 1 2) */ or %g0,%i2,%g1
-
-! 114 ! }
-! 115 !}
-! 118 !void i16_to_d16_and_d32x4(double * /*1/(2^16)*/, double * /* 2^16*/,
-! 119 ! double * /* 0 */,
-! 120 ! double * /*result16*/, double * /* result32 */,
-! 121 ! float * /*source - should be unsigned int*
-! 122 ! converted to float* */);
-! 126 !void conv_i32_to_d32_and_d16(double *d32, double *d16,
-! 127 ! unsigned int *i32, int len)
-! 128 !{
-! 129 !int i;
-! 130 !unsigned int a;
-! 132 !#pragma pipeloop(0)
-! 133 ! for(i=0;i<len-3;i+=4)
-
-/* 0x000c 133 ( 2 3) */ sub %i4,3,%g2
-/* 0x0010 ( 2 3) */ or %g0,0,%o7
-/* 0x0014 ( 3 4) */ cmp %g2,0
-/* 0x0018 128 ( 3 4) */ or %g0,%i0,%i3
-/* 0x001c 133 ( 3 4) */ ble,pt %icc,.L900000515 ! tprob=0.56
-/* 0x0020 ( 4 5) */ cmp %o7,%i4
-
-! 134 ! {
-! 135 ! i16_to_d16_and_d32x4(&TwoToMinus16, &TwoTo16, &Zero,
-! 136 ! &(d16[2*i]), &(d32[i]), (float *)(&(i32[i])));
-
-/* 0x0024 136 ( 4 5) */ sethi %hi(Zero),%g2
-/* 0x0028 133 ( 5 6) */ or %g0,%g1,%o3
-/* 0x002c ( 5 6) */ sub %i4,4,%o2
-/* 0x0030 136 ( 6 7) */ add %g2,%lo(Zero),%o1
-/* 0x0034 133 ( 6 7) */ or %g0,0,%o5
-/* 0x0038 ( 7 8) */ or %g0,0,%o4
-/* 0x003c 136 ( 7 8) */ or %g0,%o3,%g4
- .L900000514: /* frequency 6.4 confidence 0.0 */
-/* 0x0040 ( 0 3) */ ldd [%o1],%f2
-/* 0x0044 136 ( 0 1) */ add %i3,%o5,%g2
-/* 0x0048 ( 0 1) */ add %i1,%o4,%g3
-/* 0x004c ( 1 4) */ ldd [%o1-8],%f0
-/* 0x0050 ( 1 2) */ add %o7,4,%o7
-/* 0x0054 ( 1 2) */ add %o3,16,%o3
-/* 0x0058 ( 2 3) */ fmovd %f2,%f14
-/* 0x005c ( 2 5) */ ld [%g4],%f15
-/* 0x0060 ( 2 3) */ cmp %o7,%o2
-/* 0x0064 ( 3 4) */ fmovd %f2,%f10
-/* 0x0068 ( 3 6) */ ld [%g4+4],%f11
-/* 0x006c ( 4 5) */ fmovd %f2,%f6
-/* 0x0070 ( 4 7) */ ld [%g4+8],%f7
-/* 0x0074 ( 5 8) */ ld [%g4+12],%f3
-/* 0x0078 ( 5 8) */ fxtod %f14,%f14
-/* 0x007c ( 6 9) */ fxtod %f10,%f10
-/* 0x0080 ( 6 9) */ ldd [%o1-16],%f16
-/* 0x0084 ( 7 10) */ fxtod %f6,%f6
-/* 0x0088 ( 7 8) */ std %f14,[%i3+%o5]
-/* 0x008c ( 7 8) */ add %o5,32,%o5
-/* 0x0090 ( 8 11) */ fxtod %f2,%f2
-/* 0x0094 ( 8 11) */ fmuld %f0,%f14,%f12
-/* 0x0098 ( 8 9) */ std %f10,[%g2+8]
-/* 0x009c ( 9 12) */ fmuld %f0,%f10,%f8
-/* 0x00a0 ( 9 10) */ std %f6,[%g2+16]
-/* 0x00a4 (10 13) */ fmuld %f0,%f6,%f4
-/* 0x00a8 (10 11) */ std %f2,[%g2+24]
-/* 0x00ac (11 14) */ fmuld %f0,%f2,%f0
-/* 0x00b0 (11 14) */ fdtox %f12,%f12
-/* 0x00b4 (12 15) */ fdtox %f8,%f8
-/* 0x00b8 (13 16) */ fdtox %f4,%f4
-/* 0x00bc (14 17) */ fdtox %f0,%f0
-/* 0x00c0 (15 18) */ fxtod %f12,%f12
-/* 0x00c4 (15 16) */ std %f12,[%g3+8]
-/* 0x00c8 (16 19) */ fxtod %f8,%f8
-/* 0x00cc (16 17) */ std %f8,[%g3+24]
-/* 0x00d0 (17 20) */ fxtod %f4,%f4
-/* 0x00d4 (17 18) */ std %f4,[%g3+40]
-/* 0x00d8 (18 21) */ fxtod %f0,%f0
-/* 0x00dc (18 21) */ fmuld %f12,%f16,%f12
-/* 0x00e0 (18 19) */ std %f0,[%g3+56]
-/* 0x00e4 (19 22) */ fmuld %f8,%f16,%f8
-/* 0x00e8 (20 23) */ fmuld %f4,%f16,%f4
-/* 0x00ec (21 24) */ fmuld %f0,%f16,%f0
-/* 0x00f0 (21 24) */ fsubd %f14,%f12,%f12
-/* 0x00f4 (21 22) */ std %f12,[%i1+%o4]
-/* 0x00f8 (22 25) */ fsubd %f10,%f8,%f8
-/* 0x00fc (22 23) */ std %f8,[%g3+16]
-/* 0x0100 (22 23) */ add %o4,64,%o4
-/* 0x0104 (23 26) */ fsubd %f6,%f4,%f4
-/* 0x0108 (23 24) */ std %f4,[%g3+32]
-/* 0x010c (24 27) */ fsubd %f2,%f0,%f0
-/* 0x0110 (24 25) */ std %f0,[%g3+48]
-/* 0x0114 (24 25) */ ble,pt %icc,.L900000514 ! tprob=0.86
-/* 0x0118 (25 26) */ or %g0,%o3,%g4
- .L77000159: /* frequency 1.0 confidence 0.0 */
-
-! 137 ! }
-! 138 ! for(;i<len;i++)
-
-/* 0x011c 138 ( 0 1) */ cmp %o7,%i4
- .L900000515: /* frequency 1.0 confidence 0.0 */
-/* 0x0120 138 ( 0 1) */ bge,pt %icc,.L77000164 ! tprob=0.56
-/* 0x0124 ( 0 1) */ nop
-
-! 139 ! {
-! 140 ! a=i32[i];
-! 141 ! d32[i]=(double)(i32[i]);
-! 142 ! d16[2*i]=(double)(a&0xffff);
-! 143 ! d16[2*i+1]=(double)(a>>16);
-
-/* 0x0128 143 ( 0 1) */ sethi %hi(.L_const_seg_900000501),%o1
-/* 0x012c 138 ( 1 2) */ sethi %hi(0xfc00),%o0
-/* 0x0130 141 ( 1 4) */ ldd [%o1+%lo(.L_const_seg_900000501)],%f0
-/* 0x0134 138 ( 1 2) */ sub %i4,%o7,%g3
-/* 0x0138 ( 2 3) */ sll %o7,2,%g2
-/* 0x013c ( 2 3) */ add %o0,1023,%o3
-/* 0x0140 ( 3 4) */ sll %o7,3,%g4
-/* 0x0144 ( 3 4) */ cmp %g3,3
-/* 0x0148 ( 4 5) */ add %g1,%g2,%o0
-/* 0x014c ( 4 5) */ add %o1,%lo(.L_const_seg_900000501),%o2
-/* 0x0150 ( 5 6) */ add %i3,%g4,%o4
-/* 0x0154 ( 5 6) */ sub %i4,1,%o1
-/* 0x0158 ( 6 7) */ sll %o7,4,%g5
-/* 0x015c ( 6 7) */ bl,pn %icc,.L77000161 ! tprob=0.44
-/* 0x0160 ( 7 8) */ add %i1,%g5,%o5
-/* 0x0164 141 ( 7 10) */ ld [%g1+%g2],%f3
-/* 0x0168 143 ( 7 8) */ add %o4,8,%o4
-/* 0x016c 140 ( 8 11) */ ld [%g1+%g2],%g1
-/* 0x0170 143 ( 8 9) */ add %o5,16,%o5
-/* 0x0174 ( 8 9) */ add %o7,1,%o7
-/* 0x0178 141 ( 9 10) */ fmovs %f0,%f2
-/* 0x017c 143 ( 9 10) */ add %o0,4,%o0
-/* 0x0180 142 (10 11) */ and %g1,%o3,%g2
-/* 0x0184 141 (11 14) */ fsubd %f2,%f0,%f2
-/* 0x0188 (11 12) */ std %f2,[%o4-8]
-/* 0x018c 143 (11 12) */ srl %g1,16,%g1
-/* 0x0190 142 (12 13) */ st %g2,[%sp+96]
-/* 0x0194 (15 16) */ fmovs %f0,%f2
-/* 0x0198 (16 19) */ ld [%sp+96],%f3
-/* 0x019c (18 21) */ fsubd %f2,%f0,%f2
-/* 0x01a0 (18 19) */ std %f2,[%o5-16]
-/* 0x01a4 143 (19 20) */ st %g1,[%sp+92]
-/* 0x01a8 (22 23) */ fmovs %f0,%f2
-/* 0x01ac (23 26) */ ld [%sp+92],%f3
-/* 0x01b0 (25 28) */ fsubd %f2,%f0,%f2
-/* 0x01b4 (25 26) */ std %f2,[%o5-8]
- .L900000509: /* frequency 64.0 confidence 0.0 */
-/* 0x01b8 141 (26 28) */ ld [%o0],%f3
-/* 0x01bc 143 (26 27) */ add %o7,2,%o7
-/* 0x01c0 (26 27) */ add %o5,32,%o5
-/* 0x01c4 140 (27 29) */ ld [%o0],%g1
-/* 0x01c8 143 (27 27) */ cmp %o7,%o1
-/* 0x01cc (27 28) */ add %o4,16,%o4
-/* 0x01d0 141 ( 0 0) */ fmovs %f0,%f2
-/* 0x01d4 (28 31) */ fsubd %f2,%f0,%f2
-/* 0x01d8 (29 30) */ std %f2,[%o4-16]
-/* 0x01dc 142 (29 30) */ and %g1,%o3,%g2
-/* 0x01e0 (30 31) */ st %g2,[%sp+96]
-/* 0x01e4 (37 39) */ ld [%sp+96],%f3
-/* 0x01e8 ( 0 0) */ fmovs %f0,%f2
-/* 0x01ec (39 42) */ fsubd %f2,%f0,%f2
-/* 0x01f0 143 (40 41) */ srl %g1,16,%g1
-/* 0x01f4 142 (40 41) */ std %f2,[%o5-32]
-/* 0x01f8 143 (41 42) */ st %g1,[%sp+92]
-/* 0x01fc (48 50) */ ld [%sp+92],%f3
-/* 0x0200 ( 0 0) */ fmovs %f0,%f2
-/* 0x0204 (50 53) */ fsubd %f2,%f0,%f2
-/* 0x0208 (51 52) */ std %f2,[%o5-24]
-/* 0x020c (51 52) */ add %o0,4,%o0
-/* 0x0210 141 (52 54) */ ld [%o0],%f3
-/* 0x0214 140 (53 55) */ ld [%o0],%g1
-/* 0x0218 141 ( 0 0) */ fmovs %f0,%f2
-/* 0x021c (54 57) */ fsubd %f2,%f0,%f2
-/* 0x0220 (55 56) */ std %f2,[%o4-8]
-/* 0x0224 142 (55 56) */ and %g1,%o3,%g2
-/* 0x0228 (56 57) */ st %g2,[%sp+96]
-/* 0x022c (63 65) */ ld [%sp+96],%f3
-/* 0x0230 ( 0 0) */ fmovs %f0,%f2
-/* 0x0234 (65 68) */ fsubd %f2,%f0,%f2
-/* 0x0238 143 (66 67) */ srl %g1,16,%g1
-/* 0x023c 142 (66 67) */ std %f2,[%o5-16]
-/* 0x0240 143 (67 68) */ st %g1,[%sp+92]
-/* 0x0244 (74 76) */ ld [%sp+92],%f3
-/* 0x0248 ( 0 0) */ fmovs %f0,%f2
-/* 0x024c (76 79) */ fsubd %f2,%f0,%f2
-/* 0x0250 (77 78) */ std %f2,[%o5-8]
-/* 0x0254 (77 78) */ bl,pt %icc,.L900000509 ! tprob=0.50
-/* 0x0258 (77 78) */ add %o0,4,%o0
- .L900000512: /* frequency 8.0 confidence 0.0 */
-/* 0x025c 143 ( 0 1) */ cmp %o7,%i4
-/* 0x0260 ( 0 1) */ bge,pn %icc,.L77000164 ! tprob=0.14
-/* 0x0264 ( 0 1) */ nop
- .L77000161: /* frequency 0.7 confidence 0.0 */
-/* 0x0268 141 ( 0 3) */ ld [%o0],%f3
- .L900000513: /* frequency 6.4 confidence 0.0 */
-/* 0x026c 141 ( 0 3) */ ldd [%o2],%f0
-/* 0x0270 143 ( 0 1) */ add %o7,1,%o7
-/* 0x0274 140 ( 1 4) */ ld [%o0],%o1
-/* 0x0278 143 ( 1 2) */ add %o0,4,%o0
-/* 0x027c ( 1 2) */ cmp %o7,%i4
-/* 0x0280 141 ( 2 3) */ fmovs %f0,%f2
-/* 0x0284 142 ( 3 4) */ and %o1,%o3,%g1
-/* 0x0288 141 ( 4 7) */ fsubd %f2,%f0,%f2
-/* 0x028c ( 4 5) */ std %f2,[%o4]
-/* 0x0290 143 ( 4 5) */ srl %o1,16,%o1
-/* 0x0294 142 ( 5 6) */ st %g1,[%sp+96]
-/* 0x0298 143 ( 5 6) */ add %o4,8,%o4
-/* 0x029c 142 ( 8 9) */ fmovs %f0,%f2
-/* 0x02a0 ( 9 12) */ ld [%sp+96],%f3
-/* 0x02a4 (11 14) */ fsubd %f2,%f0,%f2
-/* 0x02a8 (11 12) */ std %f2,[%o5]
-/* 0x02ac 143 (12 13) */ st %o1,[%sp+92]
-/* 0x02b0 (15 16) */ fmovs %f0,%f2
-/* 0x02b4 (16 19) */ ld [%sp+92],%f3
-/* 0x02b8 (18 21) */ fsubd %f2,%f0,%f0
-/* 0x02bc (18 19) */ std %f0,[%o5+8]
-/* 0x02c0 (18 19) */ add %o5,16,%o5
-/* 0x02c4 (18 19) */ bl,a,pt %icc,.L900000513 ! tprob=0.86
-/* 0x02c8 (19 22) */ ld [%o0],%f3
- .L77000164: /* frequency 1.0 confidence 0.0 */
-/* 0x02cc ( 0 2) */ ret ! Result =
-/* 0x02d0 ( 2 3) */ restore %g0,%g0,%g0
-/* 0x02d4 0 ( 0 0) */ .type conv_i32_to_d32_and_d16,2
-/* 0x02d4 ( 0 0) */ .size conv_i32_to_d32_and_d16,(.-conv_i32_to_d32_and_d16)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 ( 0 0) */ .align 4
-!
-! SUBROUTINE adjust_montf_result
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
-
- .global adjust_montf_result
- adjust_montf_result: /* frequency 1.0 confidence 0.0 */
-
-! 144 ! }
-! 145 !}
-! 148 !void adjust_montf_result(unsigned int *i32, unsigned int *nint, int len)
-! 149 !{
-! 150 !long long acc;
-! 151 !int i;
-! 153 ! if(i32[len]>0) i=-1;
-
-/* 000000 153 ( 0 1) */ sll %o2,2,%g1
-/* 0x0004 ( 0 1) */ or %g0,-1,%g3
-/* 0x0008 ( 1 4) */ ld [%o0+%g1],%g1
-/* 0x000c ( 3 4) */ cmp %g1,0
-/* 0x0010 ( 3 4) */ bleu,pn %icc,.L77000175 ! tprob=0.50
-/* 0x0014 ( 3 4) */ or %g0,%o1,%o3
-/* 0x0018 ( 4 5) */ ba .L900000611 ! tprob=1.00
-/* 0x001c ( 4 5) */ cmp %g3,0
- .L77000175: /* frequency 0.8 confidence 0.0 */
-
-! 154 ! else
-! 155 ! {
-! 156 ! for(i=len-1; i>=0; i++)
-
-/* 0x0020 156 ( 0 1) */ subcc %o2,1,%g3
-/* 0x0024 ( 0 1) */ bneg,pt %icc,.L900000611 ! tprob=0.60
-/* 0x0028 ( 1 2) */ cmp %g3,0
-/* 0x002c ( 1 2) */ sll %g3,2,%g1
-/* 0x0030 ( 2 3) */ add %o0,%g1,%g2
-/* 0x0034 ( 2 3) */ add %o1,%g1,%g1
-
-! 157 ! {
-! 158 ! if(i32[i]!=nint[i]) break;
-
-/* 0x0038 158 ( 3 6) */ ld [%g1],%g5
- .L900000610: /* frequency 5.3 confidence 0.0 */
-/* 0x003c 158 ( 0 3) */ ld [%g2],%o5
-/* 0x0040 ( 0 1) */ add %g1,4,%g1
-/* 0x0044 ( 0 1) */ add %g2,4,%g2
-/* 0x0048 ( 2 3) */ cmp %o5,%g5
-/* 0x004c ( 2 3) */ bne,pn %icc,.L77000182 ! tprob=0.16
-/* 0x0050 ( 2 3) */ nop
-/* 0x0054 ( 3 4) */ addcc %g3,1,%g3
-/* 0x0058 ( 3 4) */ bpos,a,pt %icc,.L900000610 ! tprob=0.84
-/* 0x005c ( 3 6) */ ld [%g1],%g5
- .L77000182: /* frequency 1.0 confidence 0.0 */
-
-! 159 ! }
-! 160 ! }
-! 161 ! if((i<0)||(i32[i]>nint[i]))
-
-/* 0x0060 161 ( 0 1) */ cmp %g3,0
- .L900000611: /* frequency 1.0 confidence 0.0 */
-/* 0x0064 161 ( 0 1) */ bl,pn %icc,.L77000198 ! tprob=0.50
-/* 0x0068 ( 0 1) */ sll %g3,2,%g2
-/* 0x006c ( 1 4) */ ld [%o1+%g2],%g1
-/* 0x0070 ( 2 5) */ ld [%o0+%g2],%g2
-/* 0x0074 ( 4 5) */ cmp %g2,%g1
-/* 0x0078 ( 4 5) */ bleu,pt %icc,.L77000191 ! tprob=0.56
-/* 0x007c ( 4 5) */ nop
- .L77000198: /* frequency 0.8 confidence 0.0 */
-
-! 162 ! {
-! 163 ! acc=0;
-! 164 ! for(i=0;i<len;i++)
-
-/* 0x0080 164 ( 0 1) */ cmp %o2,0
-/* 0x0084 ( 0 1) */ ble,pt %icc,.L77000191 ! tprob=0.60
-/* 0x0088 ( 0 1) */ nop
-/* 0x008c 161 ( 1 2) */ or %g0,-1,%g2
-/* 0x0090 ( 1 2) */ sub %o2,1,%g4
-/* 0x0094 ( 2 3) */ srl %g2,0,%g3
-/* 0x0098 163 ( 2 3) */ or %g0,0,%g5
-/* 0x009c 164 ( 3 4) */ or %g0,0,%o5
-/* 0x00a0 161 ( 3 4) */ or %g0,%o0,%o4
-/* 0x00a4 ( 4 5) */ cmp %o2,3
-/* 0x00a8 ( 4 5) */ add %o1,4,%g2
-/* 0x00ac 164 ( 4 5) */ bl,pn %icc,.L77000199 ! tprob=0.40
-/* 0x00b0 ( 5 6) */ add %o0,8,%g1
-
-! 165 ! {
-! 166 ! acc=acc+(unsigned long long)(i32[i])-(unsigned long long)(nint[i]);
-
-/* 0x00b4 166 ( 5 8) */ ld [%o0],%o2
-/* 0x00b8 0 ( 5 6) */ or %g0,%g2,%o3
-/* 0x00bc 166 ( 6 9) */ ld [%o1],%o1
-/* 0x00c0 0 ( 6 7) */ or %g0,%g1,%o4
-
-! 167 ! i32[i]=acc&0xffffffff;
-! 168 ! acc=acc>>32;
-
-/* 0x00c4 168 ( 6 7) */ or %g0,2,%o5
-/* 0x00c8 166 ( 7 10) */ ld [%o0+4],%g1
-/* 0x00cc 164 ( 8 9) */ sub %o2,%o1,%o2
-/* 0x00d0 ( 9 10) */ or %g0,%o2,%g5
-/* 0x00d4 167 ( 9 10) */ and %o2,%g3,%o2
-/* 0x00d8 ( 9 10) */ st %o2,[%o0]
-/* 0x00dc 168 (10 11) */ srax %g5,32,%g5
- .L900000605: /* frequency 64.0 confidence 0.0 */
-/* 0x00e0 166 (12 20) */ ld [%o3],%o2
-/* 0x00e4 168 (12 13) */ add %o5,1,%o5
-/* 0x00e8 (12 13) */ add %o3,4,%o3
-/* 0x00ec (13 13) */ cmp %o5,%g4
-/* 0x00f0 (13 14) */ add %o4,4,%o4
-/* 0x00f4 164 (14 14) */ sub %g1,%o2,%g1
-/* 0x00f8 (15 15) */ add %g1,%g5,%g5
-/* 0x00fc 167 (16 17) */ and %g5,%g3,%o2
-/* 0x0100 166 (16 24) */ ld [%o4-4],%g1
-/* 0x0104 167 (17 18) */ st %o2,[%o4-8]
-/* 0x0108 168 (17 18) */ ble,pt %icc,.L900000605 ! tprob=0.50
-/* 0x010c (17 18) */ srax %g5,32,%g5
- .L900000608: /* frequency 8.0 confidence 0.0 */
-/* 0x0110 166 ( 0 3) */ ld [%o3],%g2
-/* 0x0114 164 ( 2 3) */ sub %g1,%g2,%g1
-/* 0x0118 ( 3 4) */ add %g1,%g5,%g1
-/* 0x011c 167 ( 4 5) */ and %g1,%g3,%g2
-/* 0x0120 ( 5 7) */ retl ! Result =
-/* 0x0124 ( 6 7) */ st %g2,[%o4-4]
- .L77000199: /* frequency 0.6 confidence 0.0 */
-/* 0x0128 166 ( 0 3) */ ld [%o4],%g1
- .L900000609: /* frequency 5.3 confidence 0.0 */
-/* 0x012c 166 ( 0 3) */ ld [%o3],%g2
-/* 0x0130 ( 0 1) */ add %g5,%g1,%g1
-/* 0x0134 168 ( 0 1) */ add %o5,1,%o5
-/* 0x0138 ( 1 2) */ add %o3,4,%o3
-/* 0x013c ( 1 2) */ cmp %o5,%g4
-/* 0x0140 166 ( 2 3) */ sub %g1,%g2,%g1
-/* 0x0144 167 ( 3 4) */ and %g1,%g3,%g2
-/* 0x0148 ( 3 4) */ st %g2,[%o4]
-/* 0x014c 168 ( 3 4) */ add %o4,4,%o4
-/* 0x0150 ( 4 5) */ srax %g1,32,%g5
-/* 0x0154 ( 4 5) */ ble,a,pt %icc,.L900000609 ! tprob=0.84
-/* 0x0158 ( 4 7) */ ld [%o4],%g1
- .L77000191: /* frequency 1.0 confidence 0.0 */
-/* 0x015c ( 0 2) */ retl ! Result =
-/* 0x0160 ( 1 2) */ nop
-/* 0x0164 0 ( 0 0) */ .type adjust_montf_result,2
-/* 0x0164 ( 0 0) */ .size adjust_montf_result,(.-adjust_montf_result)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 ( 0 0) */ .align 32
-!
-! SUBROUTINE mont_mulf_noconv
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
-
- .global mont_mulf_noconv
- mont_mulf_noconv: /* frequency 1.0 confidence 0.0 */
-/* 000000 ( 0 1) */ save %sp,-144,%sp
-/* 0x0004 ( 1 2) */ st %i0,[%fp+68]
-
-! 169 ! }
-! 170 ! }
-! 171 !}
-! 175 !void cleanup(double *dt, int from, int tlen);
-! 177 !/*
-! 178 !** the lengths of the input arrays should be at least the following:
-! 179 !** result[nlen+1], dm1[nlen], dm2[2*nlen+1], dt[4*nlen+2], dn[nlen], nint[nlen]
-! 180 !** all of them should be different from one another
-! 181 !**
-! 182 !*/
-! 183 !void mont_mulf_noconv(unsigned int *result,
-! 184 ! double *dm1, double *dm2, double *dt,
-! 185 ! double *dn, unsigned int *nint,
-! 186 ! int nlen, double dn0)
-! 187 !{
-! 188 ! int i, j, jj;
-! 189 ! int tmp;
-! 190 ! double digit, m2j, nextm2j, a, b;
-! 191 ! double *dptmp, *pdm1, *pdm2, *pdn, *pdtj, pdn_0, pdm1_0;
-! 193 ! pdm1=&(dm1[0]);
-! 194 ! pdm2=&(dm2[0]);
-! 195 ! pdn=&(dn[0]);
-! 196 ! pdm2[2*nlen]=Zero;
-
-/* 0x0008 196 ( 1 2) */ sethi %hi(Zero),%g2
-/* 0x000c 187 ( 1 2) */ or %g0,%i2,%o1
-/* 0x0010 ( 2 3) */ st %i5,[%fp+88]
-/* 0x0014 ( 2 3) */ or %g0,%i3,%o2
-/* 0x0018 196 ( 2 3) */ add %g2,%lo(Zero),%g4
-/* 0x001c ( 3 6) */ ldd [%g2+%lo(Zero)],%f2
-/* 0x0020 187 ( 3 4) */ or %g0,%o2,%g5
-/* 0x0024 196 ( 3 4) */ or %g0,%o1,%i0
-/* 0x0028 187 ( 4 5) */ or %g0,%i4,%i2
-
-! 198 ! if (nlen!=16)
-! 199 ! {
-! 200 ! for(i=0;i<4*nlen+2;i++) dt[i]=Zero;
-! 202 ! a=dt[0]=pdm1[0]*pdm2[0];
-! 203 ! digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16);
-! 205 ! pdtj=&(dt[0]);
-! 206 ! for(j=jj=0;j<2*nlen;j++,jj++,pdtj++)
-! 207 ! {
-! 208 ! m2j=pdm2[j];
-! 209 ! a=pdtj[0]+pdn[0]*digit;
-! 210 ! b=pdtj[1]+pdm1[0]*pdm2[j+1]+a*TwoToMinus16;
-! 211 ! pdtj[1]=b;
-! 213 !#pragma pipeloop(0)
-! 214 ! for(i=1;i<nlen;i++)
-! 215 ! {
-! 216 ! pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit;
-! 217 ! }
-! 218 ! if((jj==30)) {cleanup(dt,j/2+1,2*nlen+1); jj=0;}
-! 219 !
-! 220 ! digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16);
-! 221 ! }
-! 222 ! }
-! 223 ! else
-! 224 ! {
-! 225 ! a=dt[0]=pdm1[0]*pdm2[0];
-! 227 ! dt[65]= dt[64]= dt[63]= dt[62]= dt[61]= dt[60]=
-! 228 ! dt[59]= dt[58]= dt[57]= dt[56]= dt[55]= dt[54]=
-! 229 ! dt[53]= dt[52]= dt[51]= dt[50]= dt[49]= dt[48]=
-! 230 ! dt[47]= dt[46]= dt[45]= dt[44]= dt[43]= dt[42]=
-! 231 ! dt[41]= dt[40]= dt[39]= dt[38]= dt[37]= dt[36]=
-! 232 ! dt[35]= dt[34]= dt[33]= dt[32]= dt[31]= dt[30]=
-! 233 ! dt[29]= dt[28]= dt[27]= dt[26]= dt[25]= dt[24]=
-! 234 ! dt[23]= dt[22]= dt[21]= dt[20]= dt[19]= dt[18]=
-! 235 ! dt[17]= dt[16]= dt[15]= dt[14]= dt[13]= dt[12]=
-! 236 ! dt[11]= dt[10]= dt[ 9]= dt[ 8]= dt[ 7]= dt[ 6]=
-! 237 ! dt[ 5]= dt[ 4]= dt[ 3]= dt[ 2]= dt[ 1]=Zero;
-! 239 ! pdn_0=pdn[0];
-! 240 ! pdm1_0=pdm1[0];
-! 242 ! digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16);
-! 243 ! pdtj=&(dt[0]);
-! 245 ! for(j=0;j<32;j++,pdtj++)
-! 246 ! {
-! 248 ! m2j=pdm2[j];
-! 249 ! a=pdtj[0]+pdn_0*digit;
-! 250 ! b=pdtj[1]+pdm1_0*pdm2[j+1]+a*TwoToMinus16;
-! 251 ! pdtj[1]=b;
-! 253 ! /**** this loop will be fully unrolled:
-! 254 ! for(i=1;i<16;i++)
-! 255 ! {
-! 256 ! pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit;
-! 257 ! }
-! 258 ! *************************************/
-! 259 ! pdtj[2]+=pdm1[1]*m2j+pdn[1]*digit;
-! 260 ! pdtj[4]+=pdm1[2]*m2j+pdn[2]*digit;
-! 261 ! pdtj[6]+=pdm1[3]*m2j+pdn[3]*digit;
-! 262 ! pdtj[8]+=pdm1[4]*m2j+pdn[4]*digit;
-! 263 ! pdtj[10]+=pdm1[5]*m2j+pdn[5]*digit;
-! 264 ! pdtj[12]+=pdm1[6]*m2j+pdn[6]*digit;
-! 265 ! pdtj[14]+=pdm1[7]*m2j+pdn[7]*digit;
-! 266 ! pdtj[16]+=pdm1[8]*m2j+pdn[8]*digit;
-! 267 ! pdtj[18]+=pdm1[9]*m2j+pdn[9]*digit;
-! 268 ! pdtj[20]+=pdm1[10]*m2j+pdn[10]*digit;
-! 269 ! pdtj[22]+=pdm1[11]*m2j+pdn[11]*digit;
-! 270 ! pdtj[24]+=pdm1[12]*m2j+pdn[12]*digit;
-! 271 ! pdtj[26]+=pdm1[13]*m2j+pdn[13]*digit;
-! 272 ! pdtj[28]+=pdm1[14]*m2j+pdn[14]*digit;
-! 273 ! pdtj[30]+=pdm1[15]*m2j+pdn[15]*digit;
-! 274 ! /* no need for cleenup, cannot overflow */
-! 275 ! digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16);
-! 276 ! }
-! 277 ! }
-! 279 ! conv_d16_to_i32(result,dt+2*nlen,(long long *)dt,nlen+1);
-! 281 ! adjust_montf_result(result,nint,nlen);
-
-/* 0x002c 281 ( 4 5) */ or %g0,1,%o4
-/* 0x0030 187 ( 6 9) */ ldd [%fp+96],%f0
-/* 0x0034 196 ( 7 10) */ ld [%fp+92],%o0
-/* 0x0038 187 ( 8 9) */ fmovd %f0,%f16
-/* 0x003c 196 ( 9 10) */ sll %o0,4,%g2
-/* 0x0040 ( 9 10) */ or %g0,%o0,%g1
-/* 0x0044 198 (10 11) */ cmp %o0,16
-/* 0x0048 (10 11) */ be,pn %icc,.L77000289 ! tprob=0.50
-/* 0x004c (10 11) */ std %f2,[%o1+%g2]
-/* 0x0050 200 (11 12) */ sll %o0,2,%g2
-/* 0x0054 (11 14) */ ldd [%g4],%f2
-/* 0x0058 (12 13) */ add %g2,2,%o1
-/* 0x005c (12 13) */ add %g2,1,%o3
-/* 0x0060 196 (13 14) */ sll %o0,1,%o7
-/* 0x0064 200 (13 14) */ cmp %o1,0
-/* 0x0068 (13 14) */ ble,a,pt %icc,.L900000755 ! tprob=0.55
-/* 0x006c (14 17) */ ldd [%i1],%f0
-/* 0x0070 (14 15) */ cmp %o1,3
-/* 0x0074 281 (14 15) */ or %g0,1,%o1
-/* 0x0078 (14 15) */ bl,pn %icc,.L77000279 ! tprob=0.40
-/* 0x007c (15 16) */ add %o2,8,%o0
-/* 0x0080 (15 16) */ std %f2,[%g5]
-/* 0x0084 0 (16 17) */ or %g0,%o0,%o2
- .L900000726: /* frequency 64.0 confidence 0.0 */
-/* 0x0088 ( 3 5) */ ldd [%g4],%f0
-/* 0x008c ( 3 4) */ add %o4,1,%o4
-/* 0x0090 ( 3 4) */ add %o2,8,%o2
-/* 0x0094 ( 4 4) */ cmp %o4,%o3
-/* 0x0098 ( 5 6) */ ble,pt %icc,.L900000726 ! tprob=0.50
-/* 0x009c ( 5 6) */ std %f0,[%o2-8]
- .L900000729: /* frequency 8.0 confidence 0.0 */
-/* 0x00a0 ( 0 1) */ ba .L900000755 ! tprob=1.00
-/* 0x00a4 ( 0 3) */ ldd [%i1],%f0
- .L77000279: /* frequency 0.6 confidence 0.0 */
-/* 0x00a8 ( 0 1) */ std %f2,[%o2]
- .L900000754: /* frequency 5.3 confidence 0.0 */
-/* 0x00ac ( 0 3) */ ldd [%g4],%f2
-/* 0x00b0 ( 0 1) */ cmp %o1,%o3
-/* 0x00b4 ( 0 1) */ add %o2,8,%o2
-/* 0x00b8 ( 1 2) */ add %o1,1,%o1
-/* 0x00bc ( 1 2) */ ble,a,pt %icc,.L900000754 ! tprob=0.87
-/* 0x00c0 ( 3 4) */ std %f2,[%o2]
- .L77000284: /* frequency 0.8 confidence 0.0 */
-/* 0x00c4 202 ( 0 3) */ ldd [%i1],%f0
- .L900000755: /* frequency 0.8 confidence 0.0 */
-/* 0x00c8 202 ( 0 3) */ ldd [%i0],%f2
-/* 0x00cc ( 0 1) */ add %o7,1,%o2
-/* 0x00d0 206 ( 0 1) */ cmp %o7,0
-/* 0x00d4 ( 1 2) */ sll %o2,1,%o0
-/* 0x00d8 ( 1 2) */ sub %o7,1,%o1
-/* 0x00dc 202 ( 2 5) */ fmuld %f0,%f2,%f0
-/* 0x00e0 ( 2 3) */ std %f0,[%g5]
-/* 0x00e4 ( 2 3) */ sub %g1,1,%o7
-/* 0x00e8 ( 3 6) */ ldd [%g4],%f6
-/* 0x00ec 0 ( 3 4) */ or %g0,%o7,%g3
-/* 0x00f0 ( 3 4) */ or %g0,0,%l0
-/* 0x00f4 ( 4 7) */ ldd [%g4-8],%f2
-/* 0x00f8 ( 4 5) */ or %g0,0,%i5
-/* 0x00fc ( 4 5) */ or %g0,%o1,%o5
-/* 0x0100 ( 5 8) */ fdtox %f0,%f0
-/* 0x0104 ( 5 8) */ ldd [%g4-16],%f4
-/* 0x0108 ( 5 6) */ or %g0,%o0,%o3
-/* 0x010c 210 ( 6 7) */ add %i0,8,%o4
-/* 0x0110 ( 6 7) */ or %g0,0,%i4
-/* 0x0114 ( 9 10) */ fmovs %f6,%f0
-/* 0x0118 (11 14) */ fxtod %f0,%f0
-/* 0x011c 203 (14 17) */ fmuld %f0,%f16,%f0
-/* 0x0120 (17 20) */ fmuld %f0,%f2,%f2
-/* 0x0124 (20 23) */ fdtox %f2,%f2
-/* 0x0128 (23 26) */ fxtod %f2,%f2
-/* 0x012c (26 29) */ fmuld %f2,%f4,%f2
-/* 0x0130 (29 32) */ fsubd %f0,%f2,%f22
-/* 0x0134 206 (29 30) */ ble,pt %icc,.L900000748 ! tprob=0.60
-/* 0x0138 (29 30) */ sll %g1,4,%g2
-/* 0x013c 210 (30 33) */ ldd [%i2],%f0
- .L900000749: /* frequency 5.3 confidence 0.0 */
-/* 0x0140 210 ( 0 3) */ fmuld %f0,%f22,%f8
-/* 0x0144 ( 0 3) */ ldd [%i1],%f0
-/* 0x0148 214 ( 0 1) */ cmp %g1,1
-/* 0x014c 210 ( 1 4) */ ldd [%o4+%i4],%f6
-/* 0x0150 ( 1 2) */ add %i1,8,%o0
-/* 0x0154 214 ( 1 2) */ or %g0,1,%o1
-/* 0x0158 210 ( 2 5) */ ldd [%i3],%f2
-/* 0x015c ( 2 3) */ add %i3,16,%l1
-/* 0x0160 ( 3 6) */ fmuld %f0,%f6,%f6
-/* 0x0164 ( 3 6) */ ldd [%g4-8],%f4
-/* 0x0168 ( 4 7) */ faddd %f2,%f8,%f2
-/* 0x016c ( 4 7) */ ldd [%i3+8],%f0
-/* 0x0170 208 ( 5 8) */ ldd [%i0+%i4],%f20
-/* 0x0174 210 ( 6 9) */ faddd %f0,%f6,%f0
-/* 0x0178 ( 7 10) */ fmuld %f2,%f4,%f2
-/* 0x017c (10 13) */ faddd %f0,%f2,%f18
-/* 0x0180 211 (10 11) */ std %f18,[%i3+8]
-/* 0x0184 214 (10 11) */ ble,pt %icc,.L900000753 ! tprob=0.54
-/* 0x0188 (11 12) */ srl %i5,31,%g2
-/* 0x018c (11 12) */ cmp %g3,7
-/* 0x0190 210 (12 13) */ add %i2,8,%g2
-/* 0x0194 214 (12 13) */ bl,pn %icc,.L77000281 ! tprob=0.36
-/* 0x0198 (13 14) */ add %g2,24,%o2
-/* 0x019c 216 (13 16) */ ldd [%o0+16],%f14
-/* 0x01a0 (13 14) */ add %i3,48,%l1
-/* 0x01a4 (14 17) */ ldd [%o0+24],%f12
-/* 0x01a8 0 (14 15) */ or %g0,%o2,%g2
-/* 0x01ac 214 (14 15) */ sub %g1,3,%o2
-/* 0x01b0 216 (15 18) */ ldd [%o0],%f2
-/* 0x01b4 (15 16) */ or %g0,5,%o1
-/* 0x01b8 (16 19) */ ldd [%g2-24],%f0
-/* 0x01bc (17 20) */ ldd [%o0+8],%f6
-/* 0x01c0 (17 20) */ fmuld %f2,%f20,%f2
-/* 0x01c4 (17 18) */ add %o0,32,%o0
-/* 0x01c8 (18 21) */ ldd [%g2-16],%f8
-/* 0x01cc (18 21) */ fmuld %f0,%f22,%f4
-/* 0x01d0 (19 22) */ ldd [%i3+16],%f0
-/* 0x01d4 (19 22) */ fmuld %f6,%f20,%f10
-/* 0x01d8 (20 23) */ ldd [%g2-8],%f6
-/* 0x01dc (21 24) */ faddd %f2,%f4,%f4
-/* 0x01e0 (21 24) */ ldd [%i3+32],%f2
- .L900000738: /* frequency 512.0 confidence 0.0 */
-/* 0x01e4 216 (16 24) */ ldd [%g2],%f24
-/* 0x01e8 (16 17) */ add %o1,3,%o1
-/* 0x01ec (16 17) */ add %g2,24,%g2
-/* 0x01f0 (16 19) */ fmuld %f8,%f22,%f8
-/* 0x01f4 (17 25) */ ldd [%l1],%f28
-/* 0x01f8 (17 17) */ cmp %o1,%o2
-/* 0x01fc (17 18) */ add %o0,24,%o0
-/* 0x0200 (18 26) */ ldd [%o0-24],%f26
-/* 0x0204 (18 21) */ faddd %f0,%f4,%f0
-/* 0x0208 (18 19) */ add %l1,48,%l1
-/* 0x020c (19 22) */ faddd %f10,%f8,%f10
-/* 0x0210 (19 22) */ fmuld %f14,%f20,%f4
-/* 0x0214 (19 20) */ std %f0,[%l1-80]
-/* 0x0218 (20 28) */ ldd [%g2-16],%f8
-/* 0x021c (20 23) */ fmuld %f6,%f22,%f6
-/* 0x0220 (21 29) */ ldd [%l1-32],%f0
-/* 0x0224 (22 30) */ ldd [%o0-16],%f14
-/* 0x0228 (22 25) */ faddd %f2,%f10,%f2
-/* 0x022c (23 26) */ faddd %f4,%f6,%f10
-/* 0x0230 (23 26) */ fmuld %f12,%f20,%f4
-/* 0x0234 (23 24) */ std %f2,[%l1-64]
-/* 0x0238 (24 32) */ ldd [%g2-8],%f6
-/* 0x023c (24 27) */ fmuld %f24,%f22,%f24
-/* 0x0240 (25 33) */ ldd [%l1-16],%f2
-/* 0x0244 (26 34) */ ldd [%o0-8],%f12
-/* 0x0248 (26 29) */ faddd %f28,%f10,%f10
-/* 0x024c (27 28) */ std %f10,[%l1-48]
-/* 0x0250 (27 30) */ fmuld %f26,%f20,%f10
-/* 0x0254 (27 28) */ ble,pt %icc,.L900000738 ! tprob=0.50
-/* 0x0258 (27 30) */ faddd %f4,%f24,%f4
- .L900000741: /* frequency 64.0 confidence 0.0 */
-/* 0x025c 216 ( 0 3) */ fmuld %f8,%f22,%f28
-/* 0x0260 ( 0 3) */ ldd [%g2],%f24
-/* 0x0264 ( 0 3) */ faddd %f0,%f4,%f26
-/* 0x0268 ( 1 4) */ fmuld %f12,%f20,%f8
-/* 0x026c ( 1 2) */ add %l1,32,%l1
-/* 0x0270 ( 1 2) */ cmp %o1,%g3
-/* 0x0274 ( 2 5) */ fmuld %f14,%f20,%f14
-/* 0x0278 ( 2 5) */ ldd [%l1-32],%f4
-/* 0x027c ( 2 3) */ add %g2,8,%g2
-/* 0x0280 ( 3 6) */ faddd %f10,%f28,%f12
-/* 0x0284 ( 3 6) */ fmuld %f6,%f22,%f6
-/* 0x0288 ( 3 6) */ ldd [%l1-16],%f0
-/* 0x028c ( 4 7) */ fmuld %f24,%f22,%f10
-/* 0x0290 ( 4 5) */ std %f26,[%l1-64]
-/* 0x0294 ( 6 9) */ faddd %f2,%f12,%f2
-/* 0x0298 ( 6 7) */ std %f2,[%l1-48]
-/* 0x029c ( 7 10) */ faddd %f14,%f6,%f6
-/* 0x02a0 ( 8 11) */ faddd %f8,%f10,%f2
-/* 0x02a4 (10 13) */ faddd %f4,%f6,%f4
-/* 0x02a8 (10 11) */ std %f4,[%l1-32]
-/* 0x02ac (11 14) */ faddd %f0,%f2,%f0
-/* 0x02b0 (11 12) */ bg,pn %icc,.L77000213 ! tprob=0.13
-/* 0x02b4 (11 12) */ std %f0,[%l1-16]
- .L77000281: /* frequency 4.0 confidence 0.0 */
-/* 0x02b8 216 ( 0 3) */ ldd [%o0],%f0
- .L900000752: /* frequency 36.6 confidence 0.0 */
-/* 0x02bc 216 ( 0 3) */ ldd [%g2],%f4
-/* 0x02c0 ( 0 3) */ fmuld %f0,%f20,%f2
-/* 0x02c4 ( 0 1) */ add %o1,1,%o1
-/* 0x02c8 ( 1 4) */ ldd [%l1],%f0
-/* 0x02cc ( 1 2) */ add %o0,8,%o0
-/* 0x02d0 ( 1 2) */ add %g2,8,%g2
-/* 0x02d4 ( 2 5) */ fmuld %f4,%f22,%f4
-/* 0x02d8 ( 2 3) */ cmp %o1,%g3
-/* 0x02dc ( 5 8) */ faddd %f2,%f4,%f2
-/* 0x02e0 ( 8 11) */ faddd %f0,%f2,%f0
-/* 0x02e4 ( 8 9) */ std %f0,[%l1]
-/* 0x02e8 ( 8 9) */ add %l1,16,%l1
-/* 0x02ec ( 8 9) */ ble,a,pt %icc,.L900000752 ! tprob=0.87
-/* 0x02f0 (10 13) */ ldd [%o0],%f0
- .L77000213: /* frequency 5.3 confidence 0.0 */
-/* 0x02f4 ( 0 1) */ srl %i5,31,%g2
- .L900000753: /* frequency 5.3 confidence 0.0 */
-/* 0x02f8 218 ( 0 1) */ cmp %l0,30
-/* 0x02fc ( 0 1) */ bne,a,pt %icc,.L900000751 ! tprob=0.54
-/* 0x0300 ( 0 3) */ fdtox %f18,%f0
-/* 0x0304 ( 1 2) */ add %i5,%g2,%g2
-/* 0x0308 ( 1 2) */ sub %o3,1,%o2
-/* 0x030c ( 2 3) */ sra %g2,1,%o0
-/* 0x0310 216 ( 2 5) */ ldd [%g4],%f0
-/* 0x0314 ( 3 4) */ add %o0,1,%g2
-/* 0x0318 ( 4 5) */ sll %g2,1,%o0
-/* 0x031c ( 4 5) */ fmovd %f0,%f2
-/* 0x0320 ( 5 6) */ sll %g2,4,%o1
-/* 0x0324 ( 5 6) */ cmp %o0,%o3
-/* 0x0328 ( 5 6) */ bge,pt %icc,.L77000215 ! tprob=0.53
-/* 0x032c ( 6 7) */ or %g0,0,%l0
-/* 0x0330 218 ( 6 7) */ add %g5,%o1,%o1
-/* 0x0334 216 ( 7 10) */ ldd [%o1],%f8
- .L900000750: /* frequency 32.0 confidence 0.0 */
-/* 0x0338 ( 0 3) */ fdtox %f8,%f6
-/* 0x033c ( 0 3) */ ldd [%g4],%f10
-/* 0x0340 ( 0 1) */ add %o0,2,%o0
-/* 0x0344 ( 1 4) */ ldd [%o1+8],%f4
-/* 0x0348 ( 1 4) */ fdtox %f8,%f8
-/* 0x034c ( 1 2) */ cmp %o0,%o2
-/* 0x0350 ( 5 6) */ fmovs %f10,%f6
-/* 0x0354 ( 7 10) */ fxtod %f6,%f10
-/* 0x0358 ( 8 11) */ fdtox %f4,%f6
-/* 0x035c ( 9 12) */ fdtox %f4,%f4
-/* 0x0360 (10 13) */ faddd %f10,%f2,%f2
-/* 0x0364 (10 11) */ std %f2,[%o1]
-/* 0x0368 (12 15) */ ldd [%g4],%f2
-/* 0x036c (14 15) */ fmovs %f2,%f6
-/* 0x0370 (16 19) */ fxtod %f6,%f6
-/* 0x0374 (17 20) */ fitod %f8,%f2
-/* 0x0378 (19 22) */ faddd %f6,%f0,%f0
-/* 0x037c (19 20) */ std %f0,[%o1+8]
-/* 0x0380 (19 20) */ add %o1,16,%o1
-/* 0x0384 (20 23) */ fitod %f4,%f0
-/* 0x0388 (20 21) */ ble,a,pt %icc,.L900000750 ! tprob=0.87
-/* 0x038c (20 23) */ ldd [%o1],%f8
- .L77000233: /* frequency 4.6 confidence 0.0 */
-/* 0x0390 ( 0 0) */ or %g0,0,%l0
- .L77000215: /* frequency 5.3 confidence 0.0 */
-/* 0x0394 ( 0 3) */ fdtox %f18,%f0
- .L900000751: /* frequency 5.3 confidence 0.0 */
-/* 0x0398 ( 0 3) */ ldd [%g4],%f6
-/* 0x039c 220 ( 0 1) */ add %i5,1,%i5
-/* 0x03a0 ( 0 1) */ add %i4,8,%i4
-/* 0x03a4 ( 1 4) */ ldd [%g4-8],%f2
-/* 0x03a8 ( 1 2) */ add %l0,1,%l0
-/* 0x03ac ( 1 2) */ add %i3,8,%i3
-/* 0x03b0 ( 2 3) */ fmovs %f6,%f0
-/* 0x03b4 ( 2 5) */ ldd [%g4-16],%f4
-/* 0x03b8 ( 2 3) */ cmp %i5,%o5
-/* 0x03bc ( 4 7) */ fxtod %f0,%f0
-/* 0x03c0 ( 7 10) */ fmuld %f0,%f16,%f0
-/* 0x03c4 (10 13) */ fmuld %f0,%f2,%f2
-/* 0x03c8 (13 16) */ fdtox %f2,%f2
-/* 0x03cc (16 19) */ fxtod %f2,%f2
-/* 0x03d0 (19 22) */ fmuld %f2,%f4,%f2
-/* 0x03d4 (22 25) */ fsubd %f0,%f2,%f22
-/* 0x03d8 (22 23) */ ble,a,pt %icc,.L900000749 ! tprob=0.89
-/* 0x03dc (22 25) */ ldd [%i2],%f0
- .L900000725: /* frequency 0.7 confidence 0.0 */
-/* 0x03e0 220 ( 0 1) */ ba .L900000748 ! tprob=1.00
-/* 0x03e4 ( 0 1) */ sll %g1,4,%g2
-
-
- .L77000289: /* frequency 0.8 confidence 0.0 */
-/* 0x03e8 225 ( 0 3) */ ldd [%o1],%f6
-/* 0x03ec 242 ( 0 1) */ add %g4,-8,%g2
-/* 0x03f0 ( 0 1) */ add %g4,-16,%g3
-/* 0x03f4 225 ( 1 4) */ ldd [%i1],%f2
-/* 0x03f8 245 ( 1 2) */ or %g0,0,%o3
-/* 0x03fc ( 1 2) */ or %g0,0,%o0
-/* 0x0400 225 ( 3 6) */ fmuld %f2,%f6,%f2
-/* 0x0404 ( 3 4) */ std %f2,[%o2]
-/* 0x0408 ( 4 7) */ ldd [%g4],%f6
-/* 0x040c 237 ( 7 8) */ std %f6,[%o2+8]
-/* 0x0410 ( 8 9) */ std %f6,[%o2+16]
-/* 0x0414 ( 9 10) */ std %f6,[%o2+24]
-/* 0x0418 (10 11) */ std %f6,[%o2+32]
-/* 0x041c (11 12) */ std %f6,[%o2+40]
-/* 0x0420 (12 13) */ std %f6,[%o2+48]
-/* 0x0424 (13 14) */ std %f6,[%o2+56]
-/* 0x0428 (14 15) */ std %f6,[%o2+64]
-/* 0x042c (15 16) */ std %f6,[%o2+72]
-! prefetch [%i4],0
-! prefetch [%i4+32],0
-! prefetch [%i4+64],0
-! prefetch [%i4+96],0
-! prefetch [%i4+120],0
-! prefetch [%i1],0
-! prefetch [%i1+32],0
-! prefetch [%i1+64],0
-! prefetch [%i1+96],0
-! prefetch [%i1+120],0
-/* 0x0430 (16 17) */ std %f6,[%o2+80]
-/* 0x0434 (17 18) */ std %f6,[%o2+88]
-/* 0x0438 (18 19) */ std %f6,[%o2+96]
-/* 0x043c (19 20) */ std %f6,[%o2+104]
-/* 0x0440 (20 21) */ std %f6,[%o2+112]
-/* 0x0444 (21 22) */ std %f6,[%o2+120]
-/* 0x0448 (22 23) */ std %f6,[%o2+128]
-/* 0x044c (23 24) */ std %f6,[%o2+136]
-/* 0x0450 (24 25) */ std %f6,[%o2+144]
-/* 0x0454 (25 26) */ std %f6,[%o2+152]
-/* 0x0458 (26 27) */ std %f6,[%o2+160]
-/* 0x045c (27 28) */ std %f6,[%o2+168]
-/* 0x0460 (27 30) */ fdtox %f2,%f2
-/* 0x0464 (28 29) */ std %f6,[%o2+176]
-/* 0x0468 (29 30) */ std %f6,[%o2+184]
-/* 0x046c (30 31) */ std %f6,[%o2+192]
-/* 0x0470 (31 32) */ std %f6,[%o2+200]
-/* 0x0474 (32 33) */ std %f6,[%o2+208]
-/* 0x0478 (33 34) */ std %f6,[%o2+216]
-/* 0x047c (34 35) */ std %f6,[%o2+224]
-/* 0x0480 (35 36) */ std %f6,[%o2+232]
-/* 0x0484 (36 37) */ std %f6,[%o2+240]
-/* 0x0488 (37 38) */ std %f6,[%o2+248]
-/* 0x048c (38 39) */ std %f6,[%o2+256]
-/* 0x0490 (39 40) */ std %f6,[%o2+264]
-/* 0x0494 (40 41) */ std %f6,[%o2+272]
-/* 0x0498 (41 42) */ std %f6,[%o2+280]
-/* 0x049c (42 43) */ std %f6,[%o2+288]
-/* 0x04a0 (43 44) */ std %f6,[%o2+296]
-/* 0x04a4 (44 45) */ std %f6,[%o2+304]
-/* 0x04a8 (45 46) */ std %f6,[%o2+312]
-/* 0x04ac (46 47) */ std %f6,[%o2+320]
-/* 0x04b0 (47 48) */ std %f6,[%o2+328]
-/* 0x04b4 (48 49) */ std %f6,[%o2+336]
-/* 0x04b8 (49 50) */ std %f6,[%o2+344]
-/* 0x04bc (50 51) */ std %f6,[%o2+352]
-/* 0x04c0 (51 52) */ std %f6,[%o2+360]
-/* 0x04c4 (52 53) */ std %f6,[%o2+368]
-/* 0x04c8 (53 54) */ std %f6,[%o2+376]
-/* 0x04cc (54 55) */ std %f6,[%o2+384]
-/* 0x04d0 (55 56) */ std %f6,[%o2+392]
-/* 0x04d4 (56 57) */ std %f6,[%o2+400]
-/* 0x04d8 (57 58) */ std %f6,[%o2+408]
-/* 0x04dc (58 59) */ std %f6,[%o2+416]
-/* 0x04e0 (59 60) */ std %f6,[%o2+424]
-/* 0x04e4 (60 61) */ std %f6,[%o2+432]
-/* 0x04e8 (61 62) */ std %f6,[%o2+440]
-/* 0x04ec (62 63) */ std %f6,[%o2+448]
-/* 0x04f0 (63 64) */ std %f6,[%o2+456]
-/* 0x04f4 (64 65) */ std %f6,[%o2+464]
-/* 0x04f8 (65 66) */ std %f6,[%o2+472]
-/* 0x04fc (66 67) */ std %f6,[%o2+480]
-/* 0x0500 (67 68) */ std %f6,[%o2+488]
-/* 0x0504 (68 69) */ std %f6,[%o2+496]
-/* 0x0508 (69 70) */ std %f6,[%o2+504]
-/* 0x050c (70 71) */ std %f6,[%o2+512]
-/* 0x0510 (71 72) */ std %f6,[%o2+520]
-/* 0x0514 242 (72 75) */ ld [%g4],%f2 ! dalign
-/* 0x0518 (73 76) */ ld [%g2],%f6 ! dalign
-/* 0x051c (74 77) */ fxtod %f2,%f10
-/* 0x0520 (74 77) */ ld [%g2+4],%f7
-/* 0x0524 (75 78) */ ld [%g3],%f8 ! dalign
-/* 0x0528 (76 79) */ ld [%g3+4],%f9
-/* 0x052c (77 80) */ fmuld %f10,%f0,%f0
-/* 0x0530 239 (77 80) */ ldd [%i4],%f4
-/* 0x0534 240 (78 81) */ ldd [%i1],%f2
-/* 0x0538 (80 83) */ fmuld %f0,%f6,%f6
-/* 0x053c (83 86) */ fdtox %f6,%f6
-/* 0x0540 (86 89) */ fxtod %f6,%f6
-/* 0x0544 (89 92) */ fmuld %f6,%f8,%f6
-/* 0x0548 (92 95) */ fsubd %f0,%f6,%f0
-/* 0x054c 250 (95 98) */ fmuld %f4,%f0,%f10
- .L900000747: /* frequency 6.4 confidence 0.0 */
-
-
- fmovd %f0,%f0
- fmovd %f16,%f18
- ldd [%i4],%f2
- ldd [%o2],%f8
- ldd [%i1],%f10
- ldd [%g4-8],%f14
- ldd [%g4-16],%f16
- ldd [%o1],%f24
-
- ldd [%i1+8],%f26
- ldd [%i1+16],%f40
- ldd [%i1+48],%f46
- ldd [%i1+56],%f30
- ldd [%i1+64],%f54
- ldd [%i1+104],%f34
- ldd [%i1+112],%f58
-
- ldd [%i4+112],%f60
- ldd [%i4+8],%f28
- ldd [%i4+104],%f38
-
- nop
- nop
-!
- .L99999999:
-!1
-!!!
- ldd [%i1+24],%f32
- fmuld %f0,%f2,%f4
-!2
-!!!
- ldd [%i4+24],%f36
- fmuld %f26,%f24,%f20
-!3
-!!!
- ldd [%i1+40],%f42
- fmuld %f28,%f0,%f22
-!4
-!!!
- ldd [%i4+40],%f44
- fmuld %f32,%f24,%f32
-!5
-!!!
- ldd [%o1+8],%f6
- faddd %f4,%f8,%f4
- fmuld %f36,%f0,%f36
-!6
-!!!
- add %o1,8,%o1
- ldd [%i4+56],%f50
- fmuld %f42,%f24,%f42
-!7
-!!!
- ldd [%i1+72],%f52
- faddd %f20,%f22,%f20
- fmuld %f44,%f0,%f44
-!8
-!!!
- ldd [%o2+16],%f22
- fmuld %f10,%f6,%f12
-!9
-!!!
- ldd [%i4+72],%f56
- faddd %f32,%f36,%f32
- fmuld %f14,%f4,%f4
-!10
-!!!
- ldd [%o2+48],%f36
- fmuld %f30,%f24,%f48
-!11
-!!!
- ldd [%o2+8],%f8
- faddd %f20,%f22,%f20
- fmuld %f50,%f0,%f50
-!12
-!!!
- std %f20,[%o2+16]
- faddd %f42,%f44,%f42
- fmuld %f52,%f24,%f52
-!13
-!!!
- ldd [%o2+80],%f44
- faddd %f4,%f12,%f4
- fmuld %f56,%f0,%f56
-!14
-!!!
- ldd [%i1+88],%f20
- faddd %f32,%f36,%f32
-!15
-!!!
- ldd [%i4+88],%f22
- faddd %f48,%f50,%f48
-!16
-!!!
- ldd [%o2+112],%f50
- faddd %f52,%f56,%f52
-!17
-!!!
- ldd [%o2+144],%f56
- faddd %f4,%f8,%f8
- fmuld %f20,%f24,%f20
-!18
-!!!
- std %f32,[%o2+48]
- faddd %f42,%f44,%f42
- fmuld %f22,%f0,%f22
-!19
-!!!
- std %f42,[%o2+80]
- faddd %f48,%f50,%f48
- fmuld %f34,%f24,%f32
-!20
-!!!
- std %f48,[%o2+112]
- faddd %f52,%f56,%f52
- fmuld %f38,%f0,%f36
-!21
-!!!
- ldd [%i1+120],%f42
- fdtox %f8,%f4
-!22
-!!!
- std %f52,[%o2+144]
- faddd %f20,%f22,%f20
-!23
-!!!
- ldd [%i4+120],%f44
-!24
-!!!
- ldd [%o2+176],%f22
- faddd %f32,%f36,%f32
- fmuld %f42,%f24,%f42
-!25
-!!!
- ldd [%i4+16],%f50
- fmovs %f17,%f4
-!26
-!!!
- ldd [%i1+32],%f52
- fmuld %f44,%f0,%f44
-!27
-!!!
- ldd [%i4+32],%f56
- fmuld %f40,%f24,%f48
-!28
-!!!
- ldd [%o2+208],%f36
- faddd %f20,%f22,%f20
- fmuld %f50,%f0,%f50
-!29
-!!!
- std %f20,[%o2+176]
- fxtod %f4,%f4
- fmuld %f52,%f24,%f52
-!30
-!!!
- ldd [%i4+48],%f22
- faddd %f42,%f44,%f42
- fmuld %f56,%f0,%f56
-!31
-!!!
- ldd [%o2+240],%f44
- faddd %f32,%f36,%f32
-!32
-!!!
- std %f32,[%o2+208]
- faddd %f48,%f50,%f48
- fmuld %f46,%f24,%f20
-!33
-!!!
- ldd [%o2+32],%f50
- fmuld %f4,%f18,%f12
-!34
-!!!
- ldd [%i4+64],%f36
- faddd %f52,%f56,%f52
- fmuld %f22,%f0,%f22
-!35
-!!!
- ldd [%o2+64],%f56
- faddd %f42,%f44,%f42
-!36
-!!!
- std %f42,[%o2+240]
- faddd %f48,%f50,%f48
- fmuld %f54,%f24,%f32
-!37
-!!!
- std %f48,[%o2+32]
- fmuld %f12,%f14,%f4
-!38
-!!!
- ldd [%i1+80],%f42
- faddd %f52,%f56,%f56 ! yes, tmp52!
- fmuld %f36,%f0,%f36
-!39
-!!!
- ldd [%i4+80],%f44
- faddd %f20,%f22,%f20
-!40
-!!!
- ldd [%i1+96],%f48
- fmuld %f58,%f24,%f52
-!41
-!!!
- ldd [%i4+96],%f50
- fdtox %f4,%f4
- fmuld %f42,%f24,%f42
-!42
-!!!
- std %f56,[%o2+64] ! yes, tmp52!
- faddd %f32,%f36,%f32
- fmuld %f44,%f0,%f44
-!43
-!!!
- ldd [%o2+96],%f22
- fmuld %f48,%f24,%f48
-!44
-!!!
- ldd [%o2+128],%f36
- fmovd %f6,%f24
- fmuld %f50,%f0,%f50
-!45
-!!!
- fxtod %f4,%f4
- fmuld %f60,%f0,%f56
-!46
-!!!
- add %o2,8,%o2
- faddd %f42,%f44,%f42
-!47
-!!!
- ldd [%o2+160-8],%f44
- faddd %f20,%f22,%f20
-!48
-!!!
- std %f20,[%o2+96-8]
- faddd %f48,%f50,%f48
-!49
-!!!
- ldd [%o2+192-8],%f50
- faddd %f52,%f56,%f52
- fmuld %f4,%f16,%f4
-!50
-!!!
- ldd [%o2+224-8],%f56
- faddd %f32,%f36,%f32
-!51
-!!!
- std %f32,[%o2+128-8]
- faddd %f42,%f44,%f42
-!52
- add %o3,1,%o3
- std %f42,[%o2+160-8]
- faddd %f48,%f50,%f48
-!53
-!!!
- cmp %o3,31
- std %f48,[%o2+192-8]
- faddd %f52,%f56,%f52
-!54
- std %f52,[%o2+224-8]
- ble,pt %icc,.L99999999
- fsubd %f12,%f4,%f0
-
-
-
-!55
- std %f8,[%o2]
-
-
-
-
-
-
- .L77000285: /* frequency 1.0 confidence 0.0 */
-/* 0x07a8 279 ( 0 1) */ sll %g1,4,%g2
- .L900000748: /* frequency 1.0 confidence 0.0 */
-/* 0x07ac 279 ( 0 3) */ ldd [%g5+%g2],%f0
-/* 0x07b0 ( 0 1) */ add %g5,%g2,%i1
-/* 0x07b4 ( 0 1) */ or %g0,0,%o4
-/* 0x07b8 206 ( 1 4) */ ld [%fp+68],%o0
-/* 0x07bc 279 ( 1 2) */ or %g0,0,%i0
-/* 0x07c0 ( 1 2) */ cmp %g1,0
-/* 0x07c4 ( 2 5) */ fdtox %f0,%f0
-/* 0x07c8 ( 2 3) */ std %f0,[%sp+120]
-/* 0x07cc 275 ( 2 3) */ sethi %hi(0xfc00),%o1
-/* 0x07d0 206 ( 3 4) */ or %g0,%o0,%o3
-/* 0x07d4 275 ( 3 4) */ sub %g1,1,%g4
-/* 0x07d8 279 ( 4 7) */ ldd [%i1+8],%f0
-/* 0x07dc ( 4 5) */ or %g0,%o0,%g5
-/* 0x07e0 ( 4 5) */ add %o1,1023,%o1
-/* 0x07e4 ( 6 9) */ fdtox %f0,%f0
-/* 0x07e8 ( 6 7) */ std %f0,[%sp+112]
-/* 0x07ec (10 12) */ ldx [%sp+112],%o5
-/* 0x07f0 (11 13) */ ldx [%sp+120],%o7
-/* 0x07f4 (11 12) */ ble,pt %icc,.L900000746 ! tprob=0.56
-/* 0x07f8 (11 12) */ sethi %hi(0xfc00),%g2
-/* 0x07fc 275 (12 13) */ or %g0,-1,%g2
-/* 0x0800 279 (12 13) */ cmp %g1,3
-/* 0x0804 275 (13 14) */ srl %g2,0,%o2
-/* 0x0808 279 (13 14) */ bl,pn %icc,.L77000286 ! tprob=0.44
-/* 0x080c (13 14) */ or %g0,%i1,%g2
-/* 0x0810 (14 17) */ ldd [%i1+16],%f0
-/* 0x0814 (14 15) */ and %o5,%o1,%o0
-/* 0x0818 (14 15) */ add %i1,16,%g2
-/* 0x081c (15 16) */ sllx %o0,16,%g3
-/* 0x0820 (15 16) */ and %o7,%o2,%o0
-/* 0x0824 (16 19) */ fdtox %f0,%f0
-/* 0x0828 (16 17) */ std %f0,[%sp+104]
-/* 0x082c (16 17) */ add %o0,%g3,%o4
-/* 0x0830 (17 20) */ ldd [%i1+24],%f2
-/* 0x0834 (17 18) */ srax %o5,16,%o0
-/* 0x0838 (17 18) */ add %o3,4,%g5
-/* 0x083c (18 19) */ stx %o0,[%sp+128]
-/* 0x0840 (18 19) */ and %o4,%o2,%o0
-/* 0x0844 (18 19) */ or %g0,1,%i0
-/* 0x0848 (19 20) */ stx %o0,[%sp+112]
-/* 0x084c (19 20) */ srax %o4,32,%o0
-/* 0x0850 (19 22) */ fdtox %f2,%f0
-/* 0x0854 (20 21) */ stx %o0,[%sp+136]
-/* 0x0858 (20 21) */ srax %o7,32,%o4
-/* 0x085c (21 22) */ std %f0,[%sp+96]
-/* 0x0860 (22 24) */ ldx [%sp+136],%o7
-/* 0x0864 (23 25) */ ldx [%sp+128],%o0
-/* 0x0868 (25 27) */ ldx [%sp+104],%g3
-/* 0x086c (25 26) */ add %o0,%o7,%o0
-/* 0x0870 (26 28) */ ldx [%sp+112],%o7
-/* 0x0874 (26 27) */ add %o4,%o0,%o4
-/* 0x0878 (27 29) */ ldx [%sp+96],%o5
-/* 0x087c (28 29) */ st %o7,[%o3]
-/* 0x0880 (28 29) */ or %g0,%g3,%o7
- .L900000730: /* frequency 64.0 confidence 0.0 */
-/* 0x0884 (17 19) */ ldd [%g2+16],%f0
-/* 0x0888 (17 18) */ add %i0,1,%i0
-/* 0x088c (17 18) */ add %g5,4,%g5
-/* 0x0890 (18 18) */ cmp %i0,%g4
-/* 0x0894 (18 19) */ add %g2,16,%g2
-/* 0x0898 (19 22) */ fdtox %f0,%f0
-/* 0x089c (20 21) */ std %f0,[%sp+104]
-/* 0x08a0 (21 23) */ ldd [%g2+8],%f0
-/* 0x08a4 (23 26) */ fdtox %f0,%f0
-/* 0x08a8 (24 25) */ std %f0,[%sp+96]
-/* 0x08ac (25 26) */ and %o5,%o1,%g3
-/* 0x08b0 (26 27) */ sllx %g3,16,%g3
-/* 0x08b4 ( 0 0) */ stx %g3,[%sp+120]
-/* 0x08b8 (26 27) */ and %o7,%o2,%g3
-/* 0x08bc ( 0 0) */ stx %o7,[%sp+128]
-/* 0x08c0 ( 0 0) */ ldx [%sp+120],%o7
-/* 0x08c4 (27 27) */ add %g3,%o7,%g3
-/* 0x08c8 ( 0 0) */ ldx [%sp+128],%o7
-/* 0x08cc (28 29) */ srax %o5,16,%o5
-/* 0x08d0 (28 28) */ add %g3,%o4,%g3
-/* 0x08d4 (29 30) */ srax %g3,32,%o4
-/* 0x08d8 ( 0 0) */ stx %o4,[%sp+112]
-/* 0x08dc (30 31) */ srax %o7,32,%o4
-/* 0x08e0 ( 0 0) */ ldx [%sp+112],%o7
-/* 0x08e4 (30 31) */ add %o5,%o7,%o7
-/* 0x08e8 (31 33) */ ldx [%sp+96],%o5
-/* 0x08ec (31 32) */ add %o4,%o7,%o4
-/* 0x08f0 (32 33) */ and %g3,%o2,%g3
-/* 0x08f4 ( 0 0) */ ldx [%sp+104],%o7
-/* 0x08f8 (33 34) */ ble,pt %icc,.L900000730 ! tprob=0.50
-/* 0x08fc (33 34) */ st %g3,[%g5-4]
- .L900000733: /* frequency 8.0 confidence 0.0 */
-/* 0x0900 ( 0 1) */ ba .L900000746 ! tprob=1.00
-/* 0x0904 ( 0 1) */ sethi %hi(0xfc00),%g2
- .L77000286: /* frequency 0.7 confidence 0.0 */
-/* 0x0908 ( 0 3) */ ldd [%g2+16],%f0
- .L900000745: /* frequency 6.4 confidence 0.0 */
-/* 0x090c ( 0 1) */ and %o7,%o2,%o0
-/* 0x0910 ( 0 1) */ and %o5,%o1,%g3
-/* 0x0914 ( 0 3) */ fdtox %f0,%f0
-/* 0x0918 ( 1 2) */ add %o4,%o0,%o0
-/* 0x091c ( 1 2) */ std %f0,[%sp+104]
-/* 0x0920 ( 1 2) */ add %i0,1,%i0
-/* 0x0924 ( 2 3) */ sllx %g3,16,%o4
-/* 0x0928 ( 2 5) */ ldd [%g2+24],%f2
-/* 0x092c ( 2 3) */ add %g2,16,%g2
-/* 0x0930 ( 3 4) */ add %o0,%o4,%o4
-/* 0x0934 ( 3 4) */ cmp %i0,%g4
-/* 0x0938 ( 4 5) */ srax %o5,16,%o0
-/* 0x093c ( 4 5) */ stx %o0,[%sp+112]
-/* 0x0940 ( 4 5) */ and %o4,%o2,%g3
-/* 0x0944 ( 5 6) */ srax %o4,32,%o5
-/* 0x0948 ( 5 8) */ fdtox %f2,%f0
-/* 0x094c ( 5 6) */ std %f0,[%sp+96]
-/* 0x0950 ( 6 7) */ srax %o7,32,%o4
-/* 0x0954 ( 6 8) */ ldx [%sp+112],%o7
-/* 0x0958 ( 8 9) */ add %o7,%o5,%o7
-/* 0x095c ( 9 11) */ ldx [%sp+104],%o5
-/* 0x0960 ( 9 10) */ add %o4,%o7,%o4
-/* 0x0964 (10 12) */ ldx [%sp+96],%o0
-/* 0x0968 (11 12) */ st %g3,[%g5]
-/* 0x096c (11 12) */ or %g0,%o5,%o7
-/* 0x0970 (11 12) */ add %g5,4,%g5
-/* 0x0974 (12 13) */ or %g0,%o0,%o5
-/* 0x0978 (12 13) */ ble,a,pt %icc,.L900000745 ! tprob=0.86
-/* 0x097c (12 15) */ ldd [%g2+16],%f0
- .L77000236: /* frequency 1.0 confidence 0.0 */
-/* 0x0980 ( 0 1) */ sethi %hi(0xfc00),%g2
- .L900000746: /* frequency 1.0 confidence 0.0 */
-/* 0x0984 ( 0 1) */ or %g0,-1,%o0
-/* 0x0988 ( 0 1) */ add %g2,1023,%g2
-/* 0x098c ( 0 3) */ ld [%fp+88],%o1
-/* 0x0990 ( 1 2) */ srl %o0,0,%g3
-/* 0x0994 ( 1 2) */ and %o5,%g2,%g2
-/* 0x0998 ( 2 3) */ and %o7,%g3,%g4
-/* 0x099c 281 ( 2 3) */ or %g0,-1,%o5
-/* 0x09a0 275 ( 3 4) */ sllx %g2,16,%g2
-/* 0x09a4 ( 3 4) */ add %o4,%g4,%g4
-/* 0x09a8 ( 4 5) */ add %g4,%g2,%g2
-/* 0x09ac ( 5 6) */ sll %i0,2,%g4
-/* 0x09b0 ( 5 6) */ and %g2,%g3,%g2
-/* 0x09b4 ( 6 7) */ st %g2,[%o3+%g4]
-/* 0x09b8 281 ( 6 7) */ sll %g1,2,%g2
-/* 0x09bc ( 7 10) */ ld [%o3+%g2],%g2
-/* 0x09c0 ( 9 10) */ cmp %g2,0
-/* 0x09c4 ( 9 10) */ bleu,pn %icc,.L77000241 ! tprob=0.50
-/* 0x09c8 ( 9 10) */ or %g0,%o1,%o2
-/* 0x09cc (10 11) */ ba .L900000744 ! tprob=1.00
-/* 0x09d0 (10 11) */ cmp %o5,0
- .L77000241: /* frequency 0.8 confidence 0.0 */
-/* 0x09d4 ( 0 1) */ subcc %g1,1,%o5
-/* 0x09d8 ( 0 1) */ bneg,pt %icc,.L900000744 ! tprob=0.60
-/* 0x09dc ( 1 2) */ cmp %o5,0
-/* 0x09e0 ( 1 2) */ sll %o5,2,%g2
-/* 0x09e4 ( 2 3) */ add %o1,%g2,%o0
-/* 0x09e8 ( 2 3) */ add %o3,%g2,%o4
-/* 0x09ec ( 3 6) */ ld [%o0],%g2
- .L900000743: /* frequency 5.3 confidence 0.0 */
-/* 0x09f0 ( 0 3) */ ld [%o4],%g3
-/* 0x09f4 ( 0 1) */ add %o0,4,%o0
-/* 0x09f8 ( 0 1) */ add %o4,4,%o4
-/* 0x09fc ( 2 3) */ cmp %g3,%g2
-/* 0x0a00 ( 2 3) */ bne,pn %icc,.L77000244 ! tprob=0.16
-/* 0x0a04 ( 2 3) */ nop
-/* 0x0a08 ( 3 4) */ addcc %o5,1,%o5
-/* 0x0a0c ( 3 4) */ bpos,a,pt %icc,.L900000743 ! tprob=0.84
-/* 0x0a10 ( 3 6) */ ld [%o0],%g2
- .L77000244: /* frequency 1.0 confidence 0.0 */
-/* 0x0a14 ( 0 1) */ cmp %o5,0
- .L900000744: /* frequency 1.0 confidence 0.0 */
-/* 0x0a18 ( 0 1) */ bl,pn %icc,.L77000287 ! tprob=0.50
-/* 0x0a1c ( 0 1) */ sll %o5,2,%g2
-/* 0x0a20 ( 1 4) */ ld [%o2+%g2],%g3
-/* 0x0a24 ( 2 5) */ ld [%o3+%g2],%g2
-/* 0x0a28 ( 4 5) */ cmp %g2,%g3
-/* 0x0a2c ( 4 5) */ bleu,pt %icc,.L77000224 ! tprob=0.56
-/* 0x0a30 ( 4 5) */ nop
- .L77000287: /* frequency 0.8 confidence 0.0 */
-/* 0x0a34 ( 0 1) */ cmp %g1,0
-/* 0x0a38 ( 0 1) */ ble,pt %icc,.L77000224 ! tprob=0.60
-/* 0x0a3c ( 0 1) */ nop
-/* 0x0a40 281 ( 1 2) */ sub %g1,1,%o7
-/* 0x0a44 ( 1 2) */ or %g0,-1,%g2
-/* 0x0a48 ( 2 3) */ srl %g2,0,%o4
-/* 0x0a4c ( 2 3) */ add %o7,1,%o0
-/* 0x0a50 279 ( 3 4) */ or %g0,0,%o5
-/* 0x0a54 ( 3 4) */ or %g0,0,%g1
-/* 0x0a58 ( 4 5) */ cmp %o0,3
-/* 0x0a5c ( 4 5) */ bl,pn %icc,.L77000288 ! tprob=0.40
-/* 0x0a60 ( 4 5) */ add %o3,8,%o1
-/* 0x0a64 ( 5 6) */ add %o2,4,%o0
-/* 0x0a68 ( 5 8) */ ld [%o1-8],%g2
-/* 0x0a6c 0 ( 5 6) */ or %g0,%o1,%o3
-/* 0x0a70 279 ( 6 9) */ ld [%o0-4],%g3
-/* 0x0a74 0 ( 6 7) */ or %g0,%o0,%o2
-/* 0x0a78 279 ( 6 7) */ or %g0,2,%g1
-/* 0x0a7c ( 7 10) */ ld [%o3-4],%o0
-/* 0x0a80 ( 8 9) */ sub %g2,%g3,%g2
-/* 0x0a84 ( 9 10) */ or %g0,%g2,%o5
-/* 0x0a88 ( 9 10) */ and %g2,%o4,%g2
-/* 0x0a8c ( 9 10) */ st %g2,[%o3-8]
-/* 0x0a90 (10 11) */ srax %o5,32,%o5
- .L900000734: /* frequency 64.0 confidence 0.0 */
-/* 0x0a94 (12 20) */ ld [%o2],%g2
-/* 0x0a98 (12 13) */ add %g1,1,%g1
-/* 0x0a9c (12 13) */ add %o2,4,%o2
-/* 0x0aa0 (13 13) */ cmp %g1,%o7
-/* 0x0aa4 (13 14) */ add %o3,4,%o3
-/* 0x0aa8 (14 14) */ sub %o0,%g2,%o0
-/* 0x0aac (15 15) */ add %o0,%o5,%o5
-/* 0x0ab0 (16 17) */ and %o5,%o4,%g2
-/* 0x0ab4 (16 24) */ ld [%o3-4],%o0
-/* 0x0ab8 (17 18) */ st %g2,[%o3-8]
-/* 0x0abc (17 18) */ ble,pt %icc,.L900000734 ! tprob=0.50
-/* 0x0ac0 (17 18) */ srax %o5,32,%o5
- .L900000737: /* frequency 8.0 confidence 0.0 */
-/* 0x0ac4 ( 0 3) */ ld [%o2],%o1
-/* 0x0ac8 ( 2 3) */ sub %o0,%o1,%o0
-/* 0x0acc ( 3 4) */ add %o0,%o5,%o0
-/* 0x0ad0 ( 4 5) */ and %o0,%o4,%o1
-/* 0x0ad4 ( 4 5) */ st %o1,[%o3-4]
-/* 0x0ad8 ( 5 7) */ ret ! Result =
-/* 0x0adc ( 7 8) */ restore %g0,%g0,%g0
- .L77000288: /* frequency 0.6 confidence 0.0 */
-/* 0x0ae0 ( 0 3) */ ld [%o3],%o0
- .L900000742: /* frequency 5.3 confidence 0.0 */
-/* 0x0ae4 ( 0 3) */ ld [%o2],%o1
-/* 0x0ae8 ( 0 1) */ add %o5,%o0,%o0
-/* 0x0aec ( 0 1) */ add %g1,1,%g1
-/* 0x0af0 ( 1 2) */ add %o2,4,%o2
-/* 0x0af4 ( 1 2) */ cmp %g1,%o7
-/* 0x0af8 ( 2 3) */ sub %o0,%o1,%o0
-/* 0x0afc ( 3 4) */ and %o0,%o4,%o1
-/* 0x0b00 ( 3 4) */ st %o1,[%o3]
-/* 0x0b04 ( 3 4) */ add %o3,4,%o3
-/* 0x0b08 ( 4 5) */ srax %o0,32,%o5
-/* 0x0b0c ( 4 5) */ ble,a,pt %icc,.L900000742 ! tprob=0.84
-/* 0x0b10 ( 4 7) */ ld [%o3],%o0
- .L77000224: /* frequency 1.0 confidence 0.0 */
-/* 0x0b14 ( 0 2) */ ret ! Result =
-/* 0x0b18 ( 2 3) */ restore %g0,%g0,%g0
-/* 0x0b1c 0 ( 0 0) */ .type mont_mulf_noconv,2
-/* 0x0b1c ( 0 0) */ .size mont_mulf_noconv,(.-mont_mulf_noconv)
-
diff --git a/security/nss/lib/freebl/mpi/montmulfv8.il b/security/nss/lib/freebl/mpi/montmulfv8.il
deleted file mode 100644
index 2d051f426..000000000
--- a/security/nss/lib/freebl/mpi/montmulfv8.il
+++ /dev/null
@@ -1,109 +0,0 @@
-!
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-! $Id$
-
-!
-! double upper32(double /*frs1*/);
-!
- .inline upper32,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f10
-
- fdtox %f10,%f10
- fitod %f10,%f0
- .end
-
-!
-! double lower32(double /*frs1*/, double /* Zero */);
-!
- .inline lower32,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f10
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f12
-
- fdtox %f10,%f10
- fmovs %f12,%f10
- fxtod %f10,%f0
- .end
-
-!
-! double mod(double /*x*/, double /*1/m*/, double /*m*/);
-!
- .inline mod,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f2
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o4,[%sp+0x48]
- ldd [%sp+0x48],%f6
-
- fmuld %f2,%f4,%f4
- fdtox %f4,%f4
- fxtod %f4,%f4
- fmuld %f4,%f6,%f4
- fsubd %f2,%f4,%f0
- .end
-
-
-!
-! void i16_to_d16_and_d32x4(double * /*1/(2^16)*/, double * /* 2^16*/,
-! double * /* 0 */,
-! double * /*result16*/, double * /* result32 */
-! float * /*source - should be unsigned int*
-! converted to float* */);
-!
- .inline i16_to_d16_and_d32x4,24
- ldd [%o0],%f2 ! 1/(2^16)
- ldd [%o1],%f4 ! 2^16
- ldd [%o2],%f22
-
- fmovd %f22,%f6
- ld [%o5],%f7
- fmovd %f22,%f10
- ld [%o5+4],%f11
- fmovd %f22,%f14
- ld [%o5+8],%f15
- fmovd %f22,%f18
- ld [%o5+12],%f19
- fxtod %f6,%f6
- std %f6,[%o4]
- fxtod %f10,%f10
- std %f10,[%o4+8]
- fxtod %f14,%f14
- std %f14,[%o4+16]
- fxtod %f18,%f18
- std %f18,[%o4+24]
- fmuld %f2,%f6,%f8
- fmuld %f2,%f10,%f12
- fmuld %f2,%f14,%f16
- fmuld %f2,%f18,%f20
- fdtox %f8,%f8
- fdtox %f12,%f12
- fdtox %f16,%f16
- fdtox %f20,%f20
- fxtod %f8,%f8
- std %f8,[%o3+8]
- fxtod %f12,%f12
- std %f12,[%o3+24]
- fxtod %f16,%f16
- std %f16,[%o3+40]
- fxtod %f20,%f20
- std %f20,[%o3+56]
- fmuld %f8,%f4,%f8
- fmuld %f12,%f4,%f12
- fmuld %f16,%f4,%f16
- fmuld %f20,%f4,%f20
- fsubd %f6,%f8,%f8
- std %f8,[%o3]
- fsubd %f10,%f12,%f12
- std %f12,[%o3+16]
- fsubd %f14,%f16,%f16
- std %f16,[%o3+32]
- fsubd %f18,%f20,%f20
- std %f20,[%o3+48]
- .end
-
-
diff --git a/security/nss/lib/freebl/mpi/montmulfv8.s b/security/nss/lib/freebl/mpi/montmulfv8.s
deleted file mode 100644
index ca738880f..000000000
--- a/security/nss/lib/freebl/mpi/montmulfv8.s
+++ /dev/null
@@ -1,1818 +0,0 @@
-!
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
- .section ".text",#alloc,#execinstr
- .file "montmulf.c"
-
- .section ".rodata",#alloc
- .global TwoTo16
- .align 8
-!
-! CONSTANT POOL
-!
- .global TwoTo16
-TwoTo16:
- .word 1089470464
- .word 0
- .type TwoTo16,#object
- .size TwoTo16,8
- .global TwoToMinus16
-!
-! CONSTANT POOL
-!
- .global TwoToMinus16
-TwoToMinus16:
- .word 1055916032
- .word 0
- .type TwoToMinus16,#object
- .size TwoToMinus16,8
- .global Zero
-!
-! CONSTANT POOL
-!
- .global Zero
-Zero:
- .word 0
- .word 0
- .type Zero,#object
- .size Zero,8
- .global TwoTo32
-!
-! CONSTANT POOL
-!
- .global TwoTo32
-TwoTo32:
- .word 1106247680
- .word 0
- .type TwoTo32,#object
- .size TwoTo32,8
- .global TwoToMinus32
-!
-! CONSTANT POOL
-!
- .global TwoToMinus32
-TwoToMinus32:
- .word 1039138816
- .word 0
- .type TwoToMinus32,#object
- .size TwoToMinus32,8
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 4
-!
-! SUBROUTINE conv_d16_to_i32
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global conv_d16_to_i32
- conv_d16_to_i32:
-/* 000000 */ save %sp,-128,%sp
-! FILE montmulf.c
-
-! 36 !#define RF_INLINE_MACROS
-! 38 !static const double TwoTo16=65536.0;
-! 39 !static const double TwoToMinus16=1.0/65536.0;
-! 40 !static const double Zero=0.0;
-! 41 !static const double TwoTo32=65536.0*65536.0;
-! 42 !static const double TwoToMinus32=1.0/(65536.0*65536.0);
-! 44 !#ifdef RF_INLINE_MACROS
-! 46 !double upper32(double);
-! 47 !double lower32(double, double);
-! 48 !double mod(double, double, double);
-! 50 !void i16_to_d16_and_d32x4(const double * /*1/(2^16)*/,
-! 51 ! const double * /* 2^16*/,
-! 52 ! const double * /* 0 */,
-! 53 ! double * /*result16*/,
-! 54 ! double * /* result32 */,
-! 55 ! float * /*source - should be unsigned int*
-! 56 ! converted to float* */);
-! 58 !#else
-! 60 !static double upper32(double x)
-! 61 !{
-! 62 ! return floor(x*TwoToMinus32);
-! 63 !}
-! 65 !static double lower32(double x, double y)
-! 66 !{
-! 67 ! return x-TwoTo32*floor(x*TwoToMinus32);
-! 68 !}
-! 70 !static double mod(double x, double oneoverm, double m)
-! 71 !{
-! 72 ! return x-m*floor(x*oneoverm);
-! 73 !}
-! 75 !#endif
-! 78 !static void cleanup(double *dt, int from, int tlen)
-! 79 !{
-! 80 ! int i;
-! 81 ! double tmp,tmp1,x,x1;
-! 83 ! tmp=tmp1=Zero;
-! 84 ! /* original code **
-! 85 ! for(i=2*from;i<2*tlen-2;i++)
-! 86 ! {
-! 87 ! x=dt[i];
-! 88 ! dt[i]=lower32(x,Zero)+tmp1;
-! 89 ! tmp1=tmp;
-! 90 ! tmp=upper32(x);
-! 91 ! }
-! 92 ! dt[tlen-2]+=tmp1;
-! 93 ! dt[tlen-1]+=tmp;
-! 94 ! **end original code ***/
-! 95 ! /* new code ***/
-! 96 ! for(i=2*from;i<2*tlen;i+=2)
-! 97 ! {
-! 98 ! x=dt[i];
-! 99 ! x1=dt[i+1];
-! 100 ! dt[i]=lower32(x,Zero)+tmp;
-! 101 ! dt[i+1]=lower32(x1,Zero)+tmp1;
-! 102 ! tmp=upper32(x);
-! 103 ! tmp1=upper32(x1);
-! 104 ! }
-! 105 ! /** end new code **/
-! 106 !}
-! 109 !void conv_d16_to_i32(unsigned int *i32, double *d16, long long *tmp, int ilen)
-! 110 !{
-! 111 !int i;
-! 112 !long long t, t1, a, b, c, d;
-! 114 ! t1=0;
-! 115 ! a=(long long)d16[0];
-
-/* 0x0004 115 */ ldd [%i1],%f0
-/* 0x0008 110 */ or %g0,%i1,%o0
-
-! 116 ! b=(long long)d16[1];
-! 117 ! for(i=0; i<ilen-1; i++)
-
-/* 0x000c 117 */ sub %i3,1,%g2
-/* 0x0010 */ cmp %g2,0
-/* 0x0014 114 */ or %g0,0,%o4
-/* 0x0018 115 */ fdtox %f0,%f0
-/* 0x001c */ std %f0,[%sp+120]
-/* 0x0020 117 */ or %g0,0,%o7
-/* 0x0024 110 */ or %g0,%i3,%o1
-/* 0x0028 */ sub %i3,2,%o2
-/* 0x002c 116 */ ldd [%o0+8],%f0
-/* 0x0030 110 */ sethi %hi(0xfc00),%o1
-/* 0x0034 */ add %o2,1,%g3
-/* 0x0038 */ add %o1,1023,%o1
-/* 0x003c */ or %g0,%i0,%o5
-/* 0x0040 116 */ fdtox %f0,%f0
-/* 0x0044 */ std %f0,[%sp+112]
-/* 0x0048 */ ldx [%sp+112],%g1
-/* 0x004c 115 */ ldx [%sp+120],%g4
-/* 0x0050 117 */ ble,pt %icc,.L900000117
-/* 0x0054 */ sethi %hi(0xfc00),%g2
-/* 0x0058 110 */ or %g0,-1,%g2
-/* 0x005c 117 */ cmp %g3,3
-/* 0x0060 110 */ srl %g2,0,%o3
-/* 0x0064 117 */ bl,pn %icc,.L77000134
-/* 0x0068 */ or %g0,%o0,%g2
-
-! 118 ! {
-! 119 ! c=(long long)d16[2*i+2];
-
-/* 0x006c 119 */ ldd [%o0+16],%f0
-
-! 120 ! t1+=a&0xffffffff;
-! 121 ! t=(a>>32);
-! 122 ! d=(long long)d16[2*i+3];
-! 123 ! t1+=(b&0xffff)<<16;
-! 124 ! t+=(b>>16)+(t1>>32);
-! 125 ! i32[i]=t1&0xffffffff;
-! 126 ! t1=t;
-! 127 ! a=c;
-! 128 ! b=d;
-
-/* 0x0070 128 */ add %o0,16,%g2
-/* 0x0074 123 */ and %g1,%o1,%o0
-/* 0x0078 */ sllx %o0,16,%g3
-/* 0x007c 120 */ and %g4,%o3,%o0
-/* 0x0080 117 */ add %o0,%g3,%o4
-/* 0x0084 119 */ fdtox %f0,%f0
-/* 0x0088 */ std %f0,[%sp+104]
-/* 0x008c 125 */ and %o4,%o3,%g5
-/* 0x0090 122 */ ldd [%g2+8],%f2
-/* 0x0094 128 */ add %o5,4,%o5
-/* 0x0098 124 */ srax %o4,32,%o4
-/* 0x009c */ stx %o4,[%sp+112]
-/* 0x00a0 122 */ fdtox %f2,%f0
-/* 0x00a4 */ std %f0,[%sp+96]
-/* 0x00a8 124 */ srax %g1,16,%o0
-/* 0x00ac */ ldx [%sp+112],%o7
-/* 0x00b0 121 */ srax %g4,32,%o4
-/* 0x00b4 124 */ add %o0,%o7,%g4
-/* 0x00b8 128 */ or %g0,1,%o7
-/* 0x00bc 119 */ ldx [%sp+104],%g3
-/* 0x00c0 124 */ add %o4,%g4,%o4
-/* 0x00c4 122 */ ldx [%sp+96],%g1
-/* 0x00c8 125 */ st %g5,[%o5-4]
-/* 0x00cc 127 */ or %g0,%g3,%g4
- .L900000112:
-/* 0x00d0 119 */ ldd [%g2+16],%f0
-/* 0x00d4 128 */ add %o7,1,%o7
-/* 0x00d8 */ add %o5,4,%o5
-/* 0x00dc */ cmp %o7,%o2
-/* 0x00e0 */ add %g2,16,%g2
-/* 0x00e4 119 */ fdtox %f0,%f0
-/* 0x00e8 */ std %f0,[%sp+104]
-/* 0x00ec 122 */ ldd [%g2+8],%f0
-/* 0x00f0 */ fdtox %f0,%f0
-/* 0x00f4 */ std %f0,[%sp+96]
-/* 0x00f8 123 */ and %g1,%o1,%g3
-/* 0x00fc */ sllx %g3,16,%g5
-/* 0x0100 120 */ and %g4,%o3,%g3
-/* 0x0104 117 */ add %g3,%g5,%g3
-/* 0x0108 124 */ srax %g1,16,%g1
-/* 0x010c 117 */ add %g3,%o4,%g3
-/* 0x0110 124 */ srax %g3,32,%o4
-/* 0x0114 */ stx %o4,[%sp+112]
-/* 0x0118 119 */ ldx [%sp+104],%g5
-/* 0x011c 121 */ srax %g4,32,%o4
-/* 0x0120 124 */ ldx [%sp+112],%g4
-/* 0x0124 */ add %g1,%g4,%g4
-/* 0x0128 122 */ ldx [%sp+96],%g1
-/* 0x012c 124 */ add %o4,%g4,%o4
-/* 0x0130 125 */ and %g3,%o3,%g3
-/* 0x0134 127 */ or %g0,%g5,%g4
-/* 0x0138 128 */ ble,pt %icc,.L900000112
-/* 0x013c */ st %g3,[%o5-4]
- .L900000115:
-/* 0x0140 128 */ ba .L900000117
-/* 0x0144 */ sethi %hi(0xfc00),%g2
- .L77000134:
-/* 0x0148 119 */ ldd [%g2+16],%f0
- .L900000116:
-/* 0x014c 120 */ and %g4,%o3,%o0
-/* 0x0150 123 */ and %g1,%o1,%g3
-/* 0x0154 119 */ fdtox %f0,%f0
-/* 0x0158 120 */ add %o4,%o0,%o0
-/* 0x015c 119 */ std %f0,[%sp+104]
-/* 0x0160 128 */ add %o7,1,%o7
-/* 0x0164 123 */ sllx %g3,16,%o4
-/* 0x0168 122 */ ldd [%g2+24],%f2
-/* 0x016c 128 */ add %g2,16,%g2
-/* 0x0170 123 */ add %o0,%o4,%o0
-/* 0x0174 128 */ cmp %o7,%o2
-/* 0x0178 125 */ and %o0,%o3,%g3
-/* 0x017c 122 */ fdtox %f2,%f0
-/* 0x0180 */ std %f0,[%sp+96]
-/* 0x0184 124 */ srax %o0,32,%o0
-/* 0x0188 */ stx %o0,[%sp+112]
-/* 0x018c 121 */ srax %g4,32,%o4
-/* 0x0190 122 */ ldx [%sp+96],%o0
-/* 0x0194 124 */ srax %g1,16,%g5
-/* 0x0198 */ ldx [%sp+112],%g4
-/* 0x019c 119 */ ldx [%sp+104],%g1
-/* 0x01a0 125 */ st %g3,[%o5]
-/* 0x01a4 124 */ add %g5,%g4,%g4
-/* 0x01a8 128 */ add %o5,4,%o5
-/* 0x01ac 124 */ add %o4,%g4,%o4
-/* 0x01b0 127 */ or %g0,%g1,%g4
-/* 0x01b4 128 */ or %g0,%o0,%g1
-/* 0x01b8 */ ble,a,pt %icc,.L900000116
-/* 0x01bc */ ldd [%g2+16],%f0
- .L77000127:
-
-! 129 ! }
-! 130 ! t1+=a&0xffffffff;
-! 131 ! t=(a>>32);
-! 132 ! t1+=(b&0xffff)<<16;
-! 133 ! i32[i]=t1&0xffffffff;
-
-/* 0x01c0 133 */ sethi %hi(0xfc00),%g2
- .L900000117:
-/* 0x01c4 133 */ or %g0,-1,%g3
-/* 0x01c8 */ add %g2,1023,%g2
-/* 0x01cc */ srl %g3,0,%g3
-/* 0x01d0 */ and %g1,%g2,%g2
-/* 0x01d4 */ and %g4,%g3,%g4
-/* 0x01d8 */ sllx %g2,16,%g2
-/* 0x01dc */ add %o4,%g4,%g4
-/* 0x01e0 */ add %g4,%g2,%g2
-/* 0x01e4 */ sll %o7,2,%g4
-/* 0x01e8 */ and %g2,%g3,%g2
-/* 0x01ec */ st %g2,[%i0+%g4]
-/* 0x01f0 */ ret ! Result =
-/* 0x01f4 */ restore %g0,%g0,%g0
-/* 0x01f8 0 */ .type conv_d16_to_i32,2
-/* 0x01f8 */ .size conv_d16_to_i32,(.-conv_d16_to_i32)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 8
-!
-! CONSTANT POOL
-!
- .L_const_seg_900000201:
-/* 000000 0 */ .word 1127219200,0
-/* 0x0008 0 */ .align 4
-/* 0x0008 */ .skip 16
-!
-! SUBROUTINE conv_i32_to_d32
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global conv_i32_to_d32
- conv_i32_to_d32:
-/* 000000 */ or %g0,%o7,%g2
-
-! 135 !}
-! 137 !void conv_i32_to_d32(double *d32, unsigned int *i32, int len)
-! 138 !{
-! 139 !int i;
-! 141 !#pragma pipeloop(0)
-! 142 ! for(i=0;i<len;i++) d32[i]=(double)(i32[i]);
-
-/* 0x0004 142 */ cmp %o2,0
- .L900000210:
-/* 0x0008 */ call .+8
-/* 0x000c */ sethi /*X*/%hi(_GLOBAL_OFFSET_TABLE_-(.L900000210-.)),%g4
-/* 0x0010 142 */ or %g0,0,%o5
-/* 0x0014 138 */ add %g4,/*X*/%lo(_GLOBAL_OFFSET_TABLE_-(.L900000210-.)),%g4
-/* 0x0018 */ or %g0,%o0,%g5
-/* 0x001c */ add %g4,%o7,%g1
-/* 0x0020 142 */ ble,pt %icc,.L77000140
-/* 0x0024 */ or %g0,%g2,%o7
-/* 0x0028 */ sethi %hi(.L_const_seg_900000201),%g2
-/* 0x002c 138 */ or %g0,%o1,%g4
-/* 0x0030 142 */ add %g2,%lo(.L_const_seg_900000201),%g2
-/* 0x0034 */ sub %o2,1,%g3
-/* 0x0038 */ ld [%g1+%g2],%g2
-/* 0x003c */ cmp %o2,9
-/* 0x0040 */ bl,pn %icc,.L77000144
-/* 0x0044 */ ldd [%g2],%f8
-/* 0x0048 */ add %o1,16,%g4
-/* 0x004c */ sub %o2,5,%g1
-/* 0x0050 */ ld [%o1],%f7
-/* 0x0054 */ or %g0,4,%o5
-/* 0x0058 */ ld [%o1+4],%f5
-/* 0x005c */ ld [%o1+8],%f3
-/* 0x0060 */ fmovs %f8,%f6
-/* 0x0064 */ ld [%o1+12],%f1
- .L900000205:
-/* 0x0068 */ ld [%g4],%f11
-/* 0x006c */ add %o5,5,%o5
-/* 0x0070 */ add %g4,20,%g4
-/* 0x0074 */ fsubd %f6,%f8,%f6
-/* 0x0078 */ std %f6,[%g5]
-/* 0x007c */ cmp %o5,%g1
-/* 0x0080 */ add %g5,40,%g5
-/* 0x0084 */ fmovs %f8,%f4
-/* 0x0088 */ ld [%g4-16],%f7
-/* 0x008c */ fsubd %f4,%f8,%f12
-/* 0x0090 */ fmovs %f8,%f2
-/* 0x0094 */ std %f12,[%g5-32]
-/* 0x0098 */ ld [%g4-12],%f5
-/* 0x009c */ fsubd %f2,%f8,%f12
-/* 0x00a0 */ fmovs %f8,%f0
-/* 0x00a4 */ std %f12,[%g5-24]
-/* 0x00a8 */ ld [%g4-8],%f3
-/* 0x00ac */ fsubd %f0,%f8,%f12
-/* 0x00b0 */ fmovs %f8,%f10
-/* 0x00b4 */ std %f12,[%g5-16]
-/* 0x00b8 */ ld [%g4-4],%f1
-/* 0x00bc */ fsubd %f10,%f8,%f10
-/* 0x00c0 */ fmovs %f8,%f6
-/* 0x00c4 */ ble,pt %icc,.L900000205
-/* 0x00c8 */ std %f10,[%g5-8]
- .L900000208:
-/* 0x00cc */ fmovs %f8,%f4
-/* 0x00d0 */ add %g5,32,%g5
-/* 0x00d4 */ cmp %o5,%g3
-/* 0x00d8 */ fmovs %f8,%f2
-/* 0x00dc */ fmovs %f8,%f0
-/* 0x00e0 */ fsubd %f6,%f8,%f6
-/* 0x00e4 */ std %f6,[%g5-32]
-/* 0x00e8 */ fsubd %f4,%f8,%f4
-/* 0x00ec */ std %f4,[%g5-24]
-/* 0x00f0 */ fsubd %f2,%f8,%f2
-/* 0x00f4 */ std %f2,[%g5-16]
-/* 0x00f8 */ fsubd %f0,%f8,%f0
-/* 0x00fc */ bg,pn %icc,.L77000140
-/* 0x0100 */ std %f0,[%g5-8]
- .L77000144:
-/* 0x0104 */ ld [%g4],%f1
- .L900000211:
-/* 0x0108 */ ldd [%g2],%f8
-/* 0x010c */ add %o5,1,%o5
-/* 0x0110 */ add %g4,4,%g4
-/* 0x0114 */ cmp %o5,%g3
-/* 0x0118 */ fmovs %f8,%f0
-/* 0x011c */ fsubd %f0,%f8,%f0
-/* 0x0120 */ std %f0,[%g5]
-/* 0x0124 */ add %g5,8,%g5
-/* 0x0128 */ ble,a,pt %icc,.L900000211
-/* 0x012c */ ld [%g4],%f1
- .L77000140:
-/* 0x0130 */ retl ! Result =
-/* 0x0134 */ nop
-/* 0x0138 0 */ .type conv_i32_to_d32,2
-/* 0x0138 */ .size conv_i32_to_d32,(.-conv_i32_to_d32)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 8
-!
-! CONSTANT POOL
-!
- .L_const_seg_900000301:
-/* 000000 0 */ .word 1127219200,0
-/* 0x0008 0 */ .align 4
-!
-! SUBROUTINE conv_i32_to_d16
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global conv_i32_to_d16
- conv_i32_to_d16:
-/* 000000 */ save %sp,-104,%sp
-/* 0x0004 */ or %g0,%i2,%o0
-
-! 143 !}
-! 146 !void conv_i32_to_d16(double *d16, unsigned int *i32, int len)
-! 147 !{
-! 148 !int i;
-! 149 !unsigned int a;
-! 151 !#pragma pipeloop(0)
-! 152 ! for(i=0;i<len;i++)
-! 153 ! {
-! 154 ! a=i32[i];
-! 155 ! d16[2*i]=(double)(a&0xffff);
-! 156 ! d16[2*i+1]=(double)(a>>16);
-
-/* 0x0008 156 */ sethi %hi(.L_const_seg_900000301),%g2
- .L900000310:
-/* 0x000c */ call .+8
-/* 0x0010 */ sethi /*X*/%hi(_GLOBAL_OFFSET_TABLE_-(.L900000310-.)),%g3
-/* 0x0014 152 */ cmp %o0,0
-/* 0x0018 147 */ add %g3,/*X*/%lo(_GLOBAL_OFFSET_TABLE_-(.L900000310-.)),%g3
-/* 0x001c 152 */ ble,pt %icc,.L77000150
-/* 0x0020 */ add %g3,%o7,%o2
-/* 0x0024 */ sub %i2,1,%o5
-/* 0x0028 156 */ add %g2,%lo(.L_const_seg_900000301),%o1
-/* 0x002c 152 */ sethi %hi(0xfc00),%o0
-/* 0x0030 */ ld [%o2+%o1],%o3
-/* 0x0034 */ add %o5,1,%g2
-/* 0x0038 */ or %g0,0,%g1
-/* 0x003c */ cmp %g2,3
-/* 0x0040 */ or %g0,%i1,%o7
-/* 0x0044 */ add %o0,1023,%o4
-/* 0x0048 */ or %g0,%i0,%g3
-/* 0x004c */ bl,pn %icc,.L77000154
-/* 0x0050 */ add %o7,4,%o0
-/* 0x0054 155 */ ldd [%o3],%f0
-/* 0x0058 156 */ or %g0,1,%g1
-/* 0x005c 154 */ ld [%o0-4],%o1
-/* 0x0060 0 */ or %g0,%o0,%o7
-/* 0x0064 155 */ and %o1,%o4,%o0
- .L900000306:
-/* 0x0068 155 */ st %o0,[%sp+96]
-/* 0x006c 156 */ add %g1,1,%g1
-/* 0x0070 */ add %g3,16,%g3
-/* 0x0074 */ cmp %g1,%o5
-/* 0x0078 */ add %o7,4,%o7
-/* 0x007c 155 */ ld [%sp+96],%f3
-/* 0x0080 */ fmovs %f0,%f2
-/* 0x0084 */ fsubd %f2,%f0,%f2
-/* 0x0088 156 */ srl %o1,16,%o0
-/* 0x008c 155 */ std %f2,[%g3-16]
-/* 0x0090 156 */ st %o0,[%sp+92]
-/* 0x0094 */ ld [%sp+92],%f3
-/* 0x0098 154 */ ld [%o7-4],%o1
-/* 0x009c 156 */ fmovs %f0,%f2
-/* 0x00a0 */ fsubd %f2,%f0,%f2
-/* 0x00a4 155 */ and %o1,%o4,%o0
-/* 0x00a8 156 */ ble,pt %icc,.L900000306
-/* 0x00ac */ std %f2,[%g3-8]
- .L900000309:
-/* 0x00b0 155 */ st %o0,[%sp+96]
-/* 0x00b4 */ fmovs %f0,%f2
-/* 0x00b8 156 */ add %g3,16,%g3
-/* 0x00bc */ srl %o1,16,%o0
-/* 0x00c0 155 */ ld [%sp+96],%f3
-/* 0x00c4 */ fsubd %f2,%f0,%f2
-/* 0x00c8 */ std %f2,[%g3-16]
-/* 0x00cc 156 */ st %o0,[%sp+92]
-/* 0x00d0 */ fmovs %f0,%f2
-/* 0x00d4 */ ld [%sp+92],%f3
-/* 0x00d8 */ fsubd %f2,%f0,%f0
-/* 0x00dc */ std %f0,[%g3-8]
-/* 0x00e0 */ ret ! Result =
-/* 0x00e4 */ restore %g0,%g0,%g0
- .L77000154:
-/* 0x00e8 154 */ ld [%o7],%o0
- .L900000311:
-/* 0x00ec 155 */ and %o0,%o4,%o1
-/* 0x00f0 */ st %o1,[%sp+96]
-/* 0x00f4 156 */ add %g1,1,%g1
-/* 0x00f8 155 */ ldd [%o3],%f0
-/* 0x00fc 156 */ srl %o0,16,%o0
-/* 0x0100 */ add %o7,4,%o7
-/* 0x0104 */ cmp %g1,%o5
-/* 0x0108 155 */ fmovs %f0,%f2
-/* 0x010c */ ld [%sp+96],%f3
-/* 0x0110 */ fsubd %f2,%f0,%f2
-/* 0x0114 */ std %f2,[%g3]
-/* 0x0118 156 */ st %o0,[%sp+92]
-/* 0x011c */ fmovs %f0,%f2
-/* 0x0120 */ ld [%sp+92],%f3
-/* 0x0124 */ fsubd %f2,%f0,%f0
-/* 0x0128 */ std %f0,[%g3+8]
-/* 0x012c */ add %g3,16,%g3
-/* 0x0130 */ ble,a,pt %icc,.L900000311
-/* 0x0134 */ ld [%o7],%o0
- .L77000150:
-/* 0x0138 */ ret ! Result =
-/* 0x013c */ restore %g0,%g0,%g0
-/* 0x0140 0 */ .type conv_i32_to_d16,2
-/* 0x0140 */ .size conv_i32_to_d16,(.-conv_i32_to_d16)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 8
-!
-! CONSTANT POOL
-!
- .L_const_seg_900000401:
-/* 000000 0 */ .word 1127219200,0
-/* 0x0008 0 */ .align 4
-/* 0x0008 */ .skip 16
-!
-! SUBROUTINE conv_i32_to_d32_and_d16
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global conv_i32_to_d32_and_d16
- conv_i32_to_d32_and_d16:
-/* 000000 */ save %sp,-120,%sp
- .L900000415:
-/* 0x0004 */ call .+8
-/* 0x0008 */ sethi /*X*/%hi(_GLOBAL_OFFSET_TABLE_-(.L900000415-.)),%g4
-
-! 157 ! }
-! 158 !}
-! 161 !void conv_i32_to_d32_and_d16(double *d32, double *d16,
-! 162 ! unsigned int *i32, int len)
-! 163 !{
-! 164 !int i = 0;
-! 165 !unsigned int a;
-! 167 !#pragma pipeloop(0)
-! 168 !#ifdef RF_INLINE_MACROS
-! 169 ! for(;i<len-3;i+=4)
-
-/* 0x000c 169 */ sub %i3,3,%g2
-/* 0x0010 */ cmp %g2,0
-/* 0x0014 163 */ add %g4,/*X*/%lo(_GLOBAL_OFFSET_TABLE_-(.L900000415-.)),%g4
-
-! 170 ! {
-! 171 ! i16_to_d16_and_d32x4(&TwoToMinus16, &TwoTo16, &Zero,
-! 172 ! &(d16[2*i]), &(d32[i]), (float *)(&(i32[i])));
-
-/* 0x0018 172 */ sethi %hi(Zero),%g2
-/* 0x001c 163 */ add %g4,%o7,%o4
-/* 0x0020 172 */ add %g2,%lo(Zero),%g2
-/* 0x0024 */ sethi %hi(TwoToMinus16),%g3
-/* 0x0028 */ ld [%o4+%g2],%o1
-/* 0x002c */ sethi %hi(TwoTo16),%g4
-/* 0x0030 */ add %g3,%lo(TwoToMinus16),%g2
-/* 0x0034 */ ld [%o4+%g2],%o3
-/* 0x0038 164 */ or %g0,0,%g5
-/* 0x003c 172 */ add %g4,%lo(TwoTo16),%g3
-/* 0x0040 */ ld [%o4+%g3],%o2
-/* 0x0044 163 */ or %g0,%i0,%i4
-/* 0x0048 169 */ or %g0,%i2,%o7
-/* 0x004c */ ble,pt %icc,.L900000418
-/* 0x0050 */ cmp %g5,%i3
-/* 0x0054 172 */ stx %o7,[%sp+104]
-/* 0x0058 169 */ sub %i3,4,%o5
-/* 0x005c */ or %g0,0,%g4
-/* 0x0060 */ or %g0,0,%g1
- .L900000417:
-/* 0x0064 */ ldd [%o1],%f2
-/* 0x0068 172 */ add %i4,%g4,%g2
-/* 0x006c */ add %i1,%g1,%g3
-/* 0x0070 */ ldd [%o3],%f0
-/* 0x0074 */ add %g5,4,%g5
-/* 0x0078 */ fmovd %f2,%f14
-/* 0x007c */ ld [%o7],%f15
-/* 0x0080 */ cmp %g5,%o5
-/* 0x0084 */ fmovd %f2,%f10
-/* 0x0088 */ ld [%o7+4],%f11
-/* 0x008c */ add %o7,16,%o7
-/* 0x0090 */ ldx [%sp+104],%o0
-/* 0x0094 */ fmovd %f2,%f6
-/* 0x0098 */ stx %o7,[%sp+112]
-/* 0x009c */ fxtod %f14,%f14
-/* 0x00a0 */ ld [%o0+8],%f7
-/* 0x00a4 */ fxtod %f10,%f10
-/* 0x00a8 */ ld [%o0+12],%f3
-/* 0x00ac */ fxtod %f6,%f6
-/* 0x00b0 */ ldd [%o2],%f16
-/* 0x00b4 */ fmuld %f0,%f14,%f12
-/* 0x00b8 */ fxtod %f2,%f2
-/* 0x00bc */ fmuld %f0,%f10,%f8
-/* 0x00c0 */ std %f14,[%i4+%g4]
-/* 0x00c4 */ ldx [%sp+112],%o7
-/* 0x00c8 */ add %g4,32,%g4
-/* 0x00cc */ fmuld %f0,%f6,%f4
-/* 0x00d0 */ fdtox %f12,%f12
-/* 0x00d4 */ std %f10,[%g2+8]
-/* 0x00d8 */ fmuld %f0,%f2,%f0
-/* 0x00dc */ fdtox %f8,%f8
-/* 0x00e0 */ std %f6,[%g2+16]
-/* 0x00e4 */ std %f2,[%g2+24]
-/* 0x00e8 */ fdtox %f4,%f4
-/* 0x00ec */ fdtox %f0,%f0
-/* 0x00f0 */ fxtod %f12,%f12
-/* 0x00f4 */ std %f12,[%g3+8]
-/* 0x00f8 */ fxtod %f8,%f8
-/* 0x00fc */ std %f8,[%g3+24]
-/* 0x0100 */ fxtod %f4,%f4
-/* 0x0104 */ std %f4,[%g3+40]
-/* 0x0108 */ fxtod %f0,%f0
-/* 0x010c */ std %f0,[%g3+56]
-/* 0x0110 */ fmuld %f12,%f16,%f12
-/* 0x0114 */ fmuld %f8,%f16,%f8
-/* 0x0118 */ fmuld %f4,%f16,%f4
-/* 0x011c */ fsubd %f14,%f12,%f12
-/* 0x0120 */ std %f12,[%i1+%g1]
-/* 0x0124 */ fmuld %f0,%f16,%f0
-/* 0x0128 */ fsubd %f10,%f8,%f8
-/* 0x012c */ std %f8,[%g3+16]
-/* 0x0130 */ add %g1,64,%g1
-/* 0x0134 */ fsubd %f6,%f4,%f4
-/* 0x0138 */ std %f4,[%g3+32]
-/* 0x013c */ fsubd %f2,%f0,%f0
-/* 0x0140 */ std %f0,[%g3+48]
-/* 0x0144 */ ble,a,pt %icc,.L900000417
-/* 0x0148 */ stx %o7,[%sp+104]
- .L77000159:
-
-! 173 ! }
-! 174 !#endif
-! 175 ! for(;i<len;i++)
-
-/* 0x014c 175 */ cmp %g5,%i3
- .L900000418:
-/* 0x0150 175 */ bge,pt %icc,.L77000164
-/* 0x0154 */ nop
-
-! 176 ! {
-! 177 ! a=i32[i];
-! 178 ! d32[i]=(double)(i32[i]);
-! 179 ! d16[2*i]=(double)(a&0xffff);
-! 180 ! d16[2*i+1]=(double)(a>>16);
-
-/* 0x0158 180 */ sethi %hi(.L_const_seg_900000401),%g2
-/* 0x015c */ add %g2,%lo(.L_const_seg_900000401),%o1
-/* 0x0160 175 */ sethi %hi(0xfc00),%o0
-/* 0x0164 */ ld [%o4+%o1],%o2
-/* 0x0168 */ sll %g5,2,%o3
-/* 0x016c */ sub %i3,%g5,%g3
-/* 0x0170 */ sll %g5,3,%g2
-/* 0x0174 */ add %o0,1023,%o4
-/* 0x0178 178 */ ldd [%o2],%f0
-/* 0x017c */ add %i2,%o3,%o0
-/* 0x0180 175 */ cmp %g3,3
-/* 0x0184 */ add %i4,%g2,%o3
-/* 0x0188 */ sub %i3,1,%o1
-/* 0x018c */ sll %g5,4,%g4
-/* 0x0190 */ bl,pn %icc,.L77000161
-/* 0x0194 */ add %i1,%g4,%o5
-/* 0x0198 178 */ ld [%o0],%f3
-/* 0x019c 180 */ add %o3,8,%o3
-/* 0x01a0 177 */ ld [%o0],%o7
-/* 0x01a4 180 */ add %o5,16,%o5
-/* 0x01a8 */ add %g5,1,%g5
-/* 0x01ac 178 */ fmovs %f0,%f2
-/* 0x01b0 180 */ add %o0,4,%o0
-/* 0x01b4 179 */ and %o7,%o4,%g1
-/* 0x01b8 178 */ fsubd %f2,%f0,%f2
-/* 0x01bc */ std %f2,[%o3-8]
-/* 0x01c0 180 */ srl %o7,16,%o7
-/* 0x01c4 179 */ st %g1,[%sp+96]
-/* 0x01c8 */ fmovs %f0,%f2
-/* 0x01cc */ ld [%sp+96],%f3
-/* 0x01d0 */ fsubd %f2,%f0,%f2
-/* 0x01d4 */ std %f2,[%o5-16]
-/* 0x01d8 180 */ st %o7,[%sp+92]
-/* 0x01dc */ fmovs %f0,%f2
-/* 0x01e0 */ ld [%sp+92],%f3
-/* 0x01e4 */ fsubd %f2,%f0,%f2
-/* 0x01e8 */ std %f2,[%o5-8]
- .L900000411:
-/* 0x01ec 178 */ ld [%o0],%f3
-/* 0x01f0 180 */ add %g5,2,%g5
-/* 0x01f4 */ add %o5,32,%o5
-/* 0x01f8 177 */ ld [%o0],%o7
-/* 0x01fc 180 */ cmp %g5,%o1
-/* 0x0200 */ add %o3,16,%o3
-/* 0x0204 178 */ fmovs %f0,%f2
-/* 0x0208 */ fsubd %f2,%f0,%f2
-/* 0x020c */ std %f2,[%o3-16]
-/* 0x0210 179 */ and %o7,%o4,%g1
-/* 0x0214 */ st %g1,[%sp+96]
-/* 0x0218 */ ld [%sp+96],%f3
-/* 0x021c */ fmovs %f0,%f2
-/* 0x0220 */ fsubd %f2,%f0,%f2
-/* 0x0224 180 */ srl %o7,16,%o7
-/* 0x0228 179 */ std %f2,[%o5-32]
-/* 0x022c 180 */ st %o7,[%sp+92]
-/* 0x0230 */ ld [%sp+92],%f3
-/* 0x0234 */ fmovs %f0,%f2
-/* 0x0238 */ fsubd %f2,%f0,%f2
-/* 0x023c */ std %f2,[%o5-24]
-/* 0x0240 */ add %o0,4,%o0
-/* 0x0244 178 */ ld [%o0],%f3
-/* 0x0248 177 */ ld [%o0],%o7
-/* 0x024c 178 */ fmovs %f0,%f2
-/* 0x0250 */ fsubd %f2,%f0,%f2
-/* 0x0254 */ std %f2,[%o3-8]
-/* 0x0258 179 */ and %o7,%o4,%g1
-/* 0x025c */ st %g1,[%sp+96]
-/* 0x0260 */ ld [%sp+96],%f3
-/* 0x0264 */ fmovs %f0,%f2
-/* 0x0268 */ fsubd %f2,%f0,%f2
-/* 0x026c 180 */ srl %o7,16,%o7
-/* 0x0270 179 */ std %f2,[%o5-16]
-/* 0x0274 180 */ st %o7,[%sp+92]
-/* 0x0278 */ ld [%sp+92],%f3
-/* 0x027c */ fmovs %f0,%f2
-/* 0x0280 */ fsubd %f2,%f0,%f2
-/* 0x0284 */ std %f2,[%o5-8]
-/* 0x0288 */ bl,pt %icc,.L900000411
-/* 0x028c */ add %o0,4,%o0
- .L900000414:
-/* 0x0290 180 */ cmp %g5,%i3
-/* 0x0294 */ bge,pn %icc,.L77000164
-/* 0x0298 */ nop
- .L77000161:
-/* 0x029c 178 */ ld [%o0],%f3
- .L900000416:
-/* 0x02a0 178 */ ldd [%o2],%f0
-/* 0x02a4 180 */ add %g5,1,%g5
-/* 0x02a8 177 */ ld [%o0],%o1
-/* 0x02ac 180 */ add %o0,4,%o0
-/* 0x02b0 */ cmp %g5,%i3
-/* 0x02b4 178 */ fmovs %f0,%f2
-/* 0x02b8 179 */ and %o1,%o4,%o7
-/* 0x02bc 178 */ fsubd %f2,%f0,%f2
-/* 0x02c0 */ std %f2,[%o3]
-/* 0x02c4 180 */ srl %o1,16,%o1
-/* 0x02c8 179 */ st %o7,[%sp+96]
-/* 0x02cc 180 */ add %o3,8,%o3
-/* 0x02d0 179 */ fmovs %f0,%f2
-/* 0x02d4 */ ld [%sp+96],%f3
-/* 0x02d8 */ fsubd %f2,%f0,%f2
-/* 0x02dc */ std %f2,[%o5]
-/* 0x02e0 180 */ st %o1,[%sp+92]
-/* 0x02e4 */ fmovs %f0,%f2
-/* 0x02e8 */ ld [%sp+92],%f3
-/* 0x02ec */ fsubd %f2,%f0,%f0
-/* 0x02f0 */ std %f0,[%o5+8]
-/* 0x02f4 */ add %o5,16,%o5
-/* 0x02f8 */ bl,a,pt %icc,.L900000416
-/* 0x02fc */ ld [%o0],%f3
- .L77000164:
-/* 0x0300 */ ret ! Result =
-/* 0x0304 */ restore %g0,%g0,%g0
-/* 0x0308 0 */ .type conv_i32_to_d32_and_d16,2
-/* 0x0308 */ .size conv_i32_to_d32_and_d16,(.-conv_i32_to_d32_and_d16)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 4
-!
-! SUBROUTINE adjust_montf_result
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global adjust_montf_result
- adjust_montf_result:
-/* 000000 */ or %g0,%o2,%g5
-
-! 181 ! }
-! 182 !}
-! 185 !void adjust_montf_result(unsigned int *i32, unsigned int *nint, int len)
-! 186 !{
-! 187 !long long acc;
-! 188 !int i;
-! 190 ! if(i32[len]>0) i=-1;
-
-/* 0x0004 190 */ or %g0,-1,%g4
-/* 0x0008 */ sll %o2,2,%g1
-/* 0x000c */ ld [%o0+%g1],%g1
-/* 0x0010 */ cmp %g1,0
-/* 0x0014 */ bleu,pn %icc,.L77000175
-/* 0x0018 */ or %g0,%o1,%o3
-/* 0x001c */ ba .L900000511
-/* 0x0020 */ cmp %g4,0
- .L77000175:
-
-! 191 ! else
-! 192 ! {
-! 193 ! for(i=len-1; i>=0; i--)
-
-/* 0x0024 193 */ sub %o2,1,%g4
-/* 0x0028 */ sll %g4,2,%g1
-/* 0x002c */ cmp %g4,0
-/* 0x0030 */ bl,pt %icc,.L900000511
-/* 0x0034 */ cmp %g4,0
-/* 0x0038 */ add %o1,%g1,%g2
-
-! 194 ! {
-! 195 ! if(i32[i]!=nint[i]) break;
-
-/* 0x003c 195 */ ld [%g2],%o5
-/* 0x0040 193 */ add %o0,%g1,%g3
- .L900000510:
-/* 0x0044 195 */ ld [%g3],%o2
-/* 0x0048 */ sub %g4,1,%g1
-/* 0x004c */ sub %g2,4,%g2
-/* 0x0050 */ sub %g3,4,%g3
-/* 0x0054 */ cmp %o2,%o5
-/* 0x0058 */ bne,pn %icc,.L77000182
-/* 0x005c */ nop
-/* 0x0060 0 */ or %g0,%g1,%g4
-/* 0x0064 195 */ cmp %g1,0
-/* 0x0068 */ bge,a,pt %icc,.L900000510
-/* 0x006c */ ld [%g2],%o5
- .L77000182:
-
-! 196 ! }
-! 197 ! }
-! 198 ! if((i<0)||(i32[i]>nint[i]))
-
-/* 0x0070 198 */ cmp %g4,0
- .L900000511:
-/* 0x0074 198 */ bl,pn %icc,.L77000198
-/* 0x0078 */ sll %g4,2,%g2
-/* 0x007c */ ld [%o1+%g2],%g1
-/* 0x0080 */ ld [%o0+%g2],%g2
-/* 0x0084 */ cmp %g2,%g1
-/* 0x0088 */ bleu,pt %icc,.L77000191
-/* 0x008c */ nop
- .L77000198:
-
-! 199 ! {
-! 200 ! acc=0;
-! 201 ! for(i=0;i<len;i++)
-
-/* 0x0090 201 */ cmp %g5,0
-/* 0x0094 */ ble,pt %icc,.L77000191
-/* 0x0098 */ nop
-/* 0x009c */ or %g0,%g5,%g1
-/* 0x00a0 198 */ or %g0,-1,%g2
-/* 0x00a4 */ srl %g2,0,%g3
-/* 0x00a8 */ sub %g5,1,%g4
-/* 0x00ac 200 */ or %g0,0,%g5
-/* 0x00b0 201 */ or %g0,0,%o5
-/* 0x00b4 198 */ or %g0,%o0,%o4
-/* 0x00b8 */ cmp %g1,3
-/* 0x00bc 201 */ bl,pn %icc,.L77000199
-/* 0x00c0 */ add %o0,8,%g1
-/* 0x00c4 */ add %o1,4,%g2
-
-! 202 ! {
-! 203 ! acc=acc+(unsigned long long)(i32[i])-(unsigned long long)(nint[i]);
-
-/* 0x00c8 203 */ ld [%o0],%o2
-/* 0x00cc */ ld [%o1],%o1
-/* 0x00d0 0 */ or %g0,%g1,%o4
-/* 0x00d4 */ or %g0,%g2,%o3
-/* 0x00d8 203 */ ld [%o0+4],%g1
-
-! 204 ! i32[i]=acc&0xffffffff;
-! 205 ! acc=acc>>32;
-
-/* 0x00dc 205 */ or %g0,2,%o5
-/* 0x00e0 201 */ sub %o2,%o1,%o2
-/* 0x00e4 */ or %g0,%o2,%g5
-/* 0x00e8 204 */ and %o2,%g3,%o2
-/* 0x00ec */ st %o2,[%o0]
-/* 0x00f0 205 */ srax %g5,32,%g5
- .L900000505:
-/* 0x00f4 203 */ ld [%o3],%o2
-/* 0x00f8 205 */ add %o5,1,%o5
-/* 0x00fc */ add %o3,4,%o3
-/* 0x0100 */ cmp %o5,%g4
-/* 0x0104 */ add %o4,4,%o4
-/* 0x0108 201 */ sub %g1,%o2,%g1
-/* 0x010c */ add %g1,%g5,%g5
-/* 0x0110 204 */ and %g5,%g3,%o2
-/* 0x0114 203 */ ld [%o4-4],%g1
-/* 0x0118 204 */ st %o2,[%o4-8]
-/* 0x011c 205 */ ble,pt %icc,.L900000505
-/* 0x0120 */ srax %g5,32,%g5
- .L900000508:
-/* 0x0124 203 */ ld [%o3],%g2
-/* 0x0128 201 */ sub %g1,%g2,%g1
-/* 0x012c */ add %g1,%g5,%g1
-/* 0x0130 204 */ and %g1,%g3,%g2
-/* 0x0134 */ retl ! Result =
-/* 0x0138 */ st %g2,[%o4-4]
- .L77000199:
-/* 0x013c 203 */ ld [%o4],%g1
- .L900000509:
-/* 0x0140 203 */ ld [%o3],%g2
-/* 0x0144 */ add %g5,%g1,%g1
-/* 0x0148 205 */ add %o5,1,%o5
-/* 0x014c */ add %o3,4,%o3
-/* 0x0150 */ cmp %o5,%g4
-/* 0x0154 203 */ sub %g1,%g2,%g1
-/* 0x0158 204 */ and %g1,%g3,%g2
-/* 0x015c */ st %g2,[%o4]
-/* 0x0160 205 */ add %o4,4,%o4
-/* 0x0164 */ srax %g1,32,%g5
-/* 0x0168 */ ble,a,pt %icc,.L900000509
-/* 0x016c */ ld [%o4],%g1
- .L77000191:
-/* 0x0170 */ retl ! Result =
-/* 0x0174 */ nop
-/* 0x0178 0 */ .type adjust_montf_result,2
-/* 0x0178 */ .size adjust_montf_result,(.-adjust_montf_result)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 4
-/* 000000 */ .skip 16
-!
-! SUBROUTINE mont_mulf_noconv
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global mont_mulf_noconv
- mont_mulf_noconv:
-/* 000000 */ save %sp,-144,%sp
- .L900000646:
-/* 0x0004 */ call .+8
-/* 0x0008 */ sethi /*X*/%hi(_GLOBAL_OFFSET_TABLE_-(.L900000646-.)),%g5
-
-! 206 ! }
-! 207 ! }
-! 208 !}
-! 213 !/*
-! 214 !** the lengths of the input arrays should be at least the following:
-! 215 !** result[nlen+1], dm1[nlen], dm2[2*nlen+1], dt[4*nlen+2], dn[nlen], nint[nlen]
-! 216 !** all of them should be different from one another
-! 217 !**
-! 218 !*/
-! 219 !void mont_mulf_noconv(unsigned int *result,
-! 220 ! double *dm1, double *dm2, double *dt,
-! 221 ! double *dn, unsigned int *nint,
-! 222 ! int nlen, double dn0)
-! 223 !{
-! 224 ! int i, j, jj;
-! 225 ! int tmp;
-! 226 ! double digit, m2j, nextm2j, a, b;
-! 227 ! double *dptmp, *pdm1, *pdm2, *pdn, *pdtj, pdn_0, pdm1_0;
-! 229 ! pdm1=&(dm1[0]);
-! 230 ! pdm2=&(dm2[0]);
-! 231 ! pdn=&(dn[0]);
-! 232 ! pdm2[2*nlen]=Zero;
-
-/* 0x000c 232 */ ld [%fp+92],%o1
-/* 0x0010 */ sethi %hi(Zero),%g2
-/* 0x0014 223 */ ldd [%fp+96],%f2
-/* 0x0018 */ add %g5,/*X*/%lo(_GLOBAL_OFFSET_TABLE_-(.L900000646-.)),%g5
-/* 0x001c 232 */ add %g2,%lo(Zero),%g2
-/* 0x0020 223 */ st %i0,[%fp+68]
-/* 0x0024 */ add %g5,%o7,%o3
-
-! 234 ! if (nlen!=16)
-! 235 ! {
-! 236 ! for(i=0;i<4*nlen+2;i++) dt[i]=Zero;
-! 238 ! a=dt[0]=pdm1[0]*pdm2[0];
-! 239 ! digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16);
-
-/* 0x0028 239 */ sethi %hi(TwoToMinus16),%g3
-/* 0x002c 232 */ ld [%o3+%g2],%l0
-/* 0x0030 239 */ sethi %hi(TwoTo16),%g4
-/* 0x0034 223 */ or %g0,%i2,%o2
-/* 0x0038 */ fmovd %f2,%f16
-/* 0x003c */ st %i5,[%fp+88]
-/* 0x0040 239 */ add %g3,%lo(TwoToMinus16),%g2
-/* 0x0044 223 */ or %g0,%i1,%i2
-/* 0x0048 232 */ ldd [%l0],%f0
-/* 0x004c 239 */ add %g4,%lo(TwoTo16),%g3
-/* 0x0050 223 */ or %g0,%i3,%o0
-/* 0x0054 232 */ sll %o1,4,%g4
-/* 0x0058 239 */ ld [%o3+%g2],%g5
-/* 0x005c 223 */ or %g0,%i3,%i1
-/* 0x0060 239 */ ld [%o3+%g3],%g1
-/* 0x0064 232 */ or %g0,%o1,%i0
-/* 0x0068 */ or %g0,%o2,%i3
-/* 0x006c 234 */ cmp %o1,16
-/* 0x0070 */ be,pn %icc,.L77000279
-/* 0x0074 */ std %f0,[%o2+%g4]
-/* 0x0078 236 */ sll %o1,2,%g2
-/* 0x007c */ or %g0,%o0,%o3
-/* 0x0080 232 */ sll %o1,1,%o1
-/* 0x0084 236 */ add %g2,2,%o2
-/* 0x0088 */ cmp %o2,0
-/* 0x008c */ ble,a,pt %icc,.L900000660
-/* 0x0090 */ ldd [%i2],%f0
-
-! 241 ! pdtj=&(dt[0]);
-! 242 ! for(j=jj=0;j<2*nlen;j++,jj++,pdtj++)
-! 243 ! {
-! 244 ! m2j=pdm2[j];
-! 245 ! a=pdtj[0]+pdn[0]*digit;
-! 246 ! b=pdtj[1]+pdm1[0]*pdm2[j+1]+a*TwoToMinus16;
-! 247 ! pdtj[1]=b;
-! 249 !#pragma pipeloop(0)
-! 250 ! for(i=1;i<nlen;i++)
-! 251 ! {
-! 252 ! pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit;
-! 253 ! }
-! 254 ! if((jj==30)) {cleanup(dt,j/2+1,2*nlen+1); jj=0;}
-! 255 !
-! 256 ! digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16);
-! 257 ! }
-! 258 ! }
-! 259 ! else
-! 260 ! {
-! 261 ! a=dt[0]=pdm1[0]*pdm2[0];
-! 263 ! dt[65]= dt[64]= dt[63]= dt[62]= dt[61]= dt[60]=
-! 264 ! dt[59]= dt[58]= dt[57]= dt[56]= dt[55]= dt[54]=
-! 265 ! dt[53]= dt[52]= dt[51]= dt[50]= dt[49]= dt[48]=
-! 266 ! dt[47]= dt[46]= dt[45]= dt[44]= dt[43]= dt[42]=
-! 267 ! dt[41]= dt[40]= dt[39]= dt[38]= dt[37]= dt[36]=
-! 268 ! dt[35]= dt[34]= dt[33]= dt[32]= dt[31]= dt[30]=
-! 269 ! dt[29]= dt[28]= dt[27]= dt[26]= dt[25]= dt[24]=
-! 270 ! dt[23]= dt[22]= dt[21]= dt[20]= dt[19]= dt[18]=
-! 271 ! dt[17]= dt[16]= dt[15]= dt[14]= dt[13]= dt[12]=
-! 272 ! dt[11]= dt[10]= dt[ 9]= dt[ 8]= dt[ 7]= dt[ 6]=
-! 273 ! dt[ 5]= dt[ 4]= dt[ 3]= dt[ 2]= dt[ 1]=Zero;
-! 275 ! pdn_0=pdn[0];
-! 276 ! pdm1_0=pdm1[0];
-! 278 ! digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16);
-! 279 ! pdtj=&(dt[0]);
-! 281 ! for(j=0;j<32;j++,pdtj++)
-
-/* 0x0094 281 */ add %g2,2,%o0
-/* 0x0098 236 */ add %g2,1,%o2
-/* 0x009c 281 */ cmp %o0,3
-/* 0x00a0 */ bl,pn %icc,.L77000280
-/* 0x00a4 */ or %g0,1,%o0
-/* 0x00a8 */ add %o3,8,%o3
-/* 0x00ac */ or %g0,1,%o4
-/* 0x00b0 */ std %f0,[%o3-8]
- .L900000630:
-/* 0x00b4 */ std %f0,[%o3]
-/* 0x00b8 */ add %o4,2,%o4
-/* 0x00bc */ add %o3,16,%o3
-/* 0x00c0 */ cmp %o4,%g2
-/* 0x00c4 */ ble,pt %icc,.L900000630
-/* 0x00c8 */ std %f0,[%o3-8]
- .L900000633:
-/* 0x00cc */ cmp %o4,%o2
-/* 0x00d0 */ bg,pn %icc,.L77000285
-/* 0x00d4 */ add %o4,1,%o0
- .L77000280:
-/* 0x00d8 */ std %f0,[%o3]
- .L900000659:
-/* 0x00dc */ ldd [%l0],%f0
-/* 0x00e0 */ cmp %o0,%o2
-/* 0x00e4 */ add %o3,8,%o3
-/* 0x00e8 */ add %o0,1,%o0
-/* 0x00ec */ ble,a,pt %icc,.L900000659
-/* 0x00f0 */ std %f0,[%o3]
- .L77000285:
-/* 0x00f4 238 */ ldd [%i2],%f0
- .L900000660:
-/* 0x00f8 238 */ ldd [%i3],%f2
-/* 0x00fc */ add %o1,1,%o2
-/* 0x0100 242 */ cmp %o1,0
-/* 0x0104 */ sll %o2,1,%o0
-/* 0x0108 */ sub %o1,1,%o1
-/* 0x010c 238 */ fmuld %f0,%f2,%f0
-/* 0x0110 */ std %f0,[%i1]
-/* 0x0114 0 */ or %g0,0,%l1
-/* 0x0118 */ ldd [%l0],%f6
-/* 0x011c */ or %g0,0,%g4
-/* 0x0120 */ or %g0,%o2,%i5
-/* 0x0124 */ ldd [%g5],%f2
-/* 0x0128 */ or %g0,%o1,%g3
-/* 0x012c */ or %g0,%o0,%o3
-/* 0x0130 */ fdtox %f0,%f0
-/* 0x0134 */ ldd [%g1],%f4
-/* 0x0138 246 */ add %i3,8,%o4
-/* 0x013c */ or %g0,0,%l2
-/* 0x0140 */ or %g0,%i1,%o5
-/* 0x0144 */ sub %i0,1,%o7
-/* 0x0148 */ fmovs %f6,%f0
-/* 0x014c */ fxtod %f0,%f0
-/* 0x0150 239 */ fmuld %f0,%f16,%f0
-/* 0x0154 */ fmuld %f0,%f2,%f2
-/* 0x0158 */ fdtox %f2,%f2
-/* 0x015c */ fxtod %f2,%f2
-/* 0x0160 */ fmuld %f2,%f4,%f2
-/* 0x0164 */ fsubd %f0,%f2,%f22
-/* 0x0168 242 */ ble,pt %icc,.L900000653
-/* 0x016c */ sll %i0,4,%g2
-/* 0x0170 246 */ ldd [%i4],%f0
- .L900000654:
-/* 0x0174 246 */ fmuld %f0,%f22,%f8
-/* 0x0178 */ ldd [%i2],%f0
-/* 0x017c 250 */ cmp %i0,1
-/* 0x0180 246 */ ldd [%o4+%l2],%f6
-/* 0x0184 */ add %i2,8,%o0
-/* 0x0188 250 */ or %g0,1,%o1
-/* 0x018c 246 */ ldd [%o5],%f2
-/* 0x0190 */ add %o5,16,%l3
-/* 0x0194 */ fmuld %f0,%f6,%f6
-/* 0x0198 */ ldd [%g5],%f4
-/* 0x019c */ faddd %f2,%f8,%f2
-/* 0x01a0 */ ldd [%o5+8],%f0
-/* 0x01a4 244 */ ldd [%i3+%l2],%f20
-/* 0x01a8 246 */ faddd %f0,%f6,%f0
-/* 0x01ac */ fmuld %f2,%f4,%f2
-/* 0x01b0 */ faddd %f0,%f2,%f18
-/* 0x01b4 247 */ std %f18,[%o5+8]
-/* 0x01b8 250 */ ble,pt %icc,.L900000658
-/* 0x01bc */ srl %g4,31,%g2
-/* 0x01c0 */ cmp %o7,7
-/* 0x01c4 246 */ add %i4,8,%g2
-/* 0x01c8 250 */ bl,pn %icc,.L77000284
-/* 0x01cc */ add %g2,24,%o2
-/* 0x01d0 252 */ ldd [%o0+24],%f12
-/* 0x01d4 */ add %o5,48,%l3
-/* 0x01d8 */ ldd [%o0],%f2
-/* 0x01dc 0 */ or %g0,%o2,%g2
-/* 0x01e0 250 */ sub %o7,2,%o2
-/* 0x01e4 252 */ ldd [%g2-24],%f0
-/* 0x01e8 */ or %g0,5,%o1
-/* 0x01ec */ ldd [%o0+8],%f6
-/* 0x01f0 */ fmuld %f2,%f20,%f2
-/* 0x01f4 */ ldd [%o0+16],%f14
-/* 0x01f8 */ fmuld %f0,%f22,%f4
-/* 0x01fc */ add %o0,32,%o0
-/* 0x0200 */ ldd [%g2-16],%f8
-/* 0x0204 */ fmuld %f6,%f20,%f10
-/* 0x0208 */ ldd [%o5+16],%f0
-/* 0x020c */ ldd [%g2-8],%f6
-/* 0x0210 */ faddd %f2,%f4,%f4
-/* 0x0214 */ ldd [%o5+32],%f2
- .L900000642:
-/* 0x0218 252 */ ldd [%g2],%f24
-/* 0x021c */ add %o1,3,%o1
-/* 0x0220 */ add %g2,24,%g2
-/* 0x0224 */ fmuld %f8,%f22,%f8
-/* 0x0228 */ ldd [%l3],%f28
-/* 0x022c */ cmp %o1,%o2
-/* 0x0230 */ add %o0,24,%o0
-/* 0x0234 */ ldd [%o0-24],%f26
-/* 0x0238 */ faddd %f0,%f4,%f0
-/* 0x023c */ add %l3,48,%l3
-/* 0x0240 */ faddd %f10,%f8,%f10
-/* 0x0244 */ fmuld %f14,%f20,%f4
-/* 0x0248 */ std %f0,[%l3-80]
-/* 0x024c */ ldd [%g2-16],%f8
-/* 0x0250 */ fmuld %f6,%f22,%f6
-/* 0x0254 */ ldd [%l3-32],%f0
-/* 0x0258 */ ldd [%o0-16],%f14
-/* 0x025c */ faddd %f2,%f10,%f2
-/* 0x0260 */ faddd %f4,%f6,%f10
-/* 0x0264 */ fmuld %f12,%f20,%f4
-/* 0x0268 */ std %f2,[%l3-64]
-/* 0x026c */ ldd [%g2-8],%f6
-/* 0x0270 */ fmuld %f24,%f22,%f24
-/* 0x0274 */ ldd [%l3-16],%f2
-/* 0x0278 */ ldd [%o0-8],%f12
-/* 0x027c */ faddd %f28,%f10,%f10
-/* 0x0280 */ std %f10,[%l3-48]
-/* 0x0284 */ fmuld %f26,%f20,%f10
-/* 0x0288 */ ble,pt %icc,.L900000642
-/* 0x028c */ faddd %f4,%f24,%f4
- .L900000645:
-/* 0x0290 252 */ fmuld %f8,%f22,%f28
-/* 0x0294 */ ldd [%g2],%f24
-/* 0x0298 */ faddd %f0,%f4,%f26
-/* 0x029c */ fmuld %f12,%f20,%f8
-/* 0x02a0 */ add %l3,32,%l3
-/* 0x02a4 */ cmp %o1,%o7
-/* 0x02a8 */ fmuld %f14,%f20,%f14
-/* 0x02ac */ ldd [%l3-32],%f4
-/* 0x02b0 */ add %g2,8,%g2
-/* 0x02b4 */ faddd %f10,%f28,%f12
-/* 0x02b8 */ fmuld %f6,%f22,%f6
-/* 0x02bc */ ldd [%l3-16],%f0
-/* 0x02c0 */ fmuld %f24,%f22,%f10
-/* 0x02c4 */ std %f26,[%l3-64]
-/* 0x02c8 */ faddd %f2,%f12,%f2
-/* 0x02cc */ std %f2,[%l3-48]
-/* 0x02d0 */ faddd %f14,%f6,%f6
-/* 0x02d4 */ faddd %f8,%f10,%f2
-/* 0x02d8 */ faddd %f4,%f6,%f4
-/* 0x02dc */ std %f4,[%l3-32]
-/* 0x02e0 */ faddd %f0,%f2,%f0
-/* 0x02e4 */ bg,pn %icc,.L77000213
-/* 0x02e8 */ std %f0,[%l3-16]
- .L77000284:
-/* 0x02ec 252 */ ldd [%o0],%f0
- .L900000657:
-/* 0x02f0 252 */ ldd [%g2],%f4
-/* 0x02f4 */ fmuld %f0,%f20,%f2
-/* 0x02f8 */ add %o1,1,%o1
-/* 0x02fc */ ldd [%l3],%f0
-/* 0x0300 */ add %o0,8,%o0
-/* 0x0304 */ add %g2,8,%g2
-/* 0x0308 */ fmuld %f4,%f22,%f4
-/* 0x030c */ cmp %o1,%o7
-/* 0x0310 */ faddd %f2,%f4,%f2
-/* 0x0314 */ faddd %f0,%f2,%f0
-/* 0x0318 */ std %f0,[%l3]
-/* 0x031c */ add %l3,16,%l3
-/* 0x0320 */ ble,a,pt %icc,.L900000657
-/* 0x0324 */ ldd [%o0],%f0
- .L77000213:
-/* 0x0328 */ srl %g4,31,%g2
- .L900000658:
-/* 0x032c 254 */ cmp %l1,30
-/* 0x0330 */ bne,a,pt %icc,.L900000656
-/* 0x0334 */ fdtox %f18,%f0
-/* 0x0338 */ add %g4,%g2,%g2
-/* 0x033c */ sra %g2,1,%o0
-/* 0x0340 281 */ ldd [%l0],%f0
-/* 0x0344 */ sll %i5,1,%o2
-/* 0x0348 */ add %o0,1,%g2
-/* 0x034c */ sll %g2,1,%o0
-/* 0x0350 254 */ sub %o2,1,%o2
-/* 0x0354 281 */ fmovd %f0,%f2
-/* 0x0358 */ sll %g2,4,%o1
-/* 0x035c */ cmp %o0,%o3
-/* 0x0360 */ bge,pt %icc,.L77000215
-/* 0x0364 */ or %g0,0,%l1
-/* 0x0368 254 */ add %i1,%o1,%o1
-/* 0x036c 281 */ ldd [%o1],%f6
- .L900000655:
-/* 0x0370 */ fdtox %f6,%f10
-/* 0x0374 */ ldd [%o1+8],%f4
-/* 0x0378 */ add %o0,2,%o0
-/* 0x037c */ ldd [%l0],%f12
-/* 0x0380 */ fdtox %f6,%f6
-/* 0x0384 */ cmp %o0,%o2
-/* 0x0388 */ fdtox %f4,%f8
-/* 0x038c */ fdtox %f4,%f4
-/* 0x0390 */ fmovs %f12,%f10
-/* 0x0394 */ fmovs %f12,%f8
-/* 0x0398 */ fxtod %f10,%f10
-/* 0x039c */ fxtod %f8,%f8
-/* 0x03a0 */ faddd %f10,%f2,%f2
-/* 0x03a4 */ std %f2,[%o1]
-/* 0x03a8 */ faddd %f8,%f0,%f0
-/* 0x03ac */ std %f0,[%o1+8]
-/* 0x03b0 */ add %o1,16,%o1
-/* 0x03b4 */ fitod %f6,%f2
-/* 0x03b8 */ fitod %f4,%f0
-/* 0x03bc */ ble,a,pt %icc,.L900000655
-/* 0x03c0 */ ldd [%o1],%f6
- .L77000233:
-/* 0x03c4 */ or %g0,0,%l1
- .L77000215:
-/* 0x03c8 */ fdtox %f18,%f0
- .L900000656:
-/* 0x03cc */ ldd [%l0],%f6
-/* 0x03d0 256 */ add %g4,1,%g4
-/* 0x03d4 */ add %l2,8,%l2
-/* 0x03d8 */ ldd [%g5],%f2
-/* 0x03dc */ add %l1,1,%l1
-/* 0x03e0 */ add %o5,8,%o5
-/* 0x03e4 */ fmovs %f6,%f0
-/* 0x03e8 */ ldd [%g1],%f4
-/* 0x03ec */ cmp %g4,%g3
-/* 0x03f0 */ fxtod %f0,%f0
-/* 0x03f4 */ fmuld %f0,%f16,%f0
-/* 0x03f8 */ fmuld %f0,%f2,%f2
-/* 0x03fc */ fdtox %f2,%f2
-/* 0x0400 */ fxtod %f2,%f2
-/* 0x0404 */ fmuld %f2,%f4,%f2
-/* 0x0408 */ fsubd %f0,%f2,%f22
-/* 0x040c */ ble,a,pt %icc,.L900000654
-/* 0x0410 */ ldd [%i4],%f0
- .L900000629:
-/* 0x0414 256 */ ba .L900000653
-/* 0x0418 */ sll %i0,4,%g2
- .L77000279:
-/* 0x041c 261 */ ldd [%o2],%f6
-/* 0x0420 279 */ or %g0,%o0,%o4
-/* 0x0424 281 */ or %g0,0,%o3
-/* 0x0428 261 */ ldd [%i2],%f4
-/* 0x042c 273 */ std %f0,[%o0+8]
-/* 0x0430 */ std %f0,[%o0+16]
-/* 0x0434 261 */ fmuld %f4,%f6,%f4
-/* 0x0438 */ std %f4,[%o0]
-/* 0x043c 273 */ std %f0,[%o0+24]
-/* 0x0440 */ std %f0,[%o0+32]
-/* 0x0444 */ fdtox %f4,%f4
-/* 0x0448 */ std %f0,[%o0+40]
-/* 0x044c */ std %f0,[%o0+48]
-/* 0x0450 */ std %f0,[%o0+56]
-/* 0x0454 */ std %f0,[%o0+64]
-/* 0x0458 */ std %f0,[%o0+72]
-/* 0x045c */ std %f0,[%o0+80]
-/* 0x0460 */ std %f0,[%o0+88]
-/* 0x0464 */ std %f0,[%o0+96]
-/* 0x0468 */ std %f0,[%o0+104]
-/* 0x046c */ std %f0,[%o0+112]
-/* 0x0470 */ std %f0,[%o0+120]
-/* 0x0474 */ std %f0,[%o0+128]
-/* 0x0478 */ std %f0,[%o0+136]
-/* 0x047c */ std %f0,[%o0+144]
-/* 0x0480 */ std %f0,[%o0+152]
-/* 0x0484 */ std %f0,[%o0+160]
-/* 0x0488 */ std %f0,[%o0+168]
-/* 0x048c */ fmovs %f0,%f4
-/* 0x0490 */ std %f0,[%o0+176]
-/* 0x0494 281 */ or %g0,0,%o1
-/* 0x0498 273 */ std %f0,[%o0+184]
-/* 0x049c */ fxtod %f4,%f4
-/* 0x04a0 */ std %f0,[%o0+192]
-/* 0x04a4 */ std %f0,[%o0+200]
-/* 0x04a8 */ std %f0,[%o0+208]
-/* 0x04ac 278 */ fmuld %f4,%f2,%f2
-/* 0x04b0 273 */ std %f0,[%o0+216]
-/* 0x04b4 */ std %f0,[%o0+224]
-/* 0x04b8 */ std %f0,[%o0+232]
-/* 0x04bc */ std %f0,[%o0+240]
-/* 0x04c0 */ std %f0,[%o0+248]
-/* 0x04c4 */ std %f0,[%o0+256]
-/* 0x04c8 */ std %f0,[%o0+264]
-/* 0x04cc */ std %f0,[%o0+272]
-/* 0x04d0 */ std %f0,[%o0+280]
-/* 0x04d4 */ std %f0,[%o0+288]
-/* 0x04d8 */ std %f0,[%o0+296]
-/* 0x04dc */ std %f0,[%o0+304]
-/* 0x04e0 */ std %f0,[%o0+312]
-/* 0x04e4 */ std %f0,[%o0+320]
-/* 0x04e8 */ std %f0,[%o0+328]
-/* 0x04ec */ std %f0,[%o0+336]
-/* 0x04f0 */ std %f0,[%o0+344]
-/* 0x04f4 */ std %f0,[%o0+352]
-/* 0x04f8 */ std %f0,[%o0+360]
-/* 0x04fc */ std %f0,[%o0+368]
-/* 0x0500 */ std %f0,[%o0+376]
-/* 0x0504 */ std %f0,[%o0+384]
-/* 0x0508 */ std %f0,[%o0+392]
-/* 0x050c */ std %f0,[%o0+400]
-/* 0x0510 */ std %f0,[%o0+408]
-/* 0x0514 */ std %f0,[%o0+416]
-/* 0x0518 */ std %f0,[%o0+424]
-/* 0x051c */ std %f0,[%o0+432]
-/* 0x0520 */ std %f0,[%o0+440]
-/* 0x0524 */ std %f0,[%o0+448]
-/* 0x0528 */ std %f0,[%o0+456]
-/* 0x052c */ std %f0,[%o0+464]
-/* 0x0530 */ std %f0,[%o0+472]
-/* 0x0534 */ std %f0,[%o0+480]
-/* 0x0538 */ std %f0,[%o0+488]
-/* 0x053c */ std %f0,[%o0+496]
-/* 0x0540 */ std %f0,[%o0+504]
-/* 0x0544 */ std %f0,[%o0+512]
-/* 0x0548 */ std %f0,[%o0+520]
-/* 0x054c */ ldd [%g5],%f0
-/* 0x0550 */ ldd [%g1],%f8
-/* 0x0554 */ fmuld %f2,%f0,%f6
-/* 0x0558 275 */ ldd [%i4],%f4
-/* 0x055c 276 */ ldd [%i2],%f0
-/* 0x0560 */ fdtox %f6,%f6
-/* 0x0564 */ fxtod %f6,%f6
-/* 0x0568 */ fmuld %f6,%f8,%f6
-/* 0x056c */ fsubd %f2,%f6,%f2
-/* 0x0570 286 */ fmuld %f4,%f2,%f12
-
-! 282 ! {
-! 284 ! m2j=pdm2[j];
-! 285 ! a=pdtj[0]+pdn_0*digit;
-! 286 ! b=pdtj[1]+pdm1_0*pdm2[j+1]+a*TwoToMinus16;
-
-! 287 ! pdtj[1]=b;
-! 289 ! /**** this loop will be fully unrolled:
-! 290 ! for(i=1;i<16;i++)
-! 291 ! {
-! 292 ! pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit;
-! 293 ! }
-! 294 ! *************************************/
-! 295 ! pdtj[2]+=pdm1[1]*m2j+pdn[1]*digit;
-! 296 ! pdtj[4]+=pdm1[2]*m2j+pdn[2]*digit;
-! 297 ! pdtj[6]+=pdm1[3]*m2j+pdn[3]*digit;
-! 298 ! pdtj[8]+=pdm1[4]*m2j+pdn[4]*digit;
-! 299 ! pdtj[10]+=pdm1[5]*m2j+pdn[5]*digit;
-! 300 ! pdtj[12]+=pdm1[6]*m2j+pdn[6]*digit;
-! 301 ! pdtj[14]+=pdm1[7]*m2j+pdn[7]*digit;
-! 302 ! pdtj[16]+=pdm1[8]*m2j+pdn[8]*digit;
-! 303 ! pdtj[18]+=pdm1[9]*m2j+pdn[9]*digit;
-! 304 ! pdtj[20]+=pdm1[10]*m2j+pdn[10]*digit;
-! 305 ! pdtj[22]+=pdm1[11]*m2j+pdn[11]*digit;
-! 306 ! pdtj[24]+=pdm1[12]*m2j+pdn[12]*digit;
-! 307 ! pdtj[26]+=pdm1[13]*m2j+pdn[13]*digit;
-! 308 ! pdtj[28]+=pdm1[14]*m2j+pdn[14]*digit;
-! 309 ! pdtj[30]+=pdm1[15]*m2j+pdn[15]*digit;
-! 310 ! /* no need for cleenup, cannot overflow */
-! 311 ! digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16);
-
- fmovd %f2,%f0 ! hand modified
- fmovd %f16,%f18 ! hand modified
- ldd [%i4],%f2
- ldd [%o4],%f8
- ldd [%i2],%f10
- ldd [%g5],%f14 ! hand modified
- ldd [%g1],%f16 ! hand modified
- ldd [%i3],%f24
-
- ldd [%i2+8],%f26
- ldd [%i2+16],%f40
- ldd [%i2+48],%f46
- ldd [%i2+56],%f30
- ldd [%i2+64],%f54
- ldd [%i2+104],%f34
- ldd [%i2+112],%f58
-
- ldd [%i4+8],%f28
- ldd [%i4+104],%f38
- ldd [%i4+112],%f60
-
- .L99999999: !1
- ldd [%i2+24],%f32
- fmuld %f0,%f2,%f4 !2
- ldd [%i4+24],%f36
- fmuld %f26,%f24,%f20 !3
- ldd [%i2+40],%f42
- fmuld %f28,%f0,%f22 !4
- ldd [%i4+40],%f44
- fmuld %f32,%f24,%f32 !5
- ldd [%i3+8],%f6
- faddd %f4,%f8,%f4
- fmuld %f36,%f0,%f36 !6
- add %i3,8,%i3
- ldd [%i4+56],%f50
- fmuld %f42,%f24,%f42 !7
- ldd [%i2+72],%f52
- faddd %f20,%f22,%f20
- fmuld %f44,%f0,%f44 !8
- ldd [%o4+16],%f22
- fmuld %f10,%f6,%f12 !9
- ldd [%i4+72],%f56
- faddd %f32,%f36,%f32
- fmuld %f14,%f4,%f4 !10
- ldd [%o4+48],%f36
- fmuld %f30,%f24,%f48 !11
- ldd [%o4+8],%f8
- faddd %f20,%f22,%f20
- fmuld %f50,%f0,%f50 !12
- std %f20,[%o4+16]
- faddd %f42,%f44,%f42
- fmuld %f52,%f24,%f52 !13
- ldd [%o4+80],%f44
- faddd %f4,%f12,%f4
- fmuld %f56,%f0,%f56 !14
- ldd [%i2+88],%f20
- faddd %f32,%f36,%f32 !15
- ldd [%i4+88],%f22
- faddd %f48,%f50,%f48 !16
- ldd [%o4+112],%f50
- faddd %f52,%f56,%f52 !17
- ldd [%o4+144],%f56
- faddd %f4,%f8,%f8
- fmuld %f20,%f24,%f20 !18
- std %f32,[%o4+48]
- faddd %f42,%f44,%f42
- fmuld %f22,%f0,%f22 !19
- std %f42,[%o4+80]
- faddd %f48,%f50,%f48
- fmuld %f34,%f24,%f32 !20
- std %f48,[%o4+112]
- faddd %f52,%f56,%f52
- fmuld %f38,%f0,%f36 !21
- ldd [%i2+120],%f42
- fdtox %f8,%f4 !22
- std %f52,[%o4+144]
- faddd %f20,%f22,%f20 !23
- ldd [%i4+120],%f44 !24
- ldd [%o4+176],%f22
- faddd %f32,%f36,%f32
- fmuld %f42,%f24,%f42 !25
- ldd [%i4+16],%f50
- fmovs %f17,%f4 !26
- ldd [%i2+32],%f52
- fmuld %f44,%f0,%f44 !27
- ldd [%i4+32],%f56
- fmuld %f40,%f24,%f48 !28
- ldd [%o4+208],%f36
- faddd %f20,%f22,%f20
- fmuld %f50,%f0,%f50 !29
- std %f20,[%o4+176]
- fxtod %f4,%f4
- fmuld %f52,%f24,%f52 !30
- ldd [%i4+48],%f22
- faddd %f42,%f44,%f42
- fmuld %f56,%f0,%f56 !31
- ldd [%o4+240],%f44
- faddd %f32,%f36,%f32 !32
- std %f32,[%o4+208]
- faddd %f48,%f50,%f48
- fmuld %f46,%f24,%f20 !33
- ldd [%o4+32],%f50
- fmuld %f4,%f18,%f12 !34
- ldd [%i4+64],%f36
- faddd %f52,%f56,%f52
- fmuld %f22,%f0,%f22 !35
- ldd [%o4+64],%f56
- faddd %f42,%f44,%f42 !36
- std %f42,[%o4+240]
- faddd %f48,%f50,%f48
- fmuld %f54,%f24,%f32 !37
- std %f48,[%o4+32]
- fmuld %f12,%f14,%f4 !38
- ldd [%i2+80],%f42
- faddd %f52,%f56,%f56 ! yes, tmp52!
- fmuld %f36,%f0,%f36 !39
- ldd [%i4+80],%f44
- faddd %f20,%f22,%f20 !40
- ldd [%i2+96],%f48
- fmuld %f58,%f24,%f52 !41
- ldd [%i4+96],%f50
- fdtox %f4,%f4
- fmuld %f42,%f24,%f42 !42
- std %f56,[%o4+64] ! yes, tmp52!
- faddd %f32,%f36,%f32
- fmuld %f44,%f0,%f44 !43
- ldd [%o4+96],%f22
- fmuld %f48,%f24,%f48 !44
- ldd [%o4+128],%f36
- fmovd %f6,%f24
- fmuld %f50,%f0,%f50 !45
- fxtod %f4,%f4
- fmuld %f60,%f0,%f56 !46
- add %o4,8,%o4
- faddd %f42,%f44,%f42 !47
- ldd [%o4+160-8],%f44
- faddd %f20,%f22,%f20 !48
- std %f20,[%o4+96-8]
- faddd %f48,%f50,%f48 !49
- ldd [%o4+192-8],%f50
- faddd %f52,%f56,%f52
- fmuld %f4,%f16,%f4 !50
- ldd [%o4+224-8],%f56
- faddd %f32,%f36,%f32 !51
- std %f32,[%o4+128-8]
- faddd %f42,%f44,%f42 !52
- add %o3,1,%o3
- std %f42,[%o4+160-8]
- faddd %f48,%f50,%f48 !53
- cmp %o3,31
- std %f48,[%o4+192-8]
- fsubd %f12,%f4,%f0 !54
- faddd %f52,%f56,%f52
- ble,pt %icc,.L99999999
- std %f52,[%o4+224-8] !55
- std %f8,[%o4]
-
-! 312 ! }
-! 313 ! }
-! 315 ! conv_d16_to_i32(result,dt+2*nlen,(long long *)dt,nlen+1);
-
-/* 0x07c8 315 */ sll %i0,4,%g2
- .L900000653:
-/* 0x07cc 315 */ add %i1,%g2,%i1
-/* 0x07d0 242 */ ld [%fp+68],%o0
-/* 0x07d4 315 */ or %g0,0,%o4
-/* 0x07d8 */ ldd [%i1],%f0
-/* 0x07dc */ or %g0,0,%g5
-/* 0x07e0 */ cmp %i0,0
-/* 0x07e4 242 */ or %g0,%o0,%o3
-/* 0x07e8 311 */ sub %i0,1,%g1
-/* 0x07ec 315 */ fdtox %f0,%f0
-/* 0x07f0 */ std %f0,[%sp+120]
-/* 0x07f4 311 */ sethi %hi(0xfc00),%o1
-/* 0x07f8 */ add %g1,1,%g3
-/* 0x07fc */ or %g0,%o0,%g4
-/* 0x0800 315 */ ldd [%i1+8],%f0
-/* 0x0804 */ add %o1,1023,%o1
-/* 0x0808 */ fdtox %f0,%f0
-/* 0x080c */ std %f0,[%sp+112]
-/* 0x0810 */ ldx [%sp+112],%o5
-/* 0x0814 */ ldx [%sp+120],%o7
-/* 0x0818 */ ble,pt %icc,.L900000651
-/* 0x081c */ sethi %hi(0xfc00),%g2
-/* 0x0820 311 */ or %g0,-1,%g2
-/* 0x0824 315 */ cmp %g3,3
-/* 0x0828 311 */ srl %g2,0,%o2
-/* 0x082c 315 */ bl,pn %icc,.L77000287
-/* 0x0830 */ or %g0,%i1,%g2
-/* 0x0834 */ ldd [%i1+16],%f0
-/* 0x0838 */ and %o5,%o1,%o0
-/* 0x083c */ add %i1,16,%g2
-/* 0x0840 */ sllx %o0,16,%g3
-/* 0x0844 */ and %o7,%o2,%o0
-/* 0x0848 */ fdtox %f0,%f0
-/* 0x084c */ std %f0,[%sp+104]
-/* 0x0850 */ add %o0,%g3,%o4
-/* 0x0854 */ ldd [%i1+24],%f2
-/* 0x0858 */ srax %o5,16,%o0
-/* 0x085c */ add %o3,4,%g4
-/* 0x0860 */ stx %o0,[%sp+128]
-/* 0x0864 */ and %o4,%o2,%o0
-/* 0x0868 */ stx %o0,[%sp+112]
-/* 0x086c */ srax %o4,32,%o0
-/* 0x0870 */ fdtox %f2,%f0
-/* 0x0874 */ stx %o0,[%sp+136]
-/* 0x0878 */ srax %o7,32,%o4
-/* 0x087c */ std %f0,[%sp+96]
-/* 0x0880 */ ldx [%sp+128],%g5
-/* 0x0884 */ ldx [%sp+136],%o7
-/* 0x0888 */ ldx [%sp+104],%g3
-/* 0x088c */ add %g5,%o7,%o0
-/* 0x0890 */ or %g0,1,%g5
-/* 0x0894 */ ldx [%sp+112],%o7
-/* 0x0898 */ add %o4,%o0,%o4
-/* 0x089c */ ldx [%sp+96],%o5
-/* 0x08a0 */ st %o7,[%o3]
-/* 0x08a4 */ or %g0,%g3,%o7
- .L900000634:
-/* 0x08a8 */ ldd [%g2+16],%f0
-/* 0x08ac */ add %g5,1,%g5
-/* 0x08b0 */ add %g4,4,%g4
-/* 0x08b4 */ cmp %g5,%g1
-/* 0x08b8 */ add %g2,16,%g2
-/* 0x08bc */ fdtox %f0,%f0
-/* 0x08c0 */ std %f0,[%sp+104]
-/* 0x08c4 */ ldd [%g2+8],%f0
-/* 0x08c8 */ fdtox %f0,%f0
-/* 0x08cc */ std %f0,[%sp+96]
-/* 0x08d0 */ and %o5,%o1,%g3
-/* 0x08d4 */ sllx %g3,16,%g3
-/* 0x08d8 */ stx %g3,[%sp+120]
-/* 0x08dc */ and %o7,%o2,%g3
-/* 0x08e0 */ stx %o7,[%sp+128]
-/* 0x08e4 */ ldx [%sp+120],%o7
-/* 0x08e8 */ add %g3,%o7,%g3
-/* 0x08ec */ ldx [%sp+128],%o7
-/* 0x08f0 */ srax %o5,16,%o5
-/* 0x08f4 */ add %g3,%o4,%g3
-/* 0x08f8 */ srax %g3,32,%o4
-/* 0x08fc */ stx %o4,[%sp+112]
-/* 0x0900 */ srax %o7,32,%o4
-/* 0x0904 */ ldx [%sp+112],%o7
-/* 0x0908 */ add %o5,%o7,%o7
-/* 0x090c */ ldx [%sp+96],%o5
-/* 0x0910 */ add %o4,%o7,%o4
-/* 0x0914 */ and %g3,%o2,%g3
-/* 0x0918 */ ldx [%sp+104],%o7
-/* 0x091c */ ble,pt %icc,.L900000634
-/* 0x0920 */ st %g3,[%g4-4]
- .L900000637:
-/* 0x0924 */ ba .L900000651
-/* 0x0928 */ sethi %hi(0xfc00),%g2
- .L77000287:
-/* 0x092c */ ldd [%g2+16],%f0
- .L900000650:
-/* 0x0930 */ and %o7,%o2,%o0
-/* 0x0934 */ and %o5,%o1,%g3
-/* 0x0938 */ fdtox %f0,%f0
-/* 0x093c */ add %o4,%o0,%o0
-/* 0x0940 */ std %f0,[%sp+104]
-/* 0x0944 */ add %g5,1,%g5
-/* 0x0948 */ sllx %g3,16,%o4
-/* 0x094c */ ldd [%g2+24],%f2
-/* 0x0950 */ add %g2,16,%g2
-/* 0x0954 */ add %o0,%o4,%o4
-/* 0x0958 */ cmp %g5,%g1
-/* 0x095c */ srax %o5,16,%o0
-/* 0x0960 */ stx %o0,[%sp+112]
-/* 0x0964 */ and %o4,%o2,%g3
-/* 0x0968 */ srax %o4,32,%o5
-/* 0x096c */ fdtox %f2,%f0
-/* 0x0970 */ std %f0,[%sp+96]
-/* 0x0974 */ srax %o7,32,%o4
-/* 0x0978 */ ldx [%sp+112],%o7
-/* 0x097c */ add %o7,%o5,%o7
-/* 0x0980 */ ldx [%sp+104],%o5
-/* 0x0984 */ add %o4,%o7,%o4
-/* 0x0988 */ ldx [%sp+96],%o0
-/* 0x098c */ st %g3,[%g4]
-/* 0x0990 */ or %g0,%o5,%o7
-/* 0x0994 */ add %g4,4,%g4
-/* 0x0998 */ or %g0,%o0,%o5
-/* 0x099c */ ble,a,pt %icc,.L900000650
-/* 0x09a0 */ ldd [%g2+16],%f0
- .L77000236:
-/* 0x09a4 */ sethi %hi(0xfc00),%g2
- .L900000651:
-/* 0x09a8 */ or %g0,-1,%o0
-/* 0x09ac */ add %g2,1023,%g2
-/* 0x09b0 */ ld [%fp+88],%o1
-/* 0x09b4 */ srl %o0,0,%g3
-/* 0x09b8 */ and %o5,%g2,%g2
-/* 0x09bc */ and %o7,%g3,%g4
-
-! 317 ! adjust_montf_result(result,nint,nlen);
-
-/* 0x09c0 317 */ or %g0,-1,%o5
-/* 0x09c4 311 */ sllx %g2,16,%g2
-/* 0x09c8 */ add %o4,%g4,%g4
-/* 0x09cc */ add %g4,%g2,%g2
-/* 0x09d0 */ sll %g5,2,%g4
-/* 0x09d4 */ and %g2,%g3,%g2
-/* 0x09d8 */ st %g2,[%o3+%g4]
-/* 0x09dc 317 */ sll %i0,2,%g2
-/* 0x09e0 */ ld [%o3+%g2],%g2
-/* 0x09e4 */ cmp %g2,0
-/* 0x09e8 */ bleu,pn %icc,.L77000241
-/* 0x09ec */ or %g0,%o1,%o2
-/* 0x09f0 */ ba .L900000649
-/* 0x09f4 */ cmp %o5,0
- .L77000241:
-/* 0x09f8 */ sub %i0,1,%o5
-/* 0x09fc */ sll %o5,2,%g2
-/* 0x0a00 */ cmp %o5,0
-/* 0x0a04 */ bl,pt %icc,.L900000649
-/* 0x0a08 */ cmp %o5,0
-/* 0x0a0c */ add %o1,%g2,%o1
-/* 0x0a10 */ add %o3,%g2,%o4
-/* 0x0a14 */ ld [%o1],%g2
- .L900000648:
-/* 0x0a18 */ ld [%o4],%g3
-/* 0x0a1c */ sub %o5,1,%o0
-/* 0x0a20 */ sub %o1,4,%o1
-/* 0x0a24 */ sub %o4,4,%o4
-/* 0x0a28 */ cmp %g3,%g2
-/* 0x0a2c */ bne,pn %icc,.L77000244
-/* 0x0a30 */ nop
-/* 0x0a34 0 */ or %g0,%o0,%o5
-/* 0x0a38 317 */ cmp %o0,0
-/* 0x0a3c */ bge,a,pt %icc,.L900000648
-/* 0x0a40 */ ld [%o1],%g2
- .L77000244:
-/* 0x0a44 */ cmp %o5,0
- .L900000649:
-/* 0x0a48 */ bl,pn %icc,.L77000288
-/* 0x0a4c */ sll %o5,2,%g2
-/* 0x0a50 */ ld [%o2+%g2],%g3
-/* 0x0a54 */ ld [%o3+%g2],%g2
-/* 0x0a58 */ cmp %g2,%g3
-/* 0x0a5c */ bleu,pt %icc,.L77000224
-/* 0x0a60 */ nop
- .L77000288:
-/* 0x0a64 */ cmp %i0,0
-/* 0x0a68 */ ble,pt %icc,.L77000224
-/* 0x0a6c */ nop
-/* 0x0a70 317 */ sub %i0,1,%o7
-/* 0x0a74 */ or %g0,-1,%g2
-/* 0x0a78 */ srl %g2,0,%o4
-/* 0x0a7c */ add %o7,1,%o0
-/* 0x0a80 315 */ or %g0,0,%o5
-/* 0x0a84 */ or %g0,0,%g1
-/* 0x0a88 */ cmp %o0,3
-/* 0x0a8c */ bl,pn %icc,.L77000289
-/* 0x0a90 */ add %o3,8,%o1
-/* 0x0a94 */ add %o2,4,%o0
-/* 0x0a98 */ ld [%o1-8],%g2
-/* 0x0a9c 0 */ or %g0,%o1,%o3
-/* 0x0aa0 315 */ ld [%o0-4],%g3
-/* 0x0aa4 0 */ or %g0,%o0,%o2
-/* 0x0aa8 315 */ or %g0,2,%g1
-/* 0x0aac */ ld [%o3-4],%o0
-/* 0x0ab0 */ sub %g2,%g3,%g2
-/* 0x0ab4 */ or %g0,%g2,%o5
-/* 0x0ab8 */ and %g2,%o4,%g2
-/* 0x0abc */ st %g2,[%o3-8]
-/* 0x0ac0 */ srax %o5,32,%o5
- .L900000638:
-/* 0x0ac4 */ ld [%o2],%g2
-/* 0x0ac8 */ add %g1,1,%g1
-/* 0x0acc */ add %o2,4,%o2
-/* 0x0ad0 */ cmp %g1,%o7
-/* 0x0ad4 */ add %o3,4,%o3
-/* 0x0ad8 */ sub %o0,%g2,%o0
-/* 0x0adc */ add %o0,%o5,%o5
-/* 0x0ae0 */ and %o5,%o4,%g2
-/* 0x0ae4 */ ld [%o3-4],%o0
-/* 0x0ae8 */ st %g2,[%o3-8]
-/* 0x0aec */ ble,pt %icc,.L900000638
-/* 0x0af0 */ srax %o5,32,%o5
- .L900000641:
-/* 0x0af4 */ ld [%o2],%o1
-/* 0x0af8 */ sub %o0,%o1,%o0
-/* 0x0afc */ add %o0,%o5,%o0
-/* 0x0b00 */ and %o0,%o4,%o1
-/* 0x0b04 */ st %o1,[%o3-4]
-/* 0x0b08 */ ret ! Result =
-/* 0x0b0c */ restore %g0,%g0,%g0
- .L77000289:
-/* 0x0b10 */ ld [%o3],%o0
- .L900000647:
-/* 0x0b14 */ ld [%o2],%o1
-/* 0x0b18 */ add %o5,%o0,%o0
-/* 0x0b1c */ add %g1,1,%g1
-/* 0x0b20 */ add %o2,4,%o2
-/* 0x0b24 */ cmp %g1,%o7
-/* 0x0b28 */ sub %o0,%o1,%o0
-/* 0x0b2c */ and %o0,%o4,%o1
-/* 0x0b30 */ st %o1,[%o3]
-/* 0x0b34 */ add %o3,4,%o3
-/* 0x0b38 */ srax %o0,32,%o5
-/* 0x0b3c */ ble,a,pt %icc,.L900000647
-/* 0x0b40 */ ld [%o3],%o0
- .L77000224:
-/* 0x0b44 */ ret ! Result =
-/* 0x0b48 */ restore %g0,%g0,%g0
-/* 0x0b4c 0 */ .type mont_mulf_noconv,2
-/* 0x0b4c */ .size mont_mulf_noconv,(.-mont_mulf_noconv)
-
diff --git a/security/nss/lib/freebl/mpi/montmulfv9.il b/security/nss/lib/freebl/mpi/montmulfv9.il
deleted file mode 100644
index 33999d566..000000000
--- a/security/nss/lib/freebl/mpi/montmulfv9.il
+++ /dev/null
@@ -1,94 +0,0 @@
-!
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-! $Id$
-
-!
-! double upper32(double /*frs1*/);
-!
- .inline upper32,8
- fdtox %f0,%f10
- fitod %f10,%f0
- .end
-
-!
-! double lower32(double /*frs1*/, double /* Zero */);
-!
- .inline lower32,8
- fdtox %f0,%f10
- fmovs %f2,%f10
- fxtod %f10,%f0
- .end
-
-!
-! double mod(double /*x*/, double /*1/m*/, double /*m*/);
-!
- .inline mod,12
- fmuld %f0,%f2,%f2
- fdtox %f2,%f2
- fxtod %f2,%f2
- fmuld %f2,%f4,%f2
- fsubd %f0,%f2,%f0
- .end
-
-
-!
-! void i16_to_d16_and_d32x4(double * /*1/(2^16)*/, double * /* 2^16*/,
-! double * /* 0 */,
-! double * /*result16*/, double * /* result32 */
-! float * /*source - should be unsigned int*
-! converted to float* */);
-!
- .inline i16_to_d16_and_d32x4,24
- ldd [%o0],%f2 ! 1/(2^16)
- ldd [%o1],%f4 ! 2^16
- ldd [%o2],%f22
-
- fmovd %f22,%f6
- ld [%o5],%f7
- fmovd %f22,%f10
- ld [%o5+4],%f11
- fmovd %f22,%f14
- ld [%o5+8],%f15
- fmovd %f22,%f18
- ld [%o5+12],%f19
- fxtod %f6,%f6
- std %f6,[%o4]
- fxtod %f10,%f10
- std %f10,[%o4+8]
- fxtod %f14,%f14
- std %f14,[%o4+16]
- fxtod %f18,%f18
- std %f18,[%o4+24]
- fmuld %f2,%f6,%f8
- fmuld %f2,%f10,%f12
- fmuld %f2,%f14,%f16
- fmuld %f2,%f18,%f20
- fdtox %f8,%f8
- fdtox %f12,%f12
- fdtox %f16,%f16
- fdtox %f20,%f20
- fxtod %f8,%f8
- std %f8,[%o3+8]
- fxtod %f12,%f12
- std %f12,[%o3+24]
- fxtod %f16,%f16
- std %f16,[%o3+40]
- fxtod %f20,%f20
- std %f20,[%o3+56]
- fmuld %f8,%f4,%f8
- fmuld %f12,%f4,%f12
- fmuld %f16,%f4,%f16
- fmuld %f20,%f4,%f20
- fsubd %f6,%f8,%f8
- std %f8,[%o3]
- fsubd %f10,%f12,%f12
- std %f12,[%o3+16]
- fsubd %f14,%f16,%f16
- std %f16,[%o3+32]
- fsubd %f18,%f20,%f20
- std %f20,[%o3+48]
- .end
-
-
diff --git a/security/nss/lib/freebl/mpi/montmulfv9.s b/security/nss/lib/freebl/mpi/montmulfv9.s
deleted file mode 100644
index c8640922a..000000000
--- a/security/nss/lib/freebl/mpi/montmulfv9.s
+++ /dev/null
@@ -1,2348 +0,0 @@
-!
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
- .section ".text",#alloc,#execinstr
- .file "montmulf.c"
-
- .section ".rodata",#alloc
- .global TwoTo16
- .align 8
-!
-! CONSTANT POOL
-!
- .global TwoTo16
-TwoTo16:
- .word 1089470464
- .word 0
- .type TwoTo16,#object
- .size TwoTo16,8
- .global TwoToMinus16
-!
-! CONSTANT POOL
-!
- .global TwoToMinus16
-TwoToMinus16:
- .word 1055916032
- .word 0
- .type TwoToMinus16,#object
- .size TwoToMinus16,8
- .global Zero
-!
-! CONSTANT POOL
-!
- .global Zero
-Zero:
- .word 0
- .word 0
- .type Zero,#object
- .size Zero,8
- .global TwoTo32
-!
-! CONSTANT POOL
-!
- .global TwoTo32
-TwoTo32:
- .word 1106247680
- .word 0
- .type TwoTo32,#object
- .size TwoTo32,8
- .global TwoToMinus32
-!
-! CONSTANT POOL
-!
- .global TwoToMinus32
-TwoToMinus32:
- .word 1039138816
- .word 0
- .type TwoToMinus32,#object
- .size TwoToMinus32,8
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .register %g3,#scratch
-/* 000000 */ .register %g2,#scratch
-/* 000000 0 */ .align 8
-!
-! SUBROUTINE conv_d16_to_i32
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global conv_d16_to_i32
- conv_d16_to_i32:
-/* 000000 */ save %sp,-208,%sp
-! FILE montmulf.c
-
-! 1 !/*
-! 2 ! * The contents of this file are subject to the Mozilla Public
-! 3 ! * License Version 1.1 (the "License"); you may not use this file
-! 4 ! * except in compliance with the License. You may obtain a copy of
-! 5 ! * the License at http://www.mozilla.org/MPL/
-! 6 ! *
-! 7 ! * Software distributed under the License is distributed on an "AS
-! 8 ! * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-! 9 ! * implied. See the License for the specific language governing
-! 10 ! * rights and limitations under the License.
-! 11 ! *
-! 12 ! * The Original Code is SPARC optimized Montgomery multiply functions.
-! 13 ! *
-! 14 ! * The Initial Developer of the Original Code is Sun Microsystems Inc.
-! 15 ! * Portions created by Sun Microsystems Inc. are
-! 16 ! * Copyright (C) 1999-2000 Sun Microsystems Inc. All Rights Reserved.
-! 17 ! *
-! 18 ! * Contributor(s):
-! 19 ! * Netscape Communications Corporation
-! 20 ! *
-! 21 ! * Alternatively, the contents of this file may be used under the
-! 22 ! * terms of the GNU General Public License Version 2 or later (the
-! 23 ! * "GPL"), in which case the provisions of the GPL are applicable
-! 24 ! * instead of those above. If you wish to allow use of your
-! 25 ! * version of this file only under the terms of the GPL and not to
-! 26 ! * allow others to use your version of this file under the MPL,
-! 27 ! * indicate your decision by deleting the provisions above and
-! 28 ! * replace them with the notice and other provisions required by
-! 29 ! * the GPL. If you do not delete the provisions above, a recipient
-! 30 ! * may use your version of this file under either the MPL or the
-! 31 ! * GPL.
-! 32 ! *
-! 33 ! * $Id$
-! 34 ! */
-! 36 !#define RF_INLINE_MACROS
-! 38 !static const double TwoTo16=65536.0;
-! 39 !static const double TwoToMinus16=1.0/65536.0;
-! 40 !static const double Zero=0.0;
-! 41 !static const double TwoTo32=65536.0*65536.0;
-! 42 !static const double TwoToMinus32=1.0/(65536.0*65536.0);
-! 44 !#ifdef RF_INLINE_MACROS
-! 46 !double upper32(double);
-! 47 !double lower32(double, double);
-! 48 !double mod(double, double, double);
-! 50 !void i16_to_d16_and_d32x4(const double * /*1/(2^16)*/,
-! 51 ! const double * /* 2^16*/,
-! 52 ! const double * /* 0 */,
-! 53 ! double * /*result16*/,
-! 54 ! double * /* result32 */,
-! 55 ! float * /*source - should be unsigned int*
-! 56 ! converted to float* */);
-! 58 !#else
-! 60 !static double upper32(double x)
-! 61 !{
-! 62 ! return floor(x*TwoToMinus32);
-! 63 !}
-! 65 !static double lower32(double x, double y)
-! 66 !{
-! 67 ! return x-TwoTo32*floor(x*TwoToMinus32);
-! 68 !}
-! 70 !static double mod(double x, double oneoverm, double m)
-! 71 !{
-! 72 ! return x-m*floor(x*oneoverm);
-! 73 !}
-! 75 !#endif
-! 78 !static void cleanup(double *dt, int from, int tlen)
-! 79 !{
-! 80 ! int i;
-! 81 ! double tmp,tmp1,x,x1;
-! 83 ! tmp=tmp1=Zero;
-! 84 ! /* original code **
-! 85 ! for(i=2*from;i<2*tlen-2;i++)
-! 86 ! {
-! 87 ! x=dt[i];
-! 88 ! dt[i]=lower32(x,Zero)+tmp1;
-! 89 ! tmp1=tmp;
-! 90 ! tmp=upper32(x);
-! 91 ! }
-! 92 ! dt[tlen-2]+=tmp1;
-! 93 ! dt[tlen-1]+=tmp;
-! 94 ! **end original code ***/
-! 95 ! /* new code ***/
-! 96 ! for(i=2*from;i<2*tlen;i+=2)
-! 97 ! {
-! 98 ! x=dt[i];
-! 99 ! x1=dt[i+1];
-! 100 ! dt[i]=lower32(x,Zero)+tmp;
-! 101 ! dt[i+1]=lower32(x1,Zero)+tmp1;
-! 102 ! tmp=upper32(x);
-! 103 ! tmp1=upper32(x1);
-! 104 ! }
-! 105 ! /** end new code **/
-! 106 !}
-! 109 !void conv_d16_to_i32(unsigned int *i32, double *d16, long long *tmp, int ilen)
-! 110 !{
-! 111 !int i;
-! 112 !long long t, t1, a, b, c, d;
-! 114 ! t1=0;
-! 115 ! a=(long long)d16[0];
-
-/* 0x0004 115 */ ldd [%i1],%f2
-
-! 116 ! b=(long long)d16[1];
-! 117 ! for(i=0; i<ilen-1; i++)
-
-/* 0x0008 117 */ sub %i3,1,%o1
-/* 0x000c 110 */ or %g0,%i0,%g1
-/* 0x0010 116 */ ldd [%i1+8],%f4
-/* 0x0014 117 */ cmp %o1,0
-/* 0x0018 114 */ or %g0,0,%g5
-/* 0x001c 115 */ fdtox %f2,%f2
-/* 0x0020 */ std %f2,[%sp+2247]
-/* 0x0024 117 */ or %g0,0,%o0
-/* 0x0028 116 */ fdtox %f4,%f2
-/* 0x002c */ std %f2,[%sp+2239]
-/* 0x0030 110 */ sub %o1,1,%o7
-/* 0x0034 */ or %g0,%i1,%o4
-/* 0x0038 */ sethi %hi(0xfc00),%o3
-/* 0x003c */ or %g0,-1,%o1
-/* 0x0040 */ or %g0,2,%i1
-/* 0x0044 */ srl %o1,0,%g3
-/* 0x0048 */ or %g0,%o4,%g4
-/* 0x004c 116 */ ldx [%sp+2239],%i2
-/* 0x0050 */ add %o3,1023,%o5
-/* 0x0054 117 */ sub %o7,1,%o2
-/* 0x0058 115 */ ldx [%sp+2247],%i3
-/* 0x005c 117 */ ble,pt %icc,.L900000113
-/* 0x0060 */ sethi %hi(0xfc00),%g2
-/* 0x0064 */ add %o7,1,%g2
-
-! 118 ! {
-! 119 ! c=(long long)d16[2*i+2];
-! 120 ! t1+=a&0xffffffff;
-! 121 ! t=(a>>32);
-! 122 ! d=(long long)d16[2*i+3];
-! 123 ! t1+=(b&0xffff)<<16;
-
-/* 0x0068 123 */ and %i2,%o5,%i4
-/* 0x006c */ sllx %i4,16,%o1
-/* 0x0070 117 */ cmp %g2,6
-/* 0x0074 */ bl,pn %icc,.L77000134
-/* 0x0078 */ or %g0,3,%i0
-/* 0x007c 119 */ ldd [%o4+16],%f0
-/* 0x0080 120 */ and %i3,%g3,%o3
-
-! 124 ! t+=(b>>16)+(t1>>32);
-
-/* 0x0084 124 */ srax %i2,16,%i5
-/* 0x0088 117 */ add %o3,%o1,%i4
-/* 0x008c 121 */ srax %i3,32,%i3
-/* 0x0090 119 */ fdtox %f0,%f0
-/* 0x0094 */ std %f0,[%sp+2231]
-
-! 125 ! i32[i]=t1&0xffffffff;
-
-/* 0x0098 125 */ and %i4,%g3,%l0
-/* 0x009c 117 */ or %g0,72,%o3
-/* 0x00a0 122 */ ldd [%g4+24],%f0
-/* 0x00a4 117 */ or %g0,64,%o4
-/* 0x00a8 */ or %g0,4,%o1
-
-! 126 ! t1=t;
-! 127 ! a=c;
-! 128 ! b=d;
-
-/* 0x00ac 128 */ or %g0,5,%i0
-/* 0x00b0 */ or %g0,4,%i1
-/* 0x00b4 119 */ ldx [%sp+2231],%g2
-/* 0x00b8 122 */ fdtox %f0,%f0
-/* 0x00bc 128 */ or %g0,4,%o0
-/* 0x00c0 122 */ std %f0,[%sp+2223]
-/* 0x00c4 */ ldd [%g4+40],%f2
-/* 0x00c8 120 */ and %g2,%g3,%i2
-/* 0x00cc 119 */ ldd [%g4+32],%f0
-/* 0x00d0 121 */ srax %g2,32,%g2
-/* 0x00d4 122 */ ldd [%g4+56],%f4
-/* 0x00d8 */ fdtox %f2,%f2
-/* 0x00dc */ ldx [%sp+2223],%g5
-/* 0x00e0 119 */ fdtox %f0,%f0
-/* 0x00e4 125 */ st %l0,[%g1]
-/* 0x00e8 124 */ srax %i4,32,%l0
-/* 0x00ec 122 */ fdtox %f4,%f4
-/* 0x00f0 */ std %f2,[%sp+2223]
-/* 0x00f4 123 */ and %g5,%o5,%i4
-/* 0x00f8 124 */ add %i5,%l0,%i5
-/* 0x00fc 119 */ std %f0,[%sp+2231]
-/* 0x0100 123 */ sllx %i4,16,%i4
-/* 0x0104 124 */ add %i3,%i5,%i3
-/* 0x0108 119 */ ldd [%g4+48],%f2
-/* 0x010c 124 */ srax %g5,16,%g5
-/* 0x0110 117 */ add %i2,%i4,%i2
-/* 0x0114 122 */ ldd [%g4+72],%f0
-/* 0x0118 117 */ add %i2,%i3,%i4
-/* 0x011c 124 */ srax %i4,32,%i5
-/* 0x0120 119 */ fdtox %f2,%f2
-/* 0x0124 125 */ and %i4,%g3,%i4
-/* 0x0128 122 */ ldx [%sp+2223],%i2
-/* 0x012c 124 */ add %g5,%i5,%g5
-/* 0x0130 119 */ ldx [%sp+2231],%i3
-/* 0x0134 124 */ add %g2,%g5,%g5
-/* 0x0138 119 */ std %f2,[%sp+2231]
-/* 0x013c 122 */ std %f4,[%sp+2223]
-/* 0x0140 119 */ ldd [%g4+64],%f2
-/* 0x0144 125 */ st %i4,[%g1+4]
- .L900000108:
-/* 0x0148 122 */ ldx [%sp+2223],%i4
-/* 0x014c 128 */ add %o0,2,%o0
-/* 0x0150 */ add %i0,4,%i0
-/* 0x0154 119 */ ldx [%sp+2231],%l0
-/* 0x0158 117 */ add %o3,16,%o3
-/* 0x015c 123 */ and %i2,%o5,%g2
-/* 0x0160 */ sllx %g2,16,%i5
-/* 0x0164 120 */ and %i3,%g3,%g2
-/* 0x0168 122 */ ldd [%g4+%o3],%f4
-/* 0x016c */ fdtox %f0,%f0
-/* 0x0170 */ std %f0,[%sp+2223]
-/* 0x0174 124 */ srax %i2,16,%i2
-/* 0x0178 117 */ add %g2,%i5,%g2
-/* 0x017c 119 */ fdtox %f2,%f0
-/* 0x0180 117 */ add %o4,16,%o4
-/* 0x0184 119 */ std %f0,[%sp+2231]
-/* 0x0188 117 */ add %g2,%g5,%g2
-/* 0x018c 119 */ ldd [%g4+%o4],%f2
-/* 0x0190 124 */ srax %g2,32,%i5
-/* 0x0194 128 */ cmp %o0,%o2
-/* 0x0198 121 */ srax %i3,32,%g5
-/* 0x019c 124 */ add %i2,%i5,%i2
-/* 0x01a0 */ add %g5,%i2,%i5
-/* 0x01a4 117 */ add %o1,4,%o1
-/* 0x01a8 125 */ and %g2,%g3,%g2
-/* 0x01ac 127 */ or %g0,%l0,%g5
-/* 0x01b0 125 */ st %g2,[%g1+%o1]
-/* 0x01b4 128 */ add %i1,4,%i1
-/* 0x01b8 122 */ ldx [%sp+2223],%i2
-/* 0x01bc 119 */ ldx [%sp+2231],%i3
-/* 0x01c0 117 */ add %o3,16,%o3
-/* 0x01c4 123 */ and %i4,%o5,%g2
-/* 0x01c8 */ sllx %g2,16,%l0
-/* 0x01cc 120 */ and %g5,%g3,%g2
-/* 0x01d0 122 */ ldd [%g4+%o3],%f0
-/* 0x01d4 */ fdtox %f4,%f4
-/* 0x01d8 */ std %f4,[%sp+2223]
-/* 0x01dc 124 */ srax %i4,16,%i4
-/* 0x01e0 117 */ add %g2,%l0,%g2
-/* 0x01e4 119 */ fdtox %f2,%f2
-/* 0x01e8 117 */ add %o4,16,%o4
-/* 0x01ec 119 */ std %f2,[%sp+2231]
-/* 0x01f0 117 */ add %g2,%i5,%g2
-/* 0x01f4 119 */ ldd [%g4+%o4],%f2
-/* 0x01f8 124 */ srax %g2,32,%i5
-/* 0x01fc 121 */ srax %g5,32,%g5
-/* 0x0200 124 */ add %i4,%i5,%i4
-/* 0x0204 */ add %g5,%i4,%g5
-/* 0x0208 117 */ add %o1,4,%o1
-/* 0x020c 125 */ and %g2,%g3,%g2
-/* 0x0210 128 */ ble,pt %icc,.L900000108
-/* 0x0214 */ st %g2,[%g1+%o1]
- .L900000111:
-/* 0x0218 122 */ ldx [%sp+2223],%o2
-/* 0x021c 123 */ and %i2,%o5,%i4
-/* 0x0220 120 */ and %i3,%g3,%g2
-/* 0x0224 123 */ sllx %i4,16,%i4
-/* 0x0228 119 */ ldx [%sp+2231],%i5
-/* 0x022c 128 */ cmp %o0,%o7
-/* 0x0230 124 */ srax %i2,16,%i2
-/* 0x0234 117 */ add %g2,%i4,%g2
-/* 0x0238 122 */ fdtox %f0,%f4
-/* 0x023c */ std %f4,[%sp+2223]
-/* 0x0240 117 */ add %g2,%g5,%g5
-/* 0x0244 123 */ and %o2,%o5,%l0
-/* 0x0248 124 */ srax %g5,32,%l1
-/* 0x024c 120 */ and %i5,%g3,%i4
-/* 0x0250 119 */ fdtox %f2,%f0
-/* 0x0254 121 */ srax %i3,32,%g2
-/* 0x0258 119 */ std %f0,[%sp+2231]
-/* 0x025c 124 */ add %i2,%l1,%i2
-/* 0x0260 123 */ sllx %l0,16,%i3
-/* 0x0264 124 */ add %g2,%i2,%i2
-/* 0x0268 */ srax %o2,16,%o2
-/* 0x026c 117 */ add %o1,4,%g2
-/* 0x0270 */ add %i4,%i3,%o1
-/* 0x0274 125 */ and %g5,%g3,%g5
-/* 0x0278 */ st %g5,[%g1+%g2]
-/* 0x027c 119 */ ldx [%sp+2231],%i3
-/* 0x0280 117 */ add %o1,%i2,%o1
-/* 0x0284 */ add %g2,4,%g2
-/* 0x0288 124 */ srax %o1,32,%i4
-/* 0x028c 122 */ ldx [%sp+2223],%i2
-/* 0x0290 125 */ and %o1,%g3,%g5
-/* 0x0294 121 */ srax %i5,32,%o1
-/* 0x0298 124 */ add %o2,%i4,%o2
-/* 0x029c 125 */ st %g5,[%g1+%g2]
-/* 0x02a0 128 */ bg,pn %icc,.L77000127
-/* 0x02a4 */ add %o1,%o2,%g5
-/* 0x02a8 */ add %i0,6,%i0
-/* 0x02ac */ add %i1,6,%i1
- .L77000134:
-/* 0x02b0 119 */ sra %i1,0,%o2
- .L900000112:
-/* 0x02b4 119 */ sllx %o2,3,%o3
-/* 0x02b8 120 */ and %i3,%g3,%o1
-/* 0x02bc 119 */ ldd [%g4+%o3],%f0
-/* 0x02c0 122 */ sra %i0,0,%o3
-/* 0x02c4 123 */ and %i2,%o5,%o2
-/* 0x02c8 122 */ sllx %o3,3,%o3
-/* 0x02cc 120 */ add %g5,%o1,%o1
-/* 0x02d0 119 */ fdtox %f0,%f0
-/* 0x02d4 */ std %f0,[%sp+2231]
-/* 0x02d8 123 */ sllx %o2,16,%o2
-/* 0x02dc */ add %o1,%o2,%o2
-/* 0x02e0 128 */ add %i1,2,%i1
-/* 0x02e4 122 */ ldd [%g4+%o3],%f0
-/* 0x02e8 124 */ srax %o2,32,%g2
-/* 0x02ec 125 */ and %o2,%g3,%o3
-/* 0x02f0 124 */ srax %i2,16,%o1
-/* 0x02f4 128 */ add %i0,2,%i0
-/* 0x02f8 122 */ fdtox %f0,%f0
-/* 0x02fc */ std %f0,[%sp+2223]
-/* 0x0300 125 */ sra %o0,0,%o2
-/* 0x0304 */ sllx %o2,2,%o2
-/* 0x0308 124 */ add %o1,%g2,%g5
-/* 0x030c 121 */ srax %i3,32,%g2
-/* 0x0310 128 */ add %o0,1,%o0
-/* 0x0314 124 */ add %g2,%g5,%g5
-/* 0x0318 128 */ cmp %o0,%o7
-/* 0x031c 119 */ ldx [%sp+2231],%o4
-/* 0x0320 122 */ ldx [%sp+2223],%i2
-/* 0x0324 125 */ st %o3,[%g1+%o2]
-/* 0x0328 127 */ or %g0,%o4,%i3
-/* 0x032c 128 */ ble,pt %icc,.L900000112
-/* 0x0330 */ sra %i1,0,%o2
- .L77000127:
-
-! 129 ! }
-! 130 ! t1+=a&0xffffffff;
-! 131 ! t=(a>>32);
-! 132 ! t1+=(b&0xffff)<<16;
-! 133 ! i32[i]=t1&0xffffffff;
-
-/* 0x0334 133 */ sethi %hi(0xfc00),%g2
- .L900000113:
-/* 0x0338 133 */ or %g0,-1,%g3
-/* 0x033c */ add %g2,1023,%g2
-/* 0x0340 */ srl %g3,0,%g3
-/* 0x0344 */ and %i2,%g2,%g2
-/* 0x0348 */ and %i3,%g3,%g4
-/* 0x034c */ sllx %g2,16,%g2
-/* 0x0350 */ add %g5,%g4,%g4
-/* 0x0354 */ sra %o0,0,%g5
-/* 0x0358 */ add %g4,%g2,%g4
-/* 0x035c */ sllx %g5,2,%g2
-/* 0x0360 */ and %g4,%g3,%g3
-/* 0x0364 */ st %g3,[%g1+%g2]
-/* 0x0368 */ ret ! Result =
-/* 0x036c */ restore %g0,%g0,%g0
-/* 0x0370 0 */ .type conv_d16_to_i32,2
-/* 0x0370 */ .size conv_d16_to_i32,(.-conv_d16_to_i32)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 8
-!
-! CONSTANT POOL
-!
- .L_const_seg_900000201:
-/* 000000 0 */ .word 1127219200,0
-/* 0x0008 0 */ .align 8
-/* 0x0008 */ .skip 24
-!
-! SUBROUTINE conv_i32_to_d32
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global conv_i32_to_d32
- conv_i32_to_d32:
-/* 000000 */ or %g0,%o7,%g3
-
-! 135 !}
-! 137 !void conv_i32_to_d32(double *d32, unsigned int *i32, int len)
-! 138 !{
-! 139 !int i;
-! 141 !#pragma pipeloop(0)
-! 142 ! for(i=0;i<len;i++) d32[i]=(double)(i32[i]);
-
-/* 0x0004 142 */ cmp %o2,0
- .L900000210:
-/* 0x0008 */ call .+8
-/* 0x000c */ sethi /*X*/%hi(_GLOBAL_OFFSET_TABLE_-(.L900000210-.)),%g4
-/* 0x0010 142 */ or %g0,0,%o3
-/* 0x0014 138 */ add %g4,/*X*/%lo(_GLOBAL_OFFSET_TABLE_-(.L900000210-.)),%g4
-/* 0x0018 142 */ sub %o2,1,%o4
-/* 0x001c 138 */ add %g4,%o7,%g1
-/* 0x0020 142 */ ble,pt %icc,.L77000140
-/* 0x0024 */ or %g0,%g3,%o7
-/* 0x0028 */ sethi %hi(.L_const_seg_900000201),%g3
-/* 0x002c */ cmp %o2,12
-/* 0x0030 */ add %g3,%lo(.L_const_seg_900000201),%g2
-/* 0x0034 */ or %g0,%o1,%g5
-/* 0x0038 */ ldx [%g1+%g2],%g4
-/* 0x003c */ or %g0,0,%g1
-/* 0x0040 */ or %g0,24,%g2
-/* 0x0044 */ bl,pn %icc,.L77000144
-/* 0x0048 */ or %g0,0,%g3
-/* 0x004c */ ld [%o1],%f13
-/* 0x0050 */ or %g0,7,%o3
-/* 0x0054 */ ldd [%g4],%f8
-/* 0x0058 */ sub %o2,5,%g3
-/* 0x005c */ or %g0,8,%g1
-/* 0x0060 */ ld [%o1+4],%f11
-/* 0x0064 */ ld [%o1+8],%f7
-/* 0x0068 */ fmovs %f8,%f12
-/* 0x006c */ ld [%o1+12],%f5
-/* 0x0070 */ fmovs %f8,%f10
-/* 0x0074 */ ld [%o1+16],%f3
-/* 0x0078 */ fmovs %f8,%f6
-/* 0x007c */ ld [%o1+20],%f1
-/* 0x0080 */ fsubd %f12,%f8,%f12
-/* 0x0084 */ std %f12,[%o0]
-/* 0x0088 */ fsubd %f10,%f8,%f10
-/* 0x008c */ std %f10,[%o0+8]
- .L900000205:
-/* 0x0090 */ ld [%o1+%g2],%f11
-/* 0x0094 */ add %g1,8,%g1
-/* 0x0098 */ add %o3,5,%o3
-/* 0x009c */ fsubd %f6,%f8,%f6
-/* 0x00a0 */ add %g2,4,%g2
-/* 0x00a4 */ std %f6,[%o0+%g1]
-/* 0x00a8 */ cmp %o3,%g3
-/* 0x00ac */ fmovs %f8,%f4
-/* 0x00b0 */ ld [%o1+%g2],%f7
-/* 0x00b4 */ fsubd %f4,%f8,%f12
-/* 0x00b8 */ add %g1,8,%g1
-/* 0x00bc */ add %g2,4,%g2
-/* 0x00c0 */ fmovs %f8,%f2
-/* 0x00c4 */ std %f12,[%o0+%g1]
-/* 0x00c8 */ ld [%o1+%g2],%f5
-/* 0x00cc */ fsubd %f2,%f8,%f12
-/* 0x00d0 */ add %g1,8,%g1
-/* 0x00d4 */ add %g2,4,%g2
-/* 0x00d8 */ fmovs %f8,%f0
-/* 0x00dc */ std %f12,[%o0+%g1]
-/* 0x00e0 */ ld [%o1+%g2],%f3
-/* 0x00e4 */ fsubd %f0,%f8,%f12
-/* 0x00e8 */ add %g1,8,%g1
-/* 0x00ec */ add %g2,4,%g2
-/* 0x00f0 */ fmovs %f8,%f10
-/* 0x00f4 */ std %f12,[%o0+%g1]
-/* 0x00f8 */ ld [%o1+%g2],%f1
-/* 0x00fc */ fsubd %f10,%f8,%f10
-/* 0x0100 */ add %g1,8,%g1
-/* 0x0104 */ add %g2,4,%g2
-/* 0x0108 */ std %f10,[%o0+%g1]
-/* 0x010c */ ble,pt %icc,.L900000205
-/* 0x0110 */ fmovs %f8,%f6
- .L900000208:
-/* 0x0114 */ fmovs %f8,%f4
-/* 0x0118 */ ld [%o1+%g2],%f11
-/* 0x011c */ add %g1,8,%g3
-/* 0x0120 */ fmovs %f8,%f2
-/* 0x0124 */ add %g1,16,%g1
-/* 0x0128 */ cmp %o3,%o4
-/* 0x012c */ fmovs %f8,%f0
-/* 0x0130 */ add %g1,8,%o1
-/* 0x0134 */ add %g1,16,%o2
-/* 0x0138 */ fmovs %f8,%f10
-/* 0x013c */ add %g1,24,%g2
-/* 0x0140 */ fsubd %f6,%f8,%f6
-/* 0x0144 */ std %f6,[%o0+%g3]
-/* 0x0148 */ fsubd %f4,%f8,%f4
-/* 0x014c */ std %f4,[%o0+%g1]
-/* 0x0150 */ sra %o3,0,%g1
-/* 0x0154 */ fsubd %f2,%f8,%f2
-/* 0x0158 */ std %f2,[%o0+%o1]
-/* 0x015c */ sllx %g1,2,%g3
-/* 0x0160 */ fsubd %f0,%f8,%f0
-/* 0x0164 */ std %f0,[%o0+%o2]
-/* 0x0168 */ fsubd %f10,%f8,%f0
-/* 0x016c */ bg,pn %icc,.L77000140
-/* 0x0170 */ std %f0,[%o0+%g2]
- .L77000144:
-/* 0x0174 */ ldd [%g4],%f8
- .L900000211:
-/* 0x0178 */ ld [%g5+%g3],%f13
-/* 0x017c */ sllx %g1,3,%g2
-/* 0x0180 */ add %o3,1,%o3
-/* 0x0184 */ sra %o3,0,%g1
-/* 0x0188 */ cmp %o3,%o4
-/* 0x018c */ fmovs %f8,%f12
-/* 0x0190 */ sllx %g1,2,%g3
-/* 0x0194 */ fsubd %f12,%f8,%f0
-/* 0x0198 */ std %f0,[%o0+%g2]
-/* 0x019c */ ble,a,pt %icc,.L900000211
-/* 0x01a0 */ ldd [%g4],%f8
- .L77000140:
-/* 0x01a4 */ retl ! Result =
-/* 0x01a8 */ nop
-/* 0x01ac 0 */ .type conv_i32_to_d32,2
-/* 0x01ac */ .size conv_i32_to_d32,(.-conv_i32_to_d32)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 8
-!
-! CONSTANT POOL
-!
- .L_const_seg_900000301:
-/* 000000 0 */ .word 1127219200,0
-/* 0x0008 0 */ .align 8
-/* 0x0008 */ .skip 24
-!
-! SUBROUTINE conv_i32_to_d16
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global conv_i32_to_d16
- conv_i32_to_d16:
-/* 000000 */ save %sp,-192,%sp
- .L900000310:
-/* 0x0004 */ call .+8
-/* 0x0008 */ sethi /*X*/%hi(_GLOBAL_OFFSET_TABLE_-(.L900000310-.)),%g3
-
-! 143 !}
-! 146 !void conv_i32_to_d16(double *d16, unsigned int *i32, int len)
-! 147 !{
-! 148 !int i;
-! 149 !unsigned int a;
-! 151 !#pragma pipeloop(0)
-! 152 ! for(i=0;i<len;i++)
-
-/* 0x000c 152 */ cmp %i2,0
-/* 0x0010 147 */ add %g3,/*X*/%lo(_GLOBAL_OFFSET_TABLE_-(.L900000310-.)),%g3
-/* 0x0014 152 */ ble,pt %icc,.L77000150
-/* 0x0018 */ add %g3,%o7,%o0
-
-! 153 ! {
-! 154 ! a=i32[i];
-! 155 ! d16[2*i]=(double)(a&0xffff);
-! 156 ! d16[2*i+1]=(double)(a>>16);
-
-/* 0x001c 156 */ sethi %hi(.L_const_seg_900000301),%g2
-/* 0x0020 147 */ or %g0,%i2,%o1
-/* 0x0024 152 */ sethi %hi(0xfc00),%g3
-/* 0x0028 156 */ add %g2,%lo(.L_const_seg_900000301),%g2
-/* 0x002c 152 */ or %g0,%o1,%g4
-/* 0x0030 156 */ ldx [%o0+%g2],%o5
-/* 0x0034 152 */ add %g3,1023,%g1
-/* 0x0038 147 */ or %g0,%i1,%o7
-/* 0x003c 152 */ or %g0,0,%i2
-/* 0x0040 */ sub %o1,1,%g5
-/* 0x0044 */ or %g0,0,%g3
-/* 0x0048 */ or %g0,1,%g2
-/* 0x004c 154 */ or %g0,0,%o2
-/* 0x0050 */ cmp %g4,6
-/* 0x0054 152 */ bl,pn %icc,.L77000154
-/* 0x0058 */ ldd [%o5],%f0
-/* 0x005c */ sub %o1,2,%o3
-/* 0x0060 */ or %g0,16,%o2
-/* 0x0064 154 */ ld [%i1],%o4
-/* 0x0068 156 */ or %g0,3,%g2
-/* 0x006c */ or %g0,2,%g3
-/* 0x0070 155 */ fmovs %f0,%f2
-/* 0x0074 156 */ or %g0,4,%i2
-/* 0x0078 155 */ and %o4,%g1,%o0
-/* 0x007c */ st %o0,[%sp+2227]
-/* 0x0080 */ fmovs %f0,%f4
-/* 0x0084 156 */ srl %o4,16,%i4
-/* 0x0088 152 */ or %g0,12,%o4
-/* 0x008c */ or %g0,24,%o0
-/* 0x0090 155 */ ld [%sp+2227],%f3
-/* 0x0094 */ fsubd %f2,%f0,%f2
-/* 0x0098 */ std %f2,[%i0]
-/* 0x009c 156 */ st %i4,[%sp+2223]
-/* 0x00a0 154 */ ld [%o7+4],%o1
-/* 0x00a4 156 */ fmovs %f0,%f2
-/* 0x00a8 155 */ and %o1,%g1,%i1
-/* 0x00ac 156 */ ld [%sp+2223],%f3
-/* 0x00b0 */ srl %o1,16,%o1
-/* 0x00b4 */ fsubd %f2,%f0,%f2
-/* 0x00b8 */ std %f2,[%i0+8]
-/* 0x00bc */ st %o1,[%sp+2223]
-/* 0x00c0 155 */ st %i1,[%sp+2227]
-/* 0x00c4 154 */ ld [%o7+8],%o1
-/* 0x00c8 156 */ fmovs %f0,%f2
-/* 0x00cc 155 */ and %o1,%g1,%g4
-/* 0x00d0 */ ld [%sp+2227],%f5
-/* 0x00d4 156 */ srl %o1,16,%o1
-/* 0x00d8 */ ld [%sp+2223],%f3
-/* 0x00dc */ st %o1,[%sp+2223]
-/* 0x00e0 155 */ fsubd %f4,%f0,%f4
-/* 0x00e4 */ st %g4,[%sp+2227]
-/* 0x00e8 156 */ fsubd %f2,%f0,%f2
-/* 0x00ec 154 */ ld [%o7+12],%o1
-/* 0x00f0 155 */ std %f4,[%i0+16]
-/* 0x00f4 156 */ std %f2,[%i0+24]
- .L900000306:
-/* 0x00f8 155 */ ld [%sp+2227],%f5
-/* 0x00fc 156 */ add %i2,2,%i2
-/* 0x0100 */ add %g2,4,%g2
-/* 0x0104 */ ld [%sp+2223],%f3
-/* 0x0108 */ cmp %i2,%o3
-/* 0x010c */ add %g3,4,%g3
-/* 0x0110 155 */ and %o1,%g1,%g4
-/* 0x0114 156 */ srl %o1,16,%o1
-/* 0x0118 155 */ st %g4,[%sp+2227]
-/* 0x011c 156 */ st %o1,[%sp+2223]
-/* 0x0120 152 */ add %o4,4,%o1
-/* 0x0124 154 */ ld [%o7+%o1],%o4
-/* 0x0128 156 */ fmovs %f0,%f2
-/* 0x012c 155 */ fmovs %f0,%f4
-/* 0x0130 */ fsubd %f4,%f0,%f4
-/* 0x0134 152 */ add %o2,16,%o2
-/* 0x0138 156 */ fsubd %f2,%f0,%f2
-/* 0x013c 155 */ std %f4,[%i0+%o2]
-/* 0x0140 152 */ add %o0,16,%o0
-/* 0x0144 156 */ std %f2,[%i0+%o0]
-/* 0x0148 155 */ ld [%sp+2227],%f5
-/* 0x014c 156 */ ld [%sp+2223],%f3
-/* 0x0150 155 */ and %o4,%g1,%g4
-/* 0x0154 156 */ srl %o4,16,%o4
-/* 0x0158 155 */ st %g4,[%sp+2227]
-/* 0x015c 156 */ st %o4,[%sp+2223]
-/* 0x0160 152 */ add %o1,4,%o4
-/* 0x0164 154 */ ld [%o7+%o4],%o1
-/* 0x0168 156 */ fmovs %f0,%f2
-/* 0x016c 155 */ fmovs %f0,%f4
-/* 0x0170 */ fsubd %f4,%f0,%f4
-/* 0x0174 152 */ add %o2,16,%o2
-/* 0x0178 156 */ fsubd %f2,%f0,%f2
-/* 0x017c 155 */ std %f4,[%i0+%o2]
-/* 0x0180 152 */ add %o0,16,%o0
-/* 0x0184 156 */ ble,pt %icc,.L900000306
-/* 0x0188 */ std %f2,[%i0+%o0]
- .L900000309:
-/* 0x018c 155 */ ld [%sp+2227],%f5
-/* 0x0190 156 */ fmovs %f0,%f2
-/* 0x0194 */ srl %o1,16,%o3
-/* 0x0198 */ ld [%sp+2223],%f3
-/* 0x019c 155 */ and %o1,%g1,%i1
-/* 0x01a0 152 */ add %o2,16,%g4
-/* 0x01a4 155 */ fmovs %f0,%f4
-/* 0x01a8 */ st %i1,[%sp+2227]
-/* 0x01ac 152 */ add %o0,16,%o2
-/* 0x01b0 156 */ st %o3,[%sp+2223]
-/* 0x01b4 154 */ sra %i2,0,%o3
-/* 0x01b8 152 */ add %g4,16,%o1
-/* 0x01bc 155 */ fsubd %f4,%f0,%f4
-/* 0x01c0 */ std %f4,[%i0+%g4]
-/* 0x01c4 152 */ add %o0,32,%o0
-/* 0x01c8 156 */ fsubd %f2,%f0,%f2
-/* 0x01cc */ std %f2,[%i0+%o2]
-/* 0x01d0 */ sllx %o3,2,%o2
-/* 0x01d4 155 */ ld [%sp+2227],%f5
-/* 0x01d8 156 */ cmp %i2,%g5
-/* 0x01dc */ add %g2,6,%g2
-/* 0x01e0 */ ld [%sp+2223],%f3
-/* 0x01e4 */ add %g3,6,%g3
-/* 0x01e8 155 */ fmovs %f0,%f4
-/* 0x01ec 156 */ fmovs %f0,%f2
-/* 0x01f0 155 */ fsubd %f4,%f0,%f4
-/* 0x01f4 */ std %f4,[%i0+%o1]
-/* 0x01f8 156 */ fsubd %f2,%f0,%f0
-/* 0x01fc */ bg,pn %icc,.L77000150
-/* 0x0200 */ std %f0,[%i0+%o0]
- .L77000154:
-/* 0x0204 155 */ ldd [%o5],%f0
- .L900000311:
-/* 0x0208 154 */ ld [%o7+%o2],%o0
-/* 0x020c 155 */ sra %g3,0,%o1
-/* 0x0210 */ fmovs %f0,%f2
-/* 0x0214 */ sllx %o1,3,%o2
-/* 0x0218 156 */ add %i2,1,%i2
-/* 0x021c 155 */ and %o0,%g1,%o1
-/* 0x0220 */ st %o1,[%sp+2227]
-/* 0x0224 156 */ add %g3,2,%g3
-/* 0x0228 */ srl %o0,16,%o1
-/* 0x022c */ cmp %i2,%g5
-/* 0x0230 */ sra %g2,0,%o0
-/* 0x0234 */ add %g2,2,%g2
-/* 0x0238 */ sllx %o0,3,%o0
-/* 0x023c 155 */ ld [%sp+2227],%f3
-/* 0x0240 154 */ sra %i2,0,%o3
-/* 0x0244 155 */ fsubd %f2,%f0,%f2
-/* 0x0248 */ std %f2,[%i0+%o2]
-/* 0x024c */ sllx %o3,2,%o2
-/* 0x0250 156 */ st %o1,[%sp+2223]
-/* 0x0254 */ fmovs %f0,%f2
-/* 0x0258 */ ld [%sp+2223],%f3
-/* 0x025c */ fsubd %f2,%f0,%f0
-/* 0x0260 */ std %f0,[%i0+%o0]
-/* 0x0264 */ ble,a,pt %icc,.L900000311
-/* 0x0268 */ ldd [%o5],%f0
- .L77000150:
-/* 0x026c */ ret ! Result =
-/* 0x0270 */ restore %g0,%g0,%g0
-/* 0x0274 0 */ .type conv_i32_to_d16,2
-/* 0x0274 */ .size conv_i32_to_d16,(.-conv_i32_to_d16)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 8
-!
-! CONSTANT POOL
-!
- .L_const_seg_900000401:
-/* 000000 0 */ .word 1127219200,0
-/* 0x0008 0 */ .align 8
-/* 0x0008 */ .skip 24
-!
-! SUBROUTINE conv_i32_to_d32_and_d16
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global conv_i32_to_d32_and_d16
- conv_i32_to_d32_and_d16:
-/* 000000 */ save %sp,-192,%sp
- .L900000415:
-/* 0x0004 */ call .+8
-/* 0x0008 */ sethi /*X*/%hi(_GLOBAL_OFFSET_TABLE_-(.L900000415-.)),%g3
-
-! 157 ! }
-! 158 !}
-! 161 !void conv_i32_to_d32_and_d16(double *d32, double *d16,
-! 162 ! unsigned int *i32, int len)
-! 163 !{
-! 164 !int i = 0;
-! 165 !unsigned int a;
-! 167 !#pragma pipeloop(0)
-! 168 !#ifdef RF_INLINE_MACROS
-! 169 ! for(;i<len-3;i+=4)
-! 170 ! {
-! 171 ! i16_to_d16_and_d32x4(&TwoToMinus16, &TwoTo16, &Zero,
-! 172 ! &(d16[2*i]), &(d32[i]), (float *)(&(i32[i])));
-
-/* 0x000c 172 */ sethi %hi(Zero),%g2
-/* 0x0010 163 */ add %g3,/*X*/%lo(_GLOBAL_OFFSET_TABLE_-(.L900000415-.)),%g3
-/* 0x0014 */ or %g0,%i3,%g5
-/* 0x0018 */ add %g3,%o7,%o3
-/* 0x001c 172 */ add %g2,%lo(Zero),%g2
-/* 0x0020 */ ldx [%o3+%g2],%o0
-/* 0x0024 */ sethi %hi(TwoToMinus16),%g3
-/* 0x0028 163 */ or %g0,%i0,%i3
-/* 0x002c 169 */ sub %g5,3,%o1
-/* 0x0030 172 */ sethi %hi(TwoTo16),%g4
-/* 0x0034 163 */ or %g0,%i2,%i0
-/* 0x0038 172 */ add %g3,%lo(TwoToMinus16),%g2
-/* 0x003c */ ldx [%o3+%g2],%o2
-/* 0x0040 169 */ cmp %o1,0
-/* 0x0044 164 */ or %g0,0,%i2
-/* 0x0048 169 */ ble,pt %icc,.L900000418
-/* 0x004c */ cmp %i2,%g5
-/* 0x0050 */ ldd [%o0],%f2
-/* 0x0054 172 */ add %g4,%lo(TwoTo16),%g3
-/* 0x0058 */ ldx [%o3+%g3],%o1
-/* 0x005c 169 */ sub %g5,4,%o4
-/* 0x0060 */ or %g0,0,%o5
- .L900000417:
-/* 0x0064 172 */ sra %i2,0,%g2
-/* 0x0068 */ fmovd %f2,%f14
-/* 0x006c */ ldd [%o2],%f0
-/* 0x0070 */ sllx %g2,2,%g3
-/* 0x0074 */ fmovd %f2,%f10
-/* 0x0078 */ ldd [%o1],%f16
-/* 0x007c */ ld [%g3+%i0],%f15
-/* 0x0080 */ add %i0,%g3,%g3
-/* 0x0084 */ fmovd %f2,%f6
-/* 0x0088 */ ld [%g3+4],%f11
-/* 0x008c */ sra %o5,0,%g4
-/* 0x0090 */ add %i2,4,%i2
-/* 0x0094 */ ld [%g3+8],%f7
-/* 0x0098 */ fxtod %f14,%f14
-/* 0x009c */ sllx %g2,3,%g2
-/* 0x00a0 */ ld [%g3+12],%f3
-/* 0x00a4 */ fxtod %f10,%f10
-/* 0x00a8 */ sllx %g4,3,%g3
-/* 0x00ac */ fxtod %f6,%f6
-/* 0x00b0 */ std %f14,[%g2+%i3]
-/* 0x00b4 */ add %i3,%g2,%g4
-/* 0x00b8 */ fxtod %f2,%f2
-/* 0x00bc */ fmuld %f0,%f14,%f12
-/* 0x00c0 */ std %f2,[%g4+24]
-/* 0x00c4 */ fmuld %f0,%f10,%f8
-/* 0x00c8 */ std %f10,[%g4+8]
-/* 0x00cc */ add %i1,%g3,%g2
-/* 0x00d0 */ fmuld %f0,%f6,%f4
-/* 0x00d4 */ std %f6,[%g4+16]
-/* 0x00d8 */ cmp %i2,%o4
-/* 0x00dc */ fmuld %f0,%f2,%f0
-/* 0x00e0 */ fdtox %f12,%f12
-/* 0x00e4 */ add %o5,8,%o5
-/* 0x00e8 */ fdtox %f8,%f8
-/* 0x00ec */ fdtox %f4,%f4
-/* 0x00f0 */ fdtox %f0,%f0
-/* 0x00f4 */ fxtod %f12,%f12
-/* 0x00f8 */ std %f12,[%g2+8]
-/* 0x00fc */ fxtod %f8,%f8
-/* 0x0100 */ std %f8,[%g2+24]
-/* 0x0104 */ fxtod %f4,%f4
-/* 0x0108 */ std %f4,[%g2+40]
-/* 0x010c */ fxtod %f0,%f0
-/* 0x0110 */ std %f0,[%g2+56]
-/* 0x0114 */ fmuld %f12,%f16,%f12
-/* 0x0118 */ fmuld %f8,%f16,%f8
-/* 0x011c */ fmuld %f4,%f16,%f4
-/* 0x0120 */ fsubd %f14,%f12,%f12
-/* 0x0124 */ std %f12,[%g3+%i1]
-/* 0x0128 */ fmuld %f0,%f16,%f0
-/* 0x012c */ fsubd %f10,%f8,%f8
-/* 0x0130 */ std %f8,[%g2+16]
-/* 0x0134 */ fsubd %f6,%f4,%f4
-/* 0x0138 */ std %f4,[%g2+32]
-/* 0x013c */ fsubd %f2,%f0,%f0
-/* 0x0140 */ std %f0,[%g2+48]
-/* 0x0144 */ ble,a,pt %icc,.L900000417
-/* 0x0148 */ ldd [%o0],%f2
- .L77000159:
-
-! 173 ! }
-! 174 !#endif
-! 175 ! for(;i<len;i++)
-
-/* 0x014c 175 */ cmp %i2,%g5
- .L900000418:
-/* 0x0150 175 */ bge,pt %icc,.L77000164
-/* 0x0154 */ nop
-
-! 176 ! {
-! 177 ! a=i32[i];
-! 178 ! d32[i]=(double)(i32[i]);
-! 179 ! d16[2*i]=(double)(a&0xffff);
-! 180 ! d16[2*i+1]=(double)(a>>16);
-
-/* 0x0158 180 */ sethi %hi(.L_const_seg_900000401),%g2
-/* 0x015c */ add %g2,%lo(.L_const_seg_900000401),%g2
-/* 0x0160 175 */ sethi %hi(0xfc00),%g3
-/* 0x0164 180 */ ldx [%o3+%g2],%g1
-/* 0x0168 175 */ sll %i2,1,%i4
-/* 0x016c */ sub %g5,%i2,%g4
-/* 0x0170 177 */ sra %i2,0,%o3
-/* 0x0174 175 */ add %g3,1023,%g3
-/* 0x0178 178 */ ldd [%g1],%f2
-/* 0x017c */ sllx %o3,2,%o2
-/* 0x0180 175 */ add %i4,1,%g2
-/* 0x0184 177 */ or %g0,%o3,%o1
-/* 0x0188 */ cmp %g4,6
-/* 0x018c 175 */ bl,pn %icc,.L77000161
-/* 0x0190 */ sra %i2,0,%o3
-/* 0x0194 177 */ or %g0,%o2,%o0
-/* 0x0198 178 */ ld [%i0+%o2],%f5
-/* 0x019c 179 */ fmovs %f2,%f8
-/* 0x01a0 175 */ add %o0,4,%o3
-/* 0x01a4 177 */ ld [%i0+%o0],%o7
-/* 0x01a8 180 */ fmovs %f2,%f6
-/* 0x01ac 178 */ fmovs %f2,%f4
-/* 0x01b0 */ sllx %o1,3,%o2
-/* 0x01b4 175 */ add %o3,4,%o5
-/* 0x01b8 179 */ sra %i4,0,%o0
-/* 0x01bc 175 */ add %o3,8,%o4
-/* 0x01c0 178 */ fsubd %f4,%f2,%f4
-/* 0x01c4 */ std %f4,[%i3+%o2]
-/* 0x01c8 179 */ sllx %o0,3,%i5
-/* 0x01cc */ and %o7,%g3,%o0
-/* 0x01d0 */ st %o0,[%sp+2227]
-/* 0x01d4 175 */ add %i5,16,%o1
-/* 0x01d8 180 */ srl %o7,16,%g4
-/* 0x01dc */ add %i2,1,%i2
-/* 0x01e0 */ sra %g2,0,%o0
-/* 0x01e4 175 */ add %o2,8,%o2
-/* 0x01e8 179 */ fmovs %f2,%f4
-/* 0x01ec 180 */ sllx %o0,3,%l0
-/* 0x01f0 */ add %i4,3,%g2
-/* 0x01f4 179 */ ld [%sp+2227],%f5
-/* 0x01f8 175 */ add %l0,16,%o0
-/* 0x01fc 180 */ add %i4,2,%i4
-/* 0x0200 175 */ sub %g5,1,%o7
-/* 0x0204 180 */ add %i2,3,%i2
-/* 0x0208 179 */ fsubd %f4,%f2,%f4
-/* 0x020c */ std %f4,[%i1+%i5]
-/* 0x0210 180 */ st %g4,[%sp+2223]
-/* 0x0214 177 */ ld [%i0+%o3],%i5
-/* 0x0218 180 */ fmovs %f2,%f4
-/* 0x021c */ srl %i5,16,%g4
-/* 0x0220 179 */ and %i5,%g3,%i5
-/* 0x0224 180 */ ld [%sp+2223],%f5
-/* 0x0228 */ fsubd %f4,%f2,%f4
-/* 0x022c */ std %f4,[%i1+%l0]
-/* 0x0230 */ st %g4,[%sp+2223]
-/* 0x0234 177 */ ld [%i0+%o5],%g4
-/* 0x0238 179 */ st %i5,[%sp+2227]
-/* 0x023c 178 */ fmovs %f2,%f4
-/* 0x0240 180 */ srl %g4,16,%i5
-/* 0x0244 179 */ and %g4,%g3,%g4
-/* 0x0248 180 */ ld [%sp+2223],%f7
-/* 0x024c */ st %i5,[%sp+2223]
-/* 0x0250 178 */ ld [%i0+%o3],%f5
-/* 0x0254 180 */ fsubd %f6,%f2,%f6
-/* 0x0258 177 */ ld [%i0+%o4],%o3
-/* 0x025c 178 */ fsubd %f4,%f2,%f4
-/* 0x0260 179 */ ld [%sp+2227],%f9
-/* 0x0264 180 */ ld [%sp+2223],%f1
-/* 0x0268 179 */ st %g4,[%sp+2227]
-/* 0x026c */ fsubd %f8,%f2,%f8
-/* 0x0270 */ std %f8,[%i1+%o1]
-/* 0x0274 180 */ std %f6,[%i1+%o0]
-/* 0x0278 178 */ std %f4,[%i3+%o2]
- .L900000411:
-/* 0x027c 179 */ ld [%sp+2227],%f13
-/* 0x0280 180 */ srl %o3,16,%g4
-/* 0x0284 */ add %i2,2,%i2
-/* 0x0288 */ st %g4,[%sp+2223]
-/* 0x028c */ cmp %i2,%o7
-/* 0x0290 */ add %g2,4,%g2
-/* 0x0294 178 */ ld [%i0+%o5],%f11
-/* 0x0298 180 */ add %i4,4,%i4
-/* 0x029c 175 */ add %o4,4,%o5
-/* 0x02a0 177 */ ld [%i0+%o5],%g4
-/* 0x02a4 179 */ and %o3,%g3,%o3
-/* 0x02a8 */ st %o3,[%sp+2227]
-/* 0x02ac 180 */ fmovs %f2,%f0
-/* 0x02b0 179 */ fmovs %f2,%f12
-/* 0x02b4 180 */ fsubd %f0,%f2,%f8
-/* 0x02b8 179 */ fsubd %f12,%f2,%f4
-/* 0x02bc 175 */ add %o1,16,%o1
-/* 0x02c0 180 */ ld [%sp+2223],%f7
-/* 0x02c4 178 */ fmovs %f2,%f10
-/* 0x02c8 179 */ std %f4,[%i1+%o1]
-/* 0x02cc 175 */ add %o0,16,%o0
-/* 0x02d0 178 */ fsubd %f10,%f2,%f4
-/* 0x02d4 175 */ add %o2,8,%o2
-/* 0x02d8 180 */ std %f8,[%i1+%o0]
-/* 0x02dc 178 */ std %f4,[%i3+%o2]
-/* 0x02e0 179 */ ld [%sp+2227],%f9
-/* 0x02e4 180 */ srl %g4,16,%o3
-/* 0x02e8 */ st %o3,[%sp+2223]
-/* 0x02ec 178 */ ld [%i0+%o4],%f5
-/* 0x02f0 175 */ add %o4,8,%o4
-/* 0x02f4 177 */ ld [%i0+%o4],%o3
-/* 0x02f8 179 */ and %g4,%g3,%g4
-/* 0x02fc */ st %g4,[%sp+2227]
-/* 0x0300 180 */ fmovs %f2,%f6
-/* 0x0304 179 */ fmovs %f2,%f8
-/* 0x0308 180 */ fsubd %f6,%f2,%f6
-/* 0x030c 179 */ fsubd %f8,%f2,%f8
-/* 0x0310 175 */ add %o1,16,%o1
-/* 0x0314 180 */ ld [%sp+2223],%f1
-/* 0x0318 178 */ fmovs %f2,%f4
-/* 0x031c 179 */ std %f8,[%i1+%o1]
-/* 0x0320 175 */ add %o0,16,%o0
-/* 0x0324 178 */ fsubd %f4,%f2,%f4
-/* 0x0328 175 */ add %o2,8,%o2
-/* 0x032c 180 */ std %f6,[%i1+%o0]
-/* 0x0330 */ bl,pt %icc,.L900000411
-/* 0x0334 */ std %f4,[%i3+%o2]
- .L900000414:
-/* 0x0338 180 */ srl %o3,16,%o7
-/* 0x033c */ st %o7,[%sp+2223]
-/* 0x0340 179 */ fmovs %f2,%f12
-/* 0x0344 178 */ ld [%i0+%o5],%f11
-/* 0x0348 180 */ fmovs %f2,%f0
-/* 0x034c 179 */ and %o3,%g3,%g4
-/* 0x0350 180 */ fmovs %f2,%f6
-/* 0x0354 175 */ add %o1,16,%o3
-/* 0x0358 */ add %o0,16,%o7
-/* 0x035c 178 */ fmovs %f2,%f10
-/* 0x0360 175 */ add %o2,8,%o2
-/* 0x0364 */ add %o1,32,%o5
-/* 0x0368 179 */ ld [%sp+2227],%f13
-/* 0x036c 178 */ fmovs %f2,%f4
-/* 0x0370 175 */ add %o0,32,%o1
-/* 0x0374 180 */ ld [%sp+2223],%f7
-/* 0x0378 175 */ add %o2,8,%o0
-/* 0x037c 180 */ cmp %i2,%g5
-/* 0x0380 179 */ st %g4,[%sp+2227]
-/* 0x0384 */ fsubd %f12,%f2,%f8
-/* 0x0388 180 */ add %g2,6,%g2
-/* 0x038c 179 */ std %f8,[%i1+%o3]
-/* 0x0390 180 */ fsubd %f0,%f2,%f0
-/* 0x0394 177 */ sra %i2,0,%o3
-/* 0x0398 180 */ std %f0,[%i1+%o7]
-/* 0x039c 178 */ fsubd %f10,%f2,%f0
-/* 0x03a0 180 */ add %i4,6,%i4
-/* 0x03a4 178 */ std %f0,[%i3+%o2]
-/* 0x03a8 */ sllx %o3,2,%o2
-/* 0x03ac 179 */ ld [%sp+2227],%f9
-/* 0x03b0 178 */ ld [%i0+%o4],%f5
-/* 0x03b4 179 */ fmovs %f2,%f8
-/* 0x03b8 */ fsubd %f8,%f2,%f0
-/* 0x03bc */ std %f0,[%i1+%o5]
-/* 0x03c0 180 */ fsubd %f6,%f2,%f0
-/* 0x03c4 */ std %f0,[%i1+%o1]
-/* 0x03c8 178 */ fsubd %f4,%f2,%f0
-/* 0x03cc 180 */ bge,pn %icc,.L77000164
-/* 0x03d0 */ std %f0,[%i3+%o0]
- .L77000161:
-/* 0x03d4 178 */ ldd [%g1],%f2
- .L900000416:
-/* 0x03d8 178 */ ld [%i0+%o2],%f5
-/* 0x03dc 179 */ sra %i4,0,%o0
-/* 0x03e0 180 */ add %i2,1,%i2
-/* 0x03e4 177 */ ld [%i0+%o2],%o1
-/* 0x03e8 178 */ sllx %o3,3,%o3
-/* 0x03ec 180 */ add %i4,2,%i4
-/* 0x03f0 178 */ fmovs %f2,%f4
-/* 0x03f4 179 */ sllx %o0,3,%o4
-/* 0x03f8 180 */ cmp %i2,%g5
-/* 0x03fc 179 */ and %o1,%g3,%o0
-/* 0x0400 178 */ fsubd %f4,%f2,%f0
-/* 0x0404 */ std %f0,[%i3+%o3]
-/* 0x0408 180 */ srl %o1,16,%o1
-/* 0x040c 179 */ st %o0,[%sp+2227]
-/* 0x0410 180 */ sra %g2,0,%o0
-/* 0x0414 */ add %g2,2,%g2
-/* 0x0418 177 */ sra %i2,0,%o3
-/* 0x041c 180 */ sllx %o0,3,%o0
-/* 0x0420 179 */ fmovs %f2,%f4
-/* 0x0424 */ sllx %o3,2,%o2
-/* 0x0428 */ ld [%sp+2227],%f5
-/* 0x042c */ fsubd %f4,%f2,%f0
-/* 0x0430 */ std %f0,[%i1+%o4]
-/* 0x0434 180 */ st %o1,[%sp+2223]
-/* 0x0438 */ fmovs %f2,%f4
-/* 0x043c */ ld [%sp+2223],%f5
-/* 0x0440 */ fsubd %f4,%f2,%f0
-/* 0x0444 */ std %f0,[%i1+%o0]
-/* 0x0448 */ bl,a,pt %icc,.L900000416
-/* 0x044c */ ldd [%g1],%f2
- .L77000164:
-/* 0x0450 */ ret ! Result =
-/* 0x0454 */ restore %g0,%g0,%g0
-/* 0x0458 0 */ .type conv_i32_to_d32_and_d16,2
-/* 0x0458 */ .size conv_i32_to_d32_and_d16,(.-conv_i32_to_d32_and_d16)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 8
-!
-! SUBROUTINE adjust_montf_result
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global adjust_montf_result
- adjust_montf_result:
-/* 000000 */ save %sp,-176,%sp
-/* 0x0004 */ or %g0,%i2,%o1
-/* 0x0008 */ or %g0,%i0,%i2
-
-! 181 ! }
-! 182 !}
-! 185 !void adjust_montf_result(unsigned int *i32, unsigned int *nint, int len)
-! 186 !{
-! 187 !long long acc;
-! 188 !int i;
-! 190 ! if(i32[len]>0) i=-1;
-
-/* 0x000c 190 */ sra %o1,0,%g2
-/* 0x0010 */ or %g0,-1,%o2
-/* 0x0014 */ sllx %g2,2,%g2
-/* 0x0018 */ ld [%i2+%g2],%g2
-/* 0x001c */ cmp %g2,0
-/* 0x0020 */ bleu,pn %icc,.L77000175
-/* 0x0024 */ or %g0,%i1,%i0
-/* 0x0028 */ ba .L900000511
-/* 0x002c */ cmp %o2,0
- .L77000175:
-
-! 191 ! else
-! 192 ! {
-! 193 ! for(i=len-1; i>=0; i--)
-
-/* 0x0030 193 */ sub %o1,1,%o2
-/* 0x0034 */ cmp %o2,0
-/* 0x0038 */ bl,pn %icc,.L77000182
-/* 0x003c */ sra %o2,0,%g2
- .L900000510:
-
-! 194 ! {
-! 195 ! if(i32[i]!=nint[i]) break;
-
-/* 0x0040 195 */ sllx %g2,2,%g2
-/* 0x0044 */ sub %o2,1,%o0
-/* 0x0048 */ ld [%i1+%g2],%g3
-/* 0x004c */ ld [%i2+%g2],%g2
-/* 0x0050 */ cmp %g2,%g3
-/* 0x0054 */ bne,pn %icc,.L77000182
-/* 0x0058 */ nop
-/* 0x005c 0 */ or %g0,%o0,%o2
-/* 0x0060 195 */ cmp %o0,0
-/* 0x0064 */ bge,pt %icc,.L900000510
-/* 0x0068 */ sra %o2,0,%g2
- .L77000182:
-
-! 196 ! }
-! 197 ! }
-! 198 ! if((i<0)||(i32[i]>nint[i]))
-
-/* 0x006c 198 */ cmp %o2,0
- .L900000511:
-/* 0x0070 198 */ bl,pn %icc,.L77000198
-/* 0x0074 */ sra %o2,0,%g2
-/* 0x0078 */ sllx %g2,2,%g2
-/* 0x007c */ ld [%i1+%g2],%g3
-/* 0x0080 */ ld [%i2+%g2],%g2
-/* 0x0084 */ cmp %g2,%g3
-/* 0x0088 */ bleu,pt %icc,.L77000191
-/* 0x008c */ nop
- .L77000198:
-
-! 199 ! {
-! 200 ! acc=0;
-! 201 ! for(i=0;i<len;i++)
-
-/* 0x0090 201 */ cmp %o1,0
-/* 0x0094 */ ble,pt %icc,.L77000191
-/* 0x0098 */ nop
-/* 0x009c 198 */ or %g0,-1,%g2
-/* 0x00a0 201 */ or %g0,%o1,%g3
-/* 0x00a4 198 */ srl %g2,0,%g2
-/* 0x00a8 */ sub %o1,1,%g4
-/* 0x00ac */ cmp %o1,9
-/* 0x00b0 201 */ or %g0,0,%i1
-/* 0x00b4 200 */ or %g0,0,%g5
-
-! 202 ! {
-! 203 ! acc=acc+(unsigned long long)(i32[i])-(unsigned long long)(nint[i]);
-
-/* 0x00b8 203 */ or %g0,0,%o1
-/* 0x00bc 201 */ bl,pn %icc,.L77000199
-/* 0x00c0 */ sub %g3,4,%o7
-/* 0x00c4 203 */ ld [%i2],%o1
-
-! 204 ! i32[i]=acc&0xffffffff;
-! 205 ! acc=acc>>32;
-
-/* 0x00c8 205 */ or %g0,5,%i1
-/* 0x00cc 203 */ ld [%i0],%o2
-/* 0x00d0 201 */ or %g0,8,%o5
-/* 0x00d4 */ or %g0,12,%o4
-/* 0x00d8 203 */ ld [%i0+4],%o3
-/* 0x00dc 201 */ or %g0,16,%g1
-/* 0x00e0 203 */ ld [%i2+4],%o0
-/* 0x00e4 201 */ sub %o1,%o2,%o1
-/* 0x00e8 203 */ ld [%i0+8],%i3
-/* 0x00ec 204 */ and %o1,%g2,%g5
-/* 0x00f0 */ st %g5,[%i2]
-/* 0x00f4 205 */ srax %o1,32,%g5
-/* 0x00f8 201 */ sub %o0,%o3,%o0
-/* 0x00fc 203 */ ld [%i0+12],%o2
-/* 0x0100 201 */ add %o0,%g5,%o0
-/* 0x0104 204 */ and %o0,%g2,%g5
-/* 0x0108 */ st %g5,[%i2+4]
-/* 0x010c 205 */ srax %o0,32,%o0
-/* 0x0110 203 */ ld [%i2+8],%o1
-/* 0x0114 */ ld [%i2+12],%o3
-/* 0x0118 201 */ sub %o1,%i3,%o1
- .L900000505:
-/* 0x011c */ add %g1,4,%g3
-/* 0x0120 203 */ ld [%g1+%i2],%g5
-/* 0x0124 201 */ add %o1,%o0,%o0
-/* 0x0128 203 */ ld [%i0+%g1],%i3
-/* 0x012c 201 */ sub %o3,%o2,%o1
-/* 0x0130 204 */ and %o0,%g2,%o2
-/* 0x0134 */ st %o2,[%o5+%i2]
-/* 0x0138 205 */ srax %o0,32,%o2
-/* 0x013c */ add %i1,4,%i1
-/* 0x0140 201 */ add %g1,8,%o5
-/* 0x0144 203 */ ld [%g3+%i2],%o0
-/* 0x0148 201 */ add %o1,%o2,%o1
-/* 0x014c 203 */ ld [%i0+%g3],%o3
-/* 0x0150 201 */ sub %g5,%i3,%o2
-/* 0x0154 204 */ and %o1,%g2,%g5
-/* 0x0158 */ st %g5,[%o4+%i2]
-/* 0x015c 205 */ srax %o1,32,%g5
-/* 0x0160 */ cmp %i1,%o7
-/* 0x0164 201 */ add %g1,12,%o4
-/* 0x0168 203 */ ld [%o5+%i2],%o1
-/* 0x016c 201 */ add %o2,%g5,%o2
-/* 0x0170 203 */ ld [%i0+%o5],%i3
-/* 0x0174 201 */ sub %o0,%o3,%o0
-/* 0x0178 204 */ and %o2,%g2,%o3
-/* 0x017c */ st %o3,[%g1+%i2]
-/* 0x0180 205 */ srax %o2,32,%g5
-/* 0x0184 203 */ ld [%o4+%i2],%o3
-/* 0x0188 201 */ add %g1,16,%g1
-/* 0x018c */ add %o0,%g5,%o0
-/* 0x0190 203 */ ld [%i0+%o4],%o2
-/* 0x0194 201 */ sub %o1,%i3,%o1
-/* 0x0198 204 */ and %o0,%g2,%g5
-/* 0x019c */ st %g5,[%g3+%i2]
-/* 0x01a0 205 */ ble,pt %icc,.L900000505
-/* 0x01a4 */ srax %o0,32,%o0
- .L900000508:
-/* 0x01a8 */ add %o1,%o0,%g3
-/* 0x01ac */ sub %o3,%o2,%o1
-/* 0x01b0 203 */ ld [%g1+%i2],%o0
-/* 0x01b4 */ ld [%i0+%g1],%o2
-/* 0x01b8 205 */ srax %g3,32,%o7
-/* 0x01bc 204 */ and %g3,%g2,%o3
-/* 0x01c0 201 */ add %o1,%o7,%o1
-/* 0x01c4 204 */ st %o3,[%o5+%i2]
-/* 0x01c8 205 */ cmp %i1,%g4
-/* 0x01cc 201 */ sub %o0,%o2,%o0
-/* 0x01d0 204 */ and %o1,%g2,%o2
-/* 0x01d4 */ st %o2,[%o4+%i2]
-/* 0x01d8 205 */ srax %o1,32,%o1
-/* 0x01dc 203 */ sra %i1,0,%o2
-/* 0x01e0 201 */ add %o0,%o1,%o0
-/* 0x01e4 205 */ srax %o0,32,%g5
-/* 0x01e8 204 */ and %o0,%g2,%o1
-/* 0x01ec */ st %o1,[%g1+%i2]
-/* 0x01f0 205 */ bg,pn %icc,.L77000191
-/* 0x01f4 */ sllx %o2,2,%o1
- .L77000199:
-/* 0x01f8 0 */ or %g0,%o1,%g1
- .L900000509:
-/* 0x01fc 203 */ ld [%o1+%i2],%o0
-/* 0x0200 205 */ add %i1,1,%i1
-/* 0x0204 203 */ ld [%i0+%o1],%o1
-/* 0x0208 */ sra %i1,0,%o2
-/* 0x020c 205 */ cmp %i1,%g4
-/* 0x0210 203 */ add %g5,%o0,%o0
-/* 0x0214 */ sub %o0,%o1,%o0
-/* 0x0218 205 */ srax %o0,32,%g5
-/* 0x021c 204 */ and %o0,%g2,%o1
-/* 0x0220 */ st %o1,[%g1+%i2]
-/* 0x0224 */ sllx %o2,2,%o1
-/* 0x0228 205 */ ble,pt %icc,.L900000509
-/* 0x022c */ or %g0,%o1,%g1
- .L77000191:
-/* 0x0230 */ ret ! Result =
-/* 0x0234 */ restore %g0,%g0,%g0
-/* 0x0238 0 */ .type adjust_montf_result,2
-/* 0x0238 */ .size adjust_montf_result,(.-adjust_montf_result)
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 */ .align 8
-/* 000000 */ .skip 24
-!
-! SUBROUTINE mont_mulf_noconv
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION
-
- .global mont_mulf_noconv
- mont_mulf_noconv:
-/* 000000 */ save %sp,-224,%sp
- .L900000643:
-/* 0x0004 */ call .+8
-/* 0x0008 */ sethi /*X*/%hi(_GLOBAL_OFFSET_TABLE_-(.L900000643-.)),%g5
-/* 0x000c */ ldx [%fp+2223],%l0
-
-! 206 ! }
-! 207 ! }
-! 208 !}
-! 213 !/*
-! 214 !** the lengths of the input arrays should be at least the following:
-! 215 !** result[nlen+1], dm1[nlen], dm2[2*nlen+1], dt[4*nlen+2], dn[nlen], nint[nlen]
-! 216 !** all of them should be different from one another
-! 217 !**
-! 218 !*/
-! 219 !void mont_mulf_noconv(unsigned int *result,
-! 220 ! double *dm1, double *dm2, double *dt,
-! 221 ! double *dn, unsigned int *nint,
-! 222 ! int nlen, double dn0)
-! 223 !{
-! 224 ! int i, j, jj;
-! 225 ! int tmp;
-! 226 ! double digit, m2j, nextm2j, a, b;
-! 227 ! double *dptmp, *pdm1, *pdm2, *pdn, *pdtj, pdn_0, pdm1_0;
-! 229 ! pdm1=&(dm1[0]);
-! 230 ! pdm2=&(dm2[0]);
-! 231 ! pdn=&(dn[0]);
-! 232 ! pdm2[2*nlen]=Zero;
-
-/* 0x0010 232 */ sethi %hi(Zero),%g2
-/* 0x0014 223 */ fmovd %f14,%f30
-/* 0x0018 */ add %g5,/*X*/%lo(_GLOBAL_OFFSET_TABLE_-(.L900000643-.)),%g5
-/* 0x001c 232 */ add %g2,%lo(Zero),%g2
-/* 0x0020 */ sll %l0,1,%o3
-/* 0x0024 223 */ add %g5,%o7,%o4
-/* 0x0028 232 */ sra %o3,0,%g5
-/* 0x002c */ ldx [%o4+%g2],%o7
-
-! 234 ! if (nlen!=16)
-! 235 ! {
-! 236 ! for(i=0;i<4*nlen+2;i++) dt[i]=Zero;
-! 238 ! a=dt[0]=pdm1[0]*pdm2[0];
-! 239 ! digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16);
-
-/* 0x0030 239 */ sethi %hi(TwoToMinus16),%g3
-/* 0x0034 */ sethi %hi(TwoTo16),%g4
-/* 0x0038 */ add %g3,%lo(TwoToMinus16),%g2
-/* 0x003c 232 */ ldd [%o7],%f0
-/* 0x0040 239 */ add %g4,%lo(TwoTo16),%g3
-/* 0x0044 223 */ or %g0,%i4,%o0
-/* 0x0048 232 */ sllx %g5,3,%g4
-/* 0x004c 239 */ ldx [%o4+%g2],%o5
-/* 0x0050 223 */ or %g0,%i5,%l3
-/* 0x0054 */ or %g0,%i0,%l2
-/* 0x0058 239 */ ldx [%o4+%g3],%o4
-/* 0x005c 234 */ cmp %l0,16
-/* 0x0060 232 */ std %f0,[%i2+%g4]
-/* 0x0064 234 */ be,pn %icc,.L77000279
-/* 0x0068 */ or %g0,%i3,%l4
-/* 0x006c 236 */ sll %l0,2,%g2
-/* 0x0070 223 */ or %g0,%o0,%i5
-/* 0x0074 236 */ add %g2,2,%o0
-/* 0x0078 223 */ or %g0,%i1,%i4
-/* 0x007c 236 */ cmp %o0,0
-/* 0x0080 223 */ or %g0,%i2,%l1
-/* 0x0084 236 */ ble,a,pt %icc,.L900000657
-/* 0x0088 */ ldd [%i1],%f6
-
-! 241 ! pdtj=&(dt[0]);
-! 242 ! for(j=jj=0;j<2*nlen;j++,jj++,pdtj++)
-! 243 ! {
-! 244 ! m2j=pdm2[j];
-! 245 ! a=pdtj[0]+pdn[0]*digit;
-! 246 ! b=pdtj[1]+pdm1[0]*pdm2[j+1]+a*TwoToMinus16;
-! 247 ! pdtj[1]=b;
-! 249 !#pragma pipeloop(0)
-! 250 ! for(i=1;i<nlen;i++)
-! 251 ! {
-! 252 ! pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit;
-! 253 ! }
-! 254 ! if((jj==30)) {cleanup(dt,j/2+1,2*nlen+1); jj=0;}
-! 255 !
-! 256 ! digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16);
-! 257 ! }
-! 258 ! }
-! 259 ! else
-! 260 ! {
-! 261 ! a=dt[0]=pdm1[0]*pdm2[0];
-! 263 ! dt[65]= dt[64]= dt[63]= dt[62]= dt[61]= dt[60]=
-! 264 ! dt[59]= dt[58]= dt[57]= dt[56]= dt[55]= dt[54]=
-! 265 ! dt[53]= dt[52]= dt[51]= dt[50]= dt[49]= dt[48]=
-! 266 ! dt[47]= dt[46]= dt[45]= dt[44]= dt[43]= dt[42]=
-! 267 ! dt[41]= dt[40]= dt[39]= dt[38]= dt[37]= dt[36]=
-! 268 ! dt[35]= dt[34]= dt[33]= dt[32]= dt[31]= dt[30]=
-! 269 ! dt[29]= dt[28]= dt[27]= dt[26]= dt[25]= dt[24]=
-! 270 ! dt[23]= dt[22]= dt[21]= dt[20]= dt[19]= dt[18]=
-! 271 ! dt[17]= dt[16]= dt[15]= dt[14]= dt[13]= dt[12]=
-! 272 ! dt[11]= dt[10]= dt[ 9]= dt[ 8]= dt[ 7]= dt[ 6]=
-! 273 ! dt[ 5]= dt[ 4]= dt[ 3]= dt[ 2]= dt[ 1]=Zero;
-! 275 ! pdn_0=pdn[0];
-! 276 ! pdm1_0=pdm1[0];
-! 278 ! digit=mod(lower32(a,Zero)*dn0,TwoToMinus16,TwoTo16);
-! 279 ! pdtj=&(dt[0]);
-! 281 ! for(j=0;j<32;j++,pdtj++)
-
-/* 0x008c 281 */ or %g0,%o0,%o1
-/* 0x0090 236 */ sub %o0,1,%g1
-/* 0x0094 */ or %g0,0,%g2
-/* 0x0098 281 */ cmp %o1,5
-/* 0x009c */ bl,pn %icc,.L77000280
-/* 0x00a0 */ or %g0,8,%o0
-/* 0x00a4 */ std %f0,[%i3]
-/* 0x00a8 */ or %g0,2,%g2
-/* 0x00ac */ sub %g1,2,%o1
- .L900000627:
-/* 0x00b0 */ add %o0,8,%g3
-/* 0x00b4 */ std %f0,[%i3+%o0]
-/* 0x00b8 */ add %g2,3,%g2
-/* 0x00bc */ add %o0,16,%o2
-/* 0x00c0 */ std %f0,[%i3+%g3]
-/* 0x00c4 */ cmp %g2,%o1
-/* 0x00c8 */ add %o0,24,%o0
-/* 0x00cc */ ble,pt %icc,.L900000627
-/* 0x00d0 */ std %f0,[%i3+%o2]
- .L900000630:
-/* 0x00d4 */ cmp %g2,%g1
-/* 0x00d8 */ bg,pn %icc,.L77000285
-/* 0x00dc */ std %f0,[%i3+%o0]
- .L77000280:
-/* 0x00e0 */ ldd [%o7],%f0
- .L900000656:
-/* 0x00e4 */ sra %g2,0,%o0
-/* 0x00e8 */ add %g2,1,%g2
-/* 0x00ec */ sllx %o0,3,%o0
-/* 0x00f0 */ cmp %g2,%g1
-/* 0x00f4 */ std %f0,[%i3+%o0]
-/* 0x00f8 */ ble,a,pt %icc,.L900000656
-/* 0x00fc */ ldd [%o7],%f0
- .L77000285:
-/* 0x0100 238 */ ldd [%i1],%f6
- .L900000657:
-/* 0x0104 238 */ ldd [%i2],%f8
-/* 0x0108 242 */ cmp %o3,0
-/* 0x010c */ sub %o3,1,%o1
-/* 0x0110 239 */ ldd [%o7],%f10
-/* 0x0114 */ add %o3,1,%o2
-/* 0x0118 0 */ or %g0,0,%i2
-/* 0x011c 238 */ fmuld %f6,%f8,%f6
-/* 0x0120 */ std %f6,[%i3]
-/* 0x0124 0 */ or %g0,0,%g3
-/* 0x0128 239 */ ldd [%o5],%f8
-/* 0x012c 0 */ or %g0,%o2,%g1
-/* 0x0130 236 */ sub %l0,1,%i1
-/* 0x0134 239 */ ldd [%o4],%f12
-/* 0x0138 236 */ or %g0,1,%g4
-/* 0x013c */ fdtox %f6,%f0
-/* 0x0140 */ fmovs %f10,%f0
-/* 0x0144 */ fxtod %f0,%f6
-/* 0x0148 239 */ fmuld %f6,%f14,%f6
-/* 0x014c */ fmuld %f6,%f8,%f8
-/* 0x0150 */ fdtox %f8,%f8
-/* 0x0154 */ fxtod %f8,%f8
-/* 0x0158 */ fmuld %f8,%f12,%f8
-/* 0x015c */ fsubd %f6,%f8,%f20
-/* 0x0160 242 */ ble,pt %icc,.L900000650
-/* 0x0164 */ sllx %g5,3,%g2
-/* 0x0168 0 */ st %o1,[%sp+2223]
-/* 0x016c 246 */ ldd [%i5],%f6
- .L900000651:
-/* 0x0170 246 */ sra %g4,0,%g2
-/* 0x0174 */ fmuld %f6,%f20,%f6
-/* 0x0178 */ ldd [%i3],%f12
-/* 0x017c */ sllx %g2,3,%g2
-/* 0x0180 */ ldd [%i4],%f8
-/* 0x0184 250 */ cmp %l0,1
-/* 0x0188 246 */ ldd [%l1+%g2],%f10
-/* 0x018c 244 */ sra %i2,0,%g2
-/* 0x0190 */ add %i2,1,%i0
-/* 0x0194 246 */ faddd %f12,%f6,%f6
-/* 0x0198 */ ldd [%o5],%f12
-/* 0x019c 244 */ sllx %g2,3,%g2
-/* 0x01a0 246 */ fmuld %f8,%f10,%f8
-/* 0x01a4 */ ldd [%i3+8],%f10
-/* 0x01a8 */ srl %i2,31,%o3
-/* 0x01ac 244 */ ldd [%l1+%g2],%f18
-/* 0x01b0 0 */ or %g0,1,%l5
-/* 0x01b4 236 */ or %g0,2,%g2
-/* 0x01b8 246 */ fmuld %f6,%f12,%f6
-/* 0x01bc 250 */ or %g0,32,%o1
-/* 0x01c0 */ or %g0,48,%o2
-/* 0x01c4 246 */ faddd %f10,%f8,%f8
-/* 0x01c8 */ faddd %f8,%f6,%f16
-/* 0x01cc 250 */ ble,pn %icc,.L77000213
-/* 0x01d0 */ std %f16,[%i3+8]
-/* 0x01d4 */ cmp %i1,8
-/* 0x01d8 */ sub %l0,3,%o3
-/* 0x01dc */ bl,pn %icc,.L77000284
-/* 0x01e0 */ or %g0,8,%o0
-/* 0x01e4 252 */ ldd [%i5+8],%f0
-/* 0x01e8 */ or %g0,6,%l5
-/* 0x01ec */ ldd [%i4+8],%f2
-/* 0x01f0 */ or %g0,4,%g2
-/* 0x01f4 250 */ or %g0,40,%o0
-/* 0x01f8 252 */ ldd [%i5+16],%f8
-/* 0x01fc */ fmuld %f0,%f20,%f10
-/* 0x0200 */ ldd [%i4+16],%f4
-/* 0x0204 */ fmuld %f2,%f18,%f2
-/* 0x0208 */ ldd [%i3+16],%f0
-/* 0x020c */ fmuld %f8,%f20,%f12
-/* 0x0210 */ ldd [%i4+24],%f6
-/* 0x0214 */ fmuld %f4,%f18,%f4
-/* 0x0218 */ ldd [%i5+24],%f8
-/* 0x021c */ faddd %f2,%f10,%f2
-/* 0x0220 */ ldd [%i4+32],%f14
-/* 0x0224 */ fmuld %f6,%f18,%f10
-/* 0x0228 */ ldd [%i5+32],%f6
-/* 0x022c */ faddd %f4,%f12,%f4
-/* 0x0230 */ ldd [%i4+40],%f12
-/* 0x0234 */ faddd %f0,%f2,%f0
-/* 0x0238 */ std %f0,[%i3+16]
-/* 0x023c */ ldd [%i3+32],%f0
-/* 0x0240 */ ldd [%i3+48],%f2
- .L900000639:
-/* 0x0244 */ add %o2,16,%l6
-/* 0x0248 252 */ ldd [%i5+%o0],%f22
-/* 0x024c */ add %l5,3,%l5
-/* 0x0250 */ fmuld %f8,%f20,%f8
-/* 0x0254 250 */ add %o0,8,%o0
-/* 0x0258 252 */ ldd [%l6+%i3],%f26
-/* 0x025c */ cmp %l5,%o3
-/* 0x0260 */ ldd [%i4+%o0],%f24
-/* 0x0264 */ faddd %f0,%f4,%f0
-/* 0x0268 */ add %g2,6,%g2
-/* 0x026c */ faddd %f10,%f8,%f10
-/* 0x0270 */ fmuld %f14,%f18,%f4
-/* 0x0274 */ std %f0,[%o1+%i3]
-/* 0x0278 250 */ add %o2,32,%o1
-/* 0x027c 252 */ ldd [%i5+%o0],%f8
-/* 0x0280 */ fmuld %f6,%f20,%f6
-/* 0x0284 250 */ add %o0,8,%o0
-/* 0x0288 252 */ ldd [%o1+%i3],%f0
-/* 0x028c */ ldd [%i4+%o0],%f14
-/* 0x0290 */ faddd %f2,%f10,%f2
-/* 0x0294 */ faddd %f4,%f6,%f10
-/* 0x0298 */ fmuld %f12,%f18,%f4
-/* 0x029c */ std %f2,[%o2+%i3]
-/* 0x02a0 250 */ add %o2,48,%o2
-/* 0x02a4 252 */ ldd [%i5+%o0],%f6
-/* 0x02a8 */ fmuld %f22,%f20,%f22
-/* 0x02ac 250 */ add %o0,8,%o0
-/* 0x02b0 252 */ ldd [%o2+%i3],%f2
-/* 0x02b4 */ ldd [%i4+%o0],%f12
-/* 0x02b8 */ faddd %f26,%f10,%f10
-/* 0x02bc */ std %f10,[%l6+%i3]
-/* 0x02c0 */ fmuld %f24,%f18,%f10
-/* 0x02c4 */ ble,pt %icc,.L900000639
-/* 0x02c8 */ faddd %f4,%f22,%f4
- .L900000642:
-/* 0x02cc 252 */ fmuld %f8,%f20,%f24
-/* 0x02d0 */ faddd %f0,%f4,%f8
-/* 0x02d4 250 */ add %o2,16,%o3
-/* 0x02d8 252 */ ldd [%o3+%i3],%f4
-/* 0x02dc */ fmuld %f14,%f18,%f0
-/* 0x02e0 */ cmp %l5,%i1
-/* 0x02e4 */ std %f8,[%o1+%i3]
-/* 0x02e8 */ fmuld %f12,%f18,%f8
-/* 0x02ec 250 */ add %o2,32,%o1
-/* 0x02f0 252 */ faddd %f10,%f24,%f12
-/* 0x02f4 */ ldd [%i5+%o0],%f22
-/* 0x02f8 */ fmuld %f6,%f20,%f6
-/* 0x02fc */ add %g2,8,%g2
-/* 0x0300 */ fmuld %f22,%f20,%f10
-/* 0x0304 */ faddd %f2,%f12,%f2
-/* 0x0308 */ faddd %f0,%f6,%f6
-/* 0x030c */ ldd [%o1+%i3],%f0
-/* 0x0310 */ std %f2,[%o2+%i3]
-/* 0x0314 */ faddd %f8,%f10,%f2
-/* 0x0318 */ sra %l5,0,%o2
-/* 0x031c */ sllx %o2,3,%o0
-/* 0x0320 */ faddd %f4,%f6,%f4
-/* 0x0324 */ std %f4,[%o3+%i3]
-/* 0x0328 */ faddd %f0,%f2,%f0
-/* 0x032c */ std %f0,[%o1+%i3]
-/* 0x0330 */ bg,a,pn %icc,.L77000213
-/* 0x0334 */ srl %i2,31,%o3
- .L77000284:
-/* 0x0338 252 */ ldd [%i4+%o0],%f2
- .L900000655:
-/* 0x033c 252 */ ldd [%i5+%o0],%f0
-/* 0x0340 */ fmuld %f2,%f18,%f2
-/* 0x0344 */ sra %g2,0,%o0
-/* 0x0348 */ sllx %o0,3,%o1
-/* 0x034c */ add %l5,1,%l5
-/* 0x0350 */ fmuld %f0,%f20,%f4
-/* 0x0354 */ ldd [%o1+%i3],%f0
-/* 0x0358 */ sra %l5,0,%o2
-/* 0x035c */ sllx %o2,3,%o0
-/* 0x0360 */ add %g2,2,%g2
-/* 0x0364 */ cmp %l5,%i1
-/* 0x0368 */ faddd %f2,%f4,%f2
-/* 0x036c */ faddd %f0,%f2,%f0
-/* 0x0370 */ std %f0,[%o1+%i3]
-/* 0x0374 */ ble,a,pt %icc,.L900000655
-/* 0x0378 */ ldd [%i4+%o0],%f2
- .L900000626:
-/* 0x037c */ srl %i2,31,%o3
-/* 0x0380 252 */ ba .L900000654
-/* 0x0384 */ cmp %g3,30
- .L77000213:
-/* 0x0388 254 */ cmp %g3,30
- .L900000654:
-/* 0x038c */ add %i2,%o3,%o0
-/* 0x0390 254 */ bne,a,pt %icc,.L900000653
-/* 0x0394 */ fdtox %f16,%f0
-/* 0x0398 281 */ sra %o0,1,%g2
-/* 0x039c */ add %g2,1,%g2
-/* 0x03a0 */ ldd [%o7],%f0
-/* 0x03a4 */ sll %g2,1,%o1
-/* 0x03a8 */ sll %g1,1,%g2
-/* 0x03ac */ or %g0,%o1,%o2
-/* 0x03b0 */ fmovd %f0,%f2
-/* 0x03b4 */ or %g0,%g2,%o0
-/* 0x03b8 */ cmp %o1,%o0
-/* 0x03bc */ sub %g2,1,%o0
-/* 0x03c0 */ bge,pt %icc,.L77000215
-/* 0x03c4 */ or %g0,0,%g3
-/* 0x03c8 254 */ add %o1,1,%o1
-/* 0x03cc 281 */ sra %o2,0,%g2
- .L900000652:
-/* 0x03d0 */ sllx %g2,3,%g2
-/* 0x03d4 */ ldd [%o7],%f6
-/* 0x03d8 */ add %o2,2,%o2
-/* 0x03dc */ sra %o1,0,%g3
-/* 0x03e0 */ ldd [%g2+%l4],%f8
-/* 0x03e4 */ cmp %o2,%o0
-/* 0x03e8 */ sllx %g3,3,%g3
-/* 0x03ec */ add %o1,2,%o1
-/* 0x03f0 */ ldd [%l4+%g3],%f10
-/* 0x03f4 */ fdtox %f8,%f12
-/* 0x03f8 */ fdtox %f10,%f4
-/* 0x03fc */ fmovd %f12,%f8
-/* 0x0400 */ fmovs %f6,%f12
-/* 0x0404 */ fmovs %f6,%f4
-/* 0x0408 */ fxtod %f12,%f6
-/* 0x040c */ fxtod %f4,%f12
-/* 0x0410 */ fdtox %f10,%f4
-/* 0x0414 */ faddd %f6,%f2,%f6
-/* 0x0418 */ std %f6,[%g2+%l4]
-/* 0x041c */ faddd %f12,%f0,%f6
-/* 0x0420 */ std %f6,[%l4+%g3]
-/* 0x0424 */ fitod %f8,%f2
-/* 0x0428 */ fitod %f4,%f0
-/* 0x042c */ ble,pt %icc,.L900000652
-/* 0x0430 */ sra %o2,0,%g2
- .L77000233:
-/* 0x0434 */ or %g0,0,%g3
- .L77000215:
-/* 0x0438 */ fdtox %f16,%f0
- .L900000653:
-/* 0x043c 256 */ ldd [%o7],%f6
-/* 0x0440 */ add %g4,1,%g4
-/* 0x0444 */ or %g0,%i0,%i2
-/* 0x0448 */ ldd [%o5],%f8
-/* 0x044c */ add %g3,1,%g3
-/* 0x0450 */ add %i3,8,%i3
-/* 0x0454 */ fmovs %f6,%f0
-/* 0x0458 */ ldd [%o4],%f10
-/* 0x045c */ ld [%sp+2223],%o0
-/* 0x0460 */ fxtod %f0,%f6
-/* 0x0464 */ cmp %i0,%o0
-/* 0x0468 */ fmuld %f6,%f30,%f6
-/* 0x046c */ fmuld %f6,%f8,%f8
-/* 0x0470 */ fdtox %f8,%f8
-/* 0x0474 */ fxtod %f8,%f8
-/* 0x0478 */ fmuld %f8,%f10,%f8
-/* 0x047c */ fsubd %f6,%f8,%f20
-/* 0x0480 */ ble,a,pt %icc,.L900000651
-/* 0x0484 */ ldd [%i5],%f6
- .L900000625:
-/* 0x0488 256 */ ba .L900000650
-/* 0x048c */ sllx %g5,3,%g2
- .L77000279:
-/* 0x0490 261 */ ldd [%i1],%f4
-/* 0x0494 */ ldd [%i2],%f6
-/* 0x0498 273 */ std %f0,[%i3+8]
-/* 0x049c */ std %f0,[%i3+16]
-/* 0x04a0 261 */ fmuld %f4,%f6,%f6
-/* 0x04a4 */ std %f6,[%i3]
-/* 0x04a8 273 */ std %f0,[%i3+24]
-/* 0x04ac */ std %f0,[%i3+32]
-/* 0x04b0 */ fdtox %f6,%f2
-/* 0x04b4 */ std %f0,[%i3+40]
-/* 0x04b8 */ std %f0,[%i3+48]
-/* 0x04bc */ std %f0,[%i3+56]
-/* 0x04c0 */ std %f0,[%i3+64]
-/* 0x04c4 */ fmovs %f0,%f2
-/* 0x04c8 */ std %f0,[%i3+72]
-/* 0x04cc */ std %f0,[%i3+80]
-/* 0x04d0 */ std %f0,[%i3+88]
-/* 0x04d4 */ std %f0,[%i3+96]
-/* 0x04d8 */ std %f0,[%i3+104]
-/* 0x04dc */ std %f0,[%i3+112]
-/* 0x04e0 */ std %f0,[%i3+120]
-/* 0x04e4 */ std %f0,[%i3+128]
-/* 0x04e8 */ std %f0,[%i3+136]
-/* 0x04ec */ std %f0,[%i3+144]
-/* 0x04f0 */ std %f0,[%i3+152]
-/* 0x04f4 */ std %f0,[%i3+160]
-/* 0x04f8 */ std %f0,[%i3+168]
-/* 0x04fc */ fxtod %f2,%f6
-/* 0x0500 */ std %f0,[%i3+176]
-/* 0x0504 281 */ or %g0,1,%o2
-/* 0x0508 273 */ std %f0,[%i3+184]
-
-! 282 ! {
-! 284 ! m2j=pdm2[j];
-! 285 ! a=pdtj[0]+pdn_0*digit;
-! 286 ! b=pdtj[1]+pdm1_0*pdm2[j+1]+a*TwoToMinus16;
-
-/* 0x050c 286 */ sra %o2,0,%g2
-/* 0x0510 279 */ or %g0,%i3,%o3
-/* 0x0514 273 */ std %f0,[%i3+192]
-/* 0x0518 278 */ fmuld %f6,%f14,%f6
-/* 0x051c 281 */ or %g0,0,%g1
-/* 0x0520 273 */ std %f0,[%i3+200]
-/* 0x0524 */ std %f0,[%i3+208]
-/* 0x0528 */ std %f0,[%i3+216]
-/* 0x052c */ std %f0,[%i3+224]
-/* 0x0530 */ std %f0,[%i3+232]
-/* 0x0534 */ std %f0,[%i3+240]
-/* 0x0538 */ std %f0,[%i3+248]
-/* 0x053c */ std %f0,[%i3+256]
-/* 0x0540 */ std %f0,[%i3+264]
-/* 0x0544 */ std %f0,[%i3+272]
-/* 0x0548 */ std %f0,[%i3+280]
-/* 0x054c */ std %f0,[%i3+288]
-/* 0x0550 */ std %f0,[%i3+296]
-/* 0x0554 */ std %f0,[%i3+304]
-/* 0x0558 */ std %f0,[%i3+312]
-/* 0x055c */ std %f0,[%i3+320]
-/* 0x0560 */ std %f0,[%i3+328]
-/* 0x0564 */ std %f0,[%i3+336]
-/* 0x0568 */ std %f0,[%i3+344]
-/* 0x056c */ std %f0,[%i3+352]
-/* 0x0570 */ std %f0,[%i3+360]
-/* 0x0574 */ std %f0,[%i3+368]
-/* 0x0578 */ std %f0,[%i3+376]
-/* 0x057c */ std %f0,[%i3+384]
-/* 0x0580 */ std %f0,[%i3+392]
-/* 0x0584 */ std %f0,[%i3+400]
-/* 0x0588 */ std %f0,[%i3+408]
-/* 0x058c */ std %f0,[%i3+416]
-/* 0x0590 */ std %f0,[%i3+424]
-/* 0x0594 */ std %f0,[%i3+432]
-/* 0x0598 */ std %f0,[%i3+440]
-/* 0x059c */ std %f0,[%i3+448]
-/* 0x05a0 */ std %f0,[%i3+456]
-/* 0x05a4 */ std %f0,[%i3+464]
-/* 0x05a8 */ std %f0,[%i3+472]
-/* 0x05ac */ std %f0,[%i3+480]
-/* 0x05b0 */ std %f0,[%i3+488]
-/* 0x05b4 */ std %f0,[%i3+496]
-/* 0x05b8 278 */ ldd [%o5],%f8
-/* 0x05bc */ ldd [%o4],%f10
-/* 0x05c0 */ fmuld %f6,%f8,%f8
-/* 0x05c4 273 */ std %f0,[%i3+504]
-/* 0x05c8 */ std %f0,[%i3+512]
-/* 0x05cc */ std %f0,[%i3+520]
-/* 0x05d0 */ fdtox %f8,%f8
-/* 0x05d4 275 */ ldd [%o0],%f0
-/* 0x05d8 */ fxtod %f8,%f8
-/* 0x05dc */ fmuld %f8,%f10,%f8
-/* 0x05e0 */ fsubd %f6,%f8,%f2
-
-! 287 ! pdtj[1]=b;
-! 289 ! /**** this loop will be fully unrolled:
-! 290 ! for(i=1;i<16;i++)
-! 291 ! {
-! 292 ! pdtj[2*i]+=pdm1[i]*m2j+pdn[i]*digit;
-! 293 ! }
-! 294 ! *************************************/
-! 295 ! pdtj[2]+=pdm1[1]*m2j+pdn[1]*digit;
-! 296 ! pdtj[4]+=pdm1[2]*m2j+pdn[2]*digit;
-! 297 ! pdtj[6]+=pdm1[3]*m2j+pdn[3]*digit;
-! 298 ! pdtj[8]+=pdm1[4]*m2j+pdn[4]*digit;
-! 299 ! pdtj[10]+=pdm1[5]*m2j+pdn[5]*digit;
-! 300 ! pdtj[12]+=pdm1[6]*m2j+pdn[6]*digit;
-! 301 ! pdtj[14]+=pdm1[7]*m2j+pdn[7]*digit;
-! 302 ! pdtj[16]+=pdm1[8]*m2j+pdn[8]*digit;
-! 303 ! pdtj[18]+=pdm1[9]*m2j+pdn[9]*digit;
-! 304 ! pdtj[20]+=pdm1[10]*m2j+pdn[10]*digit;
-! 305 ! pdtj[22]+=pdm1[11]*m2j+pdn[11]*digit;
-! 306 ! pdtj[24]+=pdm1[12]*m2j+pdn[12]*digit;
-! 307 ! pdtj[26]+=pdm1[13]*m2j+pdn[13]*digit;
-! 308 ! pdtj[28]+=pdm1[14]*m2j+pdn[14]*digit;
-! 309 ! pdtj[30]+=pdm1[15]*m2j+pdn[15]*digit;
-! 310 ! /* no need for cleenup, cannot overflow */
-! 311 ! digit=mod(lower32(b,Zero)*dn0,TwoToMinus16,TwoTo16);
-
-
- fmovd %f2,%f0 ! hand modified
- fmovd %f30,%f18 ! hand modified
- ldd [%o0],%f2
- ldd [%o3],%f8
- ldd [%i1],%f10
- ldd [%o5],%f14 ! hand modified
- ldd [%o4],%f16 ! hand modified
- ldd [%i2],%f24
-
- ldd [%i1+8],%f26
- ldd [%i1+16],%f40
- ldd [%i1+48],%f46
- ldd [%i1+56],%f30
- ldd [%i1+64],%f54
- ldd [%i1+104],%f34
- ldd [%i1+112],%f58
-
- ldd [%o0+8],%f28
- ldd [%o0+104],%f38
- ldd [%o0+112],%f60
-
- .L99999999: !1
- ldd [%i1+24],%f32
- fmuld %f0,%f2,%f4 !2
- ldd [%o0+24],%f36
- fmuld %f26,%f24,%f20 !3
- ldd [%i1+40],%f42
- fmuld %f28,%f0,%f22 !4
- ldd [%o0+40],%f44
- fmuld %f32,%f24,%f32 !5
- ldd [%i2+8],%f6
- faddd %f4,%f8,%f4
- fmuld %f36,%f0,%f36 !6
- add %i2,8,%i2
- ldd [%o0+56],%f50
- fmuld %f42,%f24,%f42 !7
- ldd [%i1+72],%f52
- faddd %f20,%f22,%f20
- fmuld %f44,%f0,%f44 !8
- ldd [%o3+16],%f22
- fmuld %f10,%f6,%f12 !9
- ldd [%o0+72],%f56
- faddd %f32,%f36,%f32
- fmuld %f14,%f4,%f4 !10
- ldd [%o3+48],%f36
- fmuld %f30,%f24,%f48 !11
- ldd [%o3+8],%f8
- faddd %f20,%f22,%f20
- fmuld %f50,%f0,%f50 !12
- std %f20,[%o3+16]
- faddd %f42,%f44,%f42
- fmuld %f52,%f24,%f52 !13
- ldd [%o3+80],%f44
- faddd %f4,%f12,%f4
- fmuld %f56,%f0,%f56 !14
- ldd [%i1+88],%f20
- faddd %f32,%f36,%f32 !15
- ldd [%o0+88],%f22
- faddd %f48,%f50,%f48 !16
- ldd [%o3+112],%f50
- faddd %f52,%f56,%f52 !17
- ldd [%o3+144],%f56
- faddd %f4,%f8,%f8
- fmuld %f20,%f24,%f20 !18
- std %f32,[%o3+48]
- faddd %f42,%f44,%f42
- fmuld %f22,%f0,%f22 !19
- std %f42,[%o3+80]
- faddd %f48,%f50,%f48
- fmuld %f34,%f24,%f32 !20
- std %f48,[%o3+112]
- faddd %f52,%f56,%f52
- fmuld %f38,%f0,%f36 !21
- ldd [%i1+120],%f42
- fdtox %f8,%f4 !22
- std %f52,[%o3+144]
- faddd %f20,%f22,%f20 !23
- ldd [%o0+120],%f44 !24
- ldd [%o3+176],%f22
- faddd %f32,%f36,%f32
- fmuld %f42,%f24,%f42 !25
- ldd [%o0+16],%f50
- fmovs %f17,%f4 !26
- ldd [%i1+32],%f52
- fmuld %f44,%f0,%f44 !27
- ldd [%o0+32],%f56
- fmuld %f40,%f24,%f48 !28
- ldd [%o3+208],%f36
- faddd %f20,%f22,%f20
- fmuld %f50,%f0,%f50 !29
- std %f20,[%o3+176]
- fxtod %f4,%f4
- fmuld %f52,%f24,%f52 !30
- ldd [%o0+48],%f22
- faddd %f42,%f44,%f42
- fmuld %f56,%f0,%f56 !31
- ldd [%o3+240],%f44
- faddd %f32,%f36,%f32 !32
- std %f32,[%o3+208]
- faddd %f48,%f50,%f48
- fmuld %f46,%f24,%f20 !33
- ldd [%o3+32],%f50
- fmuld %f4,%f18,%f12 !34
- ldd [%o0+64],%f36
- faddd %f52,%f56,%f52
- fmuld %f22,%f0,%f22 !35
- ldd [%o3+64],%f56
- faddd %f42,%f44,%f42 !36
- std %f42,[%o3+240]
- faddd %f48,%f50,%f48
- fmuld %f54,%f24,%f32 !37
- std %f48,[%o3+32]
- fmuld %f12,%f14,%f4 !38
- ldd [%i1+80],%f42
- faddd %f52,%f56,%f56 ! yes, tmp52!
- fmuld %f36,%f0,%f36 !39
- ldd [%o0+80],%f44
- faddd %f20,%f22,%f20 !40
- ldd [%i1+96],%f48
- fmuld %f58,%f24,%f52 !41
- ldd [%o0+96],%f50
- fdtox %f4,%f4
- fmuld %f42,%f24,%f42 !42
- std %f56,[%o3+64] ! yes, tmp52!
- faddd %f32,%f36,%f32
- fmuld %f44,%f0,%f44 !43
- ldd [%o3+96],%f22
- fmuld %f48,%f24,%f48 !44
- ldd [%o3+128],%f36
- fmovd %f6,%f24
- fmuld %f50,%f0,%f50 !45
- fxtod %f4,%f4
- fmuld %f60,%f0,%f56 !46
- add %o3,8,%o3
- faddd %f42,%f44,%f42 !47
- ldd [%o3+160-8],%f44
- faddd %f20,%f22,%f20 !48
- std %f20,[%o3+96-8]
- faddd %f48,%f50,%f48 !49
- ldd [%o3+192-8],%f50
- faddd %f52,%f56,%f52
- fmuld %f4,%f16,%f4 !50
- ldd [%o3+224-8],%f56
- faddd %f32,%f36,%f32 !51
- std %f32,[%o3+128-8]
- faddd %f42,%f44,%f42 !52
- add %g1,1,%g1
- std %f42,[%o3+160-8]
- faddd %f48,%f50,%f48 !53
- cmp %g1,31
- std %f48,[%o3+192-8]
- fsubd %f12,%f4,%f0 !54
- faddd %f52,%f56,%f52
- ble,pt %icc,.L99999999
- std %f52,[%o3+224-8] !55
- std %f8,[%o3]
-! 312 ! }
-! 313 ! }
-! 315 ! conv_d16_to_i32(result,dt+2*nlen,(long long *)dt,nlen+1);
-
-/* 0x0844 315 */ sllx %g5,3,%g2
- .L900000650:
-/* 0x0848 315 */ ldd [%g2+%l4],%f2
-/* 0x084c */ add %l4,%g2,%o0
-/* 0x0850 */ or %g0,0,%g1
-/* 0x0854 */ ldd [%o0+8],%f4
-/* 0x0858 */ or %g0,0,%i2
-/* 0x085c */ cmp %l0,0
-/* 0x0860 */ fdtox %f2,%f2
-/* 0x0864 */ std %f2,[%sp+2255]
-/* 0x0868 311 */ sethi %hi(0xfc00),%o3
-/* 0x086c 315 */ fdtox %f4,%f2
-/* 0x0870 */ std %f2,[%sp+2247]
-/* 0x0874 311 */ or %g0,-1,%o2
-/* 0x0878 */ srl %o2,0,%o5
-/* 0x087c */ or %g0,2,%g5
-/* 0x0880 */ sub %l0,1,%g3
-/* 0x0884 */ or %g0,%o0,%o7
-/* 0x0888 */ add %o3,1023,%o4
-/* 0x088c 315 */ or %g0,64,%o3
-/* 0x0890 */ ldx [%sp+2255],%i0
-/* 0x0894 */ sub %l0,2,%o1
-/* 0x0898 */ ldx [%sp+2247],%i1
-/* 0x089c */ ble,pt %icc,.L900000648
-/* 0x08a0 */ sethi %hi(0xfc00),%g2
-/* 0x08a4 */ cmp %l0,6
-/* 0x08a8 */ and %i0,%o5,%o2
-/* 0x08ac */ bl,pn %icc,.L77000287
-/* 0x08b0 */ or %g0,3,%g4
-/* 0x08b4 */ ldd [%o7+16],%f0
-/* 0x08b8 */ and %i1,%o4,%i3
-/* 0x08bc */ sllx %i3,16,%o0
-/* 0x08c0 */ or %g0,5,%g4
-/* 0x08c4 */ srax %i1,16,%i4
-/* 0x08c8 */ fdtox %f0,%f0
-/* 0x08cc */ std %f0,[%sp+2239]
-/* 0x08d0 */ srax %i0,32,%i1
-/* 0x08d4 */ add %o2,%o0,%i5
-/* 0x08d8 */ ldd [%o7+24],%f0
-/* 0x08dc */ and %i5,%o5,%l1
-/* 0x08e0 */ or %g0,72,%o2
-/* 0x08e4 */ or %g0,4,%o0
-/* 0x08e8 */ or %g0,4,%g5
-/* 0x08ec */ ldx [%sp+2239],%g1
-/* 0x08f0 */ fdtox %f0,%f0
-/* 0x08f4 */ or %g0,4,%i2
-/* 0x08f8 */ std %f0,[%sp+2231]
-/* 0x08fc */ ldd [%o7+40],%f2
-/* 0x0900 */ and %g1,%o5,%i3
-/* 0x0904 */ ldd [%o7+32],%f0
-/* 0x0908 */ srax %g1,32,%g1
-/* 0x090c */ ldd [%o7+56],%f4
-/* 0x0910 */ fdtox %f2,%f2
-/* 0x0914 */ ldx [%sp+2231],%g2
-/* 0x0918 */ fdtox %f0,%f0
-/* 0x091c */ st %l1,[%l2]
-/* 0x0920 */ srax %i5,32,%l1
-/* 0x0924 */ fdtox %f4,%f4
-/* 0x0928 */ std %f2,[%sp+2231]
-/* 0x092c */ and %g2,%o4,%i5
-/* 0x0930 */ add %i4,%l1,%i4
-/* 0x0934 */ std %f0,[%sp+2239]
-/* 0x0938 */ sllx %i5,16,%i0
-/* 0x093c */ add %i1,%i4,%i1
-/* 0x0940 */ ldd [%o7+48],%f2
-/* 0x0944 */ srax %g2,16,%g2
-/* 0x0948 */ add %i3,%i0,%i0
-/* 0x094c */ ldd [%o7+72],%f0
-/* 0x0950 */ add %i0,%i1,%i3
-/* 0x0954 */ srax %i3,32,%i4
-/* 0x0958 */ fdtox %f2,%f2
-/* 0x095c */ and %i3,%o5,%i3
-/* 0x0960 */ ldx [%sp+2231],%i1
-/* 0x0964 */ add %g2,%i4,%g2
-/* 0x0968 */ ldx [%sp+2239],%i0
-/* 0x096c */ add %g1,%g2,%g1
-/* 0x0970 */ std %f2,[%sp+2239]
-/* 0x0974 */ std %f4,[%sp+2231]
-/* 0x0978 */ ldd [%o7+64],%f2
-/* 0x097c */ st %i3,[%l2+4]
- .L900000631:
-/* 0x0980 */ ldx [%sp+2231],%i3
-/* 0x0984 */ add %i2,2,%i2
-/* 0x0988 */ add %g4,4,%g4
-/* 0x098c */ ldx [%sp+2239],%i5
-/* 0x0990 */ add %o2,16,%o2
-/* 0x0994 */ and %i1,%o4,%g2
-/* 0x0998 */ sllx %g2,16,%i4
-/* 0x099c */ and %i0,%o5,%g2
-/* 0x09a0 */ ldd [%o7+%o2],%f4
-/* 0x09a4 */ fdtox %f0,%f0
-/* 0x09a8 */ std %f0,[%sp+2231]
-/* 0x09ac */ srax %i1,16,%i1
-/* 0x09b0 */ add %g2,%i4,%g2
-/* 0x09b4 */ fdtox %f2,%f0
-/* 0x09b8 */ add %o3,16,%o3
-/* 0x09bc */ std %f0,[%sp+2239]
-/* 0x09c0 */ add %g2,%g1,%g1
-/* 0x09c4 */ ldd [%o7+%o3],%f2
-/* 0x09c8 */ srax %g1,32,%i4
-/* 0x09cc */ cmp %i2,%o1
-/* 0x09d0 */ srax %i0,32,%g2
-/* 0x09d4 */ add %i1,%i4,%i0
-/* 0x09d8 */ add %g2,%i0,%i4
-/* 0x09dc */ add %o0,4,%o0
-/* 0x09e0 */ and %g1,%o5,%g2
-/* 0x09e4 */ or %g0,%i5,%g1
-/* 0x09e8 */ st %g2,[%l2+%o0]
-/* 0x09ec */ add %g5,4,%g5
-/* 0x09f0 */ ldx [%sp+2231],%i1
-/* 0x09f4 */ ldx [%sp+2239],%i0
-/* 0x09f8 */ add %o2,16,%o2
-/* 0x09fc */ and %i3,%o4,%g2
-/* 0x0a00 */ sllx %g2,16,%i5
-/* 0x0a04 */ and %g1,%o5,%g2
-/* 0x0a08 */ ldd [%o7+%o2],%f0
-/* 0x0a0c */ fdtox %f4,%f4
-/* 0x0a10 */ std %f4,[%sp+2231]
-/* 0x0a14 */ srax %i3,16,%i3
-/* 0x0a18 */ add %g2,%i5,%g2
-/* 0x0a1c */ fdtox %f2,%f2
-/* 0x0a20 */ add %o3,16,%o3
-/* 0x0a24 */ std %f2,[%sp+2239]
-/* 0x0a28 */ add %g2,%i4,%g2
-/* 0x0a2c */ ldd [%o7+%o3],%f2
-/* 0x0a30 */ srax %g2,32,%i4
-/* 0x0a34 */ srax %g1,32,%g1
-/* 0x0a38 */ add %i3,%i4,%i3
-/* 0x0a3c */ add %g1,%i3,%g1
-/* 0x0a40 */ add %o0,4,%o0
-/* 0x0a44 */ and %g2,%o5,%g2
-/* 0x0a48 */ ble,pt %icc,.L900000631
-/* 0x0a4c */ st %g2,[%l2+%o0]
- .L900000634:
-/* 0x0a50 */ srax %i1,16,%i5
-/* 0x0a54 */ ldx [%sp+2231],%o1
-/* 0x0a58 */ and %i1,%o4,%i3
-/* 0x0a5c */ sllx %i3,16,%i3
-/* 0x0a60 */ ldx [%sp+2239],%i4
-/* 0x0a64 */ and %i0,%o5,%g2
-/* 0x0a68 */ add %g2,%i3,%g2
-/* 0x0a6c */ and %o1,%o4,%i3
-/* 0x0a70 */ fdtox %f0,%f4
-/* 0x0a74 */ sllx %i3,16,%i3
-/* 0x0a78 */ std %f4,[%sp+2231]
-/* 0x0a7c */ add %g2,%g1,%g2
-/* 0x0a80 */ srax %g2,32,%l1
-/* 0x0a84 */ and %i4,%o5,%i1
-/* 0x0a88 */ fdtox %f2,%f0
-/* 0x0a8c */ srax %i0,32,%g1
-/* 0x0a90 */ std %f0,[%sp+2239]
-/* 0x0a94 */ add %i5,%l1,%i0
-/* 0x0a98 */ srax %o1,16,%o1
-/* 0x0a9c */ add %g1,%i0,%i0
-/* 0x0aa0 */ add %o0,4,%g1
-/* 0x0aa4 */ add %i1,%i3,%o0
-/* 0x0aa8 */ and %g2,%o5,%g2
-/* 0x0aac */ st %g2,[%l2+%g1]
-/* 0x0ab0 */ add %o0,%i0,%o0
-/* 0x0ab4 */ srax %o0,32,%i3
-/* 0x0ab8 */ ldx [%sp+2231],%i1
-/* 0x0abc */ add %g1,4,%g1
-/* 0x0ac0 */ ldx [%sp+2239],%i0
-/* 0x0ac4 */ and %o0,%o5,%g2
-/* 0x0ac8 */ add %o1,%i3,%o1
-/* 0x0acc */ srax %i4,32,%o0
-/* 0x0ad0 */ cmp %i2,%g3
-/* 0x0ad4 */ st %g2,[%l2+%g1]
-/* 0x0ad8 */ bg,pn %icc,.L77000236
-/* 0x0adc */ add %o0,%o1,%g1
-/* 0x0ae0 */ add %g4,6,%g4
-/* 0x0ae4 */ add %g5,6,%g5
- .L77000287:
-/* 0x0ae8 */ sra %g5,0,%o1
- .L900000647:
-/* 0x0aec */ sllx %o1,3,%o2
-/* 0x0af0 */ and %i0,%o5,%o0
-/* 0x0af4 */ ldd [%o7+%o2],%f0
-/* 0x0af8 */ sra %g4,0,%o2
-/* 0x0afc */ and %i1,%o4,%o1
-/* 0x0b00 */ sllx %o2,3,%o2
-/* 0x0b04 */ add %g1,%o0,%o0
-/* 0x0b08 */ fdtox %f0,%f0
-/* 0x0b0c */ std %f0,[%sp+2239]
-/* 0x0b10 */ sllx %o1,16,%o1
-/* 0x0b14 */ add %o0,%o1,%o1
-/* 0x0b18 */ add %g5,2,%g5
-/* 0x0b1c */ ldd [%o7+%o2],%f0
-/* 0x0b20 */ srax %o1,32,%g1
-/* 0x0b24 */ and %o1,%o5,%o2
-/* 0x0b28 */ srax %i1,16,%o0
-/* 0x0b2c */ add %g4,2,%g4
-/* 0x0b30 */ fdtox %f0,%f0
-/* 0x0b34 */ std %f0,[%sp+2231]
-/* 0x0b38 */ sra %i2,0,%o1
-/* 0x0b3c */ sllx %o1,2,%o1
-/* 0x0b40 */ add %o0,%g1,%g2
-/* 0x0b44 */ srax %i0,32,%g1
-/* 0x0b48 */ add %i2,1,%i2
-/* 0x0b4c */ add %g1,%g2,%g1
-/* 0x0b50 */ cmp %i2,%g3
-/* 0x0b54 */ ldx [%sp+2239],%o3
-/* 0x0b58 */ ldx [%sp+2231],%i1
-/* 0x0b5c */ st %o2,[%l2+%o1]
-/* 0x0b60 */ or %g0,%o3,%i0
-/* 0x0b64 */ ble,pt %icc,.L900000647
-/* 0x0b68 */ sra %g5,0,%o1
- .L77000236:
-/* 0x0b6c */ sethi %hi(0xfc00),%g2
- .L900000648:
-/* 0x0b70 */ or %g0,-1,%o0
-/* 0x0b74 */ add %g2,1023,%g2
-/* 0x0b78 */ srl %o0,0,%g3
-/* 0x0b7c */ and %i1,%g2,%g2
-/* 0x0b80 */ and %i0,%g3,%g4
-/* 0x0b84 */ sllx %g2,16,%g2
-/* 0x0b88 */ add %g1,%g4,%g4
-/* 0x0b8c */ sra %i2,0,%g5
-/* 0x0b90 */ add %g4,%g2,%g4
-/* 0x0b94 */ sllx %g5,2,%g2
-/* 0x0b98 */ and %g4,%g3,%g3
-/* 0x0b9c */ st %g3,[%l2+%g2]
-
-! 317 ! adjust_montf_result(result,nint,nlen);
-
-/* 0x0ba0 317 */ sra %l0,0,%g4
-/* 0x0ba4 */ sllx %g4,2,%g2
-/* 0x0ba8 */ ld [%l2+%g2],%g2
-/* 0x0bac */ cmp %g2,0
-/* 0x0bb0 */ bleu,pn %icc,.L77000241
-/* 0x0bb4 */ or %g0,-1,%o1
-/* 0x0bb8 */ ba .L900000646
-/* 0x0bbc */ cmp %o1,0
- .L77000241:
-/* 0x0bc0 */ sub %l0,1,%o1
-/* 0x0bc4 */ cmp %o1,0
-/* 0x0bc8 */ bl,pn %icc,.L77000244
-/* 0x0bcc */ sra %o1,0,%g2
- .L900000645:
-/* 0x0bd0 */ sllx %g2,2,%g2
-/* 0x0bd4 */ sub %o1,1,%o0
-/* 0x0bd8 */ ld [%l3+%g2],%g3
-/* 0x0bdc */ ld [%l2+%g2],%g2
-/* 0x0be0 */ cmp %g2,%g3
-/* 0x0be4 */ bne,pn %icc,.L77000244
-/* 0x0be8 */ nop
-/* 0x0bec 0 */ or %g0,%o0,%o1
-/* 0x0bf0 317 */ cmp %o0,0
-/* 0x0bf4 */ bge,pt %icc,.L900000645
-/* 0x0bf8 */ sra %o1,0,%g2
- .L77000244:
-/* 0x0bfc */ cmp %o1,0
- .L900000646:
-/* 0x0c00 */ bl,pn %icc,.L77000288
-/* 0x0c04 */ sra %o1,0,%g2
-/* 0x0c08 */ sllx %g2,2,%g2
-/* 0x0c0c */ ld [%l3+%g2],%g3
-/* 0x0c10 */ ld [%l2+%g2],%g2
-/* 0x0c14 */ cmp %g2,%g3
-/* 0x0c18 */ bleu,pt %icc,.L77000224
-/* 0x0c1c */ nop
- .L77000288:
-/* 0x0c20 */ cmp %l0,0
-/* 0x0c24 */ ble,pt %icc,.L77000224
-/* 0x0c28 */ nop
-/* 0x0c2c 317 */ or %g0,-1,%g2
-/* 0x0c30 315 */ or %g0,0,%i0
-/* 0x0c34 317 */ srl %g2,0,%g2
-/* 0x0c38 315 */ or %g0,0,%g4
-/* 0x0c3c */ or %g0,0,%o1
-/* 0x0c40 317 */ sub %l0,1,%g5
-/* 0x0c44 */ cmp %l0,9
-/* 0x0c48 315 */ or %g0,8,%o5
-/* 0x0c4c */ bl,pn %icc,.L77000289
-/* 0x0c50 */ sub %l0,4,%o7
-/* 0x0c54 */ ld [%l2],%o1
-/* 0x0c58 */ or %g0,5,%i0
-/* 0x0c5c */ ld [%l3],%o2
-/* 0x0c60 */ or %g0,12,%o4
-/* 0x0c64 */ or %g0,16,%g1
-/* 0x0c68 */ ld [%l3+4],%o3
-/* 0x0c6c */ ld [%l2+4],%o0
-/* 0x0c70 */ sub %o1,%o2,%o1
-/* 0x0c74 */ ld [%l3+8],%i1
-/* 0x0c78 */ and %o1,%g2,%g4
-/* 0x0c7c */ st %g4,[%l2]
-/* 0x0c80 */ srax %o1,32,%g4
-/* 0x0c84 */ sub %o0,%o3,%o0
-/* 0x0c88 */ ld [%l3+12],%o2
-/* 0x0c8c */ add %o0,%g4,%o0
-/* 0x0c90 */ and %o0,%g2,%g4
-/* 0x0c94 */ st %g4,[%l2+4]
-/* 0x0c98 */ srax %o0,32,%o0
-/* 0x0c9c */ ld [%l2+8],%o1
-/* 0x0ca0 */ ld [%l2+12],%o3
-/* 0x0ca4 */ sub %o1,%i1,%o1
- .L900000635:
-/* 0x0ca8 */ add %g1,4,%g3
-/* 0x0cac */ ld [%g1+%l2],%g4
-/* 0x0cb0 */ add %o1,%o0,%o0
-/* 0x0cb4 */ ld [%l3+%g1],%i1
-/* 0x0cb8 */ sub %o3,%o2,%o1
-/* 0x0cbc */ and %o0,%g2,%o2
-/* 0x0cc0 */ st %o2,[%o5+%l2]
-/* 0x0cc4 */ srax %o0,32,%o2
-/* 0x0cc8 */ add %i0,4,%i0
-/* 0x0ccc */ add %g1,8,%o5
-/* 0x0cd0 */ ld [%g3+%l2],%o0
-/* 0x0cd4 */ add %o1,%o2,%o1
-/* 0x0cd8 */ ld [%l3+%g3],%o3
-/* 0x0cdc */ sub %g4,%i1,%o2
-/* 0x0ce0 */ and %o1,%g2,%g4
-/* 0x0ce4 */ st %g4,[%o4+%l2]
-/* 0x0ce8 */ srax %o1,32,%g4
-/* 0x0cec */ cmp %i0,%o7
-/* 0x0cf0 */ add %g1,12,%o4
-/* 0x0cf4 */ ld [%o5+%l2],%o1
-/* 0x0cf8 */ add %o2,%g4,%o2
-/* 0x0cfc */ ld [%l3+%o5],%i1
-/* 0x0d00 */ sub %o0,%o3,%o0
-/* 0x0d04 */ and %o2,%g2,%o3
-/* 0x0d08 */ st %o3,[%g1+%l2]
-/* 0x0d0c */ srax %o2,32,%g4
-/* 0x0d10 */ ld [%o4+%l2],%o3
-/* 0x0d14 */ add %g1,16,%g1
-/* 0x0d18 */ add %o0,%g4,%o0
-/* 0x0d1c */ ld [%l3+%o4],%o2
-/* 0x0d20 */ sub %o1,%i1,%o1
-/* 0x0d24 */ and %o0,%g2,%g4
-/* 0x0d28 */ st %g4,[%g3+%l2]
-/* 0x0d2c */ ble,pt %icc,.L900000635
-/* 0x0d30 */ srax %o0,32,%o0
- .L900000638:
-/* 0x0d34 */ add %o1,%o0,%g3
-/* 0x0d38 */ sub %o3,%o2,%o1
-/* 0x0d3c */ ld [%g1+%l2],%o0
-/* 0x0d40 */ ld [%l3+%g1],%o2
-/* 0x0d44 */ srax %g3,32,%o7
-/* 0x0d48 */ and %g3,%g2,%o3
-/* 0x0d4c */ add %o1,%o7,%o1
-/* 0x0d50 */ st %o3,[%o5+%l2]
-/* 0x0d54 */ cmp %i0,%g5
-/* 0x0d58 */ sub %o0,%o2,%o0
-/* 0x0d5c */ and %o1,%g2,%o2
-/* 0x0d60 */ st %o2,[%o4+%l2]
-/* 0x0d64 */ srax %o1,32,%o1
-/* 0x0d68 */ sra %i0,0,%o2
-/* 0x0d6c */ add %o0,%o1,%o0
-/* 0x0d70 */ srax %o0,32,%g4
-/* 0x0d74 */ and %o0,%g2,%o1
-/* 0x0d78 */ st %o1,[%g1+%l2]
-/* 0x0d7c */ bg,pn %icc,.L77000224
-/* 0x0d80 */ sllx %o2,2,%o1
- .L77000289:
-/* 0x0d84 0 */ or %g0,%o1,%g1
- .L900000644:
-/* 0x0d88 */ ld [%o1+%l2],%o0
-/* 0x0d8c */ add %i0,1,%i0
-/* 0x0d90 */ ld [%l3+%o1],%o1
-/* 0x0d94 */ sra %i0,0,%o2
-/* 0x0d98 */ cmp %i0,%g5
-/* 0x0d9c */ add %g4,%o0,%o0
-/* 0x0da0 */ sub %o0,%o1,%o0
-/* 0x0da4 */ srax %o0,32,%g4
-/* 0x0da8 */ and %o0,%g2,%o1
-/* 0x0dac */ st %o1,[%g1+%l2]
-/* 0x0db0 */ sllx %o2,2,%o1
-/* 0x0db4 */ ble,pt %icc,.L900000644
-/* 0x0db8 */ or %g0,%o1,%g1
- .L77000224:
-/* 0x0dbc */ ret ! Result =
-/* 0x0dc0 */ restore %g0,%g0,%g0
-/* 0x0dc4 0 */ .type mont_mulf_noconv,2
-/* 0x0dc4 */ .size mont_mulf_noconv,(.-mont_mulf_noconv)
-
diff --git a/security/nss/lib/freebl/mpi/mp_comba.c b/security/nss/lib/freebl/mpi/mp_comba.c
deleted file mode 100644
index f12f454a1..000000000
--- a/security/nss/lib/freebl/mpi/mp_comba.c
+++ /dev/null
@@ -1,1298 +0,0 @@
-/*
- * The below file is derived from TFM v0.03.
- * It contains code from fp_mul_comba.c and
- * fp_sqr_comba.c, which contained the following license.
- *
- * Right now, the assembly in this file limits
- * this code to AMD 64.
- *
- * This file is public domain.
- */
-
-/* TomsFastMath, a fast ISO C bignum library.
- *
- * This project is meant to fill in where LibTomMath
- * falls short. That is speed ;-)
- *
- * This project is public domain and free for all purposes.
- *
- * Tom St Denis, tomstdenis@iahu.ca
- */
-
-
-#include "mpi-priv.h"
-
-
-
-/* clamp digits */
-#define mp_clamp(a) { while ((a)->used && (a)->dp[(a)->used-1] == 0) --((a)->used); (a)->sign = (a)->used ? (a)->sign : ZPOS; }
-
-/* anything you need at the start */
-#define COMBA_START
-
-/* clear the chaining variables */
-#define COMBA_CLEAR \
- c0 = c1 = c2 = 0;
-
-/* forward the carry to the next digit */
-#define COMBA_FORWARD \
- do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-
-/* anything you need at the end */
-#define COMBA_FINI
-
-/* this should multiply i and j */
-#define MULADD(i, j) \
-__asm__ ( \
- "movq %6,%%rax \n\t" \
- "mulq %7 \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","cc");
-
-
-
-
-/* sqr macros only */
-#define CLEAR_CARRY \
- c0 = c1 = c2 = 0;
-
-#define COMBA_STORE(x) \
- x = c0;
-
-#define COMBA_STORE2(x) \
- x = c1;
-
-#define CARRY_FORWARD \
- do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-
-#define COMBA_FINI
-
-#define SQRADD(i, j) \
-__asm__ ( \
- "movq %6,%%rax \n\t" \
- "mulq %%rax \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","cc");
-
-#define SQRADD2(i, j) \
-__asm__ ( \
- "movq %6,%%rax \n\t" \
- "mulq %7 \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","cc");
-
-#define SQRADDSC(i, j) \
-__asm__ ( \
- "movq %3,%%rax \n\t" \
- "mulq %4 \n\t" \
- "movq %%rax,%0 \n\t" \
- "movq %%rdx,%1 \n\t" \
- "xorq %2,%2 \n\t" \
- :"=r"(sc0), "=r"(sc1), "=r"(sc2): "g"(i), "g"(j) :"%rax","%rdx","cc");
-
-#define SQRADDAC(i, j) \
-__asm__ ( \
- "movq %6,%%rax \n\t" \
- "mulq %7 \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","cc");
-
-#define SQRADDDB \
-__asm__ ( \
- "addq %6,%0 \n\t" \
- "adcq %7,%1 \n\t" \
- "adcq %8,%2 \n\t" \
- "addq %6,%0 \n\t" \
- "adcq %7,%1 \n\t" \
- "adcq %8,%2 \n\t" \
- :"=&r"(c0), "=&r"(c1), "=&r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "cc");
-
-
-
-
-
-void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C)
-{
- mp_digit c0, c1, c2, at[8];
-
- memcpy(at, A->dp, 4 * sizeof(mp_digit));
- memcpy(at+4, B->dp, 4 * sizeof(mp_digit));
- COMBA_START;
-
- COMBA_CLEAR;
- /* 0 */
- MULADD(at[0], at[4]);
- COMBA_STORE(C->dp[0]);
- /* 1 */
- COMBA_FORWARD;
- MULADD(at[0], at[5]); MULADD(at[1], at[4]);
- COMBA_STORE(C->dp[1]);
- /* 2 */
- COMBA_FORWARD;
- MULADD(at[0], at[6]); MULADD(at[1], at[5]); MULADD(at[2], at[4]);
- COMBA_STORE(C->dp[2]);
- /* 3 */
- COMBA_FORWARD;
- MULADD(at[0], at[7]); MULADD(at[1], at[6]); MULADD(at[2], at[5]); MULADD(at[3], at[4]);
- COMBA_STORE(C->dp[3]);
- /* 4 */
- COMBA_FORWARD;
- MULADD(at[1], at[7]); MULADD(at[2], at[6]); MULADD(at[3], at[5]);
- COMBA_STORE(C->dp[4]);
- /* 5 */
- COMBA_FORWARD;
- MULADD(at[2], at[7]); MULADD(at[3], at[6]);
- COMBA_STORE(C->dp[5]);
- /* 6 */
- COMBA_FORWARD;
- MULADD(at[3], at[7]);
- COMBA_STORE(C->dp[6]);
- COMBA_STORE2(C->dp[7]);
- C->used = 8;
- C->sign = A->sign ^ B->sign;
- mp_clamp(C);
- COMBA_FINI;
-}
-
-void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C)
-{
- mp_digit c0, c1, c2, at[16];
-
- memcpy(at, A->dp, 8 * sizeof(mp_digit));
- memcpy(at+8, B->dp, 8 * sizeof(mp_digit));
- COMBA_START;
-
- COMBA_CLEAR;
- /* 0 */
- MULADD(at[0], at[8]);
- COMBA_STORE(C->dp[0]);
- /* 1 */
- COMBA_FORWARD;
- MULADD(at[0], at[9]); MULADD(at[1], at[8]);
- COMBA_STORE(C->dp[1]);
- /* 2 */
- COMBA_FORWARD;
- MULADD(at[0], at[10]); MULADD(at[1], at[9]); MULADD(at[2], at[8]);
- COMBA_STORE(C->dp[2]);
- /* 3 */
- COMBA_FORWARD;
- MULADD(at[0], at[11]); MULADD(at[1], at[10]); MULADD(at[2], at[9]); MULADD(at[3], at[8]);
- COMBA_STORE(C->dp[3]);
- /* 4 */
- COMBA_FORWARD;
- MULADD(at[0], at[12]); MULADD(at[1], at[11]); MULADD(at[2], at[10]); MULADD(at[3], at[9]); MULADD(at[4], at[8]);
- COMBA_STORE(C->dp[4]);
- /* 5 */
- COMBA_FORWARD;
- MULADD(at[0], at[13]); MULADD(at[1], at[12]); MULADD(at[2], at[11]); MULADD(at[3], at[10]); MULADD(at[4], at[9]); MULADD(at[5], at[8]);
- COMBA_STORE(C->dp[5]);
- /* 6 */
- COMBA_FORWARD;
- MULADD(at[0], at[14]); MULADD(at[1], at[13]); MULADD(at[2], at[12]); MULADD(at[3], at[11]); MULADD(at[4], at[10]); MULADD(at[5], at[9]); MULADD(at[6], at[8]);
- COMBA_STORE(C->dp[6]);
- /* 7 */
- COMBA_FORWARD;
- MULADD(at[0], at[15]); MULADD(at[1], at[14]); MULADD(at[2], at[13]); MULADD(at[3], at[12]); MULADD(at[4], at[11]); MULADD(at[5], at[10]); MULADD(at[6], at[9]); MULADD(at[7], at[8]);
- COMBA_STORE(C->dp[7]);
- /* 8 */
- COMBA_FORWARD;
- MULADD(at[1], at[15]); MULADD(at[2], at[14]); MULADD(at[3], at[13]); MULADD(at[4], at[12]); MULADD(at[5], at[11]); MULADD(at[6], at[10]); MULADD(at[7], at[9]);
- COMBA_STORE(C->dp[8]);
- /* 9 */
- COMBA_FORWARD;
- MULADD(at[2], at[15]); MULADD(at[3], at[14]); MULADD(at[4], at[13]); MULADD(at[5], at[12]); MULADD(at[6], at[11]); MULADD(at[7], at[10]);
- COMBA_STORE(C->dp[9]);
- /* 10 */
- COMBA_FORWARD;
- MULADD(at[3], at[15]); MULADD(at[4], at[14]); MULADD(at[5], at[13]); MULADD(at[6], at[12]); MULADD(at[7], at[11]);
- COMBA_STORE(C->dp[10]);
- /* 11 */
- COMBA_FORWARD;
- MULADD(at[4], at[15]); MULADD(at[5], at[14]); MULADD(at[6], at[13]); MULADD(at[7], at[12]);
- COMBA_STORE(C->dp[11]);
- /* 12 */
- COMBA_FORWARD;
- MULADD(at[5], at[15]); MULADD(at[6], at[14]); MULADD(at[7], at[13]);
- COMBA_STORE(C->dp[12]);
- /* 13 */
- COMBA_FORWARD;
- MULADD(at[6], at[15]); MULADD(at[7], at[14]);
- COMBA_STORE(C->dp[13]);
- /* 14 */
- COMBA_FORWARD;
- MULADD(at[7], at[15]);
- COMBA_STORE(C->dp[14]);
- COMBA_STORE2(C->dp[15]);
- C->used = 16;
- C->sign = A->sign ^ B->sign;
- mp_clamp(C);
- COMBA_FINI;
-}
-
-void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C)
-{
- mp_digit c0, c1, c2, at[32];
-
- memcpy(at, A->dp, 16 * sizeof(mp_digit));
- memcpy(at+16, B->dp, 16 * sizeof(mp_digit));
- COMBA_START;
-
- COMBA_CLEAR;
- /* 0 */
- MULADD(at[0], at[16]);
- COMBA_STORE(C->dp[0]);
- /* 1 */
- COMBA_FORWARD;
- MULADD(at[0], at[17]); MULADD(at[1], at[16]);
- COMBA_STORE(C->dp[1]);
- /* 2 */
- COMBA_FORWARD;
- MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]);
- COMBA_STORE(C->dp[2]);
- /* 3 */
- COMBA_FORWARD;
- MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]);
- COMBA_STORE(C->dp[3]);
- /* 4 */
- COMBA_FORWARD;
- MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]);
- COMBA_STORE(C->dp[4]);
- /* 5 */
- COMBA_FORWARD;
- MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]);
- COMBA_STORE(C->dp[5]);
- /* 6 */
- COMBA_FORWARD;
- MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]);
- COMBA_STORE(C->dp[6]);
- /* 7 */
- COMBA_FORWARD;
- MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]);
- COMBA_STORE(C->dp[7]);
- /* 8 */
- COMBA_FORWARD;
- MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]);
- COMBA_STORE(C->dp[8]);
- /* 9 */
- COMBA_FORWARD;
- MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]);
- COMBA_STORE(C->dp[9]);
- /* 10 */
- COMBA_FORWARD;
- MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]);
- COMBA_STORE(C->dp[10]);
- /* 11 */
- COMBA_FORWARD;
- MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]);
- COMBA_STORE(C->dp[11]);
- /* 12 */
- COMBA_FORWARD;
- MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]);
- COMBA_STORE(C->dp[12]);
- /* 13 */
- COMBA_FORWARD;
- MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); MULADD(at[13], at[16]);
- COMBA_STORE(C->dp[13]);
- /* 14 */
- COMBA_FORWARD;
- MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); MULADD(at[14], at[16]);
- COMBA_STORE(C->dp[14]);
- /* 15 */
- COMBA_FORWARD;
- MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); MULADD(at[14], at[17]); MULADD(at[15], at[16]);
- COMBA_STORE(C->dp[15]);
- /* 16 */
- COMBA_FORWARD;
- MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); MULADD(at[14], at[18]); MULADD(at[15], at[17]);
- COMBA_STORE(C->dp[16]);
- /* 17 */
- COMBA_FORWARD;
- MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); MULADD(at[14], at[19]); MULADD(at[15], at[18]);
- COMBA_STORE(C->dp[17]);
- /* 18 */
- COMBA_FORWARD;
- MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); MULADD(at[15], at[19]);
- COMBA_STORE(C->dp[18]);
- /* 19 */
- COMBA_FORWARD;
- MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); MULADD(at[15], at[20]);
- COMBA_STORE(C->dp[19]);
- /* 20 */
- COMBA_FORWARD;
- MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); MULADD(at[15], at[21]);
- COMBA_STORE(C->dp[20]);
- /* 21 */
- COMBA_FORWARD;
- MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); MULADD(at[15], at[22]);
- COMBA_STORE(C->dp[21]);
- /* 22 */
- COMBA_FORWARD;
- MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); MULADD(at[15], at[23]);
- COMBA_STORE(C->dp[22]);
- /* 23 */
- COMBA_FORWARD;
- MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]);
- COMBA_STORE(C->dp[23]);
- /* 24 */
- COMBA_FORWARD;
- MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]);
- COMBA_STORE(C->dp[24]);
- /* 25 */
- COMBA_FORWARD;
- MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]);
- COMBA_STORE(C->dp[25]);
- /* 26 */
- COMBA_FORWARD;
- MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]);
- COMBA_STORE(C->dp[26]);
- /* 27 */
- COMBA_FORWARD;
- MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]);
- COMBA_STORE(C->dp[27]);
- /* 28 */
- COMBA_FORWARD;
- MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]);
- COMBA_STORE(C->dp[28]);
- /* 29 */
- COMBA_FORWARD;
- MULADD(at[14], at[31]); MULADD(at[15], at[30]);
- COMBA_STORE(C->dp[29]);
- /* 30 */
- COMBA_FORWARD;
- MULADD(at[15], at[31]);
- COMBA_STORE(C->dp[30]);
- COMBA_STORE2(C->dp[31]);
- C->used = 32;
- C->sign = A->sign ^ B->sign;
- mp_clamp(C);
- COMBA_FINI;
-}
-
-void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C)
-{
- mp_digit c0, c1, c2, at[64];
-
- memcpy(at, A->dp, 32 * sizeof(mp_digit));
- memcpy(at+32, B->dp, 32 * sizeof(mp_digit));
- COMBA_START;
-
- COMBA_CLEAR;
- /* 0 */
- MULADD(at[0], at[32]);
- COMBA_STORE(C->dp[0]);
- /* 1 */
- COMBA_FORWARD;
- MULADD(at[0], at[33]); MULADD(at[1], at[32]);
- COMBA_STORE(C->dp[1]);
- /* 2 */
- COMBA_FORWARD;
- MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]);
- COMBA_STORE(C->dp[2]);
- /* 3 */
- COMBA_FORWARD;
- MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]);
- COMBA_STORE(C->dp[3]);
- /* 4 */
- COMBA_FORWARD;
- MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]);
- COMBA_STORE(C->dp[4]);
- /* 5 */
- COMBA_FORWARD;
- MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]);
- COMBA_STORE(C->dp[5]);
- /* 6 */
- COMBA_FORWARD;
- MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]);
- COMBA_STORE(C->dp[6]);
- /* 7 */
- COMBA_FORWARD;
- MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]);
- COMBA_STORE(C->dp[7]);
- /* 8 */
- COMBA_FORWARD;
- MULADD(at[0], at[40]); MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]);
- COMBA_STORE(C->dp[8]);
- /* 9 */
- COMBA_FORWARD;
- MULADD(at[0], at[41]); MULADD(at[1], at[40]); MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]);
- COMBA_STORE(C->dp[9]);
- /* 10 */
- COMBA_FORWARD;
- MULADD(at[0], at[42]); MULADD(at[1], at[41]); MULADD(at[2], at[40]); MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]);
- COMBA_STORE(C->dp[10]);
- /* 11 */
- COMBA_FORWARD;
- MULADD(at[0], at[43]); MULADD(at[1], at[42]); MULADD(at[2], at[41]); MULADD(at[3], at[40]); MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]);
- COMBA_STORE(C->dp[11]);
- /* 12 */
- COMBA_FORWARD;
- MULADD(at[0], at[44]); MULADD(at[1], at[43]); MULADD(at[2], at[42]); MULADD(at[3], at[41]); MULADD(at[4], at[40]); MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]);
- COMBA_STORE(C->dp[12]);
- /* 13 */
- COMBA_FORWARD;
- MULADD(at[0], at[45]); MULADD(at[1], at[44]); MULADD(at[2], at[43]); MULADD(at[3], at[42]); MULADD(at[4], at[41]); MULADD(at[5], at[40]); MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]);
- COMBA_STORE(C->dp[13]);
- /* 14 */
- COMBA_FORWARD;
- MULADD(at[0], at[46]); MULADD(at[1], at[45]); MULADD(at[2], at[44]); MULADD(at[3], at[43]); MULADD(at[4], at[42]); MULADD(at[5], at[41]); MULADD(at[6], at[40]); MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]);
- COMBA_STORE(C->dp[14]);
- /* 15 */
- COMBA_FORWARD;
- MULADD(at[0], at[47]); MULADD(at[1], at[46]); MULADD(at[2], at[45]); MULADD(at[3], at[44]); MULADD(at[4], at[43]); MULADD(at[5], at[42]); MULADD(at[6], at[41]); MULADD(at[7], at[40]); MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]);
- COMBA_STORE(C->dp[15]);
- /* 16 */
- COMBA_FORWARD;
- MULADD(at[0], at[48]); MULADD(at[1], at[47]); MULADD(at[2], at[46]); MULADD(at[3], at[45]); MULADD(at[4], at[44]); MULADD(at[5], at[43]); MULADD(at[6], at[42]); MULADD(at[7], at[41]); MULADD(at[8], at[40]); MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]);
- COMBA_STORE(C->dp[16]);
- /* 17 */
- COMBA_FORWARD;
- MULADD(at[0], at[49]); MULADD(at[1], at[48]); MULADD(at[2], at[47]); MULADD(at[3], at[46]); MULADD(at[4], at[45]); MULADD(at[5], at[44]); MULADD(at[6], at[43]); MULADD(at[7], at[42]); MULADD(at[8], at[41]); MULADD(at[9], at[40]); MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]);
- COMBA_STORE(C->dp[17]);
- /* 18 */
- COMBA_FORWARD;
- MULADD(at[0], at[50]); MULADD(at[1], at[49]); MULADD(at[2], at[48]); MULADD(at[3], at[47]); MULADD(at[4], at[46]); MULADD(at[5], at[45]); MULADD(at[6], at[44]); MULADD(at[7], at[43]); MULADD(at[8], at[42]); MULADD(at[9], at[41]); MULADD(at[10], at[40]); MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]);
- COMBA_STORE(C->dp[18]);
- /* 19 */
- COMBA_FORWARD;
- MULADD(at[0], at[51]); MULADD(at[1], at[50]); MULADD(at[2], at[49]); MULADD(at[3], at[48]); MULADD(at[4], at[47]); MULADD(at[5], at[46]); MULADD(at[6], at[45]); MULADD(at[7], at[44]); MULADD(at[8], at[43]); MULADD(at[9], at[42]); MULADD(at[10], at[41]); MULADD(at[11], at[40]); MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]);
- COMBA_STORE(C->dp[19]);
- /* 20 */
- COMBA_FORWARD;
- MULADD(at[0], at[52]); MULADD(at[1], at[51]); MULADD(at[2], at[50]); MULADD(at[3], at[49]); MULADD(at[4], at[48]); MULADD(at[5], at[47]); MULADD(at[6], at[46]); MULADD(at[7], at[45]); MULADD(at[8], at[44]); MULADD(at[9], at[43]); MULADD(at[10], at[42]); MULADD(at[11], at[41]); MULADD(at[12], at[40]); MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); MULADD(at[20], at[32]);
- COMBA_STORE(C->dp[20]);
- /* 21 */
- COMBA_FORWARD;
- MULADD(at[0], at[53]); MULADD(at[1], at[52]); MULADD(at[2], at[51]); MULADD(at[3], at[50]); MULADD(at[4], at[49]); MULADD(at[5], at[48]); MULADD(at[6], at[47]); MULADD(at[7], at[46]); MULADD(at[8], at[45]); MULADD(at[9], at[44]); MULADD(at[10], at[43]); MULADD(at[11], at[42]); MULADD(at[12], at[41]); MULADD(at[13], at[40]); MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); MULADD(at[20], at[33]); MULADD(at[21], at[32]);
- COMBA_STORE(C->dp[21]);
- /* 22 */
- COMBA_FORWARD;
- MULADD(at[0], at[54]); MULADD(at[1], at[53]); MULADD(at[2], at[52]); MULADD(at[3], at[51]); MULADD(at[4], at[50]); MULADD(at[5], at[49]); MULADD(at[6], at[48]); MULADD(at[7], at[47]); MULADD(at[8], at[46]); MULADD(at[9], at[45]); MULADD(at[10], at[44]); MULADD(at[11], at[43]); MULADD(at[12], at[42]); MULADD(at[13], at[41]); MULADD(at[14], at[40]); MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); MULADD(at[20], at[34]); MULADD(at[21], at[33]); MULADD(at[22], at[32]);
- COMBA_STORE(C->dp[22]);
- /* 23 */
- COMBA_FORWARD;
- MULADD(at[0], at[55]); MULADD(at[1], at[54]); MULADD(at[2], at[53]); MULADD(at[3], at[52]); MULADD(at[4], at[51]); MULADD(at[5], at[50]); MULADD(at[6], at[49]); MULADD(at[7], at[48]); MULADD(at[8], at[47]); MULADD(at[9], at[46]); MULADD(at[10], at[45]); MULADD(at[11], at[44]); MULADD(at[12], at[43]); MULADD(at[13], at[42]); MULADD(at[14], at[41]); MULADD(at[15], at[40]); MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); MULADD(at[20], at[35]); MULADD(at[21], at[34]); MULADD(at[22], at[33]); MULADD(at[23], at[32]);
- COMBA_STORE(C->dp[23]);
- /* 24 */
- COMBA_FORWARD;
- MULADD(at[0], at[56]); MULADD(at[1], at[55]); MULADD(at[2], at[54]); MULADD(at[3], at[53]); MULADD(at[4], at[52]); MULADD(at[5], at[51]); MULADD(at[6], at[50]); MULADD(at[7], at[49]); MULADD(at[8], at[48]); MULADD(at[9], at[47]); MULADD(at[10], at[46]); MULADD(at[11], at[45]); MULADD(at[12], at[44]); MULADD(at[13], at[43]); MULADD(at[14], at[42]); MULADD(at[15], at[41]); MULADD(at[16], at[40]); MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); MULADD(at[20], at[36]); MULADD(at[21], at[35]); MULADD(at[22], at[34]); MULADD(at[23], at[33]); MULADD(at[24], at[32]);
- COMBA_STORE(C->dp[24]);
- /* 25 */
- COMBA_FORWARD;
- MULADD(at[0], at[57]); MULADD(at[1], at[56]); MULADD(at[2], at[55]); MULADD(at[3], at[54]); MULADD(at[4], at[53]); MULADD(at[5], at[52]); MULADD(at[6], at[51]); MULADD(at[7], at[50]); MULADD(at[8], at[49]); MULADD(at[9], at[48]); MULADD(at[10], at[47]); MULADD(at[11], at[46]); MULADD(at[12], at[45]); MULADD(at[13], at[44]); MULADD(at[14], at[43]); MULADD(at[15], at[42]); MULADD(at[16], at[41]); MULADD(at[17], at[40]); MULADD(at[18], at[39]); MULADD(at[19], at[38]); MULADD(at[20], at[37]); MULADD(at[21], at[36]); MULADD(at[22], at[35]); MULADD(at[23], at[34]); MULADD(at[24], at[33]); MULADD(at[25], at[32]);
- COMBA_STORE(C->dp[25]);
- /* 26 */
- COMBA_FORWARD;
- MULADD(at[0], at[58]); MULADD(at[1], at[57]); MULADD(at[2], at[56]); MULADD(at[3], at[55]); MULADD(at[4], at[54]); MULADD(at[5], at[53]); MULADD(at[6], at[52]); MULADD(at[7], at[51]); MULADD(at[8], at[50]); MULADD(at[9], at[49]); MULADD(at[10], at[48]); MULADD(at[11], at[47]); MULADD(at[12], at[46]); MULADD(at[13], at[45]); MULADD(at[14], at[44]); MULADD(at[15], at[43]); MULADD(at[16], at[42]); MULADD(at[17], at[41]); MULADD(at[18], at[40]); MULADD(at[19], at[39]); MULADD(at[20], at[38]); MULADD(at[21], at[37]); MULADD(at[22], at[36]); MULADD(at[23], at[35]); MULADD(at[24], at[34]); MULADD(at[25], at[33]); MULADD(at[26], at[32]);
- COMBA_STORE(C->dp[26]);
- /* 27 */
- COMBA_FORWARD;
- MULADD(at[0], at[59]); MULADD(at[1], at[58]); MULADD(at[2], at[57]); MULADD(at[3], at[56]); MULADD(at[4], at[55]); MULADD(at[5], at[54]); MULADD(at[6], at[53]); MULADD(at[7], at[52]); MULADD(at[8], at[51]); MULADD(at[9], at[50]); MULADD(at[10], at[49]); MULADD(at[11], at[48]); MULADD(at[12], at[47]); MULADD(at[13], at[46]); MULADD(at[14], at[45]); MULADD(at[15], at[44]); MULADD(at[16], at[43]); MULADD(at[17], at[42]); MULADD(at[18], at[41]); MULADD(at[19], at[40]); MULADD(at[20], at[39]); MULADD(at[21], at[38]); MULADD(at[22], at[37]); MULADD(at[23], at[36]); MULADD(at[24], at[35]); MULADD(at[25], at[34]); MULADD(at[26], at[33]); MULADD(at[27], at[32]);
- COMBA_STORE(C->dp[27]);
- /* 28 */
- COMBA_FORWARD;
- MULADD(at[0], at[60]); MULADD(at[1], at[59]); MULADD(at[2], at[58]); MULADD(at[3], at[57]); MULADD(at[4], at[56]); MULADD(at[5], at[55]); MULADD(at[6], at[54]); MULADD(at[7], at[53]); MULADD(at[8], at[52]); MULADD(at[9], at[51]); MULADD(at[10], at[50]); MULADD(at[11], at[49]); MULADD(at[12], at[48]); MULADD(at[13], at[47]); MULADD(at[14], at[46]); MULADD(at[15], at[45]); MULADD(at[16], at[44]); MULADD(at[17], at[43]); MULADD(at[18], at[42]); MULADD(at[19], at[41]); MULADD(at[20], at[40]); MULADD(at[21], at[39]); MULADD(at[22], at[38]); MULADD(at[23], at[37]); MULADD(at[24], at[36]); MULADD(at[25], at[35]); MULADD(at[26], at[34]); MULADD(at[27], at[33]); MULADD(at[28], at[32]);
- COMBA_STORE(C->dp[28]);
- /* 29 */
- COMBA_FORWARD;
- MULADD(at[0], at[61]); MULADD(at[1], at[60]); MULADD(at[2], at[59]); MULADD(at[3], at[58]); MULADD(at[4], at[57]); MULADD(at[5], at[56]); MULADD(at[6], at[55]); MULADD(at[7], at[54]); MULADD(at[8], at[53]); MULADD(at[9], at[52]); MULADD(at[10], at[51]); MULADD(at[11], at[50]); MULADD(at[12], at[49]); MULADD(at[13], at[48]); MULADD(at[14], at[47]); MULADD(at[15], at[46]); MULADD(at[16], at[45]); MULADD(at[17], at[44]); MULADD(at[18], at[43]); MULADD(at[19], at[42]); MULADD(at[20], at[41]); MULADD(at[21], at[40]); MULADD(at[22], at[39]); MULADD(at[23], at[38]); MULADD(at[24], at[37]); MULADD(at[25], at[36]); MULADD(at[26], at[35]); MULADD(at[27], at[34]); MULADD(at[28], at[33]); MULADD(at[29], at[32]);
- COMBA_STORE(C->dp[29]);
- /* 30 */
- COMBA_FORWARD;
- MULADD(at[0], at[62]); MULADD(at[1], at[61]); MULADD(at[2], at[60]); MULADD(at[3], at[59]); MULADD(at[4], at[58]); MULADD(at[5], at[57]); MULADD(at[6], at[56]); MULADD(at[7], at[55]); MULADD(at[8], at[54]); MULADD(at[9], at[53]); MULADD(at[10], at[52]); MULADD(at[11], at[51]); MULADD(at[12], at[50]); MULADD(at[13], at[49]); MULADD(at[14], at[48]); MULADD(at[15], at[47]); MULADD(at[16], at[46]); MULADD(at[17], at[45]); MULADD(at[18], at[44]); MULADD(at[19], at[43]); MULADD(at[20], at[42]); MULADD(at[21], at[41]); MULADD(at[22], at[40]); MULADD(at[23], at[39]); MULADD(at[24], at[38]); MULADD(at[25], at[37]); MULADD(at[26], at[36]); MULADD(at[27], at[35]); MULADD(at[28], at[34]); MULADD(at[29], at[33]); MULADD(at[30], at[32]);
- COMBA_STORE(C->dp[30]);
- /* 31 */
- COMBA_FORWARD;
- MULADD(at[0], at[63]); MULADD(at[1], at[62]); MULADD(at[2], at[61]); MULADD(at[3], at[60]); MULADD(at[4], at[59]); MULADD(at[5], at[58]); MULADD(at[6], at[57]); MULADD(at[7], at[56]); MULADD(at[8], at[55]); MULADD(at[9], at[54]); MULADD(at[10], at[53]); MULADD(at[11], at[52]); MULADD(at[12], at[51]); MULADD(at[13], at[50]); MULADD(at[14], at[49]); MULADD(at[15], at[48]); MULADD(at[16], at[47]); MULADD(at[17], at[46]); MULADD(at[18], at[45]); MULADD(at[19], at[44]); MULADD(at[20], at[43]); MULADD(at[21], at[42]); MULADD(at[22], at[41]); MULADD(at[23], at[40]); MULADD(at[24], at[39]); MULADD(at[25], at[38]); MULADD(at[26], at[37]); MULADD(at[27], at[36]); MULADD(at[28], at[35]); MULADD(at[29], at[34]); MULADD(at[30], at[33]); MULADD(at[31], at[32]);
- COMBA_STORE(C->dp[31]);
- /* 32 */
- COMBA_FORWARD;
- MULADD(at[1], at[63]); MULADD(at[2], at[62]); MULADD(at[3], at[61]); MULADD(at[4], at[60]); MULADD(at[5], at[59]); MULADD(at[6], at[58]); MULADD(at[7], at[57]); MULADD(at[8], at[56]); MULADD(at[9], at[55]); MULADD(at[10], at[54]); MULADD(at[11], at[53]); MULADD(at[12], at[52]); MULADD(at[13], at[51]); MULADD(at[14], at[50]); MULADD(at[15], at[49]); MULADD(at[16], at[48]); MULADD(at[17], at[47]); MULADD(at[18], at[46]); MULADD(at[19], at[45]); MULADD(at[20], at[44]); MULADD(at[21], at[43]); MULADD(at[22], at[42]); MULADD(at[23], at[41]); MULADD(at[24], at[40]); MULADD(at[25], at[39]); MULADD(at[26], at[38]); MULADD(at[27], at[37]); MULADD(at[28], at[36]); MULADD(at[29], at[35]); MULADD(at[30], at[34]); MULADD(at[31], at[33]);
- COMBA_STORE(C->dp[32]);
- /* 33 */
- COMBA_FORWARD;
- MULADD(at[2], at[63]); MULADD(at[3], at[62]); MULADD(at[4], at[61]); MULADD(at[5], at[60]); MULADD(at[6], at[59]); MULADD(at[7], at[58]); MULADD(at[8], at[57]); MULADD(at[9], at[56]); MULADD(at[10], at[55]); MULADD(at[11], at[54]); MULADD(at[12], at[53]); MULADD(at[13], at[52]); MULADD(at[14], at[51]); MULADD(at[15], at[50]); MULADD(at[16], at[49]); MULADD(at[17], at[48]); MULADD(at[18], at[47]); MULADD(at[19], at[46]); MULADD(at[20], at[45]); MULADD(at[21], at[44]); MULADD(at[22], at[43]); MULADD(at[23], at[42]); MULADD(at[24], at[41]); MULADD(at[25], at[40]); MULADD(at[26], at[39]); MULADD(at[27], at[38]); MULADD(at[28], at[37]); MULADD(at[29], at[36]); MULADD(at[30], at[35]); MULADD(at[31], at[34]);
- COMBA_STORE(C->dp[33]);
- /* 34 */
- COMBA_FORWARD;
- MULADD(at[3], at[63]); MULADD(at[4], at[62]); MULADD(at[5], at[61]); MULADD(at[6], at[60]); MULADD(at[7], at[59]); MULADD(at[8], at[58]); MULADD(at[9], at[57]); MULADD(at[10], at[56]); MULADD(at[11], at[55]); MULADD(at[12], at[54]); MULADD(at[13], at[53]); MULADD(at[14], at[52]); MULADD(at[15], at[51]); MULADD(at[16], at[50]); MULADD(at[17], at[49]); MULADD(at[18], at[48]); MULADD(at[19], at[47]); MULADD(at[20], at[46]); MULADD(at[21], at[45]); MULADD(at[22], at[44]); MULADD(at[23], at[43]); MULADD(at[24], at[42]); MULADD(at[25], at[41]); MULADD(at[26], at[40]); MULADD(at[27], at[39]); MULADD(at[28], at[38]); MULADD(at[29], at[37]); MULADD(at[30], at[36]); MULADD(at[31], at[35]);
- COMBA_STORE(C->dp[34]);
- /* 35 */
- COMBA_FORWARD;
- MULADD(at[4], at[63]); MULADD(at[5], at[62]); MULADD(at[6], at[61]); MULADD(at[7], at[60]); MULADD(at[8], at[59]); MULADD(at[9], at[58]); MULADD(at[10], at[57]); MULADD(at[11], at[56]); MULADD(at[12], at[55]); MULADD(at[13], at[54]); MULADD(at[14], at[53]); MULADD(at[15], at[52]); MULADD(at[16], at[51]); MULADD(at[17], at[50]); MULADD(at[18], at[49]); MULADD(at[19], at[48]); MULADD(at[20], at[47]); MULADD(at[21], at[46]); MULADD(at[22], at[45]); MULADD(at[23], at[44]); MULADD(at[24], at[43]); MULADD(at[25], at[42]); MULADD(at[26], at[41]); MULADD(at[27], at[40]); MULADD(at[28], at[39]); MULADD(at[29], at[38]); MULADD(at[30], at[37]); MULADD(at[31], at[36]);
- COMBA_STORE(C->dp[35]);
- /* 36 */
- COMBA_FORWARD;
- MULADD(at[5], at[63]); MULADD(at[6], at[62]); MULADD(at[7], at[61]); MULADD(at[8], at[60]); MULADD(at[9], at[59]); MULADD(at[10], at[58]); MULADD(at[11], at[57]); MULADD(at[12], at[56]); MULADD(at[13], at[55]); MULADD(at[14], at[54]); MULADD(at[15], at[53]); MULADD(at[16], at[52]); MULADD(at[17], at[51]); MULADD(at[18], at[50]); MULADD(at[19], at[49]); MULADD(at[20], at[48]); MULADD(at[21], at[47]); MULADD(at[22], at[46]); MULADD(at[23], at[45]); MULADD(at[24], at[44]); MULADD(at[25], at[43]); MULADD(at[26], at[42]); MULADD(at[27], at[41]); MULADD(at[28], at[40]); MULADD(at[29], at[39]); MULADD(at[30], at[38]); MULADD(at[31], at[37]);
- COMBA_STORE(C->dp[36]);
- /* 37 */
- COMBA_FORWARD;
- MULADD(at[6], at[63]); MULADD(at[7], at[62]); MULADD(at[8], at[61]); MULADD(at[9], at[60]); MULADD(at[10], at[59]); MULADD(at[11], at[58]); MULADD(at[12], at[57]); MULADD(at[13], at[56]); MULADD(at[14], at[55]); MULADD(at[15], at[54]); MULADD(at[16], at[53]); MULADD(at[17], at[52]); MULADD(at[18], at[51]); MULADD(at[19], at[50]); MULADD(at[20], at[49]); MULADD(at[21], at[48]); MULADD(at[22], at[47]); MULADD(at[23], at[46]); MULADD(at[24], at[45]); MULADD(at[25], at[44]); MULADD(at[26], at[43]); MULADD(at[27], at[42]); MULADD(at[28], at[41]); MULADD(at[29], at[40]); MULADD(at[30], at[39]); MULADD(at[31], at[38]);
- COMBA_STORE(C->dp[37]);
- /* 38 */
- COMBA_FORWARD;
- MULADD(at[7], at[63]); MULADD(at[8], at[62]); MULADD(at[9], at[61]); MULADD(at[10], at[60]); MULADD(at[11], at[59]); MULADD(at[12], at[58]); MULADD(at[13], at[57]); MULADD(at[14], at[56]); MULADD(at[15], at[55]); MULADD(at[16], at[54]); MULADD(at[17], at[53]); MULADD(at[18], at[52]); MULADD(at[19], at[51]); MULADD(at[20], at[50]); MULADD(at[21], at[49]); MULADD(at[22], at[48]); MULADD(at[23], at[47]); MULADD(at[24], at[46]); MULADD(at[25], at[45]); MULADD(at[26], at[44]); MULADD(at[27], at[43]); MULADD(at[28], at[42]); MULADD(at[29], at[41]); MULADD(at[30], at[40]); MULADD(at[31], at[39]);
- COMBA_STORE(C->dp[38]);
- /* 39 */
- COMBA_FORWARD;
- MULADD(at[8], at[63]); MULADD(at[9], at[62]); MULADD(at[10], at[61]); MULADD(at[11], at[60]); MULADD(at[12], at[59]); MULADD(at[13], at[58]); MULADD(at[14], at[57]); MULADD(at[15], at[56]); MULADD(at[16], at[55]); MULADD(at[17], at[54]); MULADD(at[18], at[53]); MULADD(at[19], at[52]); MULADD(at[20], at[51]); MULADD(at[21], at[50]); MULADD(at[22], at[49]); MULADD(at[23], at[48]); MULADD(at[24], at[47]); MULADD(at[25], at[46]); MULADD(at[26], at[45]); MULADD(at[27], at[44]); MULADD(at[28], at[43]); MULADD(at[29], at[42]); MULADD(at[30], at[41]); MULADD(at[31], at[40]);
- COMBA_STORE(C->dp[39]);
- /* 40 */
- COMBA_FORWARD;
- MULADD(at[9], at[63]); MULADD(at[10], at[62]); MULADD(at[11], at[61]); MULADD(at[12], at[60]); MULADD(at[13], at[59]); MULADD(at[14], at[58]); MULADD(at[15], at[57]); MULADD(at[16], at[56]); MULADD(at[17], at[55]); MULADD(at[18], at[54]); MULADD(at[19], at[53]); MULADD(at[20], at[52]); MULADD(at[21], at[51]); MULADD(at[22], at[50]); MULADD(at[23], at[49]); MULADD(at[24], at[48]); MULADD(at[25], at[47]); MULADD(at[26], at[46]); MULADD(at[27], at[45]); MULADD(at[28], at[44]); MULADD(at[29], at[43]); MULADD(at[30], at[42]); MULADD(at[31], at[41]);
- COMBA_STORE(C->dp[40]);
- /* 41 */
- COMBA_FORWARD;
- MULADD(at[10], at[63]); MULADD(at[11], at[62]); MULADD(at[12], at[61]); MULADD(at[13], at[60]); MULADD(at[14], at[59]); MULADD(at[15], at[58]); MULADD(at[16], at[57]); MULADD(at[17], at[56]); MULADD(at[18], at[55]); MULADD(at[19], at[54]); MULADD(at[20], at[53]); MULADD(at[21], at[52]); MULADD(at[22], at[51]); MULADD(at[23], at[50]); MULADD(at[24], at[49]); MULADD(at[25], at[48]); MULADD(at[26], at[47]); MULADD(at[27], at[46]); MULADD(at[28], at[45]); MULADD(at[29], at[44]); MULADD(at[30], at[43]); MULADD(at[31], at[42]);
- COMBA_STORE(C->dp[41]);
- /* 42 */
- COMBA_FORWARD;
- MULADD(at[11], at[63]); MULADD(at[12], at[62]); MULADD(at[13], at[61]); MULADD(at[14], at[60]); MULADD(at[15], at[59]); MULADD(at[16], at[58]); MULADD(at[17], at[57]); MULADD(at[18], at[56]); MULADD(at[19], at[55]); MULADD(at[20], at[54]); MULADD(at[21], at[53]); MULADD(at[22], at[52]); MULADD(at[23], at[51]); MULADD(at[24], at[50]); MULADD(at[25], at[49]); MULADD(at[26], at[48]); MULADD(at[27], at[47]); MULADD(at[28], at[46]); MULADD(at[29], at[45]); MULADD(at[30], at[44]); MULADD(at[31], at[43]);
- COMBA_STORE(C->dp[42]);
- /* 43 */
- COMBA_FORWARD;
- MULADD(at[12], at[63]); MULADD(at[13], at[62]); MULADD(at[14], at[61]); MULADD(at[15], at[60]); MULADD(at[16], at[59]); MULADD(at[17], at[58]); MULADD(at[18], at[57]); MULADD(at[19], at[56]); MULADD(at[20], at[55]); MULADD(at[21], at[54]); MULADD(at[22], at[53]); MULADD(at[23], at[52]); MULADD(at[24], at[51]); MULADD(at[25], at[50]); MULADD(at[26], at[49]); MULADD(at[27], at[48]); MULADD(at[28], at[47]); MULADD(at[29], at[46]); MULADD(at[30], at[45]); MULADD(at[31], at[44]);
- COMBA_STORE(C->dp[43]);
- /* 44 */
- COMBA_FORWARD;
- MULADD(at[13], at[63]); MULADD(at[14], at[62]); MULADD(at[15], at[61]); MULADD(at[16], at[60]); MULADD(at[17], at[59]); MULADD(at[18], at[58]); MULADD(at[19], at[57]); MULADD(at[20], at[56]); MULADD(at[21], at[55]); MULADD(at[22], at[54]); MULADD(at[23], at[53]); MULADD(at[24], at[52]); MULADD(at[25], at[51]); MULADD(at[26], at[50]); MULADD(at[27], at[49]); MULADD(at[28], at[48]); MULADD(at[29], at[47]); MULADD(at[30], at[46]); MULADD(at[31], at[45]);
- COMBA_STORE(C->dp[44]);
- /* 45 */
- COMBA_FORWARD;
- MULADD(at[14], at[63]); MULADD(at[15], at[62]); MULADD(at[16], at[61]); MULADD(at[17], at[60]); MULADD(at[18], at[59]); MULADD(at[19], at[58]); MULADD(at[20], at[57]); MULADD(at[21], at[56]); MULADD(at[22], at[55]); MULADD(at[23], at[54]); MULADD(at[24], at[53]); MULADD(at[25], at[52]); MULADD(at[26], at[51]); MULADD(at[27], at[50]); MULADD(at[28], at[49]); MULADD(at[29], at[48]); MULADD(at[30], at[47]); MULADD(at[31], at[46]);
- COMBA_STORE(C->dp[45]);
- /* 46 */
- COMBA_FORWARD;
- MULADD(at[15], at[63]); MULADD(at[16], at[62]); MULADD(at[17], at[61]); MULADD(at[18], at[60]); MULADD(at[19], at[59]); MULADD(at[20], at[58]); MULADD(at[21], at[57]); MULADD(at[22], at[56]); MULADD(at[23], at[55]); MULADD(at[24], at[54]); MULADD(at[25], at[53]); MULADD(at[26], at[52]); MULADD(at[27], at[51]); MULADD(at[28], at[50]); MULADD(at[29], at[49]); MULADD(at[30], at[48]); MULADD(at[31], at[47]);
- COMBA_STORE(C->dp[46]);
- /* 47 */
- COMBA_FORWARD;
- MULADD(at[16], at[63]); MULADD(at[17], at[62]); MULADD(at[18], at[61]); MULADD(at[19], at[60]); MULADD(at[20], at[59]); MULADD(at[21], at[58]); MULADD(at[22], at[57]); MULADD(at[23], at[56]); MULADD(at[24], at[55]); MULADD(at[25], at[54]); MULADD(at[26], at[53]); MULADD(at[27], at[52]); MULADD(at[28], at[51]); MULADD(at[29], at[50]); MULADD(at[30], at[49]); MULADD(at[31], at[48]);
- COMBA_STORE(C->dp[47]);
- /* 48 */
- COMBA_FORWARD;
- MULADD(at[17], at[63]); MULADD(at[18], at[62]); MULADD(at[19], at[61]); MULADD(at[20], at[60]); MULADD(at[21], at[59]); MULADD(at[22], at[58]); MULADD(at[23], at[57]); MULADD(at[24], at[56]); MULADD(at[25], at[55]); MULADD(at[26], at[54]); MULADD(at[27], at[53]); MULADD(at[28], at[52]); MULADD(at[29], at[51]); MULADD(at[30], at[50]); MULADD(at[31], at[49]);
- COMBA_STORE(C->dp[48]);
- /* 49 */
- COMBA_FORWARD;
- MULADD(at[18], at[63]); MULADD(at[19], at[62]); MULADD(at[20], at[61]); MULADD(at[21], at[60]); MULADD(at[22], at[59]); MULADD(at[23], at[58]); MULADD(at[24], at[57]); MULADD(at[25], at[56]); MULADD(at[26], at[55]); MULADD(at[27], at[54]); MULADD(at[28], at[53]); MULADD(at[29], at[52]); MULADD(at[30], at[51]); MULADD(at[31], at[50]);
- COMBA_STORE(C->dp[49]);
- /* 50 */
- COMBA_FORWARD;
- MULADD(at[19], at[63]); MULADD(at[20], at[62]); MULADD(at[21], at[61]); MULADD(at[22], at[60]); MULADD(at[23], at[59]); MULADD(at[24], at[58]); MULADD(at[25], at[57]); MULADD(at[26], at[56]); MULADD(at[27], at[55]); MULADD(at[28], at[54]); MULADD(at[29], at[53]); MULADD(at[30], at[52]); MULADD(at[31], at[51]);
- COMBA_STORE(C->dp[50]);
- /* 51 */
- COMBA_FORWARD;
- MULADD(at[20], at[63]); MULADD(at[21], at[62]); MULADD(at[22], at[61]); MULADD(at[23], at[60]); MULADD(at[24], at[59]); MULADD(at[25], at[58]); MULADD(at[26], at[57]); MULADD(at[27], at[56]); MULADD(at[28], at[55]); MULADD(at[29], at[54]); MULADD(at[30], at[53]); MULADD(at[31], at[52]);
- COMBA_STORE(C->dp[51]);
- /* 52 */
- COMBA_FORWARD;
- MULADD(at[21], at[63]); MULADD(at[22], at[62]); MULADD(at[23], at[61]); MULADD(at[24], at[60]); MULADD(at[25], at[59]); MULADD(at[26], at[58]); MULADD(at[27], at[57]); MULADD(at[28], at[56]); MULADD(at[29], at[55]); MULADD(at[30], at[54]); MULADD(at[31], at[53]);
- COMBA_STORE(C->dp[52]);
- /* 53 */
- COMBA_FORWARD;
- MULADD(at[22], at[63]); MULADD(at[23], at[62]); MULADD(at[24], at[61]); MULADD(at[25], at[60]); MULADD(at[26], at[59]); MULADD(at[27], at[58]); MULADD(at[28], at[57]); MULADD(at[29], at[56]); MULADD(at[30], at[55]); MULADD(at[31], at[54]);
- COMBA_STORE(C->dp[53]);
- /* 54 */
- COMBA_FORWARD;
- MULADD(at[23], at[63]); MULADD(at[24], at[62]); MULADD(at[25], at[61]); MULADD(at[26], at[60]); MULADD(at[27], at[59]); MULADD(at[28], at[58]); MULADD(at[29], at[57]); MULADD(at[30], at[56]); MULADD(at[31], at[55]);
- COMBA_STORE(C->dp[54]);
- /* 55 */
- COMBA_FORWARD;
- MULADD(at[24], at[63]); MULADD(at[25], at[62]); MULADD(at[26], at[61]); MULADD(at[27], at[60]); MULADD(at[28], at[59]); MULADD(at[29], at[58]); MULADD(at[30], at[57]); MULADD(at[31], at[56]);
- COMBA_STORE(C->dp[55]);
- /* 56 */
- COMBA_FORWARD;
- MULADD(at[25], at[63]); MULADD(at[26], at[62]); MULADD(at[27], at[61]); MULADD(at[28], at[60]); MULADD(at[29], at[59]); MULADD(at[30], at[58]); MULADD(at[31], at[57]);
- COMBA_STORE(C->dp[56]);
- /* 57 */
- COMBA_FORWARD;
- MULADD(at[26], at[63]); MULADD(at[27], at[62]); MULADD(at[28], at[61]); MULADD(at[29], at[60]); MULADD(at[30], at[59]); MULADD(at[31], at[58]);
- COMBA_STORE(C->dp[57]);
- /* 58 */
- COMBA_FORWARD;
- MULADD(at[27], at[63]); MULADD(at[28], at[62]); MULADD(at[29], at[61]); MULADD(at[30], at[60]); MULADD(at[31], at[59]);
- COMBA_STORE(C->dp[58]);
- /* 59 */
- COMBA_FORWARD;
- MULADD(at[28], at[63]); MULADD(at[29], at[62]); MULADD(at[30], at[61]); MULADD(at[31], at[60]);
- COMBA_STORE(C->dp[59]);
- /* 60 */
- COMBA_FORWARD;
- MULADD(at[29], at[63]); MULADD(at[30], at[62]); MULADD(at[31], at[61]);
- COMBA_STORE(C->dp[60]);
- /* 61 */
- COMBA_FORWARD;
- MULADD(at[30], at[63]); MULADD(at[31], at[62]);
- COMBA_STORE(C->dp[61]);
- /* 62 */
- COMBA_FORWARD;
- MULADD(at[31], at[63]);
- COMBA_STORE(C->dp[62]);
- COMBA_STORE2(C->dp[63]);
- C->used = 64;
- C->sign = A->sign ^ B->sign;
- mp_clamp(C);
- COMBA_FINI;
-}
-
-
-
-void s_mp_sqr_comba_4(const mp_int *A, mp_int *B)
-{
- mp_digit *a, b[8], c0, c1, c2;
-
- a = A->dp;
- COMBA_START;
-
- /* clear carries */
- CLEAR_CARRY;
-
- /* output 0 */
- SQRADD(a[0],a[0]);
- COMBA_STORE(b[0]);
-
- /* output 1 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[1]);
- COMBA_STORE(b[1]);
-
- /* output 2 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
- COMBA_STORE(b[2]);
-
- /* output 3 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
- COMBA_STORE(b[3]);
-
- /* output 4 */
- CARRY_FORWARD;
- SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
- COMBA_STORE(b[4]);
-
- /* output 5 */
- CARRY_FORWARD;
- SQRADD2(a[2], a[3]);
- COMBA_STORE(b[5]);
-
- /* output 6 */
- CARRY_FORWARD;
- SQRADD(a[3], a[3]);
- COMBA_STORE(b[6]);
- COMBA_STORE2(b[7]);
- COMBA_FINI;
-
- B->used = 8;
- B->sign = ZPOS;
- memcpy(B->dp, b, 8 * sizeof(mp_digit));
- mp_clamp(B);
-}
-
-void s_mp_sqr_comba_8(const mp_int *A, mp_int *B)
-{
- mp_digit *a, b[16], c0, c1, c2, sc0, sc1, sc2;
-
- a = A->dp;
- COMBA_START;
-
- /* clear carries */
- CLEAR_CARRY;
-
- /* output 0 */
- SQRADD(a[0],a[0]);
- COMBA_STORE(b[0]);
-
- /* output 1 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[1]);
- COMBA_STORE(b[1]);
-
- /* output 2 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
- COMBA_STORE(b[2]);
-
- /* output 3 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
- COMBA_STORE(b[3]);
-
- /* output 4 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
- COMBA_STORE(b[4]);
-
- /* output 5 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
- COMBA_STORE(b[5]);
-
- /* output 6 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
- COMBA_STORE(b[6]);
-
- /* output 7 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
- COMBA_STORE(b[7]);
-
- /* output 8 */
- CARRY_FORWARD;
- SQRADDSC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
- COMBA_STORE(b[8]);
-
- /* output 9 */
- CARRY_FORWARD;
- SQRADDSC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
- COMBA_STORE(b[9]);
-
- /* output 10 */
- CARRY_FORWARD;
- SQRADD2(a[3], a[7]); SQRADD2(a[4], a[6]); SQRADD(a[5], a[5]);
- COMBA_STORE(b[10]);
-
- /* output 11 */
- CARRY_FORWARD;
- SQRADD2(a[4], a[7]); SQRADD2(a[5], a[6]);
- COMBA_STORE(b[11]);
-
- /* output 12 */
- CARRY_FORWARD;
- SQRADD2(a[5], a[7]); SQRADD(a[6], a[6]);
- COMBA_STORE(b[12]);
-
- /* output 13 */
- CARRY_FORWARD;
- SQRADD2(a[6], a[7]);
- COMBA_STORE(b[13]);
-
- /* output 14 */
- CARRY_FORWARD;
- SQRADD(a[7], a[7]);
- COMBA_STORE(b[14]);
- COMBA_STORE2(b[15]);
- COMBA_FINI;
-
- B->used = 16;
- B->sign = ZPOS;
- memcpy(B->dp, b, 16 * sizeof(mp_digit));
- mp_clamp(B);
-}
-
-void s_mp_sqr_comba_16(const mp_int *A, mp_int *B)
-{
- mp_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2;
-
- a = A->dp;
- COMBA_START;
-
- /* clear carries */
- CLEAR_CARRY;
-
- /* output 0 */
- SQRADD(a[0],a[0]);
- COMBA_STORE(b[0]);
-
- /* output 1 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[1]);
- COMBA_STORE(b[1]);
-
- /* output 2 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
- COMBA_STORE(b[2]);
-
- /* output 3 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
- COMBA_STORE(b[3]);
-
- /* output 4 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
- COMBA_STORE(b[4]);
-
- /* output 5 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
- COMBA_STORE(b[5]);
-
- /* output 6 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
- COMBA_STORE(b[6]);
-
- /* output 7 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
- COMBA_STORE(b[7]);
-
- /* output 8 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
- COMBA_STORE(b[8]);
-
- /* output 9 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
- COMBA_STORE(b[9]);
-
- /* output 10 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]);
- COMBA_STORE(b[10]);
-
- /* output 11 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB;
- COMBA_STORE(b[11]);
-
- /* output 12 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]);
- COMBA_STORE(b[12]);
-
- /* output 13 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB;
- COMBA_STORE(b[13]);
-
- /* output 14 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]);
- COMBA_STORE(b[14]);
-
- /* output 15 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB;
- COMBA_STORE(b[15]);
-
- /* output 16 */
- CARRY_FORWARD;
- SQRADDSC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]);
- COMBA_STORE(b[16]);
-
- /* output 17 */
- CARRY_FORWARD;
- SQRADDSC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB;
- COMBA_STORE(b[17]);
-
- /* output 18 */
- CARRY_FORWARD;
- SQRADDSC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]);
- COMBA_STORE(b[18]);
-
- /* output 19 */
- CARRY_FORWARD;
- SQRADDSC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB;
- COMBA_STORE(b[19]);
-
- /* output 20 */
- CARRY_FORWARD;
- SQRADDSC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]);
- COMBA_STORE(b[20]);
-
- /* output 21 */
- CARRY_FORWARD;
- SQRADDSC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB;
- COMBA_STORE(b[21]);
-
- /* output 22 */
- CARRY_FORWARD;
- SQRADDSC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]);
- COMBA_STORE(b[22]);
-
- /* output 23 */
- CARRY_FORWARD;
- SQRADDSC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB;
- COMBA_STORE(b[23]);
-
- /* output 24 */
- CARRY_FORWARD;
- SQRADDSC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]);
- COMBA_STORE(b[24]);
-
- /* output 25 */
- CARRY_FORWARD;
- SQRADDSC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB;
- COMBA_STORE(b[25]);
-
- /* output 26 */
- CARRY_FORWARD;
- SQRADD2(a[11], a[15]); SQRADD2(a[12], a[14]); SQRADD(a[13], a[13]);
- COMBA_STORE(b[26]);
-
- /* output 27 */
- CARRY_FORWARD;
- SQRADD2(a[12], a[15]); SQRADD2(a[13], a[14]);
- COMBA_STORE(b[27]);
-
- /* output 28 */
- CARRY_FORWARD;
- SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]);
- COMBA_STORE(b[28]);
-
- /* output 29 */
- CARRY_FORWARD;
- SQRADD2(a[14], a[15]);
- COMBA_STORE(b[29]);
-
- /* output 30 */
- CARRY_FORWARD;
- SQRADD(a[15], a[15]);
- COMBA_STORE(b[30]);
- COMBA_STORE2(b[31]);
- COMBA_FINI;
-
- B->used = 32;
- B->sign = ZPOS;
- memcpy(B->dp, b, 32 * sizeof(mp_digit));
- mp_clamp(B);
-}
-
-
-void s_mp_sqr_comba_32(const mp_int *A, mp_int *B)
-{
- mp_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2;
-
- a = A->dp;
- COMBA_START;
-
- /* clear carries */
- CLEAR_CARRY;
-
- /* output 0 */
- SQRADD(a[0],a[0]);
- COMBA_STORE(b[0]);
-
- /* output 1 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[1]);
- COMBA_STORE(b[1]);
-
- /* output 2 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
- COMBA_STORE(b[2]);
-
- /* output 3 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
- COMBA_STORE(b[3]);
-
- /* output 4 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
- COMBA_STORE(b[4]);
-
- /* output 5 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
- COMBA_STORE(b[5]);
-
- /* output 6 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
- COMBA_STORE(b[6]);
-
- /* output 7 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
- COMBA_STORE(b[7]);
-
- /* output 8 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
- COMBA_STORE(b[8]);
-
- /* output 9 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
- COMBA_STORE(b[9]);
-
- /* output 10 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]);
- COMBA_STORE(b[10]);
-
- /* output 11 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB;
- COMBA_STORE(b[11]);
-
- /* output 12 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]);
- COMBA_STORE(b[12]);
-
- /* output 13 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB;
- COMBA_STORE(b[13]);
-
- /* output 14 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]);
- COMBA_STORE(b[14]);
-
- /* output 15 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB;
- COMBA_STORE(b[15]);
-
- /* output 16 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]);
- COMBA_STORE(b[16]);
-
- /* output 17 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB;
- COMBA_STORE(b[17]);
-
- /* output 18 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]);
- COMBA_STORE(b[18]);
-
- /* output 19 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB;
- COMBA_STORE(b[19]);
-
- /* output 20 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]);
- COMBA_STORE(b[20]);
-
- /* output 21 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB;
- COMBA_STORE(b[21]);
-
- /* output 22 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]);
- COMBA_STORE(b[22]);
-
- /* output 23 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB;
- COMBA_STORE(b[23]);
-
- /* output 24 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]);
- COMBA_STORE(b[24]);
-
- /* output 25 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB;
- COMBA_STORE(b[25]);
-
- /* output 26 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]);
- COMBA_STORE(b[26]);
-
- /* output 27 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB;
- COMBA_STORE(b[27]);
-
- /* output 28 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]);
- COMBA_STORE(b[28]);
-
- /* output 29 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB;
- COMBA_STORE(b[29]);
-
- /* output 30 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]);
- COMBA_STORE(b[30]);
-
- /* output 31 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB;
- COMBA_STORE(b[31]);
-
- /* output 32 */
- CARRY_FORWARD;
- SQRADDSC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]);
- COMBA_STORE(b[32]);
-
- /* output 33 */
- CARRY_FORWARD;
- SQRADDSC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB;
- COMBA_STORE(b[33]);
-
- /* output 34 */
- CARRY_FORWARD;
- SQRADDSC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]);
- COMBA_STORE(b[34]);
-
- /* output 35 */
- CARRY_FORWARD;
- SQRADDSC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB;
- COMBA_STORE(b[35]);
-
- /* output 36 */
- CARRY_FORWARD;
- SQRADDSC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]);
- COMBA_STORE(b[36]);
-
- /* output 37 */
- CARRY_FORWARD;
- SQRADDSC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB;
- COMBA_STORE(b[37]);
-
- /* output 38 */
- CARRY_FORWARD;
- SQRADDSC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]);
- COMBA_STORE(b[38]);
-
- /* output 39 */
- CARRY_FORWARD;
- SQRADDSC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB;
- COMBA_STORE(b[39]);
-
- /* output 40 */
- CARRY_FORWARD;
- SQRADDSC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]);
- COMBA_STORE(b[40]);
-
- /* output 41 */
- CARRY_FORWARD;
- SQRADDSC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB;
- COMBA_STORE(b[41]);
-
- /* output 42 */
- CARRY_FORWARD;
- SQRADDSC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]);
- COMBA_STORE(b[42]);
-
- /* output 43 */
- CARRY_FORWARD;
- SQRADDSC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB;
- COMBA_STORE(b[43]);
-
- /* output 44 */
- CARRY_FORWARD;
- SQRADDSC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]);
- COMBA_STORE(b[44]);
-
- /* output 45 */
- CARRY_FORWARD;
- SQRADDSC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB;
- COMBA_STORE(b[45]);
-
- /* output 46 */
- CARRY_FORWARD;
- SQRADDSC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]);
- COMBA_STORE(b[46]);
-
- /* output 47 */
- CARRY_FORWARD;
- SQRADDSC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB;
- COMBA_STORE(b[47]);
-
- /* output 48 */
- CARRY_FORWARD;
- SQRADDSC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]);
- COMBA_STORE(b[48]);
-
- /* output 49 */
- CARRY_FORWARD;
- SQRADDSC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB;
- COMBA_STORE(b[49]);
-
- /* output 50 */
- CARRY_FORWARD;
- SQRADDSC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]);
- COMBA_STORE(b[50]);
-
- /* output 51 */
- CARRY_FORWARD;
- SQRADDSC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB;
- COMBA_STORE(b[51]);
-
- /* output 52 */
- CARRY_FORWARD;
- SQRADDSC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]);
- COMBA_STORE(b[52]);
-
- /* output 53 */
- CARRY_FORWARD;
- SQRADDSC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB;
- COMBA_STORE(b[53]);
-
- /* output 54 */
- CARRY_FORWARD;
- SQRADDSC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]);
- COMBA_STORE(b[54]);
-
- /* output 55 */
- CARRY_FORWARD;
- SQRADDSC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB;
- COMBA_STORE(b[55]);
-
- /* output 56 */
- CARRY_FORWARD;
- SQRADDSC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]);
- COMBA_STORE(b[56]);
-
- /* output 57 */
- CARRY_FORWARD;
- SQRADDSC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB;
- COMBA_STORE(b[57]);
-
- /* output 58 */
- CARRY_FORWARD;
- SQRADD2(a[27], a[31]); SQRADD2(a[28], a[30]); SQRADD(a[29], a[29]);
- COMBA_STORE(b[58]);
-
- /* output 59 */
- CARRY_FORWARD;
- SQRADD2(a[28], a[31]); SQRADD2(a[29], a[30]);
- COMBA_STORE(b[59]);
-
- /* output 60 */
- CARRY_FORWARD;
- SQRADD2(a[29], a[31]); SQRADD(a[30], a[30]);
- COMBA_STORE(b[60]);
-
- /* output 61 */
- CARRY_FORWARD;
- SQRADD2(a[30], a[31]);
- COMBA_STORE(b[61]);
-
- /* output 62 */
- CARRY_FORWARD;
- SQRADD(a[31], a[31]);
- COMBA_STORE(b[62]);
- COMBA_STORE2(b[63]);
- COMBA_FINI;
-
- B->used = 64;
- B->sign = ZPOS;
- memcpy(B->dp, b, 64 * sizeof(mp_digit));
- mp_clamp(B);
-}
diff --git a/security/nss/lib/freebl/mpi/mp_comba_amd64_masm.asm b/security/nss/lib/freebl/mpi/mp_comba_amd64_masm.asm
deleted file mode 100644
index ead73bbeb..000000000
--- a/security/nss/lib/freebl/mpi/mp_comba_amd64_masm.asm
+++ /dev/null
@@ -1,13066 +0,0 @@
-; This Source Code Form is subject to the terms of the Mozilla Public
-; License, v. 2.0. If a copy of the MPL was not distributed with this
-; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-;/* TomsFastMath, a fast ISO C bignum library.
-; *
-; * This project is meant to fill in where LibTomMath
-; * falls short. That is speed ;-)
-; *
-; * This project is public domain and free for all purposes.
-; *
-; * Tom St Denis, tomstdenis@iahu.ca
-; */
-
-;/*
-; * The source file from which this assembly was derived
-; * comes from TFM v0.03, which has the above license.
-; * This source was from mp_comba_amd64.sun.s and convert to
-; * MASM code set.
-; */
-
-.CODE
-
-externdef memcpy:PROC
-
-public s_mp_mul_comba_4
-public s_mp_mul_comba_8
-public s_mp_mul_comba_16
-public s_mp_mul_comba_32
-public s_mp_sqr_comba_8
-public s_mp_sqr_comba_16
-public s_mp_sqr_comba_32
-
-
-; void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C)
-
- ALIGN 16
-s_mp_mul_comba_4 PROC
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
- mov rdx, r8
-
- push r12
- push rbp
- push rbx
- sub rsp, 64
- mov r9, qword ptr [16+rdi]
- mov rbx, rdx
- mov rdx, qword ptr [16+rsi]
- mov rax, qword ptr [r9]
- mov qword ptr [-64+64+rsp], rax
- mov r8, qword ptr [8+r9]
- mov qword ptr [-56+64+rsp], r8
- mov rbp, qword ptr [16+r9]
- mov qword ptr [-48+64+rsp], rbp
- mov r12, qword ptr [24+r9]
- mov qword ptr [-40+64+rsp], r12
- mov rcx, qword ptr [rdx]
- mov qword ptr [-32+64+rsp], rcx
- mov r10, qword ptr [8+rdx]
- mov qword ptr [-24+64+rsp], r10
- mov r11, qword ptr [16+rdx]
- xor r10d, r10d
- mov r8, r10
- mov r9, r10
- mov rbp, r10
- mov qword ptr [-16+64+rsp], r11
- mov r11, qword ptr [16+rbx]
- mov rax, qword ptr [24+rdx]
- mov qword ptr [-8+64+rsp], rax
- mov rax, qword ptr [-64+64+rsp]
- mul qword ptr [-32+64+rsp]
- add r8, rax
- adc r9, rdx
- adc rbp, 0
- mov qword ptr [r11], r8
- mov r8, rbp
- mov rbp, r10
- mov rax, qword ptr [-64+64+rsp]
- mul qword ptr [-24+64+rsp]
- add r9, rax
- adc r8, rdx
- adc rbp, 0
- mov r12, rbp
- mov rax, qword ptr [-56+64+rsp]
- mul qword ptr [-32+64+rsp]
- add r9, rax
- adc r8, rdx
- adc r12, 0
- mov qword ptr [8+r11], r9
- mov r9, r12
- mov r12, r10
- mov rax, qword ptr [-64+64+rsp]
- mul qword ptr [-16+64+rsp]
- add r8, rax
- adc r9, rdx
- adc r12, 0
- mov rcx, r12
- mov rax, qword ptr [-56+64+rsp]
- mul qword ptr [-24+64+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-48+64+rsp]
- mul qword ptr [-32+64+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [16+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-64+64+rsp]
- mul qword ptr [-8+64+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-56+64+rsp]
- mul qword ptr [-16+64+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-48+64+rsp]
- mul qword ptr [-24+64+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-40+64+rsp]
- mul qword ptr [-32+64+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [24+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-56+64+rsp]
- mul qword ptr [-8+64+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-48+64+rsp]
- mul qword ptr [-16+64+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-40+64+rsp]
- mul qword ptr [-24+64+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [32+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-48+64+rsp]
- mul qword ptr [-8+64+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov r12, r8
- mov rbp, r9
- mov rax, qword ptr [-40+64+rsp]
- mul qword ptr [-16+64+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [40+r11], rcx
- mov r8, rbp
- mov rcx, r12
- mov rax, qword ptr [-40+64+rsp]
- mul qword ptr [-8+64+rsp]
- add r8, rax
- adc rcx, rdx
- adc r10, 0
- mov qword ptr [48+r11], r8
- mov esi, dword ptr [rsi]
- xor esi, dword ptr [rdi]
- test rcx, rcx
- mov qword ptr [56+r11], rcx
- mov dword ptr [8+rbx], 8
- jne L9
- ALIGN 16
-L18:
- mov edx, dword ptr [8+rbx]
- lea edi, dword ptr [-1+rdx]
- test edi, edi
- mov dword ptr [8+rbx], edi
- je L9
- lea r10d, dword ptr [-2+rdx]
- cmp dword ptr [r11+r10*8], 0
- je L18
-L9:
- mov edx, dword ptr [8+rbx]
- xor r11d, r11d
- test edx, edx
- cmovne r11d, esi
- mov dword ptr [rbx], r11d
- add rsp, 64
- pop rbx
- pop rbp
- pop r12
-
- pop rsi
- pop rdi
-
- ret
-
-s_mp_mul_comba_4 ENDP
-
-
-; void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C)
-
- ALIGN 16
-s_mp_mul_comba_8 PROC
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
- mov rdx, r8
-
- push r12
- push rbp
- push rbx
- mov rbx, rdx
- sub rsp, 8+128
- mov rdx, qword ptr [16+rdi]
- mov r8, qword ptr [rdx]
- mov qword ptr [-120+128+rsp], r8
- mov rbp, qword ptr [8+rdx]
- mov qword ptr [-112+128+rsp], rbp
- mov r9, qword ptr [16+rdx]
- mov qword ptr [-104+128+rsp], r9
- mov r12, qword ptr [24+rdx]
- mov qword ptr [-96+128+rsp], r12
- mov rcx, qword ptr [32+rdx]
- mov qword ptr [-88+128+rsp], rcx
- mov r10, qword ptr [40+rdx]
- mov qword ptr [-80+128+rsp], r10
- mov r11, qword ptr [48+rdx]
- mov qword ptr [-72+128+rsp], r11
- mov rax, qword ptr [56+rdx]
- mov rdx, qword ptr [16+rsi]
- mov qword ptr [-64+128+rsp], rax
- mov r8, qword ptr [rdx]
- mov qword ptr [-56+128+rsp], r8
- mov rbp, qword ptr [8+rdx]
- mov qword ptr [-48+128+rsp], rbp
- mov r9, qword ptr [16+rdx]
- mov qword ptr [-40+128+rsp], r9
- mov r12, qword ptr [24+rdx]
- mov qword ptr [-32+128+rsp], r12
- mov rcx, qword ptr [32+rdx]
- mov qword ptr [-24+128+rsp], rcx
- mov r10, qword ptr [40+rdx]
- mov qword ptr [-16+128+rsp], r10
- mov r11, qword ptr [48+rdx]
- xor r10d, r10d
- mov r8, r10
- mov r9, r10
- mov rbp, r10
- mov qword ptr [-8+128+rsp], r11
- mov r11, qword ptr [16+rbx]
- mov rax, qword ptr [56+rdx]
- mov qword ptr [128+rsp], rax
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [-56+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rbp, 0
- mov qword ptr [r11], r8
- mov r8, rbp
- mov rbp, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [-48+128+rsp]
- add r9, rax
- adc r8, rdx
- adc rbp, 0
- mov r12, rbp
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [-56+128+rsp]
- add r9, rax
- adc r8, rdx
- adc r12, 0
- mov qword ptr [8+r11], r9
- mov r9, r12
- mov r12, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [-40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc r12, 0
- mov rcx, r12
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [-48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [-56+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [16+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [-32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [-40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [-48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [-56+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [24+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [-24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [-32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [-40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [-48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [-56+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [32+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [-16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [-24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [-32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [-40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [-48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [-56+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [40+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [-8+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [-16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [-24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [-32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [-40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [-48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [-56+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [48+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [-8+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [-16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [-24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [-32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [-40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [-48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [-56+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [56+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [-8+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [-16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [-24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [-32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [-40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [-48+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [64+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [-8+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [-16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [-24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [-32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [-40+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [72+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [-8+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [-16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [-24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [-32+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [80+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [-8+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [-16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [-24+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [88+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [-8+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [-16+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [96+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov r12, r8
- mov rbp, r9
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [-8+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [104+r11], rcx
- mov r8, rbp
- mov rcx, r12
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [128+rsp]
- add r8, rax
- adc rcx, rdx
- adc r10, 0
- mov qword ptr [112+r11], r8
- mov esi, dword ptr [rsi]
- xor esi, dword ptr [rdi]
- test rcx, rcx
- mov qword ptr [120+r11], rcx
- mov dword ptr [8+rbx], 16
- jne L35
- ALIGN 16
-L43:
- mov edx, dword ptr [8+rbx]
- lea edi, dword ptr [-1+rdx]
- test edi, edi
- mov dword ptr [8+rbx], edi
- je L35
- lea eax, dword ptr [-2+rdx]
- cmp dword ptr [r11+rax*8], 0
- je L43
-L35:
- mov r11d, dword ptr [8+rbx]
- xor edx, edx
- test r11d, r11d
- cmovne edx, esi
- mov dword ptr [rbx], edx
- add rsp, 8+128
- pop rbx
- pop rbp
- pop r12
-
- pop rsi
- pop rdi
-
- ret
-
-s_mp_mul_comba_8 ENDP
-
-
-; void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C);
-
- ALIGN 16
-s_mp_mul_comba_16 PROC
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
- mov rdx, r8
-
- push r12
- push rbp
- push rbx
- mov rbx, rdx
- sub rsp, 136+128
- mov rax, qword ptr [16+rdi]
- mov r8, qword ptr [rax]
- mov qword ptr [-120+128+rsp], r8
- mov rbp, qword ptr [8+rax]
- mov qword ptr [-112+128+rsp], rbp
- mov r9, qword ptr [16+rax]
- mov qword ptr [-104+128+rsp], r9
- mov r12, qword ptr [24+rax]
- mov qword ptr [-96+128+rsp], r12
- mov rcx, qword ptr [32+rax]
- mov qword ptr [-88+128+rsp], rcx
- mov r10, qword ptr [40+rax]
- mov qword ptr [-80+128+rsp], r10
- mov rdx, qword ptr [48+rax]
- mov qword ptr [-72+128+rsp], rdx
- mov r11, qword ptr [56+rax]
- mov qword ptr [-64+128+rsp], r11
- mov r8, qword ptr [64+rax]
- mov qword ptr [-56+128+rsp], r8
- mov rbp, qword ptr [72+rax]
- mov qword ptr [-48+128+rsp], rbp
- mov r9, qword ptr [80+rax]
- mov qword ptr [-40+128+rsp], r9
- mov r12, qword ptr [88+rax]
- mov qword ptr [-32+128+rsp], r12
- mov rcx, qword ptr [96+rax]
- mov qword ptr [-24+128+rsp], rcx
- mov r10, qword ptr [104+rax]
- mov qword ptr [-16+128+rsp], r10
- mov rdx, qword ptr [112+rax]
- mov qword ptr [-8+128+rsp], rdx
- mov r11, qword ptr [120+rax]
- mov qword ptr [128+rsp], r11
- mov r11, qword ptr [16+rsi]
- mov r8, qword ptr [r11]
- mov qword ptr [8+128+rsp], r8
- mov rbp, qword ptr [8+r11]
- mov qword ptr [16+128+rsp], rbp
- mov r9, qword ptr [16+r11]
- mov qword ptr [24+128+rsp], r9
- mov r12, qword ptr [24+r11]
- mov qword ptr [32+128+rsp], r12
- mov rcx, qword ptr [32+r11]
- mov qword ptr [40+128+rsp], rcx
- mov r10, qword ptr [40+r11]
- mov qword ptr [48+128+rsp], r10
- mov rdx, qword ptr [48+r11]
- mov qword ptr [56+128+rsp], rdx
- mov rax, qword ptr [56+r11]
- mov qword ptr [64+128+rsp], rax
- mov r8, qword ptr [64+r11]
- mov qword ptr [72+128+rsp], r8
- mov rbp, qword ptr [72+r11]
- mov qword ptr [80+128+rsp], rbp
- mov r9, qword ptr [80+r11]
- mov qword ptr [88+128+rsp], r9
- mov r12, qword ptr [88+r11]
- mov qword ptr [96+128+rsp], r12
- mov rcx, qword ptr [96+r11]
- mov qword ptr [104+128+rsp], rcx
- mov r10, qword ptr [104+r11]
- mov qword ptr [112+128+rsp], r10
- mov rdx, qword ptr [112+r11]
- xor r10d, r10d
- mov r8, r10
- mov r9, r10
- mov rbp, r10
- mov qword ptr [120+128+rsp], rdx
- mov rax, qword ptr [120+r11]
- mov qword ptr [128+128+rsp], rax
- mov r11, qword ptr [16+rbx]
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [8+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rbp, 0
- mov qword ptr [r11], r8
- mov r8, rbp
- mov rbp, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [16+128+rsp]
- add r9, rax
- adc r8, rdx
- adc rbp, 0
- mov r12, rbp
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [8+128+rsp]
- add r9, rax
- adc r8, rdx
- adc r12, 0
- mov qword ptr [8+r11], r9
- mov r9, r12
- mov r12, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc r12, 0
- mov rcx, r12
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [8+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [16+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [8+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [24+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [8+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [32+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [8+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [40+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [56+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [8+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [48+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [64+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [56+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [8+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [56+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [72+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [64+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [56+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [8+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [64+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [80+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [72+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [64+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [56+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [8+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [72+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [88+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [80+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [72+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [64+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [56+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [8+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [80+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [96+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [88+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [80+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [72+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [64+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [56+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [8+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [88+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [104+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [96+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [88+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [80+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [72+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [64+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [56+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [8+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [96+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [112+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [104+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [96+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [88+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [80+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [72+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [64+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [56+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [8+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [104+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [120+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [112+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [104+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [96+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [88+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [80+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [72+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [64+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [56+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [16+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [8+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [112+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-120+128+rsp]
- mul qword ptr [128+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [120+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [112+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [104+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [96+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [88+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [80+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [72+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [64+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [56+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [24+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [16+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [128+rsp]
- mul qword ptr [8+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [120+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-112+128+rsp]
- mul qword ptr [128+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [120+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [112+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [104+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [96+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [88+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [80+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [72+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [64+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [56+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [32+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [24+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [128+rsp]
- mul qword ptr [16+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [128+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-104+128+rsp]
- mul qword ptr [128+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [120+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [112+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [104+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [96+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [88+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [80+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [72+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [64+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [56+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [40+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [32+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [128+rsp]
- mul qword ptr [24+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [136+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-96+128+rsp]
- mul qword ptr [128+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [120+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [112+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [104+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [96+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [88+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [80+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [72+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [64+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [56+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [48+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [40+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [128+rsp]
- mul qword ptr [32+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [144+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-88+128+rsp]
- mul qword ptr [128+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [120+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [112+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [104+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [96+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [88+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [80+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [72+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [64+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [56+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [48+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [128+rsp]
- mul qword ptr [40+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [152+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-80+128+rsp]
- mul qword ptr [128+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [120+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [112+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [104+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [96+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [88+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [80+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [72+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [64+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [56+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [128+rsp]
- mul qword ptr [48+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [160+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-72+128+rsp]
- mul qword ptr [128+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [120+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [112+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [104+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [96+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [88+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [80+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [72+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [64+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [128+rsp]
- mul qword ptr [56+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [168+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-64+128+rsp]
- mul qword ptr [128+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [120+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [112+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [104+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [96+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [88+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [80+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [72+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [128+rsp]
- mul qword ptr [64+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [176+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-56+128+rsp]
- mul qword ptr [128+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [120+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [112+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [104+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [96+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [88+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [80+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [128+rsp]
- mul qword ptr [72+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [184+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-48+128+rsp]
- mul qword ptr [128+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [120+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [112+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [104+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [96+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [88+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [128+rsp]
- mul qword ptr [80+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [192+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-40+128+rsp]
- mul qword ptr [128+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [120+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [112+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [104+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [96+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [128+rsp]
- mul qword ptr [88+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [200+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-32+128+rsp]
- mul qword ptr [128+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [120+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [112+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [104+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [128+rsp]
- mul qword ptr [96+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [208+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-24+128+rsp]
- mul qword ptr [128+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [120+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [112+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov rbp, r9
- mov r12, r8
- mov rax, qword ptr [128+rsp]
- mul qword ptr [104+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [216+r11], rcx
- mov r9, r12
- mov r8, rbp
- mov rcx, r10
- mov rax, qword ptr [-16+128+rsp]
- mul qword ptr [128+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [120+128+rsp]
- add r8, rax
- adc r9, rdx
- adc rcx, 0
- mov rbp, r9
- mov r12, rcx
- mov rax, qword ptr [128+rsp]
- mul qword ptr [112+128+rsp]
- add r8, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [224+r11], r8
- mov r9, r12
- mov rcx, rbp
- mov r8, r10
- mov rax, qword ptr [-8+128+rsp]
- mul qword ptr [128+128+rsp]
- add rcx, rax
- adc r9, rdx
- adc r8, 0
- mov r12, r8
- mov rbp, r9
- mov rax, qword ptr [128+rsp]
- mul qword ptr [120+128+rsp]
- add rcx, rax
- adc rbp, rdx
- adc r12, 0
- mov qword ptr [232+r11], rcx
- mov r8, rbp
- mov rcx, r12
- mov rax, qword ptr [128+rsp]
- mul qword ptr [128+128+rsp]
- add r8, rax
- adc rcx, rdx
- adc r10, 0
- mov qword ptr [240+r11], r8
- mov esi, dword ptr [rsi]
- xor esi, dword ptr [rdi]
- test rcx, rcx
- mov qword ptr [248+r11], rcx
- mov dword ptr [8+rbx], 32
- jne L76
- ALIGN 16
-L84:
- mov edx, dword ptr [8+rbx]
- lea edi, dword ptr [-1+rdx]
- test edi, edi
- mov dword ptr [8+rbx], edi
- je L76
- lea eax, dword ptr [-2+rdx]
- cmp dword ptr [r11+rax*8], 0
- je L84
-L76:
- mov edx, dword ptr [8+rbx]
- xor r11d, r11d
- test edx, edx
- cmovne r11d, esi
- mov dword ptr [rbx], r11d
- add rsp, 136+128
- pop rbx
- pop rbp
- pop r12
-
- pop rsi
- pop rdi
-
- ret
-
-s_mp_mul_comba_16 ENDP
-
-; void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C)
-
-
- ALIGN 16
-s_mp_mul_comba_32 PROC ; a "FRAME" function
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
- mov rdx, r8
-
- push rbp
- mov rbp, rsp
- push r13
- mov r13, rdx
-; mov edx, 256
- mov r8d, 256
- push r12
- mov r12, rsi
- push rbx
- mov rbx, rdi
- sub rsp, 520+32 ; +32 for "home" storage
-; mov rsi, qword ptr [16+rdi]
-; lea rdi, qword ptr [-544+rbp]
- mov rdx, qword ptr [16+rdi]
- lea rcx, qword ptr [-544+rbp]
- call memcpy
-; mov rsi, qword ptr [16+r12]
-; lea rdi, qword ptr [-288+rbp]
-; mov edx, 256
- mov rdx, qword ptr [16+r12]
- lea rcx, qword ptr [-288+rbp]
- mov r8d, 256
- call memcpy
- mov r9, qword ptr [16+r13]
- xor r8d, r8d
- mov rsi, r8
- mov rdi, r8
- mov r10, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc rdi, rdx
- adc r10, 0
- mov qword ptr [r9], rsi
- mov rsi, r10
- mov r10, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-280+rbp]
- add rdi, rax
- adc rsi, rdx
- adc r10, 0
- mov r11, r10
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-288+rbp]
- add rdi, rax
- adc rsi, rdx
- adc r11, 0
- mov qword ptr [8+r9], rdi
- mov rdi, r11
- mov r11, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc r11, 0
- mov rcx, r11
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [16+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [24+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [32+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [40+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [48+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [56+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [64+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [72+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [80+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [88+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [96+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [104+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [112+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [120+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [128+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [136+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [144+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [152+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [160+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [168+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [176+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [184+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [192+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [200+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [208+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [216+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [224+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [232+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-288+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [240+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-544+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-280+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-288+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [248+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-536+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-272+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-280+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [256+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-528+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-264+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-272+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [264+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-520+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-256+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-264+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [272+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-512+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-248+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-256+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [280+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-504+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-240+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-248+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [288+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-496+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-232+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-240+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [296+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-488+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-224+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-232+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [304+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-480+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-216+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-224+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [312+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-472+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-184+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-192+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-200+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-208+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-216+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [320+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-464+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-192+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-200+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-208+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [328+r9], rcx
- mov rdi, r11
- mov r11, r10
- mov r10, r8
- mov rax, qword ptr [-456+rbp]
- mul qword ptr [-40+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-48+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-56+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-64+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-72+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-80+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-88+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-96+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-104+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-112+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-120+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-128+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-136+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-144+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-152+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-160+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-168+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-176+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-184+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-192+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-200+rbp]
- add r11, rax
- adc rdi, rdx
- adc r10, 0
- mov qword ptr [336+r9], r11
- mov rsi, r10
- mov r10, r8
- mov rax, qword ptr [-448+rbp]
- mul qword ptr [-40+rbp]
- add rdi, rax
- adc rsi, rdx
- adc r10, 0
- mov rcx, r10
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-48+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-56+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-64+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-72+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-80+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-88+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-96+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-104+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-112+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-120+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-128+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-136+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-144+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-152+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-160+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-168+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-176+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-184+rbp]
- add rdi, rax
- adc rsi, rdx
- adc rcx, 0
- mov r11, rsi
- mov r10, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-192+rbp]
- add rdi, rax
- adc r11, rdx
- adc r10, 0
- mov qword ptr [344+r9], rdi
- mov rcx, r11
- mov rdi, r10
- mov r11, r8
- mov rax, qword ptr [-440+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc r11, 0
- mov rsi, r11
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-176+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-184+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [352+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-432+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-168+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-176+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [360+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-424+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-160+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-168+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [368+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-416+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-152+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-160+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [376+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-408+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-144+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-152+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [384+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-400+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-136+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-144+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [392+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-392+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-128+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-136+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [400+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-384+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-120+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-128+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [408+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-376+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-112+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-120+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [416+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-368+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-104+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-112+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [424+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-360+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-96+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-104+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [432+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-352+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-88+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-96+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [440+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-344+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-80+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-88+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [448+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-336+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-72+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-80+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [456+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-328+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-64+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-72+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [464+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-320+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-56+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r10, rdi
- mov r11, rcx
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-64+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [472+r9], rsi
- mov rdi, r11
- mov rcx, r10
- mov rsi, r8
- mov rax, qword ptr [-312+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-48+rbp]
- add rcx, rax
- adc rdi, rdx
- adc rsi, 0
- mov r10, rdi
- mov r11, rsi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-56+rbp]
- add rcx, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [480+r9], rcx
- mov rdi, r11
- mov rsi, r10
- mov rcx, r8
- mov rax, qword ptr [-304+rbp]
- mul qword ptr [-40+rbp]
- add rsi, rax
- adc rdi, rdx
- adc rcx, 0
- mov r11, rcx
- mov r10, rdi
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-48+rbp]
- add rsi, rax
- adc r10, rdx
- adc r11, 0
- mov qword ptr [488+r9], rsi
- mov rcx, r10
- mov rsi, r11
- mov rax, qword ptr [-296+rbp]
- mul qword ptr [-40+rbp]
- add rcx, rax
- adc rsi, rdx
- adc r8, 0
- mov qword ptr [496+r9], rcx
- mov ecx, dword ptr [r12]
- xor ecx, dword ptr [rbx]
- test rsi, rsi
- mov qword ptr [504+r9], rsi
- mov dword ptr [8+r13], 64
- jne L149
- ALIGN 16
-L157:
- mov edx, dword ptr [8+r13]
- lea ebx, dword ptr [-1+rdx]
- test ebx, ebx
- mov dword ptr [8+r13], ebx
- je L149
- lea r12d, dword ptr [-2+rdx]
- cmp dword ptr [r9+r12*8], 0
- je L157
-L149:
- mov r9d, dword ptr [8+r13]
- xor edx, edx
- test r9d, r9d
- cmovne edx, ecx
- mov dword ptr [r13], edx
- add rsp, 520+32 ; +32 for "home" storage
- pop rbx
- pop r12
- pop r13
- pop rbp
- pop rsi
- pop rdi
-
- ret
-
-s_mp_mul_comba_32 ENDP
-
-
-; void s_mp_sqr_comba_4(const mp_int *A, mp_int *B);
-
- ALIGN 16
-s_mp_sqr_comba_4 PROC
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
-
- push rbp
- sub rsp, 80
- mov r11, rsi
- xor esi, esi
- mov r10, rsi
- mov rbp, rsi
- mov r8, rsi
- push rbx
- mov rbx, rsi
- mov rcx, qword ptr [16+rdi]
- mov rdi, rsi
- mov rax, qword ptr [rcx]
- mul rax
- add r10, rax
- adc rbx, rdx
- adc rdi, 0
- mov qword ptr [-72+80+rsp], r10
- mov rax, qword ptr [rcx]
- mul qword ptr [8+rcx]
- add rbx, rax
- adc rdi, rdx
- adc rbp, 0
- add rbx, rax
- adc rdi, rdx
- adc rbp, 0
- mov qword ptr [-64+80+rsp], rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [16+rcx]
- add rdi, rax
- adc rbp, rdx
- adc r8, 0
- add rdi, rax
- adc rbp, rdx
- adc r8, 0
- mov rbx, rbp
- mov rbp, r8
- mov rax, qword ptr [8+rcx]
- mul rax
- add rdi, rax
- adc rbx, rdx
- adc rbp, 0
- mov qword ptr [-56+80+rsp], rdi
- mov r9, rbp
- mov r8, rbx
- mov rdi, rsi
- mov rax, qword ptr [rcx]
- mul qword ptr [24+rcx]
- add r8, rax
- adc r9, rdx
- adc rdi, 0
- add r8, rax
- adc r9, rdx
- adc rdi, 0
- mov rbx, r9
- mov rbp, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [16+rcx]
- add r8, rax
- adc rbx, rdx
- adc rbp, 0
- add r8, rax
- adc rbx, rdx
- adc rbp, 0
- mov qword ptr [-48+80+rsp], r8
- mov r9, rbp
- mov rdi, rbx
- mov r8, rsi
- mov dword ptr [8+r11], 8
- mov dword ptr [r11], 0
- mov rax, qword ptr [8+rcx]
- mul qword ptr [24+rcx]
- add rdi, rax
- adc r9, rdx
- adc r8, 0
- add rdi, rax
- adc r9, rdx
- adc r8, 0
- mov rbx, r9
- mov rbp, r8
- mov rax, qword ptr [16+rcx]
- mul rax
- add rdi, rax
- adc rbx, rdx
- adc rbp, 0
- mov rax, rbp
- mov qword ptr [-40+80+rsp], rdi
- mov rbp, rbx
- mov rdi, rax
- mov rbx, rsi
- mov rax, qword ptr [16+rcx]
- mul qword ptr [24+rcx]
- add rbp, rax
- adc rdi, rdx
- adc rbx, 0
- add rbp, rax
- adc rdi, rdx
- adc rbx, 0
- mov qword ptr [-32+80+rsp], rbp
- mov r9, rbx
- mov rax, qword ptr [24+rcx]
- mul rax
- add rdi, rax
- adc r9, rdx
- adc rsi, 0
- mov rdx, qword ptr [16+r11]
- mov qword ptr [-24+80+rsp], rdi
- mov qword ptr [-16+80+rsp], r9
- mov qword ptr [rdx], r10
- mov r8, qword ptr [-64+80+rsp]
- mov qword ptr [8+rdx], r8
- mov rbp, qword ptr [-56+80+rsp]
- mov qword ptr [16+rdx], rbp
- mov rdi, qword ptr [-48+80+rsp]
- mov qword ptr [24+rdx], rdi
- mov rsi, qword ptr [-40+80+rsp]
- mov qword ptr [32+rdx], rsi
- mov rbx, qword ptr [-32+80+rsp]
- mov qword ptr [40+rdx], rbx
- mov rcx, qword ptr [-24+80+rsp]
- mov qword ptr [48+rdx], rcx
- mov rax, qword ptr [-16+80+rsp]
- mov qword ptr [56+rdx], rax
- mov edx, dword ptr [8+r11]
- test edx, edx
- je L168
- lea ecx, dword ptr [-1+rdx]
- mov rsi, qword ptr [16+r11]
- mov r10d, ecx
- cmp dword ptr [rsi+r10*8], 0
- jne L166
- mov edx, ecx
- ALIGN 16
-L167:
- test edx, edx
- mov ecx, edx
- je L171
- dec edx
- mov eax, edx
- cmp dword ptr [rsi+rax*8], 0
- je L167
- mov dword ptr [8+r11], ecx
- mov edx, ecx
-L166:
- test edx, edx
- je L168
- mov eax, dword ptr [r11]
- jmp L169
-
-L171:
- mov dword ptr [8+r11], edx
-L168:
- xor eax, eax
-L169:
- add rsp, 80
- pop rbx
- pop rbp
- mov dword ptr [r11], eax
-
- pop rsi
- pop rdi
-
- ret
-
-s_mp_sqr_comba_4 ENDP
-
-
-; void s_mp_sqr_comba_8(const mp_int *A, mp_int *B);
-
- ALIGN 16
-s_mp_sqr_comba_8 PROC
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
- mov rdx, r8
- mov rcx, r9
-
- push r14
- xor r9d, r9d
- mov r14, r9
- mov r10, r9
- push r13
- mov r13, r9
- push r12
- mov r12, r9
- push rbp
- mov rbp, rsi
- mov rsi, r9
- push rbx
- mov rbx, r9
- sub rsp, 8+128
- mov rcx, qword ptr [16+rdi]
- mov rax, qword ptr [rcx]
- mul rax
- add r14, rax
- adc rbx, rdx
- adc r12, 0
- mov qword ptr [-120+128+rsp], r14
- mov rax, qword ptr [rcx]
- mul qword ptr [8+rcx]
- add rbx, rax
- adc r12, rdx
- adc r10, 0
- add rbx, rax
- adc r12, rdx
- adc r10, 0
- mov qword ptr [-112+128+rsp], rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [16+rcx]
- add r12, rax
- adc r10, rdx
- adc r13, 0
- add r12, rax
- adc r10, rdx
- adc r13, 0
- mov rbx, r10
- mov r10, r13
- mov r13, r9
- mov rax, qword ptr [8+rcx]
- mul rax
- add r12, rax
- adc rbx, rdx
- adc r10, 0
- mov qword ptr [-104+128+rsp], r12
- mov rdi, r10
- mov r11, rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [24+rcx]
- add r11, rax
- adc rdi, rdx
- adc rsi, 0
- add r11, rax
- adc rdi, rdx
- adc rsi, 0
- mov rbx, rdi
- mov r10, rsi
- mov rdi, r9
- mov rax, qword ptr [8+rcx]
- mul qword ptr [16+rcx]
- add r11, rax
- adc rbx, rdx
- adc r10, 0
- add r11, rax
- adc rbx, rdx
- adc r10, 0
- mov rsi, r9
- mov qword ptr [-96+128+rsp], r11
- mov r8, r10
- mov r12, rbx
- mov r11, r9
- mov rax, qword ptr [rcx]
- mul qword ptr [32+rcx]
- add r12, rax
- adc r8, rdx
- adc r13, 0
- add r12, rax
- adc r8, rdx
- adc r13, 0
- mov rax, qword ptr [8+rcx]
- mul qword ptr [24+rcx]
- add r12, rax
- adc r8, rdx
- adc r13, 0
- add r12, rax
- adc r8, rdx
- adc r13, 0
- mov rbx, r8
- mov r10, r13
- mov r8, r9
- mov rax, qword ptr [16+rcx]
- mul rax
- add r12, rax
- adc rbx, rdx
- adc r10, 0
- mov qword ptr [-88+128+rsp], r12
- mov rax, qword ptr [rcx]
- mul qword ptr [40+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [32+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [24+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add rbx, r8
- adc r10, rdi
- adc r11, rsi
- add rbx, r8
- adc r10, rdi
- adc r11, rsi
- mov qword ptr [-80+128+rsp], rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [48+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [32+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r9
- mov r13, rdi
- mov r12, rsi
- add r10, r8
- adc r11, r13
- adc rax, r12
- add r10, r8
- adc r11, r13
- adc rax, r12
- mov rdx, rax
- mov rbx, r11
- mov rdi, r13
- mov r11, rdx
- mov rsi, r12
- mov rax, qword ptr [24+rcx]
- mul rax
- add r10, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-72+128+rsp], r10
- mov r10, r11
- mov rax, qword ptr [rcx]
- mul qword ptr [56+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [32+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r9
- add rbx, r8
- adc r10, rdi
- adc rax, rsi
- add rbx, r8
- adc r10, rdi
- adc rax, rsi
- mov qword ptr [-64+128+rsp], rbx
- mov r11, rax
- mov rbx, r9
- mov rax, qword ptr [8+rcx]
- mul qword ptr [56+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [16+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov r13, rdi
- mov r12, rsi
- add r10, r8
- adc r11, r13
- adc rbx, r12
- add r10, r8
- adc r11, r13
- adc rbx, r12
- mov rsi, rbx
- mov rdi, r13
- mov rbx, r11
- mov r13, r12
- mov r11, rsi
- mov rax, qword ptr [32+rcx]
- mul rax
- add r10, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-56+128+rsp], r10
- mov r10, r9
- mov rax, qword ptr [16+rcx]
- mul qword ptr [56+rcx]
- mov r8, rax
- mov rdi, rdx
- xor r13, r13
- mov rax, qword ptr [24+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc r13, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc r13, 0
- mov r12, rdi
- mov rax, r13
- add rbx, r8
- adc r11, r12
- adc r10, rax
- add rbx, r8
- adc r11, r12
- adc r10, rax
- mov qword ptr [-48+128+rsp], rbx
- mov r12, r11
- mov rsi, r10
- mov rbx, r9
- mov r11, r9
- mov rax, qword ptr [24+rcx]
- mul qword ptr [56+rcx]
- add r12, rax
- adc rsi, rdx
- adc rbx, 0
- add r12, rax
- adc rsi, rdx
- adc rbx, 0
- mov r13, rbx
- mov rax, qword ptr [32+rcx]
- mul qword ptr [48+rcx]
- add r12, rax
- adc rsi, rdx
- adc r13, 0
- add r12, rax
- adc rsi, rdx
- adc r13, 0
- mov r10, rsi
- mov rbx, r13
- mov r13, r9
- mov rax, qword ptr [40+rcx]
- mul rax
- add r12, rax
- adc r10, rdx
- adc rbx, 0
- mov qword ptr [-40+128+rsp], r12
- mov r8, rbx
- mov rdi, r10
- mov rax, qword ptr [32+rcx]
- mul qword ptr [56+rcx]
- add rdi, rax
- adc r8, rdx
- adc r11, 0
- add rdi, rax
- adc r8, rdx
- adc r11, 0
- mov r10, r8
- mov rbx, r11
- mov rax, qword ptr [40+rcx]
- mul qword ptr [48+rcx]
- add rdi, rax
- adc r10, rdx
- adc rbx, 0
- add rdi, rax
- adc r10, rdx
- adc rbx, 0
- mov qword ptr [-32+128+rsp], rdi
- mov rsi, rbx
- mov r12, r10
- mov rax, qword ptr [40+rcx]
- mul qword ptr [56+rcx]
- add r12, rax
- adc rsi, rdx
- adc r13, 0
- add r12, rax
- adc rsi, rdx
- adc r13, 0
- mov r10, rsi
- mov rbx, r13
- mov rax, qword ptr [48+rcx]
- mul rax
- add r12, rax
- adc r10, rdx
- adc rbx, 0
- mov qword ptr [-24+128+rsp], r12
- mov rdi, r10
- mov rsi, rbx
- mov r10, r9
- mov dword ptr [8+rbp], 16
- mov dword ptr [rbp], 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [56+rcx]
- add rdi, rax
- adc rsi, rdx
- adc r10, 0
- add rdi, rax
- adc rsi, rdx
- adc r10, 0
- mov qword ptr [-16+128+rsp], rdi
- mov r8, r10
- mov rax, qword ptr [56+rcx]
- mul rax
- add rsi, rax
- adc r8, rdx
- adc r9, 0
- mov rax, qword ptr [16+rbp]
- mov qword ptr [-8+128+rsp], rsi
- mov qword ptr [128+rsp], r8
- mov qword ptr [rax], r14
- mov rbx, qword ptr [-112+128+rsp]
- mov qword ptr [8+rax], rbx
- mov rcx, qword ptr [-104+128+rsp]
- mov qword ptr [16+rax], rcx
- mov rdx, qword ptr [-96+128+rsp]
- mov qword ptr [24+rax], rdx
- mov r14, qword ptr [-88+128+rsp]
- mov qword ptr [32+rax], r14
- mov r13, qword ptr [-80+128+rsp]
- mov qword ptr [40+rax], r13
- mov r12, qword ptr [-72+128+rsp]
- mov qword ptr [48+rax], r12
- mov r11, qword ptr [-64+128+rsp]
- mov qword ptr [56+rax], r11
- mov r10, qword ptr [-56+128+rsp]
- mov qword ptr [64+rax], r10
- mov r9, qword ptr [-48+128+rsp]
- mov qword ptr [72+rax], r9
- mov r8, qword ptr [-40+128+rsp]
- mov qword ptr [80+rax], r8
- mov rdi, qword ptr [-32+128+rsp]
- mov qword ptr [88+rax], rdi
- mov rsi, qword ptr [-24+128+rsp]
- mov qword ptr [96+rax], rsi
- mov rbx, qword ptr [-16+128+rsp]
- mov qword ptr [104+rax], rbx
- mov rcx, qword ptr [-8+128+rsp]
- mov qword ptr [112+rax], rcx
- mov rdx, qword ptr [128+rsp]
- mov qword ptr [120+rax], rdx
- mov edx, dword ptr [8+rbp]
- test edx, edx
- je L192
- lea ecx, dword ptr [-1+rdx]
- mov rsi, qword ptr [16+rbp]
- mov r14d, ecx
- cmp dword ptr [rsi+r14*8], 0
- jne L190
- mov edx, ecx
- ALIGN 16
-L191:
- test edx, edx
- mov ecx, edx
- je L195
- dec edx
- mov r9d, edx
- cmp dword ptr [rsi+r9*8], 0
- je L191
- mov dword ptr [8+rbp], ecx
- mov edx, ecx
-L190:
- test edx, edx
- je L192
- mov eax, dword ptr [rbp]
- jmp L193
-
-L195:
- mov dword ptr [8+rbp], edx
-L192:
- xor eax, eax
-L193:
- mov dword ptr [rbp], eax
- add rsp, 8+128
- pop rbx
- pop rbp
- pop r12
- pop r13
- pop r14
-
- pop rsi
- pop rdi
-
- ret
-
-s_mp_sqr_comba_8 ENDP
-
-
-; void s_mp_sqr_comba_16(const mp_int *A, mp_int *B)
-
- ALIGN 16
-s_mp_sqr_comba_16 PROC ; A "FRAME" function
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
-
- push rbp
- xor r9d, r9d
- mov r8, r9
- mov r11, r9
- mov rbp, rsp
- push r14
- mov r14, rsi
- mov rsi, r9
- push r13
- mov r13, r9
- push r12
- mov r12, r9
- push rbx
- mov rbx, r9
- sub rsp, 256+32 ; +32 for "home" storage
- mov rcx, qword ptr [16+rdi]
- mov rax, qword ptr [rcx]
- mul rax
- add r8, rax
- adc rbx, rdx
- adc rsi, 0
- mov qword ptr [-288+rbp], r8
- mov rax, qword ptr [rcx]
- mul qword ptr [8+rcx]
- add rbx, rax
- adc rsi, rdx
- adc r12, 0
- add rbx, rax
- adc rsi, rdx
- adc r12, 0
- mov qword ptr [-280+rbp], rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [16+rcx]
- add rsi, rax
- adc r12, rdx
- adc r13, 0
- add rsi, rax
- adc r12, rdx
- adc r13, 0
- mov rbx, r12
- mov r10, r13
- mov rax, qword ptr [8+rcx]
- mul rax
- add rsi, rax
- adc rbx, rdx
- adc r10, 0
- mov qword ptr [-272+rbp], rsi
- mov rdi, r10
- mov rsi, r9
- mov r10, rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [24+rcx]
- add r10, rax
- adc rdi, rdx
- adc r11, 0
- add r10, rax
- adc rdi, rdx
- adc r11, 0
- mov r12, rdi
- mov rbx, r11
- mov rdi, r9
- mov rax, qword ptr [8+rcx]
- mul qword ptr [16+rcx]
- add r10, rax
- adc r12, rdx
- adc rbx, 0
- add r10, rax
- adc r12, rdx
- adc rbx, 0
- mov r11, r9
- mov qword ptr [-264+rbp], r10
- mov r8, rbx
- mov r13, r12
- mov r12, r9
- mov rax, qword ptr [rcx]
- mul qword ptr [32+rcx]
- add r13, rax
- adc r8, rdx
- adc r12, 0
- add r13, rax
- adc r8, rdx
- adc r12, 0
- mov rax, qword ptr [8+rcx]
- mul qword ptr [24+rcx]
- add r13, rax
- adc r8, rdx
- adc r12, 0
- add r13, rax
- adc r8, rdx
- adc r12, 0
- mov rbx, r8
- mov r10, r12
- mov r8, r9
- mov rax, qword ptr [16+rcx]
- mul rax
- add r13, rax
- adc rbx, rdx
- adc r10, 0
- mov qword ptr [-256+rbp], r13
- mov rax, qword ptr [rcx]
- mul qword ptr [40+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [32+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [24+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add rbx, r8
- adc r10, rdi
- adc r11, rsi
- add rbx, r8
- adc r10, rdi
- adc r11, rsi
- mov qword ptr [-248+rbp], rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [48+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [32+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r9
- mov r13, rdi
- mov r12, rsi
- add r10, r8
- adc r11, r13
- adc rax, r12
- add r10, r8
- adc r11, r13
- adc rax, r12
- mov rdx, rax
- mov rbx, r11
- mov rdi, r13
- mov r11, rdx
- mov rsi, r12
- mov rax, qword ptr [24+rcx]
- mul rax
- add r10, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-240+rbp], r10
- mov r10, r11
- mov rax, qword ptr [rcx]
- mul qword ptr [56+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [32+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rdx, r9
- add rbx, r8
- adc r10, rdi
- adc rdx, rsi
- add rbx, r8
- adc r10, rdi
- adc rdx, rsi
- mov r11, rdx
- mov qword ptr [-232+rbp], rbx
- mov rbx, r9
- mov rax, qword ptr [rcx]
- mul qword ptr [64+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov r13, rdi
- mov r12, rsi
- add r10, r8
- adc r11, r13
- adc rbx, r12
- add r10, r8
- adc r11, r13
- adc rbx, r12
- mov rax, qword ptr [32+rcx]
- mul rax
- add r10, rax
- adc r11, rdx
- adc rbx, 0
- mov rdi, r13
- mov qword ptr [-224+rbp], r10
- mov rsi, r12
- mov r10, rbx
- mov r12, r9
- mov rax, qword ptr [rcx]
- mul qword ptr [72+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add r11, r8
- adc r10, rdi
- adc r12, rsi
- add r11, r8
- adc r10, rdi
- adc r12, rsi
- mov qword ptr [-216+rbp], r11
- mov rbx, r12
- mov rax, qword ptr [rcx]
- mul qword ptr [80+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r9
- mov r13, rdi
- mov r12, rsi
- add r10, r8
- adc rbx, r13
- adc rax, r12
- add r10, r8
- adc rbx, r13
- adc rax, r12
- mov rdx, rax
- mov r11, rbx
- mov rdi, r13
- mov rbx, rdx
- mov rsi, r12
- mov rax, qword ptr [40+rcx]
- mul rax
- add r10, rax
- adc r11, rdx
- adc rbx, 0
- mov qword ptr [-208+rbp], r10
- mov r10, rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [88+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rdx, r9
- add r11, r8
- adc r10, rdi
- adc rdx, rsi
- add r11, r8
- adc r10, rdi
- adc rdx, rsi
- mov r13, rdx
- mov qword ptr [-200+rbp], r11
- mov r12, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [96+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r9
- mov rdx, rdi
- mov r11, rsi
- add r10, r8
- adc r12, rdx
- adc rax, r11
- add r10, r8
- adc r12, rdx
- adc rax, r11
- mov rbx, rdx
- mov r13, rax
- mov rsi, r11
- mov rax, qword ptr [48+rcx]
- mul rax
- add r10, rax
- adc r12, rdx
- adc r13, 0
- mov rdi, rbx
- mov qword ptr [-192+rbp], r10
- mov r10, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [104+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r9
- mov rax, qword ptr [8+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add r12, r8
- adc r10, rdi
- adc r13, rsi
- add r12, r8
- adc r10, rdi
- adc r13, rsi
- mov qword ptr [-184+rbp], r12
- mov r12, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [112+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r9
- mov rbx, rdi
- mov rdx, rsi
- add r10, r8
- adc r12, rbx
- adc rax, rdx
- add r10, r8
- adc r12, rbx
- adc rax, rdx
- mov r11, rdx
- mov r13, rax
- mov rdi, rbx
- mov rax, qword ptr [56+rcx]
- mul rax
- add r10, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-176+rbp], r10
- mov r10, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r9
- mov rax, qword ptr [8+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add r12, r8
- adc r10, rdi
- adc r13, rsi
- add r12, r8
- adc r10, rdi
- adc r13, rsi
- mov qword ptr [-168+rbp], r12
- mov r12, r13
- mov rax, qword ptr [8+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [16+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r9
- mov rbx, rdi
- mov rdx, rsi
- add r10, r8
- adc r12, rbx
- adc rax, rdx
- add r10, r8
- adc r12, rbx
- adc rax, rdx
- mov r11, rdx
- mov r13, rax
- mov rdi, rbx
- mov rax, qword ptr [64+rcx]
- mul rax
- add r10, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-160+rbp], r10
- mov r11, r9
- mov rax, qword ptr [16+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r10, r13
- mov rbx, r9
- mov rax, qword ptr [24+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add r12, r8
- adc r10, rdi
- adc r11, rsi
- add r12, r8
- adc r10, rdi
- adc r11, rsi
- mov qword ptr [-152+rbp], r12
- mov rax, qword ptr [24+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [32+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov r13, rdi
- mov r12, rsi
- add r10, r8
- adc r11, r13
- adc rbx, r12
- add r10, r8
- adc r11, r13
- adc rbx, r12
- mov rdx, rbx
- mov rdi, r13
- mov rbx, r11
- mov rsi, r12
- mov r11, rdx
- mov r12, r9
- mov rax, qword ptr [72+rcx]
- mul rax
- add r10, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-144+rbp], r10
- mov r10, r11
- mov rax, qword ptr [32+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [40+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add rbx, r8
- adc r10, rdi
- adc r12, rsi
- add rbx, r8
- adc r10, rdi
- adc r12, rsi
- mov qword ptr [-136+rbp], rbx
- mov r11, r12
- mov rax, qword ptr [40+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [48+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r9
- mov r13, rdi
- mov r12, rsi
- add r10, r8
- adc r11, r13
- adc rax, r12
- add r10, r8
- adc r11, r13
- adc rax, r12
- mov rdx, rax
- mov rbx, r11
- mov rdi, r13
- mov r11, rdx
- mov rsi, r12
- mov rax, qword ptr [80+rcx]
- mul rax
- add r10, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-128+rbp], r10
- mov r10, r11
- mov rax, qword ptr [48+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [56+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rdx, r9
- add rbx, r8
- adc r10, rdi
- adc rdx, rsi
- add rbx, r8
- adc r10, rdi
- adc rdx, rsi
- mov qword ptr [-120+rbp], rbx
- mov r11, rdx
- mov rbx, r9
- mov rax, qword ptr [56+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [64+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov r13, rdi
- mov r12, rsi
- add r10, r8
- adc r11, r13
- adc rbx, r12
- add r10, r8
- adc r11, r13
- adc rbx, r12
- mov rdx, rbx
- mov rdi, r13
- mov rbx, r11
- mov rsi, r12
- mov r11, rdx
- mov r12, r9
- mov rax, qword ptr [88+rcx]
- mul rax
- add r10, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-112+rbp], r10
- mov r10, r11
- mov rax, qword ptr [64+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [72+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add rbx, r8
- adc r10, rdi
- adc r12, rsi
- add rbx, r8
- adc r10, rdi
- adc r12, rsi
- mov qword ptr [-104+rbp], rbx
- mov r11, r12
- mov rax, qword ptr [72+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [80+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r9
- mov r13, rdi
- mov r12, rsi
- add r10, r8
- adc r11, r13
- adc rax, r12
- add r10, r8
- adc r11, r13
- adc rax, r12
- mov rdx, rax
- mov rbx, r11
- mov rdi, r13
- mov r11, rdx
- mov rsi, r12
- mov rax, qword ptr [96+rcx]
- mul rax
- add r10, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-96+rbp], r10
- mov r10, r9
- mov rax, qword ptr [80+rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [88+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov r12, rdi
- mov rax, rsi
- mov rsi, r9
- add rbx, r8
- adc r11, r12
- adc r10, rax
- add rbx, r8
- adc r11, r12
- adc r10, rax
- mov r12, r9
- mov qword ptr [-88+rbp], rbx
- mov r13, r11
- mov r11, r10
- mov rax, qword ptr [88+rcx]
- mul qword ptr [120+rcx]
- add r13, rax
- adc r11, rdx
- adc r12, 0
- add r13, rax
- adc r11, rdx
- adc r12, 0
- mov rdi, r12
- mov rax, qword ptr [96+rcx]
- mul qword ptr [112+rcx]
- add r13, rax
- adc r11, rdx
- adc rdi, 0
- add r13, rax
- adc r11, rdx
- adc rdi, 0
- mov rbx, r11
- mov r10, rdi
- mov r11, r9
- mov rax, qword ptr [104+rcx]
- mul rax
- add r13, rax
- adc rbx, rdx
- adc r10, 0
- mov qword ptr [-80+rbp], r13
- mov r8, r10
- mov r10, rbx
- mov rax, qword ptr [96+rcx]
- mul qword ptr [120+rcx]
- add r10, rax
- adc r8, rdx
- adc rsi, 0
- add r10, rax
- adc r8, rdx
- adc rsi, 0
- mov r12, r8
- mov rbx, rsi
- mov rax, qword ptr [104+rcx]
- mul qword ptr [112+rcx]
- add r10, rax
- adc r12, rdx
- adc rbx, 0
- add r10, rax
- adc r12, rdx
- adc rbx, 0
- mov qword ptr [-72+rbp], r10
- mov r13, rbx
- mov rbx, r12
- mov rax, qword ptr [104+rcx]
- mul qword ptr [120+rcx]
- add rbx, rax
- adc r13, rdx
- adc r11, 0
- add rbx, rax
- adc r13, rdx
- adc r11, 0
- mov r12, r11
- mov r10, r13
- mov rax, qword ptr [112+rcx]
- mul rax
- add rbx, rax
- adc r10, rdx
- adc r12, 0
- mov qword ptr [-64+rbp], rbx
- mov rdi, r10
- mov rbx, r9
- mov rsi, r12
- mov rax, qword ptr [112+rcx]
- mul qword ptr [120+rcx]
- add rdi, rax
- adc rsi, rdx
- adc rbx, 0
- add rdi, rax
- adc rsi, rdx
- adc rbx, 0
- mov qword ptr [-56+rbp], rdi
- mov r8, rbx
- mov rax, qword ptr [120+rcx]
- mul rax
- add rsi, rax
- adc r8, rdx
- adc r9, 0
- mov qword ptr [-48+rbp], rsi
- mov qword ptr [-40+rbp], r8
- mov dword ptr [8+r14], 32
- mov dword ptr [r14], 0
-; mov rdi, qword ptr [16+r14]
-; lea rsi, qword ptr [-288+rbp]
-; mov edx, 256
- mov rcx, qword ptr [16+r14]
- lea rdx, qword ptr [-288+rbp]
- mov r8d, 256
- call memcpy
- mov edx, dword ptr [8+r14]
- test edx, edx
- je L232
- lea ecx, dword ptr [-1+rdx]
- mov rsi, qword ptr [16+r14]
- mov r9d, ecx
- cmp dword ptr [rsi+r9*8], 0
- jne L230
- mov edx, ecx
- ALIGN 16
-L231:
- test edx, edx
- mov ecx, edx
- je L235
- dec edx
- mov eax, edx
- cmp dword ptr [rsi+rax*8], 0
- je L231
- mov dword ptr [8+r14], ecx
- mov edx, ecx
-L230:
- test edx, edx
- je L232
- mov eax, dword ptr [r14]
- jmp L233
-
-L235:
- mov dword ptr [8+r14], edx
-L232:
- xor eax, eax
-L233:
- mov dword ptr [r14], eax
- add rsp, 256+32 ; +32 for "home" storage
- pop rbx
- pop r12
- pop r13
- pop r14
- pop rbp
- pop rsi
- pop rdi
-
- ret
-
-s_mp_sqr_comba_16 ENDP
-
-
-; void s_mp_sqr_comba_32(const mp_int *A, mp_int *B);
-
- ALIGN 16
-s_mp_sqr_comba_32 PROC ; A "FRAME" function
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
-
- push rbp
- xor r10d, r10d
- mov r8, r10
- mov r11, r10
- mov rbp, rsp
- push r14
- mov r14, rsi
- mov rsi, r10
- push r13
- mov r13, r10
- push r12
- mov r12, r10
- push rbx
- mov rbx, r10
- sub rsp, 512+32 ; +32 for "home" storage
- mov rcx, qword ptr [16+rdi]
- mov rax, qword ptr [rcx]
- mul rax
- add r8, rax
- adc rbx, rdx
- adc rsi, 0
- mov qword ptr [-544+rbp], r8
- mov rax, qword ptr [rcx]
- mul qword ptr [8+rcx]
- add rbx, rax
- adc rsi, rdx
- adc r12, 0
- add rbx, rax
- adc rsi, rdx
- adc r12, 0
- mov qword ptr [-536+rbp], rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [16+rcx]
- add rsi, rax
- adc r12, rdx
- adc r13, 0
- add rsi, rax
- adc r12, rdx
- adc r13, 0
- mov rbx, r12
- mov r9, r13
- mov rax, qword ptr [8+rcx]
- mul rax
- add rsi, rax
- adc rbx, rdx
- adc r9, 0
- mov qword ptr [-528+rbp], rsi
- mov rdi, r9
- mov rsi, r10
- mov r9, rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [24+rcx]
- add r9, rax
- adc rdi, rdx
- adc r11, 0
- add r9, rax
- adc rdi, rdx
- adc r11, 0
- mov r12, rdi
- mov r13, r11
- mov rdi, r10
- mov rax, qword ptr [8+rcx]
- mul qword ptr [16+rcx]
- add r9, rax
- adc r12, rdx
- adc r13, 0
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov r11, r10
- mov qword ptr [-520+rbp], r9
- mov r8, r13
- mov r13, r12
- mov r12, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [32+rcx]
- add r13, rax
- adc r8, rdx
- adc r12, 0
- add r13, rax
- adc r8, rdx
- adc r12, 0
- mov rax, qword ptr [8+rcx]
- mul qword ptr [24+rcx]
- add r13, rax
- adc r8, rdx
- adc r12, 0
- add r13, rax
- adc r8, rdx
- adc r12, 0
- mov rbx, r8
- mov r9, r12
- mov r8, r10
- mov rax, qword ptr [16+rcx]
- mul rax
- add r13, rax
- adc rbx, rdx
- adc r9, 0
- mov qword ptr [-512+rbp], r13
- mov rax, qword ptr [rcx]
- mul qword ptr [40+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [32+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [24+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add rbx, r8
- adc r9, rdi
- adc r11, rsi
- add rbx, r8
- adc r9, rdi
- adc r11, rsi
- mov qword ptr [-504+rbp], rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [48+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [32+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r10
- mov r13, rdi
- mov r12, rsi
- add r9, r8
- adc r11, r13
- adc rax, r12
- add r9, r8
- adc r11, r13
- adc rax, r12
- mov rdx, rax
- mov rbx, r11
- mov rdi, r13
- mov r11, rdx
- mov rsi, r12
- mov rax, qword ptr [24+rcx]
- mul rax
- add r9, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-496+rbp], r9
- mov r9, r11
- mov rax, qword ptr [rcx]
- mul qword ptr [56+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [32+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rdx, r10
- add rbx, r8
- adc r9, rdi
- adc rdx, rsi
- add rbx, r8
- adc r9, rdi
- adc rdx, rsi
- mov r11, rdx
- mov qword ptr [-488+rbp], rbx
- mov rbx, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [64+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov r13, rdi
- mov r12, rsi
- add r9, r8
- adc r11, r13
- adc rbx, r12
- add r9, r8
- adc r11, r13
- adc rbx, r12
- mov rax, qword ptr [32+rcx]
- mul rax
- add r9, rax
- adc r11, rdx
- adc rbx, 0
- mov rdi, r13
- mov qword ptr [-480+rbp], r9
- mov rsi, r12
- mov r9, rbx
- mov r12, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [72+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [40+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add r11, r8
- adc r9, rdi
- adc r12, rsi
- add r11, r8
- adc r9, rdi
- adc r12, rsi
- mov qword ptr [-472+rbp], r11
- mov rbx, r12
- mov rax, qword ptr [rcx]
- mul qword ptr [80+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r10
- mov r13, rdi
- mov r12, rsi
- add r9, r8
- adc rbx, r13
- adc rax, r12
- add r9, r8
- adc rbx, r13
- adc rax, r12
- mov rdx, rax
- mov r11, rbx
- mov rdi, r13
- mov rbx, rdx
- mov rsi, r12
- mov rax, qword ptr [40+rcx]
- mul rax
- add r9, rax
- adc r11, rdx
- adc rbx, 0
- mov qword ptr [-464+rbp], r9
- mov r9, rbx
- mov rax, qword ptr [rcx]
- mul qword ptr [88+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [48+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rdx, r10
- add r11, r8
- adc r9, rdi
- adc rdx, rsi
- add r11, r8
- adc r9, rdi
- adc rdx, rsi
- mov r13, rdx
- mov qword ptr [-456+rbp], r11
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [96+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, rdi
- mov r11, rsi
- add r9, r8
- adc r12, rax
- adc r13, r11
- add r9, r8
- adc r12, rax
- adc r13, r11
- mov rbx, rax
- mov rsi, r11
- mov rax, qword ptr [48+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rdi, rbx
- mov qword ptr [-448+rbp], r9
- mov r9, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [104+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r10
- mov rax, qword ptr [8+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [56+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add r12, r8
- adc r9, rdi
- adc r13, rsi
- add r12, r8
- adc r9, rdi
- adc r13, rsi
- mov qword ptr [-440+rbp], r12
- mov r12, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [112+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rdx, r13
- mov rbx, rdi
- mov r13, rsi
- add r9, r8
- adc rdx, rbx
- adc r12, r13
- add r9, r8
- adc rdx, rbx
- adc r12, r13
- mov rax, r12
- mov r11, r13
- mov r12, rdx
- mov r13, rax
- mov rdi, rbx
- mov rsi, r11
- mov rax, qword ptr [56+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov qword ptr [-432+rbp], r9
- mov r9, r13
- mov r13, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [120+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [64+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r8
- mov rdx, rdi
- mov rbx, rsi
- add r12, rax
- adc r9, rdx
- adc r13, rbx
- add r12, rax
- adc r9, rdx
- adc r13, rbx
- mov qword ptr [-424+rbp], r12
- mov r8, rdx
- mov rsi, rax
- mov rdi, rbx
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [128+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [112+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [104+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [96+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [88+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [80+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [72+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, rsi
- mov rbx, r8
- mov rdx, rdi
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- mov r11, rdx
- mov r8, rax
- mov rdi, rbx
- mov rax, qword ptr [64+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-416+rbp], r9
- mov r9, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [136+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r10
- mov rax, qword ptr [8+rcx]
- mul qword ptr [128+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [120+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [72+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rbx, r8
- mov rax, rdi
- mov rdx, rsi
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- mov qword ptr [-408+rbp], r12
- mov rdi, rdx
- mov r8, rax
- mov rsi, rbx
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [144+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [112+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [104+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [96+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [88+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [80+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, rsi
- mov rbx, r8
- mov rdx, rdi
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- mov r11, rdx
- mov r8, rax
- mov rdi, rbx
- mov rax, qword ptr [72+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-400+rbp], r9
- mov r9, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [152+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r10
- mov rax, qword ptr [8+rcx]
- mul qword ptr [144+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [136+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [128+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [120+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [80+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rbx, r8
- mov rax, rdi
- mov rdx, rsi
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- mov qword ptr [-392+rbp], r12
- mov rdi, rdx
- mov r8, rax
- mov rsi, rbx
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [160+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [112+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [104+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [96+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [88+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, rsi
- mov rbx, r8
- mov rdx, rdi
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- mov r11, rdx
- mov r8, rax
- mov rdi, rbx
- mov rax, qword ptr [80+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-384+rbp], r9
- mov r9, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [168+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r10
- mov rax, qword ptr [8+rcx]
- mul qword ptr [160+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [152+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [144+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [136+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [128+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [120+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [88+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rbx, r8
- mov rax, rdi
- mov rdx, rsi
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- mov qword ptr [-376+rbp], r12
- mov rdi, rdx
- mov r8, rax
- mov rsi, rbx
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [176+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [112+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [104+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [96+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, rsi
- mov rbx, r8
- mov rdx, rdi
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- mov r11, rdx
- mov r8, rax
- mov rdi, rbx
- mov rax, qword ptr [88+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-368+rbp], r9
- mov r9, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [184+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r10
- mov rax, qword ptr [8+rcx]
- mul qword ptr [176+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [168+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [160+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [152+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [144+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [136+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [128+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [120+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [112+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [104+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [96+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rbx, r8
- mov rax, rdi
- mov rdx, rsi
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- mov rdi, rdx
- mov qword ptr [-360+rbp], r12
- mov r8, rax
- mov rsi, rbx
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [192+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [112+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [104+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rbx, r8
- mov rax, rdi
- add r9, rsi
- adc r12, rbx
- adc r13, rax
- add r9, rsi
- adc r12, rbx
- adc r13, rax
- mov r11, rax
- mov r8, rbx
- mov rax, qword ptr [96+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rdi, r11
- mov qword ptr [-352+rbp], r9
- mov r9, r13
- mov rax, qword ptr [rcx]
- mul qword ptr [200+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov r13, r10
- mov rax, qword ptr [8+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [112+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [104+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- add r12, rsi
- adc r9, r8
- adc r13, rdi
- add r12, rsi
- adc r9, r8
- adc r13, rdi
- mov qword ptr [-344+rbp], r12
- mov r12, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [208+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [112+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rdx, r13
- mov rbx, r8
- mov r13, rdi
- add r9, rsi
- adc rdx, rbx
- adc r12, r13
- add r9, rsi
- adc rdx, rbx
- adc r12, r13
- mov rax, r12
- mov r11, r13
- mov r12, rdx
- mov r13, rax
- mov r8, rbx
- mov rdi, r11
- mov rax, qword ptr [104+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov qword ptr [-336+rbp], r9
- mov r9, r13
- mov r13, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [216+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [112+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- add r12, rsi
- adc r9, r8
- adc r13, rdi
- add r12, rsi
- adc r9, r8
- adc r13, rdi
- mov qword ptr [-328+rbp], r12
- mov rax, qword ptr [rcx]
- mul qword ptr [224+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, r13
- mov rdx, r10
- mov rbx, r8
- mov r12, rdi
- add r9, rsi
- adc rax, rbx
- adc rdx, r12
- add r9, rsi
- adc rax, rbx
- adc rdx, r12
- mov rdi, rdx
- mov r11, r12
- mov r8, rbx
- mov r12, rax
- mov r13, rdi
- mov rdi, r11
- mov rax, qword ptr [112+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov qword ptr [-320+rbp], r9
- mov rbx, r13
- mov r9, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [232+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [120+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- add r12, rsi
- adc rbx, r8
- adc r9, rdi
- add r12, rsi
- adc rbx, r8
- adc r9, rdi
- mov qword ptr [-312+rbp], r12
- mov r13, r9
- mov rax, qword ptr [rcx]
- mul qword ptr [240+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, r10
- mov r11, r8
- mov rdx, rdi
- add rbx, rsi
- adc r13, r11
- adc rax, rdx
- add rbx, rsi
- adc r13, r11
- adc rax, rdx
- mov r9, rdx
- mov rdx, rax
- mov r12, r13
- mov r8, r11
- mov r13, rdx
- mov rdi, r9
- mov rax, qword ptr [120+rcx]
- mul rax
- add rbx, rax
- adc r12, rdx
- adc r13, 0
- mov qword ptr [-304+rbp], rbx
- mov rbx, r13
- mov r13, r10
- mov rax, qword ptr [rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [8+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [16+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [128+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- add r12, rsi
- adc rbx, r8
- adc r13, rdi
- add r12, rsi
- adc rbx, r8
- adc r13, rdi
- mov qword ptr [-296+rbp], r12
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [8+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [16+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [24+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov r11, r8
- mov rax, rdi
- add rbx, rsi
- adc r12, r11
- adc r13, rax
- add rbx, rsi
- adc r12, r11
- adc r13, rax
- mov r9, rax
- mov r8, r11
- mov rax, qword ptr [128+rcx]
- mul rax
- add rbx, rax
- adc r12, rdx
- adc r13, 0
- mov rdi, r9
- mov qword ptr [-288+rbp], rbx
- mov r9, r13
- mov rax, qword ptr [16+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov r13, r10
- mov rax, qword ptr [24+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [32+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [136+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- add r12, rsi
- adc r9, r8
- adc r13, rdi
- add r12, rsi
- adc r9, r8
- adc r13, rdi
- mov qword ptr [-280+rbp], r12
- mov r12, r10
- mov rax, qword ptr [24+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [32+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [40+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rdx, r13
- mov rbx, r8
- mov r13, rdi
- add r9, rsi
- adc rdx, rbx
- adc r12, r13
- add r9, rsi
- adc rdx, rbx
- adc r12, r13
- mov rax, r12
- mov r11, r13
- mov r12, rdx
- mov r13, rax
- mov r8, rbx
- mov rdi, r11
- mov rax, qword ptr [136+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov qword ptr [-272+rbp], r9
- mov r9, r13
- mov r13, r10
- mov rax, qword ptr [32+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [40+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [48+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [144+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- add r12, rsi
- adc r9, r8
- adc r13, rdi
- add r12, rsi
- adc r9, r8
- adc r13, rdi
- mov qword ptr [-264+rbp], r12
- mov rax, qword ptr [40+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [48+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [56+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, r13
- mov rdx, r10
- mov rbx, r8
- mov r12, rdi
- add r9, rsi
- adc rax, rbx
- adc rdx, r12
- add r9, rsi
- adc rax, rbx
- adc rdx, r12
- mov rdi, rdx
- mov r11, r12
- mov r8, rbx
- mov r12, rax
- mov r13, rdi
- mov rdi, r11
- mov rax, qword ptr [144+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov r11, r10
- mov qword ptr [-256+rbp], r9
- mov r9, r13
- mov rax, qword ptr [48+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [56+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [64+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [152+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- add r12, rsi
- adc r9, r8
- adc r11, rdi
- add r12, rsi
- adc r9, r8
- adc r11, rdi
- mov qword ptr [-248+rbp], r12
- mov r13, r11
- mov rax, qword ptr [56+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [64+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [72+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [160+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, r10
- mov rdx, rsi
- mov rbx, r8
- mov r12, rdi
- add r9, rdx
- adc r13, rbx
- adc rax, r12
- add r9, rdx
- adc r13, rbx
- adc rax, r12
- mov r11, r12
- mov r8, rdx
- mov rdx, rax
- mov r12, r13
- mov rdi, rbx
- mov r13, rdx
- mov rsi, r11
- mov rax, qword ptr [152+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov qword ptr [-240+rbp], r9
- mov r9, r13
- mov r13, r10
- mov rax, qword ptr [64+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [72+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [80+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [208+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [200+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [192+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [184+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [176+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [168+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [160+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r8
- mov rdx, rdi
- mov rbx, rsi
- add r12, rax
- adc r9, rdx
- adc r13, rbx
- add r12, rax
- adc r9, rdx
- adc r13, rbx
- mov qword ptr [-232+rbp], r12
- mov r8, rdx
- mov rsi, rax
- mov rdi, rbx
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [72+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [80+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [88+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [168+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, rsi
- mov rbx, r8
- mov rdx, rdi
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- mov r11, rdx
- mov r8, rax
- mov rdi, rbx
- mov rax, qword ptr [160+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-224+rbp], r9
- mov r9, r13
- mov rax, qword ptr [80+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r10
- mov rax, qword ptr [88+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [96+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [208+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [200+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [192+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [184+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [176+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [160+rcx]
- mul qword ptr [168+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rbx, r8
- mov rax, rdi
- mov rdx, rsi
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- mov qword ptr [-216+rbp], r12
- mov rdi, rdx
- mov r8, rax
- mov rsi, rbx
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [88+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [96+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [104+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [160+rcx]
- mul qword ptr [176+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, rsi
- mov rbx, r8
- mov rdx, rdi
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- mov r11, rdx
- mov r8, rax
- mov rdi, rbx
- mov rax, qword ptr [168+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-208+rbp], r9
- mov r9, r13
- mov rax, qword ptr [96+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r10
- mov rax, qword ptr [104+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [112+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [208+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [200+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [192+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [160+rcx]
- mul qword ptr [184+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [168+rcx]
- mul qword ptr [176+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rbx, r8
- mov rax, rdi
- mov rdx, rsi
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- mov qword ptr [-200+rbp], r12
- mov rdi, rdx
- mov r8, rax
- mov rsi, rbx
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [104+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [112+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [120+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [160+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [168+rcx]
- mul qword ptr [184+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, rsi
- mov rbx, r8
- mov rdx, rdi
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- mov r11, rdx
- mov r8, rax
- mov rdi, rbx
- mov rax, qword ptr [176+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-192+rbp], r9
- mov r9, r13
- mov rax, qword ptr [112+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r10
- mov rax, qword ptr [120+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [128+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [208+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [160+rcx]
- mul qword ptr [200+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [168+rcx]
- mul qword ptr [192+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [176+rcx]
- mul qword ptr [184+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rbx, r8
- mov rax, rdi
- mov rdx, rsi
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- add r12, rbx
- adc r9, rax
- adc r13, rdx
- mov qword ptr [-184+rbp], r12
- mov rdi, rdx
- mov r8, rax
- mov rsi, rbx
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [120+rcx]
- mul qword ptr [248+rcx]
- mov rsi, rax
- mov r8, rdx
- xor rdi, rdi
- mov rax, qword ptr [128+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [136+rcx]
- mul qword ptr [232+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [224+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [216+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [160+rcx]
- mul qword ptr [208+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [168+rcx]
- mul qword ptr [200+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, qword ptr [176+rcx]
- mul qword ptr [192+rcx]
- add rsi, rax
- adc r8, rdx
- adc rdi, 0
- mov rax, rsi
- mov rbx, r8
- mov rdx, rdi
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- add r9, rax
- adc r12, rbx
- adc r13, rdx
- mov r11, rdx
- mov r8, rax
- mov rdi, rbx
- mov rax, qword ptr [184+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-176+rbp], r9
- mov r9, r13
- mov rax, qword ptr [128+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov r13, r10
- mov rax, qword ptr [136+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [144+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [160+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [168+rcx]
- mul qword ptr [208+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [176+rcx]
- mul qword ptr [200+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [184+rcx]
- mul qword ptr [192+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add r12, r8
- adc r9, rdi
- adc r13, rsi
- add r12, r8
- adc r9, rdi
- adc r13, rsi
- mov qword ptr [-168+rbp], r12
- mov r12, r13
- mov r13, r10
- mov rax, qword ptr [136+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [144+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [152+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [160+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [168+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [176+rcx]
- mul qword ptr [208+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [184+rcx]
- mul qword ptr [200+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rbx, rdi
- mov rax, rsi
- add r9, r8
- adc r12, rbx
- adc r13, rax
- add r9, r8
- adc r12, rbx
- adc r13, rax
- mov r11, rax
- mov rdi, rbx
- mov rbx, r10
- mov rax, qword ptr [192+rcx]
- mul rax
- add r9, rax
- adc r12, rdx
- adc r13, 0
- mov rsi, r11
- mov qword ptr [-160+rbp], r9
- mov r9, r13
- mov rax, qword ptr [144+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [152+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [160+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [168+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [176+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [184+rcx]
- mul qword ptr [208+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [192+rcx]
- mul qword ptr [200+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add r12, r8
- adc r9, rdi
- adc rbx, rsi
- add r12, r8
- adc r9, rdi
- adc rbx, rsi
- mov qword ptr [-152+rbp], r12
- mov rax, qword ptr [152+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [160+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [168+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [176+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [184+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [192+rcx]
- mul qword ptr [208+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rdx, r10
- mov r13, rdi
- mov r12, rsi
- add r9, r8
- adc rbx, r13
- adc rdx, r12
- add r9, r8
- adc rbx, r13
- adc rdx, r12
- mov rax, rdx
- mov rdi, r13
- mov rsi, r12
- mov r11, rax
- mov r12, r10
- mov rax, qword ptr [200+rcx]
- mul rax
- add r9, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-144+rbp], r9
- mov r9, r11
- mov rax, qword ptr [160+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [168+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [176+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [184+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [192+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [200+rcx]
- mul qword ptr [208+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add rbx, r8
- adc r9, rdi
- adc r12, rsi
- add rbx, r8
- adc r9, rdi
- adc r12, rsi
- mov qword ptr [-136+rbp], rbx
- mov r11, r12
- mov rax, qword ptr [168+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [176+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [184+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [192+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [200+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r10
- mov r13, rdi
- mov r12, rsi
- add r9, r8
- adc r11, r13
- adc rax, r12
- add r9, r8
- adc r11, r13
- adc rax, r12
- mov rdx, rax
- mov rbx, r11
- mov rdi, r13
- mov r11, rdx
- mov rsi, r12
- mov rax, qword ptr [208+rcx]
- mul rax
- add r9, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-128+rbp], r9
- mov r9, r11
- mov rax, qword ptr [176+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [184+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [192+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [200+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [208+rcx]
- mul qword ptr [216+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rdx, r10
- add rbx, r8
- adc r9, rdi
- adc rdx, rsi
- add rbx, r8
- adc r9, rdi
- adc rdx, rsi
- mov qword ptr [-120+rbp], rbx
- mov r11, rdx
- mov rbx, r10
- mov rax, qword ptr [184+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [192+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [200+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [208+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov r13, rdi
- mov r12, rsi
- add r9, r8
- adc r11, r13
- adc rbx, r12
- add r9, r8
- adc r11, r13
- adc rbx, r12
- mov rdx, rbx
- mov rdi, r13
- mov rbx, r11
- mov rsi, r12
- mov r11, rdx
- mov r12, r10
- mov rax, qword ptr [216+rcx]
- mul rax
- add r9, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-112+rbp], r9
- mov r9, r11
- mov rax, qword ptr [192+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [200+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [208+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [216+rcx]
- mul qword ptr [224+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- add rbx, r8
- adc r9, rdi
- adc r12, rsi
- add rbx, r8
- adc r9, rdi
- adc r12, rsi
- mov qword ptr [-104+rbp], rbx
- mov r11, r12
- mov rax, qword ptr [200+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [208+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [216+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, r10
- mov r13, rdi
- mov r12, rsi
- add r9, r8
- adc r11, r13
- adc rax, r12
- add r9, r8
- adc r11, r13
- adc rax, r12
- mov rdx, rax
- mov rbx, r11
- mov rdi, r13
- mov r11, rdx
- mov rsi, r12
- mov r12, r10
- mov rax, qword ptr [224+rcx]
- mul rax
- add r9, rax
- adc rbx, rdx
- adc r11, 0
- mov qword ptr [-96+rbp], r9
- mov r9, r10
- mov rax, qword ptr [208+rcx]
- mul qword ptr [248+rcx]
- mov r8, rax
- mov rdi, rdx
- xor rsi, rsi
- mov rax, qword ptr [216+rcx]
- mul qword ptr [240+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov rax, qword ptr [224+rcx]
- mul qword ptr [232+rcx]
- add r8, rax
- adc rdi, rdx
- adc rsi, 0
- mov r13, rdi
- mov rax, rsi
- add rbx, r8
- adc r11, r13
- adc r9, rax
- add rbx, r8
- adc r11, r13
- adc r9, rax
- mov qword ptr [-88+rbp], rbx
- mov rsi, r11
- mov r8, r9
- mov rax, qword ptr [216+rcx]
- mul qword ptr [248+rcx]
- add rsi, rax
- adc r8, rdx
- adc r12, 0
- add rsi, rax
- adc r8, rdx
- adc r12, 0
- mov r11, r12
- mov rax, qword ptr [224+rcx]
- mul qword ptr [240+rcx]
- add rsi, rax
- adc r8, rdx
- adc r11, 0
- add rsi, rax
- adc r8, rdx
- adc r11, 0
- mov r13, r8
- mov rbx, r11
- mov rax, qword ptr [232+rcx]
- mul rax
- add rsi, rax
- adc r13, rdx
- adc rbx, 0
- mov qword ptr [-80+rbp], rsi
- mov r12, rbx
- mov rdi, r13
- mov r13, r10
- mov rax, qword ptr [224+rcx]
- mul qword ptr [248+rcx]
- add rdi, rax
- adc r12, rdx
- adc r13, 0
- add rdi, rax
- adc r12, rdx
- adc r13, 0
- mov r9, r12
- mov r12, r13
- mov rax, qword ptr [232+rcx]
- mul qword ptr [240+rcx]
- add rdi, rax
- adc r9, rdx
- adc r12, 0
- add rdi, rax
- adc r9, rdx
- adc r12, 0
- mov qword ptr [-72+rbp], rdi
- mov r11, r9
- mov rbx, r12
- mov r9, r10
- mov rax, qword ptr [232+rcx]
- mul qword ptr [248+rcx]
- add r11, rax
- adc rbx, rdx
- adc r9, 0
- add r11, rax
- adc rbx, rdx
- adc r9, 0
- mov r13, rbx
- mov rbx, r9
- mov r9, r10
- mov rax, qword ptr [240+rcx]
- mul rax
- add r11, rax
- adc r13, rdx
- adc rbx, 0
- mov qword ptr [-64+rbp], r11
- mov rdi, r13
- mov rsi, rbx
- mov rax, qword ptr [240+rcx]
- mul qword ptr [248+rcx]
- add rdi, rax
- adc rsi, rdx
- adc r9, 0
- add rdi, rax
- adc rsi, rdx
- adc r9, 0
- mov qword ptr [-56+rbp], rdi
- mov r8, r9
- mov rax, qword ptr [248+rcx]
- mul rax
- add rsi, rax
- adc r8, rdx
- adc r10, 0
- mov qword ptr [-48+rbp], rsi
- mov qword ptr [-40+rbp], r8
- mov dword ptr [8+r14], 64
- mov dword ptr [r14], 0
-; mov rdi, qword ptr [16+r14]
-; lea rsi, qword ptr [-544+rbp]
-; mov edx, 512
- mov rcx, qword ptr [16+r14]
- lea rdx, qword ptr [-544+rbp]
- mov r8d, 512
- call memcpy
- mov edx, dword ptr [8+r14]
- test edx, edx
- je L304
- lea ecx, dword ptr [-1+rdx]
- mov rsi, qword ptr [16+r14]
- mov r10d, ecx
- cmp dword ptr [rsi+r10*8], 0
- jne L302
- mov edx, ecx
- ALIGN 16
-L303:
- test edx, edx
- mov ecx, edx
- je L307
- dec edx
- mov eax, edx
- cmp dword ptr [rsi+rax*8], 0
- je L303
- mov dword ptr [8+r14], ecx
- mov edx, ecx
-L302:
- test edx, edx
- je L304
- mov eax, dword ptr [r14]
- jmp L305
-
-L307:
- mov dword ptr [8+r14], edx
-L304:
- xor eax, eax
-L305:
- mov dword ptr [r14], eax
- add rsp, 512+32 ; +32 for "home" storage
- pop rbx
- pop r12
- pop r13
- pop r14
- pop rbp
-
- pop rsi
- pop rdi
-
- ret
-
-s_mp_sqr_comba_32 ENDP
-
-END
diff --git a/security/nss/lib/freebl/mpi/mp_comba_amd64_sun.s b/security/nss/lib/freebl/mpi/mp_comba_amd64_sun.s
deleted file mode 100644
index a5181df33..000000000
--- a/security/nss/lib/freebl/mpi/mp_comba_amd64_sun.s
+++ /dev/null
@@ -1,16097 +0,0 @@
-//* TomsFastMath, a fast ISO C bignum library.
-/ *
-/ * This project is meant to fill in where LibTomMath
-/ * falls short. That is speed ;-)
-/ *
-/ * This project is public domain and free for all purposes.
-/ *
-/ * Tom St Denis, tomstdenis@iahu.ca
-/ */
-
-//*
-/ * The source file from which this assembly was derived
-/ * comes from TFM v0.03, which has the above license.
-/ * This source was compiled with an unnamed compiler at
-/ * the highest optimization level. Afterwards, the
-/ * trailing .section was removed because it causes errors
-/ * in the Studio 10 compiler on AMD 64.
-/ */
-
- .file "mp_comba.c"
- .text
- .align 16
-.globl s_mp_mul_comba_4
- .type s_mp_mul_comba_4, @function
-s_mp_mul_comba_4:
-.LFB2:
- pushq %r12
-.LCFI0:
- pushq %rbp
-.LCFI1:
- pushq %rbx
-.LCFI2:
- movq 16(%rdi), %r9
- movq %rdx, %rbx
- movq 16(%rsi), %rdx
- movq (%r9), %rax
- movq %rax, -64(%rsp)
- movq 8(%r9), %r8
- movq %r8, -56(%rsp)
- movq 16(%r9), %rbp
- movq %rbp, -48(%rsp)
- movq 24(%r9), %r12
- movq %r12, -40(%rsp)
- movq (%rdx), %rcx
- movq %rcx, -32(%rsp)
- movq 8(%rdx), %r10
- movq %r10, -24(%rsp)
- movq 16(%rdx), %r11
- xorl %r10d, %r10d
- movq %r10, %r8
- movq %r10, %r9
- movq %r10, %rbp
- movq %r11, -16(%rsp)
- movq 16(%rbx), %r11
- movq 24(%rdx), %rax
- movq %rax, -8(%rsp)
-/APP
- movq -64(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rbp
-
-/NO_APP
- movq %r8, (%r11)
- movq %rbp, %r8
- movq %r10, %rbp
-/APP
- movq -64(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%r9
- adcq %rdx,%r8
- adcq $0,%rbp
-
-/NO_APP
- movq %rbp, %r12
-/APP
- movq -56(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%r9
- adcq %rdx,%r8
- adcq $0,%r12
-
-/NO_APP
- movq %r9, 8(%r11)
- movq %r12, %r9
- movq %r10, %r12
-/APP
- movq -64(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%r12
-
-/NO_APP
- movq %r12, %rcx
-/APP
- movq -56(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -48(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 16(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -64(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -56(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -48(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -40(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 24(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -56(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -48(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -40(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 32(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -48(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r8, %r12
- movq %r9, %rbp
-/APP
- movq -40(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 40(%r11)
- movq %rbp, %r8
- movq %r12, %rcx
-/APP
- movq -40(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%r8
- adcq %rdx,%rcx
- adcq $0,%r10
-
-/NO_APP
- movq %r8, 48(%r11)
- movl (%rsi), %esi
- xorl (%rdi), %esi
- testq %rcx, %rcx
- movq %rcx, 56(%r11)
- movl $8, 8(%rbx)
- jne .L9
- .align 16
-.L18:
- movl 8(%rbx), %edx
- leal -1(%rdx), %edi
- testl %edi, %edi
- movl %edi, 8(%rbx)
- je .L9
- leal -2(%rdx), %r10d
- cmpq $0, (%r11,%r10,8)
- je .L18
-.L9:
- movl 8(%rbx), %edx
- xorl %r11d, %r11d
- testl %edx, %edx
- cmovne %esi, %r11d
- movl %r11d, (%rbx)
- popq %rbx
- popq %rbp
- popq %r12
- ret
-.LFE2:
- .size s_mp_mul_comba_4, .-s_mp_mul_comba_4
- .align 16
-.globl s_mp_mul_comba_8
- .type s_mp_mul_comba_8, @function
-s_mp_mul_comba_8:
-.LFB3:
- pushq %r12
-.LCFI3:
- pushq %rbp
-.LCFI4:
- pushq %rbx
-.LCFI5:
- movq %rdx, %rbx
- subq $8, %rsp
-.LCFI6:
- movq 16(%rdi), %rdx
- movq (%rdx), %r8
- movq %r8, -120(%rsp)
- movq 8(%rdx), %rbp
- movq %rbp, -112(%rsp)
- movq 16(%rdx), %r9
- movq %r9, -104(%rsp)
- movq 24(%rdx), %r12
- movq %r12, -96(%rsp)
- movq 32(%rdx), %rcx
- movq %rcx, -88(%rsp)
- movq 40(%rdx), %r10
- movq %r10, -80(%rsp)
- movq 48(%rdx), %r11
- movq %r11, -72(%rsp)
- movq 56(%rdx), %rax
- movq 16(%rsi), %rdx
- movq %rax, -64(%rsp)
- movq (%rdx), %r8
- movq %r8, -56(%rsp)
- movq 8(%rdx), %rbp
- movq %rbp, -48(%rsp)
- movq 16(%rdx), %r9
- movq %r9, -40(%rsp)
- movq 24(%rdx), %r12
- movq %r12, -32(%rsp)
- movq 32(%rdx), %rcx
- movq %rcx, -24(%rsp)
- movq 40(%rdx), %r10
- movq %r10, -16(%rsp)
- movq 48(%rdx), %r11
- xorl %r10d, %r10d
- movq %r10, %r8
- movq %r10, %r9
- movq %r10, %rbp
- movq %r11, -8(%rsp)
- movq 16(%rbx), %r11
- movq 56(%rdx), %rax
- movq %rax, (%rsp)
-/APP
- movq -120(%rsp),%rax
- mulq -56(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rbp
-
-/NO_APP
- movq %r8, (%r11)
- movq %rbp, %r8
- movq %r10, %rbp
-/APP
- movq -120(%rsp),%rax
- mulq -48(%rsp)
- addq %rax,%r9
- adcq %rdx,%r8
- adcq $0,%rbp
-
-/NO_APP
- movq %rbp, %r12
-/APP
- movq -112(%rsp),%rax
- mulq -56(%rsp)
- addq %rax,%r9
- adcq %rdx,%r8
- adcq $0,%r12
-
-/NO_APP
- movq %r9, 8(%r11)
- movq %r12, %r9
- movq %r10, %r12
-/APP
- movq -120(%rsp),%rax
- mulq -40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%r12
-
-/NO_APP
- movq %r12, %rcx
-/APP
- movq -112(%rsp),%rax
- mulq -48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -104(%rsp),%rax
- mulq -56(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 16(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq -40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq -48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -96(%rsp),%rax
- mulq -56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 24(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -120(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -112(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq -40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq -48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -88(%rsp),%rax
- mulq -56(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 32(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq -40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq -48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -80(%rsp),%rax
- mulq -56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 40(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -120(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -112(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq -40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq -48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -72(%rsp),%rax
- mulq -56(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 48(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq (%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq -40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq -48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -64(%rsp),%rax
- mulq -56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 56(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -112(%rsp),%rax
- mulq (%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq -40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -64(%rsp),%rax
- mulq -48(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 64(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -104(%rsp),%rax
- mulq (%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -64(%rsp),%rax
- mulq -40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 72(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -96(%rsp),%rax
- mulq (%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -64(%rsp),%rax
- mulq -32(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 80(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -88(%rsp),%rax
- mulq (%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -64(%rsp),%rax
- mulq -24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 88(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -80(%rsp),%rax
- mulq (%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -64(%rsp),%rax
- mulq -16(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 96(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -72(%rsp),%rax
- mulq (%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r8, %r12
- movq %r9, %rbp
-/APP
- movq -64(%rsp),%rax
- mulq -8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 104(%r11)
- movq %rbp, %r8
- movq %r12, %rcx
-/APP
- movq -64(%rsp),%rax
- mulq (%rsp)
- addq %rax,%r8
- adcq %rdx,%rcx
- adcq $0,%r10
-
-/NO_APP
- movq %r8, 112(%r11)
- movl (%rsi), %esi
- xorl (%rdi), %esi
- testq %rcx, %rcx
- movq %rcx, 120(%r11)
- movl $16, 8(%rbx)
- jne .L35
- .align 16
-.L43:
- movl 8(%rbx), %edx
- leal -1(%rdx), %edi
- testl %edi, %edi
- movl %edi, 8(%rbx)
- je .L35
- leal -2(%rdx), %eax
- cmpq $0, (%r11,%rax,8)
- je .L43
-.L35:
- movl 8(%rbx), %r11d
- xorl %edx, %edx
- testl %r11d, %r11d
- cmovne %esi, %edx
- movl %edx, (%rbx)
- addq $8, %rsp
- popq %rbx
- popq %rbp
- popq %r12
- ret
-.LFE3:
- .size s_mp_mul_comba_8, .-s_mp_mul_comba_8
- .align 16
-.globl s_mp_mul_comba_16
- .type s_mp_mul_comba_16, @function
-s_mp_mul_comba_16:
-.LFB4:
- pushq %r12
-.LCFI7:
- pushq %rbp
-.LCFI8:
- pushq %rbx
-.LCFI9:
- movq %rdx, %rbx
- subq $136, %rsp
-.LCFI10:
- movq 16(%rdi), %rax
- movq (%rax), %r8
- movq %r8, -120(%rsp)
- movq 8(%rax), %rbp
- movq %rbp, -112(%rsp)
- movq 16(%rax), %r9
- movq %r9, -104(%rsp)
- movq 24(%rax), %r12
- movq %r12, -96(%rsp)
- movq 32(%rax), %rcx
- movq %rcx, -88(%rsp)
- movq 40(%rax), %r10
- movq %r10, -80(%rsp)
- movq 48(%rax), %rdx
- movq %rdx, -72(%rsp)
- movq 56(%rax), %r11
- movq %r11, -64(%rsp)
- movq 64(%rax), %r8
- movq %r8, -56(%rsp)
- movq 72(%rax), %rbp
- movq %rbp, -48(%rsp)
- movq 80(%rax), %r9
- movq %r9, -40(%rsp)
- movq 88(%rax), %r12
- movq %r12, -32(%rsp)
- movq 96(%rax), %rcx
- movq %rcx, -24(%rsp)
- movq 104(%rax), %r10
- movq %r10, -16(%rsp)
- movq 112(%rax), %rdx
- movq %rdx, -8(%rsp)
- movq 120(%rax), %r11
- movq %r11, (%rsp)
- movq 16(%rsi), %r11
- movq (%r11), %r8
- movq %r8, 8(%rsp)
- movq 8(%r11), %rbp
- movq %rbp, 16(%rsp)
- movq 16(%r11), %r9
- movq %r9, 24(%rsp)
- movq 24(%r11), %r12
- movq %r12, 32(%rsp)
- movq 32(%r11), %rcx
- movq %rcx, 40(%rsp)
- movq 40(%r11), %r10
- movq %r10, 48(%rsp)
- movq 48(%r11), %rdx
- movq %rdx, 56(%rsp)
- movq 56(%r11), %rax
- movq %rax, 64(%rsp)
- movq 64(%r11), %r8
- movq %r8, 72(%rsp)
- movq 72(%r11), %rbp
- movq %rbp, 80(%rsp)
- movq 80(%r11), %r9
- movq %r9, 88(%rsp)
- movq 88(%r11), %r12
- movq %r12, 96(%rsp)
- movq 96(%r11), %rcx
- movq %rcx, 104(%rsp)
- movq 104(%r11), %r10
- movq %r10, 112(%rsp)
- movq 112(%r11), %rdx
- xorl %r10d, %r10d
- movq %r10, %r8
- movq %r10, %r9
- movq %r10, %rbp
- movq %rdx, 120(%rsp)
- movq 120(%r11), %rax
- movq %rax, 128(%rsp)
- movq 16(%rbx), %r11
-/APP
- movq -120(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rbp
-
-/NO_APP
- movq %r8, (%r11)
- movq %rbp, %r8
- movq %r10, %rbp
-/APP
- movq -120(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%r9
- adcq %rdx,%r8
- adcq $0,%rbp
-
-/NO_APP
- movq %rbp, %r12
-/APP
- movq -112(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%r9
- adcq %rdx,%r8
- adcq $0,%r12
-
-/NO_APP
- movq %r9, 8(%r11)
- movq %r12, %r9
- movq %r10, %r12
-/APP
- movq -120(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%r12
-
-/NO_APP
- movq %r12, %rcx
-/APP
- movq -112(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -104(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 16(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -96(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 24(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -120(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -112(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -88(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 32(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -80(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 40(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -120(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -112(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -72(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 48(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -64(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 56(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -120(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -112(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -64(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -56(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 64(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -64(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -56(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -48(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 72(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -120(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -112(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -64(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -56(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -48(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -40(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 80(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -64(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -56(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -48(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -40(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -32(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 88(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -120(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -112(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -64(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -56(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -48(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -40(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -32(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -24(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 96(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -64(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -56(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -48(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -40(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -32(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -24(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq -16(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 104(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -120(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -112(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -64(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -56(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -48(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -40(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -32(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -24(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -16(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq -8(%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 112(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -120(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -112(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -104(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -64(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -56(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -48(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -40(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -32(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -24(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -16(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -8(%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq (%rsp),%rax
- mulq 8(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 120(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -112(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -104(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -96(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -64(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -56(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -48(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -40(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -32(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -24(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -16(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -8(%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq (%rsp),%rax
- mulq 16(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 128(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -104(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -96(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -88(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -64(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -56(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -48(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -40(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -32(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -24(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -16(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -8(%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq (%rsp),%rax
- mulq 24(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 136(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -96(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -88(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -80(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -64(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -56(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -48(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -40(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -32(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -24(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -16(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -8(%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq (%rsp),%rax
- mulq 32(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 144(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -88(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -80(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -72(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -64(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -56(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -48(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -40(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -32(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -24(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -16(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -8(%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq (%rsp),%rax
- mulq 40(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 152(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -80(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -72(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -64(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -56(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -48(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -40(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -32(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -24(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -16(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -8(%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq (%rsp),%rax
- mulq 48(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 160(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -72(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -64(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -56(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -48(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -40(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -32(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -24(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -16(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -8(%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq (%rsp),%rax
- mulq 56(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 168(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -64(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -56(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -48(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -40(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -32(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -24(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -16(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -8(%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq (%rsp),%rax
- mulq 64(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 176(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -56(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -48(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -40(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -32(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -24(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -16(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -8(%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq (%rsp),%rax
- mulq 72(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 184(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -48(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -40(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -32(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -24(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -16(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -8(%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq (%rsp),%rax
- mulq 80(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 192(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -40(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -32(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -24(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -16(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -8(%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq (%rsp),%rax
- mulq 88(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 200(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -32(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -24(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -16(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -8(%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq (%rsp),%rax
- mulq 96(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 208(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -24(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -16(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
- movq -8(%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbp
- movq %r8, %r12
-/APP
- movq (%rsp),%rax
- mulq 104(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 216(%r11)
- movq %r12, %r9
- movq %rbp, %r8
- movq %r10, %rcx
-/APP
- movq -16(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
- movq -8(%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rcx
-
-/NO_APP
- movq %r9, %rbp
- movq %rcx, %r12
-/APP
- movq (%rsp),%rax
- mulq 112(%rsp)
- addq %rax,%r8
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %r8, 224(%r11)
- movq %r12, %r9
- movq %rbp, %rcx
- movq %r10, %r8
-/APP
- movq -8(%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%rcx
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r8, %r12
- movq %r9, %rbp
-/APP
- movq (%rsp),%rax
- mulq 120(%rsp)
- addq %rax,%rcx
- adcq %rdx,%rbp
- adcq $0,%r12
-
-/NO_APP
- movq %rcx, 232(%r11)
- movq %rbp, %r8
- movq %r12, %rcx
-/APP
- movq (%rsp),%rax
- mulq 128(%rsp)
- addq %rax,%r8
- adcq %rdx,%rcx
- adcq $0,%r10
-
-/NO_APP
- movq %r8, 240(%r11)
- movl (%rsi), %esi
- xorl (%rdi), %esi
- testq %rcx, %rcx
- movq %rcx, 248(%r11)
- movl $32, 8(%rbx)
- jne .L76
- .align 16
-.L84:
- movl 8(%rbx), %edx
- leal -1(%rdx), %edi
- testl %edi, %edi
- movl %edi, 8(%rbx)
- je .L76
- leal -2(%rdx), %eax
- cmpq $0, (%r11,%rax,8)
- je .L84
-.L76:
- movl 8(%rbx), %edx
- xorl %r11d, %r11d
- testl %edx, %edx
- cmovne %esi, %r11d
- movl %r11d, (%rbx)
- addq $136, %rsp
- popq %rbx
- popq %rbp
- popq %r12
- ret
-.LFE4:
- .size s_mp_mul_comba_16, .-s_mp_mul_comba_16
- .align 16
-.globl s_mp_mul_comba_32
- .type s_mp_mul_comba_32, @function
-s_mp_mul_comba_32:
-.LFB5:
- pushq %rbp
-.LCFI11:
- movq %rsp, %rbp
-.LCFI12:
- pushq %r13
-.LCFI13:
- movq %rdx, %r13
- movl $256, %edx
- pushq %r12
-.LCFI14:
- movq %rsi, %r12
- pushq %rbx
-.LCFI15:
- movq %rdi, %rbx
- subq $520, %rsp
-.LCFI16:
- movq 16(%rdi), %rsi
- leaq -544(%rbp), %rdi
- call memcpy@PLT
- movq 16(%r12), %rsi
- leaq -288(%rbp), %rdi
- movl $256, %edx
- call memcpy@PLT
- movq 16(%r13), %r9
- xorl %r8d, %r8d
- movq %r8, %rsi
- movq %r8, %rdi
- movq %r8, %r10
-/APP
- movq -544(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%r10
-
-/NO_APP
- movq %rsi, (%r9)
- movq %r10, %rsi
- movq %r8, %r10
-/APP
- movq -544(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%r10
-
-/NO_APP
- movq %r10, %r11
-/APP
- movq -536(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%r11
-
-/NO_APP
- movq %rdi, 8(%r9)
- movq %r11, %rdi
- movq %r8, %r11
-/APP
- movq -544(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%r11
-
-/NO_APP
- movq %r11, %rcx
-/APP
- movq -536(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -528(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 16(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -520(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 24(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -512(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 32(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -504(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 40(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -496(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 48(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -488(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 56(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -480(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 64(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -472(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 72(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -464(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 80(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -456(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 88(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -448(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 96(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -440(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 104(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -432(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 112(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -424(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 120(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -416(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 128(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -408(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 136(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -400(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 144(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -392(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 152(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -384(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 160(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -376(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 168(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -368(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 176(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -360(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 184(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -352(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 192(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -344(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 200(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -336(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 208(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -328(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 216(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -320(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 224(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -312(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 232(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -544(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -536(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -304(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 240(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -544(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -536(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -528(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -288(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 248(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -536(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -528(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -520(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -280(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 256(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -528(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -520(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -512(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -272(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 264(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -520(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -512(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -504(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -264(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 272(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -512(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -504(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -496(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -256(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 280(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -504(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -496(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -488(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -248(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 288(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -496(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -488(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -480(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -240(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 296(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -488(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -480(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -472(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -232(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 304(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -480(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -472(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -464(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -224(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 312(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -472(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -464(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -456(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -448(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -440(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -216(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 320(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -464(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -456(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -448(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -440(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -432(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -208(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 328(%r9)
- movq %r11, %rdi
- movq %r10, %r11
- movq %r8, %r10
-/APP
- movq -456(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -448(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -440(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -432(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -424(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -416(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -408(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -400(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -392(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -384(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -376(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -368(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -360(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -352(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -344(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -336(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -328(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -320(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -312(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -304(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
- movq -296(%rbp),%rax
- mulq -200(%rbp)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%r10
-
-/NO_APP
- movq %r11, 336(%r9)
- movq %r10, %rsi
- movq %r8, %r10
-/APP
- movq -448(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%r10
-
-/NO_APP
- movq %r10, %rcx
-/APP
- movq -440(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -432(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rcx
-
-/NO_APP
- movq %rsi, %r11
- movq %rcx, %r10
-/APP
- movq -296(%rbp),%rax
- mulq -192(%rbp)
- addq %rax,%rdi
- adcq %rdx,%r11
- adcq $0,%r10
-
-/NO_APP
- movq %rdi, 344(%r9)
- movq %r11, %rcx
- movq %r10, %rdi
- movq %r8, %r11
-/APP
- movq -440(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%r11
-
-/NO_APP
- movq %r11, %rsi
-/APP
- movq -432(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -424(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -184(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 352(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -432(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -424(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -416(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -176(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 360(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -424(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -416(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -408(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -168(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 368(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -416(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -408(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -400(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -160(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 376(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -408(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -400(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -392(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -152(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 384(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -400(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -392(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -384(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -144(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 392(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -392(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -384(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -376(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -136(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 400(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -384(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -376(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -368(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -128(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 408(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -376(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -368(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -360(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -120(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 416(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -368(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -360(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -352(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -112(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 424(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -360(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -352(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -344(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -104(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 432(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -352(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -344(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -336(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -96(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 440(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -344(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -336(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -328(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -88(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 448(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -336(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -328(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -320(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -80(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 456(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -328(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -320(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -312(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -72(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 464(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -320(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -312(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
- movq -304(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rdi, %r10
- movq %rcx, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -64(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 472(%r9)
- movq %r11, %rdi
- movq %r10, %rcx
- movq %r8, %rsi
-/APP
- movq -312(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq -304(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r10
- movq %rsi, %r11
-/APP
- movq -296(%rbp),%rax
- mulq -56(%rbp)
- addq %rax,%rcx
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rcx, 480(%r9)
- movq %r11, %rdi
- movq %r10, %rsi
- movq %r8, %rcx
-/APP
- movq -304(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rsi
- adcq %rdx,%rdi
- adcq $0,%rcx
-
-/NO_APP
- movq %rcx, %r11
- movq %rdi, %r10
-/APP
- movq -296(%rbp),%rax
- mulq -48(%rbp)
- addq %rax,%rsi
- adcq %rdx,%r10
- adcq $0,%r11
-
-/NO_APP
- movq %rsi, 488(%r9)
- movq %r10, %rcx
- movq %r11, %rsi
-/APP
- movq -296(%rbp),%rax
- mulq -40(%rbp)
- addq %rax,%rcx
- adcq %rdx,%rsi
- adcq $0,%r8
-
-/NO_APP
- movq %rcx, 496(%r9)
- movl (%r12), %ecx
- xorl (%rbx), %ecx
- testq %rsi, %rsi
- movq %rsi, 504(%r9)
- movl $64, 8(%r13)
- jne .L149
- .align 16
-.L157:
- movl 8(%r13), %edx
- leal -1(%rdx), %ebx
- testl %ebx, %ebx
- movl %ebx, 8(%r13)
- je .L149
- leal -2(%rdx), %r12d
- cmpq $0, (%r9,%r12,8)
- je .L157
-.L149:
- movl 8(%r13), %r9d
- xorl %edx, %edx
- testl %r9d, %r9d
- cmovne %ecx, %edx
- movl %edx, (%r13)
- addq $520, %rsp
- popq %rbx
- popq %r12
- popq %r13
- leave
- ret
-.LFE5:
- .size s_mp_mul_comba_32, .-s_mp_mul_comba_32
- .align 16
-.globl s_mp_sqr_comba_4
- .type s_mp_sqr_comba_4, @function
-s_mp_sqr_comba_4:
-.LFB6:
- pushq %rbp
-.LCFI17:
- movq %rsi, %r11
- xorl %esi, %esi
- movq %rsi, %r10
- movq %rsi, %rbp
- movq %rsi, %r8
- pushq %rbx
-.LCFI18:
- movq %rsi, %rbx
- movq 16(%rdi), %rcx
- movq %rsi, %rdi
-/APP
- movq (%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%rbx
- adcq $0,%rdi
-
-/NO_APP
- movq %r10, -72(%rsp)
-/APP
- movq (%rcx),%rax
- mulq 8(%rcx)
- addq %rax,%rbx
- adcq %rdx,%rdi
- adcq $0,%rbp
- addq %rax,%rbx
- adcq %rdx,%rdi
- adcq $0,%rbp
-
-/NO_APP
- movq %rbx, -64(%rsp)
-/APP
- movq (%rcx),%rax
- mulq 16(%rcx)
- addq %rax,%rdi
- adcq %rdx,%rbp
- adcq $0,%r8
- addq %rax,%rdi
- adcq %rdx,%rbp
- adcq $0,%r8
-
-/NO_APP
- movq %rbp, %rbx
- movq %r8, %rbp
-/APP
- movq 8(%rcx),%rax
- mulq %rax
- addq %rax,%rdi
- adcq %rdx,%rbx
- adcq $0,%rbp
-
-/NO_APP
- movq %rdi, -56(%rsp)
- movq %rbp, %r9
- movq %rbx, %r8
- movq %rsi, %rdi
-/APP
- movq (%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rdi
- addq %rax,%r8
- adcq %rdx,%r9
- adcq $0,%rdi
-
-/NO_APP
- movq %r9, %rbx
- movq %rdi, %rbp
-/APP
- movq 8(%rcx),%rax
- mulq 16(%rcx)
- addq %rax,%r8
- adcq %rdx,%rbx
- adcq $0,%rbp
- addq %rax,%r8
- adcq %rdx,%rbx
- adcq $0,%rbp
-
-/NO_APP
- movq %r8, -48(%rsp)
- movq %rbp, %r9
- movq %rbx, %rdi
- movq %rsi, %r8
- movl $8, 8(%r11)
- movl $0, (%r11)
-/APP
- movq 8(%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%rdi
- adcq %rdx,%r9
- adcq $0,%r8
- addq %rax,%rdi
- adcq %rdx,%r9
- adcq $0,%r8
-
-/NO_APP
- movq %r9, %rbx
- movq %r8, %rbp
-/APP
- movq 16(%rcx),%rax
- mulq %rax
- addq %rax,%rdi
- adcq %rdx,%rbx
- adcq $0,%rbp
-
-/NO_APP
- movq %rbp, %rax
- movq %rdi, -40(%rsp)
- movq %rbx, %rbp
- movq %rax, %rdi
- movq %rsi, %rbx
-/APP
- movq 16(%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%rbp
- adcq %rdx,%rdi
- adcq $0,%rbx
- addq %rax,%rbp
- adcq %rdx,%rdi
- adcq $0,%rbx
-
-/NO_APP
- movq %rbp, -32(%rsp)
- movq %rbx, %r9
-/APP
- movq 24(%rcx),%rax
- mulq %rax
- addq %rax,%rdi
- adcq %rdx,%r9
- adcq $0,%rsi
-
-/NO_APP
- movq 16(%r11), %rdx
- movq %rdi, -24(%rsp)
- movq %r9, -16(%rsp)
- movq %r10, (%rdx)
- movq -64(%rsp), %r8
- movq %r8, 8(%rdx)
- movq -56(%rsp), %rbp
- movq %rbp, 16(%rdx)
- movq -48(%rsp), %rdi
- movq %rdi, 24(%rdx)
- movq -40(%rsp), %rsi
- movq %rsi, 32(%rdx)
- movq -32(%rsp), %rbx
- movq %rbx, 40(%rdx)
- movq -24(%rsp), %rcx
- movq %rcx, 48(%rdx)
- movq -16(%rsp), %rax
- movq %rax, 56(%rdx)
- movl 8(%r11), %edx
- testl %edx, %edx
- je .L168
- leal -1(%rdx), %ecx
- movq 16(%r11), %rsi
- mov %ecx, %r10d
- cmpq $0, (%rsi,%r10,8)
- jne .L166
- movl %ecx, %edx
- .align 16
-.L167:
- testl %edx, %edx
- movl %edx, %ecx
- je .L171
- decl %edx
- mov %edx, %eax
- cmpq $0, (%rsi,%rax,8)
- je .L167
- movl %ecx, 8(%r11)
- movl %ecx, %edx
-.L166:
- testl %edx, %edx
- je .L168
- popq %rbx
- popq %rbp
- movl (%r11), %eax
- movl %eax, (%r11)
- ret
-.L171:
- movl %edx, 8(%r11)
- .align 16
-.L168:
- popq %rbx
- popq %rbp
- xorl %eax, %eax
- movl %eax, (%r11)
- ret
-.LFE6:
- .size s_mp_sqr_comba_4, .-s_mp_sqr_comba_4
- .align 16
-.globl s_mp_sqr_comba_8
- .type s_mp_sqr_comba_8, @function
-s_mp_sqr_comba_8:
-.LFB7:
- pushq %r14
-.LCFI19:
- xorl %r9d, %r9d
- movq %r9, %r14
- movq %r9, %r10
- pushq %r13
-.LCFI20:
- movq %r9, %r13
- pushq %r12
-.LCFI21:
- movq %r9, %r12
- pushq %rbp
-.LCFI22:
- movq %rsi, %rbp
- movq %r9, %rsi
- pushq %rbx
-.LCFI23:
- movq %r9, %rbx
- subq $8, %rsp
-.LCFI24:
- movq 16(%rdi), %rcx
-/APP
- movq (%rcx),%rax
- mulq %rax
- addq %rax,%r14
- adcq %rdx,%rbx
- adcq $0,%r12
-
-/NO_APP
- movq %r14, -120(%rsp)
-/APP
- movq (%rcx),%rax
- mulq 8(%rcx)
- addq %rax,%rbx
- adcq %rdx,%r12
- adcq $0,%r10
- addq %rax,%rbx
- adcq %rdx,%r12
- adcq $0,%r10
-
-/NO_APP
- movq %rbx, -112(%rsp)
-/APP
- movq (%rcx),%rax
- mulq 16(%rcx)
- addq %rax,%r12
- adcq %rdx,%r10
- adcq $0,%r13
- addq %rax,%r12
- adcq %rdx,%r10
- adcq $0,%r13
-
-/NO_APP
- movq %r10, %rbx
- movq %r13, %r10
- movq %r9, %r13
-/APP
- movq 8(%rcx),%rax
- mulq %rax
- addq %rax,%r12
- adcq %rdx,%rbx
- adcq $0,%r10
-
-/NO_APP
- movq %r12, -104(%rsp)
- movq %r10, %rdi
- movq %rbx, %r11
-/APP
- movq (%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%rsi
- addq %rax,%r11
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %rbx
- movq %rsi, %r10
- movq %r9, %rdi
-/APP
- movq 8(%rcx),%rax
- mulq 16(%rcx)
- addq %rax,%r11
- adcq %rdx,%rbx
- adcq $0,%r10
- addq %rax,%r11
- adcq %rdx,%rbx
- adcq $0,%r10
-
-/NO_APP
- movq %r9, %rsi
- movq %r11, -96(%rsp)
- movq %r10, %r8
- movq %rbx, %r12
- movq %r9, %r11
-/APP
- movq (%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r12
- adcq %rdx,%r8
- adcq $0,%r13
- addq %rax,%r12
- adcq %rdx,%r8
- adcq $0,%r13
-
- movq 8(%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r12
- adcq %rdx,%r8
- adcq $0,%r13
- addq %rax,%r12
- adcq %rdx,%r8
- adcq $0,%r13
-
-/NO_APP
- movq %r8, %rbx
- movq %r13, %r10
- movq %r9, %r8
-/APP
- movq 16(%rcx),%rax
- mulq %rax
- addq %rax,%r12
- adcq %rdx,%rbx
- adcq $0,%r10
-
-/NO_APP
- movq %r12, -88(%rsp)
-/APP
- movq (%rcx),%rax
- mulq 40(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%r11
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%r11
-
-/NO_APP
- movq %rbx, -80(%rsp)
-/APP
- movq (%rcx),%rax
- mulq 48(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rax
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rax
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rax
-
-/NO_APP
- movq %rax, %rdx
- movq %r11, %rbx
- movq %r13, %rdi
- movq %rdx, %r11
- movq %r12, %rsi
-/APP
- movq 24(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r10, -72(%rsp)
- movq %r11, %r10
-/APP
- movq (%rcx),%rax
- mulq 56(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rax
-/APP
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%rax
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%rax
-
-/NO_APP
- movq %rbx, -64(%rsp)
- movq %rax, %r11
- movq %r9, %rbx
-/APP
- movq 8(%rcx),%rax
- mulq 56(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 16(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rbx
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rbx
-
-/NO_APP
- movq %rbx, %rsi
- movq %r13, %rdi
- movq %r11, %rbx
- movq %r12, %r13
- movq %rsi, %r11
-/APP
- movq 32(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r10, -56(%rsp)
- movq %r9, %r10
-/APP
- movq 16(%rcx),%rax
- mulq 56(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %r13,%r13
-
- movq 24(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%r13
-
- movq 32(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%r13
-
-/NO_APP
- movq %rdi, %r12
- movq %r13, %rax
-/APP
- addq %r8,%rbx
- adcq %r12,%r11
- adcq %rax,%r10
- addq %r8,%rbx
- adcq %r12,%r11
- adcq %rax,%r10
-
-/NO_APP
- movq %rbx, -48(%rsp)
- movq %r11, %r12
- movq %r10, %rsi
- movq %r9, %rbx
- movq %r9, %r11
-/APP
- movq 24(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r12
- adcq %rdx,%rsi
- adcq $0,%rbx
- addq %rax,%r12
- adcq %rdx,%rsi
- adcq $0,%rbx
-
-/NO_APP
- movq %rbx, %r13
-/APP
- movq 32(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r12
- adcq %rdx,%rsi
- adcq $0,%r13
- addq %rax,%r12
- adcq %rdx,%rsi
- adcq $0,%r13
-
-/NO_APP
- movq %rsi, %r10
- movq %r13, %rbx
- movq %r9, %r13
-/APP
- movq 40(%rcx),%rax
- mulq %rax
- addq %rax,%r12
- adcq %rdx,%r10
- adcq $0,%rbx
-
-/NO_APP
- movq %r12, -40(%rsp)
- movq %rbx, %r8
- movq %r10, %rdi
-/APP
- movq 32(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%rdi
- adcq %rdx,%r8
- adcq $0,%r11
- addq %rax,%rdi
- adcq %rdx,%r8
- adcq $0,%r11
-
-/NO_APP
- movq %r8, %r10
- movq %r11, %rbx
-/APP
- movq 40(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%rdi
- adcq %rdx,%r10
- adcq $0,%rbx
- addq %rax,%rdi
- adcq %rdx,%r10
- adcq $0,%rbx
-
-/NO_APP
- movq %rdi, -32(%rsp)
- movq %rbx, %rsi
- movq %r10, %r12
-/APP
- movq 40(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r12
- adcq %rdx,%rsi
- adcq $0,%r13
- addq %rax,%r12
- adcq %rdx,%rsi
- adcq $0,%r13
-
-/NO_APP
- movq %rsi, %r10
- movq %r13, %rbx
-/APP
- movq 48(%rcx),%rax
- mulq %rax
- addq %rax,%r12
- adcq %rdx,%r10
- adcq $0,%rbx
-
-/NO_APP
- movq %r12, -24(%rsp)
- movq %r10, %rdi
- movq %rbx, %rsi
- movq %r9, %r10
- movl $16, 8(%rbp)
- movl $0, (%rbp)
-/APP
- movq 48(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%r10
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%r10
-
-/NO_APP
- movq %rdi, -16(%rsp)
- movq %r10, %r8
-/APP
- movq 56(%rcx),%rax
- mulq %rax
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%r9
-
-/NO_APP
- movq 16(%rbp), %rax
- movq %rsi, -8(%rsp)
- movq %r8, (%rsp)
- movq %r14, (%rax)
- movq -112(%rsp), %rbx
- movq %rbx, 8(%rax)
- movq -104(%rsp), %rcx
- movq %rcx, 16(%rax)
- movq -96(%rsp), %rdx
- movq %rdx, 24(%rax)
- movq -88(%rsp), %r14
- movq %r14, 32(%rax)
- movq -80(%rsp), %r13
- movq %r13, 40(%rax)
- movq -72(%rsp), %r12
- movq %r12, 48(%rax)
- movq -64(%rsp), %r11
- movq %r11, 56(%rax)
- movq -56(%rsp), %r10
- movq %r10, 64(%rax)
- movq -48(%rsp), %r9
- movq %r9, 72(%rax)
- movq -40(%rsp), %r8
- movq %r8, 80(%rax)
- movq -32(%rsp), %rdi
- movq %rdi, 88(%rax)
- movq -24(%rsp), %rsi
- movq %rsi, 96(%rax)
- movq -16(%rsp), %rbx
- movq %rbx, 104(%rax)
- movq -8(%rsp), %rcx
- movq %rcx, 112(%rax)
- movq (%rsp), %rdx
- movq %rdx, 120(%rax)
- movl 8(%rbp), %edx
- testl %edx, %edx
- je .L192
- leal -1(%rdx), %ecx
- movq 16(%rbp), %rsi
- mov %ecx, %r14d
- cmpq $0, (%rsi,%r14,8)
- jne .L190
- movl %ecx, %edx
- .align 16
-.L191:
- testl %edx, %edx
- movl %edx, %ecx
- je .L195
- decl %edx
- mov %edx, %r9d
- cmpq $0, (%rsi,%r9,8)
- je .L191
- movl %ecx, 8(%rbp)
- movl %ecx, %edx
-.L190:
- testl %edx, %edx
- je .L192
- movl (%rbp), %eax
- movl %eax, (%rbp)
- addq $8, %rsp
- popq %rbx
- popq %rbp
- popq %r12
- popq %r13
- popq %r14
- ret
-.L195:
- movl %edx, 8(%rbp)
- .align 16
-.L192:
- xorl %eax, %eax
- movl %eax, (%rbp)
- addq $8, %rsp
- popq %rbx
- popq %rbp
- popq %r12
- popq %r13
- popq %r14
- ret
-.LFE7:
- .size s_mp_sqr_comba_8, .-s_mp_sqr_comba_8
- .align 16
-.globl s_mp_sqr_comba_16
- .type s_mp_sqr_comba_16, @function
-s_mp_sqr_comba_16:
-.LFB8:
- pushq %rbp
-.LCFI25:
- xorl %r9d, %r9d
- movq %r9, %r8
- movq %r9, %r11
- movq %rsp, %rbp
-.LCFI26:
- pushq %r14
-.LCFI27:
- movq %rsi, %r14
- movq %r9, %rsi
- pushq %r13
-.LCFI28:
- movq %r9, %r13
- pushq %r12
-.LCFI29:
- movq %r9, %r12
- pushq %rbx
-.LCFI30:
- movq %r9, %rbx
- subq $256, %rsp
-.LCFI31:
- movq 16(%rdi), %rcx
-/APP
- movq (%rcx),%rax
- mulq %rax
- addq %rax,%r8
- adcq %rdx,%rbx
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, -288(%rbp)
-/APP
- movq (%rcx),%rax
- mulq 8(%rcx)
- addq %rax,%rbx
- adcq %rdx,%rsi
- adcq $0,%r12
- addq %rax,%rbx
- adcq %rdx,%rsi
- adcq $0,%r12
-
-/NO_APP
- movq %rbx, -280(%rbp)
-/APP
- movq (%rcx),%rax
- mulq 16(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r12
- adcq $0,%r13
- addq %rax,%rsi
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r12, %rbx
- movq %r13, %r10
-/APP
- movq 8(%rcx),%rax
- mulq %rax
- addq %rax,%rsi
- adcq %rdx,%rbx
- adcq $0,%r10
-
-/NO_APP
- movq %rsi, -272(%rbp)
- movq %r10, %rdi
- movq %r9, %rsi
- movq %rbx, %r10
-/APP
- movq (%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r10
- adcq %rdx,%rdi
- adcq $0,%r11
- addq %rax,%r10
- adcq %rdx,%rdi
- adcq $0,%r11
-
-/NO_APP
- movq %rdi, %r12
- movq %r11, %rbx
- movq %r9, %rdi
-/APP
- movq 8(%rcx),%rax
- mulq 16(%rcx)
- addq %rax,%r10
- adcq %rdx,%r12
- adcq $0,%rbx
- addq %rax,%r10
- adcq %rdx,%r12
- adcq $0,%rbx
-
-/NO_APP
- movq %r9, %r11
- movq %r10, -264(%rbp)
- movq %rbx, %r8
- movq %r12, %r13
- movq %r9, %r12
-/APP
- movq (%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r13
- adcq %rdx,%r8
- adcq $0,%r12
- addq %rax,%r13
- adcq %rdx,%r8
- adcq $0,%r12
-
- movq 8(%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r13
- adcq %rdx,%r8
- adcq $0,%r12
- addq %rax,%r13
- adcq %rdx,%r8
- adcq $0,%r12
-
-/NO_APP
- movq %r8, %rbx
- movq %r12, %r10
- movq %r9, %r8
-/APP
- movq 16(%rcx),%rax
- mulq %rax
- addq %rax,%r13
- adcq %rdx,%rbx
- adcq $0,%r10
-
-/NO_APP
- movq %r13, -256(%rbp)
-/APP
- movq (%rcx),%rax
- mulq 40(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%r11
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%r11
-
-/NO_APP
- movq %rbx, -248(%rbp)
-/APP
- movq (%rcx),%rax
- mulq 48(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rax
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rax
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rax
-
-/NO_APP
- movq %rax, %rdx
- movq %r11, %rbx
- movq %r13, %rdi
- movq %rdx, %r11
- movq %r12, %rsi
-/APP
- movq 24(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r10, -240(%rbp)
- movq %r11, %r10
-/APP
- movq (%rcx),%rax
- mulq 56(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rdx
-/APP
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%rdx
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%rdx
-
-/NO_APP
- movq %rdx, %r11
- movq %rbx, -232(%rbp)
- movq %r9, %rbx
-/APP
- movq (%rcx),%rax
- mulq 64(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rbx
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rbx
-
- movq 32(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%r11
- adcq $0,%rbx
-
-/NO_APP
- movq %r13, %rdi
- movq %r10, -224(%rbp)
- movq %r12, %rsi
- movq %rbx, %r10
- movq %r9, %r12
-/APP
- movq (%rcx),%rax
- mulq 72(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%r11
- adcq %rdi,%r10
- adcq %rsi,%r12
- addq %r8,%r11
- adcq %rdi,%r10
- adcq %rsi,%r12
-
-/NO_APP
- movq %r11, -216(%rbp)
- movq %r12, %rbx
-/APP
- movq (%rcx),%rax
- mulq 80(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rax
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r10
- adcq %r13,%rbx
- adcq %r12,%rax
- addq %r8,%r10
- adcq %r13,%rbx
- adcq %r12,%rax
-
-/NO_APP
- movq %rax, %rdx
- movq %rbx, %r11
- movq %r13, %rdi
- movq %rdx, %rbx
- movq %r12, %rsi
-/APP
- movq 40(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%r11
- adcq $0,%rbx
-
-/NO_APP
- movq %r10, -208(%rbp)
- movq %rbx, %r10
-/APP
- movq (%rcx),%rax
- mulq 88(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rdx
-/APP
- addq %r8,%r11
- adcq %rdi,%r10
- adcq %rsi,%rdx
- addq %r8,%r11
- adcq %rdi,%r10
- adcq %rsi,%rdx
-
-/NO_APP
- movq %rdx, %r13
- movq %r11, -200(%rbp)
- movq %r13, %r12
-/APP
- movq (%rcx),%rax
- mulq 96(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rax
- movq %rdi, %rdx
- movq %rsi, %r11
-/APP
- addq %r8,%r10
- adcq %rdx,%r12
- adcq %r11,%rax
- addq %r8,%r10
- adcq %rdx,%r12
- adcq %r11,%rax
-
-/NO_APP
- movq %rdx, %rbx
- movq %rax, %r13
- movq %r11, %rsi
-/APP
- movq 48(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %rbx, %rdi
- movq %r10, -192(%rbp)
- movq %r13, %r10
-/APP
- movq (%rcx),%rax
- mulq 104(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r9, %r13
-/APP
- movq 8(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%r12
- adcq %rdi,%r10
- adcq %rsi,%r13
- addq %r8,%r12
- adcq %rdi,%r10
- adcq %rsi,%r13
-
-/NO_APP
- movq %r12, -184(%rbp)
- movq %r13, %r12
-/APP
- movq (%rcx),%rax
- mulq 112(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rax
- movq %rdi, %rbx
- movq %rsi, %rdx
-/APP
- addq %r8,%r10
- adcq %rbx,%r12
- adcq %rdx,%rax
- addq %r8,%r10
- adcq %rbx,%r12
- adcq %rdx,%rax
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r13
- movq %rbx, %rdi
-/APP
- movq 56(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r10, -176(%rbp)
- movq %r13, %r10
-/APP
- movq (%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r9, %r13
-/APP
- movq 8(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%r12
- adcq %rdi,%r10
- adcq %rsi,%r13
- addq %r8,%r12
- adcq %rdi,%r10
- adcq %rsi,%r13
-
-/NO_APP
- movq %r12, -168(%rbp)
- movq %r13, %r12
-/APP
- movq 8(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 16(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rax
- movq %rdi, %rbx
- movq %rsi, %rdx
-/APP
- addq %r8,%r10
- adcq %rbx,%r12
- adcq %rdx,%rax
- addq %r8,%r10
- adcq %rbx,%r12
- adcq %rdx,%rax
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r13
- movq %rbx, %rdi
-/APP
- movq 64(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r10, -160(%rbp)
- movq %r9, %r11
-/APP
- movq 16(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r13, %r10
- movq %r9, %rbx
-/APP
- movq 24(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 64(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%r12
- adcq %rdi,%r10
- adcq %rsi,%r11
- addq %r8,%r12
- adcq %rdi,%r10
- adcq %rsi,%r11
-
-/NO_APP
- movq %r12, -152(%rbp)
-/APP
- movq 24(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 32(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 64(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rbx
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rbx
-
-/NO_APP
- movq %rbx, %rdx
- movq %r13, %rdi
- movq %r11, %rbx
- movq %r12, %rsi
- movq %rdx, %r11
- movq %r9, %r12
-/APP
- movq 72(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r10, -144(%rbp)
- movq %r11, %r10
-/APP
- movq 32(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 40(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 64(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 72(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%r12
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%r12
-
-/NO_APP
- movq %rbx, -136(%rbp)
- movq %r12, %r11
-/APP
- movq 40(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 48(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 64(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 72(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rax
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rax
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rax
-
-/NO_APP
- movq %rax, %rdx
- movq %r11, %rbx
- movq %r13, %rdi
- movq %rdx, %r11
- movq %r12, %rsi
-/APP
- movq 80(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r10, -128(%rbp)
- movq %r11, %r10
-/APP
- movq 48(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 56(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 64(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 72(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 80(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rdx
-/APP
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%rdx
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%rdx
-
-/NO_APP
- movq %rbx, -120(%rbp)
- movq %rdx, %r11
- movq %r9, %rbx
-/APP
- movq 56(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 64(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 72(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 80(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rbx
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rbx
-
-/NO_APP
- movq %rbx, %rdx
- movq %r13, %rdi
- movq %r11, %rbx
- movq %r12, %rsi
- movq %rdx, %r11
- movq %r9, %r12
-/APP
- movq 88(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r10, -112(%rbp)
- movq %r11, %r10
-/APP
- movq 64(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 72(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 80(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 88(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%r12
- addq %r8,%rbx
- adcq %rdi,%r10
- adcq %rsi,%r12
-
-/NO_APP
- movq %rbx, -104(%rbp)
- movq %r12, %r11
-/APP
- movq 72(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 80(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 88(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r9, %rax
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rax
- addq %r8,%r10
- adcq %r13,%r11
- adcq %r12,%rax
-
-/NO_APP
- movq %rax, %rdx
- movq %r11, %rbx
- movq %r13, %rdi
- movq %rdx, %r11
- movq %r12, %rsi
-/APP
- movq 96(%rcx),%rax
- mulq %rax
- addq %rax,%r10
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r10, -96(%rbp)
- movq %r9, %r10
-/APP
- movq 80(%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 88(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 96(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r12
- movq %rsi, %rax
- movq %r9, %rsi
-/APP
- addq %r8,%rbx
- adcq %r12,%r11
- adcq %rax,%r10
- addq %r8,%rbx
- adcq %r12,%r11
- adcq %rax,%r10
-
-/NO_APP
- movq %r9, %r12
- movq %rbx, -88(%rbp)
- movq %r11, %r13
- movq %r10, %r11
-/APP
- movq 88(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%r13
- adcq %rdx,%r11
- adcq $0,%r12
- addq %rax,%r13
- adcq %rdx,%r11
- adcq $0,%r12
-
-/NO_APP
- movq %r12, %rdi
-/APP
- movq 96(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r13
- adcq %rdx,%r11
- adcq $0,%rdi
- addq %rax,%r13
- adcq %rdx,%r11
- adcq $0,%rdi
-
-/NO_APP
- movq %r11, %rbx
- movq %rdi, %r10
- movq %r9, %r11
-/APP
- movq 104(%rcx),%rax
- mulq %rax
- addq %rax,%r13
- adcq %rdx,%rbx
- adcq $0,%r10
-
-/NO_APP
- movq %r13, -80(%rbp)
- movq %r10, %r8
- movq %rbx, %r10
-/APP
- movq 96(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%r10
- adcq %rdx,%r8
- adcq $0,%rsi
- addq %rax,%r10
- adcq %rdx,%r8
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %r12
- movq %rsi, %rbx
-/APP
- movq 104(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r10
- adcq %rdx,%r12
- adcq $0,%rbx
- addq %rax,%r10
- adcq %rdx,%r12
- adcq $0,%rbx
-
-/NO_APP
- movq %r10, -72(%rbp)
- movq %rbx, %r13
- movq %r12, %rbx
-/APP
- movq 104(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rbx
- adcq %rdx,%r13
- adcq $0,%r11
- addq %rax,%rbx
- adcq %rdx,%r13
- adcq $0,%r11
-
-/NO_APP
- movq %r11, %r12
- movq %r13, %r10
-/APP
- movq 112(%rcx),%rax
- mulq %rax
- addq %rax,%rbx
- adcq %rdx,%r10
- adcq $0,%r12
-
-/NO_APP
- movq %rbx, -64(%rbp)
- movq %r10, %rdi
- movq %r9, %rbx
- movq %r12, %rsi
-/APP
- movq 112(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rbx
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%rbx
-
-/NO_APP
- movq %rdi, -56(%rbp)
- movq %rbx, %r8
-/APP
- movq 120(%rcx),%rax
- mulq %rax
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%r9
-
-/NO_APP
- movq %rsi, -48(%rbp)
- movq 16(%r14), %rdi
- leaq -288(%rbp), %rsi
- movl $256, %edx
- movq %r8, -40(%rbp)
- movl $32, 8(%r14)
- movl $0, (%r14)
- call memcpy@PLT
- movl 8(%r14), %edx
- testl %edx, %edx
- je .L232
- leal -1(%rdx), %ecx
- movq 16(%r14), %rsi
- mov %ecx, %r9d
- cmpq $0, (%rsi,%r9,8)
- jne .L230
- movl %ecx, %edx
- .align 16
-.L231:
- testl %edx, %edx
- movl %edx, %ecx
- je .L235
- decl %edx
- mov %edx, %eax
- cmpq $0, (%rsi,%rax,8)
- je .L231
- movl %ecx, 8(%r14)
- movl %ecx, %edx
-.L230:
- testl %edx, %edx
- je .L232
- movl (%r14), %eax
- movl %eax, (%r14)
- addq $256, %rsp
- popq %rbx
- popq %r12
- popq %r13
- popq %r14
- leave
- ret
-.L235:
- movl %edx, 8(%r14)
- .align 16
-.L232:
- xorl %eax, %eax
- movl %eax, (%r14)
- addq $256, %rsp
- popq %rbx
- popq %r12
- popq %r13
- popq %r14
- leave
- ret
-.LFE8:
- .size s_mp_sqr_comba_16, .-s_mp_sqr_comba_16
- .align 16
-.globl s_mp_sqr_comba_32
- .type s_mp_sqr_comba_32, @function
-s_mp_sqr_comba_32:
-.LFB9:
- pushq %rbp
-.LCFI32:
- xorl %r10d, %r10d
- movq %r10, %r8
- movq %r10, %r11
- movq %rsp, %rbp
-.LCFI33:
- pushq %r14
-.LCFI34:
- movq %rsi, %r14
- movq %r10, %rsi
- pushq %r13
-.LCFI35:
- movq %r10, %r13
- pushq %r12
-.LCFI36:
- movq %r10, %r12
- pushq %rbx
-.LCFI37:
- movq %r10, %rbx
- subq $512, %rsp
-.LCFI38:
- movq 16(%rdi), %rcx
-/APP
- movq (%rcx),%rax
- mulq %rax
- addq %rax,%r8
- adcq %rdx,%rbx
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, -544(%rbp)
-/APP
- movq (%rcx),%rax
- mulq 8(%rcx)
- addq %rax,%rbx
- adcq %rdx,%rsi
- adcq $0,%r12
- addq %rax,%rbx
- adcq %rdx,%rsi
- adcq $0,%r12
-
-/NO_APP
- movq %rbx, -536(%rbp)
-/APP
- movq (%rcx),%rax
- mulq 16(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r12
- adcq $0,%r13
- addq %rax,%rsi
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r12, %rbx
- movq %r13, %r9
-/APP
- movq 8(%rcx),%rax
- mulq %rax
- addq %rax,%rsi
- adcq %rdx,%rbx
- adcq $0,%r9
-
-/NO_APP
- movq %rsi, -528(%rbp)
- movq %r9, %rdi
- movq %r10, %rsi
- movq %rbx, %r9
-/APP
- movq (%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r9
- adcq %rdx,%rdi
- adcq $0,%r11
- addq %rax,%r9
- adcq %rdx,%rdi
- adcq $0,%r11
-
-/NO_APP
- movq %rdi, %r12
- movq %r11, %r13
- movq %r10, %rdi
-/APP
- movq 8(%rcx),%rax
- mulq 16(%rcx)
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r10, %r11
- movq %r9, -520(%rbp)
- movq %r13, %r8
- movq %r12, %r13
- movq %r10, %r12
-/APP
- movq (%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r13
- adcq %rdx,%r8
- adcq $0,%r12
- addq %rax,%r13
- adcq %rdx,%r8
- adcq $0,%r12
-
- movq 8(%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r13
- adcq %rdx,%r8
- adcq $0,%r12
- addq %rax,%r13
- adcq %rdx,%r8
- adcq $0,%r12
-
-/NO_APP
- movq %r8, %rbx
- movq %r12, %r9
- movq %r10, %r8
-/APP
- movq 16(%rcx),%rax
- mulq %rax
- addq %rax,%r13
- adcq %rdx,%rbx
- adcq $0,%r9
-
-/NO_APP
- movq %r13, -512(%rbp)
-/APP
- movq (%rcx),%rax
- mulq 40(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 24(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%r11
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%r11
-
-/NO_APP
- movq %rbx, -504(%rbp)
-/APP
- movq (%rcx),%rax
- mulq 48(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r10, %rax
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rax
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rax
-
-/NO_APP
- movq %rax, %rdx
- movq %r11, %rbx
- movq %r13, %rdi
- movq %rdx, %r11
- movq %r12, %rsi
-/APP
- movq 24(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r9, -496(%rbp)
- movq %r11, %r9
-/APP
- movq (%rcx),%rax
- mulq 56(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 32(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r10, %rdx
-/APP
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%rdx
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%rdx
-
-/NO_APP
- movq %rdx, %r11
- movq %rbx, -488(%rbp)
- movq %r10, %rbx
-/APP
- movq (%rcx),%rax
- mulq 64(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rbx
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rbx
-
- movq 32(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r11
- adcq $0,%rbx
-
-/NO_APP
- movq %r13, %rdi
- movq %r9, -480(%rbp)
- movq %r12, %rsi
- movq %rbx, %r9
- movq %r10, %r12
-/APP
- movq (%rcx),%rax
- mulq 72(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 40(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%r11
- adcq %rdi,%r9
- adcq %rsi,%r12
- addq %r8,%r11
- adcq %rdi,%r9
- adcq %rsi,%r12
-
-/NO_APP
- movq %r11, -472(%rbp)
- movq %r12, %rbx
-/APP
- movq (%rcx),%rax
- mulq 80(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r10, %rax
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r9
- adcq %r13,%rbx
- adcq %r12,%rax
- addq %r8,%r9
- adcq %r13,%rbx
- adcq %r12,%rax
-
-/NO_APP
- movq %rax, %rdx
- movq %rbx, %r11
- movq %r13, %rdi
- movq %rdx, %rbx
- movq %r12, %rsi
-/APP
- movq 40(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r11
- adcq $0,%rbx
-
-/NO_APP
- movq %r9, -464(%rbp)
- movq %rbx, %r9
-/APP
- movq (%rcx),%rax
- mulq 88(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 48(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r10, %rdx
-/APP
- addq %r8,%r11
- adcq %rdi,%r9
- adcq %rsi,%rdx
- addq %r8,%r11
- adcq %rdi,%r9
- adcq %rsi,%rdx
-
-/NO_APP
- movq %rdx, %r13
- movq %r11, -456(%rbp)
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq (%rcx),%rax
- mulq 96(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %rax
- movq %rsi, %r11
-/APP
- addq %r8,%r9
- adcq %rax,%r12
- adcq %r11,%r13
- addq %r8,%r9
- adcq %rax,%r12
- adcq %r11,%r13
-
-/NO_APP
- movq %rax, %rbx
- movq %r11, %rsi
-/APP
- movq 48(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %rbx, %rdi
- movq %r9, -448(%rbp)
- movq %r13, %r9
-/APP
- movq (%rcx),%rax
- mulq 104(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 8(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 56(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%r12
- adcq %rdi,%r9
- adcq %rsi,%r13
- addq %r8,%r12
- adcq %rdi,%r9
- adcq %rsi,%r13
-
-/NO_APP
- movq %r12, -440(%rbp)
- movq %r10, %r12
-/APP
- movq (%rcx),%rax
- mulq 112(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r13, %rdx
- movq %rdi, %rbx
- movq %rsi, %r13
-/APP
- addq %r8,%r9
- adcq %rbx,%rdx
- adcq %r13,%r12
- addq %r8,%r9
- adcq %rbx,%rdx
- adcq %r13,%r12
-
-/NO_APP
- movq %r12, %rax
- movq %r13, %r11
- movq %rdx, %r12
- movq %rax, %r13
- movq %rbx, %rdi
- movq %r11, %rsi
-/APP
- movq 56(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r9, -432(%rbp)
- movq %r13, %r9
- movq %r10, %r13
-/APP
- movq (%rcx),%rax
- mulq 120(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 8(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 64(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %rax
- movq %rdi, %rdx
- movq %rsi, %rbx
-/APP
- addq %rax,%r12
- adcq %rdx,%r9
- adcq %rbx,%r13
- addq %rax,%r12
- adcq %rdx,%r9
- adcq %rbx,%r13
-
-/NO_APP
- movq %r12, -424(%rbp)
- movq %rdx, %r8
- movq %rax, %rsi
- movq %rbx, %rdi
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq (%rcx),%rax
- mulq 128(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %rsi, %rax
- movq %r8, %rbx
- movq %rdi, %rdx
-/APP
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r8
- movq %rbx, %rdi
-/APP
- movq 64(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r9, -416(%rbp)
- movq %r13, %r9
-/APP
- movq (%rcx),%rax
- mulq 136(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 8(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 64(%rcx),%rax
- mulq 72(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %rbx
- movq %rdi, %rax
- movq %rsi, %rdx
-/APP
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
-
-/NO_APP
- movq %r12, -408(%rbp)
- movq %rdx, %rdi
- movq %rax, %r8
- movq %rbx, %rsi
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq (%rcx),%rax
- mulq 144(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %rsi, %rax
- movq %r8, %rbx
- movq %rdi, %rdx
-/APP
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r8
- movq %rbx, %rdi
-/APP
- movq 72(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r9, -400(%rbp)
- movq %r13, %r9
-/APP
- movq (%rcx),%rax
- mulq 152(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 8(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 64(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 72(%rcx),%rax
- mulq 80(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %rbx
- movq %rdi, %rax
- movq %rsi, %rdx
-/APP
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
-
-/NO_APP
- movq %r12, -392(%rbp)
- movq %rdx, %rdi
- movq %rax, %r8
- movq %rbx, %rsi
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq (%rcx),%rax
- mulq 160(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %rsi, %rax
- movq %r8, %rbx
- movq %rdi, %rdx
-/APP
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r8
- movq %rbx, %rdi
-/APP
- movq 80(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r9, -384(%rbp)
- movq %r13, %r9
-/APP
- movq (%rcx),%rax
- mulq 168(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 8(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 64(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 72(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 80(%rcx),%rax
- mulq 88(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %rbx
- movq %rdi, %rax
- movq %rsi, %rdx
-/APP
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
-
-/NO_APP
- movq %r12, -376(%rbp)
- movq %rdx, %rdi
- movq %rax, %r8
- movq %rbx, %rsi
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq (%rcx),%rax
- mulq 176(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %rsi, %rax
- movq %r8, %rbx
- movq %rdi, %rdx
-/APP
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r8
- movq %rbx, %rdi
-/APP
- movq 88(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r9, -368(%rbp)
- movq %r13, %r9
-/APP
- movq (%rcx),%rax
- mulq 184(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 8(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 16(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 24(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 32(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 40(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 48(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 56(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 64(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 72(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 80(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 88(%rcx),%rax
- mulq 96(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %rbx
- movq %rdi, %rax
- movq %rsi, %rdx
-/APP
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
-
-/NO_APP
- movq %rdx, %rdi
- movq %r12, -360(%rbp)
- movq %rax, %r8
- movq %rbx, %rsi
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq (%rcx),%rax
- mulq 192(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %r8, %rbx
- movq %rdi, %rax
-/APP
- addq %rsi,%r9
- adcq %rbx,%r12
- adcq %rax,%r13
- addq %rsi,%r9
- adcq %rbx,%r12
- adcq %rax,%r13
-
-/NO_APP
- movq %rax, %r11
- movq %rbx, %r8
-/APP
- movq 96(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rdi
- movq %r9, -352(%rbp)
- movq %r13, %r9
-/APP
- movq (%rcx),%rax
- mulq 200(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 8(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 104(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r13
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r13
-
-/NO_APP
- movq %r12, -344(%rbp)
- movq %r10, %r12
-/APP
- movq (%rcx),%rax
- mulq 208(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %r13, %rdx
- movq %r8, %rbx
- movq %rdi, %r13
-/APP
- addq %rsi,%r9
- adcq %rbx,%rdx
- adcq %r13,%r12
- addq %rsi,%r9
- adcq %rbx,%rdx
- adcq %r13,%r12
-
-/NO_APP
- movq %r12, %rax
- movq %r13, %r11
- movq %rdx, %r12
- movq %rax, %r13
- movq %rbx, %r8
- movq %r11, %rdi
-/APP
- movq 104(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r9, -336(%rbp)
- movq %r13, %r9
- movq %r10, %r13
-/APP
- movq (%rcx),%rax
- mulq 216(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 112(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r13
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r13
-
-/NO_APP
- movq %r12, -328(%rbp)
-/APP
- movq (%rcx),%rax
- mulq 224(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %r13, %rax
- movq %r10, %rdx
- movq %r8, %rbx
- movq %rdi, %r12
-/APP
- addq %rsi,%r9
- adcq %rbx,%rax
- adcq %r12,%rdx
- addq %rsi,%r9
- adcq %rbx,%rax
- adcq %r12,%rdx
-
-/NO_APP
- movq %rdx, %rdi
- movq %r12, %r11
- movq %rbx, %r8
- movq %rax, %r12
- movq %rdi, %r13
- movq %r11, %rdi
-/APP
- movq 112(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r9, -320(%rbp)
- movq %r13, %rbx
- movq %r10, %r9
-/APP
- movq (%rcx),%rax
- mulq 232(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 120(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- addq %rsi,%r12
- adcq %r8,%rbx
- adcq %rdi,%r9
- addq %rsi,%r12
- adcq %r8,%rbx
- adcq %rdi,%r9
-
-/NO_APP
- movq %r12, -312(%rbp)
- movq %r9, %r13
-/APP
- movq (%rcx),%rax
- mulq 240(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %r10, %rax
- movq %r8, %r11
- movq %rdi, %rdx
-/APP
- addq %rsi,%rbx
- adcq %r11,%r13
- adcq %rdx,%rax
- addq %rsi,%rbx
- adcq %r11,%r13
- adcq %rdx,%rax
-
-/NO_APP
- movq %rdx, %r9
- movq %rax, %rdx
- movq %r13, %r12
- movq %r11, %r8
- movq %rdx, %r13
- movq %r9, %rdi
-/APP
- movq 120(%rcx),%rax
- mulq %rax
- addq %rax,%rbx
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %rbx, -304(%rbp)
- movq %r13, %rbx
- movq %r10, %r13
-/APP
- movq (%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 8(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 16(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 128(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- addq %rsi,%r12
- adcq %r8,%rbx
- adcq %rdi,%r13
- addq %rsi,%r12
- adcq %r8,%rbx
- adcq %rdi,%r13
-
-/NO_APP
- movq %r12, -296(%rbp)
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq 8(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 16(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 24(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %r8, %r11
- movq %rdi, %rax
-/APP
- addq %rsi,%rbx
- adcq %r11,%r12
- adcq %rax,%r13
- addq %rsi,%rbx
- adcq %r11,%r12
- adcq %rax,%r13
-
-/NO_APP
- movq %rax, %r9
- movq %r11, %r8
-/APP
- movq 128(%rcx),%rax
- mulq %rax
- addq %rax,%rbx
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r9, %rdi
- movq %rbx, -288(%rbp)
- movq %r13, %r9
-/APP
- movq 16(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 24(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 32(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 128(%rcx),%rax
- mulq 136(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r13
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r13
-
-/NO_APP
- movq %r12, -280(%rbp)
- movq %r10, %r12
-/APP
- movq 24(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 32(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 40(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 128(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %r13, %rdx
- movq %r8, %rbx
- movq %rdi, %r13
-/APP
- addq %rsi,%r9
- adcq %rbx,%rdx
- adcq %r13,%r12
- addq %rsi,%r9
- adcq %rbx,%rdx
- adcq %r13,%r12
-
-/NO_APP
- movq %r12, %rax
- movq %r13, %r11
- movq %rdx, %r12
- movq %rax, %r13
- movq %rbx, %r8
- movq %r11, %rdi
-/APP
- movq 136(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r9, -272(%rbp)
- movq %r13, %r9
- movq %r10, %r13
-/APP
- movq 32(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 40(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 48(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 128(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 136(%rcx),%rax
- mulq 144(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r13
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r13
-
-/NO_APP
- movq %r12, -264(%rbp)
-/APP
- movq 40(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 48(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 56(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 128(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 136(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %r13, %rax
- movq %r10, %rdx
- movq %r8, %rbx
- movq %rdi, %r12
-/APP
- addq %rsi,%r9
- adcq %rbx,%rax
- adcq %r12,%rdx
- addq %rsi,%r9
- adcq %rbx,%rax
- adcq %r12,%rdx
-
-/NO_APP
- movq %rdx, %rdi
- movq %r12, %r11
- movq %rbx, %r8
- movq %rax, %r12
- movq %rdi, %r13
- movq %r11, %rdi
-/APP
- movq 144(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r10, %r11
- movq %r9, -256(%rbp)
- movq %r13, %r9
-/APP
- movq 48(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 56(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 64(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 128(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 136(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 144(%rcx),%rax
- mulq 152(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r11
- addq %rsi,%r12
- adcq %r8,%r9
- adcq %rdi,%r11
-
-/NO_APP
- movq %r12, -248(%rbp)
- movq %r11, %r13
-/APP
- movq 56(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 64(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 72(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 80(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 128(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 136(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 144(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %r10, %rax
- movq %rsi, %rdx
- movq %r8, %rbx
- movq %rdi, %r12
-/APP
- addq %rdx,%r9
- adcq %rbx,%r13
- adcq %r12,%rax
- addq %rdx,%r9
- adcq %rbx,%r13
- adcq %r12,%rax
-
-/NO_APP
- movq %r12, %r11
- movq %rdx, %r8
- movq %rax, %rdx
- movq %r13, %r12
- movq %rbx, %rdi
- movq %rdx, %r13
- movq %r11, %rsi
-/APP
- movq 152(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r9, -240(%rbp)
- movq %r13, %r9
- movq %r10, %r13
-/APP
- movq 64(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 72(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 80(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 88(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 96(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 104(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 112(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 120(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 128(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 136(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 144(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 152(%rcx),%rax
- mulq 160(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %rax
- movq %rdi, %rdx
- movq %rsi, %rbx
-/APP
- addq %rax,%r12
- adcq %rdx,%r9
- adcq %rbx,%r13
- addq %rax,%r12
- adcq %rdx,%r9
- adcq %rbx,%r13
-
-/NO_APP
- movq %r12, -232(%rbp)
- movq %rdx, %r8
- movq %rax, %rsi
- movq %rbx, %rdi
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq 72(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 80(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 88(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 96(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 128(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 136(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 144(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 152(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %rsi, %rax
- movq %r8, %rbx
- movq %rdi, %rdx
-/APP
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r8
- movq %rbx, %rdi
-/APP
- movq 160(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r9, -224(%rbp)
- movq %r13, %r9
-/APP
- movq 80(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 88(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 96(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 104(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 112(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 120(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 128(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 136(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 144(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 152(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 160(%rcx),%rax
- mulq 168(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %rbx
- movq %rdi, %rax
- movq %rsi, %rdx
-/APP
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
-
-/NO_APP
- movq %r12, -216(%rbp)
- movq %rdx, %rdi
- movq %rax, %r8
- movq %rbx, %rsi
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq 88(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 96(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 104(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 112(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 128(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 136(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 144(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 152(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 160(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %rsi, %rax
- movq %r8, %rbx
- movq %rdi, %rdx
-/APP
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r8
- movq %rbx, %rdi
-/APP
- movq 168(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r9, -208(%rbp)
- movq %r13, %r9
-/APP
- movq 96(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 104(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 112(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 120(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 128(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 136(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 144(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 152(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 160(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 168(%rcx),%rax
- mulq 176(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %rbx
- movq %rdi, %rax
- movq %rsi, %rdx
-/APP
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
-
-/NO_APP
- movq %r12, -200(%rbp)
- movq %rdx, %rdi
- movq %rax, %r8
- movq %rbx, %rsi
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq 104(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 112(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 120(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 128(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 136(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 144(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 152(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 160(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 168(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %rsi, %rax
- movq %r8, %rbx
- movq %rdi, %rdx
-/APP
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r8
- movq %rbx, %rdi
-/APP
- movq 176(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r9, -192(%rbp)
- movq %r13, %r9
-/APP
- movq 112(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 120(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 128(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 136(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 144(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 152(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 160(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 168(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 176(%rcx),%rax
- mulq 184(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r8, %rbx
- movq %rdi, %rax
- movq %rsi, %rdx
-/APP
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
- addq %rbx,%r12
- adcq %rax,%r9
- adcq %rdx,%r13
-
-/NO_APP
- movq %r12, -184(%rbp)
- movq %rdx, %rdi
- movq %rax, %r8
- movq %rbx, %rsi
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq 120(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%rsi
- movq %rdx,%r8
- xorq %rdi,%rdi
-
- movq 128(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 136(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 144(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 152(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 160(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 168(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
- movq 176(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%rdi
-
-/NO_APP
- movq %rsi, %rax
- movq %r8, %rbx
- movq %rdi, %rdx
-/APP
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
- addq %rax,%r9
- adcq %rbx,%r12
- adcq %rdx,%r13
-
-/NO_APP
- movq %rdx, %r11
- movq %rax, %r8
- movq %rbx, %rdi
-/APP
- movq 184(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r9, -176(%rbp)
- movq %r13, %r9
-/APP
- movq 128(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
-/NO_APP
- movq %r10, %r13
-/APP
- movq 136(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 144(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 152(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 160(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 168(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 176(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 184(%rcx),%rax
- mulq 192(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%r12
- adcq %rdi,%r9
- adcq %rsi,%r13
- addq %r8,%r12
- adcq %rdi,%r9
- adcq %rsi,%r13
-
-/NO_APP
- movq %r12, -168(%rbp)
- movq %r13, %r12
- movq %r10, %r13
-/APP
- movq 136(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 144(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 152(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 160(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 168(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 176(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 184(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %rbx
- movq %rsi, %rax
-/APP
- addq %r8,%r9
- adcq %rbx,%r12
- adcq %rax,%r13
- addq %r8,%r9
- adcq %rbx,%r12
- adcq %rax,%r13
-
-/NO_APP
- movq %rax, %r11
- movq %rbx, %rdi
- movq %r10, %rbx
-/APP
- movq 192(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r11, %rsi
- movq %r9, -160(%rbp)
- movq %r13, %r9
-/APP
- movq 144(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 152(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 160(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 168(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 176(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 184(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 192(%rcx),%rax
- mulq 200(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%r12
- adcq %rdi,%r9
- adcq %rsi,%rbx
- addq %r8,%r12
- adcq %rdi,%r9
- adcq %rsi,%rbx
-
-/NO_APP
- movq %r12, -152(%rbp)
-/APP
- movq 152(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 160(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 168(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 176(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 184(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 192(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r10, %rdx
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r9
- adcq %r13,%rbx
- adcq %r12,%rdx
- addq %r8,%r9
- adcq %r13,%rbx
- adcq %r12,%rdx
-
-/NO_APP
- movq %rdx, %rax
- movq %r13, %rdi
- movq %r12, %rsi
- movq %rax, %r11
- movq %r10, %r12
-/APP
- movq 200(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r9, -144(%rbp)
- movq %r11, %r9
-/APP
- movq 160(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 168(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 176(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 184(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 192(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 200(%rcx),%rax
- mulq 208(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%r12
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%r12
-
-/NO_APP
- movq %rbx, -136(%rbp)
- movq %r12, %r11
-/APP
- movq 168(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 176(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 184(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 192(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 200(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r10, %rax
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rax
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rax
-
-/NO_APP
- movq %rax, %rdx
- movq %r11, %rbx
- movq %r13, %rdi
- movq %rdx, %r11
- movq %r12, %rsi
-/APP
- movq 208(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r9, -128(%rbp)
- movq %r11, %r9
-/APP
- movq 176(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 184(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 192(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 200(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 208(%rcx),%rax
- mulq 216(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r10, %rdx
-/APP
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%rdx
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%rdx
-
-/NO_APP
- movq %rbx, -120(%rbp)
- movq %rdx, %r11
- movq %r10, %rbx
-/APP
- movq 184(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 192(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 200(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 208(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rbx
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rbx
-
-/NO_APP
- movq %rbx, %rdx
- movq %r13, %rdi
- movq %r11, %rbx
- movq %r12, %rsi
- movq %rdx, %r11
- movq %r10, %r12
-/APP
- movq 216(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r9, -112(%rbp)
- movq %r11, %r9
-/APP
- movq 192(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 200(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 208(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 216(%rcx),%rax
- mulq 224(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%r12
- addq %r8,%rbx
- adcq %rdi,%r9
- adcq %rsi,%r12
-
-/NO_APP
- movq %rbx, -104(%rbp)
- movq %r12, %r11
-/APP
- movq 200(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 208(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 216(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %r10, %rax
- movq %rdi, %r13
- movq %rsi, %r12
-/APP
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rax
- addq %r8,%r9
- adcq %r13,%r11
- adcq %r12,%rax
-
-/NO_APP
- movq %rax, %rdx
- movq %r11, %rbx
- movq %r13, %rdi
- movq %rdx, %r11
- movq %r12, %rsi
- movq %r10, %r12
-/APP
- movq 224(%rcx),%rax
- mulq %rax
- addq %rax,%r9
- adcq %rdx,%rbx
- adcq $0,%r11
-
-/NO_APP
- movq %r9, -96(%rbp)
- movq %r10, %r9
-/APP
- movq 208(%rcx),%rax
- mulq 248(%rcx)
- movq %rax,%r8
- movq %rdx,%rdi
- xorq %rsi,%rsi
-
- movq 216(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
- movq 224(%rcx),%rax
- mulq 232(%rcx)
- addq %rax,%r8
- adcq %rdx,%rdi
- adcq $0,%rsi
-
-/NO_APP
- movq %rdi, %r13
- movq %rsi, %rax
-/APP
- addq %r8,%rbx
- adcq %r13,%r11
- adcq %rax,%r9
- addq %r8,%rbx
- adcq %r13,%r11
- adcq %rax,%r9
-
-/NO_APP
- movq %rbx, -88(%rbp)
- movq %r11, %rsi
- movq %r9, %r8
-/APP
- movq 216(%rcx),%rax
- mulq 248(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%r12
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%r12
-
-/NO_APP
- movq %r12, %r11
-/APP
- movq 224(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%r11
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%r11
-
-/NO_APP
- movq %r8, %r13
- movq %r11, %rbx
-/APP
- movq 232(%rcx),%rax
- mulq %rax
- addq %rax,%rsi
- adcq %rdx,%r13
- adcq $0,%rbx
-
-/NO_APP
- movq %rsi, -80(%rbp)
- movq %rbx, %r12
- movq %r13, %rdi
- movq %r10, %r13
-/APP
- movq 224(%rcx),%rax
- mulq 248(%rcx)
- addq %rax,%rdi
- adcq %rdx,%r12
- adcq $0,%r13
- addq %rax,%rdi
- adcq %rdx,%r12
- adcq $0,%r13
-
-/NO_APP
- movq %r12, %r9
- movq %r13, %r12
-/APP
- movq 232(%rcx),%rax
- mulq 240(%rcx)
- addq %rax,%rdi
- adcq %rdx,%r9
- adcq $0,%r12
- addq %rax,%rdi
- adcq %rdx,%r9
- adcq $0,%r12
-
-/NO_APP
- movq %rdi, -72(%rbp)
- movq %r9, %r11
- movq %r12, %rbx
- movq %r10, %r9
-/APP
- movq 232(%rcx),%rax
- mulq 248(%rcx)
- addq %rax,%r11
- adcq %rdx,%rbx
- adcq $0,%r9
- addq %rax,%r11
- adcq %rdx,%rbx
- adcq $0,%r9
-
-/NO_APP
- movq %rbx, %r13
- movq %r9, %rbx
- movq %r10, %r9
-/APP
- movq 240(%rcx),%rax
- mulq %rax
- addq %rax,%r11
- adcq %rdx,%r13
- adcq $0,%rbx
-
-/NO_APP
- movq %r11, -64(%rbp)
- movq %r13, %rdi
- movq %rbx, %rsi
-/APP
- movq 240(%rcx),%rax
- mulq 248(%rcx)
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%r9
- addq %rax,%rdi
- adcq %rdx,%rsi
- adcq $0,%r9
-
-/NO_APP
- movq %rdi, -56(%rbp)
- movq %r9, %r8
-/APP
- movq 248(%rcx),%rax
- mulq %rax
- addq %rax,%rsi
- adcq %rdx,%r8
- adcq $0,%r10
-
-/NO_APP
- movq %rsi, -48(%rbp)
- movq 16(%r14), %rdi
- leaq -544(%rbp), %rsi
- movl $512, %edx
- movq %r8, -40(%rbp)
- movl $64, 8(%r14)
- movl $0, (%r14)
- call memcpy@PLT
- movl 8(%r14), %edx
- testl %edx, %edx
- je .L304
- leal -1(%rdx), %ecx
- movq 16(%r14), %rsi
- mov %ecx, %r10d
- cmpq $0, (%rsi,%r10,8)
- jne .L302
- movl %ecx, %edx
- .align 16
-.L303:
- testl %edx, %edx
- movl %edx, %ecx
- je .L307
- decl %edx
- mov %edx, %eax
- cmpq $0, (%rsi,%rax,8)
- je .L303
- movl %ecx, 8(%r14)
- movl %ecx, %edx
-.L302:
- testl %edx, %edx
- je .L304
- movl (%r14), %eax
- movl %eax, (%r14)
- addq $512, %rsp
- popq %rbx
- popq %r12
- popq %r13
- popq %r14
- leave
- ret
-.L307:
- movl %edx, 8(%r14)
- .align 16
-.L304:
- xorl %eax, %eax
- movl %eax, (%r14)
- addq $512, %rsp
- popq %rbx
- popq %r12
- popq %r13
- popq %r14
- leave
- ret
-.LFE9:
- .size s_mp_sqr_comba_32, .-s_mp_sqr_comba_32
diff --git a/security/nss/lib/freebl/mpi/mp_gf2m-priv.h b/security/nss/lib/freebl/mpi/mp_gf2m-priv.h
deleted file mode 100644
index b9c2f3bb1..000000000
--- a/security/nss/lib/freebl/mpi/mp_gf2m-priv.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _MP_GF2M_PRIV_H_
-#define _MP_GF2M_PRIV_H_
-
-#include "mpi-priv.h"
-
-extern const mp_digit mp_gf2m_sqr_tb[16];
-
-#if defined(MP_USE_UINT_DIGIT)
-#define MP_DIGIT_BITS 32
-/* enable fast divide and mod operations on MP_DIGIT_BITS */
-#define MP_DIGIT_BITS_LOG_2 5
-#define MP_DIGIT_BITS_MASK 0x1f
-#else
-#define MP_DIGIT_BITS 64
-/* enable fast divide and mod operations on MP_DIGIT_BITS */
-#define MP_DIGIT_BITS_LOG_2 6
-#define MP_DIGIT_BITS_MASK 0x3f
-#endif
-
-/* Platform-specific macros for fast binary polynomial squaring. */
-#if MP_DIGIT_BITS == 32
-#define gf2m_SQR1(w) \
- mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 16 | \
- mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF]
-#define gf2m_SQR0(w) \
- mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \
- mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) & 0xF]
-#else
-#define gf2m_SQR1(w) \
- mp_gf2m_sqr_tb[(w) >> 60 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 56 & 0xF] << 48 | \
- mp_gf2m_sqr_tb[(w) >> 52 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 48 & 0xF] << 32 | \
- mp_gf2m_sqr_tb[(w) >> 44 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 40 & 0xF] << 16 | \
- mp_gf2m_sqr_tb[(w) >> 36 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) >> 32 & 0xF]
-#define gf2m_SQR0(w) \
- mp_gf2m_sqr_tb[(w) >> 28 & 0xF] << 56 | mp_gf2m_sqr_tb[(w) >> 24 & 0xF] << 48 | \
- mp_gf2m_sqr_tb[(w) >> 20 & 0xF] << 40 | mp_gf2m_sqr_tb[(w) >> 16 & 0xF] << 32 | \
- mp_gf2m_sqr_tb[(w) >> 12 & 0xF] << 24 | mp_gf2m_sqr_tb[(w) >> 8 & 0xF] << 16 | \
- mp_gf2m_sqr_tb[(w) >> 4 & 0xF] << 8 | mp_gf2m_sqr_tb[(w) & 0xF]
-#endif
-
-/* Multiply two binary polynomials mp_digits a, b.
- * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
- * Output in two mp_digits rh, rl.
- */
-void s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b);
-
-/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0)
- * result is a binary polynomial in 4 mp_digits r[4].
- * The caller MUST ensure that r has the right amount of space allocated.
- */
-void s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
- const mp_digit b0);
-
-/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, b0)
- * result is a binary polynomial in 6 mp_digits r[6].
- * The caller MUST ensure that r has the right amount of space allocated.
- */
-void s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
- const mp_digit b2, const mp_digit b1, const mp_digit b0);
-
-/* Compute xor-multiply of two binary polynomials (a3, a2, a1, a0) x (b3, b2, b1, b0)
- * result is a binary polynomial in 8 mp_digits r[8].
- * The caller MUST ensure that r has the right amount of space allocated.
- */
-void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
- const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
- const mp_digit b0);
-
-#endif /* _MP_GF2M_PRIV_H_ */
diff --git a/security/nss/lib/freebl/mpi/mp_gf2m.c b/security/nss/lib/freebl/mpi/mp_gf2m.c
deleted file mode 100644
index e84f3a044..000000000
--- a/security/nss/lib/freebl/mpi/mp_gf2m.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mp_gf2m.h"
-#include "mp_gf2m-priv.h"
-#include "mplogic.h"
-#include "mpi-priv.h"
-
-const mp_digit mp_gf2m_sqr_tb[16] =
-{
- 0, 1, 4, 5, 16, 17, 20, 21,
- 64, 65, 68, 69, 80, 81, 84, 85
-};
-
-/* Multiply two binary polynomials mp_digits a, b.
- * Result is a polynomial with degree < 2 * MP_DIGIT_BITS - 1.
- * Output in two mp_digits rh, rl.
- */
-#if MP_DIGIT_BITS == 32
-void
-s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
-{
- register mp_digit h, l, s;
- mp_digit tab[8], top2b = a >> 30;
- register mp_digit a1, a2, a4;
-
- a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1;
-
- tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2;
- tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4;
-
- s = tab[b & 0x7]; l = s;
- s = tab[b >> 3 & 0x7]; l ^= s << 3; h = s >> 29;
- s = tab[b >> 6 & 0x7]; l ^= s << 6; h ^= s >> 26;
- s = tab[b >> 9 & 0x7]; l ^= s << 9; h ^= s >> 23;
- s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20;
- s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17;
- s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14;
- s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11;
- s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >> 8;
- s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >> 5;
- s = tab[b >> 30 ]; l ^= s << 30; h ^= s >> 2;
-
- /* compensate for the top two bits of a */
-
- if (top2b & 01) { l ^= b << 30; h ^= b >> 2; }
- if (top2b & 02) { l ^= b << 31; h ^= b >> 1; }
-
- *rh = h; *rl = l;
-}
-#else
-void
-s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b)
-{
- register mp_digit h, l, s;
- mp_digit tab[16], top3b = a >> 61;
- register mp_digit a1, a2, a4, a8;
-
- a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1;
- a4 = a2 << 1; a8 = a4 << 1;
- tab[ 0] = 0; tab[ 1] = a1; tab[ 2] = a2; tab[ 3] = a1^a2;
- tab[ 4] = a4; tab[ 5] = a1^a4; tab[ 6] = a2^a4; tab[ 7] = a1^a2^a4;
- tab[ 8] = a8; tab[ 9] = a1^a8; tab[10] = a2^a8; tab[11] = a1^a2^a8;
- tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8;
-
- s = tab[b & 0xF]; l = s;
- s = tab[b >> 4 & 0xF]; l ^= s << 4; h = s >> 60;
- s = tab[b >> 8 & 0xF]; l ^= s << 8; h ^= s >> 56;
- s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52;
- s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48;
- s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44;
- s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40;
- s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36;
- s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32;
- s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28;
- s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24;
- s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20;
- s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16;
- s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12;
- s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >> 8;
- s = tab[b >> 60 ]; l ^= s << 60; h ^= s >> 4;
-
- /* compensate for the top three bits of a */
-
- if (top3b & 01) { l ^= b << 61; h ^= b >> 3; }
- if (top3b & 02) { l ^= b << 62; h ^= b >> 2; }
- if (top3b & 04) { l ^= b << 63; h ^= b >> 1; }
-
- *rh = h; *rl = l;
-}
-#endif
-
-/* Compute xor-multiply of two binary polynomials (a1, a0) x (b1, b0)
- * result is a binary polynomial in 4 mp_digits r[4].
- * The caller MUST ensure that r has the right amount of space allocated.
- */
-void
-s_bmul_2x2(mp_digit *r, const mp_digit a1, const mp_digit a0, const mp_digit b1,
- const mp_digit b0)
-{
- mp_digit m1, m0;
- /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
- s_bmul_1x1(r+3, r+2, a1, b1);
- s_bmul_1x1(r+1, r, a0, b0);
- s_bmul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
- /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
- r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */
- r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */
-}
-
-/* Compute xor-multiply of two binary polynomials (a2, a1, a0) x (b2, b1, b0)
- * result is a binary polynomial in 6 mp_digits r[6].
- * The caller MUST ensure that r has the right amount of space allocated.
- */
-void
-s_bmul_3x3(mp_digit *r, const mp_digit a2, const mp_digit a1, const mp_digit a0,
- const mp_digit b2, const mp_digit b1, const mp_digit b0)
-{
- mp_digit zm[4];
-
- s_bmul_1x1(r+5, r+4, a2, b2); /* fill top 2 words */
- s_bmul_2x2(zm, a1, a2^a0, b1, b2^b0); /* fill middle 4 words */
- s_bmul_2x2(r, a1, a0, b1, b0); /* fill bottom 4 words */
-
- zm[3] ^= r[3];
- zm[2] ^= r[2];
- zm[1] ^= r[1] ^ r[5];
- zm[0] ^= r[0] ^ r[4];
-
- r[5] ^= zm[3];
- r[4] ^= zm[2];
- r[3] ^= zm[1];
- r[2] ^= zm[0];
-}
-
-/* Compute xor-multiply of two binary polynomials (a3, a2, a1, a0) x (b3, b2, b1, b0)
- * result is a binary polynomial in 8 mp_digits r[8].
- * The caller MUST ensure that r has the right amount of space allocated.
- */
-void s_bmul_4x4(mp_digit *r, const mp_digit a3, const mp_digit a2, const mp_digit a1,
- const mp_digit a0, const mp_digit b3, const mp_digit b2, const mp_digit b1,
- const mp_digit b0)
-{
- mp_digit zm[4];
-
- s_bmul_2x2(r+4, a3, a2, b3, b2); /* fill top 4 words */
- s_bmul_2x2(zm, a3^a1, a2^a0, b3^b1, b2^b0); /* fill middle 4 words */
- s_bmul_2x2(r, a1, a0, b1, b0); /* fill bottom 4 words */
-
- zm[3] ^= r[3] ^ r[7];
- zm[2] ^= r[2] ^ r[6];
- zm[1] ^= r[1] ^ r[5];
- zm[0] ^= r[0] ^ r[4];
-
- r[5] ^= zm[3];
- r[4] ^= zm[2];
- r[3] ^= zm[1];
- r[2] ^= zm[0];
-}
-
-/* Compute addition of two binary polynomials a and b,
- * store result in c; c could be a or b, a and b could be equal;
- * c is the bitwise XOR of a and b.
- */
-mp_err
-mp_badd(const mp_int *a, const mp_int *b, mp_int *c)
-{
- mp_digit *pa, *pb, *pc;
- mp_size ix;
- mp_size used_pa, used_pb;
- mp_err res = MP_OKAY;
-
- /* Add all digits up to the precision of b. If b had more
- * precision than a initially, swap a, b first
- */
- if (MP_USED(a) >= MP_USED(b)) {
- pa = MP_DIGITS(a);
- pb = MP_DIGITS(b);
- used_pa = MP_USED(a);
- used_pb = MP_USED(b);
- } else {
- pa = MP_DIGITS(b);
- pb = MP_DIGITS(a);
- used_pa = MP_USED(b);
- used_pb = MP_USED(a);
- }
-
- /* Make sure c has enough precision for the output value */
- MP_CHECKOK( s_mp_pad(c, used_pa) );
-
- /* Do word-by-word xor */
- pc = MP_DIGITS(c);
- for (ix = 0; ix < used_pb; ix++) {
- (*pc++) = (*pa++) ^ (*pb++);
- }
-
- /* Finish the rest of digits until we're actually done */
- for (; ix < used_pa; ++ix) {
- *pc++ = *pa++;
- }
-
- MP_USED(c) = used_pa;
- MP_SIGN(c) = ZPOS;
- s_mp_clamp(c);
-
-CLEANUP:
- return res;
-}
-
-#define s_mp_div2(a) MP_CHECKOK( mpl_rsh((a), (a), 1) );
-
-/* Compute binary polynomial multiply d = a * b */
-static void
-s_bmul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
-{
- mp_digit a_i, a0b0, a1b1, carry = 0;
- while (a_len--) {
- a_i = *a++;
- s_bmul_1x1(&a1b1, &a0b0, a_i, b);
- *d++ = a0b0 ^ carry;
- carry = a1b1;
- }
- *d = carry;
-}
-
-/* Compute binary polynomial xor multiply accumulate d ^= a * b */
-static void
-s_bmul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *d)
-{
- mp_digit a_i, a0b0, a1b1, carry = 0;
- while (a_len--) {
- a_i = *a++;
- s_bmul_1x1(&a1b1, &a0b0, a_i, b);
- *d++ ^= a0b0 ^ carry;
- carry = a1b1;
- }
- *d ^= carry;
-}
-
-/* Compute binary polynomial xor multiply c = a * b.
- * All parameters may be identical.
- */
-mp_err
-mp_bmul(const mp_int *a, const mp_int *b, mp_int *c)
-{
- mp_digit *pb, b_i;
- mp_int tmp;
- mp_size ib, a_used, b_used;
- mp_err res = MP_OKAY;
-
- MP_DIGITS(&tmp) = 0;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if (a == c) {
- MP_CHECKOK( mp_init_copy(&tmp, a) );
- if (a == b)
- b = &tmp;
- a = &tmp;
- } else if (b == c) {
- MP_CHECKOK( mp_init_copy(&tmp, b) );
- b = &tmp;
- }
-
- if (MP_USED(a) < MP_USED(b)) {
- const mp_int *xch = b; /* switch a and b if b longer */
- b = a;
- a = xch;
- }
-
- MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
- MP_CHECKOK( s_mp_pad(c, USED(a) + USED(b)) );
-
- pb = MP_DIGITS(b);
- s_bmul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
-
- /* Outer loop: Digits of b */
- a_used = MP_USED(a);
- b_used = MP_USED(b);
- MP_USED(c) = a_used + b_used;
- for (ib = 1; ib < b_used; ib++) {
- b_i = *pb++;
-
- /* Inner product: Digits of a */
- if (b_i)
- s_bmul_d_add(MP_DIGITS(a), a_used, b_i, MP_DIGITS(c) + ib);
- else
- MP_DIGIT(c, ib + a_used) = b_i;
- }
-
- s_mp_clamp(c);
-
- SIGN(c) = ZPOS;
-
-CLEANUP:
- mp_clear(&tmp);
- return res;
-}
-
-
-/* Compute modular reduction of a and store result in r.
- * r could be a.
- * For modular arithmetic, the irreducible polynomial f(t) is represented
- * as an array of int[], where f(t) is of the form:
- * f(t) = t^p[0] + t^p[1] + ... + t^p[k]
- * where m = p[0] > p[1] > ... > p[k] = 0.
- */
-mp_err
-mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r)
-{
- int j, k;
- int n, dN, d0, d1;
- mp_digit zz, *z, tmp;
- mp_size used;
- mp_err res = MP_OKAY;
-
- /* The algorithm does the reduction in place in r,
- * if a != r, copy a into r first so reduction can be done in r
- */
- if (a != r) {
- MP_CHECKOK( mp_copy(a, r) );
- }
- z = MP_DIGITS(r);
-
- /* start reduction */
- /*dN = p[0] / MP_DIGIT_BITS; */
- dN = p[0] >> MP_DIGIT_BITS_LOG_2;
- used = MP_USED(r);
-
- for (j = used - 1; j > dN;) {
-
- zz = z[j];
- if (zz == 0) {
- j--; continue;
- }
- z[j] = 0;
-
- for (k = 1; p[k] > 0; k++) {
- /* reducing component t^p[k] */
- n = p[0] - p[k];
- /*d0 = n % MP_DIGIT_BITS; */
- d0 = n & MP_DIGIT_BITS_MASK;
- d1 = MP_DIGIT_BITS - d0;
- /*n /= MP_DIGIT_BITS; */
- n >>= MP_DIGIT_BITS_LOG_2;
- z[j-n] ^= (zz>>d0);
- if (d0)
- z[j-n-1] ^= (zz<<d1);
- }
-
- /* reducing component t^0 */
- n = dN;
- /*d0 = p[0] % MP_DIGIT_BITS;*/
- d0 = p[0] & MP_DIGIT_BITS_MASK;
- d1 = MP_DIGIT_BITS - d0;
- z[j-n] ^= (zz >> d0);
- if (d0)
- z[j-n-1] ^= (zz << d1);
-
- }
-
- /* final round of reduction */
- while (j == dN) {
-
- /* d0 = p[0] % MP_DIGIT_BITS; */
- d0 = p[0] & MP_DIGIT_BITS_MASK;
- zz = z[dN] >> d0;
- if (zz == 0) break;
- d1 = MP_DIGIT_BITS - d0;
-
- /* clear up the top d1 bits */
- if (d0) {
- z[dN] = (z[dN] << d1) >> d1;
- } else {
- z[dN] = 0;
- }
- *z ^= zz; /* reduction t^0 component */
-
- for (k = 1; p[k] > 0; k++) {
- /* reducing component t^p[k]*/
- /* n = p[k] / MP_DIGIT_BITS; */
- n = p[k] >> MP_DIGIT_BITS_LOG_2;
- /* d0 = p[k] % MP_DIGIT_BITS; */
- d0 = p[k] & MP_DIGIT_BITS_MASK;
- d1 = MP_DIGIT_BITS - d0;
- z[n] ^= (zz << d0);
- tmp = zz >> d1;
- if (d0 && tmp)
- z[n+1] ^= tmp;
- }
- }
-
- s_mp_clamp(r);
-CLEANUP:
- return res;
-}
-
-/* Compute the product of two polynomials a and b, reduce modulo p,
- * Store the result in r. r could be a or b; a could be b.
- */
-mp_err
-mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[], mp_int *r)
-{
- mp_err res;
-
- if (a == b) return mp_bsqrmod(a, p, r);
- if ((res = mp_bmul(a, b, r) ) != MP_OKAY)
- return res;
- return mp_bmod(r, p, r);
-}
-
-/* Compute binary polynomial squaring c = a*a mod p .
- * Parameter r and a can be identical.
- */
-
-mp_err
-mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r)
-{
- mp_digit *pa, *pr, a_i;
- mp_int tmp;
- mp_size ia, a_used;
- mp_err res;
-
- ARGCHK(a != NULL && r != NULL, MP_BADARG);
- MP_DIGITS(&tmp) = 0;
-
- if (a == r) {
- MP_CHECKOK( mp_init_copy(&tmp, a) );
- a = &tmp;
- }
-
- MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
- MP_CHECKOK( s_mp_pad(r, 2*USED(a)) );
-
- pa = MP_DIGITS(a);
- pr = MP_DIGITS(r);
- a_used = MP_USED(a);
- MP_USED(r) = 2 * a_used;
-
- for (ia = 0; ia < a_used; ia++) {
- a_i = *pa++;
- *pr++ = gf2m_SQR0(a_i);
- *pr++ = gf2m_SQR1(a_i);
- }
-
- MP_CHECKOK( mp_bmod(r, p, r) );
- s_mp_clamp(r);
- SIGN(r) = ZPOS;
-
-CLEANUP:
- mp_clear(&tmp);
- return res;
-}
-
-/* Compute binary polynomial y/x mod p, y divided by x, reduce modulo p.
- * Store the result in r. r could be x or y, and x could equal y.
- * Uses algorithm Modular_Division_GF(2^m) from
- * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to
- * the Great Divide".
- */
-int
-mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
- const unsigned int p[], mp_int *r)
-{
- mp_int aa, bb, uu;
- mp_int *a, *b, *u, *v;
- mp_err res = MP_OKAY;
-
- MP_DIGITS(&aa) = 0;
- MP_DIGITS(&bb) = 0;
- MP_DIGITS(&uu) = 0;
-
- MP_CHECKOK( mp_init_copy(&aa, x) );
- MP_CHECKOK( mp_init_copy(&uu, y) );
- MP_CHECKOK( mp_init_copy(&bb, pp) );
- MP_CHECKOK( s_mp_pad(r, USED(pp)) );
- MP_USED(r) = 1; MP_DIGIT(r, 0) = 0;
-
- a = &aa; b= &bb; u=&uu; v=r;
- /* reduce x and y mod p */
- MP_CHECKOK( mp_bmod(a, p, a) );
- MP_CHECKOK( mp_bmod(u, p, u) );
-
- while (!mp_isodd(a)) {
- s_mp_div2(a);
- if (mp_isodd(u)) {
- MP_CHECKOK( mp_badd(u, pp, u) );
- }
- s_mp_div2(u);
- }
-
- do {
- if (mp_cmp_mag(b, a) > 0) {
- MP_CHECKOK( mp_badd(b, a, b) );
- MP_CHECKOK( mp_badd(v, u, v) );
- do {
- s_mp_div2(b);
- if (mp_isodd(v)) {
- MP_CHECKOK( mp_badd(v, pp, v) );
- }
- s_mp_div2(v);
- } while (!mp_isodd(b));
- }
- else if ((MP_DIGIT(a,0) == 1) && (MP_USED(a) == 1))
- break;
- else {
- MP_CHECKOK( mp_badd(a, b, a) );
- MP_CHECKOK( mp_badd(u, v, u) );
- do {
- s_mp_div2(a);
- if (mp_isodd(u)) {
- MP_CHECKOK( mp_badd(u, pp, u) );
- }
- s_mp_div2(u);
- } while (!mp_isodd(a));
- }
- } while (1);
-
- MP_CHECKOK( mp_copy(u, r) );
-
-CLEANUP:
- mp_clear(&aa);
- mp_clear(&bb);
- mp_clear(&uu);
- return res;
-
-}
-
-/* Convert the bit-string representation of a polynomial a into an array
- * of integers corresponding to the bits with non-zero coefficient.
- * Up to max elements of the array will be filled. Return value is total
- * number of coefficients that would be extracted if array was large enough.
- */
-int
-mp_bpoly2arr(const mp_int *a, unsigned int p[], int max)
-{
- int i, j, k;
- mp_digit top_bit, mask;
-
- top_bit = 1;
- top_bit <<= MP_DIGIT_BIT - 1;
-
- for (k = 0; k < max; k++) p[k] = 0;
- k = 0;
-
- for (i = MP_USED(a) - 1; i >= 0; i--) {
- mask = top_bit;
- for (j = MP_DIGIT_BIT - 1; j >= 0; j--) {
- if (MP_DIGITS(a)[i] & mask) {
- if (k < max) p[k] = MP_DIGIT_BIT * i + j;
- k++;
- }
- mask >>= 1;
- }
- }
-
- return k;
-}
-
-/* Convert the coefficient array representation of a polynomial to a
- * bit-string. The array must be terminated by 0.
- */
-mp_err
-mp_barr2poly(const unsigned int p[], mp_int *a)
-{
-
- mp_err res = MP_OKAY;
- int i;
-
- mp_zero(a);
- for (i = 0; p[i] > 0; i++) {
- MP_CHECKOK( mpl_set_bit(a, p[i], 1) );
- }
- MP_CHECKOK( mpl_set_bit(a, 0, 1) );
-
-CLEANUP:
- return res;
-}
diff --git a/security/nss/lib/freebl/mpi/mp_gf2m.h b/security/nss/lib/freebl/mpi/mp_gf2m.h
deleted file mode 100644
index 9faa026c3..000000000
--- a/security/nss/lib/freebl/mpi/mp_gf2m.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _MP_GF2M_H_
-#define _MP_GF2M_H_
-
-#include "mpi.h"
-
-mp_err mp_badd(const mp_int *a, const mp_int *b, mp_int *c);
-mp_err mp_bmul(const mp_int *a, const mp_int *b, mp_int *c);
-
-/* For modular arithmetic, the irreducible polynomial f(t) is represented
- * as an array of int[], where f(t) is of the form:
- * f(t) = t^p[0] + t^p[1] + ... + t^p[k]
- * where m = p[0] > p[1] > ... > p[k] = 0.
- */
-mp_err mp_bmod(const mp_int *a, const unsigned int p[], mp_int *r);
-mp_err mp_bmulmod(const mp_int *a, const mp_int *b, const unsigned int p[],
- mp_int *r);
-mp_err mp_bsqrmod(const mp_int *a, const unsigned int p[], mp_int *r);
-mp_err mp_bdivmod(const mp_int *y, const mp_int *x, const mp_int *pp,
- const unsigned int p[], mp_int *r);
-
-int mp_bpoly2arr(const mp_int *a, unsigned int p[], int max);
-mp_err mp_barr2poly(const unsigned int p[], mp_int *a);
-
-#endif /* _MP_GF2M_H_ */
diff --git a/security/nss/lib/freebl/mpi/mpcpucache.c b/security/nss/lib/freebl/mpi/mpcpucache.c
deleted file mode 100644
index 9a4a9d30c..000000000
--- a/security/nss/lib/freebl/mpi/mpcpucache.c
+++ /dev/null
@@ -1,813 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi.h"
-
-/*
- * This file implements a single function: s_mpi_getProcessorLineSize();
- * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line
- * if a cache exists, or zero if there is no cache. If more than one
- * cache line exists, it should return the smallest line size (which is
- * usually the L1 cache).
- *
- * mp_modexp uses this information to make sure that private key information
- * isn't being leaked through the cache.
- *
- * Currently the file returns good data for most modern x86 processors, and
- * reasonable data on 64-bit ppc processors. All other processors are assumed
- * to have a cache line size of 32 bytes unless modified by target.mk.
- *
- */
-
-#if defined(i386) || defined(__i386) || defined(__X86__) || defined (_M_IX86) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64)
-/* X86 processors have special instructions that tell us about the cache */
-#include "string.h"
-
-#if defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64)
-#define AMD_64 1
-#endif
-
-/* Generic CPUID function */
-#if defined(AMD_64)
-
-#if defined(__GNUC__)
-
-void freebl_cpuid(unsigned long op, unsigned long *eax,
- unsigned long *ebx, unsigned long *ecx,
- unsigned long *edx)
-{
- __asm__("cpuid\n\t"
- : "=a" (*eax),
- "=b" (*ebx),
- "=c" (*ecx),
- "=d" (*edx)
- : "0" (op));
-}
-
-#elif defined(_MSC_VER)
-
-#include <intrin.h>
-
-void freebl_cpuid(unsigned long op, unsigned long *eax,
- unsigned long *ebx, unsigned long *ecx,
- unsigned long *edx)
-{
- int intrinsic_out[4];
-
- __cpuid(intrinsic_out, op);
- *eax = intrinsic_out[0];
- *ebx = intrinsic_out[1];
- *ecx = intrinsic_out[2];
- *edx = intrinsic_out[3];
-}
-
-#endif
-
-#else /* !defined(AMD_64) */
-
-/* x86 */
-
-#if defined(__GNUC__)
-void freebl_cpuid(unsigned long op, unsigned long *eax,
- unsigned long *ebx, unsigned long *ecx,
- unsigned long *edx)
-{
-/* sigh GCC isn't smart enough to save the ebx PIC register on it's own
- * in this case, so do it by hand. Use edi to store ebx and pass the
- * value returned in ebx from cpuid through edi. */
- __asm__("mov %%ebx,%%edi\n\t"
- "cpuid\n\t"
- "xchgl %%ebx,%%edi\n\t"
- : "=a" (*eax),
- "=D" (*ebx),
- "=c" (*ecx),
- "=d" (*edx)
- : "0" (op));
-}
-
-/*
- * try flipping a processor flag to determine CPU type
- */
-static unsigned long changeFlag(unsigned long flag)
-{
- unsigned long changedFlags, originalFlags;
- __asm__("pushfl\n\t" /* get the flags */
- "popl %0\n\t"
- "movl %0,%1\n\t" /* save the original flags */
- "xorl %2,%0\n\t" /* flip the bit */
- "pushl %0\n\t" /* set the flags */
- "popfl\n\t"
- "pushfl\n\t" /* get the flags again (for return) */
- "popl %0\n\t"
- "pushl %1\n\t" /* restore the original flags */
- "popfl\n\t"
- : "=r" (changedFlags),
- "=r" (originalFlags),
- "=r" (flag)
- : "2" (flag));
- return changedFlags ^ originalFlags;
-}
-
-#elif defined(_MSC_VER)
-
-/*
- * windows versions of the above assembler
- */
-#define wcpuid __asm __emit 0fh __asm __emit 0a2h
-void freebl_cpuid(unsigned long op, unsigned long *Reax,
- unsigned long *Rebx, unsigned long *Recx, unsigned long *Redx)
-{
- unsigned long Leax, Lebx, Lecx, Ledx;
- __asm {
- pushad
- mov eax,op
- wcpuid
- mov Leax,eax
- mov Lebx,ebx
- mov Lecx,ecx
- mov Ledx,edx
- popad
- }
- *Reax = Leax;
- *Rebx = Lebx;
- *Recx = Lecx;
- *Redx = Ledx;
-}
-
-static unsigned long changeFlag(unsigned long flag)
-{
- unsigned long changedFlags, originalFlags;
- __asm {
- push eax
- push ebx
- pushfd /* get the flags */
- pop eax
- push eax /* save the flags on the stack */
- mov originalFlags,eax /* save the original flags */
- mov ebx,flag
- xor eax,ebx /* flip the bit */
- push eax /* set the flags */
- popfd
- pushfd /* get the flags again (for return) */
- pop eax
- popfd /* restore the original flags */
- mov changedFlags,eax
- pop ebx
- pop eax
- }
- return changedFlags ^ originalFlags;
-}
-#endif
-
-#endif
-
-#if !defined(AMD_64)
-#define AC_FLAG 0x40000
-#define ID_FLAG 0x200000
-
-/* 386 processors can't flip the AC_FLAG, intel AP Note AP-485 */
-static int is386()
-{
- return changeFlag(AC_FLAG) == 0;
-}
-
-/* 486 processors can't flip the ID_FLAG, intel AP Note AP-485 */
-static int is486()
-{
- return changeFlag(ID_FLAG) == 0;
-}
-#endif
-
-
-/*
- * table for Intel Cache.
- * See Intel Application Note AP-485 for more information
- */
-
-typedef unsigned char CacheTypeEntry;
-
-typedef enum {
- Cache_NONE = 0,
- Cache_UNKNOWN = 1,
- Cache_TLB = 2,
- Cache_TLBi = 3,
- Cache_TLBd = 4,
- Cache_Trace = 5,
- Cache_L1 = 6,
- Cache_L1i = 7,
- Cache_L1d = 8,
- Cache_L2 = 9 ,
- Cache_L2i = 10 ,
- Cache_L2d = 11 ,
- Cache_L3 = 12 ,
- Cache_L3i = 13,
- Cache_L3d = 14
-} CacheType;
-
-struct _cache {
- CacheTypeEntry type;
- unsigned char lineSize;
-};
-static const struct _cache CacheMap[256] = {
-/* 00 */ {Cache_NONE, 0 },
-/* 01 */ {Cache_TLBi, 0 },
-/* 02 */ {Cache_TLBi, 0 },
-/* 03 */ {Cache_TLBd, 0 },
-/* 04 */ {Cache_TLBd, },
-/* 05 */ {Cache_UNKNOWN, 0 },
-/* 06 */ {Cache_L1i, 32 },
-/* 07 */ {Cache_UNKNOWN, 0 },
-/* 08 */ {Cache_L1i, 32 },
-/* 09 */ {Cache_UNKNOWN, 0 },
-/* 0a */ {Cache_L1d, 32 },
-/* 0b */ {Cache_UNKNOWN, 0 },
-/* 0c */ {Cache_L1d, 32 },
-/* 0d */ {Cache_UNKNOWN, 0 },
-/* 0e */ {Cache_UNKNOWN, 0 },
-/* 0f */ {Cache_UNKNOWN, 0 },
-/* 10 */ {Cache_UNKNOWN, 0 },
-/* 11 */ {Cache_UNKNOWN, 0 },
-/* 12 */ {Cache_UNKNOWN, 0 },
-/* 13 */ {Cache_UNKNOWN, 0 },
-/* 14 */ {Cache_UNKNOWN, 0 },
-/* 15 */ {Cache_UNKNOWN, 0 },
-/* 16 */ {Cache_UNKNOWN, 0 },
-/* 17 */ {Cache_UNKNOWN, 0 },
-/* 18 */ {Cache_UNKNOWN, 0 },
-/* 19 */ {Cache_UNKNOWN, 0 },
-/* 1a */ {Cache_UNKNOWN, 0 },
-/* 1b */ {Cache_UNKNOWN, 0 },
-/* 1c */ {Cache_UNKNOWN, 0 },
-/* 1d */ {Cache_UNKNOWN, 0 },
-/* 1e */ {Cache_UNKNOWN, 0 },
-/* 1f */ {Cache_UNKNOWN, 0 },
-/* 20 */ {Cache_UNKNOWN, 0 },
-/* 21 */ {Cache_UNKNOWN, 0 },
-/* 22 */ {Cache_L3, 64 },
-/* 23 */ {Cache_L3, 64 },
-/* 24 */ {Cache_UNKNOWN, 0 },
-/* 25 */ {Cache_L3, 64 },
-/* 26 */ {Cache_UNKNOWN, 0 },
-/* 27 */ {Cache_UNKNOWN, 0 },
-/* 28 */ {Cache_UNKNOWN, 0 },
-/* 29 */ {Cache_L3, 64 },
-/* 2a */ {Cache_UNKNOWN, 0 },
-/* 2b */ {Cache_UNKNOWN, 0 },
-/* 2c */ {Cache_L1d, 64 },
-/* 2d */ {Cache_UNKNOWN, 0 },
-/* 2e */ {Cache_UNKNOWN, 0 },
-/* 2f */ {Cache_UNKNOWN, 0 },
-/* 30 */ {Cache_L1i, 64 },
-/* 31 */ {Cache_UNKNOWN, 0 },
-/* 32 */ {Cache_UNKNOWN, 0 },
-/* 33 */ {Cache_UNKNOWN, 0 },
-/* 34 */ {Cache_UNKNOWN, 0 },
-/* 35 */ {Cache_UNKNOWN, 0 },
-/* 36 */ {Cache_UNKNOWN, 0 },
-/* 37 */ {Cache_UNKNOWN, 0 },
-/* 38 */ {Cache_UNKNOWN, 0 },
-/* 39 */ {Cache_L2, 64 },
-/* 3a */ {Cache_UNKNOWN, 0 },
-/* 3b */ {Cache_L2, 64 },
-/* 3c */ {Cache_L2, 64 },
-/* 3d */ {Cache_UNKNOWN, 0 },
-/* 3e */ {Cache_UNKNOWN, 0 },
-/* 3f */ {Cache_UNKNOWN, 0 },
-/* 40 */ {Cache_L2, 0 },
-/* 41 */ {Cache_L2, 32 },
-/* 42 */ {Cache_L2, 32 },
-/* 43 */ {Cache_L2, 32 },
-/* 44 */ {Cache_L2, 32 },
-/* 45 */ {Cache_L2, 32 },
-/* 46 */ {Cache_UNKNOWN, 0 },
-/* 47 */ {Cache_UNKNOWN, 0 },
-/* 48 */ {Cache_UNKNOWN, 0 },
-/* 49 */ {Cache_UNKNOWN, 0 },
-/* 4a */ {Cache_UNKNOWN, 0 },
-/* 4b */ {Cache_UNKNOWN, 0 },
-/* 4c */ {Cache_UNKNOWN, 0 },
-/* 4d */ {Cache_UNKNOWN, 0 },
-/* 4e */ {Cache_UNKNOWN, 0 },
-/* 4f */ {Cache_UNKNOWN, 0 },
-/* 50 */ {Cache_TLBi, 0 },
-/* 51 */ {Cache_TLBi, 0 },
-/* 52 */ {Cache_TLBi, 0 },
-/* 53 */ {Cache_UNKNOWN, 0 },
-/* 54 */ {Cache_UNKNOWN, 0 },
-/* 55 */ {Cache_UNKNOWN, 0 },
-/* 56 */ {Cache_UNKNOWN, 0 },
-/* 57 */ {Cache_UNKNOWN, 0 },
-/* 58 */ {Cache_UNKNOWN, 0 },
-/* 59 */ {Cache_UNKNOWN, 0 },
-/* 5a */ {Cache_UNKNOWN, 0 },
-/* 5b */ {Cache_TLBd, 0 },
-/* 5c */ {Cache_TLBd, 0 },
-/* 5d */ {Cache_TLBd, 0 },
-/* 5e */ {Cache_UNKNOWN, 0 },
-/* 5f */ {Cache_UNKNOWN, 0 },
-/* 60 */ {Cache_UNKNOWN, 0 },
-/* 61 */ {Cache_UNKNOWN, 0 },
-/* 62 */ {Cache_UNKNOWN, 0 },
-/* 63 */ {Cache_UNKNOWN, 0 },
-/* 64 */ {Cache_UNKNOWN, 0 },
-/* 65 */ {Cache_UNKNOWN, 0 },
-/* 66 */ {Cache_L1d, 64 },
-/* 67 */ {Cache_L1d, 64 },
-/* 68 */ {Cache_L1d, 64 },
-/* 69 */ {Cache_UNKNOWN, 0 },
-/* 6a */ {Cache_UNKNOWN, 0 },
-/* 6b */ {Cache_UNKNOWN, 0 },
-/* 6c */ {Cache_UNKNOWN, 0 },
-/* 6d */ {Cache_UNKNOWN, 0 },
-/* 6e */ {Cache_UNKNOWN, 0 },
-/* 6f */ {Cache_UNKNOWN, 0 },
-/* 70 */ {Cache_Trace, 1 },
-/* 71 */ {Cache_Trace, 1 },
-/* 72 */ {Cache_Trace, 1 },
-/* 73 */ {Cache_UNKNOWN, 0 },
-/* 74 */ {Cache_UNKNOWN, 0 },
-/* 75 */ {Cache_UNKNOWN, 0 },
-/* 76 */ {Cache_UNKNOWN, 0 },
-/* 77 */ {Cache_UNKNOWN, 0 },
-/* 78 */ {Cache_UNKNOWN, 0 },
-/* 79 */ {Cache_L2, 64 },
-/* 7a */ {Cache_L2, 64 },
-/* 7b */ {Cache_L2, 64 },
-/* 7c */ {Cache_L2, 64 },
-/* 7d */ {Cache_UNKNOWN, 0 },
-/* 7e */ {Cache_UNKNOWN, 0 },
-/* 7f */ {Cache_UNKNOWN, 0 },
-/* 80 */ {Cache_UNKNOWN, 0 },
-/* 81 */ {Cache_UNKNOWN, 0 },
-/* 82 */ {Cache_L2, 32 },
-/* 83 */ {Cache_L2, 32 },
-/* 84 */ {Cache_L2, 32 },
-/* 85 */ {Cache_L2, 32 },
-/* 86 */ {Cache_L2, 64 },
-/* 87 */ {Cache_L2, 64 },
-/* 88 */ {Cache_UNKNOWN, 0 },
-/* 89 */ {Cache_UNKNOWN, 0 },
-/* 8a */ {Cache_UNKNOWN, 0 },
-/* 8b */ {Cache_UNKNOWN, 0 },
-/* 8c */ {Cache_UNKNOWN, 0 },
-/* 8d */ {Cache_UNKNOWN, 0 },
-/* 8e */ {Cache_UNKNOWN, 0 },
-/* 8f */ {Cache_UNKNOWN, 0 },
-/* 90 */ {Cache_UNKNOWN, 0 },
-/* 91 */ {Cache_UNKNOWN, 0 },
-/* 92 */ {Cache_UNKNOWN, 0 },
-/* 93 */ {Cache_UNKNOWN, 0 },
-/* 94 */ {Cache_UNKNOWN, 0 },
-/* 95 */ {Cache_UNKNOWN, 0 },
-/* 96 */ {Cache_UNKNOWN, 0 },
-/* 97 */ {Cache_UNKNOWN, 0 },
-/* 98 */ {Cache_UNKNOWN, 0 },
-/* 99 */ {Cache_UNKNOWN, 0 },
-/* 9a */ {Cache_UNKNOWN, 0 },
-/* 9b */ {Cache_UNKNOWN, 0 },
-/* 9c */ {Cache_UNKNOWN, 0 },
-/* 9d */ {Cache_UNKNOWN, 0 },
-/* 9e */ {Cache_UNKNOWN, 0 },
-/* 9f */ {Cache_UNKNOWN, 0 },
-/* a0 */ {Cache_UNKNOWN, 0 },
-/* a1 */ {Cache_UNKNOWN, 0 },
-/* a2 */ {Cache_UNKNOWN, 0 },
-/* a3 */ {Cache_UNKNOWN, 0 },
-/* a4 */ {Cache_UNKNOWN, 0 },
-/* a5 */ {Cache_UNKNOWN, 0 },
-/* a6 */ {Cache_UNKNOWN, 0 },
-/* a7 */ {Cache_UNKNOWN, 0 },
-/* a8 */ {Cache_UNKNOWN, 0 },
-/* a9 */ {Cache_UNKNOWN, 0 },
-/* aa */ {Cache_UNKNOWN, 0 },
-/* ab */ {Cache_UNKNOWN, 0 },
-/* ac */ {Cache_UNKNOWN, 0 },
-/* ad */ {Cache_UNKNOWN, 0 },
-/* ae */ {Cache_UNKNOWN, 0 },
-/* af */ {Cache_UNKNOWN, 0 },
-/* b0 */ {Cache_TLBi, 0 },
-/* b1 */ {Cache_UNKNOWN, 0 },
-/* b2 */ {Cache_UNKNOWN, 0 },
-/* b3 */ {Cache_TLBd, 0 },
-/* b4 */ {Cache_UNKNOWN, 0 },
-/* b5 */ {Cache_UNKNOWN, 0 },
-/* b6 */ {Cache_UNKNOWN, 0 },
-/* b7 */ {Cache_UNKNOWN, 0 },
-/* b8 */ {Cache_UNKNOWN, 0 },
-/* b9 */ {Cache_UNKNOWN, 0 },
-/* ba */ {Cache_UNKNOWN, 0 },
-/* bb */ {Cache_UNKNOWN, 0 },
-/* bc */ {Cache_UNKNOWN, 0 },
-/* bd */ {Cache_UNKNOWN, 0 },
-/* be */ {Cache_UNKNOWN, 0 },
-/* bf */ {Cache_UNKNOWN, 0 },
-/* c0 */ {Cache_UNKNOWN, 0 },
-/* c1 */ {Cache_UNKNOWN, 0 },
-/* c2 */ {Cache_UNKNOWN, 0 },
-/* c3 */ {Cache_UNKNOWN, 0 },
-/* c4 */ {Cache_UNKNOWN, 0 },
-/* c5 */ {Cache_UNKNOWN, 0 },
-/* c6 */ {Cache_UNKNOWN, 0 },
-/* c7 */ {Cache_UNKNOWN, 0 },
-/* c8 */ {Cache_UNKNOWN, 0 },
-/* c9 */ {Cache_UNKNOWN, 0 },
-/* ca */ {Cache_UNKNOWN, 0 },
-/* cb */ {Cache_UNKNOWN, 0 },
-/* cc */ {Cache_UNKNOWN, 0 },
-/* cd */ {Cache_UNKNOWN, 0 },
-/* ce */ {Cache_UNKNOWN, 0 },
-/* cf */ {Cache_UNKNOWN, 0 },
-/* d0 */ {Cache_UNKNOWN, 0 },
-/* d1 */ {Cache_UNKNOWN, 0 },
-/* d2 */ {Cache_UNKNOWN, 0 },
-/* d3 */ {Cache_UNKNOWN, 0 },
-/* d4 */ {Cache_UNKNOWN, 0 },
-/* d5 */ {Cache_UNKNOWN, 0 },
-/* d6 */ {Cache_UNKNOWN, 0 },
-/* d7 */ {Cache_UNKNOWN, 0 },
-/* d8 */ {Cache_UNKNOWN, 0 },
-/* d9 */ {Cache_UNKNOWN, 0 },
-/* da */ {Cache_UNKNOWN, 0 },
-/* db */ {Cache_UNKNOWN, 0 },
-/* dc */ {Cache_UNKNOWN, 0 },
-/* dd */ {Cache_UNKNOWN, 0 },
-/* de */ {Cache_UNKNOWN, 0 },
-/* df */ {Cache_UNKNOWN, 0 },
-/* e0 */ {Cache_UNKNOWN, 0 },
-/* e1 */ {Cache_UNKNOWN, 0 },
-/* e2 */ {Cache_UNKNOWN, 0 },
-/* e3 */ {Cache_UNKNOWN, 0 },
-/* e4 */ {Cache_UNKNOWN, 0 },
-/* e5 */ {Cache_UNKNOWN, 0 },
-/* e6 */ {Cache_UNKNOWN, 0 },
-/* e7 */ {Cache_UNKNOWN, 0 },
-/* e8 */ {Cache_UNKNOWN, 0 },
-/* e9 */ {Cache_UNKNOWN, 0 },
-/* ea */ {Cache_UNKNOWN, 0 },
-/* eb */ {Cache_UNKNOWN, 0 },
-/* ec */ {Cache_UNKNOWN, 0 },
-/* ed */ {Cache_UNKNOWN, 0 },
-/* ee */ {Cache_UNKNOWN, 0 },
-/* ef */ {Cache_UNKNOWN, 0 },
-/* f0 */ {Cache_UNKNOWN, 0 },
-/* f1 */ {Cache_UNKNOWN, 0 },
-/* f2 */ {Cache_UNKNOWN, 0 },
-/* f3 */ {Cache_UNKNOWN, 0 },
-/* f4 */ {Cache_UNKNOWN, 0 },
-/* f5 */ {Cache_UNKNOWN, 0 },
-/* f6 */ {Cache_UNKNOWN, 0 },
-/* f7 */ {Cache_UNKNOWN, 0 },
-/* f8 */ {Cache_UNKNOWN, 0 },
-/* f9 */ {Cache_UNKNOWN, 0 },
-/* fa */ {Cache_UNKNOWN, 0 },
-/* fb */ {Cache_UNKNOWN, 0 },
-/* fc */ {Cache_UNKNOWN, 0 },
-/* fd */ {Cache_UNKNOWN, 0 },
-/* fe */ {Cache_UNKNOWN, 0 },
-/* ff */ {Cache_UNKNOWN, 0 }
-};
-
-
-/*
- * use the above table to determine the CacheEntryLineSize.
- */
-static void
-getIntelCacheEntryLineSize(unsigned long val, int *level,
- unsigned long *lineSize)
-{
- CacheType type;
-
- type = CacheMap[val].type;
- /* only interested in data caches */
- /* NOTE val = 0x40 is a special value that means no L2 or L3 cache.
- * this data check has the side effect of rejecting that entry. If
- * that wasn't the case, we could have to reject it explicitly */
- if (CacheMap[val].lineSize == 0) {
- return;
- }
- /* look at the caches, skip types we aren't interested in.
- * if we already have a value for a lower level cache, skip the
- * current entry */
- if ((type == Cache_L1)|| (type == Cache_L1d)) {
- *level = 1;
- *lineSize = CacheMap[val].lineSize;
- } else if ((*level >= 2) && ((type == Cache_L2) || (type == Cache_L2d))) {
- *level = 2;
- *lineSize = CacheMap[val].lineSize;
- } else if ((*level >= 3) && ((type == Cache_L3) || (type == Cache_L3d))) {
- *level = 3;
- *lineSize = CacheMap[val].lineSize;
- }
- return;
-}
-
-
-static void
-getIntelRegisterCacheLineSize(unsigned long val,
- int *level, unsigned long *lineSize)
-{
- getIntelCacheEntryLineSize(val >> 24 & 0xff, level, lineSize);
- getIntelCacheEntryLineSize(val >> 16 & 0xff, level, lineSize);
- getIntelCacheEntryLineSize(val >> 8 & 0xff, level, lineSize);
- getIntelCacheEntryLineSize(val & 0xff, level, lineSize);
-}
-
-/*
- * returns '0' if no recognized cache is found, or if the cache
- * information is supported by this processor
- */
-static unsigned long
-getIntelCacheLineSize(int cpuidLevel)
-{
- int level = 4;
- unsigned long lineSize = 0;
- unsigned long eax, ebx, ecx, edx;
- int repeat, count;
-
- if (cpuidLevel < 2) {
- return 0;
- }
-
- /* command '2' of the cpuid is intel's cache info call. Each byte of the
- * 4 registers contain a potential descriptor for the cache. The CacheMap
- * table maps the cache entry with the processor cache. Register 'al'
- * contains a count value that cpuid '2' needs to be called in order to
- * find all the cache descriptors. Only registers with the high bit set
- * to 'zero' have valid descriptors. This code loops through all the
- * required calls to cpuid '2' and passes any valid descriptors it finds
- * to the getIntelRegisterCacheLineSize code, which breaks the registers
- * down into their component descriptors. In the end the lineSize of the
- * lowest level cache data cache is returned. */
- freebl_cpuid(2, &eax, &ebx, &ecx, &edx);
- repeat = eax & 0xf;
- for (count = 0; count < repeat; count++) {
- if ((eax & 0x80000000) == 0) {
- getIntelRegisterCacheLineSize(eax & 0xffffff00, &level, &lineSize);
- }
- if ((ebx & 0x80000000) == 0) {
- getIntelRegisterCacheLineSize(ebx, &level, &lineSize);
- }
- if ((ecx & 0x80000000) == 0) {
- getIntelRegisterCacheLineSize(ecx, &level, &lineSize);
- }
- if ((edx & 0x80000000) == 0) {
- getIntelRegisterCacheLineSize(edx, &level, &lineSize);
- }
- if (count+1 != repeat) {
- freebl_cpuid(2, &eax, &ebx, &ecx, &edx);
- }
- }
- return lineSize;
-}
-
-/*
- * returns '0' if the cache info is not supported by this processor.
- * This is based on the AMD extended cache commands for cpuid.
- * (see "AMD Processor Recognition Application Note" Publication 20734).
- * Some other processors use the identical scheme.
- * (see "Processor Recognition, Transmeta Corporation").
- */
-static unsigned long
-getOtherCacheLineSize(unsigned long cpuidLevel)
-{
- unsigned long lineSize = 0;
- unsigned long eax, ebx, ecx, edx;
-
- /* get the Extended CPUID level */
- freebl_cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
- cpuidLevel = eax;
-
- if (cpuidLevel >= 0x80000005) {
- freebl_cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
- lineSize = ecx & 0xff; /* line Size, L1 Data Cache */
- }
- return lineSize;
-}
-
-static const char * const manMap[] = {
-#define INTEL 0
- "GenuineIntel",
-#define AMD 1
- "AuthenticAMD",
-#define CYRIX 2
- "CyrixInstead",
-#define CENTAUR 2
- "CentaurHauls",
-#define NEXGEN 3
- "NexGenDriven",
-#define TRANSMETA 4
- "GenuineTMx86",
-#define RISE 5
- "RiseRiseRise",
-#define UMC 6
- "UMC UMC UMC ",
-#define SIS 7
- "Sis Sis Sis ",
-#define NATIONAL 8
- "Geode by NSC",
-};
-
-static const int n_manufacturers = sizeof(manMap)/sizeof(manMap[0]);
-
-
-#define MAN_UNKNOWN 9
-
-#if !defined(AMD_64)
-#define SSE2_FLAG (1<<26)
-unsigned long
-s_mpi_is_sse2()
-{
- unsigned long eax, ebx, ecx, edx;
- int manufacturer = MAN_UNKNOWN;
- int i;
- char string[13];
-
- if (is386() || is486()) {
- return 0;
- }
- freebl_cpuid(0, &eax, &ebx, &ecx, &edx);
- /* string holds the CPU's manufacturer ID string - a twelve
- * character ASCII string stored in ebx, edx, ecx, and
- * the 32-bit extended feature flags are in edx, ecx.
- */
- *(int *)string = ebx;
- *(int *)&string[4] = (int)edx;
- *(int *)&string[8] = (int)ecx;
- string[12] = 0;
-
- /* has no SSE2 extensions */
- if (eax == 0) {
- return 0;
- }
-
- for (i=0; i < n_manufacturers; i++) {
- if ( strcmp(manMap[i],string) == 0) {
- manufacturer = i;
- break;
- }
- }
-
- freebl_cpuid(1,&eax,&ebx,&ecx,&edx);
- return (edx & SSE2_FLAG) == SSE2_FLAG;
-}
-#endif
-
-unsigned long
-s_mpi_getProcessorLineSize()
-{
- unsigned long eax, ebx, ecx, edx;
- unsigned long cpuidLevel;
- unsigned long cacheLineSize = 0;
- int manufacturer = MAN_UNKNOWN;
- int i;
- char string[65];
-
-#if !defined(AMD_64)
- if (is386()) {
- return 0; /* 386 had no cache */
- } if (is486()) {
- return 32; /* really? need more info */
- }
-#endif
-
- /* Pentium, cpuid command is available */
- freebl_cpuid(0, &eax, &ebx, &ecx, &edx);
- cpuidLevel = eax;
- /* string holds the CPU's manufacturer ID string - a twelve
- * character ASCII string stored in ebx, edx, ecx, and
- * the 32-bit extended feature flags are in edx, ecx.
- */
- *(int *)string = ebx;
- *(int *)&string[4] = (int)edx;
- *(int *)&string[8] = (int)ecx;
- string[12] = 0;
-
- manufacturer = MAN_UNKNOWN;
- for (i=0; i < n_manufacturers; i++) {
- if ( strcmp(manMap[i],string) == 0) {
- manufacturer = i;
- }
- }
-
- if (manufacturer == INTEL) {
- cacheLineSize = getIntelCacheLineSize(cpuidLevel);
- } else {
- cacheLineSize = getOtherCacheLineSize(cpuidLevel);
- }
- /* doesn't support cache info based on cpuid. This means
- * an old pentium class processor, which have cache lines of
- * 32. If we learn differently, we can use a switch based on
- * the Manufacturer id */
- if (cacheLineSize == 0) {
- cacheLineSize = 32;
- }
- return cacheLineSize;
-}
-#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
-#endif
-
-#if defined(__ppc64__)
-/*
- * Sigh, The PPC has some really nice features to help us determine cache
- * size, since it had lots of direct control functions to do so. The POWER
- * processor even has an instruction to do this, but it was dropped in
- * PowerPC. Unfortunately most of them are not available in user mode.
- *
- * The dcbz function would be a great way to determine cache line size except
- * 1) it only works on write-back memory (it throws an exception otherwise),
- * and 2) because so many mac programs 'knew' the processor cache size was
- * 32 bytes, they used this instruction as a fast 'zero 32 bytes'. Now the new
- * G5 processor has 128 byte cache, but dcbz only clears 32 bytes to keep
- * these programs happy. dcbzl work if 64 bit instructions are supported.
- * If you know 64 bit instructions are supported, and that stack is
- * write-back, you can use this code.
- */
-#include "memory.h"
-
-/* clear the cache line that contains 'array' */
-static inline void dcbzl(char *array)
-{
- register char *a asm("r2") = array;
- __asm__ __volatile__( "dcbzl %0,r0" : "=r" (a): "0"(a) );
-}
-
-
-#define PPC_DO_ALIGN(x,y) ((char *)\
- ((((long long) (x))+((y)-1))&~((y)-1)))
-
-#define PPC_MAX_LINE_SIZE 256
-unsigned long
-s_mpi_getProcessorLineSize()
-{
- char testArray[2*PPC_MAX_LINE_SIZE+1];
- char *test;
- int i;
-
- /* align the array on a maximum line size boundary, so we
- * know we are starting to clear from the first address */
- test = PPC_DO_ALIGN(testArray, PPC_MAX_LINE_SIZE);
- /* set all the values to 1's */
- memset(test, 0xff, PPC_MAX_LINE_SIZE);
- /* clear one cache block starting at 'test' */
- dcbzl(test);
-
- /* find the size of the cleared area, that's our block size */
- for (i=PPC_MAX_LINE_SIZE; i != 0; i = i/2) {
- if (test[i-1] == 0) {
- return i;
- }
- }
- return 0;
-}
-
-#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
-#endif
-
-
-/*
- * put other processor and platform specific cache code here
- * return the smallest cache line size in bytes on the processor
- * (usually the L1 cache). If the OS has a call, this would be
- * a greate place to put it.
- *
- * If there is no cache, return 0;
- *
- * define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED so the generic functions
- * below aren't compiled.
- *
- */
-
-
-/* target.mk can define MPI_CACHE_LINE_SIZE if it's common for the family or
- * OS */
-#if defined(MPI_CACHE_LINE_SIZE) && !defined(MPI_GET_PROCESSOR_LINE_SIZE_DEFINED)
-
-unsigned long
-s_mpi_getProcessorLineSize()
-{
- return MPI_CACHE_LINE_SIZE;
-}
-#define MPI_GET_PROCESSOR_LINE_SIZE_DEFINED 1
-#endif
-
-
-/* If no way to get the processor cache line size has been defined, assume
- * it's 32 bytes (most common value, does not significantly impact performance)
- */
-#ifndef MPI_GET_PROCESSOR_LINE_SIZE_DEFINED
-unsigned long
-s_mpi_getProcessorLineSize()
-{
- return 32;
-}
-#endif
-
-#ifdef TEST_IT
-#include <stdio.h>
-
-main()
-{
- printf("line size = %d\n", s_mpi_getProcessorLineSize());
-}
-#endif
diff --git a/security/nss/lib/freebl/mpi/mpcpucache_amd64.s b/security/nss/lib/freebl/mpi/mpcpucache_amd64.s
deleted file mode 100644
index d493b4762..000000000
--- a/security/nss/lib/freebl/mpi/mpcpucache_amd64.s
+++ /dev/null
@@ -1,861 +0,0 @@
-/ This Source Code Form is subject to the terms of the Mozilla Public
-/ License, v. 2.0. If a copy of the MPL was not distributed with this
-/ file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
- .file "mpcpucache.c"
-/ .section .rodata.str1.1,"aMS",@progbits,1
- .section .rodata
-.LC0:
- .string "GenuineIntel"
-.LC1:
- .string "AuthenticAMD"
-.LC2:
- .string "CyrixInstead"
-.LC3:
- .string "CentaurHauls"
-.LC4:
- .string "NexGenDriven"
-.LC5:
- .string "GenuineTMx86"
-.LC6:
- .string "RiseRiseRise"
-.LC7:
- .string "UMC UMC UMC "
-.LC8:
- .string "Sis Sis Sis "
-.LC9:
- .string "Geode by NSC"
- .section .data.rel.ro.local,"aw",@progbits
- .align 32
- .type manMap, @object
- .size manMap, 80
-manMap:
- .quad .LC0
- .quad .LC1
- .quad .LC2
- .quad .LC3
- .quad .LC4
- .quad .LC5
- .quad .LC6
- .quad .LC7
- .quad .LC8
- .quad .LC9
- .section .rodata
- .align 32
- .type CacheMap, @object
- .size CacheMap, 512
-CacheMap:
- .byte 0
- .byte 0
- .byte 3
- .byte 0
- .byte 3
- .byte 0
- .byte 4
- .byte 0
- .byte 4
- .zero 1
- .byte 1
- .byte 0
- .byte 7
- .byte 32
- .byte 1
- .byte 0
- .byte 7
- .byte 32
- .byte 1
- .byte 0
- .byte 8
- .byte 32
- .byte 1
- .byte 0
- .byte 8
- .byte 32
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 12
- .byte 64
- .byte 12
- .byte 64
- .byte 1
- .byte 0
- .byte 12
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 12
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 8
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 7
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 9
- .byte 64
- .byte 1
- .byte 0
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 9
- .byte 0
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 3
- .byte 0
- .byte 3
- .byte 0
- .byte 3
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 4
- .byte 0
- .byte 4
- .byte 0
- .byte 4
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 8
- .byte 64
- .byte 8
- .byte 64
- .byte 8
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 5
- .byte 1
- .byte 5
- .byte 1
- .byte 5
- .byte 1
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 3
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 4
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .text
- .align 16
-.globl freebl_cpuid
- .type freebl_cpuid, @function
-freebl_cpuid:
-.LFB2:
- movq %rdx, %r10
- pushq %rbx
-.LCFI0:
- movq %rcx, %r11
- movq %rdi, %rax
-/APP
- cpuid
-
-/NO_APP
- movq %rax, (%rsi)
- movq %rbx, (%r10)
- popq %rbx
- movq %rcx, (%r11)
- movq %rdx, (%r8)
- ret
-.LFE2:
- .size freebl_cpuid, .-freebl_cpuid
- .align 16
- .type getIntelCacheEntryLineSize, @function
-getIntelCacheEntryLineSize:
-.LFB3:
- leaq CacheMap(%rip), %r9
- movq %rdx, %r10
- movzbl 1(%r9,%rdi,2), %ecx
- movzbl (%r9,%rdi,2), %r8d
- testb %cl, %cl
- je .L2
- cmpl $6, %r8d
- sete %dl
- cmpl $8, %r8d
- sete %al
- orl %edx, %eax
- testb $1, %al
- je .L4
- movl $1, (%rsi)
-.L9:
- movzbl %cl, %eax
- movq %rax, (%r10)
- ret
- .align 16
-.L4:
- movl (%rsi), %r11d
- cmpl $1, %r11d
- jg .L11
-.L6:
- cmpl $2, %r11d
- jle .L2
- cmpl $12, %r8d
- sete %dl
- cmpl $14, %r8d
- sete %al
- orl %edx, %eax
- testb $1, %al
- je .L2
- movzbq 1(%r9,%rdi,2), %rax
- movl $3, (%rsi)
- movq %rax, (%r10)
- .align 16
-.L2:
- rep ; ret
- .align 16
-.L11:
- cmpl $9, %r8d
- sete %dl
- cmpl $11, %r8d
- sete %al
- orl %edx, %eax
- testb $1, %al
- je .L6
- movl $2, (%rsi)
- jmp .L9
-.LFE3:
- .size getIntelCacheEntryLineSize, .-getIntelCacheEntryLineSize
- .align 16
- .type getIntelRegisterCacheLineSize, @function
-getIntelRegisterCacheLineSize:
-.LFB4:
- pushq %rbp
-.LCFI1:
- movq %rsp, %rbp
-.LCFI2:
- movq %rbx, -24(%rbp)
-.LCFI3:
- movq %rdi, %rbx
- shrq $24, %rdi
- movq %r12, -16(%rbp)
-.LCFI4:
- movq %r13, -8(%rbp)
-.LCFI5:
- andl $255, %edi
- subq $24, %rsp
-.LCFI6:
- movq %rsi, %r13
- movq %rdx, %r12
- call getIntelCacheEntryLineSize
- movq %rbx, %rdi
- movq %r12, %rdx
- movq %r13, %rsi
- shrq $16, %rdi
- andl $255, %edi
- call getIntelCacheEntryLineSize
- movq %rbx, %rdi
- movq %r12, %rdx
- movq %r13, %rsi
- shrq $8, %rdi
- andl $255, %ebx
- andl $255, %edi
- call getIntelCacheEntryLineSize
- movq %r12, %rdx
- movq %r13, %rsi
- movq %rbx, %rdi
- movq 8(%rsp), %r12
- movq (%rsp), %rbx
- movq 16(%rsp), %r13
- leave
- jmp getIntelCacheEntryLineSize
-.LFE4:
- .size getIntelRegisterCacheLineSize, .-getIntelRegisterCacheLineSize
- .align 16
-.globl s_mpi_getProcessorLineSize
- .type s_mpi_getProcessorLineSize, @function
-s_mpi_getProcessorLineSize:
-.LFB7:
- pushq %rbp
-.LCFI7:
- xorl %edi, %edi
- movq %rsp, %rbp
-.LCFI8:
- pushq %r15
-.LCFI9:
- leaq -136(%rbp), %r8
- leaq -144(%rbp), %rcx
- leaq -152(%rbp), %rdx
- pushq %r14
-.LCFI10:
- leaq -160(%rbp), %rsi
- leaq -128(%rbp), %r14
- pushq %r13
-.LCFI11:
- leaq manMap(%rip), %r13
- pushq %r12
-.LCFI12:
- movl $9, %r12d
- pushq %rbx
-.LCFI13:
- xorl %ebx, %ebx
- subq $200, %rsp
-.LCFI14:
- call freebl_cpuid
- movq -152(%rbp), %rax
- movq -160(%rbp), %r15
- movb $0, -116(%rbp)
- movl %eax, -128(%rbp)
- movq -136(%rbp), %rax
- movl %eax, -124(%rbp)
- movq -144(%rbp), %rax
- movl %eax, -120(%rbp)
- .align 16
-.L18:
- movslq %ebx,%rax
- movq %r14, %rsi
- movq (%r13,%rax,8), %rdi
- call strcmp@PLT
- testl %eax, %eax
- cmove %ebx, %r12d
- incl %ebx
- cmpl $9, %ebx
- jle .L18
- testl %r12d, %r12d
- jne .L19
- xorl %eax, %eax
- decl %r15d
- movl $4, -204(%rbp)
- movq $0, -200(%rbp)
- jle .L21
- leaq -168(%rbp), %r8
- leaq -176(%rbp), %rcx
- leaq -184(%rbp), %rdx
- leaq -192(%rbp), %rsi
- movl $2, %edi
- xorl %ebx, %ebx
- call freebl_cpuid
- movq -192(%rbp), %rdi
- movl %edi, %r12d
- andl $15, %r12d
- cmpl %r12d, %ebx
- jl .L30
- jmp .L38
- .align 16
-.L25:
- movq -184(%rbp), %rdi
- testl $2147483648, %edi
- je .L40
-.L26:
- movq -176(%rbp), %rdi
- testl $2147483648, %edi
- je .L41
-.L27:
- movq -168(%rbp), %rdi
- testl $2147483648, %edi
- je .L42
-.L28:
- incl %ebx
- cmpl %r12d, %ebx
- je .L24
- leaq -168(%rbp), %r8
- leaq -176(%rbp), %rcx
- leaq -184(%rbp), %rdx
- leaq -192(%rbp), %rsi
- movl $2, %edi
- call freebl_cpuid
-.L24:
- cmpl %r12d, %ebx
- jge .L38
- movq -192(%rbp), %rdi
-.L30:
- testl $2147483648, %edi
- jne .L25
- leaq -200(%rbp), %rdx
- leaq -204(%rbp), %rsi
- andl $4294967040, %edi
- call getIntelRegisterCacheLineSize
- movq -184(%rbp), %rdi
- testl $2147483648, %edi
- jne .L26
-.L40:
- leaq -200(%rbp), %rdx
- leaq -204(%rbp), %rsi
- call getIntelRegisterCacheLineSize
- movq -176(%rbp), %rdi
- testl $2147483648, %edi
- jne .L27
-.L41:
- leaq -200(%rbp), %rdx
- leaq -204(%rbp), %rsi
- call getIntelRegisterCacheLineSize
- movq -168(%rbp), %rdi
- testl $2147483648, %edi
- jne .L28
-.L42:
- leaq -200(%rbp), %rdx
- leaq -204(%rbp), %rsi
- call getIntelRegisterCacheLineSize
- jmp .L28
-.L38:
- movq -200(%rbp), %rax
-.L21:
- movq %rax, %rdx
- movl $32, %eax
- testq %rdx, %rdx
- cmoveq %rax, %rdx
- addq $200, %rsp
- popq %rbx
- popq %r12
- popq %r13
- popq %r14
- popq %r15
- leave
- movq %rdx, %rax
- ret
-.L19:
- leaq -216(%rbp), %r8
- leaq -224(%rbp), %rcx
- leaq -232(%rbp), %rdx
- leaq -240(%rbp), %rsi
- movl $2147483648, %edi
- xorl %ebx, %ebx
- call freebl_cpuid
- movl $2147483652, %eax
- cmpq %rax, -240(%rbp)
- ja .L43
-.L32:
- movq %rbx, %rdx
- movl $32, %eax
- testq %rdx, %rdx
- cmoveq %rax, %rdx
- addq $200, %rsp
- popq %rbx
- popq %r12
- popq %r13
- popq %r14
- popq %r15
- leave
- movq %rdx, %rax
- ret
-.L43:
- leaq -216(%rbp), %r8
- leaq -224(%rbp), %rcx
- leaq -232(%rbp), %rdx
- leaq -240(%rbp), %rsi
- movl $2147483653, %edi
- call freebl_cpuid
- movzbq -224(%rbp), %rbx
- jmp .L32
-.LFE7:
- .size s_mpi_getProcessorLineSize, .-s_mpi_getProcessorLineSize
diff --git a/security/nss/lib/freebl/mpi/mpcpucache_x86.s b/security/nss/lib/freebl/mpi/mpcpucache_x86.s
deleted file mode 100644
index cc65ea3d4..000000000
--- a/security/nss/lib/freebl/mpi/mpcpucache_x86.s
+++ /dev/null
@@ -1,901 +0,0 @@
-/ This Source Code Form is subject to the terms of the Mozilla Public
-/ License, v. 2.0. If a copy of the MPL was not distributed with this
-/ file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
- .file "mpcpucache.c"
-/ .section .rodata.str1.1,"aMS",@progbits,1
- .section .rodata
-.LC0:
- .string "GenuineIntel"
-.LC1:
- .string "AuthenticAMD"
-.LC2:
- .string "CyrixInstead"
-.LC3:
- .string "CentaurHauls"
-.LC4:
- .string "NexGenDriven"
-.LC5:
- .string "GenuineTMx86"
-.LC6:
- .string "RiseRiseRise"
-.LC7:
- .string "UMC UMC UMC "
-.LC8:
- .string "Sis Sis Sis "
-.LC9:
- .string "Geode by NSC"
- .section .data.rel.ro.local,"aw",@progbits
- .align 32
- .type manMap, @object
- .size manMap, 40
-manMap:
- .long .LC0
- .long .LC1
- .long .LC2
- .long .LC3
- .long .LC4
- .long .LC5
- .long .LC6
- .long .LC7
- .long .LC8
- .long .LC9
- .section .rodata
- .align 32
- .type CacheMap, @object
- .size CacheMap, 512
-CacheMap:
- .byte 0
- .byte 0
- .byte 3
- .byte 0
- .byte 3
- .byte 0
- .byte 4
- .byte 0
- .byte 4
- .zero 1
- .byte 1
- .byte 0
- .byte 7
- .byte 32
- .byte 1
- .byte 0
- .byte 7
- .byte 32
- .byte 1
- .byte 0
- .byte 8
- .byte 32
- .byte 1
- .byte 0
- .byte 8
- .byte 32
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 12
- .byte 64
- .byte 12
- .byte 64
- .byte 1
- .byte 0
- .byte 12
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 12
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 8
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 7
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 9
- .byte 64
- .byte 1
- .byte 0
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 9
- .byte 0
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 3
- .byte 0
- .byte 3
- .byte 0
- .byte 3
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 4
- .byte 0
- .byte 4
- .byte 0
- .byte 4
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 8
- .byte 64
- .byte 8
- .byte 64
- .byte 8
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 5
- .byte 1
- .byte 5
- .byte 1
- .byte 5
- .byte 1
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 32
- .byte 9
- .byte 64
- .byte 9
- .byte 64
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 3
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 4
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .byte 1
- .byte 0
- .text
- .align 4
-.globl freebl_cpuid
- .type freebl_cpuid, @function
-freebl_cpuid:
- pushl %ebp
- pushl %edi
- pushl %esi
- subl $8, %esp
- movl %edx, %ebp
-/APP
- pushl %ebx
- cpuid
- mov %ebx,%esi
- popl %ebx
-
-/NO_APP
- movl %eax, (%ebp)
- movl 24(%esp), %eax
- movl %esi, (%eax)
- movl 28(%esp), %eax
- movl %ecx, (%eax)
- movl 32(%esp), %eax
- movl %edx, (%eax)
- addl $8, %esp
- popl %esi
- popl %edi
- popl %ebp
- ret
- .size freebl_cpuid, .-freebl_cpuid
- .align 4
- .type changeFlag, @function
-changeFlag:
-/APP
- pushfl
- popl %edx
- movl %edx,%ecx
- xorl %eax,%edx
- pushl %edx
- popfl
- pushfl
- popl %edx
- pushl %ecx
- popfl
-
-/NO_APP
- xorl %ecx, %edx
- movl %edx, %eax
- ret
- .size changeFlag, .-changeFlag
- .align 4
- .type getIntelCacheEntryLineSize, @function
-getIntelCacheEntryLineSize:
- pushl %edi
- pushl %esi
- pushl %ebx
- call .L17
-.L17:
- popl %ebx
- addl $_GLOBAL_OFFSET_TABLE_+[.-.L17], %ebx
- movzbl CacheMap@GOTOFF(%ebx,%eax,2), %ecx
- movb 1+CacheMap@GOTOFF(%ebx,%eax,2), %al
- testb %al, %al
- movl 16(%esp), %edi
- je .L3
- cmpl $6, %ecx
- je .L6
- cmpl $8, %ecx
- je .L6
- movl (%edx), %esi
- cmpl $1, %esi
- jg .L15
-.L8:
- cmpl $2, %esi
- jle .L3
- cmpl $12, %ecx
- je .L12
- cmpl $14, %ecx
- je .L12
- .align 4
-.L3:
- popl %ebx
- popl %esi
- popl %edi
- ret
- .align 4
-.L6:
- movzbl %al, %eax
- movl $1, (%edx)
- movl %eax, (%edi)
-.L16:
- popl %ebx
- popl %esi
- popl %edi
- ret
- .align 4
-.L15:
- cmpl $9, %ecx
- je .L9
- cmpl $11, %ecx
- jne .L8
-.L9:
- movzbl %al, %eax
- movl $2, (%edx)
- movl %eax, (%edi)
- jmp .L16
-.L12:
- movzbl %al, %eax
- movl $3, (%edx)
- movl %eax, (%edi)
- jmp .L16
- .size getIntelCacheEntryLineSize, .-getIntelCacheEntryLineSize
- .align 4
- .type getIntelRegisterCacheLineSize, @function
-getIntelRegisterCacheLineSize:
- pushl %ebp
- movl %esp, %ebp
- pushl %edi
- pushl %esi
- pushl %ecx
- movl 8(%ebp), %edi
- movl %eax, %esi
- movl %edx, -12(%ebp)
- shrl $24, %eax
- pushl %edi
- call getIntelCacheEntryLineSize
- movl %esi, %eax
- pushl %edi
- shrl $16, %eax
- movl -12(%ebp), %edx
- andl $255, %eax
- call getIntelCacheEntryLineSize
- pushl %edi
- movl %esi, %edx
- movzbl %dh, %eax
- movl -12(%ebp), %edx
- call getIntelCacheEntryLineSize
- andl $255, %esi
- movl %edi, 8(%ebp)
- movl -12(%ebp), %edx
- addl $12, %esp
- leal -8(%ebp), %esp
- movl %esi, %eax
- popl %esi
- popl %edi
- leave
- jmp getIntelCacheEntryLineSize
- .size getIntelRegisterCacheLineSize, .-getIntelRegisterCacheLineSize
- .align 4
-.globl s_mpi_getProcessorLineSize
- .type s_mpi_getProcessorLineSize, @function
-s_mpi_getProcessorLineSize:
- pushl %ebp
- movl %esp, %ebp
- pushl %edi
- pushl %esi
- pushl %ebx
- subl $188, %esp
- call .L52
-.L52:
- popl %ebx
- addl $_GLOBAL_OFFSET_TABLE_+[.-.L52], %ebx
- movl $9, -168(%ebp)
- movl $262144, %eax
- call changeFlag
- xorl %edx, %edx
- testl %eax, %eax
- jne .L50
-.L19:
- leal -12(%ebp), %esp
- popl %ebx
- popl %esi
- movl %edx, %eax
- popl %edi
- leave
- ret
- .align 4
-.L50:
- movl $2097152, %eax
- call changeFlag
- testl %eax, %eax
- movl $32, %edx
- je .L19
- leal -108(%ebp), %eax
- pushl %eax
- leal -112(%ebp), %eax
- pushl %eax
- leal -116(%ebp), %eax
- pushl %eax
- leal -120(%ebp), %edx
- xorl %eax, %eax
- call freebl_cpuid
- movl -120(%ebp), %eax
- movl %eax, -164(%ebp)
- movl -116(%ebp), %eax
- movl %eax, -104(%ebp)
- movl -108(%ebp), %eax
- movl %eax, -100(%ebp)
- movl -112(%ebp), %eax
- movl %eax, -96(%ebp)
- movb $0, -92(%ebp)
- xorl %esi, %esi
- addl $12, %esp
- leal -104(%ebp), %edi
- .align 4
-.L28:
- subl $8, %esp
- pushl %edi
- pushl manMap@GOTOFF(%ebx,%esi,4)
- call strcmp@PLT
- addl $16, %esp
- testl %eax, %eax
- jne .L26
- movl %esi, -168(%ebp)
-.L26:
- incl %esi
- cmpl $9, %esi
- jle .L28
- movl -168(%ebp), %eax
- testl %eax, %eax
- jne .L29
- xorl %eax, %eax
- cmpl $1, -164(%ebp)
- movl $4, -144(%ebp)
- movl $0, -140(%ebp)
- jle .L41
- leal -124(%ebp), %edx
- movl %edx, -188(%ebp)
- leal -128(%ebp), %eax
- pushl %edx
- movl %eax, -184(%ebp)
- leal -132(%ebp), %edx
- pushl %eax
- movl %edx, -180(%ebp)
- movl $2, %eax
- pushl %edx
- leal -136(%ebp), %edx
- call freebl_cpuid
- movl -136(%ebp), %eax
- movl %eax, %edi
- andl $15, %edi
- xorl %esi, %esi
- addl $12, %esp
- leal -140(%ebp), %edx
- cmpl %edi, %esi
- movl %edx, -176(%ebp)
- jl .L40
- jmp .L48
- .align 4
-.L49:
- movl -136(%ebp), %eax
-.L40:
- testl %eax, %eax
- js .L35
- xorb %al, %al
- pushl -176(%ebp)
- leal -144(%ebp), %edx
- call getIntelRegisterCacheLineSize
- popl %eax
-.L35:
- movl -132(%ebp), %eax
- testl %eax, %eax
- js .L36
- pushl -176(%ebp)
- leal -144(%ebp), %edx
- call getIntelRegisterCacheLineSize
- popl %eax
-.L36:
- movl -128(%ebp), %eax
- testl %eax, %eax
- js .L37
- pushl -176(%ebp)
- leal -144(%ebp), %edx
- call getIntelRegisterCacheLineSize
- popl %eax
-.L37:
- movl -124(%ebp), %eax
- testl %eax, %eax
- js .L38
- pushl -176(%ebp)
- leal -144(%ebp), %edx
- call getIntelRegisterCacheLineSize
- popl %eax
-.L38:
- incl %esi
- cmpl %edi, %esi
- je .L34
- pushl -188(%ebp)
- pushl -184(%ebp)
- pushl -180(%ebp)
- leal -136(%ebp), %edx
- movl $2, %eax
- call freebl_cpuid
- addl $12, %esp
-.L34:
- cmpl %edi, %esi
- jl .L49
-.L48:
- movl -140(%ebp), %eax
-.L41:
- testl %eax, %eax
- jne .L44
- movb $32, %al
-.L44:
- leal -12(%ebp), %esp
- popl %ebx
- popl %esi
- movl %eax, %edx
- movl %edx, %eax
- popl %edi
- leave
- ret
-.L29:
- leal -148(%ebp), %eax
- movl %eax, -192(%ebp)
- movl $0, -172(%ebp)
- leal -152(%ebp), %edi
- pushl %eax
- pushl %edi
- leal -156(%ebp), %esi
- pushl %esi
- leal -160(%ebp), %edx
- movl $-2147483648, %eax
- call freebl_cpuid
- addl $12, %esp
- cmpl $-2147483644, -160(%ebp)
- ja .L51
-.L42:
- movl -172(%ebp), %eax
- jmp .L41
-.L51:
- pushl -192(%ebp)
- pushl %edi
- pushl %esi
- leal -160(%ebp), %edx
- movl $-2147483643, %eax
- call freebl_cpuid
- movzbl -152(%ebp), %edx
- addl $12, %esp
- movl %edx, -172(%ebp)
- jmp .L42
- .size s_mpi_getProcessorLineSize, .-s_mpi_getProcessorLineSize
diff --git a/security/nss/lib/freebl/mpi/mpi-config.h b/security/nss/lib/freebl/mpi/mpi-config.h
deleted file mode 100644
index f6e21467e..000000000
--- a/security/nss/lib/freebl/mpi/mpi-config.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Default configuration for MPI library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef MPI_CONFIG_H_
-#define MPI_CONFIG_H_
-
-/*
- For boolean options,
- 0 = no
- 1 = yes
-
- Other options are documented individually.
-
- */
-
-#ifndef MP_IOFUNC
-#define MP_IOFUNC 0 /* include mp_print() ? */
-#endif
-
-#ifndef MP_MODARITH
-#define MP_MODARITH 1 /* include modular arithmetic ? */
-#endif
-
-#ifndef MP_NUMTH
-#define MP_NUMTH 1 /* include number theoretic functions? */
-#endif
-
-#ifndef MP_LOGTAB
-#define MP_LOGTAB 1 /* use table of logs instead of log()? */
-#endif
-
-#ifndef MP_MEMSET
-#define MP_MEMSET 1 /* use memset() to zero buffers? */
-#endif
-
-#ifndef MP_MEMCPY
-#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */
-#endif
-
-#ifndef MP_CRYPTO
-#define MP_CRYPTO 1 /* erase memory on free? */
-#endif
-
-#ifndef MP_ARGCHK
-/*
- 0 = no parameter checks
- 1 = runtime checks, continue execution and return an error to caller
- 2 = assertions; dump core on parameter errors
- */
-#ifdef DEBUG
-#define MP_ARGCHK 2 /* how to check input arguments */
-#else
-#define MP_ARGCHK 1 /* how to check input arguments */
-#endif
-#endif
-
-#ifndef MP_DEBUG
-#define MP_DEBUG 0 /* print diagnostic output? */
-#endif
-
-#ifndef MP_DEFPREC
-#define MP_DEFPREC 64 /* default precision, in digits */
-#endif
-
-#ifndef MP_MACRO
-#define MP_MACRO 1 /* use macros for frequent calls? */
-#endif
-
-#ifndef MP_SQUARE
-#define MP_SQUARE 1 /* use separate squaring code? */
-#endif
-
-#endif /* ifndef MPI_CONFIG_H_ */
-
-
diff --git a/security/nss/lib/freebl/mpi/mpi-priv.h b/security/nss/lib/freebl/mpi/mpi-priv.h
deleted file mode 100644
index 0e56fb4f0..000000000
--- a/security/nss/lib/freebl/mpi/mpi-priv.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * mpi-priv.h - Private header file for MPI
- * Arbitrary precision integer arithmetic library
- *
- * NOTE WELL: the content of this header file is NOT part of the "public"
- * API for the MPI library, and may change at any time.
- * Application programs that use libmpi should NOT include this header file.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#ifndef _MPI_PRIV_H_
-#define _MPI_PRIV_H_ 1
-
-#include "mpi.h"
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#if MP_DEBUG
-#include <stdio.h>
-
-#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
-#else
-#define DIAG(T,V)
-#endif
-
-/* If we aren't using a wired-in logarithm table, we need to include
- the math library to get the log() function
- */
-
-/* {{{ s_logv_2[] - log table for 2 in various bases */
-
-#if MP_LOGTAB
-/*
- A table of the logs of 2 for various bases (the 0 and 1 entries of
- this table are meaningless and should not be referenced).
-
- This table is used to compute output lengths for the mp_toradix()
- function. Since a number n in radix r takes up about log_r(n)
- digits, we estimate the output size by taking the least integer
- greater than log_r(n), where:
-
- log_r(n) = log_2(n) * log_r(2)
-
- This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
- which are the output bases supported.
- */
-
-extern const float s_logv_2[];
-#define LOG_V_2(R) s_logv_2[(R)]
-
-#else
-
-/*
- If MP_LOGTAB is not defined, use the math library to compute the
- logarithms on the fly. Otherwise, use the table.
- Pick which works best for your system.
- */
-
-#include <math.h>
-#define LOG_V_2(R) (log(2.0)/log(R))
-
-#endif /* if MP_LOGTAB */
-
-/* }}} */
-
-/* {{{ Digit arithmetic macros */
-
-/*
- When adding and multiplying digits, the results can be larger than
- can be contained in an mp_digit. Thus, an mp_word is used. These
- macros mask off the upper and lower digits of the mp_word (the
- mp_word may be more than 2 mp_digits wide, but we only concern
- ourselves with the low-order 2 mp_digits)
- */
-
-#define CARRYOUT(W) (mp_digit)((W)>>DIGIT_BIT)
-#define ACCUM(W) (mp_digit)(W)
-
-#define MP_MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MP_MAX(a,b) (((a) > (b)) ? (a) : (b))
-#define MP_HOWMANY(a,b) (((a) + (b) - 1)/(b))
-#define MP_ROUNDUP(a,b) (MP_HOWMANY(a,b) * (b))
-
-/* }}} */
-
-/* {{{ Comparison constants */
-
-#define MP_LT -1
-#define MP_EQ 0
-#define MP_GT 1
-
-/* }}} */
-
-/* {{{ private function declarations */
-
-/*
- If MP_MACRO is false, these will be defined as actual functions;
- otherwise, suitable macro definitions will be used. This works
- around the fact that ANSI C89 doesn't support an 'inline' keyword
- (although I hear C9x will ... about bloody time). At present, the
- macro definitions are identical to the function bodies, but they'll
- expand in place, instead of generating a function call.
-
- I chose these particular functions to be made into macros because
- some profiling showed they are called a lot on a typical workload,
- and yet they are primarily housekeeping.
- */
-#if MP_MACRO == 0
- void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */
- void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count); /* copy */
- void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */
- void s_mp_free(void *ptr); /* general free function */
-extern unsigned long mp_allocs;
-extern unsigned long mp_frees;
-extern unsigned long mp_copies;
-#else
-
- /* Even if these are defined as macros, we need to respect the settings
- of the MP_MEMSET and MP_MEMCPY configuration options...
- */
- #if MP_MEMSET == 0
- #define s_mp_setz(dp, count) \
- {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;}
- #else
- #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit))
- #endif /* MP_MEMSET */
-
- #if MP_MEMCPY == 0
- #define s_mp_copy(sp, dp, count) \
- {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];}
- #else
- #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit))
- #endif /* MP_MEMCPY */
-
- #define s_mp_alloc(nb, ni) calloc(nb, ni)
- #define s_mp_free(ptr) {if(ptr) free(ptr);}
-#endif /* MP_MACRO */
-
-mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */
-mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */
-
-#if MP_MACRO == 0
- void s_mp_clamp(mp_int *mp); /* clip leading zeroes */
-#else
- #define s_mp_clamp(mp)\
- { mp_size used = MP_USED(mp); \
- while (used > 1 && DIGIT(mp, used - 1) == 0) --used; \
- MP_USED(mp) = used; \
- }
-#endif /* MP_MACRO */
-
-void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */
-
-mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */
-void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */
-mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place */
-void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */
-void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */
-void s_mp_div_2(mp_int *mp); /* divide by 2 in place */
-mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */
-mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd);
- /* normalize for division */
-mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */
-mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */
-mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */
-mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r);
- /* unsigned digit divide */
-mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu);
- /* Barrett reduction */
-mp_err s_mp_add(mp_int *a, const mp_int *b); /* magnitude addition */
-mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c);
-mp_err s_mp_sub(mp_int *a, const mp_int *b); /* magnitude subtract */
-mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c);
-mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset);
- /* a += b * RADIX^offset */
-mp_err s_mp_mul(mp_int *a, const mp_int *b); /* magnitude multiply */
-#if MP_SQUARE
-mp_err s_mp_sqr(mp_int *a); /* magnitude square */
-#else
-#define s_mp_sqr(a) s_mp_mul(a, a)
-#endif
-mp_err s_mp_div(mp_int *rem, mp_int *div, mp_int *quot); /* magnitude div */
-mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
-mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */
-int s_mp_cmp(const mp_int *a, const mp_int *b); /* magnitude comparison */
-int s_mp_cmp_d(const mp_int *a, mp_digit d); /* magnitude digit compare */
-int s_mp_ispow2(const mp_int *v); /* is v a power of 2? */
-int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */
-
-int s_mp_tovalue(char ch, int r); /* convert ch to value */
-char s_mp_todigit(mp_digit val, int r, int low); /* convert val to digit */
-int s_mp_outlen(int bits, int r); /* output length in bytes */
-mp_digit s_mp_invmod_radix(mp_digit P); /* returns (P ** -1) mod RADIX */
-mp_err s_mp_invmod_odd_m( const mp_int *a, const mp_int *m, mp_int *c);
-mp_err s_mp_invmod_2d( const mp_int *a, mp_size k, mp_int *c);
-mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c);
-
-#ifdef NSS_USE_COMBA
-
-#define IS_POWER_OF_2(a) ((a) && !((a) & ((a)-1)))
-
-void s_mp_mul_comba_4(const mp_int *A, const mp_int *B, mp_int *C);
-void s_mp_mul_comba_8(const mp_int *A, const mp_int *B, mp_int *C);
-void s_mp_mul_comba_16(const mp_int *A, const mp_int *B, mp_int *C);
-void s_mp_mul_comba_32(const mp_int *A, const mp_int *B, mp_int *C);
-
-void s_mp_sqr_comba_4(const mp_int *A, mp_int *B);
-void s_mp_sqr_comba_8(const mp_int *A, mp_int *B);
-void s_mp_sqr_comba_16(const mp_int *A, mp_int *B);
-void s_mp_sqr_comba_32(const mp_int *A, mp_int *B);
-
-#endif /* end NSS_USE_COMBA */
-
-/* ------ mpv functions, operate on arrays of digits, not on mp_int's ------ */
-#if defined (__OS2__) && defined (__IBMC__)
-#define MPI_ASM_DECL __cdecl
-#else
-#define MPI_ASM_DECL
-#endif
-
-#ifdef MPI_AMD64
-
-mp_digit MPI_ASM_DECL s_mpv_mul_set_vec64(mp_digit*, mp_digit *, mp_size, mp_digit);
-mp_digit MPI_ASM_DECL s_mpv_mul_add_vec64(mp_digit*, const mp_digit*, mp_size, mp_digit);
-
-/* c = a * b */
-#define s_mpv_mul_d(a, a_len, b, c) \
- ((mp_digit *)c)[a_len] = s_mpv_mul_set_vec64(c, a, a_len, b)
-
-/* c += a * b */
-#define s_mpv_mul_d_add(a, a_len, b, c) \
- ((mp_digit *)c)[a_len] = s_mpv_mul_add_vec64(c, a, a_len, b)
-
-
-#else
-
-void MPI_ASM_DECL s_mpv_mul_d(const mp_digit *a, mp_size a_len,
- mp_digit b, mp_digit *c);
-void MPI_ASM_DECL s_mpv_mul_d_add(const mp_digit *a, mp_size a_len,
- mp_digit b, mp_digit *c);
-
-#endif
-
-void MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a,
- mp_size a_len, mp_digit b,
- mp_digit *c);
-void MPI_ASM_DECL s_mpv_sqr_add_prop(const mp_digit *a,
- mp_size a_len,
- mp_digit *sqrs);
-
-mp_err MPI_ASM_DECL s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo,
- mp_digit divisor, mp_digit *quot, mp_digit *rem);
-
-/* c += a * b * (MP_RADIX ** offset); */
-#define s_mp_mul_d_add_offset(a, b, c, off) \
-(s_mpv_mul_d_add_prop(MP_DIGITS(a), MP_USED(a), b, MP_DIGITS(c) + off), MP_OKAY)
-
-typedef struct {
- mp_int N; /* modulus N */
- mp_digit n0prime; /* n0' = - (n0 ** -1) mod MP_RADIX */
-} mp_mont_modulus;
-
-mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
- mp_mont_modulus *mmm);
-mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm);
-
-/*
- * s_mpi_getProcessorLineSize() returns the size in bytes of the cache line
- * if a cache exists, or zero if there is no cache. If more than one
- * cache line exists, it should return the smallest line size (which is
- * usually the L1 cache).
- *
- * mp_modexp uses this information to make sure that private key information
- * isn't being leaked through the cache.
- *
- * see mpcpucache.c for the implementation.
- */
-unsigned long s_mpi_getProcessorLineSize();
-
-/* }}} */
-#endif
-
diff --git a/security/nss/lib/freebl/mpi/mpi-test.c b/security/nss/lib/freebl/mpi/mpi-test.c
deleted file mode 100644
index 78d229e39..000000000
--- a/security/nss/lib/freebl/mpi/mpi-test.c
+++ /dev/null
@@ -1,1953 +0,0 @@
-/*
- * mpi-test.c
- *
- * This is a general test suite for the MPI library, which tests
- * all the functions in the library with known values. The program
- * exits with a zero (successful) status if the tests pass, or a
- * nonzero status if the tests fail.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <time.h>
-
-#include "mpi.h"
-#include "mpprime.h"
-
-#include "test-info.c"
-
-/* ZS means Zero Suppressed (no leading zeros) */
-#if MP_USE_LONG_DIGIT
-#define ZS_DIGIT_FMT "%lX"
-#elif MP_USE_LONG_LONG_DIGIT
-#define ZS_DIGIT_FMT "%llX"
-#elif MP_USE_UINT_DIGIT
-#define ZS_DIGIT_FMT "%X"
-#else
-#error "unknown type of digit"
-#endif
-
-/*
- Test vectors
-
- If you intend to change any of these values, you must also recompute
- the corresponding solutions below. Basically, these are just hex
- strings (for the big integers) or integer values (for the digits).
-
- The comparison tests think they know what relationships hold between
- these values. If you change that, you may have to adjust the code
- for the comparison tests accordingly. Most of the other tests
- should be fine as long as you re-compute the solutions, though.
- */
-const char *mp1 = "639A868CDA0C569861B";
-const char *mp2 = "AAFC0A3FE45E5E09DBE2C29";
-const char *mp3 = "B55AA8DF8A7E83241F38AC7A9E479CAEF2E4D7C5";
-const char *mp4 = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
-const char *mp5 = "F595CB42";
-const char *mp5a = "-4B597E";
-const char *mp6 = "0";
-const char *mp7 = "EBFA7121CD838CE6439CC59DDB4CBEF3";
-const char *mp8 = "5";
-const char *mp9 = "F74A2876A1432698923B0767DA19DCF3D71795EE";
-const char *mp10 = "9184E72A000";
-const char *mp11 = "54D79A3557E8";
-const char *mp12 = "10000000000000000";
-const char *mp13 =
-"34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342BDAB6163963C"
-"D5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45F2B050D226E6DA88";
-const char *mp14 =
-"AC3FA0EABAAC45724814D798942A1E28E14C81E0DE8055CED630E7689DA648683645DB6E"
-"458D9F5338CC3D4E33A5D1C9BF42780133599E60DEE0049AFA8F9489501AE5C9AA2B8C13"
-"FD21285A538B2CA87A626BB56E0A654C8707535E637FF4E39174157402BDE3AA30C9F134"
-"0C1307BAA864B075A9CC828B6A5E2B2BF1AE406D920CC5E7657D7C0E697DEE5375773AF9"
-"E200A1B8FAD7CD141F9EE47ABB55511FEB9A4D99EBA22F3A3FF6792FA7EE9E5DC0EE94F7"
-"7A631EDF3D7DD7C2DAAAFDF234D60302AB63D5234CEAE941B9AF0ADDD9E6E3A940A94EE5"
-"5DB45A7C66E61EDD0477419BBEFA44C325129601C4F45671C6A0E64665DF341D17FBC71F"
-"77418BD9F4375DDB3B9D56126526D8E5E0F35A121FD4F347013DA880020A752324F31DDD"
-"9BCDB13A3B86E207A2DE086825E6EEB87B3A64232CFD8205B799BC018634AAE193F19531"
-"D6EBC19A75F27CFFAA03EB5974898F53FD569AA5CE60F431B53B0CDE715A5F382405C9C4"
-"761A8E24888328F09F7BCE4E8D80C957DF177629C8421ACCD0C268C63C0DD47C3C0D954F"
-"D79F7D7297C6788DF4B3E51381759864D880ACA246DF09533739B8BB6085EAF7AE8DC2D9"
-"F224E6874926C8D24D34B457FD2C9A586C6B99582DC24F787A39E3942786CF1D494B6EB4"
-"A513498CDA0B217C4E80BCE7DA1C704C35E071AC21E0DA9F57C27C3533F46A8D20B04137"
-"C1B1384BE4B2EB46";
-const char *mp15 =
-"39849CF7FD65AF2E3C4D87FE5526221103D90BA26A6642FFE3C3ECC0887BBBC57E011BF1"
-"05D822A841653509C68F79EBE51C0099B8CBB04DEF31F36F5954208A3209AC122F0E11D8"
-"4AE67A494D78336A2066D394D42E27EF6B03DDAF6D69F5112C93E714D27C94F82FC7EF77"
-"445768C68EAE1C4A1407BE1B303243391D325090449764AE469CC53EC8012C4C02A72F37"
-"07ED7275D2CC8D0A14B5BCC6BF264941520EBA97E3E6BAE4EE8BC87EE0DDA1F5611A6ECB"
-"65F8AEF4F184E10CADBDFA5A2FEF828901D18C20785E5CC63473D638762DA80625003711"
-"9E984AC43E707915B133543AF9D5522C3E7180DC58E1E5381C1FB7DC6A5F4198F3E88FA6"
-"CBB6DFA8B2D1C763226B253E18BCCB79A29EE82D2DE735078C8AE3C3C86D476AAA08434C"
-"09C274BDD40A1D8FDE38D6536C22F44E807EB73DE4FB36C9F51E0BC835DDBE3A8EFCF2FE"
-"672B525769DC39230EE624D5EEDBD837C82A52E153F37378C3AD68A81A7ADBDF3345DBCE"
-"8FA18CA1DE618EF94DF72EAD928D4F45B9E51632ACF158CF8332C51891D1D12C2A7E6684"
-"360C4BF177C952579A9F442CFFEC8DAE4821A8E7A31C4861D8464CA9116C60866C5E72F7"
-"434ADBED36D54ACDFDFF70A4EFB46E285131FE725F1C637D1C62115EDAD01C4189716327"
-"BFAA79618B1656CBFA22C2C965687D0381CC2FE0245913C4D8D96108213680BD8E93E821"
-"822AD9DDBFE4BD04";
-const char *mp16 = "4A724340668DB150339A70";
-const char *mp17 = "8ADB90F58";
-const char *mp18 = "C64C230AB20E5";
-const char *mp19 =
-"F1C9DACDA287F2E3C88DCE2393B8F53DAAAC1196DC36510962B6B59454CFE64B";
-const char *mp20 =
-"D445662C8B6FE394107B867797750C326E0F4A967E135FC430F6CD7207913AC7";
-const char* mp21 = "2";
-
-const mp_digit md1 = 0;
-const mp_digit md2 = 0x1;
-const mp_digit md3 = 0x80;
-const mp_digit md4 = 0x9C97;
-const mp_digit md5 = 0xF5BF;
-const mp_digit md6 = 0x14A0;
-const mp_digit md7 = 0x03E8;
-const mp_digit md8 = 0x0101;
-const mp_digit md9 = 0xA;
-
-/*
- Solutions of the form x_mpABC, where:
-
- x = (p)roduct, (s)um, (d)ifference, (q)uotient, (r)emainder, (g)cd,
- (i)nverse, (e)xponent, square roo(t), (g)cd, (l)cm. A
- leading 'm' indicates a modular operation, e.g. ms_mp12 is the
- modular sum of operands 1 and 2
-
- ABC are the operand numbers involved in the computation. If a 'd'
- precedes the number, it is a digit operand; if a 'c' precedes it,
- it is a constant; otherwise, it is a full integer.
- */
-
-const char *p_mp12 = "4286AD72E095C9FE009938750743174ADDD7FD1E53";
-const char *p_mp34 = "-46BDBD66CA108C94A8CF46C325F7B6E2F2BA82D35"
- "A1BFD6934C441EE369B60CA29BADC26845E918B";
-const char *p_mp57 = "E260C265A0A27C17AD5F4E59D6E0360217A2EBA6";
-const char *p_mp22 = "7233B5C1097FFC77CCF55928FDC3A5D31B712FDE7A1E91";
-const char *p_mp1d4 = "3CECEA2331F4220BEF68DED";
-const char *p_mp8d6 = "6720";
-const char *p_mp1113 =
-"11590FC3831C8C3C51813142C88E566408DB04F9E27642F6471A1822E0100B12F7F1"
-"5699A127C0FA9D26DCBFF458522661F30C6ADA4A07C8C90F9116893F6DBFBF24C3A2"
-"4340";
-const char *p_mp1415 =
-"26B36540DE8B3586699CCEAE218A2842C7D5A01590E70C4A26E789107FBCDB06AA2C"
-"6DDC39E6FA18B16FCB2E934C9A5F844DAD60EE3B1EA82199EC5E9608F67F860FB965"
-"736055DF0E8F2540EB28D07F47E309B5F5D7C94FF190AB9C83A6970160CA700B1081"
-"F60518132AF28C6CEE6B7C473E461ABAC52C39CED50A08DD4E7EA8BA18DAD545126D"
-"A388F6983C29B6BE3F9DCBC15766E8E6D626A92C5296A9C4653CAE5788350C0E2107"
-"F57E5E8B6994C4847D727FF1A63A66A6CEF42B9C9E6BD04C92550B85D5527DE8A132"
-"E6BE89341A9285C7CE7FB929D871BBCBD0ED2863B6B078B0DBB30FCA66D6C64284D6"
-"57F394A0271E15B6EC7A9D530EBAC6CA262EF6F97E1A29FCE7749240E4AECA591ECF"
-"272122BC587370F9371B67BB696B3CDC1BC8C5B64B6280994EBA00CDEB8EB0F5D06E"
-"18F401D65FDCECF23DD7B9BB5B4C5458AEF2CCC09BA7F70EACB844750ACFD027521E"
-"2E047DE8388B35F8512D3DA46FF1A12D4260213602BF7BFFDB6059439B1BD0676449"
-"8D98C74F48FB3F548948D5BA0C8ECFCD054465132DC43466D6BBD59FBAF8D6D4E157"
-"2D612B40A956C7D3E140F3B8562EF18568B24D335707D5BAC7495014DF2444172426"
-"FD099DED560D30D1F945386604AFC85C64BD1E5F531F5C7840475FC0CF0F79810012"
-"4572BAF5A9910CDBD02B27FFCC3C7E5E88EF59F3AE152476E33EDA696A4F751E0AE4"
-"A3D2792DEA78E25B9110E12A19EFD09EA47FF9D6594DA445478BEB6901EAF8A35B2D"
-"FD59BEE9BF7AA8535B7D326EFA5AA2121B5EBE04DD85827A3D43BD04F4AA6D7B62A2"
-"B6D7A3077286A511A431E1EF75FCEBA3FAE9D5843A8ED17AA02BBB1B571F904699C5"
-"A6073F87DDD012E2322AB3F41F2A61F428636FE86914148E19B8EF8314ED83332F2F"
-"8C2ADE95071E792C0A68B903E060DD322A75FD0C2B992059FCCBB58AFA06B50D1634"
-"BBD93F187FCE0566609FCC2BABB269C66CEB097598AA17957BB4FDA3E64A1B30402E"
-"851CF9208E33D52E459A92C63FBB66435BB018E155E2C7F055E0B7AB82CD58FC4889"
-"372ED9EEAC2A07E8E654AB445B9298D2830D6D4DFD117B9C8ABE3968927DC24B3633"
-"BAD6E6466DB45DDAE87A0AB00336AC2CCCE176704F7214FCAB55743AB76C2B6CA231"
-"7984610B27B5786DE55C184DDF556EDFEA79A3652831940DAD941E243F482DC17E50"
-"284BC2FB1AD712A92542C573E55678878F02DFD9E3A863C7DF863227AEDE14B47AD3"
-"957190124820ADC19F5353878EDB6BF7D0C77352A6E3BDB53EEB88F5AEF6226D6E68"
-"756776A8FB49B77564147A641664C2A54F7E5B680CCC6A4D22D894E464DF20537094"
-"548F1732452F9E7F810C0B4B430C073C0FBCE03F0D03F82630654BCE166AA772E1EE"
-"DD0C08D3E3EBDF0AF54203B43AFDFC40D8FC79C97A4B0A4E1BEB14D8FCEFDDED8758"
-"6ED65B18";
-const char *p_mp2121 = "4";
-const char *mp_mp345 = "B9B6D3A3";
-const char *mp_mp335 = "16609C2D";
-
-const char *s_mp13 = "B55AA8DF8A7E83241F38B2B446B06A4FB84E5DE0";
-const char *s_mp34 = "517EE6B92EF65C965736EB6BF7C325F73504CEB6";
-const char *s_mp46 = "-63DBC2265B88268DC801C10EA68476B7BDE0090F";
-const char *s_mp5d4 = "F59667D9";
-const char *s_mp2d5 = "AAFC0A3FE45E5E09DBF21E8";
-const char *s_mp1415 =
-"E5C43DE2B811F4A084625F96E9504039E5258D8348E698CEB9F4D4292622042DB446"
-"F75F4B65C1FB7A317257FA354BB5A45E789AEC254EAECE11F80A53E3B513822491DB"
-"D9399DEC4807A2A3A10360129AC93F4A42388D3BF20B310DD0E9E9F4BE07FC88D53A"
-"78A26091E0AB506A70813712CCBFBDD440A69A906E650EE090FDD6A42A95AC1A414D"
-"317F1A9F781E6A30E9EE142ECDA45A1E3454A1417A7B9A613DA90831CF88EA1F2E82"
-"41AE88CC4053220903C2E05BCDD42F02B8CF8868F84C64C5858BAD356143C5494607"
-"EE22E11650148BAF65A985F6FC4CA540A55697F2B5AA95D6B8CF96EF638416DE1DD6"
-"3BA9E2C09E22D03E75B60BE456C642F86B82A709253E5E087B507DE3A45F8392423F"
-"4DBC284E8DC88C43CA77BC8DCEFB6129A59025F80F90FF978116DEBB9209E306FBB9"
-"1B6111F8B8CFACB7C7C9BC12691C22EE88303E1713F1DFCEB622B8EA102F6365678B"
-"C580ED87225467AA78E875868BD53B17574BA59305BC1AC666E4B7E9ED72FCFC200E"
-"189D98FC8C5C7533739C53F52DDECDDFA5A8668BFBD40DABC9640F8FCAE58F532940"
-"8162261320A25589E9FB51B50F80056471F24B7E1AEC35D1356FC2747FFC13A04B34"
-"24FCECE10880BD9D97CA8CDEB2F5969BF4F30256EB5ED2BCD1DC64BDC2EE65217848"
-"48A37FB13F84ED4FB7ACA18C4639EE64309BDD3D552AEB4AAF44295943DC1229A497"
-"A84A";
-
-const char *ms_mp345 = "1E71E292";
-
-const char *d_mp12 = "-AAFBA6A55DD183FD854A60E";
-const char *d_mp34 = "119366B05E606A9B1E73A6D8944CC1366B0C4E0D4";
-const char *d_mp5d4 = "F5952EAB";
-const char *d_mp6d2 = "-1";
-const char *md_mp345 = "26596B86";
-
-const char *q_mp42 = "-95825A1FFA1A155D5";
-const char *r_mp42 = "-6312E99D7700A3DCB32ADF2";
-const char *q_mp45a = "15344CDA3D841F661D2B61B6EDF7828CE36";
-const char *r_mp45a = "-47C47B";
-const char *q_mp7c2 = "75FD3890E6C1C67321CE62CEEDA65F79";
-const char *q_mp3d6 = "8CAFD53C272BD6FE8B0847BDC3B539EFAB5C3";
-const char *r_mp3d6 = "1E5";
-const char *r_mp5d5 = "1257";
-const char *r_mp47 = "B3A9018D970281A90FB729A181D95CB8";
-const char *q_mp1404 =
-"-1B994D869142D3EF6123A3CBBC3C0114FA071CFCEEF4B7D231D65591D32501AD80F"
-"FF49AE4EC80514CC071EF6B42521C2508F4CB2FEAD69A2D2EF3934087DCAF88CC4C4"
-"659F1CA8A7F4D36817D802F778F1392337FE36302D6865BF0D4645625DF8BB044E19"
-"930635BE2609FAC8D99357D3A9F81F2578DE15A300964188292107DAC980E0A08CD7"
-"E938A2135FAD45D50CB1D8C2D4C4E60C27AB98B9FBD7E4DBF752C57D2674520E4BB2"
-"7E42324C0EFE84FB3E38CF6950E699E86FD45FE40D428400F2F94EDF7E94FAE10B45"
-"89329E1BF61E5A378C7B31C9C6A234F8254D4C24823B84D0BF8D671D8BC9154DFAC9"
-"49BD8ACABD6BD32DD4DC587F22C86153CB3954BDF7C2A890D623642492C482CF3E2C"
-"776FC019C3BBC61688B485E6FD35D6376089C1E33F880E84C4E51E8ABEACE1B3FB70"
-"3EAD0E28D2D44E7F1C0A859C840775E94F8C1369D985A3C5E8114B21D68B3CBB75D2"
-"791C586153C85B90CAA483E57A40E2D97950AAB84920A4396C950C87C7FFFE748358"
-"42A0BF65445B26D40F05BE164B822CA96321F41D85A289C5F5CD5F438A78704C9683"
-"422299D21899A22F853B0C93081CC9925E350132A0717A611DD932A68A0ACC6E4C7F"
-"7F685EF8C1F4910AEA5DC00BB5A36FCA07FFEAA490C547F6E14A08FE87041AB803E1"
-"BD9E23E4D367A2C35762F209073DFF48F3";
-const char *r_mp1404 = "12FF98621ABF63144BFFC3207AC8FC10D8D1A09";
-
-const char *q_mp13c =
- "34584F700C15A341E40BF7BFDD88A6630C8FF2B2067469372D391342"
- "BDAB6163963CD5A5C79F708BDE26E0CCF2DB66CD6D6089E29A877C45";
-const char *r_mp13c = "F2B050D226E6DA88";
-const char *q_mp9c16 = "F74A2876A1432698923B0767DA19DCF3D71795E";
-const char *r_mp9c16 = "E";
-
-const char *e_mp5d9 = "A8FD7145E727A20E52E73D22990D35D158090307A"
- "13A5215AAC4E9AB1E96BD34E531209E03310400";
-const char *e_mp78 = "AA5F72C737DFFD8CCD108008BFE7C79ADC01A819B"
- "32B75FB82EC0FB8CA83311DA36D4063F1E57857A2"
- "1AB226563D84A15BB63CE975FF1453BD6750C58D9"
- "D113175764F5D0B3C89B262D4702F4D9640A3";
-const char *me_mp817 = "E504493ACB02F7F802B327AB13BF25";
-const char *me_mp5d47 = "1D45ED0D78F2778157992C951DD2734C";
-const char *me_mp1512 = "FB5B2A28D902B9D9";
-const char *me_mp161718 = "423C6AC6DBD74";
-const char *me_mp5114 =
-"64F0F72807993578BBA3C7C36FFB184028F9EB9A810C92079E1498D8A80FC848E1F0"
-"25F1DE43B7F6AC063F5CC29D8A7C2D7A66269D72BF5CDC327AF88AF8EF9E601DCB0A"
-"3F35BFF3525FB1B61CE3A25182F17C0A0633B4089EA15BDC47664A43FEF639748AAC"
-"19CF58E83D8FA32CD10661D2D4210CC84792937E6F36CB601851356622E63ADD4BD5"
-"542412C2E0C4958E51FD2524AABDC7D60CFB5DB332EEC9DC84210F10FAE0BA2018F2"
-"14C9D6867C9D6E49CF28C18D06CE009FD4D04BFC8837C3FAAA773F5CCF6DED1C22DE"
-"181786AFE188540586F2D74BF312E595244E6936AE52E45742109BAA76C36F2692F5"
-"CEF97AD462B138BE92721194B163254CBAAEE9B9864B21CCDD5375BCAD0D24132724"
-"113D3374B4BCF9AA49BA5ACBC12288C0BCF46DCE6CB4A241A91BD559B130B6E9CD3D"
-"D7A2C8B280C2A278BA9BF5D93244D563015C9484B86D9FEB602501DC16EEBC3EFF19"
-"53D7999682BF1A1E3B2E7B21F4BDCA3C355039FEF55B9C0885F98DC355CA7A6D8ECF"
-"5F7F1A6E11A764F2343C823B879B44616B56BF6AE3FA2ACF5483660E618882018E3F"
-"C8459313BACFE1F93CECC37B2576A5C0B2714BD3EEDEEC22F0E7E3E77B11396B9B99"
-"D683F2447A4004BBD4A57F6A616CDDFEC595C4FC19884CC2FC21CF5BF5B0B81E0F83"
-"B9DDA0CF4DFF35BB8D31245912BF4497FD0BD95F0C604E26EA5A8EA4F5EAE870A5BD"
-"FE8C";
-
-const char *e_mpc2d3 = "100000000000000000000000000000000";
-
-const char *t_mp9 = "FB9B6E32FF0452A34746";
-const char *i_mp27 = "B6AD8DCCDAF92B6FE57D062FFEE3A99";
-const char *i_mp2019 =
-"BDF3D88DC373A63EED92903115B03FC8501910AF68297B4C41870AED3EA9F839";
-/* "15E3FE09E8AE5523AABA197BD2D16318D3CA148EDF4AE1C1C52FC96AFAF5680B"; */
-
-
-const char *t_mp15 =
-"795853094E59B0008093BCA8DECF68587C64BDCA2F3F7F8963DABC12F1CFFFA9B8C4"
-"365232FD4751870A0EF6CA619287C5D8B7F1747D95076AB19645EF309773E9EACEA0"
-"975FA4AE16251A8DA5865349C3A903E3B8A2C0DEA3C0720B6020C7FED69AFF62BB72"
-"10FAC443F9FFA2950776F949E819260C2AF8D94E8A1431A40F8C23C1973DE5D49AA2"
-"0B3FF5DA5C1D5324E712A78FF33A9B1748F83FA529905924A31DF38643B3F693EF9B"
-"58D846BB1AEAE4523ECC843FF551C1B300A130B65C1677402778F98C51C10813250E"
-"2496882877B069E877B59740DC1226F18A5C0F66F64A5F59A9FAFC5E9FC45AEC0E7A"
-"BEE244F7DD3AC268CF512A0E52E4F5BE5B94";
-
-const char *g_mp71 = "1";
-const char *g_mp25 = "7";
-const char *l_mp1011 = "C589E3D7D64A6942A000";
-
-/* mp9 in radices from 5 to 64 inclusive */
-#define LOW_RADIX 5
-#define HIGH_RADIX 64
-const char *v_mp9[] = {
- "404041130042310320100141302000203430214122130002340212132414134210033",
- "44515230120451152500101352430105520150025145320010504454125502",
- "644641136612541136016610100564613624243140151310023515322",
- "173512120732412062323044435407317550316717172705712756",
- "265785018434285762514442046172754680368422060744852",
- "1411774500397290569709059837552310354075408897518",
- "184064268501499311A17746095910428222A241708032A",
- "47706011B225950B02BB45602AA039893118A85950892",
- "1A188C826B982353CB58422563AC602B783101671A86",
- "105957B358B89B018958908A9114BC3DDC410B77982",
- "CB7B3387E23452178846C55DD9D70C7CA9AEA78E8",
- "F74A2876A1432698923B0767DA19DCF3D71795EE",
- "17BF7C3673B76D7G7A5GA836277296F806E7453A",
- "2EBG8HH3HFA6185D6H0596AH96G24C966DD3HG2",
- "6G3HGBFEG8I3F25EAF61B904EIA40CFDH2124F",
- "10AHC3D29EBHDF3HD97905CG0JA8061855C3FI",
- "3BA5A55J5K699B2D09C38A4B237CH51IHA132",
- "EDEA90DJ0B5CB3FGG1C8587FEB99D3C143CA",
- "31M26JI1BBD56K3I028MML4EEDMAJK60LGLE",
- "GGG5M3142FKKG82EJ28111D70EMHC241E4E",
- "4446F4D5H10982023N297BF0DKBBHLLJB0I",
- "12E9DEEOBMKAKEP0IM284MIP7FO1O521M46",
- "85NN0HD48NN2FDDB1F5BMMKIB8CK20MDPK",
- "2D882A7A0O0JPCJ4APDRIB77IABAKDGJP2",
- "MFMCI0R7S27AAA3O3L2S8K44HKA7O02CN",
- "7IGQS73FFSHC50NNH44B6PTTNLC3M6H78",
- "2KLUB3U9850CSN6ANIDNIF1LB29MJ43LH",
- "UT52GTL18CJ9H4HR0TJTK6ESUFBHF5FE",
- "BTVL87QQBMUGF8PFWU4W3VU7U922QTMW",
- "4OG10HW0MSWJBIDEE2PDH24GA7RIHIAA",
- "1W8W9AX2DRUX48GXOLMK0PE42H0FEUWN",
- "SVWI84VBH069WR15W1U2VTK06USY8Z2",
- "CPTPNPDa5TYCPPNLALENT9IMX2GL0W2",
- "5QU21UJMRaUYYYYYN6GHSMPOYOXEEUY",
- "2O2Q7C6RPPB1SXJ9bR4035SPaQQ3H2W",
- "18d994IbT4PHbD7cGIPCRP00bbQO0bc",
- "NcDUEEWRO7XT76260WGeBHPVa72RdA",
- "BbX2WCF9VfSB5LPdJAdeXKV1fd6LC2",
- "60QDKW67P4JSQaTdQg7JE9ISafLaVU",
- "33ba9XbDbRdNF4BeDB2XYMhAVDaBdA",
- "1RIPZJA8gT5L5H7fTcaRhQ39geMMTc",
- "d65j70fBATjcDiidPYXUGcaBVVLME",
- "LKA9jhPabDG612TXWkhfT2gMXNIP2",
- "BgNaYhjfT0G8PBcYRP8khJCR3C9QE",
- "6Wk8RhJTAgDh10fYAiUVB1aM0HacG",
- "3dOCjaf78kd5EQNViUZWj3AfFL90I",
- "290VWkL3aiJoW4MBbHk0Z0bDo22Ni",
- "1DbDZ1hpPZNUDBUp6UigcJllEdC26",
- "dFSOLBUM7UZX8Vnc6qokGIOiFo1h",
- "NcoUYJOg0HVmKI9fR2ag0S8R2hrK",
- "EOpiJ5Te7oDe2pn8ZhAUKkhFHlZh",
- "8nXK8rp8neV8LWta1WDgd1QnlWsU",
- "5T3d6bcSBtHgrH9bCbu84tblaa7r",
- "3PlUDIYUvMqOVCir7AtquK5dWanq",
- "2A70gDPX2AtiicvIGGk9poiMtgvu",
- "1MjiRxjk10J6SVAxFguv9kZiUnIc",
- "rpre2vIDeb4h3sp50r1YBbtEx9L",
- "ZHcoip0AglDAfibrsUcJ9M1C8fm",
- "NHP18+eoe6uU54W49Kc6ZK7+bT2",
- "FTAA7QXGoQOaZi7PzePtFFN5vNk"
-};
-
-const unsigned char b_mp4[] = {
- 0x01,
-#if MP_DIGIT_MAX > MP_32BIT_MAX
- 0x00, 0x00, 0x00, 0x00,
-#endif
- 0x63, 0xDB, 0xC2, 0x26,
- 0x5B, 0x88, 0x26, 0x8D,
- 0xC8, 0x01, 0xC1, 0x0E,
- 0xA6, 0x84, 0x76, 0xB7,
- 0xBD, 0xE0, 0x09, 0x0F
-};
-
-/* Search for a test suite name in the names table */
-int find_name(char *name);
-void reason(char *fmt, ...);
-
-/*------------------------------------------------------------------------*/
-/*------------------------------------------------------------------------*/
-
-char g_intbuf[4096]; /* buffer for integer comparison */
-char a_intbuf[4096]; /* buffer for integer comparison */
-int g_verbose = 1; /* print out reasons for failure? */
-int res;
-
-#define IFOK(x) { if (MP_OKAY > (res = (x))) { \
- reason("test %s failed: error %d\n", #x, res); return 1; }}
-
-int main(int argc, char *argv[])
-{
- int which, res;
-
- srand((unsigned int)time(NULL));
-
- if (argc < 2) {
- fprintf(stderr, "Usage: %s <test-suite> | list\n"
- "Type '%s help' for assistance\n", argv[0], argv[0]);
- return 2;
- } else if(argc > 2) {
- if(strcmp(argv[2], "quiet") == 0)
- g_verbose = 0;
- }
-
- if(strcmp(argv[1], "help") == 0) {
- fprintf(stderr, "Help for mpi-test\n\n"
- "This program is a test driver for the MPI library, which\n"
- "tests all the various functions in the library to make sure\n"
- "they are working correctly. The syntax is:\n"
- " %s <suite-name>\n"
- "...where <suite-name> is the name of the test you wish to\n"
- "run. To get a list of the tests, use '%s list'.\n\n"
- "The program exits with a status of zero if the test passes,\n"
- "or non-zero if it fails. Ordinarily, failure is accompanied\n"
- "by a diagnostic message to standard error. To suppress this\n"
- "add the keyword 'quiet' after the suite-name on the command\n"
- "line.\n\n", argv[0], argv[0]);
- return 0;
- }
-
- if ((which = find_name(argv[1])) < 0) {
- fprintf(stderr, "%s: test suite '%s' is not known\n", argv[0], argv[1]);
- return 2;
- }
-
- if((res = (g_tests[which])()) < 0) {
- fprintf(stderr, "%s: test suite not implemented yet\n", argv[0]);
- return 2;
- } else {
- return res;
- }
-
-}
-
-/*------------------------------------------------------------------------*/
-
-int find_name(char *name)
-{
- int ix = 0;
-
- while(ix < g_count) {
- if (strcmp(name, g_names[ix]) == 0)
- return ix;
-
- ++ix;
- }
-
- return -1;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_list(void)
-{
- int ix;
-
- fprintf(stderr, "There are currently %d test suites available\n",
- g_count);
-
- for(ix = 1; ix < g_count; ix++)
- fprintf(stdout, "%-20s %s\n", g_names[ix], g_descs[ix]);
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_copy(void)
-{
- mp_int a, b;
- int ix;
-
- mp_init(&a); mp_init(&b);
-
- mp_read_radix(&a, mp3, 16);
- mp_copy(&a, &b);
-
- if(SIGN(&a) != SIGN(&b) || USED(&a) != USED(&b)) {
- if(SIGN(&a) != SIGN(&b)) {
- reason("error: sign of original is %d, sign of copy is %d\n",
- SIGN(&a), SIGN(&b));
- } else {
- reason("error: original precision is %d, copy precision is %d\n",
- USED(&a), USED(&b));
- }
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- for(ix = 0; ix < USED(&b); ix++) {
- if(DIGIT(&a, ix) != DIGIT(&b, ix)) {
- reason("error: digit %d " DIGIT_FMT " != " DIGIT_FMT "\n",
- ix, DIGIT(&a, ix), DIGIT(&b, ix));
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
- }
-
- mp_clear(&a); mp_clear(&b);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_exch(void)
-{
- mp_int a, b;
-
- mp_init(&a); mp_init(&b);
- mp_read_radix(&a, mp7, 16); mp_read_radix(&b, mp1, 16);
-
- mp_exch(&a, &b);
- mp_toradix(&a, g_intbuf, 16);
-
- mp_clear(&a);
- if(strcmp(g_intbuf, mp1) != 0) {
- mp_clear(&b);
- reason("error: exchange failed\n");
- return 1;
- }
-
- mp_toradix(&b, g_intbuf, 16);
-
- mp_clear(&b);
- if(strcmp(g_intbuf, mp7) != 0) {
- reason("error: exchange failed\n");
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_zero(void)
-{
- mp_int a;
-
- mp_init(&a); mp_read_radix(&a, mp7, 16);
- mp_zero(&a);
-
- if(USED(&a) != 1 || DIGIT(&a, 1) != 0) {
- mp_toradix(&a, g_intbuf, 16);
- reason("error: result is %s\n", g_intbuf);
- mp_clear(&a);
- return 1;
- }
-
- mp_clear(&a);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_set(void)
-{
- mp_int a;
-
- /* Test single digit set */
- mp_init(&a); mp_set(&a, 5);
- if(DIGIT(&a, 0) != 5) {
- mp_toradix(&a, g_intbuf, 16);
- reason("error: result is %s, expected 5\n", g_intbuf);
- mp_clear(&a);
- return 1;
- }
-
- /* Test integer set */
- mp_set_int(&a, -4938110);
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a);
- if(strcmp(g_intbuf, mp5a) != 0) {
- reason("error: result is %s, expected %s\n", g_intbuf, mp5a);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_abs(void)
-{
- mp_int a;
-
- mp_init(&a); mp_read_radix(&a, mp4, 16);
- mp_abs(&a, &a);
-
- if(SIGN(&a) != ZPOS) {
- reason("error: sign of result is negative\n");
- mp_clear(&a);
- return 1;
- }
-
- mp_clear(&a);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_neg(void)
-{
- mp_int a;
- mp_sign s;
-
- mp_init(&a); mp_read_radix(&a, mp4, 16);
-
- s = SIGN(&a);
- mp_neg(&a, &a);
- if(SIGN(&a) == s) {
- reason("error: sign of result is same as sign of nonzero input\n");
- mp_clear(&a);
- return 1;
- }
-
- mp_clear(&a);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_add_d(void)
-{
- mp_int a;
-
- mp_init(&a);
-
- mp_read_radix(&a, mp5, 16);
- mp_add_d(&a, md4, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, s_mp5d4) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, s_mp5d4);
- mp_clear(&a);
- return 1;
- }
-
- mp_read_radix(&a, mp2, 16);
- mp_add_d(&a, md5, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, s_mp2d5) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, s_mp2d5);
- mp_clear(&a);
- return 1;
- }
-
- mp_clear(&a);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_add(void)
-{
- mp_int a, b;
- int res = 0;
-
- mp_init(&a); mp_init(&b);
-
- mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp3, 16);
- mp_add(&a, &b, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, s_mp13) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, s_mp13);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp4, 16);
- mp_add(&a, &b, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, s_mp34) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, s_mp34);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp4, 16); mp_read_radix(&b, mp6, 16);
- mp_add(&a, &b, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, s_mp46) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, s_mp46);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp14, 16); mp_read_radix(&b, mp15, 16);
- mp_add(&a, &b, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, s_mp1415) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, s_mp1415);
- res = 1;
- }
-
- CLEANUP:
- mp_clear(&a); mp_clear(&b);
- return res;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_sub_d(void)
-{
- mp_int a;
-
- mp_init(&a);
- mp_read_radix(&a, mp5, 16);
-
- mp_sub_d(&a, md4, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, d_mp5d4) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, d_mp5d4);
- mp_clear(&a);
- return 1;
- }
-
- mp_read_radix(&a, mp6, 16);
-
- mp_sub_d(&a, md2, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- mp_clear(&a);
- if(strcmp(g_intbuf, d_mp6d2) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, d_mp6d2);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_sub(void)
-{
- mp_int a, b;
-
- mp_init(&a); mp_init(&b);
-
- mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp2, 16);
- mp_sub(&a, &b, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, d_mp12) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, d_mp12);
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
- mp_sub(&a, &b, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, d_mp34) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, d_mp34);
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- mp_clear(&a); mp_clear(&b);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_mul_d(void)
-{
- mp_int a;
-
- mp_init(&a);
- mp_read_radix(&a, mp1, 16);
-
- IFOK( mp_mul_d(&a, md4, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, p_mp1d4) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, p_mp1d4);
- mp_clear(&a);
- return 1;
- }
-
- mp_read_radix(&a, mp8, 16);
- IFOK( mp_mul_d(&a, md6, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- mp_clear(&a);
- if(strcmp(g_intbuf, p_mp8d6) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, p_mp8d6);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_mul(void)
-{
- mp_int a, b;
- int res = 0;
-
- mp_init(&a); mp_init(&b);
- mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp2, 16);
-
- IFOK( mp_mul(&a, &b, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, p_mp12) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, p_mp12);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
- IFOK( mp_mul(&a, &b, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, p_mp34) !=0) {
- reason("error: computed %s, expected %s\n", g_intbuf, p_mp34);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp5, 16); mp_read_radix(&b, mp7, 16);
- IFOK( mp_mul(&a, &b, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, p_mp57) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, p_mp57);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp11, 16); mp_read_radix(&b, mp13, 16);
- IFOK( mp_mul(&a, &b, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, p_mp1113) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, p_mp1113);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp14, 16); mp_read_radix(&b, mp15, 16);
- IFOK( mp_mul(&a, &b, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, p_mp1415) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, p_mp1415);
- res = 1;
- }
- mp_read_radix(&a, mp21, 10); mp_read_radix(&b, mp21, 10);
-
- IFOK( mp_mul(&a, &b, &a) );
- mp_toradix(&a, g_intbuf, 10);
-
- if(strcmp(g_intbuf, p_mp2121) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, p_mp2121);
- res = 1; goto CLEANUP;
- }
-
- CLEANUP:
- mp_clear(&a); mp_clear(&b);
- return res;
-
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_sqr(void)
-{
- mp_int a;
-
- mp_init(&a); mp_read_radix(&a, mp2, 16);
-
- mp_sqr(&a, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- mp_clear(&a);
- if(strcmp(g_intbuf, p_mp22) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, p_mp22);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_div_d(void)
-{
- mp_int a, q;
- mp_digit r;
- int err = 0;
-
- mp_init(&a); mp_init(&q);
- mp_read_radix(&a, mp3, 16);
-
- IFOK( mp_div_d(&a, md6, &q, &r) );
- mp_toradix(&q, g_intbuf, 16);
-
- if(strcmp(g_intbuf, q_mp3d6) != 0) {
- reason("error: computed q = %s, expected %s\n", g_intbuf, q_mp3d6);
- ++err;
- }
-
- sprintf(g_intbuf, ZS_DIGIT_FMT, r);
-
- if(strcmp(g_intbuf, r_mp3d6) != 0) {
- reason("error: computed r = %s, expected %s\n", g_intbuf, r_mp3d6);
- ++err;
- }
-
- mp_read_radix(&a, mp9, 16);
- IFOK( mp_div_d(&a, 16, &q, &r) );
- mp_toradix(&q, g_intbuf, 16);
-
- if(strcmp(g_intbuf, q_mp9c16) != 0) {
- reason("error: computed q = %s, expected %s\n", g_intbuf, q_mp9c16);
- ++err;
- }
-
- sprintf(g_intbuf, ZS_DIGIT_FMT, r);
-
- if(strcmp(g_intbuf, r_mp9c16) != 0) {
- reason("error: computed r = %s, expected %s\n", g_intbuf, r_mp9c16);
- ++err;
- }
-
- mp_clear(&a); mp_clear(&q);
- return err;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_div_2(void)
-{
- mp_int a;
-
- mp_init(&a); mp_read_radix(&a, mp7, 16);
- IFOK( mp_div_2(&a, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- mp_clear(&a);
- if(strcmp(g_intbuf, q_mp7c2) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, q_mp7c2);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_div_2d(void)
-{
- mp_int a, q, r;
-
- mp_init(&q); mp_init(&r);
- mp_init(&a); mp_read_radix(&a, mp13, 16);
-
- IFOK( mp_div_2d(&a, 64, &q, &r) );
- mp_clear(&a);
-
- mp_toradix(&q, g_intbuf, 16);
-
- if(strcmp(g_intbuf, q_mp13c) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, q_mp13c);
- mp_clear(&q); mp_clear(&r);
- return 1;
- }
-
- mp_clear(&q);
-
- mp_toradix(&r, g_intbuf, 16);
- if(strcmp(g_intbuf, r_mp13c) != 0) {
- reason("error, computed %s, expected %s\n", g_intbuf, r_mp13c);
- mp_clear(&r);
- return 1;
- }
-
- mp_clear(&r);
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_div(void)
-{
- mp_int a, b, r;
- int err = 0;
-
- mp_init(&a); mp_init(&b); mp_init(&r);
-
- mp_read_radix(&a, mp4, 16); mp_read_radix(&b, mp2, 16);
- IFOK( mp_div(&a, &b, &a, &r) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, q_mp42) != 0) {
- reason("error: test 1 computed quot %s, expected %s\n", g_intbuf, q_mp42);
- ++err;
- }
-
- mp_toradix(&r, g_intbuf, 16);
-
- if(strcmp(g_intbuf, r_mp42) != 0) {
- reason("error: test 1 computed rem %s, expected %s\n", g_intbuf, r_mp42);
- ++err;
- }
-
- mp_read_radix(&a, mp4, 16); mp_read_radix(&b, mp5a, 16);
- IFOK( mp_div(&a, &b, &a, &r) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, q_mp45a) != 0) {
- reason("error: test 2 computed quot %s, expected %s\n", g_intbuf, q_mp45a);
- ++err;
- }
-
- mp_toradix(&r, g_intbuf, 16);
-
- if(strcmp(g_intbuf, r_mp45a) != 0) {
- reason("error: test 2 computed rem %s, expected %s\n", g_intbuf, r_mp45a);
- ++err;
- }
-
- mp_read_radix(&a, mp14, 16); mp_read_radix(&b, mp4, 16);
- IFOK( mp_div(&a, &b, &a, &r) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, q_mp1404) != 0) {
- reason("error: test 3 computed quot %s, expected %s\n", g_intbuf, q_mp1404);
- ++err;
- }
-
- mp_toradix(&r, g_intbuf, 16);
-
- if(strcmp(g_intbuf, r_mp1404) != 0) {
- reason("error: test 3 computed rem %s, expected %s\n", g_intbuf, r_mp1404);
- ++err;
- }
-
- mp_clear(&a); mp_clear(&b); mp_clear(&r);
-
- return err;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_expt_d(void)
-{
- mp_int a;
-
- mp_init(&a); mp_read_radix(&a, mp5, 16);
- mp_expt_d(&a, md9, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- mp_clear(&a);
- if(strcmp(g_intbuf, e_mp5d9) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, e_mp5d9);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_expt(void)
-{
- mp_int a, b;
-
- mp_init(&a); mp_init(&b);
- mp_read_radix(&a, mp7, 16); mp_read_radix(&b, mp8, 16);
-
- mp_expt(&a, &b, &a);
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a); mp_clear(&b);
-
- if(strcmp(g_intbuf, e_mp78) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, e_mp78);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_2expt(void)
-{
- mp_int a;
-
- mp_init(&a);
- mp_2expt(&a, md3);
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a);
-
- if(strcmp(g_intbuf, e_mpc2d3) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, e_mpc2d3);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_sqrt(void)
-{
- mp_int a;
- int res = 0;
-
- mp_init(&a); mp_read_radix(&a, mp9, 16);
- mp_sqrt(&a, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, t_mp9) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, t_mp9);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp15, 16);
- mp_sqrt(&a, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, t_mp15) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, t_mp15);
- res = 1;
- }
-
- CLEANUP:
- mp_clear(&a);
- return res;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_mod_d(void)
-{
- mp_int a;
- mp_digit r;
-
- mp_init(&a); mp_read_radix(&a, mp5, 16);
- IFOK( mp_mod_d(&a, md5, &r) );
- sprintf(g_intbuf, ZS_DIGIT_FMT, r);
- mp_clear(&a);
-
- if(strcmp(g_intbuf, r_mp5d5) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, r_mp5d5);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_mod(void)
-{
- mp_int a, m;
-
- mp_init(&a); mp_init(&m);
- mp_read_radix(&a, mp4, 16); mp_read_radix(&m, mp7, 16);
- IFOK( mp_mod(&a, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a); mp_clear(&m);
-
- if(strcmp(g_intbuf, r_mp47) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, r_mp47);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_addmod(void)
-{
- mp_int a, b, m;
-
- mp_init(&a); mp_init(&b); mp_init(&m);
- mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
- mp_read_radix(&m, mp5, 16);
-
- IFOK( mp_addmod(&a, &b, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a); mp_clear(&b); mp_clear(&m);
-
- if(strcmp(g_intbuf, ms_mp345) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, ms_mp345);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_submod(void)
-{
- mp_int a, b, m;
-
- mp_init(&a); mp_init(&b); mp_init(&m);
- mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
- mp_read_radix(&m, mp5, 16);
-
- IFOK( mp_submod(&a, &b, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a); mp_clear(&b); mp_clear(&m);
-
- if(strcmp(g_intbuf, md_mp345) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, md_mp345);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_mulmod(void)
-{
- mp_int a, b, m;
-
- mp_init(&a); mp_init(&b); mp_init(&m);
- mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
- mp_read_radix(&m, mp5, 16);
-
- IFOK( mp_mulmod(&a, &b, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a); mp_clear(&b); mp_clear(&m);
-
- if(strcmp(g_intbuf, mp_mp345) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, mp_mp345);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_sqrmod(void)
-{
- mp_int a, m;
-
- mp_init(&a); mp_init(&m);
- mp_read_radix(&a, mp3, 16); mp_read_radix(&m, mp5, 16);
-
- IFOK( mp_sqrmod(&a, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a); mp_clear(&m);
-
- if(strcmp(g_intbuf, mp_mp335) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, mp_mp335);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_exptmod(void)
-{
- mp_int a, b, m;
- int res = 0;
-
- mp_init(&a); mp_init(&b); mp_init(&m);
- mp_read_radix(&a, mp8, 16); mp_read_radix(&b, mp1, 16);
- mp_read_radix(&m, mp7, 16);
-
- IFOK( mp_exptmod(&a, &b, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, me_mp817) != 0) {
- reason("case 1: error: computed %s, expected %s\n", g_intbuf, me_mp817);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp1, 16); mp_read_radix(&b, mp5, 16);
- mp_read_radix(&m, mp12, 16);
-
- IFOK( mp_exptmod(&a, &b, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, me_mp1512) != 0) {
- reason("case 2: error: computed %s, expected %s\n", g_intbuf, me_mp1512);
- res = 1; goto CLEANUP;
- }
-
- mp_read_radix(&a, mp5, 16); mp_read_radix(&b, mp1, 16);
- mp_read_radix(&m, mp14, 16);
-
- IFOK( mp_exptmod(&a, &b, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, me_mp5114) != 0) {
- reason("case 3: error: computed %s, expected %s\n", g_intbuf, me_mp5114);
- res = 1;
- }
-
- mp_read_radix(&a, mp16, 16); mp_read_radix(&b, mp17, 16);
- mp_read_radix(&m, mp18, 16);
-
- IFOK( mp_exptmod(&a, &b, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, me_mp161718) != 0) {
- reason("case 4: error: computed %s, expected %s\n", g_intbuf, me_mp161718);
- res = 1;
- }
-
- CLEANUP:
- mp_clear(&a); mp_clear(&b); mp_clear(&m);
- return res;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_exptmod_d(void)
-{
- mp_int a, m;
-
- mp_init(&a); mp_init(&m);
- mp_read_radix(&a, mp5, 16); mp_read_radix(&m, mp7, 16);
-
- IFOK( mp_exptmod_d(&a, md4, &m, &a) );
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a); mp_clear(&m);
-
- if(strcmp(g_intbuf, me_mp5d47) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, me_mp5d47);
- return 1;
- }
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_invmod(void)
-{
- mp_int a, m, c;
- mp_int p1, p2, p3, p4, p5;
- mp_int t1, t2, t3, t4;
- mp_err res;
-
- /* 5 128-bit primes. */
- static const char ivp1[] = { "AAD8A5A2A2BEF644BAEE7DB0CA643719" };
- static const char ivp2[] = { "CB371AD2B79A90BCC88D0430663E40B9" };
- static const char ivp3[] = { "C6C818D4DF2618406CA09280C0400099" };
- static const char ivp4[] = { "CE949C04512E68918006B1F0D7E93F27" };
- static const char ivp5[] = { "F8EE999B6416645040687440E0B89F51" };
-
- mp_init(&a); mp_init(&m);
- mp_read_radix(&a, mp2, 16); mp_read_radix(&m, mp7, 16);
-
- IFOK( mp_invmod(&a, &m, &a) );
-
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a); mp_clear(&m);
-
- if(strcmp(g_intbuf, i_mp27) != 0) {
- reason("error: invmod test 1 computed %s, expected %s\n", g_intbuf, i_mp27);
- return 1;
- }
-
- mp_init(&a); mp_init(&m);
- mp_read_radix(&a, mp20, 16); mp_read_radix(&m, mp19, 16);
-
- IFOK( mp_invmod(&a, &m, &a) );
-
- mp_toradix(&a, g_intbuf, 16);
- mp_clear(&a); mp_clear(&m);
-
- if(strcmp(g_intbuf, i_mp2019) != 0) {
- reason("error: invmod test 2 computed %s, expected %s\n", g_intbuf, i_mp2019);
- return 1;
- }
-
-/* Need the following test cases:
- Odd modulus
- - a is odd, relatively prime to m
- - a is odd, not relatively prime to m
- - a is even, relatively prime to m
- - a is even, not relatively prime to m
- Even modulus
- - a is even (should fail)
- - a is odd, not relatively prime to m
- - a is odd, relatively prime to m,
- m is not a power of 2
- - m has factor 2**k, k < 32
- - m has factor 2**k, k > 32
- m is a power of 2, 2**k
- - k < 32
- - k > 32
-*/
-
- mp_init(&a); mp_init(&m); mp_init(&c);
- mp_init(&p1); mp_init(&p2); mp_init(&p3); mp_init(&p4); mp_init(&p5);
- mp_init(&t1); mp_init(&t2); mp_init(&t3); mp_init(&t4);
-
- mp_read_radix(&p1, ivp1, 16);
- mp_read_radix(&p2, ivp2, 16);
- mp_read_radix(&p3, ivp3, 16);
- mp_read_radix(&p4, ivp4, 16);
- mp_read_radix(&p5, ivp5, 16);
-
- IFOK( mp_2expt(&t2, 68) ); /* t2 = 2**68 */
- IFOK( mp_2expt(&t3, 128) ); /* t3 = 2**128 */
- IFOK( mp_2expt(&t4, 31) ); /* t4 = 2**31 */
-
-/* test 3: Odd modulus - a is odd, relatively prime to m */
-
- IFOK( mp_mul(&p1, &p2, &a) );
- IFOK( mp_mul(&p3, &p4, &m) );
- IFOK( mp_invmod(&a, &m, &t1) );
- IFOK( mp_invmod_xgcd(&a, &m, &c) );
-
- if (mp_cmp(&t1, &c) != 0) {
- mp_toradix(&t1, g_intbuf, 16);
- mp_toradix(&c, a_intbuf, 16);
- reason("error: invmod test 3 computed %s, expected %s\n",
- g_intbuf, a_intbuf);
- return 1;
- }
- mp_clear(&a); mp_clear(&t1); mp_clear(&c);
- mp_init(&a); mp_init(&t1); mp_init(&c);
-
-/* test 4: Odd modulus - a is odd, NOT relatively prime to m */
-
- IFOK( mp_mul(&p1, &p3, &a) );
- /* reuse same m as before */
-
- res = mp_invmod_xgcd(&a, &m, &c);
- if (res != MP_UNDEF)
- goto CLEANUP4;
-
- res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
- if (res != MP_UNDEF) {
-CLEANUP4:
- reason("error: invmod test 4 succeeded, should have failed.\n");
- return 1;
- }
- mp_clear(&a); mp_clear(&t1); mp_clear(&c);
- mp_init(&a); mp_init(&t1); mp_init(&c);
-
-/* test 5: Odd modulus - a is even, relatively prime to m */
-
- IFOK( mp_mul(&p1, &t2, &a) );
- /* reuse m */
- IFOK( mp_invmod(&a, &m, &t1) );
- IFOK( mp_invmod_xgcd(&a, &m, &c) );
-
- if (mp_cmp(&t1, &c) != 0) {
- mp_toradix(&t1, g_intbuf, 16);
- mp_toradix(&c, a_intbuf, 16);
- reason("error: invmod test 5 computed %s, expected %s\n",
- g_intbuf, a_intbuf);
- return 1;
- }
- mp_clear(&a); mp_clear(&t1); mp_clear(&c);
- mp_init(&a); mp_init(&t1); mp_init(&c);
-
-/* test 6: Odd modulus - a is odd, NOT relatively prime to m */
-
- /* reuse t2 */
- IFOK( mp_mul(&t2, &p3, &a) );
- /* reuse same m as before */
-
- res = mp_invmod_xgcd(&a, &m, &c);
- if (res != MP_UNDEF)
- goto CLEANUP6;
-
- res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
- if (res != MP_UNDEF) {
-CLEANUP6:
- reason("error: invmod test 6 succeeded, should have failed.\n");
- return 1;
- }
- mp_clear(&a); mp_clear(&m); mp_clear(&c); mp_clear(&t1);
- mp_init(&a); mp_init(&m); mp_init(&c); mp_init(&t1);
-
-/* test 7: Even modulus, even a, should fail */
-
- IFOK( mp_mul(&p3, &t3, &m) ); /* even m */
- /* reuse t2 */
- IFOK( mp_mul(&p1, &t2, &a) ); /* even a */
-
- res = mp_invmod_xgcd(&a, &m, &c);
- if (res != MP_UNDEF)
- goto CLEANUP7;
-
- res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
- if (res != MP_UNDEF) {
-CLEANUP7:
- reason("error: invmod test 7 succeeded, should have failed.\n");
- return 1;
- }
- mp_clear(&a); mp_clear(&c); mp_clear(&t1);
- mp_init(&a); mp_init(&c); mp_init(&t1);
-
-/* test 8: Even modulus - a is odd, not relatively prime to m */
-
- /* reuse m */
- IFOK( mp_mul(&p3, &p1, &a) ); /* even a */
-
- res = mp_invmod_xgcd(&a, &m, &c);
- if (res != MP_UNDEF)
- goto CLEANUP8;
-
- res = mp_invmod(&a, &m, &t1); /* we expect this to fail. */
- if (res != MP_UNDEF) {
-CLEANUP8:
- reason("error: invmod test 8 succeeded, should have failed.\n");
- return 1;
- }
- mp_clear(&a); mp_clear(&m); mp_clear(&c); mp_clear(&t1);
- mp_init(&a); mp_init(&m); mp_init(&c); mp_init(&t1);
-
-/* test 9: Even modulus - m has factor 2**k, k < 32
- * - a is odd, relatively prime to m,
- */
- IFOK( mp_mul(&p3, &t4, &m) ); /* even m */
- IFOK( mp_mul(&p1, &p2, &a) );
- IFOK( mp_invmod(&a, &m, &t1) );
- IFOK( mp_invmod_xgcd(&a, &m, &c) );
-
- if (mp_cmp(&t1, &c) != 0) {
- mp_toradix(&t1, g_intbuf, 16);
- mp_toradix(&c, a_intbuf, 16);
- reason("error: invmod test 9 computed %s, expected %s\n",
- g_intbuf, a_intbuf);
- return 1;
- }
- mp_clear(&m); mp_clear(&t1); mp_clear(&c);
- mp_init(&m); mp_init(&t1); mp_init(&c);
-
-/* test 10: Even modulus - m has factor 2**k, k > 32
- * - a is odd, relatively prime to m,
- */
- IFOK( mp_mul(&p3, &t3, &m) ); /* even m */
- /* reuse a */
- IFOK( mp_invmod(&a, &m, &t1) );
- IFOK( mp_invmod_xgcd(&a, &m, &c) );
-
- if (mp_cmp(&t1, &c) != 0) {
- mp_toradix(&t1, g_intbuf, 16);
- mp_toradix(&c, a_intbuf, 16);
- reason("error: invmod test 10 computed %s, expected %s\n",
- g_intbuf, a_intbuf);
- return 1;
- }
- mp_clear(&t1); mp_clear(&c);
- mp_init(&t1); mp_init(&c);
-
-/* test 11: Even modulus - m is a power of 2, 2**k | k < 32
- * - a is odd, relatively prime to m,
- */
- IFOK( mp_invmod(&a, &t4, &t1) );
- IFOK( mp_invmod_xgcd(&a, &t4, &c) );
-
- if (mp_cmp(&t1, &c) != 0) {
- mp_toradix(&t1, g_intbuf, 16);
- mp_toradix(&c, a_intbuf, 16);
- reason("error: invmod test 11 computed %s, expected %s\n",
- g_intbuf, a_intbuf);
- return 1;
- }
- mp_clear(&t1); mp_clear(&c);
- mp_init(&t1); mp_init(&c);
-
-/* test 12: Even modulus - m is a power of 2, 2**k | k > 32
- * - a is odd, relatively prime to m,
- */
- IFOK( mp_invmod(&a, &t3, &t1) );
- IFOK( mp_invmod_xgcd(&a, &t3, &c) );
-
- if (mp_cmp(&t1, &c) != 0) {
- mp_toradix(&t1, g_intbuf, 16);
- mp_toradix(&c, a_intbuf, 16);
- reason("error: invmod test 12 computed %s, expected %s\n",
- g_intbuf, a_intbuf);
- return 1;
- }
-
- mp_clear(&a); mp_clear(&m); mp_clear(&c);
- mp_clear(&t1); mp_clear(&t2); mp_clear(&t3); mp_clear(&t4);
- mp_clear(&p1); mp_clear(&p2); mp_clear(&p3); mp_clear(&p4); mp_clear(&p5);
-
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_cmp_d(void)
-{
- mp_int a;
-
- mp_init(&a); mp_read_radix(&a, mp8, 16);
-
- if(mp_cmp_d(&a, md8) >= 0) {
- reason("error: %s >= " DIGIT_FMT "\n", mp8, md8);
- mp_clear(&a);
- return 1;
- }
-
- mp_read_radix(&a, mp5, 16);
-
- if(mp_cmp_d(&a, md8) <= 0) {
- reason("error: %s <= " DIGIT_FMT "\n", mp5, md8);
- mp_clear(&a);
- return 1;
- }
-
- mp_read_radix(&a, mp6, 16);
-
- if(mp_cmp_d(&a, md1) != 0) {
- reason("error: %s != " DIGIT_FMT "\n", mp6, md1);
- mp_clear(&a);
- return 1;
- }
-
- mp_clear(&a);
- return 0;
-
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_cmp_z(void)
-{
- mp_int a;
-
- mp_init(&a); mp_read_radix(&a, mp6, 16);
-
- if(mp_cmp_z(&a) != 0) {
- reason("error: someone thinks a zero value is non-zero\n");
- mp_clear(&a);
- return 1;
- }
-
- mp_read_radix(&a, mp1, 16);
-
- if(mp_cmp_z(&a) <= 0) {
- reason("error: someone thinks a positive value is non-positive\n");
- mp_clear(&a);
- return 1;
- }
-
- mp_read_radix(&a, mp4, 16);
-
- if(mp_cmp_z(&a) >= 0) {
- reason("error: someone thinks a negative value is non-negative\n");
- mp_clear(&a);
- return 1;
- }
-
- mp_clear(&a);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_cmp(void)
-{
- mp_int a, b;
-
- mp_init(&a); mp_init(&b);
- mp_read_radix(&a, mp3, 16); mp_read_radix(&b, mp4, 16);
-
- if(mp_cmp(&a, &b) <= 0) {
- reason("error: %s <= %s\n", mp3, mp4);
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- mp_read_radix(&b, mp3, 16);
- if(mp_cmp(&a, &b) != 0) {
- reason("error: %s != %s\n", mp3, mp3);
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- mp_read_radix(&a, mp5, 16);
- if(mp_cmp(&a, &b) >= 0) {
- reason("error: %s >= %s\n", mp5, mp3);
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- mp_read_radix(&a, mp5a, 16);
- if(mp_cmp_int(&a, 1000000) >= 0 ||
- (mp_cmp_int(&a, -5000000) <= 0) ||
- (mp_cmp_int(&a, -4938110) != 0)) {
- reason("error: long integer comparison failed (%s)", mp5a);
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- mp_clear(&a); mp_clear(&b);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_cmp_mag(void)
-{
- mp_int a, b;
-
- mp_init(&a); mp_init(&b);
- mp_read_radix(&a, mp5, 16); mp_read_radix(&b, mp4, 16);
-
- if(mp_cmp_mag(&a, &b) >= 0) {
- reason("error: %s >= %s\n", mp5, mp4);
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- mp_read_radix(&b, mp5, 16);
- if(mp_cmp_mag(&a, &b) != 0) {
- reason("error: %s != %s\n", mp5, mp5);
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- mp_read_radix(&a, mp1, 16);
- if(mp_cmp_mag(&b, &a) >= 0) {
- reason("error: %s >= %s\n", mp5, mp1);
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
-
- mp_clear(&a); mp_clear(&b);
- return 0;
-
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_parity(void)
-{
- mp_int a;
-
- mp_init(&a); mp_read_radix(&a, mp1, 16);
-
- if(!mp_isodd(&a)) {
- reason("error: expected operand to be odd, but it isn't\n");
- mp_clear(&a);
- return 1;
- }
-
- mp_read_radix(&a, mp6, 16);
-
- if(!mp_iseven(&a)) {
- reason("error: expected operand to be even, but it isn't\n");
- mp_clear(&a);
- return 1;
- }
-
- mp_clear(&a);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_gcd(void)
-{
- mp_int a, b;
- int out = 0;
-
- mp_init(&a); mp_init(&b);
- mp_read_radix(&a, mp7, 16); mp_read_radix(&b, mp1, 16);
-
- mp_gcd(&a, &b, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, g_mp71) != 0) {
- reason("error: computed %s, expected %s\n", g_intbuf, g_mp71);
- out = 1;
- }
-
- mp_clear(&a); mp_clear(&b);
- return out;
-
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_lcm(void)
-{
- mp_int a, b;
- int out = 0;
-
- mp_init(&a); mp_init(&b);
- mp_read_radix(&a, mp10, 16); mp_read_radix(&b, mp11, 16);
-
- mp_lcm(&a, &b, &a);
- mp_toradix(&a, g_intbuf, 16);
-
- if(strcmp(g_intbuf, l_mp1011) != 0) {
- reason("error: computed %s, expected%s\n", g_intbuf, l_mp1011);
- out = 1;
- }
-
- mp_clear(&a); mp_clear(&b);
-
- return out;
-
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_convert(void)
-{
- int ix;
- mp_int a;
-
- mp_init(&a); mp_read_radix(&a, mp9, 16);
-
- for(ix = LOW_RADIX; ix <= HIGH_RADIX; ix++) {
- mp_toradix(&a, g_intbuf, ix);
-
- if(strcmp(g_intbuf, v_mp9[ix - LOW_RADIX]) != 0) {
- reason("error: radix %d, computed %s, expected %s\n",
- ix, g_intbuf, v_mp9[ix - LOW_RADIX]);
- mp_clear(&a);
- return 1;
- }
- }
-
- mp_clear(&a);
- return 0;
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_raw(void)
-{
- int len, out = 0;
- mp_int a;
- char *buf;
-
- mp_init(&a); mp_read_radix(&a, mp4, 16);
-
- len = mp_raw_size(&a);
- if(len != sizeof(b_mp4)) {
- reason("error: test_raw: expected length %d, computed %d\n", sizeof(b_mp4),
- len);
- mp_clear(&a);
- return 1;
- }
-
- buf = calloc(len, sizeof(char));
- mp_toraw(&a, buf);
-
- if(memcmp(buf, b_mp4, sizeof(b_mp4)) != 0) {
- reason("error: test_raw: binary output does not match test vector\n");
- out = 1;
- }
-
- free(buf);
- mp_clear(&a);
-
- return out;
-
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_pprime(void)
-{
- mp_int p;
- int err = 0;
- mp_err res;
-
- mp_init(&p);
- mp_read_radix(&p, mp7, 16);
-
- if(mpp_pprime(&p, 5) != MP_YES) {
- reason("error: %s failed Rabin-Miller test, but is prime\n", mp7);
- err = 1;
- }
-
- IFOK( mp_set_int(&p, 9) );
- res = mpp_pprime(&p, 50);
- if (res == MP_YES) {
- reason("error: 9 is composite but passed Rabin-Miller test\n");
- err = 1;
- } else if (res != MP_NO) {
- reason("test mpp_pprime(9, 50) failed: error %d\n", res);
- err = 1;
- }
-
- IFOK( mp_set_int(&p, 15) );
- res = mpp_pprime(&p, 50);
- if (res == MP_YES) {
- reason("error: 15 is composite but passed Rabin-Miller test\n");
- err = 1;
- } else if (res != MP_NO) {
- reason("test mpp_pprime(15, 50) failed: error %d\n", res);
- err = 1;
- }
-
- mp_clear(&p);
-
- return err;
-
-}
-
-/*------------------------------------------------------------------------*/
-
-int test_fermat(void)
-{
- mp_int p;
- mp_err res;
- int err = 0;
-
- mp_init(&p);
- mp_read_radix(&p, mp7, 16);
-
- if((res = mpp_fermat(&p, 2)) != MP_YES) {
- reason("error: %s failed Fermat test on 2: %s\n", mp7,
- mp_strerror(res));
- ++err;
- }
-
- if((res = mpp_fermat(&p, 3)) != MP_YES) {
- reason("error: %s failed Fermat test on 3: %s\n", mp7,
- mp_strerror(res));
- ++err;
- }
-
- mp_clear(&p);
-
- return err;
-
-}
-
-/*------------------------------------------------------------------------*/
-/* Like fprintf(), but only if we are behaving in a verbose manner */
-
-void reason(char *fmt, ...)
-{
- va_list ap;
-
- if(!g_verbose)
- return;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-}
-
-/*------------------------------------------------------------------------*/
-/* HERE THERE BE DRAGONS */
diff --git a/security/nss/lib/freebl/mpi/mpi.c b/security/nss/lib/freebl/mpi/mpi.c
deleted file mode 100644
index 2cb5e5be0..000000000
--- a/security/nss/lib/freebl/mpi/mpi.c
+++ /dev/null
@@ -1,4821 +0,0 @@
-/*
- * mpi.c
- *
- * Arbitrary precision integer arithmetic library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "mpi-priv.h"
-#if defined(OSF1)
-#include <c_asm.h>
-#endif
-
-#if defined(__arm__) && \
- ((defined(__thumb__) && !defined(__thumb2__)) || defined(__ARM_ARCH_3__))
-/* 16-bit thumb or ARM v3 doesn't work inlined assember version */
-#undef MP_ASSEMBLY_MULTIPLY
-#undef MP_ASSEMBLY_SQUARE
-#endif
-
-#if MP_LOGTAB
-/*
- A table of the logs of 2 for various bases (the 0 and 1 entries of
- this table are meaningless and should not be referenced).
-
- This table is used to compute output lengths for the mp_toradix()
- function. Since a number n in radix r takes up about log_r(n)
- digits, we estimate the output size by taking the least integer
- greater than log_r(n), where:
-
- log_r(n) = log_2(n) * log_r(2)
-
- This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
- which are the output bases supported.
- */
-#include "logtab.h"
-#endif
-
-/* {{{ Constant strings */
-
-/* Constant strings returned by mp_strerror() */
-static const char *mp_err_string[] = {
- "unknown result code", /* say what? */
- "boolean true", /* MP_OKAY, MP_YES */
- "boolean false", /* MP_NO */
- "out of memory", /* MP_MEM */
- "argument out of range", /* MP_RANGE */
- "invalid input parameter", /* MP_BADARG */
- "result is undefined" /* MP_UNDEF */
-};
-
-/* Value to digit maps for radix conversion */
-
-/* s_dmap_1 - standard digits and letters */
-static const char *s_dmap_1 =
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
-
-/* }}} */
-
-unsigned long mp_allocs;
-unsigned long mp_frees;
-unsigned long mp_copies;
-
-/* {{{ Default precision manipulation */
-
-/* Default precision for newly created mp_int's */
-static mp_size s_mp_defprec = MP_DEFPREC;
-
-mp_size mp_get_prec(void)
-{
- return s_mp_defprec;
-
-} /* end mp_get_prec() */
-
-void mp_set_prec(mp_size prec)
-{
- if(prec == 0)
- s_mp_defprec = MP_DEFPREC;
- else
- s_mp_defprec = prec;
-
-} /* end mp_set_prec() */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ mp_init(mp) */
-
-/*
- mp_init(mp)
-
- Initialize a new zero-valued mp_int. Returns MP_OKAY if successful,
- MP_MEM if memory could not be allocated for the structure.
- */
-
-mp_err mp_init(mp_int *mp)
-{
- return mp_init_size(mp, s_mp_defprec);
-
-} /* end mp_init() */
-
-/* }}} */
-
-/* {{{ mp_init_size(mp, prec) */
-
-/*
- mp_init_size(mp, prec)
-
- Initialize a new zero-valued mp_int with at least the given
- precision; returns MP_OKAY if successful, or MP_MEM if memory could
- not be allocated for the structure.
- */
-
-mp_err mp_init_size(mp_int *mp, mp_size prec)
-{
- ARGCHK(mp != NULL && prec > 0, MP_BADARG);
-
- prec = MP_ROUNDUP(prec, s_mp_defprec);
- if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL)
- return MP_MEM;
-
- SIGN(mp) = ZPOS;
- USED(mp) = 1;
- ALLOC(mp) = prec;
-
- return MP_OKAY;
-
-} /* end mp_init_size() */
-
-/* }}} */
-
-/* {{{ mp_init_copy(mp, from) */
-
-/*
- mp_init_copy(mp, from)
-
- Initialize mp as an exact copy of from. Returns MP_OKAY if
- successful, MP_MEM if memory could not be allocated for the new
- structure.
- */
-
-mp_err mp_init_copy(mp_int *mp, const mp_int *from)
-{
- ARGCHK(mp != NULL && from != NULL, MP_BADARG);
-
- if(mp == from)
- return MP_OKAY;
-
- if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL)
- return MP_MEM;
-
- s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
- USED(mp) = USED(from);
- ALLOC(mp) = ALLOC(from);
- SIGN(mp) = SIGN(from);
-
- return MP_OKAY;
-
-} /* end mp_init_copy() */
-
-/* }}} */
-
-/* {{{ mp_copy(from, to) */
-
-/*
- mp_copy(from, to)
-
- Copies the mp_int 'from' to the mp_int 'to'. It is presumed that
- 'to' has already been initialized (if not, use mp_init_copy()
- instead). If 'from' and 'to' are identical, nothing happens.
- */
-
-mp_err mp_copy(const mp_int *from, mp_int *to)
-{
- ARGCHK(from != NULL && to != NULL, MP_BADARG);
-
- if(from == to)
- return MP_OKAY;
-
- { /* copy */
- mp_digit *tmp;
-
- /*
- If the allocated buffer in 'to' already has enough space to hold
- all the used digits of 'from', we'll re-use it to avoid hitting
- the memory allocater more than necessary; otherwise, we'd have
- to grow anyway, so we just allocate a hunk and make the copy as
- usual
- */
- if(ALLOC(to) >= USED(from)) {
- s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
- s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
-
- } else {
- if((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit))) == NULL)
- return MP_MEM;
-
- s_mp_copy(DIGITS(from), tmp, USED(from));
-
- if(DIGITS(to) != NULL) {
-#if MP_CRYPTO
- s_mp_setz(DIGITS(to), ALLOC(to));
-#endif
- s_mp_free(DIGITS(to));
- }
-
- DIGITS(to) = tmp;
- ALLOC(to) = ALLOC(from);
- }
-
- /* Copy the precision and sign from the original */
- USED(to) = USED(from);
- SIGN(to) = SIGN(from);
- } /* end copy */
-
- return MP_OKAY;
-
-} /* end mp_copy() */
-
-/* }}} */
-
-/* {{{ mp_exch(mp1, mp2) */
-
-/*
- mp_exch(mp1, mp2)
-
- Exchange mp1 and mp2 without allocating any intermediate memory
- (well, unless you count the stack space needed for this call and the
- locals it creates...). This cannot fail.
- */
-
-void mp_exch(mp_int *mp1, mp_int *mp2)
-{
-#if MP_ARGCHK == 2
- assert(mp1 != NULL && mp2 != NULL);
-#else
- if(mp1 == NULL || mp2 == NULL)
- return;
-#endif
-
- s_mp_exch(mp1, mp2);
-
-} /* end mp_exch() */
-
-/* }}} */
-
-/* {{{ mp_clear(mp) */
-
-/*
- mp_clear(mp)
-
- Release the storage used by an mp_int, and void its fields so that
- if someone calls mp_clear() again for the same int later, we won't
- get tollchocked.
- */
-
-void mp_clear(mp_int *mp)
-{
- if(mp == NULL)
- return;
-
- if(DIGITS(mp) != NULL) {
-#if MP_CRYPTO
- s_mp_setz(DIGITS(mp), ALLOC(mp));
-#endif
- s_mp_free(DIGITS(mp));
- DIGITS(mp) = NULL;
- }
-
- USED(mp) = 0;
- ALLOC(mp) = 0;
-
-} /* end mp_clear() */
-
-/* }}} */
-
-/* {{{ mp_zero(mp) */
-
-/*
- mp_zero(mp)
-
- Set mp to zero. Does not change the allocated size of the structure,
- and therefore cannot fail (except on a bad argument, which we ignore)
- */
-void mp_zero(mp_int *mp)
-{
- if(mp == NULL)
- return;
-
- s_mp_setz(DIGITS(mp), ALLOC(mp));
- USED(mp) = 1;
- SIGN(mp) = ZPOS;
-
-} /* end mp_zero() */
-
-/* }}} */
-
-/* {{{ mp_set(mp, d) */
-
-void mp_set(mp_int *mp, mp_digit d)
-{
- if(mp == NULL)
- return;
-
- mp_zero(mp);
- DIGIT(mp, 0) = d;
-
-} /* end mp_set() */
-
-/* }}} */
-
-/* {{{ mp_set_int(mp, z) */
-
-mp_err mp_set_int(mp_int *mp, long z)
-{
- int ix;
- unsigned long v = labs(z);
- mp_err res;
-
- ARGCHK(mp != NULL, MP_BADARG);
-
- mp_zero(mp);
- if(z == 0)
- return MP_OKAY; /* shortcut for zero */
-
- if (sizeof v <= sizeof(mp_digit)) {
- DIGIT(mp,0) = v;
- } else {
- for (ix = sizeof(long) - 1; ix >= 0; ix--) {
- if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
- return res;
-
- res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
- if (res != MP_OKAY)
- return res;
- }
- }
- if(z < 0)
- SIGN(mp) = NEG;
-
- return MP_OKAY;
-
-} /* end mp_set_int() */
-
-/* }}} */
-
-/* {{{ mp_set_ulong(mp, z) */
-
-mp_err mp_set_ulong(mp_int *mp, unsigned long z)
-{
- int ix;
- mp_err res;
-
- ARGCHK(mp != NULL, MP_BADARG);
-
- mp_zero(mp);
- if(z == 0)
- return MP_OKAY; /* shortcut for zero */
-
- if (sizeof z <= sizeof(mp_digit)) {
- DIGIT(mp,0) = z;
- } else {
- for (ix = sizeof(long) - 1; ix >= 0; ix--) {
- if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
- return res;
-
- res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX));
- if (res != MP_OKAY)
- return res;
- }
- }
- return MP_OKAY;
-} /* end mp_set_ulong() */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Digit arithmetic */
-
-/* {{{ mp_add_d(a, d, b) */
-
-/*
- mp_add_d(a, d, b)
-
- Compute the sum b = a + d, for a single digit d. Respects the sign of
- its primary addend (single digits are unsigned anyway).
- */
-
-mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b)
-{
- mp_int tmp;
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
- return res;
-
- if(SIGN(&tmp) == ZPOS) {
- if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
- goto CLEANUP;
- } else if(s_mp_cmp_d(&tmp, d) >= 0) {
- if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
- goto CLEANUP;
- } else {
- mp_neg(&tmp, &tmp);
-
- DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
- }
-
- if(s_mp_cmp_d(&tmp, 0) == 0)
- SIGN(&tmp) = ZPOS;
-
- s_mp_exch(&tmp, b);
-
-CLEANUP:
- mp_clear(&tmp);
- return res;
-
-} /* end mp_add_d() */
-
-/* }}} */
-
-/* {{{ mp_sub_d(a, d, b) */
-
-/*
- mp_sub_d(a, d, b)
-
- Compute the difference b = a - d, for a single digit d. Respects the
- sign of its subtrahend (single digits are unsigned anyway).
- */
-
-mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b)
-{
- mp_int tmp;
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
- return res;
-
- if(SIGN(&tmp) == NEG) {
- if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
- goto CLEANUP;
- } else if(s_mp_cmp_d(&tmp, d) >= 0) {
- if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
- goto CLEANUP;
- } else {
- mp_neg(&tmp, &tmp);
-
- DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
- SIGN(&tmp) = NEG;
- }
-
- if(s_mp_cmp_d(&tmp, 0) == 0)
- SIGN(&tmp) = ZPOS;
-
- s_mp_exch(&tmp, b);
-
-CLEANUP:
- mp_clear(&tmp);
- return res;
-
-} /* end mp_sub_d() */
-
-/* }}} */
-
-/* {{{ mp_mul_d(a, d, b) */
-
-/*
- mp_mul_d(a, d, b)
-
- Compute the product b = a * d, for a single digit d. Respects the sign
- of its multiplicand (single digits are unsigned anyway)
- */
-
-mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)
-{
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- if(d == 0) {
- mp_zero(b);
- return MP_OKAY;
- }
-
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
-
- res = s_mp_mul_d(b, d);
-
- return res;
-
-} /* end mp_mul_d() */
-
-/* }}} */
-
-/* {{{ mp_mul_2(a, c) */
-
-mp_err mp_mul_2(const mp_int *a, mp_int *c)
-{
- mp_err res;
-
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
- if((res = mp_copy(a, c)) != MP_OKAY)
- return res;
-
- return s_mp_mul_2(c);
-
-} /* end mp_mul_2() */
-
-/* }}} */
-
-/* {{{ mp_div_d(a, d, q, r) */
-
-/*
- mp_div_d(a, d, q, r)
-
- Compute the quotient q = a / d and remainder r = a mod d, for a
- single digit d. Respects the sign of its divisor (single digits are
- unsigned anyway).
- */
-
-mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
-{
- mp_err res;
- mp_int qp;
- mp_digit rem;
- int pow;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- if(d == 0)
- return MP_RANGE;
-
- /* Shortcut for powers of two ... */
- if((pow = s_mp_ispow2d(d)) >= 0) {
- mp_digit mask;
-
- mask = ((mp_digit)1 << pow) - 1;
- rem = DIGIT(a, 0) & mask;
-
- if(q) {
- mp_copy(a, q);
- s_mp_div_2d(q, pow);
- }
-
- if(r)
- *r = rem;
-
- return MP_OKAY;
- }
-
- if((res = mp_init_copy(&qp, a)) != MP_OKAY)
- return res;
-
- res = s_mp_div_d(&qp, d, &rem);
-
- if(s_mp_cmp_d(&qp, 0) == 0)
- SIGN(q) = ZPOS;
-
- if(r)
- *r = rem;
-
- if(q)
- s_mp_exch(&qp, q);
-
- mp_clear(&qp);
- return res;
-
-} /* end mp_div_d() */
-
-/* }}} */
-
-/* {{{ mp_div_2(a, c) */
-
-/*
- mp_div_2(a, c)
-
- Compute c = a / 2, disregarding the remainder.
- */
-
-mp_err mp_div_2(const mp_int *a, mp_int *c)
-{
- mp_err res;
-
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
- if((res = mp_copy(a, c)) != MP_OKAY)
- return res;
-
- s_mp_div_2(c);
-
- return MP_OKAY;
-
-} /* end mp_div_2() */
-
-/* }}} */
-
-/* {{{ mp_expt_d(a, d, b) */
-
-mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)
-{
- mp_int s, x;
- mp_err res;
-
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
- if((res = mp_init(&s)) != MP_OKAY)
- return res;
- if((res = mp_init_copy(&x, a)) != MP_OKAY)
- goto X;
-
- DIGIT(&s, 0) = 1;
-
- while(d != 0) {
- if(d & 1) {
- if((res = s_mp_mul(&s, &x)) != MP_OKAY)
- goto CLEANUP;
- }
-
- d /= 2;
-
- if((res = s_mp_sqr(&x)) != MP_OKAY)
- goto CLEANUP;
- }
-
- s_mp_exch(&s, c);
-
-CLEANUP:
- mp_clear(&x);
-X:
- mp_clear(&s);
-
- return res;
-
-} /* end mp_expt_d() */
-
-/* }}} */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Full arithmetic */
-
-/* {{{ mp_abs(a, b) */
-
-/*
- mp_abs(a, b)
-
- Compute b = |a|. 'a' and 'b' may be identical.
- */
-
-mp_err mp_abs(const mp_int *a, mp_int *b)
-{
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
-
- SIGN(b) = ZPOS;
-
- return MP_OKAY;
-
-} /* end mp_abs() */
-
-/* }}} */
-
-/* {{{ mp_neg(a, b) */
-
-/*
- mp_neg(a, b)
-
- Compute b = -a. 'a' and 'b' may be identical.
- */
-
-mp_err mp_neg(const mp_int *a, mp_int *b)
-{
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
-
- if(s_mp_cmp_d(b, 0) == MP_EQ)
- SIGN(b) = ZPOS;
- else
- SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG;
-
- return MP_OKAY;
-
-} /* end mp_neg() */
-
-/* }}} */
-
-/* {{{ mp_add(a, b, c) */
-
-/*
- mp_add(a, b, c)
-
- Compute c = a + b. All parameters may be identical.
- */
-
-mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
-{
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */
- MP_CHECKOK( s_mp_add_3arg(a, b, c) );
- } else if(s_mp_cmp(a, b) >= 0) { /* different sign: |a| >= |b| */
- MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
- } else { /* different sign: |a| < |b| */
- MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
- }
-
- if (s_mp_cmp_d(c, 0) == MP_EQ)
- SIGN(c) = ZPOS;
-
-CLEANUP:
- return res;
-
-} /* end mp_add() */
-
-/* }}} */
-
-/* {{{ mp_sub(a, b, c) */
-
-/*
- mp_sub(a, b, c)
-
- Compute c = a - b. All parameters may be identical.
- */
-
-mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
-{
- mp_err res;
- int magDiff;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if (a == b) {
- mp_zero(c);
- return MP_OKAY;
- }
-
- if (MP_SIGN(a) != MP_SIGN(b)) {
- MP_CHECKOK( s_mp_add_3arg(a, b, c) );
- } else if (!(magDiff = s_mp_cmp(a, b))) {
- mp_zero(c);
- res = MP_OKAY;
- } else if (magDiff > 0) {
- MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
- } else {
- MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
- MP_SIGN(c) = !MP_SIGN(a);
- }
-
- if (s_mp_cmp_d(c, 0) == MP_EQ)
- MP_SIGN(c) = MP_ZPOS;
-
-CLEANUP:
- return res;
-
-} /* end mp_sub() */
-
-/* }}} */
-
-/* {{{ mp_mul(a, b, c) */
-
-/*
- mp_mul(a, b, c)
-
- Compute c = a * b. All parameters may be identical.
- */
-mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int * c)
-{
- mp_digit *pb;
- mp_int tmp;
- mp_err res;
- mp_size ib;
- mp_size useda, usedb;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if (a == c) {
- if ((res = mp_init_copy(&tmp, a)) != MP_OKAY)
- return res;
- if (a == b)
- b = &tmp;
- a = &tmp;
- } else if (b == c) {
- if ((res = mp_init_copy(&tmp, b)) != MP_OKAY)
- return res;
- b = &tmp;
- } else {
- MP_DIGITS(&tmp) = 0;
- }
-
- if (MP_USED(a) < MP_USED(b)) {
- const mp_int *xch = b; /* switch a and b, to do fewer outer loops */
- b = a;
- a = xch;
- }
-
- MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
- if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY)
- goto CLEANUP;
-
-#ifdef NSS_USE_COMBA
- if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
- if (MP_USED(a) == 4) {
- s_mp_mul_comba_4(a, b, c);
- goto CLEANUP;
- }
- if (MP_USED(a) == 8) {
- s_mp_mul_comba_8(a, b, c);
- goto CLEANUP;
- }
- if (MP_USED(a) == 16) {
- s_mp_mul_comba_16(a, b, c);
- goto CLEANUP;
- }
- if (MP_USED(a) == 32) {
- s_mp_mul_comba_32(a, b, c);
- goto CLEANUP;
- }
- }
-#endif
-
- pb = MP_DIGITS(b);
- s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
-
- /* Outer loop: Digits of b */
- useda = MP_USED(a);
- usedb = MP_USED(b);
- for (ib = 1; ib < usedb; ib++) {
- mp_digit b_i = *pb++;
-
- /* Inner product: Digits of a */
- if (b_i)
- s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
- else
- MP_DIGIT(c, ib + useda) = b_i;
- }
-
- s_mp_clamp(c);
-
- if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)
- SIGN(c) = ZPOS;
- else
- SIGN(c) = NEG;
-
-CLEANUP:
- mp_clear(&tmp);
- return res;
-} /* end mp_mul() */
-
-/* }}} */
-
-/* {{{ mp_sqr(a, sqr) */
-
-#if MP_SQUARE
-/*
- Computes the square of a. This can be done more
- efficiently than a general multiplication, because many of the
- computation steps are redundant when squaring. The inner product
- step is a bit more complicated, but we save a fair number of
- iterations of the multiplication loop.
- */
-
-/* sqr = a^2; Caller provides both a and tmp; */
-mp_err mp_sqr(const mp_int *a, mp_int *sqr)
-{
- mp_digit *pa;
- mp_digit d;
- mp_err res;
- mp_size ix;
- mp_int tmp;
- int count;
-
- ARGCHK(a != NULL && sqr != NULL, MP_BADARG);
-
- if (a == sqr) {
- if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
- return res;
- a = &tmp;
- } else {
- DIGITS(&tmp) = 0;
- res = MP_OKAY;
- }
-
- ix = 2 * MP_USED(a);
- if (ix > MP_ALLOC(sqr)) {
- MP_USED(sqr) = 1;
- MP_CHECKOK( s_mp_grow(sqr, ix) );
- }
- MP_USED(sqr) = ix;
- MP_DIGIT(sqr, 0) = 0;
-
-#ifdef NSS_USE_COMBA
- if (IS_POWER_OF_2(MP_USED(a))) {
- if (MP_USED(a) == 4) {
- s_mp_sqr_comba_4(a, sqr);
- goto CLEANUP;
- }
- if (MP_USED(a) == 8) {
- s_mp_sqr_comba_8(a, sqr);
- goto CLEANUP;
- }
- if (MP_USED(a) == 16) {
- s_mp_sqr_comba_16(a, sqr);
- goto CLEANUP;
- }
- if (MP_USED(a) == 32) {
- s_mp_sqr_comba_32(a, sqr);
- goto CLEANUP;
- }
- }
-#endif
-
- pa = MP_DIGITS(a);
- count = MP_USED(a) - 1;
- if (count > 0) {
- d = *pa++;
- s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1);
- for (ix = 3; --count > 0; ix += 2) {
- d = *pa++;
- s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix);
- } /* for(ix ...) */
- MP_DIGIT(sqr, MP_USED(sqr)-1) = 0; /* above loop stopped short of this. */
-
- /* now sqr *= 2 */
- s_mp_mul_2(sqr);
- } else {
- MP_DIGIT(sqr, 1) = 0;
- }
-
- /* now add the squares of the digits of a to sqr. */
- s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr));
-
- SIGN(sqr) = ZPOS;
- s_mp_clamp(sqr);
-
-CLEANUP:
- mp_clear(&tmp);
- return res;
-
-} /* end mp_sqr() */
-#endif
-
-/* }}} */
-
-/* {{{ mp_div(a, b, q, r) */
-
-/*
- mp_div(a, b, q, r)
-
- Compute q = a / b and r = a mod b. Input parameters may be re-used
- as output parameters. If q or r is NULL, that portion of the
- computation will be discarded (although it will still be computed)
- */
-mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
-{
- mp_err res;
- mp_int *pQ, *pR;
- mp_int qtmp, rtmp, btmp;
- int cmp;
- mp_sign signA;
- mp_sign signB;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- signA = MP_SIGN(a);
- signB = MP_SIGN(b);
-
- if(mp_cmp_z(b) == MP_EQ)
- return MP_RANGE;
-
- DIGITS(&qtmp) = 0;
- DIGITS(&rtmp) = 0;
- DIGITS(&btmp) = 0;
-
- /* Set up some temporaries... */
- if (!r || r == a || r == b) {
- MP_CHECKOK( mp_init_copy(&rtmp, a) );
- pR = &rtmp;
- } else {
- MP_CHECKOK( mp_copy(a, r) );
- pR = r;
- }
-
- if (!q || q == a || q == b) {
- MP_CHECKOK( mp_init_size(&qtmp, MP_USED(a)) );
- pQ = &qtmp;
- } else {
- MP_CHECKOK( s_mp_pad(q, MP_USED(a)) );
- pQ = q;
- mp_zero(pQ);
- }
-
- /*
- If |a| <= |b|, we can compute the solution without division;
- otherwise, we actually do the work required.
- */
- if ((cmp = s_mp_cmp(a, b)) <= 0) {
- if (cmp) {
- /* r was set to a above. */
- mp_zero(pQ);
- } else {
- mp_set(pQ, 1);
- mp_zero(pR);
- }
- } else {
- MP_CHECKOK( mp_init_copy(&btmp, b) );
- MP_CHECKOK( s_mp_div(pR, &btmp, pQ) );
- }
-
- /* Compute the signs for the output */
- MP_SIGN(pR) = signA; /* Sr = Sa */
- /* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */
- MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG;
-
- if(s_mp_cmp_d(pQ, 0) == MP_EQ)
- SIGN(pQ) = ZPOS;
- if(s_mp_cmp_d(pR, 0) == MP_EQ)
- SIGN(pR) = ZPOS;
-
- /* Copy output, if it is needed */
- if(q && q != pQ)
- s_mp_exch(pQ, q);
-
- if(r && r != pR)
- s_mp_exch(pR, r);
-
-CLEANUP:
- mp_clear(&btmp);
- mp_clear(&rtmp);
- mp_clear(&qtmp);
-
- return res;
-
-} /* end mp_div() */
-
-/* }}} */
-
-/* {{{ mp_div_2d(a, d, q, r) */
-
-mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r)
-{
- mp_err res;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- if(q) {
- if((res = mp_copy(a, q)) != MP_OKAY)
- return res;
- }
- if(r) {
- if((res = mp_copy(a, r)) != MP_OKAY)
- return res;
- }
- if(q) {
- s_mp_div_2d(q, d);
- }
- if(r) {
- s_mp_mod_2d(r, d);
- }
-
- return MP_OKAY;
-
-} /* end mp_div_2d() */
-
-/* }}} */
-
-/* {{{ mp_expt(a, b, c) */
-
-/*
- mp_expt(a, b, c)
-
- Compute c = a ** b, that is, raise a to the b power. Uses a
- standard iterative square-and-multiply technique.
- */
-
-mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
-{
- mp_int s, x;
- mp_err res;
- mp_digit d;
- int dig, bit;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if(mp_cmp_z(b) < 0)
- return MP_RANGE;
-
- if((res = mp_init(&s)) != MP_OKAY)
- return res;
-
- mp_set(&s, 1);
-
- if((res = mp_init_copy(&x, a)) != MP_OKAY)
- goto X;
-
- /* Loop over low-order digits in ascending order */
- for(dig = 0; dig < (USED(b) - 1); dig++) {
- d = DIGIT(b, dig);
-
- /* Loop over bits of each non-maximal digit */
- for(bit = 0; bit < DIGIT_BIT; bit++) {
- if(d & 1) {
- if((res = s_mp_mul(&s, &x)) != MP_OKAY)
- goto CLEANUP;
- }
-
- d >>= 1;
-
- if((res = s_mp_sqr(&x)) != MP_OKAY)
- goto CLEANUP;
- }
- }
-
- /* Consider now the last digit... */
- d = DIGIT(b, dig);
-
- while(d) {
- if(d & 1) {
- if((res = s_mp_mul(&s, &x)) != MP_OKAY)
- goto CLEANUP;
- }
-
- d >>= 1;
-
- if((res = s_mp_sqr(&x)) != MP_OKAY)
- goto CLEANUP;
- }
-
- if(mp_iseven(b))
- SIGN(&s) = SIGN(a);
-
- res = mp_copy(&s, c);
-
-CLEANUP:
- mp_clear(&x);
-X:
- mp_clear(&s);
-
- return res;
-
-} /* end mp_expt() */
-
-/* }}} */
-
-/* {{{ mp_2expt(a, k) */
-
-/* Compute a = 2^k */
-
-mp_err mp_2expt(mp_int *a, mp_digit k)
-{
- ARGCHK(a != NULL, MP_BADARG);
-
- return s_mp_2expt(a, k);
-
-} /* end mp_2expt() */
-
-/* }}} */
-
-/* {{{ mp_mod(a, m, c) */
-
-/*
- mp_mod(a, m, c)
-
- Compute c = a (mod m). Result will always be 0 <= c < m.
- */
-
-mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
-{
- mp_err res;
- int mag;
-
- ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
-
- if(SIGN(m) == NEG)
- return MP_RANGE;
-
- /*
- If |a| > m, we need to divide to get the remainder and take the
- absolute value.
-
- If |a| < m, we don't need to do any division, just copy and adjust
- the sign (if a is negative).
-
- If |a| == m, we can simply set the result to zero.
-
- This order is intended to minimize the average path length of the
- comparison chain on common workloads -- the most frequent cases are
- that |a| != m, so we do those first.
- */
- if((mag = s_mp_cmp(a, m)) > 0) {
- if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
- return res;
-
- if(SIGN(c) == NEG) {
- if((res = mp_add(c, m, c)) != MP_OKAY)
- return res;
- }
-
- } else if(mag < 0) {
- if((res = mp_copy(a, c)) != MP_OKAY)
- return res;
-
- if(mp_cmp_z(a) < 0) {
- if((res = mp_add(c, m, c)) != MP_OKAY)
- return res;
-
- }
-
- } else {
- mp_zero(c);
-
- }
-
- return MP_OKAY;
-
-} /* end mp_mod() */
-
-/* }}} */
-
-/* {{{ mp_mod_d(a, d, c) */
-
-/*
- mp_mod_d(a, d, c)
-
- Compute c = a (mod d). Result will always be 0 <= c < d
- */
-mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c)
-{
- mp_err res;
- mp_digit rem;
-
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
- if(s_mp_cmp_d(a, d) > 0) {
- if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
- return res;
-
- } else {
- if(SIGN(a) == NEG)
- rem = d - DIGIT(a, 0);
- else
- rem = DIGIT(a, 0);
- }
-
- if(c)
- *c = rem;
-
- return MP_OKAY;
-
-} /* end mp_mod_d() */
-
-/* }}} */
-
-/* {{{ mp_sqrt(a, b) */
-
-/*
- mp_sqrt(a, b)
-
- Compute the integer square root of a, and store the result in b.
- Uses an integer-arithmetic version of Newton's iterative linear
- approximation technique to determine this value; the result has the
- following two properties:
-
- b^2 <= a
- (b+1)^2 >= a
-
- It is a range error to pass a negative value.
- */
-mp_err mp_sqrt(const mp_int *a, mp_int *b)
-{
- mp_int x, t;
- mp_err res;
- mp_size used;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- /* Cannot take square root of a negative value */
- if(SIGN(a) == NEG)
- return MP_RANGE;
-
- /* Special cases for zero and one, trivial */
- if(mp_cmp_d(a, 1) <= 0)
- return mp_copy(a, b);
-
- /* Initialize the temporaries we'll use below */
- if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
- return res;
-
- /* Compute an initial guess for the iteration as a itself */
- if((res = mp_init_copy(&x, a)) != MP_OKAY)
- goto X;
-
- used = MP_USED(&x);
- if (used > 1) {
- s_mp_rshd(&x, used / 2);
- }
-
- for(;;) {
- /* t = (x * x) - a */
- mp_copy(&x, &t); /* can't fail, t is big enough for original x */
- if((res = mp_sqr(&t, &t)) != MP_OKAY ||
- (res = mp_sub(&t, a, &t)) != MP_OKAY)
- goto CLEANUP;
-
- /* t = t / 2x */
- s_mp_mul_2(&x);
- if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
- goto CLEANUP;
- s_mp_div_2(&x);
-
- /* Terminate the loop, if the quotient is zero */
- if(mp_cmp_z(&t) == MP_EQ)
- break;
-
- /* x = x - t */
- if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
- goto CLEANUP;
-
- }
-
- /* Copy result to output parameter */
- mp_sub_d(&x, 1, &x);
- s_mp_exch(&x, b);
-
- CLEANUP:
- mp_clear(&x);
- X:
- mp_clear(&t);
-
- return res;
-
-} /* end mp_sqrt() */
-
-/* }}} */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Modular arithmetic */
-
-#if MP_MODARITH
-/* {{{ mp_addmod(a, b, m, c) */
-
-/*
- mp_addmod(a, b, m, c)
-
- Compute c = (a + b) mod m
- */
-
-mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
-{
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
-
- if((res = mp_add(a, b, c)) != MP_OKAY)
- return res;
- if((res = mp_mod(c, m, c)) != MP_OKAY)
- return res;
-
- return MP_OKAY;
-
-}
-
-/* }}} */
-
-/* {{{ mp_submod(a, b, m, c) */
-
-/*
- mp_submod(a, b, m, c)
-
- Compute c = (a - b) mod m
- */
-
-mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
-{
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
-
- if((res = mp_sub(a, b, c)) != MP_OKAY)
- return res;
- if((res = mp_mod(c, m, c)) != MP_OKAY)
- return res;
-
- return MP_OKAY;
-
-}
-
-/* }}} */
-
-/* {{{ mp_mulmod(a, b, m, c) */
-
-/*
- mp_mulmod(a, b, m, c)
-
- Compute c = (a * b) mod m
- */
-
-mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
-{
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
-
- if((res = mp_mul(a, b, c)) != MP_OKAY)
- return res;
- if((res = mp_mod(c, m, c)) != MP_OKAY)
- return res;
-
- return MP_OKAY;
-
-}
-
-/* }}} */
-
-/* {{{ mp_sqrmod(a, m, c) */
-
-#if MP_SQUARE
-mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c)
-{
- mp_err res;
-
- ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
-
- if((res = mp_sqr(a, c)) != MP_OKAY)
- return res;
- if((res = mp_mod(c, m, c)) != MP_OKAY)
- return res;
-
- return MP_OKAY;
-
-} /* end mp_sqrmod() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_exptmod(a, b, m, c) */
-
-/*
- s_mp_exptmod(a, b, m, c)
-
- Compute c = (a ** b) mod m. Uses a standard square-and-multiply
- method with modular reductions at each step. (This is basically the
- same code as mp_expt(), except for the addition of the reductions)
-
- The modular reductions are done using Barrett's algorithm (see
- s_mp_reduce() below for details)
- */
-
-mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
-{
- mp_int s, x, mu;
- mp_err res;
- mp_digit d;
- int dig, bit;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
- return MP_RANGE;
-
- if((res = mp_init(&s)) != MP_OKAY)
- return res;
- if((res = mp_init_copy(&x, a)) != MP_OKAY ||
- (res = mp_mod(&x, m, &x)) != MP_OKAY)
- goto X;
- if((res = mp_init(&mu)) != MP_OKAY)
- goto MU;
-
- mp_set(&s, 1);
-
- /* mu = b^2k / m */
- s_mp_add_d(&mu, 1);
- s_mp_lshd(&mu, 2 * USED(m));
- if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
- goto CLEANUP;
-
- /* Loop over digits of b in ascending order, except highest order */
- for(dig = 0; dig < (USED(b) - 1); dig++) {
- d = DIGIT(b, dig);
-
- /* Loop over the bits of the lower-order digits */
- for(bit = 0; bit < DIGIT_BIT; bit++) {
- if(d & 1) {
- if((res = s_mp_mul(&s, &x)) != MP_OKAY)
- goto CLEANUP;
- if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
- goto CLEANUP;
- }
-
- d >>= 1;
-
- if((res = s_mp_sqr(&x)) != MP_OKAY)
- goto CLEANUP;
- if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
- goto CLEANUP;
- }
- }
-
- /* Now do the last digit... */
- d = DIGIT(b, dig);
-
- while(d) {
- if(d & 1) {
- if((res = s_mp_mul(&s, &x)) != MP_OKAY)
- goto CLEANUP;
- if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
- goto CLEANUP;
- }
-
- d >>= 1;
-
- if((res = s_mp_sqr(&x)) != MP_OKAY)
- goto CLEANUP;
- if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
- goto CLEANUP;
- }
-
- s_mp_exch(&s, c);
-
- CLEANUP:
- mp_clear(&mu);
- MU:
- mp_clear(&x);
- X:
- mp_clear(&s);
-
- return res;
-
-} /* end s_mp_exptmod() */
-
-/* }}} */
-
-/* {{{ mp_exptmod_d(a, d, m, c) */
-
-mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c)
-{
- mp_int s, x;
- mp_err res;
-
- ARGCHK(a != NULL && c != NULL, MP_BADARG);
-
- if((res = mp_init(&s)) != MP_OKAY)
- return res;
- if((res = mp_init_copy(&x, a)) != MP_OKAY)
- goto X;
-
- mp_set(&s, 1);
-
- while(d != 0) {
- if(d & 1) {
- if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
- (res = mp_mod(&s, m, &s)) != MP_OKAY)
- goto CLEANUP;
- }
-
- d /= 2;
-
- if((res = s_mp_sqr(&x)) != MP_OKAY ||
- (res = mp_mod(&x, m, &x)) != MP_OKAY)
- goto CLEANUP;
- }
-
- s_mp_exch(&s, c);
-
-CLEANUP:
- mp_clear(&x);
-X:
- mp_clear(&s);
-
- return res;
-
-} /* end mp_exptmod_d() */
-
-/* }}} */
-#endif /* if MP_MODARITH */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Comparison functions */
-
-/* {{{ mp_cmp_z(a) */
-
-/*
- mp_cmp_z(a)
-
- Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0.
- */
-
-int mp_cmp_z(const mp_int *a)
-{
- if(SIGN(a) == NEG)
- return MP_LT;
- else if(USED(a) == 1 && DIGIT(a, 0) == 0)
- return MP_EQ;
- else
- return MP_GT;
-
-} /* end mp_cmp_z() */
-
-/* }}} */
-
-/* {{{ mp_cmp_d(a, d) */
-
-/*
- mp_cmp_d(a, d)
-
- Compare a <=> d. Returns <0 if a<d, 0 if a=d, >0 if a>d
- */
-
-int mp_cmp_d(const mp_int *a, mp_digit d)
-{
- ARGCHK(a != NULL, MP_EQ);
-
- if(SIGN(a) == NEG)
- return MP_LT;
-
- return s_mp_cmp_d(a, d);
-
-} /* end mp_cmp_d() */
-
-/* }}} */
-
-/* {{{ mp_cmp(a, b) */
-
-int mp_cmp(const mp_int *a, const mp_int *b)
-{
- ARGCHK(a != NULL && b != NULL, MP_EQ);
-
- if(SIGN(a) == SIGN(b)) {
- int mag;
-
- if((mag = s_mp_cmp(a, b)) == MP_EQ)
- return MP_EQ;
-
- if(SIGN(a) == ZPOS)
- return mag;
- else
- return -mag;
-
- } else if(SIGN(a) == ZPOS) {
- return MP_GT;
- } else {
- return MP_LT;
- }
-
-} /* end mp_cmp() */
-
-/* }}} */
-
-/* {{{ mp_cmp_mag(a, b) */
-
-/*
- mp_cmp_mag(a, b)
-
- Compares |a| <=> |b|, and returns an appropriate comparison result
- */
-
-int mp_cmp_mag(mp_int *a, mp_int *b)
-{
- ARGCHK(a != NULL && b != NULL, MP_EQ);
-
- return s_mp_cmp(a, b);
-
-} /* end mp_cmp_mag() */
-
-/* }}} */
-
-/* {{{ mp_cmp_int(a, z) */
-
-/*
- This just converts z to an mp_int, and uses the existing comparison
- routines. This is sort of inefficient, but it's not clear to me how
- frequently this wil get used anyway. For small positive constants,
- you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
- */
-int mp_cmp_int(const mp_int *a, long z)
-{
- mp_int tmp;
- int out;
-
- ARGCHK(a != NULL, MP_EQ);
-
- mp_init(&tmp); mp_set_int(&tmp, z);
- out = mp_cmp(a, &tmp);
- mp_clear(&tmp);
-
- return out;
-
-} /* end mp_cmp_int() */
-
-/* }}} */
-
-/* {{{ mp_isodd(a) */
-
-/*
- mp_isodd(a)
-
- Returns a true (non-zero) value if a is odd, false (zero) otherwise.
- */
-int mp_isodd(const mp_int *a)
-{
- ARGCHK(a != NULL, 0);
-
- return (int)(DIGIT(a, 0) & 1);
-
-} /* end mp_isodd() */
-
-/* }}} */
-
-/* {{{ mp_iseven(a) */
-
-int mp_iseven(const mp_int *a)
-{
- return !mp_isodd(a);
-
-} /* end mp_iseven() */
-
-/* }}} */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ Number theoretic functions */
-
-#if MP_NUMTH
-/* {{{ mp_gcd(a, b, c) */
-
-/*
- Like the old mp_gcd() function, except computes the GCD using the
- binary algorithm due to Josef Stein in 1961 (via Knuth).
- */
-mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
-{
- mp_err res;
- mp_int u, v, t;
- mp_size k = 0;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
- return MP_RANGE;
- if(mp_cmp_z(a) == MP_EQ) {
- return mp_copy(b, c);
- } else if(mp_cmp_z(b) == MP_EQ) {
- return mp_copy(a, c);
- }
-
- if((res = mp_init(&t)) != MP_OKAY)
- return res;
- if((res = mp_init_copy(&u, a)) != MP_OKAY)
- goto U;
- if((res = mp_init_copy(&v, b)) != MP_OKAY)
- goto V;
-
- SIGN(&u) = ZPOS;
- SIGN(&v) = ZPOS;
-
- /* Divide out common factors of 2 until at least 1 of a, b is even */
- while(mp_iseven(&u) && mp_iseven(&v)) {
- s_mp_div_2(&u);
- s_mp_div_2(&v);
- ++k;
- }
-
- /* Initialize t */
- if(mp_isodd(&u)) {
- if((res = mp_copy(&v, &t)) != MP_OKAY)
- goto CLEANUP;
-
- /* t = -v */
- if(SIGN(&v) == ZPOS)
- SIGN(&t) = NEG;
- else
- SIGN(&t) = ZPOS;
-
- } else {
- if((res = mp_copy(&u, &t)) != MP_OKAY)
- goto CLEANUP;
-
- }
-
- for(;;) {
- while(mp_iseven(&t)) {
- s_mp_div_2(&t);
- }
-
- if(mp_cmp_z(&t) == MP_GT) {
- if((res = mp_copy(&t, &u)) != MP_OKAY)
- goto CLEANUP;
-
- } else {
- if((res = mp_copy(&t, &v)) != MP_OKAY)
- goto CLEANUP;
-
- /* v = -t */
- if(SIGN(&t) == ZPOS)
- SIGN(&v) = NEG;
- else
- SIGN(&v) = ZPOS;
- }
-
- if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
- goto CLEANUP;
-
- if(s_mp_cmp_d(&t, 0) == MP_EQ)
- break;
- }
-
- s_mp_2expt(&v, k); /* v = 2^k */
- res = mp_mul(&u, &v, c); /* c = u * v */
-
- CLEANUP:
- mp_clear(&v);
- V:
- mp_clear(&u);
- U:
- mp_clear(&t);
-
- return res;
-
-} /* end mp_gcd() */
-
-/* }}} */
-
-/* {{{ mp_lcm(a, b, c) */
-
-/* We compute the least common multiple using the rule:
-
- ab = [a, b](a, b)
-
- ... by computing the product, and dividing out the gcd.
- */
-
-mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
-{
- mp_int gcd, prod;
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- /* Set up temporaries */
- if((res = mp_init(&gcd)) != MP_OKAY)
- return res;
- if((res = mp_init(&prod)) != MP_OKAY)
- goto GCD;
-
- if((res = mp_mul(a, b, &prod)) != MP_OKAY)
- goto CLEANUP;
- if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
- goto CLEANUP;
-
- res = mp_div(&prod, &gcd, c, NULL);
-
- CLEANUP:
- mp_clear(&prod);
- GCD:
- mp_clear(&gcd);
-
- return res;
-
-} /* end mp_lcm() */
-
-/* }}} */
-
-/* {{{ mp_xgcd(a, b, g, x, y) */
-
-/*
- mp_xgcd(a, b, g, x, y)
-
- Compute g = (a, b) and values x and y satisfying Bezout's identity
- (that is, ax + by = g). This uses the binary extended GCD algorithm
- based on the Stein algorithm used for mp_gcd()
- See algorithm 14.61 in Handbook of Applied Cryptogrpahy.
- */
-
-mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y)
-{
- mp_int gx, xc, yc, u, v, A, B, C, D;
- mp_int *clean[9];
- mp_err res;
- int last = -1;
-
- if(mp_cmp_z(b) == 0)
- return MP_RANGE;
-
- /* Initialize all these variables we need */
- MP_CHECKOK( mp_init(&u) );
- clean[++last] = &u;
- MP_CHECKOK( mp_init(&v) );
- clean[++last] = &v;
- MP_CHECKOK( mp_init(&gx) );
- clean[++last] = &gx;
- MP_CHECKOK( mp_init(&A) );
- clean[++last] = &A;
- MP_CHECKOK( mp_init(&B) );
- clean[++last] = &B;
- MP_CHECKOK( mp_init(&C) );
- clean[++last] = &C;
- MP_CHECKOK( mp_init(&D) );
- clean[++last] = &D;
- MP_CHECKOK( mp_init_copy(&xc, a) );
- clean[++last] = &xc;
- mp_abs(&xc, &xc);
- MP_CHECKOK( mp_init_copy(&yc, b) );
- clean[++last] = &yc;
- mp_abs(&yc, &yc);
-
- mp_set(&gx, 1);
-
- /* Divide by two until at least one of them is odd */
- while(mp_iseven(&xc) && mp_iseven(&yc)) {
- mp_size nx = mp_trailing_zeros(&xc);
- mp_size ny = mp_trailing_zeros(&yc);
- mp_size n = MP_MIN(nx, ny);
- s_mp_div_2d(&xc,n);
- s_mp_div_2d(&yc,n);
- MP_CHECKOK( s_mp_mul_2d(&gx,n) );
- }
-
- mp_copy(&xc, &u);
- mp_copy(&yc, &v);
- mp_set(&A, 1); mp_set(&D, 1);
-
- /* Loop through binary GCD algorithm */
- do {
- while(mp_iseven(&u)) {
- s_mp_div_2(&u);
-
- if(mp_iseven(&A) && mp_iseven(&B)) {
- s_mp_div_2(&A); s_mp_div_2(&B);
- } else {
- MP_CHECKOK( mp_add(&A, &yc, &A) );
- s_mp_div_2(&A);
- MP_CHECKOK( mp_sub(&B, &xc, &B) );
- s_mp_div_2(&B);
- }
- }
-
- while(mp_iseven(&v)) {
- s_mp_div_2(&v);
-
- if(mp_iseven(&C) && mp_iseven(&D)) {
- s_mp_div_2(&C); s_mp_div_2(&D);
- } else {
- MP_CHECKOK( mp_add(&C, &yc, &C) );
- s_mp_div_2(&C);
- MP_CHECKOK( mp_sub(&D, &xc, &D) );
- s_mp_div_2(&D);
- }
- }
-
- if(mp_cmp(&u, &v) >= 0) {
- MP_CHECKOK( mp_sub(&u, &v, &u) );
- MP_CHECKOK( mp_sub(&A, &C, &A) );
- MP_CHECKOK( mp_sub(&B, &D, &B) );
- } else {
- MP_CHECKOK( mp_sub(&v, &u, &v) );
- MP_CHECKOK( mp_sub(&C, &A, &C) );
- MP_CHECKOK( mp_sub(&D, &B, &D) );
- }
- } while (mp_cmp_z(&u) != 0);
-
- /* copy results to output */
- if(x)
- MP_CHECKOK( mp_copy(&C, x) );
-
- if(y)
- MP_CHECKOK( mp_copy(&D, y) );
-
- if(g)
- MP_CHECKOK( mp_mul(&gx, &v, g) );
-
- CLEANUP:
- while(last >= 0)
- mp_clear(clean[last--]);
-
- return res;
-
-} /* end mp_xgcd() */
-
-/* }}} */
-
-mp_size mp_trailing_zeros(const mp_int *mp)
-{
- mp_digit d;
- mp_size n = 0;
- int ix;
-
- if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
- return n;
-
- for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix)
- n += MP_DIGIT_BIT;
- if (!d)
- return 0; /* shouldn't happen, but ... */
-#if !defined(MP_USE_UINT_DIGIT)
- if (!(d & 0xffffffffU)) {
- d >>= 32;
- n += 32;
- }
-#endif
- if (!(d & 0xffffU)) {
- d >>= 16;
- n += 16;
- }
- if (!(d & 0xffU)) {
- d >>= 8;
- n += 8;
- }
- if (!(d & 0xfU)) {
- d >>= 4;
- n += 4;
- }
- if (!(d & 0x3U)) {
- d >>= 2;
- n += 2;
- }
- if (!(d & 0x1U)) {
- d >>= 1;
- n += 1;
- }
-#if MP_ARGCHK == 2
- assert(0 != (d & 1));
-#endif
- return n;
-}
-
-/* Given a and prime p, computes c and k such that a*c == 2**k (mod p).
-** Returns k (positive) or error (negative).
-** This technique from the paper "Fast Modular Reciprocals" (unpublished)
-** by Richard Schroeppel (a.k.a. Captain Nemo).
-*/
-mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
-{
- mp_err res;
- mp_err k = 0;
- mp_int d, f, g;
-
- ARGCHK(a && p && c, MP_BADARG);
-
- MP_DIGITS(&d) = 0;
- MP_DIGITS(&f) = 0;
- MP_DIGITS(&g) = 0;
- MP_CHECKOK( mp_init(&d) );
- MP_CHECKOK( mp_init_copy(&f, a) ); /* f = a */
- MP_CHECKOK( mp_init_copy(&g, p) ); /* g = p */
-
- mp_set(c, 1);
- mp_zero(&d);
-
- if (mp_cmp_z(&f) == 0) {
- res = MP_UNDEF;
- } else
- for (;;) {
- int diff_sign;
- while (mp_iseven(&f)) {
- mp_size n = mp_trailing_zeros(&f);
- if (!n) {
- res = MP_UNDEF;
- goto CLEANUP;
- }
- s_mp_div_2d(&f, n);
- MP_CHECKOK( s_mp_mul_2d(&d, n) );
- k += n;
- }
- if (mp_cmp_d(&f, 1) == MP_EQ) { /* f == 1 */
- res = k;
- break;
- }
- diff_sign = mp_cmp(&f, &g);
- if (diff_sign < 0) { /* f < g */
- s_mp_exch(&f, &g);
- s_mp_exch(c, &d);
- } else if (diff_sign == 0) { /* f == g */
- res = MP_UNDEF; /* a and p are not relatively prime */
- break;
- }
- if ((MP_DIGIT(&f,0) % 4) == (MP_DIGIT(&g,0) % 4)) {
- MP_CHECKOK( mp_sub(&f, &g, &f) ); /* f = f - g */
- MP_CHECKOK( mp_sub(c, &d, c) ); /* c = c - d */
- } else {
- MP_CHECKOK( mp_add(&f, &g, &f) ); /* f = f + g */
- MP_CHECKOK( mp_add(c, &d, c) ); /* c = c + d */
- }
- }
- if (res >= 0) {
- while (MP_SIGN(c) != MP_ZPOS) {
- MP_CHECKOK( mp_add(c, p, c) );
- }
- res = k;
- }
-
-CLEANUP:
- mp_clear(&d);
- mp_clear(&f);
- mp_clear(&g);
- return res;
-}
-
-/* Compute T = (P ** -1) mod MP_RADIX. Also works for 16-bit mp_digits.
-** This technique from the paper "Fast Modular Reciprocals" (unpublished)
-** by Richard Schroeppel (a.k.a. Captain Nemo).
-*/
-mp_digit s_mp_invmod_radix(mp_digit P)
-{
- mp_digit T = P;
- T *= 2 - (P * T);
- T *= 2 - (P * T);
- T *= 2 - (P * T);
- T *= 2 - (P * T);
-#if !defined(MP_USE_UINT_DIGIT)
- T *= 2 - (P * T);
- T *= 2 - (P * T);
-#endif
- return T;
-}
-
-/* Given c, k, and prime p, where a*c == 2**k (mod p),
-** Compute x = (a ** -1) mod p. This is similar to Montgomery reduction.
-** This technique from the paper "Fast Modular Reciprocals" (unpublished)
-** by Richard Schroeppel (a.k.a. Captain Nemo).
-*/
-mp_err s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int *x)
-{
- int k_orig = k;
- mp_digit r;
- mp_size ix;
- mp_err res;
-
- if (mp_cmp_z(c) < 0) { /* c < 0 */
- MP_CHECKOK( mp_add(c, p, x) ); /* x = c + p */
- } else {
- MP_CHECKOK( mp_copy(c, x) ); /* x = c */
- }
-
- /* make sure x is large enough */
- ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1;
- ix = MP_MAX(ix, MP_USED(x));
- MP_CHECKOK( s_mp_pad(x, ix) );
-
- r = 0 - s_mp_invmod_radix(MP_DIGIT(p,0));
-
- for (ix = 0; k > 0; ix++) {
- int j = MP_MIN(k, MP_DIGIT_BIT);
- mp_digit v = r * MP_DIGIT(x, ix);
- if (j < MP_DIGIT_BIT) {
- v &= ((mp_digit)1 << j) - 1; /* v = v mod (2 ** j) */
- }
- s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */
- k -= j;
- }
- s_mp_clamp(x);
- s_mp_div_2d(x, k_orig);
- res = MP_OKAY;
-
-CLEANUP:
- return res;
-}
-
-/* compute mod inverse using Schroeppel's method, only if m is odd */
-mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)
-{
- int k;
- mp_err res;
- mp_int x;
-
- ARGCHK(a && m && c, MP_BADARG);
-
- if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
- return MP_RANGE;
- if (mp_iseven(m))
- return MP_UNDEF;
-
- MP_DIGITS(&x) = 0;
-
- if (a == c) {
- if ((res = mp_init_copy(&x, a)) != MP_OKAY)
- return res;
- if (a == m)
- m = &x;
- a = &x;
- } else if (m == c) {
- if ((res = mp_init_copy(&x, m)) != MP_OKAY)
- return res;
- m = &x;
- } else {
- MP_DIGITS(&x) = 0;
- }
-
- MP_CHECKOK( s_mp_almost_inverse(a, m, c) );
- k = res;
- MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );
-CLEANUP:
- mp_clear(&x);
- return res;
-}
-
-/* Known good algorithm for computing modular inverse. But slow. */
-mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
-{
- mp_int g, x;
- mp_err res;
-
- ARGCHK(a && m && c, MP_BADARG);
-
- if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
- return MP_RANGE;
-
- MP_DIGITS(&g) = 0;
- MP_DIGITS(&x) = 0;
- MP_CHECKOK( mp_init(&x) );
- MP_CHECKOK( mp_init(&g) );
-
- MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) );
-
- if (mp_cmp_d(&g, 1) != MP_EQ) {
- res = MP_UNDEF;
- goto CLEANUP;
- }
-
- res = mp_mod(&x, m, c);
- SIGN(c) = SIGN(a);
-
-CLEANUP:
- mp_clear(&x);
- mp_clear(&g);
-
- return res;
-}
-
-/* modular inverse where modulus is 2**k. */
-/* c = a**-1 mod 2**k */
-mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c)
-{
- mp_err res;
- mp_size ix = k + 4;
- mp_int t0, t1, val, tmp, two2k;
-
- static const mp_digit d2 = 2;
- static const mp_int two = { MP_ZPOS, 1, 1, (mp_digit *)&d2 };
-
- if (mp_iseven(a))
- return MP_UNDEF;
- if (k <= MP_DIGIT_BIT) {
- mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0));
- if (k < MP_DIGIT_BIT)
- i &= ((mp_digit)1 << k) - (mp_digit)1;
- mp_set(c, i);
- return MP_OKAY;
- }
- MP_DIGITS(&t0) = 0;
- MP_DIGITS(&t1) = 0;
- MP_DIGITS(&val) = 0;
- MP_DIGITS(&tmp) = 0;
- MP_DIGITS(&two2k) = 0;
- MP_CHECKOK( mp_init_copy(&val, a) );
- s_mp_mod_2d(&val, k);
- MP_CHECKOK( mp_init_copy(&t0, &val) );
- MP_CHECKOK( mp_init_copy(&t1, &t0) );
- MP_CHECKOK( mp_init(&tmp) );
- MP_CHECKOK( mp_init(&two2k) );
- MP_CHECKOK( s_mp_2expt(&two2k, k) );
- do {
- MP_CHECKOK( mp_mul(&val, &t1, &tmp) );
- MP_CHECKOK( mp_sub(&two, &tmp, &tmp) );
- MP_CHECKOK( mp_mul(&t1, &tmp, &t1) );
- s_mp_mod_2d(&t1, k);
- while (MP_SIGN(&t1) != MP_ZPOS) {
- MP_CHECKOK( mp_add(&t1, &two2k, &t1) );
- }
- if (mp_cmp(&t1, &t0) == MP_EQ)
- break;
- MP_CHECKOK( mp_copy(&t1, &t0) );
- } while (--ix > 0);
- if (!ix) {
- res = MP_UNDEF;
- } else {
- mp_exch(c, &t1);
- }
-
-CLEANUP:
- mp_clear(&t0);
- mp_clear(&t1);
- mp_clear(&val);
- mp_clear(&tmp);
- mp_clear(&two2k);
- return res;
-}
-
-mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)
-{
- mp_err res;
- mp_size k;
- mp_int oddFactor, evenFactor; /* factors of the modulus */
- mp_int oddPart, evenPart; /* parts to combine via CRT. */
- mp_int C2, tmp1, tmp2;
-
- /*static const mp_digit d1 = 1; */
- /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */
-
- if ((res = s_mp_ispow2(m)) >= 0) {
- k = res;
- return s_mp_invmod_2d(a, k, c);
- }
- MP_DIGITS(&oddFactor) = 0;
- MP_DIGITS(&evenFactor) = 0;
- MP_DIGITS(&oddPart) = 0;
- MP_DIGITS(&evenPart) = 0;
- MP_DIGITS(&C2) = 0;
- MP_DIGITS(&tmp1) = 0;
- MP_DIGITS(&tmp2) = 0;
-
- MP_CHECKOK( mp_init_copy(&oddFactor, m) ); /* oddFactor = m */
- MP_CHECKOK( mp_init(&evenFactor) );
- MP_CHECKOK( mp_init(&oddPart) );
- MP_CHECKOK( mp_init(&evenPart) );
- MP_CHECKOK( mp_init(&C2) );
- MP_CHECKOK( mp_init(&tmp1) );
- MP_CHECKOK( mp_init(&tmp2) );
-
- k = mp_trailing_zeros(m);
- s_mp_div_2d(&oddFactor, k);
- MP_CHECKOK( s_mp_2expt(&evenFactor, k) );
-
- /* compute a**-1 mod oddFactor. */
- MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) );
- /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */
- MP_CHECKOK( s_mp_invmod_2d( a, k, &evenPart) );
-
- /* Use Chinese Remainer theorem to compute a**-1 mod m. */
- /* let m1 = oddFactor, v1 = oddPart,
- * let m2 = evenFactor, v2 = evenPart.
- */
-
- /* Compute C2 = m1**-1 mod m2. */
- MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k, &C2) );
-
- /* compute u = (v2 - v1)*C2 mod m2 */
- MP_CHECKOK( mp_sub(&evenPart, &oddPart, &tmp1) );
- MP_CHECKOK( mp_mul(&tmp1, &C2, &tmp2) );
- s_mp_mod_2d(&tmp2, k);
- while (MP_SIGN(&tmp2) != MP_ZPOS) {
- MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) );
- }
-
- /* compute answer = v1 + u*m1 */
- MP_CHECKOK( mp_mul(&tmp2, &oddFactor, c) );
- MP_CHECKOK( mp_add(&oddPart, c, c) );
- /* not sure this is necessary, but it's low cost if not. */
- MP_CHECKOK( mp_mod(c, m, c) );
-
-CLEANUP:
- mp_clear(&oddFactor);
- mp_clear(&evenFactor);
- mp_clear(&oddPart);
- mp_clear(&evenPart);
- mp_clear(&C2);
- mp_clear(&tmp1);
- mp_clear(&tmp2);
- return res;
-}
-
-
-/* {{{ mp_invmod(a, m, c) */
-
-/*
- mp_invmod(a, m, c)
-
- Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
- This is equivalent to the question of whether (a, m) = 1. If not,
- MP_UNDEF is returned, and there is no inverse.
- */
-
-mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
-{
-
- ARGCHK(a && m && c, MP_BADARG);
-
- if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
- return MP_RANGE;
-
- if (mp_isodd(m)) {
- return s_mp_invmod_odd_m(a, m, c);
- }
- if (mp_iseven(a))
- return MP_UNDEF; /* not invertable */
-
- return s_mp_invmod_even_m(a, m, c);
-
-} /* end mp_invmod() */
-
-/* }}} */
-#endif /* if MP_NUMTH */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ mp_print(mp, ofp) */
-
-#if MP_IOFUNC
-/*
- mp_print(mp, ofp)
-
- Print a textual representation of the given mp_int on the output
- stream 'ofp'. Output is generated using the internal radix.
- */
-
-void mp_print(mp_int *mp, FILE *ofp)
-{
- int ix;
-
- if(mp == NULL || ofp == NULL)
- return;
-
- fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);
-
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
- }
-
-} /* end mp_print() */
-
-#endif /* if MP_IOFUNC */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* {{{ More I/O Functions */
-
-/* {{{ mp_read_raw(mp, str, len) */
-
-/*
- mp_read_raw(mp, str, len)
-
- Read in a raw value (base 256) into the given mp_int
- */
-
-mp_err mp_read_raw(mp_int *mp, char *str, int len)
-{
- int ix;
- mp_err res;
- unsigned char *ustr = (unsigned char *)str;
-
- ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
-
- mp_zero(mp);
-
- /* Get sign from first byte */
- if(ustr[0])
- SIGN(mp) = NEG;
- else
- SIGN(mp) = ZPOS;
-
- /* Read the rest of the digits */
- for(ix = 1; ix < len; ix++) {
- if((res = mp_mul_d(mp, 256, mp)) != MP_OKAY)
- return res;
- if((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY)
- return res;
- }
-
- return MP_OKAY;
-
-} /* end mp_read_raw() */
-
-/* }}} */
-
-/* {{{ mp_raw_size(mp) */
-
-int mp_raw_size(mp_int *mp)
-{
- ARGCHK(mp != NULL, 0);
-
- return (USED(mp) * sizeof(mp_digit)) + 1;
-
-} /* end mp_raw_size() */
-
-/* }}} */
-
-/* {{{ mp_toraw(mp, str) */
-
-mp_err mp_toraw(mp_int *mp, char *str)
-{
- int ix, jx, pos = 1;
-
- ARGCHK(mp != NULL && str != NULL, MP_BADARG);
-
- str[0] = (char)SIGN(mp);
-
- /* Iterate over each digit... */
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- mp_digit d = DIGIT(mp, ix);
-
- /* Unpack digit bytes, high order first */
- for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
- str[pos++] = (char)(d >> (jx * CHAR_BIT));
- }
- }
-
- return MP_OKAY;
-
-} /* end mp_toraw() */
-
-/* }}} */
-
-/* {{{ mp_read_radix(mp, str, radix) */
-
-/*
- mp_read_radix(mp, str, radix)
-
- Read an integer from the given string, and set mp to the resulting
- value. The input is presumed to be in base 10. Leading non-digit
- characters are ignored, and the function reads until a non-digit
- character or the end of the string.
- */
-
-mp_err mp_read_radix(mp_int *mp, const char *str, int radix)
-{
- int ix = 0, val = 0;
- mp_err res;
- mp_sign sig = ZPOS;
-
- ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
- MP_BADARG);
-
- mp_zero(mp);
-
- /* Skip leading non-digit characters until a digit or '-' or '+' */
- while(str[ix] &&
- (s_mp_tovalue(str[ix], radix) < 0) &&
- str[ix] != '-' &&
- str[ix] != '+') {
- ++ix;
- }
-
- if(str[ix] == '-') {
- sig = NEG;
- ++ix;
- } else if(str[ix] == '+') {
- sig = ZPOS; /* this is the default anyway... */
- ++ix;
- }
-
- while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
- if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
- return res;
- if((res = s_mp_add_d(mp, val)) != MP_OKAY)
- return res;
- ++ix;
- }
-
- if(s_mp_cmp_d(mp, 0) == MP_EQ)
- SIGN(mp) = ZPOS;
- else
- SIGN(mp) = sig;
-
- return MP_OKAY;
-
-} /* end mp_read_radix() */
-
-mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix)
-{
- int radix = default_radix;
- int cx;
- mp_sign sig = ZPOS;
- mp_err res;
-
- /* Skip leading non-digit characters until a digit or '-' or '+' */
- while ((cx = *str) != 0 &&
- (s_mp_tovalue(cx, radix) < 0) &&
- cx != '-' &&
- cx != '+') {
- ++str;
- }
-
- if (cx == '-') {
- sig = NEG;
- ++str;
- } else if (cx == '+') {
- sig = ZPOS; /* this is the default anyway... */
- ++str;
- }
-
- if (str[0] == '0') {
- if ((str[1] | 0x20) == 'x') {
- radix = 16;
- str += 2;
- } else {
- radix = 8;
- str++;
- }
- }
- res = mp_read_radix(a, str, radix);
- if (res == MP_OKAY) {
- MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig;
- }
- return res;
-}
-
-/* }}} */
-
-/* {{{ mp_radix_size(mp, radix) */
-
-int mp_radix_size(mp_int *mp, int radix)
-{
- int bits;
-
- if(!mp || radix < 2 || radix > MAX_RADIX)
- return 0;
-
- bits = USED(mp) * DIGIT_BIT - 1;
-
- return s_mp_outlen(bits, radix);
-
-} /* end mp_radix_size() */
-
-/* }}} */
-
-/* {{{ mp_toradix(mp, str, radix) */
-
-mp_err mp_toradix(mp_int *mp, char *str, int radix)
-{
- int ix, pos = 0;
-
- ARGCHK(mp != NULL && str != NULL, MP_BADARG);
- ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
-
- if(mp_cmp_z(mp) == MP_EQ) {
- str[0] = '0';
- str[1] = '\0';
- } else {
- mp_err res;
- mp_int tmp;
- mp_sign sgn;
- mp_digit rem, rdx = (mp_digit)radix;
- char ch;
-
- if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
- return res;
-
- /* Save sign for later, and take absolute value */
- sgn = SIGN(&tmp); SIGN(&tmp) = ZPOS;
-
- /* Generate output digits in reverse order */
- while(mp_cmp_z(&tmp) != 0) {
- if((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) {
- mp_clear(&tmp);
- return res;
- }
-
- /* Generate digits, use capital letters */
- ch = s_mp_todigit(rem, radix, 0);
-
- str[pos++] = ch;
- }
-
- /* Add - sign if original value was negative */
- if(sgn == NEG)
- str[pos++] = '-';
-
- /* Add trailing NUL to end the string */
- str[pos--] = '\0';
-
- /* Reverse the digits and sign indicator */
- ix = 0;
- while(ix < pos) {
- char tmp = str[ix];
-
- str[ix] = str[pos];
- str[pos] = tmp;
- ++ix;
- --pos;
- }
-
- mp_clear(&tmp);
- }
-
- return MP_OKAY;
-
-} /* end mp_toradix() */
-
-/* }}} */
-
-/* {{{ mp_tovalue(ch, r) */
-
-int mp_tovalue(char ch, int r)
-{
- return s_mp_tovalue(ch, r);
-
-} /* end mp_tovalue() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ mp_strerror(ec) */
-
-/*
- mp_strerror(ec)
-
- Return a string describing the meaning of error code 'ec'. The
- string returned is allocated in static memory, so the caller should
- not attempt to modify or free the memory associated with this
- string.
- */
-const char *mp_strerror(mp_err ec)
-{
- int aec = (ec < 0) ? -ec : ec;
-
- /* Code values are negative, so the senses of these comparisons
- are accurate */
- if(ec < MP_LAST_CODE || ec > MP_OKAY) {
- return mp_err_string[0]; /* unknown error code */
- } else {
- return mp_err_string[aec + 1];
- }
-
-} /* end mp_strerror() */
-
-/* }}} */
-
-/*========================================================================*/
-/*------------------------------------------------------------------------*/
-/* Static function definitions (internal use only) */
-
-/* {{{ Memory management */
-
-/* {{{ s_mp_grow(mp, min) */
-
-/* Make sure there are at least 'min' digits allocated to mp */
-mp_err s_mp_grow(mp_int *mp, mp_size min)
-{
- if(min > ALLOC(mp)) {
- mp_digit *tmp;
-
- /* Set min to next nearest default precision block size */
- min = MP_ROUNDUP(min, s_mp_defprec);
-
- if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL)
- return MP_MEM;
-
- s_mp_copy(DIGITS(mp), tmp, USED(mp));
-
-#if MP_CRYPTO
- s_mp_setz(DIGITS(mp), ALLOC(mp));
-#endif
- s_mp_free(DIGITS(mp));
- DIGITS(mp) = tmp;
- ALLOC(mp) = min;
- }
-
- return MP_OKAY;
-
-} /* end s_mp_grow() */
-
-/* }}} */
-
-/* {{{ s_mp_pad(mp, min) */
-
-/* Make sure the used size of mp is at least 'min', growing if needed */
-mp_err s_mp_pad(mp_int *mp, mp_size min)
-{
- if(min > USED(mp)) {
- mp_err res;
-
- /* Make sure there is room to increase precision */
- if (min > ALLOC(mp)) {
- if ((res = s_mp_grow(mp, min)) != MP_OKAY)
- return res;
- } else {
- s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp));
- }
-
- /* Increase precision; should already be 0-filled */
- USED(mp) = min;
- }
-
- return MP_OKAY;
-
-} /* end s_mp_pad() */
-
-/* }}} */
-
-/* {{{ s_mp_setz(dp, count) */
-
-#if MP_MACRO == 0
-/* Set 'count' digits pointed to by dp to be zeroes */
-void s_mp_setz(mp_digit *dp, mp_size count)
-{
-#if MP_MEMSET == 0
- int ix;
-
- for(ix = 0; ix < count; ix++)
- dp[ix] = 0;
-#else
- memset(dp, 0, count * sizeof(mp_digit));
-#endif
-
-} /* end s_mp_setz() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_copy(sp, dp, count) */
-
-#if MP_MACRO == 0
-/* Copy 'count' digits from sp to dp */
-void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count)
-{
-#if MP_MEMCPY == 0
- int ix;
-
- for(ix = 0; ix < count; ix++)
- dp[ix] = sp[ix];
-#else
- memcpy(dp, sp, count * sizeof(mp_digit));
-#endif
- ++mp_copies;
-
-} /* end s_mp_copy() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_alloc(nb, ni) */
-
-#if MP_MACRO == 0
-/* Allocate ni records of nb bytes each, and return a pointer to that */
-void *s_mp_alloc(size_t nb, size_t ni)
-{
- ++mp_allocs;
- return calloc(nb, ni);
-
-} /* end s_mp_alloc() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_free(ptr) */
-
-#if MP_MACRO == 0
-/* Free the memory pointed to by ptr */
-void s_mp_free(void *ptr)
-{
- if(ptr) {
- ++mp_frees;
- free(ptr);
- }
-} /* end s_mp_free() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_clamp(mp) */
-
-#if MP_MACRO == 0
-/* Remove leading zeroes from the given value */
-void s_mp_clamp(mp_int *mp)
-{
- mp_size used = MP_USED(mp);
- while (used > 1 && DIGIT(mp, used - 1) == 0)
- --used;
- MP_USED(mp) = used;
-} /* end s_mp_clamp() */
-#endif
-
-/* }}} */
-
-/* {{{ s_mp_exch(a, b) */
-
-/* Exchange the data for a and b; (b, a) = (a, b) */
-void s_mp_exch(mp_int *a, mp_int *b)
-{
- mp_int tmp;
-
- tmp = *a;
- *a = *b;
- *b = tmp;
-
-} /* end s_mp_exch() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ Arithmetic helpers */
-
-/* {{{ s_mp_lshd(mp, p) */
-
-/*
- Shift mp leftward by p digits, growing if needed, and zero-filling
- the in-shifted digits at the right end. This is a convenient
- alternative to multiplication by powers of the radix
- */
-
-mp_err s_mp_lshd(mp_int *mp, mp_size p)
-{
- mp_err res;
- mp_size pos;
- int ix;
-
- if(p == 0)
- return MP_OKAY;
-
- if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0)
- return MP_OKAY;
-
- if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
- return res;
-
- pos = USED(mp) - 1;
-
- /* Shift all the significant figures over as needed */
- for(ix = pos - p; ix >= 0; ix--)
- DIGIT(mp, ix + p) = DIGIT(mp, ix);
-
- /* Fill the bottom digits with zeroes */
- for(ix = 0; ix < p; ix++)
- DIGIT(mp, ix) = 0;
-
- return MP_OKAY;
-
-} /* end s_mp_lshd() */
-
-/* }}} */
-
-/* {{{ s_mp_mul_2d(mp, d) */
-
-/*
- Multiply the integer by 2^d, where d is a number of bits. This
- amounts to a bitwise shift of the value.
- */
-mp_err s_mp_mul_2d(mp_int *mp, mp_digit d)
-{
- mp_err res;
- mp_digit dshift, bshift;
- mp_digit mask;
-
- ARGCHK(mp != NULL, MP_BADARG);
-
- dshift = d / MP_DIGIT_BIT;
- bshift = d % MP_DIGIT_BIT;
- /* bits to be shifted out of the top word */
- mask = ((mp_digit)~0 << (MP_DIGIT_BIT - bshift));
- mask &= MP_DIGIT(mp, MP_USED(mp) - 1);
-
- if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) )))
- return res;
-
- if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift)))
- return res;
-
- if (bshift) {
- mp_digit *pa = MP_DIGITS(mp);
- mp_digit *alim = pa + MP_USED(mp);
- mp_digit prev = 0;
-
- for (pa += dshift; pa < alim; ) {
- mp_digit x = *pa;
- *pa++ = (x << bshift) | prev;
- prev = x >> (DIGIT_BIT - bshift);
- }
- }
-
- s_mp_clamp(mp);
- return MP_OKAY;
-} /* end s_mp_mul_2d() */
-
-/* {{{ s_mp_rshd(mp, p) */
-
-/*
- Shift mp rightward by p digits. Maintains the invariant that
- digits above the precision are all zero. Digits shifted off the
- end are lost. Cannot fail.
- */
-
-void s_mp_rshd(mp_int *mp, mp_size p)
-{
- mp_size ix;
- mp_digit *src, *dst;
-
- if(p == 0)
- return;
-
- /* Shortcut when all digits are to be shifted off */
- if(p >= USED(mp)) {
- s_mp_setz(DIGITS(mp), ALLOC(mp));
- USED(mp) = 1;
- SIGN(mp) = ZPOS;
- return;
- }
-
- /* Shift all the significant figures over as needed */
- dst = MP_DIGITS(mp);
- src = dst + p;
- for (ix = USED(mp) - p; ix > 0; ix--)
- *dst++ = *src++;
-
- MP_USED(mp) -= p;
- /* Fill the top digits with zeroes */
- while (p-- > 0)
- *dst++ = 0;
-
-#if 0
- /* Strip off any leading zeroes */
- s_mp_clamp(mp);
-#endif
-
-} /* end s_mp_rshd() */
-
-/* }}} */
-
-/* {{{ s_mp_div_2(mp) */
-
-/* Divide by two -- take advantage of radix properties to do it fast */
-void s_mp_div_2(mp_int *mp)
-{
- s_mp_div_2d(mp, 1);
-
-} /* end s_mp_div_2() */
-
-/* }}} */
-
-/* {{{ s_mp_mul_2(mp) */
-
-mp_err s_mp_mul_2(mp_int *mp)
-{
- mp_digit *pd;
- int ix, used;
- mp_digit kin = 0;
-
- /* Shift digits leftward by 1 bit */
- used = MP_USED(mp);
- pd = MP_DIGITS(mp);
- for (ix = 0; ix < used; ix++) {
- mp_digit d = *pd;
- *pd++ = (d << 1) | kin;
- kin = (d >> (DIGIT_BIT - 1));
- }
-
- /* Deal with rollover from last digit */
- if (kin) {
- if (ix >= ALLOC(mp)) {
- mp_err res;
- if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
- return res;
- }
-
- DIGIT(mp, ix) = kin;
- USED(mp) += 1;
- }
-
- return MP_OKAY;
-
-} /* end s_mp_mul_2() */
-
-/* }}} */
-
-/* {{{ s_mp_mod_2d(mp, d) */
-
-/*
- Remainder the integer by 2^d, where d is a number of bits. This
- amounts to a bitwise AND of the value, and does not require the full
- division code
- */
-void s_mp_mod_2d(mp_int *mp, mp_digit d)
-{
- mp_size ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
- mp_size ix;
- mp_digit dmask;
-
- if(ndig >= USED(mp))
- return;
-
- /* Flush all the bits above 2^d in its digit */
- dmask = ((mp_digit)1 << nbit) - 1;
- DIGIT(mp, ndig) &= dmask;
-
- /* Flush all digits above the one with 2^d in it */
- for(ix = ndig + 1; ix < USED(mp); ix++)
- DIGIT(mp, ix) = 0;
-
- s_mp_clamp(mp);
-
-} /* end s_mp_mod_2d() */
-
-/* }}} */
-
-/* {{{ s_mp_div_2d(mp, d) */
-
-/*
- Divide the integer by 2^d, where d is a number of bits. This
- amounts to a bitwise shift of the value, and does not require the
- full division code (used in Barrett reduction, see below)
- */
-void s_mp_div_2d(mp_int *mp, mp_digit d)
-{
- int ix;
- mp_digit save, next, mask;
-
- s_mp_rshd(mp, d / DIGIT_BIT);
- d %= DIGIT_BIT;
- if (d) {
- mask = ((mp_digit)1 << d) - 1;
- save = 0;
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- next = DIGIT(mp, ix) & mask;
- DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d));
- save = next;
- }
- }
- s_mp_clamp(mp);
-
-} /* end s_mp_div_2d() */
-
-/* }}} */
-
-/* {{{ s_mp_norm(a, b, *d) */
-
-/*
- s_mp_norm(a, b, *d)
-
- Normalize a and b for division, where b is the divisor. In order
- that we might make good guesses for quotient digits, we want the
- leading digit of b to be at least half the radix, which we
- accomplish by multiplying a and b by a power of 2. The exponent
- (shift count) is placed in *pd, so that the remainder can be shifted
- back at the end of the division process.
- */
-
-mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd)
-{
- mp_digit d;
- mp_digit mask;
- mp_digit b_msd;
- mp_err res = MP_OKAY;
-
- d = 0;
- mask = DIGIT_MAX & ~(DIGIT_MAX >> 1); /* mask is msb of digit */
- b_msd = DIGIT(b, USED(b) - 1);
- while (!(b_msd & mask)) {
- b_msd <<= 1;
- ++d;
- }
-
- if (d) {
- MP_CHECKOK( s_mp_mul_2d(a, d) );
- MP_CHECKOK( s_mp_mul_2d(b, d) );
- }
-
- *pd = d;
-CLEANUP:
- return res;
-
-} /* end s_mp_norm() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ Primitive digit arithmetic */
-
-/* {{{ s_mp_add_d(mp, d) */
-
-/* Add d to |mp| in place */
-mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */
-{
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- mp_word w, k = 0;
- mp_size ix = 1;
-
- w = (mp_word)DIGIT(mp, 0) + d;
- DIGIT(mp, 0) = ACCUM(w);
- k = CARRYOUT(w);
-
- while(ix < USED(mp) && k) {
- w = (mp_word)DIGIT(mp, ix) + k;
- DIGIT(mp, ix) = ACCUM(w);
- k = CARRYOUT(w);
- ++ix;
- }
-
- if(k != 0) {
- mp_err res;
-
- if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
- return res;
-
- DIGIT(mp, ix) = (mp_digit)k;
- }
-
- return MP_OKAY;
-#else
- mp_digit * pmp = MP_DIGITS(mp);
- mp_digit sum, mp_i, carry = 0;
- mp_err res = MP_OKAY;
- int used = (int)MP_USED(mp);
-
- mp_i = *pmp;
- *pmp++ = sum = d + mp_i;
- carry = (sum < d);
- while (carry && --used > 0) {
- mp_i = *pmp;
- *pmp++ = sum = carry + mp_i;
- carry = !sum;
- }
- if (carry && !used) {
- /* mp is growing */
- used = MP_USED(mp);
- MP_CHECKOK( s_mp_pad(mp, used + 1) );
- MP_DIGIT(mp, used) = carry;
- }
-CLEANUP:
- return res;
-#endif
-} /* end s_mp_add_d() */
-
-/* }}} */
-
-/* {{{ s_mp_sub_d(mp, d) */
-
-/* Subtract d from |mp| in place, assumes |mp| > d */
-mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */
-{
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- mp_word w, b = 0;
- mp_size ix = 1;
-
- /* Compute initial subtraction */
- w = (RADIX + (mp_word)DIGIT(mp, 0)) - d;
- b = CARRYOUT(w) ? 0 : 1;
- DIGIT(mp, 0) = ACCUM(w);
-
- /* Propagate borrows leftward */
- while(b && ix < USED(mp)) {
- w = (RADIX + (mp_word)DIGIT(mp, ix)) - b;
- b = CARRYOUT(w) ? 0 : 1;
- DIGIT(mp, ix) = ACCUM(w);
- ++ix;
- }
-
- /* Remove leading zeroes */
- s_mp_clamp(mp);
-
- /* If we have a borrow out, it's a violation of the input invariant */
- if(b)
- return MP_RANGE;
- else
- return MP_OKAY;
-#else
- mp_digit *pmp = MP_DIGITS(mp);
- mp_digit mp_i, diff, borrow;
- mp_size used = MP_USED(mp);
-
- mp_i = *pmp;
- *pmp++ = diff = mp_i - d;
- borrow = (diff > mp_i);
- while (borrow && --used) {
- mp_i = *pmp;
- *pmp++ = diff = mp_i - borrow;
- borrow = (diff > mp_i);
- }
- s_mp_clamp(mp);
- return (borrow && !used) ? MP_RANGE : MP_OKAY;
-#endif
-} /* end s_mp_sub_d() */
-
-/* }}} */
-
-/* {{{ s_mp_mul_d(a, d) */
-
-/* Compute a = a * d, single digit multiplication */
-mp_err s_mp_mul_d(mp_int *a, mp_digit d)
-{
- mp_err res;
- mp_size used;
- int pow;
-
- if (!d) {
- mp_zero(a);
- return MP_OKAY;
- }
- if (d == 1)
- return MP_OKAY;
- if (0 <= (pow = s_mp_ispow2d(d))) {
- return s_mp_mul_2d(a, (mp_digit)pow);
- }
-
- used = MP_USED(a);
- MP_CHECKOK( s_mp_pad(a, used + 1) );
-
- s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a));
-
- s_mp_clamp(a);
-
-CLEANUP:
- return res;
-
-} /* end s_mp_mul_d() */
-
-/* }}} */
-
-/* {{{ s_mp_div_d(mp, d, r) */
-
-/*
- s_mp_div_d(mp, d, r)
-
- Compute the quotient mp = mp / d and remainder r = mp mod d, for a
- single digit d. If r is null, the remainder will be discarded.
- */
-
-mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
-{
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
- mp_word w = 0, q;
-#else
- mp_digit w, q;
-#endif
- int ix;
- mp_err res;
- mp_int quot;
- mp_int rem;
-
- if(d == 0)
- return MP_RANGE;
- if (d == 1) {
- if (r)
- *r = 0;
- return MP_OKAY;
- }
- /* could check for power of 2 here, but mp_div_d does that. */
- if (MP_USED(mp) == 1) {
- mp_digit n = MP_DIGIT(mp,0);
- mp_digit rem;
-
- q = n / d;
- rem = n % d;
- MP_DIGIT(mp,0) = q;
- if (r)
- *r = rem;
- return MP_OKAY;
- }
-
- MP_DIGITS(&rem) = 0;
- MP_DIGITS(&quot) = 0;
- /* Make room for the quotient */
- MP_CHECKOK( mp_init_size(&quot, USED(mp)) );
-
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- w = (w << DIGIT_BIT) | DIGIT(mp, ix);
-
- if(w >= d) {
- q = w / d;
- w = w % d;
- } else {
- q = 0;
- }
-
- s_mp_lshd(&quot, 1);
- DIGIT(&quot, 0) = (mp_digit)q;
- }
-#else
- {
- mp_digit p;
-#if !defined(MP_ASSEMBLY_DIV_2DX1D)
- mp_digit norm;
-#endif
-
- MP_CHECKOK( mp_init_copy(&rem, mp) );
-
-#if !defined(MP_ASSEMBLY_DIV_2DX1D)
- MP_DIGIT(&quot, 0) = d;
- MP_CHECKOK( s_mp_norm(&rem, &quot, &norm) );
- if (norm)
- d <<= norm;
- MP_DIGIT(&quot, 0) = 0;
-#endif
-
- p = 0;
- for (ix = USED(&rem) - 1; ix >= 0; ix--) {
- w = DIGIT(&rem, ix);
-
- if (p) {
- MP_CHECKOK( s_mpv_div_2dx1d(p, w, d, &q, &w) );
- } else if (w >= d) {
- q = w / d;
- w = w % d;
- } else {
- q = 0;
- }
-
- MP_CHECKOK( s_mp_lshd(&quot, 1) );
- DIGIT(&quot, 0) = q;
- p = w;
- }
-#if !defined(MP_ASSEMBLY_DIV_2DX1D)
- if (norm)
- w >>= norm;
-#endif
- }
-#endif
-
- /* Deliver the remainder, if desired */
- if(r)
- *r = (mp_digit)w;
-
- s_mp_clamp(&quot);
- mp_exch(&quot, mp);
-CLEANUP:
- mp_clear(&quot);
- mp_clear(&rem);
-
- return res;
-} /* end s_mp_div_d() */
-
-/* }}} */
-
-
-/* }}} */
-
-/* {{{ Primitive full arithmetic */
-
-/* {{{ s_mp_add(a, b) */
-
-/* Compute a = |a| + |b| */
-mp_err s_mp_add(mp_int *a, const mp_int *b) /* magnitude addition */
-{
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- mp_word w = 0;
-#else
- mp_digit d, sum, carry = 0;
-#endif
- mp_digit *pa, *pb;
- mp_size ix;
- mp_size used;
- mp_err res;
-
- /* Make sure a has enough precision for the output value */
- if((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY)
- return res;
-
- /*
- Add up all digits up to the precision of b. If b had initially
- the same precision as a, or greater, we took care of it by the
- padding step above, so there is no problem. If b had initially
- less precision, we'll have to make sure the carry out is duly
- propagated upward among the higher-order digits of the sum.
- */
- pa = MP_DIGITS(a);
- pb = MP_DIGITS(b);
- used = MP_USED(b);
- for(ix = 0; ix < used; ix++) {
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- w = w + *pa + *pb++;
- *pa++ = ACCUM(w);
- w = CARRYOUT(w);
-#else
- d = *pa;
- sum = d + *pb++;
- d = (sum < d); /* detect overflow */
- *pa++ = sum += carry;
- carry = d + (sum < carry); /* detect overflow */
-#endif
- }
-
- /* If we run out of 'b' digits before we're actually done, make
- sure the carries get propagated upward...
- */
- used = MP_USED(a);
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- while (w && ix < used) {
- w = w + *pa;
- *pa++ = ACCUM(w);
- w = CARRYOUT(w);
- ++ix;
- }
-#else
- while (carry && ix < used) {
- sum = carry + *pa;
- *pa++ = sum;
- carry = !sum;
- ++ix;
- }
-#endif
-
- /* If there's an overall carry out, increase precision and include
- it. We could have done this initially, but why touch the memory
- allocator unless we're sure we have to?
- */
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- if (w) {
- if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
- return res;
-
- DIGIT(a, ix) = (mp_digit)w;
- }
-#else
- if (carry) {
- if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
- return res;
-
- DIGIT(a, used) = carry;
- }
-#endif
-
- return MP_OKAY;
-} /* end s_mp_add() */
-
-/* }}} */
-
-/* Compute c = |a| + |b| */ /* magnitude addition */
-mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c)
-{
- mp_digit *pa, *pb, *pc;
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- mp_word w = 0;
-#else
- mp_digit sum, carry = 0, d;
-#endif
- mp_size ix;
- mp_size used;
- mp_err res;
-
- MP_SIGN(c) = MP_SIGN(a);
- if (MP_USED(a) < MP_USED(b)) {
- const mp_int *xch = a;
- a = b;
- b = xch;
- }
-
- /* Make sure a has enough precision for the output value */
- if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
- return res;
-
- /*
- Add up all digits up to the precision of b. If b had initially
- the same precision as a, or greater, we took care of it by the
- exchange step above, so there is no problem. If b had initially
- less precision, we'll have to make sure the carry out is duly
- propagated upward among the higher-order digits of the sum.
- */
- pa = MP_DIGITS(a);
- pb = MP_DIGITS(b);
- pc = MP_DIGITS(c);
- used = MP_USED(b);
- for (ix = 0; ix < used; ix++) {
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- w = w + *pa++ + *pb++;
- *pc++ = ACCUM(w);
- w = CARRYOUT(w);
-#else
- d = *pa++;
- sum = d + *pb++;
- d = (sum < d); /* detect overflow */
- *pc++ = sum += carry;
- carry = d + (sum < carry); /* detect overflow */
-#endif
- }
-
- /* If we run out of 'b' digits before we're actually done, make
- sure the carries get propagated upward...
- */
- for (used = MP_USED(a); ix < used; ++ix) {
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- w = w + *pa++;
- *pc++ = ACCUM(w);
- w = CARRYOUT(w);
-#else
- *pc++ = sum = carry + *pa++;
- carry = (sum < carry);
-#endif
- }
-
- /* If there's an overall carry out, increase precision and include
- it. We could have done this initially, but why touch the memory
- allocator unless we're sure we have to?
- */
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- if (w) {
- if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
- return res;
-
- DIGIT(c, used) = (mp_digit)w;
- ++used;
- }
-#else
- if (carry) {
- if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
- return res;
-
- DIGIT(c, used) = carry;
- ++used;
- }
-#endif
- MP_USED(c) = used;
- return MP_OKAY;
-}
-/* {{{ s_mp_add_offset(a, b, offset) */
-
-/* Compute a = |a| + ( |b| * (RADIX ** offset) ) */
-mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset)
-{
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- mp_word w, k = 0;
-#else
- mp_digit d, sum, carry = 0;
-#endif
- mp_size ib;
- mp_size ia;
- mp_size lim;
- mp_err res;
-
- /* Make sure a has enough precision for the output value */
- lim = MP_USED(b) + offset;
- if((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY)
- return res;
-
- /*
- Add up all digits up to the precision of b. If b had initially
- the same precision as a, or greater, we took care of it by the
- padding step above, so there is no problem. If b had initially
- less precision, we'll have to make sure the carry out is duly
- propagated upward among the higher-order digits of the sum.
- */
- lim = USED(b);
- for(ib = 0, ia = offset; ib < lim; ib++, ia++) {
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k;
- DIGIT(a, ia) = ACCUM(w);
- k = CARRYOUT(w);
-#else
- d = MP_DIGIT(a, ia);
- sum = d + MP_DIGIT(b, ib);
- d = (sum < d);
- MP_DIGIT(a,ia) = sum += carry;
- carry = d + (sum < carry);
-#endif
- }
-
- /* If we run out of 'b' digits before we're actually done, make
- sure the carries get propagated upward...
- */
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- for (lim = MP_USED(a); k && (ia < lim); ++ia) {
- w = (mp_word)DIGIT(a, ia) + k;
- DIGIT(a, ia) = ACCUM(w);
- k = CARRYOUT(w);
- }
-#else
- for (lim = MP_USED(a); carry && (ia < lim); ++ia) {
- d = MP_DIGIT(a, ia);
- MP_DIGIT(a,ia) = sum = d + carry;
- carry = (sum < d);
- }
-#endif
-
- /* If there's an overall carry out, increase precision and include
- it. We could have done this initially, but why touch the memory
- allocator unless we're sure we have to?
- */
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
- if(k) {
- if((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY)
- return res;
-
- DIGIT(a, ia) = (mp_digit)k;
- }
-#else
- if (carry) {
- if((res = s_mp_pad(a, lim + 1)) != MP_OKAY)
- return res;
-
- DIGIT(a, lim) = carry;
- }
-#endif
- s_mp_clamp(a);
-
- return MP_OKAY;
-
-} /* end s_mp_add_offset() */
-
-/* }}} */
-
-/* {{{ s_mp_sub(a, b) */
-
-/* Compute a = |a| - |b|, assumes |a| >= |b| */
-mp_err s_mp_sub(mp_int *a, const mp_int *b) /* magnitude subtract */
-{
- mp_digit *pa, *pb, *limit;
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- mp_sword w = 0;
-#else
- mp_digit d, diff, borrow = 0;
-#endif
-
- /*
- Subtract and propagate borrow. Up to the precision of b, this
- accounts for the digits of b; after that, we just make sure the
- carries get to the right place. This saves having to pad b out to
- the precision of a just to make the loops work right...
- */
- pa = MP_DIGITS(a);
- pb = MP_DIGITS(b);
- limit = pb + MP_USED(b);
- while (pb < limit) {
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- w = w + *pa - *pb++;
- *pa++ = ACCUM(w);
- w >>= MP_DIGIT_BIT;
-#else
- d = *pa;
- diff = d - *pb++;
- d = (diff > d); /* detect borrow */
- if (borrow && --diff == MP_DIGIT_MAX)
- ++d;
- *pa++ = diff;
- borrow = d;
-#endif
- }
- limit = MP_DIGITS(a) + MP_USED(a);
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- while (w && pa < limit) {
- w = w + *pa;
- *pa++ = ACCUM(w);
- w >>= MP_DIGIT_BIT;
- }
-#else
- while (borrow && pa < limit) {
- d = *pa;
- *pa++ = diff = d - borrow;
- borrow = (diff > d);
- }
-#endif
-
- /* Clobber any leading zeroes we created */
- s_mp_clamp(a);
-
- /*
- If there was a borrow out, then |b| > |a| in violation
- of our input invariant. We've already done the work,
- but we'll at least complain about it...
- */
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- return w ? MP_RANGE : MP_OKAY;
-#else
- return borrow ? MP_RANGE : MP_OKAY;
-#endif
-} /* end s_mp_sub() */
-
-/* }}} */
-
-/* Compute c = |a| - |b|, assumes |a| >= |b| */ /* magnitude subtract */
-mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c)
-{
- mp_digit *pa, *pb, *pc;
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- mp_sword w = 0;
-#else
- mp_digit d, diff, borrow = 0;
-#endif
- int ix, limit;
- mp_err res;
-
- MP_SIGN(c) = MP_SIGN(a);
-
- /* Make sure a has enough precision for the output value */
- if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
- return res;
-
- /*
- Subtract and propagate borrow. Up to the precision of b, this
- accounts for the digits of b; after that, we just make sure the
- carries get to the right place. This saves having to pad b out to
- the precision of a just to make the loops work right...
- */
- pa = MP_DIGITS(a);
- pb = MP_DIGITS(b);
- pc = MP_DIGITS(c);
- limit = MP_USED(b);
- for (ix = 0; ix < limit; ++ix) {
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- w = w + *pa++ - *pb++;
- *pc++ = ACCUM(w);
- w >>= MP_DIGIT_BIT;
-#else
- d = *pa++;
- diff = d - *pb++;
- d = (diff > d);
- if (borrow && --diff == MP_DIGIT_MAX)
- ++d;
- *pc++ = diff;
- borrow = d;
-#endif
- }
- for (limit = MP_USED(a); ix < limit; ++ix) {
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- w = w + *pa++;
- *pc++ = ACCUM(w);
- w >>= MP_DIGIT_BIT;
-#else
- d = *pa++;
- *pc++ = diff = d - borrow;
- borrow = (diff > d);
-#endif
- }
-
- /* Clobber any leading zeroes we created */
- MP_USED(c) = ix;
- s_mp_clamp(c);
-
- /*
- If there was a borrow out, then |b| > |a| in violation
- of our input invariant. We've already done the work,
- but we'll at least complain about it...
- */
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
- return w ? MP_RANGE : MP_OKAY;
-#else
- return borrow ? MP_RANGE : MP_OKAY;
-#endif
-}
-/* {{{ s_mp_mul(a, b) */
-
-/* Compute a = |a| * |b| */
-mp_err s_mp_mul(mp_int *a, const mp_int *b)
-{
- return mp_mul(a, b, a);
-} /* end s_mp_mul() */
-
-/* }}} */
-
-#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
-/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
-#define MP_MUL_DxD(a, b, Phi, Plo) \
- { unsigned long long product = (unsigned long long)a * b; \
- Plo = (mp_digit)product; \
- Phi = (mp_digit)(product >> MP_DIGIT_BIT); }
-#elif defined(OSF1)
-#define MP_MUL_DxD(a, b, Phi, Plo) \
- { Plo = asm ("mulq %a0, %a1, %v0", a, b);\
- Phi = asm ("umulh %a0, %a1, %v0", a, b); }
-#else
-#define MP_MUL_DxD(a, b, Phi, Plo) \
- { mp_digit a0b1, a1b0; \
- Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \
- Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \
- a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \
- a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \
- a1b0 += a0b1; \
- Phi += a1b0 >> MP_HALF_DIGIT_BIT; \
- if (a1b0 < a0b1) \
- Phi += MP_HALF_RADIX; \
- a1b0 <<= MP_HALF_DIGIT_BIT; \
- Plo += a1b0; \
- if (Plo < a1b0) \
- ++Phi; \
- }
-#endif
-
-#if !defined(MP_ASSEMBLY_MULTIPLY)
-/* c = a * b */
-void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
- mp_digit d = 0;
-
- /* Inner product: Digits of a */
- while (a_len--) {
- mp_word w = ((mp_word)b * *a++) + d;
- *c++ = ACCUM(w);
- d = CARRYOUT(w);
- }
- *c = d;
-#else
- mp_digit carry = 0;
- while (a_len--) {
- mp_digit a_i = *a++;
- mp_digit a0b0, a1b1;
-
- MP_MUL_DxD(a_i, b, a1b1, a0b0);
-
- a0b0 += carry;
- if (a0b0 < carry)
- ++a1b1;
- *c++ = a0b0;
- carry = a1b1;
- }
- *c = carry;
-#endif
-}
-
-/* c += a * b */
-void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,
- mp_digit *c)
-{
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
- mp_digit d = 0;
-
- /* Inner product: Digits of a */
- while (a_len--) {
- mp_word w = ((mp_word)b * *a++) + *c + d;
- *c++ = ACCUM(w);
- d = CARRYOUT(w);
- }
- *c = d;
-#else
- mp_digit carry = 0;
- while (a_len--) {
- mp_digit a_i = *a++;
- mp_digit a0b0, a1b1;
-
- MP_MUL_DxD(a_i, b, a1b1, a0b0);
-
- a0b0 += carry;
- if (a0b0 < carry)
- ++a1b1;
- a0b0 += a_i = *c;
- if (a0b0 < a_i)
- ++a1b1;
- *c++ = a0b0;
- carry = a1b1;
- }
- *c = carry;
-#endif
-}
-
-/* Presently, this is only used by the Montgomery arithmetic code. */
-/* c += a * b */
-void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
- mp_digit d = 0;
-
- /* Inner product: Digits of a */
- while (a_len--) {
- mp_word w = ((mp_word)b * *a++) + *c + d;
- *c++ = ACCUM(w);
- d = CARRYOUT(w);
- }
-
- while (d) {
- mp_word w = (mp_word)*c + d;
- *c++ = ACCUM(w);
- d = CARRYOUT(w);
- }
-#else
- mp_digit carry = 0;
- while (a_len--) {
- mp_digit a_i = *a++;
- mp_digit a0b0, a1b1;
-
- MP_MUL_DxD(a_i, b, a1b1, a0b0);
-
- a0b0 += carry;
- if (a0b0 < carry)
- ++a1b1;
-
- a0b0 += a_i = *c;
- if (a0b0 < a_i)
- ++a1b1;
-
- *c++ = a0b0;
- carry = a1b1;
- }
- while (carry) {
- mp_digit c_i = *c;
- carry += c_i;
- *c++ = carry;
- carry = carry < c_i;
- }
-#endif
-}
-#endif
-
-#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
-/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
-#define MP_SQR_D(a, Phi, Plo) \
- { unsigned long long square = (unsigned long long)a * a; \
- Plo = (mp_digit)square; \
- Phi = (mp_digit)(square >> MP_DIGIT_BIT); }
-#elif defined(OSF1)
-#define MP_SQR_D(a, Phi, Plo) \
- { Plo = asm ("mulq %a0, %a0, %v0", a);\
- Phi = asm ("umulh %a0, %a0, %v0", a); }
-#else
-#define MP_SQR_D(a, Phi, Plo) \
- { mp_digit Pmid; \
- Plo = (a & MP_HALF_DIGIT_MAX) * (a & MP_HALF_DIGIT_MAX); \
- Phi = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \
- Pmid = (a & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \
- Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1); \
- Pmid <<= (MP_HALF_DIGIT_BIT + 1); \
- Plo += Pmid; \
- if (Plo < Pmid) \
- ++Phi; \
- }
-#endif
-
-#if !defined(MP_ASSEMBLY_SQUARE)
-/* Add the squares of the digits of a to the digits of b. */
-void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
-{
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
- mp_word w;
- mp_digit d;
- mp_size ix;
-
- w = 0;
-#define ADD_SQUARE(n) \
- d = pa[n]; \
- w += (d * (mp_word)d) + ps[2*n]; \
- ps[2*n] = ACCUM(w); \
- w = (w >> DIGIT_BIT) + ps[2*n+1]; \
- ps[2*n+1] = ACCUM(w); \
- w = (w >> DIGIT_BIT)
-
- for (ix = a_len; ix >= 4; ix -= 4) {
- ADD_SQUARE(0);
- ADD_SQUARE(1);
- ADD_SQUARE(2);
- ADD_SQUARE(3);
- pa += 4;
- ps += 8;
- }
- if (ix) {
- ps += 2*ix;
- pa += ix;
- switch (ix) {
- case 3: ADD_SQUARE(-3); /* FALLTHRU */
- case 2: ADD_SQUARE(-2); /* FALLTHRU */
- case 1: ADD_SQUARE(-1); /* FALLTHRU */
- case 0: break;
- }
- }
- while (w) {
- w += *ps;
- *ps++ = ACCUM(w);
- w = (w >> DIGIT_BIT);
- }
-#else
- mp_digit carry = 0;
- while (a_len--) {
- mp_digit a_i = *pa++;
- mp_digit a0a0, a1a1;
-
- MP_SQR_D(a_i, a1a1, a0a0);
-
- /* here a1a1 and a0a0 constitute a_i ** 2 */
- a0a0 += carry;
- if (a0a0 < carry)
- ++a1a1;
-
- /* now add to ps */
- a0a0 += a_i = *ps;
- if (a0a0 < a_i)
- ++a1a1;
- *ps++ = a0a0;
- a1a1 += a_i = *ps;
- carry = (a1a1 < a_i);
- *ps++ = a1a1;
- }
- while (carry) {
- mp_digit s_i = *ps;
- carry += s_i;
- *ps++ = carry;
- carry = carry < s_i;
- }
-#endif
-}
-#endif
-
-#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) \
-&& !defined(MP_ASSEMBLY_DIV_2DX1D)
-/*
-** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
-** so its high bit is 1. This code is from NSPR.
-*/
-mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
- mp_digit *qp, mp_digit *rp)
-{
- mp_digit d1, d0, q1, q0;
- mp_digit r1, r0, m;
-
- d1 = divisor >> MP_HALF_DIGIT_BIT;
- d0 = divisor & MP_HALF_DIGIT_MAX;
- r1 = Nhi % d1;
- q1 = Nhi / d1;
- m = q1 * d0;
- r1 = (r1 << MP_HALF_DIGIT_BIT) | (Nlo >> MP_HALF_DIGIT_BIT);
- if (r1 < m) {
- q1--, r1 += divisor;
- if (r1 >= divisor && r1 < m) {
- q1--, r1 += divisor;
- }
- }
- r1 -= m;
- r0 = r1 % d1;
- q0 = r1 / d1;
- m = q0 * d0;
- r0 = (r0 << MP_HALF_DIGIT_BIT) | (Nlo & MP_HALF_DIGIT_MAX);
- if (r0 < m) {
- q0--, r0 += divisor;
- if (r0 >= divisor && r0 < m) {
- q0--, r0 += divisor;
- }
- }
- if (qp)
- *qp = (q1 << MP_HALF_DIGIT_BIT) | q0;
- if (rp)
- *rp = r0 - m;
- return MP_OKAY;
-}
-#endif
-
-#if MP_SQUARE
-/* {{{ s_mp_sqr(a) */
-
-mp_err s_mp_sqr(mp_int *a)
-{
- mp_err res;
- mp_int tmp;
-
- if((res = mp_init_size(&tmp, 2 * USED(a))) != MP_OKAY)
- return res;
- res = mp_sqr(a, &tmp);
- if (res == MP_OKAY) {
- s_mp_exch(&tmp, a);
- }
- mp_clear(&tmp);
- return res;
-}
-
-/* }}} */
-#endif
-
-/* {{{ s_mp_div(a, b) */
-
-/*
- s_mp_div(a, b)
-
- Compute a = a / b and b = a mod b. Assumes b > a.
- */
-
-mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
- mp_int *div, /* i: divisor */
- mp_int *quot) /* i: 0; o: quotient */
-{
- mp_int part, t;
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
- mp_word q_msd;
-#else
- mp_digit q_msd;
-#endif
- mp_err res;
- mp_digit d;
- mp_digit div_msd;
- int ix;
-
- if(mp_cmp_z(div) == 0)
- return MP_RANGE;
-
- DIGITS(&t) = 0;
- /* Shortcut if divisor is power of two */
- if((ix = s_mp_ispow2(div)) >= 0) {
- MP_CHECKOK( mp_copy(rem, quot) );
- s_mp_div_2d(quot, (mp_digit)ix);
- s_mp_mod_2d(rem, (mp_digit)ix);
-
- return MP_OKAY;
- }
-
- MP_SIGN(rem) = ZPOS;
- MP_SIGN(div) = ZPOS;
-
- /* A working temporary for division */
- MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem)));
-
- /* Normalize to optimize guessing */
- MP_CHECKOK( s_mp_norm(rem, div, &d) );
-
- part = *rem;
-
- /* Perform the division itself...woo! */
- MP_USED(quot) = MP_ALLOC(quot);
-
- /* Find a partial substring of rem which is at least div */
- /* If we didn't find one, we're finished dividing */
- while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
- int i;
- int unusedRem;
-
- unusedRem = MP_USED(rem) - MP_USED(div);
- MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
- MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem;
- MP_USED(&part) = MP_USED(div);
- if (s_mp_cmp(&part, div) < 0) {
- -- unusedRem;
-#if MP_ARGCHK == 2
- assert(unusedRem >= 0);
-#endif
- -- MP_DIGITS(&part);
- ++ MP_USED(&part);
- ++ MP_ALLOC(&part);
- }
-
- /* Compute a guess for the next quotient digit */
- q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
- div_msd = MP_DIGIT(div, MP_USED(div) - 1);
- if (q_msd >= div_msd) {
- q_msd = 1;
- } else if (MP_USED(&part) > 1) {
-#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
- q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
- q_msd /= div_msd;
- if (q_msd == RADIX)
- --q_msd;
-#else
- mp_digit r;
- MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
- div_msd, &q_msd, &r) );
-#endif
- } else {
- q_msd = 0;
- }
-#if MP_ARGCHK == 2
- assert(q_msd > 0); /* This case should never occur any more. */
-#endif
- if (q_msd <= 0)
- break;
-
- /* See what that multiplies out to */
- mp_copy(div, &t);
- MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) );
-
- /*
- If it's too big, back it off. We should not have to do this
- more than once, or, in rare cases, twice. Knuth describes a
- method by which this could be reduced to a maximum of once, but
- I didn't implement that here.
- * When using s_mpv_div_2dx1d, we may have to do this 3 times.
- */
- for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
- --q_msd;
- s_mp_sub(&t, div); /* t -= div */
- }
- if (i < 0) {
- res = MP_RANGE;
- goto CLEANUP;
- }
-
- /* At this point, q_msd should be the right next digit */
- MP_CHECKOK( s_mp_sub(&part, &t) ); /* part -= t */
- s_mp_clamp(rem);
-
- /*
- Include the digit in the quotient. We allocated enough memory
- for any quotient we could ever possibly get, so we should not
- have to check for failures here
- */
- MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd;
- }
-
- /* Denormalize remainder */
- if (d) {
- s_mp_div_2d(rem, d);
- }
-
- s_mp_clamp(quot);
-
-CLEANUP:
- mp_clear(&t);
-
- return res;
-
-} /* end s_mp_div() */
-
-
-/* }}} */
-
-/* {{{ s_mp_2expt(a, k) */
-
-mp_err s_mp_2expt(mp_int *a, mp_digit k)
-{
- mp_err res;
- mp_size dig, bit;
-
- dig = k / DIGIT_BIT;
- bit = k % DIGIT_BIT;
-
- mp_zero(a);
- if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
- return res;
-
- DIGIT(a, dig) |= ((mp_digit)1 << bit);
-
- return MP_OKAY;
-
-} /* end s_mp_2expt() */
-
-/* }}} */
-
-/* {{{ s_mp_reduce(x, m, mu) */
-
-/*
- Compute Barrett reduction, x (mod m), given a precomputed value for
- mu = b^2k / m, where b = RADIX and k = #digits(m). This should be
- faster than straight division, when many reductions by the same
- value of m are required (such as in modular exponentiation). This
- can nearly halve the time required to do modular exponentiation,
- as compared to using the full integer divide to reduce.
-
- This algorithm was derived from the _Handbook of Applied
- Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
- pp. 603-604.
- */
-
-mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
-{
- mp_int q;
- mp_err res;
-
- if((res = mp_init_copy(&q, x)) != MP_OKAY)
- return res;
-
- s_mp_rshd(&q, USED(m) - 1); /* q1 = x / b^(k-1) */
- s_mp_mul(&q, mu); /* q2 = q1 * mu */
- s_mp_rshd(&q, USED(m) + 1); /* q3 = q2 / b^(k+1) */
-
- /* x = x mod b^(k+1), quick (no division) */
- s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1));
-
- /* q = q * m mod b^(k+1), quick (no division) */
- s_mp_mul(&q, m);
- s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1));
-
- /* x = x - q */
- if((res = mp_sub(x, &q, x)) != MP_OKAY)
- goto CLEANUP;
-
- /* If x < 0, add b^(k+1) to it */
- if(mp_cmp_z(x) < 0) {
- mp_set(&q, 1);
- if((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY)
- goto CLEANUP;
- if((res = mp_add(x, &q, x)) != MP_OKAY)
- goto CLEANUP;
- }
-
- /* Back off if it's too big */
- while(mp_cmp(x, m) >= 0) {
- if((res = s_mp_sub(x, m)) != MP_OKAY)
- break;
- }
-
- CLEANUP:
- mp_clear(&q);
-
- return res;
-
-} /* end s_mp_reduce() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ Primitive comparisons */
-
-/* {{{ s_mp_cmp(a, b) */
-
-/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b */
-int s_mp_cmp(const mp_int *a, const mp_int *b)
-{
- mp_size used_a = MP_USED(a);
- {
- mp_size used_b = MP_USED(b);
-
- if (used_a > used_b)
- goto IS_GT;
- if (used_a < used_b)
- goto IS_LT;
- }
- {
- mp_digit *pa, *pb;
- mp_digit da = 0, db = 0;
-
-#define CMP_AB(n) if ((da = pa[n]) != (db = pb[n])) goto done
-
- pa = MP_DIGITS(a) + used_a;
- pb = MP_DIGITS(b) + used_a;
- while (used_a >= 4) {
- pa -= 4;
- pb -= 4;
- used_a -= 4;
- CMP_AB(3);
- CMP_AB(2);
- CMP_AB(1);
- CMP_AB(0);
- }
- while (used_a-- > 0 && ((da = *--pa) == (db = *--pb)))
- /* do nothing */;
-done:
- if (da > db)
- goto IS_GT;
- if (da < db)
- goto IS_LT;
- }
- return MP_EQ;
-IS_LT:
- return MP_LT;
-IS_GT:
- return MP_GT;
-} /* end s_mp_cmp() */
-
-/* }}} */
-
-/* {{{ s_mp_cmp_d(a, d) */
-
-/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d */
-int s_mp_cmp_d(const mp_int *a, mp_digit d)
-{
- if(USED(a) > 1)
- return MP_GT;
-
- if(DIGIT(a, 0) < d)
- return MP_LT;
- else if(DIGIT(a, 0) > d)
- return MP_GT;
- else
- return MP_EQ;
-
-} /* end s_mp_cmp_d() */
-
-/* }}} */
-
-/* {{{ s_mp_ispow2(v) */
-
-/*
- Returns -1 if the value is not a power of two; otherwise, it returns
- k such that v = 2^k, i.e. lg(v).
- */
-int s_mp_ispow2(const mp_int *v)
-{
- mp_digit d;
- int extra = 0, ix;
-
- ix = MP_USED(v) - 1;
- d = MP_DIGIT(v, ix); /* most significant digit of v */
-
- extra = s_mp_ispow2d(d);
- if (extra < 0 || ix == 0)
- return extra;
-
- while (--ix >= 0) {
- if (DIGIT(v, ix) != 0)
- return -1; /* not a power of two */
- extra += MP_DIGIT_BIT;
- }
-
- return extra;
-
-} /* end s_mp_ispow2() */
-
-/* }}} */
-
-/* {{{ s_mp_ispow2d(d) */
-
-int s_mp_ispow2d(mp_digit d)
-{
- if ((d != 0) && ((d & (d-1)) == 0)) { /* d is a power of 2 */
- int pow = 0;
-#if defined (MP_USE_UINT_DIGIT)
- if (d & 0xffff0000U)
- pow += 16;
- if (d & 0xff00ff00U)
- pow += 8;
- if (d & 0xf0f0f0f0U)
- pow += 4;
- if (d & 0xccccccccU)
- pow += 2;
- if (d & 0xaaaaaaaaU)
- pow += 1;
-#elif defined(MP_USE_LONG_LONG_DIGIT)
- if (d & 0xffffffff00000000ULL)
- pow += 32;
- if (d & 0xffff0000ffff0000ULL)
- pow += 16;
- if (d & 0xff00ff00ff00ff00ULL)
- pow += 8;
- if (d & 0xf0f0f0f0f0f0f0f0ULL)
- pow += 4;
- if (d & 0xccccccccccccccccULL)
- pow += 2;
- if (d & 0xaaaaaaaaaaaaaaaaULL)
- pow += 1;
-#elif defined(MP_USE_LONG_DIGIT)
- if (d & 0xffffffff00000000UL)
- pow += 32;
- if (d & 0xffff0000ffff0000UL)
- pow += 16;
- if (d & 0xff00ff00ff00ff00UL)
- pow += 8;
- if (d & 0xf0f0f0f0f0f0f0f0UL)
- pow += 4;
- if (d & 0xccccccccccccccccUL)
- pow += 2;
- if (d & 0xaaaaaaaaaaaaaaaaUL)
- pow += 1;
-#else
-#error "unknown type for mp_digit"
-#endif
- return pow;
- }
- return -1;
-
-} /* end s_mp_ispow2d() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ Primitive I/O helpers */
-
-/* {{{ s_mp_tovalue(ch, r) */
-
-/*
- Convert the given character to its digit value, in the given radix.
- If the given character is not understood in the given radix, -1 is
- returned. Otherwise the digit's numeric value is returned.
-
- The results will be odd if you use a radix < 2 or > 62, you are
- expected to know what you're up to.
- */
-int s_mp_tovalue(char ch, int r)
-{
- int val, xch;
-
- if(r > 36)
- xch = ch;
- else
- xch = toupper(ch);
-
- if(isdigit(xch))
- val = xch - '0';
- else if(isupper(xch))
- val = xch - 'A' + 10;
- else if(islower(xch))
- val = xch - 'a' + 36;
- else if(xch == '+')
- val = 62;
- else if(xch == '/')
- val = 63;
- else
- return -1;
-
- if(val < 0 || val >= r)
- return -1;
-
- return val;
-
-} /* end s_mp_tovalue() */
-
-/* }}} */
-
-/* {{{ s_mp_todigit(val, r, low) */
-
-/*
- Convert val to a radix-r digit, if possible. If val is out of range
- for r, returns zero. Otherwise, returns an ASCII character denoting
- the value in the given radix.
-
- The results may be odd if you use a radix < 2 or > 64, you are
- expected to know what you're doing.
- */
-
-char s_mp_todigit(mp_digit val, int r, int low)
-{
- char ch;
-
- if(val >= r)
- return 0;
-
- ch = s_dmap_1[val];
-
- if(r <= 36 && low)
- ch = tolower(ch);
-
- return ch;
-
-} /* end s_mp_todigit() */
-
-/* }}} */
-
-/* {{{ s_mp_outlen(bits, radix) */
-
-/*
- Return an estimate for how long a string is needed to hold a radix
- r representation of a number with 'bits' significant bits, plus an
- extra for a zero terminator (assuming C style strings here)
- */
-int s_mp_outlen(int bits, int r)
-{
- return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;
-
-} /* end s_mp_outlen() */
-
-/* }}} */
-
-/* }}} */
-
-/* {{{ mp_read_unsigned_octets(mp, str, len) */
-/* mp_read_unsigned_octets(mp, str, len)
- Read in a raw value (base 256) into the given mp_int
- No sign bit, number is positive. Leading zeros ignored.
- */
-
-mp_err
-mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)
-{
- int count;
- mp_err res;
- mp_digit d;
-
- ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
-
- mp_zero(mp);
-
- count = len % sizeof(mp_digit);
- if (count) {
- for (d = 0; count-- > 0; --len) {
- d = (d << 8) | *str++;
- }
- MP_DIGIT(mp, 0) = d;
- }
-
- /* Read the rest of the digits */
- for(; len > 0; len -= sizeof(mp_digit)) {
- for (d = 0, count = sizeof(mp_digit); count > 0; --count) {
- d = (d << 8) | *str++;
- }
- if (MP_EQ == mp_cmp_z(mp)) {
- if (!d)
- continue;
- } else {
- if((res = s_mp_lshd(mp, 1)) != MP_OKAY)
- return res;
- }
- MP_DIGIT(mp, 0) = d;
- }
- return MP_OKAY;
-} /* end mp_read_unsigned_octets() */
-/* }}} */
-
-/* {{{ mp_unsigned_octet_size(mp) */
-int
-mp_unsigned_octet_size(const mp_int *mp)
-{
- int bytes;
- int ix;
- mp_digit d = 0;
-
- ARGCHK(mp != NULL, MP_BADARG);
- ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG);
-
- bytes = (USED(mp) * sizeof(mp_digit));
-
- /* subtract leading zeros. */
- /* Iterate over each digit... */
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- d = DIGIT(mp, ix);
- if (d)
- break;
- bytes -= sizeof(d);
- }
- if (!bytes)
- return 1;
-
- /* Have MSD, check digit bytes, high order first */
- for(ix = sizeof(mp_digit) - 1; ix >= 0; ix--) {
- unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT));
- if (x)
- break;
- --bytes;
- }
- return bytes;
-} /* end mp_unsigned_octet_size() */
-/* }}} */
-
-/* {{{ mp_to_unsigned_octets(mp, str) */
-/* output a buffer of big endian octets no longer than specified. */
-mp_err
-mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
-{
- int ix, pos = 0;
- int bytes;
-
- ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
-
- bytes = mp_unsigned_octet_size(mp);
- ARGCHK(bytes >= 0 && bytes <= maxlen, MP_BADARG);
-
- /* Iterate over each digit... */
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- mp_digit d = DIGIT(mp, ix);
- int jx;
-
- /* Unpack digit bytes, high order first */
- for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
- unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
- if (!pos && !x) /* suppress leading zeros */
- continue;
- str[pos++] = x;
- }
- }
- if (!pos)
- str[pos++] = 0;
- return pos;
-} /* end mp_to_unsigned_octets() */
-/* }}} */
-
-/* {{{ mp_to_signed_octets(mp, str) */
-/* output a buffer of big endian octets no longer than specified. */
-mp_err
-mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
-{
- int ix, pos = 0;
- int bytes;
-
- ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
-
- bytes = mp_unsigned_octet_size(mp);
- ARGCHK(bytes >= 0 && bytes <= maxlen, MP_BADARG);
-
- /* Iterate over each digit... */
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- mp_digit d = DIGIT(mp, ix);
- int jx;
-
- /* Unpack digit bytes, high order first */
- for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
- unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
- if (!pos) {
- if (!x) /* suppress leading zeros */
- continue;
- if (x & 0x80) { /* add one leading zero to make output positive. */
- ARGCHK(bytes + 1 <= maxlen, MP_BADARG);
- if (bytes + 1 > maxlen)
- return MP_BADARG;
- str[pos++] = 0;
- }
- }
- str[pos++] = x;
- }
- }
- if (!pos)
- str[pos++] = 0;
- return pos;
-} /* end mp_to_signed_octets() */
-/* }}} */
-
-/* {{{ mp_to_fixlen_octets(mp, str) */
-/* output a buffer of big endian octets exactly as long as requested. */
-mp_err
-mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
-{
- int ix, pos = 0;
- int bytes;
-
- ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
-
- bytes = mp_unsigned_octet_size(mp);
- ARGCHK(bytes >= 0 && bytes <= length, MP_BADARG);
-
- /* place any needed leading zeros */
- for (;length > bytes; --length) {
- *str++ = 0;
- }
-
- /* Iterate over each digit... */
- for(ix = USED(mp) - 1; ix >= 0; ix--) {
- mp_digit d = DIGIT(mp, ix);
- int jx;
-
- /* Unpack digit bytes, high order first */
- for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
- unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
- if (!pos && !x) /* suppress leading zeros */
- continue;
- str[pos++] = x;
- }
- }
- if (!pos)
- str[pos++] = 0;
- return MP_OKAY;
-} /* end mp_to_fixlen_octets() */
-/* }}} */
-
-
-/*------------------------------------------------------------------------*/
-/* HERE THERE BE DRAGONS */
diff --git a/security/nss/lib/freebl/mpi/mpi.h b/security/nss/lib/freebl/mpi/mpi.h
deleted file mode 100644
index 4b814c984..000000000
--- a/security/nss/lib/freebl/mpi/mpi.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * mpi.h
- *
- * Arbitrary precision integer arithmetic library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _H_MPI_
-#define _H_MPI_
-
-#include "mpi-config.h"
-
-#if MP_DEBUG
-#undef MP_IOFUNC
-#define MP_IOFUNC 1
-#endif
-
-#if MP_IOFUNC
-#include <stdio.h>
-#include <ctype.h>
-#endif
-
-#include <limits.h>
-
-#if defined(BSDI)
-#undef ULLONG_MAX
-#endif
-
-#include <sys/types.h>
-
-#define MP_NEG 1
-#define MP_ZPOS 0
-
-#define MP_OKAY 0 /* no error, all is well */
-#define MP_YES 0 /* yes (boolean result) */
-#define MP_NO -1 /* no (boolean result) */
-#define MP_MEM -2 /* out of memory */
-#define MP_RANGE -3 /* argument out of range */
-#define MP_BADARG -4 /* invalid parameter */
-#define MP_UNDEF -5 /* answer is undefined */
-#define MP_LAST_CODE MP_UNDEF
-
-typedef unsigned int mp_sign;
-typedef unsigned int mp_size;
-typedef int mp_err;
-
-#define MP_32BIT_MAX 4294967295U
-
-#if !defined(ULONG_MAX)
-#error "ULONG_MAX not defined"
-#elif !defined(UINT_MAX)
-#error "UINT_MAX not defined"
-#elif !defined(USHRT_MAX)
-#error "USHRT_MAX not defined"
-#endif
-
-#if defined(ULONG_LONG_MAX) /* GCC, HPUX */
-#define MP_ULONG_LONG_MAX ULONG_LONG_MAX
-#elif defined(ULLONG_MAX) /* Solaris */
-#define MP_ULONG_LONG_MAX ULLONG_MAX
-/* MP_ULONG_LONG_MAX was defined to be ULLONG_MAX */
-#elif defined(ULONGLONG_MAX) /* IRIX, AIX */
-#define MP_ULONG_LONG_MAX ULONGLONG_MAX
-#endif
-
-/* We only use unsigned long for mp_digit iff long is more than 32 bits. */
-#if !defined(MP_USE_UINT_DIGIT) && ULONG_MAX > MP_32BIT_MAX
-typedef unsigned long mp_digit;
-#define MP_DIGIT_MAX ULONG_MAX
-#define MP_DIGIT_FMT "%016lX" /* printf() format for 1 digit */
-#define MP_HALF_DIGIT_MAX UINT_MAX
-#undef MP_NO_MP_WORD
-#define MP_NO_MP_WORD 1
-#undef MP_USE_LONG_DIGIT
-#define MP_USE_LONG_DIGIT 1
-#undef MP_USE_LONG_LONG_DIGIT
-
-#elif !defined(MP_USE_UINT_DIGIT) && defined(MP_ULONG_LONG_MAX)
-typedef unsigned long long mp_digit;
-#define MP_DIGIT_MAX MP_ULONG_LONG_MAX
-#define MP_DIGIT_FMT "%016llX" /* printf() format for 1 digit */
-#define MP_HALF_DIGIT_MAX UINT_MAX
-#undef MP_NO_MP_WORD
-#define MP_NO_MP_WORD 1
-#undef MP_USE_LONG_LONG_DIGIT
-#define MP_USE_LONG_LONG_DIGIT 1
-#undef MP_USE_LONG_DIGIT
-
-#else
-typedef unsigned int mp_digit;
-#define MP_DIGIT_MAX UINT_MAX
-#define MP_DIGIT_FMT "%08X" /* printf() format for 1 digit */
-#define MP_HALF_DIGIT_MAX USHRT_MAX
-#undef MP_USE_UINT_DIGIT
-#define MP_USE_UINT_DIGIT 1
-#undef MP_USE_LONG_LONG_DIGIT
-#undef MP_USE_LONG_DIGIT
-#endif
-
-#if !defined(MP_NO_MP_WORD)
-#if defined(MP_USE_UINT_DIGIT) && \
- (defined(MP_ULONG_LONG_MAX) || (ULONG_MAX > UINT_MAX))
-
-#if (ULONG_MAX > UINT_MAX)
-typedef unsigned long mp_word;
-typedef long mp_sword;
-#define MP_WORD_MAX ULONG_MAX
-
-#else
-typedef unsigned long long mp_word;
-typedef long long mp_sword;
-#define MP_WORD_MAX MP_ULONG_LONG_MAX
-#endif
-
-#else
-#define MP_NO_MP_WORD 1
-#endif
-#endif /* !defined(MP_NO_MP_WORD) */
-
-#if !defined(MP_WORD_MAX) && defined(MP_DEFINE_SMALL_WORD)
-typedef unsigned int mp_word;
-typedef int mp_sword;
-#define MP_WORD_MAX UINT_MAX
-#endif
-
-#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit))
-#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word))
-#define MP_RADIX (1+(mp_word)MP_DIGIT_MAX)
-
-#define MP_HALF_DIGIT_BIT (MP_DIGIT_BIT/2)
-#define MP_HALF_RADIX (1+(mp_digit)MP_HALF_DIGIT_MAX)
-/* MP_HALF_RADIX really ought to be called MP_SQRT_RADIX, but it's named
-** MP_HALF_RADIX because it's the radix for MP_HALF_DIGITs, and it's
-** consistent with the other _HALF_ names.
-*/
-
-
-/* Macros for accessing the mp_int internals */
-#define MP_SIGN(MP) ((MP)->sign)
-#define MP_USED(MP) ((MP)->used)
-#define MP_ALLOC(MP) ((MP)->alloc)
-#define MP_DIGITS(MP) ((MP)->dp)
-#define MP_DIGIT(MP,N) (MP)->dp[(N)]
-
-/* This defines the maximum I/O base (minimum is 2) */
-#define MP_MAX_RADIX 64
-
-typedef struct {
- mp_sign sign; /* sign of this quantity */
- mp_size alloc; /* how many digits allocated */
- mp_size used; /* how many digits used */
- mp_digit *dp; /* the digits themselves */
-} mp_int;
-
-/* Default precision */
-mp_size mp_get_prec(void);
-void mp_set_prec(mp_size prec);
-
-/* Memory management */
-mp_err mp_init(mp_int *mp);
-mp_err mp_init_size(mp_int *mp, mp_size prec);
-mp_err mp_init_copy(mp_int *mp, const mp_int *from);
-mp_err mp_copy(const mp_int *from, mp_int *to);
-void mp_exch(mp_int *mp1, mp_int *mp2);
-void mp_clear(mp_int *mp);
-void mp_zero(mp_int *mp);
-void mp_set(mp_int *mp, mp_digit d);
-mp_err mp_set_int(mp_int *mp, long z);
-#define mp_set_long(mp,z) mp_set_int(mp,z)
-mp_err mp_set_ulong(mp_int *mp, unsigned long z);
-
-/* Single digit arithmetic */
-mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b);
-mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b);
-mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b);
-mp_err mp_mul_2(const mp_int *a, mp_int *c);
-mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r);
-mp_err mp_div_2(const mp_int *a, mp_int *c);
-mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c);
-
-/* Sign manipulations */
-mp_err mp_abs(const mp_int *a, mp_int *b);
-mp_err mp_neg(const mp_int *a, mp_int *b);
-
-/* Full arithmetic */
-mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c);
-mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
-mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c);
-#if MP_SQUARE
-mp_err mp_sqr(const mp_int *a, mp_int *b);
-#else
-#define mp_sqr(a, b) mp_mul(a, a, b)
-#endif
-mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r);
-mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r);
-mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_2expt(mp_int *a, mp_digit k);
-mp_err mp_sqrt(const mp_int *a, mp_int *b);
-
-/* Modular arithmetic */
-#if MP_MODARITH
-mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c);
-mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c);
-mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
-mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
-mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
-#if MP_SQUARE
-mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c);
-#else
-#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
-#endif
-mp_err mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c);
-mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c);
-#endif /* MP_MODARITH */
-
-/* Comparisons */
-int mp_cmp_z(const mp_int *a);
-int mp_cmp_d(const mp_int *a, mp_digit d);
-int mp_cmp(const mp_int *a, const mp_int *b);
-int mp_cmp_mag(mp_int *a, mp_int *b);
-int mp_cmp_int(const mp_int *a, long z);
-int mp_isodd(const mp_int *a);
-int mp_iseven(const mp_int *a);
-
-/* Number theoretic */
-#if MP_NUMTH
-mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
-mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y);
-mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c);
-mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c);
-#endif /* end MP_NUMTH */
-
-/* Input and output */
-#if MP_IOFUNC
-void mp_print(mp_int *mp, FILE *ofp);
-#endif /* end MP_IOFUNC */
-
-/* Base conversion */
-mp_err mp_read_raw(mp_int *mp, char *str, int len);
-int mp_raw_size(mp_int *mp);
-mp_err mp_toraw(mp_int *mp, char *str);
-mp_err mp_read_radix(mp_int *mp, const char *str, int radix);
-mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix);
-int mp_radix_size(mp_int *mp, int radix);
-mp_err mp_toradix(mp_int *mp, char *str, int radix);
-int mp_tovalue(char ch, int r);
-
-#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
-#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
-#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
-#define mp_tohex(M, S) mp_toradix((M), (S), 16)
-
-/* Error strings */
-const char *mp_strerror(mp_err ec);
-
-/* Octet string conversion functions */
-mp_err mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len);
-int mp_unsigned_octet_size(const mp_int *mp);
-mp_err mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
-mp_err mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen);
-mp_err mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size len);
-
-/* Miscellaneous */
-mp_size mp_trailing_zeros(const mp_int *mp);
-void freebl_cpuid(unsigned long op, unsigned long *eax,
- unsigned long *ebx, unsigned long *ecx,
- unsigned long *edx);
-
-
-#define MP_CHECKOK(x) if (MP_OKAY > (res = (x))) goto CLEANUP
-#define MP_CHECKERR(x) if (MP_OKAY > (res = (x))) goto CLEANUP
-
-#if defined(MP_API_COMPATIBLE)
-#define NEG MP_NEG
-#define ZPOS MP_ZPOS
-#define DIGIT_MAX MP_DIGIT_MAX
-#define DIGIT_BIT MP_DIGIT_BIT
-#define DIGIT_FMT MP_DIGIT_FMT
-#define RADIX MP_RADIX
-#define MAX_RADIX MP_MAX_RADIX
-#define SIGN(MP) MP_SIGN(MP)
-#define USED(MP) MP_USED(MP)
-#define ALLOC(MP) MP_ALLOC(MP)
-#define DIGITS(MP) MP_DIGITS(MP)
-#define DIGIT(MP,N) MP_DIGIT(MP,N)
-
-#if MP_ARGCHK == 1
-#define ARGCHK(X,Y) {if(!(X)){return (Y);}}
-#elif MP_ARGCHK == 2
-#include <assert.h>
-#define ARGCHK(X,Y) assert(X)
-#else
-#define ARGCHK(X,Y) /* */
-#endif
-#endif /* defined MP_API_COMPATIBLE */
-
-#endif /* end _H_MPI_ */
diff --git a/security/nss/lib/freebl/mpi/mpi_amd64.c b/security/nss/lib/freebl/mpi/mpi_amd64.c
deleted file mode 100644
index 9c9b1f9bc..000000000
--- a/security/nss/lib/freebl/mpi/mpi_amd64.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef MPI_AMD64
-#error This file only works on AMD64 platforms.
-#endif
-
-#include <mpi-priv.h>
-
-/*
- * MPI glue
- *
- */
-
-/* Presently, this is only used by the Montgomery arithmetic code. */
-/* c += a * b */
-void MPI_ASM_DECL s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len,
- mp_digit b, mp_digit *c)
-{
- mp_digit w;
- mp_digit d;
-
- d = s_mpv_mul_add_vec64(c, a, a_len, b);
- c += a_len;
- while (d) {
- w = c[0] + d;
- d = (w < c[0] || w < d);
- *c++ = w;
- }
-}
-
diff --git a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s b/security/nss/lib/freebl/mpi/mpi_amd64_gas.s
deleted file mode 100644
index ad6e2b9d7..000000000
--- a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s
+++ /dev/null
@@ -1,389 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-# ------------------------------------------------------------------------
-#
-# Implementation of s_mpv_mul_set_vec which exploits
-# the 64X64->128 bit unsigned multiply instruction.
-#
-# ------------------------------------------------------------------------
-
-# r = a * digit, r and a are vectors of length len
-# returns the carry digit
-# r and a are 64 bit aligned.
-#
-# uint64_t
-# s_mpv_mul_set_vec64(uint64_t *r, uint64_t *a, int len, uint64_t digit)
-#
-
-.text; .align 16; .globl s_mpv_mul_set_vec64; .type s_mpv_mul_set_vec64, @function; s_mpv_mul_set_vec64:
-
- xorq %rax, %rax # if (len == 0) return (0)
- testq %rdx, %rdx
- jz .L17
-
- movq %rdx, %r8 # Use r8 for len; %rdx is used by mul
- xorq %r9, %r9 # cy = 0
-
-.L15:
- cmpq $8, %r8 # 8 - len
- jb .L16
- movq 0(%rsi), %rax # rax = a[0]
- movq 8(%rsi), %r11 # prefetch a[1]
- mulq %rcx # p = a[0] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 0(%rdi) # r[0] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 16(%rsi), %r11 # prefetch a[2]
- mulq %rcx # p = a[1] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 8(%rdi) # r[1] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 24(%rsi), %r11 # prefetch a[3]
- mulq %rcx # p = a[2] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 16(%rdi) # r[2] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 32(%rsi), %r11 # prefetch a[4]
- mulq %rcx # p = a[3] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 24(%rdi) # r[3] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 40(%rsi), %r11 # prefetch a[5]
- mulq %rcx # p = a[4] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 32(%rdi) # r[4] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 48(%rsi), %r11 # prefetch a[6]
- mulq %rcx # p = a[5] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 40(%rdi) # r[5] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 56(%rsi), %r11 # prefetch a[7]
- mulq %rcx # p = a[6] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 48(%rdi) # r[6] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- mulq %rcx # p = a[7] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 56(%rdi) # r[7] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- addq $64, %rsi
- addq $64, %rdi
- subq $8, %r8
-
- jz .L17
- jmp .L15
-
-.L16:
- movq 0(%rsi), %rax
- mulq %rcx # p = a[0] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 0(%rdi) # r[0] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L17
-
- movq 8(%rsi), %rax
- mulq %rcx # p = a[1] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 8(%rdi) # r[1] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L17
-
- movq 16(%rsi), %rax
- mulq %rcx # p = a[2] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 16(%rdi) # r[2] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L17
-
- movq 24(%rsi), %rax
- mulq %rcx # p = a[3] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 24(%rdi) # r[3] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L17
-
- movq 32(%rsi), %rax
- mulq %rcx # p = a[4] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 32(%rdi) # r[4] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L17
-
- movq 40(%rsi), %rax
- mulq %rcx # p = a[5] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 40(%rdi) # r[5] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L17
-
- movq 48(%rsi), %rax
- mulq %rcx # p = a[6] * digit
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 48(%rdi) # r[6] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L17
-
-
-.L17:
- movq %r9, %rax
- ret
-
-.size s_mpv_mul_set_vec64, .-s_mpv_mul_set_vec64
-
-# ------------------------------------------------------------------------
-#
-# Implementation of s_mpv_mul_add_vec which exploits
-# the 64X64->128 bit unsigned multiply instruction.
-#
-# ------------------------------------------------------------------------
-
-# r += a * digit, r and a are vectors of length len
-# returns the carry digit
-# r and a are 64 bit aligned.
-#
-# uint64_t
-# s_mpv_mul_add_vec64(uint64_t *r, uint64_t *a, int len, uint64_t digit)
-#
-
-.text; .align 16; .globl s_mpv_mul_add_vec64; .type s_mpv_mul_add_vec64, @function; s_mpv_mul_add_vec64:
-
- xorq %rax, %rax # if (len == 0) return (0)
- testq %rdx, %rdx
- jz .L27
-
- movq %rdx, %r8 # Use r8 for len; %rdx is used by mul
- xorq %r9, %r9 # cy = 0
-
-.L25:
- cmpq $8, %r8 # 8 - len
- jb .L26
- movq 0(%rsi), %rax # rax = a[0]
- movq 0(%rdi), %r10 # r10 = r[0]
- movq 8(%rsi), %r11 # prefetch a[1]
- mulq %rcx # p = a[0] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[0]
- movq 8(%rdi), %r10 # prefetch r[1]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 0(%rdi) # r[0] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 16(%rsi), %r11 # prefetch a[2]
- mulq %rcx # p = a[1] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[1]
- movq 16(%rdi), %r10 # prefetch r[2]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 8(%rdi) # r[1] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 24(%rsi), %r11 # prefetch a[3]
- mulq %rcx # p = a[2] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[2]
- movq 24(%rdi), %r10 # prefetch r[3]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 16(%rdi) # r[2] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 32(%rsi), %r11 # prefetch a[4]
- mulq %rcx # p = a[3] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[3]
- movq 32(%rdi), %r10 # prefetch r[4]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 24(%rdi) # r[3] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 40(%rsi), %r11 # prefetch a[5]
- mulq %rcx # p = a[4] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[4]
- movq 40(%rdi), %r10 # prefetch r[5]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 32(%rdi) # r[4] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 48(%rsi), %r11 # prefetch a[6]
- mulq %rcx # p = a[5] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[5]
- movq 48(%rdi), %r10 # prefetch r[6]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 40(%rdi) # r[5] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- movq 56(%rsi), %r11 # prefetch a[7]
- mulq %rcx # p = a[6] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[6]
- movq 56(%rdi), %r10 # prefetch r[7]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 48(%rdi) # r[6] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- movq %r11, %rax
- mulq %rcx # p = a[7] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[7]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 56(%rdi) # r[7] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
-
- addq $64, %rsi
- addq $64, %rdi
- subq $8, %r8
-
- jz .L27
- jmp .L25
-
-.L26:
- movq 0(%rsi), %rax
- movq 0(%rdi), %r10
- mulq %rcx # p = a[0] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[0]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 0(%rdi) # r[0] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L27
-
- movq 8(%rsi), %rax
- movq 8(%rdi), %r10
- mulq %rcx # p = a[1] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[1]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 8(%rdi) # r[1] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L27
-
- movq 16(%rsi), %rax
- movq 16(%rdi), %r10
- mulq %rcx # p = a[2] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[2]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 16(%rdi) # r[2] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L27
-
- movq 24(%rsi), %rax
- movq 24(%rdi), %r10
- mulq %rcx # p = a[3] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[3]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 24(%rdi) # r[3] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L27
-
- movq 32(%rsi), %rax
- movq 32(%rdi), %r10
- mulq %rcx # p = a[4] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[4]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 32(%rdi) # r[4] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L27
-
- movq 40(%rsi), %rax
- movq 40(%rdi), %r10
- mulq %rcx # p = a[5] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[5]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 40(%rdi) # r[5] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L27
-
- movq 48(%rsi), %rax
- movq 48(%rdi), %r10
- mulq %rcx # p = a[6] * digit
- addq %r10, %rax
- adcq $0, %rdx # p += r[6]
- addq %r9, %rax
- adcq $0, %rdx # p += cy
- movq %rax, 48(%rdi) # r[6] = lo(p)
- movq %rdx, %r9 # cy = hi(p)
- decq %r8
- jz .L27
-
-
-.L27:
- movq %r9, %rax
- ret
-
-.size s_mpv_mul_add_vec64, .-s_mpv_mul_add_vec64
-
-# Magic indicating no need for an executable stack
-.section .note.GNU-stack, "", @progbits
-.previous
diff --git a/security/nss/lib/freebl/mpi/mpi_amd64_masm.asm b/security/nss/lib/freebl/mpi/mpi_amd64_masm.asm
deleted file mode 100644
index 2120c18f9..000000000
--- a/security/nss/lib/freebl/mpi/mpi_amd64_masm.asm
+++ /dev/null
@@ -1,388 +0,0 @@
-; This Source Code Form is subject to the terms of the Mozilla Public
-; License, v. 2.0. If a copy of the MPL was not distributed with this
-; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-;
-; This code is converted from mpi_amd64_gas.asm for MASM for x64.
-;
-
-; ------------------------------------------------------------------------
-;
-; Implementation of s_mpv_mul_set_vec which exploits
-; the 64X64->128 bit unsigned multiply instruction.
-;
-; ------------------------------------------------------------------------
-
-; r = a * digit, r and a are vectors of length len
-; returns the carry digit
-; r and a are 64 bit aligned.
-;
-; uint64_t
-; s_mpv_mul_set_vec64(uint64_t *r, uint64_t *a, int len, uint64_t digit)
-;
-
-.CODE
-
-s_mpv_mul_set_vec64 PROC
-
- ; compatibilities for paramenter registers
- ;
- ; About GAS and MASM, the usage of parameter registers are different.
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
- mov edx, r8d
- mov rcx, r9
-
- xor rax, rax
- test rdx, rdx
- jz L17
- mov r8, rdx
- xor r9, r9
-
-L15:
- cmp r8, 8
- jb L16
- mov rax, [rsi]
- mov r11, [8+rsi]
- mul rcx
- add rax, r9
- adc rdx, 0
- mov [0+rdi], rax
- mov r9, rdx
- mov rax,r11
- mov r11, [16+rsi]
- mul rcx
- add rax,r9
- adc rdx,0
- mov [8+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [24+rsi]
- mul rcx
- add rax,r9
- adc rdx,0
- mov [16+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [32+rsi]
- mul rcx
- add rax,r9
- adc rdx,0
- mov [24+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [40+rsi]
- mul rcx
- add rax,r9
- adc rdx,0
- mov [32+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [48+rsi]
- mul rcx
- add rax,r9
- adc rdx,0
- mov [40+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [56+rsi]
- mul rcx
- add rax,r9
- adc rdx,0
- mov [48+rdi],rax
- mov r9,rdx
- mov rax,r11
- mul rcx
- add rax,r9
- adc rdx,0
- mov [56+rdi],rax
- mov r9,rdx
- add rsi, 64
- add rdi, 64
- sub r8, 8
- jz L17
- jmp L15
-
-L16:
- mov rax, [0+rsi]
- mul rcx
- add rax, r9
- adc rdx,0
- mov [0+rdi],rax
- mov r9,rdx
- dec r8
- jz L17
- mov rax, [8+rsi]
- mul rcx
- add rax,r9
- adc rdx,0
- mov [8+rdi], rax
- mov r9, rdx
- dec r8
- jz L17
- mov rax, [16+rsi]
- mul rcx
- add rax, r9
- adc rdx, 0
- mov [16+rdi],rax
- mov r9,rdx
- dec r8
- jz L17
- mov rax, [24+rsi]
- mul rcx
- add rax, r9
- adc rdx, 0
- mov [24+rdi], rax
- mov r9, rdx
- dec r8
- jz L17
- mov rax, [32+rsi]
- mul rcx
- add rax, r9
- adc rdx, 0
- mov [32+rdi],rax
- mov r9, rdx
- dec r8
- jz L17
- mov rax, [40+rsi]
- mul rcx
- add rax, r9
- adc rdx, 0
- mov [40+rdi], rax
- mov r9, rdx
- dec r8
- jz L17
- mov rax, [48+rsi]
- mul rcx
- add rax, r9
- adc rdx, 0
- mov [48+rdi], rax
- mov r9, rdx
- dec r8
- jz L17
-
-L17:
- mov rax, r9
- pop rsi
- pop rdi
- ret
-
-s_mpv_mul_set_vec64 ENDP
-
-
-;------------------------------------------------------------------------
-;
-; Implementation of s_mpv_mul_add_vec which exploits
-; the 64X64->128 bit unsigned multiply instruction.
-;
-;------------------------------------------------------------------------
-
-; r += a * digit, r and a are vectors of length len
-; returns the carry digit
-; r and a are 64 bit aligned.
-;
-; uint64_t
-; s_mpv_mul_add_vec64(uint64_t *r, uint64_t *a, int len, uint64_t digit)
-;
-
-s_mpv_mul_add_vec64 PROC
-
- ; compatibilities for paramenter registers
- ;
- ; About GAS and MASM, the usage of parameter registers are different.
-
- push rdi
- push rsi
-
- mov rdi, rcx
- mov rsi, rdx
- mov edx, r8d
- mov rcx, r9
-
- xor rax, rax
- test rdx, rdx
- jz L27
- mov r8, rdx
- xor r9, r9
-
-L25:
- cmp r8, 8
- jb L26
- mov rax, [0+rsi]
- mov r10, [0+rdi]
- mov r11, [8+rsi]
- mul rcx
- add rax,r10
- adc rdx,0
- mov r10, [8+rdi]
- add rax,r9
- adc rdx,0
- mov [0+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [16+rsi]
- mul rcx
- add rax,r10
- adc rdx,0
- mov r10, [16+rdi]
- add rax,r9
- adc rdx,0
- mov [8+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [24+rsi]
- mul rcx
- add rax,r10
- adc rdx,0
- mov r10, [24+rdi]
- add rax,r9
- adc rdx,0
- mov [16+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [32+rsi]
- mul rcx
- add rax,r10
- adc rdx,0
- mov r10, [32+rdi]
- add rax,r9
- adc rdx,0
- mov [24+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [40+rsi]
- mul rcx
- add rax,r10
- adc rdx,0
- mov r10, [40+rdi]
- add rax,r9
- adc rdx,0
- mov [32+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [48+rsi]
- mul rcx
- add rax,r10
- adc rdx,0
- mov r10, [48+rdi]
- add rax,r9
- adc rdx,0
- mov [40+rdi],rax
- mov r9,rdx
- mov rax,r11
- mov r11, [56+rsi]
- mul rcx
- add rax,r10
- adc rdx,0
- mov r10, [56+rdi]
- add rax,r9
- adc rdx,0
- mov [48+rdi],rax
- mov r9,rdx
- mov rax,r11
- mul rcx
- add rax,r10
- adc rdx,0
- add rax,r9
- adc rdx,0
- mov [56+rdi],rax
- mov r9,rdx
- add rsi,64
- add rdi,64
- sub r8, 8
- jz L27
- jmp L25
-
-L26:
- mov rax, [0+rsi]
- mov r10, [0+rdi]
- mul rcx
- add rax,r10
- adc rdx,0
- add rax,r9
- adc rdx,0
- mov [0+rdi],rax
- mov r9,rdx
- dec r8
- jz L27
- mov rax, [8+rsi]
- mov r10, [8+rdi]
- mul rcx
- add rax,r10
- adc rdx,0
- add rax,r9
- adc rdx,0
- mov [8+rdi],rax
- mov r9,rdx
- dec r8
- jz L27
- mov rax, [16+rsi]
- mov r10, [16+rdi]
- mul rcx
- add rax,r10
- adc rdx,0
- add rax,r9
- adc rdx,0
- mov [16+rdi],rax
- mov r9,rdx
- dec r8
- jz L27
- mov rax, [24+rsi]
- mov r10, [24+rdi]
- mul rcx
- add rax,r10
- adc rdx,0
- add rax,r9
- adc rdx,0
- mov [24+rdi],rax
- mov r9,rdx
- dec r8
- jz L27
- mov rax, [32+rsi]
- mov r10, [32+rdi]
- mul rcx
- add rax,r10
- adc rdx,0
- add rax,r9
- adc rdx,0
- mov [32+rdi],rax
- mov r9,rdx
- dec r8
- jz L27
- mov rax, [40+rsi]
- mov r10, [40+rdi]
- mul rcx
- add rax,r10
- adc rdx,0
- add rax,r9
- adc rdx,0
- mov [40+rdi],rax
- mov r9,rdx
- dec r8
- jz L27
- mov rax, [48+rsi]
- mov r10, [48+rdi]
- mul rcx
- add rax,r10
- adc rdx,0
- add rax, r9
- adc rdx, 0
- mov [48+rdi], rax
- mov r9, rdx
- dec r8
- jz L27
-
-L27:
- mov rax, r9
-
- pop rsi
- pop rdi
- ret
-
-s_mpv_mul_add_vec64 ENDP
-
-END
diff --git a/security/nss/lib/freebl/mpi/mpi_amd64_sun.s b/security/nss/lib/freebl/mpi/mpi_amd64_sun.s
deleted file mode 100644
index ddd5c40fd..000000000
--- a/security/nss/lib/freebl/mpi/mpi_amd64_sun.s
+++ /dev/null
@@ -1,385 +0,0 @@
-/ This Source Code Form is subject to the terms of the Mozilla Public
-/ License, v. 2.0. If a copy of the MPL was not distributed with this
-/ file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-/ ------------------------------------------------------------------------
-/
-/ Implementation of s_mpv_mul_set_vec which exploits
-/ the 64X64->128 bit unsigned multiply instruction.
-/
-/ ------------------------------------------------------------------------
-
-/ r = a * digit, r and a are vectors of length len
-/ returns the carry digit
-/ r and a are 64 bit aligned.
-/
-/ uint64_t
-/ s_mpv_mul_set_vec64(uint64_t *r, uint64_t *a, int len, uint64_t digit)
-/
-
-.text; .align 16; .globl s_mpv_mul_set_vec64; .type s_mpv_mul_set_vec64, @function; s_mpv_mul_set_vec64:
-
- xorq %rax, %rax / if (len == 0) return (0)
- testq %rdx, %rdx
- jz .L17
-
- movq %rdx, %r8 / Use r8 for len; %rdx is used by mul
- xorq %r9, %r9 / cy = 0
-
-.L15:
- cmpq $8, %r8 / 8 - len
- jb .L16
- movq 0(%rsi), %rax / rax = a[0]
- movq 8(%rsi), %r11 / prefetch a[1]
- mulq %rcx / p = a[0] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 0(%rdi) / r[0] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 16(%rsi), %r11 / prefetch a[2]
- mulq %rcx / p = a[1] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 8(%rdi) / r[1] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 24(%rsi), %r11 / prefetch a[3]
- mulq %rcx / p = a[2] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 16(%rdi) / r[2] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 32(%rsi), %r11 / prefetch a[4]
- mulq %rcx / p = a[3] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 24(%rdi) / r[3] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 40(%rsi), %r11 / prefetch a[5]
- mulq %rcx / p = a[4] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 32(%rdi) / r[4] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 48(%rsi), %r11 / prefetch a[6]
- mulq %rcx / p = a[5] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 40(%rdi) / r[5] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 56(%rsi), %r11 / prefetch a[7]
- mulq %rcx / p = a[6] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 48(%rdi) / r[6] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- mulq %rcx / p = a[7] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 56(%rdi) / r[7] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- addq $64, %rsi
- addq $64, %rdi
- subq $8, %r8
-
- jz .L17
- jmp .L15
-
-.L16:
- movq 0(%rsi), %rax
- mulq %rcx / p = a[0] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 0(%rdi) / r[0] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L17
-
- movq 8(%rsi), %rax
- mulq %rcx / p = a[1] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 8(%rdi) / r[1] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L17
-
- movq 16(%rsi), %rax
- mulq %rcx / p = a[2] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 16(%rdi) / r[2] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L17
-
- movq 24(%rsi), %rax
- mulq %rcx / p = a[3] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 24(%rdi) / r[3] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L17
-
- movq 32(%rsi), %rax
- mulq %rcx / p = a[4] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 32(%rdi) / r[4] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L17
-
- movq 40(%rsi), %rax
- mulq %rcx / p = a[5] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 40(%rdi) / r[5] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L17
-
- movq 48(%rsi), %rax
- mulq %rcx / p = a[6] * digit
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 48(%rdi) / r[6] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L17
-
-
-.L17:
- movq %r9, %rax
- ret
-
-.size s_mpv_mul_set_vec64, .-s_mpv_mul_set_vec64
-
-/ ------------------------------------------------------------------------
-/
-/ Implementation of s_mpv_mul_add_vec which exploits
-/ the 64X64->128 bit unsigned multiply instruction.
-/
-/ ------------------------------------------------------------------------
-
-/ r += a * digit, r and a are vectors of length len
-/ returns the carry digit
-/ r and a are 64 bit aligned.
-/
-/ uint64_t
-/ s_mpv_mul_add_vec64(uint64_t *r, uint64_t *a, int len, uint64_t digit)
-/
-
-.text; .align 16; .globl s_mpv_mul_add_vec64; .type s_mpv_mul_add_vec64, @function; s_mpv_mul_add_vec64:
-
- xorq %rax, %rax / if (len == 0) return (0)
- testq %rdx, %rdx
- jz .L27
-
- movq %rdx, %r8 / Use r8 for len; %rdx is used by mul
- xorq %r9, %r9 / cy = 0
-
-.L25:
- cmpq $8, %r8 / 8 - len
- jb .L26
- movq 0(%rsi), %rax / rax = a[0]
- movq 0(%rdi), %r10 / r10 = r[0]
- movq 8(%rsi), %r11 / prefetch a[1]
- mulq %rcx / p = a[0] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[0]
- movq 8(%rdi), %r10 / prefetch r[1]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 0(%rdi) / r[0] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 16(%rsi), %r11 / prefetch a[2]
- mulq %rcx / p = a[1] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[1]
- movq 16(%rdi), %r10 / prefetch r[2]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 8(%rdi) / r[1] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 24(%rsi), %r11 / prefetch a[3]
- mulq %rcx / p = a[2] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[2]
- movq 24(%rdi), %r10 / prefetch r[3]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 16(%rdi) / r[2] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 32(%rsi), %r11 / prefetch a[4]
- mulq %rcx / p = a[3] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[3]
- movq 32(%rdi), %r10 / prefetch r[4]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 24(%rdi) / r[3] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 40(%rsi), %r11 / prefetch a[5]
- mulq %rcx / p = a[4] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[4]
- movq 40(%rdi), %r10 / prefetch r[5]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 32(%rdi) / r[4] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 48(%rsi), %r11 / prefetch a[6]
- mulq %rcx / p = a[5] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[5]
- movq 48(%rdi), %r10 / prefetch r[6]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 40(%rdi) / r[5] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- movq 56(%rsi), %r11 / prefetch a[7]
- mulq %rcx / p = a[6] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[6]
- movq 56(%rdi), %r10 / prefetch r[7]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 48(%rdi) / r[6] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- movq %r11, %rax
- mulq %rcx / p = a[7] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[7]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 56(%rdi) / r[7] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
-
- addq $64, %rsi
- addq $64, %rdi
- subq $8, %r8
-
- jz .L27
- jmp .L25
-
-.L26:
- movq 0(%rsi), %rax
- movq 0(%rdi), %r10
- mulq %rcx / p = a[0] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[0]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 0(%rdi) / r[0] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L27
-
- movq 8(%rsi), %rax
- movq 8(%rdi), %r10
- mulq %rcx / p = a[1] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[1]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 8(%rdi) / r[1] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L27
-
- movq 16(%rsi), %rax
- movq 16(%rdi), %r10
- mulq %rcx / p = a[2] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[2]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 16(%rdi) / r[2] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L27
-
- movq 24(%rsi), %rax
- movq 24(%rdi), %r10
- mulq %rcx / p = a[3] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[3]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 24(%rdi) / r[3] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L27
-
- movq 32(%rsi), %rax
- movq 32(%rdi), %r10
- mulq %rcx / p = a[4] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[4]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 32(%rdi) / r[4] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L27
-
- movq 40(%rsi), %rax
- movq 40(%rdi), %r10
- mulq %rcx / p = a[5] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[5]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 40(%rdi) / r[5] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L27
-
- movq 48(%rsi), %rax
- movq 48(%rdi), %r10
- mulq %rcx / p = a[6] * digit
- addq %r10, %rax
- adcq $0, %rdx / p += r[6]
- addq %r9, %rax
- adcq $0, %rdx / p += cy
- movq %rax, 48(%rdi) / r[6] = lo(p)
- movq %rdx, %r9 / cy = hi(p)
- decq %r8
- jz .L27
-
-
-.L27:
- movq %r9, %rax
- ret
-
-.size s_mpv_mul_add_vec64, .-s_mpv_mul_add_vec64
diff --git a/security/nss/lib/freebl/mpi/mpi_arm.c b/security/nss/lib/freebl/mpi/mpi_arm.c
deleted file mode 100644
index 9199aab46..000000000
--- a/security/nss/lib/freebl/mpi/mpi_arm.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* This inlined version is for 32-bit ARM platform only */
-
-#if !defined(__arm__)
-#error "This is for ARM only"
-#endif
-
-/* 16-bit thumb doesn't work inlined assember version */
-#if (!defined(__thumb__) || defined(__thumb2__)) && !defined(__ARM_ARCH_3__)
-
-#include "mpi-priv.h"
-
-#ifdef MP_ASSEMBLY_MULTIPLY
-void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- __asm__ __volatile__(
- "mov r5, #0\n"
-#ifdef __thumb2__
- "cbz %1, 2f\n"
-#else
- "cmp %1, r5\n" /* r5 is 0 now */
- "beq 2f\n"
-#endif
-
- "1:\n"
- "mov r4, #0\n"
- "ldr r6, [%0], #4\n"
- "umlal r5, r4, r6, %2\n"
- "str r5, [%3], #4\n"
- "mov r5, r4\n"
-
- "subs %1, #1\n"
- "bne 1b\n"
-
- "2:\n"
- "str r5, [%3]\n"
- :
- : "r"(a), "r"(a_len), "r"(b), "r"(c)
- : "memory", "cc", "%r4", "%r5", "%r6");
-}
-
-void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- __asm__ __volatile__(
- "mov r5, #0\n"
-#ifdef __thumb2__
- "cbz %1, 2f\n"
-#else
- "cmp %1, r5\n" /* r5 is 0 now */
- "beq 2f\n"
-#endif
-
- "1:\n"
- "mov r4, #0\n"
- "ldr r6, [%3]\n"
- "adds r5, r6\n"
- "adc r4, r4, #0\n"
-
- "ldr r6, [%0], #4\n"
- "umlal r5, r4, r6, %2\n"
- "str r5, [%3], #4\n"
- "mov r5, r4\n"
-
- "subs %1, #1\n"
- "bne 1b\n"
-
- "2:\n"
- "str r5, [%3]\n"
- :
- : "r"(a), "r"(a_len), "r"(b), "r"(c)
- : "memory", "cc", "%r4", "%r5", "%r6");
-}
-
-void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- if (!a_len)
- return;
-
- __asm__ __volatile__(
- "mov r5, #0\n"
-
- "1:\n"
- "mov r4, #0\n"
- "ldr r6, [%3]\n"
- "adds r5, r6\n"
- "adc r4, r4, #0\n"
- "ldr r6, [%0], #4\n"
- "umlal r5, r4, r6, %2\n"
- "str r5, [%3], #4\n"
- "mov r5, r4\n"
-
- "subs %1, #1\n"
- "bne 1b\n"
-
-#ifdef __thumb2__
- "cbz r4, 3f\n"
-#else
- "cmp r4, #0\n"
- "beq 3f\n"
-#endif
-
- "2:\n"
- "mov r4, #0\n"
- "ldr r6, [%3]\n"
- "adds r5, r6\n"
- "adc r4, r4, #0\n"
- "str r5, [%3], #4\n"
- "movs r5, r4\n"
- "bne 2b\n"
-
- "3:\n"
- :
- : "r"(a), "r"(a_len), "r"(b), "r"(c)
- : "memory", "cc", "%r4", "%r5", "%r6");
-}
-#endif
-
-#ifdef MP_ASSEMBLY_SQUARE
-void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
-{
- if (!a_len)
- return;
-
- __asm__ __volatile__(
- "mov r3, #0\n"
-
- "1:\n"
- "mov r4, #0\n"
- "ldr r6, [%0], #4\n"
- "ldr r5, [%2]\n"
- "adds r3, r5\n"
- "adc r4, r4, #0\n"
- "umlal r3, r4, r6, r6\n" /* w = r3:r4 */
- "str r3, [%2], #4\n"
-
- "ldr r5, [%2]\n"
- "adds r3, r4, r5\n"
- "mov r4, #0\n"
- "adc r4, r4, #0\n"
- "str r3, [%2], #4\n"
- "mov r3, r4\n"
-
- "subs %1, #1\n"
- "bne 1b\n"
-
-#ifdef __thumb2__
- "cbz r3, 3f\n"
-#else
- "cmp r3, #0\n"
- "beq 3f\n"
-#endif
-
- "2:\n"
- "mov r4, #0\n"
- "ldr r5, [%2]\n"
- "adds r3, r5\n"
- "adc r4, r4, #0\n"
- "str r3, [%2], #4\n"
- "movs r3, r4\n"
- "bne 2b\n"
-
- "3:"
- :
- : "r"(pa), "r"(a_len), "r"(ps)
- : "memory", "cc", "%r3", "%r4", "%r5", "%r6");
-}
-#endif
-#endif
diff --git a/security/nss/lib/freebl/mpi/mpi_hp.c b/security/nss/lib/freebl/mpi/mpi_hp.c
deleted file mode 100644
index a62415090..000000000
--- a/security/nss/lib/freebl/mpi/mpi_hp.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* This file contains routines that perform vector multiplication. */
-
-#include "mpi-priv.h"
-#include <unistd.h>
-
-#include <stddef.h>
-/* #include <sys/systeminfo.h> */
-#include <strings.h>
-
-extern void multacc512(
- int length, /* doublewords in multiplicand vector. */
- const mp_digit *scalaraddr, /* Address of scalar. */
- const mp_digit *multiplicand, /* The multiplicand vector. */
- mp_digit * result); /* Where to accumulate the result. */
-
-extern void maxpy_little(
- int length, /* doublewords in multiplicand vector. */
- const mp_digit *scalaraddr, /* Address of scalar. */
- const mp_digit *multiplicand, /* The multiplicand vector. */
- mp_digit * result); /* Where to accumulate the result. */
-
-extern void add_diag_little(
- int length, /* doublewords in input vector. */
- const mp_digit *root, /* The vector to square. */
- mp_digit * result); /* Where to accumulate the result. */
-
-void
-s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
-{
- add_diag_little(a_len, pa, ps);
-}
-
-#define MAX_STACK_DIGITS 258
-#define MULTACC512_LEN (512 / MP_DIGIT_BIT)
-#define HP_MPY_ADD_FN (a_len == MULTACC512_LEN ? multacc512 : maxpy_little)
-
-/* c = a * b */
-void
-s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- mp_digit x[MAX_STACK_DIGITS];
- mp_digit *px = x;
- size_t xSize = 0;
-
- if (a == c) {
- if (a_len > MAX_STACK_DIGITS) {
- xSize = sizeof(mp_digit) * (a_len + 2);
- px = malloc(xSize);
- if (!px)
- return;
- }
- memcpy(px, a, a_len * sizeof(*a));
- a = px;
- }
- s_mp_setz(c, a_len + 1);
- HP_MPY_ADD_FN(a_len, &b, a, c);
- if (px != x && px) {
- memset(px, 0, xSize);
- free(px);
- }
-}
-
-/* c += a * b, where a is a_len words long. */
-void
-s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- c[a_len] = 0; /* so carry propagation stops here. */
- HP_MPY_ADD_FN(a_len, &b, a, c);
-}
-
-/* c += a * b, where a is y words long. */
-void
-s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b,
- mp_digit *c)
-{
- HP_MPY_ADD_FN(a_len, &b, a, c);
-}
-
diff --git a/security/nss/lib/freebl/mpi/mpi_i86pc.s b/security/nss/lib/freebl/mpi/mpi_i86pc.s
deleted file mode 100644
index 6b9c02f10..000000000
--- a/security/nss/lib/freebl/mpi/mpi_i86pc.s
+++ /dev/null
@@ -1,316 +0,0 @@
-/
-/ This Source Code Form is subject to the terms of the Mozilla Public
-/ License, v. 2.0. If a copy of the MPL was not distributed with this
-/ file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-/ $Id$
-/
-
-.text
-
- / ebp - 36: caller's esi
- / ebp - 32: caller's edi
- / ebp - 28:
- / ebp - 24:
- / ebp - 20:
- / ebp - 16:
- / ebp - 12:
- / ebp - 8:
- / ebp - 4:
- / ebp + 0: caller's ebp
- / ebp + 4: return address
- / ebp + 8: a argument
- / ebp + 12: a_len argument
- / ebp + 16: b argument
- / ebp + 20: c argument
- / registers:
- / eax:
- / ebx: carry
- / ecx: a_len
- / edx:
- / esi: a ptr
- / edi: c ptr
-.globl s_mpv_mul_d
-.type s_mpv_mul_d,@function
-s_mpv_mul_d:
- push %ebp
- mov %esp,%ebp
- sub $28,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx / carry = 0
- mov 12(%ebp),%ecx / ecx = a_len
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je L2 / jmp if a_len == 0
- mov 8(%ebp),%esi / esi = a
- cld
-L1:
- lodsl / eax = [ds:esi]; esi += 4
- mov 16(%ebp),%edx / edx = b
- mull %edx / edx:eax = Phi:Plo = a_i * b
-
- add %ebx,%eax / add carry (%ebx) to edx:eax
- adc $0,%edx
- mov %edx,%ebx / high half of product becomes next carry
-
- stosl / [es:edi] = ax; edi += 4;
- dec %ecx / --a_len
- jnz L1 / jmp if a_len != 0
-L2:
- mov %ebx,0(%edi) / *c = carry
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- / ebp - 36: caller's esi
- / ebp - 32: caller's edi
- / ebp - 28:
- / ebp - 24:
- / ebp - 20:
- / ebp - 16:
- / ebp - 12:
- / ebp - 8:
- / ebp - 4:
- / ebp + 0: caller's ebp
- / ebp + 4: return address
- / ebp + 8: a argument
- / ebp + 12: a_len argument
- / ebp + 16: b argument
- / ebp + 20: c argument
- / registers:
- / eax:
- / ebx: carry
- / ecx: a_len
- / edx:
- / esi: a ptr
- / edi: c ptr
-.globl s_mpv_mul_d_add
-.type s_mpv_mul_d_add,@function
-s_mpv_mul_d_add:
- push %ebp
- mov %esp,%ebp
- sub $28,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx / carry = 0
- mov 12(%ebp),%ecx / ecx = a_len
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je L4 / jmp if a_len == 0
- mov 8(%ebp),%esi / esi = a
- cld
-L3:
- lodsl / eax = [ds:esi]; esi += 4
- mov 16(%ebp),%edx / edx = b
- mull %edx / edx:eax = Phi:Plo = a_i * b
-
- add %ebx,%eax / add carry (%ebx) to edx:eax
- adc $0,%edx
- mov 0(%edi),%ebx / add in current word from *c
- add %ebx,%eax
- adc $0,%edx
- mov %edx,%ebx / high half of product becomes next carry
-
- stosl / [es:edi] = ax; edi += 4;
- dec %ecx / --a_len
- jnz L3 / jmp if a_len != 0
-L4:
- mov %ebx,0(%edi) / *c = carry
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- / ebp - 36: caller's esi
- / ebp - 32: caller's edi
- / ebp - 28:
- / ebp - 24:
- / ebp - 20:
- / ebp - 16:
- / ebp - 12:
- / ebp - 8:
- / ebp - 4:
- / ebp + 0: caller's ebp
- / ebp + 4: return address
- / ebp + 8: a argument
- / ebp + 12: a_len argument
- / ebp + 16: b argument
- / ebp + 20: c argument
- / registers:
- / eax:
- / ebx: carry
- / ecx: a_len
- / edx:
- / esi: a ptr
- / edi: c ptr
-.globl s_mpv_mul_d_add_prop
-.type s_mpv_mul_d_add_prop,@function
-s_mpv_mul_d_add_prop:
- push %ebp
- mov %esp,%ebp
- sub $28,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx / carry = 0
- mov 12(%ebp),%ecx / ecx = a_len
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je L6 / jmp if a_len == 0
- cld
- mov 8(%ebp),%esi / esi = a
-L5:
- lodsl / eax = [ds:esi]; esi += 4
- mov 16(%ebp),%edx / edx = b
- mull %edx / edx:eax = Phi:Plo = a_i * b
-
- add %ebx,%eax / add carry (%ebx) to edx:eax
- adc $0,%edx
- mov 0(%edi),%ebx / add in current word from *c
- add %ebx,%eax
- adc $0,%edx
- mov %edx,%ebx / high half of product becomes next carry
-
- stosl / [es:edi] = ax; edi += 4;
- dec %ecx / --a_len
- jnz L5 / jmp if a_len != 0
-L6:
- cmp $0,%ebx / is carry zero?
- jz L8
- mov 0(%edi),%eax / add in current word from *c
- add %ebx,%eax
- stosl / [es:edi] = ax; edi += 4;
- jnc L8
-L7:
- mov 0(%edi),%eax / add in current word from *c
- adc $0,%eax
- stosl / [es:edi] = ax; edi += 4;
- jc L7
-L8:
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- / ebp - 20: caller's esi
- / ebp - 16: caller's edi
- / ebp - 12:
- / ebp - 8: carry
- / ebp - 4: a_len local
- / ebp + 0: caller's ebp
- / ebp + 4: return address
- / ebp + 8: pa argument
- / ebp + 12: a_len argument
- / ebp + 16: ps argument
- / ebp + 20:
- / registers:
- / eax:
- / ebx: carry
- / ecx: a_len
- / edx:
- / esi: a ptr
- / edi: c ptr
-
-.globl s_mpv_sqr_add_prop
-.type s_mpv_sqr_add_prop,@function
-s_mpv_sqr_add_prop:
- push %ebp
- mov %esp,%ebp
- sub $12,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx / carry = 0
- mov 12(%ebp),%ecx / a_len
- mov 16(%ebp),%edi / edi = ps
- cmp $0,%ecx
- je L11 / jump if a_len == 0
- cld
- mov 8(%ebp),%esi / esi = pa
-L10:
- lodsl / %eax = [ds:si]; si += 4;
- mull %eax
-
- add %ebx,%eax / add "carry"
- adc $0,%edx
- mov 0(%edi),%ebx
- add %ebx,%eax / add low word from result
- mov 4(%edi),%ebx
- stosl / [es:di] = %eax; di += 4;
- adc %ebx,%edx / add high word from result
- movl $0,%ebx
- mov %edx,%eax
- adc $0,%ebx
- stosl / [es:di] = %eax; di += 4;
- dec %ecx / --a_len
- jnz L10 / jmp if a_len != 0
-L11:
- cmp $0,%ebx / is carry zero?
- jz L14
- mov 0(%edi),%eax / add in current word from *c
- add %ebx,%eax
- stosl / [es:edi] = ax; edi += 4;
- jnc L14
-L12:
- mov 0(%edi),%eax / add in current word from *c
- adc $0,%eax
- stosl / [es:edi] = ax; edi += 4;
- jc L12
-L14:
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- /
- / Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
- / so its high bit is 1. This code is from NSPR.
- /
- / mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
- / mp_digit *qp, mp_digit *rp)
-
- / esp + 0: Caller's ebx
- / esp + 4: return address
- / esp + 8: Nhi argument
- / esp + 12: Nlo argument
- / esp + 16: divisor argument
- / esp + 20: qp argument
- / esp + 24: rp argument
- / registers:
- / eax:
- / ebx: carry
- / ecx: a_len
- / edx:
- / esi: a ptr
- / edi: c ptr
- /
-
-.globl s_mpv_div_2dx1d
-.type s_mpv_div_2dx1d,@function
-s_mpv_div_2dx1d:
- push %ebx
- mov 8(%esp),%edx
- mov 12(%esp),%eax
- mov 16(%esp),%ebx
- div %ebx
- mov 20(%esp),%ebx
- mov %eax,0(%ebx)
- mov 24(%esp),%ebx
- mov %edx,0(%ebx)
- xor %eax,%eax / return zero
- pop %ebx
- ret
- nop
-
diff --git a/security/nss/lib/freebl/mpi/mpi_mips.s b/security/nss/lib/freebl/mpi/mpi_mips.s
deleted file mode 100644
index 455792bbb..000000000
--- a/security/nss/lib/freebl/mpi/mpi_mips.s
+++ /dev/null
@@ -1,472 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include <regdef.h>
- .set noreorder
- .set noat
-
- .section .text, 1, 0x00000006, 4, 4
-.text:
- .section .text
-
- .ent s_mpv_mul_d_add
- .globl s_mpv_mul_d_add
-
-s_mpv_mul_d_add:
- #/* c += a * b */
- #void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,
- # mp_digit *c)
- #{
- # mp_digit a0, a1; regs a4, a5
- # mp_digit c0, c1; regs a6, a7
- # mp_digit cy = 0; reg t2
- # mp_word w0, w1; regs t0, t1
- #
- # if (a_len) {
- beq a1,zero,.L.1
- move t2,zero # cy = 0
- dsll32 a2,a2,0 # "b" is sometimes negative (?!?!)
- dsrl32 a2,a2,0 # This clears the upper 32 bits.
- # a0 = a[0];
- lwu a4,0(a0)
- # w0 = ((mp_word)b * a0);
- dmultu a2,a4
- # if (--a_len) {
- addiu a1,a1,-1
- beq a1,zero,.L.2
- # while (a_len >= 2) {
- sltiu t3,a1,2
- bne t3,zero,.L.3
- # a1 = a[1];
- lwu a5,4(a0)
-.L.4:
- # a_len -= 2;
- addiu a1,a1,-2
- # c0 = c[0];
- lwu a6,0(a3)
- # w0 += cy;
- mflo t0
- daddu t0,t0,t2
- # w0 += c0;
- daddu t0,t0,a6
- # w1 = (mp_word)b * a1;
- dmultu a2,a5 #
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # a0 = a[2];
- lwu a4,8(a0)
- # a += 2;
- addiu a0,a0,8
- # c1 = c[1];
- lwu a7,4(a3)
- # w1 += cy;
- mflo t1
- daddu t1,t1,t2
- # w1 += c1;
- daddu t1,t1,a7
- # w0 = (mp_word)b * a0;
- dmultu a2,a4 #
- # cy = CARRYOUT(w1);
- dsrl32 t2,t1,0
- # c[1] = ACCUM(w1);
- sw t1,4(a3)
- # c += 2;
- addiu a3,a3,8
- sltiu t3,a1,2
- beq t3,zero,.L.4
- # a1 = a[1];
- lwu a5,4(a0)
- # }
-.L.3:
- # c0 = c[0];
- lwu a6,0(a3)
- # w0 += cy;
- # if (a_len) {
- mflo t0
- beq a1,zero,.L.5
- daddu t0,t0,t2
- # w1 = (mp_word)b * a1;
- dmultu a2,a5
- # w0 += c0;
- daddu t0,t0,a6 #
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # c1 = c[1];
- lwu a7,4(a3)
- # w1 += cy;
- mflo t1
- daddu t1,t1,t2
- # w1 += c1;
- daddu t1,t1,a7
- # c[1] = ACCUM(w1);
- sw t1,4(a3)
- # cy = CARRYOUT(w1);
- dsrl32 t2,t1,0
- # c += 1;
- b .L.6
- addiu a3,a3,4
- # } else {
-.L.5:
- # w0 += c0;
- daddu t0,t0,a6
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # cy = CARRYOUT(w0);
- b .L.6
- dsrl32 t2,t0,0
- # }
- # } else {
-.L.2:
- # c0 = c[0];
- lwu a6,0(a3)
- # w0 += c0;
- mflo t0
- daddu t0,t0,a6
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- # }
-.L.6:
- # c[1] = cy;
- jr ra
- sw t2,4(a3)
- # }
-.L.1:
- jr ra
- nop
- #}
- #
- .end s_mpv_mul_d_add
-
- .ent s_mpv_mul_d_add_prop
- .globl s_mpv_mul_d_add_prop
-
-s_mpv_mul_d_add_prop:
- #/* c += a * b */
- #void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b,
- # mp_digit *c)
- #{
- # mp_digit a0, a1; regs a4, a5
- # mp_digit c0, c1; regs a6, a7
- # mp_digit cy = 0; reg t2
- # mp_word w0, w1; regs t0, t1
- #
- # if (a_len) {
- beq a1,zero,.M.1
- move t2,zero # cy = 0
- dsll32 a2,a2,0 # "b" is sometimes negative (?!?!)
- dsrl32 a2,a2,0 # This clears the upper 32 bits.
- # a0 = a[0];
- lwu a4,0(a0)
- # w0 = ((mp_word)b * a0);
- dmultu a2,a4
- # if (--a_len) {
- addiu a1,a1,-1
- beq a1,zero,.M.2
- # while (a_len >= 2) {
- sltiu t3,a1,2
- bne t3,zero,.M.3
- # a1 = a[1];
- lwu a5,4(a0)
-.M.4:
- # a_len -= 2;
- addiu a1,a1,-2
- # c0 = c[0];
- lwu a6,0(a3)
- # w0 += cy;
- mflo t0
- daddu t0,t0,t2
- # w0 += c0;
- daddu t0,t0,a6
- # w1 = (mp_word)b * a1;
- dmultu a2,a5 #
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # a0 = a[2];
- lwu a4,8(a0)
- # a += 2;
- addiu a0,a0,8
- # c1 = c[1];
- lwu a7,4(a3)
- # w1 += cy;
- mflo t1
- daddu t1,t1,t2
- # w1 += c1;
- daddu t1,t1,a7
- # w0 = (mp_word)b * a0;
- dmultu a2,a4 #
- # cy = CARRYOUT(w1);
- dsrl32 t2,t1,0
- # c[1] = ACCUM(w1);
- sw t1,4(a3)
- # c += 2;
- addiu a3,a3,8
- sltiu t3,a1,2
- beq t3,zero,.M.4
- # a1 = a[1];
- lwu a5,4(a0)
- # }
-.M.3:
- # c0 = c[0];
- lwu a6,0(a3)
- # w0 += cy;
- # if (a_len) {
- mflo t0
- beq a1,zero,.M.5
- daddu t0,t0,t2
- # w1 = (mp_word)b * a1;
- dmultu a2,a5
- # w0 += c0;
- daddu t0,t0,a6 #
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # c1 = c[1];
- lwu a7,4(a3)
- # w1 += cy;
- mflo t1
- daddu t1,t1,t2
- # w1 += c1;
- daddu t1,t1,a7
- # c[1] = ACCUM(w1);
- sw t1,4(a3)
- # cy = CARRYOUT(w1);
- dsrl32 t2,t1,0
- # c += 1;
- b .M.6
- addiu a3,a3,8
- # } else {
-.M.5:
- # w0 += c0;
- daddu t0,t0,a6
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- b .M.6
- addiu a3,a3,4
- # }
- # } else {
-.M.2:
- # c0 = c[0];
- lwu a6,0(a3)
- # w0 += c0;
- mflo t0
- daddu t0,t0,a6
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- addiu a3,a3,4
- # }
-.M.6:
-
- # while (cy) {
- beq t2,zero,.M.1
- nop
-.M.7:
- # mp_word w = (mp_word)*c + cy;
- lwu a6,0(a3)
- daddu t2,t2,a6
- # *c++ = ACCUM(w);
- sw t2,0(a3)
- # cy = CARRYOUT(w);
- dsrl32 t2,t2,0
- bne t2,zero,.M.7
- addiu a3,a3,4
-
- # }
-.M.1:
- jr ra
- nop
- #}
- #
- .end s_mpv_mul_d_add_prop
-
- .ent s_mpv_mul_d
- .globl s_mpv_mul_d
-
-s_mpv_mul_d:
- #/* c = a * b */
- #void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b,
- # mp_digit *c)
- #{
- # mp_digit a0, a1; regs a4, a5
- # mp_digit cy = 0; reg t2
- # mp_word w0, w1; regs t0, t1
- #
- # if (a_len) {
- beq a1,zero,.N.1
- move t2,zero # cy = 0
- dsll32 a2,a2,0 # "b" is sometimes negative (?!?!)
- dsrl32 a2,a2,0 # This clears the upper 32 bits.
- # a0 = a[0];
- lwu a4,0(a0)
- # w0 = ((mp_word)b * a0);
- dmultu a2,a4
- # if (--a_len) {
- addiu a1,a1,-1
- beq a1,zero,.N.2
- # while (a_len >= 2) {
- sltiu t3,a1,2
- bne t3,zero,.N.3
- # a1 = a[1];
- lwu a5,4(a0)
-.N.4:
- # a_len -= 2;
- addiu a1,a1,-2
- # w0 += cy;
- mflo t0
- daddu t0,t0,t2
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- # w1 = (mp_word)b * a1;
- dmultu a2,a5
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # a0 = a[2];
- lwu a4,8(a0)
- # a += 2;
- addiu a0,a0,8
- # w1 += cy;
- mflo t1
- daddu t1,t1,t2
- # cy = CARRYOUT(w1);
- dsrl32 t2,t1,0
- # w0 = (mp_word)b * a0;
- dmultu a2,a4
- # c[1] = ACCUM(w1);
- sw t1,4(a3)
- # c += 2;
- addiu a3,a3,8
- sltiu t3,a1,2
- beq t3,zero,.N.4
- # a1 = a[1];
- lwu a5,4(a0)
- # }
-.N.3:
- # w0 += cy;
- # if (a_len) {
- mflo t0
- beq a1,zero,.N.5
- daddu t0,t0,t2
- # w1 = (mp_word)b * a1;
- dmultu a2,a5 #
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # w1 += cy;
- mflo t1
- daddu t1,t1,t2
- # c[1] = ACCUM(w1);
- sw t1,4(a3)
- # cy = CARRYOUT(w1);
- dsrl32 t2,t1,0
- # c += 1;
- b .N.6
- addiu a3,a3,4
- # } else {
-.N.5:
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # cy = CARRYOUT(w0);
- b .N.6
- dsrl32 t2,t0,0
- # }
- # } else {
-.N.2:
- mflo t0
- # c[0] = ACCUM(w0);
- sw t0,0(a3)
- # cy = CARRYOUT(w0);
- dsrl32 t2,t0,0
- # }
-.N.6:
- # c[1] = cy;
- jr ra
- sw t2,4(a3)
- # }
-.N.1:
- jr ra
- nop
- #}
- #
- .end s_mpv_mul_d
-
-
- .ent s_mpv_sqr_add_prop
- .globl s_mpv_sqr_add_prop
- #void s_mpv_sqr_add_prop(const mp_digit *a, mp_size a_len, mp_digit *sqrs);
- # registers
- # a0 *a
- # a1 a_len
- # a2 *sqr
- # a3 digit from *a, a_i
- # a4 square of digit from a
- # a5,a6 next 2 digits in sqr
- # a7,t0 carry
-s_mpv_sqr_add_prop:
- move a7,zero
- move t0,zero
- lwu a3,0(a0)
- addiu a1,a1,-1 # --a_len
- dmultu a3,a3
- beq a1,zero,.P.3 # jump if we've already done the only sqr
- addiu a0,a0,4 # ++a
-.P.2:
- lwu a5,0(a2)
- lwu a6,4(a2)
- addiu a2,a2,8 # sqrs += 2;
- dsll32 a6,a6,0
- daddu a5,a5,a6
- lwu a3,0(a0)
- addiu a0,a0,4 # ++a
- mflo a4
- daddu a6,a5,a4
- sltu a7,a6,a5 # a7 = a6 < a5 detect overflow
- dmultu a3,a3
- daddu a4,a6,t0
- sltu t0,a4,a6
- add t0,t0,a7
- sw a4,-8(a2)
- addiu a1,a1,-1 # --a_len
- dsrl32 a4,a4,0
- bne a1,zero,.P.2 # loop if a_len > 0
- sw a4,-4(a2)
-.P.3:
- lwu a5,0(a2)
- lwu a6,4(a2)
- addiu a2,a2,8 # sqrs += 2;
- dsll32 a6,a6,0
- daddu a5,a5,a6
- mflo a4
- daddu a6,a5,a4
- sltu a7,a6,a5 # a7 = a6 < a5 detect overflow
- daddu a4,a6,t0
- sltu t0,a4,a6
- add t0,t0,a7
- sw a4,-8(a2)
- beq t0,zero,.P.9 # jump if no carry
- dsrl32 a4,a4,0
-.P.8:
- sw a4,-4(a2)
- /* propagate final carry */
- lwu a5,0(a2)
- daddu a6,a5,t0
- sltu t0,a6,a5
- bne t0,zero,.P.8 # loop if carry persists
- addiu a2,a2,4 # sqrs++
-.P.9:
- jr ra
- sw a4,-4(a2)
-
- .end s_mpv_sqr_add_prop
diff --git a/security/nss/lib/freebl/mpi/mpi_sparc.c b/security/nss/lib/freebl/mpi/mpi_sparc.c
deleted file mode 100644
index 57f63c9b4..000000000
--- a/security/nss/lib/freebl/mpi/mpi_sparc.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* Multiplication performance enhancements for sparc v8+vis CPUs. */
-
-#include "mpi-priv.h"
-#include <stddef.h>
-#include <sys/systeminfo.h>
-#include <strings.h>
-
-/* In the functions below, */
-/* vector y must be 8-byte aligned, and n must be even */
-/* returns carry out of high order word of result */
-/* maximum n is 256 */
-
-/* vector x += vector y * scaler a; where y is of length n words. */
-extern mp_digit mul_add_inp(mp_digit *x, const mp_digit *y, int n, mp_digit a);
-
-/* vector z = vector x + vector y * scaler a; where y is of length n words. */
-extern mp_digit mul_add(mp_digit *z, const mp_digit *x, const mp_digit *y,
- int n, mp_digit a);
-
-/* v8 versions of these functions run on any Sparc v8 CPU. */
-
-/* This trick works on Sparc V8 CPUs with the Workshop compilers. */
-#define MP_MUL_DxD(a, b, Phi, Plo) \
- { unsigned long long product = (unsigned long long)a * b; \
- Plo = (mp_digit)product; \
- Phi = (mp_digit)(product >> MP_DIGIT_BIT); }
-
-/* c = a * b */
-static void
-v8_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
-#if !defined(MP_NO_MP_WORD)
- mp_digit d = 0;
-
- /* Inner product: Digits of a */
- while (a_len--) {
- mp_word w = ((mp_word)b * *a++) + d;
- *c++ = ACCUM(w);
- d = CARRYOUT(w);
- }
- *c = d;
-#else
- mp_digit carry = 0;
- while (a_len--) {
- mp_digit a_i = *a++;
- mp_digit a0b0, a1b1;
-
- MP_MUL_DxD(a_i, b, a1b1, a0b0);
-
- a0b0 += carry;
- if (a0b0 < carry)
- ++a1b1;
- *c++ = a0b0;
- carry = a1b1;
- }
- *c = carry;
-#endif
-}
-
-/* c += a * b */
-static void
-v8_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
-#if !defined(MP_NO_MP_WORD)
- mp_digit d = 0;
-
- /* Inner product: Digits of a */
- while (a_len--) {
- mp_word w = ((mp_word)b * *a++) + *c + d;
- *c++ = ACCUM(w);
- d = CARRYOUT(w);
- }
- *c = d;
-#else
- mp_digit carry = 0;
- while (a_len--) {
- mp_digit a_i = *a++;
- mp_digit a0b0, a1b1;
-
- MP_MUL_DxD(a_i, b, a1b1, a0b0);
-
- a0b0 += carry;
- if (a0b0 < carry)
- ++a1b1;
- a0b0 += a_i = *c;
- if (a0b0 < a_i)
- ++a1b1;
- *c++ = a0b0;
- carry = a1b1;
- }
- *c = carry;
-#endif
-}
-
-/* Presently, this is only used by the Montgomery arithmetic code. */
-/* c += a * b */
-static void
-v8_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
-#if !defined(MP_NO_MP_WORD)
- mp_digit d = 0;
-
- /* Inner product: Digits of a */
- while (a_len--) {
- mp_word w = ((mp_word)b * *a++) + *c + d;
- *c++ = ACCUM(w);
- d = CARRYOUT(w);
- }
-
- while (d) {
- mp_word w = (mp_word)*c + d;
- *c++ = ACCUM(w);
- d = CARRYOUT(w);
- }
-#else
- mp_digit carry = 0;
- while (a_len--) {
- mp_digit a_i = *a++;
- mp_digit a0b0, a1b1;
-
- MP_MUL_DxD(a_i, b, a1b1, a0b0);
-
- a0b0 += carry;
- if (a0b0 < carry)
- ++a1b1;
-
- a0b0 += a_i = *c;
- if (a0b0 < a_i)
- ++a1b1;
-
- *c++ = a0b0;
- carry = a1b1;
- }
- while (carry) {
- mp_digit c_i = *c;
- carry += c_i;
- *c++ = carry;
- carry = carry < c_i;
- }
-#endif
-}
-
-/* These functions run only on v8plus+vis or v9+vis CPUs. */
-
-/* c = a * b */
-void
-s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- mp_digit d;
- mp_digit x[258];
- if (a_len <= 256) {
- if (a == c || ((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) {
- mp_digit * px;
- px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x;
- memcpy(px, a, a_len * sizeof(*a));
- a = px;
- if (a_len & 1) {
- px[a_len] = 0;
- }
- }
- s_mp_setz(c, a_len + 1);
- d = mul_add_inp(c, a, a_len, b);
- c[a_len] = d;
- } else {
- v8_mpv_mul_d(a, a_len, b, c);
- }
-}
-
-/* c += a * b, where a is a_len words long. */
-void
-s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- mp_digit d;
- mp_digit x[258];
- if (a_len <= 256) {
- if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) {
- mp_digit * px;
- px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x;
- memcpy(px, a, a_len * sizeof(*a));
- a = px;
- if (a_len & 1) {
- px[a_len] = 0;
- }
- }
- d = mul_add_inp(c, a, a_len, b);
- c[a_len] = d;
- } else {
- v8_mpv_mul_d_add(a, a_len, b, c);
- }
-}
-
-/* c += a * b, where a is y words long. */
-void
-s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- mp_digit d;
- mp_digit x[258];
- if (a_len <= 256) {
- if (((ptrdiff_t)a & 0x7) != 0 || (a_len & 1) != 0) {
- mp_digit * px;
- px = (((ptrdiff_t)x & 0x7) != 0) ? x + 1 : x;
- memcpy(px, a, a_len * sizeof(*a));
- a = px;
- if (a_len & 1) {
- px[a_len] = 0;
- }
- }
- d = mul_add_inp(c, a, a_len, b);
- if (d) {
- c += a_len;
- do {
- mp_digit sum = d + *c;
- *c++ = sum;
- d = sum < d;
- } while (d);
- }
- } else {
- v8_mpv_mul_d_add_prop(a, a_len, b, c);
- }
-}
diff --git a/security/nss/lib/freebl/mpi/mpi_sse2.s b/security/nss/lib/freebl/mpi/mpi_sse2.s
deleted file mode 100644
index 16a47019c..000000000
--- a/security/nss/lib/freebl/mpi/mpi_sse2.s
+++ /dev/null
@@ -1,294 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifdef DARWIN
-#define s_mpv_mul_d _s_mpv_mul_d
-#define s_mpv_mul_d_add _s_mpv_mul_d_add
-#define s_mpv_mul_d_add_prop _s_mpv_mul_d_add_prop
-#define s_mpv_sqr_add_prop _s_mpv_sqr_add_prop
-#define s_mpv_div_2dx1d _s_mpv_div_2dx1d
-#define TYPE_FUNCTION(x)
-#else
-#define TYPE_FUNCTION(x) .type x, @function
-#endif
-
-.text
-
- # ebp - 8: caller's esi
- # ebp - 4: caller's edi
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: a argument
- # ebp + 12: a_len argument
- # ebp + 16: b argument
- # ebp + 20: c argument
- # registers:
- # ebx:
- # ecx: a_len
- # esi: a ptr
- # edi: c ptr
-.globl s_mpv_mul_d
-.private_extern s_mpv_mul_d
-TYPE_FUNCTION(s_mpv_mul_d)
-s_mpv_mul_d:
- push %ebp
- mov %esp, %ebp
- push %edi
- push %esi
- psubq %mm2, %mm2 # carry = 0
- mov 12(%ebp), %ecx # ecx = a_len
- movd 16(%ebp), %mm1 # mm1 = b
- mov 20(%ebp), %edi
- cmp $0, %ecx
- je 2f # jmp if a_len == 0
- mov 8(%ebp), %esi # esi = a
- cld
-1:
- movd 0(%esi), %mm0 # mm0 = *a++
- add $4, %esi
- pmuludq %mm1, %mm0 # mm0 = b * *a++
- paddq %mm0, %mm2 # add the carry
- movd %mm2, 0(%edi) # store the 32bit result
- add $4, %edi
- psrlq $32, %mm2 # save the carry
- dec %ecx # --a_len
- jnz 1b # jmp if a_len != 0
-2:
- movd %mm2, 0(%edi) # *c = carry
- emms
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- # ebp - 8: caller's esi
- # ebp - 4: caller's edi
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: a argument
- # ebp + 12: a_len argument
- # ebp + 16: b argument
- # ebp + 20: c argument
- # registers:
- # ebx:
- # ecx: a_len
- # esi: a ptr
- # edi: c ptr
-.globl s_mpv_mul_d_add
-.private_extern s_mpv_mul_d_add
-TYPE_FUNCTION(s_mpv_mul_d_add)
-s_mpv_mul_d_add:
- push %ebp
- mov %esp, %ebp
- push %edi
- push %esi
- psubq %mm2, %mm2 # carry = 0
- mov 12(%ebp), %ecx # ecx = a_len
- movd 16(%ebp), %mm1 # mm1 = b
- mov 20(%ebp), %edi
- cmp $0, %ecx
- je 2f # jmp if a_len == 0
- mov 8(%ebp), %esi # esi = a
- cld
-1:
- movd 0(%esi), %mm0 # mm0 = *a++
- add $4, %esi
- pmuludq %mm1, %mm0 # mm0 = b * *a++
- paddq %mm0, %mm2 # add the carry
- movd 0(%edi), %mm0
- paddq %mm0, %mm2 # add the carry
- movd %mm2, 0(%edi) # store the 32bit result
- add $4, %edi
- psrlq $32, %mm2 # save the carry
- dec %ecx # --a_len
- jnz 1b # jmp if a_len != 0
-2:
- movd %mm2, 0(%edi) # *c = carry
- emms
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- # ebp - 12: caller's ebx
- # ebp - 8: caller's esi
- # ebp - 4: caller's edi
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: a argument
- # ebp + 12: a_len argument
- # ebp + 16: b argument
- # ebp + 20: c argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # esi: a ptr
- # edi: c ptr
-.globl s_mpv_mul_d_add_prop
-.private_extern s_mpv_mul_d_add_prop
-TYPE_FUNCTION(s_mpv_mul_d_add_prop)
-s_mpv_mul_d_add_prop:
- push %ebp
- mov %esp, %ebp
- push %edi
- push %esi
- push %ebx
- psubq %mm2, %mm2 # carry = 0
- mov 12(%ebp), %ecx # ecx = a_len
- movd 16(%ebp), %mm1 # mm1 = b
- mov 20(%ebp), %edi
- cmp $0, %ecx
- je 2f # jmp if a_len == 0
- mov 8(%ebp), %esi # esi = a
- cld
-1:
- movd 0(%esi), %mm0 # mm0 = *a++
- movd 0(%edi), %mm3 # fetch the sum
- add $4, %esi
- pmuludq %mm1, %mm0 # mm0 = b * *a++
- paddq %mm0, %mm2 # add the carry
- paddq %mm3, %mm2 # add *c++
- movd %mm2, 0(%edi) # store the 32bit result
- add $4, %edi
- psrlq $32, %mm2 # save the carry
- dec %ecx # --a_len
- jnz 1b # jmp if a_len != 0
-2:
- movd %mm2, %ebx
- cmp $0, %ebx # is carry zero?
- jz 4f
- mov 0(%edi), %eax
- add %ebx, %eax
- stosl
- jnc 4f
-3:
- mov 0(%edi), %eax # add in current word from *c
- adc $0, %eax
- stosl # [es:edi] = ax; edi += 4;
- jc 3b
-4:
- emms
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- # ebp - 12: caller's ebx
- # ebp - 8: caller's esi
- # ebp - 4: caller's edi
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: pa argument
- # ebp + 12: a_len argument
- # ebp + 16: ps argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # esi: a ptr
- # edi: c ptr
-.globl s_mpv_sqr_add_prop
-.private_extern s_mpv_sqr_add_prop
-TYPE_FUNCTION(s_mpv_sqr_add_prop)
-s_mpv_sqr_add_prop:
- push %ebp
- mov %esp, %ebp
- push %edi
- push %esi
- push %ebx
- psubq %mm2, %mm2 # carry = 0
- mov 12(%ebp), %ecx # ecx = a_len
- mov 16(%ebp), %edi
- cmp $0, %ecx
- je 2f # jmp if a_len == 0
- mov 8(%ebp), %esi # esi = a
- cld
-1:
- movd 0(%esi), %mm0 # mm0 = *a
- movd 0(%edi), %mm3 # fetch the sum
- add $4, %esi
- pmuludq %mm0, %mm0 # mm0 = sqr(a)
- paddq %mm0, %mm2 # add the carry
- paddq %mm3, %mm2 # add the low word
- movd 4(%edi), %mm3
- movd %mm2, 0(%edi) # store the 32bit result
- psrlq $32, %mm2
- paddq %mm3, %mm2 # add the high word
- movd %mm2, 4(%edi) # store the 32bit result
- psrlq $32, %mm2 # save the carry.
- add $8, %edi
- dec %ecx # --a_len
- jnz 1b # jmp if a_len != 0
-2:
- movd %mm2, %ebx
- cmp $0, %ebx # is carry zero?
- jz 4f
- mov 0(%edi), %eax
- add %ebx, %eax
- stosl
- jnc 4f
-3:
- mov 0(%edi), %eax # add in current word from *c
- adc $0, %eax
- stosl # [es:edi] = ax; edi += 4;
- jc 3b
-4:
- emms
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- #
- # Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
- # so its high bit is 1. This code is from NSPR.
- #
- # mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
- # mp_digit *qp, mp_digit *rp)
-
- # esp + 0: Caller's ebx
- # esp + 4: return address
- # esp + 8: Nhi argument
- # esp + 12: Nlo argument
- # esp + 16: divisor argument
- # esp + 20: qp argument
- # esp + 24: rp argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
- #
-.globl s_mpv_div_2dx1d
-.private_extern s_mpv_div_2dx1d
-TYPE_FUNCTION(s_mpv_div_2dx1d)
-s_mpv_div_2dx1d:
- push %ebx
- mov 8(%esp), %edx
- mov 12(%esp), %eax
- mov 16(%esp), %ebx
- div %ebx
- mov 20(%esp), %ebx
- mov %eax, 0(%ebx)
- mov 24(%esp), %ebx
- mov %edx, 0(%ebx)
- xor %eax, %eax # return zero
- pop %ebx
- ret
- nop
-
-#ifndef DARWIN
- # Magic indicating no need for an executable stack
-.section .note.GNU-stack, "", @progbits
-.previous
-#endif
diff --git a/security/nss/lib/freebl/mpi/mpi_x86.s b/security/nss/lib/freebl/mpi/mpi_x86.s
deleted file mode 100644
index bedf6bea0..000000000
--- a/security/nss/lib/freebl/mpi/mpi_x86.s
+++ /dev/null
@@ -1,544 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-#
-
-.data
-.align 4
- #
- # -1 means to call s_mpi_is_sse to determine if we support sse
- # instructions.
- # 0 means to use x86 instructions
- # 1 means to use sse2 instructions
-.type is_sse,@object
-.size is_sse,4
-is_sse: .long -1
-
-#
-# sigh, handle the difference between -fPIC and not PIC
-# default to pic, since this file seems to be exclusively
-# linux right now (solaris uses mpi_i86pc.s and windows uses
-# mpi_x86_asm.c)
-#
-.ifndef NO_PIC
-.macro GET var,reg
- movl \var@GOTOFF(%ebx),\reg
-.endm
-.macro PUT reg,var
- movl \reg,\var@GOTOFF(%ebx)
-.endm
-.else
-.macro GET var,reg
- movl \var,\reg
-.endm
-.macro PUT reg,var
- movl \reg,\var
-.endm
-.endif
-
-.text
-
-
- # ebp - 36: caller's esi
- # ebp - 32: caller's edi
- # ebp - 28:
- # ebp - 24:
- # ebp - 20:
- # ebp - 16:
- # ebp - 12:
- # ebp - 8:
- # ebp - 4:
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: a argument
- # ebp + 12: a_len argument
- # ebp + 16: b argument
- # ebp + 20: c argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
-.globl s_mpv_mul_d
-.type s_mpv_mul_d,@function
-s_mpv_mul_d:
- GET is_sse,%eax
- cmp $0,%eax
- je s_mpv_mul_d_x86
- jg s_mpv_mul_d_sse2
- call s_mpi_is_sse2
- PUT %eax,is_sse
- cmp $0,%eax
- jg s_mpv_mul_d_sse2
-s_mpv_mul_d_x86:
- push %ebp
- mov %esp,%ebp
- sub $28,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 2f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-1:
- lodsl # eax = [ds:esi]; esi += 4
- mov 16(%ebp),%edx # edx = b
- mull %edx # edx:eax = Phi:Plo = a_i * b
-
- add %ebx,%eax # add carry (%ebx) to edx:eax
- adc $0,%edx
- mov %edx,%ebx # high half of product becomes next carry
-
- stosl # [es:edi] = ax; edi += 4;
- dec %ecx # --a_len
- jnz 1b # jmp if a_len != 0
-2:
- mov %ebx,0(%edi) # *c = carry
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-s_mpv_mul_d_sse2:
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- psubq %mm2,%mm2 # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- movd 16(%ebp),%mm1 # mm1 = b
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 6f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-5:
- movd 0(%esi),%mm0 # mm0 = *a++
- add $4,%esi
- pmuludq %mm1,%mm0 # mm0 = b * *a++
- paddq %mm0,%mm2 # add the carry
- movd %mm2,0(%edi) # store the 32bit result
- add $4,%edi
- psrlq $32, %mm2 # save the carry
- dec %ecx # --a_len
- jnz 5b # jmp if a_len != 0
-6:
- movd %mm2,0(%edi) # *c = carry
- emms
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- # ebp - 36: caller's esi
- # ebp - 32: caller's edi
- # ebp - 28:
- # ebp - 24:
- # ebp - 20:
- # ebp - 16:
- # ebp - 12:
- # ebp - 8:
- # ebp - 4:
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: a argument
- # ebp + 12: a_len argument
- # ebp + 16: b argument
- # ebp + 20: c argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
-.globl s_mpv_mul_d_add
-.type s_mpv_mul_d_add,@function
-s_mpv_mul_d_add:
- GET is_sse,%eax
- cmp $0,%eax
- je s_mpv_mul_d_add_x86
- jg s_mpv_mul_d_add_sse2
- call s_mpi_is_sse2
- PUT %eax,is_sse
- cmp $0,%eax
- jg s_mpv_mul_d_add_sse2
-s_mpv_mul_d_add_x86:
- push %ebp
- mov %esp,%ebp
- sub $28,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 11f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-10:
- lodsl # eax = [ds:esi]; esi += 4
- mov 16(%ebp),%edx # edx = b
- mull %edx # edx:eax = Phi:Plo = a_i * b
-
- add %ebx,%eax # add carry (%ebx) to edx:eax
- adc $0,%edx
- mov 0(%edi),%ebx # add in current word from *c
- add %ebx,%eax
- adc $0,%edx
- mov %edx,%ebx # high half of product becomes next carry
-
- stosl # [es:edi] = ax; edi += 4;
- dec %ecx # --a_len
- jnz 10b # jmp if a_len != 0
-11:
- mov %ebx,0(%edi) # *c = carry
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-s_mpv_mul_d_add_sse2:
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- psubq %mm2,%mm2 # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- movd 16(%ebp),%mm1 # mm1 = b
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 16f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-15:
- movd 0(%esi),%mm0 # mm0 = *a++
- add $4,%esi
- pmuludq %mm1,%mm0 # mm0 = b * *a++
- paddq %mm0,%mm2 # add the carry
- movd 0(%edi),%mm0
- paddq %mm0,%mm2 # add the carry
- movd %mm2,0(%edi) # store the 32bit result
- add $4,%edi
- psrlq $32, %mm2 # save the carry
- dec %ecx # --a_len
- jnz 15b # jmp if a_len != 0
-16:
- movd %mm2,0(%edi) # *c = carry
- emms
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- # ebp - 8: caller's esi
- # ebp - 4: caller's edi
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: a argument
- # ebp + 12: a_len argument
- # ebp + 16: b argument
- # ebp + 20: c argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
-.globl s_mpv_mul_d_add_prop
-.type s_mpv_mul_d_add_prop,@function
-s_mpv_mul_d_add_prop:
- GET is_sse,%eax
- cmp $0,%eax
- je s_mpv_mul_d_add_prop_x86
- jg s_mpv_mul_d_add_prop_sse2
- call s_mpi_is_sse2
- PUT %eax,is_sse
- cmp $0,%eax
- jg s_mpv_mul_d_add_prop_sse2
-s_mpv_mul_d_add_prop_x86:
- push %ebp
- mov %esp,%ebp
- sub $28,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 21f # jmp if a_len == 0
- cld
- mov 8(%ebp),%esi # esi = a
-20:
- lodsl # eax = [ds:esi]; esi += 4
- mov 16(%ebp),%edx # edx = b
- mull %edx # edx:eax = Phi:Plo = a_i * b
-
- add %ebx,%eax # add carry (%ebx) to edx:eax
- adc $0,%edx
- mov 0(%edi),%ebx # add in current word from *c
- add %ebx,%eax
- adc $0,%edx
- mov %edx,%ebx # high half of product becomes next carry
-
- stosl # [es:edi] = ax; edi += 4;
- dec %ecx # --a_len
- jnz 20b # jmp if a_len != 0
-21:
- cmp $0,%ebx # is carry zero?
- jz 23f
- mov 0(%edi),%eax # add in current word from *c
- add %ebx,%eax
- stosl # [es:edi] = ax; edi += 4;
- jnc 23f
-22:
- mov 0(%edi),%eax # add in current word from *c
- adc $0,%eax
- stosl # [es:edi] = ax; edi += 4;
- jc 22b
-23:
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-s_mpv_mul_d_add_prop_sse2:
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- push %ebx
- psubq %mm2,%mm2 # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- movd 16(%ebp),%mm1 # mm1 = b
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 26f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-25:
- movd 0(%esi),%mm0 # mm0 = *a++
- movd 0(%edi),%mm3 # fetch the sum
- add $4,%esi
- pmuludq %mm1,%mm0 # mm0 = b * *a++
- paddq %mm0,%mm2 # add the carry
- paddq %mm3,%mm2 # add *c++
- movd %mm2,0(%edi) # store the 32bit result
- add $4,%edi
- psrlq $32, %mm2 # save the carry
- dec %ecx # --a_len
- jnz 25b # jmp if a_len != 0
-26:
- movd %mm2,%ebx
- cmp $0,%ebx # is carry zero?
- jz 28f
- mov 0(%edi),%eax
- add %ebx, %eax
- stosl
- jnc 28f
-27:
- mov 0(%edi),%eax # add in current word from *c
- adc $0,%eax
- stosl # [es:edi] = ax; edi += 4;
- jc 27b
-28:
- emms
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
-
- # ebp - 20: caller's esi
- # ebp - 16: caller's edi
- # ebp - 12:
- # ebp - 8: carry
- # ebp - 4: a_len local
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: pa argument
- # ebp + 12: a_len argument
- # ebp + 16: ps argument
- # ebp + 20:
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
-
-.globl s_mpv_sqr_add_prop
-.type s_mpv_sqr_add_prop,@function
-s_mpv_sqr_add_prop:
- GET is_sse,%eax
- cmp $0,%eax
- je s_mpv_sqr_add_prop_x86
- jg s_mpv_sqr_add_prop_sse2
- call s_mpi_is_sse2
- PUT %eax,is_sse
- cmp $0,%eax
- jg s_mpv_sqr_add_prop_sse2
-s_mpv_sqr_add_prop_x86:
- push %ebp
- mov %esp,%ebp
- sub $12,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx # carry = 0
- mov 12(%ebp),%ecx # a_len
- mov 16(%ebp),%edi # edi = ps
- cmp $0,%ecx
- je 31f # jump if a_len == 0
- cld
- mov 8(%ebp),%esi # esi = pa
-30:
- lodsl # %eax = [ds:si]; si += 4;
- mull %eax
-
- add %ebx,%eax # add "carry"
- adc $0,%edx
- mov 0(%edi),%ebx
- add %ebx,%eax # add low word from result
- mov 4(%edi),%ebx
- stosl # [es:di] = %eax; di += 4;
- adc %ebx,%edx # add high word from result
- movl $0,%ebx
- mov %edx,%eax
- adc $0,%ebx
- stosl # [es:di] = %eax; di += 4;
- dec %ecx # --a_len
- jnz 30b # jmp if a_len != 0
-31:
- cmp $0,%ebx # is carry zero?
- jz 34f
- mov 0(%edi),%eax # add in current word from *c
- add %ebx,%eax
- stosl # [es:edi] = ax; edi += 4;
- jnc 34f
-32:
- mov 0(%edi),%eax # add in current word from *c
- adc $0,%eax
- stosl # [es:edi] = ax; edi += 4;
- jc 32b
-34:
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-s_mpv_sqr_add_prop_sse2:
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- push %ebx
- psubq %mm2,%mm2 # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- mov 16(%ebp),%edi
- cmp $0,%ecx
- je 36f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-35:
- movd 0(%esi),%mm0 # mm0 = *a
- movd 0(%edi),%mm3 # fetch the sum
- add $4,%esi
- pmuludq %mm0,%mm0 # mm0 = sqr(a)
- paddq %mm0,%mm2 # add the carry
- paddq %mm3,%mm2 # add the low word
- movd 4(%edi),%mm3
- movd %mm2,0(%edi) # store the 32bit result
- psrlq $32, %mm2
- paddq %mm3,%mm2 # add the high word
- movd %mm2,4(%edi) # store the 32bit result
- psrlq $32, %mm2 # save the carry.
- add $8,%edi
- dec %ecx # --a_len
- jnz 35b # jmp if a_len != 0
-36:
- movd %mm2,%ebx
- cmp $0,%ebx # is carry zero?
- jz 38f
- mov 0(%edi),%eax
- add %ebx, %eax
- stosl
- jnc 38f
-37:
- mov 0(%edi),%eax # add in current word from *c
- adc $0,%eax
- stosl # [es:edi] = ax; edi += 4;
- jc 37b
-38:
- emms
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- #
- # Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
- # so its high bit is 1. This code is from NSPR.
- #
- # mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
- # mp_digit *qp, mp_digit *rp)
-
- # esp + 0: Caller's ebx
- # esp + 4: return address
- # esp + 8: Nhi argument
- # esp + 12: Nlo argument
- # esp + 16: divisor argument
- # esp + 20: qp argument
- # esp + 24: rp argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
- #
-
-.globl s_mpv_div_2dx1d
-.type s_mpv_div_2dx1d,@function
-s_mpv_div_2dx1d:
- push %ebx
- mov 8(%esp),%edx
- mov 12(%esp),%eax
- mov 16(%esp),%ebx
- div %ebx
- mov 20(%esp),%ebx
- mov %eax,0(%ebx)
- mov 24(%esp),%ebx
- mov %edx,0(%ebx)
- xor %eax,%eax # return zero
- pop %ebx
- ret
- nop
-
- # Magic indicating no need for an executable stack
-.section .note.GNU-stack, "", @progbits
-.previous
diff --git a/security/nss/lib/freebl/mpi/mpi_x86_asm.c b/security/nss/lib/freebl/mpi/mpi_x86_asm.c
deleted file mode 100644
index e25166e58..000000000
--- a/security/nss/lib/freebl/mpi/mpi_x86_asm.c
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * mpi_x86_asm.c - MSVC inline assembly implementation of s_mpv_ functions.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi-priv.h"
-
-static int is_sse = -1;
-extern unsigned long s_mpi_is_sse2();
-
-/*
- * ebp - 36: caller's esi
- * ebp - 32: caller's edi
- * ebp - 28:
- * ebp - 24:
- * ebp - 20:
- * ebp - 16:
- * ebp - 12:
- * ebp - 8:
- * ebp - 4:
- * ebp + 0: caller's ebp
- * ebp + 4: return address
- * ebp + 8: a argument
- * ebp + 12: a_len argument
- * ebp + 16: b argument
- * ebp + 20: c argument
- * registers:
- * eax:
- * ebx: carry
- * ecx: a_len
- * edx:
- * esi: a ptr
- * edi: c ptr
- */
-__declspec(naked) void
-s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- __asm {
- mov eax, is_sse
- cmp eax, 0
- je s_mpv_mul_d_x86
- jg s_mpv_mul_d_sse2
- call s_mpi_is_sse2
- mov is_sse, eax
- cmp eax, 0
- jg s_mpv_mul_d_sse2
-s_mpv_mul_d_x86:
- push ebp
- mov ebp,esp
- sub esp,28
- push edi
- push esi
- push ebx
- mov ebx,0 ; carry = 0
- mov ecx,[ebp+12] ; ecx = a_len
- mov edi,[ebp+20]
- cmp ecx,0
- je L_2 ; jmp if a_len == 0
- mov esi,[ebp+8] ; esi = a
- cld
-L_1:
- lodsd ; eax = [ds:esi]; esi += 4
- mov edx,[ebp+16] ; edx = b
- mul edx ; edx:eax = Phi:Plo = a_i * b
-
- add eax,ebx ; add carry (ebx) to edx:eax
- adc edx,0
- mov ebx,edx ; high half of product becomes next carry
-
- stosd ; [es:edi] = ax; edi += 4;
- dec ecx ; --a_len
- jnz L_1 ; jmp if a_len != 0
-L_2:
- mov [edi],ebx ; *c = carry
- pop ebx
- pop esi
- pop edi
- leave
- ret
- nop
-s_mpv_mul_d_sse2:
- push ebp
- mov ebp, esp
- push edi
- push esi
- psubq mm2, mm2 ; carry = 0
- mov ecx, [ebp+12] ; ecx = a_len
- movd mm1, [ebp+16] ; mm1 = b
- mov edi, [ebp+20]
- cmp ecx, 0
- je L_6 ; jmp if a_len == 0
- mov esi, [ebp+8] ; esi = a
- cld
-L_5:
- movd mm0, [esi] ; mm0 = *a++
- add esi, 4
- pmuludq mm0, mm1 ; mm0 = b * *a++
- paddq mm2, mm0 ; add the carry
- movd [edi], mm2 ; store the 32bit result
- add edi, 4
- psrlq mm2, 32 ; save the carry
- dec ecx ; --a_len
- jnz L_5 ; jmp if a_len != 0
-L_6:
- movd [edi], mm2 ; *c = carry
- emms
- pop esi
- pop edi
- leave
- ret
- nop
- }
-}
-
-/*
- * ebp - 36: caller's esi
- * ebp - 32: caller's edi
- * ebp - 28:
- * ebp - 24:
- * ebp - 20:
- * ebp - 16:
- * ebp - 12:
- * ebp - 8:
- * ebp - 4:
- * ebp + 0: caller's ebp
- * ebp + 4: return address
- * ebp + 8: a argument
- * ebp + 12: a_len argument
- * ebp + 16: b argument
- * ebp + 20: c argument
- * registers:
- * eax:
- * ebx: carry
- * ecx: a_len
- * edx:
- * esi: a ptr
- * edi: c ptr
- */
-__declspec(naked) void
-s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- __asm {
- mov eax, is_sse
- cmp eax, 0
- je s_mpv_mul_d_add_x86
- jg s_mpv_mul_d_add_sse2
- call s_mpi_is_sse2
- mov is_sse, eax
- cmp eax, 0
- jg s_mpv_mul_d_add_sse2
-s_mpv_mul_d_add_x86:
- push ebp
- mov ebp,esp
- sub esp,28
- push edi
- push esi
- push ebx
- mov ebx,0 ; carry = 0
- mov ecx,[ebp+12] ; ecx = a_len
- mov edi,[ebp+20]
- cmp ecx,0
- je L_11 ; jmp if a_len == 0
- mov esi,[ebp+8] ; esi = a
- cld
-L_10:
- lodsd ; eax = [ds:esi]; esi += 4
- mov edx,[ebp+16] ; edx = b
- mul edx ; edx:eax = Phi:Plo = a_i * b
-
- add eax,ebx ; add carry (ebx) to edx:eax
- adc edx,0
- mov ebx,[edi] ; add in current word from *c
- add eax,ebx
- adc edx,0
- mov ebx,edx ; high half of product becomes next carry
-
- stosd ; [es:edi] = ax; edi += 4;
- dec ecx ; --a_len
- jnz L_10 ; jmp if a_len != 0
-L_11:
- mov [edi],ebx ; *c = carry
- pop ebx
- pop esi
- pop edi
- leave
- ret
- nop
-s_mpv_mul_d_add_sse2:
- push ebp
- mov ebp, esp
- push edi
- push esi
- psubq mm2, mm2 ; carry = 0
- mov ecx, [ebp+12] ; ecx = a_len
- movd mm1, [ebp+16] ; mm1 = b
- mov edi, [ebp+20]
- cmp ecx, 0
- je L_16 ; jmp if a_len == 0
- mov esi, [ebp+8] ; esi = a
- cld
-L_15:
- movd mm0, [esi] ; mm0 = *a++
- add esi, 4
- pmuludq mm0, mm1 ; mm0 = b * *a++
- paddq mm2, mm0 ; add the carry
- movd mm0, [edi]
- paddq mm2, mm0 ; add the carry
- movd [edi], mm2 ; store the 32bit result
- add edi, 4
- psrlq mm2, 32 ; save the carry
- dec ecx ; --a_len
- jnz L_15 ; jmp if a_len != 0
-L_16:
- movd [edi], mm2 ; *c = carry
- emms
- pop esi
- pop edi
- leave
- ret
- nop
- }
-}
-
-/*
- * ebp - 36: caller's esi
- * ebp - 32: caller's edi
- * ebp - 28:
- * ebp - 24:
- * ebp - 20:
- * ebp - 16:
- * ebp - 12:
- * ebp - 8:
- * ebp - 4:
- * ebp + 0: caller's ebp
- * ebp + 4: return address
- * ebp + 8: a argument
- * ebp + 12: a_len argument
- * ebp + 16: b argument
- * ebp + 20: c argument
- * registers:
- * eax:
- * ebx: carry
- * ecx: a_len
- * edx:
- * esi: a ptr
- * edi: c ptr
- */
-__declspec(naked) void
-s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
-{
- __asm {
- mov eax, is_sse
- cmp eax, 0
- je s_mpv_mul_d_add_prop_x86
- jg s_mpv_mul_d_add_prop_sse2
- call s_mpi_is_sse2
- mov is_sse, eax
- cmp eax, 0
- jg s_mpv_mul_d_add_prop_sse2
-s_mpv_mul_d_add_prop_x86:
- push ebp
- mov ebp,esp
- sub esp,28
- push edi
- push esi
- push ebx
- mov ebx,0 ; carry = 0
- mov ecx,[ebp+12] ; ecx = a_len
- mov edi,[ebp+20]
- cmp ecx,0
- je L_21 ; jmp if a_len == 0
- cld
- mov esi,[ebp+8] ; esi = a
-L_20:
- lodsd ; eax = [ds:esi]; esi += 4
- mov edx,[ebp+16] ; edx = b
- mul edx ; edx:eax = Phi:Plo = a_i * b
-
- add eax,ebx ; add carry (ebx) to edx:eax
- adc edx,0
- mov ebx,[edi] ; add in current word from *c
- add eax,ebx
- adc edx,0
- mov ebx,edx ; high half of product becomes next carry
-
- stosd ; [es:edi] = ax; edi += 4;
- dec ecx ; --a_len
- jnz L_20 ; jmp if a_len != 0
-L_21:
- cmp ebx,0 ; is carry zero?
- jz L_23
- mov eax,[edi] ; add in current word from *c
- add eax,ebx
- stosd ; [es:edi] = ax; edi += 4;
- jnc L_23
-L_22:
- mov eax,[edi] ; add in current word from *c
- adc eax,0
- stosd ; [es:edi] = ax; edi += 4;
- jc L_22
-L_23:
- pop ebx
- pop esi
- pop edi
- leave
- ret
- nop
-s_mpv_mul_d_add_prop_sse2:
- push ebp
- mov ebp, esp
- push edi
- push esi
- push ebx
- psubq mm2, mm2 ; carry = 0
- mov ecx, [ebp+12] ; ecx = a_len
- movd mm1, [ebp+16] ; mm1 = b
- mov edi, [ebp+20]
- cmp ecx, 0
- je L_26 ; jmp if a_len == 0
- mov esi, [ebp+8] ; esi = a
- cld
-L_25:
- movd mm0, [esi] ; mm0 = *a++
- movd mm3, [edi] ; fetch the sum
- add esi, 4
- pmuludq mm0, mm1 ; mm0 = b * *a++
- paddq mm2, mm0 ; add the carry
- paddq mm2, mm3 ; add *c++
- movd [edi], mm2 ; store the 32bit result
- add edi, 4
- psrlq mm2, 32 ; save the carry
- dec ecx ; --a_len
- jnz L_25 ; jmp if a_len != 0
-L_26:
- movd ebx, mm2
- cmp ebx, 0 ; is carry zero?
- jz L_28
- mov eax, [edi]
- add eax, ebx
- stosd
- jnc L_28
-L_27:
- mov eax, [edi] ; add in current word from *c
- adc eax, 0
- stosd ; [es:edi] = ax; edi += 4;
- jc L_27
-L_28:
- emms
- pop ebx
- pop esi
- pop edi
- leave
- ret
- nop
- }
-}
-
-/*
- * ebp - 20: caller's esi
- * ebp - 16: caller's edi
- * ebp - 12:
- * ebp - 8: carry
- * ebp - 4: a_len local
- * ebp + 0: caller's ebp
- * ebp + 4: return address
- * ebp + 8: pa argument
- * ebp + 12: a_len argument
- * ebp + 16: ps argument
- * ebp + 20:
- * registers:
- * eax:
- * ebx: carry
- * ecx: a_len
- * edx:
- * esi: a ptr
- * edi: c ptr
- */
-__declspec(naked) void
-s_mpv_sqr_add_prop(const mp_digit *a, mp_size a_len, mp_digit *sqrs)
-{
- __asm {
- mov eax, is_sse
- cmp eax, 0
- je s_mpv_sqr_add_prop_x86
- jg s_mpv_sqr_add_prop_sse2
- call s_mpi_is_sse2
- mov is_sse, eax
- cmp eax, 0
- jg s_mpv_sqr_add_prop_sse2
-s_mpv_sqr_add_prop_x86:
- push ebp
- mov ebp,esp
- sub esp,12
- push edi
- push esi
- push ebx
- mov ebx,0 ; carry = 0
- mov ecx,[ebp+12] ; a_len
- mov edi,[ebp+16] ; edi = ps
- cmp ecx,0
- je L_31 ; jump if a_len == 0
- cld
- mov esi,[ebp+8] ; esi = pa
-L_30:
- lodsd ; eax = [ds:si]; si += 4;
- mul eax
-
- add eax,ebx ; add "carry"
- adc edx,0
- mov ebx,[edi]
- add eax,ebx ; add low word from result
- mov ebx,[edi+4]
- stosd ; [es:di] = eax; di += 4;
- adc edx,ebx ; add high word from result
- mov ebx,0
- mov eax,edx
- adc ebx,0
- stosd ; [es:di] = eax; di += 4;
- dec ecx ; --a_len
- jnz L_30 ; jmp if a_len != 0
-L_31:
- cmp ebx,0 ; is carry zero?
- jz L_34
- mov eax,[edi] ; add in current word from *c
- add eax,ebx
- stosd ; [es:edi] = ax; edi += 4;
- jnc L_34
-L_32:
- mov eax,[edi] ; add in current word from *c
- adc eax,0
- stosd ; [es:edi] = ax; edi += 4;
- jc L_32
-L_34:
- pop ebx
- pop esi
- pop edi
- leave
- ret
- nop
-s_mpv_sqr_add_prop_sse2:
- push ebp
- mov ebp, esp
- push edi
- push esi
- push ebx
- psubq mm2, mm2 ; carry = 0
- mov ecx, [ebp+12] ; ecx = a_len
- mov edi, [ebp+16]
- cmp ecx, 0
- je L_36 ; jmp if a_len == 0
- mov esi, [ebp+8] ; esi = a
- cld
-L_35:
- movd mm0, [esi] ; mm0 = *a
- movd mm3, [edi] ; fetch the sum
- add esi, 4
- pmuludq mm0, mm0 ; mm0 = sqr(a)
- paddq mm2, mm0 ; add the carry
- paddq mm2, mm3 ; add the low word
- movd mm3, [edi+4]
- movd [edi], mm2 ; store the 32bit result
- psrlq mm2, 32
- paddq mm2, mm3 ; add the high word
- movd [edi+4], mm2 ; store the 32bit result
- psrlq mm2, 32 ; save the carry.
- add edi, 8
- dec ecx ; --a_len
- jnz L_35 ; jmp if a_len != 0
-L_36:
- movd ebx, mm2
- cmp ebx, 0 ; is carry zero?
- jz L_38
- mov eax, [edi]
- add eax, ebx
- stosd
- jnc L_38
-L_37:
- mov eax, [edi] ; add in current word from *c
- adc eax, 0
- stosd ; [es:edi] = ax; edi += 4;
- jc L_37
-L_38:
- emms
- pop ebx
- pop esi
- pop edi
- leave
- ret
- nop
- }
-}
-
-/*
- * Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
- * so its high bit is 1. This code is from NSPR.
- *
- * Dump of assembler code for function s_mpv_div_2dx1d:
- *
- * esp + 0: Caller's ebx
- * esp + 4: return address
- * esp + 8: Nhi argument
- * esp + 12: Nlo argument
- * esp + 16: divisor argument
- * esp + 20: qp argument
- * esp + 24: rp argument
- * registers:
- * eax:
- * ebx: carry
- * ecx: a_len
- * edx:
- * esi: a ptr
- * edi: c ptr
- */
-__declspec(naked) mp_err
-s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
- mp_digit *qp, mp_digit *rp)
-{
- __asm {
- push ebx
- mov edx,[esp+8]
- mov eax,[esp+12]
- mov ebx,[esp+16]
- div ebx
- mov ebx,[esp+20]
- mov [ebx],eax
- mov ebx,[esp+24]
- mov [ebx],edx
- xor eax,eax ; return zero
- pop ebx
- ret
- nop
- }
-}
diff --git a/security/nss/lib/freebl/mpi/mpi_x86_os2.s b/security/nss/lib/freebl/mpi/mpi_x86_os2.s
deleted file mode 100644
index 82e555280..000000000
--- a/security/nss/lib/freebl/mpi/mpi_x86_os2.s
+++ /dev/null
@@ -1,541 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-#
-
-.data
-.align 4
- #
- # -1 means to call _s_mpi_is_sse to determine if we support sse
- # instructions.
- # 0 means to use x86 instructions
- # 1 means to use sse2 instructions
-.type is_sse,@object
-.size is_sse,4
-is_sse: .long -1
-
-#
-# sigh, handle the difference between -fPIC and not PIC
-# default to pic, since this file seems to be exclusively
-# linux right now (solaris uses mpi_i86pc.s and windows uses
-# mpi_x86_asm.c)
-#
-#.ifndef NO_PIC
-#.macro GET var,reg
-# movl \var@GOTOFF(%ebx),\reg
-#.endm
-#.macro PUT reg,var
-# movl \reg,\var@GOTOFF(%ebx)
-#.endm
-#.else
-.macro GET var,reg
- movl \var,\reg
-.endm
-.macro PUT reg,var
- movl \reg,\var
-.endm
-#.endif
-
-.text
-
-
- # ebp - 36: caller's esi
- # ebp - 32: caller's edi
- # ebp - 28:
- # ebp - 24:
- # ebp - 20:
- # ebp - 16:
- # ebp - 12:
- # ebp - 8:
- # ebp - 4:
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: a argument
- # ebp + 12: a_len argument
- # ebp + 16: b argument
- # ebp + 20: c argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
-.globl _s_mpv_mul_d
-.type _s_mpv_mul_d,@function
-_s_mpv_mul_d:
- GET is_sse,%eax
- cmp $0,%eax
- je _s_mpv_mul_d_x86
- jg _s_mpv_mul_d_sse2
- call _s_mpi_is_sse2
- PUT %eax,is_sse
- cmp $0,%eax
- jg _s_mpv_mul_d_sse2
-_s_mpv_mul_d_x86:
- push %ebp
- mov %esp,%ebp
- sub $28,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 2f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-1:
- lodsl # eax = [ds:esi]; esi += 4
- mov 16(%ebp),%edx # edx = b
- mull %edx # edx:eax = Phi:Plo = a_i * b
-
- add %ebx,%eax # add carry (%ebx) to edx:eax
- adc $0,%edx
- mov %edx,%ebx # high half of product becomes next carry
-
- stosl # [es:edi] = ax; edi += 4;
- dec %ecx # --a_len
- jnz 1b # jmp if a_len != 0
-2:
- mov %ebx,0(%edi) # *c = carry
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-_s_mpv_mul_d_sse2:
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- psubq %mm2,%mm2 # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- movd 16(%ebp),%mm1 # mm1 = b
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 6f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-5:
- movd 0(%esi),%mm0 # mm0 = *a++
- add $4,%esi
- pmuludq %mm1,%mm0 # mm0 = b * *a++
- paddq %mm0,%mm2 # add the carry
- movd %mm2,0(%edi) # store the 32bit result
- add $4,%edi
- psrlq $32, %mm2 # save the carry
- dec %ecx # --a_len
- jnz 5b # jmp if a_len != 0
-6:
- movd %mm2,0(%edi) # *c = carry
- emms
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- # ebp - 36: caller's esi
- # ebp - 32: caller's edi
- # ebp - 28:
- # ebp - 24:
- # ebp - 20:
- # ebp - 16:
- # ebp - 12:
- # ebp - 8:
- # ebp - 4:
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: a argument
- # ebp + 12: a_len argument
- # ebp + 16: b argument
- # ebp + 20: c argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
-.globl _s_mpv_mul_d_add
-.type _s_mpv_mul_d_add,@function
-_s_mpv_mul_d_add:
- GET is_sse,%eax
- cmp $0,%eax
- je _s_mpv_mul_d_add_x86
- jg _s_mpv_mul_d_add_sse2
- call _s_mpi_is_sse2
- PUT %eax,is_sse
- cmp $0,%eax
- jg _s_mpv_mul_d_add_sse2
-_s_mpv_mul_d_add_x86:
- push %ebp
- mov %esp,%ebp
- sub $28,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 11f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-10:
- lodsl # eax = [ds:esi]; esi += 4
- mov 16(%ebp),%edx # edx = b
- mull %edx # edx:eax = Phi:Plo = a_i * b
-
- add %ebx,%eax # add carry (%ebx) to edx:eax
- adc $0,%edx
- mov 0(%edi),%ebx # add in current word from *c
- add %ebx,%eax
- adc $0,%edx
- mov %edx,%ebx # high half of product becomes next carry
-
- stosl # [es:edi] = ax; edi += 4;
- dec %ecx # --a_len
- jnz 10b # jmp if a_len != 0
-11:
- mov %ebx,0(%edi) # *c = carry
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-_s_mpv_mul_d_add_sse2:
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- psubq %mm2,%mm2 # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- movd 16(%ebp),%mm1 # mm1 = b
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 16f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-15:
- movd 0(%esi),%mm0 # mm0 = *a++
- add $4,%esi
- pmuludq %mm1,%mm0 # mm0 = b * *a++
- paddq %mm0,%mm2 # add the carry
- movd 0(%edi),%mm0
- paddq %mm0,%mm2 # add the carry
- movd %mm2,0(%edi) # store the 32bit result
- add $4,%edi
- psrlq $32, %mm2 # save the carry
- dec %ecx # --a_len
- jnz 15b # jmp if a_len != 0
-16:
- movd %mm2,0(%edi) # *c = carry
- emms
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- # ebp - 8: caller's esi
- # ebp - 4: caller's edi
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: a argument
- # ebp + 12: a_len argument
- # ebp + 16: b argument
- # ebp + 20: c argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
-.globl _s_mpv_mul_d_add_prop
-.type _s_mpv_mul_d_add_prop,@function
-_s_mpv_mul_d_add_prop:
- GET is_sse,%eax
- cmp $0,%eax
- je _s_mpv_mul_d_add_prop_x86
- jg _s_mpv_mul_d_add_prop_sse2
- call _s_mpi_is_sse2
- PUT %eax,is_sse
- cmp $0,%eax
- jg _s_mpv_mul_d_add_prop_sse2
-_s_mpv_mul_d_add_prop_x86:
- push %ebp
- mov %esp,%ebp
- sub $28,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 21f # jmp if a_len == 0
- cld
- mov 8(%ebp),%esi # esi = a
-20:
- lodsl # eax = [ds:esi]; esi += 4
- mov 16(%ebp),%edx # edx = b
- mull %edx # edx:eax = Phi:Plo = a_i * b
-
- add %ebx,%eax # add carry (%ebx) to edx:eax
- adc $0,%edx
- mov 0(%edi),%ebx # add in current word from *c
- add %ebx,%eax
- adc $0,%edx
- mov %edx,%ebx # high half of product becomes next carry
-
- stosl # [es:edi] = ax; edi += 4;
- dec %ecx # --a_len
- jnz 20b # jmp if a_len != 0
-21:
- cmp $0,%ebx # is carry zero?
- jz 23f
- mov 0(%edi),%eax # add in current word from *c
- add %ebx,%eax
- stosl # [es:edi] = ax; edi += 4;
- jnc 23f
-22:
- mov 0(%edi),%eax # add in current word from *c
- adc $0,%eax
- stosl # [es:edi] = ax; edi += 4;
- jc 22b
-23:
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-_s_mpv_mul_d_add_prop_sse2:
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- push %ebx
- psubq %mm2,%mm2 # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- movd 16(%ebp),%mm1 # mm1 = b
- mov 20(%ebp),%edi
- cmp $0,%ecx
- je 26f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-25:
- movd 0(%esi),%mm0 # mm0 = *a++
- movd 0(%edi),%mm3 # fetch the sum
- add $4,%esi
- pmuludq %mm1,%mm0 # mm0 = b * *a++
- paddq %mm0,%mm2 # add the carry
- paddq %mm3,%mm2 # add *c++
- movd %mm2,0(%edi) # store the 32bit result
- add $4,%edi
- psrlq $32, %mm2 # save the carry
- dec %ecx # --a_len
- jnz 25b # jmp if a_len != 0
-26:
- movd %mm2,%ebx
- cmp $0,%ebx # is carry zero?
- jz 28f
- mov 0(%edi),%eax
- add %ebx, %eax
- stosl
- jnc 28f
-27:
- mov 0(%edi),%eax # add in current word from *c
- adc $0,%eax
- stosl # [es:edi] = ax; edi += 4;
- jc 27b
-28:
- emms
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
-
- # ebp - 20: caller's esi
- # ebp - 16: caller's edi
- # ebp - 12:
- # ebp - 8: carry
- # ebp - 4: a_len local
- # ebp + 0: caller's ebp
- # ebp + 4: return address
- # ebp + 8: pa argument
- # ebp + 12: a_len argument
- # ebp + 16: ps argument
- # ebp + 20:
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
-
-.globl _s_mpv_sqr_add_prop
-.type _s_mpv_sqr_add_prop,@function
-_s_mpv_sqr_add_prop:
- GET is_sse,%eax
- cmp $0,%eax
- je _s_mpv_sqr_add_prop_x86
- jg _s_mpv_sqr_add_prop_sse2
- call _s_mpi_is_sse2
- PUT %eax,is_sse
- cmp $0,%eax
- jg _s_mpv_sqr_add_prop_sse2
-_s_mpv_sqr_add_prop_x86:
- push %ebp
- mov %esp,%ebp
- sub $12,%esp
- push %edi
- push %esi
- push %ebx
- movl $0,%ebx # carry = 0
- mov 12(%ebp),%ecx # a_len
- mov 16(%ebp),%edi # edi = ps
- cmp $0,%ecx
- je 31f # jump if a_len == 0
- cld
- mov 8(%ebp),%esi # esi = pa
-30:
- lodsl # %eax = [ds:si]; si += 4;
- mull %eax
-
- add %ebx,%eax # add "carry"
- adc $0,%edx
- mov 0(%edi),%ebx
- add %ebx,%eax # add low word from result
- mov 4(%edi),%ebx
- stosl # [es:di] = %eax; di += 4;
- adc %ebx,%edx # add high word from result
- movl $0,%ebx
- mov %edx,%eax
- adc $0,%ebx
- stosl # [es:di] = %eax; di += 4;
- dec %ecx # --a_len
- jnz 30b # jmp if a_len != 0
-31:
- cmp $0,%ebx # is carry zero?
- jz 34f
- mov 0(%edi),%eax # add in current word from *c
- add %ebx,%eax
- stosl # [es:edi] = ax; edi += 4;
- jnc 34f
-32:
- mov 0(%edi),%eax # add in current word from *c
- adc $0,%eax
- stosl # [es:edi] = ax; edi += 4;
- jc 32b
-34:
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-_s_mpv_sqr_add_prop_sse2:
- push %ebp
- mov %esp,%ebp
- push %edi
- push %esi
- push %ebx
- psubq %mm2,%mm2 # carry = 0
- mov 12(%ebp),%ecx # ecx = a_len
- mov 16(%ebp),%edi
- cmp $0,%ecx
- je 36f # jmp if a_len == 0
- mov 8(%ebp),%esi # esi = a
- cld
-35:
- movd 0(%esi),%mm0 # mm0 = *a
- movd 0(%edi),%mm3 # fetch the sum
- add $4,%esi
- pmuludq %mm0,%mm0 # mm0 = sqr(a)
- paddq %mm0,%mm2 # add the carry
- paddq %mm3,%mm2 # add the low word
- movd 4(%edi),%mm3
- movd %mm2,0(%edi) # store the 32bit result
- psrlq $32, %mm2
- paddq %mm3,%mm2 # add the high word
- movd %mm2,4(%edi) # store the 32bit result
- psrlq $32, %mm2 # save the carry.
- add $8,%edi
- dec %ecx # --a_len
- jnz 35b # jmp if a_len != 0
-36:
- movd %mm2,%ebx
- cmp $0,%ebx # is carry zero?
- jz 38f
- mov 0(%edi),%eax
- add %ebx, %eax
- stosl
- jnc 38f
-37:
- mov 0(%edi),%eax # add in current word from *c
- adc $0,%eax
- stosl # [es:edi] = ax; edi += 4;
- jc 37b
-38:
- emms
- pop %ebx
- pop %esi
- pop %edi
- leave
- ret
- nop
-
- #
- # Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
- # so its high bit is 1. This code is from NSPR.
- #
- # mp_err _s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
- # mp_digit *qp, mp_digit *rp)
-
- # esp + 0: Caller's ebx
- # esp + 4: return address
- # esp + 8: Nhi argument
- # esp + 12: Nlo argument
- # esp + 16: divisor argument
- # esp + 20: qp argument
- # esp + 24: rp argument
- # registers:
- # eax:
- # ebx: carry
- # ecx: a_len
- # edx:
- # esi: a ptr
- # edi: c ptr
- #
-
-.globl _s_mpv_div_2dx1d
-.type _s_mpv_div_2dx1d,@function
-_s_mpv_div_2dx1d:
- push %ebx
- mov 8(%esp),%edx
- mov 12(%esp),%eax
- mov 16(%esp),%ebx
- div %ebx
- mov 20(%esp),%ebx
- mov %eax,0(%ebx)
- mov 24(%esp),%ebx
- mov %edx,0(%ebx)
- xor %eax,%eax # return zero
- pop %ebx
- ret
- nop
-
diff --git a/security/nss/lib/freebl/mpi/mplogic.c b/security/nss/lib/freebl/mpi/mplogic.c
deleted file mode 100644
index e2e651dd3..000000000
--- a/security/nss/lib/freebl/mpi/mplogic.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * mplogic.c
- *
- * Bitwise logical operations on MPI values
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "mpi-priv.h"
-#include "mplogic.h"
-
-/* {{{ Lookup table for population count */
-
-static unsigned char bitc[] = {
- 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
- 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
-};
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/*
- mpl_not(a, b) - compute b = ~a
- mpl_and(a, b, c) - compute c = a & b
- mpl_or(a, b, c) - compute c = a | b
- mpl_xor(a, b, c) - compute c = a ^ b
- */
-
-/* {{{ mpl_not(a, b) */
-
-mp_err mpl_not(mp_int *a, mp_int *b)
-{
- mp_err res;
- unsigned int ix;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
-
- /* This relies on the fact that the digit type is unsigned */
- for(ix = 0; ix < USED(b); ix++)
- DIGIT(b, ix) = ~DIGIT(b, ix);
-
- s_mp_clamp(b);
-
- return MP_OKAY;
-
-} /* end mpl_not() */
-
-/* }}} */
-
-/* {{{ mpl_and(a, b, c) */
-
-mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c)
-{
- mp_int *which, *other;
- mp_err res;
- unsigned int ix;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if(USED(a) <= USED(b)) {
- which = a;
- other = b;
- } else {
- which = b;
- other = a;
- }
-
- if((res = mp_copy(which, c)) != MP_OKAY)
- return res;
-
- for(ix = 0; ix < USED(which); ix++)
- DIGIT(c, ix) &= DIGIT(other, ix);
-
- s_mp_clamp(c);
-
- return MP_OKAY;
-
-} /* end mpl_and() */
-
-/* }}} */
-
-/* {{{ mpl_or(a, b, c) */
-
-mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c)
-{
- mp_int *which, *other;
- mp_err res;
- unsigned int ix;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if(USED(a) >= USED(b)) {
- which = a;
- other = b;
- } else {
- which = b;
- other = a;
- }
-
- if((res = mp_copy(which, c)) != MP_OKAY)
- return res;
-
- for(ix = 0; ix < USED(which); ix++)
- DIGIT(c, ix) |= DIGIT(other, ix);
-
- return MP_OKAY;
-
-} /* end mpl_or() */
-
-/* }}} */
-
-/* {{{ mpl_xor(a, b, c) */
-
-mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c)
-{
- mp_int *which, *other;
- mp_err res;
- unsigned int ix;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if(USED(a) >= USED(b)) {
- which = a;
- other = b;
- } else {
- which = b;
- other = a;
- }
-
- if((res = mp_copy(which, c)) != MP_OKAY)
- return res;
-
- for(ix = 0; ix < USED(which); ix++)
- DIGIT(c, ix) ^= DIGIT(other, ix);
-
- s_mp_clamp(c);
-
- return MP_OKAY;
-
-} /* end mpl_xor() */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/*
- mpl_rsh(a, b, d) - b = a >> d
- mpl_lsh(a, b, d) - b = a << d
- */
-
-/* {{{ mpl_rsh(a, b, d) */
-
-mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
-{
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
-
- s_mp_div_2d(b, d);
-
- return MP_OKAY;
-
-} /* end mpl_rsh() */
-
-/* }}} */
-
-/* {{{ mpl_lsh(a, b, d) */
-
-mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
-{
- mp_err res;
-
- ARGCHK(a != NULL && b != NULL, MP_BADARG);
-
- if((res = mp_copy(a, b)) != MP_OKAY)
- return res;
-
- return s_mp_mul_2d(b, d);
-
-} /* end mpl_lsh() */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/*
- mpl_num_set(a, num)
-
- Count the number of set bits in the binary representation of a.
- Returns MP_OKAY and sets 'num' to be the number of such bits, if
- possible. If num is NULL, the result is thrown away, but it is
- not considered an error.
-
- mpl_num_clear() does basically the same thing for clear bits.
- */
-
-/* {{{ mpl_num_set(a, num) */
-
-mp_err mpl_num_set(mp_int *a, int *num)
-{
- unsigned int ix;
- int db, nset = 0;
- mp_digit cur;
- unsigned char reg;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- for(ix = 0; ix < USED(a); ix++) {
- cur = DIGIT(a, ix);
-
- for(db = 0; db < sizeof(mp_digit); db++) {
- reg = (unsigned char)(cur >> (CHAR_BIT * db));
-
- nset += bitc[reg];
- }
- }
-
- if(num)
- *num = nset;
-
- return MP_OKAY;
-
-} /* end mpl_num_set() */
-
-/* }}} */
-
-/* {{{ mpl_num_clear(a, num) */
-
-mp_err mpl_num_clear(mp_int *a, int *num)
-{
- unsigned int ix;
- int db, nset = 0;
- mp_digit cur;
- unsigned char reg;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- for(ix = 0; ix < USED(a); ix++) {
- cur = DIGIT(a, ix);
-
- for(db = 0; db < sizeof(mp_digit); db++) {
- reg = (unsigned char)(cur >> (CHAR_BIT * db));
-
- nset += bitc[UCHAR_MAX - reg];
- }
- }
-
- if(num)
- *num = nset;
-
- return MP_OKAY;
-
-
-} /* end mpl_num_clear() */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/*
- mpl_parity(a)
-
- Determines the bitwise parity of the value given. Returns MP_EVEN
- if an even number of digits are set, MP_ODD if an odd number are
- set.
- */
-
-/* {{{ mpl_parity(a) */
-
-mp_err mpl_parity(mp_int *a)
-{
- unsigned int ix;
- int par = 0;
- mp_digit cur;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- for(ix = 0; ix < USED(a); ix++) {
- int shft = (sizeof(mp_digit) * CHAR_BIT) / 2;
-
- cur = DIGIT(a, ix);
-
- /* Compute parity for current digit */
- while(shft != 0) {
- cur ^= (cur >> shft);
- shft >>= 1;
- }
- cur &= 1;
-
- /* XOR with running parity so far */
- par ^= cur;
- }
-
- if(par)
- return MP_ODD;
- else
- return MP_EVEN;
-
-} /* end mpl_parity() */
-
-/* }}} */
-
-/*
- mpl_set_bit
-
- Returns MP_OKAY or some error code.
- Grows a if needed to set a bit to 1.
- */
-mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value)
-{
- mp_size ix;
- mp_err rv;
- mp_digit mask;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- ix = bitNum / MP_DIGIT_BIT;
- if (ix + 1 > MP_USED(a)) {
- rv = s_mp_pad(a, ix + 1);
- if (rv != MP_OKAY)
- return rv;
- }
-
- bitNum = bitNum % MP_DIGIT_BIT;
- mask = (mp_digit)1 << bitNum;
- if (value)
- MP_DIGIT(a,ix) |= mask;
- else
- MP_DIGIT(a,ix) &= ~mask;
- s_mp_clamp(a);
- return MP_OKAY;
-}
-
-/*
- mpl_get_bit
-
- returns 0 or 1 or some (negative) error code.
- */
-mp_err mpl_get_bit(const mp_int *a, mp_size bitNum)
-{
- mp_size bit, ix;
- mp_err rv;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- ix = bitNum / MP_DIGIT_BIT;
- ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE);
-
- bit = bitNum % MP_DIGIT_BIT;
- rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1;
- return rv;
-}
-
-/*
- mpl_get_bits
- - Extracts numBits bits from a, where the least significant extracted bit
- is bit lsbNum. Returns a negative value if error occurs.
- - Because sign bit is used to indicate error, maximum number of bits to
- be returned is the lesser of (a) the number of bits in an mp_digit, or
- (b) one less than the number of bits in an mp_err.
- - lsbNum + numbits can be greater than the number of significant bits in
- integer a, as long as bit lsbNum is in the high order digit of a.
- */
-mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits)
-{
- mp_size rshift = (lsbNum % MP_DIGIT_BIT);
- mp_size lsWndx = (lsbNum / MP_DIGIT_BIT);
- mp_digit * digit = MP_DIGITS(a) + lsWndx;
- mp_digit mask = ((1 << numBits) - 1);
-
- ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG);
- ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE);
-
- if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) ||
- (lsWndx + 1 >= MP_USED(a))) {
- mask &= (digit[0] >> rshift);
- } else {
- mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift)));
- }
- return (mp_err)mask;
-}
-
-/*
- mpl_significant_bits
- returns number of significnant bits in abs(a).
- returns 1 if value is zero.
- */
-mp_err mpl_significant_bits(const mp_int *a)
-{
- mp_err bits = 0;
- int ix;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- ix = MP_USED(a);
- for (ix = MP_USED(a); ix > 0; ) {
- mp_digit d;
- d = MP_DIGIT(a, --ix);
- if (d) {
- while (d) {
- ++bits;
- d >>= 1;
- }
- break;
- }
- }
- bits += ix * MP_DIGIT_BIT;
- if (!bits)
- bits = 1;
- return bits;
-}
-
-/*------------------------------------------------------------------------*/
-/* HERE THERE BE DRAGONS */
diff --git a/security/nss/lib/freebl/mpi/mplogic.h b/security/nss/lib/freebl/mpi/mplogic.h
deleted file mode 100644
index faf1acb99..000000000
--- a/security/nss/lib/freebl/mpi/mplogic.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * mplogic.h
- *
- * Bitwise logical operations on MPI values
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _H_MPLOGIC_
-#define _H_MPLOGIC_
-
-#include "mpi.h"
-
-/*
- The logical operations treat an mp_int as if it were a bit vector,
- without regard to its sign (an mp_int is represented in a signed
- magnitude format). Values are treated as if they had an infinite
- string of zeros left of the most-significant bit.
- */
-
-/* Parity results */
-
-#define MP_EVEN MP_YES
-#define MP_ODD MP_NO
-
-/* Bitwise functions */
-
-mp_err mpl_not(mp_int *a, mp_int *b); /* one's complement */
-mp_err mpl_and(mp_int *a, mp_int *b, mp_int *c); /* bitwise AND */
-mp_err mpl_or(mp_int *a, mp_int *b, mp_int *c); /* bitwise OR */
-mp_err mpl_xor(mp_int *a, mp_int *b, mp_int *c); /* bitwise XOR */
-
-/* Shift functions */
-
-mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d); /* right shift */
-mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d); /* left shift */
-
-/* Bit count and parity */
-
-mp_err mpl_num_set(mp_int *a, int *num); /* count set bits */
-mp_err mpl_num_clear(mp_int *a, int *num); /* count clear bits */
-mp_err mpl_parity(mp_int *a); /* determine parity */
-
-/* Get & Set the value of a bit */
-
-mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value);
-mp_err mpl_get_bit(const mp_int *a, mp_size bitNum);
-mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits);
-mp_err mpl_significant_bits(const mp_int *a);
-
-#endif /* end _H_MPLOGIC_ */
diff --git a/security/nss/lib/freebl/mpi/mpmontg.c b/security/nss/lib/freebl/mpi/mpmontg.c
deleted file mode 100644
index 0fefe678a..000000000
--- a/security/nss/lib/freebl/mpi/mpmontg.c
+++ /dev/null
@@ -1,1174 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* This file implements moduluar exponentiation using Montgomery's
- * method for modular reduction. This file implements the method
- * described as "Improvement 2" in the paper "A Cryptogrpahic Library for
- * the Motorola DSP56000" by Stephen R. Dusse' and Burton S. Kaliski Jr.
- * published in "Advances in Cryptology: Proceedings of EUROCRYPT '90"
- * "Lecture Notes in Computer Science" volume 473, 1991, pg 230-244,
- * published by Springer Verlag.
- */
-
-#define MP_USING_CACHE_SAFE_MOD_EXP 1
-#include <string.h>
-#include "mpi-priv.h"
-#include "mplogic.h"
-#include "mpprime.h"
-#ifdef MP_USING_MONT_MULF
-#include "montmulf.h"
-#endif
-#include <stddef.h> /* ptrdiff_t */
-
-/* if MP_CHAR_STORE_SLOW is defined, we */
-/* need to know endianness of this platform. */
-#ifdef MP_CHAR_STORE_SLOW
-#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN)
-#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \
- " if you define MP_CHAR_STORE_SLOW."
-#endif
-#endif
-
-#define STATIC
-
-#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */
-
-/*! computes T = REDC(T), 2^b == R
- \param T < RN
-*/
-mp_err s_mp_redc(mp_int *T, mp_mont_modulus *mmm)
-{
- mp_err res;
- mp_size i;
-
- i = (MP_USED(&mmm->N) << 1) + 1;
- MP_CHECKOK( s_mp_pad(T, i) );
- for (i = 0; i < MP_USED(&mmm->N); ++i ) {
- mp_digit m_i = MP_DIGIT(T, i) * mmm->n0prime;
- /* T += N * m_i * (MP_RADIX ** i); */
- MP_CHECKOK( s_mp_mul_d_add_offset(&mmm->N, m_i, T, i) );
- }
- s_mp_clamp(T);
-
- /* T /= R */
- s_mp_rshd( T, MP_USED(&mmm->N) );
-
- if ((res = s_mp_cmp(T, &mmm->N)) >= 0) {
- /* T = T - N */
- MP_CHECKOK( s_mp_sub(T, &mmm->N) );
-#ifdef DEBUG
- if ((res = mp_cmp(T, &mmm->N)) >= 0) {
- res = MP_UNDEF;
- goto CLEANUP;
- }
-#endif
- }
- res = MP_OKAY;
-CLEANUP:
- return res;
-}
-
-#if !defined(MP_MONT_USE_MP_MUL)
-
-/*! c <- REDC( a * b ) mod N
- \param a < N i.e. "reduced"
- \param b < N i.e. "reduced"
- \param mmm modulus N and n0' of N
-*/
-mp_err s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
- mp_mont_modulus *mmm)
-{
- mp_digit *pb;
- mp_digit m_i;
- mp_err res;
- mp_size ib; /* "index b": index of current digit of B */
- mp_size useda, usedb;
-
- ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
-
- if (MP_USED(a) < MP_USED(b)) {
- const mp_int *xch = b; /* switch a and b, to do fewer outer loops */
- b = a;
- a = xch;
- }
-
- MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
- ib = (MP_USED(&mmm->N) << 1) + 1;
- if((res = s_mp_pad(c, ib)) != MP_OKAY)
- goto CLEANUP;
-
- useda = MP_USED(a);
- pb = MP_DIGITS(b);
- s_mpv_mul_d(MP_DIGITS(a), useda, *pb++, MP_DIGITS(c));
- s_mp_setz(MP_DIGITS(c) + useda + 1, ib - (useda + 1));
- m_i = MP_DIGIT(c, 0) * mmm->n0prime;
- s_mp_mul_d_add_offset(&mmm->N, m_i, c, 0);
-
- /* Outer loop: Digits of b */
- usedb = MP_USED(b);
- for (ib = 1; ib < usedb; ib++) {
- mp_digit b_i = *pb++;
-
- /* Inner product: Digits of a */
- if (b_i)
- s_mpv_mul_d_add_prop(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
- m_i = MP_DIGIT(c, ib) * mmm->n0prime;
- s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
- }
- if (usedb < MP_USED(&mmm->N)) {
- for (usedb = MP_USED(&mmm->N); ib < usedb; ++ib ) {
- m_i = MP_DIGIT(c, ib) * mmm->n0prime;
- s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
- }
- }
- s_mp_clamp(c);
- s_mp_rshd( c, MP_USED(&mmm->N) ); /* c /= R */
- if (s_mp_cmp(c, &mmm->N) >= 0) {
- MP_CHECKOK( s_mp_sub(c, &mmm->N) );
- }
- res = MP_OKAY;
-
-CLEANUP:
- return res;
-}
-#endif
-
-STATIC
-mp_err s_mp_to_mont(const mp_int *x, mp_mont_modulus *mmm, mp_int *xMont)
-{
- mp_err res;
-
- /* xMont = x * R mod N where N is modulus */
- MP_CHECKOK( mp_copy( x, xMont ) );
- MP_CHECKOK( s_mp_lshd( xMont, MP_USED(&mmm->N) ) ); /* xMont = x << b */
- MP_CHECKOK( mp_div(xMont, &mmm->N, 0, xMont) ); /* mod N */
-CLEANUP:
- return res;
-}
-
-#ifdef MP_USING_MONT_MULF
-
-/* the floating point multiply is already cache safe,
- * don't turn on cache safe unless we specifically
- * force it */
-#ifndef MP_FORCE_CACHE_SAFE
-#undef MP_USING_CACHE_SAFE_MOD_EXP
-#endif
-
-unsigned int mp_using_mont_mulf = 1;
-
-/* computes montgomery square of the integer in mResult */
-#define SQR \
- conv_i32_to_d32_and_d16(dm1, d16Tmp, mResult, nLen); \
- mont_mulf_noconv(mResult, dm1, d16Tmp, \
- dTmp, dn, MP_DIGITS(modulus), nLen, dn0)
-
-/* computes montgomery product of x and the integer in mResult */
-#define MUL(x) \
- conv_i32_to_d32(dm1, mResult, nLen); \
- mont_mulf_noconv(mResult, dm1, oddPowers[x], \
- dTmp, dn, MP_DIGITS(modulus), nLen, dn0)
-
-/* Do modular exponentiation using floating point multiply code. */
-mp_err mp_exptmod_f(const mp_int * montBase,
- const mp_int * exponent,
- const mp_int * modulus,
- mp_int * result,
- mp_mont_modulus *mmm,
- int nLen,
- mp_size bits_in_exponent,
- mp_size window_bits,
- mp_size odd_ints)
-{
- mp_digit *mResult;
- double *dBuf = 0, *dm1, *dn, *dSqr, *d16Tmp, *dTmp;
- double dn0;
- mp_size i;
- mp_err res;
- int expOff;
- int dSize = 0, oddPowSize, dTmpSize;
- mp_int accum1;
- double *oddPowers[MAX_ODD_INTS];
-
- /* function for computing n0prime only works if n0 is odd */
-
- MP_DIGITS(&accum1) = 0;
-
- for (i = 0; i < MAX_ODD_INTS; ++i)
- oddPowers[i] = 0;
-
- MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) );
-
- mp_set(&accum1, 1);
- MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) );
- MP_CHECKOK( s_mp_pad(&accum1, nLen) );
-
- oddPowSize = 2 * nLen + 1;
- dTmpSize = 2 * oddPowSize;
- dSize = sizeof(double) * (nLen * 4 + 1 +
- ((odd_ints + 1) * oddPowSize) + dTmpSize);
- dBuf = (double *)malloc(dSize);
- dm1 = dBuf; /* array of d32 */
- dn = dBuf + nLen; /* array of d32 */
- dSqr = dn + nLen; /* array of d32 */
- d16Tmp = dSqr + nLen; /* array of d16 */
- dTmp = d16Tmp + oddPowSize;
-
- for (i = 0; i < odd_ints; ++i) {
- oddPowers[i] = dTmp;
- dTmp += oddPowSize;
- }
- mResult = (mp_digit *)(dTmp + dTmpSize); /* size is nLen + 1 */
-
- /* Make dn and dn0 */
- conv_i32_to_d32(dn, MP_DIGITS(modulus), nLen);
- dn0 = (double)(mmm->n0prime & 0xffff);
-
- /* Make dSqr */
- conv_i32_to_d32_and_d16(dm1, oddPowers[0], MP_DIGITS(montBase), nLen);
- mont_mulf_noconv(mResult, dm1, oddPowers[0],
- dTmp, dn, MP_DIGITS(modulus), nLen, dn0);
- conv_i32_to_d32(dSqr, mResult, nLen);
-
- for (i = 1; i < odd_ints; ++i) {
- mont_mulf_noconv(mResult, dSqr, oddPowers[i - 1],
- dTmp, dn, MP_DIGITS(modulus), nLen, dn0);
- conv_i32_to_d16(oddPowers[i], mResult, nLen);
- }
-
- s_mp_copy(MP_DIGITS(&accum1), mResult, nLen); /* from, to, len */
-
- for (expOff = bits_in_exponent - window_bits; expOff >= 0; expOff -= window_bits) {
- mp_size smallExp;
- MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) );
- smallExp = (mp_size)res;
-
- if (window_bits == 1) {
- if (!smallExp) {
- SQR;
- } else if (smallExp & 1) {
- SQR; MUL(0);
- } else {
- abort();
- }
- } else if (window_bits == 4) {
- if (!smallExp) {
- SQR; SQR; SQR; SQR;
- } else if (smallExp & 1) {
- SQR; SQR; SQR; SQR; MUL(smallExp/2);
- } else if (smallExp & 2) {
- SQR; SQR; SQR; MUL(smallExp/4); SQR;
- } else if (smallExp & 4) {
- SQR; SQR; MUL(smallExp/8); SQR; SQR;
- } else if (smallExp & 8) {
- SQR; MUL(smallExp/16); SQR; SQR; SQR;
- } else {
- abort();
- }
- } else if (window_bits == 5) {
- if (!smallExp) {
- SQR; SQR; SQR; SQR; SQR;
- } else if (smallExp & 1) {
- SQR; SQR; SQR; SQR; SQR; MUL(smallExp/2);
- } else if (smallExp & 2) {
- SQR; SQR; SQR; SQR; MUL(smallExp/4); SQR;
- } else if (smallExp & 4) {
- SQR; SQR; SQR; MUL(smallExp/8); SQR; SQR;
- } else if (smallExp & 8) {
- SQR; SQR; MUL(smallExp/16); SQR; SQR; SQR;
- } else if (smallExp & 0x10) {
- SQR; MUL(smallExp/32); SQR; SQR; SQR; SQR;
- } else {
- abort();
- }
- } else if (window_bits == 6) {
- if (!smallExp) {
- SQR; SQR; SQR; SQR; SQR; SQR;
- } else if (smallExp & 1) {
- SQR; SQR; SQR; SQR; SQR; SQR; MUL(smallExp/2);
- } else if (smallExp & 2) {
- SQR; SQR; SQR; SQR; SQR; MUL(smallExp/4); SQR;
- } else if (smallExp & 4) {
- SQR; SQR; SQR; SQR; MUL(smallExp/8); SQR; SQR;
- } else if (smallExp & 8) {
- SQR; SQR; SQR; MUL(smallExp/16); SQR; SQR; SQR;
- } else if (smallExp & 0x10) {
- SQR; SQR; MUL(smallExp/32); SQR; SQR; SQR; SQR;
- } else if (smallExp & 0x20) {
- SQR; MUL(smallExp/64); SQR; SQR; SQR; SQR; SQR;
- } else {
- abort();
- }
- } else {
- abort();
- }
- }
-
- s_mp_copy(mResult, MP_DIGITS(&accum1), nLen); /* from, to, len */
-
- res = s_mp_redc(&accum1, mmm);
- mp_exch(&accum1, result);
-
-CLEANUP:
- mp_clear(&accum1);
- if (dBuf) {
- if (dSize)
- memset(dBuf, 0, dSize);
- free(dBuf);
- }
-
- return res;
-}
-#undef SQR
-#undef MUL
-#endif
-
-#define SQR(a,b) \
- MP_CHECKOK( mp_sqr(a, b) );\
- MP_CHECKOK( s_mp_redc(b, mmm) )
-
-#if defined(MP_MONT_USE_MP_MUL)
-#define MUL(x,a,b) \
- MP_CHECKOK( mp_mul(a, oddPowers + (x), b) ); \
- MP_CHECKOK( s_mp_redc(b, mmm) )
-#else
-#define MUL(x,a,b) \
- MP_CHECKOK( s_mp_mul_mont(a, oddPowers + (x), b, mmm) )
-#endif
-
-#define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp
-
-/* Do modular exponentiation using integer multiply code. */
-mp_err mp_exptmod_i(const mp_int * montBase,
- const mp_int * exponent,
- const mp_int * modulus,
- mp_int * result,
- mp_mont_modulus *mmm,
- int nLen,
- mp_size bits_in_exponent,
- mp_size window_bits,
- mp_size odd_ints)
-{
- mp_int *pa1, *pa2, *ptmp;
- mp_size i;
- mp_err res;
- int expOff;
- mp_int accum1, accum2, power2, oddPowers[MAX_ODD_INTS];
-
- /* power2 = base ** 2; oddPowers[i] = base ** (2*i + 1); */
- /* oddPowers[i] = base ** (2*i + 1); */
-
- MP_DIGITS(&accum1) = 0;
- MP_DIGITS(&accum2) = 0;
- MP_DIGITS(&power2) = 0;
- for (i = 0; i < MAX_ODD_INTS; ++i) {
- MP_DIGITS(oddPowers + i) = 0;
- }
-
- MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) );
- MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) );
-
- MP_CHECKOK( mp_init_copy(&oddPowers[0], montBase) );
-
- mp_init_size(&power2, nLen + 2 * MP_USED(montBase) + 2);
- MP_CHECKOK( mp_sqr(montBase, &power2) ); /* power2 = montBase ** 2 */
- MP_CHECKOK( s_mp_redc(&power2, mmm) );
-
- for (i = 1; i < odd_ints; ++i) {
- mp_init_size(oddPowers + i, nLen + 2 * MP_USED(&power2) + 2);
- MP_CHECKOK( mp_mul(oddPowers + (i - 1), &power2, oddPowers + i) );
- MP_CHECKOK( s_mp_redc(oddPowers + i, mmm) );
- }
-
- /* set accumulator to montgomery residue of 1 */
- mp_set(&accum1, 1);
- MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) );
- pa1 = &accum1;
- pa2 = &accum2;
-
- for (expOff = bits_in_exponent - window_bits; expOff >= 0; expOff -= window_bits) {
- mp_size smallExp;
- MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) );
- smallExp = (mp_size)res;
-
- if (window_bits == 1) {
- if (!smallExp) {
- SQR(pa1,pa2); SWAPPA;
- } else if (smallExp & 1) {
- SQR(pa1,pa2); MUL(0,pa2,pa1);
- } else {
- abort();
- }
- } else if (window_bits == 4) {
- if (!smallExp) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- } else if (smallExp & 1) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- MUL(smallExp/2, pa1,pa2); SWAPPA;
- } else if (smallExp & 2) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2);
- MUL(smallExp/4,pa2,pa1); SQR(pa1,pa2); SWAPPA;
- } else if (smallExp & 4) {
- SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/8,pa1,pa2);
- SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
- } else if (smallExp & 8) {
- SQR(pa1,pa2); MUL(smallExp/16,pa2,pa1); SQR(pa1,pa2);
- SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
- } else {
- abort();
- }
- } else if (window_bits == 5) {
- if (!smallExp) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- SQR(pa1,pa2); SWAPPA;
- } else if (smallExp & 1) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- SQR(pa1,pa2); MUL(smallExp/2,pa2,pa1);
- } else if (smallExp & 2) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- MUL(smallExp/4,pa1,pa2); SQR(pa2,pa1);
- } else if (smallExp & 4) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2);
- MUL(smallExp/8,pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- } else if (smallExp & 8) {
- SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/16,pa1,pa2);
- SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- } else if (smallExp & 0x10) {
- SQR(pa1,pa2); MUL(smallExp/32,pa2,pa1); SQR(pa1,pa2);
- SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- } else {
- abort();
- }
- } else if (window_bits == 6) {
- if (!smallExp) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- SQR(pa1,pa2); SQR(pa2,pa1);
- } else if (smallExp & 1) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/2,pa1,pa2); SWAPPA;
- } else if (smallExp & 2) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- SQR(pa1,pa2); MUL(smallExp/4,pa2,pa1); SQR(pa1,pa2); SWAPPA;
- } else if (smallExp & 4) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- MUL(smallExp/8,pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
- } else if (smallExp & 8) {
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2);
- MUL(smallExp/16,pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- SQR(pa1,pa2); SWAPPA;
- } else if (smallExp & 0x10) {
- SQR(pa1,pa2); SQR(pa2,pa1); MUL(smallExp/32,pa1,pa2);
- SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
- } else if (smallExp & 0x20) {
- SQR(pa1,pa2); MUL(smallExp/64,pa2,pa1); SQR(pa1,pa2);
- SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SWAPPA;
- } else {
- abort();
- }
- } else {
- abort();
- }
- }
-
- res = s_mp_redc(pa1, mmm);
- mp_exch(pa1, result);
-
-CLEANUP:
- mp_clear(&accum1);
- mp_clear(&accum2);
- mp_clear(&power2);
- for (i = 0; i < odd_ints; ++i) {
- mp_clear(oddPowers + i);
- }
- return res;
-}
-#undef SQR
-#undef MUL
-
-#ifdef MP_USING_CACHE_SAFE_MOD_EXP
-unsigned int mp_using_cache_safe_exp = 1;
-#endif
-
-mp_err mp_set_safe_modexp(int value)
-{
-#ifdef MP_USING_CACHE_SAFE_MOD_EXP
- mp_using_cache_safe_exp = value;
- return MP_OKAY;
-#else
- if (value == 0) {
- return MP_OKAY;
- }
- return MP_BADARG;
-#endif
-}
-
-#ifdef MP_USING_CACHE_SAFE_MOD_EXP
-#define WEAVE_WORD_SIZE 4
-
-#ifndef MP_CHAR_STORE_SLOW
-/*
- * mpi_to_weave takes an array of bignums, a matrix in which each bignum
- * occupies all the columns of a row, and transposes it into a matrix in
- * which each bignum occupies a column of every row. The first row of the
- * input matrix becomes the first column of the output matrix. The n'th
- * row of input becomes the n'th column of output. The input data is said
- * to be "interleaved" or "woven" into the output matrix.
- *
- * The array of bignums is left in this woven form. Each time a single
- * bignum value is needed, it is recreated by fetching the n'th column,
- * forming a single row which is the new bignum.
- *
- * The purpose of this interleaving is make it impossible to determine which
- * of the bignums is being used in any one operation by examining the pattern
- * of cache misses.
- *
- * The weaving function does not transpose the entire input matrix in one call.
- * It transposes 4 rows of mp_ints into their respective columns of output.
- *
- * There are two different implementations of the weaving and unweaving code
- * in this file. One uses byte loads and stores. The second uses loads and
- * stores of mp_weave_word size values. The weaved forms of these two
- * implementations differ. Consequently, each one has its own explanation.
- *
- * Here is the explanation for the byte-at-a-time implementation.
- *
- * This implementation treats each mp_int bignum as an array of bytes,
- * rather than as an array of mp_digits. It stores those bytes as a
- * column of bytes in the output matrix. It doesn't care if the machine
- * uses big-endian or little-endian byte ordering within mp_digits.
- * The first byte of the mp_digit array becomes the first byte in the output
- * column, regardless of whether that byte is the MSB or LSB of the mp_digit.
- *
- * "bignums" is an array of mp_ints.
- * It points to four rows, four mp_ints, a subset of a larger array of mp_ints.
- *
- * "weaved" is the weaved output matrix.
- * The first byte of bignums[0] is stored in weaved[0].
- *
- * "nBignums" is the total number of bignums in the array of which "bignums"
- * is a part.
- *
- * "nDigits" is the size in mp_digits of each mp_int in the "bignums" array.
- * mp_ints that use less than nDigits digits are logically padded with zeros
- * while being stored in the weaved array.
- */
-mp_err mpi_to_weave(const mp_int *bignums,
- unsigned char *weaved,
- mp_size nDigits, /* in each mp_int of input */
- mp_size nBignums) /* in the entire source array */
-{
- mp_size i;
- unsigned char * endDest = weaved + (nDigits * nBignums * sizeof(mp_digit));
-
- for (i=0; i < WEAVE_WORD_SIZE; i++) {
- mp_size used = MP_USED(&bignums[i]);
- unsigned char *pSrc = (unsigned char *)MP_DIGITS(&bignums[i]);
- unsigned char *endSrc = pSrc + (used * sizeof(mp_digit));
- unsigned char *pDest = weaved + i;
-
- ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG);
- ARGCHK(used <= nDigits, MP_BADARG);
-
- for (; pSrc < endSrc; pSrc++) {
- *pDest = *pSrc;
- pDest += nBignums;
- }
- while (pDest < endDest) {
- *pDest = 0;
- pDest += nBignums;
- }
- }
-
- return MP_OKAY;
-}
-
-/* Reverse the operation above for one mp_int.
- * Reconstruct one mp_int from its column in the weaved array.
- * "pSrc" points to the offset into the weave array of the bignum we
- * are going to reconstruct.
- */
-mp_err weave_to_mpi(mp_int *a, /* output, result */
- const unsigned char *pSrc, /* input, byte matrix */
- mp_size nDigits, /* per mp_int output */
- mp_size nBignums) /* bignums in weaved matrix */
-{
- unsigned char *pDest = (unsigned char *)MP_DIGITS(a);
- unsigned char *endDest = pDest + (nDigits * sizeof(mp_digit));
-
- MP_SIGN(a) = MP_ZPOS;
- MP_USED(a) = nDigits;
-
- for (; pDest < endDest; pSrc += nBignums, pDest++) {
- *pDest = *pSrc;
- }
- s_mp_clamp(a);
- return MP_OKAY;
-}
-
-#else
-
-/* Need a primitive that we know is 32 bits long... */
-/* this is true on all modern processors we know of today*/
-typedef unsigned int mp_weave_word;
-
-/*
- * on some platforms character stores into memory is very expensive since they
- * generate a read/modify/write operation on the bus. On those platforms
- * we need to do integer writes to the bus. Because of some unrolled code,
- * in this current code the size of mp_weave_word must be four. The code that
- * makes this assumption explicity is called out. (on some platforms a write
- * of 4 bytes still requires a single read-modify-write operation.
- *
- * This function is takes the identical parameters as the function above,
- * however it lays out the final array differently. Where the previous function
- * treats the mpi_int as an byte array, this function treats it as an array of
- * mp_digits where each digit is stored in big endian order.
- *
- * since we need to interleave on a byte by byte basis, we need to collect
- * several mpi structures together into a single uint32 before we write. We
- * also need to make sure the uint32 is arranged so that the first value of
- * the first array winds up in b[0]. This means construction of that uint32
- * is endian specific (even though the layout of the mp_digits in the array
- * is always big endian).
- *
- * The final data is stored as follows :
- *
- * Our same logical array p array, m is sizeof(mp_digit),
- * N is still count and n is now b_size. If we define p[i].digit[j]0 as the
- * most significant byte of the word p[i].digit[j], p[i].digit[j]1 as
- * the next most significant byte of p[i].digit[j], ... and p[i].digit[j]m-1
- * is the least significant byte.
- * Our array would look like:
- * p[0].digit[0]0 p[1].digit[0]0 ... p[N-2].digit[0]0 p[N-1].digit[0]0
- * p[0].digit[0]1 p[1].digit[0]1 ... p[N-2].digit[0]1 p[N-1].digit[0]1
- * . .
- * p[0].digit[0]m-1 p[1].digit[0]m-1 ... p[N-2].digit[0]m-1 p[N-1].digit[0]m-1
- * p[0].digit[1]0 p[1].digit[1]0 ... p[N-2].digit[1]0 p[N-1].digit[1]0
- * . .
- * . .
- * p[0].digit[n-1]m-2 p[1].digit[n-1]m-2 ... p[N-2].digit[n-1]m-2 p[N-1].digit[n-1]m-2
- * p[0].digit[n-1]m-1 p[1].digit[n-1]m-1 ... p[N-2].digit[n-1]m-1 p[N-1].digit[n-1]m-1
- *
- */
-mp_err mpi_to_weave(const mp_int *a, unsigned char *b,
- mp_size b_size, mp_size count)
-{
- mp_size i;
- mp_digit *digitsa0;
- mp_digit *digitsa1;
- mp_digit *digitsa2;
- mp_digit *digitsa3;
- mp_size useda0;
- mp_size useda1;
- mp_size useda2;
- mp_size useda3;
- mp_weave_word *weaved = (mp_weave_word *)b;
-
- count = count/sizeof(mp_weave_word);
-
- /* this code pretty much depends on this ! */
-#if MP_ARGCHK == 2
- assert(WEAVE_WORD_SIZE == 4);
- assert(sizeof(mp_weave_word) == 4);
-#endif
-
- digitsa0 = MP_DIGITS(&a[0]);
- digitsa1 = MP_DIGITS(&a[1]);
- digitsa2 = MP_DIGITS(&a[2]);
- digitsa3 = MP_DIGITS(&a[3]);
- useda0 = MP_USED(&a[0]);
- useda1 = MP_USED(&a[1]);
- useda2 = MP_USED(&a[2]);
- useda3 = MP_USED(&a[3]);
-
- ARGCHK(MP_SIGN(&a[0]) == MP_ZPOS, MP_BADARG);
- ARGCHK(MP_SIGN(&a[1]) == MP_ZPOS, MP_BADARG);
- ARGCHK(MP_SIGN(&a[2]) == MP_ZPOS, MP_BADARG);
- ARGCHK(MP_SIGN(&a[3]) == MP_ZPOS, MP_BADARG);
- ARGCHK(useda0 <= b_size, MP_BADARG);
- ARGCHK(useda1 <= b_size, MP_BADARG);
- ARGCHK(useda2 <= b_size, MP_BADARG);
- ARGCHK(useda3 <= b_size, MP_BADARG);
-
-#define SAFE_FETCH(digit, used, word) ((word) < (used) ? (digit[word]) : 0)
-
- for (i=0; i < b_size; i++) {
- mp_digit d0 = SAFE_FETCH(digitsa0,useda0,i);
- mp_digit d1 = SAFE_FETCH(digitsa1,useda1,i);
- mp_digit d2 = SAFE_FETCH(digitsa2,useda2,i);
- mp_digit d3 = SAFE_FETCH(digitsa3,useda3,i);
- register mp_weave_word acc;
-
-/*
- * ONE_STEP takes the MSB of each of our current digits and places that
- * byte in the appropriate position for writing to the weaved array.
- * On little endian:
- * b3 b2 b1 b0
- * On big endian:
- * b0 b1 b2 b3
- * When the data is written it would always wind up:
- * b[0] = b0
- * b[1] = b1
- * b[2] = b2
- * b[3] = b3
- *
- * Once we've written the MSB, we shift the whole digit up left one
- * byte, putting the Next Most Significant Byte in the MSB position,
- * so we we repeat the next one step that byte will be written.
- * NOTE: This code assumes sizeof(mp_weave_word) and MP_WEAVE_WORD_SIZE
- * is 4.
- */
-#ifdef MP_IS_LITTLE_ENDIAN
-#define MPI_WEAVE_ONE_STEP \
- acc = (d0 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \
- acc |= (d1 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \
- acc |= (d2 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \
- acc |= (d3 >> (MP_DIGIT_BIT-32)) & 0xff000000; d3 <<= 8; /*b3*/ \
- *weaved = acc; weaved += count;
-#else
-#define MPI_WEAVE_ONE_STEP \
- acc = (d0 >> (MP_DIGIT_BIT-32)) & 0xff000000; d0 <<= 8; /*b0*/ \
- acc |= (d1 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \
- acc |= (d2 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \
- acc |= (d3 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \
- *weaved = acc; weaved += count;
-#endif
- switch (sizeof(mp_digit)) {
- case 32:
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- case 16:
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- case 8:
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- case 4:
- MPI_WEAVE_ONE_STEP
- MPI_WEAVE_ONE_STEP
- case 2:
- MPI_WEAVE_ONE_STEP
- case 1:
- MPI_WEAVE_ONE_STEP
- break;
- }
- }
-
- return MP_OKAY;
-}
-
-/* reverse the operation above for one entry.
- * b points to the offset into the weave array of the power we are
- * calculating */
-mp_err weave_to_mpi(mp_int *a, const unsigned char *b,
- mp_size b_size, mp_size count)
-{
- mp_digit *pb = MP_DIGITS(a);
- mp_digit *end = &pb[b_size];
-
- MP_SIGN(a) = MP_ZPOS;
- MP_USED(a) = b_size;
-
- for (; pb < end; pb++) {
- register mp_digit digit;
-
- digit = *b << 8; b += count;
-#define MPI_UNWEAVE_ONE_STEP digit |= *b; b += count; digit = digit << 8;
- switch (sizeof(mp_digit)) {
- case 32:
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- case 16:
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- case 8:
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- case 4:
- MPI_UNWEAVE_ONE_STEP
- MPI_UNWEAVE_ONE_STEP
- case 2:
- break;
- }
- digit |= *b; b += count;
-
- *pb = digit;
- }
- s_mp_clamp(a);
- return MP_OKAY;
-}
-#endif
-
-
-#define SQR(a,b) \
- MP_CHECKOK( mp_sqr(a, b) );\
- MP_CHECKOK( s_mp_redc(b, mmm) )
-
-#if defined(MP_MONT_USE_MP_MUL)
-#define MUL_NOWEAVE(x,a,b) \
- MP_CHECKOK( mp_mul(a, x, b) ); \
- MP_CHECKOK( s_mp_redc(b, mmm) )
-#else
-#define MUL_NOWEAVE(x,a,b) \
- MP_CHECKOK( s_mp_mul_mont(a, x, b, mmm) )
-#endif
-
-#define MUL(x,a,b) \
- MP_CHECKOK( weave_to_mpi(&tmp, powers + (x), nLen, num_powers) ); \
- MUL_NOWEAVE(&tmp,a,b)
-
-#define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp
-#define MP_ALIGN(x,y) ((((ptrdiff_t)(x))+((y)-1))&(((ptrdiff_t)0)-(y)))
-
-/* Do modular exponentiation using integer multiply code. */
-mp_err mp_exptmod_safe_i(const mp_int * montBase,
- const mp_int * exponent,
- const mp_int * modulus,
- mp_int * result,
- mp_mont_modulus *mmm,
- int nLen,
- mp_size bits_in_exponent,
- mp_size window_bits,
- mp_size num_powers)
-{
- mp_int *pa1, *pa2, *ptmp;
- mp_size i;
- mp_size first_window;
- mp_err res;
- int expOff;
- mp_int accum1, accum2, accum[WEAVE_WORD_SIZE];
- mp_int tmp;
- unsigned char *powersArray;
- unsigned char *powers;
-
- MP_DIGITS(&accum1) = 0;
- MP_DIGITS(&accum2) = 0;
- MP_DIGITS(&accum[0]) = 0;
- MP_DIGITS(&accum[1]) = 0;
- MP_DIGITS(&accum[2]) = 0;
- MP_DIGITS(&accum[3]) = 0;
- MP_DIGITS(&tmp) = 0;
-
- powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1));
- if (powersArray == NULL) {
- res = MP_MEM;
- goto CLEANUP;
- }
-
- /* powers[i] = base ** (i); */
- powers = (unsigned char *)MP_ALIGN(powersArray,num_powers);
-
- /* grab the first window value. This allows us to preload accumulator1
- * and save a conversion, some squares and a multiple*/
- MP_CHECKOK( mpl_get_bits(exponent,
- bits_in_exponent-window_bits, window_bits) );
- first_window = (mp_size)res;
-
- MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) );
- MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) );
- MP_CHECKOK( mp_init_size(&tmp, 3 * nLen + 2) );
-
- /* build the first WEAVE_WORD powers inline */
- /* if WEAVE_WORD_SIZE is not 4, this code will have to change */
- if (num_powers > 2) {
- MP_CHECKOK( mp_init_size(&accum[0], 3 * nLen + 2) );
- MP_CHECKOK( mp_init_size(&accum[1], 3 * nLen + 2) );
- MP_CHECKOK( mp_init_size(&accum[2], 3 * nLen + 2) );
- MP_CHECKOK( mp_init_size(&accum[3], 3 * nLen + 2) );
- mp_set(&accum[0], 1);
- MP_CHECKOK( s_mp_to_mont(&accum[0], mmm, &accum[0]) );
- MP_CHECKOK( mp_copy(montBase, &accum[1]) );
- SQR(montBase, &accum[2]);
- MUL_NOWEAVE(montBase, &accum[2], &accum[3]);
- MP_CHECKOK( mpi_to_weave(accum, powers, nLen, num_powers) );
- if (first_window < 4) {
- MP_CHECKOK( mp_copy(&accum[first_window], &accum1) );
- first_window = num_powers;
- }
- } else {
- if (first_window == 0) {
- mp_set(&accum1, 1);
- MP_CHECKOK( s_mp_to_mont(&accum1, mmm, &accum1) );
- } else {
- /* assert first_window == 1? */
- MP_CHECKOK( mp_copy(montBase, &accum1) );
- }
- }
-
- /*
- * calculate all the powers in the powers array.
- * this adds 2**(k-1)-2 square operations over just calculating the
- * odd powers where k is the window size in the two other mp_modexpt
- * implementations in this file. We will get some of that
- * back by not needing the first 'k' squares and one multiply for the
- * first window */
- for (i = WEAVE_WORD_SIZE; i < num_powers; i++) {
- int acc_index = i & (WEAVE_WORD_SIZE-1); /* i % WEAVE_WORD_SIZE */
- if ( i & 1 ) {
- MUL_NOWEAVE(montBase, &accum[acc_index-1] , &accum[acc_index]);
- /* we've filled the array do our 'per array' processing */
- if (acc_index == (WEAVE_WORD_SIZE-1)) {
- MP_CHECKOK( mpi_to_weave(accum, powers + i - (WEAVE_WORD_SIZE-1),
- nLen, num_powers) );
-
- if (first_window <= i) {
- MP_CHECKOK( mp_copy(&accum[first_window & (WEAVE_WORD_SIZE-1)],
- &accum1) );
- first_window = num_powers;
- }
- }
- } else {
- /* up to 8 we can find 2^i-1 in the accum array, but at 8 we our source
- * and target are the same so we need to copy.. After that, the
- * value is overwritten, so we need to fetch it from the stored
- * weave array */
- if (i > 2* WEAVE_WORD_SIZE) {
- MP_CHECKOK(weave_to_mpi(&accum2, powers+i/2, nLen, num_powers));
- SQR(&accum2, &accum[acc_index]);
- } else {
- int half_power_index = (i/2) & (WEAVE_WORD_SIZE-1);
- if (half_power_index == acc_index) {
- /* copy is cheaper than weave_to_mpi */
- MP_CHECKOK(mp_copy(&accum[half_power_index], &accum2));
- SQR(&accum2,&accum[acc_index]);
- } else {
- SQR(&accum[half_power_index],&accum[acc_index]);
- }
- }
- }
- }
- /* if the accum1 isn't set, Then there is something wrong with our logic
- * above and is an internal programming error.
- */
-#if MP_ARGCHK == 2
- assert(MP_USED(&accum1) != 0);
-#endif
-
- /* set accumulator to montgomery residue of 1 */
- pa1 = &accum1;
- pa2 = &accum2;
-
- for (expOff = bits_in_exponent - window_bits*2; expOff >= 0; expOff -= window_bits) {
- mp_size smallExp;
- MP_CHECKOK( mpl_get_bits(exponent, expOff, window_bits) );
- smallExp = (mp_size)res;
-
- /* handle unroll the loops */
- switch (window_bits) {
- case 1:
- if (!smallExp) {
- SQR(pa1,pa2); SWAPPA;
- } else if (smallExp & 1) {
- SQR(pa1,pa2); MUL_NOWEAVE(montBase,pa2,pa1);
- } else {
- abort();
- }
- break;
- case 6:
- SQR(pa1,pa2); SQR(pa2,pa1);
- /* fall through */
- case 4:
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- MUL(smallExp, pa1,pa2); SWAPPA;
- break;
- case 5:
- SQR(pa1,pa2); SQR(pa2,pa1); SQR(pa1,pa2); SQR(pa2,pa1);
- SQR(pa1,pa2); MUL(smallExp,pa2,pa1);
- break;
- default:
- abort(); /* could do a loop? */
- }
- }
-
- res = s_mp_redc(pa1, mmm);
- mp_exch(pa1, result);
-
-CLEANUP:
- mp_clear(&accum1);
- mp_clear(&accum2);
- mp_clear(&accum[0]);
- mp_clear(&accum[1]);
- mp_clear(&accum[2]);
- mp_clear(&accum[3]);
- mp_clear(&tmp);
- /* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */
- free(powersArray);
- return res;
-}
-#undef SQR
-#undef MUL
-#endif
-
-mp_err mp_exptmod(const mp_int *inBase, const mp_int *exponent,
- const mp_int *modulus, mp_int *result)
-{
- const mp_int *base;
- mp_size bits_in_exponent, i, window_bits, odd_ints;
- mp_err res;
- int nLen;
- mp_int montBase, goodBase;
- mp_mont_modulus mmm;
-#ifdef MP_USING_CACHE_SAFE_MOD_EXP
- static unsigned int max_window_bits;
-#endif
-
- /* function for computing n0prime only works if n0 is odd */
- if (!mp_isodd(modulus))
- return s_mp_exptmod(inBase, exponent, modulus, result);
-
- MP_DIGITS(&montBase) = 0;
- MP_DIGITS(&goodBase) = 0;
-
- if (mp_cmp(inBase, modulus) < 0) {
- base = inBase;
- } else {
- MP_CHECKOK( mp_init(&goodBase) );
- base = &goodBase;
- MP_CHECKOK( mp_mod(inBase, modulus, &goodBase) );
- }
-
- nLen = MP_USED(modulus);
- MP_CHECKOK( mp_init_size(&montBase, 2 * nLen + 2) );
-
- mmm.N = *modulus; /* a copy of the mp_int struct */
-
- /* compute n0', given n0, n0' = -(n0 ** -1) mod MP_RADIX
- ** where n0 = least significant mp_digit of N, the modulus.
- */
- mmm.n0prime = 0 - s_mp_invmod_radix( MP_DIGIT(modulus, 0) );
-
- MP_CHECKOK( s_mp_to_mont(base, &mmm, &montBase) );
-
- bits_in_exponent = mpl_significant_bits(exponent);
-#ifdef MP_USING_CACHE_SAFE_MOD_EXP
- if (mp_using_cache_safe_exp) {
- if (bits_in_exponent > 780)
- window_bits = 6;
- else if (bits_in_exponent > 256)
- window_bits = 5;
- else if (bits_in_exponent > 20)
- window_bits = 4;
- /* RSA public key exponents are typically under 20 bits (common values
- * are: 3, 17, 65537) and a 4-bit window is inefficient
- */
- else
- window_bits = 1;
- } else
-#endif
- if (bits_in_exponent > 480)
- window_bits = 6;
- else if (bits_in_exponent > 160)
- window_bits = 5;
- else if (bits_in_exponent > 20)
- window_bits = 4;
- /* RSA public key exponents are typically under 20 bits (common values
- * are: 3, 17, 65537) and a 4-bit window is inefficient
- */
- else
- window_bits = 1;
-
-#ifdef MP_USING_CACHE_SAFE_MOD_EXP
- /*
- * clamp the window size based on
- * the cache line size.
- */
- if (!max_window_bits) {
- unsigned long cache_size = s_mpi_getProcessorLineSize();
- /* processor has no cache, use 'fast' code always */
- if (cache_size == 0) {
- mp_using_cache_safe_exp = 0;
- }
- if ((cache_size == 0) || (cache_size >= 64)) {
- max_window_bits = 6;
- } else if (cache_size >= 32) {
- max_window_bits = 5;
- } else if (cache_size >= 16) {
- max_window_bits = 4;
- } else max_window_bits = 1; /* should this be an assert? */
- }
-
- /* clamp the window size down before we caclulate bits_in_exponent */
- if (mp_using_cache_safe_exp) {
- if (window_bits > max_window_bits) {
- window_bits = max_window_bits;
- }
- }
-#endif
-
- odd_ints = 1 << (window_bits - 1);
- i = bits_in_exponent % window_bits;
- if (i != 0) {
- bits_in_exponent += window_bits - i;
- }
-
-#ifdef MP_USING_MONT_MULF
- if (mp_using_mont_mulf) {
- MP_CHECKOK( s_mp_pad(&montBase, nLen) );
- res = mp_exptmod_f(&montBase, exponent, modulus, result, &mmm, nLen,
- bits_in_exponent, window_bits, odd_ints);
- } else
-#endif
-#ifdef MP_USING_CACHE_SAFE_MOD_EXP
- if (mp_using_cache_safe_exp) {
- res = mp_exptmod_safe_i(&montBase, exponent, modulus, result, &mmm, nLen,
- bits_in_exponent, window_bits, 1 << window_bits);
- } else
-#endif
- res = mp_exptmod_i(&montBase, exponent, modulus, result, &mmm, nLen,
- bits_in_exponent, window_bits, odd_ints);
-
-CLEANUP:
- mp_clear(&montBase);
- mp_clear(&goodBase);
- /* Don't mp_clear mmm.N because it is merely a copy of modulus.
- ** Just zap it.
- */
- memset(&mmm, 0, sizeof mmm);
- return res;
-}
diff --git a/security/nss/lib/freebl/mpi/mpprime.c b/security/nss/lib/freebl/mpi/mpprime.c
deleted file mode 100644
index f0baf9d2a..000000000
--- a/security/nss/lib/freebl/mpi/mpprime.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * mpprime.c
- *
- * Utilities for finding and working with prime and pseudo-prime
- * integers
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi-priv.h"
-#include "mpprime.h"
-#include "mplogic.h"
-#include <stdlib.h>
-#include <string.h>
-
-#define SMALL_TABLE 0 /* determines size of hard-wired prime table */
-
-#define RANDOM() rand()
-
-#include "primes.c" /* pull in the prime digit table */
-
-/*
- Test if any of a given vector of digits divides a. If not, MP_NO
- is returned; otherwise, MP_YES is returned and 'which' is set to
- the index of the integer in the vector which divided a.
- */
-mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which);
-
-/* {{{ mpp_divis(a, b) */
-
-/*
- mpp_divis(a, b)
-
- Returns MP_YES if a is divisible by b, or MP_NO if it is not.
- */
-
-mp_err mpp_divis(mp_int *a, mp_int *b)
-{
- mp_err res;
- mp_int rem;
-
- if((res = mp_init(&rem)) != MP_OKAY)
- return res;
-
- if((res = mp_mod(a, b, &rem)) != MP_OKAY)
- goto CLEANUP;
-
- if(mp_cmp_z(&rem) == 0)
- res = MP_YES;
- else
- res = MP_NO;
-
-CLEANUP:
- mp_clear(&rem);
- return res;
-
-} /* end mpp_divis() */
-
-/* }}} */
-
-/* {{{ mpp_divis_d(a, d) */
-
-/*
- mpp_divis_d(a, d)
-
- Return MP_YES if a is divisible by d, or MP_NO if it is not.
- */
-
-mp_err mpp_divis_d(mp_int *a, mp_digit d)
-{
- mp_err res;
- mp_digit rem;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- if(d == 0)
- return MP_NO;
-
- if((res = mp_mod_d(a, d, &rem)) != MP_OKAY)
- return res;
-
- if(rem == 0)
- return MP_YES;
- else
- return MP_NO;
-
-} /* end mpp_divis_d() */
-
-/* }}} */
-
-/* {{{ mpp_random(a) */
-
-/*
- mpp_random(a)
-
- Assigns a random value to a. This value is generated using the
- standard C library's rand() function, so it should not be used for
- cryptographic purposes, but it should be fine for primality testing,
- since all we really care about there is good statistical properties.
-
- As many digits as a currently has are filled with random digits.
- */
-
-mp_err mpp_random(mp_int *a)
-
-{
- mp_digit next = 0;
- unsigned int ix, jx;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- for(ix = 0; ix < USED(a); ix++) {
- for(jx = 0; jx < sizeof(mp_digit); jx++) {
- next = (next << CHAR_BIT) | (RANDOM() & UCHAR_MAX);
- }
- DIGIT(a, ix) = next;
- }
-
- return MP_OKAY;
-
-} /* end mpp_random() */
-
-/* }}} */
-
-/* {{{ mpp_random_size(a, prec) */
-
-mp_err mpp_random_size(mp_int *a, mp_size prec)
-{
- mp_err res;
-
- ARGCHK(a != NULL && prec > 0, MP_BADARG);
-
- if((res = s_mp_pad(a, prec)) != MP_OKAY)
- return res;
-
- return mpp_random(a);
-
-} /* end mpp_random_size() */
-
-/* }}} */
-
-/* {{{ mpp_divis_vector(a, vec, size, which) */
-
-/*
- mpp_divis_vector(a, vec, size, which)
-
- Determines if a is divisible by any of the 'size' digits in vec.
- Returns MP_YES and sets 'which' to the index of the offending digit,
- if it is; returns MP_NO if it is not.
- */
-
-mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which)
-{
- ARGCHK(a != NULL && vec != NULL && size > 0, MP_BADARG);
-
- return s_mpp_divp(a, vec, size, which);
-
-} /* end mpp_divis_vector() */
-
-/* }}} */
-
-/* {{{ mpp_divis_primes(a, np) */
-
-/*
- mpp_divis_primes(a, np)
-
- Test whether a is divisible by any of the first 'np' primes. If it
- is, returns MP_YES and sets *np to the value of the digit that did
- it. If not, returns MP_NO.
- */
-mp_err mpp_divis_primes(mp_int *a, mp_digit *np)
-{
- int size, which;
- mp_err res;
-
- ARGCHK(a != NULL && np != NULL, MP_BADARG);
-
- size = (int)*np;
- if(size > prime_tab_size)
- size = prime_tab_size;
-
- res = mpp_divis_vector(a, prime_tab, size, &which);
- if(res == MP_YES)
- *np = prime_tab[which];
-
- return res;
-
-} /* end mpp_divis_primes() */
-
-/* }}} */
-
-/* {{{ mpp_fermat(a, w) */
-
-/*
- Using w as a witness, try pseudo-primality testing based on Fermat's
- little theorem. If a is prime, and (w, a) = 1, then w^a == w (mod
- a). So, we compute z = w^a (mod a) and compare z to w; if they are
- equal, the test passes and we return MP_YES. Otherwise, we return
- MP_NO.
- */
-mp_err mpp_fermat(mp_int *a, mp_digit w)
-{
- mp_int base, test;
- mp_err res;
-
- if((res = mp_init(&base)) != MP_OKAY)
- return res;
-
- mp_set(&base, w);
-
- if((res = mp_init(&test)) != MP_OKAY)
- goto TEST;
-
- /* Compute test = base^a (mod a) */
- if((res = mp_exptmod(&base, a, a, &test)) != MP_OKAY)
- goto CLEANUP;
-
-
- if(mp_cmp(&base, &test) == 0)
- res = MP_YES;
- else
- res = MP_NO;
-
- CLEANUP:
- mp_clear(&test);
- TEST:
- mp_clear(&base);
-
- return res;
-
-} /* end mpp_fermat() */
-
-/* }}} */
-
-/*
- Perform the fermat test on each of the primes in a list until
- a) one of them shows a is not prime, or
- b) the list is exhausted.
- Returns: MP_YES if it passes tests.
- MP_NO if fermat test reveals it is composite
- Some MP error code if some other error occurs.
- */
-mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes)
-{
- mp_err rv = MP_YES;
-
- while (nPrimes-- > 0 && rv == MP_YES) {
- rv = mpp_fermat(a, *primes++);
- }
- return rv;
-}
-
-/* {{{ mpp_pprime(a, nt) */
-
-/*
- mpp_pprime(a, nt)
-
- Performs nt iteration of the Miller-Rabin probabilistic primality
- test on a. Returns MP_YES if the tests pass, MP_NO if one fails.
- If MP_NO is returned, the number is definitely composite. If MP_YES
- is returned, it is probably prime (but that is not guaranteed).
- */
-
-mp_err mpp_pprime(mp_int *a, int nt)
-{
- mp_err res;
- mp_int x, amo, m, z; /* "amo" = "a minus one" */
- int iter;
- unsigned int jx;
- mp_size b;
-
- ARGCHK(a != NULL, MP_BADARG);
-
- MP_DIGITS(&x) = 0;
- MP_DIGITS(&amo) = 0;
- MP_DIGITS(&m) = 0;
- MP_DIGITS(&z) = 0;
-
- /* Initialize temporaries... */
- MP_CHECKOK( mp_init(&amo));
- /* Compute amo = a - 1 for what follows... */
- MP_CHECKOK( mp_sub_d(a, 1, &amo) );
-
- b = mp_trailing_zeros(&amo);
- if (!b) { /* a was even ? */
- res = MP_NO;
- goto CLEANUP;
- }
-
- MP_CHECKOK( mp_init_size(&x, MP_USED(a)) );
- MP_CHECKOK( mp_init(&z) );
- MP_CHECKOK( mp_init(&m) );
- MP_CHECKOK( mp_div_2d(&amo, b, &m, 0) );
-
- /* Do the test nt times... */
- for(iter = 0; iter < nt; iter++) {
-
- /* Choose a random value for 1 < x < a */
- s_mp_pad(&x, USED(a));
- mpp_random(&x);
- MP_CHECKOK( mp_mod(&x, a, &x) );
- if(mp_cmp_d(&x, 1) <= 0) {
- iter--; /* don't count this iteration */
- continue; /* choose a new x */
- }
-
- /* Compute z = (x ** m) mod a */
- MP_CHECKOK( mp_exptmod(&x, &m, a, &z) );
-
- if(mp_cmp_d(&z, 1) == 0 || mp_cmp(&z, &amo) == 0) {
- res = MP_YES;
- continue;
- }
-
- res = MP_NO; /* just in case the following for loop never executes. */
- for (jx = 1; jx < b; jx++) {
- /* z = z^2 (mod a) */
- MP_CHECKOK( mp_sqrmod(&z, a, &z) );
- res = MP_NO; /* previous line set res to MP_YES */
-
- if(mp_cmp_d(&z, 1) == 0) {
- break;
- }
- if(mp_cmp(&z, &amo) == 0) {
- res = MP_YES;
- break;
- }
- } /* end testing loop */
-
- /* If the test passes, we will continue iterating, but a failed
- test means the candidate is definitely NOT prime, so we will
- immediately break out of this loop
- */
- if(res == MP_NO)
- break;
-
- } /* end iterations loop */
-
-CLEANUP:
- mp_clear(&m);
- mp_clear(&z);
- mp_clear(&x);
- mp_clear(&amo);
- return res;
-
-} /* end mpp_pprime() */
-
-/* }}} */
-
-/* Produce table of composites from list of primes and trial value.
-** trial must be odd. List of primes must not include 2.
-** sieve should have dimension >= MAXPRIME/2, where MAXPRIME is largest
-** prime in list of primes. After this function is finished,
-** if sieve[i] is non-zero, then (trial + 2*i) is composite.
-** Each prime used in the sieve costs one division of trial, and eliminates
-** one or more values from the search space. (3 eliminates 1/3 of the values
-** alone!) Each value left in the search space costs 1 or more modular
-** exponentations. So, these divisions are a bargain!
-*/
-mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
- unsigned char *sieve, mp_size nSieve)
-{
- mp_err res;
- mp_digit rem;
- mp_size ix;
- unsigned long offset;
-
- memset(sieve, 0, nSieve);
-
- for(ix = 0; ix < nPrimes; ix++) {
- mp_digit prime = primes[ix];
- mp_size i;
- if((res = mp_mod_d(trial, prime, &rem)) != MP_OKAY)
- return res;
-
- if (rem == 0) {
- offset = 0;
- } else {
- offset = prime - (rem / 2);
- }
- for (i = offset; i < nSieve ; i += prime) {
- sieve[i] = 1;
- }
- }
-
- return MP_OKAY;
-}
-
-#define SIEVE_SIZE 32*1024
-
-mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
- unsigned long * nTries)
-{
- mp_digit np;
- mp_err res;
- int i = 0;
- mp_int trial;
- mp_int q;
- mp_size num_tests;
- unsigned char *sieve;
-
- ARGCHK(start != 0, MP_BADARG);
- ARGCHK(nBits > 16, MP_RANGE);
-
- sieve = malloc(SIEVE_SIZE);
- ARGCHK(sieve != NULL, MP_MEM);
-
- MP_DIGITS(&trial) = 0;
- MP_DIGITS(&q) = 0;
- MP_CHECKOK( mp_init(&trial) );
- MP_CHECKOK( mp_init(&q) );
- /* values taken from table 4.4, HandBook of Applied Cryptography */
- if (nBits >= 1300) {
- num_tests = 2;
- } else if (nBits >= 850) {
- num_tests = 3;
- } else if (nBits >= 650) {
- num_tests = 4;
- } else if (nBits >= 550) {
- num_tests = 5;
- } else if (nBits >= 450) {
- num_tests = 6;
- } else if (nBits >= 400) {
- num_tests = 7;
- } else if (nBits >= 350) {
- num_tests = 8;
- } else if (nBits >= 300) {
- num_tests = 9;
- } else if (nBits >= 250) {
- num_tests = 12;
- } else if (nBits >= 200) {
- num_tests = 15;
- } else if (nBits >= 150) {
- num_tests = 18;
- } else if (nBits >= 100) {
- num_tests = 27;
- } else
- num_tests = 50;
-
- if (strong)
- --nBits;
- MP_CHECKOK( mpl_set_bit(start, nBits - 1, 1) );
- MP_CHECKOK( mpl_set_bit(start, 0, 1) );
- for (i = mpl_significant_bits(start) - 1; i >= nBits; --i) {
- MP_CHECKOK( mpl_set_bit(start, i, 0) );
- }
- /* start sieveing with prime value of 3. */
- MP_CHECKOK(mpp_sieve(start, prime_tab + 1, prime_tab_size - 1,
- sieve, SIEVE_SIZE) );
-
-#ifdef DEBUG_SIEVE
- res = 0;
- for (i = 0; i < SIEVE_SIZE; ++i) {
- if (!sieve[i])
- ++res;
- }
- fprintf(stderr,"sieve found %d potential primes.\n", res);
-#define FPUTC(x,y) fputc(x,y)
-#else
-#define FPUTC(x,y)
-#endif
-
- res = MP_NO;
- for(i = 0; i < SIEVE_SIZE; ++i) {
- if (sieve[i]) /* this number is composite */
- continue;
- MP_CHECKOK( mp_add_d(start, 2 * i, &trial) );
- FPUTC('.', stderr);
- /* run a Fermat test */
- res = mpp_fermat(&trial, 2);
- if (res != MP_OKAY) {
- if (res == MP_NO)
- continue; /* was composite */
- goto CLEANUP;
- }
-
- FPUTC('+', stderr);
- /* If that passed, run some Miller-Rabin tests */
- res = mpp_pprime(&trial, num_tests);
- if (res != MP_OKAY) {
- if (res == MP_NO)
- continue; /* was composite */
- goto CLEANUP;
- }
- FPUTC('!', stderr);
-
- if (!strong)
- break; /* success !! */
-
- /* At this point, we have strong evidence that our candidate
- is itself prime. If we want a strong prime, we need now
- to test q = 2p + 1 for primality...
- */
- MP_CHECKOK( mp_mul_2(&trial, &q) );
- MP_CHECKOK( mp_add_d(&q, 1, &q) );
-
- /* Test q for small prime divisors ... */
- np = prime_tab_size;
- res = mpp_divis_primes(&q, &np);
- if (res == MP_YES) { /* is composite */
- mp_clear(&q);
- continue;
- }
- if (res != MP_NO)
- goto CLEANUP;
-
- /* And test with Fermat, as with its parent ... */
- res = mpp_fermat(&q, 2);
- if (res != MP_YES) {
- mp_clear(&q);
- if (res == MP_NO)
- continue; /* was composite */
- goto CLEANUP;
- }
-
- /* And test with Miller-Rabin, as with its parent ... */
- res = mpp_pprime(&q, num_tests);
- if (res != MP_YES) {
- mp_clear(&q);
- if (res == MP_NO)
- continue; /* was composite */
- goto CLEANUP;
- }
-
- /* If it passed, we've got a winner */
- mp_exch(&q, &trial);
- mp_clear(&q);
- break;
-
- } /* end of loop through sieved values */
- if (res == MP_YES)
- mp_exch(&trial, start);
-CLEANUP:
- mp_clear(&trial);
- mp_clear(&q);
- if (nTries)
- *nTries += i;
- if (sieve != NULL) {
- memset(sieve, 0, SIEVE_SIZE);
- free (sieve);
- }
- return res;
-}
-
-/*========================================================================*/
-/*------------------------------------------------------------------------*/
-/* Static functions visible only to the library internally */
-
-/* {{{ s_mpp_divp(a, vec, size, which) */
-
-/*
- Test for divisibility by members of a vector of digits. Returns
- MP_NO if a is not divisible by any of them; returns MP_YES and sets
- 'which' to the index of the offender, if it is. Will stop on the
- first digit against which a is divisible.
- */
-
-mp_err s_mpp_divp(mp_int *a, const mp_digit *vec, int size, int *which)
-{
- mp_err res;
- mp_digit rem;
-
- int ix;
-
- for(ix = 0; ix < size; ix++) {
- if((res = mp_mod_d(a, vec[ix], &rem)) != MP_OKAY)
- return res;
-
- if(rem == 0) {
- if(which)
- *which = ix;
- return MP_YES;
- }
- }
-
- return MP_NO;
-
-} /* end s_mpp_divp() */
-
-/* }}} */
-
-/*------------------------------------------------------------------------*/
-/* HERE THERE BE DRAGONS */
diff --git a/security/nss/lib/freebl/mpi/mpprime.h b/security/nss/lib/freebl/mpi/mpprime.h
deleted file mode 100644
index 805e0db16..000000000
--- a/security/nss/lib/freebl/mpi/mpprime.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * mpprime.h
- *
- * Utilities for finding and working with prime and pseudo-prime
- * integers
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _H_MP_PRIME_
-#define _H_MP_PRIME_
-
-#include "mpi.h"
-
-extern const int prime_tab_size; /* number of primes available */
-extern const mp_digit prime_tab[];
-
-/* Tests for divisibility */
-mp_err mpp_divis(mp_int *a, mp_int *b);
-mp_err mpp_divis_d(mp_int *a, mp_digit d);
-
-/* Random selection */
-mp_err mpp_random(mp_int *a);
-mp_err mpp_random_size(mp_int *a, mp_size prec);
-
-/* Pseudo-primality testing */
-mp_err mpp_divis_vector(mp_int *a, const mp_digit *vec, int size, int *which);
-mp_err mpp_divis_primes(mp_int *a, mp_digit *np);
-mp_err mpp_fermat(mp_int *a, mp_digit w);
-mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes);
-mp_err mpp_pprime(mp_int *a, int nt);
-mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes,
- unsigned char *sieve, mp_size nSieve);
-mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
- unsigned long * nTries);
-
-#endif /* end _H_MP_PRIME_ */
diff --git a/security/nss/lib/freebl/mpi/mpv_sparc.c b/security/nss/lib/freebl/mpi/mpv_sparc.c
deleted file mode 100644
index 8ac0673f3..000000000
--- a/security/nss/lib/freebl/mpi/mpv_sparc.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "vis_proto.h"
-
-/***************************************************************/
-
-typedef int t_s32;
-typedef unsigned int t_u32;
-#if defined(__sparcv9)
-typedef long t_s64;
-typedef unsigned long t_u64;
-#else
-typedef long long t_s64;
-typedef unsigned long long t_u64;
-#endif
-typedef double t_d64;
-
-/***************************************************************/
-
-typedef union {
- t_d64 d64;
- struct {
- t_s32 i0;
- t_s32 i1;
- } i32s;
-} d64_2_i32;
-
-/***************************************************************/
-
-#define BUFF_SIZE 256
-
-#define A_BITS 19
-#define A_MASK ((1 << A_BITS) - 1)
-
-/***************************************************************/
-
-static t_u64 mask_cnst[] = {
- 0x8000000080000000ull
-};
-
-/***************************************************************/
-
-#define DEF_VARS(N) \
- t_d64 *py = (t_d64*)y; \
- t_d64 mask = *((t_d64*)mask_cnst); \
- t_d64 ca = (1u << 31) - 1; \
- t_d64 da = (t_d64)a; \
- t_s64 buff[N], s; \
- d64_2_i32 dy
-
-/***************************************************************/
-
-#define MUL_U32_S64_2(i) \
- dy.d64 = vis_fxnor(mask, py[i]); \
- buff[2*(i) ] = (ca - (t_d64)dy.i32s.i0) * da; \
- buff[2*(i)+1] = (ca - (t_d64)dy.i32s.i1) * da
-
-#define MUL_U32_S64_2_D(i) \
- dy.d64 = vis_fxnor(mask, py[i]); \
- d0 = ca - (t_d64)dy.i32s.i0; \
- d1 = ca - (t_d64)dy.i32s.i1; \
- buff[4*(i) ] = (t_s64)(d0 * da); \
- buff[4*(i)+1] = (t_s64)(d0 * db); \
- buff[4*(i)+2] = (t_s64)(d1 * da); \
- buff[4*(i)+3] = (t_s64)(d1 * db)
-
-/***************************************************************/
-
-#define ADD_S64_U32(i) \
- s = buff[i] + x[i] + c; \
- z[i] = s; \
- c = (s >> 32)
-
-#define ADD_S64_U32_D(i) \
- s = buff[2*(i)] +(((t_s64)(buff[2*(i)+1]))<<A_BITS) + x[i] + uc; \
- z[i] = s; \
- uc = ((t_u64)s >> 32)
-
-/***************************************************************/
-
-#define MUL_U32_S64_8(i) \
- MUL_U32_S64_2(i); \
- MUL_U32_S64_2(i+1); \
- MUL_U32_S64_2(i+2); \
- MUL_U32_S64_2(i+3)
-
-#define MUL_U32_S64_D_8(i) \
- MUL_U32_S64_2_D(i); \
- MUL_U32_S64_2_D(i+1); \
- MUL_U32_S64_2_D(i+2); \
- MUL_U32_S64_2_D(i+3)
-
-/***************************************************************/
-
-#define ADD_S64_U32_8(i) \
- ADD_S64_U32(i); \
- ADD_S64_U32(i+1); \
- ADD_S64_U32(i+2); \
- ADD_S64_U32(i+3); \
- ADD_S64_U32(i+4); \
- ADD_S64_U32(i+5); \
- ADD_S64_U32(i+6); \
- ADD_S64_U32(i+7)
-
-#define ADD_S64_U32_D_8(i) \
- ADD_S64_U32_D(i); \
- ADD_S64_U32_D(i+1); \
- ADD_S64_U32_D(i+2); \
- ADD_S64_U32_D(i+3); \
- ADD_S64_U32_D(i+4); \
- ADD_S64_U32_D(i+5); \
- ADD_S64_U32_D(i+6); \
- ADD_S64_U32_D(i+7)
-
-/***************************************************************/
-
-t_u32 mul_add(t_u32 *z, t_u32 *x, t_u32 *y, int n, t_u32 a)
-{
- if (a < (1 << A_BITS)) {
-
- if (n == 8) {
- DEF_VARS(8);
- t_s32 c = 0;
-
- MUL_U32_S64_8(0);
- ADD_S64_U32_8(0);
-
- return c;
-
- } else if (n == 16) {
- DEF_VARS(16);
- t_s32 c = 0;
-
- MUL_U32_S64_8(0);
- MUL_U32_S64_8(4);
- ADD_S64_U32_8(0);
- ADD_S64_U32_8(8);
-
- return c;
-
- } else {
- DEF_VARS(BUFF_SIZE);
- t_s32 i, c = 0;
-
-#pragma pipeloop(0)
- for (i = 0; i < (n+1)/2; i ++) {
- MUL_U32_S64_2(i);
- }
-
-#pragma pipeloop(0)
- for (i = 0; i < n; i ++) {
- ADD_S64_U32(i);
- }
-
- return c;
-
- }
- } else {
-
- if (n == 8) {
- DEF_VARS(2*8);
- t_d64 d0, d1, db;
- t_u32 uc = 0;
-
- da = (t_d64)(a & A_MASK);
- db = (t_d64)(a >> A_BITS);
-
- MUL_U32_S64_D_8(0);
- ADD_S64_U32_D_8(0);
-
- return uc;
-
- } else if (n == 16) {
- DEF_VARS(2*16);
- t_d64 d0, d1, db;
- t_u32 uc = 0;
-
- da = (t_d64)(a & A_MASK);
- db = (t_d64)(a >> A_BITS);
-
- MUL_U32_S64_D_8(0);
- MUL_U32_S64_D_8(4);
- ADD_S64_U32_D_8(0);
- ADD_S64_U32_D_8(8);
-
- return uc;
-
- } else {
- DEF_VARS(2*BUFF_SIZE);
- t_d64 d0, d1, db;
- t_u32 i, uc = 0;
-
- da = (t_d64)(a & A_MASK);
- db = (t_d64)(a >> A_BITS);
-
-#pragma pipeloop(0)
- for (i = 0; i < (n+1)/2; i ++) {
- MUL_U32_S64_2_D(i);
- }
-
-#pragma pipeloop(0)
- for (i = 0; i < n; i ++) {
- ADD_S64_U32_D(i);
- }
-
- return uc;
- }
- }
-}
-
-/***************************************************************/
-
-t_u32 mul_add_inp(t_u32 *x, t_u32 *y, int n, t_u32 a)
-{
- return mul_add(x, x, y, n, a);
-}
-
-/***************************************************************/
diff --git a/security/nss/lib/freebl/mpi/mpv_sparcv8.s b/security/nss/lib/freebl/mpi/mpv_sparcv8.s
deleted file mode 100644
index daac9c289..000000000
--- a/security/nss/lib/freebl/mpi/mpv_sparcv8.s
+++ /dev/null
@@ -1,1608 +0,0 @@
-! Inner multiply loop functions for hybrid 32/64-bit Sparc v8plus CPUs.
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-! $Id$
-
- .section ".text",#alloc,#execinstr
-/* 000000 3 ( 0 0) */ .file "mpv_sparc.c"
-/* 000000 14 ( 0 0) */ .align 8
-!
-! SUBROUTINE .L_const_seg_900000106
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
-
- .L_const_seg_900000106: /* frequency 1.0 confidence 0.0 */
-/* 000000 19 ( 0 0) */ .word 1127219200,0
-/* 0x0008 20 ( 0 0) */ .word 1105199103,-4194304
-/* 0x0010 21 ( 0 0) */ .align 16
-/* 0x0010 27 ( 0 0) */ .global mul_add
-
-!
-! ENTRY mul_add
-!
-
- .global mul_add
- mul_add: /* frequency 1.0 confidence 0.0 */
-/* 0x0010 29 ( 0 1) */ sethi %hi(0x1800),%g1
-/* 0x0014 30 ( 0 1) */ sethi %hi(mask_cnst),%g2
-/* 0x0018 31 ( 1 2) */ xor %g1,-984,%g1
-/* 0x001c 32 ( 1 2) */ add %g2,%lo(mask_cnst),%g2
-/* 0x0020 33 ( 2 4) */ save %sp,%g1,%sp
-
-!
-! ENTRY .L900000154
-!
-
- .L900000154: /* frequency 1.0 confidence 0.0 */
-/* 0x0024 35 ( 0 2) */ call (.+0x8) ! params = ! Result =
-/* 0x0028 ( 1 2) */ sethi %hi((_GLOBAL_OFFSET_TABLE_-(.L900000154-.))),%g5
-/* 0x002c 177 ( 2 3) */ sethi %hi(.L_const_seg_900000106),%g3
-/* 0x0030 178 ( 2 3) */ add %g5,%lo((_GLOBAL_OFFSET_TABLE_-(.L900000154-.))),%g5
-/* 0x0034 179 ( 3 4) */ or %g0,%i4,%o1
-/* 0x0038 180 ( 3 4) */ st %o1,[%fp+84]
-/* 0x003c 181 ( 3 4) */ add %g5,%o7,%o3
-/* 0x0040 182 ( 4 5) */ add %g3,%lo(.L_const_seg_900000106),%g3
-/* 0x0044 183 ( 4 6) */ ld [%o3+%g2],%g2
-/* 0x0048 184 ( 4 5) */ or %g0,%i3,%o2
-/* 0x004c 185 ( 5 6) */ sethi %hi(0x80000),%g4
-/* 0x0050 186 ( 5 7) */ ld [%o3+%g3],%o0
-/* 0x0054 187 ( 5 6) */ or %g0,%i2,%g5
-/* 0x0058 188 ( 6 7) */ or %g0,%o2,%o3
-/* 0x005c 189 ( 6 10) */ ldd [%g2],%f0
-/* 0x0060 190 ( 6 7) */ subcc %o1,%g4,%g0
-/* 0x0064 191 ( 6 7) */ bcc,pn %icc,.L77000048 ! tprob=0.50
-/* 0x0068 ( 7 8) */ subcc %o2,8,%g0
-/* 0x006c 193 ( 7 8) */ bne,pn %icc,.L77000037 ! tprob=0.50
-/* 0x0070 ( 8 12) */ ldd [%o0],%f8
-/* 0x0074 195 ( 9 13) */ ldd [%g5],%f4
-/* 0x0078 196 (10 14) */ ldd [%g5+8],%f6
-/* 0x007c 197 (11 15) */ ldd [%g5+16],%f10
-/* 0x0080 198 (11 14) */ fmovs %f8,%f12
-/* 0x0084 199 (12 16) */ fxnor %f0,%f4,%f4
-/* 0x0088 200 (12 14) */ ld [%fp+84],%f13
-/* 0x008c 201 (13 17) */ ldd [%o0+8],%f14
-/* 0x0090 202 (13 17) */ fxnor %f0,%f6,%f6
-/* 0x0094 203 (14 18) */ ldd [%g5+24],%f16
-/* 0x0098 204 (14 18) */ fxnor %f0,%f10,%f10
-/* 0x009c 208 (15 17) */ ld [%i1],%g2
-/* 0x00a0 209 (15 20) */ fsubd %f12,%f8,%f8
-/* 0x00a4 210 (16 21) */ fitod %f4,%f18
-/* 0x00a8 211 (16 18) */ ld [%i1+4],%g3
-/* 0x00ac 212 (17 22) */ fitod %f5,%f4
-/* 0x00b0 213 (17 19) */ ld [%i1+8],%g4
-/* 0x00b4 214 (18 23) */ fitod %f6,%f20
-/* 0x00b8 215 (18 20) */ ld [%i1+12],%g5
-/* 0x00bc 216 (19 21) */ ld [%i1+16],%o0
-/* 0x00c0 217 (19 24) */ fitod %f7,%f6
-/* 0x00c4 218 (20 22) */ ld [%i1+20],%o1
-/* 0x00c8 219 (20 24) */ fxnor %f0,%f16,%f16
-/* 0x00cc 220 (21 26) */ fsubd %f14,%f18,%f12
-/* 0x00d0 221 (21 23) */ ld [%i1+24],%o2
-/* 0x00d4 222 (22 27) */ fsubd %f14,%f4,%f4
-/* 0x00d8 223 (22 24) */ ld [%i1+28],%o3
-/* 0x00dc 224 (23 28) */ fitod %f10,%f18
-/* 0x00e0 225 (24 29) */ fsubd %f14,%f20,%f20
-/* 0x00e4 226 (25 30) */ fitod %f11,%f10
-/* 0x00e8 227 (26 31) */ fsubd %f14,%f6,%f6
-/* 0x00ec 228 (26 31) */ fmuld %f12,%f8,%f12
-/* 0x00f0 229 (27 32) */ fitod %f16,%f22
-/* 0x00f4 230 (27 32) */ fmuld %f4,%f8,%f4
-/* 0x00f8 231 (28 33) */ fsubd %f14,%f18,%f18
-/* 0x00fc 232 (29 34) */ fitod %f17,%f16
-/* 0x0100 233 (29 34) */ fmuld %f20,%f8,%f20
-/* 0x0104 234 (30 35) */ fsubd %f14,%f10,%f10
-/* 0x0108 235 (31 36) */ fdtox %f12,%f12
-/* 0x010c 236 (31 32) */ std %f12,[%sp+152]
-/* 0x0110 237 (31 36) */ fmuld %f6,%f8,%f6
-/* 0x0114 238 (32 37) */ fdtox %f4,%f4
-/* 0x0118 239 (32 33) */ std %f4,[%sp+144]
-/* 0x011c 240 (33 38) */ fsubd %f14,%f22,%f4
-/* 0x0120 241 (33 38) */ fmuld %f18,%f8,%f12
-/* 0x0124 242 (34 39) */ fdtox %f20,%f18
-/* 0x0128 243 (34 35) */ std %f18,[%sp+136]
-/* 0x012c 244 (35 37) */ ldx [%sp+152],%o4
-/* 0x0130 245 (35 40) */ fsubd %f14,%f16,%f14
-/* 0x0134 246 (35 40) */ fmuld %f10,%f8,%f10
-/* 0x0138 247 (36 41) */ fdtox %f6,%f6
-/* 0x013c 248 (36 37) */ std %f6,[%sp+128]
-/* 0x0140 249 (37 39) */ ldx [%sp+144],%o5
-/* 0x0144 250 (37 38) */ add %o4,%g2,%o4
-/* 0x0148 251 (38 39) */ st %o4,[%i0]
-/* 0x014c 252 (38 39) */ srax %o4,32,%g2
-/* 0x0150 253 (38 43) */ fdtox %f12,%f6
-/* 0x0154 254 (38 43) */ fmuld %f4,%f8,%f4
-/* 0x0158 255 (39 40) */ std %f6,[%sp+120]
-/* 0x015c 256 (39 40) */ add %o5,%g3,%g3
-/* 0x0160 257 (40 42) */ ldx [%sp+136],%o7
-/* 0x0164 258 (40 41) */ add %g3,%g2,%g2
-/* 0x0168 259 (40 45) */ fmuld %f14,%f8,%f6
-/* 0x016c 260 (40 45) */ fdtox %f10,%f8
-/* 0x0170 261 (41 42) */ std %f8,[%sp+112]
-/* 0x0174 262 (41 42) */ srax %g2,32,%o5
-/* 0x0178 263 (42 44) */ ldx [%sp+128],%g3
-/* 0x017c 264 (42 43) */ add %o7,%g4,%g4
-/* 0x0180 265 (43 44) */ st %g2,[%i0+4]
-/* 0x0184 266 (43 44) */ add %g4,%o5,%g4
-/* 0x0188 267 (43 48) */ fdtox %f4,%f4
-/* 0x018c 268 (44 46) */ ldx [%sp+120],%o5
-/* 0x0190 269 (44 45) */ add %g3,%g5,%g3
-/* 0x0194 270 (44 45) */ srax %g4,32,%g5
-/* 0x0198 271 (45 46) */ std %f4,[%sp+104]
-/* 0x019c 272 (45 46) */ add %g3,%g5,%g3
-/* 0x01a0 273 (45 50) */ fdtox %f6,%f4
-/* 0x01a4 274 (46 47) */ std %f4,[%sp+96]
-/* 0x01a8 275 (46 47) */ add %o5,%o0,%o0
-/* 0x01ac 276 (46 47) */ srax %g3,32,%o5
-/* 0x01b0 277 (47 49) */ ldx [%sp+112],%g5
-/* 0x01b4 278 (47 48) */ add %o0,%o5,%o0
-/* 0x01b8 279 (48 49) */ st %g4,[%i0+8]
-/* 0x01bc 280 (49 51) */ ldx [%sp+104],%o5
-/* 0x01c0 281 (49 50) */ add %g5,%o1,%o1
-/* 0x01c4 282 (49 50) */ srax %o0,32,%g5
-/* 0x01c8 283 (50 51) */ st %o0,[%i0+16]
-/* 0x01cc 284 (50 51) */ add %o1,%g5,%o1
-/* 0x01d0 285 (51 53) */ ldx [%sp+96],%g5
-/* 0x01d4 286 (51 52) */ add %o5,%o2,%o2
-/* 0x01d8 287 (51 52) */ srax %o1,32,%o5
-/* 0x01dc 288 (52 53) */ st %o1,[%i0+20]
-/* 0x01e0 289 (52 53) */ add %o2,%o5,%o2
-/* 0x01e4 290 (53 54) */ st %o2,[%i0+24]
-/* 0x01e8 291 (53 54) */ srax %o2,32,%g4
-/* 0x01ec 292 (53 54) */ add %g5,%o3,%g2
-/* 0x01f0 293 (54 55) */ st %g3,[%i0+12]
-/* 0x01f4 294 (54 55) */ add %g2,%g4,%g2
-/* 0x01f8 295 (55 56) */ st %g2,[%i0+28]
-/* 0x01fc 299 (55 56) */ srax %g2,32,%o7
-/* 0x0200 300 (56 57) */ or %g0,%o7,%i0
-/* 0x0204 (57 64) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x0208 (59 61) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L77000037
-!
-
- .L77000037: /* frequency 1.0 confidence 0.0 */
-/* 0x020c 307 ( 0 1) */ subcc %o2,16,%g0
-/* 0x0210 308 ( 0 1) */ bne,pn %icc,.L77000076 ! tprob=0.50
-/* 0x0214 ( 1 5) */ ldd [%o0],%f8
-/* 0x0218 310 ( 2 6) */ ldd [%g5],%f4
-/* 0x021c 311 ( 3 7) */ ldd [%g5+8],%f6
-/* 0x0220 317 ( 4 8) */ ldd [%o0+8],%f14
-/* 0x0224 318 ( 4 7) */ fmovs %f8,%f12
-/* 0x0228 319 ( 5 7) */ ld [%fp+84],%f13
-/* 0x022c 320 ( 5 9) */ fxnor %f0,%f4,%f4
-/* 0x0230 321 ( 6 10) */ ldd [%g5+16],%f10
-/* 0x0234 322 ( 6 10) */ fxnor %f0,%f6,%f6
-/* 0x0238 323 ( 7 11) */ ldd [%g5+24],%f16
-/* 0x023c 324 ( 8 12) */ ldd [%g5+32],%f20
-/* 0x0240 325 ( 8 13) */ fsubd %f12,%f8,%f8
-/* 0x0244 331 ( 9 11) */ ld [%i1+40],%o7
-/* 0x0248 332 ( 9 14) */ fitod %f4,%f18
-/* 0x024c 333 (10 14) */ ldd [%g5+40],%f22
-/* 0x0250 334 (10 15) */ fitod %f5,%f4
-/* 0x0254 335 (11 12) */ stx %o7,[%sp+96]
-/* 0x0258 336 (11 16) */ fitod %f6,%f24
-/* 0x025c 337 (12 14) */ ld [%i1+44],%o7
-/* 0x0260 338 (12 16) */ fxnor %f0,%f10,%f10
-/* 0x0264 339 (13 17) */ ldd [%g5+48],%f26
-/* 0x0268 340 (13 18) */ fitod %f7,%f6
-/* 0x026c 341 (14 15) */ stx %o7,[%sp+104]
-/* 0x0270 342 (14 19) */ fsubd %f14,%f18,%f18
-/* 0x0274 343 (15 17) */ ld [%i1+48],%o7
-/* 0x0278 344 (15 20) */ fsubd %f14,%f4,%f4
-/* 0x027c 345 (16 18) */ ld [%i1+36],%o5
-/* 0x0280 346 (16 21) */ fitod %f10,%f28
-/* 0x0284 347 (17 18) */ stx %o7,[%sp+112]
-/* 0x0288 348 (17 21) */ fxnor %f0,%f16,%f16
-/* 0x028c 349 (18 20) */ ld [%i1],%g2
-/* 0x0290 350 (18 23) */ fsubd %f14,%f24,%f24
-/* 0x0294 351 (19 20) */ stx %o5,[%sp+120]
-/* 0x0298 352 (19 24) */ fitod %f11,%f10
-/* 0x029c 353 (19 24) */ fmuld %f18,%f8,%f18
-/* 0x02a0 354 (20 22) */ ld [%i1+52],%o5
-/* 0x02a4 355 (20 25) */ fsubd %f14,%f6,%f6
-/* 0x02a8 356 (20 25) */ fmuld %f4,%f8,%f4
-/* 0x02ac 357 (21 26) */ fitod %f16,%f30
-/* 0x02b0 358 (22 26) */ fxnor %f0,%f20,%f20
-/* 0x02b4 359 (22 24) */ ld [%i1+4],%g3
-/* 0x02b8 360 (23 27) */ ldd [%g5+56],%f2
-/* 0x02bc 361 (23 28) */ fsubd %f14,%f28,%f28
-/* 0x02c0 362 (23 28) */ fmuld %f24,%f8,%f24
-/* 0x02c4 363 (24 25) */ stx %o5,[%sp+128]
-/* 0x02c8 364 (24 29) */ fdtox %f18,%f18
-/* 0x02cc 365 (25 26) */ std %f18,[%sp+272]
-/* 0x02d0 366 (25 30) */ fitod %f17,%f16
-/* 0x02d4 367 (25 30) */ fmuld %f6,%f8,%f6
-/* 0x02d8 368 (26 31) */ fsubd %f14,%f10,%f10
-/* 0x02dc 369 (27 32) */ fitod %f20,%f18
-/* 0x02e0 370 (28 33) */ fdtox %f4,%f4
-/* 0x02e4 371 (28 29) */ std %f4,[%sp+264]
-/* 0x02e8 372 (28 33) */ fmuld %f28,%f8,%f28
-/* 0x02ec 373 (29 31) */ ld [%i1+8],%g4
-/* 0x02f0 374 (29 34) */ fsubd %f14,%f30,%f4
-/* 0x02f4 375 (30 34) */ fxnor %f0,%f22,%f22
-/* 0x02f8 376 (30 32) */ ld [%i1+12],%g5
-/* 0x02fc 377 (31 33) */ ld [%i1+16],%o0
-/* 0x0300 378 (31 36) */ fitod %f21,%f20
-/* 0x0304 379 (31 36) */ fmuld %f10,%f8,%f10
-/* 0x0308 380 (32 34) */ ld [%i1+20],%o1
-/* 0x030c 381 (32 37) */ fdtox %f24,%f24
-/* 0x0310 382 (33 34) */ std %f24,[%sp+256]
-/* 0x0314 383 (33 38) */ fsubd %f14,%f16,%f16
-/* 0x0318 384 (34 36) */ ldx [%sp+272],%o7
-/* 0x031c 385 (34 39) */ fdtox %f6,%f6
-/* 0x0320 386 (34 39) */ fmuld %f4,%f8,%f4
-/* 0x0324 387 (35 36) */ std %f6,[%sp+248]
-/* 0x0328 388 (35 40) */ fitod %f22,%f24
-/* 0x032c 389 (36 38) */ ld [%i1+32],%o4
-/* 0x0330 390 (36 41) */ fsubd %f14,%f18,%f6
-/* 0x0334 391 (36 37) */ add %o7,%g2,%g2
-/* 0x0338 392 (37 39) */ ldx [%sp+264],%o7
-/* 0x033c 393 (37 41) */ fxnor %f0,%f26,%f26
-/* 0x0340 394 (37 38) */ srax %g2,32,%o5
-/* 0x0344 395 (38 39) */ st %g2,[%i0]
-/* 0x0348 396 (38 43) */ fitod %f23,%f18
-/* 0x034c 397 (38 43) */ fmuld %f16,%f8,%f16
-/* 0x0350 398 (39 41) */ ldx [%sp+248],%g2
-/* 0x0354 399 (39 44) */ fdtox %f28,%f22
-/* 0x0358 400 (39 40) */ add %o7,%g3,%g3
-/* 0x035c 401 (40 42) */ ldx [%sp+256],%o7
-/* 0x0360 402 (40 45) */ fsubd %f14,%f20,%f20
-/* 0x0364 403 (40 41) */ add %g3,%o5,%g3
-/* 0x0368 404 (41 42) */ std %f22,[%sp+240]
-/* 0x036c 405 (41 46) */ fitod %f26,%f22
-/* 0x0370 406 (41 42) */ srax %g3,32,%o5
-/* 0x0374 407 (41 42) */ add %g2,%g5,%g2
-/* 0x0378 408 (42 43) */ st %g3,[%i0+4]
-/* 0x037c 409 (42 47) */ fdtox %f10,%f10
-/* 0x0380 410 (42 43) */ add %o7,%g4,%g4
-/* 0x0384 411 (42 47) */ fmuld %f6,%f8,%f6
-/* 0x0388 412 (43 44) */ std %f10,[%sp+232]
-/* 0x038c 413 (43 47) */ fxnor %f0,%f2,%f12
-/* 0x0390 414 (43 44) */ add %g4,%o5,%g4
-/* 0x0394 415 (44 45) */ st %g4,[%i0+8]
-/* 0x0398 416 (44 45) */ srax %g4,32,%o5
-/* 0x039c 417 (44 49) */ fsubd %f14,%f24,%f10
-/* 0x03a0 418 (45 47) */ ldx [%sp+240],%o7
-/* 0x03a4 419 (45 50) */ fdtox %f4,%f4
-/* 0x03a8 420 (45 46) */ add %g2,%o5,%g2
-/* 0x03ac 421 (45 50) */ fmuld %f20,%f8,%f20
-/* 0x03b0 422 (46 47) */ std %f4,[%sp+224]
-/* 0x03b4 423 (46 47) */ srax %g2,32,%g5
-/* 0x03b8 424 (46 51) */ fsubd %f14,%f18,%f4
-/* 0x03bc 425 (47 48) */ st %g2,[%i0+12]
-/* 0x03c0 426 (47 52) */ fitod %f27,%f24
-/* 0x03c4 427 (47 48) */ add %o7,%o0,%g3
-/* 0x03c8 428 (48 50) */ ldx [%sp+232],%o5
-/* 0x03cc 429 (48 53) */ fdtox %f16,%f16
-/* 0x03d0 430 (48 49) */ add %g3,%g5,%g2
-/* 0x03d4 431 (49 50) */ std %f16,[%sp+216]
-/* 0x03d8 432 (49 50) */ srax %g2,32,%g4
-/* 0x03dc 433 (49 54) */ fitod %f12,%f18
-/* 0x03e0 434 (49 54) */ fmuld %f10,%f8,%f10
-/* 0x03e4 435 (50 51) */ st %g2,[%i0+16]
-/* 0x03e8 436 (50 55) */ fsubd %f14,%f22,%f16
-/* 0x03ec 437 (50 51) */ add %o5,%o1,%g2
-/* 0x03f0 438 (51 53) */ ld [%i1+24],%o2
-/* 0x03f4 439 (51 56) */ fitod %f13,%f12
-/* 0x03f8 440 (51 52) */ add %g2,%g4,%g2
-/* 0x03fc 441 (51 56) */ fmuld %f4,%f8,%f22
-/* 0x0400 442 (52 54) */ ldx [%sp+224],%g3
-/* 0x0404 443 (52 53) */ srax %g2,32,%g4
-/* 0x0408 444 (52 57) */ fdtox %f6,%f6
-/* 0x040c 445 (53 54) */ std %f6,[%sp+208]
-/* 0x0410 446 (53 58) */ fdtox %f20,%f6
-/* 0x0414 447 (54 55) */ stx %o4,[%sp+136]
-/* 0x0418 448 (54 59) */ fsubd %f14,%f24,%f4
-/* 0x041c 449 (55 56) */ std %f6,[%sp+200]
-/* 0x0420 450 (55 60) */ fsubd %f14,%f18,%f6
-/* 0x0424 451 (55 60) */ fmuld %f16,%f8,%f16
-/* 0x0428 452 (56 57) */ st %g2,[%i0+20]
-/* 0x042c 453 (56 57) */ add %g3,%o2,%g2
-/* 0x0430 454 (56 61) */ fdtox %f10,%f10
-/* 0x0434 455 (57 59) */ ld [%i1+28],%o3
-/* 0x0438 456 (57 58) */ add %g2,%g4,%g2
-/* 0x043c 457 (58 60) */ ldx [%sp+216],%g5
-/* 0x0440 458 (58 59) */ srax %g2,32,%g4
-/* 0x0444 459 (59 60) */ std %f10,[%sp+192]
-/* 0x0448 460 (59 64) */ fsubd %f14,%f12,%f10
-/* 0x044c 461 (59 64) */ fmuld %f4,%f8,%f4
-/* 0x0450 462 (60 61) */ st %g2,[%i0+24]
-/* 0x0454 463 (60 61) */ add %g5,%o3,%g2
-/* 0x0458 464 (60 65) */ fdtox %f22,%f12
-/* 0x045c 465 (60 65) */ fmuld %f6,%f8,%f6
-/* 0x0460 466 (61 63) */ ldx [%sp+136],%o0
-/* 0x0464 467 (61 62) */ add %g2,%g4,%g2
-/* 0x0468 468 (62 64) */ ldx [%sp+208],%g3
-/* 0x046c 469 (62 63) */ srax %g2,32,%g4
-/* 0x0470 470 (63 65) */ ldx [%sp+120],%o1
-/* 0x0474 471 (64 66) */ ldx [%sp+200],%g5
-/* 0x0478 472 (64 65) */ add %g3,%o0,%g3
-/* 0x047c 473 (64 69) */ fdtox %f4,%f4
-/* 0x0480 474 (64 69) */ fmuld %f10,%f8,%f8
-/* 0x0484 475 (65 66) */ std %f12,[%sp+184]
-/* 0x0488 476 (65 66) */ add %g3,%g4,%g3
-/* 0x048c 477 (65 70) */ fdtox %f16,%f12
-/* 0x0490 478 (66 67) */ std %f12,[%sp+176]
-/* 0x0494 479 (66 67) */ srax %g3,32,%o0
-/* 0x0498 480 (66 67) */ add %g5,%o1,%g5
-/* 0x049c 481 (67 69) */ ldx [%sp+192],%o2
-/* 0x04a0 482 (67 68) */ add %g5,%o0,%g5
-/* 0x04a4 483 (68 70) */ ldx [%sp+96],%g4
-/* 0x04a8 484 (68 69) */ srax %g5,32,%o1
-/* 0x04ac 485 (69 71) */ ld [%i1+56],%o4
-/* 0x04b0 486 (70 72) */ ldx [%sp+104],%o0
-/* 0x04b4 487 (70 71) */ add %o2,%g4,%g4
-/* 0x04b8 488 (71 72) */ std %f4,[%sp+168]
-/* 0x04bc 489 (71 72) */ add %g4,%o1,%g4
-/* 0x04c0 490 (71 76) */ fdtox %f6,%f4
-/* 0x04c4 491 (72 74) */ ldx [%sp+184],%o3
-/* 0x04c8 492 (72 73) */ srax %g4,32,%o2
-/* 0x04cc 493 (73 75) */ ldx [%sp+112],%o1
-/* 0x04d0 494 (74 75) */ std %f4,[%sp+160]
-/* 0x04d4 495 (74 75) */ add %o3,%o0,%o0
-/* 0x04d8 496 (74 79) */ fdtox %f8,%f4
-/* 0x04dc 497 (75 77) */ ldx [%sp+176],%o5
-/* 0x04e0 498 (75 76) */ add %o0,%o2,%o0
-/* 0x04e4 499 (76 77) */ stx %o4,[%sp+144]
-/* 0x04e8 500 (77 78) */ st %g2,[%i0+28]
-/* 0x04ec 501 (77 78) */ add %o5,%o1,%g2
-/* 0x04f0 502 (77 78) */ srax %o0,32,%o1
-/* 0x04f4 503 (78 79) */ std %f4,[%sp+152]
-/* 0x04f8 504 (78 79) */ add %g2,%o1,%o1
-/* 0x04fc 505 (79 81) */ ldx [%sp+168],%o7
-/* 0x0500 506 (79 80) */ srax %o1,32,%o3
-/* 0x0504 507 (80 82) */ ldx [%sp+128],%o2
-/* 0x0508 508 (81 83) */ ld [%i1+60],%o4
-/* 0x050c 509 (82 83) */ add %o7,%o2,%o2
-/* 0x0510 510 (83 84) */ add %o2,%o3,%o2
-/* 0x0514 511 (83 85) */ ldx [%sp+144],%o5
-/* 0x0518 512 (84 86) */ ldx [%sp+160],%g2
-/* 0x051c 513 (85 87) */ ldx [%sp+152],%o3
-/* 0x0520 514 (86 87) */ st %g3,[%i0+32]
-/* 0x0524 515 (86 87) */ add %g2,%o5,%g2
-/* 0x0528 516 (86 87) */ srax %o2,32,%o5
-/* 0x052c 517 (87 88) */ st %g5,[%i0+36]
-/* 0x0530 518 (87 88) */ add %g2,%o5,%g2
-/* 0x0534 519 (87 88) */ add %o3,%o4,%g3
-/* 0x0538 520 (88 89) */ st %o0,[%i0+44]
-/* 0x053c 521 (88 89) */ srax %g2,32,%g5
-/* 0x0540 522 (89 90) */ st %o1,[%i0+48]
-/* 0x0544 523 (89 90) */ add %g3,%g5,%g3
-/* 0x0548 524 (90 91) */ st %o2,[%i0+52]
-/* 0x054c 528 (90 91) */ srax %g3,32,%o7
-/* 0x0550 529 (91 92) */ st %g4,[%i0+40]
-/* 0x0554 530 (92 93) */ st %g2,[%i0+56]
-/* 0x0558 531 (93 94) */ st %g3,[%i0+60]
-/* 0x055c 532 (93 94) */ or %g0,%o7,%i0
-/* 0x0560 (94 101) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x0564 (96 98) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L77000076
-!
-
- .L77000076: /* frequency 1.0 confidence 0.0 */
-/* 0x0568 540 ( 0 4) */ ldd [%o0],%f6
-/* 0x056c 546 ( 0 1) */ add %o2,1,%g2
-/* 0x0570 547 ( 0 3) */ fmovd %f0,%f14
-/* 0x0574 548 ( 0 1) */ or %g0,0,%o7
-/* 0x0578 549 ( 1 3) */ ld [%fp+84],%f9
-/* 0x057c 550 ( 1 2) */ srl %g2,31,%g3
-/* 0x0580 551 ( 1 2) */ add %fp,-2264,%o5
-/* 0x0584 552 ( 2 3) */ add %g2,%g3,%g2
-/* 0x0588 553 ( 2 6) */ ldd [%o0+8],%f18
-/* 0x058c 554 ( 2 3) */ add %fp,-2256,%o4
-/* 0x0590 555 ( 3 6) */ fmovs %f6,%f8
-/* 0x0594 556 ( 3 4) */ sra %g2,1,%o1
-/* 0x0598 557 ( 3 4) */ or %g0,0,%g2
-/* 0x059c 558 ( 4 5) */ subcc %o1,0,%g0
-/* 0x05a0 559 ( 4 5) */ sub %o1,1,%o2
-/* 0x05a4 563 ( 5 6) */ add %g5,32,%o0
-/* 0x05a8 564 ( 6 11) */ fsubd %f8,%f6,%f16
-/* 0x05ac 565 ( 6 7) */ ble,pt %icc,.L900000161 ! tprob=0.50
-/* 0x05b0 ( 6 7) */ subcc %o3,0,%g0
-/* 0x05b4 567 ( 7 8) */ subcc %o1,7,%g0
-/* 0x05b8 568 ( 7 8) */ bl,pn %icc,.L77000077 ! tprob=0.50
-/* 0x05bc ( 7 8) */ sub %o1,2,%o1
-/* 0x05c0 570 ( 8 12) */ ldd [%g5],%f2
-/* 0x05c4 571 ( 9 13) */ ldd [%g5+8],%f4
-/* 0x05c8 572 ( 9 10) */ or %g0,5,%g2
-/* 0x05cc 573 (10 14) */ ldd [%g5+16],%f0
-/* 0x05d0 574 (11 15) */ fxnor %f14,%f2,%f2
-/* 0x05d4 575 (11 15) */ ldd [%g5+24],%f12
-/* 0x05d8 576 (12 16) */ fxnor %f14,%f4,%f6
-/* 0x05dc 577 (12 16) */ ldd [%g5+32],%f10
-/* 0x05e0 578 (13 17) */ fxnor %f14,%f0,%f8
-/* 0x05e4 579 (15 20) */ fitod %f3,%f0
-/* 0x05e8 580 (16 21) */ fitod %f2,%f4
-/* 0x05ec 581 (17 22) */ fitod %f7,%f2
-/* 0x05f0 582 (18 23) */ fitod %f6,%f6
-/* 0x05f4 583 (20 25) */ fsubd %f18,%f0,%f0
-/* 0x05f8 584 (21 26) */ fsubd %f18,%f4,%f4
-
-!
-! ENTRY .L900000149
-!
-
- .L900000149: /* frequency 1.0 confidence 0.0 */
-/* 0x05fc 586 ( 0 4) */ fxnor %f14,%f12,%f22
-/* 0x0600 587 ( 0 5) */ fmuld %f4,%f16,%f4
-/* 0x0604 588 ( 0 1) */ add %g2,2,%g2
-/* 0x0608 589 ( 0 1) */ add %o4,32,%o4
-/* 0x060c 590 ( 1 6) */ fitod %f9,%f24
-/* 0x0610 591 ( 1 6) */ fmuld %f0,%f16,%f20
-/* 0x0614 592 ( 1 2) */ add %o0,8,%o0
-/* 0x0618 593 ( 1 2) */ subcc %g2,%o1,%g0
-/* 0x061c 594 ( 2 6) */ ldd [%o0],%f12
-/* 0x0620 595 ( 2 7) */ fsubd %f18,%f2,%f0
-/* 0x0624 596 ( 2 3) */ add %o5,32,%o5
-/* 0x0628 597 ( 3 8) */ fsubd %f18,%f6,%f2
-/* 0x062c 598 ( 5 10) */ fdtox %f4,%f4
-/* 0x0630 599 ( 6 11) */ fdtox %f20,%f6
-/* 0x0634 600 ( 6 7) */ std %f4,[%o5-32]
-/* 0x0638 601 ( 7 12) */ fitod %f8,%f4
-/* 0x063c 602 ( 7 8) */ std %f6,[%o4-32]
-/* 0x0640 603 ( 8 12) */ fxnor %f14,%f10,%f8
-/* 0x0644 604 ( 8 13) */ fmuld %f2,%f16,%f6
-/* 0x0648 605 ( 9 14) */ fitod %f23,%f2
-/* 0x064c 606 ( 9 14) */ fmuld %f0,%f16,%f20
-/* 0x0650 607 ( 9 10) */ add %o0,8,%o0
-/* 0x0654 608 (10 14) */ ldd [%o0],%f10
-/* 0x0658 609 (10 15) */ fsubd %f18,%f24,%f0
-/* 0x065c 610 (12 17) */ fsubd %f18,%f4,%f4
-/* 0x0660 611 (13 18) */ fdtox %f6,%f6
-/* 0x0664 612 (14 19) */ fdtox %f20,%f20
-/* 0x0668 613 (14 15) */ std %f6,[%o5-16]
-/* 0x066c 614 (15 20) */ fitod %f22,%f6
-/* 0x0670 615 (15 16) */ ble,pt %icc,.L900000149 ! tprob=0.50
-/* 0x0674 (15 16) */ std %f20,[%o4-16]
-
-!
-! ENTRY .L900000152
-!
-
- .L900000152: /* frequency 1.0 confidence 0.0 */
-/* 0x0678 618 ( 0 4) */ fxnor %f14,%f12,%f12
-/* 0x067c 619 ( 0 5) */ fmuld %f0,%f16,%f22
-/* 0x0680 620 ( 0 1) */ add %o5,80,%o5
-/* 0x0684 621 ( 0 1) */ add %o4,80,%o4
-/* 0x0688 622 ( 1 5) */ fxnor %f14,%f10,%f0
-/* 0x068c 623 ( 1 6) */ fmuld %f4,%f16,%f24
-/* 0x0690 624 ( 1 2) */ subcc %g2,%o2,%g0
-/* 0x0694 625 ( 1 2) */ add %o0,8,%g5
-/* 0x0698 626 ( 2 7) */ fitod %f8,%f20
-/* 0x069c 627 ( 3 8) */ fitod %f9,%f8
-/* 0x06a0 628 ( 4 9) */ fsubd %f18,%f6,%f6
-/* 0x06a4 629 ( 5 10) */ fitod %f12,%f26
-/* 0x06a8 630 ( 6 11) */ fitod %f13,%f4
-/* 0x06ac 631 ( 7 12) */ fsubd %f18,%f2,%f12
-/* 0x06b0 632 ( 8 13) */ fitod %f0,%f2
-/* 0x06b4 633 ( 9 14) */ fitod %f1,%f0
-/* 0x06b8 634 (10 15) */ fsubd %f18,%f20,%f10
-/* 0x06bc 635 (10 15) */ fmuld %f6,%f16,%f20
-/* 0x06c0 636 (11 16) */ fsubd %f18,%f8,%f8
-/* 0x06c4 637 (12 17) */ fsubd %f18,%f26,%f6
-/* 0x06c8 638 (12 17) */ fmuld %f12,%f16,%f12
-/* 0x06cc 639 (13 18) */ fsubd %f18,%f4,%f4
-/* 0x06d0 640 (14 19) */ fsubd %f18,%f2,%f2
-/* 0x06d4 641 (15 20) */ fsubd %f18,%f0,%f0
-/* 0x06d8 642 (15 20) */ fmuld %f10,%f16,%f10
-/* 0x06dc 643 (16 21) */ fdtox %f24,%f24
-/* 0x06e0 644 (16 17) */ std %f24,[%o5-80]
-/* 0x06e4 645 (16 21) */ fmuld %f8,%f16,%f8
-/* 0x06e8 646 (17 22) */ fdtox %f22,%f22
-/* 0x06ec 647 (17 18) */ std %f22,[%o4-80]
-/* 0x06f0 648 (17 22) */ fmuld %f6,%f16,%f6
-/* 0x06f4 649 (18 23) */ fdtox %f20,%f20
-/* 0x06f8 650 (18 19) */ std %f20,[%o5-64]
-/* 0x06fc 651 (18 23) */ fmuld %f4,%f16,%f4
-/* 0x0700 652 (19 24) */ fdtox %f12,%f12
-/* 0x0704 653 (19 20) */ std %f12,[%o4-64]
-/* 0x0708 654 (19 24) */ fmuld %f2,%f16,%f2
-/* 0x070c 655 (20 25) */ fdtox %f10,%f10
-/* 0x0710 656 (20 21) */ std %f10,[%o5-48]
-/* 0x0714 657 (20 25) */ fmuld %f0,%f16,%f0
-/* 0x0718 658 (21 26) */ fdtox %f8,%f8
-/* 0x071c 659 (21 22) */ std %f8,[%o4-48]
-/* 0x0720 660 (22 27) */ fdtox %f6,%f6
-/* 0x0724 661 (22 23) */ std %f6,[%o5-32]
-/* 0x0728 662 (23 28) */ fdtox %f4,%f4
-/* 0x072c 663 (23 24) */ std %f4,[%o4-32]
-/* 0x0730 664 (24 29) */ fdtox %f2,%f2
-/* 0x0734 665 (24 25) */ std %f2,[%o5-16]
-/* 0x0738 666 (25 30) */ fdtox %f0,%f0
-/* 0x073c 667 (25 26) */ bg,pn %icc,.L77000043 ! tprob=0.50
-/* 0x0740 (25 26) */ std %f0,[%o4-16]
-
-!
-! ENTRY .L77000077
-!
-
- .L77000077: /* frequency 1.0 confidence 0.0 */
-/* 0x0744 670 ( 0 4) */ ldd [%g5],%f0
-
-!
-! ENTRY .L900000160
-!
-
- .L900000160: /* frequency 1.0 confidence 0.0 */
-/* 0x0748 672 ( 0 4) */ fxnor %f14,%f0,%f0
-/* 0x074c 673 ( 0 1) */ add %g2,1,%g2
-/* 0x0750 674 ( 0 1) */ add %g5,8,%g5
-/* 0x0754 675 ( 1 2) */ subcc %g2,%o2,%g0
-/* 0x0758 676 ( 4 9) */ fitod %f0,%f2
-/* 0x075c 677 ( 5 10) */ fitod %f1,%f0
-/* 0x0760 678 ( 9 14) */ fsubd %f18,%f2,%f2
-/* 0x0764 679 (10 15) */ fsubd %f18,%f0,%f0
-/* 0x0768 680 (14 19) */ fmuld %f2,%f16,%f2
-/* 0x076c 681 (15 20) */ fmuld %f0,%f16,%f0
-/* 0x0770 682 (19 24) */ fdtox %f2,%f2
-/* 0x0774 683 (19 20) */ std %f2,[%o5]
-/* 0x0778 684 (19 20) */ add %o5,16,%o5
-/* 0x077c 685 (20 25) */ fdtox %f0,%f0
-/* 0x0780 686 (20 21) */ std %f0,[%o4]
-/* 0x0784 687 (20 21) */ add %o4,16,%o4
-/* 0x0788 688 (20 21) */ ble,a,pt %icc,.L900000160 ! tprob=0.50
-/* 0x078c (23 27) */ ldd [%g5],%f0
-
-!
-! ENTRY .L77000043
-!
-
- .L77000043: /* frequency 1.0 confidence 0.0 */
-/* 0x0790 696 ( 0 1) */ subcc %o3,0,%g0
-
-!
-! ENTRY .L900000161
-!
-
- .L900000161: /* frequency 1.0 confidence 0.0 */
-/* 0x0794 698 ( 0 1) */ ble,a,pt %icc,.L900000159 ! tprob=0.50
-/* 0x0798 ( 0 1) */ or %g0,%o7,%i0
-/* 0x079c 703 ( 0 2) */ ldx [%fp-2256],%o2
-/* 0x07a0 704 ( 0 1) */ or %g0,%i1,%g3
-/* 0x07a4 705 ( 1 2) */ sub %o3,1,%o5
-/* 0x07a8 706 ( 1 2) */ or %g0,0,%g4
-/* 0x07ac 707 ( 2 3) */ add %fp,-2264,%g5
-/* 0x07b0 708 ( 2 3) */ or %g0,%i0,%g2
-/* 0x07b4 709 ( 3 4) */ subcc %o3,6,%g0
-/* 0x07b8 710 ( 3 4) */ sub %o5,2,%o4
-/* 0x07bc 711 ( 3 4) */ bl,pn %icc,.L77000078 ! tprob=0.50
-/* 0x07c0 ( 3 5) */ ldx [%fp-2264],%o0
-/* 0x07c4 713 ( 4 6) */ ld [%g3],%o1
-/* 0x07c8 714 ( 4 5) */ add %g2,4,%g2
-/* 0x07cc 715 ( 4 5) */ or %g0,3,%g4
-/* 0x07d0 716 ( 5 7) */ ld [%g3+4],%o3
-/* 0x07d4 717 ( 5 6) */ add %g3,8,%g3
-/* 0x07d8 718 ( 5 6) */ add %fp,-2240,%g5
-/* 0x07dc 719 ( 6 7) */ add %o0,%o1,%o0
-/* 0x07e0 720 ( 6 8) */ ldx [%fp-2248],%o1
-/* 0x07e4 721 ( 7 8) */ st %o0,[%g2-4]
-/* 0x07e8 722 ( 7 8) */ srax %o0,32,%o0
-
-!
-! ENTRY .L900000145
-!
-
- .L900000145: /* frequency 1.0 confidence 0.0 */
-/* 0x07ec 724 ( 0 2) */ ld [%g3],%o7
-/* 0x07f0 725 ( 0 1) */ add %o2,%o3,%o2
-/* 0x07f4 726 ( 0 1) */ sra %o0,0,%o3
-/* 0x07f8 727 ( 1 3) */ ldx [%g5],%o0
-/* 0x07fc 728 ( 1 2) */ add %o2,%o3,%o2
-/* 0x0800 729 ( 1 2) */ add %g4,3,%g4
-/* 0x0804 730 ( 2 3) */ st %o2,[%g2]
-/* 0x0808 731 ( 2 3) */ srax %o2,32,%o3
-/* 0x080c 732 ( 2 3) */ subcc %g4,%o4,%g0
-/* 0x0810 733 ( 3 5) */ ld [%g3+4],%o2
-/* 0x0814 734 ( 4 5) */ stx %o2,[%sp+96]
-/* 0x0818 735 ( 4 5) */ add %o1,%o7,%o1
-/* 0x081c 736 ( 5 7) */ ldx [%g5+8],%o2
-/* 0x0820 737 ( 5 6) */ add %o1,%o3,%o1
-/* 0x0824 738 ( 5 6) */ add %g2,12,%g2
-/* 0x0828 739 ( 6 7) */ st %o1,[%g2-8]
-/* 0x082c 740 ( 6 7) */ srax %o1,32,%o7
-/* 0x0830 741 ( 6 7) */ add %g3,12,%g3
-/* 0x0834 742 ( 7 9) */ ld [%g3-4],%o3
-/* 0x0838 743 ( 8 10) */ ldx [%sp+96],%o1
-/* 0x083c 744 (10 11) */ add %o0,%o1,%o0
-/* 0x0840 745 (10 12) */ ldx [%g5+16],%o1
-/* 0x0844 746 (11 12) */ add %o0,%o7,%o0
-/* 0x0848 747 (11 12) */ add %g5,24,%g5
-/* 0x084c 748 (11 12) */ st %o0,[%g2-4]
-/* 0x0850 749 (11 12) */ ble,pt %icc,.L900000145 ! tprob=0.50
-/* 0x0854 (12 13) */ srax %o0,32,%o0
-
-!
-! ENTRY .L900000148
-!
-
- .L900000148: /* frequency 1.0 confidence 0.0 */
-/* 0x0858 752 ( 0 1) */ add %o2,%o3,%o2
-/* 0x085c 753 ( 0 1) */ sra %o0,0,%o3
-/* 0x0860 754 ( 0 2) */ ld [%g3],%o0
-/* 0x0864 755 ( 1 2) */ add %o2,%o3,%o3
-/* 0x0868 756 ( 1 2) */ add %g2,8,%g2
-/* 0x086c 757 ( 2 3) */ srax %o3,32,%o2
-/* 0x0870 758 ( 2 3) */ st %o3,[%g2-8]
-/* 0x0874 759 ( 2 3) */ add %o1,%o0,%o0
-/* 0x0878 760 ( 3 4) */ add %o0,%o2,%o0
-/* 0x087c 761 ( 3 4) */ st %o0,[%g2-4]
-/* 0x0880 762 ( 3 4) */ subcc %g4,%o5,%g0
-/* 0x0884 763 ( 3 4) */ bg,pn %icc,.L77000061 ! tprob=0.50
-/* 0x0888 ( 4 5) */ srax %o0,32,%o7
-/* 0x088c 765 ( 4 5) */ add %g3,4,%g3
-
-!
-! ENTRY .L77000078
-!
-
- .L77000078: /* frequency 1.0 confidence 0.0 */
-/* 0x0890 767 ( 0 2) */ ld [%g3],%o2
-
-!
-! ENTRY .L900000158
-!
-
- .L900000158: /* frequency 1.0 confidence 0.0 */
-/* 0x0894 769 ( 0 2) */ ldx [%g5],%o0
-/* 0x0898 770 ( 0 1) */ sra %o7,0,%o1
-/* 0x089c 771 ( 0 1) */ add %g4,1,%g4
-/* 0x08a0 772 ( 1 2) */ add %g3,4,%g3
-/* 0x08a4 773 ( 1 2) */ add %g5,8,%g5
-/* 0x08a8 774 ( 2 3) */ add %o0,%o2,%o0
-/* 0x08ac 775 ( 2 3) */ subcc %g4,%o5,%g0
-/* 0x08b0 776 ( 3 4) */ add %o0,%o1,%o0
-/* 0x08b4 777 ( 3 4) */ st %o0,[%g2]
-/* 0x08b8 778 ( 3 4) */ add %g2,4,%g2
-/* 0x08bc 779 ( 4 5) */ srax %o0,32,%o7
-/* 0x08c0 780 ( 4 5) */ ble,a,pt %icc,.L900000158 ! tprob=0.50
-/* 0x08c4 ( 4 6) */ ld [%g3],%o2
-
-!
-! ENTRY .L77000047
-!
-
- .L77000047: /* frequency 1.0 confidence 0.0 */
-/* 0x08c8 783 ( 0 1) */ or %g0,%o7,%i0
-/* 0x08cc ( 1 8) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x08d0 ( 3 5) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L77000048
-!
-
- .L77000048: /* frequency 1.0 confidence 0.0 */
-/* 0x08d4 794 ( 0 1) */ bne,pn %icc,.L77000050 ! tprob=0.50
-/* 0x08d8 ( 0 1) */ sethi %hi(0xfff80000),%g2
-/* 0x08dc 796 ( 0 4) */ ldd [%g5],%f4
-/* 0x08e0 804 ( 0 1) */ srl %o1,19,%g3
-/* 0x08e4 805 ( 1 2) */ st %g3,[%sp+240]
-/* 0x08e8 806 ( 1 2) */ andn %o1,%g2,%g2
-/* 0x08ec 807 ( 2 6) */ ldd [%o0],%f8
-/* 0x08f0 808 ( 3 4) */ st %g2,[%sp+244]
-/* 0x08f4 809 ( 3 7) */ fxnor %f0,%f4,%f4
-/* 0x08f8 810 ( 4 8) */ ldd [%g5+8],%f6
-/* 0x08fc 814 ( 5 9) */ ldd [%o0+8],%f18
-/* 0x0900 815 ( 5 8) */ fmovs %f8,%f12
-/* 0x0904 816 ( 6 10) */ ldd [%g5+16],%f10
-/* 0x0908 817 ( 6 9) */ fmovs %f8,%f16
-/* 0x090c 818 ( 7 11) */ ldd [%g5+24],%f20
-/* 0x0910 819 ( 7 12) */ fitod %f4,%f14
-/* 0x0914 823 ( 8 10) */ ld [%i1],%g2
-/* 0x0918 824 ( 8 13) */ fitod %f5,%f4
-/* 0x091c 825 ( 9 11) */ ld [%sp+240],%f13
-/* 0x0920 826 ( 9 13) */ fxnor %f0,%f6,%f6
-/* 0x0924 827 (10 12) */ ld [%sp+244],%f17
-/* 0x0928 828 (10 14) */ fxnor %f0,%f10,%f10
-/* 0x092c 829 (11 13) */ ld [%i1+28],%o3
-/* 0x0930 830 (11 15) */ fxnor %f0,%f20,%f20
-/* 0x0934 831 (12 14) */ ld [%i1+4],%g3
-/* 0x0938 832 (12 17) */ fsubd %f12,%f8,%f12
-/* 0x093c 833 (13 14) */ stx %o3,[%sp+96]
-/* 0x0940 834 (13 18) */ fsubd %f18,%f14,%f14
-/* 0x0944 835 (14 16) */ ld [%i1+8],%g4
-/* 0x0948 836 (14 19) */ fsubd %f16,%f8,%f8
-/* 0x094c 837 (15 17) */ ld [%i1+12],%g5
-/* 0x0950 838 (15 20) */ fsubd %f18,%f4,%f4
-/* 0x0954 839 (16 18) */ ld [%i1+16],%o0
-/* 0x0958 840 (16 21) */ fitod %f6,%f22
-/* 0x095c 841 (17 19) */ ld [%i1+20],%o1
-/* 0x0960 842 (17 22) */ fitod %f7,%f6
-/* 0x0964 843 (18 20) */ ld [%i1+24],%o2
-/* 0x0968 844 (18 23) */ fitod %f10,%f16
-/* 0x096c 845 (18 23) */ fmuld %f14,%f12,%f24
-/* 0x0970 846 (19 24) */ fitod %f20,%f28
-/* 0x0974 847 (19 24) */ fmuld %f14,%f8,%f14
-/* 0x0978 848 (20 25) */ fitod %f11,%f10
-/* 0x097c 849 (20 25) */ fmuld %f4,%f12,%f26
-/* 0x0980 850 (21 26) */ fsubd %f18,%f22,%f22
-/* 0x0984 851 (21 26) */ fmuld %f4,%f8,%f4
-/* 0x0988 852 (22 27) */ fsubd %f18,%f6,%f6
-/* 0x098c 853 (23 28) */ fdtox %f24,%f24
-/* 0x0990 854 (23 24) */ std %f24,[%sp+224]
-/* 0x0994 855 (24 29) */ fdtox %f14,%f14
-/* 0x0998 856 (24 25) */ std %f14,[%sp+232]
-/* 0x099c 857 (25 30) */ fdtox %f26,%f14
-/* 0x09a0 858 (25 26) */ std %f14,[%sp+208]
-/* 0x09a4 859 (26 28) */ ldx [%sp+224],%o4
-/* 0x09a8 860 (26 31) */ fitod %f21,%f20
-/* 0x09ac 861 (26 31) */ fmuld %f22,%f12,%f30
-/* 0x09b0 862 (27 29) */ ldx [%sp+232],%o5
-/* 0x09b4 863 (27 32) */ fsubd %f18,%f16,%f16
-/* 0x09b8 864 (27 32) */ fmuld %f22,%f8,%f22
-/* 0x09bc 865 (28 29) */ sllx %o4,19,%o4
-/* 0x09c0 866 (28 33) */ fdtox %f4,%f4
-/* 0x09c4 867 (28 29) */ std %f4,[%sp+216]
-/* 0x09c8 868 (28 33) */ fmuld %f6,%f12,%f24
-/* 0x09cc 869 (29 34) */ fsubd %f18,%f28,%f26
-/* 0x09d0 870 (29 30) */ add %o5,%o4,%o4
-/* 0x09d4 871 (29 34) */ fmuld %f6,%f8,%f6
-/* 0x09d8 872 (30 35) */ fsubd %f18,%f10,%f10
-/* 0x09dc 873 (30 31) */ add %o4,%g2,%g2
-/* 0x09e0 874 (30 31) */ st %g2,[%i0]
-/* 0x09e4 875 (31 33) */ ldx [%sp+208],%o7
-/* 0x09e8 876 (31 32) */ srlx %g2,32,%o5
-/* 0x09ec 877 (31 36) */ fsubd %f18,%f20,%f18
-/* 0x09f0 878 (32 37) */ fdtox %f30,%f28
-/* 0x09f4 879 (32 33) */ std %f28,[%sp+192]
-/* 0x09f8 880 (32 37) */ fmuld %f16,%f12,%f14
-/* 0x09fc 881 (33 34) */ sllx %o7,19,%o4
-/* 0x0a00 882 (33 35) */ ldx [%sp+216],%o7
-/* 0x0a04 883 (33 38) */ fdtox %f22,%f20
-/* 0x0a08 884 (33 38) */ fmuld %f16,%f8,%f16
-/* 0x0a0c 885 (34 35) */ std %f20,[%sp+200]
-/* 0x0a10 886 (34 39) */ fdtox %f24,%f20
-/* 0x0a14 887 (34 39) */ fmuld %f26,%f12,%f22
-/* 0x0a18 888 (35 36) */ std %f20,[%sp+176]
-/* 0x0a1c 889 (35 36) */ add %o7,%o4,%o4
-/* 0x0a20 890 (35 40) */ fdtox %f6,%f6
-/* 0x0a24 891 (35 40) */ fmuld %f10,%f12,%f4
-/* 0x0a28 892 (36 38) */ ldx [%sp+192],%o3
-/* 0x0a2c 893 (36 37) */ add %o4,%g3,%g3
-/* 0x0a30 894 (36 41) */ fmuld %f10,%f8,%f10
-/* 0x0a34 895 (37 38) */ std %f6,[%sp+184]
-/* 0x0a38 896 (37 38) */ add %g3,%o5,%g3
-/* 0x0a3c 897 (37 42) */ fdtox %f14,%f6
-/* 0x0a40 898 (37 42) */ fmuld %f26,%f8,%f20
-/* 0x0a44 899 (38 40) */ ldx [%sp+200],%o4
-/* 0x0a48 900 (38 39) */ sllx %o3,19,%o3
-/* 0x0a4c 901 (38 39) */ srlx %g3,32,%o5
-/* 0x0a50 902 (38 43) */ fdtox %f16,%f14
-/* 0x0a54 903 (39 40) */ std %f6,[%sp+160]
-/* 0x0a58 904 (39 44) */ fmuld %f18,%f12,%f12
-/* 0x0a5c 905 (40 42) */ ldx [%sp+176],%o7
-/* 0x0a60 906 (40 41) */ add %o4,%o3,%o3
-/* 0x0a64 907 (40 45) */ fdtox %f4,%f16
-/* 0x0a68 908 (40 45) */ fmuld %f18,%f8,%f18
-/* 0x0a6c 909 (41 42) */ std %f14,[%sp+168]
-/* 0x0a70 910 (41 42) */ add %o3,%g4,%g4
-/* 0x0a74 911 (41 46) */ fdtox %f10,%f4
-/* 0x0a78 912 (42 44) */ ldx [%sp+184],%o3
-/* 0x0a7c 913 (42 43) */ sllx %o7,19,%o4
-/* 0x0a80 914 (42 43) */ add %g4,%o5,%g4
-/* 0x0a84 915 (42 47) */ fdtox %f22,%f14
-/* 0x0a88 916 (43 44) */ std %f16,[%sp+144]
-/* 0x0a8c 917 (43 44) */ srlx %g4,32,%o5
-/* 0x0a90 918 (43 48) */ fdtox %f20,%f6
-/* 0x0a94 919 (44 46) */ ldx [%sp+160],%o7
-/* 0x0a98 920 (44 45) */ add %o3,%o4,%o3
-/* 0x0a9c 921 (44 49) */ fdtox %f12,%f16
-/* 0x0aa0 922 (45 46) */ std %f4,[%sp+152]
-/* 0x0aa4 923 (45 46) */ add %o3,%g5,%g5
-/* 0x0aa8 924 (45 50) */ fdtox %f18,%f8
-/* 0x0aac 925 (46 48) */ ldx [%sp+168],%o3
-/* 0x0ab0 926 (46 47) */ sllx %o7,19,%o4
-/* 0x0ab4 927 (46 47) */ add %g5,%o5,%g5
-/* 0x0ab8 928 (47 48) */ std %f14,[%sp+128]
-/* 0x0abc 929 (47 48) */ srlx %g5,32,%o5
-/* 0x0ac0 930 (48 49) */ std %f6,[%sp+136]
-/* 0x0ac4 931 (48 49) */ add %o3,%o4,%o3
-/* 0x0ac8 932 (49 50) */ std %f16,[%sp+112]
-/* 0x0acc 933 (49 50) */ add %o3,%o0,%o0
-/* 0x0ad0 934 (50 52) */ ldx [%sp+144],%o7
-/* 0x0ad4 935 (50 51) */ add %o0,%o5,%o0
-/* 0x0ad8 936 (51 53) */ ldx [%sp+152],%o3
-/* 0x0adc 937 (52 53) */ std %f8,[%sp+120]
-/* 0x0ae0 938 (52 53) */ sllx %o7,19,%o4
-/* 0x0ae4 939 (52 53) */ srlx %o0,32,%o7
-/* 0x0ae8 940 (53 54) */ stx %o0,[%sp+104]
-/* 0x0aec 941 (53 54) */ add %o3,%o4,%o3
-/* 0x0af0 942 (54 56) */ ldx [%sp+128],%o5
-/* 0x0af4 943 (54 55) */ add %o3,%o1,%o1
-/* 0x0af8 944 (55 57) */ ldx [%sp+136],%o0
-/* 0x0afc 945 (55 56) */ add %o1,%o7,%o1
-/* 0x0b00 946 (56 57) */ st %g3,[%i0+4]
-/* 0x0b04 947 (56 57) */ sllx %o5,19,%o3
-/* 0x0b08 948 (57 59) */ ldx [%sp+112],%o4
-/* 0x0b0c 949 (57 58) */ add %o0,%o3,%o3
-/* 0x0b10 950 (58 60) */ ldx [%sp+120],%o0
-/* 0x0b14 951 (58 59) */ add %o3,%o2,%o2
-/* 0x0b18 952 (58 59) */ srlx %o1,32,%o3
-/* 0x0b1c 953 (59 60) */ st %o1,[%i0+20]
-/* 0x0b20 954 (59 60) */ sllx %o4,19,%g2
-/* 0x0b24 955 (59 60) */ add %o2,%o3,%o2
-/* 0x0b28 956 (60 62) */ ldx [%sp+96],%o4
-/* 0x0b2c 957 (60 61) */ srlx %o2,32,%g3
-/* 0x0b30 958 (60 61) */ add %o0,%g2,%g2
-/* 0x0b34 959 (61 63) */ ldx [%sp+104],%o0
-/* 0x0b38 960 (62 63) */ st %o2,[%i0+24]
-/* 0x0b3c 961 (62 63) */ add %g2,%o4,%g2
-/* 0x0b40 962 (63 64) */ st %o0,[%i0+16]
-/* 0x0b44 963 (63 64) */ add %g2,%g3,%g2
-/* 0x0b48 964 (64 65) */ st %g4,[%i0+8]
-/* 0x0b4c 968 (64 65) */ srlx %g2,32,%o7
-/* 0x0b50 969 (65 66) */ st %g5,[%i0+12]
-/* 0x0b54 970 (66 67) */ st %g2,[%i0+28]
-/* 0x0b58 971 (66 67) */ or %g0,%o7,%i0
-/* 0x0b5c (67 74) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x0b60 (69 71) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L77000050
-!
-
- .L77000050: /* frequency 1.0 confidence 0.0 */
-/* 0x0b64 978 ( 0 1) */ subcc %o2,16,%g0
-/* 0x0b68 979 ( 0 1) */ bne,pn %icc,.L77000073 ! tprob=0.50
-/* 0x0b6c ( 0 1) */ sethi %hi(0xfff80000),%g2
-/* 0x0b70 981 ( 1 5) */ ldd [%g5],%f4
-/* 0x0b74 982 ( 2 6) */ ldd [%g5+8],%f6
-/* 0x0b78 989 ( 2 3) */ andn %o1,%g2,%g2
-/* 0x0b7c 993 ( 2 3) */ srl %o1,19,%g3
-/* 0x0b80 994 ( 3 7) */ ldd [%g5+16],%f8
-/* 0x0b84 995 ( 4 8) */ fxnor %f0,%f4,%f4
-/* 0x0b88 996 ( 4 5) */ st %g2,[%sp+356]
-/* 0x0b8c 997 ( 5 9) */ ldd [%o0],%f20
-/* 0x0b90 998 ( 5 9) */ fxnor %f0,%f6,%f6
-/* 0x0b94 999 ( 6 7) */ st %g3,[%sp+352]
-/* 0x0b98 1000 ( 6 10) */ fxnor %f0,%f8,%f8
-/* 0x0b9c 1005 ( 7 11) */ ldd [%o0+8],%f30
-/* 0x0ba0 1006 ( 8 13) */ fitod %f4,%f22
-/* 0x0ba4 1007 ( 8 12) */ ldd [%g5+24],%f10
-/* 0x0ba8 1008 ( 9 12) */ fmovs %f20,%f24
-/* 0x0bac 1009 ( 9 13) */ ldd [%g5+32],%f12
-/* 0x0bb0 1010 (10 15) */ fitod %f5,%f4
-/* 0x0bb4 1011 (10 14) */ ldd [%g5+40],%f14
-/* 0x0bb8 1012 (11 14) */ fmovs %f20,%f26
-/* 0x0bbc 1013 (11 15) */ ldd [%g5+48],%f16
-/* 0x0bc0 1014 (12 14) */ ld [%sp+356],%f25
-/* 0x0bc4 1015 (12 17) */ fitod %f6,%f28
-/* 0x0bc8 1016 (13 15) */ ld [%sp+352],%f27
-/* 0x0bcc 1017 (13 18) */ fitod %f8,%f32
-/* 0x0bd0 1018 (14 19) */ fsubd %f30,%f22,%f22
-/* 0x0bd4 1019 (14 18) */ ldd [%g5+56],%f18
-/* 0x0bd8 1020 (15 20) */ fsubd %f24,%f20,%f24
-/* 0x0bdc 1021 (16 21) */ fsubd %f26,%f20,%f20
-/* 0x0be0 1022 (17 22) */ fsubd %f30,%f4,%f4
-/* 0x0be4 1023 (18 23) */ fsubd %f30,%f28,%f26
-/* 0x0be8 1024 (19 24) */ fitod %f7,%f6
-/* 0x0bec 1025 (20 25) */ fsubd %f30,%f32,%f28
-/* 0x0bf0 1026 (20 25) */ fmuld %f22,%f24,%f32
-/* 0x0bf4 1027 (21 26) */ fmuld %f22,%f20,%f22
-/* 0x0bf8 1028 (21 25) */ fxnor %f0,%f10,%f10
-/* 0x0bfc 1029 (22 27) */ fmuld %f4,%f24,%f44
-/* 0x0c00 1030 (22 27) */ fitod %f9,%f8
-/* 0x0c04 1031 (23 28) */ fmuld %f4,%f20,%f4
-/* 0x0c08 1032 (23 27) */ fxnor %f0,%f12,%f12
-/* 0x0c0c 1033 (24 29) */ fsubd %f30,%f6,%f6
-/* 0x0c10 1034 (24 29) */ fmuld %f26,%f24,%f46
-/* 0x0c14 1035 (25 30) */ fitod %f10,%f34
-/* 0x0c18 1036 (26 31) */ fdtox %f22,%f22
-/* 0x0c1c 1037 (26 27) */ std %f22,[%sp+336]
-/* 0x0c20 1038 (27 32) */ fmuld %f26,%f20,%f22
-/* 0x0c24 1039 (27 32) */ fdtox %f44,%f26
-/* 0x0c28 1040 (27 28) */ std %f26,[%sp+328]
-/* 0x0c2c 1041 (28 33) */ fdtox %f4,%f4
-/* 0x0c30 1042 (28 29) */ std %f4,[%sp+320]
-/* 0x0c34 1043 (29 34) */ fmuld %f6,%f24,%f26
-/* 0x0c38 1044 (29 34) */ fsubd %f30,%f8,%f8
-/* 0x0c3c 1045 (30 35) */ fdtox %f46,%f4
-/* 0x0c40 1046 (30 31) */ std %f4,[%sp+312]
-/* 0x0c44 1047 (31 36) */ fmuld %f28,%f24,%f4
-/* 0x0c48 1048 (31 36) */ fdtox %f32,%f32
-/* 0x0c4c 1049 (31 32) */ std %f32,[%sp+344]
-/* 0x0c50 1050 (32 37) */ fitod %f11,%f10
-/* 0x0c54 1051 (32 37) */ fmuld %f6,%f20,%f32
-/* 0x0c58 1052 (33 38) */ fsubd %f30,%f34,%f34
-/* 0x0c5c 1053 (34 39) */ fdtox %f22,%f6
-/* 0x0c60 1054 (34 35) */ std %f6,[%sp+304]
-/* 0x0c64 1058 (35 40) */ fitod %f12,%f36
-/* 0x0c68 1059 (35 40) */ fmuld %f28,%f20,%f6
-/* 0x0c6c 1060 (36 41) */ fdtox %f26,%f22
-/* 0x0c70 1061 (36 37) */ std %f22,[%sp+296]
-/* 0x0c74 1062 (37 42) */ fmuld %f8,%f24,%f22
-/* 0x0c78 1063 (37 42) */ fdtox %f4,%f4
-/* 0x0c7c 1064 (37 38) */ std %f4,[%sp+280]
-/* 0x0c80 1065 (38 43) */ fmuld %f8,%f20,%f8
-/* 0x0c84 1066 (38 43) */ fsubd %f30,%f10,%f10
-/* 0x0c88 1067 (39 44) */ fmuld %f34,%f24,%f4
-/* 0x0c8c 1068 (39 44) */ fitod %f13,%f12
-/* 0x0c90 1069 (40 45) */ fsubd %f30,%f36,%f36
-/* 0x0c94 1070 (41 46) */ fdtox %f6,%f6
-/* 0x0c98 1071 (41 42) */ std %f6,[%sp+272]
-/* 0x0c9c 1072 (42 46) */ fxnor %f0,%f14,%f14
-/* 0x0ca0 1073 (42 47) */ fmuld %f34,%f20,%f6
-/* 0x0ca4 1074 (43 48) */ fdtox %f22,%f22
-/* 0x0ca8 1075 (43 44) */ std %f22,[%sp+264]
-/* 0x0cac 1076 (44 49) */ fdtox %f8,%f8
-/* 0x0cb0 1077 (44 45) */ std %f8,[%sp+256]
-/* 0x0cb4 1078 (44 49) */ fmuld %f10,%f24,%f22
-/* 0x0cb8 1079 (45 50) */ fdtox %f4,%f4
-/* 0x0cbc 1080 (45 46) */ std %f4,[%sp+248]
-/* 0x0cc0 1081 (45 50) */ fmuld %f10,%f20,%f8
-/* 0x0cc4 1082 (46 51) */ fsubd %f30,%f12,%f4
-/* 0x0cc8 1083 (46 51) */ fmuld %f36,%f24,%f10
-/* 0x0ccc 1084 (47 52) */ fitod %f14,%f38
-/* 0x0cd0 1085 (48 53) */ fdtox %f6,%f6
-/* 0x0cd4 1086 (48 49) */ std %f6,[%sp+240]
-/* 0x0cd8 1087 (49 54) */ fdtox %f22,%f12
-/* 0x0cdc 1088 (49 50) */ std %f12,[%sp+232]
-/* 0x0ce0 1089 (49 54) */ fmuld %f36,%f20,%f6
-/* 0x0ce4 1090 (50 55) */ fdtox %f8,%f8
-/* 0x0ce8 1091 (50 51) */ std %f8,[%sp+224]
-/* 0x0cec 1092 (51 56) */ fdtox %f10,%f22
-/* 0x0cf0 1093 (51 52) */ std %f22,[%sp+216]
-/* 0x0cf4 1094 (51 56) */ fmuld %f4,%f24,%f8
-/* 0x0cf8 1095 (52 57) */ fitod %f15,%f14
-/* 0x0cfc 1096 (52 57) */ fmuld %f4,%f20,%f4
-/* 0x0d00 1097 (53 58) */ fsubd %f30,%f38,%f22
-/* 0x0d04 1098 (54 58) */ fxnor %f0,%f16,%f16
-/* 0x0d08 1099 (55 60) */ fdtox %f6,%f6
-/* 0x0d0c 1100 (55 56) */ std %f6,[%sp+208]
-/* 0x0d10 1101 (56 61) */ fdtox %f8,%f6
-/* 0x0d14 1102 (56 57) */ std %f6,[%sp+200]
-/* 0x0d18 1103 (57 62) */ fsubd %f30,%f14,%f10
-/* 0x0d1c 1104 (58 63) */ fitod %f16,%f40
-/* 0x0d20 1105 (58 63) */ fmuld %f22,%f24,%f6
-/* 0x0d24 1106 (59 64) */ fdtox %f4,%f4
-/* 0x0d28 1107 (59 60) */ std %f4,[%sp+192]
-/* 0x0d2c 1108 (60 65) */ fitod %f17,%f16
-/* 0x0d30 1109 (60 65) */ fmuld %f22,%f20,%f4
-/* 0x0d34 1110 (61 65) */ fxnor %f0,%f18,%f18
-/* 0x0d38 1111 (62 67) */ fdtox %f32,%f32
-/* 0x0d3c 1112 (62 63) */ std %f32,[%sp+288]
-/* 0x0d40 1113 (62 67) */ fmuld %f10,%f24,%f8
-/* 0x0d44 1114 (63 68) */ fdtox %f6,%f6
-/* 0x0d48 1115 (63 64) */ std %f6,[%sp+184]
-/* 0x0d4c 1116 (63 68) */ fmuld %f10,%f20,%f22
-/* 0x0d50 1117 (64 69) */ fsubd %f30,%f40,%f6
-/* 0x0d54 1118 (65 70) */ fdtox %f4,%f4
-/* 0x0d58 1119 (65 66) */ std %f4,[%sp+176]
-/* 0x0d5c 1120 (66 71) */ fsubd %f30,%f16,%f10
-/* 0x0d60 1121 (67 72) */ fdtox %f8,%f4
-/* 0x0d64 1122 (67 68) */ std %f4,[%sp+168]
-/* 0x0d68 1123 (68 73) */ fdtox %f22,%f4
-/* 0x0d6c 1124 (68 69) */ std %f4,[%sp+160]
-/* 0x0d70 1125 (69 74) */ fitod %f18,%f42
-/* 0x0d74 1126 (69 74) */ fmuld %f6,%f24,%f4
-/* 0x0d78 1127 (70 75) */ fmuld %f6,%f20,%f22
-/* 0x0d7c 1128 (71 76) */ fmuld %f10,%f24,%f6
-/* 0x0d80 1129 (72 77) */ fmuld %f10,%f20,%f8
-/* 0x0d84 1130 (74 79) */ fdtox %f4,%f4
-/* 0x0d88 1131 (74 75) */ std %f4,[%sp+152]
-/* 0x0d8c 1132 (75 80) */ fsubd %f30,%f42,%f4
-/* 0x0d90 1133 (76 81) */ fdtox %f6,%f6
-/* 0x0d94 1134 (76 77) */ std %f6,[%sp+136]
-/* 0x0d98 1135 (77 82) */ fdtox %f22,%f22
-/* 0x0d9c 1136 (77 78) */ std %f22,[%sp+144]
-/* 0x0da0 1137 (78 83) */ fdtox %f8,%f22
-/* 0x0da4 1138 (78 79) */ std %f22,[%sp+128]
-/* 0x0da8 1139 (79 84) */ fitod %f19,%f22
-/* 0x0dac 1140 (80 85) */ fmuld %f4,%f24,%f6
-/* 0x0db0 1141 (81 86) */ fmuld %f4,%f20,%f4
-/* 0x0db4 1142 (84 89) */ fsubd %f30,%f22,%f22
-/* 0x0db8 1143 (85 90) */ fdtox %f6,%f6
-/* 0x0dbc 1144 (85 86) */ std %f6,[%sp+120]
-/* 0x0dc0 1145 (86 91) */ fdtox %f4,%f4
-/* 0x0dc4 1146 (86 87) */ std %f4,[%sp+112]
-/* 0x0dc8 1150 (87 89) */ ldx [%sp+336],%g2
-/* 0x0dcc 1151 (88 90) */ ldx [%sp+344],%g3
-/* 0x0dd0 1152 (89 91) */ ld [%i1],%g4
-/* 0x0dd4 1153 (89 90) */ sllx %g2,19,%g2
-/* 0x0dd8 1154 (89 94) */ fmuld %f22,%f20,%f4
-/* 0x0ddc 1155 (90 92) */ ldx [%sp+328],%g5
-/* 0x0de0 1156 (90 91) */ add %g3,%g2,%g2
-/* 0x0de4 1157 (90 95) */ fmuld %f22,%f24,%f6
-/* 0x0de8 1158 (91 93) */ ldx [%sp+320],%g3
-/* 0x0dec 1159 (91 92) */ add %g2,%g4,%g4
-/* 0x0df0 1160 (92 94) */ ldx [%sp+304],%o0
-/* 0x0df4 1161 (93 94) */ st %g4,[%i0]
-/* 0x0df8 1162 (93 94) */ sllx %g3,19,%g2
-/* 0x0dfc 1163 (93 94) */ srlx %g4,32,%g4
-/* 0x0e00 1164 (94 96) */ ld [%i1+4],%g3
-/* 0x0e04 1165 (94 95) */ add %g5,%g2,%g2
-/* 0x0e08 1166 (94 99) */ fdtox %f4,%f4
-/* 0x0e0c 1167 (95 97) */ ldx [%sp+312],%g5
-/* 0x0e10 1168 (95 100) */ fdtox %f6,%f6
-/* 0x0e14 1169 (96 98) */ ldx [%sp+288],%o1
-/* 0x0e18 1170 (96 97) */ add %g2,%g3,%g2
-/* 0x0e1c 1171 (96 97) */ sllx %o0,19,%g3
-/* 0x0e20 1172 (97 99) */ ldx [%sp+272],%o2
-/* 0x0e24 1173 (97 98) */ add %g2,%g4,%g2
-/* 0x0e28 1174 (97 98) */ add %g5,%g3,%g3
-/* 0x0e2c 1175 (98 100) */ ld [%i1+8],%g4
-/* 0x0e30 1176 (98 99) */ srlx %g2,32,%o0
-/* 0x0e34 1177 (99 101) */ ldx [%sp+296],%g5
-/* 0x0e38 1178 (100 101) */ st %g2,[%i0+4]
-/* 0x0e3c 1179 (100 101) */ sllx %o2,19,%g2
-/* 0x0e40 1180 (100 101) */ add %g3,%g4,%g3
-/* 0x0e44 1181 (101 103) */ ldx [%sp+256],%o2
-/* 0x0e48 1182 (101 102) */ sllx %o1,19,%g4
-/* 0x0e4c 1183 (101 102) */ add %g3,%o0,%g3
-/* 0x0e50 1184 (102 104) */ ld [%i1+12],%o0
-/* 0x0e54 1185 (102 103) */ srlx %g3,32,%o1
-/* 0x0e58 1186 (102 103) */ add %g5,%g4,%g4
-/* 0x0e5c 1187 (103 105) */ ldx [%sp+280],%g5
-/* 0x0e60 1188 (104 105) */ st %g3,[%i0+8]
-/* 0x0e64 1189 (104 105) */ sllx %o2,19,%g3
-/* 0x0e68 1190 (104 105) */ add %g4,%o0,%g4
-/* 0x0e6c 1191 (105 107) */ ld [%i1+16],%o0
-/* 0x0e70 1192 (105 106) */ add %g5,%g2,%g2
-/* 0x0e74 1193 (105 106) */ add %g4,%o1,%g4
-/* 0x0e78 1194 (106 108) */ ldx [%sp+264],%g5
-/* 0x0e7c 1195 (106 107) */ srlx %g4,32,%o1
-/* 0x0e80 1196 (107 109) */ ldx [%sp+240],%o2
-/* 0x0e84 1197 (107 108) */ add %g2,%o0,%g2
-/* 0x0e88 1198 (108 110) */ ld [%i1+20],%o0
-/* 0x0e8c 1199 (108 109) */ add %g5,%g3,%g3
-/* 0x0e90 1200 (108 109) */ add %g2,%o1,%g2
-/* 0x0e94 1201 (109 111) */ ldx [%sp+248],%g5
-/* 0x0e98 1202 (109 110) */ srlx %g2,32,%o1
-/* 0x0e9c 1203 (110 111) */ st %g4,[%i0+12]
-/* 0x0ea0 1204 (110 111) */ sllx %o2,19,%g4
-/* 0x0ea4 1205 (110 111) */ add %g3,%o0,%g3
-/* 0x0ea8 1206 (111 113) */ ld [%i1+24],%o0
-/* 0x0eac 1207 (111 112) */ add %g5,%g4,%g4
-/* 0x0eb0 1208 (111 112) */ add %g3,%o1,%g3
-/* 0x0eb4 1209 (112 114) */ ldx [%sp+224],%o2
-/* 0x0eb8 1210 (112 113) */ srlx %g3,32,%o1
-/* 0x0ebc 1211 (113 115) */ ldx [%sp+232],%g5
-/* 0x0ec0 1212 (113 114) */ add %g4,%o0,%g4
-/* 0x0ec4 1213 (114 115) */ st %g2,[%i0+16]
-/* 0x0ec8 1214 (114 115) */ sllx %o2,19,%g2
-/* 0x0ecc 1215 (114 115) */ add %g4,%o1,%g4
-/* 0x0ed0 1216 (115 117) */ ld [%i1+28],%o0
-/* 0x0ed4 1217 (115 116) */ srlx %g4,32,%o1
-/* 0x0ed8 1218 (115 116) */ add %g5,%g2,%g2
-/* 0x0edc 1222 (116 118) */ ldx [%sp+208],%o2
-/* 0x0ee0 1223 (117 119) */ ldx [%sp+216],%g5
-/* 0x0ee4 1224 (117 118) */ add %g2,%o0,%g2
-/* 0x0ee8 1225 (118 119) */ st %g3,[%i0+20]
-/* 0x0eec 1226 (118 119) */ sllx %o2,19,%g3
-/* 0x0ef0 1227 (118 119) */ add %g2,%o1,%g2
-/* 0x0ef4 1228 (119 121) */ ld [%i1+32],%o0
-/* 0x0ef8 1229 (119 120) */ srlx %g2,32,%o1
-/* 0x0efc 1230 (119 120) */ add %g5,%g3,%g3
-/* 0x0f00 1231 (120 122) */ ldx [%sp+192],%o2
-/* 0x0f04 1232 (121 123) */ ldx [%sp+200],%g5
-/* 0x0f08 1233 (121 122) */ add %g3,%o0,%g3
-/* 0x0f0c 1234 (122 123) */ st %g4,[%i0+24]
-/* 0x0f10 1235 (122 123) */ sllx %o2,19,%g4
-/* 0x0f14 1236 (122 123) */ add %g3,%o1,%g3
-/* 0x0f18 1237 (123 125) */ ld [%i1+36],%o0
-/* 0x0f1c 1238 (123 124) */ srlx %g3,32,%o1
-/* 0x0f20 1239 (123 124) */ add %g5,%g4,%g4
-/* 0x0f24 1240 (124 126) */ ldx [%sp+176],%o2
-/* 0x0f28 1241 (125 127) */ ldx [%sp+184],%g5
-/* 0x0f2c 1242 (125 126) */ add %g4,%o0,%g4
-/* 0x0f30 1243 (126 127) */ st %g2,[%i0+28]
-/* 0x0f34 1244 (126 127) */ sllx %o2,19,%g2
-/* 0x0f38 1245 (126 127) */ add %g4,%o1,%g4
-/* 0x0f3c 1246 (127 129) */ ld [%i1+40],%o0
-/* 0x0f40 1247 (127 128) */ srlx %g4,32,%o1
-/* 0x0f44 1248 (127 128) */ add %g5,%g2,%g2
-/* 0x0f48 1249 (128 130) */ ldx [%sp+160],%o2
-/* 0x0f4c 1250 (129 131) */ ldx [%sp+168],%g5
-/* 0x0f50 1251 (129 130) */ add %g2,%o0,%g2
-/* 0x0f54 1252 (130 131) */ st %g3,[%i0+32]
-/* 0x0f58 1253 (130 131) */ sllx %o2,19,%g3
-/* 0x0f5c 1254 (130 131) */ add %g2,%o1,%g2
-/* 0x0f60 1255 (131 133) */ ld [%i1+44],%o0
-/* 0x0f64 1256 (131 132) */ srlx %g2,32,%o1
-/* 0x0f68 1257 (131 132) */ add %g5,%g3,%g3
-/* 0x0f6c 1258 (132 134) */ ldx [%sp+144],%o2
-/* 0x0f70 1259 (133 135) */ ldx [%sp+152],%g5
-/* 0x0f74 1260 (133 134) */ add %g3,%o0,%g3
-/* 0x0f78 1261 (134 135) */ st %g4,[%i0+36]
-/* 0x0f7c 1262 (134 135) */ sllx %o2,19,%g4
-/* 0x0f80 1263 (134 135) */ add %g3,%o1,%g3
-/* 0x0f84 1264 (135 137) */ ld [%i1+48],%o0
-/* 0x0f88 1265 (135 136) */ srlx %g3,32,%o1
-/* 0x0f8c 1266 (135 136) */ add %g5,%g4,%g4
-/* 0x0f90 1267 (136 138) */ ldx [%sp+128],%o2
-/* 0x0f94 1268 (137 139) */ ldx [%sp+136],%g5
-/* 0x0f98 1269 (137 138) */ add %g4,%o0,%g4
-/* 0x0f9c 1270 (138 139) */ std %f4,[%sp+96]
-/* 0x0fa0 1271 (138 139) */ add %g4,%o1,%g4
-/* 0x0fa4 1272 (139 140) */ st %g2,[%i0+40]
-/* 0x0fa8 1273 (139 140) */ sllx %o2,19,%g2
-/* 0x0fac 1274 (139 140) */ srlx %g4,32,%o1
-/* 0x0fb0 1275 (140 142) */ ld [%i1+52],%o0
-/* 0x0fb4 1276 (140 141) */ add %g5,%g2,%g2
-/* 0x0fb8 1277 (141 142) */ std %f6,[%sp+104]
-/* 0x0fbc 1278 (142 144) */ ldx [%sp+120],%g5
-/* 0x0fc0 1279 (142 143) */ add %g2,%o0,%g2
-/* 0x0fc4 1280 (143 144) */ st %g3,[%i0+44]
-/* 0x0fc8 1281 (143 144) */ add %g2,%o1,%g2
-/* 0x0fcc 1282 (144 146) */ ldx [%sp+112],%o2
-/* 0x0fd0 1283 (144 145) */ srlx %g2,32,%o1
-/* 0x0fd4 1284 (145 147) */ ld [%i1+56],%o0
-/* 0x0fd8 1285 (146 147) */ st %g4,[%i0+48]
-/* 0x0fdc 1286 (146 147) */ sllx %o2,19,%g3
-/* 0x0fe0 1287 (147 149) */ ldx [%sp+96],%o2
-/* 0x0fe4 1288 (147 148) */ add %g5,%g3,%g3
-/* 0x0fe8 1289 (148 150) */ ldx [%sp+104],%g5
-/* 0x0fec 1290 (148 149) */ add %g3,%o0,%g3
-/* 0x0ff0 1291 (149 151) */ ld [%i1+60],%o0
-/* 0x0ff4 1292 (149 150) */ sllx %o2,19,%g4
-/* 0x0ff8 1293 (149 150) */ add %g3,%o1,%g3
-/* 0x0ffc 1294 (150 151) */ st %g2,[%i0+52]
-/* 0x1000 1295 (150 151) */ srlx %g3,32,%o1
-/* 0x1004 1296 (150 151) */ add %g5,%g4,%g4
-/* 0x1008 1297 (151 152) */ st %g3,[%i0+56]
-/* 0x100c 1298 (151 152) */ add %g4,%o0,%g2
-/* 0x1010 1299 (152 153) */ add %g2,%o1,%g2
-/* 0x1014 1300 (152 153) */ st %g2,[%i0+60]
-/* 0x1018 1304 (153 154) */ srlx %g2,32,%o7
-
-!
-! ENTRY .L77000061
-!
-
- .L77000061: /* frequency 1.0 confidence 0.0 */
-/* 0x119c 1437 ( 0 1) */ or %g0,%o7,%i0
-
-!
-! ENTRY .L900000159
-!
-
- .L900000159: /* frequency 1.0 confidence 0.0 */
-/* 0x11a0 ( 0 7) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x11a4 ( 2 4) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L77000073
-!
-
- .L77000073: /* frequency 1.0 confidence 0.0 */
- or %g0, %i4, %o2
- or %g0, %o0, %o1
- or %g0, %i3, %o0
-
-!
-! ENTRY .L77000052
-!
-
- .L77000052: /* frequency 1.0 confidence 0.0 */
-/* 0x1028 1318 ( 0 1) */ andn %o2,%g2,%g2
-/* 0x102c 1319 ( 0 1) */ st %g2,[%sp+96]
-/* 0x1030 1325 ( 0 1) */ add %o0,1,%g3
-/* 0x1034 1326 ( 0 1) */ fmovd %f0,%f14
-/* 0x1038 1327 ( 1 2) */ srl %o2,19,%g2
-/* 0x103c 1328 ( 1 2) */ st %g2,[%sp+92]
-/* 0x1040 1329 ( 1 2) */ or %g0,0,%o5
-/* 0x1044 1330 ( 2 3) */ srl %g3,31,%g2
-/* 0x1048 1331 ( 2 5) */ ldd [%o1],%f6
-/* 0x104c 1335 ( 2 3) */ sethi %hi(0x1800),%g1
-/* 0x1050 1336 ( 3 4) */ add %g3,%g2,%g2
-/* 0x1054 1337 ( 3 4) */ xor %g1,-304,%g1
-/* 0x1058 1338 ( 3 6) */ ldd [%o1+8],%f20
-/* 0x105c 1339 ( 4 5) */ sra %g2,1,%o3
-/* 0x1060 1340 ( 4 5) */ fmovs %f6,%f8
-/* 0x1064 1341 ( 4 5) */ add %g1,%fp,%g3
-/* 0x1068 1342 ( 5 6) */ fmovs %f6,%f10
-/* 0x106c 1343 ( 5 7) */ ld [%sp+96],%f9
-/* 0x1070 1344 ( 5 6) */ subcc %o3,0,%g0
-/* 0x1074 1345 ( 6 8) */ ld [%sp+92],%f11
-/* 0x1078 1346 ( 6 7) */ sethi %hi(0x1800),%g1
-/* 0x107c 1347 ( 6 7) */ or %g0,%i2,%o1
-/* 0x1080 1348 ( 7 10) */ fsubd %f8,%f6,%f18
-/* 0x1084 1349 ( 7 8) */ xor %g1,-296,%g1
-/* 0x1088 1350 ( 7 8) */ or %g0,0,%g4
-/* 0x108c 1351 ( 8 11) */ fsubd %f10,%f6,%f16
-/* 0x1090 1352 ( 8 9) */ bleu,pt %icc,.L990000162 ! tprob=0.50
-/* 0x1094 ( 8 9) */ subcc %o0,0,%g0
-/* 0x1098 1354 ( 9 10) */ add %g1,%fp,%g2
-/* 0x109c 1355 ( 9 10) */ sethi %hi(0x1800),%g1
-/* 0x10a0 1356 (10 11) */ xor %g1,-288,%g1
-/* 0x10a4 1357 (10 11) */ subcc %o3,7,%g0
-/* 0x10a8 1358 (11 12) */ add %g1,%fp,%o7
-/* 0x10ac 1359 (11 12) */ sethi %hi(0x1800),%g1
-/* 0x10b0 1360 (12 13) */ xor %g1,-280,%g1
-/* 0x10b4 1361 (13 14) */ add %g1,%fp,%o4
-/* 0x10b8 1362 (13 14) */ bl,pn %icc,.L77000054 ! tprob=0.50
-/* 0x10bc (13 14) */ sub %o3,2,%o2
-/* 0x10c0 1364 (14 17) */ ldd [%o1],%f2
-/* 0x10c4 1365 (14 15) */ add %o1,16,%g5
-/* 0x10c8 1366 (14 15) */ or %g0,4,%g4
-/* 0x10cc 1367 (15 18) */ ldd [%o1+8],%f0
-/* 0x10d0 1368 (15 16) */ add %o1,8,%o1
-/* 0x10d4 1369 (16 18) */ fxnor %f14,%f2,%f6
-/* 0x10d8 1370 (16 19) */ ldd [%g5],%f4
-/* 0x10dc 1371 (16 17) */ add %o1,16,%o1
-/* 0x10e0 1372 (17 19) */ fxnor %f14,%f0,%f12
-/* 0x10e4 1373 (17 20) */ ldd [%o1],%f0
-/* 0x10e8 1374 (17 18) */ add %o1,8,%o1
-/* 0x10ec 1375 (18 21) */ fitod %f7,%f2
-/* 0x10f0 1376 (19 22) */ fitod %f6,%f6
-/* 0x10f4 1377 (20 22) */ fxnor %f14,%f4,%f10
-/* 0x10f8 1378 (21 24) */ fsubd %f20,%f2,%f2
-/* 0x10fc 1379 (22 24) */ fxnor %f14,%f0,%f8
-/* 0x1100 1380 (23 26) */ fitod %f13,%f4
-/* 0x1104 1381 (24 27) */ fsubd %f20,%f6,%f6
-/* 0x1108 1382 (24 27) */ fmuld %f2,%f16,%f0
-
-!
-! ENTRY .L990000154
-!
-
- .L990000154: /* frequency 1.0 confidence 0.0 */
-/* 0x110c 1384 ( 0 3) */ ldd [%o1],%f24
-/* 0x1110 1385 ( 0 1) */ add %g4,3,%g4
-/* 0x1114 1386 ( 0 1) */ add %o4,96,%o4
-/* 0x1118 1387 ( 1 4) */ fitod %f11,%f22
-/* 0x111c 1388 ( 2 5) */ fsubd %f20,%f4,%f26
-/* 0x1120 1389 ( 2 3) */ subcc %g4,%o2,%g0
-/* 0x1124 1390 ( 2 3) */ add %o7,96,%o7
-/* 0x1128 1391 ( 2 5) */ fmuld %f6,%f18,%f28
-/* 0x112c 1392 ( 3 6) */ fmuld %f6,%f16,%f6
-/* 0x1130 1393 ( 3 4) */ add %g2,96,%g2
-/* 0x1134 1394 ( 3 4) */ add %g3,96,%g3
-/* 0x1138 1395 ( 4 7) */ fdtox %f0,%f0
-/* 0x113c 1396 ( 5 8) */ fitod %f12,%f4
-/* 0x1140 1397 ( 5 8) */ fmuld %f2,%f18,%f2
-/* 0x1144 1398 ( 6 9) */ fdtox %f28,%f12
-/* 0x1148 1399 ( 7 10) */ fdtox %f6,%f6
-/* 0x114c 1400 ( 7 8) */ std %f12,[%g3-96]
-/* 0x1150 1401 ( 8 9) */ std %f6,[%g2-96]
-/* 0x1154 1402 ( 8 11) */ fdtox %f2,%f2
-/* 0x1158 1403 ( 9 12) */ fsubd %f20,%f4,%f6
-/* 0x115c 1404 ( 9 10) */ std %f2,[%o7-96]
-/* 0x1160 1405 ( 9 10) */ add %o1,8,%o1
-/* 0x1164 1406 (10 12) */ fxnor %f14,%f24,%f12
-/* 0x1168 1407 (10 13) */ fmuld %f26,%f16,%f4
-/* 0x116c 1408 (10 11) */ std %f0,[%o4-96]
-/* 0x1170 1409 (11 14) */ ldd [%o1],%f0
-/* 0x1174 1410 (11 14) */ fitod %f9,%f2
-/* 0x1178 1411 (12 15) */ fsubd %f20,%f22,%f28
-/* 0x117c 1412 (12 15) */ fmuld %f6,%f18,%f24
-/* 0x1180 1413 (13 16) */ fmuld %f6,%f16,%f22
-/* 0x1184 1414 (13 16) */ fdtox %f4,%f4
-/* 0x1188 1415 (14 17) */ fitod %f10,%f6
-/* 0x118c 1416 (14 17) */ fmuld %f26,%f18,%f10
-/* 0x1190 1417 (15 18) */ fdtox %f24,%f24
-/* 0x1194 1418 (16 19) */ fdtox %f22,%f22
-/* 0x1198 1419 (16 17) */ std %f24,[%g3-64]
-/* 0x119c 1420 (17 18) */ std %f22,[%g2-64]
-/* 0x11a0 1421 (17 20) */ fdtox %f10,%f10
-/* 0x11a4 1422 (18 21) */ fsubd %f20,%f6,%f6
-/* 0x11a8 1423 (18 19) */ std %f10,[%o7-64]
-/* 0x11ac 1424 (18 19) */ add %o1,8,%o1
-/* 0x11b0 1425 (19 21) */ fxnor %f14,%f0,%f10
-/* 0x11b4 1426 (19 22) */ fmuld %f28,%f16,%f0
-/* 0x11b8 1427 (19 20) */ std %f4,[%o4-64]
-/* 0x11bc 1428 (20 23) */ ldd [%o1],%f22
-/* 0x11c0 1429 (20 23) */ fitod %f13,%f4
-/* 0x11c4 1430 (21 24) */ fsubd %f20,%f2,%f2
-/* 0x11c8 1431 (21 24) */ fmuld %f6,%f18,%f26
-/* 0x11cc 1432 (22 25) */ fmuld %f6,%f16,%f24
-/* 0x11d0 1433 (22 25) */ fdtox %f0,%f0
-/* 0x11d4 1434 (23 26) */ fitod %f8,%f6
-/* 0x11d8 1435 (23 26) */ fmuld %f28,%f18,%f8
-/* 0x11dc 1436 (24 27) */ fdtox %f26,%f26
-/* 0x11e0 1437 (25 28) */ fdtox %f24,%f24
-/* 0x11e4 1438 (25 26) */ std %f26,[%g3-32]
-/* 0x11e8 1439 (26 27) */ std %f24,[%g2-32]
-/* 0x11ec 1440 (26 29) */ fdtox %f8,%f8
-/* 0x11f0 1441 (27 30) */ fsubd %f20,%f6,%f6
-/* 0x11f4 1442 (27 28) */ std %f8,[%o7-32]
-/* 0x11f8 1443 (27 28) */ add %o1,8,%o1
-/* 0x11fc 1444 (28 30) */ fxnor %f14,%f22,%f8
-/* 0x1200 1445 (28 29) */ std %f0,[%o4-32]
-/* 0x1204 1446 (28 29) */ bcs,pt %icc,.L990000154 ! tprob=0.50
-/* 0x1208 (28 31) */ fmuld %f2,%f16,%f0
-
-!
-! ENTRY .L990000157
-!
-
- .L990000157: /* frequency 1.0 confidence 0.0 */
-/* 0x120c 1449 ( 0 3) */ fitod %f12,%f28
-/* 0x1210 1450 ( 0 3) */ fmuld %f6,%f18,%f24
-/* 0x1214 1451 ( 0 1) */ add %g3,128,%g3
-/* 0x1218 1452 ( 1 4) */ fitod %f10,%f12
-/* 0x121c 1453 ( 1 4) */ fmuld %f6,%f16,%f26
-/* 0x1220 1454 ( 1 2) */ add %g2,128,%g2
-/* 0x1224 1455 ( 2 5) */ fsubd %f20,%f4,%f4
-/* 0x1228 1456 ( 2 5) */ fmuld %f2,%f18,%f22
-/* 0x122c 1457 ( 2 3) */ add %o7,128,%o7
-/* 0x1230 1458 ( 3 6) */ fdtox %f24,%f6
-/* 0x1234 1459 ( 3 4) */ std %f6,[%g3-128]
-/* 0x1238 1460 ( 3 4) */ add %o4,128,%o4
-/* 0x123c 1461 ( 4 7) */ fsubd %f20,%f28,%f2
-/* 0x1240 1462 ( 4 5) */ subcc %g4,%o3,%g0
-/* 0x1244 1463 ( 5 8) */ fitod %f11,%f6
-/* 0x1248 1464 ( 5 8) */ fmuld %f4,%f18,%f24
-/* 0x124c 1465 ( 6 9) */ fdtox %f26,%f10
-/* 0x1250 1466 ( 6 7) */ std %f10,[%g2-128]
-/* 0x1254 1467 ( 7 10) */ fdtox %f22,%f10
-/* 0x1258 1468 ( 7 8) */ std %f10,[%o7-128]
-/* 0x125c 1469 ( 7 10) */ fmuld %f2,%f18,%f26
-/* 0x1260 1470 ( 8 11) */ fsubd %f20,%f12,%f10
-/* 0x1264 1471 ( 8 11) */ fmuld %f2,%f16,%f2
-/* 0x1268 1472 ( 9 12) */ fsubd %f20,%f6,%f22
-/* 0x126c 1473 ( 9 12) */ fmuld %f4,%f16,%f12
-/* 0x1270 1474 (10 13) */ fdtox %f0,%f0
-/* 0x1274 1475 (10 11) */ std %f0,[%o4-128]
-/* 0x1278 1476 (11 14) */ fitod %f8,%f4
-/* 0x127c 1477 (11 14) */ fmuld %f10,%f18,%f6
-/* 0x1280 1478 (12 15) */ fdtox %f26,%f0
-/* 0x1284 1479 (12 13) */ std %f0,[%g3-96]
-/* 0x1288 1480 (12 15) */ fmuld %f10,%f16,%f10
-/* 0x128c 1481 (13 16) */ fdtox %f2,%f2
-/* 0x1290 1482 (13 14) */ std %f2,[%g2-96]
-/* 0x1294 1483 (14 17) */ fitod %f9,%f0
-/* 0x1298 1484 (14 17) */ fmuld %f22,%f18,%f2
-/* 0x129c 1485 (15 18) */ fdtox %f24,%f8
-/* 0x12a0 1486 (15 16) */ std %f8,[%o7-96]
-/* 0x12a4 1487 (16 19) */ fsubd %f20,%f4,%f4
-/* 0x12a8 1488 (16 19) */ fmuld %f22,%f16,%f8
-/* 0x12ac 1489 (17 20) */ fdtox %f12,%f12
-/* 0x12b0 1490 (17 18) */ std %f12,[%o4-96]
-/* 0x12b4 1491 (18 21) */ fsubd %f20,%f0,%f0
-/* 0x12b8 1492 (19 22) */ fdtox %f6,%f6
-/* 0x12bc 1493 (19 20) */ std %f6,[%g3-64]
-/* 0x12c0 1494 (20 23) */ fdtox %f10,%f10
-/* 0x12c4 1495 (20 21) */ std %f10,[%g2-64]
-/* 0x12c8 1496 (20 23) */ fmuld %f4,%f18,%f6
-/* 0x12cc 1497 (21 24) */ fdtox %f2,%f2
-/* 0x12d0 1498 (21 22) */ std %f2,[%o7-64]
-/* 0x12d4 1499 (21 24) */ fmuld %f4,%f16,%f4
-/* 0x12d8 1500 (22 25) */ fmuld %f0,%f18,%f2
-/* 0x12dc 1501 (22 25) */ fdtox %f8,%f8
-/* 0x12e0 1502 (22 23) */ std %f8,[%o4-64]
-/* 0x12e4 1503 (23 26) */ fdtox %f6,%f6
-/* 0x12e8 1504 (23 24) */ std %f6,[%g3-32]
-/* 0x12ec 1505 (23 26) */ fmuld %f0,%f16,%f0
-/* 0x12f0 1506 (24 27) */ fdtox %f4,%f4
-/* 0x12f4 1507 (24 25) */ std %f4,[%g2-32]
-/* 0x12f8 1508 (25 28) */ fdtox %f2,%f2
-/* 0x12fc 1509 (25 26) */ std %f2,[%o7-32]
-/* 0x1300 1510 (26 29) */ fdtox %f0,%f0
-/* 0x1304 1511 (26 27) */ bcc,pn %icc,.L77000056 ! tprob=0.50
-/* 0x1308 (26 27) */ std %f0,[%o4-32]
-
-!
-! ENTRY .L77000054
-!
-
- .L77000054: /* frequency 1.0 confidence 0.0 */
-/* 0x130c 1514 ( 0 3) */ ldd [%o1],%f0
-
-!
-! ENTRY .L990000161
-!
-
- .L990000161: /* frequency 1.0 confidence 0.0 */
-/* 0x1310 1516 ( 0 2) */ fxnor %f14,%f0,%f0
-/* 0x1314 1517 ( 0 1) */ add %g4,1,%g4
-/* 0x1318 1518 ( 0 1) */ add %o1,8,%o1
-/* 0x131c 1519 ( 1 2) */ subcc %g4,%o3,%g0
-/* 0x1320 1520 ( 2 5) */ fitod %f0,%f2
-/* 0x1324 1521 ( 3 6) */ fitod %f1,%f0
-/* 0x1328 1522 ( 5 8) */ fsubd %f20,%f2,%f2
-/* 0x132c 1523 ( 6 9) */ fsubd %f20,%f0,%f0
-/* 0x1330 1524 ( 8 11) */ fmuld %f2,%f18,%f6
-/* 0x1334 1525 ( 9 12) */ fmuld %f2,%f16,%f4
-/* 0x1338 1526 (10 13) */ fmuld %f0,%f18,%f2
-/* 0x133c 1527 (11 14) */ fdtox %f6,%f6
-/* 0x1340 1528 (11 12) */ std %f6,[%g3]
-/* 0x1344 1529 (11 14) */ fmuld %f0,%f16,%f0
-/* 0x1348 1530 (12 15) */ fdtox %f4,%f4
-/* 0x134c 1531 (12 13) */ std %f4,[%g2]
-/* 0x1350 1532 (12 13) */ add %g2,32,%g2
-/* 0x1354 1533 (13 16) */ fdtox %f2,%f2
-/* 0x1358 1534 (13 14) */ std %f2,[%o7]
-/* 0x135c 1535 (13 14) */ add %o7,32,%o7
-/* 0x1360 1536 (14 17) */ fdtox %f0,%f0
-/* 0x1364 1537 (14 15) */ std %f0,[%o4]
-/* 0x1368 1538 (14 15) */ add %o4,32,%o4
-/* 0x136c 1539 (15 16) */ add %g3,32,%g3
-/* 0x1370 1540 (15 16) */ bcs,a,pt %icc,.L990000161 ! tprob=0.50
-/* 0x1374 (16 19) */ ldd [%o1],%f0
-
-!
-! ENTRY .L77000056
-!
-
- .L77000056: /* frequency 1.0 confidence 0.0 */
-/* 0x1378 1548 ( 0 1) */ subcc %o0,0,%g0
-
-!
-! ENTRY .L990000162
-!
-
- .L990000162: /* frequency 1.0 confidence 0.0 */
-/* 0x137c 1550 ( 0 1) */ bleu,pt %icc,.L77770061 ! tprob=0.50
-/* 0x1380 ( 0 1) */ nop
-/* 0x1384 1555 ( 0 1) */ sethi %hi(0x1800),%g1
-/* 0x1388 1556 ( 1 2) */ xor %g1,-304,%g1
-/* 0x138c 1557 ( 1 2) */ or %g0,%i1,%g4
-/* 0x1390 1558 ( 2 3) */ add %g1,%fp,%g5
-/* 0x1394 1559 ( 2 3) */ sethi %hi(0x1800),%g1
-/* 0x1398 1560 ( 3 4) */ xor %g1,-296,%g1
-/* 0x139c 1561 ( 3 4) */ or %g0,%o0,%o7
-/* 0x13a0 1562 ( 4 5) */ add %g1,%fp,%g2
-/* 0x13a4 1563 ( 4 5) */ or %g0,0,%i2
-/* 0x13a8 1564 ( 5 6) */ or %g0,%i0,%g3
-/* 0x13ac 1565 ( 5 6) */ subcc %o0,6,%g0
-/* 0x13b0 1566 ( 5 6) */ bl,pn %icc,.L77000058 ! tprob=0.50
-/* 0x13b4 ( 6 7) */ sethi %hi(0x1800),%g1
-/* 0x13b8 1568 ( 6 8) */ ld [%g4],%o2
-/* 0x13bc 1569 ( 6 7) */ add %g3,4,%g3
-/* 0x13c0 1570 ( 7 8) */ xor %g1,-264,%g1
-/* 0x13c4 1571 ( 7 8) */ sub %o7,3,%o4
-/* 0x13c8 1572 ( 8 9) */ add %g1,%fp,%g2
-/* 0x13cc 1573 ( 8 9) */ sethi %hi(0x1800),%g1
-/* 0x13d0 1574 ( 9 10) */ xor %g1,-272,%g1
-/* 0x13d4 1575 ( 9 10) */ or %g0,2,%i2
-/* 0x13d8 1576 (10 11) */ add %g1,%fp,%g5
-/* 0x13dc 1577 (10 11) */ sethi %hi(0x1800),%g1
-/* 0x13e0 1578 (11 12) */ xor %g1,-296,%g1
-/* 0x13e4 1579 (12 13) */ add %g1,%fp,%g1
-/* 0x13e8 1580 (13 15) */ ldx [%g1],%o1
-/* 0x13ec 1581 (14 16) */ ldx [%g1-8],%o0
-/* 0x13f0 1582 (15 16) */ sllx %o1,19,%o1
-/* 0x13f4 1583 (15 17) */ ldx [%g1+16],%o3
-/* 0x13f8 1584 (16 17) */ add %o0,%o1,%o0
-/* 0x13fc 1585 (16 18) */ ld [%g4+4],%o1
-/* 0x1400 1586 (16 17) */ add %g4,8,%g4
-/* 0x1404 1587 (17 18) */ sllx %o3,19,%o3
-/* 0x1408 1588 (17 18) */ add %o0,%o2,%o0
-/* 0x140c 1589 (17 19) */ ldx [%g1+8],%o2
-/* 0x1410 1590 (18 19) */ st %o0,[%g3-4]
-/* 0x1414 1591 (18 19) */ srlx %o0,32,%o0
-
-!
-! ENTRY .L990000142
-!
-
- .L990000142: /* frequency 1.0 confidence 0.0 */
-/* 0x1418 1593 ( 0 1) */ add %o2,%o3,%o2
-/* 0x141c 1594 ( 0 1) */ add %i2,4,%i2
-/* 0x1420 1595 ( 0 2) */ ld [%g4],%o3
-/* 0x1424 1596 ( 1 2) */ srl %o0,0,%o5
-/* 0x1428 1597 ( 1 2) */ add %o2,%o1,%o1
-/* 0x142c 1598 ( 1 3) */ ldx [%g2],%o0
-/* 0x1430 1599 ( 3 4) */ sllx %o0,19,%o2
-/* 0x1434 1600 ( 3 5) */ ldx [%g5],%o0
-/* 0x1438 1601 ( 3 4) */ add %o1,%o5,%o1
-/* 0x143c 1602 ( 4 5) */ st %o1,[%g3]
-/* 0x1440 1603 ( 4 5) */ srlx %o1,32,%o5
-/* 0x1444 1604 ( 4 5) */ subcc %i2,%o4,%g0
-/* 0x1448 1605 ( 5 7) */ ldx [%g2+16],%o1
-/* 0x144c 1606 ( 5 6) */ add %o0,%o2,%o0
-/* 0x1450 1607 ( 5 6) */ add %g3,16,%g3
-/* 0x1454 1608 ( 6 8) */ ld [%g4+4],%o2
-/* 0x1458 1609 ( 6 7) */ add %o0,%o3,%o0
-/* 0x145c 1610 ( 7 8) */ sllx %o1,19,%o3
-/* 0x1460 1611 ( 7 9) */ ldx [%g5+16],%o1
-/* 0x1464 1612 ( 7 8) */ add %o0,%o5,%o0
-/* 0x1468 1613 ( 8 9) */ st %o0,[%g3-12]
-/* 0x146c 1614 ( 8 9) */ srlx %o0,32,%o5
-/* 0x1470 1615 ( 8 9) */ add %g4,16,%g4
-/* 0x1474 1616 ( 9 11) */ ldx [%g2+32],%o0
-/* 0x1478 1617 ( 9 10) */ add %o1,%o3,%o1
-/* 0x147c 1618 ( 9 10) */ add %g2,64,%g2
-/* 0x1480 1619 (10 12) */ ld [%g4-8],%o3
-/* 0x1484 1620 (10 11) */ add %o1,%o2,%o2
-/* 0x1488 1621 (11 12) */ sllx %o0,19,%o1
-/* 0x148c 1622 (11 13) */ ldx [%g5+32],%o0
-/* 0x1490 1623 (11 12) */ add %o2,%o5,%o2
-/* 0x1494 1624 (12 13) */ st %o2,[%g3-8]
-/* 0x1498 1625 (12 13) */ srlx %o2,32,%o5
-/* 0x149c 1626 (12 13) */ add %g5,64,%g5
-/* 0x14a0 1627 (13 15) */ ldx [%g2-16],%o2
-/* 0x14a4 1628 (13 14) */ add %o0,%o1,%o0
-/* 0x14a8 1629 (14 16) */ ld [%g4-4],%o1
-/* 0x14ac 1630 (14 15) */ add %o0,%o3,%o0
-/* 0x14b0 1631 (15 16) */ sllx %o2,19,%o3
-/* 0x14b4 1632 (15 17) */ ldx [%g5-16],%o2
-/* 0x14b8 1633 (15 16) */ add %o0,%o5,%o0
-/* 0x14bc 1634 (16 17) */ st %o0,[%g3-4]
-/* 0x14c0 1635 (16 17) */ bcs,pt %icc,.L990000142 ! tprob=0.50
-/* 0x14c4 (16 17) */ srlx %o0,32,%o0
-
-!
-! ENTRY .L990000145
-!
-
- .L990000145: /* frequency 1.0 confidence 0.0 */
-/* 0x14c8 1638 ( 0 1) */ add %o2,%o3,%o3
-/* 0x14cc 1639 ( 0 1) */ add %g3,4,%g3
-/* 0x14d0 1640 ( 1 2) */ srl %o0,0,%o2
-/* 0x14d4 1641 ( 1 2) */ add %o3,%o1,%o0
-/* 0x14d8 1642 ( 2 3) */ add %o0,%o2,%o0
-/* 0x14dc 1643 ( 2 3) */ st %o0,[%g3-4]
-/* 0x14e0 1644 ( 2 3) */ subcc %i2,%o7,%g0
-/* 0x14e4 1645 ( 2 3) */ bcc,pn %icc,.L77770061 ! tprob=0.50
-/* 0x14e8 ( 3 4) */ srlx %o0,32,%o5
-
-!
-! ENTRY .L77000058
-!
-
- .L77000058: /* frequency 1.0 confidence 0.0 */
-/* 0x14ec 1648 ( 0 2) */ ldx [%g2],%o2
-
-!
-! ENTRY .L990000160
-!
-
- .L990000160: /* frequency 1.0 confidence 0.0 */
-/* 0x14f0 1650 ( 0 1) */ sllx %o2,19,%o3
-/* 0x14f4 1651 ( 0 2) */ ldx [%g5],%o0
-/* 0x14f8 1652 ( 0 1) */ add %i2,1,%i2
-/* 0x14fc 1653 ( 1 2) */ srl %o5,0,%o1
-/* 0x1500 1654 ( 1 3) */ ld [%g4],%o2
-/* 0x1504 1655 ( 1 2) */ add %g2,16,%g2
-/* 0x1508 1656 ( 2 3) */ add %o0,%o3,%o0
-/* 0x150c 1657 ( 2 3) */ add %g5,16,%g5
-/* 0x1510 1658 ( 3 4) */ add %o0,%o2,%o0
-/* 0x1514 1659 ( 3 4) */ add %g4,4,%g4
-/* 0x1518 1660 ( 4 5) */ add %o0,%o1,%o0
-/* 0x151c 1661 ( 4 5) */ st %o0,[%g3]
-/* 0x1520 1662 ( 4 5) */ subcc %i2,%o7,%g0
-/* 0x1524 1663 ( 5 6) */ srlx %o0,32,%o5
-/* 0x1528 1664 ( 5 6) */ add %g3,4,%g3
-/* 0x152c 1665 ( 5 6) */ bcs,a,pt %icc,.L990000160 ! tprob=0.50
-/* 0x1530 ( 6 8) */ ldx [%g2],%o2
-
-!
-! ENTRY .L77770061
-!
-
- .L77770061: /* frequency 1.0 confidence 0.0 */
-/* 0x1534 ( 0 2) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x1538 ( 2 3) */ restore %g0,%o5,%o0
-
-/* 0x11a8 1441 ( 0 0) */ .type mul_add,2
-/* 0x11a8 1442 ( 0 0) */ .size mul_add,(.-mul_add)
-/* 0x11a8 1445 ( 0 0) */ .align 16
-/* 0x11b0 1451 ( 0 0) */ .global mul_add_inp
-
-!
-! ENTRY mul_add_inp
-!
-
- .global mul_add_inp
- mul_add_inp: /* frequency 1.0 confidence 0.0 */
-/* 0x11b0 1453 ( 0 1) */ or %g0,%o2,%g1
-/* 0x11b4 1454 ( 0 1) */ or %g0,%o3,%o4
-/* 0x11b8 1455 ( 1 2) */ or %g0,%o0,%g3
-/* 0x11bc 1456 ( 1 2) */ or %g0,%o1,%g2
-/* 0x11c0 1466 ( 2 3) */ or %g0,%g1,%o3
-/* 0x11c4 1467 ( 2 3) */ or %g0,%g3,%o1
-/* 0x11c8 1468 ( 3 4) */ or %g0,%g2,%o2
-/* 0x11cc 1469 ( 3 4) */ or %g0,%o7,%g1
-/* 0x11d0 1470 ( 4 6) */ call mul_add ! params = ! Result =
-/* 0x11d4 ( 5 6) */ or %g0,%g1,%o7
-/* 0x11d8 1472 ( 0 0) */ .type mul_add_inp,2
-/* 0x11d8 1473 ( 0 0) */ .size mul_add_inp,(.-mul_add_inp)
-
- .section ".data",#alloc,#write
-/* 0x11d8 6 ( 0 0) */ .align 8
-
-!
-! ENTRY mask_cnst
-!
-
- mask_cnst: /* frequency 1.0 confidence 0.0 */
-/* 0x11d8 8 ( 0 0) */ .word -2147483648
-/* 0x11dc 9 ( 0 0) */ .word -2147483648
-/* 0x11e0 10 ( 0 0) */ .type mask_cnst,#object
-/* 0x11e0 11 ( 0 0) */ .size mask_cnst,8
-
diff --git a/security/nss/lib/freebl/mpi/mpv_sparcv9.s b/security/nss/lib/freebl/mpi/mpv_sparcv9.s
deleted file mode 100644
index 927214da0..000000000
--- a/security/nss/lib/freebl/mpi/mpv_sparcv9.s
+++ /dev/null
@@ -1,1648 +0,0 @@
-!
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-! $Id$
-!
-
- .section ".text",#alloc,#execinstr
-/* 000000 0 ( 0 0) */ .register %g2,#scratch
-/* 000000 ( 0 0) */ .register %g3,#scratch
-/* 000000 3 ( 0 0) */ .file "mpv_sparc.c"
-/* 000000 15 ( 0 0) */ .align 8
-!
-! SUBROUTINE .L_const_seg_900000101
-!
-! OFFSET SOURCE LINE LABEL INSTRUCTION (ISSUE TIME) (COMPLETION TIME)
-
- .L_const_seg_900000101: /* frequency 1.0 confidence 0.0 */
-/* 000000 20 ( 0 0) */ .word 1127219200,0
-/* 0x0008 21 ( 0 0) */ .word 1105199103,-4194304
-/* 0x0010 22 ( 0 0) */ .align 8
-/* 0x0010 28 ( 0 0) */ .global mul_add
-
-!
-! ENTRY mul_add
-!
-
- .global mul_add
- mul_add: /* frequency 1.0 confidence 0.0 */
-/* 0x0010 30 ( 0 1) */ sethi %hi(0x1c00),%g1
-/* 0x0014 31 ( 0 1) */ sethi %hi(mask_cnst),%g2
-/* 0x0018 32 ( 1 2) */ xor %g1,-48,%g1
-/* 0x001c 33 ( 1 2) */ add %g2,%lo(mask_cnst),%g2
-/* 0x0020 34 ( 2 3) */ save %sp,%g1,%sp
-
-!
-! ENTRY .L900000149
-!
-
- .L900000149: /* frequency 1.0 confidence 0.0 */
-/* 0x0024 36 ( 0 2) */ call (.+0x8) ! params = ! Result =
-/* 0x0028 ( 1 2) */ sethi %hi((_GLOBAL_OFFSET_TABLE_-(.L900000149-.))),%g5
-/* 0x002c 178 ( 2 3) */ sethi %hi(.L_const_seg_900000101),%g3
-/* 0x0030 179 ( 2 3) */ add %g5,%lo((_GLOBAL_OFFSET_TABLE_-(.L900000149-.))),%g5
-/* 0x0034 180 ( 3 4) */ add %g3,%lo(.L_const_seg_900000101),%g3
-/* 0x0038 181 ( 3 4) */ add %g5,%o7,%o1
-/* 0x003c 182 ( 4 5) */ sethi %hi(0x80000),%g4
-/* 0x0040 183 ( 4 6) */ ldx [%o1+%g2],%g2
-/* 0x0044 184 ( 4 5) */ or %g0,%i2,%o2
-/* 0x0048 185 ( 5 6) */ subcc %i4,%g4,%g0
-/* 0x004c 186 ( 5 7) */ ldx [%o1+%g3],%o0
-/* 0x0050 187 ( 6 7) */ or %g0,%i0,%o7
-/* 0x0054 188 ( 6 7) */ or %g0,%i1,%o5
-/* 0x0058 189 ( 6 9) */ ldd [%g2],%f0
-/* 0x005c 190 ( 6 7) */ bcc,pn %icc,.L77000048 ! tprob=0.50
-/* 0x0060 ( 7 8) */ subcc %i3,8,%g0
-/* 0x0064 192 ( 7 8) */ bne,pn %icc,.L900000158 ! tprob=0.50
-/* 0x0068 ( 8 9) */ subcc %i3,16,%g0
-/* 0x006c 194 ( 9 12) */ ldd [%o2],%f4
-/* 0x0070 195 (10 11) */ st %i4,[%sp+2287]
-/* 0x0074 196 (11 14) */ ldd [%o0],%f8
-/* 0x0078 197 (11 13) */ fxnor %f0,%f4,%f4
-/* 0x007c 198 (12 15) */ ldd [%o2+8],%f10
-/* 0x0080 199 (13 16) */ fitod %f4,%f12
-/* 0x0084 200 (13 16) */ ldd [%o0+8],%f14
-/* 0x0088 201 (14 17) */ ld [%sp+2287],%f7
-/* 0x008c 202 (14 17) */ fitod %f5,%f4
-/* 0x0090 203 (15 17) */ fxnor %f0,%f10,%f10
-/* 0x0094 204 (15 18) */ ldd [%o2+16],%f16
-/* 0x0098 205 (16 19) */ ldd [%o2+24],%f18
-/* 0x009c 206 (17 20) */ fsubd %f14,%f4,%f4
-/* 0x00a0 210 (17 20) */ ld [%i1],%g2
-/* 0x00a4 211 (18 20) */ fxnor %f0,%f16,%f16
-/* 0x00a8 212 (18 21) */ ld [%i1+4],%g3
-/* 0x00ac 213 (19 22) */ ld [%i1+8],%g4
-/* 0x00b0 214 (20 23) */ fitod %f16,%f20
-/* 0x00b4 215 (20 23) */ ld [%i1+16],%o0
-/* 0x00b8 216 (21 24) */ ld [%i1+12],%g5
-/* 0x00bc 217 (22 25) */ ld [%i1+20],%o1
-/* 0x00c0 218 (23 26) */ ld [%i1+24],%o2
-/* 0x00c4 219 (24 25) */ fmovs %f8,%f6
-/* 0x00c8 220 (24 27) */ ld [%i1+28],%o3
-/* 0x00cc 221 (26 29) */ fsubd %f6,%f8,%f6
-/* 0x00d0 222 (27 30) */ fsubd %f14,%f12,%f8
-/* 0x00d4 223 (28 31) */ fitod %f10,%f12
-/* 0x00d8 224 (29 32) */ fmuld %f4,%f6,%f4
-/* 0x00dc 225 (29 32) */ fitod %f11,%f10
-/* 0x00e0 226 (30 33) */ fmuld %f8,%f6,%f8
-/* 0x00e4 227 (31 34) */ fsubd %f14,%f12,%f12
-/* 0x00e8 228 (32 35) */ fdtox %f4,%f4
-/* 0x00ec 229 (32 33) */ std %f4,[%sp+2271]
-/* 0x00f0 230 (33 36) */ fdtox %f8,%f8
-/* 0x00f4 231 (33 34) */ std %f8,[%sp+2279]
-/* 0x00f8 232 (34 37) */ fmuld %f12,%f6,%f12
-/* 0x00fc 233 (34 37) */ fsubd %f14,%f10,%f10
-/* 0x0100 234 (35 38) */ fsubd %f14,%f20,%f4
-/* 0x0104 235 (36 39) */ fitod %f17,%f8
-/* 0x0108 236 (37 39) */ fxnor %f0,%f18,%f16
-/* 0x010c 237 (37 39) */ ldx [%sp+2279],%o4
-/* 0x0110 238 (37 40) */ fmuld %f10,%f6,%f10
-/* 0x0114 239 (38 41) */ fdtox %f12,%f12
-/* 0x0118 240 (38 39) */ std %f12,[%sp+2263]
-/* 0x011c 241 (38 41) */ fmuld %f4,%f6,%f4
-/* 0x0120 242 (39 42) */ fitod %f16,%f18
-/* 0x0124 243 (39 40) */ add %o4,%g2,%g2
-/* 0x0128 244 (39 40) */ st %g2,[%i0]
-/* 0x012c 245 (40 42) */ ldx [%sp+2271],%o4
-/* 0x0130 246 (40 43) */ fsubd %f14,%f8,%f8
-/* 0x0134 247 (40 41) */ srax %g2,32,%o5
-/* 0x0138 248 (41 44) */ fdtox %f10,%f10
-/* 0x013c 249 (41 42) */ std %f10,[%sp+2255]
-/* 0x0140 250 (42 45) */ fdtox %f4,%f4
-/* 0x0144 251 (42 43) */ std %f4,[%sp+2247]
-/* 0x0148 252 (42 43) */ add %o4,%g3,%o4
-/* 0x014c 253 (43 46) */ fitod %f17,%f12
-/* 0x0150 254 (43 45) */ ldx [%sp+2263],%g2
-/* 0x0154 255 (43 44) */ add %o4,%o5,%g3
-/* 0x0158 256 (43 46) */ fmuld %f8,%f6,%f8
-/* 0x015c 257 (44 47) */ fsubd %f14,%f18,%f10
-/* 0x0160 258 (44 45) */ st %g3,[%i0+4]
-/* 0x0164 259 (44 45) */ srax %g3,32,%g3
-/* 0x0168 260 (45 46) */ add %g2,%g4,%g4
-/* 0x016c 261 (45 47) */ ldx [%sp+2255],%g2
-/* 0x0170 262 (46 49) */ fsubd %f14,%f12,%f4
-/* 0x0174 263 (46 47) */ add %g4,%g3,%g3
-/* 0x0178 264 (46 48) */ ldx [%sp+2247],%g4
-/* 0x017c 265 (47 50) */ fmuld %f10,%f6,%f10
-/* 0x0180 266 (47 50) */ fdtox %f8,%f8
-/* 0x0184 267 (47 48) */ std %f8,[%sp+2239]
-/* 0x0188 268 (48 49) */ add %g4,%o0,%g4
-/* 0x018c 269 (48 49) */ add %g2,%g5,%g2
-/* 0x0190 270 (48 49) */ st %g3,[%i0+8]
-/* 0x0194 271 (49 52) */ fmuld %f4,%f6,%f4
-/* 0x0198 272 (49 50) */ srax %g3,32,%o0
-/* 0x019c 273 (49 51) */ ldx [%sp+2239],%g5
-/* 0x01a0 274 (50 53) */ fdtox %f10,%f6
-/* 0x01a4 275 (50 51) */ std %f6,[%sp+2231]
-/* 0x01a8 276 (50 51) */ add %g2,%o0,%g2
-/* 0x01ac 277 (51 52) */ srax %g2,32,%g3
-/* 0x01b0 278 (51 52) */ add %g5,%o1,%o1
-/* 0x01b4 279 (51 52) */ st %g2,[%i0+12]
-/* 0x01b8 280 (52 55) */ fdtox %f4,%f4
-/* 0x01bc 281 (52 53) */ std %f4,[%sp+2223]
-/* 0x01c0 282 (52 53) */ add %g4,%g3,%g3
-/* 0x01c4 283 (53 54) */ srax %g3,32,%g4
-/* 0x01c8 284 (53 54) */ st %g3,[%i0+16]
-/* 0x01cc 285 (54 56) */ ldx [%sp+2231],%o0
-/* 0x01d0 286 (54 55) */ add %o1,%g4,%g4
-/* 0x01d4 287 (55 56) */ srax %g4,32,%g2
-/* 0x01d8 288 (55 57) */ ldx [%sp+2223],%g5
-/* 0x01dc 289 (56 57) */ add %o0,%o2,%o2
-/* 0x01e0 290 (56 57) */ st %g4,[%i0+20]
-/* 0x01e4 291 (57 58) */ add %o2,%g2,%g2
-/* 0x01e8 292 (57 58) */ add %g5,%o3,%g5
-/* 0x01ec 293 (57 58) */ st %g2,[%i0+24]
-/* 0x01f0 294 (58 59) */ srax %g2,32,%g3
-/* 0x01f4 295 (59 60) */ add %g5,%g3,%g2
-/* 0x01f8 296 (59 60) */ st %g2,[%i0+28]
-/* 0x01fc 300 (60 61) */ srax %g2,32,%o3
-/* 0x0200 301 (61 62) */ srl %o3,0,%i0
-/* 0x0204 (62 64) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x0208 (64 65) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L900000158
-!
-
- .L900000158: /* frequency 1.0 confidence 0.0 */
-/* 0x020c 308 ( 0 1) */ bne,a,pn %icc,.L900000157 ! tprob=0.50
-/* 0x0210 ( 0 1) */ st %i4,[%sp+2223]
-/* 0x0214 315 ( 1 4) */ ldd [%o2],%f4
-/* 0x0218 316 ( 2 3) */ st %i4,[%sp+2351]
-/* 0x021c 317 ( 3 6) */ ldd [%o0],%f8
-/* 0x0220 318 ( 3 5) */ fxnor %f0,%f4,%f4
-/* 0x0224 319 ( 4 7) */ ldd [%o2+8],%f10
-/* 0x0228 320 ( 5 8) */ ldd [%o0+8],%f14
-/* 0x022c 321 ( 5 8) */ fitod %f4,%f12
-/* 0x0230 322 ( 6 9) */ ld [%sp+2351],%f7
-/* 0x0234 323 ( 6 8) */ fxnor %f0,%f10,%f10
-/* 0x0238 324 ( 7 10) */ ldd [%o2+16],%f16
-/* 0x023c 325 ( 7 10) */ fitod %f5,%f4
-/* 0x0240 326 ( 8 11) */ ldd [%o2+24],%f18
-/* 0x0244 330 ( 9 12) */ ldd [%o2+32],%f20
-/* 0x0248 331 ( 9 11) */ fxnor %f0,%f16,%f16
-/* 0x024c 335 (10 13) */ ld [%i1],%g2
-/* 0x0250 336 (10 13) */ fsubd %f14,%f4,%f4
-/* 0x0254 337 (11 14) */ ldd [%o2+40],%f22
-/* 0x0258 338 (11 14) */ fitod %f16,%f28
-/* 0x025c 339 (12 15) */ ld [%i1+4],%g3
-/* 0x0260 340 (13 16) */ ld [%i1+8],%g4
-/* 0x0264 341 (13 15) */ fxnor %f0,%f22,%f22
-/* 0x0268 342 (14 17) */ ld [%i1+12],%g5
-/* 0x026c 343 (15 18) */ ld [%i1+16],%o0
-/* 0x0270 344 (16 19) */ ldd [%o2+48],%f24
-/* 0x0274 345 (17 20) */ ld [%i1+20],%o1
-/* 0x0278 346 (17 18) */ fmovs %f8,%f6
-/* 0x027c 347 (18 21) */ ldd [%o2+56],%f26
-/* 0x0280 348 (19 22) */ ld [%i1+24],%o2
-/* 0x0284 349 (19 22) */ fsubd %f6,%f8,%f6
-/* 0x0288 350 (20 23) */ ld [%i1+28],%o3
-/* 0x028c 351 (20 23) */ fsubd %f14,%f12,%f8
-/* 0x0290 355 (21 24) */ ld [%i1+32],%o4
-/* 0x0294 356 (21 24) */ fitod %f10,%f12
-/* 0x0298 357 (22 25) */ ld [%i1+36],%o7
-/* 0x029c 358 (22 25) */ fitod %f11,%f10
-/* 0x02a0 359 (22 25) */ fmuld %f4,%f6,%f4
-/* 0x02a4 360 (23 26) */ ld [%i1+40],%l1
-/* 0x02a8 361 (23 26) */ fmuld %f8,%f6,%f8
-/* 0x02ac 362 (24 27) */ ld [%i1+56],%l5
-/* 0x02b0 363 (24 27) */ fsubd %f14,%f12,%f12
-/* 0x02b4 364 (25 28) */ fsubd %f14,%f10,%f10
-/* 0x02b8 365 (26 29) */ fdtox %f8,%f8
-/* 0x02bc 366 (26 27) */ std %f8,[%sp+2343]
-/* 0x02c0 367 (27 30) */ fitod %f17,%f8
-/* 0x02c4 368 (27 30) */ fmuld %f12,%f6,%f12
-/* 0x02c8 369 (28 31) */ fdtox %f4,%f4
-/* 0x02cc 370 (28 29) */ std %f4,[%sp+2335]
-/* 0x02d0 371 (28 31) */ fmuld %f10,%f6,%f10
-/* 0x02d4 372 (29 31) */ fxnor %f0,%f18,%f16
-/* 0x02d8 373 (30 33) */ fdtox %f12,%f12
-/* 0x02dc 374 (30 31) */ std %f12,[%sp+2327]
-/* 0x02e0 375 (31 33) */ ldx [%sp+2343],%o5
-/* 0x02e4 376 (31 34) */ fsubd %f14,%f8,%f8
-/* 0x02e8 377 (32 35) */ fsubd %f14,%f28,%f4
-/* 0x02ec 378 (33 36) */ fitod %f17,%f12
-/* 0x02f0 379 (33 34) */ add %o5,%g2,%g2
-/* 0x02f4 380 (33 34) */ st %g2,[%i0]
-/* 0x02f8 381 (34 36) */ ldx [%sp+2335],%o5
-/* 0x02fc 382 (34 37) */ fitod %f16,%f18
-/* 0x0300 383 (34 35) */ srax %g2,32,%l0
-/* 0x0304 384 (35 37) */ fxnor %f0,%f20,%f16
-/* 0x0308 385 (35 38) */ fmuld %f8,%f6,%f20
-/* 0x030c 386 (36 39) */ fdtox %f10,%f10
-/* 0x0310 387 (36 37) */ std %f10,[%sp+2319]
-/* 0x0314 388 (36 37) */ add %o5,%g3,%g3
-/* 0x0318 389 (36 39) */ fmuld %f4,%f6,%f4
-/* 0x031c 390 (37 40) */ fitod %f16,%f8
-/* 0x0320 391 (37 38) */ add %g3,%l0,%g3
-/* 0x0324 392 (37 38) */ st %g3,[%i0+4]
-/* 0x0328 393 (38 40) */ ldx [%sp+2327],%o5
-/* 0x032c 394 (38 41) */ fsubd %f14,%f18,%f18
-/* 0x0330 395 (38 39) */ srax %g3,32,%l3
-/* 0x0334 396 (39 41) */ ldx [%sp+2319],%l2
-/* 0x0338 397 (39 42) */ fdtox %f4,%f4
-/* 0x033c 398 (40 41) */ std %f4,[%sp+2311]
-/* 0x0340 399 (40 43) */ fdtox %f20,%f20
-/* 0x0344 400 (40 41) */ add %o5,%g4,%g4
-/* 0x0348 401 (41 42) */ std %f20,[%sp+2303]
-/* 0x034c 402 (41 44) */ fsubd %f14,%f12,%f4
-/* 0x0350 403 (41 42) */ add %g4,%l3,%g4
-/* 0x0354 404 (41 44) */ fmuld %f18,%f6,%f18
-/* 0x0358 405 (42 43) */ st %g4,[%i0+8]
-/* 0x035c 406 (42 45) */ fitod %f17,%f16
-/* 0x0360 407 (42 43) */ srax %g4,32,%l4
-/* 0x0364 408 (43 46) */ ld [%i1+44],%l0
-/* 0x0368 409 (43 46) */ fsubd %f14,%f8,%f20
-/* 0x036c 410 (43 44) */ add %l2,%g5,%l2
-/* 0x0370 411 (44 46) */ ldx [%sp+2311],%g5
-/* 0x0374 412 (44 47) */ fitod %f22,%f8
-/* 0x0378 413 (44 45) */ add %l2,%l4,%l2
-/* 0x037c 414 (44 47) */ fmuld %f4,%f6,%f4
-/* 0x0380 415 (45 46) */ st %l2,[%i0+12]
-/* 0x0384 416 (45 48) */ fsubd %f14,%f16,%f10
-/* 0x0388 417 (46 49) */ ld [%i1+52],%l3
-/* 0x038c 418 (46 49) */ fdtox %f18,%f18
-/* 0x0390 419 (46 47) */ add %g5,%o0,%l4
-/* 0x0394 420 (46 49) */ fmuld %f20,%f6,%f12
-/* 0x0398 421 (47 48) */ std %f18,[%sp+2295]
-/* 0x039c 422 (47 48) */ srax %l2,32,%o0
-/* 0x03a0 423 (47 50) */ fitod %f23,%f16
-/* 0x03a4 424 (48 51) */ ld [%i1+48],%o5
-/* 0x03a8 425 (48 51) */ fsubd %f14,%f8,%f8
-/* 0x03ac 426 (48 49) */ add %l4,%o0,%l4
-/* 0x03b0 427 (49 50) */ st %l4,[%i0+16]
-/* 0x03b4 428 (49 50) */ srax %l4,32,%o0
-/* 0x03b8 429 (49 51) */ fxnor %f0,%f24,%f18
-/* 0x03bc 430 (50 52) */ ldx [%sp+2303],%g5
-/* 0x03c0 431 (50 53) */ fdtox %f4,%f4
-/* 0x03c4 432 (51 52) */ std %f4,[%sp+2287]
-/* 0x03c8 433 (51 54) */ fdtox %f12,%f12
-/* 0x03cc 434 (51 54) */ fmuld %f10,%f6,%f4
-/* 0x03d0 435 (52 53) */ std %f12,[%sp+2279]
-/* 0x03d4 436 (52 55) */ fsubd %f14,%f16,%f12
-/* 0x03d8 437 (52 53) */ add %g5,%o1,%g2
-/* 0x03dc 438 (52 55) */ fmuld %f8,%f6,%f8
-/* 0x03e0 439 (53 55) */ ldx [%sp+2295],%g5
-/* 0x03e4 440 (53 56) */ fitod %f18,%f10
-/* 0x03e8 441 (53 54) */ add %g2,%o0,%g2
-/* 0x03ec 442 (54 55) */ st %g2,[%i0+20]
-/* 0x03f0 443 (54 57) */ fitod %f19,%f16
-/* 0x03f4 444 (54 55) */ srax %g2,32,%o0
-/* 0x03f8 445 (55 58) */ fdtox %f8,%f8
-/* 0x03fc 446 (55 56) */ std %f8,[%sp+2263]
-/* 0x0400 447 (55 56) */ add %g5,%o2,%g3
-/* 0x0404 448 (56 58) */ ldx [%sp+2287],%g5
-/* 0x0408 449 (56 59) */ fsubd %f14,%f10,%f10
-/* 0x040c 450 (56 57) */ add %g3,%o0,%g3
-/* 0x0410 451 (57 58) */ st %g3,[%i0+24]
-/* 0x0414 452 (57 60) */ fsubd %f14,%f16,%f8
-/* 0x0418 453 (57 58) */ srax %g3,32,%o0
-/* 0x041c 454 (58 61) */ fdtox %f4,%f4
-/* 0x0420 455 (58 59) */ std %f4,[%sp+2271]
-/* 0x0424 456 (58 59) */ add %g5,%o3,%g4
-/* 0x0428 457 (59 61) */ fxnor %f0,%f26,%f18
-/* 0x042c 458 (59 62) */ fmuld %f12,%f6,%f4
-/* 0x0430 459 (59 60) */ add %g4,%o0,%g4
-/* 0x0434 460 (60 61) */ st %g4,[%i0+28]
-/* 0x0438 461 (60 63) */ fmuld %f10,%f6,%f10
-/* 0x043c 462 (60 61) */ srax %g4,32,%o0
-/* 0x0440 463 (61 63) */ ldx [%sp+2279],%g5
-/* 0x0444 464 (61 64) */ fitod %f18,%f12
-/* 0x0448 465 (61 64) */ fmuld %f8,%f6,%f8
-/* 0x044c 466 (62 65) */ fdtox %f4,%f4
-/* 0x0450 467 (62 63) */ std %f4,[%sp+2255]
-/* 0x0454 468 (63 64) */ add %g5,%o4,%l2
-/* 0x0458 469 (63 65) */ ldx [%sp+2271],%g5
-/* 0x045c 470 (63 66) */ fdtox %f10,%f16
-/* 0x0460 471 (64 67) */ fsubd %f14,%f12,%f4
-/* 0x0464 472 (64 65) */ std %f16,[%sp+2247]
-/* 0x0468 473 (64 65) */ add %l2,%o0,%l2
-/* 0x046c 474 (65 68) */ fdtox %f8,%f8
-/* 0x0470 475 (65 66) */ std %f8,[%sp+2239]
-/* 0x0474 476 (65 66) */ add %g5,%o7,%l4
-/* 0x0478 477 (66 69) */ fitod %f19,%f10
-/* 0x047c 478 (66 68) */ ldx [%sp+2263],%g5
-/* 0x0480 479 (66 67) */ srax %l2,32,%o0
-/* 0x0484 480 (67 68) */ add %l4,%o0,%l4
-/* 0x0488 481 (67 70) */ fmuld %f4,%f6,%f4
-/* 0x048c 482 (67 69) */ ldx [%sp+2255],%o0
-/* 0x0490 483 (68 69) */ srax %l4,32,%o1
-/* 0x0494 484 (68 69) */ add %g5,%l1,%l1
-/* 0x0498 485 (68 69) */ st %l2,[%i0+32]
-/* 0x049c 486 (69 72) */ fsubd %f14,%f10,%f8
-/* 0x04a0 487 (69 71) */ ldx [%sp+2239],%o3
-/* 0x04a4 488 (69 70) */ add %l1,%o1,%o1
-/* 0x04a8 489 (70 72) */ ldx [%sp+2247],%g5
-/* 0x04ac 490 (70 71) */ srax %o1,32,%o2
-/* 0x04b0 491 (70 71) */ add %o0,%l0,%o0
-/* 0x04b4 492 (71 74) */ fdtox %f4,%f4
-/* 0x04b8 493 (71 72) */ std %f4,[%sp+2231]
-/* 0x04bc 494 (71 72) */ add %o0,%o2,%o2
-/* 0x04c0 495 (72 73) */ add %o3,%l3,%l3
-/* 0x04c4 496 (72 75) */ fmuld %f8,%f6,%f4
-/* 0x04c8 497 (72 73) */ add %g5,%o5,%g5
-/* 0x04cc 498 (73 74) */ srax %o2,32,%o3
-/* 0x04d0 499 (73 74) */ st %l4,[%i0+36]
-/* 0x04d4 500 (74 75) */ add %g5,%o3,%g2
-/* 0x04d8 501 (74 76) */ ldx [%sp+2231],%o0
-/* 0x04dc 502 (75 76) */ srax %g2,32,%g3
-/* 0x04e0 503 (75 78) */ fdtox %f4,%f4
-/* 0x04e4 504 (75 76) */ std %f4,[%sp+2223]
-/* 0x04e8 505 (76 77) */ st %o1,[%i0+40]
-/* 0x04ec 506 (76 77) */ add %l3,%g3,%g3
-/* 0x04f0 507 (76 77) */ add %o0,%l5,%g5
-/* 0x04f4 508 (77 78) */ st %o2,[%i0+44]
-/* 0x04f8 509 (77 78) */ srax %g3,32,%g4
-/* 0x04fc 510 (78 79) */ st %g2,[%i0+48]
-/* 0x0500 511 (78 79) */ add %g5,%g4,%g4
-/* 0x0504 512 (79 80) */ st %g3,[%i0+52]
-/* 0x0508 513 (79 80) */ srax %g4,32,%g5
-/* 0x050c 514 (80 83) */ ld [%i1+60],%g3
-/* 0x0510 515 (81 83) */ ldx [%sp+2223],%g2
-/* 0x0514 516 (82 83) */ st %g4,[%i0+56]
-/* 0x0518 517 (83 84) */ add %g2,%g3,%g2
-/* 0x051c 518 (84 85) */ add %g2,%g5,%g2
-/* 0x0520 519 (84 85) */ st %g2,[%i0+60]
-/* 0x0524 523 (85 86) */ srax %g2,32,%o3
-/* 0x0528 524 (86 87) */ srl %o3,0,%i0
-/* 0x052c (87 89) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x0530 (89 90) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L900000157
-!
-
- .L900000157: /* frequency 1.0 confidence 0.0 */
-/* 0x0534 532 ( 0 1) */ fmovd %f0,%f14
-/* 0x0538 533 ( 0 3) */ ldd [%o0],%f8
-/* 0x053c 539 ( 0 1) */ add %i3,1,%g2
-/* 0x0540 540 ( 1 4) */ ld [%sp+2223],%f7
-/* 0x0544 541 ( 1 2) */ srl %g2,31,%g3
-/* 0x0548 545 ( 1 2) */ add %fp,-217,%g4
-/* 0x054c 546 ( 2 3) */ add %g2,%g3,%g2
-/* 0x0550 547 ( 2 3) */ or %g0,0,%g5
-/* 0x0554 548 ( 2 5) */ ldd [%o0+8],%f18
-/* 0x0558 549 ( 3 4) */ fmovs %f8,%f6
-/* 0x055c 550 ( 3 4) */ sra %g2,1,%o1
-/* 0x0560 551 ( 3 4) */ or %g0,0,%o0
-/* 0x0564 552 ( 4 5) */ subcc %o1,0,%g0
-/* 0x0568 553 ( 5 6) */ or %g0,%o1,%o3
-/* 0x056c 554 ( 5 8) */ fsubd %f6,%f8,%f16
-/* 0x0570 555 ( 5 6) */ ble,pt %icc,.L900000156 ! tprob=0.50
-/* 0x0574 ( 6 7) */ subcc %i3,0,%g0
-/* 0x0578 557 ( 6 7) */ sub %o1,1,%g2
-/* 0x057c 558 ( 7 8) */ or %g0,0,%i0
-/* 0x0580 559 ( 7 8) */ or %g0,1,%g3
-/* 0x0584 560 ( 8 9) */ subcc %o3,10,%g0
-/* 0x0588 561 ( 8 9) */ bl,pn %icc,.L77000077 ! tprob=0.50
-/* 0x058c ( 9 10) */ or %g0,0,%o1
-/* 0x0590 563 ( 9 12) */ ldd [%i2+8],%f0
-/* 0x0594 564 ( 9 10) */ sub %o3,3,%o3
-/* 0x0598 565 (10 13) */ ldd [%i2],%f2
-/* 0x059c 566 (10 11) */ or %g0,7,%o0
-/* 0x05a0 567 (10 11) */ or %g0,2,%i0
-/* 0x05a4 568 (11 13) */ fxnor %f14,%f0,%f8
-/* 0x05a8 569 (11 14) */ ldd [%i2+16],%f4
-/* 0x05ac 570 (11 12) */ or %g0,16,%o2
-/* 0x05b0 571 (12 14) */ fxnor %f14,%f2,%f2
-/* 0x05b4 572 (12 15) */ ldd [%i2+24],%f6
-/* 0x05b8 573 (12 13) */ or %g0,48,%o4
-/* 0x05bc 574 (13 16) */ fitod %f8,%f12
-/* 0x05c0 575 (13 14) */ or %g0,24,%o1
-/* 0x05c4 576 (13 14) */ or %g0,3,%g3
-/* 0x05c8 577 (14 17) */ fitod %f2,%f0
-/* 0x05cc 578 (15 18) */ fitod %f3,%f20
-/* 0x05d0 579 (15 18) */ ldd [%i2+32],%f2
-/* 0x05d4 580 (16 19) */ fitod %f9,%f10
-/* 0x05d8 581 (16 19) */ ldd [%i2+40],%f8
-/* 0x05dc 582 (17 20) */ fsubd %f18,%f0,%f0
-/* 0x05e0 583 (18 21) */ fsubd %f18,%f20,%f22
-/* 0x05e4 584 (19 22) */ fsubd %f18,%f12,%f20
-/* 0x05e8 585 (19 22) */ ldd [%i2+48],%f12
-/* 0x05ec 586 (20 23) */ fsubd %f18,%f10,%f10
-/* 0x05f0 587 (20 23) */ fmuld %f0,%f16,%f0
-/* 0x05f4 588 (21 23) */ fxnor %f14,%f4,%f4
-/* 0x05f8 589 (21 24) */ fmuld %f22,%f16,%f22
-/* 0x05fc 590 (22 24) */ fxnor %f14,%f6,%f6
-/* 0x0600 591 (22 25) */ fmuld %f20,%f16,%f20
-/* 0x0604 592 (23 26) */ fdtox %f0,%f0
-/* 0x0608 593 (23 24) */ std %f0,[%fp-217]
-/* 0x060c 594 (23 26) */ fmuld %f10,%f16,%f10
-/* 0x0610 595 (24 27) */ fdtox %f22,%f22
-/* 0x0614 596 (24 25) */ std %f22,[%fp-209]
-/* 0x0618 597 (25 28) */ fitod %f5,%f0
-/* 0x061c 598 (26 29) */ fdtox %f10,%f10
-/* 0x0620 599 (27 30) */ fdtox %f20,%f20
-/* 0x0624 600 (27 28) */ std %f20,[%fp-201]
-/* 0x0628 601 (28 31) */ fitod %f4,%f4
-/* 0x062c 602 (28 29) */ std %f10,[%fp-193]
-/* 0x0630 603 (29 31) */ fxnor %f14,%f2,%f10
-/* 0x0634 604 (30 33) */ fitod %f7,%f2
-/* 0x0638 605 (31 34) */ fsubd %f18,%f0,%f0
-/* 0x063c 606 (32 35) */ fsubd %f18,%f4,%f4
-/* 0x0640 607 (33 35) */ fxnor %f14,%f8,%f8
-
-!
-! ENTRY .L900000144
-!
-
- .L900000144: /* frequency 1.0 confidence 0.0 */
-/* 0x0644 609 ( 0 3) */ fitod %f11,%f22
-/* 0x0648 610 ( 0 1) */ add %o0,3,%o0
-/* 0x064c 611 ( 0 1) */ add %g3,6,%g3
-/* 0x0650 612 ( 0 3) */ fmuld %f0,%f16,%f0
-/* 0x0654 613 ( 1 4) */ fmuld %f4,%f16,%f24
-/* 0x0658 614 ( 1 2) */ subcc %o0,%o3,%g0
-/* 0x065c 615 ( 1 2) */ add %i0,6,%i0
-/* 0x0660 616 ( 1 4) */ fsubd %f18,%f2,%f2
-/* 0x0664 617 ( 2 5) */ fitod %f6,%f4
-/* 0x0668 618 ( 3 6) */ fdtox %f0,%f0
-/* 0x066c 619 ( 3 4) */ add %o4,8,%i1
-/* 0x0670 620 ( 4 7) */ ldd [%i2+%i1],%f20
-/* 0x0674 621 ( 4 7) */ fdtox %f24,%f6
-/* 0x0678 622 ( 4 5) */ add %o2,16,%o4
-/* 0x067c 623 ( 5 8) */ fsubd %f18,%f4,%f4
-/* 0x0680 624 ( 5 6) */ std %f6,[%o4+%g4]
-/* 0x0684 625 ( 5 6) */ add %o1,16,%o2
-/* 0x0688 626 ( 6 8) */ fxnor %f14,%f12,%f6
-/* 0x068c 627 ( 6 7) */ std %f0,[%o2+%g4]
-/* 0x0690 628 ( 7 10) */ fitod %f9,%f0
-/* 0x0694 629 ( 7 10) */ fmuld %f2,%f16,%f2
-/* 0x0698 630 ( 8 11) */ fmuld %f4,%f16,%f24
-/* 0x069c 631 ( 8 11) */ fsubd %f18,%f22,%f12
-/* 0x06a0 632 ( 9 12) */ fitod %f10,%f4
-/* 0x06a4 633 (10 13) */ fdtox %f2,%f2
-/* 0x06a8 634 (10 11) */ add %i1,8,%o1
-/* 0x06ac 635 (11 14) */ ldd [%i2+%o1],%f22
-/* 0x06b0 636 (11 14) */ fdtox %f24,%f10
-/* 0x06b4 637 (11 12) */ add %o4,16,%i4
-/* 0x06b8 638 (12 15) */ fsubd %f18,%f4,%f4
-/* 0x06bc 639 (12 13) */ std %f10,[%i4+%g4]
-/* 0x06c0 640 (12 13) */ add %o2,16,%i1
-/* 0x06c4 641 (13 15) */ fxnor %f14,%f20,%f10
-/* 0x06c8 642 (13 14) */ std %f2,[%i1+%g4]
-/* 0x06cc 643 (14 17) */ fitod %f7,%f2
-/* 0x06d0 644 (14 17) */ fmuld %f12,%f16,%f12
-/* 0x06d4 645 (15 18) */ fmuld %f4,%f16,%f24
-/* 0x06d8 646 (15 18) */ fsubd %f18,%f0,%f0
-/* 0x06dc 647 (16 19) */ fitod %f8,%f4
-/* 0x06e0 648 (17 20) */ fdtox %f12,%f20
-/* 0x06e4 649 (17 18) */ add %o1,8,%o4
-/* 0x06e8 650 (18 21) */ ldd [%i2+%o4],%f12
-/* 0x06ec 651 (18 21) */ fdtox %f24,%f8
-/* 0x06f0 652 (18 19) */ add %i4,16,%o2
-/* 0x06f4 653 (19 22) */ fsubd %f18,%f4,%f4
-/* 0x06f8 654 (19 20) */ std %f8,[%o2+%g4]
-/* 0x06fc 655 (19 20) */ add %i1,16,%o1
-/* 0x0700 656 (20 22) */ fxnor %f14,%f22,%f8
-/* 0x0704 657 (20 21) */ ble,pt %icc,.L900000144 ! tprob=0.50
-/* 0x0708 (20 21) */ std %f20,[%o1+%g4]
-
-!
-! ENTRY .L900000147
-!
-
- .L900000147: /* frequency 1.0 confidence 0.0 */
-/* 0x070c 660 ( 0 3) */ fitod %f6,%f6
-/* 0x0710 661 ( 0 3) */ fmuld %f4,%f16,%f24
-/* 0x0714 662 ( 0 1) */ add %i4,32,%l4
-/* 0x0718 663 ( 1 4) */ fsubd %f18,%f2,%f2
-/* 0x071c 664 ( 1 4) */ fmuld %f0,%f16,%f22
-/* 0x0720 665 ( 1 2) */ add %i1,32,%l3
-/* 0x0724 666 ( 2 5) */ fitod %f10,%f28
-/* 0x0728 667 ( 2 3) */ sra %o0,0,%o2
-/* 0x072c 668 ( 2 3) */ add %i4,48,%l2
-/* 0x0730 669 ( 3 6) */ fsubd %f18,%f6,%f4
-/* 0x0734 670 ( 3 4) */ add %i1,48,%l1
-/* 0x0738 671 ( 3 4) */ add %i4,64,%l0
-/* 0x073c 672 ( 4 7) */ fitod %f11,%f26
-/* 0x0740 673 ( 4 5) */ sllx %o2,3,%o1
-/* 0x0744 674 ( 4 5) */ add %i1,64,%i5
-/* 0x0748 675 ( 5 8) */ fitod %f8,%f6
-/* 0x074c 676 ( 5 6) */ add %i4,80,%i4
-/* 0x0750 677 ( 5 6) */ add %i1,80,%i1
-/* 0x0754 678 ( 6 8) */ fxnor %f14,%f12,%f0
-/* 0x0758 679 ( 6 9) */ fmuld %f4,%f16,%f20
-/* 0x075c 680 ( 6 7) */ add %i4,16,%o4
-/* 0x0760 681 ( 7 10) */ fitod %f9,%f4
-/* 0x0764 682 ( 7 10) */ fmuld %f2,%f16,%f12
-/* 0x0768 683 ( 7 8) */ add %i1,16,%o3
-/* 0x076c 684 ( 8 11) */ fsubd %f18,%f28,%f10
-/* 0x0770 685 ( 8 9) */ subcc %o0,%g2,%g0
-/* 0x0774 686 ( 8 9) */ add %g3,12,%g3
-/* 0x0778 687 ( 9 12) */ fitod %f0,%f2
-/* 0x077c 688 (10 13) */ fsubd %f18,%f26,%f8
-/* 0x0780 689 (11 14) */ fitod %f1,%f0
-/* 0x0784 690 (11 14) */ fmuld %f10,%f16,%f10
-/* 0x0788 691 (12 15) */ fdtox %f24,%f24
-/* 0x078c 692 (12 13) */ std %f24,[%l4+%g4]
-/* 0x0790 693 (12 13) */ add %i0,12,%i0
-/* 0x0794 694 (13 16) */ fsubd %f18,%f6,%f6
-/* 0x0798 695 (13 16) */ fmuld %f8,%f16,%f8
-/* 0x079c 696 (14 17) */ fdtox %f22,%f22
-/* 0x07a0 697 (14 15) */ std %f22,[%l3+%g4]
-/* 0x07a4 698 (15 18) */ fsubd %f18,%f4,%f4
-/* 0x07a8 699 (16 19) */ fdtox %f20,%f20
-/* 0x07ac 700 (16 17) */ std %f20,[%l2+%g4]
-/* 0x07b0 701 (16 19) */ fmuld %f6,%f16,%f6
-/* 0x07b4 702 (17 20) */ fsubd %f18,%f2,%f2
-/* 0x07b8 703 (18 21) */ fsubd %f18,%f0,%f0
-/* 0x07bc 704 (18 21) */ fmuld %f4,%f16,%f4
-/* 0x07c0 705 (19 22) */ fdtox %f12,%f12
-/* 0x07c4 706 (19 20) */ std %f12,[%l1+%g4]
-/* 0x07c8 707 (20 23) */ fdtox %f10,%f10
-/* 0x07cc 708 (20 21) */ std %f10,[%l0+%g4]
-/* 0x07d0 709 (20 23) */ fmuld %f2,%f16,%f2
-/* 0x07d4 710 (21 24) */ fdtox %f8,%f8
-/* 0x07d8 711 (21 22) */ std %f8,[%i5+%g4]
-/* 0x07dc 712 (21 24) */ fmuld %f0,%f16,%f0
-/* 0x07e0 713 (22 25) */ fdtox %f6,%f6
-/* 0x07e4 714 (22 23) */ std %f6,[%i4+%g4]
-/* 0x07e8 715 (23 26) */ fdtox %f4,%f4
-/* 0x07ec 716 (23 24) */ std %f4,[%i1+%g4]
-/* 0x07f0 717 (24 27) */ fdtox %f2,%f2
-/* 0x07f4 718 (24 25) */ std %f2,[%o4+%g4]
-/* 0x07f8 719 (25 28) */ fdtox %f0,%f0
-/* 0x07fc 720 (25 26) */ bg,pn %icc,.L77000043 ! tprob=0.50
-/* 0x0800 (25 26) */ std %f0,[%o3+%g4]
-
-!
-! ENTRY .L77000077
-!
-
- .L77000077: /* frequency 1.0 confidence 0.0 */
-/* 0x0804 723 ( 0 3) */ ldd [%i2+%o1],%f0
-
-!
-! ENTRY .L900000155
-!
-
- .L900000155: /* frequency 1.0 confidence 0.0 */
-/* 0x0808 725 ( 0 2) */ fxnor %f14,%f0,%f0
-/* 0x080c 726 ( 0 1) */ sra %i0,0,%o1
-/* 0x0810 727 ( 0 1) */ add %o0,1,%o0
-/* 0x0814 728 ( 1 2) */ sllx %o1,3,%i4
-/* 0x0818 729 ( 1 2) */ add %i0,2,%i0
-/* 0x081c 730 ( 2 5) */ fitod %f0,%f2
-/* 0x0820 731 ( 2 3) */ sra %g3,0,%o1
-/* 0x0824 732 ( 2 3) */ add %g3,2,%g3
-/* 0x0828 733 ( 3 6) */ fitod %f1,%f0
-/* 0x082c 734 ( 3 4) */ sllx %o1,3,%i1
-/* 0x0830 735 ( 3 4) */ subcc %o0,%g2,%g0
-/* 0x0834 736 ( 4 5) */ sra %o0,0,%o2
-/* 0x0838 737 ( 5 8) */ fsubd %f18,%f2,%f2
-/* 0x083c 738 ( 5 6) */ sllx %o2,3,%o1
-/* 0x0840 739 ( 6 9) */ fsubd %f18,%f0,%f0
-/* 0x0844 740 ( 8 11) */ fmuld %f2,%f16,%f2
-/* 0x0848 741 ( 9 12) */ fmuld %f0,%f16,%f0
-/* 0x084c 742 (11 14) */ fdtox %f2,%f2
-/* 0x0850 743 (11 12) */ std %f2,[%i4+%g4]
-/* 0x0854 744 (12 15) */ fdtox %f0,%f0
-/* 0x0858 745 (12 13) */ std %f0,[%i1+%g4]
-/* 0x085c 746 (12 13) */ ble,a,pt %icc,.L900000155 ! tprob=0.50
-/* 0x0860 (14 17) */ ldd [%i2+%o1],%f0
-
-!
-! ENTRY .L77000043
-!
-
- .L77000043: /* frequency 1.0 confidence 0.0 */
-/* 0x0864 754 ( 0 1) */ subcc %i3,0,%g0
-
-!
-! ENTRY .L900000156
-!
-
- .L900000156: /* frequency 1.0 confidence 0.0 */
-/* 0x0868 756 ( 0 1) */ ble,a,pt %icc,.L77000061 ! tprob=0.50
-/* 0x086c ( 0 1) */ or %g0,%g5,%o3
-/* 0x0870 761 ( 0 2) */ ldx [%fp-209],%i1
-/* 0x0874 762 ( 1 2) */ sub %i3,1,%g3
-/* 0x0878 763 ( 1 2) */ or %g0,0,%i0
-/* 0x087c 764 ( 2 3) */ subcc %i3,5,%g0
-/* 0x0880 765 ( 2 3) */ bl,pn %icc,.L77000078 ! tprob=0.50
-/* 0x0884 ( 2 4) */ ldx [%fp-217],%i2
-/* 0x0888 767 ( 3 6) */ ld [%o5],%i3
-/* 0x088c 768 ( 3 4) */ or %g0,8,%g2
-/* 0x0890 769 ( 3 4) */ or %g0,16,%o4
-/* 0x0894 770 ( 4 5) */ sub %g3,1,%o3
-/* 0x0898 771 ( 4 5) */ or %g0,3,%i0
-/* 0x089c 772 ( 5 6) */ add %i2,%i3,%o1
-/* 0x08a0 773 ( 5 8) */ ld [%o5+4],%i2
-/* 0x08a4 774 ( 6 7) */ st %o1,[%o7]
-/* 0x08a8 775 ( 6 7) */ srax %o1,32,%o1
-/* 0x08ac 776 ( 7 9) */ ldx [%fp-201],%o2
-/* 0x08b0 777 ( 7 8) */ add %i1,%i2,%o0
-/* 0x08b4 778 ( 7 8) */ or %g0,%o1,%i1
-/* 0x08b8 779 ( 8 11) */ ld [%o5+8],%o1
-/* 0x08bc 780 ( 8 9) */ add %o0,%i1,%o0
-/* 0x08c0 781 ( 9 10) */ st %o0,[%o7+4]
-/* 0x08c4 782 ( 9 10) */ srax %o0,32,%o0
-
-!
-! ENTRY .L900000140
-!
-
- .L900000140: /* frequency 1.0 confidence 0.0 */
-/* 0x08c8 784 ( 0 1) */ add %g2,4,%i1
-/* 0x08cc 785 ( 0 1) */ add %o4,8,%o4
-/* 0x08d0 786 ( 1 3) */ ldx [%o4+%g4],%i2
-/* 0x08d4 787 ( 1 2) */ sra %o0,0,%g5
-/* 0x08d8 788 ( 1 2) */ add %o2,%o1,%o1
-/* 0x08dc 789 ( 2 5) */ ld [%o5+%i1],%o0
-/* 0x08e0 790 ( 2 3) */ add %o1,%g5,%o1
-/* 0x08e4 791 ( 2 3) */ add %i0,2,%i0
-/* 0x08e8 792 ( 3 4) */ st %o1,[%o7+%g2]
-/* 0x08ec 793 ( 3 4) */ srax %o1,32,%g5
-/* 0x08f0 794 ( 3 4) */ subcc %i0,%o3,%g0
-/* 0x08f4 795 ( 4 5) */ add %g2,8,%g2
-/* 0x08f8 796 ( 4 5) */ add %o4,8,%o4
-/* 0x08fc 797 ( 5 7) */ ldx [%o4+%g4],%o2
-/* 0x0900 798 ( 5 6) */ add %i2,%o0,%o0
-/* 0x0904 799 ( 6 9) */ ld [%o5+%g2],%o1
-/* 0x0908 800 ( 6 7) */ add %o0,%g5,%o0
-/* 0x090c 801 ( 7 8) */ st %o0,[%o7+%i1]
-/* 0x0910 802 ( 7 8) */ ble,pt %icc,.L900000140 ! tprob=0.50
-/* 0x0914 ( 7 8) */ srax %o0,32,%o0
-
-!
-! ENTRY .L900000143
-!
-
- .L900000143: /* frequency 1.0 confidence 0.0 */
-/* 0x0918 805 ( 0 1) */ sra %o0,0,%o3
-/* 0x091c 806 ( 0 1) */ add %o2,%o1,%o0
-/* 0x0920 807 ( 1 2) */ add %o0,%o3,%o0
-/* 0x0924 808 ( 1 2) */ st %o0,[%o7+%g2]
-/* 0x0928 809 ( 1 2) */ subcc %i0,%g3,%g0
-/* 0x092c 810 ( 2 3) */ srax %o0,32,%g5
-/* 0x0930 811 ( 2 3) */ bg,a,pn %icc,.L77000061 ! tprob=0.50
-/* 0x0934 ( 3 4) */ or %g0,%g5,%o3
-
-!
-! ENTRY .L77000078
-!
-
- .L77000078: /* frequency 1.0 confidence 0.0 */
-/* 0x0938 814 ( 0 1) */ sra %i0,0,%o0
-
-!
-! ENTRY .L900000154
-!
-
- .L900000154: /* frequency 1.0 confidence 0.0 */
-/* 0x093c 816 ( 0 1) */ sllx %o0,2,%g2
-/* 0x0940 817 ( 0 1) */ add %i0,1,%i0
-/* 0x0944 818 ( 1 2) */ sllx %o0,3,%o4
-/* 0x0948 819 ( 1 4) */ ld [%o5+%g2],%o2
-/* 0x094c 820 ( 1 2) */ subcc %i0,%g3,%g0
-/* 0x0950 821 ( 2 4) */ ldx [%o4+%g4],%o0
-/* 0x0954 822 ( 2 3) */ sra %g5,0,%o1
-/* 0x0958 823 ( 4 5) */ add %o0,%o2,%o0
-/* 0x095c 824 ( 5 6) */ add %o0,%o1,%o0
-/* 0x0960 825 ( 5 6) */ st %o0,[%o7+%g2]
-/* 0x0964 826 ( 6 7) */ srax %o0,32,%g5
-/* 0x0968 827 ( 6 7) */ ble,pt %icc,.L900000154 ! tprob=0.50
-/* 0x096c ( 7 8) */ sra %i0,0,%o0
-
-!
-! ENTRY .L77000047
-!
-
- .L77000047: /* frequency 1.0 confidence 0.0 */
-/* 0x0970 834 ( 0 1) */ or %g0,%g5,%o3
-
-!
-! ENTRY .L77000061
-!
-
- .L77000061: /* frequency 1.0 confidence 0.0 */
-
-/* 0x0974 835 ( 1 2) */ srl %o3,0,%i0
-/* 0x0978 ( 2 4) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x097c ( 4 5) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L77000048
-!
-
- .L77000048: /* frequency 1.0 confidence 0.0 */
-/* 0x0980 844 ( 0 1) */ bne,pn %icc,.L77000050 ! tprob=0.50
-/* 0x0984 ( 0 1) */ sethi %hi(0xfff80000),%g2
-/* 0x0988 854 ( 0 3) */ ldd [%o2],%f4
-/* 0x098c 855 ( 1 4) */ ldd [%o0],%f6
-/* 0x0990 856 ( 1 2) */ srl %i4,19,%g3
-/* 0x0994 857 ( 1 2) */ andn %i4,%g2,%g2
-/* 0x0998 858 ( 2 3) */ st %g3,[%sp+2351]
-/* 0x099c 859 ( 2 4) */ fxnor %f0,%f4,%f4
-/* 0x09a0 860 ( 3 4) */ st %g2,[%sp+2355]
-/* 0x09a4 861 ( 4 7) */ ldd [%o2+8],%f12
-/* 0x09a8 862 ( 4 7) */ fitod %f4,%f10
-/* 0x09ac 863 ( 5 8) */ ldd [%o0+8],%f16
-/* 0x09b0 864 ( 5 8) */ fitod %f5,%f4
-/* 0x09b4 865 ( 6 9) */ ldd [%o2+16],%f18
-/* 0x09b8 866 ( 6 8) */ fxnor %f0,%f12,%f12
-/* 0x09bc 867 ( 7 10) */ ld [%sp+2351],%f9
-/* 0x09c0 868 ( 7 10) */ fsubd %f16,%f10,%f10
-/* 0x09c4 869 ( 8 11) */ ld [%sp+2355],%f15
-/* 0x09c8 870 ( 8 11) */ fitod %f12,%f22
-/* 0x09cc 871 ( 9 12) */ ldd [%o2+24],%f20
-/* 0x09d0 872 ( 9 12) */ fitod %f13,%f12
-/* 0x09d4 876 (10 13) */ ld [%i1],%g2
-/* 0x09d8 877 (10 13) */ fsubd %f16,%f4,%f4
-/* 0x09dc 878 (11 14) */ ld [%i1+4],%g3
-/* 0x09e0 879 (11 14) */ fsubd %f16,%f22,%f22
-/* 0x09e4 880 (12 15) */ ld [%i1+8],%g4
-/* 0x09e8 881 (12 14) */ fxnor %f0,%f18,%f18
-/* 0x09ec 882 (13 16) */ ld [%i1+12],%g5
-/* 0x09f0 883 (13 16) */ fsubd %f16,%f12,%f12
-/* 0x09f4 884 (14 17) */ ld [%i1+16],%o0
-/* 0x09f8 885 (14 17) */ fitod %f18,%f26
-/* 0x09fc 886 (15 18) */ ld [%i1+20],%o1
-/* 0x0a00 887 (15 17) */ fxnor %f0,%f20,%f20
-/* 0x0a04 888 (16 19) */ ld [%i1+24],%o2
-/* 0x0a08 889 (17 20) */ ld [%i1+28],%o3
-/* 0x0a0c 890 (19 20) */ fmovs %f6,%f8
-/* 0x0a10 891 (20 21) */ fmovs %f6,%f14
-/* 0x0a14 892 (22 25) */ fsubd %f8,%f6,%f8
-/* 0x0a18 893 (23 26) */ fsubd %f14,%f6,%f6
-/* 0x0a1c 894 (25 28) */ fmuld %f10,%f8,%f14
-/* 0x0a20 895 (26 29) */ fmuld %f10,%f6,%f10
-/* 0x0a24 896 (27 30) */ fmuld %f4,%f8,%f24
-/* 0x0a28 897 (28 31) */ fdtox %f14,%f14
-/* 0x0a2c 898 (28 29) */ std %f14,[%sp+2335]
-/* 0x0a30 899 (28 31) */ fmuld %f22,%f8,%f28
-/* 0x0a34 900 (29 32) */ fitod %f19,%f14
-/* 0x0a38 901 (29 32) */ fmuld %f22,%f6,%f18
-/* 0x0a3c 902 (30 33) */ fdtox %f10,%f10
-/* 0x0a40 903 (30 31) */ std %f10,[%sp+2343]
-/* 0x0a44 904 (30 33) */ fmuld %f4,%f6,%f4
-/* 0x0a48 905 (31 34) */ fmuld %f12,%f8,%f22
-/* 0x0a4c 906 (32 35) */ fdtox %f18,%f18
-/* 0x0a50 907 (32 33) */ std %f18,[%sp+2311]
-/* 0x0a54 908 (32 35) */ fmuld %f12,%f6,%f10
-/* 0x0a58 909 (33 35) */ ldx [%sp+2335],%o4
-/* 0x0a5c 910 (33 36) */ fdtox %f24,%f12
-/* 0x0a60 911 (34 35) */ std %f12,[%sp+2319]
-/* 0x0a64 912 (34 37) */ fsubd %f16,%f26,%f12
-/* 0x0a68 913 (35 37) */ ldx [%sp+2343],%o5
-/* 0x0a6c 914 (35 36) */ sllx %o4,19,%o4
-/* 0x0a70 915 (35 38) */ fdtox %f4,%f4
-/* 0x0a74 916 (36 37) */ std %f4,[%sp+2327]
-/* 0x0a78 917 (36 39) */ fdtox %f28,%f24
-/* 0x0a7c 918 (37 38) */ std %f24,[%sp+2303]
-/* 0x0a80 919 (37 40) */ fitod %f20,%f4
-/* 0x0a84 920 (37 38) */ add %o5,%o4,%o4
-/* 0x0a88 921 (37 40) */ fmuld %f12,%f8,%f24
-/* 0x0a8c 922 (38 40) */ ldx [%sp+2319],%o7
-/* 0x0a90 923 (38 41) */ fsubd %f16,%f14,%f14
-/* 0x0a94 924 (38 39) */ add %o4,%g2,%o4
-/* 0x0a98 925 (38 41) */ fmuld %f12,%f6,%f12
-/* 0x0a9c 926 (39 41) */ ldx [%sp+2327],%o5
-/* 0x0aa0 927 (39 42) */ fitod %f21,%f18
-/* 0x0aa4 928 (40 41) */ st %o4,[%i0]
-/* 0x0aa8 929 (40 41) */ sllx %o7,19,%o7
-/* 0x0aac 930 (40 43) */ fdtox %f22,%f20
-/* 0x0ab0 931 (41 42) */ std %f20,[%sp+2287]
-/* 0x0ab4 932 (41 44) */ fdtox %f10,%f10
-/* 0x0ab8 933 (41 42) */ add %o5,%o7,%o5
-/* 0x0abc 934 (41 44) */ fmuld %f14,%f8,%f20
-/* 0x0ac0 935 (42 43) */ std %f10,[%sp+2295]
-/* 0x0ac4 936 (42 43) */ srlx %o4,32,%o7
-/* 0x0ac8 937 (42 45) */ fsubd %f16,%f4,%f4
-/* 0x0acc 938 (42 45) */ fmuld %f14,%f6,%f14
-/* 0x0ad0 939 (43 45) */ ldx [%sp+2311],%g2
-/* 0x0ad4 940 (43 46) */ fdtox %f24,%f10
-/* 0x0ad8 941 (43 44) */ add %o5,%g3,%g3
-/* 0x0adc 942 (44 45) */ std %f10,[%sp+2271]
-/* 0x0ae0 943 (44 45) */ add %g3,%o7,%g3
-/* 0x0ae4 944 (44 47) */ fdtox %f12,%f12
-/* 0x0ae8 945 (45 47) */ ldx [%sp+2303],%l0
-/* 0x0aec 946 (45 48) */ fsubd %f16,%f18,%f10
-/* 0x0af0 947 (45 48) */ fmuld %f4,%f8,%f16
-/* 0x0af4 948 (46 47) */ std %f12,[%sp+2279]
-/* 0x0af8 949 (46 49) */ fdtox %f20,%f12
-/* 0x0afc 950 (46 49) */ fmuld %f4,%f6,%f4
-/* 0x0b00 951 (47 48) */ std %f12,[%sp+2255]
-/* 0x0b04 952 (47 48) */ sllx %l0,19,%l0
-/* 0x0b08 953 (47 50) */ fdtox %f14,%f12
-/* 0x0b0c 954 (48 50) */ ldx [%sp+2287],%o5
-/* 0x0b10 955 (48 49) */ add %g2,%l0,%g2
-/* 0x0b14 956 (48 51) */ fmuld %f10,%f8,%f8
-/* 0x0b18 957 (49 51) */ ldx [%sp+2295],%l1
-/* 0x0b1c 958 (49 50) */ srlx %g3,32,%l0
-/* 0x0b20 959 (49 50) */ add %g2,%g4,%g4
-/* 0x0b24 960 (49 52) */ fmuld %f10,%f6,%f6
-/* 0x0b28 961 (50 51) */ std %f12,[%sp+2263]
-/* 0x0b2c 962 (50 51) */ sllx %o5,19,%g2
-/* 0x0b30 963 (50 51) */ add %g4,%l0,%g4
-/* 0x0b34 964 (51 53) */ ldx [%sp+2279],%l0
-/* 0x0b38 965 (51 52) */ srlx %g4,32,%o5
-/* 0x0b3c 966 (51 52) */ add %l1,%g2,%g2
-/* 0x0b40 967 (52 53) */ st %g3,[%i0+4]
-/* 0x0b44 968 (52 53) */ add %g2,%g5,%g2
-/* 0x0b48 969 (52 55) */ fdtox %f16,%f10
-/* 0x0b4c 970 (53 55) */ ldx [%sp+2271],%o7
-/* 0x0b50 971 (53 54) */ add %g2,%o5,%g2
-/* 0x0b54 972 (53 56) */ fdtox %f4,%f4
-/* 0x0b58 973 (54 55) */ std %f10,[%sp+2239]
-/* 0x0b5c 974 (55 56) */ sllx %o7,19,%o7
-/* 0x0b60 975 (55 56) */ std %f4,[%sp+2247]
-/* 0x0b64 976 (55 58) */ fdtox %f8,%f4
-/* 0x0b68 977 (56 57) */ add %l0,%o7,%o7
-/* 0x0b6c 978 (56 58) */ ldx [%sp+2263],%o5
-/* 0x0b70 979 (57 58) */ add %o7,%o0,%o0
-/* 0x0b74 980 (57 58) */ std %f4,[%sp+2223]
-/* 0x0b78 981 (57 60) */ fdtox %f6,%f4
-/* 0x0b7c 982 (58 60) */ ldx [%sp+2255],%g5
-/* 0x0b80 983 (58 59) */ srlx %g2,32,%o7
-/* 0x0b84 984 (59 60) */ std %f4,[%sp+2231]
-/* 0x0b88 985 (59 60) */ add %o0,%o7,%o0
-/* 0x0b8c 986 (60 61) */ sllx %g5,19,%g5
-/* 0x0b90 987 (60 62) */ ldx [%sp+2247],%l1
-/* 0x0b94 988 (61 62) */ add %o5,%g5,%g5
-/* 0x0b98 989 (61 62) */ st %g2,[%i0+12]
-/* 0x0b9c 990 (62 64) */ ldx [%sp+2239],%l0
-/* 0x0ba0 991 (62 63) */ srlx %o0,32,%o4
-/* 0x0ba4 992 (62 63) */ add %g5,%o1,%o1
-/* 0x0ba8 993 (63 64) */ add %o1,%o4,%o1
-/* 0x0bac 994 (63 65) */ ldx [%sp+2223],%o7
-/* 0x0bb0 995 (64 65) */ sllx %l0,19,%g3
-/* 0x0bb4 996 (64 66) */ ldx [%sp+2231],%o5
-/* 0x0bb8 997 (65 66) */ add %l1,%g3,%o4
-/* 0x0bbc 998 (65 66) */ st %o0,[%i0+16]
-/* 0x0bc0 999 (66 67) */ add %o4,%o2,%o2
-/* 0x0bc4 1000 (66 67) */ st %o1,[%i0+20]
-/* 0x0bc8 1001 (67 68) */ srlx %o1,32,%o4
-/* 0x0bcc 1002 (67 68) */ st %g4,[%i0+8]
-/* 0x0bd0 1003 (68 69) */ sllx %o7,19,%g2
-/* 0x0bd4 1004 (68 69) */ add %o2,%o4,%o4
-/* 0x0bd8 1005 (68 69) */ st %o4,[%i0+24]
-/* 0x0bdc 1006 (69 70) */ add %o5,%g2,%g2
-/* 0x0be0 1007 (70 71) */ srlx %o4,32,%g3
-/* 0x0be4 1008 (70 71) */ add %g2,%o3,%g2
-/* 0x0be8 1009 (71 72) */ add %g2,%g3,%g2
-/* 0x0bec 1010 (71 72) */ st %g2,[%i0+28]
-/* 0x0bf0 1014 (72 73) */ srlx %g2,32,%o3
-/* 0x0bf4 1015 (73 74) */ srl %o3,0,%i0
-/* 0x0bf8 (74 76) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x0bfc (76 77) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L77000050
-!
-
- .L77000050: /* frequency 1.0 confidence 0.0 */
-/* 0x0c00 1022 ( 0 1) */ subcc %i3,16,%g0
-/* 0x0c04 1023 ( 0 1) */ bne,pn %icc,.L77000073 ! tprob=0.50
-/* 0x0c08 ( 0 1) */ sethi %hi(0xfff80000),%g2
-/* 0x0c0c 1034 ( 1 4) */ ldd [%o2],%f4
-/* 0x0c10 1035 ( 1 2) */ andn %i4,%g2,%g2
-/* 0x0c14 1036 ( 2 3) */ st %g2,[%sp+2483]
-/* 0x0c18 1037 ( 2 3) */ srl %i4,19,%g2
-/* 0x0c1c 1038 ( 3 4) */ st %g2,[%sp+2479]
-/* 0x0c20 1039 ( 3 5) */ fxnor %f0,%f4,%f4
-/* 0x0c24 1040 ( 4 7) */ ldd [%o0],%f8
-/* 0x0c28 1041 ( 5 8) */ fitod %f4,%f10
-/* 0x0c2c 1042 ( 5 8) */ ldd [%o0+8],%f16
-/* 0x0c30 1043 ( 6 9) */ ldd [%o2+8],%f14
-/* 0x0c34 1044 ( 6 9) */ fitod %f5,%f4
-/* 0x0c38 1045 ( 7 10) */ ld [%sp+2483],%f13
-/* 0x0c3c 1046 ( 8 11) */ ld [%sp+2479],%f7
-/* 0x0c40 1047 ( 8 11) */ fsubd %f16,%f10,%f10
-/* 0x0c44 1048 ( 9 11) */ fxnor %f0,%f14,%f14
-/* 0x0c48 1049 (10 13) */ fsubd %f16,%f4,%f4
-/* 0x0c4c 1050 (14 15) */ fmovs %f8,%f12
-/* 0x0c50 1051 (15 16) */ fmovs %f8,%f6
-/* 0x0c54 1052 (17 20) */ fsubd %f12,%f8,%f12
-/* 0x0c58 1053 (18 21) */ fsubd %f6,%f8,%f6
-/* 0x0c5c 1054 (19 22) */ fitod %f14,%f8
-/* 0x0c60 1055 (20 23) */ fmuld %f10,%f12,%f18
-/* 0x0c64 1056 (20 23) */ fitod %f15,%f14
-/* 0x0c68 1057 (21 24) */ fmuld %f10,%f6,%f10
-/* 0x0c6c 1058 (22 25) */ fsubd %f16,%f8,%f8
-/* 0x0c70 1059 (22 25) */ fmuld %f4,%f12,%f20
-/* 0x0c74 1060 (23 26) */ fmuld %f4,%f6,%f4
-/* 0x0c78 1061 (23 26) */ fsubd %f16,%f14,%f14
-/* 0x0c7c 1062 (24 27) */ fdtox %f10,%f10
-/* 0x0c80 1063 (24 25) */ std %f10,[%sp+2463]
-/* 0x0c84 1064 (25 28) */ fmuld %f8,%f12,%f10
-/* 0x0c88 1065 (25 28) */ fdtox %f18,%f18
-/* 0x0c8c 1066 (25 26) */ std %f18,[%sp+2471]
-/* 0x0c90 1067 (26 29) */ fmuld %f8,%f6,%f8
-/* 0x0c94 1068 (26 29) */ fdtox %f4,%f4
-/* 0x0c98 1069 (26 27) */ std %f4,[%sp+2447]
-/* 0x0c9c 1070 (27 30) */ fmuld %f14,%f12,%f4
-/* 0x0ca0 1071 (27 30) */ fdtox %f20,%f18
-/* 0x0ca4 1072 (27 28) */ std %f18,[%sp+2455]
-/* 0x0ca8 1073 (28 31) */ fdtox %f10,%f10
-/* 0x0cac 1074 (28 29) */ std %f10,[%sp+2439]
-/* 0x0cb0 1075 (28 31) */ fmuld %f14,%f6,%f14
-/* 0x0cb4 1076 (29 32) */ fdtox %f8,%f8
-/* 0x0cb8 1077 (29 30) */ std %f8,[%sp+2431]
-/* 0x0cbc 1078 (30 33) */ ldd [%o2+16],%f10
-/* 0x0cc0 1079 (30 33) */ fdtox %f4,%f4
-/* 0x0cc4 1080 (31 34) */ ldd [%o2+24],%f8
-/* 0x0cc8 1081 (31 34) */ fdtox %f14,%f14
-/* 0x0ccc 1082 (32 33) */ std %f4,[%sp+2423]
-/* 0x0cd0 1083 (32 34) */ fxnor %f0,%f10,%f10
-/* 0x0cd4 1084 (33 35) */ fxnor %f0,%f8,%f4
-/* 0x0cd8 1085 (33 34) */ std %f14,[%sp+2415]
-/* 0x0cdc 1086 (34 37) */ fitod %f10,%f8
-/* 0x0ce0 1087 (35 38) */ fitod %f11,%f10
-/* 0x0ce4 1088 (36 39) */ fitod %f4,%f14
-/* 0x0ce8 1089 (37 40) */ fsubd %f16,%f8,%f8
-/* 0x0cec 1090 (38 41) */ fsubd %f16,%f10,%f10
-/* 0x0cf0 1091 (39 42) */ fsubd %f16,%f14,%f14
-/* 0x0cf4 1092 (40 43) */ fmuld %f8,%f12,%f18
-/* 0x0cf8 1093 (40 43) */ fitod %f5,%f4
-/* 0x0cfc 1094 (41 44) */ fmuld %f8,%f6,%f8
-/* 0x0d00 1095 (42 45) */ fmuld %f10,%f12,%f20
-/* 0x0d04 1096 (43 46) */ fmuld %f10,%f6,%f10
-/* 0x0d08 1097 (43 46) */ fsubd %f16,%f4,%f4
-/* 0x0d0c 1098 (44 47) */ fdtox %f8,%f8
-/* 0x0d10 1099 (44 45) */ std %f8,[%sp+2399]
-/* 0x0d14 1100 (45 48) */ fmuld %f14,%f12,%f8
-/* 0x0d18 1101 (45 48) */ fdtox %f18,%f18
-/* 0x0d1c 1102 (45 46) */ std %f18,[%sp+2407]
-/* 0x0d20 1103 (46 49) */ fdtox %f10,%f10
-/* 0x0d24 1104 (46 47) */ std %f10,[%sp+2383]
-/* 0x0d28 1105 (46 49) */ fmuld %f14,%f6,%f14
-/* 0x0d2c 1106 (47 50) */ fmuld %f4,%f12,%f10
-/* 0x0d30 1107 (47 50) */ fdtox %f20,%f18
-/* 0x0d34 1108 (47 48) */ std %f18,[%sp+2391]
-/* 0x0d38 1109 (48 51) */ fdtox %f8,%f8
-/* 0x0d3c 1110 (48 49) */ std %f8,[%sp+2375]
-/* 0x0d40 1111 (48 51) */ fmuld %f4,%f6,%f4
-/* 0x0d44 1112 (49 52) */ fdtox %f14,%f14
-/* 0x0d48 1113 (49 50) */ std %f14,[%sp+2367]
-/* 0x0d4c 1117 (50 53) */ ldd [%o2+32],%f8
-/* 0x0d50 1118 (50 53) */ fdtox %f10,%f10
-/* 0x0d54 1119 (51 54) */ fdtox %f4,%f4
-/* 0x0d58 1120 (51 52) */ std %f4,[%sp+2351]
-/* 0x0d5c 1121 (52 54) */ fxnor %f0,%f8,%f8
-/* 0x0d60 1122 (52 55) */ ldd [%o2+40],%f14
-/* 0x0d64 1123 (53 54) */ std %f10,[%sp+2359]
-/* 0x0d68 1124 (54 57) */ fitod %f8,%f4
-/* 0x0d6c 1125 (55 57) */ fxnor %f0,%f14,%f10
-/* 0x0d70 1126 (56 59) */ fitod %f9,%f8
-/* 0x0d74 1127 (57 60) */ fsubd %f16,%f4,%f4
-/* 0x0d78 1128 (58 61) */ fitod %f10,%f14
-/* 0x0d7c 1129 (59 62) */ fsubd %f16,%f8,%f8
-/* 0x0d80 1130 (60 63) */ fmuld %f4,%f12,%f18
-/* 0x0d84 1131 (60 63) */ fitod %f11,%f10
-/* 0x0d88 1132 (61 64) */ fmuld %f4,%f6,%f4
-/* 0x0d8c 1133 (61 64) */ fsubd %f16,%f14,%f14
-/* 0x0d90 1134 (62 65) */ fmuld %f8,%f12,%f20
-/* 0x0d94 1135 (63 66) */ fmuld %f8,%f6,%f8
-/* 0x0d98 1136 (63 66) */ fsubd %f16,%f10,%f10
-/* 0x0d9c 1137 (64 67) */ fdtox %f4,%f4
-/* 0x0da0 1138 (64 65) */ std %f4,[%sp+2335]
-/* 0x0da4 1139 (65 68) */ fmuld %f14,%f12,%f4
-/* 0x0da8 1140 (65 68) */ fdtox %f18,%f18
-/* 0x0dac 1141 (65 66) */ std %f18,[%sp+2343]
-/* 0x0db0 1142 (66 69) */ fdtox %f8,%f8
-/* 0x0db4 1143 (66 67) */ std %f8,[%sp+2319]
-/* 0x0db8 1144 (66 69) */ fmuld %f14,%f6,%f14
-/* 0x0dbc 1145 (67 70) */ fmuld %f10,%f12,%f8
-/* 0x0dc0 1146 (67 70) */ fdtox %f20,%f18
-/* 0x0dc4 1147 (67 68) */ std %f18,[%sp+2327]
-/* 0x0dc8 1148 (68 71) */ fdtox %f4,%f4
-/* 0x0dcc 1149 (68 69) */ std %f4,[%sp+2311]
-/* 0x0dd0 1150 (68 71) */ fmuld %f10,%f6,%f10
-/* 0x0dd4 1151 (69 72) */ fdtox %f14,%f14
-/* 0x0dd8 1152 (69 70) */ std %f14,[%sp+2303]
-/* 0x0ddc 1153 (70 73) */ ldd [%o2+48],%f4
-/* 0x0de0 1154 (70 73) */ fdtox %f8,%f8
-/* 0x0de4 1155 (71 74) */ fdtox %f10,%f10
-/* 0x0de8 1156 (71 72) */ std %f10,[%sp+2287]
-/* 0x0dec 1157 (72 74) */ fxnor %f0,%f4,%f4
-/* 0x0df0 1158 (72 75) */ ldd [%o2+56],%f14
-/* 0x0df4 1159 (73 74) */ std %f8,[%sp+2295]
-/* 0x0df8 1160 (74 77) */ fitod %f4,%f10
-/* 0x0dfc 1161 (75 78) */ fitod %f5,%f4
-/* 0x0e00 1162 (76 78) */ fxnor %f0,%f14,%f8
-/* 0x0e04 1163 (77 80) */ fsubd %f16,%f10,%f10
-/* 0x0e08 1164 (78 81) */ fsubd %f16,%f4,%f4
-/* 0x0e0c 1165 (79 82) */ fitod %f8,%f14
-/* 0x0e10 1166 (80 83) */ fmuld %f10,%f12,%f18
-/* 0x0e14 1167 (80 83) */ fitod %f9,%f8
-/* 0x0e18 1168 (81 84) */ fmuld %f10,%f6,%f10
-/* 0x0e1c 1169 (82 85) */ fmuld %f4,%f12,%f20
-/* 0x0e20 1170 (82 85) */ fsubd %f16,%f14,%f14
-/* 0x0e24 1171 (83 86) */ fdtox %f18,%f18
-/* 0x0e28 1172 (83 84) */ std %f18,[%sp+2279]
-/* 0x0e2c 1173 (83 86) */ fmuld %f4,%f6,%f4
-/* 0x0e30 1174 (84 87) */ fdtox %f10,%f10
-/* 0x0e34 1175 (84 85) */ std %f10,[%sp+2271]
-/* 0x0e38 1176 (85 88) */ fdtox %f20,%f10
-/* 0x0e3c 1177 (85 86) */ std %f10,[%sp+2263]
-/* 0x0e40 1178 (86 89) */ fdtox %f4,%f4
-/* 0x0e44 1179 (86 87) */ std %f4,[%sp+2255]
-/* 0x0e48 1180 (86 89) */ fmuld %f14,%f12,%f10
-/* 0x0e4c 1181 (87 90) */ fmuld %f14,%f6,%f4
-/* 0x0e50 1182 (89 92) */ fdtox %f10,%f10
-/* 0x0e54 1183 (89 90) */ std %f10,[%sp+2247]
-/* 0x0e58 1184 (90 93) */ fdtox %f4,%f4
-/* 0x0e5c 1185 (90 91) */ std %f4,[%sp+2239]
-/* 0x0e60 1189 (91 93) */ ldx [%sp+2463],%g2
-/* 0x0e64 1190 (91 94) */ fsubd %f16,%f8,%f4
-/* 0x0e68 1191 (92 94) */ ldx [%sp+2471],%g3
-/* 0x0e6c 1192 (93 96) */ ld [%i1],%g4
-/* 0x0e70 1193 (93 94) */ sllx %g2,19,%g2
-/* 0x0e74 1194 (94 96) */ ldx [%sp+2455],%g5
-/* 0x0e78 1195 (94 95) */ add %g3,%g2,%g2
-/* 0x0e7c 1196 (94 97) */ fmuld %f4,%f6,%f6
-/* 0x0e80 1197 (95 97) */ ldx [%sp+2447],%g3
-/* 0x0e84 1198 (95 96) */ add %g2,%g4,%g4
-/* 0x0e88 1199 (95 98) */ fmuld %f4,%f12,%f4
-/* 0x0e8c 1200 (96 97) */ st %g4,[%i0]
-/* 0x0e90 1201 (96 97) */ srlx %g4,32,%g4
-/* 0x0e94 1202 (97 100) */ ld [%i1+8],%o0
-/* 0x0e98 1203 (97 98) */ sllx %g3,19,%g2
-/* 0x0e9c 1204 (97 100) */ fdtox %f6,%f6
-/* 0x0ea0 1205 (98 101) */ ld [%i1+4],%g3
-/* 0x0ea4 1206 (98 99) */ add %g5,%g2,%g2
-/* 0x0ea8 1207 (98 101) */ fdtox %f4,%f4
-/* 0x0eac 1208 (99 101) */ ldx [%sp+2439],%g5
-/* 0x0eb0 1209 (100 103) */ ld [%i1+12],%o1
-/* 0x0eb4 1210 (100 101) */ add %g2,%g3,%g2
-/* 0x0eb8 1211 (101 103) */ ldx [%sp+2431],%g3
-/* 0x0ebc 1212 (101 102) */ add %g2,%g4,%g4
-/* 0x0ec0 1213 (102 103) */ st %g4,[%i0+4]
-/* 0x0ec4 1214 (103 104) */ std %f6,[%sp+2223]
-/* 0x0ec8 1215 (103 104) */ sllx %g3,19,%g2
-/* 0x0ecc 1216 (104 106) */ ldx [%sp+2423],%g3
-/* 0x0ed0 1217 (104 105) */ add %g5,%g2,%g2
-/* 0x0ed4 1218 (105 107) */ ldx [%sp+2415],%g5
-/* 0x0ed8 1219 (105 106) */ add %g2,%o0,%g2
-/* 0x0edc 1220 (106 107) */ std %f4,[%sp+2231]
-/* 0x0ee0 1221 (106 107) */ srlx %g4,32,%o0
-/* 0x0ee4 1222 (107 109) */ ldx [%sp+2407],%g4
-/* 0x0ee8 1223 (107 108) */ sllx %g5,19,%g5
-/* 0x0eec 1224 (107 108) */ add %g2,%o0,%g2
-/* 0x0ef0 1225 (108 109) */ st %g2,[%i0+8]
-/* 0x0ef4 1226 (108 109) */ srlx %g2,32,%o0
-/* 0x0ef8 1227 (108 109) */ add %g3,%g5,%g3
-/* 0x0efc 1228 (109 111) */ ldx [%sp+2399],%g5
-/* 0x0f00 1229 (109 110) */ add %g3,%o1,%g3
-/* 0x0f04 1230 (110 113) */ ld [%i1+16],%o1
-/* 0x0f08 1231 (110 111) */ add %g3,%o0,%g3
-/* 0x0f0c 1232 (111 112) */ st %g3,[%i0+12]
-/* 0x0f10 1233 (111 112) */ sllx %g5,19,%g5
-/* 0x0f14 1234 (112 113) */ srlx %g3,32,%o0
-/* 0x0f18 1235 (112 113) */ add %g4,%g5,%g2
-/* 0x0f1c 1236 (112 114) */ ldx [%sp+2383],%g5
-/* 0x0f20 1237 (113 115) */ ldx [%sp+2391],%g4
-/* 0x0f24 1238 (113 114) */ add %g2,%o1,%g2
-/* 0x0f28 1239 (114 117) */ ld [%i1+20],%o1
-/* 0x0f2c 1240 (114 115) */ sllx %g5,19,%g5
-/* 0x0f30 1241 (114 115) */ add %g2,%o0,%g2
-/* 0x0f34 1242 (115 116) */ st %g2,[%i0+16]
-/* 0x0f38 1243 (115 116) */ srlx %g2,32,%o0
-/* 0x0f3c 1244 (115 116) */ add %g4,%g5,%g3
-/* 0x0f40 1245 (116 118) */ ldx [%sp+2367],%g5
-/* 0x0f44 1246 (116 117) */ add %g3,%o1,%g3
-/* 0x0f48 1247 (117 119) */ ldx [%sp+2375],%g4
-/* 0x0f4c 1248 (117 118) */ add %g3,%o0,%g3
-/* 0x0f50 1249 (118 121) */ ld [%i1+24],%o1
-/* 0x0f54 1250 (118 119) */ sllx %g5,19,%g5
-/* 0x0f58 1251 (119 120) */ st %g3,[%i0+20]
-/* 0x0f5c 1252 (119 120) */ add %g4,%g5,%g2
-/* 0x0f60 1253 (120 122) */ ldx [%sp+2351],%g5
-/* 0x0f64 1254 (120 121) */ srlx %g3,32,%o0
-/* 0x0f68 1255 (120 121) */ add %g2,%o1,%g2
-/* 0x0f6c 1256 (121 123) */ ldx [%sp+2359],%g4
-/* 0x0f70 1257 (121 122) */ add %g2,%o0,%g2
-/* 0x0f74 1258 (122 125) */ ld [%i1+28],%o1
-/* 0x0f78 1259 (122 123) */ sllx %g5,19,%g5
-/* 0x0f7c 1260 (123 124) */ st %g2,[%i0+24]
-/* 0x0f80 1261 (123 124) */ add %g4,%g5,%g3
-/* 0x0f84 1265 (124 126) */ ldx [%sp+2335],%g5
-/* 0x0f88 1266 (124 125) */ srlx %g2,32,%o0
-/* 0x0f8c 1267 (124 125) */ add %g3,%o1,%g3
-/* 0x0f90 1268 (125 127) */ ldx [%sp+2343],%g4
-/* 0x0f94 1269 (125 126) */ add %g3,%o0,%g3
-/* 0x0f98 1270 (126 127) */ sllx %g5,19,%g5
-/* 0x0f9c 1271 (126 129) */ ld [%i1+32],%o1
-/* 0x0fa0 1272 (127 128) */ add %g4,%g5,%g2
-/* 0x0fa4 1273 (127 129) */ ldx [%sp+2319],%g5
-/* 0x0fa8 1274 (128 130) */ ldx [%sp+2327],%g4
-/* 0x0fac 1275 (128 129) */ srlx %g3,32,%o0
-/* 0x0fb0 1276 (128 129) */ add %g2,%o1,%g2
-/* 0x0fb4 1277 (129 130) */ st %g3,[%i0+28]
-/* 0x0fb8 1278 (129 130) */ sllx %g5,19,%g5
-/* 0x0fbc 1279 (129 130) */ add %g2,%o0,%g2
-/* 0x0fc0 1280 (130 133) */ ld [%i1+36],%o1
-/* 0x0fc4 1281 (130 131) */ add %g4,%g5,%g3
-/* 0x0fc8 1282 (131 133) */ ldx [%sp+2303],%g5
-/* 0x0fcc 1283 (131 132) */ srlx %g2,32,%o0
-/* 0x0fd0 1284 (132 134) */ ldx [%sp+2311],%g4
-/* 0x0fd4 1285 (132 133) */ add %g3,%o1,%g3
-/* 0x0fd8 1286 (133 134) */ sllx %g5,19,%g5
-/* 0x0fdc 1287 (133 134) */ st %g2,[%i0+32]
-/* 0x0fe0 1288 (133 134) */ add %g3,%o0,%g3
-/* 0x0fe4 1289 (134 135) */ add %g4,%g5,%g2
-/* 0x0fe8 1290 (134 136) */ ldx [%sp+2287],%g5
-/* 0x0fec 1291 (135 137) */ ldx [%sp+2295],%g4
-/* 0x0ff0 1292 (135 136) */ srlx %g3,32,%o0
-/* 0x0ff4 1293 (136 139) */ ld [%i1+40],%o1
-/* 0x0ff8 1294 (136 137) */ sllx %g5,19,%g5
-/* 0x0ffc 1295 (137 138) */ st %g3,[%i0+36]
-/* 0x1000 1296 (137 138) */ add %g4,%g5,%g3
-/* 0x1004 1297 (138 140) */ ldx [%sp+2271],%g5
-/* 0x1008 1298 (138 139) */ add %g2,%o1,%g2
-/* 0x100c 1299 (139 141) */ ldx [%sp+2279],%g4
-/* 0x1010 1300 (139 140) */ add %g2,%o0,%g2
-/* 0x1014 1301 (140 143) */ ld [%i1+44],%o1
-/* 0x1018 1302 (140 141) */ sllx %g5,19,%g5
-/* 0x101c 1303 (141 142) */ st %g2,[%i0+40]
-/* 0x1020 1304 (141 142) */ srlx %g2,32,%o0
-/* 0x1024 1305 (141 142) */ add %g4,%g5,%g2
-/* 0x1028 1306 (142 144) */ ldx [%sp+2255],%g5
-/* 0x102c 1307 (142 143) */ add %g3,%o1,%g3
-/* 0x1030 1308 (143 145) */ ldx [%sp+2263],%g4
-/* 0x1034 1309 (143 144) */ add %g3,%o0,%g3
-/* 0x1038 1310 (144 147) */ ld [%i1+48],%o1
-/* 0x103c 1311 (144 145) */ sllx %g5,19,%g5
-/* 0x1040 1312 (145 146) */ srlx %g3,32,%o0
-/* 0x1044 1313 (145 146) */ st %g3,[%i0+44]
-/* 0x1048 1314 (145 146) */ add %g4,%g5,%g3
-/* 0x104c 1315 (146 148) */ ldx [%sp+2239],%g5
-/* 0x1050 1316 (146 147) */ add %g2,%o1,%g2
-/* 0x1054 1317 (147 150) */ ld [%i1+52],%o1
-/* 0x1058 1318 (147 148) */ add %g2,%o0,%g2
-/* 0x105c 1319 (148 150) */ ldx [%sp+2247],%g4
-/* 0x1060 1320 (148 149) */ sllx %g5,19,%g5
-/* 0x1064 1321 (149 150) */ srlx %g2,32,%o0
-/* 0x1068 1322 (149 150) */ st %g2,[%i0+48]
-/* 0x106c 1323 (149 150) */ add %g3,%o1,%g3
-/* 0x1070 1324 (150 153) */ ld [%i1+56],%o1
-/* 0x1074 1325 (150 151) */ add %g4,%g5,%g2
-/* 0x1078 1326 (150 151) */ add %g3,%o0,%g3
-/* 0x107c 1327 (151 153) */ ldx [%sp+2223],%g5
-/* 0x1080 1328 (151 152) */ srlx %g3,32,%o0
-/* 0x1084 1329 (152 154) */ ldx [%sp+2231],%g4
-/* 0x1088 1330 (152 153) */ add %g2,%o1,%g2
-/* 0x108c 1331 (153 154) */ sllx %g5,19,%g5
-/* 0x1090 1332 (153 156) */ ld [%i1+60],%o1
-/* 0x1094 1333 (153 154) */ add %g2,%o0,%g2
-/* 0x1098 1334 (154 155) */ st %g3,[%i0+52]
-/* 0x109c 1335 (154 155) */ add %g4,%g5,%g3
-/* 0x10a0 1336 (155 156) */ st %g2,[%i0+56]
-/* 0x10a4 1337 (155 156) */ srlx %g2,32,%g2
-/* 0x10a8 1338 (155 156) */ add %g3,%o1,%g3
-/* 0x10ac 1339 (156 157) */ add %g3,%g2,%g2
-/* 0x10b0 1340 (156 157) */ st %g2,[%i0+60]
-/* 0x10b4 1344 (157 158) */ srlx %g2,32,%o3
-/* 0x10b8 1345 (158 159) */ srl %o3,0,%i0
-/* 0x10bc (159 161) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x10c0 (161 162) */ restore %g0,%g0,%g0
-
-!
-! ENTRY .L77000073
-!
-
- .L77000073: /* frequency 1.0 confidence 0.0 */
-
-
- or %g0, %i4, %o2
- or %g0, %o0, %o1
- or %g0, %i3, %o0
-
-!
-! ENTRY .L77000052
-!
-
- .L77000052: /* frequency 1.0 confidence 0.0 */
-/* 0x1028 1318 ( 0 1) */ andn %o2,%g2,%g2
-/* 0x102c 1319 ( 0 1) */ st %g2,[%sp+2227]
-/* 0x1030 1325 ( 0 1) */ add %o0,1,%g3
-/* 0x1034 1326 ( 0 1) */ fmovd %f0,%f14
-/* 0x1038 1327 ( 1 2) */ srl %o2,19,%g2
-/* 0x103c 1328 ( 1 2) */ st %g2,[%sp+2223]
-/* 0x1040 1329 ( 1 2) */ or %g0,0,%o5
-/* 0x1044 1330 ( 2 3) */ srl %g3,31,%g2
-/* 0x1048 1331 ( 2 5) */ ldd [%o1],%f6
-/* 0x104c 1335 ( 2 3) */ sethi %hi(0x1000),%g1
-/* 0x1050 1336 ( 3 4) */ add %g3,%g2,%g2
-/* 0x1054 1337 ( 3 4) */ xor %g1,-625,%g1
-/* 0x1058 1338 ( 3 6) */ ldd [%o1+8],%f20
-/* 0x105c 1339 ( 4 5) */ sra %g2,1,%o3
-/* 0x1060 1340 ( 4 5) */ fmovs %f6,%f8
-/* 0x1064 1341 ( 4 5) */ add %g1,%fp,%g3
-/* 0x1068 1342 ( 5 6) */ fmovs %f6,%f10
-/* 0x106c 1343 ( 5 7) */ ld [%sp+2227],%f9
-/* 0x1070 1344 ( 5 6) */ subcc %o3,0,%g0
-/* 0x1074 1345 ( 6 8) */ ld [%sp+2223],%f11
-/* 0x1078 1346 ( 6 7) */ sethi %hi(0x1000),%g1
-/* 0x107c 1347 ( 6 7) */ or %g0,%i2,%o1
-/* 0x1080 1348 ( 7 10) */ fsubd %f8,%f6,%f18
-/* 0x1084 1349 ( 7 8) */ xor %g1,-617,%g1
-/* 0x1088 1350 ( 7 8) */ or %g0,0,%g4
-/* 0x108c 1351 ( 8 11) */ fsubd %f10,%f6,%f16
-/* 0x1090 1352 ( 8 9) */ bleu,pt %icc,.L990000162 ! tprob=0.50
-/* 0x1094 ( 8 9) */ subcc %o0,0,%g0
-/* 0x1098 1354 ( 9 10) */ add %g1,%fp,%g2
-/* 0x109c 1355 ( 9 10) */ sethi %hi(0x1000),%g1
-/* 0x10a0 1356 (10 11) */ xor %g1,-609,%g1
-/* 0x10a4 1357 (10 11) */ subcc %o3,7,%g0
-/* 0x10a8 1358 (11 12) */ add %g1,%fp,%o7
-/* 0x10ac 1359 (11 12) */ sethi %hi(0x1000),%g1
-/* 0x10b0 1360 (12 13) */ xor %g1,-601,%g1
-/* 0x10b4 1361 (13 14) */ add %g1,%fp,%o4
-/* 0x10b8 1362 (13 14) */ bl,pn %icc,.L77000054 ! tprob=0.50
-/* 0x10bc (13 14) */ sub %o3,2,%o2
-/* 0x10c0 1364 (14 17) */ ldd [%o1],%f2
-/* 0x10c4 1365 (14 15) */ add %o1,16,%g5
-/* 0x10c8 1366 (14 15) */ or %g0,4,%g4
-/* 0x10cc 1367 (15 18) */ ldd [%o1+8],%f0
-/* 0x10d0 1368 (15 16) */ add %o1,8,%o1
-/* 0x10d4 1369 (16 18) */ fxnor %f14,%f2,%f6
-/* 0x10d8 1370 (16 19) */ ldd [%g5],%f4
-/* 0x10dc 1371 (16 17) */ add %o1,16,%o1
-/* 0x10e0 1372 (17 19) */ fxnor %f14,%f0,%f12
-/* 0x10e4 1373 (17 20) */ ldd [%o1],%f0
-/* 0x10e8 1374 (17 18) */ add %o1,8,%o1
-/* 0x10ec 1375 (18 21) */ fitod %f7,%f2
-/* 0x10f0 1376 (19 22) */ fitod %f6,%f6
-/* 0x10f4 1377 (20 22) */ fxnor %f14,%f4,%f10
-/* 0x10f8 1378 (21 24) */ fsubd %f20,%f2,%f2
-/* 0x10fc 1379 (22 24) */ fxnor %f14,%f0,%f8
-/* 0x1100 1380 (23 26) */ fitod %f13,%f4
-/* 0x1104 1381 (24 27) */ fsubd %f20,%f6,%f6
-/* 0x1108 1382 (24 27) */ fmuld %f2,%f16,%f0
-
-!
-! ENTRY .L990000154
-!
-
- .L990000154: /* frequency 1.0 confidence 0.0 */
-/* 0x110c 1384 ( 0 3) */ ldd [%o1],%f24
-/* 0x1110 1385 ( 0 1) */ add %g4,3,%g4
-/* 0x1114 1386 ( 0 1) */ add %o4,96,%o4
-/* 0x1118 1387 ( 1 4) */ fitod %f11,%f22
-/* 0x111c 1388 ( 2 5) */ fsubd %f20,%f4,%f26
-/* 0x1120 1389 ( 2 3) */ subcc %g4,%o2,%g0
-/* 0x1124 1390 ( 2 3) */ add %o7,96,%o7
-/* 0x1128 1391 ( 2 5) */ fmuld %f6,%f18,%f28
-/* 0x112c 1392 ( 3 6) */ fmuld %f6,%f16,%f6
-/* 0x1130 1393 ( 3 4) */ add %g2,96,%g2
-/* 0x1134 1394 ( 3 4) */ add %g3,96,%g3
-/* 0x1138 1395 ( 4 7) */ fdtox %f0,%f0
-/* 0x113c 1396 ( 5 8) */ fitod %f12,%f4
-/* 0x1140 1397 ( 5 8) */ fmuld %f2,%f18,%f2
-/* 0x1144 1398 ( 6 9) */ fdtox %f28,%f12
-/* 0x1148 1399 ( 7 10) */ fdtox %f6,%f6
-/* 0x114c 1400 ( 7 8) */ std %f12,[%g3-96]
-/* 0x1150 1401 ( 8 9) */ std %f6,[%g2-96]
-/* 0x1154 1402 ( 8 11) */ fdtox %f2,%f2
-/* 0x1158 1403 ( 9 12) */ fsubd %f20,%f4,%f6
-/* 0x115c 1404 ( 9 10) */ std %f2,[%o7-96]
-/* 0x1160 1405 ( 9 10) */ add %o1,8,%o1
-/* 0x1164 1406 (10 12) */ fxnor %f14,%f24,%f12
-/* 0x1168 1407 (10 13) */ fmuld %f26,%f16,%f4
-/* 0x116c 1408 (10 11) */ std %f0,[%o4-96]
-/* 0x1170 1409 (11 14) */ ldd [%o1],%f0
-/* 0x1174 1410 (11 14) */ fitod %f9,%f2
-/* 0x1178 1411 (12 15) */ fsubd %f20,%f22,%f28
-/* 0x117c 1412 (12 15) */ fmuld %f6,%f18,%f24
-/* 0x1180 1413 (13 16) */ fmuld %f6,%f16,%f22
-/* 0x1184 1414 (13 16) */ fdtox %f4,%f4
-/* 0x1188 1415 (14 17) */ fitod %f10,%f6
-/* 0x118c 1416 (14 17) */ fmuld %f26,%f18,%f10
-/* 0x1190 1417 (15 18) */ fdtox %f24,%f24
-/* 0x1194 1418 (16 19) */ fdtox %f22,%f22
-/* 0x1198 1419 (16 17) */ std %f24,[%g3-64]
-/* 0x119c 1420 (17 18) */ std %f22,[%g2-64]
-/* 0x11a0 1421 (17 20) */ fdtox %f10,%f10
-/* 0x11a4 1422 (18 21) */ fsubd %f20,%f6,%f6
-/* 0x11a8 1423 (18 19) */ std %f10,[%o7-64]
-/* 0x11ac 1424 (18 19) */ add %o1,8,%o1
-/* 0x11b0 1425 (19 21) */ fxnor %f14,%f0,%f10
-/* 0x11b4 1426 (19 22) */ fmuld %f28,%f16,%f0
-/* 0x11b8 1427 (19 20) */ std %f4,[%o4-64]
-/* 0x11bc 1428 (20 23) */ ldd [%o1],%f22
-/* 0x11c0 1429 (20 23) */ fitod %f13,%f4
-/* 0x11c4 1430 (21 24) */ fsubd %f20,%f2,%f2
-/* 0x11c8 1431 (21 24) */ fmuld %f6,%f18,%f26
-/* 0x11cc 1432 (22 25) */ fmuld %f6,%f16,%f24
-/* 0x11d0 1433 (22 25) */ fdtox %f0,%f0
-/* 0x11d4 1434 (23 26) */ fitod %f8,%f6
-/* 0x11d8 1435 (23 26) */ fmuld %f28,%f18,%f8
-/* 0x11dc 1436 (24 27) */ fdtox %f26,%f26
-/* 0x11e0 1437 (25 28) */ fdtox %f24,%f24
-/* 0x11e4 1438 (25 26) */ std %f26,[%g3-32]
-/* 0x11e8 1439 (26 27) */ std %f24,[%g2-32]
-/* 0x11ec 1440 (26 29) */ fdtox %f8,%f8
-/* 0x11f0 1441 (27 30) */ fsubd %f20,%f6,%f6
-/* 0x11f4 1442 (27 28) */ std %f8,[%o7-32]
-/* 0x11f8 1443 (27 28) */ add %o1,8,%o1
-/* 0x11fc 1444 (28 30) */ fxnor %f14,%f22,%f8
-/* 0x1200 1445 (28 29) */ std %f0,[%o4-32]
-/* 0x1204 1446 (28 29) */ bcs,pt %icc,.L990000154 ! tprob=0.50
-/* 0x1208 (28 31) */ fmuld %f2,%f16,%f0
-
-!
-! ENTRY .L990000157
-!
-
- .L990000157: /* frequency 1.0 confidence 0.0 */
-/* 0x120c 1449 ( 0 3) */ fitod %f12,%f28
-/* 0x1210 1450 ( 0 3) */ fmuld %f6,%f18,%f24
-/* 0x1214 1451 ( 0 1) */ add %g3,128,%g3
-/* 0x1218 1452 ( 1 4) */ fitod %f10,%f12
-/* 0x121c 1453 ( 1 4) */ fmuld %f6,%f16,%f26
-/* 0x1220 1454 ( 1 2) */ add %g2,128,%g2
-/* 0x1224 1455 ( 2 5) */ fsubd %f20,%f4,%f4
-/* 0x1228 1456 ( 2 5) */ fmuld %f2,%f18,%f22
-/* 0x122c 1457 ( 2 3) */ add %o7,128,%o7
-/* 0x1230 1458 ( 3 6) */ fdtox %f24,%f6
-/* 0x1234 1459 ( 3 4) */ std %f6,[%g3-128]
-/* 0x1238 1460 ( 3 4) */ add %o4,128,%o4
-/* 0x123c 1461 ( 4 7) */ fsubd %f20,%f28,%f2
-/* 0x1240 1462 ( 4 5) */ subcc %g4,%o3,%g0
-/* 0x1244 1463 ( 5 8) */ fitod %f11,%f6
-/* 0x1248 1464 ( 5 8) */ fmuld %f4,%f18,%f24
-/* 0x124c 1465 ( 6 9) */ fdtox %f26,%f10
-/* 0x1250 1466 ( 6 7) */ std %f10,[%g2-128]
-/* 0x1254 1467 ( 7 10) */ fdtox %f22,%f10
-/* 0x1258 1468 ( 7 8) */ std %f10,[%o7-128]
-/* 0x125c 1469 ( 7 10) */ fmuld %f2,%f18,%f26
-/* 0x1260 1470 ( 8 11) */ fsubd %f20,%f12,%f10
-/* 0x1264 1471 ( 8 11) */ fmuld %f2,%f16,%f2
-/* 0x1268 1472 ( 9 12) */ fsubd %f20,%f6,%f22
-/* 0x126c 1473 ( 9 12) */ fmuld %f4,%f16,%f12
-/* 0x1270 1474 (10 13) */ fdtox %f0,%f0
-/* 0x1274 1475 (10 11) */ std %f0,[%o4-128]
-/* 0x1278 1476 (11 14) */ fitod %f8,%f4
-/* 0x127c 1477 (11 14) */ fmuld %f10,%f18,%f6
-/* 0x1280 1478 (12 15) */ fdtox %f26,%f0
-/* 0x1284 1479 (12 13) */ std %f0,[%g3-96]
-/* 0x1288 1480 (12 15) */ fmuld %f10,%f16,%f10
-/* 0x128c 1481 (13 16) */ fdtox %f2,%f2
-/* 0x1290 1482 (13 14) */ std %f2,[%g2-96]
-/* 0x1294 1483 (14 17) */ fitod %f9,%f0
-/* 0x1298 1484 (14 17) */ fmuld %f22,%f18,%f2
-/* 0x129c 1485 (15 18) */ fdtox %f24,%f8
-/* 0x12a0 1486 (15 16) */ std %f8,[%o7-96]
-/* 0x12a4 1487 (16 19) */ fsubd %f20,%f4,%f4
-/* 0x12a8 1488 (16 19) */ fmuld %f22,%f16,%f8
-/* 0x12ac 1489 (17 20) */ fdtox %f12,%f12
-/* 0x12b0 1490 (17 18) */ std %f12,[%o4-96]
-/* 0x12b4 1491 (18 21) */ fsubd %f20,%f0,%f0
-/* 0x12b8 1492 (19 22) */ fdtox %f6,%f6
-/* 0x12bc 1493 (19 20) */ std %f6,[%g3-64]
-/* 0x12c0 1494 (20 23) */ fdtox %f10,%f10
-/* 0x12c4 1495 (20 21) */ std %f10,[%g2-64]
-/* 0x12c8 1496 (20 23) */ fmuld %f4,%f18,%f6
-/* 0x12cc 1497 (21 24) */ fdtox %f2,%f2
-/* 0x12d0 1498 (21 22) */ std %f2,[%o7-64]
-/* 0x12d4 1499 (21 24) */ fmuld %f4,%f16,%f4
-/* 0x12d8 1500 (22 25) */ fmuld %f0,%f18,%f2
-/* 0x12dc 1501 (22 25) */ fdtox %f8,%f8
-/* 0x12e0 1502 (22 23) */ std %f8,[%o4-64]
-/* 0x12e4 1503 (23 26) */ fdtox %f6,%f6
-/* 0x12e8 1504 (23 24) */ std %f6,[%g3-32]
-/* 0x12ec 1505 (23 26) */ fmuld %f0,%f16,%f0
-/* 0x12f0 1506 (24 27) */ fdtox %f4,%f4
-/* 0x12f4 1507 (24 25) */ std %f4,[%g2-32]
-/* 0x12f8 1508 (25 28) */ fdtox %f2,%f2
-/* 0x12fc 1509 (25 26) */ std %f2,[%o7-32]
-/* 0x1300 1510 (26 29) */ fdtox %f0,%f0
-/* 0x1304 1511 (26 27) */ bcc,pn %icc,.L77000056 ! tprob=0.50
-/* 0x1308 (26 27) */ std %f0,[%o4-32]
-
-!
-! ENTRY .L77000054
-!
-
- .L77000054: /* frequency 1.0 confidence 0.0 */
-/* 0x130c 1514 ( 0 3) */ ldd [%o1],%f0
-
-!
-! ENTRY .L990000161
-!
-
- .L990000161: /* frequency 1.0 confidence 0.0 */
-/* 0x1310 1516 ( 0 2) */ fxnor %f14,%f0,%f0
-/* 0x1314 1517 ( 0 1) */ add %g4,1,%g4
-/* 0x1318 1518 ( 0 1) */ add %o1,8,%o1
-/* 0x131c 1519 ( 1 2) */ subcc %g4,%o3,%g0
-/* 0x1320 1520 ( 2 5) */ fitod %f0,%f2
-/* 0x1324 1521 ( 3 6) */ fitod %f1,%f0
-/* 0x1328 1522 ( 5 8) */ fsubd %f20,%f2,%f2
-/* 0x132c 1523 ( 6 9) */ fsubd %f20,%f0,%f0
-/* 0x1330 1524 ( 8 11) */ fmuld %f2,%f18,%f6
-/* 0x1334 1525 ( 9 12) */ fmuld %f2,%f16,%f4
-/* 0x1338 1526 (10 13) */ fmuld %f0,%f18,%f2
-/* 0x133c 1527 (11 14) */ fdtox %f6,%f6
-/* 0x1340 1528 (11 12) */ std %f6,[%g3]
-/* 0x1344 1529 (11 14) */ fmuld %f0,%f16,%f0
-/* 0x1348 1530 (12 15) */ fdtox %f4,%f4
-/* 0x134c 1531 (12 13) */ std %f4,[%g2]
-/* 0x1350 1532 (12 13) */ add %g2,32,%g2
-/* 0x1354 1533 (13 16) */ fdtox %f2,%f2
-/* 0x1358 1534 (13 14) */ std %f2,[%o7]
-/* 0x135c 1535 (13 14) */ add %o7,32,%o7
-/* 0x1360 1536 (14 17) */ fdtox %f0,%f0
-/* 0x1364 1537 (14 15) */ std %f0,[%o4]
-/* 0x1368 1538 (14 15) */ add %o4,32,%o4
-/* 0x136c 1539 (15 16) */ add %g3,32,%g3
-/* 0x1370 1540 (15 16) */ bcs,a,pt %icc,.L990000161 ! tprob=0.50
-/* 0x1374 (16 19) */ ldd [%o1],%f0
-
-!
-! ENTRY .L77000056
-!
-
- .L77000056: /* frequency 1.0 confidence 0.0 */
-/* 0x1378 1548 ( 0 1) */ subcc %o0,0,%g0
-
-!
-! ENTRY .L990000162
-!
-
- .L990000162: /* frequency 1.0 confidence 0.0 */
-/* 0x137c 1550 ( 0 1) */ bleu,pt %icc,.L77770061 ! tprob=0.50
-/* 0x1380 ( 0 1) */ nop
-/* 0x1384 1555 ( 0 1) */ sethi %hi(0x1000),%g1
-/* 0x1388 1556 ( 1 2) */ xor %g1,-625,%g1
-/* 0x138c 1557 ( 1 2) */ or %g0,%i1,%g4
-/* 0x1390 1558 ( 2 3) */ add %g1,%fp,%g5
-/* 0x1394 1559 ( 2 3) */ sethi %hi(0x1000),%g1
-/* 0x1398 1560 ( 3 4) */ xor %g1,-617,%g1
-/* 0x139c 1561 ( 3 4) */ or %g0,%o0,%o7
-/* 0x13a0 1562 ( 4 5) */ add %g1,%fp,%g2
-/* 0x13a4 1563 ( 4 5) */ or %g0,0,%i2
-/* 0x13a8 1564 ( 5 6) */ or %g0,%i0,%g3
-/* 0x13ac 1565 ( 5 6) */ subcc %o0,6,%g0
-/* 0x13b0 1566 ( 5 6) */ bl,pn %icc,.L77000058 ! tprob=0.50
-/* 0x13b4 ( 6 7) */ sethi %hi(0x1000),%g1
-/* 0x13b8 1568 ( 6 8) */ ld [%g4],%o2
-/* 0x13bc 1569 ( 6 7) */ add %g3,4,%g3
-/* 0x13c0 1570 ( 7 8) */ xor %g1,-585,%g1
-/* 0x13c4 1571 ( 7 8) */ sub %o7,3,%o4
-/* 0x13c8 1572 ( 8 9) */ add %g1,%fp,%g2
-/* 0x13cc 1573 ( 8 9) */ sethi %hi(0x1000),%g1
-/* 0x13d0 1574 ( 9 10) */ xor %g1,-593,%g1
-/* 0x13d4 1575 ( 9 10) */ or %g0,2,%i2
-/* 0x13d8 1576 (10 11) */ add %g1,%fp,%g5
-/* 0x13dc 1577 (10 11) */ sethi %hi(0x1000),%g1
-/* 0x13e0 1578 (11 12) */ xor %g1,-617,%g1
-/* 0x13e4 1579 (12 13) */ add %g1,%fp,%g1
-/* 0x13e8 1580 (13 15) */ ldx [%g1],%o1
-/* 0x13ec 1581 (14 16) */ ldx [%g1-8],%o0
-/* 0x13f0 1582 (15 16) */ sllx %o1,19,%o1
-/* 0x13f4 1583 (15 17) */ ldx [%g1+16],%o3
-/* 0x13f8 1584 (16 17) */ add %o0,%o1,%o0
-/* 0x13fc 1585 (16 18) */ ld [%g4+4],%o1
-/* 0x1400 1586 (16 17) */ add %g4,8,%g4
-/* 0x1404 1587 (17 18) */ sllx %o3,19,%o3
-/* 0x1408 1588 (17 18) */ add %o0,%o2,%o0
-/* 0x140c 1589 (17 19) */ ldx [%g1+8],%o2
-/* 0x1410 1590 (18 19) */ st %o0,[%g3-4]
-/* 0x1414 1591 (18 19) */ srlx %o0,32,%o0
-
-!
-! ENTRY .L990000142
-!
-
- .L990000142: /* frequency 1.0 confidence 0.0 */
-/* 0x1418 1593 ( 0 1) */ add %o2,%o3,%o2
-/* 0x141c 1594 ( 0 1) */ add %i2,4,%i2
-/* 0x1420 1595 ( 0 2) */ ld [%g4],%o3
-/* 0x1424 1596 ( 1 2) */ srl %o0,0,%o5
-/* 0x1428 1597 ( 1 2) */ add %o2,%o1,%o1
-/* 0x142c 1598 ( 1 3) */ ldx [%g2],%o0
-/* 0x1430 1599 ( 3 4) */ sllx %o0,19,%o2
-/* 0x1434 1600 ( 3 5) */ ldx [%g5],%o0
-/* 0x1438 1601 ( 3 4) */ add %o1,%o5,%o1
-/* 0x143c 1602 ( 4 5) */ st %o1,[%g3]
-/* 0x1440 1603 ( 4 5) */ srlx %o1,32,%o5
-/* 0x1444 1604 ( 4 5) */ subcc %i2,%o4,%g0
-/* 0x1448 1605 ( 5 7) */ ldx [%g2+16],%o1
-/* 0x144c 1606 ( 5 6) */ add %o0,%o2,%o0
-/* 0x1450 1607 ( 5 6) */ add %g3,16,%g3
-/* 0x1454 1608 ( 6 8) */ ld [%g4+4],%o2
-/* 0x1458 1609 ( 6 7) */ add %o0,%o3,%o0
-/* 0x145c 1610 ( 7 8) */ sllx %o1,19,%o3
-/* 0x1460 1611 ( 7 9) */ ldx [%g5+16],%o1
-/* 0x1464 1612 ( 7 8) */ add %o0,%o5,%o0
-/* 0x1468 1613 ( 8 9) */ st %o0,[%g3-12]
-/* 0x146c 1614 ( 8 9) */ srlx %o0,32,%o5
-/* 0x1470 1615 ( 8 9) */ add %g4,16,%g4
-/* 0x1474 1616 ( 9 11) */ ldx [%g2+32],%o0
-/* 0x1478 1617 ( 9 10) */ add %o1,%o3,%o1
-/* 0x147c 1618 ( 9 10) */ add %g2,64,%g2
-/* 0x1480 1619 (10 12) */ ld [%g4-8],%o3
-/* 0x1484 1620 (10 11) */ add %o1,%o2,%o2
-/* 0x1488 1621 (11 12) */ sllx %o0,19,%o1
-/* 0x148c 1622 (11 13) */ ldx [%g5+32],%o0
-/* 0x1490 1623 (11 12) */ add %o2,%o5,%o2
-/* 0x1494 1624 (12 13) */ st %o2,[%g3-8]
-/* 0x1498 1625 (12 13) */ srlx %o2,32,%o5
-/* 0x149c 1626 (12 13) */ add %g5,64,%g5
-/* 0x14a0 1627 (13 15) */ ldx [%g2-16],%o2
-/* 0x14a4 1628 (13 14) */ add %o0,%o1,%o0
-/* 0x14a8 1629 (14 16) */ ld [%g4-4],%o1
-/* 0x14ac 1630 (14 15) */ add %o0,%o3,%o0
-/* 0x14b0 1631 (15 16) */ sllx %o2,19,%o3
-/* 0x14b4 1632 (15 17) */ ldx [%g5-16],%o2
-/* 0x14b8 1633 (15 16) */ add %o0,%o5,%o0
-/* 0x14bc 1634 (16 17) */ st %o0,[%g3-4]
-/* 0x14c0 1635 (16 17) */ bcs,pt %icc,.L990000142 ! tprob=0.50
-/* 0x14c4 (16 17) */ srlx %o0,32,%o0
-
-!
-! ENTRY .L990000145
-!
-
- .L990000145: /* frequency 1.0 confidence 0.0 */
-/* 0x14c8 1638 ( 0 1) */ add %o2,%o3,%o3
-/* 0x14cc 1639 ( 0 1) */ add %g3,4,%g3
-/* 0x14d0 1640 ( 1 2) */ srl %o0,0,%o2
-/* 0x14d4 1641 ( 1 2) */ add %o3,%o1,%o0
-/* 0x14d8 1642 ( 2 3) */ add %o0,%o2,%o0
-/* 0x14dc 1643 ( 2 3) */ st %o0,[%g3-4]
-/* 0x14e0 1644 ( 2 3) */ subcc %i2,%o7,%g0
-/* 0x14e4 1645 ( 2 3) */ bcc,pn %icc,.L77770061 ! tprob=0.50
-/* 0x14e8 ( 3 4) */ srlx %o0,32,%o5
-
-!
-! ENTRY .L77000058
-!
-
- .L77000058: /* frequency 1.0 confidence 0.0 */
-/* 0x14ec 1648 ( 0 2) */ ldx [%g2],%o2
-
-!
-! ENTRY .L990000160
-!
-
- .L990000160: /* frequency 1.0 confidence 0.0 */
-/* 0x14f0 1650 ( 0 1) */ sllx %o2,19,%o3
-/* 0x14f4 1651 ( 0 2) */ ldx [%g5],%o0
-/* 0x14f8 1652 ( 0 1) */ add %i2,1,%i2
-/* 0x14fc 1653 ( 1 2) */ srl %o5,0,%o1
-/* 0x1500 1654 ( 1 3) */ ld [%g4],%o2
-/* 0x1504 1655 ( 1 2) */ add %g2,16,%g2
-/* 0x1508 1656 ( 2 3) */ add %o0,%o3,%o0
-/* 0x150c 1657 ( 2 3) */ add %g5,16,%g5
-/* 0x1510 1658 ( 3 4) */ add %o0,%o2,%o0
-/* 0x1514 1659 ( 3 4) */ add %g4,4,%g4
-/* 0x1518 1660 ( 4 5) */ add %o0,%o1,%o0
-/* 0x151c 1661 ( 4 5) */ st %o0,[%g3]
-/* 0x1520 1662 ( 4 5) */ subcc %i2,%o7,%g0
-/* 0x1524 1663 ( 5 6) */ srlx %o0,32,%o5
-/* 0x1528 1664 ( 5 6) */ add %g3,4,%g3
-/* 0x152c 1665 ( 5 6) */ bcs,a,pt %icc,.L990000160 ! tprob=0.50
-/* 0x1530 ( 6 8) */ ldx [%g2],%o2
-
-!
-! ENTRY .L77770061
-!
-
- .L77770061: /* frequency 1.0 confidence 0.0 */
-/* 0x1534 ( 0 2) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x1538 ( 2 3) */ restore %g0,%o5,%o0
-
-
-/* 0x124c 1476 ( 0 0) */ .type mul_add,2
-/* 0x124c 1477 ( 0 0) */ .size mul_add,(.-mul_add)
-/* 0x124c 1480 ( 0 0) */ .align 8
-/* 0x1250 1486 ( 0 0) */ .global mul_add_inp
-
-!
-! ENTRY mul_add_inp
-!
-
- .global mul_add_inp
- mul_add_inp: /* frequency 1.0 confidence 0.0 */
-/* 0x1250 1488 ( 0 1) */ save %sp,-176,%sp
-/* 0x1254 1500 ( 1 2) */ sra %i2,0,%o3
-/* 0x1258 1501 ( 1 2) */ or %g0,%i1,%o2
-/* 0x125c 1502 ( 2 3) */ or %g0,%i0,%o0
-/* 0x1260 1503 ( 2 3) */ or %g0,%i0,%o1
-/* 0x1264 1504 ( 3 5) */ call mul_add ! params = ! Result =
-/* 0x1268 ( 4 5) */ srl %i3,0,%o4
-/* 0x126c 1506 ( 5 6) */ srl %o0,0,%i0
-/* 0x1270 ( 6 8) */ ret ! Result = %o1 %o0 %f0 %f1
-/* 0x1274 ( 8 9) */ restore %g0,%g0,%g0
-/* 0x1278 1509 ( 0 0) */ .type mul_add_inp,2
-/* 0x1278 1510 ( 0 0) */ .size mul_add_inp,(.-mul_add_inp)
-
- .section ".data",#alloc,#write
-/* 0x1278 6 ( 0 0) */ .align 8
-
-!
-! ENTRY mask_cnst
-!
-
- mask_cnst: /* frequency 1.0 confidence 0.0 */
-/* 0x1278 8 ( 0 0) */ .xword -9223372034707292160
-/* 0x1280 9 ( 0 0) */ .type mask_cnst,#object
-/* 0x1280 10 ( 0 0) */ .size mask_cnst,8
-
diff --git a/security/nss/lib/freebl/mpi/mpvalpha.c b/security/nss/lib/freebl/mpi/mpvalpha.c
deleted file mode 100644
index 943064dc5..000000000
--- a/security/nss/lib/freebl/mpi/mpvalpha.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi-priv.h"
-#include <c_asm.h>
-
-
-#define MP_MUL_DxD(a, b, Phi, Plo) \
- { Plo = asm ("mulq %a0, %a1, %v0", a, b); \
- Phi = asm ("umulh %a0, %a1, %v0", a, b); } \
-
-/* This is empty for the loop in s_mpv_mul_d */
-#define CARRY_ADD
-
-#define ONE_MUL \
- a_i = *a++; \
- MP_MUL_DxD(a_i, b, a1b1, a0b0); \
- a0b0 += carry; \
- if (a0b0 < carry) \
- ++a1b1; \
- CARRY_ADD \
- *c++ = a0b0; \
- carry = a1b1; \
-
-#define FOUR_MUL \
- ONE_MUL \
- ONE_MUL \
- ONE_MUL \
- ONE_MUL \
-
-#define SIXTEEN_MUL \
- FOUR_MUL \
- FOUR_MUL \
- FOUR_MUL \
- FOUR_MUL \
-
-#define THIRTYTWO_MUL \
- SIXTEEN_MUL \
- SIXTEEN_MUL \
-
-#define ONETWENTYEIGHT_MUL \
- THIRTYTWO_MUL \
- THIRTYTWO_MUL \
- THIRTYTWO_MUL \
- THIRTYTWO_MUL \
-
-
-#define EXPAND_256(CALL) \
- mp_digit carry = 0; \
- mp_digit a_i; \
- mp_digit a0b0, a1b1; \
- if (a_len &255) { \
- if (a_len &1) { \
- ONE_MUL \
- } \
- if (a_len &2) { \
- ONE_MUL \
- ONE_MUL \
- } \
- if (a_len &4) { \
- FOUR_MUL \
- } \
- if (a_len &8) { \
- FOUR_MUL \
- FOUR_MUL \
- } \
- if (a_len & 16 ) { \
- SIXTEEN_MUL \
- } \
- if (a_len & 32 ) { \
- THIRTYTWO_MUL \
- } \
- if (a_len & 64 ) { \
- THIRTYTWO_MUL \
- THIRTYTWO_MUL \
- } \
- if (a_len & 128) { \
- ONETWENTYEIGHT_MUL \
- } \
- a_len = a_len & (-256); \
- } \
- if (a_len>=256 ) { \
- carry = CALL(a, a_len, b, c, carry); \
- c += a_len; \
- } \
-
-#define FUNC_NAME(NAME) \
-mp_digit NAME(const mp_digit *a, \
- mp_size a_len, \
- mp_digit b, mp_digit *c, \
- mp_digit carry) \
-
-#define DECLARE_MUL_256(FNAME) \
-FUNC_NAME(FNAME) \
-{ \
- mp_digit a_i; \
- mp_digit a0b0, a1b1; \
- while (a_len) { \
- ONETWENTYEIGHT_MUL \
- ONETWENTYEIGHT_MUL \
- a_len-= 256; \
- } \
- return carry; \
-} \
-
-/* Expanding the loop in s_mpv_mul_d appeared to slow down the
- (admittedly) small number of tests (i.e., timetest) used to
- measure performance, so this define disables that optimization. */
-#define DO_NOT_EXPAND 1
-
-/* Need forward declaration so it can be instantiated after
- the routine that uses it; this helps locality somewhat */
-#if !defined(DO_NOT_EXPAND)
-FUNC_NAME(s_mpv_mul_d_MUL256);
-#endif
-
-/* c = a * b */
-void s_mpv_mul_d(const mp_digit *a, mp_size a_len,
- mp_digit b, mp_digit *c)
-{
-#if defined(DO_NOT_EXPAND)
- mp_digit carry = 0;
- while (a_len--) {
- mp_digit a_i = *a++;
- mp_digit a0b0, a1b1;
-
- MP_MUL_DxD(a_i, b, a1b1, a0b0);
-
- a0b0 += carry;
- if (a0b0 < carry)
- ++a1b1;
- *c++ = a0b0;
- carry = a1b1;
- }
-#else
- EXPAND_256(s_mpv_mul_d_MUL256)
-#endif
- *c = carry;
-}
-
-#if !defined(DO_NOT_EXPAND)
-DECLARE_MUL_256(s_mpv_mul_d_MUL256)
-#endif
-
-#undef CARRY_ADD
-/* This is redefined for the loop in s_mpv_mul_d_add */
-#define CARRY_ADD \
- a0b0 += a_i = *c; \
- if (a0b0 < a_i) \
- ++a1b1; \
-
-/* Need forward declaration so it can be instantiated between the
- two routines that use it; this helps locality somewhat */
-FUNC_NAME(s_mpv_mul_d_add_MUL256);
-
-/* c += a * b */
-void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len,
- mp_digit b, mp_digit *c)
-{
- EXPAND_256(s_mpv_mul_d_add_MUL256)
- *c = carry;
-}
-
-/* Instantiate multiply 256 routine here */
-DECLARE_MUL_256(s_mpv_mul_d_add_MUL256)
-
-/* Presently, this is only used by the Montgomery arithmetic code. */
-/* c += a * b */
-void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len,
- mp_digit b, mp_digit *c)
-{
- EXPAND_256(s_mpv_mul_d_add_MUL256)
- while (carry) {
- mp_digit c_i = *c;
- carry += c_i;
- *c++ = carry;
- carry = carry < c_i;
- }
-}
-
diff --git a/security/nss/lib/freebl/mpi/mulsqr.c b/security/nss/lib/freebl/mpi/mulsqr.c
deleted file mode 100644
index 702ad2466..000000000
--- a/security/nss/lib/freebl/mpi/mulsqr.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Test whether to include squaring code given the current settings
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <time.h>
-
-#define MP_SQUARE 1 /* make sure squaring code is included */
-
-#include "mpi.h"
-#include "mpprime.h"
-
-int main(int argc, char *argv[])
-{
- int ntests, prec, ix;
- unsigned int seed;
- clock_t start, stop;
- double multime, sqrtime;
- mp_int a, c;
-
- seed = (unsigned int)time(NULL);
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <ntests> <nbits>\n", argv[0]);
- return 1;
- }
-
- if((ntests = abs(atoi(argv[1]))) == 0) {
- fprintf(stderr, "%s: must request at least 1 test.\n", argv[0]);
- return 1;
- }
- if((prec = abs(atoi(argv[2]))) < CHAR_BIT) {
- fprintf(stderr, "%s: must request at least %d bits.\n", argv[0],
- CHAR_BIT);
- return 1;
- }
-
- prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT;
-
- mp_init_size(&a, prec);
- mp_init_size(&c, 2 * prec);
-
- /* Test multiplication by self */
- srand(seed);
- start = clock();
- for(ix = 0; ix < ntests; ix++) {
- mpp_random_size(&a, prec);
- mp_mul(&a, &a, &c);
- }
- stop = clock();
-
- multime = (double)(stop - start) / CLOCKS_PER_SEC;
-
- /* Test squaring */
- srand(seed);
- start = clock();
- for(ix = 0; ix < ntests; ix++) {
- mpp_random_size(&a, prec);
- mp_sqr(&a, &c);
- }
- stop = clock();
-
- sqrtime = (double)(stop - start) / CLOCKS_PER_SEC;
-
- printf("Multiply: %.4f\n", multime);
- printf("Square: %.4f\n", sqrtime);
- if(multime < sqrtime) {
- printf("Speedup: %.1f%%\n", 100.0 * (1.0 - multime / sqrtime));
- printf("Prefer: multiply\n");
- } else {
- printf("Speedup: %.1f%%\n", 100.0 * (1.0 - sqrtime / multime));
- printf("Prefer: square\n");
- }
-
- mp_clear(&a); mp_clear(&c);
- return 0;
-
-}
diff --git a/security/nss/lib/freebl/mpi/multest b/security/nss/lib/freebl/mpi/multest
deleted file mode 100755
index 1c0287f1d..000000000
--- a/security/nss/lib/freebl/mpi/multest
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/sh
-#
-# multest
-#
-# Run multiply and square timing tests, to compute a chart for the
-# current processor and compiler combination.
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-#
-
-ECHO=/bin/echo
-MAKE=gmake
-
-$ECHO "\n** Running multiply and square timing tests\n"
-
-$ECHO "Bringing 'mulsqr' up to date ... "
-if $MAKE mulsqr ; then
- :
-else
- $ECHO "\nMake failed to build mulsqr.\n"
- exit 1
-fi
-
-if [ ! -x ./mulsqr ] ; then
- $ECHO "\nCannot find 'mulsqr' program, testing cannot continue.\n"
- exit 1
-fi
-
-sizes='64 128 192 256 320 384 448 512 640 768 896 1024 1536 2048'
-ntests=500000
-
-$ECHO "Running timing tests, please wait ... "
-
-trap 'echo "oop!";rm -f tt*.tmp;exit 0' INT HUP
-
-touch tt$$.tmp
-$ECHO $ntests tests >> tt$$.tmp
-for size in $sizes ; do
- $ECHO "$size bits ... \c"
- set -A res `./mulsqr $ntests $size|head -3|tr -d '%'|awk '{print $2}'`
- $ECHO $size"\t"${res[0]}"\t"${res[1]}"\t"${res[2]} >> tt$$.tmp
- $ECHO "(done)"
-done
-mv tt$$.tmp mulsqr-results.txt
-rm -f tt$$.tmp
-
-$ECHO "\n** Running Karatsuba-Ofman multiplication tests\n"
-
-$ECHO "Brining 'karatsuba' up to date ... "
-if $MAKE karatsuba ; then
- :
-else
- $ECHO "\nMake failed to build karatsuba.\n"
- exit 1
-fi
-
-if [ ! -x ./karatsuba ] ; then
- $ECHO "\nCannot find 'karatsuba' program, testing cannot continue.\n"
- exit 1
-fi
-
-ntests=100000
-
-trap 'echo "oop!";rm -f tt*.tmp;exit 0' INT HUP
-
-touch tt$$.tmp
-for size in $sizes ; do
- $ECHO "$size bits ... "
- ./karatsuba $ntests $size >> tt$$.tmp
- tail -2 tt$$.tmp
-done
-mv tt$$.tmp karatsuba-results.txt
-rm -f tt$$.tmp
-
-exit 0
diff --git a/security/nss/lib/freebl/mpi/primes.c b/security/nss/lib/freebl/mpi/primes.c
deleted file mode 100644
index 58536ad5a..000000000
--- a/security/nss/lib/freebl/mpi/primes.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
- * These tables of primes wwere generated using the 'sieve' program
- * (sieve.c) and converted to this format with 'ptab.pl'.
- *
- * The 'small' table is just the first 128 primes. The 'large' table
- * is a table of all the prime values that will fit into a single
- * mp_digit (given the current size of an mp_digit, which is two bytes).
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#if SMALL_TABLE
-#define MP_PRIME_TAB_SIZE 128
-#else
-#define MP_PRIME_TAB_SIZE 6542
-#endif
-
-const int prime_tab_size = MP_PRIME_TAB_SIZE;
-const mp_digit prime_tab[] = {
- 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
- 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
- 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
- 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083,
- 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
- 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
- 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
- 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
- 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
- 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
- 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
- 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
- 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
- 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
- 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
- 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
-#if ! SMALL_TABLE
- 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
- 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
- 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
- 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
- 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
- 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
- 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
- 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
- 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
- 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
- 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
- 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
- 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
- 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
- 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
- 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653,
- 0x0655, 0x065B, 0x0665, 0x0679, 0x067F, 0x0683, 0x0685, 0x069D,
- 0x06A1, 0x06A3, 0x06AD, 0x06B9, 0x06BB, 0x06C5, 0x06CD, 0x06D3,
- 0x06D9, 0x06DF, 0x06F1, 0x06F7, 0x06FB, 0x06FD, 0x0709, 0x0713,
- 0x071F, 0x0727, 0x0737, 0x0745, 0x074B, 0x074F, 0x0751, 0x0755,
- 0x0757, 0x0761, 0x076D, 0x0773, 0x0779, 0x078B, 0x078D, 0x079D,
- 0x079F, 0x07B5, 0x07BB, 0x07C3, 0x07C9, 0x07CD, 0x07CF, 0x07D3,
- 0x07DB, 0x07E1, 0x07EB, 0x07ED, 0x07F7, 0x0805, 0x080F, 0x0815,
- 0x0821, 0x0823, 0x0827, 0x0829, 0x0833, 0x083F, 0x0841, 0x0851,
- 0x0853, 0x0859, 0x085D, 0x085F, 0x0869, 0x0871, 0x0883, 0x089B,
- 0x089F, 0x08A5, 0x08AD, 0x08BD, 0x08BF, 0x08C3, 0x08CB, 0x08DB,
- 0x08DD, 0x08E1, 0x08E9, 0x08EF, 0x08F5, 0x08F9, 0x0905, 0x0907,
- 0x091D, 0x0923, 0x0925, 0x092B, 0x092F, 0x0935, 0x0943, 0x0949,
- 0x094D, 0x094F, 0x0955, 0x0959, 0x095F, 0x096B, 0x0971, 0x0977,
- 0x0985, 0x0989, 0x098F, 0x099B, 0x09A3, 0x09A9, 0x09AD, 0x09C7,
- 0x09D9, 0x09E3, 0x09EB, 0x09EF, 0x09F5, 0x09F7, 0x09FD, 0x0A13,
- 0x0A1F, 0x0A21, 0x0A31, 0x0A39, 0x0A3D, 0x0A49, 0x0A57, 0x0A61,
- 0x0A63, 0x0A67, 0x0A6F, 0x0A75, 0x0A7B, 0x0A7F, 0x0A81, 0x0A85,
- 0x0A8B, 0x0A93, 0x0A97, 0x0A99, 0x0A9F, 0x0AA9, 0x0AAB, 0x0AB5,
- 0x0ABD, 0x0AC1, 0x0ACF, 0x0AD9, 0x0AE5, 0x0AE7, 0x0AED, 0x0AF1,
- 0x0AF3, 0x0B03, 0x0B11, 0x0B15, 0x0B1B, 0x0B23, 0x0B29, 0x0B2D,
- 0x0B3F, 0x0B47, 0x0B51, 0x0B57, 0x0B5D, 0x0B65, 0x0B6F, 0x0B7B,
- 0x0B89, 0x0B8D, 0x0B93, 0x0B99, 0x0B9B, 0x0BB7, 0x0BB9, 0x0BC3,
- 0x0BCB, 0x0BCF, 0x0BDD, 0x0BE1, 0x0BE9, 0x0BF5, 0x0BFB, 0x0C07,
- 0x0C0B, 0x0C11, 0x0C25, 0x0C2F, 0x0C31, 0x0C41, 0x0C5B, 0x0C5F,
- 0x0C61, 0x0C6D, 0x0C73, 0x0C77, 0x0C83, 0x0C89, 0x0C91, 0x0C95,
- 0x0C9D, 0x0CB3, 0x0CB5, 0x0CB9, 0x0CBB, 0x0CC7, 0x0CE3, 0x0CE5,
- 0x0CEB, 0x0CF1, 0x0CF7, 0x0CFB, 0x0D01, 0x0D03, 0x0D0F, 0x0D13,
- 0x0D1F, 0x0D21, 0x0D2B, 0x0D2D, 0x0D3D, 0x0D3F, 0x0D4F, 0x0D55,
- 0x0D69, 0x0D79, 0x0D81, 0x0D85, 0x0D87, 0x0D8B, 0x0D8D, 0x0DA3,
- 0x0DAB, 0x0DB7, 0x0DBD, 0x0DC7, 0x0DC9, 0x0DCD, 0x0DD3, 0x0DD5,
- 0x0DDB, 0x0DE5, 0x0DE7, 0x0DF3, 0x0DFD, 0x0DFF, 0x0E09, 0x0E17,
- 0x0E1D, 0x0E21, 0x0E27, 0x0E2F, 0x0E35, 0x0E3B, 0x0E4B, 0x0E57,
- 0x0E59, 0x0E5D, 0x0E6B, 0x0E71, 0x0E75, 0x0E7D, 0x0E87, 0x0E8F,
- 0x0E95, 0x0E9B, 0x0EB1, 0x0EB7, 0x0EB9, 0x0EC3, 0x0ED1, 0x0ED5,
- 0x0EDB, 0x0EED, 0x0EEF, 0x0EF9, 0x0F07, 0x0F0B, 0x0F0D, 0x0F17,
- 0x0F25, 0x0F29, 0x0F31, 0x0F43, 0x0F47, 0x0F4D, 0x0F4F, 0x0F53,
- 0x0F59, 0x0F5B, 0x0F67, 0x0F6B, 0x0F7F, 0x0F95, 0x0FA1, 0x0FA3,
- 0x0FA7, 0x0FAD, 0x0FB3, 0x0FB5, 0x0FBB, 0x0FD1, 0x0FD3, 0x0FD9,
- 0x0FE9, 0x0FEF, 0x0FFB, 0x0FFD, 0x1003, 0x100F, 0x101F, 0x1021,
- 0x1025, 0x102B, 0x1039, 0x103D, 0x103F, 0x1051, 0x1069, 0x1073,
- 0x1079, 0x107B, 0x1085, 0x1087, 0x1091, 0x1093, 0x109D, 0x10A3,
- 0x10A5, 0x10AF, 0x10B1, 0x10BB, 0x10C1, 0x10C9, 0x10E7, 0x10F1,
- 0x10F3, 0x10FD, 0x1105, 0x110B, 0x1115, 0x1127, 0x112D, 0x1139,
- 0x1145, 0x1147, 0x1159, 0x115F, 0x1163, 0x1169, 0x116F, 0x1181,
- 0x1183, 0x118D, 0x119B, 0x11A1, 0x11A5, 0x11A7, 0x11AB, 0x11C3,
- 0x11C5, 0x11D1, 0x11D7, 0x11E7, 0x11EF, 0x11F5, 0x11FB, 0x120D,
- 0x121D, 0x121F, 0x1223, 0x1229, 0x122B, 0x1231, 0x1237, 0x1241,
- 0x1247, 0x1253, 0x125F, 0x1271, 0x1273, 0x1279, 0x127D, 0x128F,
- 0x1297, 0x12AF, 0x12B3, 0x12B5, 0x12B9, 0x12BF, 0x12C1, 0x12CD,
- 0x12D1, 0x12DF, 0x12FD, 0x1307, 0x130D, 0x1319, 0x1327, 0x132D,
- 0x1337, 0x1343, 0x1345, 0x1349, 0x134F, 0x1357, 0x135D, 0x1367,
- 0x1369, 0x136D, 0x137B, 0x1381, 0x1387, 0x138B, 0x1391, 0x1393,
- 0x139D, 0x139F, 0x13AF, 0x13BB, 0x13C3, 0x13D5, 0x13D9, 0x13DF,
- 0x13EB, 0x13ED, 0x13F3, 0x13F9, 0x13FF, 0x141B, 0x1421, 0x142F,
- 0x1433, 0x143B, 0x1445, 0x144D, 0x1459, 0x146B, 0x146F, 0x1471,
- 0x1475, 0x148D, 0x1499, 0x149F, 0x14A1, 0x14B1, 0x14B7, 0x14BD,
- 0x14CB, 0x14D5, 0x14E3, 0x14E7, 0x1505, 0x150B, 0x1511, 0x1517,
- 0x151F, 0x1525, 0x1529, 0x152B, 0x1537, 0x153D, 0x1541, 0x1543,
- 0x1549, 0x155F, 0x1565, 0x1567, 0x156B, 0x157D, 0x157F, 0x1583,
- 0x158F, 0x1591, 0x1597, 0x159B, 0x15B5, 0x15BB, 0x15C1, 0x15C5,
- 0x15CD, 0x15D7, 0x15F7, 0x1607, 0x1609, 0x160F, 0x1613, 0x1615,
- 0x1619, 0x161B, 0x1625, 0x1633, 0x1639, 0x163D, 0x1645, 0x164F,
- 0x1655, 0x1669, 0x166D, 0x166F, 0x1675, 0x1693, 0x1697, 0x169F,
- 0x16A9, 0x16AF, 0x16B5, 0x16BD, 0x16C3, 0x16CF, 0x16D3, 0x16D9,
- 0x16DB, 0x16E1, 0x16E5, 0x16EB, 0x16ED, 0x16F7, 0x16F9, 0x1709,
- 0x170F, 0x1723, 0x1727, 0x1733, 0x1741, 0x175D, 0x1763, 0x1777,
- 0x177B, 0x178D, 0x1795, 0x179B, 0x179F, 0x17A5, 0x17B3, 0x17B9,
- 0x17BF, 0x17C9, 0x17CB, 0x17D5, 0x17E1, 0x17E9, 0x17F3, 0x17F5,
- 0x17FF, 0x1807, 0x1813, 0x181D, 0x1835, 0x1837, 0x183B, 0x1843,
- 0x1849, 0x184D, 0x1855, 0x1867, 0x1871, 0x1877, 0x187D, 0x187F,
- 0x1885, 0x188F, 0x189B, 0x189D, 0x18A7, 0x18AD, 0x18B3, 0x18B9,
- 0x18C1, 0x18C7, 0x18D1, 0x18D7, 0x18D9, 0x18DF, 0x18E5, 0x18EB,
- 0x18F5, 0x18FD, 0x1915, 0x191B, 0x1931, 0x1933, 0x1945, 0x1949,
- 0x1951, 0x195B, 0x1979, 0x1981, 0x1993, 0x1997, 0x1999, 0x19A3,
- 0x19A9, 0x19AB, 0x19B1, 0x19B5, 0x19C7, 0x19CF, 0x19DB, 0x19ED,
- 0x19FD, 0x1A03, 0x1A05, 0x1A11, 0x1A17, 0x1A21, 0x1A23, 0x1A2D,
- 0x1A2F, 0x1A35, 0x1A3F, 0x1A4D, 0x1A51, 0x1A69, 0x1A6B, 0x1A7B,
- 0x1A7D, 0x1A87, 0x1A89, 0x1A93, 0x1AA7, 0x1AAB, 0x1AAD, 0x1AB1,
- 0x1AB9, 0x1AC9, 0x1ACF, 0x1AD5, 0x1AD7, 0x1AE3, 0x1AF3, 0x1AFB,
- 0x1AFF, 0x1B05, 0x1B23, 0x1B25, 0x1B2F, 0x1B31, 0x1B37, 0x1B3B,
- 0x1B41, 0x1B47, 0x1B4F, 0x1B55, 0x1B59, 0x1B65, 0x1B6B, 0x1B73,
- 0x1B7F, 0x1B83, 0x1B91, 0x1B9D, 0x1BA7, 0x1BBF, 0x1BC5, 0x1BD1,
- 0x1BD7, 0x1BD9, 0x1BEF, 0x1BF7, 0x1C09, 0x1C13, 0x1C19, 0x1C27,
- 0x1C2B, 0x1C2D, 0x1C33, 0x1C3D, 0x1C45, 0x1C4B, 0x1C4F, 0x1C55,
- 0x1C73, 0x1C81, 0x1C8B, 0x1C8D, 0x1C99, 0x1CA3, 0x1CA5, 0x1CB5,
- 0x1CB7, 0x1CC9, 0x1CE1, 0x1CF3, 0x1CF9, 0x1D09, 0x1D1B, 0x1D21,
- 0x1D23, 0x1D35, 0x1D39, 0x1D3F, 0x1D41, 0x1D4B, 0x1D53, 0x1D5D,
- 0x1D63, 0x1D69, 0x1D71, 0x1D75, 0x1D7B, 0x1D7D, 0x1D87, 0x1D89,
- 0x1D95, 0x1D99, 0x1D9F, 0x1DA5, 0x1DA7, 0x1DB3, 0x1DB7, 0x1DC5,
- 0x1DD7, 0x1DDB, 0x1DE1, 0x1DF5, 0x1DF9, 0x1E01, 0x1E07, 0x1E0B,
- 0x1E13, 0x1E17, 0x1E25, 0x1E2B, 0x1E2F, 0x1E3D, 0x1E49, 0x1E4D,
- 0x1E4F, 0x1E6D, 0x1E71, 0x1E89, 0x1E8F, 0x1E95, 0x1EA1, 0x1EAD,
- 0x1EBB, 0x1EC1, 0x1EC5, 0x1EC7, 0x1ECB, 0x1EDD, 0x1EE3, 0x1EEF,
- 0x1EF7, 0x1EFD, 0x1F01, 0x1F0D, 0x1F0F, 0x1F1B, 0x1F39, 0x1F49,
- 0x1F4B, 0x1F51, 0x1F67, 0x1F75, 0x1F7B, 0x1F85, 0x1F91, 0x1F97,
- 0x1F99, 0x1F9D, 0x1FA5, 0x1FAF, 0x1FB5, 0x1FBB, 0x1FD3, 0x1FE1,
- 0x1FE7, 0x1FEB, 0x1FF3, 0x1FFF, 0x2011, 0x201B, 0x201D, 0x2027,
- 0x2029, 0x202D, 0x2033, 0x2047, 0x204D, 0x2051, 0x205F, 0x2063,
- 0x2065, 0x2069, 0x2077, 0x207D, 0x2089, 0x20A1, 0x20AB, 0x20B1,
- 0x20B9, 0x20C3, 0x20C5, 0x20E3, 0x20E7, 0x20ED, 0x20EF, 0x20FB,
- 0x20FF, 0x210D, 0x2113, 0x2135, 0x2141, 0x2149, 0x214F, 0x2159,
- 0x215B, 0x215F, 0x2173, 0x217D, 0x2185, 0x2195, 0x2197, 0x21A1,
- 0x21AF, 0x21B3, 0x21B5, 0x21C1, 0x21C7, 0x21D7, 0x21DD, 0x21E5,
- 0x21E9, 0x21F1, 0x21F5, 0x21FB, 0x2203, 0x2209, 0x220F, 0x221B,
- 0x2221, 0x2225, 0x222B, 0x2231, 0x2239, 0x224B, 0x224F, 0x2263,
- 0x2267, 0x2273, 0x2275, 0x227F, 0x2285, 0x2287, 0x2291, 0x229D,
- 0x229F, 0x22A3, 0x22B7, 0x22BD, 0x22DB, 0x22E1, 0x22E5, 0x22ED,
- 0x22F7, 0x2303, 0x2309, 0x230B, 0x2327, 0x2329, 0x232F, 0x2333,
- 0x2335, 0x2345, 0x2351, 0x2353, 0x2359, 0x2363, 0x236B, 0x2383,
- 0x238F, 0x2395, 0x23A7, 0x23AD, 0x23B1, 0x23BF, 0x23C5, 0x23C9,
- 0x23D5, 0x23DD, 0x23E3, 0x23EF, 0x23F3, 0x23F9, 0x2405, 0x240B,
- 0x2417, 0x2419, 0x2429, 0x243D, 0x2441, 0x2443, 0x244D, 0x245F,
- 0x2467, 0x246B, 0x2479, 0x247D, 0x247F, 0x2485, 0x249B, 0x24A1,
- 0x24AF, 0x24B5, 0x24BB, 0x24C5, 0x24CB, 0x24CD, 0x24D7, 0x24D9,
- 0x24DD, 0x24DF, 0x24F5, 0x24F7, 0x24FB, 0x2501, 0x2507, 0x2513,
- 0x2519, 0x2527, 0x2531, 0x253D, 0x2543, 0x254B, 0x254F, 0x2573,
- 0x2581, 0x258D, 0x2593, 0x2597, 0x259D, 0x259F, 0x25AB, 0x25B1,
- 0x25BD, 0x25CD, 0x25CF, 0x25D9, 0x25E1, 0x25F7, 0x25F9, 0x2605,
- 0x260B, 0x260F, 0x2615, 0x2627, 0x2629, 0x2635, 0x263B, 0x263F,
- 0x264B, 0x2653, 0x2659, 0x2665, 0x2669, 0x266F, 0x267B, 0x2681,
- 0x2683, 0x268F, 0x269B, 0x269F, 0x26AD, 0x26B3, 0x26C3, 0x26C9,
- 0x26CB, 0x26D5, 0x26DD, 0x26EF, 0x26F5, 0x2717, 0x2719, 0x2735,
- 0x2737, 0x274D, 0x2753, 0x2755, 0x275F, 0x276B, 0x276D, 0x2773,
- 0x2777, 0x277F, 0x2795, 0x279B, 0x279D, 0x27A7, 0x27AF, 0x27B3,
- 0x27B9, 0x27C1, 0x27C5, 0x27D1, 0x27E3, 0x27EF, 0x2803, 0x2807,
- 0x280D, 0x2813, 0x281B, 0x281F, 0x2821, 0x2831, 0x283D, 0x283F,
- 0x2849, 0x2851, 0x285B, 0x285D, 0x2861, 0x2867, 0x2875, 0x2881,
- 0x2897, 0x289F, 0x28BB, 0x28BD, 0x28C1, 0x28D5, 0x28D9, 0x28DB,
- 0x28DF, 0x28ED, 0x28F7, 0x2903, 0x2905, 0x2911, 0x2921, 0x2923,
- 0x293F, 0x2947, 0x295D, 0x2965, 0x2969, 0x296F, 0x2975, 0x2983,
- 0x2987, 0x298F, 0x299B, 0x29A1, 0x29A7, 0x29AB, 0x29BF, 0x29C3,
- 0x29D5, 0x29D7, 0x29E3, 0x29E9, 0x29ED, 0x29F3, 0x2A01, 0x2A13,
- 0x2A1D, 0x2A25, 0x2A2F, 0x2A4F, 0x2A55, 0x2A5F, 0x2A65, 0x2A6B,
- 0x2A6D, 0x2A73, 0x2A83, 0x2A89, 0x2A8B, 0x2A97, 0x2A9D, 0x2AB9,
- 0x2ABB, 0x2AC5, 0x2ACD, 0x2ADD, 0x2AE3, 0x2AEB, 0x2AF1, 0x2AFB,
- 0x2B13, 0x2B27, 0x2B31, 0x2B33, 0x2B3D, 0x2B3F, 0x2B4B, 0x2B4F,
- 0x2B55, 0x2B69, 0x2B6D, 0x2B6F, 0x2B7B, 0x2B8D, 0x2B97, 0x2B99,
- 0x2BA3, 0x2BA5, 0x2BA9, 0x2BBD, 0x2BCD, 0x2BE7, 0x2BEB, 0x2BF3,
- 0x2BF9, 0x2BFD, 0x2C09, 0x2C0F, 0x2C17, 0x2C23, 0x2C2F, 0x2C35,
- 0x2C39, 0x2C41, 0x2C57, 0x2C59, 0x2C69, 0x2C77, 0x2C81, 0x2C87,
- 0x2C93, 0x2C9F, 0x2CAD, 0x2CB3, 0x2CB7, 0x2CCB, 0x2CCF, 0x2CDB,
- 0x2CE1, 0x2CE3, 0x2CE9, 0x2CEF, 0x2CFF, 0x2D07, 0x2D1D, 0x2D1F,
- 0x2D3B, 0x2D43, 0x2D49, 0x2D4D, 0x2D61, 0x2D65, 0x2D71, 0x2D89,
- 0x2D9D, 0x2DA1, 0x2DA9, 0x2DB3, 0x2DB5, 0x2DC5, 0x2DC7, 0x2DD3,
- 0x2DDF, 0x2E01, 0x2E03, 0x2E07, 0x2E0D, 0x2E19, 0x2E1F, 0x2E25,
- 0x2E2D, 0x2E33, 0x2E37, 0x2E39, 0x2E3F, 0x2E57, 0x2E5B, 0x2E6F,
- 0x2E79, 0x2E7F, 0x2E85, 0x2E93, 0x2E97, 0x2E9D, 0x2EA3, 0x2EA5,
- 0x2EB1, 0x2EB7, 0x2EC1, 0x2EC3, 0x2ECD, 0x2ED3, 0x2EE7, 0x2EEB,
- 0x2F05, 0x2F09, 0x2F0B, 0x2F11, 0x2F27, 0x2F29, 0x2F41, 0x2F45,
- 0x2F4B, 0x2F4D, 0x2F51, 0x2F57, 0x2F6F, 0x2F75, 0x2F7D, 0x2F81,
- 0x2F83, 0x2FA5, 0x2FAB, 0x2FB3, 0x2FC3, 0x2FCF, 0x2FD1, 0x2FDB,
- 0x2FDD, 0x2FE7, 0x2FED, 0x2FF5, 0x2FF9, 0x3001, 0x300D, 0x3023,
- 0x3029, 0x3037, 0x303B, 0x3055, 0x3059, 0x305B, 0x3067, 0x3071,
- 0x3079, 0x307D, 0x3085, 0x3091, 0x3095, 0x30A3, 0x30A9, 0x30B9,
- 0x30BF, 0x30C7, 0x30CB, 0x30D1, 0x30D7, 0x30DF, 0x30E5, 0x30EF,
- 0x30FB, 0x30FD, 0x3103, 0x3109, 0x3119, 0x3121, 0x3127, 0x312D,
- 0x3139, 0x3143, 0x3145, 0x314B, 0x315D, 0x3161, 0x3167, 0x316D,
- 0x3173, 0x317F, 0x3191, 0x3199, 0x319F, 0x31A9, 0x31B1, 0x31C3,
- 0x31C7, 0x31D5, 0x31DB, 0x31ED, 0x31F7, 0x31FF, 0x3209, 0x3215,
- 0x3217, 0x321D, 0x3229, 0x3235, 0x3259, 0x325D, 0x3263, 0x326B,
- 0x326F, 0x3275, 0x3277, 0x327B, 0x328D, 0x3299, 0x329F, 0x32A7,
- 0x32AD, 0x32B3, 0x32B7, 0x32C9, 0x32CB, 0x32CF, 0x32D1, 0x32E9,
- 0x32ED, 0x32F3, 0x32F9, 0x3307, 0x3325, 0x332B, 0x332F, 0x3335,
- 0x3341, 0x3347, 0x335B, 0x335F, 0x3367, 0x336B, 0x3373, 0x3379,
- 0x337F, 0x3383, 0x33A1, 0x33A3, 0x33AD, 0x33B9, 0x33C1, 0x33CB,
- 0x33D3, 0x33EB, 0x33F1, 0x33FD, 0x3401, 0x340F, 0x3413, 0x3419,
- 0x341B, 0x3437, 0x3445, 0x3455, 0x3457, 0x3463, 0x3469, 0x346D,
- 0x3481, 0x348B, 0x3491, 0x3497, 0x349D, 0x34A5, 0x34AF, 0x34BB,
- 0x34C9, 0x34D3, 0x34E1, 0x34F1, 0x34FF, 0x3509, 0x3517, 0x351D,
- 0x352D, 0x3533, 0x353B, 0x3541, 0x3551, 0x3565, 0x356F, 0x3571,
- 0x3577, 0x357B, 0x357D, 0x3581, 0x358D, 0x358F, 0x3599, 0x359B,
- 0x35A1, 0x35B7, 0x35BD, 0x35BF, 0x35C3, 0x35D5, 0x35DD, 0x35E7,
- 0x35EF, 0x3605, 0x3607, 0x3611, 0x3623, 0x3631, 0x3635, 0x3637,
- 0x363B, 0x364D, 0x364F, 0x3653, 0x3659, 0x3661, 0x366B, 0x366D,
- 0x368B, 0x368F, 0x36AD, 0x36AF, 0x36B9, 0x36BB, 0x36CD, 0x36D1,
- 0x36E3, 0x36E9, 0x36F7, 0x3701, 0x3703, 0x3707, 0x371B, 0x373F,
- 0x3745, 0x3749, 0x374F, 0x375D, 0x3761, 0x3775, 0x377F, 0x378D,
- 0x37A3, 0x37A9, 0x37AB, 0x37C9, 0x37D5, 0x37DF, 0x37F1, 0x37F3,
- 0x37F7, 0x3805, 0x380B, 0x3821, 0x3833, 0x3835, 0x3841, 0x3847,
- 0x384B, 0x3853, 0x3857, 0x385F, 0x3865, 0x386F, 0x3871, 0x387D,
- 0x388F, 0x3899, 0x38A7, 0x38B7, 0x38C5, 0x38C9, 0x38CF, 0x38D5,
- 0x38D7, 0x38DD, 0x38E1, 0x38E3, 0x38FF, 0x3901, 0x391D, 0x3923,
- 0x3925, 0x3929, 0x392F, 0x393D, 0x3941, 0x394D, 0x395B, 0x396B,
- 0x3979, 0x397D, 0x3983, 0x398B, 0x3991, 0x3995, 0x399B, 0x39A1,
- 0x39A7, 0x39AF, 0x39B3, 0x39BB, 0x39BF, 0x39CD, 0x39DD, 0x39E5,
- 0x39EB, 0x39EF, 0x39FB, 0x3A03, 0x3A13, 0x3A15, 0x3A1F, 0x3A27,
- 0x3A2B, 0x3A31, 0x3A4B, 0x3A51, 0x3A5B, 0x3A63, 0x3A67, 0x3A6D,
- 0x3A79, 0x3A87, 0x3AA5, 0x3AA9, 0x3AB7, 0x3ACD, 0x3AD5, 0x3AE1,
- 0x3AE5, 0x3AEB, 0x3AF3, 0x3AFD, 0x3B03, 0x3B11, 0x3B1B, 0x3B21,
- 0x3B23, 0x3B2D, 0x3B39, 0x3B45, 0x3B53, 0x3B59, 0x3B5F, 0x3B71,
- 0x3B7B, 0x3B81, 0x3B89, 0x3B9B, 0x3B9F, 0x3BA5, 0x3BA7, 0x3BAD,
- 0x3BB7, 0x3BB9, 0x3BC3, 0x3BCB, 0x3BD1, 0x3BD7, 0x3BE1, 0x3BE3,
- 0x3BF5, 0x3BFF, 0x3C01, 0x3C0D, 0x3C11, 0x3C17, 0x3C1F, 0x3C29,
- 0x3C35, 0x3C43, 0x3C4F, 0x3C53, 0x3C5B, 0x3C65, 0x3C6B, 0x3C71,
- 0x3C85, 0x3C89, 0x3C97, 0x3CA7, 0x3CB5, 0x3CBF, 0x3CC7, 0x3CD1,
- 0x3CDD, 0x3CDF, 0x3CF1, 0x3CF7, 0x3D03, 0x3D0D, 0x3D19, 0x3D1B,
- 0x3D1F, 0x3D21, 0x3D2D, 0x3D33, 0x3D37, 0x3D3F, 0x3D43, 0x3D6F,
- 0x3D73, 0x3D75, 0x3D79, 0x3D7B, 0x3D85, 0x3D91, 0x3D97, 0x3D9D,
- 0x3DAB, 0x3DAF, 0x3DB5, 0x3DBB, 0x3DC1, 0x3DC9, 0x3DCF, 0x3DF3,
- 0x3E05, 0x3E09, 0x3E0F, 0x3E11, 0x3E1D, 0x3E23, 0x3E29, 0x3E2F,
- 0x3E33, 0x3E41, 0x3E57, 0x3E63, 0x3E65, 0x3E77, 0x3E81, 0x3E87,
- 0x3EA1, 0x3EB9, 0x3EBD, 0x3EBF, 0x3EC3, 0x3EC5, 0x3EC9, 0x3ED7,
- 0x3EDB, 0x3EE1, 0x3EE7, 0x3EEF, 0x3EFF, 0x3F0B, 0x3F0D, 0x3F37,
- 0x3F3B, 0x3F3D, 0x3F41, 0x3F59, 0x3F5F, 0x3F65, 0x3F67, 0x3F79,
- 0x3F7D, 0x3F8B, 0x3F91, 0x3FAD, 0x3FBF, 0x3FCD, 0x3FD3, 0x3FDD,
- 0x3FE9, 0x3FEB, 0x3FF1, 0x3FFD, 0x401B, 0x4021, 0x4025, 0x402B,
- 0x4031, 0x403F, 0x4043, 0x4045, 0x405D, 0x4061, 0x4067, 0x406D,
- 0x4087, 0x4091, 0x40A3, 0x40A9, 0x40B1, 0x40B7, 0x40BD, 0x40DB,
- 0x40DF, 0x40EB, 0x40F7, 0x40F9, 0x4109, 0x410B, 0x4111, 0x4115,
- 0x4121, 0x4133, 0x4135, 0x413B, 0x413F, 0x4159, 0x4165, 0x416B,
- 0x4177, 0x417B, 0x4193, 0x41AB, 0x41B7, 0x41BD, 0x41BF, 0x41CB,
- 0x41E7, 0x41EF, 0x41F3, 0x41F9, 0x4205, 0x4207, 0x4219, 0x421F,
- 0x4223, 0x4229, 0x422F, 0x4243, 0x4253, 0x4255, 0x425B, 0x4261,
- 0x4273, 0x427D, 0x4283, 0x4285, 0x4289, 0x4291, 0x4297, 0x429D,
- 0x42B5, 0x42C5, 0x42CB, 0x42D3, 0x42DD, 0x42E3, 0x42F1, 0x4307,
- 0x430F, 0x431F, 0x4325, 0x4327, 0x4333, 0x4337, 0x4339, 0x434F,
- 0x4357, 0x4369, 0x438B, 0x438D, 0x4393, 0x43A5, 0x43A9, 0x43AF,
- 0x43B5, 0x43BD, 0x43C7, 0x43CF, 0x43E1, 0x43E7, 0x43EB, 0x43ED,
- 0x43F1, 0x43F9, 0x4409, 0x440B, 0x4417, 0x4423, 0x4429, 0x443B,
- 0x443F, 0x4445, 0x444B, 0x4451, 0x4453, 0x4459, 0x4465, 0x446F,
- 0x4483, 0x448F, 0x44A1, 0x44A5, 0x44AB, 0x44AD, 0x44BD, 0x44BF,
- 0x44C9, 0x44D7, 0x44DB, 0x44F9, 0x44FB, 0x4505, 0x4511, 0x4513,
- 0x452B, 0x4531, 0x4541, 0x4549, 0x4553, 0x4555, 0x4561, 0x4577,
- 0x457D, 0x457F, 0x458F, 0x45A3, 0x45AD, 0x45AF, 0x45BB, 0x45C7,
- 0x45D9, 0x45E3, 0x45EF, 0x45F5, 0x45F7, 0x4601, 0x4603, 0x4609,
- 0x4613, 0x4625, 0x4627, 0x4633, 0x4639, 0x463D, 0x4643, 0x4645,
- 0x465D, 0x4679, 0x467B, 0x467F, 0x4681, 0x468B, 0x468D, 0x469D,
- 0x46A9, 0x46B1, 0x46C7, 0x46C9, 0x46CF, 0x46D3, 0x46D5, 0x46DF,
- 0x46E5, 0x46F9, 0x4705, 0x470F, 0x4717, 0x4723, 0x4729, 0x472F,
- 0x4735, 0x4739, 0x474B, 0x474D, 0x4751, 0x475D, 0x476F, 0x4771,
- 0x477D, 0x4783, 0x4787, 0x4789, 0x4799, 0x47A5, 0x47B1, 0x47BF,
- 0x47C3, 0x47CB, 0x47DD, 0x47E1, 0x47ED, 0x47FB, 0x4801, 0x4807,
- 0x480B, 0x4813, 0x4819, 0x481D, 0x4831, 0x483D, 0x4847, 0x4855,
- 0x4859, 0x485B, 0x486B, 0x486D, 0x4879, 0x4897, 0x489B, 0x48A1,
- 0x48B9, 0x48CD, 0x48E5, 0x48EF, 0x48F7, 0x4903, 0x490D, 0x4919,
- 0x491F, 0x492B, 0x4937, 0x493D, 0x4945, 0x4955, 0x4963, 0x4969,
- 0x496D, 0x4973, 0x4997, 0x49AB, 0x49B5, 0x49D3, 0x49DF, 0x49E1,
- 0x49E5, 0x49E7, 0x4A03, 0x4A0F, 0x4A1D, 0x4A23, 0x4A39, 0x4A41,
- 0x4A45, 0x4A57, 0x4A5D, 0x4A6B, 0x4A7D, 0x4A81, 0x4A87, 0x4A89,
- 0x4A8F, 0x4AB1, 0x4AC3, 0x4AC5, 0x4AD5, 0x4ADB, 0x4AED, 0x4AEF,
- 0x4B07, 0x4B0B, 0x4B0D, 0x4B13, 0x4B1F, 0x4B25, 0x4B31, 0x4B3B,
- 0x4B43, 0x4B49, 0x4B59, 0x4B65, 0x4B6D, 0x4B77, 0x4B85, 0x4BAD,
- 0x4BB3, 0x4BB5, 0x4BBB, 0x4BBF, 0x4BCB, 0x4BD9, 0x4BDD, 0x4BDF,
- 0x4BE3, 0x4BE5, 0x4BE9, 0x4BF1, 0x4BF7, 0x4C01, 0x4C07, 0x4C0D,
- 0x4C0F, 0x4C15, 0x4C1B, 0x4C21, 0x4C2D, 0x4C33, 0x4C4B, 0x4C55,
- 0x4C57, 0x4C61, 0x4C67, 0x4C73, 0x4C79, 0x4C7F, 0x4C8D, 0x4C93,
- 0x4C99, 0x4CCD, 0x4CE1, 0x4CE7, 0x4CF1, 0x4CF3, 0x4CFD, 0x4D05,
- 0x4D0F, 0x4D1B, 0x4D27, 0x4D29, 0x4D2F, 0x4D33, 0x4D41, 0x4D51,
- 0x4D59, 0x4D65, 0x4D6B, 0x4D81, 0x4D83, 0x4D8D, 0x4D95, 0x4D9B,
- 0x4DB1, 0x4DB3, 0x4DC9, 0x4DCF, 0x4DD7, 0x4DE1, 0x4DED, 0x4DF9,
- 0x4DFB, 0x4E05, 0x4E0B, 0x4E17, 0x4E19, 0x4E1D, 0x4E2B, 0x4E35,
- 0x4E37, 0x4E3D, 0x4E4F, 0x4E53, 0x4E5F, 0x4E67, 0x4E79, 0x4E85,
- 0x4E8B, 0x4E91, 0x4E95, 0x4E9B, 0x4EA1, 0x4EAF, 0x4EB3, 0x4EB5,
- 0x4EC1, 0x4ECD, 0x4ED1, 0x4ED7, 0x4EE9, 0x4EFB, 0x4F07, 0x4F09,
- 0x4F19, 0x4F25, 0x4F2D, 0x4F3F, 0x4F49, 0x4F63, 0x4F67, 0x4F6D,
- 0x4F75, 0x4F7B, 0x4F81, 0x4F85, 0x4F87, 0x4F91, 0x4FA5, 0x4FA9,
- 0x4FAF, 0x4FB7, 0x4FBB, 0x4FCF, 0x4FD9, 0x4FDB, 0x4FFD, 0x4FFF,
- 0x5003, 0x501B, 0x501D, 0x5029, 0x5035, 0x503F, 0x5045, 0x5047,
- 0x5053, 0x5071, 0x5077, 0x5083, 0x5093, 0x509F, 0x50A1, 0x50B7,
- 0x50C9, 0x50D5, 0x50E3, 0x50ED, 0x50EF, 0x50FB, 0x5107, 0x510B,
- 0x510D, 0x5111, 0x5117, 0x5123, 0x5125, 0x5135, 0x5147, 0x5149,
- 0x5171, 0x5179, 0x5189, 0x518F, 0x5197, 0x51A1, 0x51A3, 0x51A7,
- 0x51B9, 0x51C1, 0x51CB, 0x51D3, 0x51DF, 0x51E3, 0x51F5, 0x51F7,
- 0x5209, 0x5213, 0x5215, 0x5219, 0x521B, 0x521F, 0x5227, 0x5243,
- 0x5245, 0x524B, 0x5261, 0x526D, 0x5273, 0x5281, 0x5293, 0x5297,
- 0x529D, 0x52A5, 0x52AB, 0x52B1, 0x52BB, 0x52C3, 0x52C7, 0x52C9,
- 0x52DB, 0x52E5, 0x52EB, 0x52FF, 0x5315, 0x531D, 0x5323, 0x5341,
- 0x5345, 0x5347, 0x534B, 0x535D, 0x5363, 0x5381, 0x5383, 0x5387,
- 0x538F, 0x5395, 0x5399, 0x539F, 0x53AB, 0x53B9, 0x53DB, 0x53E9,
- 0x53EF, 0x53F3, 0x53F5, 0x53FB, 0x53FF, 0x540D, 0x5411, 0x5413,
- 0x5419, 0x5435, 0x5437, 0x543B, 0x5441, 0x5449, 0x5453, 0x5455,
- 0x545F, 0x5461, 0x546B, 0x546D, 0x5471, 0x548F, 0x5491, 0x549D,
- 0x54A9, 0x54B3, 0x54C5, 0x54D1, 0x54DF, 0x54E9, 0x54EB, 0x54F7,
- 0x54FD, 0x5507, 0x550D, 0x551B, 0x5527, 0x552B, 0x5539, 0x553D,
- 0x554F, 0x5551, 0x555B, 0x5563, 0x5567, 0x556F, 0x5579, 0x5585,
- 0x5597, 0x55A9, 0x55B1, 0x55B7, 0x55C9, 0x55D9, 0x55E7, 0x55ED,
- 0x55F3, 0x55FD, 0x560B, 0x560F, 0x5615, 0x5617, 0x5623, 0x562F,
- 0x5633, 0x5639, 0x563F, 0x564B, 0x564D, 0x565D, 0x565F, 0x566B,
- 0x5671, 0x5675, 0x5683, 0x5689, 0x568D, 0x568F, 0x569B, 0x56AD,
- 0x56B1, 0x56D5, 0x56E7, 0x56F3, 0x56FF, 0x5701, 0x5705, 0x5707,
- 0x570B, 0x5713, 0x571F, 0x5723, 0x5747, 0x574D, 0x575F, 0x5761,
- 0x576D, 0x5777, 0x577D, 0x5789, 0x57A1, 0x57A9, 0x57AF, 0x57B5,
- 0x57C5, 0x57D1, 0x57D3, 0x57E5, 0x57EF, 0x5803, 0x580D, 0x580F,
- 0x5815, 0x5827, 0x582B, 0x582D, 0x5855, 0x585B, 0x585D, 0x586D,
- 0x586F, 0x5873, 0x587B, 0x588D, 0x5897, 0x58A3, 0x58A9, 0x58AB,
- 0x58B5, 0x58BD, 0x58C1, 0x58C7, 0x58D3, 0x58D5, 0x58DF, 0x58F1,
- 0x58F9, 0x58FF, 0x5903, 0x5917, 0x591B, 0x5921, 0x5945, 0x594B,
- 0x594D, 0x5957, 0x595D, 0x5975, 0x597B, 0x5989, 0x5999, 0x599F,
- 0x59B1, 0x59B3, 0x59BD, 0x59D1, 0x59DB, 0x59E3, 0x59E9, 0x59ED,
- 0x59F3, 0x59F5, 0x59FF, 0x5A01, 0x5A0D, 0x5A11, 0x5A13, 0x5A17,
- 0x5A1F, 0x5A29, 0x5A2F, 0x5A3B, 0x5A4D, 0x5A5B, 0x5A67, 0x5A77,
- 0x5A7F, 0x5A85, 0x5A95, 0x5A9D, 0x5AA1, 0x5AA3, 0x5AA9, 0x5ABB,
- 0x5AD3, 0x5AE5, 0x5AEF, 0x5AFB, 0x5AFD, 0x5B01, 0x5B0F, 0x5B19,
- 0x5B1F, 0x5B25, 0x5B2B, 0x5B3D, 0x5B49, 0x5B4B, 0x5B67, 0x5B79,
- 0x5B87, 0x5B97, 0x5BA3, 0x5BB1, 0x5BC9, 0x5BD5, 0x5BEB, 0x5BF1,
- 0x5BF3, 0x5BFD, 0x5C05, 0x5C09, 0x5C0B, 0x5C0F, 0x5C1D, 0x5C29,
- 0x5C2F, 0x5C33, 0x5C39, 0x5C47, 0x5C4B, 0x5C4D, 0x5C51, 0x5C6F,
- 0x5C75, 0x5C77, 0x5C7D, 0x5C87, 0x5C89, 0x5CA7, 0x5CBD, 0x5CBF,
- 0x5CC3, 0x5CC9, 0x5CD1, 0x5CD7, 0x5CDD, 0x5CED, 0x5CF9, 0x5D05,
- 0x5D0B, 0x5D13, 0x5D17, 0x5D19, 0x5D31, 0x5D3D, 0x5D41, 0x5D47,
- 0x5D4F, 0x5D55, 0x5D5B, 0x5D65, 0x5D67, 0x5D6D, 0x5D79, 0x5D95,
- 0x5DA3, 0x5DA9, 0x5DAD, 0x5DB9, 0x5DC1, 0x5DC7, 0x5DD3, 0x5DD7,
- 0x5DDD, 0x5DEB, 0x5DF1, 0x5DFD, 0x5E07, 0x5E0D, 0x5E13, 0x5E1B,
- 0x5E21, 0x5E27, 0x5E2B, 0x5E2D, 0x5E31, 0x5E39, 0x5E45, 0x5E49,
- 0x5E57, 0x5E69, 0x5E73, 0x5E75, 0x5E85, 0x5E8B, 0x5E9F, 0x5EA5,
- 0x5EAF, 0x5EB7, 0x5EBB, 0x5ED9, 0x5EFD, 0x5F09, 0x5F11, 0x5F27,
- 0x5F33, 0x5F35, 0x5F3B, 0x5F47, 0x5F57, 0x5F5D, 0x5F63, 0x5F65,
- 0x5F77, 0x5F7B, 0x5F95, 0x5F99, 0x5FA1, 0x5FB3, 0x5FBD, 0x5FC5,
- 0x5FCF, 0x5FD5, 0x5FE3, 0x5FE7, 0x5FFB, 0x6011, 0x6023, 0x602F,
- 0x6037, 0x6053, 0x605F, 0x6065, 0x606B, 0x6073, 0x6079, 0x6085,
- 0x609D, 0x60AD, 0x60BB, 0x60BF, 0x60CD, 0x60D9, 0x60DF, 0x60E9,
- 0x60F5, 0x6109, 0x610F, 0x6113, 0x611B, 0x612D, 0x6139, 0x614B,
- 0x6155, 0x6157, 0x615B, 0x616F, 0x6179, 0x6187, 0x618B, 0x6191,
- 0x6193, 0x619D, 0x61B5, 0x61C7, 0x61C9, 0x61CD, 0x61E1, 0x61F1,
- 0x61FF, 0x6209, 0x6217, 0x621D, 0x6221, 0x6227, 0x623B, 0x6241,
- 0x624B, 0x6251, 0x6253, 0x625F, 0x6265, 0x6283, 0x628D, 0x6295,
- 0x629B, 0x629F, 0x62A5, 0x62AD, 0x62D5, 0x62D7, 0x62DB, 0x62DD,
- 0x62E9, 0x62FB, 0x62FF, 0x6305, 0x630D, 0x6317, 0x631D, 0x632F,
- 0x6341, 0x6343, 0x634F, 0x635F, 0x6367, 0x636D, 0x6371, 0x6377,
- 0x637D, 0x637F, 0x63B3, 0x63C1, 0x63C5, 0x63D9, 0x63E9, 0x63EB,
- 0x63EF, 0x63F5, 0x6401, 0x6403, 0x6409, 0x6415, 0x6421, 0x6427,
- 0x642B, 0x6439, 0x6443, 0x6449, 0x644F, 0x645D, 0x6467, 0x6475,
- 0x6485, 0x648D, 0x6493, 0x649F, 0x64A3, 0x64AB, 0x64C1, 0x64C7,
- 0x64C9, 0x64DB, 0x64F1, 0x64F7, 0x64F9, 0x650B, 0x6511, 0x6521,
- 0x652F, 0x6539, 0x653F, 0x654B, 0x654D, 0x6553, 0x6557, 0x655F,
- 0x6571, 0x657D, 0x658D, 0x658F, 0x6593, 0x65A1, 0x65A5, 0x65AD,
- 0x65B9, 0x65C5, 0x65E3, 0x65F3, 0x65FB, 0x65FF, 0x6601, 0x6607,
- 0x661D, 0x6629, 0x6631, 0x663B, 0x6641, 0x6647, 0x664D, 0x665B,
- 0x6661, 0x6673, 0x667D, 0x6689, 0x668B, 0x6695, 0x6697, 0x669B,
- 0x66B5, 0x66B9, 0x66C5, 0x66CD, 0x66D1, 0x66E3, 0x66EB, 0x66F5,
- 0x6703, 0x6713, 0x6719, 0x671F, 0x6727, 0x6731, 0x6737, 0x673F,
- 0x6745, 0x6751, 0x675B, 0x676F, 0x6779, 0x6781, 0x6785, 0x6791,
- 0x67AB, 0x67BD, 0x67C1, 0x67CD, 0x67DF, 0x67E5, 0x6803, 0x6809,
- 0x6811, 0x6817, 0x682D, 0x6839, 0x683B, 0x683F, 0x6845, 0x684B,
- 0x684D, 0x6857, 0x6859, 0x685D, 0x6863, 0x6869, 0x686B, 0x6871,
- 0x6887, 0x6899, 0x689F, 0x68B1, 0x68BD, 0x68C5, 0x68D1, 0x68D7,
- 0x68E1, 0x68ED, 0x68EF, 0x68FF, 0x6901, 0x690B, 0x690D, 0x6917,
- 0x6929, 0x692F, 0x6943, 0x6947, 0x6949, 0x694F, 0x6965, 0x696B,
- 0x6971, 0x6983, 0x6989, 0x6997, 0x69A3, 0x69B3, 0x69B5, 0x69BB,
- 0x69C1, 0x69C5, 0x69D3, 0x69DF, 0x69E3, 0x69E5, 0x69F7, 0x6A07,
- 0x6A2B, 0x6A37, 0x6A3D, 0x6A4B, 0x6A67, 0x6A69, 0x6A75, 0x6A7B,
- 0x6A87, 0x6A8D, 0x6A91, 0x6A93, 0x6AA3, 0x6AC1, 0x6AC9, 0x6AE1,
- 0x6AE7, 0x6B05, 0x6B0F, 0x6B11, 0x6B23, 0x6B27, 0x6B2D, 0x6B39,
- 0x6B41, 0x6B57, 0x6B59, 0x6B5F, 0x6B75, 0x6B87, 0x6B89, 0x6B93,
- 0x6B95, 0x6B9F, 0x6BBD, 0x6BBF, 0x6BDB, 0x6BE1, 0x6BEF, 0x6BFF,
- 0x6C05, 0x6C19, 0x6C29, 0x6C2B, 0x6C31, 0x6C35, 0x6C55, 0x6C59,
- 0x6C5B, 0x6C5F, 0x6C65, 0x6C67, 0x6C73, 0x6C77, 0x6C7D, 0x6C83,
- 0x6C8F, 0x6C91, 0x6C97, 0x6C9B, 0x6CA1, 0x6CA9, 0x6CAF, 0x6CB3,
- 0x6CC7, 0x6CCB, 0x6CEB, 0x6CF5, 0x6CFD, 0x6D0D, 0x6D0F, 0x6D25,
- 0x6D27, 0x6D2B, 0x6D31, 0x6D39, 0x6D3F, 0x6D4F, 0x6D5D, 0x6D61,
- 0x6D73, 0x6D7B, 0x6D7F, 0x6D93, 0x6D99, 0x6DA5, 0x6DB1, 0x6DB7,
- 0x6DC1, 0x6DC3, 0x6DCD, 0x6DCF, 0x6DDB, 0x6DF7, 0x6E03, 0x6E15,
- 0x6E17, 0x6E29, 0x6E33, 0x6E3B, 0x6E45, 0x6E75, 0x6E77, 0x6E7B,
- 0x6E81, 0x6E89, 0x6E93, 0x6E95, 0x6E9F, 0x6EBD, 0x6EBF, 0x6EE3,
- 0x6EE9, 0x6EF3, 0x6EF9, 0x6EFB, 0x6F0D, 0x6F11, 0x6F17, 0x6F1F,
- 0x6F2F, 0x6F3D, 0x6F4D, 0x6F53, 0x6F61, 0x6F65, 0x6F79, 0x6F7D,
- 0x6F83, 0x6F85, 0x6F8F, 0x6F9B, 0x6F9D, 0x6FA3, 0x6FAF, 0x6FB5,
- 0x6FBB, 0x6FBF, 0x6FCB, 0x6FCD, 0x6FD3, 0x6FD7, 0x6FE3, 0x6FE9,
- 0x6FF1, 0x6FF5, 0x6FF7, 0x6FFD, 0x700F, 0x7019, 0x701F, 0x7027,
- 0x7033, 0x7039, 0x704F, 0x7051, 0x7057, 0x7063, 0x7075, 0x7079,
- 0x7087, 0x708D, 0x7091, 0x70A5, 0x70AB, 0x70BB, 0x70C3, 0x70C7,
- 0x70CF, 0x70E5, 0x70ED, 0x70F9, 0x70FF, 0x7105, 0x7115, 0x7121,
- 0x7133, 0x7151, 0x7159, 0x715D, 0x715F, 0x7163, 0x7169, 0x7183,
- 0x7187, 0x7195, 0x71AD, 0x71C3, 0x71C9, 0x71CB, 0x71D1, 0x71DB,
- 0x71E1, 0x71EF, 0x71F5, 0x71FB, 0x7207, 0x7211, 0x7217, 0x7219,
- 0x7225, 0x722F, 0x723B, 0x7243, 0x7255, 0x7267, 0x7271, 0x7277,
- 0x727F, 0x728F, 0x7295, 0x729B, 0x72A3, 0x72B3, 0x72C7, 0x72CB,
- 0x72CD, 0x72D7, 0x72D9, 0x72E3, 0x72EF, 0x72F5, 0x72FD, 0x7303,
- 0x730D, 0x7321, 0x732B, 0x733D, 0x7357, 0x735B, 0x7361, 0x737F,
- 0x7381, 0x7385, 0x738D, 0x7393, 0x739F, 0x73AB, 0x73BD, 0x73C1,
- 0x73C9, 0x73DF, 0x73E5, 0x73E7, 0x73F3, 0x7415, 0x741B, 0x742D,
- 0x7439, 0x743F, 0x7441, 0x745D, 0x746B, 0x747B, 0x7489, 0x748D,
- 0x749B, 0x74A7, 0x74AB, 0x74B1, 0x74B7, 0x74B9, 0x74DD, 0x74E1,
- 0x74E7, 0x74FB, 0x7507, 0x751F, 0x7525, 0x753B, 0x753D, 0x754D,
- 0x755F, 0x756B, 0x7577, 0x7589, 0x758B, 0x7591, 0x7597, 0x759D,
- 0x75A1, 0x75A7, 0x75B5, 0x75B9, 0x75BB, 0x75D1, 0x75D9, 0x75E5,
- 0x75EB, 0x75F5, 0x75FB, 0x7603, 0x760F, 0x7621, 0x762D, 0x7633,
- 0x763D, 0x763F, 0x7655, 0x7663, 0x7669, 0x766F, 0x7673, 0x7685,
- 0x768B, 0x769F, 0x76B5, 0x76B7, 0x76C3, 0x76DB, 0x76DF, 0x76F1,
- 0x7703, 0x7705, 0x771B, 0x771D, 0x7721, 0x772D, 0x7735, 0x7741,
- 0x774B, 0x7759, 0x775D, 0x775F, 0x7771, 0x7781, 0x77A7, 0x77AD,
- 0x77B3, 0x77B9, 0x77C5, 0x77CF, 0x77D5, 0x77E1, 0x77E9, 0x77EF,
- 0x77F3, 0x77F9, 0x7807, 0x7825, 0x782B, 0x7835, 0x783D, 0x7853,
- 0x7859, 0x7861, 0x786D, 0x7877, 0x7879, 0x7883, 0x7885, 0x788B,
- 0x7895, 0x7897, 0x78A1, 0x78AD, 0x78BF, 0x78D3, 0x78D9, 0x78DD,
- 0x78E5, 0x78FB, 0x7901, 0x7907, 0x7925, 0x792B, 0x7939, 0x793F,
- 0x794B, 0x7957, 0x795D, 0x7967, 0x7969, 0x7973, 0x7991, 0x7993,
- 0x79A3, 0x79AB, 0x79AF, 0x79B1, 0x79B7, 0x79C9, 0x79CD, 0x79CF,
- 0x79D5, 0x79D9, 0x79F3, 0x79F7, 0x79FF, 0x7A05, 0x7A0F, 0x7A11,
- 0x7A15, 0x7A1B, 0x7A23, 0x7A27, 0x7A2D, 0x7A4B, 0x7A57, 0x7A59,
- 0x7A5F, 0x7A65, 0x7A69, 0x7A7D, 0x7A93, 0x7A9B, 0x7A9F, 0x7AA1,
- 0x7AA5, 0x7AED, 0x7AF5, 0x7AF9, 0x7B01, 0x7B17, 0x7B19, 0x7B1D,
- 0x7B2B, 0x7B35, 0x7B37, 0x7B3B, 0x7B4F, 0x7B55, 0x7B5F, 0x7B71,
- 0x7B77, 0x7B8B, 0x7B9B, 0x7BA1, 0x7BA9, 0x7BAF, 0x7BB3, 0x7BC7,
- 0x7BD3, 0x7BE9, 0x7BEB, 0x7BEF, 0x7BF1, 0x7BFD, 0x7C07, 0x7C19,
- 0x7C1B, 0x7C31, 0x7C37, 0x7C49, 0x7C67, 0x7C69, 0x7C73, 0x7C81,
- 0x7C8B, 0x7C93, 0x7CA3, 0x7CD5, 0x7CDB, 0x7CE5, 0x7CED, 0x7CF7,
- 0x7D03, 0x7D09, 0x7D1B, 0x7D1D, 0x7D33, 0x7D39, 0x7D3B, 0x7D3F,
- 0x7D45, 0x7D4D, 0x7D53, 0x7D59, 0x7D63, 0x7D75, 0x7D77, 0x7D8D,
- 0x7D8F, 0x7D9F, 0x7DAD, 0x7DB7, 0x7DBD, 0x7DBF, 0x7DCB, 0x7DD5,
- 0x7DE9, 0x7DED, 0x7DFB, 0x7E01, 0x7E05, 0x7E29, 0x7E2B, 0x7E2F,
- 0x7E35, 0x7E41, 0x7E43, 0x7E47, 0x7E55, 0x7E61, 0x7E67, 0x7E6B,
- 0x7E71, 0x7E73, 0x7E79, 0x7E7D, 0x7E91, 0x7E9B, 0x7E9D, 0x7EA7,
- 0x7EAD, 0x7EB9, 0x7EBB, 0x7ED3, 0x7EDF, 0x7EEB, 0x7EF1, 0x7EF7,
- 0x7EFB, 0x7F13, 0x7F15, 0x7F19, 0x7F31, 0x7F33, 0x7F39, 0x7F3D,
- 0x7F43, 0x7F4B, 0x7F5B, 0x7F61, 0x7F63, 0x7F6D, 0x7F79, 0x7F87,
- 0x7F8D, 0x7FAF, 0x7FB5, 0x7FC3, 0x7FC9, 0x7FCD, 0x7FCF, 0x7FED,
- 0x8003, 0x800B, 0x800F, 0x8015, 0x801D, 0x8021, 0x8023, 0x803F,
- 0x8041, 0x8047, 0x804B, 0x8065, 0x8077, 0x808D, 0x808F, 0x8095,
- 0x80A5, 0x80AB, 0x80AD, 0x80BD, 0x80C9, 0x80CB, 0x80D7, 0x80DB,
- 0x80E1, 0x80E7, 0x80F5, 0x80FF, 0x8105, 0x810D, 0x8119, 0x811D,
- 0x812F, 0x8131, 0x813B, 0x8143, 0x8153, 0x8159, 0x815F, 0x817D,
- 0x817F, 0x8189, 0x819B, 0x819D, 0x81A7, 0x81AF, 0x81B3, 0x81BB,
- 0x81C7, 0x81DF, 0x8207, 0x8209, 0x8215, 0x821F, 0x8225, 0x8231,
- 0x8233, 0x823F, 0x8243, 0x8245, 0x8249, 0x824F, 0x8261, 0x826F,
- 0x827B, 0x8281, 0x8285, 0x8293, 0x82B1, 0x82B5, 0x82BD, 0x82C7,
- 0x82CF, 0x82D5, 0x82DF, 0x82F1, 0x82F9, 0x82FD, 0x830B, 0x831B,
- 0x8321, 0x8329, 0x832D, 0x8333, 0x8335, 0x833F, 0x8341, 0x834D,
- 0x8351, 0x8353, 0x8357, 0x835D, 0x8365, 0x8369, 0x836F, 0x838F,
- 0x83A7, 0x83B1, 0x83B9, 0x83CB, 0x83D5, 0x83D7, 0x83DD, 0x83E7,
- 0x83E9, 0x83ED, 0x83FF, 0x8405, 0x8411, 0x8413, 0x8423, 0x8425,
- 0x843B, 0x8441, 0x8447, 0x844F, 0x8461, 0x8465, 0x8477, 0x8483,
- 0x848B, 0x8491, 0x8495, 0x84A9, 0x84AF, 0x84CD, 0x84E3, 0x84EF,
- 0x84F1, 0x84F7, 0x8509, 0x850D, 0x854B, 0x854F, 0x8551, 0x855D,
- 0x8563, 0x856D, 0x856F, 0x857B, 0x8587, 0x85A3, 0x85A5, 0x85A9,
- 0x85B7, 0x85CD, 0x85D3, 0x85D5, 0x85DB, 0x85E1, 0x85EB, 0x85F9,
- 0x85FD, 0x85FF, 0x8609, 0x860F, 0x8617, 0x8621, 0x862F, 0x8639,
- 0x863F, 0x8641, 0x864D, 0x8663, 0x8675, 0x867D, 0x8687, 0x8699,
- 0x86A5, 0x86A7, 0x86B3, 0x86B7, 0x86C3, 0x86C5, 0x86CF, 0x86D1,
- 0x86D7, 0x86E9, 0x86EF, 0x86F5, 0x8717, 0x871D, 0x871F, 0x872B,
- 0x872F, 0x8735, 0x8747, 0x8759, 0x875B, 0x876B, 0x8771, 0x8777,
- 0x877F, 0x8785, 0x878F, 0x87A1, 0x87A9, 0x87B3, 0x87BB, 0x87C5,
- 0x87C7, 0x87CB, 0x87DD, 0x87F7, 0x8803, 0x8819, 0x881B, 0x881F,
- 0x8821, 0x8837, 0x883D, 0x8843, 0x8851, 0x8861, 0x8867, 0x887B,
- 0x8885, 0x8891, 0x8893, 0x88A5, 0x88CF, 0x88D3, 0x88EB, 0x88ED,
- 0x88F3, 0x88FD, 0x8909, 0x890B, 0x8911, 0x891B, 0x8923, 0x8927,
- 0x892D, 0x8939, 0x8945, 0x894D, 0x8951, 0x8957, 0x8963, 0x8981,
- 0x8995, 0x899B, 0x89B3, 0x89B9, 0x89C3, 0x89CF, 0x89D1, 0x89DB,
- 0x89EF, 0x89F5, 0x89FB, 0x89FF, 0x8A0B, 0x8A19, 0x8A23, 0x8A35,
- 0x8A41, 0x8A49, 0x8A4F, 0x8A5B, 0x8A5F, 0x8A6D, 0x8A77, 0x8A79,
- 0x8A85, 0x8AA3, 0x8AB3, 0x8AB5, 0x8AC1, 0x8AC7, 0x8ACB, 0x8ACD,
- 0x8AD1, 0x8AD7, 0x8AF1, 0x8AF5, 0x8B07, 0x8B09, 0x8B0D, 0x8B13,
- 0x8B21, 0x8B57, 0x8B5D, 0x8B91, 0x8B93, 0x8BA3, 0x8BA9, 0x8BAF,
- 0x8BBB, 0x8BD5, 0x8BD9, 0x8BDB, 0x8BE1, 0x8BF7, 0x8BFD, 0x8BFF,
- 0x8C0B, 0x8C17, 0x8C1D, 0x8C27, 0x8C39, 0x8C3B, 0x8C47, 0x8C53,
- 0x8C5D, 0x8C6F, 0x8C7B, 0x8C81, 0x8C89, 0x8C8F, 0x8C99, 0x8C9F,
- 0x8CA7, 0x8CAB, 0x8CAD, 0x8CB1, 0x8CC5, 0x8CDD, 0x8CE3, 0x8CE9,
- 0x8CF3, 0x8D01, 0x8D0B, 0x8D0D, 0x8D23, 0x8D29, 0x8D37, 0x8D41,
- 0x8D5B, 0x8D5F, 0x8D71, 0x8D79, 0x8D85, 0x8D91, 0x8D9B, 0x8DA7,
- 0x8DAD, 0x8DB5, 0x8DC5, 0x8DCB, 0x8DD3, 0x8DD9, 0x8DDF, 0x8DF5,
- 0x8DF7, 0x8E01, 0x8E15, 0x8E1F, 0x8E25, 0x8E51, 0x8E63, 0x8E69,
- 0x8E73, 0x8E75, 0x8E79, 0x8E7F, 0x8E8D, 0x8E91, 0x8EAB, 0x8EAF,
- 0x8EB1, 0x8EBD, 0x8EC7, 0x8ECF, 0x8ED3, 0x8EDB, 0x8EE7, 0x8EEB,
- 0x8EF7, 0x8EFF, 0x8F15, 0x8F1D, 0x8F23, 0x8F2D, 0x8F3F, 0x8F45,
- 0x8F4B, 0x8F53, 0x8F59, 0x8F65, 0x8F69, 0x8F71, 0x8F83, 0x8F8D,
- 0x8F99, 0x8F9F, 0x8FAB, 0x8FAD, 0x8FB3, 0x8FB7, 0x8FB9, 0x8FC9,
- 0x8FD5, 0x8FE1, 0x8FEF, 0x8FF9, 0x9007, 0x900D, 0x9017, 0x9023,
- 0x9025, 0x9031, 0x9037, 0x903B, 0x9041, 0x9043, 0x904F, 0x9053,
- 0x906D, 0x9073, 0x9085, 0x908B, 0x9095, 0x909B, 0x909D, 0x90AF,
- 0x90B9, 0x90C1, 0x90C5, 0x90DF, 0x90E9, 0x90FD, 0x9103, 0x9113,
- 0x9127, 0x9133, 0x913D, 0x9145, 0x914F, 0x9151, 0x9161, 0x9167,
- 0x917B, 0x9185, 0x9199, 0x919D, 0x91BB, 0x91BD, 0x91C1, 0x91C9,
- 0x91D9, 0x91DB, 0x91ED, 0x91F1, 0x91F3, 0x91F9, 0x9203, 0x9215,
- 0x9221, 0x922F, 0x9241, 0x9247, 0x9257, 0x926B, 0x9271, 0x9275,
- 0x927D, 0x9283, 0x9287, 0x928D, 0x9299, 0x92A1, 0x92AB, 0x92AD,
- 0x92B9, 0x92BF, 0x92C3, 0x92C5, 0x92CB, 0x92D5, 0x92D7, 0x92E7,
- 0x92F3, 0x9301, 0x930B, 0x9311, 0x9319, 0x931F, 0x933B, 0x933D,
- 0x9343, 0x9355, 0x9373, 0x9395, 0x9397, 0x93A7, 0x93B3, 0x93B5,
- 0x93C7, 0x93D7, 0x93DD, 0x93E5, 0x93EF, 0x93F7, 0x9401, 0x9409,
- 0x9413, 0x943F, 0x9445, 0x944B, 0x944F, 0x9463, 0x9467, 0x9469,
- 0x946D, 0x947B, 0x9497, 0x949F, 0x94A5, 0x94B5, 0x94C3, 0x94E1,
- 0x94E7, 0x9505, 0x9509, 0x9517, 0x9521, 0x9527, 0x952D, 0x9535,
- 0x9539, 0x954B, 0x9557, 0x955D, 0x955F, 0x9575, 0x9581, 0x9589,
- 0x958F, 0x959B, 0x959F, 0x95AD, 0x95B1, 0x95B7, 0x95B9, 0x95BD,
- 0x95CF, 0x95E3, 0x95E9, 0x95F9, 0x961F, 0x962F, 0x9631, 0x9635,
- 0x963B, 0x963D, 0x9665, 0x968F, 0x969D, 0x96A1, 0x96A7, 0x96A9,
- 0x96C1, 0x96CB, 0x96D1, 0x96D3, 0x96E5, 0x96EF, 0x96FB, 0x96FD,
- 0x970D, 0x970F, 0x9715, 0x9725, 0x972B, 0x9733, 0x9737, 0x9739,
- 0x9743, 0x9749, 0x9751, 0x975B, 0x975D, 0x976F, 0x977F, 0x9787,
- 0x9793, 0x97A5, 0x97B1, 0x97B7, 0x97C3, 0x97CD, 0x97D3, 0x97D9,
- 0x97EB, 0x97F7, 0x9805, 0x9809, 0x980B, 0x9815, 0x9829, 0x982F,
- 0x983B, 0x9841, 0x9851, 0x986B, 0x986F, 0x9881, 0x9883, 0x9887,
- 0x98A7, 0x98B1, 0x98B9, 0x98BF, 0x98C3, 0x98C9, 0x98CF, 0x98DD,
- 0x98E3, 0x98F5, 0x98F9, 0x98FB, 0x990D, 0x9917, 0x991F, 0x9929,
- 0x9931, 0x993B, 0x993D, 0x9941, 0x9947, 0x9949, 0x9953, 0x997D,
- 0x9985, 0x9991, 0x9995, 0x999B, 0x99AD, 0x99AF, 0x99BF, 0x99C7,
- 0x99CB, 0x99CD, 0x99D7, 0x99E5, 0x99F1, 0x99FB, 0x9A0F, 0x9A13,
- 0x9A1B, 0x9A25, 0x9A4B, 0x9A4F, 0x9A55, 0x9A57, 0x9A61, 0x9A75,
- 0x9A7F, 0x9A8B, 0x9A91, 0x9A9D, 0x9AB7, 0x9AC3, 0x9AC7, 0x9ACF,
- 0x9AEB, 0x9AF3, 0x9AF7, 0x9AFF, 0x9B17, 0x9B1D, 0x9B27, 0x9B2F,
- 0x9B35, 0x9B45, 0x9B51, 0x9B59, 0x9B63, 0x9B6F, 0x9B77, 0x9B8D,
- 0x9B93, 0x9B95, 0x9B9F, 0x9BA1, 0x9BA7, 0x9BB1, 0x9BB7, 0x9BBD,
- 0x9BC5, 0x9BCB, 0x9BCF, 0x9BDD, 0x9BF9, 0x9C01, 0x9C11, 0x9C23,
- 0x9C2B, 0x9C2F, 0x9C35, 0x9C49, 0x9C4D, 0x9C5F, 0x9C65, 0x9C67,
- 0x9C7F, 0x9C97, 0x9C9D, 0x9CA3, 0x9CAF, 0x9CBB, 0x9CBF, 0x9CC1,
- 0x9CD7, 0x9CD9, 0x9CE3, 0x9CE9, 0x9CF1, 0x9CFD, 0x9D01, 0x9D15,
- 0x9D27, 0x9D2D, 0x9D31, 0x9D3D, 0x9D55, 0x9D5B, 0x9D61, 0x9D97,
- 0x9D9F, 0x9DA5, 0x9DA9, 0x9DC3, 0x9DE7, 0x9DEB, 0x9DED, 0x9DF1,
- 0x9E0B, 0x9E17, 0x9E23, 0x9E27, 0x9E2D, 0x9E33, 0x9E3B, 0x9E47,
- 0x9E51, 0x9E53, 0x9E5F, 0x9E6F, 0x9E81, 0x9E87, 0x9E8F, 0x9E95,
- 0x9EA1, 0x9EB3, 0x9EBD, 0x9EBF, 0x9EF5, 0x9EF9, 0x9EFB, 0x9F05,
- 0x9F23, 0x9F2F, 0x9F37, 0x9F3B, 0x9F43, 0x9F53, 0x9F61, 0x9F6D,
- 0x9F73, 0x9F77, 0x9F7D, 0x9F89, 0x9F8F, 0x9F91, 0x9F95, 0x9FA3,
- 0x9FAF, 0x9FB3, 0x9FC1, 0x9FC7, 0x9FDF, 0x9FE5, 0x9FEB, 0x9FF5,
- 0xA001, 0xA00D, 0xA021, 0xA033, 0xA039, 0xA03F, 0xA04F, 0xA057,
- 0xA05B, 0xA061, 0xA075, 0xA079, 0xA099, 0xA09D, 0xA0AB, 0xA0B5,
- 0xA0B7, 0xA0BD, 0xA0C9, 0xA0D9, 0xA0DB, 0xA0DF, 0xA0E5, 0xA0F1,
- 0xA0F3, 0xA0FD, 0xA105, 0xA10B, 0xA10F, 0xA111, 0xA11B, 0xA129,
- 0xA12F, 0xA135, 0xA141, 0xA153, 0xA175, 0xA17D, 0xA187, 0xA18D,
- 0xA1A5, 0xA1AB, 0xA1AD, 0xA1B7, 0xA1C3, 0xA1C5, 0xA1E3, 0xA1ED,
- 0xA1FB, 0xA207, 0xA213, 0xA223, 0xA229, 0xA22F, 0xA231, 0xA243,
- 0xA247, 0xA24D, 0xA26B, 0xA279, 0xA27D, 0xA283, 0xA289, 0xA28B,
- 0xA291, 0xA295, 0xA29B, 0xA2A9, 0xA2AF, 0xA2B3, 0xA2BB, 0xA2C5,
- 0xA2D1, 0xA2D7, 0xA2F7, 0xA301, 0xA309, 0xA31F, 0xA321, 0xA32B,
- 0xA331, 0xA349, 0xA351, 0xA355, 0xA373, 0xA379, 0xA37B, 0xA387,
- 0xA397, 0xA39F, 0xA3A5, 0xA3A9, 0xA3AF, 0xA3B7, 0xA3C7, 0xA3D5,
- 0xA3DB, 0xA3E1, 0xA3E5, 0xA3E7, 0xA3F1, 0xA3FD, 0xA3FF, 0xA40F,
- 0xA41D, 0xA421, 0xA423, 0xA427, 0xA43B, 0xA44D, 0xA457, 0xA459,
- 0xA463, 0xA469, 0xA475, 0xA493, 0xA49B, 0xA4AD, 0xA4B9, 0xA4C3,
- 0xA4C5, 0xA4CB, 0xA4D1, 0xA4D5, 0xA4E1, 0xA4ED, 0xA4EF, 0xA4F3,
- 0xA4FF, 0xA511, 0xA529, 0xA52B, 0xA535, 0xA53B, 0xA543, 0xA553,
- 0xA55B, 0xA561, 0xA56D, 0xA577, 0xA585, 0xA58B, 0xA597, 0xA59D,
- 0xA5A3, 0xA5A7, 0xA5A9, 0xA5C1, 0xA5C5, 0xA5CB, 0xA5D3, 0xA5D9,
- 0xA5DD, 0xA5DF, 0xA5E3, 0xA5E9, 0xA5F7, 0xA5FB, 0xA603, 0xA60D,
- 0xA625, 0xA63D, 0xA649, 0xA64B, 0xA651, 0xA65D, 0xA673, 0xA691,
- 0xA693, 0xA699, 0xA6AB, 0xA6B5, 0xA6BB, 0xA6C1, 0xA6C9, 0xA6CD,
- 0xA6CF, 0xA6D5, 0xA6DF, 0xA6E7, 0xA6F1, 0xA6F7, 0xA6FF, 0xA70F,
- 0xA715, 0xA723, 0xA729, 0xA72D, 0xA745, 0xA74D, 0xA757, 0xA759,
- 0xA765, 0xA76B, 0xA76F, 0xA793, 0xA795, 0xA7AB, 0xA7B1, 0xA7B9,
- 0xA7BF, 0xA7C9, 0xA7D1, 0xA7D7, 0xA7E3, 0xA7ED, 0xA7FB, 0xA805,
- 0xA80B, 0xA81D, 0xA829, 0xA82B, 0xA837, 0xA83B, 0xA855, 0xA85F,
- 0xA86D, 0xA87D, 0xA88F, 0xA897, 0xA8A9, 0xA8B5, 0xA8C1, 0xA8C7,
- 0xA8D7, 0xA8E5, 0xA8FD, 0xA907, 0xA913, 0xA91B, 0xA931, 0xA937,
- 0xA939, 0xA943, 0xA97F, 0xA985, 0xA987, 0xA98B, 0xA993, 0xA9A3,
- 0xA9B1, 0xA9BB, 0xA9C1, 0xA9D9, 0xA9DF, 0xA9EB, 0xA9FD, 0xAA15,
- 0xAA17, 0xAA35, 0xAA39, 0xAA3B, 0xAA47, 0xAA4D, 0xAA57, 0xAA59,
- 0xAA5D, 0xAA6B, 0xAA71, 0xAA81, 0xAA83, 0xAA8D, 0xAA95, 0xAAAB,
- 0xAABF, 0xAAC5, 0xAAC9, 0xAAE9, 0xAAEF, 0xAB01, 0xAB05, 0xAB07,
- 0xAB0B, 0xAB0D, 0xAB11, 0xAB19, 0xAB4D, 0xAB5B, 0xAB71, 0xAB73,
- 0xAB89, 0xAB9D, 0xABA7, 0xABAF, 0xABB9, 0xABBB, 0xABC1, 0xABC5,
- 0xABD3, 0xABD7, 0xABDD, 0xABF1, 0xABF5, 0xABFB, 0xABFD, 0xAC09,
- 0xAC15, 0xAC1B, 0xAC27, 0xAC37, 0xAC39, 0xAC45, 0xAC4F, 0xAC57,
- 0xAC5B, 0xAC61, 0xAC63, 0xAC7F, 0xAC8B, 0xAC93, 0xAC9D, 0xACA9,
- 0xACAB, 0xACAF, 0xACBD, 0xACD9, 0xACE1, 0xACE7, 0xACEB, 0xACED,
- 0xACF1, 0xACF7, 0xACF9, 0xAD05, 0xAD3F, 0xAD45, 0xAD53, 0xAD5D,
- 0xAD5F, 0xAD65, 0xAD81, 0xADA1, 0xADA5, 0xADC3, 0xADCB, 0xADD1,
- 0xADD5, 0xADDB, 0xADE7, 0xADF3, 0xADF5, 0xADF9, 0xADFF, 0xAE05,
- 0xAE13, 0xAE23, 0xAE2B, 0xAE49, 0xAE4D, 0xAE4F, 0xAE59, 0xAE61,
- 0xAE67, 0xAE6B, 0xAE71, 0xAE8B, 0xAE8F, 0xAE9B, 0xAE9D, 0xAEA7,
- 0xAEB9, 0xAEC5, 0xAED1, 0xAEE3, 0xAEE5, 0xAEE9, 0xAEF5, 0xAEFD,
- 0xAF09, 0xAF13, 0xAF27, 0xAF2B, 0xAF33, 0xAF43, 0xAF4F, 0xAF57,
- 0xAF5D, 0xAF6D, 0xAF75, 0xAF7F, 0xAF8B, 0xAF99, 0xAF9F, 0xAFA3,
- 0xAFAB, 0xAFB7, 0xAFBB, 0xAFCF, 0xAFD5, 0xAFFD, 0xB005, 0xB015,
- 0xB01B, 0xB03F, 0xB041, 0xB047, 0xB04B, 0xB051, 0xB053, 0xB069,
- 0xB07B, 0xB07D, 0xB087, 0xB08D, 0xB0B1, 0xB0BF, 0xB0CB, 0xB0CF,
- 0xB0E1, 0xB0E9, 0xB0ED, 0xB0FB, 0xB105, 0xB107, 0xB111, 0xB119,
- 0xB11D, 0xB11F, 0xB131, 0xB141, 0xB14D, 0xB15B, 0xB165, 0xB173,
- 0xB179, 0xB17F, 0xB1A9, 0xB1B3, 0xB1B9, 0xB1BF, 0xB1D3, 0xB1DD,
- 0xB1E5, 0xB1F1, 0xB1F5, 0xB201, 0xB213, 0xB215, 0xB21F, 0xB22D,
- 0xB23F, 0xB249, 0xB25B, 0xB263, 0xB269, 0xB26D, 0xB27B, 0xB281,
- 0xB28B, 0xB2A9, 0xB2B7, 0xB2BD, 0xB2C3, 0xB2C7, 0xB2D3, 0xB2F9,
- 0xB2FD, 0xB2FF, 0xB303, 0xB309, 0xB311, 0xB31D, 0xB327, 0xB32D,
- 0xB33F, 0xB345, 0xB377, 0xB37D, 0xB381, 0xB387, 0xB393, 0xB39B,
- 0xB3A5, 0xB3C5, 0xB3CB, 0xB3E1, 0xB3E3, 0xB3ED, 0xB3F9, 0xB40B,
- 0xB40D, 0xB413, 0xB417, 0xB435, 0xB43D, 0xB443, 0xB449, 0xB45B,
- 0xB465, 0xB467, 0xB46B, 0xB477, 0xB48B, 0xB495, 0xB49D, 0xB4B5,
- 0xB4BF, 0xB4C1, 0xB4C7, 0xB4DD, 0xB4E3, 0xB4E5, 0xB4F7, 0xB501,
- 0xB50D, 0xB50F, 0xB52D, 0xB53F, 0xB54B, 0xB567, 0xB569, 0xB56F,
- 0xB573, 0xB579, 0xB587, 0xB58D, 0xB599, 0xB5A3, 0xB5AB, 0xB5AF,
- 0xB5BB, 0xB5D5, 0xB5DF, 0xB5E7, 0xB5ED, 0xB5FD, 0xB5FF, 0xB609,
- 0xB61B, 0xB629, 0xB62F, 0xB633, 0xB639, 0xB647, 0xB657, 0xB659,
- 0xB65F, 0xB663, 0xB66F, 0xB683, 0xB687, 0xB69B, 0xB69F, 0xB6A5,
- 0xB6B1, 0xB6B3, 0xB6D7, 0xB6DB, 0xB6E1, 0xB6E3, 0xB6ED, 0xB6EF,
- 0xB705, 0xB70D, 0xB713, 0xB71D, 0xB729, 0xB735, 0xB747, 0xB755,
- 0xB76D, 0xB791, 0xB795, 0xB7A9, 0xB7C1, 0xB7CB, 0xB7D1, 0xB7D3,
- 0xB7EF, 0xB7F5, 0xB807, 0xB80F, 0xB813, 0xB819, 0xB821, 0xB827,
- 0xB82B, 0xB82D, 0xB839, 0xB855, 0xB867, 0xB875, 0xB885, 0xB893,
- 0xB8A5, 0xB8AF, 0xB8B7, 0xB8BD, 0xB8C1, 0xB8C7, 0xB8CD, 0xB8D5,
- 0xB8EB, 0xB8F7, 0xB8F9, 0xB903, 0xB915, 0xB91B, 0xB91D, 0xB92F,
- 0xB939, 0xB93B, 0xB947, 0xB951, 0xB963, 0xB983, 0xB989, 0xB98D,
- 0xB993, 0xB999, 0xB9A1, 0xB9A7, 0xB9AD, 0xB9B7, 0xB9CB, 0xB9D1,
- 0xB9DD, 0xB9E7, 0xB9EF, 0xB9F9, 0xBA07, 0xBA0D, 0xBA17, 0xBA25,
- 0xBA29, 0xBA2B, 0xBA41, 0xBA53, 0xBA55, 0xBA5F, 0xBA61, 0xBA65,
- 0xBA79, 0xBA7D, 0xBA7F, 0xBAA1, 0xBAA3, 0xBAAF, 0xBAB5, 0xBABF,
- 0xBAC1, 0xBACB, 0xBADD, 0xBAE3, 0xBAF1, 0xBAFD, 0xBB09, 0xBB1F,
- 0xBB27, 0xBB2D, 0xBB3D, 0xBB43, 0xBB4B, 0xBB4F, 0xBB5B, 0xBB61,
- 0xBB69, 0xBB6D, 0xBB91, 0xBB97, 0xBB9D, 0xBBB1, 0xBBC9, 0xBBCF,
- 0xBBDB, 0xBBED, 0xBBF7, 0xBBF9, 0xBC03, 0xBC1D, 0xBC23, 0xBC33,
- 0xBC3B, 0xBC41, 0xBC45, 0xBC5D, 0xBC6F, 0xBC77, 0xBC83, 0xBC8F,
- 0xBC99, 0xBCAB, 0xBCB7, 0xBCB9, 0xBCD1, 0xBCD5, 0xBCE1, 0xBCF3,
- 0xBCFF, 0xBD0D, 0xBD17, 0xBD19, 0xBD1D, 0xBD35, 0xBD41, 0xBD4F,
- 0xBD59, 0xBD5F, 0xBD61, 0xBD67, 0xBD6B, 0xBD71, 0xBD8B, 0xBD8F,
- 0xBD95, 0xBD9B, 0xBD9D, 0xBDB3, 0xBDBB, 0xBDCD, 0xBDD1, 0xBDE3,
- 0xBDEB, 0xBDEF, 0xBE07, 0xBE09, 0xBE15, 0xBE21, 0xBE25, 0xBE27,
- 0xBE5B, 0xBE5D, 0xBE6F, 0xBE75, 0xBE79, 0xBE7F, 0xBE8B, 0xBE8D,
- 0xBE93, 0xBE9F, 0xBEA9, 0xBEB1, 0xBEB5, 0xBEB7, 0xBECF, 0xBED9,
- 0xBEDB, 0xBEE5, 0xBEE7, 0xBEF3, 0xBEF9, 0xBF0B, 0xBF33, 0xBF39,
- 0xBF4D, 0xBF5D, 0xBF5F, 0xBF6B, 0xBF71, 0xBF7B, 0xBF87, 0xBF89,
- 0xBF8D, 0xBF93, 0xBFA1, 0xBFAD, 0xBFB9, 0xBFCF, 0xBFD5, 0xBFDD,
- 0xBFE1, 0xBFE3, 0xBFF3, 0xC005, 0xC011, 0xC013, 0xC019, 0xC029,
- 0xC02F, 0xC031, 0xC037, 0xC03B, 0xC047, 0xC065, 0xC06D, 0xC07D,
- 0xC07F, 0xC091, 0xC09B, 0xC0B3, 0xC0B5, 0xC0BB, 0xC0D3, 0xC0D7,
- 0xC0D9, 0xC0EF, 0xC0F1, 0xC101, 0xC103, 0xC109, 0xC115, 0xC119,
- 0xC12B, 0xC133, 0xC137, 0xC145, 0xC149, 0xC15B, 0xC173, 0xC179,
- 0xC17B, 0xC181, 0xC18B, 0xC18D, 0xC197, 0xC1BD, 0xC1C3, 0xC1CD,
- 0xC1DB, 0xC1E1, 0xC1E7, 0xC1FF, 0xC203, 0xC205, 0xC211, 0xC221,
- 0xC22F, 0xC23F, 0xC24B, 0xC24D, 0xC253, 0xC25D, 0xC277, 0xC27B,
- 0xC27D, 0xC289, 0xC28F, 0xC293, 0xC29F, 0xC2A7, 0xC2B3, 0xC2BD,
- 0xC2CF, 0xC2D5, 0xC2E3, 0xC2FF, 0xC301, 0xC307, 0xC311, 0xC313,
- 0xC317, 0xC325, 0xC347, 0xC349, 0xC34F, 0xC365, 0xC367, 0xC371,
- 0xC37F, 0xC383, 0xC385, 0xC395, 0xC39D, 0xC3A7, 0xC3AD, 0xC3B5,
- 0xC3BF, 0xC3C7, 0xC3CB, 0xC3D1, 0xC3D3, 0xC3E3, 0xC3E9, 0xC3EF,
- 0xC401, 0xC41F, 0xC42D, 0xC433, 0xC437, 0xC455, 0xC457, 0xC461,
- 0xC46F, 0xC473, 0xC487, 0xC491, 0xC499, 0xC49D, 0xC4A5, 0xC4B7,
- 0xC4BB, 0xC4C9, 0xC4CF, 0xC4D3, 0xC4EB, 0xC4F1, 0xC4F7, 0xC509,
- 0xC51B, 0xC51D, 0xC541, 0xC547, 0xC551, 0xC55F, 0xC56B, 0xC56F,
- 0xC575, 0xC577, 0xC595, 0xC59B, 0xC59F, 0xC5A1, 0xC5A7, 0xC5C3,
- 0xC5D7, 0xC5DB, 0xC5EF, 0xC5FB, 0xC613, 0xC623, 0xC635, 0xC641,
- 0xC64F, 0xC655, 0xC659, 0xC665, 0xC685, 0xC691, 0xC697, 0xC6A1,
- 0xC6A9, 0xC6B3, 0xC6B9, 0xC6CB, 0xC6CD, 0xC6DD, 0xC6EB, 0xC6F1,
- 0xC707, 0xC70D, 0xC719, 0xC71B, 0xC72D, 0xC731, 0xC739, 0xC757,
- 0xC763, 0xC767, 0xC773, 0xC775, 0xC77F, 0xC7A5, 0xC7BB, 0xC7BD,
- 0xC7C1, 0xC7CF, 0xC7D5, 0xC7E1, 0xC7F9, 0xC7FD, 0xC7FF, 0xC803,
- 0xC811, 0xC81D, 0xC827, 0xC829, 0xC839, 0xC83F, 0xC853, 0xC857,
- 0xC86B, 0xC881, 0xC88D, 0xC88F, 0xC893, 0xC895, 0xC8A1, 0xC8B7,
- 0xC8CF, 0xC8D5, 0xC8DB, 0xC8DD, 0xC8E3, 0xC8E7, 0xC8ED, 0xC8EF,
- 0xC8F9, 0xC905, 0xC911, 0xC917, 0xC919, 0xC91F, 0xC92F, 0xC937,
- 0xC93D, 0xC941, 0xC953, 0xC95F, 0xC96B, 0xC979, 0xC97D, 0xC989,
- 0xC98F, 0xC997, 0xC99D, 0xC9AF, 0xC9B5, 0xC9BF, 0xC9CB, 0xC9D9,
- 0xC9DF, 0xC9E3, 0xC9EB, 0xCA01, 0xCA07, 0xCA09, 0xCA25, 0xCA37,
- 0xCA39, 0xCA4B, 0xCA55, 0xCA5B, 0xCA69, 0xCA73, 0xCA75, 0xCA7F,
- 0xCA8D, 0xCA93, 0xCA9D, 0xCA9F, 0xCAB5, 0xCABB, 0xCAC3, 0xCAC9,
- 0xCAD9, 0xCAE5, 0xCAED, 0xCB03, 0xCB05, 0xCB09, 0xCB17, 0xCB29,
- 0xCB35, 0xCB3B, 0xCB53, 0xCB59, 0xCB63, 0xCB65, 0xCB71, 0xCB87,
- 0xCB99, 0xCB9F, 0xCBB3, 0xCBB9, 0xCBC3, 0xCBD1, 0xCBD5, 0xCBD7,
- 0xCBDD, 0xCBE9, 0xCBFF, 0xCC0D, 0xCC19, 0xCC1D, 0xCC23, 0xCC2B,
- 0xCC41, 0xCC43, 0xCC4D, 0xCC59, 0xCC61, 0xCC89, 0xCC8B, 0xCC91,
- 0xCC9B, 0xCCA3, 0xCCA7, 0xCCD1, 0xCCE5, 0xCCE9, 0xCD09, 0xCD15,
- 0xCD1F, 0xCD25, 0xCD31, 0xCD3D, 0xCD3F, 0xCD49, 0xCD51, 0xCD57,
- 0xCD5B, 0xCD63, 0xCD67, 0xCD81, 0xCD93, 0xCD97, 0xCD9F, 0xCDBB,
- 0xCDC1, 0xCDD3, 0xCDD9, 0xCDE5, 0xCDE7, 0xCDF1, 0xCDF7, 0xCDFD,
- 0xCE0B, 0xCE15, 0xCE21, 0xCE2F, 0xCE47, 0xCE4D, 0xCE51, 0xCE65,
- 0xCE7B, 0xCE7D, 0xCE8F, 0xCE93, 0xCE99, 0xCEA5, 0xCEA7, 0xCEB7,
- 0xCEC9, 0xCED7, 0xCEDD, 0xCEE3, 0xCEE7, 0xCEED, 0xCEF5, 0xCF07,
- 0xCF0B, 0xCF19, 0xCF37, 0xCF3B, 0xCF4D, 0xCF55, 0xCF5F, 0xCF61,
- 0xCF65, 0xCF6D, 0xCF79, 0xCF7D, 0xCF89, 0xCF9B, 0xCF9D, 0xCFA9,
- 0xCFB3, 0xCFB5, 0xCFC5, 0xCFCD, 0xCFD1, 0xCFEF, 0xCFF1, 0xCFF7,
- 0xD013, 0xD015, 0xD01F, 0xD021, 0xD033, 0xD03D, 0xD04B, 0xD04F,
- 0xD069, 0xD06F, 0xD081, 0xD085, 0xD099, 0xD09F, 0xD0A3, 0xD0AB,
- 0xD0BD, 0xD0C1, 0xD0CD, 0xD0E7, 0xD0FF, 0xD103, 0xD117, 0xD12D,
- 0xD12F, 0xD141, 0xD157, 0xD159, 0xD15D, 0xD169, 0xD16B, 0xD171,
- 0xD177, 0xD17D, 0xD181, 0xD187, 0xD195, 0xD199, 0xD1B1, 0xD1BD,
- 0xD1C3, 0xD1D5, 0xD1D7, 0xD1E3, 0xD1FF, 0xD20D, 0xD211, 0xD217,
- 0xD21F, 0xD235, 0xD23B, 0xD247, 0xD259, 0xD261, 0xD265, 0xD279,
- 0xD27F, 0xD283, 0xD289, 0xD28B, 0xD29D, 0xD2A3, 0xD2A7, 0xD2B3,
- 0xD2BF, 0xD2C7, 0xD2E3, 0xD2E9, 0xD2F1, 0xD2FB, 0xD2FD, 0xD315,
- 0xD321, 0xD32B, 0xD343, 0xD34B, 0xD355, 0xD369, 0xD375, 0xD37B,
- 0xD387, 0xD393, 0xD397, 0xD3A5, 0xD3B1, 0xD3C9, 0xD3EB, 0xD3FD,
- 0xD405, 0xD40F, 0xD415, 0xD427, 0xD42F, 0xD433, 0xD43B, 0xD44B,
- 0xD459, 0xD45F, 0xD463, 0xD469, 0xD481, 0xD483, 0xD489, 0xD48D,
- 0xD493, 0xD495, 0xD4A5, 0xD4AB, 0xD4B1, 0xD4C5, 0xD4DD, 0xD4E1,
- 0xD4E3, 0xD4E7, 0xD4F5, 0xD4F9, 0xD50B, 0xD50D, 0xD513, 0xD51F,
- 0xD523, 0xD531, 0xD535, 0xD537, 0xD549, 0xD559, 0xD55F, 0xD565,
- 0xD567, 0xD577, 0xD58B, 0xD591, 0xD597, 0xD5B5, 0xD5B9, 0xD5C1,
- 0xD5C7, 0xD5DF, 0xD5EF, 0xD5F5, 0xD5FB, 0xD603, 0xD60F, 0xD62D,
- 0xD631, 0xD643, 0xD655, 0xD65D, 0xD661, 0xD67B, 0xD685, 0xD687,
- 0xD69D, 0xD6A5, 0xD6AF, 0xD6BD, 0xD6C3, 0xD6C7, 0xD6D9, 0xD6E1,
- 0xD6ED, 0xD709, 0xD70B, 0xD711, 0xD715, 0xD721, 0xD727, 0xD73F,
- 0xD745, 0xD74D, 0xD757, 0xD76B, 0xD77B, 0xD783, 0xD7A1, 0xD7A7,
- 0xD7AD, 0xD7B1, 0xD7B3, 0xD7BD, 0xD7CB, 0xD7D1, 0xD7DB, 0xD7FB,
- 0xD811, 0xD823, 0xD825, 0xD829, 0xD82B, 0xD82F, 0xD837, 0xD84D,
- 0xD855, 0xD867, 0xD873, 0xD88F, 0xD891, 0xD8A1, 0xD8AD, 0xD8BF,
- 0xD8CD, 0xD8D7, 0xD8E9, 0xD8F5, 0xD8FB, 0xD91B, 0xD925, 0xD933,
- 0xD939, 0xD943, 0xD945, 0xD94F, 0xD951, 0xD957, 0xD96D, 0xD96F,
- 0xD973, 0xD979, 0xD981, 0xD98B, 0xD991, 0xD99F, 0xD9A5, 0xD9A9,
- 0xD9B5, 0xD9D3, 0xD9EB, 0xD9F1, 0xD9F7, 0xD9FF, 0xDA05, 0xDA09,
- 0xDA0B, 0xDA0F, 0xDA15, 0xDA1D, 0xDA23, 0xDA29, 0xDA3F, 0xDA51,
- 0xDA59, 0xDA5D, 0xDA5F, 0xDA71, 0xDA77, 0xDA7B, 0xDA7D, 0xDA8D,
- 0xDA9F, 0xDAB3, 0xDABD, 0xDAC3, 0xDAC9, 0xDAE7, 0xDAE9, 0xDAF5,
- 0xDB11, 0xDB17, 0xDB1D, 0xDB23, 0xDB25, 0xDB31, 0xDB3B, 0xDB43,
- 0xDB55, 0xDB67, 0xDB6B, 0xDB73, 0xDB85, 0xDB8F, 0xDB91, 0xDBAD,
- 0xDBAF, 0xDBB9, 0xDBC7, 0xDBCB, 0xDBCD, 0xDBEB, 0xDBF7, 0xDC0D,
- 0xDC27, 0xDC31, 0xDC39, 0xDC3F, 0xDC49, 0xDC51, 0xDC61, 0xDC6F,
- 0xDC75, 0xDC7B, 0xDC85, 0xDC93, 0xDC99, 0xDC9D, 0xDC9F, 0xDCA9,
- 0xDCB5, 0xDCB7, 0xDCBD, 0xDCC7, 0xDCCF, 0xDCD3, 0xDCD5, 0xDCDF,
- 0xDCF9, 0xDD0F, 0xDD15, 0xDD17, 0xDD23, 0xDD35, 0xDD39, 0xDD53,
- 0xDD57, 0xDD5F, 0xDD69, 0xDD6F, 0xDD7D, 0xDD87, 0xDD89, 0xDD9B,
- 0xDDA1, 0xDDAB, 0xDDBF, 0xDDC5, 0xDDCB, 0xDDCF, 0xDDE7, 0xDDE9,
- 0xDDED, 0xDDF5, 0xDDFB, 0xDE0B, 0xDE19, 0xDE29, 0xDE3B, 0xDE3D,
- 0xDE41, 0xDE4D, 0xDE4F, 0xDE59, 0xDE5B, 0xDE61, 0xDE6D, 0xDE77,
- 0xDE7D, 0xDE83, 0xDE97, 0xDE9D, 0xDEA1, 0xDEA7, 0xDECD, 0xDED1,
- 0xDED7, 0xDEE3, 0xDEF1, 0xDEF5, 0xDF01, 0xDF09, 0xDF13, 0xDF1F,
- 0xDF2B, 0xDF33, 0xDF37, 0xDF3D, 0xDF4B, 0xDF55, 0xDF5B, 0xDF67,
- 0xDF69, 0xDF73, 0xDF85, 0xDF87, 0xDF99, 0xDFA3, 0xDFAB, 0xDFB5,
- 0xDFB7, 0xDFC3, 0xDFC7, 0xDFD5, 0xDFF1, 0xDFF3, 0xE003, 0xE005,
- 0xE017, 0xE01D, 0xE027, 0xE02D, 0xE035, 0xE045, 0xE053, 0xE071,
- 0xE07B, 0xE08F, 0xE095, 0xE09F, 0xE0B7, 0xE0B9, 0xE0D5, 0xE0D7,
- 0xE0E3, 0xE0F3, 0xE0F9, 0xE101, 0xE125, 0xE129, 0xE131, 0xE135,
- 0xE143, 0xE14F, 0xE159, 0xE161, 0xE16D, 0xE171, 0xE177, 0xE17F,
- 0xE183, 0xE189, 0xE197, 0xE1AD, 0xE1B5, 0xE1BB, 0xE1BF, 0xE1C1,
- 0xE1CB, 0xE1D1, 0xE1E5, 0xE1EF, 0xE1F7, 0xE1FD, 0xE203, 0xE219,
- 0xE22B, 0xE22D, 0xE23D, 0xE243, 0xE257, 0xE25B, 0xE275, 0xE279,
- 0xE287, 0xE29D, 0xE2AB, 0xE2AF, 0xE2BB, 0xE2C1, 0xE2C9, 0xE2CD,
- 0xE2D3, 0xE2D9, 0xE2F3, 0xE2FD, 0xE2FF, 0xE311, 0xE323, 0xE327,
- 0xE329, 0xE339, 0xE33B, 0xE34D, 0xE351, 0xE357, 0xE35F, 0xE363,
- 0xE369, 0xE375, 0xE377, 0xE37D, 0xE383, 0xE39F, 0xE3C5, 0xE3C9,
- 0xE3D1, 0xE3E1, 0xE3FB, 0xE3FF, 0xE401, 0xE40B, 0xE417, 0xE419,
- 0xE423, 0xE42B, 0xE431, 0xE43B, 0xE447, 0xE449, 0xE453, 0xE455,
- 0xE46D, 0xE471, 0xE48F, 0xE4A9, 0xE4AF, 0xE4B5, 0xE4C7, 0xE4CD,
- 0xE4D3, 0xE4E9, 0xE4EB, 0xE4F5, 0xE507, 0xE521, 0xE525, 0xE537,
- 0xE53F, 0xE545, 0xE54B, 0xE557, 0xE567, 0xE56D, 0xE575, 0xE585,
- 0xE58B, 0xE593, 0xE5A3, 0xE5A5, 0xE5CF, 0xE609, 0xE611, 0xE615,
- 0xE61B, 0xE61D, 0xE621, 0xE629, 0xE639, 0xE63F, 0xE653, 0xE657,
- 0xE663, 0xE66F, 0xE675, 0xE681, 0xE683, 0xE68D, 0xE68F, 0xE695,
- 0xE6AB, 0xE6AD, 0xE6B7, 0xE6BD, 0xE6C5, 0xE6CB, 0xE6D5, 0xE6E3,
- 0xE6E9, 0xE6EF, 0xE6F3, 0xE705, 0xE70D, 0xE717, 0xE71F, 0xE72F,
- 0xE73D, 0xE747, 0xE749, 0xE753, 0xE755, 0xE761, 0xE767, 0xE76B,
- 0xE77F, 0xE789, 0xE791, 0xE7C5, 0xE7CD, 0xE7D7, 0xE7DD, 0xE7DF,
- 0xE7E9, 0xE7F1, 0xE7FB, 0xE801, 0xE807, 0xE80F, 0xE819, 0xE81B,
- 0xE831, 0xE833, 0xE837, 0xE83D, 0xE84B, 0xE84F, 0xE851, 0xE869,
- 0xE875, 0xE879, 0xE893, 0xE8A5, 0xE8A9, 0xE8AF, 0xE8BD, 0xE8DB,
- 0xE8E1, 0xE8E5, 0xE8EB, 0xE8ED, 0xE903, 0xE90B, 0xE90F, 0xE915,
- 0xE917, 0xE92D, 0xE933, 0xE93B, 0xE94B, 0xE951, 0xE95F, 0xE963,
- 0xE969, 0xE97B, 0xE983, 0xE98F, 0xE995, 0xE9A1, 0xE9B9, 0xE9D7,
- 0xE9E7, 0xE9EF, 0xEA11, 0xEA19, 0xEA2F, 0xEA35, 0xEA43, 0xEA4D,
- 0xEA5F, 0xEA6D, 0xEA71, 0xEA7D, 0xEA85, 0xEA89, 0xEAAD, 0xEAB3,
- 0xEAB9, 0xEABB, 0xEAC5, 0xEAC7, 0xEACB, 0xEADF, 0xEAE5, 0xEAEB,
- 0xEAF5, 0xEB01, 0xEB07, 0xEB09, 0xEB31, 0xEB39, 0xEB3F, 0xEB5B,
- 0xEB61, 0xEB63, 0xEB6F, 0xEB81, 0xEB85, 0xEB9D, 0xEBAB, 0xEBB1,
- 0xEBB7, 0xEBC1, 0xEBD5, 0xEBDF, 0xEBED, 0xEBFD, 0xEC0B, 0xEC1B,
- 0xEC21, 0xEC29, 0xEC4D, 0xEC51, 0xEC5D, 0xEC69, 0xEC6F, 0xEC7B,
- 0xECAD, 0xECB9, 0xECBF, 0xECC3, 0xECC9, 0xECCF, 0xECD7, 0xECDD,
- 0xECE7, 0xECE9, 0xECF3, 0xECF5, 0xED07, 0xED11, 0xED1F, 0xED2F,
- 0xED37, 0xED3D, 0xED41, 0xED55, 0xED59, 0xED5B, 0xED65, 0xED6B,
- 0xED79, 0xED8B, 0xED95, 0xEDBB, 0xEDC5, 0xEDD7, 0xEDD9, 0xEDE3,
- 0xEDE5, 0xEDF1, 0xEDF5, 0xEDF7, 0xEDFB, 0xEE09, 0xEE0F, 0xEE19,
- 0xEE21, 0xEE49, 0xEE4F, 0xEE63, 0xEE67, 0xEE73, 0xEE7B, 0xEE81,
- 0xEEA3, 0xEEAB, 0xEEC1, 0xEEC9, 0xEED5, 0xEEDF, 0xEEE1, 0xEEF1,
- 0xEF1B, 0xEF27, 0xEF2F, 0xEF45, 0xEF4D, 0xEF63, 0xEF6B, 0xEF71,
- 0xEF93, 0xEF95, 0xEF9B, 0xEF9F, 0xEFAD, 0xEFB3, 0xEFC3, 0xEFC5,
- 0xEFDB, 0xEFE1, 0xEFE9, 0xF001, 0xF017, 0xF01D, 0xF01F, 0xF02B,
- 0xF02F, 0xF035, 0xF043, 0xF047, 0xF04F, 0xF067, 0xF06B, 0xF071,
- 0xF077, 0xF079, 0xF08F, 0xF0A3, 0xF0A9, 0xF0AD, 0xF0BB, 0xF0BF,
- 0xF0C5, 0xF0CB, 0xF0D3, 0xF0D9, 0xF0E3, 0xF0E9, 0xF0F1, 0xF0F7,
- 0xF107, 0xF115, 0xF11B, 0xF121, 0xF137, 0xF13D, 0xF155, 0xF175,
- 0xF17B, 0xF18D, 0xF193, 0xF1A5, 0xF1AF, 0xF1B7, 0xF1D5, 0xF1E7,
- 0xF1ED, 0xF1FD, 0xF209, 0xF20F, 0xF21B, 0xF21D, 0xF223, 0xF227,
- 0xF233, 0xF23B, 0xF241, 0xF257, 0xF25F, 0xF265, 0xF269, 0xF277,
- 0xF281, 0xF293, 0xF2A7, 0xF2B1, 0xF2B3, 0xF2B9, 0xF2BD, 0xF2BF,
- 0xF2DB, 0xF2ED, 0xF2EF, 0xF2F9, 0xF2FF, 0xF305, 0xF30B, 0xF319,
- 0xF341, 0xF359, 0xF35B, 0xF35F, 0xF367, 0xF373, 0xF377, 0xF38B,
- 0xF38F, 0xF3AF, 0xF3C1, 0xF3D1, 0xF3D7, 0xF3FB, 0xF403, 0xF409,
- 0xF40D, 0xF413, 0xF421, 0xF425, 0xF42B, 0xF445, 0xF44B, 0xF455,
- 0xF463, 0xF475, 0xF47F, 0xF485, 0xF48B, 0xF499, 0xF4A3, 0xF4A9,
- 0xF4AF, 0xF4BD, 0xF4C3, 0xF4DB, 0xF4DF, 0xF4ED, 0xF503, 0xF50B,
- 0xF517, 0xF521, 0xF529, 0xF535, 0xF547, 0xF551, 0xF563, 0xF56B,
- 0xF583, 0xF58D, 0xF595, 0xF599, 0xF5B1, 0xF5B7, 0xF5C9, 0xF5CF,
- 0xF5D1, 0xF5DB, 0xF5F9, 0xF5FB, 0xF605, 0xF607, 0xF60B, 0xF60D,
- 0xF635, 0xF637, 0xF653, 0xF65B, 0xF661, 0xF667, 0xF679, 0xF67F,
- 0xF689, 0xF697, 0xF69B, 0xF6AD, 0xF6CB, 0xF6DD, 0xF6DF, 0xF6EB,
- 0xF709, 0xF70F, 0xF72D, 0xF731, 0xF743, 0xF74F, 0xF751, 0xF755,
- 0xF763, 0xF769, 0xF773, 0xF779, 0xF781, 0xF787, 0xF791, 0xF79D,
- 0xF79F, 0xF7A5, 0xF7B1, 0xF7BB, 0xF7BD, 0xF7CF, 0xF7D3, 0xF7E7,
- 0xF7EB, 0xF7F1, 0xF7FF, 0xF805, 0xF80B, 0xF821, 0xF827, 0xF82D,
- 0xF835, 0xF847, 0xF859, 0xF863, 0xF865, 0xF86F, 0xF871, 0xF877,
- 0xF87B, 0xF881, 0xF88D, 0xF89F, 0xF8A1, 0xF8AB, 0xF8B3, 0xF8B7,
- 0xF8C9, 0xF8CB, 0xF8D1, 0xF8D7, 0xF8DD, 0xF8E7, 0xF8EF, 0xF8F9,
- 0xF8FF, 0xF911, 0xF91D, 0xF925, 0xF931, 0xF937, 0xF93B, 0xF941,
- 0xF94F, 0xF95F, 0xF961, 0xF96D, 0xF971, 0xF977, 0xF99D, 0xF9A3,
- 0xF9A9, 0xF9B9, 0xF9CD, 0xF9E9, 0xF9FD, 0xFA07, 0xFA0D, 0xFA13,
- 0xFA21, 0xFA25, 0xFA3F, 0xFA43, 0xFA51, 0xFA5B, 0xFA6D, 0xFA7B,
- 0xFA97, 0xFA99, 0xFA9D, 0xFAAB, 0xFABB, 0xFABD, 0xFAD9, 0xFADF,
- 0xFAE7, 0xFAED, 0xFB0F, 0xFB17, 0xFB1B, 0xFB2D, 0xFB2F, 0xFB3F,
- 0xFB47, 0xFB4D, 0xFB75, 0xFB7D, 0xFB8F, 0xFB93, 0xFBB1, 0xFBB7,
- 0xFBC3, 0xFBC5, 0xFBE3, 0xFBE9, 0xFBF3, 0xFC01, 0xFC29, 0xFC37,
- 0xFC41, 0xFC43, 0xFC4F, 0xFC59, 0xFC61, 0xFC65, 0xFC6D, 0xFC73,
- 0xFC79, 0xFC95, 0xFC97, 0xFC9B, 0xFCA7, 0xFCB5, 0xFCC5, 0xFCCD,
- 0xFCEB, 0xFCFB, 0xFD0D, 0xFD0F, 0xFD19, 0xFD2B, 0xFD31, 0xFD51,
- 0xFD55, 0xFD67, 0xFD6D, 0xFD6F, 0xFD7B, 0xFD85, 0xFD97, 0xFD99,
- 0xFD9F, 0xFDA9, 0xFDB7, 0xFDC9, 0xFDE5, 0xFDEB, 0xFDF3, 0xFE03,
- 0xFE05, 0xFE09, 0xFE1D, 0xFE27, 0xFE2F, 0xFE41, 0xFE4B, 0xFE4D,
- 0xFE57, 0xFE5F, 0xFE63, 0xFE69, 0xFE75, 0xFE7B, 0xFE8F, 0xFE93,
- 0xFE95, 0xFE9B, 0xFE9F, 0xFEB3, 0xFEBD, 0xFED7, 0xFEE9, 0xFEF3,
- 0xFEF5, 0xFF07, 0xFF0D, 0xFF1D, 0xFF2B, 0xFF2F, 0xFF49, 0xFF4D,
- 0xFF5B, 0xFF65, 0xFF71, 0xFF7F, 0xFF85, 0xFF8B, 0xFF8F, 0xFF9D,
- 0xFFA7, 0xFFA9, 0xFFC7, 0xFFD9, 0xFFEF, 0xFFF1,
-#endif
-};
-
diff --git a/security/nss/lib/freebl/mpi/stats b/security/nss/lib/freebl/mpi/stats
deleted file mode 100755
index 599298f4f..000000000
--- a/security/nss/lib/freebl/mpi/stats
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/perl
-
-#
-# Treat each line as a sequence of comma and/or space delimited
-# floating point numbers, and compute basic statistics on them.
-# These are written to standard output
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-#
-
-$min = 1.7976931348623157E+308;
-$max = 2.2250738585072014E-308;
-$sum = $num = 0;
-
-while(<>) {
- chomp;
-
- @nums = split(/[\s,]+/, $_);
- next if($#nums < 0);
-
- $num += scalar @nums;
- foreach (@nums) {
- $min = $_ if($_ < $min);
- $max = $_ if($_ > $max);
- $sum += $_;
- }
-}
-
-if($num) {
- $avg = $sum / $num;
-} else {
- $min = $max = 0;
-}
-
-printf "%d\tmin=%.2f, avg=%.2f, max=%.2f, sum=%.2f\n",
- $num, $min, $avg, $max, $sum;
-
-# end
diff --git a/security/nss/lib/freebl/mpi/target.mk b/security/nss/lib/freebl/mpi/target.mk
deleted file mode 100644
index 2392faff1..000000000
--- a/security/nss/lib/freebl/mpi/target.mk
+++ /dev/null
@@ -1,233 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-##
-## Define CFLAGS to contain any local options your compiler
-## setup requires.
-##
-## Conditional compilation options are no longer here; see
-## the file 'mpi-config.h' instead.
-##
-MPICMN = -I. -DMP_API_COMPATIBLE -DMP_IOFUNC
-CFLAGS= -O $(MPICMN)
-#CFLAGS=-ansi -fullwarn -woff 1521 -O3 $(MPICMN)
-#CFLAGS=-ansi -pedantic -Wall -O3 $(MPICMN)
-#CFLAGS=-ansi -pedantic -Wall -g -O2 -DMP_DEBUG=1 $(MPICMN)
-
-ifeq ($(TARGET),mipsIRIX)
-#IRIX
-#MPICMN += -DMP_MONT_USE_MP_MUL
-MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
-MPICMN += -DMP_USE_UINT_DIGIT
-#MPICMN += -DMP_NO_MP_WORD
-AS_OBJS = mpi_mips.o
-#ASFLAGS = -O -OPT:Olimit=4000 -dollar -fullwarn -xansi -n32 -mips3 -exceptions
-ASFLAGS = -O -OPT:Olimit=4000 -dollar -fullwarn -xansi -n32 -mips3
-#CFLAGS=-ansi -n32 -O3 -fullwarn -woff 1429 -D_SGI_SOURCE $(MPICMN)
-CFLAGS=-ansi -n32 -O2 -fullwarn -woff 1429 -D_SGI_SOURCE $(MPICMN)
-#CFLAGS=-ansi -n32 -g -fullwarn -woff 1429 -D_SGI_SOURCE $(MPICMN)
-#CFLAGS=-ansi -64 -O2 -fullwarn -woff 1429 -D_SGI_SOURCE -DMP_NO_MP_WORD \
- $(MPICMN)
-endif
-
-ifeq ($(TARGET),alphaOSF1)
-#Alpha/OSF1
-MPICMN += -DMP_ASSEMBLY_MULTIPLY
-AS_OBJS+= mpvalpha.o
-#CFLAGS= -O -Olimit 4000 -ieee_with_inexact -std1 -DOSF1 -D_REENTRANT $(MPICMN)
-CFLAGS= -O -Olimit 4000 -ieee_with_inexact -std1 -DOSF1 -D_REENTRANT \
- -DMP_NO_MP_WORD $(MPICMN)
-endif
-
-ifeq ($(TARGET),v9SOLARIS)
-#Solaris 64
-SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xchip=ultra -xarch=v9a -KPIC -mt
-#SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xdepend -xchip=ultra -xarch=v9a -KPIC -mt
-SOLARIS_ASM_FLAGS = -xchip=ultra -xarch=v9a -KPIC -mt
-AS_OBJS += montmulfv9.o
-AS_OBJS += mpi_sparc.o mpv_sparcv9.o
-MPICMN += -DMP_USE_UINT_DIGIT
-#MPICMN += -DMP_NO_MP_WORD
-MPICMN += -DMP_ASSEMBLY_MULTIPLY
-MPICMN += -DMP_USING_MONT_MULF
-CFLAGS= -O -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \
- -DSOLARIS2_8 -xarch=v9 -DXP_UNIX $(MPICMN)
-#CFLAGS= -g -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \
- -DSOLARIS2_8 -xarch=v9 -DXP_UNIX $(MPICMN)
-endif
-
-ifeq ($(TARGET),v8plusSOLARIS)
-#Solaris 32
-SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xdepend -xchip=ultra -xarch=v8plusa -KPIC -mt
-SOLARIS_ASM_FLAGS = -xchip=ultra -xarch=v8plusa -KPIC -mt
-AS_OBJS += montmulfv8.o
-AS_OBJS += mpi_sparc.o mpv_sparcv8.o
-#AS_OBJS = montmulf.o
-MPICMN += -DMP_ASSEMBLY_MULTIPLY
-MPICMN += -DMP_USING_MONT_MULF
-MPICMN += -DMP_USE_UINT_DIGIT
-MPICMN += -DMP_NO_MP_WORD
-CFLAGS=-O -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \
- -DSOLARIS2_6 -xarch=v8plus -DXP_UNIX $(MPICMN)
-endif
-
-ifeq ($(TARGET),v8SOLARIS)
-#Solaris 32
-#SOLARIS_FPU_FLAGS = -fast -xO5 -xrestrict=%all -xdepend -xchip=ultra -xarch=v8 -KPIC -mt
-#SOLARIS_ASM_FLAGS = -xchip=ultra -xarch=v8plusa -KPIC -mt
-#AS_OBJS = montmulfv8.o mpi_sparc.o mpv_sparcv8.o
-#AS_OBJS = montmulf.o
-#MPICMN += -DMP_USING_MONT_MULF
-#MPICMN += -DMP_ASSEMBLY_MULTIPLY
-MPICMN += -DMP_USE_LONG_LONG_MULTIPLY -DMP_USE_UINT_DIGIT
-MPICMN += -DMP_NO_MP_WORD
-CFLAGS=-O -KPIC -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT \
- -DSOLARIS2_6 -xarch=v8 -DXP_UNIX $(MPICMN)
-endif
-
-ifeq ($(TARGET),ia64HPUX)
-#HPUX 32 on ia64 -- 64 bit digits SCREAM.
-# This one is for DD32 which is the 32-bit ABI with 64-bit registers.
-CFLAGS= +O3 -DHPUX10 -D_POSIX_C_SOURCE=199506L -Aa +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE -Aa +e -z +p +DD32 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
-#CFLAGS= -O -DHPUX10 -D_POSIX_C_SOURCE=199506L -Aa +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE -Aa +e -z +p +DD32 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
-#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE -Aa +e -z +p +DD32 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
-endif
-
-ifeq ($(TARGET),ia64HPUX64)
-#HPUX 32 on ia64
-# This one is for DD64 which is the 64-bit ABI
-CFLAGS= +O3 -DHPUX10 -D_POSIX_C_SOURCE=199506L -Aa +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE -Aa +e -z +p +DD64 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
-#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE -Aa +e -z +p +DD64 -DHPUX11 -DXP_UNIX -Wl,+k $(MPICMN)
-endif
-
-ifeq ($(TARGET),PA2.0WHPUX)
-#HPUX64 (HP PA 2.0 Wide) using MAXPY and 64-bit digits
-MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
-AS_OBJS = mpi_hp.o hpma512.o hppa20.o
-CFLAGS= -O -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE -Aa +e -z +DA2.0W +DS2.0 +O3 +DChpux -DHPUX11 -DXP_UNIX \
- $(MPICMN)
-#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE -Aa +e -z +DA2.0W +DS2.0 +DChpux -DHPUX11 -DXP_UNIX \
- $(MPICMN)
-AS = $(CC) $(CFLAGS) -c
-endif
-
-ifeq ($(TARGET),PA2.0NHPUX)
-#HPUX32 (HP PA 2.0 Narrow) hybrid model, using 32-bit digits
-# This one is for DA2.0 (N) which is the 32-bit ABI with 64-bit registers.
-MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
-AS_OBJS = mpi_hp.o hpma512.o hppa20.o
-CFLAGS= +O3 -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE -Aa +e -z +DA2.0 +DS2.0 +DChpux -DHPUX11 -DXP_UNIX \
- -Wl,+k $(MPICMN)
-#CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE -Aa +e -z +DA2.0 +DS2.0 +DChpux -DHPUX11 -DXP_UNIX \
- -Wl,+k $(MPICMN)
-AS = $(CC) $(CFLAGS) -c
-endif
-
-ifeq ($(TARGET),PA1.1HPUX)
-#HPUX32 (HP PA 1.1) Pure 32 bit
-MPICMN += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
-#MPICMN += -DMP_USE_LONG_LONG_MULTIPLY
-CFLAGS= -O -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
- -D_HPUX_SOURCE +DAportable +DS1.1 -DHPUX11 -DXP_UNIX $(MPICMN)
-##CFLAGS= -g -DHPUX10 -D_POSIX_C_SOURCE=199506L -Ae +Z -DHPUX -Dhppa \
-# -D_HPUX_SOURCE +DAportable +DS1.1 -DHPUX11 -DXP_UNIX $(MPICMN)
-endif
-
-ifeq ($(TARGET),32AIX)
-#
-CC = xlC_r
-MPICMN += -DMP_USE_UINT_DIGIT
-MPICMN += -DMP_NO_DIV_WORD
-#MPICMN += -DMP_NO_MUL_WORD
-MPICMN += -DMP_NO_ADD_WORD
-MPICMN += -DMP_NO_SUB_WORD
-#MPICMN += -DMP_NO_MP_WORD
-#MPICMN += -DMP_USE_LONG_LONG_MULTIPLY
-CFLAGS = -O -DAIX -DSYSV -qarch=com -DAIX4_3 -DXP_UNIX -UDEBUG -DNDEBUG $(MPICMN)
-#CFLAGS = -g -DAIX -DSYSV -qarch=com -DAIX4_3 -DXP_UNIX -UDEBUG -DNDEBUG $(MPICMN)
-#CFLAGS += -pg
-endif
-
-ifeq ($(TARGET),64AIX)
-#
-CC = xlC_r
-MPICMN += -DMP_USE_UINT_DIGIT
-CFLAGS = -O -O2 -DAIX -DSYSV -qarch=com -DAIX_64BIT -DAIX4_3 -DXP_UNIX -UDEBUG -DNDEBUG $(MPICMN)
-OBJECT_MODE=64
-export OBJECT_MODE
-endif
-
-ifeq ($(TARGET),x86LINUX)
-#Linux
-AS_OBJS = mpi_x86.o
-MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
-MPICMN += -DMP_MONT_USE_MP_MUL -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
-CFLAGS= -O2 -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \
- -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \
- -DXP_UNIX -UDEBUG -DNDEBUG -D_REENTRANT $(MPICMN)
-#CFLAGS= -g -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \
- -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \
- -DXP_UNIX -DDEBUG -UNDEBUG -D_REENTRANT $(MPICMN)
-#CFLAGS= -g -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \
- -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \
- -DXP_UNIX -UDEBUG -DNDEBUG -D_REENTRANT $(MPICMN)
-endif
-
-ifeq ($(TARGET),armLINUX)
-MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
-MPICMN += -DMP_USE_UINT_DIGIT
-AS_OBJS += mpi_arm.o
-endif
-
-ifeq ($(TARGET),AMD64SOLARIS)
-ASFLAGS += -xarch=generic64
-AS_OBJS = mpi_amd64.o mpi_amd64_sun.o
-MP_CONFIG = -DMP_ASSEMBLY_MULTIPLY -DMPI_AMD64
-MP_CONFIG += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
-CFLAGS = -xarch=generic64 -xO4 -I. -DMP_API_COMPATIBLE -DMP_IOFUNC $(MP_CONFIG)
-MPICMN += $(MP_CONFIG)
-
-mpi_amd64_asm.o: mpi_amd64_sun.s
- $(AS) -xarch=generic64 -P -D_ASM mpi_amd64_sun.s
-endif
-
-ifeq ($(TARGET),WIN32)
-ifeq ($(CPU_ARCH),x86_64)
-AS_OBJS = mpi_amd64.obj mpi_amd64_masm.obj mp_comba_amd64_masm.asm
-CFLAGS = -Od -Z7 -MDd -W3 -nologo -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USER)
-CFLAGS += -DWIN32 -DWIN64 -D_WINDOWS -D_AMD_64_ -D_M_AMD64 -DWIN95 -DXP_PC -DNSS_ENABLE_ECC
-CFLAGS += $(MPICMN)
-
-$(AS_OBJS): %.obj : %.asm
- ml64 -Cp -Sn -Zi -coff -nologo -c $<
-
-$(LIBOBJS): %.obj : %.c
- cl $(CFLAGS) -Fo$@ -c $<
-else
-AS_OBJS = mpi_x86.obj
-MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
-MPICMN += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD -DMP_API_COMPATIBLE
-MPICMN += -DMP_MONT_USE_MP_MUL
-MPICMN += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
-CFLAGS = -Od -Z7 -MDd -W3 -nologo -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USER)
-CFLAGS += -DWIN32 -D_WINDOWS -D_X86_ -DWIN95 -DXP_PC -DNSS_ENABLE_ECC
-CFLAGS += $(MPICMN)
-
-$(AS_OBJS): %.obj : %.asm
- ml -Cp -Sn -Zi -coff -nologo -c $<
-
-$(LIBOBJS): %.obj : %.c
- cl $(CFLAGS) -Fo$@ -c $<
-
-endif
-endif
diff --git a/security/nss/lib/freebl/mpi/test-arrays.txt b/security/nss/lib/freebl/mpi/test-arrays.txt
deleted file mode 100644
index 0268bd94b..000000000
--- a/security/nss/lib/freebl/mpi/test-arrays.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Test suite table for MPI library
-#
-# Format of entries:
-# suite-name:function-name:description
-#
-# suite-name The name used to identify this test in mpi-test
-# function-name The function called to perform this test in mpi-test.c
-# description A brief description of what the suite tests
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-#
-list:test_list:print out a list of the available test suites
-copy:test_copy:test assignment of mp-int structures
-exchange:test_exch:test exchange of mp-int structures
-zero:test_zero:test zeroing of an mp-int
-set:test_set:test setting an mp-int to a small constant
-absolute-value:test_abs:test the absolute value function
-negate:test_neg:test the arithmetic negation function
-add-digit:test_add_d:test digit addition
-add:test_add:test full addition
-subtract-digit:test_sub_d:test digit subtraction
-subtract:test_sub:test full subtraction
-multiply-digit:test_mul_d:test digit multiplication
-multiply:test_mul:test full multiplication
-square:test_sqr:test full squaring function
-divide-digit:test_div_d:test digit division
-divide-2:test_div_2:test division by two
-divide-2d:test_div_2d:test division & remainder by 2^d
-divide:test_div:test full division
-expt-digit:test_expt_d:test digit exponentiation
-expt:test_expt:test full exponentiation
-expt-2:test_2expt:test power-of-two exponentiation
-square-root:test_sqrt:test integer square root function
-modulo-digit:test_mod_d:test digit modular reduction
-modulo:test_mod:test full modular reduction
-mod-add:test_addmod:test modular addition
-mod-subtract:test_submod:test modular subtraction
-mod-multiply:test_mulmod:test modular multiplication
-mod-square:test_sqrmod:test modular squaring function
-mod-expt:test_exptmod:test full modular exponentiation
-mod-expt-digit:test_exptmod_d:test digit modular exponentiation
-mod-inverse:test_invmod:test modular inverse function
-compare-digit:test_cmp_d:test digit comparison function
-compare-zero:test_cmp_z:test zero comparison function
-compare:test_cmp:test general signed comparison
-compare-magnitude:test_cmp_mag:test general magnitude comparison
-parity:test_parity:test parity comparison functions
-gcd:test_gcd:test greatest common divisor functions
-lcm:test_lcm:test least common multiple function
-conversion:test_convert:test general radix conversion facilities
-binary:test_raw:test raw output format
-pprime:test_pprime:test probabilistic primality tester
-fermat:test_fermat:test Fermat pseudoprimality tester
diff --git a/security/nss/lib/freebl/mpi/test-info.c b/security/nss/lib/freebl/mpi/test-info.c
deleted file mode 100644
index 6335e949b..000000000
--- a/security/nss/lib/freebl/mpi/test-info.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * test-info.c
- *
- * Arbitrary precision integer arithmetic library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* Table mapping test suite names to index numbers */
-const int g_count = 42;
-const char *g_names[] = {
- "list", /* print out a list of the available test suites */
- "copy", /* test assignment of mp-int structures */
- "exchange", /* test exchange of mp-int structures */
- "zero", /* test zeroing of an mp-int */
- "set", /* test setting an mp-int to a small constant */
- "absolute-value", /* test the absolute value function */
- "negate", /* test the arithmetic negation function */
- "add-digit", /* test digit addition */
- "add", /* test full addition */
- "subtract-digit", /* test digit subtraction */
- "subtract", /* test full subtraction */
- "multiply-digit", /* test digit multiplication */
- "multiply", /* test full multiplication */
- "square", /* test full squaring function */
- "divide-digit", /* test digit division */
- "divide-2", /* test division by two */
- "divide-2d", /* test division & remainder by 2^d */
- "divide", /* test full division */
- "expt-digit", /* test digit exponentiation */
- "expt", /* test full exponentiation */
- "expt-2", /* test power-of-two exponentiation */
- "square-root", /* test integer square root function */
- "modulo-digit", /* test digit modular reduction */
- "modulo", /* test full modular reduction */
- "mod-add", /* test modular addition */
- "mod-subtract", /* test modular subtraction */
- "mod-multiply", /* test modular multiplication */
- "mod-square", /* test modular squaring function */
- "mod-expt", /* test full modular exponentiation */
- "mod-expt-digit", /* test digit modular exponentiation */
- "mod-inverse", /* test modular inverse function */
- "compare-digit", /* test digit comparison function */
- "compare-zero", /* test zero comparison function */
- "compare", /* test general signed comparison */
- "compare-magnitude", /* test general magnitude comparison */
- "parity", /* test parity comparison functions */
- "gcd", /* test greatest common divisor functions */
- "lcm", /* test least common multiple function */
- "conversion", /* test general radix conversion facilities */
- "binary", /* test raw output format */
- "pprime", /* test probabilistic primality tester */
- "fermat" /* test Fermat pseudoprimality tester */
-};
-
-/* Test function prototypes */
-int test_list(void);
-int test_copy(void);
-int test_exch(void);
-int test_zero(void);
-int test_set(void);
-int test_abs(void);
-int test_neg(void);
-int test_add_d(void);
-int test_add(void);
-int test_sub_d(void);
-int test_sub(void);
-int test_mul_d(void);
-int test_mul(void);
-int test_sqr(void);
-int test_div_d(void);
-int test_div_2(void);
-int test_div_2d(void);
-int test_div(void);
-int test_expt_d(void);
-int test_expt(void);
-int test_2expt(void);
-int test_sqrt(void);
-int test_mod_d(void);
-int test_mod(void);
-int test_addmod(void);
-int test_submod(void);
-int test_mulmod(void);
-int test_sqrmod(void);
-int test_exptmod(void);
-int test_exptmod_d(void);
-int test_invmod(void);
-int test_cmp_d(void);
-int test_cmp_z(void);
-int test_cmp(void);
-int test_cmp_mag(void);
-int test_parity(void);
-int test_gcd(void);
-int test_lcm(void);
-int test_convert(void);
-int test_raw(void);
-int test_pprime(void);
-int test_fermat(void);
-
-/* Table mapping index numbers to functions */
-int (*g_tests[])(void) = {
- test_list, test_copy, test_exch, test_zero,
- test_set, test_abs, test_neg, test_add_d,
- test_add, test_sub_d, test_sub, test_mul_d,
- test_mul, test_sqr, test_div_d, test_div_2,
- test_div_2d, test_div, test_expt_d, test_expt,
- test_2expt, test_sqrt, test_mod_d, test_mod,
- test_addmod, test_submod, test_mulmod, test_sqrmod,
- test_exptmod, test_exptmod_d, test_invmod, test_cmp_d,
- test_cmp_z, test_cmp, test_cmp_mag, test_parity,
- test_gcd, test_lcm, test_convert, test_raw,
- test_pprime, test_fermat
-};
-
-/* Table mapping index numbers to descriptions */
-const char *g_descs[] = {
- "print out a list of the available test suites",
- "test assignment of mp-int structures",
- "test exchange of mp-int structures",
- "test zeroing of an mp-int",
- "test setting an mp-int to a small constant",
- "test the absolute value function",
- "test the arithmetic negation function",
- "test digit addition",
- "test full addition",
- "test digit subtraction",
- "test full subtraction",
- "test digit multiplication",
- "test full multiplication",
- "test full squaring function",
- "test digit division",
- "test division by two",
- "test division & remainder by 2^d",
- "test full division",
- "test digit exponentiation",
- "test full exponentiation",
- "test power-of-two exponentiation",
- "test integer square root function",
- "test digit modular reduction",
- "test full modular reduction",
- "test modular addition",
- "test modular subtraction",
- "test modular multiplication",
- "test modular squaring function",
- "test full modular exponentiation",
- "test digit modular exponentiation",
- "test modular inverse function",
- "test digit comparison function",
- "test zero comparison function",
- "test general signed comparison",
- "test general magnitude comparison",
- "test parity comparison functions",
- "test greatest common divisor functions",
- "test least common multiple function",
- "test general radix conversion facilities",
- "test raw output format",
- "test probabilistic primality tester",
- "test Fermat pseudoprimality tester"
-};
-
diff --git a/security/nss/lib/freebl/mpi/tests/LICENSE b/security/nss/lib/freebl/mpi/tests/LICENSE
deleted file mode 100644
index c2c5d0190..000000000
--- a/security/nss/lib/freebl/mpi/tests/LICENSE
+++ /dev/null
@@ -1,6 +0,0 @@
-Within this directory, each of the file listed below is licensed under
-the terms given in the file LICENSE-MPL, also in this directory.
-
-pi1k.txt
-pi2k.txt
-pi5k.txt
diff --git a/security/nss/lib/freebl/mpi/tests/LICENSE-MPL b/security/nss/lib/freebl/mpi/tests/LICENSE-MPL
deleted file mode 100644
index d1f78f522..000000000
--- a/security/nss/lib/freebl/mpi/tests/LICENSE-MPL
+++ /dev/null
@@ -1,35 +0,0 @@
-***** BEGIN LICENSE BLOCK *****
-Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
-The contents of this file are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-The Original Code is the Netscape security libraries.
-
-The Initial Developer of the Original Code is Netscape
-Communications Corporation. Portions created by Netscape are
-Copyright (C) 1994-2000 Netscape Communications Corporation. All
-Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of this file only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of this file under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of this file under
-the terms of any one of the MPL, the GPL or the LGPL.
-
-***** END LICENSE BLOCK *****
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-1.c b/security/nss/lib/freebl/mpi/tests/mptest-1.c
deleted file mode 100644
index bd30ddfd6..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-1.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 1: Simple input test (drives single-digit multiply and add,
- * as well as I/O routines)
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-
-#ifdef MAC_CW_SIOUX
-#include <console.h>
-#endif
-
-#include "mpi.h"
-
-int main(int argc, char *argv[])
-{
- int ix;
- mp_int mp;
-
-#ifdef MAC_CW_SIOUX
- argc = ccommand(&argv);
-#endif
-
- mp_init(&mp);
-
- for(ix = 1; ix < argc; ix++) {
- mp_read_radix(&mp, argv[ix], 10);
- mp_print(&mp, stdout);
- fputc('\n', stdout);
- }
-
- mp_clear(&mp);
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-2.c b/security/nss/lib/freebl/mpi/tests/mptest-2.c
deleted file mode 100644
index fd686c7fb..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-2.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 2: Basic addition and subtraction test
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include "mpi.h"
-
-int main(int argc, char *argv[])
-{
- mp_int a, b, c;
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]);
- return 1;
- }
-
- printf("Test 2: Basic addition and subtraction\n\n");
-
- mp_init(&a);
- mp_init(&b);
-
- mp_read_radix(&a, argv[1], 10);
- mp_read_radix(&b, argv[2], 10);
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
-
- mp_init(&c);
- printf("c = a + b\n");
-
- mp_add(&a, &b, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- printf("c = a - b\n");
-
- mp_sub(&a, &b, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- mp_clear(&c);
- mp_clear(&b);
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-3.c b/security/nss/lib/freebl/mpi/tests/mptest-3.c
deleted file mode 100644
index 6bd588980..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-3.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 3: Multiplication, division, and exponentiation test
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include <time.h>
-
-#include "mpi.h"
-
-#define SQRT 1 /* define nonzero to get square-root test */
-#define EXPT 0 /* define nonzero to get exponentiate test */
-
-int main(int argc, char *argv[])
-{
- int ix;
- mp_int a, b, c, d;
- mp_digit r;
- mp_err res;
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]);
- return 1;
- }
-
- printf("Test 3: Multiplication and division\n\n");
- srand(time(NULL));
-
- mp_init(&a);
- mp_init(&b);
-
- mp_read_variable_radix(&a, argv[1], 10);
- mp_read_variable_radix(&b, argv[2], 10);
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
-
- mp_init(&c);
- printf("\nc = a * b\n");
-
- mp_mul(&a, &b, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- printf("\nc = b * 32523\n");
-
- mp_mul_d(&b, 32523, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- mp_init(&d);
- printf("\nc = a / b, d = a mod b\n");
-
- mp_div(&a, &b, &c, &d);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- printf("d = "); mp_print(&d, stdout); fputc('\n', stdout);
-
- ix = rand() % 256;
- printf("\nc = a / %d, r = a mod %d\n", ix, ix);
- mp_div_d(&a, (mp_digit)ix, &c, &r);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- printf("r = %04X\n", r);
-
-#if EXPT
- printf("\nc = a ** b\n");
- mp_expt(&a, &b, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-#endif
-
- ix = rand() % 256;
- printf("\nc = 2^%d\n", ix);
- mp_2expt(&c, ix);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
-#if SQRT
- printf("\nc = sqrt(a)\n");
- if((res = mp_sqrt(&a, &c)) != MP_OKAY) {
- printf("mp_sqrt: %s\n", mp_strerror(res));
- } else {
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- mp_sqr(&c, &c);
- printf("c^2 = "); mp_print(&c, stdout); fputc('\n', stdout);
- }
-#endif
-
- mp_clear(&d);
- mp_clear(&c);
- mp_clear(&b);
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-3a.c b/security/nss/lib/freebl/mpi/tests/mptest-3a.c
deleted file mode 100644
index 0bdaaf9fe..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-3a.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 3a: Multiplication vs. squaring timing test
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include <time.h>
-
-#include "mpi.h"
-#include "mpprime.h"
-
-int main(int argc, char *argv[])
-{
- int ix, num, prec = 8;
- double d1, d2;
- clock_t start, finish;
- time_t seed;
- mp_int a, c, d;
-
- seed = time(NULL);
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <num-tests> [<precision>]\n", argv[0]);
- return 1;
- }
-
- if((num = atoi(argv[1])) < 0)
- num = -num;
-
- if(!num) {
- fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]);
- return 1;
- }
-
- if(argc > 2) {
- if((prec = atoi(argv[2])) <= 0)
- prec = 8;
- else
- prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT;
- }
-
- printf("Test 3a: Multiplication vs squaring timing test\n"
- "Precision: %d digits (%u bits)\n"
- "# of tests: %d\n\n", prec, prec * DIGIT_BIT, num);
-
- mp_init_size(&a, prec);
-
- mp_init(&c); mp_init(&d);
-
- printf("Verifying accuracy ... \n");
- srand((unsigned int)seed);
- for(ix = 0; ix < num; ix++) {
- mpp_random_size(&a, prec);
- mp_mul(&a, &a, &c);
- mp_sqr(&a, &d);
-
- if(mp_cmp(&c, &d) != 0) {
- printf("Error! Results not accurate:\n");
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- printf("d = "); mp_print(&d, stdout); fputc('\n', stdout);
- mp_sub(&c, &d, &d);
- printf("dif "); mp_print(&d, stdout); fputc('\n', stdout);
- mp_clear(&c); mp_clear(&d);
- mp_clear(&a);
- return 1;
- }
- }
- printf("Accuracy is confirmed for the %d test samples\n", num);
- mp_clear(&d);
-
- printf("Testing squaring ... \n");
- srand((unsigned int)seed);
- start = clock();
- for(ix = 0; ix < num; ix++) {
- mpp_random_size(&a, prec);
- mp_sqr(&a, &c);
- }
- finish = clock();
-
- d2 = (double)(finish - start) / CLOCKS_PER_SEC;
-
- printf("Testing multiplication ... \n");
- srand((unsigned int)seed);
- start = clock();
- for(ix = 0; ix < num; ix++) {
- mpp_random(&a);
- mp_mul(&a, &a, &c);
- }
- finish = clock();
-
- d1 = (double)(finish - start) / CLOCKS_PER_SEC;
-
- printf("Multiplication time: %.3f sec (%.3f each)\n", d1, d1 / num);
- printf("Squaring time: %.3f sec (%.3f each)\n", d2, d2 / num);
- printf("Improvement: %.2f%%\n", (1.0 - (d2 / d1)) * 100.0);
-
- mp_clear(&c);
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-4.c b/security/nss/lib/freebl/mpi/tests/mptest-4.c
deleted file mode 100644
index 45a67283d..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-4.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 4: Modular arithmetic tests
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include "mpi.h"
-
-int main(int argc, char *argv[])
-{
- int ix;
- mp_int a, b, c, m;
- mp_digit r;
-
- if(argc < 4) {
- fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]);
- return 1;
- }
-
- printf("Test 4: Modular arithmetic\n\n");
-
- mp_init(&a);
- mp_init(&b);
- mp_init(&m);
-
- mp_read_radix(&a, argv[1], 10);
- mp_read_radix(&b, argv[2], 10);
- mp_read_radix(&m, argv[3], 10);
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
- printf("m = "); mp_print(&m, stdout); fputc('\n', stdout);
-
- mp_init(&c);
- printf("\nc = a (mod m)\n");
-
- mp_mod(&a, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- printf("\nc = b (mod m)\n");
-
- mp_mod(&b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- printf("\nc = b (mod 1853)\n");
-
- mp_mod_d(&b, 1853, &r);
- printf("c = %04X\n", r);
-
- printf("\nc = (a + b) mod m\n");
-
- mp_addmod(&a, &b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- printf("\nc = (a - b) mod m\n");
-
- mp_submod(&a, &b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- printf("\nc = (a * b) mod m\n");
-
- mp_mulmod(&a, &b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- printf("\nc = (a ** b) mod m\n");
-
- mp_exptmod(&a, &b, &m, &c);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- printf("\nIn-place modular squaring test:\n");
- for(ix = 0; ix < 5; ix++) {
- printf("a = (a * a) mod m a = ");
- mp_sqrmod(&a, &m, &a);
- mp_print(&a, stdout);
- fputc('\n', stdout);
- }
-
-
- mp_clear(&c);
- mp_clear(&m);
- mp_clear(&b);
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-4a.c b/security/nss/lib/freebl/mpi/tests/mptest-4a.c
deleted file mode 100644
index f6edd942a..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-4a.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * mptest4a - modular exponentiation speed test
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <time.h>
-
-#include <sys/time.h>
-
-#include "mpi.h"
-#include "mpprime.h"
-
-typedef struct {
- unsigned int sec;
- unsigned int usec;
-} instant_t;
-
-instant_t now(void)
-{
- struct timeval clk;
- instant_t res;
-
- res.sec = res.usec = 0;
-
- if(gettimeofday(&clk, NULL) != 0)
- return res;
-
- res.sec = clk.tv_sec;
- res.usec = clk.tv_usec;
-
- return res;
-}
-
-extern mp_err s_mp_pad();
-
-int main(int argc, char *argv[])
-{
- int ix, num, prec = 8;
- unsigned int d;
- instant_t start, finish;
- time_t seed;
- mp_int a, m, c;
-
- seed = time(NULL);
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <num-tests> [<precision>]\n", argv[0]);
- return 1;
- }
-
- if((num = atoi(argv[1])) < 0)
- num = -num;
-
- if(!num) {
- fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]);
- return 1;
- }
-
- if(argc > 2) {
- if((prec = atoi(argv[2])) <= 0)
- prec = 8;
- }
-
- printf("Test 3a: Modular exponentiation timing test\n"
- "Precision: %d digits (%d bits)\n"
- "# of tests: %d\n\n", prec, prec * DIGIT_BIT, num);
-
- mp_init_size(&a, prec);
- mp_init_size(&m, prec);
- mp_init_size(&c, prec);
- s_mp_pad(&a, prec);
- s_mp_pad(&m, prec);
- s_mp_pad(&c, prec);
-
- printf("Testing modular exponentiation ... \n");
- srand((unsigned int)seed);
-
- start = now();
- for(ix = 0; ix < num; ix++) {
- mpp_random(&a);
- mpp_random(&c);
- mpp_random(&m);
- mp_exptmod(&a, &c, &m, &c);
- }
- finish = now();
-
- d = (finish.sec - start.sec) * 1000000;
- d -= start.usec; d += finish.usec;
-
- printf("Total time elapsed: %u usec\n", d);
- printf("Time per exponentiation: %u usec (%.3f sec)\n",
- (d / num), (double)(d / num) / 1000000);
-
- mp_clear(&c);
- mp_clear(&a);
- mp_clear(&m);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-4b.c b/security/nss/lib/freebl/mpi/tests/mptest-4b.c
deleted file mode 100644
index e0273c7a6..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-4b.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * mptest-4b.c
- *
- * Test speed of a large modular exponentiation of a primitive element
- * modulo a prime.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <time.h>
-
-#include <sys/time.h>
-
-#include "mpi.h"
-#include "mpprime.h"
-
-char *g_prime =
- "34BD53C07350E817CCD49721020F1754527959C421C1533244769D4CF060A8B1C3DA"
- "25094BE723FB1E2369B55FEEBBE0FAC16425161BF82684062B5EC5D7D47D1B23C117"
- "0FA19745E44A55E148314E582EB813AC9EE5126295E2E380CACC2F6D206B293E5ED9"
- "23B54EE961A8C69CD625CE4EC38B70C649D7F014432AEF3A1C93";
-char *g_gen = "5";
-
-typedef struct {
- unsigned int sec;
- unsigned int usec;
-} instant_t;
-
-instant_t now(void)
-{
- struct timeval clk;
- instant_t res;
-
- res.sec = res.usec = 0;
-
- if(gettimeofday(&clk, NULL) != 0)
- return res;
-
- res.sec = clk.tv_sec;
- res.usec = clk.tv_usec;
-
- return res;
-}
-
-extern mp_err s_mp_pad();
-
-int main(int argc, char *argv[])
-{
- instant_t start, finish;
- mp_int prime, gen, expt, res;
- unsigned int ix, diff;
- int num;
-
- srand(time(NULL));
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]);
- return 1;
- }
-
- if((num = atoi(argv[1])) < 0)
- num = -num;
-
- if(num == 0)
- ++num;
-
- mp_init(&prime); mp_init(&gen); mp_init(&res);
- mp_read_radix(&prime, g_prime, 16);
- mp_read_radix(&gen, g_gen, 16);
-
- mp_init_size(&expt, USED(&prime) - 1);
- s_mp_pad(&expt, USED(&prime) - 1);
-
- printf("Testing %d modular exponentations ... \n", num);
-
- start = now();
- for(ix = 0; ix < num; ix++) {
- mpp_random(&expt);
- mp_exptmod(&gen, &expt, &prime, &res);
- }
- finish = now();
-
- diff = (finish.sec - start.sec) * 1000000;
- diff += finish.usec; diff -= start.usec;
-
- printf("%d operations took %u usec (%.3f sec)\n",
- num, diff, (double)diff / 1000000.0);
- printf("That is %.3f sec per operation.\n",
- ((double)diff / 1000000.0) / num);
-
- mp_clear(&expt);
- mp_clear(&res);
- mp_clear(&gen);
- mp_clear(&prime);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-5.c b/security/nss/lib/freebl/mpi/tests/mptest-5.c
deleted file mode 100644
index ffb7407f1..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-5.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 5: Other number theoretic functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include "mpi.h"
-
-int main(int argc, char *argv[])
-{
- mp_int a, b, c, x, y;
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]);
- return 1;
- }
-
- printf("Test 5: Number theoretic functions\n\n");
-
- mp_init(&a);
- mp_init(&b);
-
- mp_read_radix(&a, argv[1], 10);
- mp_read_radix(&b, argv[2], 10);
-
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
-
- mp_init(&c);
- printf("\nc = (a, b)\n");
-
- mp_gcd(&a, &b, &c);
- printf("Euclid: c = "); mp_print(&c, stdout); fputc('\n', stdout);
-/*
- mp_bgcd(&a, &b, &c);
- printf("Binary: c = "); mp_print(&c, stdout); fputc('\n', stdout);
-*/
- mp_init(&x);
- mp_init(&y);
- printf("\nc = (a, b) = ax + by\n");
-
- mp_xgcd(&a, &b, &c, &x, &y);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- printf("x = "); mp_print(&x, stdout); fputc('\n', stdout);
- printf("y = "); mp_print(&y, stdout); fputc('\n', stdout);
-
- printf("\nc = a^-1 (mod b)\n");
- if(mp_invmod(&a, &b, &c) == MP_UNDEF) {
- printf("a has no inverse mod b\n");
- } else {
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- }
-
- mp_clear(&y);
- mp_clear(&x);
- mp_clear(&c);
- mp_clear(&b);
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-5a.c b/security/nss/lib/freebl/mpi/tests/mptest-5a.c
deleted file mode 100644
index 54379e552..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-5a.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 5a: Greatest common divisor speed test, binary vs. Euclid
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <time.h>
-
-#include <sys/time.h>
-
-#include "mpi.h"
-#include "mpprime.h"
-
-typedef struct {
- unsigned int sec;
- unsigned int usec;
-} instant_t;
-
-instant_t now(void)
-{
- struct timeval clk;
- instant_t res;
-
- res.sec = res.usec = 0;
-
- if(gettimeofday(&clk, NULL) != 0)
- return res;
-
- res.sec = clk.tv_sec;
- res.usec = clk.tv_usec;
-
- return res;
-}
-
-#define PRECISION 16
-
-int main(int argc, char *argv[])
-{
- int ix, num, prec = PRECISION;
- mp_int a, b, c, d;
- instant_t start, finish;
- time_t seed;
- unsigned int d1, d2;
-
- seed = time(NULL);
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]);
- return 1;
- }
-
- if((num = atoi(argv[1])) < 0)
- num = -num;
-
- printf("Test 5a: Euclid vs. Binary, a GCD speed test\n\n"
- "Number of tests: %d\n"
- "Precision: %d digits\n\n", num, prec);
-
- mp_init_size(&a, prec);
- mp_init_size(&b, prec);
- mp_init(&c);
- mp_init(&d);
-
- printf("Verifying accuracy ... \n");
- srand((unsigned int)seed);
- for(ix = 0; ix < num; ix++) {
- mpp_random_size(&a, prec);
- mpp_random_size(&b, prec);
-
- mp_gcd(&a, &b, &c);
- mp_bgcd(&a, &b, &d);
-
- if(mp_cmp(&c, &d) != 0) {
- printf("Error! Results not accurate:\n");
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- printf("d = "); mp_print(&d, stdout); fputc('\n', stdout);
-
- mp_clear(&a); mp_clear(&b); mp_clear(&c); mp_clear(&d);
- return 1;
- }
- }
- mp_clear(&d);
- printf("Accuracy confirmed for the %d test samples\n", num);
-
- printf("Testing Euclid ... \n");
- srand((unsigned int)seed);
- start = now();
- for(ix = 0; ix < num; ix++) {
- mpp_random_size(&a, prec);
- mpp_random_size(&b, prec);
- mp_gcd(&a, &b, &c);
-
- }
- finish = now();
-
- d1 = (finish.sec - start.sec) * 1000000;
- d1 -= start.usec; d1 += finish.usec;
-
- printf("Testing binary ... \n");
- srand((unsigned int)seed);
- start = now();
- for(ix = 0; ix < num; ix++) {
- mpp_random_size(&a, prec);
- mpp_random_size(&b, prec);
- mp_bgcd(&a, &b, &c);
- }
- finish = now();
-
- d2 = (finish.sec - start.sec) * 1000000;
- d2 -= start.usec; d2 += finish.usec;
-
- printf("Euclidean algorithm time: %u usec\n", d1);
- printf("Binary algorithm time: %u usec\n", d2);
- printf("Improvement: %.2f%%\n",
- (1.0 - ((double)d2 / (double)d1)) * 100.0);
-
- mp_clear(&c);
- mp_clear(&b);
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-6.c b/security/nss/lib/freebl/mpi/tests/mptest-6.c
deleted file mode 100644
index 1014b91ab..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-6.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 6: Output functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include "mpi.h"
-
-void print_buf(FILE *ofp, char *buf, int len)
-{
- int ix, brk = 0;
-
- for(ix = 0; ix < len; ix++) {
- fprintf(ofp, "%02X ", buf[ix]);
-
- brk = (brk + 1) & 0xF;
- if(!brk)
- fputc('\n', ofp);
- }
-
- if(brk)
- fputc('\n', ofp);
-
-}
-
-int main(int argc, char *argv[])
-{
- int ix, size;
- mp_int a;
- char *buf;
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <a>\n", argv[0]);
- return 1;
- }
-
- printf("Test 6: Output functions\n\n");
-
- mp_init(&a);
-
- mp_read_radix(&a, argv[1], 10);
-
- printf("\nConverting to a string:\n");
-
- printf("Rx Size Representation\n");
- for(ix = 2; ix <= MAX_RADIX; ix++) {
- size = mp_radix_size(&a, ix);
-
- buf = calloc(size, sizeof(char));
- mp_toradix(&a, buf, ix);
- printf("%2d: %3d: %s\n", ix, size, buf);
- free(buf);
-
- }
-
- printf("\nRaw output:\n");
- size = mp_raw_size(&a);
- buf = calloc(size, sizeof(char));
-
- printf("Size: %d bytes\n", size);
-
- mp_toraw(&a, buf);
- print_buf(stdout, buf, size);
- free(buf);
-
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-7.c b/security/nss/lib/freebl/mpi/tests/mptest-7.c
deleted file mode 100644
index 21994c957..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-7.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 7: Random and divisibility tests
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <time.h>
-
-#define MP_IOFUNC 1
-#include "mpi.h"
-
-#include "mpprime.h"
-
-int main(int argc, char *argv[])
-{
- mp_digit num;
- mp_int a, b;
-
- srand(time(NULL));
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]);
- return 1;
- }
-
- printf("Test 7: Random & divisibility tests\n\n");
-
- mp_init(&a);
- mp_init(&b);
-
- mp_read_radix(&a, argv[1], 10);
- mp_read_radix(&b, argv[2], 10);
-
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
-
- if(mpp_divis(&a, &b) == MP_YES)
- printf("a is divisible by b\n");
- else
- printf("a is not divisible by b\n");
-
- if(mpp_divis(&b, &a) == MP_YES)
- printf("b is divisible by a\n");
- else
- printf("b is not divisible by a\n");
-
- printf("\nb = mpp_random()\n");
- mpp_random(&b);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
- mpp_random(&b);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
- mpp_random(&b);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
-
- printf("\nTesting a for divisibility by first 170 primes\n");
- num = 170;
- if(mpp_divis_primes(&a, &num) == MP_YES)
- printf("It is divisible by at least one of them\n");
- else
- printf("It is not divisible by any of them\n");
-
- mp_clear(&b);
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-8.c b/security/nss/lib/freebl/mpi/tests/mptest-8.c
deleted file mode 100644
index dfbedb32c..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-8.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test 8: Probabilistic primality tester
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <time.h>
-
-#define MP_IOFUNC 1
-#include "mpi.h"
-
-#include "mpprime.h"
-
-int main(int argc, char *argv[])
-{
- int ix;
- mp_digit num;
- mp_int a;
-
- srand(time(NULL));
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <a>\n", argv[0]);
- return 1;
- }
-
- printf("Test 8: Probabilistic primality testing\n\n");
-
- mp_init(&a);
-
- mp_read_radix(&a, argv[1], 10);
-
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
-
- printf("\nChecking for divisibility by small primes ... \n");
- num = 170;
- if(mpp_divis_primes(&a, &num) == MP_YES) {
- printf("it is not prime\n");
- goto CLEANUP;
- }
- printf("Passed that test (not divisible by any small primes).\n");
-
- for(ix = 0; ix < 10; ix++) {
- printf("\nPerforming Rabin-Miller test, iteration %d\n", ix + 1);
-
- if(mpp_pprime(&a, 5) == MP_NO) {
- printf("it is not prime\n");
- goto CLEANUP;
- }
- }
- printf("All tests passed; a is probably prime\n");
-
-CLEANUP:
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-9.c b/security/nss/lib/freebl/mpi/tests/mptest-9.c
deleted file mode 100644
index f63d00dbd..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-9.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * mptest-9.c
- *
- * Test logical functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <time.h>
-
-#include "mpi.h"
-#include "mplogic.h"
-
-int main(int argc, char *argv[])
-{
- mp_int a, b, c;
- int pco;
- mp_err res;
-
- printf("Test 9: Logical functions\n\n");
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <b>\n", argv[0]);
- return 1;
- }
-
- mp_init(&a); mp_init(&b); mp_init(&c);
- mp_read_radix(&a, argv[1], 16);
- mp_read_radix(&b, argv[2], 16);
-
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
-
- mpl_not(&a, &c);
- printf("~a = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- mpl_and(&a, &b, &c);
- printf("a & b = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- mpl_or(&a, &b, &c);
- printf("a | b = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- mpl_xor(&a, &b, &c);
- printf("a ^ b = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- mpl_rsh(&a, &c, 1);
- printf("a >> 1 = "); mp_print(&c, stdout); fputc('\n', stdout);
- mpl_rsh(&a, &c, 5);
- printf("a >> 5 = "); mp_print(&c, stdout); fputc('\n', stdout);
- mpl_rsh(&a, &c, 16);
- printf("a >> 16 = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- mpl_lsh(&a, &c, 1);
- printf("a << 1 = "); mp_print(&c, stdout); fputc('\n', stdout);
- mpl_lsh(&a, &c, 5);
- printf("a << 5 = "); mp_print(&c, stdout); fputc('\n', stdout);
- mpl_lsh(&a, &c, 16);
- printf("a << 16 = "); mp_print(&c, stdout); fputc('\n', stdout);
-
- mpl_num_set(&a, &pco);
- printf("population(a) = %d\n", pco);
- mpl_num_set(&b, &pco);
- printf("population(b) = %d\n", pco);
-
- res = mpl_parity(&a);
- if(res == MP_EVEN)
- printf("a has even parity\n");
- else
- printf("a has odd parity\n");
-
- mp_clear(&c);
- mp_clear(&b);
- mp_clear(&a);
-
- return 0;
-}
-
diff --git a/security/nss/lib/freebl/mpi/tests/mptest-b.c b/security/nss/lib/freebl/mpi/tests/mptest-b.c
deleted file mode 100644
index 51ffc202c..000000000
--- a/security/nss/lib/freebl/mpi/tests/mptest-b.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Simple test driver for MPI library
- *
- * Test GF2m: Binary Polynomial Arithmetic
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-
-#include "mp_gf2m.h"
-
-int main(int argc, char *argv[])
-{
- int ix;
- mp_int pp, a, b, x, y, order;
- mp_int c, d, e;
- mp_digit r;
- mp_err res;
- unsigned int p[] = {163,7,6,3,0};
- unsigned int ptemp[10];
-
- printf("Test b: Binary Polynomial Arithmetic\n\n");
-
- mp_init(&pp);
- mp_init(&a);
- mp_init(&b);
- mp_init(&x);
- mp_init(&y);
- mp_init(&order);
-
- mp_read_radix(&pp, "0800000000000000000000000000000000000000C9", 16);
- mp_read_radix(&a, "1", 16);
- mp_read_radix(&b, "020A601907B8C953CA1481EB10512F78744A3205FD", 16);
- mp_read_radix(&x, "03F0EBA16286A2D57EA0991168D4994637E8343E36", 16);
- mp_read_radix(&y, "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", 16);
- mp_read_radix(&order, "040000000000000000000292FE77E70C12A4234C33", 16);
- printf("pp = "); mp_print(&pp, stdout); fputc('\n', stdout);
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
- printf("x = "); mp_print(&x, stdout); fputc('\n', stdout);
- printf("y = "); mp_print(&y, stdout); fputc('\n', stdout);
- printf("order = "); mp_print(&order, stdout); fputc('\n', stdout);
-
- mp_init(&c);
- mp_init(&d);
- mp_init(&e);
-
- /* Test polynomial conversion */
- ix = mp_bpoly2arr(&pp, ptemp, 10);
- if (
- (ix != 5) ||
- (ptemp[0] != p[0]) ||
- (ptemp[1] != p[1]) ||
- (ptemp[2] != p[2]) ||
- (ptemp[3] != p[3]) ||
- (ptemp[4] != p[4])
- ) {
- printf("Polynomial to array conversion not correct\n");
- return -1;
- }
-
- printf("Polynomial conversion test #1 successful.\n");
- MP_CHECKOK( mp_barr2poly(p, &c) );
- if (mp_cmp(&pp, &c) != 0) {
- printf("Array to polynomial conversion not correct\n");
- return -1;
- }
- printf("Polynomial conversion test #2 successful.\n");
-
- /* Test addition */
- MP_CHECKOK( mp_badd(&a, &a, &c) );
- if (mp_cmp_z(&c) != 0) {
- printf("a+a should equal zero\n");
- return -1;
- }
- printf("Addition test #1 successful.\n");
- MP_CHECKOK( mp_badd(&a, &b, &c) );
- MP_CHECKOK( mp_badd(&b, &c, &c) );
- if (mp_cmp(&c, &a) != 0) {
- printf("c = (a + b) + b should equal a\n");
- printf("a = "); mp_print(&a, stdout); fputc('\n', stdout);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- return -1;
- }
- printf("Addition test #2 successful.\n");
-
- /* Test multiplication */
- mp_set(&c, 2);
- MP_CHECKOK( mp_bmul(&b, &c, &c) );
- MP_CHECKOK( mp_badd(&b, &c, &c) );
- mp_set(&d, 3);
- MP_CHECKOK( mp_bmul(&b, &d, &d) );
- if (mp_cmp(&c, &d) != 0) {
- printf("c = (2 * b) + b should equal c = 3 * b\n");
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- printf("d = "); mp_print(&d, stdout); fputc('\n', stdout);
- return -1;
- }
- printf("Multiplication test #1 successful.\n");
-
- /* Test modular reduction */
- MP_CHECKOK( mp_bmod(&b, p, &c) );
- if (mp_cmp(&b, &c) != 0) {
- printf("c = b mod p should equal b\n");
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- return -1;
- }
- printf("Modular reduction test #1 successful.\n");
- MP_CHECKOK( mp_badd(&b, &pp, &c) );
- MP_CHECKOK( mp_bmod(&c, p, &c) );
- if (mp_cmp(&b, &c) != 0) {
- printf("c = (b + p) mod p should equal b\n");
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- return -1;
- }
- printf("Modular reduction test #2 successful.\n");
- MP_CHECKOK( mp_bmul(&b, &pp, &c) );
- MP_CHECKOK( mp_bmod(&c, p, &c) );
- if (mp_cmp_z(&c) != 0) {
- printf("c = (b * p) mod p should equal 0\n");
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- return -1;
- }
- printf("Modular reduction test #3 successful.\n");
-
- /* Test modular multiplication */
- MP_CHECKOK( mp_bmulmod(&b, &pp, p, &c) );
- if (mp_cmp_z(&c) != 0) {
- printf("c = (b * p) mod p should equal 0\n");
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- return -1;
- }
- printf("Modular multiplication test #1 successful.\n");
- mp_set(&c, 1);
- MP_CHECKOK( mp_badd(&pp, &c, &c) );
- MP_CHECKOK( mp_bmulmod(&b, &c, p, &c) );
- if (mp_cmp(&b, &c) != 0) {
- printf("c = (b * (p + 1)) mod p should equal b\n");
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- return -1;
- }
- printf("Modular multiplication test #2 successful.\n");
-
- /* Test modular squaring */
- MP_CHECKOK( mp_copy(&b, &c) );
- MP_CHECKOK( mp_bmulmod(&b, &c, p, &c) );
- MP_CHECKOK( mp_bsqrmod(&b, p, &d) );
- if (mp_cmp(&c, &d) != 0) {
- printf("c = (b * b) mod p should equal d = b^2 mod p\n");
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- printf("d = "); mp_print(&d, stdout); fputc('\n', stdout);
- return -1;
- }
- printf("Modular squaring test #1 successful.\n");
-
- /* Test modular division */
- MP_CHECKOK( mp_bdivmod(&b, &x, &pp, p, &c) );
- MP_CHECKOK( mp_bmulmod(&c, &x, p, &c) );
- if (mp_cmp(&b, &c) != 0) {
- printf("c = (b / x) * x mod p should equal b\n");
- printf("b = "); mp_print(&b, stdout); fputc('\n', stdout);
- printf("c = "); mp_print(&c, stdout); fputc('\n', stdout);
- return -1;
- }
- printf("Modular division test #1 successful.\n");
-
-CLEANUP:
-
- mp_clear(&order);
- mp_clear(&y);
- mp_clear(&x);
- mp_clear(&b);
- mp_clear(&a);
- mp_clear(&pp);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/tests/pi1k.txt b/security/nss/lib/freebl/mpi/tests/pi1k.txt
deleted file mode 100644
index 5ff6209ff..000000000
--- a/security/nss/lib/freebl/mpi/tests/pi1k.txt
+++ /dev/null
@@ -1 +0,0 @@
-31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989
diff --git a/security/nss/lib/freebl/mpi/tests/pi2k.txt b/security/nss/lib/freebl/mpi/tests/pi2k.txt
deleted file mode 100644
index 9ce82acd1..000000000
--- a/security/nss/lib/freebl/mpi/tests/pi2k.txt
+++ /dev/null
@@ -1 +0,0 @@
-314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759010
diff --git a/security/nss/lib/freebl/mpi/tests/pi5k.txt b/security/nss/lib/freebl/mpi/tests/pi5k.txt
deleted file mode 100644
index 901fac2ea..000000000
--- a/security/nss/lib/freebl/mpi/tests/pi5k.txt
+++ /dev/null
@@ -1 +0,0 @@
-314159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745530506820349625245174939965143142980919065925093722169646151570985838741059788595977297549893016175392846813826868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388439045124413654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767889525213852254995466672782398645659611635488623057745649803559363456817432411251507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858900971490967598526136554978189312978482168299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610213596953623144295248493718711014576540359027993440374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927819119793995206141966342875444064374512371819217999839101591956181467514269123974894090718649423196156794520809514655022523160388193014209376213785595663893778708303906979207734672218256259966150142150306803844773454920260541466592520149744285073251866600213243408819071048633173464965145390579626856100550810665879699816357473638405257145910289706414011097120628043903975951567715770042033786993600723055876317635942187312514712053292819182618612586732157919841484882916447060957527069572209175671167229109816909152801735067127485832228718352093539657251210835791513698820914442100675103346711031412671113699086585163983150197016515116851714376576183515565088490998985998238734552833163550764791853589322618548963213293308985706420467525907091548141654985946163718027098199430992448895757128289059232332609729971208443357326548938239119325974636673058360414281388303203824903758985243744170291327656180937734440307074692112019130203303801976211011004492932151608424448596376698389522868478312355265821314495768572624334418930396864262434107732269780280731891544110104468232527162010526522721116603966655730925471105578537634668206531098965269186205647693125705863566201855810072936065987648611791045334885034611365768675324944166803962657978771855608455296541266540853061434443185867697514566140680070023787765913440171274947042056223053899456131407112700040785473326993908145466464588079727082668306343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923099079654737612551765675135751782966645477917450112996148903046399471329621073404375189573596145890193897131117904297828564750320319869151402870808599048010941214722131794764777262241425485454033215718530614228813758504306332175182979866223717215916077166925474873898665494945011465406284336639379003976926567214638530673609657120918076383271664162748888007869256029022847210403172118608204190004229661711963779213375751149595015660496318629472654736425230817703675159067350235072835405670403867435136222247715891504953098444893330963408780769325993978054193414473774418426312986080998886874132604721
diff --git a/security/nss/lib/freebl/mpi/timetest b/security/nss/lib/freebl/mpi/timetest
deleted file mode 100755
index a74815ffd..000000000
--- a/security/nss/lib/freebl/mpi/timetest
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/bin/sh
-
-# Simple timing test for the MPI library. Basically, we use prime
-# generation as a timing test, since it exercises most of the pathways
-# of the library fairly heavily. The 'primegen' tool outputs a line
-# summarizing timing results. We gather these and process them for
-# statistical information, which is collected into a file.
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# $Id$
-#
-
-# Avoid using built-in shell echoes
-ECHO=/bin/echo
-MAKE=gmake
-PERL=perl
-
-# Use a fixed seed so timings will be more consistent
-# This one is the 11th-18th decimal digits of 'e'
-#export SEED=45904523
-SEED=45904523; export SEED
-
-#------------------------------------------------------------------------
-
-$ECHO "\n** Running timing tests for MPI library\n"
-
-$ECHO "Bringing 'metime' up to date ... "
-if $MAKE metime ; then
- :
-else
- $ECHO "\nMake failed to build metime.\n"
- exit 1
-fi
-
-if [ ! -x ./metime ] ; then
- $ECHO "\nCannot find 'metime' program, testing cannot continue.\n"
- exit 1
-fi
-
-#------------------------------------------------------------------------
-
-$ECHO "Bringing 'primegen' up to date ... "
-if $MAKE primegen ; then
- :
-else
- $ECHO "\nMake failed to build primegen.\n"
- exit 1
-fi
-
-if [ ! -x ./primegen ] ; then
- $ECHO "\nCannot find 'primegen' program, testing cannot continue.\n"
- exit 1
-fi
-
-#------------------------------------------------------------------------
-
-rm -f timing-results.txt
-touch timing-results.txt
-
-sizes="256 512 1024 2048"
-ntests=10
-
-trap 'echo "oop!";rm -f tt*.tmp timing-results.txt;exit 0' INT HUP
-
-$ECHO "\n-- Modular exponentiation\n"
-$ECHO "Modular exponentiation:" >> timing-results.txt
-
-$ECHO "Running $ntests modular exponentiations per test:"
-for size in $sizes ; do
- $ECHO "- Gathering statistics for $size bits ... "
- secs=`./metime $ntests $size | tail -1 | awk '{print $2}'`
- $ECHO "$size: " $secs " seconds per op" >> timing-results.txt
- tail -1 timing-results.txt
-done
-
-$ECHO "<done>";
-
-sizes="256 512 1024"
-ntests=1
-
-$ECHO "\n-- Prime generation\n"
-$ECHO "Prime generation:" >> timing-results.txt
-
-$ECHO "Generating $ntests prime values per test:"
-for size in $sizes ; do
- $ECHO "- Gathering statistics for $size bits ... "
- ./primegen $size $ntests | grep ticks | awk '{print $7}' | tr -d '(' > tt$$.tmp
- $ECHO "$size:" >> timing-results.txt
- $PERL stats tt$$.tmp >> timing-results.txt
- tail -1 timing-results.txt
- rm -f tt$$.tmp
-done
-
-$ECHO "<done>"
-
-trap 'rm -f tt*.tmp timing-results.txt' INT HUP
-
-exit 0
-
diff --git a/security/nss/lib/freebl/mpi/types.pl b/security/nss/lib/freebl/mpi/types.pl
deleted file mode 100755
index 1d3e0d874..000000000
--- a/security/nss/lib/freebl/mpi/types.pl
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/perl
-
-#
-# types.pl - find recommended type definitions for digits and words
-#
-# This script scans the Makefile for the C compiler and compilation
-# flags currently in use, and using this combination, attempts to
-# compile a simple test program that outputs the sizes of the various
-# unsigned integer types, in bytes. Armed with these, it finds all
-# the "viable" type combinations for mp_digit and mp_word, where
-# viability is defined by the requirement that mp_word be at least two
-# times the precision of mp_digit.
-#
-# Of these, the one with the largest digit size is chosen, and
-# appropriate typedef statements are written to standard output.
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-#
-
-@_=split(/\//,$0);chomp($prog=pop(@_));
-
-# The array of integer types to be considered...
-@TYPES = (
- "unsigned char",
- "unsigned short",
- "unsigned int",
- "unsigned long"
-);
-
-# Macro names for the maximum unsigned value of each type
-%TMAX = (
- "unsigned char" => "UCHAR_MAX",
- "unsigned short" => "USHRT_MAX",
- "unsigned int" => "UINT_MAX",
- "unsigned long" => "ULONG_MAX"
-);
-
-# Read the Makefile to find out which C compiler to use
-open(MFP, "<Makefile") or die "$prog: Makefile: $!\n";
-while(<MFP>) {
- chomp;
- if(/^CC=(.*)$/) {
- $cc = $1;
- last if $cflags;
- } elsif(/^CFLAGS=(.*)$/) {
- $cflags = $1;
- last if $cc;
- }
-}
-close(MFP);
-
-# If we couldn't find that, use 'cc' by default
-$cc = "cc" unless $cc;
-
-printf STDERR "Using '%s' as the C compiler.\n", $cc;
-
-print STDERR "Determining type sizes ... \n";
-open(OFP, ">tc$$.c") or die "$prog: tc$$.c: $!\n";
-print OFP "#include <stdio.h>\n\nint main(void)\n{\n";
-foreach $type (@TYPES) {
- printf OFP "\tprintf(\"%%d\\n\", (int)sizeof(%s));\n", $type;
-}
-print OFP "\n\treturn 0;\n}\n";
-close(OFP);
-
-system("$cc $cflags -o tc$$ tc$$.c");
-
-die "$prog: unable to build test program\n" unless(-x "tc$$");
-
-open(IFP, "./tc$$|") or die "$prog: can't execute test program\n";
-$ix = 0;
-while(<IFP>) {
- chomp;
- $size{$TYPES[$ix++]} = $_;
-}
-close(IFP);
-
-unlink("tc$$");
-unlink("tc$$.c");
-
-print STDERR "Selecting viable combinations ... \n";
-while(($type, $size) = each(%size)) {
- push(@ts, [ $size, $type ]);
-}
-
-# Sort them ascending by size
-@ts = sort { $a->[0] <=> $b->[0] } @ts;
-
-# Try all possible combinations, finding pairs in which the word size
-# is twice the digit size. The number of possible pairs is too small
-# to bother doing this more efficiently than by brute force
-for($ix = 0; $ix <= $#ts; $ix++) {
- $w = $ts[$ix];
-
- for($jx = 0; $jx <= $#ts; $jx++) {
- $d = $ts[$jx];
-
- if($w->[0] == 2 * $d->[0]) {
- push(@valid, [ $d, $w ]);
- }
- }
-}
-
-# Sort descending by digit size
-@valid = sort { $b->[0]->[0] <=> $a->[0]->[0] } @valid;
-
-# Select the maximum as the recommended combination
-$rec = shift(@valid);
-
-printf("typedef %-18s mp_sign;\n", "char");
-printf("typedef %-18s mp_digit; /* %d byte type */\n",
- $rec->[0]->[1], $rec->[0]->[0]);
-printf("typedef %-18s mp_word; /* %d byte type */\n",
- $rec->[1]->[1], $rec->[1]->[0]);
-printf("typedef %-18s mp_size;\n", "unsigned int");
-printf("typedef %-18s mp_err;\n\n", "int");
-
-printf("#define %-18s (CHAR_BIT*sizeof(mp_digit))\n", "DIGIT_BIT");
-printf("#define %-18s %s\n", "DIGIT_MAX", $TMAX{$rec->[0]->[1]});
-printf("#define %-18s (CHAR_BIT*sizeof(mp_word))\n", "MP_WORD_BIT");
-printf("#define %-18s %s\n\n", "MP_WORD_MAX", $TMAX{$rec->[1]->[1]});
-printf("#define %-18s (DIGIT_MAX+1)\n\n", "RADIX");
-
-printf("#define %-18s \"%%0%dX\"\n", "DIGIT_FMT", (2 * $rec->[0]->[0]));
-
-exit 0;
diff --git a/security/nss/lib/freebl/mpi/utils/LICENSE b/security/nss/lib/freebl/mpi/utils/LICENSE
deleted file mode 100644
index 5f96df7ab..000000000
--- a/security/nss/lib/freebl/mpi/utils/LICENSE
+++ /dev/null
@@ -1,4 +0,0 @@
-Within this directory, each of the file listed below is licensed under
-the terms given in the file LICENSE-MPL, also in this directory.
-
-PRIMES
diff --git a/security/nss/lib/freebl/mpi/utils/LICENSE-MPL b/security/nss/lib/freebl/mpi/utils/LICENSE-MPL
deleted file mode 100644
index d1f78f522..000000000
--- a/security/nss/lib/freebl/mpi/utils/LICENSE-MPL
+++ /dev/null
@@ -1,35 +0,0 @@
-***** BEGIN LICENSE BLOCK *****
-Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
-The contents of this file are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-The Original Code is the Netscape security libraries.
-
-The Initial Developer of the Original Code is Netscape
-Communications Corporation. Portions created by Netscape are
-Copyright (C) 1994-2000 Netscape Communications Corporation. All
-Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of this file only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of this file under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of this file under
-the terms of any one of the MPL, the GPL or the LGPL.
-
-***** END LICENSE BLOCK *****
diff --git a/security/nss/lib/freebl/mpi/utils/PRIMES b/security/nss/lib/freebl/mpi/utils/PRIMES
deleted file mode 100644
index ed65703ff..000000000
--- a/security/nss/lib/freebl/mpi/utils/PRIMES
+++ /dev/null
@@ -1,41 +0,0 @@
-Probable primes (sorted by number of significant bits)
-
- 128: 81386202757205669562183851789305348631
-
- 128: 180241813863264101444573802809858694397
-
- 128: 245274683055224433281596312431122059021
-
- 128: 187522309397665259809392608791686659539
-
- 256: 83252422946206411852330647237287722547866360773229941071371588246436\
- 513990159
-
- 256: 79132571131322331023736933767063051273085304521895229780914612117520\
- 058517909
-
- 256: 72081815425552909748220041100909735706208853818662000557743644603407\
- 965465527
-
- 256: 87504602391905701494845474079163412737334477797316409702279059573654\
- 274811271
-
- 512: 12233064210800062190450937494718705259777386009095453001870729392786\
- 63450255179083524798507997690270500580265258111668148238355016411719\
- 9168737693316468563
-
- 512: 12003639081420725322369909586347545220275253633035565716386136197501\
- 88208318984400479275215620499883521216480724155582768193682335576385\
- 2069481074929084063
-
-1024: 16467877625718912296741904171202513097057724053648819680815842057593\
- 20371835940722471475475803725455063836431454757000451907612224427007\
- 63984592414360595161051906727075047683803534852982766542661204179549\
- 77327573530800542562611753617736693359790119074768292178493884576587\
- 0230450429880021317876149636714743053
-
-1024: 16602953991090311275234291158294516471009930684624948451178742895360\
- 86073703307475884280944414508444679430090561246728195735962931545473\
- 40743240318558456247740186704660778277799687988031119436541068736925\
- 20563780233711166724859277827382391527748470939542560819625727876091\
- 5372193745283891895989104479029844957
diff --git a/security/nss/lib/freebl/mpi/utils/README b/security/nss/lib/freebl/mpi/utils/README
deleted file mode 100644
index 90da5fee5..000000000
--- a/security/nss/lib/freebl/mpi/utils/README
+++ /dev/null
@@ -1,241 +0,0 @@
-***** BEGIN LICENSE BLOCK *****
-Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
-The contents of this file are subject to the Mozilla Public License Version
-1.1 (the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the
-License.
-
-The Original Code is the MPI Arbitrary Precision Integer Arithmetic
-library.
-
-The Initial Developer of the Original Code is
-Michael J. Fromberger <sting@linguist.dartmouth.edu>
-Portions created by the Initial Developer are Copyright (C) 1998, 2000
-the Initial Developer. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms of
-either the GNU General Public License Version 2 or later (the "GPL"), or
-the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-in which case the provisions of the GPL or the LGPL are applicable instead
-of those above. If you wish to allow use of your version of this file only
-under the terms of either the GPL or the LGPL, and not to allow others to
-use your version of this file under the terms of the MPL, indicate your
-decision by deleting the provisions above and replace them with the notice
-and other provisions required by the GPL or the LGPL. If you do not delete
-the provisions above, a recipient may use your version of this file under
-the terms of any one of the MPL, the GPL or the LGPL.
-
-***** END LICENSE BLOCK *****
-
-Additional MPI utilities
-------------------------
-
-The files 'mpprime.h' and 'mpprime.c' define some useful extensions to
-the MPI library for dealing with prime numbers (in particular, testing
-for divisbility, and the Rabin-Miller probabilistic primality test).
-
-The files 'mplogic.h' and 'mplogic.c' define extensions to the MPI
-library for doing bitwise logical operations and shifting.
-
-This document assumes you have read the help file for the MPI library
-and understand its conventions.
-
-Divisibility (mpprime.h)
-------------
-
-To test a number for divisibility by another number:
-
-mpp_divis(a, b) - test if b|a
-mpp_divis_d(a, d) - test if d|a
-
-Each of these functions returns MP_YES if its initial argument is
-divisible by its second, or MP_NO if it is not. Other errors may be
-returned as appropriate (such as MP_RANGE if you try to test for
-divisibility by zero).
-
-Randomness (mpprime.h)
-----------
-
-To generate random data:
-
-mpp_random(a) - fill a with random data
-mpp_random_size(a, p) - fill a with p digits of random data
-
-The mpp_random_size() function increases the precision of a to at
-least p, then fills all those digits randomly. The mp_random()
-function fills a to its current precision (as determined by the number
-of significant digits, USED(a))
-
-Note that these functions simply use the C library's rand() function
-to fill a with random digits up to its precision. This should be
-adequate for primality testing, but should not be used for
-cryptographic applications where truly random values are required for
-security.
-
-You should call srand() in your driver program in order to seed the
-random generator; this function doesn't call it.
-
-Primality Testing (mpprime.h)
------------------
-
-mpp_divis_vector(a, v, s, w) - is a divisible by any of the s values
- in v, and if so, w = which.
-mpp_divis_primes(a, np) - is a divisible by any of the first np primes?
-mpp_fermat(a, w) - is a pseudoprime with respect to witness w?
-mpp_pprime(a, nt) - run nt iterations of Rabin-Miller on a.
-
-The mpp_divis_vector() function tests a for divisibility by each
-member of an array of digits. The array is v, the size of that array
-is s. Returns MP_YES if a is divisible, and stores the index of the
-offending digit in w. Returns MP_NO if a is not divisible by any of
-the digits in the array.
-
-A small table of primes is compiled into the library (typically the
-first 128 primes, although you can change this by editing the file
-'primes.c' before you build). The global variable prime_tab_size
-contains the number of primes in the table, and the values themselves
-are in the array prime_tab[], which is an array of mp_digit.
-
-The mpp_divis_primes() function is basically just a wrapper around
-mpp_divis_vector() that uses prime_tab[] as the test vector. The np
-parameter is a pointer to an mp_digit -- on input, it should specify
-the number of primes to be tested against. If a is divisible by any
-of the primes, MP_YES is returned and np is given the prime value that
-divided a (you can use this if you're factoring, for example).
-Otherwise, MP_NO is returned and np is untouched.
-
-The function mpp_fermat() performs Fermat's test, using w as a
-witness. This test basically relies on the fact that if a is prime,
-and w is relatively prime to a, then:
-
- w^a = w (mod a)
-
-That is,
-
- w^(a - 1) = 1 (mod a)
-
-The function returns MP_YES if the test passes, MP_NO if it fails. If
-w is relatively prime to a, and the test fails, a is definitely
-composite. If w is relatively prime to a and the test passes, then a
-is either prime, or w is a false witness (the probability of this
-happening depends on the choice of w and of a ... consult a number
-theory textbook for more information about this).
-
-Note: If (w, a) != 1, the output of this test is meaningless.
-----
-
-The function mpp_pprime() performs the Rabin-Miller probabilistic
-primality test for nt rounds. If all the tests pass, MP_YES is
-returned, and a is probably prime. The probability that an answer of
-MP_YES is incorrect is no greater than 1 in 4^nt, and in fact is
-usually much less than that (this is a pessimistic estimate). If any
-test fails, MP_NO is returned, and a is definitely composite.
-
-Bruce Schneier recommends at least 5 iterations of this test for most
-cryptographic applications; Knuth suggests that 25 are reasonable.
-Run it as many times as you feel are necessary.
-
-See the programs 'makeprime.c' and 'isprime.c' for reasonable examples
-of how to use these functions for primality testing.
-
-
-Bitwise Logic (mplogic.c)
--------------
-
-The four commonest logical operations are implemented as:
-
-mpl_not(a, b) - Compute bitwise (one's) complement, b = ~a
-
-mpl_and(a, b, c) - Compute bitwise AND, c = a & b
-
-mpl_or(a, b, c) - Compute bitwise OR, c = a | b
-
-mpl_xor(a, b, c) - Compute bitwise XOR, c = a ^ b
-
-Left and right shifts are available as well. These take a number to
-shift, a destination, and a shift amount. The shift amount must be a
-digit value between 0 and DIGIT_BIT inclusive; if it is not, MP_RANGE
-will be returned and the shift will not happen.
-
-mpl_rsh(a, b, d) - Compute logical right shift, b = a >> d
-
-mpl_lsh(a, b, d) - Compute logical left shift, b = a << d
-
-Since these are logical shifts, they fill with zeroes (the library
-uses a signed magnitude representation, so there are no sign bits to
-extend anyway).
-
-
-Command-line Utilities
-----------------------
-
-A handful of interesting command-line utilities are provided. These
-are:
-
-lap.c - Find the order of a mod m. Usage is 'lap <a> <m>'.
- This uses a dumb algorithm, so don't use it for
- a really big modulus.
-
-invmod.c - Find the inverse of a mod m, if it exists. Usage
- is 'invmod <a> <m>'
-
-sieve.c - A simple bitmap-based implementation of the Sieve
- of Eratosthenes. Used to generate the table of
- primes in primes.c. Usage is 'sieve <nbits>'
-
-prng.c - Uses the routines in bbs_rand.{h,c} to generate
- one or more 32-bit pseudo-random integers. This
- is mainly an example, not intended for use in a
- cryptographic application (the system time is
- the only source of entropy used)
-
-dec2hex.c - Convert decimal to hexadecimal
-
-hex2dec.c - Convert hexadecimal to decimal
-
-basecvt.c - General radix conversion tool (supports 2-64)
-
-isprime.c - Probabilistically test an integer for primality
- using the Rabin-Miller pseudoprime test combined
- with division by small primes.
-
-primegen.c - Generate primes at random.
-
-exptmod.c - Perform modular exponentiation
-
-ptab.pl - A Perl script to munge the output of the sieve
- program into a compilable C structure.
-
-
-Other Files
------------
-
-PRIMES - Some randomly generated numbers which are prime with
- extremely high probability.
-
-README - You're reading me already.
-
-
-About the Author
-----------------
-
-This software was written by Michael J. Fromberger. You can contact
-the author as follows:
-
-E-mail: <sting@linguist.dartmouth.edu>
-
-Postal: 8000 Cummings Hall, Thayer School of Engineering
- Dartmouth College, Hanover, New Hampshire, USA
-
-PGP key: http://linguist.dartmouth.edu/~sting/keys/mjf.html
- 9736 188B 5AFA 23D6 D6AA BE0D 5856 4525 289D 9907
-
-Last updated: $Id$
diff --git a/security/nss/lib/freebl/mpi/utils/basecvt.c b/security/nss/lib/freebl/mpi/utils/basecvt.c
deleted file mode 100644
index 7ffd1cad6..000000000
--- a/security/nss/lib/freebl/mpi/utils/basecvt.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * basecvt.c
- *
- * Convert integer values specified on the command line from one input
- * base to another. Accepts input and output bases between 2 and 36
- * inclusive.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mpi.h"
-
-#define IBASE 10
-#define OBASE 16
-#define USAGE "Usage: %s ibase obase [value]\n"
-#define MAXBASE 64
-#define MINBASE 2
-
-int main(int argc, char *argv[])
-{
- int ix, ibase = IBASE, obase = OBASE;
- mp_int val;
-
- ix = 1;
- if(ix < argc) {
- ibase = atoi(argv[ix++]);
-
- if(ibase < MINBASE || ibase > MAXBASE) {
- fprintf(stderr, "%s: input radix must be between %d and %d inclusive\n",
- argv[0], MINBASE, MAXBASE);
- return 1;
- }
- }
- if(ix < argc) {
- obase = atoi(argv[ix++]);
-
- if(obase < MINBASE || obase > MAXBASE) {
- fprintf(stderr, "%s: output radix must be between %d and %d inclusive\n",
- argv[0], MINBASE, MAXBASE);
- return 1;
- }
- }
-
- mp_init(&val);
- while(ix < argc) {
- char *out;
- int outlen;
-
- mp_read_radix(&val, argv[ix++], ibase);
-
- outlen = mp_radix_size(&val, obase);
- out = calloc(outlen, sizeof(char));
- mp_toradix(&val, out, obase);
-
- printf("%s\n", out);
- free(out);
- }
-
- mp_clear(&val);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/bbs_rand.c b/security/nss/lib/freebl/mpi/utils/bbs_rand.c
deleted file mode 100644
index cb0ca3c3c..000000000
--- a/security/nss/lib/freebl/mpi/utils/bbs_rand.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Blum, Blum & Shub PRNG using the MPI library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "bbs_rand.h"
-
-#define SEED 1
-#define MODULUS 2
-
-/* This modulus is the product of two randomly generated 512-bit
- prime integers, each of which is congruent to 3 (mod 4). */
-static char *bbs_modulus =
-"75A2A6E1D27393B86562B9CE7279A8403CB4258A637DAB5233465373E37837383EDC"
-"332282B8575927BC4172CE8C147B4894050EE9D2BDEED355C121037270CA2570D127"
-"7D2390CD1002263326635CC6B259148DE3A1A03201980A925E395E646A5E9164B0EC"
-"28559EBA58C87447245ADD0651EDA507056A1129E3A3E16E903D64B437";
-
-static int bbs_init = 0; /* flag set when library is initialized */
-static mp_int bbs_state; /* the current state of the generator */
-
-/* Suggested size of random seed data */
-int bbs_seed_size = (sizeof(bbs_modulus) / 2);
-
-void bbs_srand(unsigned char *data, int len)
-{
- if((bbs_init & SEED) == 0) {
- mp_init(&bbs_state);
- bbs_init |= SEED;
- }
-
- mp_read_raw(&bbs_state, (char *)data, len);
-
-} /* end bbs_srand() */
-
-unsigned int bbs_rand(void)
-{
- static mp_int modulus;
- unsigned int result = 0, ix;
-
- if((bbs_init & MODULUS) == 0) {
- mp_init(&modulus);
- mp_read_radix(&modulus, bbs_modulus, 16);
- bbs_init |= MODULUS;
- }
-
- for(ix = 0; ix < sizeof(unsigned int); ix++) {
- mp_digit d;
-
- mp_sqrmod(&bbs_state, &modulus, &bbs_state);
- d = DIGIT(&bbs_state, 0);
-
- result = (result << CHAR_BIT) | (d & UCHAR_MAX);
- }
-
- return result;
-
-} /* end bbs_rand() */
-
-/*------------------------------------------------------------------------*/
-/* HERE THERE BE DRAGONS */
diff --git a/security/nss/lib/freebl/mpi/utils/bbs_rand.h b/security/nss/lib/freebl/mpi/utils/bbs_rand.h
deleted file mode 100644
index cb48bf5e4..000000000
--- a/security/nss/lib/freebl/mpi/utils/bbs_rand.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * bbs_rand.h
- *
- * Blum, Blum & Shub PRNG using the MPI library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _H_BBSRAND_
-#define _H_BBSRAND_
-
-#include <limits.h>
-#include "mpi.h"
-
-#define BBS_RAND_MAX UINT_MAX
-
-/* Suggested length of seed data */
-extern int bbs_seed_size;
-
-void bbs_srand(unsigned char *data, int len);
-unsigned int bbs_rand(void);
-
-#endif /* end _H_BBSRAND_ */
diff --git a/security/nss/lib/freebl/mpi/utils/bbsrand.c b/security/nss/lib/freebl/mpi/utils/bbsrand.c
deleted file mode 100644
index 832bd860c..000000000
--- a/security/nss/lib/freebl/mpi/utils/bbsrand.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * bbsrand.c
- *
- * Test driver for routines in bbs_rand.h
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <limits.h>
-
-#include "bbs_rand.h"
-
-#define NUM_TESTS 100
-
-int main(void)
-{
- unsigned int seed, result, ix;
-
- seed = time(NULL);
- bbs_srand((unsigned char *)&seed, sizeof(seed));
-
- for(ix = 0; ix < NUM_TESTS; ix++) {
- result = bbs_rand();
-
- printf("Test %3u: %08X\n", ix + 1, result);
- }
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/dec2hex.c b/security/nss/lib/freebl/mpi/utils/dec2hex.c
deleted file mode 100644
index ae9c1ab88..000000000
--- a/security/nss/lib/freebl/mpi/utils/dec2hex.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * dec2hex.c
- *
- * Convert decimal integers into hexadecimal
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mpi.h"
-
-int main(int argc, char *argv[])
-{
- mp_int a;
- char *buf;
- int len;
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <a>\n", argv[0]);
- return 1;
- }
-
- mp_init(&a); mp_read_radix(&a, argv[1], 10);
- len = mp_radix_size(&a, 16);
- buf = malloc(len);
- mp_toradix(&a, buf, 16);
-
- printf("%s\n", buf);
-
- free(buf);
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/exptmod.c b/security/nss/lib/freebl/mpi/utils/exptmod.c
deleted file mode 100644
index 78419431c..000000000
--- a/security/nss/lib/freebl/mpi/utils/exptmod.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * exptmod.c
- *
- * Command line tool to perform modular exponentiation on arbitrary
- * precision integers.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mpi.h"
-
-int main(int argc, char *argv[])
-{
- mp_int a, b, m;
- mp_err res;
- char *str;
- int len, rval = 0;
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]);
- return 1;
- }
-
- mp_init(&a); mp_init(&b); mp_init(&m);
- mp_read_radix(&a, argv[1], 10);
- mp_read_radix(&b, argv[2], 10);
- mp_read_radix(&m, argv[3], 10);
-
- if((res = mp_exptmod(&a, &b, &m, &a)) != MP_OKAY) {
- fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res));
- rval = 1;
- } else {
- len = mp_radix_size(&a, 10);
- str = calloc(len, sizeof(char));
- mp_toradix(&a, str, 10);
-
- printf("%s\n", str);
-
- free(str);
- }
-
- mp_clear(&a); mp_clear(&b); mp_clear(&m);
-
- return rval;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/fact.c b/security/nss/lib/freebl/mpi/utils/fact.c
deleted file mode 100644
index a965ad283..000000000
--- a/security/nss/lib/freebl/mpi/utils/fact.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * fact.c
- *
- * Compute factorial of input integer
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mpi.h"
-
-mp_err mp_fact(mp_int *a, mp_int *b);
-
-int main(int argc, char *argv[])
-{
- mp_int a;
- mp_err res;
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <number>\n", argv[0]);
- return 1;
- }
-
- mp_init(&a);
- mp_read_radix(&a, argv[1], 10);
-
- if((res = mp_fact(&a, &a)) != MP_OKAY) {
- fprintf(stderr, "%s: error: %s\n", argv[0],
- mp_strerror(res));
- mp_clear(&a);
- return 1;
- }
-
- {
- char *buf;
- int len;
-
- len = mp_radix_size(&a, 10);
- buf = malloc(len);
- mp_todecimal(&a, buf);
-
- puts(buf);
-
- free(buf);
- }
-
- mp_clear(&a);
- return 0;
-}
-
-mp_err mp_fact(mp_int *a, mp_int *b)
-{
- mp_int ix, s;
- mp_err res = MP_OKAY;
-
- if(mp_cmp_z(a) < 0)
- return MP_UNDEF;
-
- mp_init(&s);
- mp_add_d(&s, 1, &s); /* s = 1 */
- mp_init(&ix);
- mp_add_d(&ix, 1, &ix); /* ix = 1 */
-
- for(/* */; mp_cmp(&ix, a) <= 0; mp_add_d(&ix, 1, &ix)) {
- if((res = mp_mul(&s, &ix, &s)) != MP_OKAY)
- break;
- }
-
- mp_clear(&ix);
-
- /* Copy out results if we got them */
- if(res == MP_OKAY)
- mp_copy(&s, b);
-
- mp_clear(&s);
-
- return res;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/gcd.c b/security/nss/lib/freebl/mpi/utils/gcd.c
deleted file mode 100644
index bbfa9f0ab..000000000
--- a/security/nss/lib/freebl/mpi/utils/gcd.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * gcd.c
- *
- * Greatest common divisor
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mpi.h"
-
-char *g_prog = NULL;
-
-void print_mp_int(mp_int *mp, FILE *ofp);
-
-int main(int argc, char *argv[])
-{
- mp_int a, b, x, y;
- mp_err res;
- int ext = 0;
-
- g_prog = argv[0];
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <b>\n", g_prog);
- return 1;
- }
-
- mp_init(&a); mp_read_radix(&a, argv[1], 10);
- mp_init(&b); mp_read_radix(&b, argv[2], 10);
-
- /* If we were called 'xgcd', compute x, y so that g = ax + by */
- if(strcmp(g_prog, "xgcd") == 0) {
- ext = 1;
- mp_init(&x); mp_init(&y);
- }
-
- if(ext) {
- if((res = mp_xgcd(&a, &b, &a, &x, &y)) != MP_OKAY) {
- fprintf(stderr, "%s: error: %s\n", g_prog, mp_strerror(res));
- mp_clear(&a); mp_clear(&b);
- mp_clear(&x); mp_clear(&y);
- return 1;
- }
- } else {
- if((res = mp_gcd(&a, &b, &a)) != MP_OKAY) {
- fprintf(stderr, "%s: error: %s\n", g_prog,
- mp_strerror(res));
- mp_clear(&a); mp_clear(&b);
- return 1;
- }
- }
-
- print_mp_int(&a, stdout);
- if(ext) {
- fputs("x = ", stdout); print_mp_int(&x, stdout);
- fputs("y = ", stdout); print_mp_int(&y, stdout);
- }
-
- mp_clear(&a); mp_clear(&b);
-
- if(ext) {
- mp_clear(&x);
- mp_clear(&y);
- }
-
- return 0;
-
-}
-
-void print_mp_int(mp_int *mp, FILE *ofp)
-{
- char *buf;
- int len;
-
- len = mp_radix_size(mp, 10);
- buf = calloc(len, sizeof(char));
- mp_todecimal(mp, buf);
- fprintf(ofp, "%s\n", buf);
- free(buf);
-
-}
diff --git a/security/nss/lib/freebl/mpi/utils/hex2dec.c b/security/nss/lib/freebl/mpi/utils/hex2dec.c
deleted file mode 100644
index 390e0d2ef..000000000
--- a/security/nss/lib/freebl/mpi/utils/hex2dec.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * hex2dec.c
- *
- * Convert decimal integers into hexadecimal
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mpi.h"
-
-int main(int argc, char *argv[])
-{
- mp_int a;
- char *buf;
- int len;
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <a>\n", argv[0]);
- return 1;
- }
-
- mp_init(&a); mp_read_radix(&a, argv[1], 16);
- len = mp_radix_size(&a, 10);
- buf = malloc(len);
- mp_toradix(&a, buf, 10);
-
- printf("%s\n", buf);
-
- free(buf);
- mp_clear(&a);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/identest.c b/security/nss/lib/freebl/mpi/utils/identest.c
deleted file mode 100644
index 8172d7708..000000000
--- a/security/nss/lib/freebl/mpi/utils/identest.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "mpi.h"
-#include "mpprime.h"
-#include <sys/types.h>
-#include <time.h>
-
-#define MAX_PREC (4096 / MP_DIGIT_BIT)
-
-mp_err identity_test(void)
-{
- mp_size preca, precb;
- mp_err res;
- mp_int a, b;
- mp_int t1, t2, t3, t4, t5;
-
- preca = (rand() % MAX_PREC) + 1;
- precb = (rand() % MAX_PREC) + 1;
-
- MP_DIGITS(&a) = 0;
- MP_DIGITS(&b) = 0;
- MP_DIGITS(&t1) = 0;
- MP_DIGITS(&t2) = 0;
- MP_DIGITS(&t3) = 0;
- MP_DIGITS(&t4) = 0;
- MP_DIGITS(&t5) = 0;
-
- MP_CHECKOK( mp_init(&a) );
- MP_CHECKOK( mp_init(&b) );
- MP_CHECKOK( mp_init(&t1) );
- MP_CHECKOK( mp_init(&t2) );
- MP_CHECKOK( mp_init(&t3) );
- MP_CHECKOK( mp_init(&t4) );
- MP_CHECKOK( mp_init(&t5) );
-
- MP_CHECKOK( mpp_random_size(&a, preca) );
- MP_CHECKOK( mpp_random_size(&b, precb) );
-
- if (mp_cmp(&a, &b) < 0)
- mp_exch(&a, &b);
-
- MP_CHECKOK( mp_mod(&a, &b, &t1) ); /* t1 = a%b */
- MP_CHECKOK( mp_div(&a, &b, &t2, NULL) ); /* t2 = a/b */
- MP_CHECKOK( mp_mul(&b, &t2, &t3) ); /* t3 = (a/b)*b */
- MP_CHECKOK( mp_add(&t1, &t3, &t4) ); /* t4 = a%b + (a/b)*b */
- MP_CHECKOK( mp_sub(&t4, &a, &t5) ); /* t5 = a%b + (a/b)*b - a */
- if (mp_cmp_z(&t5) != 0) {
- res = MP_UNDEF;
- goto CLEANUP;
- }
-
-CLEANUP:
- mp_clear(&t5);
- mp_clear(&t4);
- mp_clear(&t3);
- mp_clear(&t2);
- mp_clear(&t1);
- mp_clear(&b);
- mp_clear(&a);
- return res;
-}
-
-int
-main(void)
-{
- unsigned int seed = (unsigned int)time(NULL);
- unsigned long count = 0;
- mp_err res;
-
- srand(seed);
-
- while (MP_OKAY == (res = identity_test())) {
- if ((++count % 100) == 0)
- fputc('.', stderr);
- }
-
- fprintf(stderr, "\ntest failed, err %d\n", res);
- return res;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/invmod.c b/security/nss/lib/freebl/mpi/utils/invmod.c
deleted file mode 100644
index e8d6f12be..000000000
--- a/security/nss/lib/freebl/mpi/utils/invmod.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * invmod.c
- *
- * Compute modular inverses
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "mpi.h"
-
-int main(int argc, char *argv[])
-{
- mp_int a, m;
- mp_err res;
- char *buf;
- int len, out = 0;
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]);
- return 1;
- }
-
- mp_init(&a); mp_init(&m);
- mp_read_radix(&a, argv[1], 10);
- mp_read_radix(&m, argv[2], 10);
-
- if(mp_cmp(&a, &m) > 0)
- mp_mod(&a, &m, &a);
-
- switch((res = mp_invmod(&a, &m, &a))) {
- case MP_OKAY:
- len = mp_radix_size(&a, 10);
- buf = malloc(len);
-
- mp_toradix(&a, buf, 10);
- printf("%s\n", buf);
- free(buf);
- break;
-
- case MP_UNDEF:
- printf("No inverse\n");
- out = 1;
- break;
-
- default:
- printf("error: %s (%d)\n", mp_strerror(res), res);
- out = 2;
- break;
- }
-
- mp_clear(&a);
- mp_clear(&m);
-
- return out;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/isprime.c b/security/nss/lib/freebl/mpi/utils/isprime.c
deleted file mode 100644
index 2534fd191..000000000
--- a/security/nss/lib/freebl/mpi/utils/isprime.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * isprime.c
- *
- * Probabilistic primality tester command-line tool
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "mpi.h"
-#include "mpprime.h"
-
-#define RM_TESTS 15 /* how many iterations of Rabin-Miller? */
-#define MINIMUM 1024 /* don't bother us with a < this */
-
-int g_tests = RM_TESTS;
-char *g_prog = NULL;
-
-int main(int argc, char *argv[])
-{
- mp_int a;
- mp_digit np = prime_tab_size; /* from mpprime.h */
- int res = 0;
-
- g_prog = argv[0];
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <a>, where <a> is a decimal integer\n"
- "Use '0x' prefix for a hexadecimal value\n", g_prog);
- return 1;
- }
-
- /* Read number of tests from environment, if present */
- {
- char *tmp;
-
- if((tmp = getenv("RM_TESTS")) != NULL) {
- if((g_tests = atoi(tmp)) <= 0)
- g_tests = RM_TESTS;
- }
- }
-
- mp_init(&a);
- if(argv[1][0] == '0' && argv[1][1] == 'x')
- mp_read_radix(&a, argv[1] + 2, 16);
- else
- mp_read_radix(&a, argv[1], 10);
-
- if(mp_cmp_d(&a, MINIMUM) <= 0) {
- fprintf(stderr, "%s: please use a value greater than %d\n",
- g_prog, MINIMUM);
- mp_clear(&a);
- return 1;
- }
-
- /* Test for divisibility by small primes */
- if(mpp_divis_primes(&a, &np) != MP_NO) {
- printf("Not prime (divisible by small prime %d)\n", np);
- res = 2;
- goto CLEANUP;
- }
-
- /* Test with Fermat's test, using 2 as a witness */
- if(mpp_fermat(&a, 2) != MP_YES) {
- printf("Not prime (failed Fermat test)\n");
- res = 2;
- goto CLEANUP;
- }
-
- /* Test with Rabin-Miller probabilistic test */
- if(mpp_pprime(&a, g_tests) == MP_NO) {
- printf("Not prime (failed pseudoprime test)\n");
- res = 2;
- goto CLEANUP;
- }
-
- printf("Probably prime, 1 in 4^%d chance of false positive\n", g_tests);
-
-CLEANUP:
- mp_clear(&a);
-
- return res;
-
-}
diff --git a/security/nss/lib/freebl/mpi/utils/lap.c b/security/nss/lib/freebl/mpi/utils/lap.c
deleted file mode 100644
index 99694fad6..000000000
--- a/security/nss/lib/freebl/mpi/utils/lap.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * lap.c
- *
- * Find least annihilating power of a mod m
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-
-#include "mpi.h"
-
-void sig_catch(int ign);
-
-int g_quit = 0;
-
-int main(int argc, char *argv[])
-{
- mp_int a, m, p, k;
-
- if(argc < 3) {
- fprintf(stderr, "Usage: %s <a> <m>\n", argv[0]);
- return 1;
- }
-
- mp_init(&a);
- mp_init(&m);
- mp_init(&p);
- mp_add_d(&p, 1, &p);
-
- mp_read_radix(&a, argv[1], 10);
- mp_read_radix(&m, argv[2], 10);
-
- mp_init_copy(&k, &a);
-
- signal(SIGINT, sig_catch);
-#ifndef __OS2__
- signal(SIGHUP, sig_catch);
-#endif
- signal(SIGTERM, sig_catch);
-
- while(mp_cmp(&p, &m) < 0) {
- if(g_quit) {
- int len;
- char *buf;
-
- len = mp_radix_size(&p, 10);
- buf = malloc(len);
- mp_toradix(&p, buf, 10);
-
- fprintf(stderr, "Terminated at: %s\n", buf);
- free(buf);
- return 1;
- }
- if(mp_cmp_d(&k, 1) == 0) {
- int len;
- char *buf;
-
- len = mp_radix_size(&p, 10);
- buf = malloc(len);
- mp_toradix(&p, buf, 10);
-
- printf("%s\n", buf);
-
- free(buf);
- break;
- }
-
- mp_mulmod(&k, &a, &m, &k);
- mp_add_d(&p, 1, &p);
- }
-
- if(mp_cmp(&p, &m) >= 0)
- printf("No annihilating power.\n");
-
- mp_clear(&p);
- mp_clear(&m);
- mp_clear(&a);
- return 0;
-}
-
-void sig_catch(int ign)
-{
- g_quit = 1;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/makeprime.c b/security/nss/lib/freebl/mpi/utils/makeprime.c
deleted file mode 100644
index cd08feb7f..000000000
--- a/security/nss/lib/freebl/mpi/utils/makeprime.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * makeprime.c
- *
- * A simple prime generator function (and test driver). Prints out the
- * first prime it finds greater than or equal to the starting value.
- *
- * Usage: makeprime <start>
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-/* These two must be included for make_prime() to work */
-
-#include "mpi.h"
-#include "mpprime.h"
-
-/*
- make_prime(p, nr)
-
- Find the smallest prime integer greater than or equal to p, where
- primality is verified by 'nr' iterations of the Rabin-Miller
- probabilistic primality test. The caller is responsible for
- generating the initial value of p.
-
- Returns MP_OKAY if a prime has been generated, otherwise the error
- code indicates some other problem. The value of p is clobbered; the
- caller should keep a copy if the value is needed.
- */
-mp_err make_prime(mp_int *p, int nr);
-
-/* The main() is not required -- it's just a test driver */
-int main(int argc, char *argv[])
-{
- mp_int start;
- mp_err res;
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <start-value>\n", argv[0]);
- return 1;
- }
-
- mp_init(&start);
- if(argv[1][0] == '0' && tolower(argv[1][1]) == 'x') {
- mp_read_radix(&start, argv[1] + 2, 16);
- } else {
- mp_read_radix(&start, argv[1], 10);
- }
- mp_abs(&start, &start);
-
- if((res = make_prime(&start, 5)) != MP_OKAY) {
- fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res));
- mp_clear(&start);
-
- return 1;
-
- } else {
- char *buf = malloc(mp_radix_size(&start, 10));
-
- mp_todecimal(&start, buf);
- printf("%s\n", buf);
- free(buf);
-
- mp_clear(&start);
-
- return 0;
- }
-
-} /* end main() */
-
-/*------------------------------------------------------------------------*/
-
-mp_err make_prime(mp_int *p, int nr)
-{
- mp_err res;
-
- if(mp_iseven(p)) {
- mp_add_d(p, 1, p);
- }
-
- do {
- mp_digit which = prime_tab_size;
-
- /* First test for divisibility by a few small primes */
- if((res = mpp_divis_primes(p, &which)) == MP_YES)
- continue;
- else if(res != MP_NO)
- goto CLEANUP;
-
- /* If that passes, try one iteration of Fermat's test */
- if((res = mpp_fermat(p, 2)) == MP_NO)
- continue;
- else if(res != MP_YES)
- goto CLEANUP;
-
- /* If that passes, run Rabin-Miller as often as requested */
- if((res = mpp_pprime(p, nr)) == MP_YES)
- break;
- else if(res != MP_NO)
- goto CLEANUP;
-
- } while((res = mp_add_d(p, 2, p)) == MP_OKAY);
-
- CLEANUP:
- return res;
-
-} /* end make_prime() */
-
-/*------------------------------------------------------------------------*/
-/* HERE THERE BE DRAGONS */
diff --git a/security/nss/lib/freebl/mpi/utils/metime.c b/security/nss/lib/freebl/mpi/utils/metime.c
deleted file mode 100644
index 89fb4022e..000000000
--- a/security/nss/lib/freebl/mpi/utils/metime.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * metime.c
- *
- * Modular exponentiation timing test
- *
- * $Id$
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <time.h>
-
-#include "mpi.h"
-#include "mpprime.h"
-
-double clk_to_sec(clock_t start, clock_t stop);
-
-int main(int argc, char *argv[])
-{
- int ix, num, prec = 8;
- unsigned int seed;
- clock_t start, stop;
- double sec;
-
- mp_int a, m, c;
-
- if(getenv("SEED") != NULL)
- seed = abs(atoi(getenv("SEED")));
- else
- seed = (unsigned int)time(NULL);
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <num-tests> [<nbits>]\n", argv[0]);
- return 1;
- }
-
- if((num = atoi(argv[1])) < 0)
- num = -num;
-
- if(!num) {
- fprintf(stderr, "%s: must perform at least 1 test\n", argv[0]);
- return 1;
- }
-
- if(argc > 2) {
- if((prec = atoi(argv[2])) <= 0)
- prec = 8;
- else
- prec = (prec + (DIGIT_BIT - 1)) / DIGIT_BIT;
-
- }
-
- printf("Modular exponentiation timing test\n"
- "Precision: %d digits (%d bits)\n"
- "# of tests: %d\n\n", prec, prec * DIGIT_BIT, num);
-
- mp_init_size(&a, prec);
- mp_init_size(&m, prec);
- mp_init_size(&c, prec);
-
- srand(seed);
-
- start = clock();
- for(ix = 0; ix < num; ix++) {
-
- mpp_random_size(&a, prec);
- mpp_random_size(&c, prec);
- mpp_random_size(&m, prec);
- /* set msb and lsb of m */
- DIGIT(&m,0) |= 1;
- DIGIT(&m, USED(&m)-1) |= (mp_digit)1 << (DIGIT_BIT - 1);
- if (mp_cmp(&a, &m) > 0)
- mp_sub(&a, &m, &a);
-
- mp_exptmod(&a, &c, &m, &c);
- }
- stop = clock();
-
- sec = clk_to_sec(start, stop);
-
- printf("Total: %.3f seconds\n", sec);
- printf("Individual: %.3f seconds\n", sec / num);
-
- mp_clear(&c);
- mp_clear(&a);
- mp_clear(&m);
-
- return 0;
-}
-
-double clk_to_sec(clock_t start, clock_t stop)
-{
- return (double)(stop - start) / CLOCKS_PER_SEC;
-}
-
-/*------------------------------------------------------------------------*/
-/* HERE THERE BE DRAGONS */
diff --git a/security/nss/lib/freebl/mpi/utils/pi.c b/security/nss/lib/freebl/mpi/utils/pi.c
deleted file mode 100644
index 53edc323d..000000000
--- a/security/nss/lib/freebl/mpi/utils/pi.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * pi.c
- *
- * Compute pi to an arbitrary number of digits. Uses Machin's formula,
- * like everyone else on the planet:
- *
- * pi = 16 * arctan(1/5) - 4 * arctan(1/239)
- *
- * This is pretty effective for up to a few thousand digits, but it
- * gets pretty slow after that.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <time.h>
-
-#include "mpi.h"
-
-mp_err arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum);
-
-int main(int argc, char *argv[])
-{
- mp_err res;
- mp_digit ndigits;
- mp_int sum1, sum2;
- clock_t start, stop;
- int out = 0;
-
- /* Make the user specify precision on the command line */
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <num-digits>\n", argv[0]);
- return 1;
- }
-
- if((ndigits = abs(atoi(argv[1]))) == 0) {
- fprintf(stderr, "%s: you must request at least 1 digit\n", argv[0]);
- return 1;
- }
-
- start = clock();
- mp_init(&sum1); mp_init(&sum2);
-
- /* sum1 = 16 * arctan(1/5) */
- if((res = arctan(16, 5, ndigits, &sum1)) != MP_OKAY) {
- fprintf(stderr, "%s: arctan: %s\n", argv[0], mp_strerror(res));
- out = 1; goto CLEANUP;
- }
-
- /* sum2 = 4 * arctan(1/239) */
- if((res = arctan(4, 239, ndigits, &sum2)) != MP_OKAY) {
- fprintf(stderr, "%s: arctan: %s\n", argv[0], mp_strerror(res));
- out = 1; goto CLEANUP;
- }
-
- /* pi = sum1 - sum2 */
- if((res = mp_sub(&sum1, &sum2, &sum1)) != MP_OKAY) {
- fprintf(stderr, "%s: mp_sub: %s\n", argv[0], mp_strerror(res));
- out = 1; goto CLEANUP;
- }
- stop = clock();
-
- /* Write the output in decimal */
- {
- char *buf = malloc(mp_radix_size(&sum1, 10));
-
- if(buf == NULL) {
- fprintf(stderr, "%s: out of memory\n", argv[0]);
- out = 1; goto CLEANUP;
- }
- mp_todecimal(&sum1, buf);
- printf("%s\n", buf);
- free(buf);
- }
-
- fprintf(stderr, "Computation took %.2f sec.\n",
- (double)(stop - start) / CLOCKS_PER_SEC);
-
- CLEANUP:
- mp_clear(&sum1);
- mp_clear(&sum2);
-
- return out;
-
-}
-
-/* Compute sum := mul * arctan(1/x), to 'prec' digits of precision */
-mp_err arctan(mp_digit mul, mp_digit x, mp_digit prec, mp_int *sum)
-{
- mp_int t, v;
- mp_digit q = 1, rd;
- mp_err res;
- int sign = 1;
-
- prec += 3; /* push inaccuracies off the end */
-
- mp_init(&t); mp_set(&t, 10);
- mp_init(&v);
- if((res = mp_expt_d(&t, prec, &t)) != MP_OKAY || /* get 10^prec */
- (res = mp_mul_d(&t, mul, &t)) != MP_OKAY || /* ... times mul */
- (res = mp_mul_d(&t, x, &t)) != MP_OKAY) /* ... times x */
- goto CLEANUP;
-
- /*
- The extra multiplication by x in the above takes care of what
- would otherwise have to be a special case for 1 / x^1 during the
- first loop iteration. A little sneaky, but effective.
-
- We compute arctan(1/x) by the formula:
-
- 1 1 1 1
- - - ----- + ----- - ----- + ...
- x 3 x^3 5 x^5 7 x^7
-
- We multiply through by 'mul' beforehand, which gives us a couple
- more iterations and more precision
- */
-
- x *= x; /* works as long as x < sqrt(RADIX), which it is here */
-
- mp_zero(sum);
-
- do {
- if((res = mp_div_d(&t, x, &t, &rd)) != MP_OKAY)
- goto CLEANUP;
-
- if(sign < 0 && rd != 0)
- mp_add_d(&t, 1, &t);
-
- if((res = mp_div_d(&t, q, &v, &rd)) != MP_OKAY)
- goto CLEANUP;
-
- if(sign < 0 && rd != 0)
- mp_add_d(&v, 1, &v);
-
- if(sign > 0)
- res = mp_add(sum, &v, sum);
- else
- res = mp_sub(sum, &v, sum);
-
- if(res != MP_OKAY)
- goto CLEANUP;
-
- sign *= -1;
- q += 2;
-
- } while(mp_cmp_z(&t) != 0);
-
- /* Chop off inaccurate low-order digits */
- mp_div_d(sum, 1000, sum, NULL);
-
- CLEANUP:
- mp_clear(&v);
- mp_clear(&t);
-
- return res;
-}
-
-/*------------------------------------------------------------------------*/
-/* HERE THERE BE DRAGONS */
diff --git a/security/nss/lib/freebl/mpi/utils/primegen.c b/security/nss/lib/freebl/mpi/utils/primegen.c
deleted file mode 100644
index 5c1213f98..000000000
--- a/security/nss/lib/freebl/mpi/utils/primegen.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * primegen.c
- *
- * Generates random integers which are prime with a high degree of
- * probability using the Miller-Rabin probabilistic primality testing
- * algorithm.
- *
- * Usage:
- * primegen <bits> [<num>]
- *
- * <bits> - number of significant bits each prime should have
- * <num> - number of primes to generate
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <time.h>
-
-#include "mpi.h"
-#include "mplogic.h"
-#include "mpprime.h"
-
-#define NUM_TESTS 5 /* Number of Rabin-Miller iterations to test with */
-
-#ifdef DEBUG
-#define FPUTC(x,y) fputc(x,y)
-#else
-#define FPUTC(x,y)
-#endif
-
-int main(int argc, char *argv[])
-{
- unsigned char *raw;
- char *out;
- unsigned long nTries;
- int rawlen, bits, outlen, ngen, ix, jx;
- int g_strong = 0;
- mp_int testval;
- mp_err res;
- clock_t start, end;
-
- /* We'll just use the C library's rand() for now, although this
- won't be good enough for cryptographic purposes */
- if((out = getenv("SEED")) == NULL) {
- srand((unsigned int)time(NULL));
- } else {
- srand((unsigned int)atoi(out));
- }
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <bits> [<count> [strong]]\n", argv[0]);
- return 1;
- }
-
- if((bits = abs(atoi(argv[1]))) < CHAR_BIT) {
- fprintf(stderr, "%s: please request at least %d bits.\n",
- argv[0], CHAR_BIT);
- return 1;
- }
-
- /* If optional third argument is given, use that as the number of
- primes to generate; otherwise generate one prime only.
- */
- if(argc < 3) {
- ngen = 1;
- } else {
- ngen = abs(atoi(argv[2]));
- }
-
- /* If fourth argument is given, and is the word "strong", we'll
- generate strong (Sophie Germain) primes.
- */
- if(argc > 3 && strcmp(argv[3], "strong") == 0)
- g_strong = 1;
-
- /* testval - candidate being tested; nTries - number tried so far */
- if ((res = mp_init(&testval)) != MP_OKAY) {
- fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res));
- return 1;
- }
-
- if(g_strong) {
- printf("Requested %d strong prime value(s) of %d bits.\n",
- ngen, bits);
- } else {
- printf("Requested %d prime value(s) of %d bits.\n", ngen, bits);
- }
-
- rawlen = (bits / CHAR_BIT) + ((bits % CHAR_BIT) ? 1 : 0) + 1;
-
- if((raw = calloc(rawlen, sizeof(unsigned char))) == NULL) {
- fprintf(stderr, "%s: out of memory, sorry.\n", argv[0]);
- return 1;
- }
-
- /* This loop is one for each prime we need to generate */
- for(jx = 0; jx < ngen; jx++) {
-
- raw[0] = 0; /* sign is positive */
-
- /* Pack the initializer with random bytes */
- for(ix = 1; ix < rawlen; ix++)
- raw[ix] = (rand() * rand()) & UCHAR_MAX;
-
- raw[1] |= 0x80; /* set high-order bit of test value */
- raw[rawlen - 1] |= 1; /* set low-order bit of test value */
-
- /* Make an mp_int out of the initializer */
- mp_read_raw(&testval, (char *)raw, rawlen);
-
- /* Initialize candidate counter */
- nTries = 0;
-
- start = clock(); /* time generation for this prime */
- do {
- res = mpp_make_prime(&testval, bits, g_strong, &nTries);
- if (res != MP_NO)
- break;
- /* This code works whether digits are 16 or 32 bits */
- res = mp_add_d(&testval, 32 * 1024, &testval);
- res = mp_add_d(&testval, 32 * 1024, &testval);
- FPUTC(',', stderr);
- } while (1);
- end = clock();
-
- if (res != MP_YES) {
- break;
- }
- FPUTC('\n', stderr);
- puts("The following value is probably prime:");
- outlen = mp_radix_size(&testval, 10);
- out = calloc(outlen, sizeof(unsigned char));
- mp_toradix(&testval, (char *)out, 10);
- printf("10: %s\n", out);
- mp_toradix(&testval, (char *)out, 16);
- printf("16: %s\n\n", out);
- free(out);
-
- printf("Number of candidates tried: %lu\n", nTries);
- printf("This computation took %ld clock ticks (%.2f seconds)\n",
- (end - start), ((double)(end - start) / CLOCKS_PER_SEC));
-
- FPUTC('\n', stderr);
- } /* end of loop to generate all requested primes */
-
- if(res != MP_OKAY)
- fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res));
-
- free(raw);
- mp_clear(&testval);
-
- return 0;
-}
diff --git a/security/nss/lib/freebl/mpi/utils/prng.c b/security/nss/lib/freebl/mpi/utils/prng.c
deleted file mode 100644
index b826d3ca3..000000000
--- a/security/nss/lib/freebl/mpi/utils/prng.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * prng.c
- *
- * Command-line pseudo-random number generator
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <time.h>
-
-#ifdef __OS2__
-#include <types.h>
-#include <process.h>
-#else
-#include <unistd.h>
-#endif
-
-#include "bbs_rand.h"
-
-int main(int argc, char *argv[])
-{
- unsigned char *seed;
- unsigned int ix, num = 1;
- pid_t pid;
-
- if(argc > 1) {
- num = atoi(argv[1]);
- if(num <= 0)
- num = 1;
- }
-
- pid = getpid();
- srand(time(NULL) * (unsigned int)pid);
-
- /* Not a perfect seed, but not bad */
- seed = malloc(bbs_seed_size);
- for(ix = 0; ix < bbs_seed_size; ix++) {
- seed[ix] = rand() % UCHAR_MAX;
- }
-
- bbs_srand(seed, bbs_seed_size);
- memset(seed, 0, bbs_seed_size);
- free(seed);
-
- while(num-- > 0) {
- ix = bbs_rand();
-
- printf("%u\n", ix);
- }
-
- return 0;
-
-}
diff --git a/security/nss/lib/freebl/mpi/utils/ptab.pl b/security/nss/lib/freebl/mpi/utils/ptab.pl
deleted file mode 100755
index d0fadfceb..000000000
--- a/security/nss/lib/freebl/mpi/utils/ptab.pl
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/perl
-
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $Id$
-#
-
-while(<>) {
- chomp;
- push(@primes, $_);
-}
-
-printf("mp_size prime_tab_size = %d;\n", ($#primes + 1));
-print "mp_digit prime_tab[] = {\n";
-
-print "\t";
-$last = pop(@primes);
-foreach $prime (sort {$a<=>$b} @primes) {
- printf("0x%04X, ", $prime);
- $brk = ($brk + 1) % 8;
- print "\n\t" if(!$brk);
-}
-printf("0x%04X", $last);
-print "\n" if($brk);
-print "};\n\n";
-
-exit 0;
diff --git a/security/nss/lib/freebl/mpi/utils/sieve.c b/security/nss/lib/freebl/mpi/utils/sieve.c
deleted file mode 100644
index 2729c24f2..000000000
--- a/security/nss/lib/freebl/mpi/utils/sieve.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * sieve.c
- *
- * Finds prime numbers using the Sieve of Eratosthenes
- *
- * This implementation uses a bitmap to represent all odd integers in a
- * given range. We iterate over this bitmap, crossing off the
- * multiples of each prime we find. At the end, all the remaining set
- * bits correspond to prime integers.
- *
- * Here, we make two passes -- once we have generated a sieve-ful of
- * primes, we copy them out, reset the sieve using the highest
- * generated prime from the first pass as a base. Then we cross out
- * all the multiples of all the primes we found the first time through,
- * and re-sieve. In this way, we get double use of the memory we
- * allocated for the sieve the first time though. Since we also
- * implicitly ignore multiples of 2, this amounts to 4 times the
- * values.
- *
- * This could (and probably will) be generalized to re-use the sieve a
- * few more times.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <limits.h>
-
-typedef unsigned char byte;
-
-typedef struct {
- int size;
- byte *bits;
- long base;
- int next;
- int nbits;
-} sieve;
-
-void sieve_init(sieve *sp, long base, int nbits);
-void sieve_grow(sieve *sp, int nbits);
-long sieve_next(sieve *sp);
-void sieve_reset(sieve *sp, long base);
-void sieve_cross(sieve *sp, long val);
-void sieve_clear(sieve *sp);
-
-#define S_ISSET(S, B) (((S)->bits[(B)/CHAR_BIT]>>((B)%CHAR_BIT))&1)
-#define S_SET(S, B) ((S)->bits[(B)/CHAR_BIT]|=(1<<((B)%CHAR_BIT)))
-#define S_CLR(S, B) ((S)->bits[(B)/CHAR_BIT]&=~(1<<((B)%CHAR_BIT)))
-#define S_VAL(S, B) ((S)->base+(2*(B)))
-#define S_BIT(S, V) (((V)-((S)->base))/2)
-
-int main(int argc, char *argv[])
-{
- sieve s;
- long pr, *p;
- int c, ix, cur = 0;
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s <width>\n", argv[0]);
- return 1;
- }
-
- c = atoi(argv[1]);
- if(c < 0) c = -c;
-
- fprintf(stderr, "%s: sieving to %d positions\n", argv[0], c);
-
- sieve_init(&s, 3, c);
-
- c = 0;
- while((pr = sieve_next(&s)) > 0) {
- ++c;
- }
-
- p = calloc(c, sizeof(long));
- if(!p) {
- fprintf(stderr, "%s: out of memory after first half\n", argv[0]);
- sieve_clear(&s);
- exit(1);
- }
-
- fprintf(stderr, "%s: half done ... \n", argv[0]);
-
- for(ix = 0; ix < s.nbits; ix++) {
- if(S_ISSET(&s, ix)) {
- p[cur] = S_VAL(&s, ix);
- printf("%ld\n", p[cur]);
- ++cur;
- }
- }
-
- sieve_reset(&s, p[cur - 1]);
- fprintf(stderr, "%s: crossing off %d found primes ... \n", argv[0], cur);
- for(ix = 0; ix < cur; ix++) {
- sieve_cross(&s, p[ix]);
- if(!(ix % 1000))
- fputc('.', stderr);
- }
- fputc('\n', stderr);
-
- free(p);
-
- fprintf(stderr, "%s: sieving again from %ld ... \n", argv[0], p[cur - 1]);
- c = 0;
- while((pr = sieve_next(&s)) > 0) {
- ++c;
- }
-
- fprintf(stderr, "%s: done!\n", argv[0]);
- for(ix = 0; ix < s.nbits; ix++) {
- if(S_ISSET(&s, ix)) {
- printf("%ld\n", S_VAL(&s, ix));
- }
- }
-
- sieve_clear(&s);
-
- return 0;
-}
-
-void sieve_init(sieve *sp, long base, int nbits)
-{
- sp->size = (nbits / CHAR_BIT);
-
- if(nbits % CHAR_BIT)
- ++sp->size;
-
- sp->bits = calloc(sp->size, sizeof(byte));
- memset(sp->bits, UCHAR_MAX, sp->size);
- if(!(base & 1))
- ++base;
- sp->base = base;
-
- sp->next = 0;
- sp->nbits = sp->size * CHAR_BIT;
-}
-
-void sieve_grow(sieve *sp, int nbits)
-{
- int ns = (nbits / CHAR_BIT);
-
- if(nbits % CHAR_BIT)
- ++ns;
-
- if(ns > sp->size) {
- byte *tmp;
- int ix;
-
- tmp = calloc(ns, sizeof(byte));
- if(tmp == NULL) {
- fprintf(stderr, "Error: out of memory in sieve_grow\n");
- return;
- }
-
- memcpy(tmp, sp->bits, sp->size);
- for(ix = sp->size; ix < ns; ix++) {
- tmp[ix] = UCHAR_MAX;
- }
-
- free(sp->bits);
- sp->bits = tmp;
- sp->size = ns;
-
- sp->nbits = sp->size * CHAR_BIT;
- }
-}
-
-long sieve_next(sieve *sp)
-{
- long out;
- int ix = 0;
- long val;
-
- if(sp->next > sp->nbits)
- return -1;
-
- out = S_VAL(sp, sp->next);
-#ifdef DEBUG
- fprintf(stderr, "Sieving %ld\n", out);
-#endif
-
- /* Sieve out all multiples of the current prime */
- val = out;
- while(ix < sp->nbits) {
- val += out;
- ix = S_BIT(sp, val);
- if((val & 1) && ix < sp->nbits) { /* && S_ISSET(sp, ix)) { */
- S_CLR(sp, ix);
-#ifdef DEBUG
- fprintf(stderr, "Crossing out %ld (bit %d)\n", val, ix);
-#endif
- }
- }
-
- /* Scan ahead to the next prime */
- ++sp->next;
- while(sp->next < sp->nbits && !S_ISSET(sp, sp->next))
- ++sp->next;
-
- return out;
-}
-
-void sieve_cross(sieve *sp, long val)
-{
- int ix = 0;
- long cur = val;
-
- while(cur < sp->base)
- cur += val;
-
- ix = S_BIT(sp, cur);
- while(ix < sp->nbits) {
- if(cur & 1)
- S_CLR(sp, ix);
- cur += val;
- ix = S_BIT(sp, cur);
- }
-}
-
-void sieve_reset(sieve *sp, long base)
-{
- memset(sp->bits, UCHAR_MAX, sp->size);
- sp->base = base;
- sp->next = 0;
-}
-
-void sieve_clear(sieve *sp)
-{
- if(sp->bits)
- free(sp->bits);
-
- sp->bits = NULL;
-}
diff --git a/security/nss/lib/freebl/mpi/vis_32.il b/security/nss/lib/freebl/mpi/vis_32.il
deleted file mode 100644
index 093c176fd..000000000
--- a/security/nss/lib/freebl/mpi/vis_32.il
+++ /dev/null
@@ -1,1292 +0,0 @@
-!
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-! $Id$
-
-! The interface to the VIS instructions as declared below (and in the VIS
-! User's Manual) will not change, but the macro implementation might change
-! in the future.
-
-!--------------------------------------------------------------------
-! Pure edge handling instructions
-!
-! int vis_edge8(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge8,8
- edge8 %o0,%o1,%o0
- .end
-!
-! int vis_edge8l(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge8l,8
- edge8l %o0,%o1,%o0
- .end
-!
-! int vis_edge16(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge16,8
- edge16 %o0,%o1,%o0
- .end
-!
-! int vis_edge16l(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge16l,8
- edge16l %o0,%o1,%o0
- .end
-!
-! int vis_edge32(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge32,8
- edge32 %o0,%o1,%o0
- .end
-!
-! int vis_edge32l(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge32l,8
- edge32l %o0,%o1,%o0
- .end
-
-!--------------------------------------------------------------------
-! Edge handling instructions with negative return values if cc set
-!
-! int vis_edge8cc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge8cc,8
- edge8 %o0,%o1,%o0
- mov 0,%o1
- movgu %icc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge8lcc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge8lcc,8
- edge8l %o0,%o1,%o0
- mov 0,%o1
- movgu %icc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge16cc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge16cc,8
- edge16 %o0,%o1,%o0
- mov 0,%o1
- movgu %icc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge16lcc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge16lcc,8
- edge16l %o0,%o1,%o0
- mov 0,%o1
- movgu %icc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge32cc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge32cc,8
- edge32 %o0,%o1,%o0
- mov 0,%o1
- movgu %icc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge32lcc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge32lcc,8
- edge32l %o0,%o1,%o0
- mov 0,%o1
- movgu %icc,-1024,%o1
- or %o1,%o0,%o0
- .end
-
-!--------------------------------------------------------------------
-! Alignment instructions
-!
-! void *vis_alignaddr(void */*rs1*/, int /*rs2*/);
-!
- .inline vis_alignaddr,8
- alignaddr %o0,%o1,%o0
- .end
-!
-! void *vis_alignaddrl(void */*rs1*/, int /*rs2*/);
-!
- .inline vis_alignaddrl,8
- alignaddrl %o0,%o1,%o0
- .end
-!
-! double vis_faligndata(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_faligndata,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- faligndata %f4,%f10,%f0
- .end
-
-!--------------------------------------------------------------------
-! Partitioned comparison instructions
-!
-! int vis_fcmple16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmple16,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fcmple16 %f4,%f10,%o0
- .end
-!
-! int vis_fcmpne16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpne16,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fcmpne16 %f4,%f10,%o0
- .end
-!
-! int vis_fcmple32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmple32,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fcmple32 %f4,%f10,%o0
- .end
-!
-! int vis_fcmpne32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpne32,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fcmpne32 %f4,%f10,%o0
- .end
-!
-! int vis_fcmpgt16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpgt16,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fcmpgt16 %f4,%f10,%o0
- .end
-!
-! int vis_fcmpeq16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpeq16,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fcmpeq16 %f4,%f10,%o0
- .end
-!
-! int vis_fcmpgt32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpgt32,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fcmpgt32 %f4,%f10,%o0
- .end
-!
-! int vis_fcmpeq32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpeq32,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fcmpeq32 %f4,%f10,%o0
- .end
-
-!--------------------------------------------------------------------
-! Partitioned arithmetic
-!
-! double vis_fmul8x16(float /*frs1*/, double /*frs2*/);
-!
- .inline vis_fmul8x16,12
- st %o0,[%sp+0x44]
- ld [%sp+0x44],%f4
- st %o1,[%sp+0x48]
- st %o2,[%sp+0x4c]
- ldd [%sp+0x48],%f10
- fmul8x16 %f4,%f10,%f0
- .end
-!
-! double vis_fmul8x16_dummy(float /*frs1*/, int /*dummy*/, double /*frs2*/);
-!
- .inline vis_fmul8x16_dummy,16
- st %o0,[%sp+0x44]
- ld [%sp+0x44],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fmul8x16 %f4,%f10,%f0
- .end
-!
-! double vis_fmul8x16au(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fmul8x16au,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fmul8x16au %f4,%f10,%f0
- .end
-!
-! double vis_fmul8x16al(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fmul8x16al,8
- st %o0,[%sp+0x44]
- ld [%sp+0x44],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fmul8x16al %f4,%f10,%f0
- .end
-!
-! double vis_fmul8sux16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fmul8sux16,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fmul8sux16 %f4,%f10,%f0
- .end
-!
-! double vis_fmul8ulx16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fmul8ulx16,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fmul8ulx16 %f4,%f10,%f0
- .end
-!
-! double vis_fmuld8sux16(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fmuld8sux16,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fmuld8sux16 %f4,%f10,%f0
- .end
-!
-! double vis_fmuld8ulx16(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fmuld8ulx16,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fmuld8ulx16 %f4,%f10,%f0
- .end
-!
-! double vis_fpadd16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpadd16,16
- std %o0,[%sp+0x40]
- ldd [%sp+0x40],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fpadd16 %f4,%f10,%f0
- .end
-!
-! float vis_fpadd16s(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpadd16s,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fpadd16s %f4,%f10,%f0
- .end
-!
-! double vis_fpadd32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpadd32,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fpadd32 %f4,%f10,%f0
- .end
-!
-! float vis_fpadd32s(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpadd32s,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fpadd32s %f4,%f10,%f0
- .end
-!
-! double vis_fpsub16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpsub16,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fpsub16 %f4,%f10,%f0
- .end
-!
-! float vis_fpsub16s(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpsub16s,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fpsub16s %f4,%f10,%f0
- .end
-!
-! double vis_fpsub32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpsub32,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fpsub32 %f4,%f10,%f0
- .end
-!
-! float vis_fpsub32s(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpsub32s,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fpsub32s %f4,%f10,%f0
- .end
-
-!--------------------------------------------------------------------
-! Pixel packing
-!
-! float vis_fpack16(double /*frs2*/);
-!
- .inline vis_fpack16,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- fpack16 %f4,%f0
- .end
-
-!
-! double vis_fpack16_pair(double /*frs2*/, double /*frs2*/);
-!
- .inline vis_fpack16_pair,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fpack16 %f4,%f0
- fpack16 %f10,%f1
- .end
-!
-! void vis_st2_fpack16(double, double, double *)
-!
- .inline vis_st2_fpack16,20
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fpack16 %f4,%f0
- fpack16 %f10,%f1
- st %f0,[%o4+0]
- st %f1,[%o4+4]
- .end
-!
-! void vis_std_fpack16(double, double, double *)
-!
- .inline vis_std_fpack16,20
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fpack16 %f4,%f0
- fpack16 %f10,%f1
- std %f0,[%o4]
- .end
-!
-! void vis_st2_fpackfix(double, double, double *)
-!
- .inline vis_st2_fpackfix,20
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fpackfix %f4,%f0
- fpackfix %f10,%f1
- st %f0,[%o4+0]
- st %f1,[%o4+4]
- .end
-!
-! double vis_fpack16_to_hi(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpack16_to_hi,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f0
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f4
- fpack16 %f4,%f0
- .end
-
-! double vis_fpack16_to_lo(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpack16_to_lo,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f0
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f4
- fpack16 %f4,%f3
- fmovs %f3,%f1 /* without this, optimizer goes wrong */
- .end
-
-!
-! double vis_fpack32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpack32,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fpack32 %f4,%f10,%f0
- .end
-!
-! float vis_fpackfix(double /*frs2*/);
-!
- .inline vis_fpackfix,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- fpackfix %f4,%f0
- .end
-!
-! double vis_fpackfix_pair(double /*frs2*/, double /*frs2*/);
-!
- .inline vis_fpackfix_pair,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f6
- fpackfix %f4,%f0
- fpackfix %f6,%f1
- .end
-
-!--------------------------------------------------------------------
-! Motion estimation
-!
-! double vis_pdist(double /*frs1*/, double /*frs2*/, double /*frd*/);
-!
- .inline vis_pdist,24
- std %o4,[%sp+0x48]
- ldd [%sp+0x48],%f0
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- pdist %f4,%f10,%f0
- .end
-
-!--------------------------------------------------------------------
-! Channel merging
-!
-! double vis_fpmerge(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpmerge,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fpmerge %f4,%f10,%f0
- .end
-
-!--------------------------------------------------------------------
-! Pixel expansion
-!
-! double vis_fexpand(float /*frs2*/);
-!
- .inline vis_fexpand,4
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- fexpand %f4,%f0
- .end
-
-! double vis_fexpand_hi(double /*frs2*/);
-!
- .inline vis_fexpand_hi,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- fexpand %f4,%f0
- .end
-
-! double vis_fexpand_lo(double /*frs2*/);
-!
- .inline vis_fexpand_lo,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- fmovs %f5, %f2
- fexpand %f2,%f0
- .end
-
-!--------------------------------------------------------------------
-! Bitwise logical operations
-!
-! double vis_fnor(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fnor,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fnor %f4,%f10,%f0
- .end
-!
-! float vis_fnors(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fnors,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fnors %f4,%f10,%f0
- .end
-!
-! double vis_fandnot(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fandnot,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fandnot1 %f4,%f10,%f0
- .end
-!
-! float vis_fandnots(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fandnots,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fandnot1s %f4,%f10,%f0
- .end
-!
-! double vis_fnot(double /*frs1*/);
-!
- .inline vis_fnot,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- fnot1 %f4,%f0
- .end
-!
-! float vis_fnots(float /*frs1*/);
-!
- .inline vis_fnots,4
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- fnot1s %f4,%f0
- .end
-!
-! double vis_fxor(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fxor,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fxor %f4,%f10,%f0
- .end
-!
-! float vis_fxors(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fxors,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fxors %f4,%f10,%f0
- .end
-!
-! double vis_fnand(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fnand,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fnand %f4,%f10,%f0
- .end
-!
-! float vis_fnands(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fnands,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fnands %f4,%f10,%f0
- .end
-!
-! double vis_fand(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fand,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fand %f4,%f10,%f0
- .end
-!
-! float vis_fands(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fands,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fands %f4,%f10,%f0
- .end
-!
-! double vis_fxnor(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fxnor,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fxnor %f4,%f10,%f0
- .end
-!
-! float vis_fxnors(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fxnors,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fxnors %f4,%f10,%f0
- .end
-!
-! double vis_fsrc(double /*frs1*/);
-!
- .inline vis_fsrc,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- fsrc1 %f4,%f0
- .end
-!
-! float vis_fsrcs(float /*frs1*/);
-!
- .inline vis_fsrcs,4
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- fsrc1s %f4,%f0
- .end
-!
-! double vis_fornot(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fornot,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- fornot1 %f4,%f10,%f0
- .end
-!
-! float vis_fornots(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fornots,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fornot1s %f4,%f10,%f0
- .end
-!
-! double vis_for(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_for,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- std %o2,[%sp+0x48]
- ldd [%sp+0x48],%f10
- for %f4,%f10,%f0
- .end
-!
-! float vis_fors(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fors,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- st %o1,[%sp+0x48]
- ld [%sp+0x48],%f10
- fors %f4,%f10,%f0
- .end
-!
-! double vis_fzero(/* void */)
-!
- .inline vis_fzero,0
- fzero %f0
- .end
-!
-! float vis_fzeros(/* void */)
-!
- .inline vis_fzeros,0
- fzeros %f0
- .end
-!
-! double vis_fone(/* void */)
-!
- .inline vis_fone,0
- fone %f0
- .end
-!
-! float vis_fones(/* void */)
-!
- .inline vis_fones,0
- fones %f0
- .end
-
-!--------------------------------------------------------------------
-! Partial store instructions
-!
-! vis_stdfa_ASI_PST8P(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST8P,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]%o3,0xc0 ! ASI_PST8_P
- .end
-!
-! vis_stdfa_ASI_PST8PL(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST8PL,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]%o3,0xc8 ! ASI_PST8_PL
- .end
-!
-! vis_stdfa_ASI_PST8P_int_pair(void *rs1, void *rs2, void *rs3, int rmask);
-!
- .inline vis_stdfa_ASI_PST8P_int_pair,16
- ld [%o0],%f4
- ld [%o1],%f5
- stda %f4,[%o2]%o3,0xc0 ! ASI_PST8_P
- .end
-!
-! vis_stdfa_ASI_PST8S(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST8S,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]%o3,0xc1 ! ASI_PST8_S
- .end
-!
-! vis_stdfa_ASI_PST16P(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST16P,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]%o3,0xc2 ! ASI_PST16_P
- .end
-!
-! vis_stdfa_ASI_PST16S(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST16S,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]%o3,0xc3 ! ASI_PST16_S
- .end
-!
-! vis_stdfa_ASI_PST32P(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST32P,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]%o3,0xc4 ! ASI_PST32_P
- .end
-!
-! vis_stdfa_ASI_PST32S(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST32S,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]%o3,0xc5 ! ASI_PST32_S
- .end
-
-!--------------------------------------------------------------------
-! Short store instructions
-!
-! vis_stdfa_ASI_FL8P(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL8P,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0xd0 ! ASI_FL8_P
- .end
-!
-! vis_stdfa_ASI_FL8P_index(double frd, void *rs1, long index)
-!
- .inline vis_stdfa_ASI_FL8P_index,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2+%o3]0xd0 ! ASI_FL8_P
- .end
-!
-! vis_stdfa_ASI_FL8S(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL8S,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0xd1 ! ASI_FL8_S
- .end
-!
-! vis_stdfa_ASI_FL16P(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL16P,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0xd2 ! ASI_FL16_P
- .end
-!
-! vis_stdfa_ASI_FL16P_index(double frd, void *rs1, long index)
-!
- .inline vis_stdfa_ASI_FL16P_index,16
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2+%o3]0xd2 ! ASI_FL16_P
- .end
-!
-! vis_stdfa_ASI_FL16S(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL16S,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0xd3 ! ASI_FL16_S
- .end
-!
-! vis_stdfa_ASI_FL8PL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL8PL,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0xd8 ! ASI_FL8_PL
- .end
-!
-! vis_stdfa_ASI_FL8SL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL8SL,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0xd9 ! ASI_FL8_SL
- .end
-!
-! vis_stdfa_ASI_FL16PL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL16PL,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0xda ! ASI_FL16_PL
- .end
-!
-! vis_stdfa_ASI_FL16SL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL16SL,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0xdb ! ASI_FL16_SL
- .end
-
-!--------------------------------------------------------------------
-! Short load instructions
-!
-! double vis_lddfa_ASI_FL8P(void *rs1)
-!
- .inline vis_lddfa_ASI_FL8P,4
- ldda [%o0]0xd0,%f4 ! ASI_FL8_P
- fmovd %f4,%f0 ! Compiler can clean this up
- .end
-!
-! double vis_lddfa_ASI_FL8P_index(void *rs1, long index)
-!
- .inline vis_lddfa_ASI_FL8P_index,8
- ldda [%o0+%o1]0xd0,%f4
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8P_hi(void *rs1, unsigned int index)
-!
- .inline vis_lddfa_ASI_FL8P_hi,8
- sra %o1,16,%o1
- ldda [%o0+%o1]0xd0,%f4
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8P_lo(void *rs1, unsigned int index)
-!
- .inline vis_lddfa_ASI_FL8P_lo,8
- sll %o1,16,%o1
- sra %o1,16,%o1
- ldda [%o0+%o1]0xd0,%f4
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8S(void *rs1)
-!
- .inline vis_lddfa_ASI_FL8S,4
- ldda [%o0]0xd1,%f4 ! ASI_FL8_S
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16P(void *rs1)
-!
- .inline vis_lddfa_ASI_FL16P,4
- ldda [%o0]0xd2,%f4 ! ASI_FL16_P
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16P_index(void *rs1, long index)
-!
- .inline vis_lddfa_ASI_FL16P_index,8
- ldda [%o0+%o1]0xd2,%f4 ! ASI_FL16_P
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16S(void *rs1)
-!
- .inline vis_lddfa_ASI_FL16S,4
- ldda [%o0]0xd3,%f4 ! ASI_FL16_S
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8PL(void *rs1)
-!
- .inline vis_lddfa_ASI_FL8PL,4
- ldda [%o0]0xd8,%f4 ! ASI_FL8_PL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8PL_index(void *rs1, long index)
-!
- .inline vis_lddfa_ASI_FL8PL_index,8
- ldda [%o0+%o1]0xd8,%f4 ! ASI_FL8_PL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8SL(void *rs1)
-!
- .inline vis_lddfa_ASI_FL8SL,4
- ldda [%o0]0xd9,%f4 ! ASI_FL8_SL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16PL(void *rs1)
-!
- .inline vis_lddfa_ASI_FL16PL,4
- ldda [%o0]0xda,%f4 ! ASI_FL16_PL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16PL_index(void *rs1, long index)
-!
- .inline vis_lddfa_ASI_FL16PL_index,8
- ldda [%o0+%o1]0xda,%f4 ! ASI_FL16_PL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16SL(void *rs1)
-!
- .inline vis_lddfa_ASI_FL16SL,4
- ldda [%o0]0xdb,%f4 ! ASI_FL16_SL
- fmovd %f4,%f0
- .end
-
-!--------------------------------------------------------------------
-! Graphics status register
-!
-! unsigned int vis_read_gsr(void)
-!
- .inline vis_read_gsr,0
- rd %gsr,%o0
- .end
-!
-! void vis_write_gsr(unsigned int /* GSR */)
-!
- .inline vis_write_gsr,4
- wr %g0,%o0,%gsr
- .end
-
-!--------------------------------------------------------------------
-! Voxel texture mapping
-!
-! unsigned long vis_array8(unsigned long long /*rs1 */, int /*rs2*/)
-!
- .inline vis_array8,12
- sllx %o0,32,%o0
- srl %o1,0,%o1 ! clear the most significant 32 bits of %o1
- or %o0,%o1,%o3 ! join %o0 and %o1 into %o3
- array8 %o3,%o2,%o0
- .end
-!
-! unsigned long vis_array16(unsigned long long /*rs1*/, int /*rs2*/)
-!
- .inline vis_array16,12
- sllx %o0,32,%o0
- srl %o1,0,%o1 ! clear the most significant 32 bits of %o1
- or %o0,%o1,%o3 ! join %o0 and %o1 into %o3
- array16 %o3,%o2,%o0
- .end
-!
-! unsigned long vis_array32(unsigned long long /*rs1*/, int /*rs2*/)
-!
- .inline vis_array32,12
- sllx %o0,32,%o0
- srl %o1,0,%o1 ! clear the most significant 32 bits of %o1
- or %o0,%o1,%o3 ! join %o0 and %o1 into %o3
- array32 %o3,%o2,%o0
- .end
-
-!--------------------------------------------------------------------
-! Register aliasing and type casts
-!
-! float vis_read_hi(double /* frs1 */);
-!
- .inline vis_read_hi,8
- std %o0,[%sp+0x48] ! store double frs1
- ldd [%sp+0x48],%f0 ! %f0:%f1 = double frs1; return %f0;
- .end
-!
-! float vis_read_lo(double /* frs1 */);
-!
- .inline vis_read_lo,8
- std %o0,[%sp+0x48] ! store double frs1
- ldd [%sp+0x48],%f0 ! %f0:%f1 = double frs1;
- fmovs %f1,%f0 ! %f0 = low word (frs1); return %f0;
- .end
-!
-! double vis_write_hi(double /* frs1 */, float /* frs2 */);
-!
- .inline vis_write_hi,12
- std %o0,[%sp+0x48] ! store double frs1;
- ldd [%sp+0x48],%f0 ! %f0:%f1 = double frs1;
- st %o2,[%sp+0x44] ! store float frs2;
- ld [%sp+0x44],%f2 ! %f2 = float frs2;
- fmovs %f2,%f0 ! %f0 = float frs2; return %f0:f1;
- .end
-!
-! double vis_write_lo(double /* frs1 */, float /* frs2 */);
-!
- .inline vis_write_lo,12
- std %o0,[%sp+0x48] ! store double frs1;
- ldd [%sp+0x48],%f0 ! %f0:%f1 = double frs1;
- st %o2,[%sp+0x44] ! store float frs2;
- ld [%sp+0x44],%f2 ! %f2 = float frs2;
- fmovs %f2,%f1 ! %f1 = float frs2; return %f0:f1;
- .end
-!
-! double vis_freg_pair(float /* frs1 */, float /* frs2 */);
-!
- .inline vis_freg_pair,8
- st %o0,[%sp+0x48] ! store float frs1
- ld [%sp+0x48],%f0
- st %o1,[%sp+0x48] ! store float frs2
- ld [%sp+0x48],%f1
- .end
-!
-! float vis_to_float(unsigned int /*value*/);
-!
- .inline vis_to_float,4
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f0
- .end
-!
-! double vis_to_double(unsigned int /*value1*/, unsigned int /*value2*/);
-!
- .inline vis_to_double,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f0
- .end
-!
-! double vis_to_double_dup(unsigned int /*value*/);
-!
- .inline vis_to_double_dup,4
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f1
- fmovs %f1,%f0 ! duplicate value
- .end
-!
-! double vis_ll_to_double(unsigned long long /*value*/);
-!
- .inline vis_ll_to_double,8
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f0
- .end
-
-!--------------------------------------------------------------------
-! Address space identifier (ASI) register
-!
-! unsigned int vis_read_asi(void)
-!
- .inline vis_read_asi,0
- rd %asi,%o0
- .end
-!
-! void vis_write_asi(unsigned int /* ASI */)
-!
- .inline vis_write_asi,4
- wr %g0,%o0,%asi
- .end
-
-!--------------------------------------------------------------------
-! Load/store from/into alternate space
-!
-! float vis_ldfa_ASI_REG(void *rs1)
-!
- .inline vis_ldfa_ASI_REG,4
- lda [%o0+0]%asi,%f4
- fmovs %f4,%f0 ! Compiler can clean this up
- .end
-!
-! float vis_ldfa_ASI_P(void *rs1)
-!
- .inline vis_ldfa_ASI_P,4
- lda [%o0]0x80,%f4 ! ASI_P
- fmovs %f4,%f0 ! Compiler can clean this up
- .end
-!
-! float vis_ldfa_ASI_PL(void *rs1)
-!
- .inline vis_ldfa_ASI_PL,4
- lda [%o0]0x88,%f4 ! ASI_PL
- fmovs %f4,%f0 ! Compiler can clean this up
- .end
-!
-! double vis_lddfa_ASI_REG(void *rs1)
-!
- .inline vis_lddfa_ASI_REG,4
- ldda [%o0+0]%asi,%f4
- fmovd %f4,%f0 ! Compiler can clean this up
- .end
-!
-! double vis_lddfa_ASI_P(void *rs1)
-!
- .inline vis_lddfa_ASI_P,4
- ldda [%o0]0x80,%f4 ! ASI_P
- fmovd %f4,%f0 ! Compiler can clean this up
- .end
-!
-! double vis_lddfa_ASI_PL(void *rs1)
-!
- .inline vis_lddfa_ASI_PL,4
- ldda [%o0]0x88,%f4 ! ASI_PL
- fmovd %f4,%f0 ! Compiler can clean this up
- .end
-!
-! vis_stfa_ASI_REG(float frs, void *rs1)
-!
- .inline vis_stfa_ASI_REG,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- sta %f4,[%o1+0]%asi
- .end
-!
-! vis_stfa_ASI_P(float frs, void *rs1)
-!
- .inline vis_stfa_ASI_P,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- sta %f4,[%o1]0x80 ! ASI_P
- .end
-!
-! vis_stfa_ASI_PL(float frs, void *rs1)
-!
- .inline vis_stfa_ASI_PL,8
- st %o0,[%sp+0x48]
- ld [%sp+0x48],%f4
- sta %f4,[%o1]0x88 ! ASI_PL
- .end
-!
-! vis_stdfa_ASI_REG(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_REG,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2+0]%asi
- .end
-!
-! vis_stdfa_ASI_P(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_P,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0x80 ! ASI_P
- .end
-!
-! vis_stdfa_ASI_PL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_PL,12
- std %o0,[%sp+0x48]
- ldd [%sp+0x48],%f4
- stda %f4,[%o2]0x88 ! ASI_PL
- .end
-!
-! unsigned short vis_lduha_ASI_REG(void *rs1)
-!
- .inline vis_lduha_ASI_REG,4
- lduha [%o0+0]%asi,%o0
- .end
-!
-! unsigned short vis_lduha_ASI_P(void *rs1)
-!
- .inline vis_lduha_ASI_P,4
- lduha [%o0]0x80,%o0 ! ASI_P
- .end
-!
-! unsigned short vis_lduha_ASI_PL(void *rs1)
-!
- .inline vis_lduha_ASI_PL,4
- lduha [%o0]0x88,%o0 ! ASI_PL
- .end
-!
-! unsigned short vis_lduha_ASI_P_index(void *rs1, long index)
-!
- .inline vis_lduha_ASI_P_index,8
- lduha [%o0+%o1]0x80,%o0 ! ASI_P
- .end
-!
-! unsigned short vis_lduha_ASI_PL_index(void *rs1, long index)
-!
- .inline vis_lduha_ASI_PL_index,8
- lduha [%o0+%o1]0x88,%o0 ! ASI_PL
- .end
-
-!--------------------------------------------------------------------
-! Prefetch
-!
-! void vis_prefetch_read(void * /*address*/);
-!
- .inline vis_prefetch_read,4
- prefetch [%o0+0],0
- .end
-!
-! void vis_prefetch_write(void * /*address*/);
-!
- .inline vis_prefetch_write,4
- prefetch [%o0+0],2
- .end
diff --git a/security/nss/lib/freebl/mpi/vis_64.il b/security/nss/lib/freebl/mpi/vis_64.il
deleted file mode 100644
index 39ab79a1a..000000000
--- a/security/nss/lib/freebl/mpi/vis_64.il
+++ /dev/null
@@ -1,998 +0,0 @@
-!
-! This Source Code Form is subject to the terms of the Mozilla Public
-! License, v. 2.0. If a copy of the MPL was not distributed with this
-! file, You can obtain one at http://mozilla.org/MPL/2.0/.
-! $Id$
-
-! This file is to be used in place of vis.il in 64-bit builds.
-
-!--------------------------------------------------------------------
-! Pure edge handling instructions
-!
-! int vis_edge8(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge8,16
- edge8 %o0,%o1,%o0
- .end
-!
-! int vis_edge8l(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge8l,16
- edge8l %o0,%o1,%o0
- .end
-!
-! int vis_edge16(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge16,16
- edge16 %o0,%o1,%o0
- .end
-!
-! int vis_edge16l(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge16l,16
- edge16l %o0,%o1,%o0
- .end
-!
-! int vis_edge32(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge32,16
- edge32 %o0,%o1,%o0
- .end
-!
-! int vis_edge32l(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge32l,16
- edge32l %o0,%o1,%o0
- .end
-
-!--------------------------------------------------------------------
-! Edge handling instructions with negative return values if cc set
-!
-! int vis_edge8cc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge8cc,16
- edge8 %o0,%o1,%o0
- mov 0,%o1
- movgu %xcc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge8lcc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge8lcc,16
- edge8l %o0,%o1,%o0
- mov 0,%o1
- movgu %xcc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge16cc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge16cc,16
- edge16 %o0,%o1,%o0
- mov 0,%o1
- movgu %xcc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge16lcc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge16lcc,16
- edge16l %o0,%o1,%o0
- mov 0,%o1
- movgu %xcc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge32cc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge32cc,16
- edge32 %o0,%o1,%o0
- mov 0,%o1
- movgu %xcc,-1024,%o1
- or %o1,%o0,%o0
- .end
-!
-! int vis_edge32lcc(void */*frs1*/, void */*frs2*/);
-!
- .inline vis_edge32lcc,16
- edge32l %o0,%o1,%o0
- mov 0,%o1
- movgu %xcc,-1024,%o1
- or %o1,%o0,%o0
- .end
-
-!--------------------------------------------------------------------
-! Alignment instructions
-!
-! void *vis_alignaddr(void */*rs1*/, int /*rs2*/);
-!
- .inline vis_alignaddr,12
- alignaddr %o0,%o1,%o0
- .end
-!
-! void *vis_alignaddrl(void */*rs1*/, int /*rs2*/);
-!
- .inline vis_alignaddrl,12
- alignaddrl %o0,%o1,%o0
- .end
-!
-! double vis_faligndata(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_faligndata,16
- faligndata %f0,%f2,%f0
- .end
-
-!--------------------------------------------------------------------
-! Partitioned comparison instructions
-!
-! int vis_fcmple16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmple16,16
- fcmple16 %f0,%f2,%o0
- .end
-!
-! int vis_fcmpne16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpne16,16
- fcmpne16 %f0,%f2,%o0
- .end
-!
-! int vis_fcmple32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmple32,16
- fcmple32 %f0,%f2,%o0
- .end
-!
-! int vis_fcmpne32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpne32,16
- fcmpne32 %f0,%f2,%o0
- .end
-!
-! int vis_fcmpgt16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpgt16,16
- fcmpgt16 %f0,%f2,%o0
- .end
-!
-! int vis_fcmpeq16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpeq16,16
- fcmpeq16 %f0,%f2,%o0
- .end
-!
-! int vis_fcmpgt32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpgt32,16
- fcmpgt32 %f0,%f2,%o0
- .end
-!
-! int vis_fcmpeq32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fcmpeq32,16
- fcmpeq32 %f0,%f2,%o0
- .end
-
-!--------------------------------------------------------------------
-! Partitioned arithmetic
-!
-! double vis_fmul8x16(float /*frs1*/, double /*frs2*/);
-!
- .inline vis_fmul8x16,12
- fmul8x16 %f1,%f2,%f0
- .end
-!
-! double vis_fmul8x16_dummy(float /*frs1*/, int /*dummy*/, double /*frs2*/);
-!
- .inline vis_fmul8x16_dummy,16
- fmul8x16 %f1,%f4,%f0
- .end
-!
-! double vis_fmul8x16au(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fmul8x16au,8
- fmul8x16au %f1,%f3,%f0
- .end
-!
-! double vis_fmul8x16al(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fmul8x16al,8
- fmul8x16al %f1,%f3,%f0
- .end
-!
-! double vis_fmul8sux16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fmul8sux16,16
- fmul8sux16 %f0,%f2,%f0
- .end
-!
-! double vis_fmul8ulx16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fmul8ulx16,16
- fmul8ulx16 %f0,%f2,%f0
- .end
-!
-! double vis_fmuld8sux16(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fmuld8sux16,8
- fmuld8sux16 %f1,%f3,%f0
- .end
-!
-! double vis_fmuld8ulx16(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fmuld8ulx16,8
- fmuld8ulx16 %f1,%f3,%f0
- .end
-!
-! double vis_fpadd16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpadd16,16
- fpadd16 %f0,%f2,%f0
- .end
-!
-! float vis_fpadd16s(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpadd16s,8
- fpadd16s %f1,%f3,%f0
- .end
-!
-! double vis_fpadd32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpadd32,16
- fpadd32 %f0,%f2,%f0
- .end
-!
-! float vis_fpadd32s(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpadd32s,8
- fpadd32s %f1,%f3,%f0
- .end
-!
-! double vis_fpsub16(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpsub16,16
- fpsub16 %f0,%f2,%f0
- .end
-!
-! float vis_fpsub16s(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpsub16s,8
- fpsub16s %f1,%f3,%f0
- .end
-!
-! double vis_fpsub32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpsub32,16
- fpsub32 %f0,%f2,%f0
- .end
-!
-! float vis_fpsub32s(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpsub32s,8
- fpsub32s %f1,%f3,%f0
- .end
-
-!--------------------------------------------------------------------
-! Pixel packing
-!
-! float vis_fpack16(double /*frs2*/);
-!
- .inline vis_fpack16,8
- fpack16 %f0,%f0
- .end
-!
-! double vis_fpack16_pair(double /*frs2*/, double /*frs2*/);
-!
- .inline vis_fpack16_pair,16
- fpack16 %f0,%f0
- fpack16 %f2,%f1
- .end
-!
-! void vis_st2_fpack16(double, double, double *)
-!
- .inline vis_st2_fpack16,24
- fpack16 %f0,%f0
- fpack16 %f2,%f1
- st %f0,[%o2+0]
- st %f1,[%o2+4]
- .end
-!
-! void vis_std_fpack16(double, double, double *)
-!
- .inline vis_std_fpack16,24
- fpack16 %f0,%f0
- fpack16 %f2,%f1
- std %f0,[%o2]
- .end
-!
-! void vis_st2_fpackfix(double, double, double *)
-!
- .inline vis_st2_fpackfix,24
- fpackfix %f0,%f0
- fpackfix %f2,%f1
- st %f0,[%o2+0]
- st %f1,[%o2+4]
- .end
-!
-! double vis_fpack16_to_hi(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpack16_to_hi,16
- fpack16 %f2,%f0
- .end
-
-! double vis_fpack16_to_lo(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpack16_to_lo,16
- fpack16 %f2,%f3
- fmovs %f3,%f1 /* without this, optimizer goes wrong */
- .end
-
-!
-! double vis_fpack32(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fpack32,16
- fpack32 %f0,%f2,%f0
- .end
-!
-! float vis_fpackfix(double /*frs2*/);
-!
- .inline vis_fpackfix,8
- fpackfix %f0,%f0
- .end
-!
-! double vis_fpackfix_pair(double /*frs2*/, double /*frs2*/);
-!
- .inline vis_fpackfix_pair,16
- fpackfix %f0,%f0
- fpackfix %f2,%f1
- .end
-
-!--------------------------------------------------------------------
-! Motion estimation
-!
-! double vis_pxldist64(double accum /*frd*/, double pxls1 /*frs1*/,
-! double pxls2 /*frs2*/);
-!
- .inline vis_pxldist64,24
- pdist %f2,%f4,%f0
- .end
-
-!--------------------------------------------------------------------
-! Channel merging
-!
-! double vis_fpmerge(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fpmerge,8
- fpmerge %f1,%f3,%f0
- .end
-
-!--------------------------------------------------------------------
-! Pixel expansion
-!
-! double vis_fexpand(float /*frs2*/);
-!
- .inline vis_fexpand,4
- fexpand %f1,%f0
- .end
-
-! double vis_fexpand_hi(double /*frs2*/);
-!
- .inline vis_fexpand_hi,8
- fexpand %f0,%f0
- .end
-
-! double vis_fexpand_lo(double /*frs2*/);
-!
- .inline vis_fexpand_lo,8
- fexpand %f1,%f0
- .end
-
-!--------------------------------------------------------------------
-! Bitwise logical operations
-!
-! double vis_fnor(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fnor,16
- fnor %f0,%f2,%f0
- .end
-!
-! float vis_fnors(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fnors,8
- fnors %f1,%f3,%f0
- .end
-!
-! double vis_fandnot(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fandnot,16
- fandnot1 %f0,%f2,%f0
- .end
-!
-! float vis_fandnots(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fandnots,8
- fandnot1s %f1,%f3,%f0
- .end
-!
-! double vis_fnot(double /*frs1*/);
-!
- .inline vis_fnot,8
- fnot1 %f0,%f0
- .end
-!
-! float vis_fnots(float /*frs1*/);
-!
- .inline vis_fnots,4
- fnot1s %f1,%f0
- .end
-!
-! double vis_fxor(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fxor,16
- fxor %f0,%f2,%f0
- .end
-!
-! float vis_fxors(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fxors,8
- fxors %f1,%f3,%f0
- .end
-!
-! double vis_fnand(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fnand,16
- fnand %f0,%f2,%f0
- .end
-!
-! float vis_fnands(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fnands,8
- fnands %f1,%f3,%f0
- .end
-!
-! double vis_fand(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fand,16
- fand %f0,%f2,%f0
- .end
-!
-! float vis_fands(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fands,8
- fands %f1,%f3,%f0
- .end
-!
-! double vis_fxnor(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fxnor,16
- fxnor %f0,%f2,%f0
- .end
-!
-! float vis_fxnors(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fxnors,8
- fxnors %f1,%f3,%f0
- .end
-!
-! double vis_fsrc(double /*frs1*/);
-!
- .inline vis_fsrc,8
- fsrc1 %f0,%f0
- .end
-!
-! float vis_fsrcs(float /*frs1*/);
-!
- .inline vis_fsrcs,4
- fsrc1s %f1,%f0
- .end
-!
-! double vis_fornot(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_fornot,16
- fornot1 %f0,%f2,%f0
- .end
-!
-! float vis_fornots(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fornots,8
- fornot1s %f1,%f3,%f0
- .end
-!
-! double vis_for(double /*frs1*/, double /*frs2*/);
-!
- .inline vis_for,16
- for %f0,%f2,%f0
- .end
-!
-! float vis_fors(float /*frs1*/, float /*frs2*/);
-!
- .inline vis_fors,8
- fors %f1,%f3,%f0
- .end
-!
-! double vis_fzero(/* void */)
-!
- .inline vis_fzero,0
- fzero %f0
- .end
-!
-! float vis_fzeros(/* void */)
-!
- .inline vis_fzeros,0
- fzeros %f0
- .end
-!
-! double vis_fone(/* void */)
-!
- .inline vis_fone,0
- fone %f0
- .end
-!
-! float vis_fones(/* void */)
-!
- .inline vis_fones,0
- fones %f0
- .end
-
-!--------------------------------------------------------------------
-! Partial store instructions
-!
-! vis_stdfa_ASI_PST8P(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST8P,20
- stda %f0,[%o1]%o2,0xc0 ! ASI_PST8_P
- .end
-!
-! vis_stdfa_ASI_PST8PL(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST8PL,20
- stda %f0,[%o1]%o2,0xc8 ! ASI_PST8_PL
- .end
-!
-! vis_stdfa_ASI_PST8P_int_pair(void *rs1, void *rs2, void *rs3, int rmask);
-!
- .inline vis_stdfa_ASI_PST8P_int_pair,28
- ld [%o0],%f4
- ld [%o1],%f5
- stda %f4,[%o2]%o3,0xc0 ! ASI_PST8_P
- .end
-!
-! vis_stdfa_ASI_PST8S(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST8S,20
- stda %f0,[%o1]%o2,0xc1 ! ASI_PST8_S
- .end
-!
-! vis_stdfa_ASI_PST16P(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST16P,20
- stda %f0,[%o1]%o2,0xc2 ! ASI_PST16_P
- .end
-!
-! vis_stdfa_ASI_PST16S(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST16S,20
- stda %f0,[%o1]%o2,0xc3 ! ASI_PST16_S
- .end
-!
-! vis_stdfa_ASI_PST32P(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST32P,20
- stda %f0,[%o1]%o2,0xc4 ! ASI_PST32_P
- .end
-!
-! vis_stdfa_ASI_PST32S(double frd, void *rs1, int rmask)
-!
- .inline vis_stdfa_ASI_PST32S,20
- stda %f0,[%o1]%o2,0xc5 ! ASI_PST32_S
- .end
-
-!--------------------------------------------------------------------
-! Short store instructions
-!
-! vis_stdfa_ASI_FL8P(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL8P,16
- stda %f0,[%o1]0xd0 ! ASI_FL8_P
- .end
-!
-! vis_stdfa_ASI_FL8P_index(double frd, void *rs1, long index)
-!
- .inline vis_stdfa_ASI_FL8P_index,24
- stda %f0,[%o1+%o2]0xd0 ! ASI_FL8_P
- .end
-!
-! vis_stdfa_ASI_FL8S(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL8S,16
- stda %f0,[%o1]0xd1 ! ASI_FL8_S
- .end
-!
-! vis_stdfa_ASI_FL16P(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL16P,16
- stda %f0,[%o1]0xd2 ! ASI_FL16_P
- .end
-!
-! vis_stdfa_ASI_FL16P_index(double frd, void *rs1, long index)
-!
- .inline vis_stdfa_ASI_FL16P_index,24
- stda %f0,[%o1+%o2]0xd2 ! ASI_FL16_P
- .end
-!
-! vis_stdfa_ASI_FL16S(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL16S,16
- stda %f0,[%o1]0xd3 ! ASI_FL16_S
- .end
-!
-! vis_stdfa_ASI_FL8PL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL8PL,16
- stda %f0,[%o1]0xd8 ! ASI_FL8_PL
- .end
-!
-! vis_stdfa_ASI_FL8SL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL8SL,16
- stda %f0,[%o1]0xd9 ! ASI_FL8_SL
- .end
-!
-! vis_stdfa_ASI_FL16PL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL16PL,16
- stda %f0,[%o1]0xda ! ASI_FL16_PL
- .end
-!
-! vis_stdfa_ASI_FL16SL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_FL16SL,16
- stda %f0,[%o1]0xdb ! ASI_FL16_SL
- .end
-
-!--------------------------------------------------------------------
-! Short load instructions
-!
-! double vis_lddfa_ASI_FL8P(void *rs1)
-!
- .inline vis_lddfa_ASI_FL8P,8
- ldda [%o0]0xd0,%f4 ! ASI_FL8_P
- fmovd %f4,%f0 ! Compiler can clean this up
- .end
-!
-! double vis_lddfa_ASI_FL8P_index(void *rs1, long index)
-!
- .inline vis_lddfa_ASI_FL8P_index,16
- ldda [%o0+%o1]0xd0,%f4
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8P_hi(void *rs1, unsigned int index)
-!
- .inline vis_lddfa_ASI_FL8P_hi,12
- sra %o1,16,%o1
- ldda [%o0+%o1]0xd0,%f4
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8P_lo(void *rs1, unsigned int index)
-!
- .inline vis_lddfa_ASI_FL8P_lo,12
- sll %o1,16,%o1
- sra %o1,16,%o1
- ldda [%o0+%o1]0xd0,%f4
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8S(void *rs1)
-!
- .inline vis_lddfa_ASI_FL8S,8
- ldda [%o0]0xd1,%f4 ! ASI_FL8_S
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16P(void *rs1)
-!
- .inline vis_lddfa_ASI_FL16P,8
- ldda [%o0]0xd2,%f4 ! ASI_FL16_P
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16P_index(void *rs1, long index)
-!
- .inline vis_lddfa_ASI_FL16P_index,16
- ldda [%o0+%o1]0xd2,%f4 ! ASI_FL16_P
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16S(void *rs1)
-!
- .inline vis_lddfa_ASI_FL16S,8
- ldda [%o0]0xd3,%f4 ! ASI_FL16_S
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8PL(void *rs1)
-!
- .inline vis_lddfa_ASI_FL8PL,8
- ldda [%o0]0xd8,%f4 ! ASI_FL8_PL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8PL_index(void *rs1, long index)
-!
- .inline vis_lddfa_ASI_FL8PL_index,16
- ldda [%o0+%o1]0xd8,%f4 ! ASI_FL8_PL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL8SL(void *rs1)
-!
- .inline vis_lddfa_ASI_FL8SL,8
- ldda [%o0]0xd9,%f4 ! ASI_FL8_SL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16PL(void *rs1)
-!
- .inline vis_lddfa_ASI_FL16PL,8
- ldda [%o0]0xda,%f4 ! ASI_FL16_PL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16PL_index(void *rs1, long index)
-!
- .inline vis_lddfa_ASI_FL16PL_index,16
- ldda [%o0+%o1]0xda,%f4 ! ASI_FL16_PL
- fmovd %f4,%f0
- .end
-!
-! double vis_lddfa_ASI_FL16SL(void *rs1)
-!
- .inline vis_lddfa_ASI_FL16SL,8
- ldda [%o0]0xdb,%f4 ! ASI_FL16_SL
- fmovd %f4,%f0
- .end
-
-!--------------------------------------------------------------------
-! Graphics status register
-!
-! unsigned int vis_read_gsr(void)
-!
- .inline vis_read_gsr,0
- rd %gsr,%o0
- .end
-!
-! void vis_write_gsr(unsigned int /* GSR */)
-!
- .inline vis_write_gsr,4
- wr %g0,%o0,%gsr
- .end
-
-!--------------------------------------------------------------------
-! Voxel texture mapping
-!
-! unsigned long vis_array8(unsigned long long /*rs1 */, int /*rs2*/)
-!
- .inline vis_array8,12
- array8 %o0,%o1,%o0
- .end
-!
-! unsigned long vis_array16(unsigned long long /*rs1*/, int /*rs2*/)
-!
- .inline vis_array16,12
- array16 %o0,%o1,%o0
- .end
-!
-! unsigned long vis_array32(unsigned long long /*rs1*/, int /*rs2*/)
-!
- .inline vis_array32,12
- array32 %o0,%o1,%o0
- .end
-
-!--------------------------------------------------------------------
-! Register aliasing and type casts
-!
-! float vis_read_hi(double /* frs1 */);
-!
- .inline vis_read_hi,8
- fmovs %f0,%f0
- .end
-!
-! float vis_read_lo(double /* frs1 */);
-!
- .inline vis_read_lo,8
- fmovs %f1,%f0 ! %f0 = low word (frs1); return %f0;
- .end
-!
-! double vis_write_hi(double /* frs1 */, float /* frs2 */);
-!
- .inline vis_write_hi,12
- fmovs %f3,%f0 ! %f3 = float frs2; return %f0:f1;
- .end
-!
-! double vis_write_lo(double /* frs1 */, float /* frs2 */);
-!
- .inline vis_write_lo,12
- fmovs %f3,%f1 ! %f3 = float frs2; return %f0:f1;
- .end
-!
-! double vis_freg_pair(float /* frs1 */, float /* frs2 */);
-!
- .inline vis_freg_pair,8
- fmovs %f1,%f0 ! %f1 = float frs1; put in hi;
- fmovs %f3,%f1 ! %f3 = float frs2; put in lo; return %f0:f1;
- .end
-!
-! float vis_to_float(unsigned int /*value*/);
-!
- .inline vis_to_float,4
- st %o0,[%sp+2183]
- ld [%sp+2183],%f0
- .end
-!
-! double vis_to_double(unsigned int /*value1*/, unsigned int /*value2*/);
-!
- .inline vis_to_double,8
- st %o0,[%sp+2183]
- ld [%sp+2183],%f0
- st %o1,[%sp+2183]
- ld [%sp+2183],%f1
- .end
-!
-! double vis_to_double_dup(unsigned int /*value*/);
-!
- .inline vis_to_double_dup,4
- st %o0,[%sp+2183]
- ld [%sp+2183],%f1
- fmovs %f1,%f0 ! duplicate value
- .end
-!
-! double vis_ll_to_double(unsigned long long /*value*/);
-!
- .inline vis_ll_to_double,8
- stx %o0,[%sp+2183]
- ldd [%sp+2183],%f0
- .end
-
-!--------------------------------------------------------------------
-! Address space identifier (ASI) register
-!
-! unsigned int vis_read_asi(void)
-!
- .inline vis_read_asi,0
- rd %asi,%o0
- .end
-!
-! void vis_write_asi(unsigned int /* ASI */)
-!
- .inline vis_write_asi,4
- wr %g0,%o0,%asi
- .end
-
-!--------------------------------------------------------------------
-! Load/store from/into alternate space
-!
-! float vis_ldfa_ASI_REG(void *rs1)
-!
- .inline vis_ldfa_ASI_REG,8
- lda [%o0+0]%asi,%f4
- fmovs %f4,%f0 ! Compiler can clean this up
- .end
-!
-! float vis_ldfa_ASI_P(void *rs1)
-!
- .inline vis_ldfa_ASI_P,8
- lda [%o0]0x80,%f4 ! ASI_P
- fmovs %f4,%f0 ! Compiler can clean this up
- .end
-!
-! float vis_ldfa_ASI_PL(void *rs1)
-!
- .inline vis_ldfa_ASI_PL,8
- lda [%o0]0x88,%f4 ! ASI_PL
- fmovs %f4,%f0 ! Compiler can clean this up
- .end
-!
-! double vis_lddfa_ASI_REG(void *rs1)
-!
- .inline vis_lddfa_ASI_REG,8
- ldda [%o0+0]%asi,%f4
- fmovd %f4,%f0 ! Compiler can clean this up
- .end
-!
-! double vis_lddfa_ASI_P(void *rs1)
-!
- .inline vis_lddfa_ASI_P,8
- ldda [%o0]0x80,%f4 ! ASI_P
- fmovd %f4,%f0 ! Compiler can clean this up
- .end
-!
-! double vis_lddfa_ASI_PL(void *rs1)
-!
- .inline vis_lddfa_ASI_PL,8
- ldda [%o0]0x88,%f4 ! ASI_PL
- fmovd %f4,%f0 ! Compiler can clean this up
- .end
-!
-! vis_stfa_ASI_REG(float frs, void *rs1)
-!
- .inline vis_stfa_ASI_REG,12
- sta %f1,[%o1+0]%asi
- .end
-!
-! vis_stfa_ASI_P(float frs, void *rs1)
-!
- .inline vis_stfa_ASI_P,12
- sta %f1,[%o1]0x80 ! ASI_P
- .end
-!
-! vis_stfa_ASI_PL(float frs, void *rs1)
-!
- .inline vis_stfa_ASI_PL,12
- sta %f1,[%o1]0x88 ! ASI_PL
- .end
-!
-! vis_stdfa_ASI_REG(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_REG,16
- stda %f0,[%o1+0]%asi
- .end
-!
-! vis_stdfa_ASI_P(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_P,16
- stda %f0,[%o1]0x80 ! ASI_P
- .end
-!
-! vis_stdfa_ASI_PL(double frd, void *rs1)
-!
- .inline vis_stdfa_ASI_PL,16
- stda %f0,[%o1]0x88 ! ASI_PL
- .end
-!
-! unsigned short vis_lduha_ASI_REG(void *rs1)
-!
- .inline vis_lduha_ASI_REG,8
- lduha [%o0+0]%asi,%o0
- .end
-!
-! unsigned short vis_lduha_ASI_P(void *rs1)
-!
- .inline vis_lduha_ASI_P,8
- lduha [%o0]0x80,%o0 ! ASI_P
- .end
-!
-! unsigned short vis_lduha_ASI_PL(void *rs1)
-!
- .inline vis_lduha_ASI_PL,8
- lduha [%o0]0x88,%o0 ! ASI_PL
- .end
-!
-! unsigned short vis_lduha_ASI_P_index(void *rs1, long index)
-!
- .inline vis_lduha_ASI_P_index,16
- lduha [%o0+%o1]0x80,%o0 ! ASI_P
- .end
-!
-! unsigned short vis_lduha_ASI_PL_index(void *rs1, long index)
-!
- .inline vis_lduha_ASI_PL_index,16
- lduha [%o0+%o1]0x88,%o0 ! ASI_PL
- .end
-
-!--------------------------------------------------------------------
-! Prefetch
-!
-! void vis_prefetch_read(void * /*address*/);
-!
- .inline vis_prefetch_read,8
- prefetch [%o0+0],0
- .end
-!
-! void vis_prefetch_write(void * /*address*/);
-!
- .inline vis_prefetch_write,8
- prefetch [%o0+0],2
- .end
diff --git a/security/nss/lib/freebl/mpi/vis_proto.h b/security/nss/lib/freebl/mpi/vis_proto.h
deleted file mode 100644
index 9e0954d0b..000000000
--- a/security/nss/lib/freebl/mpi/vis_proto.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/*
- * Prototypes for the inline templates in vis.il
- */
-
-#ifndef VIS_PROTO_H
-#define VIS_PROTO_H
-
-#pragma ident "@(#)vis_proto.h 1.3 97/03/30 SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* Pure edge handling instructions */
-int vis_edge8(void * /*frs1*/, void * /*frs2*/);
-int vis_edge8l(void * /*frs1*/, void * /*frs2*/);
-int vis_edge16(void * /*frs1*/, void * /*frs2*/);
-int vis_edge16l(void * /*frs1*/, void * /*frs2*/);
-int vis_edge32(void * /*frs1*/, void * /*frs2*/);
-int vis_edge32l(void * /*frs1*/, void * /*frs2*/);
-
-/* Edge handling instructions with negative return values if cc set. */
-int vis_edge8cc(void * /*frs1*/, void * /*frs2*/);
-int vis_edge8lcc(void * /*frs1*/, void * /*frs2*/);
-int vis_edge16cc(void * /*frs1*/, void * /*frs2*/);
-int vis_edge16lcc(void * /*frs1*/, void * /*frs2*/);
-int vis_edge32cc(void * /*frs1*/, void * /*frs2*/);
-int vis_edge32lcc(void * /*frs1*/, void * /*frs2*/);
-
-/* Alignment instructions. */
-void *vis_alignaddr(void * /*rs1*/, int /*rs2*/);
-void *vis_alignaddrl(void * /*rs1*/, int /*rs2*/);
-double vis_faligndata(double /*frs1*/, double /*frs2*/);
-
-/* Partitioned comparison instructions. */
-int vis_fcmple16(double /*frs1*/, double /*frs2*/);
-int vis_fcmpne16(double /*frs1*/, double /*frs2*/);
-int vis_fcmple32(double /*frs1*/, double /*frs2*/);
-int vis_fcmpne32(double /*frs1*/, double /*frs2*/);
-int vis_fcmpgt16(double /*frs1*/, double /*frs2*/);
-int vis_fcmpeq16(double /*frs1*/, double /*frs2*/);
-int vis_fcmpgt32(double /*frs1*/, double /*frs2*/);
-int vis_fcmpeq32(double /*frs1*/, double /*frs2*/);
-
-/* Partitioned multiplication. */
-#if 0
-double vis_fmul8x16(float /*frs1*/, double /*frs2*/);
-#endif
-double vis_fmul8x16_dummy(float /*frs1*/, int /*dummy*/, double /*frs2*/);
-double vis_fmul8x16au(float /*frs1*/, float /*frs2*/);
-double vis_fmul8x16al(float /*frs1*/, float /*frs2*/);
-double vis_fmul8sux16(double /*frs1*/, double /*frs2*/);
-double vis_fmul8ulx16(double /*frs1*/, double /*frs2*/);
-double vis_fmuld8ulx16(float /*frs1*/, float /*frs2*/);
-double vis_fmuld8sux16(float /*frs1*/, float /*frs2*/);
-
-/* Partitioned addition & subtraction. */
-double vis_fpadd16(double /*frs1*/, double /*frs2*/);
-float vis_fpadd16s(float /*frs1*/, float /*frs2*/);
-double vis_fpadd32(double /*frs1*/, double /*frs2*/);
-float vis_fpadd32s(float /*frs1*/, float /*frs2*/);
-double vis_fpsub16(double /*frs1*/, double /*frs2*/);
-float vis_fpsub16s(float /*frs1*/, float /*frs2*/);
-double vis_fpsub32(double /*frs1*/, double /*frs2*/);
-float vis_fpsub32s(float /*frs1*/, float /*frs2*/);
-
-/* Pixel packing & clamping. */
-float vis_fpack16(double /*frs2*/);
-double vis_fpack32(double /*frs1*/, double /*frs2*/);
-float vis_fpackfix(double /*frs2*/);
-
-/* Combined pack ops. */
-double vis_fpack16_pair(double /*frs2*/, double /*frs2*/);
-double vis_fpackfix_pair(double /*frs2*/, double /*frs2*/);
-void vis_st2_fpack16(double, double, double *);
-void vis_std_fpack16(double, double, double *);
-void vis_st2_fpackfix(double, double, double *);
-
-double vis_fpack16_to_hi(double /*frs1*/, double /*frs2*/);
-double vis_fpack16_to_lo(double /*frs1*/, double /*frs2*/);
-
-/* Motion estimation. */
-double vis_pdist(double /*frs1*/, double /*frs2*/, double /*frd*/);
-
-/* Channel merging. */
-double vis_fpmerge(float /*frs1*/, float /*frs2*/);
-
-/* Pixel expansion. */
-double vis_fexpand(float /*frs2*/);
-double vis_fexpand_hi(double /*frs2*/);
-double vis_fexpand_lo(double /*frs2*/);
-
-/* Bitwise logical operators. */
-double vis_fnor(double /*frs1*/, double /*frs2*/);
-float vis_fnors(float /*frs1*/, float /*frs2*/);
-double vis_fandnot(double /*frs1*/, double /*frs2*/);
-float vis_fandnots(float /*frs1*/, float /*frs2*/);
-double vis_fnot(double /*frs1*/);
-float vis_fnots(float /*frs1*/);
-double vis_fxor(double /*frs1*/, double /*frs2*/);
-float vis_fxors(float /*frs1*/, float /*frs2*/);
-double vis_fnand(double /*frs1*/, double /*frs2*/);
-float vis_fnands(float /*frs1*/, float /*frs2*/);
-double vis_fand(double /*frs1*/, double /*frs2*/);
-float vis_fands(float /*frs1*/, float /*frs2*/);
-double vis_fxnor(double /*frs1*/, double /*frs2*/);
-float vis_fxnors(float /*frs1*/, float /*frs2*/);
-double vis_fsrc(double /*frs1*/);
-float vis_fsrcs(float /*frs1*/);
-double vis_fornot(double /*frs1*/, double /*frs2*/);
-float vis_fornots(float /*frs1*/, float /*frs2*/);
-double vis_for(double /*frs1*/, double /*frs2*/);
-float vis_fors(float /*frs1*/, float /*frs2*/);
-double vis_fzero(void);
-float vis_fzeros(void);
-double vis_fone(void);
-float vis_fones(void);
-
-/* Partial stores. */
-void vis_stdfa_ASI_PST8P(double /*frd*/, void * /*rs1*/, int /*rmask*/);
-void vis_stdfa_ASI_PST8PL(double /*frd*/, void * /*rs1*/, int /*rmask*/);
-void vis_stdfa_ASI_PST8P_int_pair(void * /*rs1*/, void * /*rs2*/,
- void * /*rs3*/, int /*rmask*/);
-void vis_stdfa_ASI_PST8S(double /*frd*/, void * /*rs1*/, int /*rmask*/);
-void vis_stdfa_ASI_PST16P(double /*frd*/, void * /*rs1*/, int /*rmask*/);
-void vis_stdfa_ASI_PST16S(double /*frd*/, void * /*rs1*/, int /*rmask*/);
-void vis_stdfa_ASI_PST32P(double /*frd*/, void * /*rs1*/, int /*rmask*/);
-void vis_stdfa_ASI_PST32S(double /*frd*/, void * /*rs1*/, int /*rmask*/);
-
-/* Byte & short stores. */
-void vis_stdfa_ASI_FL8P(double /*frd*/, void * /*rs1*/);
-void vis_stdfa_ASI_FL8P_index(double /*frd*/, void * /*rs1*/, long /*index*/);
-void vis_stdfa_ASI_FL8S(double /*frd*/, void * /*rs1*/);
-void vis_stdfa_ASI_FL16P(double /*frd*/, void * /*rs1*/);
-void vis_stdfa_ASI_FL16P_index(double /*frd*/, void * /*rs1*/, long /*index*/);
-void vis_stdfa_ASI_FL16S(double /*frd*/, void * /*rs1*/);
-void vis_stdfa_ASI_FL8PL(double /*frd*/, void * /*rs1*/);
-void vis_stdfa_ASI_FL8SL(double /*frd*/, void * /*rs1*/);
-void vis_stdfa_ASI_FL16PL(double /*frd*/, void * /*rs1*/);
-void vis_stdfa_ASI_FL16SL(double /*frd*/, void * /*rs1*/);
-
-/* Byte & short loads. */
-double vis_lddfa_ASI_FL8P(void * /*rs1*/);
-double vis_lddfa_ASI_FL8P_index(void * /*rs1*/, long /*index*/);
-double vis_lddfa_ASI_FL8P_hi(void * /*rs1*/, unsigned int /*index*/);
-double vis_lddfa_ASI_FL8P_lo(void * /*rs1*/, unsigned int /*index*/);
-double vis_lddfa_ASI_FL8S(void * /*rs1*/);
-double vis_lddfa_ASI_FL16P(void * /*rs1*/);
-double vis_lddfa_ASI_FL16P_index(void * /*rs1*/, long /*index*/);
-double vis_lddfa_ASI_FL16S(void * /*rs1*/);
-double vis_lddfa_ASI_FL8PL(void * /*rs1*/);
-double vis_lddfa_ASI_FL8SL(void * /*rs1*/);
-double vis_lddfa_ASI_FL16PL(void * /*rs1*/);
-double vis_lddfa_ASI_FL16SL(void * /*rs1*/);
-
-/* Direct write to GSR, read from GSR */
-void vis_write_gsr(unsigned int /*GSR*/);
-unsigned int vis_read_gsr(void);
-
-/* Voxel texture mapping. */
-#if !defined(_NO_LONGLONG)
-unsigned long vis_array8(unsigned long long /*rs1*/, int /*rs2*/);
-unsigned long vis_array16(unsigned long long /*rs1*/, int /*rs2*/);
-unsigned long vis_array32(unsigned long long /*rs1*/, int /*rs2*/);
-#endif /* !defined(_NO_LONGLONG) */
-
-/* Register aliasing and type casts. */
-float vis_read_hi(double /*frs1*/);
-float vis_read_lo(double /*frs1*/);
-double vis_write_hi(double /*frs1*/, float /*frs2*/);
-double vis_write_lo(double /*frs1*/, float /*frs2*/);
-double vis_freg_pair(float /*frs1*/, float /*frs2*/);
-float vis_to_float(unsigned int /*value*/);
-double vis_to_double(unsigned int /*value1*/, unsigned int /*value2*/);
-double vis_to_double_dup(unsigned int /*value*/);
-#if !defined(_NO_LONGLONG)
-double vis_ll_to_double(unsigned long long /*value*/);
-#endif /* !defined(_NO_LONGLONG) */
-
-/* Miscellany (no inlines) */
-void vis_error(char * /*fmt*/, int /*a0*/);
-void vis_sim_init(void);
-
-/* For better performance */
-#define vis_fmul8x16(farg,darg) vis_fmul8x16_dummy((farg),0,(darg))
-
-/* Nicknames for explicit ASI loads and stores. */
-#define vis_st_u8 vis_stdfa_ASI_FL8P
-#define vis_st_u8_i vis_stdfa_ASI_FL8P_index
-#define vis_st_u8_le vis_stdfa_ASI_FL8PL
-#define vis_st_u16 vis_stdfa_ASI_FL16P
-#define vis_st_u16_i vis_stdfa_ASI_FL16P_index
-#define vis_st_u16_le vis_stdfa_ASI_FL16PL
-
-#define vis_ld_u8 vis_lddfa_ASI_FL8P
-#define vis_ld_u8_i vis_lddfa_ASI_FL8P_index
-#define vis_ld_u8_le vis_lddfa_ASI_FL8PL
-#define vis_ld_u16 vis_lddfa_ASI_FL16P
-#define vis_ld_u16_i vis_lddfa_ASI_FL16P_index
-#define vis_ld_u16_le vis_lddfa_ASI_FL16PL
-
-#define vis_pst_8 vis_stdfa_ASI_PST8P
-#define vis_pst_16 vis_stdfa_ASI_PST16P
-#define vis_pst_32 vis_stdfa_ASI_PST32P
-
-#define vis_st_u8s vis_stdfa_ASI_FL8S
-#define vis_st_u8s_le vis_stdfa_ASI_FL8SL
-#define vis_st_u16s vis_stdfa_ASI_FL16S
-#define vis_st_u16s_le vis_stdfa_ASI_FL16SL
-
-#define vis_ld_u8s vis_lddfa_ASI_FL8S
-#define vis_ld_u8s_le vis_lddfa_ASI_FL8SL
-#define vis_ld_u16s vis_lddfa_ASI_FL16S
-#define vis_ld_u16s_le vis_lddfa_ASI_FL16SL
-
-#define vis_pst_8s vis_stdfa_ASI_PST8S
-#define vis_pst_16s vis_stdfa_ASI_PST16S
-#define vis_pst_32s vis_stdfa_ASI_PST32S
-
-/* "<" and ">=" may be implemented in terms of ">" and "<=". */
-#define vis_fcmplt16(a,b) vis_fcmpgt16((b),(a))
-#define vis_fcmplt32(a,b) vis_fcmpgt32((b),(a))
-#define vis_fcmpge16(a,b) vis_fcmple16((b),(a))
-#define vis_fcmpge32(a,b) vis_fcmple32((b),(a))
-
-#ifdef __cplusplus
-} // End of extern "C"
-#endif /* __cplusplus */
-
-#endif /* VIS_PROTO_H */
diff --git a/security/nss/lib/freebl/nsslowhash.c b/security/nss/lib/freebl/nsslowhash.c
deleted file mode 100644
index e2ca562c2..000000000
--- a/security/nss/lib/freebl/nsslowhash.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-#include "prtypes.h"
-#include "secerr.h"
-#include "pkcs11t.h"
-#include "blapi.h"
-#include "hasht.h"
-#include "plhash.h"
-#include "nsslowhash.h"
-
-/* FIPS preprocessor directives for message digests */
-#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
-
-/* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */
-static const PRUint8 known_hash_message[] = {
- "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
-
-static CK_RV
-freebl_fips_MD2_PowerUpSelfTest( void )
-{
- /* MD2 Known Digest Message (128-bits). */
- static const PRUint8 md2_known_digest[] = {
- 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
- 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
-
- /* MD2 variables. */
- MD2Context * md2_context;
- unsigned int md2_bytes_hashed;
- PRUint8 md2_computed_digest[MD2_LENGTH];
-
-
- /***********************************************/
- /* MD2 Single-Round Known Answer Hashing Test. */
- /***********************************************/
-
- md2_context = MD2_NewContext();
-
- if( md2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- MD2_Begin( md2_context );
-
- MD2_Update( md2_context, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
-
- MD2_DestroyContext( md2_context , PR_TRUE );
-
- if( ( md2_bytes_hashed != MD2_LENGTH ) ||
- ( PORT_Memcmp( md2_computed_digest, md2_known_digest,
- MD2_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-
-static CK_RV
-freebl_fips_MD5_PowerUpSelfTest( void )
-{
- /* MD5 Known Digest Message (128-bits). */
- static const PRUint8 md5_known_digest[] = {
- 0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28,
- 0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d};
-
- /* MD5 variables. */
- PRUint8 md5_computed_digest[MD5_LENGTH];
- SECStatus md5_status;
-
-
- /***********************************************/
- /* MD5 Single-Round Known Answer Hashing Test. */
- /***********************************************/
-
- md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( md5_status != SECSuccess ) ||
- ( PORT_Memcmp( md5_computed_digest, md5_known_digest,
- MD5_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-static CK_RV
-freebl_fips_SHA_PowerUpSelfTest( void )
-{
- /* SHA-1 Known Digest Message (160-bits). */
- static const PRUint8 sha1_known_digest[] = {
- 0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b,
- 0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0,
- 0xe0,0x68,0x47,0x7a};
-
- /* SHA-224 Known Digest Message (224-bits). */
- static const PRUint8 sha224_known_digest[] = {
- 0x89,0x5e,0x7f,0xfd,0x0e,0xd8,0x35,0x6f,
- 0x64,0x6d,0xf2,0xde,0x5e,0xed,0xa6,0x7f,
- 0x29,0xd1,0x12,0x73,0x42,0x84,0x95,0x4f,
- 0x8e,0x08,0xe5,0xcb};
-
- /* SHA-256 Known Digest Message (256-bits). */
- static const PRUint8 sha256_known_digest[] = {
- 0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61,
- 0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d,
- 0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9,
- 0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79};
-
- /* SHA-384 Known Digest Message (384-bits). */
- static const PRUint8 sha384_known_digest[] = {
- 0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3,
- 0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe,
- 0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8,
- 0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b,
- 0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3,
- 0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72};
-
- /* SHA-512 Known Digest Message (512-bits). */
- static const PRUint8 sha512_known_digest[] = {
- 0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf,
- 0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb,
- 0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99,
- 0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28,
- 0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12,
- 0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f,
- 0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a,
- 0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07};
-
- /* SHA-X variables. */
- PRUint8 sha_computed_digest[HASH_LENGTH_MAX];
- SECStatus sha_status;
-
- /*************************************************/
- /* SHA-1 Single-Round Known Answer Hashing Test. */
- /*************************************************/
-
- sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha1_known_digest,
- SHA1_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-224 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA224_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha224_known_digest,
- SHA224_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-256 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha256_known_digest,
- SHA256_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-384 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha384_known_digest,
- SHA384_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-512 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha512_known_digest,
- SHA512_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-freebl_fipsSoftwareIntegrityTest(void)
-{
- CK_RV crv = CKR_OK;
-
- /* make sure that our check file signatures are OK */
- if (!BLAPI_VerifySelf(SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX)) {
- crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
- }
- return crv;
-}
-
-CK_RV
-freebl_fipsPowerUpSelfTest( void )
-{
- CK_RV rv;
-
- /* MD2 Power-Up SelfTest(s). */
- rv = freebl_fips_MD2_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* MD5 Power-Up SelfTest(s). */
- rv = freebl_fips_MD5_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* SHA-X Power-Up SelfTest(s). */
- rv = freebl_fips_SHA_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* Software/Firmware Integrity Test. */
- rv = freebl_fipsSoftwareIntegrityTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* Passed Power-Up SelfTest(s). */
- return( CKR_OK );
-}
-
-struct NSSLOWInitContextStr {
- int count;
-};
-
-struct NSSLOWHASHContextStr {
- const SECHashObject *hashObj;
- void *hashCtxt;
-
-};
-
-static int nsslow_GetFIPSEnabled(void) {
-#ifdef LINUX
- FILE *f;
- char d;
- size_t size;
-
- f = fopen("/proc/sys/crypto/fips_enabled", "r");
- if (!f)
- return 0;
-
- size = fread(&d, 1, 1, f);
- fclose(f);
- if (size != 1)
- return 0;
- if (d != '1')
- return 0;
-#endif
- return 1;
-}
-
-
-static int post = 0;
-static int post_failed = 0;
-
-static NSSLOWInitContext dummyContext = { 0 };
-
-NSSLOWInitContext *
-NSSLOW_Init(void)
-{
- SECStatus rv;
- CK_RV crv;
-#ifdef FREEBL_NO_DEPEND
- PRBool nsprAvailable = PR_FALSE;
-
-
- rv = FREEBL_InitStubs();
- nsprAvailable = (rv == SECSuccess ) ? PR_TRUE : PR_FALSE;
-#endif
-
- if (post_failed) {
- return NULL;
- }
-
-
- if (!post && nsslow_GetFIPSEnabled()) {
- crv = freebl_fipsPowerUpSelfTest();
- if (crv != CKR_OK) {
- post_failed = 1;
- return NULL;
- }
- }
- post = 1;
-
-
- return &dummyContext;
-}
-
-void
-NSSLOW_Shutdown(NSSLOWInitContext *context)
-{
- PORT_Assert(context == &dummyContext);
- return;
-}
-
-void
-NSSLOW_Reset(NSSLOWInitContext *context)
-{
- PORT_Assert(context == &dummyContext);
- post_failed = 0;
- post = 0;
- return;
-}
-
-NSSLOWHASHContext *
-NSSLOWHASH_NewContext(NSSLOWInitContext *initContext,
- HASH_HashType hashType)
-{
- NSSLOWHASHContext *context;
-
- if (post_failed) {
- PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR);
- return NULL;
- }
-
- if (initContext != &dummyContext) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return (NULL);
- }
-
- context = PORT_ZNew(NSSLOWHASHContext);
- if (!context) {
- return NULL;
- }
- context->hashObj = HASH_GetRawHashObject(hashType);
- if (!context->hashObj) {
- PORT_Free(context);
- return NULL;
- }
- context->hashCtxt = context->hashObj->create();
- if (!context->hashCtxt) {
- PORT_Free(context);
- return NULL;
- }
-
- return context;
-}
-
-void
-NSSLOWHASH_Begin(NSSLOWHASHContext *context)
-{
- return context->hashObj->begin(context->hashCtxt);
-}
-
-void
-NSSLOWHASH_Update(NSSLOWHASHContext *context, const unsigned char *buf,
- unsigned int len)
-{
- return context->hashObj->update(context->hashCtxt, buf, len);
-}
-
-void
-NSSLOWHASH_End(NSSLOWHASHContext *context, unsigned char *buf,
- unsigned int *ret, unsigned int len)
-{
- return context->hashObj->end(context->hashCtxt, buf, ret, len);
-}
-
-void
-NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
-{
- context->hashObj->destroy(context->hashCtxt, PR_TRUE);
- PORT_Free(context);
-}
-
-unsigned int
-NSSLOWHASH_Length(NSSLOWHASHContext *context)
-{
- return context->hashObj->length;
-}
diff --git a/security/nss/lib/freebl/nsslowhash.h b/security/nss/lib/freebl/nsslowhash.h
deleted file mode 100644
index bbd537b5c..000000000
--- a/security/nss/lib/freebl/nsslowhash.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Provide FIPS validated hashing for applications that only need hashing.
- * NOTE: mac'ing requires keys and will not work in this interface.
- * Also NOTE: this only works with Hashing. Only the FIPS interface is enabled.
- */
-
-typedef struct NSSLOWInitContextStr NSSLOWInitContext;
-typedef struct NSSLOWHASHContextStr NSSLOWHASHContext;
-
-NSSLOWInitContext *NSSLOW_Init(void);
-void NSSLOW_Shutdown(NSSLOWInitContext *context);
-void NSSLOW_Reset(NSSLOWInitContext *context);
-NSSLOWHASHContext *NSSLOWHASH_NewContext(
- NSSLOWInitContext *initContext,
- HASH_HashType hashType);
-void NSSLOWHASH_Begin(NSSLOWHASHContext *context);
-void NSSLOWHASH_Update(NSSLOWHASHContext *context,
- const unsigned char *buf,
- unsigned int len);
-void NSSLOWHASH_End(NSSLOWHASHContext *context,
- unsigned char *buf,
- unsigned int *ret, unsigned int len);
-void NSSLOWHASH_Destroy(NSSLOWHASHContext *context);
-unsigned int NSSLOWHASH_Length(NSSLOWHASHContext *context);
diff --git a/security/nss/lib/freebl/os2_rand.c b/security/nss/lib/freebl/os2_rand.c
deleted file mode 100644
index bfe28cfc1..000000000
--- a/security/nss/lib/freebl/os2_rand.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#define INCL_DOS
-#define INCL_DOSERRORS
-#include <os2.h>
-#include "secrng.h"
-#include "prerror.h"
-#include <stdlib.h>
-#include <time.h>
-#include <stdio.h>
-#include <sys/stat.h>
-
-static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow)
-{
- APIRET rc = NO_ERROR;
- QWORD qword = {0,0};
-
- rc = DosTmrQueryTime(&qword);
- if (rc != NO_ERROR)
- return FALSE;
-
- *phigh = qword.ulHi;
- *plow = qword.ulLo;
-
- return TRUE;
-}
-
-size_t RNG_GetNoise(void *buf, size_t maxbuf)
-{
- unsigned long high = 0;
- unsigned long low = 0;
- clock_t val = 0;
- int n = 0;
- int nBytes = 0;
- time_t sTime;
-
- if (maxbuf <= 0)
- return 0;
-
- clockTickTime(&high, &low);
-
- /* get the maximally changing bits first */
- nBytes = sizeof(low) > maxbuf ? maxbuf : sizeof(low);
- memcpy(buf, &low, nBytes);
- n += nBytes;
- maxbuf -= nBytes;
-
- if (maxbuf <= 0)
- return n;
-
- nBytes = sizeof(high) > maxbuf ? maxbuf : sizeof(high);
- memcpy(((char *)buf) + n, &high, nBytes);
- n += nBytes;
- maxbuf -= nBytes;
-
- if (maxbuf <= 0)
- return n;
-
- /* get the number of milliseconds that have elapsed since application started */
- val = clock();
-
- nBytes = sizeof(val) > maxbuf ? maxbuf : sizeof(val);
- memcpy(((char *)buf) + n, &val, nBytes);
- n += nBytes;
- maxbuf -= nBytes;
-
- if (maxbuf <= 0)
- return n;
-
- /* get the time in seconds since midnight Jan 1, 1970 */
- time(&sTime);
- nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime);
- memcpy(((char *)buf) + n, &sTime, nBytes);
- n += nBytes;
-
- return n;
-}
-
-static BOOL
-EnumSystemFiles(void (*func)(const char *))
-{
- APIRET rc;
- ULONG sysInfo = 0;
- char bootLetter[2];
- char sysDir[_MAX_PATH] = "";
- char filename[_MAX_PATH];
- HDIR hdir = HDIR_CREATE;
- ULONG numFiles = 1;
- FILEFINDBUF3 fileBuf = {0};
- ULONG buflen = sizeof(FILEFINDBUF3);
-
- if (DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PVOID)&sysInfo,
- sizeof(ULONG)) == NO_ERROR)
- {
- bootLetter[0] = sysInfo + 'A' -1;
- bootLetter[1] = '\0';
- strcpy(sysDir, bootLetter);
- strcpy(sysDir+1, ":\\OS2\\");
-
- strcpy( filename, sysDir );
- strcat( filename, "*.*" );
- }
-
- rc =DosFindFirst( filename, &hdir, FILE_NORMAL, &fileBuf, buflen,
- &numFiles, FIL_STANDARD );
- if( rc == NO_ERROR )
- {
- do {
- // pass the full pathname to the callback
- sprintf( filename, "%s%s", sysDir, fileBuf.achName );
- (*func)(filename);
-
- numFiles = 1;
- rc = DosFindNext( hdir, &fileBuf, buflen, &numFiles );
- if( rc != NO_ERROR && rc != ERROR_NO_MORE_FILES )
- printf( "DosFindNext errod code = %d\n", rc );
- } while ( rc == NO_ERROR );
-
- rc = DosFindClose(hdir);
- if( rc != NO_ERROR )
- printf( "DosFindClose error code = %d", rc );
- }
- else
- printf( "DosFindFirst error code = %d", rc );
-
- return TRUE;
-}
-
-static int dwNumFiles, dwReadEvery, dwFileToRead=0;
-
-static void
-CountFiles(const char *file)
-{
- dwNumFiles++;
-}
-
-static void
-ReadFiles(const char *file)
-{
- if ((dwNumFiles % dwReadEvery) == 0)
- RNG_FileForRNG(file);
-
- dwNumFiles++;
-}
-
-static void
-ReadSingleFile(const char *filename)
-{
- unsigned char buffer[1024];
- FILE *file;
-
- file = fopen((char *)filename, "rb");
- if (file != NULL) {
- while (fread(buffer, 1, sizeof(buffer), file) > 0)
- ;
- fclose(file);
- }
-}
-
-static void
-ReadOneFile(const char *file)
-{
- if (dwNumFiles == dwFileToRead) {
- ReadSingleFile(file);
- }
-
- dwNumFiles++;
-}
-
-static void
-ReadSystemFiles(void)
-{
- // first count the number of files
- dwNumFiles = 0;
- if (!EnumSystemFiles(CountFiles))
- return;
-
- RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles));
-
- // now read 10 files
- if (dwNumFiles == 0)
- return;
-
- dwReadEvery = dwNumFiles / 10;
- if (dwReadEvery == 0)
- dwReadEvery = 1; // less than 10 files
-
- dwNumFiles = 0;
- EnumSystemFiles(ReadFiles);
-}
-
-void RNG_SystemInfoForRNG(void)
-{
- unsigned long *plong = 0;
- PTIB ptib;
- PPIB ppib;
- APIRET rc = NO_ERROR;
- DATETIME dt;
- COUNTRYCODE cc = {0};
- COUNTRYINFO ci = {0};
- unsigned long actual = 0;
- char path[_MAX_PATH]="";
- char fullpath[_MAX_PATH]="";
- unsigned long pathlength = sizeof(path);
- FSALLOCATE fsallocate;
- FILESTATUS3 fstatus;
- unsigned long defaultdrive = 0;
- unsigned long logicaldrives = 0;
- unsigned long sysInfo[QSV_MAX] = {0};
- char buffer[20];
- int nBytes = 0;
-
- nBytes = RNG_GetNoise(buffer, sizeof(buffer));
- RNG_RandomUpdate(buffer, nBytes);
-
- /* allocate memory and use address and memory */
- plong = (unsigned long *)malloc(sizeof(*plong));
- RNG_RandomUpdate(&plong, sizeof(plong));
- RNG_RandomUpdate(plong, sizeof(*plong));
- free(plong);
-
- /* process info */
- rc = DosGetInfoBlocks(&ptib, &ppib);
- if (rc == NO_ERROR)
- {
- RNG_RandomUpdate(ptib, sizeof(*ptib));
- RNG_RandomUpdate(ppib, sizeof(*ppib));
- }
-
- /* time */
- rc = DosGetDateTime(&dt);
- if (rc == NO_ERROR)
- {
- RNG_RandomUpdate(&dt, sizeof(dt));
- }
-
- /* country */
- rc = DosQueryCtryInfo(sizeof(ci), &cc, &ci, &actual);
- if (rc == NO_ERROR)
- {
- RNG_RandomUpdate(&cc, sizeof(cc));
- RNG_RandomUpdate(&ci, sizeof(ci));
- RNG_RandomUpdate(&actual, sizeof(actual));
- }
-
- /* current directory */
- rc = DosQueryCurrentDir(0, path, &pathlength);
- strcat(fullpath, "\\");
- strcat(fullpath, path);
- if (rc == NO_ERROR)
- {
- RNG_RandomUpdate(fullpath, strlen(fullpath));
- // path info
- rc = DosQueryPathInfo(fullpath, FIL_STANDARD, &fstatus, sizeof(fstatus));
- if (rc == NO_ERROR)
- {
- RNG_RandomUpdate(&fstatus, sizeof(fstatus));
- }
- }
-
- /* file system info */
- rc = DosQueryFSInfo(0, FSIL_ALLOC, &fsallocate, sizeof(fsallocate));
- if (rc == NO_ERROR)
- {
- RNG_RandomUpdate(&fsallocate, sizeof(fsallocate));
- }
-
- /* drive info */
- rc = DosQueryCurrentDisk(&defaultdrive, &logicaldrives);
- if (rc == NO_ERROR)
- {
- RNG_RandomUpdate(&defaultdrive, sizeof(defaultdrive));
- RNG_RandomUpdate(&logicaldrives, sizeof(logicaldrives));
- }
-
- /* system info */
- rc = DosQuerySysInfo(1L, QSV_MAX, (PVOID)&sysInfo, sizeof(ULONG)*QSV_MAX);
- if (rc == NO_ERROR)
- {
- RNG_RandomUpdate(&sysInfo, sizeof(sysInfo));
- }
-
- // now let's do some files
- ReadSystemFiles();
-
- /* more noise */
- nBytes = RNG_GetNoise(buffer, sizeof(buffer));
- RNG_RandomUpdate(buffer, nBytes);
-}
-
-void RNG_FileForRNG(const char *filename)
-{
- struct stat stat_buf;
- unsigned char buffer[1024];
- FILE *file = 0;
- int nBytes = 0;
- static int totalFileBytes = 0;
-
- if (stat((char *)filename, &stat_buf) < 0)
- return;
-
- RNG_RandomUpdate((unsigned char*)&stat_buf, sizeof(stat_buf));
-
- file = fopen((char *)filename, "r");
- if (file != NULL)
- {
- for (;;)
- {
- size_t bytes = fread(buffer, 1, sizeof(buffer), file);
-
- if (bytes == 0)
- break;
-
- RNG_RandomUpdate(buffer, bytes);
- totalFileBytes += bytes;
- if (totalFileBytes > 250000)
- break;
- }
- fclose(file);
- }
-
- nBytes = RNG_GetNoise(buffer, 20);
- RNG_RandomUpdate(buffer, nBytes);
-}
-
-static void rng_systemJitter(void)
-{
- dwNumFiles = 0;
- EnumSystemFiles(ReadOneFile);
- dwFileToRead++;
- if (dwFileToRead >= dwNumFiles) {
- dwFileToRead = 0;
- }
-}
-
-size_t RNG_SystemRNG(void *dest, size_t maxLen)
-{
- return rng_systemFromNoise(dest,maxLen);
-}
diff --git a/security/nss/lib/freebl/pqg.c b/security/nss/lib/freebl/pqg.c
deleted file mode 100644
index 586bec409..000000000
--- a/security/nss/lib/freebl/pqg.c
+++ /dev/null
@@ -1,1849 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * PQG parameter generation/verification. Based on FIPS 186-3.
- *
- * $Id$
- */
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prerr.h"
-#include "secerr.h"
-
-#include "prtypes.h"
-#include "blapi.h"
-#include "secitem.h"
-#include "mpi.h"
-#include "mpprime.h"
-#include "mplogic.h"
-#include "secmpi.h"
-
-#define MAX_ITERATIONS 1000 /* Maximum number of iterations of primegen */
-
-typedef enum {
- FIPS186_1_TYPE, /* Probablistic */
- FIPS186_3_TYPE, /* Probablistic */
- FIPS186_3_ST_TYPE /* Shawe-Taylor provable */
-} pqgGenType;
-
-/*
- * These test iterations are quite a bit larger than we previously had.
- * This is because FIPS 186-3 is worried about the primes in PQG generation.
- * It may be possible to purposefully construct composites which more
- * iterations of Miller-Rabin than the for your normal randomly selected
- * numbers.There are 3 ways to counter this: 1) use one of the cool provably
- * prime algorithms (which would require a lot more work than DSA-2 deservers.
- * 2) add a Lucas primality test (which requires coding a Lucas primality test,
- * or 3) use a larger M-R test count. I chose the latter. It increases the time
- * that it takes to prove the selected prime, but it shouldn't increase the
- * overall time to run the algorithm (non-primes should still faile M-R
- * realively quickly). If you want to get that last bit of performance,
- * implement Lucas and adjust these two functions. See FIPS 186-3 Appendix C
- * and F for more information.
- */
-int prime_testcount_p(int L, int N)
-{
- switch (L) {
- case 1024:
- return 40;
- case 2048:
- return 56;
- case 3072:
- return 64;
- default:
- break;
- }
- return 50; /* L = 512-960 */
-}
-
-/* The q numbers are different if you run M-R followd by Lucas. I created
- * a separate function so if someone wanted to add the Lucas check, they
- * could do so fairly easily */
-int prime_testcount_q(int L, int N)
-{
- return prime_testcount_p(L,N);
-}
-
-/*
- * generic function to make sure our input matches DSA2 requirements
- * this gives us one place to go if we need to bump the requirements in the
- * future.
- */
-static SECStatus
-pqg_validate_dsa2(unsigned int L, unsigned int N)
-{
-
- switch (L) {
- case 1024:
- if (N != DSA1_Q_BITS) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- break;
- case 2048:
- if ((N != 224) && (N != 256)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- break;
- case 3072:
- if (N != 256) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-static unsigned int
-pqg_get_default_N(unsigned int L)
-{
- unsigned int N = 0;
- switch (L) {
- case 1024:
- N = DSA1_Q_BITS;
- break;
- case 2048:
- N = 224;
- break;
- case 3072:
- N = 256;
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- break; /* N already set to zero */
- }
- return N;
-}
-
-/*
- * Select the lowest hash algorithm usable
- */
-static HASH_HashType
-getFirstHash(unsigned int L, unsigned int N)
-{
- if (N < 224) {
- return HASH_AlgSHA1;
- }
- if (N < 256) {
- return HASH_AlgSHA224;
- }
- if (N < 384) {
- return HASH_AlgSHA256;
- }
- if (N < 512) {
- return HASH_AlgSHA384;
- }
- return HASH_AlgSHA512;
-}
-
-/*
- * find the next usable hash algorthim
- */
-static HASH_HashType
-getNextHash(HASH_HashType hashtype)
-{
- switch (hashtype) {
- case HASH_AlgSHA1:
- hashtype = HASH_AlgSHA224;
- break;
- case HASH_AlgSHA224:
- hashtype = HASH_AlgSHA256;
- break;
- case HASH_AlgSHA256:
- hashtype = HASH_AlgSHA384;
- break;
- case HASH_AlgSHA384:
- hashtype = HASH_AlgSHA512;
- break;
- case HASH_AlgSHA512:
- default:
- hashtype = HASH_AlgTOTAL;
- break;
- }
- return hashtype;
-}
-
-static unsigned int
-HASH_ResultLen(HASH_HashType type)
-{
- const SECHashObject *hash_obj = HASH_GetRawHashObject(type);
- if (hash_obj == NULL) {
- return 0;
- }
- return hash_obj->length;
-}
-
-static SECStatus
-HASH_HashBuf(HASH_HashType type, unsigned char *dest,
- const unsigned char *src, PRUint32 src_len)
-{
- const SECHashObject *hash_obj = HASH_GetRawHashObject(type);
- void *hashcx = NULL;
- unsigned int dummy;
-
- if (hash_obj == NULL) {
- return SECFailure;
- }
-
- hashcx = hash_obj->create();
- if (hashcx == NULL) {
- return SECFailure;
- }
- hash_obj->begin(hashcx);
- hash_obj->update(hashcx,src,src_len);
- hash_obj->end(hashcx,dest, &dummy, hash_obj->length);
- hash_obj->destroy(hashcx, PR_TRUE);
- return SECSuccess;
-}
-
-unsigned int
-PQG_GetLength(const SECItem *obj)
-{
- unsigned int len = obj->len;
-
- if (obj->data == NULL) {
- return 0;
- }
- if (len > 1 && obj->data[0] == 0) {
- len--;
- }
- return len;
-}
-
-SECStatus
-PQG_Check(const PQGParams *params)
-{
- unsigned int L,N;
- SECStatus rv = SECSuccess;
-
- if (params == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- L = PQG_GetLength(&params->prime)*BITS_PER_BYTE;
- N = PQG_GetLength(&params->subPrime)*BITS_PER_BYTE;
-
- if (L < 1024) {
- int j;
-
- /* handle DSA1 pqg parameters with less thatn 1024 bits*/
- if ( N != DSA1_Q_BITS ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- j = PQG_PBITS_TO_INDEX(L);
- if ( j < 0 ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
- } else {
- /* handle DSA2 parameters (includes DSA1, 1024 bits) */
- rv = pqg_validate_dsa2(L, N);
- }
- return rv;
-}
-
-HASH_HashType
-PQG_GetHashType(const PQGParams *params)
-{
- unsigned int L,N;
-
- if (params == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return HASH_AlgNULL;
- }
-
- L = PQG_GetLength(&params->prime)*BITS_PER_BYTE;
- N = PQG_GetLength(&params->subPrime)*BITS_PER_BYTE;
- return getFirstHash(L, N);
-}
-
-/* Get a seed for generating P and Q. If in testing mode, copy in the
-** seed from FIPS 186-1 appendix 5. Otherwise, obtain bytes from the
-** global random number generator.
-*/
-static SECStatus
-getPQseed(SECItem *seed, PRArenaPool* arena)
-{
- SECStatus rv;
-
- if (!seed->data) {
- seed->data = (unsigned char*)PORT_ArenaZAlloc(arena, seed->len);
- }
- if (!seed->data) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- rv = RNG_GenerateGlobalRandomBytes(seed->data, seed->len);
- /*
- * NIST CMVP disallows a sequence of 20 bytes with the most
- * significant byte equal to 0. Perhaps they interpret
- * "a sequence of at least 160 bits" as "a number >= 2^159".
- * So we always set the most significant bit to 1. (bug 334533)
- */
- seed->data[0] |= 0x80;
- return rv;
-}
-
-/* Generate a candidate h value. If in testing mode, use the h value
-** specified in FIPS 186-1 appendix 5, h = 2. Otherwise, obtain bytes
-** from the global random number generator.
-*/
-static SECStatus
-generate_h_candidate(SECItem *hit, mp_int *H)
-{
- SECStatus rv = SECSuccess;
- mp_err err = MP_OKAY;
-#ifdef FIPS_186_1_A5_TEST
- memset(hit->data, 0, hit->len);
- hit->data[hit->len-1] = 0x02;
-#else
- rv = RNG_GenerateGlobalRandomBytes(hit->data, hit->len);
-#endif
- if (rv)
- return SECFailure;
- err = mp_read_unsigned_octets(H, hit->data, hit->len);
- if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-static SECStatus
-addToSeed(const SECItem * seed,
- unsigned long addend,
- int seedlen, /* g in 186-1 */
- SECItem * seedout)
-{
- mp_int s, sum, modulus, tmp;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- MP_DIGITS(&s) = 0;
- MP_DIGITS(&sum) = 0;
- MP_DIGITS(&modulus) = 0;
- MP_DIGITS(&tmp) = 0;
- CHECK_MPI_OK( mp_init(&s) );
- CHECK_MPI_OK( mp_init(&sum) );
- CHECK_MPI_OK( mp_init(&modulus) );
- SECITEM_TO_MPINT(*seed, &s); /* s = seed */
- /* seed += addend */
- if (addend < MP_DIGIT_MAX) {
- CHECK_MPI_OK( mp_add_d(&s, (mp_digit)addend, &s) );
- } else {
- CHECK_MPI_OK( mp_init(&tmp) );
- CHECK_MPI_OK( mp_set_ulong(&tmp, addend) );
- CHECK_MPI_OK( mp_add(&s, &tmp, &s) );
- }
- /*sum = s mod 2**seedlen */
- CHECK_MPI_OK( mp_div_2d(&s, (mp_digit)seedlen, NULL, &sum) );
- if (seedout->data != NULL) {
- SECITEM_ZfreeItem(seedout, PR_FALSE);
- }
- MPINT_TO_SECITEM(&sum, seedout, NULL);
-cleanup:
- mp_clear(&s);
- mp_clear(&sum);
- mp_clear(&modulus);
- mp_clear(&tmp);
- if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
- }
- return rv;
-}
-
-/* Compute Hash[(SEED + addend) mod 2**g]
-** Result is placed in shaOutBuf.
-** This computation is used in steps 2 and 7 of FIPS 186 Appendix 2.2 and
-** step 11.2 of FIPS 186-3 Appendix A.1.1.2 .
-*/
-static SECStatus
-addToSeedThenHash(HASH_HashType hashtype,
- const SECItem * seed,
- unsigned long addend,
- int seedlen, /* g in 186-1 */
- unsigned char * hashOutBuf)
-{
- SECItem str = { 0, 0, 0 };
- SECStatus rv;
- rv = addToSeed(seed, addend, seedlen, &str);
- if (rv != SECSuccess) {
- return rv;
- }
- rv = HASH_HashBuf(hashtype, hashOutBuf, str.data, str.len);/* hash result */
- if (str.data)
- SECITEM_ZfreeItem(&str, PR_FALSE);
- return rv;
-}
-
-/*
-** Perform steps 2 and 3 of FIPS 186-1, appendix 2.2.
-** Generate Q from seed.
-*/
-static SECStatus
-makeQfromSeed(
- unsigned int g, /* input. Length of seed in bits. */
-const SECItem * seed, /* input. */
- mp_int * Q) /* output. */
-{
- unsigned char sha1[SHA1_LENGTH];
- unsigned char sha2[SHA1_LENGTH];
- unsigned char U[SHA1_LENGTH];
- SECStatus rv = SECSuccess;
- mp_err err = MP_OKAY;
- int i;
- /* ******************************************************************
- ** Step 2.
- ** "Compute U = SHA[SEED] XOR SHA[(SEED+1) mod 2**g]."
- **/
- CHECK_SEC_OK( SHA1_HashBuf(sha1, seed->data, seed->len) );
- CHECK_SEC_OK( addToSeedThenHash(HASH_AlgSHA1, seed, 1, g, sha2) );
- for (i=0; i<SHA1_LENGTH; ++i)
- U[i] = sha1[i] ^ sha2[i];
- /* ******************************************************************
- ** Step 3.
- ** "Form Q from U by setting the most signficant bit (the 2**159 bit)
- ** and the least signficant bit to 1. In terms of boolean operations,
- ** Q = U OR 2**159 OR 1. Note that 2**159 < Q < 2**160."
- */
- U[0] |= 0x80; /* U is MSB first */
- U[SHA1_LENGTH-1] |= 0x01;
- err = mp_read_unsigned_octets(Q, U, SHA1_LENGTH);
-cleanup:
- memset(U, 0, SHA1_LENGTH);
- memset(sha1, 0, SHA1_LENGTH);
- memset(sha2, 0, SHA1_LENGTH);
- if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
- }
- return rv;
-}
-
-/*
-** Perform steps 6 and 7 of FIPS 186-3, appendix A.1.1.2.
-** Generate Q from seed.
-*/
-static SECStatus
-makeQ2fromSeed(
- HASH_HashType hashtype, /* selected Hashing algorithm */
- unsigned int N, /* input. Length of q in bits. */
-const SECItem * seed, /* input. */
- mp_int * Q) /* output. */
-{
- unsigned char U[HASH_LENGTH_MAX];
- SECStatus rv = SECSuccess;
- mp_err err = MP_OKAY;
- int N_bytes = N/BITS_PER_BYTE; /* length of N in bytes rather than bits */
- int hashLen = HASH_ResultLen(hashtype);
- int offset = 0;
-
- /* ******************************************************************
- ** Step 6.
- ** "Compute U = hash[SEED] mod 2**N-1]."
- **/
- CHECK_SEC_OK( HASH_HashBuf(hashtype, U, seed->data, seed->len) );
- /* mod 2**N . Step 7 will explicitly set the top bit to 1, so no need
- * to handle mod 2**N-1 */
- if (hashLen > N_bytes) {
- offset = hashLen - N_bytes;
- }
- /* ******************************************************************
- ** Step 7.
- ** computed_q = 2**(N-1) + U + 1 - (U mod 2)
- **
- ** This is the same as:
- ** computed_q = 2**(N-1) | U | 1;
- */
- U[offset] |= 0x80; /* U is MSB first */
- U[hashLen-1] |= 0x01;
- err = mp_read_unsigned_octets(Q, &U[offset], N_bytes);
-cleanup:
- memset(U, 0, HASH_LENGTH_MAX);
- if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
- }
- return rv;
-}
-
-/*
-** Perform steps from FIPS 186-3, Appendix A.1.2.1 and Appendix C.6
-**
-** This generates a provable prime from two smaller prime. The resulting
-** prime p will have q0 as a multiple of p-1. q0 can be 1.
-**
-** This implments steps 4 thorough 22 of FIPS 186-3 A.1.2.1 and
-** steps 16 through 34 of FIPS 186-2 C.6
-*/
-#define MAX_ST_SEED_BITS HASH_LENGTH_MAX*BITS_PER_BYTE
-SECStatus
-makePrimefromPrimesShaweTaylor(
- HASH_HashType hashtype, /* selected Hashing algorithm */
- unsigned int length, /* input. Length of prime in bits. */
- mp_int * c0, /* seed prime */
- mp_int * q, /* sub prime, can be 1 */
- mp_int * prime, /* output. */
- SECItem * prime_seed, /* input/output. */
- int * prime_gen_counter) /* input/output. */
-{
- mp_int c;
- mp_int c0_2;
- mp_int t;
- mp_int a;
- mp_int z;
- mp_int two_length_minus_1;
- SECStatus rv = SECFailure;
- int hashlen = HASH_ResultLen(hashtype);
- int outlen = hashlen*BITS_PER_BYTE;
- int offset;
- unsigned char bit, mask;
- /* x needs to hold roundup(L/outlen)*outlen.
- * This can be no larger than L+outlen-1, So we set it's size to
- * our max L + max outlen and know we are safe */
- unsigned char x[DSA_MAX_P_BITS/8+HASH_LENGTH_MAX];
- mp_err err = MP_OKAY;
- int i;
- int iterations;
- int old_counter;
-
- MP_DIGITS(&c) = 0;
- MP_DIGITS(&c0_2) = 0;
- MP_DIGITS(&t) = 0;
- MP_DIGITS(&a) = 0;
- MP_DIGITS(&z) = 0;
- MP_DIGITS(&two_length_minus_1) = 0;
- CHECK_MPI_OK( mp_init(&c) );
- CHECK_MPI_OK( mp_init(&c0_2) );
- CHECK_MPI_OK( mp_init(&t) );
- CHECK_MPI_OK( mp_init(&a) );
- CHECK_MPI_OK( mp_init(&z) );
- CHECK_MPI_OK( mp_init(&two_length_minus_1) );
-
-
- /*
- ** There is a slight mapping of variable names depending on which
- ** FIPS 186 steps are being carried out. The mapping is as follows:
- ** variable A.1.2.1 C.6
- ** c0 p0 c0
- ** q q 1
- ** c p c
- ** c0_2 2*p0*q 2*c0
- ** length L length
- ** prime_seed pseed prime_seed
- ** prime_gen_counter pgen_counter prime_gen_counter
- **
- ** Also note: or iterations variable is actually iterations+1, since
- ** iterations+1 works better in C.
- */
-
- /* Step 4/16 iterations = ceiling(length/outlen)-1 */
- iterations = (length+outlen-1)/outlen; /* NOTE: iterations +1 */
- /* Step 5/17 old_counter = prime_gen_counter */
- old_counter = *prime_gen_counter;
- /*
- ** Comment: Generate a pseudorandom integer x in the interval
- ** [2**(lenght-1), 2**length].
- **
- ** Step 6/18 x = 0
- */
- PORT_Memset(x, 0, sizeof(x));
- /*
- ** Step 7/19 for i = 0 to iterations do
- ** x = x + (HASH(prime_seed + i) * 2^(i*outlen))
- */
- for (i=0; i < iterations; i++) {
- /* is bigger than prime_seed should get to */
- CHECK_SEC_OK( addToSeedThenHash(hashtype, prime_seed, i,
- MAX_ST_SEED_BITS,&x[(iterations - i - 1)*hashlen]));
- }
- /* Step 8/20 prime_seed = prime_seed + iterations + 1 */
- CHECK_SEC_OK(addToSeed(prime_seed, iterations, MAX_ST_SEED_BITS,
- prime_seed));
- /*
- ** Step 9/21 x = 2 ** (length-1) + x mod 2 ** (length-1)
- **
- ** This step mathematically sets the high bit and clears out
- ** all the other bits higher than length. 'x' is stored
- ** in the x array, MSB first. The above formula gives us an 'x'
- ** which is length bytes long and has the high bit set. We also know
- ** that length <= iterations*outlen since
- ** iterations=ceiling(length/outlen). First we find the offset in
- ** bytes into the array where the high bit is.
- */
- offset = (outlen*iterations - length)/BITS_PER_BYTE;
- /* now we want to set the 'high bit', since length may not be a
- * multiple of 8,*/
- bit = 1 << ((length-1) & 0x7); /* select the proper bit in the byte */
- /* we need to zero out the rest of the bits in the byte above */
- mask = (bit-1);
- /* now we set it */
- x[offset] = (mask & x[offset]) | bit;
- /*
- ** Comment: Generate a candidate prime c in the interval
- ** [2**(lenght-1), 2**length].
- **
- ** Step 10 t = ceiling(x/(2q(p0)))
- ** Step 22 t = ceiling(x/(2(c0)))
- */
- CHECK_MPI_OK( mp_read_unsigned_octets(&t, &x[offset],
- hashlen*iterations - offset ) ); /* t = x */
- CHECK_MPI_OK( mp_mul(c0, q, &c0_2) ); /* c0_2 is now c0*q */
- CHECK_MPI_OK( mp_add(&c0_2, &c0_2, &c0_2) ); /* c0_2 is now 2*q*c0 */
- CHECK_MPI_OK( mp_add(&t, &c0_2, &t) ); /* t = x+2*q*c0 */
- CHECK_MPI_OK( mp_sub_d(&t, (mp_digit) 1, &t) ); /* t = x+2*q*c0 -1 */
- /* t = floor((x+2qc0-1)/2qc0) = ceil(x/2qc0) */
- CHECK_MPI_OK( mp_div(&t, &c0_2, &t, NULL) );
- /*
- ** step 11: if (2tqp0 +1 > 2**length), then t = ceiling(2**(length-1)/2qp0)
- ** step 12: t = 2tqp0 +1.
- **
- ** step 23: if (2tc0 +1 > 2**length), then t = ceiling(2**(length-1)/2c0)
- ** step 24: t = 2tc0 +1.
- */
- CHECK_MPI_OK( mp_2expt(&two_length_minus_1, length-1) );
-step_23:
- CHECK_MPI_OK( mp_mul(&t, &c0_2, &c) ); /* c = t*2qc0 */
- CHECK_MPI_OK( mp_add_d(&c, (mp_digit)1, &c) ); /* c= 2tqc0 + 1*/
- if (mpl_significant_bits(&c) > length) { /* if c > 2**length */
- CHECK_MPI_OK( mp_sub_d(&c0_2, (mp_digit) 1, &t) ); /* t = 2qc0-1 */
- /* t = 2**(length-1) + 2qc0 -1 */
- CHECK_MPI_OK( mp_add(&two_length_minus_1,&t, &t) );
- /* t = floor((2**(length-1)+2qc0 -1)/2qco)
- * = ceil(2**(lenght-2)/2qc0) */
- CHECK_MPI_OK( mp_div(&t, &c0_2, &t, NULL) );
- CHECK_MPI_OK( mp_mul(&t, &c0_2, &c) );
- CHECK_MPI_OK( mp_add_d(&c, (mp_digit)1, &c) ); /* c= 2tqc0 + 1*/
- }
- /* Step 13/25 prime_gen_counter = prime_gen_counter + 1*/
- (*prime_gen_counter)++;
- /*
- ** Comment: Test the candidate prime c for primality; first pick an
- ** integer a between 2 and c-2.
- **
- ** Step 14/26 a=0
- */
- PORT_Memset(x, 0, sizeof(x)); /* use x for a */
- /*
- ** Step 15/27 for i = 0 to iterations do
- ** a = a + (HASH(prime_seed + i) * 2^(i*outlen))
- **
- ** NOTE: we reuse the x array for 'a' initially.
- */
- for (i=0; i < iterations; i++) {
- /* MAX_ST_SEED_BITS is bigger than prime_seed should get to */
- CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, i,
- MAX_ST_SEED_BITS,&x[(iterations - i - 1)*hashlen]));
- }
- /* Step 16/28 prime_seed = prime_seed + iterations + 1 */
- CHECK_SEC_OK(addToSeed(prime_seed, iterations, MAX_ST_SEED_BITS,
- prime_seed));
- /* Step 17/29 a = 2 + (a mod (c-3)). */
- CHECK_MPI_OK( mp_read_unsigned_octets(&a, x, iterations*hashlen) );
- CHECK_MPI_OK( mp_sub_d(&c, (mp_digit) 3, &z) ); /* z = c -3 */
- CHECK_MPI_OK( mp_mod(&a, &z, &a) ); /* a = a mod c -3 */
- CHECK_MPI_OK( mp_add_d(&a, (mp_digit) 2, &a) ); /* a = 2 + a mod c -3 */
- /*
- ** Step 18 z = a**(2tq) mod p.
- ** Step 30 z = a**(2t) mod c.
- */
- CHECK_MPI_OK( mp_mul(&t, q, &z) ); /* z = tq */
- CHECK_MPI_OK( mp_add(&z, &z, &z) ); /* z = 2tq */
- CHECK_MPI_OK( mp_exptmod(&a, &z, &c, &z) ); /* z = a**(2tq) mod c */
- /*
- ** Step 19 if (( 1 == GCD(z-1,p)) and ( 1 == z**p0 mod p )), then
- ** Step 31 if (( 1 == GCD(z-1,c)) and ( 1 == z**c0 mod c )), then
- */
- CHECK_MPI_OK( mp_sub_d(&z, (mp_digit) 1, &a) );
- CHECK_MPI_OK( mp_gcd(&a,&c,&a ));
- if (mp_cmp_d(&a, (mp_digit)1) == 0) {
- CHECK_MPI_OK( mp_exptmod(&z, c0, &c, &a) );
- if (mp_cmp_d(&a, (mp_digit)1) == 0) {
- /* Step 31.1 prime = c */
- CHECK_MPI_OK( mp_copy(&c, prime) );
- /*
- ** Step 31.2 return Success, prime, prime_seed,
- ** prime_gen_counter
- */
- rv = SECSuccess;
- goto cleanup;
- }
- }
- /*
- ** Step 20/32 If (prime_gen_counter > 4 * length + old_counter then
- ** return (FAILURE, 0, 0, 0).
- ** NOTE: the test is reversed, so we fall through on failure to the
- ** cleanup routine
- */
- if (*prime_gen_counter < (4*length + old_counter)) {
- /* Step 21/33 t = t + 1 */
- CHECK_MPI_OK( mp_add_d(&t, (mp_digit) 1, &t) );
- /* Step 22/34 Go to step 23/11 */
- goto step_23;
- }
-
- /* if (prime_gencont > (4*length + old_counter), fall through to failure */
- rv = SECFailure; /* really is already set, but paranoia is good */
-
-cleanup:
- mp_clear(&c);
- mp_clear(&c0_2);
- mp_clear(&t);
- mp_clear(&a);
- mp_clear(&z);
- mp_clear(&two_length_minus_1);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- if (rv == SECFailure) {
- mp_zero(prime);
- if (prime_seed->data) {
- SECITEM_FreeItem(prime_seed, PR_FALSE);
- }
- *prime_gen_counter = 0;
- }
- return rv;
-}
-
-/*
-** Perform steps from FIPS 186-3, Appendix C.6
-**
-** This generates a provable prime from a seed
-*/
-SECStatus
-makePrimefromSeedShaweTaylor(
- HASH_HashType hashtype, /* selected Hashing algorithm */
- unsigned int length, /* input. Length of prime in bits. */
-const SECItem * input_seed, /* input. */
- mp_int * prime, /* output. */
- SECItem * prime_seed, /* output. */
- int * prime_gen_counter) /* output. */
-{
- mp_int c;
- mp_int c0;
- mp_int one;
- SECStatus rv = SECFailure;
- int hashlen = HASH_ResultLen(hashtype);
- int outlen = hashlen*BITS_PER_BYTE;
- int offset;
- unsigned char bit, mask;
- unsigned char x[HASH_LENGTH_MAX*2];
- mp_digit dummy;
- mp_err err = MP_OKAY;
- int i;
-
- MP_DIGITS(&c) = 0;
- MP_DIGITS(&c0) = 0;
- MP_DIGITS(&one) = 0;
- CHECK_MPI_OK( mp_init(&c) );
- CHECK_MPI_OK( mp_init(&c0) );
- CHECK_MPI_OK( mp_init(&one) );
-
- /* Step 1. if length < 2 then return (FAILURE, 0, 0, 0) */
- if (length < 2) {
- rv = SECFailure;
- goto cleanup;
- }
- /* Step 2. if length >= 33 then goto step 14 */
- if (length >= 33) {
- mp_zero(&one);
- CHECK_MPI_OK( mp_add_d(&one, (mp_digit) 1, &one) );
-
- /* Step 14 (status, c0, prime_seed, prime_gen_counter) =
- ** (ST_Random_Prime((ceil(length/2)+1, input_seed)
- */
- rv = makePrimefromSeedShaweTaylor(hashtype, (length+1)/2+1,
- input_seed, &c0, prime_seed, prime_gen_counter);
- /* Step 15 if FAILURE is returned, return (FAILURE, 0, 0, 0). */
- if (rv != SECSuccess) {
- goto cleanup;
- }
- /* Steps 16-34 */
- rv = makePrimefromPrimesShaweTaylor(hashtype,length, &c0, &one,
- prime, prime_seed, prime_gen_counter);
- goto cleanup; /* we're done, one way or the other */
- }
- /* Step 3 prime_seed = input_seed */
- CHECK_SEC_OK(SECITEM_CopyItem(NULL, prime_seed, input_seed));
- /* Step 4 prime_gen_count = 0 */
- *prime_gen_counter = 0;
-
-step_5:
- /* Step 5 c = Hash(prime_seed) xor Hash(prime_seed+1). */
- CHECK_SEC_OK(HASH_HashBuf(hashtype, x, prime_seed->data, prime_seed->len) );
- CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, 1,
- MAX_ST_SEED_BITS, &x[hashlen]) );
- for (i=0; i < hashlen; i++) {
- x[i] = x[i] ^ x[i+hashlen];
- }
- /* Step 6 c = 2**length-1 + c mod 2**length-1 */
- /* This step mathematically sets the high bit and clears out
- ** all the other bits higher than length. Right now c is stored
- ** in the x array, MSB first. The above formula gives us a c which
- ** is length bytes long and has the high bit set. We also know that
- ** length < outlen since the smallest outlen is 160 bits and the largest
- ** length at this point is 32 bits. So first we find the offset in bytes
- ** into the array where the high bit is.
- */
- offset = (outlen - length)/BITS_PER_BYTE;
- /* now we want to set the 'high bit'. We have to calculate this since
- * length may not be a multiple of 8.*/
- bit = 1 << ((length-1) & 0x7); /* select the proper bit in the byte */
- /* we need to zero out the rest of the bits in the byte above */
- mask = (bit-1);
- /* now we set it */
- x[offset] = (mask & x[offset]) | bit;
- /* Step 7 c = c*floor(c/2) + 1 */
- /* set the low bit. much easier to find (the end of the array) */
- x[hashlen-1] |= 1;
- /* now that we've set our bits, we can create our candidate "c" */
- CHECK_MPI_OK( mp_read_unsigned_octets(&c, &x[offset], hashlen-offset) );
- /* Step 8 prime_gen_counter = prime_gen_counter + 1 */
- (*prime_gen_counter)++;
- /* Step 9 prime_seed = prime_seed + 2 */
- CHECK_SEC_OK(addToSeed(prime_seed, 2, MAX_ST_SEED_BITS, prime_seed));
- /* Step 10 Perform deterministic primality test on c. For example, since
- ** c is small, it's primality can be tested by trial division, See
- ** See Appendic C.7.
- **
- ** We in fact test with trial division. mpi has a built int trial divider
- ** that divides all divisors up to 2^16.
- */
- if (prime_tab[prime_tab_size-1] < 0xFFF1) {
- /* we aren't testing all the primes between 0 and 2^16, we really
- * can't use this construction. Just fail. */
- rv = SECFailure;
- goto cleanup;
- }
- dummy = prime_tab_size;
- err = mpp_divis_primes(&c, &dummy);
- /* Step 11 if c is prime then */
- if (err == MP_NO) {
- /* Step 11.1 prime = c */
- CHECK_MPI_OK( mp_copy(&c, prime) );
- /* Step 11.2 return SUCCESS prime, prime_seed, prime_gen_counter */
- err = MP_OKAY;
- rv = SECSuccess;
- goto cleanup;
- } else if (err != MP_YES) {
- goto cleanup; /* function failed, bail out */
- } else {
- /* reset mp_err */
- err = MP_OKAY;
- }
- /*
- ** Step 12 if (prime_gen_counter > (4*len))
- ** then return (FAILURE, 0, 0, 0))
- ** Step 13 goto step 5
- */
- if (*prime_gen_counter <= (4*length)) {
- goto step_5;
- }
- /* if (prime_gencont > 4*length), fall through to failure */
- rv = SECFailure; /* really is already set, but paranoia is good */
-
-cleanup:
- mp_clear(&c);
- mp_clear(&c0);
- mp_clear(&one);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- if (rv == SECFailure) {
- mp_zero(prime);
- if (prime_seed->data) {
- SECITEM_FreeItem(prime_seed, PR_FALSE);
- }
- *prime_gen_counter = 0;
- }
- return rv;
-}
-
-
-/*
- * Find a Q and algorithm from Seed.
- */
-static SECStatus
-findQfromSeed(
- unsigned int L, /* input. Length of p in bits. */
- unsigned int N, /* input. Length of q in bits. */
- unsigned int g, /* input. Length of seed in bits. */
-const SECItem * seed, /* input. */
- mp_int * Q, /* input. */
- mp_int * Q_, /* output. */
- int * qseed_len, /* output */
- HASH_HashType *hashtypePtr, /* output. Hash uses */
- pqgGenType *typePtr) /* output. Generation Type used */
-{
- HASH_HashType hashtype;
- SECItem firstseed = { 0, 0, 0 };
- SECItem qseed = { 0, 0, 0 };
- SECStatus rv;
-
- *qseed_len = 0; /* only set if FIPS186_3_ST_TYPE */
-
- /* handle legacy small DSA first can only be FIPS186_1_TYPE */
- if (L < 1024) {
- rv =makeQfromSeed(g,seed,Q_);
- if ((rv == SECSuccess) && (mp_cmp(Q,Q_) == 0)) {
- *hashtypePtr = HASH_AlgSHA1;
- *typePtr = FIPS186_1_TYPE;
- return SECSuccess;
- }
- return SECFailure;
- }
- /* 1024 could use FIPS186_1 or FIPS186_3 algorithms, we need to try
- * them both */
- if (L == 1024) {
- rv = makeQfromSeed(g,seed,Q_);
- if (rv == SECSuccess) {
- if (mp_cmp(Q,Q_) == 0) {
- *hashtypePtr = HASH_AlgSHA1;
- *typePtr = FIPS186_1_TYPE;
- return SECSuccess;
- }
- }
- /* fall through for FIPS186_3 types */
- }
- /* at this point we know we aren't using FIPS186_1, start trying FIPS186_3
- * with appropriate hash types */
- for (hashtype = getFirstHash(L,N); hashtype != HASH_AlgTOTAL;
- hashtype=getNextHash(hashtype)) {
- rv = makeQ2fromSeed(hashtype, N, seed, Q_);
- if (rv != SECSuccess) {
- continue;
- }
- if (mp_cmp(Q,Q_) == 0) {
- *hashtypePtr = hashtype;
- *typePtr = FIPS186_3_TYPE;
- return SECSuccess;
- }
- }
- /*
- * OK finally try FIPS186_3 Shawe-Taylor
- */
- firstseed = *seed;
- firstseed.len = seed->len/3;
- for (hashtype = getFirstHash(L,N); hashtype != HASH_AlgTOTAL;
- hashtype=getNextHash(hashtype)) {
- int count;
-
- rv = makePrimefromSeedShaweTaylor(hashtype, N, &firstseed, Q_,
- &qseed, &count);
- if (rv != SECSuccess) {
- continue;
- }
- if (mp_cmp(Q,Q_) == 0) {
- /* check qseed as well... */
- int offset = seed->len - qseed.len;
- if ((offset < 0) ||
- (PORT_Memcmp(&seed->data[offset],qseed.data,qseed.len) != 0)) {
- /* we found q, but the seeds don't match. This isn't an
- * accident, someone has been tweeking with the seeds, just
- * fail a this point. */
- SECITEM_FreeItem(&qseed,PR_FALSE);
- return SECFailure;
- }
- *qseed_len = qseed.len;
- *hashtypePtr = hashtype;
- *typePtr = FIPS186_3_ST_TYPE;
- SECITEM_FreeItem(&qseed, PR_FALSE);
- return SECSuccess;
- }
- SECITEM_FreeItem(&qseed, PR_FALSE);
- }
- /* no hash algorithms found which match seed to Q, fail */
- return SECFailure;
-}
-
-
-
-/*
-** Perform steps 7, 8 and 9 of FIPS 186, appendix 2.2.
-** which are the same as steps 11.1-11.5 of FIPS 186-2, App A.1.1.2
-** Generate P from Q, seed, L, and offset.
-*/
-static SECStatus
-makePfromQandSeed(
- HASH_HashType hashtype, /* selected Hashing algorithm */
- unsigned int L, /* Length of P in bits. Per FIPS 186. */
- unsigned int N, /* Length of Q in bits. Per FIPS 186. */
- unsigned int offset, /* Per FIPS 186, App 2.2. & 186-3 App A.1.1.2 */
- unsigned int seedlen, /* input. Length of seed in bits. (g in 186-1)*/
-const SECItem * seed, /* input. */
-const mp_int * Q, /* input. */
- mp_int * P) /* output. */
-{
- unsigned int j; /* Per FIPS 186-3 App. A.1.1.2 (k in 186-1)*/
- unsigned int n; /* Per FIPS 186, appendix 2.2. */
- mp_digit b; /* Per FIPS 186, appendix 2.2. */
- unsigned int outlen; /* Per FIPS 186-3 App. A.1.1.2 */
- unsigned int hashlen; /* outlen in bytes */
- unsigned char V_j[HASH_LENGTH_MAX];
- mp_int W, X, c, twoQ, V_n, tmp;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- /* Initialize bignums */
- MP_DIGITS(&W) = 0;
- MP_DIGITS(&X) = 0;
- MP_DIGITS(&c) = 0;
- MP_DIGITS(&twoQ) = 0;
- MP_DIGITS(&V_n) = 0;
- MP_DIGITS(&tmp) = 0;
- CHECK_MPI_OK( mp_init(&W) );
- CHECK_MPI_OK( mp_init(&X) );
- CHECK_MPI_OK( mp_init(&c) );
- CHECK_MPI_OK( mp_init(&twoQ) );
- CHECK_MPI_OK( mp_init(&tmp) );
- CHECK_MPI_OK( mp_init(&V_n) );
-
- hashlen = HASH_ResultLen(hashtype);
- outlen = hashlen*BITS_PER_BYTE;
-
- /* L - 1 = n*outlen + b */
- n = (L - 1) / outlen;
- b = (L - 1) % outlen;
-
- /* ******************************************************************
- ** Step 11.1 (Step 7 in 186-1)
- ** "for j = 0 ... n let
- ** V_j = SHA[(SEED + offset + j) mod 2**seedlen]."
- **
- ** Step 11.2 (Step 8 in 186-1)
- ** "W = V_0 + (V_1 * 2**outlen) + ... + (V_n-1 * 2**((n-1)*outlen))
- ** + ((V_n mod 2**b) * 2**(n*outlen))
- */
- for (j=0; j<n; ++j) { /* Do the first n terms of V_j */
- /* Do step 11.1 for iteration j.
- ** V_j = HASH[(seed + offset + j) mod 2**g]
- */
- CHECK_SEC_OK( addToSeedThenHash(hashtype,seed,offset+j, seedlen, V_j) );
- /* Do step 11.2 for iteration j.
- ** W += V_j * 2**(j*outlen)
- */
- OCTETS_TO_MPINT(V_j, &tmp, hashlen); /* get bignum V_j */
- CHECK_MPI_OK( mpl_lsh(&tmp, &tmp, j*outlen) );/* tmp=V_j << j*outlen */
- CHECK_MPI_OK( mp_add(&W, &tmp, &W) ); /* W += tmp */
- }
- /* Step 11.2, continued.
- ** [W += ((V_n mod 2**b) * 2**(n*outlen))]
- */
- CHECK_SEC_OK( addToSeedThenHash(hashtype, seed, offset + n, seedlen, V_j) );
- OCTETS_TO_MPINT(V_j, &V_n, hashlen); /* get bignum V_n */
- CHECK_MPI_OK( mp_div_2d(&V_n, b, NULL, &tmp) ); /* tmp = V_n mod 2**b */
- CHECK_MPI_OK( mpl_lsh(&tmp, &tmp, n*outlen) ); /* tmp = tmp << n*outlen */
- CHECK_MPI_OK( mp_add(&W, &tmp, &W) ); /* W += tmp */
- /* Step 11.3, (Step 8 in 186-1)
- ** "X = W + 2**(L-1).
- ** Note that 0 <= W < 2**(L-1) and hence 2**(L-1) <= X < 2**L."
- */
- CHECK_MPI_OK( mpl_set_bit(&X, (mp_size)(L-1), 1) ); /* X = 2**(L-1) */
- CHECK_MPI_OK( mp_add(&X, &W, &X) ); /* X += W */
- /*************************************************************
- ** Step 11.4. (Step 9 in 186-1)
- ** "c = X mod 2q"
- */
- CHECK_MPI_OK( mp_mul_2(Q, &twoQ) ); /* 2q */
- CHECK_MPI_OK( mp_mod(&X, &twoQ, &c) ); /* c = X mod 2q */
- /*************************************************************
- ** Step 11.5. (Step 9 in 186-1)
- ** "p = X - (c - 1).
- ** Note that p is congruent to 1 mod 2q."
- */
- CHECK_MPI_OK( mp_sub_d(&c, 1, &c) ); /* c -= 1 */
- CHECK_MPI_OK( mp_sub(&X, &c, P) ); /* P = X - c */
-cleanup:
- mp_clear(&W);
- mp_clear(&X);
- mp_clear(&c);
- mp_clear(&twoQ);
- mp_clear(&V_n);
- mp_clear(&tmp);
- if (err) {
- MP_TO_SEC_ERROR(err);
- return SECFailure;
- }
- return rv;
-}
-
-/*
-** Generate G from h, P, and Q.
-*/
-static SECStatus
-makeGfromH(const mp_int *P, /* input. */
- const mp_int *Q, /* input. */
- mp_int *H, /* input and output. */
- mp_int *G, /* output. */
- PRBool *passed)
-{
- mp_int exp, pm1;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- *passed = PR_FALSE;
- MP_DIGITS(&exp) = 0;
- MP_DIGITS(&pm1) = 0;
- CHECK_MPI_OK( mp_init(&exp) );
- CHECK_MPI_OK( mp_init(&pm1) );
- CHECK_MPI_OK( mp_sub_d(P, 1, &pm1) ); /* P - 1 */
- if ( mp_cmp(H, &pm1) >= 0) /* H >= P-1 */
- CHECK_MPI_OK( mp_sub(H, &pm1, H) ); /* H = H mod (P-1) */
- /* Let b = 2**n (smallest power of 2 greater than P).
- ** Since P-1 >= b/2, and H < b, quotient(H/(P-1)) = 0 or 1
- ** so the above operation safely computes H mod (P-1)
- */
- /* Check for H = to 0 or 1. Regen H if so. (Regen means return error). */
- if (mp_cmp_d(H, 1) <= 0) {
- rv = SECFailure;
- goto cleanup;
- }
- /* Compute G, according to the equation G = (H ** ((P-1)/Q)) mod P */
- CHECK_MPI_OK( mp_div(&pm1, Q, &exp, NULL) ); /* exp = (P-1)/Q */
- CHECK_MPI_OK( mp_exptmod(H, &exp, P, G) ); /* G = H ** exp mod P */
- /* Check for G == 0 or G == 1, return error if so. */
- if (mp_cmp_d(G, 1) <= 0) {
- rv = SECFailure;
- goto cleanup;
- }
- *passed = PR_TRUE;
-cleanup:
- mp_clear(&exp);
- mp_clear(&pm1);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/*
-** Generate G from seed, index, P, and Q.
-*/
-static SECStatus
-makeGfromIndex(HASH_HashType hashtype,
- const mp_int *P, /* input. */
- const mp_int *Q, /* input. */
- const SECItem *seed, /* input. */
- unsigned char index, /* input. */
- mp_int *G) /* input/output */
-{
- mp_int e, pm1, W;
- unsigned int count;
- unsigned char data[HASH_LENGTH_MAX];
- unsigned int len;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- const SECHashObject *hashobj;
- void *hashcx = NULL;
-
- MP_DIGITS(&e) = 0;
- MP_DIGITS(&pm1) = 0;
- MP_DIGITS(&W) = 0;
- CHECK_MPI_OK( mp_init(&e) );
- CHECK_MPI_OK( mp_init(&pm1) );
- CHECK_MPI_OK( mp_init(&W) );
-
- /* initialize our hash stuff */
- hashobj = HASH_GetRawHashObject(hashtype);
- if (hashobj == NULL) {
- /* shouldn't happen */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- goto cleanup;
- }
- hashcx = hashobj->create();
- if (hashcx == NULL) {
- rv = SECFailure;
- goto cleanup;
- }
-
- CHECK_MPI_OK( mp_sub_d(P, 1, &pm1) ); /* P - 1 */
- /* Step 3 e = (p-1)/q */
- CHECK_MPI_OK( mp_div(&pm1, Q, &e, NULL) ); /* e = (P-1)/Q */
- /* Steps 4, 5, and 6 */
- /* count is a 16 bit value in the spec. We actually represent count
- * as more than 16 bits so we can easily detect the 16 bit overflow */
-#define MAX_COUNT 0x10000
- for (count = 1; count < MAX_COUNT; count++) {
- /* step 7
- * U = domain_param_seed || "ggen" || index || count
- * step 8
- * W = HASH(U)
- */
- hashobj->begin(hashcx);
- hashobj->update(hashcx,seed->data,seed->len);
- hashobj->update(hashcx, (unsigned char *)"ggen", 4);
- hashobj->update(hashcx,&index, 1);
- data[0] = (count >> 8) & 0xff;
- data[1] = count & 0xff;
- hashobj->update(hashcx, data, 2);
- hashobj->end(hashcx, data, &len, sizeof(data));
- OCTETS_TO_MPINT(data, &W, len);
- /* step 9. g = W**e mod p */
- CHECK_MPI_OK( mp_exptmod(&W, &e, P, G) );
- /* step 10. if (g < 2) then goto step 5 */
- /* NOTE: this weird construct is to keep the flow according to the spec.
- * the continue puts us back to step 5 of the for loop */
- if (mp_cmp_d(G, 2) < 0) {
- continue;
- }
- break; /* step 11 follows step 10 if the test condition is false */
- }
- if (count >= MAX_COUNT) {
- rv = SECFailure; /* last part of step 6 */
- }
- /* step 11.
- * return valid G */
-cleanup:
- PORT_Memset(data, 0, sizeof(data));
- if (hashcx) {
- hashobj->destroy(hashcx, PR_TRUE);
- }
- mp_clear(&e);
- mp_clear(&pm1);
- mp_clear(&W);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/* This code uses labels and gotos, so that it can follow the numbered
-** steps in the algorithms from FIPS 186-3 appendix A.1.1.2 very closely,
-** and so that the correctness of this code can be easily verified.
-** So, please forgive the ugly c code.
-**/
-static SECStatus
-pqg_ParamGen(unsigned int L, unsigned int N, pqgGenType type,
- unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy)
-{
- unsigned int n; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
- unsigned int b; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
- unsigned int seedlen; /* Per FIPS 186-3 app A.1.1.2 (was 'g' 186-1)*/
- unsigned int counter; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
- unsigned int offset; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
- unsigned int outlen; /* Per FIPS 186-3, appendix A.1.1.2. */
- unsigned int maxCount;
- HASH_HashType hashtype;
- SECItem *seed; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
- PRArenaPool *arena = NULL;
- PQGParams *params = NULL;
- PQGVerify *verify = NULL;
- PRBool passed;
- SECItem hit = { 0, 0, 0 };
- SECItem firstseed = { 0, 0, 0 };
- SECItem qseed = { 0, 0, 0 };
- SECItem pseed = { 0, 0, 0 };
- mp_int P, Q, G, H, l, p0;
- mp_err err = MP_OKAY;
- SECStatus rv = SECFailure;
- int iterations = 0;
-
-
- /* Step 1. L and N already checked by caller*/
- /* Step 2. if (seedlen < N) return INVALID; */
- if (seedBytes < N/BITS_PER_BYTE || !pParams || !pVfy) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* Initialize an arena for the params. */
- arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
- if (!arena) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- params = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
- if (!params) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
- }
- params->arena = arena;
- /* Initialize an arena for the verify. */
- arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
- if (!arena) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_FreeArena(params->arena, PR_TRUE);
- return SECFailure;
- }
- verify = (PQGVerify *)PORT_ArenaZAlloc(arena, sizeof(PQGVerify));
- if (!verify) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_FreeArena(arena, PR_TRUE);
- PORT_FreeArena(params->arena, PR_TRUE);
- return SECFailure;
- }
- verify->arena = arena;
- seed = &verify->seed;
- arena = NULL;
- /* Initialize bignums */
- MP_DIGITS(&P) = 0;
- MP_DIGITS(&Q) = 0;
- MP_DIGITS(&G) = 0;
- MP_DIGITS(&H) = 0;
- MP_DIGITS(&l) = 0;
- MP_DIGITS(&p0) = 0;
- CHECK_MPI_OK( mp_init(&P) );
- CHECK_MPI_OK( mp_init(&Q) );
- CHECK_MPI_OK( mp_init(&G) );
- CHECK_MPI_OK( mp_init(&H) );
- CHECK_MPI_OK( mp_init(&l) );
- CHECK_MPI_OK( mp_init(&p0) );
-
- /* Select Hash and Compute lengths. */
- /* getFirstHash gives us the smallest acceptable hash for this key
- * strength */
- hashtype = getFirstHash(L,N);
- outlen = HASH_ResultLen(hashtype)*BITS_PER_BYTE;
-
- /* Step 3: n = Ceil(L/outlen)-1; (same as n = Floor((L-1)/outlen)) */
- n = (L - 1) / outlen;
- /* Step 4: b = L -1 - (n*outlen); (same as n = (L-1) mod outlen) */
- b = (L - 1) % outlen;
- seedlen = seedBytes * BITS_PER_BYTE; /* bits in seed */
-step_5:
- /* ******************************************************************
- ** Step 5. (Step 1 in 186-1)
- ** "Choose an abitrary sequence of at least N bits and call it SEED.
- ** Let g be the length of SEED in bits."
- */
- if (++iterations > MAX_ITERATIONS) { /* give up after a while */
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- goto cleanup;
- }
- seed->len = seedBytes;
- CHECK_SEC_OK( getPQseed(seed, verify->arena) );
- /* ******************************************************************
- ** Step 6. (Step 2 in 186-1)
- **
- ** "Compute U = SHA[SEED] XOR SHA[(SEED+1) mod 2**g]. (186-1)"
- ** "Compute U = HASH[SEED] 2**(N-1). (186-3)"
- **
- ** Step 7. (Step 3 in 186-1)
- ** "Form Q from U by setting the most signficant bit (the 2**159 bit)
- ** and the least signficant bit to 1. In terms of boolean operations,
- ** Q = U OR 2**159 OR 1. Note that 2**159 < Q < 2**160. (186-1)"
- **
- ** "q = 2**(N-1) + U + 1 - (U mod 2) (186-3)
- **
- ** Note: Both formulations are the same for U < 2**(N-1) and N=160
- **
- ** If using Shawe-Taylor, We do the entire A.1.2.1.2 setps in the block
- ** FIPS186_3_ST_TYPE.
- */
- if (type == FIPS186_1_TYPE) {
- CHECK_SEC_OK( makeQfromSeed(seedlen, seed, &Q) );
- } else if (type == FIPS186_3_TYPE) {
- CHECK_SEC_OK( makeQ2fromSeed(hashtype, N, seed, &Q) );
- } else {
- /* FIPS186_3_ST_TYPE */
- int qgen_counter, pgen_counter;
-
- /* Step 1 (L,N) already checked for acceptability */
-
- firstseed = *seed;
- qgen_counter = 0;
- /* Step 2. Use N and firstseed to generate random prime q
- * using Apendix C.6 */
- CHECK_SEC_OK( makePrimefromSeedShaweTaylor(hashtype, N, &firstseed, &Q,
- &qseed, &qgen_counter) );
- /* Step 3. Use floor(L/2+1) and qseed to generate random prime p0
- * using Appendix C.6 */
- pgen_counter = 0;
- CHECK_SEC_OK( makePrimefromSeedShaweTaylor(hashtype, (L+1)/2+1,
- &qseed, &p0, &pseed, &pgen_counter) );
- /* Steps 4-22 FIPS 186-3 appendix A.1.2.1.2 */
- CHECK_SEC_OK( makePrimefromPrimesShaweTaylor(hashtype, L,
- &p0, &Q, &P, &pseed, &pgen_counter) );
-
- /* combine all the seeds */
- seed->len = firstseed.len +qseed.len + pseed.len;
- seed->data = PORT_ArenaZAlloc(verify->arena, seed->len);
- if (seed->data == NULL) {
- goto cleanup;
- }
- PORT_Memcpy(seed->data, firstseed.data, firstseed.len);
- PORT_Memcpy(seed->data+firstseed.len, pseed.data, pseed.len);
- PORT_Memcpy(seed->data+firstseed.len+pseed.len, qseed.data, qseed.len);
- counter = 0 ; /* (qgen_counter << 16) | pgen_counter; */
-
- /* we've generated both P and Q now, skip to generating G */
- goto generate_G;
- }
- /* ******************************************************************
- ** Step 8. (Step 4 in 186-1)
- ** "Use a robust primality testing algorithm to test whether q is prime."
- **
- ** Appendix 2.1 states that a Rabin test with at least 50 iterations
- ** "will give an acceptable probability of error."
- */
- /*CHECK_SEC_OK( prm_RabinTest(&Q, &passed) );*/
- err = mpp_pprime(&Q, prime_testcount_q(L,N));
- passed = (err == MP_YES) ? SECSuccess : SECFailure;
- /* ******************************************************************
- ** Step 9. (Step 5 in 186-1) "If q is not prime, goto step 5 (1 in 186-1)."
- */
- if (passed != SECSuccess)
- goto step_5;
- /* ******************************************************************
- ** Step 10.
- ** offset = 1;
- **( Step 6b 186-1)"Let counter = 0 and offset = 2."
- */
- offset = (type == FIPS186_1_TYPE) ? 2 : 1;
- /*
- ** Step 11. (Step 6a,13a,14 in 186-1)
- ** For counter - 0 to (4L-1) do
- **
- */
- maxCount = L >= 1024 ? (4*L - 1) : 4095;
- for (counter = 0; counter <= maxCount; counter++) {
- /* ******************************************************************
- ** Step 11.1 (Step 7 in 186-1)
- ** "for j = 0 ... n let
- ** V_j = HASH[(SEED + offset + j) mod 2**seedlen]."
- **
- ** Step 11.2 (Step 8 in 186-1)
- ** "W = V_0 + V_1*2**outlen+...+ V_n-1 * 2**((n-1)*outlen) +
- ** ((Vn* mod 2**b)*2**(n*outlen))"
- ** Step 11.3 (Step 8 in 186-1)
- ** "X = W + 2**(L-1)
- ** Note that 0 <= W < 2**(L-1) and hence 2**(L-1) <= X < 2**L."
- **
- ** Step 11.4 (Step 9 in 186-1).
- ** "c = X mod 2q"
- **
- ** Step 11.5 (Step 9 in 186-1).
- ** " p = X - (c - 1).
- ** Note that p is congruent to 1 mod 2q."
- */
- CHECK_SEC_OK( makePfromQandSeed(hashtype, L, N, offset, seedlen,
- seed, &Q, &P) );
- /*************************************************************
- ** Step 11.6. (Step 10 in 186-1)
- ** "if p < 2**(L-1), then goto step 11.9. (step 13 in 186-1)"
- */
- CHECK_MPI_OK( mpl_set_bit(&l, (mp_size)(L-1), 1) ); /* l = 2**(L-1) */
- if (mp_cmp(&P, &l) < 0)
- goto step_11_9;
- /************************************************************
- ** Step 11.7 (step 11 in 186-1)
- ** "Perform a robust primality test on p."
- */
- /*CHECK_SEC_OK( prm_RabinTest(&P, &passed) );*/
- err = mpp_pprime(&P, prime_testcount_p(L, N));
- passed = (err == MP_YES) ? SECSuccess : SECFailure;
- /* ******************************************************************
- ** Step 11.8. "If p is determined to be primed return VALID
- ** values of p, q, seed and counter."
- */
- if (passed == SECSuccess)
- break;
-step_11_9:
- /* ******************************************************************
- ** Step 11.9. "offset = offset + n + 1."
- */
- offset += n + 1;
- }
- /* ******************************************************************
- ** Step 12. "goto step 5."
- **
- ** NOTE: if counter <= maxCount, then we exited the loop at Step 11.8
- ** and now need to return p,q, seed, and counter.
- */
- if (counter > maxCount)
- goto step_5;
-
-generate_G:
- /* ******************************************************************
- ** returning p, q, seed and counter
- */
- if (type == FIPS186_1_TYPE) {
- /* Generate g, This is called the "Unverifiable Generation of g
- * in FIPA186-3 Appedix A.2.1. For compatibility we maintain
- * this version of the code */
- SECITEM_AllocItem(NULL, &hit, L/8); /* h is no longer than p */
- if (!hit.data) goto cleanup;
- do {
- /* loop generate h until 1<h<p-1 and (h**[(p-1)/q])mod p > 1 */
- CHECK_SEC_OK( generate_h_candidate(&hit, &H) );
- CHECK_SEC_OK( makeGfromH(&P, &Q, &H, &G, &passed) );
- } while (passed != PR_TRUE);
- MPINT_TO_SECITEM(&H, &verify->h, verify->arena);
- } else {
- unsigned char index = 1; /* default to 1 */
- verify->h.data = (unsigned char *)PORT_ArenaZAlloc(verify->arena, 1);
- if (verify->h.data == NULL) { goto cleanup; }
- verify->h.len = 1;
- verify->h.data[0] = index;
- /* Generate g, using the FIPS 186-3 Appendix A.23 */
- CHECK_SEC_OK(makeGfromIndex(hashtype, &P, &Q, seed, index, &G) );
- }
- /* All generation is done. Now, save the PQG params. */
- MPINT_TO_SECITEM(&P, &params->prime, params->arena);
- MPINT_TO_SECITEM(&Q, &params->subPrime, params->arena);
- MPINT_TO_SECITEM(&G, &params->base, params->arena);
- verify->counter = counter;
- *pParams = params;
- *pVfy = verify;
-cleanup:
- if (pseed.data) {
- PORT_Free(pseed.data);
- }
- if (qseed.data) {
- PORT_Free(qseed.data);
- }
- mp_clear(&P);
- mp_clear(&Q);
- mp_clear(&G);
- mp_clear(&H);
- mp_clear(&l);
- mp_clear(&p0);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- if (rv) {
- PORT_FreeArena(params->arena, PR_TRUE);
- PORT_FreeArena(verify->arena, PR_TRUE);
- }
- if (hit.data) {
- SECITEM_FreeItem(&hit, PR_FALSE);
- }
- return rv;
-}
-
-SECStatus
-PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy)
-{
- unsigned int L; /* Length of P in bits. Per FIPS 186. */
- unsigned int seedBytes;
-
- if (j > 8 || !pParams || !pVfy) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- L = 512 + (j * 64); /* bits in P */
- seedBytes = L/8;
- return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes,
- pParams, pVfy);
-}
-
-SECStatus
-PQG_ParamGenSeedLen(unsigned int j, unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy)
-{
- unsigned int L; /* Length of P in bits. Per FIPS 186. */
-
- if (j > 8 || !pParams || !pVfy) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- L = 512 + (j * 64); /* bits in P */
- return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes,
- pParams, pVfy);
-}
-
-SECStatus
-PQG_ParamGenV2(unsigned int L, unsigned int N, unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy)
-{
- if (N == 0) {
- N = pqg_get_default_N(L);
- }
- if (seedBytes == 0) {
- /* seedBytes == L/8 for probable primes, N/8 for Shawe-Taylor Primes */
- seedBytes = N/8;
- }
- if (pqg_validate_dsa2(L,N) != SECSuccess) {
- /* error code already set */
- return SECFailure;
- }
- return pqg_ParamGen(L, N, FIPS186_3_ST_TYPE, seedBytes, pParams, pVfy);
-}
-
-
-/*
- * verify can use vfy structures returned from either FIPS186-1 or
- * FIPS186-2, and can handle differences in selected Hash functions to
- * generate the parameters.
- */
-SECStatus
-PQG_VerifyParams(const PQGParams *params,
- const PQGVerify *vfy, SECStatus *result)
-{
- SECStatus rv = SECSuccess;
- unsigned int g, n, L, N, offset, outlen;
- mp_int p0, P, Q, G, P_, Q_, G_, r, h;
- mp_err err = MP_OKAY;
- int j;
- unsigned int counter_max = 0; /* handle legacy L < 1024 */
- int qseed_len;
- SECItem pseed_ = {0, 0, 0};
- HASH_HashType hashtype;
- pqgGenType type;
-
-#define CHECKPARAM(cond) \
- if (!(cond)) { \
- *result = SECFailure; \
- goto cleanup; \
- }
- if (!params || !vfy || !result) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* always need at least p, q, and seed for any meaningful check */
- if ((params->prime.len == 0) || (params->subPrime.len == 0) ||
- (vfy->seed.len == 0)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* we want to either check PQ or G or both. If we don't have G, make
- * sure we have count so we can check P. */
- if ((params->base.len == 0) && (vfy->counter == -1)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- MP_DIGITS(&p0) = 0;
- MP_DIGITS(&P) = 0;
- MP_DIGITS(&Q) = 0;
- MP_DIGITS(&G) = 0;
- MP_DIGITS(&P_) = 0;
- MP_DIGITS(&Q_) = 0;
- MP_DIGITS(&G_) = 0;
- MP_DIGITS(&r) = 0;
- MP_DIGITS(&h) = 0;
- CHECK_MPI_OK( mp_init(&p0) );
- CHECK_MPI_OK( mp_init(&P) );
- CHECK_MPI_OK( mp_init(&Q) );
- CHECK_MPI_OK( mp_init(&G) );
- CHECK_MPI_OK( mp_init(&P_) );
- CHECK_MPI_OK( mp_init(&Q_) );
- CHECK_MPI_OK( mp_init(&G_) );
- CHECK_MPI_OK( mp_init(&r) );
- CHECK_MPI_OK( mp_init(&h) );
- *result = SECSuccess;
- SECITEM_TO_MPINT(params->prime, &P);
- SECITEM_TO_MPINT(params->subPrime, &Q);
- /* if G isn't specified, just check P and Q */
- if (params->base.len != 0) {
- SECITEM_TO_MPINT(params->base, &G);
- }
- /* 1. Check (L,N) pair */
- N = mpl_significant_bits(&Q);
- L = mpl_significant_bits(&P);
- if (L < 1024) {
- /* handle DSA1 pqg parameters with less thatn 1024 bits*/
- CHECKPARAM( N == DSA1_Q_BITS );
- j = PQG_PBITS_TO_INDEX(L);
- CHECKPARAM( j >= 0 && j <= 8 );
- counter_max = 4096;
- } else {
- /* handle DSA2 parameters (includes DSA1, 1024 bits) */
- CHECKPARAM(pqg_validate_dsa2(L, N) == SECSuccess);
- counter_max = 4*L;
- }
- /* 3. G < P */
- if (params->base.len != 0) {
- CHECKPARAM( mp_cmp(&G, &P) < 0 );
- }
- /* 4. P % Q == 1 */
- CHECK_MPI_OK( mp_mod(&P, &Q, &r) );
- CHECKPARAM( mp_cmp_d(&r, 1) == 0 );
- /* 5. Q is prime */
- CHECKPARAM( mpp_pprime(&Q, prime_testcount_q(L,N)) == MP_YES );
- /* 6. P is prime */
- CHECKPARAM( mpp_pprime(&P, prime_testcount_p(L,N)) == MP_YES );
- /* Steps 7-12 are done only if the optional PQGVerify is supplied. */
- /* continue processing P */
- /* 7. counter < 4*L */
- CHECKPARAM( (vfy->counter == -1) || (vfy->counter < counter_max) );
- /* 8. g >= N and g < 2*L (g is length of seed in bits) */
- g = vfy->seed.len * 8;
- CHECKPARAM( g >= N && g < counter_max/2 );
- /* 9. Q generated from SEED matches Q in PQGParams. */
- /* This function checks all possible hash and generation types to
- * find a Q_ which matches Q. */
- CHECKPARAM( findQfromSeed(L, N, g, &vfy->seed, &Q, &Q_, &qseed_len,
- &hashtype, &type) == SECSuccess );
- CHECKPARAM( mp_cmp(&Q, &Q_) == 0 );
- if (type == FIPS186_3_ST_TYPE) {
- SECItem qseed = { 0, 0, 0 };
- SECItem pseed = { 0, 0, 0 };
- int first_seed_len;
- int pgen_counter = 0;
-
- /* extract pseed and qseed from domain_parameter_seed, which is
- * first_seed || pseed || qseed. qseed is first_seed + small_integer
- * pseed is qseed + small_integer. This means most of the time
- * first_seed.len == qseed.len == pseed.len. Rarely qseed.len and/or
- * pseed.len will be one greater than first_seed.len, so we can
- * depend on the fact that
- * first_seed.len = floor(domain_parameter_seed.len/3).
- * findQfromSeed returned qseed.len, so we can calculate pseed.len as
- * pseed.len = domain_parameter_seed.len - first_seed.len - qseed.len
- * this is probably over kill, since 99.999% of the time they will all
- * be equal.
- *
- * With the lengths, we can now find the offsets;
- * first_seed.data = domain_parameter_seed.data + 0
- * pseed.data = domain_parameter_seed.data + first_seed.len
- * qseed.data = domain_parameter_seed.data
- * + domain_paramter_seed.len - qseed.len
- *
- */
- first_seed_len = vfy->seed.len/3;
- CHECKPARAM(qseed_len < vfy->seed.len);
- CHECKPARAM(first_seed_len*8 > N-1);
- CHECKPARAM(first_seed_len+qseed_len < vfy->seed.len);
- qseed.len = qseed_len;
- qseed.data = vfy->seed.data + vfy->seed.len - qseed.len;
- pseed.len = vfy->seed.len - (first_seed_len+qseed_len);
- pseed.data = vfy->seed.data + first_seed_len;
-
- /*
- * now complete FIPS 186-3 A.1.2.1.2. Step 1 was completed
- * above in our initial checks, Step 2 was completed by
- * findQfromSeed */
-
- /* Step 3 (status, c0, prime_seed, prime_gen_counter) =
- ** (ST_Random_Prime((ceil(length/2)+1, input_seed)
- */
- CHECK_SEC_OK( makePrimefromSeedShaweTaylor(hashtype, (L+1)/2+1,
- &qseed, &p0, &pseed_, &pgen_counter) );
- /* Steps 4-22 FIPS 186-3 appendix A.1.2.1.2 */
- CHECK_SEC_OK( makePrimefromPrimesShaweTaylor(hashtype, L,
- &p0, &Q_, &P_, &pseed_, &pgen_counter) );
- CHECKPARAM( mp_cmp(&P, &P_) == 0 );
- /* make sure pseed wasn't tampered with (since it is part of
- * calculating G) */
- CHECKPARAM( SECITEM_CompareItem(&pseed, &pseed_) == SECEqual );
- } else if (vfy->counter == -1) {
- /* If counter is set to -1, we are really only verifying G, skip
- * the remainder of the checks for P */
- CHECKPARAM(type != FIPS186_1_TYPE); /* we only do this for DSA2 */
- } else {
- /* 10. P generated from (L, counter, g, SEED, Q) matches P
- * in PQGParams. */
- outlen = HASH_ResultLen(hashtype)*BITS_PER_BYTE;
- n = (L - 1) / outlen;
- offset = vfy->counter * (n + 1) + ((type == FIPS186_1_TYPE) ? 2 : 1);
- CHECK_SEC_OK( makePfromQandSeed(hashtype, L, N, offset, g, &vfy->seed,
- &Q, &P_) );
- CHECKPARAM( mp_cmp(&P, &P_) == 0 );
- }
-
- /* now check G, skip if don't have a g */
- if (params->base.len == 0) goto cleanup;
-
- /* first Always check that G is OK FIPS186-3 A.2.2 & A.2.4*/
- /* 1. 2 < G < P-1 */
- /* P is prime, p-1 == zero 1st bit */
- CHECK_MPI_OK( mpl_set_bit(&P, 0, 0) );
- CHECKPARAM( mp_cmp_d(&G, 2) > 0 && mp_cmp(&G, &P) < 0 );
- CHECK_MPI_OK( mpl_set_bit(&P, 0, 1) ); /* set it back */
- /* 2. verify g**q mod p == 1 */
- CHECK_MPI_OK( mp_exptmod(&G, &Q, &P, &h) ); /* h = G ** Q mod P */
- CHECKPARAM(mp_cmp_d(&h, 1) == 0);
-
- /* no h, the above is the best we can do */
- if (vfy->h.len == 0) {
- if (type != FIPS186_1_TYPE) {
- *result = SECWouldBlock;
- }
- goto cleanup;
- }
-
- /*
- * If h is one byte and FIPS186-3 was used to generate Q (we've verified
- * Q was generated from seed already, then we assume that FIPS 186-3
- * appendix A.2.3 was used to generate G. Otherwise we assume A.2.1 was
- * used to generate G.
- */
- if ((vfy->h.len == 1) && (type != FIPS186_1_TYPE)) {
- /* A.2.3 */
- CHECK_SEC_OK(makeGfromIndex(hashtype, &P, &Q, &vfy->seed,
- vfy->h.data[0], &G_) );
- CHECKPARAM( mp_cmp(&G, &G_) == 0 );
- } else {
- int passed;
- /* A.2.1 */
- SECITEM_TO_MPINT(vfy->h, &h);
- /* 11. 1 < h < P-1 */
- /* P is prime, p-1 == zero 1st bit */
- CHECK_MPI_OK( mpl_set_bit(&P, 0, 0) );
- CHECKPARAM( mp_cmp_d(&G, 2) > 0 && mp_cmp(&G, &P) );
- CHECK_MPI_OK( mpl_set_bit(&P, 0, 1) ); /* set it back */
- /* 12. G generated from h matches G in PQGParams. */
- CHECK_SEC_OK( makeGfromH(&P, &Q, &h, &G_, &passed) );
- CHECKPARAM( passed && mp_cmp(&G, &G_) == 0 );
- }
-cleanup:
- mp_clear(&p0);
- mp_clear(&P);
- mp_clear(&Q);
- mp_clear(&G);
- mp_clear(&P_);
- mp_clear(&Q_);
- mp_clear(&G_);
- mp_clear(&r);
- mp_clear(&h);
- if (pseed_.data) {
- SECITEM_FreeItem(&pseed_,PR_FALSE);
- }
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/**************************************************************************
- * Free the PQGParams struct and the things it points to. *
- **************************************************************************/
-void
-PQG_DestroyParams(PQGParams *params)
-{
- if (params == NULL)
- return;
- if (params->arena != NULL) {
- PORT_FreeArena(params->arena, PR_FALSE); /* don't zero it */
- } else {
- SECITEM_FreeItem(&params->prime, PR_FALSE); /* don't free prime */
- SECITEM_FreeItem(&params->subPrime, PR_FALSE); /* don't free subPrime */
- SECITEM_FreeItem(&params->base, PR_FALSE); /* don't free base */
- PORT_Free(params);
- }
-}
-
-/**************************************************************************
- * Free the PQGVerify struct and the things it points to. *
- **************************************************************************/
-
-void
-PQG_DestroyVerify(PQGVerify *vfy)
-{
- if (vfy == NULL)
- return;
- if (vfy->arena != NULL) {
- PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */
- } else {
- SECITEM_FreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
- SECITEM_FreeItem(&vfy->h, PR_FALSE); /* don't free h */
- PORT_Free(vfy);
- }
-}
diff --git a/security/nss/lib/freebl/pqg.h b/security/nss/lib/freebl/pqg.h
deleted file mode 100644
index 097f360c1..000000000
--- a/security/nss/lib/freebl/pqg.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * pqg.h
- *
- * header file for pqg functions exported just to freebl
- */
-
-#ifndef _PQG_H_
-#define _PQG_H_ 1
-
-/* PQG_GetLength returns the significant bytes in the SECItem object (that is
- * the length of the object minus any leading zeros. Any SECItem may be used,
- * though this function is usually used for P, Q, or G values */
-unsigned int PQG_GetLength(const SECItem *obj);
-/* Check to see the PQG parameters patch a NIST defined DSA size,
- * returns SECFaillure and sets SEC_ERROR_INVALID_ARGS if it doesn't.
- * See blapi.h for legal DSA PQG sizes. */
-SECStatus PQG_Check(const PQGParams *params);
-/* Return the prefered hash algorithm for the given PQGParameters. */
-HASH_HashType PQG_GetHashType(const PQGParams *params);
-
-#endif /* _PQG_H_ */
diff --git a/security/nss/lib/freebl/rawhash.c b/security/nss/lib/freebl/rawhash.c
deleted file mode 100644
index 7962b1fff..000000000
--- a/security/nss/lib/freebl/rawhash.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "nspr.h"
-#include "hasht.h"
-#include "blapi.h" /* below the line */
-#include "secerr.h"
-
-static void *
-null_hash_new_context(void)
-{
- return NULL;
-}
-
-static void *
-null_hash_clone_context(void *v)
-{
- PORT_Assert(v == NULL);
- return NULL;
-}
-
-static void
-null_hash_begin(void *v)
-{
-}
-
-static void
-null_hash_update(void *v, const unsigned char *input, unsigned int length)
-{
-}
-
-static void
-null_hash_end(void *v, unsigned char *output, unsigned int *outLen,
- unsigned int maxOut)
-{
- *outLen = 0;
-}
-
-static void
-null_hash_destroy_context(void *v, PRBool b)
-{
- PORT_Assert(v == NULL);
-}
-
-
-const SECHashObject SECRawHashObjects[] = {
- { 0,
- (void * (*)(void)) null_hash_new_context,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) null_hash_destroy_context,
- (void (*)(void *)) null_hash_begin,
- (void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) null_hash_end,
- 0,
- HASH_AlgNULL,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) null_hash_end
- },
- { MD2_LENGTH,
- (void * (*)(void)) MD2_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) MD2_DestroyContext,
- (void (*)(void *)) MD2_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) MD2_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD2_End,
- MD2_BLOCK_LENGTH,
- HASH_AlgMD2,
- NULL /* end_raw */
- },
- { MD5_LENGTH,
- (void * (*)(void)) MD5_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) MD5_DestroyContext,
- (void (*)(void *)) MD5_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) MD5_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD5_End,
- MD5_BLOCK_LENGTH,
- HASH_AlgMD5,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD5_EndRaw
- },
- { SHA1_LENGTH,
- (void * (*)(void)) SHA1_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) SHA1_DestroyContext,
- (void (*)(void *)) SHA1_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) SHA1_Update,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA1_End,
- SHA1_BLOCK_LENGTH,
- HASH_AlgSHA1,
- (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
- SHA1_EndRaw
- },
- { SHA256_LENGTH,
- (void * (*)(void)) SHA256_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) SHA256_DestroyContext,
- (void (*)(void *)) SHA256_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) SHA256_Update,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) SHA256_End,
- SHA256_BLOCK_LENGTH,
- HASH_AlgSHA256,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) SHA256_EndRaw
- },
- { SHA384_LENGTH,
- (void * (*)(void)) SHA384_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) SHA384_DestroyContext,
- (void (*)(void *)) SHA384_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) SHA384_Update,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) SHA384_End,
- SHA384_BLOCK_LENGTH,
- HASH_AlgSHA384,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) SHA384_EndRaw
- },
- { SHA512_LENGTH,
- (void * (*)(void)) SHA512_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) SHA512_DestroyContext,
- (void (*)(void *)) SHA512_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) SHA512_Update,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) SHA512_End,
- SHA512_BLOCK_LENGTH,
- HASH_AlgSHA512,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) SHA512_EndRaw
- },
- { SHA224_LENGTH,
- (void * (*)(void)) SHA224_NewContext,
- (void * (*)(void *)) null_hash_clone_context,
- (void (*)(void *, PRBool)) SHA224_DestroyContext,
- (void (*)(void *)) SHA224_Begin,
- (void (*)(void *, const unsigned char *, unsigned int)) SHA224_Update,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) SHA224_End,
- SHA224_BLOCK_LENGTH,
- HASH_AlgSHA224,
- (void (*)(void *, unsigned char *, unsigned int *,
- unsigned int)) SHA224_EndRaw
- },
-};
-
-const SECHashObject *
-HASH_GetRawHashObject(HASH_HashType hashType)
-{
- if (hashType < HASH_AlgNULL || hashType >= HASH_AlgTOTAL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- return &SECRawHashObjects[hashType];
-}
diff --git a/security/nss/lib/freebl/ret_cr16.s b/security/nss/lib/freebl/ret_cr16.s
deleted file mode 100644
index 1f53fc900..000000000
--- a/security/nss/lib/freebl/ret_cr16.s
+++ /dev/null
@@ -1,27 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef __LP64__
- .LEVEL 2.0W
-#else
- .LEVEL 1.1
-#endif
-
- .CODE ; equivalent to the following two lines
-; .SPACE $TEXT$,SORT=8
-; .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24
-
-ret_cr16
- .PROC
- .CALLINFO FRAME=0, NO_CALLS
- .EXPORT ret_cr16,ENTRY
- .ENTRY
-; BV %r0(%rp)
- BV 0(%rp)
- MFCTL %cr16,%ret0
- BV %r0(%rp)
- .EXIT
- NOP
- .PROCEND
- .END
diff --git a/security/nss/lib/freebl/rijndael.c b/security/nss/lib/freebl/rijndael.c
deleted file mode 100644
index f7fcb0edb..000000000
--- a/security/nss/lib/freebl/rijndael.c
+++ /dev/null
@@ -1,1271 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prinit.h"
-#include "prerr.h"
-#include "secerr.h"
-
-#include "prtypes.h"
-#include "blapi.h"
-#include "rijndael.h"
-
-#include "cts.h"
-#include "ctr.h"
-#include "gcm.h"
-
-#if USE_HW_AES
-#include "intel-gcm.h"
-#include "intel-aes.h"
-#include "mpi.h"
-
-static int has_intel_aes = 0;
-static int has_intel_avx = 0;
-static int has_intel_clmul = 0;
-static PRBool use_hw_aes = PR_FALSE;
-static PRBool use_hw_avx = PR_FALSE;
-static PRBool use_hw_gcm = PR_FALSE;
-#endif
-
-/*
- * There are currently five ways to build this code, varying in performance
- * and code size.
- *
- * RIJNDAEL_INCLUDE_TABLES Include all tables from rijndael32.tab
- * RIJNDAEL_GENERATE_TABLES Generate tables on first
- * encryption/decryption, then store them;
- * use the function gfm
- * RIJNDAEL_GENERATE_TABLES_MACRO Same as above, but use macros to do
- * the generation
- * RIJNDAEL_GENERATE_VALUES Do not store tables, generate the table
- * values "on-the-fly", using gfm
- * RIJNDAEL_GENERATE_VALUES_MACRO Same as above, but use macros
- *
- * The default is RIJNDAEL_INCLUDE_TABLES.
- */
-
-/*
- * When building RIJNDAEL_INCLUDE_TABLES, includes S**-1, Rcon, T[0..4],
- * T**-1[0..4], IMXC[0..4]
- * When building anything else, includes S, S**-1, Rcon
- */
-#include "rijndael32.tab"
-
-#if defined(RIJNDAEL_INCLUDE_TABLES)
-/*
- * RIJNDAEL_INCLUDE_TABLES
- */
-#define T0(i) _T0[i]
-#define T1(i) _T1[i]
-#define T2(i) _T2[i]
-#define T3(i) _T3[i]
-#define TInv0(i) _TInv0[i]
-#define TInv1(i) _TInv1[i]
-#define TInv2(i) _TInv2[i]
-#define TInv3(i) _TInv3[i]
-#define IMXC0(b) _IMXC0[b]
-#define IMXC1(b) _IMXC1[b]
-#define IMXC2(b) _IMXC2[b]
-#define IMXC3(b) _IMXC3[b]
-/* The S-box can be recovered from the T-tables */
-#ifdef IS_LITTLE_ENDIAN
-#define SBOX(b) ((PRUint8)_T3[b])
-#else
-#define SBOX(b) ((PRUint8)_T1[b])
-#endif
-#define SINV(b) (_SInv[b])
-
-#else /* not RIJNDAEL_INCLUDE_TABLES */
-
-/*
- * Code for generating T-table values.
- */
-
-#ifdef IS_LITTLE_ENDIAN
-#define WORD4(b0, b1, b2, b3) \
- (((b3) << 24) | ((b2) << 16) | ((b1) << 8) | (b0))
-#else
-#define WORD4(b0, b1, b2, b3) \
- (((b0) << 24) | ((b1) << 16) | ((b2) << 8) | (b3))
-#endif
-
-/*
- * Define the S and S**-1 tables (both have been stored)
- */
-#define SBOX(b) (_S[b])
-#define SINV(b) (_SInv[b])
-
-/*
- * The function xtime, used for Galois field multiplication
- */
-#define XTIME(a) \
- ((a & 0x80) ? ((a << 1) ^ 0x1b) : (a << 1))
-
-/* Choose GFM method (macros or function) */
-#if defined(RIJNDAEL_GENERATE_TABLES_MACRO) || \
- defined(RIJNDAEL_GENERATE_VALUES_MACRO)
-
-/*
- * Galois field GF(2**8) multipliers, in macro form
- */
-#define GFM01(a) \
- (a) /* a * 01 = a, the identity */
-#define GFM02(a) \
- (XTIME(a) & 0xff) /* a * 02 = xtime(a) */
-#define GFM04(a) \
- (GFM02(GFM02(a))) /* a * 04 = xtime**2(a) */
-#define GFM08(a) \
- (GFM02(GFM04(a))) /* a * 08 = xtime**3(a) */
-#define GFM03(a) \
- (GFM01(a) ^ GFM02(a)) /* a * 03 = a * (01 + 02) */
-#define GFM09(a) \
- (GFM01(a) ^ GFM08(a)) /* a * 09 = a * (01 + 08) */
-#define GFM0B(a) \
- (GFM01(a) ^ GFM02(a) ^ GFM08(a)) /* a * 0B = a * (01 + 02 + 08) */
-#define GFM0D(a) \
- (GFM01(a) ^ GFM04(a) ^ GFM08(a)) /* a * 0D = a * (01 + 04 + 08) */
-#define GFM0E(a) \
- (GFM02(a) ^ GFM04(a) ^ GFM08(a)) /* a * 0E = a * (02 + 04 + 08) */
-
-#else /* RIJNDAEL_GENERATE_TABLES or RIJNDAEL_GENERATE_VALUES */
-
-/* GF_MULTIPLY
- *
- * multiply two bytes represented in GF(2**8), mod (x**4 + 1)
- */
-PRUint8 gfm(PRUint8 a, PRUint8 b)
-{
- PRUint8 res = 0;
- while (b > 0) {
- res = (b & 0x01) ? res ^ a : res;
- a = XTIME(a);
- b >>= 1;
- }
- return res;
-}
-
-#define GFM01(a) \
- (a) /* a * 01 = a, the identity */
-#define GFM02(a) \
- (XTIME(a) & 0xff) /* a * 02 = xtime(a) */
-#define GFM03(a) \
- (gfm(a, 0x03)) /* a * 03 */
-#define GFM09(a) \
- (gfm(a, 0x09)) /* a * 09 */
-#define GFM0B(a) \
- (gfm(a, 0x0B)) /* a * 0B */
-#define GFM0D(a) \
- (gfm(a, 0x0D)) /* a * 0D */
-#define GFM0E(a) \
- (gfm(a, 0x0E)) /* a * 0E */
-
-#endif /* choosing GFM function */
-
-/*
- * The T-tables
- */
-#define G_T0(i) \
- ( WORD4( GFM02(SBOX(i)), GFM01(SBOX(i)), GFM01(SBOX(i)), GFM03(SBOX(i)) ) )
-#define G_T1(i) \
- ( WORD4( GFM03(SBOX(i)), GFM02(SBOX(i)), GFM01(SBOX(i)), GFM01(SBOX(i)) ) )
-#define G_T2(i) \
- ( WORD4( GFM01(SBOX(i)), GFM03(SBOX(i)), GFM02(SBOX(i)), GFM01(SBOX(i)) ) )
-#define G_T3(i) \
- ( WORD4( GFM01(SBOX(i)), GFM01(SBOX(i)), GFM03(SBOX(i)), GFM02(SBOX(i)) ) )
-
-/*
- * The inverse T-tables
- */
-#define G_TInv0(i) \
- ( WORD4( GFM0E(SINV(i)), GFM09(SINV(i)), GFM0D(SINV(i)), GFM0B(SINV(i)) ) )
-#define G_TInv1(i) \
- ( WORD4( GFM0B(SINV(i)), GFM0E(SINV(i)), GFM09(SINV(i)), GFM0D(SINV(i)) ) )
-#define G_TInv2(i) \
- ( WORD4( GFM0D(SINV(i)), GFM0B(SINV(i)), GFM0E(SINV(i)), GFM09(SINV(i)) ) )
-#define G_TInv3(i) \
- ( WORD4( GFM09(SINV(i)), GFM0D(SINV(i)), GFM0B(SINV(i)), GFM0E(SINV(i)) ) )
-
-/*
- * The inverse mix column tables
- */
-#define G_IMXC0(i) \
- ( WORD4( GFM0E(i), GFM09(i), GFM0D(i), GFM0B(i) ) )
-#define G_IMXC1(i) \
- ( WORD4( GFM0B(i), GFM0E(i), GFM09(i), GFM0D(i) ) )
-#define G_IMXC2(i) \
- ( WORD4( GFM0D(i), GFM0B(i), GFM0E(i), GFM09(i) ) )
-#define G_IMXC3(i) \
- ( WORD4( GFM09(i), GFM0D(i), GFM0B(i), GFM0E(i) ) )
-
-/* Now choose the T-table indexing method */
-#if defined(RIJNDAEL_GENERATE_VALUES)
-/* generate values for the tables with a function*/
-static PRUint32 gen_TInvXi(PRUint8 tx, PRUint8 i)
-{
- PRUint8 si01, si02, si03, si04, si08, si09, si0B, si0D, si0E;
- si01 = SINV(i);
- si02 = XTIME(si01);
- si04 = XTIME(si02);
- si08 = XTIME(si04);
- si03 = si02 ^ si01;
- si09 = si08 ^ si01;
- si0B = si08 ^ si03;
- si0D = si09 ^ si04;
- si0E = si08 ^ si04 ^ si02;
- switch (tx) {
- case 0:
- return WORD4(si0E, si09, si0D, si0B);
- case 1:
- return WORD4(si0B, si0E, si09, si0D);
- case 2:
- return WORD4(si0D, si0B, si0E, si09);
- case 3:
- return WORD4(si09, si0D, si0B, si0E);
- }
- return -1;
-}
-#define T0(i) G_T0(i)
-#define T1(i) G_T1(i)
-#define T2(i) G_T2(i)
-#define T3(i) G_T3(i)
-#define TInv0(i) gen_TInvXi(0, i)
-#define TInv1(i) gen_TInvXi(1, i)
-#define TInv2(i) gen_TInvXi(2, i)
-#define TInv3(i) gen_TInvXi(3, i)
-#define IMXC0(b) G_IMXC0(b)
-#define IMXC1(b) G_IMXC1(b)
-#define IMXC2(b) G_IMXC2(b)
-#define IMXC3(b) G_IMXC3(b)
-#elif defined(RIJNDAEL_GENERATE_VALUES_MACRO)
-/* generate values for the tables with macros */
-#define T0(i) G_T0(i)
-#define T1(i) G_T1(i)
-#define T2(i) G_T2(i)
-#define T3(i) G_T3(i)
-#define TInv0(i) G_TInv0(i)
-#define TInv1(i) G_TInv1(i)
-#define TInv2(i) G_TInv2(i)
-#define TInv3(i) G_TInv3(i)
-#define IMXC0(b) G_IMXC0(b)
-#define IMXC1(b) G_IMXC1(b)
-#define IMXC2(b) G_IMXC2(b)
-#define IMXC3(b) G_IMXC3(b)
-#else /* RIJNDAEL_GENERATE_TABLES or RIJNDAEL_GENERATE_TABLES_MACRO */
-/* Generate T and T**-1 table values and store, then index */
-/* The inverse mix column tables are still generated */
-#define T0(i) rijndaelTables->T0[i]
-#define T1(i) rijndaelTables->T1[i]
-#define T2(i) rijndaelTables->T2[i]
-#define T3(i) rijndaelTables->T3[i]
-#define TInv0(i) rijndaelTables->TInv0[i]
-#define TInv1(i) rijndaelTables->TInv1[i]
-#define TInv2(i) rijndaelTables->TInv2[i]
-#define TInv3(i) rijndaelTables->TInv3[i]
-#define IMXC0(b) G_IMXC0(b)
-#define IMXC1(b) G_IMXC1(b)
-#define IMXC2(b) G_IMXC2(b)
-#define IMXC3(b) G_IMXC3(b)
-#endif /* choose T-table indexing method */
-
-#endif /* not RIJNDAEL_INCLUDE_TABLES */
-
-#if defined(RIJNDAEL_GENERATE_TABLES) || \
- defined(RIJNDAEL_GENERATE_TABLES_MACRO)
-
-/* Code to generate and store the tables */
-
-struct rijndael_tables_str {
- PRUint32 T0[256];
- PRUint32 T1[256];
- PRUint32 T2[256];
- PRUint32 T3[256];
- PRUint32 TInv0[256];
- PRUint32 TInv1[256];
- PRUint32 TInv2[256];
- PRUint32 TInv3[256];
-};
-
-static struct rijndael_tables_str *rijndaelTables = NULL;
-static PRCallOnceType coRTInit = { 0, 0, 0 };
-static PRStatus
-init_rijndael_tables(void)
-{
- PRUint32 i;
- PRUint8 si01, si02, si03, si04, si08, si09, si0B, si0D, si0E;
- struct rijndael_tables_str *rts;
- rts = (struct rijndael_tables_str *)
- PORT_Alloc(sizeof(struct rijndael_tables_str));
- if (!rts) return PR_FAILURE;
- for (i=0; i<256; i++) {
- /* The forward values */
- si01 = SBOX(i);
- si02 = XTIME(si01);
- si03 = si02 ^ si01;
- rts->T0[i] = WORD4(si02, si01, si01, si03);
- rts->T1[i] = WORD4(si03, si02, si01, si01);
- rts->T2[i] = WORD4(si01, si03, si02, si01);
- rts->T3[i] = WORD4(si01, si01, si03, si02);
- /* The inverse values */
- si01 = SINV(i);
- si02 = XTIME(si01);
- si04 = XTIME(si02);
- si08 = XTIME(si04);
- si03 = si02 ^ si01;
- si09 = si08 ^ si01;
- si0B = si08 ^ si03;
- si0D = si09 ^ si04;
- si0E = si08 ^ si04 ^ si02;
- rts->TInv0[i] = WORD4(si0E, si09, si0D, si0B);
- rts->TInv1[i] = WORD4(si0B, si0E, si09, si0D);
- rts->TInv2[i] = WORD4(si0D, si0B, si0E, si09);
- rts->TInv3[i] = WORD4(si09, si0D, si0B, si0E);
- }
- /* wait until all the values are in to set */
- rijndaelTables = rts;
- return PR_SUCCESS;
-}
-
-#endif /* code to generate tables */
-
-/**************************************************************************
- *
- * Stuff related to the Rijndael key schedule
- *
- *************************************************************************/
-
-#define SUBBYTE(w) \
- ((SBOX((w >> 24) & 0xff) << 24) | \
- (SBOX((w >> 16) & 0xff) << 16) | \
- (SBOX((w >> 8) & 0xff) << 8) | \
- (SBOX((w ) & 0xff) ))
-
-#ifdef IS_LITTLE_ENDIAN
-#define ROTBYTE(b) \
- ((b >> 8) | (b << 24))
-#else
-#define ROTBYTE(b) \
- ((b << 8) | (b >> 24))
-#endif
-
-/* rijndael_key_expansion7
- *
- * Generate the expanded key from the key input by the user.
- * XXX
- * Nk == 7 (224 key bits) is a weird case. Since Nk > 6, an added SubByte
- * transformation is done periodically. The period is every 4 bytes, and
- * since 7%4 != 0 this happens at different times for each key word (unlike
- * Nk == 8 where it happens twice in every key word, in the same positions).
- * For now, I'm implementing this case "dumbly", w/o any unrolling.
- */
-static SECStatus
-rijndael_key_expansion7(AESContext *cx, const unsigned char *key, unsigned int Nk)
-{
- unsigned int i;
- PRUint32 *W;
- PRUint32 *pW;
- PRUint32 tmp;
- W = cx->expandedKey;
- /* 1. the first Nk words contain the cipher key */
- memcpy(W, key, Nk * 4);
- i = Nk;
- /* 2. loop until full expanded key is obtained */
- pW = W + i - 1;
- for (; i < cx->Nb * (cx->Nr + 1); ++i) {
- tmp = *pW++;
- if (i % Nk == 0)
- tmp = SUBBYTE(ROTBYTE(tmp)) ^ Rcon[i / Nk - 1];
- else if (i % Nk == 4)
- tmp = SUBBYTE(tmp);
- *pW = W[i - Nk] ^ tmp;
- }
- return SECSuccess;
-}
-
-/* rijndael_key_expansion
- *
- * Generate the expanded key from the key input by the user.
- */
-static SECStatus
-rijndael_key_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk)
-{
- unsigned int i;
- PRUint32 *W;
- PRUint32 *pW;
- PRUint32 tmp;
- unsigned int round_key_words = cx->Nb * (cx->Nr + 1);
- if (Nk == 7)
- return rijndael_key_expansion7(cx, key, Nk);
- W = cx->expandedKey;
- /* The first Nk words contain the input cipher key */
- memcpy(W, key, Nk * 4);
- i = Nk;
- pW = W + i - 1;
- /* Loop over all sets of Nk words, except the last */
- while (i < round_key_words - Nk) {
- tmp = *pW++;
- tmp = SUBBYTE(ROTBYTE(tmp)) ^ Rcon[i / Nk - 1];
- *pW = W[i++ - Nk] ^ tmp;
- tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
- tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
- tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
- if (Nk == 4)
- continue;
- switch (Nk) {
- case 8: tmp = *pW++; tmp = SUBBYTE(tmp); *pW = W[i++ - Nk] ^ tmp;
- case 7: tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
- case 6: tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
- case 5: tmp = *pW++; *pW = W[i++ - Nk] ^ tmp;
- }
- }
- /* Generate the last word */
- tmp = *pW++;
- tmp = SUBBYTE(ROTBYTE(tmp)) ^ Rcon[i / Nk - 1];
- *pW = W[i++ - Nk] ^ tmp;
- /* There may be overflow here, if Nk % (Nb * (Nr + 1)) > 0. However,
- * since the above loop generated all but the last Nk key words, there
- * is no more need for the SubByte transformation.
- */
- if (Nk < 8) {
- for (; i < round_key_words; ++i) {
- tmp = *pW++;
- *pW = W[i - Nk] ^ tmp;
- }
- } else {
- /* except in the case when Nk == 8. Then one more SubByte may have
- * to be performed, at i % Nk == 4.
- */
- for (; i < round_key_words; ++i) {
- tmp = *pW++;
- if (i % Nk == 4)
- tmp = SUBBYTE(tmp);
- *pW = W[i - Nk] ^ tmp;
- }
- }
- return SECSuccess;
-}
-
-/* rijndael_invkey_expansion
- *
- * Generate the expanded key for the inverse cipher from the key input by
- * the user.
- */
-static SECStatus
-rijndael_invkey_expansion(AESContext *cx, const unsigned char *key, unsigned int Nk)
-{
- unsigned int r;
- PRUint32 *roundkeyw;
- PRUint8 *b;
- int Nb = cx->Nb;
- /* begins like usual key expansion ... */
- if (rijndael_key_expansion(cx, key, Nk) != SECSuccess)
- return SECFailure;
- /* ... but has the additional step of InvMixColumn,
- * excepting the first and last round keys.
- */
- roundkeyw = cx->expandedKey + cx->Nb;
- for (r=1; r<cx->Nr; ++r) {
- /* each key word, roundkeyw, represents a column in the key
- * matrix. Each column is multiplied by the InvMixColumn matrix.
- * [ 0E 0B 0D 09 ] [ b0 ]
- * [ 09 0E 0B 0D ] * [ b1 ]
- * [ 0D 09 0E 0B ] [ b2 ]
- * [ 0B 0D 09 0E ] [ b3 ]
- */
- b = (PRUint8 *)roundkeyw;
- *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ IMXC2(b[2]) ^ IMXC3(b[3]);
- b = (PRUint8 *)roundkeyw;
- *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ IMXC2(b[2]) ^ IMXC3(b[3]);
- b = (PRUint8 *)roundkeyw;
- *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ IMXC2(b[2]) ^ IMXC3(b[3]);
- b = (PRUint8 *)roundkeyw;
- *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^ IMXC2(b[2]) ^ IMXC3(b[3]);
- if (Nb <= 4)
- continue;
- switch (Nb) {
- case 8: b = (PRUint8 *)roundkeyw;
- *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^
- IMXC2(b[2]) ^ IMXC3(b[3]);
- case 7: b = (PRUint8 *)roundkeyw;
- *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^
- IMXC2(b[2]) ^ IMXC3(b[3]);
- case 6: b = (PRUint8 *)roundkeyw;
- *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^
- IMXC2(b[2]) ^ IMXC3(b[3]);
- case 5: b = (PRUint8 *)roundkeyw;
- *roundkeyw++ = IMXC0(b[0]) ^ IMXC1(b[1]) ^
- IMXC2(b[2]) ^ IMXC3(b[3]);
- }
- }
- return SECSuccess;
-}
-/**************************************************************************
- *
- * Stuff related to Rijndael encryption/decryption, optimized for
- * a 128-bit blocksize.
- *
- *************************************************************************/
-
-#ifdef IS_LITTLE_ENDIAN
-#define BYTE0WORD(w) ((w) & 0x000000ff)
-#define BYTE1WORD(w) ((w) & 0x0000ff00)
-#define BYTE2WORD(w) ((w) & 0x00ff0000)
-#define BYTE3WORD(w) ((w) & 0xff000000)
-#else
-#define BYTE0WORD(w) ((w) & 0xff000000)
-#define BYTE1WORD(w) ((w) & 0x00ff0000)
-#define BYTE2WORD(w) ((w) & 0x0000ff00)
-#define BYTE3WORD(w) ((w) & 0x000000ff)
-#endif
-
-typedef union {
- PRUint32 w[4];
- PRUint8 b[16];
-} rijndael_state;
-
-#define COLUMN_0(state) state.w[0]
-#define COLUMN_1(state) state.w[1]
-#define COLUMN_2(state) state.w[2]
-#define COLUMN_3(state) state.w[3]
-
-#define STATE_BYTE(i) state.b[i]
-
-static SECStatus
-rijndael_encryptBlock128(AESContext *cx,
- unsigned char *output,
- const unsigned char *input)
-{
- unsigned int r;
- PRUint32 *roundkeyw;
- rijndael_state state;
- PRUint32 C0, C1, C2, C3;
-#if defined(NSS_X86_OR_X64)
-#define pIn input
-#define pOut output
-#else
- unsigned char *pIn, *pOut;
- PRUint32 inBuf[4], outBuf[4];
-
- if ((ptrdiff_t)input & 0x3) {
- memcpy(inBuf, input, sizeof inBuf);
- pIn = (unsigned char *)inBuf;
- } else {
- pIn = (unsigned char *)input;
- }
- if ((ptrdiff_t)output & 0x3) {
- pOut = (unsigned char *)outBuf;
- } else {
- pOut = (unsigned char *)output;
- }
-#endif
- roundkeyw = cx->expandedKey;
- /* Step 1: Add Round Key 0 to initial state */
- COLUMN_0(state) = *((PRUint32 *)(pIn )) ^ *roundkeyw++;
- COLUMN_1(state) = *((PRUint32 *)(pIn + 4 )) ^ *roundkeyw++;
- COLUMN_2(state) = *((PRUint32 *)(pIn + 8 )) ^ *roundkeyw++;
- COLUMN_3(state) = *((PRUint32 *)(pIn + 12)) ^ *roundkeyw++;
- /* Step 2: Loop over rounds [1..NR-1] */
- for (r=1; r<cx->Nr; ++r) {
- /* Do ShiftRow, ByteSub, and MixColumn all at once */
- C0 = T0(STATE_BYTE(0)) ^
- T1(STATE_BYTE(5)) ^
- T2(STATE_BYTE(10)) ^
- T3(STATE_BYTE(15));
- C1 = T0(STATE_BYTE(4)) ^
- T1(STATE_BYTE(9)) ^
- T2(STATE_BYTE(14)) ^
- T3(STATE_BYTE(3));
- C2 = T0(STATE_BYTE(8)) ^
- T1(STATE_BYTE(13)) ^
- T2(STATE_BYTE(2)) ^
- T3(STATE_BYTE(7));
- C3 = T0(STATE_BYTE(12)) ^
- T1(STATE_BYTE(1)) ^
- T2(STATE_BYTE(6)) ^
- T3(STATE_BYTE(11));
- /* Round key addition */
- COLUMN_0(state) = C0 ^ *roundkeyw++;
- COLUMN_1(state) = C1 ^ *roundkeyw++;
- COLUMN_2(state) = C2 ^ *roundkeyw++;
- COLUMN_3(state) = C3 ^ *roundkeyw++;
- }
- /* Step 3: Do the last round */
- /* Final round does not employ MixColumn */
- C0 = ((BYTE0WORD(T2(STATE_BYTE(0)))) |
- (BYTE1WORD(T3(STATE_BYTE(5)))) |
- (BYTE2WORD(T0(STATE_BYTE(10)))) |
- (BYTE3WORD(T1(STATE_BYTE(15))))) ^
- *roundkeyw++;
- C1 = ((BYTE0WORD(T2(STATE_BYTE(4)))) |
- (BYTE1WORD(T3(STATE_BYTE(9)))) |
- (BYTE2WORD(T0(STATE_BYTE(14)))) |
- (BYTE3WORD(T1(STATE_BYTE(3))))) ^
- *roundkeyw++;
- C2 = ((BYTE0WORD(T2(STATE_BYTE(8)))) |
- (BYTE1WORD(T3(STATE_BYTE(13)))) |
- (BYTE2WORD(T0(STATE_BYTE(2)))) |
- (BYTE3WORD(T1(STATE_BYTE(7))))) ^
- *roundkeyw++;
- C3 = ((BYTE0WORD(T2(STATE_BYTE(12)))) |
- (BYTE1WORD(T3(STATE_BYTE(1)))) |
- (BYTE2WORD(T0(STATE_BYTE(6)))) |
- (BYTE3WORD(T1(STATE_BYTE(11))))) ^
- *roundkeyw++;
- *((PRUint32 *) pOut ) = C0;
- *((PRUint32 *)(pOut + 4)) = C1;
- *((PRUint32 *)(pOut + 8)) = C2;
- *((PRUint32 *)(pOut + 12)) = C3;
-#if defined(NSS_X86_OR_X64)
-#undef pIn
-#undef pOut
-#else
- if ((ptrdiff_t)output & 0x3) {
- memcpy(output, outBuf, sizeof outBuf);
- }
-#endif
- return SECSuccess;
-}
-
-static SECStatus
-rijndael_decryptBlock128(AESContext *cx,
- unsigned char *output,
- const unsigned char *input)
-{
- int r;
- PRUint32 *roundkeyw;
- rijndael_state state;
- PRUint32 C0, C1, C2, C3;
-#if defined(NSS_X86_OR_X64)
-#define pIn input
-#define pOut output
-#else
- unsigned char *pIn, *pOut;
- PRUint32 inBuf[4], outBuf[4];
-
- if ((ptrdiff_t)input & 0x3) {
- memcpy(inBuf, input, sizeof inBuf);
- pIn = (unsigned char *)inBuf;
- } else {
- pIn = (unsigned char *)input;
- }
- if ((ptrdiff_t)output & 0x3) {
- pOut = (unsigned char *)outBuf;
- } else {
- pOut = (unsigned char *)output;
- }
-#endif
- roundkeyw = cx->expandedKey + cx->Nb * cx->Nr + 3;
- /* reverse the final key addition */
- COLUMN_3(state) = *((PRUint32 *)(pIn + 12)) ^ *roundkeyw--;
- COLUMN_2(state) = *((PRUint32 *)(pIn + 8)) ^ *roundkeyw--;
- COLUMN_1(state) = *((PRUint32 *)(pIn + 4)) ^ *roundkeyw--;
- COLUMN_0(state) = *((PRUint32 *)(pIn )) ^ *roundkeyw--;
- /* Loop over rounds in reverse [NR..1] */
- for (r=cx->Nr; r>1; --r) {
- /* Invert the (InvByteSub*InvMixColumn)(InvShiftRow(state)) */
- C0 = TInv0(STATE_BYTE(0)) ^
- TInv1(STATE_BYTE(13)) ^
- TInv2(STATE_BYTE(10)) ^
- TInv3(STATE_BYTE(7));
- C1 = TInv0(STATE_BYTE(4)) ^
- TInv1(STATE_BYTE(1)) ^
- TInv2(STATE_BYTE(14)) ^
- TInv3(STATE_BYTE(11));
- C2 = TInv0(STATE_BYTE(8)) ^
- TInv1(STATE_BYTE(5)) ^
- TInv2(STATE_BYTE(2)) ^
- TInv3(STATE_BYTE(15));
- C3 = TInv0(STATE_BYTE(12)) ^
- TInv1(STATE_BYTE(9)) ^
- TInv2(STATE_BYTE(6)) ^
- TInv3(STATE_BYTE(3));
- /* Invert the key addition step */
- COLUMN_3(state) = C3 ^ *roundkeyw--;
- COLUMN_2(state) = C2 ^ *roundkeyw--;
- COLUMN_1(state) = C1 ^ *roundkeyw--;
- COLUMN_0(state) = C0 ^ *roundkeyw--;
- }
- /* inverse sub */
- pOut[ 0] = SINV(STATE_BYTE( 0));
- pOut[ 1] = SINV(STATE_BYTE(13));
- pOut[ 2] = SINV(STATE_BYTE(10));
- pOut[ 3] = SINV(STATE_BYTE( 7));
- pOut[ 4] = SINV(STATE_BYTE( 4));
- pOut[ 5] = SINV(STATE_BYTE( 1));
- pOut[ 6] = SINV(STATE_BYTE(14));
- pOut[ 7] = SINV(STATE_BYTE(11));
- pOut[ 8] = SINV(STATE_BYTE( 8));
- pOut[ 9] = SINV(STATE_BYTE( 5));
- pOut[10] = SINV(STATE_BYTE( 2));
- pOut[11] = SINV(STATE_BYTE(15));
- pOut[12] = SINV(STATE_BYTE(12));
- pOut[13] = SINV(STATE_BYTE( 9));
- pOut[14] = SINV(STATE_BYTE( 6));
- pOut[15] = SINV(STATE_BYTE( 3));
- /* final key addition */
- *((PRUint32 *)(pOut + 12)) ^= *roundkeyw--;
- *((PRUint32 *)(pOut + 8)) ^= *roundkeyw--;
- *((PRUint32 *)(pOut + 4)) ^= *roundkeyw--;
- *((PRUint32 *) pOut ) ^= *roundkeyw--;
-#if defined(NSS_X86_OR_X64)
-#undef pIn
-#undef pOut
-#else
- if ((ptrdiff_t)output & 0x3) {
- memcpy(output, outBuf, sizeof outBuf);
- }
-#endif
- return SECSuccess;
-}
-
-/**************************************************************************
- *
- * Stuff related to general Rijndael encryption/decryption, for blocksizes
- * greater than 128 bits.
- *
- * XXX This code is currently untested! So far, AES specs have only been
- * released for 128 bit blocksizes. This will be tested, but for now
- * only the code above has been tested using known values.
- *
- *************************************************************************/
-
-#define COLUMN(array, j) *((PRUint32 *)(array + j))
-
-SECStatus
-rijndael_encryptBlock(AESContext *cx,
- unsigned char *output,
- const unsigned char *input)
-{
- return SECFailure;
-#ifdef rijndael_large_blocks_fixed
- unsigned int j, r, Nb;
- unsigned int c2=0, c3=0;
- PRUint32 *roundkeyw;
- PRUint8 clone[RIJNDAEL_MAX_STATE_SIZE];
- Nb = cx->Nb;
- roundkeyw = cx->expandedKey;
- /* Step 1: Add Round Key 0 to initial state */
- for (j=0; j<4*Nb; j+=4) {
- COLUMN(clone, j) = COLUMN(input, j) ^ *roundkeyw++;
- }
- /* Step 2: Loop over rounds [1..NR-1] */
- for (r=1; r<cx->Nr; ++r) {
- for (j=0; j<Nb; ++j) {
- COLUMN(output, j) = T0(STATE_BYTE(4* j )) ^
- T1(STATE_BYTE(4*((j+ 1)%Nb)+1)) ^
- T2(STATE_BYTE(4*((j+c2)%Nb)+2)) ^
- T3(STATE_BYTE(4*((j+c3)%Nb)+3));
- }
- for (j=0; j<4*Nb; j+=4) {
- COLUMN(clone, j) = COLUMN(output, j) ^ *roundkeyw++;
- }
- }
- /* Step 3: Do the last round */
- /* Final round does not employ MixColumn */
- for (j=0; j<Nb; ++j) {
- COLUMN(output, j) = ((BYTE0WORD(T2(STATE_BYTE(4* j )))) |
- (BYTE1WORD(T3(STATE_BYTE(4*(j+ 1)%Nb)+1))) |
- (BYTE2WORD(T0(STATE_BYTE(4*(j+c2)%Nb)+2))) |
- (BYTE3WORD(T1(STATE_BYTE(4*(j+c3)%Nb)+3)))) ^
- *roundkeyw++;
- }
- return SECSuccess;
-#endif
-}
-
-SECStatus
-rijndael_decryptBlock(AESContext *cx,
- unsigned char *output,
- const unsigned char *input)
-{
- return SECFailure;
-#ifdef rijndael_large_blocks_fixed
- int j, r, Nb;
- int c2=0, c3=0;
- PRUint32 *roundkeyw;
- PRUint8 clone[RIJNDAEL_MAX_STATE_SIZE];
- Nb = cx->Nb;
- roundkeyw = cx->expandedKey + cx->Nb * cx->Nr + 3;
- /* reverse key addition */
- for (j=4*Nb; j>=0; j-=4) {
- COLUMN(clone, j) = COLUMN(input, j) ^ *roundkeyw--;
- }
- /* Loop over rounds in reverse [NR..1] */
- for (r=cx->Nr; r>1; --r) {
- /* Invert the (InvByteSub*InvMixColumn)(InvShiftRow(state)) */
- for (j=0; j<Nb; ++j) {
- COLUMN(output, 4*j) = TInv0(STATE_BYTE(4* j )) ^
- TInv1(STATE_BYTE(4*(j+Nb- 1)%Nb)+1) ^
- TInv2(STATE_BYTE(4*(j+Nb-c2)%Nb)+2) ^
- TInv3(STATE_BYTE(4*(j+Nb-c3)%Nb)+3);
- }
- /* Invert the key addition step */
- for (j=4*Nb; j>=0; j-=4) {
- COLUMN(clone, j) = COLUMN(output, j) ^ *roundkeyw--;
- }
- }
- /* inverse sub */
- for (j=0; j<4*Nb; ++j) {
- output[j] = SINV(clone[j]);
- }
- /* final key addition */
- for (j=4*Nb; j>=0; j-=4) {
- COLUMN(output, j) ^= *roundkeyw--;
- }
- return SECSuccess;
-#endif
-}
-
-/**************************************************************************
- *
- * Rijndael modes of operation (ECB and CBC)
- *
- *************************************************************************/
-
-static SECStatus
-rijndael_encryptECB(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
- unsigned int blocksize)
-{
- SECStatus rv;
- AESBlockFunc *encryptor;
-
-
- encryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE)
- ? &rijndael_encryptBlock128
- : &rijndael_encryptBlock;
- while (inputLen > 0) {
- rv = (*encryptor)(cx, output, input);
- if (rv != SECSuccess)
- return rv;
- output += blocksize;
- input += blocksize;
- inputLen -= blocksize;
- }
- return SECSuccess;
-}
-
-static SECStatus
-rijndael_encryptCBC(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
- unsigned int blocksize)
-{
- unsigned int j;
- SECStatus rv;
- AESBlockFunc *encryptor;
- unsigned char *lastblock;
- unsigned char inblock[RIJNDAEL_MAX_STATE_SIZE * 8];
-
- if (!inputLen)
- return SECSuccess;
- lastblock = cx->iv;
- encryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE)
- ? &rijndael_encryptBlock128
- : &rijndael_encryptBlock;
- while (inputLen > 0) {
- /* XOR with the last block (IV if first block) */
- for (j=0; j<blocksize; ++j)
- inblock[j] = input[j] ^ lastblock[j];
- /* encrypt */
- rv = (*encryptor)(cx, output, inblock);
- if (rv != SECSuccess)
- return rv;
- /* move to the next block */
- lastblock = output;
- output += blocksize;
- input += blocksize;
- inputLen -= blocksize;
- }
- memcpy(cx->iv, lastblock, blocksize);
- return SECSuccess;
-}
-
-static SECStatus
-rijndael_decryptECB(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
- unsigned int blocksize)
-{
- SECStatus rv;
- AESBlockFunc *decryptor;
-
- decryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE)
- ? &rijndael_decryptBlock128
- : &rijndael_decryptBlock;
- while (inputLen > 0) {
- rv = (*decryptor)(cx, output, input);
- if (rv != SECSuccess)
- return rv;
- output += blocksize;
- input += blocksize;
- inputLen -= blocksize;
- }
- return SECSuccess;
-}
-
-static SECStatus
-rijndael_decryptCBC(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
- unsigned int blocksize)
-{
- SECStatus rv;
- AESBlockFunc *decryptor;
- const unsigned char *in;
- unsigned char *out;
- unsigned int j;
- unsigned char newIV[RIJNDAEL_MAX_BLOCKSIZE];
-
-
- if (!inputLen)
- return SECSuccess;
- PORT_Assert(output - input >= 0 || input - output >= (int)inputLen );
- decryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE)
- ? &rijndael_decryptBlock128
- : &rijndael_decryptBlock;
- in = input + (inputLen - blocksize);
- memcpy(newIV, in, blocksize);
- out = output + (inputLen - blocksize);
- while (inputLen > blocksize) {
- rv = (*decryptor)(cx, out, in);
- if (rv != SECSuccess)
- return rv;
- for (j=0; j<blocksize; ++j)
- out[j] ^= in[(int)(j - blocksize)];
- out -= blocksize;
- in -= blocksize;
- inputLen -= blocksize;
- }
- if (in == input) {
- rv = (*decryptor)(cx, out, in);
- if (rv != SECSuccess)
- return rv;
- for (j=0; j<blocksize; ++j)
- out[j] ^= cx->iv[j];
- }
- memcpy(cx->iv, newIV, blocksize);
- return SECSuccess;
-}
-
-/************************************************************************
- *
- * BLAPI Interface functions
- *
- * The following functions implement the encryption routines defined in
- * BLAPI for the AES cipher, Rijndael.
- *
- ***********************************************************************/
-
-AESContext * AES_AllocateContext(void)
-{
- return PORT_ZNew(AESContext);
-}
-
-
-/*
-** Initialize a new AES context suitable for AES encryption/decryption in
-** the ECB or CBC mode.
-** "mode" the mode of operation, which must be NSS_AES or NSS_AES_CBC
-*/
-static SECStatus
-aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
- const unsigned char *iv, int mode, unsigned int encrypt,
- unsigned int blocksize)
-{
- unsigned int Nk;
- /* According to Rijndael AES Proposal, section 12.1, block and key
- * lengths between 128 and 256 bits are supported, as long as the
- * length in bytes is divisible by 4.
- */
- if (key == NULL ||
- keysize < RIJNDAEL_MIN_BLOCKSIZE ||
- keysize > RIJNDAEL_MAX_BLOCKSIZE ||
- keysize % 4 != 0 ||
- blocksize < RIJNDAEL_MIN_BLOCKSIZE ||
- blocksize > RIJNDAEL_MAX_BLOCKSIZE ||
- blocksize % 4 != 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (mode != NSS_AES && mode != NSS_AES_CBC) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (mode == NSS_AES_CBC && iv == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-#if USE_HW_AES
- if (has_intel_aes == 0) {
- unsigned long eax, ebx, ecx, edx;
- char *disable_hw_aes = getenv("NSS_DISABLE_HW_AES");
-
- if (disable_hw_aes == NULL) {
- freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
- has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1;
- has_intel_clmul = (ecx & (1 << 1)) != 0 ? 1 : -1;
- has_intel_avx = (ecx & (1 << 28)) != 0 ? 1 : -1;
- } else {
- has_intel_aes = -1;
- has_intel_avx = -1;
- has_intel_clmul = -1;
- }
- }
- use_hw_aes = (PRBool)
- (has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16);
- use_hw_gcm = (PRBool)
- (use_hw_aes && has_intel_avx>0 && has_intel_clmul>0);
-#endif
- /* Nb = (block size in bits) / 32 */
- cx->Nb = blocksize / 4;
- /* Nk = (key size in bits) / 32 */
- Nk = keysize / 4;
- /* Obtain number of rounds from "table" */
- cx->Nr = RIJNDAEL_NUM_ROUNDS(Nk, cx->Nb);
- /* copy in the iv, if neccessary */
- if (mode == NSS_AES_CBC) {
- memcpy(cx->iv, iv, blocksize);
-#if USE_HW_AES
- if (use_hw_aes) {
- cx->worker = (freeblCipherFunc)
- intel_aes_cbc_worker(encrypt, keysize);
- } else
-#endif
- cx->worker = (freeblCipherFunc) (encrypt
- ? &rijndael_encryptCBC : &rijndael_decryptCBC);
- } else {
-#if USE_HW_AES
- if (use_hw_aes) {
- cx->worker = (freeblCipherFunc)
- intel_aes_ecb_worker(encrypt, keysize);
- } else
-#endif
- cx->worker = (freeblCipherFunc) (encrypt
- ? &rijndael_encryptECB : &rijndael_decryptECB);
- }
- PORT_Assert((cx->Nb * (cx->Nr + 1)) <= RIJNDAEL_MAX_EXP_KEY_SIZE);
- if ((cx->Nb * (cx->Nr + 1)) > RIJNDAEL_MAX_EXP_KEY_SIZE) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- goto cleanup;
- }
-#ifdef USE_HW_AES
- if (use_hw_aes) {
- intel_aes_init(encrypt, keysize);
- } else
-#endif
- {
-
-#if defined(RIJNDAEL_GENERATE_TABLES) || \
- defined(RIJNDAEL_GENERATE_TABLES_MACRO)
- if (rijndaelTables == NULL) {
- if (PR_CallOnce(&coRTInit, init_rijndael_tables)
- != PR_SUCCESS) {
- return SecFailure;
- }
- }
-#endif
- /* Generate expanded key */
- if (encrypt) {
- if (rijndael_key_expansion(cx, key, Nk) != SECSuccess)
- goto cleanup;
- } else {
- if (rijndael_invkey_expansion(cx, key, Nk) != SECSuccess)
- goto cleanup;
- }
- }
- cx->worker_cx = cx;
- cx->destroy = NULL;
- cx->isBlock = PR_TRUE;
- return SECSuccess;
-cleanup:
- return SECFailure;
-}
-
-SECStatus
-AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
- const unsigned char *iv, int mode, unsigned int encrypt,
- unsigned int blocksize)
-{
- int basemode = mode;
- PRBool baseencrypt = encrypt;
- SECStatus rv;
-
- switch (mode) {
- case NSS_AES_CTS:
- basemode = NSS_AES_CBC;
- break;
- case NSS_AES_GCM:
- case NSS_AES_CTR:
- basemode = NSS_AES;
- baseencrypt = PR_TRUE;
- break;
- }
- /* make sure enough is initializes so we can safely call Destroy */
- cx->worker_cx = NULL;
- cx->destroy = NULL;
- rv = aes_InitContext(cx, key, keysize, iv, basemode,
- baseencrypt, blocksize);
- if (rv != SECSuccess) {
- AES_DestroyContext(cx, PR_FALSE);
- return rv;
- }
-
- /* finally, set up any mode specific contexts */
- switch (mode) {
- case NSS_AES_CTS:
- cx->worker_cx = CTS_CreateContext(cx, cx->worker, iv, blocksize);
- cx->worker = (freeblCipherFunc)
- (encrypt ? CTS_EncryptUpdate : CTS_DecryptUpdate);
- cx->destroy = (freeblDestroyFunc) CTS_DestroyContext;
- cx->isBlock = PR_FALSE;
- break;
- case NSS_AES_GCM:
-#if USE_HW_AES
- if(use_hw_gcm) {
- cx->worker_cx = intel_AES_GCM_CreateContext(cx, cx->worker, iv, blocksize);
- cx->worker = (freeblCipherFunc)
- (encrypt ? intel_AES_GCM_EncryptUpdate : intel_AES_GCM_DecryptUpdate);
- cx->destroy = (freeblDestroyFunc) intel_AES_GCM_DestroyContext;
- cx->isBlock = PR_FALSE;
- } else
-#endif
- {
- cx->worker_cx = GCM_CreateContext(cx, cx->worker, iv, blocksize);
- cx->worker = (freeblCipherFunc)
- (encrypt ? GCM_EncryptUpdate : GCM_DecryptUpdate);
- cx->destroy = (freeblDestroyFunc) GCM_DestroyContext;
- cx->isBlock = PR_FALSE;
- }
- break;
- case NSS_AES_CTR:
- cx->worker_cx = CTR_CreateContext(cx, cx->worker, iv, blocksize);
- cx->worker = (freeblCipherFunc) CTR_Update ;
- cx->destroy = (freeblDestroyFunc) CTR_DestroyContext;
- cx->isBlock = PR_FALSE;
- break;
- default:
- /* everything has already been set up by aes_InitContext, just
- * return */
- return SECSuccess;
- }
- /* check to see if we succeeded in getting the worker context */
- if (cx->worker_cx == NULL) {
- /* no, just destroy the existing context */
- cx->destroy = NULL; /* paranoia, though you can see a dozen lines */
- /* below that this isn't necessary */
- AES_DestroyContext(cx, PR_FALSE);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/* AES_CreateContext
- *
- * create a new context for Rijndael operations
- */
-AESContext *
-AES_CreateContext(const unsigned char *key, const unsigned char *iv,
- int mode, int encrypt,
- unsigned int keysize, unsigned int blocksize)
-{
- AESContext *cx = AES_AllocateContext();
- if (cx) {
- SECStatus rv = AES_InitContext(cx, key, keysize, iv, mode, encrypt,
- blocksize);
- if (rv != SECSuccess) {
- AES_DestroyContext(cx, PR_TRUE);
- cx = NULL;
- }
- }
- return cx;
-}
-
-/*
- * AES_DestroyContext
- *
- * Zero an AES cipher context. If freeit is true, also free the pointer
- * to the context.
- */
-void
-AES_DestroyContext(AESContext *cx, PRBool freeit)
-{
- if (cx->worker_cx && cx->destroy) {
- (*cx->destroy)(cx->worker_cx, PR_TRUE);
- cx->worker_cx = NULL;
- cx->destroy = NULL;
- }
- if (freeit)
- PORT_Free(cx);
-}
-
-/*
- * AES_Encrypt
- *
- * Encrypt an arbitrary-length buffer. The output buffer must already be
- * allocated to at least inputLen.
- */
-SECStatus
-AES_Encrypt(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- int blocksize;
- /* Check args */
- if (cx == NULL || output == NULL || input == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- blocksize = 4 * cx->Nb;
- if (cx->isBlock && (inputLen % blocksize != 0)) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- *outputLen = inputLen;
- return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
- input, inputLen, blocksize);
-}
-
-/*
- * AES_Decrypt
- *
- * Decrypt and arbitrary-length buffer. The output buffer must already be
- * allocated to at least inputLen.
- */
-SECStatus
-AES_Decrypt(AESContext *cx, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- int blocksize;
- /* Check args */
- if (cx == NULL || output == NULL || input == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- blocksize = 4 * cx->Nb;
- if (cx->isBlock && (inputLen % blocksize != 0)) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- if (maxOutputLen < inputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- *outputLen = inputLen;
- return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
- input, inputLen, blocksize);
-}
diff --git a/security/nss/lib/freebl/rijndael.h b/security/nss/lib/freebl/rijndael.h
deleted file mode 100644
index 28ffb58fd..000000000
--- a/security/nss/lib/freebl/rijndael.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _RIJNDAEL_H_
-#define _RIJNDAEL_H_ 1
-
-#include "blapii.h"
-
-#define RIJNDAEL_MIN_BLOCKSIZE 16 /* bytes */
-#define RIJNDAEL_MAX_BLOCKSIZE 32 /* bytes */
-
-typedef SECStatus AESBlockFunc(AESContext *cx,
- unsigned char *output,
- const unsigned char *input);
-
-/* RIJNDAEL_NUM_ROUNDS
- *
- * Number of rounds per execution
- * Nk - number of key bytes
- * Nb - blocksize (in bytes)
- */
-#define RIJNDAEL_NUM_ROUNDS(Nk, Nb) \
- (PR_MAX(Nk, Nb) + 6)
-
-/* RIJNDAEL_MAX_STATE_SIZE
- *
- * Maximum number of bytes in the state (spec includes up to 256-bit block
- * size)
- */
-#define RIJNDAEL_MAX_STATE_SIZE 32
-
-/*
- * This magic number is (Nb_max * (Nr_max + 1))
- * where Nb_max is the maximum block size in 32-bit words,
- * Nr_max is the maximum number of rounds, which is Nb_max + 6
- */
-#define RIJNDAEL_MAX_EXP_KEY_SIZE (8 * 15)
-
-/* AESContextStr
- *
- * Values which maintain the state for Rijndael encryption/decryption.
- *
- * iv - initialization vector for CBC mode
- * Nb - the number of bytes in a block, specified by user
- * Nr - the number of rounds, specified by a table
- * expandedKey - the round keys in 4-byte words, the length is Nr * Nb
- * worker - the encryption/decryption function to use with worker_cx
- * destroy - if not NULL, the destroy function to use with worker_cx
- * worker_cx - the context for worker and destroy
- * isBlock - is the mode of operation a block cipher or a stream cipher?
- */
-struct AESContextStr
-{
- unsigned int Nb;
- unsigned int Nr;
- freeblCipherFunc worker;
- /* NOTE: The offsets of iv and expandedKey are hardcoded in intel-aes.s.
- * Don't add new members before them without updating intel-aes.s. */
- unsigned char iv[RIJNDAEL_MAX_BLOCKSIZE];
- PRUint32 expandedKey[RIJNDAEL_MAX_EXP_KEY_SIZE];
- freeblDestroyFunc destroy;
- void *worker_cx;
- PRBool isBlock;
-};
-
-#endif /* _RIJNDAEL_H_ */
diff --git a/security/nss/lib/freebl/rijndael32.tab b/security/nss/lib/freebl/rijndael32.tab
deleted file mode 100644
index 59be7c2c0..000000000
--- a/security/nss/lib/freebl/rijndael32.tab
+++ /dev/null
@@ -1,1219 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef RIJNDAEL_INCLUDE_TABLES
-static const PRUint8 _S[256] =
-{
- 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
-202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
-183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
- 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
- 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
- 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
-208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
- 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
-205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
- 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
-224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
-231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
-186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
-112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
-225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
-140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22
-};
-#endif /* not RIJNDAEL_INCLUDE_TABLES */
-
-static const PRUint8 _SInv[256] =
-{
- 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
-124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
- 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78,
- 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37,
-114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
-108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132,
-144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6,
-208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107,
- 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115,
-150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
- 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27,
-252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244,
- 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95,
- 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239,
-160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
- 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125
-};
-
-#ifdef RIJNDAEL_INCLUDE_TABLES
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _T0[256] =
-{
-0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6,
-0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
-0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f,
-0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
-0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453,
-0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
-0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551,
-0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
-0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637,
-0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
-0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d,
-0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
-0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd,
-0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
-0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d,
-0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
-0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a,
-0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
-0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d,
-0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
-0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5,
-0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
-0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755,
-0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
-0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54,
-0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
-0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264,
-0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
-0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531,
-0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
-0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac,
-0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
-0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657,
-0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
-0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c,
-0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
-0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199,
-0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
-0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c,
-0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
-0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7,
-0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
-0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
-};
-#else
-static const PRUint32 _T0[256] =
-{
-0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd,
-0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
-0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d,
-0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
-0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7,
-0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
-0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4,
-0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
-0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1,
-0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
-0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e,
-0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
-0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e,
-0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
-0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46,
-0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
-0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7,
-0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
-0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe,
-0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
-0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a,
-0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
-0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2,
-0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
-0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e,
-0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
-0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256,
-0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
-0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4,
-0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
-0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa,
-0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
-0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1,
-0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
-0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42,
-0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
-0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158,
-0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
-0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22,
-0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
-0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631,
-0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
-0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _T1[256] =
-{
-0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd,
-0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d,
-0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d,
-0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
-0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7,
-0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a,
-0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 0x3434685c, 0xa5a551f4,
-0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f,
-0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1,
-0x05050a0f, 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d,
-0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b, 0x83831d9e,
-0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb,
-0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e,
-0x2f2f5e71, 0x84841397, 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c,
-0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46,
-0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
-0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7,
-0x33336655, 0x85851194, 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81,
-0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe,
-0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
-0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a,
-0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f,
-0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2,
-0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695,
-0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e,
-0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c,
-0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, 0xe0e0db3b, 0x32326456,
-0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
-0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4,
-0xe4e4d337, 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7,
-0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa,
-0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018,
-0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1,
-0xb4b473c7, 0xc6c69751, 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21,
-0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42,
-0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12,
-0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958,
-0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233,
-0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22,
-0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
-0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731,
-0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11,
-0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a
-};
-#else
-static const PRUint32 _T1[256] =
-{
-0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b,
-0xb1de6f6f, 0x5491c5c5, 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b,
-0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676, 0x458fcaca, 0x9d1f8282,
-0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
-0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4,
-0x96e47272, 0x5b9bc0c0, 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
-0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc, 0x5c683434, 0xf451a5a5,
-0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
-0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696,
-0x0f0a0505, 0xb52f9a9a, 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
-0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575, 0x1b120909, 0x9e1d8383,
-0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
-0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3,
-0x715e2f2f, 0x97138484, 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded,
-0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b, 0xbed46a6a, 0x468dcbcb,
-0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
-0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d,
-0x55663333, 0x94118585, 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f,
-0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8, 0xf3a25151, 0xfe5da3a3,
-0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
-0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff,
-0x0efdf3f3, 0x6dbfd2d2, 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
-0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717, 0x5793c4c4, 0xf255a7a7,
-0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
-0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a,
-0xab3b9090, 0x830b8888, 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
-0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb, 0x3bdbe0e0, 0x56643232,
-0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
-0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595,
-0x37d3e4e4, 0x8bf27979, 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
-0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9, 0xb4d86c6c, 0xfaac5656,
-0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
-0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6,
-0xc773b4b4, 0x5197c6c6, 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
-0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a, 0x90e07070, 0x427c3e3e,
-0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
-0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1,
-0x273a1d1d, 0xb9279e9e, 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
-0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494, 0xb62d9b9b, 0x223c1e1e,
-0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
-0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6,
-0xc6844242, 0xb8d06868, 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
-0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _T2[256] =
-{
-0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b,
-0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b,
-0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82,
-0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
-0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4,
-0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26,
-0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 0x34685c34, 0xa551f4a5,
-0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15,
-0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196,
-0x050a0f05, 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2,
-0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09, 0x831d9e83,
-0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0,
-0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3,
-0x2f5e712f, 0x84139784, 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced,
-0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb,
-0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
-0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d,
-0x33665533, 0x85119485, 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f,
-0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3,
-0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
-0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff,
-0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec,
-0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7,
-0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573,
-0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a,
-0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14,
-0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, 0xe0db3be0, 0x32645632,
-0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
-0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495,
-0xe4d337e4, 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d,
-0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56,
-0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808,
-0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6,
-0xb473c7b4, 0xc69751c6, 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f,
-0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e,
-0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e,
-0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1,
-0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311,
-0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e,
-0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
-0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6,
-0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f,
-0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16
-};
-#else
-static const PRUint32 _T2[256] =
-{
-0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b,
-0x6fb1de6f, 0xc55491c5, 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b,
-0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76, 0xca458fca, 0x829d1f82,
-0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
-0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4,
-0x7296e472, 0xc05b9bc0, 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
-0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc, 0x345c6834, 0xa5f451a5,
-0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
-0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796,
-0x050f0a05, 0x9ab52f9a, 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
-0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75, 0x091b1209, 0x839e1d83,
-0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
-0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3,
-0x2f715e2f, 0x84971384, 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed,
-0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b, 0x6abed46a, 0xcb468dcb,
-0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
-0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d,
-0x33556633, 0x85941185, 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f,
-0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8, 0x51f3a251, 0xa3fe5da3,
-0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
-0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff,
-0xf30efdf3, 0xd26dbfd2, 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec,
-0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17, 0xc45793c4, 0xa7f255a7,
-0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
-0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a,
-0x90ab3b90, 0x88830b88, 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
-0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb, 0xe03bdbe0, 0x32566432,
-0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
-0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195,
-0xe437d3e4, 0x798bf279, 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
-0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9, 0x6cb4d86c, 0x56faac56,
-0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
-0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6,
-0xb4c773b4, 0xc65197c6, 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
-0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a, 0x7090e070, 0x3e427c3e,
-0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
-0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1,
-0x1d273a1d, 0x9eb9279e, 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
-0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394, 0x9bb62d9b, 0x1e223c1e,
-0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
-0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6,
-0x42c68442, 0x68b8d068, 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f,
-0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _T3[256] =
-{
-0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b,
-0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b,
-0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282,
-0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
-0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4,
-0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626,
-0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 0x685c3434, 0x51f4a5a5,
-0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515,
-0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696,
-0x0a0f0505, 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2,
-0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383,
-0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0,
-0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3,
-0x5e712f2f, 0x13978484, 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded,
-0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb,
-0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
-0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d,
-0x66553333, 0x11948585, 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f,
-0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3,
-0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
-0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff,
-0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec,
-0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7,
-0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373,
-0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a,
-0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414,
-0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 0xdb3be0e0, 0x64563232,
-0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
-0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595,
-0xd337e4e4, 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d,
-0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656,
-0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808,
-0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6,
-0x73c7b4b4, 0x9751c6c6, 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f,
-0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e,
-0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e,
-0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1,
-0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111,
-0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e,
-0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
-0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6,
-0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f,
-0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616
-};
-#else
-static const PRUint32 _T3[256] =
-{
-0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6,
-0x6f6fb1de, 0xc5c55491, 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56,
-0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec, 0xcaca458f, 0x82829d1f,
-0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
-0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753,
-0x727296e4, 0xc0c05b9b, 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
-0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83, 0x34345c68, 0xa5a5f451,
-0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
-0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137,
-0x05050f0a, 0x9a9ab52f, 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
-0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea, 0x09091b12, 0x83839e1d,
-0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
-0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd,
-0x2f2f715e, 0x84849713, 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1,
-0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6, 0x6a6abed4, 0xcbcb468d,
-0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
-0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a,
-0x33335566, 0x85859411, 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe,
-0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b, 0x5151f3a2, 0xa3a3fe5d,
-0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
-0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5,
-0xf3f30efd, 0xd2d26dbf, 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3,
-0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e, 0xc4c45793, 0xa7a7f255,
-0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
-0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54,
-0x9090ab3b, 0x8888830b, 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
-0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad, 0xe0e03bdb, 0x32325664,
-0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
-0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431,
-0xe4e437d3, 0x79798bf2, 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
-0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049, 0x6c6cb4d8, 0x5656faac,
-0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
-0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157,
-0xb4b4c773, 0xc6c65197, 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
-0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f, 0x707090e0, 0x3e3e427c,
-0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
-0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899,
-0x1d1d273a, 0x9e9eb927, 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
-0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733, 0x9b9bb62d, 0x1e1e223c,
-0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
-0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7,
-0x4242c684, 0x6868b8d0, 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e,
-0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _TInv0[256] =
-{
-0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f,
-0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5,
-0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de, 0x671bba25,
-0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
-0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458,
-0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927,
-0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5,
-0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
-0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72,
-0x578f1fe3, 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
-0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7,
-0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
-0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040,
-0x069f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d,
-0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6,
-0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
-0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32,
-0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36,
-0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793,
-0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
-0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2,
-0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3,
-0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb,
-0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
-0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc,
-0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947,
-0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9,
-0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
-0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890,
-0x5ef7392e, 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf,
-0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, 0xf418596e,
-0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,
-0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a,
-0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733,
-0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43,
-0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
-0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92,
-0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb,
-0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255,
-0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
-0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc,
-0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664,
-0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0
-};
-#else
-static const PRUint32 _TInv0[256] =
-{
-0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1,
-0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
-0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67,
-0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
-0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3,
-0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
-0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182,
-0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
-0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2,
-0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
-0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, 0x8acf1c2b, 0xa779b492,
-0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
-0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa,
-0x5e719f06, 0xbd6e1051, 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
-0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997,
-0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
-0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48,
-0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
-0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, 0x0c0a67b1, 0x9357e70f,
-0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
-0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad,
-0x2db6a8b9, 0x141ea9c8, 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
-0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc,
-0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
-0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3,
-0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
-0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1,
-0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
-0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8,
-0x2e39f75e, 0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
-0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4,
-0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
-0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331,
-0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
-0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 0x764dd68d, 0x43efb04d,
-0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
-0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252,
-0xe9105633, 0x6dd64713, 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
-0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f,
-0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
-0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c,
-0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
-0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _TInv1[256] =
-{
-0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, 0x6bab3bcb, 0x459d1ff1,
-0x58faacab, 0x03e34b93, 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525,
-0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, 0x5ab1de49, 0x1bba2567,
-0x0eea4598, 0xc0fe5de1, 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6,
-0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, 0x83bed42d, 0x217458d3,
-0x69e04929, 0xc8c98e44, 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd,
-0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, 0x4adf6318, 0x311ae582,
-0x33519760, 0x7f536245, 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994,
-0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, 0xd373ab23, 0x024b72e2,
-0x8f1fe357, 0xab55662a, 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5,
-0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, 0x1ccf8a2b, 0xb479a792,
-0xf207f3f0, 0xe2694ea1, 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a,
-0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, 0xec830b39, 0xef6040aa,
-0x9f715e06, 0x106ebd51, 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46,
-0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, 0xfb981924, 0xe9bdd697,
-0x434089cc, 0x9ed96777, 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db,
-0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000, 0x86800983, 0xed2b3248,
-0x70111eac, 0x725a6c4e, 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627,
-0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, 0x670a0cb1, 0xe757930f,
-0x96eeb4d2, 0x919b1b9e, 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16,
-0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, 0x0d090e0b, 0xc78bf2ad,
-0xa8b62db9, 0xa91e14c8, 0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd,
-0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, 0x29438b76, 0xc623cbdc,
-0xfcedb668, 0xf1e4b863, 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420,
-0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, 0x2f9e1d4b, 0x30b2dcf3,
-0x52860dec, 0xe3c177d0, 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722,
-0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, 0x4e4987c7, 0xd138d9c1,
-0xa2ca8cfe, 0x0bd49836, 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4,
-0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, 0x138df6c2, 0xb8d890e8,
-0xf7392e5e, 0xafc382f5, 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3,
-0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, 0x7826cd09, 0x18596ef4,
-0xb79aec01, 0x9a4f83a8, 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6,
-0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6, 0xb2a431af, 0x233f2a31,
-0x94a5c630, 0x66a235c0, 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315,
-0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, 0xd64d768d, 0xb0ef434d,
-0x4daacc54, 0x0496e4df, 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f,
-0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, 0x1d67b35a, 0xd2db9252,
-0x5610e933, 0x47d66d13, 0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89,
-0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, 0xdfd29c59, 0x73f2553f,
-0xce141879, 0x37c773bf, 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886,
-0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, 0xc31d1672, 0x25e2bc0c,
-0x493c288b, 0x950dff41, 0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490,
-0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042
-};
-#else
-static const PRUint32 _TInv1[256] =
-{
-0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45,
-0xabacfa58, 0x934be303, 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c,
-0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3, 0x49deb15a, 0x6725ba1b,
-0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
-0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421,
-0x2949e069, 0x448ec9c8, 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971,
-0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a, 0x1863df4a, 0x82e51a31,
-0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
-0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02,
-0x57e31f8f, 0x2a6655ab, 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708,
-0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682, 0x2b8acf1c, 0x92a779b4,
-0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
-0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef,
-0x065e719f, 0x51bd6e10, 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd,
-0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015, 0x241998fb, 0x97d6bde9,
-0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
-0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed,
-0xac1e1170, 0x4e6c5a72, 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39,
-0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e, 0xb10c0a67, 0x0f9357e7,
-0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
-0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7,
-0xb92db6a8, 0xc8141ea9, 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60,
-0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e, 0x768b4329, 0xdccb23c6,
-0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
-0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230,
-0xec0d8652, 0xd077c1e3, 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964,
-0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390, 0xc787494e, 0xc1d938d1,
-0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
-0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8,
-0x5e2e39f7, 0xf582c3af, 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512,
-0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb, 0x09cd2678, 0xf46e5918,
-0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
-0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23,
-0x30c6a594, 0xc035a266, 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8,
-0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6, 0x8d764dd6, 0x4d43efb0,
-0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
-0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2,
-0x33e91056, 0x136dd647, 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c,
-0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1, 0x599cd2df, 0x3f55f273,
-0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
-0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225,
-0x8b283c49, 0x41ff0d95, 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,
-0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _TInv2[256] =
-{
-0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, 0xab3bcb6b, 0x9d1ff145,
-0xfaacab58, 0xe34b9303, 0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c,
-0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, 0xb1de495a, 0xba25671b,
-0xea45980e, 0xfe5de1c0, 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9,
-0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, 0xbed42d83, 0x7458d321,
-0xe0492969, 0xc98e44c8, 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71,
-0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, 0xdf63184a, 0x1ae58231,
-0x51976033, 0x5362457f, 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b,
-0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, 0x73ab23d3, 0x4b72e202,
-0x1fe3578f, 0x55662aab, 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508,
-0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82, 0xcf8a2b1c, 0x79a792b4,
-0x07f3f0f2, 0x694ea1e2, 0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe,
-0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, 0x830b39ec, 0x6040aaef,
-0x715e069f, 0x6ebd5110, 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd,
-0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15, 0x981924fb, 0xbdd697e9,
-0x4089cc43, 0xd967779e, 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee,
-0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000, 0x80098386, 0x2b3248ed,
-0x111eac70, 0x5a6c4e72, 0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739,
-0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, 0x0a0cb167, 0x57930fe7,
-0xeeb4d296, 0x9b1b9e91, 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a,
-0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, 0x090e0b0d, 0x8bf2adc7,
-0xb62db9a8, 0x1e14c8a9, 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60,
-0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, 0x438b7629, 0x23cbdcc6,
-0xedb668fc, 0xe4b863f1, 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011,
-0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, 0x9e1d4b2f, 0xb2dcf330,
-0x860dec52, 0xc177d0e3, 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264,
-0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, 0x4987c74e, 0x38d9c1d1,
-0xca8cfea2, 0xd498360b, 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf,
-0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, 0x8df6c213, 0xd890e8b8,
-0x392e5ef7, 0xc382f5af, 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312,
-0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, 0x26cd0978, 0x596ef418,
-0x9aec01b7, 0x4f83a89a, 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8,
-0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, 0xa431afb2, 0x3f2a3123,
-0xa5c63094, 0xa235c066, 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8,
-0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, 0x4d768dd6, 0xef434db0,
-0xaacc544d, 0x96e4df04, 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51,
-0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, 0x67b35a1d, 0xdb9252d2,
-0x10e93356, 0xd66d1347, 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c,
-0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, 0xd29c59df, 0xf2553f73,
-0x141879ce, 0xc773bf37, 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db,
-0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, 0x1d1672c3, 0xe2bc0c25,
-0x3c288b49, 0x0dff4195, 0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1,
-0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257
-};
-#else
-static const PRUint32 _TInv2[256] =
-{
-0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d,
-0x58abacfa, 0x03934be3, 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502,
-0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562, 0x5a49deb1, 0x1b6725ba,
-0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
-0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874,
-0x692949e0, 0xc8448ec9, 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9,
-0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce, 0x4a1863df, 0x3182e51a,
-0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
-0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b,
-0x8f57e31f, 0xab2a6655, 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337,
-0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16, 0x1c2b8acf, 0xb492a779,
-0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
-0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060,
-0x9f065e71, 0x1051bd6e, 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6,
-0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050, 0xfb241998, 0xe997d6bd,
-0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
-0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b,
-0x70ac1e11, 0x724e6c5a, 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d,
-0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436, 0x67b10c0a, 0xe70f9357,
-0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
-0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b,
-0xa8b92db6, 0xa9c8141e, 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f,
-0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb, 0x29768b43, 0xc6dccb23,
-0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
-0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2,
-0x52ec0d86, 0xe3d077c1, 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9,
-0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233, 0x4ec78749, 0xd1c1d938,
-0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
-0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8,
-0xf75e2e39, 0xaff582c3, 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25,
-0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b, 0x7809cd26, 0x18f46e59,
-0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
-0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f,
-0x9430c6a5, 0x66c035a2, 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7,
-0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791, 0xd68d764d, 0xb04d43ef,
-0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
-0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db,
-0x5633e910, 0x47136dd6, 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13,
-0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47, 0xdf599cd2, 0x733f55f2,
-0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
-0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2,
-0x498b283c, 0x9541ff0d, 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,
-0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _TInv3[256] =
-{
-0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, 0x3bcb6bab, 0x1ff1459d,
-0xacab58fa, 0x4b9303e3, 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02,
-0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, 0xde495ab1, 0x25671bba,
-0x45980eea, 0x5de1c0fe, 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3,
-0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, 0xd42d83be, 0x58d32174,
-0x492969e0, 0x8e44c8c9, 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9,
-0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, 0x63184adf, 0xe582311a,
-0x97603351, 0x62457f53, 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08,
-0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, 0xab23d373, 0x72e2024b,
-0xe3578f1f, 0x662aab55, 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837,
-0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, 0x8a2b1ccf, 0xa792b479,
-0xf3f0f207, 0x4ea1e269, 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6,
-0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, 0x0b39ec83, 0x40aaef60,
-0x5e069f71, 0xbd51106e, 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6,
-0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550, 0x1924fb98, 0xd697e9bd,
-0x89cc4340, 0x67779ed9, 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8,
-0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, 0x09838680, 0x3248ed2b,
-0x1eac7011, 0x6c4e725a, 0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d,
-0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, 0x0cb1670a, 0x930fe757,
-0xb4d296ee, 0x1b9e919b, 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12,
-0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, 0x0e0b0d09, 0xf2adc78b,
-0x2db9a8b6, 0x14c8a91e, 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f,
-0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, 0x8b762943, 0xcbdcc623,
-0xb668fced, 0xb863f1e4, 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6,
-0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, 0x1d4b2f9e, 0xdcf330b2,
-0x0dec5286, 0x77d0e3c1, 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9,
-0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, 0x87c74e49, 0xd9c1d138,
-0x8cfea2ca, 0x98360bd4, 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad,
-0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, 0xf6c2138d, 0x90e8b8d8,
-0x2e5ef739, 0x82f5afc3, 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225,
-0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, 0xcd097826, 0x6ef41859,
-0xec01b79a, 0x83a89a4f, 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815,
-0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, 0x31afb2a4, 0x2a31233f,
-0xc63094a5, 0x35c066a2, 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7,
-0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, 0x768dd64d, 0x434db0ef,
-0xcc544daa, 0xe4df0496, 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165,
-0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, 0xb35a1d67, 0x9252d2db,
-0xe9335610, 0x6d1347d6, 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13,
-0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, 0x9c59dfd2, 0x553f73f2,
-0x1879ce14, 0x73bf37c7, 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
-0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, 0x1672c31d, 0xbc0c25e2,
-0x288b493c, 0xff41950d, 0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156,
-0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8
-};
-#else
-static const PRUint32 _TInv3[256] =
-{
-0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f,
-0xfa58abac, 0xe303934b, 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5,
-0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, 0xb15a49de, 0xba1b6725,
-0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
-0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358,
-0xe0692949, 0xc9c8448e, 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27,
-0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, 0xdf4a1863, 0x1a3182e5,
-0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
-0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272,
-0x1f8f57e3, 0x55ab2a66, 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3,
-0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced, 0xcf1c2b8a, 0x79b492a7,
-0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
-0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40,
-0x719f065e, 0x6e1051bd, 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d,
-0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60, 0x98fb2419, 0xbde997d6,
-0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
-0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832,
-0x1170ac1e, 0x5a724e6c, 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736,
-0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, 0x0a67b10c, 0x57e70f93,
-0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
-0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2,
-0xb6a8b92d, 0x1ea9c814, 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3,
-0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, 0x4329768b, 0x23c6dccb,
-0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
-0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc,
-0x8652ec0d, 0xc1e3d077, 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247,
-0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, 0x494ec787, 0x38d1c1d9,
-0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
-0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890,
-0x39f75e2e, 0xc3aff582, 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf,
-0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, 0x267809cd, 0x5918f46e,
-0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
-0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a,
-0xa59430c6, 0xa266c035, 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533,
-0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, 0x4dd68d76, 0xefb04d43,
-0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
-0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292,
-0x105633e9, 0xd647136d, 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb,
-0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, 0xd2df599c, 0xf2733f55,
-0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
-0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc,
-0x3c498b28, 0x0d9541ff, 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064,
-0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _IMXC0[256] =
-{
-0x00000000, 0x0b0d090e, 0x161a121c, 0x1d171b12, 0x2c342438, 0x27392d36,
-0x3a2e3624, 0x31233f2a, 0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362,
-0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a, 0xb0d090e0, 0xbbdd99ee,
-0xa6ca82fc, 0xadc78bf2, 0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca,
-0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382, 0xc48cfca8, 0xcf81f5a6,
-0xd296eeb4, 0xd99be7ba, 0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9,
-0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1, 0x23d373ab, 0x28de7aa5,
-0x35c961b7, 0x3ec468b9, 0x0fe75793, 0x04ea5e9d, 0x19fd458f, 0x12f04c81,
-0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029, 0xe75f8f03, 0xec52860d,
-0xf1459d1f, 0xfa489411, 0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859,
-0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61, 0xf66d76ad, 0xfd607fa3,
-0xe07764b1, 0xeb7a6dbf, 0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987,
-0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf, 0x82311ae5, 0x893c13eb,
-0x942b08f9, 0x9f2601f7, 0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f,
-0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967, 0x1ed5ae3d, 0x15d8a733,
-0x08cfbc21, 0x03c2b52f, 0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117,
-0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664, 0xa1e2694e, 0xaaef6040,
-0xb7f87b52, 0xbcf5725c, 0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14,
-0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c, 0x3d06dd96, 0x360bd498,
-0x2b1ccf8a, 0x2011c684, 0x1132f9ae, 0x1a3ff0a0, 0x0728ebb2, 0x0c25e2bc,
-0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4, 0x495ab1de, 0x4257b8d0,
-0x5f40a3c2, 0x544daacc, 0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753,
-0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b, 0xafb2a431, 0xa4bfad3f,
-0xb9a8b62d, 0xb2a5bf23, 0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b,
-0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3, 0x6b3e5899, 0x60335197,
-0x7d244a85, 0x7629438b, 0x1f6234d1, 0x146f3ddf, 0x097826cd, 0x02752fc3,
-0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb, 0x8c61d79a, 0x876cde94,
-0x9a7bc586, 0x9176cc88, 0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0,
-0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8, 0xf83dbbd2, 0xf330b2dc,
-0xee27a9ce, 0xe52aa0c0, 0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68,
-0x10856342, 0x1b886a4c, 0x069f715e, 0x0d927850, 0x64d90f0a, 0x6fd40604,
-0x72c31d16, 0x79ce1418, 0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020,
-0x01b79aec, 0x0aba93e2, 0x17ad88f0, 0x1ca081fe, 0x2d83bed4, 0x268eb7da,
-0x3b99acc8, 0x3094a5c6, 0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e,
-0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6, 0xb1670a0c, 0xba6a0302,
-0xa77d1810, 0xac70111e, 0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526,
-0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e, 0xc53b6644, 0xce366f4a,
-0xd3217458, 0xd82c7d56, 0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25,
-0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d, 0x2264e947, 0x2969e049,
-0x347efb5b, 0x3f73f255, 0x0e50cd7f, 0x055dc471, 0x184adf63, 0x1347d66d,
-0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5, 0xe6e815ef, 0xede51ce1,
-0xf0f207f3, 0xfbff0efd, 0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
-0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d
-};
-#else
-static const PRUint32 _IMXC0[256] =
-{
-0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927,
-0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45,
-0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb,
-0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381,
-0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf,
-0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66,
-0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28,
-0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012,
-0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec,
-0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e,
-0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd,
-0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7,
-0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89,
-0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b,
-0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815,
-0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f,
-0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa,
-0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8,
-0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36,
-0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c,
-0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742,
-0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea,
-0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4,
-0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e,
-0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360,
-0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502,
-0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87,
-0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd,
-0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3,
-0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621,
-0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f,
-0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55,
-0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26,
-0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844,
-0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba,
-0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480,
-0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce,
-0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67,
-0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929,
-0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713,
-0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed,
-0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f,
-0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _IMXC1[256] =
-{
-0x00000000, 0x0d090e0b, 0x1a121c16, 0x171b121d, 0x3424382c, 0x392d3627,
-0x2e36243a, 0x233f2a31, 0x68487058, 0x65417e53, 0x725a6c4e, 0x7f536245,
-0x5c6c4874, 0x5165467f, 0x467e5462, 0x4b775a69, 0xd090e0b0, 0xdd99eebb,
-0xca82fca6, 0xc78bf2ad, 0xe4b4d89c, 0xe9bdd697, 0xfea6c48a, 0xf3afca81,
-0xb8d890e8, 0xb5d19ee3, 0xa2ca8cfe, 0xafc382f5, 0x8cfca8c4, 0x81f5a6cf,
-0x96eeb4d2, 0x9be7bad9, 0xbb3bdb7b, 0xb632d570, 0xa129c76d, 0xac20c966,
-0x8f1fe357, 0x8216ed5c, 0x950dff41, 0x9804f14a, 0xd373ab23, 0xde7aa528,
-0xc961b735, 0xc468b93e, 0xe757930f, 0xea5e9d04, 0xfd458f19, 0xf04c8112,
-0x6bab3bcb, 0x66a235c0, 0x71b927dd, 0x7cb029d6, 0x5f8f03e7, 0x52860dec,
-0x459d1ff1, 0x489411fa, 0x03e34b93, 0x0eea4598, 0x19f15785, 0x14f8598e,
-0x37c773bf, 0x3ace7db4, 0x2dd56fa9, 0x20dc61a2, 0x6d76adf6, 0x607fa3fd,
-0x7764b1e0, 0x7a6dbfeb, 0x595295da, 0x545b9bd1, 0x434089cc, 0x4e4987c7,
-0x053eddae, 0x0837d3a5, 0x1f2cc1b8, 0x1225cfb3, 0x311ae582, 0x3c13eb89,
-0x2b08f994, 0x2601f79f, 0xbde64d46, 0xb0ef434d, 0xa7f45150, 0xaafd5f5b,
-0x89c2756a, 0x84cb7b61, 0x93d0697c, 0x9ed96777, 0xd5ae3d1e, 0xd8a73315,
-0xcfbc2108, 0xc2b52f03, 0xe18a0532, 0xec830b39, 0xfb981924, 0xf691172f,
-0xd64d768d, 0xdb447886, 0xcc5f6a9b, 0xc1566490, 0xe2694ea1, 0xef6040aa,
-0xf87b52b7, 0xf5725cbc, 0xbe0506d5, 0xb30c08de, 0xa4171ac3, 0xa91e14c8,
-0x8a213ef9, 0x872830f2, 0x903322ef, 0x9d3a2ce4, 0x06dd963d, 0x0bd49836,
-0x1ccf8a2b, 0x11c68420, 0x32f9ae11, 0x3ff0a01a, 0x28ebb207, 0x25e2bc0c,
-0x6e95e665, 0x639ce86e, 0x7487fa73, 0x798ef478, 0x5ab1de49, 0x57b8d042,
-0x40a3c25f, 0x4daacc54, 0xdaec41f7, 0xd7e54ffc, 0xc0fe5de1, 0xcdf753ea,
-0xeec879db, 0xe3c177d0, 0xf4da65cd, 0xf9d36bc6, 0xb2a431af, 0xbfad3fa4,
-0xa8b62db9, 0xa5bf23b2, 0x86800983, 0x8b890788, 0x9c921595, 0x919b1b9e,
-0x0a7ca147, 0x0775af4c, 0x106ebd51, 0x1d67b35a, 0x3e58996b, 0x33519760,
-0x244a857d, 0x29438b76, 0x6234d11f, 0x6f3ddf14, 0x7826cd09, 0x752fc302,
-0x5610e933, 0x5b19e738, 0x4c02f525, 0x410bfb2e, 0x61d79a8c, 0x6cde9487,
-0x7bc5869a, 0x76cc8891, 0x55f3a2a0, 0x58faacab, 0x4fe1beb6, 0x42e8b0bd,
-0x099fead4, 0x0496e4df, 0x138df6c2, 0x1e84f8c9, 0x3dbbd2f8, 0x30b2dcf3,
-0x27a9ceee, 0x2aa0c0e5, 0xb1477a3c, 0xbc4e7437, 0xab55662a, 0xa65c6821,
-0x85634210, 0x886a4c1b, 0x9f715e06, 0x9278500d, 0xd90f0a64, 0xd406046f,
-0xc31d1672, 0xce141879, 0xed2b3248, 0xe0223c43, 0xf7392e5e, 0xfa302055,
-0xb79aec01, 0xba93e20a, 0xad88f017, 0xa081fe1c, 0x83bed42d, 0x8eb7da26,
-0x99acc83b, 0x94a5c630, 0xdfd29c59, 0xd2db9252, 0xc5c0804f, 0xc8c98e44,
-0xebf6a475, 0xe6ffaa7e, 0xf1e4b863, 0xfcedb668, 0x670a0cb1, 0x6a0302ba,
-0x7d1810a7, 0x70111eac, 0x532e349d, 0x5e273a96, 0x493c288b, 0x44352680,
-0x0f427ce9, 0x024b72e2, 0x155060ff, 0x18596ef4, 0x3b6644c5, 0x366f4ace,
-0x217458d3, 0x2c7d56d8, 0x0ca1377a, 0x01a83971, 0x16b32b6c, 0x1bba2567,
-0x38850f56, 0x358c015d, 0x22971340, 0x2f9e1d4b, 0x64e94722, 0x69e04929,
-0x7efb5b34, 0x73f2553f, 0x50cd7f0e, 0x5dc47105, 0x4adf6318, 0x47d66d13,
-0xdc31d7ca, 0xd138d9c1, 0xc623cbdc, 0xcb2ac5d7, 0xe815efe6, 0xe51ce1ed,
-0xf207f3f0, 0xff0efdfb, 0xb479a792, 0xb970a999, 0xae6bbb84, 0xa362b58f,
-0x805d9fbe, 0x8d5491b5, 0x9a4f83a8, 0x97468da3
-};
-#else
-static const PRUint32 _IMXC1[256] =
-{
-0x00000000, 0x0b0e090d, 0x161c121a, 0x1d121b17, 0x2c382434, 0x27362d39,
-0x3a24362e, 0x312a3f23, 0x58704868, 0x537e4165, 0x4e6c5a72, 0x4562537f,
-0x74486c5c, 0x7f466551, 0x62547e46, 0x695a774b, 0xb0e090d0, 0xbbee99dd,
-0xa6fc82ca, 0xadf28bc7, 0x9cd8b4e4, 0x97d6bde9, 0x8ac4a6fe, 0x81caaff3,
-0xe890d8b8, 0xe39ed1b5, 0xfe8ccaa2, 0xf582c3af, 0xc4a8fc8c, 0xcfa6f581,
-0xd2b4ee96, 0xd9bae79b, 0x7bdb3bbb, 0x70d532b6, 0x6dc729a1, 0x66c920ac,
-0x57e31f8f, 0x5ced1682, 0x41ff0d95, 0x4af10498, 0x23ab73d3, 0x28a57ade,
-0x35b761c9, 0x3eb968c4, 0x0f9357e7, 0x049d5eea, 0x198f45fd, 0x12814cf0,
-0xcb3bab6b, 0xc035a266, 0xdd27b971, 0xd629b07c, 0xe7038f5f, 0xec0d8652,
-0xf11f9d45, 0xfa119448, 0x934be303, 0x9845ea0e, 0x8557f119, 0x8e59f814,
-0xbf73c737, 0xb47dce3a, 0xa96fd52d, 0xa261dc20, 0xf6ad766d, 0xfda37f60,
-0xe0b16477, 0xebbf6d7a, 0xda955259, 0xd19b5b54, 0xcc894043, 0xc787494e,
-0xaedd3e05, 0xa5d33708, 0xb8c12c1f, 0xb3cf2512, 0x82e51a31, 0x89eb133c,
-0x94f9082b, 0x9ff70126, 0x464de6bd, 0x4d43efb0, 0x5051f4a7, 0x5b5ffdaa,
-0x6a75c289, 0x617bcb84, 0x7c69d093, 0x7767d99e, 0x1e3daed5, 0x1533a7d8,
-0x0821bccf, 0x032fb5c2, 0x32058ae1, 0x390b83ec, 0x241998fb, 0x2f1791f6,
-0x8d764dd6, 0x867844db, 0x9b6a5fcc, 0x906456c1, 0xa14e69e2, 0xaa4060ef,
-0xb7527bf8, 0xbc5c72f5, 0xd50605be, 0xde080cb3, 0xc31a17a4, 0xc8141ea9,
-0xf93e218a, 0xf2302887, 0xef223390, 0xe42c3a9d, 0x3d96dd06, 0x3698d40b,
-0x2b8acf1c, 0x2084c611, 0x11aef932, 0x1aa0f03f, 0x07b2eb28, 0x0cbce225,
-0x65e6956e, 0x6ee89c63, 0x73fa8774, 0x78f48e79, 0x49deb15a, 0x42d0b857,
-0x5fc2a340, 0x54ccaa4d, 0xf741ecda, 0xfc4fe5d7, 0xe15dfec0, 0xea53f7cd,
-0xdb79c8ee, 0xd077c1e3, 0xcd65daf4, 0xc66bd3f9, 0xaf31a4b2, 0xa43fadbf,
-0xb92db6a8, 0xb223bfa5, 0x83098086, 0x8807898b, 0x9515929c, 0x9e1b9b91,
-0x47a17c0a, 0x4caf7507, 0x51bd6e10, 0x5ab3671d, 0x6b99583e, 0x60975133,
-0x7d854a24, 0x768b4329, 0x1fd13462, 0x14df3d6f, 0x09cd2678, 0x02c32f75,
-0x33e91056, 0x38e7195b, 0x25f5024c, 0x2efb0b41, 0x8c9ad761, 0x8794de6c,
-0x9a86c57b, 0x9188cc76, 0xa0a2f355, 0xabacfa58, 0xb6bee14f, 0xbdb0e842,
-0xd4ea9f09, 0xdfe49604, 0xc2f68d13, 0xc9f8841e, 0xf8d2bb3d, 0xf3dcb230,
-0xeecea927, 0xe5c0a02a, 0x3c7a47b1, 0x37744ebc, 0x2a6655ab, 0x21685ca6,
-0x10426385, 0x1b4c6a88, 0x065e719f, 0x0d507892, 0x640a0fd9, 0x6f0406d4,
-0x72161dc3, 0x791814ce, 0x48322bed, 0x433c22e0, 0x5e2e39f7, 0x552030fa,
-0x01ec9ab7, 0x0ae293ba, 0x17f088ad, 0x1cfe81a0, 0x2dd4be83, 0x26dab78e,
-0x3bc8ac99, 0x30c6a594, 0x599cd2df, 0x5292dbd2, 0x4f80c0c5, 0x448ec9c8,
-0x75a4f6eb, 0x7eaaffe6, 0x63b8e4f1, 0x68b6edfc, 0xb10c0a67, 0xba02036a,
-0xa710187d, 0xac1e1170, 0x9d342e53, 0x963a275e, 0x8b283c49, 0x80263544,
-0xe97c420f, 0xe2724b02, 0xff605015, 0xf46e5918, 0xc544663b, 0xce4a6f36,
-0xd3587421, 0xd8567d2c, 0x7a37a10c, 0x7139a801, 0x6c2bb316, 0x6725ba1b,
-0x560f8538, 0x5d018c35, 0x40139722, 0x4b1d9e2f, 0x2247e964, 0x2949e069,
-0x345bfb7e, 0x3f55f273, 0x0e7fcd50, 0x0571c45d, 0x1863df4a, 0x136dd647,
-0xcad731dc, 0xc1d938d1, 0xdccb23c6, 0xd7c52acb, 0xe6ef15e8, 0xede11ce5,
-0xf0f307f2, 0xfbfd0eff, 0x92a779b4, 0x99a970b9, 0x84bb6bae, 0x8fb562a3,
-0xbe9f5d80, 0xb591548d, 0xa8834f9a, 0xa38d4697
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _IMXC2[256] =
-{
-0x00000000, 0x090e0b0d, 0x121c161a, 0x1b121d17, 0x24382c34, 0x2d362739,
-0x36243a2e, 0x3f2a3123, 0x48705868, 0x417e5365, 0x5a6c4e72, 0x5362457f,
-0x6c48745c, 0x65467f51, 0x7e546246, 0x775a694b, 0x90e0b0d0, 0x99eebbdd,
-0x82fca6ca, 0x8bf2adc7, 0xb4d89ce4, 0xbdd697e9, 0xa6c48afe, 0xafca81f3,
-0xd890e8b8, 0xd19ee3b5, 0xca8cfea2, 0xc382f5af, 0xfca8c48c, 0xf5a6cf81,
-0xeeb4d296, 0xe7bad99b, 0x3bdb7bbb, 0x32d570b6, 0x29c76da1, 0x20c966ac,
-0x1fe3578f, 0x16ed5c82, 0x0dff4195, 0x04f14a98, 0x73ab23d3, 0x7aa528de,
-0x61b735c9, 0x68b93ec4, 0x57930fe7, 0x5e9d04ea, 0x458f19fd, 0x4c8112f0,
-0xab3bcb6b, 0xa235c066, 0xb927dd71, 0xb029d67c, 0x8f03e75f, 0x860dec52,
-0x9d1ff145, 0x9411fa48, 0xe34b9303, 0xea45980e, 0xf1578519, 0xf8598e14,
-0xc773bf37, 0xce7db43a, 0xd56fa92d, 0xdc61a220, 0x76adf66d, 0x7fa3fd60,
-0x64b1e077, 0x6dbfeb7a, 0x5295da59, 0x5b9bd154, 0x4089cc43, 0x4987c74e,
-0x3eddae05, 0x37d3a508, 0x2cc1b81f, 0x25cfb312, 0x1ae58231, 0x13eb893c,
-0x08f9942b, 0x01f79f26, 0xe64d46bd, 0xef434db0, 0xf45150a7, 0xfd5f5baa,
-0xc2756a89, 0xcb7b6184, 0xd0697c93, 0xd967779e, 0xae3d1ed5, 0xa73315d8,
-0xbc2108cf, 0xb52f03c2, 0x8a0532e1, 0x830b39ec, 0x981924fb, 0x91172ff6,
-0x4d768dd6, 0x447886db, 0x5f6a9bcc, 0x566490c1, 0x694ea1e2, 0x6040aaef,
-0x7b52b7f8, 0x725cbcf5, 0x0506d5be, 0x0c08deb3, 0x171ac3a4, 0x1e14c8a9,
-0x213ef98a, 0x2830f287, 0x3322ef90, 0x3a2ce49d, 0xdd963d06, 0xd498360b,
-0xcf8a2b1c, 0xc6842011, 0xf9ae1132, 0xf0a01a3f, 0xebb20728, 0xe2bc0c25,
-0x95e6656e, 0x9ce86e63, 0x87fa7374, 0x8ef47879, 0xb1de495a, 0xb8d04257,
-0xa3c25f40, 0xaacc544d, 0xec41f7da, 0xe54ffcd7, 0xfe5de1c0, 0xf753eacd,
-0xc879dbee, 0xc177d0e3, 0xda65cdf4, 0xd36bc6f9, 0xa431afb2, 0xad3fa4bf,
-0xb62db9a8, 0xbf23b2a5, 0x80098386, 0x8907888b, 0x9215959c, 0x9b1b9e91,
-0x7ca1470a, 0x75af4c07, 0x6ebd5110, 0x67b35a1d, 0x58996b3e, 0x51976033,
-0x4a857d24, 0x438b7629, 0x34d11f62, 0x3ddf146f, 0x26cd0978, 0x2fc30275,
-0x10e93356, 0x19e7385b, 0x02f5254c, 0x0bfb2e41, 0xd79a8c61, 0xde94876c,
-0xc5869a7b, 0xcc889176, 0xf3a2a055, 0xfaacab58, 0xe1beb64f, 0xe8b0bd42,
-0x9fead409, 0x96e4df04, 0x8df6c213, 0x84f8c91e, 0xbbd2f83d, 0xb2dcf330,
-0xa9ceee27, 0xa0c0e52a, 0x477a3cb1, 0x4e7437bc, 0x55662aab, 0x5c6821a6,
-0x63421085, 0x6a4c1b88, 0x715e069f, 0x78500d92, 0x0f0a64d9, 0x06046fd4,
-0x1d1672c3, 0x141879ce, 0x2b3248ed, 0x223c43e0, 0x392e5ef7, 0x302055fa,
-0x9aec01b7, 0x93e20aba, 0x88f017ad, 0x81fe1ca0, 0xbed42d83, 0xb7da268e,
-0xacc83b99, 0xa5c63094, 0xd29c59df, 0xdb9252d2, 0xc0804fc5, 0xc98e44c8,
-0xf6a475eb, 0xffaa7ee6, 0xe4b863f1, 0xedb668fc, 0x0a0cb167, 0x0302ba6a,
-0x1810a77d, 0x111eac70, 0x2e349d53, 0x273a965e, 0x3c288b49, 0x35268044,
-0x427ce90f, 0x4b72e202, 0x5060ff15, 0x596ef418, 0x6644c53b, 0x6f4ace36,
-0x7458d321, 0x7d56d82c, 0xa1377a0c, 0xa8397101, 0xb32b6c16, 0xba25671b,
-0x850f5638, 0x8c015d35, 0x97134022, 0x9e1d4b2f, 0xe9472264, 0xe0492969,
-0xfb5b347e, 0xf2553f73, 0xcd7f0e50, 0xc471055d, 0xdf63184a, 0xd66d1347,
-0x31d7cadc, 0x38d9c1d1, 0x23cbdcc6, 0x2ac5d7cb, 0x15efe6e8, 0x1ce1ede5,
-0x07f3f0f2, 0x0efdfbff, 0x79a792b4, 0x70a999b9, 0x6bbb84ae, 0x62b58fa3,
-0x5d9fbe80, 0x5491b58d, 0x4f83a89a, 0x468da397
-};
-#else
-static const PRUint32 _IMXC2[256] =
-{
-0x00000000, 0x0d0b0e09, 0x1a161c12, 0x171d121b, 0x342c3824, 0x3927362d,
-0x2e3a2436, 0x23312a3f, 0x68587048, 0x65537e41, 0x724e6c5a, 0x7f456253,
-0x5c74486c, 0x517f4665, 0x4662547e, 0x4b695a77, 0xd0b0e090, 0xddbbee99,
-0xcaa6fc82, 0xc7adf28b, 0xe49cd8b4, 0xe997d6bd, 0xfe8ac4a6, 0xf381caaf,
-0xb8e890d8, 0xb5e39ed1, 0xa2fe8cca, 0xaff582c3, 0x8cc4a8fc, 0x81cfa6f5,
-0x96d2b4ee, 0x9bd9bae7, 0xbb7bdb3b, 0xb670d532, 0xa16dc729, 0xac66c920,
-0x8f57e31f, 0x825ced16, 0x9541ff0d, 0x984af104, 0xd323ab73, 0xde28a57a,
-0xc935b761, 0xc43eb968, 0xe70f9357, 0xea049d5e, 0xfd198f45, 0xf012814c,
-0x6bcb3bab, 0x66c035a2, 0x71dd27b9, 0x7cd629b0, 0x5fe7038f, 0x52ec0d86,
-0x45f11f9d, 0x48fa1194, 0x03934be3, 0x0e9845ea, 0x198557f1, 0x148e59f8,
-0x37bf73c7, 0x3ab47dce, 0x2da96fd5, 0x20a261dc, 0x6df6ad76, 0x60fda37f,
-0x77e0b164, 0x7aebbf6d, 0x59da9552, 0x54d19b5b, 0x43cc8940, 0x4ec78749,
-0x05aedd3e, 0x08a5d337, 0x1fb8c12c, 0x12b3cf25, 0x3182e51a, 0x3c89eb13,
-0x2b94f908, 0x269ff701, 0xbd464de6, 0xb04d43ef, 0xa75051f4, 0xaa5b5ffd,
-0x896a75c2, 0x84617bcb, 0x937c69d0, 0x9e7767d9, 0xd51e3dae, 0xd81533a7,
-0xcf0821bc, 0xc2032fb5, 0xe132058a, 0xec390b83, 0xfb241998, 0xf62f1791,
-0xd68d764d, 0xdb867844, 0xcc9b6a5f, 0xc1906456, 0xe2a14e69, 0xefaa4060,
-0xf8b7527b, 0xf5bc5c72, 0xbed50605, 0xb3de080c, 0xa4c31a17, 0xa9c8141e,
-0x8af93e21, 0x87f23028, 0x90ef2233, 0x9de42c3a, 0x063d96dd, 0x0b3698d4,
-0x1c2b8acf, 0x112084c6, 0x3211aef9, 0x3f1aa0f0, 0x2807b2eb, 0x250cbce2,
-0x6e65e695, 0x636ee89c, 0x7473fa87, 0x7978f48e, 0x5a49deb1, 0x5742d0b8,
-0x405fc2a3, 0x4d54ccaa, 0xdaf741ec, 0xd7fc4fe5, 0xc0e15dfe, 0xcdea53f7,
-0xeedb79c8, 0xe3d077c1, 0xf4cd65da, 0xf9c66bd3, 0xb2af31a4, 0xbfa43fad,
-0xa8b92db6, 0xa5b223bf, 0x86830980, 0x8b880789, 0x9c951592, 0x919e1b9b,
-0x0a47a17c, 0x074caf75, 0x1051bd6e, 0x1d5ab367, 0x3e6b9958, 0x33609751,
-0x247d854a, 0x29768b43, 0x621fd134, 0x6f14df3d, 0x7809cd26, 0x7502c32f,
-0x5633e910, 0x5b38e719, 0x4c25f502, 0x412efb0b, 0x618c9ad7, 0x6c8794de,
-0x7b9a86c5, 0x769188cc, 0x55a0a2f3, 0x58abacfa, 0x4fb6bee1, 0x42bdb0e8,
-0x09d4ea9f, 0x04dfe496, 0x13c2f68d, 0x1ec9f884, 0x3df8d2bb, 0x30f3dcb2,
-0x27eecea9, 0x2ae5c0a0, 0xb13c7a47, 0xbc37744e, 0xab2a6655, 0xa621685c,
-0x85104263, 0x881b4c6a, 0x9f065e71, 0x920d5078, 0xd9640a0f, 0xd46f0406,
-0xc372161d, 0xce791814, 0xed48322b, 0xe0433c22, 0xf75e2e39, 0xfa552030,
-0xb701ec9a, 0xba0ae293, 0xad17f088, 0xa01cfe81, 0x832dd4be, 0x8e26dab7,
-0x993bc8ac, 0x9430c6a5, 0xdf599cd2, 0xd25292db, 0xc54f80c0, 0xc8448ec9,
-0xeb75a4f6, 0xe67eaaff, 0xf163b8e4, 0xfc68b6ed, 0x67b10c0a, 0x6aba0203,
-0x7da71018, 0x70ac1e11, 0x539d342e, 0x5e963a27, 0x498b283c, 0x44802635,
-0x0fe97c42, 0x02e2724b, 0x15ff6050, 0x18f46e59, 0x3bc54466, 0x36ce4a6f,
-0x21d35874, 0x2cd8567d, 0x0c7a37a1, 0x017139a8, 0x166c2bb3, 0x1b6725ba,
-0x38560f85, 0x355d018c, 0x22401397, 0x2f4b1d9e, 0x642247e9, 0x692949e0,
-0x7e345bfb, 0x733f55f2, 0x500e7fcd, 0x5d0571c4, 0x4a1863df, 0x47136dd6,
-0xdccad731, 0xd1c1d938, 0xc6dccb23, 0xcbd7c52a, 0xe8e6ef15, 0xe5ede11c,
-0xf2f0f307, 0xfffbfd0e, 0xb492a779, 0xb999a970, 0xae84bb6b, 0xa38fb562,
-0x80be9f5d, 0x8db59154, 0x9aa8834f, 0x97a38d46
-};
-#endif
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 _IMXC3[256] =
-{
-0x00000000, 0x0e0b0d09, 0x1c161a12, 0x121d171b, 0x382c3424, 0x3627392d,
-0x243a2e36, 0x2a31233f, 0x70586848, 0x7e536541, 0x6c4e725a, 0x62457f53,
-0x48745c6c, 0x467f5165, 0x5462467e, 0x5a694b77, 0xe0b0d090, 0xeebbdd99,
-0xfca6ca82, 0xf2adc78b, 0xd89ce4b4, 0xd697e9bd, 0xc48afea6, 0xca81f3af,
-0x90e8b8d8, 0x9ee3b5d1, 0x8cfea2ca, 0x82f5afc3, 0xa8c48cfc, 0xa6cf81f5,
-0xb4d296ee, 0xbad99be7, 0xdb7bbb3b, 0xd570b632, 0xc76da129, 0xc966ac20,
-0xe3578f1f, 0xed5c8216, 0xff41950d, 0xf14a9804, 0xab23d373, 0xa528de7a,
-0xb735c961, 0xb93ec468, 0x930fe757, 0x9d04ea5e, 0x8f19fd45, 0x8112f04c,
-0x3bcb6bab, 0x35c066a2, 0x27dd71b9, 0x29d67cb0, 0x03e75f8f, 0x0dec5286,
-0x1ff1459d, 0x11fa4894, 0x4b9303e3, 0x45980eea, 0x578519f1, 0x598e14f8,
-0x73bf37c7, 0x7db43ace, 0x6fa92dd5, 0x61a220dc, 0xadf66d76, 0xa3fd607f,
-0xb1e07764, 0xbfeb7a6d, 0x95da5952, 0x9bd1545b, 0x89cc4340, 0x87c74e49,
-0xddae053e, 0xd3a50837, 0xc1b81f2c, 0xcfb31225, 0xe582311a, 0xeb893c13,
-0xf9942b08, 0xf79f2601, 0x4d46bde6, 0x434db0ef, 0x5150a7f4, 0x5f5baafd,
-0x756a89c2, 0x7b6184cb, 0x697c93d0, 0x67779ed9, 0x3d1ed5ae, 0x3315d8a7,
-0x2108cfbc, 0x2f03c2b5, 0x0532e18a, 0x0b39ec83, 0x1924fb98, 0x172ff691,
-0x768dd64d, 0x7886db44, 0x6a9bcc5f, 0x6490c156, 0x4ea1e269, 0x40aaef60,
-0x52b7f87b, 0x5cbcf572, 0x06d5be05, 0x08deb30c, 0x1ac3a417, 0x14c8a91e,
-0x3ef98a21, 0x30f28728, 0x22ef9033, 0x2ce49d3a, 0x963d06dd, 0x98360bd4,
-0x8a2b1ccf, 0x842011c6, 0xae1132f9, 0xa01a3ff0, 0xb20728eb, 0xbc0c25e2,
-0xe6656e95, 0xe86e639c, 0xfa737487, 0xf478798e, 0xde495ab1, 0xd04257b8,
-0xc25f40a3, 0xcc544daa, 0x41f7daec, 0x4ffcd7e5, 0x5de1c0fe, 0x53eacdf7,
-0x79dbeec8, 0x77d0e3c1, 0x65cdf4da, 0x6bc6f9d3, 0x31afb2a4, 0x3fa4bfad,
-0x2db9a8b6, 0x23b2a5bf, 0x09838680, 0x07888b89, 0x15959c92, 0x1b9e919b,
-0xa1470a7c, 0xaf4c0775, 0xbd51106e, 0xb35a1d67, 0x996b3e58, 0x97603351,
-0x857d244a, 0x8b762943, 0xd11f6234, 0xdf146f3d, 0xcd097826, 0xc302752f,
-0xe9335610, 0xe7385b19, 0xf5254c02, 0xfb2e410b, 0x9a8c61d7, 0x94876cde,
-0x869a7bc5, 0x889176cc, 0xa2a055f3, 0xacab58fa, 0xbeb64fe1, 0xb0bd42e8,
-0xead4099f, 0xe4df0496, 0xf6c2138d, 0xf8c91e84, 0xd2f83dbb, 0xdcf330b2,
-0xceee27a9, 0xc0e52aa0, 0x7a3cb147, 0x7437bc4e, 0x662aab55, 0x6821a65c,
-0x42108563, 0x4c1b886a, 0x5e069f71, 0x500d9278, 0x0a64d90f, 0x046fd406,
-0x1672c31d, 0x1879ce14, 0x3248ed2b, 0x3c43e022, 0x2e5ef739, 0x2055fa30,
-0xec01b79a, 0xe20aba93, 0xf017ad88, 0xfe1ca081, 0xd42d83be, 0xda268eb7,
-0xc83b99ac, 0xc63094a5, 0x9c59dfd2, 0x9252d2db, 0x804fc5c0, 0x8e44c8c9,
-0xa475ebf6, 0xaa7ee6ff, 0xb863f1e4, 0xb668fced, 0x0cb1670a, 0x02ba6a03,
-0x10a77d18, 0x1eac7011, 0x349d532e, 0x3a965e27, 0x288b493c, 0x26804435,
-0x7ce90f42, 0x72e2024b, 0x60ff1550, 0x6ef41859, 0x44c53b66, 0x4ace366f,
-0x58d32174, 0x56d82c7d, 0x377a0ca1, 0x397101a8, 0x2b6c16b3, 0x25671bba,
-0x0f563885, 0x015d358c, 0x13402297, 0x1d4b2f9e, 0x472264e9, 0x492969e0,
-0x5b347efb, 0x553f73f2, 0x7f0e50cd, 0x71055dc4, 0x63184adf, 0x6d1347d6,
-0xd7cadc31, 0xd9c1d138, 0xcbdcc623, 0xc5d7cb2a, 0xefe6e815, 0xe1ede51c,
-0xf3f0f207, 0xfdfbff0e, 0xa792b479, 0xa999b970, 0xbb84ae6b, 0xb58fa362,
-0x9fbe805d, 0x91b58d54, 0x83a89a4f, 0x8da39746
-};
-#else
-static const PRUint32 _IMXC3[256] =
-{
-0x00000000, 0x090d0b0e, 0x121a161c, 0x1b171d12, 0x24342c38, 0x2d392736,
-0x362e3a24, 0x3f23312a, 0x48685870, 0x4165537e, 0x5a724e6c, 0x537f4562,
-0x6c5c7448, 0x65517f46, 0x7e466254, 0x774b695a, 0x90d0b0e0, 0x99ddbbee,
-0x82caa6fc, 0x8bc7adf2, 0xb4e49cd8, 0xbde997d6, 0xa6fe8ac4, 0xaff381ca,
-0xd8b8e890, 0xd1b5e39e, 0xcaa2fe8c, 0xc3aff582, 0xfc8cc4a8, 0xf581cfa6,
-0xee96d2b4, 0xe79bd9ba, 0x3bbb7bdb, 0x32b670d5, 0x29a16dc7, 0x20ac66c9,
-0x1f8f57e3, 0x16825ced, 0x0d9541ff, 0x04984af1, 0x73d323ab, 0x7ade28a5,
-0x61c935b7, 0x68c43eb9, 0x57e70f93, 0x5eea049d, 0x45fd198f, 0x4cf01281,
-0xab6bcb3b, 0xa266c035, 0xb971dd27, 0xb07cd629, 0x8f5fe703, 0x8652ec0d,
-0x9d45f11f, 0x9448fa11, 0xe303934b, 0xea0e9845, 0xf1198557, 0xf8148e59,
-0xc737bf73, 0xce3ab47d, 0xd52da96f, 0xdc20a261, 0x766df6ad, 0x7f60fda3,
-0x6477e0b1, 0x6d7aebbf, 0x5259da95, 0x5b54d19b, 0x4043cc89, 0x494ec787,
-0x3e05aedd, 0x3708a5d3, 0x2c1fb8c1, 0x2512b3cf, 0x1a3182e5, 0x133c89eb,
-0x082b94f9, 0x01269ff7, 0xe6bd464d, 0xefb04d43, 0xf4a75051, 0xfdaa5b5f,
-0xc2896a75, 0xcb84617b, 0xd0937c69, 0xd99e7767, 0xaed51e3d, 0xa7d81533,
-0xbccf0821, 0xb5c2032f, 0x8ae13205, 0x83ec390b, 0x98fb2419, 0x91f62f17,
-0x4dd68d76, 0x44db8678, 0x5fcc9b6a, 0x56c19064, 0x69e2a14e, 0x60efaa40,
-0x7bf8b752, 0x72f5bc5c, 0x05bed506, 0x0cb3de08, 0x17a4c31a, 0x1ea9c814,
-0x218af93e, 0x2887f230, 0x3390ef22, 0x3a9de42c, 0xdd063d96, 0xd40b3698,
-0xcf1c2b8a, 0xc6112084, 0xf93211ae, 0xf03f1aa0, 0xeb2807b2, 0xe2250cbc,
-0x956e65e6, 0x9c636ee8, 0x877473fa, 0x8e7978f4, 0xb15a49de, 0xb85742d0,
-0xa3405fc2, 0xaa4d54cc, 0xecdaf741, 0xe5d7fc4f, 0xfec0e15d, 0xf7cdea53,
-0xc8eedb79, 0xc1e3d077, 0xdaf4cd65, 0xd3f9c66b, 0xa4b2af31, 0xadbfa43f,
-0xb6a8b92d, 0xbfa5b223, 0x80868309, 0x898b8807, 0x929c9515, 0x9b919e1b,
-0x7c0a47a1, 0x75074caf, 0x6e1051bd, 0x671d5ab3, 0x583e6b99, 0x51336097,
-0x4a247d85, 0x4329768b, 0x34621fd1, 0x3d6f14df, 0x267809cd, 0x2f7502c3,
-0x105633e9, 0x195b38e7, 0x024c25f5, 0x0b412efb, 0xd7618c9a, 0xde6c8794,
-0xc57b9a86, 0xcc769188, 0xf355a0a2, 0xfa58abac, 0xe14fb6be, 0xe842bdb0,
-0x9f09d4ea, 0x9604dfe4, 0x8d13c2f6, 0x841ec9f8, 0xbb3df8d2, 0xb230f3dc,
-0xa927eece, 0xa02ae5c0, 0x47b13c7a, 0x4ebc3774, 0x55ab2a66, 0x5ca62168,
-0x63851042, 0x6a881b4c, 0x719f065e, 0x78920d50, 0x0fd9640a, 0x06d46f04,
-0x1dc37216, 0x14ce7918, 0x2bed4832, 0x22e0433c, 0x39f75e2e, 0x30fa5520,
-0x9ab701ec, 0x93ba0ae2, 0x88ad17f0, 0x81a01cfe, 0xbe832dd4, 0xb78e26da,
-0xac993bc8, 0xa59430c6, 0xd2df599c, 0xdbd25292, 0xc0c54f80, 0xc9c8448e,
-0xf6eb75a4, 0xffe67eaa, 0xe4f163b8, 0xedfc68b6, 0x0a67b10c, 0x036aba02,
-0x187da710, 0x1170ac1e, 0x2e539d34, 0x275e963a, 0x3c498b28, 0x35448026,
-0x420fe97c, 0x4b02e272, 0x5015ff60, 0x5918f46e, 0x663bc544, 0x6f36ce4a,
-0x7421d358, 0x7d2cd856, 0xa10c7a37, 0xa8017139, 0xb3166c2b, 0xba1b6725,
-0x8538560f, 0x8c355d01, 0x97224013, 0x9e2f4b1d, 0xe9642247, 0xe0692949,
-0xfb7e345b, 0xf2733f55, 0xcd500e7f, 0xc45d0571, 0xdf4a1863, 0xd647136d,
-0x31dccad7, 0x38d1c1d9, 0x23c6dccb, 0x2acbd7c5, 0x15e8e6ef, 0x1ce5ede1,
-0x07f2f0f3, 0x0efffbfd, 0x79b492a7, 0x70b999a9, 0x6bae84bb, 0x62a38fb5,
-0x5d80be9f, 0x548db591, 0x4f9aa883, 0x4697a38d
-};
-#endif
-
-#endif /* RIJNDAEL_INCLUDE_TABLES */
-
-#ifdef IS_LITTLE_ENDIAN
-static const PRUint32 Rcon[30] = {
-0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020,
-0x00000040, 0x00000080, 0x0000001b, 0x00000036, 0x0000006c, 0x000000d8,
-0x000000ab, 0x0000004d, 0x0000009a, 0x0000002f, 0x0000005e, 0x000000bc,
-0x00000063, 0x000000c6, 0x00000097, 0x00000035, 0x0000006a, 0x000000d4,
-0x000000b3, 0x0000007d, 0x000000fa, 0x000000ef, 0x000000c5, 0x00000091
-};
-#else
-static const PRUint32 Rcon[30] = {
-0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
-0x40000000, 0x80000000, 0x1b000000, 0x36000000, 0x6c000000, 0xd8000000,
-0xab000000, 0x4d000000, 0x9a000000, 0x2f000000, 0x5e000000, 0xbc000000,
-0x63000000, 0xc6000000, 0x97000000, 0x35000000, 0x6a000000, 0xd4000000,
-0xb3000000, 0x7d000000, 0xfa000000, 0xef000000, 0xc5000000, 0x91000000
-};
-#endif
-
diff --git a/security/nss/lib/freebl/rijndael_tables.c b/security/nss/lib/freebl/rijndael_tables.c
deleted file mode 100644
index e235cf759..000000000
--- a/security/nss/lib/freebl/rijndael_tables.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "stdio.h"
-#include "prtypes.h"
-#include "blapi.h"
-
-/*
- * what follows is code thrown together to generate the myriad of tables
- * used by Rijndael, the AES cipher.
- */
-
-
-#define WORD_LE(b0, b1, b2, b3) \
- (((b3) << 24) | ((b2) << 16) | ((b1) << 8) | b0)
-
-#define WORD_BE(b0, b1, b2, b3) \
- (((b0) << 24) | ((b1) << 16) | ((b2) << 8) | b3)
-
-static const PRUint8 __S[256] =
-{
- 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
-202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
-183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
- 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
- 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
- 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
-208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
- 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
-205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
- 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
-224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
-231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
-186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
-112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
-225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
-140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22,
-};
-
-static const PRUint8 __SInv[256] =
-{
- 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
-124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
- 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78,
- 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37,
-114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
-108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132,
-144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6,
-208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107,
- 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115,
-150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
- 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27,
-252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244,
- 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95,
- 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239,
-160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
- 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125
-};
-
-/* GF_MULTIPLY
- *
- * multiply two bytes represented in GF(2**8), mod (x**4 + 1)
- */
-PRUint8 gf_multiply(PRUint8 a, PRUint8 b)
-{
- PRUint8 res = 0;
- while (b > 0) {
- res = (b & 0x01) ? res ^ a : res;
- a = (a & 0x80) ? ((a << 1) ^ 0x1b) : (a << 1);
- b >>= 1;
- }
- return res;
-}
-
-void
-make_T_Table(char *table, const PRUint8 Sx[256], FILE *file,
- unsigned char m0, unsigned char m1,
- unsigned char m2, unsigned char m3)
-{
- PRUint32 Ti;
- int i;
- fprintf(file, "#ifdef IS_LITTLE_ENDIAN\n");
- fprintf(file, "static const PRUint32 _T%s[256] = \n{\n", table);
- for (i=0; i<256; i++) {
- Ti = WORD_LE( gf_multiply(Sx[i], m0),
- gf_multiply(Sx[i], m1),
- gf_multiply(Sx[i], m2),
- gf_multiply(Sx[i], m3) );
- if (Ti == 0)
- fprintf(file, "0x00000000%c%c", (i==255)?' ':',',
- (i%6==5)?'\n':' ');
- else
- fprintf(file, "%#.8x%c%c", Ti, (i==255)?' ':',',
- (i%6==5)?'\n':' ');
- }
- fprintf(file, "\n};\n");
- fprintf(file, "#else\n");
- fprintf(file, "static const PRUint32 _T%s[256] = \n{\n", table);
- for (i=0; i<256; i++) {
- Ti = WORD_BE( gf_multiply(Sx[i], m0),
- gf_multiply(Sx[i], m1),
- gf_multiply(Sx[i], m2),
- gf_multiply(Sx[i], m3) );
- if (Ti == 0)
- fprintf(file, "0x00000000%c%c", (i==255)?' ':',',
- (i%6==5)?'\n':' ');
- else
- fprintf(file, "%#.8x%c%c", Ti, (i==255)?' ':',',
- (i%6==5)?'\n':' ');
- }
- fprintf(file, "\n};\n");
- fprintf(file, "#endif\n\n");
-}
-
-void make_InvMixCol_Table(int num, FILE *file, PRUint8 m0, PRUint8 m1, PRUint8 m2, PRUint8 m3)
-{
- PRUint16 i;
- PRUint8 b0, b1, b2, b3;
- fprintf(file, "#ifdef IS_LITTLE_ENDIAN\n");
- fprintf(file, "static const PRUint32 _IMXC%d[256] = \n{\n", num);
- for (i=0; i<256; i++) {
- b0 = gf_multiply(i, m0);
- b1 = gf_multiply(i, m1);
- b2 = gf_multiply(i, m2);
- b3 = gf_multiply(i, m3);
- fprintf(file, "0x%.2x%.2x%.2x%.2x%c%c", b3, b2, b1, b0, (i==255)?' ':',', (i%6==5)?'\n':' ');
- }
- fprintf(file, "\n};\n");
- fprintf(file, "#else\n");
- fprintf(file, "static const PRUint32 _IMXC%d[256] = \n{\n", num);
- for (i=0; i<256; i++) {
- b0 = gf_multiply(i, m0);
- b1 = gf_multiply(i, m1);
- b2 = gf_multiply(i, m2);
- b3 = gf_multiply(i, m3);
- fprintf(file, "0x%.2x%.2x%.2x%.2x%c%c", b0, b1, b2, b3, (i==255)?' ':',', (i%6==5)?'\n':' ');
- }
- fprintf(file, "\n};\n");
- fprintf(file, "#endif\n\n");
-}
-
-int main()
-{
- int i, j;
- PRUint8 cur, last;
- PRUint32 tmp;
- FILE *optfile;
- optfile = fopen("rijndael32.tab", "w");
- /* output S, if there are no T tables */
- fprintf(optfile, "#ifndef RIJNDAEL_INCLUDE_TABLES\n");
- fprintf(optfile, "static const PRUint8 _S[256] = \n{\n");
- for (i=0; i<256; i++) {
- fprintf(optfile, "%3d%c%c", __S[i],(i==255)?' ':',',
- (i%16==15)?'\n':' ');
- }
- fprintf(optfile, "};\n#endif /* not RIJNDAEL_INCLUDE_TABLES */\n\n");
- /* output S**-1 */
- fprintf(optfile, "static const PRUint8 _SInv[256] = \n{\n");
- for (i=0; i<256; i++) {
- fprintf(optfile, "%3d%c%c", __SInv[i],(i==255)?' ':',',
- (i%16==15)?'\n':' ');
- }
- fprintf(optfile, "};\n\n");
- fprintf(optfile, "#ifdef RIJNDAEL_INCLUDE_TABLES\n");
- /* The 32-bit word tables for optimized implementation */
- /* T0 = [ S[a] * 02, S[a], S[a], S[a] * 03 ] */
- make_T_Table("0", __S, optfile, 0x02, 0x01, 0x01, 0x03);
- /* T1 = [ S[a] * 03, S[a] * 02, S[a], S[a] ] */
- make_T_Table("1", __S, optfile, 0x03, 0x02, 0x01, 0x01);
- /* T2 = [ S[a], S[a] * 03, S[a] * 02, S[a] ] */
- make_T_Table("2", __S, optfile, 0x01, 0x03, 0x02, 0x01);
- /* T3 = [ S[a], S[a], S[a] * 03, S[a] * 02 ] */
- make_T_Table("3", __S, optfile, 0x01, 0x01, 0x03, 0x02);
- /* TInv0 = [ Si[a] * 0E, Si[a] * 09, Si[a] * 0D, Si[a] * 0B ] */
- make_T_Table("Inv0", __SInv, optfile, 0x0e, 0x09, 0x0d, 0x0b);
- /* TInv1 = [ Si[a] * 0B, Si[a] * 0E, Si[a] * 09, Si[a] * 0D ] */
- make_T_Table("Inv1", __SInv, optfile, 0x0b, 0x0e, 0x09, 0x0d);
- /* TInv2 = [ Si[a] * 0D, Si[a] * 0B, Si[a] * 0E, Si[a] * 09 ] */
- make_T_Table("Inv2", __SInv, optfile, 0x0d, 0x0b, 0x0e, 0x09);
- /* TInv3 = [ Si[a] * 09, Si[a] * 0D, Si[a] * 0B, Si[a] * 0E ] */
- make_T_Table("Inv3", __SInv, optfile, 0x09, 0x0d, 0x0b, 0x0e);
- /* byte multiply tables for inverse key expansion (mimics InvMixColumn) */
- make_InvMixCol_Table(0, optfile, 0x0e, 0x09, 0x0d, 0x0b);
- make_InvMixCol_Table(1, optfile, 0x0b, 0x0E, 0x09, 0x0d);
- make_InvMixCol_Table(2, optfile, 0x0d, 0x0b, 0x0e, 0x09);
- make_InvMixCol_Table(3, optfile, 0x09, 0x0d, 0x0b, 0x0e);
- fprintf(optfile, "#endif /* RIJNDAEL_INCLUDE_TABLES */\n\n");
- /* round constants for key expansion */
- fprintf(optfile, "#ifdef IS_LITTLE_ENDIAN\n");
- fprintf(optfile, "static const PRUint32 Rcon[30] = {\n");
- cur = 0x01;
- for (i=0; i<30; i++) {
- fprintf(optfile, "%#.8x%c%c", WORD_LE(cur, 0, 0, 0),
- (i==29)?' ':',', (i%6==5)?'\n':' ');
- last = cur;
- cur = gf_multiply(last, 0x02);
- }
- fprintf(optfile, "};\n");
- fprintf(optfile, "#else\n");
- fprintf(optfile, "static const PRUint32 Rcon[30] = {\n");
- cur = 0x01;
- for (i=0; i<30; i++) {
- fprintf(optfile, "%#.8x%c%c", WORD_BE(cur, 0, 0, 0),
- (i==29)?' ':',', (i%6==5)?'\n':' ');
- last = cur;
- cur = gf_multiply(last, 0x02);
- }
- fprintf(optfile, "};\n");
- fprintf(optfile, "#endif\n\n");
- fclose(optfile);
- return 0;
-}
diff --git a/security/nss/lib/freebl/rsa.c b/security/nss/lib/freebl/rsa.c
deleted file mode 100644
index 6ac1eefea..000000000
--- a/security/nss/lib/freebl/rsa.c
+++ /dev/null
@@ -1,1573 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * RSA key generation, public key op, private key op.
- *
- * $Id$
- */
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "secerr.h"
-
-#include "prclist.h"
-#include "nssilock.h"
-#include "prinit.h"
-#include "blapi.h"
-#include "mpi.h"
-#include "mpprime.h"
-#include "mplogic.h"
-#include "secmpi.h"
-#include "secitem.h"
-#include "blapii.h"
-
-/*
-** Number of times to attempt to generate a prime (p or q) from a random
-** seed (the seed changes for each iteration).
-*/
-#define MAX_PRIME_GEN_ATTEMPTS 10
-/*
-** Number of times to attempt to generate a key. The primes p and q change
-** for each attempt.
-*/
-#define MAX_KEY_GEN_ATTEMPTS 10
-
-/* Blinding Parameters max cache size */
-#define RSA_BLINDING_PARAMS_MAX_CACHE_SIZE 20
-
-/* exponent should not be greater than modulus */
-#define BAD_RSA_KEY_SIZE(modLen, expLen) \
- ((expLen) > (modLen) || (modLen) > RSA_MAX_MODULUS_BITS/8 || \
- (expLen) > RSA_MAX_EXPONENT_BITS/8)
-
-struct blindingParamsStr;
-typedef struct blindingParamsStr blindingParams;
-
-struct blindingParamsStr {
- blindingParams *next;
- mp_int f, g; /* blinding parameter */
- int counter; /* number of remaining uses of (f, g) */
-};
-
-/*
-** RSABlindingParamsStr
-**
-** For discussion of Paul Kocher's timing attack against an RSA private key
-** operation, see http://www.cryptography.com/timingattack/paper.html. The
-** countermeasure to this attack, known as blinding, is also discussed in
-** the Handbook of Applied Cryptography, 11.118-11.119.
-*/
-struct RSABlindingParamsStr
-{
- /* Blinding-specific parameters */
- PRCList link; /* link to list of structs */
- SECItem modulus; /* list element "key" */
- blindingParams *free, *bp; /* Blinding parameters queue */
- blindingParams array[RSA_BLINDING_PARAMS_MAX_CACHE_SIZE];
-};
-typedef struct RSABlindingParamsStr RSABlindingParams;
-
-/*
-** RSABlindingParamsListStr
-**
-** List of key-specific blinding params. The arena holds the volatile pool
-** of memory for each entry and the list itself. The lock is for list
-** operations, in this case insertions and iterations, as well as control
-** of the counter for each set of blinding parameters.
-*/
-struct RSABlindingParamsListStr
-{
- PZLock *lock; /* Lock for the list */
- PRCondVar *cVar; /* Condidtion Variable */
- int waitCount; /* Number of threads waiting on cVar */
- PRCList head; /* Pointer to the list */
-};
-
-/*
-** The master blinding params list.
-*/
-static struct RSABlindingParamsListStr blindingParamsList = { 0 };
-
-/* Number of times to reuse (f, g). Suggested by Paul Kocher */
-#define RSA_BLINDING_PARAMS_MAX_REUSE 50
-
-/* Global, allows optional use of blinding. On by default. */
-/* Cannot be changed at the moment, due to thread-safety issues. */
-static PRBool nssRSAUseBlinding = PR_TRUE;
-
-static SECStatus
-rsa_build_from_primes(mp_int *p, mp_int *q,
- mp_int *e, PRBool needPublicExponent,
- mp_int *d, PRBool needPrivateExponent,
- RSAPrivateKey *key, unsigned int keySizeInBits)
-{
- mp_int n, phi;
- mp_int psub1, qsub1, tmp;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- MP_DIGITS(&n) = 0;
- MP_DIGITS(&phi) = 0;
- MP_DIGITS(&psub1) = 0;
- MP_DIGITS(&qsub1) = 0;
- MP_DIGITS(&tmp) = 0;
- CHECK_MPI_OK( mp_init(&n) );
- CHECK_MPI_OK( mp_init(&phi) );
- CHECK_MPI_OK( mp_init(&psub1) );
- CHECK_MPI_OK( mp_init(&qsub1) );
- CHECK_MPI_OK( mp_init(&tmp) );
- /* 1. Compute n = p*q */
- CHECK_MPI_OK( mp_mul(p, q, &n) );
- /* verify that the modulus has the desired number of bits */
- if ((unsigned)mpl_significant_bits(&n) != keySizeInBits) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- rv = SECFailure;
- goto cleanup;
- }
-
- /* at least one exponent must be given */
- PORT_Assert(!(needPublicExponent && needPrivateExponent));
-
- /* 2. Compute phi = (p-1)*(q-1) */
- CHECK_MPI_OK( mp_sub_d(p, 1, &psub1) );
- CHECK_MPI_OK( mp_sub_d(q, 1, &qsub1) );
- if (needPublicExponent || needPrivateExponent) {
- CHECK_MPI_OK( mp_mul(&psub1, &qsub1, &phi) );
- /* 3. Compute d = e**-1 mod(phi) */
- /* or e = d**-1 mod(phi) as necessary */
- if (needPublicExponent) {
- err = mp_invmod(d, &phi, e);
- } else {
- err = mp_invmod(e, &phi, d);
- }
- } else {
- err = MP_OKAY;
- }
- /* Verify that phi(n) and e have no common divisors */
- if (err != MP_OKAY) {
- if (err == MP_UNDEF) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM);
- err = MP_OKAY; /* to keep PORT_SetError from being called again */
- rv = SECFailure;
- }
- goto cleanup;
- }
-
- /* 4. Compute exponent1 = d mod (p-1) */
- CHECK_MPI_OK( mp_mod(d, &psub1, &tmp) );
- MPINT_TO_SECITEM(&tmp, &key->exponent1, key->arena);
- /* 5. Compute exponent2 = d mod (q-1) */
- CHECK_MPI_OK( mp_mod(d, &qsub1, &tmp) );
- MPINT_TO_SECITEM(&tmp, &key->exponent2, key->arena);
- /* 6. Compute coefficient = q**-1 mod p */
- CHECK_MPI_OK( mp_invmod(q, p, &tmp) );
- MPINT_TO_SECITEM(&tmp, &key->coefficient, key->arena);
-
- /* copy our calculated results, overwrite what is there */
- key->modulus.data = NULL;
- MPINT_TO_SECITEM(&n, &key->modulus, key->arena);
- key->privateExponent.data = NULL;
- MPINT_TO_SECITEM(d, &key->privateExponent, key->arena);
- key->publicExponent.data = NULL;
- MPINT_TO_SECITEM(e, &key->publicExponent, key->arena);
- key->prime1.data = NULL;
- MPINT_TO_SECITEM(p, &key->prime1, key->arena);
- key->prime2.data = NULL;
- MPINT_TO_SECITEM(q, &key->prime2, key->arena);
-cleanup:
- mp_clear(&n);
- mp_clear(&phi);
- mp_clear(&psub1);
- mp_clear(&qsub1);
- mp_clear(&tmp);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-static SECStatus
-generate_prime(mp_int *prime, int primeLen)
-{
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- unsigned long counter = 0;
- int piter;
- unsigned char *pb = NULL;
- pb = PORT_Alloc(primeLen);
- if (!pb) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto cleanup;
- }
- for (piter = 0; piter < MAX_PRIME_GEN_ATTEMPTS; piter++) {
- CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(pb, primeLen) );
- pb[0] |= 0xC0; /* set two high-order bits */
- pb[primeLen-1] |= 0x01; /* set low-order bit */
- CHECK_MPI_OK( mp_read_unsigned_octets(prime, pb, primeLen) );
- err = mpp_make_prime(prime, primeLen * 8, PR_FALSE, &counter);
- if (err != MP_NO)
- goto cleanup;
- /* keep going while err == MP_NO */
- }
-cleanup:
- if (pb)
- PORT_ZFree(pb, primeLen);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/*
-** Generate and return a new RSA public and private key.
-** Both keys are encoded in a single RSAPrivateKey structure.
-** "cx" is the random number generator context
-** "keySizeInBits" is the size of the key to be generated, in bits.
-** 512, 1024, etc.
-** "publicExponent" when not NULL is a pointer to some data that
-** represents the public exponent to use. The data is a byte
-** encoded integer, in "big endian" order.
-*/
-RSAPrivateKey *
-RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
-{
- unsigned int primeLen;
- mp_int p, q, e, d;
- int kiter;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- int prerr = 0;
- RSAPrivateKey *key = NULL;
- PRArenaPool *arena = NULL;
- /* Require key size to be a multiple of 16 bits. */
- if (!publicExponent || keySizeInBits % 16 != 0 ||
- BAD_RSA_KEY_SIZE(keySizeInBits/8, publicExponent->len)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- /* 1. Allocate arena & key */
- arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
- if (!arena) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
- key = PORT_ArenaZNew(arena, RSAPrivateKey);
- if (!key) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_FreeArena(arena, PR_TRUE);
- return NULL;
- }
- key->arena = arena;
- /* length of primes p and q (in bytes) */
- primeLen = keySizeInBits / (2 * BITS_PER_BYTE);
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&e) = 0;
- MP_DIGITS(&d) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&e) );
- CHECK_MPI_OK( mp_init(&d) );
- /* 2. Set the version number (PKCS1 v1.5 says it should be zero) */
- SECITEM_AllocItem(arena, &key->version, 1);
- key->version.data[0] = 0;
- /* 3. Set the public exponent */
- SECITEM_TO_MPINT(*publicExponent, &e);
- kiter = 0;
- do {
- prerr = 0;
- PORT_SetError(0);
- CHECK_SEC_OK( generate_prime(&p, primeLen) );
- CHECK_SEC_OK( generate_prime(&q, primeLen) );
- /* Assure q < p */
- if (mp_cmp(&p, &q) < 0)
- mp_exch(&p, &q);
- /* Attempt to use these primes to generate a key */
- rv = rsa_build_from_primes(&p, &q,
- &e, PR_FALSE, /* needPublicExponent=false */
- &d, PR_TRUE, /* needPrivateExponent=true */
- key, keySizeInBits);
- if (rv == SECSuccess)
- break; /* generated two good primes */
- prerr = PORT_GetError();
- kiter++;
- /* loop until have primes */
- } while (prerr == SEC_ERROR_NEED_RANDOM && kiter < MAX_KEY_GEN_ATTEMPTS);
- if (prerr)
- goto cleanup;
-cleanup:
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&e);
- mp_clear(&d);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- if (rv && arena) {
- PORT_FreeArena(arena, PR_TRUE);
- key = NULL;
- }
- return key;
-}
-
-mp_err
-rsa_is_prime(mp_int *p) {
- int res;
-
- /* run a Fermat test */
- res = mpp_fermat(p, 2);
- if (res != MP_OKAY) {
- return res;
- }
-
- /* If that passed, run some Miller-Rabin tests */
- res = mpp_pprime(p, 2);
- return res;
-}
-
-/*
- * Try to find the two primes based on 2 exponents plus either a prime
- * or a modulus.
- *
- * In: e, d and either p or n (depending on the setting of hasModulus).
- * Out: p,q.
- *
- * Step 1, Since d = e**-1 mod phi, we know that d*e == 1 mod phi, or
- * d*e = 1+k*phi, or d*e-1 = k*phi. since d is less than phi and e is
- * usually less than d, then k must be an integer between e-1 and 1
- * (probably on the order of e).
- * Step 1a, If we were passed just a prime, we can divide k*phi by that
- * prime-1 and get k*(q-1). This will reduce the size of our division
- * through the rest of the loop.
- * Step 2, Loop through the values k=e-1 to 1 looking for k. k should be on
- * the order or e, and e is typically small. This may take a while for
- * a large random e. We are looking for a k that divides kphi
- * evenly. Once we find a k that divides kphi evenly, we assume it
- * is the true k. It's possible this k is not the 'true' k but has
- * swapped factors of p-1 and/or q-1. Because of this, we
- * tentatively continue Steps 3-6 inside this loop, and may return looking
- * for another k on failure.
- * Step 3, Calculate are tentative phi=kphi/k. Note: real phi is (p-1)*(q-1).
- * Step 4a, if we have a prime, kphi is already k*(q-1), so phi is or tenative
- * q-1. q = phi+1. If k is correct, q should be the right length and
- * prime.
- * Step 4b, It's possible q-1 and k could have swapped factors. We now have a
- * possible solution that meets our criteria. It may not be the only
- * solution, however, so we keep looking. If we find more than one,
- * we will fail since we cannot determine which is the correct
- * solution, and returning the wrong modulus will compromise both
- * moduli. If no other solution is found, we return the unique solution.
- * Step 5a, If we have the modulus (n=pq), then use the following formula to
- * calculate s=(p+q): , phi = (p-1)(q-1) = pq -p-q +1 = n-s+1. so
- * s=n-phi+1.
- * Step 5b, Use n=pq and s=p+q to solve for p and q as follows:
- * since q=s-p, then n=p*(s-p)= sp - p^2, rearranging p^2-s*p+n = 0.
- * from the quadratic equation we have p=1/2*(s+sqrt(s*s-4*n)) and
- * q=1/2*(s-sqrt(s*s-4*n)) if s*s-4*n is a perfect square, we are DONE.
- * If it is not, continue in our look looking for another k. NOTE: the
- * code actually distributes the 1/2 and results in the equations:
- * sqrt = sqrt(s/2*s/2-n), p=s/2+sqrt, q=s/2-sqrt. The algebra saves us
- * and extra divide by 2 and a multiply by 4.
- *
- * This will return p & q. q may be larger than p in the case that p was given
- * and it was the smaller prime.
- */
-static mp_err
-rsa_get_primes_from_exponents(mp_int *e, mp_int *d, mp_int *p, mp_int *q,
- mp_int *n, PRBool hasModulus,
- unsigned int keySizeInBits)
-{
- mp_int kphi; /* k*phi */
- mp_int k; /* current guess at 'k' */
- mp_int phi; /* (p-1)(q-1) */
- mp_int s; /* p+q/2 (s/2 in the algebra) */
- mp_int r; /* remainder */
- mp_int tmp; /* p-1 if p is given, n+1 is modulus is given */
- mp_int sqrt; /* sqrt(s/2*s/2-n) */
- mp_err err = MP_OKAY;
- unsigned int order_k;
-
- MP_DIGITS(&kphi) = 0;
- MP_DIGITS(&phi) = 0;
- MP_DIGITS(&s) = 0;
- MP_DIGITS(&k) = 0;
- MP_DIGITS(&r) = 0;
- MP_DIGITS(&tmp) = 0;
- MP_DIGITS(&sqrt) = 0;
- CHECK_MPI_OK( mp_init(&kphi) );
- CHECK_MPI_OK( mp_init(&phi) );
- CHECK_MPI_OK( mp_init(&s) );
- CHECK_MPI_OK( mp_init(&k) );
- CHECK_MPI_OK( mp_init(&r) );
- CHECK_MPI_OK( mp_init(&tmp) );
- CHECK_MPI_OK( mp_init(&sqrt) );
-
- /* our algorithm looks for a factor k whose maximum size is dependent
- * on the size of our smallest exponent, which had better be the public
- * exponent (if it's the private, the key is vulnerable to a brute force
- * attack).
- *
- * since our factor search is linear, we need to limit the maximum
- * size of the public key. this should not be a problem normally, since
- * public keys are usually small.
- *
- * if we want to handle larger public key sizes, we should have
- * a version which tries to 'completely' factor k*phi (where completely
- * means 'factor into primes, or composites with which are products of
- * large primes). Once we have all the factors, we can sort them out and
- * try different combinations to form our phi. The risk is if (p-1)/2,
- * (q-1)/2, and k are all large primes. In any case if the public key
- * is small (order of 20 some bits), then a linear search for k is
- * manageable.
- */
- if (mpl_significant_bits(e) > 23) {
- err=MP_RANGE;
- goto cleanup;
- }
-
- /* calculate k*phi = e*d - 1 */
- CHECK_MPI_OK( mp_mul(e, d, &kphi) );
- CHECK_MPI_OK( mp_sub_d(&kphi, 1, &kphi) );
-
-
- /* kphi is (e*d)-1, which is the same as k*(p-1)(q-1)
- * d < (p-1)(q-1), therefor k must be less than e-1
- * We can narrow down k even more, though. Since p and q are odd and both
- * have their high bit set, then we know that phi must be on order of
- * keySizeBits.
- */
- order_k = (unsigned)mpl_significant_bits(&kphi) - keySizeInBits;
-
- /* for (k=kinit; order(k) >= order_k; k--) { */
- /* k=kinit: k can't be bigger than kphi/2^(keySizeInBits -1) */
- CHECK_MPI_OK( mp_2expt(&k,keySizeInBits-1) );
- CHECK_MPI_OK( mp_div(&kphi, &k, &k, NULL));
- if (mp_cmp(&k,e) >= 0) {
- /* also can't be bigger then e-1 */
- CHECK_MPI_OK( mp_sub_d(e, 1, &k) );
- }
-
- /* calculate our temp value */
- /* This saves recalculating this value when the k guess is wrong, which
- * is reasonably frequent. */
- /* for the modulus case, tmp = n+1 (used to calculate p+q = tmp - phi) */
- /* for the prime case, tmp = p-1 (used to calculate q-1= phi/tmp) */
- if (hasModulus) {
- CHECK_MPI_OK( mp_add_d(n, 1, &tmp) );
- } else {
- CHECK_MPI_OK( mp_sub_d(p, 1, &tmp) );
- CHECK_MPI_OK(mp_div(&kphi,&tmp,&kphi,&r));
- if (mp_cmp_z(&r) != 0) {
- /* p-1 doesn't divide kphi, some parameter wasn't correct */
- err=MP_RANGE;
- goto cleanup;
- }
- mp_zero(q);
- /* kphi is now k*(q-1) */
- }
-
- /* rest of the for loop */
- for (; (err == MP_OKAY) && (mpl_significant_bits(&k) >= order_k);
- err = mp_sub_d(&k, 1, &k)) {
- /* looking for k as a factor of kphi */
- CHECK_MPI_OK(mp_div(&kphi,&k,&phi,&r));
- if (mp_cmp_z(&r) != 0) {
- /* not a factor, try the next one */
- continue;
- }
- /* we have a possible phi, see if it works */
- if (!hasModulus) {
- if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits/2) {
- /* phi is not the right size */
- continue;
- }
- /* phi should be divisible by 2, since
- * q is odd and phi=(q-1). */
- if (mpp_divis_d(&phi,2) == MP_NO) {
- /* phi is not divisible by 4 */
- continue;
- }
- /* we now have a candidate for the second prime */
- CHECK_MPI_OK(mp_add_d(&phi, 1, &tmp));
-
- /* check to make sure it is prime */
- err = rsa_is_prime(&tmp);
- if (err != MP_OKAY) {
- if (err == MP_NO) {
- /* No, then we still have the wrong phi */
- err = MP_OKAY;
- continue;
- }
- goto cleanup;
- }
- /*
- * It is possible that we have the wrong phi if
- * k_guess*(q_guess-1) = k*(q-1) (k and q-1 have swapped factors).
- * since our q_quess is prime, however. We have found a valid
- * rsa key because:
- * q is the correct order of magnitude.
- * phi = (p-1)(q-1) where p and q are both primes.
- * e*d mod phi = 1.
- * There is no way to know from the info given if this is the
- * original key. We never want to return the wrong key because if
- * two moduli with the same factor is known, then euclid's gcd
- * algorithm can be used to find that factor. Even though the
- * caller didn't pass the original modulus, it doesn't mean the
- * modulus wasn't known or isn't available somewhere. So to be safe
- * if we can't be sure we have the right q, we don't return any.
- *
- * So to make sure we continue looking for other valid q's. If none
- * are found, then we can safely return this one, otherwise we just
- * fail */
- if (mp_cmp_z(q) != 0) {
- /* this is the second valid q, don't return either,
- * just fail */
- err = MP_RANGE;
- break;
- }
- /* we only have one q so far, save it and if no others are found,
- * it's safe to return it */
- CHECK_MPI_OK(mp_copy(&tmp, q));
- continue;
- }
- /* test our tentative phi */
- /* phi should be the correct order */
- if ((unsigned)mpl_significant_bits(&phi) != keySizeInBits) {
- /* phi is not the right size */
- continue;
- }
- /* phi should be divisible by 4, since
- * p and q are odd and phi=(p-1)(q-1). */
- if (mpp_divis_d(&phi,4) == MP_NO) {
- /* phi is not divisible by 4 */
- continue;
- }
- /* n was given, calculate s/2=(p+q)/2 */
- CHECK_MPI_OK( mp_sub(&tmp, &phi, &s) );
- CHECK_MPI_OK( mp_div_2(&s, &s) );
-
- /* calculate sqrt(s/2*s/2-n) */
- CHECK_MPI_OK(mp_sqr(&s,&sqrt));
- CHECK_MPI_OK(mp_sub(&sqrt,n,&r)); /* r as a tmp */
- CHECK_MPI_OK(mp_sqrt(&r,&sqrt));
- /* make sure it's a perfect square */
- /* r is our original value we took the square root of */
- /* q is the square of our tentative square root. They should be equal*/
- CHECK_MPI_OK(mp_sqr(&sqrt,q)); /* q as a tmp */
- if (mp_cmp(&r,q) != 0) {
- /* sigh according to the doc, mp_sqrt could return sqrt-1 */
- CHECK_MPI_OK(mp_add_d(&sqrt,1,&sqrt));
- CHECK_MPI_OK(mp_sqr(&sqrt,q));
- if (mp_cmp(&r,q) != 0) {
- /* s*s-n not a perfect square, this phi isn't valid, find * another.*/
- continue;
- }
- }
-
- /* NOTE: In this case we know we have the one and only answer.
- * "Why?", you ask. Because:
- * 1) n is a composite of two large primes (or it wasn't a
- * valid RSA modulus).
- * 2) If we know any number such that x^2-n is a perfect square
- * and x is not (n+1)/2, then we can calculate 2 non-trivial
- * factors of n.
- * 3) Since we know that n has only 2 non-trivial prime factors,
- * we know the two factors we have are the only possible factors.
- */
-
- /* Now we are home free to calculate p and q */
- /* p = s/2 + sqrt, q= s/2 - sqrt */
- CHECK_MPI_OK(mp_add(&s,&sqrt,p));
- CHECK_MPI_OK(mp_sub(&s,&sqrt,q));
- break;
- }
- if ((unsigned)mpl_significant_bits(&k) < order_k) {
- if (hasModulus || (mp_cmp_z(q) == 0)) {
- /* If we get here, something was wrong with the parameters we
- * were given */
- err = MP_RANGE;
- }
- }
-cleanup:
- mp_clear(&kphi);
- mp_clear(&phi);
- mp_clear(&s);
- mp_clear(&k);
- mp_clear(&r);
- mp_clear(&tmp);
- mp_clear(&sqrt);
- return err;
-}
-
-/*
- * take a private key with only a few elements and fill out the missing pieces.
- *
- * All the entries will be overwritten with data allocated out of the arena
- * If no arena is supplied, one will be created.
- *
- * The following fields must be supplied in order for this function
- * to succeed:
- * one of either publicExponent or privateExponent
- * two more of the following 5 parameters.
- * modulus (n)
- * prime1 (p)
- * prime2 (q)
- * publicExponent (e)
- * privateExponent (d)
- *
- * NOTE: if only the publicExponent, privateExponent, and one prime is given,
- * then there may be more than one RSA key that matches that combination.
- *
- * All parameters will be replaced in the key structure with new parameters
- * Allocated out of the arena. There is no attempt to free the old structures.
- * Prime1 will always be greater than prime2 (even if the caller supplies the
- * smaller prime as prime1 or the larger prime as prime2). The parameters are
- * not overwritten on failure.
- *
- * How it works:
- * We can generate all the parameters from:
- * one of the exponents, plus the two primes. (rsa_build_key_from_primes) *
- * If we are given one of the exponents and both primes, we are done.
- * If we are given one of the exponents, the modulus and one prime, we
- * caclulate the second prime by dividing the modulus by the given
- * prime, giving us and exponent and 2 primes.
- * If we are given 2 exponents and either the modulus or one of the primes
- * we calculate k*phi = d*e-1, where k is an integer less than d which
- * divides d*e-1. We find factor k so we can isolate phi.
- * phi = (p-1)(q-1)
- * If one of the primes are given, we can use phi to find the other prime
- * as follows: q = (phi/(p-1)) + 1. We now have 2 primes and an
- * exponent. (NOTE: if more then one prime meets this condition, the
- * operation will fail. See comments elsewhere in this file about this).
- * If the modulus is given, then we can calculate the sum of the primes
- * as follows: s := (p+q), phi = (p-1)(q-1) = pq -p - q +1, pq = n ->
- * phi = n - s + 1, s = n - phi +1. Now that we have s = p+q and n=pq,
- * we can solve our 2 equations and 2 unknowns as follows: q=s-p ->
- * n=p*(s-p)= sp -p^2 -> p^2-sp+n = 0. Using the quadratic to solve for
- * p, p=1/2*(s+ sqrt(s*s-4*n)) [q=1/2*(s-sqrt(s*s-4*n)]. We again have
- * 2 primes and an exponent.
- *
- */
-SECStatus
-RSA_PopulatePrivateKey(RSAPrivateKey *key)
-{
- PRArenaPool *arena = NULL;
- PRBool needPublicExponent = PR_TRUE;
- PRBool needPrivateExponent = PR_TRUE;
- PRBool hasModulus = PR_FALSE;
- unsigned int keySizeInBits = 0;
- int prime_count = 0;
- /* standard RSA nominclature */
- mp_int p, q, e, d, n;
- /* remainder */
- mp_int r;
- mp_err err = 0;
- SECStatus rv = SECFailure;
-
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&e) = 0;
- MP_DIGITS(&d) = 0;
- MP_DIGITS(&n) = 0;
- MP_DIGITS(&r) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&e) );
- CHECK_MPI_OK( mp_init(&d) );
- CHECK_MPI_OK( mp_init(&n) );
- CHECK_MPI_OK( mp_init(&r) );
-
- /* if the key didn't already have an arena, create one. */
- if (key->arena == NULL) {
- arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
- if (!arena) {
- goto cleanup;
- }
- key->arena = arena;
- }
-
- /* load up the known exponents */
- if (key->publicExponent.data) {
- SECITEM_TO_MPINT(key->publicExponent, &e);
- needPublicExponent = PR_FALSE;
- }
- if (key->privateExponent.data) {
- SECITEM_TO_MPINT(key->privateExponent, &d);
- needPrivateExponent = PR_FALSE;
- }
- if (needPrivateExponent && needPublicExponent) {
- /* Not enough information, we need at least one exponent */
- err = MP_BADARG;
- goto cleanup;
- }
-
- /* load up the known primes. If only one prime is given, it will be
- * assigned 'p'. Once we have both primes, well make sure p is the larger.
- * The value prime_count tells us howe many we have acquired.
- */
- if (key->prime1.data) {
- int primeLen = key->prime1.len;
- if (key->prime1.data[0] == 0) {
- primeLen--;
- }
- keySizeInBits = primeLen * 2 * BITS_PER_BYTE;
- SECITEM_TO_MPINT(key->prime1, &p);
- prime_count++;
- }
- if (key->prime2.data) {
- int primeLen = key->prime2.len;
- if (key->prime2.data[0] == 0) {
- primeLen--;
- }
- keySizeInBits = primeLen * 2 * BITS_PER_BYTE;
- SECITEM_TO_MPINT(key->prime2, prime_count ? &q : &p);
- prime_count++;
- }
- /* load up the modulus */
- if (key->modulus.data) {
- int modLen = key->modulus.len;
- if (key->modulus.data[0] == 0) {
- modLen--;
- }
- keySizeInBits = modLen * BITS_PER_BYTE;
- SECITEM_TO_MPINT(key->modulus, &n);
- hasModulus = PR_TRUE;
- }
- /* if we have the modulus and one prime, calculate the second. */
- if ((prime_count == 1) && (hasModulus)) {
- mp_div(&n,&p,&q,&r);
- if (mp_cmp_z(&r) != 0) {
- /* p is not a factor or n, fail */
- err = MP_BADARG;
- goto cleanup;
- }
- prime_count++;
- }
-
- /* If we didn't have enough primes try to calculate the primes from
- * the exponents */
- if (prime_count < 2) {
- /* if we don't have at least 2 primes at this point, then we need both
- * exponents and one prime or a modulus*/
- if (!needPublicExponent && !needPrivateExponent &&
- ((prime_count > 0) || hasModulus)) {
- CHECK_MPI_OK(rsa_get_primes_from_exponents(&e,&d,&p,&q,
- &n,hasModulus,keySizeInBits));
- } else {
- /* not enough given parameters to get both primes */
- err = MP_BADARG;
- goto cleanup;
- }
- }
-
- /* force p to the the larger prime */
- if (mp_cmp(&p, &q) < 0)
- mp_exch(&p, &q);
-
- /* we now have our 2 primes and at least one exponent, we can fill
- * in the key */
- rv = rsa_build_from_primes(&p, &q,
- &e, needPublicExponent,
- &d, needPrivateExponent,
- key, keySizeInBits);
-cleanup:
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&e);
- mp_clear(&d);
- mp_clear(&n);
- mp_clear(&r);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- if (rv && arena) {
- PORT_FreeArena(arena, PR_TRUE);
- key->arena = NULL;
- }
- return rv;
-}
-
-static unsigned int
-rsa_modulusLen(SECItem *modulus)
-{
- unsigned char byteZero = modulus->data[0];
- unsigned int modLen = modulus->len - !byteZero;
- return modLen;
-}
-
-/*
-** Perform a raw public-key operation
-** Length of input and output buffers are equal to key's modulus len.
-*/
-SECStatus
-RSA_PublicKeyOp(RSAPublicKey *key,
- unsigned char *output,
- const unsigned char *input)
-{
- unsigned int modLen, expLen, offset;
- mp_int n, e, m, c;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- if (!key || !output || !input) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- MP_DIGITS(&n) = 0;
- MP_DIGITS(&e) = 0;
- MP_DIGITS(&m) = 0;
- MP_DIGITS(&c) = 0;
- CHECK_MPI_OK( mp_init(&n) );
- CHECK_MPI_OK( mp_init(&e) );
- CHECK_MPI_OK( mp_init(&m) );
- CHECK_MPI_OK( mp_init(&c) );
- modLen = rsa_modulusLen(&key->modulus);
- expLen = rsa_modulusLen(&key->publicExponent);
- /* 1. Obtain public key (n, e) */
- if (BAD_RSA_KEY_SIZE(modLen, expLen)) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- rv = SECFailure;
- goto cleanup;
- }
- SECITEM_TO_MPINT(key->modulus, &n);
- SECITEM_TO_MPINT(key->publicExponent, &e);
- if (e.used > n.used) {
- /* exponent should not be greater than modulus */
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- rv = SECFailure;
- goto cleanup;
- }
- /* 2. check input out of range (needs to be in range [0..n-1]) */
- offset = (key->modulus.data[0] == 0) ? 1 : 0; /* may be leading 0 */
- if (memcmp(input, key->modulus.data + offset, modLen) >= 0) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- rv = SECFailure;
- goto cleanup;
- }
- /* 2 bis. Represent message as integer in range [0..n-1] */
- CHECK_MPI_OK( mp_read_unsigned_octets(&m, input, modLen) );
- /* 3. Compute c = m**e mod n */
-#ifdef USE_MPI_EXPT_D
- /* XXX see which is faster */
- if (MP_USED(&e) == 1) {
- CHECK_MPI_OK( mp_exptmod_d(&m, MP_DIGIT(&e, 0), &n, &c) );
- } else
-#endif
- CHECK_MPI_OK( mp_exptmod(&m, &e, &n, &c) );
- /* 4. result c is ciphertext */
- err = mp_to_fixlen_octets(&c, output, modLen);
- if (err >= 0) err = MP_OKAY;
-cleanup:
- mp_clear(&n);
- mp_clear(&e);
- mp_clear(&m);
- mp_clear(&c);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/*
-** RSA Private key operation (no CRT).
-*/
-static SECStatus
-rsa_PrivateKeyOpNoCRT(RSAPrivateKey *key, mp_int *m, mp_int *c, mp_int *n,
- unsigned int modLen)
-{
- mp_int d;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- MP_DIGITS(&d) = 0;
- CHECK_MPI_OK( mp_init(&d) );
- SECITEM_TO_MPINT(key->privateExponent, &d);
- /* 1. m = c**d mod n */
- CHECK_MPI_OK( mp_exptmod(c, &d, n, m) );
-cleanup:
- mp_clear(&d);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/*
-** RSA Private key operation using CRT.
-*/
-static SECStatus
-rsa_PrivateKeyOpCRTNoCheck(RSAPrivateKey *key, mp_int *m, mp_int *c)
-{
- mp_int p, q, d_p, d_q, qInv;
- mp_int m1, m2, h, ctmp;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&d_p) = 0;
- MP_DIGITS(&d_q) = 0;
- MP_DIGITS(&qInv) = 0;
- MP_DIGITS(&m1) = 0;
- MP_DIGITS(&m2) = 0;
- MP_DIGITS(&h) = 0;
- MP_DIGITS(&ctmp) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&d_p) );
- CHECK_MPI_OK( mp_init(&d_q) );
- CHECK_MPI_OK( mp_init(&qInv) );
- CHECK_MPI_OK( mp_init(&m1) );
- CHECK_MPI_OK( mp_init(&m2) );
- CHECK_MPI_OK( mp_init(&h) );
- CHECK_MPI_OK( mp_init(&ctmp) );
- /* copy private key parameters into mp integers */
- SECITEM_TO_MPINT(key->prime1, &p); /* p */
- SECITEM_TO_MPINT(key->prime2, &q); /* q */
- SECITEM_TO_MPINT(key->exponent1, &d_p); /* d_p = d mod (p-1) */
- SECITEM_TO_MPINT(key->exponent2, &d_q); /* d_q = d mod (q-1) */
- SECITEM_TO_MPINT(key->coefficient, &qInv); /* qInv = q**-1 mod p */
- /* 1. m1 = c**d_p mod p */
- CHECK_MPI_OK( mp_mod(c, &p, &ctmp) );
- CHECK_MPI_OK( mp_exptmod(&ctmp, &d_p, &p, &m1) );
- /* 2. m2 = c**d_q mod q */
- CHECK_MPI_OK( mp_mod(c, &q, &ctmp) );
- CHECK_MPI_OK( mp_exptmod(&ctmp, &d_q, &q, &m2) );
- /* 3. h = (m1 - m2) * qInv mod p */
- CHECK_MPI_OK( mp_submod(&m1, &m2, &p, &h) );
- CHECK_MPI_OK( mp_mulmod(&h, &qInv, &p, &h) );
- /* 4. m = m2 + h * q */
- CHECK_MPI_OK( mp_mul(&h, &q, m) );
- CHECK_MPI_OK( mp_add(m, &m2, m) );
-cleanup:
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&d_p);
- mp_clear(&d_q);
- mp_clear(&qInv);
- mp_clear(&m1);
- mp_clear(&m2);
- mp_clear(&h);
- mp_clear(&ctmp);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-/*
-** An attack against RSA CRT was described by Boneh, DeMillo, and Lipton in:
-** "On the Importance of Eliminating Errors in Cryptographic Computations",
-** http://theory.stanford.edu/~dabo/papers/faults.ps.gz
-**
-** As a defense against the attack, carry out the private key operation,
-** followed up with a public key operation to invert the result.
-** Verify that result against the input.
-*/
-static SECStatus
-rsa_PrivateKeyOpCRTCheckedPubKey(RSAPrivateKey *key, mp_int *m, mp_int *c)
-{
- mp_int n, e, v;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- MP_DIGITS(&n) = 0;
- MP_DIGITS(&e) = 0;
- MP_DIGITS(&v) = 0;
- CHECK_MPI_OK( mp_init(&n) );
- CHECK_MPI_OK( mp_init(&e) );
- CHECK_MPI_OK( mp_init(&v) );
- CHECK_SEC_OK( rsa_PrivateKeyOpCRTNoCheck(key, m, c) );
- SECITEM_TO_MPINT(key->modulus, &n);
- SECITEM_TO_MPINT(key->publicExponent, &e);
- /* Perform a public key operation v = m ** e mod n */
- CHECK_MPI_OK( mp_exptmod(m, &e, &n, &v) );
- if (mp_cmp(&v, c) != 0) {
- rv = SECFailure;
- }
-cleanup:
- mp_clear(&n);
- mp_clear(&e);
- mp_clear(&v);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-static PRCallOnceType coBPInit = { 0, 0, 0 };
-static PRStatus
-init_blinding_params_list(void)
-{
- blindingParamsList.lock = PZ_NewLock(nssILockOther);
- if (!blindingParamsList.lock) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return PR_FAILURE;
- }
- blindingParamsList.cVar = PR_NewCondVar( blindingParamsList.lock );
- if (!blindingParamsList.cVar) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return PR_FAILURE;
- }
- blindingParamsList.waitCount = 0;
- PR_INIT_CLIST(&blindingParamsList.head);
- return PR_SUCCESS;
-}
-
-static SECStatus
-generate_blinding_params(RSAPrivateKey *key, mp_int* f, mp_int* g, mp_int *n,
- unsigned int modLen)
-{
- SECStatus rv = SECSuccess;
- mp_int e, k;
- mp_err err = MP_OKAY;
- unsigned char *kb = NULL;
-
- MP_DIGITS(&e) = 0;
- MP_DIGITS(&k) = 0;
- CHECK_MPI_OK( mp_init(&e) );
- CHECK_MPI_OK( mp_init(&k) );
- SECITEM_TO_MPINT(key->publicExponent, &e);
- /* generate random k < n */
- kb = PORT_Alloc(modLen);
- if (!kb) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto cleanup;
- }
- CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(kb, modLen) );
- CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, modLen) );
- /* k < n */
- CHECK_MPI_OK( mp_mod(&k, n, &k) );
- /* f = k**e mod n */
- CHECK_MPI_OK( mp_exptmod(&k, &e, n, f) );
- /* g = k**-1 mod n */
- CHECK_MPI_OK( mp_invmod(&k, n, g) );
-cleanup:
- if (kb)
- PORT_ZFree(kb, modLen);
- mp_clear(&k);
- mp_clear(&e);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-static SECStatus
-init_blinding_params(RSABlindingParams *rsabp, RSAPrivateKey *key,
- mp_int *n, unsigned int modLen)
-{
- blindingParams * bp = rsabp->array;
- int i = 0;
-
- /* Initialize the list pointer for the element */
- PR_INIT_CLIST(&rsabp->link);
- for (i = 0; i < RSA_BLINDING_PARAMS_MAX_CACHE_SIZE; ++i, ++bp) {
- bp->next = bp + 1;
- MP_DIGITS(&bp->f) = 0;
- MP_DIGITS(&bp->g) = 0;
- bp->counter = 0;
- }
- /* The last bp->next value was initialized with out
- * of rsabp->array pointer and must be set to NULL
- */
- rsabp->array[RSA_BLINDING_PARAMS_MAX_CACHE_SIZE - 1].next = NULL;
-
- bp = rsabp->array;
- rsabp->bp = NULL;
- rsabp->free = bp;
-
- /* List elements are keyed using the modulus */
- SECITEM_CopyItem(NULL, &rsabp->modulus, &key->modulus);
-
- return SECSuccess;
-}
-
-static SECStatus
-get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen,
- mp_int *f, mp_int *g)
-{
- RSABlindingParams *rsabp = NULL;
- blindingParams *bpUnlinked = NULL;
- blindingParams *bp, *prevbp = NULL;
- PRCList *el;
- SECStatus rv = SECSuccess;
- mp_err err = MP_OKAY;
- int cmp = -1;
- PRBool holdingLock = PR_FALSE;
-
- do {
- if (blindingParamsList.lock == NULL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* Acquire the list lock */
- PZ_Lock(blindingParamsList.lock);
- holdingLock = PR_TRUE;
-
- /* Walk the list looking for the private key */
- for (el = PR_NEXT_LINK(&blindingParamsList.head);
- el != &blindingParamsList.head;
- el = PR_NEXT_LINK(el)) {
- rsabp = (RSABlindingParams *)el;
- cmp = SECITEM_CompareItem(&rsabp->modulus, &key->modulus);
- if (cmp >= 0) {
- /* The key is found or not in the list. */
- break;
- }
- }
-
- if (cmp) {
- /* At this point, the key is not in the list. el should point to
- ** the list element before which this key should be inserted.
- */
- rsabp = PORT_ZNew(RSABlindingParams);
- if (!rsabp) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto cleanup;
- }
-
- rv = init_blinding_params(rsabp, key, n, modLen);
- if (rv != SECSuccess) {
- PORT_ZFree(rsabp, sizeof(RSABlindingParams));
- goto cleanup;
- }
-
- /* Insert the new element into the list
- ** If inserting in the middle of the list, el points to the link
- ** to insert before. Otherwise, the link needs to be appended to
- ** the end of the list, which is the same as inserting before the
- ** head (since el would have looped back to the head).
- */
- PR_INSERT_BEFORE(&rsabp->link, el);
- }
-
- /* We've found (or created) the RSAblindingParams struct for this key.
- * Now, search its list of ready blinding params for a usable one.
- */
- while (0 != (bp = rsabp->bp)) {
- if (--(bp->counter) > 0) {
- /* Found a match and there are still remaining uses left */
- /* Return the parameters */
- CHECK_MPI_OK( mp_copy(&bp->f, f) );
- CHECK_MPI_OK( mp_copy(&bp->g, g) );
-
- PZ_Unlock(blindingParamsList.lock);
- return SECSuccess;
- }
- /* exhausted this one, give its values to caller, and
- * then retire it.
- */
- mp_exch(&bp->f, f);
- mp_exch(&bp->g, g);
- mp_clear( &bp->f );
- mp_clear( &bp->g );
- bp->counter = 0;
- /* Move to free list */
- rsabp->bp = bp->next;
- bp->next = rsabp->free;
- rsabp->free = bp;
- /* In case there're threads waiting for new blinding
- * value - notify 1 thread the value is ready
- */
- if (blindingParamsList.waitCount > 0) {
- PR_NotifyCondVar( blindingParamsList.cVar );
- blindingParamsList.waitCount--;
- }
- PZ_Unlock(blindingParamsList.lock);
- return SECSuccess;
- }
- /* We did not find a usable set of blinding params. Can we make one? */
- /* Find a free bp struct. */
- prevbp = NULL;
- if ((bp = rsabp->free) != NULL) {
- /* unlink this bp */
- rsabp->free = bp->next;
- bp->next = NULL;
- bpUnlinked = bp; /* In case we fail */
-
- PZ_Unlock(blindingParamsList.lock);
- holdingLock = PR_FALSE;
- /* generate blinding parameter values for the current thread */
- CHECK_SEC_OK( generate_blinding_params(key, f, g, n, modLen ) );
-
- /* put the blinding parameter values into cache */
- CHECK_MPI_OK( mp_init( &bp->f) );
- CHECK_MPI_OK( mp_init( &bp->g) );
- CHECK_MPI_OK( mp_copy( f, &bp->f) );
- CHECK_MPI_OK( mp_copy( g, &bp->g) );
-
- /* Put this at head of queue of usable params. */
- PZ_Lock(blindingParamsList.lock);
- holdingLock = PR_TRUE;
- /* initialize RSABlindingParamsStr */
- bp->counter = RSA_BLINDING_PARAMS_MAX_REUSE;
- bp->next = rsabp->bp;
- rsabp->bp = bp;
- bpUnlinked = NULL;
- /* In case there're threads waiting for new blinding value
- * just notify them the value is ready
- */
- if (blindingParamsList.waitCount > 0) {
- PR_NotifyAllCondVar( blindingParamsList.cVar );
- blindingParamsList.waitCount = 0;
- }
- PZ_Unlock(blindingParamsList.lock);
- return SECSuccess;
- }
- /* Here, there are no usable blinding parameters available,
- * and no free bp blocks, presumably because they're all
- * actively having parameters generated for them.
- * So, we need to wait here and not eat up CPU until some
- * change happens.
- */
- blindingParamsList.waitCount++;
- PR_WaitCondVar( blindingParamsList.cVar, PR_INTERVAL_NO_TIMEOUT );
- PZ_Unlock(blindingParamsList.lock);
- holdingLock = PR_FALSE;
- } while (1);
-
-cleanup:
- /* It is possible to reach this after the lock is already released. */
- if (bpUnlinked) {
- if (!holdingLock) {
- PZ_Lock(blindingParamsList.lock);
- holdingLock = PR_TRUE;
- }
- bp = bpUnlinked;
- mp_clear( &bp->f );
- mp_clear( &bp->g );
- bp->counter = 0;
- /* Must put the unlinked bp back on the free list */
- bp->next = rsabp->free;
- rsabp->free = bp;
- }
- if (holdingLock) {
- PZ_Unlock(blindingParamsList.lock);
- holdingLock = PR_FALSE;
- }
- if (err) {
- MP_TO_SEC_ERROR(err);
- }
- return SECFailure;
-}
-
-/*
-** Perform a raw private-key operation
-** Length of input and output buffers are equal to key's modulus len.
-*/
-static SECStatus
-rsa_PrivateKeyOp(RSAPrivateKey *key,
- unsigned char *output,
- const unsigned char *input,
- PRBool check)
-{
- unsigned int modLen;
- unsigned int offset;
- SECStatus rv = SECSuccess;
- mp_err err;
- mp_int n, c, m;
- mp_int f, g;
- if (!key || !output || !input) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* check input out of range (needs to be in range [0..n-1]) */
- modLen = rsa_modulusLen(&key->modulus);
- offset = (key->modulus.data[0] == 0) ? 1 : 0; /* may be leading 0 */
- if (memcmp(input, key->modulus.data + offset, modLen) >= 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- MP_DIGITS(&n) = 0;
- MP_DIGITS(&c) = 0;
- MP_DIGITS(&m) = 0;
- MP_DIGITS(&f) = 0;
- MP_DIGITS(&g) = 0;
- CHECK_MPI_OK( mp_init(&n) );
- CHECK_MPI_OK( mp_init(&c) );
- CHECK_MPI_OK( mp_init(&m) );
- CHECK_MPI_OK( mp_init(&f) );
- CHECK_MPI_OK( mp_init(&g) );
- SECITEM_TO_MPINT(key->modulus, &n);
- OCTETS_TO_MPINT(input, &c, modLen);
- /* If blinding, compute pre-image of ciphertext by multiplying by
- ** blinding factor
- */
- if (nssRSAUseBlinding) {
- CHECK_SEC_OK( get_blinding_params(key, &n, modLen, &f, &g) );
- /* c' = c*f mod n */
- CHECK_MPI_OK( mp_mulmod(&c, &f, &n, &c) );
- }
- /* Do the private key operation m = c**d mod n */
- if ( key->prime1.len == 0 ||
- key->prime2.len == 0 ||
- key->exponent1.len == 0 ||
- key->exponent2.len == 0 ||
- key->coefficient.len == 0) {
- CHECK_SEC_OK( rsa_PrivateKeyOpNoCRT(key, &m, &c, &n, modLen) );
- } else if (check) {
- CHECK_SEC_OK( rsa_PrivateKeyOpCRTCheckedPubKey(key, &m, &c) );
- } else {
- CHECK_SEC_OK( rsa_PrivateKeyOpCRTNoCheck(key, &m, &c) );
- }
- /* If blinding, compute post-image of plaintext by multiplying by
- ** blinding factor
- */
- if (nssRSAUseBlinding) {
- /* m = m'*g mod n */
- CHECK_MPI_OK( mp_mulmod(&m, &g, &n, &m) );
- }
- err = mp_to_fixlen_octets(&m, output, modLen);
- if (err >= 0) err = MP_OKAY;
-cleanup:
- mp_clear(&n);
- mp_clear(&c);
- mp_clear(&m);
- mp_clear(&f);
- mp_clear(&g);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-SECStatus
-RSA_PrivateKeyOp(RSAPrivateKey *key,
- unsigned char *output,
- const unsigned char *input)
-{
- return rsa_PrivateKeyOp(key, output, input, PR_FALSE);
-}
-
-SECStatus
-RSA_PrivateKeyOpDoubleChecked(RSAPrivateKey *key,
- unsigned char *output,
- const unsigned char *input)
-{
- return rsa_PrivateKeyOp(key, output, input, PR_TRUE);
-}
-
-static SECStatus
-swap_in_key_value(PRArenaPool *arena, mp_int *mpval, SECItem *buffer)
-{
- int len;
- mp_err err = MP_OKAY;
- memset(buffer->data, 0, buffer->len);
- len = mp_unsigned_octet_size(mpval);
- if (len <= 0) return SECFailure;
- if ((unsigned int)len <= buffer->len) {
- /* The new value is no longer than the old buffer, so use it */
- err = mp_to_unsigned_octets(mpval, buffer->data, len);
- if (err >= 0) err = MP_OKAY;
- buffer->len = len;
- } else if (arena) {
- /* The new value is longer, but working within an arena */
- (void)SECITEM_AllocItem(arena, buffer, len);
- err = mp_to_unsigned_octets(mpval, buffer->data, len);
- if (err >= 0) err = MP_OKAY;
- } else {
- /* The new value is longer, no arena, can't handle this key */
- return SECFailure;
- }
- return (err == MP_OKAY) ? SECSuccess : SECFailure;
-}
-
-SECStatus
-RSA_PrivateKeyCheck(RSAPrivateKey *key)
-{
- mp_int p, q, n, psub1, qsub1, e, d, d_p, d_q, qInv, res;
- mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&n) = 0;
- MP_DIGITS(&psub1)= 0;
- MP_DIGITS(&qsub1)= 0;
- MP_DIGITS(&e) = 0;
- MP_DIGITS(&d) = 0;
- MP_DIGITS(&d_p) = 0;
- MP_DIGITS(&d_q) = 0;
- MP_DIGITS(&qInv) = 0;
- MP_DIGITS(&res) = 0;
- CHECK_MPI_OK( mp_init(&p) );
- CHECK_MPI_OK( mp_init(&q) );
- CHECK_MPI_OK( mp_init(&n) );
- CHECK_MPI_OK( mp_init(&psub1));
- CHECK_MPI_OK( mp_init(&qsub1));
- CHECK_MPI_OK( mp_init(&e) );
- CHECK_MPI_OK( mp_init(&d) );
- CHECK_MPI_OK( mp_init(&d_p) );
- CHECK_MPI_OK( mp_init(&d_q) );
- CHECK_MPI_OK( mp_init(&qInv) );
- CHECK_MPI_OK( mp_init(&res) );
- SECITEM_TO_MPINT(key->modulus, &n);
- SECITEM_TO_MPINT(key->prime1, &p);
- SECITEM_TO_MPINT(key->prime2, &q);
- SECITEM_TO_MPINT(key->publicExponent, &e);
- SECITEM_TO_MPINT(key->privateExponent, &d);
- SECITEM_TO_MPINT(key->exponent1, &d_p);
- SECITEM_TO_MPINT(key->exponent2, &d_q);
- SECITEM_TO_MPINT(key->coefficient, &qInv);
- /* p > q */
- if (mp_cmp(&p, &q) <= 0) {
- /* mind the p's and q's (and d_p's and d_q's) */
- SECItem tmp;
- mp_exch(&p, &q);
- mp_exch(&d_p,&d_q);
- tmp = key->prime1;
- key->prime1 = key->prime2;
- key->prime2 = tmp;
- tmp = key->exponent1;
- key->exponent1 = key->exponent2;
- key->exponent2 = tmp;
- }
-#define VERIFY_MPI_EQUAL(m1, m2) \
- if (mp_cmp(m1, m2) != 0) { \
- rv = SECFailure; \
- goto cleanup; \
- }
-#define VERIFY_MPI_EQUAL_1(m) \
- if (mp_cmp_d(m, 1) != 0) { \
- rv = SECFailure; \
- goto cleanup; \
- }
- /*
- * The following errors cannot be recovered from.
- */
- /* n == p * q */
- CHECK_MPI_OK( mp_mul(&p, &q, &res) );
- VERIFY_MPI_EQUAL(&res, &n);
- /* gcd(e, p-1) == 1 */
- CHECK_MPI_OK( mp_sub_d(&p, 1, &psub1) );
- CHECK_MPI_OK( mp_gcd(&e, &psub1, &res) );
- VERIFY_MPI_EQUAL_1(&res);
- /* gcd(e, q-1) == 1 */
- CHECK_MPI_OK( mp_sub_d(&q, 1, &qsub1) );
- CHECK_MPI_OK( mp_gcd(&e, &qsub1, &res) );
- VERIFY_MPI_EQUAL_1(&res);
- /* d*e == 1 mod p-1 */
- CHECK_MPI_OK( mp_mulmod(&d, &e, &psub1, &res) );
- VERIFY_MPI_EQUAL_1(&res);
- /* d*e == 1 mod q-1 */
- CHECK_MPI_OK( mp_mulmod(&d, &e, &qsub1, &res) );
- VERIFY_MPI_EQUAL_1(&res);
- /*
- * The following errors can be recovered from.
- */
- /* d_p == d mod p-1 */
- CHECK_MPI_OK( mp_mod(&d, &psub1, &res) );
- if (mp_cmp(&d_p, &res) != 0) {
- /* swap in the correct value */
- CHECK_SEC_OK( swap_in_key_value(key->arena, &res, &key->exponent1) );
- }
- /* d_q == d mod q-1 */
- CHECK_MPI_OK( mp_mod(&d, &qsub1, &res) );
- if (mp_cmp(&d_q, &res) != 0) {
- /* swap in the correct value */
- CHECK_SEC_OK( swap_in_key_value(key->arena, &res, &key->exponent2) );
- }
- /* q * q**-1 == 1 mod p */
- CHECK_MPI_OK( mp_mulmod(&q, &qInv, &p, &res) );
- if (mp_cmp_d(&res, 1) != 0) {
- /* compute the correct value */
- CHECK_MPI_OK( mp_invmod(&q, &p, &qInv) );
- CHECK_SEC_OK( swap_in_key_value(key->arena, &qInv, &key->coefficient) );
- }
-cleanup:
- mp_clear(&n);
- mp_clear(&p);
- mp_clear(&q);
- mp_clear(&psub1);
- mp_clear(&qsub1);
- mp_clear(&e);
- mp_clear(&d);
- mp_clear(&d_p);
- mp_clear(&d_q);
- mp_clear(&qInv);
- mp_clear(&res);
- if (err) {
- MP_TO_SEC_ERROR(err);
- rv = SECFailure;
- }
- return rv;
-}
-
-static SECStatus RSA_Init(void)
-{
- if (PR_CallOnce(&coBPInit, init_blinding_params_list) != PR_SUCCESS) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus BL_Init(void)
-{
- return RSA_Init();
-}
-
-/* cleanup at shutdown */
-void RSA_Cleanup(void)
-{
- blindingParams * bp = NULL;
- if (!coBPInit.initialized)
- return;
-
- while (!PR_CLIST_IS_EMPTY(&blindingParamsList.head)) {
- RSABlindingParams *rsabp =
- (RSABlindingParams *)PR_LIST_HEAD(&blindingParamsList.head);
- PR_REMOVE_LINK(&rsabp->link);
- /* clear parameters cache */
- while (rsabp->bp != NULL) {
- bp = rsabp->bp;
- rsabp->bp = rsabp->bp->next;
- mp_clear( &bp->f );
- mp_clear( &bp->g );
- }
- SECITEM_FreeItem(&rsabp->modulus,PR_FALSE);
- PORT_Free(rsabp);
- }
-
- if (blindingParamsList.cVar) {
- PR_DestroyCondVar(blindingParamsList.cVar);
- blindingParamsList.cVar = NULL;
- }
-
- if (blindingParamsList.lock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(blindingParamsList.lock));
- blindingParamsList.lock = NULL;
- }
-
- coBPInit.initialized = 0;
- coBPInit.inProgress = 0;
- coBPInit.status = 0;
-}
-
-/*
- * need a central place for this function to free up all the memory that
- * free_bl may have allocated along the way. Currently only RSA does this,
- * so I've put it here for now.
- */
-void BL_Cleanup(void)
-{
- RSA_Cleanup();
-}
-
-PRBool bl_parentForkedAfterC_Initialize;
-
-/*
- * Set fork flag so it can be tested in SKIP_AFTER_FORK on relevant platforms.
- */
-void BL_SetForkState(PRBool forked)
-{
- bl_parentForkedAfterC_Initialize = forked;
-}
-
diff --git a/security/nss/lib/freebl/secmpi.h b/security/nss/lib/freebl/secmpi.h
deleted file mode 100644
index 92ab612e8..000000000
--- a/security/nss/lib/freebl/secmpi.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mpi.h"
-
-#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
-
-#define CHECK_MPI_OK(func) if (MP_OKAY > (err = func)) goto cleanup
-
-#define OCTETS_TO_MPINT(oc, mp, len) \
- CHECK_MPI_OK(mp_read_unsigned_octets((mp), oc, len))
-
-#define SECITEM_TO_MPINT(it, mp) \
- CHECK_MPI_OK(mp_read_unsigned_octets((mp), (it).data, (it).len))
-
-#define MPINT_TO_SECITEM(mp, it, arena) \
- do { int mpintLen = mp_unsigned_octet_size(mp); \
- if (mpintLen <= 0) {err = MP_RANGE; goto cleanup;} \
- SECITEM_AllocItem(arena, (it), mpintLen); \
- if ((it)->data == NULL) {err = MP_MEM; goto cleanup;} \
- err = mp_to_unsigned_octets(mp, (it)->data, (it)->len); \
- if (err < 0) goto cleanup; else err = MP_OKAY; \
- } while (0)
-
-#define MP_TO_SEC_ERROR(err) \
- switch (err) { \
- case MP_MEM: PORT_SetError(SEC_ERROR_NO_MEMORY); break; \
- case MP_RANGE: PORT_SetError(SEC_ERROR_BAD_DATA); break; \
- case MP_BADARG: PORT_SetError(SEC_ERROR_INVALID_ARGS); break; \
- default: PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); break; \
- }
diff --git a/security/nss/lib/freebl/secrng.h b/security/nss/lib/freebl/secrng.h
deleted file mode 100644
index 0f75426f4..000000000
--- a/security/nss/lib/freebl/secrng.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SECRNG_H_
-#define _SECRNG_H_
-/*
- * secrng.h - public data structures and prototypes for the secure random
- * number generator
- *
- * $Id$
- */
-
-/******************************************/
-/*
-** Random number generation. A cryptographically strong random number
-** generator.
-*/
-
-#include "blapi.h"
-
-/* the number of bytes to read from the system random number generator */
-#define SYSTEM_RNG_SEED_COUNT 1024
-
-SEC_BEGIN_PROTOS
-
-/*
-** The following functions are provided by the security library
-** but are differently implemented for the UNIX, Win, and OS/2
-** versions
-*/
-
-/*
-** Get the "noisiest" information available on the system.
-** The amount of data returned depends on the system implementation.
-** It will not exceed maxbytes, but may be (much) less.
-** Returns number of noise bytes copied into buf, or zero if error.
-*/
-extern size_t RNG_GetNoise(void *buf, size_t maxbytes);
-
-/*
-** RNG_SystemInfoForRNG should be called before any use of SSL. It
-** gathers up the system specific information to help seed the
-** state of the global random number generator.
-*/
-extern void RNG_SystemInfoForRNG(void);
-
-/*
-** Use the contents (and stat) of a file to help seed the
-** global random number generator.
-*/
-extern void RNG_FileForRNG(const char *filename);
-
-/*
-** Get maxbytes bytes of random data from the system random number
-** generator.
-** Returns the number of bytes copied into buf -- maxbytes if success
-** or zero if error.
-** Errors:
-** PR_NOT_IMPLEMENTED_ERROR There is no system RNG on the platform.
-** SEC_ERROR_NEED_RANDOM The system RNG failed.
-*/
-extern size_t RNG_SystemRNG(void *buf, size_t maxbytes);
-
-SEC_END_PROTOS
-
-#endif /* _SECRNG_H_ */
diff --git a/security/nss/lib/freebl/seed.c b/security/nss/lib/freebl/seed.c
deleted file mode 100644
index 1e1639e77..000000000
--- a/security/nss/lib/freebl/seed.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-#ifdef WIN32
-#include <memory.h>
-#endif
-
-#include "seed.h"
-#include "secerr.h"
-
-static const seed_word SS[4][256] = {
- {
- 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0,
- 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
- 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
- 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
- 0x28082028, 0x04444044, 0x20002020, 0x1d8d919c,
- 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
- 0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378,
- 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
- 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
- 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
- 0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354,
- 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
- 0x24042024, 0x1c0c101c, 0x33437370, 0x18889098,
- 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
- 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
- 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
- 0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8,
- 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
- 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078,
- 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
- 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
- 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
- 0x1f0f131c, 0x19899198, 0x00000000, 0x19091118,
- 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
- 0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324,
- 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
- 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
- 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
- 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4,
- 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
- 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218,
- 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
- 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
- 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
- 0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4,
- 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
- 0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac,
- 0x36063234, 0x15051114, 0x22022220, 0x38083038,
- 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
- 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
- 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c,
- 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
- 0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8,
- 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
- 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
- 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
- 0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320,
- 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
- 0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0,
- 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
- 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
- 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
- 0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c,
- 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
- 0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244,
- 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
- 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
- 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
- 0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c,
- 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
- 0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4,
- 0x22426260, 0x29092128, 0x07070304, 0x33033330,
- 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
- 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298
- },
- {
- 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2,
- 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
- 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
- 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
- 0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1,
- 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
- 0xd013c3d3, 0x90118191, 0x10110111, 0x04060602,
- 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
- 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
- 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
- 0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2,
- 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
- 0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32,
- 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
- 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
- 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
- 0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0,
- 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
- 0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13,
- 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
- 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
- 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
- 0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1,
- 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
- 0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131,
- 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
- 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
- 0x20220222, 0x04040400, 0x68284860, 0x70314171,
- 0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991,
- 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
- 0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0,
- 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
- 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
- 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
- 0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2,
- 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
- 0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32,
- 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
- 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
- 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
- 0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571,
- 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
- 0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470,
- 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
- 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
- 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
- 0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22,
- 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
- 0x84058581, 0x14140410, 0x88098981, 0x981b8b93,
- 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
- 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
- 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
- 0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11,
- 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
- 0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3,
- 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
- 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
- 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
- 0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622,
- 0x30320232, 0x84048480, 0x68294961, 0x90138393,
- 0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0,
- 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
- 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
- 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3
- },
- {
- 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3,
- 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
- 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
- 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
- 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d,
- 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
- 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b,
- 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
- 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
- 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
- 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747,
- 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
- 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888,
- 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
- 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
- 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
- 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb,
- 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
- 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848,
- 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
- 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
- 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
- 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909,
- 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
- 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707,
- 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
- 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
- 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
- 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5,
- 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
- 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a,
- 0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
- 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
- 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
- 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5,
- 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
- 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e,
- 0x32343606, 0x11141505, 0x22202202, 0x30383808,
- 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
- 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
- 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c,
- 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
- 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8,
- 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
- 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
- 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
- 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303,
- 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
- 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2,
- 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
- 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
- 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
- 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f,
- 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
- 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646,
- 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
- 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
- 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
- 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f,
- 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
- 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4,
- 0x62602242, 0x21282909, 0x03040707, 0x33303303,
- 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
- 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a
- },
- {
- 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426,
- 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
- 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
- 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
- 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435,
- 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
- 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406,
- 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
- 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
- 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
- 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416,
- 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
- 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e,
- 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
- 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
- 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
- 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000,
- 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
- 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f,
- 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
- 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
- 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
- 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405,
- 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
- 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031,
- 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
- 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
- 0x02222022, 0x04000404, 0x48606828, 0x41717031,
- 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819,
- 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
- 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c,
- 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
- 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
- 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
- 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022,
- 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
- 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a,
- 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
- 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
- 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
- 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435,
- 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
- 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434,
- 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
- 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
- 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
- 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a,
- 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
- 0x85818405, 0x04101414, 0x89818809, 0x8b93981b,
- 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
- 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
- 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
- 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d,
- 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
- 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b,
- 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
- 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
- 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
- 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426,
- 0x02323032, 0x84808404, 0x49616829, 0x83939013,
- 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424,
- 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
- 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
- 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437
- }
-};
-
-/* key schedule constants - golden ratio */
-#define KC0 0x9e3779b9
-#define KC1 0x3c6ef373
-#define KC2 0x78dde6e6
-#define KC3 0xf1bbcdcc
-#define KC4 0xe3779b99
-#define KC5 0xc6ef3733
-#define KC6 0x8dde6e67
-#define KC7 0x1bbcdccf
-#define KC8 0x3779b99e
-#define KC9 0x6ef3733c
-#define KC10 0xdde6e678
-#define KC11 0xbbcdccf1
-#define KC12 0x779b99e3
-#define KC13 0xef3733c6
-#define KC14 0xde6e678d
-#define KC15 0xbcdccf1b
-
-
-void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
- SEED_KEY_SCHEDULE *ks)
-{
- seed_word K0, K1, K2, K3;
- seed_word t0, t1;
-
- char2word(rawkey , K0);
- char2word(rawkey+4 , K1);
- char2word(rawkey+8 , K2);
- char2word(rawkey+12, K3);
-
- t0 = (K0 + K2 - KC0);
- t1 = (K1 - K3 + KC0);
- KEYUPDATE_TEMP(t0, t1, &ks->data[0]);
- KEYSCHEDULE_UPDATE1(t0, t1, K0, K1, K2, K3, KC1);
- KEYUPDATE_TEMP(t0, t1, &ks->data[2]);
- KEYSCHEDULE_UPDATE0(t0, t1, K0, K1, K2, K3, KC2);
- KEYUPDATE_TEMP(t0, t1, &ks->data[4]);
- KEYSCHEDULE_UPDATE1(t0, t1, K0, K1, K2, K3, KC3);
- KEYUPDATE_TEMP(t0, t1, &ks->data[6]);
- KEYSCHEDULE_UPDATE0(t0, t1, K0, K1, K2, K3, KC4);
- KEYUPDATE_TEMP(t0, t1, &ks->data[8]);
- KEYSCHEDULE_UPDATE1(t0, t1, K0, K1, K2, K3, KC5);
- KEYUPDATE_TEMP(t0, t1, &ks->data[10]);
- KEYSCHEDULE_UPDATE0(t0, t1, K0, K1, K2, K3, KC6);
- KEYUPDATE_TEMP(t0, t1, &ks->data[12]);
- KEYSCHEDULE_UPDATE1(t0, t1, K0, K1, K2, K3, KC7);
- KEYUPDATE_TEMP(t0, t1, &ks->data[14]);
- KEYSCHEDULE_UPDATE0(t0, t1, K0, K1, K2, K3, KC8);
- KEYUPDATE_TEMP(t0, t1, &ks->data[16]);
- KEYSCHEDULE_UPDATE1(t0, t1, K0, K1, K2, K3, KC9);
- KEYUPDATE_TEMP(t0, t1, &ks->data[18]);
- KEYSCHEDULE_UPDATE0(t0, t1, K0, K1, K2, K3, KC10);
- KEYUPDATE_TEMP(t0, t1, &ks->data[20]);
- KEYSCHEDULE_UPDATE1(t0, t1, K0, K1, K2, K3, KC11);
- KEYUPDATE_TEMP(t0, t1, &ks->data[22]);
- KEYSCHEDULE_UPDATE0(t0, t1, K0, K1, K2, K3, KC12);
- KEYUPDATE_TEMP(t0, t1, &ks->data[24]);
- KEYSCHEDULE_UPDATE1(t0, t1, K0, K1, K2, K3, KC13);
- KEYUPDATE_TEMP(t0, t1, &ks->data[26]);
- KEYSCHEDULE_UPDATE0(t0, t1, K0, K1, K2, K3, KC14);
- KEYUPDATE_TEMP(t0, t1, &ks->data[28]);
- KEYSCHEDULE_UPDATE1(t0, t1, K0, K1, K2, K3, KC15);
- KEYUPDATE_TEMP(t0, t1, &ks->data[30]);
-}
-
-void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE],
- unsigned char d[SEED_BLOCK_SIZE],
- const SEED_KEY_SCHEDULE *ks)
-{
- seed_word L0, L1, R0, R1;
- seed_word t0, t1;
-
- char2word(s, L0);
- char2word(s+4, L1);
- char2word(s+8, R0);
- char2word(s+12, R1);
-
- E_SEED(t0, t1, L0, L1, R0, R1, 0);
- E_SEED(t0, t1, R0, R1, L0, L1, 2);
- E_SEED(t0, t1, L0, L1, R0, R1, 4);
- E_SEED(t0, t1, R0, R1, L0, L1, 6);
- E_SEED(t0, t1, L0, L1, R0, R1, 8);
- E_SEED(t0, t1, R0, R1, L0, L1, 10);
- E_SEED(t0, t1, L0, L1, R0, R1, 12);
- E_SEED(t0, t1, R0, R1, L0, L1, 14);
- E_SEED(t0, t1, L0, L1, R0, R1, 16);
- E_SEED(t0, t1, R0, R1, L0, L1, 18);
- E_SEED(t0, t1, L0, L1, R0, R1, 20);
- E_SEED(t0, t1, R0, R1, L0, L1, 22);
- E_SEED(t0, t1, L0, L1, R0, R1, 24);
- E_SEED(t0, t1, R0, R1, L0, L1, 26);
- E_SEED(t0, t1, L0, L1, R0, R1, 28);
- E_SEED(t0, t1, R0, R1, L0, L1, 30);
-
- word2char(R0, d);
- word2char(R1, d+4);
- word2char(L0, d+8);
- word2char(L1, d+12);
-}
-
-void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
- unsigned char d[SEED_BLOCK_SIZE],
- const SEED_KEY_SCHEDULE *ks)
-{
- seed_word L0, L1, R0, R1;
- seed_word t0, t1;
-
- char2word(s, L0);
- char2word(s+4, L1);
- char2word(s+8, R0);
- char2word(s+12, R1);
-
- E_SEED(t0, t1, L0, L1, R0, R1, 30);
- E_SEED(t0, t1, R0, R1, L0, L1, 28);
- E_SEED(t0, t1, L0, L1, R0, R1, 26);
- E_SEED(t0, t1, R0, R1, L0, L1, 24);
- E_SEED(t0, t1, L0, L1, R0, R1, 22);
- E_SEED(t0, t1, R0, R1, L0, L1, 20);
- E_SEED(t0, t1, L0, L1, R0, R1, 18);
- E_SEED(t0, t1, R0, R1, L0, L1, 16);
- E_SEED(t0, t1, L0, L1, R0, R1, 14);
- E_SEED(t0, t1, R0, R1, L0, L1, 12);
- E_SEED(t0, t1, L0, L1, R0, R1, 10);
- E_SEED(t0, t1, R0, R1, L0, L1, 8);
- E_SEED(t0, t1, L0, L1, R0, R1, 6);
- E_SEED(t0, t1, R0, R1, L0, L1, 4);
- E_SEED(t0, t1, L0, L1, R0, R1, 2);
- E_SEED(t0, t1, R0, R1, L0, L1, 0);
-
- word2char(R0, d);
- word2char(R1, d+4);
- word2char(L0, d+8);
- word2char(L1, d+12);
-}
-
-void SEED_ecb_encrypt(const unsigned char *in,
- unsigned char *out,
- const SEED_KEY_SCHEDULE *ks, int enc)
-{
- if (enc) {
- SEED_encrypt(in, out, ks);
- } else {
- SEED_decrypt(in, out, ks);
- }
-}
-
-
-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)
-{
- size_t n;
- unsigned char tmp[SEED_BLOCK_SIZE];
- const unsigned char *iv = ivec;
-
- if (enc) {
- while (len >= SEED_BLOCK_SIZE) {
- for (n = 0; n < SEED_BLOCK_SIZE; ++n)
- out[n] = in[n] ^ iv[n];
-
- SEED_encrypt(out, out, ks);
- iv = out;
- len -= SEED_BLOCK_SIZE;
- in += SEED_BLOCK_SIZE;
- out += SEED_BLOCK_SIZE;
- }
-
- if (len) {
- for (n = 0; n < len; ++n)
- out[n] = in[n] ^ iv[n];
-
- for (n = len; n < SEED_BLOCK_SIZE; ++n)
- out[n] = iv[n];
-
- SEED_encrypt(out, out, ks);
- iv = out;
- }
-
- memcpy(ivec, iv, SEED_BLOCK_SIZE);
- } else if (in != out) {
- while (len >= SEED_BLOCK_SIZE) {
- SEED_decrypt(in, out, ks);
-
- for (n = 0; n < SEED_BLOCK_SIZE; ++n)
- out[n] ^= iv[n];
-
- iv = in;
- len -= SEED_BLOCK_SIZE;
- in += SEED_BLOCK_SIZE;
- out += SEED_BLOCK_SIZE;
- }
-
- if (len) {
- SEED_decrypt(in, tmp, ks);
-
- for (n = 0; n < len; ++n)
- out[n] = tmp[n] ^ iv[n];
-
- iv = in;
- }
-
- memcpy(ivec, iv, SEED_BLOCK_SIZE);
- } else {
- while (len >= SEED_BLOCK_SIZE) {
- memcpy(tmp, in, SEED_BLOCK_SIZE);
- SEED_decrypt(in, out, ks);
-
- for (n = 0; n < SEED_BLOCK_SIZE; ++n)
- out[n] ^= ivec[n];
-
- memcpy(ivec, tmp, SEED_BLOCK_SIZE);
- len -= SEED_BLOCK_SIZE;
- in += SEED_BLOCK_SIZE;
- out += SEED_BLOCK_SIZE;
- }
-
- if (len) {
- memcpy(tmp, in, SEED_BLOCK_SIZE);
- SEED_decrypt(tmp, tmp, ks);
-
- for (n = 0; n < len; ++n)
- out[n] = tmp[n] ^ ivec[n];
-
- memcpy(ivec, tmp, SEED_BLOCK_SIZE);
- }
- }
-}
-
-SEEDContext *
-SEED_AllocateContext(void)
-{
- return PORT_ZNew(SEEDContext);
-}
-
-SECStatus
-SEED_InitContext(SEEDContext *cx, const unsigned char *key,
- unsigned int keylen, const unsigned char *iv,
- int mode, unsigned int encrypt,unsigned int unused)
-{
- if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- switch (mode) {
- case NSS_SEED:
- SEED_set_key(key, &cx->ks);
- cx->mode = NSS_SEED;
- cx->encrypt = encrypt;
- break;
-
- case NSS_SEED_CBC:
- memcpy(cx->iv, iv, 16);
- SEED_set_key(key, &cx->ks);
- cx->mode = NSS_SEED_CBC;
- cx->encrypt = encrypt;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-SEEDContext *
-SEED_CreateContext(const unsigned char * key, const unsigned char *iv,
- int mode, PRBool encrypt)
-{
- SEEDContext *cx = PORT_ZNew(SEEDContext);
- SECStatus rv = SEED_InitContext(cx, key, SEED_KEY_LENGTH, iv, mode,
- encrypt, 0);
-
- if (rv != SECSuccess) {
- PORT_ZFree(cx, sizeof *cx);
- cx = NULL;
- }
-
- return cx;
-}
-
-void
-SEED_DestroyContext(SEEDContext *cx, PRBool freeit)
-{
- if (cx) {
- memset(cx, 0, sizeof *cx);
-
- if (freeit)
- PORT_Free(cx);
- }
-}
-
-SECStatus
-SEED_Encrypt(SEEDContext *cx, unsigned char *out, unsigned int *outLen,
- unsigned int maxOutLen, const unsigned char *in,
- unsigned int inLen)
-{
- if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (!cx->encrypt) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- switch (cx->mode) {
- case NSS_SEED:
- SEED_ecb_encrypt(in, out, &cx->ks, 1);
- *outLen = inLen;
- break;
-
- case NSS_SEED_CBC:
- SEED_cbc_encrypt(in, out, inLen, &cx->ks, cx->iv, 1);
- *outLen = inLen;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-SECStatus
-SEED_Decrypt(SEEDContext *cx, unsigned char *out, unsigned int *outLen,
- unsigned int maxOutLen, const unsigned char *in,
- unsigned int inLen)
-{
- if (!cx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (cx->encrypt) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- switch (cx->mode) {
- case NSS_SEED:
- SEED_ecb_encrypt(in, out, &cx->ks, 0);
- *outLen = inLen;
- break;
-
- case NSS_SEED_CBC:
- SEED_cbc_encrypt(in, out, inLen, &cx->ks, cx->iv, 0);
- *outLen = inLen;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/freebl/seed.h b/security/nss/lib/freebl/seed.h
deleted file mode 100644
index 8e09dbf30..000000000
--- a/security/nss/lib/freebl/seed.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef HEADER_SEED_H
-#define HEADER_SEED_H
-
-#include <string.h>
-#include "blapi.h"
-
-#if !defined(NO_SYS_TYPES_H)
-# include <sys/types.h>
-#endif
-
-typedef PRUint32 seed_word;
-
-#define G_FUNC(v) \
- SS[0][((v) & 0xff)] ^ \
- SS[1][((v)>> 8 & 0xff)] ^ \
- SS[2][((v)>>16 & 0xff)] ^ \
- SS[3][((v)>>24 & 0xff)]
-
-#define char2word(c, i) \
- (i) = ((((seed_word)((c)[0])) << 24) | \
- (((seed_word)((c)[1])) << 16) | \
- (((seed_word)((c)[2])) << 8) | \
- ((seed_word)((c)[3])))
-
-#define word2char(l, c) \
- *((c)+0) = (unsigned char)((l)>>24); \
- *((c)+1) = (unsigned char)((l)>>16); \
- *((c)+2) = (unsigned char)((l)>> 8); \
- *((c)+3) = (unsigned char)((l) )
-
-#define KEYSCHEDULE_UPDATE0(T0, T1, K0, K1, K2, K3, KC) \
- (T0) = (K2); \
- (K2) = (((K2)<<8) ^ ((K3)>>24)); \
- (K3) = (((K3)<<8) ^ ((T0)>>24)); \
- (T0) = ((K0) + (K2) - (KC)); \
- (T1) = ((K1) + (KC) - (K3))
-
-#define KEYSCHEDULE_UPDATE1(T0, T1, K0, K1, K2, K3, KC) \
- (T0) = (K0); \
- (K0) = (((K0)>>8) ^ ((K1)<<24)); \
- (K1) = (((K1)>>8) ^ ((T0)<<24)); \
- (T0) = ((K0) + (K2) - (KC)); \
- (T1) = ((K1) + (KC) - (K3))
-
-#define KEYUPDATE_TEMP(T0, T1, K) \
- (K)[0] = G_FUNC((T0)); \
- (K)[1] = G_FUNC((T1))
-
-#define XOR_SEEDBLOCK(DST, SRC) \
- (DST)[0] ^= (SRC)[0]; \
- (DST)[1] ^= (SRC)[1]; \
- (DST)[2] ^= (SRC)[2]; \
- (DST)[3] ^= (SRC)[3]
-
-#define MOV_SEEDBLOCK(DST, SRC) \
- (DST)[0] = (SRC)[0]; \
- (DST)[1] = (SRC)[1]; \
- (DST)[2] = (SRC)[2]; \
- (DST)[3] = (SRC)[3]
-
-# define CHAR2WORD(C, I) \
- char2word((C), (I)[0]); \
- char2word((C)+4, (I)[1]); \
- char2word((C)+8, (I)[2]); \
- char2word((C)+12, (I)[3])
-
-# define WORD2CHAR(I, C) \
- word2char((I)[0], (C)); \
- word2char((I)[1], (C+4)); \
- word2char((I)[2], (C+8)); \
- word2char((I)[3], (C+12))
-
-# define E_SEED(T0, T1, X1, X2, X3, X4, rbase) \
- (T0) = (X3) ^ (ks->data)[(rbase)]; \
- (T1) = (X4) ^ (ks->data)[(rbase)+1]; \
- (T1) ^= (T0); \
- (T1) = G_FUNC(T1); \
- (T0) += (T1); \
- (T0) = G_FUNC(T0); \
- (T1) += (T0); \
- (T1) = G_FUNC(T1); \
- (T0) += (T1); \
- (X1) ^= (T0); \
- (X2) ^= (T1)
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct seed_key_st {
- PRUint32 data[32];
-} SEED_KEY_SCHEDULE;
-
-
-
-struct SEEDContextStr {
- unsigned char iv[SEED_BLOCK_SIZE];
- SEED_KEY_SCHEDULE ks;
- int mode;
- unsigned int encrypt;
-};
-
-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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HEADER_SEED_H */
diff --git a/security/nss/lib/freebl/sha-fast-amd64-sun.s b/security/nss/lib/freebl/sha-fast-amd64-sun.s
deleted file mode 100644
index 71996f04f..000000000
--- a/security/nss/lib/freebl/sha-fast-amd64-sun.s
+++ /dev/null
@@ -1,2110 +0,0 @@
-/ This Source Code Form is subject to the terms of the Mozilla Public
-/ License, v. 2.0. If a copy of the MPL was not distributed with this
-/ file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
- .file "sha_fast.c"
- .text
- .align 16
-.globl SHA1_Begin
- .type SHA1_Begin, @function
-SHA1_Begin:
-.LFB4:
- movl $4023233417, %ecx
- movl $2562383102, %edx
- movl $3285377520, %eax
- movq $0, 64(%rdi)
- movq $1732584193, 72(%rdi)
- movq %rcx, 80(%rdi)
- movq %rdx, 88(%rdi)
- movq $271733878, 96(%rdi)
- movq %rax, 104(%rdi)
- ret
-.LFE4:
- .size SHA1_Begin, .-SHA1_Begin
- .align 16
- .type shaCompress, @function
-shaCompress:
-.LFB7:
- pushq %r15
-.LCFI0:
- pushq %r14
-.LCFI1:
- pushq %r13
-.LCFI2:
- pushq %r12
-.LCFI3:
- movq -88(%rdi), %r12
- movq -80(%rdi), %r10
- movq -72(%rdi), %r13
- movq -64(%rdi), %r8
- pushq %rbx
-.LCFI4:
- movq -56(%rdi), %rcx
- movl (%rsi), %eax
- movl %r12d, %edx
- movq %r13, %r9
- roll $5, %edx
- movl 4(%rsi), %ebx
- xorq %r8, %r9
-/APP
- bswap %eax
-/NO_APP
- andq %r10, %r9
- mov %eax, %r15d
- roll $30, %r10d
- movq %r15, -48(%rdi)
- xorq %r8, %r9
- movq -48(%rdi), %r14
- addq %r9, %rdx
- movq %r10, %rax
- movl %r12d, %r15d
- addq %rcx, %rdx
- xorq %r13, %rax
- roll $30, %r15d
- leaq 1518500249(%rdx,%r14), %rdx
- andq %r12, %rax
- movq %r15, %r12
-/APP
- bswap %ebx
-/NO_APP
- movl %edx, %ecx
- mov %ebx, %r11d
- xorq %r13, %rax
- movq %r11, -40(%rdi)
- roll $5, %ecx
- movq -40(%rdi), %r9
- addq %rax, %rcx
- xorq %r10, %r12
- movl 8(%rsi), %r14d
- addq %r8, %rcx
- andq %rdx, %r12
- movl %edx, %r11d
- leaq 1518500249(%rcx,%r9), %rcx
- xorq %r10, %r12
- roll $30, %r11d
-/APP
- bswap %r14d
-/NO_APP
- movl %ecx, %r8d
- mov %r14d, %ebx
- movl 12(%rsi), %r9d
- movq %rbx, -32(%rdi)
- roll $5, %r8d
- movq -32(%rdi), %rax
- addq %r12, %r8
- movq %r11, %r12
- movl %ecx, %ebx
- addq %r13, %r8
- xorq %r15, %r12
- roll $30, %ebx
- leaq 1518500249(%r8,%rax), %r8
- andq %rcx, %r12
- movl 16(%rsi), %eax
-/APP
- bswap %r9d
-/NO_APP
- movl %r8d, %edx
- mov %r9d, %r14d
- xorq %r15, %r12
- movq %r14, -24(%rdi)
- roll $5, %edx
- movq -24(%rdi), %r13
- addq %r12, %rdx
- movq %rbx, %r12
- movl %r8d, %r14d
- addq %r10, %rdx
- leaq 1518500249(%rdx,%r13), %rdx
- movl 20(%rsi), %r13d
-/APP
- bswap %eax
-/NO_APP
- movl %edx, %ecx
- mov %eax, %r9d
- roll $5, %ecx
- xorq %r11, %r12
- movq %r9, -16(%rdi)
- andq %r8, %r12
- movq -16(%rdi), %r10
- roll $30, %r14d
- xorq %r11, %r12
- movq %r14, %rax
- movl %edx, %r9d
- addq %r12, %rcx
- xorq %rbx, %rax
- roll $30, %r9d
- addq %r15, %rcx
- andq %rdx, %rax
- leaq 1518500249(%rcx,%r10), %rcx
- xorq %rbx, %rax
- movl 24(%rsi), %r10d
-/APP
- bswap %r13d
-/NO_APP
- movl %ecx, %r8d
- mov %r13d, %r15d
- movq %r15, -8(%rdi)
- roll $5, %r8d
- movq -8(%rdi), %r12
- addq %rax, %r8
- movl %ecx, %r15d
- addq %r11, %r8
- movq %r9, %r11
- roll $30, %r15d
- leaq 1518500249(%r8,%r12), %r8
- xorq %r14, %r11
- movl 28(%rsi), %r12d
-/APP
- bswap %r10d
-/NO_APP
- andq %rcx, %r11
- mov %r10d, %r13d
- movl %r8d, %edx
- movq %r13, (%rdi)
- xorq %r14, %r11
- movq (%rdi), %rax
- roll $5, %edx
- movq %r15, %r10
- movl %r8d, %r13d
- addq %r11, %rdx
- xorq %r9, %r10
- roll $30, %r13d
- addq %rbx, %rdx
- andq %r8, %r10
- leaq 1518500249(%rdx,%rax), %rdx
- xorq %r9, %r10
- movl 32(%rsi), %eax
-/APP
- bswap %r12d
-/NO_APP
- movl %edx, %ecx
- mov %r12d, %ebx
- movq %rbx, 8(%rdi)
- roll $5, %ecx
- movq 8(%rdi), %r11
- addq %r10, %rcx
- movq %r13, %r10
- movl %edx, %ebx
- addq %r14, %rcx
- leaq 1518500249(%rcx,%r11), %rcx
-/APP
- bswap %eax
-/NO_APP
- movl %ecx, %r8d
- mov %eax, %r12d
- roll $5, %r8d
- xorq %r15, %r10
- movq %r12, 16(%rdi)
- andq %rdx, %r10
- movq 16(%rdi), %r14
- roll $30, %ebx
- xorq %r15, %r10
- movq %rbx, %rax
- movl 36(%rsi), %r11d
- addq %r10, %r8
- xorq %r13, %rax
- movl %ecx, %r12d
- addq %r9, %r8
- andq %rcx, %rax
- roll $30, %r12d
- leaq 1518500249(%r8,%r14), %r8
- xorq %r13, %rax
- movl 40(%rsi), %r14d
-/APP
- bswap %r11d
-/NO_APP
- movl %r8d, %edx
- mov %r11d, %r9d
- movq %r12, %r11
- movq %r9, 24(%rdi)
- roll $5, %edx
- movq 24(%rdi), %r10
- addq %rax, %rdx
- xorq %rbx, %r11
- movl %r8d, %r9d
- addq %r15, %rdx
- andq %r8, %r11
- roll $30, %r9d
- leaq 1518500249(%rdx,%r10), %rdx
- xorq %rbx, %r11
- movl 44(%rsi), %r10d
-/APP
- bswap %r14d
-/NO_APP
- movl %edx, %ecx
- mov %r14d, %r15d
- movq %r15, 32(%rdi)
- roll $5, %ecx
- movq 32(%rdi), %rax
- addq %r11, %rcx
- movq %r9, %r11
- movl %edx, %r15d
- addq %r13, %rcx
- xorq %r12, %r11
- roll $30, %r15d
- leaq 1518500249(%rcx,%rax), %rcx
- andq %rdx, %r11
- movl 48(%rsi), %eax
-/APP
- bswap %r10d
-/NO_APP
- movl %ecx, %r8d
- mov %r10d, %r14d
- xorq %r12, %r11
- movq %r14, 40(%rdi)
- roll $5, %r8d
- movq 40(%rdi), %r13
- addq %r11, %r8
- movq %r15, %r10
- movl %ecx, %r14d
- addq %rbx, %r8
- xorq %r9, %r10
- leaq 1518500249(%r8,%r13), %r8
- movl 52(%rsi), %r13d
-/APP
- bswap %eax
-/NO_APP
- movl %r8d, %edx
- mov %eax, %ebx
- roll $5, %edx
- andq %rcx, %r10
- movq %rbx, 48(%rdi)
- xorq %r9, %r10
- movq 48(%rdi), %r11
- roll $30, %r14d
- addq %r10, %rdx
- movq %r14, %rax
- movl %r8d, %ebx
- addq %r12, %rdx
- xorq %r15, %rax
- roll $30, %ebx
- leaq 1518500249(%rdx,%r11), %rdx
- andq %r8, %rax
- movl 56(%rsi), %r11d
-/APP
- bswap %r13d
-/NO_APP
- movl %edx, %ecx
- mov %r13d, %r12d
- xorq %r15, %rax
- movq %r12, 56(%rdi)
- roll $5, %ecx
- movq 56(%rdi), %r10
- addq %rax, %rcx
- movl %edx, %r12d
- addq %r9, %rcx
- movq %rbx, %r9
- roll $30, %r12d
- leaq 1518500249(%rcx,%r10), %rcx
- xorq %r14, %r9
- movl 60(%rsi), %r10d
-/APP
- bswap %r11d
-/NO_APP
- andq %rdx, %r9
- mov %r11d, %r13d
- movl %ecx, %r8d
- movq %r13, 64(%rdi)
- xorq %r14, %r9
- movq 64(%rdi), %rax
- roll $5, %r8d
- movq %r12, %r11
- movl %ecx, %r13d
- addq %r9, %r8
- xorq %rbx, %r11
- roll $30, %r13d
- addq %r15, %r8
- andq %rcx, %r11
- leaq 1518500249(%r8,%rax), %r8
- xorq %rbx, %r11
-/APP
- bswap %r10d
-/NO_APP
- movl %r8d, %esi
- mov %r10d, %r15d
- movq %r15, 72(%rdi)
- roll $5, %esi
- movq 72(%rdi), %r9
- movq 56(%rdi), %r10
- movq 16(%rdi), %rcx
- addq %r11, %rsi
- movq -32(%rdi), %rdx
- addq %r14, %rsi
- movq -48(%rdi), %rax
- leaq 1518500249(%rsi,%r9), %r14
- movq %r13, %r11
- movl %r8d, %r15d
- xorq %rcx, %r10
- xorq %rdx, %r10
- movl %r14d, %ecx
- xorl %eax, %r10d
- roll %r10d
- roll $5, %ecx
- xorq %r12, %r11
- andq %r8, %r11
- movq %r10, -48(%rdi)
- movq -48(%rdi), %r9
- xorq %r12, %r11
- roll $30, %r15d
- movl %r14d, %r10d
- addq %r11, %rcx
- movq 64(%rdi), %r11
- movq 24(%rdi), %rdx
- addq %rbx, %rcx
- movq -24(%rdi), %rbx
- movq -40(%rdi), %rax
- leaq 1518500249(%rcx,%r9), %rcx
- movq %r15, %r8
- roll $30, %r10d
- xorq %rdx, %r11
- xorq %r13, %r8
- xorq %rbx, %r11
- andq %r14, %r8
- movl %ecx, %r9d
- xorl %eax, %r11d
- xorq %r13, %r8
- roll $5, %r9d
- roll %r11d
- addq %r8, %r9
- movq %r10, %rax
- movq %r11, -40(%rdi)
- movq -40(%rdi), %rsi
- addq %r12, %r9
- movq 72(%rdi), %rbx
- movq 32(%rdi), %rdx
- xorq %r15, %rax
- movq -16(%rdi), %r14
- movq -32(%rdi), %r12
- andq %rcx, %rax
- leaq 1518500249(%r9,%rsi), %r9
- xorq %r15, %rax
- movl %ecx, %r11d
- xorq %rdx, %rbx
- roll $30, %r11d
- xorq %r14, %rbx
- movl %r9d, %esi
- xorl %r12d, %ebx
- roll $5, %esi
- roll %ebx
- addq %rax, %rsi
- movq %rbx, -32(%rdi)
- movq -32(%rdi), %r8
- addq %r13, %rsi
- movq -48(%rdi), %r12
- movq 40(%rdi), %rdx
- movq %r11, %r13
- movq -8(%rdi), %r14
- movq -24(%rdi), %rcx
- movl %r9d, %ebx
- leaq 1518500249(%rsi,%r8), %rsi
- xorq %rdx, %r12
- xorq %r14, %r12
- movl %esi, %r8d
- xorl %ecx, %r12d
- roll %r12d
- roll $5, %r8d
- xorq %r10, %r13
- andq %r9, %r13
- movq %r12, -24(%rdi)
- movq -24(%rdi), %rax
- xorq %r10, %r13
- roll $30, %ebx
- movl %esi, %r12d
- addq %r13, %r8
- xorq %rbx, %rsi
- roll $30, %r12d
- addq %r15, %r8
- movq -40(%rdi), %r15
- movq 48(%rdi), %rdx
- movq (%rdi), %r14
- movq -16(%rdi), %r9
- leaq 1518500249(%r8,%rax), %r13
- xorq %r11, %rsi
- xorq %rdx, %r15
- movl %r13d, %ecx
- xorq %r14, %r15
- roll $5, %ecx
- xorl %r9d, %r15d
- addq %rsi, %rcx
- roll %r15d
- addq %r10, %rcx
- movq %r15, -16(%rdi)
- movq -16(%rdi), %rsi
- movl %r13d, %r15d
- movq -32(%rdi), %r14
- movq 56(%rdi), %rax
- xorq %r12, %r13
- movq 8(%rdi), %rdx
- movq -8(%rdi), %r10
- xorq %rbx, %r13
- leaq 1859775393(%rcx,%rsi), %r9
- roll $30, %r15d
- xorq %rax, %r14
- xorq %rdx, %r14
- movl %r9d, %esi
- xorl %r10d, %r14d
- roll $5, %esi
- roll %r14d
- addq %r13, %rsi
- movq %r14, -8(%rdi)
- movq -8(%rdi), %r8
- addq %r11, %rsi
- movq -24(%rdi), %r13
- movq 64(%rdi), %rax
- movl %r9d, %r14d
- movq 16(%rdi), %rdx
- movq (%rdi), %r11
- xorq %r15, %r9
- leaq 1859775393(%rsi,%r8), %r10
- xorq %rax, %r13
- xorq %rdx, %r13
- movl %r10d, %r8d
- xorl %r11d, %r13d
- roll $5, %r8d
- roll %r13d
- xorq %r12, %r9
- roll $30, %r14d
- addq %r9, %r8
- movq %r13, (%rdi)
- movq (%rdi), %rcx
- addq %rbx, %r8
- movq -16(%rdi), %rbx
- movq 72(%rdi), %rax
- movq 24(%rdi), %rdx
- movq 8(%rdi), %r9
- movl %r10d, %r13d
- leaq 1859775393(%r8,%rcx), %r11
- xorq %r14, %r10
- roll $30, %r13d
- xorq %rax, %rbx
- xorq %r15, %r10
- xorq %rdx, %rbx
- movl %r11d, %ecx
- xorl %r9d, %ebx
- roll $5, %ecx
- roll %ebx
- addq %r10, %rcx
- movq %rbx, 8(%rdi)
- movq 8(%rdi), %rsi
- addq %r12, %rcx
- movq -8(%rdi), %r12
- movq -48(%rdi), %rax
- movl %r11d, %ebx
- movq 32(%rdi), %rdx
- movq 16(%rdi), %r9
- xorq %r13, %r11
- leaq 1859775393(%rcx,%rsi), %r10
- xorq %r14, %r11
- roll $30, %ebx
- xorq %rax, %r12
- xorq %rdx, %r12
- movl %r10d, %esi
- xorl %r9d, %r12d
- roll $5, %esi
- roll %r12d
- addq %r11, %rsi
- movq %r12, 16(%rdi)
- addq %r15, %rsi
- movq 16(%rdi), %r8
- movq (%rdi), %r15
- movq -40(%rdi), %rax
- movl %r10d, %r12d
- movq 40(%rdi), %rdx
- movq 24(%rdi), %r9
- xorq %rbx, %r10
- leaq 1859775393(%rsi,%r8), %r11
- xorq %r13, %r10
- xorq %rax, %r15
- xorq %rdx, %r15
- movl %r11d, %r8d
- xorl %r9d, %r15d
- roll $5, %r8d
- roll %r15d
- addq %r10, %r8
- movq %r15, 24(%rdi)
- movq 24(%rdi), %rcx
- addq %r14, %r8
- movq 8(%rdi), %r14
- movq -32(%rdi), %rax
- roll $30, %r12d
- movq 48(%rdi), %rdx
- movq 32(%rdi), %r10
- movl %r11d, %r15d
- leaq 1859775393(%r8,%rcx), %r9
- xorq %r12, %r11
- roll $30, %r15d
- xorq %rax, %r14
- xorq %rbx, %r11
- xorq %rdx, %r14
- movl %r9d, %ecx
- xorl %r10d, %r14d
- roll $5, %ecx
- roll %r14d
- addq %r11, %rcx
- movq %r14, 32(%rdi)
- addq %r13, %rcx
- movq 32(%rdi), %rsi
- movq 16(%rdi), %r13
- movq -24(%rdi), %rax
- movl %r9d, %r14d
- movq 56(%rdi), %rdx
- movq 40(%rdi), %r11
- xorq %r15, %r9
- leaq 1859775393(%rcx,%rsi), %r10
- xorq %r12, %r9
- roll $30, %r14d
- xorq %rax, %r13
- xorq %rdx, %r13
- movl %r10d, %esi
- xorl %r11d, %r13d
- roll $5, %esi
- roll %r13d
- addq %r9, %rsi
- movq %r13, 40(%rdi)
- movq 40(%rdi), %r8
- addq %rbx, %rsi
- movq 24(%rdi), %rbx
- movq -16(%rdi), %rax
- movl %r10d, %r13d
- movq 64(%rdi), %rdx
- movq 48(%rdi), %r9
- xorq %r14, %r10
- leaq 1859775393(%rsi,%r8), %r11
- xorq %r15, %r10
- roll $30, %r13d
- xorq %rax, %rbx
- xorq %rdx, %rbx
- movl %r11d, %r8d
- xorl %r9d, %ebx
- roll $5, %r8d
- roll %ebx
- addq %r10, %r8
- movq %rbx, 48(%rdi)
- addq %r12, %r8
- movq 48(%rdi), %rcx
- movq 32(%rdi), %r12
- movq -8(%rdi), %rax
- movl %r11d, %ebx
- movq 72(%rdi), %rdx
- movq 56(%rdi), %r9
- leaq 1859775393(%r8,%rcx), %r10
- xorq %rax, %r12
- xorq %rdx, %r12
- movl %r10d, %ecx
- xorl %r9d, %r12d
- xorq %r13, %r11
- roll $5, %ecx
- xorq %r14, %r11
- roll %r12d
- roll $30, %ebx
- addq %r11, %rcx
- movq %r12, 56(%rdi)
- movq 56(%rdi), %rsi
- addq %r15, %rcx
- movq 40(%rdi), %r15
- movq (%rdi), %rax
- movq -48(%rdi), %rdx
- movq 64(%rdi), %r9
- movl %r10d, %r12d
- leaq 1859775393(%rcx,%rsi), %r11
- xorq %rbx, %r10
- roll $30, %r12d
- xorq %rax, %r15
- xorq %r13, %r10
- xorq %rdx, %r15
- movl %r11d, %esi
- xorl %r9d, %r15d
- roll $5, %esi
- roll %r15d
- addq %r10, %rsi
- movq %r15, 64(%rdi)
- movq 64(%rdi), %r8
- addq %r14, %rsi
- movq 48(%rdi), %r14
- movq 8(%rdi), %rax
- movl %r11d, %r15d
- movq -40(%rdi), %rdx
- movq 72(%rdi), %r10
- xorq %r12, %r11
- leaq 1859775393(%rsi,%r8), %r9
- xorq %rbx, %r11
- roll $30, %r15d
- xorq %rax, %r14
- xorq %rdx, %r14
- movl %r9d, %r8d
- xorl %r10d, %r14d
- roll $5, %r8d
- roll %r14d
- addq %r11, %r8
- movq %r14, 72(%rdi)
- addq %r13, %r8
- movq 72(%rdi), %rcx
- movq 56(%rdi), %r13
- movq 16(%rdi), %rax
- movl %r9d, %r14d
- movq -32(%rdi), %rdx
- movq -48(%rdi), %r11
- leaq 1859775393(%r8,%rcx), %r10
- xorq %rax, %r13
- xorq %rdx, %r13
- movl %r10d, %ecx
- xorl %r11d, %r13d
- roll $5, %ecx
- roll %r13d
- xorq %r15, %r9
- roll $30, %r14d
- xorq %r12, %r9
- movq %r13, -48(%rdi)
- movq -48(%rdi), %rsi
- addq %r9, %rcx
- movl %r10d, %r13d
- xorq %r14, %r10
- addq %rbx, %rcx
- movq 64(%rdi), %rbx
- movq 24(%rdi), %rax
- movq -24(%rdi), %rdx
- leaq 1859775393(%rcx,%rsi), %r11
- movq -40(%rdi), %r9
- xorq %r15, %r10
- roll $30, %r13d
- xorq %rax, %rbx
- movl %r11d, %esi
- xorq %rdx, %rbx
- roll $5, %esi
- xorl %r9d, %ebx
- addq %r10, %rsi
- roll %ebx
- addq %r12, %rsi
- movq %rbx, -40(%rdi)
- movq -40(%rdi), %r8
- movl %r11d, %ebx
- movq 72(%rdi), %r12
- movq 32(%rdi), %rax
- xorq %r13, %r11
- movq -16(%rdi), %rdx
- movq -32(%rdi), %r9
- xorq %r14, %r11
- leaq 1859775393(%rsi,%r8), %r10
- roll $30, %ebx
- xorq %rax, %r12
- xorq %rdx, %r12
- movl %r10d, %r8d
- xorl %r9d, %r12d
- roll $5, %r8d
- roll %r12d
- addq %r11, %r8
- movq %r12, -32(%rdi)
- movq -32(%rdi), %rcx
- addq %r15, %r8
- movq -48(%rdi), %r15
- movq 40(%rdi), %rax
- movl %r10d, %r12d
- movq -8(%rdi), %rdx
- movq -24(%rdi), %r9
- xorq %rbx, %r10
- leaq 1859775393(%r8,%rcx), %r11
- xorq %r13, %r10
- xorq %rax, %r15
- xorq %rdx, %r15
- movl %r11d, %ecx
- xorl %r9d, %r15d
- roll $5, %ecx
- roll %r15d
- addq %r10, %rcx
- addq %r14, %rcx
- movq %r15, -24(%rdi)
- movq -24(%rdi), %rsi
- movq -40(%rdi), %r14
- movq 48(%rdi), %rax
- roll $30, %r12d
- movq (%rdi), %rdx
- movq -16(%rdi), %r10
- movl %r11d, %r15d
- leaq 1859775393(%rcx,%rsi), %r9
- xorq %r12, %r11
- roll $30, %r15d
- xorq %rax, %r14
- xorq %rbx, %r11
- xorq %rdx, %r14
- movl %r9d, %esi
- xorl %r10d, %r14d
- roll $5, %esi
- roll %r14d
- addq %r11, %rsi
- movq %r14, -16(%rdi)
- movq -16(%rdi), %r8
- addq %r13, %rsi
- movq -32(%rdi), %r11
- movq 56(%rdi), %rax
- movl %r9d, %r14d
- movq 8(%rdi), %rdx
- movq -8(%rdi), %r10
- xorq %r15, %r9
- leaq 1859775393(%rsi,%r8), %r13
- xorq %r12, %r9
- roll $30, %r14d
- xorq %rax, %r11
- xorq %rdx, %r11
- movl %r13d, %r8d
- xorl %r10d, %r11d
- roll $5, %r8d
- movl %r13d, %r10d
- roll %r11d
- addq %r9, %r8
- xorq %r14, %r13
- movq %r11, -8(%rdi)
- addq %rbx, %r8
- movq -8(%rdi), %rbx
- movq -24(%rdi), %r9
- movq 64(%rdi), %rax
- xorq %r15, %r13
- movq 16(%rdi), %rdx
- movq (%rdi), %rcx
- leaq 1859775393(%r8,%rbx), %r11
- xorq %rax, %r9
- xorq %rdx, %r9
- movl %r11d, %ebx
- xorl %ecx, %r9d
- roll $5, %ebx
- roll %r9d
- addq %r13, %rbx
- movq %r9, (%rdi)
- movq (%rdi), %rsi
- addq %r12, %rbx
- movq -16(%rdi), %r12
- movq 72(%rdi), %r13
- movl %r11d, %r9d
- leaq 1859775393(%rbx,%rsi), %rcx
- movl %r10d, %ebx
- movq 24(%rdi), %r10
- movq 8(%rdi), %rax
- xorq %r13, %r12
- roll $30, %ebx
- movl %ecx, %esi
- xorq %r10, %r12
- xorq %rbx, %r11
- roll $5, %esi
- xorl %eax, %r12d
- xorq %r14, %r11
- roll $30, %r9d
- roll %r12d
- addq %r11, %rsi
- movq %rcx, %rax
- movq %r12, 8(%rdi)
- movq 8(%rdi), %rdx
- addq %r15, %rsi
- movq -8(%rdi), %r11
- movq -48(%rdi), %r13
- movl %ecx, %r12d
- movq 32(%rdi), %r10
- movq 16(%rdi), %r8
- orq %r9, %rcx
- leaq 1859775393(%rsi,%rdx), %rsi
- andq %rbx, %rcx
- andq %r9, %rax
- xorq %r13, %r11
- orq %rcx, %rax
- roll $30, %r12d
- xorq %r10, %r11
- movq %rsi, %r10
- xorl %r8d, %r11d
- movl %esi, %r8d
- andq %r12, %r10
- roll %r11d
- roll $5, %r8d
- movq %r11, 16(%rdi)
- addq %rax, %r8
- movq 16(%rdi), %r15
- movq (%rdi), %r13
- movq -40(%rdi), %rdx
- addq %r14, %r8
- movq 40(%rdi), %r14
- movq 24(%rdi), %rcx
- movl %esi, %r11d
- addq %r15, %r8
- movl $2400959708, %r15d
- orq %r12, %rsi
- xorq %rdx, %r13
- addq %r15, %r8
- andq %r9, %rsi
- xorq %r14, %r13
- orq %rsi, %r10
- xorl %ecx, %r13d
- movl %r8d, %ecx
- roll %r13d
- roll $5, %ecx
- movq %r13, 24(%rdi)
- addq %r10, %rcx
- movq 24(%rdi), %rax
- movq 8(%rdi), %r14
- movq -32(%rdi), %rdx
- addq %rbx, %rcx
- movq 48(%rdi), %rbx
- movq 32(%rdi), %rsi
- roll $30, %r11d
- addq %rax, %rcx
- movl %r8d, %r13d
- movq %r8, %r10
- xorq %rdx, %r14
- addq %r15, %rcx
- orq %r11, %r8
- xorq %rbx, %r14
- andq %r12, %r8
- andq %r11, %r10
- xorl %esi, %r14d
- movl %ecx, %esi
- orq %r8, %r10
- roll $5, %esi
- roll %r14d
- roll $30, %r13d
- addq %r10, %rsi
- movq %r14, 32(%rdi)
- movq 32(%rdi), %rax
- addq %r9, %rsi
- movq 16(%rdi), %r9
- movq -24(%rdi), %rdx
- movq 56(%rdi), %rbx
- movq 40(%rdi), %r8
- movl %ecx, %r14d
- addq %rax, %rsi
- movq %rcx, %r10
- orq %r13, %rcx
- xorq %rdx, %r9
- addq %r15, %rsi
- andq %r11, %rcx
- xorq %rbx, %r9
- andq %r13, %r10
- roll $30, %r14d
- xorl %r8d, %r9d
- movl %esi, %r8d
- orq %rcx, %r10
- roll %r9d
- roll $5, %r8d
- movq %r9, 40(%rdi)
- addq %r10, %r8
- movq 40(%rdi), %rax
- movq 24(%rdi), %r10
- movq -16(%rdi), %rdx
- addq %r12, %r8
- movq 64(%rdi), %rbx
- movq 48(%rdi), %rcx
- movl %esi, %r9d
- addq %rax, %r8
- movq %rsi, %r12
- xorq %rdx, %r10
- addq %r15, %r8
- xorq %rbx, %r10
- orq %r14, %rsi
- andq %r14, %r12
- andq %r13, %rsi
- xorl %ecx, %r10d
- movl %r8d, %ecx
- orq %rsi, %r12
- roll %r10d
- roll $5, %ecx
- movq %r10, 48(%rdi)
- addq %r12, %rcx
- movq 48(%rdi), %rax
- movq 32(%rdi), %r12
- movq -8(%rdi), %rdx
- addq %r11, %rcx
- movq 72(%rdi), %rbx
- movq 56(%rdi), %rsi
- roll $30, %r9d
- addq %rax, %rcx
- movl %r8d, %r10d
- movq %r8, %r11
- xorq %rdx, %r12
- addq %r15, %rcx
- orq %r9, %r8
- xorq %rbx, %r12
- andq %r14, %r8
- andq %r9, %r11
- xorl %esi, %r12d
- movl %ecx, %esi
- orq %r8, %r11
- roll %r12d
- roll $5, %esi
- roll $30, %r10d
- movq %r12, 56(%rdi)
- addq %r11, %rsi
- movq 56(%rdi), %rax
- movq 40(%rdi), %r11
- movq (%rdi), %rdx
- addq %r13, %rsi
- movq -48(%rdi), %rbx
- movq 64(%rdi), %r8
- movq %rcx, %r13
- addq %rax, %rsi
- andq %r10, %r13
- movl %ecx, %r12d
- xorq %rdx, %r11
- addq %r15, %rsi
- xorq %rbx, %r11
- xorl %r8d, %r11d
- movl %esi, %r8d
- roll %r11d
- roll $5, %r8d
- orq %r10, %rcx
- andq %r9, %rcx
- movq %r11, 64(%rdi)
- movq 64(%rdi), %rax
- orq %rcx, %r13
- roll $30, %r12d
- movl %esi, %r11d
- addq %r13, %r8
- movq 48(%rdi), %r13
- movq 8(%rdi), %rdx
- movq -40(%rdi), %rbx
- addq %r14, %r8
- movq 72(%rdi), %rcx
- addq %rax, %r8
- movq %rsi, %r14
- orq %r12, %rsi
- xorq %rdx, %r13
- addq %r15, %r8
- andq %r10, %rsi
- xorq %rbx, %r13
- andq %r12, %r14
- roll $30, %r11d
- xorl %ecx, %r13d
- movl %r8d, %ecx
- orq %rsi, %r14
- roll %r13d
- roll $5, %ecx
- movq %r13, 72(%rdi)
- addq %r14, %rcx
- movq 72(%rdi), %rax
- movq 56(%rdi), %r14
- movq 16(%rdi), %rdx
- addq %r9, %rcx
- movq -32(%rdi), %rbx
- movq -48(%rdi), %rsi
- movl %r8d, %r13d
- addq %rax, %rcx
- movq %r8, %r9
- orq %r11, %r8
- xorq %rdx, %r14
- addq %r15, %rcx
- andq %r12, %r8
- xorq %rbx, %r14
- andq %r11, %r9
- xorl %esi, %r14d
- movl %ecx, %esi
- orq %r8, %r9
- roll $5, %esi
- roll %r14d
- addq %r9, %rsi
- movq %r14, -48(%rdi)
- movq -48(%rdi), %rax
- addq %r10, %rsi
- movq 64(%rdi), %r10
- movq 24(%rdi), %rdx
- movq -24(%rdi), %rbx
- movq -40(%rdi), %r8
- movl %ecx, %r14d
- addq %rax, %rsi
- roll $30, %r13d
- movq %rcx, %r9
- xorq %rdx, %r10
- addq %r15, %rsi
- orq %r13, %rcx
- xorq %rbx, %r10
- andq %r11, %rcx
- andq %r13, %r9
- xorl %r8d, %r10d
- movl %esi, %r8d
- orq %rcx, %r9
- roll $5, %r8d
- roll %r10d
- roll $30, %r14d
- addq %r9, %r8
- movq %r10, -40(%rdi)
- movq -40(%rdi), %rax
- addq %r12, %r8
- movq 72(%rdi), %r12
- movq 32(%rdi), %rdx
- movq -16(%rdi), %rbx
- movq -32(%rdi), %rcx
- movl %esi, %r10d
- addq %rax, %r8
- movq %rsi, %r9
- orq %r14, %rsi
- xorq %rdx, %r12
- addq %r15, %r8
- andq %r13, %rsi
- xorq %rbx, %r12
- andq %r14, %r9
- roll $30, %r10d
- xorl %ecx, %r12d
- movl %r8d, %ecx
- orq %rsi, %r9
- roll $5, %ecx
- roll %r12d
- addq %r9, %rcx
- movq %r12, -32(%rdi)
- movq -32(%rdi), %rax
- addq %r11, %rcx
- movq -48(%rdi), %r11
- movq 40(%rdi), %rdx
- movq -8(%rdi), %rbx
- movq -24(%rdi), %rsi
- movl %r8d, %r12d
- addq %rax, %rcx
- movq %r8, %r9
- xorq %rdx, %r11
- addq %r15, %rcx
- xorq %rbx, %r11
- xorl %esi, %r11d
- orq %r10, %r8
- andq %r10, %r9
- andq %r14, %r8
- movl %ecx, %esi
- roll %r11d
- orq %r8, %r9
- roll $5, %esi
- movq %r11, -24(%rdi)
- addq %r9, %rsi
- movq -24(%rdi), %rax
- roll $30, %r12d
- addq %r13, %rsi
- movq -40(%rdi), %r13
- movq 48(%rdi), %rdx
- movq (%rdi), %rbx
- movq -16(%rdi), %r8
- movl %ecx, %r11d
- addq %rax, %rsi
- movq %rcx, %r9
- orq %r12, %rcx
- xorq %rdx, %r13
- addq %r15, %rsi
- andq %r10, %rcx
- xorq %rbx, %r13
- andq %r12, %r9
- roll $30, %r11d
- xorl %r8d, %r13d
- movl %esi, %r8d
- orq %rcx, %r9
- roll %r13d
- roll $5, %r8d
- movq %r13, -16(%rdi)
- addq %r9, %r8
- movq -16(%rdi), %rax
- movq -32(%rdi), %r9
- movq 56(%rdi), %rdx
- addq %r14, %r8
- movq 8(%rdi), %rcx
- movq -8(%rdi), %rbx
- movl %esi, %r13d
- addq %rax, %r8
- movq %rsi, %r14
- orq %r11, %rsi
- xorq %rdx, %r9
- addq %r15, %r8
- andq %r11, %r14
- xorq %rcx, %r9
- xorl %ebx, %r9d
- movl %r8d, %ebx
- roll %r9d
- roll $5, %ebx
- andq %r12, %rsi
- orq %rsi, %r14
- movq %r9, -8(%rdi)
- movq -8(%rdi), %rax
- addq %r14, %rbx
- movq -24(%rdi), %r14
- movq 64(%rdi), %rdx
- movq 16(%rdi), %rcx
- addq %r10, %rbx
- movq (%rdi), %rsi
- roll $30, %r13d
- addq %rax, %rbx
- movl %r8d, %r9d
- xorq %rdx, %r14
- addq %r15, %rbx
- movq %r8, %r10
- xorq %rcx, %r14
- orq %r13, %r8
- andq %r13, %r10
- andq %r11, %r8
- xorl %esi, %r14d
- movl %ebx, %esi
- orq %r8, %r10
- roll $5, %esi
- roll %r14d
- addq %r10, %rsi
- movq %r14, (%rdi)
- movq (%rdi), %rax
- addq %r12, %rsi
- movq -16(%rdi), %r12
- movq 72(%rdi), %rdx
- movq 24(%rdi), %rcx
- movq 8(%rdi), %r8
- roll $30, %r9d
- addq %rax, %rsi
- movl %ebx, %r14d
- movq %rbx, %r10
- xorq %rdx, %r12
- addq %r15, %rsi
- orq %r9, %rbx
- xorq %rcx, %r12
- andq %r13, %rbx
- andq %r9, %r10
- xorl %r8d, %r12d
- movl %esi, %r8d
- orq %rbx, %r10
- roll %r12d
- roll $5, %r8d
- movq %r12, 8(%rdi)
- movq 8(%rdi), %rax
- addq %r10, %r8
- movq -8(%rdi), %rbx
- movq -48(%rdi), %rdx
- addq %r11, %r8
- movq 32(%rdi), %r11
- movq 16(%rdi), %rcx
- movl %esi, %r12d
- addq %rax, %r8
- movq %rsi, %r10
- addq %r15, %r8
- xorq %rdx, %rbx
- roll $30, %r14d
- xorq %r11, %rbx
- orq %r14, %rsi
- andq %r14, %r10
- xorl %ecx, %ebx
- andq %r9, %rsi
- movl %r8d, %ecx
- roll %ebx
- orq %rsi, %r10
- roll $5, %ecx
- movq %rbx, 16(%rdi)
- movq 16(%rdi), %rsi
- addq %r10, %rcx
- movq (%rdi), %r11
- movq -40(%rdi), %rax
- addq %r13, %rcx
- movq 40(%rdi), %rdx
- movq 24(%rdi), %r13
- roll $30, %r12d
- addq %rsi, %rcx
- movl %r8d, %ebx
- movq %r8, %r10
- xorq %rax, %r11
- addq %r15, %rcx
- orq %r12, %r8
- xorq %rdx, %r11
- andq %r14, %r8
- andq %r12, %r10
- xorl %r13d, %r11d
- movl %ecx, %r13d
- orq %r8, %r10
- roll %r11d
- roll $5, %r13d
- roll $30, %ebx
- movq %r11, 24(%rdi)
- addq %r10, %r13
- movq 24(%rdi), %rsi
- movq 8(%rdi), %r10
- movq -32(%rdi), %rax
- addq %r9, %r13
- movq 48(%rdi), %rdx
- movq 32(%rdi), %r8
- movl %ecx, %r11d
- addq %rsi, %r13
- movq %rcx, %r9
- xorq %rax, %r10
- addq %r15, %r13
- xorq %rdx, %r10
- xorl %r8d, %r10d
- movl %r13d, %r8d
- roll %r10d
- orq %rbx, %rcx
- andq %rbx, %r9
- movq %r10, 32(%rdi)
- andq %r12, %rcx
- movl %r13d, %r10d
- orq %rcx, %r9
- roll $5, %r10d
- movq 32(%rdi), %rsi
- addq %r9, %r10
- roll $30, %r11d
- movq %r13, %rcx
- addq %r14, %r10
- movq 16(%rdi), %r14
- movq -24(%rdi), %rax
- movq 56(%rdi), %rdx
- movq 40(%rdi), %r9
- addq %rsi, %r10
- addq %r15, %r10
- orq %r11, %r13
- andq %r11, %rcx
- xorq %rax, %r14
- andq %rbx, %r13
- xorq %rdx, %r14
- orq %r13, %rcx
- xorl %r9d, %r14d
- movl %r10d, %r9d
- roll %r14d
- roll $5, %r9d
- movq %r14, 40(%rdi)
- movq 40(%rdi), %rsi
- addq %rcx, %r9
- movq 24(%rdi), %r13
- addq %r12, %r9
- movq -16(%rdi), %r12
- movq 64(%rdi), %rax
- movl %r10d, %r14d
- addq %rsi, %r9
- movl %r8d, %esi
- addq %r15, %r9
- movq 48(%rdi), %r15
- xorq %r12, %r13
- roll $30, %esi
- xorq %rax, %r13
- xorq %rsi, %r10
- xorl %r15d, %r13d
- movl %r9d, %r15d
- xorq %r11, %r10
- roll $5, %r15d
- roll %r13d
- addq %r10, %r15
- movq %r13, 48(%rdi)
- movq 48(%rdi), %r10
- addq %rbx, %r15
- movq 32(%rdi), %rbx
- movq -8(%rdi), %r8
- movq 72(%rdi), %rdx
- movq 56(%rdi), %rcx
- roll $30, %r14d
- addq %r10, %r15
- movl $3395469782, %r10d
- movl %r9d, %r13d
- xorq %r8, %rbx
- addq %r10, %r15
- xorq %r14, %r9
- xorq %rdx, %rbx
- xorq %rsi, %r9
- roll $30, %r13d
- xorl %ecx, %ebx
- movl %r15d, %ecx
- roll %ebx
- roll $5, %ecx
- movq %rbx, 56(%rdi)
- addq %r9, %rcx
- movq 56(%rdi), %r12
- movq 40(%rdi), %r9
- movq (%rdi), %rax
- addq %r11, %rcx
- movq -48(%rdi), %r8
- movq 64(%rdi), %r11
- movl %r15d, %ebx
- addq %r12, %rcx
- xorq %r13, %r15
- roll $30, %ebx
- xorq %rax, %r9
- addq %r10, %rcx
- xorq %r14, %r15
- xorq %r8, %r9
- xorl %r11d, %r9d
- movl %ecx, %r11d
- roll %r9d
- roll $5, %r11d
- movq %r9, 64(%rdi)
- addq %r15, %r11
- movq 64(%rdi), %rdx
- movq 48(%rdi), %r15
- movq 8(%rdi), %r12
- addq %rsi, %r11
- movq -40(%rdi), %rax
- movq 72(%rdi), %r8
- movl %ecx, %r9d
- addq %rdx, %r11
- xorq %r12, %r15
- addq %r10, %r11
- xorq %rax, %r15
- xorl %r8d, %r15d
- movl %r11d, %r8d
- roll %r15d
- roll $5, %r8d
- xorq %rbx, %rcx
- xorq %r13, %rcx
- movq %r15, 72(%rdi)
- movq 72(%rdi), %rsi
- addq %rcx, %r8
- movq 56(%rdi), %r12
- movq 16(%rdi), %rcx
- movq -32(%rdi), %rdx
- addq %r14, %r8
- movq -48(%rdi), %r14
- addq %rsi, %r8
- roll $30, %r9d
- movl %r11d, %r15d
- xorq %rcx, %r12
- addq %r10, %r8
- xorq %r9, %r11
- xorq %rdx, %r12
- xorq %rbx, %r11
- roll $30, %r15d
- xorl %r14d, %r12d
- movl %r8d, %r14d
- roll $5, %r14d
- roll %r12d
- addq %r11, %r14
- movq %r12, -48(%rdi)
- movq -48(%rdi), %rax
- addq %r13, %r14
- movq 64(%rdi), %r13
- movq 24(%rdi), %rsi
- movq -24(%rdi), %rcx
- movq -40(%rdi), %r11
- movl %r8d, %r12d
- addq %rax, %r14
- xorq %r15, %r8
- roll $30, %r12d
- xorq %rsi, %r13
- addq %r10, %r14
- xorq %r9, %r8
- xorq %rcx, %r13
- xorl %r11d, %r13d
- movl %r14d, %r11d
- roll $5, %r11d
- roll %r13d
- addq %r8, %r11
- movq %r13, -40(%rdi)
- movq -40(%rdi), %rdx
- addq %rbx, %r11
- movq 72(%rdi), %rbx
- movq 32(%rdi), %rax
- movq -16(%rdi), %rsi
- movq -32(%rdi), %r8
- movl %r14d, %r13d
- addq %rdx, %r11
- xorq %rax, %rbx
- addq %r10, %r11
- xorq %rsi, %rbx
- xorl %r8d, %ebx
- xorq %r12, %r14
- movl %r11d, %r8d
- xorq %r15, %r14
- roll %ebx
- roll $5, %r8d
- movq %rbx, -32(%rdi)
- addq %r14, %r8
- movq -32(%rdi), %rcx
- movq -48(%rdi), %r14
- movq 40(%rdi), %rdx
- addq %r9, %r8
- movq -8(%rdi), %rax
- movq -24(%rdi), %r9
- roll $30, %r13d
- addq %rcx, %r8
- movl %r11d, %ebx
- xorq %r13, %r11
- xorq %rdx, %r14
- addq %r10, %r8
- xorq %r12, %r11
- xorq %rax, %r14
- roll $30, %ebx
- xorl %r9d, %r14d
- movl %r8d, %r9d
- roll $5, %r9d
- roll %r14d
- addq %r11, %r9
- movq %r14, -24(%rdi)
- movq -24(%rdi), %rsi
- addq %r15, %r9
- movq -40(%rdi), %r15
- movq 48(%rdi), %rcx
- movq (%rdi), %rdx
- movq -16(%rdi), %r11
- movl %r8d, %r14d
- addq %rsi, %r9
- xorq %rbx, %r8
- xorq %rcx, %r15
- addq %r10, %r9
- xorq %r13, %r8
- xorq %rdx, %r15
- xorl %r11d, %r15d
- movl %r9d, %r11d
- roll %r15d
- roll $5, %r11d
- movq %r15, -16(%rdi)
- addq %r8, %r11
- movq -16(%rdi), %rax
- addq %r12, %r11
- movq -32(%rdi), %r12
- movq 56(%rdi), %rsi
- movq 8(%rdi), %rcx
- movq -8(%rdi), %r8
- movl %r9d, %r15d
- addq %rax, %r11
- addq %r10, %r11
- roll $30, %r14d
- xorq %rsi, %r12
- xorq %rcx, %r12
- xorq %r14, %r9
- roll $30, %r15d
- xorl %r8d, %r12d
- movl %r11d, %r8d
- xorq %rbx, %r9
- roll $5, %r8d
- roll %r12d
- addq %r9, %r8
- movq %r12, -8(%rdi)
- movq -8(%rdi), %rdx
- addq %r13, %r8
- movq -24(%rdi), %r13
- movq 64(%rdi), %rax
- movq 16(%rdi), %rsi
- movq (%rdi), %rcx
- movl %r11d, %r12d
- addq %rdx, %r8
- xorq %r15, %r11
- roll $30, %r12d
- xorq %rax, %r13
- addq %r10, %r8
- xorq %r14, %r11
- xorq %rsi, %r13
- xorl %ecx, %r13d
- movl %r8d, %ecx
- roll $5, %ecx
- roll %r13d
- addq %r11, %rcx
- movq %r13, (%rdi)
- movq (%rdi), %r9
- addq %rbx, %rcx
- movq -16(%rdi), %rbx
- movq 72(%rdi), %rdx
- movq 24(%rdi), %rax
- movq 8(%rdi), %rsi
- movl %r8d, %r13d
- addq %r9, %rcx
- xorq %r12, %r8
- xorq %rdx, %rbx
- addq %r10, %rcx
- xorq %r15, %r8
- xorq %rax, %rbx
- xorl %esi, %ebx
- movl %ecx, %esi
- roll $5, %esi
- roll %ebx
- addq %r8, %rsi
- movq %rbx, 8(%rdi)
- movq 8(%rdi), %r11
- addq %r14, %rsi
- movq -8(%rdi), %r14
- movq -48(%rdi), %r9
- movq 32(%rdi), %rdx
- movq 16(%rdi), %r8
- roll $30, %r13d
- addq %r11, %rsi
- movl %ecx, %ebx
- xorq %r13, %rcx
- xorq %r9, %r14
- addq %r10, %rsi
- xorq %r12, %rcx
- xorq %rdx, %r14
- roll $30, %ebx
- xorl %r8d, %r14d
- movl %esi, %r8d
- roll $5, %r8d
- roll %r14d
- addq %rcx, %r8
- movq %r14, 16(%rdi)
- movq 16(%rdi), %rax
- addq %r15, %r8
- movq (%rdi), %r15
- movq -40(%rdi), %r11
- movq 40(%rdi), %r9
- movq 24(%rdi), %rcx
- movl %esi, %r14d
- addq %rax, %r8
- xorq %rbx, %rsi
- roll $30, %r14d
- xorq %r11, %r15
- addq %r10, %r8
- xorq %r13, %rsi
- xorq %r9, %r15
- xorl %ecx, %r15d
- movl %r8d, %ecx
- roll %r15d
- roll $5, %ecx
- movq %r15, 24(%rdi)
- addq %rsi, %rcx
- movq 24(%rdi), %rdx
- movq 8(%rdi), %r11
- movq -32(%rdi), %rax
- addq %r12, %rcx
- movq 48(%rdi), %r12
- movq 32(%rdi), %rsi
- movl %r8d, %r15d
- addq %rdx, %rcx
- xorq %rax, %r11
- addq %r10, %rcx
- xorq %r12, %r11
- xorl %esi, %r11d
- movl %ecx, %esi
- roll %r11d
- movq %r11, 32(%rdi)
- movl %ecx, %r11d
- movq 32(%rdi), %r9
- roll $5, %r11d
- xorq %r14, %r8
- movq 16(%rdi), %r12
- xorq %rbx, %r8
- movq -24(%rdi), %rdx
- movq 56(%rdi), %rax
- addq %r8, %r11
- movq 40(%rdi), %r8
- roll $30, %r15d
- addq %r13, %r11
- xorq %r15, %rcx
- addq %r9, %r11
- xorq %rdx, %r12
- xorq %r14, %rcx
- addq %r10, %r11
- xorq %rax, %r12
- xorl %r8d, %r12d
- movl %r11d, %r8d
- roll $5, %r8d
- roll %r12d
- addq %rcx, %r8
- movq %r12, 40(%rdi)
- movq 40(%rdi), %r13
- addq %rbx, %r8
- movq 24(%rdi), %rbx
- movq -16(%rdi), %r9
- movq 64(%rdi), %rdx
- movq 48(%rdi), %rcx
- movl %r11d, %r12d
- addq %r13, %r8
- movl %esi, %r13d
- roll $30, %r12d
- xorq %r9, %rbx
- addq %r10, %r8
- roll $30, %r13d
- xorq %rdx, %rbx
- xorq %r13, %r11
- xorl %ecx, %ebx
- movl %r8d, %ecx
- xorq %r15, %r11
- roll %ebx
- roll $5, %ecx
- movq %rbx, 48(%rdi)
- addq %r11, %rcx
- movq 48(%rdi), %rax
- movq 32(%rdi), %r11
- movq -8(%rdi), %rsi
- addq %r14, %rcx
- movq 72(%rdi), %r9
- movq 56(%rdi), %r14
- movl %r8d, %ebx
- addq %rax, %rcx
- xorq %rsi, %r11
- addq %r10, %rcx
- xorq %r9, %r11
- xorl %r14d, %r11d
- xorq %r12, %r8
- movl %ecx, %r14d
- xorq %r13, %r8
- roll %r11d
- roll $5, %r14d
- movq %r11, 56(%rdi)
- addq %r8, %r14
- movq 56(%rdi), %rdx
- movq 40(%rdi), %r8
- movq (%rdi), %rax
- addq %r15, %r14
- movq -48(%rdi), %r15
- movq 64(%rdi), %rsi
- roll $30, %ebx
- addq %rdx, %r14
- movl %ecx, %r11d
- xorq %rbx, %rcx
- xorq %rax, %r8
- addq %r10, %r14
- xorq %r12, %rcx
- xorq %r15, %r8
- roll $30, %r11d
- xorl %esi, %r8d
- movl %r14d, %esi
- roll %r8d
- roll $5, %esi
- movq %r8, 64(%rdi)
- movq 64(%rdi), %r9
- addq %rcx, %rsi
- movq 48(%rdi), %r15
- movq 8(%rdi), %rcx
- addq %r13, %rsi
- movq -40(%rdi), %rdx
- movq 72(%rdi), %rax
- movl %r14d, %r8d
- addq %r9, %rsi
- xorq %r11, %r14
- addq %r10, %rsi
- xorq %rcx, %r15
- xorq %rbx, %r14
- xorq %rdx, %r15
- movl %esi, %r13d
- xorl %eax, %r15d
- roll $5, %r13d
- roll %r15d
- addq %r14, %r13
- movq %r15, 72(%rdi)
- addq %r12, %r13
- movq 72(%rdi), %r12
- addq %r12, %r13
- addq %r10, %r13
- movq -88(%rdi), %r10
- roll $30, %r8d
- addq %r13, %r10
- movq %r10, -88(%rdi)
- movq -80(%rdi), %r9
- addq %rsi, %r9
- movq %r9, -80(%rdi)
- movq -72(%rdi), %rcx
- addq %r8, %rcx
- movq %rcx, -72(%rdi)
- movq -64(%rdi), %rdx
- addq %r11, %rdx
- movq %rdx, -64(%rdi)
- movq -56(%rdi), %rax
- addq %rbx, %rax
- popq %rbx
- popq %r12
- popq %r13
- popq %r14
- popq %r15
- movq %rax, -56(%rdi)
- ret
-.LFE7:
- .size shaCompress, .-shaCompress
- .align 16
-.globl SHA1_Update
- .type SHA1_Update, @function
-SHA1_Update:
-.LFB5:
- pushq %rbp
-.LCFI5:
- movq %rsp, %rbp
-.LCFI6:
- movq %r13, -24(%rbp)
-.LCFI7:
- movq %r14, -16(%rbp)
-.LCFI8:
- movl %edx, %r13d
- movq %r15, -8(%rbp)
-.LCFI9:
- movq %rbx, -40(%rbp)
-.LCFI10:
- movq %rdi, %r15
- movq %r12, -32(%rbp)
-.LCFI11:
- subq $48, %rsp
-.LCFI12:
- testl %edx, %edx
- movq %rsi, %r14
- je .L243
- movq 64(%rdi), %rdx
- mov %r13d, %ecx
- leaq (%rdx,%rcx), %rax
- movq %rax, 64(%rdi)
- movl %edx, %eax
- andl $63, %eax
- movl %eax, -44(%rbp)
- jne .L256
-.L245:
- cmpl $63, %r13d
- jbe .L253
- leaq 160(%r15), %rbx
- .align 16
-.L250:
- movq %r14, %rsi
- subl $64, %r13d
- movq %rbx, %rdi
- call shaCompress
- addq $64, %r14
- cmpl $63, %r13d
- ja .L250
-.L253:
- testl %r13d, %r13d
- je .L243
- mov %r13d, %edx
- movq %r14, %rsi
- movq %r15, %rdi
- movq -40(%rbp), %rbx
- movq -32(%rbp), %r12
- movq -24(%rbp), %r13
- movq -16(%rbp), %r14
- movq -8(%rbp), %r15
- leave
- jmp memcpy@PLT
- .align 16
-.L243:
- movq -40(%rbp), %rbx
- movq -32(%rbp), %r12
- movq -24(%rbp), %r13
- movq -16(%rbp), %r14
- movq -8(%rbp), %r15
- leave
- ret
-.L256:
- movl $64, %ebx
- mov %eax, %edi
- subl %eax, %ebx
- cmpl %ebx, %r13d
- cmovb %r13d, %ebx
- addq %r15, %rdi
- mov %ebx, %r12d
- subl %ebx, %r13d
- movq %r12, %rdx
- addq %r12, %r14
- call memcpy@PLT
- addl -44(%rbp), %ebx
- andl $63, %ebx
- jne .L245
- leaq 160(%r15), %rdi
- movq %r15, %rsi
- call shaCompress
- jmp .L245
-.LFE5:
- .size SHA1_Update, .-SHA1_Update
- .section .rodata
- .align 32
- .type bulk_pad.0, @object
- .size bulk_pad.0, 64
-bulk_pad.0:
- .byte -128
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .byte 0
- .text
- .align 16
-.globl SHA1_End
- .type SHA1_End, @function
-SHA1_End:
-.LFB6:
- pushq %rbp
-.LCFI13:
- movq %rsp, %rbp
-.LCFI14:
- movq %r12, -24(%rbp)
-.LCFI15:
- movq %r13, -16(%rbp)
-.LCFI16:
- movq %rsi, %r13
- movq %r14, -8(%rbp)
-.LCFI17:
- movq %rbx, -32(%rbp)
-.LCFI18:
- subq $32, %rsp
-.LCFI19:
- movq 64(%rdi), %rbx
- movq %rdx, %r14
- movl $119, %edx
- leaq bulk_pad.0(%rip), %rsi
- movq %rdi, %r12
- movl %ebx, %r8d
- salq $3, %rbx
- andl $63, %r8d
- subl %r8d, %edx
- andl $63, %edx
- incl %edx
- call SHA1_Update@PLT
- movq %rbx, %rdi
- movq %r12, %rsi
- shrq $32, %rdi
-/APP
- bswap %edi
-/NO_APP
- movl %edi, 56(%r12)
- leaq 160(%r12), %rdi
-/APP
- bswap %ebx
-/NO_APP
- movl %ebx, 60(%r12)
- call shaCompress
- movl 72(%r12), %esi
- movl 80(%r12), %ebx
- movl 88(%r12), %ecx
- movl 96(%r12), %edx
- movl 104(%r12), %eax
- movq 8(%rsp), %r12
-/APP
- bswap %ebx
- bswap %esi
-/NO_APP
- movl %ebx, 4(%r13)
- movl %esi, (%r13)
-/APP
- bswap %ecx
- bswap %edx
-/NO_APP
- movl %ecx, 8(%r13)
- movl %edx, 12(%r13)
-/APP
- bswap %eax
-/NO_APP
- movq (%rsp), %rbx
- movl %eax, 16(%r13)
- movl $20, (%r14)
- movq 16(%rsp), %r13
- movq 24(%rsp), %r14
- leave
- ret
-.LFE6:
- .size SHA1_End, .-SHA1_End
- .align 16
-.globl SHA1_NewContext
- .type SHA1_NewContext, @function
-SHA1_NewContext:
-.LFB8:
- movl $248, %edi
- jmp PORT_Alloc_Util@PLT
-.LFE8:
- .size SHA1_NewContext, .-SHA1_NewContext
- .align 16
-.globl SHA1_DestroyContext
- .type SHA1_DestroyContext, @function
-SHA1_DestroyContext:
-.LFB9:
- pushq %rbp
-.LCFI20:
- movl $248, %edx
- movq %rsp, %rbp
-.LCFI21:
- movq %rbx, -16(%rbp)
-.LCFI22:
- movq %r12, -8(%rbp)
-.LCFI23:
- movl %esi, %ebx
- subq $16, %rsp
-.LCFI24:
- xorl %esi, %esi
- movq %rdi, %r12
- call memset@PLT
- testl %ebx, %ebx
- jne .L268
- movq (%rsp), %rbx
- movq 8(%rsp), %r12
- leave
- ret
- .align 16
-.L268:
- movq %r12, %rdi
- movq (%rsp), %rbx
- movq 8(%rsp), %r12
- leave
- jmp PORT_Free_Util@PLT
-.LFE9:
- .size SHA1_DestroyContext, .-SHA1_DestroyContext
- .align 16
-.globl SHA1_HashBuf
- .type SHA1_HashBuf, @function
-SHA1_HashBuf:
-.LFB10:
- pushq %rbp
-.LCFI25:
- movq %rsp, %rbp
-.LCFI26:
- movq %rbx, -32(%rbp)
-.LCFI27:
- leaq -288(%rbp), %rbx
- movq %r12, -24(%rbp)
-.LCFI28:
- movq %r13, -16(%rbp)
-.LCFI29:
- movq %r14, -8(%rbp)
-.LCFI30:
- movq %rsi, %r13
- subq $304, %rsp
-.LCFI31:
- movq %rdi, %r14
- movl %edx, %r12d
- movq %rbx, %rdi
- call SHA1_Begin@PLT
- movl %r12d, %edx
- movq %r13, %rsi
- movq %rbx, %rdi
- call SHA1_Update@PLT
- leaq -292(%rbp), %rdx
- movq %r14, %rsi
- movq %rbx, %rdi
- movl $20, %ecx
- call SHA1_End@PLT
- movq -32(%rbp), %rbx
- movq -24(%rbp), %r12
- xorl %eax, %eax
- movq -16(%rbp), %r13
- movq -8(%rbp), %r14
- leave
- ret
-.LFE10:
- .size SHA1_HashBuf, .-SHA1_HashBuf
- .align 16
-.globl SHA1_Hash
- .type SHA1_Hash, @function
-SHA1_Hash:
-.LFB11:
- pushq %rbp
-.LCFI32:
- movq %rsp, %rbp
-.LCFI33:
- movq %rbx, -16(%rbp)
-.LCFI34:
- movq %r12, -8(%rbp)
-.LCFI35:
- movq %rsi, %rbx
- subq $16, %rsp
-.LCFI36:
- movq %rdi, %r12
- movq %rsi, %rdi
- call strlen@PLT
- movq %rbx, %rsi
- movq %r12, %rdi
- movq (%rsp), %rbx
- movq 8(%rsp), %r12
- leave
- movl %eax, %edx
- jmp SHA1_HashBuf@PLT
-.LFE11:
- .size SHA1_Hash, .-SHA1_Hash
- .align 16
-.globl SHA1_FlattenSize
- .type SHA1_FlattenSize, @function
-SHA1_FlattenSize:
-.LFB12:
- movl $248, %eax
- ret
-.LFE12:
- .size SHA1_FlattenSize, .-SHA1_FlattenSize
- .align 16
-.globl SHA1_Flatten
- .type SHA1_Flatten, @function
-SHA1_Flatten:
-.LFB13:
- pushq %rbp
-.LCFI37:
- movq %rsi, %rax
- movl $248, %edx
- movq %rdi, %rsi
- movq %rax, %rdi
- movq %rsp, %rbp
-.LCFI38:
- call memcpy@PLT
- leave
- xorl %eax, %eax
- ret
-.LFE13:
- .size SHA1_Flatten, .-SHA1_Flatten
- .align 16
-.globl SHA1_Resurrect
- .type SHA1_Resurrect, @function
-SHA1_Resurrect:
-.LFB14:
- pushq %rbp
-.LCFI39:
- movq %rsp, %rbp
-.LCFI40:
- movq %rbx, -16(%rbp)
-.LCFI41:
- movq %r12, -8(%rbp)
-.LCFI42:
- subq $16, %rsp
-.LCFI43:
- movq %rdi, %r12
- call SHA1_NewContext@PLT
- movq %rax, %rbx
- xorl %eax, %eax
- testq %rbx, %rbx
- je .L273
- movl $248, %edx
- movq %r12, %rsi
- movq %rbx, %rdi
- call memcpy@PLT
- movq %rbx, %rax
-.L273:
- movq (%rsp), %rbx
- movq 8(%rsp), %r12
- leave
- ret
-.LFE14:
- .size SHA1_Resurrect, .-SHA1_Resurrect
- .align 16
-.globl SHA1_Clone
- .type SHA1_Clone, @function
-SHA1_Clone:
-.LFB15:
- movl $248, %edx
- jmp memcpy@PLT
-.LFE15:
- .size SHA1_Clone, .-SHA1_Clone
- .align 16
-.globl SHA1_TraceState
- .type SHA1_TraceState, @function
-SHA1_TraceState:
-.LFB16:
- movl $-5992, %edi
- jmp PORT_SetError_Util@PLT
-.LFE16:
- .size SHA1_TraceState, .-SHA1_TraceState
diff --git a/security/nss/lib/freebl/sha256.h b/security/nss/lib/freebl/sha256.h
deleted file mode 100644
index 86bec7ccb..000000000
--- a/security/nss/lib/freebl/sha256.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SHA_256_H_
-#define _SHA_256_H_
-
-#include "prtypes.h"
-
-struct SHA256ContextStr {
- union {
- PRUint32 w[64]; /* message schedule, input buffer, plus 48 words */
- PRUint8 b[256];
- } u;
- PRUint32 h[8]; /* 8 state variables */
- PRUint32 sizeHi,sizeLo; /* 64-bit count of hashed bytes. */
-};
-
-#endif /* _SHA_256_H_ */
diff --git a/security/nss/lib/freebl/sha512.c b/security/nss/lib/freebl/sha512.c
deleted file mode 100644
index 58dc5a447..000000000
--- a/security/nss/lib/freebl/sha512.c
+++ /dev/null
@@ -1,1599 +0,0 @@
-/*
- * sha512.c - implementation of SHA224, SHA256, SHA384 and SHA512
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "prcpucfg.h"
-#if defined(NSS_X86) || defined(SHA_NO_LONG_LONG)
-#define NOUNROLL512 1
-#undef HAVE_LONG_LONG
-#endif
-#include "prtypes.h" /* for PRUintXX */
-#include "prlong.h"
-#include "secport.h" /* for PORT_XXX */
-#include "blapi.h"
-#include "sha256.h" /* for struct SHA256ContextStr */
-
-/* ============= Common constants and defines ======================= */
-
-#define W ctx->u.w
-#define B ctx->u.b
-#define H ctx->h
-
-#define SHR(x,n) (x >> n)
-#define SHL(x,n) (x << n)
-#define Ch(x,y,z) ((x & y) ^ (~x & z))
-#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
-#define SHA_MIN(a,b) (a < b ? a : b)
-
-/* Padding used with all flavors of SHA */
-static const PRUint8 pad[240] = {
-0x80,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,
- 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,0
- /* compiler will fill the rest in with zeros */
-};
-
-/* ============= SHA256 implementation ================================== */
-
-/* SHA-256 constants, K256. */
-static const PRUint32 K256[64] = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
- 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
- 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
- 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
- 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
- 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-
-/* SHA-256 initial hash values */
-static const PRUint32 H256[8] = {
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
- 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
-};
-
-#if (_MSC_VER >= 1300)
-#include <stdlib.h>
-#pragma intrinsic(_byteswap_ulong)
-#define SHA_HTONL(x) _byteswap_ulong(x)
-#define BYTESWAP4(x) x = SHA_HTONL(x)
-#elif defined(_MSC_VER) && defined(NSS_X86_OR_X64)
-#ifndef FORCEINLINE
-#if (_MSC_VER >= 1200)
-#define FORCEINLINE __forceinline
-#else
-#define FORCEINLINE __inline
-#endif
-#endif
-#define FASTCALL __fastcall
-
-static FORCEINLINE PRUint32 FASTCALL
-swap4b(PRUint32 dwd)
-{
- __asm {
- mov eax,dwd
- bswap eax
- }
-}
-
-#define SHA_HTONL(x) swap4b(x)
-#define BYTESWAP4(x) x = SHA_HTONL(x)
-
-#elif defined(__GNUC__) && defined(NSS_X86_OR_X64)
-static __inline__ PRUint32 swap4b(PRUint32 value)
-{
- __asm__("bswap %0" : "+r" (value));
- return (value);
-}
-#define SHA_HTONL(x) swap4b(x)
-#define BYTESWAP4(x) x = SHA_HTONL(x)
-
-#elif defined(__GNUC__) && (defined(__thumb2__) || \
- (!defined(__thumb__) && \
- (defined(__ARM_ARCH_6__) || \
- defined(__ARM_ARCH_6J__) || \
- defined(__ARM_ARCH_6K__) || \
- defined(__ARM_ARCH_6Z__) || \
- defined(__ARM_ARCH_6ZK__) || \
- defined(__ARM_ARCH_6T2__) || \
- defined(__ARM_ARCH_7__) || \
- defined(__ARM_ARCH_7A__) || \
- defined(__ARM_ARCH_7R__))))
-static __inline__ PRUint32 swap4b(PRUint32 value)
-{
- PRUint32 ret;
- __asm__("rev %0, %1" : "=r" (ret) : "r"(value));
- return ret;
-}
-#define SHA_HTONL(x) swap4b(x)
-#define BYTESWAP4(x) x = SHA_HTONL(x)
-
-#else
-#define SWAP4MASK 0x00FF00FF
-#define SHA_HTONL(x) (t1 = (x), t1 = (t1 << 16) | (t1 >> 16), \
- ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK))
-#define BYTESWAP4(x) x = SHA_HTONL(x)
-#endif
-
-#if defined(_MSC_VER)
-#pragma intrinsic (_lrotr, _lrotl)
-#define ROTR32(x,n) _lrotr(x,n)
-#define ROTL32(x,n) _lrotl(x,n)
-#else
-#define ROTR32(x,n) ((x >> n) | (x << ((8 * sizeof x) - n)))
-#define ROTL32(x,n) ((x << n) | (x >> ((8 * sizeof x) - n)))
-#endif
-
-/* Capitol Sigma and lower case sigma functions */
-#define S0(x) (ROTR32(x, 2) ^ ROTR32(x,13) ^ ROTR32(x,22))
-#define S1(x) (ROTR32(x, 6) ^ ROTR32(x,11) ^ ROTR32(x,25))
-#define s0(x) (t1 = x, ROTR32(t1, 7) ^ ROTR32(t1,18) ^ SHR(t1, 3))
-#define s1(x) (t2 = x, ROTR32(t2,17) ^ ROTR32(t2,19) ^ SHR(t2,10))
-
-SHA256Context *
-SHA256_NewContext(void)
-{
- SHA256Context *ctx = PORT_New(SHA256Context);
- return ctx;
-}
-
-void
-SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
-{
- memset(ctx, 0, sizeof *ctx);
- if (freeit) {
- PORT_Free(ctx);
- }
-}
-
-void
-SHA256_Begin(SHA256Context *ctx)
-{
- memset(ctx, 0, sizeof *ctx);
- memcpy(H, H256, sizeof H256);
-}
-
-static void
-SHA256_Compress(SHA256Context *ctx)
-{
- {
- register PRUint32 t1, t2;
-
-#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP4(W[0]);
- BYTESWAP4(W[1]);
- BYTESWAP4(W[2]);
- BYTESWAP4(W[3]);
- BYTESWAP4(W[4]);
- BYTESWAP4(W[5]);
- BYTESWAP4(W[6]);
- BYTESWAP4(W[7]);
- BYTESWAP4(W[8]);
- BYTESWAP4(W[9]);
- BYTESWAP4(W[10]);
- BYTESWAP4(W[11]);
- BYTESWAP4(W[12]);
- BYTESWAP4(W[13]);
- BYTESWAP4(W[14]);
- BYTESWAP4(W[15]);
-#endif
-
-#define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
-
- /* prepare the "message schedule" */
-#ifdef NOUNROLL256
- {
- int t;
- for (t = 16; t < 64; ++t) {
- INITW(t);
- }
- }
-#else
- INITW(16);
- INITW(17);
- INITW(18);
- INITW(19);
-
- INITW(20);
- INITW(21);
- INITW(22);
- INITW(23);
- INITW(24);
- INITW(25);
- INITW(26);
- INITW(27);
- INITW(28);
- INITW(29);
-
- INITW(30);
- INITW(31);
- INITW(32);
- INITW(33);
- INITW(34);
- INITW(35);
- INITW(36);
- INITW(37);
- INITW(38);
- INITW(39);
-
- INITW(40);
- INITW(41);
- INITW(42);
- INITW(43);
- INITW(44);
- INITW(45);
- INITW(46);
- INITW(47);
- INITW(48);
- INITW(49);
-
- INITW(50);
- INITW(51);
- INITW(52);
- INITW(53);
- INITW(54);
- INITW(55);
- INITW(56);
- INITW(57);
- INITW(58);
- INITW(59);
-
- INITW(60);
- INITW(61);
- INITW(62);
- INITW(63);
-
-#endif
-#undef INITW
- }
- {
- PRUint32 a, b, c, d, e, f, g, h;
-
- a = H[0];
- b = H[1];
- c = H[2];
- d = H[3];
- e = H[4];
- f = H[5];
- g = H[6];
- h = H[7];
-
-#define ROUND(n,a,b,c,d,e,f,g,h) \
- h += S1(e) + Ch(e,f,g) + K256[n] + W[n]; \
- d += h; \
- h += S0(a) + Maj(a,b,c);
-
-#ifdef NOUNROLL256
- {
- int t;
- for (t = 0; t < 64; t+= 8) {
- ROUND(t+0,a,b,c,d,e,f,g,h)
- ROUND(t+1,h,a,b,c,d,e,f,g)
- ROUND(t+2,g,h,a,b,c,d,e,f)
- ROUND(t+3,f,g,h,a,b,c,d,e)
- ROUND(t+4,e,f,g,h,a,b,c,d)
- ROUND(t+5,d,e,f,g,h,a,b,c)
- ROUND(t+6,c,d,e,f,g,h,a,b)
- ROUND(t+7,b,c,d,e,f,g,h,a)
- }
- }
-#else
- ROUND( 0,a,b,c,d,e,f,g,h)
- ROUND( 1,h,a,b,c,d,e,f,g)
- ROUND( 2,g,h,a,b,c,d,e,f)
- ROUND( 3,f,g,h,a,b,c,d,e)
- ROUND( 4,e,f,g,h,a,b,c,d)
- ROUND( 5,d,e,f,g,h,a,b,c)
- ROUND( 6,c,d,e,f,g,h,a,b)
- ROUND( 7,b,c,d,e,f,g,h,a)
-
- ROUND( 8,a,b,c,d,e,f,g,h)
- ROUND( 9,h,a,b,c,d,e,f,g)
- ROUND(10,g,h,a,b,c,d,e,f)
- ROUND(11,f,g,h,a,b,c,d,e)
- ROUND(12,e,f,g,h,a,b,c,d)
- ROUND(13,d,e,f,g,h,a,b,c)
- ROUND(14,c,d,e,f,g,h,a,b)
- ROUND(15,b,c,d,e,f,g,h,a)
-
- ROUND(16,a,b,c,d,e,f,g,h)
- ROUND(17,h,a,b,c,d,e,f,g)
- ROUND(18,g,h,a,b,c,d,e,f)
- ROUND(19,f,g,h,a,b,c,d,e)
- ROUND(20,e,f,g,h,a,b,c,d)
- ROUND(21,d,e,f,g,h,a,b,c)
- ROUND(22,c,d,e,f,g,h,a,b)
- ROUND(23,b,c,d,e,f,g,h,a)
-
- ROUND(24,a,b,c,d,e,f,g,h)
- ROUND(25,h,a,b,c,d,e,f,g)
- ROUND(26,g,h,a,b,c,d,e,f)
- ROUND(27,f,g,h,a,b,c,d,e)
- ROUND(28,e,f,g,h,a,b,c,d)
- ROUND(29,d,e,f,g,h,a,b,c)
- ROUND(30,c,d,e,f,g,h,a,b)
- ROUND(31,b,c,d,e,f,g,h,a)
-
- ROUND(32,a,b,c,d,e,f,g,h)
- ROUND(33,h,a,b,c,d,e,f,g)
- ROUND(34,g,h,a,b,c,d,e,f)
- ROUND(35,f,g,h,a,b,c,d,e)
- ROUND(36,e,f,g,h,a,b,c,d)
- ROUND(37,d,e,f,g,h,a,b,c)
- ROUND(38,c,d,e,f,g,h,a,b)
- ROUND(39,b,c,d,e,f,g,h,a)
-
- ROUND(40,a,b,c,d,e,f,g,h)
- ROUND(41,h,a,b,c,d,e,f,g)
- ROUND(42,g,h,a,b,c,d,e,f)
- ROUND(43,f,g,h,a,b,c,d,e)
- ROUND(44,e,f,g,h,a,b,c,d)
- ROUND(45,d,e,f,g,h,a,b,c)
- ROUND(46,c,d,e,f,g,h,a,b)
- ROUND(47,b,c,d,e,f,g,h,a)
-
- ROUND(48,a,b,c,d,e,f,g,h)
- ROUND(49,h,a,b,c,d,e,f,g)
- ROUND(50,g,h,a,b,c,d,e,f)
- ROUND(51,f,g,h,a,b,c,d,e)
- ROUND(52,e,f,g,h,a,b,c,d)
- ROUND(53,d,e,f,g,h,a,b,c)
- ROUND(54,c,d,e,f,g,h,a,b)
- ROUND(55,b,c,d,e,f,g,h,a)
-
- ROUND(56,a,b,c,d,e,f,g,h)
- ROUND(57,h,a,b,c,d,e,f,g)
- ROUND(58,g,h,a,b,c,d,e,f)
- ROUND(59,f,g,h,a,b,c,d,e)
- ROUND(60,e,f,g,h,a,b,c,d)
- ROUND(61,d,e,f,g,h,a,b,c)
- ROUND(62,c,d,e,f,g,h,a,b)
- ROUND(63,b,c,d,e,f,g,h,a)
-#endif
-
- H[0] += a;
- H[1] += b;
- H[2] += c;
- H[3] += d;
- H[4] += e;
- H[5] += f;
- H[6] += g;
- H[7] += h;
- }
-#undef ROUND
-}
-
-#undef s0
-#undef s1
-#undef S0
-#undef S1
-
-void
-SHA256_Update(SHA256Context *ctx, const unsigned char *input,
- unsigned int inputLen)
-{
- unsigned int inBuf = ctx->sizeLo & 0x3f;
- if (!inputLen)
- return;
-
- /* Add inputLen into the count of bytes processed, before processing */
- if ((ctx->sizeLo += inputLen) < inputLen)
- ctx->sizeHi++;
-
- /* if data already in buffer, attemp to fill rest of buffer */
- if (inBuf) {
- unsigned int todo = SHA256_BLOCK_LENGTH - inBuf;
- if (inputLen < todo)
- todo = inputLen;
- memcpy(B + inBuf, input, todo);
- input += todo;
- inputLen -= todo;
- if (inBuf + todo == SHA256_BLOCK_LENGTH)
- SHA256_Compress(ctx);
- }
-
- /* if enough data to fill one or more whole buffers, process them. */
- while (inputLen >= SHA256_BLOCK_LENGTH) {
- memcpy(B, input, SHA256_BLOCK_LENGTH);
- input += SHA256_BLOCK_LENGTH;
- inputLen -= SHA256_BLOCK_LENGTH;
- SHA256_Compress(ctx);
- }
- /* if data left over, fill it into buffer */
- if (inputLen)
- memcpy(B, input, inputLen);
-}
-
-void
-SHA256_End(SHA256Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- unsigned int inBuf = ctx->sizeLo & 0x3f;
- unsigned int padLen = (inBuf < 56) ? (56 - inBuf) : (56 + 64 - inBuf);
- PRUint32 hi, lo;
-#ifdef SWAP4MASK
- PRUint32 t1;
-#endif
-
- hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29);
- lo = (ctx->sizeLo << 3);
-
- SHA256_Update(ctx, pad, padLen);
-
-#if defined(IS_LITTLE_ENDIAN)
- W[14] = SHA_HTONL(hi);
- W[15] = SHA_HTONL(lo);
-#else
- W[14] = hi;
- W[15] = lo;
-#endif
- SHA256_Compress(ctx);
-
- /* now output the answer */
-#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP4(H[0]);
- BYTESWAP4(H[1]);
- BYTESWAP4(H[2]);
- BYTESWAP4(H[3]);
- BYTESWAP4(H[4]);
- BYTESWAP4(H[5]);
- BYTESWAP4(H[6]);
- BYTESWAP4(H[7]);
-#endif
- padLen = PR_MIN(SHA256_LENGTH, maxDigestLen);
- memcpy(digest, H, padLen);
- if (digestLen)
- *digestLen = padLen;
-}
-
-void
-SHA256_EndRaw(SHA256Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- PRUint32 h[8];
- unsigned int len;
-#ifdef SWAP4MASK
- PRUint32 t1;
-#endif
-
- memcpy(h, ctx->h, sizeof(h));
-
-#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP4(h[0]);
- BYTESWAP4(h[1]);
- BYTESWAP4(h[2]);
- BYTESWAP4(h[3]);
- BYTESWAP4(h[4]);
- BYTESWAP4(h[5]);
- BYTESWAP4(h[6]);
- BYTESWAP4(h[7]);
-#endif
-
- len = PR_MIN(SHA256_LENGTH, maxDigestLen);
- memcpy(digest, h, len);
- if (digestLen)
- *digestLen = len;
-}
-
-SECStatus
-SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length)
-{
- SHA256Context ctx;
- unsigned int outLen;
-
- SHA256_Begin(&ctx);
- SHA256_Update(&ctx, src, src_length);
- SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH);
- memset(&ctx, 0, sizeof ctx);
-
- return SECSuccess;
-}
-
-
-SECStatus
-SHA256_Hash(unsigned char *dest, const char *src)
-{
- return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
-}
-
-
-void SHA256_TraceState(SHA256Context *ctx) { }
-
-unsigned int
-SHA256_FlattenSize(SHA256Context *ctx)
-{
- return sizeof *ctx;
-}
-
-SECStatus
-SHA256_Flatten(SHA256Context *ctx,unsigned char *space)
-{
- PORT_Memcpy(space, ctx, sizeof *ctx);
- return SECSuccess;
-}
-
-SHA256Context *
-SHA256_Resurrect(unsigned char *space, void *arg)
-{
- SHA256Context *ctx = SHA256_NewContext();
- if (ctx)
- PORT_Memcpy(ctx, space, sizeof *ctx);
- return ctx;
-}
-
-void SHA256_Clone(SHA256Context *dest, SHA256Context *src)
-{
- memcpy(dest, src, sizeof *dest);
-}
-
-/* ============= SHA224 implementation ================================== */
-
-/* SHA-224 initial hash values */
-static const PRUint32 H224[8] = {
- 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
- 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
-};
-
-SHA224Context *
-SHA224_NewContext(void)
-{
- return SHA256_NewContext();
-}
-
-void
-SHA224_DestroyContext(SHA224Context *ctx, PRBool freeit)
-{
- SHA256_DestroyContext(ctx, freeit);
-}
-
-void
-SHA224_Begin(SHA224Context *ctx)
-{
- memset(ctx, 0, sizeof *ctx);
- memcpy(H, H224, sizeof H224);
-}
-
-void
-SHA224_Update(SHA224Context *ctx, const unsigned char *input,
- unsigned int inputLen)
-{
- SHA256_Update(ctx, input, inputLen);
-}
-
-void
-SHA224_End(SHA256Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH);
- SHA256_End(ctx, digest, digestLen, maxLen);
-}
-
-void
-SHA224_EndRaw(SHA256Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH);
- SHA256_EndRaw(ctx, digest, digestLen, maxLen);
-}
-
-SECStatus
-SHA224_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length)
-{
- SHA256Context ctx;
- unsigned int outLen;
-
- SHA224_Begin(&ctx);
- SHA256_Update(&ctx, src, src_length);
- SHA256_End(&ctx, dest, &outLen, SHA224_LENGTH);
- memset(&ctx, 0, sizeof ctx);
-
- return SECSuccess;
-}
-
-SECStatus
-SHA224_Hash(unsigned char *dest, const char *src)
-{
- return SHA224_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
-}
-
-void SHA224_TraceState(SHA224Context *ctx) { }
-
-unsigned int
-SHA224_FlattenSize(SHA224Context *ctx)
-{
- return SHA256_FlattenSize(ctx);
-}
-
-SECStatus
-SHA224_Flatten(SHA224Context *ctx, unsigned char *space)
-{
- return SHA256_Flatten(ctx, space);
-}
-
-SHA224Context *
-SHA224_Resurrect(unsigned char *space, void *arg)
-{
- return SHA256_Resurrect(space, arg);
-}
-
-void SHA224_Clone(SHA224Context *dest, SHA224Context *src)
-{
- SHA256_Clone(dest, src);
-}
-
-
-/* ======= SHA512 and SHA384 common constants and defines ================= */
-
-/* common #defines for SHA512 and SHA384 */
-#if defined(HAVE_LONG_LONG)
-#if defined(_MSC_VER)
-#pragma intrinsic(_rotr64,_rotl64)
-#define ROTR64(x,n) _rotr64(x,n)
-#define ROTL64(x,n) _rotl64(x,n)
-#else
-#define ROTR64(x,n) ((x >> n) | (x << (64 - n)))
-#define ROTL64(x,n) ((x << n) | (x >> (64 - n)))
-#endif
-
-#define S0(x) (ROTR64(x,28) ^ ROTR64(x,34) ^ ROTR64(x,39))
-#define S1(x) (ROTR64(x,14) ^ ROTR64(x,18) ^ ROTR64(x,41))
-#define s0(x) (t1 = x, ROTR64(t1, 1) ^ ROTR64(t1, 8) ^ SHR(t1,7))
-#define s1(x) (t2 = x, ROTR64(t2,19) ^ ROTR64(t2,61) ^ SHR(t2,6))
-
-#if PR_BYTES_PER_LONG == 8
-#define ULLC(hi,lo) 0x ## hi ## lo ## UL
-#elif defined(_MSC_VER)
-#define ULLC(hi,lo) 0x ## hi ## lo ## ui64
-#else
-#define ULLC(hi,lo) 0x ## hi ## lo ## ULL
-#endif
-
-#if defined(_MSC_VER)
-#pragma intrinsic(_byteswap_uint64)
-#define SHA_HTONLL(x) _byteswap_uint64(x)
-
-#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__x86_64))
-static __inline__ PRUint64 swap8b(PRUint64 value)
-{
- __asm__("bswapq %0" : "+r" (value));
- return (value);
-}
-#define SHA_HTONLL(x) swap8b(x)
-
-#else
-#define SHA_MASK16 ULLC(0000FFFF,0000FFFF)
-#define SHA_MASK8 ULLC(00FF00FF,00FF00FF)
-#define SHA_HTONLL(x) (t1 = x, \
- t1 = ((t1 & SHA_MASK8 ) << 8) | ((t1 >> 8) & SHA_MASK8 ), \
- t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16), \
- (t1 >> 32) | (t1 << 32))
-#endif
-#define BYTESWAP8(x) x = SHA_HTONLL(x)
-
-#else /* no long long */
-
-#if defined(IS_LITTLE_ENDIAN)
-#define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U }
-#else
-#define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
-#endif
-
-#define SHA_HTONLL(x) ( BYTESWAP4(x.lo), BYTESWAP4(x.hi), \
- x.hi ^= x.lo ^= x.hi ^= x.lo, x)
-#define BYTESWAP8(x) do { PRUint32 tmp; BYTESWAP4(x.lo); BYTESWAP4(x.hi); \
- tmp = x.lo; x.lo = x.hi; x.hi = tmp; } while (0)
-#endif
-
-/* SHA-384 and SHA-512 constants, K512. */
-static const PRUint64 K512[80] = {
-#if PR_BYTES_PER_LONG == 8
- 0x428a2f98d728ae22UL , 0x7137449123ef65cdUL ,
- 0xb5c0fbcfec4d3b2fUL , 0xe9b5dba58189dbbcUL ,
- 0x3956c25bf348b538UL , 0x59f111f1b605d019UL ,
- 0x923f82a4af194f9bUL , 0xab1c5ed5da6d8118UL ,
- 0xd807aa98a3030242UL , 0x12835b0145706fbeUL ,
- 0x243185be4ee4b28cUL , 0x550c7dc3d5ffb4e2UL ,
- 0x72be5d74f27b896fUL , 0x80deb1fe3b1696b1UL ,
- 0x9bdc06a725c71235UL , 0xc19bf174cf692694UL ,
- 0xe49b69c19ef14ad2UL , 0xefbe4786384f25e3UL ,
- 0x0fc19dc68b8cd5b5UL , 0x240ca1cc77ac9c65UL ,
- 0x2de92c6f592b0275UL , 0x4a7484aa6ea6e483UL ,
- 0x5cb0a9dcbd41fbd4UL , 0x76f988da831153b5UL ,
- 0x983e5152ee66dfabUL , 0xa831c66d2db43210UL ,
- 0xb00327c898fb213fUL , 0xbf597fc7beef0ee4UL ,
- 0xc6e00bf33da88fc2UL , 0xd5a79147930aa725UL ,
- 0x06ca6351e003826fUL , 0x142929670a0e6e70UL ,
- 0x27b70a8546d22ffcUL , 0x2e1b21385c26c926UL ,
- 0x4d2c6dfc5ac42aedUL , 0x53380d139d95b3dfUL ,
- 0x650a73548baf63deUL , 0x766a0abb3c77b2a8UL ,
- 0x81c2c92e47edaee6UL , 0x92722c851482353bUL ,
- 0xa2bfe8a14cf10364UL , 0xa81a664bbc423001UL ,
- 0xc24b8b70d0f89791UL , 0xc76c51a30654be30UL ,
- 0xd192e819d6ef5218UL , 0xd69906245565a910UL ,
- 0xf40e35855771202aUL , 0x106aa07032bbd1b8UL ,
- 0x19a4c116b8d2d0c8UL , 0x1e376c085141ab53UL ,
- 0x2748774cdf8eeb99UL , 0x34b0bcb5e19b48a8UL ,
- 0x391c0cb3c5c95a63UL , 0x4ed8aa4ae3418acbUL ,
- 0x5b9cca4f7763e373UL , 0x682e6ff3d6b2b8a3UL ,
- 0x748f82ee5defb2fcUL , 0x78a5636f43172f60UL ,
- 0x84c87814a1f0ab72UL , 0x8cc702081a6439ecUL ,
- 0x90befffa23631e28UL , 0xa4506cebde82bde9UL ,
- 0xbef9a3f7b2c67915UL , 0xc67178f2e372532bUL ,
- 0xca273eceea26619cUL , 0xd186b8c721c0c207UL ,
- 0xeada7dd6cde0eb1eUL , 0xf57d4f7fee6ed178UL ,
- 0x06f067aa72176fbaUL , 0x0a637dc5a2c898a6UL ,
- 0x113f9804bef90daeUL , 0x1b710b35131c471bUL ,
- 0x28db77f523047d84UL , 0x32caab7b40c72493UL ,
- 0x3c9ebe0a15c9bebcUL , 0x431d67c49c100d4cUL ,
- 0x4cc5d4becb3e42b6UL , 0x597f299cfc657e2aUL ,
- 0x5fcb6fab3ad6faecUL , 0x6c44198c4a475817UL
-#else
- ULLC(428a2f98,d728ae22), ULLC(71374491,23ef65cd),
- ULLC(b5c0fbcf,ec4d3b2f), ULLC(e9b5dba5,8189dbbc),
- ULLC(3956c25b,f348b538), ULLC(59f111f1,b605d019),
- ULLC(923f82a4,af194f9b), ULLC(ab1c5ed5,da6d8118),
- ULLC(d807aa98,a3030242), ULLC(12835b01,45706fbe),
- ULLC(243185be,4ee4b28c), ULLC(550c7dc3,d5ffb4e2),
- ULLC(72be5d74,f27b896f), ULLC(80deb1fe,3b1696b1),
- ULLC(9bdc06a7,25c71235), ULLC(c19bf174,cf692694),
- ULLC(e49b69c1,9ef14ad2), ULLC(efbe4786,384f25e3),
- ULLC(0fc19dc6,8b8cd5b5), ULLC(240ca1cc,77ac9c65),
- ULLC(2de92c6f,592b0275), ULLC(4a7484aa,6ea6e483),
- ULLC(5cb0a9dc,bd41fbd4), ULLC(76f988da,831153b5),
- ULLC(983e5152,ee66dfab), ULLC(a831c66d,2db43210),
- ULLC(b00327c8,98fb213f), ULLC(bf597fc7,beef0ee4),
- ULLC(c6e00bf3,3da88fc2), ULLC(d5a79147,930aa725),
- ULLC(06ca6351,e003826f), ULLC(14292967,0a0e6e70),
- ULLC(27b70a85,46d22ffc), ULLC(2e1b2138,5c26c926),
- ULLC(4d2c6dfc,5ac42aed), ULLC(53380d13,9d95b3df),
- ULLC(650a7354,8baf63de), ULLC(766a0abb,3c77b2a8),
- ULLC(81c2c92e,47edaee6), ULLC(92722c85,1482353b),
- ULLC(a2bfe8a1,4cf10364), ULLC(a81a664b,bc423001),
- ULLC(c24b8b70,d0f89791), ULLC(c76c51a3,0654be30),
- ULLC(d192e819,d6ef5218), ULLC(d6990624,5565a910),
- ULLC(f40e3585,5771202a), ULLC(106aa070,32bbd1b8),
- ULLC(19a4c116,b8d2d0c8), ULLC(1e376c08,5141ab53),
- ULLC(2748774c,df8eeb99), ULLC(34b0bcb5,e19b48a8),
- ULLC(391c0cb3,c5c95a63), ULLC(4ed8aa4a,e3418acb),
- ULLC(5b9cca4f,7763e373), ULLC(682e6ff3,d6b2b8a3),
- ULLC(748f82ee,5defb2fc), ULLC(78a5636f,43172f60),
- ULLC(84c87814,a1f0ab72), ULLC(8cc70208,1a6439ec),
- ULLC(90befffa,23631e28), ULLC(a4506ceb,de82bde9),
- ULLC(bef9a3f7,b2c67915), ULLC(c67178f2,e372532b),
- ULLC(ca273ece,ea26619c), ULLC(d186b8c7,21c0c207),
- ULLC(eada7dd6,cde0eb1e), ULLC(f57d4f7f,ee6ed178),
- ULLC(06f067aa,72176fba), ULLC(0a637dc5,a2c898a6),
- ULLC(113f9804,bef90dae), ULLC(1b710b35,131c471b),
- ULLC(28db77f5,23047d84), ULLC(32caab7b,40c72493),
- ULLC(3c9ebe0a,15c9bebc), ULLC(431d67c4,9c100d4c),
- ULLC(4cc5d4be,cb3e42b6), ULLC(597f299c,fc657e2a),
- ULLC(5fcb6fab,3ad6faec), ULLC(6c44198c,4a475817)
-#endif
-};
-
-struct SHA512ContextStr {
- union {
- PRUint64 w[80]; /* message schedule, input buffer, plus 64 words */
- PRUint32 l[160];
- PRUint8 b[640];
- } u;
- PRUint64 h[8]; /* 8 state variables */
- PRUint64 sizeLo; /* 64-bit count of hashed bytes. */
-};
-
-/* =========== SHA512 implementation ===================================== */
-
-/* SHA-512 initial hash values */
-static const PRUint64 H512[8] = {
-#if PR_BYTES_PER_LONG == 8
- 0x6a09e667f3bcc908UL , 0xbb67ae8584caa73bUL ,
- 0x3c6ef372fe94f82bUL , 0xa54ff53a5f1d36f1UL ,
- 0x510e527fade682d1UL , 0x9b05688c2b3e6c1fUL ,
- 0x1f83d9abfb41bd6bUL , 0x5be0cd19137e2179UL
-#else
- ULLC(6a09e667,f3bcc908), ULLC(bb67ae85,84caa73b),
- ULLC(3c6ef372,fe94f82b), ULLC(a54ff53a,5f1d36f1),
- ULLC(510e527f,ade682d1), ULLC(9b05688c,2b3e6c1f),
- ULLC(1f83d9ab,fb41bd6b), ULLC(5be0cd19,137e2179)
-#endif
-};
-
-
-SHA512Context *
-SHA512_NewContext(void)
-{
- SHA512Context *ctx = PORT_New(SHA512Context);
- return ctx;
-}
-
-void
-SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
-{
- memset(ctx, 0, sizeof *ctx);
- if (freeit) {
- PORT_Free(ctx);
- }
-}
-
-void
-SHA512_Begin(SHA512Context *ctx)
-{
- memset(ctx, 0, sizeof *ctx);
- memcpy(H, H512, sizeof H512);
-}
-
-#if defined(SHA512_TRACE)
-#if defined(HAVE_LONG_LONG)
-#define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %016lx, %s = %016lx\n", \
- n, #e, d, #a, h);
-#else
-#define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %08x%08x, %s = %08x%08x\n", \
- n, #e, d.hi, d.lo, #a, h.hi, h.lo);
-#endif
-#else
-#define DUMP(n,a,d,e,h)
-#endif
-
-#if defined(HAVE_LONG_LONG)
-
-#define ADDTO(x,y) y += x
-
-#define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
-
-#define ROUND(n,a,b,c,d,e,f,g,h) \
- h += S1(e) + Ch(e,f,g) + K512[n] + W[n]; \
- d += h; \
- h += S0(a) + Maj(a,b,c); \
- DUMP(n,a,d,e,h)
-
-#else /* use only 32-bit variables, and don't unroll loops */
-
-#undef NOUNROLL512
-#define NOUNROLL512 1
-
-#define ADDTO(x,y) y.lo += x.lo; y.hi += x.hi + (x.lo > y.lo)
-
-#define ROTR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
-#define ROTR64A(x,n,lo,hi) (x.lo << (64-n) | x.hi >> (n-32))
-#define SHR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
-
-/* Capitol Sigma and lower case sigma functions */
-#define s0lo(x) (ROTR64a(x,1,lo,hi) ^ ROTR64a(x,8,lo,hi) ^ SHR64a(x,7,lo,hi))
-#define s0hi(x) (ROTR64a(x,1,hi,lo) ^ ROTR64a(x,8,hi,lo) ^ (x.hi >> 7))
-
-#define s1lo(x) (ROTR64a(x,19,lo,hi) ^ ROTR64A(x,61,lo,hi) ^ SHR64a(x,6,lo,hi))
-#define s1hi(x) (ROTR64a(x,19,hi,lo) ^ ROTR64A(x,61,hi,lo) ^ (x.hi >> 6))
-
-#define S0lo(x)(ROTR64a(x,28,lo,hi) ^ ROTR64A(x,34,lo,hi) ^ ROTR64A(x,39,lo,hi))
-#define S0hi(x)(ROTR64a(x,28,hi,lo) ^ ROTR64A(x,34,hi,lo) ^ ROTR64A(x,39,hi,lo))
-
-#define S1lo(x)(ROTR64a(x,14,lo,hi) ^ ROTR64a(x,18,lo,hi) ^ ROTR64A(x,41,lo,hi))
-#define S1hi(x)(ROTR64a(x,14,hi,lo) ^ ROTR64a(x,18,hi,lo) ^ ROTR64A(x,41,hi,lo))
-
-/* 32-bit versions of Ch and Maj */
-#define Chxx(x,y,z,lo) ((x.lo & y.lo) ^ (~x.lo & z.lo))
-#define Majx(x,y,z,lo) ((x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo))
-
-#define INITW(t) \
- do { \
- PRUint32 lo, tm; \
- PRUint32 cy = 0; \
- lo = s1lo(W[t-2]); \
- lo += (tm = W[t-7].lo); if (lo < tm) cy++; \
- lo += (tm = s0lo(W[t-15])); if (lo < tm) cy++; \
- lo += (tm = W[t-16].lo); if (lo < tm) cy++; \
- W[t].lo = lo; \
- W[t].hi = cy + s1hi(W[t-2]) + W[t-7].hi + s0hi(W[t-15]) + W[t-16].hi; \
- } while (0)
-
-#define ROUND(n,a,b,c,d,e,f,g,h) \
- { \
- PRUint32 lo, tm, cy; \
- lo = S1lo(e); \
- lo += (tm = Chxx(e,f,g,lo)); cy = (lo < tm); \
- lo += (tm = K512[n].lo); if (lo < tm) cy++; \
- lo += (tm = W[n].lo); if (lo < tm) cy++; \
- h.lo += lo; if (h.lo < lo) cy++; \
- h.hi += cy + S1hi(e) + Chxx(e,f,g,hi) + K512[n].hi + W[n].hi; \
- d.lo += h.lo; \
- d.hi += h.hi + (d.lo < h.lo); \
- lo = S0lo(a); \
- lo += (tm = Majx(a,b,c,lo)); cy = (lo < tm); \
- h.lo += lo; if (h.lo < lo) cy++; \
- h.hi += cy + S0hi(a) + Majx(a,b,c,hi); \
- DUMP(n,a,d,e,h) \
- }
-#endif
-
-static void
-SHA512_Compress(SHA512Context *ctx)
-{
-#if defined(IS_LITTLE_ENDIAN)
- {
-#if defined(HAVE_LONG_LONG)
- PRUint64 t1;
-#else
- PRUint32 t1;
-#endif
- BYTESWAP8(W[0]);
- BYTESWAP8(W[1]);
- BYTESWAP8(W[2]);
- BYTESWAP8(W[3]);
- BYTESWAP8(W[4]);
- BYTESWAP8(W[5]);
- BYTESWAP8(W[6]);
- BYTESWAP8(W[7]);
- BYTESWAP8(W[8]);
- BYTESWAP8(W[9]);
- BYTESWAP8(W[10]);
- BYTESWAP8(W[11]);
- BYTESWAP8(W[12]);
- BYTESWAP8(W[13]);
- BYTESWAP8(W[14]);
- BYTESWAP8(W[15]);
- }
-#endif
-
- {
- PRUint64 t1, t2;
-#ifdef NOUNROLL512
- {
- /* prepare the "message schedule" */
- int t;
- for (t = 16; t < 80; ++t) {
- INITW(t);
- }
- }
-#else
- INITW(16);
- INITW(17);
- INITW(18);
- INITW(19);
-
- INITW(20);
- INITW(21);
- INITW(22);
- INITW(23);
- INITW(24);
- INITW(25);
- INITW(26);
- INITW(27);
- INITW(28);
- INITW(29);
-
- INITW(30);
- INITW(31);
- INITW(32);
- INITW(33);
- INITW(34);
- INITW(35);
- INITW(36);
- INITW(37);
- INITW(38);
- INITW(39);
-
- INITW(40);
- INITW(41);
- INITW(42);
- INITW(43);
- INITW(44);
- INITW(45);
- INITW(46);
- INITW(47);
- INITW(48);
- INITW(49);
-
- INITW(50);
- INITW(51);
- INITW(52);
- INITW(53);
- INITW(54);
- INITW(55);
- INITW(56);
- INITW(57);
- INITW(58);
- INITW(59);
-
- INITW(60);
- INITW(61);
- INITW(62);
- INITW(63);
- INITW(64);
- INITW(65);
- INITW(66);
- INITW(67);
- INITW(68);
- INITW(69);
-
- INITW(70);
- INITW(71);
- INITW(72);
- INITW(73);
- INITW(74);
- INITW(75);
- INITW(76);
- INITW(77);
- INITW(78);
- INITW(79);
-#endif
- }
-#ifdef SHA512_TRACE
- {
- int i;
- for (i = 0; i < 80; ++i) {
-#ifdef HAVE_LONG_LONG
- printf("W[%2d] = %016lx\n", i, W[i]);
-#else
- printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo);
-#endif
- }
- }
-#endif
- {
- PRUint64 a, b, c, d, e, f, g, h;
-
- a = H[0];
- b = H[1];
- c = H[2];
- d = H[3];
- e = H[4];
- f = H[5];
- g = H[6];
- h = H[7];
-
-#ifdef NOUNROLL512
- {
- int t;
- for (t = 0; t < 80; t+= 8) {
- ROUND(t+0,a,b,c,d,e,f,g,h)
- ROUND(t+1,h,a,b,c,d,e,f,g)
- ROUND(t+2,g,h,a,b,c,d,e,f)
- ROUND(t+3,f,g,h,a,b,c,d,e)
- ROUND(t+4,e,f,g,h,a,b,c,d)
- ROUND(t+5,d,e,f,g,h,a,b,c)
- ROUND(t+6,c,d,e,f,g,h,a,b)
- ROUND(t+7,b,c,d,e,f,g,h,a)
- }
- }
-#else
- ROUND( 0,a,b,c,d,e,f,g,h)
- ROUND( 1,h,a,b,c,d,e,f,g)
- ROUND( 2,g,h,a,b,c,d,e,f)
- ROUND( 3,f,g,h,a,b,c,d,e)
- ROUND( 4,e,f,g,h,a,b,c,d)
- ROUND( 5,d,e,f,g,h,a,b,c)
- ROUND( 6,c,d,e,f,g,h,a,b)
- ROUND( 7,b,c,d,e,f,g,h,a)
-
- ROUND( 8,a,b,c,d,e,f,g,h)
- ROUND( 9,h,a,b,c,d,e,f,g)
- ROUND(10,g,h,a,b,c,d,e,f)
- ROUND(11,f,g,h,a,b,c,d,e)
- ROUND(12,e,f,g,h,a,b,c,d)
- ROUND(13,d,e,f,g,h,a,b,c)
- ROUND(14,c,d,e,f,g,h,a,b)
- ROUND(15,b,c,d,e,f,g,h,a)
-
- ROUND(16,a,b,c,d,e,f,g,h)
- ROUND(17,h,a,b,c,d,e,f,g)
- ROUND(18,g,h,a,b,c,d,e,f)
- ROUND(19,f,g,h,a,b,c,d,e)
- ROUND(20,e,f,g,h,a,b,c,d)
- ROUND(21,d,e,f,g,h,a,b,c)
- ROUND(22,c,d,e,f,g,h,a,b)
- ROUND(23,b,c,d,e,f,g,h,a)
-
- ROUND(24,a,b,c,d,e,f,g,h)
- ROUND(25,h,a,b,c,d,e,f,g)
- ROUND(26,g,h,a,b,c,d,e,f)
- ROUND(27,f,g,h,a,b,c,d,e)
- ROUND(28,e,f,g,h,a,b,c,d)
- ROUND(29,d,e,f,g,h,a,b,c)
- ROUND(30,c,d,e,f,g,h,a,b)
- ROUND(31,b,c,d,e,f,g,h,a)
-
- ROUND(32,a,b,c,d,e,f,g,h)
- ROUND(33,h,a,b,c,d,e,f,g)
- ROUND(34,g,h,a,b,c,d,e,f)
- ROUND(35,f,g,h,a,b,c,d,e)
- ROUND(36,e,f,g,h,a,b,c,d)
- ROUND(37,d,e,f,g,h,a,b,c)
- ROUND(38,c,d,e,f,g,h,a,b)
- ROUND(39,b,c,d,e,f,g,h,a)
-
- ROUND(40,a,b,c,d,e,f,g,h)
- ROUND(41,h,a,b,c,d,e,f,g)
- ROUND(42,g,h,a,b,c,d,e,f)
- ROUND(43,f,g,h,a,b,c,d,e)
- ROUND(44,e,f,g,h,a,b,c,d)
- ROUND(45,d,e,f,g,h,a,b,c)
- ROUND(46,c,d,e,f,g,h,a,b)
- ROUND(47,b,c,d,e,f,g,h,a)
-
- ROUND(48,a,b,c,d,e,f,g,h)
- ROUND(49,h,a,b,c,d,e,f,g)
- ROUND(50,g,h,a,b,c,d,e,f)
- ROUND(51,f,g,h,a,b,c,d,e)
- ROUND(52,e,f,g,h,a,b,c,d)
- ROUND(53,d,e,f,g,h,a,b,c)
- ROUND(54,c,d,e,f,g,h,a,b)
- ROUND(55,b,c,d,e,f,g,h,a)
-
- ROUND(56,a,b,c,d,e,f,g,h)
- ROUND(57,h,a,b,c,d,e,f,g)
- ROUND(58,g,h,a,b,c,d,e,f)
- ROUND(59,f,g,h,a,b,c,d,e)
- ROUND(60,e,f,g,h,a,b,c,d)
- ROUND(61,d,e,f,g,h,a,b,c)
- ROUND(62,c,d,e,f,g,h,a,b)
- ROUND(63,b,c,d,e,f,g,h,a)
-
- ROUND(64,a,b,c,d,e,f,g,h)
- ROUND(65,h,a,b,c,d,e,f,g)
- ROUND(66,g,h,a,b,c,d,e,f)
- ROUND(67,f,g,h,a,b,c,d,e)
- ROUND(68,e,f,g,h,a,b,c,d)
- ROUND(69,d,e,f,g,h,a,b,c)
- ROUND(70,c,d,e,f,g,h,a,b)
- ROUND(71,b,c,d,e,f,g,h,a)
-
- ROUND(72,a,b,c,d,e,f,g,h)
- ROUND(73,h,a,b,c,d,e,f,g)
- ROUND(74,g,h,a,b,c,d,e,f)
- ROUND(75,f,g,h,a,b,c,d,e)
- ROUND(76,e,f,g,h,a,b,c,d)
- ROUND(77,d,e,f,g,h,a,b,c)
- ROUND(78,c,d,e,f,g,h,a,b)
- ROUND(79,b,c,d,e,f,g,h,a)
-#endif
-
- ADDTO(a,H[0]);
- ADDTO(b,H[1]);
- ADDTO(c,H[2]);
- ADDTO(d,H[3]);
- ADDTO(e,H[4]);
- ADDTO(f,H[5]);
- ADDTO(g,H[6]);
- ADDTO(h,H[7]);
- }
-}
-
-void
-SHA512_Update(SHA512Context *ctx, const unsigned char *input,
- unsigned int inputLen)
-{
- unsigned int inBuf;
- if (!inputLen)
- return;
-
-#if defined(HAVE_LONG_LONG)
- inBuf = (unsigned int)ctx->sizeLo & 0x7f;
- /* Add inputLen into the count of bytes processed, before processing */
- ctx->sizeLo += inputLen;
-#else
- inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
- ctx->sizeLo.lo += inputLen;
- if (ctx->sizeLo.lo < inputLen) ctx->sizeLo.hi++;
-#endif
-
- /* if data already in buffer, attemp to fill rest of buffer */
- if (inBuf) {
- unsigned int todo = SHA512_BLOCK_LENGTH - inBuf;
- if (inputLen < todo)
- todo = inputLen;
- memcpy(B + inBuf, input, todo);
- input += todo;
- inputLen -= todo;
- if (inBuf + todo == SHA512_BLOCK_LENGTH)
- SHA512_Compress(ctx);
- }
-
- /* if enough data to fill one or more whole buffers, process them. */
- while (inputLen >= SHA512_BLOCK_LENGTH) {
- memcpy(B, input, SHA512_BLOCK_LENGTH);
- input += SHA512_BLOCK_LENGTH;
- inputLen -= SHA512_BLOCK_LENGTH;
- SHA512_Compress(ctx);
- }
- /* if data left over, fill it into buffer */
- if (inputLen)
- memcpy(B, input, inputLen);
-}
-
-void
-SHA512_End(SHA512Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
-#if defined(HAVE_LONG_LONG)
- unsigned int inBuf = (unsigned int)ctx->sizeLo & 0x7f;
- PRUint64 t1;
-#else
- unsigned int inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
- PRUint32 t1;
-#endif
- unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
- PRUint64 lo;
- LL_SHL(lo, ctx->sizeLo, 3);
-
- SHA512_Update(ctx, pad, padLen);
-
-#if defined(HAVE_LONG_LONG)
- W[14] = 0;
-#else
- W[14].lo = 0;
- W[14].hi = 0;
-#endif
-
- W[15] = lo;
-#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP8(W[15]);
-#endif
- SHA512_Compress(ctx);
-
- /* now output the answer */
-#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP8(H[0]);
- BYTESWAP8(H[1]);
- BYTESWAP8(H[2]);
- BYTESWAP8(H[3]);
- BYTESWAP8(H[4]);
- BYTESWAP8(H[5]);
- BYTESWAP8(H[6]);
- BYTESWAP8(H[7]);
-#endif
- padLen = PR_MIN(SHA512_LENGTH, maxDigestLen);
- memcpy(digest, H, padLen);
- if (digestLen)
- *digestLen = padLen;
-}
-
-void
-SHA512_EndRaw(SHA512Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
-#if defined(HAVE_LONG_LONG)
- PRUint64 t1;
-#else
- PRUint32 t1;
-#endif
- PRUint64 h[8];
- unsigned int len;
-
- memcpy(h, ctx->h, sizeof(h));
-
-#if defined(IS_LITTLE_ENDIAN)
- BYTESWAP8(h[0]);
- BYTESWAP8(h[1]);
- BYTESWAP8(h[2]);
- BYTESWAP8(h[3]);
- BYTESWAP8(h[4]);
- BYTESWAP8(h[5]);
- BYTESWAP8(h[6]);
- BYTESWAP8(h[7]);
-#endif
- len = PR_MIN(SHA512_LENGTH, maxDigestLen);
- memcpy(digest, h, len);
- if (digestLen)
- *digestLen = len;
-}
-
-SECStatus
-SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length)
-{
- SHA512Context ctx;
- unsigned int outLen;
-
- SHA512_Begin(&ctx);
- SHA512_Update(&ctx, src, src_length);
- SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH);
- memset(&ctx, 0, sizeof ctx);
-
- return SECSuccess;
-}
-
-
-SECStatus
-SHA512_Hash(unsigned char *dest, const char *src)
-{
- return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
-}
-
-
-void SHA512_TraceState(SHA512Context *ctx) { }
-
-unsigned int
-SHA512_FlattenSize(SHA512Context *ctx)
-{
- return sizeof *ctx;
-}
-
-SECStatus
-SHA512_Flatten(SHA512Context *ctx,unsigned char *space)
-{
- PORT_Memcpy(space, ctx, sizeof *ctx);
- return SECSuccess;
-}
-
-SHA512Context *
-SHA512_Resurrect(unsigned char *space, void *arg)
-{
- SHA512Context *ctx = SHA512_NewContext();
- if (ctx)
- PORT_Memcpy(ctx, space, sizeof *ctx);
- return ctx;
-}
-
-void SHA512_Clone(SHA512Context *dest, SHA512Context *src)
-{
- memcpy(dest, src, sizeof *dest);
-}
-
-/* ======================================================================= */
-/* SHA384 uses a SHA512Context as the real context.
-** The only differences between SHA384 an SHA512 are:
-** a) the intialization values for the context, and
-** b) the number of bytes of data produced as output.
-*/
-
-/* SHA-384 initial hash values */
-static const PRUint64 H384[8] = {
-#if PR_BYTES_PER_LONG == 8
- 0xcbbb9d5dc1059ed8UL , 0x629a292a367cd507UL ,
- 0x9159015a3070dd17UL , 0x152fecd8f70e5939UL ,
- 0x67332667ffc00b31UL , 0x8eb44a8768581511UL ,
- 0xdb0c2e0d64f98fa7UL , 0x47b5481dbefa4fa4UL
-#else
- ULLC(cbbb9d5d,c1059ed8), ULLC(629a292a,367cd507),
- ULLC(9159015a,3070dd17), ULLC(152fecd8,f70e5939),
- ULLC(67332667,ffc00b31), ULLC(8eb44a87,68581511),
- ULLC(db0c2e0d,64f98fa7), ULLC(47b5481d,befa4fa4)
-#endif
-};
-
-SHA384Context *
-SHA384_NewContext(void)
-{
- return SHA512_NewContext();
-}
-
-void
-SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit)
-{
- SHA512_DestroyContext(ctx, freeit);
-}
-
-void
-SHA384_Begin(SHA384Context *ctx)
-{
- memset(ctx, 0, sizeof *ctx);
- memcpy(H, H384, sizeof H384);
-}
-
-void
-SHA384_Update(SHA384Context *ctx, const unsigned char *input,
- unsigned int inputLen)
-{
- SHA512_Update(ctx, input, inputLen);
-}
-
-void
-SHA384_End(SHA384Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
- SHA512_End(ctx, digest, digestLen, maxLen);
-}
-
-void
-SHA384_EndRaw(SHA384Context *ctx, unsigned char *digest,
- unsigned int *digestLen, unsigned int maxDigestLen)
-{
- unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
- SHA512_EndRaw(ctx, digest, digestLen, maxLen);
-}
-
-SECStatus
-SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
- uint32 src_length)
-{
- SHA512Context ctx;
- unsigned int outLen;
-
- SHA384_Begin(&ctx);
- SHA512_Update(&ctx, src, src_length);
- SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
- memset(&ctx, 0, sizeof ctx);
-
- return SECSuccess;
-}
-
-SECStatus
-SHA384_Hash(unsigned char *dest, const char *src)
-{
- return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
-}
-
-void SHA384_TraceState(SHA384Context *ctx) { }
-
-unsigned int
-SHA384_FlattenSize(SHA384Context *ctx)
-{
- return sizeof(SHA384Context);
-}
-
-SECStatus
-SHA384_Flatten(SHA384Context *ctx,unsigned char *space)
-{
- return SHA512_Flatten(ctx, space);
-}
-
-SHA384Context *
-SHA384_Resurrect(unsigned char *space, void *arg)
-{
- return SHA512_Resurrect(space, arg);
-}
-
-void SHA384_Clone(SHA384Context *dest, SHA384Context *src)
-{
- memcpy(dest, src, sizeof *dest);
-}
-
-/* ======================================================================= */
-#ifdef SELFTEST
-#include <stdio.h>
-
-static const char abc[] = { "abc" };
-static const char abcdbc[] = {
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
-};
-static const char abcdef[] = {
- "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
-};
-
-void
-dumpHash32(const unsigned char *buf, unsigned int bufLen)
-{
- unsigned int i;
- for (i = 0; i < bufLen; i += 4) {
- printf(" %02x%02x%02x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]);
- }
- printf("\n");
-}
-
-void test256(void)
-{
- unsigned char outBuf[SHA256_LENGTH];
-
- printf("SHA256, input = %s\n", abc);
- SHA256_Hash(outBuf, abc);
- dumpHash32(outBuf, sizeof outBuf);
-
- printf("SHA256, input = %s\n", abcdbc);
- SHA256_Hash(outBuf, abcdbc);
- dumpHash32(outBuf, sizeof outBuf);
-}
-
-void test224(void)
-{
- SHA224Context ctx;
- unsigned char a1000times[1000];
- unsigned int outLen;
- unsigned char outBuf[SHA224_LENGTH];
- int i;
-
- /* Test Vector 1 */
- printf("SHA224, input = %s\n", abc);
- SHA224_Hash(outBuf, abc);
- dumpHash32(outBuf, sizeof outBuf);
-
- /* Test Vector 2 */
- printf("SHA224, input = %s\n", abcdbc);
- SHA224_Hash(outBuf, abcdbc);
- dumpHash32(outBuf, sizeof outBuf);
-
- /* Test Vector 3 */
-
- /* to hash one million 'a's perform 1000
- * sha224 updates on a buffer with 1000 'a's
- */
- memset(a1000times, 'a', 1000);
- printf("SHA224, input = %s\n", "a one million times");
- SHA224_Begin(&ctx);
- for (i = 0; i < 1000; i++)
- SHA224_Update(&ctx, a1000times, 1000);
- SHA224_End(&ctx, outBuf, &outLen, SHA224_LENGTH);
- dumpHash32(outBuf, sizeof outBuf);
-}
-
-void
-dumpHash64(const unsigned char *buf, unsigned int bufLen)
-{
- unsigned int i;
- for (i = 0; i < bufLen; i += 8) {
- if (i % 32 == 0)
- printf("\n");
- printf(" %02x%02x%02x%02x%02x%02x%02x%02x",
- buf[i ], buf[i+1], buf[i+2], buf[i+3],
- buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
- }
- printf("\n");
-}
-
-void test512(void)
-{
- unsigned char outBuf[SHA512_LENGTH];
-
- printf("SHA512, input = %s\n", abc);
- SHA512_Hash(outBuf, abc);
- dumpHash64(outBuf, sizeof outBuf);
-
- printf("SHA512, input = %s\n", abcdef);
- SHA512_Hash(outBuf, abcdef);
- dumpHash64(outBuf, sizeof outBuf);
-}
-
-void time512(void)
-{
- unsigned char outBuf[SHA512_LENGTH];
-
- SHA512_Hash(outBuf, abc);
- SHA512_Hash(outBuf, abcdef);
-}
-
-void test384(void)
-{
- unsigned char outBuf[SHA384_LENGTH];
-
- printf("SHA384, input = %s\n", abc);
- SHA384_Hash(outBuf, abc);
- dumpHash64(outBuf, sizeof outBuf);
-
- printf("SHA384, input = %s\n", abcdef);
- SHA384_Hash(outBuf, abcdef);
- dumpHash64(outBuf, sizeof outBuf);
-}
-
-int main (int argc, char *argv[], char *envp[])
-{
- int i = 1;
- if (argc > 1) {
- i = atoi(argv[1]);
- }
- if (i < 2) {
- test224();
- test256();
- test384();
- test512();
- } else {
- while (i-- > 0) {
- time512();
- }
- printf("done\n");
- }
- return 0;
-}
-
-void *PORT_Alloc(size_t len) { return malloc(len); }
-void PORT_Free(void *ptr) { free(ptr); }
-void PORT_ZFree(void *ptr, size_t len) { memset(ptr, 0, len); free(ptr); }
-#endif
diff --git a/security/nss/lib/freebl/sha_fast.c b/security/nss/lib/freebl/sha_fast.c
deleted file mode 100644
index 4db53fe15..000000000
--- a/security/nss/lib/freebl/sha_fast.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include <memory.h>
-#include "blapi.h"
-#include "sha_fast.h"
-#include "prerror.h"
-
-#ifdef TRACING_SSL
-#include "ssl.h"
-#include "ssltrace.h"
-#endif
-
-static void shaCompress(volatile SHA_HW_t *X, const PRUint32 * datain);
-
-#define W u.w
-#define B u.b
-
-
-#define SHA_F1(X,Y,Z) ((((Y)^(Z))&(X))^(Z))
-#define SHA_F2(X,Y,Z) ((X)^(Y)^(Z))
-#define SHA_F3(X,Y,Z) (((X)&(Y))|((Z)&((X)|(Y))))
-#define SHA_F4(X,Y,Z) ((X)^(Y)^(Z))
-
-#define SHA_MIX(n,a,b,c) XW(n) = SHA_ROTL(XW(a)^XW(b)^XW(c)^XW(n), 1)
-
-/*
- * SHA: initialize context
- */
-void
-SHA1_Begin(SHA1Context *ctx)
-{
- ctx->size = 0;
- /*
- * Initialize H with constants from FIPS180-1.
- */
- ctx->H[0] = 0x67452301L;
- ctx->H[1] = 0xefcdab89L;
- ctx->H[2] = 0x98badcfeL;
- ctx->H[3] = 0x10325476L;
- ctx->H[4] = 0xc3d2e1f0L;
-}
-
-/* Explanation of H array and index values:
- * The context's H array is actually the concatenation of two arrays
- * defined by SHA1, the H array of state variables (5 elements),
- * and the W array of intermediate values, of which there are 16 elements.
- * The W array starts at H[5], that is W[0] is H[5].
- * Although these values are defined as 32-bit values, we use 64-bit
- * variables to hold them because the AMD64 stores 64 bit values in
- * memory MUCH faster than it stores any smaller values.
- *
- * Rather than passing the context structure to shaCompress, we pass
- * this combined array of H and W values. We do not pass the address
- * of the first element of this array, but rather pass the address of an
- * element in the middle of the array, element X. Presently X[0] is H[11].
- * So we pass the address of H[11] as the address of array X to shaCompress.
- * Then shaCompress accesses the members of the array using positive AND
- * negative indexes.
- *
- * Pictorially: (each element is 8 bytes)
- * H | H0 H1 H2 H3 H4 W0 W1 W2 W3 W4 W5 W6 W7 W8 W9 Wa Wb Wc Wd We Wf |
- * X |-11-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 |
- *
- * The byte offset from X[0] to any member of H and W is always
- * representable in a signed 8-bit value, which will be encoded
- * as a single byte offset in the X86-64 instruction set.
- * If we didn't pass the address of H[11], and instead passed the
- * address of H[0], the offsets to elements H[16] and above would be
- * greater than 127, not representable in a signed 8-bit value, and the
- * x86-64 instruction set would encode every such offset as a 32-bit
- * signed number in each instruction that accessed element H[16] or
- * higher. This results in much bigger and slower code.
- */
-#if !defined(SHA_PUT_W_IN_STACK)
-#define H2X 11 /* X[0] is H[11], and H[0] is X[-11] */
-#define W2X 6 /* X[0] is W[6], and W[0] is X[-6] */
-#else
-#define H2X 0
-#endif
-
-/*
- * SHA: Add data to context.
- */
-void
-SHA1_Update(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
-{
- register unsigned int lenB;
- register unsigned int togo;
-
- if (!len)
- return;
-
- /* accumulate the byte count. */
- lenB = (unsigned int)(ctx->size) & 63U;
-
- ctx->size += len;
-
- /*
- * Read the data into W and process blocks as they get full
- */
- if (lenB > 0) {
- togo = 64U - lenB;
- if (len < togo)
- togo = len;
- memcpy(ctx->B + lenB, dataIn, togo);
- len -= togo;
- dataIn += togo;
- lenB = (lenB + togo) & 63U;
- if (!lenB) {
- shaCompress(&ctx->H[H2X], ctx->W);
- }
- }
-#if !defined(SHA_ALLOW_UNALIGNED_ACCESS)
- if ((ptrdiff_t)dataIn % sizeof(PRUint32)) {
- while (len >= 64U) {
- memcpy(ctx->B, dataIn, 64);
- len -= 64U;
- shaCompress(&ctx->H[H2X], ctx->W);
- dataIn += 64U;
- }
- } else
-#endif
- {
- while (len >= 64U) {
- len -= 64U;
- shaCompress(&ctx->H[H2X], (PRUint32 *)dataIn);
- dataIn += 64U;
- }
- }
- if (len) {
- memcpy(ctx->B, dataIn, len);
- }
-}
-
-
-/*
- * SHA: Generate hash value from context
- */
-void
-SHA1_End(SHA1Context *ctx, unsigned char *hashout,
- unsigned int *pDigestLen, unsigned int maxDigestLen)
-{
- register PRUint64 size;
- register PRUint32 lenB;
- PRUint32 tmpbuf[5];
-
- static const unsigned char bulk_pad[64] = { 0x80,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,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,0 };
-#define tmp lenB
-
- PORT_Assert (maxDigestLen >= SHA1_LENGTH);
-
- /*
- * Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits
- */
- size = ctx->size;
-
- lenB = (PRUint32)size & 63;
- SHA1_Update(ctx, bulk_pad, (((55+64) - lenB) & 63) + 1);
- PORT_Assert(((PRUint32)ctx->size & 63) == 56);
- /* Convert size from bytes to bits. */
- size <<= 3;
- ctx->W[14] = SHA_HTONL((PRUint32)(size >> 32));
- ctx->W[15] = SHA_HTONL((PRUint32)size);
- shaCompress(&ctx->H[H2X], ctx->W);
-
- /*
- * Output hash
- */
- SHA_STORE_RESULT;
- if (pDigestLen) {
- *pDigestLen = SHA1_LENGTH;
- }
-#undef tmp
-}
-
-void
-SHA1_EndRaw(SHA1Context *ctx, unsigned char *hashout,
- unsigned int *pDigestLen, unsigned int maxDigestLen)
-{
-#if defined(SHA_NEED_TMP_VARIABLE)
- register PRUint32 tmp;
-#endif
- PRUint32 tmpbuf[5];
- PORT_Assert (maxDigestLen >= SHA1_LENGTH);
-
- SHA_STORE_RESULT;
- if (pDigestLen)
- *pDigestLen = SHA1_LENGTH;
-}
-
-#undef B
-/*
- * SHA: Compression function, unrolled.
- *
- * Some operations in shaCompress are done as 5 groups of 16 operations.
- * Others are done as 4 groups of 20 operations.
- * The code below shows that structure.
- *
- * The functions that compute the new values of the 5 state variables
- * A-E are done in 4 groups of 20 operations (or you may also think
- * of them as being done in 16 groups of 5 operations). They are
- * done by the SHA_RNDx macros below, in the right column.
- *
- * The functions that set the 16 values of the W array are done in
- * 5 groups of 16 operations. The first group is done by the
- * LOAD macros below, the latter 4 groups are done by SHA_MIX below,
- * in the left column.
- *
- * gcc's optimizer observes that each member of the W array is assigned
- * a value 5 times in this code. It reduces the number of store
- * operations done to the W array in the context (that is, in the X array)
- * by creating a W array on the stack, and storing the W values there for
- * the first 4 groups of operations on W, and storing the values in the
- * context's W array only in the fifth group. This is undesirable.
- * It is MUCH bigger code than simply using the context's W array, because
- * all the offsets to the W array in the stack are 32-bit signed offsets,
- * and it is no faster than storing the values in the context's W array.
- *
- * The original code for sha_fast.c prevented this creation of a separate
- * W array in the stack by creating a W array of 80 members, each of
- * whose elements is assigned only once. It also separated the computations
- * of the W array values and the computations of the values for the 5
- * state variables into two separate passes, W's, then A-E's so that the
- * second pass could be done all in registers (except for accessing the W
- * array) on machines with fewer registers. The method is suboptimal
- * for machines with enough registers to do it all in one pass, and it
- * necessitates using many instructions with 32-bit offsets.
- *
- * This code eliminates the separate W array on the stack by a completely
- * different means: by declaring the X array volatile. This prevents
- * the optimizer from trying to reduce the use of the X array by the
- * creation of a MORE expensive W array on the stack. The result is
- * that all instructions use signed 8-bit offsets and not 32-bit offsets.
- *
- * The combination of this code and the -O3 optimizer flag on GCC 3.4.3
- * results in code that is 3 times faster than the previous NSS sha_fast
- * code on AMD64.
- */
-static void
-shaCompress(volatile SHA_HW_t *X, const PRUint32 *inbuf)
-{
- register SHA_HW_t A, B, C, D, E;
-
-#if defined(SHA_NEED_TMP_VARIABLE)
- register PRUint32 tmp;
-#endif
-
-#if !defined(SHA_PUT_W_IN_STACK)
-#define XH(n) X[n-H2X]
-#define XW(n) X[n-W2X]
-#else
- SHA_HW_t w_0, w_1, w_2, w_3, w_4, w_5, w_6, w_7,
- w_8, w_9, w_10, w_11, w_12, w_13, w_14, w_15;
-#define XW(n) w_ ## n
-#define XH(n) X[n]
-#endif
-
-#define K0 0x5a827999L
-#define K1 0x6ed9eba1L
-#define K2 0x8f1bbcdcL
-#define K3 0xca62c1d6L
-
-#define SHA_RND1(a,b,c,d,e,n) \
- a = SHA_ROTL(b,5)+SHA_F1(c,d,e)+a+XW(n)+K0; c=SHA_ROTL(c,30)
-#define SHA_RND2(a,b,c,d,e,n) \
- a = SHA_ROTL(b,5)+SHA_F2(c,d,e)+a+XW(n)+K1; c=SHA_ROTL(c,30)
-#define SHA_RND3(a,b,c,d,e,n) \
- a = SHA_ROTL(b,5)+SHA_F3(c,d,e)+a+XW(n)+K2; c=SHA_ROTL(c,30)
-#define SHA_RND4(a,b,c,d,e,n) \
- a = SHA_ROTL(b,5)+SHA_F4(c,d,e)+a+XW(n)+K3; c=SHA_ROTL(c,30)
-
-#define LOAD(n) XW(n) = SHA_HTONL(inbuf[n])
-
- A = XH(0);
- B = XH(1);
- C = XH(2);
- D = XH(3);
- E = XH(4);
-
- LOAD(0); SHA_RND1(E,A,B,C,D, 0);
- LOAD(1); SHA_RND1(D,E,A,B,C, 1);
- LOAD(2); SHA_RND1(C,D,E,A,B, 2);
- LOAD(3); SHA_RND1(B,C,D,E,A, 3);
- LOAD(4); SHA_RND1(A,B,C,D,E, 4);
- LOAD(5); SHA_RND1(E,A,B,C,D, 5);
- LOAD(6); SHA_RND1(D,E,A,B,C, 6);
- LOAD(7); SHA_RND1(C,D,E,A,B, 7);
- LOAD(8); SHA_RND1(B,C,D,E,A, 8);
- LOAD(9); SHA_RND1(A,B,C,D,E, 9);
- LOAD(10); SHA_RND1(E,A,B,C,D,10);
- LOAD(11); SHA_RND1(D,E,A,B,C,11);
- LOAD(12); SHA_RND1(C,D,E,A,B,12);
- LOAD(13); SHA_RND1(B,C,D,E,A,13);
- LOAD(14); SHA_RND1(A,B,C,D,E,14);
- LOAD(15); SHA_RND1(E,A,B,C,D,15);
-
- SHA_MIX( 0, 13, 8, 2); SHA_RND1(D,E,A,B,C, 0);
- SHA_MIX( 1, 14, 9, 3); SHA_RND1(C,D,E,A,B, 1);
- SHA_MIX( 2, 15, 10, 4); SHA_RND1(B,C,D,E,A, 2);
- SHA_MIX( 3, 0, 11, 5); SHA_RND1(A,B,C,D,E, 3);
-
- SHA_MIX( 4, 1, 12, 6); SHA_RND2(E,A,B,C,D, 4);
- SHA_MIX( 5, 2, 13, 7); SHA_RND2(D,E,A,B,C, 5);
- SHA_MIX( 6, 3, 14, 8); SHA_RND2(C,D,E,A,B, 6);
- SHA_MIX( 7, 4, 15, 9); SHA_RND2(B,C,D,E,A, 7);
- SHA_MIX( 8, 5, 0, 10); SHA_RND2(A,B,C,D,E, 8);
- SHA_MIX( 9, 6, 1, 11); SHA_RND2(E,A,B,C,D, 9);
- SHA_MIX(10, 7, 2, 12); SHA_RND2(D,E,A,B,C,10);
- SHA_MIX(11, 8, 3, 13); SHA_RND2(C,D,E,A,B,11);
- SHA_MIX(12, 9, 4, 14); SHA_RND2(B,C,D,E,A,12);
- SHA_MIX(13, 10, 5, 15); SHA_RND2(A,B,C,D,E,13);
- SHA_MIX(14, 11, 6, 0); SHA_RND2(E,A,B,C,D,14);
- SHA_MIX(15, 12, 7, 1); SHA_RND2(D,E,A,B,C,15);
-
- SHA_MIX( 0, 13, 8, 2); SHA_RND2(C,D,E,A,B, 0);
- SHA_MIX( 1, 14, 9, 3); SHA_RND2(B,C,D,E,A, 1);
- SHA_MIX( 2, 15, 10, 4); SHA_RND2(A,B,C,D,E, 2);
- SHA_MIX( 3, 0, 11, 5); SHA_RND2(E,A,B,C,D, 3);
- SHA_MIX( 4, 1, 12, 6); SHA_RND2(D,E,A,B,C, 4);
- SHA_MIX( 5, 2, 13, 7); SHA_RND2(C,D,E,A,B, 5);
- SHA_MIX( 6, 3, 14, 8); SHA_RND2(B,C,D,E,A, 6);
- SHA_MIX( 7, 4, 15, 9); SHA_RND2(A,B,C,D,E, 7);
-
- SHA_MIX( 8, 5, 0, 10); SHA_RND3(E,A,B,C,D, 8);
- SHA_MIX( 9, 6, 1, 11); SHA_RND3(D,E,A,B,C, 9);
- SHA_MIX(10, 7, 2, 12); SHA_RND3(C,D,E,A,B,10);
- SHA_MIX(11, 8, 3, 13); SHA_RND3(B,C,D,E,A,11);
- SHA_MIX(12, 9, 4, 14); SHA_RND3(A,B,C,D,E,12);
- SHA_MIX(13, 10, 5, 15); SHA_RND3(E,A,B,C,D,13);
- SHA_MIX(14, 11, 6, 0); SHA_RND3(D,E,A,B,C,14);
- SHA_MIX(15, 12, 7, 1); SHA_RND3(C,D,E,A,B,15);
-
- SHA_MIX( 0, 13, 8, 2); SHA_RND3(B,C,D,E,A, 0);
- SHA_MIX( 1, 14, 9, 3); SHA_RND3(A,B,C,D,E, 1);
- SHA_MIX( 2, 15, 10, 4); SHA_RND3(E,A,B,C,D, 2);
- SHA_MIX( 3, 0, 11, 5); SHA_RND3(D,E,A,B,C, 3);
- SHA_MIX( 4, 1, 12, 6); SHA_RND3(C,D,E,A,B, 4);
- SHA_MIX( 5, 2, 13, 7); SHA_RND3(B,C,D,E,A, 5);
- SHA_MIX( 6, 3, 14, 8); SHA_RND3(A,B,C,D,E, 6);
- SHA_MIX( 7, 4, 15, 9); SHA_RND3(E,A,B,C,D, 7);
- SHA_MIX( 8, 5, 0, 10); SHA_RND3(D,E,A,B,C, 8);
- SHA_MIX( 9, 6, 1, 11); SHA_RND3(C,D,E,A,B, 9);
- SHA_MIX(10, 7, 2, 12); SHA_RND3(B,C,D,E,A,10);
- SHA_MIX(11, 8, 3, 13); SHA_RND3(A,B,C,D,E,11);
-
- SHA_MIX(12, 9, 4, 14); SHA_RND4(E,A,B,C,D,12);
- SHA_MIX(13, 10, 5, 15); SHA_RND4(D,E,A,B,C,13);
- SHA_MIX(14, 11, 6, 0); SHA_RND4(C,D,E,A,B,14);
- SHA_MIX(15, 12, 7, 1); SHA_RND4(B,C,D,E,A,15);
-
- SHA_MIX( 0, 13, 8, 2); SHA_RND4(A,B,C,D,E, 0);
- SHA_MIX( 1, 14, 9, 3); SHA_RND4(E,A,B,C,D, 1);
- SHA_MIX( 2, 15, 10, 4); SHA_RND4(D,E,A,B,C, 2);
- SHA_MIX( 3, 0, 11, 5); SHA_RND4(C,D,E,A,B, 3);
- SHA_MIX( 4, 1, 12, 6); SHA_RND4(B,C,D,E,A, 4);
- SHA_MIX( 5, 2, 13, 7); SHA_RND4(A,B,C,D,E, 5);
- SHA_MIX( 6, 3, 14, 8); SHA_RND4(E,A,B,C,D, 6);
- SHA_MIX( 7, 4, 15, 9); SHA_RND4(D,E,A,B,C, 7);
- SHA_MIX( 8, 5, 0, 10); SHA_RND4(C,D,E,A,B, 8);
- SHA_MIX( 9, 6, 1, 11); SHA_RND4(B,C,D,E,A, 9);
- SHA_MIX(10, 7, 2, 12); SHA_RND4(A,B,C,D,E,10);
- SHA_MIX(11, 8, 3, 13); SHA_RND4(E,A,B,C,D,11);
- SHA_MIX(12, 9, 4, 14); SHA_RND4(D,E,A,B,C,12);
- SHA_MIX(13, 10, 5, 15); SHA_RND4(C,D,E,A,B,13);
- SHA_MIX(14, 11, 6, 0); SHA_RND4(B,C,D,E,A,14);
- SHA_MIX(15, 12, 7, 1); SHA_RND4(A,B,C,D,E,15);
-
- XH(0) += A;
- XH(1) += B;
- XH(2) += C;
- XH(3) += D;
- XH(4) += E;
-}
-
-/*************************************************************************
-** Code below this line added to make SHA code support BLAPI interface
-*/
-
-SHA1Context *
-SHA1_NewContext(void)
-{
- SHA1Context *cx;
-
- /* no need to ZNew, SHA1_Begin will init the context */
- cx = PORT_New(SHA1Context);
- return cx;
-}
-
-/* Zero and free the context */
-void
-SHA1_DestroyContext(SHA1Context *cx, PRBool freeit)
-{
- memset(cx, 0, sizeof *cx);
- if (freeit) {
- PORT_Free(cx);
- }
-}
-
-SECStatus
-SHA1_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
-{
- SHA1Context ctx;
- unsigned int outLen;
-
- SHA1_Begin(&ctx);
- SHA1_Update(&ctx, src, src_length);
- SHA1_End(&ctx, dest, &outLen, SHA1_LENGTH);
- memset(&ctx, 0, sizeof ctx);
- return SECSuccess;
-}
-
-/* Hash a null-terminated character string. */
-SECStatus
-SHA1_Hash(unsigned char *dest, const char *src)
-{
- return SHA1_HashBuf(dest, (const unsigned char *)src, PORT_Strlen (src));
-}
-
-/*
- * need to support save/restore state in pkcs11. Stores all the info necessary
- * for a structure into just a stream of bytes.
- */
-unsigned int
-SHA1_FlattenSize(SHA1Context *cx)
-{
- return sizeof(SHA1Context);
-}
-
-SECStatus
-SHA1_Flatten(SHA1Context *cx,unsigned char *space)
-{
- PORT_Memcpy(space,cx, sizeof(SHA1Context));
- return SECSuccess;
-}
-
-SHA1Context *
-SHA1_Resurrect(unsigned char *space,void *arg)
-{
- SHA1Context *cx = SHA1_NewContext();
- if (cx == NULL) return NULL;
-
- PORT_Memcpy(cx,space, sizeof(SHA1Context));
- return cx;
-}
-
-void SHA1_Clone(SHA1Context *dest, SHA1Context *src)
-{
- memcpy(dest, src, sizeof *dest);
-}
-
-void
-SHA1_TraceState(SHA1Context *ctx)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
-}
diff --git a/security/nss/lib/freebl/sha_fast.h b/security/nss/lib/freebl/sha_fast.h
deleted file mode 100644
index 9d47aba42..000000000
--- a/security/nss/lib/freebl/sha_fast.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SHA_FAST_H_
-#define _SHA_FAST_H_
-
-#include "prlong.h"
-
-#define SHA1_INPUT_LEN 64
-
-#if defined(IS_64) && !defined(__sparc)
-typedef PRUint64 SHA_HW_t;
-#define SHA1_USING_64_BIT 1
-#else
-typedef PRUint32 SHA_HW_t;
-#endif
-
-struct SHA1ContextStr {
- union {
- PRUint32 w[16]; /* input buffer */
- PRUint8 b[64];
- } u;
- PRUint64 size; /* count of hashed bytes. */
- SHA_HW_t H[22]; /* 5 state variables, 16 tmp values, 1 extra */
-};
-
-#if defined(_MSC_VER)
-#include <stdlib.h>
-#if defined(IS_LITTLE_ENDIAN)
-#if (_MSC_VER >= 1300)
-#pragma intrinsic(_byteswap_ulong)
-#define SHA_HTONL(x) _byteswap_ulong(x)
-#elif defined(NSS_X86_OR_X64)
-#ifndef FORCEINLINE
-#if (_MSC_VER >= 1200)
-#define FORCEINLINE __forceinline
-#else
-#define FORCEINLINE __inline
-#endif /* _MSC_VER */
-#endif /* !defined FORCEINLINE */
-#define FASTCALL __fastcall
-
-static FORCEINLINE PRUint32 FASTCALL
-swap4b(PRUint32 dwd)
-{
- __asm {
- mov eax,dwd
- bswap eax
- }
-}
-
-#define SHA_HTONL(x) swap4b(x)
-#endif /* NSS_X86_OR_X64 */
-#endif /* IS_LITTLE_ENDIAN */
-
-#pragma intrinsic (_lrotr, _lrotl)
-#define SHA_ROTL(x,n) _lrotl(x,n)
-#define SHA_ROTL_IS_DEFINED 1
-#endif /* _MSC_VER */
-
-#if defined(__GNUC__)
-/* __x86_64__ and __x86_64 are defined by GCC on x86_64 CPUs */
-#if defined( SHA1_USING_64_BIT )
-static __inline__ PRUint64 SHA_ROTL(PRUint64 x, PRUint32 n)
-{
- PRUint32 t = (PRUint32)x;
- return ((t << n) | (t >> (32 - n)));
-}
-#else
-static __inline__ PRUint32 SHA_ROTL(PRUint32 t, PRUint32 n)
-{
- return ((t << n) | (t >> (32 - n)));
-}
-#endif
-#define SHA_ROTL_IS_DEFINED 1
-
-#if defined(NSS_X86_OR_X64)
-static __inline__ PRUint32 swap4b(PRUint32 value)
-{
- __asm__("bswap %0" : "+r" (value));
- return (value);
-}
-#define SHA_HTONL(x) swap4b(x)
-
-#elif defined(__thumb2__) || \
- (!defined(__thumb__) && \
- (defined(__ARM_ARCH_6__) || \
- defined(__ARM_ARCH_6J__) || \
- defined(__ARM_ARCH_6K__) || \
- defined(__ARM_ARCH_6Z__) || \
- defined(__ARM_ARCH_6ZK__) || \
- defined(__ARM_ARCH_6T2__) || \
- defined(__ARM_ARCH_7__) || \
- defined(__ARM_ARCH_7A__) || \
- defined(__ARM_ARCH_7R__)))
-static __inline__ PRUint32 swap4b(PRUint32 value)
-{
- PRUint32 ret;
- __asm__("rev %0, %1" : "=r" (ret) : "r"(value));
- return ret;
-}
-#define SHA_HTONL(x) swap4b(x)
-
-#endif /* x86 family */
-
-#endif /* __GNUC__ */
-
-#if !defined(SHA_ROTL_IS_DEFINED)
-#define SHA_NEED_TMP_VARIABLE 1
-#define SHA_ROTL(X,n) (tmp = (X), ((tmp) << (n)) | ((tmp) >> (32-(n))))
-#endif
-
-#if defined(NSS_X86_OR_X64)
-#define SHA_ALLOW_UNALIGNED_ACCESS 1
-#endif
-
-#if !defined(SHA_HTONL)
-#define SHA_MASK 0x00FF00FF
-#if defined(IS_LITTLE_ENDIAN)
-#undef SHA_NEED_TMP_VARIABLE
-#define SHA_NEED_TMP_VARIABLE 1
-#define SHA_HTONL(x) (tmp = (x), tmp = (tmp << 16) | (tmp >> 16), \
- ((tmp & SHA_MASK) << 8) | ((tmp >> 8) & SHA_MASK))
-#else
-#define SHA_HTONL(x) (x)
-#endif
-#endif
-
-#define SHA_BYTESWAP(x) x = SHA_HTONL(x)
-
-#define SHA_STORE(n) ((PRUint32*)hashout)[n] = SHA_HTONL(ctx->H[n])
-#if defined(SHA_ALLOW_UNALIGNED_ACCESS)
-#define SHA_STORE_RESULT \
- SHA_STORE(0); \
- SHA_STORE(1); \
- SHA_STORE(2); \
- SHA_STORE(3); \
- SHA_STORE(4);
-
-#elif defined(IS_LITTLE_ENDIAN) || defined( SHA1_USING_64_BIT )
-#define SHA_STORE_RESULT \
- if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \
- SHA_STORE(0); \
- SHA_STORE(1); \
- SHA_STORE(2); \
- SHA_STORE(3); \
- SHA_STORE(4); \
- } else { \
- tmpbuf[0] = SHA_HTONL(ctx->H[0]); \
- tmpbuf[1] = SHA_HTONL(ctx->H[1]); \
- tmpbuf[2] = SHA_HTONL(ctx->H[2]); \
- tmpbuf[3] = SHA_HTONL(ctx->H[3]); \
- tmpbuf[4] = SHA_HTONL(ctx->H[4]); \
- memcpy(hashout, tmpbuf, SHA1_LENGTH); \
- }
-
-#else
-#define SHA_STORE_RESULT \
- if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \
- SHA_STORE(0); \
- SHA_STORE(1); \
- SHA_STORE(2); \
- SHA_STORE(3); \
- SHA_STORE(4); \
- } else { \
- memcpy(hashout, ctx->H, SHA1_LENGTH); \
- }
-#endif
-
-#endif /* _SHA_FAST_H_ */
diff --git a/security/nss/lib/freebl/shsign.h b/security/nss/lib/freebl/shsign.h
deleted file mode 100644
index 8caef6d33..000000000
--- a/security/nss/lib/freebl/shsign.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _SHSIGN_H_
-#define _SHSIGN_H_
-
-#define SGN_SUFFIX ".chk"
-#define NSS_SIGN_CHK_MAGIC1 0xf1
-#define NSS_SIGN_CHK_MAGIC2 0xc5
-#define NSS_SIGN_CHK_MAJOR_VERSION 0x01
-#define NSS_SIGN_CHK_MINOR_VERSION 0x02
-
-#endif /* _SHSIGN_H_ */
diff --git a/security/nss/lib/freebl/shvfy.c b/security/nss/lib/freebl/shvfy.c
deleted file mode 100644
index 385837ee8..000000000
--- a/security/nss/lib/freebl/shvfy.c
+++ /dev/null
@@ -1,509 +0,0 @@
-
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "shsign.h"
-#include "prlink.h"
-#include "prio.h"
-#include "blapi.h"
-#include "seccomon.h"
-#include "stdio.h"
-#include "prmem.h"
-#include "hasht.h"
-#include "pqg.h"
-
-/*
- * Most modern version of Linux support a speed optimization scheme where an
- * application called prelink modifies programs and shared libraries to quickly
- * load if they fit into an already designed address space. In short, prelink
- * scans the list of programs and libraries on your system, assigns them a
- * predefined space in the the address space, then provides the fixups to the
- * library.
-
- * The modification of the shared library is correctly detected by the freebl
- * FIPS checksum scheme where we check a signed hash of the library against the
- * library itself.
- *
- * The prelink command itself can reverse the process of modification and
- * output the prestine shared library as it was before prelink made it's
- * changes. If FREEBL_USE_PRELINK is set Freebl uses prelink to output the
- * original copy of the shared library before prelink modified it.
- */
-#ifdef FREEBL_USE_PRELINK
-#ifndef FREELB_PRELINK_COMMAND
-#define FREEBL_PRELINK_COMMAND "/usr/sbin/prelink -u -o -"
-#endif
-#include "private/pprio.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-
-/*
- * This function returns an NSPR PRFileDesc * which the caller can read to
- * obtain the prestine value of the shared library, before any OS related
- * changes to it (usually address fixups).
- *
- * If prelink is installed, this
- * file descriptor is a pipe connecting the output of
- * /usr/sbin/prelink -u -o - {Library}
- * and *pid returns the process id of the prelink child.
- *
- * If prelink is not installed, it returns a normal readonly handle to the
- * library itself and *pid is set to '0'.
- */
-PRFileDesc *
-bl_OpenUnPrelink(const char *shName, int *pid)
-{
- char *command= strdup(FREEBL_PRELINK_COMMAND);
- char *argString = NULL;
- char **argv = NULL;
- char *shNameArg = NULL;
- char *cp;
- pid_t child;
- int argc = 0, argNext = 0;
- struct stat statBuf;
- int pipefd[2] = {-1,-1};
- int ret;
-
- *pid = 0;
-
- /* make sure the prelink command exists first. If not, fall back to
- * just reading the file */
- for (cp = command; *cp ; cp++) {
- if (*cp == ' ') {
- *cp++ = 0;
- argString = cp;
- break;
- }
- }
- memset (&statBuf, 0, sizeof(statBuf));
- /* stat the file, follow the link */
- ret = stat(command, &statBuf);
- if (ret < 0) {
- free(command);
- return PR_Open(shName, PR_RDONLY, 0);
- }
- /* file exits, make sure it's an executable */
- if (!S_ISREG(statBuf.st_mode) ||
- ((statBuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0)) {
- free(command);
- return PR_Open(shName, PR_RDONLY, 0);
- }
-
- /* OK, the prelink command exists and looks correct, use it */
- /* build the arglist while we can still malloc */
- /* count the args if any */
- if (argString && *argString) {
- /* argString may have leading spaces, strip them off*/
- for (cp = argString; *cp && *cp == ' '; cp++);
- argString = cp;
- if (*cp) {
- /* there is at least one arg.. */
- argc = 1;
- }
-
- /* count the rest: Note there is no provision for escaped
- * spaces here */
- for (cp = argString; *cp ; cp++) {
- if (*cp == ' ') {
- while (*cp && *cp == ' ') cp++;
- if (*cp) argc++;
- }
- }
- }
-
- /* add the additional args: argv[0] (command), shName, NULL*/
- argc += 3;
- argv = PORT_NewArray(char *, argc);
- if (argv == NULL) {
- goto loser;
- }
-
- /* fill in the arglist */
- argv[argNext++] = command;
- if (argString && *argString) {
- argv[argNext++] = argString;
- for (cp = argString; *cp; cp++) {
- if (*cp == ' ') {
- *cp++ = 0;
- while (*cp && *cp == ' ') cp++;
- if (*cp) argv[argNext++] = cp;
- }
- }
- }
- /* exec doesn't advertise taking const char **argv, do the paranoid
- * copy */
- shNameArg = strdup(shName);
- if (shNameArg == NULL) {
- goto loser;
- }
- argv[argNext++] = shNameArg;
- argv[argNext++] = 0;
-
- ret = pipe(pipefd);
- if (ret < 0) {
- goto loser;
- }
-
- /* use vfork() so we don't trigger the pthread_at_fork() handlers */
- child = vfork();
- if (child < 0) goto loser;
- if (child == 0) {
- /* set up the file descriptors */
- /* if we need to support BSD, this will need to be an open of
- * /dev/null and dup2(nullFD, 0)*/
- close(0);
- /* associate pipefd[1] with stdout */
- if (pipefd[1] != 1) dup2(pipefd[1], 1);
- close(2);
- close(pipefd[0]);
- /* should probably close the other file descriptors? */
-
-
- execv(command, argv);
- /* avoid at_exit() handlers */
- _exit(1); /* shouldn't reach here except on an error */
- }
- close(pipefd[1]);
- pipefd[1] = -1;
-
- /* this is safe because either vfork() as full fork() semantics, and thus
- * already has it's own address space, or because vfork() has paused
- * the parent util the exec or exit */
- free(command);
- free(shNameArg);
- PORT_Free(argv);
-
- *pid = child;
-
- return PR_ImportPipe(pipefd[0]);
-
-loser:
- if (pipefd[0] != -1) {
- close(pipefd[0]);
- }
- if (pipefd[1] != -1) {
- close(pipefd[1]);
- }
- free(command);
- free(shNameArg);
- PORT_Free(argv);
-
- return NULL;
-}
-
-/*
- * bl_CloseUnPrelink -
- *
- * This closes the file descripter and reaps and children openned and crated by
- * b;_OpenUnprelink. It's primary difference between it and just close is
- * that it calls wait on the pid if one is supplied, preventing zombie children
- * from hanging around.
- */
-void
-bl_CloseUnPrelink( PRFileDesc *file, int pid)
-{
- /* close the file descriptor */
- PR_Close(file);
- /* reap the child */
- if (pid) {
- waitpid(pid, NULL, 0);
- }
-}
-#endif
-
-/* #define DEBUG_SHVERIFY 1 */
-
-static char *
-mkCheckFileName(const char *libName)
-{
- int ln_len = PORT_Strlen(libName);
- char *output = PORT_Alloc(ln_len+sizeof(SGN_SUFFIX));
- int index = ln_len + 1 - sizeof("."SHLIB_SUFFIX);
-
- if ((index > 0) &&
- (PORT_Strncmp(&libName[index],
- "."SHLIB_SUFFIX,sizeof("."SHLIB_SUFFIX)) == 0)) {
- ln_len = index;
- }
- PORT_Memcpy(output,libName,ln_len);
- PORT_Memcpy(&output[ln_len],SGN_SUFFIX,sizeof(SGN_SUFFIX));
- return output;
-}
-
-static int
-decodeInt(unsigned char *buf)
-{
- return (buf[3]) | (buf[2] << 8) | (buf[1] << 16) | (buf[0] << 24);
-}
-
-static SECStatus
-readItem(PRFileDesc *fd, SECItem *item)
-{
- unsigned char buf[4];
- int bytesRead;
-
-
- bytesRead = PR_Read(fd, buf, 4);
- if (bytesRead != 4) {
- return SECFailure;
- }
- item->len = decodeInt(buf);
-
- item->data = PORT_Alloc(item->len);
- if (item->data == NULL) {
- item->len = 0;
- return SECFailure;
- }
- bytesRead = PR_Read(fd, item->data, item->len);
- if (bytesRead != item->len) {
- PORT_Free(item->data);
- item->data = NULL;
- item->len = 0;
- return SECFailure;
- }
- return SECSuccess;
-}
-
-PRBool
-BLAPI_SHVerify(const char *name, PRFuncPtr addr)
-{
- PRBool result = PR_FALSE; /* if anything goes wrong,
- * the signature does not verify */
- /* find our shared library name */
- char *shName = PR_GetLibraryFilePathname(name, addr);
- if (!shName) {
- goto loser;
- }
- result = BLAPI_SHVerifyFile(shName);
-
-loser:
- if (shName != NULL) {
- PR_Free(shName);
- }
-
- return result;
-}
-
-PRBool
-BLAPI_SHVerifyFile(const char *shName)
-{
- char *checkName = NULL;
- PRFileDesc *checkFD = NULL;
- PRFileDesc *shFD = NULL;
- void *hashcx = NULL;
- const SECHashObject *hashObj = NULL;
- SECItem signature = { 0, NULL, 0 };
- SECItem hash;
- int bytesRead, offset;
- SECStatus rv;
- DSAPublicKey key;
- int count;
-#ifdef FREEBL_USE_PRELINK
- int pid = 0;
-#endif
-
- PRBool result = PR_FALSE; /* if anything goes wrong,
- * the signature does not verify */
- unsigned char buf[4096];
- unsigned char hashBuf[HASH_LENGTH_MAX];
-
- PORT_Memset(&key,0,sizeof(key));
- hash.data = hashBuf;
- hash.len = sizeof(hashBuf);
-
- if (!shName) {
- goto loser;
- }
-
- /* figure out the name of our check file */
- checkName = mkCheckFileName(shName);
- if (!checkName) {
- goto loser;
- }
-
- /* open the check File */
- checkFD = PR_Open(checkName, PR_RDONLY, 0);
- if (checkFD == NULL) {
-#ifdef DEBUG_SHVERIFY
- fprintf(stderr, "Failed to open the check file %s: (%d, %d)\n",
- checkName, (int)PR_GetError(), (int)PR_GetOSError());
-#endif /* DEBUG_SHVERIFY */
- goto loser;
- }
-
- /* read and Verify the headerthe header */
- bytesRead = PR_Read(checkFD, buf, 12);
- if (bytesRead != 12) {
- goto loser;
- }
- if ((buf[0] != NSS_SIGN_CHK_MAGIC1) || (buf[1] != NSS_SIGN_CHK_MAGIC2)) {
- goto loser;
- }
- if ((buf[2] != NSS_SIGN_CHK_MAJOR_VERSION) ||
- (buf[3] < NSS_SIGN_CHK_MINOR_VERSION)) {
- goto loser;
- }
-#ifdef notdef
- if (decodeInt(&buf[8]) != CKK_DSA) {
- goto loser;
- }
-#endif
-
- /* seek past any future header extensions */
- offset = decodeInt(&buf[4]);
- PR_Seek(checkFD, offset, PR_SEEK_SET);
-
- /* read the key */
- rv = readItem(checkFD,&key.params.prime);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = readItem(checkFD,&key.params.subPrime);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = readItem(checkFD,&key.params.base);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = readItem(checkFD,&key.publicValue);
- if (rv != SECSuccess) {
- goto loser;
- }
- /* read the siganture */
- rv = readItem(checkFD,&signature);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* done with the check file */
- PR_Close(checkFD);
- checkFD = NULL;
-
- hashObj = HASH_GetRawHashObject(PQG_GetHashType(&key.params));
- if (hashObj == NULL) {
- goto loser;
- }
-
- /* open our library file */
-#ifdef FREEBL_USE_PRELINK
- shFD = bl_OpenUnPrelink(shName,&pid);
-#else
- shFD = PR_Open(shName, PR_RDONLY, 0);
-#endif
- if (shFD == NULL) {
-#ifdef DEBUG_SHVERIFY
- fprintf(stderr, "Failed to open the library file %s: (%d, %d)\n",
- shName, (int)PR_GetError(), (int)PR_GetOSError());
-#endif /* DEBUG_SHVERIFY */
- goto loser;
- }
-
- /* hash our library file with SHA1 */
- hashcx = hashObj->create();
- if (hashcx == NULL) {
- goto loser;
- }
- hashObj->begin(hashcx);
-
- count = 0;
- while ((bytesRead = PR_Read(shFD, buf, sizeof(buf))) > 0) {
- hashObj->update(hashcx, buf, bytesRead);
- count += bytesRead;
- }
-#ifdef FREEBL_USE_PRELINK
- bl_CloseUnPrelink(shFD, pid);
-#else
- PR_Close(shFD);
-#endif
- shFD = NULL;
-
- hashObj->end(hashcx, hash.data, &hash.len, hash.len);
-
-
- /* verify the hash against the check file */
- if (DSA_VerifyDigest(&key, &signature, &hash) == SECSuccess) {
- result = PR_TRUE;
- }
-#ifdef DEBUG_SHVERIFY
- {
- int i,j;
- fprintf(stderr,"File %s: %d bytes\n",shName, count);
- fprintf(stderr," hash: %d bytes\n", hash.len);
-#define STEP 10
- for (i=0; i < hash.len; i += STEP) {
- fprintf(stderr," ");
- for (j=0; j < STEP && (i+j) < hash.len; j++) {
- fprintf(stderr," %02x", hash.data[i+j]);
- }
- fprintf(stderr,"\n");
- }
- fprintf(stderr," signature: %d bytes\n", signature.len);
- for (i=0; i < signature.len; i += STEP) {
- fprintf(stderr," ");
- for (j=0; j < STEP && (i+j) < signature.len; j++) {
- fprintf(stderr," %02x", signature.data[i+j]);
- }
- fprintf(stderr,"\n");
- }
- fprintf(stderr,"Verified : %s\n",result?"TRUE": "FALSE");
- }
-#endif /* DEBUG_SHVERIFY */
-
-
-loser:
- if (checkName != NULL) {
- PORT_Free(checkName);
- }
- if (checkFD != NULL) {
- PR_Close(checkFD);
- }
- if (shFD != NULL) {
- PR_Close(shFD);
- }
- if (hashcx != NULL) {
- if (hashObj) {
- hashObj->destroy(hashcx,PR_TRUE);
- }
- }
- if (signature.data != NULL) {
- PORT_Free(signature.data);
- }
- if (key.params.prime.data != NULL) {
- PORT_Free(key.params.prime.data);
- }
- if (key.params.subPrime.data != NULL) {
- PORT_Free(key.params.subPrime.data);
- }
- if (key.params.base.data != NULL) {
- PORT_Free(key.params.base.data);
- }
- if (key.publicValue.data != NULL) {
- PORT_Free(key.publicValue.data);
- }
-
- return result;
-}
-
-PRBool
-BLAPI_VerifySelf(const char *name)
-{
- if (name == NULL) {
- /*
- * If name is NULL, freebl is statically linked into softoken.
- * softoken will call BLAPI_SHVerify next to verify itself.
- */
- return PR_TRUE;
- }
- return BLAPI_SHVerify(name, (PRFuncPtr) decodeInt);
-}
diff --git a/security/nss/lib/freebl/stubs.c b/security/nss/lib/freebl/stubs.c
deleted file mode 100644
index e57976b30..000000000
--- a/security/nss/lib/freebl/stubs.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Allow freebl and softoken to be loaded without util or NSPR.
- *
- * These symbols are overridden once real NSPR, and libutil are attached.
- */
-#define _GNU_SOURCE 1
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <dlfcn.h>
-#include <prio.h>
-#include <prlink.h>
-#include <prlog.h>
-#include <prthread.h>
-#include <plstr.h>
-#include <prinit.h>
-#include <prlock.h>
-#include <prmem.h>
-#include <prerror.h>
-#include <prmon.h>
-#include <pratom.h>
-#include <prsystem.h>
-#include <prinrval.h>
-#include <prtime.h>
-#include <prcvar.h>
-#include <secasn1.h>
-#include <secoid.h>
-#include <secdig.h>
-#include <secport.h>
-#include <secitem.h>
-#include <blapi.h>
-#include <private/pprio.h>
-
-#define FREEBL_NO_WEAK 1
-
-#define WEAK __attribute__((weak))
-
-#ifdef FREEBL_NO_WEAK
-
-/*
- * This uses function pointers.
- *
- * CONS: A separate function is needed to
- * fill in the function pointers.
- *
- * PROS: it works on all platforms.
- * it allows for dynamically finding nspr and libutil, even once
- * softoken is loaded and running. (NOTE: this may be a problem if
- * we switch between the stubs and real NSPR on the fly. NSPR will
- * do bad things if passed an _FakeArena to free or allocate from).
- */
-#define STUB_DECLARE(ret, fn, args) \
- typedef ret (*type_##fn) args; \
- static type_##fn ptr_##fn = NULL
-
-#define STUB_SAFE_CALL0(fn) \
- if (ptr_##fn) { return ptr_##fn(); }
-#define STUB_SAFE_CALL1(fn,a1) \
- if (ptr_##fn) { return ptr_##fn(a1); }
-#define STUB_SAFE_CALL2(fn,a1,a2) \
- if (ptr_##fn) { return ptr_##fn(a1,a2); }
-#define STUB_SAFE_CALL3(fn,a1,a2,a3) \
- if (ptr_##fn) { return ptr_##fn(a1,a2,a3); }
-#define STUB_SAFE_CALL4(fn,a1,a2,a3,a4) \
- if (ptr_##fn) { return ptr_##fn(a1,a2,a3,a4); }
-#define STUB_SAFE_CALL6(fn,a1,a2,a3,a4,a5,a6) \
- if (ptr_##fn) { return ptr_##fn(a1,a2,a3,a4,a5,a6); }
-
-#define STUB_FETCH_FUNCTION(fn) \
- ptr_##fn = (type_##fn) dlsym(lib,#fn); \
- if (ptr_##fn == NULL) { \
- return SECFailure; \
- }
-
-#else
-/*
- * this uses the loader weak attribute. it works automatically, but once
- * freebl is loaded, the symbols are 'fixed' (later loading of NSPR or
- * libutil will not resolve these symbols.
- */
-
-#define STUB_DECLARE(ret, fn, args) \
- WEAK extern ret fn args
-
-#define STUB_SAFE_CALL0(fn) \
- if (fn) { return fn(); }
-#define STUB_SAFE_CALL1(fn,a1) \
- if (fn) { return fn(a1); }
-#define STUB_SAFE_CALL2(fn,a1,a2) \
- if (fn) { return fn(a1,a2); }
-#define STUB_SAFE_CALL3(fn,a1,a2,a3) \
- if (fn) { return fn(a1,a2,a3); }
-#define STUB_SAFE_CALL4(fn,a1,a2,a3,a4) \
- if (fn) { return fn(a1,a2,a3,a4); }
-#define STUB_SAFE_CALL6(fn,a1,a2,a3,a4,a5,a6) \
- if (fn) { return fn(a1,a2,a3,a4,a5,a6); }
-#endif
-
-
-STUB_DECLARE(void *,PORT_Alloc_Util,(size_t len));
-STUB_DECLARE(void *,PORT_ArenaZAlloc_Util,(PLArenaPool *arena, size_t size));
-STUB_DECLARE(void ,PORT_Free_Util,(void *ptr));
-STUB_DECLARE(void ,PORT_FreeArena_Util,(PLArenaPool *arena, PRBool zero));
-STUB_DECLARE(int,PORT_GetError_Util,(void));
-STUB_DECLARE(PLArenaPool *,PORT_NewArena_Util,(unsigned long chunksize));
-STUB_DECLARE(void,PORT_SetError_Util,(int value));
-STUB_DECLARE(void *,PORT_ZAlloc_Util,(size_t len));
-STUB_DECLARE(void,PORT_ZFree_Util,(void *ptr, size_t len));
-
-STUB_DECLARE(void,PR_Assert,(const char *s, const char *file, PRIntn ln));
-STUB_DECLARE(PRStatus,PR_CallOnce,(PRCallOnceType *once, PRCallOnceFN func));
-STUB_DECLARE(PRStatus,PR_Close,(PRFileDesc *fd));
-STUB_DECLARE(void,PR_DestroyLock,(PRLock *lock));
-STUB_DECLARE(void,PR_DestroyCondVar,(PRCondVar *cvar));
-STUB_DECLARE(void,PR_Free,(void *ptr));
-STUB_DECLARE(char * ,PR_GetLibraryFilePathname,(const char *name,
- PRFuncPtr addr));
-STUB_DECLARE(PRFileDesc *,PR_ImportPipe,(PROsfd osfd));
-STUB_DECLARE(void,PR_Lock,(PRLock *lock));
-STUB_DECLARE(PRCondVar *,PR_NewCondVar,(PRLock *lock));
-STUB_DECLARE(PRLock *,PR_NewLock,(void));
-STUB_DECLARE(PRStatus,PR_NotifyCondVar,(PRCondVar *cvar));
-STUB_DECLARE(PRStatus,PR_NotifyAllCondVar,(PRCondVar *cvar));
-STUB_DECLARE(PRFileDesc *,PR_Open,(const char *name, PRIntn flags,
- PRIntn mode));
-STUB_DECLARE(PRInt32,PR_Read,(PRFileDesc *fd, void *buf, PRInt32 amount));
-STUB_DECLARE(PROffset32,PR_Seek,(PRFileDesc *fd, PROffset32 offset,
- PRSeekWhence whence));
-STUB_DECLARE(PRStatus,PR_Sleep,(PRIntervalTime ticks));
-STUB_DECLARE(PRStatus,PR_Unlock,(PRLock *lock));
-STUB_DECLARE(PRStatus,PR_WaitCondVar,(PRCondVar *cvar,
- PRIntervalTime timeout));
-
-
-STUB_DECLARE(SECItem *,SECITEM_AllocItem_Util,(PRArenaPool *arena,
- SECItem *item,unsigned int len));
-STUB_DECLARE(SECComparison,SECITEM_CompareItem_Util,(const SECItem *a,
- const SECItem *b));
-STUB_DECLARE(SECStatus,SECITEM_CopyItem_Util,(PRArenaPool *arena,
- SECItem *to,const SECItem *from));
-STUB_DECLARE(void,SECITEM_FreeItem_Util,(SECItem *zap, PRBool freeit));
-STUB_DECLARE(void,SECITEM_ZfreeItem_Util,(SECItem *zap, PRBool freeit));
-STUB_DECLARE(int, NSS_SecureMemcmp,(const void *a, const void *b, size_t n));
-
-
-#define PORT_ZNew_stub(type) (type*)PORT_ZAlloc_stub(sizeof(type))
-#define PORT_New_stub(type) (type*)PORT_Alloc_stub(sizeof(type))
-#define PORT_ZNewArray_stub(type, num) \
- (type*) PORT_ZAlloc_stub (sizeof(type)*(num))
-
-
-/*
- * NOTE: in order to support hashing only the memory allocation stubs,
- * the get library name stubs, and the file io stubs are needed (the latter
- * two are for the library verification). The remaining stubs are simply to
- * compile. Attempts to use the library for other operations without NSPR
- * will most likely fail.
- */
-
-
-/* memory */
-extern void *
-PORT_Alloc_stub(size_t len)
-{
- STUB_SAFE_CALL1(PORT_Alloc_Util, len);
- return malloc(len);
-}
-
-extern void
-PORT_Free_stub(void *ptr)
-{
- STUB_SAFE_CALL1(PORT_Free_Util, ptr);
- return free(ptr);
-}
-
-extern void *
-PORT_ZAlloc_stub(size_t len)
-{
- STUB_SAFE_CALL1(PORT_ZAlloc_Util, len);
- void *ptr = malloc(len);
- if (ptr) {
- memset(ptr, 0, len);
- }
- return ptr;
-}
-
-
-extern void
-PORT_ZFree_stub(void *ptr, size_t len)
-{
- STUB_SAFE_CALL2(PORT_ZFree_Util, ptr, len);
- memset(ptr, 0, len);
- return free(ptr);
-}
-
-extern void
-PR_Free_stub(void *ptr)
-{
- STUB_SAFE_CALL1(PR_Free, ptr);
- return free(ptr);
-}
-
-/*
- * arenas
- *
- */
-extern PLArenaPool *
-PORT_NewArena_stub(unsigned long chunksize)
-{
- STUB_SAFE_CALL1(PORT_NewArena_Util, chunksize);
- abort();
- return NULL;
-}
-
-extern void *
-PORT_ArenaZAlloc_stub(PLArenaPool *arena, size_t size)
-{
-
- STUB_SAFE_CALL2(PORT_ArenaZAlloc_Util, arena, size);
- abort();
- return NULL;
-}
-
-extern void
-PORT_FreeArena_stub(PLArenaPool *arena, PRBool zero)
-{
-
- STUB_SAFE_CALL2(PORT_FreeArena_Util, arena, zero);
- abort();
-}
-
-
-/* io */
-extern PRFileDesc *
-PR_Open_stub(const char *name, PRIntn flags, PRIntn mode)
-{
- int *lfd = NULL;
- int fd;
- int lflags = 0;
-
- STUB_SAFE_CALL3(PR_Open, name, flags, mode);
-
- if (flags & PR_RDWR) {
- lflags = O_RDWR;
- } else if (flags & PR_WRONLY) {
- lflags = O_WRONLY;
- } else {
- lflags = O_RDONLY;
- }
-
- if (flags & PR_EXCL)
- lflags |= O_EXCL;
- if (flags & PR_APPEND)
- lflags |= O_APPEND;
- if (flags & PR_TRUNCATE)
- lflags |= O_TRUNC;
-
- fd = open(name, lflags, mode);
- if (fd >= 0) {
- lfd = PORT_New_stub(int);
- if (lfd != NULL) {
- *lfd = fd;
- }
- }
- return (PRFileDesc *)lfd;
-}
-
-extern PRFileDesc *
-PR_ImportPipe_stub(PROsfd fd)
-{
- int *lfd = NULL;
-
- STUB_SAFE_CALL1(PR_ImportPipe, fd);
-
- lfd = PORT_New_stub(int);
- if (lfd != NULL) {
- *lfd = fd;
- }
- return (PRFileDesc *)lfd;
-}
-
-extern PRStatus
-PR_Close_stub(PRFileDesc *fd)
-{
- int *lfd;
- STUB_SAFE_CALL1(PR_Close, fd);
-
- lfd = (int *)fd;
- close(*lfd);
- PORT_Free_stub(lfd);
-
- return PR_SUCCESS;
-}
-
-extern PRInt32
-PR_Read_stub(PRFileDesc *fd, void *buf, PRInt32 amount)
-{
- int *lfd;
- STUB_SAFE_CALL3(PR_Read, fd, buf, amount);
-
- lfd = (int *)fd;
- return read(*lfd, buf, amount);
-}
-
-extern PROffset32
-PR_Seek_stub(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
-{
- int *lfd;
- int lwhence = SEEK_SET;;
- STUB_SAFE_CALL3(PR_Seek, fd, offset, whence);
- lfd = (int *)fd;
- switch (whence) {
- case PR_SEEK_CUR:
- lwhence = SEEK_CUR;
- break;
- case PR_SEEK_END:
- lwhence = SEEK_END;
- break;
- }
-
- return lseek(*lfd, offset, lwhence);
-}
-
-
-/*
- * library
- */
-extern char *
-PR_GetLibraryFilePathname_stub(const char *name, PRFuncPtr addr)
-{
- Dl_info dli;
- char *result;
-
- STUB_SAFE_CALL2(PR_GetLibraryFilePathname, name, addr);
-
- if (dladdr((void *)addr, &dli) == 0) {
- return NULL;
- }
- result = PORT_Alloc_stub(strlen(dli.dli_fname)+1);
- if (result != NULL) {
- strcpy(result, dli.dli_fname);
- }
- return result;
-}
-
-
-#include <errno.h>
-
-/* errors */
-extern int
-PORT_GetError_stub(void)
-{
- STUB_SAFE_CALL0(PORT_GetError_Util);
- return errno;
-}
-
-extern void
-PORT_SetError_stub(int value)
-{
- STUB_SAFE_CALL1(PORT_SetError_Util, value);
- errno = value;
-}
-
-/* misc */
-extern void
-PR_Assert_stub(const char *s, const char *file, PRIntn ln)
-{
- STUB_SAFE_CALL3(PR_Assert, s, file, ln);
- fprintf(stderr, "%s line %d: %s\n", file, ln, s);
- abort();
-}
-
-/* time */
-extern PRStatus
-PR_Sleep_stub(PRIntervalTime ticks)
-{
- STUB_SAFE_CALL1(PR_Sleep, ticks);
- usleep(ticks*1000);
- return PR_SUCCESS;
-}
-
-
-/* locking */
-extern PRLock *
-PR_NewLock_stub(void)
-{
- STUB_SAFE_CALL0(PR_NewLock);
- abort();
- return NULL;
-}
-
-extern PRStatus
-PR_Unlock_stub(PRLock *lock)
-{
- STUB_SAFE_CALL1(PR_Unlock, lock);
- abort();
- return PR_FAILURE;
-}
-
-extern void
-PR_Lock_stub(PRLock *lock)
-{
- STUB_SAFE_CALL1(PR_Lock, lock);
- abort();
- return;
-}
-
-extern void
-PR_DestroyLock_stub(PRLock *lock)
-{
- STUB_SAFE_CALL1(PR_DestroyLock, lock);
- abort();
- return;
-}
-
-extern PRCondVar *
-PR_NewCondVar_stub(PRLock *lock)
-{
- STUB_SAFE_CALL1(PR_NewCondVar, lock);
- abort();
- return NULL;
-}
-
-extern PRStatus
-PR_NotifyCondVar_stub(PRCondVar *cvar)
-{
- STUB_SAFE_CALL1(PR_NotifyCondVar, cvar);
- abort();
- return PR_FAILURE;
-}
-
-extern PRStatus
-PR_NotifyAllCondVar_stub(PRCondVar *cvar)
-{
- STUB_SAFE_CALL1(PR_NotifyAllCondVar, cvar);
- abort();
- return PR_FAILURE;
-}
-
-extern PRStatus
-PR_WaitCondVar_stub(PRCondVar *cvar, PRIntervalTime timeout)
-{
- STUB_SAFE_CALL2(PR_WaitCondVar, cvar, timeout);
- abort();
- return PR_FAILURE;
-}
-
-
-
-extern void
-PR_DestroyCondVar_stub(PRCondVar *cvar)
-{
- STUB_SAFE_CALL1(PR_DestroyCondVar, cvar);
- abort();
- return;
-}
-
-/*
- * NOTE: this presupposes GCC 4.1
- */
-extern PRStatus
-PR_CallOnce_stub(PRCallOnceType *once, PRCallOnceFN func)
-{
- STUB_SAFE_CALL2(PR_CallOnce, once, func);
- abort();
- return PR_FAILURE;
-}
-
-
-/*
- * SECITEMS implement Item Utilities
- */
-extern void
-SECITEM_FreeItem_stub(SECItem *zap, PRBool freeit)
-{
- STUB_SAFE_CALL2(SECITEM_FreeItem_Util, zap, freeit);
- abort();
-}
-
-extern SECItem *
-SECITEM_AllocItem_stub(PRArenaPool *arena, SECItem *item, unsigned int len)
-{
- STUB_SAFE_CALL3(SECITEM_AllocItem_Util, arena, item, len);
- abort();
- return NULL;
-}
-
-extern SECComparison
-SECITEM_CompareItem_stub(const SECItem *a, const SECItem *b)
-{
- STUB_SAFE_CALL2(SECITEM_CompareItem_Util, a, b);
- abort();
- return SECEqual;
-}
-
-extern SECStatus
-SECITEM_CopyItem_stub(PRArenaPool *arena, SECItem *to, const SECItem *from)
-{
- STUB_SAFE_CALL3(SECITEM_CopyItem_Util, arena, to, from);
- abort();
- return SECFailure;
-}
-
-extern void
-SECITEM_ZfreeItem_stub(SECItem *zap, PRBool freeit)
-{
- STUB_SAFE_CALL2(SECITEM_ZfreeItem_Util, zap, freeit);
- abort();
-}
-
-extern int
-NSS_SecureMemcmp_stub(const void *a, const void *b, size_t n)
-{
- STUB_SAFE_CALL3(NSS_SecureMemcmp, a, b, n);
- abort();
-}
-
-#ifdef FREEBL_NO_WEAK
-
-static const char *nsprLibName = SHLIB_PREFIX"nspr4."SHLIB_SUFFIX;
-static const char *nssutilLibName = SHLIB_PREFIX"nssutil3."SHLIB_SUFFIX;
-
-static SECStatus
-freebl_InitNSPR(void *lib)
-{
- STUB_FETCH_FUNCTION(PR_Free);
- STUB_FETCH_FUNCTION(PR_Open);
- STUB_FETCH_FUNCTION(PR_ImportPipe);
- STUB_FETCH_FUNCTION(PR_Close);
- STUB_FETCH_FUNCTION(PR_Read);
- STUB_FETCH_FUNCTION(PR_Seek);
- STUB_FETCH_FUNCTION(PR_GetLibraryFilePathname);
- STUB_FETCH_FUNCTION(PR_Assert);
- STUB_FETCH_FUNCTION(PR_Sleep);
- STUB_FETCH_FUNCTION(PR_CallOnce);
- STUB_FETCH_FUNCTION(PR_NewCondVar);
- STUB_FETCH_FUNCTION(PR_NotifyCondVar);
- STUB_FETCH_FUNCTION(PR_NotifyAllCondVar);
- STUB_FETCH_FUNCTION(PR_WaitCondVar);
- STUB_FETCH_FUNCTION(PR_DestroyCondVar);
- STUB_FETCH_FUNCTION(PR_NewLock);
- STUB_FETCH_FUNCTION(PR_Unlock);
- STUB_FETCH_FUNCTION(PR_Lock);
- STUB_FETCH_FUNCTION(PR_DestroyLock);
- return SECSuccess;
-}
-
-static SECStatus
-freebl_InitNSSUtil(void *lib)
-{
- STUB_FETCH_FUNCTION(PORT_Alloc_Util);
- STUB_FETCH_FUNCTION(PORT_Free_Util);
- STUB_FETCH_FUNCTION(PORT_ZAlloc_Util);
- STUB_FETCH_FUNCTION(PORT_ZFree_Util);
- STUB_FETCH_FUNCTION(PORT_NewArena_Util);
- STUB_FETCH_FUNCTION(PORT_ArenaZAlloc_Util);
- STUB_FETCH_FUNCTION(PORT_FreeArena_Util);
- STUB_FETCH_FUNCTION(PORT_GetError_Util);
- STUB_FETCH_FUNCTION(PORT_SetError_Util);
- STUB_FETCH_FUNCTION(SECITEM_FreeItem_Util);
- STUB_FETCH_FUNCTION(SECITEM_AllocItem_Util);
- STUB_FETCH_FUNCTION(SECITEM_CompareItem_Util);
- STUB_FETCH_FUNCTION(SECITEM_CopyItem_Util);
- STUB_FETCH_FUNCTION(SECITEM_ZfreeItem_Util);
- STUB_FETCH_FUNCTION(NSS_SecureMemcmp);
- return SECSuccess;
-}
-
-/*
- * fetch the library if it's loaded. For NSS it should already be loaded
- */
-#define freebl_getLibrary(libName) \
- dlopen (libName, RTLD_LAZY|RTLD_NOLOAD)
-
-#define freebl_releaseLibrary(lib) \
- if (lib) dlclose(lib)
-
-static void * FREEBLnsprGlobalLib = NULL;
-static void * FREEBLnssutilGlobalLib = NULL;
-
-void __attribute ((destructor)) FREEBL_unload()
-{
- freebl_releaseLibrary(FREEBLnsprGlobalLib);
- freebl_releaseLibrary(FREEBLnssutilGlobalLib);
-}
-#endif
-
-/*
- * load the symbols from the real libraries if available.
- *
- * if force is set, explicitly load the libraries if they are not already
- * loaded. If we could not use the real libraries, return failure.
- */
-extern SECStatus
-FREEBL_InitStubs()
-{
- SECStatus rv = SECSuccess;
-#ifdef FREEBL_NO_WEAK
- void *nspr = NULL;
- void *nssutil = NULL;
-
- /* NSPR should be first */
- if (!FREEBLnsprGlobalLib) {
- nspr = freebl_getLibrary(nsprLibName);
- if (!nspr) {
- return SECFailure;
- }
- rv = freebl_InitNSPR(nspr);
- if (rv != SECSuccess) {
- freebl_releaseLibrary(nspr);
- return rv;
- }
- FREEBLnsprGlobalLib = nspr; /* adopt */
- }
- /* now load NSSUTIL */
- if (!FREEBLnssutilGlobalLib) {
- nssutil= freebl_getLibrary(nssutilLibName);
- if (!nssutil) {
- return SECFailure;
- }
- rv = freebl_InitNSSUtil(nssutil);
- if (rv != SECSuccess) {
- freebl_releaseLibrary(nssutil);
- return rv;
- }
- FREEBLnssutilGlobalLib = nssutil; /* adopt */
- }
-#endif
-
- return rv;
-}
diff --git a/security/nss/lib/freebl/stubs.h b/security/nss/lib/freebl/stubs.h
deleted file mode 100644
index 8f77e0152..000000000
--- a/security/nss/lib/freebl/stubs.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Allow freebl and softoken to be loaded without util or NSPR.
- *
- * These symbols are overridden once real NSPR, and libutil are attached.
- */
-
-#ifndef _STUBS_H
-#define _STUBS_H_ 1
-
-#ifdef _LIBUTIL_H_
-/* must be included before util */
-/*#error stubs.h included too late */
-#define MP_DIGITES(x) "stubs included too late"
-#endif
-
-/* hide libutil rename */
-#define _LIBUTIL_H_ 1
-
-#define PORT_Alloc PORT_Alloc_stub
-#define PORT_ArenaZAlloc PORT_ArenaZAlloc_stub
-#define PORT_Free PORT_Free_stub
-#define PORT_FreeArena PORT_FreeArena_stub
-#define PORT_GetError PORT_GetError_stub
-#define PORT_NewArena PORT_NewArena_stub
-#define PORT_SetError PORT_SetError_stub
-#define PORT_ZAlloc PORT_ZAlloc_stub
-#define PORT_ZFree PORT_ZFree_stub
-
-#define SECITEM_AllocItem SECITEM_AllocItem_stub
-#define SECITEM_CompareItem SECITEM_CompareItem_stub
-#define SECITEM_CopyItem SECITEM_CopyItem_stub
-#define SECITEM_FreeItem SECITEM_FreeItem_stub
-#define SECITEM_ZfreeItem SECITEM_ZfreeItem_stub
-#define NSS_SecureMemcmp NSS_SecureMemcmp_stub
-
-#define PR_Assert PR_Assert_stub
-#define PR_CallOnce PR_CallOnce_stub
-#define PR_Close PR_Close_stub
-#define PR_DestroyCondVar PR_DestroyCondVar_stub
-#define PR_DestroyLock PR_DestroyLock_stub
-#define PR_Free PR_Free_stub
-#define PR_GetLibraryFilePathname PR_GetLibraryFilePathname_stub
-#define PR_ImportPipe PR_ImportPipe_stub
-#define PR_Lock PR_Lock_stub
-#define PR_NewCondVar PR_NewCondVar_stub
-#define PR_NewLock PR_NewLock_stub
-#define PR_NotifyCondVar PR_NotifyCondVar_stub
-#define PR_NotifyAllCondVar PR_NotifyAllCondVar_stub
-#define PR_Open PR_Open_stub
-#define PR_Read PR_Read_stub
-#define PR_Seek PR_Seek_stub
-#define PR_Sleep PR_Sleep_stub
-#define PR_Unlock PR_Unlock_stub
-#define PR_WaitCondVar PR_WaitCondVar_stub
-
-extern int FREEBL_InitStubs(void);
-
-#endif
diff --git a/security/nss/lib/freebl/sysrand.c b/security/nss/lib/freebl/sysrand.c
deleted file mode 100644
index 0dfb081d0..000000000
--- a/security/nss/lib/freebl/sysrand.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "seccomon.h"
-
-static size_t rng_systemFromNoise(unsigned char *dest, size_t maxLen);
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
-#include "unix_rand.c"
-#endif
-#ifdef XP_WIN
-#include "win_rand.c"
-#endif
-#ifdef XP_OS2
-#include "os2_rand.c"
-#endif
-
-/*
- * Normal RNG_SystemRNG() isn't available, use the system noise to collect
- * the required amount of entropy.
- */
-static size_t
-rng_systemFromNoise(unsigned char *dest, size_t maxLen)
-{
- size_t retBytes = maxLen;
-
- while (maxLen) {
- size_t nbytes = RNG_GetNoise(dest, maxLen);
-
- PORT_Assert(nbytes != 0);
-
- dest += nbytes;
- maxLen -= nbytes;
-
- /* some hw op to try to introduce more entropy into the next
- * RNG_GetNoise call */
- rng_systemJitter();
- }
- return retBytes;
-}
-
diff --git a/security/nss/lib/freebl/tlsprfalg.c b/security/nss/lib/freebl/tlsprfalg.c
deleted file mode 100644
index 9fb64ef0b..000000000
--- a/security/nss/lib/freebl/tlsprfalg.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* tlsprfalg.c - TLS Pseudo Random Function (PRF) implementation
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifdef FREEBL_NO_DEPEND
-#include "stubs.h"
-#endif
-
-#include "blapi.h"
-#include "hasht.h"
-#include "alghmac.h"
-
-
-#define PHASH_STATE_MAX_LEN HASH_LENGTH_MAX
-
-/* TLS P_hash function */
-SECStatus
-TLS_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
- SECItem *seed, SECItem *result, PRBool isFIPS)
-{
- unsigned char state[PHASH_STATE_MAX_LEN];
- unsigned char outbuf[PHASH_STATE_MAX_LEN];
- unsigned int state_len = 0, label_len = 0, outbuf_len = 0, chunk_size;
- unsigned int remaining;
- unsigned char *res;
- SECStatus status;
- HMACContext *cx;
- SECStatus rv = SECFailure;
- const SECHashObject *hashObj = HASH_GetRawHashObject(hashType);
-
- PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
- PORT_Assert((seed != NULL) && (seed->data != NULL));
- PORT_Assert((result != NULL) && (result->data != NULL));
-
- remaining = result->len;
- res = result->data;
-
- if (label != NULL)
- label_len = PORT_Strlen(label);
-
- cx = HMAC_Create(hashObj, secret->data, secret->len, isFIPS);
- if (cx == NULL)
- goto loser;
-
- /* initialize the state = A(1) = HMAC_hash(secret, seed) */
- HMAC_Begin(cx);
- HMAC_Update(cx, (unsigned char *)label, label_len);
- HMAC_Update(cx, seed->data, seed->len);
- status = HMAC_Finish(cx, state, &state_len, sizeof(state));
- if (status != SECSuccess)
- goto loser;
-
- /* generate a block at a time until we're done */
- while (remaining > 0) {
-
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- if (label_len)
- HMAC_Update(cx, (unsigned char *)label, label_len);
- HMAC_Update(cx, seed->data, seed->len);
- status = HMAC_Finish(cx, outbuf, &outbuf_len, sizeof(outbuf));
- if (status != SECSuccess)
- goto loser;
-
- /* Update the state = A(i) = HMAC_hash(secret, A(i-1)) */
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- status = HMAC_Finish(cx, state, &state_len, sizeof(state));
- if (status != SECSuccess)
- goto loser;
-
- chunk_size = PR_MIN(outbuf_len, remaining);
- PORT_Memcpy(res, &outbuf, chunk_size);
- res += chunk_size;
- remaining -= chunk_size;
- }
-
- rv = SECSuccess;
-
-loser:
- /* clear out state so it's not left on the stack */
- if (cx)
- HMAC_Destroy(cx, PR_TRUE);
- PORT_Memset(state, 0, sizeof(state));
- PORT_Memset(outbuf, 0, sizeof(outbuf));
- return rv;
-}
-
-SECStatus
-TLS_PRF(const SECItem *secret, const char *label, SECItem *seed,
- SECItem *result, PRBool isFIPS)
-{
- SECStatus rv = SECFailure, status;
- unsigned int i;
- SECItem tmp = { siBuffer, NULL, 0};
- SECItem S1;
- SECItem S2;
-
- PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
- PORT_Assert((seed != NULL) && (seed->data != NULL));
- PORT_Assert((result != NULL) && (result->data != NULL));
-
- S1.type = siBuffer;
- S1.len = (secret->len / 2) + (secret->len & 1);
- S1.data = secret->data;
-
- S2.type = siBuffer;
- S2.len = S1.len;
- S2.data = secret->data + (secret->len - S2.len);
-
- tmp.data = (unsigned char*)PORT_Alloc(result->len);
- if (tmp.data == NULL)
- goto loser;
- tmp.len = result->len;
-
- status = TLS_P_hash(HASH_AlgMD5, &S1, label, seed, result, isFIPS);
- if (status != SECSuccess)
- goto loser;
-
- status = TLS_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp, isFIPS);
- if (status != SECSuccess)
- goto loser;
-
- for (i = 0; i < result->len; i++)
- result->data[i] ^= tmp.data[i];
-
- rv = SECSuccess;
-
-loser:
- if (tmp.data != NULL)
- PORT_ZFree(tmp.data, tmp.len);
- return rv;
-}
-
diff --git a/security/nss/lib/freebl/unix_rand.c b/security/nss/lib/freebl/unix_rand.c
deleted file mode 100644
index 95c2d0595..000000000
--- a/security/nss/lib/freebl/unix_rand.c
+++ /dev/null
@@ -1,1151 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdio.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
-#include <limits.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include "secrng.h"
-#include "secerr.h"
-#include "prerror.h"
-#include "prthread.h"
-#include "prprf.h"
-
-size_t RNG_FileUpdate(const char *fileName, size_t limit);
-
-/*
- * When copying data to the buffer we want the least signicant bytes
- * from the input since those bits are changing the fastest. The address
- * of least significant byte depends upon whether we are running on
- * a big-endian or little-endian machine.
- *
- * Does this mean the least signicant bytes are the most significant
- * to us? :-)
- */
-
-static size_t CopyLowBits(void *dst, size_t dstlen, void *src, size_t srclen)
-{
- union endianness {
- int32 i;
- char c[4];
- } u;
-
- if (srclen <= dstlen) {
- memcpy(dst, src, srclen);
- return srclen;
- }
- u.i = 0x01020304;
- if (u.c[0] == 0x01) {
- /* big-endian case */
- memcpy(dst, (char*)src + (srclen - dstlen), dstlen);
- } else {
- /* little-endian case */
- memcpy(dst, src, dstlen);
- }
- return dstlen;
-}
-
-#ifdef SOLARIS
-
-#include <kstat.h>
-
-static const PRUint32 entropy_buf_len = 4096; /* buffer up to 4 KB */
-
-/* Buffer entropy data, and feed it to the RNG, entropy_buf_len bytes at a time.
- * Returns error if RNG_RandomUpdate fails. Also increments *total_fed
- * by the number of bytes successfully buffered.
- */
-static SECStatus BufferEntropy(char* inbuf, PRUint32 inlen,
- char* entropy_buf, PRUint32* entropy_buffered,
- PRUint32* total_fed)
-{
- PRUint32 tocopy = 0;
- PRUint32 avail = 0;
- SECStatus rv = SECSuccess;
-
- while (inlen) {
- avail = entropy_buf_len - *entropy_buffered;
- if (!avail) {
- /* Buffer is full, time to feed it to the RNG. */
- rv = RNG_RandomUpdate(entropy_buf, entropy_buf_len);
- if (SECSuccess != rv) {
- break;
- }
- *entropy_buffered = 0;
- avail = entropy_buf_len;
- }
- tocopy = PR_MIN(avail, inlen);
- memcpy(entropy_buf + *entropy_buffered, inbuf, tocopy);
- *entropy_buffered += tocopy;
- inlen -= tocopy;
- inbuf += tocopy;
- *total_fed += tocopy;
- }
- return rv;
-}
-
-/* Feed kernel statistics structures and ks_data field to the RNG.
- * Returns status as well as the number of bytes successfully fed to the RNG.
- */
-static SECStatus RNG_kstat(PRUint32* fed)
-{
- kstat_ctl_t* kc = NULL;
- kstat_t* ksp = NULL;
- PRUint32 entropy_buffered = 0;
- char* entropy_buf = NULL;
- SECStatus rv = SECSuccess;
-
- PORT_Assert(fed);
- if (!fed) {
- return SECFailure;
- }
- *fed = 0;
-
- kc = kstat_open();
- PORT_Assert(kc);
- if (!kc) {
- return SECFailure;
- }
- entropy_buf = (char*) PORT_Alloc(entropy_buf_len);
- PORT_Assert(entropy_buf);
- if (entropy_buf) {
- for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
- if (-1 == kstat_read(kc, ksp, NULL)) {
- /* missing data from a single kstat shouldn't be fatal */
- continue;
- }
- rv = BufferEntropy((char*)ksp, sizeof(kstat_t),
- entropy_buf, &entropy_buffered,
- fed);
- if (SECSuccess != rv) {
- break;
- }
-
- if (ksp->ks_data && ksp->ks_data_size>0 && ksp->ks_ndata>0) {
- rv = BufferEntropy((char*)ksp->ks_data, ksp->ks_data_size,
- entropy_buf, &entropy_buffered,
- fed);
- if (SECSuccess != rv) {
- break;
- }
- }
- }
- if (SECSuccess == rv && entropy_buffered) {
- /* Buffer is not empty, time to feed it to the RNG */
- rv = RNG_RandomUpdate(entropy_buf, entropy_buffered);
- }
- PORT_Free(entropy_buf);
- } else {
- rv = SECFailure;
- }
- if (kstat_close(kc)) {
- PORT_Assert(0);
- rv = SECFailure;
- }
- return rv;
-}
-
-#endif
-
-#if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) \
- || defined(NETBSD) || defined(DARWIN) || defined(OPENBSD) \
- || defined(NTO) || defined(__riscos__)
-#include <sys/times.h>
-
-#define getdtablesize() sysconf(_SC_OPEN_MAX)
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- int ticks;
- struct tms buffer;
-
- ticks=times(&buffer);
- return CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
-}
-
-static void
-GiveSystemInfo(void)
-{
- long si;
-
- /*
- * Is this really necessary? Why not use rand48 or something?
- */
- si = sysconf(_SC_CHILD_MAX);
- RNG_RandomUpdate(&si, sizeof(si));
-
- si = sysconf(_SC_STREAM_MAX);
- RNG_RandomUpdate(&si, sizeof(si));
-
- si = sysconf(_SC_OPEN_MAX);
- RNG_RandomUpdate(&si, sizeof(si));
-}
-#endif
-
-#if defined(__sun)
-#if defined(__svr4) || defined(SVR4)
-#include <sys/systeminfo.h>
-
-#define getdtablesize() sysconf(_SC_OPEN_MAX)
-
-static void
-GiveSystemInfo(void)
-{
- int rv;
- char buf[2000];
-
- rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
-}
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- hrtime_t t;
- t = gethrtime();
- if (t) {
- return CopyLowBits(buf, maxbytes, &t, sizeof(t));
- }
- return 0;
-}
-#else /* SunOS (Sun, but not SVR4) */
-
-extern long sysconf(int name);
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- return 0;
-}
-
-static void
-GiveSystemInfo(void)
-{
- long si;
-
- /* This is not very good */
- si = sysconf(_SC_CHILD_MAX);
- RNG_RandomUpdate(&si, sizeof(si));
-}
-#endif
-#endif /* Sun */
-
-#if defined(__hpux)
-#include <sys/unistd.h>
-
-#define getdtablesize() sysconf(_SC_OPEN_MAX)
-
-#if defined(__ia64)
-#include <ia64/sys/inline.h>
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- PRUint64 t;
-
- t = _Asm_mov_from_ar(_AREG44);
- return CopyLowBits(buf, maxbytes, &t, sizeof(t));
-}
-#else
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- extern int ret_cr16();
- int cr16val;
-
- cr16val = ret_cr16();
- return CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val));
-}
-#endif
-
-static void
-GiveSystemInfo(void)
-{
- long si;
-
- /* This is not very good */
- si = sysconf(_AES_OS_VERSION);
- RNG_RandomUpdate(&si, sizeof(si));
- si = sysconf(_SC_CPU_VERSION);
- RNG_RandomUpdate(&si, sizeof(si));
-}
-#endif /* HPUX */
-
-#if defined(OSF1)
-#include <sys/types.h>
-#include <sys/sysinfo.h>
-#include <sys/systeminfo.h>
-#include <c_asm.h>
-
-static void
-GiveSystemInfo(void)
-{
- char buf[BUFSIZ];
- int rv;
- int off = 0;
-
- rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
-}
-
-/*
- * Use the "get the cycle counter" instruction on the alpha.
- * The low 32 bits completely turn over in less than a minute.
- * The high 32 bits are some non-counter gunk that changes sometimes.
- */
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- unsigned long t;
-
- t = asm("rpcc %v0");
- return CopyLowBits(buf, maxbytes, &t, sizeof(t));
-}
-
-#endif /* Alpha */
-
-#if defined(_IBMR2)
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- return 0;
-}
-
-static void
-GiveSystemInfo(void)
-{
- /* XXX haven't found any yet! */
-}
-#endif /* IBM R2 */
-
-#if defined(LINUX)
-#include <sys/sysinfo.h>
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- return 0;
-}
-
-static void
-GiveSystemInfo(void)
-{
-#ifndef NO_SYSINFO
- struct sysinfo si;
- if (sysinfo(&si) == 0) {
- RNG_RandomUpdate(&si, sizeof(si));
- }
-#endif
-}
-#endif /* LINUX */
-
-#if defined(NCR)
-
-#include <sys/utsname.h>
-#include <sys/systeminfo.h>
-
-#define getdtablesize() sysconf(_SC_OPEN_MAX)
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- return 0;
-}
-
-static void
-GiveSystemInfo(void)
-{
- int rv;
- char buf[2000];
-
- rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
-}
-
-#endif /* NCR */
-
-#if defined(sgi)
-#include <fcntl.h>
-#undef PRIVATE
-#include <sys/mman.h>
-#include <sys/syssgi.h>
-#include <sys/immu.h>
-#include <sys/systeminfo.h>
-#include <sys/utsname.h>
-#include <wait.h>
-
-static void
-GiveSystemInfo(void)
-{
- int rv;
- char buf[4096];
-
- rv = syssgi(SGI_SYSID, &buf[0]);
- if (rv > 0) {
- RNG_RandomUpdate(buf, MAXSYSIDSIZE);
- }
-#ifdef SGI_RDUBLK
- rv = syssgi(SGI_RDUBLK, getpid(), &buf[0], sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, sizeof(buf));
- }
-#endif /* SGI_RDUBLK */
- rv = syssgi(SGI_INVENT, SGI_INV_READ, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, sizeof(buf));
- }
- rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
-}
-
-static size_t GetHighResClock(void *buf, size_t maxbuf)
-{
- unsigned phys_addr, raddr, cycleval;
- static volatile unsigned *iotimer_addr = NULL;
- static int tries = 0;
- static int cntr_size;
- int mfd;
- long s0[2];
- struct timeval tv;
-
-#ifndef SGI_CYCLECNTR_SIZE
-#define SGI_CYCLECNTR_SIZE 165 /* Size user needs to use to read CC */
-#endif
-
- if (iotimer_addr == NULL) {
- if (tries++ > 1) {
- /* Don't keep trying if it didn't work */
- return 0;
- }
-
- /*
- ** For SGI machines we can use the cycle counter, if it has one,
- ** to generate some truly random numbers
- */
- phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
- if (phys_addr) {
- int pgsz = getpagesize();
- int pgoffmask = pgsz - 1;
-
- raddr = phys_addr & ~pgoffmask;
- mfd = open("/dev/mmem", O_RDONLY);
- if (mfd < 0) {
- return 0;
- }
- iotimer_addr = (unsigned *)
- mmap(0, pgoffmask, PROT_READ, MAP_PRIVATE, mfd, (int)raddr);
- if (iotimer_addr == (void*)-1) {
- close(mfd);
- iotimer_addr = NULL;
- return 0;
- }
- iotimer_addr = (unsigned*)
- ((__psint_t)iotimer_addr | (phys_addr & pgoffmask));
- /*
- * The file 'mfd' is purposefully not closed.
- */
- cntr_size = syssgi(SGI_CYCLECNTR_SIZE);
- if (cntr_size < 0) {
- struct utsname utsinfo;
-
- /*
- * We must be executing on a 6.0 or earlier system, since the
- * SGI_CYCLECNTR_SIZE call is not supported.
- *
- * The only pre-6.1 platforms with 64-bit counters are
- * IP19 and IP21 (Challenge, PowerChallenge, Onyx).
- */
- uname(&utsinfo);
- if (!strncmp(utsinfo.machine, "IP19", 4) ||
- !strncmp(utsinfo.machine, "IP21", 4))
- cntr_size = 64;
- else
- cntr_size = 32;
- }
- cntr_size /= 8; /* Convert from bits to bytes */
- }
- }
-
- s0[0] = *iotimer_addr;
- if (cntr_size > 4)
- s0[1] = *(iotimer_addr + 1);
- memcpy(buf, (char *)&s0[0], cntr_size);
- return CopyLowBits(buf, maxbuf, &s0, cntr_size);
-}
-#endif
-
-#if defined(sony)
-#include <sys/systeminfo.h>
-
-#define getdtablesize() sysconf(_SC_OPEN_MAX)
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- return 0;
-}
-
-static void
-GiveSystemInfo(void)
-{
- int rv;
- char buf[2000];
-
- rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
-}
-#endif /* sony */
-
-#if defined(sinix)
-#include <sys/systeminfo.h>
-#include <sys/times.h>
-
-int gettimeofday(struct timeval *, struct timezone *);
-int gethostname(char *, int);
-
-#define getdtablesize() sysconf(_SC_OPEN_MAX)
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- int ticks;
- struct tms buffer;
-
- ticks=times(&buffer);
- return CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
-}
-
-static void
-GiveSystemInfo(void)
-{
- int rv;
- char buf[2000];
-
- rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
-}
-#endif /* sinix */
-
-
-#ifdef BEOS
-#include <be/kernel/OS.h>
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- bigtime_t bigtime; /* Actually an int64 */
-
- bigtime = real_time_clock_usecs();
- return CopyLowBits(buf, maxbytes, &bigtime, sizeof(bigtime));
-}
-
-static void
-GiveSystemInfo(void)
-{
- system_info *info = NULL;
- int32 val;
- get_system_info(info);
- if (info) {
- val = info->boot_time;
- RNG_RandomUpdate(&val, sizeof(val));
- val = info->used_pages;
- RNG_RandomUpdate(&val, sizeof(val));
- val = info->used_ports;
- RNG_RandomUpdate(&val, sizeof(val));
- val = info->used_threads;
- RNG_RandomUpdate(&val, sizeof(val));
- val = info->used_teams;
- RNG_RandomUpdate(&val, sizeof(val));
- }
-}
-#endif /* BEOS */
-
-#if defined(nec_ews)
-#include <sys/systeminfo.h>
-
-#define getdtablesize() sysconf(_SC_OPEN_MAX)
-
-static size_t
-GetHighResClock(void *buf, size_t maxbytes)
-{
- return 0;
-}
-
-static void
-GiveSystemInfo(void)
-{
- int rv;
- char buf[2000];
-
- rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
- rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
- if (rv > 0) {
- RNG_RandomUpdate(buf, rv);
- }
-}
-#endif /* nec_ews */
-
-size_t RNG_GetNoise(void *buf, size_t maxbytes)
-{
- struct timeval tv;
- int n = 0;
- int c;
-
- n = GetHighResClock(buf, maxbytes);
- maxbytes -= n;
-
- (void)gettimeofday(&tv, 0);
- c = CopyLowBits((char*)buf+n, maxbytes, &tv.tv_usec, sizeof(tv.tv_usec));
- n += c;
- maxbytes -= c;
- c = CopyLowBits((char*)buf+n, maxbytes, &tv.tv_sec, sizeof(tv.tv_sec));
- n += c;
- return n;
-}
-
-#define SAFE_POPEN_MAXARGS 10 /* must be at least 2 */
-
-/*
- * safe_popen is static to this module and we know what arguments it is
- * called with. Note that this version only supports a single open child
- * process at any time.
- */
-static pid_t safe_popen_pid;
-static struct sigaction oldact;
-
-static FILE *
-safe_popen(char *cmd)
-{
- int p[2], fd, argc;
- pid_t pid;
- char *argv[SAFE_POPEN_MAXARGS + 1];
- FILE *fp;
- static char blank[] = " \t";
- static struct sigaction newact;
-
- if (pipe(p) < 0)
- return 0;
-
- fp = fdopen(p[0], "r");
- if (fp == 0) {
- close(p[0]);
- close(p[1]);
- return 0;
- }
-
- /* Setup signals so that SIGCHLD is ignored as we want to do waitpid */
- newact.sa_handler = SIG_DFL;
- newact.sa_flags = 0;
- sigfillset(&newact.sa_mask);
- sigaction (SIGCHLD, &newact, &oldact);
-
- pid = fork();
- switch (pid) {
- int ndesc;
-
- case -1:
- fclose(fp); /* this closes p[0], the fd associated with fp */
- close(p[1]);
- sigaction (SIGCHLD, &oldact, NULL);
- return 0;
-
- case 0:
- /* dup write-side of pipe to stderr and stdout */
- if (p[1] != 1) dup2(p[1], 1);
- if (p[1] != 2) dup2(p[1], 2);
-
- /*
- * close the other file descriptors, except stdin which we
- * try reassociating with /dev/null, first (bug 174993)
- */
- if (!freopen("/dev/null", "r", stdin))
- close(0);
- ndesc = getdtablesize();
- for (fd = PR_MIN(65536, ndesc); --fd > 2; close(fd));
-
- /* clean up environment in the child process */
- putenv("PATH=/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc");
- putenv("SHELL=/bin/sh");
- putenv("IFS= \t");
-
- /*
- * The caller may have passed us a string that is in text
- * space. It may be illegal to modify the string
- */
- cmd = strdup(cmd);
- /* format argv */
- argv[0] = strtok(cmd, blank);
- argc = 1;
- while ((argv[argc] = strtok(0, blank)) != 0) {
- if (++argc == SAFE_POPEN_MAXARGS) {
- argv[argc] = 0;
- break;
- }
- }
-
- /* and away we go */
- execvp(argv[0], argv);
- exit(127);
- break;
-
- default:
- close(p[1]);
- break;
- }
-
- /* non-zero means there's a cmd running */
- safe_popen_pid = pid;
- return fp;
-}
-
-static int
-safe_pclose(FILE *fp)
-{
- pid_t pid;
- int status = -1, rv;
-
- if ((pid = safe_popen_pid) == 0)
- return -1;
- safe_popen_pid = 0;
-
- fclose(fp);
-
- /* yield the processor so the child gets some time to exit normally */
- PR_Sleep(PR_INTERVAL_NO_WAIT);
-
- /* if the child hasn't exited, kill it -- we're done with its output */
- while ((rv = waitpid(pid, &status, WNOHANG)) == -1 && errno == EINTR)
- ;
- if (rv == 0) {
- kill(pid, SIGKILL);
- while ((rv = waitpid(pid, &status, 0)) == -1 && errno == EINTR)
- ;
- }
-
- /* Reset SIGCHLD signal hander before returning */
- sigaction(SIGCHLD, &oldact, NULL);
-
- return status;
-}
-
-#ifdef DARWIN
-#include <TargetConditionals.h>
-#if !TARGET_OS_IPHONE
-#include <crt_externs.h>
-#endif
-#endif
-
-/* Fork netstat to collect its output by default. Do not unset this unless
- * another source of entropy is available
- */
-#define DO_NETSTAT 1
-
-void RNG_SystemInfoForRNG(void)
-{
- FILE *fp;
- char buf[BUFSIZ];
- size_t bytes;
- const char * const *cp;
- char *randfile;
-#ifdef DARWIN
-#if TARGET_OS_IPHONE
- /* iOS does not expose a way to access environ. */
- char **environ = NULL;
-#else
- char **environ = *_NSGetEnviron();
-#endif
-#else
- extern char **environ;
-#endif
-#ifdef BEOS
- static const char * const files[] = {
- "/boot/var/swap",
- "/boot/var/log/syslog",
- "/boot/var/tmp",
- "/boot/home/config/settings",
- "/boot/home",
- 0
- };
-#else
- static const char * const files[] = {
- "/etc/passwd",
- "/etc/utmp",
- "/tmp",
- "/var/tmp",
- "/usr/tmp",
- 0
- };
-#endif
-
-#if defined(BSDI)
- static char netstat_ni_cmd[] = "netstat -nis";
-#else
- static char netstat_ni_cmd[] = "netstat -ni";
-#endif
-
- GiveSystemInfo();
-
- bytes = RNG_GetNoise(buf, sizeof(buf));
- RNG_RandomUpdate(buf, bytes);
-
- /*
- * Pass the C environment and the addresses of the pointers to the
- * hash function. This makes the random number function depend on the
- * execution environment of the user and on the platform the program
- * is running on.
- */
- if (environ != NULL) {
- cp = (const char * const *) environ;
- while (*cp) {
- RNG_RandomUpdate(*cp, strlen(*cp));
- cp++;
- }
- RNG_RandomUpdate(environ, (char*)cp - (char*)environ);
- }
-
- /* Give in system information */
- if (gethostname(buf, sizeof(buf)) == 0) {
- RNG_RandomUpdate(buf, strlen(buf));
- }
- GiveSystemInfo();
-
- /* grab some data from system's PRNG before any other files. */
- bytes = RNG_FileUpdate("/dev/urandom", SYSTEM_RNG_SEED_COUNT);
-
- /* If the user points us to a random file, pass it through the rng */
- randfile = getenv("NSRANDFILE");
- if ( ( randfile != NULL ) && ( randfile[0] != '\0') ) {
- char *randCountString = getenv("NSRANDCOUNT");
- int randCount = randCountString ? atoi(randCountString) : 0;
- if (randCount != 0) {
- RNG_FileUpdate(randfile, randCount);
- } else {
- RNG_FileForRNG(randfile);
- }
- }
-
- /* pass other files through */
- for (cp = files; *cp; cp++)
- RNG_FileForRNG(*cp);
-
-/*
- * Bug 100447: On BSD/OS 4.2 and 4.3, we have problem calling safe_popen
- * in a pthreads environment. Therefore, we call safe_popen last and on
- * BSD/OS we do not call safe_popen when we succeeded in getting data
- * from /dev/urandom.
- *
- * Bug 174993: On platforms providing /dev/urandom, don't fork netstat
- * either, if data has been gathered successfully.
- */
-
-#if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \
- || defined(OPENBSD) || defined(DARWIN) || defined(LINUX) \
- || defined(HPUX)
- if (bytes)
- return;
-#endif
-
-#ifdef SOLARIS
-
-/*
- * On Solaris, NSS may be initialized automatically from libldap in
- * applications that are unaware of the use of NSS. safe_popen forks, and
- * sometimes creates issues with some applications' pthread_atfork handlers.
- * We always have /dev/urandom on Solaris 9 and above as an entropy source,
- * and for Solaris 8 we have the libkstat interface, so we don't need to
- * fork netstat.
- */
-
-#undef DO_NETSTAT
- if (!bytes) {
- /* On Solaris 8, /dev/urandom isn't available, so we use libkstat. */
- PRUint32 kstat_bytes = 0;
- if (SECSuccess != RNG_kstat(&kstat_bytes)) {
- PORT_Assert(0);
- }
- bytes += kstat_bytes;
- PORT_Assert(bytes);
- }
-#endif
-
-#ifdef DO_NETSTAT
- fp = safe_popen(netstat_ni_cmd);
- if (fp != NULL) {
- while ((bytes = fread(buf, 1, sizeof(buf), fp)) > 0)
- RNG_RandomUpdate(buf, bytes);
- safe_pclose(fp);
- }
-#endif
-
-}
-
-#define TOTAL_FILE_LIMIT 1000000 /* one million */
-
-size_t RNG_FileUpdate(const char *fileName, size_t limit)
-{
- FILE * file;
- size_t bytes;
- size_t fileBytes = 0;
- struct stat stat_buf;
- unsigned char buffer[BUFSIZ];
- static size_t totalFileBytes = 0;
-
- /* suppress valgrind warnings due to holes in struct stat */
- memset(&stat_buf, 0, sizeof(stat_buf));
-
- if (stat((char *)fileName, &stat_buf) < 0)
- return fileBytes;
- RNG_RandomUpdate(&stat_buf, sizeof(stat_buf));
-
- file = fopen((char *)fileName, "r");
- if (file != NULL) {
- while (limit > fileBytes) {
- bytes = PR_MIN(sizeof buffer, limit - fileBytes);
- bytes = fread(buffer, 1, bytes, file);
- if (bytes == 0)
- break;
- RNG_RandomUpdate(buffer, bytes);
- fileBytes += bytes;
- totalFileBytes += bytes;
- /* after TOTAL_FILE_LIMIT has been reached, only read in first
- ** buffer of data from each subsequent file.
- */
- if (totalFileBytes > TOTAL_FILE_LIMIT)
- break;
- }
- fclose(file);
- }
- /*
- * Pass yet another snapshot of our highest resolution clock into
- * the hash function.
- */
- bytes = RNG_GetNoise(buffer, sizeof(buffer));
- RNG_RandomUpdate(buffer, bytes);
- return fileBytes;
-}
-
-void RNG_FileForRNG(const char *fileName)
-{
- RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT);
-}
-
-void ReadSingleFile(const char *fileName)
-{
- FILE * file;
- unsigned char buffer[BUFSIZ];
-
- file = fopen((char *)fileName, "rb");
- if (file != NULL) {
- while (fread(buffer, 1, sizeof(buffer), file) > 0)
- ;
- fclose(file);
- }
-}
-
-#define _POSIX_PTHREAD_SEMANTICS
-#include <dirent.h>
-
-PRBool
-ReadFileOK(char *dir, char *file)
-{
- struct stat stat_buf;
- char filename[PATH_MAX];
- int count = snprintf(filename, sizeof filename, "%s/%s",dir, file);
-
- if (count <= 0) {
- return PR_FALSE; /* name too long, can't read it anyway */
- }
-
- if (stat(filename, &stat_buf) < 0)
- return PR_FALSE; /* can't stat, probably can't read it then as well */
- return S_ISREG(stat_buf.st_mode) ? PR_TRUE : PR_FALSE;
-}
-
-/*
- * read one file out of either /etc or the user's home directory.
- * fileToRead tells which file to read.
- *
- * return 1 if it's time to reset the fileToRead (no more files to read).
- */
-int ReadOneFile(int fileToRead)
-{
- char *dir = "/etc";
- DIR *fd = opendir(dir);
- int resetCount = 0;
-#ifdef SOLARIS
- /* grumble, Solaris does not define struct dirent to be the full length */
- typedef union {
- unsigned char space[sizeof(struct dirent) + MAXNAMELEN];
- struct dirent dir;
- } dirent_hack;
- dirent_hack entry, firstEntry;
-
-#define entry_dir entry.dir
-#else
- struct dirent entry, firstEntry;
-#define entry_dir entry
-#endif
-
- int i, error = -1;
-
- if (fd == NULL) {
- dir = getenv("HOME");
- if (dir) {
- fd = opendir(dir);
- }
- }
- if (fd == NULL) {
- return 1;
- }
-
- for (i=0; i <= fileToRead; i++) {
- struct dirent *result = NULL;
- do {
- error = readdir_r(fd, &entry_dir, &result);
- } while (error == 0 && result != NULL &&
- !ReadFileOK(dir,&result->d_name[0]));
- if (error != 0 || result == NULL) {
- resetCount = 1; /* read to the end, start again at the beginning */
- if (i != 0) {
- /* ran out of entries in the directory, use the first one */
- entry = firstEntry;
- error = 0;
- break;
- }
- /* if i== 0, there were no readable entries in the directory */
- break;
- }
- if (i==0) {
- /* save the first entry in case we run out of entries */
- firstEntry = entry;
- }
- }
-
- if (error == 0) {
- char filename[PATH_MAX];
- int count = snprintf(filename, sizeof filename,
- "%s/%s",dir, &entry_dir.d_name[0]);
- if (count >= 1) {
- ReadSingleFile(filename);
- }
- }
-
- closedir(fd);
- return resetCount;
-}
-
-/*
- * do something to try to introduce more noise into the 'GetNoise' call
- */
-static void rng_systemJitter(void)
-{
- static int fileToRead = 1;
-
- if (ReadOneFile(fileToRead)) {
- fileToRead = 1;
- } else {
- fileToRead++;
- }
-}
-
-size_t RNG_SystemRNG(void *dest, size_t maxLen)
-{
- FILE *file;
- size_t bytes;
- size_t fileBytes = 0;
- unsigned char *buffer = dest;
-
- file = fopen("/dev/urandom", "r");
- if (file == NULL) {
- return rng_systemFromNoise(dest, maxLen);
- }
- while (maxLen > fileBytes) {
- bytes = maxLen - fileBytes;
- bytes = fread(buffer, 1, bytes, file);
- if (bytes == 0)
- break;
- fileBytes += bytes;
- buffer += bytes;
- }
- fclose(file);
- if (fileBytes != maxLen) {
- PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */
- fileBytes = 0;
- }
- return fileBytes;
-}
diff --git a/security/nss/lib/freebl/win_rand.c b/security/nss/lib/freebl/win_rand.c
deleted file mode 100644
index 0100ac446..000000000
--- a/security/nss/lib/freebl/win_rand.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secrng.h"
-#include "secerr.h"
-
-#ifdef XP_WIN
-#include <windows.h>
-#include <shlobj.h> /* for CSIDL constants */
-#include <time.h>
-#include <io.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include "prio.h"
-#include "prerror.h"
-
-static PRInt32 filesToRead;
-static DWORD totalFileBytes;
-static DWORD maxFileBytes = 250000; /* 250 thousand */
-static DWORD dwNumFiles, dwReadEvery, dwFileToRead;
-static PRBool usedWindowsPRNG;
-
-static BOOL
-CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow)
-{
- LARGE_INTEGER liCount;
-
- if (!QueryPerformanceCounter(&liCount))
- return FALSE;
-
- *lpdwHigh = liCount.u.HighPart;
- *lpdwLow = liCount.u.LowPart;
- return TRUE;
-}
-
-size_t RNG_GetNoise(void *buf, size_t maxbuf)
-{
- DWORD dwHigh, dwLow, dwVal;
- int n = 0;
- int nBytes;
- time_t sTime;
-
- if (maxbuf <= 0)
- return 0;
-
- CurrentClockTickTime(&dwHigh, &dwLow);
-
- // get the maximally changing bits first
- nBytes = sizeof(dwLow) > maxbuf ? maxbuf : sizeof(dwLow);
- memcpy((char *)buf, &dwLow, nBytes);
- n += nBytes;
- maxbuf -= nBytes;
-
- if (maxbuf <= 0)
- return n;
-
- nBytes = sizeof(dwHigh) > maxbuf ? maxbuf : sizeof(dwHigh);
- memcpy(((char *)buf) + n, &dwHigh, nBytes);
- n += nBytes;
- maxbuf -= nBytes;
-
- if (maxbuf <= 0)
- return n;
-
- // get the number of milliseconds that have elapsed since Windows started
- dwVal = GetTickCount();
-
- nBytes = sizeof(dwVal) > maxbuf ? maxbuf : sizeof(dwVal);
- memcpy(((char *)buf) + n, &dwVal, nBytes);
- n += nBytes;
- maxbuf -= nBytes;
-
- if (maxbuf <= 0)
- return n;
-
- // get the time in seconds since midnight Jan 1, 1970
- time(&sTime);
- nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime);
- memcpy(((char *)buf) + n, &sTime, nBytes);
- n += nBytes;
-
- return n;
-}
-
-typedef PRInt32 (* Handler)(const PRUnichar *);
-#define MAX_DEPTH 2
-#define MAX_FOLDERS 4
-#define MAX_FILES 1024
-
-static void
-EnumSystemFilesInFolder(Handler func, PRUnichar* szSysDir, int maxDepth)
-{
- int iContinue;
- unsigned int uFolders = 0;
- unsigned int uFiles = 0;
- HANDLE lFindHandle;
- WIN32_FIND_DATAW fdData;
- PRUnichar szFileName[_MAX_PATH];
-
- if (maxDepth < 0)
- return;
- // append *.* so we actually look for files.
- _snwprintf(szFileName, _MAX_PATH, L"%s\\*.*", szSysDir);
- szFileName[_MAX_PATH - 1] = L'\0';
-
- lFindHandle = FindFirstFileW(szFileName, &fdData);
- if (lFindHandle == INVALID_HANDLE_VALUE)
- return;
- do {
- iContinue = 1;
- if (wcscmp(fdData.cFileName, L".") == 0 ||
- wcscmp(fdData.cFileName, L"..") == 0) {
- // skip "." and ".."
- } else {
- // pass the full pathname to the callback
- _snwprintf(szFileName, _MAX_PATH, L"%s\\%s", szSysDir,
- fdData.cFileName);
- szFileName[_MAX_PATH - 1] = L'\0';
- if (fdData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- if (++uFolders <= MAX_FOLDERS)
- EnumSystemFilesInFolder(func, szFileName, maxDepth - 1);
- } else {
- iContinue = (++uFiles <= MAX_FILES) && !(*func)(szFileName);
- }
- }
- if (iContinue)
- iContinue = FindNextFileW(lFindHandle, &fdData);
- } while (iContinue);
- FindClose(lFindHandle);
-}
-
-static BOOL
-EnumSystemFiles(Handler func)
-{
- PRUnichar szSysDir[_MAX_PATH];
- static const int folders[] = {
- CSIDL_BITBUCKET,
- CSIDL_RECENT,
- CSIDL_INTERNET_CACHE,
- CSIDL_HISTORY,
- 0
- };
- int i = 0;
- if (_MAX_PATH > (i = GetTempPathW(_MAX_PATH, szSysDir))) {
- if (i > 0 && szSysDir[i-1] == L'\\')
- szSysDir[i-1] = L'\0'; // we need to lop off the trailing slash
- EnumSystemFilesInFolder(func, szSysDir, MAX_DEPTH);
- }
- for(i = 0; folders[i]; i++) {
- DWORD rv = SHGetSpecialFolderPathW(NULL, szSysDir, folders[i], 0);
- if (szSysDir[0])
- EnumSystemFilesInFolder(func, szSysDir, MAX_DEPTH);
- szSysDir[0] = L'\0';
- }
- return PR_TRUE;
-}
-
-static PRInt32
-CountFiles(const PRUnichar *file)
-{
- dwNumFiles++;
- return 0;
-}
-
-static int
-ReadSingleFile(const char *filename)
-{
- PRFileDesc * file;
- unsigned char buffer[1024];
-
- file = PR_Open(filename, PR_RDONLY, 0);
- if (file != NULL) {
- while (PR_Read(file, buffer, sizeof buffer) > 0)
- ;
- PR_Close(file);
- }
- return (file != NULL);
-}
-
-static PRInt32
-ReadOneFile(const PRUnichar *szFileName)
-{
- char narrowFileName[_MAX_PATH];
-
- if (dwNumFiles == dwFileToRead) {
- int success = WideCharToMultiByte(CP_ACP, 0, szFileName, -1,
- narrowFileName, _MAX_PATH,
- NULL, NULL);
- if (success)
- success = ReadSingleFile(narrowFileName);
- if (!success)
- dwFileToRead++; /* couldn't read this one, read the next one. */
- }
- dwNumFiles++;
- return dwNumFiles > dwFileToRead;
-}
-
-static PRInt32
-ReadFiles(const PRUnichar *szFileName)
-{
- char narrowFileName[_MAX_PATH];
-
- if ((dwNumFiles % dwReadEvery) == 0) {
- ++filesToRead;
- }
- if (filesToRead) {
- DWORD prevFileBytes = totalFileBytes;
- int iContinue = WideCharToMultiByte(CP_ACP, 0, szFileName, -1,
- narrowFileName, _MAX_PATH,
- NULL, NULL);
- if (iContinue) {
- RNG_FileForRNG(narrowFileName);
- }
- if (prevFileBytes < totalFileBytes) {
- --filesToRead;
- }
- }
- dwNumFiles++;
- return (totalFileBytes >= maxFileBytes);
-}
-
-static void
-ReadSystemFiles(void)
-{
- // first count the number of files
- dwNumFiles = 0;
- if (!EnumSystemFiles(CountFiles))
- return;
-
- RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles));
-
- // now read the first 10 readable files, then 10 or 11 files
- // spread throughout the system directory
- filesToRead = 10;
- if (dwNumFiles == 0)
- return;
-
- dwReadEvery = dwNumFiles / 10;
- if (dwReadEvery == 0)
- dwReadEvery = 1; // less than 10 files
-
- dwNumFiles = 0;
- totalFileBytes = 0;
- EnumSystemFiles(ReadFiles);
-}
-
-void RNG_SystemInfoForRNG(void)
-{
- DWORD dwVal;
- char buffer[256];
- int nBytes;
- MEMORYSTATUS sMem;
- HANDLE hVal;
- DWORD dwSerialNum;
- DWORD dwComponentLen;
- DWORD dwSysFlags;
- char volName[128];
- DWORD dwSectors, dwBytes, dwFreeClusters, dwNumClusters;
-
- nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
- RNG_RandomUpdate(buffer, nBytes);
-
- sMem.dwLength = sizeof(sMem);
- GlobalMemoryStatus(&sMem); // assorted memory stats
- RNG_RandomUpdate(&sMem, sizeof(sMem));
-
- dwVal = GetLogicalDrives();
- RNG_RandomUpdate(&dwVal, sizeof(dwVal)); // bitfields in bits 0-25
-
- dwVal = sizeof(buffer);
- if (GetComputerName(buffer, &dwVal))
- RNG_RandomUpdate(buffer, dwVal);
-
- hVal = GetCurrentProcess(); // 4 or 8 byte pseudo handle (a
- // constant!) of current process
- RNG_RandomUpdate(&hVal, sizeof(hVal));
-
- dwVal = GetCurrentProcessId(); // process ID (4 bytes)
- RNG_RandomUpdate(&dwVal, sizeof(dwVal));
-
- dwVal = GetCurrentThreadId(); // thread ID (4 bytes)
- RNG_RandomUpdate(&dwVal, sizeof(dwVal));
-
- volName[0] = '\0';
- buffer[0] = '\0';
- GetVolumeInformation(NULL,
- volName,
- sizeof(volName),
- &dwSerialNum,
- &dwComponentLen,
- &dwSysFlags,
- buffer,
- sizeof(buffer));
-
- RNG_RandomUpdate(volName, strlen(volName));
- RNG_RandomUpdate(&dwSerialNum, sizeof(dwSerialNum));
- RNG_RandomUpdate(&dwComponentLen, sizeof(dwComponentLen));
- RNG_RandomUpdate(&dwSysFlags, sizeof(dwSysFlags));
- RNG_RandomUpdate(buffer, strlen(buffer));
-
- if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters,
- &dwNumClusters)) {
- RNG_RandomUpdate(&dwSectors, sizeof(dwSectors));
- RNG_RandomUpdate(&dwBytes, sizeof(dwBytes));
- RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters));
- RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters));
- }
-
- // Skip the potentially slow file scanning if the OS's PRNG worked.
- if (!usedWindowsPRNG)
- ReadSystemFiles();
-
- nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
- RNG_RandomUpdate(buffer, nBytes);
-}
-
-static void rng_systemJitter(void)
-{
- dwNumFiles = 0;
- EnumSystemFiles(ReadOneFile);
- dwFileToRead++;
- if (dwFileToRead >= dwNumFiles) {
- dwFileToRead = 0;
- }
-}
-
-
-void RNG_FileForRNG(const char *filename)
-{
- FILE* file;
- int nBytes;
- struct stat stat_buf;
- unsigned char buffer[1024];
-
- /* windows doesn't initialize all the bytes in the stat buf,
- * so initialize them all here to avoid UMRs.
- */
- memset(&stat_buf, 0, sizeof stat_buf);
-
- if (stat((char *)filename, &stat_buf) < 0)
- return;
-
- RNG_RandomUpdate((unsigned char*)&stat_buf, sizeof(stat_buf));
-
- file = fopen((char *)filename, "r");
- if (file != NULL) {
- for (;;) {
- size_t bytes = fread(buffer, 1, sizeof(buffer), file);
-
- if (bytes == 0)
- break;
-
- RNG_RandomUpdate(buffer, bytes);
- totalFileBytes += bytes;
- if (totalFileBytes > maxFileBytes)
- break;
- }
-
- fclose(file);
- }
-
- nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
- RNG_RandomUpdate(buffer, nBytes);
-}
-
-
-/*
- * CryptoAPI requires Windows NT 4.0 or Windows 95 OSR2 and later.
- * Until we drop support for Windows 95, we need to emulate some
- * definitions and declarations in <wincrypt.h> and look up the
- * functions in advapi32.dll at run time.
- */
-
-#ifndef WIN64
-typedef unsigned long HCRYPTPROV;
-#endif
-
-#define CRYPT_VERIFYCONTEXT 0xF0000000
-
-#define PROV_RSA_FULL 1
-
-typedef BOOL
-(WINAPI *CryptAcquireContextAFn)(
- HCRYPTPROV *phProv,
- LPCSTR pszContainer,
- LPCSTR pszProvider,
- DWORD dwProvType,
- DWORD dwFlags);
-
-typedef BOOL
-(WINAPI *CryptReleaseContextFn)(
- HCRYPTPROV hProv,
- DWORD dwFlags);
-
-typedef BOOL
-(WINAPI *CryptGenRandomFn)(
- HCRYPTPROV hProv,
- DWORD dwLen,
- BYTE *pbBuffer);
-
-/*
- * Windows XP and Windows Server 2003 and later have RtlGenRandom,
- * which must be looked up by the name SystemFunction036.
- */
-typedef BOOLEAN
-(APIENTRY *RtlGenRandomFn)(
- PVOID RandomBuffer,
- ULONG RandomBufferLength);
-
-size_t RNG_SystemRNG(void *dest, size_t maxLen)
-{
- HMODULE hModule;
- RtlGenRandomFn pRtlGenRandom;
- CryptAcquireContextAFn pCryptAcquireContextA;
- CryptReleaseContextFn pCryptReleaseContext;
- CryptGenRandomFn pCryptGenRandom;
- HCRYPTPROV hCryptProv;
- size_t bytes = 0;
-
- usedWindowsPRNG = PR_FALSE;
- hModule = LoadLibrary("advapi32.dll");
- if (hModule == NULL) {
- return rng_systemFromNoise(dest,maxLen);
- }
- pRtlGenRandom = (RtlGenRandomFn)
- GetProcAddress(hModule, "SystemFunction036");
- if (pRtlGenRandom) {
- if (pRtlGenRandom(dest, maxLen)) {
- bytes = maxLen;
- usedWindowsPRNG = PR_TRUE;
- } else {
- bytes = rng_systemFromNoise(dest,maxLen);
- }
- goto done;
- }
- pCryptAcquireContextA = (CryptAcquireContextAFn)
- GetProcAddress(hModule, "CryptAcquireContextA");
- pCryptReleaseContext = (CryptReleaseContextFn)
- GetProcAddress(hModule, "CryptReleaseContext");
- pCryptGenRandom = (CryptGenRandomFn)
- GetProcAddress(hModule, "CryptGenRandom");
- if (!pCryptAcquireContextA || !pCryptReleaseContext || !pCryptGenRandom) {
- bytes = rng_systemFromNoise(dest,maxLen);
- goto done;
- }
- if (pCryptAcquireContextA(&hCryptProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
- if (pCryptGenRandom(hCryptProv, maxLen, dest)) {
- bytes = maxLen;
- usedWindowsPRNG = PR_TRUE;
- }
- pCryptReleaseContext(hCryptProv, 0);
- }
- if (bytes == 0) {
- bytes = rng_systemFromNoise(dest,maxLen);
- }
-done:
- FreeLibrary(hModule);
- return bytes;
-}
-#endif /* is XP_WIN */
diff --git a/security/nss/lib/jar/Makefile b/security/nss/lib/jar/Makefile
deleted file mode 100644
index 245c127a4..000000000
--- a/security/nss/lib/jar/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
-include $(CORE_DEPTH)/coreconf/rules.mk
-
diff --git a/security/nss/lib/jar/config.mk b/security/nss/lib/jar/config.mk
deleted file mode 100644
index 1412dcc59..000000000
--- a/security/nss/lib/jar/config.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
-# NSS_X86 means the target is a 32-bits x86 CPU architecture
-# NSS_X64 means the target is a 64-bits x64 CPU architecture
-# NSS_X86_OR_X64 means the target is either x86 or x64
-ifeq (,$(filter-out i386 x386 x86 x86_64,$(CPU_ARCH)))
- DEFINES += -DNSS_X86_OR_X64
-ifdef USE_64
- DEFINES += -DNSS_X64
-else
- DEFINES += -DNSS_X86
-endif
-endif
diff --git a/security/nss/lib/jar/jar-ds.c b/security/nss/lib/jar/jar-ds.c
deleted file mode 100644
index 0d787baa6..000000000
--- a/security/nss/lib/jar/jar-ds.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "jar.h"
-
-/* These are old DS_* routines renamed to ZZ_* */
-ZZList *
-ZZ_NewList(void)
-{
- ZZList *list = (ZZList *) PORT_ZAlloc (sizeof (ZZList));
- if (list)
- ZZ_InitList (list);
- return list;
-}
-
-ZZLink *
-ZZ_NewLink(JAR_Item *thing)
-{
- ZZLink *link = (ZZLink *) PORT_ZAlloc (sizeof (ZZLink));
- if (link)
- link->thing = thing;
- return link;
-}
-
-void
-ZZ_DestroyLink(ZZLink *link)
-{
- PORT_Free(link);
-}
-
-void
-ZZ_DestroyList (ZZList *list)
-{
- PORT_Free(list);
-}
diff --git a/security/nss/lib/jar/jar-ds.h b/security/nss/lib/jar/jar-ds.h
deleted file mode 100644
index dd212e47b..000000000
--- a/security/nss/lib/jar/jar-ds.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __JAR_DS_h_
-#define __JAR_DS_h_
-
-/* Typedefs */
-typedef struct ZZLinkStr ZZLink;
-typedef struct ZZListStr ZZList;
-
-/*
-** Circular linked list. Each link contains a pointer to the object that
-** is actually in the list.
-*/
-struct ZZLinkStr {
- ZZLink *next;
- ZZLink *prev;
- JAR_Item *thing;
-};
-
-struct ZZListStr {
- ZZLink link;
-};
-
-#define ZZ_InitList(lst) \
-{ \
- (lst)->link.next = &(lst)->link; \
- (lst)->link.prev = &(lst)->link; \
- (lst)->link.thing = 0; \
-}
-
-#define ZZ_ListEmpty(lst) ((lst)->link.next == &(lst)->link)
-
-#define ZZ_ListHead(lst) ((lst)->link.next)
-
-#define ZZ_ListTail(lst) ((lst)->link.prev)
-
-#define ZZ_ListIterDone(lst,lnk) ((lnk) == &(lst)->link)
-
-#define ZZ_AppendLink(lst,lnk) \
-{ \
- (lnk)->next = &(lst)->link; \
- (lnk)->prev = (lst)->link.prev; \
- (lst)->link.prev->next = (lnk); \
- (lst)->link.prev = (lnk); \
-}
-
-#define ZZ_InsertLink(lst,lnk) \
-{ \
- (lnk)->next = (lst)->link.next; \
- (lnk)->prev = &(lst)->link; \
- (lst)->link.next->prev = (lnk); \
- (lst)->link.next = (lnk); \
-}
-
-#define ZZ_RemoveLink(lnk) \
-{ \
- (lnk)->next->prev = (lnk)->prev; \
- (lnk)->prev->next = (lnk)->next; \
- (lnk)->next = 0; \
- (lnk)->prev = 0; \
-}
-
-extern ZZLink *
-ZZ_NewLink(JAR_Item *thing);
-
-extern void
-ZZ_DestroyLink(ZZLink *link);
-
-extern ZZList *
-ZZ_NewList(void);
-
-extern void
-ZZ_DestroyList(ZZList *list);
-
-
-#endif /* __JAR_DS_h_ */
diff --git a/security/nss/lib/jar/jar.c b/security/nss/lib/jar/jar.c
deleted file mode 100644
index d7aadbbeb..000000000
--- a/security/nss/lib/jar/jar.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * JAR.C
- *
- * Jarnature.
- * Routines common to signing and validating.
- *
- */
-
-#include "jar.h"
-#include "jarint.h"
-#include "portreg.h"
-
-static void
-jar_destroy_list (ZZList *list);
-
-static int
-jar_find_first_cert(JAR_Signer *signer, int type, JAR_Item **it);
-
-/*
- * J A R _ n e w
- *
- * Create a new instantiation of a manifest representation.
- * Use this as a token to any calls to this API.
- *
- */
-JAR *
-JAR_new(void)
-{
- JAR *jar;
-
- if ((jar = (JAR*)PORT_ZAlloc (sizeof (JAR))) == NULL)
- goto loser;
- if ((jar->manifest = ZZ_NewList()) == NULL)
- goto loser;
- if ((jar->hashes = ZZ_NewList()) == NULL)
- goto loser;
- if ((jar->phy = ZZ_NewList()) == NULL)
- goto loser;
- if ((jar->metainfo = ZZ_NewList()) == NULL)
- goto loser;
- if ((jar->signers = ZZ_NewList()) == NULL)
- goto loser;
- return jar;
-
-loser:
- if (jar) {
- if (jar->manifest)
- ZZ_DestroyList (jar->manifest);
- if (jar->hashes)
- ZZ_DestroyList (jar->hashes);
- if (jar->phy)
- ZZ_DestroyList (jar->phy);
- if (jar->metainfo)
- ZZ_DestroyList (jar->metainfo);
- if (jar->signers)
- ZZ_DestroyList (jar->signers);
- PORT_Free (jar);
- }
- return NULL;
-}
-
-/*
- * J A R _ d e s t r o y
- */
-void PR_CALLBACK
-JAR_destroy(JAR *jar)
-{
- PORT_Assert( jar != NULL );
-
- if (jar == NULL)
- return;
-
- if (jar->fp)
- JAR_FCLOSE ((PRFileDesc*)jar->fp);
- if (jar->url)
- PORT_Free (jar->url);
- if (jar->filename)
- PORT_Free (jar->filename);
-
- /* Free the linked list elements */
- jar_destroy_list (jar->manifest);
- ZZ_DestroyList (jar->manifest);
- jar_destroy_list (jar->hashes);
- ZZ_DestroyList (jar->hashes);
- jar_destroy_list (jar->phy);
- ZZ_DestroyList (jar->phy);
- jar_destroy_list (jar->metainfo);
- ZZ_DestroyList (jar->metainfo);
- jar_destroy_list (jar->signers);
- ZZ_DestroyList (jar->signers);
- PORT_Free (jar);
-}
-
-static void
-jar_destroy_list(ZZList *list)
-{
- ZZLink *link, *oldlink;
- JAR_Item *it;
- JAR_Physical *phy;
- JAR_Digest *dig;
- JAR_Cert *fing;
- JAR_Metainfo *met;
- JAR_Signer *signer;
-
- if (list && !ZZ_ListEmpty (list)) {
- link = ZZ_ListHead (list);
- while (!ZZ_ListIterDone (list, link)) {
- it = link->thing;
- if (!it)
- goto next;
- if (it->pathname)
- PORT_Free (it->pathname);
-
- switch (it->type) {
- case jarTypeMeta:
- met = (JAR_Metainfo *) it->data;
- if (met) {
- if (met->header)
- PORT_Free (met->header);
- if (met->info)
- PORT_Free (met->info);
- PORT_Free (met);
- }
- break;
-
- case jarTypePhy:
- phy = (JAR_Physical *) it->data;
- if (phy)
- PORT_Free (phy);
- break;
-
- case jarTypeSign:
- fing = (JAR_Cert *) it->data;
- if (fing) {
- if (fing->cert)
- CERT_DestroyCertificate (fing->cert);
- if (fing->key)
- PORT_Free (fing->key);
- PORT_Free (fing);
- }
- break;
-
- case jarTypeSect:
- case jarTypeMF:
- case jarTypeSF:
- dig = (JAR_Digest *) it->data;
- if (dig) {
- PORT_Free (dig);
- }
- break;
-
- case jarTypeOwner:
- signer = (JAR_Signer *) it->data;
- if (signer)
- JAR_destroy_signer (signer);
- break;
-
- default:
- /* PORT_Assert( 1 != 2 ); */
- break;
- }
- PORT_Free (it);
-
-next:
- oldlink = link;
- link = link->next;
- ZZ_DestroyLink (oldlink);
- }
- }
-}
-
-/*
- * J A R _ g e t _ m e t a i n f o
- *
- * Retrieve meta information from the manifest file.
- * It doesn't matter whether it's from .MF or .SF, does it?
- *
- */
-
-int
-JAR_get_metainfo(JAR *jar, char *name, char *header, void **info,
- unsigned long *length)
-{
- JAR_Item *it;
- ZZLink *link;
- ZZList *list;
-
- PORT_Assert( jar != NULL && header != NULL );
-
- if (jar == NULL || header == NULL)
- return JAR_ERR_PNF;
-
- list = jar->metainfo;
-
- if (ZZ_ListEmpty (list))
- return JAR_ERR_PNF;
-
- for (link = ZZ_ListHead (list);
- !ZZ_ListIterDone (list, link);
- link = link->next) {
- it = link->thing;
- if (it->type == jarTypeMeta) {
- JAR_Metainfo *met;
-
- if ((name && !it->pathname) || (!name && it->pathname))
- continue;
- if (name && it->pathname && strcmp (it->pathname, name))
- continue;
- met = (JAR_Metainfo *) it->data;
- if (!PORT_Strcasecmp (met->header, header)) {
- *info = PORT_Strdup (met->info);
- *length = PORT_Strlen (met->info);
- return 0;
- }
- }
- }
- return JAR_ERR_PNF;
-}
-
-/*
- * J A R _ f i n d
- *
- * Establish the search pattern for use
- * by JAR_find_next, to traverse the filenames
- * or certificates in the JAR structure.
- *
- * See jar.h for a description on how to use.
- *
- */
-JAR_Context *
-JAR_find (JAR *jar, char *pattern, jarType type)
-{
- JAR_Context *ctx;
-
- PORT_Assert( jar != NULL );
-
- if (!jar)
- return NULL;
-
- ctx = (JAR_Context *) PORT_ZAlloc (sizeof (JAR_Context));
- if (ctx == NULL)
- return NULL;
-
- ctx->jar = jar;
- if (pattern) {
- if ((ctx->pattern = PORT_Strdup (pattern)) == NULL) {
- PORT_Free (ctx);
- return NULL;
- }
- }
- ctx->finding = type;
-
- switch (type) {
- case jarTypeMF:
- ctx->next = ZZ_ListHead (jar->hashes);
- break;
-
- case jarTypeSF:
- case jarTypeSign:
- ctx->next = NULL;
- ctx->nextsign = ZZ_ListHead (jar->signers);
- break;
-
- case jarTypeSect:
- ctx->next = ZZ_ListHead (jar->manifest);
- break;
-
- case jarTypePhy:
- ctx->next = ZZ_ListHead (jar->phy);
- break;
-
- case jarTypeOwner:
- if (jar->signers)
- ctx->next = ZZ_ListHead (jar->signers);
- else
- ctx->next = NULL;
- break;
-
- case jarTypeMeta:
- ctx->next = ZZ_ListHead (jar->metainfo);
- break;
-
- default:
- PORT_Assert( 1 != 2);
- break;
- }
- return ctx;
-}
-
-/*
- * J A R _ f i n d _ e n d
- *
- * Destroy the find iterator context.
- *
- */
-void
-JAR_find_end (JAR_Context *ctx)
-{
- PORT_Assert( ctx != NULL );
- if (ctx) {
- if (ctx->pattern)
- PORT_Free (ctx->pattern);
- PORT_Free (ctx);
- }
-}
-
-/*
- * J A R _ f i n d _ n e x t
- *
- * Return the next item of the given type
- * from one of the JAR linked lists.
- *
- */
-
-int JAR_find_next (JAR_Context *ctx, JAR_Item **it)
-{
- JAR *jar;
- ZZList *list = NULL;
- int finding;
- JAR_Signer *signer = NULL;
-
- PORT_Assert( ctx != NULL );
- PORT_Assert( ctx->jar != NULL );
-
- jar = ctx->jar;
-
- /* Internally, convert jarTypeSign to jarTypeSF, and return
- the actual attached certificate later */
- finding = (ctx->finding == jarTypeSign) ? jarTypeSF : ctx->finding;
- if (ctx->nextsign) {
- if (ZZ_ListIterDone (jar->signers, ctx->nextsign)) {
- *it = NULL;
- return -1;
- }
- PORT_Assert (ctx->nextsign->thing != NULL);
- signer = (JAR_Signer*)ctx->nextsign->thing->data;
- }
-
- /* Find out which linked list to traverse. Then if
- necessary, advance to the next linked list. */
- while (1) {
- switch (finding) {
- case jarTypeSign: /* not any more */
- PORT_Assert( finding != jarTypeSign );
- list = signer->certs;
- break;
-
- case jarTypeSect:
- list = jar->manifest;
- break;
-
- case jarTypePhy:
- list = jar->phy;
- break;
-
- case jarTypeSF: /* signer, not jar */
- PORT_Assert( signer != NULL );
- list = signer ? signer->sf : NULL;
- break;
-
- case jarTypeMF:
- list = jar->hashes;
- break;
-
- case jarTypeOwner:
- list = jar->signers;
- break;
-
- case jarTypeMeta:
- list = jar->metainfo;
- break;
-
- default:
- PORT_Assert( 1 != 2 );
- list = NULL;
- break;
- }
- if (list == NULL) {
- *it = NULL;
- return -1;
- }
- /* When looping over lists of lists, advance to the next signer.
- This is done when multiple signers are possible. */
- if (ZZ_ListIterDone (list, ctx->next)) {
- if (ctx->nextsign && jar->signers) {
- ctx->nextsign = ctx->nextsign->next;
- if (!ZZ_ListIterDone (jar->signers, ctx->nextsign)) {
- PORT_Assert (ctx->nextsign->thing != NULL);
- signer = (JAR_Signer*)ctx->nextsign->thing->data;
- PORT_Assert( signer != NULL );
- ctx->next = NULL;
- continue;
- }
- }
- *it = NULL;
- return -1;
- }
-
- /* if the signer changed, still need to fill in the "next" link */
- if (ctx->nextsign && ctx->next == NULL) {
- switch (finding) {
- case jarTypeSF:
- ctx->next = ZZ_ListHead (signer->sf);
- break;
-
- case jarTypeSign:
- ctx->next = ZZ_ListHead (signer->certs);
- break;
- }
- }
- PORT_Assert( ctx->next != NULL );
- if (ctx->next == NULL) {
- *it = NULL;
- return -1;
- }
- while (!ZZ_ListIterDone (list, ctx->next)) {
- *it = ctx->next->thing;
- ctx->next = ctx->next->next;
- if (!*it || (*it)->type != finding)
- continue;
- if (ctx->pattern && *ctx->pattern) {
- if (PORT_RegExpSearch ((*it)->pathname, ctx->pattern))
- continue;
- }
- /* We have a valid match. If this is a jarTypeSign
- return the certificate instead.. */
- if (ctx->finding == jarTypeSign) {
- JAR_Item *itt;
-
- /* just the first one for now */
- if (jar_find_first_cert (signer, jarTypeSign, &itt) >= 0) {
- *it = itt;
- return 0;
- }
- continue;
- }
- return 0;
- }
- } /* end while */
-}
-
-static int
-jar_find_first_cert (JAR_Signer *signer, int type, JAR_Item **it)
-{
- ZZLink *link;
- ZZList *list = signer->certs;
- int status = JAR_ERR_PNF;
-
- *it = NULL;
- if (ZZ_ListEmpty (list)) {
- /* empty list */
- return JAR_ERR_PNF;
- }
-
- for (link = ZZ_ListHead (list);
- !ZZ_ListIterDone (list, link);
- link = link->next) {
- if (link->thing->type == type) {
- *it = link->thing;
- status = 0;
- break;
- }
- }
- return status;
-}
-
-JAR_Signer *
-JAR_new_signer (void)
-{
- JAR_Signer *signer = (JAR_Signer *) PORT_ZAlloc (sizeof (JAR_Signer));
- if (signer == NULL)
- goto loser;
-
- /* certs */
- signer->certs = ZZ_NewList();
- if (signer->certs == NULL)
- goto loser;
-
- /* sf */
- signer->sf = ZZ_NewList();
- if (signer->sf == NULL)
- goto loser;
- return signer;
-
-loser:
- if (signer) {
- if (signer->certs)
- ZZ_DestroyList (signer->certs);
- if (signer->sf)
- ZZ_DestroyList (signer->sf);
- PORT_Free (signer);
- }
- return NULL;
-}
-
-void
-JAR_destroy_signer(JAR_Signer *signer)
-{
- if (signer) {
- if (signer->owner)
- PORT_Free (signer->owner);
- if (signer->digest)
- PORT_Free (signer->digest);
- jar_destroy_list (signer->sf);
- ZZ_DestroyList (signer->sf);
- jar_destroy_list (signer->certs);
- ZZ_DestroyList (signer->certs);
- PORT_Free (signer);
- }
-}
-
-JAR_Signer *
-jar_get_signer(JAR *jar, char *basename)
-{
- JAR_Item *it;
- JAR_Context *ctx = JAR_find (jar, NULL, jarTypeOwner);
- JAR_Signer *candidate;
- JAR_Signer *signer = NULL;
-
- if (ctx == NULL)
- return NULL;
-
- while (JAR_find_next (ctx, &it) >= 0) {
- candidate = (JAR_Signer *) it->data;
- if (*basename == '*' || !PORT_Strcmp (candidate->owner, basename)) {
- signer = candidate;
- break;
- }
- }
- JAR_find_end (ctx);
- return signer;
-}
-
-/*
- * J A R _ g e t _ f i l e n a m e
- *
- * Returns the filename associated with
- * a JAR structure.
- *
- */
-char *
-JAR_get_filename(JAR *jar)
-{
- return jar->filename;
-}
-
-/*
- * J A R _ g e t _ u r l
- *
- * Returns the URL associated with
- * a JAR structure. Nobody really uses this now.
- *
- */
-char *
-JAR_get_url(JAR *jar)
-{
- return jar->url;
-}
-
-/*
- * J A R _ s e t _ c a l l b a c k
- *
- * Register some manner of callback function for this jar.
- *
- */
-int
-JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn)
-{
- if (type == JAR_CB_SIGNAL) {
- jar->signal = fn;
- return 0;
- }
- return -1;
-}
-
-/*
- * Callbacks
- *
- */
-
-/* To return an error string */
-char *(*jar_fn_GetString) (int) = NULL;
-
-/* To return an MWContext for Java */
-void *(*jar_fn_FindSomeContext) (void) = NULL;
-
-/* To fabricate an MWContext for FE_GetPassword */
-void *(*jar_fn_GetInitContext) (void) = NULL;
-
-void
-JAR_init_callbacks(char *(*string_cb)(int),
- void *(*find_cx)(void),
- void *(*init_cx)(void))
-{
- jar_fn_GetString = string_cb;
- jar_fn_FindSomeContext = find_cx;
- jar_fn_GetInitContext = init_cx;
-}
-
-/*
- * J A R _ g e t _ e r r o r
- *
- * This is provided to map internal JAR errors to strings for
- * the Java console. Also, a DLL may call this function if it does
- * not have access to the XP_GetString function.
- *
- * These strings aren't UI, since they are Java console only.
- *
- */
-char *
-JAR_get_error(int status)
-{
- char *errstring = NULL;
-
- switch (status) {
- case JAR_ERR_GENERAL:
- errstring = "General JAR file error";
- break;
-
- case JAR_ERR_FNF:
- errstring = "JAR file not found";
- break;
-
- case JAR_ERR_CORRUPT:
- errstring = "Corrupt JAR file";
- break;
-
- case JAR_ERR_MEMORY:
- errstring = "Out of memory";
- break;
-
- case JAR_ERR_DISK:
- errstring = "Disk error (perhaps out of space)";
- break;
-
- case JAR_ERR_ORDER:
- errstring = "Inconsistent files in META-INF directory";
- break;
-
- case JAR_ERR_SIG:
- errstring = "Invalid digital signature file";
- break;
-
- case JAR_ERR_METADATA:
- errstring = "JAR metadata failed verification";
- break;
-
- case JAR_ERR_ENTRY:
- errstring = "No Manifest entry for this JAR entry";
- break;
-
- case JAR_ERR_HASH:
- errstring = "Invalid Hash of this JAR entry";
- break;
-
- case JAR_ERR_PK7:
- errstring = "Strange PKCS7 or RSA failure";
- break;
-
- case JAR_ERR_PNF:
- errstring = "Path not found inside JAR file";
- break;
-
- default:
- if (jar_fn_GetString) {
- errstring = jar_fn_GetString (status);
- } else {
- /* this is not a normal situation, and would only be
- called in cases of improper initialization */
- char *err = (char*)PORT_Alloc (40);
- if (err)
- PR_snprintf (err, 39, "Error %d\n", status); /* leak me! */
- else
- err = "Error! Bad! Out of memory!";
- return err;
- }
- break;
- }
- return errstring;
-}
diff --git a/security/nss/lib/jar/jar.h b/security/nss/lib/jar/jar.h
deleted file mode 100644
index 9a6005891..000000000
--- a/security/nss/lib/jar/jar.h
+++ /dev/null
@@ -1,373 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __JAR_h_
-#define __JAR_h_
-
-/*
- * In general, any functions that return pointers
- * have memory owned by the caller.
- *
- */
-
-/* security includes */
-#include "cert.h"
-#include "hasht.h"
-
-/* nspr 2.0 includes */
-#include "prio.h"
-
-#define ZHUGEP
-
-#include <stdio.h>
-
-/* various types */
-
-typedef enum {
- jarTypeMF = 2,
- jarTypeSF = 3,
- jarTypeMeta = 6,
- jarTypePhy = 7,
- jarTypeSign = 10,
- jarTypeSect = 11,
- jarTypeOwner = 13
-} jarType;
-
-/* void data in ZZList's contain JAR_Item type */
-typedef struct JAR_Item_ {
- char *pathname; /* relative. inside zip file */
- jarType type; /* various types */
- size_t size; /* size of data below */
- void *data; /* totally opaque */
-} JAR_Item;
-
-/* hashes */
-typedef enum {
- jarHashNone = 0,
- jarHashBad = 1,
- jarHashPresent = 2
-} jarHash;
-
-typedef struct JAR_Digest_ {
- jarHash md5_status;
- unsigned char md5 [MD5_LENGTH];
- jarHash sha1_status;
- unsigned char sha1 [SHA1_LENGTH];
-} JAR_Digest;
-
-/* physical archive formats */
-typedef enum {
- jarArchGuess = 0,
- jarArchNone = 1,
- jarArchZip = 2,
- jarArchTar = 3
-} jarArch;
-
-#include "jar-ds.h"
-
-struct JAR_;
-
-typedef int jar_settable_callback_fn(int status, struct JAR_ *jar,
- const char *metafile, char *pathname,
- char *errortext);
-
-/* jar object */
-typedef struct JAR_ {
- jarArch format; /* physical archive format */
-
- char *url; /* Where it came from */
- char *filename; /* Disk location */
- FILE *fp; /* For multiple extractions */
- /* JAR_FILE */
-
- /* various linked lists */
- ZZList *manifest; /* Digests of MF sections */
- ZZList *hashes; /* Digests of actual signed files */
- ZZList *phy; /* Physical layout of JAR file */
- ZZList *metainfo; /* Global metainfo */
-
- JAR_Digest *globalmeta; /* digest of .MF global portion */
-
- /* Below will change to a linked list to support multiple sigs */
- int pkcs7; /* Enforced opaqueness */
- int valid; /* PKCS7 signature validated */
-
- ZZList *signers; /* the above, per signer */
-
- /* Window context, very necessary for PKCS11 now */
- void *mw; /* MWContext window context */
-
- /* Signal callback function */
- jar_settable_callback_fn *signal;
-} JAR;
-
-/*
- * Iterator
- *
- * Context for iterative operations. Certain operations
- * require iterating multiple linked lists because of
- * multiple signers. "nextsign" is used for this purpose.
- *
- */
-typedef struct JAR_Context_ {
- JAR *jar; /* Jar we are searching */
- char *pattern; /* Regular expression */
- jarType finding; /* Type of item to find */
- ZZLink *next; /* Next item in find */
- ZZLink *nextsign; /* Next signer, sometimes */
-} JAR_Context;
-
-typedef struct JAR_Signer_ {
- int pkcs7; /* Enforced opaqueness */
- int valid; /* PKCS7 signature validated */
- char *owner; /* name of .RSA file */
- JAR_Digest *digest; /* of .SF file */
- ZZList *sf; /* Linked list of .SF file contents */
- ZZList *certs; /* Signing information */
-} JAR_Signer;
-
-/* Meta informaton, or "policy", from the manifest file.
- Right now just one tuple per JAR_Item. */
-typedef struct JAR_Metainfo_ {
- char *header;
- char *info;
-} JAR_Metainfo;
-
-/* This should not be global */
-typedef struct JAR_Physical_ {
- unsigned char compression;
- unsigned long offset;
- unsigned long length;
- unsigned long uncompressed_length;
-#if defined(XP_UNIX) || defined(XP_BEOS)
- uint16 mode;
-#endif
-} JAR_Physical;
-
-typedef struct JAR_Cert_ {
- size_t length;
- void *key;
- CERTCertificate *cert;
-} JAR_Cert;
-
-
-/* certificate stuff */
-typedef enum {
- jarCertCompany = 1,
- jarCertCA = 2,
- jarCertSerial = 3,
- jarCertExpires = 4,
- jarCertNickname = 5,
- jarCertFinger = 6,
- jarCertJavaHack = 100
-} jarCert;
-
-/* callback types */
-#define JAR_CB_SIGNAL 1
-
-/*
- * This is the base for the JAR error codes. It will
- * change when these are incorporated into allxpstr.c,
- * but right now they won't let me put them there.
- *
- */
-#ifndef SEC_ERR_BASE
-#define SEC_ERR_BASE (-0x2000)
-#endif
-
-#define JAR_BASE SEC_ERR_BASE + 300
-
-/* Jar specific error definitions */
-
-#define JAR_ERR_GENERAL (JAR_BASE + 1)
-#define JAR_ERR_FNF (JAR_BASE + 2)
-#define JAR_ERR_CORRUPT (JAR_BASE + 3)
-#define JAR_ERR_MEMORY (JAR_BASE + 4)
-#define JAR_ERR_DISK (JAR_BASE + 5)
-#define JAR_ERR_ORDER (JAR_BASE + 6)
-#define JAR_ERR_SIG (JAR_BASE + 7)
-#define JAR_ERR_METADATA (JAR_BASE + 8)
-#define JAR_ERR_ENTRY (JAR_BASE + 9)
-#define JAR_ERR_HASH (JAR_BASE + 10)
-#define JAR_ERR_PK7 (JAR_BASE + 11)
-#define JAR_ERR_PNF (JAR_BASE + 12)
-
-/* Function declarations */
-
-extern JAR *JAR_new (void);
-
-extern void PR_CALLBACK JAR_destroy (JAR *jar);
-
-extern char *JAR_get_error (int status);
-
-extern int JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn);
-
-extern void
-JAR_init_callbacks(char *(*string_cb)(int),
- void *(*find_cx)(void),
- void *(*init_cx)(void) );
-
-/*
- * JAR_set_context
- *
- * PKCS11 may require a password to be entered by the user
- * before any crypto routines may be called. This will require
- * a window context if used from inside Mozilla.
- *
- * Call this routine with your context before calling
- * verifying or signing. If you have no context, call with NULL
- * and one will be chosen for you.
- *
- */
-int JAR_set_context (JAR *jar, void /*MWContext*/ *mw);
-
-/*
- * Iterative operations
- *
- * JAR_find sets up for repeated calls with JAR_find_next.
- * I never liked findfirst and findnext, this is nicer.
- *
- * Pattern contains a relative pathname to match inside the
- * archive. It is currently assumed to be "*".
- *
- * To use:
- *
- * JAR_Item *item;
- * JAR_find (jar, "*.class", jarTypeMF);
- * while (JAR_find_next (jar, &item) >= 0)
- * { do stuff }
- *
- */
-
-/* Replacement functions with an external context */
-
-extern JAR_Context *JAR_find (JAR *jar, char *pattern, jarType type);
-
-extern int JAR_find_next (JAR_Context *ctx, JAR_Item **it);
-
-extern void JAR_find_end (JAR_Context *ctx);
-
-/*
- * Function to parse manifest file:
- *
- * Many signatures may be attached to a single filename located
- * inside the zip file. We only support one.
- *
- * Several manifests may be included in the zip file.
- *
- * You must pass the MANIFEST.MF file before any .SF files.
- *
- * Right now this returns a big ole list, privately in the jar structure.
- * If you need to traverse it, use JAR_find if possible.
- *
- * The path is needed to determine what type of binary signature is
- * being passed, though it is technically not needed for manifest files.
- *
- * When parsing an ASCII file, null terminate the ASCII raw_manifest
- * prior to sending it, and indicate a length of 0. For binary digital
- * signatures only, indicate the true length of the signature.
- * (This is legacy behavior.)
- *
- * You may free the manifest after parsing it.
- *
- */
-
-extern int
-JAR_parse_manifest(JAR *jar, char *raw_manifest, long length, const char *path,
- const char *url);
-
-/*
- * Verify data (nonstreaming). The signature is actually
- * checked by JAR_parse_manifest or JAR_pass_archive.
- *
- */
-
-extern JAR_Digest * PR_CALLBACK
-JAR_calculate_digest(void *data, long length);
-
-extern int PR_CALLBACK
-JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig);
-
-extern int
-JAR_digest_file(char *filename, JAR_Digest *dig);
-
-/*
- * Meta information
- *
- * Currently, since this call does not support passing of an owner
- * (certificate, or physical name of the .sf file), it is restricted to
- * returning information located in the manifest.mf file.
- *
- * Meta information is a name/value pair inside the archive file. Here,
- * the name is passed in *header and value returned in **info.
- *
- * Pass a NULL as the name to retrieve metainfo from the global section.
- *
- * Data is returned in **info, of size *length. The return value
- * will indicate if no data was found.
- *
- */
-
-extern int
-JAR_get_metainfo(JAR *jar, char *name, char *header, void **info,
- unsigned long *length);
-
-extern char *JAR_get_filename (JAR *jar);
-
-extern char *JAR_get_url (JAR *jar);
-
-/* save the certificate with this fingerprint in persistent
- storage, somewhere, for retrieval in a future session when there
- is no corresponding JAR structure. */
-extern int PR_CALLBACK
-JAR_stash_cert(JAR *jar, long keylen, void *key);
-
-/* retrieve a certificate presumably stashed with the above
- function, but may be any certificate. Type is &CERTCertificate */
-CERTCertificate *
-JAR_fetch_cert(long length, void *key);
-
-/*
- * New functions to handle archives alone
- * (call JAR_new beforehand)
- *
- * JAR_pass_archive acts much like parse_manifest. Certificates
- * are returned in the JAR structure but as opaque data. When calling
- * JAR_verified_extract you still need to decide which of these
- * certificates to honor.
- *
- * Code to examine a JAR structure is in jarbert.c. You can obtain both
- * a list of filenames and certificates from traversing the linked list.
- *
- */
-extern int
-JAR_pass_archive(JAR *jar, jarArch format, char *filename, const char *url);
-
-/*
- * Same thing, but don't check signatures
- */
-extern int
-JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename,
- const char *url);
-
-/*
- * Extracts a relative pathname from the archive and places it
- * in the filename specified.
- *
- * Call JAR_set_nailed if you want to keep the file descriptors
- * open between multiple calls to JAR_verify_extract.
- *
- */
-extern int
-JAR_verified_extract(JAR *jar, char *path, char *outpath);
-
-/*
- * JAR_extract does no crypto checking. This can be used if you
- * need to extract a manifest file or signature, etc.
- *
- */
-extern int
-JAR_extract(JAR *jar, char *path, char *outpath);
-
-#endif /* __JAR_h_ */
diff --git a/security/nss/lib/jar/jarfile.c b/security/nss/lib/jar/jarfile.c
deleted file mode 100644
index a604f19cd..000000000
--- a/security/nss/lib/jar/jarfile.c
+++ /dev/null
@@ -1,965 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * JARFILE
- *
- * Parsing of a Jar file
- */
-#define JAR_SIZE 256
-
-#include "jar.h"
-#include "jarint.h"
-#include "jarfile.h"
-
-/* commercial compression */
-#include "jzlib.h"
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
-#include "sys/stat.h"
-#endif
-
-#include "sechash.h" /* for HASH_GetHashObject() */
-
-PR_STATIC_ASSERT(46 == sizeof(struct ZipCentral));
-PR_STATIC_ASSERT(30 == sizeof(struct ZipLocal));
-PR_STATIC_ASSERT(22 == sizeof(struct ZipEnd));
-PR_STATIC_ASSERT(512 == sizeof(union TarEntry));
-
-/* extracting */
-static int
-jar_guess_jar(const char *filename, JAR_FILE fp);
-
-static int
-jar_inflate_memory(unsigned int method, long *length, long expected_out_len,
- char **data);
-
-static int
-jar_physical_extraction(JAR_FILE fp, char *outpath, long offset, long length);
-
-static int
-jar_physical_inflate(JAR_FILE fp, char *outpath, long offset, long length,
- unsigned int method);
-
-static int
-jar_verify_extract(JAR *jar, char *path, char *physical_path);
-
-static JAR_Physical *
-jar_get_physical(JAR *jar, char *pathname);
-
-static int
-jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp);
-
-static int
-jar_extract_mf(JAR *jar, jarArch format, JAR_FILE fp, char *ext);
-
-
-/* indexing */
-static int
-jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp);
-
-static int
-jar_listtar(JAR *jar, JAR_FILE fp);
-
-static int
-jar_listzip(JAR *jar, JAR_FILE fp);
-
-
-/* conversions */
-static int
-dosdate(char *date, const char *s);
-
-static int
-dostime(char *time, const char *s);
-
-#ifdef NSS_X86_OR_X64
-#define x86ShortToUint32(ii) ((const PRUint32)*((const PRUint16 *)(ii)))
-#define x86LongToUint32(ii) (*(const PRUint32 *)(ii))
-#else
-static PRUint32
-x86ShortToUint32(const void *ii);
-
-static PRUint32
-x86LongToUint32(const void *ll);
-#endif
-
-static long
-octalToLong(const char *s);
-
-/*
- * J A R _ p a s s _ a r c h i v e
- *
- * For use by naive clients. Slam an entire archive file
- * into this function. We extract manifests, parse, index
- * the archive file, and do whatever nastiness.
- *
- */
-int
-JAR_pass_archive(JAR *jar, jarArch format, char *filename, const char *url)
-{
- JAR_FILE fp;
- int status = 0;
-
- if (filename == NULL)
- return JAR_ERR_GENERAL;
-
- if ((fp = JAR_FOPEN (filename, "rb")) != NULL) {
- if (format == jarArchGuess)
- format = (jarArch)jar_guess_jar (filename, fp);
-
- jar->format = format;
- jar->url = url ? PORT_Strdup (url) : NULL;
- jar->filename = PORT_Strdup (filename);
-
- status = jar_gen_index (jar, format, fp);
- if (status == 0)
- status = jar_extract_manifests (jar, format, fp);
-
- JAR_FCLOSE (fp);
- if (status < 0)
- return status;
-
- /* people were expecting it this way */
- return jar->valid;
- }
- /* file not found */
- return JAR_ERR_FNF;
-}
-
-/*
- * J A R _ p a s s _ a r c h i v e _ u n v e r i f i e d
- *
- * Same as JAR_pass_archive, but doesn't parse signatures.
- *
- */
-int
-JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename,
- const char *url)
-{
- JAR_FILE fp;
- int status = 0;
-
- if (filename == NULL) {
- return JAR_ERR_GENERAL;
- }
-
- if ((fp = JAR_FOPEN (filename, "rb")) != NULL) {
- if (format == jarArchGuess) {
- format = (jarArch)jar_guess_jar (filename, fp);
- }
-
- jar->format = format;
- jar->url = url ? PORT_Strdup (url) : NULL;
- jar->filename = PORT_Strdup (filename);
-
- status = jar_gen_index (jar, format, fp);
- if (status == 0) {
- status = jar_extract_mf(jar, format, fp, "mf");
- }
-
- JAR_FCLOSE (fp);
- if (status < 0) {
- return status;
- }
-
- /* people were expecting it this way */
- return jar->valid;
- }
- /* file not found */
- return JAR_ERR_FNF;
-}
-
-/*
- * J A R _ v e r i f i e d _ e x t r a c t
- *
- * Optimization: keep a file descriptor open
- * inside the JAR structure, so we don't have to
- * open the file 25 times to run java.
- *
- */
-
-int
-JAR_verified_extract(JAR *jar, char *path, char *outpath)
-{
- int status = JAR_extract (jar, path, outpath);
-
- if (status >= 0)
- return jar_verify_extract(jar, path, outpath);
- return status;
-}
-
-int
-JAR_extract(JAR *jar, char *path, char *outpath)
-{
- int result;
- JAR_Physical *phy;
-
- if (jar->fp == NULL && jar->filename) {
- jar->fp = (FILE*)JAR_FOPEN (jar->filename, "rb");
- }
- if (jar->fp == NULL) {
- /* file not found */
- return JAR_ERR_FNF;
- }
-
- phy = jar_get_physical (jar, path);
- if (phy) {
- if (phy->compression != 0 && phy->compression != 8) {
- /* unsupported compression method */
- result = JAR_ERR_CORRUPT;
- }
- if (phy->compression == 0) {
- result = jar_physical_extraction
- ((PRFileDesc*)jar->fp, outpath, phy->offset, phy->length);
- } else {
- result = jar_physical_inflate((PRFileDesc*)jar->fp, outpath,
- phy->offset, phy->length,
- (unsigned int) phy->compression);
- }
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
- if (phy->mode)
- chmod (outpath, 0400 | (mode_t) phy->mode);
-#endif
- } else {
- /* pathname not found in archive */
- result = JAR_ERR_PNF;
- }
- return result;
-}
-
-/*
- * p h y s i c a l _ e x t r a c t i o n
- *
- * This needs to be done in chunks of say 32k, instead of
- * in one bulk calloc. (Necessary under Win16 platform.)
- * This is done for uncompressed entries only.
- *
- */
-
-#define CHUNK 32768
-
-static int
-jar_physical_extraction(JAR_FILE fp, char *outpath, long offset, long length)
-{
- JAR_FILE out;
- char *buffer = (char *)PORT_ZAlloc(CHUNK);
- int status = 0;
-
- if (buffer == NULL)
- return JAR_ERR_MEMORY;
-
- if ((out = JAR_FOPEN (outpath, "wb")) != NULL) {
- long at = 0;
-
- JAR_FSEEK (fp, offset, (PRSeekWhence)0);
- while (at < length) {
- long chunk = (at + CHUNK <= length) ? CHUNK : length - at;
- if (JAR_FREAD (fp, buffer, chunk) != chunk) {
- status = JAR_ERR_DISK;
- break;
- }
- at += chunk;
- if (JAR_FWRITE (out, buffer, chunk) < chunk) {
- /* most likely a disk full error */
- status = JAR_ERR_DISK;
- break;
- }
- }
- JAR_FCLOSE (out);
- } else {
- /* error opening output file */
- status = JAR_ERR_DISK;
- }
- PORT_Free (buffer);
- return status;
-}
-
-/*
- * j a r _ p h y s i c a l _ i n f l a t e
- *
- * Inflate a range of bytes in a file, writing the inflated
- * result to "outpath". Chunk based.
- *
- */
-/* input and output chunks differ, assume 4x compression */
-
-#define ICHUNK 8192
-#define OCHUNK 32768
-
-static int
-jar_physical_inflate(JAR_FILE fp, char *outpath, long offset, long length,
- unsigned int method)
-{
- char *inbuf, *outbuf;
- int status = 0;
- z_stream zs;
- JAR_FILE out;
-
- /* Raw inflate in zlib 1.1.4 needs an extra dummy byte at the end */
- if ((inbuf = (char *)PORT_ZAlloc(ICHUNK + 1)) == NULL)
- return JAR_ERR_MEMORY;
-
- if ((outbuf = (char *)PORT_ZAlloc(OCHUNK)) == NULL) {
- PORT_Free (inbuf);
- return JAR_ERR_MEMORY;
- }
-
- PORT_Memset (&zs, 0, sizeof (zs));
- status = inflateInit2 (&zs, -MAX_WBITS);
- if (status != Z_OK) {
- PORT_Free (inbuf);
- PORT_Free (outbuf);
- return JAR_ERR_GENERAL;
- }
-
- if ((out = JAR_FOPEN (outpath, "wb")) != NULL) {
- long at = 0;
-
- JAR_FSEEK (fp, offset, (PRSeekWhence)0);
- while (at < length) {
- long chunk = (at + ICHUNK <= length) ? ICHUNK : length - at;
- unsigned long tin;
-
- if (JAR_FREAD (fp, inbuf, chunk) != chunk) {
- /* incomplete read */
- JAR_FCLOSE (out);
- PORT_Free (inbuf);
- PORT_Free (outbuf);
- return JAR_ERR_CORRUPT;
- }
- at += chunk;
- if (at == length) {
- /* add an extra dummy byte at the end */
- inbuf[chunk++] = 0xDD;
- }
- zs.next_in = (Bytef *) inbuf;
- zs.avail_in = chunk;
- zs.avail_out = OCHUNK;
- tin = zs.total_in;
- while ((zs.total_in - tin < chunk) || (zs.avail_out == 0)) {
- unsigned long prev_total = zs.total_out;
- unsigned long ochunk;
-
- zs.next_out = (Bytef *) outbuf;
- zs.avail_out = OCHUNK;
- status = inflate (&zs, Z_NO_FLUSH);
- if (status != Z_OK && status != Z_STREAM_END) {
- /* error during decompression */
- JAR_FCLOSE (out);
- PORT_Free (inbuf);
- PORT_Free (outbuf);
- return JAR_ERR_CORRUPT;
- }
- ochunk = zs.total_out - prev_total;
- if (JAR_FWRITE (out, outbuf, ochunk) < ochunk) {
- /* most likely a disk full error */
- status = JAR_ERR_DISK;
- break;
- }
- if (status == Z_STREAM_END)
- break;
- }
- }
- JAR_FCLOSE (out);
- status = inflateEnd (&zs);
- } else {
- /* error opening output file */
- status = JAR_ERR_DISK;
- }
- PORT_Free (inbuf);
- PORT_Free (outbuf);
- return status;
-}
-
-/*
- * j a r _ i n f l a t e _ m e m o r y
- *
- * Call zlib to inflate the given memory chunk. It is re-XP_ALLOC'd,
- * and thus appears to operate inplace to the caller.
- *
- */
-static int
-jar_inflate_memory(unsigned int method, long *length, long expected_out_len,
- char **data)
-{
- char *inbuf = *data;
- char *outbuf = (char*)PORT_ZAlloc(expected_out_len);
- long insz = *length;
- int status;
- z_stream zs;
-
- if (outbuf == NULL)
- return JAR_ERR_MEMORY;
-
- PORT_Memset(&zs, 0, sizeof zs);
- status = inflateInit2 (&zs, -MAX_WBITS);
- if (status < 0) {
- /* error initializing zlib stream */
- PORT_Free (outbuf);
- return JAR_ERR_GENERAL;
- }
-
- zs.next_in = (Bytef *) inbuf;
- zs.next_out = (Bytef *) outbuf;
- zs.avail_in = insz;
- zs.avail_out = expected_out_len;
-
- status = inflate (&zs, Z_FINISH);
- if (status != Z_OK && status != Z_STREAM_END) {
- /* error during deflation */
- PORT_Free (outbuf);
- return JAR_ERR_GENERAL;
- }
-
- status = inflateEnd (&zs);
- if (status != Z_OK) {
- /* error during deflation */
- PORT_Free (outbuf);
- return JAR_ERR_GENERAL;
- }
- PORT_Free(*data);
- *data = outbuf;
- *length = zs.total_out;
- return 0;
-}
-
-/*
- * v e r i f y _ e x t r a c t
- *
- * Validate signature on the freshly extracted file.
- *
- */
-static int
-jar_verify_extract(JAR *jar, char *path, char *physical_path)
-{
- int status;
- JAR_Digest dig;
-
- PORT_Memset (&dig, 0, sizeof dig);
- status = JAR_digest_file (physical_path, &dig);
- if (!status)
- status = JAR_verify_digest (jar, path, &dig);
- return status;
-}
-
-/*
- * g e t _ p h y s i c a l
- *
- * Let's get physical.
- * Obtains the offset and length of this file in the jar file.
- *
- */
-static JAR_Physical *
-jar_get_physical(JAR *jar, char *pathname)
-{
- ZZLink *link;
- ZZList *list = jar->phy;
-
- if (ZZ_ListEmpty (list))
- return NULL;
-
- for (link = ZZ_ListHead (list);
- !ZZ_ListIterDone (list, link);
- link = link->next) {
- JAR_Item *it = link->thing;
-
- if (it->type == jarTypePhy &&
- it->pathname && !PORT_Strcmp (it->pathname, pathname)) {
- JAR_Physical *phy = (JAR_Physical *)it->data;
- return phy;
- }
- }
- return NULL;
-}
-
-/*
- * j a r _ e x t r a c t _ m a n i f e s t s
- *
- * Extract the manifest files and parse them,
- * from an open archive file whose contents are known.
- *
- */
-static int
-jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp)
-{
- int status, signatures;
-
- if (format != jarArchZip && format != jarArchTar)
- return JAR_ERR_CORRUPT;
-
- if ((status = jar_extract_mf (jar, format, fp, "mf")) < 0)
- return status;
- if (!status)
- return JAR_ERR_ORDER;
- if ((status = jar_extract_mf (jar, format, fp, "sf")) < 0)
- return status;
- if (!status)
- return JAR_ERR_ORDER;
- if ((status = jar_extract_mf (jar, format, fp, "rsa")) < 0)
- return status;
- signatures = status;
- if ((status = jar_extract_mf (jar, format, fp, "dsa")) < 0)
- return status;
- if (!(signatures += status))
- return JAR_ERR_SIG;
- return 0;
-}
-
-/*
- * j a r _ e x t r a c t _ m f
- *
- * Extracts manifest files based on an extension, which
- * should be .MF, .SF, .RSA, etc. Order of the files is now no
- * longer important when zipping jar files.
- *
- */
-static int
-jar_extract_mf(JAR *jar, jarArch format, JAR_FILE fp, char *ext)
-{
- ZZLink *link;
- ZZList *list = jar->phy;
- int ret = 0;
-
- if (ZZ_ListEmpty (list))
- return JAR_ERR_PNF;
-
- for (link = ZZ_ListHead (list);
- ret >= 0 && !ZZ_ListIterDone (list, link);
- link = link->next) {
- JAR_Item *it = link->thing;
-
- if (it->type == jarTypePhy &&
- !PORT_Strncmp (it->pathname, "META-INF", 8))
- {
- JAR_Physical *phy = (JAR_Physical *) it->data;
- char *fn = it->pathname + 8;
- char *e;
- char *manifest;
- long length;
- int num, status;
-
- if (PORT_Strlen (it->pathname) < 8)
- continue;
-
- if (*fn == '/' || *fn == '\\')
- fn++;
- if (*fn == 0) {
- /* just a directory entry */
- continue;
- }
-
- /* skip to extension */
- for (e = fn; *e && *e != '.'; e++)
- /* yip */ ;
-
- /* and skip dot */
- if (*e == '.')
- e++;
- if (PORT_Strcasecmp (ext, e)) {
- /* not the right extension */
- continue;
- }
- if (phy->length == 0 || phy->length > 0xFFFF) {
- /* manifest files cannot be zero length or too big! */
- /* the 0xFFFF limit is per J2SE SDK */
- return JAR_ERR_CORRUPT;
- }
-
- /* Read in the manifest and parse it */
- /* Raw inflate in zlib 1.1.4 needs an extra dummy byte at the end */
- manifest = (char *)PORT_ZAlloc(phy->length + 1);
- if (!manifest)
- return JAR_ERR_MEMORY;
-
- JAR_FSEEK (fp, phy->offset, (PRSeekWhence)0);
- num = JAR_FREAD (fp, manifest, phy->length);
- if (num != phy->length) {
- /* corrupt archive file */
- PORT_Free (manifest);
- return JAR_ERR_CORRUPT;
- }
-
- if (phy->compression == 8) {
- length = phy->length;
- /* add an extra dummy byte at the end */
- manifest[length++] = 0xDD;
- status = jar_inflate_memory((unsigned int)phy->compression,
- &length,
- phy->uncompressed_length,
- &manifest);
- if (status < 0) {
- PORT_Free (manifest);
- return status;
- }
- } else if (phy->compression) {
- /* unsupported compression method */
- PORT_Free (manifest);
- return JAR_ERR_CORRUPT;
- } else
- length = phy->length;
-
- status = JAR_parse_manifest(jar, manifest, length,
- it->pathname, "url");
- PORT_Free (manifest);
- if (status < 0)
- ret = status;
- else
- ++ret;
- } else if (it->type == jarTypePhy) {
- /* ordinary file */
- }
- }
- return ret;
-}
-
-/*
- * j a r _ g e n _ i n d e x
- *
- * Generate an index for the various types of
- * known archive files. Right now .ZIP and .TAR
- *
- */
-static int
-jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp)
-{
- int result = JAR_ERR_CORRUPT;
-
- JAR_FSEEK (fp, 0, (PRSeekWhence)0);
- switch (format) {
- case jarArchZip:
- result = jar_listzip (jar, fp);
- break;
-
- case jarArchTar:
- result = jar_listtar (jar, fp);
- break;
-
- case jarArchGuess:
- case jarArchNone:
- return JAR_ERR_GENERAL;
- }
- JAR_FSEEK (fp, 0, (PRSeekWhence)0);
- return result;
-}
-
-/*
- * j a r _ l i s t z i p
- *
- * List the physical contents of a Phil Katz
- * style .ZIP file into the JAR linked list.
- *
- */
-static int
-jar_listzip(JAR *jar, JAR_FILE fp)
-{
- ZZLink *ent;
- JAR_Item *it;
- JAR_Physical *phy;
- struct ZipLocal *Local = PORT_ZNew(struct ZipLocal);
- struct ZipCentral *Central = PORT_ZNew(struct ZipCentral);
- struct ZipEnd *End = PORT_ZNew(struct ZipEnd);
-
- int err = 0;
- long pos = 0L;
- unsigned int compression;
- unsigned int filename_len, extra_len;
-
- char filename[JAR_SIZE];
- char date[9], time[9];
- char sig[4];
-
- if (!Local || !Central || !End) {
- /* out of memory */
- err = JAR_ERR_MEMORY;
- goto loser;
- }
-
- while (1) {
- PRUint32 sigVal;
- JAR_FSEEK (fp, pos, (PRSeekWhence)0);
-
- if (JAR_FREAD(fp, sig, sizeof sig) != sizeof sig) {
- /* zip file ends prematurely */
- err = JAR_ERR_CORRUPT;
- goto loser;
- }
-
- JAR_FSEEK (fp, pos, (PRSeekWhence)0);
- sigVal = x86LongToUint32(sig);
- if (sigVal == LSIG) {
- JAR_FREAD (fp, Local, sizeof *Local);
-
- filename_len = x86ShortToUint32(Local->filename_len);
- extra_len = x86ShortToUint32(Local->extrafield_len);
- if (filename_len >= JAR_SIZE) {
- /* corrupt zip file */
- err = JAR_ERR_CORRUPT;
- goto loser;
- }
-
- if (JAR_FREAD (fp, filename, filename_len) != filename_len) {
- /* truncated archive file */
- err = JAR_ERR_CORRUPT;
- goto loser;
- }
- filename [filename_len] = 0;
- /* Add this to our jar chain */
- phy = PORT_ZNew(JAR_Physical);
- if (phy == NULL) {
- err = JAR_ERR_MEMORY;
- goto loser;
- }
-
- /* We will index any file that comes our way, but when it comes
- to actually extraction, compression must be 0 or 8 */
- compression = x86ShortToUint32(Local->method);
- phy->compression = (compression <= 255) ? compression : 222;
- /* XXX 222 is bad magic. */
-
- phy->offset = pos + (sizeof *Local) + filename_len + extra_len;
- phy->length = x86LongToUint32(Local->size);
- phy->uncompressed_length = x86LongToUint32(Local->orglen);
-
- dosdate (date, Local->date);
- dostime (time, Local->time);
-
- it = PORT_ZNew(JAR_Item);
- if (it == NULL) {
- err = JAR_ERR_MEMORY;
- goto loser;
- }
-
- it->pathname = PORT_Strdup(filename);
- it->type = jarTypePhy;
- it->data = (unsigned char *) phy;
- it->size = sizeof (JAR_Physical);
-
- ent = ZZ_NewLink (it);
- if (ent == NULL) {
- err = JAR_ERR_MEMORY;
- goto loser;
- }
-
- ZZ_AppendLink (jar->phy, ent);
- pos = phy->offset + phy->length;
- } else if (sigVal == CSIG) {
- unsigned int attr = 0;
- if (JAR_FREAD(fp, Central, sizeof *Central) != sizeof *Central) {
- /* apparently truncated archive */
- err = JAR_ERR_CORRUPT;
- goto loser;
- }
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
- /* with unix we need to locate any bits from
- the protection mask in the external attributes. */
- attr = Central->external_attributes [2]; /* magic */
- if (attr) {
- /* we have to read the filename, again */
- filename_len = x86ShortToUint32(Central->filename_len);
- if (filename_len >= JAR_SIZE) {
- /* corrupt in central directory */
- err = JAR_ERR_CORRUPT;
- goto loser;
- }
-
- if (JAR_FREAD(fp, filename, filename_len) != filename_len) {
- /* truncated in central directory */
- err = JAR_ERR_CORRUPT;
- goto loser;
- }
- filename [filename_len] = 0;
-
- /* look up this name again */
- phy = jar_get_physical (jar, filename);
- if (phy) {
- /* always allow access by self */
- phy->mode = 0400 | attr;
- }
- }
-#endif
- pos += sizeof(struct ZipCentral)
- + x86ShortToUint32(Central->filename_len)
- + x86ShortToUint32(Central->commentfield_len)
- + x86ShortToUint32(Central->extrafield_len);
- } else if (sigVal == ESIG) {
- if (JAR_FREAD(fp, End, sizeof *End) != sizeof *End) {
- err = JAR_ERR_CORRUPT;
- goto loser;
- }
- break;
- } else {
- /* garbage in archive */
- err = JAR_ERR_CORRUPT;
- goto loser;
- }
- }
-
-loser:
- if (Local)
- PORT_Free(Local);
- if (Central)
- PORT_Free(Central);
- if (End)
- PORT_Free(End);
- return err;
-}
-
-/*
- * j a r _ l i s t t a r
- *
- * List the physical contents of a Unix
- * .tar file into the JAR linked list.
- *
- */
-static int
-jar_listtar(JAR *jar, JAR_FILE fp)
-{
- char *s;
- JAR_Physical *phy;
- long pos = 0L;
- long sz, mode;
- time_t when;
- union TarEntry tarball;
-
- while (1) {
- JAR_FSEEK (fp, pos, (PRSeekWhence)0);
-
- if (JAR_FREAD (fp, &tarball, sizeof tarball) < sizeof tarball)
- break;
-
- if (!*tarball.val.filename)
- break;
-
- when = octalToLong (tarball.val.time);
- sz = octalToLong (tarball.val.size);
- mode = octalToLong (tarball.val.mode);
-
- /* Tag the end of filename */
- s = tarball.val.filename;
- while (*s && *s != ' ')
- s++;
- *s = 0;
-
- /* Add to our linked list */
- phy = PORT_ZNew(JAR_Physical);
- if (phy == NULL)
- return JAR_ERR_MEMORY;
-
- phy->compression = 0;
- phy->offset = pos + sizeof tarball;
- phy->length = sz;
-
- ADDITEM(jar->phy, jarTypePhy, tarball.val.filename, phy,
- sizeof *phy);
-
- /* Advance to next file entry */
- sz = PR_ROUNDUP(sz,sizeof tarball);
- pos += sz + sizeof tarball;
- }
-
- return 0;
-}
-
-/*
- * d o s d a t e
- *
- * Not used right now, but keep it in here because
- * it will be needed.
- *
- */
-static int
-dosdate(char *date, const char *s)
-{
- PRUint32 num = x86ShortToUint32(s);
-
- PR_snprintf(date, 9, "%02d-%02d-%02d", ((num >> 5) & 0x0F), (num & 0x1F),
- ((num >> 9) + 80));
- return 0;
-}
-
-/*
- * d o s t i m e
- *
- * Not used right now, but keep it in here because
- * it will be needed.
- *
- */
-static int
-dostime (char *time, const char *s)
-{
- PRUint32 num = x86ShortToUint32(s);
-
- PR_snprintf (time, 6, "%02d:%02d", ((num >> 11) & 0x1F),
- ((num >> 5) & 0x3F));
- return 0;
-}
-
-#ifndef NSS_X86_OR_X64
-/*
- * Simulates an x86 (little endian, unaligned) ushort fetch from any address.
- */
-static PRUint32
-x86ShortToUint32(const void * v)
-{
- const unsigned char *ii = (const unsigned char *)v;
- PRUint32 ret = (PRUint32)(ii[0]) | ((PRUint32)(ii[1]) << 8);
- return ret;
-}
-
-/*
- * Simulates an x86 (little endian, unaligned) uint fetch from any address.
- */
-static PRUint32
-x86LongToUint32(const void *v)
-{
- const unsigned char *ll = (const unsigned char *)v;
- PRUint32 ret;
-
- ret = ((((PRUint32)(ll[0])) << 0) |
- (((PRUint32)(ll[1])) << 8) |
- (((PRUint32)(ll[2])) << 16) |
- (((PRUint32)(ll[3])) << 24));
- return ret;
-}
-#endif
-
-/*
- * ASCII octal to binary long.
- * Used for integer encoding inside tar files.
- *
- */
-static long
-octalToLong(const char *s)
-{
- long num = 0L;
-
- while (*s == ' ')
- s++;
- while (*s >= '0' && *s <= '7') {
- num <<= 3;
- num += *s++ - '0';
- }
- return num;
-}
-
-/*
- * g u e s s _ j a r
- *
- * Try to guess what kind of JAR file this is.
- * Maybe tar, maybe zip. Look in the file for magic
- * or at its filename.
- *
- */
-static int
-jar_guess_jar(const char *filename, JAR_FILE fp)
-{
- PRInt32 len = PORT_Strlen(filename);
- const char *ext = filename + len - 4; /* 4 for ".tar" */
-
- if (len >= 4 && !PL_strcasecmp(ext, ".tar"))
- return jarArchTar;
- return jarArchZip;
-}
diff --git a/security/nss/lib/jar/jarfile.h b/security/nss/lib/jar/jarfile.h
deleted file mode 100644
index 667415d45..000000000
--- a/security/nss/lib/jar/jarfile.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * JARFILE.H
- *
- * Certain constants and structures for the archive format.
- *
- */
-
-/* ZIP */
-struct ZipLocal { /* 30 bytes */
- char signature [4];
- char word [2];
- char bitflag [2];
- char method [2];
- char time [2];
- char date [2];
- char crc32 [4];
- char size [4];
- char orglen [4];
- char filename_len [2];
- char extrafield_len [2];
-};
-
-struct ZipCentral { /* 46 bytes */
- char signature [4];
- char version_made_by [2];
- char version [2];
- char bitflag [2];
- char method [2];
- char time [2];
- char date [2];
- char crc32 [4];
- char size [4];
- char orglen [4];
- char filename_len [2];
- char extrafield_len [2];
- char commentfield_len [2];
- char diskstart_number [2];
- char internal_attributes [2];
- char external_attributes [4];
- char localhdr_offset [4];
-};
-
-struct ZipEnd { /* 22 bytes */
- char signature [4];
- char disk_nr [2];
- char start_central_dir [2];
- char total_entries_disk [2];
- char total_entries_archive [2];
- char central_dir_size [4];
- char offset_central_dir [4];
- char commentfield_len [2];
-};
-
-#define LSIG 0x04034B50l
-#define CSIG 0x02014B50l
-#define ESIG 0x06054B50l
-
-/* TAR */
-union TarEntry { /* 512 bytes */
- struct header { /* 257 bytes */
- char filename [100];
- char mode [8];
- char uid [8];
- char gid [8];
- char size [12];
- char time [12];
- char checksum [8];
- char linkflag;
- char linkname [100];
- } val;
- char buffer [512];
-};
diff --git a/security/nss/lib/jar/jarint.c b/security/nss/lib/jar/jarint.c
deleted file mode 100644
index 2fa220b2a..000000000
--- a/security/nss/lib/jar/jarint.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Internal libjar routines.
- */
-
-#include "jar.h"
-#include "jarint.h"
-
-/*-----------------------------------------------------------------------
- * JAR_FOPEN_to_PR_Open
- * Translate JAR_FOPEN arguments to PR_Open arguments
- */
-PRFileDesc*
-JAR_FOPEN_to_PR_Open(const char* name, const char *mode)
-{
-
- PRIntn prflags=0, prmode=0;
-
- /* Get read/write flags */
- if (strchr(mode, 'r') && !strchr(mode, '+')) {
- prflags |= PR_RDONLY;
- } else if( (strchr(mode, 'w') || strchr(mode, 'a')) &&
- !strchr(mode,'+') ) {
- prflags |= PR_WRONLY;
- } else {
- prflags |= PR_RDWR;
- }
-
- /* Create a new file? */
- if (strchr(mode, 'w') || strchr(mode, 'a')) {
- prflags |= PR_CREATE_FILE;
- }
-
- /* Append? */
- if (strchr(mode, 'a')) {
- prflags |= PR_APPEND;
- }
-
- /* Truncate? */
- if (strchr(mode, 'w')) {
- prflags |= PR_TRUNCATE;
- }
-
- /* We can't do umask because it isn't XP. Choose some default
- mode for created files */
- prmode = 0755;
-
- return PR_Open(name, prflags, prmode);
-}
diff --git a/security/nss/lib/jar/jarint.h b/security/nss/lib/jar/jarint.h
deleted file mode 100644
index 214b8a1d1..000000000
--- a/security/nss/lib/jar/jarint.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* JAR internal routines */
-
-#include "nspr.h"
-#include "key.h"
-#include "base64.h"
-
-extern CERTCertDBHandle *JAR_open_database (void);
-
-extern int JAR_close_database (CERTCertDBHandle *certdb);
-
-extern int jar_close_key_database (void *keydb);
-
-extern void *jar_open_key_database (void);
-
-extern JAR_Signer *JAR_new_signer (void);
-
-extern void JAR_destroy_signer (JAR_Signer *signer);
-
-extern JAR_Signer *jar_get_signer (JAR *jar, char *basename);
-
-extern int
-jar_append(ZZList *list, int type, char *pathname, void *data, size_t size);
-
-/* Translate fopen mode arg to PR_Open flags and mode */
-PRFileDesc*
-JAR_FOPEN_to_PR_Open(const char *name, const char *mode);
-
-#define ADDITEM(list,type,pathname,data,size) \
-{ \
- int err = jar_append (list, type, pathname, data, size); \
- if (err < 0) \
- return err; \
-}
-
-/* Here is some ugliness in the event it is necessary to link
- with NSPR 1.0 libraries, which do not include an FSEEK. It is
- difficult to fudge an FSEEK into 1.0 so we use stdio. */
-
-/* nspr 2.0 suite */
-#define JAR_FILE PRFileDesc *
-#define JAR_FOPEN(fn,mode) JAR_FOPEN_to_PR_Open(fn,mode)
-#define JAR_FCLOSE PR_Close
-#define JAR_FSEEK PR_Seek
-#define JAR_FREAD PR_Read
-#define JAR_FWRITE PR_Write
-
-int
-jar_create_pk7(CERTCertDBHandle *certdb, void *keydb,
- CERTCertificate *cert, char *password, JAR_FILE infp,
- JAR_FILE outfp);
-
diff --git a/security/nss/lib/jar/jarnav.c b/security/nss/lib/jar/jarnav.c
deleted file mode 100644
index 6ae763c32..000000000
--- a/security/nss/lib/jar/jarnav.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * JARNAV.C
- *
- * JAR stuff needed for client only.
- *
- */
-
-#include "jar.h"
-#include "jarint.h"
-
-/* from proto.h */
-extern MWContext *FE_GetInitContext(void);
-
-/* To return an MWContext for Java */
-static MWContext *(*jar_fn_FindSomeContext) (void) = NULL;
-
-/* To fabricate an MWContext for FE_GetPassword */
-static MWContext *(*jar_fn_GetInitContext) (void) = NULL;
-
-/*
- * J A R _ i n i t
- *
- * Initialize the JAR functions.
- *
- */
-
-void JAR_init (void)
-{
- JAR_init_callbacks (XP_GetString, NULL, NULL);
-}
-
-/*
- * J A R _ s e t _ c o n t e x t
- *
- * Set the jar window context for use by PKCS11, since
- * it may be needed to prompt the user for a password.
- *
- */
-int
-JAR_set_context(JAR *jar, MWContext *mw)
-{
- if (mw) {
- jar->mw = mw;
- } else {
- /* jar->mw = XP_FindSomeContext(); */
- jar->mw = NULL;
- /*
- * We can't find a context because we're in startup state and none
- * exist yet. go get an FE_InitContext that only works at
- * initialization time.
- */
- /* Turn on the mac when we get the FE_ function */
- if (jar->mw == NULL) {
- jar->mw = jar_fn_GetInitContext();
- }
- }
- return 0;
-}
diff --git a/security/nss/lib/jar/jarsign.c b/security/nss/lib/jar/jarsign.c
deleted file mode 100644
index 9d05d9b5b..000000000
--- a/security/nss/lib/jar/jarsign.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * JARSIGN
- *
- * Routines used in signing archives.
- */
-
-
-#include "jar.h"
-#include "jarint.h"
-#include "secpkcs7.h"
-#include "pk11func.h"
-#include "sechash.h"
-
-/* from libevent.h */
-typedef void (*ETVoidPtrFunc) (void * data);
-
-/* key database wrapper */
-/* static SECKEYKeyDBHandle *jar_open_key_database (void); */
-/* CHUNQ is our bite size */
-
-#define CHUNQ 64000
-#define FILECHUNQ 32768
-
-/*
- * J A R _ c a l c u l a t e _ d i g e s t
- *
- * Quick calculation of a digest for
- * the specified block of memory. Will calculate
- * for all supported algorithms, now MD5.
- *
- * This version supports huge pointers for WIN16.
- *
- */
-JAR_Digest * PR_CALLBACK
-JAR_calculate_digest(void *data, long length)
-{
- PK11Context *md5 = 0;
- PK11Context *sha1 = 0;
- JAR_Digest *dig = PORT_ZNew(JAR_Digest);
- long chunq;
- unsigned int md5_length, sha1_length;
-
- if (dig == NULL) {
- /* out of memory allocating digest */
- return NULL;
- }
-
- md5 = PK11_CreateDigestContext(SEC_OID_MD5);
- sha1 = PK11_CreateDigestContext(SEC_OID_SHA1);
-
- if (length >= 0) {
- PK11_DigestBegin (md5);
- PK11_DigestBegin (sha1);
-
- do {
- chunq = length;
-
- PK11_DigestOp(md5, (unsigned char*)data, chunq);
- PK11_DigestOp(sha1, (unsigned char*)data, chunq);
- length -= chunq;
- data = ((char *) data + chunq);
- }
- while (length > 0);
-
- PK11_DigestFinal (md5, dig->md5, &md5_length, MD5_LENGTH);
- PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH);
-
- PK11_DestroyContext (md5, PR_TRUE);
- PK11_DestroyContext (sha1, PR_TRUE);
- }
- return dig;
-}
-
-/*
- * J A R _ d i g e s t _ f i l e
- *
- * Calculates the MD5 and SHA1 digests for a file
- * present on disk, and returns these in JAR_Digest struct.
- *
- */
-int
-JAR_digest_file (char *filename, JAR_Digest *dig)
-{
- JAR_FILE fp;
- PK11Context *md5 = 0;
- PK11Context *sha1 = 0;
- unsigned char *buf = (unsigned char *) PORT_ZAlloc (FILECHUNQ);
- int num;
- unsigned int md5_length, sha1_length;
-
- if (buf == NULL) {
- /* out of memory */
- return JAR_ERR_MEMORY;
- }
-
- if ((fp = JAR_FOPEN (filename, "rb")) == 0) {
- /* perror (filename); FIX XXX XXX XXX XXX XXX XXX */
- PORT_Free (buf);
- return JAR_ERR_FNF;
- }
-
- md5 = PK11_CreateDigestContext (SEC_OID_MD5);
- sha1 = PK11_CreateDigestContext (SEC_OID_SHA1);
-
- if (md5 == NULL || sha1 == NULL) {
- /* can't generate digest contexts */
- PORT_Free (buf);
- JAR_FCLOSE (fp);
- return JAR_ERR_GENERAL;
- }
-
- PK11_DigestBegin (md5);
- PK11_DigestBegin (sha1);
-
- while (1) {
- if ((num = JAR_FREAD (fp, buf, FILECHUNQ)) == 0)
- break;
-
- PK11_DigestOp (md5, buf, num);
- PK11_DigestOp (sha1, buf, num);
- }
-
- PK11_DigestFinal (md5, dig->md5, &md5_length, MD5_LENGTH);
- PK11_DigestFinal (sha1, dig->sha1, &sha1_length, SHA1_LENGTH);
-
- PK11_DestroyContext (md5, PR_TRUE);
- PK11_DestroyContext (sha1, PR_TRUE);
-
- PORT_Free (buf);
- JAR_FCLOSE (fp);
-
- return 0;
-}
-
-/*
- * J A R _ o p e n _ k e y _ d a t a b a s e
- *
- */
-
-void*
-jar_open_key_database(void)
-{
- return NULL;
-}
-
-int
-jar_close_key_database(void *keydb)
-{
- /* We never do close it */
- return 0;
-}
-
-
-/*
- * j a r _ c r e a t e _ p k 7
- *
- */
-
-static void jar_pk7_out (void *arg, const char *buf, unsigned long len)
-{
- JAR_FWRITE ((JAR_FILE) arg, buf, len);
-}
-
-int
-jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert,
- char *password, JAR_FILE infp, JAR_FILE outfp)
-{
- SEC_PKCS7ContentInfo *cinfo;
- const SECHashObject *hashObj;
- char *errstring;
- void *mw = NULL;
- void *hashcx;
- unsigned int len;
- int status = 0;
- SECStatus rv;
- SECItem digest;
- unsigned char digestdata[32];
- unsigned char buffer[4096];
-
- if (outfp == NULL || infp == NULL || cert == NULL)
- return JAR_ERR_GENERAL;
-
- /* we sign with SHA */
- hashObj = HASH_GetHashObject(HASH_AlgSHA1);
-
- hashcx = (* hashObj->create)();
- if (hashcx == NULL)
- return JAR_ERR_GENERAL;
-
- (* hashObj->begin)(hashcx);
- while (1) {
- int nb = JAR_FREAD(infp, buffer, sizeof buffer);
- if (nb == 0) { /* eof */
- break;
- }
- (* hashObj->update) (hashcx, buffer, nb);
- }
- (* hashObj->end)(hashcx, digestdata, &len, 32);
- (* hashObj->destroy)(hashcx, PR_TRUE);
-
- digest.data = digestdata;
- digest.len = len;
-
- /* signtool must use any old context it can find since it's
- calling from inside javaland. */
- PORT_SetError (0);
- cinfo = SEC_PKCS7CreateSignedData(cert, certUsageObjectSigner, NULL,
- SEC_OID_SHA1, &digest, NULL, mw);
- if (cinfo == NULL)
- return JAR_ERR_PK7;
-
- rv = SEC_PKCS7IncludeCertChain(cinfo, NULL);
- if (rv != SECSuccess) {
- status = PORT_GetError();
- SEC_PKCS7DestroyContentInfo(cinfo);
- return status;
- }
-
- /* Having this here forces signtool to always include signing time. */
- rv = SEC_PKCS7AddSigningTime(cinfo);
- /* don't check error */
- PORT_SetError(0);
-
- /* if calling from mozilla thread*/
- rv = SEC_PKCS7Encode(cinfo, jar_pk7_out, outfp, NULL, NULL, mw);
- if (rv != SECSuccess)
- status = PORT_GetError();
- SEC_PKCS7DestroyContentInfo (cinfo);
- if (rv != SECSuccess) {
- errstring = JAR_get_error (status);
- return ((status < 0) ? status : JAR_ERR_GENERAL);
- }
- return 0;
-}
diff --git a/security/nss/lib/jar/jarver.c b/security/nss/lib/jar/jarver.c
deleted file mode 100644
index d06b4e00c..000000000
--- a/security/nss/lib/jar/jarver.c
+++ /dev/null
@@ -1,1175 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * JARVER
- *
- * Jarnature Parsing & Verification
- */
-
-#include "nssrenam.h"
-#include "jar.h"
-#include "jarint.h"
-#include "certdb.h"
-#include "certt.h"
-#include "secpkcs7.h"
-
-/*#include "cdbhdl.h" */
-#include "secder.h"
-
-/* from certdb.h */
-#define CERTDB_USER (1<<6)
-
-#define SZ 512
-
-static int
-jar_validate_pkcs7(JAR *jar, JAR_Signer *signer, char *data, long length);
-
-static void
-jar_catch_bytes(void *arg, const char *buf, unsigned long len);
-
-static int
-jar_gather_signers(JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo);
-
-static char *
-jar_eat_line(int lines, int eating, char *data, long *len);
-
-static JAR_Digest *
-jar_digest_section(char *manifest, long length);
-
-static JAR_Digest *jar_get_mf_digest(JAR *jar, char *path);
-
-static int
-jar_parse_digital_signature(char *raw_manifest, JAR_Signer *signer,
- long length, JAR *jar);
-
-static int
-jar_add_cert(JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert);
-
-static char *jar_basename(const char *path);
-
-static int
-jar_signal(int status, JAR *jar, const char *metafile, char *pathname);
-
-#ifdef DEBUG
-static int jar_insanity_check(char *data, long length);
-#endif
-
-int
-jar_parse_mf(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url);
-
-int
-jar_parse_sf(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url);
-
-int
-jar_parse_sig(JAR *jar, const char *path, char *raw_manifest,
- long length);
-
-int
-jar_parse_any(JAR *jar, int type, JAR_Signer *signer,
- char *raw_manifest, long length, const char *path,
- const char *url);
-
-static int
-jar_internal_digest(JAR *jar, const char *path, char *x_name, JAR_Digest *dig);
-
-/*
- * J A R _ p a r s e _ m a n i f e s t
- *
- * Pass manifest files to this function. They are
- * decoded and placed into internal representations.
- *
- * Accepts both signature and manifest files. Use
- * the same "jar" for both.
- *
- */
-int
-JAR_parse_manifest(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url)
-{
- int filename_free = 0;
-
- /* fill in the path, if supplied. This is the location
- of the jar file on disk, if known */
-
- if (jar->filename == NULL && path) {
- jar->filename = PORT_Strdup(path);
- if (jar->filename == NULL)
- return JAR_ERR_MEMORY;
- filename_free = 1;
- }
-
- /* fill in the URL, if supplied. This is the place
- from which the jar file was retrieved. */
-
- if (jar->url == NULL && url) {
- jar->url = PORT_Strdup(url);
- if (jar->url == NULL) {
- if (filename_free) {
- PORT_Free(jar->filename);
- }
- return JAR_ERR_MEMORY;
- }
- }
-
- /* Determine what kind of file this is from the META-INF
- directory. It could be MF, SF, or a binary RSA/DSA file */
-
- if (!PORT_Strncasecmp (raw_manifest, "Manifest-Version:", 17)) {
- return jar_parse_mf(jar, raw_manifest, length, path, url);
- }
- else if (!PORT_Strncasecmp (raw_manifest, "Signature-Version:", 18))
- {
- return jar_parse_sf(jar, raw_manifest, length, path, url);
- } else {
- /* This is probably a binary signature */
- return jar_parse_sig(jar, path, raw_manifest, length);
- }
-}
-
-/*
- * j a r _ p a r s e _ s i g
- *
- * Pass some manner of RSA or DSA digital signature
- * on, after checking to see if it comes at an appropriate state.
- *
- */
-int
-jar_parse_sig(JAR *jar, const char *path, char *raw_manifest,
- long length)
-{
- JAR_Signer *signer;
- int status = JAR_ERR_ORDER;
-
- if (length <= 128) {
- /* signature is way too small */
- return JAR_ERR_SIG;
- }
-
- /* make sure that MF and SF have already been processed */
-
- if (jar->globalmeta == NULL)
- return JAR_ERR_ORDER;
-
- /* Determine whether or not this RSA file has
- has an associated SF file */
-
- if (path) {
- char *owner;
- owner = jar_basename(path);
-
- if (owner == NULL)
- return JAR_ERR_MEMORY;
-
- signer = jar_get_signer(jar, owner);
- PORT_Free(owner);
- } else
- signer = jar_get_signer(jar, "*");
-
- if (signer == NULL)
- return JAR_ERR_ORDER;
-
-
- /* Do not pass a huge pointer to this function,
- since the underlying security code is unaware. We will
- never pass >64k through here. */
-
- if (length > 64000) {
- /* this digital signature is way too big */
- return JAR_ERR_SIG;
- }
-
- /* don't expense unneeded calloc overhead on non-win16 */
- status = jar_parse_digital_signature(raw_manifest, signer, length, jar);
-
- return status;
-}
-
-/*
- * j a r _ p a r s e _ m f
- *
- * Parse the META-INF/manifest.mf file, whose
- * information applies to all signers.
- *
- */
-int
-jar_parse_mf(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url)
-{
- if (jar->globalmeta) {
- /* refuse a second manifest file, if passed for some reason */
- return JAR_ERR_ORDER;
- }
-
- /* remember a digest for the global section */
- jar->globalmeta = jar_digest_section(raw_manifest, length);
- if (jar->globalmeta == NULL)
- return JAR_ERR_MEMORY;
- return jar_parse_any(jar, jarTypeMF, NULL, raw_manifest, length,
- path, url);
-}
-
-/*
- * j a r _ p a r s e _ s f
- *
- * Parse META-INF/xxx.sf, a digitally signed file
- * pointing to a subset of MF sections.
- *
- */
-int
-jar_parse_sf(JAR *jar, char *raw_manifest, long length,
- const char *path, const char *url)
-{
- JAR_Signer *signer = NULL;
- int status = JAR_ERR_MEMORY;
-
- if (jar->globalmeta == NULL) {
- /* It is a requirement that the MF file be passed before the SF file */
- return JAR_ERR_ORDER;
- }
-
- signer = JAR_new_signer();
- if (signer == NULL)
- goto loser;
-
- if (path) {
- signer->owner = jar_basename(path);
- if (signer->owner == NULL)
- goto loser;
- }
-
- /* check for priors. When someone doctors a jar file
- to contain identical path entries, prevent the second
- one from affecting JAR functions */
- if (jar_get_signer(jar, signer->owner)) {
- /* someone is trying to spoof us */
- status = JAR_ERR_ORDER;
- goto loser;
- }
-
- /* remember its digest */
- signer->digest = JAR_calculate_digest (raw_manifest, length);
- if (signer->digest == NULL)
- goto loser;
-
- /* Add this signer to the jar */
- ADDITEM(jar->signers, jarTypeOwner, signer->owner, signer,
- sizeof (JAR_Signer));
-
- return jar_parse_any(jar, jarTypeSF, signer, raw_manifest, length,
- path, url);
-
-loser:
- if (signer)
- JAR_destroy_signer (signer);
- return status;
-}
-
-/*
- * j a r _ p a r s e _ a n y
- *
- * Parse a MF or SF manifest file.
- *
- */
-int
-jar_parse_any(JAR *jar, int type, JAR_Signer *signer,
- char *raw_manifest, long length, const char *path,
- const char *url)
-{
- int status;
- long raw_len;
- JAR_Digest *dig, *mfdig = NULL;
- char line [SZ];
- char x_name [SZ], x_md5 [SZ], x_sha [SZ];
- char *x_info;
- char *sf_md5 = NULL, *sf_sha1 = NULL;
-
- *x_name = 0;
- *x_md5 = 0;
- *x_sha = 0;
-
- PORT_Assert( length > 0 );
- raw_len = length;
-
-#ifdef DEBUG
- if ((status = jar_insanity_check(raw_manifest, raw_len)) < 0)
- return status;
-#endif
-
- /* null terminate the first line */
- raw_manifest = jar_eat_line(0, PR_TRUE, raw_manifest, &raw_len);
-
- /* skip over the preliminary section */
- /* This is one section at the top of the file with global metainfo */
- while (raw_len > 0) {
- JAR_Metainfo *met;
-
- raw_manifest = jar_eat_line(1, PR_TRUE, raw_manifest, &raw_len);
- if (raw_len <= 0 || !*raw_manifest)
- break;
-
- met = PORT_ZNew(JAR_Metainfo);
- if (met == NULL)
- return JAR_ERR_MEMORY;
-
- /* Parse out the header & info */
- if (PORT_Strlen (raw_manifest) >= SZ) {
- /* almost certainly nonsense */
- PORT_Free(met);
- continue;
- }
-
- PORT_Strcpy (line, raw_manifest);
- x_info = line;
-
- while (*x_info && *x_info != ' ' && *x_info != '\t' && *x_info != ':')
- x_info++;
-
- if (*x_info)
- *x_info++ = 0;
-
- while (*x_info == ' ' || *x_info == '\t')
- x_info++;
-
- /* metainfo (name, value) pair is now (line, x_info) */
- met->header = PORT_Strdup(line);
- met->info = PORT_Strdup(x_info);
-
- if (type == jarTypeMF) {
- ADDITEM (jar->metainfo, jarTypeMeta,
- /* pathname */ NULL, met, sizeof (JAR_Metainfo));
- }
-
- /* For SF files, this metadata may be the digests
- of the MF file, still in the "met" structure. */
-
- if (type == jarTypeSF) {
- if (!PORT_Strcasecmp(line, "MD5-Digest"))
- sf_md5 = (char *) met->info;
-
- if (!PORT_Strcasecmp(line, "SHA1-Digest") ||
- !PORT_Strcasecmp(line, "SHA-Digest"))
- sf_sha1 = (char *) met->info;
- }
-
- if (type != jarTypeMF) {
- PORT_Free(met->header);
- if (type != jarTypeSF) {
- PORT_Free(met->info);
- }
- PORT_Free(met);
- }
- }
-
- if (type == jarTypeSF && jar->globalmeta) {
- /* this is a SF file which may contain a digest of the manifest.mf's
- global metainfo. */
-
- int match = 0;
- JAR_Digest *glob = jar->globalmeta;
-
- if (sf_md5) {
- unsigned int md5_length;
- unsigned char *md5_digest;
-
- md5_digest = ATOB_AsciiToData (sf_md5, &md5_length);
- PORT_Assert( md5_length == MD5_LENGTH );
-
- if (md5_length != MD5_LENGTH)
- return JAR_ERR_CORRUPT;
-
- match = PORT_Memcmp(md5_digest, glob->md5, MD5_LENGTH);
- }
-
- if (sf_sha1 && match == 0) {
- unsigned int sha1_length;
- unsigned char *sha1_digest;
-
- sha1_digest = ATOB_AsciiToData (sf_sha1, &sha1_length);
- PORT_Assert( sha1_length == SHA1_LENGTH );
-
- if (sha1_length != SHA1_LENGTH)
- return JAR_ERR_CORRUPT;
-
- match = PORT_Memcmp(sha1_digest, glob->sha1, SHA1_LENGTH);
- }
-
- if (match != 0) {
- /* global digest doesn't match, SF file therefore invalid */
- jar->valid = JAR_ERR_METADATA;
- return JAR_ERR_METADATA;
- }
- }
-
- /* done with top section of global data */
- while (raw_len > 0) {
- *x_md5 = 0;
- *x_sha = 0;
- *x_name = 0;
-
- /* If this is a manifest file, attempt to get a digest of the following
- section, without damaging it. This digest will be saved later. */
-
- if (type == jarTypeMF) {
- char *sec;
- long sec_len = raw_len;
-
- if (!*raw_manifest || *raw_manifest == '\n') {
- /* skip the blank line */
- sec = jar_eat_line(1, PR_FALSE, raw_manifest, &sec_len);
- } else
- sec = raw_manifest;
-
- if (sec_len > 0 && !PORT_Strncasecmp(sec, "Name:", 5)) {
- if (type == jarTypeMF)
- mfdig = jar_digest_section(sec, sec_len);
- else
- mfdig = NULL;
- }
- }
-
-
- while (raw_len > 0) {
- raw_manifest = jar_eat_line(1, PR_TRUE, raw_manifest, &raw_len);
- if (raw_len <= 0 || !*raw_manifest)
- break; /* blank line, done with this entry */
-
- if (PORT_Strlen(raw_manifest) >= SZ) {
- /* almost certainly nonsense */
- continue;
- }
-
- /* Parse out the name/value pair */
- PORT_Strcpy(line, raw_manifest);
- x_info = line;
-
- while (*x_info && *x_info != ' ' && *x_info != '\t' &&
- *x_info != ':')
- x_info++;
-
- if (*x_info)
- *x_info++ = 0;
-
- while (*x_info == ' ' || *x_info == '\t')
- x_info++;
-
- if (!PORT_Strcasecmp(line, "Name"))
- PORT_Strcpy(x_name, x_info);
- else if (!PORT_Strcasecmp(line, "MD5-Digest"))
- PORT_Strcpy(x_md5, x_info);
- else if (!PORT_Strcasecmp(line, "SHA1-Digest")
- || !PORT_Strcasecmp(line, "SHA-Digest"))
- PORT_Strcpy(x_sha, x_info);
-
- /* Algorithm list is meta info we don't care about; keeping it out
- of metadata saves significant space for large jar files */
- else if (!PORT_Strcasecmp(line, "Digest-Algorithms")
- || !PORT_Strcasecmp(line, "Hash-Algorithms"))
- continue;
-
- /* Meta info is only collected for the manifest.mf file,
- since the JAR_get_metainfo call does not support identity */
- else if (type == jarTypeMF) {
- JAR_Metainfo *met;
-
- /* this is meta-data */
- met = PORT_ZNew(JAR_Metainfo);
- if (met == NULL)
- return JAR_ERR_MEMORY;
-
- /* metainfo (name, value) pair is now (line, x_info) */
- if ((met->header = PORT_Strdup(line)) == NULL) {
- PORT_Free(met);
- return JAR_ERR_MEMORY;
- }
-
- if ((met->info = PORT_Strdup(x_info)) == NULL) {
- PORT_Free(met->header);
- PORT_Free(met);
- return JAR_ERR_MEMORY;
- }
-
- ADDITEM (jar->metainfo, jarTypeMeta,
- x_name, met, sizeof (JAR_Metainfo));
- }
- }
-
- if (!*x_name) {
- /* Whatever that was, it wasn't an entry, because we didn't get a
- name. We don't really have anything, so don't record this. */
- continue;
- }
-
- dig = PORT_ZNew(JAR_Digest);
- if (dig == NULL)
- return JAR_ERR_MEMORY;
-
- if (*x_md5) {
- unsigned int binary_length;
- unsigned char *binary_digest;
-
- binary_digest = ATOB_AsciiToData (x_md5, &binary_length);
- PORT_Assert( binary_length == MD5_LENGTH );
- if (binary_length != MD5_LENGTH) {
- PORT_Free(dig);
- return JAR_ERR_CORRUPT;
- }
- memcpy (dig->md5, binary_digest, MD5_LENGTH);
- dig->md5_status = jarHashPresent;
- }
-
- if (*x_sha ) {
- unsigned int binary_length;
- unsigned char *binary_digest;
-
- binary_digest = ATOB_AsciiToData (x_sha, &binary_length);
- PORT_Assert( binary_length == SHA1_LENGTH );
- if (binary_length != SHA1_LENGTH) {
- PORT_Free(dig);
- return JAR_ERR_CORRUPT;
- }
- memcpy (dig->sha1, binary_digest, SHA1_LENGTH);
- dig->sha1_status = jarHashPresent;
- }
-
- PORT_Assert( type == jarTypeMF || type == jarTypeSF );
- if (type == jarTypeMF) {
- ADDITEM (jar->hashes, jarTypeMF, x_name, dig, sizeof (JAR_Digest));
- } else if (type == jarTypeSF) {
- ADDITEM (signer->sf, jarTypeSF, x_name, dig, sizeof (JAR_Digest));
- } else {
- PORT_Free(dig);
- return JAR_ERR_ORDER;
- }
-
- /* we're placing these calculated digests of manifest.mf
- sections in a list where they can subsequently be forgotten */
- if (type == jarTypeMF && mfdig) {
- ADDITEM (jar->manifest, jarTypeSect,
- x_name, mfdig, sizeof (JAR_Digest));
- mfdig = NULL;
- }
-
- /* Retrieve our saved SHA1 digest from saved copy and check digests.
- This is just comparing the digest of the MF section as indicated in
- the SF file with the one we remembered from parsing the MF file */
-
- if (type == jarTypeSF) {
- if ((status = jar_internal_digest(jar, path, x_name, dig)) < 0)
- return status;
- }
- }
-
- return 0;
-}
-
-static int
-jar_internal_digest(JAR *jar, const char *path, char *x_name, JAR_Digest *dig)
-{
- int cv;
- int status;
-
- JAR_Digest *savdig;
-
- savdig = jar_get_mf_digest(jar, x_name);
- if (savdig == NULL) {
- /* no .mf digest for this pathname */
- status = jar_signal(JAR_ERR_ENTRY, jar, path, x_name);
- if (status < 0)
- return 0; /* was continue; */
- return status;
- }
-
- /* check for md5 consistency */
- if (dig->md5_status) {
- cv = PORT_Memcmp(savdig->md5, dig->md5, MD5_LENGTH);
- /* md5 hash of .mf file is not what expected */
- if (cv) {
- status = jar_signal(JAR_ERR_HASH, jar, path, x_name);
-
- /* bad hash, man */
- dig->md5_status = jarHashBad;
- savdig->md5_status = jarHashBad;
-
- if (status < 0)
- return 0; /* was continue; */
- return status;
- }
- }
-
- /* check for sha1 consistency */
- if (dig->sha1_status) {
- cv = PORT_Memcmp(savdig->sha1, dig->sha1, SHA1_LENGTH);
- /* sha1 hash of .mf file is not what expected */
- if (cv) {
- status = jar_signal(JAR_ERR_HASH, jar, path, x_name);
-
- /* bad hash, man */
- dig->sha1_status = jarHashBad;
- savdig->sha1_status = jarHashBad;
-
- if (status < 0)
- return 0; /* was continue; */
- return status;
- }
- }
- return 0;
-}
-
-#ifdef DEBUG
-/*
- * j a r _ i n s a n i t y _ c h e c k
- *
- * Check for illegal characters (or possibly so)
- * in the manifest files, to detect potential memory
- * corruption by our neighbors. Debug only, since
- * not I18N safe.
- *
- */
-static int
-jar_insanity_check(char *data, long length)
-{
- int c;
- long off;
-
- for (off = 0; off < length; off++) {
- c = data [off];
- if (c == '\n' || c == '\r' || (c >= ' ' && c <= 128))
- continue;
- return JAR_ERR_CORRUPT;
- }
- return 0;
-}
-#endif
-
-/*
- * j a r _ p a r s e _ d i g i t a l _ s i g n a t u r e
- *
- * Parse an RSA or DSA (or perhaps other) digital signature.
- * Right now everything is PKCS7.
- *
- */
-static int
-jar_parse_digital_signature(char *raw_manifest, JAR_Signer *signer,
- long length, JAR *jar)
-{
- return jar_validate_pkcs7 (jar, signer, raw_manifest, length);
-}
-
-/*
- * j a r _ a d d _ c e r t
- *
- * Add information for the given certificate
- * (or whatever) to the JAR linked list. A pointer
- * is passed for some relevant reference, say
- * for example the original certificate.
- *
- */
-static int
-jar_add_cert(JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert)
-{
- JAR_Cert *fing;
- unsigned char *keyData;
-
- if (cert == NULL)
- return JAR_ERR_ORDER;
-
- fing = PORT_ZNew(JAR_Cert);
- if (fing == NULL)
- goto loser;
-
- fing->cert = CERT_DupCertificate (cert);
-
- /* get the certkey */
- fing->length = cert->derIssuer.len + 2 + cert->serialNumber.len;
- fing->key = keyData = (unsigned char *) PORT_ZAlloc(fing->length);
- if (fing->key == NULL)
- goto loser;
- keyData[0] = ((cert->derIssuer.len) >> 8) & 0xff;
- keyData[1] = ((cert->derIssuer.len) & 0xff);
- PORT_Memcpy(&keyData[2], cert->derIssuer.data, cert->derIssuer.len);
- PORT_Memcpy(&keyData[2+cert->derIssuer.len], cert->serialNumber.data,
- cert->serialNumber.len);
-
- ADDITEM (signer->certs, type, NULL, fing, sizeof (JAR_Cert));
- return 0;
-
-loser:
- if (fing) {
- if (fing->cert)
- CERT_DestroyCertificate (fing->cert);
- PORT_Free(fing);
- }
- return JAR_ERR_MEMORY;
-}
-
-/*
- * e a t _ l i n e
- *
- * Reads and/or modifies input buffer "data" of length "*len".
- * This function does zero, one or two of the following tasks:
- * 1) if "lines" is non-zero, it reads and discards that many lines from
- * the input. NUL characters are treated as end-of-line characters,
- * not as end-of-input characters. The input is NOT NUL terminated.
- * Note: presently, all callers pass either 0 or 1 for lines.
- * 2) After skipping the specified number of input lines, if "eating" is
- * non-zero, it finds the end of the next line of input and replaces
- * the end of line character(s) with a NUL character.
- * This function modifies the input buffer, containing the file, in place.
- * This function handles PC, Mac, and Unix style text files.
- * On entry, *len contains the maximum number of characters that this
- * function should ever examine, starting with the character in *data.
- * On return, *len is reduced by the number of characters skipped by the
- * first task, if any;
- * If lines is zero and eating is false, this function returns
- * the value in the data argument, but otherwise does nothing.
- */
-static char *
-jar_eat_line(int lines, int eating, char *data, long *len)
-{
- char *start = data;
- long maxLen = *len;
-
- if (maxLen <= 0)
- return start;
-
-#define GO_ON ((data - start) < maxLen)
-
- /* Eat the requisite number of lines, if any;
- prior to terminating the current line with a 0. */
- for (/* yip */ ; lines > 0; lines--) {
- while (GO_ON && *data && *data != '\r' && *data != '\n')
- data++;
-
- /* Eat any leading CR */
- if (GO_ON && *data == '\r')
- data++;
-
- /* After the CR, ok to eat one LF */
- if (GO_ON && *data == '\n')
- data++;
-
- /* If there are NULs, this function probably put them there */
- while (GO_ON && !*data)
- data++;
- }
- maxLen -= data - start; /* we have this many characters left. */
- *len = maxLen;
- start = data; /* now start again here. */
- if (maxLen > 0 && eating) {
- /* Terminate this line with a 0 */
- while (GO_ON && *data && *data != '\n' && *data != '\r')
- data++;
-
- /* If not past the end, we are allowed to eat one CR */
- if (GO_ON && *data == '\r')
- *data++ = 0;
-
- /* After the CR (if any), if not past the end, ok to eat one LF */
- if (GO_ON && *data == '\n')
- *data++ = 0;
- }
- return start;
-}
-#undef GO_ON
-
-/*
- * j a r _ d i g e s t _ s e c t i o n
- *
- * Return the digests of the next section of the manifest file.
- * Does not damage the manifest file, unlike parse_manifest.
- *
- */
-static JAR_Digest *
-jar_digest_section(char *manifest, long length)
-{
- long global_len;
- char *global_end;
-
- global_end = manifest;
- global_len = length;
-
- while (global_len > 0) {
- global_end = jar_eat_line(1, PR_FALSE, global_end, &global_len);
- if (global_len > 0 && (*global_end == 0 || *global_end == '\n'))
- break;
- }
- return JAR_calculate_digest (manifest, global_end - manifest);
-}
-
-/*
- * J A R _ v e r i f y _ d i g e s t
- *
- * Verifies that a precalculated digest matches the
- * expected value in the manifest.
- *
- */
-int PR_CALLBACK
-JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig)
-{
- JAR_Item *it;
- JAR_Digest *shindig;
- ZZLink *link;
- ZZList *list = jar->hashes;
- int result1 = 0;
- int result2 = 0;
-
-
- if (jar->valid < 0) {
- /* signature not valid */
- return JAR_ERR_SIG;
- }
- if (ZZ_ListEmpty (list)) {
- /* empty list */
- return JAR_ERR_PNF;
- }
-
- for (link = ZZ_ListHead (list);
- !ZZ_ListIterDone (list, link);
- link = link->next) {
- it = link->thing;
- if (it->type == jarTypeMF
- && it->pathname && !PORT_Strcmp(it->pathname, name)) {
- shindig = (JAR_Digest *) it->data;
- if (shindig->md5_status) {
- if (shindig->md5_status == jarHashBad)
- return JAR_ERR_HASH;
- result1 = memcmp (dig->md5, shindig->md5, MD5_LENGTH);
- }
- if (shindig->sha1_status) {
- if (shindig->sha1_status == jarHashBad)
- return JAR_ERR_HASH;
- result2 = memcmp (dig->sha1, shindig->sha1, SHA1_LENGTH);
- }
- return (result1 == 0 && result2 == 0) ? 0 : JAR_ERR_HASH;
- }
- }
- return JAR_ERR_PNF;
-}
-
-
-
-
-
-
-
-/*
- * J A R _ f e t c h _ c e r t
- *
- * Given an opaque identifier of a certificate,
- * return the full certificate.
- *
- * The new function, which retrieves by key.
- *
- */
-CERTCertificate *
-JAR_fetch_cert(long length, void *key)
-{
- CERTIssuerAndSN issuerSN;
- CERTCertificate *cert = NULL;
- CERTCertDBHandle *certdb;
-
- certdb = JAR_open_database();
- if (certdb) {
- unsigned char *keyData = (unsigned char *)key;
- issuerSN.derIssuer.len = (keyData[0] << 8) + keyData[0];
- issuerSN.derIssuer.data = &keyData[2];
- issuerSN.serialNumber.len = length - (2 + issuerSN.derIssuer.len);
- issuerSN.serialNumber.data = &keyData[2+issuerSN.derIssuer.len];
- cert = CERT_FindCertByIssuerAndSN (certdb, &issuerSN);
- JAR_close_database (certdb);
- }
- return cert;
-}
-
-/*
- * j a r _ g e t _ m f _ d i g e s t
- *
- * Retrieve a corresponding saved digest over a section
- * of the main manifest file.
- *
- */
-static JAR_Digest *
-jar_get_mf_digest(JAR *jar, char *pathname)
-{
- JAR_Item *it;
- JAR_Digest *dig;
- ZZLink *link;
- ZZList *list = jar->manifest;
-
- if (ZZ_ListEmpty (list))
- return NULL;
-
- for (link = ZZ_ListHead (list);
- !ZZ_ListIterDone (list, link);
- link = link->next) {
- it = link->thing;
- if (it->type == jarTypeSect
- && it->pathname && !PORT_Strcmp(it->pathname, pathname)) {
- dig = (JAR_Digest *) it->data;
- return dig;
- }
- }
- return NULL;
-}
-
-/*
- * j a r _ b a s e n a m e
- *
- * Return the basename -- leading components of path stripped off,
- * extension ripped off -- of a path.
- *
- */
-static char *
-jar_basename(const char *path)
-{
- char *pith, *e, *basename, *ext;
-
- if (path == NULL)
- return PORT_Strdup("");
-
- pith = PORT_Strdup(path);
- basename = pith;
- while (1) {
- for (e = basename; *e && *e != '/' && *e != '\\'; e++)
- /* yip */ ;
- if (*e)
- basename = ++e;
- else
- break;
- }
-
- if ((ext = PORT_Strrchr(basename, '.')) != NULL)
- *ext = 0;
-
- /* We already have the space allocated */
- PORT_Strcpy(pith, basename);
- return pith;
-}
-
-/*
- * + + + + + + + + + + + + + + +
- *
- * CRYPTO ROUTINES FOR JAR
- *
- * The following functions are the cryptographic
- * interface to PKCS7 for Jarnatures.
- *
- * + + + + + + + + + + + + + + +
- *
- */
-
-/*
- * j a r _ c a t c h _ b y t e s
- *
- * In the event signatures contain enveloped data, it will show up here.
- * But note that the lib/pkcs7 routines aren't ready for it.
- *
- */
-static void
-jar_catch_bytes(void *arg, const char *buf, unsigned long len)
-{
- /* Actually this should never be called, since there is
- presumably no data in the signature itself. */
-}
-
-/*
- * j a r _ v a l i d a t e _ p k c s 7
- *
- * Validate (and decode, if necessary) a binary pkcs7
- * signature in DER format.
- *
- */
-static int
-jar_validate_pkcs7(JAR *jar, JAR_Signer *signer, char *data, long length)
-{
-
- SEC_PKCS7ContentInfo *cinfo = NULL;
- SEC_PKCS7DecoderContext *dcx;
- PRBool goodSig;
- int status = 0;
- SECItem detdig;
-
- PORT_Assert( jar != NULL && signer != NULL );
-
- if (jar == NULL || signer == NULL)
- return JAR_ERR_ORDER;
-
- signer->valid = JAR_ERR_SIG;
-
- /* We need a context if we can get one */
- dcx = SEC_PKCS7DecoderStart(jar_catch_bytes, NULL /*cb_arg*/,
- NULL /*getpassword*/, jar->mw,
- NULL, NULL, NULL);
- if (dcx == NULL) {
- /* strange pkcs7 failure */
- return JAR_ERR_PK7;
- }
-
- SEC_PKCS7DecoderUpdate (dcx, data, length);
- cinfo = SEC_PKCS7DecoderFinish (dcx);
- if (cinfo == NULL) {
- /* strange pkcs7 failure */
- return JAR_ERR_PK7;
- }
- if (SEC_PKCS7ContentIsEncrypted (cinfo)) {
- /* content was encrypted, fail */
- return JAR_ERR_PK7;
- }
- if (SEC_PKCS7ContentIsSigned (cinfo) == PR_FALSE) {
- /* content was not signed, fail */
- return JAR_ERR_PK7;
- }
-
- PORT_SetError(0);
-
- /* use SHA1 only */
- detdig.len = SHA1_LENGTH;
- detdig.data = signer->digest->sha1;
- goodSig = SEC_PKCS7VerifyDetachedSignature(cinfo,
- certUsageObjectSigner,
- &detdig, HASH_AlgSHA1,
- PR_FALSE);
- jar_gather_signers(jar, signer, cinfo);
- if (goodSig == PR_TRUE) {
- /* signature is valid */
- signer->valid = 0;
- } else {
- status = PORT_GetError();
- PORT_Assert( status < 0 );
- if (status >= 0)
- status = JAR_ERR_SIG;
- jar->valid = status;
- signer->valid = status;
- }
- jar->pkcs7 = PR_TRUE;
- signer->pkcs7 = PR_TRUE;
- SEC_PKCS7DestroyContentInfo(cinfo);
- return status;
-}
-
-/*
- * j a r _ g a t h e r _ s i g n e r s
- *
- * Add the single signer of this signature to the
- * certificate linked list.
- *
- */
-static int
-jar_gather_signers(JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo)
-{
- int result;
- CERTCertificate *cert;
- CERTCertDBHandle *certdb;
- SEC_PKCS7SignedData *sdp = cinfo->content.signedData;
- SEC_PKCS7SignerInfo **pksigners, *pksigner;
-
- if (sdp == NULL)
- return JAR_ERR_PK7;
-
- pksigners = sdp->signerInfos;
- /* permit exactly one signer */
- if (pksigners == NULL || pksigners [0] == NULL || pksigners [1] != NULL)
- return JAR_ERR_PK7;
-
- pksigner = *pksigners;
- cert = pksigner->cert;
-
- if (cert == NULL)
- return JAR_ERR_PK7;
-
- certdb = JAR_open_database();
- if (certdb == NULL)
- return JAR_ERR_GENERAL;
-
- result = jar_add_cert(jar, signer, jarTypeSign, cert);
- JAR_close_database (certdb);
- return result;
-}
-
-/*
- * j a r _ o p e n _ d a t a b a s e
- *
- * Open the certificate database,
- * for use by JAR functions.
- *
- */
-CERTCertDBHandle *
-JAR_open_database(void)
-{
- return CERT_GetDefaultCertDB();
-}
-
-/*
- * j a r _ c l o s e _ d a t a b a s e
- *
- * Close the certificate database.
- * For use by JAR functions.
- *
- */
-int
-JAR_close_database(CERTCertDBHandle *certdb)
-{
- return 0;
-}
-
-
-/*
- * j a r _ s i g n a l
- *
- * Nonfatal errors come here to callback Java.
- *
- */
-static int
-jar_signal(int status, JAR *jar, const char *metafile, char *pathname)
-{
- char *errstring = JAR_get_error (status);
- if (jar->signal) {
- (*jar->signal) (status, jar, metafile, pathname, errstring);
- return 0;
- }
- return status;
-}
-
-/*
- * j a r _ a p p e n d
- *
- * Tack on an element to one of a JAR's linked
- * lists, with rudimentary error handling.
- *
- */
-int
-jar_append(ZZList *list, int type, char *pathname, void *data, size_t size)
-{
- JAR_Item *it = PORT_ZNew(JAR_Item);
- ZZLink *entity;
-
- if (it == NULL)
- goto loser;
-
- if (pathname) {
- it->pathname = PORT_Strdup(pathname);
- if (it->pathname == NULL)
- goto loser;
- }
-
- it->type = (jarType)type;
- it->data = (unsigned char *) data;
- it->size = size;
- entity = ZZ_NewLink (it);
- if (entity) {
- ZZ_AppendLink (list, entity);
- return 0;
- }
-
-loser:
- if (it) {
- if (it->pathname)
- PORT_Free(it->pathname);
- PORT_Free(it);
- }
- return JAR_ERR_MEMORY;
-}
diff --git a/security/nss/lib/jar/jzconf.h b/security/nss/lib/jar/jzconf.h
deleted file mode 100644
index 278aaa5d5..000000000
--- a/security/nss/lib/jar/jzconf.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-1996 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-/* This file was modified since it was taken from the zlib distribution */
-/* $Id$ */
-
-#ifndef _ZCONF_H
-#define _ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateReset z_inflateReset
-# define compress z_compress
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-# define WIN32
-#endif
-#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-# ifndef __32BIT__
-# define __32BIT__
-# endif
-#endif
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#if defined(MSDOS) && !defined(__32BIT__)
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32) || defined(XP_OS2)) && !defined(STDC)
-# define STDC
-#endif
-#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC)
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- 1 << (windowBits+2) + 1 << (memLevel+9)
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR __far
-# else
-# define FAR far
-# endif
-#endif
-#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-# ifndef __32BIT__
-# define SMALL_MEDIUM
-# define FAR __far
-# endif
-#endif
-#ifndef FAR
-# define FAR
-#endif
-
-typedef unsigned char Byte; /* 8 bits */
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#if defined(__BORLANDC__) && defined(SMALL_MEDIUM)
- /* Borland C/C++ ignores FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#ifdef MOZILLA_CLIENT
-#include "prtypes.h"
-#else
-/* Compile with -DZLIB_DLL for Windows DLL support */
-#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
-# include <windows.h>
-# define EXPORT WINAPI
-#else
-# define EXPORT
-#endif
-
-#define PR_PUBLIC_API(type) type
-
-#endif /* MOZILLA_CLIENT */
-
-#endif /* _ZCONF_H */
diff --git a/security/nss/lib/jar/jzlib.h b/security/nss/lib/jar/jzlib.h
deleted file mode 100644
index dd5b4d8e9..000000000
--- a/security/nss/lib/jar/jzlib.h
+++ /dev/null
@@ -1,896 +0,0 @@
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.0.4, Jul 24th, 1996.
-
- Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- gzip@prep.ai.mit.edu madler@alumni.caltech.edu
-
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-/* This file was modified since it was taken from the zlib distribution */
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef MOZILLA_CLIENT
-#include "jzconf.h"
-#else
-#include "zconf.h"
-#endif
-
-#define ZLIB_VERSION "1.0.4"
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms may be added later and will have the same
- stream interface.
-
- For compression the application must provide the output buffer and
- may optionally provide the input buffer for optimization. For decompression,
- the application must provide the input buffer and may optionally provide
- the output buffer for optimization.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-
- The library does not install any signal handler. It is recommended to
- add at least a handler for SIGSEGV when decompressing; the library checks
- the consistency of the input data whenever possible but may go nuts
- for some forms of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidpf opaque; /* private data object passed to zalloc and zfree */
-
- int data_type; /* best guess about the data type: ascii or binary */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-/* Allowed flush values; see deflate() below for details */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_NEED_DICT 2
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION 0
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_ASCII 1
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field */
-
-#define Z_DEFLATED 8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
- /* basic functions */
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern const char *) zlibVersion (void);
-#else
-extern const char * EXPORT zlibVersion OF((void));
-#endif
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
- */
-
-/*
-extern int EXPORT deflateInit OF((z_streamp strm, int level));
-
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
-
- The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
-
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
- Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
-*/
-
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) deflate (z_streamp strm, int flush);
-#else
-extern int EXPORT deflate OF((z_streamp strm, int flush));
-#endif
-/*
- Performs one or both of the following actions:
-
- - Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in and avail_in are updated and
- processing will resume at this point for the next call of deflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
-
- If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression
- block is terminated and flushed to the output buffer so that the
- decompressor can get all input data available so far. For method 9, a future
- variant on method 8, the current block will be flushed but not terminated.
- Z_SYNC_FLUSH has the same effect as partial flush except that the compressed
- output is byte aligned (the compressor can clear its internal bit buffer)
- and the current block is always terminated; this can be useful if the
- compressor has to be restarted from scratch after an interruption (in which
- case the internal state of the compressor may be lost).
- If flush is set to Z_FULL_FLUSH, the compression block is terminated, a
- special marker is output and the compression dictionary is discarded; this
- is useful to allow the decompressor to synchronize if one compressed block
- has been damaged (see inflateSync below). Flushing degrades compression and
- so should be used only when necessary. Using Z_FULL_FLUSH too often can
- seriously degrade the compression. If deflate returns with avail_out == 0,
- this function must be called again with the same value of the flush
- parameter and more output space (updated avail_out), until the flush is
- complete (deflate returns with non-zero avail_out).
-
- If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- 0.1% larger than avail_in plus 12 bytes. If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() may update data_type if it can make a good guess about
- the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
-
- deflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if all input has been
- consumed and all output has been produced (only when flush is set to
- Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible.
-*/
-
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) deflateEnd (z_streamp strm);
-#else
-extern int EXPORT deflateEnd OF((z_streamp strm));
-#endif
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
- stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
- deallocated).
-*/
-
-
-/*
-extern int EXPORT inflateInit OF((z_streamp strm));
-
- Initializes the internal stream state for decompression. The fields
- zalloc, zfree and opaque must be initialized before by the caller. If
- zalloc and zfree are set to Z_NULL, inflateInit updates them to use default
- allocation functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_VERSION_ERROR if the zlib library version is incompatible
- with the version assumed by the caller. msg is set to null if there is no
- error message. inflateInit does not perform any decompression: this will be
- done by inflate().
-*/
-
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) inflate (z_streamp strm, int flush);
-#else
-extern int EXPORT inflate OF((z_streamp strm, int flush));
-#endif
-/*
- Performs one or both of the following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- If the parameter flush is set to Z_PARTIAL_FLUSH, inflate flushes as much
- output as possible to the output buffer. The flushing behavior of inflate is
- not specified for values of the flush parameter other than Z_PARTIAL_FLUSH
- and Z_FINISH, but the current implementation actually flushes as much output
- as possible anyway.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster routine
- may be used for the single inflate() call.
-
- inflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if the end of the
- compressed data has been reached and all uncompressed output has been
- produced, Z_NEED_DICT if a preset dictionary is needed at this point (see
- inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted,
- Z_STREAM_ERROR if the stream structure was inconsistent (for example if
- next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
- Z_BUF_ERROR if no progress is possible or if there was not enough room in
- the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the
- application may then call inflateSync to look for a good compression block.
- In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the
- dictionary chosen by the compressor.
-*/
-
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) inflateEnd (z_streamp strm);
-#else
-extern int EXPORT inflateEnd OF((z_streamp strm));
-#endif
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* Advanced functions */
-
-/*
- The following functions are needed only in some special applications.
-*/
-
-/*
-extern int EXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
-
- The method parameter is the compression method. It must be Z_DEFLATED in
- this version of the library. (Method 9 will allow a 64K history buffer and
- partial block flushes.)
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library (the value 16 will be allowed for method 9). Larger
- values of this parameter result in better compression at the expense of
- memory usage. The default value is 15 if deflateInit is used instead.
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
- filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match). Filtered data consists mostly of small values with a
- somewhat random distribution. In this case, the compression algorithm is
- tuned to compress them better. The effect of Z_FILTERED is to force more
- Huffman coding and less string matching; it is somewhat intermediate
- between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
- the compression ratio but not the correctness of the compressed output even
- if it is not set appropriately.
-
- If next_in is not null, the library will use this buffer to hold also
- some history information; the buffer must either hold the entire input
- data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in
- is null, the library will allocate its own history buffer (and leave next_in
- null). next_out need not be provided here but must be provided by the
- application for the next call of deflate().
-
- If the history buffer is provided by the application, next_in must
- must never be changed by the application since the compressor maintains
- information inside this buffer from call to call; the application
- must provide more input only by increasing avail_in. next_in is always
- reset by the library in this case.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
- not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
- an invalid method). msg is set to null if there is no error message.
- deflateInit2 does not perform any compression: this will be done by
- deflate().
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) deflateSetDictionary (z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength);
-#else
-extern int EXPORT deflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-#endif
-/*
- Initializes the compression dictionary (history buffer) from the given
- byte sequence without producing any compressed output. This function must
- be called immediately after deflateInit or deflateInit2, before any call
- of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and
- can be predicted with good accuracy; the data can then be compressed better
- than with the default empty dictionary. In this version of the library,
- only the last 32K bytes of the dictionary are used.
- Upon return of this function, strm->adler is set to the Adler32 value
- of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The Adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.)
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state
- is inconsistent (for example if deflate has already been called for this
- stream). deflateSetDictionary does not perform any compression: this will
- be done by deflate().
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) deflateCopy (z_streamp dest, z_streamp source);
-#else
-extern int EXPORT deflateCopy OF((z_streamp dest, z_streamp source));
-#endif
-/*
- Sets the destination stream as a complete copy of the source stream. If
- the source stream is using an application-supplied history buffer, a new
- buffer is allocated for the destination stream. The compressed output
- buffer is always application-supplied. It's the responsibility of the
- application to provide the correct values of next_out and avail_out for the
- next call of deflate.
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
-
- deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) deflateReset (z_streamp strm);
-#else
-extern int EXPORT deflateReset OF((z_streamp strm));
-#endif
-/*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
-
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) deflateParams (z_streamp strm, int level, int strategy);
-#else
-extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy));
-#endif
-/*
- Dynamically update the compression level and compression strategy.
- This can be used to switch between compression and straight copy of
- the input data, or to switch to a different kind of input data requiring
- a different strategy. If the compression level is changed, the input
- available so far is compressed with the old level (and may be flushed);
- the new level will take effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
-*/
-
-/*
-extern int EXPORT inflateInit2 OF((z_streamp strm,
- int windowBits));
-
- This is another version of inflateInit with more compression options. The
- fields next_out, zalloc, zfree and opaque must be initialized before by
- the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library (the value 16 will be allowed soon). The
- default value is 15 if inflateInit is used instead. If a compressed stream
- with a larger window size is given as input, inflate() will return with
- the error code Z_DATA_ERROR instead of trying to allocate a larger window.
-
- If next_out is not null, the library will use this buffer for the history
- buffer; the buffer must either be large enough to hold the entire output
- data, or have at least 1<<windowBits bytes. If next_out is null, the
- library will allocate its own buffer (and leave next_out null). next_in
- need not be provided here but must be provided by the application for the
- next call of inflate().
-
- If the history buffer is provided by the application, next_out must
- never be changed by the application since the decompressor maintains
- history information inside this buffer from call to call; the application
- can only reset next_out to the beginning of the history buffer when
- avail_out is zero and all output has been consumed.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
- not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
- windowBits < 8). msg is set to null if there is no error message.
- inflateInit2 does not perform any decompression: this will be done by
- inflate().
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) inflateSetDictionary (z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength);
-#else
-extern int EXPORT inflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-#endif
-/*
- Initializes the decompression dictionary (history buffer) from the given
- uncompressed byte sequence. This function must be called immediately after
- a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen
- by the compressor can be determined from the Adler32 value returned by this
- call of inflate. The compressor and decompressor must use exactly the same
- dictionary (see deflateSetDictionary).
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect Adler32 value). inflateSetDictionary does not
- perform any decompression: this will be done by subsequent calls of
- inflate().
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) inflateSync (z_streamp strm);
-#else
-extern int EXPORT inflateSync OF((z_streamp strm));
-#endif
-/*
- Skips invalid compressed data until the special marker (see deflate()
- above) can be found, or until all available input is skipped. No output
- is provided.
-
- inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no marker has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) inflateReset (z_streamp strm);
-#else
-extern int EXPORT inflateReset OF((z_streamp strm));
-#endif
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-
- /* utility functions */
-
-/*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level, window size,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) compress (Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen);
-#else
-extern int EXPORT compress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-#endif
-/*
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least 0.1% larger than
- sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
- compress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer.
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) uncompress (Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen);
-#else
-extern int EXPORT uncompress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-#endif
-/*
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-
-
-typedef voidp gzFile;
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern gzFile) gzopen (const char *path, const char *mode);
-#else
-extern gzFile EXPORT gzopen OF((const char *path, const char *mode));
-#endif
-/*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9"). gzopen can be used to read a file which is not in gzip format;
- in this case gzread will directly read from the file without decompression.
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern gzFile) gzdopen (int fd, const char *mode);
-#else
-extern gzFile EXPORT gzdopen OF((int fd, const char *mode));
-#endif
-/*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) gzread (gzFile file, voidp buf, unsigned len);
-#else
-extern int EXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-#endif
-/*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) gzwrite (gzFile file, const voidp buf, unsigned len);
-#else
-extern int EXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len));
-#endif
-/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) gzflush (gzFile file, int flush);
-#else
-extern int EXPORT gzflush OF((gzFile file, int flush));
-#endif
-/*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) gzclose (gzFile file);
-#else
-extern int EXPORT gzclose OF((gzFile file));
-#endif
-/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern const char *) gzerror (gzFile file, int *errnum);
-#else
-extern const char * EXPORT gzerror OF((gzFile file, int *errnum));
-#endif
-/*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-
- /* checksum functions */
-
-/*
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern uLong) adler32 (uLong adler, const Bytef *buf, uInt len);
-#else
-extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-#endif
-
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern uLong) crc32 (uLong crc, const Bytef *buf, uInt len);
-#else
-extern uLong EXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-#endif
-/*
- Update a running crc with the bytes buf[0..len-1] and return the updated
- crc. If buf is NULL, this function returns the required initial value
- for the crc. Pre- and post-conditioning (one's complement) is performed
- within this function so it shouldn't be done by the application.
- Usage example:
-
- uLong crc = crc32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = crc32(crc, buffer, length);
- }
- if (crc != original_crc) error();
-*/
-
-
- /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-#ifdef MOZILLA_CLIENT
-PR_PUBLIC_API(extern int) deflateInit_ (z_streamp strm, int level, const char *version,
- int stream_size);
-PR_PUBLIC_API(extern int) inflateInit_ (z_streamp strm, const char *version,
- int stream_size);
-PR_PUBLIC_API(extern int) deflateInit2_ (z_streamp strm, int level, int method,
- int windowBits, int memLevel, int strategy,
- const char *version, int stream_size);
-PR_PUBLIC_API(extern int) inflateInit2_ (z_streamp strm, int windowBits,
- const char *version, int stream_size);
-#else
-extern int EXPORT deflateInit_ OF((z_streamp strm, int level, const char *version,
- int stream_size));
-extern int EXPORT inflateInit_ OF((z_streamp strm, const char *version,
- int stream_size));
-extern int EXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel, int strategy,
- const char *version, int stream_size));
-extern int EXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
-#endif /* MOZILLA_CLIENT */
-
-
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-
-#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ZLIB_H */
diff --git a/security/nss/lib/jar/manifest.mn b/security/nss/lib/jar/manifest.mn
deleted file mode 100644
index 3368387f9..000000000
--- a/security/nss/lib/jar/manifest.mn
+++ /dev/null
@@ -1,25 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-MODULE = nss
-
-LIBRARY_NAME = jar
-
-CORE_DEPTH = ../../..
-
-CSRCS = \
- jarver.c \
- jarsign.c \
- jar.c \
- jar-ds.c \
- jarfile.c \
- jarint.c \
- $(NULL)
-
-EXPORTS = jar.h jar-ds.h jarfile.h
-
-DEFINES = -DMOZILLA_CLIENT=1
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/libpkix/Makefile b/security/nss/lib/libpkix/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/config.mk b/security/nss/lib/libpkix/config.mk
deleted file mode 100755
index 5d75e1c04..000000000
--- a/security/nss/lib/libpkix/config.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-# DEFINES+=-DPKIX_LISTDEBUG Can be used to turn on debug compilation
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/include/Makefile b/security/nss/lib/libpkix/include/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/include/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/include/config.mk b/security/nss/lib/libpkix/include/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/include/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/include/manifest.mn b/security/nss/lib/libpkix/include/manifest.mn
deleted file mode 100755
index 9dc7a6781..000000000
--- a/security/nss/lib/libpkix/include/manifest.mn
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix.h \
- pkix_crlsel.h \
- pkix_errorstrings.h \
- pkix_results.h \
- pkixt.h \
- pkix_certsel.h \
- pkix_params.h \
- pkix_revchecker.h \
- pkix_certstore.h \
- pkix_pl_pki.h \
- pkix_sample_modules.h \
- pkix_checker.h \
- pkix_pl_system.h \
- pkix_util.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- $(NULL)
-
-REQUIRES = dbm
diff --git a/security/nss/lib/libpkix/include/pkix.h b/security/nss/lib/libpkix/include/pkix.h
deleted file mode 100755
index 4ef3cf1fb..000000000
--- a/security/nss/lib/libpkix/include/pkix.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines the public API for libpkix. These are the top-level
- * functions in the library. They perform the primary operations of this
- * library: building and validating chains of X.509 certificates.
- *
- */
-
-#ifndef _PKIX_H
-#define _PKIX_H
-
-#include "pkixt.h"
-#include "pkix_util.h"
-#include "pkix_results.h"
-#include "pkix_certstore.h"
-#include "pkix_certsel.h"
-#include "pkix_crlsel.h"
-#include "pkix_checker.h"
-#include "pkix_revchecker.h"
-#include "pkix_pl_system.h"
-#include "pkix_pl_pki.h"
-#include "pkix_params.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/*
- * FUNCTION: PKIX_Initialize
- * DESCRIPTION:
- *
- * No PKIX_* types and functions should be used before this function is called
- * and returns successfully. This function should only be called once. If it
- * is called more than once, the behavior is undefined.
- *
- * NSS applications are expected to call NSS_Init, and need not know that
- * NSS will call this function (with "platformInitNeeded" set to PKIX_FALSE).
- * PKIX applications are expected instead to call this function with
- * "platformInitNeeded" set to PKIX_TRUE.
- *
- * This function initializes data structures critical to the operation of
- * libpkix. It also ensures that the API version (major.minor) desired by the
- * caller (the "desiredMajorVersion", "minDesiredMinorVersion", and
- * "maxDesiredMinorVersion") is compatible with the API version supported by
- * the library. As such, the library must support the "desiredMajorVersion"
- * of the API and must support a minor version that falls between
- * "minDesiredMinorVersion" and "maxDesiredMinorVersion", inclusive. If
- * compatibility exists, the function returns NULL and stores the library's
- * actual minor version at "pActualMinorVersion" (which may be greater than
- * "desiredMinorVersion"). If no compatibility exists, the function returns a
- * PKIX_Error pointer. If the caller wishes to specify that the largest
- * minor version available should be used, then maxDesiredMinorVersion should
- * be set to the macro PKIX_MAX_MINOR_VERSION (defined in pkixt.h).
- *
- * PARAMETERS:
- * "platformInitNeeded"
- * Boolean indicating whether the platform layer initialization code
- * has previously been run, or should be called from this function.
- * "desiredMajorVersion"
- * The major version of the libpkix API the application wishes to use.
- * "minDesiredMinorVersion"
- * The minimum minor version of the libpkix API the application wishes
- * to use.
- * "maxDesiredMinorVersion"
- * The maximum minor version of the libpkix API the application wishes
- * to use.
- * "pActualMinorVersion"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "pPlContext"
- * Address at which platform-specific context pointer is stored. Must
- * be non-NULL.
- * THREAD SAFETY:
- * Not Thread Safe
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Initialize Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Initialize(
- PKIX_Boolean platformInitNeeded,
- PKIX_UInt32 desiredMajorVersion,
- PKIX_UInt32 minDesiredMinorVersion,
- PKIX_UInt32 maxDesiredMinorVersion,
- PKIX_UInt32 *pActualMinorVersion,
- void **pPlContext);
-
-/*
- * FUNCTION: PKIX_Shutdown
- * DESCRIPTION:
- *
- * This function deallocates any memory used by libpkix and shuts down any
- * ongoing operations. This function should only be called once. If it is
- * called more than once, the behavior is undefined.
- *
- * No PKIX_* types and functions should be used after this function is called
- * and returns successfully.
- * PARAMETERS:
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Shutdown(void *plContext);
-
-/*
- * FUNCTION: PKIX_ValidateChain
- * DESCRIPTION:
- *
- * This function attempts to validate the CertChain that has been set in the
- * ValidateParams pointed to by "params" using an RFC 3280-compliant
- * algorithm. If successful, this function returns NULL and stores the
- * ValidateResult at "pResult", which holds additional information, such as
- * the policy tree and the target's public key. If unsuccessful, an Error is
- * returned. Note: This function does not currently support non-blocking I/O.
- *
- * If "pVerifyTree" is non-NULL, a chain of VerifyNodes is created which
- * tracks the results of the validation. That is, either each node in the
- * chain has a NULL Error component, or the last node contains an Error
- * which indicates why the validation failed.
- *
- * PARAMETERS:
- * "params"
- * Address of ValidateParams used to validate CertChain. Must be non-NULL.
- * "pResult"
- * Address where object pointer will be stored. Must be non-NULL.
- * "pVerifyTree"
- * Address where a VerifyTree is stored, if non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (See Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Validate Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ValidateChain(
- PKIX_ValidateParams *params,
- PKIX_ValidateResult **pResult,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ValidateChain_NB
- * DESCRIPTION:
- *
- * This function is the equivalent of PKIX_ValidateChain, except that it
- * supports non-blocking I/O. When called with "pNBIOContext" pointing to NULL
- * it initiates a new chain validation as in PKIX_ValidateChain, ignoring the
- * value in all input variables except "params". If forced to suspend
- * processing by a WOULDBLOCK return from some operation, such as a CertStore
- * request, it stores the platform-dependent I/O context at "pNBIOContext" and
- * stores other intermediate variables at "pCertIndex", "pAnchorIndex",
- * "pCheckerIndex", "pRevChecking", and "pCheckers".
- *
- * When called subsequently with that non-NULL value at "pNBIOContext", it
- * relies on those intermediate values to be untouched, and it resumes chain
- * validation where it left off. Its behavior is undefined if any of the
- * intermediate values was not preserved.
- *
- * PARAMETERS:
- * "params"
- * Address of ValidateParams used to validate CertChain. Must be non-NULL.
- * "pCertIndex"
- * The UInt32 value of the index to the Cert chain, indicating which Cert
- * is currently being processed.
- * "pAnchorIndex"
- * The UInt32 value of the index to the Anchor chain, indicating which
- * Trust Anchor is currently being processed.
- * "pCheckerIndex"
- * The UInt32 value of the index to the List of CertChainCheckers,
- * indicating which Checker is currently processing.
- * "pRevChecking"
- * The Boolean flag indicating whether normal checking or revocation
- * checking is occurring for the Cert indicated by "pCertIndex".
- * "pCheckers"
- * The address of the List of CertChainCheckers. Must be non-NULL.
- * "pNBIOContext"
- * The address of the platform-dependend I/O context. Must be a non-NULL
- * pointer to a NULL value for the call to initiate chain validation.
- * "pResult"
- * Address where ValidateResult object pointer will be stored. Must be
- * non-NULL.
- * "pVerifyTree"
- * Address where a VerifyTree is stored, if non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a VALIDATE Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */PKIX_Error *
-PKIX_ValidateChain_NB(
- PKIX_ValidateParams *params,
- PKIX_UInt32 *pCertIndex,
- PKIX_UInt32 *pAnchorIndex,
- PKIX_UInt32 *pCheckerIndex,
- PKIX_Boolean *pRevChecking,
- PKIX_List **pCheckers,
- void **pNBIOContext,
- PKIX_ValidateResult **pResult,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_BuildChain
- * DESCRIPTION:
- *
- * If called with a NULL "state", this function attempts to build and validate
- * a CertChain according to the ProcessingParams pointed to by "params", using
- * an RFC 3280-compliant validation algorithm. If successful, this function
- * returns NULL and stores the BuildResult at "pResult", which holds the built
- * CertChain, as well as additional information, such as the policy tree and
- * the target's public key. If unsuccessful, an Error is returned.
- *
- * If the chain building is blocked by a CertStore using non-blocking I/O, this
- * function stores platform-dependent non-blocking I/O context at
- * "pNBIOContext", its state at "pState", and NULL at "pResult". The caller
- * may be able to determine, in a platform-dependent way, when the I/O has
- * completed. In any case, calling the function again with "pState" containing
- * the returned value will allow the chain building to resume.
- *
- * If chain building is completed, either successfully or unsuccessfully, NULL
- * is stored at "pNBIOContext".
- *
- * If "pVerifyTree" is non-NULL, a tree of VerifyNodes is created which
- * tracks the results of the building. That is, each node of the tree either
- * has a NULL Error component, or it is a leaf node and it contains an Error
- * which indicates why the chain building could not proceed on this branch.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams used to build and validate CertChain.
- * Must be non-NULL.
- * "pNBIOContext"
- * Address where platform-dependent information is store if the build
- * is suspended waiting for non-blocking I/O. Must be non-NULL.
- * "pState"
- * Address of BuildChain state. Must be NULL on initial call, and the
- * value previously returned on subsequent calls.
- * "pResult"
- * Address where object pointer will be stored. Must be non-NULL.
- * "pVerifyTree"
- * Address where a VerifyTree is stored, if non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (See Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_BuildChain(
- PKIX_ProcessingParams *params,
- void **pNBIOContext,
- void **pState,
- PKIX_BuildResult **pResult,
- PKIX_VerifyNode **pVerifyNode,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_H */
diff --git a/security/nss/lib/libpkix/include/pkix_certsel.h b/security/nss/lib/libpkix/include/pkix_certsel.h
deleted file mode 100755
index e6b20c8c5..000000000
--- a/security/nss/lib/libpkix/include/pkix_certsel.h
+++ /dev/null
@@ -1,1826 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines functions associated with the PKIX_CertSelector and the
- * PKIX_ComCertSelParams types.
- *
- */
-
-#ifndef _PKIX_CERTSEL_H
-#define _PKIX_CERTSEL_H
-
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/* PKIX_CertSelector
- *
- * PKIX_CertSelectors provide a standard way for the caller to select
- * certificates based on particular criteria. A CertSelector is typically used
- * by the caller to specify the constraints they wish to impose on the target
- * certificate in a chain. (see pkix_params.h) A CertSelector is also often
- * used to retrieve certificates from a CertStore that match the selector's
- * criteria. (See pkix_certstore.h) For example, the caller may wish to only
- * select those certificates that have a particular Subject Distinguished Name
- * and a particular value for a private certificate extension. The
- * MatchCallback allows the caller to specify the custom matching logic to be
- * used by a CertSelector.
- *
- * By default, the MatchCallback is set to point to the default implementation
- * provided by libpkix, which understands how to process the most common
- * parameters. If the default implementation is used, the caller should set
- * these common parameters using PKIX_CertSelector_SetCommonCertSelectorParams.
- * Any common parameter that is not set is assumed to be disabled, which means
- * the default MatchCallback implementation will select all certificates
- * without regard to that particular disabled parameter. For example, if the
- * SerialNumber parameter is not set, MatchCallback will not filter out any
- * certificate based on its serial number. As such, if no parameters are set,
- * all are disabled and any certificate will match. If a parameter is
- * disabled, its associated PKIX_ComCertSelParams_Get* function returns a
- * default value of NULL, or -1 for PKIX_ComCertSelParams_GetBasicConstraints
- * and PKIX_ComCertSelParams_GetVersion, or 0 for
- * PKIX_ComCertSelParams_GetKeyUsage.
- *
- * If a custom implementation is desired, the default implementation can be
- * overridden by calling PKIX_CertSelector_SetMatchCallback. In this case, the
- * CertSelector can be initialized with a certSelectorContext, which is where
- * the caller can specify the desired parameters the caller wishes to match
- * against. Note that this certSelectorContext must be an Object (although any
- * object type), allowing it to be reference-counted and allowing it to
- * provide the standard Object functions (Equals, Hashcode, ToString, Compare,
- * Duplicate).
- *
- */
-
-/*
- * FUNCTION: PKIX_CertSelector_MatchCallback
- * DESCRIPTION:
- *
- * This callback function determines whether the specified Cert pointed to by
- * "cert" matches the criteria of the CertSelector pointed to by "selector".
- * If the Cert does not matches the CertSelector's criteria, an exception will
- * be thrown.
- *
- * PARAMETERS:
- * "selector"
- * Address of CertSelector whose MatchCallback logic and parameters are
- * to be used. Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched using "selector".
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_CertSelector_MatchCallback)(
- PKIX_CertSelector *selector,
- PKIX_PL_Cert *cert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertSelector_Create
- * DESCRIPTION:
- *
- * Creates a new CertSelector using the Object pointed to by
- * "certSelectorContext" (if any) and stores it at "pSelector". As noted
- * above, by default, the MatchCallback is set to point to the default
- * implementation provided by libpkix, which understands how to process
- * ComCertSelParams objects. This is overridden if the MatchCallback pointed
- * to by "callback" is not NULL, in which case the parameters are specified
- * using the certSelectorContext.
- *
- * PARAMETERS:
- * "callback"
- * The MatchCallback function to be used.
- * "certSelectorContext"
- * Address of Object representing the CertSelector's context (if any).
- * "pSelector"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertSelector_Create(
- PKIX_CertSelector_MatchCallback callback,
- PKIX_PL_Object *certSelectorContext,
- PKIX_CertSelector **pSelector,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertSelector_GetMatchCallback
- * DESCRIPTION:
- *
- * Retrieves a pointer to "selector's" Match callback function and puts it in
- * "pCallback".
- *
- * PARAMETERS:
- * "selector"
- * The CertSelector whose Match callback is desired. Must be non-NULL.
- * "pCallback"
- * Address where Match callback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertSelector_GetMatchCallback(
- PKIX_CertSelector *selector,
- PKIX_CertSelector_MatchCallback *pCallback,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertSelector_GetCertSelectorContext
- * DESCRIPTION:
- *
- * Retrieves a pointer to a PKIX_PL_Object representing the context (if any)
- * of the CertSelector pointed to by "selector" and stores it at
- * "pCertSelectorContext".
- *
- * PARAMETERS:
- * "selector"
- * Address of CertSelector whose context is to be stored.
- * Must be non-NULL.
- * "pCertSelectorContext"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertSelector_GetCertSelectorContext(
- PKIX_CertSelector *selector,
- PKIX_PL_Object **pCertSelectorContext,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertSelector_GetCommonCertSelectorParams
- * DESCRIPTION:
- *
- * Retrieves a pointer to the ComCertSelParams object that represent the
- * common parameters of the CertSelector pointed to by "selector" and stores
- * it at "pCommonCertSelectorParams". If there are no common parameters
- * stored with the CertSelector, this function stores NULL at
- * "pCommonCertSelectorParams".
- *
- * PARAMETERS:
- * "selector"
- * Address of CertSelector whose ComCertSelParams object is to be stored.
- * Must be non-NULL.
- * "pCommonCertSelectorParams"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertSelector_GetCommonCertSelectorParams(
- PKIX_CertSelector *selector,
- PKIX_ComCertSelParams **pCommonCertSelectorParams,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertSelector_SetCommonCertSelectorParams
- * DESCRIPTION:
- *
- * Sets the common parameters for the CertSelector pointed to by "selector"
- * using the ComCertSelParams object pointed to by "commonCertSelectorParams".
- *
- * PARAMETERS:
- * "selector"
- * Address of CertSelector whose common parameters are to be set.
- * Must be non-NULL.
- * "commonCertSelectorParams"
- * Address of ComCertSelParams object representing the common parameters.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "selector"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertSelector_SetCommonCertSelectorParams(
- PKIX_CertSelector *selector,
- PKIX_ComCertSelParams *commonCertSelectorParams,
- void *plContext);
-
-/* PKIX_ComCertSelParams
- *
- * PKIX_ComCertSelParams objects are X.509 parameters commonly used with
- * CertSelectors, especially when enforcing constraints on a target
- * certificate or determining which certificates to retrieve from a CertStore.
- * ComCertSelParams objects are typically used with those CertSelectors that
- * use the default implementation of MatchCallback, which understands how to
- * process ComCertSelParams objects.
- */
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_Create
- * DESCRIPTION:
- *
- * Creates a new ComCertSelParams object and stores it at "pParams".
- *
- * PARAMETERS:
- * "pParams"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_Create(
- PKIX_ComCertSelParams **pParams,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubjAltNames
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of GeneralNames (if any) representing the
- * subject alternative names criterion that is set in the ComCertSelParams
- * object pointed to by "params" and stores it at "pNames". In order to match
- * against this criterion, a certificate must contain all or at least one of
- * the criterion's subject alternative names (depending on the result of
- * PKIX_ComCertSelParams_GetMatchAllSubjAltNames). The default behavior
- * requires a certificate to contain all of the criterion's subject
- * alternative names in order to match.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pNames", in which case all certificates are considered to match this
- * criterion.
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject alternative names
- * criterion (if any) is to be stored. Must be non-NULL.
- * "pNames"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubjAltNames(
- PKIX_ComCertSelParams *params,
- PKIX_List **pNames, /* list of PKIX_PL_GeneralName */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubjAltNames
- * DESCRIPTION:
- *
- * Sets the subject alternative names criterion of the ComCertSelParams object
- * pointed to by "params" using a List of GeneralNames pointed to by "names".
- * In order to match against this criterion, a certificate must contain all or
- * at least one of the criterion's subject alternative names (depending on the
- * result of PKIX_ComCertSelParams_GetMatchAllSubjAltNames). The default
- * behavior requires a certificate to contain all of the criterion's subject
- * alternative names in order to match.
- *
- * If "names" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject alternative
- * names criterion is to be set. Must be non-NULL.
- * "names"
- * Address of List of GeneralNames used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubjAltNames(
- PKIX_ComCertSelParams *params,
- PKIX_List *names, /* list of PKIX_PL_GeneralName */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_AddSubjAltName
- * DESCRIPTION:
- *
- * Adds to the subject alternative names criterion of the ComCertSelParams
- * object pointed to by "params" using the GeneralName pointed to by "name".
- * In order to match against this criterion, a certificate must contain all
- * or at least one of the criterion's subject alternative names (depending on
- * the result of PKIX_ComCertSelParams_GetMatchAllSubjAltNames). The default
- * behavior requires a certificate to contain all of the criterion's subject
- * alternative names in order to match.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject alternative names
- * criterion is to be added to. Must be non-NULL.
- * "name"
- * Address of GeneralName to be added.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_AddSubjAltName(
- PKIX_ComCertSelParams *params,
- PKIX_PL_GeneralName *name,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetPathToNames
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of GeneralNames (if any) representing the
- * path to names criterion that is set in the ComCertSelParams object pointed
- * to by "params" and stores it at "pNames". In order to match against this
- * criterion, a certificate must not include name constraints that would
- * prohibit building a path to the criterion's specified names.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pNames", in which case all certificates are considered to match this
- * criterion.
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose path to names criterion
- * (if any) is to be stored. Must be non-NULL.
- * "pNames"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetPathToNames(
- PKIX_ComCertSelParams *params,
- PKIX_List **pNames, /* list of PKIX_PL_GeneralName */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetPathToNames
- * DESCRIPTION:
- *
- * Sets the path to names criterion of the ComCertSelParams object pointed to
- * by "params" using a List of GeneralNames pointed to by "names". In order to
- * match against this criterion, a certificate must not include name
- * constraints that would prohibit building a path to the criterion's
- * specified names.
- *
- * If "names" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose path to names criterion
- * is to be set. Must be non-NULL.
- * "names"
- * Address of List of GeneralNames used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetPathToNames(
- PKIX_ComCertSelParams *params,
- PKIX_List *names, /* list of PKIX_PL_GeneralName */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_AddPathToName
- * DESCRIPTION:
- *
- * Adds to the path to names criterion of the ComCertSelParams object pointed
- * to by "params" using the GeneralName pointed to by "pathToName". In order
- * to match against this criterion, a certificate must not include name
- * constraints that would prohibit building a path to the criterion's
- * specified names.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose path to names criterion is to
- * be added to. Must be non-NULL.
- * "pathToName"
- * Address of GeneralName to be added.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_AddPathToName(
- PKIX_ComCertSelParams *params,
- PKIX_PL_GeneralName *pathToName,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetAuthorityKeyIdentifier
- * DESCRIPTION:
- *
- * Retrieves a pointer to the ByteArray (if any) representing the authority
- * key identifier criterion that is set in the ComCertSelParams object
- * pointed to by "params" and stores it at "pAuthKeyId". In order to match
- * against this criterion, a certificate must contain an
- * AuthorityKeyIdentifier extension whose value matches the criterion's
- * authority key identifier value.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pAuthKeyId", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose authority key identifier
- * criterion (if any) is to be stored. Must be non-NULL.
- * "pAuthKeyId"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetAuthorityKeyIdentifier(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray **pAuthKeyId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetAuthorityKeyIdentifier
- * DESCRIPTION:
- *
- * Sets the authority key identifier criterion of the ComCertSelParams object
- * pointed to by "params" to the ByteArray pointed to by "authKeyId". In
- * order to match against this criterion, a certificate must contain an
- * AuthorityKeyIdentifier extension whose value matches the criterion's
- * authority key identifier value.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose authority key identifier
- * criterion is to be set. Must be non-NULL.
- * "authKeyId"
- * Address of ByteArray used to set the criterion
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetAuthorityKeyIdentifier(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray *authKeyId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubjKeyIdentifier
- * DESCRIPTION:
- *
- * Retrieves a pointer to the ByteArray (if any) representing the subject key
- * identifier criterion that is set in the ComCertSelParams object pointed to
- * by "params" and stores it at "pSubjKeyId". In order to match against this
- * criterion, a certificate must contain a SubjectKeyIdentifier extension
- * whose value matches the criterion's subject key identifier value.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pSubjKeyId", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject key identifier
- * criterion (if any) is to be stored. Must be non-NULL.
- * "pSubjKeyId"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubjKeyIdentifier(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray **pSubjKeyId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubjKeyIdentifier
- * DESCRIPTION:
- *
- * Sets the subject key identifier criterion of the ComCertSelParams object
- * pointed to by "params" using a ByteArray pointed to by "subjKeyId". In
- * order to match against this criterion, a certificate must contain an
- * SubjectKeyIdentifier extension whose value matches the criterion's subject
- * key identifier value.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject key identifier
- * criterion is to be set. Must be non-NULL.
- * "subjKeyId"
- * Address of ByteArray used to set the criterion
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubjKeyIdentifier(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray *subKeyId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubjPubKey
- * DESCRIPTION:
- *
- * Retrieves a pointer to the PublicKey (if any) representing the subject
- * public key criterion that is set in the ComCertSelParams object pointed to
- * by "params" and stores it at "pPubKey". In order to match against this
- * criterion, a certificate must contain a SubjectPublicKey that matches the
- * criterion's public key.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pPubKey", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject public key criterion
- * (if any) is to be stored. Must be non-NULL.
- * "pPubKey"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubjPubKey(
- PKIX_ComCertSelParams *params,
- PKIX_PL_PublicKey **pPubKey,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubjPubKey
- * DESCRIPTION:
- *
- * Sets the subject public key criterion of the ComCertSelParams object
- * pointed to by "params" using a PublicKey pointed to by "pubKey". In order
- * to match against this criterion, a certificate must contain a
- * SubjectPublicKey that matches the criterion's public key.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject public key
- * criterion is to be set. Must be non-NULL.
- * "pubKey"
- * Address of PublicKey used to set the criterion
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubjPubKey(
- PKIX_ComCertSelParams *params,
- PKIX_PL_PublicKey *pubKey,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubjPKAlgId
- * DESCRIPTION:
- *
- * Retrieves a pointer to the OID (if any) representing the subject public key
- * algorithm identifier criterion that is set in the ComCertSelParams object
- * pointed to by "params" and stores it at "pPubKey". In order to match
- * against this criterion, a certificate must contain a SubjectPublicKey with
- * an algorithm that matches the criterion's algorithm.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pAlgId", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject public key algorithm
- * identifier (if any) is to be stored. Must be non-NULL.
- * "pAlgId"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubjPKAlgId(
- PKIX_ComCertSelParams *params,
- PKIX_PL_OID **pAlgId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubjPKAlgId
- * DESCRIPTION:
- *
- * Sets the subject public key algorithm identifier criterion of the
- * ComCertSelParams object pointed to by "params" using an OID pointed to by
- * "algId". In order to match against this criterion, a certificate must
- * contain a SubjectPublicKey with an algorithm that matches the criterion's
- * algorithm.
- *
- * If "algId" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject public key
- * algorithm identifier criterion is to be set. Must be non-NULL.
- * "algId"
- * Address of OID used to set criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubjPKAlgId(
- PKIX_ComCertSelParams *params,
- PKIX_PL_OID *algId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetBasicConstraints
- * DESCRIPTION:
- *
- * Retrieves a pointer to the minimum path length (if any) representing the
- * basic constraints criterion that is set in the ComCertSelParams object
- * pointed to by "params" and stores it at "pMinPathLength". In order to
- * match against this criterion, there are several possibilities.
- *
- * 1) If the criterion's minimum path length is greater than or equal to zero,
- * a certificate must include a BasicConstraints extension with a pathLen of
- * at least this value.
- *
- * 2) If the criterion's minimum path length is -2, a certificate must be an
- * end-entity certificate.
- *
- * 3) If the criterion's minimum path length is -1, no basic constraints check
- * is done and all certificates are considered to match this criterion.
- *
- * The semantics of other values of the criterion's minimum path length are
- * undefined but may be defined in future versions of the API.
- *
- * If "params" does not have this criterion set, this function stores -1 at
- * "pMinPathLength", in which case all certificates are considered to match
- * this criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose basic constraints criterion
- * (if any) is to be stored. Must be non-NULL.
- * "pMinPathLength"
- * Address where PKIX_Int32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetBasicConstraints(
- PKIX_ComCertSelParams *params,
- PKIX_Int32 *pMinPathLength,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetBasicConstraints
- * DESCRIPTION:
- *
- * Sets the basic constraints criterion of the ComCertSelParams object
- * pointed to by "params" using the integer value of "minPathLength". In
- * order to match against this criterion, there are several possibilities.
- *
- * 1) If the criterion's minimum path length is greater than or equal to zero,
- * a certificate must include a BasicConstraints extension with a pathLen of
- * at least this value.
- *
- * 2) If the criterion's minimum path length is -2, a certificate must be an
- * end-entity certificate.
- *
- * 3) If the criterion's minimum path length is -1, no basic constraints check
- * is done and all certificates are considered to match this criterion.
- *
- * The semantics of other values of the criterion's minimum path length are
- * undefined but may be defined in future versions of the API.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose basic constraints
- * criterion is to be set. Must be non-NULL.
- * "minPathLength"
- * Value of PKIX_Int32 used to set the criterion
- * (or -1 to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetBasicConstraints(
- PKIX_ComCertSelParams *params,
- PKIX_Int32 minPathLength,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetCertificate
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Cert (if any) representing the certificate
- * criterion that is set in the ComCertSelParams object pointed to by
- * "params" and stores it at "pCert". In order to match against this
- * criterion, a certificate must be equal to the criterion's certificate. If
- * this criterion is specified, it is usually not necessary to specify any
- * other criteria, since this criterion requires an exact certificate match.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pCert", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose certificate criterion
- * (if any) is to be stored. Must be non-NULL.
- * "pCert"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetCertificate(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert **pCert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetCertificate
- * DESCRIPTION:
- *
- * Sets the certificate criterion of the ComCertSelParams object pointed to by
- * "params" using a Cert pointed to by "cert". In order to match against this
- * criterion, a certificate must be equal to the criterion's certificate.
- * If this criterion is specified, it is usually not necessary to specify
- * any other criteria, since this criterion requires an exact certificate
- * match.
- *
- * If "cert" is NULL, all certificates are considered to match this criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose certificate criterion is to be
- * set. Must be non-NULL.
- * "cert"
- * Address of Cert used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetCertificate(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetCertificateValid
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Date (if any) representing the certificate
- * validity criterion that is set in the ComCertSelParams object pointed to by
- * "params" and stores it at "pDate". In order to match against this
- * criterion, a certificate's validity period must include the criterion's
- * Date.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pDate", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose certificate validity criterion
- * (if any) is to be stored. Must be non-NULL.
- * "pDate"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetCertificateValid(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Date **pDate,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetCertificateValid
- * DESCRIPTION:
- *
- * Sets the certificate validity criterion of the ComCertSelParams object
- * pointed to by "params" using a Date pointed to by "date". In order to
- * match against this criterion, a certificate's validity period must include
- * the criterion's Date.
- *
- * If "date" is NULL, all certificates are considered to match this criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose certificate validity criterion
- * is to be set. Must be non-NULL.
- * "date"
- * Address of Date used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetCertificateValid(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Date *date,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSerialNumber
- * DESCRIPTION:
- *
- * Retrieves a pointer to the BigInt (if any) representing the serial number
- * criterion that is set in the ComCertSelParams object pointed to by
- * "params" and stores it at "pSerialNumber". In order to match against this
- * criterion, a certificate must have a serial number equal to the
- * criterion's serial number.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pSerialNumber", in which case all certificates are considered to match
- * this criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose serial number criterion
- * (if any) is to be stored. Must be non-NULL.
- * "pSerialNumber"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSerialNumber(
- PKIX_ComCertSelParams *params,
- PKIX_PL_BigInt **pSerialNumber,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSerialNumber
- * DESCRIPTION:
- *
- * Sets the serial number criterion of the ComCertSelParams object pointed to
- * by "params" using a BigInt pointed to by "serialNumber". In order to match
- * against this criterion, a certificate must have a serial number equal to
- * the criterion's serial number.
- *
- * If "serialNumber" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose serial number criterion is to
- * be set. Must be non-NULL.
- * "serialNumber"
- * Address of BigInt used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSerialNumber(
- PKIX_ComCertSelParams *params,
- PKIX_PL_BigInt *serialNumber,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetVersion
- * DESCRIPTION:
- *
- * Retrieves a PKIX_UInt32 (if any) representing the version criterion that is
- * set in the ComCertSelParams object pointed to by "params" and stores it at
- * "pVersion". In order to match against this criterion, a certificate's
- * version must be equal to the criterion's version.
- *
- * The version number will either be 0, 1, or 2 (corresponding to
- * v1, v2, or v3, respectively).
- *
- * If "params" does not have this criterion set, this function stores
- * 0xFFFFFFFF at "pVersion", in which case all certificates are considered
- * to match this criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose version criterion (if any) is
- * to be stored. Must be non-NULL.
- * "pVersion"
- * Address where PKIX_Int32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetVersion(
- PKIX_ComCertSelParams *params,
- PKIX_UInt32 *pVersion,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetVersion
- * DESCRIPTION:
- *
- * Sets the version criterion of the ComCertSelParams object pointed to by
- * "params" using the integer value of "version". In order to match against
- * this criterion, a certificate's version must be equal to the criterion's
- * version. If the criterion's version is -1, no version check is done and
- * all certificates are considered to match this criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose version criterion is to be
- * set. Must be non-NULL.
- * "version"
- * Value of PKIX_Int32 used to set the criterion
- * (or -1 to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetVersion(
- PKIX_ComCertSelParams *params,
- PKIX_Int32 version,
- void *plContext);
-
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetKeyUsage
- * DESCRIPTION:
- *
- * Retrieves a PKIX_UInt32 (if any) representing the key usage criterion that
- * is set in the ComCertSelParams object pointed to by "params" and stores it
- * at "pKeyUsage". In order to match against this criterion, a certificate
- * must allow the criterion's key usage values. Note that a certificate that
- * has no KeyUsage extension implicity allows all key usages. Note also that
- * this functions supports a maximum of 32 key usage bits.
- *
- * If "params" does not have this criterion set, this function stores zero at
- * "pKeyUsage", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose key usage criterion (if any)
- * is to be stored. Must be non-NULL.
- * "pKeyUsage"
- * Address where PKIX_UInt32 will be stored. Must not be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetKeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_UInt32 *pKeyUsage,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetKeyUsage
- * DESCRIPTION:
- *
- * Sets the key usage criterion of the ComCertSelParams object pointed to by
- * "params" using the integer value of "keyUsage". In order to match against
- * this criterion, a certificate must allow the criterion's key usage values.
- * Note that a certificate that has no KeyUsage extension implicity allows
- * all key usages. Note also that this functions supports a maximum of 32 key
- * usage bits.
- *
- * If the criterion's key usage value is zero, no key usage check is done and
- * all certificates are considered to match this criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose key usage criterion is to be
- * set. Must be non-NULL.
- * "keyUsage"
- * Value of PKIX_Int32 used to set the criterion
- * (or zero to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetKeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_UInt32 keyUsage,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetExtendedKeyUsage
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of OIDs (if any) representing the extended
- * key usage criterion that is set in the ComCertSelParams object pointed to
- * by "params" and stores it at "pExtKeyUsage". In order to match against this
- * criterion, a certificate's ExtendedKeyUsage extension must allow the
- * criterion's extended key usages. Note that a certificate that has no
- * ExtendedKeyUsage extension implicity allows all key purposes.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pExtKeyUsage", in which case all certificates are considered to match
- * this criterion.
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose extended key usage criterion
- * (if any) is to be stored. Must be non-NULL.
- * "pExtKeyUsage"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetExtendedKeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_List **pExtKeyUsage, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetExtendedKeyUsage
- * DESCRIPTION:
- *
- * Sets the extended key usage criterion of the ComCertSelParams object
- * pointed to by "params" using a List of OIDs pointed to by "extKeyUsage".
- * In order to match against this criterion, a certificate's ExtendedKeyUsage
- * extension must allow the criterion's extended key usages. Note that a
- * certificate that has no ExtendedKeyUsage extension implicitly allows all
- * key purposes.
- *
- * If "extKeyUsage" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose extended key usage criterion
- * is to be set. Must be non-NULL.
- * "extKeyUsage"
- * Address of List of OIDs used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetExtendedKeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_List *extKeyUsage, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetPolicy
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of OIDs (if any) representing the policy
- * criterion that is set in the ComCertSelParams object pointed to by
- * "params" and stores it at "pPolicy". In order to match against this
- * criterion, a certificate's CertificatePolicies extension must include at
- * least one of the criterion's policies. If "params" has this criterion set,
- * but the List of OIDs is empty, then a certificate's CertificatePolicies
- * extension must include at least some policy.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pPolicy", in which case all certificates are considered to match this
- * criterion.
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose policy criterion (if any) is
- * to be stored. Must be non-NULL.
- * "pPolicy"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetPolicy(
- PKIX_ComCertSelParams *params,
- PKIX_List **pPolicy, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetPolicy
- * DESCRIPTION:
- *
- * Sets the policy criterion of the ComCertSelParams object pointed to by
- * "params" using a List of OIDs pointed to by "policy". In order to match
- * against this criterion, a certificate's CertificatePolicies extension must
- * include at least one of the criterion's policies. If "params" has this
- * criterion set, but the List of OIDs is empty, then a certificate's
- * CertificatePolicies extension must include at least some policy.
- *
- * If "policy" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose policy criterion is to be set.
- * Must be non-NULL.
- * "policy"
- * Address of List of OIDs used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetPolicy(
- PKIX_ComCertSelParams *params,
- PKIX_List *policy, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetIssuer
- * DESCRIPTION:
- *
- * Retrieves a pointer to the X500Name (if any) representing the issuer
- * criterion that is set in the ComCertSelParams object pointed to by
- * "params" and stores it at "pIssuer". In order to match against this
- * criterion, a certificate's IssuerName must match the criterion's issuer
- * name.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pIssuer", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose issuer criterion (if any) is
- * to be stored. Must be non-NULL.
- * "pIssuer"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetIssuer(
- PKIX_ComCertSelParams *params,
- PKIX_PL_X500Name **pIssuer,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetIssuer
- * DESCRIPTION:
- *
- * Sets the issuer criterion of the ComCertSelParams object pointed to by
- * "params" using an X500Name pointed to by "issuer". In order to match
- * against this criterion, a certificate's IssuerName must match the
- * criterion's issuer name.
- *
- * If "issuer" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose issuer criterion is to be set.
- * Must be non-NULL.
- * "issuer"
- * Address of X500Name used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetIssuer(
- PKIX_ComCertSelParams *params,
- PKIX_PL_X500Name *issuer,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubject
- * DESCRIPTION:
- *
- * Retrieves a pointer to the X500Name (if any) representing the subject
- * criterion that is set in the ComCertSelParams object pointed to by
- * "params" and stores it at "pSubject". In order to match against this
- * criterion, a certificate's SubjectName must match the criterion's subject
- * name.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pSubject", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject criterion (if any) is
- * to be stored. Must be non-NULL.
- * "pSubject"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubject(
- PKIX_ComCertSelParams *params,
- PKIX_PL_X500Name **pSubject,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubject
- * DESCRIPTION:
- *
- * Sets the subject criterion of the ComCertSelParams object pointed to by
- * "params" using an X500Name pointed to by "subject". In order to match
- * against this criterion, a certificate's SubjectName must match the
- * criterion's subject name.
- *
- * If "subject" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject criterion is to be
- * set. Must be non-NULL.
- * "subject"
- * Address of X500Name used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubject(
- PKIX_ComCertSelParams *params,
- PKIX_PL_X500Name *subject,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubjectAsByteArray
- * DESCRIPTION:
- *
- * Retrieves a pointer to the ByteArray (if any) representing the subject
- * criterion that is set in the ComCertSelParams object pointed to by
- * "params" and stores it at "pSubject". In order to match against this
- * criterion, a certificate's SubjectName must match the criterion's subject
- * name.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pSubject", in which case all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject criterion (if any) is
- * to be stored. Must be non-NULL.
- * "pSubject"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubjectAsByteArray(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray **pSubject,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubjectAsByteArray
- * DESCRIPTION:
- *
- * Sets the subject criterion of the ComCertSelParams object pointed to by
- * "params" using a ByteArray pointed to by "subject". In order to match
- * against this criterion, a certificate's SubjectName must match the
- * criterion's subject name.
- *
- * If "subject" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose subject criterion is to be
- * set. Must be non-NULL.
- * "subject"
- * Address of ByteArray used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubjectAsByteArray(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray *subject,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetNameConstraints
- * DESCRIPTION:
- *
- * Retrieves a pointer to the X500Name (if any) representing the name
- * constraints criterion that is set in the ComCertSelParams object pointed
- * to by "params" and stores it at "pConstraints". In order to match against
- * this criterion, a certificate's subject and subject alternative names must
- * be allowed by the criterion's name constraints.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pConstraints", in which case all certificates are considered to match
- * this criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose name constraints criterion
- * (if any) is to be stored. Must be non-NULL.
- * "pConstraints"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetNameConstraints(
- PKIX_ComCertSelParams *params,
- PKIX_PL_CertNameConstraints **pConstraints,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetNameConstraints
- * DESCRIPTION:
- *
- * Sets the name constraints criterion of the ComCertSelParams object pointed
- * to by "params" using the CertNameConstraints pointed to by "constraints".
- * In order to match against this criterion, a certificate's subject and
- * subject alternative names must be allowed by the criterion's name
- * constraints.
- *
- * If "constraints" is NULL, all certificates are considered to match this
- * criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose name constraints criterion is
- * to be set. Must be non-NULL.
- * "constraints"
- * Address of CertNameConstraints used to set the criterion
- * (or NULL to disable the criterion).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetNameConstraints(
- PKIX_ComCertSelParams *params,
- PKIX_PL_CertNameConstraints *constraints,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetMatchAllSubjAltNames
- * DESCRIPTION:
- *
- * Checks whether the ComCertSelParams object pointed to by "params" indicate
- * that all subject alternative names are to be matched and stores the Boolean
- * result at "pMatch". This Boolean value determines the behavior of the
- * subject alternative names criterion.
- *
- * In order to match against the subject alternative names criterion, if the
- * Boolean value at "pMatch" is PKIX_TRUE, a certificate must contain all of
- * the criterion's subject alternative names. If the Boolean value at
- * "pMatch" is PKIX_FALSE, a certificate must contain at least one of the
- * criterion's subject alternative names. The default behavior is as if the
- * Boolean value at "pMatch" is PKIX_TRUE.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object used to determine whether all
- * subject alternative names must be matched. Must be non-NULL.
- * "pMatch"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetMatchAllSubjAltNames(
- PKIX_ComCertSelParams *params,
- PKIX_Boolean *pMatch,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetMatchAllSubjAltNames
- * DESCRIPTION:
- *
- * Sets the match flag of the ComCertSelParams object pointed to by "params"
- * using the Boolean value of "match". This Boolean value determines the
- * behavior of the subject alternative names criterion.
- *
- * In order to match against the subject alternative names criterion, if the
- * "match" is PKIX_TRUE, a certificate must contain all of the criterion's
- * subject alternative names. If the "match" is PKIX_FALSE, a certificate
- * must contain at least one of the criterion's subject alternative names.
- * The default behavior is as if "match" is PKIX_TRUE.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose match flag is to be set.
- * Must be non-NULL.
- * "match"
- * Boolean value used to set the match flag.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetMatchAllSubjAltNames(
- PKIX_ComCertSelParams *params,
- PKIX_Boolean match,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetLeafCertFlag
- * DESCRIPTION:
- *
- * Return "leafCert" flag of the ComCertSelParams structure. If set to true,
- * the flag indicates that a selector should filter out all cert that are not
- * qualified to be a leaf cert according to the specified key/ekey usages.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object used to determine whether all
- * subject alternative names must be matched. Must be non-NULL.
- * "pLeafFlag"
- * Address of returned value.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error*
-PKIX_ComCertSelParams_GetLeafCertFlag(
- PKIX_ComCertSelParams *params,
- PKIX_Boolean *pLeafFlag,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetLeafCertFlag
- * DESCRIPTION:
- *
- * Sets a flag that if its value is true, indicates that the selector
- * should only pick certs that qualifies to be leaf for this cert path
- * validation.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams object whose match flag is to be set.
- * Must be non-NULL.
- * "leafFlag"
- * Boolean value used to set the leaf flag.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetLeafCertFlag(
- PKIX_ComCertSelParams *params,
- PKIX_Boolean leafFlag,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_CERTSEL_H */
diff --git a/security/nss/lib/libpkix/include/pkix_certstore.h b/security/nss/lib/libpkix/include/pkix_certstore.h
deleted file mode 100755
index 2feb3334d..000000000
--- a/security/nss/lib/libpkix/include/pkix_certstore.h
+++ /dev/null
@@ -1,713 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines functions associated with the PKIX_CertStore type.
- *
- */
-
-#ifndef _PKIX_CERTSTORE_H
-#define _PKIX_CERTSTORE_H
-
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/* PKIX_CertStore
- *
- * A PKIX_CertStore provides a standard way for the caller to retrieve
- * certificates and CRLs from a particular repository (or "store") of
- * certificates and CRLs, including LDAP directories, flat files, local
- * databases, etc. The CertCallback allows custom certificate retrieval logic
- * to be used while the CRLCallback allows custom CRL retrieval logic to be
- * used. Additionally, a CertStore can be initialized with a certStoreContext,
- * which is where the caller can specify configuration data such as the host
- * name of an LDAP server. Note that this certStoreContext must be an
- * Object (although any object type), allowing it to be reference-counted and
- * allowing it to provide the standard Object functions (Equals, Hashcode,
- * ToString, Compare, Duplicate). Please note that each certStoreContext must
- * provide Equals and Hashcode functions in order for the caching (on Cert and
- * CertChain) to work correctly. When providing those two functions, it is not
- * required that all the components of the object be hashed or checked for
- * equality, but merely that the functions distinguish between unique
- * instances of the certStoreContext.
- *
- * Once the caller has created the CertStore object, the caller then specifies
- * these CertStore objects in a ProcessingParams object and passes that object
- * to PKIX_ValidateChain or PKIX_BuildChain, which uses the objects to call the
- * user's callback functions as needed during the validation or building
- * process.
- *
- * The order of CertStores stored (as a list) at ProcessingParams determines
- * the order in which certificates are retrieved. Trusted CertStores should
- * precede non-trusted ones on the list of CertStores so their certificates
- * are evaluated ahead of other certificates selected on the basis of the same
- * selector criteria.
- *
- * The CheckTrustCallback function is used when the CertStore object
- * supports trust status, which means a Cert's trust status can be altered
- * dynamically. When a CertStore object is created, if the
- * CheckTrustCallback is initialized to be non-NULL, this CertStore is
- * defaulted as supporting trust. Then whenever a Cert needs to (re)check its
- * trust status, this callback can be invoked. When a Cert is retrieved by
- * a CertStore supports trust, at its GetCertCallback, the CertStore
- * information should be updated in Cert's data structure so the link between
- * the Cert and CertStore exists.
- *
- */
-
-/*
- * FUNCTION: PKIX_CertStore_CertCallback
- * DESCRIPTION:
- *
- * This callback function retrieves from the CertStore pointed to by "store"
- * all the certificates that match the CertSelector pointed to by "selector".
- * It places these certificates in a List and stores a pointer to the List at
- * "pCerts". If no certificates are found which match the CertSelector's
- * criteria, this function stores an empty List at "pCerts". In either case, if
- * the operation is completed, NULL is stored at "pNBIOContext".
- *
- * A CertStore which uses non-blocking I/O may store platform-dependent
- * information at "pNBIOContext" and NULL at "pCerts" to indicate that I/O is
- * pending. A subsequent call to PKIX_CertStore_CertContinue is required to
- * finish the operation and to obtain the List of Certs.
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore from which Certs are to be retrieved.
- * Must be non-NULL.
- * "selector"
- * Address of CertSelector whose criteria must be satisfied.
- * Must be non-NULL.
- * "verifyNode"
- * Parent log node for tracking of filtered out certs.
- * "pNBIOContext"
- * Address at which platform-dependent information is stored if the
- * operation is suspended for non-blocking I/O. Must be non-NULL.
- * "pCerts"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_CertStore_CertCallback)(
- PKIX_CertStore *store,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *verifyNode,
- void **pNBIOContext,
- PKIX_List **pCerts, /* list of PKIX_PL_Cert */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_CertContinue
- * DESCRIPTION:
- *
- * This function continues the non-blocking operation initiated by an earlier
- * call to the CertCallback function, for the CertStore pointed to by "store".
- * If an earlier call did not terminate with the WOULDBLOCK indication (non-NULL
- * value returned in "pNBIOContext") calling this function will return a fatal
- * error. If the operation is completed the certificates found are placed in a
- * List, a pointer to which is stored at "pCerts". If no certificates are found
- * which match the CertSelector's criteria, this function stores an empty List
- * at "pCerts". In either case, if the operation is completed, NULL is stored
- * at "pNBIOContext".
- *
- * If non-blocking I/O is still pending this function stores platform-dependent
- * information at "pNBIOContext" and NULL at "pCerts". A subsequent call to
- * PKIX_CertStore_CertContinue is required to finish the operation and to
- * obtain the List of Certs.
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore from which Certs are to be retrieved.
- * Must be non-NULL.
- * "selector"
- * Address of CertSelector whose criteria must be satisfied.
- * Must be non-NULL.
- * "verifyNode"
- * Parent log node for tracking of filtered out certs.
- * "pNBIOContext"
- * Address at which platform-dependent information is stored if the
- * operation is suspended for non-blocking I/O. Must be non-NULL.
- * "pCerts"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_CertContinue(
- PKIX_CertStore *store,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *verifyNode,
- void **pNBIOContext,
- PKIX_List **pCerts, /* list of PKIX_PL_Cert */
- void *plContext);
-
-typedef PKIX_Error *
-(*PKIX_CertStore_CertContinueFunction)(
- PKIX_CertStore *store,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *verifyNode,
- void **pNBIOContext,
- PKIX_List **pCerts, /* list of PKIX_PL_Cert */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_CRLCallback
- * DESCRIPTION:
- *
- * This callback function retrieves from the CertStore pointed to by "store"
- * all the CRLs that match the CRLSelector pointed to by "selector". It
- * places these CRLs in a List and stores a pointer to the List at "pCRLs".
- * If no CRLs are found which match the CRLSelector's criteria, this function
- * stores an empty List at "pCRLs". In either case, if the operation is
- * completed, NULL is stored at "pNBIOContext".
- *
- * A CertStore which uses non-blocking I/O may store platform-dependent
- * information at "pNBIOContext" and NULL at "pCrls" to indicate that I/O is
- * pending. A subsequent call to PKIX_CertStore_CRLContinue is required to
- * finish the operation and to obtain the List of Crls.
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore from which CRLs are to be retrieved.
- * Must be non-NULL.
- * "selector"
- * Address of CRLSelector whose criteria must be satisfied.
- * Must be non-NULL.
- * "pCrls"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_CertStore_CRLCallback)(
- PKIX_CertStore *store,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrls, /* list of PKIX_PL_CRL */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_ImportCrlCallback
- * DESCRIPTION:
- *
- * The function imports crl list into a cert store. Stores that
- * have local cache may only have that function defined.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore from which CRLs are to be retrieved.
- * Must be non-NULL.
- * "issuerName"
- * Name of the issuer that will be used to track bad der crls.
- * "crlList"
- * Address on the importing crl list.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_CertStore_ImportCrlCallback)(
- PKIX_CertStore *store,
- PKIX_PL_X500Name *issuerName,
- PKIX_List *crlList,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_CheckRevokationByCrlCallback
- * DESCRIPTION:
- *
- * The function checks revocation status of a cert with specified
- * issuer, date. It returns revocation status of a cert and
- * a reason code(if any) if a cert was revoked.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore from which CRLs are to be retrieved.
- * Must be non-NULL.
- * "cert"
- * Certificate which revocation status will be checked.
- * "issuer"
- * Issuer certificate of the "crl".
- * "date"
- * Date of the revocation check.
- * "crlDownloadDone"
- * Indicates, that all needed crl downloads are done by the time of
- * the revocation check.
- * "reasonCode"
- * If cert is revoked, returned reason code for which a cert was revoked.
- * "revStatus"
- * Returned revocation status of the cert. See PKIX_RevocationStatus
- * for more details
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_CertStore_CheckRevokationByCrlCallback)(
- PKIX_CertStore *store,
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- PKIX_Boolean crlDownloadDone,
- PKIX_UInt32 *reasonCode,
- PKIX_RevocationStatus *revStatus,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_CrlContinue
- * DESCRIPTION:
- *
- * This function continues the non-blocking operation initiated by an earlier
- * call to the CRLCallback function, for the CertStore pointed to by "store".
- * If an earlier call did not terminate with the WOULDBLOCK indication (non-NULL
- * value returned in "pNBIOContext") calling this function will return a fatal
- * error. If the operation is completed the crls found are placed in a List, a
- * pointer to which is stored at "pCrls". If no crls are found which match the
- * CRLSelector's criteria, this function stores an empty List at "pCrls". In
- * either case, if the operation is completed, NULL is stored at "pNBIOContext".
- *
- * If non-blocking I/O is still pending this function stores platform-dependent
- * information at "pNBIOContext" and NULL at "pCrls". A subsequent call to
- * PKIX_CertStore_CrlContinue is required to finish the operation and to
- * obtain the List of Crls.
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore from which Crls are to be retrieved.
- * Must be non-NULL.
- * "selector"
- * Address of CRLSelector whose criteria must be satisfied.
- * Must be non-NULL.
- * "pNBIOContext"
- * Address at which platform-dependent information is stored if the
- * operation is suspended for non-blocking I/O. Must be non-NULL.
- * "pCrls"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_CrlContinue(
- PKIX_CertStore *store,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrls, /* list of PKIX_PL_CRL */
- void *plContext);
-
-typedef PKIX_Error *
-(*PKIX_CertStore_CrlContinueFunction)(
- PKIX_CertStore *store,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrls, /* list of PKIX_PL_CRL */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_CheckTrustCallback
- * DESCRIPTION:
- *
- * This callback function rechecks "cert's" trust status from the CertStore
- * pointed to by "store".
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore from which Certs are to be checked.
- * Must be non-NULL.
- * "cert"
- * Address of Cert whose trust status needs to be rechecked.
- * Must be non-NULL.
- * "pTrusted"
- * Address of PKIX_Boolean where the trust status is returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_CertStore_CheckTrustCallback)(
- PKIX_CertStore *store,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pTrusted,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_Create
- * DESCRIPTION:
- *
- * Creates a new CertStore and stores it at "pStore". The new CertStore uses
- * the CertCallback pointed to by "certCallback" and the CRLCallback pointed
- * to by "crlCallback" as its callback functions and uses the Object pointed
- * to by "certStoreContext" as its context . Note that this certStoreContext
- * must be an Object (although any object type), allowing it to be
- * reference-counted and allowing it to provide the standard Object functions
- * (Equals, Hashcode, ToString, Compare, Duplicate). Once created, a
- * CertStore object is immutable, although the underlying repository can
- * change. For example, a CertStore will often be a front-end for a database
- * or directory. The contents of that directory can change after the
- * CertStore object is created, but the CertStore object remains immutable.
- *
- * PARAMETERS:
- * "certCallback"
- * The CertCallback function to be used. Must be non-NULL.
- * "crlCallback"
- * The CRLCallback function to be used. Must be non-NULL.
- * "certContinue"
- * The function to be used to resume a certCallback that returned with a
- * WOULDBLOCK condition. Must be non-NULL if certStore supports non-blocking
- * I/O.
- * "crlContinue"
- * The function to be used to resume a crlCallback that returned with a
- * WOULDBLOCK condition. Must be non-NULL if certStore supports non-blocking
- * I/O.
- * "trustCallback"
- * Address of PKIX_CertStore_CheckTrustCallback which is called to
- * verify the trust status of Certs in this CertStore.
- * "certStoreContext"
- * Address of Object representing the CertStore's context (if any).
- * "cachedFlag"
- * If TRUE indicates data retrieved from CertStore should be cached.
- * "localFlag"
- * Boolean value indicating whether this CertStore is local.
- * "pStore"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_Create(
- PKIX_CertStore_CertCallback certCallback,
- PKIX_CertStore_CRLCallback crlCallback,
- PKIX_CertStore_CertContinueFunction certContinue,
- PKIX_CertStore_CrlContinueFunction crlContinue,
- PKIX_CertStore_CheckTrustCallback trustCallback,
- PKIX_CertStore_ImportCrlCallback importCrlCallback,
- PKIX_CertStore_CheckRevokationByCrlCallback checkRevByCrlCallback,
- PKIX_PL_Object *certStoreContext,
- PKIX_Boolean cachedFlag,
- PKIX_Boolean localFlag,
- PKIX_CertStore **pStore,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_GetCertCallback
- * DESCRIPTION:
- *
- * Retrieves a pointer to "store's" Cert callback function and put it in
- * "pCallback".
- *
- * PARAMETERS:
- * "store"
- * The CertStore whose Cert callback is desired. Must be non-NULL.
- * "pCallback"
- * Address where Cert callback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_GetCertCallback(
- PKIX_CertStore *store,
- PKIX_CertStore_CertCallback *pCallback,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_GetCRLCallback
- * DESCRIPTION:
- *
- * Retrieves a pointer to "store's" CRL callback function and put it in
- * "pCallback".
- *
- * PARAMETERS:
- * "store"
- * The CertStore whose CRL callback is desired. Must be non-NULL.
- * "pCallback"
- * Address where CRL callback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_GetCRLCallback(
- PKIX_CertStore *store,
- PKIX_CertStore_CRLCallback *pCallback,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_GetImportCrlCallback
- * DESCRIPTION:
- *
- * Retrieves a pointer to "store's" Import CRL callback function and put it in
- * "pCallback".
- *
- * PARAMETERS:
- * "store"
- * The CertStore whose CRL callback is desired. Must be non-NULL.
- * "pCallback"
- * Address where CRL callback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_GetImportCrlCallback(
- PKIX_CertStore *store,
- PKIX_CertStore_ImportCrlCallback *pCallback,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_GetCheckRevByCrl
- * DESCRIPTION:
- *
- * Retrieves a pointer to "store's" CRL revocation checker callback function
- * and put it in "pCallback".
- *
- * PARAMETERS:
- * "store"
- * The CertStore whose CRL callback is desired. Must be non-NULL.
- * "pCallback"
- * Address where CRL callback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_GetCrlCheckerFn(
- PKIX_CertStore *store,
- PKIX_CertStore_CheckRevokationByCrlCallback *pCallback,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_GetTrustCallback
- * DESCRIPTION:
- *
- * Retrieves the function pointer to the CheckTrust callback function of the
- * CertStore pointed to by "store" and stores it at "pCallback".
- *
- * PARAMETERS:
- * "store"
- * The CertStore whose CheckTrust callback is desired. Must be non-NULL.
- * "pCallback"
- * Address where CheckTrust callback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_GetTrustCallback(
- PKIX_CertStore *store,
- PKIX_CertStore_CheckTrustCallback *pCallback,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_GetCertStoreContext
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Object representing the context (if any)
- * of the CertStore pointed to by "store" and stores it at
- * "pCertStoreContext".
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore whose context is to be stored. Must be non-NULL.
- * "pCertStoreContext"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_GetCertStoreContext(
- PKIX_CertStore *store,
- PKIX_PL_Object **pCertStoreContext,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_GetCertStoreCacheFlag
- * DESCRIPTION:
- *
- * Retrieves the Boolean cache flag of the CertStore pointed to by "store" and
- * stores it at "pCachedFlag".
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore whose cache flag is to be stored. Must be non-NULL.
- * "pCacheFlag"
- * Address where the result will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_GetCertStoreCacheFlag(
- PKIX_CertStore *store,
- PKIX_Boolean *pCacheFlag,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertStore_GetLocalFlag
- * DESCRIPTION:
- *
- * Retrieves the Boolean localFlag for the CertStore pointed to by "store" and
- * stores it at "pLocalFlag". The localFlag is TRUE if the CertStore can
- * fulfill a request without performing network I/O.
- *
- * PARAMETERS:
- * "store"
- * The CertStore whose Local flag is desired. Must be non-NULL.
- * "pCallback"
- * Address where the Boolean LocalFlag will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertStore_GetLocalFlag(
- PKIX_CertStore *store,
- PKIX_Boolean *pLocalFlag,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_CERTSTORE_H */
diff --git a/security/nss/lib/libpkix/include/pkix_checker.h b/security/nss/lib/libpkix/include/pkix_checker.h
deleted file mode 100755
index 97e29a840..000000000
--- a/security/nss/lib/libpkix/include/pkix_checker.h
+++ /dev/null
@@ -1,394 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines functions associated with the PKIX_CertChainChecker type.
- *
- */
-
-#ifndef _PKIX_CHECKER_H
-#define _PKIX_CHECKER_H
-
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/* PKIX_CertChainChecker
- *
- * PKIX_CertChainCheckers provide a standard way for the caller to insert their
- * own custom checks to validate certificates. This may be useful in many
- * scenarios, including when the caller wishes to validate private certificate
- * extensions. The CheckCallback allows custom certificate processing to take
- * place. Additionally, a CertChainChecker can optionally maintain state
- * between successive calls to the CheckCallback. This certChainCheckerState
- * must be an Object (although any object type), allowing it to be
- * reference-counted and allowing it to provide the standard Object functions
- * (Equals, Hashcode, ToString, Compare, Duplicate). If the caller wishes
- * their CertChainChecker to be used during chain building, their
- * certChainCheckerState object must implement an appropriate Duplicate
- * function. The builder uses this Duplicate function when backtracking.
- *
- * Once the caller has created a CertChainChecker object, the caller then
- * specifies a CertChainChecker object in a ProcessingParams object
- * and passes the ProcessingParams object to PKIX_ValidateChain or
- * PKIX_BuildChain, which uses the objects to call the user's callback
- * functions as needed during the validation or building process.
- *
- * A CertChainChecker may be presented certificates in the "reverse" direction
- * (from trust anchor to target) or in the "forward" direction (from target to
- * trust anchor). All CertChainCheckers must support "reverse checking", while
- * support for "forward checking" is optional, but recommended. If "forward
- * checking" is not supported, building chains may be much less efficient. The
- * PKIX_CertChainChecker_IsForwardCheckingSupported function is used to
- * determine whether forward checking is supported, and the
- * PKIX_CertChainChecker_IsForwardDirectionExpected function is used to
- * determine whether the CertChainChecker has been initialized to expect the
- * certificates to be presented in the "forward" direction.
- */
-
-/*
- * FUNCTION: PKIX_CertChainChecker_CheckCallback
- * DESCRIPTION:
- *
- * This callback function checks whether the specified Cert pointed to by
- * "cert" is valid using "checker's" internal certChainCheckerState (if any)
- * and removes the critical extensions that it processes (if any) from the
- * List of OIDs (possibly empty) pointed to by "unresolvedCriticalExtensions".
- * If the checker finds that the certificate is not valid, an Error pointer is
- * returned.
- *
- * If the checker uses non-blocking I/O, the address of a platform-dependent
- * non-blocking I/O context ("nbioContext") will be stored at "pNBIOContext",
- * which the caller may use, in a platform-dependent way, to wait, poll, or
- * otherwise determine when to try again. If the checker does not use
- * non-blocking I/O, NULL will always be stored at "pNBIOContext". If a non-NULL
- * value was stored, on a subsequent call the checker will attempt to complete
- * the pending I/O and, if successful, NULL will be stored at "pNBIOContext".
- *
- * PARAMETERS:
- * "checker"
- * Address of CertChainChecker whose certChainCheckerState and
- * CheckCallback logic is to be used. Must be non-NULL.
- * "cert"
- * Address of Cert that is to be validated using "checker".
- * Must be non-NULL.
- * "unresolvedCriticalExtensions"
- * Address of List of OIDs that represents the critical certificate
- * extensions that have yet to be resolved. This parameter may be
- * modified during the function call. Must be non-NULL.
- * "pNBIOContext"
- * Address at which is stored a platform-dependent structure indicating
- * whether checking was suspended for non-blocking I/O. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_CertChainChecker_CheckCallback)(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Cert *cert,
- PKIX_List *unresolvedCriticalExtensions, /* list of PKIX_PL_OID */
- void **pNBIOContext,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertChainChecker_Create
- * DESCRIPTION:
- *
- * Creates a new CertChainChecker and stores it at "pChecker". The new
- * CertChainChecker uses the CheckCallback pointed to by "callback" as its
- * callback function. It uses the Object pointed to by "initialState" (if
- * any) as its initial state. As noted above, the initial state Object must
- * provide a custom implementation of PKIX_PL_Object_Duplicate if the
- * CertChainChecker is to be used during certificate chain building.
- *
- * A CertChainChecker may be presented certificates in the "reverse"
- * direction (from trust anchor to target) or in the "forward" direction
- * (from target to trust anchor). All CertChainCheckers must support
- * "reverse checking", while support for "forward checking" is optional. The
- * CertChainChecker is initialized with two Boolean flags that deal with this
- * distinction: "forwardCheckingSupported" and "forwardDirectionExpected".
- * If the "forwardCheckingSupported" Boolean flag is TRUE, it indicates that
- * this CertChainChecker is capable of checking certificates in the "forward"
- * direction (as well as the "reverse" direction, which all CertChainCheckers
- * MUST support). The "forwardDirectionExpected" Boolean flag indicates in
- * which direction the CertChainChecker should expect the certificates to be
- * presented. This is particularly useful for CertChainCheckers that are
- * capable of checking in either the "forward" direction or the "reverse"
- * direction, but have different processing steps depending on the direction.
- *
- * The CertChainChecker also uses the List of OIDs pointed to by "extensions"
- * as the supported certificate extensions. All certificate extensions that
- * the CertChainChecker might possibly recognize and be able to process
- * should be included in the List of supported extensions. If "checker" does
- * not recognize or process any certificate extensions, "extensions" should
- * be set to NULL.
- *
- * PARAMETERS:
- * "callback"
- * The CheckCallback function to be used. Must be non-NULL.
- * "forwardCheckingSupported"
- * A Boolean value indicating whether or not this CertChainChecker is
- * capable of checking certificates in the "forward" direction.
- * "forwardDirectionExpected"
- * A Boolean value indicating whether or not this CertChainChecker should
- * be used to check in the "forward" direction.
- * "extensions"
- * Address of List of OIDs representing the supported extensions.
- * "initialState"
- * Address of Object representing the CertChainChecker's initial state
- * (if any).
- * "pChecker"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertChainChecker_Create(
- PKIX_CertChainChecker_CheckCallback callback,
- PKIX_Boolean forwardCheckingSupported,
- PKIX_Boolean forwardDirectionExpected,
- PKIX_List *extensions, /* list of PKIX_PL_OID */
- PKIX_PL_Object *initialState,
- PKIX_CertChainChecker **pChecker,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertChainChecker_GetCheckCallback
- * DESCRIPTION:
- *
- * Retrieves a pointer to "checker's" Check callback function and puts it in
- * "pCallback".
- *
- * PARAMETERS:
- * "checker"
- * The CertChainChecker whose Check callback is desired. Must be non-NULL.
- * "pCallback"
- * Address where Check callback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertChainChecker_GetCheckCallback(
- PKIX_CertChainChecker *checker,
- PKIX_CertChainChecker_CheckCallback *pCallback,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertChainChecker_IsForwardCheckingSupported
- * DESCRIPTION:
- *
- * Checks whether forward checking is supported by the CertChainChecker
- * pointed to by "checker" and stores the Boolean result at
- * "pForwardCheckingSupported".
- *
- * A CertChainChecker may be presented certificates in the "reverse"
- * direction (from trust anchor to target) or in the "forward" direction
- * (from target to trust anchor). All CertChainCheckers must support
- * "reverse checking", while support for "forward checking" is optional. This
- * function is used to determine whether forward checking is supported.
- *
- * PARAMETERS:
- * "checker"
- * The CertChainChecker whose ability to validate certificates in the
- * "forward" direction is to be checked. Must be non-NULL.
- * "pForwardCheckingSupported"
- * Destination of the Boolean result. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertChainChecker_IsForwardCheckingSupported(
- PKIX_CertChainChecker *checker,
- PKIX_Boolean *pForwardCheckingSupported,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertChainChecker_IsForwardDirectionExpected
- * DESCRIPTION:
- *
- * Checks whether the CertChainChecker pointed to by "checker" has been
- * initialized to expect the certificates to be presented in the "forward"
- * direction and stores the Boolean result at "pForwardDirectionExpected".
- *
- * A CertChainChecker may be presented certificates in the "reverse"
- * direction (from trust anchor to target) or in the "forward" direction
- * (from target to trust anchor). All CertChainCheckers must support
- * "reverse checking", while support for "forward checking" is optional. This
- * function is used to determine in which direction the CertChainChecker
- * expects the certificates to be presented.
- *
- * PARAMETERS:
- * "checker"
- * The CertChainChecker that has been initialized to expect certificates
- * in either the "forward" or "reverse" directions. Must be non-NULL.
- * "pForwardDirectionExpected"
- * Destination of the Boolean result. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertChainChecker_IsForwardDirectionExpected(
- PKIX_CertChainChecker *checker,
- PKIX_Boolean *pForwardDirectionExpected,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertChainChecker_GetSupportedExtensions
- * DESCRIPTION:
- *
- * Retrieves a pointer to a List of OIDs (each OID corresponding to a
- * certificate extension supported by the CertChainChecker pointed to by
- * "checker") and stores it at "pExtensions". All certificate extensions that
- * the CertChainChecker might possibly recognize and be able to process
- * should be included in the List of supported extensions. If "checker" does
- * not recognize or process any certificate extensions, this function stores
- * NULL at "pExtensions".
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "checker"
- * Address of CertChainChecker whose supported extension OIDs are to be
- * stored. Must be non-NULL.
- * "pExtensions"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertChainChecker_GetSupportedExtensions(
- PKIX_CertChainChecker *checker,
- PKIX_List **pExtensions, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertChainChecker_GetCertChainCheckerState
- * DESCRIPTION:
- *
- * Retrieves a pointer to a PKIX_PL_Object representing the internal state
- * (if any) of the CertChainChecker pointed to by "checker" and stores it at
- * "pCertChainCheckerState".
- *
- * PARAMETERS:
- * "checker"
- * Address of CertChainChecker whose state is to be stored.
- * Must be non-NULL.
- * "pCertChainCheckerState"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertChainChecker_GetCertChainCheckerState(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Object **pCertChainCheckerState,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CertChainChecker_SetCertChainCheckerState
- * DESCRIPTION:
- *
- * Sets the internal state of the CertChainChecker pointed to by "checker"
- * using the Object pointed to by "certChainCheckerState". If "checker" needs
- * a NULL internal state, "certChainCheckerState" should be set to NULL.
- *
- * PARAMETERS:
- * "checker"
- * Address of CertChainChecker whose state is to be set. Must be non-NULL.
- * "certChainCheckerState"
- * Address of Object representing internal state.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "checker"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CertChainChecker_SetCertChainCheckerState(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Object *certChainCheckerState,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_CHECKER_H */
diff --git a/security/nss/lib/libpkix/include/pkix_crlsel.h b/security/nss/lib/libpkix/include/pkix_crlsel.h
deleted file mode 100755
index 491e72f43..000000000
--- a/security/nss/lib/libpkix/include/pkix_crlsel.h
+++ /dev/null
@@ -1,759 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines functions associated with the PKIX_CRLSelector and the
- * PKIX_ComCRLSelParams types.
- *
- */
-
-
-#ifndef _PKIX_CRLSEL_H
-#define _PKIX_CRLSEL_H
-
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/* PKIX_CRLSelector
- *
- * PKIX_CRLSelectors provide a standard way for the caller to select CRLs
- * based on particular criteria. A CRLSelector is typically used by libpkix
- * to retrieve CRLs from a CertStore during certificate chain validation or
- * building. (see pkix_certstore.h) For example, the caller may wish to only
- * select those CRLs that have a particular issuer or a particular value for a
- * private CRL extension. The MatchCallback allows the caller to specify the
- * custom matching logic to be used by a CRLSelector.
-
- * By default, the MatchCallback is set to point to the default implementation
- * provided by libpkix, which understands how to process the most common
- * parameters. If the default implementation is used, the caller should set
- * these common parameters using PKIX_CRLSelector_SetCommonCRLSelectorParams.
- * Any common parameter that is not set is assumed to be disabled, which means
- * the default MatchCallback implementation will select all CRLs without
- * regard to that particular disabled parameter. For example, if the
- * MaxCRLNumber parameter is not set, MatchCallback will not filter out any
- * CRL based on its CRL number. As such, if no parameters are set, all are
- * disabled and any CRL will match. If a parameter is disabled, its associated
- * PKIX_ComCRLSelParams_Get* function returns a default value of NULL.
- *
- * If a custom implementation is desired, the default implementation can be
- * overridden by calling PKIX_CRLSelector_SetMatchCallback. In this case, the
- * CRLSelector can be initialized with a crlSelectorContext, which is where
- * the caller can specify the desired parameters the caller wishes to match
- * against. Note that this crlSelectorContext must be a PKIX_PL_Object,
- * allowing it to be reference-counted and allowing it to provide the standard
- * PKIX_PL_Object functions (Equals, Hashcode, ToString, Compare, Duplicate).
- *
- */
-
-/*
- * FUNCTION: PKIX_CRLSelector_MatchCallback
- * DESCRIPTION:
- *
- * This callback function determines whether the specified CRL pointed to by
- * "crl" matches the criteria of the CRLSelector pointed to by "selector".
- * If the CRL matches the CRLSelector's criteria, PKIX_TRUE is stored at
- * "pMatch". Otherwise PKIX_FALSE is stored at "pMatch".
- *
- * PARAMETERS:
- * "selector"
- * Address of CRLSelector whose MatchCallback logic and parameters are
- * to be used. Must be non-NULL.
- * "crl"
- * Address of CRL that is to be matched using "selector". Must be non-NULL.
- * "pMatch"
- * Address at which Boolean result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same objects.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_CRLSelector_MatchCallback)(
- PKIX_CRLSelector *selector,
- PKIX_PL_CRL *crl,
- PKIX_Boolean *pMatch,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CRLSelector_Create
- * DESCRIPTION:
- *
- * Creates a new CRLSelector using the Object pointed to by
- * "crlSelectorContext" (if any) and stores it at "pSelector". As noted
- * above, by default, the MatchCallback is set to point to the default
- * implementation provided by libpkix, which understands how to process
- * ComCRLSelParams. This is overridden if the MatchCallback pointed to by
- * "callback" is not NULL, in which case the parameters are specified using
- * the Object pointed to by "crlSelectorContext".
- *
- * PARAMETERS:
- * "issue"
- * crl issuer.
- * "crlDpList"
- * distribution points list
- * "callback"
- * The MatchCallback function to be used.
- * "pSelector"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CRLSelector_Create(
- PKIX_PL_Cert *issuer,
- PKIX_List *crlDpList,
- PKIX_PL_Date *date,
- PKIX_CRLSelector **pSelector,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CRLSelector_GetMatchCallback
- * DESCRIPTION:
- *
- * Retrieves a pointer to "selector's" Match callback function and puts it in
- * "pCallback".
- *
- * PARAMETERS:
- * "selector"
- * The CRLSelector whose Match callback is desired. Must be non-NULL.
- * "pCallback"
- * Address where Match callback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CRLSelector_GetMatchCallback(
- PKIX_CRLSelector *selector,
- PKIX_CRLSelector_MatchCallback *pCallback,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CRLSelector_GetCRLSelectorContext
- * DESCRIPTION:
- *
- * Retrieves a pointer to a PKIX_PL_Object representing the context (if any)
- * of the CRLSelector pointed to by "selector" and stores it at
- * "pCRLSelectorContext".
- *
- * PARAMETERS:
- * "selector"
- * Address of CRLSelector whose context is to be stored. Must be non-NULL.
- * "pCRLSelectorContext"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CRLSelector_GetCRLSelectorContext(
- PKIX_CRLSelector *selector,
- void **pCRLSelectorContext,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CRLSelector_GetCommonCRLSelectorParams
- * DESCRIPTION:
- *
- * Retrieves a pointer to the ComCRLSelParams object that represent the common
- * parameters of the CRLSelector pointed to by "selector" and stores it at
- * "pCommonCRLSelectorParams". If there are no common parameters stored with
- * the CRLSelector, this function stores NULL at "pCommonCRLSelectorParams".
- *
- * PARAMETERS:
- * "selector"
- * Address of CRLSelector whose ComCRLSelParams are to be stored.
- * Must be non-NULL.
- * "pCommonCRLSelectorParams"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CRLSelector_GetCommonCRLSelectorParams(
- PKIX_CRLSelector *selector,
- PKIX_ComCRLSelParams **pCommonCRLSelectorParams,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_CRLSelector_SetCommonCRLSelectorParams
- * DESCRIPTION:
- *
- * Sets the common parameters for the CRLSelector pointed to by "selector"
- * using the ComCRLSelParams pointed to by "commonCRLSelectorParams".
- *
- * PARAMETERS:
- * "selector"
- * Address of CRLSelector whose common parameters are to be set.
- * Must be non-NULL.
- * "commonCRLSelectorParams"
- * Address of ComCRLSelParams representing the common parameters.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "selector"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_CRLSelector_SetCommonCRLSelectorParams(
- PKIX_CRLSelector *selector,
- PKIX_ComCRLSelParams *commonCRLSelectorParams,
- void *plContext);
-
-/* PKIX_ComCRLSelParams
- *
- * PKIX_ComCRLSelParams are X.509 parameters commonly used with CRLSelectors,
- * especially determining which CRLs to retrieve from a CertStore.
- * PKIX_ComCRLSelParams are typically used with those CRLSelectors that use
- * the default implementation of MatchCallback, which understands how to
- * process ComCRLSelParams.
- */
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_Create
- * DESCRIPTION:
- *
- * Creates a new ComCRLSelParams object and stores it at "pParams".
- *
- * PARAMETERS:
- * "pParams"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_Create(
- PKIX_ComCRLSelParams **pParams,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetIssuerNames
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of X500Names (if any) representing the
- * issuer names criterion that is set in the ComCRLSelParams pointed to by
- * "params" and stores it at "pNames". In order to match against this
- * criterion, a CRL's IssuerName must match at least one of the criterion's
- * issuer names.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pNames", in which case all CRLs are considered to match.
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParams whose issuer names criterion (if any) is to
- * be stored. Must be non-NULL.
- * "pNames"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetIssuerNames(
- PKIX_ComCRLSelParams *params,
- PKIX_List **pNames, /* list of PKIX_PL_X500Name */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetIssuerNames
- * DESCRIPTION:
- *
- * Sets the issuer names criterion of the ComCRLSelParams pointed to by
- * "params" using a List of X500Names pointed to by "names". In order to match
- * against this criterion, a CRL's IssuerName must match at least one of the
- * criterion's issuer names.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParamsParams whose issuer names criterion is to be
- * set. Must be non-NULL.
- * "names"
- * Address of List of X500Names used to set the criterion
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetIssuerNames(
- PKIX_ComCRLSelParams *params,
- PKIX_List *names, /* list of PKIX_PL_X500Name */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_AddIssuerName
- * DESCRIPTION:
- *
- * Adds to the issuer names criterion of the ComCRLSelParams pointed to by
- * "params" using the X500Name pointed to by "name". In order to match
- * against this criterion, a CRL's IssuerName must match at least one of the
- * criterion's issuer names.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParams whose issuer names criterion is to be added
- * to. Must be non-NULL.
- * "name"
- * Address of X500Name to be added.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_AddIssuerName(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_X500Name *name,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetCertificateChecking
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Cert (if any) representing the certificate whose
- * revocation status is being checked. This is not a criterion. It is simply
- * optional information that may help a CertStore find relevant CRLs.
- *
- * If "params" does not have a certificate set, this function stores NULL at
- * "pCert", in which case there is no optional information to provide.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParams whose certificate being checked (if any) is
- * to be stored. Must be non-NULL.
- * "pCert"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetCertificateChecking(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_Cert **pCert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetCertificateChecking
- * DESCRIPTION:
- *
- * Sets the ComCRLSelParams pointed to by "params" with the certificate
- * (pointed to by "cert") whose revocation status is being checked. This is
- * not a criterion. It is simply optional information that may help a
- * CertStore find relevant CRLs.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParams whose certificate being checked is to be
- * set. Must be non-NULL.
- * "cert"
- * Address of Cert whose revocation status is being checked
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetCertificateChecking(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_Cert *cert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetDateAndTime
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Date (if any) representing the dateAndTime
- * criterion that is set in the ComCRLSelParams pointed to by "params" and
- * stores it at "pDate". In order to match against this criterion, a CRL's
- * thisUpdate component must be less than or equal to the criterion's
- * dateAndTime and the CRL's nextUpdate component must be later than the
- * criterion's dateAndTime. There is no match if the CRL does not contain a
- * nextUpdate component.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pDate", in which case all CRLs are considered to match.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParams whose dateAndTime criterion (if any) is to
- * be stored. Must be non-NULL.
- * "pDate"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetDateAndTime(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_Date **pDate,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetDateAndTime
- * DESCRIPTION:
- *
- * Sets the dateAndTime criterion of the ComCRLSelParams pointed to by
- * "params" using a Date pointed to by "date". In order to match against this
- * criterion, a CRL's thisUpdate component must be less than or equal to the
- * criterion's dateAndTime and the CRL's nextUpdate component must be later
- * than the criterion's dateAndTime. There is no match if the CRL does not
- * contain a nextUpdate component.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParamsParams whose dateAndTime criterion is to be
- * set. Must be non-NULL.
- * "date"
- * Address of Date used to set the criterion
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetDateAndTime(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_Date *date,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetNISTPolicyEnabled
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Boolean representing the NIST CRL policy
- * activation flag that is set in the ComCRLSelParams pointed to by "params"
- * and stores it at "enabled". If enabled, a CRL must have nextUpdate field.
- *
- * Default value for this flag is TRUE.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParams whose NIST CRL policy criterion is to
- * be stored. Must be non-NULL.
- * "pEnabled"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetNISTPolicyEnabled(
- PKIX_ComCRLSelParams *params,
- PKIX_Boolean *pEnabled,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetNISTPolicyEnabled
- * DESCRIPTION:
- *
- * Sets the NIST crl policy criterion of the ComCRLSelParams pointed to by
- * "params" using a "enabled" flag. In order to match against this
- * criterion, a CRL's nextUpdate must be available and criterion's
- * dataAndTime must be within thisUpdate and nextUpdate time period.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParamsParams whose NIST CRL policy criterion
- * is to be set. Must be non-NULL.
- * "enabled"
- * Address of Bollean used to set the criterion
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetNISTPolicyEnabled(
- PKIX_ComCRLSelParams *params,
- PKIX_Boolean enabled,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetMaxCRLNumber
- * DESCRIPTION:
- *
- * Retrieves a pointer to the BigInt (if any) representing the maxCRLNumber
- * criterion that is set in the ComCRLSelParams pointed to by "params" and
- * stores it at "pNumber". In order to match against this criterion, a CRL
- * must have a CRL number extension whose value is less than or equal to the
- * criterion's value.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pNumber", in which case all CRLs are considered to match.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParams whose maxCRLNumber criterion (if any) is to
- * be stored. Must be non-NULL.
- * "pNumber"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetMaxCRLNumber(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_BigInt **pNumber,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetMaxCRLNumber
- * DESCRIPTION:
- *
- * Sets the maxCRLNumber criterion of the ComCRLSelParams pointed to by
- * "params" using a BigInt pointed to by "number". In order to match against
- * this criterion, a CRL must have a CRL number extension whose value is less
- * than or equal to the criterion's value.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParamsParams whose maxCRLNumber criterion is to be
- * set. Must be non-NULL.
- * "number"
- * Address of BigInt used to set the criterion
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetMaxCRLNumber(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_BigInt *number,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetMinCRLNumber
- * DESCRIPTION:
- *
- * Retrieves a pointer to the BigInt (if any) representing the minCRLNumber
- * criterion that is set in the ComCRLSelParams pointed to by "params" and
- * stores it at "pNumber". In order to match against this criterion, a CRL
- * must have a CRL number extension whose value is greater than or equal to
- * the criterion's value.
- *
- * If "params" does not have this criterion set, this function stores NULL at
- * "pNumber", in which case all CRLs are considered to match.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParams whose minCRLNumber criterion (if any) is to
- * be stored. Must be non-NULL.
- * "pNumber"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetMinCRLNumber(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_BigInt **pNumber,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetMinCRLNumber
- * DESCRIPTION:
- *
- * Sets the minCRLNumber criterion of the ComCRLSelParams pointed to by
- * "params" using a BigInt pointed to by "number". In order to match against
- * this criterion, a CRL must have a CRL number extension whose value is
- * greater than or equal to the criterion's value.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParamsParams whose minCRLNumber criterion is to be
- * set. Must be non-NULL.
- * "number"
- * Address of BigInt used to set the criterion
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetMinCRLNumber(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_BigInt *number,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetCrlDp
- * DESCRIPTION:
- *
- * Sets crldp list that can be used to download a crls.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCRLSelParamsParams whose minCRLNumber criterion is to be
- * set. Must be non-NULL.
- * "crldpList"
- * A list of CRLDPs. Can be an emptry list.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error*
-PKIX_ComCRLSelParams_SetCrlDp(
- PKIX_ComCRLSelParams *params,
- PKIX_List *crldpList,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_CRLSEL_H */
diff --git a/security/nss/lib/libpkix/include/pkix_errorstrings.h b/security/nss/lib/libpkix/include/pkix_errorstrings.h
deleted file mode 100755
index b6f7d7684..000000000
--- a/security/nss/lib/libpkix/include/pkix_errorstrings.h
+++ /dev/null
@@ -1,1097 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * This file is intended to be included after different definitions of
- * PKIX_ERRORENTRY. It is included in pkixt.h to define a number for each error
- * by defining PKIX_ERRORENTRY(x,y) as PKIX_ ## x and then listing thim within
- * an enum. It is included in pkix_error.c to define an array of error strings
- * by defining PKIX_ERRORENTRY(x,y) #y and then listing thim within an array
- * const char * const PKIX_ErrorText[]
- */
-/* ALLOCERROR should always be the first */
-PKIX_ERRORENTRY(ALLOCERROR,Allocation Error,SEC_ERROR_NO_MEMORY),
-PKIX_ERRORENTRY(ADDHEADERFUNCTIONNOTSUPPORTED,AddHeader function not supported,0),
-PKIX_ERRORENTRY(ADDTOVERIFYLOGFAILED,pkix_AddToVerifyLog failed,0),
-PKIX_ERRORENTRY(AIAMGRCREATEFAILED,PKIX_PL_AIAMgr_Create failed,0),
-PKIX_ERRORENTRY(AIAMGRFINDLDAPCLIENTFAILED,pkix_pl_AiaMgr_FindLDAPClient failed,0),
-PKIX_ERRORENTRY(AIAMGRGETAIACERTSFAILED,PKIX_PL_AIAMgr_GetAIACerts failed,SEC_ERROR_UNKNOWN_ISSUER),
-PKIX_ERRORENTRY(AIAMGRGETHTTPCERTSFAILED,pkix_pl_AIAMgr_GetHTTPCerts failed,0),
-PKIX_ERRORENTRY(AIAMGRGETLDAPCERTSFAILED,pkix_pl_AIAMgr_GetLDAPCerts failed,0),
-PKIX_ERRORENTRY(ALGORITHMBYTESLENGTH0,Algorithm bytes length is 0,0),
-PKIX_ERRORENTRY(ALLOCATENEWCERTGENERALNAMEFAILED,Allocate new CERTGeneralName failed,0),
-PKIX_ERRORENTRY(AMBIGUOUSPARENTAGEOFVERIFYNODE,Ambiguous parentage of VerifyNode,0),
-PKIX_ERRORENTRY(ANCHORDIDNOTCHAINTOCERT,Anchor did not chain to Cert,SEC_ERROR_UNKNOWN_ISSUER),
-PKIX_ERRORENTRY(ANCHORDIDNOTPASSCERTSELECTORCRITERIA,Anchor did not pass CertSelector criteria,0),
-PKIX_ERRORENTRY(APPENDLISTFAILED,pkix_pl_AppendList failed,0),
-PKIX_ERRORENTRY(ARGUMENTNOTSTRING,Argument is not a String,0),
-PKIX_ERRORENTRY(ARGUMENTSNOTBIGINTS,Arguments are not BigInts,0),
-PKIX_ERRORENTRY(ARGUMENTSNOTBYTEARRAYS,Arguments are not Byte Arrays,0),
-PKIX_ERRORENTRY(ARGUMENTSNOTDATES,Arguments are not Dates,0),
-PKIX_ERRORENTRY(ARGUMENTSNOTOIDS,Arguments are not OIDs,0),
-PKIX_ERRORENTRY(ATTEMPTTOADDDUPLICATEKEY,Attempt to add duplicate key,0),
-PKIX_ERRORENTRY(ATTEMPTTODECODEANINCOMPLETERESPONSE,Attempt to decode an incomplete response,SEC_ERROR_BAD_DER),
-PKIX_ERRORENTRY(ATTEMPTTODECREFALLOCERROR,Attempt to DecRef Alloc Error,0),
-PKIX_ERRORENTRY(ATTEMPTTOINCREFALLOCERROR,Attempt to IncRef Alloc Error,0),
-PKIX_ERRORENTRY(BADHTTPRESPONSE,Bad Http Response,SEC_ERROR_BAD_HTTP_RESPONSE),
-PKIX_ERRORENTRY(BASICCONSTRAINTSCHECKERINITIALIZEFAILED,pkix_BasicConstraintsChecker_Initialize failed,0),
-PKIX_ERRORENTRY(BASICCONSTRAINTSCHECKERSTATECREATEFAILED,PKIX_BasicConstraintsCheckerState_Create failed,0),
-PKIX_ERRORENTRY(BASICCONSTRAINTSGETCAFLAGFAILED,PKIX_PL_BasicConstraints_GetCAFlag failed,0),
-PKIX_ERRORENTRY(BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED,PKIX_PL_BasicConstraints_GetPathLenConstraint failed,0),
-PKIX_ERRORENTRY(BASICCONSTRAINTSVALIDATIONFAILEDCA,PKIX_BasicConstraints validation failed: CA Flag not set,SEC_ERROR_CA_CERT_INVALID),
-PKIX_ERRORENTRY(BASICCONSTRAINTSVALIDATIONFAILEDLN,PKIX_BasicConstraints validation failed: maximum length mismatch,SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID),
-PKIX_ERRORENTRY(BIGINTCOMPARATORFAILED,pkix_pl_BigInt_Comparator failed,0),
-PKIX_ERRORENTRY(BIGINTCREATEWITHBYTESFAILED,pkix_pl_BigInt_CreateWithBytes failed,0),
-PKIX_ERRORENTRY(BIGINTEQUALSFAILED,PKIX_PL_BigInt_Equals failed,0),
-PKIX_ERRORENTRY(BIGINTLENGTH0INVALID,BigInt length 0 is invalid,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(BIGINTTOSTRINGFAILED,pkix_pl_BigInt_ToString failed,0),
-PKIX_ERRORENTRY(BIGINTTOSTRINGHELPERFAILED,PKIX_PL_BigInt_ToString_Helper failed,0),
-PKIX_ERRORENTRY(BINDREJECTEDBYSERVER,BIND rejected by server,SEC_ERROR_BAD_LDAP_RESPONSE),
-PKIX_ERRORENTRY(BUILDANDVALIDATECHAINFAILED,Failed to build and validate a chain,0),
-PKIX_ERRORENTRY(BUILDBUILDSELECTORANDPARAMSFAILED,pkix_Build_BuildSelectorAndParams failed,0),
-PKIX_ERRORENTRY(BUILDCOMBINEWITHTRUSTFAILED,pkix_Build_CombineWithTrust failed,0),
-PKIX_ERRORENTRY(BUILDFORWARDDEPTHFIRSTSEARCHFAILED,pkix_BuildForwardDepthFirstSearch failed,0),
-PKIX_ERRORENTRY(BUILDGATHERCERTSFAILED,pkix_Build_GatherCerts failed,0),
-PKIX_ERRORENTRY(BUILDGETRESOURCELIMITSFAILED,pkix_Build_GetResourceLimits failed,0),
-PKIX_ERRORENTRY(BUILDINITIATEBUILDCHAINFAILED,pkix_Build_InitiateBuildChain failed,0),
-PKIX_ERRORENTRY(BUILDRESULTCREATEFAILED,pkix_BuildResult_Create failed,0),
-PKIX_ERRORENTRY(BUILDRESULTGETCERTCHAINFAILED,PKIX_BuildResult_GetCertChain failed,0),
-PKIX_ERRORENTRY(BUILDRESULTGETVALIDATERESULTFAILED,PKIX_BuildResult_GetValidateResult failed,0),
-PKIX_ERRORENTRY(BUILDREVCHECKPREPFAILED,pkix_Build_RevCheckPrep failed,0),
-PKIX_ERRORENTRY(BUILDSORTCANDIDATECERTSFAILED,pkix_Build_SortCandidateCerts failed,0),
-PKIX_ERRORENTRY(BUILDSTATECREATEFAILED,pkix_BuildState_Create failed,0),
-PKIX_ERRORENTRY(BUILDTRYSHORTCUTFAILED,pkix_Build_TryShortcut failed,0),
-PKIX_ERRORENTRY(BUILDUPDATEDATEFAILED,pkix_Build_UpdateDate failed,0),
-PKIX_ERRORENTRY(BUILDVALIDATEENTIRECHAINFAILED,pkix_Build_ValidateEntireChain failed,0),
-PKIX_ERRORENTRY(BUILDVALIDATIONCHECKERSFAILED,pkix_Build_ValidationCheckers failed,0),
-PKIX_ERRORENTRY(BUILDVERIFYCERTIFICATEFAILED,pkix_Build_VerifyCertificate failed,0),
-PKIX_ERRORENTRY(BYTEARRAYCOMPARATORFAILED,pkix_pl_ByteArray_Comparator failed,0),
-PKIX_ERRORENTRY(BYTEARRAYCREATEFAILED,PKIX_PL_ByteArray_Create failed,0),
-PKIX_ERRORENTRY(BYTEARRAYEQUALSFAILED,PKIX_PL_ByteArray_Equals failed,0),
-PKIX_ERRORENTRY(BYTEARRAYGETLENGTHFAILED,PKIX_PL_ByteArray_GetLength failed,0),
-PKIX_ERRORENTRY(BYTEARRAYGETPOINTERFAILED,PKIX_PL_ByteArray_GetPointer failed,0),
-PKIX_ERRORENTRY(BYTEARRAYTOHEXSTRINGFAILED,pkix_pl_ByteArray_ToHexString failed,0),
-PKIX_ERRORENTRY(BYTEARRAYTOSTRINGFAILED,PKIX_PL_ByteArray_ToString failed,0),
-PKIX_ERRORENTRY(CACHECERTADDFAILED,pkix_CacheCert_Add failed,0),
-PKIX_ERRORENTRY(CACHECERTCHAINADDFAILED,pkix_CacheCertChain_Add failed,0),
-PKIX_ERRORENTRY(CACHECERTCHAINLOOKUPFAILED,pkix_CacheCertChain_Lookup failed,0),
-PKIX_ERRORENTRY(CACHECERTCHAINREMOVEFAILED,pkix_CacheCertChain_Remove failed,0),
-PKIX_ERRORENTRY(CACHECRLENTRYADDFAILED,pkix_CacheCrlEntry_Add failed,0),
-PKIX_ERRORENTRY(CACHECRLENTRYLOOKUPFAILED,pkix_CacheCrlEntry_Lookup failed,0),
-PKIX_ERRORENTRY(CALLOCFAILED,PKIX_PL_Calloc failed,0),
-PKIX_ERRORENTRY(CANNOTAQUIRECRLDER,Failed to get DER CRL,0),
-PKIX_ERRORENTRY(CANNOTCONVERTCERTUSAGETOPKIXKEYANDEKUSAGES, Fail to convert certificate usage to pkix KU and EKU,0),
-PKIX_ERRORENTRY(CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY,Cannot open CollectionCertStoreContext directory,0),
-PKIX_ERRORENTRY(CANTCREATESTRING,Cannot create PKIX_PL_String,0),
-PKIX_ERRORENTRY(CANTDECODEBINDRESPONSEFROMSERVER,Cannot decode BIND response from server,SEC_ERROR_BAD_LDAP_RESPONSE),
-PKIX_ERRORENTRY(CANTDECODESEARCHRESPONSEFROMSERVER,Cannot decode SEARCH response from server,SEC_ERROR_BAD_LDAP_RESPONSE),
-PKIX_ERRORENTRY(CANTENABLEREVOCATIONWITHOUTCERTSTORE,Cannot enable Revocation without CertStore,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(CANTLOADLIBSMIME,Cannot load smime3 library,0),
-PKIX_ERRORENTRY(CANTREREGISTERSYSTEMTYPE,Cannot reregister system type,0),
-PKIX_ERRORENTRY(CERTARECERTPOLICIESCRITICALFAILED,PKIX_PL_Cert_AreCertPoliciesCritical failed,0),
-PKIX_ERRORENTRY(CERTBASICCONSTRAINTSCREATEFAILED,pkix_pl_CertBasicConstraints_Create failed,0),
-PKIX_ERRORENTRY(CERTBASICCONSTRAINTSTOSTRINGFAILED,PKIX_PL_CertBasicConstraints_ToString failed,0),
-PKIX_ERRORENTRY(CERTCHAINCHECKERCHECKCALLBACKFAILED,PKIX_CertChainChecker_CheckCallback failed,0),
-PKIX_ERRORENTRY(CERTCHAINCHECKERCHECKFAILED,PKIX_CertChainChecker_Check failed,0),
-PKIX_ERRORENTRY(CERTCHAINCHECKERCREATEFAILED,PKIX_CertChainChecker_Create failed,0),
-PKIX_ERRORENTRY(CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED,PKIX_CertChainChecker_GetCertChainCheckerState failed,0),
-PKIX_ERRORENTRY(CERTCHAINCHECKERGETCHECKCALLBACKFAILED,PKIX_CertChainChecker_GetCheckCallback failed,0),
-PKIX_ERRORENTRY(CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED,PKIX_CertChainChecker_GetSupportedExtensions failed,0),
-PKIX_ERRORENTRY(CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED,PKIX_CertChainChecker_IsForwardCheckingSupported failed,0),
-PKIX_ERRORENTRY(CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED,PKIX_CertChainChecker_SetCertChainCheckerState failed,0),
-PKIX_ERRORENTRY(CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION,CertChain fails Certificate Policy validation,SEC_ERROR_POLICY_VALIDATION_FAILED),
-PKIX_ERRORENTRY(CERTCHAINTONSSCHAINFAILED,Fail to convert pkix cert chain to nss cert chain,0),
-PKIX_ERRORENTRY(CERTCHAINTOPKIXCERTLISTFAILED,Failed to convert nss cert chain to pkix cert chain,0),
-PKIX_ERRORENTRY(CERTCHECKCERTTYPEFAILED,Check cert type failed,SEC_ERROR_INADEQUATE_CERT_TYPE),
-PKIX_ERRORENTRY(CERTCHECKCERTVALIDTIMESFAILED,CERT_CheckCertValidTimes failed,SEC_ERROR_EXPIRED_CERTIFICATE),
-PKIX_ERRORENTRY(CERTCHECKCRLFAILED,Fail to get crl cache issued by cert,0),
-PKIX_ERRORENTRY(CERTCHECKEXTENDEDKEYUSAGEFAILED,pkix_pl_Cert_CheckExtendedKeyUsage failed,0),
-PKIX_ERRORENTRY(CERTCHECKKEYUSAGEFAILED,CERT_CheckKeyUsage failed,SEC_ERROR_INADEQUATE_KEY_USAGE),
-PKIX_ERRORENTRY(CERTCHECKNAMECONSTRAINTSFAILED,PKIX_PL_Cert_CheckNameConstraints failed,0),
-PKIX_ERRORENTRY(CERTCHECKVALIDITYFAILED,PKIX_PL_Cert_CheckValidity failed,0),
-PKIX_ERRORENTRY(CERTCOMPLETECRLDECODEDENTRIESFAILED,CERT_CompleteCRLDecodedEntries failed,0),
-PKIX_ERRORENTRY(CERTCOPYNAMECONSTRAINTFAILED,CERT_CopyNameConstraint failed,0),
-PKIX_ERRORENTRY(CERTCOPYNAMEFAILED,CERT_CopyName failed,0),
-PKIX_ERRORENTRY(CERTCREATEFAILED,PKIX_PL_Cert_Create failed,0),
-PKIX_ERRORENTRY(CERTCREATEGENERALNAMELISTFAILED,CERT_CreateGeneralNameList failed,0),
-PKIX_ERRORENTRY(CERTCREATETOLISTFAILED,pkix_pl_Cert_CreateToList failed,0),
-PKIX_ERRORENTRY(CERTCREATEWITHNSSCERTFAILED,pkix_pl_Cert_CreateWithNSSCert failed,0),
-PKIX_ERRORENTRY(CERTDECODEALTNAMEEXTENSIONFAILED,CERT_DecodeAltNameExtension failed,0),
-PKIX_ERRORENTRY(CERTDECODECERTIFICATEPOLICIESEXTENSIONFAILED,CERT_DecodeCertificatePoliciesExtension failed,0),
-PKIX_ERRORENTRY(CERTDECODEDERCERTIFICATEFAILED,CERT_DecodeDERCertificate failed,0),
-PKIX_ERRORENTRY(CERTDECODEDERCRLFAILED,CERT_DecodeDERCrl failed,0),
-PKIX_ERRORENTRY(CERTDECODEINHIBITANYEXTENSIONFAILED,CERT_DecodeInhibitAnyExtension failed,0),
-PKIX_ERRORENTRY(CERTDECODEINHIBITANYPOLICYFAILED,pkix_pl_Cert_DecodeInhibitAnyPolicy failed,0),
-PKIX_ERRORENTRY(CERTDECODEOIDSEQUENCEFAILED,CERT_DecodeOidSequence failed,0),
-PKIX_ERRORENTRY(CERTDECODEPOLICYCONSTRAINTSEXTENSIONFAILED,CERT_DecodePolicyConstraintsExtension failed,0),
-PKIX_ERRORENTRY(CERTDECODEPOLICYCONSTRAINTSFAILED,pkix_pl_Cert_DecodePolicyConstraints failed,0),
-PKIX_ERRORENTRY(CERTDECODEPOLICYINFOFAILED,pkix_pl_Cert_DecodePolicyInfo failed,0),
-PKIX_ERRORENTRY(CERTDECODEPOLICYMAPPINGFAILED,pkix_pl_Cert_DecodePolicyMapping failed,0),
-PKIX_ERRORENTRY(CERTDECODEPOLICYMAPPINGSEXTENSIONFAILED,CERT_DecodePolicyMappingsExtension failed,0),
-PKIX_ERRORENTRY(CERTEQUALSFAILED,pkix_pl_Cert_Equals failed,0),
-PKIX_ERRORENTRY(CERTFAILEDNAMECONSTRAINTSCHECKING,Cert failed NameConstraints checking,SEC_ERROR_CERT_NOT_IN_NAME_SPACE),
-PKIX_ERRORENTRY(CERTGETALLSUBJECTNAMESFAILED,PKIX_PL_Cert_GetAllSubjectNames failed,0),
-PKIX_ERRORENTRY(CERTGETAUTHORITYINFOACCESSFAILED,PKIX_PL_Cert_GetAuthorityInfoAccess failed,0),
-PKIX_ERRORENTRY(CERTGETAUTHORITYKEYIDENTIFIERFAILED,PKIX_PL_Cert_GetAuthorityKeyIdentifier failed,0),
-PKIX_ERRORENTRY(CERTGETBASICCONSTRAINTFAILED,PKIX_PL_Cert_GetBasicConstraint failed,0),
-PKIX_ERRORENTRY(CERTGETBASICCONSTRAINTSFAILED,PKIX_PL_Cert_GetBasicConstraints failed,0),
-PKIX_ERRORENTRY(CERTGETCACHEFLAGFAILED,PKIX_Cert_GetCacheFlag failed,0),
-PKIX_ERRORENTRY(CERTGETCERTCERTIFICATEFAILED,PKIX_PL_Cert_GetCERTCertificate failed,0),
-PKIX_ERRORENTRY(CERTGETCRITICALEXTENSIONOIDSFAILED,PKIX_PL_Cert_GetCriticalExtensionOIDs failed,0),
-PKIX_ERRORENTRY(CERTGETCRLDPFAILED,Failed to get cert crldp extension, 0),
-PKIX_ERRORENTRY(CERTGETEXTENDEDKEYUSAGEFAILED,PKIX_PL_Cert_GetExtendedKeyUsage failed,0),
-PKIX_ERRORENTRY(CERTGETINHIBITANYPOLICYFAILED,PKIX_PL_Cert_GetInhibitAnyPolicy failed,0),
-PKIX_ERRORENTRY(CERTGETISSUERFAILED,PKIX_PL_Cert_GetIssuer failed,0),
-PKIX_ERRORENTRY(CERTGETNAMECONSTRAINTSFAILED,PKIX_PL_CertGetNameConstraints failed,0),
-PKIX_ERRORENTRY(CERTGETNSSSUBJECTALTNAMESFAILED,pkix_pl_Cert_GetNssSubjectAltNames failed,0),
-PKIX_ERRORENTRY(CERTGETPOLICYINFORMATIONFAILED,PKIX_PL_Cert_GetPolicyInformation failed,0),
-PKIX_ERRORENTRY(CERTGETPOLICYMAPPINGINHIBITEDFAILED,PKIX_PL_Cert_GetPolicyMappingInhibited failed,0),
-PKIX_ERRORENTRY(CERTGETPOLICYMAPPINGSFAILED,PKIX_PL_Cert_GetPolicyMappings failed,0),
-PKIX_ERRORENTRY(CERTGETREQUIREEXPLICITPOLICYFAILED,PKIX_PL_Cert_GetRequireExplicitPolicy failed,0),
-PKIX_ERRORENTRY(CERTGETSERIALNUMBERFAILED,PKIX_PL_Cert_GetSerialNumber failed,0),
-PKIX_ERRORENTRY(CERTGETSUBJALTNAMESFAILED,PKIX_PL_Cert_GetSubjAltNames failed,0),
-PKIX_ERRORENTRY(CERTGETSUBJECTALTNAMESFAILED,PKIX_PL_Cert_GetSubjectAltNames failed,0),
-PKIX_ERRORENTRY(CERTGETSUBJECTFAILED,PKIX_PL_Cert_GetSubject failed,0),
-PKIX_ERRORENTRY(CERTGETSUBJECTINFOACCESSFAILED,PKIX_PL_Cert_GetSubjectInfoAccess failed,0),
-PKIX_ERRORENTRY(CERTGETSUBJECTKEYIDENTIFIERFAILED,PKIX_PL_Cert_GetSubjectKeyIdentifier failed,0),
-PKIX_ERRORENTRY(CERTGETSUBJECTPUBLICKEYALGIDFAILED,PKIX_PL_Cert_GetSubjectPublicKeyAlgId failed,0),
-PKIX_ERRORENTRY(CERTGETSUBJECTPUBLICKEYFAILED,PKIX_PL_Cert_GetSubjectPublicKey failed,0),
-PKIX_ERRORENTRY(CERTGETVALIDITYNOTAFTERFAILED,PKIX_PL_Cert_GetValidityNotAfter failed,0),
-PKIX_ERRORENTRY(CERTGETVERSIONFAILED,PKIX_PL_Cert_GetVersion failed,0),
-PKIX_ERRORENTRY(CERTHASHCODEFAILED,PKIX_PL_Cert_Hashcode failed,0),
-PKIX_ERRORENTRY(CERTIFICATEDOESNTHAVEVALIDCRL,Certificate does not have a valid CRL,SEC_ERROR_CRL_NOT_FOUND),
-PKIX_ERRORENTRY(CERTIFICATEREVOKED,Certificate is revoked,SEC_ERROR_REVOKED_CERTIFICATE),
-PKIX_ERRORENTRY(CERTIMPORTCERTIFICATEFUNCTIONFAILED,CERTImportCertificate function failed,0),
-PKIX_ERRORENTRY(CERTISCERTTRUSTEDFAILED,PKIX_PL_Cert_IsCertTrusted failed,SEC_ERROR_UNTRUSTED_CERT),
-PKIX_ERRORENTRY(CERTISEXTENSIONCRITICALFAILED,pkix_pl_Cert_IsExtensionCritical failed,0),
-PKIX_ERRORENTRY(CERTMERGENAMECONSTRAINTSFAILED,PKIX_PL_Cert_MergeNameConstraints failed,0),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSCHECKNAMEINNAMESPACEFAILED,PKIX_PL_CertNameConstraints_CheckNameInNameSpace failed,SEC_ERROR_CERT_NOT_IN_NAME_SPACE),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSCHECKNAMESINNAMESPACEFAILED,PKIX_PL_CertNameConstraints_CheckNamesInNameSpace failed,SEC_ERROR_CERT_NOT_IN_NAME_SPACE),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSCHECKNAMESPACENSSNAMESFAILED,pkix_pl_CertNameConstraints_CheckNameSpaceNssNames failed,SEC_ERROR_CERT_NOT_IN_NAME_SPACE),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED,pkix_pl_CertNameConstraints_CopyNssNameConstraints failed,0),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSCREATEBYMERGEFAILED,pkix_pl_CertNameConstraints_CreateByMerge failed,0),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSCREATEFAILED,pkix_pl_CertNameConstraints_Create failed,0),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSCREATEHELPERFAILED,pkix_pl_CertNameConstraints_Create_Helper failed,0),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSGETEXCLUDEDFAILED,pkix_pl_CertNameConstraints_GetExcluded failed,0),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSGETPERMITTEDFAILED,pkix_pl_CertNameConstraints_GetPermitted failed,0),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSMERGEFAILED,pkix_pl_CertNameConstraints_Merge failed,0),
-PKIX_ERRORENTRY(CERTNAMECONSTRAINTSTOSTRINGHELPERFAILED,pkix_pl_CertNameConstraints_ToString_Helper failed,0),
-PKIX_ERRORENTRY(CERTNAMETOASCIIFAILED,CERT_NameToAscii failed,0),
-PKIX_ERRORENTRY(CERTNOTALLOWEDTOSIGNCERTIFICATES,Cert not allowed to sign certificates,SEC_ERROR_CA_CERT_INVALID),
-PKIX_ERRORENTRY(CERTPOLICYINFOCREATEFAILED,pkix_pl_CertPolicyInfo_Create failed,0),
-PKIX_ERRORENTRY(CERTPOLICYINFOGETPOLICYIDFAILED,PKIX_PL_CertPolicyInfo_GetPolicyId failed,0),
-PKIX_ERRORENTRY(CERTPOLICYINFOGETPOLQUALIFIERSFAILED,PKIX_PL_CertPolicyInfo_GetPolQualifiers failed,0),
-PKIX_ERRORENTRY(CERTPOLICYMAPCREATEFAILED,pkix_pl_CertPolicyMap_Create failed,0),
-PKIX_ERRORENTRY(CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED,PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy failed,0),
-PKIX_ERRORENTRY(CERTPOLICYMAPGETSUBJECTDOMAINPOLICYFAILED,PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy failed,0),
-PKIX_ERRORENTRY(CERTPOLICYQUALIFIERCREATEFAILED,pkix_pl_CertPolicyQualifier_Create failed,0),
-PKIX_ERRORENTRY(CERTREJECTEDBYREVOCATIONCHECKER,Cert rejected by revocation checker,0),
-PKIX_ERRORENTRY(CERTSELECTORCHECKFAILED,Validation failed: CertSelector check failed,0),
-PKIX_ERRORENTRY(CERTSELECTORCREATEFAILED,PKIX_CertSelector_Create failed,0),
-PKIX_ERRORENTRY(CERTSELECTORFAILED,certSelector failed,0),
-PKIX_ERRORENTRY(CERTSELECTORGETCOMCERTSELPARAMSFAILED,PKIX_CertSelector_GetComCertSelParams failed,0),
-PKIX_ERRORENTRY(CERTSELECTORGETCOMMONCERTSELECTORPARAMFAILED,PKIX_CertSelector_GetCommonCertSelectorParam failed,0),
-PKIX_ERRORENTRY(CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED,PKIX_CertSelector_GetCommonCertSelectorParams failed,0),
-PKIX_ERRORENTRY(CERTSELECTORGETMATCHCALLBACKFAILED,PKIX_CertSelector_GetMatchCallback failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHAUTHKEYIDFAILED,pkix_CertSelector_Match_AuthKeyId failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHBASICCONSTRAINTFAILED,pkix_CertSelector_Match_BasicConstraint failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHCALLBACKFAILED,PKIX_CertSelector_MatchCallback failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHCERTIFICATEVALIDFAILED,pkix_CertSelector_Match_CertificateValid failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHCERTISSUERFAILED,cert does not match issuer name,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHCERTOBJECTFAILED,cert does not match cert object,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHCERTSERIALNUMFAILED,cert does not match serial number,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHCERTSUBJECTFAILED,cert does not match subject name,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHCERTVERSIONFAILED,cert does not match cert version,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED,pkix_CertSelector_Match_ExtendedKeyUsage failed,SEC_ERROR_INADEQUATE_CERT_TYPE),
-PKIX_ERRORENTRY(CERTSELECTORMATCHFAILED,certSelectorMatch failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHKEYUSAGEFAILED,pkix_CertSelector_Match_KeyUsage failed,SEC_ERROR_INADEQUATE_KEY_USAGE),
-PKIX_ERRORENTRY(CERTSELECTORMATCHNAMECONSTRAINTSFAILED,pkix_CertSelector_Match_NameConstraints failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHPATHTONAMESFAILED,pkix_CertSelector_Match_PathToNames failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHPOLICIESFAILED,pkix_CertSelector_Match_Policies failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHSUBJALTNAMESFAILED,pkix_CertSelector_Match_SubjAltNames failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHSUBJKEYIDFAILED,pkix_CertSelector_Match_SubjKeyId failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHSUBJPKALGIDFAILED,pkix_CertSelector_Match_SubjPKAlgId failed,0),
-PKIX_ERRORENTRY(CERTSELECTORMATCHSUBJPUBKEYFAILED,pkix_CertSelector_Match_SubjPubKey failed,0),
-PKIX_ERRORENTRY(CERTSELECTORSELECTFAILED,pkix_CertSelector_Select failed,0),
-PKIX_ERRORENTRY(CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED,PKIX_CertSelector_SetCommonCertSelectorParams failed,0),
-PKIX_ERRORENTRY(CERTSETASTRUSTANCHORFAILED, PKIX_PL_Cert_SetAsTrustAnchor failed, 0),
-PKIX_ERRORENTRY(CERTSETCACHEFLAGFAILED,PKIX_PL_Cert_SetCacheFlag failed,0),
-PKIX_ERRORENTRY(CERTSETTRUSTCERTSTOREFAILED,PKIX_PL_Cert_SetTrustCertStore failed,0),
-PKIX_ERRORENTRY(CERTSTORECERTCONTINUEFAILED,PKIX_CertStore_CertContinue failed,0),
-PKIX_ERRORENTRY(CERTSTORECERTCONTINUEFUNCTIONFAILED,PKIX_CertStore_CertContinueFunction failed,0),
-PKIX_ERRORENTRY(CERTSTORECREATEFAILED,PKIX_CertStore_Create failed,0),
-PKIX_ERRORENTRY(CERTSTORECRLCONTINUEFAILED,PKIX_CertStore_CrlContinue failed,0),
-PKIX_ERRORENTRY(CERTSTOREEQUALSFAILED,pkix_CertStore_Equals failed,0),
-PKIX_ERRORENTRY(CERTSTORECRLCHECKFAILED,Fail to check cert crl revocation,0),
-PKIX_ERRORENTRY(CERTSTOREGETCHECKREVBYCRLFAILED,Can not get revocation check function,0),
-PKIX_ERRORENTRY(CERTSTOREFAILTOIMPORTCRLLIST,Fail to import crls,0),
-PKIX_ERRORENTRY(CERTSTOREGETCERTCALLBACKFAILED,PKIX_CertStore_GetCertCallback failed,0),
-PKIX_ERRORENTRY(CERTSTOREGETCERTSTORECACHEFLAGFAILED,PKIX_CertStore_GetCertStoreCacheFlag failed,0),
-PKIX_ERRORENTRY(CERTSTOREGETCERTSTORECONTEXTFAILED,PKIX_CertStore_GetCertStoreContext failed,0),
-PKIX_ERRORENTRY(CERTSTOREGETCRLCALLBACKFAILED,PKIX_CertStore_GetCRLCallback failed,0),
-PKIX_ERRORENTRY(CERTSTOREGETLOCALFLAGFAILED,PKIX_CertStore_GetLocalFlag failed,0),
-PKIX_ERRORENTRY(CERTSTOREGETTRUSTCALLBACKFAILED,PKIX_CertStore_GetTrustCallback failed,0),
-PKIX_ERRORENTRY(CERTSTOREHASHCODEFAILED,pkix_CertStore_Hashcode failed,0),
-PKIX_ERRORENTRY(CERTTOSTRINGFAILED,PKIX_PL_Cert_ToString failed,0),
-PKIX_ERRORENTRY(CERTTOSTRINGHELPERFAILED,pkix_pl_Cert_ToString_Helper failed,0),
-PKIX_ERRORENTRY(CERTVERIFYCERTTYPEFAILED,PKIX_PL_Cert_VerifyCertAndKeyType failed,0),
-PKIX_ERRORENTRY(CERTVERIFYKEYUSAGEFAILED,PKIX_PL_Cert_VerifyKeyUsage failed,0),
-PKIX_ERRORENTRY(CERTVERIFYSIGNATUREFAILED,PKIX_PL_Cert_VerifySignature failed,0),
-PKIX_ERRORENTRY(CHAINREJECTEDBYREVOCATIONCHECKER,Chain rejected by Revocation Checker,0),
-PKIX_ERRORENTRY(CHAINVERIFYCALLBACKFAILED,Chain rejected by Application Callback,SEC_ERROR_APPLICATION_CALLBACK_ERROR),
-PKIX_ERRORENTRY(CHECKCERTAGAINSTANCHORFAILED,pkix_CheckCertAgainstAnchor failed,0),
-PKIX_ERRORENTRY(CHECKCERTFAILED,pkix_CheckCert failed,0),
-PKIX_ERRORENTRY(CHECKCHAINFAILED,pkix_CheckChain failed,0),
-PKIX_ERRORENTRY(CHECKTRUSTCALLBACKFAILED,CheckTrustCallback failed,0),
-PKIX_ERRORENTRY(COLLECTIONCERTSTOREPOPULATECERTFAILED,pkix_pl_CollectionCertStoreContext_PopulateCert failed,0),
-PKIX_ERRORENTRY(COLLECTIONCERTSTOREPOPULATECRLFAILED,pkix_pl_CollectionCertStoreContext_PopulateCrl failed,0),
-PKIX_ERRORENTRY(COLLECTIONCERTSTORECONTEXTCREATECERTFAILED,pkix_pl_CollectionCertStoreContext_CreateCert failed,0),
-PKIX_ERRORENTRY(COLLECTIONCERTSTORECONTEXTCREATECRLFAILED,pkix_pl_CollectionCertStoreContext_CreateCRL failed,0),
-PKIX_ERRORENTRY(COLLECTIONCERTSTORECONTEXTGETSELECTCERTFAILED,pkix_pl_CollectionCertStoreContext_GetSelectCert failed,0),
-PKIX_ERRORENTRY(COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED,pkix_pl_CollectionCertStoreContext_GetSelectCRL failed,0),
-PKIX_ERRORENTRY(COLLECTIONCERTSTORECONTEXTPOPULATECERTFAILED,pkix_pl_CollectionCertStoreContext_PopulateCert failed,0),
-PKIX_ERRORENTRY(COLLECTIONCERTSTORECONTEXTPOPULATECRLFAILED,pkix_pl_CollectionCertStoreContext_PopulateCRL failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSCREATEFAILED,PKIX_ComCertSelParams_Create failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETAUTHORITYKEYIDENTIFIERFAILED,PKIX_ComCertSelParams_GetAuthorityKeyIdentifier failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED,PKIX_ComCertSelParams_GetBasicConstraints failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETCERTIFICATEFAILED,PKIX_ComCertSelParams_GetCertificate failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED,PKIX_ComCertSelParams_GetCertificateValid failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED,PKIX_ComCertSelParams_GetExtendedKeyUsage failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETISSUERFAILED,PKIX_ComCertSelParams_GetIssuer failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETKEYUSAGEFAILED,PKIX_ComCertSelParams_GetKeyUsage failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETLEAFCERTFLAGFAILED,PKIX_ComCertSelParams_GetLeafCertFlag failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETMATCHALLSUBJALTNAMESFAILED,PKIX_ComCertSelParams_GetMatchAllSubjAltNames failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETNAMECONSTRAINTSFAILED,PKIX_ComCertSelParams_GetNameConstraints failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETPATHTONAMESFAILED,PKIX_ComCertSelParams_GetPathToNames failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETPOLICYFAILED,PKIX_ComCertSelParams_GetPolicy failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETSERIALNUMBERFAILED,PKIX_ComCertSelParams_GetSerialNumber failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETSUBJALTNAMESFAILED,PKIX_ComCertSelParams_GetSubjAltNames failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETSUBJECTFAILED,PKIX_ComCertSelParams_GetSubject failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETSUBJKEYIDENTIFIERFAILED,PKIX_ComCertSelParams_GetSubjKeyIdentifier failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETSUBJPKALGIDFAILED,PKIX_ComCertSelParams_GetSubjPKAlgId failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETSUBJPUBKEYFAILED,PKIX_ComCertSelParams_GetSubjPubKey failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSGETVERSIONFAILED,PKIX_ComCertSelParams_GetVersion failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETBASICCONSTRAINTSFAILED,PKIX_ComCertSelParams_SetBasicConstraints failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETCERTIFICATEFAILED,PKIX_ComCertSelParams_SetCertificate failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETCERTIFICATEVALIDFAILED,PKIX_ComCertSelParams_SetCertificateValid failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETEXTKEYUSAGEFAILED,PKIX_ComCertSelParams_SetExtendedKeyUsage failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETKEYUSAGEFAILED,PKIX_ComCertSelParams_SetKeyUsage failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETLEAFCERTFLAGFAILED,PKIX_ComCertSelParams_SetLeafCertFlag failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETNISTPOLICYENABLEDFAILED,PKIX_ComCertSelParams_SetNISTPolicyEnabled failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETPATHTONAMESFAILED,PKIX_ComCertSelParams_SetPathToNames failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETSUBJECTFAILED,PKIX_ComCertSelParams_SetSubject failed,0),
-PKIX_ERRORENTRY(COMCERTSELPARAMSSETSUBJKEYIDENTIFIERFAILED,PKIX_ComCertSelParams_SetSubjKeyIdentifier failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSADDISSUERNAMEFAILED,PKIX_ComCRLSelParams_AddIssuerName failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSCREATEFAILED,PKIX_ComCRLSelParams_Create failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSEQUALSFAILED,pkix_ComCRLSelParams_Equals failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSGETDATEANDTIMEFAILED,PKIX_ComCRLSelParams_GetDateAndTime failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSGETISSUERNAMESFAILED,PKIX_ComCRLSelParams_GetIssuerNames failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSGETMAXCRLNUMBERFAILED,PKIX_ComCRLSelParams_GetMaxCRLNumber failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSGETMINCRLNUMBERFAILED,PKIX_ComCRLSelParams_GetMinCRLNumber failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSGETNISTPOLICYENABLEDFAILED,PKIX_ComCRLSelParams_GetNISTPolicyEnabled failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSSETCERTFAILED,PKIX_ComCRLSelParams_SetCertificateChecking failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSSETDATEANDTIMEFAILED,PKIX_ComCRLSelParams_SetDateAndTime failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSTOSTRINGFAILED,pkix_ComCRLSelParams_ToString failed,0),
-PKIX_ERRORENTRY(COMCRLSELPARAMSTOSTRINGHELPERFAILED,pkix_ComCRLSelParams_ToString_Helper failed,0),
-PKIX_ERRORENTRY(COMPARATORCALLBACKFAILED,comparator callback failed,0),
-PKIX_ERRORENTRY(CONTENTTYPENOTPKCS7MIME,Content type is not application/pkcs7-mime,0),
-PKIX_ERRORENTRY(CONTENTTYPENOTPKIXCRL,Content type is not application/pkix-crl,SEC_ERROR_BAD_HTTP_RESPONSE),
-PKIX_ERRORENTRY(COULDNOTALLOCATEMEMORY,Could not allocate memory,0),
-PKIX_ERRORENTRY(COULDNOTALLOCATENEWSTRINGOBJECT,Could not allocate new string object,0),
-PKIX_ERRORENTRY(COULDNOTAPPENDCHILDTOPARENTSPOLICYNODELIST,Could not append child to parent PolicyNode list,0),
-PKIX_ERRORENTRY(COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST,Could not append child to parent VerifyNode list,0),
-PKIX_ERRORENTRY(COULDNOTCREATEAIAMGROBJECT,Could not create AiaMgr object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEBASICCONSTRAINTSSTATEOBJECT,Could not create basic constraints state object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEBUILDPARAMSOBJECT,Could not create build params object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEBUILDRESULTOBJECT,Could not create build result object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECERTBASICCONSTRAINTSOBJECT,Could not create a CertBasicConstraints object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECERTCHAINCHECKEROBJECT,Could not create cert chain checker object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECERTNAMECONSTRAINTSOBJECT,Could not create CertNameConstraints object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECERTPOLICYINFOOBJECT,Could not create a CertPolicyInfo object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECERTPOLICYMAPOBJECT,Could not create a CertPolicyMap object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECERTPOLICYQUALIFIEROBJECT,Could not create a CertPolicyQualifier object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECERTSELECTOROBJECT,Could not create cert selector object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECERTSTOREOBJECT,Could not create CertStore object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECOLLECTIONCERTSTORECONTEXTOBJECT,Could not create CollectionCertStoreContext object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECOMMONCERTSELPARAMSOBJECT,Could not create common certsel params object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECOMMONCRLSELECTORPARAMSOBJECT,Could not create common crl selector params object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECRLENTRYOBJECT,Could not create CRLENTRY object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECRLOBJECT,Could not create CRL object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECRLSELECTOROBJECT,Could not create CRLSelector object,0),
-PKIX_ERRORENTRY(COULDNOTCREATECRLCHECKEROBJECT,Could not create CRLChecker object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEOCSPCHECKEROBJECT,Could not create OcspChecker object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEREVOCATIONMETHODOBJECT,Could not create RevocationMethod object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEDEFAULTREVOCATIONCHECKEROBJECT,Could not create DefaultRevocationChecker object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEEKUCHECKERSTATEOBJECT,Could not create EkuCheckerState object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEFORWARDBUILDERSTATEOBJECT,Could not create forwardBuilder state object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEHASHTABLEOBJECT,Could not create HashTable object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEHTTPDEFAULTCLIENTOBJECT,Could not create HttpDefaultClient object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEINFOACCESSOBJECT,Could not create InfoAccess object,0),
-PKIX_ERRORENTRY(COULDNOTCREATELDAPDEFAULTCLIENTOBJECT,Could not create LdapDefaultClient object,0),
-PKIX_ERRORENTRY(COULDNOTCREATELOCKOBJECT,Could not create lock object,0),
-PKIX_ERRORENTRY(COULDNOTCREATELOGGEROBJECT,Could not create Logger object,0),
-PKIX_ERRORENTRY(COULDNOTCREATENAMECONSTRAINTSCHECKERSTATEOBJECT,Could not create NameConstraintsCheckerState object,0),
-PKIX_ERRORENTRY(COULDNOTCREATENSSDN,Could not create NSS DN,0),
-PKIX_ERRORENTRY(COULDNOTCREATEOBJECT,Could not create object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEOBJECTSTORAGE,Could not create object storage,0),
-PKIX_ERRORENTRY(COULDNOTCREATEPOLICYCHECKERSTATEOBJECT,Could not create policyChecker state object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEPOLICYNODEOBJECT,Could not create a PolicyNode object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEPROCESSINGPARAMSOBJECT,Could not create processing params object,0),
-PKIX_ERRORENTRY(COULDNOTCREATERESOURCELIMITOBJECT,Could not create ResourceLimit object,0),
-PKIX_ERRORENTRY(COULDNOTCREATESIGNATURECHECKERSTATEOBJECT,Could not create SignatureCheckerState object,0),
-PKIX_ERRORENTRY(COULDNOTCREATESOCKETOBJECT,Could not create Socket object,0),
-PKIX_ERRORENTRY(COULDNOTCREATESTRING,Could not create string,0),
-PKIX_ERRORENTRY(COULDNOTCREATETARGETCERTCHECKERSTATEOBJECT,Could not create target cert checker state object,0),
-PKIX_ERRORENTRY(COULDNOTCREATETRUSTANCHOROBJECT,Could not create trust anchor object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEVALIDATEPARAMSOBJECT,Could not create validate params object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEVALIDATERESULTOBJECT,Could not create validate result object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEVERIFYNODEOBJECT,Could not create a VerifyNode object,0),
-PKIX_ERRORENTRY(COULDNOTCREATEX500NAMEOBJECT,Could not create X500Name object,0),
-PKIX_ERRORENTRY(COULDNOTGETFIRSTOBJECTTYPE,Could not get first object type,0),
-PKIX_ERRORENTRY(COULDNOTGETSECONDOBJECTTYPE,Could not get second object type,0),
-PKIX_ERRORENTRY(COULDNOTGETTYPEOFSECONDARGUMENT,Could not get type of second argument,0),
-PKIX_ERRORENTRY(COULDNOTLOOKUPINHASHTABLE,Could not lookup in hashtable,0),
-PKIX_ERRORENTRY(COULDNOTMALLOCNEWKEY,Could not malloc new key,0),
-PKIX_ERRORENTRY(COULDNOTTESTWHETHERKEYSEQUAL,Could not test whether keys are equal,0),
-PKIX_ERRORENTRY(CREATECERTFAILED,CreateCert failed,0),
-PKIX_ERRORENTRY(CREATECRLSELECTORDUPLICATEOBJECTFAILED,Create CRLSelector Duplicate Object failed,0),
-PKIX_ERRORENTRY(CREATEPROCESSINGPARAMSFAILED,Failed to create processing parameters,0),
-PKIX_ERRORENTRY(CRLCHECKERCREATEFAILED,pkix_CRLChecker_Create failed,0),
-PKIX_ERRORENTRY(CRLCHECKERINITIALIZEFAILED,pkix_CRLChecker_Initialize failed,0),
-PKIX_ERRORENTRY(CRLCHECKERNOLOCALCERTSTOREFOUND,No local cert store found, 0),
-PKIX_ERRORENTRY(CRLCHECKERSETSELECTORFAILED,pkix_CRLChecker_SetSelector failed,0),
-PKIX_ERRORENTRY(CRLCREATEFAILED,PKIX_PL_CRL_Create failed,0),
-PKIX_ERRORENTRY(CRLCREATETOLISTFAILED,pkix_pl_CRL_CreateToList failed,0),
-PKIX_ERRORENTRY(CRLCREATEWITHSIGNEDCRLFAILED,pkix_pl_CRL_CreateWithSignedCRL failed,0),
-PKIX_ERRORENTRY(CRLCRITICALEXTENSIONOIDSNOTPROCESSED,CRL Critical Extension OIDs not processed,0),
-PKIX_ERRORENTRY(CRLDPCREATEFAILED, Failed to create CRL DP,0),
-PKIX_ERRORENTRY(CRLENTRYCREATEFAILED,pkix_pl_CRLEntry_Create failed,0),
-PKIX_ERRORENTRY(CRLENTRYCRITICALEXTENSIONWASNOTPROCESSED,CRLEntry Critical Extension was not processed,0),
-PKIX_ERRORENTRY(CRLENTRYEXTENSIONSEQUALSFAILED,PKIX_PL_CRLEntry_Extensions_Equals failed,0),
-PKIX_ERRORENTRY(CRLENTRYEXTENSIONSHASHCODEFAILED,pkix_pl_CRLEntry_Extensions_Hashcode failed,0),
-PKIX_ERRORENTRY(CRLENTRYGETCRITICALEXTENSIONOIDSFAILED,PKIX_PL_CRLEntry_GetCriticalExtensionOIDs failed,0),
-PKIX_ERRORENTRY(CRLENTRYGETCRLENTRYREASONCODEFAILED,PKIX_PL_CRLEntry_GetCRLEntryReasonCode failed,0),
-PKIX_ERRORENTRY(CRLENTRYTOSTRINGHELPERFAILED,pkix_pl_CRLEntry_ToString_Helper failed,0),
-PKIX_ERRORENTRY(CRLGETCRITICALEXTENSIONOIDSFAILED,PKIX_PL_CRL_GetCriticalExtensionOIDs failed,0),
-PKIX_ERRORENTRY(CRLGETCRLENTRIESFAILED,pkix_pl_CRL_GetCRLEntries failed,0),
-PKIX_ERRORENTRY(CRLGETCRLENTRYFORSERIALNUMBERFAILED,PKIX_PL_CRL_GetCRLEntryForSerialNumber failed,0),
-PKIX_ERRORENTRY(CRLGETCRLNUMBERFAILED,PKIX_PL_CRL_GetCRLNumber failed,0),
-PKIX_ERRORENTRY(CRLGETISSUERFAILED,PKIX_PL_CRL_GetIssuer failed,0),
-PKIX_ERRORENTRY(CRLGETPARTITIONEDFLAGFAILED,PKIX_PL_CRL_IsPartitioned failed,0),
-PKIX_ERRORENTRY(CRLGETSIGNATUREALGIDFAILED,pkix_pl_CRL_GetSignatureAlgId failed,0),
-PKIX_ERRORENTRY(CRLGETVERSIONFAILED,pkix_pl_CRL_GetVersion failed,0),
-PKIX_ERRORENTRY(CRLISSUECERTEXPIRED,CRL issue cert has expired,0),
-PKIX_ERRORENTRY(CRLMAXNUMBERRANGEMATCHFAILED,CRL MaxNumber Range Match Failed,0),
-PKIX_ERRORENTRY(CRLSELECTORCREATEFAILED,PKIX_CRLSelector_Create failed,0),
-PKIX_ERRORENTRY(CRLSELECTORFAILED,crlSelector failed,0),
-PKIX_ERRORENTRY(CRLSELECTORGETCOMCERTSELPARAMSFAILED,PKIX_CRLSelector_GetComCertSelParams failed,0),
-PKIX_ERRORENTRY(CRLSELECTORGETMATCHCALLBACKFAILED,PKIX_CRLSelector_GetMatchCallback failed,0),
-PKIX_ERRORENTRY(CRLSELECTORMATCHCALLBACKFAILED,PKIX_CRLSelector_MatchCallback failed,0),
-PKIX_ERRORENTRY(CRLSELECTORMATCHFAILED,crlSelectorMatch failed,0),
-PKIX_ERRORENTRY(CRLSELECTORSELECTFAILED,pkix_CRLSelector_Select failed,0),
-PKIX_ERRORENTRY(CRLSELECTORSETCOMMONCRLSELECTORPARAMSFAILED,PKIX_CRLSelector_SetCommonCRLSelectorParams failed,0),
-PKIX_ERRORENTRY(CRLSELECTORTOSTRINGHELPERFAILED,pkix_CRLSelector_ToString_Helper failed,0),
-PKIX_ERRORENTRY(CRLTOSTRINGHELPERFAILED,pkix_pl_CRL_ToString_Helper failed,0),
-PKIX_ERRORENTRY(CRLVERIFYUPDATETIMEFAILED,pkix_pl_CRL_VerifyUpdateTime failed,0),
-PKIX_ERRORENTRY(DATECREATECURRENTOFFBYSECONDSFAILED,PKIX_PL_Date_Create_CurrentOffBySeconds failed,0),
-PKIX_ERRORENTRY(DATECREATEFROMPRTIMEFAILED,pkix_pl_Date_CreateFromPRTime failed,0),
-PKIX_ERRORENTRY(DATECREATEUTCTIMEFAILED,PKIX_PL_Date_Create_UTCTime failed,0),
-PKIX_ERRORENTRY(DATEDERTIMETOPRTIMEFAILED,Fail to convert encoded time to PRTime,0),
-PKIX_ERRORENTRY(DATEEQUALSFAILED,PKIX_PL_Date_Equals failed,0),
-PKIX_ERRORENTRY(DATEGETPRTIMEFAILED,pkix_pl_Date_GetPRTime failed,0),
-PKIX_ERRORENTRY(DATEHASHCODEFAILED,PKIX_PL_Date_Hashcode failed,0),
-PKIX_ERRORENTRY(DATETOSTRINGFAILED,PKIX_Date_ToString failed,0),
-PKIX_ERRORENTRY(DATETOSTRINGHELPERFAILED,pkix_pl_Date_ToString_Helper failed,0),
-PKIX_ERRORENTRY(DECIPHERONLYKEYUSAGENOTSUPPORTED,decipherOnly key usage not supported,0),
-PKIX_ERRORENTRY(DECODINGCERTNAMECONSTRAINTSFAILED,Decoding Cert NameConstraints failed,0),
-PKIX_ERRORENTRY(DEFAULTREVCHECKERCREATEFAILED,pkix_DefaultRevChecker_Create failed,0),
-PKIX_ERRORENTRY(DEFAULTREVCHECKERINITIALIZEFAILED,pkix_DefaultRevChecker_Initialize failed,0),
-PKIX_ERRORENTRY(DEPTHWOULDEXCEEDRESOURCELIMITS,Depth would exceed Resource Limits,SEC_ERROR_OUT_OF_SEARCH_LIMITS),
-PKIX_ERRORENTRY(DERASCIITOTIMEFAILED,DER_AsciiToTime failed,0),
-PKIX_ERRORENTRY(DERDECODETIMECHOICEFAILED,DER_DecodeTimeChoice failed,0),
-PKIX_ERRORENTRY(DERDECODETIMECHOICEFORLASTUPDATEFAILED,DER_DecodeTimeChoice for lastUpdate failed,0),
-PKIX_ERRORENTRY(DERDECODETIMECHOICEFORNEXTUPDATEFAILED,DER_DecodeTimeChoice for nextUpdate failed,0),
-PKIX_ERRORENTRY(DERENCODETIMECHOICEFAILED,DER_EncodeTimeChoice failed,0),
-PKIX_ERRORENTRY(DERGENERALIZEDDAYTOASCIIFAILED,DER_GeneralizedDayToAscii failed,0),
-PKIX_ERRORENTRY(DERTIMETOUTCTIMEFAILED,DER_TimeToUTCTime failed,0),
-PKIX_ERRORENTRY(DERUTCTIMETOASCIIFAILED,DER_UTCTimeToAscii failed,0),
-PKIX_ERRORENTRY(DESTROYSPKIFAILED,pkix_pl_DestroySPKI failed,0),
-PKIX_ERRORENTRY(DIRECTORYNAMECREATEFAILED,pkix_pl_DirectoryName_Create failed,0),
-PKIX_ERRORENTRY(DUPLICATEIMMUTABLEFAILED,pkix_duplicateImmutable failed,0),
-PKIX_ERRORENTRY(CANNOTSORTIMMUTABLELIST,pkix_List_BubbleSort can not sort immutable list,0),
-PKIX_ERRORENTRY(EKUCHECKERGETREQUIREDEKUFAILED,pkix_pl_EkuChecker_GetRequiredEku failed,0),
-PKIX_ERRORENTRY(EKUCHECKERINITIALIZEFAILED,PKIX_PL_EkuChecker_Initialize failed,0),
-PKIX_ERRORENTRY(EKUCHECKERSTATECREATEFAILED,pkix_pl_EkuCheckerState_Create failed,0),
-PKIX_ERRORENTRY(ENABLEREVOCATIONWITHOUTCERTSTORE,Enable Revocation without CertStore,0),
-PKIX_ERRORENTRY(ERRORALLOCATINGMONITORLOCK,Error Allocating MonitorLock,0),
-PKIX_ERRORENTRY(ERRORALLOCATINGRWLOCK,Error Allocating RWLock,0),
-PKIX_ERRORENTRY(ERRORCREATINGCHILDSTRING,Error creating child string,0),
-PKIX_ERRORENTRY(ERRORCREATINGFORMATSTRING,Error creating format string,0),
-PKIX_ERRORENTRY(ERRORCREATINGINDENTSTRING,Error creating indent string,0),
-PKIX_ERRORENTRY(ERRORCREATINGITEMSTRING,Error creating item string,0),
-PKIX_ERRORENTRY(ERRORCREATINGLISTITEM,Error Creating List Item,0),
-PKIX_ERRORENTRY(ERRORCREATINGSUBTREESTRING,Error creating subtree string,0),
-PKIX_ERRORENTRY(ERRORCREATINGTABLELOCK,Error creating table lock,0),
-PKIX_ERRORENTRY(ERRORFINDINGORPROCESSINGURI,Error finding or processing URI,0),
-PKIX_ERRORENTRY(ERRORGETTINGCAUSESTRING,Error getting cause string,0),
-PKIX_ERRORENTRY(ERRORGETTINGCLASSTABLEENTRY,Error getting class table entry,0),
-PKIX_ERRORENTRY(ERRORGETTINGHASHCODE,Error getting hashcode,0),
-PKIX_ERRORENTRY(ERRORGETTINGSECONDOBJECTTYPE,Error getting second object type,0),
-PKIX_ERRORENTRY(ERRORINBYTEARRAYHASHCODE,Error in PKIX_PL_ByteArray_Hashcode,0),
-PKIX_ERRORENTRY(ERRORINGETTINGDESTRUCTOR,Error in getting destructor,0),
-PKIX_ERRORENTRY(ERRORINHASH,Error in pkix_hash,0),
-PKIX_ERRORENTRY(ERRORINLISTHASHCODE,Error in PKIX_List_Hashcode,0),
-PKIX_ERRORENTRY(ERRORINOBJECTDEFINEDESTROY,Error in object-defined destroy callback,0),
-PKIX_ERRORENTRY(ERRORINOIDHASHCODE,Error in PKIX_PL_OID_Hashcode,0),
-PKIX_ERRORENTRY(ERRORINRECURSIVEEQUALSCALL,Error in recursive equals call,0),
-PKIX_ERRORENTRY(ERRORINSINGLEPOLICYNODETOSTRING,Error in pkix_SinglePolicyNode_ToString,0),
-PKIX_ERRORENTRY(ERRORINSINGLEVERIFYNODETOSTRING,Error in pkix_SingleVerifyNode_ToString,0),
-PKIX_ERRORENTRY(ERRORINSPRINTF,Error in PKIX_PL_Sprintf,0),
-PKIX_ERRORENTRY(ERRORINSTRINGCREATE,Error in PKIX_PL_String_Create,0),
-PKIX_ERRORENTRY(ERRORLOCKINGOBJECT,Error locking object,0),
-PKIX_ERRORENTRY(ERRORTOSTRINGFAILED,PKIX_Error_ToString failed,0),
-PKIX_ERRORENTRY(ERRORTRAVERSINGBUCKET,Error traversing bucket,0),
-PKIX_ERRORENTRY(ERRORUNLOCKINGMUTEX,Error unlocking mutex,0),
-PKIX_ERRORENTRY(ERRORUNLOCKINGOBJECT,Error unlocking object,0),
-PKIX_ERRORENTRY(ESCASCIITOUTF16FAILED,pkix_EscASCII_to_UTF16 failed,0),
-PKIX_ERRORENTRY(EXPIRATIONCHECKERINITIALIZEFAILED,pkix_ExpirationChecker_Initialize failed,0),
-PKIX_ERRORENTRY(EXTENDEDKEYUSAGECHECKINGFAILED,Extended Key Usage Checking failed,SEC_ERROR_INADEQUATE_CERT_TYPE),
-PKIX_ERRORENTRY(EXTENDEDKEYUSAGEUSEROBJECT,Extended Key Usage User Object,0),
-PKIX_ERRORENTRY(EXTRACTPARAMETERSFAILED,pkix_ExtractParameters failed,0),
-PKIX_ERRORENTRY(FAILEDINENCODINGSEARCHREQUEST,failed in encoding searchRequest,SEC_ERROR_FAILED_TO_ENCODE_DATA),
-PKIX_ERRORENTRY(FAILEDTODECODECRL, failed to decode CRL,SEC_ERROR_BAD_DER),
-PKIX_ERRORENTRY(FAILEDTOGETNSSTRUSTANCHORS,Failed to get nss trusted roots,0),
-PKIX_ERRORENTRY(FAILEDTOGETTRUST, failed to get trust from the cert,0),
-PKIX_ERRORENTRY(FAILTOREMOVEDPFROMLIST, failed to remove dp from the list,0),
-PKIX_ERRORENTRY(FAILTOSELECTCERTSFROMANCHORS,failed to select certs from anchors,0),
-PKIX_ERRORENTRY(FAILUREHASHINGCERT,Failure hashing Cert,0),
-PKIX_ERRORENTRY(FAILUREHASHINGERROR,Failure hashing Error,0),
-PKIX_ERRORENTRY(FAILUREHASHINGLISTEXPECTEDPOLICYSET,Failure hashing PKIX_List expectedPolicySet,0),
-PKIX_ERRORENTRY(FAILUREHASHINGLISTQUALIFIERSET,Failure hashing PKIX_List qualifierSet,0),
-PKIX_ERRORENTRY(FAILUREHASHINGOIDVALIDPOLICY,Failure hashing PKIX_PL_OID validPolicy,0),
-PKIX_ERRORENTRY(FANOUTEXCEEDSRESOURCELIMITS,Fanout exceeds Resource Limits,0),
-PKIX_ERRORENTRY(FETCHINGCACHEDCRLFAILED,Fetching Cached CRLfailed,0),
-PKIX_ERRORENTRY(FILLINPROCESSINGPARAMSFAILED,Fail to fill in parameters,0),
-PKIX_ERRORENTRY(FILLINRETURNRESULTSFAILED,Fail to fill in return results,0),
-PKIX_ERRORENTRY(FIRSTARGUMENTNOTANOID,FirstObject is not an OID,0),
-PKIX_ERRORENTRY(FIRSTARGUMENTNOTBYTEARRAY,FirstObject is not a ByteArray,0),
-PKIX_ERRORENTRY(FIRSTARGUMENTNOTCERTBASICCONSTRAINTSOBJECT,First argument is not a CertBasicConstraints Object,0),
-PKIX_ERRORENTRY(FIRSTDOUBLEHEXMUSTNOTBE00,First DoubleHex MUST NOT be 00,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(FIRSTFIELDMUSTBEBETWEEN02,First field must be between 0-2,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(FIRSTOBJARGUMENTNOTANOCSPRESPONSE,FirstObject is not an OcspResponse,0),
-PKIX_ERRORENTRY(FIRSTOBJARGUMENTNOTLDAPREQUEST,FirstObject is not a LdapRequest,0),
-PKIX_ERRORENTRY(FIRSTOBJARGUMENTNOTLDAPRESPONSE,FirstObject is not a LdapResponse,0),
-PKIX_ERRORENTRY(FIRSTOBJARGUMENTNOTOCSPREQUEST,FirstObject is not a OcspRequest,0),
-PKIX_ERRORENTRY(FIRSTOBJECTARGUMENTNOTANX500NAME,FirstObject is not an X500Name,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTANERROROBJECT,FirstObject is not an Error object,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTBIGINT,FirstObject not a BigInt,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTBUILDPARAMS,FirstObject is not a BuildParams,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTBUILDRESULT,FirstObject is not a BuildResult,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCERT,FirstObject is not a Cert,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCERTBASICCONSTRAINTS,FirstObject is not a CertBasicConstraints,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCERTNAMECONSTRAINTS,FirstObject is not a CertNameConstraints,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCERTPOLICYINFO,FirstObject is not a CertPolicyInfo,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCERTPOLICYMAP,FirstObject is not a CertPolicyMap,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCERTPOLICYQUALIFIER,FirstObject is not a CertPolicyQualifier,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCOMCRLSELPARAMS,FirstObject is not a ComCRLSelParams,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCRL,FirstObject is not a CRL,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCRLENTRY,FirstObject is not a CRLEntry,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTCRLSELECTOR,FirstObject is not a CRLSelector,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTDATE,FirstObject is not a Date,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTERROR,FirstObject is not an Error,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTGENERALNAME,FirstObject is not a GeneralName,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTINFOACCESS,FirstObject is not a InfoAccess,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTLIST,FirstObject is not a List,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTLOGGER,FirstObject is not a Logger,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTPOLICYNODE,FirstObject is not a PolicyNode,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTPROCESSINGPARAMS,FirstObject is not a ProcessingParams,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTPUBLICKEY,FirstObject is not a PublicKey,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTRESOURCELIMITS,FirstObject is not a ResourceLimits,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTSTRING,FirstObject is not a String,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTTRUSTANCHOR,FirstObject is not a TrustAnchor,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTVALIDATEPARAMS,FirstObject is not a ValidateParams,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTVALIDATERESULT,FirstObject is not a ValidateResult,0),
-PKIX_ERRORENTRY(FIRSTOBJECTNOTVERIFYNODE,FirstObject is not a VerifyNode,0),
-PKIX_ERRORENTRY(FIRSTPUBKEYTYPENULLKEY,firstPubKeyType is nullKey,0),
-PKIX_ERRORENTRY(FUNCTIONMUSTNOTBEUSED,Function MUST not be used,SEC_ERROR_LIBPKIX_INTERNAL),
-PKIX_ERRORENTRY(FORWARDBUILDERSTATEDUMPSTATEFAILED,pkix_ForwardBuilderState_DumpState failed,0),
-PKIX_ERRORENTRY(FORWARDBUILDERSTATEISIOPENDINGFAILED,pkix_ForwardBuilderState_IsIOPending failed,0),
-PKIX_ERRORENTRY(FORWARDBUILDSTATECREATEFAILED,pkix_ForwardBuildState_Create failed,0),
-PKIX_ERRORENTRY(FREEFAILED,PKIX_PL_Free failed,0),
-PKIX_ERRORENTRY(GENERALNAMECREATEFAILED,pkix_pl_GeneralName_Create failed,0),
-PKIX_ERRORENTRY(GENERALNAMEGETNSSGENERALNAMEFAILED,pkix_pl_GeneralName_GetNssGeneralName failed,0),
-PKIX_ERRORENTRY(GENERALNAMESTRINGMISSINGDOUBLESLASH,GeneralName string missing double slash,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
-PKIX_ERRORENTRY(GENERALNAMESTRINGMISSINGLOCATIONTYPE,GeneralName string missing location type,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
-PKIX_ERRORENTRY(GENERALNAMESTRINGMISSINGSERVERSITE,GeneralName string missing server-site,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
-PKIX_ERRORENTRY(GENERALNAMETOSTRINGFAILED,pkix_pl_GeneralName_ToString failed,0),
-PKIX_ERRORENTRY(GENERALNAMETOSTRINGHELPERFAILED,pkix_pl_GeneralName_ToString_Helper failed,0),
-PKIX_ERRORENTRY(GENERICCLIENTNOTANLDAPDEFAULTCLIENT,genericClient is not an LdapDefaultClient,0),
-PKIX_ERRORENTRY(GETATTRIBUTESCALLEDFORNONENTRYMESSAGE,GetAttributes called for non-Entry message,SEC_ERROR_BAD_LDAP_RESPONSE),
-PKIX_ERRORENTRY(GETCERTSFAILED,getCerts failed,0),
-PKIX_ERRORENTRY(GETCRITICALEXTENSIONOIDSFAILED,pkix_GetCriticalExtensionOIDs failed,0),
-PKIX_ERRORENTRY(GETCRLSFAILED,getCrls failed,0),
-PKIX_ERRORENTRY(GETOIDTOKENFAILED,pkix_pl_getOIDToken failed,0),
-PKIX_ERRORENTRY(GETPKIXERRORCODEFAILED,Get PKIX error code failed,0),
-PKIX_ERRORENTRY(GETREQCERTIFICATEUSAGESFAILED,Fail to get required certificate usages,0),
-PKIX_ERRORENTRY(GETRESULTCODECALLEDFORNONRESULTMESSAGE,GetResultCode called for non-Result message,SEC_ERROR_BAD_LDAP_RESPONSE),
-PKIX_ERRORENTRY(GETRETCERTIFICATEUSAGESFAILED,Fail to get returned certificate usages,0),
-PKIX_ERRORENTRY(GETTRUSTEDCERTLISTFAILED,Fail to get trusted cert list,0),
-PKIX_ERRORENTRY(HASHFAILED,pkix_hash failed,0),
-PKIX_ERRORENTRY(HASHTABLEADDFAILED,PKIX_PL_HashTable_Add failed,0),
-PKIX_ERRORENTRY(HASHTABLECREATEFAILED,PKIX_PL_HashTable_Create failed,0),
-PKIX_ERRORENTRY(HASHTABLELOOKUPFAILED,PKIX_PL_HashTable_Lookup failed,0),
-PKIX_ERRORENTRY(HASHTABLEREMOVEFAILED,PKIX_PL_HashTable_Remove failed,0),
-PKIX_ERRORENTRY(HELPERBYTES2ASCIIFAILED,pkix_pl_helperBytes2Ascii failed,0),
-PKIX_ERRORENTRY(HELPERBYTES2ASCIINUMTOKENSZERO,pkix_pl_helperBytes2Ascii: numTokens is zero,0),
-PKIX_ERRORENTRY(HTTPCERTSTORECREATEREQUESTSESSIONFAILED,pkix_pl_HttpCertStore_CreateRequestSession failed,0),
-PKIX_ERRORENTRY(HTTPCERTSTORECREATEWITHASCIINAMEFAILED,PKIX_PL_HttpCertStore_CreateWithAsciiName failed,0),
-PKIX_ERRORENTRY(HTTPCERTSTOREDECODECERTPACKAGEFAILED,pkix_pl_HttpCertStore_DecodeCertPackage failed,0),
-PKIX_ERRORENTRY(HTTPCERTSTOREFINDSOCKETCONNECTIONFAILED,pkix_HttpCertStore_FindSocketConnection failed,0),
-PKIX_ERRORENTRY(HTTPCERTSTOREPROCESSCERTRESPONSEFAILED,pkix_pl_HttpCertStore_ProcessCertResponse failed,0),
-PKIX_ERRORENTRY(HTTPCERTSTOREPROCESSCRLRESPONSEFAILED,pkix_pl_HttpCertStore_ProcessCrlResponse failed,0),
-PKIX_ERRORENTRY(HTTPCLIENTCREATESESSIONFAILED,HttpClient->CreateSession failed,0),
-PKIX_ERRORENTRY(HTTPCLIENTININVALIDSTATE,HttpClient in invalid state,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTCONNECTCONTINUEFAILED,pkix_pl_HttpDefaultClient_ConnectContinue failed,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTCREATEFAILED,pkix_pl_HttpDefaultClient_Create failed,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTDISPATCHFAILED,pkix_pl_HttpDefaultClient_Dispatch failed,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTHDRCHECKCOMPLETEFAILED,pkix_pl_HttpDefaultClient_HdrCheckComplete failed,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTINILLEGALSTATE,HttpDefaultClient in illegal state,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTRECVBODYCONTINUEFAILED,pkix_pl_HttpDefaultClient_RecvBodyContinue failed,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTRECVBODYFAILED,pkix_pl_HttpDefaultClient_RecvBody failed,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTRECVHDRCONTINUEFAILED,pkix_pl_HttpDefaultClient_RecvHdrContinue failed,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTRECVHDRFAILED,pkix_pl_HttpDefaultClient_RecvHdr failed,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTSENDCONTINUEFAILED,pkix_pl_HttpDefaultClient_SendContinue failed,0),
-PKIX_ERRORENTRY(HTTPDEFAULTCLIENTSENDFAILED,pkix_pl_HttpDefaultClient_Send failed,0),
-PKIX_ERRORENTRY(HTTPSERVERERROR,HTTP Server Error,0),
-PKIX_ERRORENTRY(ILLEGALCHARACTERINESCAPEDASCII,Illegal character in Escaped ASCII String,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(ILLEGALCHARACTERINOID,Illegal character in OID,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(ILLEGALDOTINOID,Illegal period in OID,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(ILLEGALSURROGATEPAIR,Illegal surrogate pair in EscapedASCII,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(ILLEGALUNICODECHARACTER,Illegal Unicode character in EscapedASCII,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(ILLEGALUSEOFAMP,Illegal use of ampersand character,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(IMPOSSIBLECRITERIONFORCRLQUERY,Impossible criterion for Crl Query,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(INDEXOUTOFBOUNDS,Index out of bounds,SEC_ERROR_LIBPKIX_INTERNAL),
-PKIX_ERRORENTRY(INESCAPEDASCII,in EscapedASCII,0),
-PKIX_ERRORENTRY(INFOACCESSCREATEFAILED,pkix_pl_InfoAccess_Create failed,0),
-PKIX_ERRORENTRY(INFOACCESSCREATELISTFAILED,pkix_pl_InfoAccess_CreateList failed,0),
-PKIX_ERRORENTRY(INFOACCESSGETLOCATIONFAILED,PKIX_PL_InfoAccess_GetLocation failed,0),
-PKIX_ERRORENTRY(INFOACCESSGETLOCATIONTYPEFAILED,PKIX_PL_InfoAccess_GetLocationType failed,0),
-PKIX_ERRORENTRY(INFOACCESSGETMETHODFAILED,PKIX_PL_InfoAccess_GetMethod failed,0),
-PKIX_ERRORENTRY(INFOACCESSPARSELOCATIONFAILED,pkix_pl_InfoAccess_ParseLocation failed,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
-PKIX_ERRORENTRY(INFOACCESSPARSETOKENSFAILED,pkix_pl_InfoAccess_ParseTokens failed,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
-PKIX_ERRORENTRY(INITIALIZECHECKERSFAILED,pkix_InitializeCheckers failed,0),
-PKIX_ERRORENTRY(INITIALIZEFAILED,PKIX_PL_Initialize failed,0),
-PKIX_ERRORENTRY(INPUTLISTMUSTBEHEADER,Input List must be header,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(INPUTLISTSMUSTBELISTHEADERS,Input Lists must be list headers,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(INSUFFICIENTCRITERIAFORCERTQUERY,Insufficient criteria for Cert query,0),
-PKIX_ERRORENTRY(INSUFFICIENTCRITERIAFORCRLQUERY,Insufficient criteria for Crl Query,0),
-PKIX_ERRORENTRY(INTRUSTEDCERT,in Trusted Cert,0),
-PKIX_ERRORENTRY(INVALIDCHARACTERINBIGINT,Invalid character in BigInt,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(INVALIDDERENCODINGFOROID,Invalid DER-encoding for OID,0),
-PKIX_ERRORENTRY(INVALIDENCODINGOIDTOKENVALUETOOBIG,Invalid encoding: OID token value too big,0),
-PKIX_ERRORENTRY(INVALIDPOLICYMAPPINGINCLUDESANYPOLICY,Invalid policyMapping includes anyPolicy,SEC_ERROR_INVALID_POLICY_MAPPING),
-PKIX_ERRORENTRY(INVALIDREVOCATIONMETHOD,Invalid revocation method,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(INVALIDSIGNINGCERTINOCSPRESPONSE,Invalid signing Cert in OCSP response,SEC_ERROR_OCSP_INVALID_SIGNING_CERT),
-PKIX_ERRORENTRY(INVALIDSTATUS,INVALID STATUS,0),
-PKIX_ERRORENTRY(INVALIDSTORETYPEFORSETTINGCONFIGDIR,Invalid Store type for Setting ConfigDir,0),
-PKIX_ERRORENTRY(IPADDRBYTES2ASCIIDATALENGTHZERO,pkix_pl_ipAddrBytes2Ascii: data length is zero,0),
-PKIX_ERRORENTRY(IPADDRBYTES2ASCIIFAILED,pkix_pl_ipAddrBytes2Ascii failed,0),
-PKIX_ERRORENTRY(ISCERTSELFISSUEDFAILED,pkix_IsCertSelfIssued failed,0),
-PKIX_ERRORENTRY(ISCERTSELFISSUEFAILED,pkix_IsCertSelfIssue failed,0),
-PKIX_ERRORENTRY(KEYUSAGEKEYCERTSIGNBITNOTON,Validation failed: KeyUsage KeyCertSign bit is not on,SEC_ERROR_CA_CERT_INVALID),
-PKIX_ERRORENTRY(KEYUSAGEKEYCRLSIGNBITNOTON,Validation failed: KeyUsage CRLSign bit is not on,0),
-PKIX_ERRORENTRY(LDAPCERTSTOREBUILDCERTLISTFAILED,pkix_pl_LdapCertStore_BuildCertList failed,0),
-PKIX_ERRORENTRY(LDAPCERTSTOREBUILDCRLLISTFAILED,pkix_pl_LdapCertStore_BuildCrlList failed,0),
-PKIX_ERRORENTRY(LDAPCERTSTOREDECODECROSSCERTPAIRFAILED,pkix_pl_LdapCertStore_DecodeCrossCertPair failed,0),
-PKIX_ERRORENTRY(LDAPCERTSTOREDESTROYAVALISTFAILED,pkix_pl_LdapCertStore_DestroyAVAList failed,0),
-PKIX_ERRORENTRY(LDAPCERTSTOREINILLEGALSTATE,LDAP CertStore in illegal state,0),
-PKIX_ERRORENTRY(LDAPCERTSTOREMAKENAMEAVALISTFAILED,pkix_pl_LdapCertStore_MakeNameAVAList failed,0),
-PKIX_ERRORENTRY(LDAPCLIENTINITIATEREQUESTFAILED,PKIX_PL_LdapClient_InitiateRequest failed,0),
-PKIX_ERRORENTRY(LDAPCLIENTRESUMEREQUESTFAILED,PKIX_PL_LdapClient_ResumeRequest failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTABANDONCONTINUEFAILED,pkix_pl_LdapDefaultClient_AbandonContinue failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTBINDCONTINUEFAILED,pkix_pl_LdapDefaultClient_BindContinue failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTBINDFAILED,pkix_pl_LdapDefaultClient_Bind failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTBINDRESPONSECONTINUEFAILED,pkix_pl_LdapDefaultClient_BindResponseContinue failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTBINDRESPONSEFAILED,pkix_pl_LdapDefaultClient_BindResponse failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTCONNECTCONTINUEFAILED,pkix_pl_LdapDefaultClient_ConnectContinue failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTCREATEBYNAMEFAILED,PKIX_PL_LdapDefaultClient_CreateByName failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTCREATEHELPERFAILED,pkix_pl_LdapDefaultClient_CreateHelper failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTDECODEBINDRESPONSEFAILED,pkix_pl_LdapDefaultClient_DecodeBindResponse failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTDISPATCHFAILED,pkix_pl_LdapDefaultClient_Dispatch failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTINILLEGALSTATE,LDAP DefaultClient in illegal state,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTMAKEABANDONFAILED,pkix_pl_LdapDefaultClient_MakeAbandon failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTMAKEANDFILTERFAILED,pkix_pl_LdapDefaultClient_MakeAndFilter failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTMAKEBINDFAILED,pkix_pl_LdapDefaultClient_MakeBind failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTMAKEUNBINDFAILED,pkix_pl_LdapDefaultClient_MakeUnbind failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED,pkix_pl_LdapDefaultClient_RecvCheckComplete failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTRECVCONTINUEFAILED,pkix_pl_LdapDefaultClient_RecvContinue failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTRECVFAILED,pkix_pl_LdapDefaultClient_Recv failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTRECVINITIALFAILED,pkix_pl_LdapDefaultClient_RecvInitial failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTRECVNONINITIALFAILED,pkix_pl_LdapDefaultClient_RecvNonInitial failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTSENDCONTINUEFAILED,pkix_pl_LdapDefaultClient_SendContinue failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTSENDFAILED,pkix_pl_LdapDefaultClient_Send failed,0),
-PKIX_ERRORENTRY(LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED,pkix_pl_LdapDefaultClient_VerifyBindResponse failed,0),
-PKIX_ERRORENTRY(LDAPREQUESTATTRSTRINGTOBITFAILED,pkix_pl_LdapRequest_AttrStringToBit failed,0),
-PKIX_ERRORENTRY(LDAPREQUESTATTRTYPETOBITFAILED,pkix_pl_LdapRequest_AttrTypeToBit failed,0),
-PKIX_ERRORENTRY(LDAPREQUESTCREATEFAILED,pkix_pl_LdapRequest_Create failed,0),
-PKIX_ERRORENTRY(LDAPREQUESTENCODEATTRSFAILED,pkix_pl_LdapRequest_EncodeAttrs failed,0),
-PKIX_ERRORENTRY(LDAPREQUESTGETENCODEDFAILED,pkix_pl_LdapRequest_GetEncoded failed,0),
-PKIX_ERRORENTRY(LDAPRESPONSEAPPENDFAILED,pkix_pl_LdapResponse_Append failed,0),
-PKIX_ERRORENTRY(LDAPRESPONSECREATEFAILED,pkix_pl_LdapResponseCreate failed,0),
-PKIX_ERRORENTRY(LDAPRESPONSEDECODEFAILED,pkix_pl_LDAPResponse_Decode failed,0),
-PKIX_ERRORENTRY(LDAPRESPONSEGETCAPACITYFAILED,pkix_pl_LdapResponse_GetCapacity failed,0),
-PKIX_ERRORENTRY(LDAPRESPONSEGETMESSAGEFAILED,pkix_pl_LdapResponse_GetMessage failed,0),
-PKIX_ERRORENTRY(LDAPRESPONSEGETMESSAGETYPEFAILED,pkix_pl_LdapResponse_GetMessageType failed,0),
-PKIX_ERRORENTRY(LDAPRESPONSEGETRESULTCODEFAILED,pkix_pl_LdapResponse_GetResultCode failed,0),
-PKIX_ERRORENTRY(LDAPRESPONSEISCOMPLETEFAILED,pkix_pl_LdapResponse_IsComplete failed,0),
-PKIX_ERRORENTRY(LISTAPPENDFAILED,PKIX_List_Append failed,0),
-PKIX_ERRORENTRY(LISTAPPENDITEMFAILED,PKIX_List_AppendItem failed,0),
-PKIX_ERRORENTRY(LISTAPPENDLISTFAILED,pkix_List_AppendList failed,0),
-PKIX_ERRORENTRY(LISTAPPENDUNIQUEFAILED,pkix_List_AppendUnique failed,0),
-PKIX_ERRORENTRY(LISTBUBBLESORTFAILED,pkix_List_BubbleSort failed,0),
-PKIX_ERRORENTRY(LISTCONTAINSFAILED,pkix_List_Contains failed,0),
-PKIX_ERRORENTRY(LISTCREATEFAILED,PKIX_List_Create failed,0),
-PKIX_ERRORENTRY(LISTCREATEINTERNALFAILED,pkix_List_Create_Internal failed,0),
-PKIX_ERRORENTRY(LISTDELETEITEMFAILED,PKIX_List_DeleteItem failed,0),
-PKIX_ERRORENTRY(LISTDUPLICATEFAILED,pkix_List_Duplicate failed,0),
-PKIX_ERRORENTRY(LISTEQUALSFAILED,PKIX_List_Equals failed,0),
-PKIX_ERRORENTRY(LISTGETELEMENTFAILED,pkix_List_GetElement failed,0),
-PKIX_ERRORENTRY(LISTGETITEMFAILED,PKIX_List_GetItem failed,0),
-PKIX_ERRORENTRY(LISTGETLENGTHFAILED,PKIX_List_GetLength failed,0),
-PKIX_ERRORENTRY(LISTHASHCODEFAILED,pkix_List_Hashcode failed,0),
-PKIX_ERRORENTRY(LISTINSERTITEMFAILED,PKIX_List_InsertItem failed,0),
-PKIX_ERRORENTRY(LISTISEMPTYFAILED,PKIX_List_IsEmpty failed,0),
-PKIX_ERRORENTRY(LISTMERGEFAILED,pkix_List_MergeList failed,0),
-PKIX_ERRORENTRY(LISTQUICKSORTFAILED,pkix_List_QuickSort failed,0),
-PKIX_ERRORENTRY(LISTREMOVEFAILED,pkix_List_Remove failed,0),
-PKIX_ERRORENTRY(LISTREMOVEITEMSFAILED,pkix_List_RemoveItems failed,0),
-PKIX_ERRORENTRY(LISTREVERSELISTFAILED,PKIX_List_ReverseList failed,0),
-PKIX_ERRORENTRY(LISTSETIMMUTABLEFAILED,PKIX_List_SetImmutable failed,0),
-PKIX_ERRORENTRY(LISTSETITEMFAILED,PKIX_List_SetItem failed,0),
-PKIX_ERRORENTRY(LISTTOSTRINGFAILED,pkix_List_ToString failed,0),
-PKIX_ERRORENTRY(LISTTOSTRINGHELPERFAILED,pkix_List_ToString Helper failed,0),
-PKIX_ERRORENTRY(LOCATIONSTRINGNOTPROPERLYTERMINATED,Location string not properly terminated,0),
-PKIX_ERRORENTRY(LOCKHASNONZEROREADCOUNT,Lock has non-zero read count,0),
-PKIX_ERRORENTRY(LOCKOBJECTFAILED,pkix_LockObject failed,0),
-PKIX_ERRORENTRY(LOGGERDUPLICATEFAILED,pkix_Logger_Duplicate failed,0),
-PKIX_ERRORENTRY(LOGGINGLEVELEXCEEDSMAXIMUM,Logging Level exceeds Maximum,0),
-PKIX_ERRORENTRY(LOOPDISCOVEREDDUPCERTSNOTALLOWED,Loop discovered: duplicate certificates not allowed,SEC_ERROR_UNTRUSTED_ISSUER),
-PKIX_ERRORENTRY(LOOPOFERRORCAUSEDETECTED,Loop of error causes detected,0),
-PKIX_ERRORENTRY(MAJORVERSIONSDONTMATCH,Major versions do not match,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(MALLOCFAILED,PKIX_PL_Malloc failed,0),
-PKIX_ERRORENTRY(MEMLEAKGENERATEDERROR,Error generated for memory leak testing,SEC_ERROR_NO_MEMORY),
-PKIX_ERRORENTRY(MINORVERSIONNOTBETWEENDESIREDMINANDMAX,Minor version does not fall between desired minimum and maximum,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(MISSINGDSAPARAMETERS,Missing DSA parameters in Trusted Cert,SEC_ERROR_INVALID_KEY),
-PKIX_ERRORENTRY(MONITORLOCKCREATEFAILED,PKIX_PL_MonitorLock_Create failed,0),
-PKIX_ERRORENTRY(MONITORLOCKENTERFAILED,PKIX_PL_MonitorLock_Enter failed,0),
-PKIX_ERRORENTRY(MONITORLOCKEXITFAILED,PKIX_PL_MonitorLock_Exit failed,0),
-PKIX_ERRORENTRY(MUTEXLOCKFAILED,PKIX_PL_Mutex_Lock failed,0),
-PKIX_ERRORENTRY(NAMECHAININGCHECKERINITIALIZEFAILED,pkix_NameChainingChecker_Initialize failed,0),
-PKIX_ERRORENTRY(NAMECHAININGCHECKFAILED,Name Chaining Check failed,SEC_ERROR_UNKNOWN_ISSUER),
-PKIX_ERRORENTRY(NAMECOMPONENTWITHNOEQ,Name Component with no equal sign,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
-PKIX_ERRORENTRY(NAMECONSTRAINTSCHECKERINITIALIZEFAILED,pkix_NameConstraintsChecker_Initialize failed,0),
-PKIX_ERRORENTRY(NAMECONSTRAINTSCHECKERSTATECREATEFAILED,pkix_NameConstraintsCheckerState_Create failed,0),
-PKIX_ERRORENTRY(NAMETYPENOTSUPPORTED,name type not supported,0),
-PKIX_ERRORENTRY(NOCONTENTTYPEINHTTPRESPONSE,No content type in Http Response,SEC_ERROR_BAD_HTTP_RESPONSE),
-PKIX_ERRORENTRY(NODESMISSINGFROMCHAIN,Nodes missing from chain,0),
-PKIX_ERRORENTRY(NOREGISTEREDHTTPCLIENT,No registered Http Client,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(NORESPONSEDATAINHTTPRESPONSE,No responseData in Http Response,SEC_ERROR_BAD_HTTP_RESPONSE),
-PKIX_ERRORENTRY(NOTARGETCERTSUPPLIED,No target cert supplied,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(NOTCONFORMINGCRLDP,Cert CRL DP does not conform to the rfc, 0),
-PKIX_ERRORENTRY(NOTDERPACKAGE,Not a DER package,0),
-PKIX_ERRORENTRY(NOTENOUGHNAMECOMPONENTSINGENERALNAME,Not enough name components in GeneralName,SEC_ERROR_BAD_INFO_ACCESS_LOCATION),
-PKIX_ERRORENTRY(NSSCERTIFICATEUSAGETOPKIXKUANDEKUFAILED,Failed to convert nss certificate usage to pkix ku and eku data structures,0),
-PKIX_ERRORENTRY(NSSCONTEXTCREATEFAILED,PKIX_PL_NssContext_Create failed,0),
-PKIX_ERRORENTRY(NSSCONTEXTDESTROYFAILED,PKIX_PL_NssContext_Destroy failed,0),
-PKIX_ERRORENTRY(NSSCONTEXTGETCHECKALLUSAGESFAILED, pkix_pl_NssContext_GetCheckAllUsages failed,0),
-PKIX_ERRORENTRY(NSSCONTEXTGETRETURNUSAGESFAILED, pkix_pl_NssContext_GetReturnUsages failed,0),
-PKIX_ERRORENTRY(NSSCONTEXTGETWINCXFAILED,pkix_pl_NssContext_GetWincx failed,0),
-PKIX_ERRORENTRY(NSSCONTEXTSETCERTSIGNCHECKFAILED, pkix_pl_NssContext_SetCertSignatureCheck,0),
-PKIX_ERRORENTRY(NSSCONTEXTSETCERTUSAGEFAILED, pkix_pl_NssContext_SetCertUsage failed,0),
-PKIX_ERRORENTRY(NSSCONTEXTSETCHECKALLUSAGESFAILED, pkix_pl_NssContext_SetCheckAllUsages failed,0),
-PKIX_ERRORENTRY(NSSCONTEXTSETRETURNEDCERTUSAGEFAILED, pkix_pl_NssContext_SetReturnedCertUsage,0),
-PKIX_ERRORENTRY(NSSCONTEXTSETRETURNUSAGESFAILED, pkix_pl_NssContext_SetReturnUsages failed,0),
-PKIX_ERRORENTRY(NSSCONTEXTVALIDATINGRESPONDERCERTFAILED,pkix_pl_NssContext_ValidatingResponderCert failed,0),
-PKIX_ERRORENTRY(NSSTRUSTEDLISTISEMPTY,nss trusted roots list is empty,0),
-PKIX_ERRORENTRY(NULLARGUMENT,Null argument,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(NUMBUCKETSEQUALSZERO,NumBuckets equals zero,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(OBJECTALLOCFAILED,PKIX_PL_Object_Alloc failed,0),
-PKIX_ERRORENTRY(OBJECTARGUMENTNOTPOLICYMAP,object argument is not a PolicyMap,0),
-PKIX_ERRORENTRY(OBJECTCOMPARATORFAILED,PKIX_PL_Object_Comparator failed,0),
-PKIX_ERRORENTRY(OBJECTDEFINED,object-defined ,0),
-PKIX_ERRORENTRY(OBJECTDUPLICATECERTFAILED,PKIX_PL_Object_Duplicate Cert failed,0),
-PKIX_ERRORENTRY(OBJECTDUPLICATECONTEXTFAILED,PKIX_PL_Object_Duplicate Context failed,0),
-PKIX_ERRORENTRY(OBJECTDUPLICATEDATEFAILED,PKIX_PL_Object_Duplicate Date failed,0),
-PKIX_ERRORENTRY(OBJECTDUPLICATEFAILED,PKIX_PL_Object_Duplicate failed,0),
-PKIX_ERRORENTRY(OBJECTDUPLICATEISSUERNAMESFAILED,PKIX_PL_Object_Duplicate IssuerNames failed,0),
-PKIX_ERRORENTRY(OBJECTDUPLICATELISTFAILED,PKIX_PL_Object_Duplicate List failed,0),
-PKIX_ERRORENTRY(OBJECTDUPLICATEMAXCRLNUMBERFAILED,PKIX_PL_Object_Duplicate maxCRLNumber failed,0),
-PKIX_ERRORENTRY(OBJECTDUPLICATEMINCRLNUMBERFAILED,PKIX_PL_Object_Duplicate minCRLNumber failed,0),
-PKIX_ERRORENTRY(OBJECTDUPLICATEPARAMSFAILED,PKIX_PL_Object_Duplicate Params failed,0),
-PKIX_ERRORENTRY(OBJECTEQUALSFAILED,PKIX_PL_Object_Equals failed,0),
-PKIX_ERRORENTRY(OBJECTEQUALSFAILEDONCHILDREN,PKIX_PL_Object_Equals failed on children,0),
-PKIX_ERRORENTRY(OBJECTEQUALSFAILEDONEXPECTEDPOLICYSETS,PKIX_PL_Object_Equals failed on expectedPolicySets,0),
-PKIX_ERRORENTRY(OBJECTGETTYPEFAILED,PKIX_PL_Object_GetType failed,0),
-PKIX_ERRORENTRY(OBJECTHASHCODEFAILED,PKIX_PL_Object_Hashcode failed,0),
-PKIX_ERRORENTRY(OBJECTINVALIDATECACHEFAILED,PKIX_PL_Object_InvalidateCache failed,0),
-PKIX_ERRORENTRY(OBJECTISTYPEREGISTEREDFAILED,PKIX_PL_Object_IsTypeRegistered failed,0),
-PKIX_ERRORENTRY(OBJECTLOCKFAILED,PKIX_PL_Object_Lock failed,0),
-PKIX_ERRORENTRY(OBJECTNOTAIAMGR,Object is not a AIAMgr,0),
-PKIX_ERRORENTRY(OBJECTNOTANEKUCHECKERSTATE,Object is not an EKU Checker State,0),
-PKIX_ERRORENTRY(OBJECTNOTANERROR,Object is not an Error,0),
-PKIX_ERRORENTRY(OBJECTNOTANHTTPCERTSTORECONTEXT,Object is not an HttpCertStoreContext,0),
-PKIX_ERRORENTRY(OBJECTNOTANHTTPDEFAULTCLIENT,Object is not an HttpDefaultClient,0),
-PKIX_ERRORENTRY(OBJECTNOTANINFOACCESS,Object is not an InfoAccess,0),
-PKIX_ERRORENTRY(OBJECTNOTANLDAPDEFAULTCLIENT,Object is not an LdapDefaultClient,0),
-PKIX_ERRORENTRY(OBJECTNOTANOCSPRESPONSE,Object is not an OcspResponse,0),
-PKIX_ERRORENTRY(OBJECTNOTANOID,Object is not an OID,0),
-PKIX_ERRORENTRY(OBJECTNOTANSOCKET,Object is not an Socket,0),
-PKIX_ERRORENTRY(OBJECTNOTANX500NAME,Object is not an X500Name,0),
-PKIX_ERRORENTRY(OBJECTNOTBASICCONSTRAINTSCHECKERSTATE,Object is not a basic constraints checker state,0),
-PKIX_ERRORENTRY(OBJECTNOTBIGINT,Object is not a BigInt,0),
-PKIX_ERRORENTRY(OBJECTNOTBUILDPARAMS,Object is not a BuildParams,0),
-PKIX_ERRORENTRY(OBJECTNOTBUILDRESULT,Object is not a BuildResult,0),
-PKIX_ERRORENTRY(OBJECTNOTBYTEARRAY,Object is not a bytearray,0),
-PKIX_ERRORENTRY(OBJECTNOTCERT,Object is not a Cert,0),
-PKIX_ERRORENTRY(OBJECTNOTCERTBASICCONSTRAINTS,Object is not a CertBasicConstraints,0),
-PKIX_ERRORENTRY(OBJECTNOTCERTCHAINCHECKER,Object is not a cert chain checker,0),
-PKIX_ERRORENTRY(OBJECTNOTCERTNAMECONSTRAINTS,Object is not a CertNameConstraints,0),
-PKIX_ERRORENTRY(OBJECTNOTCERTPOLICYINFO,Object is not a CertPolicyInfo,0),
-PKIX_ERRORENTRY(OBJECTNOTCERTPOLICYMAP,Object is not a CertPolicyMap,0),
-PKIX_ERRORENTRY(OBJECTNOTCERTPOLICYQUALIFIER,Object is not a CertPolicyQualifier,0),
-PKIX_ERRORENTRY(OBJECTNOTCERTSELECTOR,Object is not a cert selector,0),
-PKIX_ERRORENTRY(OBJECTNOTCERTSTORE,Object is not a CertStore,0),
-PKIX_ERRORENTRY(OBJECTNOTCOLLECTIONCERTSTORECONTEXT,Object is not a CollectionCertStoreContext,0),
-PKIX_ERRORENTRY(OBJECTNOTCOMCERTSELPARAMS,Object is not a comCertSelParams,0),
-PKIX_ERRORENTRY(OBJECTNOTCOMCRLSELPARAMS,Object is not a ComCRLSelParams,0),
-PKIX_ERRORENTRY(OBJECTNOTCRL,Object is not a CRL,0),
-PKIX_ERRORENTRY(OBJECTNOTCRLENTRY,Object is not a CRLEntry,0),
-PKIX_ERRORENTRY(OBJECTNOTCRLSELECTOR,Object is not a CRLSelector,0),
-PKIX_ERRORENTRY(OBJECTNOTDATE,Object is not a Date,0),
-PKIX_ERRORENTRY(OBJECTNOTCRLCHECKER,Object is not a CRLChecker,0),
-PKIX_ERRORENTRY(OBJECTNOTDEFAULTREVOCATIONCHECKER,Object is not a DefaultRevocationChecker,0),
-PKIX_ERRORENTRY(OBJECTNOTFORWARDBUILDERSTATE,Object is not a PKIX_ForwardBuilderState,0),
-PKIX_ERRORENTRY(OBJECTNOTGENERALNAME,Object is not a GeneralName,0),
-PKIX_ERRORENTRY(OBJECTNOTHASHTABLE,Object is not a hashtable,0),
-PKIX_ERRORENTRY(OBJECTNOTINFOACCESS,Object is not a InfoAccess,0),
-PKIX_ERRORENTRY(OBJECTNOTLDAPREQUEST,Object is not a LdapRequest,0),
-PKIX_ERRORENTRY(OBJECTNOTLDAPRESPONSE,Object is not a LdapResponse,0),
-PKIX_ERRORENTRY(OBJECTNOTLIST,Object is not a list,0),
-PKIX_ERRORENTRY(OBJECTNOTLOGGER,Object is not a Logger,0),
-PKIX_ERRORENTRY(OBJECTNOTMONITORLOCK,Object is not a MonitorLock,0),
-PKIX_ERRORENTRY(OBJECTNOTMUTEX,Object is not a Mutex,0),
-PKIX_ERRORENTRY(OBJECTNOTNAMECONSTRAINTSCHECKERSTATE,Object is not a name constraints checker state,0),
-PKIX_ERRORENTRY(OBJECTNOTOCSPCERTID,Object is not an OcspCertID,0),
-PKIX_ERRORENTRY(OBJECTNOTOCSPCHECKER,Object is not an OCSPChecker,0),
-PKIX_ERRORENTRY(OBJECTNOTOCSPREQUEST,Object is not an OcspRequest,0),
-PKIX_ERRORENTRY(OBJECTNOTPOLICYCHECKERSTATE,Object is not a PKIX_PolicyCheckerState,0),
-PKIX_ERRORENTRY(OBJECTNOTPOLICYNODE,Object is not a PolicyNode,0),
-PKIX_ERRORENTRY(OBJECTNOTPROCESSINGPARAMS,Object is not a ProcessingParams,0),
-PKIX_ERRORENTRY(OBJECTNOTPUBLICKEY,Object is not a PublicKey,0),
-PKIX_ERRORENTRY(OBJECTNOTRESOURCELIMITS,Object is not a ResourceLimits,0),
-PKIX_ERRORENTRY(OBJECTNOTREVOCATIONCHECKER,Object is not a revocation checker,0),
-PKIX_ERRORENTRY(OBJECTNOTRWLOCK,Object is not a RWLock,0),
-PKIX_ERRORENTRY(OBJECTNOTSIGNATURECHECKERSTATE,Object is not a signature checker state,0),
-PKIX_ERRORENTRY(OBJECTNOTSOCKET,Object is not a Socket,0),
-PKIX_ERRORENTRY(OBJECTNOTSTRING,Object is not a string,0),
-PKIX_ERRORENTRY(OBJECTNOTTARGETCERTCHECKERSTATE,Object is not a target cert checker state,0),
-PKIX_ERRORENTRY(OBJECTNOTTRUSTANCHOR,Object is not a trustAnchor,0),
-PKIX_ERRORENTRY(OBJECTNOTVALIDATEPARAMS,Object is not a ValidateParams,0),
-PKIX_ERRORENTRY(OBJECTNOTVALIDATERESULT,Object is not a ValidateResult,0),
-PKIX_ERRORENTRY(OBJECTNOTVERIFYNODE,Object is not a VerifyNode,0),
-PKIX_ERRORENTRY(OBJECTREGISTERTYPEFAILED,PKIX_PL_Object_RegisterType failed,0),
-PKIX_ERRORENTRY(OBJECTRETRIEVEEQUALSCALLBACKFAILED,pkix_pl_Object_RetrieveEqualsCallback failed,0),
-PKIX_ERRORENTRY(OBJECTSPECIFICFUNCTIONFAILED,object-specific function failed,0),
-PKIX_ERRORENTRY(OBJECTSTILLREFERENCED,Object is still referenced,0),
-PKIX_ERRORENTRY(OBJECTTOSTRINGFAILED,PKIX_PL_Object_ToString failed,0),
-PKIX_ERRORENTRY(OBJECTTYPESDONOTMATCH,Object types do not match,0),
-PKIX_ERRORENTRY(OBJECTWITHNONPOSITIVEREFERENCES,Object with non-positive references,0),
-PKIX_ERRORENTRY(OCSPCERTIDCREATEFAILED,PKIX_PL_OcspCertID_Create failed,0),
-PKIX_ERRORENTRY(OCSPCERTIDGETFRESHCACHESTATUSFAILED,PKIX_PL_OcspCertID_GetFreshCacheStatus returned an error,0),
-PKIX_ERRORENTRY(OCSPCERTIDREMEMBEROCSPFAILUREDFAILED,PKIX_PL_OcspCertID_RememberOCSPProcessingFailure,0),
-PKIX_ERRORENTRY(OCSPCHECKERCREATEFAILED,PKIX_OcspChecker_Create failed,0),
-PKIX_ERRORENTRY(OCSPBADHTTPRESPONSE,Bad Http Response,SEC_ERROR_OCSP_BAD_HTTP_RESPONSE),
-PKIX_ERRORENTRY(OCSPREQUESTCREATEFAILED,PKIX_PL_OcspRequest_Create failed,0),
-PKIX_ERRORENTRY(OCSPREQUESTGETCERTIDFAILED,pkix_pl_OcspRequest_GetCertID failed,0),
-PKIX_ERRORENTRY(OCSPREQUESTGETENCODEDFAILED,pkix_pl_OcspRequest_GetEncoded failed,0),
-PKIX_ERRORENTRY(OCSPREQUESTGETLOCATIONFAILED,pkix_pl_OcspRequest_GetLocation failed,0),
-PKIX_ERRORENTRY(OCSPRESPONSECREATEFAILED,pkix_pl_OcspResponse_Create failed,0),
-PKIX_ERRORENTRY(OCSPRESPONSEDECODEFAILED,pkix_pl_OcspResponse_Decode failed,0),
-PKIX_ERRORENTRY(OCSPRESPONSEGETSTATUSFORCERTFAILED,pkix_pl_OcspResponse_GetStatusForCert failed,0),
-PKIX_ERRORENTRY(OCSPRESPONSEGETSTATUSRETURNEDANERROR,pkix_pl_OcspResponse_GetStatus returned an error,0),
-PKIX_ERRORENTRY(OCSPRESPONSESAYSCERTREVOKED,OCSP response says Cert revoked,SEC_ERROR_REVOKED_CERTIFICATE_OCSP),
-PKIX_ERRORENTRY(OCSPRESPONSEVERIFYSIGNATUREFAILED,pkix_pl_OcspResponse_VerifySignature failed,0),
-PKIX_ERRORENTRY(OCSPSERVERERROR,OCSP Server Error,SEC_ERROR_OCSP_SERVER_ERROR),
-PKIX_ERRORENTRY(OIDBYTES2ASCIIDATALENGTHZERO,pkix_pl_oidBytes2Ascii: data length is zero,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(OIDBYTES2ASCIIFAILED,pkix_pl_oidBytes2Ascii failed,0),
-PKIX_ERRORENTRY(OIDBYTESLENGTH0,Oid bytes length is 0,0),
-PKIX_ERRORENTRY(OIDCOMPARATORFAILED,pkix_pl_OID_Comparator failed,0),
-PKIX_ERRORENTRY(OIDCOMPONENTTOOBIG,Overflow error: OID component > 2^32,0),
-PKIX_ERRORENTRY(OIDCREATEFAILED,PKIX_PL_OID_Create failed,0),
-PKIX_ERRORENTRY(OIDEQUALFAILED,PKIX_PL_OID_Equal failed,0),
-PKIX_ERRORENTRY(OIDEQUALSFAILED,PKIX_PL_OID_Equals failed,0),
-PKIX_ERRORENTRY(OIDGETNEXTTOKENFAILED,pkix_pl_OID_GetNextToken failed,0),
-PKIX_ERRORENTRY(OIDHASHCODEFAILED,PKIX_PL_OID_Hashcode failed,0),
-PKIX_ERRORENTRY(OIDLENGTHTOOSHORT,OID length too short,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(OIDNEEDS2ORMOREFIELDS,OID needs 2 or more fields,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(OIDTOSTRINGFAILED,PKIX_PL_OID_ToString failed,0),
-PKIX_ERRORENTRY(OPERATIONNOTPERMITTEDONIMMUTABLELIST,Operation not permitted on Immutable List,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(OTHERNAMECREATEFAILED,pkix_pl_OtherName_Create failed,0),
-PKIX_ERRORENTRY(OUTOFMEMORY,Out of Memory,0),
-PKIX_ERRORENTRY(PATHLENCONSTRAINTINVALID,Certificate path length constraint is invalid,SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID),
-PKIX_ERRORENTRY(PK11CERTSTORECERTQUERYFAILED,pkix_pl_Pk11CertStore_CertQuery failed,0),
-PKIX_ERRORENTRY(PK11CERTSTORECREATEFAILED,PKIX_PL_Pk11CertStore_Create failed,0),
-PKIX_ERRORENTRY(PK11CERTSTORECRLQUERYFAILED,pkix_pl_Pk11CertStore_CrlQuery failed,0),
-PKIX_ERRORENTRY(PKIXUNKNOWNERROR,PKIX uninitialized error code,0),
-PKIX_ERRORENTRY(POLICYCHECKERCALCULATEINTERSECTIONFAILED,pkix_PolicyChecker_CalculateIntersection failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERCHECKANYFAILED,pkix_PolicyChecker_CheckAny failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERCHECKPOLICYRECURSIVEFAILED,pkix_PolicyChecker_CheckPolicyRecursive failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERERROR,PolicyChecker Error,0),
-PKIX_ERRORENTRY(POLICYCHECKERINITIALIZEFAILED,pkix_PolicyChecker_Initialize failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERMAKEMUTABLECOPYFAILED,pkix_PolicyChecker_MakeMutableCopy failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERMAKESINGLETONFAILED,pkix_PolicyChecker_MakeSingleton failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERMAPCONTAINSFAILED,pkix_PolicyChecker_MapContains failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERMAPGETMAPPEDPOLICIESFAILED,pkix_PolicyChecker_MapGetMappedPolicies failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED,pkix_PolicyChecker_MapGetSubjectDomainPolicies failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERSPAWNFAILED,pkix_PolicyChecker_Spawn failed,0),
-PKIX_ERRORENTRY(POLICYCHECKERSTATECREATEFAILED,PKIX_PolicyCheckerState_Create failed,0),
-PKIX_ERRORENTRY(POLICYNODEADDTOPARENTFAILED,pkix_PolicyNode_AddToParent failed,0),
-PKIX_ERRORENTRY(POLICYNODECREATEFAILED,pkix_PolicyNode_Create failed,0),
-PKIX_ERRORENTRY(POLICYNODEDUPLICATEHELPERFAILED,pkix_PolicyNode_DuplicateHelper failed,0),
-PKIX_ERRORENTRY(POLICYNODEGETCHILDRENMUTABLEFAILED,pkix_PolicyNode_GetChildrenMutable failed,0),
-PKIX_ERRORENTRY(POLICYNODEGETDEPTHFAILED,PKIX_PolicyNode_GetDepth failed,0),
-PKIX_ERRORENTRY(POLICYNODEGETEXPECTEDPOLICIESFAILED,PKIX_PolicyNode_GetExpectedPolicies failed,0),
-PKIX_ERRORENTRY(POLICYNODEGETPARENTFAILED,PKIX_PolicyNode_GetParent failed,0),
-PKIX_ERRORENTRY(POLICYNODEGETPOLICYQUALIFIERSFAILED,PKIX_PolicyNode_GetPolicyQualifiers failed,0),
-PKIX_ERRORENTRY(POLICYNODEGETVALIDPOLICYFAILED,PKIX_PolicyNode_GetValidPolicy failed,0),
-PKIX_ERRORENTRY(POLICYNODEISCRITICALFAILED,PKIX_PolicyNode_IsCritical failed,0),
-PKIX_ERRORENTRY(POLICYNODEPRUNEFAILED,pkix_PolicyNode_Prune failed,0),
-PKIX_ERRORENTRY(POLICYTREETOOIDSFAILED,Failed to convert policy tree to oid,0),
-PKIX_ERRORENTRY(PORTARENAALLOCFAILED,PORT Arena Allocation failed, 0),
-PKIX_ERRORENTRY(PORTUCS2UTF8CONVERSIONFAILED,PORT_UCS2_UTF8Conversion failed.,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(PRACCEPTFAILED,PR_Accept failed,0),
-PKIX_ERRORENTRY(PRBINDFAILED,PR_Bind failed,0),
-PKIX_ERRORENTRY(PRCONNECTCONTINUEFAILED,PR_ConnectContinue failed,0),
-PKIX_ERRORENTRY(PRCONNECTFAILED,PR_Connect failed,0),
-PKIX_ERRORENTRY(PRECONDITIONFAILED,Function precondition failed,SEC_ERROR_LIBPKIX_INTERNAL),
-PKIX_ERRORENTRY(PRENUMERATEHOSTENTFAILED,PR_EnumerateHostEnt failed.,0),
-PKIX_ERRORENTRY(PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT,PR_GetHostByName rejects hostname argument.,0),
-PKIX_ERRORENTRY(PRIMHASHTABLEADDFAILED,pkix_pl_PrimHashTable_Add failed,0),
-PKIX_ERRORENTRY(PRIMHASHTABLECREATEFAILED,pkix_pl_PrimHashTable_Create failed,0),
-PKIX_ERRORENTRY(PRIMHASHTABLEDESTROYFAILED,pkix_pl_PrimHashTable_Destroy failed,0),
-PKIX_ERRORENTRY(PRIMHASHTABLEGETBUCKETSIZEFAILED,pkix_pl_PrimHashTable_GetBucketSize failed,0),
-PKIX_ERRORENTRY(PRIMHASHTABLELOOKUPFAILED,pkix_pl_PrimHashTable_Lookup failed,0),
-PKIX_ERRORENTRY(PRIMHASHTABLEREMOVEFAILED,pkix_pl_PrimHashTable_Remove failed,0),
-PKIX_ERRORENTRY(PRLISTENFAILED,PR_Listen failed,0),
-PKIX_ERRORENTRY(PRNEWTCPSOCKETFAILED,PR_NewTCPSocket failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSADDCERTCHAINCHECKERFAILED,PKIX_ProcessingParams_AddCertChainChecker failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSADDCERTSTOREFAILED,PKIX_ProcessingParams_AddCertStore failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSADDREVMETHODFAILED,PKIX_ProcessingParams_AddRevocationMethod failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSCREATEFAILED,PKIX_ProcessingParams_Create failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED,PKIX_ProcessingParams_GetCertChainCheckers failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETCERTSTORESFAILED,PKIX_ProcessingParams_GetCertStores failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETDATEFAILED,PKIX_ProcessingParams_GetDate failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETHINTCERTSFAILED,PKIX_ProcessingParams_GetHintCerts failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETINITIALPOLICIESFAILED,PKIX_ProcessingParams_GetInitialPolicies failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETNISTREVPOLICYENABLEDFAILED,pkix_ProcessingParams_GetNISTRevocationPolicyEnabled failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETPOLICYQUALIFIERSREJECTEDFAILED,PKIX_ProcessingParams_GetPolicyQualifiersRejected failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETRESOURCELIMITSFAILED,PKIX_ProcessingParams_GetResourceLimits failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED,PKIX_ProcessingParams_GetRevocationChecker failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETREVOCATIONENABLEDFAILED,PKIX_ProcessingParams_GetRevocationEnabled failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED,PKIX_ProcessingParams_GetTargetCertConstraints failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSGETTRUSTANCHORSFAILED,PKIX_ProcessingParams_GetTrustAnchors failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSISANYPOLICYINHIBITEDFAILED,PKIX_ProcessingParams_IsAnyPolicyInhibited failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSISEXPLICITPOLICYREQUIREDFAILED,PKIX_ProcessingParams_IsExplicitPolicyRequired failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSISPOLICYMAPPINGINHIBITEDFAILED,PKIX_ProcessingParams_IsPolicyMappingInhibited failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETANYPOLICYINHIBITED,PKIX_ProcessingParams_SetAnyPolicyInhibited failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETCERTSTORESFAILED,PKIX_ProcessingParams_SetCertStores failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETDATEFAILED,PKIX_ProcessingParams_SetDate failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETEXPLICITPOLICYREQUIRED,PKIX_ProcessingParams_SetExplicitPolicyRequired failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETHINTCERTSFAILED,PKIX_ProcessingParams_SetHintCerts failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETINITIALPOLICIESFAILED,PKIX_ProcessingParams_SetInitialPolicies failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETNISTREVOCATIONENABLEDFAILED,PKIX_ProcessingParams_SetNISTRevocationEnabled failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETPOLICYMAPPINGINHIBITED,PKIX_ProcessingParams_SetPolicyMappingInhibited failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETREVOCATIONCHECKERFAILED,PKIX_ProcessingParams_SetRevocationChecker failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED,PKIX_ProcessingParams_SetTargetCertConstraints failed,0),
-PKIX_ERRORENTRY(PROCESSINGPARAMSSETQUALIFYTARGETCERTFLAGFAILED,ProcessingParams_SetQualifyTargetCertFlag failed,0),
-PKIX_ERRORENTRY(PRPOLLFAILED,PR_Poll failed,0),
-PKIX_ERRORENTRY(PRPOLLRETBADFILENUM,PR_Poll failed,0),
-PKIX_ERRORENTRY(PRRECVFAILED,PR_Recv failed,0),
-PKIX_ERRORENTRY(PRRECVREPORTSNETWORKCONNECTIONCLOSED,PR_Recv reports network connection is closed,0),
-PKIX_ERRORENTRY(PRSENDFAILED,PR_Send failed,0),
-PKIX_ERRORENTRY(PRSHUTDOWNFAILED,PR_Shutdown failed,0),
-PKIX_ERRORENTRY(PRSMPRINTFFAILED,PR_smprintf failed,0),
-PKIX_ERRORENTRY(PRSNPRINTFFAILED,PR_snprintf failed,0),
-PKIX_ERRORENTRY(PUBKEYTYPENULLKEY,pubKeyType is nullKey,0),
-PKIX_ERRORENTRY(PUBLICKEYMAKEINHERITEDDSAPUBLICKEYFAILED,PKIX_PL_PublicKey_MakeInheritedDSAPublicKey failed,0),
-PKIX_ERRORENTRY(PUBLICKEYNEEDSDSAPARAMETERSFAILED,PKIX_PL_PublicKey_NeedsDSAParameters failed,0),
-PKIX_ERRORENTRY(PUBLICKEYTOSTRINGFAILED,PKIX_PL_PublicKey_ToString failed,0),
-PKIX_ERRORENTRY(PUBLICKEYTOSTRINGHELPERFAILED,pkix_pl_PublicKey_ToString_Helper failed,0),
-PKIX_ERRORENTRY(QUALIFIERSINCRITICALCERTIFICATEPOLICYEXTENSION,Qualifiers in critical Certificate Policy extension,0),
-PKIX_ERRORENTRY(REALLOCFAILED,PKIX_PL_Realloc failed,0),
-PKIX_ERRORENTRY(RECEIVEDCORRUPTEDOBJECTARGUMENT,Received corrupted object argument,0),
-PKIX_ERRORENTRY(REGISTERCERTSTOREFAILED,RegisterCertStores failed,0),
-PKIX_ERRORENTRY(REMOVEDUPUNTRUSTEDCERTSFAILED, pkix_Build_RemoveDupUntrustedCerts failed,0),
-PKIX_ERRORENTRY(REQUESTNOTANHTTPDEFAULTCLIENT,request is not an HttpDefaultClient,0),
-PKIX_ERRORENTRY(RESOURCELIMITSGETMAXDEPTHFAILED,PKIX_ResourceLimits_GetMaxDepth failed,0),
-PKIX_ERRORENTRY(RESOURCELIMITSGETMAXFANOUTFAILED,PKIX_ResourceLimits_GetMaxFanout failed,0),
-PKIX_ERRORENTRY(RESOURCELIMITSGETMAXTIMEFAILED,PKIX_ResourceLimits_GetMaxTime failed,0),
-PKIX_ERRORENTRY(RETRIEVEOUTPUTSFAILED,pkix_RetrieveOutputs failed,0),
-PKIX_ERRORENTRY(REVCHECKCERTFAILED,pkix_RevCheckCert failed,0),
-PKIX_ERRORENTRY(REVCHECKERCHECKFAILED,revCheckerCheck failed,0),
-PKIX_ERRORENTRY(REVOCATIONCHECKERADDMETHODFAILED,Can not add revocation method,0),
-PKIX_ERRORENTRY(REVOCATIONCHECKERCREATEFAILED,PKIX_RevocationChecker_Create failed,0),
-PKIX_ERRORENTRY(REVOCATIONCHECKERGETREVCALLBACKFAILED,PKIX_RevocationChecker_GetRevCallback failed,0),
-PKIX_ERRORENTRY(REVOCATIONCHECKERGETREVCHECKERCONTEXTFAILED,PKIX_RevocationChecker_GetRevCheckerContext failed,0),
-PKIX_ERRORENTRY(REVOCATIONCHECKERWASNOTSET,Revocation chekcer was not set,0),
-PKIX_ERRORENTRY(REVOKEDBYUNKNOWNCRLREASONCODE,Revoked by Unknown CRL ReasonCode,0),
-PKIX_ERRORENTRY(SEARCHRESPONSEPACKETOFUNKNOWNTYPE,SearchResponse packet of unknown type,SEC_ERROR_BAD_LDAP_RESPONSE),
-PKIX_ERRORENTRY(SECASN1ENCODEITEMFAILED,SEC_ASN1EncodeItem failed,SEC_ERROR_FAILED_TO_ENCODE_DATA),
-PKIX_ERRORENTRY(SECERRORUNKNOWNISSUER,Nss legacy err code: build failed. Issuer is unknown.,SEC_ERROR_UNKNOWN_ISSUER),
-PKIX_ERRORENTRY(SECKEYCOPYSUBJECTPUBLICKEYINFOFAILED,SECKEY_CopySubjectPublicKeyInfo failed,0),
-PKIX_ERRORENTRY(SECKEYEXTRACTPUBLICKEYFAILED,SECKEY_ExtractPublicKey failed,0),
-PKIX_ERRORENTRY(SECOIDCOPYALGORITHMIDFAILED,SECOID_CopyAlgorithmID failed,0),
-PKIX_ERRORENTRY(SECOIDFINDOIDTAGDESCRIPTIONFAILED,SECOID_FindOIDTag Description failed,0),
-PKIX_ERRORENTRY(SECONDFIELDMUSTBEBETWEEN039,Second field must be between 0-39,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(SECONDKEYDSAPUBLICKEY,Second key is a DSA public key but has null parameters,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(SECONDKEYNOTDSAPUBLICKEY,Second key is not a DSA public key,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(SECONDPUBKEYTYPENULLKEY,secondPubKeyType is nullKey,0),
-PKIX_ERRORENTRY(SECQUICKDERDECODERFAILED,SEC_QuickDERDecodeItem failed,0),
-PKIX_ERRORENTRY(SECREADPKCS7CERTSFAILED,SEC_ReadPKCS7Certs failed,0),
-PKIX_ERRORENTRY(SELECTORMATCHFAILED,selectorMatch failed,0),
-PKIX_ERRORENTRY(SESSIONNOTANHTTPDEFAULTCLIENT,session is not an HttpDefaultClient,0),
-PKIX_ERRORENTRY(SETPOLICIESFAILED,Fail to set cert validation policies,0),
-PKIX_ERRORENTRY(SHUTDOWNFAILED,PKIX_PL_Shutdown failed,0),
-PKIX_ERRORENTRY(SIGNATURECHECKERINITIALIZEFAILED,pkix_SignatureChecker_Initialize failed,0),
-PKIX_ERRORENTRY(SIGNATURECHECKERSTATECREATEFAILED,pkix_SignatureCheckerState_Create failed,0),
-PKIX_ERRORENTRY(SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY,Signature did not verify with the public key,0),
-PKIX_ERRORENTRY(SINGLEPOLICYNODEEQUALSFAILED,PKIX_PL_SinglePolicyNode_Equals failed,0),
-PKIX_ERRORENTRY(SINGLEPOLICYNODEHASHCODEFAILED,pkix_SinglePolicyNode_Hashcode failed,0),
-PKIX_ERRORENTRY(SINGLEPOLICYNODETOSTRINGFAILED,pkix_SinglePolicyNode_ToString failed,0),
-PKIX_ERRORENTRY(SINGLEVERIFYNODEEQUALSFAILED,PKIX_PL_SingleVerifyNode_Equals failed,0),
-PKIX_ERRORENTRY(SINGLEVERIFYNODEHASHCODEFAILED,pkix_SingleVerifyNode_Hashcode failed,0),
-PKIX_ERRORENTRY(SOCKETCONNECTCONTINUEFAILED,pkix_pl_Socket_ConnectContinue failed,0),
-PKIX_ERRORENTRY(SOCKETCONNECTFAILED,pkix_pl_Socket_Connect failed,0),
-PKIX_ERRORENTRY(SOCKETCREATEBYHOSTANDPORTFAILED,pkix_pl_Socket_CreateByHostAndPort failed,0),
-PKIX_ERRORENTRY(SOCKETCREATEBYNAMEFAILED,pkix_pl_Socket_CreateByName failed,0),
-PKIX_ERRORENTRY(SOCKETCREATECLIENTFAILED,pkix_pl_Socket_CreateClient failed,0),
-PKIX_ERRORENTRY(SOCKETCREATEFAILED,pkix_pl_Socket_Create failed,0),
-PKIX_ERRORENTRY(SOCKETCREATESERVERFAILED,pkix_pl_Socket_CreateServer failed,0),
-PKIX_ERRORENTRY(SOCKETEQUALSFAILED,PKIX_PL_Socket_Equals failed,0),
-PKIX_ERRORENTRY(SOCKETGETCALLBACKLISTFAILED,pkix_pl_Socket_GetCallbackList failed,0),
-PKIX_ERRORENTRY(SOCKETGETPRFILEDESCFAILED,pkix_pl_Socket_GetPRFileDesc failed,0),
-PKIX_ERRORENTRY(SOCKETHASHCODEFAILED,PKIX_PL_Socket_Hashcode failed,0),
-PKIX_ERRORENTRY(SOCKETPOLLFAILED,pkix_pl_Socket_Poll failed,0),
-PKIX_ERRORENTRY(SOCKETRECVFAILED,pkix_pl_Socket_Recv failed,0),
-PKIX_ERRORENTRY(SOCKETSENDFAILED,pkix_pl_Socket_Send failed,0),
-PKIX_ERRORENTRY(SOCKETSETNONBLOCKINGFAILED,pkix_pl_Socket_SetNonBlocking failed,0),
-PKIX_ERRORENTRY(SOURCESTRINGHASINVALIDLENGTH,Source string has invalid length,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(SPRINTFFAILED,PKIX_PL_Sprintf failed,0),
-PKIX_ERRORENTRY(STRINGCOMPARATORFAILED,pkix_pl_String_Comparator failed,0),
-PKIX_ERRORENTRY(STRINGCREATEFAILED,PKIX_PL_String_Create failed,0),
-PKIX_ERRORENTRY(STRINGEQUALSFAILED,pkix_pl_String_Equals failed,0),
-PKIX_ERRORENTRY(STRINGGETENCODEDFAILED,PKIX_PL_String_GetEncoded failed,0),
-PKIX_ERRORENTRY(STRINGHASHCODEFAILED,pkix_pl_String_Hashcode failed,0),
-PKIX_ERRORENTRY(SUBJALTNAMECHECKFAILED,Validation failed: SubjAltNamecheck failed,0),
-PKIX_ERRORENTRY(TARGETCERTCHECKERINITIALIZEFAILED,pkix_TargetCertChecker_Initialize failed,0),
-PKIX_ERRORENTRY(TARGETCERTCHECKERSTATECREATEFAILED,pkix_TargetCertCheckerState_Create failed,0),
-PKIX_ERRORENTRY(TESTANOTHERERRORMESSAGE, Another Error Message,0),
-PKIX_ERRORENTRY(TESTERRORMESSAGE, Error Message,0),
-PKIX_ERRORENTRY(TESTNOMATCHINGPOLICY, No Matching Policy,0),
-PKIX_ERRORENTRY(TESTNOTANERRORCRLSELECTMISMATCH, Not an error CRL Select mismatch,0),
-PKIX_ERRORENTRY(TESTPOLICYEXTWITHNOPOLICYQUALIFIERS, Policies extension but no Policy Qualifiers,0),
-PKIX_ERRORENTRY(TIMECONSUMEDEXCEEDSRESOURCELIMITS,Time consumed exceeds Resource Limits,SEC_ERROR_OUT_OF_SEARCH_LIMITS),
-PKIX_ERRORENTRY(TOOLITTLEDATAINDERSEQUENCE,Too little data in DER Sequence,0),
-PKIX_ERRORENTRY(TOOMUCHDATAINDERSEQUENCE,Too much data in DER Sequence,0),
-PKIX_ERRORENTRY(TOSTRINGFORTHISGENERALNAMETYPENOTSUPPORTED,ToString for this GeneralName type not supported,0),
-PKIX_ERRORENTRY(TRUNCATEDUNICODEINESCAPEDASCII,Truncated Unicode in EscapedASCII,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(TRUSTANCHORCREATEWITHCERTFAILED,PKIX_TrustAnchor_CreateWithCert failed,0),
-PKIX_ERRORENTRY(TRUSTANCHORGETCANAMEFAILED,PKIX_TrustAnchor_GetCAName failed,0),
-PKIX_ERRORENTRY(TRUSTANCHORGETCAPUBLICKEYFAILED,PKIX_TrustAnchor_GetCAPublicKey failed,0),
-PKIX_ERRORENTRY(TRUSTANCHORGETNAMECONSTRAINTSFAILED,PKIX_TrustAnchor_GetNameConstraints failed,0),
-PKIX_ERRORENTRY(TRUSTANCHORGETTRUSTEDCERTFAILED,PKIX_TrustAnchor_GetTrustedCert failed,0),
-PKIX_ERRORENTRY(TRUSTANCHORTOCERTFAILED,Fail to convert trust anchor to cert,0),
-PKIX_ERRORENTRY(TYPEALREADYREGISTERED,Type is already registered,0),
-PKIX_ERRORENTRY(UNABLETOADDACCEPTABLERESPONSESTOREQUEST,Unable to add acceptableResponses to request,0),
-PKIX_ERRORENTRY(UNABLETOADDCERTTOCERTLIST,Unable to add Cert to CertList,0),
-PKIX_ERRORENTRY(UNABLETOBUILDCHAIN,Unable to build chain,0),
-PKIX_ERRORENTRY(UNABLETOCREATECERTOCSPREQUEST,Unable to create a CertOCSPRequest,0),
-PKIX_ERRORENTRY(UNABLETOCREATECRLSTRING,Unable to create crlString,0),
-PKIX_ERRORENTRY(UNABLETOCREATEGENERALNAMEOFTHISTYPE,Unable to create GeneralName of this type,0),
-PKIX_ERRORENTRY(UNABLETOCREATEISSUER,Unable to create Issuer,0),
-PKIX_ERRORENTRY(UNABLETOCREATELIST,Unable to create list,0),
-PKIX_ERRORENTRY(UNABLETOCREATENEWCERTLIST,Unable to create a new CertList,0),
-PKIX_ERRORENTRY(UNABLETOCREATEPSTRING,Unable to create pString,0),
-PKIX_ERRORENTRY(UNABLETOFINDSTATUSINOCSPRESPONSE,Unable to find status in OCSP response,SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS),
-PKIX_ERRORENTRY(UNABLETOMAKELISTIMMUTABLE,Unable to make list immutable,0),
-PKIX_ERRORENTRY(UNABLETOOPENCERTFILE,Unable to open cert file,0),
-PKIX_ERRORENTRY(UNABLETOOPENCRLFILE,Unable to open crl file,0),
-PKIX_ERRORENTRY(UNABLETOPARSEOCSPRESPONSE,Unable to parse OCSP response,SEC_ERROR_OCSP_MALFORMED_RESPONSE),
-PKIX_ERRORENTRY(UNABLETOREADDERFROMCERTFILE,Unable to read DER from cert file,0),
-PKIX_ERRORENTRY(UNABLETOREADDERFROMCRLFILE,Unable to read DER from crl file,0),
-PKIX_ERRORENTRY(UNABLETOSETSOCKETTONONBLOCKING,Unable to set socket to non-blocking I/O,0),
-PKIX_ERRORENTRY(UNDEFINEDCALLBACK,Undefined callback,0),
-PKIX_ERRORENTRY(UNDEFINEDCLASSTABLEENTRY,Undefined class table entry,0),
-PKIX_ERRORENTRY(UNDEFINEDCOMPARATOR,Undefined Comparator,0),
-PKIX_ERRORENTRY(UNDEFINEDDUPLICATEFUNCTION,Undefined Duplicate function,0),
-PKIX_ERRORENTRY(UNDEFINEDEQUALSCALLBACK,Undefined equals callback,0),
-PKIX_ERRORENTRY(UNEXPECTEDERRORINESTABLISHINGCONNECTION,Unexpected error in establishing connection,0),
-PKIX_ERRORENTRY(UNEXPECTEDRESULTCODEINRESPONSE,Unexpected result code in Response,SEC_ERROR_BAD_LDAP_RESPONSE),
-PKIX_ERRORENTRY(UNKNOWNFORMAT,Unknown format,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(UNKNOWNINFOACCESSMETHOD,Unknown InfoAccess method,SEC_ERROR_BAD_INFO_ACCESS_METHOD),
-PKIX_ERRORENTRY(UNKNOWNOBJECTOID,Unknown object OID,0),
-PKIX_ERRORENTRY(UNKNOWNOBJECTTYPE,Unknown object type,0),
-PKIX_ERRORENTRY(UNKNOWNTYPEARGUMENT,Unknown type argument,0),
-PKIX_ERRORENTRY(UNLOCKOBJECTFAILED,pkix_UnlockObject failed,0),
-PKIX_ERRORENTRY(UNRECOGNIZEDCRITICALEXTENSION,Unrecognized Critical Extension,SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION),
-PKIX_ERRORENTRY(UNRECOGNIZEDCRLENTRYCRITICALEXTENSION,Unrecognized CRLEntry Critical Extension,SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION),
-PKIX_ERRORENTRY(UNRECOGNIZEDPROTOCOLREQUESTED,Unrecognized protocol requested,0),
-PKIX_ERRORENTRY(UNRECOGNIZEDREQUESTMETHOD,Unrecognized request method,0),
-PKIX_ERRORENTRY(UNRECOGNIZEDTIMETYPE,Unrecognized time type,0),
-PKIX_ERRORENTRY(UNSUPPORTEDCRLDPTYPE,CrlDp type is not supported,0),
-PKIX_ERRORENTRY(UNSUPPORTEDVERSIONOFHTTPCLIENT,Unsupported version of Http Client,0),
-PKIX_ERRORENTRY(UNSUPPORTEDCERTUSAGE,Specified certificate usage is unsupported,SEC_ERROR_CERT_USAGES_INVALID),
-PKIX_ERRORENTRY(URLPARSINGFAILED,URL Parsing failed,0),
-PKIX_ERRORENTRY(USERCHECKERCHECKFAILED,userCheckerCheck failed,0),
-PKIX_ERRORENTRY(UTF16ALIGNMENTERROR,UTF16 Alignment Error,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(UTF16HIGHZONEALIGNMENTERROR,UTF16 High Zone Alignment Error,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(UTF16LOWZONEERROR,UTF16 Low Zone Error,SEC_ERROR_INVALID_ARGS),
-PKIX_ERRORENTRY(UTF16TOESCASCIIFAILED,pkix_UTF16_to_EscASCII failed,0),
-PKIX_ERRORENTRY(UTF16TOUTF8FAILED,pkix_UTF16_to_UTF8 failed,0),
-PKIX_ERRORENTRY(UTF8TOUTF16FAILED,pkix_UTF8_to_UTF16 failed,0),
-PKIX_ERRORENTRY(VALIDATEBUILDUSEROIDSFAILED,pkix_Validate_BuildUserOIDs failed,0),
-PKIX_ERRORENTRY(VALIDATECERTCHAINFAILED,Failed to validate cert chain,0),
-PKIX_ERRORENTRY(VALIDATECHAINFAILED,PKIX_ValidateChain failed,0),
-PKIX_ERRORENTRY(VALIDATEPARAMSGETCERTCHAINFAILED,PKIX_ValidateParams_GetCertChain failed,0),
-PKIX_ERRORENTRY(VALIDATEPARAMSGETPROCESSINGPARAMSFAILED,PKIX_ValidateParams_GetProcessingParams failed,0),
-PKIX_ERRORENTRY(VALIDATERESULTCREATEFAILED,pkix_ValidateResult_Create failed,0),
-PKIX_ERRORENTRY(VALIDATERESULTGETPOLICYTREEFAILED,PKIX_ValidateResult_GetPolicyTree failed,0),
-PKIX_ERRORENTRY(VALIDATERESULTGETTRUSTANCHORFAILED,PKIX_ValidateResult_GetTrustAnchor failed,0),
-PKIX_ERRORENTRY(VALIDATIONFAILEDCERTSIGNATURECHECKING,Validation failed: Cert Signature checking,0),
-PKIX_ERRORENTRY(VALIDATIONFAILEDNULLCERTPOINTER,Validation failed: NULL Cert pointer,0),
-PKIX_ERRORENTRY(VALIDATIONFAILEDPATHTONAMECHECKFAILED,Validation failed: PathToName check failed,SEC_ERROR_CERT_NOT_IN_NAME_SPACE),
-PKIX_ERRORENTRY(VALUEINESCAPEDASCII,value in EscapedASCII,0),
-PKIX_ERRORENTRY(VERIFYNODEADDTOCHAINFAILED,pkix_VerifyNode_AddToChain failed,0),
-PKIX_ERRORENTRY(VERIFYNODEADDTOTREEFAILED,pkix_VerifyNode_AddToTree failed,0),
-PKIX_ERRORENTRY(VERIFYNODECREATEFAILED,pkix_VerifyNode_Create failed,0),
-PKIX_ERRORENTRY(VERIFYNODEDUPLICATEHELPERFAILED,pkix_VerifyNode_DuplicateHelper failed,0),
-PKIX_ERRORENTRY(VERIFYNODEFINDERRORFAILED,pkix_VerifyNode_FindError failed,0),
-PKIX_ERRORENTRY(VERIFYNODESETDEPTHFAILED,pkix_VerifyNode_SetDepth failed,0),
-PKIX_ERRORENTRY(VERIFYNODESETERRORFAILED,pkix_VerifyNode_SetError failed,0),
-PKIX_ERRORENTRY(VERSIONVALUEMUSTBEV1ORV2,Version value must be V1(0) or V2(1),SEC_ERROR_CRL_INVALID),
-PKIX_ERRORENTRY(VERSIONVALUEMUSTBEV1V2ORV3,Version value must be v1(0) v2(1) or v3(2),SEC_ERROR_CERT_VALID),
-PKIX_ERRORENTRY(X500NAMECOMPAREDERBYTESFAILED,pkix_pl_X500Name_CompareDERBytes failed,0),
-PKIX_ERRORENTRY(X500NAMECREATEFAILED,PKIX_PL_X500Name_Create failed,0),
-PKIX_ERRORENTRY(X500NAMECREATEFROMCERTNAMEFAILED,pkix_pl_X500Name_CreateFromCERTName failed,0),
-PKIX_ERRORENTRY(X500NAMECREATEFROMUTF8FAILED,pkix_pl_X500Name_CreateFromUtf8 failed,0),
-PKIX_ERRORENTRY(X500NAMEEQUALSFAILED,PKIX_PL_X500Name_Equals failed,0),
-PKIX_ERRORENTRY(X500NAMEGETCOMMONNAMEFAILED,pkix_pl_X500Name_GetCommonName failed,0),
-PKIX_ERRORENTRY(X500NAMEGETCOUNTRYNAMEFAILED,pkix_pl_X500Name_GetCountryName failed,0),
-PKIX_ERRORENTRY(X500NAMEGETORGNAMEFAILED,pkix_pl_X500Name_GetOrgName failed,0),
-PKIX_ERRORENTRY(X500NAMEGETSECNAMEFAILED,pkix_pl_X500Name_GetSECName failed,0),
-PKIX_ERRORENTRY(X500NAMEHASHCODEFAILED,PKIX_PL_X500Name_Hashcode failed,0),
-PKIX_ERRORENTRY(X500NAMEMATCHFAILED,PKIX_PL_X500Name_Match failed,0),
-PKIX_ERRORENTRY(X500NAMETOSTRINGFAILED,PKIX_PL_X500Name_ToString failed,0),
-PKIX_ERRORENTRY(X500NAMETOSTRINGHELPERFAILED,pkix_pl_X500Name_ToString_Helper failed,0),
-PKIX_ERRORENTRY(ZEROLENGTHBYTEARRAYFORCRLENCODING,Zero-length ByteArray for CRL encoding,0)
diff --git a/security/nss/lib/libpkix/include/pkix_params.h b/security/nss/lib/libpkix/include/pkix_params.h
deleted file mode 100755
index a4d8e485c..000000000
--- a/security/nss/lib/libpkix/include/pkix_params.h
+++ /dev/null
@@ -1,1793 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines functions associated with the various parameters used
- * by the top-level functions.
- *
- */
-
-#ifndef _PKIX_PARAMS_H
-#define _PKIX_PARAMS_H
-
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/* PKIX_ProcessingParams
- *
- * PKIX_ProcessingParams are parameters used when validating or building a
- * chain of certificates. Using the parameters, the caller can specify several
- * things, including the various inputs to the PKIX chain validation
- * algorithm (such as trust anchors, initial policies, etc), any customized
- * functionality (such as CertChainCheckers, RevocationCheckers, CertStores),
- * and whether revocation checking should be disabled.
- *
- * Once the caller has created the ProcessingParams object, the caller then
- * passes it to PKIX_ValidateChain or PKIX_BuildChain, which uses it to call
- * the user's callback functions as needed during the validation or building
- * process.
- *
- * If a parameter is not set (or is set to NULL), it will be set to the
- * default value for that parameter. The default value for the Date parameter
- * is NULL, which indicates the current time when the path is validated. The
- * default for the remaining parameters is the least constrained.
- */
-
-/*
- * FUNCTION: PKIX_ProcessingParams_Create
- * DESCRIPTION:
- *
- * Creates a new ProcessingParams object. Trust anchor list is set to
- * newly created empty list of trust. In this case trust anchors will
- * be taken from provided cert store. Pointed to the created
- * ProcessingParams object is stored in "pParams".
- *
- * PARAMETERS:
- * "anchors"
- * Address of List of (non-empty) TrustAnchors to be used.
- * Must be non-NULL.
- * "pParams"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_Create(
- PKIX_ProcessingParams **pParams,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetCertChainCheckers
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of CertChainCheckers (if any) that are set
- * in the ProcessingParams pointed to by "params" and stores it at
- * "pCheckers". Each CertChainChecker represents a custom certificate
- * validation check used by PKIX_ValidateChain or PKIX_BuildChain as needed
- * during the validation or building process. If "params" does not have any
- * CertChainCheckers, this function stores an empty List at "pCheckers".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of CertChainCheckers (if any)
- * are to be stored. Must be non-NULL.
- * "pCheckers"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetCertChainCheckers(
- PKIX_ProcessingParams *params,
- PKIX_List **pCheckers, /* list of PKIX_CertChainChecker */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetCertChainCheckers
- * DESCRIPTION:
- *
- * Sets the ProcessingParams pointed to by "params" with a List of
- * CertChainCheckers pointed to by "checkers". Each CertChainChecker
- * represents a custom certificate validation check used by
- * PKIX_ValidateChain or PKIX_BuildChain as needed during the validation or
- * building process. If "checkers" is NULL, no CertChainCheckers will be used.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of CertChainCheckers is to be
- * set. Must be non-NULL.
- * "checkers"
- * Address of List of CertChainCheckers to be set. If NULL, no
- * CertChainCheckers will be used.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params" and "checkers"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetCertChainCheckers(
- PKIX_ProcessingParams *params,
- PKIX_List *checkers, /* list of PKIX_CertChainChecker */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_AddCertChainChecker
- * DESCRIPTION:
- *
- * Adds the CertChainChecker pointed to by "checker" to the ProcessingParams
- * pointed to by "params". The CertChainChecker represents a custom
- * certificate validation check used by PKIX_ValidateChain or PKIX_BuildChain
- * as needed during the validation or building process.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams to be added to. Must be non-NULL.
- * "checker"
- * Address of CertChainChecker to be added. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_AddCertChainChecker(
- PKIX_ProcessingParams *params,
- PKIX_CertChainChecker *checker,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetRevocationChecker
- * DESCRIPTION:
- *
- * Retrieves a pointer to the RevocationChecker that are set
- * in the ProcessingParams pointed to by "params" and stores it at
- * "pRevChecker". Each RevocationChecker represents a revocation
- * check used by PKIX_ValidateChain or PKIX_BuildChain as needed during the
- * validation or building process. If "params" does not have any
- * RevocationCheckers, this function stores an empty List at "pRevChecker".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of RevocationCheckers
- * is to be stored. Must be non-NULL.
- * "pRevChecker"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetRevocationChecker(
- PKIX_ProcessingParams *params,
- PKIX_RevocationChecker **pChecker,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetRevocationChecker
- * DESCRIPTION:
- *
- * Sets the ProcessingParams pointed to by "params" with a
- * RevocationChecker pointed to by "revChecker". Revocation
- * checker object should be created and assigned to processing
- * parameters before chain build or validation can begin.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of RevocationCheckers is to be
- * set. Must be non-NULL.
- * "revChecker"
- * Address of RevocationChecker to be set. Must be set before chain
- * building or validation.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetRevocationChecker(
- PKIX_ProcessingParams *params,
- PKIX_RevocationChecker *revChecker,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetCertStores
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of CertStores (if any) that are set in the
- * ProcessingParams pointed to by "params" and stores it at "pStores". Each
- * CertStore represents a particular repository from which certificates and
- * CRLs can be retrieved by PKIX_ValidateChain or PKIX_BuildChain as needed
- * during the validation or building process. If "params" does not have any
- * CertStores, this function stores an empty List at "pStores".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of CertStores (if any) are to
- * be stored. Must be non-NULL.
- * "pStores"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetCertStores(
- PKIX_ProcessingParams *params,
- PKIX_List **pStores, /* list of PKIX_CertStore */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetCertStores
- * DESCRIPTION:
- *
- * Sets the ProcessingParams pointed to by "params" with a List of CertStores
- * pointed to by "stores". Each CertStore represents a particular repository
- * from which certificates and CRLs can be retrieved by PKIX_ValidateChain or
- * PKIX_BuildChain as needed during the validation or building process. If
- * "stores" is NULL, no CertStores will be used.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of CertStores is to be set.
- * Must be non-NULL.
- * "stores"
- * Address of List of CertStores to be set. If NULL, no CertStores will
- * be used.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetCertStores(
- PKIX_ProcessingParams *params,
- PKIX_List *stores, /* list of PKIX_CertStore */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_AddCertStore
- * DESCRIPTION:
- *
- * Adds the CertStore pointed to by "store" to the ProcessingParams pointed
- * to by "params". The CertStore represents a particular repository from
- * which certificates and CRLs can be retrieved by PKIX_ValidateChain or
- * PKIX_BuildChain as needed during the validation or building process.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams to be added to. Must be non-NULL.
- * "store"
- * Address of CertStore to be added.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_AddCertStore(
- PKIX_ProcessingParams *params,
- PKIX_CertStore *store,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetDate
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Date (if any) that is set in the
- * ProcessingParams pointed to by "params" and stores it at "pDate". The
- * Date represents the time for which the validation of the certificate chain
- * should be determined. If "params" does not have any Date set, this function
- * stores NULL at "pDate".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose Date (if any) is to be stored.
- * Must be non-NULL.
- * "pDate"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetDate(
- PKIX_ProcessingParams *params,
- PKIX_PL_Date **pDate,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetDate
- * DESCRIPTION:
- *
- * Sets the ProcessingParams pointed to by "params" with a Date pointed to by
- * "date". The Date represents the time for which the validation of the
- * certificate chain should be determined. If "date" is NULL, the current
- * time is used during validation.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose Date is to be set. Must be non-NULL.
- * "date"
- * Address of Date to be set. If NULL, current time is used.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetDate(
- PKIX_ProcessingParams *params,
- PKIX_PL_Date *date,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetInitialPolicies
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of OIDs (if any) that are set in the
- * ProcessingParams pointed to by "params" and stores it at "pInitPolicies".
- * Each OID represents an initial policy identifier, indicating that any
- * one of these policies would be acceptable to the certificate user for
- * the purposes of certification path processing. If "params" does not have
- * any initial policies, this function stores an empty List at
- * "pInitPolicies".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of OIDs (if any) are to be
- * stored. Must be non-NULL.
- * "pInitPolicies"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetInitialPolicies(
- PKIX_ProcessingParams *params,
- PKIX_List **pInitPolicies, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetInitialPolicies
- * DESCRIPTION:
- *
- * Sets the ProcessingParams pointed to by "params" with a List of OIDs
- * pointed to by "initPolicies".
- *
- * Each OID represents an initial policy identifier, indicating that any
- * one of these policies would be acceptable to the certificate user for
- * the purposes of certification path processing. By default, any policy
- * is acceptable (i.e. all policies), so a user that wants to allow any
- * policy as acceptable does not need to call this method. Similarly, if
- * initPolicies is NULL or points to an empty List, all policies are
- * acceptable.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of OIDs is to be set.
- * Must be non-NULL.
- * "initPolicies"
- * Address of List of OIDs to be set. If NULL or if pointing to an empty
- * List, all policies are acceptable.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetInitialPolicies(
- PKIX_ProcessingParams *params,
- PKIX_List *initPolicies, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetPolicyQualifiersRejected
- * DESCRIPTION:
- *
- * Checks whether the ProcessingParams pointed to by "params" indicate that
- * policy qualifiers should be rejected and stores the Boolean result at
- * "pRejected".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams used to determine whether or not policy
- * qualifiers should be rejected. Must be non-NULL.
- * "pRejected"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetPolicyQualifiersRejected(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pRejected,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetPolicyQualifiersRejected
- * DESCRIPTION:
- *
- * Specifies in the ProcessingParams pointed to by "params" whether policy
- * qualifiers are rejected using the Boolean value of "rejected".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams to be set. Must be non-NULL.
- * "rejected"
- * Boolean value indicating whether policy qualifiers are to be rejected.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetPolicyQualifiersRejected(
- PKIX_ProcessingParams *params,
- PKIX_Boolean rejected,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetTargetCertConstraints
- * DESCRIPTION:
- *
- * Retrieves a pointer to the CertSelector (if any) that is set in the
- * ProcessingParams pointed to by "params" and stores it at "pConstraints".
- * The CertSelector represents the constraints to be placed on the target
- * certificate. If "params" does not have any CertSelector set, this function
- * stores NULL at "pConstraints".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose CertSelector (if any) is to be
- * stored. Must be non-NULL.
- * "pConstraints"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetTargetCertConstraints(
- PKIX_ProcessingParams *params,
- PKIX_CertSelector **pConstraints,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetTargetCertConstraints
- * DESCRIPTION:
- *
- * Sets the ProcessingParams pointed to by "params" with a CertSelector
- * pointed to by "constraints". The CertSelector represents the constraints
- * to be placed on the target certificate. If "constraints" is NULL, no
- * constraints are defined.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose CertSelector is to be set.
- * Must be non-NULL.
- * "constraints"
- * Address of CertSelector to be set. If NULL, no constraints are defined.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetTargetCertConstraints(
- PKIX_ProcessingParams *params,
- PKIX_CertSelector *constraints,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetTrustAnchors
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of TrustAnchors that are set in
- * the ProcessingParams pointed to by "params" and stores it at "pAnchors".
- * If the function succeeds, the pointer to the List is guaranteed to be
- * non-NULL and the List is guaranteed to be non-empty.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of TrustAnchors are to
- * be stored. Must be non-NULL.
- * "pAnchors"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetTrustAnchors(
- PKIX_ProcessingParams *params,
- PKIX_List **pAnchors, /* list of TrustAnchor */
- void *plContext);
-/*
- * FUNCTION: PKIX_ProcessingParams_SetTrustAnchors
- * DESCRIPTION:
- *
- * Sets user defined set of trust anchors. The handling of the trust anchors
- * may be furthered alter via PKIX_ProcessingParams_SetUseOnlyTrustAnchors.
- * By default, a certificate will be considered invalid if it does not chain
- * to a trusted anchor from this list.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of TrustAnchors are to
- * be stored. Must be non-NULL.
- * "anchors"
- * Address of the trust anchors list object. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetTrustAnchors(
- PKIX_ProcessingParams *params,
- PKIX_List *pAnchors, /* list of TrustAnchor */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetUseOnlyTrustAnchors
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Boolean. The boolean value represents
- * the switch value that is used to identify whether trust anchors, if
- * specified, should be the exclusive source of trust information.
- * If the function succeeds, the pointer to the Boolean is guaranteed to be
- * non-NULL.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams. Must be non-NULL.
- * "pUseOnlyTrustAnchors"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetUseOnlyTrustAnchors(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pUseOnlyTrustAnchors,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetUseOnlyTrustAnchors
- * DESCRIPTION:
- *
- * Configures whether trust anchors are used as the exclusive source of trust.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams. Must be non-NULL.
- * "useOnlyTrustAnchors"
- * If true, indicates that trust anchors should be used exclusively when
- * they have been specified via PKIX_ProcessingParams_SetTrustAnchors. A
- * certificate will be considered invalid if it does not chain to a
- * trusted anchor from that list.
- * If false, indicates that the trust anchors are additive to whatever
- * existing trust stores are configured. A certificate is considered
- * valid if it chains to EITHER a trusted anchor from that list OR a
- * certificate marked trusted in a trust store.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetUseOnlyTrustAnchors(
- PKIX_ProcessingParams *params,
- PKIX_Boolean useOnlyTrustAnchors,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetUseAIAForCertFetching
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Boolean. The boolean value represents
- * the switch value that is used to identify if url in cert AIA extension
- * may be used for cert fetching.
- * If the function succeeds, the pointer to the Boolean is guaranteed to be
- * non-NULL.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams. Must be non-NULL.
- * "pUseAIA"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetUseAIAForCertFetching(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pUseAIA, /* list of TrustAnchor */
- void *plContext);
-/*
- * FUNCTION: PKIX_ProcessingParams_SetTrustAnchors
- * DESCRIPTION:
- *
- * Sets switch value that defines if url in cert AIA extension
- * may be used for cert fetching.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams.
- * "useAIA"
- * Address of the trust anchors list object. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetUseAIAForCertFetching(
- PKIX_ProcessingParams *params,
- PKIX_Boolean useAIA,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetQualifyTargetCert
- * DESCRIPTION:
- *
- * Sets a boolean value that tells if libpkix needs to check that
- * the target certificate satisfies the conditions set in processing
- * parameters. Includes but not limited to date, ku and eku checks.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of TrustAnchors are to
- * be stored. Must be non-NULL.
- * "qualifyTargetCert"
- * boolean value if set to true will trigger qualification of the
- * target certificate.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetQualifyTargetCert(
- PKIX_ProcessingParams *params,
- PKIX_Boolean qualifyTargetCert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetHintCerts
- * DESCRIPTION:
- *
- * Retrieves a pointer to a List of Certs supplied by the user as a suggested
- * partial CertChain (subject to verification), that are set in the
- * ProcessingParams pointed to by "params", and stores it at "pHintCerts".
- * The List returned may be empty or NULL.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of TrustAnchors are to
- * be stored. Must be non-NULL.
- * "pHintCerts"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetHintCerts(
- PKIX_ProcessingParams *params,
- PKIX_List **pHintCerts,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetHintCerts
- * DESCRIPTION:
- *
- * Stores a pointer to a List of Certs supplied by the user as a suggested
- * partial CertChain (subject to verification), as an element in the
- * ProcessingParams pointed to by "params". The List may be empty or NULL.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose List of HintCerts is to be stored.
- * Must be non-NULL.
- * "hintCerts"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetHintCerts(
- PKIX_ProcessingParams *params,
- PKIX_List *hintCerts,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetResourceLimits
- * DESCRIPTION:
- *
- * Retrieves a pointer to the ResourceLimits (if any) that is set in the
- * ProcessingParams pointed to by "params" and stores it at "pResourceLimits".
- * The ResourceLimits represent the maximum resource usage that the caller
- * desires (such as MaxTime). The ValidateChain or BuildChain call will not
- * exceed these maximum limits. If "params" does not have any ResourceLimits
- * set, this function stores NULL at "pResourceLimits".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose ResourceLimits (if any) are to be
- * stored. Must be non-NULL.
- * "pResourceLimits"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetResourceLimits(
- PKIX_ProcessingParams *params,
- PKIX_ResourceLimits **pResourceLimits,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetResourceLimits
- * DESCRIPTION:
- *
- * Sets the ProcessingParams pointed to by "params" with a ResourceLimits
- * object pointed to by "resourceLimits". The ResourceLimits represent the
- * maximum resource usage that the caller desires (such as MaxTime). The
- * ValidateChain or BuildChain call will not exceed these maximum limits.
- * If "resourceLimits" is NULL, no ResourceLimits are defined.
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams whose ResourceLimits are to be set.
- * Must be non-NULL.
- * "resourceLimits"
- * Address of ResourceLimits to be set. If NULL, no limits are defined.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetResourceLimits(
- PKIX_ProcessingParams *params,
- PKIX_ResourceLimits *resourceLimits,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_IsAnyPolicyInhibited
- * DESCRIPTION:
- *
- * Checks whether the ProcessingParams pointed to by "params" indicate that
- * anyPolicy is inhibited and stores the Boolean result at "pInhibited".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams used to determine whether or not anyPolicy
- * inhibited. Must be non-NULL.
- * "pInhibited"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_IsAnyPolicyInhibited(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pInhibited,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetAnyPolicyInhibited
- * DESCRIPTION:
- *
- * Specifies in the ProcessingParams pointed to by "params" whether anyPolicy
- * is inhibited using the Boolean value of "inhibited".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams to be set. Must be non-NULL.
- * "inhibited"
- * Boolean value indicating whether anyPolicy is to be inhibited.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetAnyPolicyInhibited(
- PKIX_ProcessingParams *params,
- PKIX_Boolean inhibited,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_IsExplicitPolicyRequired
- * DESCRIPTION:
- *
- * Checks whether the ProcessingParams pointed to by "params" indicate that
- * explicit policies are required and stores the Boolean result at
- * "pRequired".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams used to determine whether or not explicit
- * policies are required. Must be non-NULL.
- * "pRequired"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_IsExplicitPolicyRequired(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pRequired,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetExplicitPolicyRequired
- * DESCRIPTION:
- *
- * Specifies in the ProcessingParams pointed to by "params" whether explicit
- * policies are required using the Boolean value of "required".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams to be set. Must be non-NULL.
- * "required"
- * Boolean value indicating whether explicit policies are to be required.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetExplicitPolicyRequired(
- PKIX_ProcessingParams *params,
- PKIX_Boolean required,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_IsPolicyMappingInhibited
- * DESCRIPTION:
- *
- * Checks whether the ProcessingParams pointed to by "params" indicate that
- * policyMapping is inhibited and stores the Boolean result at "pInhibited".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams used to determine whether or not policy
- * mappings are inhibited. Must be non-NULL.
- * "pInhibited"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_IsPolicyMappingInhibited(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pInhibited,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetPolicyMappingInhibited
- * DESCRIPTION:
- *
- * Specifies in the ProcessingParams pointed to by "params" whether policy
- * mapping is inhibited using the Boolean value of "inhibited".
- *
- * PARAMETERS:
- * "params"
- * Address of ProcessingParams to be set. Must be non-NULL.
- * "inhibited"
- * Boolean value indicating whether policy mapping is to be inhibited.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetPolicyMappingInhibited(
- PKIX_ProcessingParams *params,
- PKIX_Boolean inhibited,
- void *plContext);
-
-
-/* PKIX_ValidateParams
- *
- * PKIX_ValidateParams consists of a ProcessingParams object as well as the
- * List of Certs (certChain) that the caller is trying to validate.
- */
-
-/*
- * FUNCTION: PKIX_ValidateParams_Create
- * DESCRIPTION:
- *
- * Creates a new ValidateParams object and stores it at "pParams".
- *
- * PARAMETERS:
- * "procParams"
- * Address of ProcessingParams to be used. Must be non-NULL.
- * "chain"
- * Address of List of Certs (certChain) to be validated. Must be non-NULL.
- * "pParams"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ValidateParams_Create(
- PKIX_ProcessingParams *procParams,
- PKIX_List *chain,
- PKIX_ValidateParams **pParams,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ValidateParams_GetProcessingParams
- * DESCRIPTION:
- *
- * Retrieves a pointer to the ProcessingParams that represent the basic
- * certificate processing parameters used during chain validation and chain
- * building from the ValidateParams pointed to by "valParams" and stores it
- * at "pProcParams". If the function succeeds, the pointer to the
- * ProcessingParams is guaranteed to be non-NULL.
- *
- * PARAMETERS:
- * "valParams"
- * Address of ValidateParams whose ProcessingParams are to be stored.
- * Must be non-NULL.
- * "pProcParams"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ValidateParams_GetProcessingParams(
- PKIX_ValidateParams *valParams,
- PKIX_ProcessingParams **pProcParams,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ValidateParams_GetCertChain
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of Certs (certChain) that is set in the
- * ValidateParams pointed to by "valParams" and stores it at "pChain". If the
- * function succeeds, the pointer to the CertChain is guaranteed to be
- * non-NULL.
- *
- * PARAMETERS:
- * "valParams"
- * Address of ValidateParams whose CertChain is to be stored.
- * Must be non-NULL.
- * "pChain"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ValidateParams_GetCertChain(
- PKIX_ValidateParams *valParams,
- PKIX_List **pChain,
- void *plContext);
-
-/* PKIX_TrustAnchor
- *
- * A PKIX_TrustAnchor represents a trusted entity and can be specified using a
- * self-signed certificate or using the trusted CA's name and public key. In
- * order to limit the trust in the trusted entity, name constraints can also
- * be imposed on the trust anchor.
- */
-
-/*
- * FUNCTION: PKIX_TrustAnchor_CreateWithCert
- * DESCRIPTION:
- *
- * Creates a new TrustAnchor object using the Cert pointed to by "cert" as
- * the trusted certificate and stores it at "pAnchor". Once created, a
- * TrustAnchor is immutable.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert to use as trusted certificate. Must be non-NULL.
- * "pAnchor"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_TrustAnchor_CreateWithCert(
- PKIX_PL_Cert *cert,
- PKIX_TrustAnchor **pAnchor,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_TrustAnchor_CreateWithNameKeyPair
- * DESCRIPTION:
- *
- * Creates a new TrustAnchor object using the X500Name pointed to by "name",
- * and the PublicKey pointed to by "pubKey" and stores it at "pAnchor". The
- * CertNameConstraints pointed to by "nameConstraints" (if any) are used to
- * limit the trust placed in this trust anchor. To indicate that name
- * constraints don't apply, set "nameConstraints" to NULL. Once created, a
- * TrustAnchor is immutable.
- *
- * PARAMETERS:
- * "name"
- * Address of X500Name to use as name of trusted CA. Must be non-NULL.
- * "pubKey"
- * Address of PublicKey to use as trusted public key. Must be non-NULL.
- * "nameConstraints"
- * Address of CertNameConstraints to use as initial name constraints.
- * If NULL, no name constraints are applied.
- * "pAnchor"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_TrustAnchor_CreateWithNameKeyPair(
- PKIX_PL_X500Name *name,
- PKIX_PL_PublicKey *pubKey,
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_TrustAnchor **pAnchor,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_TrustAnchor_GetTrustedCert
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Cert that is set in the TrustAnchor pointed to
- * by "anchor" and stores it at "pCert". If "anchor" does not have a Cert
- * set, this function stores NULL at "pCert".
- *
- * PARAMETERS:
- * "anchor"
- * Address of TrustAnchor whose Cert is to be stored. Must be non-NULL.
- * "pChain"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_TrustAnchor_GetTrustedCert(
- PKIX_TrustAnchor *anchor,
- PKIX_PL_Cert **pCert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_TrustAnchor_GetCAName
- * DESCRIPTION:
- *
- * Retrieves a pointer to the CA's X500Name (if any) that is set in the
- * TrustAnchor pointed to by "anchor" and stores it at "pCAName". If "anchor"
- * does not have an X500Name set, this function stores NULL at "pCAName".
- *
- * PARAMETERS:
- * "anchor"
- * Address of TrustAnchor whose CA Name is to be stored. Must be non-NULL.
- * "pCAName"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_TrustAnchor_GetCAName(
- PKIX_TrustAnchor *anchor,
- PKIX_PL_X500Name **pCAName,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_TrustAnchor_GetCAPublicKey
- * DESCRIPTION:
- *
- * Retrieves a pointer to the CA's PublicKey (if any) that is set in the
- * TrustAnchor pointed to by "anchor" and stores it at "pPubKey". If "anchor"
- * does not have a PublicKey set, this function stores NULL at "pPubKey".
- *
- * PARAMETERS:
- * "anchor"
- * Address of TrustAnchor whose CA PublicKey is to be stored.
- * Must be non-NULL.
- * "pPubKey"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_TrustAnchor_GetCAPublicKey(
- PKIX_TrustAnchor *anchor,
- PKIX_PL_PublicKey **pPubKey,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_TrustAnchor_GetNameConstraints
- * DESCRIPTION:
- *
- * Retrieves a pointer to the CertNameConstraints (if any) set in the
- * TrustAnchor pointed to by "anchor" and stores it at "pConstraints". If
- * "anchor" does not have any CertNameConstraints set, this function stores
- * NULL at "pConstraints".
- *
- * PARAMETERS:
- * "anchor"
- * Address of TrustAnchor whose CertNameConstraints are to be stored.
- * Must be non-NULL.
- * "pConstraints"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Params Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_TrustAnchor_GetNameConstraints(
- PKIX_TrustAnchor *anchor,
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext);
-
-/* PKIX_ResourceLimits
- *
- * A PKIX_ResourceLimits object represents the maximum resource usage that
- * the caller desires. The ValidateChain or BuildChain call
- * will not exceed these maximum limits. For example, the caller may want
- * a timeout value of 1 minute, meaning that if the ValidateChain or
- * BuildChain function is unable to finish in 1 minute, it should abort
- * with an Error.
- */
-
-/*
- * FUNCTION: PKIX_ResourceLimits_Create
- * DESCRIPTION:
- *
- * Creates a new ResourceLimits object and stores it at "pResourceLimits".
- *
- * PARAMETERS:
- * "pResourceLimits"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_Create(
- PKIX_ResourceLimits **pResourceLimits,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxTime
- * DESCRIPTION:
- *
- * Retrieves a PKIX_UInt32 (if any) representing the maximum time that is
- * set in the ResourceLimits object pointed to by "resourceLimits" and stores
- * it at "pMaxTime". This maximum time (in seconds) should not be exceeded
- * by the function whose ProcessingParams contain this ResourceLimits object
- * (typically ValidateChain or BuildChain). It essentially functions as a
- * time-out value and is only appropriate if blocking I/O is being used.
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum time (in seconds) is
- * to be stored. Must be non-NULL.
- * "pMaxTime"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxTime(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 *pMaxTime,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxTime
- * DESCRIPTION:
- *
- * Sets the maximum time of the ResourceLimits object pointed to by
- * "resourceLimits" using the PKIX_UInt32 value of "maxTime". This
- * maximum time (in seconds) should not be exceeded by the function
- * whose ProcessingParams contain this ResourceLimits object
- * (typically ValidateChain or BuildChain). It essentially functions as a
- * time-out value and is only appropriate if blocking I/O is being used.
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum time (in seconds) is
- * to be set. Must be non-NULL.
- * "maxTime"
- * Value of PKIX_UInt32 representing the maximum time (in seconds)
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxTime(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 maxTime,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxFanout
- * DESCRIPTION:
- *
- * Retrieves a PKIX_UInt32 (if any) representing the maximum fanout that is
- * set in the ResourceLimits object pointed to by "resourceLimits" and stores
- * it at "pMaxFanout". This maximum fanout (number of certs) should not be
- * exceeded by the function whose ProcessingParams contain this ResourceLimits
- * object (typically ValidateChain or BuildChain). If the builder encounters
- * more than this maximum number of certificates when searching for the next
- * candidate certificate, it should abort and return an error. This
- * parameter is only relevant for ValidateChain if it needs to internally call
- * BuildChain (e.g. in order to build the chain to a CRL's issuer).
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum fanout (number of certs)
- * is to be stored. Must be non-NULL.
- * "pMaxFanout"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxFanout(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 *pMaxFanout,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxFanout
- * DESCRIPTION:
- *
- * Sets the maximum fanout of the ResourceLimits object pointed to by
- * "resourceLimits" using the PKIX_UInt32 value of "maxFanout". This maximum
- * fanout (number of certs) should not be exceeded by the function whose
- * ProcessingParams contain this ResourceLimits object (typically ValidateChain
- * or BuildChain). If the builder encounters more than this maximum number of
- * certificates when searching for the next candidate certificate, it should
- * abort and return an Error. This parameter is only relevant for ValidateChain
- * if it needs to internally call BuildChain (e.g. in order to build the
- * chain to a CRL's issuer).
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum fanout (number of certs)
- * is to be set. Must be non-NULL.
- * "maxFanout"
- * Value of PKIX_UInt32 representing the maximum fanout (number of certs)
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxFanout(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 maxFanout,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxDepth
- * DESCRIPTION:
- *
- * Retrieves a PKIX_UInt32 (if any) representing the maximum depth that is
- * set in the ResourceLimits object pointed to by "resourceLimits" and stores
- * it at "pMaxDepth". This maximum depth (number of certs) should not be
- * exceeded by the function whose ProcessingParams contain this ResourceLimits
- * object (typically ValidateChain or BuildChain). If the builder encounters
- * more than this maximum number of certificates when searching for the next
- * candidate certificate, it should abort and return an error. This
- * parameter is only relevant for ValidateChain if it needs to internally call
- * BuildChain (e.g. in order to build the chain to a CRL's issuer).
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum depth (number of certs)
- * is to be stored. Must be non-NULL.
- * "pMaxDepth"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxDepth(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 *pMaxDepth,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxDepth
- * DESCRIPTION:
- *
- * Sets the maximum depth of the ResourceLimits object pointed to by
- * "resourceLimits" using the PKIX_UInt32 value of "maxDepth". This maximum
- * depth (number of certs) should not be exceeded by the function whose
- * ProcessingParams contain this ResourceLimits object (typically ValidateChain
- * or BuildChain). If the builder encounters more than this maximum number of
- * certificates when searching for the next candidate certificate, it should
- * abort and return an Error. This parameter is only relevant for ValidateChain
- * if it needs to internally call BuildChain (e.g. in order to build the
- * chain to a CRL's issuer).
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum depth (number of certs)
- * is to be set. Must be non-NULL.
- * "maxDepth"
- * Value of PKIX_UInt32 representing the maximum depth (number of certs)
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxDepth(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 maxDepth,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxNumberOfCerts
- * DESCRIPTION:
- *
- * Retrieves a PKIX_UInt32 (if any) representing the maximum number of traversed
- * certs that is set in the ResourceLimits object pointed to by "resourceLimits"
- * and stores it at "pMaxNumber". This maximum number of traversed certs should
- * not be exceeded by the function whose ProcessingParams contain this ResourceLimits
- * object (typically ValidateChain or BuildChain). If the builder traverses more
- * than this number of certs during the build process, it should abort and
- * return an Error. This parameter is only relevant for ValidateChain if it
- * needs to internally call BuildChain (e.g. in order to build the chain to a
- * CRL's issuer).
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum number of traversed certs
- * is to be stored. Must be non-NULL.
- * "pMaxNumber"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxNumberOfCerts(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 *pMaxNumber,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxNumberOfCerts
- * DESCRIPTION:
- *
- * Sets the maximum number of traversed certs of the ResourceLimits object
- * pointed to by "resourceLimits" using the PKIX_UInt32 value of "maxNumber".
- * This maximum number of traversed certs should not be exceeded by the function
- * whose ProcessingParams contain this ResourceLimits object (typically ValidateChain
- * or BuildChain). If the builder traverses more than this number of certs
- * during the build process, it should abort and return an Error. This parameter
- * is only relevant for ValidateChain if it needs to internally call BuildChain
- * (e.g. in order to build the chain to a CRL's issuer).
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum number of traversed certs
- * is to be set. Must be non-NULL.
- * "maxNumber"
- * Value of PKIX_UInt32 representing the maximum number of traversed certs
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxNumberOfCerts(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 maxNumber,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxNumberOfCRLs
- * DESCRIPTION:
- *
- * Retrieves a PKIX_UInt32 (if any) representing the maximum number of traversed
- * CRLs that is set in the ResourceLimits object pointed to by "resourceLimits"
- * and stores it at "pMaxNumber". This maximum number of traversed CRLs should
- * not be exceeded by the function whose ProcessingParams contain this ResourceLimits
- * object (typically ValidateChain or BuildChain). If the builder traverses more
- * than this number of CRLs during the build process, it should abort and
- * return an Error. This parameter is only relevant for ValidateChain if it
- * needs to internally call BuildChain (e.g. in order to build the chain to a
- * CRL's issuer).
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum number of traversed CRLs
- * is to be stored. Must be non-NULL.
- * "pMaxNumber"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxNumberOfCRLs(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 *pMaxNumber,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxNumberOfCRLs
- * DESCRIPTION:
- *
- * Sets the maximum number of traversed CRLs of the ResourceLimits object
- * pointed to by "resourceLimits" using the PKIX_UInt32 value of "maxNumber".
- * This maximum number of traversed CRLs should not be exceeded by the function
- * whose ProcessingParams contain this ResourceLimits object (typically ValidateChain
- * or BuildChain). If the builder traverses more than this number of CRLs
- * during the build process, it should abort and return an Error. This parameter
- * is only relevant for ValidateChain if it needs to internally call BuildChain
- * (e.g. in order to build the chain to a CRL's issuer).
- *
- * PARAMETERS:
- * "resourceLimits"
- * Address of ResourceLimits object whose maximum number of traversed CRLs
- * is to be set. Must be non-NULL.
- * "maxNumber"
- * Value of PKIX_UInt32 representing the maximum number of traversed CRLs
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "params"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ResourceLimits Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxNumberOfCRLs(
- PKIX_ResourceLimits *resourceLimits,
- PKIX_UInt32 maxNumber,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PARAMS_H */
diff --git a/security/nss/lib/libpkix/include/pkix_pl_pki.h b/security/nss/lib/libpkix/include/pkix_pl_pki.h
deleted file mode 100755
index 8da25b88d..000000000
--- a/security/nss/lib/libpkix/include/pkix_pl_pki.h
+++ /dev/null
@@ -1,2702 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines several platform independent functions to
- * manipulate certificates and CRLs in a portable manner.
- *
- */
-
-#ifndef _PKIX_PL_PKI_H
-#define _PKIX_PL_PKI_H
-
-#include "pkixt.h"
-#include "seccomon.h"
-#include "certt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/*
- * Cert
- *
- * A Cert represents an X.509 certificate. It can be created using the bytes
- * of a valid ASN.1 DER encoding. Once created, a Cert is immutable. The
- * following functions include accessors (gettors) for the various components
- * of an X.509 certificate. Also included are functions to perform various
- * checks on a certificate, including name constraints, key usage, validity
- * (expiration), and signature verification.
- */
-
-/*
- * FUNCTION: PKIX_PL_Cert_Create
- * DESCRIPTION:
- *
- * Creates a new certificate using the bytes in the ByteArray pointed to by
- * "byteArray" and stores it at "pCert". If the bytes are not a valid ASN.1
- * DER encoding of a certificate, a PKIX_Error pointer is returned. Once
- * created, a Cert is immutable.
- *
- * Certificate ::= SEQUENCE {
- * tbsCertificate TBSCertificate,
- * signatureAlgorithm AlgorithmIdentifier,
- * signatureValue BIT STRING }
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL }
- *
- * TBSCertificate ::= SEQUENCE {
- * version [0] EXPLICIT Version DEFAULT v1,
- * serialNumber CertificateSerialNumber,
- * signature AlgorithmIdentifier,
- * issuer Name,
- * validity Validity,
- * subject Name,
- * subjectPublicKeyInfo SubjectPublicKeyInfo,
- * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
- * -- If present, version MUST be v2 or v3
- * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
- * -- If present, version MUST be v2 or v3
- * extensions [3] EXPLICIT Extensions OPTIONAL
- * -- If present, version MUST be v3
- * }
- *
- * Version ::= INTEGER { v1(0), v2(1), v3(2) }
- *
- * CertificateSerialNumber ::= INTEGER
- *
- * Validity ::= SEQUENCE {
- * notBefore Time,
- * notAfter Time }
- *
- * Time ::= CHOICE {
- * utcTime UTCTime,
- * generalTime GeneralizedTime }
- *
- * UniqueIdentifier ::= BIT STRING
- *
- * SubjectPublicKeyInfo ::= SEQUENCE {
- * algorithm AlgorithmIdentifier,
- * subjectPublicKey BIT STRING }
- *
- * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
- *
- * Extension ::= SEQUENCE {
- * extnID OBJECT IDENTIFIER,
- * critical BOOLEAN DEFAULT FALSE,
- * extnValue OCTET STRING }
- *
- * PARAMETERS:
- * "byteArray"
- * Address of ByteArray representing the CERT's DER encoding.
- * Must be non-NULL.
- * "pCert"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_Create(
- PKIX_PL_ByteArray *byteArray,
- PKIX_PL_Cert **pCert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_CreateFromCERTCertificate
- * DESCRIPTION:
- *
- * Creates a new certificate using passed in CERTCertificate object.
- *
- * PARAMETERS:
- * "nssCert"
- * The object that will be used to create new PKIX_PL_Cert.
- * "pCert"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_CreateFromCERTCertificate(
- const CERTCertificate *nssCert,
- PKIX_PL_Cert **pCert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetCERTCertificate
- * DESCRIPTION:
- *
- * Returns underlying CERTCertificate structure. Return CERTCertificate
- * object is duplicated and should be destroyed by caller.
- *
- * PARAMETERS:
- * "cert"
- * Address of PKIX_PL_Cert. Must be non-NULL.
- * "pCert"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetCERTCertificate(
- PKIX_PL_Cert *cert,
- CERTCertificate **pnssCert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetVersion
- * DESCRIPTION:
- *
- * Retrieves the version of the Cert pointed to by "cert" and stores it at
- * "pVersion". The version number will either be 0, 1, or 2 (corresponding to
- * v1, v2, or v3, respectively).
- *
- * Version ::= INTEGER { v1(0), v2(1), v3(2) }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose version is to be stored. Must be non-NULL.
- * "pVersion"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetVersion(
- PKIX_PL_Cert *cert,
- PKIX_UInt32 *pVersion,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSerialNumber
- * DESCRIPTION:
- *
- * Retrieves a pointer to the BigInt that represents the serial number of the
- * Cert pointed to by "cert" and stores it at "pSerialNumber".
- *
- * CertificateSerialNumber ::= INTEGER
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose serial number is to be stored. Must be non-NULL.
- * "pSerial"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSerialNumber(
- PKIX_PL_Cert *cert,
- PKIX_PL_BigInt **pSerial,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetIssuer
- * DESCRIPTION:
- *
- * Retrieves a pointer to the X500Name that represents the issuer DN of the
- * Cert pointed to by "cert" and stores it at "pIssuer".
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose issuer is to be stored. Must be non-NULL.
- * "pIssuer"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetIssuer(
- PKIX_PL_Cert *cert,
- PKIX_PL_X500Name **pIssuer,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubject
- * DESCRIPTION:
- *
- * Retrieves a pointer to the X500Name that represents the subject DN of the
- * Cert pointed to by "cert" and stores it at "pSubject". If the Cert does not
- * have a subject DN, this function stores NULL at "pSubject".
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose subject is to be stored. Must be non-NULL.
- * "pSubject"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubject(
- PKIX_PL_Cert *cert,
- PKIX_PL_X500Name **pSubject,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKeyAlgId
- * DESCRIPTION:
- *
- * Retrieves a pointer to the OID that represents the subject public key
- * algorithm of the Cert pointed to by "cert" and stores it at
- * "pSubjKeyAlgId".
- *
- * SubjectPublicKeyInfo ::= SEQUENCE {
- * algorithm AlgorithmIdentifier,
- * subjectPublicKey BIT STRING }
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose subject public key algorithm OID is to be stored.
- * Must be non-NULL.
- * "pSubjKeyAlgId"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectPublicKeyAlgId(
- PKIX_PL_Cert *cert,
- PKIX_PL_OID **pSubjKeyAlgId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKey
- * DESCRIPTION:
- *
- * Retrieves a pointer to the PublicKey that represents the subject public key
- * of the Cert pointed to by "cert" and stores it at "pPublicKey".
- *
- * SubjectPublicKeyInfo ::= SEQUENCE {
- * algorithm AlgorithmIdentifier,
- * subjectPublicKey BIT STRING }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose subject public key is to be stored.
- * Must be non-NULL.
- * "pPublicKey"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectPublicKey(
- PKIX_PL_Cert *cert,
- PKIX_PL_PublicKey **pPublicKey,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_PublicKey_NeedsDSAParameters
- * DESCRIPTION:
- *
- * Determines if the PublicKey pointed to by "pubKey" is a DSA Key with null
- * parameters and stores the result at "pNeedsParams".
- *
- * PARAMETERS:
- * "pubKey"
- * Address of the Public Key of interest. Must be non-NULL.
- * "pNeedsParams"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a PublicKey Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_PublicKey_NeedsDSAParameters(
- PKIX_PL_PublicKey *pubKey,
- PKIX_Boolean *pNeedsParams,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_PublicKey_MakeInheritedDSAPublicKey
- * DESCRIPTION:
- *
- * This function is used for DSA key parameter inheritance, which allows a
- * first DSA key with omitted parameters (pointed to by "firstKey") to inherit
- * the PQG parameters of a second DSA key that does have parameters. (pointed
- * to by "secondKey"). Once created, a PublicKey is immutable.
- *
- * Specifically, the algorithm used by the function is:
- *
- * If the first PublicKey is not a DSA public key with omitted parameters,
- * the function stores NULL at "pResultKey". (No Error is returned)
- * Else if the second PublicKey is not a DSA public key with non-NULL,
- * parameters, the function returns an Error.
- * Else
- * the function creates a third PublicKey with a "Y" value from the
- * first PublicKey and the DSA parameters from the second PublicKey,
- * and stores it at "pResultKey".
- *
- * PARAMETERS:
- * "firstKey"
- * Address of a Public Key that needs to inherit DSA parameters.
- * Must be non-NULL.
- * "secondKey"
- * Address of a Public Key that has DSA parameters that will be inherited
- * by "firstKey". Must be non-NULL.
- * "pResultKey"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a PublicKey Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_PublicKey_MakeInheritedDSAPublicKey(
- PKIX_PL_PublicKey *firstKey,
- PKIX_PL_PublicKey *secondKey,
- PKIX_PL_PublicKey **pResultKey,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetCriticalExtensionOIDs
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of OIDs (each OID corresponding to a
- * critical extension of the Cert pointed to by "cert") and stores it at
- * "pExtensions". If "cert" does not have any critical extensions, this
- * function stores an empty List at "pExtensions".
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose critical extension OIDs are to be stored.
- * Must be non-NULL.
- * "pExtensions"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetCriticalExtensionOIDs(
- PKIX_PL_Cert *cert,
- PKIX_List **pExtensions, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetAuthorityKeyIdentifier
- * DESCRIPTION:
- *
- * Retrieves a pointer to a ByteArray representing the authority key
- * identifier extension of the Cert pointed to by "cert" and stores it at
- * "pAuthKeyId".
- *
- * Note that this function only retrieves the keyIdentifier component
- * (OCTET STRING) of the AuthorityKeyIdentifier extension, when present.
- *
- * If "cert" does not have an AuthorityKeyIdentifier extension or if the
- * keyIdentifier component of the AuthorityKeyIdentifier extension is not
- * present, this function stores NULL at "pAuthKeyId".
- *
- * AuthorityKeyIdentifier ::= SEQUENCE {
- * keyIdentifier [0] KeyIdentifier OPTIONAL,
- * authorityCertIssuer [1] GeneralNames OPTIONAL,
- * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose authority key identifier is to be stored.
- * Must be non-NULL.
- * "pAuthKeyId"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetAuthorityKeyIdentifier(
- PKIX_PL_Cert *cert,
- PKIX_PL_ByteArray **pAuthKeyId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectKeyIdentifier
- * DESCRIPTION:
- *
- * Retrieves a pointer to a ByteArray representing the subject key identifier
- * extension of the Cert pointed to by "cert" and stores it at "pSubjKeyId".
- * If "cert" does not have a SubjectKeyIdentifier extension, this function
- * stores NULL at "pSubjKeyId".
- *
- * SubjectKeyIdentifier ::= KeyIdentifier
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose subject key identifier is to be stored.
- * Must be non-NULL.
- * "pSubjKeyId"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectKeyIdentifier(
- PKIX_PL_Cert *cert,
- PKIX_PL_ByteArray **pSubjKeyId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectAltNames
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of GeneralNames (each GeneralName
- * representing a subject alternative name found in the subject alternative
- * names extension of the Cert pointed to by "cert") and stores it at
- * "pSubjectAltNames". If "cert" does not have a SubjectAlternativeNames
- * extension, this function stores NULL at "pSubjectAltNames".
- *
- * Note that the List returned by this function is immutable.
- *
- * SubjectAltName ::= GeneralNames
- *
- * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
- *
- * GeneralName ::= CHOICE {
- * otherName [0] OtherName,
- * rfc822Name [1] IA5String,
- * dNSName [2] IA5String,
- * x400Address [3] ORAddress,
- * directoryName [4] Name,
- * ediPartyName [5] EDIPartyName,
- * uniformResourceIdentifier [6] IA5String,
- * iPAddress [7] OCTET STRING,
- * registeredID [8] OBJECT IDENTIFIER }
- *
- * OtherName ::= SEQUENCE {
- * type-id OBJECT IDENTIFIER,
- * value [0] EXPLICIT ANY DEFINED BY type-id }
- *
- * EDIPartyName ::= SEQUENCE {
- * nameAssigner [0] DirectoryString OPTIONAL,
- * partyName [1] DirectoryString }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose subjectAltNames are to be stored.
- * Must be non-NULL.
- * "pSubjectAltNames"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectAltNames(
- PKIX_PL_Cert *cert,
- PKIX_List **pSubjectAltNames, /* list of PKIX_PL_GeneralName */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetAllSubjectNames
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of GeneralNames (each GeneralName
- * representing a subject DN or a subject alternative name found in the
- * subject alternative names extension of the Cert pointed to by "cert") and
- * stores it at "pAllSubjectNames".If the Subject DN of "cert" is empty and
- * it does not have a SubjectAlternativeNames extension, this function stores
- * NULL at "pAllSubjectNames".
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose subject DN and subjectAltNames are to be stored.
- * Must be non-NULL.
- * "pAllSubjectNames"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetAllSubjectNames(
- PKIX_PL_Cert *cert,
- PKIX_List **pAllSubjectNames, /* list of PKIX_PL_GeneralName */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetExtendedKeyUsage
- * DESCRIPTION:
- *
- * Retrieves a pointer to a List of OIDs (each OID corresponding to an
- * extended key usage of the Cert pointed to by "cert") and stores it at
- * "pKeyUsage". If "cert" does not have an extended key usage extension, this
- * function stores a NULL at "pKeyUsage".
- *
- * Note that the List returned by this function is immutable.
- *
- * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
- *
- * KeyPurposeId ::= OBJECT IDENTIFIER
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose extended key usage OIDs are to be stored.
- * Must be non-NULL.
- * "pKeyUsage"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetExtendedKeyUsage(
- PKIX_PL_Cert *cert,
- PKIX_List **pKeyUsage, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetNameConstraints
- * DESCRIPTION:
- *
- * Retrieves a pointer to a CertNameConstraints object representing the name
- * constraints extension of the Cert pointed to by "cert" and stores it at
- * "pNameConstraints".
- *
- * If "cert" does not have a name constraints extension, this function stores
- * NULL at "pNameConstraints".
- *
- * NameConstraints ::= SEQUENCE {
- * permittedSubtrees [0] GeneralSubtrees OPTIONAL,
- * excludedSubtrees [1] GeneralSubtrees OPTIONAL }
- *
- * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
- *
- * GeneralSubtree ::= SEQUENCE {
- * base GeneralName,
- * minimum [0] BaseDistance DEFAULT 0,
- * maximum [1] BaseDistance OPTIONAL }
- *
- * BaseDistance ::= INTEGER (0..MAX)
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose name constraints extension is to be stored.
- * Must be non-NULL.
- * "pNameConstraints"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetNameConstraints(
- PKIX_PL_Cert *cert,
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetBasicConstraints
- * DESCRIPTION:
- *
- * Retrieves a pointer to a CertBasicConstraints object representing the basic
- * constraints extension of the Cert pointed to by "cert" and stores it at
- * "pBasicConstraints".
- *
- * If "cert" does not have a basic constraints extension, this function stores
- * NULL at "pBasicConstraints". Once created, a CertBasicConstraints object
- * is immutable.
- *
- * BasicConstraints ::= SEQUENCE {
- * cA BOOLEAN DEFAULT FALSE,
- * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose basic constraints extension is to be stored.
- * Must be non-NULL.
- * "pBasicConstraints"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetBasicConstraints(
- PKIX_PL_Cert *cert,
- PKIX_PL_CertBasicConstraints **pBasicConstraints,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_BasicConstraints_GetCAFlag
- * DESCRIPTION:
- *
- * Retrieves a pointer to a Boolean value representing the cA Flag component
- * of the CertBasicConstraints object pointed to by "basicConstraints" and
- * stores it at "pResult".
- *
- * BasicConstraints ::= SEQUENCE {
- * cA BOOLEAN DEFAULT FALSE,
- * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
- *
- * PARAMETERS:
- * "basicConstraints"
- * Address of CertBasicConstraints whose cA Flag is to be stored.
- * Must be non-NULL.
- * "pResult"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_BasicConstraints_GetCAFlag(
- PKIX_PL_CertBasicConstraints *basicConstraints,
- PKIX_Boolean *pResult,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_BasicConstraints_GetPathLenConstraint
- * DESCRIPTION:
- *
- * Retrieves a pointer to an integer value representing the pathLenConstraint
- * component of the CertBasicConstraints object pointed to by
- * "basicConstraints" and stores it at "pPathLenConstraint". If the
- * pathLenConstraint component is not present, this function stores -1 at
- * "pPathLenConstraint".
- *
- * PARAMETERS:
- * "basicConstraints"
- * Address of CertBasicConstraints whose pathLen is to be stored.
- * Must be non-NULL.
- * "pPathLenConstraint"
- * Address where PKIX_Int32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_BasicConstraints_GetPathLenConstraint(
- PKIX_PL_CertBasicConstraints *basicConstraints,
- PKIX_Int32 *pPathLenConstraint,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetPolicyInformation
- * DESCRIPTION:
- *
- * Retrieves a pointer to a List of CertPolicyInfos found in the certificate
- * policies extension of the Cert pointed to by "cert" and stores it at
- * "pPolicyInfo". If "cert" does not have a certificate policies extension,
- * this function stores NULL at "pPolicyInfo". Once created, a CertPolicyInfo
- * object is immutable.
- *
- * Note that the List returned by this function is immutable.
- *
- * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
- *
- * PolicyInformation ::= SEQUENCE {
- * policyIdentifier CertPolicyId,
- * policyQualifiers SEQUENCE SIZE (1..MAX) OF
- * PolicyQualifierInfo OPTIONAL }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose CertPolicyInfos are to be stored.
- * Must be non-NULL.
- * "pPolicyInfo"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetPolicyInformation(
- PKIX_PL_Cert *cert,
- PKIX_List **pPolicyInfo, /* list of PKIX_PL_CertPolicyInfo */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CertPolicyInfo_GetPolicyId
- * DESCRIPTION:
- *
- * Retrieves a pointer to an OID representing the policyIdentifier of the
- * CertPolicyInfo pointed to by "policyInfo" and stores it at "pCertPolicyId".
- *
- * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
- *
- * PolicyInformation ::= SEQUENCE {
- * policyIdentifier CertPolicyId,
- * policyQualifiers SEQUENCE SIZE (1..MAX) OF
- * PolicyQualifierInfo OPTIONAL }
- *
- * CertPolicyId ::= OBJECT IDENTIFIER
- *
- * PARAMETERS:
- * "policyInfo"
- * Address of CertPolicyInfo whose policy identifier is to be stored.
- * Must be non-NULL.
- * "pCertPolicyId"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CertPolicyInfo_GetPolicyId(
- PKIX_PL_CertPolicyInfo *policyInfo,
- PKIX_PL_OID **pCertPolicyId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CertPolicyInfo_GetPolQualifiers
- * DESCRIPTION:
- *
- * Retrieves a pointer to a List of the CertPolicyQualifiers representing
- * the policyQualifiers of the CertPolicyInfo pointed to by "policyInfo" and
- * stores it at "pPolicyQualifiers". If "policyInfo" does not have any
- * policyQualifiers, this function stores NULL at "pPolicyQualifiers". Once
- * created, a CertPolicyQualifier is immutable.
- *
- * Note that the List returned by this function is immutable.
- *
- * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
- *
- * PolicyInformation ::= SEQUENCE {
- * policyIdentifier CertPolicyId,
- * policyQualifiers SEQUENCE SIZE (1..MAX) OF
- * PolicyQualifierInfo OPTIONAL }
- *
- * PolicyQualifierInfo ::= SEQUENCE {
- * policyQualifierId PolicyQualifierId,
- * qualifier ANY DEFINED BY policyQualifierId }
- *
- * PARAMETERS:
- * "policyInfo"
- * Address of CertPolicyInfo whose policy qualifiers List is to be stored.
- * Must be non-NULL.
- * "pPolicyQualifiers"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CertPolicyInfo_GetPolQualifiers(
- PKIX_PL_CertPolicyInfo *policyInfo,
- PKIX_List **pPolicyQualifiers, /* list of PKIX_PL_CertPolicyQualifier */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_PolicyQualifier_GetPolicyQualifierId
- * DESCRIPTION:
- *
- * Retrieves a pointer to an OID representing the policyQualifierId of the
- * CertPolicyQualifier pointed to by "policyQualifier" and stores it at
- * "pPolicyQualifierId".
- *
- * PolicyQualifierInfo ::= SEQUENCE {
- * policyQualifierId PolicyQualifierId,
- * qualifier ANY DEFINED BY policyQualifierId }
- *
- * PolicyQualifierId ::=
- * OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
- *
- * PARAMETERS:
- * "policyQualifier"
- * Address of CertPolQualifier whose policyQualifierId is to be stored.
- * Must be non-NULL.
- * "pPolicyQualifierId"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_PolicyQualifier_GetPolicyQualifierId(
- PKIX_PL_CertPolicyQualifier *policyQualifier,
- PKIX_PL_OID **pPolicyQualifierId,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_PolicyQualifier_GetQualifier
- * DESCRIPTION:
- *
- * Retrieves a pointer to a ByteArray representing the qualifier of the
- * CertPolicyQualifier pointed to by "policyQualifier" and stores it at
- * "pQualifier".
- *
- * PolicyQualifierInfo ::= SEQUENCE {
- * policyQualifierId PolicyQualifierId,
- * qualifier ANY DEFINED BY policyQualifierId }
- *
- * PARAMETERS:
- * "policyQualifier"
- * Address of CertPolicyQualifier whose qualifier is to be stored.
- * Must be non-NULL.
- * "pQualifier"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_PolicyQualifier_GetQualifier(
- PKIX_PL_CertPolicyQualifier *policyQualifier,
- PKIX_PL_ByteArray **pQualifier,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetPolicyMappings
- * DESCRIPTION:
- *
- * Retrieves a pointer to a List of CertPolicyMaps found in the policy
- * mappings extension of the Cert pointed to by "cert" and stores it at
- * "pPolicyMappings". If "cert" does not have a policy mappings extension,
- * this function stores NULL at "pPolicyMappings". Once created, a
- * CertPolicyMap is immutable.
- *
- * Note that the List returned by this function is immutable.
- *
- * PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
- * issuerDomainPolicy CertPolicyId,
- * subjectDomainPolicy CertPolicyId }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose CertPolicyMaps are to be stored.
- * Must be non-NULL.
- * "pPolicyMappings"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetPolicyMappings(
- PKIX_PL_Cert *cert,
- PKIX_List **pPolicyMappings, /* list of PKIX_PL_CertPolicyMap */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy
- * DESCRIPTION:
- *
- * Retrieves a pointer to an OID representing the issuerDomainPolicy of the
- * CertPolicyMap pointed to by "policyMapping" and stores it at
- * "pIssuerDomainPolicy".
- *
- * PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
- * issuerDomainPolicy CertPolicyId,
- * subjectDomainPolicy CertPolicyId }
- *
- * PARAMETERS:
- * "policyMapping"
- * Address of CertPolicyMap whose issuerDomainPolicy is to be stored.
- * Must be non-NULL.
- * "pIssuerDomainPolicy"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy(
- PKIX_PL_CertPolicyMap *policyMapping,
- PKIX_PL_OID **pIssuerDomainPolicy,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy
- * DESCRIPTION:
- *
- * Retrieves a pointer to an OID representing the subjectDomainPolicy of the
- * CertPolicyMap pointed to by "policyMapping" and stores it at
- * "pSubjectDomainPolicy".
- *
- * PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
- * issuerDomainPolicy CertPolicyId,
- * subjectDomainPolicy CertPolicyId }
- *
- * PARAMETERS:
- * "policyMapping"
- * Address of CertPolicyMap whose subjectDomainPolicy is to be stored.
- * Must be non-NULL.
- * "pSubjectDomainPolicy"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy(
- PKIX_PL_CertPolicyMap *policyMapping,
- PKIX_PL_OID **pSubjectDomainPolicy,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetRequireExplicitPolicy
- * DESCRIPTION:
- *
- * Retrieves the requireExplicitPolicy value of the policy constraints
- * extension of the Cert pointed to by "cert" and stores it at "pSkipCerts".
- * If "cert" does not have a policy constraints extension or the
- * requireExplicitPolicy component is not populated, this function stores -1
- * at "pSkipCerts".
- *
- * PolicyConstraints ::= SEQUENCE {
- * requireExplicitPolicy [0] SkipCerts OPTIONAL,
- * inhibitPolicyMapping [1] SkipCerts OPTIONAL }
- *
- * SkipCerts ::= INTEGER (0..MAX)
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose requireExplicitPolicy value is to be stored.
- * Must be non-NULL.
- * "pSkipCerts"
- * Address where PKIX_Int32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetRequireExplicitPolicy(
- PKIX_PL_Cert *cert,
- PKIX_Int32 *pSkipCerts,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetPolicyMappingInhibited
- * DESCRIPTION:
- *
- * Retrieves the inhibitPolicyMapping value of the policy constraints
- * extension of the Cert pointed to by "cert" and stores it at "pSkipCerts".
- * If "cert" does not have a policy constraints extension or the
- * inhibitPolicyMapping component is not populated, this function stores -1
- * at "pSkipCerts".
- *
- * PolicyConstraints ::= SEQUENCE {
- * requireExplicitPolicy [0] SkipCerts OPTIONAL,
- * inhibitPolicyMapping [1] SkipCerts OPTIONAL }
- *
- * SkipCerts ::= INTEGER (0..MAX)
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose requireExplicitPolicy value is to be stored.
- * Must be non-NULL.
- * "pSkipCerts"
- * Address where PKIX_Int32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetPolicyMappingInhibited(
- PKIX_PL_Cert *cert,
- PKIX_Int32 *pSkipCerts,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetInhibitAnyPolicy
- * DESCRIPTION:
- *
- * Retrieves the value of the inhibit any-policy extension of the Cert
- * pointed to by "cert" and stores it at "pSkipCerts". If "cert" does not have
- * an inhibit any-policy extension, this function stores -1 at "pSkipCerts".
- *
- * InhibitAnyPolicy ::= SkipCerts
- *
- * SkipCerts ::= INTEGER (0..MAX)
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose inhibit any-policy extensions value is to be
- * stored. Must be non-NULL.
- * "pSkipCerts"
- * Address where PKIX_Int32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetInhibitAnyPolicy(
- PKIX_PL_Cert *cert,
- PKIX_Int32 *pSkipCerts,
- void *plContext);
-
-/* policy processing functions */
-
-/*
- * FUNCTION: PKIX_PL_Cert_AreCertPoliciesCritical
- * DESCRIPTION:
- *
- * Checks whether the certificate policies extension of the Cert pointed to
- * by "cert" is critical and stores the Boolean result at "pCritical". If
- * "cert" does not have a certificate policies extension, this function
- * stores NULL at "pCritical".
- *
- * XXX what distinguishes NULL from PKIX_FALSE?
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose certificate policies extension's criticality is
- * to be determined. Must be non-NULL.
- * "pCritical"
- * Address where PKIX_Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_AreCertPoliciesCritical(
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pCritical,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_CheckNameConstraints
- * DESCRIPTION:
- *
- * Checks whether the subject distinguished name and subject alternative names
- * of the Cert pointed to by "cert" satisfy the CertNameConstraints pointed
- * to by "nameConstraints". If the CertNameConstraints are not satisfied, a
- * PKIX_Error pointer is returned. If "nameConstraints" is NULL, the function
- * does nothing.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose subject names are to be checked.
- * Must be non-NULL.
- * "nameConstraints"
- * Address of CertNameConstraints that need to be satisfied.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_CheckNameConstraints(
- PKIX_PL_Cert *cert,
- PKIX_PL_CertNameConstraints *nameConstraints,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_MergeNameConstraints
- * DESCRIPTION:
- *
- * Merges the CertNameConstraints pointed to by "firstNC" and the
- * CertNameConstraints pointed to by "secondNC" and stores the merged
- * CertNameConstraints at "pResultNC". If "secondNC" is NULL, the
- * CertNameConstraints pointed to by "firstNC" is stored at "pResultNC".
- *
- * Once created, a CertNameConstraints object is immutable.
- *
- * PARAMETERS:
- * "firstNC"
- * Address of first CertNameConstraints to be merged. Must be non-NULL.
- * "secondNC"
- * Address of second CertNameConstraints to be merged
- * "pResultNC"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_MergeNameConstraints(
- PKIX_PL_CertNameConstraints *firstNC,
- PKIX_PL_CertNameConstraints *secondNC,
- PKIX_PL_CertNameConstraints **pResultNC,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_VerifyKeyUsage
- * DESCRIPTION:
- *
- * Verifies that the keyUsage bit(s) specified by "keyUsage" appear in the
- * keyUsage extension of the Cert pointed to by "cert". The keyUsage bit
- * values specified in pkixt.h are supported, and can be bitwise or'ed if
- * multiple bit values are to be verified. If the keyUsages do not all appear
- * in the keyUsage extension of "cert", a PKIX_Error pointer is returned.
- *
- * KeyUsage ::= BIT STRING {
- * digitalSignature (0),
- * nonRepudiation (1),
- * keyEncipherment (2),
- * dataEncipherment (3),
- * keyAgreement (4),
- * keyCertSign (5),
- * cRLSign (6),
- * encipherOnly (7),
- * decipherOnly (8) }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose keyUsage bits are to be verified.
- * Must be non-NULL.
- * "keyUsage"
- * Constant representing keyUsage bit(s) that all must appear in keyUsage
- * extension of "cert".
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_VerifyKeyUsage(
- PKIX_PL_Cert *cert,
- PKIX_UInt32 keyUsage,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_VerifyCertAndKeyType
- * DESCRIPTION:
- *
- * Verifies cert and key types against certificate usage that is
- * a part of plContext(pkix_pl_nsscontext) structure. Throws an error
- * if cert or key types does not match.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose keyUsage bits are to be verified.
- * Must be non-NULL.
- * "isLeafCert"
- * What type of a cert has been verified.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_VerifyCertAndKeyType(
- PKIX_PL_Cert *cert,
- PKIX_Boolean isChainCert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_CheckValidity
- * DESCRIPTION:
- *
- * Checks whether the Cert pointed to by "cert" would be valid at the time
- * represented by the Date pointed to by "date". If "date" is NULL, then this
- * function checks whether the Cert would be valid at the current time. If the
- * Cert would not be valid at the specified Date, a PKIX_Error pointer is
- * returned.
- *
- * Validity ::= SEQUENCE {
- * notBefore Time,
- * notAfter Time }
- *
- * Time ::= CHOICE {
- * utcTime UTCTime,
- * generalTime GeneralizedTime }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose validity is to be checked. Must be non-NULL.
- * "date"
- * Address of Date at which the Cert is being checked for validity.
- * If NULL, the current time is used for the Date.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_CheckValidity(
- PKIX_PL_Cert *cert,
- PKIX_PL_Date *date,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetValidityNotAfter
- * DESCRIPTION:
- *
- * Retrieves a pointer to the Date that represents the notAfter time of the
- * Certificate pointed to by "cert" and stores it at "pDate".
- *
- * Validity ::= SEQUENCE {
- * notBefore Time,
- * notAfter Time }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose validity time is to be retrieved. Must be
- * non-NULL.
- * "date"
- * Address of Date at which the Cert's notAfter time is being retrieved.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetValidityNotAfter(
- PKIX_PL_Cert *cert,
- PKIX_PL_Date **pDate,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_VerifySignature
- * DESCRIPTION:
- *
- * Verifies the signature on the Cert pointed to by "cert" using the
- * PublicKey pointed to by "pubKey". If the signature doesn't verify, an
- * Error pointer is returned.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose signature is to be verified. Must be non-NULL.
- * "pubKey"
- * Address of a Public Key used to verify the signature. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_VerifySignature(
- PKIX_PL_Cert *cert,
- PKIX_PL_PublicKey *pubKey,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_IsCertTrusted
- * DESCRIPTION:
- *
- * Checks the Cert specified by "cert" to determine, in a manner that depends
- * on the underlying platform, whether it is trusted, and stores the result in
- * "pTrusted". If a certificate is trusted it means that a chain built to that
- * certificate, and satisfying all the usage, policy, validity, and other
- * tests, is a valid chain and the End Entity certificate from which it was
- * built can be trusted.
- *
- * If the Certificate is not intrinsically trustworthy, it still might end up a
- * component in a successful chain.
- *
- * If the Certificate is intrinsically untrustworthy, this function will return
- * an error.
- *
- * PARAMETERS
- * "cert"
- * Address of Cert whose trustworthiness is to be determined. Must be
- * non-NULL.
- * "trustOnlyUserAnchors"
- * States that we can only trust explicitly defined user trust anchors.
- * "pTrusted"
- * Address where the Boolean value will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CERT Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_IsCertTrusted(
- PKIX_PL_Cert *cert,
- PKIX_Boolean trustOnlyUserAnchors,
- PKIX_Boolean *pTrusted,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_IsLeafCertTrusted
- * DESCRIPTION:
- *
- * Checks the Leaf Cert specified by "cert" to determine, in a manner that
- * depends on the underlying platform, whether it is trusted, and stores the
- * result in "pTrusted". If a certificate is trusted it means that this
- * End Entify certificate has been marked as trusted for the requested usage,
- * policy, validity, and other tests.
- *
- * If the Certificate is not intrinsically trustworthy, we can still try to
- * build a successful chain.
- *
- * If the Certificate is intrinsically untrustworthy, this function will return
- * an error.
- *
- * PARAMETERS
- * "cert"
- * Address of Cert whose trustworthiness is to be determined. Must be
- * non-NULL.
- * "pTrusted"
- * Address where the Boolean value will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CERT Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_IsLeafCertTrusted(
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pTrusted,
- void *plContext);
-
-/* FUNCTION: PKIX_PL_Cert_SetAsTrustAnchor */
-PKIX_Error*
-PKIX_PL_Cert_SetAsTrustAnchor(PKIX_PL_Cert *cert,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetCacheFlag
- * DESCRIPTION:
- *
- * Retrieves the value of the cache flag in "cert" and return it at address
- * pointed by "pCacheFlag". The initila cache flag is determined by the
- * CertStore this "cert" is fetched from. When CertStore is created, user
- * need to specify if the data should be cached.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose cache flag is fetched. Must be non-NULL.
- * "pCacheFlag"
- * Address where PKIX_Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetCacheFlag(
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pCacheFlag,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_SetCacheFlag
- * DESCRIPTION:
- *
- * Set the value of the cache flag in "cert" base on the boolean value stored
- * at "cacheFlag". This function is meant to be used by CertStore after a
- * Cert is created.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert where "cacheFlag" is stored. Must be non-NULL.
- * "cacheFlag"
- * PKIX_Boolean flag for cache flag.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_SetCacheFlag(
- PKIX_PL_Cert *cert,
- PKIX_Boolean cacheFlag,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetTrustCertStore
- * DESCRIPTION:
- *
- * Retrieves the value of the CertStore in "cert" and return it at address
- * pointed by "pCertStore".
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose CertStore is fetched. Must be non-NULL.
- * "pTrustCertStore"
- * Address where CertStore will be stored and returned. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetTrustCertStore(
- PKIX_PL_Cert *cert,
- PKIX_CertStore **pTrustCertStore,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Cert_SetTrustCertStore
- * DESCRIPTION:
- *
- * Set the value of the CertStore "certStore" in "cert".
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert where "certStore" will be stored. Must be non-NULL.
- * "trustCertStore"
- * Address where the CertStore is. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_SetTrustCertStore(
- PKIX_PL_Cert *cert,
- PKIX_CertStore *trustCertStore,
- void *plContext);
-
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetAuthorityInfoAccess
- * DESCRIPTION:
- *
- * Retrieves the value(s) of the Authority Information Access in "cert" and
- * returns it in a list at address pointed by "pAuthorityInfoAccess".
- *
- * SubjectInfoAccess ::=
- * SEQUENCE SIZE (1..MAX) of AccessDescription
- * AccessDescription ::= SEQUENCE {
- * accessMethod OBJECT IDENTIFIER,
- * accessLocation GeneralName
- * }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose Authority Information Access is fetched.
- * Must be non-NULL.
- * "pAuthorityInfoAccess"
- * Address where Authority InfoAccess will be stored and returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetAuthorityInfoAccess(
- PKIX_PL_Cert *cert,
- PKIX_List **pAiaList, /* of PKIX_PL_InfoAccess */
- void *plContext);
-
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectInfoAccess
- * DESCRIPTION:
- *
- * Retrieves the value(s) of the Subject Information Access in "cert" and
- * returns it in a list at address pointed by "pSubjectInfoAccess".
- *
- * SubjectInfoAccess ::=
- * SEQUENCE SIZE (1..MAX) of AccessDescription
- * AccessDescription ::= SEQUENCE {
- * accessMethod OBJECT IDENTIFIER,
- * accessLocation GeneralName
- * }
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose Subject Information Access is fetched.
- * Must be non-NULL.
- * "pSubjectInfoAccess"
- * Address where Subject InfoAccess will be stored and returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectInfoAccess(
- PKIX_PL_Cert *cert,
- PKIX_List **pSiaList, /* of PKIX_PL_InfoAccess */
- void *plContext);
-
-
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetCrlDp
- * DESCRIPTION:
- *
- * Retrieves the value(s) of the CRL Distribution Point Extension and
- * returns it in a list at address pointed by "pDpList".
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose Subject Information Access is fetched.
- * Must be non-NULL.
- * "pDpList"
- * Address where CRL DP will be stored and returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Cert_GetCrlDp(PKIX_PL_Cert *cert,
- PKIX_List **pDpList,
- void *plContext);
-
-
-/*
- * InfoAccess
- *
- * To hold Authority Information Access or Subject Information Access
- * retrieved from a Certificate.
- */
-
-#define PKIX_INFOACCESS_OCSP 1
-#define PKIX_INFOACCESS_CA_ISSUERS 2
-#define PKIX_INFOACCESS_TIMESTAMPING 3
-#define PKIX_INFOACCESS_CA_REPOSITORY 5
-
-#define PKIX_INFOACCESS_LOCATION_UNKNOWN 0
-#define PKIX_INFOACCESS_LOCATION_HTTP 1
-#define PKIX_INFOACCESS_LOCATION_LDAP 2
-
-/*
- * FUNCTION: PKIX_PL_InfoAccess_GetMethod
- * DESCRIPTION:
- *
- * Stores the method of the Information Access from "infoAccess" and
- * returns in "pMethod".
- *
- * SubjectInfoAccess ::=
- * AccessDescription ::= SEQUENCE {
- * accessMethod OBJECT IDENTIFIER,
- * accessLocation GeneralName
- * }
- *
- * PARAMETERS:
- * "infoAccess"
- * Address of PKIX_PL_InfoAccess that has the access data.
- * Must be non-NULL.
- * "pMethod"
- * Address where access method will be stored and returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_InfoAccess_GetMethod(
- PKIX_PL_InfoAccess *infoAccess,
- PKIX_UInt32 *pMethod,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_InfoAccess_GetLocation
- * DESCRIPTION:
- *
- * Stores the location of the Information Access from "infoAccess" and
- * returns in "pLocation".
- *
- * SubjectInfoAccess ::=
- * AccessDescription ::= SEQUENCE {
- * accessMethod OBJECT IDENTIFIER,
- * accessLocation GeneralName
- * }
- *
- * PARAMETERS:
- * "infoAccess"
- * Address of PKIX_PL_InfoAccess that has the access data.
- * Must be non-NULL.
- * "pLocation"
- * Address where access location will be stored and returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_InfoAccess_GetLocation(
- PKIX_PL_InfoAccess *infoAccess,
- PKIX_PL_GeneralName **pLocation,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_InfoAccess_GetLocationType
- * DESCRIPTION:
- *
- * Stores the type of location of the Information Access from "infoAccess" and
- * returns in "pType".
- *
- * SubjectInfoAccess ::=
- * AccessDescription ::= SEQUENCE {
- * accessMethod OBJECT IDENTIFIER,
- * accessLocation GeneralName
- * }
- *
- * PARAMETERS:
- * "infoAccess"
- * Address of PKIX_PL_InfoAccess that has the access data.
- * Must be non-NULL.
- * "pType"
- * Address where access location type will be stored and returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_InfoAccess_GetLocationType(
- PKIX_PL_InfoAccess *infoAccess,
- PKIX_UInt32 *pType,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_InfoAccess_GetAIACerts(
- PKIX_PL_InfoAccess *ia,
- void **pNBIOContext,
- void **pHandle,
- PKIX_List **pCerts,
- void *plContext);
-
-/*
- * CRL
- *
- * A CRL represents an X.509 certificate revocation list. It can be created
- * using the bytes of a valid ASN.1 DER encoding. Once created, a CRL is
- * immutable. The following functions include accessors (gettors) for the
- * various components of an X.509 CRL, as well as a function for signature
- * verification.
- */
-
-/*
- * FUNCTION: PKIX_PL_CRL_Create
- * DESCRIPTION:
- *
- * Creates a new CRL using the bytes in the ByteArray pointed to by
- * "byteArray" and stores it at "pCRL". If the bytes are not a valid ASN.1
- * DER encoding of a CRL, a PKIX_Error pointer is returned. Once created, a
- * CRL is immutable.
- *
- * CertificateList ::= SEQUENCE {
- * tbsCertList TBSCertList,
- * signatureAlgorithm AlgorithmIdentifier,
- * signatureValue BIT STRING }
- *
- * TBSCertList ::= SEQUENCE {
- * version Version OPTIONAL,
- * -- if present, MUST be v2
- * signature AlgorithmIdentifier,
- * issuer Name,
- * thisUpdate Time,
- * nextUpdate Time OPTIONAL,
- * revokedCertificates SEQUENCE OF SEQUENCE {
- * userCertificate CertificateSerialNumber,
- * revocationDate Time,
- * crlEntryExtensions Extensions OPTIONAL
- * -- if present, MUST be v2
- * } OPTIONAL,
- * crlExtensions [0] EXPLICIT Extensions OPTIONAL
- * -- if present, MUST be v2
- * }
- *
- * PARAMETERS:
- * "byteArray"
- * Address of ByteArray representing the CRL's DER encoding.
- * Must be non-NULL.
- * "pCRL"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRL_Create(
- PKIX_PL_ByteArray *byteArray,
- PKIX_PL_CRL **pCRL,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CRL_GetIssuer
- * DESCRIPTION:
- *
- * Retrieves a pointer to the X500Name that represents the issuer of the CRL
- * pointed to by "crl" and stores it at "pCRLIssuer".
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose issuer is to be stored. Must be non-NULL.
- * "pCRLIssuer"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRL_GetIssuer(
- PKIX_PL_CRL *crl,
- PKIX_PL_X500Name **pCRLIssuer,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CRL_GetCriticalExtensionOIDs
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of OIDs (each OID corresponding to a
- * critical extension of the CRL pointed to by "crl") and stores it at
- * "pExtensions". If "crl" does not have any critical extensions, this
- * function stores an empty List at "pExtensions".
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose critical extension OIDs are to be stored.
- * Must be non-NULL.
- * "pExtensions"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRL_GetCriticalExtensionOIDs(
- PKIX_PL_CRL *crl,
- PKIX_List **pExtensions, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CRL_GetCRLEntryForSerialNumber
- * DESCRIPTION:
- *
- * Retrieves a pointer to the CRLEntry (found in the CRL pointed to by "crl")
- * corresponding to the BigInt pointed to by "serialNumber" and stores it at
- * "pCRLEntry". If there is no such CRLEntry, this functions stores NULL at
- * "pCRLEntry". Once created, a CRLEntry is immutable.
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose CRL Entries are to be searched. Must be non-NULL.
- * "serialNumber"
- * Address of BigInt representing serial number of certificate whose
- * CRLEntry is to be found. Must be non-NULL.
- * "pCRLEntry"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRL_GetCRLEntryForSerialNumber(
- PKIX_PL_CRL *crl,
- PKIX_PL_BigInt *serialNumber,
- PKIX_PL_CRLEntry **pCRLEntry,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CRL_GetCRLNumber
- * DESCRIPTION:
- * Retrieves the CRL Number from extension. This is non-critical extension.
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose version is to be stored. Must be non-NULL.
- * "pCrlNumber"
- * Address where a CRL Number will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRL_GetCRLNumber(
- PKIX_PL_CRL *crl,
- PKIX_PL_BigInt **pCrlNumber,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CRL_VerifyUpdateTime
- * DESCRIPTION:
- *
- * Checks whether the CRL pointed to by "crl" would be valid at the time
- * represented by the Date pointed to by "date" and stores the Boolean result
- * at "pResult". This check is done only when NIST policy is enforced.
- *
- * Time ::= CHOICE {
- * utcTime UTCTime,
- * generalTime GeneralizedTime }
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose validity is to be checked. Must be non-NULL.
- * "date"
- * Address of Date at which the CRL is being checked for validity.
- * Must be non-NULL.
- * "pResult"
- * Address of Boolean result. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRL_VerifyUpdateTime(
- PKIX_PL_CRL *crl,
- PKIX_PL_Date *date,
- PKIX_Boolean *pResult,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CRL_VerifySignature
- * DESCRIPTION:
- *
- * Verifies the signature on the CRL pointed to by "crl" using the PublicKey
- * pointed to by "pubKey". If the signature doesn't verify, a PKIX_Error
- * pointer is returned.
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose signature is to be verified. Must be non-NULL.
- * "pubKey"
- * Address of a Public Key used to verify the signature. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRL_VerifySignature(
- PKIX_PL_CRL *crl,
- PKIX_PL_PublicKey *pubKey,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CRL_ReleaseDerCrl
- * DESCRIPTION:
- *
- * Relinguish the ownership for the crl der. The operation will succeed if
- * a crl owns the der. If the crl was created from existing crl and does not
- * own the der, then the function will return null.
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose signature is to be verified. Must be non-NULL.
- * "derCrl"
- * Pointer to a SECItem that has der crl.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRL_ReleaseDerCrl(PKIX_PL_CRL *crl,
- SECItem **derCrl,
- void *plContext);
-/*
- * FUNCTION: PKIX_PL_CRL_AdoptDerCrl
- * DESCRIPTION:
- *
- * Adopt memory of the der. The secItem that contains der will be
- * freed with destruction of parent pkix crl structure.
- *
- * * PARAMETERS:
- * "crl"
- * Address of CRL whose signature is to be verified. Must be non-NULL.
- * "derCrl"
- * Pointer to a SECItem that has der crl.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRL_AdoptDerCrl(PKIX_PL_CRL *crl,
- SECItem *derCrl,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CRLEntry_GetCRLEntryReasonCode
- * DESCRIPTION:
- *
- * Retrieves the value of the reason code extension of the CRLEntry pointed
- * to by "crlEntry" and stores it at "pReason". If the "crlEntry" has no
- * reason code extension, this function stores -1 at "pReason".
- *
- * CRLReason ::= ENUMERATED {
- * unspecified (0),
- * keyCompromise (1),
- * cACompromise (2),
- * affiliationChanged (3),
- * superseded (4),
- * cessationOfOperation (5),
- * certificateHold (6),
- * removeFromCRL (8),
- * privilegeWithdrawn (9),
- * aACompromise (10) }
- *
- * PARAMETERS:
- * "crlEntry"
- * Address of CRLEntry whose reason code bit values are to be returned
- * at "pReason". Must be non-NULL.
- * "pReason"
- * Address of PKIX_Int32 where reason code is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRLEntry_GetCRLEntryReasonCode(
- PKIX_PL_CRLEntry *crlEntry,
- PKIX_Int32 *pReason,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_CRLEntry_GetCriticalExtensionOIDs
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of OIDs (each OID corresponding to a
- * critical extension of the CRLEntry pointed to by "crlEntry") and stores it
- * at "pExtensions". If "crlEntry" does not have any critical extensions, this
- * function stores an empty List at "pExtensions".
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "crlEntry"
- * Address of CRLEntry whose critical extension OIDs are to be stored.
- * Must be non-NULL.
- * "pExtensions"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CRLEntry_GetCriticalExtensionOIDs(
- PKIX_PL_CRLEntry *crlEntry,
- PKIX_List **pExtensions, /* list of PKIX_PL_OID */
- void *plContext);
-
-#ifdef BUILD_LIBPKIX_TESTS
-/*
- * FUNCTION: PKIX_PL_X500Name_Create
- * DESCRIPTION:
- *
- * Creates a new X500Name using the UTF8 string representation pointed to by
- * "stringRep" and stores it at "pName". Once created, an X500Name is
- * immutable.
- *
- * Name ::= CHOICE {
- * RDNSequence }
- *
- * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
- *
- * RelativeDistinguishedName ::=
- * SET OF AttributeTypeAndValue
- *
- * AttributeTypeAndValue ::= SEQUENCE {
- * type AttributeType,
- * value AttributeValue }
- *
- * AttributeType ::= OBJECT IDENTIFIER
- *
- * AttributeValue ::= ANY DEFINED BY AttributeType
- *
- * DirectoryString ::= CHOICE {
- * teletexString TeletexString (SIZE (1..MAX)),
- * printableString PrintableString (SIZE (1..MAX)),
- * universalString UniversalString (SIZE (1..MAX)),
- * utf8String UTF8String (SIZE (1..MAX)),
- * bmpString BMPString (SIZE (1..MAX)) }
- *
- * PARAMETERS:
- * "stringRep"
- * Address of UTF8 String representation of X500Name. Must be non-NULL.
- * "pName"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an X500Name Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_X500Name_Create (
- PKIX_PL_String *stringRep,
- PKIX_PL_X500Name **pName,
- void *plContext);
-
-#endif /* BUILD_LIBPKIX_TESTS */
-
-/*
- * FUNCTION: PKIX_PL_X500Name_CreateFromCERTName
- * DESCRIPTION:
- *
- * The function creates x500Name using der encoded DN and/or pointer to
- * CERTName. If arument "name" is NULL, but derName is supplied when
- * the function generates nssDN(CERTName type) from der data. If derName
- * is not supplied, CERTName *name will not be used to generate DN DER
- * encoding.
- *
- * PARAMETERS:
- * "derName"
- * Address of DER representation of X500Name. Can be NULL
- * "name"
- * Address of CERTName representation of X500Name. Can be NULL
- * "pName"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an X500Name Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_X500Name_CreateFromCERTName(
- SECItem *derName,
- CERTName *name,
- PKIX_PL_X500Name **pName,
- void *plContext);
-
-
-/*
- * TYPE: PKIX_PL_X500Name_Match
- * DESCRIPTION:
- * Checks whether the X500Name pointed to by "firstX500Name" MATCHES the
- * X500Name pointed to by "secondX500Name" and stores the boolean result at
- * "pResult". Two X500Names MATCH if they meet the conditions specified by
- * RFC 3280 (section 4.1.2.4). Namely:
- *
- * "This specification requires only a subset of the name comparison
- * functionality specified in the X.500 series of specifications.
- * Conforming implementations are REQUIRED to implement the following
- * name comparison rules:
- *
- * (a) attribute values encoded in different types (e.g., PrintableString
- * and BMPString) MAY be assumed to represent different strings;
- *
- * (b) attribute values in types other than PrintableString are case
- * sensitive (this permits matching of attribute values as binary objects)
- *
- * (c) attribute values in PrintableString are not case sensitive
- * (e.g., "Marianne Swanson" is the same as "MARIANNE SWANSON"); and
- *
- * (d) attribute values in PrintableString are compared after removing
- * leading and trailing white space and converting internal substrings of
- * one or more consecutive white space characters to a single space."
- *
- * PARAMETERS:
- * "firstX500Name"
- * Address of first X500Name to compare. Must be non-NULL.
- * "secondX500Name"
- * Address of second X500Name to compare. Must be non-NULL.
- * "pResult"
- * Address of Boolean result. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an X500Name Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_X500Name_Match(
- PKIX_PL_X500Name *firstX500Name,
- PKIX_PL_X500Name *secondX500Name,
- PKIX_Boolean *pResult,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Date_Create_UTCTime
- * DESCRIPTION:
- * Creates a new Date of type UTCTime using the string representation pointed
- * to by "stringRep" and stores it at "pDate". The UTCTime restriction means
- * that the year can only be specified by the least significant two digits
- * (YY). As such, Only the years 1950-2049 can be represented. If "stringRep"
- * is NULL, this function creates a new Date representing the current time
- * and stores it at "pDate". Once created, a Date is immutable.
- *
- * If YY is greater than or equal to 50, the year is interpreted as 19YY.
- * If YY is less than 50, the year is interpreted as 20YY.
- *
- * The string representation of the date must be in the following form:
- * "YYMMDDhhmmssZ" where:
- *
- * YY is the least significant two digits of the year
- * MM is the month (01 to 12)
- * DD is the day (01 to 31)
- * hh is the hour (00 to 23)
- * mm are the minutes (00 to 59)
- * ss are the seconds (00 to 59)
- * Z indicates that local time is GMT
- *
- * PARAMETERS:
- * "stringRep"
- * Address of String representation of Date.
- * If NULL, current time is used.
- * "pDate"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Date Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Date_Create_UTCTime (
- PKIX_PL_String *stringRep,
- PKIX_PL_Date **pDate,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Date_Create_UTCTime
- * DESCRIPTION:
- * Creates a new Date from PRTime data.
- *
- * PARAMETERS:
- * "time"
- * Represented time in PRTime type.
- * "pDate"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Date Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Date_CreateFromPRTime(
- PRTime time,
- PKIX_PL_Date **pDate,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Date_Create_CurrentOffBySeconds
- * DESCRIPTION:
- * Creates a new Date of type UTCTime for current time with seconds off by
- * "secondsOffset" and returns it at "pDate".
- *
- * PARAMETERS:
- * "secondsOffset"
- * A PKIX_Int32 indicates the time offset from current. If "secondsOffset"
- * is negative, the time is in past.
- * "pDate"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Date Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Date_Create_CurrentOffBySeconds(
- PKIX_Int32 secondsOffset,
- PKIX_PL_Date **pDate,
- void *plContext);
-
-#ifdef BUILD_LIBPKIX_TESTS
-/*
- * FUNCTION: PKIX_PL_GeneralName_Create
- * DESCRIPTION:
- *
- * Creates a new GeneralName of type "nameType" using the string
- * representation pointed to by "stringRep" and stores it at "pGName".
- * All of the GeneralName type format values specified in pkixt.h are
- * supported, with the exception of PKIX_OTHER_NAME, PKIX_EDIPARTY_NAME,
- * PKIX_IP_NAME, and PKIX_X400_ADDRESS. A PKIX_ESCASCII string representation
- * should be used for all supported nameTypes, with the exception of
- * registeredID and directoryName. For registeredID, the string representation
- * should be the same as that used by PKIX_PL_OID_Create. For directoryName,
- * the string representation should be the same as that used by
- * PKIX_PL_X500Name_Create. If an unsupported name type is used, an Error is
- * returned. Once created, a GeneralName is immutable.
- *
- * GeneralName ::= CHOICE {
- * otherName [0] OtherName,
- * rfc822Name [1] IA5String,
- * dNSName [2] IA5String,
- * x400Address [3] ORAddress,
- * directoryName [4] Name,
- * ediPartyName [5] EDIPartyName,
- * uniformResourceIdentifier [6] IA5String,
- * iPAddress [7] OCTET STRING,
- * registeredID [8] OBJECT IDENTIFIER }
- *
- *
- * NOTE: This function is allowed to be called only by pkix tests programs.
- *
- * PARAMETERS:
- * "nameType"
- * Type of GeneralName to be created. This must be one of the GeneralName
- * type format values specified in pkixt.h
- * "stringRep"
- * Address of String representation of GeneralName. Must be non-NULL.
- * "pGName"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a GeneralName Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_GeneralName_Create (
- PKIX_UInt32 nameType,
- PKIX_PL_String *stringRep,
- PKIX_PL_GeneralName **pGName,
- void *plContext);
-#endif /* BUILD_LIBPKIX_TESTS */
-
-/*
- * FUNCTION: PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
- * DESCRIPTION:
- *
- * This function checks whether names in "nameList" comply with
- * "nameConstraints". It stores PKIX_TRUE at "pCheckPass" if the names meet the
- * requirement of the NameConstraints, PKIX_FALSE otherwise.
- *
- * PARAMETERS
- * "nameList"
- * List of GeneralNames that are checked for compliance. May be empty
- * or NULL.
- * "nameConstraints"
- * Address of CertNameConstraints that provides lists of permitted
- * and excluded names. Must be non-NULL.
- * "pCheckPass"
- * Address where PKIX_TRUE is returned if the all names in "nameList" are
- * valid. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CertNameConstraints_CheckNamesInNameSpace(
- PKIX_List *nameList, /* List of PKIX_PL_GeneralName */
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_Boolean *pCheckPass,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_AIAMgr_Create
- * DESCRIPTION:
- *
- * This function creates an AIAMgr to handle retrieval of Certs and CRLs
- * from servers given by AIA Certificate extensions. It manages connections
- * and caches. The manager created is stored at "pAIAMgr".
- *
- * PARAMETERS:
- * "pAIAMgr"
- * The address at which the result is stored. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an AIAMgr Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_AIAMgr_Create(
- PKIX_PL_AIAMgr **pAIAMgr,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_AIAMgr_GetAIACerts
- * DESCRIPTION:
- *
- * This function uses the AIAMgr pointed to by "aiaMgr" to retrieve the Certs
- * specified by an AIA certificate extension, if any, in the Cert pointed to by
- * "prevCert", storing the results at "pCerts". If the certificate has no such
- * extension, this function stores NULL at "pCerts".
- *
- * If the request is suspended for non-blocking I/O, a platform-dependent
- * context is stored at "pNBIOContext" and NULL is stored at "pCerts". This
- * return is referred to as the WOULDBLOCK state. Note that the caller must
- * check for a non-NULL value at "pNBIOContext", to distinguish this state from
- * the "no such extension" return described in the first paragraph. (The
- * alternative would be to return an empty List, but it seemed wrong to incur
- * the overhead of creating and destroying an empty List for the most common
- * situation.)
- *
- * After a WOULDBLOCK return, the user may continue the operation by calling
- * pkix_AIAMgr_GetAIACerts (possibly more than once, if the function again
- * returns in the WOULDBLOCK state) with the previously-returned non-NULL
- * value of "pNBIOContext". When results are complete, NULL is stored at
- * "pNBIOContext", and the results (which may be NULL) are stored at "pCerts".
- *
- * PARAMETERS:
- * "aiaMgr"
- * The AIAMgr which controls the retrieval of certificates. Must be
- * non-NULL.
- * "prevCert"
- * Address of PKIX_PL_Cert which may provide an AIA or SIA extension. Must
- * be non-NULL.
- * "pNBIOContext"
- * Address at which platform-dependent information is returned if request
- * is suspended for non-blocking I/O. Must be non-NULL.
- * "pCerts"
- * Address at which the returned List is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an AIAMgr Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_AIAMgr_GetAIACerts(
- PKIX_PL_AIAMgr *aiaMgr,
- PKIX_PL_Cert *prevCert,
- void **pNBIOContext,
- PKIX_List **pCerts,
- void *plContext);
-
-typedef PKIX_Error *
-(*PKIX_PL_VerifyCallback)(
- PKIX_PL_Object *signedObject,
- PKIX_PL_Cert *signerCert, /* can be unknown */
- PKIX_PL_Date *producedAt,
- PKIX_ProcessingParams *procParams,
- void **pNBIOContext,
- void **pState,
- PKIX_BuildResult **pBuildResult,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_PKI_H */
diff --git a/security/nss/lib/libpkix/include/pkix_pl_system.h b/security/nss/lib/libpkix/include/pkix_pl_system.h
deleted file mode 100755
index 57d5df7cc..000000000
--- a/security/nss/lib/libpkix/include/pkix_pl_system.h
+++ /dev/null
@@ -1,1545 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines several platform independent functions to make system
- * calls in a portable manner.
- *
- */
-
-#ifndef _PKIX_PL_SYSTEM_H
-#define _PKIX_PL_SYSTEM_H
-
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/*
- * FUNCTION: PKIX_PL_Initialize
- * DESCRIPTION:
- *
- * XXX If this function is really only meant to be used by PKIX_Initialize,
- * why don't we just put it in a private header file rather than the public
- * API. I think it may confuse users.
- *
- * This function should NOT be called by applications. It is only meant to
- * be used internally. The application needs only to call PKIX_Initialize,
- * which in turn will call this function.
- *
- * This function initializes data structures critical to the operation of
- * libpkix. If initialization is not successful, an Error pointer is
- * returned. This function should only be called once. If it is called more
- * than once, the behavior is undefined.
- *
- * No PKIX_* types and functions should be used before this function is
- * called and returns successfully.
- *
- * PARAMETERS:
- * "platformInitNeeded"
- * Boolean indicating whether platform initialization is to be called
- * "useArenas"
- * Boolean indicating whether allocation is to be done using arenas or
- * individual allocation (malloc).
- * "pPlContext"
- * Address at which platform-specific context pointer is stored. Must be
- * non-NULL.
- * THREAD SAFETY:
- * Not Thread Safe
- *
- * This function assumes that no other thread is calling this function while
- * it is executing.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Initialize(
- PKIX_Boolean platformInitNeeded,
- PKIX_Boolean useArenas,
- void **pPlContext);
-
-/*
- * FUNCTION: PKIX_PL_Shutdown
- * DESCRIPTION:
- *
- * XXX If this function is really only meant to be used by PKIX_Shutdown,
- * why don't we just put it in a private header file rather than the public
- * API. I think it may confuse users.
- *
- * This function should NOT be called by applications. It is only meant to
- * be used internally. The application needs only to call PKIX_Shutdown,
- * which in turn will call this function.
- *
- * This function deallocates any memory used by the Portability Layer (PL)
- * component of the libpkix library and shuts down any ongoing operations.
- * This function should only be called once. If it is called more than once,
- * the behavior is undefined.
- *
- * No PKIX_* types and functions should be used after this function is called
- * and returns successfully.
- *
- * PARAMETERS:
- * "platformInitNeeded"
- * Boolean value of whether PKIX initialized NSS: PKIX_TRUE if we
- * called nssInit, PKIX_FALSE otherwise
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe
- *
- * This function makes use of global variables and should only be called once.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Shutdown(void *plContext);
-
-/* standard memory management operations (not reference-counted) */
-
-/*
- * FUNCTION: PKIX_PL_Malloc
- * DESCRIPTION:
- *
- * Allocates a block of "size" bytes. The bytes are not initialized. A
- * pointer to the newly allocated memory will be stored at "pMemory". The
- * memory allocated by PKIX_PL_Malloc() may only be freed by PKIX_PL_Free().
- * If "size" equals zero, this function stores NULL at "pMemory".
- *
- * PARAMETERS:
- * "size"
- * Number of bytes to allocate.
- * "pMemory"
- * Address where newly allocated pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread safety depends on underlying thread safety of platform used by PL.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Malloc(
- PKIX_UInt32 size,
- void **pMemory,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Calloc
- * DESCRIPTION:
- *
- * Allocates memory for an array of "nElem" elements, with each element
- * requiring "elSize" bytes, and with all the bits initialized to zero. A
- * pointer to the newly allocated memory will be stored at "pMemory". The
- * memory allocated by PKIX_PL_Calloc() may only be freed by PKIX_PL_Free().
- * If "nElem" equals zero or "elSize" equals zero, this function stores NULL
- * at "pMemory".
- *
- * PARAMETERS:
- * "nElem"
- * Number of elements needed.
- * "elSize"
- * Number of bytes needed per element.
- * "pMemory"
- * Address where newly allocated pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread safety depends on underlying thread safety of platform used by PL.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Calloc(
- PKIX_UInt32 nElem,
- PKIX_UInt32 elSize,
- void **pMemory,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Realloc
- * DESCRIPTION:
- *
- * Resizes an existing block of memory (pointed to by "ptr") to "size" bytes.
- * Stores a pointer to the resized memory at "pNewPtr". The "ptr" must
- * originate from either PKIX_PL_Malloc(), PKIX_PL_Realloc(), or
- * PKIX_PL_Calloc(). If "ptr" is NULL, this function behaves as if
- * PKIX_PL_Malloc were called. If "ptr" is not NULL and "size" equals zero,
- * the memory pointed to by "ptr" is deallocated and this function stores
- * NULL at "pPtr".
- *
- * PARAMETERS:
- * "ptr"
- * A pointer to an existing block of memory.
- * "size"
- * New size in bytes.
- * "pPtr"
- * Address where newly allocated pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread safety depends on underlying thread safety of platform used by PL.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Realloc(
- void *ptr,
- PKIX_UInt32 size,
- void **pNewPtr,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Free
- * DESCRIPTION:
- *
- * Frees a block of memory pointed to by "ptr". This value must originate with
- * either PKIX_PL_Malloc(), PKIX_PL_Calloc, or PKIX_PL_Realloc(). If "ptr" is
- * NULL, the function has no effect.
- *
- * PARAMETERS:
- * "ptr"
- * A pointer to an existing block of memory.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread safety depends on underlying thread safety of platform used by PL.
- * RETURNS:
- * Returns NULL always.
- */
-PKIX_Error *
-PKIX_PL_Free(
- void *ptr,
- void *plContext);
-
-/* Callback Types
- *
- * The next few typedefs define function pointer types for the standard
- * functions associated with every object type. See the Implementation
- * Guidelines or the comments below for more information.
- */
-
-/*
- * TYPE: PKIX_PL_DestructorCallback
- * DESCRIPTION:
- *
- * This callback function destroys (or DecRef's) any pointers contained in
- * the user data for the Object pointed to by "object" before the Object is
- * destroyed.
- *
- * PARAMETERS:
- * "object"
- * Address of Object to destroy. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts (as long as they're not operating on the same
- * object and nobody else is performing an operation on the object at the
- * same time). Both of these conditions should be guaranteed by the fact that
- * the object's ref count was reduced to 0 in a lock that's still held when
- * this callback is called.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_PL_DestructorCallback)(
- PKIX_PL_Object *object,
- void *plContext);
-
-/*
- * TYPE: PKIX_PL_EqualsCallback
- * DESCRIPTION:
- *
- * This callback function compares the Object pointed to by "firstObject" with
- * the Object pointed to by "secondObject" for equality and stores the result
- * at "pResult" (PKIX_TRUE if equal; PKIX_FALSE if not).
- *
- * PARAMETERS:
- * "firstObject"
- * Address of first object to compare. Must be non-NULL.
- * "secondObject"
- * Address of second object to compare. Must be non-NULL.
- * "pResult"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same objects.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_PL_EqualsCallback)(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext);
-
-/*
- * TYPE: PKIX_PL_HashcodeCallback
- * DESCRIPTION:
- *
- * This callback function computes the hashcode of the Object pointed to by
- * "object" and stores the result at "pValue".
- *
- * PARAMETERS:
- * "object"
- * Address of Object whose hashcode is desired. Must be non-NULL.
- * "pValue"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_PL_HashcodeCallback)(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pValue,
- void *plContext);
-
-/*
- * TYPE: PKIX_PL_ToStringCallback
- * DESCRIPTION:
- *
- * This callback function converts the Object pointed to by "object" to a
- * string representation and stores the result at "pString".
- *
- * PARAMETERS:
- * "object"
- * Object to get a string representation from. Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_PL_ToStringCallback)(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext);
-
-/*
- * TYPE: PKIX_PL_ComparatorCallback
- * DESCRIPTION:
- *
- * This callback function determines how the Object pointed to by
- * "firstObject" compares to the Object pointed to by "secondObject" and
- * stores the result at "pResult".
- *
- * Result is less than 0 if firstObject < secondObject
- * Result equals 0 if firstObject = secondObject
- * Result is greater than 0 if firstObject > secondObject
- *
- * PARAMETERS:
- * "firstObject"
- * Address of the first Object to compare. Must be non-NULL.
- * "secondObject"
- * Address of the second Object to compare. Must be non-NULL.
- * "pResult"
- * Address where PKIX_Int32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same objects.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_PL_ComparatorCallback)(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext);
-
-/*
- * TYPE: PKIX_PL_DuplicateCallback
- * DESCRIPTION:
- *
- * This callback function creates a copy of the Object pointed to by "object"
- * and stores it at "pNewObject". Changes to the copy will not affect the
- * original and vice versa.
- *
- * Note that if "object" is immutable, the Duplicate callback function simply
- * needs to increment the reference count on "object" and return a reference
- * to "object".
- *
- * PARAMETERS:
- * "object"
- * Address of the object to be copied. Must be non-NULL.
- * "pNewObject"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_PL_DuplicateCallback)(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext);
-
-/* reference-counted objects */
-
-/*
- * FUNCTION: PKIX_PL_Object_Alloc
- * DESCRIPTION:
- *
- * Allocates a new Object of type "type" with "size" bytes and stores the
- * resulting pointer at "pObject". The reference count of the newly
- * allocated object will be initialized to 1. To improve performance, each
- * object maintains a small cache for the results of Hashcode and ToString.
- * Mutable objects should call InvalidateCache whenever changes are made to
- * the object's state (after creation). If an error occurs during allocation,
- * "pObject" will be set to NULL. If "size" equals zero, this function creates
- * an Object with a reference count of 1, and places a pointer to unallocated
- * memory at "pMemory".
- *
- * PARAMETERS:
- * "type"
- * The type code of this object. See pkixt.h for codes. The type code
- * must be previously registered with PKIX_PL_Object_RegisterType().
- * "size"
- * The number of bytes needed for this object.
- * "pMemory"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_Alloc(
- PKIX_TYPENUM type,
- PKIX_UInt32 size,
- PKIX_PL_Object **pObject,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_IsTypeRegistered
- * DESCRIPTION:
- *
- * Checks whether "type" has been registered by a previous call to
- * PKIX_PL_Object_RegisterType() and stores the Boolean result at "pBool".
- * This function will typically only be called by constructors for specific
- * types.
- *
- * PARAMETERS:
- * "type"
- * The type code to check if valid.
- * "pBool"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_IsTypeRegistered(
- PKIX_UInt32 type,
- PKIX_Boolean *pBool,
- void *plContext);
-
-#ifdef PKIX_USER_OBJECT_TYPE
-/*
- * FUNCTION: PKIX_PL_Object_RegisterType
- * DESCRIPTION:
- *
- * Registers a new Object with type value "type" and associates it with a set
- * of functions ("destructor", "equalsFunction", "hashcodeFunction",
- * "toStringFunction", "comparator", "duplicateFunction"). The new type value
- * is also associated with a string pointed to by "description", which is used
- * by the default ToStringCallback. This function may only be called with a
- * particular "type" value once. If "destructor", "equalsFunction",
- * "hashcodeFunction", or "toStringFunction" are NULL, default functions will
- * be registered. However, if "comparator" and "duplicateFunction" are NULL,
- * no functions will be registered and calls to PKIX_PL_Object_Compare and
- * PKIX_PL_Object_Duplicate will result in an error.
- *
- * PARAMETERS:
- * "type"
- * The type code.
- * "description"
- * The string used by the default ToStringCallback. Default used if NULL.
- * "destructor"
- * The DestructorCallback function to be set. Default used if NULL.
- * "equalsFunction"
- * The EqualsCallback function to be set. Default used if NULL.
- * "hashcodeFunction"
- * The HashcodeCallback function to be set. Default used if NULL.
- * "toStringFunction"
- * The ToStringCallback function to be set. Default used if NULL.
- * "comparator"
- * The ComparatorCallback function to be set. None set if NULL. If no
- * callback function is set in this field, calls to
- * PKIX_PL_Object_Compare() will result in an error.
- * "duplicateFunction"
- * The DuplicateCallback function to be set. None set if NULL. If no
- * callback function is set in this field, calls to
- * PKIX_PL_Object_Duplicate() will result in an error.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if "type" is already registered.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_RegisterType(
- PKIX_UInt32 type,
- char *description,
- PKIX_PL_DestructorCallback destructor,
- PKIX_PL_EqualsCallback equalsFunction,
- PKIX_PL_HashcodeCallback hashcodeFunction,
- PKIX_PL_ToStringCallback toStringFunction,
- PKIX_PL_ComparatorCallback comparator,
- PKIX_PL_DuplicateCallback duplicateFunction,
- void *plContext);
-
-#endif
-/*
- * FUNCTION: PKIX_PL_Object_InvalidateCache
- * DESCRIPTION:
- *
- * Invalidates the cache of the Object pointed to by "object". The cache
- * contains results of Hashcode and ToString. This function should be used by
- * mutable objects whenever changes are made to the Object's state (after
- * creation).
- *
- * For example, if ToString is called on a mutable Object, the result will be
- * computed, cached, and returned. If the Object's state does not change, a
- * subsequent call to ToString will recognize that the relevant result is
- * cached and will simply return the result (without calling the Object's
- * ToStringCallback to recompute it). However, when the Object's state
- * changes, the cache needs to be invalidated in order to force a subsequent
- * call to ToString to recompute the result.
- *
- * PARAMETERS:
- * "object"
- * Address of Object whose cache is to be invalidated. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY
- * Thread Safe - Object Type Table is locked during modification.
- *
- * Multiple threads can safely call this function without worrying about
- * conflicts, even if they're operating on the same object.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_InvalidateCache(
- PKIX_PL_Object *object,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_IncRef
- * DESCRIPTION:
- *
- * Increments the reference count of the Object pointed to by "object".
- *
- * PARAMETERS:
- * "object"
- * Address of Object whose reference count is to be incremented.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_IncRef(
- PKIX_PL_Object *object,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_DecRef
- * DESCRIPTION:
- *
- * Decrements the reference count of the Object pointed to by "object". If the
- * resulting reference count is zero, the destructor (if any) registered for
- * the Object's type (by PKIX_PL_RegisterType) will be called and then the
- * Object will be destroyed.
- *
- * PARAMETERS:
- * "object"
- * Address of Object whose reference count is to be decremented.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * If destructor is not called, multiple threads can safely call this function
- * without worrying about conflicts, even if they're operating on the same
- * object. If destructor is called, thread safety depends on the callback
- * defined by PKIX_PL_RegisterType().
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_DecRef(
- PKIX_PL_Object *object,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_Equals
- * DESCRIPTION:
- *
- * Compares the Object pointed to by "firstObject" with the Object pointed to
- * by "secondObject" for equality using the callback function registered for
- * "firstObject"'s type, and stores the Boolean result at "pResult". While
- * typical callbacks will return PKIX_FALSE if the objects are of different
- * types, other callbacks may be capable of comparing objects of different
- * types [which may correctly result in cases where Equals(first, second)
- * differs from Equals(second, first)].
- *
- * PARAMETERS:
- * "firstObject"
- * Address of the first Object to compare. Must be non-NULL.
- * The EqualsCallback for this Object will be called.
- * "secondObject"
- * Address of the second Object to compare. Must be non-NULL.
- * "pResult"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread safety depends on the callback defined by PKIX_PL_RegisterType().
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_Hashcode
- * DESCRIPTION:
- *
- * Computes a hashcode of the Object pointed to by "object" using the
- * callback registered for "object"'s type and stores it at "pValue". Two
- * objects which are equal should have the same hashcode. Once a call to
- * Hashcode has been made, the results are cached and subsequent calls to
- * Hashcode will return the cached value. For mutable objects, an
- * InvalidateCache function is provided, which should be called whenever
- * changes are made to the object's state (after creation).
- *
- * PARAMETERS:
- * "object"
- * Address of the Object whose hashcode is desired. Must be non-NULL.
- * The HashcodeCallback for this object will be called.
- * "pValue"
- * Address where PKIX_Int32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread safety depends on the callback defined by PKIX_PL_RegisterType().
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pValue,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_ToString
- * DESCRIPTION:
- *
- * Creates a string representation of the Object pointed to by "object" using
- * the callback registered for "object"'s type and stores it at "pString".
- * Once a call to ToString has been made, the results are cached and
- * subsequent calls to ToString will return the cached value. For mutable
- * objects, an InvalidateCache function is provided, which should be called
- * whenever changes are made to the object's state (after creation).
- *
- * PARAMETERS:
- * "object"
- * Address of Object whose string representation is desired.
- * Must be non-NULL. The ToStringCallback for this object will be called.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread safety depends on the callback defined by PKIX_PL_RegisterType().
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_Compare
- * DESCRIPTION:
- *
- * Compares the Object pointed to by "firstObject" and the Object pointed to
- * by "secondObject" using the comparator registered for "firstObject"'s type
- * and stores the result at "pResult". Different types may be compared. This
- * may correctly result in cases where Compare(first, second) is not the
- * opposite of Compare(second, first). The PKIX_Int32 value stored at
- * "pResult" will be:
- * Less than 0 if "firstObject" < "secondObject"
- * Equals to 0 if "firstObject" = "secondObject"
- * Greater than 0 if "firstObject" > "secondObject"
- *
- * PARAMETERS:
- * "firstObject"
- * Address of first Object to compare. Must be non-NULL.
- * The ComparatorCallback for this object will be called.
- * "secondObject"
- * Address of second object to compare. Must be non-NULL.
- * "pResult
- * Address where PKIX_Int32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread safety depends on the comparator defined by PKIX_PL_RegisterType().
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_Compare(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_Duplicate
- * DESCRIPTION:
- *
- * Creates a duplicate copy of the Object pointed to by "object" using the
- * callback registered for "object"'s type and stores the copy at
- * "pNewObject". Changes to the new object will not affect the original and
- * vice versa.
- *
- * Note that if "object" is immutable, the Duplicate callback function simply
- * needs to increment the reference count on "object" and return a reference
- * to "object".
- *
- * PARAMETERS:
- * "object"
- * Address of Object to be duplicated. Must be non-NULL.
- * The DuplicateCallback for this Object will be called.
- * "pNewObject"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread safety depends on the callback defined by PKIX_PL_RegisterType().
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_GetType
- * DESCRIPTION:
- *
- * Retrieves the type code of the Object pointed to by "object" and stores it
- * at "pType". See pkixt.h for type codes.
- *
- * PARAMETERS:
- * "object"
- * Address of Object whose type is desired. Must be non-NULL.
- * "pType"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_GetType(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pType,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_Lock
- * DESCRIPTION:
- *
- * Locks the Mutex associated with the Object pointed to by "object". When an
- * object is created, it is associated with an object-specific Mutex to allow
- * for synchronization when the fields of the object are modified.
- *
- * PARAMETERS:
- * "object"
- * Address of Object whose Mutex is to be locked. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_Lock(
- PKIX_PL_Object *object,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Object_Unlock
- * DESCRIPTION:
- *
- * Unlocks the Mutex associated with the Object pointed to by "object". When
- * an object is created, it is associated with an object-specific Mutex to
- * allow for synchronization when the fields of the object are modified.
- *
- * PARAMETERS:
- * "object"
- * Address of Object whose Mutex is to be unlocked. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Object_Unlock(
- PKIX_PL_Object *object,
- void *plContext);
-
-/* mutexes (locks) */
-
-/*
- * FUNCTION: PKIX_PL_Mutex_Create
- * DESCRIPTION:
- *
- * Creates a new Mutex and stores it at "pNewLock".
- *
- * PARAMETERS:
- * "pNewLock"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Mutex_Create(
- PKIX_PL_Mutex **pNewLock,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Mutex_Lock
- * DESCRIPTION:
- *
- * Locks the Mutex pointed to by "lock". If the Mutex is already locked, this
- * function will block the current thread until the mutex can be locked by
- * this thread.
- *
- * PARAMETERS:
- * "lock"
- * Address of Mutex to lock. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Mutex_Lock(
- PKIX_PL_Mutex *lock,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Mutex_Unlock
- * DESCRIPTION:
- *
- * Unlocks the Mutex pointed to by "lock" if the current thread holds the
- * Mutex.
- *
- * PARAMETERS:
- * "lock"
- * Address of Mutex to unlock. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Mutex_Unlock(
- PKIX_PL_Mutex *lock,
- void *plContext);
-
-/* monitor (locks) */
-
-/*
- * FUNCTION: PKIX_PL_MonitorLock_Create
- * DESCRIPTION:
- *
- * Creates a new PKIX_PL_MonitorLock and stores it at "pNewLock".
- *
- * PARAMETERS:
- * "pNewLock"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_MonitorLock_Create(
- PKIX_PL_MonitorLock **pNewLock,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_MonitorLock_Enter
- * DESCRIPTION:
- *
- * Locks the MonitorLock pointed to by "lock". If the MonitorLock is already
- * locked by other thread, this function will block the current thread. If
- * the "lock" had been locked by current thread, this function will NOT block.
- *
- * PARAMETERS:
- * "lock"
- * Address of MonitorLock to lock. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_MonitorLock_Enter(
- PKIX_PL_MonitorLock *lock,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_MonitorLock_Exit
- * DESCRIPTION:
- *
- * Unlocks the MonitorLock pointed to by "lock" if the lock counter of
- * current thread holds the MonitorLock reach 0, the lock is released.
- *
- * PARAMETERS:
- * "lock"
- * Address of MonitorLock to unlock. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_MonitorLock_Exit(
- PKIX_PL_MonitorLock *lock,
- void *plContext);
-
-/* strings and formatted printing */
-
-/*
- * FUNCTION: PKIX_PL_String_Create
- * DESCRIPTION:
- *
- * Creates a new String using the data pointed to by "pString", the
- * PKIX_UInt32 pointed to by "stringLen", and the PKIX_UInt32 pointed to by
- * "fmtIndicator" and stores it at "pString". If the format is PKIX_ESCASCII
- * the "stringLen" parameter is ignored and the string extends until a zero
- * byte is found. Once created, a String object is immutable.
- *
- * Valid formats are:
- * PKIX_ESCASCII
- * PKIX_ESCASCII_DEBUG
- * PKIX_UTF8
- * PKIX_UTF8_NULL_TERM
- * PKIX_UTF16
- *
- * PARAMETERS:
- * "fmtIndicator"
- * Format that "stringRep" is encoded with. Must be non-NULL.
- * "stringRep"
- * Address of encoded string representation. Must be non-NULL.
- * "stringLen"
- * Length of data stored at stringRep.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a String Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_String_Create(
- PKIX_UInt32 fmtIndicator,
- const void *stringRep,
- PKIX_UInt32 stringLen,
- PKIX_PL_String **pString,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_Sprintf
- * DESCRIPTION:
- *
- * Creates a formatted string at "pOut" using the given format "fmt" and a
- * variable length list of arguments. The format flags are identical to
- * standard C with the exception that %s expects a PKIX_PL_String*, rather
- * than a char *, and that {%d, %i, %o, %u, %x, %X} expect PKIX_UInt32 or
- * PKIX_Int32 instead of int or unsigned int.
- *
- * PARAMETERS:
- * "pOut"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * "fmt"
- * Address of format string. Must be non-NULL.
- * THREAD SAFETY:
- * Not Thread Safe - Caller must have exclusive access to all arguments.
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a String Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Sprintf(
- PKIX_PL_String **pOut,
- void *plContext,
- const PKIX_PL_String *fmt, ...);
-
-/*
- * FUNCTION: PKIX_PL_GetString
- * DESCRIPTION:
- *
- * Retrieves the String associated with the value of "stringID" (if any) and
- * stores it at "pString". If no such string is associated with "stringID",
- * this function uses "defaultString" to create a String and stores it at
- * "pString".
- *
- * PARAMETERS:
- * "stringID"
- * PKIX_UInt32 valud of string identifier.
- * "defaultString"
- * Address of a PKIX_ESCASCII encoded string representation.
- * Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a String Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_GetString(
- PKIX_UInt32 stringID,
- char *defaultString,
- PKIX_PL_String **pString,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_String_GetEncoded
- * DESCRIPTION:
- *
- * Retrieves the value of the String pointed to by "string" in the encoding
- * specified by "fmtIndicator" and stores the result in "pStringRep" and
- * "pLength", respectively. Note that "pStringRep" is not reference counted
- * and will need to be freed with PKIX_PL_Free().
- *
- * PARAMETERS:
- * "string"
- * Address of String whose encoded value is desired. Must be non-NULL.
- * "fmtIndicator"
- * Format of encoding. Supported formats are:
- * PKIX_ESCASCII, PKIX_ESCASII_DEBUG, PKIX_UTF8, PKIX_UTF8_NULL_TERM, and
- * PKIX_UTF16. XXX Where are these documented?
- * "pStringRep"
- * Address where pointer to encoded value will be stored.
- * Must be non-NULL.
- * "pLength"
- * Address where byte length of encoded value will be stored.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a String Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_String_GetEncoded(
- PKIX_PL_String *string,
- PKIX_UInt32 fmtIndicator,
- void **pStringRep,
- PKIX_UInt32 *pLength,
- void *plContext);
-
-/*
- * Hashtable
- *
- * A hashtable is a very efficient data structure used for mapping keys to
- * values. Any non-null PKIX_PL_Object can be used as a key or as a value,
- * provided that it correctly implements the PKIX_PL_EqualsCallback and the
- * PKIX_PL_HashcodeCallback. A hashtable consists of several buckets, with
- * each bucket capable of holding a linked list of key/value mappings. When
- * adding, retrieving, or deleting a value, the hashcode of the key is used to
- * determine which bucket's linked list is relevant. The corresponding
- * key/value pair is then appended, retrieved, or deleted.
- */
-
-/*
- * FUNCTION: PKIX_PL_HashTable_Create
- * DESCRIPTION:
- *
- * Creates a new Hashtable with an initial capacity of "numBuckets" buckets
- * and "maxEntriesPerBucket" of entries limit for each bucket and stores it
- * at "pResult".
- *
- * PARAMETERS:
- * "numBuckets"
- * The initial number of hash table buckets. Must be non-zero.
- * "maxEntriesPerBucket"
- * The limit of entries per bucket. Zero means no limit.
- * "pResult"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_HashTable_Create(
- PKIX_UInt32 numBuckets,
- PKIX_UInt32 maxEntriesPerBucket,
- PKIX_PL_HashTable **pResult,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_HashTable_Add
- * DESCRIPTION:
- *
- * Adds a key/value mapping using the Objects pointed to by "key" and "value"
- * to the Hashtable pointed to by "ht".
- *
- * Function increments key/value reference counts. Caller is responsible to
- * to decrement(destroy) key/value ref counts(objects).
- *
- * PARAMETERS:
- * "ht"
- * Address of Hashtable to be added to. Must be non-NULL.
- * "key"
- * Address of Object to be associated with "value". Must be non-NULL.
- * "value"
- * Address of Object to be added to Hashtable. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "ht"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Hashtable Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_HashTable_Add(
- PKIX_PL_HashTable *ht,
- PKIX_PL_Object *key,
- PKIX_PL_Object *value,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_HashTable_Remove
- * DESCRIPTION:
- *
- * Removes the Object value whose key is equal to the Object pointed to by
- * "key" from the Hashtable pointed to by "ht". If no such object exists,
- * this function throws an Error.
- *
- * Function frees "value" object. Caller is responsible to free "key"
- * object.
- *
- * PARAMETERS:
- * "ht"
- * Address of Hashtable to remove object from. Must be non-NULL.
- * "key"
- * Address of Object used for lookup. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "ht"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Hashtable Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_HashTable_Remove(
- PKIX_PL_HashTable *ht,
- PKIX_PL_Object *key,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_HashTable_Lookup
- * DESCRIPTION:
- *
- * Retrieves the Object whose key equals the Object pointed to by "key" from
- * the Hashtable associated with "ht" and stores it at "pResult". If no
- * Object is found, this function stores NULL at "pResult".
- *
- * PARAMETERS:
- * "ht"
- * Address of Hashtable to lookup Object from. Must be non-NULL.
- * "key"
- * Address of key Object used for lookup. Must be non-NULL.
- * "pResult"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Hashtable Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_HashTable_Lookup(
- PKIX_PL_HashTable *ht,
- PKIX_PL_Object *key,
- PKIX_PL_Object **pResult,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_ByteArray_Create
- * DESCRIPTION:
- *
- * Creates a new ByteArray using "length" bytes of data pointed to by "array"
- * and stores it at "pByteArray". Once created, a ByteArray is immutable.
- *
- * PARAMETERS:
- * "array"
- * Address of source data.
- * "length"
- * Number of bytes to copy.
- * "pByteArray"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_ByteArray_Create(
- void *array,
- PKIX_UInt32 length,
- PKIX_PL_ByteArray **pByteArray,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_ByteArray_GetPointer
- * DESCRIPTION:
- *
- * Allocates enough memory to hold the contents of the ByteArray pointed to
- * by "byteArray", copies the data from the ByteArray pointed to by
- * "byteArray" into the newly allocated memory, and stores a pointer to the
- * memory at "pArray". Note that "pArray" is not reference counted. It will
- * need to be freed with PKIX_PL_Free().
- *
- * PARAMETERS:
- * "byteArray"
- * Address of ByteArray whose data is desired. Must be non-NULL.
- * "pArray"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_ByteArray_GetPointer(
- PKIX_PL_ByteArray *byteArray,
- void **pArray,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_ByteArray_GetLength
- * DESCRIPTION:
- *
- * Retrieves the length of the ByteArray pointed to by "byteArray" and stores
- * the length at "pLength".
- *
- * PARAMETERS:
- * "byteArray"
- * Address of ByteArray whose length is desired. Must be non-NULL.
- * "pLength"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_ByteArray_GetLength(
- PKIX_PL_ByteArray *byteArray,
- PKIX_UInt32 *pLength,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_OID_Create
- * DESCRIPTION:
- *
- * Creates a new OID using NSS oid tag.
- *
- * PARAMETERS:
- * "idtag"
- * nss oid id tag.
- * "pOID"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OID Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_OID_Create(
- SECOidTag idtag,
- PKIX_PL_OID **pOID,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_OID_CreateBySECItem
- * DESCRIPTION:
- *
- * Creates a new OID using a DER encoded OID stored as SECItem.
- *
- * PARAMETERS:
- * "derOid"
- * Address of SECItem that holds DER encoded OID.
- * "pOID"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OID Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_OID_CreateBySECItem(
- SECItem *derOid,
- PKIX_PL_OID **pOID,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_BigInt_Create
- * DESCRIPTION:
- *
- * Creates a new BigInt using the source String pointed to by "stringRep" and
- * stores it at "pBigInt". Valid source Strings consist of an even number of
- * hexadecimal digits, which are always interpreted as a positive number.
- * Once created, a BigInt is immutable.
- *
- * The regexp format is:
- * HexDigit ::= [0-9] | [A-F] | [a-f]
- * DoubleHex ::= HexDigit HexDigit
- * BigIntSrc ::= (DoubleHex)+
- *
- * Note that since we are using DoubleHex, the number of characters in the
- * source MUST be even. Additionally, the first DoubleHex MUST NOT be "00"
- * unless it is the only DoubleHex.
- *
- * Valid : "09"
- * Valid : "00" (special case where first and only DoubleHex is "00")
- * Invalid: "9" (not DoubleHex: odd number of characters)
- * Invalid: "0009" (first DoubleHex is "00")
- *
- * XXX Why does this take a String object while OID_Create takes a char* ?
- * Perhaps because OID_Create is often used with constant strings and
- * this function isn't. That's a good reason, but we should explain it
- * (if it's right)
- * PARAMETERS:
- * "stringRep"
- * Address of String representing a BigInt. Must be non-NULL.
- * "pBigInt"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a BigInt Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_BigInt_Create(
- PKIX_PL_String *stringRep,
- PKIX_PL_BigInt **pBigInt,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-/*
- * FUNCTION: PKIX_PL_GetPLErrorCode
- * DESCRIPTION:
- *
- * Returns error code from PL layer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * PL layer error code.
- */
-int
-PKIX_PL_GetPLErrorCode();
-
-#endif /* _LIBPKIX_SYSTEM_H */
diff --git a/security/nss/lib/libpkix/include/pkix_results.h b/security/nss/lib/libpkix/include/pkix_results.h
deleted file mode 100755
index bf4a381fa..000000000
--- a/security/nss/lib/libpkix/include/pkix_results.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines functions associated with the results used
- * by the top-level functions.
- *
- */
-
-#ifndef _PKIX_RESULTS_H
-#define _PKIX_RESULTS_H
-
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-/* PKIX_ValidateResult
- *
- * PKIX_ValidateResult represents the result of a PKIX_ValidateChain call. It
- * consists of the valid policy tree and public key resulting from validation,
- * as well as the trust anchor used for this chain. Once created, a
- * ValidateResult object is immutable.
- */
-
-/*
- * FUNCTION: PKIX_ValidateResult_GetPolicyTree
- * DESCRIPTION:
- *
- * Retrieves the PolicyNode component (representing the valid_policy_tree)
- * from the ValidateResult object pointed to by "result" and stores it at
- * "pPolicyTree".
- *
- * PARAMETERS:
- * "result"
- * Address of ValidateResult whose policy tree is to be stored. Must be
- * non-NULL.
- * "pPolicyTree"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ValidateResult_GetPolicyTree(
- PKIX_ValidateResult *result,
- PKIX_PolicyNode **pPolicyTree,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ValidateResult_GetPublicKey
- * DESCRIPTION:
- *
- * Retrieves the PublicKey component (representing the valid public_key) of
- * the ValidateResult object pointed to by "result" and stores it at
- * "pPublicKey".
- *
- * PARAMETERS:
- * "result"
- * Address of ValidateResult whose public key is to be stored.
- * Must be non-NULL.
- * "pPublicKey"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ValidateResult_GetPublicKey(
- PKIX_ValidateResult *result,
- PKIX_PL_PublicKey **pPublicKey,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_ValidateResult_GetTrustAnchor
- * DESCRIPTION:
- *
- * Retrieves the TrustAnchor component (representing the trust anchor used
- * during chain validation) of the ValidateResult object pointed to by
- * "result" and stores it at "pTrustAnchor".
- *
- * PARAMETERS:
- * "result"
- * Address of ValidateResult whose trust anchor is to be stored.
- * Must be non-NULL.
- * "pTrustAnchor"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_ValidateResult_GetTrustAnchor(
- PKIX_ValidateResult *result,
- PKIX_TrustAnchor **pTrustAnchor,
- void *plContext);
-
-/* PKIX_BuildResult
- *
- * PKIX_BuildResult represents the result of a PKIX_BuildChain call. It
- * consists of a ValidateResult object, as well as the built and validated
- * CertChain. Once created, a BuildResult object is immutable.
- */
-
-/*
- * FUNCTION: PKIX_BuildResult_GetValidateResult
- * DESCRIPTION:
- *
- * Retrieves the ValidateResult component (representing the build's validate
- * result) of the BuildResult object pointed to by "result" and stores it at
- * "pResult".
- *
- * PARAMETERS:
- * "result"
- * Address of BuildResult whose ValidateResult component is to be stored.
- * Must be non-NULL.
- * "pResult"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_BuildResult_GetValidateResult(
- PKIX_BuildResult *result,
- PKIX_ValidateResult **pResult,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_BuildResult_GetCertChain
- * DESCRIPTION:
- *
- * Retrieves the List of Certs (certChain) component (representing the built
- * and validated CertChain) of the BuildResult object pointed to by "result"
- * and stores it at "pChain".
- *
- * PARAMETERS:
- * "result"
- * Address of BuildResult whose CertChain component is to be stored.
- * Must be non-NULL.
- * "pChain"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_BuildResult_GetCertChain(
- PKIX_BuildResult *result,
- PKIX_List **pChain,
- void *plContext);
-
-/* PKIX_PolicyNode
- *
- * PKIX_PolicyNode represents a node in the policy tree returned in
- * ValidateResult. The policy tree is the same length as the validated
- * certificate chain and the nodes are associated with a particular depth
- * (corresponding to a particular certificate in the chain).
- * PKIX_ValidateResult_GetPolicyTree returns the root node of the valid policy
- * tree. Other nodes can be accessed using the getChildren and getParents
- * functions, and individual elements of a node can be accessed with the
- * appropriate gettors. Once created, a PolicyNode is immutable.
- */
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetChildren
- * DESCRIPTION:
- *
- * Retrieves the List of PolicyNodes representing the child nodes of the
- * Policy Node pointed to by "node" and stores it at "pChildren". If "node"
- * has no child nodes, this function stores an empty List at "pChildren".
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode whose child nodes are to be stored.
- * Must be non-NULL.
- * "pChildren"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PolicyNode_GetChildren(
- PKIX_PolicyNode *node,
- PKIX_List **pChildren, /* list of PKIX_PolicyNode */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetParent
- * DESCRIPTION:
- *
- * Retrieves the PolicyNode representing the parent node of the PolicyNode
- * pointed to by "node" and stores it at "pParent". If "node" has no parent
- * node, this function stores NULL at "pParent".
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode whose parent node is to be stored.
- * Must be non-NULL.
- * "pParent"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PolicyNode_GetParent(
- PKIX_PolicyNode *node,
- PKIX_PolicyNode **pParent,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetValidPolicy
- * DESCRIPTION:
- *
- * Retrieves the OID representing the valid policy of the PolicyNode pointed
- * to by "node" and stores it at "pValidPolicy".
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode whose valid policy is to be stored.
- * Must be non-NULL.
- * "pValidPolicy"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PolicyNode_GetValidPolicy(
- PKIX_PolicyNode *node,
- PKIX_PL_OID **pValidPolicy,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetPolicyQualifiers
- * DESCRIPTION:
- *
- * Retrieves the List of CertPolicyQualifiers representing the policy
- * qualifiers associated with the PolicyNode pointed to by "node" and stores
- * it at "pQualifiers". If "node" has no policy qualifiers, this function
- * stores an empty List at "pQualifiers".
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode whose policy qualifiers are to be stored.
- * Must be non-NULL.
- * "pQualifiers"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PolicyNode_GetPolicyQualifiers(
- PKIX_PolicyNode *node,
- PKIX_List **pQualifiers, /* list of PKIX_PL_CertPolicyQualifier */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetExpectedPolicies
- * DESCRIPTION:
- *
- * Retrieves the List of OIDs representing the expected policies associated
- * with the PolicyNode pointed to by "node" and stores it at "pExpPolicies".
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode whose expected policies are to be stored.
- * Must be non-NULL.
- * "pExpPolicies"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PolicyNode_GetExpectedPolicies(
- PKIX_PolicyNode *node,
- PKIX_List **pExpPolicies, /* list of PKIX_PL_OID */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PolicyNode_IsCritical
- * DESCRIPTION:
- *
- * Checks the criticality field of the PolicyNode pointed to by "node" and
- * stores the Boolean result at "pCritical".
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode whose criticality field is examined.
- * Must be non-NULL.
- * "pCritical"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PolicyNode_IsCritical(
- PKIX_PolicyNode *node,
- PKIX_Boolean *pCritical,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetDepth
- * DESCRIPTION:
- *
- * Retrieves the depth component of the PolicyNode pointed to by "node" and
- * stores it at "pDepth".
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode whose depth component is to be stored.
- * Must be non-NULL.
- * "pDepth"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Result Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PolicyNode_GetDepth(
- PKIX_PolicyNode *node,
- PKIX_UInt32 *pDepth,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_RESULTS_H */
diff --git a/security/nss/lib/libpkix/include/pkix_revchecker.h b/security/nss/lib/libpkix/include/pkix_revchecker.h
deleted file mode 100755
index 9f65a8444..000000000
--- a/security/nss/lib/libpkix/include/pkix_revchecker.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines functions associated with the PKIX_RevocationChecker
- * type.
- *
- */
-
-#ifndef _PKIX_REVCHECKER_H
-#define _PKIX_REVCHECKER_H
-
-#include "pkixt.h"
-#include "pkix_pl_pki.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/* PKIX_RevocationChecker
- *
- * PKIX_RevocationChecker provides a standard way of revocation checking.
- * Caller should configure two set of tests(represented at lists of
- * RevocationMethod objects) to be performed on the leaf and on the rest of
- * the chain certificates.
- *
- * PKIX_RevocationMethods provide a standard way for the caller to insert
- * their own custom revocation checks to verify the revocation status of
- * certificates. This may be useful in many scenarios, including when the
- * caller wishes to use their own revocation checking mechanism instead of (or
- * in addition to) the default revocation checking mechanism provided by
- * libpkix, which uses CRLs and OCSP.
- *
- * Once the caller has created the RevocationMethod object(s), the caller
- * then specifies the RevocationMethod object(s) in a RevocationCheck object
- * and sets it into a ProcessingParams.
- */
-
-/*
- * FUNCTION: PKIX_RevocationChecker_Create
- * DESCRIPTION:
- *
- * Creates revocation checker object with a given flags.
- *
- * PARAMETERS:
- * "revDate"
- * Revocation will be checked at this date. Current date is taken if the
- * parameter is not specified.
- * "leafMethodListFlags"
- * Defines a set of method independent flags that will be used to check
- * revocation of the leaf cert in the chain.
- * "chainMethodListFlags"
- * Defines a set of method independent flags that will be used to check
- * revocation of the remaining certs in the chain.
- * "pChecker"
- * The return address of created checker.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same objects.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a RevocationChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_RevocationChecker_Create(
- PKIX_UInt32 leafMethodListFlags,
- PKIX_UInt32 chainMethodListFlags,
- PKIX_RevocationChecker **pChecker,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_RevocationChecker_CreateAndAddMethod
- * DESCRIPTION:
- *
- * Creates revocation method object with given parameters and adds it
- * to revocation checker method list.
- *
- * PARAMETERS:
- * "revChecker"
- * Address of revocation checker structure.
- * "procParams"
- * Address of ProcessingParams used to initialize the checker.
- * Must be non-NULL.
- * "methodType"
- * Type of the method. Currently only two types are
- * supported: crl and ocsp. (See PKIX_RevocationMethodType enum).
- * "methodFlags"
- * Set of flags for the method.
- * "methodPriority"
- * Method priority. (0 corresponds to a highest priority)
- * "verificationFn"
- * User call back function that will perform validation of fetched
- * revocation information(new crl or ocsp response)
- * "isLeafMethod"
- * Boolean flag that if set to true indicates that the method should
- * should be used for leaf cert revocation test(false for chain set
- * methods).
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same objects.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a RevocationChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_RevocationChecker_CreateAndAddMethod(
- PKIX_RevocationChecker *revChecker,
- PKIX_ProcessingParams *params,
- PKIX_RevocationMethodType methodType,
- PKIX_UInt32 methodFlags,
- PKIX_UInt32 mathodPriority,
- PKIX_PL_VerifyCallback verificationFn,
- PKIX_Boolean isLeafMethod,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_RevocationChecker_Check
- * DESCRIPTION:
- *
- * Verifies revocation status of the certificate. Issuer cert is given to
- * be used in verification of revocation information. Performed verification
- * check depends on configured revocation methods(ocsp, crl. See
- * PKIX_RevocationChecker_CreateAndAddMethod function) and a point of chain
- * building process at which PKIX_RevocationChecker_Check was invoked.
- * For security reasons, the cert status is checked only against cached
- * revocation information during chain building stage(no trust anchor yes has
- * been found). The fresh revocation information fetching is done only at chain
- * verification stage after trust anchor was identified.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert whose revocation status is to be determined.
- * Must be non-NULL.
- * "issuer"
- * Issuer cert that potentially holds public key that will be used
- * to verify revocation info.
- * "revChecker"
- * Address of revocation checker structure.
- * "procParams"
- * Address of ProcessingParams used to initialize the checker.
- * Must be non-NULL.
- * "chainVerificationState"
- * Need to be set to true, if the check was called during chain verification
- * as an opposite to chain building.
- * "testingLeafCert"
- * Set to true if verifying revocation status of a leaf cert.
- * "revStatus"
- * Address of the returned revocation status of the cert.
- * "pResultCode"
- * Address where revocation status will be stored. Must be non-NULL.
- * "pNBIOContext"
- * Address at which platform-dependent non-blocking I/O context is stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same objects.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a RevocationChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_RevocationChecker_Check(PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_RevocationChecker *revChecker,
- PKIX_ProcessingParams *procParams,
- PKIX_Boolean chainVerificationState,
- PKIX_Boolean testingLeafCert,
- PKIX_RevocationStatus *revStatus,
- PKIX_UInt32 *pReasonCode,
- void **pNbioContext,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_REVCHECKER_H */
diff --git a/security/nss/lib/libpkix/include/pkix_sample_modules.h b/security/nss/lib/libpkix/include/pkix_sample_modules.h
deleted file mode 100755
index c031a1246..000000000
--- a/security/nss/lib/libpkix/include/pkix_sample_modules.h
+++ /dev/null
@@ -1,418 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines functions associated with CertStore types.
- *
- */
-
-
-#ifndef _PKIX_SAMPLEMODULES_H
-#define _PKIX_SAMPLEMODULES_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/* PKIX_PL_CollectionCertStore
- *
- * A PKIX_CollectionCertStore provides an example for showing how to retrieve
- * certificates and CRLs from a repository, such as a directory in the system.
- * It is expected the directory is an absolute directory which contains CRL
- * and Cert data files. CRL files are expected to have the suffix of .crl
- * and Cert files are expected to have the suffix of .crt .
- *
- * Once the caller has created the CollectionCertStoreContext object, the caller
- * then can call pkix_pl_CollectionCertStore_GetCert or
- * pkix_pl_CollectionCertStore_GetCRL to obtain Lists of PKIX_PL_Cert or
- * PKIX_PL_CRL objects, respectively.
- */
-
-/*
- * FUNCTION: PKIX_PL_CollectionCertStore_Create
- * DESCRIPTION:
- *
- * Creates a new CollectionCertStore and returns it at
- * "pColCertStore".
- *
- * PARAMETERS:
- * "storeDir"
- * The absolute path where *.crl files are located.
- * "pColCertStoreContext"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CollectionCertStoreContext Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_CollectionCertStore_Create(
- PKIX_PL_String *storeDir,
- PKIX_CertStore **pCertStore,
- void *plContext);
-
-/* PKIX_PL_PK11CertStore
- *
- * A PKIX_PL_PK11CertStore retrieves certificates and CRLs from a PKCS11
- * database. The directory that contains the cert8.db, key3.db, and secmod.db
- * files that comprise a PKCS11 database are specified in NSS initialization.
- *
- * Once the caller has created the Pk11CertStore object, the caller can call
- * pkix_pl_Pk11CertStore_GetCert or pkix_pl_Pk11CertStore_GetCert to obtain
- * a List of PKIX_PL_Certs or PKIX_PL_CRL objects, respectively.
- */
-
-/*
- * FUNCTION: PKIX_PL_Pk11CertStore_Create
- * DESCRIPTION:
- *
- * Creates a new Pk11CertStore and returns it at "pPk11CertStore".
- *
- * PARAMETERS:
- * "pPk11CertStore"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_Pk11CertStore_Create(
- PKIX_CertStore **pPk11CertStore,
- void *plContext);
-
-/* PKIX_PL_LdapCertStore
- *
- * A PKIX_PL_LdapCertStore retrieves certificates and CRLs from an LDAP server
- * over a socket connection. It used the LDAP protocol as described in RFC1777.
- *
- * Once the caller has created the LdapCertStore object, the caller can call
- * pkix_pl_LdapCertStore_GetCert or pkix_pl_LdapCertStore_GetCert to obtain
- * a List of PKIX_PL_Certs or PKIX_PL_CRL objects, respectively.
- */
-
-/*
- * FUNCTION: PKIX_PL_LdapDefaultClient_Create
- * DESCRIPTION:
- *
- * Creates an LdapDefaultClient using the PRNetAddr poined to by "sockaddr",
- * with a timeout value of "timeout", and a BindAPI pointed to by "bindAPI";
- * and stores the address of the default LdapClient at "pClient".
- *
- * At the time of this version, there are unresolved questions about the LDAP
- * protocol. Although RFC1777 describes a BIND and UNBIND message, it is not
- * clear whether they are appropriate to this application. We have tested only
- * using servers that do not expect authentication, and that reject BIND
- * messages. It is not clear what values might be appropriate for the bindname
- * and authentication fields, which are currently implemented as char strings
- * supplied by the caller. (If this changes, the API and possibly the templates
- * will have to change.) Therefore the Client_Create API contains a BindAPI
- * structure, a union, which will have to be revised and extended when this
- * area of the protocol is better understood.
- *
- * PARAMETERS:
- * "sockaddr"
- * Address of the PRNetAddr to be used for the socket connection. Must be
- * non-NULL.
- * "timeout"
- * The PRIntervalTime value to be used as a timeout value in socket calls;
- * a zero value indicates non-blocking I/O is to be used.
- * "bindAPI"
- * The address of a BindAPI to be used if a BIND message is required. If
- * this argument is NULL, no Bind (or Unbind) will be sent.
- * "pClient"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_LdapDefaultClient_Create(
- PRNetAddr *sockaddr,
- PRIntervalTime timeout,
- LDAPBindAPI *bindAPI,
- PKIX_PL_LdapDefaultClient **pClient,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_LdapDefaultClient_CreateByName
- * DESCRIPTION:
- *
- * Creates an LdapDefaultClient using the hostname poined to by "hostname",
- * with a timeout value of "timeout", and a BindAPI pointed to by "bindAPI";
- * and stores the address of the default LdapClient at "pClient".
- *
- * At the time of this version, there are unresolved questions about the LDAP
- * protocol. Although RFC1777 describes a BIND and UNBIND message, it is not
- * clear whether they are appropriate to this application. We have tested only
- * using servers that do not expect authentication, and that reject BIND
- * messages. It is not clear what values might be appropriate for the bindname
- * and authentication fields, which are currently implemented as char strings
- * supplied by the caller. (If this changes, the API and possibly the templates
- * will have to change.) Therefore the Client_Create API contains a BindAPI
- * structure, a union, which will have to be revised and extended when this
- * area of the protocol is better understood.
- *
- * PARAMETERS:
- * "hostname"
- * Address of the hostname to be used for the socket connection. Must be
- * non-NULL.
- * "timeout"
- * The PRIntervalTime value to be used as a timeout value in socket calls;
- * a zero value indicates non-blocking I/O is to be used.
- * "bindAPI"
- * The address of a BindAPI to be used if a BIND message is required. If
- * this argument is NULL, no Bind (or Unbind) will be sent.
- * "pClient"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_LdapDefaultClient_CreateByName(
- char *hostname,
- PRIntervalTime timeout,
- LDAPBindAPI *bindAPI,
- PKIX_PL_LdapDefaultClient **pClient,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_LdapCertStore_Create
- * DESCRIPTION:
- *
- * Creates a new LdapCertStore using the LdapClient pointed to by "client",
- * and stores the address of the CertStore at "pCertStore".
- *
- * PARAMETERS:
- * "client"
- * Address of the LdapClient to be used. Must be non-NULL.
- * "pCertStore"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_LdapCertStore_Create(
- PKIX_PL_LdapClient *client,
- PKIX_CertStore **pCertStore,
- void *plContext);
-
-/* PKIX_PL_NssContext
- *
- * A PKIX_PL_NssContext provides an example showing how the "plContext"
- * argument, that is part of every libpkix function call, can be used.
- * The "plContext" is the Portability Layer Context, which can be used
- * to communicate layer-specific information from the application to the
- * underlying Portability Layer (while bypassing the Portable Code, which
- * blindly passes the plContext on to every function call).
- *
- * In this case, NSS serves as both the application and the Portability Layer.
- * We define an NSS-specific structure, which includes an arena and a number
- * of SECCertificateUsage bit flags encoded as a PKIX_UInt32. A third argument,
- * wincx, is used on Windows platforms for PKCS11 access, and should be set to
- * NULL for other platforms.
- * Before calling any of the libpkix functions, the caller should create the NSS
- * context, by calling PKIX_PL_NssContext_Create, and provide that NSS context
- * as the "plContext" argument in every libpkix function call the caller makes.
- * When the caller is finished using the NSS context (usually just after he
- * calls PKIX_Shutdown), the caller should call PKIX_PL_NssContext_Destroy to
- * free the NSS context structure.
- */
-
-/*
- * FUNCTION: PKIX_PL_NssContext_Create
- * DESCRIPTION:
- *
- * Creates a new NssContext using the certificate usage(s) specified by
- * "certUsage" and stores it at "pNssContext". This function also internally
- * creates an arena and stores it as part of the NssContext structure. Unlike
- * most other libpkix API functions, this function does not take a "plContext"
- * parameter.
- *
- * PARAMETERS:
- * "certUsage"
- * The desired SECCertificateUsage(s).
- * "useNssArena"
- * Boolean flag indicates NSS Arena is used for memory allocation.
- * "wincx"
- * A Windows-dependent pointer for PKCS11 token handling.
- * "pNssContext"
- * Address where object pointer will be stored. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Context Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_NssContext_Create(
- PKIX_UInt32 certificateUsage,
- PKIX_Boolean useNssArena,
- void *wincx,
- void **pNssContext);
-
-/*
- * FUNCTION: PKIX_PL_NssContext_Destroy
- * DESCRIPTION:
- *
- * Frees the structure pointed to by "nssContext" along with any of its
- * associated memory. Unlike most other libpkix API functions, this function
- * does not take a "plContext" parameter.
- *
- * PARAMETERS:
- * "nssContext"
- * Address of NssContext to be destroyed. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Context Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_NssContext_Destroy(
- void *nssContext);
-
-/*
- * FUNCTION: PKIX_PL_NssContext_SetTimeout
- * DESCRIPTION:
- *
- * Sets IO timeout for network operations like OCSP response and cert
- * fetching.
- *
- * PARAMETERS:
- * "nssContext"
- * Address of NssContext to be destroyed. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Context Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_NssContext_SetTimeout(PKIX_UInt32 timeout, PKIX_PL_NssContext *nssContext);
-
-/*
- * FUNCTION: PKIX_PL_NssContext_SetMaxResponseLen
- * DESCRIPTION:
- *
- * Sets maximum responce length allowed during network IO operations.
- *
- * PARAMETERS:
- * "nssContext"
- * Address of NssContext to be destroyed. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Context Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_NssContext_SetMaxResponseLen(PKIX_UInt32 len, PKIX_PL_NssContext *nssContext);
-
-/*
- * FUNCTION: PKIX_PL_NssContext_SetCrlReloadDelay
- * DESCRIPTION:
- *
- * Sets user defined timeout between attempts to load crl using
- * CRLDP.
- *
- * PARAMETERS:
- * "delaySeconds"
- * Reload delay in seconds.
- * "nssContext"
- * Address of NssContext to be destroyed. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Context Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_NssContext_SetCrlReloadDelay(PKIX_UInt32 delaySeconds,
- PKIX_PL_NssContext *nssContext);
-
-/*
- * FUNCTION: PKIX_PL_NssContext_SetBadDerCrlReloadDelay
- * DESCRIPTION:
- *
- * Sets user defined timeout between attempts to load crls
- * that failed to decode.
- *
- * PARAMETERS:
- * "delaySeconds"
- * Reload delay in seconds.
- * "nssContext"
- * Address of NssContext to be destroyed. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Context Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_NssContext_SetBadDerCrlReloadDelay(PKIX_UInt32 delaySeconds,
- PKIX_PL_NssContext *nssContext);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_SAMPLEMODULES_H */
diff --git a/security/nss/lib/libpkix/include/pkix_util.h b/security/nss/lib/libpkix/include/pkix_util.h
deleted file mode 100755
index e42f608c1..000000000
--- a/security/nss/lib/libpkix/include/pkix_util.h
+++ /dev/null
@@ -1,941 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * These functions provide support for a number of other functions
- * by creating and manipulating data structures used by those functions.
- *
- */
-
-#ifndef _PKIX_UTIL_H
-#define _PKIX_UTIL_H
-
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* General
- *
- * Please refer to the libpkix Programmer's Guide for detailed information
- * about how to use the libpkix library. Certain key warnings and notices from
- * that document are repeated here for emphasis.
- *
- * All identifiers in this file (and all public identifiers defined in
- * libpkix) begin with "PKIX_". Private identifiers only intended for use
- * within the library begin with "pkix_".
- *
- * A function returns NULL upon success, and a PKIX_Error pointer upon failure.
- *
- * Unless otherwise noted, for all accessor (gettor) functions that return a
- * PKIX_PL_Object pointer, callers should assume that this pointer refers to a
- * shared object. Therefore, the caller should treat this shared object as
- * read-only and should not modify this shared object. When done using the
- * shared object, the caller should release the reference to the object by
- * using the PKIX_PL_Object_DecRef function.
- *
- * While a function is executing, if its arguments (or anything referred to by
- * its arguments) are modified, free'd, or destroyed, the function's behavior
- * is undefined.
- *
- */
-
-/* PKIX_Logger
- *
- * PKIX_Loggers provide a standard way for the caller to insert custom logging
- * facilities. These are used by libpkix to log errors, debug information,
- * status, etc. The LogCallback allows custom logging to take place.
- * Additionally, a Logger can be initialized with a loggerContext, which is
- * where the caller can specify configuration data such as the name of a
- * logfile or database. Note that this loggerContext must be a PKIX_PL_Object,
- * allowing it to be reference-counted and allowing it to provide the standard
- * PKIX_PL_Object functions (Equals, Hashcode, ToString, Compare, Duplicate).
- *
- * Once the caller has created the Logger object(s) (and set the loggerContext
- * (if any) and the Log callback), the caller then registers these Loggers
- * with the system by calling PKIX_SetLoggers or PKIX_AddLogger. All log
- * entries will then be logged using the specified Loggers. If multiple
- * Loggers are specified, every log entry will be logged with each of them.
- *
- * XXX Maybe give some guidance somewhere on how much detail each logging
- * level should have and where component boundaries should be. Maybe in
- * Implementor's Guide or Programmer's Guide.
- */
-
-#define PKIX_LOGGER_LEVEL_TRACE 5
-#define PKIX_LOGGER_LEVEL_DEBUG 4
-#define PKIX_LOGGER_LEVEL_WARNING 3
-#define PKIX_LOGGER_LEVEL_ERROR 2
-#define PKIX_LOGGER_LEVEL_FATALERROR 1
-
-#define PKIX_LOGGER_LEVEL_MAX 5
-
-/*
- * FUNCTION: PKIX_Logger_LogCallback
- * DESCRIPTION:
- *
- * This callback function logs a log entry containing the String pointed to
- * by "message", the integer value of logLevel, and the String pointed to by
- * "logComponent". A log entry can be associated with a particular log
- * level (i.e. level 3) and a particular log component (i.e. "CertStore").
- * For example, someone reading the log may only be interested in very general
- * log entries so they look only for log level 1. Similarly, they may only be
- * interested in log entries pertaining to the CertStore component so they
- * look only for that log component. This function can be used before calling
- * PKIX_Initialize.
- *
- * PARAMETERS:
- * "logger"
- * Address of logger whose LogCallback is to be used. Must be non-NULL.
- * "message"
- * Address of String that is to be logged used "logger". Must be non-NULL.
- * "logLevel"
- * Integer value representing the log level for this entry. The higher the
- * level, the more detail. Must be non-NULL.
- * "logComponent"
- * PKIXERRORNUM value (defined in pkixt.h) designating the log component
- * for this entry.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe
- *
- * Multiple threads must be able to safely call this function without
- * worrying about conflicts, even if they're operating on the same objects.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-typedef PKIX_Error *
-(*PKIX_Logger_LogCallback)(
- PKIX_Logger *logger,
- PKIX_PL_String *message,
- PKIX_UInt32 logLevel,
- PKIX_ERRORCLASS logComponent,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Logger_Create
- * DESCRIPTION:
- *
- * Creates a new Logger using the Object pointed to by "loggerContext"
- * (if any) and stores it at "pLogger". The new Logger uses the LogCallback
- * pointed to by "callback". The Logger's maximum logging level is initially
- * set to a very high level and its logging component is set to NULL (all
- * components).
- *
- * PARAMETERS:
- * "callback"
- * The LogCallback function to be used. Must be non-NULL.
- * "loggerContext"
- * Address of Object representing the Logger's context (if any).
- * "pLogger"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Logger_Create(
- PKIX_Logger_LogCallback callback,
- PKIX_PL_Object *loggerContext,
- PKIX_Logger **pLogger,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Logger_GetLogCallback
- * DESCRIPTION:
- *
- * Retrieves a pointer to "logger's" Log callback function and puts it in
- * "pCallback".
- *
- * PARAMETERS:
- * "logger"
- * Address of Logger whose Log callback is desired. Must be non-NULL.
- * "pCallback"
- * Address where Log callback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Logger_GetLogCallback(
- PKIX_Logger *logger,
- PKIX_Logger_LogCallback *pCallback,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Logger_GetLoggerContext
- * DESCRIPTION:
- *
- * Retrieves a pointer to a PKIX_PL_Object representing the context (if any)
- * of the Logger pointed to by "logger" and stores it at "pLoggerContext".
- *
- * PARAMETERS:
- * "logger"
- * Address of Logger whose context is to be stored. Must be non-NULL.
- * "pLoggerContext"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Logger_GetLoggerContext(
- PKIX_Logger *logger,
- PKIX_PL_Object **pLoggerContext,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Logger_GetMaxLoggingLevel
- * DESCRIPTION:
- *
- * Retrieves a pointer to a PKIX_UInt32 representing the maximum logging
- * level of the Logger pointed to by "logger" and stores it at "pLevel". Only
- * log entries whose log level is less than or equal to this maximum logging
- * level will be logged.
- *
- * PARAMETERS:
- * "logger"
- * Address of Logger whose maximum logging level is to be stored.
- * Must be non-NULL.
- * "pLevel"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Logger_GetMaxLoggingLevel(
- PKIX_Logger *logger,
- PKIX_UInt32 *pLevel,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Logger_SetMaxLoggingLevel
- * DESCRIPTION:
- *
- * Sets the maximum logging level of the Logger pointed to by "logger" with
- * the integer value of "level".
- *
- * PARAMETERS:
- * "logger"
- * Address of Logger whose maximum logging level is to be set.
- * Must be non-NULL.
- * "level"
- * Maximum logging level to be set
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "logger"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Logger_SetMaxLoggingLevel(
- PKIX_Logger *logger,
- PKIX_UInt32 level,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Logger_GetLoggingComponent
- * DESCRIPTION:
- *
- * Retrieves a pointer to a String representing the logging component of the
- * Logger pointed to by "logger" and stores it at "pComponent". Only log
- * entries whose log component matches the specified logging component will
- * be logged.
- *
- * PARAMETERS:
- * "logger"
- * Address of Logger whose logging component is to be stored.
- * Must be non-NULL.
- * "pComponent"
- * Address where PKIXERRORNUM will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Logger_GetLoggingComponent(
- PKIX_Logger *logger,
- PKIX_ERRORCLASS *pComponent,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Logger_SetLoggingComponent
- * DESCRIPTION:
- *
- * Sets the logging component of the Logger pointed to by "logger" with the
- * PKIXERRORNUM pointed to by "component". To match a small set of components,
- * create a Logger for each.
- *
- * PARAMETERS:
- * "logger"
- * Address of Logger whose logging component is to be set.
- * Must be non-NULL.
- * "component"
- * PKIXERRORNUM value representing logging component to be set.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "logger"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Logger_SetLoggingComponent(
- PKIX_Logger *logger,
- PKIX_ERRORCLASS component,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_GetLoggers
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of Loggers (if any) being used for logging
- * by libpkix and stores it at "pLoggers". If no loggers are being used, this
- * function stores an empty List at "pLoggers".
- *
- * Note that the List returned by this function is immutable.
- *
- * PARAMETERS:
- * "pLoggers"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_GetLoggers(
- PKIX_List **pLoggers, /* list of PKIX_Logger */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_SetLoggers
- * DESCRIPTION:
- *
- * Sets the Loggers to be used by libpkix to the List of Loggers pointed to
- * by "loggers". If "loggers" is NULL, no Loggers will be used.
- *
- * PARAMETERS:
- * "loggers"
- * Address of List of Loggers to be set. NULL for no Loggers.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_SetLoggers(
- PKIX_List *loggers, /* list of PKIX_Logger */
- void *plContext);
-
-/*
- * FUNCTION: PKIX_AddLogger
- * DESCRIPTION:
- *
- * Adds the Logger pointed to by "logger" to the List of Loggers used by
- * libpkix.
- *
- * PARAMETERS:
- * "logger"
- * Address of Logger to be added. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Logger Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_AddLogger(
- PKIX_Logger *logger,
- void *plContext);
-
-/* Functions pertaining to the PKIX_Error type */
-
-/* Error
- *
- * An Error object is returned by a function upon encountering some error
- * condition. Each Error is associated with an errorCode specified in pkixt.h.
- * The remaining components of an Error are optional. An Error's description
- * specifies a text message describing the Error. An Error's supplementary info
- * specifies additional information that might be useful. Finally, an Error's
- * cause specifies the underlying Error (if any) that resulted in this Error
- * being returned, thereby allowing Errors to be chained so that an entire
- * "error stack trace" can be represented. Once created, an Error is immutable.
- *
- * Note that the Error's supplementary info must be an Object (although any
- * object type), allowing it to be reference-counted and allowing it to
- * provide the standard Object functions (Equals, Hashcode, ToString, Compare,
- * Duplicate).
- *
- * Errors are classified as either being fatal or non-fatal. If a function
- * fails in an unrecoverable way, it returns an Error whose errorCode is
- * PKIX_FATAL_ERROR. If such an error is encountered, the caller should
- * not attempt to recover since something seriously wrong has happened
- * (e.g. corrupted memory, memory finished, etc.). All other errorCodes
- * are considered non-fatal errors and can be handled by the caller as they
- * see fit.
- */
-
-/*
- * FUNCTION: PKIX_Error_Create
- * DESCRIPTION:
- *
- * Creates a new Error using the value of "errorCode", the Error pointed to by
- * "cause" (if any), the Object pointed to by "info" (if any), and the String
- * pointed to by "desc" and stores it at "pError". If any error occurs during
- * error allocation, it will be returned without chaining, since new errors
- * cannot be created. Once created, an Error is immutable.
- *
- * PARAMETERS:
- * "errorCode"
- * Value of error code.
- * "cause"
- * Address of Error representing error's cause.
- * NULL if none or unspecified.
- * "info"
- * Address of Object representing error's supplementary information.
- * NULL if none.
- * "desc"
- * Address of String representing error's description. NULL if none.
- * "pError"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Error_Create(
- PKIX_ERRORCLASS errClass,
- PKIX_Error *cause,
- PKIX_PL_Object *info,
- PKIX_ERRORCODE errCode,
- PKIX_Error **pError,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Error_GetErrorClass
- * DESCRIPTION:
- *
- * Retrieves the error class of the Error pointed to by "error" and
- * stores it at "pClass". Supported error codes are defined in pkixt.h.
- *
- * PARAMETERS:
- * "error"
- * Address of Error whose error code is desired. Must be non-NULL.
- * "pClass"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Error_GetErrorClass(
- PKIX_Error *error,
- PKIX_ERRORCLASS *pClass,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Error_GetErrorCode
- * DESCRIPTION:
- *
- * Retrieves the error code of the Error pointed to by "error" and
- * stores it at "pCode". Supported error codes are defined in pkixt.h.
- *
- * PARAMETERS:
- * "error"
- * Address of Error whose error code is desired. Must be non-NULL.
- * "pCode"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Error_GetErrorCode(
- PKIX_Error *error,
- PKIX_ERRORCODE *pCode,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Error_GetCause
- * DESCRIPTION:
- *
- * Retrieves the cause of the Error pointed to by "error" and stores it at
- * "pCause". If no cause was specified, NULL will be stored at "pCause".
- *
- * PARAMETERS:
- * "error"
- * Address of Error whose cause is desired. Must be non-NULL.
- * "pCause"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Error_GetCause(
- PKIX_Error *error,
- PKIX_Error **pCause,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Error_GetSupplementaryInfo
- * DESCRIPTION:
- *
- * Retrieves the supplementary info of the Error pointed to by "error" and
- * stores it at "pInfo".
- *
- * PARAMETERS:
- * "error"
- * Address of Error whose info is desired. Must be non-NULL.
- * "pInfo"
- * Address where info pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Error_GetSupplementaryInfo(
- PKIX_Error *error,
- PKIX_PL_Object **pInfo,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_Error_GetDescription
- * DESCRIPTION:
- *
- * Retrieves the description of the Error pointed to by "error" and stores it
- * at "pDesc". If no description was specified, NULL will be stored at
- * "pDesc".
- *
- * PARAMETERS:
- * "error"
- * Address of Error whose description is desired. Must be non-NULL.
- * "pDesc"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_Error_GetDescription(
- PKIX_Error *error,
- PKIX_PL_String **pDesc,
- void *plContext);
-
-/* PKIX_List
- *
- * Represents a collection of items. NULL is considered a valid item.
- */
-
-/*
- * FUNCTION: PKIX_List_Create
- * DESCRIPTION:
- *
- * Creates a new List and stores it at "pList". The List is initially empty
- * and holds no items. To initially add items to the List, use
- * PKIX_List_AppendItem
- *
- * PARAMETERS:
- * "pList"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_Create(
- PKIX_List **pList,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_SetImmutable
- * DESCRIPTION:
- *
- * Sets the List pointed to by "list" to be immutable. If a caller tries to
- * change a List after it has been marked immutable (i.e. by calling
- * PKIX_List_AppendItem, PKIX_List_InsertItem, PKIX_List_SetItem, or
- * PKIX_List_DeleteItem), an Error is returned.
- *
- * PARAMETERS:
- * "list"
- * Address of List to be marked immutable. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "list"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_SetImmutable(
- PKIX_List *list,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_IsImmutable
- * DESCRIPTION:
- *
- * Checks whether the List pointed to by "list" is immutable and stores
- * the Boolean result at "pImmutable". If a caller tries to change a List
- * after it has been marked immutable (i.e. by calling PKIX_List_AppendItem,
- * PKIX_List_InsertItem, PKIX_List_SetItem, or PKIX_List_DeleteItem), an
- * Error is returned.
- *
- * PARAMETERS:
- * "list"
- * Address of List whose immutability is to be determined.
- * Must be non-NULL.
- * "pImmutable"
- * Address where PKIX_Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_IsImmutable(
- PKIX_List *list,
- PKIX_Boolean *pImmutable,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_GetLength
- * DESCRIPTION:
- *
- * Retrieves the length of the List pointed to by "list" and stores it at
- * "pLength".
- *
- * PARAMETERS:
- * "list"
- * Address of List whose length is desired. Must be non-NULL.
- * "pLength"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_GetLength(
- PKIX_List *list,
- PKIX_UInt32 *pLength,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_IsEmpty
- * DESCRIPTION:
- *
- * Checks whether the List pointed to by "list" is empty and stores
- * the Boolean result at "pEmpty".
- *
- * PARAMETERS:
- * "list"
- * Address of List whose emptiness is to be determined. Must be non-NULL.
- * "pEmpty"
- * Address where PKIX_Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_IsEmpty(
- PKIX_List *list,
- PKIX_Boolean *pEmpty,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_AppendItem
- * DESCRIPTION:
- *
- * Appends the Object pointed to by "item" after the last non-NULL item in
- * List pointed to by "list", if any. Note that a List may validly contain
- * NULL items. Appending "c" into the List ("a", NULL, "b", NULL) will result
- * in ("a", NULL, "b", "c").
- *
- * PARAMETERS:
- * "list"
- * Address of List to append to. Must be non-NULL.
- * "item"
- * Address of new item to append.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "list"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_AppendItem(
- PKIX_List *list,
- PKIX_PL_Object *item,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_InsertItem
- * DESCRIPTION:
- *
- * Inserts the Object pointed to by "item" into the List pointed to by "list"
- * at the given "index". The index counts from zero and must be less than the
- * List's length. Existing list entries at or after this index will be moved
- * to the next highest index.
- *
- * XXX why not allow equal to length which would be equivalent to AppendItem?
- *
- * PARAMETERS:
- * "list"
- * Address of List to insert into. Must be non-NULL.
- * "index"
- * Position to insert into. Must be less than List's length.
- * "item"
- * Address of new item to append.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "list"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_InsertItem(
- PKIX_List *list,
- PKIX_UInt32 index,
- PKIX_PL_Object *item,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_GetItem
- * DESCRIPTION:
- *
- * Copies the "list"'s item at "index" into "pItem". The index counts from
- * zero and must be less than the list's length. Increments the reference
- * count on the returned object, if non-NULL.
- *
- * PARAMETERS:
- * "list"
- * Address of List to get item from. Must be non-NULL.
- * "index"
- * Index of list to get item from. Must be less than List's length.
- * "pItem"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_GetItem(
- PKIX_List *list,
- PKIX_UInt32 index,
- PKIX_PL_Object **pItem,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_SetItem
- * DESCRIPTION:
- *
- * Sets the item at "index" of the List pointed to by "list" with the Object
- * pointed to by "item". The index counts from zero and must be less than the
- * List's length. The previous entry at this index will have its reference
- * count decremented and the new entry will have its reference count
- * incremented.
- *
- * PARAMETERS:
- * "list"
- * Address of List to modify. Must be non-NULL.
- * "index"
- * Position in List to set. Must be less than List's length.
- * "item"
- * Address of Object to set at "index".
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "list"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_SetItem(
- PKIX_List *list,
- PKIX_UInt32 index,
- PKIX_PL_Object *item,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_DeleteItem
- *
- * Deletes the item at "index" from the List pointed to by "list". The index
- * counts from zero and must be less than the List's length. Note that this
- * function does not destroy the List. It simply decrements the reference
- * count of the item at "index" in the List, deletes that item from the list
- * and moves all subsequent entries to a lower index in the list. If there is
- * only a single element in the List and that element is deleted, then the
- * List will be empty.
- *
- * PARAMETERS:
- * "list"
- * Address of List to delete from. Must be non-NULL.
- * "index"
- * Position in List to delete. Must be less than List's length.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "list"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_DeleteItem(
- PKIX_List *list,
- PKIX_UInt32 index,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_List_ReverseList
- * DESCRIPTION:
- *
- * Creates a new List whose elements are in the reverse order as the elements
- * of the Object pointed to by "list" and stores the copy at "pReversedList".
- * If "list" is empty, the new reversed List will be a copy of "list".
- * Changes to the new object will not affect the original and vice versa.
- *
- * PARAMETERS:
- * "list"
- * Address of List whose elements are to be reversed. Must be non-NULL.
- * "pReversedList"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_List_ReverseList(
- PKIX_List *list,
- PKIX_List **pReversedList,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_UTIL_H */
diff --git a/security/nss/lib/libpkix/include/pkixt.h b/security/nss/lib/libpkix/include/pkixt.h
deleted file mode 100755
index 71997f700..000000000
--- a/security/nss/lib/libpkix/include/pkixt.h
+++ /dev/null
@@ -1,485 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file defines the types in the libpkix API.
- * XXX Maybe we should specify the API version number in all API header files
- *
- */
-
-#ifndef _PKIXT_H
-#define _PKIXT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "secerr.h"
-
-/* Types
- *
- * This header file provides typedefs for the abstract types used by libpkix.
- * It also provides several useful macros.
- *
- * Note that all these abstract types are typedef'd as opaque structures. This
- * is intended to discourage the caller from looking at the contents directly,
- * since the format of the contents may change from one version of the library
- * to the next. Instead, callers should only access these types using the
- * functions defined in the public header files.
- *
- * An instance of an abstract type defined in this file is called an "object"
- * here, although C does not have real support for objects.
- *
- * Because C does not typically have automatic garbage collection, the caller
- * is expected to release the reference to any object that they create or that
- * is returned to them by a libpkix function. The caller should do this by
- * using the PKIX_PL_Object_DecRef function. Note that the caller should not
- * release the reference to an object if the object has been passed to a
- * libpkix function and that function has not returned.
- *
- * Please refer to libpkix Programmer's Guide for more details.
- */
-
-/* Version
- *
- * These macros specify the major and minor version of the libpkix API defined
- * by this header file.
- */
-
-#define PKIX_MAJOR_VERSION ((PKIX_UInt32) 0)
-#define PKIX_MINOR_VERSION ((PKIX_UInt32) 3)
-
-/* Maximum minor version
- *
- * This macro is used to specify that the caller wants the largest minor
- * version available.
- */
-
-#define PKIX_MAX_MINOR_VERSION ((PKIX_UInt32) 4000000000)
-
-/* Define Cert Store type for database access */
-#define PKIX_STORE_TYPE_NONE 0
-#define PKIX_STORE_TYPE_PK11 1
-
-/* Portable Code (PC) data types
- *
- * These types are used to perform the primary operations of this library:
- * building and validating chains of X.509 certificates.
- */
-
-typedef struct PKIX_ErrorStruct PKIX_Error;
-typedef struct PKIX_ProcessingParamsStruct PKIX_ProcessingParams;
-typedef struct PKIX_ValidateParamsStruct PKIX_ValidateParams;
-typedef struct PKIX_ValidateResultStruct PKIX_ValidateResult;
-typedef struct PKIX_ResourceLimitsStruct PKIX_ResourceLimits;
-typedef struct PKIX_BuildResultStruct PKIX_BuildResult;
-typedef struct PKIX_CertStoreStruct PKIX_CertStore;
-typedef struct PKIX_CertChainCheckerStruct PKIX_CertChainChecker;
-typedef struct PKIX_RevocationCheckerStruct PKIX_RevocationChecker;
-typedef struct PKIX_CertSelectorStruct PKIX_CertSelector;
-typedef struct PKIX_CRLSelectorStruct PKIX_CRLSelector;
-typedef struct PKIX_ComCertSelParamsStruct PKIX_ComCertSelParams;
-typedef struct PKIX_ComCRLSelParamsStruct PKIX_ComCRLSelParams;
-typedef struct PKIX_TrustAnchorStruct PKIX_TrustAnchor;
-typedef struct PKIX_PolicyNodeStruct PKIX_PolicyNode;
-typedef struct PKIX_LoggerStruct PKIX_Logger;
-typedef struct PKIX_ListStruct PKIX_List;
-typedef struct PKIX_ForwardBuilderStateStruct PKIX_ForwardBuilderState;
-typedef struct PKIX_DefaultRevocationCheckerStruct
- PKIX_DefaultRevocationChecker;
-typedef struct PKIX_VerifyNodeStruct PKIX_VerifyNode;
-
-/* Portability Layer (PL) data types
- *
- * These types are used are used as portable data types that are defined
- * consistently across platforms
- */
-
-typedef struct PKIX_PL_NssContextStruct PKIX_PL_NssContext;
-typedef struct PKIX_PL_ObjectStruct PKIX_PL_Object;
-typedef struct PKIX_PL_ByteArrayStruct PKIX_PL_ByteArray;
-typedef struct PKIX_PL_HashTableStruct PKIX_PL_HashTable;
-typedef struct PKIX_PL_MutexStruct PKIX_PL_Mutex;
-typedef struct PKIX_PL_RWLockStruct PKIX_PL_RWLock;
-typedef struct PKIX_PL_MonitorLockStruct PKIX_PL_MonitorLock;
-typedef struct PKIX_PL_BigIntStruct PKIX_PL_BigInt;
-typedef struct PKIX_PL_StringStruct PKIX_PL_String;
-typedef struct PKIX_PL_OIDStruct PKIX_PL_OID;
-typedef struct PKIX_PL_CertStruct PKIX_PL_Cert;
-typedef struct PKIX_PL_GeneralNameStruct PKIX_PL_GeneralName;
-typedef struct PKIX_PL_X500NameStruct PKIX_PL_X500Name;
-typedef struct PKIX_PL_PublicKeyStruct PKIX_PL_PublicKey;
-typedef struct PKIX_PL_DateStruct PKIX_PL_Date;
-typedef struct PKIX_PL_CertNameConstraintsStruct PKIX_PL_CertNameConstraints;
-typedef struct PKIX_PL_CertBasicConstraintsStruct PKIX_PL_CertBasicConstraints;
-typedef struct PKIX_PL_CertPoliciesStruct PKIX_PL_CertPolicies;
-typedef struct PKIX_PL_CertPolicyInfoStruct PKIX_PL_CertPolicyInfo;
-typedef struct PKIX_PL_CertPolicyQualifierStruct PKIX_PL_CertPolicyQualifier;
-typedef struct PKIX_PL_CertPolicyMapStruct PKIX_PL_CertPolicyMap;
-typedef struct PKIX_PL_CRLStruct PKIX_PL_CRL;
-typedef struct PKIX_PL_CRLEntryStruct PKIX_PL_CRLEntry;
-typedef struct PKIX_PL_CollectionCertStoreStruct PKIX_PL_CollectionCertStore;
-typedef struct PKIX_PL_CollectionCertStoreContext
- PKIX_PL_CollectionCertStoreContext;
-typedef struct PKIX_PL_LdapCertStoreContext PKIX_PL_LdapCertStoreContext;
-typedef struct PKIX_PL_LdapRequestStruct PKIX_PL_LdapRequest;
-typedef struct PKIX_PL_LdapResponseStruct PKIX_PL_LdapResponse;
-typedef struct PKIX_PL_LdapDefaultClientStruct PKIX_PL_LdapDefaultClient;
-typedef struct PKIX_PL_SocketStruct PKIX_PL_Socket;
-typedef struct PKIX_PL_InfoAccessStruct PKIX_PL_InfoAccess;
-typedef struct PKIX_PL_AIAMgrStruct PKIX_PL_AIAMgr;
-typedef struct PKIX_PL_OcspCertIDStruct PKIX_PL_OcspCertID;
-typedef struct PKIX_PL_OcspRequestStruct PKIX_PL_OcspRequest;
-typedef struct PKIX_PL_OcspResponseStruct PKIX_PL_OcspResponse;
-typedef struct PKIX_PL_HttpClientStruct PKIX_PL_HttpClient;
-typedef struct PKIX_PL_HttpDefaultClientStruct PKIX_PL_HttpDefaultClient;
-typedef struct PKIX_PL_HttpCertStoreContextStruct PKIX_PL_HttpCertStoreContext;
-
-/* Primitive types
- *
- * In order to guarantee desired behavior as well as platform-independence, we
- * typedef these types depending on the platform. XXX This needs more work!
- */
-
-/* XXX Try compiling these files (and maybe the whole libpkix-nss) on Win32.
- * We don't know what type is at least 32 bits long. ISO C probably requires
- * at least 32 bits for long. we could default to that and only list platforms
- * where that's not true.
- *
- * #elif
- * #error
- * #endif
- */
-
-/* currently, int is 32 bits on all our supported platforms */
-
-typedef unsigned int PKIX_UInt32;
-typedef int PKIX_Int32;
-
-typedef int PKIX_Boolean;
-
-/* Object Types
- *
- * Every reference-counted PKIX_PL_Object is associated with an integer type.
- */
-#define PKIX_TYPES \
- TYPEMACRO(AIAMGR), \
- TYPEMACRO(BASICCONSTRAINTSCHECKERSTATE), \
- TYPEMACRO(BIGINT), \
- TYPEMACRO(BUILDRESULT), \
- TYPEMACRO(BYTEARRAY), \
- TYPEMACRO(CERT), \
- TYPEMACRO(CERTBASICCONSTRAINTS), \
- TYPEMACRO(CERTCHAINCHECKER), \
- TYPEMACRO(CERTNAMECONSTRAINTS), \
- TYPEMACRO(CERTNAMECONSTRAINTSCHECKERSTATE), \
- TYPEMACRO(CERTPOLICYCHECKERSTATE), \
- TYPEMACRO(CERTPOLICYINFO), \
- TYPEMACRO(CERTPOLICYMAP), \
- TYPEMACRO(CERTPOLICYNODE), \
- TYPEMACRO(CERTPOLICYQUALIFIER), \
- TYPEMACRO(CERTSELECTOR), \
- TYPEMACRO(CERTSTORE), \
- TYPEMACRO(COLLECTIONCERTSTORECONTEXT), \
- TYPEMACRO(COMCERTSELPARAMS), \
- TYPEMACRO(COMCRLSELPARAMS), \
- TYPEMACRO(CRL), \
- TYPEMACRO(CRLDP), \
- TYPEMACRO(CRLENTRY), \
- TYPEMACRO(CRLSELECTOR), \
- TYPEMACRO(DATE), \
- TYPEMACRO(CRLCHECKER), \
- TYPEMACRO(EKUCHECKER), \
- TYPEMACRO(ERROR), \
- TYPEMACRO(FORWARDBUILDERSTATE), \
- TYPEMACRO(GENERALNAME), \
- TYPEMACRO(HASHTABLE), \
- TYPEMACRO(HTTPCERTSTORECONTEXT), \
- TYPEMACRO(HTTPDEFAULTCLIENT), \
- TYPEMACRO(INFOACCESS), \
- TYPEMACRO(LDAPDEFAULTCLIENT), \
- TYPEMACRO(LDAPREQUEST), \
- TYPEMACRO(LDAPRESPONSE), \
- TYPEMACRO(LIST), \
- TYPEMACRO(LOGGER), \
- TYPEMACRO(MONITORLOCK), \
- TYPEMACRO(MUTEX), \
- TYPEMACRO(OBJECT), \
- TYPEMACRO(OCSPCERTID), \
- TYPEMACRO(OCSPCHECKER), \
- TYPEMACRO(OCSPREQUEST), \
- TYPEMACRO(OCSPRESPONSE), \
- TYPEMACRO(OID), \
- TYPEMACRO(REVOCATIONCHECKER), \
- TYPEMACRO(PROCESSINGPARAMS), \
- TYPEMACRO(PUBLICKEY), \
- TYPEMACRO(RESOURCELIMITS), \
- TYPEMACRO(RWLOCK), \
- TYPEMACRO(SIGNATURECHECKERSTATE), \
- TYPEMACRO(SOCKET), \
- TYPEMACRO(STRING), \
- TYPEMACRO(TARGETCERTCHECKERSTATE), \
- TYPEMACRO(TRUSTANCHOR), \
- TYPEMACRO(VALIDATEPARAMS), \
- TYPEMACRO(VALIDATERESULT), \
- TYPEMACRO(VERIFYNODE), \
- TYPEMACRO(X500NAME)
-
-#define TYPEMACRO(type) PKIX_ ## type ## _TYPE
-
-typedef enum { /* Now invoke all those TYPEMACROs to assign the numbers */
- PKIX_TYPES,
- PKIX_NUMTYPES /* This gets PKIX_NUMTYPES defined as the total number */
-} PKIX_TYPENUM;
-
-
-#ifdef PKIX_USER_OBJECT_TYPE
-
-/* User Define Object Types
- *
- * User may define their own object types offset from PKIX_USER_OBJECT_TYPE
- */
-#define PKIX_USER_OBJECT_TYPEBASE 1000
-
-#endif /* PKIX_USER_OBJECT_TYPE */
-
-/* Error Codes
- *
- * This list is used to define a set of PKIX_Error exception class numbers.
- * ERRMACRO is redefined to produce a corresponding set of
- * strings in the table "const char *PKIX_ERRORCLASSNAMES[PKIX_NUMERRORCLASSES]" in
- * pkix_error.c. For example, since the fifth ERRMACRO entry is MUTEX, then
- * PKIX_MUTEX_ERROR is defined in pkixt.h as 4, and PKIX_ERRORCLASSNAMES[4] is
- * initialized in pkix_error.c with the value "MUTEX".
- */
-#define PKIX_ERRORCLASSES \
- ERRMACRO(AIAMGR), \
- ERRMACRO(BASICCONSTRAINTSCHECKERSTATE), \
- ERRMACRO(BIGINT), \
- ERRMACRO(BUILD), \
- ERRMACRO(BUILDRESULT), \
- ERRMACRO(BYTEARRAY), \
- ERRMACRO(CERT), \
- ERRMACRO(CERTBASICCONSTRAINTS), \
- ERRMACRO(CERTCHAINCHECKER), \
- ERRMACRO(CERTNAMECONSTRAINTS), \
- ERRMACRO(CERTNAMECONSTRAINTSCHECKERSTATE), \
- ERRMACRO(CERTPOLICYCHECKERSTATE), \
- ERRMACRO(CERTPOLICYINFO), \
- ERRMACRO(CERTPOLICYMAP), \
- ERRMACRO(CERTPOLICYNODE), \
- ERRMACRO(CERTPOLICYQUALIFIER), \
- ERRMACRO(CERTSELECTOR), \
- ERRMACRO(CERTSTORE), \
- ERRMACRO(CERTVFYPKIX), \
- ERRMACRO(COLLECTIONCERTSTORECONTEXT), \
- ERRMACRO(COMCERTSELPARAMS), \
- ERRMACRO(COMCRLSELPARAMS), \
- ERRMACRO(CONTEXT), \
- ERRMACRO(CRL), \
- ERRMACRO(CRLDP), \
- ERRMACRO(CRLENTRY), \
- ERRMACRO(CRLSELECTOR), \
- ERRMACRO(CRLCHECKER), \
- ERRMACRO(DATE), \
- ERRMACRO(EKUCHECKER), \
- ERRMACRO(ERROR), \
- ERRMACRO(FATAL), \
- ERRMACRO(FORWARDBUILDERSTATE), \
- ERRMACRO(GENERALNAME), \
- ERRMACRO(HASHTABLE), \
- ERRMACRO(HTTPCERTSTORECONTEXT), \
- ERRMACRO(HTTPDEFAULTCLIENT), \
- ERRMACRO(INFOACCESS), \
- ERRMACRO(LDAPCLIENT), \
- ERRMACRO(LDAPDEFAULTCLIENT), \
- ERRMACRO(LDAPREQUEST), \
- ERRMACRO(LDAPRESPONSE), \
- ERRMACRO(LIFECYCLE), \
- ERRMACRO(LIST), \
- ERRMACRO(LOGGER), \
- ERRMACRO(MEM), \
- ERRMACRO(MONITORLOCK), \
- ERRMACRO(MUTEX), \
- ERRMACRO(OBJECT), \
- ERRMACRO(OCSPCERTID), \
- ERRMACRO(OCSPCHECKER), \
- ERRMACRO(OCSPREQUEST), \
- ERRMACRO(OCSPRESPONSE), \
- ERRMACRO(OID), \
- ERRMACRO(PROCESSINGPARAMS), \
- ERRMACRO(PUBLICKEY), \
- ERRMACRO(RESOURCELIMITS), \
- ERRMACRO(REVOCATIONMETHOD), \
- ERRMACRO(REVOCATIONCHECKER), \
- ERRMACRO(RWLOCK), \
- ERRMACRO(SIGNATURECHECKERSTATE), \
- ERRMACRO(SOCKET), \
- ERRMACRO(STRING), \
- ERRMACRO(TARGETCERTCHECKERSTATE), \
- ERRMACRO(TRUSTANCHOR), \
- ERRMACRO(USERDEFINEDMODULES), \
- ERRMACRO(VALIDATE), \
- ERRMACRO(VALIDATEPARAMS), \
- ERRMACRO(VALIDATERESULT), \
- ERRMACRO(VERIFYNODE), \
- ERRMACRO(X500NAME)
-
-#define ERRMACRO(type) PKIX_ ## type ## _ERROR
-
-typedef enum { /* Now invoke all those ERRMACROs to assign the numbers */
- PKIX_ERRORCLASSES,
- PKIX_NUMERRORCLASSES /* This gets PKIX_NUMERRORCLASSES defined as the total number */
-} PKIX_ERRORCLASS;
-
-/* Now define error strings (for internationalization) */
-
-#define PKIX_ERRORENTRY(name,desc,plerr) PKIX_ ## name
-
-/* Define all the error numbers */
-typedef enum {
-#include "pkix_errorstrings.h"
-, PKIX_NUMERRORCODES
-} PKIX_ERRORCODE;
-
-extern const char * const PKIX_ErrorText[];
-
-/* String Formats
- *
- * These formats specify supported encoding formats for Strings.
- */
-
-#define PKIX_ESCASCII 0
-#define PKIX_UTF8 1
-#define PKIX_UTF16 2
-#define PKIX_UTF8_NULL_TERM 3
-#define PKIX_ESCASCII_DEBUG 4
-
-/* Name Types
- *
- * These types specify supported formats for GeneralNames.
- */
-
-#define PKIX_OTHER_NAME 1
-#define PKIX_RFC822_NAME 2
-#define PKIX_DNS_NAME 3
-#define PKIX_X400_ADDRESS 4
-#define PKIX_DIRECTORY_NAME 5
-#define PKIX_EDIPARTY_NAME 6
-#define PKIX_URI_NAME 7
-#define PKIX_IP_NAME 8
-#define PKIX_OID_NAME 9
-
-/* Key Usages
- *
- * These types specify supported Key Usages
- */
-
-#define PKIX_DIGITAL_SIGNATURE 0x001
-#define PKIX_NON_REPUDIATION 0x002
-#define PKIX_KEY_ENCIPHERMENT 0x004
-#define PKIX_DATA_ENCIPHERMENT 0x008
-#define PKIX_KEY_AGREEMENT 0x010
-#define PKIX_KEY_CERT_SIGN 0x020
-#define PKIX_CRL_SIGN 0x040
-#define PKIX_ENCIPHER_ONLY 0x080
-#define PKIX_DECIPHER_ONLY 0x100
-
-/* Reason Flags
- *
- * These macros specify supported Reason Flags
- */
-
-#define PKIX_UNUSED 0x001
-#define PKIX_KEY_COMPROMISE 0x002
-#define PKIX_CA_COMPROMISE 0x004
-#define PKIX_AFFILIATION_CHANGED 0x008
-#define PKIX_SUPERSEDED 0x010
-#define PKIX_CESSATION_OF_OPERATION 0x020
-#define PKIX_CERTIFICATE_HOLD 0x040
-#define PKIX_PRIVILEGE_WITHDRAWN 0x080
-#define PKIX_AA_COMPROMISE 0x100
-
-/* Boolean values
- *
- * These macros specify the Boolean values of TRUE and FALSE
- * XXX Is it the case that any non-zero value is actually considered TRUE
- * and this is just a convenient mnemonic macro?
- */
-
-#define PKIX_TRUE ((PKIX_Boolean) 1)
-#define PKIX_FALSE ((PKIX_Boolean) 0)
-
-/*
- * Define constants for basic constraints selector
- * (see comments in pkix_certsel.h)
- */
-
-#define PKIX_CERTSEL_ENDENTITY_MIN_PATHLENGTH (-2)
-#define PKIX_CERTSEL_ALL_MATCH_MIN_PATHLENGTH (-1)
-
-/*
- * PKIX_ALLOC_ERROR is a special error object hard-coded into the pkix_error.o
- * object file. It is thrown if system memory cannot be allocated or may be
- * thrown for other unrecoverable errors. PKIX_ALLOC_ERROR is immutable.
- * IncRef, DecRef and all Settor functions cannot be called.
- * XXX Does anyone actually need to know about this?
- * XXX Why no DecRef? Would be good to handle it the same.
- */
-
-PKIX_Error* PKIX_ALLOC_ERROR(void);
-
-/*
- * In a CertBasicConstraints extension, if the CA flag is set,
- * indicating the certificate refers to a Certification
- * Authority, then the pathLen field indicates how many intermediate
- * certificates (not counting self-signed ones) can exist in a valid
- * chain following this certificate. If the pathLen has the value
- * of this constant, then the length of the chain is unlimited
- */
-#define PKIX_UNLIMITED_PATH_CONSTRAINT ((PKIX_Int32) -1)
-
-/*
- * Define Certificate Extension hard-coded OID's
- */
-#define PKIX_UNKNOWN_OID SEC_OID_UNKNOWN
-#define PKIX_CERTKEYUSAGE_OID SEC_OID_X509_KEY_USAGE
-#define PKIX_CERTSUBJALTNAME_OID SEC_OID_X509_SUBJECT_ALT_NAME
-#define PKIX_BASICCONSTRAINTS_OID SEC_OID_X509_BASIC_CONSTRAINTS
-#define PKIX_CRLREASONCODE_OID SEC_OID_X509_REASON_CODE
-#define PKIX_NAMECONSTRAINTS_OID SEC_OID_X509_NAME_CONSTRAINTS
-#define PKIX_CERTIFICATEPOLICIES_OID SEC_OID_X509_CERTIFICATE_POLICIES
-#define PKIX_CERTIFICATEPOLICIES_ANYPOLICY_OID SEC_OID_X509_ANY_POLICY
-#define PKIX_POLICYMAPPINGS_OID SEC_OID_X509_POLICY_MAPPINGS
-#define PKIX_POLICYCONSTRAINTS_OID SEC_OID_X509_POLICY_CONSTRAINTS
-#define PKIX_EXTENDEDKEYUSAGE_OID SEC_OID_X509_EXT_KEY_USAGE
-#define PKIX_INHIBITANYPOLICY_OID SEC_OID_X509_INHIBIT_ANY_POLICY
-#define PKIX_NSCERTTYPE_OID SEC_OID_NS_CERT_EXT_CERT_TYPE
-#define PKIX_KEY_USAGE_SERVER_AUTH_OID SEC_OID_EXT_KEY_USAGE_SERVER_AUTH
-#define PKIX_KEY_USAGE_CLIENT_AUTH_OID SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH
-#define PKIX_KEY_USAGE_CODE_SIGN_OID SEC_OID_EXT_KEY_USAGE_CODE_SIGN
-#define PKIX_KEY_USAGE_EMAIL_PROTECT_OID SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT
-#define PKIX_KEY_USAGE_TIME_STAMP_OID SEC_OID_EXT_KEY_USAGE_TIME_STAMP
-#define PKIX_KEY_USAGE_OCSP_RESPONDER_OID SEC_OID_OCSP_RESPONDER
-
-
-/* Available revocation method types. */
-typedef enum PKIX_RevocationMethodTypeEnum {
- PKIX_RevocationMethod_CRL = 0,
- PKIX_RevocationMethod_OCSP,
- PKIX_RevocationMethod_MAX
-} PKIX_RevocationMethodType;
-
-/* A set of statuses revocation checker operates on */
-typedef enum PKIX_RevocationStatusEnum {
- PKIX_RevStatus_NoInfo = 0,
- PKIX_RevStatus_Revoked,
- PKIX_RevStatus_Success
-} PKIX_RevocationStatus;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIXT_H */
diff --git a/security/nss/lib/libpkix/manifest.mn b/security/nss/lib/libpkix/manifest.mn
deleted file mode 100755
index ebf01f259..000000000
--- a/security/nss/lib/libpkix/manifest.mn
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-DEPTH = ../../..
-
-#
-DIRS = include pkix pkix_pl_nss \
- $(NULL)
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/libpkix/pkix/Makefile b/security/nss/lib/libpkix/pkix/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix/certsel/Makefile b/security/nss/lib/libpkix/pkix/certsel/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix/certsel/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix/certsel/config.mk b/security/nss/lib/libpkix/pkix/certsel/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix/certsel/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix/certsel/manifest.mn b/security/nss/lib/libpkix/pkix/certsel/manifest.mn
deleted file mode 100755
index d90f1a274..000000000
--- a/security/nss/lib/libpkix/pkix/certsel/manifest.mn
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_certselector.h \
- pkix_comcertselparams.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_certselector.c \
- pkix_comcertselparams.c \
- $(NULL)
-
-LIBRARY_NAME = pkixcertsel
-
diff --git a/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.c b/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.c
deleted file mode 100755
index b9cde1697..000000000
--- a/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.c
+++ /dev/null
@@ -1,1633 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_certselector.c
- *
- * CertSelector Object Functions
- *
- */
-
-#include "pkix_certselector.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_CertSelector_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CertSelector_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_CertSelector *selector = NULL;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a cert selector */
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
- PKIX_OBJECTNOTCERTSELECTOR);
-
- selector = (PKIX_CertSelector *)object;
- PKIX_DECREF(selector->params);
- PKIX_DECREF(selector->context);
-
-cleanup:
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Duplicate
- * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CertSelector_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_CertSelector *certSelector = NULL;
- PKIX_CertSelector *certSelectorDuplicate = NULL;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Duplicate");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSELECTOR_TYPE, plContext),
- PKIX_OBJECTNOTCERTSELECTOR);
-
- certSelector = (PKIX_CertSelector *)object;
-
- PKIX_CHECK(PKIX_CertSelector_Create
- (certSelector->matchCallback,
- certSelector->context,
- &certSelectorDuplicate,
- plContext),
- PKIX_CERTSELECTORCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- ((PKIX_PL_Object *)certSelector->params,
- (PKIX_PL_Object **)&certSelectorDuplicate->params,
- plContext),
- PKIX_OBJECTDUPLICATEFAILED);
-
- *pNewObject = (PKIX_PL_Object *)certSelectorDuplicate;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(certSelectorDuplicate);
- }
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_BasicConstraint
- * DESCRIPTION:
- *
- * Determines whether the Cert pointed to by "cert" matches the basic
- * constraints criterion using the basic constraints field of the
- * ComCertSelParams pointed to by "params". If the basic constraints field is
- * -1, no basic constraints check is done and the Cert is considered to match
- * the basic constraints criterion. If the Cert does not match the basic
- * constraints criterion, an Error pointer is returned.
- *
- * In order to match against this criterion, there are several possibilities.
- *
- * 1) If the criterion's minimum path length is greater than or equal to zero,
- * a certificate must include a BasicConstraints extension with a pathLen of
- * at least this value.
- *
- * 2) If the criterion's minimum path length is -2, a certificate must be an
- * end-entity certificate.
- *
- * 3) If the criterion's minimum path length is -1, no basic constraints check
- * is done and all certificates are considered to match this criterion.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose basic constraints field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * OUTPUT PARAMETERS ON FAILURE:
- * If the function returns a failure,
- * the output parameters of this function are undefined.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_BasicConstraint(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
- PKIX_Boolean caFlag = PKIX_FALSE; /* EE Cert by default */
- PKIX_Int32 pathLength = 0;
- PKIX_Int32 minPathLength = 0;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_BasicConstraint");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
- *pResult = PKIX_TRUE;
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetBasicConstraints
- (params, &minPathLength, plContext),
- PKIX_COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED);
-
- /* If the minPathLength is unlimited (-1), no checking */
- if (minPathLength == PKIX_CERTSEL_ALL_MATCH_MIN_PATHLENGTH) {
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
- (cert, &basicConstraints, plContext),
- PKIX_CERTGETBASICCONSTRAINTSFAILED);
-
- if (basicConstraints != NULL) {
- PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
- (basicConstraints, &caFlag, plContext),
- PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
-
- PKIX_CHECK(PKIX_PL_BasicConstraints_GetPathLenConstraint
- (basicConstraints, &pathLength, plContext),
- PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED);
- }
-
- /*
- * if minPathLength >= 0, the cert must have a BasicConstraints ext and
- * the pathLength in this cert
- * BasicConstraints needs to be >= minPathLength.
- */
- if (minPathLength >= 0){
- if ((!basicConstraints) || (caFlag == PKIX_FALSE)){
- PKIX_ERROR(PKIX_CERTNOTALLOWEDTOSIGNCERTIFICATES);
- } else if ((pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) &&
- (pathLength < minPathLength)){
- PKIX_CERTSELECTOR_DEBUG
- ("Basic Constraints path length match failed\n");
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
- }
- }
-
- /* if the minPathLength is -2, this cert must be an end-entity cert. */
- if (minPathLength == PKIX_CERTSEL_ENDENTITY_MIN_PATHLENGTH) {
- if (caFlag == PKIX_TRUE) {
- PKIX_CERTSELECTOR_DEBUG
- ("Basic Constraints end-entity match failed\n");
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_PATHLENCONSTRAINTINVALID);
- }
- }
-
-cleanup:
-
- PKIX_DECREF(basicConstraints);
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_Policies
- * DESCRIPTION:
- *
- * Determines whether the Cert pointed to by "cert" matches the policy
- * constraints specified in the ComCertsSelParams given by "params".
- * If "params" specifies a policy constraint of NULL, all certificates
- * match. If "params" specifies an empty list, "cert" must have at least
- * some policy. Otherwise "cert" must include at least one of the
- * policies in the list. See the description of PKIX_CertSelector in
- * pkix_certsel.h for more.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose policy criterion (if any) is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_Policies(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 numConstraintPolicies = 0;
- PKIX_UInt32 numCertPolicies = 0;
- PKIX_UInt32 certPolicyIndex = 0;
- PKIX_Boolean result = PKIX_FALSE;
- PKIX_List *constraintPolicies = NULL; /* List of PKIX_PL_OID */
- PKIX_List *certPolicyInfos = NULL; /* List of PKIX_PL_CertPolicyInfo */
- PKIX_PL_CertPolicyInfo *policyInfo = NULL;
- PKIX_PL_OID *polOID = NULL;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_Policies");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetPolicy
- (params, &constraintPolicies, plContext),
- PKIX_COMCERTSELPARAMSGETPOLICYFAILED);
-
- /* If constraintPolicies is NULL, all certificates "match" */
- if (constraintPolicies) {
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
- (cert, &certPolicyInfos, plContext),
- PKIX_CERTGETPOLICYINFORMATIONFAILED);
-
- /* No hope of a match if cert has no policies */
- if (!certPolicyInfos) {
- PKIX_CERTSELECTOR_DEBUG("Certificate has no policies\n");
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
- }
-
- PKIX_CHECK(PKIX_List_GetLength
- (constraintPolicies, &numConstraintPolicies, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (numConstraintPolicies > 0) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (certPolicyInfos, &numCertPolicies, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (certPolicyIndex = 0;
- ((!result) && (certPolicyIndex < numCertPolicies));
- certPolicyIndex++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (certPolicyInfos,
- certPolicyIndex,
- (PKIX_PL_Object **)&policyInfo,
- plContext),
- PKIX_LISTGETELEMENTFAILED);
- PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolicyId
- (policyInfo, &polOID, plContext),
- PKIX_CERTPOLICYINFOGETPOLICYIDFAILED);
-
- PKIX_CHECK(pkix_List_Contains
- (constraintPolicies,
- (PKIX_PL_Object *)polOID,
- &result,
- plContext),
- PKIX_LISTCONTAINSFAILED);
- PKIX_DECREF(policyInfo);
- PKIX_DECREF(polOID);
- }
- if (!result) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHPOLICIESFAILED);
- }
- }
- }
-
-cleanup:
-
- PKIX_DECREF(constraintPolicies);
- PKIX_DECREF(certPolicyInfos);
- PKIX_DECREF(policyInfo);
- PKIX_DECREF(polOID);
-
- PKIX_RETURN(CERTSELECTOR);
-
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_CertificateValid
- * DESCRIPTION:
- *
- * Determines whether the Cert pointed to by "cert" matches the certificate
- * validity criterion using the CertificateValid field of the
- * ComCertSelParams pointed to by "params". If the CertificateValid field is
- * NULL, no validity check is done and the Cert is considered to match
- * the CertificateValid criterion. If the CertificateValid field specifies a
- * Date prior to the notBefore field in the Cert, or greater than the notAfter
- * field in the Cert, an Error is returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose certValid field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_CertificateValid(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_Date *validityTime = NULL;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_CertificateValid");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
- (params, &validityTime, plContext),
- PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
-
- /* If the validityTime is not set, all certificates are acceptable */
- if (validityTime) {
- PKIX_CHECK(PKIX_PL_Cert_CheckValidity
- (cert, validityTime, plContext),
- PKIX_CERTCHECKVALIDITYFAILED);
- }
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- *pResult = PKIX_FALSE;
- }
- PKIX_DECREF(validityTime);
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_NameConstraints
- * DESCRIPTION:
- *
- * Determines whether the Cert pointed to by "cert" matches the name
- * constraints criterion specified in the ComCertSelParams pointed to by
- * "params". If the name constraints field is NULL, no name constraints check
- * is done and the Cert is considered to match the name constraints criterion.
- * If the Cert does not match the name constraints criterion, an Error pointer
- * is returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose name constraints field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_NameConstraints(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_NameConstraints");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetNameConstraints
- (params, &nameConstraints, plContext),
- PKIX_COMCERTSELPARAMSGETNAMECONSTRAINTSFAILED);
-
- if (nameConstraints != NULL) {
-
- PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints
- (cert, nameConstraints, plContext),
- PKIX_CERTCHECKNAMECONSTRAINTSFAILED);
- }
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- *pResult = PKIX_FALSE;
- }
-
- PKIX_DECREF(nameConstraints);
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_PathToNames
- * DESCRIPTION:
- *
- * Determines whether the names at pathToNames in "params" complies with the
- * NameConstraints pointed to by "cert". If the pathToNames field is NULL
- * or there is no name constraints for this "cert", no checking is done
- * and the Cert is considered to match the name constraints criterion.
- * If the Cert does not match the name constraints criterion, an Error
- * pointer is returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose PathToNames field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_PathToNames(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_List *pathToNamesList = NULL;
- PKIX_Boolean passed = PKIX_FALSE;
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_PathToNames");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames
- (params, &pathToNamesList, plContext),
- PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED);
-
- if (pathToNamesList != NULL) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
- (cert, &nameConstraints, plContext),
- PKIX_CERTGETNAMECONSTRAINTSFAILED);
-
- if (nameConstraints != NULL) {
-
- PKIX_CHECK(PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
- (pathToNamesList, nameConstraints, &passed, plContext),
- PKIX_CERTNAMECONSTRAINTSCHECKNAMESINNAMESPACEFAILED);
-
- if (passed != PKIX_TRUE) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
- }
- }
-
- }
-
-cleanup:
-
- PKIX_DECREF(nameConstraints);
- PKIX_DECREF(pathToNamesList);
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_SubjAltNames
- * DESCRIPTION:
- *
- * Determines whether the names at subjAltNames in "params" match with the
- * SubjAltNames pointed to by "cert". If the subjAltNames field is NULL,
- * no name checking is done and the Cert is considered to match the
- * criterion. If the Cert does not match the criterion, an Error pointer
- * is returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose SubjAltNames field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_SubjAltNames(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_List *subjAltNamesList = NULL;
- PKIX_List *certSubjAltNames = NULL;
- PKIX_PL_GeneralName *name = NULL;
- PKIX_Boolean checkPassed = PKIX_FALSE;
- PKIX_Boolean matchAll = PKIX_TRUE;
- PKIX_UInt32 i, numItems;
- PKIX_UInt32 matchCount = 0;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjAltNames");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames
- (params, &matchAll, plContext),
- PKIX_COMCERTSELPARAMSGETMATCHALLSUBJALTNAMESFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames
- (params, &subjAltNamesList, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
-
- if (subjAltNamesList != NULL) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
- (cert, &certSubjAltNames, plContext),
- PKIX_CERTGETSUBJALTNAMESFAILED);
-
- if (certSubjAltNames == NULL) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
- }
-
- PKIX_CHECK(PKIX_List_GetLength
- (subjAltNamesList, &numItems, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (subjAltNamesList,
- i,
- (PKIX_PL_Object **) &name,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_List_Contains
- (certSubjAltNames,
- (PKIX_PL_Object *) name,
- &checkPassed,
- plContext),
- PKIX_LISTCONTAINSFAILED);
-
- PKIX_DECREF(name);
-
- if (checkPassed == PKIX_TRUE) {
-
- if (matchAll == PKIX_FALSE) {
- /* one match is good enough */
- matchCount = numItems;
- break;
- } else {
- /* else continue checking next */
- matchCount++;
- }
-
- }
-
- }
-
- if (matchCount != numItems) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
- }
- }
-
-cleanup:
-
- PKIX_DECREF(name);
- PKIX_DECREF(certSubjAltNames);
- PKIX_DECREF(subjAltNamesList);
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_ExtendedKeyUsage
- * DESCRIPTION:
- *
- * Determines whether the names at ExtKeyUsage in "params" matches with the
- * ExtKeyUsage pointed to by "cert". If the ExtKeyUsage criterion or
- * ExtKeyUsage in "cert" is NULL, no checking is done and the Cert is
- * considered a match. If the Cert does not match, an Error pointer is
- * returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose ExtKeyUsage field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_ExtendedKeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_List *extKeyUsageList = NULL;
- PKIX_List *certExtKeyUsageList = NULL;
- PKIX_PL_OID *ekuOid = NULL;
- PKIX_Boolean isContained = PKIX_FALSE;
- PKIX_UInt32 numItems = 0;
- PKIX_UInt32 i;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_ExtendedKeyUsage");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
- (params, &extKeyUsageList, plContext),
- PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
-
- if (extKeyUsageList == NULL) {
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
- (cert, &certExtKeyUsageList, plContext),
- PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
-
- if (certExtKeyUsageList != NULL) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (extKeyUsageList, &numItems, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (extKeyUsageList, i, (PKIX_PL_Object **)&ekuOid, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_List_Contains
- (certExtKeyUsageList,
- (PKIX_PL_Object *)ekuOid,
- &isContained,
- plContext),
- PKIX_LISTCONTAINSFAILED);
-
- PKIX_DECREF(ekuOid);
-
- if (isContained != PKIX_TRUE) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
- }
- }
- }
-
-cleanup:
-
- PKIX_DECREF(ekuOid);
- PKIX_DECREF(extKeyUsageList);
- PKIX_DECREF(certExtKeyUsageList);
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_KeyUsage
- * DESCRIPTION:
- *
- * Determines whether the bits at KeyUsage in "params" matches with the
- * KeyUsage pointed to by "cert". If the KeyUsage in params is 0
- * no checking is done and the Cert is considered a match. If the Cert does
- * not match, an Error pointer is returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose ExtKeyUsage field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_KeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 keyUsage = 0;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_KeyUsage");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetKeyUsage
- (params, &keyUsage, plContext),
- PKIX_COMCERTSELPARAMSGETKEYUSAGEFAILED);
-
- if (keyUsage != 0) {
-
- PKIX_CHECK(PKIX_PL_Cert_VerifyKeyUsage
- (cert, keyUsage, plContext),
- PKIX_CERTVERIFYKEYUSAGEFAILED);
-
- }
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- *pResult = PKIX_FALSE;
- }
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_SubjKeyId
- * DESCRIPTION:
- *
- * Determines whether the bytes at subjKeyId in "params" matches with the
- * Subject Key Identifier pointed to by "cert". If the subjKeyId in params is
- * set to NULL or the Cert doesn't have a Subject Key Identifier, no checking
- * is done and the Cert is considered a match. If the Cert does not match, an
- * Error pointer is returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose subjKeyId field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_SubjKeyId(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_ByteArray *selSubjKeyId = NULL;
- PKIX_PL_ByteArray *certSubjKeyId = NULL;
- PKIX_Boolean equals = PKIX_FALSE;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjKeyId");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubjKeyIdentifier
- (params, &selSubjKeyId, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJKEYIDENTIFIERFAILED);
-
- if (selSubjKeyId != NULL) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
- (cert, &certSubjKeyId, plContext),
- PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED);
-
- if (certSubjKeyId == NULL) {
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)selSubjKeyId,
- (PKIX_PL_Object *)certSubjKeyId,
- &equals,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (equals == PKIX_FALSE) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
- }
- }
-
-cleanup:
-
- PKIX_DECREF(selSubjKeyId);
- PKIX_DECREF(certSubjKeyId);
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_AuthKeyId
- * DESCRIPTION:
- *
- * Determines whether the bytes at authKeyId in "params" matches with the
- * Authority Key Identifier pointed to by "cert". If the authKeyId in params
- * is set to NULL, no checking is done and the Cert is considered a match. If
- * the Cert does not match, an Error pointer is returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose authKeyId field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_AuthKeyId(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_ByteArray *selAuthKeyId = NULL;
- PKIX_PL_ByteArray *certAuthKeyId = NULL;
- PKIX_Boolean equals = PKIX_FALSE;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_AuthKeyId");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetAuthorityKeyIdentifier
- (params, &selAuthKeyId, plContext),
- PKIX_COMCERTSELPARAMSGETAUTHORITYKEYIDENTIFIERFAILED);
-
- if (selAuthKeyId != NULL) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
- (cert, &certAuthKeyId, plContext),
- PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
-
- if (certAuthKeyId == NULL) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
- }
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)selAuthKeyId,
- (PKIX_PL_Object *)certAuthKeyId,
- &equals,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (equals != PKIX_TRUE) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
- }
- }
-
-cleanup:
-
- PKIX_DECREF(selAuthKeyId);
- PKIX_DECREF(certAuthKeyId);
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_SubjPKAlgId
- * DESCRIPTION:
- *
- * Determines whether the OID at subjPKAlgId in "params" matches with the
- * Subject Public Key Alg Id pointed to by "cert". If the subjPKAlgId in params
- * is set to NULL, no checking is done and the Cert is considered a match. If
- * the Cert does not match, an Error pointer is returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose subjPKAlgId field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_SubjPKAlgId(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_OID *selPKAlgId = NULL;
- PKIX_PL_OID *certPKAlgId = NULL;
- PKIX_Boolean equals = PKIX_FALSE;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPKAlgId");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPKAlgId
- (params, &selPKAlgId, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJPKALGIDFAILED);
-
- if (selPKAlgId != NULL) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKeyAlgId
- (cert, &certPKAlgId, plContext),
- PKIX_CERTGETSUBJECTPUBLICKEYALGIDFAILED);
-
- if (certPKAlgId != NULL) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
- }
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)selPKAlgId,
- (PKIX_PL_Object *)certPKAlgId,
- &equals,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (equals != PKIX_TRUE) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
- }
- }
-
-cleanup:
-
- PKIX_DECREF(selPKAlgId);
- PKIX_DECREF(certPKAlgId);
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Match_SubjPubKey
- * DESCRIPTION:
- *
- * Determines whether the key at subjPubKey in "params" matches with the
- * Subject Public Key pointed to by "cert". If the subjPubKey in params
- * is set to NULL, no checking is done and the Cert is considered a match. If
- * the Cert does not match, an Error pointer is returned.
- *
- * PARAMETERS:
- * "params"
- * Address of ComCertSelParams whose subPubKey field is used.
- * Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched. Must be non-NULL.
- * "pResult"
- * Address of PKIX_Boolean that returns the match result.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_Match_SubjPubKey(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_PublicKey *selPK = NULL;
- PKIX_PL_PublicKey *certPK = NULL;
- PKIX_Boolean equals = PKIX_FALSE;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_Match_SubjPubKey");
- PKIX_NULLCHECK_THREE(params, cert, pResult);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubjPubKey
- (params, &selPK, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJPUBKEYFAILED);
-
- if (selPK != NULL) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
- (cert, &certPK, plContext),
- PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
-
- if (certPK == NULL) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
- }
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)selPK,
- (PKIX_PL_Object *)certPK,
- &equals,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (equals != PKIX_TRUE) {
- *pResult = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
- }
- }
-
-cleanup:
-
- PKIX_DECREF(selPK);
- PKIX_DECREF(certPK);
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_DefaultMatch
- * DESCRIPTION:
- *
- * This default match function determines whether the specified Cert pointed
- * to by "cert" matches the criteria of the CertSelector pointed to by
- * "selector". If the Cert does not match the CertSelector's
- * criteria, an error will be thrown.
- *
- * This default match function understands how to process the most common
- * parameters. Any common parameter that is not set is assumed to be disabled,
- * which means this function will select all certificates without regard to
- * that particular disabled parameter. For example, if the SerialNumber
- * parameter is not set, this function will not filter out any certificate
- * based on its serial number. As such, if no parameters are set, all are
- * disabled and any certificate will match. If a parameter is disabled, its
- * associated PKIX_ComCertSelParams_Get* function returns a default value.
- * That value is -1 for PKIX_ComCertSelParams_GetBasicConstraints and
- * PKIX_ComCertSelParams_GetVersion, 0 for PKIX_ComCertSelParams_GetKeyUsage,
- * and NULL for all other Get functions.
- *
- * PARAMETERS:
- * "selector"
- * Address of CertSelector whose MatchCallback logic and parameters are
- * to be used. Must be non-NULL.
- * "cert"
- * Address of Cert that is to be matched using "selector".
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CertSelector_DefaultMatch(
- PKIX_CertSelector *selector,
- PKIX_PL_Cert *cert,
- void *plContext)
-{
- PKIX_ComCertSelParams *params = NULL;
- PKIX_PL_X500Name *certSubject = NULL;
- PKIX_PL_X500Name *selSubject = NULL;
- PKIX_PL_X500Name *certIssuer = NULL;
- PKIX_PL_X500Name *selIssuer = NULL;
- PKIX_PL_BigInt *certSerialNumber = NULL;
- PKIX_PL_BigInt *selSerialNumber = NULL;
- PKIX_PL_Cert *selCert = NULL;
- PKIX_PL_Date *selDate = NULL;
- PKIX_UInt32 selVersion = 0xFFFFFFFF;
- PKIX_UInt32 certVersion = 0;
- PKIX_Boolean result = PKIX_TRUE;
- PKIX_Boolean isLeafCert = PKIX_TRUE;
-
-#ifdef PKIX_BUILDDEBUG
- PKIX_PL_String *certString = NULL;
- void *certAscii = NULL;
- PKIX_UInt32 certAsciiLen;
-#endif
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_DefaultMatch");
- PKIX_NULLCHECK_TWO(selector, cert);
-
- PKIX_INCREF(selector->params);
- params = selector->params;
-
- /* Are we looking for CAs? */
- PKIX_CHECK(PKIX_ComCertSelParams_GetLeafCertFlag
- (params, &isLeafCert, plContext),
- PKIX_COMCERTSELPARAMSGETLEAFCERTFLAGFAILED);
-
- if (params == NULL){
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetVersion
- (params, &selVersion, plContext),
- PKIX_COMCERTSELPARAMSGETVERSIONFAILED);
-
- if (selVersion != 0xFFFFFFFF){
- PKIX_CHECK(PKIX_PL_Cert_GetVersion
- (cert, &certVersion, plContext),
- PKIX_CERTGETVERSIONFAILED);
-
- if (selVersion != certVersion) {
- PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTVERSIONFAILED);
- }
- }
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
- (params, &selSubject, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
-
- if (selSubject){
- PKIX_CHECK(PKIX_PL_Cert_GetSubject
- (cert, &certSubject, plContext),
- PKIX_CERTGETSUBJECTFAILED);
-
- if (certSubject){
- PKIX_CHECK(PKIX_PL_X500Name_Match
- (selSubject, certSubject, &result, plContext),
- PKIX_X500NAMEMATCHFAILED);
-
- if (result == PKIX_FALSE){
- PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
- }
- } else { /* cert has no subject */
- PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSUBJECTFAILED);
- }
- }
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetIssuer
- (params, &selIssuer, plContext),
- PKIX_COMCERTSELPARAMSGETISSUERFAILED);
-
- if (selIssuer){
- PKIX_CHECK(PKIX_PL_Cert_GetIssuer
- (cert, &certIssuer, plContext),
- PKIX_CERTGETISSUERFAILED);
-
- PKIX_CHECK(PKIX_PL_X500Name_Match
- (selIssuer, certIssuer, &result, plContext),
- PKIX_X500NAMEMATCHFAILED);
-
- if (result == PKIX_FALSE){
- PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTISSUERFAILED);
- }
- }
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSerialNumber
- (params, &selSerialNumber, plContext),
- PKIX_COMCERTSELPARAMSGETSERIALNUMBERFAILED);
-
- if (selSerialNumber){
- PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber
- (cert, &certSerialNumber, plContext),
- PKIX_CERTGETSERIALNUMBERFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)selSerialNumber,
- (PKIX_PL_Object *)certSerialNumber,
- &result,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (result == PKIX_FALSE){
- PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTSERIALNUMFAILED);
- }
- }
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetCertificate
- (params, &selCert, plContext),
- PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED);
-
- if (selCert){
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *) selCert,
- (PKIX_PL_Object *) cert,
- &result,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (result == PKIX_FALSE){
- PKIX_ERROR(PKIX_CERTSELECTORMATCHCERTOBJECTFAILED);
- }
- }
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
- (params, &selDate, plContext),
- PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
-
- if (selDate){
- PKIX_CHECK(PKIX_PL_Cert_CheckValidity
- (cert, selDate, plContext),
- PKIX_CERTCHECKVALIDITYFAILED);
- }
-
- PKIX_CHECK(pkix_CertSelector_Match_BasicConstraint
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHBASICCONSTRAINTFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_Policies
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHPOLICIESFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_CertificateValid
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHCERTIFICATEVALIDFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_NameConstraints
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHNAMECONSTRAINTSFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_PathToNames
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHPATHTONAMESFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_SubjAltNames
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHSUBJALTNAMESFAILED);
-
- /* Check key usage and cert type based on certificate usage. */
- PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, !isLeafCert,
- plContext),
- PKIX_CERTVERIFYCERTTYPEFAILED);
-
- /* Next two check are for user supplied additional KU and EKU. */
- PKIX_CHECK(pkix_CertSelector_Match_ExtendedKeyUsage
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHEXTENDEDKEYUSAGEFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_KeyUsage
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHKEYUSAGEFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_SubjKeyId
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHSUBJKEYIDFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_AuthKeyId
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHAUTHKEYIDFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_SubjPKAlgId
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHSUBJPKALGIDFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Match_SubjPubKey
- (params, cert, &result, plContext),
- PKIX_CERTSELECTORMATCHSUBJPUBKEYFAILED);
-
- /* if we reach here, the cert has successfully matched criteria */
-
-
-#ifdef PKIX_BUILDDEBUG
-
- PKIX_CHECK(pkix_pl_Cert_ToString_Helper
- (cert, PKIX_TRUE, &certString, plContext),
- PKIX_CERTTOSTRINGHELPERFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (certString,
- PKIX_ESCASCII,
- &certAscii,
- &certAsciiLen,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_CERTSELECTOR_DEBUG_ARG("Cert Selected:\n%s\n", certAscii);
-
-#endif
-
-cleanup:
-
-#ifdef PKIX_BUILDDEBUG
- PKIX_DECREF(certString);
- PKIX_FREE(certAscii);
-#endif
-
- PKIX_DECREF(certSubject);
- PKIX_DECREF(selSubject);
- PKIX_DECREF(certIssuer);
- PKIX_DECREF(selIssuer);
- PKIX_DECREF(certSerialNumber);
- PKIX_DECREF(selSerialNumber);
- PKIX_DECREF(selCert);
- PKIX_DECREF(selDate);
- PKIX_DECREF(params);
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CertSelector_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERTSELECTOR_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_CertSelector_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTSELECTOR, "pkix_CertSelector_RegisterSelf");
-
- entry.description = "CertSelector";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_CertSelector);
- entry.destructor = pkix_CertSelector_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_CertSelector_Duplicate;
-
- systemClasses[PKIX_CERTSELECTOR_TYPE] = entry;
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-
-/*
- * FUNCTION: PKIX_CertSelector_Create (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_CertSelector_Create(
- PKIX_CertSelector_MatchCallback callback,
- PKIX_PL_Object *certSelectorContext,
- PKIX_CertSelector **pSelector,
- void *plContext)
-{
- PKIX_CertSelector *selector = NULL;
-
- PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Create");
- PKIX_NULLCHECK_ONE(pSelector);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTSELECTOR_TYPE,
- sizeof (PKIX_CertSelector),
- (PKIX_PL_Object **)&selector,
- plContext),
- PKIX_COULDNOTCREATECERTSELECTOROBJECT);
-
- /*
- * if user specified a particular match callback, we use that one.
- * otherwise, we use the default match implementation which
- * understands how to process PKIX_ComCertSelParams
- */
-
- if (callback){
- selector->matchCallback = callback;
- } else {
- selector->matchCallback = pkix_CertSelector_DefaultMatch;
- }
-
- /* initialize other fields */
- selector->params = NULL;
-
- PKIX_INCREF(certSelectorContext);
- selector->context = certSelectorContext;
-
- *pSelector = selector;
-
-cleanup:
-
- PKIX_RETURN(CERTSELECTOR);
-
-}
-
-/*
- * FUNCTION: PKIX_CertSelector_GetMatchCallback
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_CertSelector_GetMatchCallback(
- PKIX_CertSelector *selector,
- PKIX_CertSelector_MatchCallback *pCallback,
- void *plContext)
-{
- PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetMatchCallback");
- PKIX_NULLCHECK_TWO(selector, pCallback);
-
- *pCallback = selector->matchCallback;
-
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: PKIX_CertSelector_GetCertSelectorContext
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_CertSelector_GetCertSelectorContext(
- PKIX_CertSelector *selector,
- PKIX_PL_Object **pCertSelectorContext,
- void *plContext)
-{
- PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_GetCertSelectorContext");
- PKIX_NULLCHECK_TWO(selector, pCertSelectorContext);
-
- PKIX_INCREF(selector->context);
-
- *pCertSelectorContext = selector->context;
-
-cleanup:
- PKIX_RETURN(CERTSELECTOR);
-}
-
-/*
- * FUNCTION: PKIX_CertSelector_GetCommonCertSelectorParams
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_CertSelector_GetCommonCertSelectorParams(
- PKIX_CertSelector *selector,
- PKIX_ComCertSelParams **pParams,
- void *plContext)
-{
- PKIX_ENTER(CERTSELECTOR,
- "PKIX_CertSelector_GetCommonCertSelectorParams");
-
- PKIX_NULLCHECK_TWO(selector, pParams);
-
- PKIX_INCREF(selector->params);
- *pParams = selector->params;
-
-cleanup:
- PKIX_RETURN(CERTSELECTOR);
-
-}
-
-/*
- * FUNCTION: PKIX_CertSelector_SetCommonCertSelectorParams
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_CertSelector_SetCommonCertSelectorParams(
- PKIX_CertSelector *selector,
- PKIX_ComCertSelParams *params,
- void *plContext)
-{
- PKIX_ENTER(CERTSELECTOR,
- "PKIX_CertSelector_SetCommonCertSelectorParams");
-
- PKIX_NULLCHECK_ONE(selector);
-
- PKIX_DECREF(selector->params);
- PKIX_INCREF(params);
- selector->params = params;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)selector, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(CERTSELECTOR);
-
-}
-
-/*
- * FUNCTION: pkix_CertSelector_Select
- * DESCRIPTION:
- *
- * This function applies the selector pointed to by "selector" to each Cert,
- * in turn, in the List pointed to by "before", and creates a List containing
- * all the Certs that matched, or passed the selection process, storing that
- * List at "pAfter". If no Certs match, an empty List is stored at "pAfter".
- *
- * The List returned in "pAfter" is immutable.
- *
- * PARAMETERS:
- * "selector"
- * Address of CertSelelector to be applied to the List. Must be non-NULL.
- * "before"
- * Address of List that is to be filtered. Must be non-NULL.
- * "pAfter"
- * Address at which resulting List, possibly empty, is stored. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CertSelector_Select(
- PKIX_CertSelector *selector,
- PKIX_List *before,
- PKIX_List **pAfter,
- void *plContext)
-{
- PKIX_UInt32 numBefore = 0;
- PKIX_UInt32 i = 0;
- PKIX_List *filtered = NULL;
- PKIX_PL_Cert *candidate = NULL;
-
- PKIX_ENTER(CERTSELECTOR, "PKIX_CertSelector_Select");
- PKIX_NULLCHECK_THREE(selector, before, pAfter);
-
- PKIX_CHECK(PKIX_List_Create(&filtered, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(before, &numBefore, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numBefore; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (before, i, (PKIX_PL_Object **)&candidate, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK_ONLY_FATAL(selector->matchCallback
- (selector, candidate, plContext),
- PKIX_CERTSELECTORMATCHCALLBACKFAILED);
-
- if (!(PKIX_ERROR_RECEIVED)) {
-
- PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem
- (filtered,
- (PKIX_PL_Object *)candidate,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
-
- pkixTempErrorReceived = PKIX_FALSE;
- PKIX_DECREF(candidate);
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable(filtered, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- /* Don't throw away the list if one Cert was bad! */
- pkixTempErrorReceived = PKIX_FALSE;
-
- *pAfter = filtered;
- filtered = NULL;
-
-cleanup:
-
- PKIX_DECREF(filtered);
- PKIX_DECREF(candidate);
-
- PKIX_RETURN(CERTSELECTOR);
-
-}
diff --git a/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.h b/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.h
deleted file mode 100755
index 33b648354..000000000
--- a/security/nss/lib/libpkix/pkix/certsel/pkix_certselector.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_certselector.h
- *
- * CertSelector Object Type Definition
- *
- */
-
-#ifndef _PKIX_CERTSELECTOR_H
-#define _PKIX_CERTSELECTOR_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_CertSelectorStruct {
- PKIX_CertSelector_MatchCallback matchCallback;
- PKIX_ComCertSelParams *params;
- PKIX_PL_Object *context;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_CertSelector_Select(
- PKIX_CertSelector *selector,
- PKIX_List *before,
- PKIX_List **pAfter,
- void *plContext);
-
-PKIX_Error *pkix_CertSelector_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_CERTSELECTOR_H */
diff --git a/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c b/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c
deleted file mode 100755
index a62f78d23..000000000
--- a/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c
+++ /dev/null
@@ -1,1188 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_comcertselparams.c
- *
- * ComCertSelParams Object Functions
- *
- */
-
-#include "pkix_comcertselparams.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_ComCertSelParams_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ComCertSelParams_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ComCertSelParams *params = NULL;
-
- PKIX_ENTER(COMCERTSELPARAMS, "pkix_ComCertSelParams_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a comCertSelParams object */
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_COMCERTSELPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTCOMCERTSELPARAMS);
-
- params = (PKIX_ComCertSelParams *)object;
-
- PKIX_DECREF(params->subject);
- PKIX_DECREF(params->policies);
- PKIX_DECREF(params->cert);
- PKIX_DECREF(params->nameConstraints);
- PKIX_DECREF(params->pathToNames);
- PKIX_DECREF(params->subjAltNames);
- PKIX_DECREF(params->date);
- PKIX_DECREF(params->extKeyUsage);
- PKIX_DECREF(params->certValid);
- PKIX_DECREF(params->issuer);
- PKIX_DECREF(params->serialNumber);
- PKIX_DECREF(params->authKeyId);
- PKIX_DECREF(params->subjKeyId);
- PKIX_DECREF(params->subjPubKey);
- PKIX_DECREF(params->subjPKAlgId);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ComCertSelParams_Duplicate
- * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ComCertSelParams_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_ComCertSelParams *params = NULL;
- PKIX_ComCertSelParams *paramsDuplicate = NULL;
-
- PKIX_ENTER(COMCERTSELPARAMS, "pkix_ComCertSelParams_Duplicate");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_COMCERTSELPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTCOMCERTSELPARAMS);
-
- params = (PKIX_ComCertSelParams *)object;
-
- PKIX_CHECK(PKIX_ComCertSelParams_Create(&paramsDuplicate, plContext),
- PKIX_COMCERTSELPARAMSCREATEFAILED);
-
- paramsDuplicate->minPathLength = params->minPathLength;
- paramsDuplicate->matchAllSubjAltNames = params->matchAllSubjAltNames;
-
- PKIX_DUPLICATE(params->subject, &paramsDuplicate->subject, plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE(params->policies, &paramsDuplicate->policies, plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- if (params->cert){
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- ((PKIX_PL_Object *)params->cert,
- (PKIX_PL_Object **)&paramsDuplicate->cert,
- plContext),
- PKIX_OBJECTDUPLICATEFAILED);
- }
-
- PKIX_DUPLICATE
- (params->nameConstraints,
- &paramsDuplicate->nameConstraints,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE
- (params->pathToNames,
- &paramsDuplicate->pathToNames,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE
- (params->subjAltNames,
- &paramsDuplicate->subjAltNames,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- if (params->date){
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- ((PKIX_PL_Object *)params->date,
- (PKIX_PL_Object **)&paramsDuplicate->date,
- plContext),
- PKIX_OBJECTDUPLICATEFAILED);
- }
-
- paramsDuplicate->keyUsage = params->keyUsage;
-
- PKIX_DUPLICATE(params->certValid,
- &paramsDuplicate->certValid,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE(params->issuer,
- &paramsDuplicate->issuer,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE(params->serialNumber,
- &paramsDuplicate->serialNumber,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE(params->authKeyId,
- &paramsDuplicate->authKeyId,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE(params->subjKeyId,
- &paramsDuplicate->subjKeyId,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE(params->subjPubKey,
- &paramsDuplicate->subjPubKey,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE(params->subjPKAlgId,
- &paramsDuplicate->subjPKAlgId,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- paramsDuplicate->leafCertFlag = params->leafCertFlag;
-
- *pNewObject = (PKIX_PL_Object *)paramsDuplicate;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(paramsDuplicate);
- }
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ComCertSelParams_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_COMCERTSELPARAMS_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_ComCertSelParams_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry* entry = &systemClasses[PKIX_COMCERTSELPARAMS_TYPE];
-
- PKIX_ENTER(COMCERTSELPARAMS, "pkix_ComCertSelParams_RegisterSelf");
-
- entry->description = "ComCertSelParams";
- entry->typeObjectSize = sizeof(PKIX_ComCertSelParams);
- entry->destructor = pkix_ComCertSelParams_Destroy;
- entry->duplicateFunction = pkix_ComCertSelParams_Duplicate;
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_Create (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_Create(
- PKIX_ComCertSelParams **pParams,
- void *plContext)
-{
- PKIX_ComCertSelParams *params = NULL;
-
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_Create");
- PKIX_NULLCHECK_ONE(pParams);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_COMCERTSELPARAMS_TYPE,
- sizeof (PKIX_ComCertSelParams),
- (PKIX_PL_Object **)&params,
- plContext),
- PKIX_COULDNOTCREATECOMMONCERTSELPARAMSOBJECT);
-
- /* initialize fields */
- params->version = 0xFFFFFFFF;
- params->minPathLength = -1;
- params->matchAllSubjAltNames = PKIX_TRUE;
- params->subject = NULL;
- params->policies = NULL;
- params->cert = NULL;
- params->nameConstraints = NULL;
- params->pathToNames = NULL;
- params->subjAltNames = NULL;
- params->extKeyUsage = NULL;
- params->keyUsage = 0;
- params->extKeyUsage = NULL;
- params->keyUsage = 0;
- params->date = NULL;
- params->certValid = NULL;
- params->issuer = NULL;
- params->serialNumber = NULL;
- params->authKeyId = NULL;
- params->subjKeyId = NULL;
- params->subjPubKey = NULL;
- params->subjPKAlgId = NULL;
- params->leafCertFlag = PKIX_FALSE;
-
- *pParams = params;
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubject (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubject(
- PKIX_ComCertSelParams *params,
- PKIX_PL_X500Name **pSubject,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetSubject");
- PKIX_NULLCHECK_TWO(params, pSubject);
-
- PKIX_INCREF(params->subject);
-
- *pSubject = params->subject;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubject (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubject(
- PKIX_ComCertSelParams *params,
- PKIX_PL_X500Name *subject,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetSubject");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->subject);
-
- PKIX_INCREF(subject);
-
- params->subject = subject;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetBasicConstraints
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetBasicConstraints(
- PKIX_ComCertSelParams *params,
- PKIX_Int32 *pMinPathLength,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_GetBasicConstraints");
- PKIX_NULLCHECK_TWO(params, pMinPathLength);
-
- *pMinPathLength = params->minPathLength;
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetBasicConstraints
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetBasicConstraints(
- PKIX_ComCertSelParams *params,
- PKIX_Int32 minPathLength,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_SetBasicConstraints");
- PKIX_NULLCHECK_ONE(params);
-
- params->minPathLength = minPathLength;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetPolicy (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetPolicy(
- PKIX_ComCertSelParams *params,
- PKIX_List **pPolicy, /* List of PKIX_PL_OID */
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetPolicy");
- PKIX_NULLCHECK_TWO(params, pPolicy);
-
- PKIX_INCREF(params->policies);
- *pPolicy = params->policies;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetPolicy (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetPolicy(
- PKIX_ComCertSelParams *params,
- PKIX_List *policy, /* List of PKIX_PL_OID */
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetPolicy");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->policies);
- PKIX_INCREF(policy);
- params->policies = policy;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetCertificate
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetCertificate(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert **pCert,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetCertificate");
- PKIX_NULLCHECK_TWO(params, pCert);
-
- PKIX_INCREF(params->cert);
- *pCert = params->cert;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetCertificate
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetCertificate(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Cert *cert,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetCertificate");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->cert);
- PKIX_INCREF(cert);
- params->cert = cert;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetCertificateValid
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetCertificateValid(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Date **pDate,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_GetCertificateValid");
-
- PKIX_NULLCHECK_TWO(params, pDate);
-
- PKIX_INCREF(params->date);
- *pDate = params->date;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetCertificateValid
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetCertificateValid(
- PKIX_ComCertSelParams *params,
- PKIX_PL_Date *date,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_SetCertificateValid");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->date);
- PKIX_INCREF(date);
- params->date = date;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetNameConstraints
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetNameConstraints(
- PKIX_ComCertSelParams *params,
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_GetNameConstraints");
- PKIX_NULLCHECK_TWO(params, pNameConstraints);
-
- PKIX_INCREF(params->nameConstraints);
-
- *pNameConstraints = params->nameConstraints;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetNameConstraints
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetNameConstraints(
- PKIX_ComCertSelParams *params,
- PKIX_PL_CertNameConstraints *nameConstraints,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_SetNameConstraints");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->nameConstraints);
- PKIX_INCREF(nameConstraints);
- params->nameConstraints = nameConstraints;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetPathToNames
- * (see comments in pkix_certsel.h)
- */PKIX_Error *
-PKIX_ComCertSelParams_GetPathToNames(
- PKIX_ComCertSelParams *params,
- PKIX_List **pNames, /* list of PKIX_PL_GeneralName */
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetPathToNames");
- PKIX_NULLCHECK_TWO(params, pNames);
-
- PKIX_INCREF(params->pathToNames);
-
- *pNames = params->pathToNames;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetPathToNames
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetPathToNames(
- PKIX_ComCertSelParams *params,
- PKIX_List *names, /* list of PKIX_PL_GeneralName */
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetPathToNames");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->pathToNames);
- PKIX_INCREF(names);
-
- params->pathToNames = names;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_AddPathToName
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_AddPathToName(
- PKIX_ComCertSelParams *params,
- PKIX_PL_GeneralName *name,
- void *plContext)
-{
- PKIX_List *pathToNamesList = NULL;
-
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_AddPathToName");
- PKIX_NULLCHECK_ONE(params);
-
- if (name == NULL) {
- goto cleanup;
- }
-
- if (params->pathToNames == NULL) {
- /* Create a list for name item */
- PKIX_CHECK(PKIX_List_Create(&pathToNamesList, plContext),
- PKIX_LISTCREATEFAILED);
-
- params->pathToNames = pathToNamesList;
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (params->pathToNames, (PKIX_PL_Object *)name, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubjAltNames
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubjAltNames(
- PKIX_ComCertSelParams *params,
- PKIX_List **pNames, /* list of PKIX_PL_GeneralName */
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetSubjAltNames");
- PKIX_NULLCHECK_TWO(params, pNames);
-
- PKIX_INCREF(params->subjAltNames);
-
- *pNames = params->subjAltNames;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubjAltNames
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubjAltNames(
- PKIX_ComCertSelParams *params,
- PKIX_List *names, /* list of PKIX_PL_GeneralName */
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetSubjAltNames");
- PKIX_NULLCHECK_TWO(params, names);
-
- PKIX_DECREF(params->subjAltNames);
- PKIX_INCREF(names);
-
- params->subjAltNames = names;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_AddSubjAltNames
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_AddSubjAltName(
- PKIX_ComCertSelParams *params,
- PKIX_PL_GeneralName *name,
- void *plContext)
-{
- PKIX_List *list = NULL;
-
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_AddSubjAltName");
- PKIX_NULLCHECK_TWO(params, name);
-
- if (params->subjAltNames == NULL) {
- PKIX_CHECK(PKIX_List_Create(&list, plContext),
- PKIX_LISTCREATEFAILED);
- params->subjAltNames = list;
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (params->subjAltNames, (PKIX_PL_Object *)name, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS)
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetMatchAllSubjAltNames
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetMatchAllSubjAltNames(
- PKIX_ComCertSelParams *params,
- PKIX_Boolean *pMatch,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_GetMatchAllSubjAltNames");
- PKIX_NULLCHECK_TWO(params, pMatch);
-
- *pMatch = params->matchAllSubjAltNames;
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetMatchAllSubjAltNames
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetMatchAllSubjAltNames(
- PKIX_ComCertSelParams *params,
- PKIX_Boolean match,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_SetMatchAllSubjAltNames");
- PKIX_NULLCHECK_ONE(params);
-
- params->matchAllSubjAltNames = match;
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetExtendedKeyUsage
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetExtendedKeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_List **pExtKeyUsage, /* list of PKIX_PL_OID */
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_GetExtendedKeyUsage");
- PKIX_NULLCHECK_TWO(params, pExtKeyUsage);
-
- PKIX_INCREF(params->extKeyUsage);
- *pExtKeyUsage = params->extKeyUsage;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetExtendedKeyUsage
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetExtendedKeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_List *extKeyUsage, /* list of PKIX_PL_OID */
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_SetExtendedKeyUsage");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->extKeyUsage);
- PKIX_INCREF(extKeyUsage);
-
- params->extKeyUsage = extKeyUsage;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetKeyUsage
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetKeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_UInt32 *pKeyUsage,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_GetKeyUsage");
- PKIX_NULLCHECK_TWO(params, pKeyUsage);
-
- *pKeyUsage = params->keyUsage;
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetKeyUsage
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetKeyUsage(
- PKIX_ComCertSelParams *params,
- PKIX_UInt32 keyUsage,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_SetKeyUsage");
- PKIX_NULLCHECK_ONE(params);
-
- params->keyUsage = keyUsage;
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetIssuer
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetIssuer(
- PKIX_ComCertSelParams *params,
- PKIX_PL_X500Name **pIssuer,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetIssuer");
- PKIX_NULLCHECK_TWO(params, pIssuer);
-
- PKIX_INCREF(params->issuer);
- *pIssuer = params->issuer;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetIssuer
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetIssuer(
- PKIX_ComCertSelParams *params,
- PKIX_PL_X500Name *issuer,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetIssuer");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->issuer);
- PKIX_INCREF(issuer);
- params->issuer = issuer;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSerialNumber
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSerialNumber(
- PKIX_ComCertSelParams *params,
- PKIX_PL_BigInt **pSerialNumber,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetSerialNumber");
- PKIX_NULLCHECK_TWO(params, pSerialNumber);
-
- PKIX_INCREF(params->serialNumber);
- *pSerialNumber = params->serialNumber;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSerialNumber
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSerialNumber(
- PKIX_ComCertSelParams *params,
- PKIX_PL_BigInt *serialNumber,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetSerialNumber");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->serialNumber);
- PKIX_INCREF(serialNumber);
- params->serialNumber = serialNumber;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetVersion
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetVersion(
- PKIX_ComCertSelParams *params,
- PKIX_UInt32 *pVersion,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetVersion");
- PKIX_NULLCHECK_TWO(params, pVersion);
-
- *pVersion = params->version;
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetVersion
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetVersion(
- PKIX_ComCertSelParams *params,
- PKIX_Int32 version,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetVersion");
- PKIX_NULLCHECK_ONE(params);
-
- params->version = version;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubjKeyIdentifier
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubjKeyIdentifier(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray **pSubjKeyId,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_GetSubjKeyIdentifier");
- PKIX_NULLCHECK_TWO(params, pSubjKeyId);
-
- PKIX_INCREF(params->subjKeyId);
-
- *pSubjKeyId = params->subjKeyId;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubjKeyIdentifier
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubjKeyIdentifier(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray *subjKeyId,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_SetSubjKeyIdentifier");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->subjKeyId);
- PKIX_INCREF(subjKeyId);
-
- params->subjKeyId = subjKeyId;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetAuthorityKeyIdentifier
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetAuthorityKeyIdentifier(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray **pAuthKeyId,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_GetAuthorityKeyIdentifier");
- PKIX_NULLCHECK_TWO(params, pAuthKeyId);
-
- PKIX_INCREF(params->authKeyId);
-
- *pAuthKeyId = params->authKeyId;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetAuthorityKeyIdentifier
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetAuthorityKeyIdentifier(
- PKIX_ComCertSelParams *params,
- PKIX_PL_ByteArray *authKeyId,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_SetAuthKeyIdentifier");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->authKeyId);
- PKIX_INCREF(authKeyId);
-
- params->authKeyId = authKeyId;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubjPubKey
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubjPubKey(
- PKIX_ComCertSelParams *params,
- PKIX_PL_PublicKey **pSubjPubKey,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetSubjPubKey");
- PKIX_NULLCHECK_TWO(params, pSubjPubKey);
-
- PKIX_INCREF(params->subjPubKey);
-
- *pSubjPubKey = params->subjPubKey;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubjPubKey
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubjPubKey(
- PKIX_ComCertSelParams *params,
- PKIX_PL_PublicKey *subjPubKey,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS,
- "PKIX_ComCertSelParams_SetSubjPubKey");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->subjPubKey);
- PKIX_INCREF(subjPubKey);
-
- params->subjPubKey = subjPubKey;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetSubjPKAlgId
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_GetSubjPKAlgId(
- PKIX_ComCertSelParams *params,
- PKIX_PL_OID **pAlgId,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetSubjPKAlgId");
- PKIX_NULLCHECK_TWO(params, pAlgId);
-
- PKIX_INCREF(params->subjPKAlgId);
-
- *pAlgId = params->subjPKAlgId;
-
-cleanup:
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetSubjPKAlgId
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetSubjPKAlgId(
- PKIX_ComCertSelParams *params,
- PKIX_PL_OID *algId,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetSubjPKAlgId");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->subjPKAlgId);
- PKIX_INCREF(algId);
-
- params->subjPKAlgId = algId;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_GetLeafCertFlag
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error*
-PKIX_ComCertSelParams_GetLeafCertFlag(
- PKIX_ComCertSelParams *params,
- PKIX_Boolean *pLeafFlag,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_GetLeafCertFlag");
- PKIX_NULLCHECK_TWO(params, pLeafFlag);
-
- *pLeafFlag = params->leafCertFlag;
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCertSelParams_SetLeafCertFlag
- * (see comments in pkix_certsel.h)
- */
-PKIX_Error *
-PKIX_ComCertSelParams_SetLeafCertFlag(
- PKIX_ComCertSelParams *params,
- PKIX_Boolean leafFlag,
- void *plContext)
-{
- PKIX_ENTER(COMCERTSELPARAMS, "PKIX_ComCertSelParams_SetLeafCertFlag");
- PKIX_NULLCHECK_ONE(params);
-
- params->leafCertFlag = leafFlag;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCERTSELPARAMS);
-}
diff --git a/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.h b/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.h
deleted file mode 100755
index 935c639f0..000000000
--- a/security/nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_comcertselparams.h
- *
- * ComCertSelParams Object Type Definition
- *
- */
-
-#ifndef _PKIX_COMCERTSELPARAMS_H
-#define _PKIX_COMCERTSELPARAMS_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * pathToNamesConstraint is Name Constraints generated based on the
- * pathToNames. We save a cached copy to save regeneration for each
- * check. SubjAltNames also has its cache, since SubjAltNames are
- * verified by checker, its cache copy is stored in checkerstate.
- */
-struct PKIX_ComCertSelParamsStruct {
- PKIX_Int32 version;
- PKIX_Int32 minPathLength;
- PKIX_Boolean matchAllSubjAltNames;
- PKIX_PL_X500Name *subject;
- PKIX_List *policies; /* List of PKIX_PL_OID */
- PKIX_PL_Cert *cert;
- PKIX_PL_CertNameConstraints *nameConstraints;
- PKIX_List *pathToNames; /* List of PKIX_PL_GeneralNames */
- PKIX_List *subjAltNames; /* List of PKIX_PL_GeneralNames */
- PKIX_List *extKeyUsage; /* List of PKIX_PL_OID */
- PKIX_UInt32 keyUsage;
- PKIX_PL_Date *date;
- PKIX_PL_Date *certValid;
- PKIX_PL_X500Name *issuer;
- PKIX_PL_BigInt *serialNumber;
- PKIX_PL_ByteArray *authKeyId;
- PKIX_PL_ByteArray *subjKeyId;
- PKIX_PL_PublicKey *subjPubKey;
- PKIX_PL_OID *subjPKAlgId;
- PKIX_Boolean leafCertFlag;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_ComCertSelParams_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_COMCERTSELPARAMS_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/Makefile b/security/nss/lib/libpkix/pkix/checker/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix/checker/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix/checker/config.mk b/security/nss/lib/libpkix/pkix/checker/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix/checker/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix/checker/manifest.mn b/security/nss/lib/libpkix/pkix/checker/manifest.mn
deleted file mode 100755
index f9566dde2..000000000
--- a/security/nss/lib/libpkix/pkix/checker/manifest.mn
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_basicconstraintschecker.h \
- pkix_certchainchecker.h \
- pkix_crlchecker.h \
- pkix_ekuchecker.h \
- pkix_expirationchecker.h \
- pkix_namechainingchecker.h \
- pkix_nameconstraintschecker.h \
- pkix_ocspchecker.h \
- pkix_policychecker.h \
- pkix_revocationmethod.h \
- pkix_revocationchecker.h \
- pkix_signaturechecker.h \
- pkix_targetcertchecker.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_basicconstraintschecker.c \
- pkix_certchainchecker.c \
- pkix_crlchecker.c \
- pkix_ekuchecker.c \
- pkix_expirationchecker.c \
- pkix_namechainingchecker.c \
- pkix_nameconstraintschecker.c \
- pkix_ocspchecker.c \
- pkix_revocationmethod.c \
- pkix_revocationchecker.c \
- pkix_policychecker.c \
- pkix_signaturechecker.c \
- pkix_targetcertchecker.c \
- $(NULL)
-
-LIBRARY_NAME = pkixchecker
-
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.c
deleted file mode 100755
index 0e7a87997..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_basicconstraintschecker.c
- *
- * Functions for basic constraints validation
- *
- */
-
-#include "pkix_basicconstraintschecker.h"
-
-/* --Private-BasicConstraintsCheckerState-Functions------------------------- */
-
-/*
- * FUNCTION: pkix_BasicConstraintsCheckerState_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_BasicConstraintsCheckerState_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- pkix_BasicConstraintsCheckerState *state = NULL;
-
- PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
- "pkix_BasicConstraintsCheckerState_Destroy");
-
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a basic constraints checker state */
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE, plContext),
- PKIX_OBJECTNOTBASICCONSTRAINTSCHECKERSTATE);
-
- state = (pkix_BasicConstraintsCheckerState *)object;
-
- PKIX_DECREF(state->basicConstraintsOID);
-
-cleanup:
-
- PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_BasicConstraintsCheckerState_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_BasicConstraintsCheckerState_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
- "pkix_BasicConstraintsCheckerState_RegisterSelf");
-
- entry.description = "BasicConstraintsCheckerState";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(pkix_BasicConstraintsCheckerState);
- entry.destructor = pkix_BasicConstraintsCheckerState_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE] = entry;
-
- PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_BasicConstraintsCheckerState_Create
- * DESCRIPTION:
- *
- * Creates a new BasicConstraintsCheckerState using the number of certs in
- * the chain represented by "certsRemaining" and stores it at "pState".
- *
- * PARAMETERS:
- * "certsRemaining"
- * Number of certificates in the chain.
- * "pState"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a BasicConstraintsCheckerState Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_BasicConstraintsCheckerState_Create(
- PKIX_UInt32 certsRemaining,
- pkix_BasicConstraintsCheckerState **pState,
- void *plContext)
-{
- pkix_BasicConstraintsCheckerState *state = NULL;
-
- PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
- "pkix_BasicConstraintsCheckerState_Create");
-
- PKIX_NULLCHECK_ONE(pState);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE,
- sizeof (pkix_BasicConstraintsCheckerState),
- (PKIX_PL_Object **)&state,
- plContext),
- PKIX_COULDNOTCREATEBASICCONSTRAINTSSTATEOBJECT);
-
- /* initialize fields */
- state->certsRemaining = certsRemaining;
- state->maxPathLength = PKIX_UNLIMITED_PATH_CONSTRAINT;
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_BASICCONSTRAINTS_OID,
- &state->basicConstraintsOID,
- plContext),
- PKIX_OIDCREATEFAILED);
-
- *pState = state;
- state = NULL;
-
-cleanup:
-
- PKIX_DECREF(state);
-
- PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
-}
-
-/* --Private-BasicConstraintsChecker-Functions------------------------------ */
-
-/*
- * FUNCTION: pkix_BasicConstraintsChecker_Check
- * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
- */
-PKIX_Error *
-pkix_BasicConstraintsChecker_Check(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Cert *cert,
- PKIX_List *unresolvedCriticalExtensions, /* list of PKIX_PL_OID */
- void **pNBIOContext,
- void *plContext)
-{
- PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
- pkix_BasicConstraintsCheckerState *state = NULL;
- PKIX_Boolean caFlag = PKIX_FALSE;
- PKIX_Int32 pathLength = 0;
- PKIX_Int32 maxPathLength_now;
- PKIX_Boolean isSelfIssued = PKIX_FALSE;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Check");
- PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
-
- *pNBIOContext = NULL; /* we never block on pending I/O */
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
- (checker, (PKIX_PL_Object **)&state, plContext),
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
-
- state->certsRemaining--;
-
- if (state->certsRemaining != 0) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
- (cert, &basicConstraints, plContext),
- PKIX_CERTGETBASICCONSTRAINTSFAILED);
-
- /* get CA Flag and path length */
- if (basicConstraints != NULL) {
- PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
- (basicConstraints,
- &caFlag,
- plContext),
- PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
-
- if (caFlag == PKIX_TRUE) {
- PKIX_CHECK
- (PKIX_PL_BasicConstraints_GetPathLenConstraint
- (basicConstraints,
- &pathLength,
- plContext),
- PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED);
- }
-
- }else{
- caFlag = PKIX_FALSE;
- pathLength = PKIX_UNLIMITED_PATH_CONSTRAINT;
- }
-
- PKIX_CHECK(pkix_IsCertSelfIssued
- (cert,
- &isSelfIssued,
- plContext),
- PKIX_ISCERTSELFISSUEDFAILED);
-
- maxPathLength_now = state->maxPathLength;
-
- if (isSelfIssued != PKIX_TRUE) {
-
- /* Not last CA Cert, but maxPathLength is down to zero */
- if (maxPathLength_now == 0) {
- PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDLN);
- }
-
- if (caFlag == PKIX_FALSE) {
- PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDCA);
- }
-
- if (maxPathLength_now > 0) { /* can be unlimited (-1) */
- maxPathLength_now--;
- }
-
- }
-
- if (caFlag == PKIX_TRUE) {
- if (maxPathLength_now == PKIX_UNLIMITED_PATH_CONSTRAINT){
- maxPathLength_now = pathLength;
- } else {
- /* If pathLength is not specified, don't set */
- if (pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) {
- maxPathLength_now =
- (maxPathLength_now > pathLength)?
- pathLength:maxPathLength_now;
- }
- }
- }
-
- state->maxPathLength = maxPathLength_now;
- }
-
- /* Remove Basic Constraints Extension OID from list */
- if (unresolvedCriticalExtensions != NULL) {
-
- PKIX_CHECK(pkix_List_Remove
- (unresolvedCriticalExtensions,
- (PKIX_PL_Object *) state->basicConstraintsOID,
- plContext),
- PKIX_LISTREMOVEFAILED);
- }
-
-
- PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
- (checker, (PKIX_PL_Object *)state, plContext),
- PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
-
-
-cleanup:
- PKIX_DECREF(state);
- PKIX_DECREF(basicConstraints);
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
-
-/*
- * FUNCTION: pkix_BasicConstraintsChecker_Initialize
- * DESCRIPTION:
- * Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_BasicConstraintsChecker_Initialize(
- PKIX_UInt32 certsRemaining,
- PKIX_CertChainChecker **pChecker,
- void *plContext)
-{
- pkix_BasicConstraintsCheckerState *state = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Initialize");
- PKIX_NULLCHECK_ONE(pChecker);
-
- PKIX_CHECK(pkix_BasicConstraintsCheckerState_Create
- (certsRemaining, &state, plContext),
- PKIX_BASICCONSTRAINTSCHECKERSTATECREATEFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_Create
- (pkix_BasicConstraintsChecker_Check,
- PKIX_FALSE,
- PKIX_FALSE,
- NULL,
- (PKIX_PL_Object *)state,
- pChecker,
- plContext),
- PKIX_CERTCHAINCHECKERCHECKFAILED);
-
-cleanup:
- PKIX_DECREF(state);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.h
deleted file mode 100755
index 7a8b09c37..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_basicconstraintschecker.h
- *
- * Header file for basic constraints checker.
- *
- */
-
-#ifndef _PKIX_BASICCONSTRAINTSCHECKER_H
-#define _PKIX_BASICCONSTRAINTSCHECKER_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct pkix_BasicConstraintsCheckerStateStruct \
- pkix_BasicConstraintsCheckerState;
-
-struct pkix_BasicConstraintsCheckerStateStruct{
- PKIX_PL_OID *basicConstraintsOID;
- PKIX_Int32 certsRemaining;
- PKIX_Int32 maxPathLength;
-};
-
-PKIX_Error *
-pkix_BasicConstraintsChecker_Initialize(
- PKIX_UInt32 numCerts,
- PKIX_CertChainChecker **pChecker,
- void *plContext);
-
-PKIX_Error *
-pkix_BasicConstraintsCheckerState_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_BASICCONSTRAINTSCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.c
deleted file mode 100755
index a6ea50d02..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_certchainchecker.c
- *
- * CertChainChecker Object Functions
- *
- */
-
-#include "pkix_certchainchecker.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_CertChainChecker_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CertChainChecker_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_CertChainChecker *checker = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_CertChainChecker_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a cert chain checker */
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTCHAINCHECKER_TYPE, plContext),
- PKIX_OBJECTNOTCERTCHAINCHECKER);
-
- checker = (PKIX_CertChainChecker *)object;
-
- PKIX_DECREF(checker->extensions);
- PKIX_DECREF(checker->state);
-
-cleanup:
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_CertChainChecker_Duplicate
- * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CertChainChecker_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_CertChainChecker *checker = NULL;
- PKIX_CertChainChecker *checkerDuplicate = NULL;
- PKIX_List *extensionsDuplicate = NULL;
- PKIX_PL_Object *stateDuplicate = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_CertChainChecker_Duplicate");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTCHAINCHECKER_TYPE, plContext),
- PKIX_OBJECTNOTCERTCHAINCHECKER);
-
- checker = (PKIX_CertChainChecker *)object;
-
- if (checker->extensions){
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- ((PKIX_PL_Object *)checker->extensions,
- (PKIX_PL_Object **)&extensionsDuplicate,
- plContext),
- PKIX_OBJECTDUPLICATEFAILED);
- }
-
- if (checker->state){
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- ((PKIX_PL_Object *)checker->state,
- (PKIX_PL_Object **)&stateDuplicate,
- plContext),
- PKIX_OBJECTDUPLICATEFAILED);
- }
-
- PKIX_CHECK(PKIX_CertChainChecker_Create
- (checker->checkCallback,
- checker->forwardChecking,
- checker->isForwardDirectionExpected,
- extensionsDuplicate,
- stateDuplicate,
- &checkerDuplicate,
- plContext),
- PKIX_CERTCHAINCHECKERCREATEFAILED);
-
- *pNewObject = (PKIX_PL_Object *)checkerDuplicate;
-
-cleanup:
-
- PKIX_DECREF(extensionsDuplicate);
- PKIX_DECREF(stateDuplicate);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_CertChainChecker_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERTCHAINCHECKER_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_CertChainChecker_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_CertChainChecker_RegisterSelf");
-
- entry.description = "CertChainChecker";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_CertChainChecker);
- entry.destructor = pkix_CertChainChecker_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_CertChainChecker_Duplicate;
-
- systemClasses[PKIX_CERTCHAINCHECKER_TYPE] = entry;
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-
-/*
- * FUNCTION: PKIX_CertChainChecker_Create (see comments in pkix_checker.h)
- */
-PKIX_Error *
-PKIX_CertChainChecker_Create(
- PKIX_CertChainChecker_CheckCallback callback,
- PKIX_Boolean forwardCheckingSupported,
- PKIX_Boolean isForwardDirectionExpected,
- PKIX_List *list, /* list of PKIX_PL_OID */
- PKIX_PL_Object *initialState,
- PKIX_CertChainChecker **pChecker,
- void *plContext)
-{
- PKIX_CertChainChecker *checker = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "PKIX_CertChainChecker_Create");
- PKIX_NULLCHECK_ONE(pChecker);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTCHAINCHECKER_TYPE,
- sizeof (PKIX_CertChainChecker),
- (PKIX_PL_Object **)&checker,
- plContext),
- PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT);
-
- /* initialize fields */
- checker->checkCallback = callback;
- checker->forwardChecking = forwardCheckingSupported;
- checker->isForwardDirectionExpected = isForwardDirectionExpected;
-
- PKIX_INCREF(list);
- checker->extensions = list;
-
- PKIX_INCREF(initialState);
- checker->state = initialState;
-
- *pChecker = checker;
- checker = NULL;
-cleanup:
-
- PKIX_DECREF(checker);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
-
-/*
- * FUNCTION: PKIX_CertChainChecker_GetCheckCallback
- * (see comments in pkix_checker.h)
- */
-PKIX_Error *
-PKIX_CertChainChecker_GetCheckCallback(
- PKIX_CertChainChecker *checker,
- PKIX_CertChainChecker_CheckCallback *pCallback,
- void *plContext)
-{
- PKIX_ENTER(CERTCHAINCHECKER, "PKIX_CertChainChecker_GetCheckCallback");
- PKIX_NULLCHECK_TWO(checker, pCallback);
-
- *pCallback = checker->checkCallback;
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: PKIX_CertChainChecker_IsForwardCheckingSupported
- * (see comments in pkix_checker.h)
- */
-PKIX_Error *
-PKIX_CertChainChecker_IsForwardCheckingSupported(
- PKIX_CertChainChecker *checker,
- PKIX_Boolean *pForwardCheckingSupported,
- void *plContext)
-{
- PKIX_ENTER
- (CERTCHAINCHECKER,
- "PKIX_CertChainChecker_IsForwardCheckingSupported");
- PKIX_NULLCHECK_TWO(checker, pForwardCheckingSupported);
-
- *pForwardCheckingSupported = checker->forwardChecking;
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: PKIX_CertChainChecker_IsForwardDirectionExpected
- * (see comments in pkix_checker.h)
- */
-PKIX_Error *
-PKIX_CertChainChecker_IsForwardDirectionExpected(
- PKIX_CertChainChecker *checker,
- PKIX_Boolean *pForwardDirectionExpected,
- void *plContext)
-{
- PKIX_ENTER
- (CERTCHAINCHECKER,
- "PKIX_CertChainChecker_IsForwardDirectionExpected");
- PKIX_NULLCHECK_TWO(checker, pForwardDirectionExpected);
-
- *pForwardDirectionExpected = checker->isForwardDirectionExpected;
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: PKIX_CertChainChecker_GetCertChainCheckerState
- * (see comments in pkix_checker.h)
- */
-PKIX_Error *
-PKIX_CertChainChecker_GetCertChainCheckerState(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Object **pCertChainCheckerState,
- void *plContext)
-{
- PKIX_ENTER(CERTCHAINCHECKER,
- "PKIX_CertChainChecker_GetCertChainCheckerState");
-
- PKIX_NULLCHECK_TWO(checker, pCertChainCheckerState);
-
- PKIX_INCREF(checker->state);
-
- *pCertChainCheckerState = checker->state;
-
-cleanup:
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
-
-/*
- * FUNCTION: PKIX_CertChainChecker_SetCertChainCheckerState
- * (see comments in pkix_checker.h)
- */
-PKIX_Error *
-PKIX_CertChainChecker_SetCertChainCheckerState(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Object *certChainCheckerState,
- void *plContext)
-{
- PKIX_ENTER(CERTCHAINCHECKER,
- "PKIX_CertChainChecker_SetCertChainCheckerState");
-
- PKIX_NULLCHECK_ONE(checker);
-
- /* DecRef old contents */
- PKIX_DECREF(checker->state);
-
- PKIX_INCREF(certChainCheckerState);
- checker->state = certChainCheckerState;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)checker, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: PKIX_CertChainChecker_GetSupportedExtensions
- * (see comments in pkix_checker.h)
- */
-PKIX_Error *
-PKIX_CertChainChecker_GetSupportedExtensions(
- PKIX_CertChainChecker *checker,
- PKIX_List **pExtensions, /* list of PKIX_PL_OID */
- void *plContext)
-{
- PKIX_ENTER(CERTCHAINCHECKER,
- "PKIX_CertChainChecker_GetSupportedExtensions");
-
- PKIX_NULLCHECK_TWO(checker, pExtensions);
-
- PKIX_INCREF(checker->extensions);
-
- *pExtensions = checker->extensions;
-
-cleanup:
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.h
deleted file mode 100755
index ff6454761..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_certchainchecker.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_certchainchecker.h
- *
- * CertChainChecker Object Type Definition
- *
- */
-
-#ifndef _PKIX_CERTCHAINCHECKER_H
-#define _PKIX_CERTCHAINCHECKER_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_CertChainCheckerStruct {
- PKIX_CertChainChecker_CheckCallback checkCallback;
- PKIX_List *extensions;
- PKIX_PL_Object *state;
- PKIX_Boolean forwardChecking;
- PKIX_Boolean isForwardDirectionExpected;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_CertChainChecker_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_CERTCHAINCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.c
deleted file mode 100644
index 63bccd565..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_defaultcrlchecker.c
- *
- * Functions for default CRL Checkers
- *
- */
-#include "pkix.h"
-#include "pkix_crlchecker.h"
-#include "pkix_tools.h"
-
-/* --Private-CRLChecker-Data-and-Types------------------------------- */
-
-typedef struct pkix_CrlCheckerStruct {
- /* RevocationMethod is the super class of CrlChecker. */
- pkix_RevocationMethod method;
- PKIX_List *certStores; /* list of CertStore */
- PKIX_PL_VerifyCallback crlVerifyFn;
-} pkix_CrlChecker;
-
-
-/* --Private-CRLChecker-Functions----------------------------------- */
-
-/*
- * FUNCTION: pkix_CrlCheckerstate_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CrlChecker_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- pkix_CrlChecker *state = NULL;
-
- PKIX_ENTER(CRLCHECKER, "pkix_CrlChecker_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a default CRL checker state */
- PKIX_CHECK(
- pkix_CheckType(object, PKIX_CRLCHECKER_TYPE, plContext),
- PKIX_OBJECTNOTCRLCHECKER);
-
- state = (pkix_CrlChecker *)object;
-
- PKIX_DECREF(state->certStores);
-
-cleanup:
-
- PKIX_RETURN(CRLCHECKER);
-}
-
-/*
- * FUNCTION: pkix_CrlChecker_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_CRLCHECKER_TYPE and its related functions
- * with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_CrlChecker_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry* entry = &systemClasses[PKIX_CRLCHECKER_TYPE];
-
- PKIX_ENTER(CRLCHECKER, "pkix_CrlChecker_RegisterSelf");
-
- entry->description = "CRLChecker";
- entry->typeObjectSize = sizeof(pkix_CrlChecker);
- entry->destructor = pkix_CrlChecker_Destroy;
-
- PKIX_RETURN(CRLCHECKER);
-}
-
-/*
- * FUNCTION: pkix_CrlChecker_Create
- *
- * DESCRIPTION:
- * Allocate and initialize CRLChecker state data.
- *
- * PARAMETERS
- * "certStores"
- * Address of CertStore List to be stored in state. Must be non-NULL.
- * "testDate"
- * Address of PKIX_PL_Date to be checked. May be NULL.
- * "trustedPubKey"
- * Trusted Anchor Public Key for verifying first Cert in the chain.
- * Must be non-NULL.
- * "certsRemaining"
- * Number of certificates remaining in the chain.
- * "nistCRLPolicyEnabled"
- * If enabled, enforce nist crl policy.
- * "pChecker"
- * Address of CRLChecker that is returned. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a DefaultCrlChecker Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error
- */
-PKIX_Error *
-pkix_CrlChecker_Create(PKIX_RevocationMethodType methodType,
- PKIX_UInt32 flags,
- PKIX_UInt32 priority,
- pkix_LocalRevocationCheckFn localRevChecker,
- pkix_ExternalRevocationCheckFn externalRevChecker,
- PKIX_List *certStores,
- PKIX_PL_VerifyCallback crlVerifyFn,
- pkix_RevocationMethod **pChecker,
- void *plContext)
-{
- pkix_CrlChecker *crlChecker = NULL;
-
- PKIX_ENTER(CRLCHECKER, "pkix_CrlChecker_Create");
- PKIX_NULLCHECK_TWO(certStores, pChecker);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CRLCHECKER_TYPE,
- sizeof (pkix_CrlChecker),
- (PKIX_PL_Object **)&crlChecker,
- plContext),
- PKIX_COULDNOTCREATECRLCHECKEROBJECT);
-
- pkixErrorResult = pkix_RevocationMethod_Init(
- (pkix_RevocationMethod*)crlChecker, methodType, flags, priority,
- localRevChecker, externalRevChecker, plContext);
- if (pkixErrorResult) {
- goto cleanup;
- }
-
- /* Initialize fields */
- PKIX_INCREF(certStores);
- crlChecker->certStores = certStores;
-
- crlChecker->crlVerifyFn = crlVerifyFn;
- *pChecker = (pkix_RevocationMethod*)crlChecker;
- crlChecker = NULL;
-
-cleanup:
- PKIX_DECREF(crlChecker);
-
- PKIX_RETURN(CRLCHECKER);
-}
-
-/* --Private-CRLChecker-Functions------------------------------------ */
-
-/*
- * FUNCTION: pkix_CrlChecker_CheckLocal
- *
- * DESCRIPTION:
- * Check if the Cert has been revoked based the CRLs data. This function
- * maintains the checker state to be current.
- *
- * PARAMETERS
- * "checker"
- * Address of CertChainChecker which has the state data.
- * Must be non-NULL.
- * "cert"
- * Address of Certificate that is to be validated. Must be non-NULL.
- * "unreslvdCrtExts"
- * A List OIDs. Not **yet** used in this checker function.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Not Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error
- */
-PKIX_Error *
-pkix_CrlChecker_CheckLocal(
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_Boolean chainVerificationState,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *pReasonCode,
- void *plContext)
-{
- PKIX_CertStore_CheckRevokationByCrlCallback storeCheckRevocationFn;
- PKIX_CertStore *certStore = NULL;
- pkix_CrlChecker *state = NULL;
- PKIX_UInt32 reasonCode = 0;
- PKIX_UInt32 crlStoreIndex = 0;
- PKIX_UInt32 numCrlStores = 0;
- PKIX_Boolean storeIsLocal = PKIX_FALSE;
- PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_CrlChecker_CheckLocal");
- PKIX_NULLCHECK_FOUR(cert, issuer, checkerObject, checkerObject);
-
- state = (pkix_CrlChecker*)checkerObject;
-
- PKIX_CHECK(
- PKIX_List_GetLength(state->certStores, &numCrlStores, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (;crlStoreIndex < numCrlStores;crlStoreIndex++) {
- PKIX_CHECK(
- PKIX_List_GetItem(state->certStores, crlStoreIndex,
- (PKIX_PL_Object **)&certStore,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(
- PKIX_CertStore_GetLocalFlag(certStore, &storeIsLocal,
- plContext),
- PKIX_CERTSTOREGETLOCALFLAGFAILED);
- if (storeIsLocal) {
- PKIX_CHECK(
- PKIX_CertStore_GetCrlCheckerFn(certStore,
- &storeCheckRevocationFn,
- plContext),
- PKIX_CERTSTOREGETCHECKREVBYCRLFAILED);
-
- if (storeCheckRevocationFn) {
- PKIX_CHECK(
- (*storeCheckRevocationFn)(certStore, cert, issuer,
- /* delay sig check if building
- * a chain by not specifying the time*/
- chainVerificationState ? date : NULL,
- /* crl downloading is not done. */
- PKIX_FALSE,
- &reasonCode, &revStatus, plContext),
- PKIX_CERTSTORECRLCHECKFAILED);
- if (revStatus == PKIX_RevStatus_Revoked) {
- break;
- }
- }
- }
- PKIX_DECREF(certStore);
- } /* while */
-
-cleanup:
- *pRevStatus = revStatus;
- PKIX_DECREF(certStore);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_CrlChecker_CheckRemote
- *
- * DESCRIPTION:
- * Check if the Cert has been revoked based the CRLs data. This function
- * maintains the checker state to be current.
- *
- * PARAMETERS
- * "checker"
- * Address of CertChainChecker which has the state data.
- * Must be non-NULL.
- * "cert"
- * Address of Certificate that is to be validated. Must be non-NULL.
- * "unreslvdCrtExts"
- * A List OIDs. Not **yet** used in this checker function.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Not Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error
- */
-PKIX_Error *
-pkix_CrlChecker_CheckExternal(
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *pReasonCode,
- void **pNBIOContext,
- void *plContext)
-{
- PKIX_CertStore_CheckRevokationByCrlCallback storeCheckRevocationFn = NULL;
- PKIX_CertStore_ImportCrlCallback storeImportCrlFn = NULL;
- PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
- PKIX_CertStore *certStore = NULL;
- PKIX_CertStore *localStore = NULL;
- PKIX_CRLSelector *crlSelector = NULL;
- PKIX_PL_X500Name *issuerName = NULL;
- pkix_CrlChecker *state = NULL;
- PKIX_UInt32 reasonCode = 0;
- PKIX_UInt32 crlStoreIndex = 0;
- PKIX_UInt32 numCrlStores = 0;
- PKIX_Boolean storeIsLocal = PKIX_FALSE;
- PKIX_List *crlList = NULL;
- PKIX_List *dpList = NULL;
- void *nbioContext = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_CrlChecker_CheckExternal");
- PKIX_NULLCHECK_FOUR(cert, issuer, checkerObject, pNBIOContext);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL; /* prepare for Error exit */
-
- state = (pkix_CrlChecker*)checkerObject;
-
- PKIX_CHECK(
- PKIX_List_GetLength(state->certStores, &numCrlStores, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- /* Find a cert store that is capable of storing crls */
- for (;crlStoreIndex < numCrlStores;crlStoreIndex++) {
- PKIX_CHECK(
- PKIX_List_GetItem(state->certStores, crlStoreIndex,
- (PKIX_PL_Object **)&certStore,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(
- PKIX_CertStore_GetLocalFlag(certStore, &storeIsLocal,
- plContext),
- PKIX_CERTSTOREGETLOCALFLAGFAILED);
- if (storeIsLocal) {
- PKIX_CHECK(
- PKIX_CertStore_GetImportCrlCallback(certStore,
- &storeImportCrlFn,
- plContext),
- PKIX_CERTSTOREGETCHECKREVBYCRLFAILED);
-
- PKIX_CHECK(
- PKIX_CertStore_GetCrlCheckerFn(certStore,
- &storeCheckRevocationFn,
- plContext),
- PKIX_CERTSTOREGETCHECKREVBYCRLFAILED);
-
- if (storeImportCrlFn && storeCheckRevocationFn) {
- localStore = certStore;
- certStore = NULL;
- break;
- }
- }
- PKIX_DECREF(certStore);
- } /* while */
-
- /* Report unknown status if we can not check crl in one of the
- * local stores. */
- if (!localStore) {
- PKIX_ERROR_FATAL(PKIX_CRLCHECKERNOLOCALCERTSTOREFOUND);
- }
- PKIX_CHECK(
- PKIX_PL_Cert_VerifyKeyUsage(issuer, PKIX_CRL_SIGN, plContext),
- PKIX_CERTCHECKKEYUSAGEFAILED);
- PKIX_CHECK(
- PKIX_PL_Cert_GetCrlDp(cert, &dpList, plContext),
- PKIX_CERTGETCRLDPFAILED);
- if (!(methodFlags & PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE) &&
- (!dpList || !dpList->length)) {
- goto cleanup;
- }
- PKIX_CHECK(
- PKIX_PL_Cert_GetIssuer(cert, &issuerName, plContext),
- PKIX_CERTGETISSUERFAILED);
- PKIX_CHECK(
- PKIX_CRLSelector_Create(issuer, dpList, date, &crlSelector, plContext),
- PKIX_CRLCHECKERSETSELECTORFAILED);
- /* Fetch crl and store in a local cert store */
- for (crlStoreIndex = 0;crlStoreIndex < numCrlStores;crlStoreIndex++) {
- PKIX_CertStore_CRLCallback getCrlsFn;
-
- PKIX_CHECK(
- PKIX_List_GetItem(state->certStores, crlStoreIndex,
- (PKIX_PL_Object **)&certStore,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(
- PKIX_CertStore_GetCRLCallback(certStore, &getCrlsFn,
- plContext),
- PKIX_CERTSTOREGETCRLCALLBACKFAILED);
-
- PKIX_CHECK(
- (*getCrlsFn)(certStore, crlSelector, &nbioContext,
- &crlList, plContext),
- PKIX_GETCRLSFAILED);
-
- PKIX_CHECK(
- (*storeImportCrlFn)(localStore, issuerName, crlList, plContext),
- PKIX_CERTSTOREFAILTOIMPORTCRLLIST);
-
- PKIX_CHECK(
- (*storeCheckRevocationFn)(certStore, cert, issuer, date,
- /* done with crl downloading */
- PKIX_TRUE,
- &reasonCode, &revStatus, plContext),
- PKIX_CERTSTORECRLCHECKFAILED);
- if (revStatus != PKIX_RevStatus_NoInfo) {
- break;
- }
- PKIX_DECREF(crlList);
- PKIX_DECREF(certStore);
- } /* while */
-
-cleanup:
- /* Update return flags */
- if (revStatus == PKIX_RevStatus_NoInfo &&
- ((dpList && dpList->length > 0) ||
- (methodFlags & PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE)) &&
- methodFlags & PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
- revStatus = PKIX_RevStatus_Revoked;
- }
- *pRevStatus = revStatus;
-
- PKIX_DECREF(dpList);
- PKIX_DECREF(crlList);
- PKIX_DECREF(certStore);
- PKIX_DECREF(issuerName);
- PKIX_DECREF(localStore);
- PKIX_DECREF(crlSelector);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.h
deleted file mode 100644
index d7213aadb..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_crlchecker.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_defaultcrlchecker.h
- *
- * Header file for default CRL function
- *
- */
-
-#ifndef _PKIX_CRLCHECKER_H
-#define _PKIX_CRLCHECKER_H
-
-#include "pkixt.h"
-#include "pkix_revocationmethod.h"
-#include "pkix_crlsel.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* NOTE: nbio logic removed. Will be replaced later. */
-
-PKIX_Error *
-pkix_CrlChecker_CheckLocal(
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_Boolean chainVerificationState,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *reasonCode,
- void *plContext);
-
-PKIX_Error *
-pkix_CrlChecker_CheckExternal(
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *reasonCode,
- void **pNBIOContext,
- void *plContext);
-
-PKIX_Error *
-pkix_CrlChecker_Create(PKIX_RevocationMethodType methodType,
- PKIX_UInt32 flags,
- PKIX_UInt32 priority,
- pkix_LocalRevocationCheckFn localRevChecker,
- pkix_ExternalRevocationCheckFn externalRevChecker,
- PKIX_List *certStores,
- PKIX_PL_VerifyCallback crlVerifyFn,
- pkix_RevocationMethod **pChecker,
- void *plContext);
-
-PKIX_Error *
-pkix_CrlChecker_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_CRLCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c
deleted file mode 100644
index a2b843739..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_ekuchecker.c
- *
- * User Defined ExtenedKeyUsage Function Definitions
- *
- */
-
-#include "pkix_ekuchecker.h"
-
-SECOidTag ekuOidStrings[] = {
- PKIX_KEY_USAGE_SERVER_AUTH_OID,
- PKIX_KEY_USAGE_CLIENT_AUTH_OID,
- PKIX_KEY_USAGE_CODE_SIGN_OID,
- PKIX_KEY_USAGE_EMAIL_PROTECT_OID,
- PKIX_KEY_USAGE_TIME_STAMP_OID,
- PKIX_KEY_USAGE_OCSP_RESPONDER_OID,
- PKIX_UNKNOWN_OID
-};
-
-typedef struct pkix_EkuCheckerStruct {
- PKIX_List *requiredExtKeyUsageOids;
- PKIX_PL_OID *ekuOID;
-} pkix_EkuChecker;
-
-
-/*
- * FUNCTION: pkix_EkuChecker_Destroy
- * (see comments for PKIX_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_EkuChecker_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- pkix_EkuChecker *ekuCheckerState = NULL;
-
- PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_EKUCHECKER_TYPE, plContext),
- PKIX_OBJECTNOTANEKUCHECKERSTATE);
-
- ekuCheckerState = (pkix_EkuChecker *)object;
-
- PKIX_DECREF(ekuCheckerState->ekuOID);
- PKIX_DECREF(ekuCheckerState->requiredExtKeyUsageOids);
-
-cleanup:
-
- PKIX_RETURN(EKUCHECKER);
-}
-
-/*
- * FUNCTION: pkix_EkuChecker_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related
- * functions with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_EkuChecker_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry *entry = &systemClasses[PKIX_EKUCHECKER_TYPE];
-
- PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_RegisterSelf");
-
- entry->description = "EkuChecker";
- entry->typeObjectSize = sizeof(pkix_EkuChecker);
- entry->destructor = pkix_EkuChecker_Destroy;
-
- PKIX_RETURN(EKUCHECKER);
-}
-
-/*
- * FUNCTION: pkix_EkuChecker_Create
- * DESCRIPTION:
- *
- * Creates a new Extend Key Usage CheckerState using "params" to retrieve
- * application specified EKU for verification and stores it at "pState".
- *
- * PARAMETERS:
- * "params"
- * a PKIX_ProcessingParams links to PKIX_ComCertSelParams where a list of
- * Extended Key Usage OIDs specified by application can be retrieved for
- * verification.
- * "pState"
- * Address where state pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a UserDefinedModules Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_EkuChecker_Create(
- PKIX_ProcessingParams *params,
- pkix_EkuChecker **pState,
- void *plContext)
-{
- pkix_EkuChecker *state = NULL;
- PKIX_CertSelector *certSelector = NULL;
- PKIX_ComCertSelParams *comCertSelParams = NULL;
- PKIX_List *requiredOids = NULL;
-
- PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Create");
- PKIX_NULLCHECK_TWO(params, pState);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_EKUCHECKER_TYPE,
- sizeof (pkix_EkuChecker),
- (PKIX_PL_Object **)&state,
- plContext),
- PKIX_COULDNOTCREATEEKUCHECKERSTATEOBJECT);
-
-
- PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
- (params, &certSelector, plContext),
- PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
-
- if (certSelector != NULL) {
-
- /* Get initial EKU OIDs from ComCertSelParams, if set */
- PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
- (certSelector, &comCertSelParams, plContext),
- PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
-
- if (comCertSelParams != NULL) {
- PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
- (comCertSelParams, &requiredOids, plContext),
- PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
-
- }
- }
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_EXTENDEDKEYUSAGE_OID,
- &state->ekuOID,
- plContext),
- PKIX_OIDCREATEFAILED);
-
- state->requiredExtKeyUsageOids = requiredOids;
- requiredOids = NULL;
- *pState = state;
- state = NULL;
-
-cleanup:
-
- PKIX_DECREF(certSelector);
- PKIX_DECREF(comCertSelParams);
- PKIX_DECREF(requiredOids);
- PKIX_DECREF(state);
-
- PKIX_RETURN(EKUCHECKER);
-}
-
-/*
- * FUNCTION: pkix_EkuChecker_Check
- * DESCRIPTION:
- *
- * This function determines the Extended Key Usage OIDs specified by the
- * application is included in the Extended Key Usage OIDs of this "cert".
- *
- * PARAMETERS:
- * "checker"
- * Address of CertChainChecker which has the state data.
- * Must be non-NULL.
- * "cert"
- * Address of Certificate that is to be validated. Must be non-NULL.
- * "unresolvedCriticalExtensions"
- * A List OIDs. The OID for Extended Key Usage is removed.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a UserDefinedModules Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_EkuChecker_Check(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Cert *cert,
- PKIX_List *unresolvedCriticalExtensions,
- void **pNBIOContext,
- void *plContext)
-{
- pkix_EkuChecker *state = NULL;
- PKIX_List *requiredExtKeyUsageList = NULL;
- PKIX_List *certExtKeyUsageList = NULL;
- PKIX_PL_OID *ekuOid = NULL;
- PKIX_Boolean isContained = PKIX_FALSE;
- PKIX_UInt32 numItems = 0;
- PKIX_UInt32 i;
- PKIX_Boolean checkResult = PKIX_TRUE;
-
- PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Check");
- PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
-
- *pNBIOContext = NULL; /* no non-blocking IO */
-
- PKIX_CHECK(
- PKIX_CertChainChecker_GetCertChainCheckerState
- (checker, (PKIX_PL_Object **)&state, plContext),
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
-
- requiredExtKeyUsageList = state->requiredExtKeyUsageOids;
- if (requiredExtKeyUsageList == NULL) {
- goto cleanup;
- }
-
- PKIX_CHECK(
- PKIX_List_GetLength(requiredExtKeyUsageList, &numItems,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
- if (numItems == 0) {
- goto cleanup;
- }
-
- PKIX_CHECK(
- PKIX_PL_Cert_GetExtendedKeyUsage(cert, &certExtKeyUsageList,
- plContext),
- PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
-
- if (certExtKeyUsageList == NULL) {
- goto cleanup;
- }
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_CHECK(
- PKIX_List_GetItem(requiredExtKeyUsageList, i,
- (PKIX_PL_Object **)&ekuOid, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(
- pkix_List_Contains(certExtKeyUsageList,
- (PKIX_PL_Object *)ekuOid,
- &isContained,
- plContext),
- PKIX_LISTCONTAINSFAILED);
-
- PKIX_DECREF(ekuOid);
- if (isContained != PKIX_TRUE) {
- checkResult = PKIX_FALSE;
- goto cleanup;
- }
- }
-
-cleanup:
- if (!pkixErrorResult && checkResult == PKIX_FALSE) {
- pkixErrorReceived = PKIX_TRUE;
- pkixErrorCode = PKIX_EXTENDEDKEYUSAGECHECKINGFAILED;
- }
-
- PKIX_DECREF(ekuOid);
- PKIX_DECREF(certExtKeyUsageList);
- PKIX_DECREF(state);
-
- PKIX_RETURN(EKUCHECKER);
-}
-
-/*
- * FUNCTION: pkix_EkuChecker_Initialize
- * (see comments in pkix_sample_modules.h)
- */
-PKIX_Error *
-PKIX_EkuChecker_Create(
- PKIX_ProcessingParams *params,
- PKIX_CertChainChecker **pEkuChecker,
- void *plContext)
-{
- pkix_EkuChecker *state = NULL;
- PKIX_List *critExtOIDsList = NULL;
-
- PKIX_ENTER(EKUCHECKER, "PKIX_EkuChecker_Initialize");
- PKIX_NULLCHECK_ONE(params);
-
- /*
- * This function and functions in this file provide an example of how
- * an application defined checker can be hooked into libpkix.
- */
-
- PKIX_CHECK(pkix_EkuChecker_Create
- (params, &state, plContext),
- PKIX_EKUCHECKERSTATECREATEFAILED);
-
- PKIX_CHECK(PKIX_List_Create(&critExtOIDsList, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (critExtOIDsList,
- (PKIX_PL_Object *)state->ekuOID,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_Create
- (pkix_EkuChecker_Check,
- PKIX_TRUE, /* forwardCheckingSupported */
- PKIX_FALSE, /* forwardDirectionExpected */
- critExtOIDsList,
- (PKIX_PL_Object *) state,
- pEkuChecker,
- plContext),
- PKIX_CERTCHAINCHECKERCREATEFAILED);
-cleanup:
-
- PKIX_DECREF(critExtOIDsList);
- PKIX_DECREF(state);
-
- PKIX_RETURN(EKUCHECKER);
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.h
deleted file mode 100644
index e542dda20..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_ekuchecker.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_ekuchecker.h
- *
- * User Defined Object Type Extended Key Usage Definition
- *
- */
-
-#ifndef _PKIX_EKUCHECKER_H
-#define _PKIX_EKUCHECKER_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * FUNCTION: PKIX_PL_EkuChecker_Create
- *
- * DESCRIPTION:
- * Create a CertChainChecker with EkuCheckerState and add it into
- * PKIX_ProcessingParams object.
- *
- * PARAMETERS
- * "params"
- * a PKIX_ProcessingParams links to PKIX_ComCertSelParams where a list of
- * Extended Key Usage OIDs specified by application can be retrieved for
- * verification.
- * "ekuChecker"
- * Address of created ekuchecker.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a UserDefinedModules Error if the function fails in a non-fatal
- * way.
- * Returns a Fatal Error
- */
-PKIX_Error *
-PKIX_EkuChecker_Create(
- PKIX_ProcessingParams *params,
- PKIX_CertChainChecker **ekuChecker,
- void *plContext);
-
-/*
- * FUNCTION: PKIX_PL_EkuChecker_GetRequiredEku
- *
- * DESCRIPTION:
- * This function retrieves application specified ExtenedKeyUsage(s) from
- * ComCertSetparams and converts its OID representations to SECCertUsageEnum.
- * The result is stored and returned in bit mask at "pRequiredExtKeyUsage".
- *
- * PARAMETERS
- * "certSelector"
- * a PKIX_CertSelector links to PKIX_ComCertSelParams where a list of
- * Extended Key Usage OIDs specified by application can be retrieved for
- * verification. Must be non-NULL.
- * "pRequiredExtKeyUsage"
- * Address where the result is returned. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a UserDefinedModules Error if the function fails in a non-fatal
- * way.
- * Returns a Fatal Error
- */
-PKIX_Error *
-pkix_EkuChecker_GetRequiredEku(
- PKIX_CertSelector *certSelector,
- PKIX_UInt32 *pRequiredExtKeyUsage,
- void *plContext);
-
-/* see source file for function documentation */
-PKIX_Error *pkix_EkuChecker_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_EKUCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.c
deleted file mode 100755
index 4f101ee29..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_expirationchecker.c
- *
- * Functions for expiration validation
- *
- */
-
-
-#include "pkix_expirationchecker.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_ExpirationChecker_Check
- * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
- */
-PKIX_Error *
-pkix_ExpirationChecker_Check(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Cert *cert,
- PKIX_List *unresolvedCriticalExtensions,
- void **pNBIOContext,
- void *plContext)
-{
- PKIX_PL_Date *testDate = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_ExpirationChecker_Check");
- PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
-
- *pNBIOContext = NULL; /* we never block on pending I/O */
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
- (checker, (PKIX_PL_Object **)&testDate, plContext),
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_CheckValidity(cert, testDate, plContext),
- PKIX_CERTCHECKVALIDITYFAILED);
-
-cleanup:
-
- PKIX_DECREF(testDate);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
-
-/*
- * FUNCTION: pkix_ExpirationChecker_Initialize
- * DESCRIPTION:
- *
- * Creates a new CertChainChecker and stores it at "pChecker", where it will
- * used by pkix_ExpirationChecker_Check to check that the certificate has not
- * expired with respect to the Date pointed to by "testDate." If "testDate"
- * is NULL, then the CertChainChecker will check that a certificate has not
- * expired with respect to the current date and time.
- *
- * PARAMETERS:
- * "testDate"
- * Address of Date representing the point in time at which the cert is to
- * be validated. If "testDate" is NULL, the current date and time is used.
- * "pChecker"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_ExpirationChecker_Initialize(
- PKIX_PL_Date *testDate,
- PKIX_CertChainChecker **pChecker,
- void *plContext)
-{
- PKIX_PL_Date *myDate = NULL;
- PKIX_PL_Date *nowDate = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_ExpirationChecker_Initialize");
- PKIX_NULLCHECK_ONE(pChecker);
-
- /* if testDate is NULL, we use the current time */
- if (!testDate){
- PKIX_CHECK(PKIX_PL_Date_Create_UTCTime
- (NULL, &nowDate, plContext),
- PKIX_DATECREATEUTCTIMEFAILED);
- myDate = nowDate;
- } else {
- myDate = testDate;
- }
-
- PKIX_CHECK(PKIX_CertChainChecker_Create
- (pkix_ExpirationChecker_Check,
- PKIX_TRUE,
- PKIX_FALSE,
- NULL,
- (PKIX_PL_Object *)myDate,
- pChecker,
- plContext),
- PKIX_CERTCHAINCHECKERCREATEFAILED);
-
-cleanup:
-
- PKIX_DECREF(nowDate);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.h
deleted file mode 100755
index 17b5c1bc1..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_expirationchecker.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_expirationchecker.h
- *
- * Header file for validate expiration function
- *
- */
-
-#ifndef _PKIX_EXPIRATIONCHECKER_H
-#define _PKIX_EXPIRATIONCHECKER_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-PKIX_Error *
-pkix_ExpirationChecker_Initialize(
- PKIX_PL_Date *testDate,
- PKIX_CertChainChecker **pChecker,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_EXPIRATIONCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.c
deleted file mode 100755
index 873d19cd0..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_namechainingchecker.c
- *
- * Functions for name chaining validation
- *
- */
-
-
-#include "pkix_namechainingchecker.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_NameChainingChecker_Check
- * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
- */
-PKIX_Error *
-pkix_NameChainingChecker_Check(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Cert *cert,
- PKIX_List *unresolvedCriticalExtensions,
- void **pNBIOContext,
- void *plContext)
-{
- PKIX_PL_X500Name *prevSubject = NULL;
- PKIX_PL_X500Name *currIssuer = NULL;
- PKIX_PL_X500Name *currSubject = NULL;
- PKIX_Boolean result;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameChainingChecker_Check");
- PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
-
- *pNBIOContext = NULL; /* we never block on pending I/O */
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
- (checker, (PKIX_PL_Object **)&prevSubject, plContext),
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetIssuer(cert, &currIssuer, plContext),
- PKIX_CERTGETISSUERFAILED);
-
- if (prevSubject){
- PKIX_CHECK(PKIX_PL_X500Name_Match
- (prevSubject, currIssuer, &result, plContext),
- PKIX_X500NAMEMATCHFAILED);
- if (!result){
- PKIX_ERROR(PKIX_NAMECHAININGCHECKFAILED);
- }
- } else {
- PKIX_ERROR(PKIX_NAMECHAININGCHECKFAILED);
- }
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &currSubject, plContext),
- PKIX_CERTGETSUBJECTFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
- (checker, (PKIX_PL_Object *)currSubject, plContext),
- PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
-
-cleanup:
-
- PKIX_DECREF(prevSubject);
- PKIX_DECREF(currIssuer);
- PKIX_DECREF(currSubject);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
-
-/*
- * FUNCTION: pkix_NameChainingChecker_Initialize
- * DESCRIPTION:
- *
- * Creates a new CertChainChecker and stores it at "pChecker", where it will
- * be used by pkix_NameChainingChecker_Check to check that the issuer name
- * of the certificate matches the subject name in the checker's state. The
- * X500Name pointed to by "trustedCAName" is used to initialize the checker's
- * state.
- *
- * PARAMETERS:
- * "trustedCAName"
- * Address of X500Name representing the trusted CA Name used to
- * initialize the state of this checker. Must be non-NULL.
- * "pChecker"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_NameChainingChecker_Initialize(
- PKIX_PL_X500Name *trustedCAName,
- PKIX_CertChainChecker **pChecker,
- void *plContext)
-{
- PKIX_ENTER(CERTCHAINCHECKER, "PKIX_NameChainingChecker_Initialize");
- PKIX_NULLCHECK_TWO(pChecker, trustedCAName);
-
- PKIX_CHECK(PKIX_CertChainChecker_Create
- (pkix_NameChainingChecker_Check,
- PKIX_FALSE,
- PKIX_FALSE,
- NULL,
- (PKIX_PL_Object *)trustedCAName,
- pChecker,
- plContext),
- PKIX_CERTCHAINCHECKERCREATEFAILED);
-
-cleanup:
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.h
deleted file mode 100755
index bc413f456..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_namechainingchecker.h
- *
- * Header file for name chaining checker.
- *
- */
-
-#ifndef _PKIX_NAMECHAININGCHECKER_H
-#define _PKIX_NAMECHAININGCHECKER_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-PKIX_Error *
-pkix_NameChainingChecker_Initialize(
- PKIX_PL_X500Name *trustedCAName,
- PKIX_CertChainChecker **pChecker,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_NAMECHAININGCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c
deleted file mode 100755
index c04aa262b..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_nameconstraintschecker.c
- *
- * Functions for Name Constraints Checkers
- *
- */
-
-#include "pkix_nameconstraintschecker.h"
-
-/* --Private-NameConstraintsCheckerState-Functions---------------------- */
-
-/*
- * FUNCTION: pkix_NameConstraintsCheckerstate_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_NameConstraintsCheckerState_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- pkix_NameConstraintsCheckerState *state = NULL;
-
- PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
- "pkix_NameConstraintsCheckerState_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that object type */
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE, plContext),
- PKIX_OBJECTNOTNAMECONSTRAINTSCHECKERSTATE);
-
- state = (pkix_NameConstraintsCheckerState *)object;
-
- PKIX_DECREF(state->nameConstraints);
- PKIX_DECREF(state->nameConstraintsOID);
-
-cleanup:
-
- PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_NameConstraintsCheckerState_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE and its related
- * functions with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_NameConstraintsCheckerState_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
- "pkix_NameConstraintsCheckerState_RegisterSelf");
-
- entry.description = "NameConstraintsCheckerState";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(pkix_NameConstraintsCheckerState);
- entry.destructor = pkix_NameConstraintsCheckerState_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE] = entry;
-
- PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_NameConstraintsCheckerState_Create
- *
- * DESCRIPTION:
- * Allocate and initialize NameConstraintsChecker state data.
- *
- * PARAMETERS
- * "nameConstraints"
- * Address of NameConstraints to be stored in state. May be NULL.
- * "numCerts"
- * Number of certificates in the validation chain. This data is used
- * to identify end-entity.
- * "pCheckerState"
- * Address of NameConstraintsCheckerState that is returned. Must be
- * non-NULL.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CERTNAMECONSTRAINTSCHECKERSTATE Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error
- */
-static PKIX_Error *
-pkix_NameConstraintsCheckerState_Create(
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_UInt32 numCerts,
- pkix_NameConstraintsCheckerState **pCheckerState,
- void *plContext)
-{
- pkix_NameConstraintsCheckerState *state = NULL;
-
- PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
- "pkix_NameConstraintsCheckerState_Create");
- PKIX_NULLCHECK_ONE(pCheckerState);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE,
- sizeof (pkix_NameConstraintsCheckerState),
- (PKIX_PL_Object **)&state,
- plContext),
- PKIX_COULDNOTCREATENAMECONSTRAINTSCHECKERSTATEOBJECT);
-
- /* Initialize fields */
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_NAMECONSTRAINTS_OID,
- &state->nameConstraintsOID,
- plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_INCREF(nameConstraints);
-
- state->nameConstraints = nameConstraints;
- state->certsRemaining = numCerts;
-
- *pCheckerState = state;
- state = NULL;
-
-cleanup:
-
- PKIX_DECREF(state);
-
- PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
-}
-
-/* --Private-NameConstraintsChecker-Functions------------------------- */
-
-/*
- * FUNCTION: pkix_NameConstraintsChecker_Check
- * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
- */
-static PKIX_Error *
-pkix_NameConstraintsChecker_Check(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Cert *cert,
- PKIX_List *unresolvedCriticalExtensions,
- void **pNBIOContext,
- void *plContext)
-{
- pkix_NameConstraintsCheckerState *state = NULL;
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
- PKIX_PL_CertNameConstraints *mergedNameConstraints = NULL;
- PKIX_Boolean selfIssued = PKIX_FALSE;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Check");
- PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
-
- *pNBIOContext = NULL; /* we never block on pending I/O */
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
- (checker, (PKIX_PL_Object **)&state, plContext),
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
-
- state->certsRemaining--;
-
- /* Get status of self issued */
- PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext),
- PKIX_ISCERTSELFISSUEDFAILED);
-
- /* Check on non self-issued and if so only for last cert */
- if (selfIssued == PKIX_FALSE ||
- (selfIssued == PKIX_TRUE && state->certsRemaining == 0)) {
- PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints
- (cert, state->nameConstraints, plContext),
- PKIX_CERTCHECKNAMECONSTRAINTSFAILED);
- }
-
- if (state->certsRemaining != 0) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
- (cert, &nameConstraints, plContext),
- PKIX_CERTGETNAMECONSTRAINTSFAILED);
-
- /* Merge with previous name constraints kept in state */
-
- if (nameConstraints != NULL) {
-
- if (state->nameConstraints == NULL) {
-
- state->nameConstraints = nameConstraints;
-
- } else {
-
- PKIX_CHECK(PKIX_PL_Cert_MergeNameConstraints
- (nameConstraints,
- state->nameConstraints,
- &mergedNameConstraints,
- plContext),
- PKIX_CERTMERGENAMECONSTRAINTSFAILED);
-
- PKIX_DECREF(nameConstraints);
- PKIX_DECREF(state->nameConstraints);
-
- state->nameConstraints = mergedNameConstraints;
- }
-
- /* Remove Name Constraints Extension OID from list */
- if (unresolvedCriticalExtensions != NULL) {
- PKIX_CHECK(pkix_List_Remove
- (unresolvedCriticalExtensions,
- (PKIX_PL_Object *)state->nameConstraintsOID,
- plContext),
- PKIX_LISTREMOVEFAILED);
- }
- }
- }
-
- PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
- (checker, (PKIX_PL_Object *)state, plContext),
- PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
-
-cleanup:
-
- PKIX_DECREF(state);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_NameConstraintsChecker_Initialize
- *
- * DESCRIPTION:
- * Create a CertChainChecker with a NameConstraintsCheckerState. The
- * NameConstraintsCheckerState is created with "trustedNC" and "numCerts"
- * as its initial state. The CertChainChecker for the NameConstraints is
- * returned at address of "pChecker".
- *
- * PARAMETERS
- * "trustedNC"
- * The NameConstraints from trusted anchor Cert is stored at "trustedNC"
- * for initialization. May be NULL.
- * "numCerts"
- * Number of certificates in the validation chain. This data is used
- * to identify end-entity.
- * "pChecker"
- * Address of CertChainChecker to bo created and returned.
- * Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CERTCHAINCHECKER Error if the function fails in a non-fatal way.
- * Returns a Fatal Error
- */
-PKIX_Error *
-pkix_NameConstraintsChecker_Initialize(
- PKIX_PL_CertNameConstraints *trustedNC,
- PKIX_UInt32 numCerts,
- PKIX_CertChainChecker **pChecker,
- void *plContext)
-{
- pkix_NameConstraintsCheckerState *state = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Initialize");
- PKIX_NULLCHECK_ONE(pChecker);
-
- PKIX_CHECK(pkix_NameConstraintsCheckerState_Create
- (trustedNC, numCerts, &state, plContext),
- PKIX_NAMECONSTRAINTSCHECKERSTATECREATEFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_Create
- (pkix_NameConstraintsChecker_Check,
- PKIX_FALSE,
- PKIX_FALSE,
- NULL,
- (PKIX_PL_Object *) state,
- pChecker,
- plContext),
- PKIX_CERTCHAINCHECKERCREATEFAILED);
-
-cleanup:
-
- PKIX_DECREF(state);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.h
deleted file mode 100755
index ac3de346d..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_nameconstraintschecker.h
- *
- * Header file for validate Name Constraints Checker function
- *
- */
-
-#ifndef _PKIX_NAMECONSTRAINTSCHECKER_H
-#define _PKIX_NAMECONSTRAINTSCHECKER_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct pkix_NameConstraintsCheckerState \
- pkix_NameConstraintsCheckerState;
-
-struct pkix_NameConstraintsCheckerState {
- PKIX_PL_CertNameConstraints *nameConstraints;
- PKIX_PL_OID *nameConstraintsOID;
- PKIX_UInt32 certsRemaining;
-};
-
-PKIX_Error *
-pkix_NameConstraintsChecker_Initialize(
- PKIX_PL_CertNameConstraints *trustedNC,
- PKIX_UInt32 numCerts,
- PKIX_CertChainChecker **pChecker,
- void *plContext);
-
-PKIX_Error *
-pkix_NameConstraintsCheckerState_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_NAMECONSTRAINTSCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
deleted file mode 100644
index 8108b7687..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_ocspchecker.c
- *
- * OcspChecker Object Functions
- *
- */
-
-#include "pkix_ocspchecker.h"
-#include "pkix_pl_ocspcertid.h"
-#include "pkix_error.h"
-
-
-/* --Private-Data-and-Types--------------------------------------- */
-
-typedef struct pkix_OcspCheckerStruct {
- /* RevocationMethod is the super class of OcspChecker. */
- pkix_RevocationMethod method;
- PKIX_PL_VerifyCallback certVerifyFcn;
-} pkix_OcspChecker;
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_OcspChecker_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_OcspChecker_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- return NULL;
-}
-
-/*
- * FUNCTION: pkix_OcspChecker_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_OCSPCHECKER_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_OcspChecker_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry* entry = &systemClasses[PKIX_OCSPCHECKER_TYPE];
-
- PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_RegisterSelf");
-
- entry->description = "OcspChecker";
- entry->typeObjectSize = sizeof(pkix_OcspChecker);
- entry->destructor = pkix_OcspChecker_Destroy;
-
- PKIX_RETURN(OCSPCHECKER);
-}
-
-
-/*
- * FUNCTION: pkix_OcspChecker_Create
- */
-PKIX_Error *
-pkix_OcspChecker_Create(PKIX_RevocationMethodType methodType,
- PKIX_UInt32 flags,
- PKIX_UInt32 priority,
- pkix_LocalRevocationCheckFn localRevChecker,
- pkix_ExternalRevocationCheckFn externalRevChecker,
- PKIX_PL_VerifyCallback verifyFn,
- pkix_RevocationMethod **pChecker,
- void *plContext)
-{
- pkix_OcspChecker *method = NULL;
-
- PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_Create");
- PKIX_NULLCHECK_ONE(pChecker);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_OCSPCHECKER_TYPE,
- sizeof (pkix_OcspChecker),
- (PKIX_PL_Object **)&method,
- plContext),
- PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT);
-
- pkixErrorResult = pkix_RevocationMethod_Init(
- (pkix_RevocationMethod*)method, methodType, flags, priority,
- localRevChecker, externalRevChecker, plContext);
- if (pkixErrorResult) {
- goto cleanup;
- }
- method->certVerifyFcn = (PKIX_PL_VerifyCallback)verifyFn;
-
- *pChecker = (pkix_RevocationMethod*)method;
- method = NULL;
-
-cleanup:
- PKIX_DECREF(method);
-
- PKIX_RETURN(OCSPCHECKER);
-}
-
-/*
- * FUNCTION: pkix_OcspChecker_MapResultCodeToRevStatus
- */
-PKIX_RevocationStatus
-pkix_OcspChecker_MapResultCodeToRevStatus(SECErrorCodes resultCode)
-{
- switch (resultCode) {
- case SEC_ERROR_REVOKED_CERTIFICATE:
- return PKIX_RevStatus_Revoked;
- default:
- return PKIX_RevStatus_NoInfo;
- }
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: pkix_OcspChecker_Check (see comments in pkix_checker.h)
- */
-
-/*
- * The OCSPChecker is created in an idle state, and remains in this state until
- * either (a) the default Responder has been set and enabled, and a Check
- * request is received with no responder specified, or (b) a Check request is
- * received with a specified responder. A request message is constructed and
- * given to the HttpClient. If non-blocking I/O is used the client may return
- * with WOULDBLOCK, in which case the OCSPChecker returns the WOULDBLOCK
- * condition to its caller in turn. On a subsequent call the I/O is resumed.
- * When a response is received it is decoded and the results provided to the
- * caller.
- *
- */
-PKIX_Error *
-pkix_OcspChecker_CheckLocal(
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_Boolean chainVerificationState,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *pReasonCode,
- void *plContext)
-{
- PKIX_PL_OcspCertID *cid = NULL;
- PKIX_Boolean hasFreshStatus = PKIX_FALSE;
- PKIX_Boolean statusIsGood = PKIX_FALSE;
- SECErrorCodes resultCode = SEC_ERROR_REVOKED_CERTIFICATE_OCSP;
- PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
-
- PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_CheckLocal");
-
- PKIX_CHECK(
- PKIX_PL_OcspCertID_Create(cert, NULL, &cid,
- plContext),
- PKIX_OCSPCERTIDCREATEFAILED);
- if (!cid) {
- goto cleanup;
- }
-
- PKIX_CHECK(
- PKIX_PL_OcspCertID_GetFreshCacheStatus(cid, date,
- &hasFreshStatus,
- &statusIsGood,
- &resultCode,
- plContext),
- PKIX_OCSPCERTIDGETFRESHCACHESTATUSFAILED);
- if (hasFreshStatus) {
- if (statusIsGood) {
- revStatus = PKIX_RevStatus_Success;
- resultCode = 0;
- } else {
- revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode);
- }
- }
-
-cleanup:
- *pRevStatus = revStatus;
-
- /* ocsp carries only tree statuses: good, bad, and unknown.
- * revStatus is used to pass them. reasonCode is always set
- * to be unknown. */
- *pReasonCode = crlEntryReasonUnspecified;
- PKIX_DECREF(cid);
-
- PKIX_RETURN(OCSPCHECKER);
-}
-
-
-/*
- * The OCSPChecker is created in an idle state, and remains in this state until
- * either (a) the default Responder has been set and enabled, and a Check
- * request is received with no responder specified, or (b) a Check request is
- * received with a specified responder. A request message is constructed and
- * given to the HttpClient. If non-blocking I/O is used the client may return
- * with WOULDBLOCK, in which case the OCSPChecker returns the WOULDBLOCK
- * condition to its caller in turn. On a subsequent call the I/O is resumed.
- * When a response is received it is decoded and the results provided to the
- * caller.
- *
- */
-PKIX_Error *
-pkix_OcspChecker_CheckExternal(
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *pReasonCode,
- void **pNBIOContext,
- void *plContext)
-{
- SECErrorCodes resultCode = SEC_ERROR_REVOKED_CERTIFICATE_OCSP;
- PKIX_Boolean uriFound = PKIX_FALSE;
- PKIX_Boolean passed = PKIX_TRUE;
- pkix_OcspChecker *checker = NULL;
- PKIX_PL_OcspCertID *cid = NULL;
- PKIX_PL_OcspRequest *request = NULL;
- PKIX_PL_OcspResponse *response = NULL;
- PKIX_PL_Date *validity = NULL;
- PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
- void *nbioContext = NULL;
-
- PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_CheckExternal");
-
- PKIX_CHECK(
- pkix_CheckType((PKIX_PL_Object*)checkerObject,
- PKIX_OCSPCHECKER_TYPE, plContext),
- PKIX_OBJECTNOTOCSPCHECKER);
-
- checker = (pkix_OcspChecker *)checkerObject;
-
- PKIX_CHECK(
- PKIX_PL_OcspCertID_Create(cert, NULL, &cid,
- plContext),
- PKIX_OCSPCERTIDCREATEFAILED);
-
- /* create request */
- PKIX_CHECK(
- pkix_pl_OcspRequest_Create(cert, cid, validity, NULL,
- methodFlags, &uriFound, &request,
- plContext),
- PKIX_OCSPREQUESTCREATEFAILED);
-
- if (uriFound == PKIX_FALSE) {
- /* no caching for certs lacking URI */
- resultCode = 0;
- goto cleanup;
- }
-
- /* send request and create a response object */
- PKIX_CHECK(
- pkix_pl_OcspResponse_Create(request, NULL,
- checker->certVerifyFcn,
- &nbioContext,
- &response,
- plContext),
- PKIX_OCSPRESPONSECREATEFAILED);
- if (nbioContext != 0) {
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
-
- PKIX_CHECK(
- pkix_pl_OcspResponse_Decode(response, &passed,
- &resultCode, plContext),
- PKIX_OCSPRESPONSEDECODEFAILED);
- if (passed == PKIX_FALSE) {
- goto cleanup;
- }
-
- PKIX_CHECK(
- pkix_pl_OcspResponse_GetStatus(response, &passed,
- &resultCode, plContext),
- PKIX_OCSPRESPONSEGETSTATUSRETURNEDANERROR);
- if (passed == PKIX_FALSE) {
- goto cleanup;
- }
-
- PKIX_CHECK(
- pkix_pl_OcspResponse_VerifySignature(response, cert,
- procParams, &passed,
- &nbioContext, plContext),
- PKIX_OCSPRESPONSEVERIFYSIGNATUREFAILED);
- if (nbioContext != 0) {
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
- if (passed == PKIX_FALSE) {
- goto cleanup;
- }
-
- PKIX_CHECK(
- pkix_pl_OcspResponse_GetStatusForCert(cid, response, date,
- &passed, &resultCode,
- plContext),
- PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED);
- if (passed == PKIX_FALSE) {
- revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode);
- } else {
- revStatus = PKIX_RevStatus_Success;
- }
-
-cleanup:
- if (revStatus == PKIX_RevStatus_NoInfo && (uriFound ||
- methodFlags & PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE) &&
- methodFlags & PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
- revStatus = PKIX_RevStatus_Revoked;
- }
- *pRevStatus = revStatus;
-
- /* ocsp carries only tree statuses: good, bad, and unknown.
- * revStatus is used to pass them. reasonCode is always set
- * to be unknown. */
- *pReasonCode = crlEntryReasonUnspecified;
-
- if (!passed && cid && cid->certID) {
- /* We still own the certID object, which means that
- * it did not get consumed to create a cache entry.
- * Let's make sure there is one.
- */
- PKIX_Error *err;
- err = PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
- cid, plContext);
- if (err) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)err, plContext);
- }
- }
- PKIX_DECREF(cid);
- PKIX_DECREF(request);
- PKIX_DECREF(response);
-
- PKIX_RETURN(OCSPCHECKER);
-}
-
-
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h
deleted file mode 100644
index 547b403b4..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_ocspchecker.h
- *
- * OcspChecker Object Type Definition
- *
- */
-
-#ifndef _PKIX_OCSPCHECKER_H
-#define _PKIX_OCSPCHECKER_H
-
-#include "pkix_tools.h"
-#include "pkix_revocationmethod.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* NOTE: nbio logic removed. Will be replaced later. */
-
-PKIX_Error *
-pkix_OcspChecker_CheckLocal(
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_Boolean chainVerificationState,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *reasonCode,
- void *plContext);
-
-PKIX_Error *
-pkix_OcspChecker_CheckExternal(
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *reasonCode,
- void **pNBIOContext,
- void *plContext);
-
-PKIX_Error *
-pkix_OcspChecker_Create(PKIX_RevocationMethodType methodType,
- PKIX_UInt32 flags,
- PKIX_UInt32 priority,
- pkix_LocalRevocationCheckFn localRevChecker,
- pkix_ExternalRevocationCheckFn externalRevChecker,
- PKIX_PL_VerifyCallback certVerifyFn,
- pkix_RevocationMethod **pChecker,
- void *plContext);
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_OcspChecker_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_OCSPCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.c
deleted file mode 100755
index 8e4059654..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.c
+++ /dev/null
@@ -1,2783 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_policychecker.c
- *
- * Functions for Policy Checker
- *
- */
-#include "pkix_policychecker.h"
-
-/* --Forward declarations----------------------------------------------- */
-
-static PKIX_Error *
-pkix_PolicyChecker_MakeSingleton(
- PKIX_PL_Object *listItem,
- PKIX_Boolean immutability,
- PKIX_List **pList,
- void *plContext);
-
-/* --Private-PolicyCheckerState-Functions---------------------------------- */
-
-/*
- * FUNCTION:pkix_PolicyCheckerState_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_PolicyCheckerState_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PolicyCheckerState *checkerState = NULL;
-
- PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTPOLICYCHECKERSTATE_TYPE, plContext),
- PKIX_OBJECTNOTPOLICYCHECKERSTATE);
-
- checkerState = (PKIX_PolicyCheckerState *)object;
-
- PKIX_DECREF(checkerState->certPoliciesExtension);
- PKIX_DECREF(checkerState->policyMappingsExtension);
- PKIX_DECREF(checkerState->policyConstraintsExtension);
- PKIX_DECREF(checkerState->inhibitAnyPolicyExtension);
- PKIX_DECREF(checkerState->anyPolicyOID);
- PKIX_DECREF(checkerState->validPolicyTree);
- PKIX_DECREF(checkerState->userInitialPolicySet);
- PKIX_DECREF(checkerState->mappedUserInitialPolicySet);
-
- checkerState->policyQualifiersRejected = PKIX_FALSE;
- checkerState->explicitPolicy = 0;
- checkerState->inhibitAnyPolicy = 0;
- checkerState->policyMapping = 0;
- checkerState->numCerts = 0;
- checkerState->certsProcessed = 0;
- checkerState->certPoliciesCritical = PKIX_FALSE;
-
- PKIX_DECREF(checkerState->anyPolicyNodeAtBottom);
- PKIX_DECREF(checkerState->newAnyPolicyNode);
- PKIX_DECREF(checkerState->mappedPolicyOIDs);
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYCHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_PolicyCheckerState_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_PolicyCheckerState_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pCheckerStateString,
- void *plContext)
-{
- PKIX_PolicyCheckerState *state = NULL;
- PKIX_PL_String *resultString = NULL;
- PKIX_PL_String *policiesExtOIDString = NULL;
- PKIX_PL_String *policyMapOIDString = NULL;
- PKIX_PL_String *policyConstrOIDString = NULL;
- PKIX_PL_String *inhAnyPolOIDString = NULL;
- PKIX_PL_String *anyPolicyOIDString = NULL;
- PKIX_PL_String *validPolicyTreeString = NULL;
- PKIX_PL_String *userInitialPolicySetString = NULL;
- PKIX_PL_String *mappedUserPolicySetString = NULL;
- PKIX_PL_String *mappedPolicyOIDsString = NULL;
- PKIX_PL_String *anyAtBottomString = NULL;
- PKIX_PL_String *newAnyPolicyString = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *trueString = NULL;
- PKIX_PL_String *falseString = NULL;
- PKIX_PL_String *nullString = NULL;
- PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE;
- PKIX_Boolean initialExplicitPolicy = PKIX_FALSE;
- PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE;
- PKIX_Boolean initialIsAnyPolicy = PKIX_FALSE;
- PKIX_Boolean policyQualifiersRejected = PKIX_FALSE;
- PKIX_Boolean certPoliciesCritical = PKIX_FALSE;
- char *asciiFormat =
- "{\n"
- "\tcertPoliciesExtension: \t%s\n"
- "\tpolicyMappingsExtension: \t%s\n"
- "\tpolicyConstraintsExtension:\t%s\n"
- "\tinhibitAnyPolicyExtension:\t%s\n"
- "\tanyPolicyOID: \t%s\n"
- "\tinitialIsAnyPolicy: \t%s\n"
- "\tvalidPolicyTree: \t%s\n"
- "\tuserInitialPolicySet: \t%s\n"
- "\tmappedUserPolicySet: \t%s\n"
- "\tpolicyQualifiersRejected: \t%s\n"
- "\tinitialPolMappingInhibit: \t%s\n"
- "\tinitialExplicitPolicy: \t%s\n"
- "\tinitialAnyPolicyInhibit: \t%s\n"
- "\texplicitPolicy: \t%d\n"
- "\tinhibitAnyPolicy: \t%d\n"
- "\tpolicyMapping: \t%d\n"
- "\tnumCerts: \t%d\n"
- "\tcertsProcessed: \t%d\n"
- "\tanyPolicyNodeAtBottom: \t%s\n"
- "\tnewAnyPolicyNode: \t%s\n"
- "\tcertPoliciesCritical: \t%s\n"
- "\tmappedPolicyOIDs: \t%s\n"
- "}";
-
- PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_ToString");
-
- PKIX_NULLCHECK_TWO(object, pCheckerStateString);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTPOLICYCHECKERSTATE_TYPE, plContext),
- PKIX_OBJECTNOTPOLICYCHECKERSTATE);
-
- state = (PKIX_PolicyCheckerState *)object;
- PKIX_NULLCHECK_THREE
- (state->certPoliciesExtension,
- state->policyMappingsExtension,
- state->policyConstraintsExtension);
- PKIX_NULLCHECK_THREE
- (state->inhibitAnyPolicyExtension,
- state->anyPolicyOID,
- state->userInitialPolicySet);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
- PKIX_STRINGCREATEFAILED);
- /*
- * Create TRUE, FALSE, and "NULL" PKIX_PL_Strings. But creating a
- * PKIX_PL_String is complicated enough, it's worth checking, for
- * each, to make sure the string is needed.
- */
- initialPolicyMappingInhibit = state->initialPolicyMappingInhibit;
- initialExplicitPolicy = state->initialExplicitPolicy;
- initialAnyPolicyInhibit = state->initialAnyPolicyInhibit;
- initialIsAnyPolicy = state->initialIsAnyPolicy;
- policyQualifiersRejected = state->policyQualifiersRejected;
- certPoliciesCritical = state->certPoliciesCritical;
-
- if (initialPolicyMappingInhibit || initialExplicitPolicy ||
- initialAnyPolicyInhibit || initialIsAnyPolicy ||
- policyQualifiersRejected || certPoliciesCritical) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "TRUE", 0, &trueString, plContext),
- PKIX_STRINGCREATEFAILED);
- }
- if (!initialPolicyMappingInhibit || !initialExplicitPolicy ||
- !initialAnyPolicyInhibit || !initialIsAnyPolicy ||
- !policyQualifiersRejected || !certPoliciesCritical) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "FALSE", 0, &falseString, plContext),
- PKIX_STRINGCREATEFAILED);
- }
- if (!(state->anyPolicyNodeAtBottom) || !(state->newAnyPolicyNode)) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "(null)", 0, &nullString, plContext),
- PKIX_STRINGCREATEFAILED);
- }
-
- PKIX_TOSTRING
- (state->certPoliciesExtension, &policiesExtOIDString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->policyMappingsExtension,
- &policyMapOIDString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->policyConstraintsExtension,
- &policyConstrOIDString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->inhibitAnyPolicyExtension,
- &inhAnyPolOIDString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING(state->anyPolicyOID, &anyPolicyOIDString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING(state->validPolicyTree, &validPolicyTreeString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->userInitialPolicySet,
- &userInitialPolicySetString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->mappedUserInitialPolicySet,
- &mappedUserPolicySetString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- if (state->anyPolicyNodeAtBottom) {
- PKIX_CHECK(pkix_SinglePolicyNode_ToString
- (state->anyPolicyNodeAtBottom,
- &anyAtBottomString,
- plContext),
- PKIX_SINGLEPOLICYNODETOSTRINGFAILED);
- } else {
- PKIX_INCREF(nullString);
- anyAtBottomString = nullString;
- }
-
- if (state->newAnyPolicyNode) {
- PKIX_CHECK(pkix_SinglePolicyNode_ToString
- (state->newAnyPolicyNode,
- &newAnyPolicyString,
- plContext),
- PKIX_SINGLEPOLICYNODETOSTRINGFAILED);
- } else {
- PKIX_INCREF(nullString);
- newAnyPolicyString = nullString;
- }
-
- PKIX_TOSTRING
- (state->mappedPolicyOIDs,
- &mappedPolicyOIDsString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&resultString,
- plContext,
- formatString,
- policiesExtOIDString,
- policyMapOIDString,
- policyConstrOIDString,
- inhAnyPolOIDString,
- anyPolicyOIDString,
- initialIsAnyPolicy?trueString:falseString,
- validPolicyTreeString,
- userInitialPolicySetString,
- mappedUserPolicySetString,
- policyQualifiersRejected?trueString:falseString,
- initialPolicyMappingInhibit?trueString:falseString,
- initialExplicitPolicy?trueString:falseString,
- initialAnyPolicyInhibit?trueString:falseString,
- state->explicitPolicy,
- state->inhibitAnyPolicy,
- state->policyMapping,
- state->numCerts,
- state->certsProcessed,
- anyAtBottomString,
- newAnyPolicyString,
- certPoliciesCritical?trueString:falseString,
- mappedPolicyOIDsString),
- PKIX_SPRINTFFAILED);
-
- *pCheckerStateString = resultString;
-
-cleanup:
- PKIX_DECREF(policiesExtOIDString);
- PKIX_DECREF(policyMapOIDString);
- PKIX_DECREF(policyConstrOIDString);
- PKIX_DECREF(inhAnyPolOIDString);
- PKIX_DECREF(anyPolicyOIDString);
- PKIX_DECREF(validPolicyTreeString);
- PKIX_DECREF(userInitialPolicySetString);
- PKIX_DECREF(mappedUserPolicySetString);
- PKIX_DECREF(anyAtBottomString);
- PKIX_DECREF(newAnyPolicyString);
- PKIX_DECREF(mappedPolicyOIDsString);
- PKIX_DECREF(formatString);
- PKIX_DECREF(trueString);
- PKIX_DECREF(falseString);
- PKIX_DECREF(nullString);
-
- PKIX_RETURN(CERTPOLICYCHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_PolicyCheckerState_RegisterSelf
- * DESCRIPTION:
- *
- * Registers PKIX_POLICYCHECKERSTATE_TYPE and its related functions
- * with systemClasses[]
- *
- * PARAMETERS:
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_PolicyCheckerState_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER
- (CERTPOLICYCHECKERSTATE,
- "pkix_PolicyCheckerState_RegisterSelf");
-
- entry.description = "PolicyCheckerState";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PolicyCheckerState);
- entry.destructor = pkix_PolicyCheckerState_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = pkix_PolicyCheckerState_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_CERTPOLICYCHECKERSTATE_TYPE] = entry;
-
- PKIX_RETURN(CERTPOLICYCHECKERSTATE);
-}
-
-/*
- * FUNCTION:pkix_PolicyCheckerState_Create
- * DESCRIPTION:
- *
- * Creates a PolicyCheckerState Object, using the List pointed to
- * by "initialPolicies" for the user-initial-policy-set, the Boolean value
- * of "policyQualifiersRejected" for the policyQualifiersRejected parameter,
- * the Boolean value of "initialPolicyMappingInhibit" for the
- * inhibitPolicyMappings parameter, the Boolean value of
- * "initialExplicitPolicy" for the initialExplicitPolicy parameter, the
- * Boolean value of "initialAnyPolicyInhibit" for the inhibitAnyPolicy
- * parameter, and the UInt32 value of "numCerts" as the number of
- * certificates in the chain; and stores the Object at "pCheckerState".
- *
- * PARAMETERS:
- * "initialPolicies"
- * Address of List of OIDs comprising the user-initial-policy-set; the List
- * may be empty, but must be non-NULL
- * "policyQualifiersRejected"
- * Boolean value of the policyQualifiersRejected parameter
- * "initialPolicyMappingInhibit"
- * Boolean value of the inhibitPolicyMappings parameter
- * "initialExplicitPolicy"
- * Boolean value of the initialExplicitPolicy parameter
- * "initialAnyPolicyInhibit"
- * Boolean value of the inhibitAnyPolicy parameter
- * "numCerts"
- * Number of certificates in the chain to be validated
- * "pCheckerState"
- * Address where PolicyCheckerState will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertPolicyCheckerState Error if the functions fails in a
- * non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyCheckerState_Create(
- PKIX_List *initialPolicies,
- PKIX_Boolean policyQualifiersRejected,
- PKIX_Boolean initialPolicyMappingInhibit,
- PKIX_Boolean initialExplicitPolicy,
- PKIX_Boolean initialAnyPolicyInhibit,
- PKIX_UInt32 numCerts,
- PKIX_PolicyCheckerState **pCheckerState,
- void *plContext)
-{
- PKIX_PolicyCheckerState *checkerState = NULL;
- PKIX_PolicyNode *policyNode = NULL;
- PKIX_List *anyPolicyList = NULL;
- PKIX_Boolean initialPoliciesIsEmpty = PKIX_FALSE;
-
- PKIX_ENTER(CERTPOLICYCHECKERSTATE, "pkix_PolicyCheckerState_Create");
- PKIX_NULLCHECK_TWO(initialPolicies, pCheckerState);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTPOLICYCHECKERSTATE_TYPE,
- sizeof (PKIX_PolicyCheckerState),
- (PKIX_PL_Object **)&checkerState,
- plContext),
- PKIX_COULDNOTCREATEPOLICYCHECKERSTATEOBJECT);
-
- /* Create constant PKIX_PL_OIDs: */
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_CERTIFICATEPOLICIES_OID,
- &(checkerState->certPoliciesExtension),
- plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_POLICYMAPPINGS_OID,
- &(checkerState->policyMappingsExtension),
- plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_POLICYCONSTRAINTS_OID,
- &(checkerState->policyConstraintsExtension),
- plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_INHIBITANYPOLICY_OID,
- &(checkerState->inhibitAnyPolicyExtension),
- plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_CERTIFICATEPOLICIES_ANYPOLICY_OID,
- &(checkerState->anyPolicyOID),
- plContext),
- PKIX_OIDCREATEFAILED);
-
- /* Create an initial policy set from argument supplied */
- PKIX_INCREF(initialPolicies);
- checkerState->userInitialPolicySet = initialPolicies;
- PKIX_INCREF(initialPolicies);
- checkerState->mappedUserInitialPolicySet = initialPolicies;
-
- PKIX_CHECK(PKIX_List_IsEmpty
- (initialPolicies,
- &initialPoliciesIsEmpty,
- plContext),
- PKIX_LISTISEMPTYFAILED);
- if (initialPoliciesIsEmpty) {
- checkerState->initialIsAnyPolicy = PKIX_TRUE;
- } else {
- PKIX_CHECK(pkix_List_Contains
- (initialPolicies,
- (PKIX_PL_Object *)(checkerState->anyPolicyOID),
- &(checkerState->initialIsAnyPolicy),
- plContext),
- PKIX_LISTCONTAINSFAILED);
- }
-
- checkerState->policyQualifiersRejected =
- policyQualifiersRejected;
- checkerState->initialExplicitPolicy = initialExplicitPolicy;
- checkerState->explicitPolicy =
- (initialExplicitPolicy? 0: numCerts + 1);
- checkerState->initialAnyPolicyInhibit = initialAnyPolicyInhibit;
- checkerState->inhibitAnyPolicy =
- (initialAnyPolicyInhibit? 0: numCerts + 1);
- checkerState->initialPolicyMappingInhibit = initialPolicyMappingInhibit;
- checkerState->policyMapping =
- (initialPolicyMappingInhibit? 0: numCerts + 1);
- ;
- checkerState->numCerts = numCerts;
- checkerState->certsProcessed = 0;
- checkerState->certPoliciesCritical = PKIX_FALSE;
-
- /* Create a valid_policy_tree as in RFC3280 6.1.2(a) */
- PKIX_CHECK(pkix_PolicyChecker_MakeSingleton
- ((PKIX_PL_Object *)(checkerState->anyPolicyOID),
- PKIX_TRUE,
- &anyPolicyList,
- plContext),
- PKIX_POLICYCHECKERMAKESINGLETONFAILED);
-
- PKIX_CHECK(pkix_PolicyNode_Create
- (checkerState->anyPolicyOID, /* validPolicy */
- NULL, /* qualifier set */
- PKIX_FALSE, /* criticality */
- anyPolicyList, /* expectedPolicySet */
- &policyNode,
- plContext),
- PKIX_POLICYNODECREATEFAILED);
- checkerState->validPolicyTree = policyNode;
-
- /*
- * Since the initial validPolicyTree specifies
- * ANY_POLICY, begin with a pointer to the root node.
- */
- PKIX_INCREF(policyNode);
- checkerState->anyPolicyNodeAtBottom = policyNode;
-
- checkerState->newAnyPolicyNode = NULL;
-
- checkerState->mappedPolicyOIDs = NULL;
-
- *pCheckerState = checkerState;
- checkerState = NULL;
-
-cleanup:
-
- PKIX_DECREF(checkerState);
-
- PKIX_DECREF(anyPolicyList);
-
- PKIX_RETURN(CERTPOLICYCHECKERSTATE);
-}
-
-/* --Private-PolicyChecker-Functions--------------------------------------- */
-
-/*
- * FUNCTION: pkix_PolicyChecker_MapContains
- * DESCRIPTION:
- *
- * Checks the List of CertPolicyMaps pointed to by "certPolicyMaps", to
- * determine whether the OID pointed to by "policy" is among the
- * issuerDomainPolicies or subjectDomainPolicies of "certPolicyMaps", and
- * stores the result in "pFound".
- *
- * This function is intended to allow an efficient check that the proscription
- * against anyPolicy being mapped, described in RFC3280 Section 6.1.4(a), is
- * not violated.
- *
- * PARAMETERS:
- * "certPolicyMaps"
- * Address of List of CertPolicyMaps to be searched. May be empty, but
- * must be non-NULL
- * "policy"
- * Address of OID to be checked for. Must be non-NULL
- * "pFound"
- * Address where the result of the search will be stored. Must be non-NULL.
- * "plContext"
- * platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_PolicyChecker_MapContains(
- PKIX_List *certPolicyMaps,
- PKIX_PL_OID *policy,
- PKIX_Boolean *pFound,
- void *plContext)
-{
- PKIX_PL_CertPolicyMap *map = NULL;
- PKIX_UInt32 numEntries = 0;
- PKIX_UInt32 index = 0;
- PKIX_Boolean match = PKIX_FALSE;
- PKIX_PL_OID *issuerDomainPolicy = NULL;
- PKIX_PL_OID *subjectDomainPolicy = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MapContains");
- PKIX_NULLCHECK_THREE(certPolicyMaps, policy, pFound);
-
- PKIX_CHECK(PKIX_List_GetLength(certPolicyMaps, &numEntries, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (index = 0; (!match) && (index < numEntries); index++) {
- PKIX_CHECK(PKIX_List_GetItem
- (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_NULLCHECK_ONE(map);
-
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy
- (map, &issuerDomainPolicy, plContext),
- PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED);
-
- PKIX_EQUALS
- (policy, issuerDomainPolicy, &match, plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (!match) {
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy
- (map, &subjectDomainPolicy, plContext),
- PKIX_CERTPOLICYMAPGETSUBJECTDOMAINPOLICYFAILED);
-
- PKIX_EQUALS
- (policy, subjectDomainPolicy, &match, plContext,
- PKIX_OBJECTEQUALSFAILED);
- }
-
- PKIX_DECREF(map);
- PKIX_DECREF(issuerDomainPolicy);
- PKIX_DECREF(subjectDomainPolicy);
- }
-
- *pFound = match;
-
-cleanup:
-
- PKIX_DECREF(map);
- PKIX_DECREF(issuerDomainPolicy);
- PKIX_DECREF(subjectDomainPolicy);
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_MapGetSubjectDomainPolicies
- * DESCRIPTION:
- *
- * Checks the List of CertPolicyMaps pointed to by "certPolicyMaps", to create
- * a list of all SubjectDomainPolicies for which the IssuerDomainPolicy is the
- * policy pointed to by "policy", and stores the result in
- * "pSubjectDomainPolicies".
- *
- * If the List of CertPolicyMaps provided in "certPolicyMaps" is NULL, the
- * resulting List will be NULL. If there are CertPolicyMaps, but none that
- * include "policy" as an IssuerDomainPolicy, the returned List pointer will
- * be NULL. Otherwise, the returned List will contain the SubjectDomainPolicies
- * of all CertPolicyMaps for which "policy" is the IssuerDomainPolicy. If a
- * List is returned it will be immutable.
- *
- * PARAMETERS:
- * "certPolicyMaps"
- * Address of List of CertPolicyMaps to be searched. May be empty or NULL.
- * "policy"
- * Address of OID to be checked for. Must be non-NULL
- * "pSubjectDomainPolicies"
- * Address where the result of the search will be stored. Must be non-NULL.
- * "plContext"
- * platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_PolicyChecker_MapGetSubjectDomainPolicies(
- PKIX_List *certPolicyMaps,
- PKIX_PL_OID *policy,
- PKIX_List **pSubjectDomainPolicies,
- void *plContext)
-{
- PKIX_PL_CertPolicyMap *map = NULL;
- PKIX_List *subjectList = NULL;
- PKIX_UInt32 numEntries = 0;
- PKIX_UInt32 index = 0;
- PKIX_Boolean match = PKIX_FALSE;
- PKIX_PL_OID *issuerDomainPolicy = NULL;
- PKIX_PL_OID *subjectDomainPolicy = NULL;
-
- PKIX_ENTER
- (CERTCHAINCHECKER,
- "pkix_PolicyChecker_MapGetSubjectDomainPolicies");
- PKIX_NULLCHECK_TWO(policy, pSubjectDomainPolicies);
-
- if (certPolicyMaps) {
- PKIX_CHECK(PKIX_List_GetLength
- (certPolicyMaps,
- &numEntries,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- for (index = 0; index < numEntries; index++) {
- PKIX_CHECK(PKIX_List_GetItem
- (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_NULLCHECK_ONE(map);
-
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy
- (map, &issuerDomainPolicy, plContext),
- PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED);
-
- PKIX_EQUALS
- (policy, issuerDomainPolicy, &match, plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (match) {
- if (!subjectList) {
- PKIX_CHECK(PKIX_List_Create(&subjectList, plContext),
- PKIX_LISTCREATEFAILED);
- }
-
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy
- (map, &subjectDomainPolicy, plContext),
- PKIX_CERTPOLICYMAPGETSUBJECTDOMAINPOLICYFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (subjectList,
- (PKIX_PL_Object *)subjectDomainPolicy,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
-
- PKIX_DECREF(map);
- PKIX_DECREF(issuerDomainPolicy);
- PKIX_DECREF(subjectDomainPolicy);
- }
-
- if (subjectList) {
- PKIX_CHECK(PKIX_List_SetImmutable(subjectList, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
- }
-
- *pSubjectDomainPolicies = subjectList;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(subjectList);
- }
-
- PKIX_DECREF(map);
- PKIX_DECREF(issuerDomainPolicy);
- PKIX_DECREF(subjectDomainPolicy);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_MapGetMappedPolicies
- * DESCRIPTION:
- *
- * Checks the List of CertPolicyMaps pointed to by "certPolicyMaps" to create a
- * List of all IssuerDomainPolicies, and stores the result in
- * "pMappedPolicies".
- *
- * The caller may not rely on the IssuerDomainPolicies to be in any particular
- * order. IssuerDomainPolicies that appear in more than one CertPolicyMap will
- * only appear once in "pMappedPolicies". If "certPolicyMaps" is empty the
- * result will be an empty List. The created List is mutable.
- *
- * PARAMETERS:
- * "certPolicyMaps"
- * Address of List of CertPolicyMaps to be searched. May be empty, but
- * must be non-NULL.
- * "pMappedPolicies"
- * Address where the result will be stored. Must be non-NULL.
- * "plContext"
- * platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_PolicyChecker_MapGetMappedPolicies(
- PKIX_List *certPolicyMaps,
- PKIX_List **pMappedPolicies,
- void *plContext)
-{
- PKIX_PL_CertPolicyMap *map = NULL;
- PKIX_List *mappedList = NULL;
- PKIX_UInt32 numEntries = 0;
- PKIX_UInt32 index = 0;
- PKIX_Boolean isContained = PKIX_FALSE;
- PKIX_PL_OID *issuerDomainPolicy = NULL;
-
- PKIX_ENTER
- (CERTCHAINCHECKER, "pkix_PolicyChecker_MapGetMappedPolicies");
- PKIX_NULLCHECK_TWO(certPolicyMaps, pMappedPolicies);
-
- PKIX_CHECK(PKIX_List_Create(&mappedList, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(certPolicyMaps, &numEntries, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (index = 0; index < numEntries; index++) {
- PKIX_CHECK(PKIX_List_GetItem
- (certPolicyMaps, index, (PKIX_PL_Object **)&map, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_NULLCHECK_ONE(map);
-
- PKIX_CHECK(PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy
- (map, &issuerDomainPolicy, plContext),
- PKIX_CERTPOLICYMAPGETISSUERDOMAINPOLICYFAILED);
-
- PKIX_CHECK(pkix_List_Contains
- (mappedList,
- (PKIX_PL_Object *)issuerDomainPolicy,
- &isContained,
- plContext),
- PKIX_LISTCONTAINSFAILED);
-
- if (isContained == PKIX_FALSE) {
- PKIX_CHECK(PKIX_List_AppendItem
- (mappedList,
- (PKIX_PL_Object *)issuerDomainPolicy,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
-
- PKIX_DECREF(map);
- PKIX_DECREF(issuerDomainPolicy);
- }
-
- *pMappedPolicies = mappedList;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(mappedList);
- }
-
- PKIX_DECREF(map);
- PKIX_DECREF(issuerDomainPolicy);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_MakeMutableCopy
- * DESCRIPTION:
- *
- * Creates a mutable copy of the List pointed to by "list", which may or may
- * not be immutable, and stores the address at "pMutableCopy".
- *
- * PARAMETERS:
- * "list"
- * Address of List to be copied. Must be non-NULL.
- * "pMutableCopy"
- * Address where mutable copy will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyChecker_MakeMutableCopy(
- PKIX_List *list,
- PKIX_List **pMutableCopy,
- void *plContext)
-{
- PKIX_List *newList = NULL;
- PKIX_UInt32 listLen = 0;
- PKIX_UInt32 listIx = 0;
- PKIX_PL_Object *object = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MakeMutableCopy");
- PKIX_NULLCHECK_TWO(list, pMutableCopy);
-
- PKIX_CHECK(PKIX_List_Create(&newList, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(list, &listLen, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (listIx = 0; listIx < listLen; listIx++) {
-
- PKIX_CHECK(PKIX_List_GetItem(list, listIx, &object, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem(newList, object, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(object);
- }
-
- *pMutableCopy = newList;
- newList = NULL;
-
-cleanup:
- PKIX_DECREF(newList);
- PKIX_DECREF(object);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_MakeSingleton
- * DESCRIPTION:
- *
- * Creates a new List containing the Object pointed to by "listItem", using
- * the Boolean value of "immutability" to determine whether to set the List
- * immutable, and stores the address at "pList".
- *
- * PARAMETERS:
- * "listItem"
- * Address of Object to be inserted into the new List. Must be non-NULL.
- * "immutability"
- * Boolean value indicating whether new List is to be immutable
- * "pList"
- * Address where List will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyChecker_MakeSingleton(
- PKIX_PL_Object *listItem,
- PKIX_Boolean immutability,
- PKIX_List **pList,
- void *plContext)
-{
- PKIX_List *newList = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_MakeSingleton");
- PKIX_NULLCHECK_TWO(listItem, pList);
-
- PKIX_CHECK(PKIX_List_Create(&newList, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (newList, (PKIX_PL_Object *)listItem, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- if (immutability) {
- PKIX_CHECK(PKIX_List_SetImmutable(newList, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
- }
-
- *pList = newList;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(newList);
- }
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_Spawn
- * DESCRIPTION:
- *
- * Creates a new childNode for the parent pointed to by "parent", using
- * the OID pointed to by "policyOID", the List of CertPolicyQualifiers
- * pointed to by "qualifiers", the List of OIDs pointed to by
- * "subjectDomainPolicies", and the PolicyCheckerState pointed to by
- * "state". The new node will be added to "parent".
- *
- * The validPolicy of the new node is set from the OID pointed to by
- * "policyOID". The policy qualifiers for the new node is set from the
- * List of qualifiers pointed to by "qualifiers", and may be NULL or
- * empty if the argument provided was NULL or empty. The criticality is
- * set according to the criticality obtained from the PolicyCheckerState.
- * If "subjectDomainPolicies" is NULL, the expectedPolicySet of the
- * child is set to contain the same policy as the validPolicy. If
- * "subjectDomainPolicies" is not NULL, it is used as the value for
- * the expectedPolicySet.
- *
- * The PolicyCheckerState also contains a constant, anyPolicy, which is
- * compared to "policyOID". If they match, the address of the childNode
- * is saved in the state's newAnyPolicyNode.
- *
- * PARAMETERS:
- * "parent"
- * Address of PolicyNode to which the child will be linked. Must be
- * non-NULL.
- * "policyOID"
- * Address of OID of the new child's validPolicy and also, if
- * subjectDomainPolicies is NULL, of the new child's expectedPolicySet.
- * Must be non-NULL.
- * "qualifiers"
- * Address of List of CertPolicyQualifiers. May be NULL or empty.
- * "subjectDomainPolicies"
- * Address of List of OIDs indicating the policies to which "policy" is
- * mapped. May be empty or NULL.
- * "state"
- * Address of the current PKIX_PolicyCheckerState. Must be non-NULL..
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyChecker_Spawn(
- PKIX_PolicyNode *parent,
- PKIX_PL_OID *policyOID,
- PKIX_List *qualifiers, /* CertPolicyQualifiers */
- PKIX_List *subjectDomainPolicies,
- PKIX_PolicyCheckerState *state,
- void *plContext)
-{
- PKIX_List *expectedSet = NULL; /* OIDs */
- PKIX_PolicyNode *childNode = NULL;
- PKIX_Boolean match = PKIX_FALSE;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Spawn");
- PKIX_NULLCHECK_THREE(policyOID, parent, state);
-
- if (subjectDomainPolicies) {
-
- PKIX_INCREF(subjectDomainPolicies);
- expectedSet = subjectDomainPolicies;
-
- } else {
- /* Create the child's ExpectedPolicy Set */
- PKIX_CHECK(pkix_PolicyChecker_MakeSingleton
- ((PKIX_PL_Object *)policyOID,
- PKIX_TRUE, /* make expectedPolicySet immutable */
- &expectedSet,
- plContext),
- PKIX_POLICYCHECKERMAKESINGLETONFAILED);
- }
-
- PKIX_CHECK(pkix_PolicyNode_Create
- (policyOID,
- qualifiers,
- state->certPoliciesCritical,
- expectedSet,
- &childNode,
- plContext),
- PKIX_POLICYNODECREATEFAILED);
-
- /*
- * If we had a non-empty mapping, we know the new node could not
- * have been created with a validPolicy of anyPolicy. Otherwise,
- * check whether we just created a new node with anyPolicy, because
- * in that case we want to save the child pointer in newAnyPolicyNode.
- */
- if (!subjectDomainPolicies) {
- PKIX_EQUALS(policyOID, state->anyPolicyOID, &match, plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (match) {
- PKIX_DECREF(state->newAnyPolicyNode);
- PKIX_INCREF(childNode);
- state->newAnyPolicyNode = childNode;
- }
- }
-
- PKIX_CHECK(pkix_PolicyNode_AddToParent(parent, childNode, plContext),
- PKIX_POLICYNODEADDTOPARENTFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
- PKIX_DECREF(childNode);
- PKIX_DECREF(expectedSet);
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_CheckPolicyRecursive
- * DESCRIPTION:
- *
- * Performs policy processing for the policy whose OID is pointed to by
- * "policyOID" and whose List of CertPolicyQualifiers is pointed to by
- * "policyQualifiers", using the List of policy OIDs pointed to by
- * "subjectDomainPolicies" and the PolicyNode pointed to by "currentNode",
- * in accordance with the current PolicyCheckerState pointed to by "state",
- * and setting "pChildNodeCreated" to TRUE if a new childNode is created.
- * Note: "pChildNodeCreated" is not set to FALSE if no childNode is created.
- * The intent of the design is that the caller can set a variable to FALSE
- * initially, prior to a recursive set of calls. At the end, the variable
- * can be tested to see whether *any* of the calls created a child node.
- *
- * If the currentNode is not at the bottom of the tree, this function
- * calls itself recursively for each child of currentNode. At the bottom of
- * the tree, it creates new child nodes as appropriate. This function will
- * never be called with policy = anyPolicy.
- *
- * This function implements the processing described in RFC3280
- * Section 6.1.3(d)(1)(i).
- *
- * PARAMETERS:
- * "policyOID"
- * Address of OID of the policy to be checked for. Must be non-NULL.
- * "policyQualifiers"
- * Address of List of CertPolicyQualifiers of the policy to be checked for.
- * May be empty or NULL.
- * "subjectDomainPolicies"
- * Address of List of OIDs indicating the policies to which "policy" is
- * mapped. May be empty or NULL.
- * "currentNode"
- * Address of PolicyNode whose descendants will be checked, if not at the
- * bottom of the tree; or whose expectedPolicySet will be compared to
- * "policy", if at the bottom. Must be non-NULL.
- * "state"
- * Address of PolicyCheckerState of the current PolicyChecker. Must be
- * non-NULL.
- * "pChildNodeCreated"
- * Address of the Boolean that will be set TRUE if this function
- * creates a child node. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyChecker_CheckPolicyRecursive(
- PKIX_PL_OID *policyOID,
- PKIX_List *policyQualifiers,
- PKIX_List *subjectDomainPolicies,
- PKIX_PolicyNode *currentNode,
- PKIX_PolicyCheckerState *state,
- PKIX_Boolean *pChildNodeCreated,
- void *plContext)
-{
- PKIX_UInt32 depth = 0;
- PKIX_UInt32 numChildren = 0;
- PKIX_UInt32 childIx = 0;
- PKIX_Boolean isIncluded = PKIX_FALSE;
- PKIX_List *children = NULL; /* PolicyNodes */
- PKIX_PolicyNode *childNode = NULL;
- PKIX_List *expectedPolicies = NULL; /* OIDs */
-
- PKIX_ENTER
- (CERTCHAINCHECKER,
- "pkix_PolicyChecker_CheckPolicyRecursive");
- PKIX_NULLCHECK_FOUR(policyOID, currentNode, state, pChildNodeCreated);
-
- /* if not at the bottom of the tree */
- PKIX_CHECK(PKIX_PolicyNode_GetDepth
- (currentNode, &depth, plContext),
- PKIX_POLICYNODEGETDEPTHFAILED);
-
- if (depth < (state->certsProcessed)) {
- PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable
- (currentNode, &children, plContext),
- PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED);
-
- if (children) {
- PKIX_CHECK(PKIX_List_GetLength
- (children, &numChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- for (childIx = 0; childIx < numChildren; childIx++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (children,
- childIx,
- (PKIX_PL_Object **)&childNode,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_PolicyChecker_CheckPolicyRecursive
- (policyOID,
- policyQualifiers,
- subjectDomainPolicies,
- childNode,
- state,
- pChildNodeCreated,
- plContext),
- PKIX_POLICYCHECKERCHECKPOLICYRECURSIVEFAILED);
-
- PKIX_DECREF(childNode);
- }
- } else { /* if at the bottom of the tree */
-
- /* Check whether policy is in this node's expectedPolicySet */
- PKIX_CHECK(PKIX_PolicyNode_GetExpectedPolicies
- (currentNode, &expectedPolicies, plContext),
- PKIX_POLICYNODEGETEXPECTEDPOLICIESFAILED);
-
- PKIX_NULLCHECK_ONE(expectedPolicies);
-
- PKIX_CHECK(pkix_List_Contains
- (expectedPolicies,
- (PKIX_PL_Object *)policyOID,
- &isIncluded,
- plContext),
- PKIX_LISTCONTAINSFAILED);
-
- if (isIncluded) {
- PKIX_CHECK(pkix_PolicyChecker_Spawn
- (currentNode,
- policyOID,
- policyQualifiers,
- subjectDomainPolicies,
- state,
- plContext),
- PKIX_POLICYCHECKERSPAWNFAILED);
-
- *pChildNodeCreated = PKIX_TRUE;
- }
- }
-
-cleanup:
-
- PKIX_DECREF(children);
- PKIX_DECREF(childNode);
- PKIX_DECREF(expectedPolicies);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_CheckPolicy
- * DESCRIPTION:
- *
- * Performs the non-recursive portion of the policy processing for the policy
- * whose OID is pointed to by "policyOID" and whose List of
- * CertPolicyQualifiers is pointed to by "policyQualifiers", for the
- * Certificate pointed to by "cert" with the List of CertPolicyMaps pointed
- * to by "maps", in accordance with the current PolicyCheckerState pointed
- * to by "state".
- *
- * This function implements the processing described in RFC3280
- * Section 6.1.3(d)(1)(i).
- *
- * PARAMETERS:
- * "policyOID"
- * Address of OID of the policy to be checked for. Must be non-NULL.
- * "policyQualifiers"
- * Address of List of CertPolicyQualifiers of the policy to be checked for.
- * May be empty or NULL.
- * "cert"
- * Address of the current certificate. Must be non-NULL.
- * "maps"
- * Address of List of CertPolicyMaps for the current certificate
- * "state"
- * Address of PolicyCheckerState of the current PolicyChecker. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyChecker_CheckPolicy(
- PKIX_PL_OID *policyOID,
- PKIX_List *policyQualifiers,
- PKIX_PL_Cert *cert,
- PKIX_List *maps,
- PKIX_PolicyCheckerState *state,
- void *plContext)
-{
- PKIX_Boolean childNodeCreated = PKIX_FALSE;
- PKIX_Boolean okToSpawn = PKIX_FALSE;
- PKIX_Boolean found = PKIX_FALSE;
- PKIX_List *subjectDomainPolicies = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_CheckPolicy");
- PKIX_NULLCHECK_THREE(policyOID, cert, state);
-
- /*
- * If this is not the last certificate, get the set of
- * subjectDomainPolicies that "policy" maps to, according to the
- * current cert's policy mapping extension. That set will be NULL
- * if the current cert does not have a policy mapping extension,
- * or if the current policy is not mapped.
- */
- if (state->certsProcessed != (state->numCerts - 1)) {
- PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies
- (maps, policyOID, &subjectDomainPolicies, plContext),
- PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED);
- }
-
- /*
- * Section 6.1.4(b)(2) tells us that if policyMapping is zero, we
- * will have to delete any nodes created with validPolicies equal to
- * policies that appear as issuerDomainPolicies in a policy mapping
- * extension. Let's avoid creating any such nodes.
- */
- if ((state->policyMapping) == 0) {
- if (subjectDomainPolicies) {
- goto cleanup;
- }
- }
-
- PKIX_CHECK(pkix_PolicyChecker_CheckPolicyRecursive
- (policyOID,
- policyQualifiers,
- subjectDomainPolicies,
- state->validPolicyTree,
- state,
- &childNodeCreated,
- plContext),
- PKIX_POLICYCHECKERCHECKPOLICYRECURSIVEFAILED);
-
- if (!childNodeCreated) {
- /*
- * Section 6.1.3(d)(1)(ii)
- * There was no match. If there was a node at
- * depth i-1 with valid policy anyPolicy,
- * generate a node subordinate to that.
- *
- * But that means this created node would be in
- * the valid-policy-node-set, and will be
- * pruned in 6.1.5(g)(iii)(2) unless it is in
- * the user-initial-policy-set or the user-
- * initial-policy-set is {anyPolicy}. So check,
- * and don't create it if it will be pruned.
- */
- if (state->anyPolicyNodeAtBottom) {
- if (state->initialIsAnyPolicy) {
- okToSpawn = PKIX_TRUE;
- } else {
- PKIX_CHECK(pkix_List_Contains
- (state->mappedUserInitialPolicySet,
- (PKIX_PL_Object *)policyOID,
- &okToSpawn,
- plContext),
- PKIX_LISTCONTAINSFAILED);
- }
- if (okToSpawn) {
- PKIX_CHECK(pkix_PolicyChecker_Spawn
- (state->anyPolicyNodeAtBottom,
- policyOID,
- policyQualifiers,
- subjectDomainPolicies,
- state,
- plContext),
- PKIX_POLICYCHECKERSPAWNFAILED);
- childNodeCreated = PKIX_TRUE;
- }
- }
- }
-
- if (childNodeCreated) {
- /*
- * If this policy had qualifiers, and the certificate policies
- * extension was marked critical, and the user cannot deal with
- * policy qualifiers, throw an error.
- */
- if (policyQualifiers &&
- state->certPoliciesCritical &&
- state->policyQualifiersRejected) {
- PKIX_ERROR
- (PKIX_QUALIFIERSINCRITICALCERTIFICATEPOLICYEXTENSION);
- }
- /*
- * If the policy we just propagated was in the list of mapped
- * policies, remove it from the list. That list is used, at the
- * end, to determine policies that have not been propagated.
- */
- if (state->mappedPolicyOIDs) {
- PKIX_CHECK(pkix_List_Contains
- (state->mappedPolicyOIDs,
- (PKIX_PL_Object *)policyOID,
- &found,
- plContext),
- PKIX_LISTCONTAINSFAILED);
- if (found) {
- PKIX_CHECK(pkix_List_Remove
- (state->mappedPolicyOIDs,
- (PKIX_PL_Object *)policyOID,
- plContext),
- PKIX_LISTREMOVEFAILED);
- }
- }
- }
-
-cleanup:
-
- PKIX_DECREF(subjectDomainPolicies);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_CheckAny
- * DESCRIPTION:
- * Performs the creation of PolicyNodes, for the PolicyNode pointed to by
- * "currentNode" and PolicyNodes subordinate to it, using the List of
- * qualifiers pointed to by "qualsOfAny", in accordance with the current
- * certificate's PolicyMaps pointed to by "policyMaps" and the current
- * PolicyCheckerState pointed to by "state".
- *
- * If the currentNode is not just above the bottom of the validPolicyTree, this
- * function calls itself recursively for each child of currentNode. At the
- * level just above the bottom, for each policy in the currentNode's
- * expectedPolicySet not already present in a child node, it creates a new
- * child node. The validPolicy of the child created, and its expectedPolicySet,
- * will be the policy from the currentNode's expectedPolicySet. The policy
- * qualifiers will be the qualifiers from the current certificate's anyPolicy,
- * the "qualsOfAny" parameter. If the currentNode's expectedSet includes
- * anyPolicy, a childNode will be created with a policy of anyPolicy. This is
- * the only way such a node can be created.
- *
- * This function is called only when anyPolicy is one of the current
- * certificate's policies. This function implements the processing described
- * in RFC3280 Section 6.1.3(d)(2).
- *
- * PARAMETERS:
- * "currentNode"
- * Address of PolicyNode whose descendants will be checked, if not at the
- * bottom of the tree; or whose expectedPolicySet will be compared to those
- * in "alreadyPresent", if at the bottom. Must be non-NULL.
- * "qualsOfAny"
- * Address of List of qualifiers of the anyPolicy in the current
- * certificate. May be empty or NULL.
- * "policyMaps"
- * Address of the List of PolicyMaps of the current certificate. May be
- * empty or NULL.
- * "state"
- * Address of the current state of the PKIX_PolicyChecker.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyChecker_CheckAny(
- PKIX_PolicyNode *currentNode,
- PKIX_List *qualsOfAny, /* CertPolicyQualifiers */
- PKIX_List *policyMaps, /* CertPolicyMaps */
- PKIX_PolicyCheckerState *state,
- void *plContext)
-{
- PKIX_UInt32 depth = 0;
- PKIX_UInt32 numChildren = 0;
- PKIX_UInt32 childIx = 0;
- PKIX_UInt32 numPolicies = 0;
- PKIX_UInt32 polx = 0;
- PKIX_Boolean isIncluded = PKIX_FALSE;
- PKIX_List *children = NULL; /* PolicyNodes */
- PKIX_PolicyNode *childNode = NULL;
- PKIX_List *expectedPolicies = NULL; /* OIDs */
- PKIX_PL_OID *policyOID = NULL;
- PKIX_PL_OID *childPolicy = NULL;
- PKIX_List *subjectDomainPolicies = NULL; /* OIDs */
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_CheckAny");
- PKIX_NULLCHECK_TWO(currentNode, state);
-
- PKIX_CHECK(PKIX_PolicyNode_GetDepth
- (currentNode, &depth, plContext),
- PKIX_POLICYNODEGETDEPTHFAILED);
-
- PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable
- (currentNode, &children, plContext),
- PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED);
-
- if (children) {
- PKIX_CHECK(PKIX_List_GetLength
- (children, &numChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- if (depth < (state->certsProcessed)) {
- for (childIx = 0; childIx < numChildren; childIx++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (children,
- childIx,
- (PKIX_PL_Object **)&childNode,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_NULLCHECK_ONE(childNode);
- PKIX_CHECK(pkix_PolicyChecker_CheckAny
- (childNode,
- qualsOfAny,
- policyMaps,
- state,
- plContext),
- PKIX_POLICYCHECKERCHECKANYFAILED);
-
- PKIX_DECREF(childNode);
- }
- } else { /* if at the bottom of the tree */
-
- PKIX_CHECK(PKIX_PolicyNode_GetExpectedPolicies
- (currentNode, &expectedPolicies, plContext),
- PKIX_POLICYNODEGETEXPECTEDPOLICIESFAILED);
-
- /* Expected Policy Set is not allowed to be NULL */
- PKIX_NULLCHECK_ONE(expectedPolicies);
-
- PKIX_CHECK(PKIX_List_GetLength
- (expectedPolicies, &numPolicies, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (polx = 0; polx < numPolicies; polx++) {
- PKIX_CHECK(PKIX_List_GetItem
- (expectedPolicies,
- polx,
- (PKIX_PL_Object **)&policyOID,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_NULLCHECK_ONE(policyOID);
-
- isIncluded = PKIX_FALSE;
-
- for (childIx = 0;
- (!isIncluded && (childIx < numChildren));
- childIx++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (children,
- childIx,
- (PKIX_PL_Object **)&childNode,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_NULLCHECK_ONE(childNode);
-
- PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy
- (childNode, &childPolicy, plContext),
- PKIX_POLICYNODEGETVALIDPOLICYFAILED);
-
- PKIX_NULLCHECK_ONE(childPolicy);
-
- PKIX_EQUALS(policyOID, childPolicy, &isIncluded, plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- PKIX_DECREF(childNode);
- PKIX_DECREF(childPolicy);
- }
-
- if (!isIncluded) {
- if (policyMaps) {
- PKIX_CHECK
- (pkix_PolicyChecker_MapGetSubjectDomainPolicies
- (policyMaps,
- policyOID,
- &subjectDomainPolicies,
- plContext),
- PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED);
- }
- PKIX_CHECK(pkix_PolicyChecker_Spawn
- (currentNode,
- policyOID,
- qualsOfAny,
- subjectDomainPolicies,
- state,
- plContext),
- PKIX_POLICYCHECKERSPAWNFAILED);
- PKIX_DECREF(subjectDomainPolicies);
- }
-
- PKIX_DECREF(policyOID);
- }
- }
-
-cleanup:
-
- PKIX_DECREF(children);
- PKIX_DECREF(childNode);
- PKIX_DECREF(expectedPolicies);
- PKIX_DECREF(policyOID);
- PKIX_DECREF(childPolicy);
- PKIX_DECREF(subjectDomainPolicies);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_CalculateIntersection
- * DESCRIPTION:
- *
- * Processes the PolicyNode pointed to by "currentNode", and its descendants,
- * using the PolicyCheckerState pointed to by "state", using the List at
- * the address pointed to by "nominees" the OIDs of policies that are in the
- * user-initial-policy-set but are not represented among the nodes at the
- * bottom of the tree, and storing at "pShouldBePruned" the value TRUE if
- * currentNode is childless at the end of this processing, FALSE if it has
- * children or is at the bottom of the tree.
- *
- * When this function is called at the top level, "nominees" should be the List
- * of all policies in the user-initial-policy-set. Policies that are
- * represented in the valid-policy-node-set are removed from this List. As a
- * result when nodes are created according to 6.1.5.(g)(iii)(3)(b), a node will
- * be created for each policy remaining in this List.
- *
- * This function implements the calculation of the intersection of the
- * validPolicyTree with the user-initial-policy-set, as described in
- * RFC 3280 6.1.5(g)(iii).
- *
- * PARAMETERS:
- * "currentNode"
- * Address of PolicyNode whose descendants will be processed as described.
- * Must be non-NULL.
- * "state"
- * Address of the current state of the PKIX_PolicyChecker. Must be non-NULL
- * "nominees"
- * Address of List of the OIDs for which nodes should be created to replace
- * anyPolicy nodes. Must be non-NULL but may be empty.
- * "pShouldBePruned"
- * Address where Boolean return value, set to TRUE if this PolicyNode
- * should be deleted, is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyChecker_CalculateIntersection(
- PKIX_PolicyNode *currentNode,
- PKIX_PolicyCheckerState *state,
- PKIX_List *nominees, /* OIDs */
- PKIX_Boolean *pShouldBePruned,
- void *plContext)
-{
- PKIX_Boolean currentPolicyIsAny = PKIX_FALSE;
- PKIX_Boolean parentPolicyIsAny = PKIX_FALSE;
- PKIX_Boolean currentPolicyIsValid = PKIX_FALSE;
- PKIX_Boolean shouldBePruned = PKIX_FALSE;
- PKIX_Boolean priorCriticality = PKIX_FALSE;
- PKIX_UInt32 depth = 0;
- PKIX_UInt32 numChildren = 0;
- PKIX_UInt32 childIndex = 0;
- PKIX_UInt32 numNominees = 0;
- PKIX_UInt32 polIx = 0;
- PKIX_PL_OID *currentPolicy = NULL;
- PKIX_PL_OID *parentPolicy = NULL;
- PKIX_PL_OID *substPolicy = NULL;
- PKIX_PolicyNode *parent = NULL;
- PKIX_PolicyNode *child = NULL;
- PKIX_List *children = NULL; /* PolicyNodes */
- PKIX_List *policyQualifiers = NULL;
-
- PKIX_ENTER
- (CERTCHAINCHECKER,
- "pkix_PolicyChecker_CalculateIntersection");
-
- /*
- * We call this function if the valid_policy_tree is not NULL and
- * the user-initial-policy-set is not any-policy.
- */
- if (!state->validPolicyTree || state->initialIsAnyPolicy) {
- PKIX_ERROR(PKIX_PRECONDITIONFAILED);
- }
-
- PKIX_NULLCHECK_FOUR(currentNode, state, nominees, pShouldBePruned);
-
- PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy
- (currentNode, &currentPolicy, plContext),
- PKIX_POLICYNODEGETVALIDPOLICYFAILED);
-
- PKIX_NULLCHECK_TWO(state->anyPolicyOID, currentPolicy);
-
- PKIX_EQUALS
- (state->anyPolicyOID,
- currentPolicy,
- &currentPolicyIsAny,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- PKIX_CHECK(PKIX_PolicyNode_GetParent(currentNode, &parent, plContext),
- PKIX_POLICYNODEGETPARENTFAILED);
-
- if (currentPolicyIsAny == PKIX_FALSE) {
-
- /*
- * If we are at the top of the tree, or if our
- * parent's validPolicy is anyPolicy, we are in
- * the valid policy node set.
- */
- if (parent) {
- PKIX_CHECK(PKIX_PolicyNode_GetValidPolicy
- (parent, &parentPolicy, plContext),
- PKIX_POLICYNODEGETVALIDPOLICYFAILED);
-
- PKIX_NULLCHECK_ONE(parentPolicy);
-
- PKIX_EQUALS
- (state->anyPolicyOID,
- parentPolicy,
- &parentPolicyIsAny,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
- }
-
- /*
- * Section 6.1.5(g)(iii)(2)
- * If this node's policy is not in the user-initial-policy-set,
- * it is not in the intersection. Prune it.
- */
- if (!parent || parentPolicyIsAny) {
- PKIX_CHECK(pkix_List_Contains
- (state->userInitialPolicySet,
- (PKIX_PL_Object *)currentPolicy,
- &currentPolicyIsValid,
- plContext),
- PKIX_LISTCONTAINSFAILED);
- if (!currentPolicyIsValid) {
- *pShouldBePruned = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If this node's policy is in the user-initial-policy-
- * set, it will propagate that policy into the next
- * level of the tree. Remove the policy from the list
- * of policies that an anyPolicy will spawn.
- */
- PKIX_CHECK(pkix_List_Remove
- (nominees,
- (PKIX_PL_Object *)currentPolicy,
- plContext),
- PKIX_LISTREMOVEFAILED);
- }
- }
-
-
- /* Are we at the bottom of the tree? */
-
- PKIX_CHECK(PKIX_PolicyNode_GetDepth
- (currentNode, &depth, plContext),
- PKIX_POLICYNODEGETDEPTHFAILED);
-
- if (depth == (state->numCerts)) {
- /*
- * Section 6.1.5(g)(iii)(3)
- * Replace anyPolicy nodes...
- */
- if (currentPolicyIsAny == PKIX_TRUE) {
-
- /* replace this node */
-
- PKIX_CHECK(PKIX_List_GetLength
- (nominees, &numNominees, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (numNominees) {
-
- PKIX_CHECK(PKIX_PolicyNode_GetPolicyQualifiers
- (currentNode,
- &policyQualifiers,
- plContext),
- PKIX_POLICYNODEGETPOLICYQUALIFIERSFAILED);
-
- PKIX_CHECK(PKIX_PolicyNode_IsCritical
- (currentNode, &priorCriticality, plContext),
- PKIX_POLICYNODEISCRITICALFAILED);
- }
-
- PKIX_NULLCHECK_ONE(parent);
-
- for (polIx = 0; polIx < numNominees; polIx++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (nominees,
- polIx,
- (PKIX_PL_Object **)&substPolicy,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_PolicyChecker_Spawn
- (parent,
- substPolicy,
- policyQualifiers,
- NULL,
- state,
- plContext),
- PKIX_POLICYCHECKERSPAWNFAILED);
-
- PKIX_DECREF(substPolicy);
-
- }
- /* remove currentNode from parent */
- *pShouldBePruned = PKIX_TRUE;
- /*
- * We can get away with augmenting the parent's List
- * of children because we started at the end and went
- * toward the beginning. New nodes are added at the end.
- */
- }
- } else {
- /*
- * Section 6.1.5(g)(iii)(4)
- * Prune any childless nodes above the bottom level
- */
- PKIX_CHECK(pkix_PolicyNode_GetChildrenMutable
- (currentNode, &children, plContext),
- PKIX_POLICYNODEGETCHILDRENMUTABLEFAILED);
-
- /* CurrentNode should have been pruned if childless. */
- PKIX_NULLCHECK_ONE(children);
-
- PKIX_CHECK(PKIX_List_GetLength
- (children, &numChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (childIndex = numChildren; childIndex > 0; childIndex--) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (children,
- childIndex - 1,
- (PKIX_PL_Object **)&child,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_PolicyChecker_CalculateIntersection
- (child, state, nominees, &shouldBePruned, plContext),
- PKIX_POLICYCHECKERCALCULATEINTERSECTIONFAILED);
-
- if (PKIX_TRUE == shouldBePruned) {
-
- PKIX_CHECK(PKIX_List_DeleteItem
- (children, childIndex - 1, plContext),
- PKIX_LISTDELETEITEMFAILED);
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
- }
-
- PKIX_DECREF(child);
- }
-
- PKIX_CHECK(PKIX_List_GetLength
- (children, &numChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (numChildren == 0) {
- *pShouldBePruned = PKIX_TRUE;
- }
- }
-cleanup:
- PKIX_DECREF(currentPolicy);
- PKIX_DECREF(parentPolicy);
- PKIX_DECREF(substPolicy);
- PKIX_DECREF(parent);
- PKIX_DECREF(child);
- PKIX_DECREF(children);
- PKIX_DECREF(policyQualifiers);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_PolicyMapProcessing
- * DESCRIPTION:
- *
- * Performs the processing of Policies in the List of CertPolicyMaps pointed
- * to by "policyMaps", using and updating the PolicyCheckerState pointed to by
- * "state".
- *
- * This function implements the policyMap processing described in RFC3280
- * Section 6.1.4(b)(1), after certificate i has been processed, in preparation
- * for certificate i+1. Section references are to that document.
- *
- * PARAMETERS:
- * "policyMaps"
- * Address of the List of CertPolicyMaps presented by certificate i.
- * Must be non-NULL.
- * "certPoliciesIncludeAny"
- * Boolean value which is PKIX_TRUE if the current certificate asserts
- * anyPolicy, PKIX_FALSE otherwise.
- * "qualsOfAny"
- * Address of List of qualifiers of the anyPolicy in the current
- * certificate. May be empty or NULL.
- * "state"
- * Address of the current state of the PKIX_PolicyChecker.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyChecker_PolicyMapProcessing(
- PKIX_List *policyMaps, /* CertPolicyMaps */
- PKIX_Boolean certPoliciesIncludeAny,
- PKIX_List *qualsOfAny,
- PKIX_PolicyCheckerState *state,
- void *plContext)
-{
- PKIX_UInt32 numPolicies = 0;
- PKIX_UInt32 polX = 0;
- PKIX_PL_OID *policyOID = NULL;
- PKIX_List *newMappedPolicies = NULL; /* OIDs */
- PKIX_List *subjectDomainPolicies = NULL; /* OIDs */
-
- PKIX_ENTER
- (CERTCHAINCHECKER,
- "pkix_PolicyChecker_PolicyMapProcessing");
- PKIX_NULLCHECK_THREE
- (policyMaps,
- state,
- state->mappedUserInitialPolicySet);
-
- /*
- * For each policy in mappedUserInitialPolicySet, if it is not mapped,
- * append it to new policySet; if it is mapped, append its
- * subjectDomainPolicies to new policySet. When done, this new
- * policySet will replace mappedUserInitialPolicySet.
- */
- PKIX_CHECK(PKIX_List_Create
- (&newMappedPolicies, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength
- (state->mappedUserInitialPolicySet,
- &numPolicies,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (polX = 0; polX < numPolicies; polX++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (state->mappedUserInitialPolicySet,
- polX,
- (PKIX_PL_Object **)&policyOID,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies
- (policyMaps,
- policyOID,
- &subjectDomainPolicies,
- plContext),
- PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED);
-
- if (subjectDomainPolicies) {
-
- PKIX_CHECK(pkix_List_AppendUnique
- (newMappedPolicies,
- subjectDomainPolicies,
- plContext),
- PKIX_LISTAPPENDUNIQUEFAILED);
-
- PKIX_DECREF(subjectDomainPolicies);
-
- } else {
- PKIX_CHECK(PKIX_List_AppendItem
- (newMappedPolicies,
- (PKIX_PL_Object *)policyOID,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
- PKIX_DECREF(policyOID);
- }
-
- /*
- * For each policy ID-P remaining in mappedPolicyOIDs, it has not been
- * propagated to the bottom of the tree (depth i). If policyMapping
- * is greater than zero and this cert contains anyPolicy and the tree
- * contains an anyPolicy node at depth i-1, then we must create a node
- * with validPolicy ID-P, the policy qualifiers of anyPolicy in
- * this certificate, and expectedPolicySet the subjectDomainPolicies
- * that ID-P maps to. We also then add those subjectDomainPolicies to
- * the list of policies that will be accepted in the next certificate,
- * the mappedUserInitialPolicySet.
- */
-
- if ((state->policyMapping > 0) && (certPoliciesIncludeAny) &&
- (state->anyPolicyNodeAtBottom) && (state->mappedPolicyOIDs)) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (state->mappedPolicyOIDs,
- &numPolicies,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (polX = 0; polX < numPolicies; polX++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (state->mappedPolicyOIDs,
- polX,
- (PKIX_PL_Object **)&policyOID,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_PolicyChecker_MapGetSubjectDomainPolicies
- (policyMaps,
- policyOID,
- &subjectDomainPolicies,
- plContext),
- PKIX_POLICYCHECKERMAPGETSUBJECTDOMAINPOLICIESFAILED);
-
- PKIX_CHECK(pkix_PolicyChecker_Spawn
- (state->anyPolicyNodeAtBottom,
- policyOID,
- qualsOfAny,
- subjectDomainPolicies,
- state,
- plContext),
- PKIX_POLICYCHECKERSPAWNFAILED);
-
- PKIX_CHECK(pkix_List_AppendUnique
- (newMappedPolicies,
- subjectDomainPolicies,
- plContext),
- PKIX_LISTAPPENDUNIQUEFAILED);
-
- PKIX_DECREF(subjectDomainPolicies);
- PKIX_DECREF(policyOID);
- }
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable(newMappedPolicies, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- PKIX_DECREF(state->mappedUserInitialPolicySet);
- PKIX_INCREF(newMappedPolicies);
-
- state->mappedUserInitialPolicySet = newMappedPolicies;
-
-cleanup:
-
- PKIX_DECREF(policyOID);
- PKIX_DECREF(newMappedPolicies);
- PKIX_DECREF(subjectDomainPolicies);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_WrapUpProcessing
- * DESCRIPTION:
- *
- * Performs the wrap-up processing for the Cert pointed to by "cert",
- * using and updating the PolicyCheckerState pointed to by "state".
- *
- * This function implements the wrap-up processing described in RFC3280
- * Section 6.1.5, after the final certificate has been processed. Section
- * references in the comments are to that document.
- *
- * PARAMETERS:
- * "cert"
- * Address of the current (presumably the end entity) certificate.
- * Must be non-NULL.
- * "state"
- * Address of the current state of the PKIX_PolicyChecker.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-static PKIX_Error *
-pkix_PolicyChecker_WrapUpProcessing(
- PKIX_PL_Cert *cert,
- PKIX_PolicyCheckerState *state,
- void *plContext)
-{
- PKIX_Int32 explicitPolicySkipCerts = 0;
- PKIX_Boolean isSelfIssued = PKIX_FALSE;
- PKIX_Boolean shouldBePruned = PKIX_FALSE;
- PKIX_List *nominees = NULL; /* OIDs */
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG
- PKIX_PL_String *stateString = NULL;
- char *stateAscii = NULL;
- PKIX_UInt32 length;
-#endif
-
- PKIX_ENTER
- (CERTCHAINCHECKER,
- "pkix_PolicyChecker_WrapUpProcessing");
- PKIX_NULLCHECK_THREE(cert, state, state->userInitialPolicySet);
-
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)state, &stateString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stateString,
- PKIX_ESCASCII,
- (void **)&stateAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_DEBUG_ARG("%s\n", stateAscii);
-
- PKIX_FREE(stateAscii);
- PKIX_DECREF(stateString);
-#endif
-
- /* Section 6.1.5(a) ... */
- PKIX_CHECK(pkix_IsCertSelfIssued
- (cert, &isSelfIssued, plContext),
- PKIX_ISCERTSELFISSUEDFAILED);
-
- if (!isSelfIssued) {
- if (state->explicitPolicy > 0) {
-
- state->explicitPolicy--;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
- }
- }
-
- /* Section 6.1.5(b) ... */
- PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy
- (cert, &explicitPolicySkipCerts, plContext),
- PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED);
-
- if (explicitPolicySkipCerts == 0) {
- state->explicitPolicy = 0;
- }
-
- /* Section 6.1.5(g)(i) ... */
-
- if (!(state->validPolicyTree)) {
- goto cleanup;
- }
-
- /* Section 6.1.5(g)(ii) ... */
-
- if (state->initialIsAnyPolicy) {
- goto cleanup;
- }
-
- /*
- * Section 6.1.5(g)(iii) ...
- * Create a list of policies which could be substituted for anyPolicy.
- * Start with a (mutable) copy of user-initial-policy-set.
- */
- PKIX_CHECK(pkix_PolicyChecker_MakeMutableCopy
- (state->userInitialPolicySet, &nominees, plContext),
- PKIX_POLICYCHECKERMAKEMUTABLECOPYFAILED);
-
- PKIX_CHECK(pkix_PolicyChecker_CalculateIntersection
- (state->validPolicyTree, /* node at top of tree */
- state,
- nominees,
- &shouldBePruned,
- plContext),
- PKIX_POLICYCHECKERCALCULATEINTERSECTIONFAILED);
-
- if (PKIX_TRUE == shouldBePruned) {
- PKIX_DECREF(state->validPolicyTree);
- }
-
- if (state->validPolicyTree) {
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state->validPolicyTree, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG
- if (state->validPolicyTree) {
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)state, &stateString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stateString,
- PKIX_ESCASCII,
- (void **)&stateAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_DEBUG_ARG
- ("After CalculateIntersection:\n%s\n", stateAscii);
-
- PKIX_FREE(stateAscii);
- PKIX_DECREF(stateString);
- } else {
- PKIX_DEBUG("validPolicyTree is NULL\n");
- }
-#endif
-
- /* Section 6.1.5(g)(iii)(4) ... */
-
- if (state->validPolicyTree) {
-
- PKIX_CHECK(pkix_PolicyNode_Prune
- (state->validPolicyTree,
- state->numCerts,
- &shouldBePruned,
- plContext),
- PKIX_POLICYNODEPRUNEFAILED);
-
- if (shouldBePruned) {
- PKIX_DECREF(state->validPolicyTree);
- }
- }
-
- if (state->validPolicyTree) {
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state->validPolicyTree, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)state, &stateString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stateString,
- PKIX_ESCASCII,
- (void **)&stateAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
- PKIX_DEBUG_ARG("%s\n", stateAscii);
-
- PKIX_FREE(stateAscii);
- PKIX_DECREF(stateString);
-#endif
-
-cleanup:
-
- PKIX_DECREF(nominees);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-
-/*
- * FUNCTION: pkix_PolicyChecker_Check
- * (see comments in pkix_checker.h for PKIX_CertChainChecker_CheckCallback)
- *
- * Labels referring to sections, such as "Section 6.1.3(d)", refer to
- * sections of RFC3280, Section 6.1.3 Basic Certificate Processing.
- *
- * If a non-fatal error occurs, it is unlikely that policy processing can
- * continue. But it is still possible that chain validation could succeed if
- * policy processing is non-critical. So if this function receives a non-fatal
- * error from a lower level routine, it aborts policy processing by setting
- * the validPolicyTree to NULL and tries to continue.
- *
- */
-static PKIX_Error *
-pkix_PolicyChecker_Check(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Cert *cert,
- PKIX_List *unresolvedCriticals, /* OIDs */
- void **pNBIOContext,
- void *plContext)
-{
- PKIX_UInt32 numPolicies = 0;
- PKIX_UInt32 polX = 0;
- PKIX_Boolean result = PKIX_FALSE;
- PKIX_Int32 inhibitMappingSkipCerts = 0;
- PKIX_Int32 explicitPolicySkipCerts = 0;
- PKIX_Int32 inhibitAnyPolicySkipCerts = 0;
- PKIX_Boolean shouldBePruned = PKIX_FALSE;
- PKIX_Boolean isSelfIssued = PKIX_FALSE;
- PKIX_Boolean certPoliciesIncludeAny = PKIX_FALSE;
- PKIX_Boolean doAnyPolicyProcessing = PKIX_FALSE;
-
- PKIX_PolicyCheckerState *state = NULL;
- PKIX_List *certPolicyInfos = NULL; /* CertPolicyInfos */
- PKIX_PL_CertPolicyInfo *policy = NULL;
- PKIX_PL_OID *policyOID = NULL;
- PKIX_List *qualsOfAny = NULL; /* CertPolicyQualifiers */
- PKIX_List *policyQualifiers = NULL; /* CertPolicyQualifiers */
- PKIX_List *policyMaps = NULL; /* CertPolicyMaps */
- PKIX_List *mappedPolicies = NULL; /* OIDs */
- PKIX_Error *subroutineErr = NULL;
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG
- PKIX_PL_String *stateString = NULL;
- char *stateAscii = NULL;
- PKIX_PL_String *certString = NULL;
- char *certAscii = NULL;
- PKIX_UInt32 length;
-#endif
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Check");
- PKIX_NULLCHECK_FOUR(checker, cert, unresolvedCriticals, pNBIOContext);
-
- *pNBIOContext = NULL; /* we never block on pending I/O */
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
- (checker, (PKIX_PL_Object **)&state, plContext),
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
-
- PKIX_NULLCHECK_TWO(state, state->certPoliciesExtension);
-
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)state, &stateString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stateString,
- PKIX_ESCASCII,
- (void **)&stateAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
- PKIX_DEBUG_ARG("On entry %s\n", stateAscii);
- PKIX_FREE(stateAscii);
- PKIX_DECREF(stateString);
-#endif
-
- /*
- * Section 6.1.4(a)
- * If this is not the last certificate, and if
- * policyMapping extension is present, check that no
- * issuerDomainPolicy or subjectDomainPolicy is equal to the
- * special policy anyPolicy.
- */
- if (state->certsProcessed != (state->numCerts - 1)) {
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings
- (cert, &policyMaps, plContext),
- PKIX_CERTGETPOLICYMAPPINGSFAILED);
- }
-
- if (policyMaps) {
-
- PKIX_CHECK(pkix_PolicyChecker_MapContains
- (policyMaps, state->anyPolicyOID, &result, plContext),
- PKIX_POLICYCHECKERMAPCONTAINSFAILED);
-
- if (result) {
- PKIX_ERROR(PKIX_INVALIDPOLICYMAPPINGINCLUDESANYPOLICY);
- }
-
- PKIX_CHECK(pkix_PolicyChecker_MapGetMappedPolicies
- (policyMaps, &mappedPolicies, plContext),
- PKIX_POLICYCHECKERMAPGETMAPPEDPOLICIESFAILED);
-
- PKIX_DECREF(state->mappedPolicyOIDs);
- PKIX_INCREF(mappedPolicies);
- state->mappedPolicyOIDs = mappedPolicies;
- }
-
- /* Section 6.1.3(d) */
- if (state->validPolicyTree) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
- (cert, &certPolicyInfos, plContext),
- PKIX_CERTGETPOLICYINFORMATIONFAILED);
-
- if (certPolicyInfos) {
- PKIX_CHECK(PKIX_List_GetLength
- (certPolicyInfos, &numPolicies, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- if (numPolicies > 0) {
-
- PKIX_CHECK(PKIX_PL_Cert_AreCertPoliciesCritical
- (cert, &(state->certPoliciesCritical), plContext),
- PKIX_CERTARECERTPOLICIESCRITICALFAILED);
-
- /* Section 6.1.3(d)(1) For each policy not equal to anyPolicy */
- for (polX = 0; polX < numPolicies; polX++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (certPolicyInfos,
- polX,
- (PKIX_PL_Object **)&policy,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolicyId
- (policy, &policyOID, plContext),
- PKIX_CERTPOLICYINFOGETPOLICYIDFAILED);
-
- PKIX_CHECK(PKIX_PL_CertPolicyInfo_GetPolQualifiers
- (policy, &policyQualifiers, plContext),
- PKIX_CERTPOLICYINFOGETPOLQUALIFIERSFAILED);
-
- PKIX_EQUALS
- (state->anyPolicyOID,
- policyOID,
- &result,
- plContext,
- PKIX_OIDEQUALFAILED);
-
- if (result == PKIX_FALSE) {
-
- /* Section 6.1.3(d)(1)(i) */
- subroutineErr = pkix_PolicyChecker_CheckPolicy
- (policyOID,
- policyQualifiers,
- cert,
- policyMaps,
- state,
- plContext);
- if (subroutineErr) {
- goto subrErrorCleanup;
- }
-
- } else {
- /*
- * No descent (yet) for anyPolicy, but we will need
- * the policyQualifiers for anyPolicy in 6.1.3(d)(2)
- */
- PKIX_DECREF(qualsOfAny);
- PKIX_INCREF(policyQualifiers);
- qualsOfAny = policyQualifiers;
- certPoliciesIncludeAny = PKIX_TRUE;
- }
- PKIX_DECREF(policy);
- PKIX_DECREF(policyOID);
- PKIX_DECREF(policyQualifiers);
- }
-
- /* Section 6.1.3(d)(2) */
- if (certPoliciesIncludeAny == PKIX_TRUE) {
- if (state->inhibitAnyPolicy > 0) {
- doAnyPolicyProcessing = PKIX_TRUE;
- } else {
- /* We haven't yet counted the current cert */
- if (((state->certsProcessed) + 1) <
- (state->numCerts)) {
-
- PKIX_CHECK(pkix_IsCertSelfIssued
- (cert,
- &doAnyPolicyProcessing,
- plContext),
- PKIX_ISCERTSELFISSUEDFAILED);
- }
- }
- if (doAnyPolicyProcessing) {
- subroutineErr = pkix_PolicyChecker_CheckAny
- (state->validPolicyTree,
- qualsOfAny,
- policyMaps,
- state,
- plContext);
- if (subroutineErr) {
- goto subrErrorCleanup;
- }
- }
- }
-
- /* Section 6.1.3(d)(3) */
- if (state->validPolicyTree) {
- subroutineErr = pkix_PolicyNode_Prune
- (state->validPolicyTree,
- state->certsProcessed + 1,
- &shouldBePruned,
- plContext);
- if (subroutineErr) {
- goto subrErrorCleanup;
- }
- if (shouldBePruned) {
- PKIX_DECREF(state->validPolicyTree);
- PKIX_DECREF(state->anyPolicyNodeAtBottom);
- }
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- } else {
- /* Section 6.1.3(e) */
- PKIX_DECREF(state->validPolicyTree);
- PKIX_DECREF(state->anyPolicyNodeAtBottom);
- PKIX_DECREF(state->newAnyPolicyNode);
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
- }
- }
-
- /* Section 6.1.3(f) */
- if ((0 == state->explicitPolicy) && (!state->validPolicyTree)) {
- PKIX_ERROR(PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION);
- }
-
- /*
- * Remove Policy OIDs from list of unresolved critical
- * extensions, if present.
- */
- PKIX_CHECK(pkix_List_Remove
- (unresolvedCriticals,
- (PKIX_PL_Object *)state->certPoliciesExtension,
- plContext),
- PKIX_LISTREMOVEFAILED);
-
- PKIX_CHECK(pkix_List_Remove
- (unresolvedCriticals,
- (PKIX_PL_Object *)state->policyMappingsExtension,
- plContext),
- PKIX_LISTREMOVEFAILED);
-
- PKIX_CHECK(pkix_List_Remove
- (unresolvedCriticals,
- (PKIX_PL_Object *)state->policyConstraintsExtension,
- plContext),
- PKIX_LISTREMOVEFAILED);
-
- PKIX_CHECK(pkix_List_Remove
- (unresolvedCriticals,
- (PKIX_PL_Object *)state->inhibitAnyPolicyExtension,
- plContext),
- PKIX_LISTREMOVEFAILED);
-
- state->certsProcessed++;
-
- /* If this was not the last certificate, do next-cert preparation */
- if (state->certsProcessed != state->numCerts) {
-
- if (policyMaps) {
- subroutineErr = pkix_PolicyChecker_PolicyMapProcessing
- (policyMaps,
- certPoliciesIncludeAny,
- qualsOfAny,
- state,
- plContext);
- if (subroutineErr) {
- goto subrErrorCleanup;
- }
- }
-
- /* update anyPolicyNodeAtBottom pointer */
- PKIX_DECREF(state->anyPolicyNodeAtBottom);
- state->anyPolicyNodeAtBottom = state->newAnyPolicyNode;
- state->newAnyPolicyNode = NULL;
-
- /* Section 6.1.4(h) */
- PKIX_CHECK(pkix_IsCertSelfIssued
- (cert, &isSelfIssued, plContext),
- PKIX_ISCERTSELFISSUEDFAILED);
-
- if (!isSelfIssued) {
- if (state->explicitPolicy > 0) {
- state->explicitPolicy--;
- }
- if (state->policyMapping > 0) {
- state->policyMapping--;
- }
- if (state->inhibitAnyPolicy > 0) {
- state->inhibitAnyPolicy--;
- }
- }
-
- /* Section 6.1.4(i) */
- PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy
- (cert, &explicitPolicySkipCerts, plContext),
- PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED);
-
- if (explicitPolicySkipCerts != -1) {
- if (((PKIX_UInt32)explicitPolicySkipCerts) <
- (state->explicitPolicy)) {
- state->explicitPolicy =
- ((PKIX_UInt32) explicitPolicySkipCerts);
- }
- }
-
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited
- (cert, &inhibitMappingSkipCerts, plContext),
- PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED);
-
- if (inhibitMappingSkipCerts != -1) {
- if (((PKIX_UInt32)inhibitMappingSkipCerts) <
- (state->policyMapping)) {
- state->policyMapping =
- ((PKIX_UInt32)inhibitMappingSkipCerts);
- }
- }
-
- PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy
- (cert, &inhibitAnyPolicySkipCerts, plContext),
- PKIX_CERTGETINHIBITANYPOLICYFAILED);
-
- if (inhibitAnyPolicySkipCerts != -1) {
- if (((PKIX_UInt32)inhibitAnyPolicySkipCerts) <
- (state->inhibitAnyPolicy)) {
- state->inhibitAnyPolicy =
- ((PKIX_UInt32)inhibitAnyPolicySkipCerts);
- }
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- } else { /* If this was the last certificate, do wrap-up processing */
-
- /* Section 6.1.5 */
- subroutineErr = pkix_PolicyChecker_WrapUpProcessing
- (cert, state, plContext);
- if (subroutineErr) {
- goto subrErrorCleanup;
- }
-
- if ((0 == state->explicitPolicy) && (!state->validPolicyTree)) {
- PKIX_ERROR(PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION);
- }
-
- PKIX_DECREF(state->anyPolicyNodeAtBottom);
- PKIX_DECREF(state->newAnyPolicyNode);
- }
-
-
- if (subroutineErr) {
-
-subrErrorCleanup:
- /* We had an error. Was it a fatal error? */
- pkixErrorClass = subroutineErr->errClass;
- if (pkixErrorClass == PKIX_FATAL_ERROR) {
- pkixErrorResult = subroutineErr;
- subroutineErr = NULL;
- goto cleanup;
- }
- /*
- * Abort policy processing, and then determine whether
- * we can continue without policy processing.
- */
- PKIX_DECREF(state->validPolicyTree);
- PKIX_DECREF(state->anyPolicyNodeAtBottom);
- PKIX_DECREF(state->newAnyPolicyNode);
- if (state->explicitPolicy == 0) {
- PKIX_ERROR
- (PKIX_CERTCHAINFAILSCERTIFICATEPOLICYVALIDATION);
- }
- }
-
- /* Checking is complete. Save state for the next certificate. */
- PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
- (checker, (PKIX_PL_Object *)state, plContext),
- PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
-
-cleanup:
-
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG
- if (cert) {
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)cert, &certString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (certString,
- PKIX_ESCASCII,
- (void **)&certAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
- PKIX_DEBUG_ARG("Cert was %s\n", certAscii);
- PKIX_FREE(certAscii);
- PKIX_DECREF(certString);
- }
- if (state) {
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)state, &stateString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stateString,
- PKIX_ESCASCII,
- (void **)&stateAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
- PKIX_DEBUG_ARG("On exit %s\n", stateAscii);
- PKIX_FREE(stateAscii);
- PKIX_DECREF(stateString);
- }
-#endif
-
- PKIX_DECREF(state);
- PKIX_DECREF(certPolicyInfos);
- PKIX_DECREF(policy);
- PKIX_DECREF(qualsOfAny);
- PKIX_DECREF(policyQualifiers);
- PKIX_DECREF(policyOID);
- PKIX_DECREF(subroutineErr);
- PKIX_DECREF(policyMaps);
- PKIX_DECREF(mappedPolicies);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: pkix_PolicyChecker_Initialize
- * DESCRIPTION:
- *
- * Creates and initializes a PolicyChecker, using the List pointed to
- * by "initialPolicies" for the user-initial-policy-set, the Boolean value
- * of "policyQualifiersRejected" for the policyQualifiersRejected parameter,
- * the Boolean value of "initialPolicyMappingInhibit" for the
- * inhibitPolicyMappings parameter, the Boolean value of
- * "initialExplicitPolicy" for the initialExplicitPolicy parameter, the
- * Boolean value of "initialAnyPolicyInhibit" for the inhibitAnyPolicy
- * parameter, and the UInt32 value of "numCerts" as the number of
- * certificates in the chain; and stores the Checker at "pChecker".
- *
- * PARAMETERS:
- * "initialPolicies"
- * Address of List of OIDs comprising the user-initial-policy-set; the List
- * may be empty or NULL
- * "policyQualifiersRejected"
- * Boolean value of the policyQualifiersRejected parameter
- * "initialPolicyMappingInhibit"
- * Boolean value of the inhibitPolicyMappings parameter
- * "initialExplicitPolicy"
- * Boolean value of the initialExplicitPolicy parameter
- * "initialAnyPolicyInhibit"
- * Boolean value of the inhibitAnyPolicy parameter
- * "numCerts"
- * Number of certificates in the chain to be validated
- * "pChecker"
- * Address to store the created PolicyChecker. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a CertChainChecker Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_PolicyChecker_Initialize(
- PKIX_List *initialPolicies,
- PKIX_Boolean policyQualifiersRejected,
- PKIX_Boolean initialPolicyMappingInhibit,
- PKIX_Boolean initialExplicitPolicy,
- PKIX_Boolean initialAnyPolicyInhibit,
- PKIX_UInt32 numCerts,
- PKIX_CertChainChecker **pChecker,
- void *plContext)
-{
- PKIX_PolicyCheckerState *polCheckerState = NULL;
- PKIX_List *policyExtensions = NULL; /* OIDs */
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_PolicyChecker_Initialize");
- PKIX_NULLCHECK_ONE(pChecker);
-
- PKIX_CHECK(pkix_PolicyCheckerState_Create
- (initialPolicies,
- policyQualifiersRejected,
- initialPolicyMappingInhibit,
- initialExplicitPolicy,
- initialAnyPolicyInhibit,
- numCerts,
- &polCheckerState,
- plContext),
- PKIX_POLICYCHECKERSTATECREATEFAILED);
-
- /* Create the list of extensions that we handle */
- PKIX_CHECK(pkix_PolicyChecker_MakeSingleton
- ((PKIX_PL_Object *)(polCheckerState->certPoliciesExtension),
- PKIX_TRUE,
- &policyExtensions,
- plContext),
- PKIX_POLICYCHECKERMAKESINGLETONFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_Create
- (pkix_PolicyChecker_Check,
- PKIX_FALSE, /* forwardCheckingSupported */
- PKIX_FALSE,
- policyExtensions,
- (PKIX_PL_Object *)polCheckerState,
- pChecker,
- plContext),
- PKIX_CERTCHAINCHECKERCREATEFAILED);
-
-cleanup:
- PKIX_DECREF(polCheckerState);
- PKIX_DECREF(policyExtensions);
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.h
deleted file mode 100755
index 8b87ac122..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_policychecker.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_policychecker.h
- *
- * Header file for policy checker.
- *
- */
-
-#ifndef _PKIX_POLICYCHECKER_H
-#define _PKIX_POLICYCHECKER_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct PKIX_PolicyCheckerStateStruct PKIX_PolicyCheckerState;
-
-struct PKIX_PolicyCheckerStateStruct{
- PKIX_PL_OID *certPoliciesExtension; /* const */
- PKIX_PL_OID *policyMappingsExtension; /* const */
- PKIX_PL_OID *policyConstraintsExtension; /* const */
- PKIX_PL_OID *inhibitAnyPolicyExtension; /* const */
- PKIX_PL_OID *anyPolicyOID; /* const */
- PKIX_Boolean initialIsAnyPolicy; /* const */
- PKIX_PolicyNode *validPolicyTree;
- PKIX_List *userInitialPolicySet; /* immutable */
- PKIX_List *mappedUserInitialPolicySet;
- PKIX_Boolean policyQualifiersRejected;
- PKIX_Boolean initialPolicyMappingInhibit;
- PKIX_Boolean initialExplicitPolicy;
- PKIX_Boolean initialAnyPolicyInhibit;
- PKIX_UInt32 explicitPolicy;
- PKIX_UInt32 inhibitAnyPolicy;
- PKIX_UInt32 policyMapping;
- PKIX_UInt32 numCerts;
- PKIX_UInt32 certsProcessed;
- PKIX_PolicyNode *anyPolicyNodeAtBottom;
- PKIX_PolicyNode *newAnyPolicyNode;
- /*
- * The following variables do not survive from one
- * certificate to the next. They are needed at each
- * level of recursive routines, any by placing them
- * in the state object we can pass fewer arguments.
- */
- PKIX_Boolean certPoliciesCritical;
- PKIX_List *mappedPolicyOIDs;
-};
-
-PKIX_Error *
-pkix_PolicyChecker_Initialize(
- PKIX_List *initialPolicies,
- PKIX_Boolean policyQualifiersRejected,
- PKIX_Boolean initialPolicyMappingInhibit,
- PKIX_Boolean initialExplicitPolicy,
- PKIX_Boolean initialAnyPolicyInhibit,
- PKIX_UInt32 numCerts,
- PKIX_CertChainChecker **pChecker,
- void *plContext);
-
-/* --Private-Functions-------------------------------------------- */
-
-PKIX_Error *
-pkix_PolicyCheckerState_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_POLICYCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c
deleted file mode 100755
index d1499a7dc..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_revocationchecker.c
- *
- * RevocationChecker Object Functions
- *
- */
-
-#include "pkix_revocationchecker.h"
-#include "pkix_tools.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_RevocationChecker_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_RevocationChecker_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_RevocationChecker *checker = NULL;
-
- PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a revocation checker */
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_REVOCATIONCHECKER_TYPE, plContext),
- PKIX_OBJECTNOTREVOCATIONCHECKER);
-
- checker = (PKIX_RevocationChecker *)object;
-
- PKIX_DECREF(checker->leafMethodList);
- PKIX_DECREF(checker->chainMethodList);
-
-cleanup:
-
- PKIX_RETURN(REVOCATIONCHECKER);
-}
-
-/*
- * FUNCTION: pkix_RevocationChecker_Duplicate
- * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_RevocationChecker_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_RevocationChecker *checker = NULL;
- PKIX_RevocationChecker *checkerDuplicate = NULL;
- PKIX_List *dupLeafList = NULL;
- PKIX_List *dupChainList = NULL;
-
- PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_Duplicate");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_REVOCATIONCHECKER_TYPE, plContext),
- PKIX_OBJECTNOTCERTCHAINCHECKER);
-
- checker = (PKIX_RevocationChecker *)object;
-
- if (checker->leafMethodList){
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- ((PKIX_PL_Object *)checker->leafMethodList,
- (PKIX_PL_Object **)&dupLeafList,
- plContext),
- PKIX_OBJECTDUPLICATEFAILED);
- }
- if (checker->chainMethodList){
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- ((PKIX_PL_Object *)checker->chainMethodList,
- (PKIX_PL_Object **)&dupChainList,
- plContext),
- PKIX_OBJECTDUPLICATEFAILED);
- }
-
- PKIX_CHECK(
- PKIX_RevocationChecker_Create(checker->leafMethodListFlags,
- checker->chainMethodListFlags,
- &checkerDuplicate,
- plContext),
- PKIX_REVOCATIONCHECKERCREATEFAILED);
-
- checkerDuplicate->leafMethodList = dupLeafList;
- checkerDuplicate->chainMethodList = dupChainList;
- dupLeafList = NULL;
- dupChainList = NULL;
-
- *pNewObject = (PKIX_PL_Object *)checkerDuplicate;
-
-cleanup:
- PKIX_DECREF(dupLeafList);
- PKIX_DECREF(dupChainList);
-
- PKIX_RETURN(REVOCATIONCHECKER);
-}
-
-/*
- * FUNCTION: pkix_RevocationChecker_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_REVOCATIONCHECKER_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_RevocationChecker_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_RegisterSelf");
-
- entry.description = "RevocationChecker";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_RevocationChecker);
- entry.destructor = pkix_RevocationChecker_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_RevocationChecker_Duplicate;
-
- systemClasses[PKIX_REVOCATIONCHECKER_TYPE] = entry;
-
- PKIX_RETURN(REVOCATIONCHECKER);
-}
-
-/* Sort methods by theirs priorities */
-static PKIX_Error *
-pkix_RevocationChecker_SortComparator(
- PKIX_PL_Object *obj1,
- PKIX_PL_Object *obj2,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- pkix_RevocationMethod *method1 = NULL, *method2 = NULL;
-
- PKIX_ENTER(BUILD, "pkix_RevocationChecker_SortComparator");
-
- method1 = (pkix_RevocationMethod *)obj1;
- method2 = (pkix_RevocationMethod *)obj2;
-
- *pResult = (method1->priority > method2->priority);
-
- PKIX_RETURN(BUILD);
-}
-
-
-/* --Public-Functions--------------------------------------------- */
-
-
-/*
- * FUNCTION: PKIX_RevocationChecker_Create (see comments in pkix_revchecker.h)
- */
-PKIX_Error *
-PKIX_RevocationChecker_Create(
- PKIX_UInt32 leafMethodListFlags,
- PKIX_UInt32 chainMethodListFlags,
- PKIX_RevocationChecker **pChecker,
- void *plContext)
-{
- PKIX_RevocationChecker *checker = NULL;
-
- PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Create");
- PKIX_NULLCHECK_ONE(pChecker);
-
- PKIX_CHECK(
- PKIX_PL_Object_Alloc(PKIX_REVOCATIONCHECKER_TYPE,
- sizeof (PKIX_RevocationChecker),
- (PKIX_PL_Object **)&checker,
- plContext),
- PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT);
-
- checker->leafMethodListFlags = leafMethodListFlags;
- checker->chainMethodListFlags = chainMethodListFlags;
- checker->leafMethodList = NULL;
- checker->chainMethodList = NULL;
-
- *pChecker = checker;
- checker = NULL;
-
-cleanup:
- PKIX_DECREF(checker);
-
- PKIX_RETURN(REVOCATIONCHECKER);
-}
-
-/*
- * FUNCTION: PKIX_RevocationChecker_CreateAndAddMethod
- */
-PKIX_Error *
-PKIX_RevocationChecker_CreateAndAddMethod(
- PKIX_RevocationChecker *revChecker,
- PKIX_ProcessingParams *params,
- PKIX_RevocationMethodType methodType,
- PKIX_UInt32 flags,
- PKIX_UInt32 priority,
- PKIX_PL_VerifyCallback verificationFn,
- PKIX_Boolean isLeafMethod,
- void *plContext)
-{
- PKIX_List **methodList = NULL;
- PKIX_List *unsortedList = NULL;
- PKIX_List *certStores = NULL;
- pkix_RevocationMethod *method = NULL;
- pkix_LocalRevocationCheckFn *localRevChecker = NULL;
- pkix_ExternalRevocationCheckFn *externRevChecker = NULL;
- PKIX_UInt32 miFlags;
-
- PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_CreateAndAddMethod");
- PKIX_NULLCHECK_ONE(revChecker);
-
- /* If the caller has said "Either one is sufficient, then don't let the
- * absence of any one method's info lead to an overall failure.
- */
- miFlags = isLeafMethod ? revChecker->leafMethodListFlags
- : revChecker->chainMethodListFlags;
- if (miFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE)
- flags &= ~PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;
-
- switch (methodType) {
- case PKIX_RevocationMethod_CRL:
- localRevChecker = pkix_CrlChecker_CheckLocal;
- externRevChecker = pkix_CrlChecker_CheckExternal;
- PKIX_CHECK(
- PKIX_ProcessingParams_GetCertStores(params, &certStores,
- plContext),
- PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
- PKIX_CHECK(
- pkix_CrlChecker_Create(methodType, flags, priority,
- localRevChecker, externRevChecker,
- certStores, verificationFn,
- &method,
- plContext),
- PKIX_COULDNOTCREATECRLCHECKEROBJECT);
- break;
- case PKIX_RevocationMethod_OCSP:
- localRevChecker = pkix_OcspChecker_CheckLocal;
- externRevChecker = pkix_OcspChecker_CheckExternal;
- PKIX_CHECK(
- pkix_OcspChecker_Create(methodType, flags, priority,
- localRevChecker, externRevChecker,
- verificationFn,
- &method,
- plContext),
- PKIX_COULDNOTCREATEOCSPCHECKEROBJECT);
- break;
- default:
- PKIX_ERROR(PKIX_INVALIDREVOCATIONMETHOD);
- }
-
- if (isLeafMethod) {
- methodList = &revChecker->leafMethodList;
- } else {
- methodList = &revChecker->chainMethodList;
- }
-
- if (*methodList == NULL) {
- PKIX_CHECK(
- PKIX_List_Create(methodList, plContext),
- PKIX_LISTCREATEFAILED);
- }
- unsortedList = *methodList;
- PKIX_CHECK(
- PKIX_List_AppendItem(unsortedList, (PKIX_PL_Object*)method, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_CHECK(
- pkix_List_BubbleSort(unsortedList,
- pkix_RevocationChecker_SortComparator,
- methodList, plContext),
- PKIX_LISTBUBBLESORTFAILED);
-
-cleanup:
- PKIX_DECREF(method);
- PKIX_DECREF(unsortedList);
- PKIX_DECREF(certStores);
-
- PKIX_RETURN(REVOCATIONCHECKER);
-}
-
-/*
- * FUNCTION: PKIX_RevocationChecker_Check
- */
-PKIX_Error *
-PKIX_RevocationChecker_Check(
- PKIX_PL_Cert *cert,
- PKIX_PL_Cert *issuer,
- PKIX_RevocationChecker *revChecker,
- PKIX_ProcessingParams *procParams,
- PKIX_Boolean chainVerificationState,
- PKIX_Boolean testingLeafCert,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *pReasonCode,
- void **pNbioContext,
- void *plContext)
-{
- PKIX_RevocationStatus overallStatus = PKIX_RevStatus_NoInfo;
- PKIX_RevocationStatus methodStatus[PKIX_RevocationMethod_MAX];
- PKIX_Boolean onlyUseRemoteMethods = PKIX_FALSE;
- PKIX_UInt32 revFlags = 0;
- PKIX_List *revList = NULL;
- PKIX_PL_Date *date = NULL;
- pkix_RevocationMethod *method = NULL;
- void *nbioContext;
- int tries;
-
- PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_Check");
- PKIX_NULLCHECK_TWO(revChecker, procParams);
-
- nbioContext = *pNbioContext;
- *pNbioContext = NULL;
-
- if (testingLeafCert) {
- revList = revChecker->leafMethodList;
- revFlags = revChecker->leafMethodListFlags;
- } else {
- revList = revChecker->chainMethodList;
- revFlags = revChecker->chainMethodListFlags;
- }
- if (!revList) {
- /* Return NoInfo status */
- goto cleanup;
- }
-
- PORT_Memset(methodStatus, PKIX_RevStatus_NoInfo,
- sizeof(PKIX_RevocationStatus) * PKIX_RevocationMethod_MAX);
-
- date = procParams->date;
-
- /* Need to have two loops if we testing all local info first:
- * first we are going to test all local(cached) info
- * second, all remote info(fetching) */
- for (tries = 0;tries < 2;tries++) {
- int methodNum = 0;
- for (;methodNum < revList->length;methodNum++) {
- PKIX_UInt32 methodFlags = 0;
-
- PKIX_DECREF(method);
- PKIX_CHECK(
- PKIX_List_GetItem(revList, methodNum,
- (PKIX_PL_Object**)&method, plContext),
- PKIX_LISTGETITEMFAILED);
- methodFlags = method->flags;
- if (!(methodFlags & PKIX_REV_M_TEST_USING_THIS_METHOD)) {
- /* Will not check with this method. Skipping... */
- continue;
- }
- if (!onlyUseRemoteMethods &&
- methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
- PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
- PKIX_CHECK_NO_GOTO(
- (*method->localRevChecker)(cert, issuer, date,
- method, procParams,
- methodFlags,
- chainVerificationState,
- &revStatus,
- pReasonCode, plContext),
- PKIX_REVCHECKERCHECKFAILED);
- methodStatus[methodNum] = revStatus;
- if (revStatus == PKIX_RevStatus_Revoked) {
- /* if error was generated use it as final error. */
- overallStatus = PKIX_RevStatus_Revoked;
- goto cleanup;
- }
- if (pkixErrorResult) {
- /* Disregard errors. Only returned revStatus matters. */
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
- plContext);
- pkixErrorResult = NULL;
- }
- }
- if ((!(revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST) ||
- onlyUseRemoteMethods) &&
- chainVerificationState &&
- methodStatus[methodNum] == PKIX_RevStatus_NoInfo) {
- if (!(methodFlags & PKIX_REV_M_FORBID_NETWORK_FETCHING)) {
- PKIX_RevocationStatus revStatus = PKIX_RevStatus_NoInfo;
- PKIX_CHECK_NO_GOTO(
- (*method->externalRevChecker)(cert, issuer, date,
- method,
- procParams, methodFlags,
- &revStatus, pReasonCode,
- &nbioContext, plContext),
- PKIX_REVCHECKERCHECKFAILED);
- methodStatus[methodNum] = revStatus;
- if (revStatus == PKIX_RevStatus_Revoked) {
- /* if error was generated use it as final error. */
- overallStatus = PKIX_RevStatus_Revoked;
- goto cleanup;
- }
- if (pkixErrorResult) {
- /* Disregard errors. Only returned revStatus matters. */
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorResult,
- plContext);
- pkixErrorResult = NULL;
- }
- } else if (methodFlags &
- PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO) {
- /* Info is not in the local cache. Network fetching is not
- * allowed. If need to fail on missing fresh info for the
- * the method, then we should fail right here.*/
- overallStatus = PKIX_RevStatus_Revoked;
- goto cleanup;
- }
- }
- /* If success and we should not check the next method, then
- * return a success. */
- if (methodStatus[methodNum] == PKIX_RevStatus_Success &&
- !(methodFlags & PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO)) {
- overallStatus = PKIX_RevStatus_Success;
- goto cleanup;
- }
- } /* inner loop */
- if (!onlyUseRemoteMethods &&
- revFlags & PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST &&
- chainVerificationState) {
- onlyUseRemoteMethods = PKIX_TRUE;
- continue;
- }
- break;
- } /* outer loop */
-
- if (overallStatus == PKIX_RevStatus_NoInfo &&
- chainVerificationState) {
- /* The following check makes sence only for chain
- * validation step, sinse we do not fetch info while
- * in the process of finding trusted anchor.
- * For chain building step it is enough to know, that
- * the cert was not directly revoked by any of the
- * methods. */
-
- /* Still have no info. But one of the method could
- * have returned success status(possible if CONTINUE
- * TESTING ON FRESH INFO flag was used).
- * If any of the methods have returned Success status,
- * the overallStatus should be success. */
- int methodNum = 0;
- for (;methodNum < PKIX_RevocationMethod_MAX;methodNum++) {
- if (methodStatus[methodNum] == PKIX_RevStatus_Success) {
- overallStatus = PKIX_RevStatus_Success;
- goto cleanup;
- }
- }
- if (revFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE) {
- overallStatus = PKIX_RevStatus_Revoked;
- }
- }
-
-cleanup:
- *pRevStatus = overallStatus;
- PKIX_DECREF(method);
-
- PKIX_RETURN(REVOCATIONCHECKER);
-}
-
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h
deleted file mode 100755
index 80d9eeaa2..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_revocationchecker.h
- *
- * RevocationChecker Object Type Definition
- *
- */
-
-#ifndef _PKIX_REVOCATIONCHECKER_H
-#define _PKIX_REVOCATIONCHECKER_H
-
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* NOTE: nbio logistic removed. Will be replaced later. */
-
-/*
- * All Flags are prefixed by CERT_REV_M_, where _M_ indicates
- * this is a method dependent flag.
- */
-
-/*
- * Whether or not to use a method for revocation testing.
- * If set to "do not test", then all other flags are ignored.
- */
-#define PKIX_REV_M_DO_NOT_TEST_USING_THIS_METHOD 0x00L
-#define PKIX_REV_M_TEST_USING_THIS_METHOD 0x01L
-
-/*
- * Whether or not NSS is allowed to attempt to fetch fresh information
- * from the network.
- * (Although fetching will never happen if fresh information for the
- * method is already locally available.)
- */
-#define PKIX_REV_M_ALLOW_NETWORK_FETCHING 0x00L
-#define PKIX_REV_M_FORBID_NETWORK_FETCHING 0x02L
-
-/*
- * Example for an implicit default source:
- * The globally configured default OCSP responder.
- * IGNORE means:
- * ignore the implicit default source, whether it's configured or not.
- * ALLOW means:
- * if an implicit default source is configured,
- * then it overrides any available or missing source in the cert.
- * if no implicit default source is configured,
- * then we continue to use what's available (or not available)
- * in the certs.
- */
-#define PKIX_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE 0x00L
-#define PKIX_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE 0x04L /* OCSP only */
-
-/*
- * Defines the behavior if no fresh information is available,
- * fetching from the network is allowed, but the source of revocation
- * information is unknown (even after considering implicit sources,
- * if allowed by other flags).
- * SKIPT_TEST means:
- * We ignore that no fresh information is available and
- * skip this test.
- * REQUIRE_INFO means:
- * We still require that fresh information is available.
- * Other flags define what happens on missing fresh info.
- */
-
-#define PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE 0x00L
-#define PKIX_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE 0x08L
-
-/*
- * Defines the behavior if we are unable to obtain fresh information.
- * INGORE means:
- * Return "cert status unknown"
- * FAIL means:
- * Return "cert revoked".
- */
-
-#define PKIX_REV_M_IGNORE_MISSING_FRESH_INFO 0x00L
-#define PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO 0x10L
-
-/*
- * What should happen if we were able to find fresh information using
- * this method, and the data indicated the cert is good?
- * STOP_TESTING means:
- * Our success is sufficient, do not continue testing
- * other methods.
- * CONTINUE_TESTING means:
- * We will continue and test the next allowed
- * specified method.
- */
-
-#define PKIX_REV_M_STOP_TESTING_ON_FRESH_INFO 0x00L
-#define PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO 0x20L
-
-/*
- * All Flags are prefixed by PKIX_REV_MI_, where _MI_ indicates
- * this is a method independent flag.
- */
-
-/*
- * This defines the order to checking.
- * EACH_METHOD_SEPARATELY means:
- * Do all tests related to a particular allowed method
- * (both local information and network fetching) in a single step.
- * Only after testing for a particular method is done,
- * then switching to the next method will happen.
- * ALL_LOCAL_INFORMATION_FIRST means:
- * Start by testing the information for all allowed methods
- * which are already locally available. Only after that is done
- * consider to fetch from the network (as allowed by other flags).
- */
-#define PKIX_REV_MI_TEST_EACH_METHOD_SEPARATELY 0x00L
-#define PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST 0x01L
-
-/*
- * Use this flag to specify that it's necessary that fresh information
- * is available for at least one of the allowed methods, but it's
- * irrelevant which of the mechanisms succeeded.
- * NO_OVERALL_INFO_REQUIREMENT means:
- * We strictly follow the requirements for each individual method.
- * REQUIRE_SOME_FRESH_INFO_AVAILABLE means:
- * After the individual tests have been executed, we must have
- * been able to find fresh information using at least one method.
- * If we were unable to find fresh info, it's a failure.
- */
-#define PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT 0x00L
-#define PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE 0x02L
-
-/* Defines check time for the cert, revocation methods lists and
- * flags for leaf and chain certs revocation tests. */
-struct PKIX_RevocationCheckerStruct {
- PKIX_List *leafMethodList;
- PKIX_List *chainMethodList;
- PKIX_UInt32 leafMethodListFlags;
- PKIX_UInt32 chainMethodListFlags;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_RevocationChecker_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_REVOCATIONCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_revocationmethod.c b/security/nss/lib/libpkix/pkix/checker/pkix_revocationmethod.c
deleted file mode 100644
index ee18ddef9..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_revocationmethod.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_revocationmethod.c
- *
- * RevocationMethod Object Functions
- *
- */
-
-#include "pkix_revocationmethod.h"
-#include "pkix_tools.h"
-
-/* Constructor of revocation method object. Does not create an object,
- * but just initializez PKIX_RevocationMethodStruct fields. Object
- * suppose to be already created. */
-PKIX_Error *
-pkix_RevocationMethod_Init(
- pkix_RevocationMethod *method,
- PKIX_RevocationMethodType methodType,
- PKIX_UInt32 flags,
- PKIX_UInt32 priority,
- pkix_LocalRevocationCheckFn localRevChecker,
- pkix_ExternalRevocationCheckFn externalRevChecker,
- void *plContext)
-{
- PKIX_ENTER(REVOCATIONMETHOD, "PKIX_RevocationMethod_Init");
-
- method->methodType = methodType;
- method->flags = flags;
- method->priority = priority;
- method->localRevChecker = localRevChecker;
- method->externalRevChecker = externalRevChecker;
-
- PKIX_RETURN(REVOCATIONMETHOD);
-}
-
-/* Data duplication data. Not create an object. Only initializes fields
- * in the new object by data from "object". */
-PKIX_Error *
-pkix_RevocationMethod_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object *newObject,
- void *plContext)
-{
- pkix_RevocationMethod *method = NULL;
-
- PKIX_ENTER(REVOCATIONMETHOD, "pkix_RevocationMethod_Duplicate");
- PKIX_NULLCHECK_TWO(object, newObject);
-
- method = (pkix_RevocationMethod *)object;
-
- PKIX_CHECK(
- pkix_RevocationMethod_Init((pkix_RevocationMethod*)newObject,
- method->methodType,
- method->flags,
- method->priority,
- method->localRevChecker,
- method->externalRevChecker,
- plContext),
- PKIX_COULDNOTCREATEREVOCATIONMETHODOBJECT);
-
-cleanup:
-
- PKIX_RETURN(REVOCATIONMETHOD);
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_revocationmethod.h b/security/nss/lib/libpkix/pkix/checker/pkix_revocationmethod.h
deleted file mode 100644
index 32e452556..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_revocationmethod.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_revocationmethod.h
- *
- * RevocationMethod Object
- *
- */
-
-#ifndef _PKIX_REVOCATIONMETHOD_H
-#define _PKIX_REVOCATIONMETHOD_H
-
-#include "pkixt.h"
-#include "pkix_revocationchecker.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct pkix_RevocationMethodStruct pkix_RevocationMethod;
-
-/* Local revocation check function prototype definition.
- * Revocation methods capable of checking revocation though local
- * means(cache) should implement this prototype. */
-typedef PKIX_Error *
-pkix_LocalRevocationCheckFn(PKIX_PL_Cert *cert, PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_Boolean chainVerificationState,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *reasonCode,
- void *plContext);
-
-/* External revocation check function prototype definition.
- * Revocation methods that required external communications(crldp
- * ocsp) shoult implement this prototype. */
-typedef PKIX_Error *
-pkix_ExternalRevocationCheckFn(PKIX_PL_Cert *cert, PKIX_PL_Cert *issuer,
- PKIX_PL_Date *date,
- pkix_RevocationMethod *checkerObject,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 methodFlags,
- PKIX_RevocationStatus *pRevStatus,
- PKIX_UInt32 *reasonCode,
- void **pNBIOContext, void *plContext);
-
-/* Revocation method structure assosiates revocation types with
- * a set of flags on the method, a priority of the method, and
- * method local/external checker functions. */
-struct pkix_RevocationMethodStruct {
- PKIX_RevocationMethodType methodType;
- PKIX_UInt32 flags;
- PKIX_UInt32 priority;
- pkix_LocalRevocationCheckFn (*localRevChecker);
- pkix_ExternalRevocationCheckFn (*externalRevChecker);
-};
-
-PKIX_Error *
-pkix_RevocationMethod_Duplicate(PKIX_PL_Object *object,
- PKIX_PL_Object *newObject,
- void *plContext);
-
-PKIX_Error *
-pkix_RevocationMethod_Init(pkix_RevocationMethod *method,
- PKIX_RevocationMethodType methodType,
- PKIX_UInt32 flags,
- PKIX_UInt32 priority,
- pkix_LocalRevocationCheckFn localRevChecker,
- pkix_ExternalRevocationCheckFn externalRevChecker,
- void *plContext);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_REVOCATIONMETHOD_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.c
deleted file mode 100755
index 0ed9ffaec..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_signaturechecker.c
- *
- * Functions for signature validation
- *
- */
-
-#include "pkix_signaturechecker.h"
-
-/*
- * FUNCTION: pkix_SignatureCheckerstate_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_SignatureCheckerState_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- pkix_SignatureCheckerState *state = NULL;
-
- PKIX_ENTER(SIGNATURECHECKERSTATE,
- "pkix_SignatureCheckerState_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a signature checker state */
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_SIGNATURECHECKERSTATE_TYPE, plContext),
- PKIX_OBJECTNOTSIGNATURECHECKERSTATE);
-
- state = (pkix_SignatureCheckerState *) object;
-
- state->prevCertCertSign = PKIX_FALSE;
-
- PKIX_DECREF(state->prevPublicKey);
- PKIX_DECREF(state->prevPublicKeyList);
- PKIX_DECREF(state->keyUsageOID);
-
-cleanup:
-
- PKIX_RETURN(SIGNATURECHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_SignatureCheckerState_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_SIGNATURECHECKERSTATE_TYPE and its related functions
- * with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_SignatureCheckerState_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(SIGNATURECHECKERSTATE,
- "pkix_SignatureCheckerState_RegisterSelf");
-
- entry.description = "SignatureCheckerState";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(pkix_SignatureCheckerState);
- entry.destructor = pkix_SignatureCheckerState_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_SIGNATURECHECKERSTATE_TYPE] = entry;
-
- PKIX_RETURN(SIGNATURECHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_SignatureCheckerState_Create
- *
- * DESCRIPTION:
- * Allocate and initialize SignatureChecker state data.
- *
- * PARAMETERS
- * "trustedPubKey"
- * Address of trusted Anchor Public Key for verifying first Cert in the
- * chain. Must be non-NULL.
- * "certsRemaining"
- * Number of certificates remaining in the chain.
- * "pCheckerState"
- * Address where SignatureCheckerState will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a SignatureCheckerState Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_SignatureCheckerState_Create(
- PKIX_PL_PublicKey *trustedPubKey,
- PKIX_UInt32 certsRemaining,
- pkix_SignatureCheckerState **pCheckerState,
- void *plContext)
-{
- pkix_SignatureCheckerState *state = NULL;
- PKIX_PL_OID *keyUsageOID = NULL;
-
- PKIX_ENTER(SIGNATURECHECKERSTATE, "pkix_SignatureCheckerState_Create");
- PKIX_NULLCHECK_TWO(trustedPubKey, pCheckerState);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_SIGNATURECHECKERSTATE_TYPE,
- sizeof (pkix_SignatureCheckerState),
- (PKIX_PL_Object **)&state,
- plContext),
- PKIX_COULDNOTCREATESIGNATURECHECKERSTATEOBJECT);
-
- /* Initialize fields */
-
- state->prevCertCertSign = PKIX_TRUE;
- state->prevPublicKeyList = NULL;
- state->certsRemaining = certsRemaining;
-
- PKIX_INCREF(trustedPubKey);
- state->prevPublicKey = trustedPubKey;
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_CERTKEYUSAGE_OID,
- &keyUsageOID,
- plContext),
- PKIX_OIDCREATEFAILED);
-
- state->keyUsageOID = keyUsageOID;
- keyUsageOID = NULL;
-
- *pCheckerState = state;
- state = NULL;
-
-cleanup:
-
- PKIX_DECREF(keyUsageOID);
- PKIX_DECREF(state);
-
- PKIX_RETURN(SIGNATURECHECKERSTATE);
-}
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_SignatureChecker_Check
- * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
- */
-PKIX_Error *
-pkix_SignatureChecker_Check(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Cert *cert,
- PKIX_List *unresolvedCriticalExtensions,
- void **pNBIOContext,
- void *plContext)
-{
- pkix_SignatureCheckerState *state = NULL;
- PKIX_PL_PublicKey *prevPubKey = NULL;
- PKIX_PL_PublicKey *currPubKey = NULL;
- PKIX_PL_PublicKey *newPubKey = NULL;
- PKIX_PL_PublicKey *pKey = NULL;
- PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
- PKIX_Error *checkKeyUsageFail = NULL;
- PKIX_Error *verifyFail = NULL;
- PKIX_Boolean certVerified = PKIX_FALSE;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_SignatureChecker_Check");
- PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
-
- *pNBIOContext = NULL; /* we never block on pending I/O */
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
- (checker, (PKIX_PL_Object **)&state, plContext),
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
-
- (state->certsRemaining)--;
-
- PKIX_INCREF(state->prevPublicKey);
- prevPubKey = state->prevPublicKey;
-
- /*
- * Previous Cert doesn't have CertSign bit on for signature
- * verification and it is not a self-issued Cert so there is no
- * old key saved. This is considered error.
- */
- if (state->prevCertCertSign == PKIX_FALSE &&
- state->prevPublicKeyList == NULL) {
- PKIX_ERROR(PKIX_KEYUSAGEKEYCERTSIGNBITNOTON);
- }
-
- /* Previous Cert is valid for signature verification, try it first */
- if (state->prevCertCertSign == PKIX_TRUE) {
- verifyFail = PKIX_PL_Cert_VerifySignature
- (cert, prevPubKey, plContext);
- if (verifyFail == NULL) {
- certVerified = PKIX_TRUE;
- } else {
- certVerified = PKIX_FALSE;
- }
- }
-
-#ifdef NIST_TEST_4_5_4_AND_4_5_6
-
- /*
- * Following codes under this compiler flag is implemented for
- * special cases of NIST tests 4.5.4 and 4.5.6. We are not sure
- * we should handle these two tests as what is implemented so the
- * codes are commented out, and the tests fails (for now).
- * For Cert chain validation, our assumption is all the Certs on
- * the chain are using its previous Cert's public key to decode
- * its current key. But for thses two tests, keys are used not
- * in this precedent order, we can either
- * 1) Use what is implemented here: take in what Cert order NIST
- * specified and for continuous self-issued Certs, stacking up
- * their keys and tries all of them in FILO order.
- * But this method breaks the idea of chain key presdency.
- * 2) Use Build Chain facility: we will specify the valid Certs
- * order (means key precedency is kept) and count on Build Chain
- * to get the Certs that can fill for the needed keys. This may have
- * performance impact.
- * 3) Fetch Certs from CertStore: we will specifiy the valid Certs
- * order and use CertSelector on SubjectName to get a list of
- * candidates Certs to fill in for the needed keys.
- * Anyhow, the codes are kept around just in case we want to use
- * solution one...
- */
-
- /* If failed and previous key is self-issued, try its old key(s) */
- if (certVerified == PKIX_FALSE && state->prevPublicKeyList != NULL) {
-
- /* Verify from keys on the list */
- PKIX_CHECK(PKIX_List_GetLength
- (state->prevPublicKeyList, &numKeys, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = numKeys - 1; i >= 0; i--) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (state->prevPublicKeyList,
- i,
- (PKIX_PL_Object **) &pKey,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_DECREF(verifyFail);
- verifyFail = PKIX_PL_Cert_VerifySignature
- (cert, pKey, plContext);
-
- if (verifyFail == NULL) {
- certVerified = PKIX_TRUE;
- break;
- } else {
- certVerified = PKIX_FALSE;
- }
-
- PKIX_DECREF(pKey);
- }
- }
-#endif
-
- if (certVerified == PKIX_FALSE) {
- pkixErrorResult = verifyFail;
- verifyFail = NULL;
- PKIX_ERROR(PKIX_VALIDATIONFAILEDCERTSIGNATURECHECKING);
- }
-
-#ifdef NIST_TEST_4_5_4_AND_4_5_6
- /*
- * Check if Cert is self-issued. If so, the old key(s) is saved, in
- * conjunction to the new key, for verifying CERT validity later.
- */
- PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext),
- PKIX_ISCERTSELFISSUEFAILED);
-
- /*
- * Check if Cert is self-issued. If so, the public key of the Cert
- * that issues this Cert (old key) can be used together with this
- * current key (new key) for key verification. If there are multiple
- * self-issued certs, keys of those Certs (old keys) can also be used
- * for key verification. Old key(s) is saved in a list (PrevPublickKey-
- * List) and cleared when a Cert is no longer self-issued. PrevPublic-
- * Key keep key of the previous Cert.
- */
- if (selfIssued == PKIX_TRUE) {
-
- /* Make sure previous Cert is valid for signature verification */
- if (state->prevCertCertSign == PKIX_TRUE) {
-
- if (state->prevPublicKeyList == NULL) {
-
- PKIX_CHECK(PKIX_List_Create
- (&state->prevPublicKeyList, plContext),
- PKIX_LISTCREATEFALIED);
-
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (state->prevPublicKeyList,
- (PKIX_PL_Object *) state->prevPublicKey,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
-
- } else {
- /* Not self-issued Cert any more, clear old key(s) saved */
- PKIX_DECREF(state->prevPublicKeyList);
- }
-#endif
-
- /* Save current key as prevPublicKey */
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
- (cert, &currPubKey, plContext),
- PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
-
- PKIX_CHECK(PKIX_PL_PublicKey_MakeInheritedDSAPublicKey
- (currPubKey, prevPubKey, &newPubKey, plContext),
- PKIX_PUBLICKEYMAKEINHERITEDDSAPUBLICKEYFAILED);
-
- if (newPubKey == NULL){
- PKIX_INCREF(currPubKey);
- newPubKey = currPubKey;
- }
-
- PKIX_INCREF(newPubKey);
- PKIX_DECREF(state->prevPublicKey);
-
- state->prevPublicKey = newPubKey;
-
- /* Save this Cert key usage CertSign bit */
- if (state->certsRemaining != 0) {
- checkKeyUsageFail = PKIX_PL_Cert_VerifyKeyUsage
- (cert, PKIX_KEY_CERT_SIGN, plContext);
-
- state->prevCertCertSign = (checkKeyUsageFail == NULL)?
- PKIX_TRUE:PKIX_FALSE;
-
- PKIX_DECREF(checkKeyUsageFail);
- }
-
- /* Remove Key Usage Extension OID from list */
- if (unresolvedCriticalExtensions != NULL) {
-
- PKIX_CHECK(pkix_List_Remove
- (unresolvedCriticalExtensions,
- (PKIX_PL_Object *) state->keyUsageOID,
- plContext),
- PKIX_LISTREMOVEFAILED);
- }
-
- PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
- (checker, (PKIX_PL_Object *)state, plContext),
- PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
-
-cleanup:
-
- PKIX_DECREF(state);
- PKIX_DECREF(pKey);
- PKIX_DECREF(prevPubKey);
- PKIX_DECREF(currPubKey);
- PKIX_DECREF(newPubKey);
- PKIX_DECREF(basicConstraints);
- PKIX_DECREF(verifyFail);
- PKIX_DECREF(checkKeyUsageFail);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
-
-/*
- * FUNCTION: pkix_SignatureChecker_Initialize
- * DESCRIPTION:
- *
- * Creates a new CertChainChecker and stores it at "pChecker", where it will
- * be used by pkix_SignatureChecker_Check to check that the public key in
- * the checker's state is able to successfully validate the certificate's
- * signature. The PublicKey pointed to by "trustedPubKey" is used to
- * initialize the checker's state.
- *
- * PARAMETERS:
- * "trustedPubKey"
- * Address of PublicKey representing the trusted public key used to
- * initialize the state of this checker. Must be non-NULL.
- * "certsRemaining"
- * Number of certificates remaining in the chain.
- * "pChecker"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_SignatureChecker_Initialize(
- PKIX_PL_PublicKey *trustedPubKey,
- PKIX_UInt32 certsRemaining,
- PKIX_CertChainChecker **pChecker,
- void *plContext)
-{
- pkix_SignatureCheckerState* state = NULL;
- PKIX_ENTER(CERTCHAINCHECKER, "PKIX_SignatureChecker_Initialize");
- PKIX_NULLCHECK_TWO(pChecker, trustedPubKey);
-
- PKIX_CHECK(pkix_SignatureCheckerState_Create
- (trustedPubKey, certsRemaining, &state, plContext),
- PKIX_SIGNATURECHECKERSTATECREATEFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_Create
- (pkix_SignatureChecker_Check,
- PKIX_FALSE,
- PKIX_FALSE,
- NULL,
- (PKIX_PL_Object *) state,
- pChecker,
- plContext),
- PKIX_CERTCHAINCHECKERCREATEFAILED);
-
-cleanup:
-
- PKIX_DECREF(state);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.h
deleted file mode 100755
index ccfb57857..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_signaturechecker.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_signaturechecker.h
- *
- * Header file for validate signature function
- *
- */
-
-#ifndef _PKIX_SIGNATURECHECKER_H
-#define _PKIX_SIGNATURECHECKER_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct pkix_SignatureCheckerState pkix_SignatureCheckerState;
-
-struct pkix_SignatureCheckerState {
- PKIX_Boolean prevCertCertSign;
- PKIX_UInt32 certsRemaining;
- PKIX_PL_PublicKey *prevPublicKey; /* Subject PubKey of last cert */
- PKIX_List *prevPublicKeyList; /* of PKIX_PL_PublicKey */
- PKIX_PL_OID *keyUsageOID;
-};
-
-PKIX_Error *
-pkix_SignatureChecker_Initialize(
- PKIX_PL_PublicKey *trustedPubKey,
- PKIX_UInt32 certsRemaining,
- PKIX_CertChainChecker **pChecker,
- void *plContext);
-
-PKIX_Error *
-pkix_SignatureCheckerState_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_SIGNATURECHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c b/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c
deleted file mode 100755
index 46fe07112..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_targetcertchecker.c
- *
- * Functions for target cert validation
- *
- */
-
-
-#include "pkix_targetcertchecker.h"
-
-/* --Private-TargetCertCheckerState-Functions------------------------------- */
-
-/*
- * FUNCTION: pkix_TargetCertCheckerState_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_TargetCertCheckerState_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- pkix_TargetCertCheckerState *state = NULL;
-
- PKIX_ENTER(TARGETCERTCHECKERSTATE,
- "pkix_TargetCertCheckerState_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a target cert checker state */
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_TARGETCERTCHECKERSTATE_TYPE, plContext),
- PKIX_OBJECTNOTTARGETCERTCHECKERSTATE);
-
- state = (pkix_TargetCertCheckerState *)object;
-
- PKIX_DECREF(state->certSelector);
- PKIX_DECREF(state->extKeyUsageOID);
- PKIX_DECREF(state->subjAltNameOID);
- PKIX_DECREF(state->pathToNameList);
- PKIX_DECREF(state->extKeyUsageList);
- PKIX_DECREF(state->subjAltNameList);
-
-cleanup:
-
- PKIX_RETURN(TARGETCERTCHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_TargetCertCheckerState_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_TARGETCERTCHECKERSTATE_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_TargetCertCheckerState_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(TARGETCERTCHECKERSTATE,
- "pkix_TargetCertCheckerState_RegisterSelf");
-
- entry.description = "TargetCertCheckerState";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(pkix_TargetCertCheckerState);
- entry.destructor = pkix_TargetCertCheckerState_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_TARGETCERTCHECKERSTATE_TYPE] = entry;
-
- PKIX_RETURN(TARGETCERTCHECKERSTATE);
-}
-
-/*
- * FUNCTION: pkix_TargetCertCheckerState_Create
- * DESCRIPTION:
- *
- * Creates a new TargetCertCheckerState using the CertSelector pointed to
- * by "certSelector" and the number of certs represented by "certsRemaining"
- * and stores it at "pState".
- *
- * PARAMETERS:
- * "certSelector"
- * Address of CertSelector representing the criteria against which the
- * final certificate in a chain is to be matched. Must be non-NULL.
- * "certsRemaining"
- * Number of certificates remaining in the chain.
- * "pState"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a TargetCertCheckerState Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_TargetCertCheckerState_Create(
- PKIX_CertSelector *certSelector,
- PKIX_UInt32 certsRemaining,
- pkix_TargetCertCheckerState **pState,
- void *plContext)
-{
- pkix_TargetCertCheckerState *state = NULL;
- PKIX_ComCertSelParams *certSelectorParams = NULL;
- PKIX_List *pathToNameList = NULL;
- PKIX_List *extKeyUsageList = NULL;
- PKIX_List *subjAltNameList = NULL;
- PKIX_PL_OID *extKeyUsageOID = NULL;
- PKIX_PL_OID *subjAltNameOID = NULL;
- PKIX_Boolean subjAltNameMatchAll = PKIX_TRUE;
-
- PKIX_ENTER(TARGETCERTCHECKERSTATE,
- "pkix_TargetCertCheckerState_Create");
- PKIX_NULLCHECK_ONE(pState);
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_EXTENDEDKEYUSAGE_OID,
- &extKeyUsageOID,
- plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_OID_Create
- (PKIX_CERTSUBJALTNAME_OID,
- &subjAltNameOID,
- plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_TARGETCERTCHECKERSTATE_TYPE,
- sizeof (pkix_TargetCertCheckerState),
- (PKIX_PL_Object **)&state,
- plContext),
- PKIX_COULDNOTCREATETARGETCERTCHECKERSTATEOBJECT);
-
- /* initialize fields */
-
- if (certSelector != NULL) {
-
- PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
- (certSelector, &certSelectorParams, plContext),
- PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMFAILED);
-
- if (certSelectorParams != NULL) {
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames
- (certSelectorParams,
- &pathToNameList,
- plContext),
- PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
- (certSelectorParams,
- &extKeyUsageList,
- plContext),
- PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames
- (certSelectorParams,
- &subjAltNameList,
- plContext),
- PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames
- (certSelectorParams,
- &subjAltNameMatchAll,
- plContext),
- PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
- }
- }
-
- state->certsRemaining = certsRemaining;
- state->subjAltNameMatchAll = subjAltNameMatchAll;
-
- PKIX_INCREF(certSelector);
- state->certSelector = certSelector;
-
- state->pathToNameList = pathToNameList;
- pathToNameList = NULL;
-
- state->extKeyUsageList = extKeyUsageList;
- extKeyUsageList = NULL;
-
- state->subjAltNameList = subjAltNameList;
- subjAltNameList = NULL;
-
- state->extKeyUsageOID = extKeyUsageOID;
- extKeyUsageOID = NULL;
-
- state->subjAltNameOID = subjAltNameOID;
- subjAltNameOID = NULL;
-
- *pState = state;
- state = NULL;
-
-cleanup:
-
- PKIX_DECREF(extKeyUsageOID);
- PKIX_DECREF(subjAltNameOID);
- PKIX_DECREF(pathToNameList);
- PKIX_DECREF(extKeyUsageList);
- PKIX_DECREF(subjAltNameList);
- PKIX_DECREF(state);
-
- PKIX_DECREF(certSelectorParams);
-
- PKIX_RETURN(TARGETCERTCHECKERSTATE);
-
-}
-
-/* --Private-TargetCertChecker-Functions------------------------------- */
-
-/*
- * FUNCTION: pkix_TargetCertChecker_Check
- * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
- */
-PKIX_Error *
-pkix_TargetCertChecker_Check(
- PKIX_CertChainChecker *checker,
- PKIX_PL_Cert *cert,
- PKIX_List *unresolvedCriticalExtensions,
- void **pNBIOContext,
- void *plContext)
-{
- pkix_TargetCertCheckerState *state = NULL;
- PKIX_CertSelector_MatchCallback certSelectorMatch = NULL;
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
- PKIX_List *certSubjAltNames = NULL;
- PKIX_List *certExtKeyUsageList = NULL;
- PKIX_PL_GeneralName *name = NULL;
- PKIX_PL_X500Name *certSubjectName = NULL;
- PKIX_Boolean checkPassed = PKIX_FALSE;
- PKIX_UInt32 numItems, i;
- PKIX_UInt32 matchCount = 0;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_TargetCertChecker_Check");
- PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
-
- *pNBIOContext = NULL; /* we never block on pending I/O */
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
- (checker, (PKIX_PL_Object **)&state, plContext),
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
-
- (state->certsRemaining)--;
-
- if (state->pathToNameList != NULL) {
-
- PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
- (cert, &nameConstraints, plContext),
- PKIX_CERTGETNAMECONSTRAINTSFAILED);
-
- /*
- * XXX We should either make the following call a public one
- * so it is legal to call from the portability layer or we
- * should try to create pathToNameList as CertNameConstraints
- * then call the existing check function.
- */
- PKIX_CHECK(PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
- (state->pathToNameList,
- nameConstraints,
- &checkPassed,
- plContext),
- PKIX_CERTNAMECONSTRAINTSCHECKNAMEINNAMESPACEFAILED);
-
- if (checkPassed != PKIX_TRUE) {
- PKIX_ERROR(PKIX_VALIDATIONFAILEDPATHTONAMECHECKFAILED);
- }
-
- }
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
- (cert, &certSubjAltNames, plContext),
- PKIX_CERTGETSUBJALTNAMESFAILED);
-
- if (state->subjAltNameList != NULL && certSubjAltNames != NULL) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (state->subjAltNameList, &numItems, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (state->subjAltNameList,
- i,
- (PKIX_PL_Object **) &name,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_List_Contains
- (certSubjAltNames,
- (PKIX_PL_Object *) name,
- &checkPassed,
- plContext),
- PKIX_LISTCONTAINSFAILED);
-
- PKIX_DECREF(name);
-
- if (checkPassed == PKIX_TRUE) {
-
- if (state->subjAltNameMatchAll == PKIX_FALSE) {
- matchCount = numItems;
- break;
- } else {
- /* else continue checking next */
- matchCount++;
- }
-
- }
- }
-
- if (matchCount != numItems) {
- PKIX_ERROR(PKIX_SUBJALTNAMECHECKFAILED);
-
- }
- }
-
- if (state->certsRemaining == 0) {
-
- if (state->certSelector != NULL) {
- PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
- (state->certSelector,
- &certSelectorMatch,
- plContext),
- PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
-
- PKIX_CHECK(certSelectorMatch
- (state->certSelector,
- cert,
- plContext),
- PKIX_CERTSELECTORMATCHFAILED);
- } else {
- /* Check at least cert/key usages if target cert selector
- * is not set. */
- PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert,
- PKIX_FALSE /* is chain cert*/,
- plContext),
- PKIX_CERTVERIFYCERTTYPEFAILED);
- }
- /*
- * There are two Extended Key Usage Checkings
- * available :
- * 1) here at the targetcertchecker where we
- * verify the Extended Key Usage OIDs application
- * specifies via ComCertSelParams are included
- * in Cert's Extended Key Usage OID's. Note,
- * this is an OID to OID comparison and only last
- * Cert is checked.
- * 2) at user defined ekuchecker where checking
- * is applied to all Certs on the chain and
- * the NSS Extended Key Usage algorithm is
- * used. In order to invoke this checking, not
- * only does the ComCertSelparams needs to be
- * set, the EKU initialize call is required to
- * activate the checking.
- *
- * XXX We use the same ComCertSelParams Set/Get
- * functions to set the parameters for both cases.
- * We may want to separate them in the future.
- */
-
- PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
- (cert, &certExtKeyUsageList, plContext),
- PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
-
-
- if (state->extKeyUsageList != NULL &&
- certExtKeyUsageList != NULL) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (state->extKeyUsageList, &numItems, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (state->extKeyUsageList,
- i,
- (PKIX_PL_Object **) &name,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_List_Contains
- (certExtKeyUsageList,
- (PKIX_PL_Object *) name,
- &checkPassed,
- plContext),
- PKIX_LISTCONTAINSFAILED);
-
- PKIX_DECREF(name);
-
- if (checkPassed != PKIX_TRUE) {
- PKIX_ERROR
- (PKIX_EXTENDEDKEYUSAGECHECKINGFAILED);
-
- }
- }
- }
- } else {
- /* Check key usage and cert type based on certificate usage. */
- PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, PKIX_TRUE,
- plContext),
- PKIX_CERTVERIFYCERTTYPEFAILED);
- }
-
- /* Remove Critical Extension OID from list */
- if (unresolvedCriticalExtensions != NULL) {
-
- PKIX_CHECK(pkix_List_Remove
- (unresolvedCriticalExtensions,
- (PKIX_PL_Object *) state->extKeyUsageOID,
- plContext),
- PKIX_LISTREMOVEFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubject
- (cert, &certSubjectName, plContext),
- PKIX_CERTGETSUBJECTFAILED);
-
- if (certSubjAltNames != NULL) {
- PKIX_CHECK(pkix_List_Remove
- (unresolvedCriticalExtensions,
- (PKIX_PL_Object *) state->subjAltNameOID,
- plContext),
- PKIX_LISTREMOVEFAILED);
- }
-
- }
-
-cleanup:
-
- PKIX_DECREF(name);
- PKIX_DECREF(nameConstraints);
- PKIX_DECREF(certSubjAltNames);
- PKIX_DECREF(certExtKeyUsageList);
- PKIX_DECREF(certSubjectName);
- PKIX_DECREF(state);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-
-}
-
-/*
- * FUNCTION: pkix_TargetCertChecker_Initialize
- * DESCRIPTION:
- *
- * Creates a new CertChainChecker and stores it at "pChecker", where it will
- * used by pkix_TargetCertChecker_Check to check that the final certificate
- * of a chain meets the criteria of the CertSelector pointed to by
- * "certSelector". The number of certs remaining in the chain, represented by
- * "certsRemaining" is used to initialize the checker's state.
- *
- * PARAMETERS:
- * "certSelector"
- * Address of CertSelector representing the criteria against which the
- * final certificate in a chain is to be matched. May be NULL.
- * "certsRemaining"
- * Number of certificates remaining in the chain.
- * "pChecker"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertChainChecker Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_TargetCertChecker_Initialize(
- PKIX_CertSelector *certSelector,
- PKIX_UInt32 certsRemaining,
- PKIX_CertChainChecker **pChecker,
- void *plContext)
-{
- pkix_TargetCertCheckerState *state = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "pkix_TargetCertChecker_Initialize");
- PKIX_NULLCHECK_ONE(pChecker);
-
- PKIX_CHECK(pkix_TargetCertCheckerState_Create
- (certSelector, certsRemaining, &state, plContext),
- PKIX_TARGETCERTCHECKERSTATECREATEFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_Create
- (pkix_TargetCertChecker_Check,
- PKIX_FALSE,
- PKIX_FALSE,
- NULL,
- (PKIX_PL_Object *)state,
- pChecker,
- plContext),
- PKIX_CERTCHAINCHECKERCREATEFAILED);
-
-cleanup:
-
- PKIX_DECREF(state);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
diff --git a/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.h b/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.h
deleted file mode 100755
index 4592d10a9..000000000
--- a/security/nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_targetcertchecker.h
- *
- * Header file for validate target cert function
- *
- */
-
-#ifndef _PKIX_TARGETCERTCHECKER_H
-#define _PKIX_TARGETCERTCHECKER_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct pkix_TargetCertCheckerState pkix_TargetCertCheckerState;
-
-struct pkix_TargetCertCheckerState {
- PKIX_CertSelector *certSelector;
- PKIX_List *pathToNameList;
- PKIX_List *extKeyUsageList; /* List of PKIX_PL_OID */
- PKIX_List *subjAltNameList;
- PKIX_Boolean subjAltNameMatchAll;
- PKIX_UInt32 certsRemaining;
- PKIX_PL_OID *extKeyUsageOID;
- PKIX_PL_OID *subjAltNameOID;
-};
-
-PKIX_Error *
-pkix_TargetCertChecker_Initialize(
- PKIX_CertSelector *certSelector,
- PKIX_UInt32 certsRemaining,
- PKIX_CertChainChecker **pChecker,
- void *plContext);
-
-PKIX_Error *
-pkix_TargetCertCheckerState_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_TARGETCERTCHECKER_H */
diff --git a/security/nss/lib/libpkix/pkix/config.mk b/security/nss/lib/libpkix/pkix/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix/crlsel/Makefile b/security/nss/lib/libpkix/pkix/crlsel/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix/crlsel/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix/crlsel/config.mk b/security/nss/lib/libpkix/pkix/crlsel/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix/crlsel/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix/crlsel/manifest.mn b/security/nss/lib/libpkix/pkix/crlsel/manifest.mn
deleted file mode 100755
index 6086f0f9a..000000000
--- a/security/nss/lib/libpkix/pkix/crlsel/manifest.mn
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_comcrlselparams.h \
- pkix_crlselector.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_crlselector.c \
- pkix_comcrlselparams.c \
- $(NULL)
-
-LIBRARY_NAME = pkixcrlsel
-
diff --git a/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c b/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c
deleted file mode 100755
index 90380c5b2..000000000
--- a/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c
+++ /dev/null
@@ -1,826 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_comcrlselparams.c
- *
- * ComCRLSelParams Function Definitions
- *
- */
-
-#include "pkix_comcrlselparams.h"
-
-/* --ComCRLSelParams-Private-Functions------------------------------------ */
-
-/*
- * FUNCTION: pkix_ComCrlSelParams_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ComCRLSelParams_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ComCRLSelParams *params = NULL;
-
- PKIX_ENTER(COMCRLSELPARAMS, "pkix_ComCRLSelParams_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_COMCRLSELPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTCOMCRLSELPARAMS);
-
- params = (PKIX_ComCRLSelParams *)object;
-
- PKIX_DECREF(params->issuerNames);
- PKIX_DECREF(params->cert);
- PKIX_DECREF(params->date);
- PKIX_DECREF(params->maxCRLNumber);
- PKIX_DECREF(params->minCRLNumber);
- PKIX_DECREF(params->crldpList);
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ComCRLSelParams_ToString_Helper
- * DESCRIPTION:
- *
- * Helper function that creates a string representation of ComCRLSelParams
- * pointed to by "crlParams" and stores the result at "pString".
- *
- * PARAMETERS
- * "crlParams"
- * Address of ComCRLSelParams whose string representation is desired.
- * Must be non-NULL.
- * "pString"
- * Address of object pointer's destination. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLEntry Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_ComCRLSelParams_ToString_Helper(
- PKIX_ComCRLSelParams *crlParams,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *crlIssuerNamesString = NULL;
- PKIX_PL_String *crlDateString = NULL;
- PKIX_PL_String *crlMaxCRLNumberString = NULL;
- PKIX_PL_String *crlMinCRLNumberString = NULL;
- PKIX_PL_String *crlCertString = NULL;
- PKIX_PL_String *crlParamsString = NULL;
- char *asciiFormat = NULL;
- PKIX_PL_String *formatString = NULL;
-
- PKIX_ENTER(COMCRLSELPARAMS, "pkix_ComCRLSelParams_ToString_Helper");
- PKIX_NULLCHECK_TWO(crlParams, pString);
-
- asciiFormat =
- "\n\t[\n"
- "\tIssuerNames: %s\n"
- "\tDate: %s\n"
- "\tmaxCRLNumber: %s\n"
- "\tminCRLNumber: %s\n"
- "\tCertificate: %s\n"
- "\t]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_TOSTRING
- (crlParams->issuerNames, &crlIssuerNamesString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- PKIX_TOSTRING(crlParams->date, &crlDateString, plContext,
- PKIX_DATETOSTRINGFAILED);
-
- PKIX_TOSTRING
- (crlParams->maxCRLNumber, &crlMaxCRLNumberString, plContext,
- PKIX_BIGINTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (crlParams->minCRLNumber, &crlMinCRLNumberString, plContext,
- PKIX_BIGINTTOSTRINGFAILED);
-
- PKIX_TOSTRING(crlParams->cert, &crlCertString, plContext,
- PKIX_CERTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&crlParamsString,
- plContext,
- formatString,
- crlIssuerNamesString,
- crlDateString,
- crlMaxCRLNumberString,
- crlMinCRLNumberString,
- crlCertString),
- PKIX_SPRINTFFAILED);
-
- *pString = crlParamsString;
-
-cleanup:
-
- PKIX_DECREF(crlIssuerNamesString);
- PKIX_DECREF(crlDateString);
- PKIX_DECREF(crlMaxCRLNumberString);
- PKIX_DECREF(crlMinCRLNumberString);
- PKIX_DECREF(crlCertString);
- PKIX_DECREF(formatString);
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ComCRLSelParams_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ComCRLSelParams_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *crlParamsString = NULL;
- PKIX_ComCRLSelParams *crlParams = NULL;
-
- PKIX_ENTER(COMCRLSELPARAMS, "pkix_ComCRLSelParams_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_COMCRLSELPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTCOMCRLSELPARAMS);
-
- crlParams = (PKIX_ComCRLSelParams *) object;
-
- PKIX_CHECK(pkix_ComCRLSelParams_ToString_Helper
- (crlParams, &crlParamsString, plContext),
- PKIX_COMCRLSELPARAMSTOSTRINGHELPERFAILED);
-
- *pString = crlParamsString;
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ComCRLSelParams_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ComCRLSelParams_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_ComCRLSelParams *crlParams = NULL;
- PKIX_UInt32 namesHash = 0;
- PKIX_UInt32 certHash = 0;
- PKIX_UInt32 dateHash = 0;
- PKIX_UInt32 maxCRLNumberHash = 0;
- PKIX_UInt32 minCRLNumberHash = 0;
- PKIX_UInt32 hash = 0;
-
- PKIX_ENTER(COMCRLSELPARAMS, "pkix_ComCRLSelParams_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_COMCRLSELPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTCOMCRLSELPARAMS);
-
- crlParams = (PKIX_ComCRLSelParams *)object;
-
- PKIX_HASHCODE(crlParams->issuerNames, &namesHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(crlParams->cert, &certHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(crlParams->date, &dateHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(crlParams->maxCRLNumber, &maxCRLNumberHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(crlParams->minCRLNumber, &minCRLNumberHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
-
- hash = (((namesHash << 3) + certHash) << 3) + dateHash;
- hash = (hash << 3) + maxCRLNumberHash + minCRLNumberHash;
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ComCRLSelParams_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ComCRLSelParams_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_ComCRLSelParams *firstCrlParams = NULL;
- PKIX_ComCRLSelParams *secondCrlParams = NULL;
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult = PKIX_FALSE;
-
- PKIX_ENTER(COMCRLSELPARAMS, "pkix_ComCRLSelParams_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a ComCRLSelParams */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_COMCRLSELPARAMS_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCOMCRLSELPARAMS);
-
- firstCrlParams = (PKIX_ComCRLSelParams *)firstObject;
- secondCrlParams = (PKIX_ComCRLSelParams *)secondObject;
-
- /*
- * Since we know firstObject is a ComCRLSelParams, if both references
- * are identical, they must be equal
- */
- if (firstCrlParams == secondCrlParams){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondComCRLSelParams isn't a ComCRLSelParams, we don't
- * throw an error. We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- ((PKIX_PL_Object *)secondCrlParams, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- if (secondType != PKIX_COMCRLSELPARAMS_TYPE) {
- goto cleanup;
- }
-
- /* Compare Issuer Names */
- PKIX_EQUALS
- (firstCrlParams->issuerNames,
- secondCrlParams->issuerNames,
- &cmpResult,
- plContext,
- PKIX_LISTEQUALSFAILED);
-
- if (cmpResult != PKIX_TRUE) {
- goto cleanup;
- }
-
- /* Compare Date */
- PKIX_EQUALS
- (firstCrlParams->date,
- secondCrlParams->date,
- &cmpResult,
- plContext,
- PKIX_DATEEQUALSFAILED);
-
- if (cmpResult != PKIX_TRUE) {
- goto cleanup;
- }
-
- /* Compare Max CRL Number */
- PKIX_EQUALS
- (firstCrlParams->maxCRLNumber,
- secondCrlParams->maxCRLNumber,
- &cmpResult,
- plContext,
- PKIX_BIGINTEQUALSFAILED);
-
- if (cmpResult != PKIX_TRUE) {
- goto cleanup;
- }
-
- /* Compare Min CRL Number */
- PKIX_EQUALS
- (firstCrlParams->minCRLNumber,
- secondCrlParams->minCRLNumber,
- &cmpResult,
- plContext,
- PKIX_BIGINTEQUALSFAILED);
-
- if (cmpResult != PKIX_TRUE) {
- goto cleanup;
- }
-
- /* Compare Cert */
- PKIX_EQUALS
- (firstCrlParams->cert,
- secondCrlParams->cert,
- &cmpResult,
- plContext,
- PKIX_CERTEQUALSFAILED);
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ComCRLSelParams_Duplicate
- * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ComCRLSelParams_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_ComCRLSelParams *old;
- PKIX_ComCRLSelParams *new = NULL;
-
- PKIX_ENTER(COMCRLSELPARAMS, "pkix_ComCRLSelParams_Duplicate");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_COMCRLSELPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTCOMCRLSELPARAMS);
-
- old = (PKIX_ComCRLSelParams *)object;
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_COMCRLSELPARAMS_TYPE,
- (PKIX_UInt32)(sizeof (PKIX_ComCRLSelParams)),
- (PKIX_PL_Object **)&new,
- plContext),
- PKIX_OBJECTALLOCFAILED);
-
- PKIX_DUPLICATE(old->cert, &new->cert, plContext,
- PKIX_OBJECTDUPLICATECERTFAILED);
-
- PKIX_DUPLICATE(old->crldpList, &new->crldpList, plContext,
- PKIX_OBJECTDUPLICATECERTFAILED);
-
- PKIX_DUPLICATE(old->issuerNames, &new->issuerNames, plContext,
- PKIX_OBJECTDUPLICATEISSUERNAMESFAILED);
-
- PKIX_DUPLICATE(old->date, &new->date, plContext,
- PKIX_OBJECTDUPLICATEDATEFAILED);
-
- PKIX_DUPLICATE(old->maxCRLNumber, &new->maxCRLNumber, plContext,
- PKIX_OBJECTDUPLICATEMAXCRLNUMBERFAILED);
-
- PKIX_DUPLICATE(old->minCRLNumber, &new->minCRLNumber, plContext,
- PKIX_OBJECTDUPLICATEMINCRLNUMBERFAILED);
-
- *pNewObject = (PKIX_PL_Object *)new;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(new);
- }
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ComCrlSelParams_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_COMCRLSELPARAMS_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_ComCRLSelParams_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(COMCRLSELPARAMS, "pkix_ComCRLSelParams_RegisterSelf");
-
- entry.description = "ComCRLSelParams";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_ComCRLSelParams);
- entry.destructor = pkix_ComCRLSelParams_Destroy;
- entry.equalsFunction = pkix_ComCRLSelParams_Equals;
- entry.hashcodeFunction = pkix_ComCRLSelParams_Hashcode;
- entry.toStringFunction = pkix_ComCRLSelParams_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_ComCRLSelParams_Duplicate;
-
- systemClasses[PKIX_COMCRLSELPARAMS_TYPE] = entry;
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/* --ComCRLSelParams-Public-Functions------------------------------------- */
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_Create (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_Create(
- PKIX_ComCRLSelParams **pParams,
- void *plContext)
-{
- PKIX_ComCRLSelParams *params = NULL;
-
- PKIX_ENTER(COMCRLSELPARAMS, "PKIX_ComCRLSelParams_Create");
- PKIX_NULLCHECK_ONE(pParams);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_COMCRLSELPARAMS_TYPE,
- sizeof (PKIX_ComCRLSelParams),
- (PKIX_PL_Object **)&params,
- plContext),
- PKIX_COULDNOTCREATECOMMONCRLSELECTORPARAMSOBJECT);
-
- /* initialize fields */
- params->issuerNames = NULL;
- params->cert = NULL;
- params->crldpList = NULL;
- params->date = NULL;
- params->nistPolicyEnabled = PKIX_TRUE;
- params->maxCRLNumber = NULL;
- params->minCRLNumber = NULL;
-
- *pParams = params;
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetIssuerNames (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetIssuerNames(
- PKIX_ComCRLSelParams *params,
- PKIX_List **pIssuerNames,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS, "PKIX_ComCRLSelParams_GetIssuerNames");
- PKIX_NULLCHECK_TWO(params, pIssuerNames);
-
- PKIX_INCREF(params->issuerNames);
-
- *pIssuerNames = params->issuerNames;
-
-cleanup:
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetIssuerNames (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetIssuerNames(
- PKIX_ComCRLSelParams *params,
- PKIX_List *names,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS, "PKIX_ComCRLSelParams_SetIssuerNames");
- PKIX_NULLCHECK_ONE(params); /* allows null for names from spec */
-
- PKIX_DECREF(params->issuerNames);
-
- PKIX_INCREF(names); /* if NULL, allows to reset for no action */
-
- params->issuerNames = names;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_AddIssuerName (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_AddIssuerName(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_X500Name *name,
- void *plContext)
-{
- PKIX_List *list = NULL;
-
- PKIX_ENTER(COMCRLSELPARAMS, "PKIX_ComCRLSelParams_AddIssuerName");
- PKIX_NULLCHECK_ONE(params);
-
- if (name != NULL) {
-
- if (params->issuerNames == NULL) {
-
- PKIX_CHECK(PKIX_List_Create(&list, plContext),
- PKIX_LISTCREATEFAILED);
- params->issuerNames = list;
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (params->issuerNames, (PKIX_PL_Object *)name, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- }
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetCertificateChecking
- * (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetCertificateChecking(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_Cert **pCert,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_GetCertificateChecking");
- PKIX_NULLCHECK_TWO(params, pCert);
-
- PKIX_INCREF(params->cert);
-
- *pCert = params->cert;
-
-cleanup:
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetCertificateChecking
- * (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetCertificateChecking(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_Cert *cert,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_SetCertificateChecking");
- PKIX_NULLCHECK_ONE(params); /* allows cert to be NULL from spec */
-
- PKIX_DECREF(params->cert);
-
- PKIX_INCREF(cert);
-
- params->cert = cert;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetDateAndTime (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetDateAndTime(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_Date **pDate,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_GetDateAndTime");
- PKIX_NULLCHECK_TWO(params, pDate);
-
- PKIX_INCREF(params->date);
-
- *pDate = params->date;
-
-cleanup:
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetDateAndTime (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetDateAndTime(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_Date *date,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_SetDateAndTime");
- PKIX_NULLCHECK_ONE(params); /* allows date to be NULL from spec */
-
- PKIX_DECREF (params->date);
-
- PKIX_INCREF(date);
-
- params->date = date;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetDateAndTime (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetNISTPolicyEnabled(
- PKIX_ComCRLSelParams *params,
- PKIX_Boolean *pEnabled,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_GetNISTPolicyEnabled");
- PKIX_NULLCHECK_TWO(params, pEnabled);
-
- *pEnabled = params->nistPolicyEnabled;
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetDateAndTime (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetNISTPolicyEnabled(
- PKIX_ComCRLSelParams *params,
- PKIX_Boolean enabled,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_SetNISTPolicyEnabled");
- PKIX_NULLCHECK_ONE(params); /* allows date to be NULL from spec */
-
- params->nistPolicyEnabled = enabled;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetMaxCRLNumber
- * (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetMaxCRLNumber(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_BigInt **pMaxCRLNumber,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_GetMaxCRLNumber");
- PKIX_NULLCHECK_TWO(params, pMaxCRLNumber);
-
- PKIX_INCREF(params->maxCRLNumber);
-
- *pMaxCRLNumber = params->maxCRLNumber;
-
-cleanup:
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetMaxCRLNumber
- * (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetMaxCRLNumber(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_BigInt *maxCRLNumber,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_SetMaxCRLNumber");
- PKIX_NULLCHECK_ONE(params); /* maxCRLNumber can be NULL - from spec */
-
- PKIX_DECREF(params->maxCRLNumber);
-
- PKIX_INCREF(maxCRLNumber);
-
- params->maxCRLNumber = maxCRLNumber;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_GetMinCRLNumber
- * (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_GetMinCRLNumber(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_BigInt **pMinCRLNumber,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_GetMinCRLNumber");
- PKIX_NULLCHECK_TWO(params, pMinCRLNumber);
-
- PKIX_INCREF(params->minCRLNumber);
-
- *pMinCRLNumber = params->minCRLNumber;
-
-cleanup:
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ComCRLSelParams_SetMinCRLNumber
- * (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_ComCRLSelParams_SetMinCRLNumber(
- PKIX_ComCRLSelParams *params,
- PKIX_PL_BigInt *minCRLNumber,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS,
- "PKIX_ComCRLSelParams_SetMinCRLNumber");
- PKIX_NULLCHECK_ONE(params); /* minCRLNumber can be NULL - from spec */
-
- PKIX_DECREF(params->minCRLNumber);
-
- PKIX_INCREF(minCRLNumber);
-
- params->minCRLNumber = minCRLNumber;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
-
-
-PKIX_Error*
-PKIX_ComCRLSelParams_SetCrlDp(
- PKIX_ComCRLSelParams *params,
- PKIX_List *crldpList,
- void *plContext)
-{
- PKIX_ENTER(COMCRLSELPARAMS, "PKIX_ComCRLSelParams_SetCrlDp");
- PKIX_NULLCHECK_ONE(params); /* minCRLNumber can be NULL - from spec */
-
- PKIX_INCREF(crldpList);
- params->crldpList = crldpList;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-cleanup:
-
- PKIX_RETURN(COMCRLSELPARAMS);
-}
diff --git a/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h b/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h
deleted file mode 100755
index 08351375d..000000000
--- a/security/nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_comcrlselparams.h
- *
- * ComCrlSelParams Object Type Definition
- *
- */
-
-#ifndef _PKIX_COMCRLSELPARAMS_H
-#define _PKIX_COMCRLSELPARAMS_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_ComCRLSelParamsStruct {
- PKIX_List *issuerNames; /* list of PKIX_PL_X500Name */
- PKIX_PL_Cert *cert; /* certificate being checked */
- PKIX_List *crldpList;
- PKIX_PL_Date *date;
- PKIX_Boolean nistPolicyEnabled;
- PKIX_PL_BigInt *maxCRLNumber;
- PKIX_PL_BigInt *minCRLNumber;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_ComCRLSelParams_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_COMCRLSELPARAMS_H */
diff --git a/security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c b/security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c
deleted file mode 100755
index 9967af9b8..000000000
--- a/security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c
+++ /dev/null
@@ -1,870 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_crlselector.c
- *
- * CRLSelector Function Definitions
- *
- */
-
-#include "pkix_crlselector.h"
-
-/* --CRLSelector Private-Functions-------------------------------------- */
-
-/*
- * FUNCTION: pkix_CRLSelector_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CRLSelector_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_CRLSelector *selector = NULL;
-
- PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRLSELECTOR_TYPE, plContext),
- PKIX_OBJECTNOTCRLSELECTOR);
-
- selector = (PKIX_CRLSelector *)object;
-
- selector->matchCallback = NULL;
-
- PKIX_DECREF(selector->params);
- PKIX_DECREF(selector->context);
-
-cleanup:
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CRLSelector_ToString_Helper
- *
- * DESCRIPTION:
- * Helper function that creates a string representation of CRLSelector
- * pointed to by "crlParams" and stores its address in the object pointed to
- * by "pString".
- *
- * PARAMETERS
- * "list"
- * Address of CRLSelector whose string representation is desired.
- * Must be non-NULL.
- * "pString"
- * Address of object pointer's destination. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CRLSelector_ToString_Helper(
- PKIX_CRLSelector *crlSelector,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *crlSelectorString = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *crlParamsString = NULL;
- PKIX_PL_String *crlContextString = NULL;
- char *asciiFormat = NULL;
-
- PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_ToString_Helper");
- PKIX_NULLCHECK_TWO(crlSelector, pString);
- PKIX_NULLCHECK_ONE(crlSelector->params);
-
- asciiFormat =
- "\n\t[\n"
- "\tMatchCallback: 0x%x\n"
- "\tParams: %s\n"
- "\tContext: %s\n"
- "\t]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- /* Params */
- PKIX_TOSTRING
- ((PKIX_PL_Object *)crlSelector->params,
- &crlParamsString,
- plContext,
- PKIX_COMCRLSELPARAMSTOSTRINGFAILED);
-
- /* Context */
- PKIX_TOSTRING(crlSelector->context, &crlContextString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&crlSelectorString,
- plContext,
- formatString,
- crlSelector->matchCallback,
- crlParamsString,
- crlContextString),
- PKIX_SPRINTFFAILED);
-
- *pString = crlSelectorString;
-
-cleanup:
-
- PKIX_DECREF(crlParamsString);
- PKIX_DECREF(crlContextString);
- PKIX_DECREF(formatString);
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CRLSelector_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CRLSelector_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *crlSelectorString = NULL;
- PKIX_CRLSelector *crlSelector = NULL;
-
- PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRLSELECTOR_TYPE, plContext),
- PKIX_OBJECTNOTCRLSELECTOR);
-
- crlSelector = (PKIX_CRLSelector *) object;
-
- PKIX_CHECK(pkix_CRLSelector_ToString_Helper
- (crlSelector, &crlSelectorString, plContext),
- PKIX_CRLSELECTORTOSTRINGHELPERFAILED);
-
- *pString = crlSelectorString;
-
-cleanup:
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CRLSelector_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CRLSelector_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_UInt32 paramsHash = 0;
- PKIX_UInt32 contextHash = 0;
- PKIX_UInt32 hash = 0;
-
- PKIX_CRLSelector *crlSelector = NULL;
-
- PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRLSELECTOR_TYPE, plContext),
- PKIX_OBJECTNOTCRLSELECTOR);
-
- crlSelector = (PKIX_CRLSelector *)object;
-
- PKIX_HASHCODE(crlSelector->params, &paramsHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(crlSelector->context, &contextHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- hash = 31 * ((PKIX_UInt32)crlSelector->matchCallback +
- (contextHash << 3)) + paramsHash;
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CRLSelector_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CRLSelector_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_CRLSelector *firstCrlSelector = NULL;
- PKIX_CRLSelector *secondCrlSelector = NULL;
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult = PKIX_FALSE;
-
- PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a CRLSelector */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_CRLSELECTOR_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCRLSELECTOR);
-
- firstCrlSelector = (PKIX_CRLSelector *)firstObject;
- secondCrlSelector = (PKIX_CRLSelector *)secondObject;
-
- /*
- * Since we know firstObject is a CRLSelector, if both references are
- * identical, they must be equal
- */
- if (firstCrlSelector == secondCrlSelector){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondCRLSelector isn't a CRLSelector, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- ((PKIX_PL_Object *)secondCrlSelector,
- &secondType,
- plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- if (secondType != PKIX_CRLSELECTOR_TYPE) {
- goto cleanup;
- }
-
- /* Compare MatchCallback address */
- cmpResult = (firstCrlSelector->matchCallback ==
- secondCrlSelector->matchCallback);
-
- if (cmpResult == PKIX_FALSE) {
- goto cleanup;
- }
-
- /* Compare Common CRL Selector Params */
- PKIX_EQUALS
- (firstCrlSelector->params,
- secondCrlSelector->params,
- &cmpResult,
- plContext,
- PKIX_COMCRLSELPARAMSEQUALSFAILED);
-
-
- if (cmpResult == PKIX_FALSE) {
- goto cleanup;
- }
-
- /* Compare Context */
- PKIX_EQUALS
- (firstCrlSelector->context,
- secondCrlSelector->context,
- &cmpResult,
- plContext,
- PKIX_COMCRLSELPARAMSEQUALSFAILED);
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CRLSelector_Duplicate
- * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CRLSelector_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_CRLSelector *old;
- PKIX_CRLSelector *new = NULL;
-
- PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_Duplicate");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CRLSELECTOR_TYPE, plContext),
- PKIX_OBJECTNOTCRLSELECTOR);
-
- old = (PKIX_CRLSelector *)object;
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CRLSELECTOR_TYPE,
- (PKIX_UInt32)(sizeof (PKIX_CRLSelector)),
- (PKIX_PL_Object **)&new,
- plContext),
- PKIX_CREATECRLSELECTORDUPLICATEOBJECTFAILED);
-
- new->matchCallback = old->matchCallback;
-
- PKIX_DUPLICATE(old->params, &new->params, plContext,
- PKIX_OBJECTDUPLICATEPARAMSFAILED);
-
- PKIX_DUPLICATE(old->context, &new->context, plContext,
- PKIX_OBJECTDUPLICATECONTEXTFAILED);
-
- *pNewObject = (PKIX_PL_Object *)new;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(new);
- }
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CRLSelector_DefaultMatch
- *
- * DESCRIPTION:
- * This function compares the parameter values (Issuer, date, and CRL number)
- * set in the ComCRLSelParams of the CRLSelector pointed to by "selector" with
- * the corresponding values in the CRL pointed to by "crl". When all the
- * criteria set in the parameter values match the values in "crl", PKIX_TRUE is
- * stored at "pMatch". If the CRL does not match the CRLSelector's criteria,
- * PKIX_FALSE is stored at "pMatch".
- *
- * PARAMETERS
- * "selector"
- * Address of CRLSelector which is verified for a match
- * Must be non-NULL.
- * "crl"
- * Address of the CRL object to be verified. Must be non-NULL.
- * "pMatch"
- * Address at which Boolean result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CRLSelector_DefaultMatch(
- PKIX_CRLSelector *selector,
- PKIX_PL_CRL *crl,
- PKIX_Boolean *pMatch,
- void *plContext)
-{
- PKIX_ComCRLSelParams *params = NULL;
- PKIX_PL_X500Name *crlIssuerName = NULL;
- PKIX_PL_X500Name *issuerName = NULL;
- PKIX_List *selIssuerNames = NULL;
- PKIX_PL_Date *selDate = NULL;
- PKIX_Boolean result = PKIX_TRUE;
- PKIX_UInt32 numIssuers = 0;
- PKIX_UInt32 i;
- PKIX_PL_BigInt *minCRLNumber = NULL;
- PKIX_PL_BigInt *maxCRLNumber = NULL;
- PKIX_PL_BigInt *crlNumber = NULL;
- PKIX_Boolean nistPolicyEnabled = PKIX_FALSE;
-
- PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_DefaultMatch");
- PKIX_NULLCHECK_TWO(selector, crl);
-
- *pMatch = PKIX_TRUE;
- params = selector->params;
-
- /* No matching parameter provided, just a match */
- if (params == NULL) {
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_ComCRLSelParams_GetIssuerNames
- (params, &selIssuerNames, plContext),
- PKIX_COMCRLSELPARAMSGETISSUERNAMESFAILED);
-
- /* Check for Issuers */
- if (selIssuerNames != NULL){
-
- result = PKIX_FALSE;
-
- PKIX_CHECK(PKIX_PL_CRL_GetIssuer
- (crl, &crlIssuerName, plContext),
- PKIX_CRLGETISSUERFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength
- (selIssuerNames, &numIssuers, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numIssuers; i++){
-
- PKIX_CHECK(PKIX_List_GetItem
- (selIssuerNames,
- i,
- (PKIX_PL_Object **)&issuerName,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_X500Name_Match
- (crlIssuerName,
- issuerName,
- &result,
- plContext),
- PKIX_X500NAMEMATCHFAILED);
-
- PKIX_DECREF(issuerName);
-
- if (result == PKIX_TRUE) {
- break;
- }
- }
-
- if (result == PKIX_FALSE) {
- PKIX_CRLSELECTOR_DEBUG("Issuer Match Failed\N");
- *pMatch = PKIX_FALSE;
- goto cleanup;
- }
-
- }
-
- PKIX_CHECK(PKIX_ComCRLSelParams_GetDateAndTime
- (params, &selDate, plContext),
- PKIX_COMCRLSELPARAMSGETDATEANDTIMEFAILED);
-
- /* Check for Date */
- if (selDate != NULL){
-
- PKIX_CHECK(PKIX_ComCRLSelParams_GetNISTPolicyEnabled
- (params, &nistPolicyEnabled, plContext),
- PKIX_COMCRLSELPARAMSGETNISTPOLICYENABLEDFAILED);
-
- /* check crl dates only for if NIST policies enforced */
- if (nistPolicyEnabled) {
- result = PKIX_FALSE;
-
- PKIX_CHECK(PKIX_PL_CRL_VerifyUpdateTime
- (crl, selDate, &result, plContext),
- PKIX_CRLVERIFYUPDATETIMEFAILED);
-
- if (result == PKIX_FALSE) {
- *pMatch = PKIX_FALSE;
- goto cleanup;
- }
- }
-
- }
-
- /* Check for CRL number in range */
- PKIX_CHECK(PKIX_PL_CRL_GetCRLNumber(crl, &crlNumber, plContext),
- PKIX_CRLGETCRLNUMBERFAILED);
-
- if (crlNumber != NULL) {
- result = PKIX_FALSE;
-
- PKIX_CHECK(PKIX_ComCRLSelParams_GetMinCRLNumber
- (params, &minCRLNumber, plContext),
- PKIX_COMCRLSELPARAMSGETMINCRLNUMBERFAILED);
-
- if (minCRLNumber != NULL) {
-
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)minCRLNumber,
- (PKIX_PL_Object *)crlNumber,
- &result,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
-
- if (result == 1) {
- PKIX_CRLSELECTOR_DEBUG
- ("CRL MinNumber Range Match Failed\n");
- *pMatch = PKIX_FALSE;
- goto cleanup;
- }
- }
-
- PKIX_CHECK(PKIX_ComCRLSelParams_GetMaxCRLNumber
- (params, &maxCRLNumber, plContext),
- PKIX_COMCRLSELPARAMSGETMAXCRLNUMBERFAILED);
-
- if (maxCRLNumber != NULL) {
-
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)crlNumber,
- (PKIX_PL_Object *)maxCRLNumber,
- &result,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
-
- if (result == 1) {
- PKIX_CRLSELECTOR_DEBUG
- (PKIX_CRLMAXNUMBERRANGEMATCHFAILED);
- *pMatch = PKIX_FALSE;
- goto cleanup;
- }
- }
- }
-
-cleanup:
-
- PKIX_DECREF(selIssuerNames);
- PKIX_DECREF(selDate);
- PKIX_DECREF(crlIssuerName);
- PKIX_DECREF(issuerName);
- PKIX_DECREF(crlNumber);
- PKIX_DECREF(minCRLNumber);
- PKIX_DECREF(maxCRLNumber);
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CRLSelector_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CRLSELECTOR_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_CRLSelector_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CRLSELECTOR, "pkix_CRLSelector_RegisterSelf");
-
- entry.description = "CRLSelector";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_CRLSelector);
- entry.destructor = pkix_CRLSelector_Destroy;
- entry.equalsFunction = pkix_CRLSelector_Equals;
- entry.hashcodeFunction = pkix_CRLSelector_Hashcode;
- entry.toStringFunction = pkix_CRLSelector_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_CRLSelector_Duplicate;
-
- systemClasses[PKIX_CRLSELECTOR_TYPE] = entry;
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/* --CRLSelector-Public-Functions---------------------------------------- */
-PKIX_Error *
-pkix_CRLSelector_Create(
- PKIX_CRLSelector_MatchCallback callback,
- PKIX_PL_Object *crlSelectorContext,
- PKIX_CRLSelector **pSelector,
- void *plContext)
-{
- PKIX_CRLSelector *selector = NULL;
-
- PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_Create");
- PKIX_NULLCHECK_ONE(pSelector);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CRLSELECTOR_TYPE,
- sizeof (PKIX_CRLSelector),
- (PKIX_PL_Object **)&selector,
- plContext),
- PKIX_COULDNOTCREATECRLSELECTOROBJECT);
-
- /*
- * if user specified a particular match callback, we use that one.
- * otherwise, we use the default match provided.
- */
-
- if (callback != NULL){
- selector->matchCallback = callback;
- } else {
- selector->matchCallback = pkix_CRLSelector_DefaultMatch;
- }
-
- /* initialize other fields */
- selector->params = NULL;
-
- PKIX_INCREF(crlSelectorContext);
- selector->context = crlSelectorContext;
-
- *pSelector = selector;
- selector = NULL;
-
-cleanup:
-
- PKIX_DECREF(selector);
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: PKIX_CRLSelector_Create (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_CRLSelector_Create(
- PKIX_PL_Cert *issuer,
- PKIX_List *crldpList,
- PKIX_PL_Date *date,
- PKIX_CRLSelector **pCrlSelector,
- void *plContext)
-{
- PKIX_PL_X500Name *issuerName = NULL;
- PKIX_PL_Date *nowDate = NULL;
- PKIX_ComCRLSelParams *comCrlSelParams = NULL;
- PKIX_CRLSelector *crlSelector = NULL;
-
- PKIX_ENTER(CERTCHAINCHECKER, "PKIX_CrlSelector_Create");
- PKIX_NULLCHECK_ONE(issuer);
-
- PKIX_CHECK(
- PKIX_PL_Cert_GetSubject(issuer, &issuerName, plContext),
- PKIX_CERTGETISSUERFAILED);
-
- if (date != NULL) {
- PKIX_INCREF(date);
- nowDate = date;
- } else {
- PKIX_CHECK(
- PKIX_PL_Date_Create_UTCTime(NULL, &nowDate, plContext),
- PKIX_DATECREATEUTCTIMEFAILED);
- }
-
- PKIX_CHECK(
- PKIX_ComCRLSelParams_Create(&comCrlSelParams, plContext),
- PKIX_COMCRLSELPARAMSCREATEFAILED);
-
- PKIX_CHECK(
- PKIX_ComCRLSelParams_AddIssuerName(comCrlSelParams, issuerName,
- plContext),
- PKIX_COMCRLSELPARAMSADDISSUERNAMEFAILED);
-
- PKIX_CHECK(
- PKIX_ComCRLSelParams_SetCrlDp(comCrlSelParams, crldpList,
- plContext),
- PKIX_COMCRLSELPARAMSSETCERTFAILED);
-
- PKIX_CHECK(
- PKIX_ComCRLSelParams_SetDateAndTime(comCrlSelParams, nowDate,
- plContext),
- PKIX_COMCRLSELPARAMSSETDATEANDTIMEFAILED);
-
- PKIX_CHECK(
- pkix_CRLSelector_Create(NULL, NULL, &crlSelector, plContext),
- PKIX_CRLSELECTORCREATEFAILED);
-
- PKIX_CHECK(
- PKIX_CRLSelector_SetCommonCRLSelectorParams(crlSelector,
- comCrlSelParams,
- plContext),
- PKIX_CRLSELECTORSETCOMMONCRLSELECTORPARAMSFAILED);
-
- *pCrlSelector = crlSelector;
- crlSelector = NULL;
-
-cleanup:
-
- PKIX_DECREF(issuerName);
- PKIX_DECREF(nowDate);
- PKIX_DECREF(comCrlSelParams);
- PKIX_DECREF(crlSelector);
-
- PKIX_RETURN(CERTCHAINCHECKER);
-}
-
-/*
- * FUNCTION: PKIX_CRLSelector_GetMatchCallback (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_CRLSelector_GetMatchCallback(
- PKIX_CRLSelector *selector,
- PKIX_CRLSelector_MatchCallback *pCallback,
- void *plContext)
-{
- PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_GetMatchCallback");
- PKIX_NULLCHECK_TWO(selector, pCallback);
-
- *pCallback = selector->matchCallback;
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-
-/*
- * FUNCTION: PKIX_CRLSelector_GetCRLSelectorContext
- * (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_CRLSelector_GetCRLSelectorContext(
- PKIX_CRLSelector *selector,
- void **pCrlSelectorContext,
- void *plContext)
-{
- PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_GetCRLSelectorContext");
- PKIX_NULLCHECK_TWO(selector, pCrlSelectorContext);
-
- PKIX_INCREF(selector->context);
-
- *pCrlSelectorContext = selector->context;
-
-cleanup:
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: PKIX_CRLSelector_GetCommonCRLSelectorParams
- * (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_CRLSelector_GetCommonCRLSelectorParams(
- PKIX_CRLSelector *selector,
- PKIX_ComCRLSelParams **pParams,
- void *plContext)
-{
- PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_GetCommonCRLSelectorParams");
- PKIX_NULLCHECK_TWO(selector, pParams);
-
- PKIX_INCREF(selector->params);
-
- *pParams = selector->params;
-
-cleanup:
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: PKIX_CRLSelector_SetCommonCRLSelectorParams
- * (see comments in pkix_crlsel.h)
- */
-PKIX_Error *
-PKIX_CRLSelector_SetCommonCRLSelectorParams(
- PKIX_CRLSelector *selector,
- PKIX_ComCRLSelParams *params,
- void *plContext)
-{
- PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_SetCommonCRLSelectorParams");
- PKIX_NULLCHECK_TWO(selector, params);
-
- PKIX_DECREF(selector->params);
-
- PKIX_INCREF(params);
- selector->params = params;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)selector, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(CRLSELECTOR);
-}
-
-/*
- * FUNCTION: pkix_CRLSelector_Select
- * DESCRIPTION:
- *
- * This function applies the selector pointed to by "selector" to each CRL,
- * in turn, in the List pointed to by "before", and creates a List containing
- * all the CRLs that matched, or passed the selection process, storing that
- * List at "pAfter". If no CRLs match, an empty List is stored at "pAfter".
- *
- * The List returned in "pAfter" is immutable.
- *
- * PARAMETERS:
- * "selector"
- * Address of CRLSelelector to be applied to the List. Must be non-NULL.
- * "before"
- * Address of List that is to be filtered. Must be non-NULL.
- * "pAfter"
- * Address at which resulting List, possibly empty, is stored. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLSelector Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CRLSelector_Select(
- PKIX_CRLSelector *selector,
- PKIX_List *before,
- PKIX_List **pAfter,
- void *plContext)
-{
- PKIX_Boolean match = PKIX_FALSE;
- PKIX_UInt32 numBefore = 0;
- PKIX_UInt32 i = 0;
- PKIX_List *filtered = NULL;
- PKIX_PL_CRL *candidate = NULL;
-
- PKIX_ENTER(CRLSELECTOR, "PKIX_CRLSelector_Select");
- PKIX_NULLCHECK_THREE(selector, before, pAfter);
-
- PKIX_CHECK(PKIX_List_Create(&filtered, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(before, &numBefore, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numBefore; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (before, i, (PKIX_PL_Object **)&candidate, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK_ONLY_FATAL(selector->matchCallback
- (selector, candidate, &match, plContext),
- PKIX_CRLSELECTORMATCHCALLBACKFAILED);
-
- if (!(PKIX_ERROR_RECEIVED) && match == PKIX_TRUE) {
-
- PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem
- (filtered,
- (PKIX_PL_Object *)candidate,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
-
- pkixTempErrorReceived = PKIX_FALSE;
- PKIX_DECREF(candidate);
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable(filtered, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- /* Don't throw away the list if one CRL was bad! */
- pkixTempErrorReceived = PKIX_FALSE;
-
- *pAfter = filtered;
- filtered = NULL;
-
-cleanup:
-
- PKIX_DECREF(filtered);
- PKIX_DECREF(candidate);
-
- PKIX_RETURN(CRLSELECTOR);
-
-}
diff --git a/security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.h b/security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.h
deleted file mode 100755
index 4f44cc768..000000000
--- a/security/nss/lib/libpkix/pkix/crlsel/pkix_crlselector.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_crlselector.h
- *
- * CrlSelector Object Type Definition
- *
- */
-
-#ifndef _PKIX_CRLSELECTOR_H
-#define _PKIX_CRLSELECTOR_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_CRLSelectorStruct {
- PKIX_CRLSelector_MatchCallback matchCallback;
- PKIX_ComCRLSelParams *params;
- PKIX_PL_Object *context;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_CRLSelector_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_CRLSelector_Select(
- PKIX_CRLSelector *selector,
- PKIX_List *before,
- PKIX_List **pAfter,
- void *plContext);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_CRLSELECTOR_H */
diff --git a/security/nss/lib/libpkix/pkix/manifest.mn b/security/nss/lib/libpkix/pkix/manifest.mn
deleted file mode 100755
index 24e639c38..000000000
--- a/security/nss/lib/libpkix/pkix/manifest.mn
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../..
-DEPTH = ../../../..
-
-#
-DIRS = certsel crlsel checker params results store top util \
- $(NULL)
-
diff --git a/security/nss/lib/libpkix/pkix/params/Makefile b/security/nss/lib/libpkix/pkix/params/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix/params/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix/params/config.mk b/security/nss/lib/libpkix/pkix/params/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix/params/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix/params/manifest.mn b/security/nss/lib/libpkix/pkix/params/manifest.mn
deleted file mode 100755
index ff40ffac6..000000000
--- a/security/nss/lib/libpkix/pkix/params/manifest.mn
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_procparams.h \
- pkix_trustanchor.h \
- pkix_valparams.h \
- pkix_resourcelimits.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_trustanchor.c \
- pkix_procparams.c \
- pkix_valparams.c \
- pkix_resourcelimits.c \
- $(NULL)
-
-LIBRARY_NAME = pkixparams
-
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_buildparams.c b/security/nss/lib/libpkix/pkix/params/pkix_buildparams.c
deleted file mode 100755
index de5d203a6..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_buildparams.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_buildparams.c
- *
- * Build Params Object Functions
- *
- */
-
-#include "pkix_buildparams.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_BuildParams_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_BuildParams_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_BuildParams *params = NULL;
-
- PKIX_ENTER(BUILDPARAMS, "pkix_BuildParams_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a build params object */
- PKIX_CHECK(pkix_CheckType(object, PKIX_BUILDPARAMS_TYPE, plContext),
- "Object is not a build params object");
-
- params = (PKIX_BuildParams *)object;
-
- PKIX_DECREF(params->procParams);
-
-cleanup:
-
- PKIX_RETURN(BUILDPARAMS);
-}
-
-/*
- * FUNCTION: pkix_BuildParams_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_BuildParams_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
- PKIX_BuildParams *firstBuildParams = NULL;
- PKIX_BuildParams *secondBuildParams = NULL;
-
- PKIX_ENTER(BUILDPARAMS, "pkix_BuildParams_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- PKIX_CHECK(pkix_CheckType(first, PKIX_BUILDPARAMS_TYPE, plContext),
- "First Argument is not a BuildParams object");
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- *pResult = PKIX_FALSE;
-
- if (secondType != PKIX_BUILDPARAMS_TYPE) goto cleanup;
-
- firstBuildParams = (PKIX_BuildParams *)first;
- secondBuildParams = (PKIX_BuildParams *)second;
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstBuildParams->procParams,
- (PKIX_PL_Object *)secondBuildParams->procParams,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(BUILDPARAMS);
-}
-
-/*
- * FUNCTION: pkix_BuildParams_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_BuildParams_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_BuildParams *buildParams = NULL;
- PKIX_UInt32 hash = 0;
- PKIX_UInt32 procParamsHash = 0;
-
- PKIX_ENTER(BUILDPARAMS, "pkix_BuildParams_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BUILDPARAMS_TYPE, plContext),
- "Object is not a processingParams object");
-
- buildParams = (PKIX_BuildParams*)object;
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)buildParams->procParams,
- &procParamsHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- hash = 31 * procParamsHash;
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(BUILDPARAMS);
-}
-
-/*
- * FUNCTION: pkix_BuildParams_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_BuildParams_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_BuildParams *buildParams = NULL;
- char *asciiFormat = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *buildParamsString = NULL;
-
- PKIX_PL_String *procParamsString = NULL;
-
- PKIX_ENTER(BUILDPARAMS, "pkix_BuildParams_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BUILDPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTBUILDPARAMS);
-
- asciiFormat =
- "[\n"
- "\tProcessing Params: \n"
- "\t********BEGIN PROCESSING PARAMS********\n"
- "\t\t%s\n"
- "\t********END PROCESSING PARAMS********\n"
- "]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- buildParams = (PKIX_BuildParams*)object;
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)buildParams->procParams,
- &procParamsString,
- plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&buildParamsString,
- plContext,
- formatString,
- procParamsString),
- PKIX_SPRINTFFAILED);
-
- *pString = buildParamsString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(procParamsString);
-
- PKIX_RETURN(BUILDPARAMS);
-}
-
-/*
- * FUNCTION: pkix_BuildParams_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_BUILDPARAMS_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_BuildParams_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(BUILDPARAMS, "pkix_BuildParams_RegisterSelf");
-
- entry.description = "BuildParams";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_BuildParams);
- entry.destructor = pkix_BuildParams_Destroy;
- entry.equalsFunction = pkix_BuildParams_Equals;
- entry.hashcodeFunction = pkix_BuildParams_Hashcode;
- entry.toStringFunction = pkix_BuildParams_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_BUILDPARAMS_TYPE] = entry;
-
- PKIX_RETURN(BUILDPARAMS);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_BuildParams_Create (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_BuildParams_Create(
- PKIX_ProcessingParams *procParams,
- PKIX_BuildParams **pParams,
- void *plContext)
-{
- PKIX_BuildParams *params = NULL;
-
- PKIX_ENTER(BUILDPARAMS, "PKIX_BuildParams_Create");
- PKIX_NULLCHECK_TWO(procParams, pParams);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_BUILDPARAMS_TYPE,
- sizeof (PKIX_BuildParams),
- (PKIX_PL_Object **)&params,
- plContext),
- PKIX_COULDNOTCREATEBUILDPARAMSOBJECT);
-
- /* initialize fields */
- PKIX_INCREF(procParams);
- params->procParams = procParams;
-
- *pParams = params;
- params = NULL;
-
-cleanup:
-
- PKIX_DECREF(params);
-
- PKIX_RETURN(BUILDPARAMS);
-
-}
-
-/*
- * FUNCTION: PKIX_BuildParams_GetProcessingParams
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_BuildParams_GetProcessingParams(
- PKIX_BuildParams *buildParams,
- PKIX_ProcessingParams **pProcParams,
- void *plContext)
-{
- PKIX_ENTER(BUILDPARAMS, "PKIX_BuildParams_GetProcessingParams");
- PKIX_NULLCHECK_TWO(buildParams, pProcParams);
-
- PKIX_INCREF(buildParams->procParams);
-
- *pProcParams = buildParams->procParams;
-
-cleanup:
- PKIX_RETURN(BUILDPARAMS);
-}
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_buildparams.h b/security/nss/lib/libpkix/pkix/params/pkix_buildparams.h
deleted file mode 100755
index 4bf130b3f..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_buildparams.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_buildparams.h
- *
- * BuildParams Object Type Definition
- *
- */
-
-#ifndef _PKIX_BUILDPARAMS_H
-#define _PKIX_BUILDPARAMS_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_BuildParamsStruct {
- PKIX_ProcessingParams *procParams; /* Never NULL */
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_BuildParams_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_BUILDPARAMS_H */
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_procparams.c b/security/nss/lib/libpkix/pkix/params/pkix_procparams.c
deleted file mode 100755
index 260b0074c..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_procparams.c
+++ /dev/null
@@ -1,1417 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_procparams.c
- *
- * ProcessingParams Object Functions
- *
- */
-
-#include "pkix_procparams.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_ProcessingParams_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ProcessingParams_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ProcessingParams *params = NULL;
-
- PKIX_ENTER(PROCESSINGPARAMS, "pkix_ProcessingParams_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a processing params object */
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_PROCESSINGPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTPROCESSINGPARAMS);
-
- params = (PKIX_ProcessingParams *)object;
-
- PKIX_DECREF(params->trustAnchors);
- PKIX_DECREF(params->hintCerts);
- PKIX_DECREF(params->constraints);
- PKIX_DECREF(params->date);
- PKIX_DECREF(params->initialPolicies);
- PKIX_DECREF(params->certChainCheckers);
- PKIX_DECREF(params->revChecker);
- PKIX_DECREF(params->certStores);
- PKIX_DECREF(params->resourceLimits);
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ProcessingParams_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ProcessingParams_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
- PKIX_ProcessingParams *firstProcParams = NULL;
- PKIX_ProcessingParams *secondProcParams = NULL;
-
- PKIX_ENTER(PROCESSINGPARAMS, "pkix_ProcessingParams_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- PKIX_CHECK(pkix_CheckType(first, PKIX_PROCESSINGPARAMS_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTPROCESSINGPARAMS);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- *pResult = PKIX_FALSE;
-
- if (secondType != PKIX_PROCESSINGPARAMS_TYPE) goto cleanup;
-
- firstProcParams = (PKIX_ProcessingParams *)first;
- secondProcParams = (PKIX_ProcessingParams *)second;
-
- /* Do the simplest tests first */
- if ((firstProcParams->qualifiersRejected) !=
- (secondProcParams->qualifiersRejected)) {
- goto cleanup;
- }
-
- if (firstProcParams->isCrlRevocationCheckingEnabled !=
- secondProcParams->isCrlRevocationCheckingEnabled) {
- goto cleanup;
- }
- if (firstProcParams->isCrlRevocationCheckingEnabledWithNISTPolicy !=
- secondProcParams->isCrlRevocationCheckingEnabledWithNISTPolicy) {
- goto cleanup;
- }
-
- /* trustAnchors can never be NULL */
-
- PKIX_EQUALS
- (firstProcParams->trustAnchors,
- secondProcParams->trustAnchors,
- &cmpResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- PKIX_EQUALS
- (firstProcParams->hintCerts,
- secondProcParams->hintCerts,
- &cmpResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- PKIX_EQUALS
- (firstProcParams->date,
- secondProcParams->date,
- &cmpResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- PKIX_EQUALS
- (firstProcParams->constraints,
- secondProcParams->constraints,
- &cmpResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- PKIX_EQUALS
- (firstProcParams->initialPolicies,
- secondProcParams->initialPolicies,
- &cmpResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- /* There is no Equals function for CertChainCheckers */
-
- PKIX_EQUALS
- ((PKIX_PL_Object *)firstProcParams->certStores,
- (PKIX_PL_Object *)secondProcParams->certStores,
- &cmpResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- PKIX_EQUALS
- (firstProcParams->resourceLimits,
- secondProcParams->resourceLimits,
- &cmpResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (cmpResult == PKIX_FALSE) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ProcessingParams_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ProcessingParams_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_UInt32 hash = 0;
- PKIX_UInt32 anchorsHash = 0;
- PKIX_UInt32 hintCertsHash = 0;
- PKIX_UInt32 dateHash = 0;
- PKIX_UInt32 constraintsHash = 0;
- PKIX_UInt32 initialHash = 0;
- PKIX_UInt32 rejectedHash = 0;
- PKIX_UInt32 certChainCheckersHash = 0;
- PKIX_UInt32 revCheckerHash = 0;
- PKIX_UInt32 certStoresHash = 0;
- PKIX_UInt32 resourceLimitsHash = 0;
-
- PKIX_ENTER(PROCESSINGPARAMS, "pkix_ProcessingParams_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_PROCESSINGPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTPROCESSINGPARAMS);
-
- procParams = (PKIX_ProcessingParams*)object;
-
- PKIX_HASHCODE(procParams->trustAnchors, &anchorsHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(procParams->hintCerts, &hintCertsHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(procParams->date, &dateHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(procParams->constraints, &constraintsHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(procParams->initialPolicies, &initialHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- rejectedHash = procParams->qualifiersRejected;
-
- /* There is no Hash function for CertChainCheckers */
-
- PKIX_HASHCODE(procParams->certStores, &certStoresHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(procParams->resourceLimits,
- &resourceLimitsHash,
- plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- hash = (31 * ((31 * anchorsHash) + hintCertsHash + dateHash)) +
- constraintsHash + initialHash + rejectedHash;
-
- hash += ((((certStoresHash + resourceLimitsHash) << 7) +
- certChainCheckersHash + revCheckerHash +
- procParams->isCrlRevocationCheckingEnabled +
- procParams->isCrlRevocationCheckingEnabledWithNISTPolicy) << 7);
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ProcessingParams_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ProcessingParams_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_ProcessingParams *procParams = NULL;
- char *asciiFormat = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *procParamsString = NULL;
- PKIX_PL_String *anchorsString = NULL;
- PKIX_PL_String *dateString = NULL;
- PKIX_PL_String *constraintsString = NULL;
- PKIX_PL_String *InitialPoliciesString = NULL;
- PKIX_PL_String *qualsRejectedString = NULL;
- PKIX_List *certStores = NULL;
- PKIX_PL_String *certStoresString = NULL;
- PKIX_PL_String *resourceLimitsString = NULL;
-
- PKIX_ENTER(PROCESSINGPARAMS, "pkix_ProcessingParams_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_PROCESSINGPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTPROCESSINGPARAMS);
-
- asciiFormat =
- "[\n"
- "\tTrust Anchors: \n"
- "\t********BEGIN LIST OF TRUST ANCHORS********\n"
- "\t\t%s\n"
- "\t********END LIST OF TRUST ANCHORS********\n"
- "\tDate: \t\t%s\n"
- "\tTarget Constraints: %s\n"
- "\tInitial Policies: %s\n"
- "\tQualifiers Rejected: %s\n"
- "\tCert Stores: %s\n"
- "\tResource Limits: %s\n"
- "\tCRL Checking Enabled: %d\n"
- "]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- procParams = (PKIX_ProcessingParams*)object;
-
- PKIX_TOSTRING(procParams->trustAnchors, &anchorsString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING(procParams->date, &dateString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING(procParams->constraints, &constraintsString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (procParams->initialPolicies, &InitialPoliciesString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- (procParams->qualifiersRejected)?"TRUE":"FALSE",
- 0,
- &qualsRejectedString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- /* There is no ToString function for CertChainCheckers */
-
- PKIX_CHECK(PKIX_ProcessingParams_GetCertStores
- (procParams, &certStores, plContext),
- PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
-
- PKIX_TOSTRING(certStores, &certStoresString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- PKIX_TOSTRING(procParams->resourceLimits,
- &resourceLimitsString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&procParamsString,
- plContext,
- formatString,
- anchorsString,
- dateString,
- constraintsString,
- InitialPoliciesString,
- qualsRejectedString,
- certStoresString,
- resourceLimitsString,
- procParams->isCrlRevocationCheckingEnabled,
- procParams->isCrlRevocationCheckingEnabledWithNISTPolicy),
- PKIX_SPRINTFFAILED);
-
- *pString = procParamsString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(anchorsString);
- PKIX_DECREF(dateString);
- PKIX_DECREF(constraintsString);
- PKIX_DECREF(InitialPoliciesString);
- PKIX_DECREF(qualsRejectedString);
- PKIX_DECREF(certStores);
- PKIX_DECREF(certStoresString);
- PKIX_DECREF(resourceLimitsString);
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ProcessingParams_Duplicate
- * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ProcessingParams_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_ProcessingParams *params = NULL;
- PKIX_ProcessingParams *paramsDuplicate = NULL;
-
- PKIX_ENTER(PROCESSINGPARAMS, "pkix_ProcessingParams_Duplicate");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_PROCESSINGPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTPROCESSINGPARAMS);
-
- params = (PKIX_ProcessingParams *)object;
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_PROCESSINGPARAMS_TYPE,
- sizeof (PKIX_ProcessingParams),
- (PKIX_PL_Object **)&paramsDuplicate,
- plContext),
- PKIX_PROCESSINGPARAMSCREATEFAILED);
-
- /* initialize fields */
- PKIX_DUPLICATE
- (params->trustAnchors,
- &(paramsDuplicate->trustAnchors),
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE
- (params->hintCerts, &(paramsDuplicate->hintCerts), plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE
- (params->constraints,
- &(paramsDuplicate->constraints),
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE
- (params->date, &(paramsDuplicate->date), plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE
- (params->initialPolicies,
- &(paramsDuplicate->initialPolicies),
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- paramsDuplicate->initialPolicyMappingInhibit =
- params->initialPolicyMappingInhibit;
- paramsDuplicate->initialAnyPolicyInhibit =
- params->initialAnyPolicyInhibit;
- paramsDuplicate->initialExplicitPolicy = params->initialExplicitPolicy;
- paramsDuplicate->qualifiersRejected = params->qualifiersRejected;
-
- PKIX_DUPLICATE
- (params->certChainCheckers,
- &(paramsDuplicate->certChainCheckers),
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE
- (params->revChecker,
- &(paramsDuplicate->revChecker),
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE
- (params->certStores, &(paramsDuplicate->certStores), plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_DUPLICATE
- (params->resourceLimits,
- &(paramsDuplicate->resourceLimits),
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- paramsDuplicate->isCrlRevocationCheckingEnabled =
- params->isCrlRevocationCheckingEnabled;
-
- paramsDuplicate->isCrlRevocationCheckingEnabledWithNISTPolicy =
- params->isCrlRevocationCheckingEnabledWithNISTPolicy;
-
- *pNewObject = (PKIX_PL_Object *)paramsDuplicate;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(paramsDuplicate);
- }
-
- PKIX_RETURN(PROCESSINGPARAMS);
-
-}
-
-/*
- * FUNCTION: pkix_ProcessingParams_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_PROCESSINGPARAMS_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_ProcessingParams_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(PROCESSINGPARAMS, "pkix_ProcessingParams_RegisterSelf");
-
- entry.description = "ProcessingParams";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_ProcessingParams);
- entry.destructor = pkix_ProcessingParams_Destroy;
- entry.equalsFunction = pkix_ProcessingParams_Equals;
- entry.hashcodeFunction = pkix_ProcessingParams_Hashcode;
- entry.toStringFunction = pkix_ProcessingParams_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_ProcessingParams_Duplicate;
-
- systemClasses[PKIX_PROCESSINGPARAMS_TYPE] = entry;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_ProcessingParams_Create (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_Create(
- PKIX_ProcessingParams **pParams,
- void *plContext)
-{
- PKIX_ProcessingParams *params = NULL;
-
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_Create");
- PKIX_NULLCHECK_ONE(pParams);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_PROCESSINGPARAMS_TYPE,
- sizeof (PKIX_ProcessingParams),
- (PKIX_PL_Object **)&params,
- plContext),
- PKIX_COULDNOTCREATEPROCESSINGPARAMSOBJECT);
-
- /* initialize fields */
- PKIX_CHECK(PKIX_List_Create(&params->trustAnchors, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_List_SetImmutable(params->trustAnchors, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- PKIX_CHECK(PKIX_PL_Date_Create_UTCTime
- (NULL, &params->date, plContext),
- PKIX_DATECREATEUTCTIMEFAILED);
-
- params->hintCerts = NULL;
- params->constraints = NULL;
- params->initialPolicies = NULL;
- params->initialPolicyMappingInhibit = PKIX_FALSE;
- params->initialAnyPolicyInhibit = PKIX_FALSE;
- params->initialExplicitPolicy = PKIX_FALSE;
- params->qualifiersRejected = PKIX_FALSE;
- params->certChainCheckers = NULL;
- params->revChecker = NULL;
- params->certStores = NULL;
- params->resourceLimits = NULL;
-
- params->isCrlRevocationCheckingEnabled = PKIX_TRUE;
-
- params->isCrlRevocationCheckingEnabledWithNISTPolicy = PKIX_TRUE;
-
- params->useAIAForCertFetching = PKIX_FALSE;
- params->qualifyTargetCert = PKIX_TRUE;
- params->useOnlyTrustAnchors = PKIX_TRUE;
-
- *pParams = params;
- params = NULL;
-
-cleanup:
-
- PKIX_DECREF(params);
-
- PKIX_RETURN(PROCESSINGPARAMS);
-
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetUseAIAForCertFetching
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetUseAIAForCertFetching(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pUseAIA, /* list of TrustAnchor */
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_GetUseAIAForCertFetching");
- PKIX_NULLCHECK_TWO(params, pUseAIA);
-
- *pUseAIA = params->useAIAForCertFetching;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetUseAIAForCertFetching
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetUseAIAForCertFetching(
- PKIX_ProcessingParams *params,
- PKIX_Boolean useAIA,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_SetUseAIAForCertFetching");
- PKIX_NULLCHECK_ONE(params);
-
- params->useAIAForCertFetching = useAIA;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetQualifyTargetCert
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetValidateTargetCert(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pQualifyTargetCert,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_GetValidateTargetCert");
- PKIX_NULLCHECK_TWO(params, pQualifyTargetCert);
-
- *pQualifyTargetCert = params->qualifyTargetCert;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetQualifyTargetCert
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetQualifyTargetCert(
- PKIX_ProcessingParams *params,
- PKIX_Boolean qualifyTargetCert,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetQualifyTargetCert");
- PKIX_NULLCHECK_ONE(params);
-
- params->qualifyTargetCert = qualifyTargetCert;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetTrustAnchors
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetTrustAnchors(
- PKIX_ProcessingParams *params,
- PKIX_List *anchors, /* list of TrustAnchor */
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_SetTrustAnchors");
- PKIX_NULLCHECK_TWO(params, anchors);
-
- PKIX_DECREF(params->trustAnchors);
-
- PKIX_INCREF(anchors);
- params->trustAnchors = anchors;
- PKIX_CHECK(PKIX_List_SetImmutable(params->trustAnchors, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
-cleanup:
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetTrustAnchors
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetTrustAnchors(
- PKIX_ProcessingParams *params,
- PKIX_List **pAnchors, /* list of TrustAnchor */
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_GetTrustAnchors");
- PKIX_NULLCHECK_TWO(params, pAnchors);
-
- PKIX_INCREF(params->trustAnchors);
-
- *pAnchors = params->trustAnchors;
-
-cleanup:
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/**
- * FUNCTION: PKIX_ProcessingParams_SetUseOnlyTrustAnchors
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetUseOnlyTrustAnchors(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pUseOnlyTrustAnchors,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetUseTrustAnchorsOnly");
- PKIX_NULLCHECK_TWO(params, pUseOnlyTrustAnchors);
-
- *pUseOnlyTrustAnchors = params->useOnlyTrustAnchors;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/**
- * FUNCTION: PKIX_ProcessingParams_SetUseOnlyTrustAnchors
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetUseOnlyTrustAnchors(
- PKIX_ProcessingParams *params,
- PKIX_Boolean useOnlyTrustAnchors,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetUseTrustAnchorsOnly");
- PKIX_NULLCHECK_ONE(params);
-
- params->useOnlyTrustAnchors = useOnlyTrustAnchors;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetDate (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetDate(
- PKIX_ProcessingParams *params,
- PKIX_PL_Date **pDate,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_GetDate");
- PKIX_NULLCHECK_TWO(params, pDate);
-
- PKIX_INCREF(params->date);
- *pDate = params->date;
-
-cleanup:
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetDate (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetDate(
- PKIX_ProcessingParams *params,
- PKIX_PL_Date *date,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_SetDate");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->date);
-
- PKIX_INCREF(date);
- params->date = date;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED && params) {
- PKIX_DECREF(params->date);
- }
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetTargetCertConstraints
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetTargetCertConstraints(
- PKIX_ProcessingParams *params,
- PKIX_CertSelector **pConstraints,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_GetTargetCertConstraints");
-
- PKIX_NULLCHECK_TWO(params, pConstraints);
-
- PKIX_INCREF(params->constraints);
- *pConstraints = params->constraints;
-
-cleanup:
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetTargetCertConstraints
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetTargetCertConstraints(
- PKIX_ProcessingParams *params,
- PKIX_CertSelector *constraints,
- void *plContext)
-{
-
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetTargetCertConstraints");
-
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->constraints);
-
- PKIX_INCREF(constraints);
- params->constraints = constraints;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
- if (PKIX_ERROR_RECEIVED && params) {
- PKIX_DECREF(params->constraints);
- }
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetInitialPolicies
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetInitialPolicies(
- PKIX_ProcessingParams *params,
- PKIX_List **pInitPolicies, /* list of PKIX_PL_OID */
- void *plContext)
-{
-
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_GetInitialPolicies");
-
- PKIX_NULLCHECK_TWO(params, pInitPolicies);
-
- if (params->initialPolicies == NULL) {
- PKIX_CHECK(PKIX_List_Create
- (&params->initialPolicies, plContext),
- PKIX_UNABLETOCREATELIST);
- PKIX_CHECK(PKIX_List_SetImmutable
- (params->initialPolicies, plContext),
- PKIX_UNABLETOMAKELISTIMMUTABLE);
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
- }
-
- PKIX_INCREF(params->initialPolicies);
- *pInitPolicies = params->initialPolicies;
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetInitialPolicies
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetInitialPolicies(
- PKIX_ProcessingParams *params,
- PKIX_List *initPolicies, /* list of PKIX_PL_OID */
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetInitialPolicies");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->initialPolicies);
-
- PKIX_INCREF(initPolicies);
- params->initialPolicies = initPolicies;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED && params) {
- PKIX_DECREF(params->initialPolicies);
- }
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetPolicyQualifiersRejected
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetPolicyQualifiersRejected(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pRejected,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_GetPolicyQualifiersRejected");
-
- PKIX_NULLCHECK_TWO(params, pRejected);
-
- *pRejected = params->qualifiersRejected;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetPolicyQualifiersRejected
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetPolicyQualifiersRejected(
- PKIX_ProcessingParams *params,
- PKIX_Boolean rejected,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetPolicyQualifiersRejected");
-
- PKIX_NULLCHECK_ONE(params);
-
- params->qualifiersRejected = rejected;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetCertChainCheckers
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetCertChainCheckers(
- PKIX_ProcessingParams *params,
- PKIX_List **pCheckers, /* list of PKIX_CertChainChecker */
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_GetCertChainCheckers");
- PKIX_NULLCHECK_TWO(params, pCheckers);
-
- PKIX_INCREF(params->certChainCheckers);
- *pCheckers = params->certChainCheckers;
-
-cleanup:
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetCertChainCheckers
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetCertChainCheckers(
- PKIX_ProcessingParams *params,
- PKIX_List *checkers, /* list of PKIX_CertChainChecker */
- void *plContext)
-{
-
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetCertChainCheckers");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->certChainCheckers);
-
- PKIX_INCREF(checkers);
- params->certChainCheckers = checkers;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED && params) {
- PKIX_DECREF(params->certChainCheckers);
- }
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_AddCertChainCheckers
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_AddCertChainChecker(
- PKIX_ProcessingParams *params,
- PKIX_CertChainChecker *checker,
- void *plContext)
-{
- PKIX_List *list = NULL;
-
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_AddCertChainChecker");
- PKIX_NULLCHECK_TWO(params, checker);
-
- if (params->certChainCheckers == NULL) {
-
- PKIX_CHECK(PKIX_List_Create(&list, plContext),
- PKIX_LISTCREATEFAILED);
-
- params->certChainCheckers = list;
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (params->certChainCheckers, (PKIX_PL_Object *)checker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- list = NULL;
-
-cleanup:
-
- if (list && params) {
- PKIX_DECREF(params->certChainCheckers);
- }
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetRevocationChecker
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetRevocationChecker(
- PKIX_ProcessingParams *params,
- PKIX_RevocationChecker **pChecker,
- void *plContext)
-{
-
- PKIX_ENTER
- (PROCESSINGPARAMS, "PKIX_ProcessingParams_GetRevocationCheckers");
- PKIX_NULLCHECK_TWO(params, pChecker);
-
- PKIX_INCREF(params->revChecker);
- *pChecker = params->revChecker;
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetRevocationChecker
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetRevocationChecker(
- PKIX_ProcessingParams *params,
- PKIX_RevocationChecker *checker,
- void *plContext)
-{
-
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_InitRevocationChecker");
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->revChecker);
- PKIX_INCREF(checker);
- params->revChecker = checker;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetCertStores
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetCertStores(
- PKIX_ProcessingParams *params,
- PKIX_List **pStores, /* list of PKIX_CertStore */
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_GetCertStores");
-
- PKIX_NULLCHECK_TWO(params, pStores);
-
- if (!params->certStores){
- PKIX_CHECK(PKIX_List_Create(&params->certStores, plContext),
- PKIX_UNABLETOCREATELIST);
- }
-
- PKIX_INCREF(params->certStores);
- *pStores = params->certStores;
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetCertStores
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetCertStores(
- PKIX_ProcessingParams *params,
- PKIX_List *stores, /* list of PKIX_CertStore */
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_SetCertStores");
-
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->certStores);
-
- PKIX_INCREF(stores);
- params->certStores = stores;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED && params) {
- PKIX_DECREF(params->certStores);
- }
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_AddCertStore
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_AddCertStore(
- PKIX_ProcessingParams *params,
- PKIX_CertStore *store,
- void *plContext)
-{
- PKIX_List *certStores = NULL;
-
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_AddCertStore");
- PKIX_NULLCHECK_TWO(params, store);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetCertStores
- (params, &certStores, plContext),
- PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (certStores, (PKIX_PL_Object *)store, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_DECREF(certStores);
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetResourceLimits
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetResourceLimits(
- PKIX_ProcessingParams *params,
- PKIX_ResourceLimits *resourceLimits,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetResourceLimits");
-
- PKIX_NULLCHECK_TWO(params, resourceLimits);
-
- PKIX_DECREF(params->resourceLimits);
- PKIX_INCREF(resourceLimits);
- params->resourceLimits = resourceLimits;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED && params) {
- PKIX_DECREF(params->resourceLimits);
- }
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetResourceLimits
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetResourceLimits(
- PKIX_ProcessingParams *params,
- PKIX_ResourceLimits **pResourceLimits,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_GetResourceLimits");
-
- PKIX_NULLCHECK_TWO(params, pResourceLimits);
-
- PKIX_INCREF(params->resourceLimits);
- *pResourceLimits = params->resourceLimits;
-
-cleanup:
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_IsAnyPolicyInhibited
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_IsAnyPolicyInhibited(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pInhibited,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_IsAnyPolicyInhibited");
-
- PKIX_NULLCHECK_TWO(params, pInhibited);
-
- *pInhibited = params->initialAnyPolicyInhibit;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetAnyPolicyInhibited
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetAnyPolicyInhibited(
- PKIX_ProcessingParams *params,
- PKIX_Boolean inhibited,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetAnyPolicyInhibited");
-
- PKIX_NULLCHECK_ONE(params);
-
- params->initialAnyPolicyInhibit = inhibited;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_IsExplicitPolicyRequired
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_IsExplicitPolicyRequired(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pRequired,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_IsExplicitPolicyRequired");
-
- PKIX_NULLCHECK_TWO(params, pRequired);
-
- *pRequired = params->initialExplicitPolicy;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetExplicitPolicyRequired
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetExplicitPolicyRequired(
- PKIX_ProcessingParams *params,
- PKIX_Boolean required,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetExplicitPolicyRequired");
-
- PKIX_NULLCHECK_ONE(params);
-
- params->initialExplicitPolicy = required;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_IsPolicyMappingInhibited
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_IsPolicyMappingInhibited(
- PKIX_ProcessingParams *params,
- PKIX_Boolean *pInhibited,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_IsPolicyMappingInhibited");
-
- PKIX_NULLCHECK_TWO(params, pInhibited);
-
- *pInhibited = params->initialPolicyMappingInhibit;
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetPolicyMappingInhibited
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetPolicyMappingInhibited(
- PKIX_ProcessingParams *params,
- PKIX_Boolean inhibited,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS,
- "PKIX_ProcessingParams_SetPolicyMappingInhibited");
-
- PKIX_NULLCHECK_ONE(params);
-
- params->initialPolicyMappingInhibit = inhibited;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)params, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_SetHintCerts
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_SetHintCerts(
- PKIX_ProcessingParams *params,
- PKIX_List *hintCerts,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_SetHintCerts");
-
- PKIX_NULLCHECK_ONE(params);
-
- PKIX_DECREF(params->hintCerts);
- PKIX_INCREF(hintCerts);
- params->hintCerts = hintCerts;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED && params) {
- PKIX_DECREF(params->hintCerts);
- }
-
- PKIX_RETURN(PROCESSINGPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ProcessingParams_GetHintCerts
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ProcessingParams_GetHintCerts(
- PKIX_ProcessingParams *params,
- PKIX_List **pHintCerts,
- void *plContext)
-{
- PKIX_ENTER(PROCESSINGPARAMS, "PKIX_ProcessingParams_GetHintCerts");
-
- PKIX_NULLCHECK_TWO(params, pHintCerts);
-
- PKIX_INCREF(params->hintCerts);
- *pHintCerts = params->hintCerts;
-
-cleanup:
- PKIX_RETURN(PROCESSINGPARAMS);
-}
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_procparams.h b/security/nss/lib/libpkix/pkix/params/pkix_procparams.h
deleted file mode 100755
index 599f5d498..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_procparams.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_procparams.h
- *
- * ProcessingParams Object Type Definition
- *
- */
-
-#ifndef _PKIX_PROCESSINGPARAMS_H
-#define _PKIX_PROCESSINGPARAMS_H
-
-#include "pkix_tools.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_ProcessingParamsStruct {
- PKIX_List *trustAnchors; /* Never NULL */
- PKIX_List *hintCerts; /* user-supplied partial chain, may be NULL */
- PKIX_CertSelector *constraints;
- PKIX_PL_Date *date;
- PKIX_List *initialPolicies; /* list of PKIX_PL_OID */
- PKIX_Boolean initialPolicyMappingInhibit;
- PKIX_Boolean initialAnyPolicyInhibit;
- PKIX_Boolean initialExplicitPolicy;
- PKIX_Boolean qualifiersRejected;
- PKIX_List *certChainCheckers;
- PKIX_List *certStores;
- PKIX_Boolean isCrlRevocationCheckingEnabled;
- PKIX_Boolean isCrlRevocationCheckingEnabledWithNISTPolicy;
- PKIX_RevocationChecker *revChecker;
- PKIX_ResourceLimits *resourceLimits;
- PKIX_Boolean useAIAForCertFetching;
- PKIX_Boolean qualifyTargetCert;
- PKIX_Boolean useOnlyTrustAnchors;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_ProcessingParams_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PROCESSINGPARAMS_H */
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_resourcelimits.c b/security/nss/lib/libpkix/pkix/params/pkix_resourcelimits.c
deleted file mode 100755
index de93e9d77..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_resourcelimits.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_resourcelimits.c
- *
- * Resourcelimits Params Object Functions
- *
- */
-
-#include "pkix_resourcelimits.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_ResourceLimits_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ResourceLimits_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ResourceLimits *rLimits = NULL;
-
- PKIX_ENTER(RESOURCELIMITS, "pkix_ResourceLimits_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a ResourceLimits object */
- PKIX_CHECK(pkix_CheckType(object, PKIX_RESOURCELIMITS_TYPE, plContext),
- PKIX_OBJECTNOTRESOURCELIMITS);
-
- rLimits = (PKIX_ResourceLimits *)object;
-
- rLimits->maxTime = 0;
- rLimits->maxFanout = 0;
- rLimits->maxDepth = 0;
- rLimits->maxCertsNumber = 0;
- rLimits->maxCrlsNumber = 0;
-
-cleanup:
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: pkix_ResourceLimits_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ResourceLimits_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
- PKIX_ResourceLimits *firstRLimits = NULL;
- PKIX_ResourceLimits *secondRLimits = NULL;
-
- PKIX_ENTER(RESOURCELIMITS, "pkix_ResourceLimits_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- PKIX_CHECK(pkix_CheckType(first, PKIX_RESOURCELIMITS_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTRESOURCELIMITS);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- *pResult = PKIX_FALSE;
-
- if (secondType != PKIX_RESOURCELIMITS_TYPE) goto cleanup;
-
- firstRLimits = (PKIX_ResourceLimits *)first;
- secondRLimits = (PKIX_ResourceLimits *)second;
-
- cmpResult = (firstRLimits->maxTime == secondRLimits->maxTime) &&
- (firstRLimits->maxFanout == secondRLimits->maxFanout) &&
- (firstRLimits->maxDepth == secondRLimits->maxDepth) &&
- (firstRLimits->maxCertsNumber ==
- secondRLimits->maxCertsNumber) &&
- (firstRLimits->maxCrlsNumber ==
- secondRLimits->maxCrlsNumber);
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: pkix_ResourceLimits_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ResourceLimits_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_ResourceLimits *rLimits = NULL;
- PKIX_UInt32 hash = 0;
-
- PKIX_ENTER(RESOURCELIMITS, "pkix_ResourceLimits_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_RESOURCELIMITS_TYPE, plContext),
- PKIX_OBJECTNOTRESOURCELIMITS);
-
- rLimits = (PKIX_ResourceLimits*)object;
-
- hash = 31 * rLimits->maxTime + (rLimits->maxFanout << 1) +
- (rLimits->maxDepth << 2) + (rLimits->maxCertsNumber << 3) +
- rLimits->maxCrlsNumber;
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: pkix_ResourceLimits_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ResourceLimits_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_ResourceLimits *rLimits = NULL;
- char *asciiFormat = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *rLimitsString = NULL;
-
- PKIX_ENTER(RESOURCELIMITS, "pkix_ResourceLimits_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_RESOURCELIMITS_TYPE, plContext),
- PKIX_OBJECTNOTRESOURCELIMITS);
-
- /* maxCertsNumber and maxCrlsNumber are not supported */
- asciiFormat =
- "[\n"
- "\tMaxTime: \t\t%d\n"
- "\tMaxFanout: \t\t%d\n"
- "\tMaxDepth: \t\t%d\n"
- "]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- rLimits = (PKIX_ResourceLimits*)object;
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&rLimitsString,
- plContext,
- formatString,
- rLimits->maxTime,
- rLimits->maxFanout,
- rLimits->maxDepth),
- PKIX_SPRINTFFAILED);
-
- *pString = rLimitsString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: pkix_ResourceLimits_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_RESOURCELIMITS_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_ResourceLimits_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(RESOURCELIMITS, "pkix_ResourceLimits_RegisterSelf");
-
- entry.description = "ResourceLimits";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_ResourceLimits);
- entry.destructor = pkix_ResourceLimits_Destroy;
- entry.equalsFunction = pkix_ResourceLimits_Equals;
- entry.hashcodeFunction = pkix_ResourceLimits_Hashcode;
- entry.toStringFunction = pkix_ResourceLimits_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_RESOURCELIMITS_TYPE] = entry;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_ResourceLimits_Create (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_Create(
- PKIX_ResourceLimits **pResourceLimits,
- void *plContext)
-{
- PKIX_ResourceLimits *rLimits = NULL;
-
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_Create");
- PKIX_NULLCHECK_ONE(pResourceLimits);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_RESOURCELIMITS_TYPE,
- sizeof (PKIX_ResourceLimits),
- (PKIX_PL_Object **)&rLimits,
- plContext),
- PKIX_COULDNOTCREATERESOURCELIMITOBJECT);
-
- /* initialize fields */
- rLimits->maxTime = 0;
- rLimits->maxFanout = 0;
- rLimits->maxDepth = 0;
- rLimits->maxCertsNumber = 0;
- rLimits->maxCrlsNumber = 0;
-
- *pResourceLimits = rLimits;
-
-cleanup:
-
- PKIX_RETURN(RESOURCELIMITS);
-
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxTime
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxTime(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 *pMaxTime,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_GetMaxTime");
- PKIX_NULLCHECK_TWO(rLimits, pMaxTime);
-
- *pMaxTime = rLimits->maxTime;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxTime
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxTime(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 maxTime,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_SetMaxTime");
- PKIX_NULLCHECK_ONE(rLimits);
-
- rLimits->maxTime = maxTime;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxFanout
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxFanout(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 *pMaxFanout,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_GetMaxFanout");
- PKIX_NULLCHECK_TWO(rLimits, pMaxFanout);
-
- *pMaxFanout = rLimits->maxFanout;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxFanout
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxFanout(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 maxFanout,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_SetMaxFanout");
- PKIX_NULLCHECK_ONE(rLimits);
-
- rLimits->maxFanout = maxFanout;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxDepth
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxDepth(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 *pMaxDepth,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_GetMaxDepth");
- PKIX_NULLCHECK_TWO(rLimits, pMaxDepth);
-
- *pMaxDepth = rLimits->maxDepth;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxDepth
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxDepth(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 maxDepth,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_SetMaxDepth");
- PKIX_NULLCHECK_ONE(rLimits);
-
- rLimits->maxDepth = maxDepth;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxNumberOfCerts
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxNumberOfCerts(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 *pMaxNumber,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_GetMaxNumberOfCerts");
- PKIX_NULLCHECK_TWO(rLimits, pMaxNumber);
-
- *pMaxNumber = rLimits->maxCertsNumber;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxNumberOfCerts
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxNumberOfCerts(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 maxNumber,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_SetMaxNumberOfCerts");
- PKIX_NULLCHECK_ONE(rLimits);
-
- rLimits->maxCertsNumber = maxNumber;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_GetMaxNumberOfCRLs
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_GetMaxNumberOfCRLs(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 *pMaxNumber,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_GetMaxNumberOfCRLs");
- PKIX_NULLCHECK_TWO(rLimits, pMaxNumber);
-
- *pMaxNumber = rLimits->maxCrlsNumber;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
-
-/*
- * FUNCTION: PKIX_ResourceLimits_SetMaxNumberOfCRLs
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ResourceLimits_SetMaxNumberOfCRLs(
- PKIX_ResourceLimits *rLimits,
- PKIX_UInt32 maxNumber,
- void *plContext)
-{
- PKIX_ENTER(RESOURCELIMITS, "PKIX_ResourceLimits_SetMaxNumberOfCRLs");
- PKIX_NULLCHECK_ONE(rLimits);
-
- rLimits->maxCrlsNumber = maxNumber;
-
- PKIX_RETURN(RESOURCELIMITS);
-}
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_resourcelimits.h b/security/nss/lib/libpkix/pkix/params/pkix_resourcelimits.h
deleted file mode 100755
index c4f582ce6..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_resourcelimits.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_resourcelimits.h
- *
- * ResourceLimits Object Type Definition
- *
- */
-
-#ifndef _PKIX_RESOURCELIMITS_H
-#define _PKIX_RESOURCELIMITS_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_ResourceLimitsStruct {
- PKIX_UInt32 maxTime;
- PKIX_UInt32 maxFanout;
- PKIX_UInt32 maxDepth;
- PKIX_UInt32 maxCertsNumber;
- PKIX_UInt32 maxCrlsNumber;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_ResourceLimits_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_RESOURCELIMITS_H */
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_trustanchor.c b/security/nss/lib/libpkix/pkix/params/pkix_trustanchor.c
deleted file mode 100755
index 5693569e6..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_trustanchor.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_trustanchor.c
- *
- * TrustAnchor Object Functions
- *
- */
-
-#include "pkix_trustanchor.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_TrustAnchor_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_TrustAnchor_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_TrustAnchor *anchor = NULL;
-
- PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a trust anchor */
- PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext),
- PKIX_OBJECTNOTTRUSTANCHOR);
-
- anchor = (PKIX_TrustAnchor *)object;
-
- PKIX_DECREF(anchor->trustedCert);
- PKIX_DECREF(anchor->caName);
- PKIX_DECREF(anchor->caPubKey);
- PKIX_DECREF(anchor->nameConstraints);
-
-cleanup:
-
- PKIX_RETURN(TRUSTANCHOR);
-}
-
-/*
- * FUNCTION: pkix_TrustAnchor_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_TrustAnchor_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
- PKIX_TrustAnchor *firstAnchor = NULL;
- PKIX_TrustAnchor *secondAnchor = NULL;
- PKIX_PL_Cert *firstCert = NULL;
- PKIX_PL_Cert *secondCert = NULL;
-
- PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- PKIX_CHECK(pkix_CheckType(first, PKIX_TRUSTANCHOR_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTTRUSTANCHOR);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- *pResult = PKIX_FALSE;
-
- if (secondType != PKIX_TRUSTANCHOR_TYPE) goto cleanup;
-
- firstAnchor = (PKIX_TrustAnchor *)first;
- secondAnchor = (PKIX_TrustAnchor *)second;
-
- firstCert = firstAnchor->trustedCert;
- secondCert = secondAnchor->trustedCert;
-
- if ((firstCert && !secondCert) || (!firstCert && secondCert)){
- goto cleanup;
- }
-
- if (firstCert && secondCert){
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstCert,
- (PKIX_PL_Object *)secondCert,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
- } else {
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstAnchor->caName,
- (PKIX_PL_Object *)secondAnchor->caName,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstAnchor->caPubKey,
- (PKIX_PL_Object *)secondAnchor->caPubKey,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- PKIX_EQUALS
- (firstAnchor->nameConstraints,
- secondAnchor->nameConstraints,
- &cmpResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- }
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(TRUSTANCHOR);
-}
-
-/*
- * FUNCTION: pkix_TrustAnchor_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_TrustAnchor_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_TrustAnchor *anchor = NULL;
- PKIX_PL_Cert *cert = NULL;
- PKIX_UInt32 hash = 0;
- PKIX_UInt32 certHash = 0;
- PKIX_UInt32 nameHash = 0;
- PKIX_UInt32 pubKeyHash = 0;
- PKIX_UInt32 ncHash = 0;
-
- PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext),
- PKIX_OBJECTNOTTRUSTANCHOR);
-
- anchor = (PKIX_TrustAnchor*)object;
- cert = anchor->trustedCert;
-
- if (cert){
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)cert,
- &certHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- hash = certHash;
-
- } else {
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)anchor->caName,
- &nameHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)anchor->caPubKey,
- &pubKeyHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE(anchor->nameConstraints, &ncHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- hash = 31 * nameHash + pubKeyHash + ncHash;
-
- }
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(TRUSTANCHOR);
-}
-
-/*
- * FUNCTION: pkix_TrustAnchor_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_TrustAnchor_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_TrustAnchor *anchor = NULL;
- char *asciiFormat = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *anchorString = NULL;
- PKIX_PL_String *certString = NULL;
- PKIX_PL_String *nameString = NULL;
- PKIX_PL_String *pubKeyString = NULL;
- PKIX_PL_String *nameConstraintsString = NULL;
-
- PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext),
- PKIX_OBJECTNOTTRUSTANCHOR);
-
- anchor = (PKIX_TrustAnchor*)object;
-
- if (anchor->trustedCert){
- asciiFormat =
- "[\n"
- "\tTrusted Cert: %s\n"
- "]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)anchor->trustedCert,
- &certString,
- plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&anchorString,
- plContext,
- formatString,
- certString),
- PKIX_SPRINTFFAILED);
- } else {
- asciiFormat =
- "[\n"
- "\tTrusted CA Name: %s\n"
- "\tTrusted CA PublicKey: %s\n"
- "\tInitial Name Constraints:%s\n"
- "]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)anchor->caName,
- &nameString,
- plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)anchor->caPubKey,
- &pubKeyString,
- plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (anchor->nameConstraints,
- &nameConstraintsString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&anchorString,
- plContext,
- formatString,
- nameString,
- pubKeyString,
- nameConstraintsString),
- PKIX_SPRINTFFAILED);
- }
-
- *pString = anchorString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(certString);
- PKIX_DECREF(nameString);
- PKIX_DECREF(pubKeyString);
- PKIX_DECREF(nameConstraintsString);
-
- PKIX_RETURN(TRUSTANCHOR);
-}
-
-/*
- * FUNCTION: pkix_TrustAnchor_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_TRUSTANCHOR_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_TrustAnchor_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_RegisterSelf");
-
- entry.description = "TrustAnchor";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_TrustAnchor);
- entry.destructor = pkix_TrustAnchor_Destroy;
- entry.equalsFunction = pkix_TrustAnchor_Equals;
- entry.hashcodeFunction = pkix_TrustAnchor_Hashcode;
- entry.toStringFunction = pkix_TrustAnchor_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_TRUSTANCHOR_TYPE] = entry;
-
- PKIX_RETURN(TRUSTANCHOR);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-
-/*
- * FUNCTION: PKIX_TrustAnchor_CreateWithCert (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_TrustAnchor_CreateWithCert(
- PKIX_PL_Cert *cert,
- PKIX_TrustAnchor **pAnchor,
- void *plContext)
-{
- PKIX_TrustAnchor *anchor = NULL;
-
- PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithCert");
- PKIX_NULLCHECK_TWO(cert, pAnchor);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_TRUSTANCHOR_TYPE,
- sizeof (PKIX_TrustAnchor),
- (PKIX_PL_Object **)&anchor,
- plContext),
- PKIX_COULDNOTCREATETRUSTANCHOROBJECT);
-
- /* initialize fields */
- PKIX_CHECK(
- PKIX_PL_Cert_SetAsTrustAnchor(cert, plContext),
- PKIX_CERTSETASTRUSTANCHORFAILED);
-
- PKIX_INCREF(cert);
- anchor->trustedCert = cert;
-
- anchor->caName = NULL;
- anchor->caPubKey = NULL;
- anchor->nameConstraints = NULL;
-
- *pAnchor = anchor;
- anchor = NULL;
-
-cleanup:
-
- PKIX_DECREF(anchor);
-
- PKIX_RETURN(TRUSTANCHOR);
-
-}
-
-/*
- * FUNCTION: PKIX_TrustAnchor_CreateWithNameKeyPair
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_TrustAnchor_CreateWithNameKeyPair(
- PKIX_PL_X500Name *name,
- PKIX_PL_PublicKey *pubKey,
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_TrustAnchor **pAnchor,
- void *plContext)
-{
- PKIX_TrustAnchor *anchor = NULL;
-
- PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithNameKeyPair");
-
-#ifndef BUILD_LIBPKIX_TESTS
- /* Nss creates trust anchors by using PKIX_TrustAnchor_CreateWithCert
- * function as the complete trusted cert structure, and not only cert
- * public key, is required for chain building and validation processes.
- * Restricting this function for been used only in libpkix unit
- * tests. */
- PKIX_ERROR(PKIX_FUNCTIONMUSTNOTBEUSED);
-#endif
-
- PKIX_NULLCHECK_THREE(name, pubKey, pAnchor);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_TRUSTANCHOR_TYPE,
- sizeof (PKIX_TrustAnchor),
- (PKIX_PL_Object **)&anchor,
- plContext),
- PKIX_COULDNOTCREATETRUSTANCHOROBJECT);
-
- /* initialize fields */
- anchor->trustedCert = NULL;
-
- PKIX_INCREF(name);
- anchor->caName = name;
-
- PKIX_INCREF(pubKey);
- anchor->caPubKey = pubKey;
-
- PKIX_INCREF(nameConstraints);
- anchor->nameConstraints = nameConstraints;
-
- *pAnchor = anchor;
- anchor = NULL;
-cleanup:
-
- PKIX_DECREF(anchor);
-
- PKIX_RETURN(TRUSTANCHOR);
-}
-
-/*
- * FUNCTION: PKIX_TrustAnchor_GetTrustedCert (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_TrustAnchor_GetTrustedCert(
- PKIX_TrustAnchor *anchor,
- PKIX_PL_Cert **pCert,
- void *plContext)
-{
- PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetTrustedCert");
- PKIX_NULLCHECK_TWO(anchor, pCert);
-
- PKIX_INCREF(anchor->trustedCert);
-
- *pCert = anchor->trustedCert;
-
-cleanup:
- PKIX_RETURN(TRUSTANCHOR);
-
-}
-
-/*
- * FUNCTION: PKIX_TrustAnchor_GetCAName (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_TrustAnchor_GetCAName(
- PKIX_TrustAnchor *anchor,
- PKIX_PL_X500Name **pCAName,
- void *plContext)
-{
- PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetCAName");
- PKIX_NULLCHECK_TWO(anchor, pCAName);
-
- PKIX_INCREF(anchor->caName);
-
- *pCAName = anchor->caName;
-
-cleanup:
- PKIX_RETURN(TRUSTANCHOR);
-
-}
-
-/*
- * FUNCTION: PKIX_TrustAnchor_GetCAPublicKey (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_TrustAnchor_GetCAPublicKey(
- PKIX_TrustAnchor *anchor,
- PKIX_PL_PublicKey **pPubKey,
- void *plContext)
-{
- PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetCAPublicKey");
- PKIX_NULLCHECK_TWO(anchor, pPubKey);
-
- PKIX_INCREF(anchor->caPubKey);
-
- *pPubKey = anchor->caPubKey;
-
-cleanup:
- PKIX_RETURN(TRUSTANCHOR);
-}
-
-/*
- * FUNCTION: PKIX_TrustAnchor_GetNameConstraints
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_TrustAnchor_GetNameConstraints(
- PKIX_TrustAnchor *anchor,
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext)
-{
- PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetNameConstraints");
- PKIX_NULLCHECK_TWO(anchor, pNameConstraints);
-
- PKIX_INCREF(anchor->nameConstraints);
-
- *pNameConstraints = anchor->nameConstraints;
-
-cleanup:
- PKIX_RETURN(TRUSTANCHOR);
-}
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_trustanchor.h b/security/nss/lib/libpkix/pkix/params/pkix_trustanchor.h
deleted file mode 100755
index e3ceb7fd3..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_trustanchor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_trustanchor.h
- *
- * TrustAnchor Object Type Definition
- *
- */
-
-#ifndef _PKIX_TRUSTANCHOR_H
-#define _PKIX_TRUSTANCHOR_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_TrustAnchorStruct {
- PKIX_PL_Cert *trustedCert;
- PKIX_PL_X500Name *caName;
- PKIX_PL_PublicKey *caPubKey;
- PKIX_PL_CertNameConstraints *nameConstraints;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_TrustAnchor_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_TRUSTANCHOR_H */
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_valparams.c b/security/nss/lib/libpkix/pkix/params/pkix_valparams.c
deleted file mode 100755
index 83c3d2b08..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_valparams.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_valparams.c
- *
- * Validate Params Object Functions
- *
- */
-
-#include "pkix_valparams.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_ValidateParams_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ValidateParams_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ValidateParams *params = NULL;
-
- PKIX_ENTER(VALIDATEPARAMS, "pkix_ValidateParams_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a validate params object */
- PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATEPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTVALIDATEPARAMS);
-
- params = (PKIX_ValidateParams *)object;
-
- PKIX_DECREF(params->procParams);
- PKIX_DECREF(params->chain);
-
-cleanup:
-
- PKIX_RETURN(VALIDATEPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ValidateParams_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ValidateParams_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
- PKIX_ValidateParams *firstValParams = NULL;
- PKIX_ValidateParams *secondValParams = NULL;
-
- PKIX_ENTER(VALIDATEPARAMS, "pkix_ValidateParams_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- PKIX_CHECK(pkix_CheckType(first, PKIX_VALIDATEPARAMS_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTVALIDATEPARAMS);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- *pResult = PKIX_FALSE;
-
- if (secondType != PKIX_VALIDATEPARAMS_TYPE) goto cleanup;
-
- firstValParams = (PKIX_ValidateParams *)first;
- secondValParams = (PKIX_ValidateParams *)second;
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstValParams->procParams,
- (PKIX_PL_Object *)secondValParams->procParams,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstValParams->chain,
- (PKIX_PL_Object *)secondValParams->chain,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(VALIDATEPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ValidateParams_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ValidateParams_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_ValidateParams *valParams = NULL;
- PKIX_UInt32 hash = 0;
- PKIX_UInt32 procParamsHash = 0;
- PKIX_UInt32 chainHash = 0;
-
- PKIX_ENTER(VALIDATEPARAMS, "pkix_ValidateParams_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATEPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTVALIDATEPARAMS);
-
- valParams = (PKIX_ValidateParams*)object;
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)valParams->procParams,
- &procParamsHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)valParams->chain,
- &chainHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- hash = 31 * procParamsHash + chainHash;
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(VALIDATEPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ValidateParams_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ValidateParams_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_ValidateParams *valParams = NULL;
- char *asciiFormat = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *valParamsString = NULL;
-
- PKIX_PL_String *procParamsString = NULL;
- PKIX_PL_String *chainString = NULL;
-
- PKIX_ENTER(VALIDATEPARAMS, "pkix_ValidateParams_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATEPARAMS_TYPE, plContext),
- PKIX_OBJECTNOTVALIDATEPARAMS);
-
- asciiFormat =
- "[\n"
- "\tProcessing Params: \n"
- "\t********BEGIN PROCESSING PARAMS********\n"
- "\t\t%s\n"
- "\t********END PROCESSING PARAMS********\n"
- "\tChain: \t\t%s\n"
- "]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- valParams = (PKIX_ValidateParams*)object;
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)valParams->procParams,
- &procParamsString,
- plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)valParams->chain,
- &chainString,
- plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&valParamsString,
- plContext,
- formatString,
- procParamsString,
- chainString),
- PKIX_SPRINTFFAILED);
-
- *pString = valParamsString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(procParamsString);
- PKIX_DECREF(chainString);
-
- PKIX_RETURN(VALIDATEPARAMS);
-}
-
-/*
- * FUNCTION: pkix_ValidateParams_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_VALIDATEPARAMS_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_ValidateParams_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(VALIDATEPARAMS, "pkix_ValidateParams_RegisterSelf");
-
- entry.description = "ValidateParams";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_ValidateParams);
- entry.destructor = pkix_ValidateParams_Destroy;
- entry.equalsFunction = pkix_ValidateParams_Equals;
- entry.hashcodeFunction = pkix_ValidateParams_Hashcode;
- entry.toStringFunction = pkix_ValidateParams_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_VALIDATEPARAMS_TYPE] = entry;
-
- PKIX_RETURN(VALIDATEPARAMS);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_ValidateParams_Create (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ValidateParams_Create(
- PKIX_ProcessingParams *procParams,
- PKIX_List *chain,
- PKIX_ValidateParams **pParams,
- void *plContext)
-{
- PKIX_ValidateParams *params = NULL;
-
- PKIX_ENTER(VALIDATEPARAMS, "PKIX_ValidateParams_Create");
- PKIX_NULLCHECK_THREE(procParams, chain, pParams);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_VALIDATEPARAMS_TYPE,
- sizeof (PKIX_ValidateParams),
- (PKIX_PL_Object **)&params,
- plContext),
- PKIX_COULDNOTCREATEVALIDATEPARAMSOBJECT);
-
- /* initialize fields */
- PKIX_INCREF(procParams);
- params->procParams = procParams;
-
- PKIX_INCREF(chain);
- params->chain = chain;
-
- *pParams = params;
- params = NULL;
-
-cleanup:
-
- PKIX_DECREF(params);
-
- PKIX_RETURN(VALIDATEPARAMS);
-
-}
-
-/*
- * FUNCTION: PKIX_ValidateParams_GetProcessingParams
- * (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ValidateParams_GetProcessingParams(
- PKIX_ValidateParams *valParams,
- PKIX_ProcessingParams **pProcParams,
- void *plContext)
-{
- PKIX_ENTER(VALIDATEPARAMS, "PKIX_ValidateParams_GetProcessingParams");
- PKIX_NULLCHECK_TWO(valParams, pProcParams);
-
- PKIX_INCREF(valParams->procParams);
-
- *pProcParams = valParams->procParams;
-
-cleanup:
- PKIX_RETURN(VALIDATEPARAMS);
-}
-
-/*
- * FUNCTION: PKIX_ValidateParams_GetCertChain (see comments in pkix_params.h)
- */
-PKIX_Error *
-PKIX_ValidateParams_GetCertChain(
- PKIX_ValidateParams *valParams,
- PKIX_List **pChain,
- void *plContext)
-{
- PKIX_ENTER(VALIDATEPARAMS, "PKIX_ValidateParams_GetCertChain");
- PKIX_NULLCHECK_TWO(valParams, pChain);
-
- PKIX_INCREF(valParams->chain);
-
- *pChain = valParams->chain;
-
-cleanup:
- PKIX_RETURN(VALIDATEPARAMS);
-}
diff --git a/security/nss/lib/libpkix/pkix/params/pkix_valparams.h b/security/nss/lib/libpkix/pkix/params/pkix_valparams.h
deleted file mode 100755
index 93b754f71..000000000
--- a/security/nss/lib/libpkix/pkix/params/pkix_valparams.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_valparams.h
- *
- * ValidateParams Object Type Definition
- *
- */
-
-#ifndef _PKIX_VALIDATEPARAMS_H
-#define _PKIX_VALIDATEPARAMS_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_ValidateParamsStruct {
- PKIX_ProcessingParams *procParams; /* Never NULL */
- PKIX_List *chain; /* Never NULL */
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_ValidateParams_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_VALIDATEPARAMS_H */
diff --git a/security/nss/lib/libpkix/pkix/results/Makefile b/security/nss/lib/libpkix/pkix/results/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix/results/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix/results/config.mk b/security/nss/lib/libpkix/pkix/results/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix/results/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix/results/manifest.mn b/security/nss/lib/libpkix/pkix/results/manifest.mn
deleted file mode 100755
index a91f2efcc..000000000
--- a/security/nss/lib/libpkix/pkix/results/manifest.mn
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_buildresult.h \
- pkix_policynode.h \
- pkix_valresult.h \
- pkix_verifynode.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_buildresult.c \
- pkix_policynode.c \
- pkix_valresult.c \
- pkix_verifynode.c \
- $(NULL)
-
-LIBRARY_NAME = pkixresults
-
diff --git a/security/nss/lib/libpkix/pkix/results/pkix_buildresult.c b/security/nss/lib/libpkix/pkix/results/pkix_buildresult.c
deleted file mode 100755
index 7d35119bc..000000000
--- a/security/nss/lib/libpkix/pkix/results/pkix_buildresult.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_buildresult.c
- *
- * BuildResult Object Functions
- *
- */
-
-#include "pkix_buildresult.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_BuildResult_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_BuildResult_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_BuildResult *result = NULL;
-
- PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a build result object */
- PKIX_CHECK(pkix_CheckType(object, PKIX_BUILDRESULT_TYPE, plContext),
- PKIX_OBJECTNOTBUILDRESULT);
-
- result = (PKIX_BuildResult *)object;
-
- PKIX_DECREF(result->valResult);
- PKIX_DECREF(result->certChain);
-
-cleanup:
-
- PKIX_RETURN(BUILDRESULT);
-}
-
-/*
- * FUNCTION: pkix_BuildResult_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_BuildResult_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
- PKIX_BuildResult *firstBuildResult = NULL;
- PKIX_BuildResult *secondBuildResult = NULL;
-
- PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- PKIX_CHECK(pkix_CheckType(first, PKIX_BUILDRESULT_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTBUILDRESULT);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- *pResult = PKIX_FALSE;
-
- if (secondType != PKIX_BUILDRESULT_TYPE) goto cleanup;
-
- firstBuildResult = (PKIX_BuildResult *)first;
- secondBuildResult = (PKIX_BuildResult *)second;
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstBuildResult->valResult,
- (PKIX_PL_Object *)secondBuildResult->valResult,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstBuildResult->certChain,
- (PKIX_PL_Object *)secondBuildResult->certChain,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- /*
- * The remaining case is that both are null,
- * which we consider equality.
- * cmpResult = PKIX_TRUE;
- */
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(BUILDRESULT);
-}
-
-/*
- * FUNCTION: pkix_BuildResult_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_BuildResult_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_BuildResult *buildResult = NULL;
- PKIX_UInt32 hash = 0;
- PKIX_UInt32 valResultHash = 0;
- PKIX_UInt32 certChainHash = 0;
-
- PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BUILDRESULT_TYPE, plContext),
- PKIX_OBJECTNOTBUILDRESULT);
-
- buildResult = (PKIX_BuildResult*)object;
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)buildResult->valResult,
- &valResultHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)buildResult->certChain,
- &certChainHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- hash = 31*(31 * valResultHash + certChainHash);
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(BUILDRESULT);
-}
-
-/*
- * FUNCTION: pkix_BuildResult_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_BuildResult_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_BuildResult *buildResult = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *buildResultString = NULL;
-
- PKIX_ValidateResult *valResult = NULL;
- PKIX_List *certChain = NULL;
-
- PKIX_PL_String *valResultString = NULL;
- PKIX_PL_String *certChainString = NULL;
-
- char *asciiFormat =
- "[\n"
- "\tValidateResult: \t\t%s"
- "\tCertChain: \t\t%s\n"
- "]\n";
-
- PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BUILDRESULT_TYPE, plContext),
- PKIX_OBJECTNOTBUILDRESULT);
-
- buildResult = (PKIX_BuildResult*)object;
-
- valResult = buildResult->valResult;
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)valResult, &valResultString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- certChain = buildResult->certChain;
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)certChain, &certChainString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&buildResultString,
- plContext,
- formatString,
- valResultString,
- certChainString),
- PKIX_SPRINTFFAILED);
-
- *pString = buildResultString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(valResultString);
- PKIX_DECREF(certChainString);
-
- PKIX_RETURN(BUILDRESULT);
-}
-
-/*
- * FUNCTION: pkix_BuildResult_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_BUILDRESULT_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_BuildResult_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_RegisterSelf");
-
- entry.description = "BuildResult";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_BuildResult);
- entry.destructor = pkix_BuildResult_Destroy;
- entry.equalsFunction = pkix_BuildResult_Equals;
- entry.hashcodeFunction = pkix_BuildResult_Hashcode;
- entry.toStringFunction = pkix_BuildResult_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_BUILDRESULT_TYPE] = entry;
-
- PKIX_RETURN(BUILDRESULT);
-}
-
-/*
- * FUNCTION: pkix_BuildResult_Create
- * DESCRIPTION:
- *
- * Creates a new BuildResult Object using the ValidateResult pointed to by
- * "valResult" and the List pointed to by "certChain", and stores it at
- * "pResult".
- *
- * PARAMETERS
- * "valResult"
- * Address of ValidateResult component. Must be non-NULL.
- * "certChain
- * Address of List component. Must be non-NULL.
- * "pResult"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_BuildResult_Create(
- PKIX_ValidateResult *valResult,
- PKIX_List *certChain,
- PKIX_BuildResult **pResult,
- void *plContext)
-{
- PKIX_BuildResult *result = NULL;
-
- PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_Create");
- PKIX_NULLCHECK_THREE(valResult, certChain, pResult);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_BUILDRESULT_TYPE,
- sizeof (PKIX_BuildResult),
- (PKIX_PL_Object **)&result,
- plContext),
- PKIX_COULDNOTCREATEBUILDRESULTOBJECT);
-
- /* initialize fields */
-
- PKIX_INCREF(valResult);
- result->valResult = valResult;
-
- PKIX_INCREF(certChain);
- result->certChain = certChain;
-
- PKIX_CHECK(PKIX_List_SetImmutable(result->certChain, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- *pResult = result;
- result = NULL;
-
-cleanup:
-
- PKIX_DECREF(result);
-
- PKIX_RETURN(BUILDRESULT);
-
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-
-/*
- * FUNCTION: PKIX_BuildResult_GetValidateResult
- * (see comments in pkix_result.h)
- */
-PKIX_Error *
-PKIX_BuildResult_GetValidateResult(
- PKIX_BuildResult *result,
- PKIX_ValidateResult **pResult,
- void *plContext)
-{
- PKIX_ENTER(BUILDRESULT, "PKIX_BuildResult_GetValidateResult");
- PKIX_NULLCHECK_TWO(result, pResult);
-
- PKIX_INCREF(result->valResult);
- *pResult = result->valResult;
-
-cleanup:
- PKIX_RETURN(BUILDRESULT);
-}
-
-
-
-/*
- * FUNCTION: PKIX_BuildResult_GetCertChain
- * (see comments in pkix_result.h)
- */
-PKIX_Error *
-PKIX_BuildResult_GetCertChain(
- PKIX_BuildResult *result,
- PKIX_List **pChain,
- void *plContext)
-{
- PKIX_ENTER(BUILDRESULT, "PKIX_BuildResult_GetCertChain");
- PKIX_NULLCHECK_TWO(result, pChain);
-
- PKIX_INCREF(result->certChain);
- *pChain = result->certChain;
-
-cleanup:
- PKIX_RETURN(BUILDRESULT);
-}
diff --git a/security/nss/lib/libpkix/pkix/results/pkix_buildresult.h b/security/nss/lib/libpkix/pkix/results/pkix_buildresult.h
deleted file mode 100755
index b43f12ba1..000000000
--- a/security/nss/lib/libpkix/pkix/results/pkix_buildresult.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_buildresult.h
- *
- * BuildResult Object Type Definition
- *
- */
-
-#ifndef _PKIX_BUILDRESULT_H
-#define _PKIX_BUILDRESULT_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_BuildResultStruct {
- PKIX_ValidateResult *valResult;
- PKIX_List *certChain;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_BuildResult_Create(
- PKIX_ValidateResult *valResult,
- PKIX_List *certChain,
- PKIX_BuildResult **pResult,
- void *plContext);
-
-PKIX_Error *pkix_BuildResult_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_BUILDRESULT_H */
diff --git a/security/nss/lib/libpkix/pkix/results/pkix_policynode.c b/security/nss/lib/libpkix/pkix/results/pkix_policynode.c
deleted file mode 100755
index 91d8a74b6..000000000
--- a/security/nss/lib/libpkix/pkix/results/pkix_policynode.c
+++ /dev/null
@@ -1,1377 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_policynode.c
- *
- * Policy Node Object Type Definition
- *
- */
-
-#include "pkix_policynode.h"
-
-/* --Private-PolicyNode-Functions---------------------------------- */
-
-/*
- * FUNCTION: pkix_PolicyNode_GetChildrenMutable
- * DESCRIPTION:
- *
- * Retrieves the List of PolicyNodes representing the child nodes of the
- * Policy Node pointed to by "node" and stores it at "pChildren". If "node"
- * has no List of child nodes, this function stores NULL at "pChildren".
- *
- * Note that the List returned by this function may be mutable. This function
- * differs from the public function PKIX_PolicyNode_GetChildren in that
- * respect. (It also differs in that the public function creates an empty
- * List, if necessary, rather than storing NULL.)
- *
- * During certificate processing, children Lists are created and modified.
- * Once the list is accessed using the public call, the List is set immutable.
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode whose child nodes are to be stored.
- * Must be non-NULL.
- * "pChildren"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a PolicyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_PolicyNode_GetChildrenMutable(
- PKIX_PolicyNode *node,
- PKIX_List **pChildren, /* list of PKIX_PolicyNode */
- void *plContext)
-{
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_GetChildrenMutable");
-
- PKIX_NULLCHECK_TWO(node, pChildren);
-
- PKIX_INCREF(node->children);
-
- *pChildren = node->children;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_Create
- * DESCRIPTION:
- *
- * Creates a new PolicyNode using the OID pointed to by "validPolicy", the List
- * of CertPolicyQualifiers pointed to by "qualifierSet", the criticality
- * indicated by the Boolean value of "criticality", and the List of OIDs
- * pointed to by "expectedPolicySet", and stores the result at "pObject". The
- * criticality should be derived from whether the certificate policy extension
- * was marked as critical in the certificate that led to creation of this
- * PolicyNode. The "qualifierSet" and "expectedPolicySet" Lists are made
- * immutable. The PolicyNode pointers to parent and to children are initialized
- * to NULL, and the depth is set to zero; those values should be set by using
- * the pkix_PolicyNode_AddToParent function.
- *
- * PARAMETERS
- * "validPolicy"
- * Address of OID of the valid policy for the path. Must be non-NULL
- * "qualifierSet"
- * Address of List of CertPolicyQualifiers associated with the validpolicy.
- * May be NULL
- * "criticality"
- * Boolean indicator of whether the criticality should be set in this
- * PolicyNode
- * "expectedPolicySet"
- * Address of List of OIDs that would satisfy this policy in the next
- * certificate. Must be non-NULL
- * "pObject"
- * Address where the PolicyNode pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a PolicyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_PolicyNode_Create(
- PKIX_PL_OID *validPolicy,
- PKIX_List *qualifierSet,
- PKIX_Boolean criticality,
- PKIX_List *expectedPolicySet,
- PKIX_PolicyNode **pObject,
- void *plContext)
-{
- PKIX_PolicyNode *node = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Create");
-
- PKIX_NULLCHECK_THREE(validPolicy, expectedPolicySet, pObject);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTPOLICYNODE_TYPE,
- sizeof (PKIX_PolicyNode),
- (PKIX_PL_Object **)&node,
- plContext),
- PKIX_COULDNOTCREATEPOLICYNODEOBJECT);
-
- PKIX_INCREF(validPolicy);
- node->validPolicy = validPolicy;
-
- PKIX_INCREF(qualifierSet);
- node->qualifierSet = qualifierSet;
- if (qualifierSet) {
- PKIX_CHECK(PKIX_List_SetImmutable(qualifierSet, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
- }
-
- node->criticality = criticality;
-
- PKIX_INCREF(expectedPolicySet);
- node->expectedPolicySet = expectedPolicySet;
- PKIX_CHECK(PKIX_List_SetImmutable(expectedPolicySet, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- node->parent = NULL;
- node->children = NULL;
- node->depth = 0;
-
- *pObject = node;
- node = NULL;
-
-cleanup:
-
- PKIX_DECREF(node);
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_AddToParent
- * DESCRIPTION:
- *
- * Adds the PolicyNode pointed to by "child" to the List of children of
- * the PolicyNode pointed to by "parentNode". If "parentNode" had a
- * NULL pointer for the List of children, a new List is created containing
- * "child". Otherwise "child" is appended to the existing List. The
- * parent field in "child" is set to "parent", and the depth field is
- * set to one more than the corresponding value in "parent".
- *
- * Depth, in this context, means distance from the root node, which
- * is at depth zero.
- *
- * PARAMETERS:
- * "parentNode"
- * Address of PolicyNode whose List of child PolicyNodes is to be
- * created or appended to. Must be non-NULL.
- * "child"
- * Address of PolicyNode to be added to parentNode's List. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a PolicyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_PolicyNode_AddToParent(
- PKIX_PolicyNode *parentNode,
- PKIX_PolicyNode *child,
- void *plContext)
-{
- PKIX_List *listOfChildren = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_AddToParent");
-
- PKIX_NULLCHECK_TWO(parentNode, child);
-
- listOfChildren = parentNode->children;
- if (listOfChildren == NULL) {
- PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
- PKIX_LISTCREATEFAILED);
- parentNode->children = listOfChildren;
- }
-
- /*
- * Note: this link is not reference-counted. The link from parent
- * to child is counted (actually, the parent "owns" a List which
- * "owns" children), but the children do not "own" the parent.
- * Otherwise, there would be loops.
- */
- child->parent = parentNode;
-
- child->depth = 1 + (parentNode->depth);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (listOfChildren, (PKIX_PL_Object *)child, plContext),
- PKIX_COULDNOTAPPENDCHILDTOPARENTSPOLICYNODELIST);
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)parentNode, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)child, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_Prune
- * DESCRIPTION:
- *
- * Prunes a tree below the PolicyNode whose address is pointed to by "node",
- * using the UInt32 value of "height" as the distance from the leaf level,
- * and storing at "pDelete" the Boolean value of whether this PolicyNode is,
- * after pruning, childless and should be pruned.
- *
- * Any PolicyNode at height 0 is allowed to survive. If the height is greater
- * than zero, pkix_PolicyNode_Prune is called recursively for each child of
- * the current PolicyNode. After this process, a node with no children
- * stores PKIX_TRUE in "pDelete" to indicate that it should be deleted.
- *
- * PARAMETERS:
- * "node"
- * Address of the PolicyNode to be pruned. Must be non-NULL.
- * "height"
- * UInt32 value for the distance from the leaf level
- * "pDelete"
- * Address to store the Boolean return value of PKIX_TRUE if this node
- * should be pruned, or PKIX_FALSE if there remains at least one
- * branch of the required height. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a PolicyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_PolicyNode_Prune(
- PKIX_PolicyNode *node,
- PKIX_UInt32 height,
- PKIX_Boolean *pDelete,
- void *plContext)
-{
- PKIX_Boolean childless = PKIX_FALSE;
- PKIX_Boolean shouldBePruned = PKIX_FALSE;
- PKIX_UInt32 listSize = 0;
- PKIX_UInt32 listIndex = 0;
- PKIX_PolicyNode *candidate = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Prune");
-
- PKIX_NULLCHECK_TWO(node, pDelete);
-
- /* Don't prune at the leaf */
- if (height == 0) {
- goto cleanup;
- }
-
- /* Above the bottom level, childless nodes get pruned */
- if (!(node->children)) {
- childless = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * This node has children. If they are leaf nodes,
- * we know they will live. Otherwise, check them out.
- */
- if (height > 1) {
- PKIX_CHECK(PKIX_List_GetLength
- (node->children, &listSize, plContext),
- PKIX_LISTGETLENGTHFAILED);
- /*
- * By working backwards from the end of the list,
- * we avoid having to worry about possible
- * decreases in the size of the list, as we
- * delete items. The only nuisance is that since the
- * index is UInt32, we can't check for it to reach -1;
- * we have to use the 1-based index, rather than the
- * 0-based index that PKIX_List functions require.
- */
- for (listIndex = listSize; listIndex > 0; listIndex--) {
- PKIX_CHECK(PKIX_List_GetItem
- (node->children,
- (listIndex - 1),
- (PKIX_PL_Object **)&candidate,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_PolicyNode_Prune
- (candidate,
- height - 1,
- &shouldBePruned,
- plContext),
- PKIX_POLICYNODEPRUNEFAILED);
-
- if (shouldBePruned == PKIX_TRUE) {
- PKIX_CHECK(PKIX_List_DeleteItem
- (node->children,
- (listIndex - 1),
- plContext),
- PKIX_LISTDELETEITEMFAILED);
- }
-
- PKIX_DECREF(candidate);
- }
- }
-
- /* Prune if this node has *become* childless */
- PKIX_CHECK(PKIX_List_GetLength
- (node->children, &listSize, plContext),
- PKIX_LISTGETLENGTHFAILED);
- if (listSize == 0) {
- childless = PKIX_TRUE;
- }
-
- /*
- * Even if we did not change this node, or any of its children,
- * maybe a [great-]*grandchild was pruned.
- */
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)node, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
- *pDelete = childless;
-
- PKIX_DECREF(candidate);
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_SinglePolicyNode_ToString
- * DESCRIPTION:
- *
- * Creates a String representation of the attributes of the PolicyNode
- * pointed to by "node", other than its parents or children, and
- * stores the result at "pString".
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode to be described by the string. Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if function succeeds
- * Returns a PolicyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in a fatal way
- */
-PKIX_Error *
-pkix_SinglePolicyNode_ToString(
- PKIX_PolicyNode *node,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *fmtString = NULL;
- PKIX_PL_String *validString = NULL;
- PKIX_PL_String *qualifierString = NULL;
- PKIX_PL_String *criticalityString = NULL;
- PKIX_PL_String *expectedString = NULL;
- PKIX_PL_String *outString = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_ToString");
- PKIX_NULLCHECK_TWO(node, pString);
- PKIX_NULLCHECK_TWO(node->validPolicy, node->expectedPolicySet);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "{%s,%s,%s,%s,%d}",
- 0,
- &fmtString,
- plContext),
- PKIX_CANTCREATESTRING);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)(node->validPolicy),
- &validString,
- plContext),
- PKIX_OIDTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)(node->expectedPolicySet),
- &expectedString,
- plContext),
- PKIX_LISTTOSTRINGFAILED);
-
- if (node->qualifierSet) {
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)(node->qualifierSet),
- &qualifierString,
- plContext),
- PKIX_LISTTOSTRINGFAILED);
- } else {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "{}",
- 0,
- &qualifierString,
- plContext),
- PKIX_CANTCREATESTRING);
- }
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- (node->criticality)?"Critical":"Not Critical",
- 0,
- &criticalityString,
- plContext),
- PKIX_CANTCREATESTRING);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&outString,
- plContext,
- fmtString,
- validString,
- qualifierString,
- criticalityString,
- expectedString,
- node->depth),
- PKIX_SPRINTFFAILED);
-
- *pString = outString;
-
-cleanup:
-
- PKIX_DECREF(fmtString);
- PKIX_DECREF(validString);
- PKIX_DECREF(qualifierString);
- PKIX_DECREF(criticalityString);
- PKIX_DECREF(expectedString);
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_ToString_Helper
- * DESCRIPTION:
- *
- * Produces a String representation of a PolicyNode tree below the PolicyNode
- * pointed to by "rootNode", with each line of output prefixed by the String
- * pointed to by "indent", and stores the result at "pTreeString". It is
- * called recursively, with ever-increasing indentation, for successively
- * lower nodes on the tree.
- *
- * PARAMETERS:
- * "rootNode"
- * Address of PolicyNode subtree. Must be non-NULL.
- * "indent"
- * Address of String to be prefixed to each line of output. May be NULL
- * if no indentation is desired
- * "pTreeString"
- * Address where the resulting String will be stored; must be non-NULL
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a PolicyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_PolicyNode_ToString_Helper(
- PKIX_PolicyNode *rootNode,
- PKIX_PL_String *indent,
- PKIX_PL_String **pTreeString,
- void *plContext)
-{
- PKIX_PL_String *nextIndentFormat = NULL;
- PKIX_PL_String *thisNodeFormat = NULL;
- PKIX_PL_String *childrenFormat = NULL;
- PKIX_PL_String *nextIndentString = NULL;
- PKIX_PL_String *resultString = NULL;
- PKIX_PL_String *thisItemString = NULL;
- PKIX_PL_String *childString = NULL;
- PKIX_PolicyNode *childNode = NULL;
- PKIX_UInt32 numberOfChildren = 0;
- PKIX_UInt32 childIndex = 0;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_ToString_Helper");
-
- PKIX_NULLCHECK_TWO(rootNode, pTreeString);
-
- /* Create a string for this node */
- PKIX_CHECK(pkix_SinglePolicyNode_ToString
- (rootNode, &thisItemString, plContext),
- PKIX_ERRORINSINGLEPOLICYNODETOSTRING);
-
- if (indent) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "%s%s",
- 0,
- &thisNodeFormat,
- plContext),
- PKIX_ERRORCREATINGFORMATSTRING);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&resultString,
- plContext,
- thisNodeFormat,
- indent,
- thisItemString),
- PKIX_ERRORINSPRINTF);
- } else {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "%s",
- 0,
- &thisNodeFormat,
- plContext),
- PKIX_ERRORCREATINGFORMATSTRING);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&resultString,
- plContext,
- thisNodeFormat,
- thisItemString),
- PKIX_ERRORINSPRINTF);
- }
-
- PKIX_DECREF(thisItemString);
- thisItemString = resultString;
-
- /* if no children, we are done */
- if (rootNode->children) {
- PKIX_CHECK(PKIX_List_GetLength
- (rootNode->children, &numberOfChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- if (numberOfChildren != 0) {
- /*
- * We create a string for each child in turn,
- * concatenating them to thisItemString.
- */
-
- /* Prepare an indent string for each child */
- if (indent) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "%s. ",
- 0,
- &nextIndentFormat,
- plContext),
- PKIX_ERRORCREATINGFORMATSTRING);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&nextIndentString,
- plContext,
- nextIndentFormat,
- indent),
- PKIX_ERRORINSPRINTF);
- } else {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- ". ",
- 0,
- &nextIndentString,
- plContext),
- PKIX_ERRORCREATINGINDENTSTRING);
- }
-
- /* Prepare the format for concatenation. */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "%s\n%s",
- 0,
- &childrenFormat,
- plContext),
- PKIX_ERRORCREATINGFORMATSTRING);
-
- for (childIndex = 0;
- childIndex < numberOfChildren;
- childIndex++) {
- PKIX_CHECK(PKIX_List_GetItem
- (rootNode->children,
- childIndex,
- (PKIX_PL_Object **)&childNode,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_PolicyNode_ToString_Helper
- (childNode,
- nextIndentString,
- &childString,
- plContext),
- PKIX_ERRORCREATINGCHILDSTRING);
-
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&resultString,
- plContext,
- childrenFormat,
- thisItemString,
- childString),
- PKIX_ERRORINSPRINTF);
-
- PKIX_DECREF(childNode);
- PKIX_DECREF(childString);
- PKIX_DECREF(thisItemString);
-
- thisItemString = resultString;
- }
- }
-
- *pTreeString = thisItemString;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(thisItemString);
- }
-
- PKIX_DECREF(nextIndentFormat);
- PKIX_DECREF(thisNodeFormat);
- PKIX_DECREF(childrenFormat);
- PKIX_DECREF(nextIndentString);
- PKIX_DECREF(childString);
- PKIX_DECREF(childNode);
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_PolicyNode_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pTreeString,
- void *plContext)
-{
- PKIX_PolicyNode *rootNode = NULL;
- PKIX_PL_String *resultString = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_ToString");
-
- PKIX_NULLCHECK_TWO(object, pTreeString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYNODE_TYPE, plContext),
- PKIX_OBJECTNOTPOLICYNODE);
-
- rootNode = (PKIX_PolicyNode *)object;
-
- PKIX_CHECK(pkix_PolicyNode_ToString_Helper
- (rootNode, NULL, &resultString, plContext),
- PKIX_ERRORCREATINGSUBTREESTRING);
-
- *pTreeString = resultString;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_PolicyNode_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PolicyNode *node = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Destroy");
-
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYNODE_TYPE, plContext),
- PKIX_OBJECTNOTPOLICYNODE);
-
- node = (PKIX_PolicyNode*)object;
-
- node->criticality = PKIX_FALSE;
- PKIX_DECREF(node->validPolicy);
- PKIX_DECREF(node->qualifierSet);
- PKIX_DECREF(node->expectedPolicySet);
- PKIX_DECREF(node->children);
-
- /*
- * Note: the link to parent is not reference-counted. See comment
- * in pkix_PolicyNode_AddToParent for more details.
- */
- node->parent = NULL;
- node->depth = 0;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_SinglePolicyNode_Hashcode
- * DESCRIPTION:
- *
- * Computes the hashcode of the attributes of the PolicyNode pointed to by
- * "node", other than its parents and children, and stores the result at
- * "pHashcode".
- *
- * PARAMETERS:
- * "node"
- * Address of PolicyNode to be hashcoded; must be non-NULL
- * "pHashcode"
- * Address where UInt32 result will be stored; must be non-NULL
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if function succeeds
- * Returns a PolicyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in a fatal way
- */
-static PKIX_Error *
-pkix_SinglePolicyNode_Hashcode(
- PKIX_PolicyNode *node,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_UInt32 componentHash = 0;
- PKIX_UInt32 nodeHash = 0;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_Hashcode");
- PKIX_NULLCHECK_TWO(node, pHashcode);
- PKIX_NULLCHECK_TWO(node->validPolicy, node->expectedPolicySet);
-
- PKIX_HASHCODE
- (node->qualifierSet,
- &nodeHash,
- plContext,
- PKIX_FAILUREHASHINGLISTQUALIFIERSET);
-
- if (PKIX_TRUE == (node->criticality)) {
- nodeHash = 31*nodeHash + 0xff;
- } else {
- nodeHash = 31*nodeHash + 0x00;
- }
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)node->validPolicy,
- &componentHash,
- plContext),
- PKIX_FAILUREHASHINGOIDVALIDPOLICY);
-
- nodeHash = 31*nodeHash + componentHash;
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)node->expectedPolicySet,
- &componentHash,
- plContext),
- PKIX_FAILUREHASHINGLISTEXPECTEDPOLICYSET);
-
- nodeHash = 31*nodeHash + componentHash;
-
- *pHashcode = nodeHash;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_PolicyNode_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PolicyNode *node = NULL;
- PKIX_UInt32 childrenHash = 0;
- PKIX_UInt32 nodeHash = 0;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTPOLICYNODE_TYPE, plContext),
- PKIX_OBJECTNOTPOLICYNODE);
-
- node = (PKIX_PolicyNode *)object;
-
- PKIX_CHECK(pkix_SinglePolicyNode_Hashcode
- (node, &nodeHash, plContext),
- PKIX_SINGLEPOLICYNODEHASHCODEFAILED);
-
- nodeHash = 31*nodeHash + (PKIX_UInt32)(node->parent);
-
- PKIX_HASHCODE
- (node->children,
- &childrenHash,
- plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- nodeHash = 31*nodeHash + childrenHash;
-
- *pHashcode = nodeHash;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_SinglePolicyNode_Equals
- * DESCRIPTION:
- *
- * Compares for equality the components of the PolicyNode pointed to by
- * "firstPN", other than its parents and children, with those of the
- * PolicyNode pointed to by "secondPN" and stores the result at "pResult"
- * (PKIX_TRUE if equal; PKIX_FALSE if not).
- *
- * PARAMETERS:
- * "firstPN"
- * Address of first of the PolicyNodes to be compared; must be non-NULL
- * "secondPN"
- * Address of second of the PolicyNodes to be compared; must be non-NULL
- * "pResult"
- * Address where Boolean will be stored; must be non-NULL
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if function succeeds
- * Returns a PolicyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in a fatal way
- */
-static PKIX_Error *
-pkix_SinglePolicyNode_Equals(
- PKIX_PolicyNode *firstPN,
- PKIX_PolicyNode *secondPN,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_Boolean compResult = PKIX_FALSE;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_Equals");
- PKIX_NULLCHECK_THREE(firstPN, secondPN, pResult);
-
- /* If both references are identical, they must be equal */
- if (firstPN == secondPN) {
- compResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * It seems we have to do the comparisons. Do
- * the easiest ones first.
- */
- if ((firstPN->criticality) != (secondPN->criticality)) {
- goto cleanup;
- }
- if ((firstPN->depth) != (secondPN->depth)) {
- goto cleanup;
- }
-
- PKIX_EQUALS
- (firstPN->qualifierSet,
- secondPN->qualifierSet,
- &compResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (compResult == PKIX_FALSE) {
- goto cleanup;
- }
-
- /* These fields must be non-NULL */
- PKIX_NULLCHECK_TWO(firstPN->validPolicy, secondPN->validPolicy);
-
- PKIX_EQUALS
- (firstPN->validPolicy,
- secondPN->validPolicy,
- &compResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (compResult == PKIX_FALSE) {
- goto cleanup;
- }
-
- /* These fields must be non-NULL */
- PKIX_NULLCHECK_TWO
- (firstPN->expectedPolicySet, secondPN->expectedPolicySet);
-
- PKIX_EQUALS
- (firstPN->expectedPolicySet,
- secondPN->expectedPolicySet,
- &compResult,
- plContext,
- PKIX_OBJECTEQUALSFAILEDONEXPECTEDPOLICYSETS);
-
-cleanup:
-
- *pResult = compResult;
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_PolicyNode_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PolicyNode *firstPN = NULL;
- PKIX_PolicyNode *secondPN = NULL;
- PKIX_UInt32 secondType;
- PKIX_Boolean compResult = PKIX_FALSE;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a PolicyNode */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_CERTPOLICYNODE_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTPOLICYNODE);
-
- /*
- * Since we know firstObject is a PolicyNode,
- * if both references are identical, they must be equal
- */
- if (firstObject == secondObject){
- compResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a PolicyNode, we
- * don't throw an error. We simply return FALSE.
- */
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- if (secondType != PKIX_CERTPOLICYNODE_TYPE) {
- goto cleanup;
- }
-
- /*
- * Oh, well, we have to do the comparisons. Do
- * the easiest ones first.
- */
- firstPN = (PKIX_PolicyNode *)firstObject;
- secondPN = (PKIX_PolicyNode *)secondObject;
-
- /*
- * We don't require the parents to be identical. In the
- * course of traversing the tree, we will have checked the
- * attributes of the parent nodes, and checking the lists
- * of children will determine whether they match.
- */
-
- PKIX_EQUALS
- (firstPN->children,
- secondPN->children,
- &compResult,
- plContext,
- PKIX_OBJECTEQUALSFAILEDONCHILDREN);
-
- if (compResult == PKIX_FALSE) {
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_SinglePolicyNode_Equals
- (firstPN, secondPN, &compResult, plContext),
- PKIX_SINGLEPOLICYNODEEQUALSFAILED);
-
-cleanup:
-
- *pResult = compResult;
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_DuplicateHelper
- * DESCRIPTION:
- *
- * Duplicates the PolicyNode whose address is pointed to by "original",
- * and stores the result at "pNewNode", if a non-NULL pointer is provided
- * for "pNewNode". In addition, the created PolicyNode is added as a child
- * to "parent", if a non-NULL pointer is provided for "parent". Then this
- * function is called recursively to duplicate each of the children of
- * "original". At the top level this function is called with a null
- * "parent" and a non-NULL "pNewNode". Below the top level "parent" will
- * be non-NULL and "pNewNode" will be NULL.
- *
- * PARAMETERS:
- * "original"
- * Address of PolicyNode to be copied; must be non-NULL
- * "parent"
- * Address of PolicyNode to which the created node is to be added as a
- * child; NULL for the top-level call and non-NULL below the top level
- * "pNewNode"
- * Address to store the node created; should be NULL if "parent" is
- * non-NULL and vice versa
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if function succeeds
- * Returns a PolicyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in a fatal way
- */
-static PKIX_Error *
-pkix_PolicyNode_DuplicateHelper(
- PKIX_PolicyNode *original,
- PKIX_PolicyNode *parent,
- PKIX_PolicyNode **pNewNode,
- void *plContext)
-{
- PKIX_UInt32 numChildren = 0;
- PKIX_UInt32 childIndex = 0;
- PKIX_List *children = NULL; /* List of PKIX_PolicyNode */
- PKIX_PolicyNode *copy = NULL;
- PKIX_PolicyNode *child = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_DuplicateHelper");
-
- PKIX_NULLCHECK_THREE
- (original, original->validPolicy, original->expectedPolicySet);
-
- /*
- * These components are immutable, so copying the pointers
- * is sufficient. The create function increments the reference
- * counts as it stores the pointers into the new object.
- */
- PKIX_CHECK(pkix_PolicyNode_Create
- (original->validPolicy,
- original->qualifierSet,
- original->criticality,
- original->expectedPolicySet,
- &copy,
- plContext),
- PKIX_POLICYNODECREATEFAILED);
-
- if (parent) {
- PKIX_CHECK(pkix_PolicyNode_AddToParent(parent, copy, plContext),
- PKIX_POLICYNODEADDTOPARENTFAILED);
- }
-
- /* Are there any children to duplicate? */
- children = original->children;
-
- if (children) {
- PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- for (childIndex = 0; childIndex < numChildren; childIndex++) {
- PKIX_CHECK(PKIX_List_GetItem
- (children,
- childIndex,
- (PKIX_PL_Object **)&child,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_PolicyNode_DuplicateHelper
- (child, copy, NULL, plContext),
- PKIX_POLICYNODEDUPLICATEHELPERFAILED);
-
- PKIX_DECREF(child);
- }
-
- if (pNewNode) {
- *pNewNode = copy;
- copy = NULL; /* no DecRef if we give our handle away */
- }
-
-cleanup:
- PKIX_DECREF(copy);
- PKIX_DECREF(child);
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_Duplicate
- * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_PolicyNode_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_PolicyNode *original = NULL;
- PKIX_PolicyNode *copy = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Duplicate");
-
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTPOLICYNODE_TYPE, plContext),
- PKIX_OBJECTNOTPOLICYNODE);
-
- original = (PKIX_PolicyNode *)object;
-
- PKIX_CHECK(pkix_PolicyNode_DuplicateHelper
- (original, NULL, &copy, plContext),
- PKIX_POLICYNODEDUPLICATEHELPERFAILED);
-
- *pNewObject = (PKIX_PL_Object *)copy;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: pkix_PolicyNode_RegisterSelf
- * DESCRIPTION:
- *
- * Registers PKIX_CERTPOLICYNODE_TYPE and its related
- * functions with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize,
- * which should only be called once, it is acceptable that
- * this function is not thread-safe.
- */
-PKIX_Error *
-pkix_PolicyNode_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_RegisterSelf");
-
- entry.description = "PolicyNode";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PolicyNode);
- entry.destructor = pkix_PolicyNode_Destroy;
- entry.equalsFunction = pkix_PolicyNode_Equals;
- entry.hashcodeFunction = pkix_PolicyNode_Hashcode;
- entry.toStringFunction = pkix_PolicyNode_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_PolicyNode_Duplicate;
-
- systemClasses[PKIX_CERTPOLICYNODE_TYPE] = entry;
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-
-/* --Public-PolicyNode-Functions----------------------------------- */
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetChildren
- * (see description of this function in pkix_results.h)
- */
-PKIX_Error *
-PKIX_PolicyNode_GetChildren(
- PKIX_PolicyNode *node,
- PKIX_List **pChildren, /* list of PKIX_PolicyNode */
- void *plContext)
-{
- PKIX_List *children = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetChildren");
-
- PKIX_NULLCHECK_TWO(node, pChildren);
-
- PKIX_INCREF(node->children);
- children = node->children;
-
- if (!children) {
- PKIX_CHECK(PKIX_List_Create(&children, plContext),
- PKIX_LISTCREATEFAILED);
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable(children, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- *pChildren = children;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(children);
- }
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetParent
- * (see description of this function in pkix_results.h)
- */
-PKIX_Error *
-PKIX_PolicyNode_GetParent(
- PKIX_PolicyNode *node,
- PKIX_PolicyNode **pParent,
- void *plContext)
-{
-
- PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetParent");
-
- PKIX_NULLCHECK_TWO(node, pParent);
-
- PKIX_INCREF(node->parent);
- *pParent = node->parent;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetValidPolicy
- * (see description of this function in pkix_results.h)
- */
-PKIX_Error *
-PKIX_PolicyNode_GetValidPolicy(
- PKIX_PolicyNode *node,
- PKIX_PL_OID **pValidPolicy,
- void *plContext)
-{
-
- PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetValidPolicy");
-
- PKIX_NULLCHECK_TWO(node, pValidPolicy);
-
- PKIX_INCREF(node->validPolicy);
- *pValidPolicy = node->validPolicy;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetPolicyQualifiers
- * (see description of this function in pkix_results.h)
- */
-PKIX_Error *
-PKIX_PolicyNode_GetPolicyQualifiers(
- PKIX_PolicyNode *node,
- PKIX_List **pQualifiers, /* list of PKIX_PL_CertPolicyQualifier */
- void *plContext)
-{
- PKIX_List *qualifiers = NULL;
-
- PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetPolicyQualifiers");
-
- PKIX_NULLCHECK_TWO(node, pQualifiers);
-
- PKIX_INCREF(node->qualifierSet);
- qualifiers = node->qualifierSet;
-
- if (!qualifiers) {
- PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext),
- PKIX_LISTCREATEFAILED);
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable(qualifiers, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- *pQualifiers = qualifiers;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetExpectedPolicies
- * (see description of this function in pkix_results.h)
- */
-PKIX_Error *
-PKIX_PolicyNode_GetExpectedPolicies(
- PKIX_PolicyNode *node,
- PKIX_List **pExpPolicies, /* list of PKIX_PL_OID */
- void *plContext)
-{
-
- PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetExpectedPolicies");
-
- PKIX_NULLCHECK_TWO(node, pExpPolicies);
-
- PKIX_INCREF(node->expectedPolicySet);
- *pExpPolicies = node->expectedPolicySet;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: PKIX_PolicyNode_IsCritical
- * (see description of this function in pkix_results.h)
- */
-PKIX_Error *
-PKIX_PolicyNode_IsCritical(
- PKIX_PolicyNode *node,
- PKIX_Boolean *pCritical,
- void *plContext)
-{
-
- PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_IsCritical");
-
- PKIX_NULLCHECK_TWO(node, pCritical);
-
- *pCritical = node->criticality;
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
-
-/*
- * FUNCTION: PKIX_PolicyNode_GetDepth
- * (see description of this function in pkix_results.h)
- */
-PKIX_Error *
-PKIX_PolicyNode_GetDepth(
- PKIX_PolicyNode *node,
- PKIX_UInt32 *pDepth,
- void *plContext)
-{
-
- PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetDepth");
-
- PKIX_NULLCHECK_TWO(node, pDepth);
-
- *pDepth = node->depth;
-
- PKIX_RETURN(CERTPOLICYNODE);
-}
diff --git a/security/nss/lib/libpkix/pkix/results/pkix_policynode.h b/security/nss/lib/libpkix/pkix/results/pkix_policynode.h
deleted file mode 100755
index 799b7a60a..000000000
--- a/security/nss/lib/libpkix/pkix/results/pkix_policynode.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_policynode.h
- *
- * PolicyNode Type Definitions
- *
- */
-
-#ifndef _PKIX_POLICYNODE_H
-#define _PKIX_POLICYNODE_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This structure reflects the contents of a policy node...
- */
-struct PKIX_PolicyNodeStruct {
- PKIX_PL_OID *validPolicy;
- PKIX_List *qualifierSet; /* CertPolicyQualifiers */
- PKIX_Boolean criticality;
- PKIX_List *expectedPolicySet; /* OIDs */
- PKIX_PolicyNode *parent;
- PKIX_List *children; /* PolicyNodes */
- PKIX_UInt32 depth;
-};
-
-PKIX_Error *
-pkix_SinglePolicyNode_ToString(
- PKIX_PolicyNode *node,
- PKIX_PL_String **pString,
- void *plContext);
-
-PKIX_Error *
-pkix_PolicyNode_GetChildrenMutable(
- PKIX_PolicyNode *node,
- PKIX_List **pChildren, /* PolicyNodes */
- void *plContext);
-
-PKIX_Error *
-pkix_PolicyNode_Create(
- PKIX_PL_OID *validPolicy,
- PKIX_List *qualifierSet, /* CertPolicyQualifiers */
- PKIX_Boolean criticality,
- PKIX_List *expectedPolicySet, /* OIDs */
- PKIX_PolicyNode **pObject,
- void *plContext);
-
-PKIX_Error *
-pkix_PolicyNode_AddToParent(
- PKIX_PolicyNode *parentNode,
- PKIX_PolicyNode *child,
- void *plContext);
-
-PKIX_Error *
-pkix_PolicyNode_Prune(
- PKIX_PolicyNode *node,
- PKIX_UInt32 depth,
- PKIX_Boolean *pDelete,
- void *plContext);
-
-PKIX_Error *
-pkix_PolicyNode_RegisterSelf(
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_POLICYNODE_H */
diff --git a/security/nss/lib/libpkix/pkix/results/pkix_valresult.c b/security/nss/lib/libpkix/pkix/results/pkix_valresult.c
deleted file mode 100755
index 25b69e59c..000000000
--- a/security/nss/lib/libpkix/pkix/results/pkix_valresult.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_valresult.c
- *
- * ValidateResult Object Functions
- *
- */
-
-#include "pkix_valresult.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_ValidateResult_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ValidateResult_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ValidateResult *result = NULL;
-
- PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a validate result object */
- PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATERESULT_TYPE, plContext),
- PKIX_OBJECTNOTVALIDATERESULT);
-
- result = (PKIX_ValidateResult *)object;
-
- PKIX_DECREF(result->anchor);
- PKIX_DECREF(result->pubKey);
- PKIX_DECREF(result->policyTree);
-
-cleanup:
-
- PKIX_RETURN(VALIDATERESULT);
-}
-
-/*
- * FUNCTION: pkix_ValidateResult_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ValidateResult_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
- PKIX_ValidateResult *firstValResult = NULL;
- PKIX_ValidateResult *secondValResult = NULL;
- PKIX_TrustAnchor *firstAnchor = NULL;
- PKIX_TrustAnchor *secondAnchor = NULL;
- PKIX_PolicyNode *firstTree = NULL;
- PKIX_PolicyNode *secondTree = NULL;
-
- PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- PKIX_CHECK(pkix_CheckType(first, PKIX_VALIDATERESULT_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTVALIDATERESULT);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- *pResult = PKIX_FALSE;
-
- if (secondType != PKIX_VALIDATERESULT_TYPE) goto cleanup;
-
- firstValResult = (PKIX_ValidateResult *)first;
- secondValResult = (PKIX_ValidateResult *)second;
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstValResult->pubKey,
- (PKIX_PL_Object *)secondValResult->pubKey,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (!cmpResult) goto cleanup;
-
- firstAnchor = firstValResult->anchor;
- secondAnchor = secondValResult->anchor;
-
- if ((firstAnchor != NULL) && (secondAnchor != NULL)) {
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstAnchor,
- (PKIX_PL_Object *)secondAnchor,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
- } else {
- cmpResult = (firstAnchor == secondAnchor);
- }
-
- if (!cmpResult) goto cleanup;
-
- firstTree = firstValResult->policyTree;
- secondTree = secondValResult->policyTree;
-
- if ((firstTree != NULL) && (secondTree != NULL)) {
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstTree,
- (PKIX_PL_Object *)secondTree,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
- } else {
- cmpResult = (firstTree == secondTree);
- }
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(VALIDATERESULT);
-}
-
-/*
- * FUNCTION: pkix_ValidateResult_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ValidateResult_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_ValidateResult *valResult = NULL;
- PKIX_UInt32 hash = 0;
- PKIX_UInt32 pubKeyHash = 0;
- PKIX_UInt32 anchorHash = 0;
- PKIX_UInt32 policyTreeHash = 0;
-
- PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATERESULT_TYPE, plContext),
- PKIX_OBJECTNOTVALIDATERESULT);
-
- valResult = (PKIX_ValidateResult*)object;
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)valResult->pubKey, &pubKeyHash, plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- if (valResult->anchor) {
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)valResult->anchor,
- &anchorHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
- }
-
- if (valResult->policyTree) {
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)valResult->policyTree,
- &policyTreeHash,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
- }
-
- hash = 31*(31 * pubKeyHash + anchorHash) + policyTreeHash;
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(VALIDATERESULT);
-}
-
-/*
- * FUNCTION: pkix_ValidateResult_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ValidateResult_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_ValidateResult *valResult = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *valResultString = NULL;
-
- PKIX_TrustAnchor *anchor = NULL;
- PKIX_PL_PublicKey *pubKey = NULL;
- PKIX_PolicyNode *policyTree = NULL;
-
- PKIX_PL_String *anchorString = NULL;
- PKIX_PL_String *pubKeyString = NULL;
- PKIX_PL_String *treeString = NULL;
- char *asciiNullString = "(null)";
- char *asciiFormat =
- "[\n"
- "\tTrustAnchor: \t\t%s"
- "\tPubKey: \t\t%s\n"
- "\tPolicyTree: \t\t%s\n"
- "]\n";
-
- PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATERESULT_TYPE, plContext),
- PKIX_OBJECTNOTVALIDATERESULT);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- valResult = (PKIX_ValidateResult*)object;
-
- anchor = valResult->anchor;
-
- if (anchor) {
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)anchor, &anchorString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
- } else {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiNullString,
- 0,
- &anchorString,
- plContext),
- PKIX_STRINGCREATEFAILED);
- }
-
- pubKey = valResult->pubKey;
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)pubKey, &pubKeyString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- policyTree = valResult->policyTree;
-
- if (policyTree) {
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)policyTree, &treeString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
- } else {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiNullString,
- 0,
- &treeString,
- plContext),
- PKIX_STRINGCREATEFAILED);
- }
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&valResultString,
- plContext,
- formatString,
- anchorString,
- pubKeyString,
- treeString),
- PKIX_SPRINTFFAILED);
-
- *pString = valResultString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(anchorString);
- PKIX_DECREF(pubKeyString);
- PKIX_DECREF(treeString);
-
- PKIX_RETURN(VALIDATERESULT);
-}
-
-/*
- * FUNCTION: pkix_ValidateResult_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_VALIDATERESULT_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_ValidateResult_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_RegisterSelf");
-
- entry.description = "ValidateResult";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_ValidateResult);
- entry.destructor = pkix_ValidateResult_Destroy;
- entry.equalsFunction = pkix_ValidateResult_Equals;
- entry.hashcodeFunction = pkix_ValidateResult_Hashcode;
- entry.toStringFunction = pkix_ValidateResult_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_VALIDATERESULT_TYPE] = entry;
-
- PKIX_RETURN(VALIDATERESULT);
-}
-
-/*
- * FUNCTION: pkix_ValidateResult_Create
- * DESCRIPTION:
- *
- * Creates a new ValidateResult Object using the PublicKey pointed to by
- * "pubKey", the TrustAnchor pointed to by "anchor", and the PolicyNode
- * pointed to by "policyTree", and stores it at "pResult".
- *
- * PARAMETERS
- * "pubKey"
- * PublicKey of the desired ValidateResult. Must be non-NULL.
- * "anchor"
- * TrustAnchor of the desired Validateresult. May be NULL.
- * "policyTree"
- * PolicyNode of the desired ValidateResult; may be NULL
- * "pResult"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_ValidateResult_Create(
- PKIX_PL_PublicKey *pubKey,
- PKIX_TrustAnchor *anchor,
- PKIX_PolicyNode *policyTree,
- PKIX_ValidateResult **pResult,
- void *plContext)
-{
- PKIX_ValidateResult *result = NULL;
-
- PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Create");
- PKIX_NULLCHECK_TWO(pubKey, pResult);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_VALIDATERESULT_TYPE,
- sizeof (PKIX_ValidateResult),
- (PKIX_PL_Object **)&result,
- plContext),
- PKIX_COULDNOTCREATEVALIDATERESULTOBJECT);
-
- /* initialize fields */
-
- PKIX_INCREF(pubKey);
- result->pubKey = pubKey;
-
- PKIX_INCREF(anchor);
- result->anchor = anchor;
-
- PKIX_INCREF(policyTree);
- result->policyTree = policyTree;
-
- *pResult = result;
- result = NULL;
-
-cleanup:
-
- PKIX_DECREF(result);
-
- PKIX_RETURN(VALIDATERESULT);
-
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_ValidateResult_GetPublicKey
- * (see comments in pkix_result.h)
- */
-PKIX_Error *
-PKIX_ValidateResult_GetPublicKey(
- PKIX_ValidateResult *result,
- PKIX_PL_PublicKey **pPublicKey,
- void *plContext)
-{
- PKIX_ENTER(VALIDATERESULT, "PKIX_ValidateResult_GetPublicKey");
- PKIX_NULLCHECK_TWO(result, pPublicKey);
-
- PKIX_INCREF(result->pubKey);
- *pPublicKey = result->pubKey;
-
-cleanup:
- PKIX_RETURN(VALIDATERESULT);
-}
-
-/*
- * FUNCTION: PKIX_ValidateResult_GetTrustAnchor
- * (see comments in pkix_result.h)
- */
-PKIX_Error *
-PKIX_ValidateResult_GetTrustAnchor(
- PKIX_ValidateResult *result,
- PKIX_TrustAnchor **pTrustAnchor,
- void *plContext)
-{
- PKIX_ENTER(VALIDATERESULT, "PKIX_ValidateResult_GetTrustAnchor");
- PKIX_NULLCHECK_TWO(result, pTrustAnchor);
-
- PKIX_INCREF(result->anchor);
- *pTrustAnchor = result->anchor;
-
-cleanup:
- PKIX_RETURN(VALIDATERESULT);
-}
-
-/*
- * FUNCTION: PKIX_ValidateResult_GetPolicyTree
- * (see comments in pkix_result.h)
- */
-PKIX_Error *
-PKIX_ValidateResult_GetPolicyTree(
- PKIX_ValidateResult *result,
- PKIX_PolicyNode **pPolicyTree,
- void *plContext)
-{
- PKIX_ENTER(VALIDATERESULT, "PKIX_ValidateResult_GetPolicyTree");
- PKIX_NULLCHECK_TWO(result, pPolicyTree);
-
- PKIX_INCREF(result->policyTree);
- (*pPolicyTree) = result->policyTree;
-
-cleanup:
- PKIX_RETURN(VALIDATERESULT);
-}
diff --git a/security/nss/lib/libpkix/pkix/results/pkix_valresult.h b/security/nss/lib/libpkix/pkix/results/pkix_valresult.h
deleted file mode 100755
index 8011ae8c8..000000000
--- a/security/nss/lib/libpkix/pkix/results/pkix_valresult.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_valresult.h
- *
- * ValidateResult Object Type Definition
- *
- */
-
-#ifndef _PKIX_VALIDATERESULT_H
-#define _PKIX_VALIDATERESULT_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_ValidateResultStruct {
- PKIX_PL_PublicKey *pubKey;
- PKIX_TrustAnchor *anchor;
- PKIX_PolicyNode *policyTree;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_ValidateResult_Create(
- PKIX_PL_PublicKey *pubKey,
- PKIX_TrustAnchor *anchor,
- PKIX_PolicyNode *policyTree,
- PKIX_ValidateResult **pResult,
- void *plContext);
-
-PKIX_Error *pkix_ValidateResult_RegisterSelf(void *plContext);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_VALIDATERESULT_H */
diff --git a/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c b/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c
deleted file mode 100755
index b52f83fca..000000000
--- a/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c
+++ /dev/null
@@ -1,1182 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_verifynode.c
- *
- * Verify Node Object Type Definition
- *
- */
-
-#include "pkix_verifynode.h"
-
-/* --Private-VerifyNode-Functions---------------------------------- */
-
-/*
- * FUNCTION: pkix_VerifyNode_Create
- * DESCRIPTION:
- *
- * This function creates a VerifyNode using the Cert pointed to by "cert",
- * the depth given by "depth", and the Error pointed to by "error", storing
- * the result at "pObject".
- *
- * PARAMETERS
- * "cert"
- * Address of Cert for the node. Must be non-NULL
- * "depth"
- * UInt32 value of the depth for this node.
- * "error"
- * Address of Error for the node.
- * "pObject"
- * Address where the VerifyNode pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_VerifyNode_Create(
- PKIX_PL_Cert *cert,
- PKIX_UInt32 depth,
- PKIX_Error *error,
- PKIX_VerifyNode **pObject,
- void *plContext)
-{
- PKIX_VerifyNode *node = NULL;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Create");
- PKIX_NULLCHECK_TWO(cert, pObject);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_VERIFYNODE_TYPE,
- sizeof (PKIX_VerifyNode),
- (PKIX_PL_Object **)&node,
- plContext),
- PKIX_COULDNOTCREATEVERIFYNODEOBJECT);
-
- PKIX_INCREF(cert);
- node->verifyCert = cert;
-
- PKIX_INCREF(error);
- node->error = error;
-
- node->depth = depth;
-
- node->children = NULL;
-
- *pObject = node;
- node = NULL;
-
-cleanup:
-
- PKIX_DECREF(node);
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_AddToChain
- * DESCRIPTION:
- *
- * Adds the VerifyNode pointed to by "child", at the appropriate depth, to the
- * List of children of the VerifyNode pointed to by "parentNode". The chain of
- * VerifyNodes is traversed until a VerifyNode is found at a depth one less
- * than that specified in "child". An Error is returned if there is no parent
- * at a suitable depth.
- *
- * If "parentNode" has a NULL pointer for the List of children, a new List is
- * created containing "child". Otherwise "child" is appended to the existing
- * List.
- *
- * Depth, in this context, means distance from the root node, which
- * is at depth zero.
- *
- * PARAMETERS:
- * "parentNode"
- * Address of VerifyNode whose List of child VerifyNodes is to be
- * created or appended to. Must be non-NULL.
- * "child"
- * Address of VerifyNode to be added to parentNode's List. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a VerifyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_VerifyNode_AddToChain(
- PKIX_VerifyNode *parentNode,
- PKIX_VerifyNode *child,
- void *plContext)
-{
- PKIX_VerifyNode *successor = NULL;
- PKIX_List *listOfChildren = NULL;
- PKIX_UInt32 numChildren = 0;
- PKIX_UInt32 parentDepth = 0;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToChain");
- PKIX_NULLCHECK_TWO(parentNode, child);
-
- parentDepth = parentNode->depth;
- listOfChildren = parentNode->children;
- if (listOfChildren == NULL) {
-
- if (parentDepth != (child->depth - 1)) {
- PKIX_ERROR(PKIX_NODESMISSINGFROMCHAIN);
- }
-
- PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (listOfChildren, (PKIX_PL_Object *)child, plContext),
- PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST);
-
- parentNode->children = listOfChildren;
- } else {
- /* get number of children */
- PKIX_CHECK(PKIX_List_GetLength
- (listOfChildren, &numChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (numChildren != 1) {
- PKIX_ERROR(PKIX_AMBIGUOUSPARENTAGEOFVERIFYNODE);
- }
-
- /* successor = listOfChildren[0] */
- PKIX_CHECK(PKIX_List_GetItem
- (listOfChildren,
- 0,
- (PKIX_PL_Object **)&successor,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_VerifyNode_AddToChain
- (successor, child, plContext),
- PKIX_VERIFYNODEADDTOCHAINFAILED);
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)parentNode, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
- PKIX_DECREF(successor);
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_SetDepth
- * DESCRIPTION:
- *
- * The function sets the depth field of each VerifyNode in the List "children"
- * to the value given by "depth", and recursively sets the depth of any
- * successive generations to the successive values.
- *
- * PARAMETERS:
- * "children"
- * The List of VerifyNodes. Must be non-NULL.
- * "depth"
- * The value of the depth field to be set in members of the List.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_VerifyNode_SetDepth(PKIX_List *children,
- PKIX_UInt32 depth,
- void *plContext)
-{
- PKIX_UInt32 numChildren = 0;
- PKIX_UInt32 chIx = 0;
- PKIX_VerifyNode *child = NULL;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_SetDepth");
- PKIX_NULLCHECK_ONE(children);
-
- PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (chIx = 0; chIx < numChildren; chIx++) {
- PKIX_CHECK(PKIX_List_GetItem
- (children, chIx, (PKIX_PL_Object **)&child, plContext),
- PKIX_LISTGETITEMFAILED);
-
- child->depth = depth;
-
- if (child->children != NULL) {
- PKIX_CHECK(pkix_VerifyNode_SetDepth
- (child->children, depth + 1, plContext),
- PKIX_VERIFYNODESETDEPTHFAILED);
- }
-
- PKIX_DECREF(child);
- }
-
-cleanup:
-
- PKIX_DECREF(child);
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_AddToTree
- * DESCRIPTION:
- *
- * Adds the VerifyNode pointed to by "child" to the List of children of the
- * VerifyNode pointed to by "parentNode". If "parentNode" has a NULL pointer
- * for the List of children, a new List is created containing "child".
- * Otherwise "child" is appended to the existing List. The depth field of
- * "child" is set to one more than the corresponding value in "parent", and
- * if the "child" itself has child nodes, their depth fields are updated
- * accordingly.
- *
- * Depth, in this context, means distance from the root node, which
- * is at depth zero.
- *
- * PARAMETERS:
- * "parentNode"
- * Address of VerifyNode whose List of child VerifyNodes is to be
- * created or appended to. Must be non-NULL.
- * "child"
- * Address of VerifyNode to be added to parentNode's List. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_VerifyNode_AddToTree(
- PKIX_VerifyNode *parentNode,
- PKIX_VerifyNode *child,
- void *plContext)
-{
- PKIX_List *listOfChildren = NULL;
- PKIX_UInt32 parentDepth = 0;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToTree");
- PKIX_NULLCHECK_TWO(parentNode, child);
-
- parentDepth = parentNode->depth;
- listOfChildren = parentNode->children;
- if (listOfChildren == NULL) {
-
- PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
- PKIX_LISTCREATEFAILED);
-
- parentNode->children = listOfChildren;
- }
-
- child->depth = parentDepth + 1;
-
- PKIX_CHECK(PKIX_List_AppendItem
- (parentNode->children, (PKIX_PL_Object *)child, plContext),
- PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST);
-
- if (child->children != NULL) {
- PKIX_CHECK(pkix_VerifyNode_SetDepth
- (child->children, child->depth + 1, plContext),
- PKIX_VERIFYNODESETDEPTHFAILED);
- }
-
-
-cleanup:
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_SingleVerifyNode_ToString
- * DESCRIPTION:
- *
- * Creates a String representation of the attributes of the VerifyNode pointed
- * to by "node", other than its children, and stores the result at "pString".
- *
- * PARAMETERS:
- * "node"
- * Address of VerifyNode to be described by the string. Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if function succeeds
- * Returns a VerifyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in a fatal way
- */
-PKIX_Error *
-pkix_SingleVerifyNode_ToString(
- PKIX_VerifyNode *node,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *fmtString = NULL;
- PKIX_PL_String *errorString = NULL;
- PKIX_PL_String *outString = NULL;
-
- PKIX_PL_X500Name *issuerName = NULL;
- PKIX_PL_X500Name *subjectName = NULL;
- PKIX_PL_String *issuerString = NULL;
- PKIX_PL_String *subjectString = NULL;
-
- PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_ToString");
- PKIX_NULLCHECK_THREE(node, pString, node->verifyCert);
-
- PKIX_TOSTRING(node->error, &errorString, plContext,
- PKIX_ERRORTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetIssuer
- (node->verifyCert, &issuerName, plContext),
- PKIX_CERTGETISSUERFAILED);
-
- PKIX_TOSTRING(issuerName, &issuerString, plContext,
- PKIX_X500NAMETOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubject
- (node->verifyCert, &subjectName, plContext),
- PKIX_CERTGETSUBJECTFAILED);
-
- PKIX_TOSTRING(subjectName, &subjectString, plContext,
- PKIX_X500NAMETOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "CERT[Issuer:%s, Subject:%s], depth=%d, error=%s",
- 0,
- &fmtString,
- plContext),
- PKIX_CANTCREATESTRING);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&outString,
- plContext,
- fmtString,
- issuerString,
- subjectString,
- node->depth,
- errorString),
- PKIX_SPRINTFFAILED);
-
- *pString = outString;
-
-cleanup:
-
- PKIX_DECREF(fmtString);
- PKIX_DECREF(errorString);
- PKIX_DECREF(issuerName);
- PKIX_DECREF(subjectName);
- PKIX_DECREF(issuerString);
- PKIX_DECREF(subjectString);
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_ToString_Helper
- * DESCRIPTION:
- *
- * Produces a String representation of a VerifyNode tree below the VerifyNode
- * pointed to by "rootNode", with each line of output prefixed by the String
- * pointed to by "indent", and stores the result at "pTreeString". It is
- * called recursively, with ever-increasing indentation, for successively
- * lower nodes on the tree.
- *
- * PARAMETERS:
- * "rootNode"
- * Address of VerifyNode subtree. Must be non-NULL.
- * "indent"
- * Address of String to be prefixed to each line of output. May be NULL
- * if no indentation is desired
- * "pTreeString"
- * Address where the resulting String will be stored; must be non-NULL
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a VerifyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_VerifyNode_ToString_Helper(
- PKIX_VerifyNode *rootNode,
- PKIX_PL_String *indent,
- PKIX_PL_String **pTreeString,
- void *plContext)
-{
- PKIX_PL_String *nextIndentFormat = NULL;
- PKIX_PL_String *thisNodeFormat = NULL;
- PKIX_PL_String *childrenFormat = NULL;
- PKIX_PL_String *nextIndentString = NULL;
- PKIX_PL_String *resultString = NULL;
- PKIX_PL_String *thisItemString = NULL;
- PKIX_PL_String *childString = NULL;
- PKIX_VerifyNode *childNode = NULL;
- PKIX_UInt32 numberOfChildren = 0;
- PKIX_UInt32 childIndex = 0;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString_Helper");
-
- PKIX_NULLCHECK_TWO(rootNode, pTreeString);
-
- /* Create a string for this node */
- PKIX_CHECK(pkix_SingleVerifyNode_ToString
- (rootNode, &thisItemString, plContext),
- PKIX_ERRORINSINGLEVERIFYNODETOSTRING);
-
- if (indent) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "%s%s",
- 0,
- &thisNodeFormat,
- plContext),
- PKIX_ERRORCREATINGFORMATSTRING);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&resultString,
- plContext,
- thisNodeFormat,
- indent,
- thisItemString),
- PKIX_ERRORINSPRINTF);
- } else {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "%s",
- 0,
- &thisNodeFormat,
- plContext),
- PKIX_ERRORCREATINGFORMATSTRING);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&resultString,
- plContext,
- thisNodeFormat,
- thisItemString),
- PKIX_ERRORINSPRINTF);
- }
-
- PKIX_DECREF(thisItemString);
- thisItemString = resultString;
-
- /* if no children, we are done */
- if (rootNode->children) {
- PKIX_CHECK(PKIX_List_GetLength
- (rootNode->children, &numberOfChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- if (numberOfChildren != 0) {
- /*
- * We create a string for each child in turn,
- * concatenating them to thisItemString.
- */
-
- /* Prepare an indent string for each child */
- if (indent) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "%s. ",
- 0,
- &nextIndentFormat,
- plContext),
- PKIX_ERRORCREATINGFORMATSTRING);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&nextIndentString,
- plContext,
- nextIndentFormat,
- indent),
- PKIX_ERRORINSPRINTF);
- } else {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- ". ",
- 0,
- &nextIndentString,
- plContext),
- PKIX_ERRORCREATINGINDENTSTRING);
- }
-
- /* Prepare the format for concatenation. */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "%s\n%s",
- 0,
- &childrenFormat,
- plContext),
- PKIX_ERRORCREATINGFORMATSTRING);
-
- for (childIndex = 0;
- childIndex < numberOfChildren;
- childIndex++) {
- PKIX_CHECK(PKIX_List_GetItem
- (rootNode->children,
- childIndex,
- (PKIX_PL_Object **)&childNode,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_VerifyNode_ToString_Helper
- (childNode,
- nextIndentString,
- &childString,
- plContext),
- PKIX_ERRORCREATINGCHILDSTRING);
-
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&resultString,
- plContext,
- childrenFormat,
- thisItemString,
- childString),
- PKIX_ERRORINSPRINTF);
-
- PKIX_DECREF(childNode);
- PKIX_DECREF(childString);
- PKIX_DECREF(thisItemString);
-
- thisItemString = resultString;
- }
- }
-
- *pTreeString = thisItemString;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(thisItemString);
- }
-
- PKIX_DECREF(nextIndentFormat);
- PKIX_DECREF(thisNodeFormat);
- PKIX_DECREF(childrenFormat);
- PKIX_DECREF(nextIndentString);
- PKIX_DECREF(childString);
- PKIX_DECREF(childNode);
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_VerifyNode_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pTreeString,
- void *plContext)
-{
- PKIX_VerifyNode *rootNode = NULL;
- PKIX_PL_String *resultString = NULL;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString");
-
- PKIX_NULLCHECK_TWO(object, pTreeString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext),
- PKIX_OBJECTNOTVERIFYNODE);
-
- rootNode = (PKIX_VerifyNode *)object;
-
- PKIX_CHECK(pkix_VerifyNode_ToString_Helper
- (rootNode, NULL, &resultString, plContext),
- PKIX_ERRORCREATINGSUBTREESTRING);
-
- *pTreeString = resultString;
-
-cleanup:
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_VerifyNode_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_VerifyNode *node = NULL;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Destroy");
-
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext),
- PKIX_OBJECTNOTVERIFYNODE);
-
- node = (PKIX_VerifyNode*)object;
-
- PKIX_DECREF(node->verifyCert);
- PKIX_DECREF(node->children);
- PKIX_DECREF(node->error);
-
- node->depth = 0;
-
-cleanup:
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_SingleVerifyNode_Hashcode
- * DESCRIPTION:
- *
- * Computes the hashcode of the attributes of the VerifyNode pointed to by
- * "node", other than its parents and children, and stores the result at
- * "pHashcode".
- *
- * PARAMETERS:
- * "node"
- * Address of VerifyNode to be hashcoded; must be non-NULL
- * "pHashcode"
- * Address where UInt32 result will be stored; must be non-NULL
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if function succeeds
- * Returns a VerifyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in a fatal way
- */
-static PKIX_Error *
-pkix_SingleVerifyNode_Hashcode(
- PKIX_VerifyNode *node,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_UInt32 errorHash = 0;
- PKIX_UInt32 nodeHash = 0;
-
- PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Hashcode");
- PKIX_NULLCHECK_TWO(node, pHashcode);
-
- PKIX_HASHCODE
- (node->verifyCert,
- &nodeHash,
- plContext,
- PKIX_FAILUREHASHINGCERT);
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)node->error,
- &errorHash,
- plContext),
- PKIX_FAILUREHASHINGERROR);
-
- nodeHash = 31*nodeHash + errorHash;
- *pHashcode = nodeHash;
-
-cleanup:
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_VerifyNode_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_VerifyNode *node = NULL;
- PKIX_UInt32 childrenHash = 0;
- PKIX_UInt32 nodeHash = 0;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_VERIFYNODE_TYPE, plContext),
- PKIX_OBJECTNOTVERIFYNODE);
-
- node = (PKIX_VerifyNode *)object;
-
- PKIX_CHECK(pkix_SingleVerifyNode_Hashcode
- (node, &nodeHash, plContext),
- PKIX_SINGLEVERIFYNODEHASHCODEFAILED);
-
- PKIX_HASHCODE
- (node->children,
- &childrenHash,
- plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- nodeHash = 31*nodeHash + childrenHash;
-
- *pHashcode = nodeHash;
-
-cleanup:
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_SingleVerifyNode_Equals
- * DESCRIPTION:
- *
- * Compares for equality the components of the VerifyNode pointed to by
- * "firstPN", other than its parents and children, with those of the
- * VerifyNode pointed to by "secondPN" and stores the result at "pResult"
- * (PKIX_TRUE if equal; PKIX_FALSE if not).
- *
- * PARAMETERS:
- * "firstPN"
- * Address of first of the VerifyNodes to be compared; must be non-NULL
- * "secondPN"
- * Address of second of the VerifyNodes to be compared; must be non-NULL
- * "pResult"
- * Address where Boolean will be stored; must be non-NULL
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if function succeeds
- * Returns a VerifyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in a fatal way
- */
-static PKIX_Error *
-pkix_SingleVerifyNode_Equals(
- PKIX_VerifyNode *firstVN,
- PKIX_VerifyNode *secondVN,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_Boolean compResult = PKIX_FALSE;
-
- PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Equals");
- PKIX_NULLCHECK_THREE(firstVN, secondVN, pResult);
-
- /* If both references are identical, they must be equal */
- if (firstVN == secondVN) {
- compResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * It seems we have to do the comparisons. Do
- * the easiest ones first.
- */
- if ((firstVN->depth) != (secondVN->depth)) {
- goto cleanup;
- }
-
- /* These fields must be non-NULL */
- PKIX_NULLCHECK_TWO(firstVN->verifyCert, secondVN->verifyCert);
-
- PKIX_EQUALS
- (firstVN->verifyCert,
- secondVN->verifyCert,
- &compResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (compResult == PKIX_FALSE) {
- goto cleanup;
- }
-
- PKIX_EQUALS
- (firstVN->error,
- secondVN->error,
- &compResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
-cleanup:
-
- *pResult = compResult;
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_VerifyNode_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_VerifyNode *firstVN = NULL;
- PKIX_VerifyNode *secondVN = NULL;
- PKIX_UInt32 secondType;
- PKIX_Boolean compResult = PKIX_FALSE;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a VerifyNode */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_VERIFYNODE_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTVERIFYNODE);
-
- /*
- * Since we know firstObject is a VerifyNode,
- * if both references are identical, they must be equal
- */
- if (firstObject == secondObject){
- compResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a VerifyNode, we
- * don't throw an error. We simply return FALSE.
- */
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- if (secondType != PKIX_VERIFYNODE_TYPE) {
- goto cleanup;
- }
-
- /*
- * Oh, well, we have to do the comparisons. Do
- * the easiest ones first.
- */
- firstVN = (PKIX_VerifyNode *)firstObject;
- secondVN = (PKIX_VerifyNode *)secondObject;
-
- PKIX_CHECK(pkix_SingleVerifyNode_Equals
- (firstVN, secondVN, &compResult, plContext),
- PKIX_SINGLEVERIFYNODEEQUALSFAILED);
-
- if (compResult == PKIX_FALSE) {
- goto cleanup;
- }
-
- PKIX_EQUALS
- (firstVN->children,
- secondVN->children,
- &compResult,
- plContext,
- PKIX_OBJECTEQUALSFAILEDONCHILDREN);
-
-cleanup:
-
- *pResult = compResult;
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_DuplicateHelper
- * DESCRIPTION:
- *
- * Duplicates the VerifyNode whose address is pointed to by "original",
- * and stores the result at "pNewNode", if a non-NULL pointer is provided
- * for "pNewNode". In addition, the created VerifyNode is added as a child
- * to "parent", if a non-NULL pointer is provided for "parent". Then this
- * function is called recursively to duplicate each of the children of
- * "original". At the top level this function is called with a null
- * "parent" and a non-NULL "pNewNode". Below the top level "parent" will
- * be non-NULL and "pNewNode" will be NULL.
- *
- * PARAMETERS:
- * "original"
- * Address of VerifyNode to be copied; must be non-NULL
- * "parent"
- * Address of VerifyNode to which the created node is to be added as a
- * child; NULL for the top-level call and non-NULL below the top level
- * "pNewNode"
- * Address to store the node created; should be NULL if "parent" is
- * non-NULL and vice versa
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if function succeeds
- * Returns a VerifyNode Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in a fatal way
- */
-static PKIX_Error *
-pkix_VerifyNode_DuplicateHelper(
- PKIX_VerifyNode *original,
- PKIX_VerifyNode *parent,
- PKIX_VerifyNode **pNewNode,
- void *plContext)
-{
- PKIX_UInt32 numChildren = 0;
- PKIX_UInt32 childIndex = 0;
- PKIX_List *children = NULL; /* List of PKIX_VerifyNode */
- PKIX_VerifyNode *copy = NULL;
- PKIX_VerifyNode *child = NULL;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_DuplicateHelper");
-
- PKIX_NULLCHECK_TWO
- (original, original->verifyCert);
-
- /*
- * These components are immutable, so copying the pointers
- * is sufficient. The create function increments the reference
- * counts as it stores the pointers into the new object.
- */
- PKIX_CHECK(pkix_VerifyNode_Create
- (original->verifyCert,
- original->depth,
- original->error,
- &copy,
- plContext),
- PKIX_VERIFYNODECREATEFAILED);
-
- /* Are there any children to duplicate? */
- children = original->children;
-
- if (children) {
- PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- for (childIndex = 0; childIndex < numChildren; childIndex++) {
- PKIX_CHECK(PKIX_List_GetItem
- (children,
- childIndex,
- (PKIX_PL_Object **)&child,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_VerifyNode_DuplicateHelper
- (child, copy, NULL, plContext),
- PKIX_VERIFYNODEDUPLICATEHELPERFAILED);
-
- PKIX_DECREF(child);
- }
-
- if (pNewNode) {
- *pNewNode = copy;
- copy = NULL; /* no DecRef if we give our handle away */
- }
-
-cleanup:
- PKIX_DECREF(copy);
- PKIX_DECREF(child);
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_Duplicate
- * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_VerifyNode_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_VerifyNode *original = NULL;
- PKIX_VerifyNode *copy = NULL;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Duplicate");
-
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_VERIFYNODE_TYPE, plContext),
- PKIX_OBJECTNOTVERIFYNODE);
-
- original = (PKIX_VerifyNode *)object;
-
- PKIX_CHECK(pkix_VerifyNode_DuplicateHelper
- (original, NULL, &copy, plContext),
- PKIX_VERIFYNODEDUPLICATEHELPERFAILED);
-
- *pNewObject = (PKIX_PL_Object *)copy;
-
-cleanup:
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: pkix_VerifyNode_RegisterSelf
- * DESCRIPTION:
- *
- * Registers PKIX_VERIFYNODE_TYPE and its related
- * functions with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize,
- * which should only be called once, it is acceptable that
- * this function is not thread-safe.
- */
-PKIX_Error *
-pkix_VerifyNode_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_RegisterSelf");
-
- entry.description = "VerifyNode";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_VerifyNode);
- entry.destructor = pkix_VerifyNode_Destroy;
- entry.equalsFunction = pkix_VerifyNode_Equals;
- entry.hashcodeFunction = pkix_VerifyNode_Hashcode;
- entry.toStringFunction = pkix_VerifyNode_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_VerifyNode_Duplicate;
-
- systemClasses[PKIX_VERIFYNODE_TYPE] = entry;
-
- PKIX_RETURN(VERIFYNODE);
-}
-
-/* --Public-VerifyNode-Functions----------------------------------- */
-
-/*
- * FUNCTION: PKIX_VerifyNode_SetError
- * DESCRIPTION:
- *
- * This function sets the Error field of the VerifyNode pointed to by "node"
- * to contain the Error pointed to by "error".
- *
- * PARAMETERS:
- * "node"
- * The address of the VerifyNode to be modified. Must be non-NULL.
- * "error"
- * The address of the Error to be stored.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_VerifyNode_SetError(
- PKIX_VerifyNode *node,
- PKIX_Error *error,
- void *plContext)
-{
-
- PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_SetError");
-
- PKIX_NULLCHECK_TWO(node, error);
-
- PKIX_DECREF(node->error); /* should have been NULL */
- PKIX_INCREF(error);
- node->error = error;
-
-cleanup:
- PKIX_RETURN(VERIFYNODE);
-}
-
-/*
- * FUNCTION: PKIX_VerifyNode_FindError
- * DESCRIPTION:
- *
- * Finds meaningful error in the log. For now, just returns the first
- * error it finds in. In the future the function should be changed to
- * return a top priority error.
- *
- * PARAMETERS:
- * "node"
- * The address of the VerifyNode to be modified. Must be non-NULL.
- * "error"
- * The address of a pointer the error will be returned to.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_VerifyNode_FindError(
- PKIX_VerifyNode *node,
- PKIX_Error **error,
- void *plContext)
-{
- PKIX_VerifyNode *childNode = NULL;
-
- PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_FindError");
-
- /* Make sure the return address is initialized with NULL */
- PKIX_DECREF(*error);
-
- if (!node)
- goto cleanup;
-
- /* First, try to get error from lowest level. */
- if (node->children) {
- PKIX_UInt32 length = 0;
- PKIX_UInt32 index = 0;
-
- PKIX_CHECK(
- PKIX_List_GetLength(node->children, &length,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
- for (index = 0;index < length;index++) {
- PKIX_CHECK(
- PKIX_List_GetItem(node->children, index,
- (PKIX_PL_Object**)&childNode, plContext),
- PKIX_LISTGETITEMFAILED);
- if (!childNode)
- continue;
- PKIX_CHECK(
- pkix_VerifyNode_FindError(childNode, error,
- plContext),
- PKIX_VERIFYNODEFINDERRORFAILED);
- PKIX_DECREF(childNode);
- if (*error) {
- goto cleanup;
- }
- }
- }
-
- if (node->error && node->error->plErr) {
- PKIX_INCREF(node->error);
- *error = node->error;
- }
-
-cleanup:
- PKIX_DECREF(childNode);
-
- PKIX_RETURN(VERIFYNODE);
-}
diff --git a/security/nss/lib/libpkix/pkix/results/pkix_verifynode.h b/security/nss/lib/libpkix/pkix/results/pkix_verifynode.h
deleted file mode 100755
index c943ae4dd..000000000
--- a/security/nss/lib/libpkix/pkix/results/pkix_verifynode.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_verifynode.h
- *
- * VerifyNode Type Definitions
- *
- */
-
-#ifndef _PKIX_VERIFYNODE_H
-#define _PKIX_VERIFYNODE_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This structure reflects the contents of a verify node...
- */
-struct PKIX_VerifyNodeStruct {
- PKIX_PL_Cert *verifyCert;
- PKIX_List *children; /* VerifyNodes */
- PKIX_UInt32 depth;
- PKIX_Error *error;
-};
-
-PKIX_Error *
-pkix_SingleVerifyNode_ToString(
- PKIX_VerifyNode *node,
- PKIX_PL_String **pString,
- void *plContext);
-
-PKIX_Error *
-pkix_VerifyNode_Create(
- PKIX_PL_Cert *verifyCert,
- PKIX_UInt32 depth,
- PKIX_Error *error,
- PKIX_VerifyNode **pObject,
- void *plContext);
-
-PKIX_Error *
-pkix_VerifyNode_AddToChain(
- PKIX_VerifyNode *parentNode,
- PKIX_VerifyNode *child,
- void *plContext);
-
-PKIX_Error *
-pkix_VerifyNode_AddToTree(
- PKIX_VerifyNode *parentNode,
- PKIX_VerifyNode *child,
- void *plContext);
-
-PKIX_Error *
-pkix_VerifyNode_SetError(
- PKIX_VerifyNode *node,
- PKIX_Error *error,
- void *plContext);
-
-PKIX_Error *
-pkix_VerifyNode_RegisterSelf(
- void *plContext);
-
-PKIX_Error *
-pkix_VerifyNode_FindError(
- PKIX_VerifyNode *node,
- PKIX_Error **error,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_VERIFYNODE_H */
diff --git a/security/nss/lib/libpkix/pkix/store/Makefile b/security/nss/lib/libpkix/pkix/store/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix/store/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix/store/config.mk b/security/nss/lib/libpkix/pkix/store/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix/store/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix/store/manifest.mn b/security/nss/lib/libpkix/pkix/store/manifest.mn
deleted file mode 100755
index 37b5dcdce..000000000
--- a/security/nss/lib/libpkix/pkix/store/manifest.mn
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_store.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_store.c \
- $(NULL)
-
-LIBRARY_NAME = pkixstore
-
diff --git a/security/nss/lib/libpkix/pkix/store/pkix_store.c b/security/nss/lib/libpkix/pkix/store/pkix_store.c
deleted file mode 100755
index 31c21ea16..000000000
--- a/security/nss/lib/libpkix/pkix/store/pkix_store.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_store.c
- *
- * CertStore Function Definitions
- *
- */
-
-#include "pkix_store.h"
-
-/* --CertStore-Private-Functions----------------------------------------- */
-
-/*
- * FUNCTION: pkix_CertStore_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CertStore_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_CertStore *certStore = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_CertStore_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a CertStore object */
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSTORE_TYPE, plContext),
- PKIX_OBJECTNOTCERTSTORE);
-
- certStore = (PKIX_CertStore *)object;
-
- certStore->certCallback = NULL;
- certStore->crlCallback = NULL;
- certStore->certContinue = NULL;
- certStore->crlContinue = NULL;
- certStore->trustCallback = NULL;
-
- PKIX_DECREF(certStore->certStoreContext);
-
-cleanup:
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_CertStore_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CertStore_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_CertStore *certStore = NULL;
- PKIX_UInt32 tempHash = 0;
-
- PKIX_ENTER(CERTSTORE, "pkix_CertStore_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTSTORE_TYPE, plContext),
- PKIX_OBJECTNOTCERTSTORE);
-
- certStore = (PKIX_CertStore *)object;
-
- if (certStore->certStoreContext) {
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *) certStore->certStoreContext,
- &tempHash,
- plContext),
- PKIX_CERTSTOREHASHCODEFAILED);
- }
-
- *pHashcode = (PKIX_UInt32) certStore->certCallback +
- (PKIX_UInt32) certStore->crlCallback +
- (PKIX_UInt32) certStore->certContinue +
- (PKIX_UInt32) certStore->crlContinue +
- (PKIX_UInt32) certStore->trustCallback +
- (tempHash << 7);
-
-cleanup:
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_CertStore_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_CertStore_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PKIX_CertStore *firstCS = NULL;
- PKIX_CertStore *secondCS = NULL;
- PKIX_Boolean cmpResult = PKIX_FALSE;
-
- PKIX_ENTER(CERTSTORE, "pkix_CertStore_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- PKIX_CHECK(pkix_CheckTypes
- (firstObject, secondObject, PKIX_CERTSTORE_TYPE, plContext),
- PKIX_ARGUMENTSNOTDATES);
-
- firstCS = (PKIX_CertStore *)firstObject;
- secondCS = (PKIX_CertStore *)secondObject;
-
- cmpResult = (firstCS->certCallback == secondCS->certCallback) &&
- (firstCS->crlCallback == secondCS->crlCallback) &&
- (firstCS->certContinue == secondCS->certContinue) &&
- (firstCS->crlContinue == secondCS->crlContinue) &&
- (firstCS->trustCallback == secondCS->trustCallback);
-
- if (cmpResult &&
- (firstCS->certStoreContext != secondCS->certStoreContext)) {
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *) firstCS->certStoreContext,
- (PKIX_PL_Object *) secondCS->certStoreContext,
- &cmpResult,
- plContext),
- PKIX_CERTSTOREEQUALSFAILED);
- }
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_CertStore_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERTSTORE_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_CertStore_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTSTORE, "pkix_CertStore_RegisterSelf");
-
- entry.description = "CertStore";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_CertStore);
- entry.destructor = pkix_CertStore_Destroy;
- entry.equalsFunction = pkix_CertStore_Equals;
- entry.hashcodeFunction = pkix_CertStore_Hashcode;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_CERTSTORE_TYPE] = entry;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/* --CertStore-Public-Functions------------------------------------------ */
-
-/*
- * FUNCTION: PKIX_CertStore_Create (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_Create(
- PKIX_CertStore_CertCallback certCallback,
- PKIX_CertStore_CRLCallback crlCallback,
- PKIX_CertStore_CertContinueFunction certContinue,
- PKIX_CertStore_CrlContinueFunction crlContinue,
- PKIX_CertStore_CheckTrustCallback trustCallback,
- PKIX_CertStore_ImportCrlCallback importCrlCallback,
- PKIX_CertStore_CheckRevokationByCrlCallback checkRevByCrlCallback,
- PKIX_PL_Object *certStoreContext,
- PKIX_Boolean cacheFlag,
- PKIX_Boolean localFlag,
- PKIX_CertStore **pStore,
- void *plContext)
-{
- PKIX_CertStore *certStore = NULL;
-
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_Create");
- PKIX_NULLCHECK_THREE(certCallback, crlCallback, pStore);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTSTORE_TYPE,
- sizeof (PKIX_CertStore),
- (PKIX_PL_Object **)&certStore,
- plContext),
- PKIX_COULDNOTCREATECERTSTOREOBJECT);
-
- certStore->certCallback = certCallback;
- certStore->crlCallback = crlCallback;
- certStore->certContinue = certContinue;
- certStore->crlContinue = crlContinue;
- certStore->trustCallback = trustCallback;
- certStore->importCrlCallback = importCrlCallback;
- certStore->checkRevByCrlCallback = checkRevByCrlCallback;
- certStore->cacheFlag = cacheFlag;
- certStore->localFlag = localFlag;
-
- PKIX_INCREF(certStoreContext);
- certStore->certStoreContext = certStoreContext;
-
- *pStore = certStore;
- certStore = NULL;
-
-cleanup:
-
- PKIX_DECREF(certStore);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_GetCertCallback (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_GetCertCallback(
- PKIX_CertStore *store,
- PKIX_CertStore_CertCallback *pCallback,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_GetCertCallback");
- PKIX_NULLCHECK_TWO(store, pCallback);
-
- *pCallback = store->certCallback;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_GetCRLCallback (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_GetCRLCallback(
- PKIX_CertStore *store,
- PKIX_CertStore_CRLCallback *pCallback,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_GetCRLCallback");
- PKIX_NULLCHECK_TWO(store, pCallback);
-
- *pCallback = store->crlCallback;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_CertContinue (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_CertContinue(
- PKIX_CertStore *store,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *verifyNode,
- void **pNBIOContext,
- PKIX_List **pCertList,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_CertContinue");
- PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCertList);
-
- PKIX_CHECK(store->certContinue
- (store, selector, verifyNode,
- pNBIOContext, pCertList, plContext),
- PKIX_CERTSTORECERTCONTINUEFUNCTIONFAILED);
-
-cleanup:
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_CrlContinue (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_CrlContinue(
- PKIX_CertStore *store,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrlList,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_CrlContinue");
- PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCrlList);
-
- PKIX_CHECK(store->crlContinue
- (store, selector, pNBIOContext, pCrlList, plContext),
- PKIX_CERTSTORECRLCONTINUEFAILED);
-
-cleanup:
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_GetTrustCallback (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_GetTrustCallback(
- PKIX_CertStore *store,
- PKIX_CertStore_CheckTrustCallback *pCallback,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_GetTrustCallback");
- PKIX_NULLCHECK_TWO(store, pCallback);
-
- *pCallback = store->trustCallback;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_GetImportCrlCallback (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_GetImportCrlCallback(
- PKIX_CertStore *store,
- PKIX_CertStore_ImportCrlCallback *pCallback,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_GetTrustCallback");
- PKIX_NULLCHECK_TWO(store, pCallback);
-
- *pCallback = store->importCrlCallback;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_GetCheckRevByCrl (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_GetCrlCheckerFn(
- PKIX_CertStore *store,
- PKIX_CertStore_CheckRevokationByCrlCallback *pCallback,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_GetTrustCallback");
- PKIX_NULLCHECK_TWO(store, pCallback);
-
- *pCallback = store->checkRevByCrlCallback;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_GetCertStoreContext
- * (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_GetCertStoreContext(
- PKIX_CertStore *store,
- PKIX_PL_Object **pCertStoreContext,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_GetCertStoreContext");
- PKIX_NULLCHECK_TWO(store, pCertStoreContext);
-
- PKIX_INCREF(store->certStoreContext);
- *pCertStoreContext = store->certStoreContext;
-
-cleanup:
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_GetCertStoreCacheFlag
- * (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_GetCertStoreCacheFlag(
- PKIX_CertStore *store,
- PKIX_Boolean *pCacheFlag,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_GetCertStoreCacheFlag");
- PKIX_NULLCHECK_TWO(store, pCacheFlag);
-
- *pCacheFlag = store->cacheFlag;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_CertStore_GetLocalFlag
- * (see comments in pkix_certstore.h)
- */
-PKIX_Error *
-PKIX_CertStore_GetLocalFlag(
- PKIX_CertStore *store,
- PKIX_Boolean *pLocalFlag,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "PKIX_CertStore_GetLocalFlag");
- PKIX_NULLCHECK_TWO(store, pLocalFlag);
-
- *pLocalFlag = store->localFlag;
-
- PKIX_RETURN(CERTSTORE);
-}
diff --git a/security/nss/lib/libpkix/pkix/store/pkix_store.h b/security/nss/lib/libpkix/pkix/store/pkix_store.h
deleted file mode 100755
index 9d116ffbd..000000000
--- a/security/nss/lib/libpkix/pkix/store/pkix_store.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_store.h
- *
- * CertStore Object Type Definition
- *
- */
-
-#ifndef _PKIX_STORE_H
-#define _PKIX_STORE_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_CertStoreStruct {
- PKIX_CertStore_CertCallback certCallback;
- PKIX_CertStore_CRLCallback crlCallback;
- PKIX_CertStore_CertContinueFunction certContinue;
- PKIX_CertStore_CrlContinueFunction crlContinue;
- PKIX_CertStore_CheckTrustCallback trustCallback;
- PKIX_CertStore_ImportCrlCallback importCrlCallback;
- PKIX_CertStore_CheckRevokationByCrlCallback checkRevByCrlCallback;
- PKIX_PL_Object *certStoreContext;
- PKIX_Boolean cacheFlag;
- PKIX_Boolean localFlag; /* TRUE if CertStore is local */
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_CertStore_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_STORE_H */
diff --git a/security/nss/lib/libpkix/pkix/top/Makefile b/security/nss/lib/libpkix/pkix/top/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix/top/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix/top/config.mk b/security/nss/lib/libpkix/pkix/top/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix/top/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix/top/manifest.mn b/security/nss/lib/libpkix/pkix/top/manifest.mn
deleted file mode 100755
index bb7a600b3..000000000
--- a/security/nss/lib/libpkix/pkix/top/manifest.mn
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_build.h \
- pkix_lifecycle.h \
- pkix_validate.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_validate.c \
- pkix_lifecycle.c \
- pkix_build.c \
- $(NULL)
-
-LIBRARY_NAME = pkixtop
-
diff --git a/security/nss/lib/libpkix/pkix/top/pkix_build.c b/security/nss/lib/libpkix/pkix/top/pkix_build.c
deleted file mode 100755
index 574fcfbbf..000000000
--- a/security/nss/lib/libpkix/pkix/top/pkix_build.c
+++ /dev/null
@@ -1,3821 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_build.c
- *
- * Top level buildChain function
- *
- */
-
-/* #define PKIX_BUILDDEBUG 1 */
-/* #define PKIX_FORWARDBUILDERSTATEDEBUG 1 */
-
-#include "pkix_build.h"
-
-extern PRLogModuleInfo *pkixLog;
-
-/*
- * List of critical extension OIDs associate with what build chain has
- * checked. Those OIDs need to be removed from the unresolved critical
- * extension OIDs list manually (instead of by checker automatically).
- */
-static SECOidTag buildCheckedCritExtOIDs[] = {
- PKIX_CERTKEYUSAGE_OID,
- PKIX_CERTSUBJALTNAME_OID,
- PKIX_BASICCONSTRAINTS_OID,
- PKIX_NAMECONSTRAINTS_OID,
- PKIX_EXTENDEDKEYUSAGE_OID,
- PKIX_NSCERTTYPE_OID,
- PKIX_UNKNOWN_OID
-};
-
-/* --Private-ForwardBuilderState-Functions---------------------------------- */
-
-/*
- * FUNCTION: pkix_ForwardBuilderState_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ForwardBuilderState_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ForwardBuilderState *state = NULL;
-
- PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_FORWARDBUILDERSTATE_TYPE, plContext),
- PKIX_OBJECTNOTFORWARDBUILDERSTATE);
-
- state = (PKIX_ForwardBuilderState *)object;
-
- state->status = BUILD_INITIAL;
- state->traversedCACerts = 0;
- state->certStoreIndex = 0;
- state->numCerts = 0;
- state->numAias = 0;
- state->certIndex = 0;
- state->aiaIndex = 0;
- state->certCheckedIndex = 0;
- state->checkerIndex = 0;
- state->hintCertIndex = 0;
- state->numFanout = 0;
- state->numDepth = 0;
- state->reasonCode = 0;
- state->revCheckDelayed = PKIX_FALSE;
- state->canBeCached = PKIX_FALSE;
- state->useOnlyLocal = PKIX_FALSE;
- state->revChecking = PKIX_FALSE;
- state->usingHintCerts = PKIX_FALSE;
- state->certLoopingDetected = PKIX_FALSE;
- PKIX_DECREF(state->validityDate);
- PKIX_DECREF(state->prevCert);
- PKIX_DECREF(state->candidateCert);
- PKIX_DECREF(state->traversedSubjNames);
- PKIX_DECREF(state->trustChain);
- PKIX_DECREF(state->aia);
- PKIX_DECREF(state->candidateCerts);
- PKIX_DECREF(state->reversedCertChain);
- PKIX_DECREF(state->checkedCritExtOIDs);
- PKIX_DECREF(state->checkerChain);
- PKIX_DECREF(state->certSel);
- PKIX_DECREF(state->verifyNode);
- PKIX_DECREF(state->client);
-
- /*
- * If we ever add a child link we have to be careful not to have loops
- * in the Destroy process. But with one-way links we should be okay.
- */
- if (state->parentState == NULL) {
- state->buildConstants.numAnchors = 0;
- state->buildConstants.numCertStores = 0;
- state->buildConstants.numHintCerts = 0;
- state->buildConstants.procParams = 0;
- PKIX_DECREF(state->buildConstants.testDate);
- PKIX_DECREF(state->buildConstants.timeLimit);
- PKIX_DECREF(state->buildConstants.targetCert);
- PKIX_DECREF(state->buildConstants.targetPubKey);
- PKIX_DECREF(state->buildConstants.certStores);
- PKIX_DECREF(state->buildConstants.anchors);
- PKIX_DECREF(state->buildConstants.userCheckers);
- PKIX_DECREF(state->buildConstants.hintCerts);
- PKIX_DECREF(state->buildConstants.revChecker);
- PKIX_DECREF(state->buildConstants.aiaMgr);
- } else {
- PKIX_DECREF(state->parentState);
- }
-
-cleanup:
-
- PKIX_RETURN(FORWARDBUILDERSTATE);
-}
-
-/*
- * FUNCTION: pkix_ForwardBuilderState_Create
- *
- * DESCRIPTION:
- * Allocate and initialize a ForwardBuilderState.
- *
- * PARAMETERS
- * "traversedCACerts"
- * Number of CA certificates traversed.
- * "numFanout"
- * Number of Certs that can be considered at this level (0 = no limit)
- * "numDepth"
- * Number of additional levels that can be searched (0 = no limit)
- * "revCheckDelayed"
- * Boolean value indicating whether rev check is delayed until after
- * entire chain is built.
- * "canBeCached"
- * Boolean value indicating whether all certs on the chain can be cached.
- * "validityDate"
- * Address of Date at which build chain Certs' most restricted validity
- * time is kept. May be NULL.
- * "prevCert"
- * Address of Cert just traversed. Must be non-NULL.
- * "traversedSubjNames"
- * Address of List of GeneralNames that have been traversed.
- * Must be non-NULL.
- * "trustChain"
- * Address of List of certificates traversed. Must be non-NULL.
- * "parentState"
- * Address of previous ForwardBuilderState
- * "pState"
- * Address where ForwardBuilderState will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_ForwardBuilderState_Create(
- PKIX_Int32 traversedCACerts,
- PKIX_UInt32 numFanout,
- PKIX_UInt32 numDepth,
- PKIX_Boolean revCheckDelayed,
- PKIX_Boolean canBeCached,
- PKIX_PL_Date *validityDate,
- PKIX_PL_Cert *prevCert,
- PKIX_List *traversedSubjNames,
- PKIX_List *trustChain,
- PKIX_ForwardBuilderState *parentState,
- PKIX_ForwardBuilderState **pState,
- void *plContext)
-{
- PKIX_ForwardBuilderState *state = NULL;
-
- PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_Create");
- PKIX_NULLCHECK_FOUR(prevCert, traversedSubjNames, pState, trustChain);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_FORWARDBUILDERSTATE_TYPE,
- sizeof (PKIX_ForwardBuilderState),
- (PKIX_PL_Object **)&state,
- plContext),
- PKIX_COULDNOTCREATEFORWARDBUILDERSTATEOBJECT);
-
- state->status = BUILD_INITIAL;
- state->traversedCACerts = traversedCACerts;
- state->certStoreIndex = 0;
- state->numCerts = 0;
- state->numAias = 0;
- state->certIndex = 0;
- state->aiaIndex = 0;
- state->certCheckedIndex = 0;
- state->checkerIndex = 0;
- state->hintCertIndex = 0;
- state->numFanout = numFanout;
- state->numDepth = numDepth;
- state->reasonCode = 0;
- state->revChecking = numDepth;
- state->revCheckDelayed = revCheckDelayed;
- state->canBeCached = canBeCached;
- state->useOnlyLocal = PKIX_TRUE;
- state->revChecking = PKIX_FALSE;
- state->usingHintCerts = PKIX_FALSE;
- state->certLoopingDetected = PKIX_FALSE;
-
- PKIX_INCREF(validityDate);
- state->validityDate = validityDate;
-
- PKIX_INCREF(prevCert);
- state->prevCert = prevCert;
-
- state->candidateCert = NULL;
-
- PKIX_INCREF(traversedSubjNames);
- state->traversedSubjNames = traversedSubjNames;
-
- PKIX_INCREF(trustChain);
- state->trustChain = trustChain;
-
- state->aia = NULL;
- state->candidateCerts = NULL;
- state->reversedCertChain = NULL;
- state->checkedCritExtOIDs = NULL;
- state->checkerChain = NULL;
- state->certSel = NULL;
- state->verifyNode = NULL;
- state->client = NULL;
-
- PKIX_INCREF(parentState);
- state->parentState = parentState;
-
- if (parentState != NULL) {
- state->buildConstants.numAnchors =
- parentState->buildConstants.numAnchors;
- state->buildConstants.numCertStores =
- parentState->buildConstants.numCertStores;
- state->buildConstants.numHintCerts =
- parentState->buildConstants.numHintCerts;
- state->buildConstants.maxFanout =
- parentState->buildConstants.maxFanout;
- state->buildConstants.maxDepth =
- parentState->buildConstants.maxDepth;
- state->buildConstants.maxTime =
- parentState->buildConstants.maxTime;
- state->buildConstants.procParams =
- parentState->buildConstants.procParams;
- state->buildConstants.testDate =
- parentState->buildConstants.testDate;
- state->buildConstants.timeLimit =
- parentState->buildConstants.timeLimit;
- state->buildConstants.targetCert =
- parentState->buildConstants.targetCert;
- state->buildConstants.targetPubKey =
- parentState->buildConstants.targetPubKey;
- state->buildConstants.certStores =
- parentState->buildConstants.certStores;
- state->buildConstants.anchors =
- parentState->buildConstants.anchors;
- state->buildConstants.userCheckers =
- parentState->buildConstants.userCheckers;
- state->buildConstants.hintCerts =
- parentState->buildConstants.hintCerts;
- state->buildConstants.revChecker =
- parentState->buildConstants.revChecker;
- state->buildConstants.aiaMgr =
- parentState->buildConstants.aiaMgr;
- state->buildConstants.trustOnlyUserAnchors =
- parentState->buildConstants.trustOnlyUserAnchors;
- }
-
- *pState = state;
- state = NULL;
-cleanup:
-
- PKIX_DECREF(state);
-
- PKIX_RETURN(FORWARDBUILDERSTATE);
-}
-
-/*
- * FUNCTION: pkix_Build_GetResourceLimits
- *
- * DESCRIPTION:
- * Retrieve Resource Limits from ProcessingParams and initialize them in
- * BuildConstants.
- *
- * PARAMETERS
- * "buildConstants"
- * Address of a BuildConstants structure containing objects and values
- * that remain constant throughout the building of a chain. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_GetResourceLimits(
- BuildConstants *buildConstants,
- void *plContext)
-{
- PKIX_ResourceLimits *resourceLimits = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_GetResourceLimits");
- PKIX_NULLCHECK_ONE(buildConstants);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetResourceLimits
- (buildConstants->procParams, &resourceLimits, plContext),
- PKIX_PROCESSINGPARAMSGETRESOURCELIMITSFAILED);
-
- buildConstants->maxFanout = 0;
- buildConstants->maxDepth = 0;
- buildConstants->maxTime = 0;
-
- if (resourceLimits) {
-
- PKIX_CHECK(PKIX_ResourceLimits_GetMaxFanout
- (resourceLimits, &buildConstants->maxFanout, plContext),
- PKIX_RESOURCELIMITSGETMAXFANOUTFAILED);
-
- PKIX_CHECK(PKIX_ResourceLimits_GetMaxDepth
- (resourceLimits, &buildConstants->maxDepth, plContext),
- PKIX_RESOURCELIMITSGETMAXDEPTHFAILED);
-
- PKIX_CHECK(PKIX_ResourceLimits_GetMaxTime
- (resourceLimits, &buildConstants->maxTime, plContext),
- PKIX_RESOURCELIMITSGETMAXTIMEFAILED);
- }
-
-cleanup:
-
- PKIX_DECREF(resourceLimits);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_ForwardBuilderState_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_ForwardBuilderState_ToString
- (PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_ForwardBuilderState *state = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *resultString = NULL;
- PKIX_PL_String *buildStatusString = NULL;
- PKIX_PL_String *validityDateString = NULL;
- PKIX_PL_String *prevCertString = NULL;
- PKIX_PL_String *candidateCertString = NULL;
- PKIX_PL_String *traversedSubjNamesString = NULL;
- PKIX_PL_String *trustChainString = NULL;
- PKIX_PL_String *candidateCertsString = NULL;
- PKIX_PL_String *certSelString = NULL;
- PKIX_PL_String *verifyNodeString = NULL;
- PKIX_PL_String *parentStateString = NULL;
- char *asciiFormat = "\n"
- "\t{buildStatus: \t%s\n"
- "\ttraversedCACerts: \t%d\n"
- "\tcertStoreIndex: \t%d\n"
- "\tnumCerts: \t%d\n"
- "\tnumAias: \t%d\n"
- "\tcertIndex: \t%d\n"
- "\taiaIndex: \t%d\n"
- "\tnumFanout: \t%d\n"
- "\tnumDepth: \t%d\n"
- "\treasonCode: \t%d\n"
- "\trevCheckDelayed: \t%d\n"
- "\tcanBeCached: \t%d\n"
- "\tuseOnlyLocal: \t%d\n"
- "\trevChecking: \t%d\n"
- "\tvalidityDate: \t%s\n"
- "\tprevCert: \t%s\n"
- "\tcandidateCert: \t%s\n"
- "\ttraversedSubjNames: \t%s\n"
- "\ttrustChain: \t%s\n"
- "\tcandidateCerts: \t%s\n"
- "\tcertSel: \t%s\n"
- "\tverifyNode: \t%s\n"
- "\tparentState: \t%s}\n";
- char *asciiStatus = NULL;
-
- PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_FORWARDBUILDERSTATE_TYPE, plContext),
- PKIX_OBJECTNOTFORWARDBUILDERSTATE);
-
- state = (PKIX_ForwardBuilderState *)object;
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- switch (state->status) {
- case BUILD_SHORTCUTPENDING: asciiStatus = "BUILD_SHORTCUTPENDING";
- break;
- case BUILD_INITIAL: asciiStatus = "BUILD_INITIAL";
- break;
- case BUILD_TRYAIA: asciiStatus = "BUILD_TRYAIA";
- break;
- case BUILD_AIAPENDING: asciiStatus = "BUILD_AIAPENDING";
- break;
- case BUILD_COLLECTINGCERTS: asciiStatus = "BUILD_COLLECTINGCERTS";
- break;
- case BUILD_GATHERPENDING: asciiStatus = "BUILD_GATHERPENDING";
- break;
- case BUILD_CERTVALIDATING: asciiStatus = "BUILD_CERTVALIDATING";
- break;
- case BUILD_ABANDONNODE: asciiStatus = "BUILD_ABANDONNODE";
- break;
- case BUILD_CRLPREP: asciiStatus = "BUILD_CRLPREP";
- break;
- case BUILD_CRL1: asciiStatus = "BUILD_CRL1";
- break;
- case BUILD_DATEPREP: asciiStatus = "BUILD_DATEPREP";
- break;
- case BUILD_CHECKTRUSTED: asciiStatus = "BUILD_CHECKTRUSTED";
- break;
- case BUILD_CHECKTRUSTED2: asciiStatus = "BUILD_CHECKTRUSTED2";
- break;
- case BUILD_ADDTOCHAIN: asciiStatus = "BUILD_ADDTOCHAIN";
- break;
- case BUILD_CRL2: asciiStatus = "BUILD_CRL2";
- break;
- case BUILD_VALCHAIN: asciiStatus = "BUILD_VALCHAIN";
- break;
- case BUILD_VALCHAIN2: asciiStatus = "BUILD_VALCHAIN2";
- break;
- case BUILD_EXTENDCHAIN: asciiStatus = "BUILD_EXTENDCHAIN";
- break;
- case BUILD_GETNEXTCERT: asciiStatus = "BUILD_GETNEXTCERT";
- break;
- default: asciiStatus = "INVALID STATUS";
- break;
- }
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, asciiStatus, 0, &buildStatusString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_TOSTRING
- (state->validityDate, &validityDateString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->prevCert, &prevCertString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->candidateCert, &candidateCertString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->traversedSubjNames,
- &traversedSubjNamesString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->trustChain, &trustChainString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->candidateCerts, &candidateCertsString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->certSel, &certSelString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->verifyNode, &verifyNodeString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (state->parentState, &parentStateString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&resultString,
- plContext,
- formatString,
- buildStatusString,
- (PKIX_Int32)state->traversedCACerts,
- (PKIX_UInt32)state->certStoreIndex,
- (PKIX_UInt32)state->numCerts,
- (PKIX_UInt32)state->numAias,
- (PKIX_UInt32)state->certIndex,
- (PKIX_UInt32)state->aiaIndex,
- (PKIX_UInt32)state->numFanout,
- (PKIX_UInt32)state->numDepth,
- (PKIX_UInt32)state->reasonCode,
- state->revCheckDelayed,
- state->canBeCached,
- state->useOnlyLocal,
- state->revChecking,
- validityDateString,
- prevCertString,
- candidateCertString,
- traversedSubjNamesString,
- trustChainString,
- candidateCertsString,
- certSelString,
- verifyNodeString,
- parentStateString),
- PKIX_SPRINTFFAILED);
-
- *pString = resultString;
-
-cleanup:
- PKIX_DECREF(formatString);
- PKIX_DECREF(buildStatusString);
- PKIX_DECREF(validityDateString);
- PKIX_DECREF(prevCertString);
- PKIX_DECREF(candidateCertString);
- PKIX_DECREF(traversedSubjNamesString);
- PKIX_DECREF(trustChainString);
- PKIX_DECREF(candidateCertsString);
- PKIX_DECREF(certSelString);
- PKIX_DECREF(verifyNodeString);
- PKIX_DECREF(parentStateString);
-
- PKIX_RETURN(FORWARDBUILDERSTATE);
-
-}
-
-/*
- * FUNCTION: pkix_ForwardBuilderState_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_FORWARDBUILDERSTATE_TYPE and its related functions
- * with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_ForwardBuilderState_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(FORWARDBUILDERSTATE,
- "pkix_ForwardBuilderState_RegisterSelf");
-
- entry.description = "ForwardBuilderState";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_ForwardBuilderState);
- entry.destructor = pkix_ForwardBuilderState_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = pkix_ForwardBuilderState_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_FORWARDBUILDERSTATE_TYPE] = entry;
-
- PKIX_RETURN(FORWARDBUILDERSTATE);
-}
-
-#if PKIX_FORWARDBUILDERSTATEDEBUG
-/*
- * FUNCTION: pkix_ForwardBuilderState_DumpState
- *
- * DESCRIPTION:
- * This function invokes the ToString function on the argument pointed to
- * by "state".
- * PARAMETERS:
- * "state"
- * The address of the ForwardBuilderState object. Must be non-NULL.
- *
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- */
-PKIX_Error *
-pkix_ForwardBuilderState_DumpState(
- PKIX_ForwardBuilderState *state,
- void *plContext)
-{
- PKIX_PL_String *stateString = NULL;
- char *stateAscii = NULL;
- PKIX_UInt32 length;
-
- PKIX_ENTER(FORWARDBUILDERSTATE,"pkix_ForwardBuilderState_DumpState");
- PKIX_NULLCHECK_ONE(state);
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)state, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)state, &stateString, plContext),
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stateString,
- PKIX_ESCASCII,
- (void **)&stateAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_DEBUG_ARG("In Phase 1: state = %s\n", stateAscii);
-
- PKIX_FREE(stateAscii);
- PKIX_DECREF(stateString);
-
-cleanup:
- PKIX_RETURN(FORWARDBUILDERSTATE);
-}
-#endif
-
-/*
- * FUNCTION: pkix_ForwardBuilderState_IsIOPending
- * DESCRIPTION:
- *
- * This function determines whether the state of the ForwardBuilderState
- * pointed to by "state" indicates I/O is in progress, and stores the Boolean
- * result at "pPending".
- *
- * PARAMETERS:
- * "state"
- * The address of the ForwardBuilderState object. Must be non-NULL.
- * "pPending"
- * The address at which the result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a ForwardBuilderState Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error*
-pkix_ForwardBuilderState_IsIOPending(
- PKIX_ForwardBuilderState *state,
- PKIX_Boolean *pPending,
- void *plContext)
-{
- PKIX_ENTER(FORWARDBUILDERSTATE, "pkix_ForwardBuilderState_IsIOPending");
- PKIX_NULLCHECK_TWO(state, pPending);
-
- if ((state->status == BUILD_GATHERPENDING) ||
- (state->status == BUILD_CRL1) ||
- (state->status == BUILD_CRL2) ||
- (state->status == BUILD_CHECKTRUSTED2) ||
- (state->status == BUILD_VALCHAIN2) ||
- (state->status == BUILD_AIAPENDING)) {
- *pPending = PKIX_TRUE;
- } else {
- *pPending = PKIX_FALSE;
- }
-
- PKIX_RETURN(FORWARDBUILDERSTATE);
-}
-
-/* --Private-BuildChain-Functions------------------------------------------- */
-
-/*
- * FUNCTION: pkix_Build_SortCertComparator
- * DESCRIPTION:
- *
- * This Function takes two Certificates cast in "obj1" and "obj2",
- * compares their validity NotAfter dates and returns the result at
- * "pResult". The comparison key(s) can be expanded by using other
- * data in the Certificate in the future.
- *
- * PARAMETERS:
- * "obj1"
- * Address of the PKIX_PL_Object that is a cast of PKIX_PL_Cert.
- * Must be non-NULL.
- * "obj2"
- * Address of the PKIX_PL_Object that is a cast of PKIX_PL_Cert.
- * Must be non-NULL.
- * "pResult"
- * Address where the comparison result is returned. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_SortCertComparator(
- PKIX_PL_Object *obj1,
- PKIX_PL_Object *obj2,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PKIX_PL_Date *date1 = NULL;
- PKIX_PL_Date *date2 = NULL;
- PKIX_Boolean result = PKIX_FALSE;
-
- PKIX_ENTER(BUILD, "pkix_Build_SortCertComparator");
- PKIX_NULLCHECK_THREE(obj1, obj2, pResult);
-
- /*
- * For sorting candidate certificates, we use NotAfter date as the
- * sorted key for now (can be expanded if desired in the future).
- *
- * In PKIX_BuildChain, the List of CertStores was reordered so that
- * trusted CertStores are ahead of untrusted CertStores. That sort, or
- * this one, could be taken out if it is determined that it doesn't help
- * performance, or in some way hinders the solution of choosing desired
- * candidates.
- */
-
- PKIX_CHECK(pkix_CheckType(obj1, PKIX_CERT_TYPE, plContext),
- PKIX_OBJECTNOTCERT);
- PKIX_CHECK(pkix_CheckType(obj2, PKIX_CERT_TYPE, plContext),
- PKIX_OBJECTNOTCERT);
-
- PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter
- ((PKIX_PL_Cert *)obj1, &date1, plContext),
- PKIX_CERTGETVALIDITYNOTAFTERFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter
- ((PKIX_PL_Cert *)obj2, &date2, plContext),
- PKIX_CERTGETVALIDITYNOTAFTERFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)date1,
- (PKIX_PL_Object *)date2,
- &result,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
-
- *pResult = !result;
-
-cleanup:
-
- PKIX_DECREF(date1);
- PKIX_DECREF(date2);
-
- PKIX_RETURN(BUILD);
-}
-
-/* This local error check macro */
-#define ERROR_CHECK(errCode) \
- if (pkixErrorResult) { \
- if (pkixLog) { \
- PR_LOG(pkixLog, PR_LOG_DEBUG, ("====> ERROR_CHECK code %s\n", #errCode)); \
- } \
- pkixTempErrorReceived = PKIX_TRUE; \
- pkixErrorClass = pkixErrorResult->errClass; \
- if (pkixErrorClass == PKIX_FATAL_ERROR) { \
- goto cleanup; \
- } \
- if (verifyNode) { \
- PKIX_DECREF(verifyNode->error); \
- PKIX_INCREF(pkixErrorResult); \
- verifyNode->error = pkixErrorResult; \
- } \
- pkixErrorCode = errCode; \
- goto cleanup; \
- }
-
-/*
- * FUNCTION: pkix_Build_VerifyCertificate
- * DESCRIPTION:
- *
- * Checks whether the previous Cert stored in the ForwardBuilderState pointed
- * to by "state" successfully chains, including signature verification, to the
- * candidate Cert also stored in "state", using the Boolean value in "trusted"
- * to determine whether "candidateCert" is trusted. Using the Boolean value in
- * "revocationChecking" for the existence of revocation checking, it sets
- * "pNeedsCRLChecking" to PKIX_TRUE if the candidate Cert needs to be checked
- * against Certificate Revocation Lists.
- *
- * First it checks whether "candidateCert" has already been traversed by
- * determining whether it is contained in the List of traversed Certs. It
- * checks the candidate Cert with user checkers, if any, in the List pointed to
- * by "userCheckers". It then runs the signature validation. Finally, it
- * determines the appropriate value for "pNeedsCRLChecking".
- *
- * If this Certificate fails verification, and state->verifyNode is non-NULL,
- * this function sets the Error code into the verifyNode.
- *
- * PARAMETERS:
- * "state"
- * Address of ForwardBuilderState to be used. Must be non-NULL.
- * "userCheckers"
- * Address of a List of CertChainCheckers to be used, if present, to
- * validate the candidateCert.
- * "revocationChecking"
- * Boolean indication of whether revocation checking is available, either
- * as a CertChainChecker or a List of RevocationCheckers.
- * "trusted"
- * Boolean value of trust for the candidate Cert
- * "pNeedsCRLChecking"
- * Address where Boolean CRL-checking-needed value is stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_VerifyCertificate(
- PKIX_ForwardBuilderState *state,
- PKIX_List *userCheckers,
- PKIX_Boolean revocationChecking,
- PKIX_Boolean *pTrusted,
- PKIX_Boolean *pNeedsCRLChecking,
- PKIX_VerifyNode *verifyNode,
- void *plContext)
-{
- PKIX_UInt32 numUserCheckers = 0;
- PKIX_UInt32 i = 0;
- PKIX_Boolean loopFound = PKIX_FALSE;
- PKIX_Boolean supportForwardChecking = PKIX_FALSE;
- PKIX_Boolean trusted = PKIX_FALSE;
- PKIX_PL_Cert *candidateCert = NULL;
- PKIX_PL_PublicKey *candidatePubKey = NULL;
- PKIX_CertChainChecker *userChecker = NULL;
- PKIX_CertChainChecker_CheckCallback checkerCheck = NULL;
- PKIX_Boolean trustOnlyUserAnchors = PKIX_FALSE;
- void *nbioContext = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_VerifyCertificate");
- PKIX_NULLCHECK_THREE(state, pTrusted, pNeedsCRLChecking);
- PKIX_NULLCHECK_THREE
- (state->candidateCerts, state->prevCert, state->trustChain);
-
- *pNeedsCRLChecking = PKIX_FALSE;
-
- PKIX_INCREF(state->candidateCert);
- candidateCert = state->candidateCert;
-
- if (state->buildConstants.numAnchors) {
- trustOnlyUserAnchors = state->buildConstants.trustOnlyUserAnchors;
- }
-
- PKIX_CHECK(
- PKIX_PL_Cert_IsCertTrusted(candidateCert,
- trustOnlyUserAnchors,
- &trusted, plContext),
- PKIX_CERTISCERTTRUSTEDFAILED);
-
- *pTrusted = trusted;
-
- /* check for loops */
- PKIX_CHECK(pkix_List_Contains
- (state->trustChain,
- (PKIX_PL_Object *)candidateCert,
- &loopFound,
- plContext),
- PKIX_LISTCONTAINSFAILED);
-
- if (loopFound) {
- if (verifyNode != NULL) {
- PKIX_Error *verifyError = NULL;
- PKIX_ERROR_CREATE
- (BUILD,
- PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED,
- verifyError);
- PKIX_DECREF(verifyNode->error);
- verifyNode->error = verifyError;
- }
- /* Even if error logged, still need to abort
- * if cert is not trusted. */
- if (!trusted) {
- PKIX_ERROR(PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED);
- }
- state->certLoopingDetected = PKIX_TRUE;
- }
-
- if (userCheckers != NULL) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (userCheckers, &numUserCheckers, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numUserCheckers; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (userCheckers,
- i,
- (PKIX_PL_Object **) &userChecker,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK
- (PKIX_CertChainChecker_IsForwardCheckingSupported
- (userChecker, &supportForwardChecking, plContext),
- PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED);
-
- if (supportForwardChecking == PKIX_TRUE) {
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCheckCallback
- (userChecker, &checkerCheck, plContext),
- PKIX_CERTCHAINCHECKERGETCHECKCALLBACKFAILED);
-
- pkixErrorResult =
- checkerCheck(userChecker, candidateCert, NULL,
- &nbioContext, plContext);
-
- ERROR_CHECK(PKIX_USERCHECKERCHECKFAILED);
- }
-
- PKIX_DECREF(userChecker);
- }
- }
-
- /* Check that public key of the trusted dsa cert has
- * dsa parameters */
- if (trusted) {
- PKIX_Boolean paramsNeeded = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
- (candidateCert, &candidatePubKey, plContext),
- PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
- PKIX_CHECK(PKIX_PL_PublicKey_NeedsDSAParameters
- (candidatePubKey, &paramsNeeded, plContext),
- PKIX_PUBLICKEYNEEDSDSAPARAMETERSFAILED);
- if (paramsNeeded) {
- PKIX_ERROR(PKIX_MISSINGDSAPARAMETERS);
- }
- }
-
-
- if (revocationChecking) {
- if (!trusted) {
- if (state->revCheckDelayed) {
- goto cleanup;
- } else {
- PKIX_Boolean isSelfIssued = PKIX_FALSE;
- PKIX_CHECK(
- pkix_IsCertSelfIssued(candidateCert, &isSelfIssued,
- plContext),
- PKIX_ISCERTSELFISSUEDFAILED);
- if (isSelfIssued) {
- state->revCheckDelayed = PKIX_TRUE;
- goto cleanup;
- }
- }
- }
- *pNeedsCRLChecking = PKIX_TRUE;
- }
-
-cleanup:
- PKIX_DECREF(candidateCert);
- PKIX_DECREF(candidatePubKey);
- PKIX_DECREF(userChecker);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_Build_ValidationCheckers
- * DESCRIPTION:
- *
- * Creates a List of Objects to be used in determining whether the List of
- * Certs pointed to by "certChain" successfully validates using the
- * ForwardBuilderState pointed to by "state", and the TrustAnchor pointed to by
- * "anchor". These objects are a reversed Cert Chain, consisting of the certs
- * in "certChain" in reversed order, suitable for presenting to the
- * CertChainCheckers; a List of critical extension OIDS that have already been
- * processed in forward building; a List of CertChainCheckers to be called, and
- * a List of RevocationCheckers to be called. These results are stored in
- * fields of "state".
- *
- * PARAMETERS:
- * "state"
- * Address of ForwardBuilderState to be used. Must be non-NULL.
- * "certChain"
- * Address of List of Certs to be validated. Must be non-NULL.
- * "anchor"
- * Address of TrustAnchor to be used. Must be non-NULL.
- * "addEkuChecker"
- * Boolean flags that tells to add eku checker to the list
- * of checkers. Only needs to be done for existing chain revalidation.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_ValidationCheckers(
- PKIX_ForwardBuilderState *state,
- PKIX_List *certChain,
- PKIX_TrustAnchor *anchor,
- PKIX_Boolean chainRevalidationStage,
- void *plContext)
-{
- PKIX_List *checkers = NULL;
- PKIX_List *initialPolicies = NULL;
- PKIX_List *reversedCertChain = NULL;
- PKIX_List *buildCheckedCritExtOIDsList = NULL;
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_PL_Cert *trustedCert = NULL;
- PKIX_PL_PublicKey *trustedPubKey = NULL;
- PKIX_CertChainChecker *sigChecker = NULL;
- PKIX_CertChainChecker *policyChecker = NULL;
- PKIX_CertChainChecker *userChecker = NULL;
- PKIX_CertChainChecker *checker = NULL;
- PKIX_CertSelector *certSelector = NULL;
- PKIX_List *userCheckerExtOIDs = NULL;
- PKIX_PL_OID *oid = NULL;
- PKIX_Boolean supportForwardChecking = PKIX_FALSE;
- PKIX_Boolean policyQualifiersRejected = PKIX_FALSE;
- PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE;
- PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE;
- PKIX_Boolean initialExplicitPolicy = PKIX_FALSE;
- PKIX_UInt32 numChainCerts;
- PKIX_UInt32 numCertCheckers;
- PKIX_UInt32 i;
-
- PKIX_ENTER(BUILD, "pkix_Build_ValidationCheckers");
- PKIX_NULLCHECK_THREE(state, certChain, anchor);
-
- PKIX_CHECK(PKIX_List_Create(&checkers, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_ReverseList
- (certChain, &reversedCertChain, plContext),
- PKIX_LISTREVERSELISTFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength
- (reversedCertChain, &numChainCerts, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- procParams = state->buildConstants.procParams;
-
- /* Do need to add a number of checker to revalidate
- * a built chain. KU, EKU, CertType and Validity Date
- * get checked by certificate selector during chain
- * construction, but needed to be checked for chain from
- * the cache.*/
- if (chainRevalidationStage) {
- PKIX_CHECK(pkix_ExpirationChecker_Initialize
- (state->buildConstants.testDate, &checker, plContext),
- PKIX_EXPIRATIONCHECKERINITIALIZEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)checker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_DECREF(checker);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
- (procParams, &certSelector, plContext),
- PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
-
- PKIX_CHECK(pkix_TargetCertChecker_Initialize
- (certSelector, numChainCerts, &checker, plContext),
- PKIX_EXPIRATIONCHECKERINITIALIZEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)checker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_DECREF(checker);
- }
-
- PKIX_CHECK(PKIX_ProcessingParams_GetInitialPolicies
- (procParams, &initialPolicies, plContext),
- PKIX_PROCESSINGPARAMSGETINITIALPOLICIESFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetPolicyQualifiersRejected
- (procParams, &policyQualifiersRejected, plContext),
- PKIX_PROCESSINGPARAMSGETPOLICYQUALIFIERSREJECTEDFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_IsPolicyMappingInhibited
- (procParams, &initialPolicyMappingInhibit, plContext),
- PKIX_PROCESSINGPARAMSISPOLICYMAPPINGINHIBITEDFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_IsAnyPolicyInhibited
- (procParams, &initialAnyPolicyInhibit, plContext),
- PKIX_PROCESSINGPARAMSISANYPOLICYINHIBITEDFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_IsExplicitPolicyRequired
- (procParams, &initialExplicitPolicy, plContext),
- PKIX_PROCESSINGPARAMSISEXPLICITPOLICYREQUIREDFAILED);
-
- PKIX_CHECK(pkix_PolicyChecker_Initialize
- (initialPolicies,
- policyQualifiersRejected,
- initialPolicyMappingInhibit,
- initialExplicitPolicy,
- initialAnyPolicyInhibit,
- numChainCerts,
- &policyChecker,
- plContext),
- PKIX_POLICYCHECKERINITIALIZEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)policyChecker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- /*
- * Create an OID list that contains critical extensions processed
- * by BuildChain. These are specified in a static const array.
- */
- PKIX_CHECK(PKIX_List_Create(&buildCheckedCritExtOIDsList, plContext),
- PKIX_LISTCREATEFAILED);
-
- for (i = 0; buildCheckedCritExtOIDs[i] != PKIX_UNKNOWN_OID; i++) {
- PKIX_CHECK(PKIX_PL_OID_Create
- (buildCheckedCritExtOIDs[i], &oid, plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (buildCheckedCritExtOIDsList,
- (PKIX_PL_Object *) oid,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(oid);
- }
-
- if (state->buildConstants.userCheckers != NULL) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (state->buildConstants.userCheckers,
- &numCertCheckers,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numCertCheckers; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (state->buildConstants.userCheckers,
- i,
- (PKIX_PL_Object **) &userChecker,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK
- (PKIX_CertChainChecker_IsForwardCheckingSupported
- (userChecker, &supportForwardChecking, plContext),
- PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED);
-
- /*
- * If this userChecker supports forwardChecking then it
- * should have been checked during build chain. Skip
- * checking but need to add checker's extension OIDs
- * to buildCheckedCritExtOIDsList.
- */
- if (supportForwardChecking == PKIX_TRUE) {
-
- PKIX_CHECK
- (PKIX_CertChainChecker_GetSupportedExtensions
- (userChecker, &userCheckerExtOIDs, plContext),
- PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED);
-
- if (userCheckerExtOIDs != NULL) {
- PKIX_CHECK(pkix_List_AppendList
- (buildCheckedCritExtOIDsList,
- userCheckerExtOIDs,
- plContext),
- PKIX_LISTAPPENDLISTFAILED);
- }
-
- } else {
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers,
- (PKIX_PL_Object *)userChecker,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
-
- PKIX_DECREF(userCheckerExtOIDs);
- PKIX_DECREF(userChecker);
- }
- }
-
- /* Inabling post chain building signature check on the certs. */
- PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
- (anchor, &trustedCert, plContext),
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
- (trustedCert, &trustedPubKey, plContext),
- PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
-
- PKIX_CHECK(pkix_SignatureChecker_Initialize
- (trustedPubKey,
- numChainCerts,
- &sigChecker,
- plContext),
- PKIX_SIGNATURECHECKERINITIALIZEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers,
- (PKIX_PL_Object *)sigChecker,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(state->reversedCertChain);
- PKIX_INCREF(reversedCertChain);
- state->reversedCertChain = reversedCertChain;
- PKIX_DECREF(state->checkedCritExtOIDs);
- PKIX_INCREF(buildCheckedCritExtOIDsList);
- state->checkedCritExtOIDs = buildCheckedCritExtOIDsList;
- PKIX_DECREF(state->checkerChain);
- state->checkerChain = checkers;
- checkers = NULL;
- state->certCheckedIndex = 0;
- state->checkerIndex = 0;
- state->revChecking = PKIX_FALSE;
-
-
-cleanup:
-
- PKIX_DECREF(oid);
- PKIX_DECREF(reversedCertChain);
- PKIX_DECREF(buildCheckedCritExtOIDsList);
- PKIX_DECREF(checker);
- PKIX_DECREF(checkers);
- PKIX_DECREF(initialPolicies);
- PKIX_DECREF(trustedCert);
- PKIX_DECREF(trustedPubKey);
- PKIX_DECREF(certSelector);
- PKIX_DECREF(sigChecker);
- PKIX_DECREF(policyChecker);
- PKIX_DECREF(userChecker);
- PKIX_DECREF(userCheckerExtOIDs);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_Build_ValidateEntireChain
- * DESCRIPTION:
- *
- * Checks whether the current List of Certs successfully validates using the
- * TrustAnchor pointed to by "anchor" and other parameters contained, as was
- * the Cert List, in "state".
- *
- * If a checker using non-blocking I/O returns with a non-NULL non-blocking I/O
- * context (NBIOContext), an indication that I/O is in progress and the
- * checking has not been completed, this function stores that context at
- * "pNBIOContext". Otherwise, it stores NULL at "pNBIOContext".
- *
- * If not awaiting I/O and if successful, a ValidateResult is created
- * containing the Public Key of the target certificate (including DSA parameter
- * inheritance, if any) and the PolicyNode representing the policy tree output
- * by the validation algorithm. If not successful, an Error pointer is
- * returned.
- *
- * PARAMETERS:
- * "state"
- * Address of ForwardBuilderState to be used. Must be non-NULL.
- * "anchor"
- * Address of TrustAnchor to be used. Must be non-NULL.
- * "pNBIOContext"
- * Address at which the NBIOContext is stored indicating whether the
- * validation is complete. Must be non-NULL.
- * "pValResult"
- * Address at which the ValidateResult is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_ValidateEntireChain(
- PKIX_ForwardBuilderState *state,
- PKIX_TrustAnchor *anchor,
- void **pNBIOContext,
- PKIX_ValidateResult **pValResult,
- PKIX_VerifyNode *verifyNode,
- void *plContext)
-{
- PKIX_UInt32 numChainCerts = 0;
- PKIX_PL_PublicKey *subjPubKey = NULL;
- PKIX_PolicyNode *policyTree = NULL;
- PKIX_ValidateResult *valResult = NULL;
- void *nbioContext = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_ValidateEntireChain");
- PKIX_NULLCHECK_FOUR(state, anchor, pNBIOContext, pValResult);
-
- *pNBIOContext = NULL; /* prepare for case of error exit */
-
- PKIX_CHECK(PKIX_List_GetLength
- (state->reversedCertChain, &numChainCerts, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- pkixErrorResult =
- pkix_CheckChain(state->reversedCertChain, numChainCerts, anchor,
- state->checkerChain,
- state->buildConstants.revChecker,
- state->checkedCritExtOIDs,
- state->buildConstants.procParams,
- &state->certCheckedIndex, &state->checkerIndex,
- &state->revChecking, &state->reasonCode,
- &nbioContext, &subjPubKey, &policyTree, NULL,
- plContext);
-
- if (nbioContext != NULL) {
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
-
- ERROR_CHECK(PKIX_CHECKCHAINFAILED);
-
- if (state->reasonCode != 0) {
- PKIX_ERROR(PKIX_CHAINREJECTEDBYREVOCATIONCHECKER);
- }
-
- PKIX_CHECK(pkix_ValidateResult_Create
- (subjPubKey, anchor, policyTree, &valResult, plContext),
- PKIX_VALIDATERESULTCREATEFAILED);
-
- *pValResult = valResult;
- valResult = NULL;
-
-cleanup:
- PKIX_DECREF(subjPubKey);
- PKIX_DECREF(policyTree);
- PKIX_DECREF(valResult);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_Build_SortCandidateCerts
- * DESCRIPTION:
- *
- * This function sorts a List of candidate Certs pointed to by "candidates"
- * using an algorithm that places Certs most likely to produce a successful
- * chain at the front of the list, storing the resulting sorted List at
- * "pSortedCandidates".
- *
- * At present the only sort criterion is that trusted Certs go ahead of
- * untrusted Certs.
- *
- * PARAMETERS:
- * "candidates"
- * Address of List of Candidate Certs to be sorted. Must be non-NULL.
- * "pSortedCandidates"
- * Address at which sorted List is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_SortCandidateCerts(
- PKIX_List *candidates,
- PKIX_List **pSortedCandidates,
- void *plContext)
-{
- PKIX_List *sortedList = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_SortCandidateCerts");
- PKIX_NULLCHECK_TWO(candidates, pSortedCandidates);
-
- /*
- * Both bubble and quick sort algorithms are available.
- * For a list of fewer than around 100 items, the bubble sort is more
- * efficient. (This number was determined by experimenting with both
- * algorithms on a Java List.)
- * If the candidate list is very small, using the sort can drag down
- * the performance a little bit.
- */
-
- PKIX_CHECK(pkix_List_BubbleSort
- (candidates,
- pkix_Build_SortCertComparator,
- &sortedList,
- plContext),
- PKIX_LISTBUBBLESORTFAILED);
-
- *pSortedCandidates = sortedList;
-
-cleanup:
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_Build_BuildSelectorAndParams
- * DESCRIPTION:
- *
- * This function creates a CertSelector, initialized with an appropriate
- * ComCertSelParams, using the variables provided in the ForwardBuilderState
- * pointed to by "state". The CertSelector created is stored in the certsel
- * element of "state".
- *
- * PARAMETERS:
- * "state"
- * Address of ForwardBuilderState to be used. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_BuildSelectorAndParams(
- PKIX_ForwardBuilderState *state,
- void *plContext)
-{
- PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_CertSelector *certSel = NULL;
- PKIX_PL_X500Name *currentIssuer = NULL;
- PKIX_PL_ByteArray *authKeyId = NULL;
- PKIX_PL_Date *testDate = NULL;
- PKIX_CertSelector *callerCertSelector = NULL;
- PKIX_ComCertSelParams *callerComCertSelParams = NULL;
- PKIX_UInt32 reqKu = 0;
- PKIX_List *reqEkuOids = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_BuildSelectorAndParams");
- PKIX_NULLCHECK_THREE(state, state->prevCert, state->traversedSubjNames);
-
- PKIX_CHECK(PKIX_PL_Cert_GetIssuer
- (state->prevCert, &currentIssuer, plContext),
- PKIX_CERTGETISSUERFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
- (state->prevCert, &authKeyId, plContext),
- PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_Create(&certSelParams, plContext),
- PKIX_COMCERTSELPARAMSCREATEFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_SetSubject
- (certSelParams, currentIssuer, plContext),
- PKIX_COMCERTSELPARAMSSETSUBJECTFAILED);
-
- if (authKeyId != NULL) {
- PKIX_CHECK(PKIX_ComCertSelParams_SetSubjKeyIdentifier
- (certSelParams, authKeyId, plContext),
- PKIX_COMCERTSELPARAMSSETSUBJKEYIDENTIFIERFAILED);
- }
-
- PKIX_INCREF(state->buildConstants.testDate);
- testDate = state->buildConstants.testDate;
-
- PKIX_CHECK(PKIX_ComCertSelParams_SetCertificateValid
- (certSelParams, testDate, plContext),
- PKIX_COMCERTSELPARAMSSETCERTIFICATEVALIDFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_SetBasicConstraints
- (certSelParams, state->traversedCACerts, plContext),
- PKIX_COMCERTSELPARAMSSETBASICCONSTRAINTSFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_SetPathToNames
- (certSelParams, state->traversedSubjNames, plContext),
- PKIX_COMCERTSELPARAMSSETPATHTONAMESFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
- (state->buildConstants.procParams,
- &callerCertSelector, plContext),
- PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
-
- if (callerCertSelector != NULL) {
-
- /* Get initial EKU OIDs from ComCertSelParams, if set */
- PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
- (callerCertSelector, &callerComCertSelParams, plContext),
- PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
-
- if (callerComCertSelParams != NULL) {
- PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
- (callerComCertSelParams, &reqEkuOids, plContext),
- PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetKeyUsage
- (callerComCertSelParams, &reqKu, plContext),
- PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);
- }
- }
-
- PKIX_CHECK(
- PKIX_ComCertSelParams_SetKeyUsage(certSelParams, reqKu,
- plContext),
- PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED);
-
- PKIX_CHECK(
- PKIX_ComCertSelParams_SetExtendedKeyUsage(certSelParams,
- reqEkuOids,
- plContext),
- PKIX_COMCERTSELPARAMSSETEXTKEYUSAGEFAILED);
-
- PKIX_CHECK(PKIX_CertSelector_Create
- (NULL, NULL, &state->certSel, plContext),
- PKIX_CERTSELECTORCREATEFAILED);
-
- PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams
- (state->certSel, certSelParams, plContext),
- PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
-
- PKIX_CHECK(PKIX_List_Create(&state->candidateCerts, plContext),
- PKIX_LISTCREATEFAILED);
-
- state->certStoreIndex = 0;
-
-cleanup:
- PKIX_DECREF(certSelParams);
- PKIX_DECREF(certSel);
- PKIX_DECREF(currentIssuer);
- PKIX_DECREF(authKeyId);
- PKIX_DECREF(testDate);
- PKIX_DECREF(reqEkuOids);
- PKIX_DECREF(callerComCertSelParams);
- PKIX_DECREF(callerCertSelector);
-
- PKIX_RETURN(BUILD);
-}
-
-/* Match trust anchor to select params in order to find next cert. */
-static PKIX_Error*
-pkix_Build_SelectCertsFromTrustAnchors(
- PKIX_List *trustAnchorsList,
- PKIX_ComCertSelParams *certSelParams,
- PKIX_List **pMatchList,
- void *plContext)
-{
- int anchorIndex = 0;
- PKIX_TrustAnchor *anchor = NULL;
- PKIX_PL_Cert *trustedCert = NULL;
- PKIX_List *matchList = NULL;
- PKIX_CertSelector *certSel = NULL;
- PKIX_CertSelector_MatchCallback selectorMatchCB = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_SelectCertsFromTrustAnchors");
-
- PKIX_CHECK(PKIX_CertSelector_Create
- (NULL, NULL, &certSel, plContext),
- PKIX_CERTSELECTORCREATEFAILED);
- PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams
- (certSel, certSelParams, plContext),
- PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
- PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
- (certSel, &selectorMatchCB, plContext),
- PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
-
- for (anchorIndex = 0;anchorIndex < trustAnchorsList->length; anchorIndex++) {
- PKIX_CHECK(
- PKIX_List_GetItem(trustAnchorsList,
- anchorIndex,
- (PKIX_PL_Object **)&anchor,
- plContext),
- PKIX_LISTGETITEMFAILED);
- PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
- (anchor, &trustedCert, plContext),
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
- pkixErrorResult =
- (*selectorMatchCB)(certSel, trustedCert, plContext);
- if (!pkixErrorResult) {
- if (!matchList) {
- PKIX_CHECK(PKIX_List_Create(&matchList,
- plContext),
- PKIX_LISTCREATEFAILED);
- }
- PKIX_CHECK(
- PKIX_List_AppendItem(matchList,
- (PKIX_PL_Object*)trustedCert,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- } else {
- PKIX_DECREF(pkixErrorResult);
- }
- PKIX_DECREF(trustedCert);
- PKIX_DECREF(anchor);
- }
-
- *pMatchList = matchList;
- matchList = NULL;
-
-cleanup:
- PKIX_DECREF(matchList);
- PKIX_DECREF(trustedCert);
- PKIX_DECREF(anchor);
- PKIX_DECREF(certSel);
-
- PKIX_RETURN(BUILD);
-}
-
-
-static PKIX_Error*
-pkix_Build_RemoveDupUntrustedCerts(
- PKIX_List *trustedCertList,
- PKIX_List *certsFound,
- void *plContext)
-{
- PKIX_UInt32 trustIndex;
- PKIX_PL_Cert *trustCert = NULL, *cert = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_RemoveDupUntrustedCerts");
- if (trustedCertList == NULL || certsFound == NULL) {
- goto cleanup;
- }
- for (trustIndex = 0;trustIndex < trustedCertList->length;
- trustIndex++) {
- PKIX_UInt32 certIndex = 0;
- PKIX_CHECK(
- PKIX_List_GetItem(trustedCertList,
- trustIndex,
- (PKIX_PL_Object **)&trustCert,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- while (certIndex < certsFound->length) {
- PKIX_Boolean result = PKIX_FALSE;
- PKIX_DECREF(cert);
- PKIX_CHECK(
- PKIX_List_GetItem(certsFound, certIndex,
- (PKIX_PL_Object **)&cert,
- plContext),
- PKIX_LISTGETITEMFAILED);
- PKIX_CHECK(
- PKIX_PL_Object_Equals((PKIX_PL_Object *)trustCert,
- (PKIX_PL_Object *)cert,
- &result,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
- if (!result) {
- certIndex += 1;
- continue;
- }
- PKIX_CHECK(
- PKIX_List_DeleteItem(certsFound, certIndex,
- plContext),
- PKIX_LISTDELETEITEMFAILED);
- }
- PKIX_DECREF(trustCert);
- }
-cleanup:
- PKIX_DECREF(cert);
- PKIX_DECREF(trustCert);
-
- PKIX_RETURN(BUILD);
-}
-
-
-/*
- * FUNCTION: pkix_Build_GatherCerts
- * DESCRIPTION:
- *
- * This function traverses the CertStores in the List of CertStores contained
- * in "state", using the certSelector and other parameters contained in
- * "state", to obtain a List of all available Certs that satisfy the criteria.
- * If a CertStore has a cache, "certSelParams" is used both to query the cache
- * and, if an actual CertStore search occurred, to update the cache. (Behavior
- * is undefined if "certSelParams" is different from the parameters that were
- * used to initialize the certSelector in "state".)
- *
- * If a CertStore using non-blocking I/O returns with an indication that I/O is
- * in progress and the checking has not been completed, this function stores
- * platform-dependent information at "pNBIOContext". Otherwise it stores NULL
- * at "pNBIOContext", and state is updated with the results of the search.
- *
- * PARAMETERS:
- * "state"
- * Address of ForwardBuilderState to be used. Must be non-NULL.
- * "certSelParams"
- * Address of ComCertSelParams which were used in creating the current
- * CertSelector, and to be used in querying and updating any caches that
- * may be associated with with the CertStores.
- * "pNBIOContext"
- * Address at which platform-dependent information is returned if request
- * is suspended for non-blocking I/O. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-/* return NULL if wouldblock, empty list if none found, else list of found */
-static PKIX_Error *
-pkix_Build_GatherCerts(
- PKIX_ForwardBuilderState *state,
- PKIX_ComCertSelParams *certSelParams,
- void **pNBIOContext,
- void *plContext)
-{
- PKIX_Boolean certStoreIsCached = PKIX_FALSE;
- PKIX_Boolean certStoreIsLocal = PKIX_FALSE;
- PKIX_Boolean foundInCache = PKIX_FALSE;
- PKIX_CertStore *certStore = NULL;
- PKIX_CertStore_CertCallback getCerts = NULL;
- PKIX_List *certsFound = NULL;
- PKIX_List *trustedCertList = NULL;
- void *nbioContext = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_GatherCerts");
- PKIX_NULLCHECK_THREE(state, certSelParams, pNBIOContext);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- PKIX_DECREF(state->candidateCerts);
-
- while (state->certStoreIndex < state->buildConstants.numCertStores) {
-
- /* Get the current CertStore */
- PKIX_CHECK(PKIX_List_GetItem
- (state->buildConstants.certStores,
- state->certStoreIndex,
- (PKIX_PL_Object **)&certStore,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_CertStore_GetLocalFlag
- (certStore, &certStoreIsLocal, plContext),
- PKIX_CERTSTOREGETLOCALFLAGFAILED);
-
- if (state->useOnlyLocal == certStoreIsLocal) {
- /* If GATHERPENDING, we've already checked the cache */
- if (state->status == BUILD_GATHERPENDING) {
- certStoreIsCached = PKIX_FALSE;
- foundInCache = PKIX_FALSE;
- } else {
- PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
- (certStore, &certStoreIsCached, plContext),
- PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED);
-
- if (certStoreIsCached) {
- /*
- * Look for Certs in the cache, using the SubjectName as
- * the key. Then the ComCertSelParams are used to filter
- * for qualified certs. If none are found, then the
- * certStores are queried. When we eventually add items
- * to the cache, we will only add items that passed the
- * ComCertSelParams filter, rather than all Certs which
- * matched the SubjectName.
- */
-
- PKIX_CHECK(pkix_CacheCert_Lookup
- (certStore,
- certSelParams,
- state->buildConstants.testDate,
- &foundInCache,
- &certsFound,
- plContext),
- PKIX_CACHECERTCHAINLOOKUPFAILED);
-
- }
- }
-
- /*
- * XXX need to verify if Cert is trusted, hence may not
- * be worth it to have the Cert Cached or
- * If it is trusted, don't cache, but once there is cached
- * certs, we won't get certs from database any more.
- * can use flag to force not getting certs from cache
- */
- if (!foundInCache) {
-
- if (nbioContext == NULL) {
- PKIX_CHECK(PKIX_CertStore_GetCertCallback
- (certStore, &getCerts, plContext),
- PKIX_CERTSTOREGETCERTCALLBACKFAILED);
-
- PKIX_CHECK(getCerts
- (certStore,
- state->certSel,
- state->verifyNode,
- &nbioContext,
- &certsFound,
- plContext),
- PKIX_GETCERTSFAILED);
- } else {
- PKIX_CHECK(PKIX_CertStore_CertContinue
- (certStore,
- state->certSel,
- state->verifyNode,
- &nbioContext,
- &certsFound,
- plContext),
- PKIX_CERTSTORECERTCONTINUEFAILED);
- }
-
- if (certStoreIsCached && certsFound) {
-
- PKIX_CHECK(pkix_CacheCert_Add
- (certStore,
- certSelParams,
- certsFound,
- plContext),
- PKIX_CACHECERTADDFAILED);
- }
- }
-
- /*
- * getCerts returns an empty list for "NONE FOUND",
- * a NULL list for "would block"
- */
- if (certsFound == NULL) {
- state->status = BUILD_GATHERPENDING;
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
- }
-
- /* Are there any more certStores to query? */
- PKIX_DECREF(certStore);
- ++(state->certStoreIndex);
- }
-
- if (certsFound && certsFound->length > 1) {
- PKIX_List *sorted = NULL;
-
- /* sort Certs to try to optimize search */
- PKIX_CHECK(pkix_Build_SortCandidateCerts
- (certsFound, &sorted, plContext),
- PKIX_BUILDSORTCANDIDATECERTSFAILED);
- PKIX_DECREF(certsFound);
- certsFound = sorted;
- }
-
- PKIX_CHECK(
- pkix_Build_SelectCertsFromTrustAnchors(
- state->buildConstants.anchors,
- certSelParams, &trustedCertList,
- plContext),
- PKIX_FAILTOSELECTCERTSFROMANCHORS);
- PKIX_CHECK(
- pkix_Build_RemoveDupUntrustedCerts(trustedCertList,
- certsFound,
- plContext),
- PKIX_REMOVEDUPUNTRUSTEDCERTSFAILED);
-
- PKIX_CHECK(
- pkix_List_MergeLists(trustedCertList,
- certsFound,
- &state->candidateCerts,
- plContext),
- PKIX_LISTMERGEFAILED);
-
- /* No, return the list we have gathered */
- PKIX_CHECK(PKIX_List_GetLength
- (state->candidateCerts, &state->numCerts, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- state->certIndex = 0;
-
-cleanup:
- PKIX_DECREF(trustedCertList);
- PKIX_DECREF(certStore);
- PKIX_DECREF(certsFound);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_Build_UpdateDate
- * DESCRIPTION:
- *
- * This function updates the validityDate contained in "state", for the current
- * CertChain contained in "state", to include the validityDate of the
- * candidateCert contained in "state". The validityDate of a chain is the
- * earliest of all the notAfter dates contained in the respective Certificates.
- *
- * PARAMETERS:
- * "state"
- * Address of ForwardBuilderState to be used. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_UpdateDate(
- PKIX_ForwardBuilderState *state,
- void *plContext)
-{
- PKIX_Boolean canBeCached = PKIX_FALSE;
- PKIX_Int32 comparison = 0;
- PKIX_PL_Date *notAfter = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_UpdateDate");
- PKIX_NULLCHECK_ONE(state);
-
- PKIX_CHECK(PKIX_PL_Cert_GetCacheFlag
- (state->candidateCert, &canBeCached, plContext),
- PKIX_CERTGETCACHEFLAGFAILED);
-
- state->canBeCached = state->canBeCached && canBeCached;
- if (state->canBeCached == PKIX_TRUE) {
-
- /*
- * So far, all certs can be cached. Update cert
- * chain validity time, which is the earliest of
- * all certs' notAfter times.
- */
- PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter
- (state->candidateCert, &notAfter, plContext),
- PKIX_CERTGETVALIDITYNOTAFTERFAILED);
-
- if (state->validityDate == NULL) {
- state->validityDate = notAfter;
- notAfter = NULL;
- } else {
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)state->validityDate,
- (PKIX_PL_Object *)notAfter,
- &comparison,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
- if (comparison > 0) {
- PKIX_DECREF(state->validityDate);
- state->validityDate = notAfter;
- notAfter = NULL;
- }
- }
- }
-
-cleanup:
-
- PKIX_DECREF(notAfter);
-
- PKIX_RETURN(BUILD);
-}
-
-/* Prepare 'state' for the AIA round. */
-static void
-pkix_PrepareForwardBuilderStateForAIA(
- PKIX_ForwardBuilderState *state)
-{
- PORT_Assert(state->useOnlyLocal == PKIX_TRUE);
- state->useOnlyLocal = PKIX_FALSE;
- state->certStoreIndex = 0;
- state->numFanout = state->buildConstants.maxFanout;
- state->status = BUILD_TRYAIA;
-}
-
-/*
- * FUNCTION: pkix_BuildForwardDepthFirstSearch
- * DESCRIPTION:
- *
- * This function performs a depth first search in the "forward" direction (from
- * the target Cert to the trust anchor). A non-NULL targetCert must be stored
- * in the ForwardBuilderState before this function is called. It is not written
- * recursively since execution may be suspended in in any of several places
- * pending completion of non-blocking I/O. This iterative structure makes it
- * much easier to resume where it left off.
- *
- * Since the nature of the search is recursive, the recursion is handled by
- * chaining states. That is, each new step involves creating a new
- * ForwardBuilderState linked to its predecessor. If a step turns out to be
- * fruitless, the state of the predecessor is restored and the next alternative
- * is tried. When a search is successful, values needed from the last state
- * (canBeCached and validityDate) are copied to the state provided by the
- * caller, so that the caller can retrieve those values.
- *
- * There are three return arguments, the NBIOContext, the ValidateResult and
- * the ForwardBuilderState. If NBIOContext is non-NULL, it means the search is
- * suspended until the results of a non-blocking IO become available. The
- * caller may wait for the completion using platform-dependent methods and then
- * call this function again, allowing it to resume the search. If NBIOContext
- * is NULL and the ValidateResult is non-NULL, it means the search has
- * concluded successfully. If the NBIOContext is NULL but the ValidateResult is
- * NULL, it means the search was unsuccessful.
- *
- * This function performs several steps at each node in the constructed chain:
- *
- * 1) It retrieves Certs from the registered CertStores that match the
- * criteria established by the ForwardBuilderState pointed to by "state", such
- * as a subject name matching the issuer name of the previous Cert. If there
- * are no matching Certs, the function returns to the previous, or "parent",
- * state and tries to continue the chain building with another of the Certs
- * obtained from the CertStores as possible issuers for that parent Cert.
- *
- * 2) For each candidate Cert returned by the CertStores, this function checks
- * whether the Cert is valid. If it is trusted, this function checks whether
- * this Cert might serve as a TrustAnchor for a complete chain.
- *
- * 3) It determines whether this Cert, in conjunction with any of the
- * TrustAnchors, might complete a chain. A complete chain, from this or the
- * preceding step, is checked to see whether it is valid as a complete
- * chain, including the checks that cannot be done in the forward direction.
- *
- * 4) If this Cert chains successfully, but is not a complete chain, that is,
- * we have not reached a trusted Cert, a new ForwardBuilderState is created
- * with this Cert as the immediate predecessor, and we continue in step (1),
- * attempting to get Certs from the CertStores with this Certs "issuer" as
- * their subject.
- *
- * 5) If an entire chain validates successfully, then we are done. A
- * ValidateResult is created containing the Public Key of the target
- * certificate (including DSA parameter inheritance, if any) and the
- * PolicyNode representing the policy tree output by the validation algorithm,
- * and stored at pValResult, and the function exits returning NULL.
- *
- * 5) If the entire chain does not validate successfully, the algorithm
- * discards the latest Cert and continues in step 2 with the next candidate
- * Cert, backing up to a parent state when no more possibilities exist at a
- * given level, and returning failure when we try to back up but discover we
- * are at the top level.
- *
- * PARAMETERS:
- * "pNBIOContext"
- * Address at which platform-dependent information is returned if building
- * is suspended for non-blocking I/O. Must be non-NULL.
- * "pState"
- * Address at which input ForwardBuilderState is found, and at which output
- * ForwardBuilderState is stored. Must be non-NULL.
- * "pValResult"
- * Address at which the ValidateResult is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_BuildForwardDepthFirstSearch(
- void **pNBIOContext,
- PKIX_ForwardBuilderState *state,
- PKIX_ValidateResult **pValResult,
- void *plContext)
-{
- PKIX_Boolean outOfOptions = PKIX_FALSE;
- PKIX_Boolean trusted = PKIX_FALSE;
- PKIX_Boolean isSelfIssued = PKIX_FALSE;
- PKIX_Boolean canBeCached = PKIX_FALSE;
- PKIX_Boolean revocationCheckingExists = PKIX_FALSE;
- PKIX_Boolean needsCRLChecking = PKIX_FALSE;
- PKIX_Boolean ioPending = PKIX_FALSE;
- PKIX_PL_Date *validityDate = NULL;
- PKIX_PL_Date *currTime = NULL;
- PKIX_Int32 childTraversedCACerts = 0;
- PKIX_UInt32 numSubjectNames = 0;
- PKIX_UInt32 numChained = 0;
- PKIX_Int32 cmpTimeResult = 0;
- PKIX_UInt32 i = 0;
- PKIX_UInt32 certsSoFar = 0;
- PKIX_List *childTraversedSubjNames = NULL;
- PKIX_List *subjectNames = NULL;
- PKIX_List *unfilteredCerts = NULL;
- PKIX_List *filteredCerts = NULL;
- PKIX_PL_Object *subjectName = NULL;
- PKIX_ValidateResult *valResult = NULL;
- PKIX_ForwardBuilderState *childState = NULL;
- PKIX_ForwardBuilderState *parentState = NULL;
- PKIX_PL_Object *revCheckerState = NULL;
- PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_TrustAnchor *trustAnchor = NULL;
- PKIX_PL_Cert *trustedCert = NULL;
- PKIX_VerifyNode *verifyNode = NULL;
- PKIX_Error *verifyError = NULL;
- PKIX_Error *finalError = NULL;
- void *nbio = NULL;
- PKIX_UInt32 numIterations = 0;
-
- PKIX_ENTER(BUILD, "pkix_BuildForwardDepthFirstSearch");
- PKIX_NULLCHECK_THREE(pNBIOContext, state, pValResult);
-
- nbio = *pNBIOContext;
- *pNBIOContext = NULL;
- PKIX_INCREF(state->validityDate);
- validityDate = state->validityDate;
- canBeCached = state->canBeCached;
- PKIX_DECREF(*pValResult);
-
- /*
- * We return if successful; if we fall off the end
- * of this "while" clause our search has failed.
- */
- while (outOfOptions == PKIX_FALSE) {
- /*
- * The maximum number of iterations works around a bug that
- * causes this while loop to never exit when AIA and cross
- * certificates are involved. See bug xxxxx.
- */
- if (numIterations++ > 250)
- PKIX_ERROR(PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS);
-
- if (state->buildConstants.maxTime != 0) {
- PKIX_DECREF(currTime);
- PKIX_CHECK(PKIX_PL_Date_Create_UTCTime
- (NULL, &currTime, plContext),
- PKIX_DATECREATEUTCTIMEFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)state->buildConstants.timeLimit,
- (PKIX_PL_Object *)currTime,
- &cmpTimeResult,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
-
- if (cmpTimeResult < 0) {
- if (state->verifyNode != NULL) {
- PKIX_ERROR_CREATE
- (BUILD,
- PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS,
- verifyError);
- PKIX_CHECK_FATAL(pkix_VerifyNode_SetError
- (state->verifyNode,
- verifyError,
- plContext),
- PKIX_VERIFYNODESETERRORFAILED);
- PKIX_DECREF(finalError);
- finalError = verifyError;
- verifyError = NULL;
- }
- /* Even if we logged error, we still have to abort */
- PKIX_ERROR(PKIX_TIMECONSUMEDEXCEEDSRESOURCELIMITS);
- }
- }
-
- if (state->status == BUILD_INITIAL) {
-
- PKIX_CHECK(pkix_Build_BuildSelectorAndParams(state, plContext),
- PKIX_BUILDBUILDSELECTORANDPARAMSFAILED);
-
- /*
- * If the caller supplied a partial certChain (hintCerts) try
- * the next one from that List before we go to the certStores.
- */
- if (state->buildConstants.numHintCerts > 0) {
- /* How many Certs does our trust chain have already? */
- PKIX_CHECK(PKIX_List_GetLength
- (state->trustChain, &certsSoFar, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- /* That includes the target Cert. Don't count it. */
- certsSoFar--;
-
- /* Are we still within range of the partial chain? */
- if (certsSoFar >= state->buildConstants.numHintCerts) {
- state->status = BUILD_TRYAIA;
- } else {
- /*
- * If we already have n certs, we want the n+1th
- * (i.e., index = n) from the list of hints.
- */
- PKIX_DECREF(state->candidateCert);
- PKIX_CHECK(PKIX_List_GetItem
- (state->buildConstants.hintCerts,
- certsSoFar,
- (PKIX_PL_Object **)&state->candidateCert,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (state->candidateCerts,
- (PKIX_PL_Object *)state->candidateCert,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- state->numCerts = 1;
- state->usingHintCerts = PKIX_TRUE;
- state->status = BUILD_CERTVALIDATING;
- }
- } else {
- state->status = BUILD_TRYAIA;
- }
-
- }
-
- if (state->status == BUILD_TRYAIA) {
- if (state->useOnlyLocal == PKIX_TRUE) {
- state->status = BUILD_COLLECTINGCERTS;
- } else {
- state->status = BUILD_AIAPENDING;
- }
- }
-
- if (state->status == BUILD_AIAPENDING &&
- state->buildConstants.aiaMgr) {
- pkixErrorResult = PKIX_PL_AIAMgr_GetAIACerts
- (state->buildConstants.aiaMgr,
- state->prevCert,
- &nbio,
- &unfilteredCerts,
- plContext);
-
- if (nbio != NULL) {
- /* IO still pending, resume later */
- *pNBIOContext = nbio;
- goto cleanup;
- }
- state->numCerts = 0;
- if (pkixErrorResult) {
- pkixErrorClass = pkixErrorResult->errClass;
- if (pkixErrorClass == PKIX_FATAL_ERROR) {
- goto fatal;
- }
- PKIX_DECREF(finalError);
- finalError = pkixErrorResult;
- pkixErrorResult = NULL;
- if (state->verifyNode != NULL) {
- /* state->verifyNode is the object that contains a list
- * of verifyNodes. verifyNodes contains cert chain
- * build failures that occurred on this level of chain
- * building. Here, creating new verify node
- * to log the failure and adding it to the list. */
- PKIX_CHECK_FATAL(pkix_VerifyNode_Create
- (state->prevCert,
- 0, NULL,
- &verifyNode,
- plContext),
- PKIX_VERIFYNODECREATEFAILED);
- PKIX_CHECK_FATAL(pkix_VerifyNode_SetError
- (verifyNode, finalError, plContext),
- PKIX_VERIFYNODESETERRORFAILED);
- PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
- (state->verifyNode,
- verifyNode,
- plContext),
- PKIX_VERIFYNODEADDTOTREEFAILED);
- PKIX_DECREF(verifyNode);
- }
- }
-#ifdef PKIX_BUILDDEBUG
- /* Turn this on to trace the List of Certs, before CertSelect */
- {
- PKIX_PL_String *unString;
- char *unAscii;
- PKIX_UInt32 length;
- PKIX_TOSTRING
- ((PKIX_PL_Object*)unfilteredCerts,
- &unString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (unString,
- PKIX_ESCASCII,
- (void **)&unAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_DEBUG_ARG
- ("unfilteredCerts = %s\n", unAscii);
- PKIX_DECREF(unString);
- PKIX_FREE(unAscii);
- }
-#endif
-
- /* Note: Certs winnowed here don't get into VerifyTree. */
- if (unfilteredCerts) {
- PKIX_CHECK(pkix_CertSelector_Select
- (state->certSel,
- unfilteredCerts,
- &filteredCerts,
- plContext),
- PKIX_CERTSELECTORSELECTFAILED);
-
- PKIX_DECREF(unfilteredCerts);
-
- PKIX_CHECK(PKIX_List_GetLength
- (filteredCerts, &(state->numCerts), plContext),
- PKIX_LISTGETLENGTHFAILED);
-
-#ifdef PKIX_BUILDDEBUG
- /* Turn this on to trace the List of Certs, after CertSelect */
- {
- PKIX_PL_String *unString;
- char *unAscii;
- PKIX_UInt32 length;
- PKIX_TOSTRING
- ((PKIX_PL_Object*)filteredCerts,
- &unString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (unString,
- PKIX_ESCASCII,
- (void **)&unAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_DEBUG_ARG("filteredCerts = %s\n", unAscii);
- PKIX_DECREF(unString);
- PKIX_FREE(unAscii);
- }
-#endif
-
- PKIX_DECREF(state->candidateCerts);
- state->candidateCerts = filteredCerts;
- state->certIndex = 0;
- filteredCerts = NULL;
- }
-
- /* Are there any Certs to try? */
- if (state->numCerts > 0) {
- state->status = BUILD_CERTVALIDATING;
- } else {
- state->status = BUILD_COLLECTINGCERTS;
- }
- }
-
- PKIX_DECREF(certSelParams);
- PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
- (state->certSel, &certSelParams, plContext),
- PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
-
- /* **** Querying the CertStores ***** */
- if ((state->status == BUILD_COLLECTINGCERTS) ||
- (state->status == BUILD_GATHERPENDING)) {
-
-#if PKIX_FORWARDBUILDERSTATEDEBUG
- PKIX_CHECK(pkix_ForwardBuilderState_DumpState
- (state, plContext),
- PKIX_FORWARDBUILDERSTATEDUMPSTATEFAILED);
-#endif
-
- PKIX_CHECK(pkix_Build_GatherCerts
- (state, certSelParams, &nbio, plContext),
- PKIX_BUILDGATHERCERTSFAILED);
-
- if (nbio != NULL) {
- /* IO still pending, resume later */
- *pNBIOContext = nbio;
- goto cleanup;
- }
-
- /* Are there any Certs to try? */
- if (state->numCerts > 0) {
- state->status = BUILD_CERTVALIDATING;
- } else {
- state->status = BUILD_ABANDONNODE;
- }
- }
-
- /* ****Phase 2 - Chain building***** */
-
-#if PKIX_FORWARDBUILDERSTATEDEBUG
- PKIX_CHECK(pkix_ForwardBuilderState_DumpState(state, plContext),
- PKIX_FORWARDBUILDERSTATEDUMPSTATEFAILED);
-#endif
-
- if (state->status == BUILD_CERTVALIDATING) {
- revocationCheckingExists =
- (state->buildConstants.revChecker != NULL);
-
- PKIX_DECREF(state->candidateCert);
- PKIX_CHECK(PKIX_List_GetItem
- (state->candidateCerts,
- state->certIndex,
- (PKIX_PL_Object **)&(state->candidateCert),
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- if ((state->verifyNode) != NULL) {
- PKIX_CHECK_FATAL(pkix_VerifyNode_Create
- (state->candidateCert,
- 0,
- NULL,
- &verifyNode,
- plContext),
- PKIX_VERIFYNODECREATEFAILED);
- }
-
- /* If failure, this function sets Error in verifyNode */
- verifyError = pkix_Build_VerifyCertificate
- (state,
- state->buildConstants.userCheckers,
- revocationCheckingExists,
- &trusted,
- &needsCRLChecking,
- verifyNode,
- plContext);
-
- if (verifyError) {
- pkixTempErrorReceived = PKIX_TRUE;
- pkixErrorClass = verifyError->errClass;
- if (pkixErrorClass == PKIX_FATAL_ERROR) {
- pkixErrorResult = verifyError;
- verifyError = NULL;
- goto fatal;
- }
- }
-
- if (PKIX_ERROR_RECEIVED) {
- if (state->verifyNode != NULL) {
- PKIX_CHECK_FATAL(pkix_VerifyNode_SetError
- (verifyNode, verifyError, plContext),
- PKIX_VERIFYNODESETERRORFAILED);
- PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
- (state->verifyNode,
- verifyNode,
- plContext),
- PKIX_VERIFYNODEADDTOTREEFAILED);
- PKIX_DECREF(verifyNode);
- }
- pkixTempErrorReceived = PKIX_FALSE;
- PKIX_DECREF(finalError);
- finalError = verifyError;
- verifyError = NULL;
- if (state->certLoopingDetected) {
- PKIX_ERROR
- (PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED);
- }
- state->status = BUILD_GETNEXTCERT;
- } else if (needsCRLChecking) {
- state->status = BUILD_CRLPREP;
- } else {
- state->status = BUILD_DATEPREP;
- }
- }
-
- if (state->status == BUILD_CRLPREP) {
- PKIX_RevocationStatus revStatus;
- PKIX_UInt32 reasonCode;
-
- verifyError =
- PKIX_RevocationChecker_Check(
- state->prevCert, state->candidateCert,
- state->buildConstants.revChecker,
- state->buildConstants.procParams,
- PKIX_FALSE,
- (state->parentState == NULL) ?
- PKIX_TRUE : PKIX_FALSE,
- &revStatus, &reasonCode,
- &nbio, plContext);
- if (nbio != NULL) {
- *pNBIOContext = nbio;
- goto cleanup;
- }
- if (revStatus == PKIX_RevStatus_Revoked || verifyError) {
- if (!verifyError) {
- /* if verifyError is returned then use it as
- * it has a detailed revocation error code.
- * Otherwise create a new error */
- PKIX_ERROR_CREATE(VALIDATE, PKIX_CERTIFICATEREVOKED,
- verifyError);
- }
- if (state->verifyNode != NULL) {
- PKIX_CHECK_FATAL(pkix_VerifyNode_SetError
- (verifyNode, verifyError, plContext),
- PKIX_VERIFYNODESETERRORFAILED);
- PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
- (state->verifyNode,
- verifyNode,
- plContext),
- PKIX_VERIFYNODEADDTOTREEFAILED);
- PKIX_DECREF(verifyNode);
- }
- PKIX_DECREF(finalError);
- finalError = verifyError;
- verifyError = NULL;
- if (state->certLoopingDetected) {
- PKIX_ERROR
- (PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED);
- }
- state->status = BUILD_GETNEXTCERT;
- } else {
- state->status = BUILD_DATEPREP;
- }
- }
-
- if (state->status == BUILD_DATEPREP) {
- /* Keep track of whether this chain can be cached */
- PKIX_CHECK(pkix_Build_UpdateDate(state, plContext),
- PKIX_BUILDUPDATEDATEFAILED);
-
- canBeCached = state->canBeCached;
- PKIX_DECREF(validityDate);
- PKIX_INCREF(state->validityDate);
- validityDate = state->validityDate;
- if (trusted == PKIX_TRUE) {
- state->status = BUILD_CHECKTRUSTED;
- } else {
- state->status = BUILD_ADDTOCHAIN;
- }
- }
-
- if (state->status == BUILD_CHECKTRUSTED) {
-
- /*
- * If this cert is trusted, try to validate the entire
- * chain using this certificate as trust anchor.
- */
- PKIX_CHECK(PKIX_TrustAnchor_CreateWithCert
- (state->candidateCert,
- &trustAnchor,
- plContext),
- PKIX_TRUSTANCHORCREATEWITHCERTFAILED);
-
- PKIX_CHECK(pkix_Build_ValidationCheckers
- (state,
- state->trustChain,
- trustAnchor,
- PKIX_FALSE, /* do not add eku checker
- * since eku was already
- * checked */
- plContext),
- PKIX_BUILDVALIDATIONCHECKERSFAILED);
-
- state->status = BUILD_CHECKTRUSTED2;
- }
-
- if (state->status == BUILD_CHECKTRUSTED2) {
- verifyError =
- pkix_Build_ValidateEntireChain(state,
- trustAnchor,
- &nbio, &valResult,
- verifyNode,
- plContext);
- if (nbio != NULL) {
- /* IO still pending, resume later */
- goto cleanup;
- } else {
- /* checking the error for fatal status */
- if (verifyError) {
- pkixTempErrorReceived = PKIX_TRUE;
- pkixErrorClass = verifyError->errClass;
- if (pkixErrorClass == PKIX_FATAL_ERROR) {
- pkixErrorResult = verifyError;
- verifyError = NULL;
- goto fatal;
- }
- }
- if (state->verifyNode != NULL) {
- PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
- (state->verifyNode,
- verifyNode,
- plContext),
- PKIX_VERIFYNODEADDTOTREEFAILED);
- PKIX_DECREF(verifyNode);
- }
- if (!PKIX_ERROR_RECEIVED) {
- *pValResult = valResult;
- valResult = NULL;
- /* Change state so IsIOPending is FALSE */
- state->status = BUILD_CHECKTRUSTED;
- goto cleanup;
- }
- PKIX_DECREF(finalError);
- finalError = verifyError;
- verifyError = NULL;
- /* Reset temp error that was set by
- * PKIX_CHECK_ONLY_FATAL and continue */
- pkixTempErrorReceived = PKIX_FALSE;
- PKIX_DECREF(trustAnchor);
- }
-
- /*
- * If chain doesn't validate with a trusted Cert,
- * adding more Certs to it can't help.
- */
- if (state->certLoopingDetected) {
- PKIX_DECREF(verifyError);
- PKIX_ERROR_CREATE(BUILD,
- PKIX_LOOPDISCOVEREDDUPCERTSNOTALLOWED,
- verifyError);
- PKIX_CHECK_FATAL(
- pkix_VerifyNode_SetError(state->verifyNode,
- verifyError,
- plContext),
- PKIX_VERIFYNODESETERRORFAILED);
- PKIX_DECREF(verifyError);
- }
- state->status = BUILD_GETNEXTCERT;
- }
-
- /*
- * This Cert was not trusted. Add it to our chain, and
- * continue building. If we don't reach a trust anchor,
- * we'll take it off later and continue without it.
- */
- if (state->status == BUILD_ADDTOCHAIN) {
- PKIX_CHECK(PKIX_List_AppendItem
- (state->trustChain,
- (PKIX_PL_Object *)state->candidateCert,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- state->status = BUILD_EXTENDCHAIN;
- }
-
- if (state->status == BUILD_EXTENDCHAIN) {
-
- /* Check whether we are allowed to extend the chain */
- if ((state->buildConstants.maxDepth != 0) &&
- (state->numDepth <= 1)) {
-
- if (state->verifyNode != NULL) {
- PKIX_ERROR_CREATE
- (BUILD,
- PKIX_DEPTHWOULDEXCEEDRESOURCELIMITS,
- verifyError);
- PKIX_CHECK_FATAL(pkix_VerifyNode_SetError
- (verifyNode, verifyError, plContext),
- PKIX_VERIFYNODESETERRORFAILED);
- PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
- (state->verifyNode, verifyNode, plContext),
- PKIX_VERIFYNODEADDTOTREEFAILED);
- PKIX_DECREF(verifyNode);
- PKIX_DECREF(finalError);
- finalError = verifyError;
- verifyError = NULL;
- }
- /* Even if error logged, still need to abort */
- PKIX_ERROR(PKIX_DEPTHWOULDEXCEEDRESOURCELIMITS);
- }
-
- PKIX_CHECK(pkix_IsCertSelfIssued
- (state->candidateCert, &isSelfIssued, plContext),
- PKIX_ISCERTSELFISSUEDFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- ((PKIX_PL_Object *)state->traversedSubjNames,
- (PKIX_PL_Object **)&childTraversedSubjNames,
- plContext),
- PKIX_OBJECTDUPLICATEFAILED);
-
- if (isSelfIssued) {
- childTraversedCACerts = state->traversedCACerts;
- } else {
- childTraversedCACerts = state->traversedCACerts + 1;
-
- PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames
- (state->candidateCert,
- &subjectNames,
- plContext),
- PKIX_CERTGETALLSUBJECTNAMESFAILED);
-
- if (subjectNames) {
- PKIX_CHECK(PKIX_List_GetLength
- (subjectNames,
- &numSubjectNames,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- } else {
- numSubjectNames = 0;
- }
-
- for (i = 0; i < numSubjectNames; i++) {
- PKIX_CHECK(PKIX_List_GetItem
- (subjectNames,
- i,
- &subjectName,
- plContext),
- PKIX_LISTGETITEMFAILED);
- PKIX_NULLCHECK_ONE
- (state->traversedSubjNames);
- PKIX_CHECK(PKIX_List_AppendItem
- (state->traversedSubjNames,
- subjectName,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_DECREF(subjectName);
- }
- PKIX_DECREF(subjectNames);
- }
-
- PKIX_CHECK(pkix_ForwardBuilderState_Create
- (childTraversedCACerts,
- state->buildConstants.maxFanout,
- state->numDepth - 1,
- state->revCheckDelayed,
- canBeCached,
- validityDate,
- state->candidateCert,
- childTraversedSubjNames,
- state->trustChain,
- state,
- &childState,
- plContext),
- PKIX_FORWARDBUILDSTATECREATEFAILED);
-
- PKIX_DECREF(childTraversedSubjNames);
- PKIX_DECREF(certSelParams);
- childState->verifyNode = verifyNode;
- verifyNode = NULL;
- PKIX_DECREF(state);
- state = childState; /* state->status == BUILD_INITIAL */
- childState = NULL;
- continue; /* with while (!outOfOptions) */
- }
-
- if (state->status == BUILD_GETNEXTCERT) {
- pkixTempErrorReceived = PKIX_FALSE;
- PKIX_DECREF(state->candidateCert);
-
- /*
- * If we were using a Cert from the callier-supplied partial
- * chain, delete it and go to the certStores.
- */
- if (state->usingHintCerts == PKIX_TRUE) {
- PKIX_DECREF(state->candidateCerts);
- PKIX_CHECK(PKIX_List_Create
- (&state->candidateCerts, plContext),
- PKIX_LISTCREATEFAILED);
-
- state->numCerts = 0;
- state->usingHintCerts = PKIX_FALSE;
- state->status = BUILD_TRYAIA;
- continue;
- } else if (++(state->certIndex) < (state->numCerts)) {
- if ((state->buildConstants.maxFanout != 0) &&
- (--(state->numFanout) == 0)) {
-
- if (state->verifyNode != NULL) {
- PKIX_ERROR_CREATE
- (BUILD,
- PKIX_FANOUTEXCEEDSRESOURCELIMITS,
- verifyError);
- PKIX_CHECK_FATAL
- (pkix_VerifyNode_SetError
- (state->verifyNode,
- verifyError,
- plContext),
- PKIX_VERIFYNODESETERRORFAILED);
- PKIX_DECREF(finalError);
- finalError = verifyError;
- verifyError = NULL;
- }
- /* Even if error logged, still need to abort */
- PKIX_ERROR
- (PKIX_FANOUTEXCEEDSRESOURCELIMITS);
- }
- state->status = BUILD_CERTVALIDATING;
- continue;
- }
- }
-
- /*
- * Adding the current cert to the chain didn't help. If our search
- * has been restricted to local certStores, try opening up the
- * search and see whether that helps. Otherwise, back up to the
- * parent cert, and see if there are any more to try.
- */
- if (state->useOnlyLocal == PKIX_TRUE) {
- pkix_PrepareForwardBuilderStateForAIA(state);
- } else do {
- if (state->parentState == NULL) {
- /* We are at the top level, and can't back up! */
- outOfOptions = PKIX_TRUE;
- } else {
- /*
- * Try the next cert, if any, for this parent.
- * Otherwise keep backing up until we reach a
- * parent with more certs to try.
- */
- PKIX_CHECK(PKIX_List_GetLength
- (state->trustChain, &numChained, plContext),
- PKIX_LISTGETLENGTHFAILED);
- PKIX_CHECK(PKIX_List_DeleteItem
- (state->trustChain, numChained - 1, plContext),
- PKIX_LISTDELETEITEMFAILED);
-
- /* local and aia fetching returned no good certs.
- * Creating a verify node in the parent that tells
- * us this. */
- if (!state->verifyNode) {
- PKIX_CHECK_FATAL(
- pkix_VerifyNode_Create(state->prevCert,
- 0, NULL,
- &state->verifyNode,
- plContext),
- PKIX_VERIFYNODECREATEFAILED);
- }
- /* Updating the log with the error. */
- PKIX_DECREF(verifyError);
- PKIX_ERROR_CREATE(BUILD, PKIX_SECERRORUNKNOWNISSUER,
- verifyError);
- PKIX_CHECK_FATAL(
- pkix_VerifyNode_SetError(state->verifyNode,
- verifyError,
- plContext),
- PKIX_VERIFYNODESETERRORFAILED);
- PKIX_DECREF(verifyError);
-
- PKIX_INCREF(state->parentState);
- parentState = state->parentState;
- PKIX_DECREF(verifyNode);
- verifyNode = state->verifyNode;
- state->verifyNode = NULL;
- PKIX_DECREF(state);
- state = parentState;
- parentState = NULL;
- if (state->verifyNode != NULL && verifyNode) {
- PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
- (state->verifyNode,
- verifyNode,
- plContext),
- PKIX_VERIFYNODEADDTOTREEFAILED);
- PKIX_DECREF(verifyNode);
- }
- PKIX_DECREF(validityDate);
- PKIX_INCREF(state->validityDate);
- validityDate = state->validityDate;
- canBeCached = state->canBeCached;
-
- /* Are there any more Certs to try? */
- if (++(state->certIndex) < (state->numCerts)) {
- state->status = BUILD_CERTVALIDATING;
- PKIX_DECREF(state->candidateCert);
- break;
- }
- if (state->useOnlyLocal == PKIX_TRUE) {
- /* Clean up and go for AIA round. */
- pkix_PrepareForwardBuilderStateForAIA(state);
- break;
- }
- }
- PKIX_DECREF(state->candidateCert);
- } while (outOfOptions == PKIX_FALSE);
-
- } /* while (outOfOptions == PKIX_FALSE) */
-
-cleanup:
-
- if (pkixErrorClass == PKIX_FATAL_ERROR) {
- goto fatal;
- }
-
- /* verifyNode should be equal to NULL at this point. Assert it.
- * Temporarelly use verifyError to store an error ref to which we
- * have in pkixErrorResult. This is done to prevent error cloberring
- * while using macros below. */
- PORT_Assert(verifyError == NULL);
- verifyError = pkixErrorResult;
-
- /*
- * We were called with an initialState that had no parent. If we are
- * returning with an error or with a result, we must destroy any state
- * that we created (any state with a parent).
- */
-
- PKIX_CHECK_FATAL(pkix_ForwardBuilderState_IsIOPending
- (state, &ioPending, plContext),
- PKIX_FORWARDBUILDERSTATEISIOPENDINGFAILED);
-
- if (ioPending == PKIX_FALSE) {
- while (state->parentState) {
- PKIX_INCREF(state->parentState);
- parentState = state->parentState;
- PKIX_DECREF(verifyNode);
- verifyNode = state->verifyNode;
- state->verifyNode = NULL;
- PKIX_DECREF(state);
- state = parentState;
- parentState = NULL;
- if (state->verifyNode != NULL && verifyNode) {
- PKIX_CHECK_FATAL(pkix_VerifyNode_AddToTree
- (state->verifyNode,
- verifyNode,
- plContext),
- PKIX_VERIFYNODEADDTOTREEFAILED);
- PKIX_DECREF(verifyNode);
- }
- }
- state->canBeCached = canBeCached;
- PKIX_DECREF(state->validityDate);
- state->validityDate = validityDate;
- validityDate = NULL;
- }
- if (!*pValResult && !verifyError) {
- if (!finalError) {
- PKIX_CHECK_FATAL(
- pkix_VerifyNode_FindError(state->verifyNode,
- &finalError,
- plContext),
- PKIX_VERIFYNODEFINDERRORFAILED);
- }
- if (finalError) {
- pkixErrorResult = finalError;
- pkixErrorCode = PKIX_BUILDFORWARDDEPTHFIRSTSEARCHFAILED;
- finalError = NULL;
- goto fatal;
- }
- pkixErrorCode = PKIX_SECERRORUNKNOWNISSUER;
- pkixErrorReceived = PKIX_TRUE;
- PKIX_ERROR_CREATE(BUILD, PKIX_SECERRORUNKNOWNISSUER,
- verifyError);
- PKIX_CHECK_FATAL(
- pkix_VerifyNode_SetError(state->verifyNode, verifyError,
- plContext),
- PKIX_VERIFYNODESETERRORFAILED);
- } else {
- pkixErrorResult = verifyError;
- verifyError = NULL;
- }
-
-fatal:
- if (state->parentState) {
- /* parentState in "state" object should be NULL at this point.
- * If itn't, that means that we got fatal error(we have jumped to
- * "fatal" label) and we should destroy all state except the top one. */
- while (state->parentState) {
- PKIX_Error *error = NULL;
- PKIX_ForwardBuilderState *prntState = state->parentState;
- /* Dumb: need to increment parentState to avoid destruction
- * of "build constants"(they get destroyed when parentState is
- * set to NULL. */
- PKIX_INCREF(prntState);
- error = PKIX_PL_Object_DecRef((PKIX_PL_Object*)state, plContext);
- if (error) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)error, plContext);
- }
- /* No need to decref the parent state. It was already done by
- * pkix_ForwardBuilderState_Destroy function. */
- state = prntState;
- }
- }
- PKIX_DECREF(parentState);
- PKIX_DECREF(childState);
- PKIX_DECREF(valResult);
- PKIX_DECREF(verifyError);
- PKIX_DECREF(finalError);
- PKIX_DECREF(verifyNode);
- PKIX_DECREF(childTraversedSubjNames);
- PKIX_DECREF(certSelParams);
- PKIX_DECREF(subjectNames);
- PKIX_DECREF(subjectName);
- PKIX_DECREF(trustAnchor);
- PKIX_DECREF(validityDate);
- PKIX_DECREF(revCheckerState);
- PKIX_DECREF(currTime);
- PKIX_DECREF(filteredCerts);
- PKIX_DECREF(unfilteredCerts);
- PKIX_DECREF(trustedCert);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_Build_CheckInCache
- * DESCRIPTION:
- *
- * The function tries to locate a chain for a cert in the cert chain cache.
- * If found, the chain goes through revocation chacking and returned back to
- * caller. Chains that fail revocation check get removed from cache.
- *
- * PARAMETERS:
- * "state"
- * Address of ForwardBuilderState to be used. Must be non-NULL.
- * "pBuildResult"
- * Address at which the BuildResult is stored, after a successful build.
- * Must be non-NULL.
- * "pNBIOContext"
- * Address at which the NBIOContext is stored indicating whether the
- * validation is complete. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error*
-pkix_Build_CheckInCache(
- PKIX_ForwardBuilderState *state,
- PKIX_BuildResult **pBuildResult,
- void **pNBIOContext,
- void *plContext)
-{
- PKIX_PL_Cert *targetCert = NULL;
- PKIX_List *anchors = NULL;
- PKIX_PL_Date *testDate = NULL;
- PKIX_BuildResult *buildResult = NULL;
- PKIX_ValidateResult *valResult = NULL;
- PKIX_Error *buildError = NULL;
- PKIX_TrustAnchor *matchingAnchor = NULL;
- PKIX_PL_Cert *trustedCert = NULL;
- PKIX_List *certList = NULL;
- PKIX_Boolean cacheHit = PKIX_FALSE;
- PKIX_Boolean trusted = PKIX_FALSE;
- PKIX_Boolean stillValid = PKIX_FALSE;
- void *nbioContext = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_CheckInCache");
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- targetCert = state->buildConstants.targetCert;
- anchors = state->buildConstants.anchors;
- testDate = state->buildConstants.testDate;
-
- /* Check whether this cert verification has been cached. */
- PKIX_CHECK(pkix_CacheCertChain_Lookup
- (targetCert,
- anchors,
- testDate,
- &cacheHit,
- &buildResult,
- plContext),
- PKIX_CACHECERTCHAINLOOKUPFAILED);
-
- if (!cacheHit) {
- goto cleanup;
- }
-
- /*
- * We found something in cache. Verify that the anchor
- * cert is still trusted,
- */
- PKIX_CHECK(PKIX_BuildResult_GetValidateResult
- (buildResult, &valResult, plContext),
- PKIX_BUILDRESULTGETVALIDATERESULTFAILED);
-
- PKIX_CHECK(PKIX_ValidateResult_GetTrustAnchor
- (valResult, &matchingAnchor, plContext),
- PKIX_VALIDATERESULTGETTRUSTANCHORFAILED);
-
- PKIX_DECREF(valResult);
-
- PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
- (matchingAnchor, &trustedCert, plContext),
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
-
- if (state->buildConstants.anchors &&
- state->buildConstants.anchors->length) {
- /* Check if it is one of the trust anchors */
- PKIX_CHECK(
- pkix_List_Contains(state->buildConstants.anchors,
- (PKIX_PL_Object *)matchingAnchor,
- &trusted,
- plContext),
- PKIX_LISTCONTAINSFAILED);
- } else {
- PKIX_CHECK(PKIX_PL_Cert_IsCertTrusted
- (trustedCert, PKIX_FALSE, &trusted, plContext),
- PKIX_CERTISCERTTRUSTEDFAILED);
- }
-
- if (!trusted) {
- goto cleanup;
- }
- /*
- * Since the key usage may vary for different
- * applications, we need to verify the chain again.
- * Reverification will be improved with a fix for 397805.
- */
- PKIX_CHECK(PKIX_BuildResult_GetCertChain
- (buildResult, &certList, plContext),
- PKIX_BUILDRESULTGETCERTCHAINFAILED);
-
- PKIX_CHECK(pkix_Build_ValidationCheckers
- (state,
- certList,
- matchingAnchor,
- PKIX_TRUE, /* Chain revalidation stage. */
- plContext),
- PKIX_BUILDVALIDATIONCHECKERSFAILED);
-
- PKIX_CHECK_ONLY_FATAL(
- pkix_Build_ValidateEntireChain(state, matchingAnchor,
- &nbioContext, &valResult,
- state->verifyNode, plContext),
- PKIX_BUILDVALIDATEENTIRECHAINFAILED);
-
- if (nbioContext != NULL) {
- /* IO still pending, resume later */
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
- if (!PKIX_ERROR_RECEIVED) {
- /* The result from cache is still valid. But we replace an old*/
- *pBuildResult = buildResult;
- buildResult = NULL;
- stillValid = PKIX_TRUE;
- }
-
-cleanup:
-
- if (!nbioContext && cacheHit && !(trusted && stillValid)) {
- /* The anchor of this chain is no longer trusted or
- * chain cert(s) has been revoked.
- * Invalidate this result in the cache */
- buildError = pkixErrorResult;
- PKIX_CHECK_FATAL(pkix_CacheCertChain_Remove
- (targetCert,
- anchors,
- plContext),
- PKIX_CACHECERTCHAINREMOVEFAILED);
- pkixErrorResult = buildError;
- buildError = NULL;
- }
-
-fatal:
- PKIX_DECREF(buildResult);
- PKIX_DECREF(valResult);
- PKIX_DECREF(buildError);
- PKIX_DECREF(certList);
- PKIX_DECREF(matchingAnchor);
- PKIX_DECREF(trustedCert);
-
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_Build_InitiateBuildChain
- * DESCRIPTION:
- *
- * This function initiates the search for a BuildChain, using the parameters
- * provided in "procParams" and, if continuing a search that was suspended
- * for I/O, using the ForwardBuilderState pointed to by "pState".
- *
- * If a successful chain is built, this function stores the BuildResult at
- * "pBuildResult". Alternatively, if an operation using non-blocking I/O
- * is in progress and the operation has not been completed, this function
- * stores the platform-dependent non-blocking I/O context (nbioContext) at
- * "pNBIOContext", the FowardBuilderState at "pState", and NULL at
- * "pBuildResult". Finally, if chain building was unsuccessful, this function
- * stores NULL at both "pState" and at "pBuildResult".
- *
- * Note: This function is re-entered only for the case of non-blocking I/O
- * in the "short-cut" attempt to build a chain using the target Certificate
- * directly with one of the trustAnchors. For all other cases, resumption
- * after non-blocking I/O is via pkix_Build_ResumeBuildChain.
- *
- * PARAMETERS:
- * "procParams"
- * Address of the ProcessingParams for the search. Must be non-NULL.
- * "pNBIOContext"
- * Address at which the NBIOContext is stored indicating whether the
- * validation is complete. Must be non-NULL.
- * "pState"
- * Address at which the ForwardBuilderState is stored, if the chain
- * building is suspended for waiting I/O; also, the address at which the
- * ForwardBuilderState is provided for resumption of the chain building
- * attempt. Must be non-NULL.
- * "pBuildResult"
- * Address at which the BuildResult is stored, after a successful build.
- * Must be non-NULL.
- * "pVerifyNode"
- * Address at which a VerifyNode chain is returned, if non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_InitiateBuildChain(
- PKIX_ProcessingParams *procParams,
- void **pNBIOContext,
- PKIX_ForwardBuilderState **pState,
- PKIX_BuildResult **pBuildResult,
- PKIX_VerifyNode **pVerifyNode,
- void *plContext)
-{
- PKIX_UInt32 numAnchors = 0;
- PKIX_UInt32 numCertStores = 0;
- PKIX_UInt32 numHintCerts = 0;
- PKIX_UInt32 i = 0;
- PKIX_Boolean isDuplicate = PKIX_FALSE;
- PKIX_PL_Cert *trustedCert = NULL;
- PKIX_CertSelector *targetConstraints = NULL;
- PKIX_ComCertSelParams *targetParams = NULL;
- PKIX_List *anchors = NULL;
- PKIX_List *targetSubjNames = NULL;
- PKIX_PL_Cert *targetCert = NULL;
- PKIX_PL_Object *firstHintCert = NULL;
- PKIX_RevocationChecker *revChecker = NULL;
- PKIX_List *certStores = NULL;
- PKIX_CertStore *certStore = NULL;
- PKIX_List *userCheckers = NULL;
- PKIX_List *hintCerts = NULL;
- PKIX_PL_Date *testDate = NULL;
- PKIX_PL_PublicKey *targetPubKey = NULL;
- void *nbioContext = NULL;
- BuildConstants buildConstants;
-
- PKIX_List *tentativeChain = NULL;
- PKIX_ValidateResult *valResult = NULL;
- PKIX_BuildResult *buildResult = NULL;
- PKIX_List *certList = NULL;
- PKIX_ForwardBuilderState *state = NULL;
- PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
- PKIX_CertSelector_MatchCallback selectorCallback = NULL;
- PKIX_Boolean trusted = PKIX_FALSE;
- PKIX_PL_AIAMgr *aiaMgr = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_InitiateBuildChain");
- PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- state = *pState;
- *pState = NULL; /* no net change in reference count */
-
- if (state == NULL) {
- PKIX_CHECK(PKIX_ProcessingParams_GetDate
- (procParams, &testDate, plContext),
- PKIX_PROCESSINGPARAMSGETDATEFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetTrustAnchors
- (procParams, &anchors, plContext),
- PKIX_PROCESSINGPARAMSGETTRUSTANCHORSFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(anchors, &numAnchors, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- /* retrieve stuff from targetCertConstraints */
- PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
- (procParams, &targetConstraints, plContext),
- PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
-
- PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
- (targetConstraints, &targetParams, plContext),
- PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetCertificate
- (targetParams, &targetCert, plContext),
- PKIX_COMCERTSELPARAMSGETCERTIFICATEFAILED);
-
- PKIX_CHECK(
- PKIX_ComCertSelParams_SetLeafCertFlag(targetParams,
- PKIX_TRUE, plContext),
- PKIX_COMCERTSELPARAMSSETLEAFCERTFLAGFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetHintCerts
- (procParams, &hintCerts, plContext),
- PKIX_PROCESSINGPARAMSGETHINTCERTSFAILED);
-
- if (hintCerts != NULL) {
- PKIX_CHECK(PKIX_List_GetLength
- (hintCerts, &numHintCerts, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- /*
- * Caller must provide either a target Cert
- * (in ComCertSelParams->Certificate) or a partial Cert
- * chain (in ProcParams->HintCerts).
- */
-
- if (targetCert == NULL) {
-
- /* Use first cert of hintCerts as the targetCert */
- if (numHintCerts == 0) {
- PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED);
- }
-
- PKIX_CHECK(PKIX_List_GetItem
- (hintCerts,
- 0,
- (PKIX_PL_Object **)&targetCert,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_List_DeleteItem(hintCerts, 0, plContext),
- PKIX_LISTGETITEMFAILED);
- } else {
-
- /*
- * If the first hintCert is the same as the targetCert,
- * delete it from hintCerts.
- */
- if (numHintCerts != 0) {
- PKIX_CHECK(PKIX_List_GetItem
- (hintCerts, 0, &firstHintCert, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)targetCert,
- firstHintCert,
- &isDuplicate,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- if (isDuplicate) {
- PKIX_CHECK(PKIX_List_DeleteItem
- (hintCerts, 0, plContext),
- PKIX_LISTGETITEMFAILED);
- }
- PKIX_DECREF(firstHintCert);
- }
-
- }
-
- if (targetCert == NULL) {
- PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED);
- }
-
- PKIX_CHECK(PKIX_PL_Cert_IsLeafCertTrusted
- (targetCert,
- &trusted,
- plContext),
- PKIX_CERTISCERTTRUSTEDFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames
- (targetCert,
- &targetSubjNames,
- plContext),
- PKIX_CERTGETALLSUBJECTNAMESFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
- (targetCert, &targetPubKey, plContext),
- PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
-
- PKIX_CHECK(PKIX_List_Create(&tentativeChain, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (tentativeChain, (PKIX_PL_Object *)targetCert, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- if (procParams->qualifyTargetCert) {
- /* EE cert validation */
- /* Sync up the time on the target selector parameter struct. */
- PKIX_CHECK(
- PKIX_ComCertSelParams_SetCertificateValid(targetParams,
- testDate,
- plContext),
- PKIX_COMCERTSELPARAMSSETCERTIFICATEVALIDFAILED);
-
- PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
- (targetConstraints, &selectorCallback, plContext),
- PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
-
- pkixErrorResult =
- (*selectorCallback)(targetConstraints, targetCert,
- plContext);
- if (pkixErrorResult) {
- pkixErrorClass = pkixErrorResult->errClass;
- if (pkixErrorClass == PKIX_FATAL_ERROR) {
- goto cleanup;
- }
- if (pVerifyNode != NULL) {
- PKIX_Error *tempResult =
- pkix_VerifyNode_Create(targetCert, 0,
- pkixErrorResult,
- pVerifyNode,
- plContext);
- if (tempResult) {
- PKIX_DECREF(pkixErrorResult);
- pkixErrorResult = tempResult;
- pkixErrorCode = PKIX_VERIFYNODECREATEFAILED;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
- }
- }
- pkixErrorCode = PKIX_CERTCHECKVALIDITYFAILED;
- goto cleanup;
- }
- }
-
- /* If the EE cert is trusted, force success. We only want to do
- * this if we aren't validating against a policy (like EV). */
- if (trusted && procParams->initialPolicies == NULL) {
- if (pVerifyNode != NULL) {
- PKIX_Error *tempResult =
- pkix_VerifyNode_Create(targetCert, 0, NULL,
- pVerifyNode,
- plContext);
- if (tempResult) {
- pkixErrorResult = tempResult;
- pkixErrorCode = PKIX_VERIFYNODECREATEFAILED;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
- }
- }
- PKIX_CHECK(pkix_ValidateResult_Create
- (targetPubKey, NULL /* anchor */,
- NULL /* policyTree */, &valResult, plContext),
- PKIX_VALIDATERESULTCREATEFAILED);
- PKIX_CHECK(
- pkix_BuildResult_Create(valResult, tentativeChain,
- &buildResult, plContext),
- PKIX_BUILDRESULTCREATEFAILED);
- *pBuildResult = buildResult;
- /* Note that *pState is NULL. The only side effect is that
- * the cert chain won't be cached in PKIX_BuildChain, which
- * is fine. */
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_ProcessingParams_GetCertStores
- (procParams, &certStores, plContext),
- PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength
- (certStores, &numCertStores, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- /* Reorder CertStores so trusted are at front of the List */
- if (numCertStores > 1) {
- for (i = numCertStores - 1; i > 0; i--) {
- PKIX_CHECK_ONLY_FATAL(PKIX_List_GetItem
- (certStores,
- i,
- (PKIX_PL_Object **)&certStore,
- plContext),
- PKIX_LISTGETITEMFAILED);
- PKIX_CHECK_ONLY_FATAL(PKIX_CertStore_GetTrustCallback
- (certStore, &trustCallback, plContext),
- PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
-
- if (trustCallback != NULL) {
- /* Is a trusted Cert, move CertStore to front */
- PKIX_CHECK(PKIX_List_DeleteItem
- (certStores, i, plContext),
- PKIX_LISTDELETEITEMFAILED);
- PKIX_CHECK(PKIX_List_InsertItem
- (certStores,
- 0,
- (PKIX_PL_Object *)certStore,
- plContext),
- PKIX_LISTINSERTITEMFAILED);
-
- }
-
- PKIX_DECREF(certStore);
- }
- }
-
- PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
- (procParams, &userCheckers, plContext),
- PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker
- (procParams, &revChecker, plContext),
- PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED);
- /* Do not initialize AIA manager if we are not going to fetch
- * cert using aia url. */
- if (procParams->useAIAForCertFetching) {
- PKIX_CHECK(PKIX_PL_AIAMgr_Create(&aiaMgr, plContext),
- PKIX_AIAMGRCREATEFAILED);
- }
-
- /*
- * We initialize all the fields of buildConstants here, in one place,
- * just to help keep track and ensure that we got everything.
- */
-
- buildConstants.numAnchors = numAnchors;
- buildConstants.numCertStores = numCertStores;
- buildConstants.numHintCerts = numHintCerts;
- buildConstants.procParams = procParams;
- buildConstants.testDate = testDate;
- buildConstants.timeLimit = NULL;
- buildConstants.targetCert = targetCert;
- buildConstants.targetPubKey = targetPubKey;
- buildConstants.certStores = certStores;
- buildConstants.anchors = anchors;
- buildConstants.userCheckers = userCheckers;
- buildConstants.hintCerts = hintCerts;
- buildConstants.revChecker = revChecker;
- buildConstants.aiaMgr = aiaMgr;
- buildConstants.trustOnlyUserAnchors =
- procParams->useOnlyTrustAnchors;
-
- PKIX_CHECK(pkix_Build_GetResourceLimits(&buildConstants, plContext),
- PKIX_BUILDGETRESOURCELIMITSFAILED);
-
- PKIX_CHECK(pkix_ForwardBuilderState_Create
- (0, /* PKIX_UInt32 traversedCACerts */
- buildConstants.maxFanout,
- buildConstants.maxDepth,
- PKIX_FALSE, /* PKIX_Boolean revCheckDelayed */
- PKIX_TRUE, /* PKIX_Boolean canBeCached */
- NULL, /* PKIX_Date *validityDate */
- targetCert, /* PKIX_PL_Cert *prevCert */
- targetSubjNames, /* PKIX_List *traversedSubjNames */
- tentativeChain, /* PKIX_List *trustChain */
- NULL, /* PKIX_ForwardBuilderState *parent */
- &state, /* PKIX_ForwardBuilderState **pState */
- plContext),
- PKIX_BUILDSTATECREATEFAILED);
-
- state->buildConstants.numAnchors = buildConstants.numAnchors;
- state->buildConstants.numCertStores = buildConstants.numCertStores;
- state->buildConstants.numHintCerts = buildConstants.numHintCerts;
- state->buildConstants.maxFanout = buildConstants.maxFanout;
- state->buildConstants.maxDepth = buildConstants.maxDepth;
- state->buildConstants.maxTime = buildConstants.maxTime;
- state->buildConstants.procParams = buildConstants.procParams;
- PKIX_INCREF(buildConstants.testDate);
- state->buildConstants.testDate = buildConstants.testDate;
- state->buildConstants.timeLimit = buildConstants.timeLimit;
- PKIX_INCREF(buildConstants.targetCert);
- state->buildConstants.targetCert = buildConstants.targetCert;
- PKIX_INCREF(buildConstants.targetPubKey);
- state->buildConstants.targetPubKey =
- buildConstants.targetPubKey;
- PKIX_INCREF(buildConstants.certStores);
- state->buildConstants.certStores = buildConstants.certStores;
- PKIX_INCREF(buildConstants.anchors);
- state->buildConstants.anchors = buildConstants.anchors;
- PKIX_INCREF(buildConstants.userCheckers);
- state->buildConstants.userCheckers =
- buildConstants.userCheckers;
- PKIX_INCREF(buildConstants.hintCerts);
- state->buildConstants.hintCerts = buildConstants.hintCerts;
- PKIX_INCREF(buildConstants.revChecker);
- state->buildConstants.revChecker = buildConstants.revChecker;
- state->buildConstants.aiaMgr = buildConstants.aiaMgr;
- aiaMgr = NULL;
- state->buildConstants.trustOnlyUserAnchors =
- buildConstants.trustOnlyUserAnchors;
-
- if (buildConstants.maxTime != 0) {
- PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds
- (buildConstants.maxTime,
- &state->buildConstants.timeLimit,
- plContext),
- PKIX_DATECREATECURRENTOFFBYSECONDSFAILED);
- }
-
- if (pVerifyNode != NULL) {
- PKIX_Error *tempResult =
- pkix_VerifyNode_Create(targetCert, 0, NULL,
- &(state->verifyNode),
- plContext);
- if (tempResult) {
- pkixErrorResult = tempResult;
- pkixErrorCode = PKIX_VERIFYNODECREATEFAILED;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
- }
- }
-
- PKIX_CHECK_ONLY_FATAL(
- pkix_Build_CheckInCache(state, &buildResult,
- &nbioContext, plContext),
- PKIX_UNABLETOBUILDCHAIN);
- if (nbioContext) {
- *pNBIOContext = nbioContext;
- *pState = state;
- state = NULL;
- goto cleanup;
- }
- if (buildResult) {
- *pBuildResult = buildResult;
- if (pVerifyNode != NULL) {
- *pVerifyNode = state->verifyNode;
- state->verifyNode = NULL;
- }
- goto cleanup;
- }
- }
-
- /* If we're resuming after non-blocking I/O we need to get SubjNames */
- if (targetSubjNames == NULL) {
- PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames
- (state->buildConstants.targetCert,
- &targetSubjNames,
- plContext),
- PKIX_CERTGETALLSUBJECTNAMESFAILED);
- }
-
- state->status = BUILD_INITIAL;
-
- pkixErrorResult =
- pkix_BuildForwardDepthFirstSearch(&nbioContext, state,
- &valResult, plContext);
-
- /* non-null nbioContext means the build would block */
- if (pkixErrorResult == NULL && nbioContext != NULL) {
-
- *pNBIOContext = nbioContext;
- *pBuildResult = NULL;
-
- /* no valResult means the build has failed */
- } else {
- if (pVerifyNode != NULL) {
- PKIX_INCREF(state->verifyNode);
- *pVerifyNode = state->verifyNode;
- }
-
- if (valResult == NULL || pkixErrorResult)
- PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN);
- PKIX_CHECK(
- pkix_BuildResult_Create(valResult, state->trustChain,
- &buildResult, plContext),
- PKIX_BUILDRESULTCREATEFAILED);
- *pBuildResult = buildResult;
- }
-
- *pState = state;
- state = NULL;
-
-cleanup:
-
- PKIX_DECREF(targetConstraints);
- PKIX_DECREF(targetParams);
- PKIX_DECREF(anchors);
- PKIX_DECREF(targetSubjNames);
- PKIX_DECREF(targetCert);
- PKIX_DECREF(revChecker);
- PKIX_DECREF(certStores);
- PKIX_DECREF(certStore);
- PKIX_DECREF(userCheckers);
- PKIX_DECREF(hintCerts);
- PKIX_DECREF(firstHintCert);
- PKIX_DECREF(testDate);
- PKIX_DECREF(targetPubKey);
- PKIX_DECREF(tentativeChain);
- PKIX_DECREF(valResult);
- PKIX_DECREF(certList);
- PKIX_DECREF(trustedCert);
- PKIX_DECREF(state);
- PKIX_DECREF(aiaMgr);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_Build_ResumeBuildChain
- * DESCRIPTION:
- *
- * This function continues the search for a BuildChain, using the parameters
- * provided in "procParams" and the ForwardBuilderState pointed to by "state".
- *
- * If a successful chain is built, this function stores the BuildResult at
- * "pBuildResult". Alternatively, if an operation using non-blocking I/O
- * is in progress and the operation has not been completed, this function
- * stores the FowardBuilderState at "pState" and NULL at "pBuildResult".
- * Finally, if chain building was unsuccessful, this function stores NULL
- * at both "pState" and at "pBuildResult".
- *
- * PARAMETERS:
- * "pNBIOContext"
- * Address at which the NBIOContext is stored indicating whether the
- * validation is complete. Must be non-NULL.
- * "pState"
- * Address at which the ForwardBuilderState is provided for resumption of
- * the chain building attempt; also, the address at which the
- * ForwardBuilderStateis stored, if the chain building is suspended for
- * waiting I/O. Must be non-NULL.
- * "pBuildResult"
- * Address at which the BuildResult is stored, after a successful build.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Build Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Build_ResumeBuildChain(
- void **pNBIOContext,
- PKIX_ForwardBuilderState *state,
- PKIX_BuildResult **pBuildResult,
- PKIX_VerifyNode **pVerifyNode,
- void *plContext)
-{
- PKIX_ValidateResult *valResult = NULL;
- PKIX_BuildResult *buildResult = NULL;
- void *nbioContext = NULL;
-
- PKIX_ENTER(BUILD, "pkix_Build_ResumeBuildChain");
- PKIX_NULLCHECK_TWO(state, pBuildResult);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- pkixErrorResult =
- pkix_BuildForwardDepthFirstSearch(&nbioContext, state,
- &valResult, plContext);
-
- /* non-null nbioContext means the build would block */
- if (pkixErrorResult == NULL && nbioContext != NULL) {
-
- *pNBIOContext = nbioContext;
- *pBuildResult = NULL;
-
- /* no valResult means the build has failed */
- } else {
- if (pVerifyNode != NULL) {
- PKIX_INCREF(state->verifyNode);
- *pVerifyNode = state->verifyNode;
- }
-
- if (valResult == NULL || pkixErrorResult)
- PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN);
-
- PKIX_CHECK(
- pkix_BuildResult_Create(valResult, state->trustChain,
- &buildResult, plContext),
- PKIX_BUILDRESULTCREATEFAILED);
- *pBuildResult = buildResult;
- }
-
-cleanup:
-
- PKIX_DECREF(valResult);
-
- PKIX_RETURN(BUILD);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_BuildChain (see comments in pkix.h)
- */
-PKIX_Error *
-PKIX_BuildChain(
- PKIX_ProcessingParams *procParams,
- void **pNBIOContext,
- void **pState,
- PKIX_BuildResult **pBuildResult,
- PKIX_VerifyNode **pVerifyNode,
- void *plContext)
-{
- PKIX_ForwardBuilderState *state = NULL;
- PKIX_BuildResult *buildResult = NULL;
- void *nbioContext = NULL;
-
- PKIX_ENTER(BUILD, "PKIX_BuildChain");
- PKIX_NULLCHECK_FOUR(procParams, pNBIOContext, pState, pBuildResult);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- if (*pState == NULL) {
- PKIX_CHECK(pkix_Build_InitiateBuildChain
- (procParams,
- &nbioContext,
- &state,
- &buildResult,
- pVerifyNode,
- plContext),
- PKIX_BUILDINITIATEBUILDCHAINFAILED);
- } else {
- state = (PKIX_ForwardBuilderState *)(*pState);
- *pState = NULL; /* no net change in reference count */
- if (state->status == BUILD_SHORTCUTPENDING) {
- PKIX_CHECK(pkix_Build_InitiateBuildChain
- (procParams,
- &nbioContext,
- &state,
- &buildResult,
- pVerifyNode,
- plContext),
- PKIX_BUILDINITIATEBUILDCHAINFAILED);
- } else {
- PKIX_CHECK(pkix_Build_ResumeBuildChain
- (&nbioContext,
- state,
- &buildResult,
- pVerifyNode,
- plContext),
- PKIX_BUILDINITIATEBUILDCHAINFAILED);
- }
- }
-
- /* non-null nbioContext means the build would block */
- if (nbioContext != NULL) {
-
- *pNBIOContext = nbioContext;
- *pState = state;
- state = NULL;
- *pBuildResult = NULL;
-
- /* no buildResult means the build has failed */
- } else if (buildResult == NULL) {
- PKIX_ERROR(PKIX_UNABLETOBUILDCHAIN);
- } else {
- /*
- * If we made a successful chain by combining the target Cert
- * with one of the Trust Anchors, we may have never created a
- * validityDate. We treat this situation as
- * canBeCached = PKIX_FALSE.
- */
- if ((state != NULL) &&
- ((state->validityDate) != NULL) &&
- (state->canBeCached)) {
- PKIX_CHECK(pkix_CacheCertChain_Add
- (state->buildConstants.targetCert,
- state->buildConstants.anchors,
- state->validityDate,
- buildResult,
- plContext),
- PKIX_CACHECERTCHAINADDFAILED);
- }
-
- *pState = NULL;
- *pBuildResult = buildResult;
- buildResult = NULL;
- }
-
-cleanup:
- PKIX_DECREF(buildResult);
- PKIX_DECREF(state);
-
- PKIX_RETURN(BUILD);
-}
diff --git a/security/nss/lib/libpkix/pkix/top/pkix_build.h b/security/nss/lib/libpkix/pkix/top/pkix_build.h
deleted file mode 100755
index 91916d4c8..000000000
--- a/security/nss/lib/libpkix/pkix/top/pkix_build.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_build.h
- *
- * Header file for buildChain function
- *
- */
-
-#ifndef _PKIX_BUILD_H
-#define _PKIX_BUILD_H
-#include "pkix_tools.h"
-#include "pkix_pl_ldapt.h"
-#include "pkix_ekuchecker.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- BUILD_SHORTCUTPENDING,
- BUILD_INITIAL,
- BUILD_TRYAIA,
- BUILD_AIAPENDING,
- BUILD_COLLECTINGCERTS,
- BUILD_GATHERPENDING,
- BUILD_CERTVALIDATING,
- BUILD_ABANDONNODE,
- BUILD_CRLPREP,
- BUILD_CRL1,
- BUILD_DATEPREP,
- BUILD_CHECKTRUSTED,
- BUILD_CHECKTRUSTED2,
- BUILD_ADDTOCHAIN,
- BUILD_CRL2PREP,
- BUILD_CRL2,
- BUILD_VALCHAIN,
- BUILD_VALCHAIN2,
- BUILD_EXTENDCHAIN,
- BUILD_GETNEXTCERT
-} BuildStatus;
-
-typedef struct BuildConstantsStruct BuildConstants;
-
-/*
- * These fields (the ones that are objects) are not reference-counted
- * in *each* state, but only in the root, the state that has no parent.
- * That saves time in creation and destruction of child states, but is
- * safe enough since they are constants.
- */
-struct BuildConstantsStruct {
- PKIX_UInt32 numAnchors;
- PKIX_UInt32 numCertStores;
- PKIX_UInt32 numHintCerts;
- PKIX_UInt32 maxDepth;
- PKIX_UInt32 maxFanout;
- PKIX_UInt32 maxTime;
- PKIX_ProcessingParams *procParams;
- PKIX_PL_Date *testDate;
- PKIX_PL_Date *timeLimit;
- PKIX_PL_Cert *targetCert;
- PKIX_PL_PublicKey *targetPubKey;
- PKIX_List *certStores;
- PKIX_List *anchors;
- PKIX_List *userCheckers;
- PKIX_List *hintCerts;
- PKIX_RevocationChecker *revChecker;
- PKIX_PL_AIAMgr *aiaMgr;
- PKIX_Boolean useAIAForCertFetching;
- PKIX_Boolean trustOnlyUserAnchors;
-};
-
-struct PKIX_ForwardBuilderStateStruct{
- BuildStatus status;
- PKIX_Int32 traversedCACerts;
- PKIX_UInt32 certStoreIndex;
- PKIX_UInt32 numCerts;
- PKIX_UInt32 numAias;
- PKIX_UInt32 certIndex;
- PKIX_UInt32 aiaIndex;
- PKIX_UInt32 certCheckedIndex;
- PKIX_UInt32 checkerIndex;
- PKIX_UInt32 hintCertIndex;
- PKIX_UInt32 numFanout;
- PKIX_UInt32 numDepth;
- PKIX_UInt32 reasonCode;
- PKIX_Boolean revCheckDelayed;
- PKIX_Boolean canBeCached;
- PKIX_Boolean useOnlyLocal;
- PKIX_Boolean revChecking;
- PKIX_Boolean usingHintCerts;
- PKIX_Boolean certLoopingDetected;
- PKIX_PL_Date *validityDate;
- PKIX_PL_Cert *prevCert;
- PKIX_PL_Cert *candidateCert;
- PKIX_List *traversedSubjNames;
- PKIX_List *trustChain;
- PKIX_List *aia;
- PKIX_List *candidateCerts;
- PKIX_List *reversedCertChain;
- PKIX_List *checkedCritExtOIDs;
- PKIX_List *checkerChain;
- PKIX_CertSelector *certSel;
- PKIX_VerifyNode *verifyNode;
- void *client; /* messageHandler, such as LDAPClient */
- PKIX_ForwardBuilderState *parentState;
- BuildConstants buildConstants;
-};
-
-/* --Private-Functions-------------------------------------------- */
-
-PKIX_Error *
-pkix_ForwardBuilderState_RegisterSelf(void *plContext);
-
-PKIX_Error *
-PKIX_Build_GetNBIOContext(void *state, void **pNBIOContext, void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_BUILD_H */
diff --git a/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c b/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c
deleted file mode 100755
index aad0e1aaf..000000000
--- a/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_lifecycle.c
- *
- * Top level initialize and shutdown functions
- *
- */
-
-#include "pkix_lifecycle.h"
-
-static PKIX_Boolean pkixIsInitialized;
-
-/* Lock used by Logger - is reentrant by the same thread */
-extern PKIX_PL_MonitorLock *pkixLoggerLock;
-
-/*
- * Following pkix_* variables are for debugging purpose. They should be taken
- * out eventually. The purpose is to verify cache tables usage (via debugger).
- */
-int pkix_ccAddCount = 0;
-int pkix_ccLookupCount = 0;
-int pkix_ccRemoveCount = 0;
-int pkix_cAddCount = 0;
-int pkix_cLookupCount = 0;
-int pkix_cRemoveCount = 0;
-int pkix_ceAddCount = 0;
-int pkix_ceLookupCount = 0;
-
-PKIX_PL_HashTable *cachedCrlSigTable = NULL;
-PKIX_PL_HashTable *cachedCertSigTable = NULL;
-PKIX_PL_HashTable *cachedCertChainTable = NULL;
-PKIX_PL_HashTable *cachedCertTable = NULL;
-PKIX_PL_HashTable *cachedCrlEntryTable = NULL;
-PKIX_PL_HashTable *aiaConnectionCache = NULL;
-PKIX_PL_HashTable *httpSocketCache = NULL;
-
-extern PKIX_List *pkixLoggers;
-extern PKIX_List *pkixLoggersErrors;
-extern PKIX_List *pkixLoggersDebugTrace;
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_Initialize (see comments in pkix.h)
- */
-PKIX_Error *
-PKIX_Initialize(
- PKIX_Boolean platformInitNeeded,
- PKIX_UInt32 desiredMajorVersion,
- PKIX_UInt32 minDesiredMinorVersion,
- PKIX_UInt32 maxDesiredMinorVersion,
- PKIX_UInt32 *pActualMinorVersion,
- void **pPlContext)
-{
- void *plContext = NULL;
-
- PKIX_ENTER(LIFECYCLE, "PKIX_Initialize");
- PKIX_NULLCHECK_ONE(pPlContext);
-
- /*
- * If we are called a second time other than in the situation handled
- * above, we return a positive status.
- */
- if (pkixIsInitialized){
- /* Already initialized */
- PKIX_RETURN(LIFECYCLE);
- }
-
- PKIX_CHECK(PKIX_PL_Initialize
- (platformInitNeeded, PKIX_FALSE, &plContext),
- PKIX_INITIALIZEFAILED);
-
- *pPlContext = plContext;
-
- if (desiredMajorVersion != PKIX_MAJOR_VERSION){
- PKIX_ERROR(PKIX_MAJORVERSIONSDONTMATCH);
- }
-
- if ((minDesiredMinorVersion > PKIX_MINOR_VERSION) ||
- (maxDesiredMinorVersion < PKIX_MINOR_VERSION)){
- PKIX_ERROR(PKIX_MINORVERSIONNOTBETWEENDESIREDMINANDMAX);
- }
-
- *pActualMinorVersion = PKIX_MINOR_VERSION;
-
- /* Create Cache Tables
- * Do not initialize hash tables for object leak test */
-#if !defined(PKIX_OBJECT_LEAK_TEST)
- PKIX_CHECK(PKIX_PL_HashTable_Create
- (32, 0, &cachedCertSigTable, plContext),
- PKIX_HASHTABLECREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_HashTable_Create
- (32, 0, &cachedCrlSigTable, plContext),
- PKIX_HASHTABLECREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_HashTable_Create
- (32, 10, &cachedCertChainTable, plContext),
- PKIX_HASHTABLECREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_HashTable_Create
- (32, 10, &cachedCertTable, plContext),
- PKIX_HASHTABLECREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_HashTable_Create
- (32, 10, &cachedCrlEntryTable, plContext),
- PKIX_HASHTABLECREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_HashTable_Create
- (5, 5, &aiaConnectionCache, plContext),
- PKIX_HASHTABLECREATEFAILED);
-
-#ifdef PKIX_SOCKETCACHE
- PKIX_CHECK(PKIX_PL_HashTable_Create
- (5, 5, &httpSocketCache, plContext),
- PKIX_HASHTABLECREATEFAILED);
-#endif
- if (pkixLoggerLock == NULL) {
- PKIX_CHECK(PKIX_PL_MonitorLock_Create
- (&pkixLoggerLock, plContext),
- PKIX_MONITORLOCKCREATEFAILED);
- }
-#else
- fnInvTable = PL_NewHashTable(0, pkix_ErrorGen_Hash,
- PL_CompareValues,
- PL_CompareValues, NULL, NULL);
- if (!fnInvTable) {
- PKIX_ERROR(PKIX_HASHTABLECREATEFAILED);
- }
-
- fnStackNameArr = PORT_ZNewArray(char*, MAX_STACK_DEPTH);
- if (!fnStackNameArr) {
- PKIX_ERROR(PKIX_HASHTABLECREATEFAILED);
- }
-
- fnStackInvCountArr = PORT_ZNewArray(PKIX_UInt32, MAX_STACK_DEPTH);
- if (!fnStackInvCountArr) {
- PKIX_ERROR(PKIX_HASHTABLECREATEFAILED);
- }
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- pkixIsInitialized = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(LIFECYCLE);
-}
-
-/*
- * FUNCTION: PKIX_Shutdown (see comments in pkix.h)
- */
-PKIX_Error *
-PKIX_Shutdown(void *plContext)
-{
- PKIX_List *savedPkixLoggers = NULL;
- PKIX_List *savedPkixLoggersErrors = NULL;
- PKIX_List *savedPkixLoggersDebugTrace = NULL;
-
- PKIX_ENTER(LIFECYCLE, "PKIX_Shutdown");
-
- if (!pkixIsInitialized){
- /* The library was not initialized */
- PKIX_RETURN(LIFECYCLE);
- }
-
- pkixIsInitialized = PKIX_FALSE;
-
- if (pkixLoggers) {
- savedPkixLoggers = pkixLoggers;
- savedPkixLoggersErrors = pkixLoggersErrors;
- savedPkixLoggersDebugTrace = pkixLoggersDebugTrace;
- pkixLoggers = NULL;
- pkixLoggersErrors = NULL;
- pkixLoggersDebugTrace = NULL;
- PKIX_DECREF(savedPkixLoggers);
- PKIX_DECREF(savedPkixLoggersErrors);
- PKIX_DECREF(savedPkixLoggersDebugTrace);
- }
- PKIX_DECREF(pkixLoggerLock);
-
- /* Destroy Cache Tables */
- PKIX_DECREF(cachedCertSigTable);
- PKIX_DECREF(cachedCrlSigTable);
- PKIX_DECREF(cachedCertChainTable);
- PKIX_DECREF(cachedCertTable);
- PKIX_DECREF(cachedCrlEntryTable);
- PKIX_DECREF(aiaConnectionCache);
- PKIX_DECREF(httpSocketCache);
-
- /* Clean up any temporary errors that happened during shutdown */
- if (pkixErrorList) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorList, plContext);
- pkixErrorList = NULL;
- }
-
- PKIX_CHECK(PKIX_PL_Shutdown(plContext),
- PKIX_SHUTDOWNFAILED);
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- PORT_Free(fnStackInvCountArr);
- PORT_Free(fnStackNameArr);
- PL_HashTableDestroy(fnInvTable);
-#endif
-
-cleanup:
-
- PKIX_RETURN(LIFECYCLE);
-}
diff --git a/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.h b/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.h
deleted file mode 100755
index 02631229c..000000000
--- a/security/nss/lib/libpkix/pkix/top/pkix_lifecycle.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_lifecycle.h
- *
- * Header file for initialize and shutdown functions.
- *
- */
-
-#ifndef _PKIX_LIFECYCLE_H
-#define _PKIX_LIFECYCLE_H
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_LIFECYCLE_H */
diff --git a/security/nss/lib/libpkix/pkix/top/pkix_validate.c b/security/nss/lib/libpkix/pkix/top/pkix_validate.c
deleted file mode 100755
index edee9f32e..000000000
--- a/security/nss/lib/libpkix/pkix/top/pkix_validate.c
+++ /dev/null
@@ -1,1443 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_validate.c
- *
- * Top level validateChain function
- *
- */
-
-#include "pkix_validate.h"
-#include "pkix_pl_common.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_AddToVerifyLog
- * DESCRIPTION:
- *
- * This function returns immediately if the address for the VerifyNode tree
- * pointed to by "pVerifyTree" is NULL. Otherwise it creates a new VerifyNode
- * from the Cert pointed to by "cert" and the Error pointed to by "error",
- * and inserts it at the depth in the VerifyNode tree determined by "depth". A
- * depth of zero means that this function creates the root node of a new tree.
- *
- * Note: this function does not include the means of choosing among branches
- * of a tree. It is intended for non-branching trees, that is, where each
- * parent node has only a single child node.
- *
- * PARAMETERS:
- * "cert"
- * The address of the Cert to be included in the new VerifyNode. Must be
- * non-NULL.
- * "depth"
- * The UInt32 value of the depth.
- * "error"
- * The address of the Error to be included in the new VerifyNode.
- * "pVerifyTree"
- * The address of the VerifyNode tree into which the created VerifyNode
- * is to be inserted. The node is not created if VerifyTree is NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Validate Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_AddToVerifyLog(
- PKIX_PL_Cert *cert,
- PKIX_UInt32 depth,
- PKIX_Error *error,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext)
-{
-
- PKIX_VerifyNode *verifyNode = NULL;
-
- PKIX_ENTER(VALIDATE, "pkix_AddToVerifyLog");
- PKIX_NULLCHECK_ONE(cert);
-
- if (pVerifyTree) { /* nothing to do if no address given for log */
-
- PKIX_CHECK(pkix_VerifyNode_Create
- (cert, depth, error, &verifyNode, plContext),
- PKIX_VERIFYNODECREATEFAILED);
-
- if (depth == 0) {
- /* We just created the root node */
- *pVerifyTree = verifyNode;
- } else {
- PKIX_CHECK(pkix_VerifyNode_AddToChain
- (*pVerifyTree, verifyNode, plContext),
- PKIX_VERIFYNODEADDTOCHAINFAILED);
- }
- }
-
-cleanup:
-
- PKIX_RETURN(VALIDATE);
-
-}
-
-/*
- * FUNCTION: pkix_CheckCert
- * DESCRIPTION:
- *
- * Checks whether the Cert pointed to by "cert" successfully validates
- * using the List of CertChainCheckers pointed to by "checkers". If the
- * certificate does not validate, an Error pointer is returned.
- *
- * This function should be called initially with the UInt32 pointed to by
- * "pCheckerIndex" containing zero, and the pointer at "pNBIOContext"
- * containing NULL. If a checker does non-blocking I/O, this function will
- * return with the index of that checker stored at "pCheckerIndex" and a
- * platform-dependent non-blocking I/O context stored at "pNBIOContext".
- * A subsequent call to this function with those values intact will allow the
- * checking to resume where it left off. This should be repeated until the
- * function returns with NULL stored at "pNBIOContext".
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert to validate. Must be non-NULL.
- * "checkers"
- * List of CertChainCheckers which must each validate the certificate.
- * Must be non-NULL.
- * "checkedExtOIDs"
- * List of PKIX_PL_OID that has been processed. If called from building
- * chain, it is the list of critical extension OIDs that has been
- * processed prior to validation. May be NULL.
- * "pCheckerIndex"
- * Address at which is stored the the index, within the List "checkers",
- * of a checker whose processing was interrupted by non-blocking I/O.
- * Must be non-NULL.
- * "pNBIOContext"
- * Address at which is stored platform-specific non-blocking I/O context.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Validate Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_CheckCert(
- PKIX_PL_Cert *cert,
- PKIX_List *checkers,
- PKIX_List *checkedExtOIDsList,
- PKIX_UInt32 *pCheckerIndex,
- void **pNBIOContext,
- void *plContext)
-{
- PKIX_CertChainChecker_CheckCallback checkerCheck = NULL;
- PKIX_CertChainChecker *checker = NULL;
- PKIX_List *unresCritExtOIDs = NULL;
- PKIX_UInt32 numCheckers;
- PKIX_UInt32 numUnresCritExtOIDs = 0;
- PKIX_UInt32 checkerIndex = 0;
- void *nbioContext = NULL;
-
- PKIX_ENTER(VALIDATE, "pkix_CheckCert");
- PKIX_NULLCHECK_FOUR(cert, checkers, pCheckerIndex, pNBIOContext);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL; /* prepare for case of error exit */
-
- PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs
- (cert, &unresCritExtOIDs, plContext),
- PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (checkerIndex = *pCheckerIndex;
- checkerIndex < numCheckers;
- checkerIndex++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (checkers,
- checkerIndex,
- (PKIX_PL_Object **)&checker,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCheckCallback
- (checker, &checkerCheck, plContext),
- PKIX_CERTCHAINCHECKERGETCHECKCALLBACKFAILED);
-
- PKIX_CHECK(checkerCheck(checker, cert, unresCritExtOIDs,
- &nbioContext, plContext),
- PKIX_CERTCHAINCHECKERCHECKFAILED);
-
- if (nbioContext != NULL) {
- *pCheckerIndex = checkerIndex;
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
-
- PKIX_DECREF(checker);
- }
-
- if (unresCritExtOIDs){
-
-#ifdef PKIX_VALIDATEDEBUG
- {
- PKIX_PL_String *oidString = NULL;
- PKIX_UInt32 length;
- char *oidAscii = NULL;
- PKIX_TOSTRING(unresCritExtOIDs, &oidString, plContext,
- PKIX_LISTTOSTRINGFAILED);
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (oidString,
- PKIX_ESCASCII,
- (void **) &oidAscii,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
- PKIX_VALIDATE_DEBUG_ARG
- ("unrecognized critical extension OIDs:"
- " %s\n", oidAscii);
- PKIX_DECREF(oidString);
- PKIX_PL_Free(oidAscii, plContext);
- }
-#endif
-
- if (checkedExtOIDsList != NULL) {
- /* Take out OID's that had been processed, if any */
- PKIX_CHECK(pkix_List_RemoveItems
- (unresCritExtOIDs,
- checkedExtOIDsList,
- plContext),
- PKIX_LISTREMOVEITEMSFAILED);
- }
-
- PKIX_CHECK(PKIX_List_GetLength
- (unresCritExtOIDs, &numUnresCritExtOIDs, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (numUnresCritExtOIDs != 0){
- PKIX_ERROR(PKIX_UNRECOGNIZEDCRITICALEXTENSION);
- }
-
- }
-
-cleanup:
-
- PKIX_DECREF(checker);
- PKIX_DECREF(unresCritExtOIDs);
-
- PKIX_RETURN(VALIDATE);
-
-}
-
-/*
- * FUNCTION: pkix_InitializeCheckers
- * DESCRIPTION:
- *
- * Creates several checkers and initializes them with values derived from the
- * TrustAnchor pointed to by "anchor", the ProcessingParams pointed to by
- * "procParams", and the number of Certs in the Chain, represented by
- * "numCerts". The List of checkers is stored at "pCheckers".
- *
- * PARAMETERS:
- * "anchor"
- * Address of TrustAnchor used to initialize the SignatureChecker and
- * NameChainingChecker. Must be non-NULL.
- * "procParams"
- * Address of ProcessingParams used to initialize the ExpirationChecker
- * and TargetCertChecker. Must be non-NULL.
- * "numCerts"
- * Number of certificates in the CertChain.
- * "pCheckers"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Validate Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_InitializeCheckers(
- PKIX_TrustAnchor *anchor,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 numCerts,
- PKIX_List **pCheckers,
- void *plContext)
-{
- PKIX_CertChainChecker *targetCertChecker = NULL;
- PKIX_CertChainChecker *expirationChecker = NULL;
- PKIX_CertChainChecker *nameChainingChecker = NULL;
- PKIX_CertChainChecker *nameConstraintsChecker = NULL;
- PKIX_CertChainChecker *basicConstraintsChecker = NULL;
- PKIX_CertChainChecker *policyChecker = NULL;
- PKIX_CertChainChecker *sigChecker = NULL;
- PKIX_CertChainChecker *defaultCrlChecker = NULL;
- PKIX_CertChainChecker *userChecker = NULL;
- PKIX_PL_X500Name *trustedCAName = NULL;
- PKIX_PL_PublicKey *trustedPubKey = NULL;
- PKIX_List *checkers = NULL;
- PKIX_PL_Date *testDate = NULL;
- PKIX_CertSelector *certSelector = NULL;
- PKIX_PL_Cert *trustedCert = NULL;
- PKIX_PL_CertNameConstraints *trustedNC = NULL;
- PKIX_List *initialPolicies = NULL;
- PKIX_Boolean policyQualifiersRejected = PKIX_FALSE;
- PKIX_Boolean initialPolicyMappingInhibit = PKIX_FALSE;
- PKIX_Boolean initialAnyPolicyInhibit = PKIX_FALSE;
- PKIX_Boolean initialExplicitPolicy = PKIX_FALSE;
- PKIX_List *userCheckersList = NULL;
- PKIX_List *certStores = NULL;
- PKIX_UInt32 numCertCheckers = 0;
- PKIX_UInt32 i;
-
- PKIX_ENTER(VALIDATE, "pkix_InitializeCheckers");
- PKIX_NULLCHECK_THREE(anchor, procParams, pCheckers);
- PKIX_CHECK(PKIX_List_Create(&checkers, plContext),
- PKIX_LISTCREATEFAILED);
-
- /*
- * The TrustAnchor may have been created using CreateWithCert
- * (in which case GetCAPublicKey and GetCAName will return NULL)
- * or may have been created using CreateWithNameKeyPair (in which
- * case GetTrustedCert will return NULL. So we call GetTrustedCert
- * and populate trustedPubKey and trustedCAName accordingly.
- */
-
- PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
- (anchor, &trustedCert, plContext),
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
-
- if (trustedCert){
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
- (trustedCert, &trustedPubKey, plContext),
- PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubject
- (trustedCert, &trustedCAName, plContext),
- PKIX_CERTGETSUBJECTFAILED);
- } else {
- PKIX_CHECK(PKIX_TrustAnchor_GetCAPublicKey
- (anchor, &trustedPubKey, plContext),
- PKIX_TRUSTANCHORGETCAPUBLICKEYFAILED);
-
- PKIX_CHECK(PKIX_TrustAnchor_GetCAName
- (anchor, &trustedCAName, plContext),
- PKIX_TRUSTANCHORGETCANAMEFAILED);
- }
-
- PKIX_NULLCHECK_TWO(trustedPubKey, trustedCAName);
-
- PKIX_CHECK(PKIX_TrustAnchor_GetNameConstraints
- (anchor, &trustedNC, plContext),
- PKIX_TRUSTANCHORGETNAMECONSTRAINTSFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
- (procParams, &certSelector, plContext),
- PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetDate
- (procParams, &testDate, plContext),
- PKIX_PROCESSINGPARAMSGETDATEFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetInitialPolicies
- (procParams, &initialPolicies, plContext),
- PKIX_PROCESSINGPARAMSGETINITIALPOLICIESFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetPolicyQualifiersRejected
- (procParams, &policyQualifiersRejected, plContext),
- PKIX_PROCESSINGPARAMSGETPOLICYQUALIFIERSREJECTEDFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_IsPolicyMappingInhibited
- (procParams, &initialPolicyMappingInhibit, plContext),
- PKIX_PROCESSINGPARAMSISPOLICYMAPPINGINHIBITEDFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_IsAnyPolicyInhibited
- (procParams, &initialAnyPolicyInhibit, plContext),
- PKIX_PROCESSINGPARAMSISANYPOLICYINHIBITEDFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_IsExplicitPolicyRequired
- (procParams, &initialExplicitPolicy, plContext),
- PKIX_PROCESSINGPARAMSISEXPLICITPOLICYREQUIREDFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetCertStores
- (procParams, &certStores, plContext),
- PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
- (procParams, &userCheckersList, plContext),
- PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
-
- /* now, initialize all the checkers */
- PKIX_CHECK(pkix_TargetCertChecker_Initialize
- (certSelector, numCerts, &targetCertChecker, plContext),
- PKIX_TARGETCERTCHECKERINITIALIZEFAILED);
-
- PKIX_CHECK(pkix_ExpirationChecker_Initialize
- (testDate, &expirationChecker, plContext),
- PKIX_EXPIRATIONCHECKERINITIALIZEFAILED);
-
- PKIX_CHECK(pkix_NameChainingChecker_Initialize
- (trustedCAName, &nameChainingChecker, plContext),
- PKIX_NAMECHAININGCHECKERINITIALIZEFAILED);
-
- PKIX_CHECK(pkix_NameConstraintsChecker_Initialize
- (trustedNC, numCerts, &nameConstraintsChecker, plContext),
- PKIX_NAMECONSTRAINTSCHECKERINITIALIZEFAILED);
-
- PKIX_CHECK(pkix_BasicConstraintsChecker_Initialize
- (numCerts, &basicConstraintsChecker, plContext),
- PKIX_BASICCONSTRAINTSCHECKERINITIALIZEFAILED);
-
- PKIX_CHECK(pkix_PolicyChecker_Initialize
- (initialPolicies,
- policyQualifiersRejected,
- initialPolicyMappingInhibit,
- initialExplicitPolicy,
- initialAnyPolicyInhibit,
- numCerts,
- &policyChecker,
- plContext),
- PKIX_POLICYCHECKERINITIALIZEFAILED);
-
- PKIX_CHECK(pkix_SignatureChecker_Initialize
- (trustedPubKey, numCerts, &sigChecker, plContext),
- PKIX_SIGNATURECHECKERINITIALIZEFAILED);
-
- if (userCheckersList != NULL) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (userCheckersList, &numCertCheckers, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numCertCheckers; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (userCheckersList,
- i,
- (PKIX_PL_Object **) &userChecker,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers,
- (PKIX_PL_Object *)userChecker,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(userChecker);
- }
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)targetCertChecker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)expirationChecker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)nameChainingChecker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)nameConstraintsChecker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)basicConstraintsChecker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)policyChecker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (checkers, (PKIX_PL_Object *)sigChecker, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- *pCheckers = checkers;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(checkers);
- }
-
- PKIX_DECREF(certSelector);
- PKIX_DECREF(testDate);
- PKIX_DECREF(initialPolicies);
- PKIX_DECREF(targetCertChecker);
- PKIX_DECREF(expirationChecker);
- PKIX_DECREF(nameChainingChecker);
- PKIX_DECREF(nameConstraintsChecker);
- PKIX_DECREF(basicConstraintsChecker);
- PKIX_DECREF(policyChecker);
- PKIX_DECREF(sigChecker);
- PKIX_DECREF(trustedCAName);
- PKIX_DECREF(trustedPubKey);
- PKIX_DECREF(trustedNC);
- PKIX_DECREF(trustedCert);
- PKIX_DECREF(defaultCrlChecker);
- PKIX_DECREF(userCheckersList);
- PKIX_DECREF(certStores);
- PKIX_DECREF(userChecker);
-
- PKIX_RETURN(VALIDATE);
-}
-
-/*
- * FUNCTION: pkix_RetrieveOutputs
- * DESCRIPTION:
- *
- * This function queries the respective states of the List of checkers in
- * "checkers" to to obtain the final public key from the SignatureChecker
- * and the policy tree from the PolicyChecker, storing those values at
- * "pFinalSubjPubKey" and "pPolicyTree", respectively.
- *
- * PARAMETERS:
- * "checkers"
- * Address of List of checkers to be queried. Must be non-NULL.
- * "pFinalSubjPubKey"
- * Address where final public key will be stored. Must be non-NULL.
- * "pPolicyTree"
- * Address where policy tree will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Validate Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_RetrieveOutputs(
- PKIX_List *checkers,
- PKIX_PL_PublicKey **pFinalSubjPubKey,
- PKIX_PolicyNode **pPolicyTree,
- void *plContext)
-{
- PKIX_PL_PublicKey *finalSubjPubKey = NULL;
- PKIX_PolicyNode *validPolicyTree = NULL;
- PKIX_CertChainChecker *checker = NULL;
- PKIX_PL_Object *state = NULL;
- PKIX_UInt32 numCheckers = 0;
- PKIX_UInt32 type;
- PKIX_Int32 j;
-
- PKIX_ENTER(VALIDATE, "pkix_RetrieveOutputs");
-
- PKIX_NULLCHECK_TWO(checkers, pPolicyTree);
-
- /*
- * To optimize the search, we guess that the sigChecker is
- * last in the tree and is preceded by the policyChecker. We
- * search toward the front of the chain. Remember that List
- * items are indexed 0..(numItems - 1).
- */
-
- PKIX_CHECK(PKIX_List_GetLength(checkers, &numCheckers, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (j = numCheckers - 1; j >= 0; j--){
- PKIX_CHECK(PKIX_List_GetItem
- (checkers, j, (PKIX_PL_Object **)&checker, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
- (checker, &state, plContext),
- PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
-
- /* user defined checker may have no state */
- if (state != NULL) {
-
- PKIX_CHECK(PKIX_PL_Object_GetType(state, &type, plContext),
- PKIX_OBJECTGETTYPEFAILED);
-
- if (type == PKIX_SIGNATURECHECKERSTATE_TYPE){
- /* final pubKey will include any inherited DSA params */
- finalSubjPubKey =
- ((pkix_SignatureCheckerState *)state)->
- prevPublicKey;
- PKIX_INCREF(finalSubjPubKey);
- *pFinalSubjPubKey = finalSubjPubKey;
- }
-
- if (type == PKIX_CERTPOLICYCHECKERSTATE_TYPE) {
- validPolicyTree =
- ((PKIX_PolicyCheckerState *)state)->validPolicyTree;
- break;
- }
- }
-
- PKIX_DECREF(checker);
- PKIX_DECREF(state);
- }
-
- PKIX_INCREF(validPolicyTree);
- *pPolicyTree = validPolicyTree;
-
-cleanup:
-
- PKIX_DECREF(checker);
- PKIX_DECREF(state);
-
- PKIX_RETURN(VALIDATE);
-
-}
-
-/*
- * FUNCTION: pkix_CheckChain
- * DESCRIPTION:
- *
- * Checks whether the List of Certs pointed to by "certs", containing
- * "numCerts" entries, successfully validates using each CertChainChecker in
- * the List pointed to by "checkers" and has not been revoked, according to any
- * of the Revocation Checkers in the List pointed to by "revChecker". Checkers
- * are expected to remove from "removeCheckedExtOIDs" and extensions that they
- * process. Indices to the certChain and the checkerChain are obtained and
- * returned in "pCertCheckedIndex" and "pCheckerIndex", respectively. These
- * should be set to zero prior to the initial call, but may be changed (and
- * must be supplied on subsequent calls) if processing is suspended for non-
- * blocking I/O. Each time a Cert passes from being validated by one of the
- * CertChainCheckers to being checked by a Revocation Checker, the Boolean
- * stored at "pRevChecking" is changed from FALSE to TRUE. If the Cert is
- * rejected by a Revocation Checker, its reason code is returned at
- * "pReasonCode. If the List of Certs successfully validates, the public key i
- * the final certificate is obtained and stored at "pFinalSubjPubKey" and the
- * validPolicyTree, which could be NULL, is stored at pPolicyTree. If the List
- * of Certs fails to validate, an Error pointer is returned.
- *
- * If "pVerifyTree" is non-NULL, a chain of VerifyNodes is created which
- * tracks the results of the validation. That is, either each node in the
- * chain has a NULL Error component, or the last node contains an Error
- * which indicates why the validation failed.
- *
- * The number of Certs in the List, represented by "numCerts", is used to
- * determine which Cert is the final Cert.
- *
- * PARAMETERS:
- * "certs"
- * Address of List of Certs to validate. Must be non-NULL.
- * "numCerts"
- * Number of certificates in the List of certificates.
- * "checkers"
- * List of CertChainCheckers which must each validate the List of
- * certificates. Must be non-NULL.
- * "revChecker"
- * List of RevocationCheckers which must each not reject the List of
- * certificates. May be empty, but must be non-NULL.
- * "removeCheckedExtOIDs"
- * List of PKIX_PL_OID that has been processed. If called from building
- * chain, it is the list of critical extension OIDs that has been
- * processed prior to validation. Extension OIDs that may be processed by
- * user defined checker processes are also in the list. May be NULL.
- * "procParams"
- * Address of ProcessingParams used to initialize various checkers. Must
- * be non-NULL.
- * "pCertCheckedIndex"
- * Address where Int32 index to the Cert chain is obtained and
- * returned. Must be non-NULL.
- * "pCheckerIndex"
- * Address where Int32 index to the CheckerChain is obtained and
- * returned. Must be non-NULL.
- * "pRevChecking"
- * Address where Boolean is obtained and returned, indicating, if FALSE,
- * that CertChainCheckers are being called; or, if TRUE, that RevChecker
- * are being called. Must be non-NULL.
- * "pReasonCode"
- * Address where UInt32 results of revocation checking are stored. Must be
- * non-NULL.
- * "pNBIOContext"
- * Address where platform-dependent context is stored if checking is
- * suspended for non-blocking I/O. Must be non-NULL.
- * "pFinalSubjPubKey"
- * Address where the final public key will be stored. Must be non-NULL.
- * "pPolicyTree"
- * Address where the final validPolicyTree is stored. Must be non-NULL.
- * "pVerifyTree"
- * Address where a VerifyTree is stored, if non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Validate Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CheckChain(
- PKIX_List *certs,
- PKIX_UInt32 numCerts,
- PKIX_TrustAnchor *anchor,
- PKIX_List *checkers,
- PKIX_RevocationChecker *revChecker,
- PKIX_List *removeCheckedExtOIDs,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 *pCertCheckedIndex,
- PKIX_UInt32 *pCheckerIndex,
- PKIX_Boolean *pRevChecking,
- PKIX_UInt32 *pReasonCode,
- void **pNBIOContext,
- PKIX_PL_PublicKey **pFinalSubjPubKey,
- PKIX_PolicyNode **pPolicyTree,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext)
-{
- PKIX_UInt32 j = 0;
- PKIX_Boolean revChecking = PKIX_FALSE;
- PKIX_Error *checkCertError = NULL;
- void *nbioContext = NULL;
- PKIX_PL_Cert *cert = NULL;
- PKIX_PL_Cert *issuer = NULL;
- PKIX_PL_NssContext *nssContext = NULL;
- CERTCertList *certList = NULL;
- const CERTChainVerifyCallback *chainVerifyCallback = NULL;
- CERTCertificate *nssCert = NULL;
-
- PKIX_ENTER(VALIDATE, "pkix_CheckChain");
- PKIX_NULLCHECK_FOUR(certs, checkers, revChecker, pCertCheckedIndex);
- PKIX_NULLCHECK_FOUR(pCheckerIndex, pRevChecking, pReasonCode, anchor);
- PKIX_NULLCHECK_THREE(pNBIOContext, pFinalSubjPubKey, pPolicyTree);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
- revChecking = *pRevChecking;
- nssContext = (PKIX_PL_NssContext *)plContext;
- chainVerifyCallback = &nssContext->chainVerifyCallback;
-
- if (chainVerifyCallback->isChainValid != NULL) {
- PRBool chainOK = PR_FALSE; /*assume failure*/
- SECStatus rv;
-
- certList = CERT_NewCertList();
- if (certList == NULL) {
- PKIX_ERROR_ALLOC_ERROR();
- }
-
- /* Add the trust anchor to the list */
- PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
- (anchor, &cert, plContext),
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
-
- PKIX_CHECK(
- PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert, plContext),
- PKIX_CERTGETCERTCERTIFICATEFAILED);
-
- rv = CERT_AddCertToListHead(certList, nssCert);
- if (rv != SECSuccess) {
- PKIX_ERROR_ALLOC_ERROR();
- }
- /* the certList takes ownership of nssCert on success */
- nssCert = NULL;
- PKIX_DECREF(cert);
-
- /* Add the rest of the chain to the list */
- for (j = *pCertCheckedIndex; j < numCerts; j++) {
- PKIX_CHECK(PKIX_List_GetItem(
- certs, j, (PKIX_PL_Object **)&cert, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(
- PKIX_PL_Cert_GetCERTCertificate(cert, &nssCert, plContext),
- PKIX_CERTGETCERTCERTIFICATEFAILED);
-
- rv = CERT_AddCertToListHead(certList, nssCert);
- if (rv != SECSuccess) {
- PKIX_ERROR_ALLOC_ERROR();
- }
- /* the certList takes ownership of nssCert on success */
- nssCert = NULL;
- PKIX_DECREF(cert);
- }
-
- rv = (*chainVerifyCallback->isChainValid)
- (chainVerifyCallback->isChainValidArg, certList, &chainOK);
- if (rv != SECSuccess) {
- PKIX_ERROR_FATAL(PKIX_CHAINVERIFYCALLBACKFAILED);
- }
-
- if (!chainOK) {
- PKIX_ERROR(PKIX_CHAINVERIFYCALLBACKFAILED);
- }
-
- }
-
- PKIX_CHECK(PKIX_TrustAnchor_GetTrustedCert
- (anchor, &cert, plContext),
- PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
-
- for (j = *pCertCheckedIndex; j < numCerts; j++) {
-
- PORT_Assert(cert);
- PKIX_DECREF(issuer);
- issuer = cert;
- cert = NULL;
-
- PKIX_CHECK(PKIX_List_GetItem(
- certs, j, (PKIX_PL_Object **)&cert, plContext),
- PKIX_LISTGETITEMFAILED);
-
- /* check if cert pointer is valid */
- PORT_Assert(cert);
- if (cert == NULL) {
- continue;
- }
-
- if (revChecking == PKIX_FALSE) {
-
- PKIX_CHECK(pkix_CheckCert
- (cert,
- checkers,
- removeCheckedExtOIDs,
- pCheckerIndex,
- &nbioContext,
- plContext),
- PKIX_CHECKCERTFAILED);
-
- if (nbioContext != NULL) {
- *pCertCheckedIndex = j;
- *pRevChecking = revChecking;
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
-
- revChecking = PKIX_TRUE;
- *pCheckerIndex = 0;
- }
-
- if (revChecking == PKIX_TRUE) {
- PKIX_RevocationStatus revStatus;
- pkixErrorResult =
- PKIX_RevocationChecker_Check(
- cert, issuer, revChecker,
- procParams, PKIX_TRUE,
- (j == numCerts - 1) ? PKIX_TRUE : PKIX_FALSE,
- &revStatus, pReasonCode,
- &nbioContext, plContext);
- if (nbioContext != NULL) {
- *pCertCheckedIndex = j;
- *pRevChecking = revChecking;
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
- if (revStatus == PKIX_RevStatus_Revoked ||
- pkixErrorResult) {
- if (!pkixErrorResult) {
- /* if pkixErrorResult is returned then
- * use it as it has a detailed revocation
- * error code. Otherwise create a new error */
- PKIX_ERROR_CREATE(VALIDATE,
- PKIX_CERTIFICATEREVOKED,
- pkixErrorResult);
- }
- goto cleanup;
- }
- revChecking = PKIX_FALSE;
- *pCheckerIndex = 0;
- }
-
- PKIX_CHECK(pkix_AddToVerifyLog
- (cert, j, NULL, pVerifyTree, plContext),
- PKIX_ADDTOVERIFYLOGFAILED);
- }
-
- PKIX_CHECK(pkix_RetrieveOutputs
- (checkers, pFinalSubjPubKey, pPolicyTree, plContext),
- PKIX_RETRIEVEOUTPUTSFAILED);
-
- *pNBIOContext = NULL;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED && cert) {
- checkCertError = pkixErrorResult;
-
- PKIX_CHECK_FATAL(
- pkix_AddToVerifyLog(cert, j, checkCertError, pVerifyTree,
- plContext),
- PKIX_ADDTOVERIFYLOGFAILED);
- pkixErrorResult = checkCertError;
- pkixErrorCode = pkixErrorResult->errCode;
- checkCertError = NULL;
- }
-
-fatal:
- if (nssCert) {
- CERT_DestroyCertificate(nssCert);
- }
-
- if (certList) {
- CERT_DestroyCertList(certList);
- }
-
- PKIX_DECREF(checkCertError);
- PKIX_DECREF(cert);
- PKIX_DECREF(issuer);
-
- PKIX_RETURN(VALIDATE);
-}
-
-/*
- * FUNCTION: pkix_ExtractParameters
- * DESCRIPTION:
- *
- * Extracts several parameters from the ValidateParams object pointed to by
- * "valParams" and stores the CertChain at "pChain", the List of Certs at
- * "pCerts", the number of Certs in the chain at "pNumCerts", the
- * ProcessingParams object at "pProcParams", the List of TrustAnchors at
- * "pAnchors", and the number of TrustAnchors at "pNumAnchors".
- *
- * PARAMETERS:
- * "valParams"
- * Address of ValidateParams from which the parameters are extracted.
- * Must be non-NULL.
- * "pCerts"
- * Address where object pointer for List of Certs will be stored.
- * Must be non-NULL.
- * "pNumCerts"
- * Address where number of Certs will be stored. Must be non-NULL.
- * "pProcParams"
- * Address where object pointer for ProcessingParams will be stored.
- * Must be non-NULL.
- * "pAnchors"
- * Address where object pointer for List of Anchors will be stored.
- * Must be non-NULL.
- * "pNumAnchors"
- * Address where number of Anchors will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Validate Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_ExtractParameters(
- PKIX_ValidateParams *valParams,
- PKIX_List **pCerts,
- PKIX_UInt32 *pNumCerts,
- PKIX_ProcessingParams **pProcParams,
- PKIX_List **pAnchors,
- PKIX_UInt32 *pNumAnchors,
- void *plContext)
-{
- PKIX_ENTER(VALIDATE, "pkix_ExtractParameters");
- PKIX_NULLCHECK_THREE(valParams, pCerts, pNumCerts);
- PKIX_NULLCHECK_THREE(pProcParams, pAnchors, pNumAnchors);
-
- /* extract relevant parameters from chain */
- PKIX_CHECK(PKIX_ValidateParams_GetCertChain
- (valParams, pCerts, plContext),
- PKIX_VALIDATEPARAMSGETCERTCHAINFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(*pCerts, pNumCerts, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- /* extract relevant parameters from procParams */
- PKIX_CHECK(PKIX_ValidateParams_GetProcessingParams
- (valParams, pProcParams, plContext),
- PKIX_VALIDATEPARAMSGETPROCESSINGPARAMSFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetTrustAnchors
- (*pProcParams, pAnchors, plContext),
- PKIX_PROCESSINGPARAMSGETTRUSTANCHORSFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(*pAnchors, pNumAnchors, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
-cleanup:
-
- PKIX_RETURN(VALIDATE);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_ValidateChain (see comments in pkix.h)
- */
-PKIX_Error *
-PKIX_ValidateChain(
- PKIX_ValidateParams *valParams,
- PKIX_ValidateResult **pResult,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext)
-{
- PKIX_Error *chainFailed = NULL;
-
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_CertChainChecker *userChecker = NULL;
- PKIX_RevocationChecker *revChecker = NULL;
- PKIX_List *certs = NULL;
- PKIX_List *checkers = NULL;
- PKIX_List *anchors = NULL;
- PKIX_List *userCheckers = NULL;
- PKIX_List *userCheckerExtOIDs = NULL;
- PKIX_List *validateCheckedCritExtOIDsList = NULL;
- PKIX_TrustAnchor *anchor = NULL;
- PKIX_ValidateResult *valResult = NULL;
- PKIX_PL_PublicKey *finalPubKey = NULL;
- PKIX_PolicyNode *validPolicyTree = NULL;
- PKIX_Boolean supportForwarding = PKIX_FALSE;
- PKIX_Boolean revChecking = PKIX_FALSE;
- PKIX_UInt32 i, numCerts, numAnchors;
- PKIX_UInt32 numUserCheckers = 0;
- PKIX_UInt32 certCheckedIndex = 0;
- PKIX_UInt32 checkerIndex = 0;
- PKIX_UInt32 reasonCode = 0;
- void *nbioContext = NULL;
-
- PKIX_ENTER(VALIDATE, "PKIX_ValidateChain");
- PKIX_NULLCHECK_TWO(valParams, pResult);
-
- /* extract various parameters from valParams */
- PKIX_CHECK(pkix_ExtractParameters
- (valParams,
- &certs,
- &numCerts,
- &procParams,
- &anchors,
- &numAnchors,
- plContext),
- PKIX_EXTRACTPARAMETERSFAILED);
-
- /*
- * setup an extension OID list that user had defined for his checker
- * processing. User checker is not responsible for taking out OIDs
- * from unresolved critical extension list as the libpkix checker
- * is doing. Here we add those user checkers' OIDs to the removal
- * list to be taken out by CheckChain
- */
- PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
- (procParams, &userCheckers, plContext),
- PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
-
- if (userCheckers != NULL) {
-
- PKIX_CHECK(PKIX_List_Create
- (&validateCheckedCritExtOIDsList,
- plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength
- (userCheckers, &numUserCheckers, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numUserCheckers; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (userCheckers,
- i,
- (PKIX_PL_Object **) &userChecker,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK
- (PKIX_CertChainChecker_IsForwardCheckingSupported
- (userChecker, &supportForwarding, plContext),
- PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED);
-
- if (supportForwarding == PKIX_FALSE) {
-
- PKIX_CHECK
- (PKIX_CertChainChecker_GetSupportedExtensions
- (userChecker, &userCheckerExtOIDs, plContext),
- PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED);
-
- if (userCheckerExtOIDs != NULL) {
- PKIX_CHECK(pkix_List_AppendList
- (validateCheckedCritExtOIDsList,
- userCheckerExtOIDs,
- plContext),
- PKIX_LISTAPPENDLISTFAILED);
- }
- }
-
- PKIX_DECREF(userCheckerExtOIDs);
- PKIX_DECREF(userChecker);
- }
- }
-
- PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker
- (procParams, &revChecker, plContext),
- PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED);
-
- /* try to validate the chain with each anchor */
- for (i = 0; i < numAnchors; i++){
-
- /* get trust anchor */
- PKIX_CHECK(PKIX_List_GetItem
- (anchors, i, (PKIX_PL_Object **)&anchor, plContext),
- PKIX_LISTGETITEMFAILED);
-
- /* initialize checkers using information from trust anchor */
- PKIX_CHECK(pkix_InitializeCheckers
- (anchor, procParams, numCerts, &checkers, plContext),
- PKIX_INITIALIZECHECKERSFAILED);
-
- /*
- * Validate the chain using this trust anchor and these
- * checkers. (WARNING: checkers that use non-blocking I/O
- * are not currently supported.)
- */
- certCheckedIndex = 0;
- checkerIndex = 0;
- revChecking = PKIX_FALSE;
- chainFailed = pkix_CheckChain
- (certs,
- numCerts,
- anchor,
- checkers,
- revChecker,
- validateCheckedCritExtOIDsList,
- procParams,
- &certCheckedIndex,
- &checkerIndex,
- &revChecking,
- &reasonCode,
- &nbioContext,
- &finalPubKey,
- &validPolicyTree,
- pVerifyTree,
- plContext);
-
- if (chainFailed || (reasonCode != 0)) {
-
- /* cert chain failed to validate */
-
- PKIX_DECREF(chainFailed);
- PKIX_DECREF(anchor);
- PKIX_DECREF(checkers);
- PKIX_DECREF(validPolicyTree);
-
- /* if last anchor, we fail; else, we try next anchor */
- if (i == (numAnchors - 1)) { /* last anchor */
- PKIX_ERROR(PKIX_VALIDATECHAINFAILED);
- }
-
- } else {
-
- /* cert chain successfully validated! */
- PKIX_CHECK(pkix_ValidateResult_Create
- (finalPubKey,
- anchor,
- validPolicyTree,
- &valResult,
- plContext),
- PKIX_VALIDATERESULTCREATEFAILED);
-
- *pResult = valResult;
-
- /* no need to try any more anchors in the loop */
- goto cleanup;
- }
- }
-
-cleanup:
-
- PKIX_DECREF(finalPubKey);
- PKIX_DECREF(certs);
- PKIX_DECREF(anchors);
- PKIX_DECREF(anchor);
- PKIX_DECREF(checkers);
- PKIX_DECREF(revChecker);
- PKIX_DECREF(validPolicyTree);
- PKIX_DECREF(chainFailed);
- PKIX_DECREF(procParams);
- PKIX_DECREF(userCheckers);
- PKIX_DECREF(validateCheckedCritExtOIDsList);
-
- PKIX_RETURN(VALIDATE);
-}
-
-/*
- * FUNCTION: pkix_Validate_BuildUserOIDs
- * DESCRIPTION:
- *
- * This function creates a List of the OIDs that are processed by the user
- * checkers in the List pointed to by "userCheckers", storing the resulting
- * List at "pUserCritOIDs". If the List of userCheckers is NULL, the output
- * List will be NULL. Otherwise the output List will be non-NULL, but may be
- * empty.
- *
- * PARAMETERS:
- * "userCheckers"
- * The address of the List of userCheckers.
- * "pUserCritOIDs"
- * The address at which the List is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a VALIDATE Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_Validate_BuildUserOIDs(
- PKIX_List *userCheckers,
- PKIX_List **pUserCritOIDs,
- void *plContext)
-{
- PKIX_UInt32 numUserCheckers = 0;
- PKIX_UInt32 i = 0;
- PKIX_List *userCritOIDs = NULL;
- PKIX_List *userCheckerExtOIDs = NULL;
- PKIX_Boolean supportForwarding = PKIX_FALSE;
- PKIX_CertChainChecker *userChecker = NULL;
-
- PKIX_ENTER(VALIDATE, "pkix_Validate_BuildUserOIDs");
- PKIX_NULLCHECK_ONE(pUserCritOIDs);
-
- if (userCheckers != NULL) {
- PKIX_CHECK(PKIX_List_Create(&userCritOIDs, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength
- (userCheckers, &numUserCheckers, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numUserCheckers; i++) {
- PKIX_CHECK(PKIX_List_GetItem
- (userCheckers,
- i,
- (PKIX_PL_Object **) &userChecker,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_CertChainChecker_IsForwardCheckingSupported
- (userChecker, &supportForwarding, plContext),
- PKIX_CERTCHAINCHECKERISFORWARDCHECKINGSUPPORTEDFAILED);
-
- if (supportForwarding == PKIX_FALSE) {
-
- PKIX_CHECK(PKIX_CertChainChecker_GetSupportedExtensions
- (userChecker, &userCheckerExtOIDs, plContext),
- PKIX_CERTCHAINCHECKERGETSUPPORTEDEXTENSIONSFAILED);
-
- if (userCheckerExtOIDs != NULL) {
- PKIX_CHECK(pkix_List_AppendList
- (userCritOIDs, userCheckerExtOIDs, plContext),
- PKIX_LISTAPPENDLISTFAILED);
- }
- }
-
- PKIX_DECREF(userCheckerExtOIDs);
- PKIX_DECREF(userChecker);
- }
- }
-
- *pUserCritOIDs = userCritOIDs;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(userCritOIDs);
- }
-
- PKIX_DECREF(userCheckerExtOIDs);
- PKIX_DECREF(userChecker);
-
- PKIX_RETURN(VALIDATE);
-}
-
-/*
- * FUNCTION: PKIX_ValidateChain_nb (see comments in pkix.h)
- */
-PKIX_Error *
-PKIX_ValidateChain_NB(
- PKIX_ValidateParams *valParams,
- PKIX_UInt32 *pCertIndex,
- PKIX_UInt32 *pAnchorIndex,
- PKIX_UInt32 *pCheckerIndex,
- PKIX_Boolean *pRevChecking,
- PKIX_List **pCheckers,
- void **pNBIOContext,
- PKIX_ValidateResult **pResult,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext)
-{
- PKIX_UInt32 numCerts = 0;
- PKIX_UInt32 numAnchors = 0;
- PKIX_UInt32 i = 0;
- PKIX_UInt32 certIndex = 0;
- PKIX_UInt32 anchorIndex = 0;
- PKIX_UInt32 checkerIndex = 0;
- PKIX_UInt32 reasonCode = 0;
- PKIX_Boolean revChecking = PKIX_FALSE;
- PKIX_List *certs = NULL;
- PKIX_List *anchors = NULL;
- PKIX_List *checkers = NULL;
- PKIX_List *userCheckers = NULL;
- PKIX_List *validateCheckedCritExtOIDsList = NULL;
- PKIX_TrustAnchor *anchor = NULL;
- PKIX_ValidateResult *valResult = NULL;
- PKIX_PL_PublicKey *finalPubKey = NULL;
- PKIX_PolicyNode *validPolicyTree = NULL;
- PKIX_ProcessingParams *procParams = NULL;
- PKIX_RevocationChecker *revChecker = NULL;
- PKIX_Error *chainFailed = NULL;
- void *nbioContext = NULL;
-
- PKIX_ENTER(VALIDATE, "PKIX_ValidateChain_NB");
- PKIX_NULLCHECK_FOUR
- (valParams, pCertIndex, pAnchorIndex, pCheckerIndex);
- PKIX_NULLCHECK_FOUR(pRevChecking, pCheckers, pNBIOContext, pResult);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- /* extract various parameters from valParams */
- PKIX_CHECK(pkix_ExtractParameters
- (valParams,
- &certs,
- &numCerts,
- &procParams,
- &anchors,
- &numAnchors,
- plContext),
- PKIX_EXTRACTPARAMETERSFAILED);
-
- /*
- * Create a List of the OIDs that will be processed by the user
- * checkers. User checkers are not responsible for removing OIDs from
- * the List of unresolved critical extensions, as libpkix checkers are.
- * So we add those user checkers' OIDs to the removal list to be taken
- * out by CheckChain.
- */
- PKIX_CHECK(PKIX_ProcessingParams_GetCertChainCheckers
- (procParams, &userCheckers, plContext),
- PKIX_PROCESSINGPARAMSGETCERTCHAINCHECKERSFAILED);
-
- PKIX_CHECK(pkix_Validate_BuildUserOIDs
- (userCheckers, &validateCheckedCritExtOIDsList, plContext),
- PKIX_VALIDATEBUILDUSEROIDSFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_GetRevocationChecker
- (procParams, &revChecker, plContext),
- PKIX_PROCESSINGPARAMSGETREVOCATIONCHECKERFAILED);
-
- /* Are we resuming after a WOULDBLOCK return, or starting anew ? */
- if (nbioContext != NULL) {
- /* Resuming */
- certIndex = *pCertIndex;
- anchorIndex = *pAnchorIndex;
- checkerIndex = *pCheckerIndex;
- revChecking = *pRevChecking;
- checkers = *pCheckers;
- *pCheckers = NULL;
- }
-
- /* try to validate the chain with each anchor */
- for (i = anchorIndex; i < numAnchors; i++) {
-
- /* get trust anchor */
- PKIX_CHECK(PKIX_List_GetItem
- (anchors, i, (PKIX_PL_Object **)&anchor, plContext),
- PKIX_LISTGETITEMFAILED);
-
- /* initialize checkers using information from trust anchor */
- if (nbioContext == NULL) {
- PKIX_CHECK(pkix_InitializeCheckers
- (anchor,
- procParams,
- numCerts,
- &checkers,
- plContext),
- PKIX_INITIALIZECHECKERSFAILED);
- }
-
- /*
- * Validate the chain using this trust anchor and these
- * checkers.
- */
- chainFailed = pkix_CheckChain
- (certs,
- numCerts,
- anchor,
- checkers,
- revChecker,
- validateCheckedCritExtOIDsList,
- procParams,
- &certIndex,
- &checkerIndex,
- &revChecking,
- &reasonCode,
- &nbioContext,
- &finalPubKey,
- &validPolicyTree,
- pVerifyTree,
- plContext);
-
- if (nbioContext != NULL) {
- *pCertIndex = certIndex;
- *pAnchorIndex = anchorIndex;
- *pCheckerIndex = checkerIndex;
- *pRevChecking = revChecking;
- PKIX_INCREF(checkers);
- *pCheckers = checkers;
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
-
- if (chainFailed || (reasonCode != 0)) {
-
- /* cert chain failed to validate */
-
- PKIX_DECREF(chainFailed);
- PKIX_DECREF(anchor);
- PKIX_DECREF(checkers);
- PKIX_DECREF(validPolicyTree);
-
- /* if last anchor, we fail; else, we try next anchor */
- if (i == (numAnchors - 1)) { /* last anchor */
- PKIX_ERROR(PKIX_VALIDATECHAINFAILED);
- }
-
- } else {
-
- /* cert chain successfully validated! */
- PKIX_CHECK(pkix_ValidateResult_Create
- (finalPubKey,
- anchor,
- validPolicyTree,
- &valResult,
- plContext),
- PKIX_VALIDATERESULTCREATEFAILED);
-
- *pResult = valResult;
-
- /* no need to try any more anchors in the loop */
- goto cleanup;
- }
- }
-
-cleanup:
-
- PKIX_DECREF(finalPubKey);
- PKIX_DECREF(certs);
- PKIX_DECREF(anchors);
- PKIX_DECREF(anchor);
- PKIX_DECREF(checkers);
- PKIX_DECREF(revChecker);
- PKIX_DECREF(validPolicyTree);
- PKIX_DECREF(chainFailed);
- PKIX_DECREF(procParams);
- PKIX_DECREF(userCheckers);
- PKIX_DECREF(validateCheckedCritExtOIDsList);
-
- PKIX_RETURN(VALIDATE);
-}
diff --git a/security/nss/lib/libpkix/pkix/top/pkix_validate.h b/security/nss/lib/libpkix/pkix/top/pkix_validate.h
deleted file mode 100755
index 7692e3bab..000000000
--- a/security/nss/lib/libpkix/pkix/top/pkix_validate.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_validate.h
- *
- * Header file for validateChain function
- *
- */
-
-#ifndef _PKIX_VALIDATE_H
-#define _PKIX_VALIDATE_H
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-PKIX_Error *
-pkix_CheckChain(
- PKIX_List *certs,
- PKIX_UInt32 numCerts,
- PKIX_TrustAnchor *anchor,
- PKIX_List *checkers,
- PKIX_RevocationChecker *revChecker,
- PKIX_List *buildCheckedExtOIDs,
- PKIX_ProcessingParams *procParams,
- PKIX_UInt32 *pCertCheckedIndex,
- PKIX_UInt32 *pCheckerIndex,
- PKIX_Boolean *pRevChecking,
- PKIX_UInt32 *pReasonCode,
- void **pNBIOContext,
- PKIX_PL_PublicKey **pFinalSubjPubKey,
- PKIX_PolicyNode **pPolicyTree,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_VALIDATE_H */
diff --git a/security/nss/lib/libpkix/pkix/util/Makefile b/security/nss/lib/libpkix/pkix/util/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix/util/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix/util/config.mk b/security/nss/lib/libpkix/pkix/util/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix/util/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix/util/manifest.mn b/security/nss/lib/libpkix/pkix/util/manifest.mn
deleted file mode 100755
index 5609ca26c..000000000
--- a/security/nss/lib/libpkix/pkix/util/manifest.mn
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_tools.h \
- pkix_error.h \
- pkix_logger.h \
- pkix_list.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_tools.c \
- pkix_error.c \
- pkix_logger.c \
- pkix_list.c \
- pkix_errpaths.c \
- $(NULL)
-
-LIBRARY_NAME = pkixutil
-
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_error.c b/security/nss/lib/libpkix/pkix/util/pkix_error.c
deleted file mode 100755
index e6fba866a..000000000
--- a/security/nss/lib/libpkix/pkix/util/pkix_error.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_error.c
- *
- * Error Object Functions
- *
- */
-
-#include "pkix_error.h"
-
-#undef PKIX_ERRORENTRY
-
-#define PKIX_ERRORENTRY(name,desc,nsserr) #desc
-
-#if defined PKIX_ERROR_DESCRIPTION
-
-const char * const PKIX_ErrorText[] =
-{
-#include "pkix_errorstrings.h"
-};
-
-#else
-
-#include "prprf.h"
-
-#endif /* PKIX_ERROR_DESCRIPTION */
-
-extern const PKIX_Int32 PKIX_PLErrorIndex[];
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_Error_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_Error_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_Error *firstError = NULL;
- PKIX_Error *secondError = NULL;
- PKIX_Error *firstCause = NULL;
- PKIX_Error *secondCause = NULL;
- PKIX_PL_Object *firstInfo = NULL;
- PKIX_PL_Object *secondInfo = NULL;
- PKIX_ERRORCLASS firstClass, secondClass;
- PKIX_UInt32 secondType;
- PKIX_Boolean boolResult, unequalFlag;
-
- PKIX_ENTER(ERROR, "pkix_Error_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- unequalFlag = PKIX_FALSE;
-
- /* First just compare pointer values to save time */
- if (firstObject == secondObject) {
- *pResult = PKIX_TRUE;
- goto cleanup;
- } else {
- /* Result will only be set to true if all tests pass */
- *pResult = PKIX_FALSE;
- }
-
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_ERROR_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTANERROROBJECT);
-
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_ERRORGETTINGSECONDOBJECTTYPE);
-
- /* If types differ, then return false. Result is already set */
- if (secondType != PKIX_ERROR_TYPE) goto cleanup;
-
- /* It is safe to cast to PKIX_Error */
- firstError = (PKIX_Error *) firstObject;
- secondError = (PKIX_Error *) secondObject;
-
- /* Compare error codes */
- firstClass = firstError->errClass;
- secondClass = secondError->errClass;
-
- /* If codes differ, return false. Result is already set */
- if (firstClass != secondClass) goto cleanup;
-
- /* Compare causes */
- firstCause = firstError->cause;
- secondCause = secondError->cause;
-
- /* Ensure that either both or none of the causes are NULL */
- if (((firstCause != NULL) && (secondCause == NULL))||
- ((firstCause == NULL) && (secondCause != NULL)))
- unequalFlag = PKIX_TRUE;
-
- if ((firstCause != NULL) && (secondCause != NULL)) {
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object*)firstCause,
- (PKIX_PL_Object*)secondCause,
- &boolResult,
- plContext),
- PKIX_ERRORINRECURSIVEEQUALSCALL);
-
- /* Set the unequalFlag so that we return after dec refing */
- if (boolResult == 0) unequalFlag = PKIX_TRUE;
- }
-
- /* If the cause errors are not equal, return null */
- if (unequalFlag) goto cleanup;
-
- /* Compare info fields */
- firstInfo = firstError->info;
- secondInfo = secondError->info;
-
- if (firstInfo != secondInfo) goto cleanup;
-
- /* Ensure that either both or none of the infos are NULL */
- if (((firstInfo != NULL) && (secondInfo == NULL))||
- ((firstInfo == NULL) && (secondInfo != NULL)))
- unequalFlag = PKIX_TRUE;
-
- if ((firstInfo != NULL) && (secondInfo != NULL)) {
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object*)firstInfo,
- (PKIX_PL_Object*)secondInfo,
- &boolResult,
- plContext),
- PKIX_ERRORINRECURSIVEEQUALSCALL);
-
- /* Set the unequalFlag so that we return after dec refing */
- if (boolResult == 0) unequalFlag = PKIX_TRUE;
- }
-
- /* If the infos are not equal, return null */
- if (unequalFlag) goto cleanup;
-
-
- /* Compare descs */
- if (firstError->errCode != secondError->errCode) {
- unequalFlag = PKIX_TRUE;
- }
-
- if (firstError->plErr != secondError->plErr) {
- unequalFlag = PKIX_TRUE;
- }
-
- /* If the unequalFlag was set, return false */
- if (unequalFlag) goto cleanup;
-
- /* Errors are equal in all fields at this point */
- *pResult = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(ERROR);
-}
-
-/*
- * FUNCTION: pkix_Error_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_Error_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_Error *error = NULL;
-
- PKIX_ENTER(ERROR, "pkix_Error_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_ERROR_TYPE, plContext),
- PKIX_OBJECTNOTANERROR);
-
- error = (PKIX_Error *)object;
-
- PKIX_DECREF(error->cause);
-
- PKIX_DECREF(error->info);
-
-cleanup:
-
- PKIX_RETURN(ERROR);
-}
-
-
-/* XXX This is not thread safe */
-static PKIX_UInt32 pkix_error_cause_depth = 1;
-
-/*
- * FUNCTION: pkix_Error_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_Error_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_Error *error = NULL;
- PKIX_Error *cause = NULL;
- PKIX_PL_String *desc = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *causeString = NULL;
- PKIX_PL_String *optCauseString = NULL;
- PKIX_PL_String *errorNameString = NULL;
- char *format = NULL;
- PKIX_ERRORCLASS errClass;
-
- PKIX_ENTER(ERROR, "pkix_Error_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_ERROR_TYPE, plContext),
- PKIX_OBJECTNOTANERROR);
-
- error = (PKIX_Error *)object;
-
- /* Get this error's errClass, description and the string of its cause */
- errClass = error->errClass;
-
- /* Get the description string */
- PKIX_Error_GetDescription(error, &desc, plContext);
-
- /* Get the cause */
- cause = error->cause;
-
- /* Get the causes's description string */
- if (cause != NULL) {
- pkix_error_cause_depth++;
-
- /* Get the cause string */
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)cause, &causeString, plContext),
- PKIX_ERRORGETTINGCAUSESTRING);
-
- format = "\n*** Cause (%d): %s";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- format,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- /* Create the optional Cause String */
- PKIX_CHECK(PKIX_PL_Sprintf
- (&optCauseString,
- plContext,
- formatString,
- pkix_error_cause_depth,
- causeString),
- PKIX_SPRINTFFAILED);
-
- PKIX_DECREF(formatString);
-
- pkix_error_cause_depth--;
- }
-
- /* Create the Format String */
- if (optCauseString != NULL) {
- format = "*** %s Error- %s%s";
- } else {
- format = "*** %s Error- %s";
- }
-
- /* Ensure that error errClass is known, otherwise default to Object */
- if (errClass >= PKIX_NUMERRORCLASSES) {
- errClass = 0;
- }
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- (void *)PKIX_ERRORCLASSNAMES[errClass],
- 0,
- &errorNameString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- format,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- /* Create the output String */
- PKIX_CHECK(PKIX_PL_Sprintf
- (pString,
- plContext,
- formatString,
- errorNameString,
- desc,
- optCauseString),
- PKIX_SPRINTFFAILED);
-
-cleanup:
-
- PKIX_DECREF(desc);
- PKIX_DECREF(causeString);
- PKIX_DECREF(formatString);
- PKIX_DECREF(optCauseString);
- PKIX_DECREF(errorNameString);
-
- PKIX_RETURN(ERROR);
-}
-
-/*
- * FUNCTION: pkix_Error_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_Error_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pResult,
- void *plContext)
-{
- PKIX_ENTER(ERROR, "pkix_Error_Hashcode");
- PKIX_NULLCHECK_TWO(object, pResult);
-
- /* XXX Unimplemented */
- /* XXX Need to make hashcodes equal when two errors are equal */
- *pResult = (PKIX_UInt32)object;
-
- PKIX_RETURN(ERROR);
-}
-
-/* --Initializers------------------------------------------------- */
-
-/*
- * PKIX_ERRORCLASSNAMES is an array of strings, with each string holding a
- * descriptive name for an error errClass. This is used by the default
- * PKIX_PL_Error_ToString function.
- *
- * Note: PKIX_ERRORCLASSES is defined in pkixt.h as a list of error types.
- * (More precisely, as a list of invocations of ERRMACRO(type).) The
- * macro is expanded in pkixt.h to define error numbers, and here to
- * provide corresponding strings. For example, since the fifth ERRMACRO
- * entry is MUTEX, then PKIX_MUTEX_ERROR is defined in pkixt.h as 4, and
- * PKIX_ERRORCLASSNAMES[4] is initialized here with the value "MUTEX".
- */
-#undef ERRMACRO
-#define ERRMACRO(type) #type
-
-const char *
-PKIX_ERRORCLASSNAMES[PKIX_NUMERRORCLASSES] =
-{
- PKIX_ERRORCLASSES
-};
-
-/*
- * FUNCTION: pkix_Error_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_ERROR_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_Error_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(ERROR, "pkix_Error_RegisterSelf");
-
- entry.description = "Error";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_Error);
- entry.destructor = pkix_Error_Destroy;
- entry.equalsFunction = pkix_Error_Equals;
- entry.hashcodeFunction = pkix_Error_Hashcode;
- entry.toStringFunction = pkix_Error_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_ERROR_TYPE] = entry;
-
- PKIX_RETURN(ERROR);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_Error_Create (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Error_Create(
- PKIX_ERRORCLASS errClass,
- PKIX_Error *cause,
- PKIX_PL_Object *info,
- PKIX_ERRORCODE errCode,
- PKIX_Error **pError,
- void *plContext)
-{
- PKIX_Error *tempCause = NULL;
- PKIX_Error *error = NULL;
-
- PKIX_ENTER(ERROR, "PKIX_Error_Create");
-
- PKIX_NULLCHECK_ONE(pError);
-
- /*
- * when called here, if PKIX_PL_Object_Alloc returns an error,
- * it must be a PKIX_ALLOC_ERROR
- */
- pkixErrorResult = PKIX_PL_Object_Alloc
- (PKIX_ERROR_TYPE,
- ((PKIX_UInt32)(sizeof (PKIX_Error))),
- (PKIX_PL_Object **)&error,
- plContext);
-
- if (pkixErrorResult) return (pkixErrorResult);
-
- error->errClass = errClass;
-
- /* Ensure we don't have a loop. Follow causes until NULL */
- for (tempCause = cause;
- tempCause != NULL;
- tempCause = tempCause->cause) {
- /* If we detect a loop, throw a new error */
- if (tempCause == error) {
- PKIX_ERROR(PKIX_LOOPOFERRORCAUSEDETECTED);
- }
- }
-
- PKIX_INCREF(cause);
- error->cause = cause;
-
- PKIX_INCREF(info);
- error->info = info;
-
- error->errCode = errCode;
-
- error->plErr = PKIX_PLErrorIndex[error->errCode];
-
- *pError = error;
- error = NULL;
-
-cleanup:
- /* PKIX-XXX Fix for leak during error creation */
- PKIX_DECREF(error);
-
- PKIX_RETURN(ERROR);
-}
-
-/*
- * FUNCTION: PKIX_Error_GetErrorClass (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Error_GetErrorClass(
- PKIX_Error *error,
- PKIX_ERRORCLASS *pClass,
- void *plContext)
-{
- PKIX_ENTER(ERROR, "PKIX_Error_GetErrorClass");
- PKIX_NULLCHECK_TWO(error, pClass);
-
- *pClass = error->errClass;
-
- PKIX_RETURN(ERROR);
-}
-
-/*
- * FUNCTION: PKIX_Error_GetErrorCode (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Error_GetErrorCode(
- PKIX_Error *error,
- PKIX_ERRORCODE *pCode,
- void *plContext)
-{
- PKIX_ENTER(ERROR, "PKIX_Error_GetErrorCode");
- PKIX_NULLCHECK_TWO(error, pCode);
-
- *pCode = error->errCode;
-
- PKIX_RETURN(ERROR);
-}
-
-/*
- * FUNCTION: PKIX_Error_GetCause (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Error_GetCause(
- PKIX_Error *error,
- PKIX_Error **pCause,
- void *plContext)
-{
- PKIX_ENTER(ERROR, "PKIX_Error_GetCause");
- PKIX_NULLCHECK_TWO(error, pCause);
-
- if (error->cause != PKIX_ALLOC_ERROR()){
- PKIX_INCREF(error->cause);
- }
-
- *pCause = error->cause;
-
-cleanup:
- PKIX_RETURN(ERROR);
-}
-
-/*
- * FUNCTION: PKIX_Error_GetSupplementaryInfo (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Error_GetSupplementaryInfo(
- PKIX_Error *error,
- PKIX_PL_Object **pInfo,
- void *plContext)
-{
- PKIX_ENTER(ERROR, "PKIX_Error_GetSupplementaryInfo");
- PKIX_NULLCHECK_TWO(error, pInfo);
-
- PKIX_INCREF(error->info);
-
- *pInfo = error->info;
-
-cleanup:
- PKIX_RETURN(ERROR);
-}
-
-/*
- * FUNCTION: PKIX_Error_GetDescription (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Error_GetDescription(
- PKIX_Error *error,
- PKIX_PL_String **pDesc,
- void *plContext)
-{
- PKIX_PL_String *descString = NULL;
-#ifndef PKIX_ERROR_DESCRIPTION
- char errorStr[32];
-#endif
-
- PKIX_ENTER(ERROR, "PKIX_Error_GetDescription");
- PKIX_NULLCHECK_TWO(error, pDesc);
-
-#ifndef PKIX_ERROR_DESCRIPTION
- PR_snprintf(errorStr, 32, "Error code: %d", error->errCode);
-#endif
-
- PKIX_PL_String_Create(PKIX_ESCASCII,
-#if defined PKIX_ERROR_DESCRIPTION
- (void *)PKIX_ErrorText[error->errCode],
-#else
- errorStr,
-#endif
- 0,
- &descString,
- plContext);
-
- *pDesc = descString;
-
- PKIX_RETURN(ERROR);
-}
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_error.h b/security/nss/lib/libpkix/pkix/util/pkix_error.h
deleted file mode 100755
index ca4171ab1..000000000
--- a/security/nss/lib/libpkix/pkix/util/pkix_error.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_error.h
- *
- * Error Object Type Definition
- *
- */
-
-#ifndef _PKIX_ERROR_H
-#define _PKIX_ERROR_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_ErrorStruct {
- PKIX_ERRORCODE errCode;
- PKIX_ERRORCLASS errClass; /* was formerly "code" */
- PKIX_Int32 plErr;
- PKIX_Error *cause;
- PKIX_PL_Object *info;
-};
-
-/* see source file for function documentation */
-
-extern PKIX_Error * pkix_Error_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_ERROR_H */
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_errpaths.c b/security/nss/lib/libpkix/pkix/util/pkix_errpaths.c
deleted file mode 100644
index a33ccf7dd..000000000
--- a/security/nss/lib/libpkix/pkix/util/pkix_errpaths.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_errpaths.c
- *
- * Error Handling Helper Functions
- *
- */
-
-#define PKIX_STDVARS_POINTER
-#include "pkix_error.h"
-
-const PKIX_StdVars zeroStdVars;
-
-PKIX_Error*
-PKIX_DoThrow(PKIX_StdVars * stdVars, PKIX_ERRORCLASS errClass,
- PKIX_ERRORCODE errCode, PKIX_ERRORCLASS overrideClass,
- void *plContext)
-{
- if (!pkixErrorReceived && !pkixErrorResult && pkixErrorList) {
- pkixTempResult = PKIX_List_GetItem(pkixErrorList, 0,
- (PKIX_PL_Object**)&pkixReturnResult,
- plContext);
- } else {
- pkixTempResult = (PKIX_Error*)pkix_Throw(errClass, myFuncName, errCode,
- overrideClass, pkixErrorResult,
- &pkixReturnResult, plContext);
- }
- if (pkixReturnResult) {
- if (pkixErrorResult != PKIX_ALLOC_ERROR()) {
- PKIX_DECREF(pkixErrorResult);
- }
- pkixTempResult = pkixReturnResult;
- } else if (pkixErrorResult) {
- if (pkixTempResult != PKIX_ALLOC_ERROR()) {
- PKIX_DECREF(pkixTempResult);
- }
- pkixTempResult = pkixErrorResult;
- }
- if (pkixErrorList) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixErrorList, plContext);
- pkixErrorList = NULL;
- }
- return pkixTempResult;
-}
-
-PKIX_Error *
-PKIX_DoReturn(PKIX_StdVars * stdVars, PKIX_ERRORCLASS errClass,
- PKIX_Boolean doLogger, void *plContext)
-{
- PKIX_OBJECT_UNLOCK(lockedObject);
- if (pkixErrorReceived || pkixErrorResult || pkixErrorList)
- return PKIX_DoThrow(stdVars, errClass, pkixErrorCode, pkixErrorClass,
- plContext);
- /* PKIX_DEBUG_EXIT(type); */
- if (doLogger)
- _PKIX_DEBUG_TRACE(pkixLoggersDebugTrace, "<<<", PKIX_LOGGER_LEVEL_TRACE);
- return NULL;
-}
-
-/* PKIX_DoAddError - creates the list of received error if it does not exist
- * yet and adds newly received error into the list. */
-void
-PKIX_DoAddError(PKIX_StdVars *stdVars, PKIX_Error *error, void * plContext)
-{
- PKIX_List *localList = NULL;
- PKIX_Error *localError = NULL;
- PKIX_Boolean listCreated = PKIX_FALSE;
-
- if (!pkixErrorList) {
- localError = PKIX_List_Create(&localList, plContext);
- if (localError)
- goto cleanup;
- listCreated = PKIX_TRUE;
- } else {
- localList = pkixErrorList;
- }
-
- localError = PKIX_List_AppendItem(localList, (PKIX_PL_Object*)error,
- plContext);
- PORT_Assert (localError == NULL);
- if (localError != NULL) {
- if (listCreated) {
- /* ignore the error code of DecRef function */
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)localList, plContext);
- localList = NULL;
- }
- } else {
- pkixErrorList = localList;
- }
-
-cleanup:
-
- if (localError && localError != PKIX_ALLOC_ERROR()) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)localError, plContext);
- }
-
- if (error && error != PKIX_ALLOC_ERROR()) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)error, plContext);
- }
-}
-
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_list.c b/security/nss/lib/libpkix/pkix/util/pkix_list.c
deleted file mode 100755
index d02b66e6d..000000000
--- a/security/nss/lib/libpkix/pkix/util/pkix_list.c
+++ /dev/null
@@ -1,1701 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_list.c
- *
- * List Object Functions
- *
- */
-
-#include "pkix_list.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_List_Create_Internal
- * DESCRIPTION:
- *
- * Creates a new List, using the Boolean value of "isHeader" to determine
- * whether the new List should be a header, and stores it at "pList". The
- * List is initially empty and holds no items. To initially add items to
- * the List, use PKIX_List_AppendItem.
- *
- * PARAMETERS:
- * "isHeader"
- * Boolean value indicating whether new List should be a header.
- * "pList"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_List_Create_Internal(
- PKIX_Boolean isHeader,
- PKIX_List **pList,
- void *plContext)
-{
- PKIX_List *list = NULL;
-
- PKIX_ENTER(LIST, "pkix_List_Create_Internal");
- PKIX_NULLCHECK_ONE(pList);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_LIST_TYPE,
- ((PKIX_UInt32)(sizeof (PKIX_List))),
- (PKIX_PL_Object **)&list, plContext),
- PKIX_ERRORCREATINGLISTITEM);
-
- list->item = NULL;
- list->next = NULL;
- list->immutable = PKIX_FALSE;
- list->length = 0;
- list->isHeader = isHeader;
-
- *pList = list;
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_List_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_List *list = NULL;
- PKIX_List *nextItem = NULL;
-
- PKIX_ENTER(LIST, "pkix_List_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a list */
- PKIX_CHECK(pkix_CheckType(object, PKIX_LIST_TYPE, plContext),
- PKIX_OBJECTNOTLIST);
-
- list = (PKIX_List *)object;
-
- /* We have a valid list. DecRef its item and recurse on next */
- PKIX_DECREF(list->item);
- while ((nextItem = list->next) != NULL) {
- list->next = nextItem->next;
- nextItem->next = NULL;
- PKIX_DECREF(nextItem);
- }
- list->immutable = PKIX_FALSE;
- list->length = 0;
- list->isHeader = PKIX_FALSE;
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_ToString_Helper
- * DESCRIPTION:
- *
- * Helper function that creates a string representation of the List pointed
- * to by "list" and stores its address in the object pointed to by "pString".
- *
- * PARAMETERS
- * "list"
- * Address of List whose string representation is desired.
- * Must be non-NULL.
- * "pString"
- * Address of object pointer's destination. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a List Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_List_ToString_Helper(
- PKIX_List *list,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *itemString = NULL;
- PKIX_PL_String *nextString = NULL;
- PKIX_PL_String *format = NULL;
- PKIX_Boolean empty;
-
- PKIX_ENTER(LIST, "pkix_List_ToString_Helper");
- PKIX_NULLCHECK_TWO(list, pString);
-
- /* special case when list is the header */
- if (list->isHeader){
-
- PKIX_CHECK(PKIX_List_IsEmpty(list, &empty, plContext),
- PKIX_LISTISEMPTYFAILED);
-
- if (empty){
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "EMPTY",
- 0,
- &itemString,
- plContext),
- PKIX_ERRORCREATINGITEMSTRING);
- (*pString) = itemString;
- PKIX_DEBUG_EXIT(LIST);
- return (NULL);
- } else {
- PKIX_CHECK(pkix_List_ToString_Helper
- (list->next, &itemString, plContext),
- PKIX_LISTTOSTRINGHELPERFAILED);
- }
-
- /* Create a string object from the format */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "%s", 0, &format, plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (pString, plContext, format, itemString),
- PKIX_SPRINTFFAILED);
- } else {
- /* Get a string for this list's item */
- if (list->item == NULL) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "(null)",
- 0,
- &itemString,
- plContext),
- PKIX_STRINGCREATEFAILED);
- } else {
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object*)list->item,
- &itemString,
- plContext),
- PKIX_OBJECTTOSTRINGFAILED);
- }
- if (list->next == NULL) {
- /* Just return the itemstring */
- (*pString) = itemString;
- PKIX_DEBUG_EXIT(LIST);
- return (NULL);
- }
-
- /* Recursive call to get string for this list's next pointer */
- PKIX_CHECK(pkix_List_ToString_Helper
- (list->next, &nextString, plContext),
- PKIX_LISTTOSTRINGHELPERFAILED);
-
- /* Create a string object from the format */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- "%s, %s",
- 0,
- &format,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (pString,
- plContext,
- format,
- itemString,
- nextString),
- PKIX_SPRINTFFAILED);
- }
-
-cleanup:
-
- PKIX_DECREF(itemString);
- PKIX_DECREF(nextString);
- PKIX_DECREF(format);
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_List_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_List *list = NULL;
- PKIX_PL_String *listString = NULL;
- PKIX_PL_String *format = NULL;
-
- PKIX_ENTER(LIST, "pkix_List_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_LIST_TYPE, plContext),
- PKIX_OBJECTNOTLIST);
-
- list = (PKIX_List *)object;
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- PKIX_CHECK(pkix_List_ToString_Helper(list, &listString, plContext),
- PKIX_LISTTOSTRINGHELPERFAILED);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "(%s)", 0, &format, plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf(pString, plContext, format, listString),
- PKIX_SPRINTFFAILED);
-
-cleanup:
-
- PKIX_DECREF(listString);
- PKIX_DECREF(format);
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_List_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
- PKIX_List *firstList = NULL;
- PKIX_List *secondList = NULL;
- PKIX_UInt32 firstLength = 0;
- PKIX_UInt32 secondLength = 0;
- PKIX_PL_Object *firstItem = NULL;
- PKIX_PL_Object *secondItem = NULL;
- PKIX_UInt32 i = 0;
-
- PKIX_ENTER(LIST, "pkix_List_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- /* test that first is a List */
- PKIX_CHECK(pkix_CheckType(first, PKIX_LIST_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTLIST);
-
- /*
- * Since we know first is a List, if both references are
- * identical, they must be equal
- */
- if (first == second){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If second isn't a List, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_LIST_TYPE) goto cleanup;
-
- firstList = (PKIX_List *)first;
- secondList = (PKIX_List *)second;
-
- if ((!firstList->isHeader) && (!secondList->isHeader)){
- PKIX_ERROR(PKIX_INPUTLISTSMUSTBELISTHEADERS);
- }
-
- firstLength = firstList->length;
- secondLength = secondList->length;
-
- cmpResult = PKIX_FALSE;
- if (firstLength == secondLength){
- for (i = 0, cmpResult = PKIX_TRUE;
- ((i < firstLength) && cmpResult);
- i++){
- PKIX_CHECK(PKIX_List_GetItem
- (firstList, i, &firstItem, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_List_GetItem
- (secondList, i, &secondItem, plContext),
- PKIX_LISTGETITEMFAILED);
-
- if ((!firstItem && secondItem) ||
- (firstItem && !secondItem)){
- cmpResult = PKIX_FALSE;
- } else if (!firstItem && !secondItem){
- continue;
- } else {
- PKIX_CHECK(PKIX_PL_Object_Equals
- (firstItem,
- secondItem,
- &cmpResult,
- plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- PKIX_DECREF(firstItem);
- PKIX_DECREF(secondItem);
- }
- }
- }
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_DECREF(firstItem);
- PKIX_DECREF(secondItem);
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_List_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_List *list = NULL;
- PKIX_PL_Object *element = NULL;
- PKIX_UInt32 hash = 0;
- PKIX_UInt32 tempHash = 0;
- PKIX_UInt32 length, i;
-
- PKIX_ENTER(LIST, "pkix_List_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_LIST_TYPE, plContext),
- PKIX_OBJECTNOTLIST);
-
- list = (PKIX_List *)object;
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- length = list->length;
-
- for (i = 0; i < length; i++){
- PKIX_CHECK(PKIX_List_GetItem(list, i, &element, plContext),
- PKIX_LISTGETITEMFAILED);
-
- if (!element){
- tempHash = 100;
- } else {
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- (element, &tempHash, plContext),
- PKIX_LISTHASHCODEFAILED);
- }
-
- hash = 31 * hash + tempHash;
-
- PKIX_DECREF(element);
- }
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_DECREF(element);
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_Duplicate
- * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_List_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_List *list = NULL;
- PKIX_List *listDuplicate = NULL;
-
- PKIX_ENTER(LIST, "pkix_List_Duplicate");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_LIST_TYPE, plContext),
- PKIX_OBJECTNOTLIST);
-
- list = (PKIX_List *)object;
-
- if (list->immutable){
- PKIX_CHECK(pkix_duplicateImmutable
- (object, pNewObject, plContext),
- PKIX_DUPLICATEIMMUTABLEFAILED);
- } else {
-
- PKIX_CHECK(pkix_List_Create_Internal
- (list->isHeader, &listDuplicate, plContext),
- PKIX_LISTCREATEINTERNALFAILED);
-
- listDuplicate->length = list->length;
-
- PKIX_INCREF(list->item);
- listDuplicate->item = list->item;
-
- if (list->next == NULL){
- listDuplicate->next = NULL;
- } else {
- /* Recursively Duplicate list */
- PKIX_CHECK(pkix_List_Duplicate
- ((PKIX_PL_Object *)list->next,
- (PKIX_PL_Object **)&listDuplicate->next,
- plContext),
- PKIX_LISTDUPLICATEFAILED);
- }
-
- *pNewObject = (PKIX_PL_Object *)listDuplicate;
- }
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(listDuplicate);
- }
-
- PKIX_RETURN(LIST);
-}
-
-
-/*
- * FUNCTION: pkix_List_GetElement
- * DESCRIPTION:
- *
- * Copies the "list"'s element at "index" into "element". The input List must
- * be the header of the List (as opposed to being an element of the List). The
- * index counts from zero and must be less than the List's length. This
- * function does NOT increment the reference count of the List element since
- * the returned element's reference will not be stored by the calling
- * function.
- *
- * PARAMETERS:
- * "list"
- * Address of List (must be header) to get element from. Must be non-NULL.
- * "index"
- * Index of list to get element from. Must be less than List's length.
- * "pElement"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_List_GetElement(
- PKIX_List *list,
- PKIX_UInt32 index,
- PKIX_List **pElement,
- void *plContext)
-{
- PKIX_List *iterator = NULL;
- PKIX_UInt32 length;
- PKIX_UInt32 position = 0;
-
- PKIX_ENTER(LIST, "pkix_List_GetElement");
- PKIX_NULLCHECK_TWO(list, pElement);
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- length = list->length;
-
- if (index >= length) {
- PKIX_ERROR(PKIX_INDEXOUTOFBOUNDS);
- }
-
- for (iterator = list; position++ <= index; iterator = iterator->next)
- ;
-
- (*pElement) = iterator;
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-
-/*
- * FUNCTION: pkix_List_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_LIST_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_List_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(LIST, "pkix_List_RegisterSelf");
-
- entry.description = "List";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_List);
- entry.destructor = pkix_List_Destroy;
- entry.equalsFunction = pkix_List_Equals;
- entry.hashcodeFunction = pkix_List_Hashcode;
- entry.toStringFunction = pkix_List_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_List_Duplicate;
-
- systemClasses[PKIX_LIST_TYPE] = entry;
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_Contains
- * DESCRIPTION:
- *
- * Checks a List pointed to by "list", to determine whether it includes
- * an entry that is equal to the Object pointed to by "object", and stores
- * the result in "pFound".
- *
- * PARAMETERS:
- * "list"
- * List to be searched; may be empty; must be non-NULL
- * "object"
- * Object to be checked for; must be non-NULL
- * "pFound"
- * Address where the result of the search will be stored. Must
- * be non-NULL
- * "plContext"
- * platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_List_Contains(
- PKIX_List *list,
- PKIX_PL_Object *object,
- PKIX_Boolean *pFound,
- void *plContext)
-{
- PKIX_PL_Object *current = NULL;
- PKIX_UInt32 numEntries = 0;
- PKIX_UInt32 index = 0;
- PKIX_Boolean match = PKIX_FALSE;
-
- PKIX_ENTER(LIST, "pkix_List_Contains");
- PKIX_NULLCHECK_THREE(list, object, pFound);
-
- PKIX_CHECK(PKIX_List_GetLength(list, &numEntries, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (index = 0; index < numEntries; index++) {
- PKIX_CHECK(PKIX_List_GetItem
- (list, index, &current, plContext),
- PKIX_LISTGETITEMFAILED);
-
- if (current) {
- PKIX_CHECK(PKIX_PL_Object_Equals
- (object, current, &match, plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- PKIX_DECREF(current);
- }
-
- if (match) {
- break;
- }
- }
-
- *pFound = match;
-
-cleanup:
-
- PKIX_DECREF(current);
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_Remove
- * DESCRIPTION:
- *
- * Traverses the List pointed to by "list", to find and delete an entry
- * that is equal to the Object pointed to by "object". If no such entry
- * is found the function does not return an error.
- *
- * PARAMETERS:
- * "list"
- * List to be searched; may be empty; must be non-NULL
- * "object"
- * Object to be checked for and deleted, if found; must be non-NULL
- * "plContext"
- * platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a Validate Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_List_Remove(
- PKIX_List *list,
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_Object *current = NULL;
- PKIX_UInt32 numEntries = 0;
- PKIX_UInt32 index = 0;
- PKIX_Boolean match = PKIX_FALSE;
-
- PKIX_ENTER(LIST, "pkix_List_Remove");
- PKIX_NULLCHECK_TWO(list, object);
-
- PKIX_CHECK(PKIX_List_GetLength(list, &numEntries, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (index = 0; index < numEntries; index++) {
- PKIX_CHECK(PKIX_List_GetItem
- (list, index, &current, plContext),
- PKIX_LISTGETITEMFAILED);
-
- if (current) {
- PKIX_CHECK(PKIX_PL_Object_Equals
- (object, current, &match, plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- PKIX_DECREF(current);
- }
-
- if (match) {
- PKIX_CHECK(PKIX_List_DeleteItem
- (list, index, plContext),
- PKIX_LISTDELETEITEMFAILED);
- break;
- }
- }
-
-cleanup:
-
- PKIX_DECREF(current);
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_RemoveItems
- * DESCRIPTION:
- *
- * Traverses the List pointed to by "list", to find and delete an entry
- * that is equal to the Object in the "deleteList". If no such entry
- * is found the function does not return an error.
- *
- * PARAMETERS:
- * "list"
- * Object in "list" is checked for object in "deleteList" and deleted if
- * found; may be empty; must be non-NULL
- * "deleteList"
- * List of objects to be searched ; may be empty; must be non-NULL
- * "plContext"
- * platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a Validate Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_List_RemoveItems(
- PKIX_List *list,
- PKIX_List *deleteList,
- void *plContext)
-{
- PKIX_PL_Object *current = NULL;
- PKIX_UInt32 numEntries = 0;
- PKIX_UInt32 index = 0;
-
- PKIX_ENTER(LIST, "pkix_List_RemoveItems");
- PKIX_NULLCHECK_TWO(list, deleteList);
-
- PKIX_CHECK(PKIX_List_GetLength(deleteList, &numEntries, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (index = 0; index < numEntries; index++) {
- PKIX_CHECK(PKIX_List_GetItem
- (deleteList, index, &current, plContext),
- PKIX_LISTGETITEMFAILED);
-
- if (current) {
- PKIX_CHECK(pkix_List_Remove
- (list, current, plContext),
- PKIX_OBJECTEQUALSFAILED);
-
- PKIX_DECREF(current);
- }
- }
-
-cleanup:
-
- PKIX_DECREF(current);
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_MergeLists
- * DESCRIPTION:
- *
- * Creates a new list consisting of the items from "firstList", followed by
- * the items on "secondList", returns the new list at "pMergedList". If
- * both input lists are NULL or empty, the result is an empty list. If an error
- * occurs, the result is NULL.
- *
- * PARAMETERS:
- * "firstList"
- * Address of list to be merged from. May be NULL or empty.
- * "secondList"
- * Address of list to be merged from. May be NULL or empty.
- * "pMergedList"
- * Address where returned object is stored.
- * "plContext"
- * platform-specific context pointer * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a List Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_List_MergeLists(
- PKIX_List *firstList,
- PKIX_List *secondList,
- PKIX_List **pMergedList,
- void *plContext)
-{
- PKIX_List *list = NULL;
- PKIX_PL_Object *item = NULL;
- PKIX_UInt32 numItems = 0;
- PKIX_UInt32 i;
-
- PKIX_ENTER(LIST, "pkix_List_MergeLists");
- PKIX_NULLCHECK_ONE(pMergedList);
-
- *pMergedList = NULL;
-
- PKIX_CHECK(PKIX_List_Create(&list, plContext),
- PKIX_LISTCREATEFAILED);
-
- if (firstList != NULL) {
-
- PKIX_CHECK(PKIX_List_GetLength(firstList, &numItems, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem(firstList, i, &item, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem(list, item, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(item);
- }
-
- numItems = 0;
- if (secondList != NULL) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (secondList,
- &numItems,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- }
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (secondList, i, &item, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (list, item, plContext), PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(item);
- }
-
- *pMergedList = list;
- list = NULL;
-
-cleanup:
- PKIX_DECREF(list);
- PKIX_DECREF(item);
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_AppendList
- * DESCRIPTION:
- *
- * Append items on "fromList" to the "toList". Item reference count on
- * "toList" is not incremented, but items appended from "fromList" are
- * incremented.
- *
- * PARAMETERS:
- * "toList"
- * Address of list to be appended to. Must be non-NULL.
- * "fromList"
- * Address of list to be appended from. May be NULL or empty.
- * "plContext"
- * platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a List Error if the functions fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_List_AppendList(
- PKIX_List *toList,
- PKIX_List *fromList,
- void *plContext)
-{
- PKIX_PL_Object *item = NULL;
- PKIX_UInt32 numItems = 0;
- PKIX_UInt32 i;
-
- PKIX_ENTER(LIST, "pkix_List_AppendList");
- PKIX_NULLCHECK_ONE(toList);
-
- /* if fromList is NULL or is an empty list, no action */
-
- if (fromList == NULL) {
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_List_GetLength(fromList, &numItems, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (numItems == 0) {
- goto cleanup;
- }
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (fromList, i, &item, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem(toList, item, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(item);
- }
-
-cleanup:
-
- PKIX_DECREF(item);
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_AppendUnique
- * DESCRIPTION:
- *
- * Adds each Object in the List pointed to by "fromList" to the List pointed
- * to by "toList", if it is not already a member of that List. In other words,
- * "toList" becomes the union of the two sets.
- *
- * PARAMETERS:
- * "toList"
- * Address of a List of Objects to be augmented by "fromList". Must be
- * non-NULL, but may be empty.
- * "fromList"
- * Address of a List of Objects to be added, if not already present, to
- * "toList". Must be non-NULL, but may be empty.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "toList"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_List_AppendUnique(
- PKIX_List *toList,
- PKIX_List *fromList,
- void *plContext)
-{
- PKIX_Boolean isContained = PKIX_FALSE;
- PKIX_UInt32 listLen = 0;
- PKIX_UInt32 listIx = 0;
- PKIX_PL_Object *object = NULL;
-
- PKIX_ENTER(BUILD, "pkix_List_AppendUnique");
- PKIX_NULLCHECK_TWO(fromList, toList);
-
- PKIX_CHECK(PKIX_List_GetLength(fromList, &listLen, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (listIx = 0; listIx < listLen; listIx++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (fromList, listIx, &object, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_List_Contains
- (toList, object, &isContained, plContext),
- PKIX_LISTCONTAINSFAILED);
-
- if (isContained == PKIX_FALSE) {
- PKIX_CHECK(PKIX_List_AppendItem
- (toList, object, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
-
- PKIX_DECREF(object);
- }
-
-cleanup:
-
- PKIX_DECREF(object);
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_QuickSort
- * DESCRIPTION:
- *
- * Sorts List of Objects "fromList" using "comparatorCallback"'s result as
- * comasrison key and returns the sorted List at "pSortedList". The sorting
- * algorithm used is quick sort (n*logn).
- *
- * PARAMETERS:
- * "fromList"
- * Address of a List of Objects to be sorted. Must be non-NULL, but may be
- * empty.
- * "comparatorCallback"
- * Address of callback function that will compare two Objects on the List.
- * It should return -1 for less, 0 for equal and 1 for greater. The
- * callback implementation chooses what in Objects to be compared. Must be
- * non-NULL.
- * "pSortedList"
- * Address of a List of Objects that shall be sorted and returned. Must be
- * non-NULL, but may be empty.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "toList"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_List_QuickSort(
- PKIX_List *fromList,
- PKIX_List_SortComparatorCallback comparator,
- PKIX_List **pSortedList,
- void *plContext)
-{
- PKIX_List *sortedList = NULL;
- PKIX_List *lessList = NULL;
- PKIX_List *greaterList = NULL;
- PKIX_List *sortedLessList = NULL;
- PKIX_List *sortedGreaterList = NULL;
- PKIX_PL_Object *object = NULL;
- PKIX_PL_Object *cmpObj = NULL;
- PKIX_Int32 cmpResult = 0;
- PKIX_UInt32 size = 0;
- PKIX_UInt32 i;
-
- PKIX_ENTER(BUILD, "pkix_List_QuickSort");
- PKIX_NULLCHECK_THREE(fromList, comparator, pSortedList);
-
- PKIX_CHECK(PKIX_List_GetLength(fromList, &size, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- PKIX_CHECK(PKIX_List_Create(&lessList, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_Create(&greaterList, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetItem
- (fromList, 0, &object, plContext),
- PKIX_LISTGETITEMFAILED);
-
- /*
- * Pick the first item on the list as the one to be compared.
- * Separate rest of the itmes into two lists: less-than or greater-
- * than lists. Sort those two lists recursively. Insert sorted
- * less-than list before the picked item and append the greater-
- * than list after the picked item.
- */
- for (i = 1; i < size; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (fromList, i, &cmpObj, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(comparator(object, cmpObj, &cmpResult, plContext),
- PKIX_COMPARATORCALLBACKFAILED);
-
- if (cmpResult >= 0) {
- PKIX_CHECK(PKIX_List_AppendItem
- (lessList, cmpObj, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- } else {
- PKIX_CHECK(PKIX_List_AppendItem
- (greaterList, cmpObj, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
- PKIX_DECREF(cmpObj);
- }
-
- PKIX_CHECK(PKIX_List_Create(&sortedList, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(lessList, &size, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (size > 1) {
-
- PKIX_CHECK(pkix_List_QuickSort
- (lessList, comparator, &sortedLessList, plContext),
- PKIX_LISTQUICKSORTFAILED);
-
- PKIX_CHECK(pkix_List_AppendList
- (sortedList, sortedLessList, plContext),
- PKIX_LISTAPPENDLISTFAILED);
- } else {
- PKIX_CHECK(pkix_List_AppendList
- (sortedList, lessList, plContext),
- PKIX_LISTAPPENDLISTFAILED);
- }
-
- PKIX_CHECK(PKIX_List_AppendItem(sortedList, object, plContext),
- PKIX_LISTAPPENDFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(greaterList, &size, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (size > 1) {
-
- PKIX_CHECK(pkix_List_QuickSort
- (greaterList, comparator, &sortedGreaterList, plContext),
- PKIX_LISTQUICKSORTFAILED);
-
- PKIX_CHECK(pkix_List_AppendList
- (sortedList, sortedGreaterList, plContext),
- PKIX_LISTAPPENDLISTFAILED);
- } else {
- PKIX_CHECK(pkix_List_AppendList
- (sortedList, greaterList, plContext),
- PKIX_LISTAPPENDLISTFAILED);
- }
-
- *pSortedList = sortedList;
-
-cleanup:
-
- PKIX_DECREF(cmpObj);
- PKIX_DECREF(object);
- PKIX_DECREF(sortedGreaterList);
- PKIX_DECREF(sortedLessList);
- PKIX_DECREF(greaterList);
- PKIX_DECREF(lessList);
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: pkix_List_BubbleSort
- * DESCRIPTION:
- *
- * Sorts List of Objects "fromList" using "comparatorCallback"'s result as
- * comasrison key and returns the sorted List at "pSortedList". The sorting
- * algorithm used is bubble sort (n*n).
- *
- * PARAMETERS:
- * "fromList"
- * Address of a List of Objects to be sorted. Must be non-NULL, but may be
- * empty.
- * "comparatorCallback"
- * Address of callback function that will compare two Objects on the List.
- * It should return -1 for less, 0 for equal and 1 for greater. The
- * callback implementation chooses what in Objects to be compared. Must be
- * non-NULL.
- * "pSortedList"
- * Address of a List of Objects that shall be sorted and returned. Must be
- * non-NULL, but may be empty.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "toList"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_List_BubbleSort(
- PKIX_List *fromList,
- PKIX_List_SortComparatorCallback comparator,
- PKIX_List **pSortedList,
- void *plContext)
-{
- PKIX_List *sortedList = NULL;
- PKIX_PL_Object *cmpObj = NULL;
- PKIX_PL_Object *leastObj = NULL;
- PKIX_Int32 cmpResult = 0;
- PKIX_UInt32 size = 0;
- PKIX_UInt32 i, j;
-
- PKIX_ENTER(BUILD, "pkix_List_BubbleSort");
- PKIX_NULLCHECK_THREE(fromList, comparator, pSortedList);
-
- if (fromList->immutable) {
- PKIX_ERROR(PKIX_CANNOTSORTIMMUTABLELIST);
- }
- PKIX_CHECK(pkix_List_Duplicate
- ((PKIX_PL_Object *) fromList,
- (PKIX_PL_Object **) &sortedList,
- plContext),
- PKIX_LISTDUPLICATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(sortedList, &size, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (size > 1) {
-
- /*
- * Move from the first of the item on the list, For each iteration,
- * compare and swap the least value to the head of the comparisoning
- * sub-list.
- */
- for (i = 0; i < size - 1; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (sortedList, i, &leastObj, plContext),
- PKIX_LISTGETITEMFAILED);
-
- for (j = i + 1; j < size; j++) {
- PKIX_CHECK(PKIX_List_GetItem
- (sortedList, j, &cmpObj, plContext),
- PKIX_LISTGETITEMFAILED);
- PKIX_CHECK(comparator
- (leastObj, cmpObj, &cmpResult, plContext),
- PKIX_COMPARATORCALLBACKFAILED);
- if (cmpResult > 0) {
- PKIX_CHECK(PKIX_List_SetItem
- (sortedList, j, leastObj, plContext),
- PKIX_LISTSETITEMFAILED);
-
- PKIX_DECREF(leastObj);
- leastObj = cmpObj;
- cmpObj = NULL;
- } else {
- PKIX_DECREF(cmpObj);
- }
- }
- PKIX_CHECK(PKIX_List_SetItem
- (sortedList, i, leastObj, plContext),
- PKIX_LISTSETITEMFAILED);
-
- PKIX_DECREF(leastObj);
- }
-
- }
-
- *pSortedList = sortedList;
- sortedList = NULL;
-cleanup:
-
- PKIX_DECREF(sortedList);
- PKIX_DECREF(leastObj);
- PKIX_DECREF(cmpObj);
-
- PKIX_RETURN(LIST);
-}
-
-/* --Public-List-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_List_Create (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_Create(
- PKIX_List **pList,
- void *plContext)
-{
- PKIX_List *list = NULL;
-
- PKIX_ENTER(LIST, "PKIX_List_Create");
- PKIX_NULLCHECK_ONE(pList);
-
- PKIX_CHECK(pkix_List_Create_Internal(PKIX_TRUE, &list, plContext),
- PKIX_LISTCREATEINTERNALFAILED);
-
- *pList = list;
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_SetImmutable (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_SetImmutable(
- PKIX_List *list,
- void *plContext)
-{
- PKIX_ENTER(LIST, "PKIX_List_SetImmutable");
- PKIX_NULLCHECK_ONE(list);
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- list->immutable = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_IsImmutable (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_IsImmutable(
- PKIX_List *list,
- PKIX_Boolean *pImmutable,
- void *plContext)
-{
- PKIX_ENTER(LIST, "PKIX_List_IsImmutable");
- PKIX_NULLCHECK_TWO(list, pImmutable);
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- *pImmutable = list->immutable;
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_GetLength (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_GetLength(
- PKIX_List *list,
- PKIX_UInt32 *pLength,
- void *plContext)
-{
- PKIX_ENTER(LIST, "PKIX_List_GetLength");
- PKIX_NULLCHECK_TWO(list, pLength);
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- *pLength = list->length;
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_IsEmpty (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_IsEmpty(
- PKIX_List *list,
- PKIX_Boolean *pEmpty,
- void *plContext)
-{
- PKIX_UInt32 length;
-
- PKIX_ENTER(LIST, "PKIX_List_IsEmpty");
- PKIX_NULLCHECK_TWO(list, pEmpty);
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- length = list->length;
-
- if (length == 0){
- *pEmpty = PKIX_TRUE;
- } else {
- *pEmpty = PKIX_FALSE;
- }
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_AppendItem (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_AppendItem(
- PKIX_List *list,
- PKIX_PL_Object *item,
- void *plContext)
-{
- PKIX_List *lastElement = NULL;
- PKIX_List *newElement = NULL;
- PKIX_UInt32 length, i;
-
- PKIX_ENTER(LIST, "PKIX_List_AppendItem");
- PKIX_NULLCHECK_ONE(list);
-
- if (list->immutable){
- PKIX_ERROR(PKIX_OPERATIONNOTPERMITTEDONIMMUTABLELIST);
- }
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- length = list->length;
-
- /* find last element of list and create new element there */
-
- lastElement = list;
- for (i = 0; i < length; i++){
- lastElement = lastElement->next;
- }
-
- PKIX_CHECK(pkix_List_Create_Internal
- (PKIX_FALSE, &newElement, plContext),
- PKIX_LISTCREATEINTERNALFAILED);
-
- PKIX_INCREF(item);
- newElement->item = item;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)list, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- lastElement->next = newElement;
- newElement = NULL;
- list->length += 1;
-
-cleanup:
-
- PKIX_DECREF(newElement);
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_InsertItem (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_InsertItem(
- PKIX_List *list,
- PKIX_UInt32 index,
- PKIX_PL_Object *item,
- void *plContext)
-{
- PKIX_List *element = NULL;
- PKIX_List *newElem = NULL;
-
- PKIX_ENTER(LIST, "PKIX_List_InsertItem");
- PKIX_NULLCHECK_ONE(list);
-
-
- if (list->immutable){
- PKIX_ERROR(PKIX_OPERATIONNOTPERMITTEDONIMMUTABLELIST);
- }
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- /* Create a new list object */
- PKIX_CHECK(pkix_List_Create_Internal(PKIX_FALSE, &newElem, plContext),
- PKIX_LISTCREATEINTERNALFAILED);
-
- if (list->length) {
- PKIX_CHECK(pkix_List_GetElement(list, index, &element, plContext),
- PKIX_LISTGETELEMENTFAILED);
- /* Copy the old element's contents into the new element */
- newElem->item = element->item;
- /* Add new item to the list */
- PKIX_INCREF(item);
- element->item = item;
- /* Set the new element's next pointer to the old element's next */
- newElem->next = element->next;
- /* Set the old element's next pointer to the new element */
- element->next = newElem;
- newElem = NULL;
- } else {
- PKIX_INCREF(item);
- newElem->item = item;
- newElem->next = NULL;
- list->next = newElem;
- newElem = NULL;
- }
- list->length++;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)list, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-cleanup:
- PKIX_DECREF(newElem);
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_GetItem (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_GetItem(
- PKIX_List *list,
- PKIX_UInt32 index,
- PKIX_PL_Object **pItem,
- void *plContext)
-{
- PKIX_List *element = NULL;
-
- PKIX_ENTER(LIST, "PKIX_List_GetItem");
- PKIX_NULLCHECK_TWO(list, pItem);
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- PKIX_CHECK(pkix_List_GetElement(list, index, &element, plContext),
- PKIX_LISTGETELEMENTFAILED);
-
- PKIX_INCREF(element->item);
- *pItem = element->item;
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_SetItem (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_SetItem(
- PKIX_List *list,
- PKIX_UInt32 index,
- PKIX_PL_Object *item,
- void *plContext)
-{
- PKIX_List *element;
-
- PKIX_ENTER(LIST, "PKIX_List_SetItem");
- PKIX_NULLCHECK_ONE(list);
-
- if (list->immutable){
- PKIX_ERROR(PKIX_OPERATIONNOTPERMITTEDONIMMUTABLELIST);
- }
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- PKIX_CHECK(pkix_List_GetElement(list, index, &element, plContext),
- PKIX_LISTGETELEMENTFAILED);
-
- /* DecRef old contents */
- PKIX_DECREF(element->item);
-
- /* Set New Contents */
- PKIX_INCREF(item);
- element->item = item;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)list, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_DeleteItem (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_DeleteItem(
- PKIX_List *list,
- PKIX_UInt32 index,
- void *plContext)
-{
- PKIX_List *element = NULL;
- PKIX_List *prevElement = NULL;
- PKIX_List *nextElement = NULL;
-
- PKIX_ENTER(LIST, "PKIX_List_DeleteItem");
- PKIX_NULLCHECK_ONE(list);
-
- if (list->immutable){
- PKIX_ERROR(PKIX_OPERATIONNOTPERMITTEDONIMMUTABLELIST);
- }
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- PKIX_CHECK(pkix_List_GetElement(list, index, &element, plContext),
- PKIX_LISTGETELEMENTFAILED);
-
- /* DecRef old contents */
- PKIX_DECREF(element->item);
-
- nextElement = element->next;
-
- if (nextElement != NULL) {
- /* If the next element exists, splice it out. */
-
- /* Don't need to change ref counts for targets of next */
- element->item = nextElement->item;
- nextElement->item = NULL;
-
- /* Don't need to change ref counts for targets of next */
- element->next = nextElement->next;
- nextElement->next = NULL;
-
- PKIX_DECREF(nextElement);
-
- } else { /* The element is at the tail of the list */
- if (index != 0) {
- PKIX_CHECK(pkix_List_GetElement
- (list, index-1, &prevElement, plContext),
- PKIX_LISTGETELEMENTFAILED);
- } else if (index == 0){ /* prevElement must be header */
- prevElement = list;
- }
- prevElement->next = NULL;
-
- /* Delete the element */
- PKIX_DECREF(element);
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)list, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- list->length = list->length - 1;
-
-cleanup:
-
- PKIX_RETURN(LIST);
-}
-
-/*
- * FUNCTION: PKIX_List_ReverseList (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_List_ReverseList(
- PKIX_List *list,
- PKIX_List **pReversedList,
- void *plContext)
-{
- PKIX_List *reversedList = NULL;
- PKIX_PL_Object *item = NULL;
- PKIX_PL_Object *duplicateItem = NULL;
- PKIX_UInt32 length, i;
-
- PKIX_ENTER(LIST, "pkix_List_ReverseList");
- PKIX_NULLCHECK_TWO(list, pReversedList);
-
- if (!list->isHeader){
- PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
- }
-
- length = list->length;
-
- /* Create a new list object */
- PKIX_CHECK(PKIX_List_Create(&reversedList, plContext),
- PKIX_LISTCREATEINTERNALFAILED);
-
- /*
- * Starting with the last item and traversing backwards (from
- * the original list), append each item to the reversed list
- */
-
- for (i = 1; i <= length; i++){
- PKIX_CHECK(PKIX_List_GetItem
- (list, (length - i), &item, plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- (item, &duplicateItem, plContext),
- PKIX_LISTDUPLICATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (reversedList, duplicateItem, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(item);
- PKIX_DECREF(duplicateItem);
- }
-
- *pReversedList = reversedList;
-
-cleanup:
-
- PKIX_DECREF(item);
- PKIX_DECREF(duplicateItem);
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(reversedList);
- }
-
- PKIX_RETURN(LIST);
-}
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_list.h b/security/nss/lib/libpkix/pkix/util/pkix_list.h
deleted file mode 100755
index 13e104f21..000000000
--- a/security/nss/lib/libpkix/pkix/util/pkix_list.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_list.h
- *
- * List Object Type Definition
- *
- */
-
-#ifndef _PKIX_LIST_H
-#define _PKIX_LIST_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef PKIX_Error *
-(*PKIX_List_SortComparatorCallback)(
- PKIX_PL_Object *obj1,
- PKIX_PL_Object *obj2,
- PKIX_Int32 *pResult,
- void *plContext);
-
-struct PKIX_ListStruct {
- PKIX_PL_Object *item;
- PKIX_List *next;
- PKIX_Boolean immutable;
- PKIX_UInt32 length;
- PKIX_Boolean isHeader;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_List_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_List_Contains(
- PKIX_List *list,
- PKIX_PL_Object *object,
- PKIX_Boolean *pFound,
- void *plContext);
-
-PKIX_Error *
-pkix_List_Remove(
- PKIX_List *list,
- PKIX_PL_Object *target,
- void *plContext);
-
-PKIX_Error *
-pkix_List_MergeLists(
- PKIX_List *firstList,
- PKIX_List *secondList,
- PKIX_List **pMergedList,
- void *plContext);
-
-PKIX_Error *
-pkix_List_AppendList(
- PKIX_List *toList,
- PKIX_List *fromList,
- void *plContext);
-
-PKIX_Error *
-pkix_List_AppendUnique(
- PKIX_List *toList,
- PKIX_List *fromList,
- void *plContext);
-
-PKIX_Error *
-pkix_List_RemoveItems(
- PKIX_List *list,
- PKIX_List *deleteList,
- void *plContext);
-
-PKIX_Error *
-pkix_List_QuickSort(
- PKIX_List *fromList,
- PKIX_List_SortComparatorCallback comparator,
- PKIX_List **pSortedList,
- void *plContext);
-
-PKIX_Error *
-pkix_List_BubbleSort(
- PKIX_List *fromList,
- PKIX_List_SortComparatorCallback comparator,
- PKIX_List **pSortedList,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_LIST_H */
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_logger.c b/security/nss/lib/libpkix/pkix/util/pkix_logger.c
deleted file mode 100644
index cfd870def..000000000
--- a/security/nss/lib/libpkix/pkix/util/pkix_logger.c
+++ /dev/null
@@ -1,1088 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_logger.c
- *
- * Logger Object Functions
- *
- */
-
-#include "pkix_logger.h"
-#ifndef PKIX_ERROR_DESCRIPTION
-#include "prprf.h"
-#endif
-
-/* Global variable to keep PKIX_Logger List */
-PKIX_List *pkixLoggers = NULL;
-
-/*
- * Once the Logger has been set, for any logging related operations, we have
- * to go through the List to find a match, and if found, issue the
- * corresponding callback. The overhead to check for DEBUG and TRACE in each
- * PKIX function entering and exiting is very expensive (400X), and redundant
- * if they are not the interest of the Logger. Therefore, the PKIX_Logger List
- * pkixLoggers is separated into two lists based on its Loggers' trace level.
- *
- * Whenever the pkixLoggers List is updated by PKIX_Logger_AddLogger() or
- * PKIX_Logger_SetLoggers(), we destroy and reconstruct pkixLoggersErrors
- * and pkixLoggersDebugTrace Logger Lists. The ERROR, FATAL_ERROR and
- * WARNING goes to pkixLoggersErrors and the DEBUG and TRACE goes to
- * pkixLoggersDebugTrace.
- *
- * Currently we provide five logging levels and the default setting are by:
- *
- * PKIX_FATAL_ERROR() macro invokes pkix_Logger_Check of FATAL_ERROR level
- * PKIX_ERROR() macro invokes pkix_Logger_Check of ERROR level
- * WARNING is not invoked as default
- * PKIX_DEBUG() macro invokes pkix_Logger_Check of DEBUG level. This needs
- * compilation -DPKIX_<component>DEBUG flag to turn on
- * PKIX_ENTER() and PKIX_RETURN() macros invoke pkix_Logger_Check of TRACE
- * level. TRACE provides duplicate information of DEBUG, but needs no
- * recompilation and cannot choose component. To allow application
- * to use DEBUG level, TRACE is put as last.
- *
- */
-PKIX_List *pkixLoggersErrors = NULL;
-PKIX_List *pkixLoggersDebugTrace = NULL;
-
-/* To ensure atomic update on pkixLoggers lists */
-PKIX_PL_MonitorLock *pkixLoggerLock = NULL;
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_Logger_CheckErrors
- * DESCRIPTION:
- *
- * This function goes through each PKIX_Logger at "pkixLoggersList" and
- * checks if "maxLevel" and "logComponent" satisfies what is specified in the
- * PKIX_Logger. If satisfies, it invokes the callback in PKIX_Logger and
- * passes a PKIX_PL_String that is the concatenation of "message" and
- * "message2" to the application for processing.
- * Since this call is inserted into a handful of PKIX macros, no macros are
- * applied in this function, to avoid infinite recursion.
- * If an error occurs, this call is aborted.
- *
- * PARAMETERS:
- * "pkixLoggersList"
- * A list of PKIX_Loggers to be examined for invoking callback. Must be
- * non-NULL.
- * "message"
- * Address of "message" to be logged. Must be non-NULL.
- * "message2"
- * Address of "message2" to be concatenated and logged. May be NULL.
- * "logComponent"
- * A PKIX_UInt32 that indicates the component the message is from.
- * "maxLevel"
- * A PKIX_UInt32 that represents the level of severity of the message.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a Fatal Error if the function fails in an unrecoverable way
- */
-PKIX_Error *
-pkix_Logger_Check(
- PKIX_List *pkixLoggersList,
- const char *message,
- const char *message2,
- PKIX_ERRORCLASS logComponent,
- PKIX_UInt32 currentLevel,
- void *plContext)
-{
- PKIX_Logger *logger = NULL;
- PKIX_List *savedPkixLoggersErrors = NULL;
- PKIX_List *savedPkixLoggersDebugTrace = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *messageString = NULL;
- PKIX_PL_String *message2String = NULL;
- PKIX_PL_String *msgString = NULL;
- PKIX_Error *error = NULL;
- PKIX_Boolean needLogging = PKIX_FALSE;
- PKIX_UInt32 i, length;
-
- /*
- * We cannot use any the PKIX_ macros here, since this function is
- * called from some of these macros. It can create infinite recursion.
- */
-
- if ((pkixLoggersList == NULL) || (message == NULL)) {
- return(NULL);
- }
-
- /*
- * Disable all subsequent loggings to avoid recursion. The result is
- * if other thread is calling this function at the same time, there
- * won't be any logging because the pkixLoggersErrors and
- * pkixLoggersDebugTrace are set to null.
- * It would be nice if we provide control per thread (e.g. make
- * plContext threadable) then we can avoid the recursion by setting
- * flag at plContext. Then other thread's logging won't be affected.
- *
- * Also we need to use a reentrant Lock. Although we avoid recursion
- * for TRACE. When there is an ERROR occurs in subsequent call, this
- * function will be called.
- */
-
- error = PKIX_PL_MonitorLock_Enter(pkixLoggerLock, plContext);
- if (error) { return(NULL); }
-
- savedPkixLoggersDebugTrace = pkixLoggersDebugTrace;
- pkixLoggersDebugTrace = NULL;
- savedPkixLoggersErrors = pkixLoggersErrors;
- pkixLoggersErrors = NULL;
-
- /* Convert message and message2 to String */
- error = PKIX_PL_String_Create
- (PKIX_ESCASCII, message, 0, &messageString, plContext);
- if (error) { goto cleanup; }
-
- if (message2) {
- error = PKIX_PL_String_Create
- (PKIX_ESCASCII, message2, 0, &message2String, plContext);
- if (error) { goto cleanup; }
- error = PKIX_PL_String_Create
- (PKIX_ESCASCII, "%s %s", 0, &formatString, plContext);
- if (error) { goto cleanup; }
-
- } else {
- error = PKIX_PL_String_Create
- (PKIX_ESCASCII, "%s", 0, &formatString, plContext);
- if (error) { goto cleanup; }
-
- }
-
- error = PKIX_PL_Sprintf
- (&msgString,
- plContext,
- formatString,
- messageString,
- message2String);
- if (error) { goto cleanup; }
-
- /* Go through the Logger list */
-
- error = PKIX_List_GetLength(pkixLoggersList, &length, plContext);
- if (error) { goto cleanup; }
-
- for (i = 0; i < length; i++) {
-
- error = PKIX_List_GetItem
- (pkixLoggersList,
- i,
- (PKIX_PL_Object **) &logger,
- plContext);
- if (error) { goto cleanup; }
-
- /* Intended logging level less or equal than the max */
- needLogging = (currentLevel <= logger->maxLevel);
-
- if (needLogging && (logger->callback)) {
-
- /*
- * We separate Logger into two lists based on log level
- * but log level is not modified. We need to check here to
- * avoid logging the higher log level (lower value) twice.
- */
- if (pkixLoggersList == pkixLoggersErrors) {
- needLogging = needLogging &&
- (currentLevel <= PKIX_LOGGER_LEVEL_WARNING);
- } else if (pkixLoggersList == pkixLoggersDebugTrace) {
- needLogging = needLogging &&
- (currentLevel > PKIX_LOGGER_LEVEL_WARNING);
- }
-
- if (needLogging) {
- if (logComponent == logger->logComponent) {
- needLogging = PKIX_TRUE;
- } else {
- needLogging = PKIX_FALSE;
- }
- }
-
- if (needLogging) {
- error = logger->callback
- (logger,
- msgString,
- currentLevel,
- logComponent,
- plContext);
- if (error) { goto cleanup; }
- }
- }
-
- error = PKIX_PL_Object_DecRef
- ((PKIX_PL_Object *)logger, plContext);
- logger = NULL;
- if (error) { goto cleanup; }
-
- }
-
-cleanup:
-
- if (formatString) {
- error = PKIX_PL_Object_DecRef
- ((PKIX_PL_Object *)formatString, plContext);
- }
-
- if (messageString) {
- error = PKIX_PL_Object_DecRef
- ((PKIX_PL_Object *)messageString, plContext);
- }
-
- if (message2String) {
- error = PKIX_PL_Object_DecRef
- ((PKIX_PL_Object *)message2String, plContext);
- }
-
- if (msgString) {
- error = PKIX_PL_Object_DecRef
- ((PKIX_PL_Object *)msgString, plContext);
- }
-
- if (logger) {
- error = PKIX_PL_Object_DecRef
- ((PKIX_PL_Object *)logger, plContext);
- }
-
- if (pkixLoggersErrors == NULL && savedPkixLoggersErrors != NULL) {
- pkixLoggersErrors = savedPkixLoggersErrors;
- }
-
- if (pkixLoggersDebugTrace == NULL &&
- savedPkixLoggersDebugTrace != NULL) {
- pkixLoggersDebugTrace = savedPkixLoggersDebugTrace;
- }
-
- error = PKIX_PL_MonitorLock_Exit(pkixLoggerLock, plContext);
- if (error) { return(NULL); }
-
- return(NULL);
-}
-
-PKIX_Error *
-pkix_Logger_CheckWithCode(
- PKIX_List *pkixLoggersList,
- PKIX_UInt32 errorCode,
- const char *message2,
- PKIX_ERRORCLASS logComponent,
- PKIX_UInt32 currentLevel,
- void *plContext)
-{
- char error[32];
- char *errorString = NULL;
-
- PKIX_ENTER(LOGGER, "pkix_Logger_CheckWithCode");
-#if defined PKIX_ERROR_DESCRIPTION
- errorString = PKIX_ErrorText[errorCode];
-#else
- PR_snprintf(error, 32, "Error code: %d", errorCode);
- errorString = error;
-#endif /* PKIX_ERROR_DESCRIPTION */
-
- pkixErrorResult = pkix_Logger_Check(pkixLoggersList, errorString,
- message2, logComponent,
- currentLevel, plContext);
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: pkix_Logger_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_Logger_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_Logger *logger = NULL;
-
- PKIX_ENTER(LOGGER, "pkix_Logger_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a logger */
- PKIX_CHECK(pkix_CheckType(object, PKIX_LOGGER_TYPE, plContext),
- PKIX_OBJECTNOTLOGGER);
-
- logger = (PKIX_Logger *)object;
-
- /* We have a valid logger. DecRef its item and recurse on next */
-
- logger->callback = NULL;
- PKIX_DECREF(logger->context);
- logger->logComponent = (PKIX_ERRORCLASS)NULL;
-
-cleanup:
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: pkix_Logger_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_Logger_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_Logger *logger = NULL;
- char *asciiFormat = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *contextString = NULL;
- PKIX_PL_String *componentString = NULL;
- PKIX_PL_String *loggerString = NULL;
-
- PKIX_ENTER(LOGGER, "pkix_Logger_ToString_Helper");
- PKIX_NULLCHECK_TWO(object, pString);
-
- /* Check that this object is a logger */
- PKIX_CHECK(pkix_CheckType(object, PKIX_LOGGER_TYPE, plContext),
- PKIX_OBJECTNOTLOGGER);
-
- logger = (PKIX_Logger *)object;
-
- asciiFormat =
- "[\n"
- "\tLogger: \n"
- "\tContext: %s\n"
- "\tMaximum Level: %d\n"
- "\tComponent Name: %s\n"
- "]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_TOSTRING(logger->context, &contextString, plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- (void *)PKIX_ERRORCLASSNAMES[logger->logComponent],
- 0,
- &componentString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&loggerString,
- plContext,
- formatString,
- contextString,
- logger->maxLevel,
- componentString),
- PKIX_SPRINTFFAILED);
-
- *pString = loggerString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(contextString);
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: pkix_Logger_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_Logger_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
- PKIX_Logger *firstLogger = NULL;
- PKIX_Logger *secondLogger = NULL;
-
- PKIX_ENTER(LOGGER, "pkix_Logger_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- /* test that first is a Logger */
- PKIX_CHECK(pkix_CheckType(first, PKIX_LOGGER_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTLOGGER);
-
- /*
- * Since we know first is a Logger, if both references are
- * identical, they must be equal
- */
- if (first == second){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If second isn't a Logger, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_LOGGER_TYPE) goto cleanup;
-
- firstLogger = (PKIX_Logger *)first;
- secondLogger = (PKIX_Logger *)second;
-
- cmpResult = PKIX_FALSE;
-
- if (firstLogger->callback != secondLogger->callback) {
- goto cleanup;
- }
-
- if (firstLogger->logComponent != secondLogger->logComponent) {
- goto cleanup;
- }
-
- PKIX_EQUALS
- (firstLogger->context,
- secondLogger->context,
- &cmpResult,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (cmpResult == PKIX_FALSE) {
- goto cleanup;
- }
-
- if (firstLogger->maxLevel != secondLogger->maxLevel) {
- goto cleanup;
- }
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: pkix_Logger_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_Logger_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_Logger *logger = NULL;
- PKIX_UInt32 hash = 0;
- PKIX_UInt32 tempHash = 0;
-
- PKIX_ENTER(LOGGER, "pkix_Logger_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_LOGGER_TYPE, plContext),
- PKIX_OBJECTNOTLOGGER);
-
- logger = (PKIX_Logger *)object;
-
- PKIX_HASHCODE(logger->context, &tempHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- hash = (((((PKIX_UInt32) logger->callback + tempHash) << 7) +
- logger->maxLevel) << 7) + (PKIX_UInt32)logger->logComponent;
-
- *pHashcode = hash;
-
-cleanup:
-
- PKIX_RETURN(LOGGER);
-}
-
-
-/*
- * FUNCTION: pkix_Logger_Duplicate
- * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_Logger_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_Logger *logger = NULL;
- PKIX_Logger *dupLogger = NULL;
-
- PKIX_ENTER(LOGGER, "pkix_Logger_Duplicate");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)object, PKIX_LOGGER_TYPE, plContext),
- PKIX_OBJECTNOTLOGGER);
-
- logger = (PKIX_Logger *) object;
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_LOGGER_TYPE,
- sizeof (PKIX_Logger),
- (PKIX_PL_Object **)&dupLogger,
- plContext),
- PKIX_COULDNOTCREATELOGGEROBJECT);
-
- dupLogger->callback = logger->callback;
- dupLogger->maxLevel = logger->maxLevel;
-
- PKIX_DUPLICATE
- (logger->context,
- &dupLogger->context,
- plContext,
- PKIX_OBJECTDUPLICATEFAILED);
-
- dupLogger->logComponent = logger->logComponent;
-
- *pNewObject = (PKIX_PL_Object *) dupLogger;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(dupLogger);
- }
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: pkix_Logger_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_LOGGER_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_Logger_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(LOGGER, "pkix_Logger_RegisterSelf");
-
- entry.description = "Logger";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_Logger);
- entry.destructor = pkix_Logger_Destroy;
- entry.equalsFunction = pkix_Logger_Equals;
- entry.hashcodeFunction = pkix_Logger_Hashcode;
- entry.toStringFunction = pkix_Logger_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_Logger_Duplicate;
-
- systemClasses[PKIX_LOGGER_TYPE] = entry;
-
- PKIX_RETURN(LOGGER);
-}
-
-/* --Public-Logger-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_Logger_Create (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Logger_Create(
- PKIX_Logger_LogCallback callback,
- PKIX_PL_Object *loggerContext,
- PKIX_Logger **pLogger,
- void *plContext)
-{
- PKIX_Logger *logger = NULL;
-
- PKIX_ENTER(LOGGER, "PKIX_Logger_Create");
- PKIX_NULLCHECK_ONE(pLogger);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_LOGGER_TYPE,
- sizeof (PKIX_Logger),
- (PKIX_PL_Object **)&logger,
- plContext),
- PKIX_COULDNOTCREATELOGGEROBJECT);
-
- logger->callback = callback;
- logger->maxLevel = 0;
- logger->logComponent = (PKIX_ERRORCLASS)NULL;
-
- PKIX_INCREF(loggerContext);
- logger->context = loggerContext;
-
- *pLogger = logger;
- logger = NULL;
-
-cleanup:
-
- PKIX_DECREF(logger);
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: PKIX_Logger_GetLogCallback (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Logger_GetLogCallback(
- PKIX_Logger *logger,
- PKIX_Logger_LogCallback *pCallback,
- void *plContext)
-{
- PKIX_ENTER(LOGGER, "PKIX_Logger_GetLogCallback");
- PKIX_NULLCHECK_TWO(logger, pCallback);
-
- *pCallback = logger->callback;
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: PKIX_Logger_GetLoggerContext (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Logger_GetLoggerContext(
- PKIX_Logger *logger,
- PKIX_PL_Object **pLoggerContext,
- void *plContext)
-{
- PKIX_ENTER(LOGGER, "PKIX_Logger_GetLoggerContex");
- PKIX_NULLCHECK_TWO(logger, pLoggerContext);
-
- PKIX_INCREF(logger->context);
- *pLoggerContext = logger->context;
-
-cleanup:
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: PKIX_Logger_GetMaxLoggingLevel (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Logger_GetMaxLoggingLevel(
- PKIX_Logger *logger,
- PKIX_UInt32 *pLevel,
- void *plContext)
-{
- PKIX_ENTER(LOGGER, "PKIX_Logger_GetMaxLoggingLevel");
- PKIX_NULLCHECK_TWO(logger, pLevel);
-
- *pLevel = logger->maxLevel;
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: PKIX_Logger_SetMaxLoggingLevel (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Logger_SetMaxLoggingLevel(
- PKIX_Logger *logger,
- PKIX_UInt32 level,
- void *plContext)
-{
- PKIX_ENTER(LOGGER, "PKIX_Logger_SetMaxLoggingLevel");
- PKIX_NULLCHECK_ONE(logger);
-
- if (level > PKIX_LOGGER_LEVEL_MAX) {
- PKIX_ERROR(PKIX_LOGGINGLEVELEXCEEDSMAXIMUM);
- } else {
- logger->maxLevel = level;
- }
-
-cleanup:
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: PKIX_Logger_GetLoggingComponent (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Logger_GetLoggingComponent(
- PKIX_Logger *logger,
- PKIX_ERRORCLASS *pComponent,
- void *plContext)
-{
- PKIX_ENTER(LOGGER, "PKIX_Logger_GetLoggingComponent");
- PKIX_NULLCHECK_TWO(logger, pComponent);
-
- *pComponent = logger->logComponent;
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: PKIX_Logger_SetLoggingComponent (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_Logger_SetLoggingComponent(
- PKIX_Logger *logger,
- PKIX_ERRORCLASS component,
- void *plContext)
-{
- PKIX_ENTER(LOGGER, "PKIX_Logger_SetLoggingComponent");
- PKIX_NULLCHECK_ONE(logger);
-
- logger->logComponent = component;
-
- PKIX_RETURN(LOGGER);
-}
-
-
-/*
- * Following PKIX_GetLoggers(), PKIX_SetLoggers() and PKIX_AddLogger() are
- * documented as not thread-safe. However they are thread-safe now. We need
- * the lock when accessing the logger lists.
- */
-
-/*
- * FUNCTION: PKIX_Logger_GetLoggers (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_GetLoggers(
- PKIX_List **pLoggers, /* list of PKIX_Logger */
- void *plContext)
-{
- PKIX_List *list = NULL;
- PKIX_List *savedPkixLoggersDebugTrace = NULL;
- PKIX_List *savedPkixLoggersErrors = NULL;
- PKIX_Logger *logger = NULL;
- PKIX_Logger *dupLogger = NULL;
- PKIX_UInt32 i, length;
- PKIX_Boolean locked = PKIX_FALSE;
-
- PKIX_ENTER(LOGGER, "PKIX_Logger_GetLoggers");
- PKIX_NULLCHECK_ONE(pLoggers);
-
- PKIX_CHECK(PKIX_PL_MonitorLock_Enter(pkixLoggerLock, plContext),
- PKIX_MONITORLOCKENTERFAILED);
- locked = PKIX_TRUE;
-
- /*
- * Temporarily disable DEBUG/TRACE Logging to avoid possible
- * deadlock:
- * When the Logger List is being accessed, e.g. by PKIX_ENTER or
- * PKIX_DECREF, pkix_Logger_Check may check whether logging
- * is requested, creating a deadlock situation.
- */
- savedPkixLoggersDebugTrace = pkixLoggersDebugTrace;
- pkixLoggersDebugTrace = NULL;
- savedPkixLoggersErrors = pkixLoggersErrors;
- pkixLoggersErrors = NULL;
-
- if (pkixLoggers == NULL) {
- length = 0;
- } else {
- PKIX_CHECK(PKIX_List_GetLength
- (pkixLoggers, &length, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- /* Create a list and copy the pkixLoggers item to the list */
- PKIX_CHECK(PKIX_List_Create(&list, plContext),
- PKIX_LISTCREATEFAILED);
-
- for (i = 0; i < length; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (pkixLoggers,
- i,
- (PKIX_PL_Object **) &logger,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_Logger_Duplicate
- ((PKIX_PL_Object *)logger,
- (PKIX_PL_Object **)&dupLogger,
- plContext),
- PKIX_LOGGERDUPLICATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (list,
- (PKIX_PL_Object *) dupLogger,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(logger);
- PKIX_DECREF(dupLogger);
- }
-
- /* Set the list to be immutable */
- PKIX_CHECK(PKIX_List_SetImmutable(list, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- *pLoggers = list;
-
-cleanup:
-
- PKIX_DECREF(logger);
-
- /* Restore logging capability */
- pkixLoggersDebugTrace = savedPkixLoggersDebugTrace;
- pkixLoggersErrors = savedPkixLoggersErrors;
-
- if (locked) {
- PKIX_CHECK(PKIX_PL_MonitorLock_Exit(pkixLoggerLock, plContext),
- PKIX_MONITORLOCKEXITFAILED);
- }
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: PKIX_Logger_SetLoggers (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_SetLoggers(
- PKIX_List *loggers, /* list of PKIX_Logger */
- void *plContext)
-{
- PKIX_List *list = NULL;
- PKIX_List *savedPkixLoggersErrors = NULL;
- PKIX_List *savedPkixLoggersDebugTrace = NULL;
- PKIX_Logger *logger = NULL;
- PKIX_Logger *dupLogger = NULL;
- PKIX_Boolean locked = PKIX_FALSE;
- PKIX_UInt32 i, length;
-
- PKIX_ENTER(LOGGER, "PKIX_SetLoggers");
-
- PKIX_CHECK(PKIX_PL_MonitorLock_Enter(pkixLoggerLock, plContext),
- PKIX_MONITORLOCKENTERFAILED);
- locked = PKIX_TRUE;
-
- /* Disable tracing, etc. to avoid recursion and deadlock */
- savedPkixLoggersDebugTrace = pkixLoggersDebugTrace;
- pkixLoggersDebugTrace = NULL;
- savedPkixLoggersErrors = pkixLoggersErrors;
- pkixLoggersErrors = NULL;
-
- /* discard any prior loggers */
- PKIX_DECREF(pkixLoggers);
- PKIX_DECREF(savedPkixLoggersErrors);
- PKIX_DECREF(savedPkixLoggersDebugTrace);
-
- if (loggers != NULL) {
-
- PKIX_CHECK(PKIX_List_Create(&list, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(loggers, &length, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < length; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (loggers,
- i,
- (PKIX_PL_Object **) &logger,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_Logger_Duplicate
- ((PKIX_PL_Object *)logger,
- (PKIX_PL_Object **)&dupLogger,
- plContext),
- PKIX_LOGGERDUPLICATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (list,
- (PKIX_PL_Object *) dupLogger,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- /* Make two lists */
-
- /* Put in pkixLoggersErrors in any case*/
-
- if (savedPkixLoggersErrors == NULL) {
-
- PKIX_CHECK(PKIX_List_Create
- (&savedPkixLoggersErrors,
- plContext),
- PKIX_LISTCREATEFAILED);
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (savedPkixLoggersErrors,
- (PKIX_PL_Object *) dupLogger,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- if (logger->maxLevel > PKIX_LOGGER_LEVEL_WARNING) {
-
- /* Put in pkixLoggersDebugTrace */
-
- if (savedPkixLoggersDebugTrace == NULL) {
-
- PKIX_CHECK(PKIX_List_Create
- (&savedPkixLoggersDebugTrace,
- plContext),
- PKIX_LISTCREATEFAILED);
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (savedPkixLoggersDebugTrace,
- (PKIX_PL_Object *) dupLogger,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
- PKIX_DECREF(logger);
- PKIX_DECREF(dupLogger);
-
- }
-
- pkixLoggers = list;
- }
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(list);
- PKIX_DECREF(savedPkixLoggersErrors);
- PKIX_DECREF(savedPkixLoggersDebugTrace);
- pkixLoggers = NULL;
- }
-
- PKIX_DECREF(logger);
-
- /* Reenable logging capability with new lists */
- pkixLoggersErrors = savedPkixLoggersErrors;
- pkixLoggersDebugTrace = savedPkixLoggersDebugTrace;
-
- if (locked) {
- PKIX_CHECK(PKIX_PL_MonitorLock_Exit(pkixLoggerLock, plContext),
- PKIX_MONITORLOCKEXITFAILED);
- }
-
- PKIX_RETURN(LOGGER);
-}
-
-/*
- * FUNCTION: PKIX_Logger_AddLogger (see comments in pkix_util.h)
- */
-PKIX_Error *
-PKIX_AddLogger(
- PKIX_Logger *logger,
- void *plContext)
-{
- PKIX_Logger *dupLogger = NULL;
- PKIX_Logger *addLogger = NULL;
- PKIX_List *savedPkixLoggersErrors = NULL;
- PKIX_List *savedPkixLoggersDebugTrace = NULL;
- PKIX_Boolean locked = PKIX_FALSE;
- PKIX_UInt32 i, length;
-
- PKIX_ENTER(LOGGER, "PKIX_Logger_AddLogger");
- PKIX_NULLCHECK_ONE(logger);
-
- PKIX_CHECK(PKIX_PL_MonitorLock_Enter(pkixLoggerLock, plContext),
- PKIX_MONITORLOCKENTERFAILED);
- locked = PKIX_TRUE;
-
- savedPkixLoggersDebugTrace = pkixLoggersDebugTrace;
- pkixLoggersDebugTrace = NULL;
- savedPkixLoggersErrors = pkixLoggersErrors;
- pkixLoggersErrors = NULL;
-
- PKIX_DECREF(savedPkixLoggersErrors);
- PKIX_DECREF(savedPkixLoggersDebugTrace);
-
- if (pkixLoggers == NULL) {
-
- PKIX_CHECK(PKIX_List_Create(&pkixLoggers, plContext),
- PKIX_LISTCREATEFAILED);
- }
-
- PKIX_CHECK(pkix_Logger_Duplicate
- ((PKIX_PL_Object *)logger,
- (PKIX_PL_Object **)&dupLogger,
- plContext),
- PKIX_LOGGERDUPLICATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (pkixLoggers,
- (PKIX_PL_Object *) dupLogger,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(pkixLoggers, &length, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- /* Reconstruct pkixLoggersErrors and pkixLoggersDebugTrace */
- for (i = 0; i < length; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (pkixLoggers,
- i,
- (PKIX_PL_Object **) &addLogger,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
-
- /* Put in pkixLoggersErrors */
-
- if (savedPkixLoggersErrors == NULL) {
-
- PKIX_CHECK(PKIX_List_Create
- (&savedPkixLoggersErrors,
- plContext),
- PKIX_LISTCREATEFAILED);
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (savedPkixLoggersErrors,
- (PKIX_PL_Object *) addLogger,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- if (addLogger->maxLevel > PKIX_LOGGER_LEVEL_WARNING) {
-
- /* Put in pkixLoggersDebugTrace */
-
- if (savedPkixLoggersDebugTrace == NULL) {
-
- PKIX_CHECK(PKIX_List_Create
- (&savedPkixLoggersDebugTrace,
- plContext),
- PKIX_LISTCREATEFAILED);
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (savedPkixLoggersDebugTrace,
- (PKIX_PL_Object *) addLogger,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
-
- PKIX_DECREF(addLogger);
-
- }
-
-cleanup:
-
- PKIX_DECREF(dupLogger);
- PKIX_DECREF(addLogger);
-
- /* Restore logging capability */
- pkixLoggersErrors = savedPkixLoggersErrors;
- pkixLoggersDebugTrace = savedPkixLoggersDebugTrace;
-
- if (locked) {
- PKIX_CHECK(PKIX_PL_MonitorLock_Exit(pkixLoggerLock, plContext),
- PKIX_MONITORLOCKEXITFAILED);
- }
-
- PKIX_RETURN(LOGGER);
-}
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_logger.h b/security/nss/lib/libpkix/pkix/util/pkix_logger.h
deleted file mode 100644
index 9411aed2e..000000000
--- a/security/nss/lib/libpkix/pkix/util/pkix_logger.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_logger.h
- *
- * Logger Object Type Definition
- *
- */
-
-#ifndef _PKIX_LOGGER_H
-#define _PKIX_LOGGER_H
-
-#include "pkix_tools.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern PKIX_List *pkixLoggers;
-extern PKIX_List *pkixLoggersErrors;
-extern PKIX_List *pkixLoggersDebugTrace;
-
-struct PKIX_LoggerStruct {
- PKIX_Logger_LogCallback callback;
- PKIX_PL_Object *context;
- PKIX_UInt32 maxLevel;
- PKIX_ERRORCLASS logComponent;
-};
-
-PKIX_Error *
-pkix_Logger_Check(
- PKIX_List *pkixLoggersList,
- const char *message,
- const char *message2,
- PKIX_ERRORCLASS logComponent,
- PKIX_UInt32 maxLevel,
- void *plContext);
-
-PKIX_Error *
-pkix_Logger_CheckWithCode(
- PKIX_List *pkixLoggersList,
- PKIX_UInt32 errorCode,
- const char *message2,
- PKIX_ERRORCLASS logComponent,
- PKIX_UInt32 maxLevel,
- void *plContext);
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_Logger_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_LOGGER_H */
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_tools.c b/security/nss/lib/libpkix/pkix/util/pkix_tools.c
deleted file mode 100755
index 6348b8936..000000000
--- a/security/nss/lib/libpkix/pkix/util/pkix_tools.c
+++ /dev/null
@@ -1,1519 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_tools.c
- *
- * Private Utility Functions
- *
- */
-
-#include "pkix_tools.h"
-
-#define CACHE_ITEM_PERIOD_SECONDS (3600) /* one hour */
-
-/*
- * This cahce period is only for CertCache. A Cert from a trusted CertStore
- * should be checked more frequently for update new arrival, etc.
- */
-#define CACHE_TRUST_ITEM_PERIOD_SECONDS (CACHE_ITEM_PERIOD_SECONDS/10)
-
-extern PKIX_PL_HashTable *cachedCertChainTable;
-extern PKIX_PL_HashTable *cachedCertTable;
-extern PKIX_PL_HashTable *cachedCrlEntryTable;
-
-/* Following variables are used to checked cache hits - can be taken out */
-extern int pkix_ccAddCount;
-extern int pkix_ccLookupCount;
-extern int pkix_ccRemoveCount;
-extern int pkix_cAddCount;
-extern int pkix_cLookupCount;
-extern int pkix_cRemoveCount;
-extern int pkix_ceAddCount;
-extern int pkix_ceLookupCount;
-
-#ifdef PKIX_OBJECT_LEAK_TEST
-/* Following variables are used for object leak test */
-char *nonNullValue = "Non Empty Value";
-PKIX_Boolean noErrorState = PKIX_TRUE;
-PKIX_Boolean runningLeakTest;
-PKIX_Boolean errorGenerated;
-PKIX_UInt32 stackPosition;
-PKIX_UInt32 *fnStackInvCountArr;
-char **fnStackNameArr;
-PLHashTable *fnInvTable;
-PKIX_UInt32 testStartFnStackPosition;
-char *errorFnStackString;
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
-/* --Private-Functions-------------------------------------------- */
-
-#ifdef PKIX_OBJECT_LEAK_TEST
-/*
- * FUNCTION: pkix_ErrorGen_Hash
- * DESCRIPTION:
- *
- * Hash function to be used in object leak test hash table.
- *
- */
-PLHashNumber PR_CALLBACK
-pkix_ErrorGen_Hash (const void *key)
-{
- char *str = NULL;
- PLHashNumber rv = (*(PRUint8*)key) << 5;
- PRUint32 i, counter = 0;
- PRUint8 *rvc = (PRUint8 *)&rv;
-
- while ((str = fnStackNameArr[counter++]) != NULL) {
- PRUint32 len = strlen(str);
- for( i = 0; i < len; i++ ) {
- rvc[ i % sizeof(rv) ] ^= *str;
- str++;
- }
- }
-
- return rv;
-}
-
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
-/*
- * FUNCTION: pkix_IsCertSelfIssued
- * DESCRIPTION:
- *
- * Checks whether the Cert pointed to by "cert" is self-issued and stores the
- * Boolean result at "pSelfIssued". A Cert is considered self-issued if the
- * Cert's issuer matches the Cert's subject. If the subject or issuer is
- * not specified, a PKIX_FALSE is returned.
- *
- * PARAMETERS:
- * "cert"
- * Address of Cert used to determine whether Cert is self-issued.
- * Must be non-NULL.
- * "pSelfIssued"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_IsCertSelfIssued(
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pSelfIssued,
- void *plContext)
-{
- PKIX_PL_X500Name *subject = NULL;
- PKIX_PL_X500Name *issuer = NULL;
-
- PKIX_ENTER(CERT, "pkix_IsCertSelfIssued");
- PKIX_NULLCHECK_TWO(cert, pSelfIssued);
-
- PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &subject, plContext),
- PKIX_CERTGETSUBJECTFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetIssuer(cert, &issuer, plContext),
- PKIX_CERTGETISSUERFAILED);
-
- if (subject == NULL || issuer == NULL) {
- *pSelfIssued = PKIX_FALSE;
- } else {
-
- PKIX_CHECK(PKIX_PL_X500Name_Match
- (subject, issuer, pSelfIssued, plContext),
- PKIX_X500NAMEMATCHFAILED);
- }
-
-cleanup:
- PKIX_DECREF(subject);
- PKIX_DECREF(issuer);
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_Throw
- * DESCRIPTION:
- *
- * Creates an Error using the value of "errorCode", the character array
- * pointed to by "funcName", the character array pointed to by "errorText",
- * and the Error pointed to by "cause" (if any), and stores it at "pError".
- *
- * If "cause" is not NULL and has an errorCode of "PKIX_FATAL_ERROR",
- * then there is no point creating a new Error object. Rather, we simply
- * store "cause" at "pError".
- *
- * PARAMETERS:
- * "errorCode"
- * Value of error code.
- * "funcName"
- * Address of EscASCII array representing name of function throwing error.
- * Must be non-NULL.
- * "errnum"
- * PKIX_ERRMSGNUM of error description for new error.
- * "cause"
- * Address of Error representing error's cause.
- * "pError"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_Throw(
- PKIX_ERRORCLASS errorClass,
- const char *funcName,
- PKIX_ERRORCODE errorCode,
- PKIX_ERRORCLASS overrideClass,
- PKIX_Error *cause,
- PKIX_Error **pError,
- void *plContext)
-{
- PKIX_Error *error = NULL;
-
- PKIX_ENTER(ERROR, "pkix_Throw");
- PKIX_NULLCHECK_TWO(funcName, pError);
-
- *pError = NULL;
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- noErrorState = PKIX_TRUE;
- if (pkixLog) {
-#ifdef PKIX_ERROR_DESCRIPTION
- PR_LOG(pkixLog, 4, ("Error in function \"%s\":\"%s\" with cause \"%s\"\n",
- funcName, PKIX_ErrorText[errorCode],
- (cause ? PKIX_ErrorText[cause->errCode] : "null")));
-#else
- PR_LOG(pkixLog, 4, ("Error in function \"%s\": error code \"%d\"\n",
- funcName, errorCode));
-#endif /* PKIX_ERROR_DESCRIPTION */
- PORT_Assert(strcmp(funcName, "PKIX_PL_Object_DecRef"));
- }
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- /* if cause has error class of PKIX_FATAL_ERROR, return immediately */
- if (cause) {
- if (cause->errClass == PKIX_FATAL_ERROR){
- PKIX_INCREF(cause);
- *pError = cause;
- goto cleanup;
- }
- }
-
- if (overrideClass == PKIX_FATAL_ERROR){
- errorClass = overrideClass;
- }
-
- pkixTempResult = PKIX_Error_Create(errorClass, cause, NULL,
- errorCode, &error, plContext);
-
- if (!pkixTempResult) {
- /* Setting plErr error code:
- * get it from PORT_GetError if it is a leaf error and
- * default error code does not exist(eq 0) */
- if (!cause && !error->plErr) {
- error->plErr = PKIX_PL_GetPLErrorCode();
- }
- }
-
- *pError = error;
-
-cleanup:
-
- PKIX_DEBUG_EXIT(ERROR);
- pkixErrorClass = 0;
-#ifdef PKIX_OBJECT_LEAK_TEST
- noErrorState = PKIX_FALSE;
-
- if (runningLeakTest && fnStackNameArr) {
- PR_LOG(pkixLog, 5,
- ("%s%*s<- %s(%d) - %s\n", (errorGenerated ? "*" : " "),
- stackPosition, " ", fnStackNameArr[stackPosition],
- stackPosition, myFuncName));
- fnStackNameArr[stackPosition--] = NULL;
- }
-#endif /* PKIX_OBJECT_LEAK_TEST */
- return (pkixTempResult);
-}
-
-/*
- * FUNCTION: pkix_CheckTypes
- * DESCRIPTION:
- *
- * Checks that the types of the Object pointed to by "first" and the Object
- * pointed to by "second" are both equal to the value of "type". If they
- * are not equal, a PKIX_Error is returned.
- *
- * PARAMETERS:
- * "first"
- * Address of first Object. Must be non-NULL.
- * "second"
- * Address of second Object. Must be non-NULL.
- * "type"
- * Value of type to check against.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CheckTypes(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_UInt32 type,
- void *plContext)
-{
- PKIX_UInt32 firstType, secondType;
-
- PKIX_ENTER(OBJECT, "pkix_CheckTypes");
- PKIX_NULLCHECK_TWO(first, second);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(first, &firstType, plContext),
- PKIX_COULDNOTGETFIRSTOBJECTTYPE);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETSECONDOBJECTTYPE);
-
- if ((firstType != type)||(firstType != secondType)) {
- PKIX_ERROR(PKIX_OBJECTTYPESDONOTMATCH);
- }
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: pkix_CheckType
- * DESCRIPTION:
- *
- * Checks that the type of the Object pointed to by "object" is equal to the
- * value of "type". If it is not equal, a PKIX_Error is returned.
- *
- * PARAMETERS:
- * "object"
- * Address of Object. Must be non-NULL.
- * "type"
- * Value of type to check against.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CheckType(
- PKIX_PL_Object *object,
- PKIX_UInt32 type,
- void *plContext)
-{
- return (pkix_CheckTypes(object, object, type, plContext));
-}
-
-/*
- * FUNCTION: pkix_hash
- * DESCRIPTION:
- *
- * Computes a hash value for "length" bytes starting at the array of bytes
- * pointed to by "bytes" and stores the result at "pHash".
- *
- * XXX To speed this up, we could probably read 32 bits at a time from
- * bytes (maybe even 64 bits on some platforms)
- *
- * PARAMETERS:
- * "bytes"
- * Address of array of bytes to hash. Must be non-NULL.
- * "length"
- * Number of bytes to hash.
- * "pHash"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_hash(
- const unsigned char *bytes,
- PKIX_UInt32 length,
- PKIX_UInt32 *pHash,
- void *plContext)
-{
- PKIX_UInt32 i;
- PKIX_UInt32 hash;
-
- PKIX_ENTER(OBJECT, "pkix_hash");
- if (length != 0) {
- PKIX_NULLCHECK_ONE(bytes);
- }
- PKIX_NULLCHECK_ONE(pHash);
-
- hash = 0;
- for (i = 0; i < length; i++) {
- /* hash = 31 * hash + bytes[i]; */
- hash = (hash << 5) - hash + bytes[i];
- }
-
- *pHash = hash;
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: pkix_countArray
- * DESCRIPTION:
- *
- * Counts the number of elements in the null-terminated array of pointers
- * pointed to by "array" and returns the result.
- *
- * PARAMETERS
- * "array"
- * Address of null-terminated array of pointers.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns the number of elements in the array.
- */
-PKIX_UInt32
-pkix_countArray(void **array)
-{
- PKIX_UInt32 count = 0;
-
- if (array) {
- while (*array++) {
- count++;
- }
- }
- return (count);
-}
-
-/*
- * FUNCTION: pkix_duplicateImmutable
- * DESCRIPTION:
- *
- * Convenience callback function used for duplicating immutable objects.
- * Since the objects can not be modified, this function simply increments the
- * reference count on the object, and returns a reference to that object.
- *
- * (see comments for PKIX_PL_DuplicateCallback in pkix_pl_system.h)
- */
-PKIX_Error *
-pkix_duplicateImmutable(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_ENTER(OBJECT, "pkix_duplicateImmutable");
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_INCREF(object);
-
- *pNewObject = object;
-
-cleanup:
- PKIX_RETURN(OBJECT);
-}
-
-/* --String-Encoding-Conversion-Functions------------------------ */
-
-/*
- * FUNCTION: pkix_hex2i
- * DESCRIPTION:
- *
- * Converts hexadecimal character "c" to its integer value and returns result.
- *
- * PARAMETERS
- * "c"
- * Character to convert to a hex value.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * The hexadecimal value of "c". Otherwise -1. (Unsigned 0xFFFFFFFF).
- */
-PKIX_UInt32
-pkix_hex2i(char c)
-{
- if ((c >= '0')&&(c <= '9'))
- return (c-'0');
- else if ((c >= 'a')&&(c <= 'f'))
- return (c-'a'+10);
- else if ((c >= 'A')&&(c <= 'F'))
- return (c-'A'+10);
- else
- return ((PKIX_UInt32)(-1));
-}
-
-/*
- * FUNCTION: pkix_i2hex
- * DESCRIPTION:
- *
- * Converts integer value "digit" to its ASCII hex value
- *
- * PARAMETERS
- * "digit"
- * Value of integer to convert to ASCII hex value. Must be 0-15.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * The ASCII hexadecimal value of "digit".
- */
-char
-pkix_i2hex(char digit)
-{
- if ((digit >= 0)&&(digit <= 9))
- return (digit+'0');
- else if ((digit >= 0xa)&&(digit <= 0xf))
- return (digit - 10 + 'a');
- else
- return (-1);
-}
-
-/*
- * FUNCTION: pkix_isPlaintext
- * DESCRIPTION:
- *
- * Returns whether character "c" is plaintext using EscASCII or EscASCII_Debug
- * depending on the value of "debug".
- *
- * In EscASCII, [01, 7E] except '&' are plaintext.
- * In EscASCII_Debug [20, 7E] except '&' are plaintext.
- *
- * PARAMETERS:
- * "c"
- * Character to check.
- * "debug"
- * Value of debug flag.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * True if "c" is plaintext.
- */
-PKIX_Boolean
-pkix_isPlaintext(unsigned char c, PKIX_Boolean debug) {
- return ((c >= 0x01)&&(c <= 0x7E)&&(c != '&')&&(!debug || (c >= 20)));
-}
-
-/* --Cache-Functions------------------------ */
-
-/*
- * FUNCTION: pkix_CacheCertChain_Lookup
- * DESCRIPTION:
- *
- * Look up CertChain Hash Table for a cached BuildResult based on "targetCert"
- * and "anchors" as the hash keys. If there is no item to match the key,
- * PKIX_FALSE is stored at "pFound". If an item is found, its cache time is
- * compared to "testDate". If expired, the item is removed and PKIX_FALSE is
- * stored at "pFound". Otherwise, PKIX_TRUE is stored at "pFound" and the
- * BuildResult is stored at "pBuildResult".
- * The hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "targetCert"
- * Address of Target Cert as key to retrieve this CertChain. Must be
- * non-NULL.
- * "anchors"
- * Address of PKIX_List of "anchors" is used as key to retrive CertChain.
- * Must be non-NULL.
- * "testDate"
- * Address of PKIX_PL_Date for verifying time validity and cache validity.
- * May be NULL. If testDate is NULL, this cache item will not be out-dated.
- * "pFound"
- * Address of PKIX_Boolean indicating valid data is found.
- * Must be non-NULL.
- * "pBuildResult"
- * Address where BuildResult will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CacheCertChain_Lookup(
- PKIX_PL_Cert* targetCert,
- PKIX_List* anchors,
- PKIX_PL_Date *testDate,
- PKIX_Boolean *pFound,
- PKIX_BuildResult **pBuildResult,
- void *plContext)
-{
- PKIX_List *cachedValues = NULL;
- PKIX_List *cachedKeys = NULL;
- PKIX_Error *cachedCertChainError = NULL;
- PKIX_PL_Date *cacheValidUntilDate = NULL;
- PKIX_PL_Date *validityDate = NULL;
- PKIX_Int32 cmpValidTimeResult = 0;
- PKIX_Int32 cmpCacheTimeResult = 0;
-
- PKIX_ENTER(BUILD, "pkix_CacheCertChain_Lookup");
-
- PKIX_NULLCHECK_FOUR(targetCert, anchors, pFound, pBuildResult);
-
- *pFound = PKIX_FALSE;
-
- /* use trust anchors and target cert as hash key */
-
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)targetCert,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)anchors,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- cachedCertChainError = PKIX_PL_HashTable_Lookup
- (cachedCertChainTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object **) &cachedValues,
- plContext);
-
- pkix_ccLookupCount++;
-
- /* retrieve data from hashed value list */
-
- if (cachedValues != NULL && cachedCertChainError == NULL) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 0,
- (PKIX_PL_Object **) &cacheValidUntilDate,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- /* check validity time and cache age time */
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 1,
- (PKIX_PL_Object **) &validityDate,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- /* if testDate is not set, this cache item is not out-dated */
- if (testDate) {
-
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)testDate,
- (PKIX_PL_Object *)cacheValidUntilDate,
- &cmpCacheTimeResult,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)testDate,
- (PKIX_PL_Object *)validityDate,
- &cmpValidTimeResult,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
- }
-
- /* certs' date are all valid and cache item is not old */
- if (cmpValidTimeResult <= 0 && cmpCacheTimeResult <=0) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 2,
- (PKIX_PL_Object **) pBuildResult,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- *pFound = PKIX_TRUE;
-
- } else {
-
- pkix_ccRemoveCount++;
- *pFound = PKIX_FALSE;
-
- /* out-dated item, remove it from cache */
- PKIX_CHECK(PKIX_PL_HashTable_Remove
- (cachedCertChainTable,
- (PKIX_PL_Object *) cachedKeys,
- plContext),
- PKIX_HASHTABLEREMOVEFAILED);
- }
- }
-
-cleanup:
-
- PKIX_DECREF(cachedValues);
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedCertChainError);
- PKIX_DECREF(cacheValidUntilDate);
- PKIX_DECREF(validityDate);
-
- PKIX_RETURN(BUILD);
-
-}
-
-/*
- * FUNCTION: pkix_CacheCertChain_Remove
- * DESCRIPTION:
- *
- * Remove CertChain Hash Table entry based on "targetCert" and "anchors"
- * as the hash keys. If there is no item to match the key, no action is
- * taken.
- * The hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "targetCert"
- * Address of Target Cert as key to retrieve this CertChain. Must be
- * non-NULL.
- * "anchors"
- * Address of PKIX_List of "anchors" is used as key to retrive CertChain.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CacheCertChain_Remove(
- PKIX_PL_Cert* targetCert,
- PKIX_List* anchors,
- void *plContext)
-{
- PKIX_List *cachedKeys = NULL;
-
- PKIX_ENTER(BUILD, "pkix_CacheCertChain_Remove");
- PKIX_NULLCHECK_TWO(targetCert, anchors);
-
- /* use trust anchors and target cert as hash key */
-
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)targetCert,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)anchors,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK_ONLY_FATAL(PKIX_PL_HashTable_Remove
- (cachedCertChainTable,
- (PKIX_PL_Object *) cachedKeys,
- plContext),
- PKIX_HASHTABLEREMOVEFAILED);
-
- pkix_ccRemoveCount++;
-
-cleanup:
-
- PKIX_DECREF(cachedKeys);
-
- PKIX_RETURN(BUILD);
-
-}
-
-/*
- * FUNCTION: pkix_CacheCertChain_Add
- * DESCRIPTION:
- *
- * Add a BuildResult to the CertChain Hash Table for a "buildResult" with
- * "targetCert" and "anchors" as the hash keys.
- * "validityDate" is the most restricted notAfter date of all Certs in
- * this CertChain and is verified when this BuildChain is retrieved.
- * The hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "targetCert"
- * Address of Target Cert as key to retrieve this CertChain. Must be
- * non-NULL.
- * "anchors"
- * Address of PKIX_List of "anchors" is used as key to retrive CertChain.
- * Must be non-NULL.
- * "validityDate"
- * Address of PKIX_PL_Date contains the most restriced notAfter time of
- * all "certs". Must be non-NULL.
- * Address of PKIX_Boolean indicating valid data is found.
- * Must be non-NULL.
- * "buildResult"
- * Address of BuildResult to be cached. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CacheCertChain_Add(
- PKIX_PL_Cert* targetCert,
- PKIX_List* anchors,
- PKIX_PL_Date *validityDate,
- PKIX_BuildResult *buildResult,
- void *plContext)
-{
- PKIX_List *cachedValues = NULL;
- PKIX_List *cachedKeys = NULL;
- PKIX_Error *cachedCertChainError = NULL;
- PKIX_PL_Date *cacheValidUntilDate = NULL;
-
- PKIX_ENTER(BUILD, "pkix_CacheCertChain_Add");
-
- PKIX_NULLCHECK_FOUR(targetCert, anchors, validityDate, buildResult);
-
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)targetCert, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)anchors, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_Create(&cachedValues, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds
- (CACHE_ITEM_PERIOD_SECONDS,
- &cacheValidUntilDate,
- plContext),
- PKIX_DATECREATECURRENTOFFBYSECONDSFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues,
- (PKIX_PL_Object *)cacheValidUntilDate,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues, (PKIX_PL_Object *)validityDate, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues, (PKIX_PL_Object *)buildResult, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- cachedCertChainError = PKIX_PL_HashTable_Add
- (cachedCertChainTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object *) cachedValues,
- plContext);
-
- pkix_ccAddCount++;
-
- if (cachedCertChainError != NULL) {
- PKIX_DEBUG("PKIX_PL_HashTable_Add for CertChain skipped: "
- "entry existed\n");
- }
-
-cleanup:
-
- PKIX_DECREF(cachedValues);
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedCertChainError);
- PKIX_DECREF(cacheValidUntilDate);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_CacheCert_Lookup
- * DESCRIPTION:
- *
- * Look up Cert Hash Table for a cached item based on "store" and Subject in
- * "certSelParams" as the hash keys and returns values Certs in "pCerts".
- * If there isn't an item to match the key, a PKIX_FALSE is returned at
- * "pFound". The item's cache time is verified with "testDate". If out-dated,
- * this item is removed and PKIX_FALSE is returned at "pFound".
- * This hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * If the CertStore this Cert is from is a trusted one, the cache period is
- * shorter so cache can be updated more frequently.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore as key to retrieve this CertChain. Must be
- * non-NULL.
- * "certSelParams"
- * Address of ComCertSelParams that its subject is used as key to retrieve
- * this CertChain. Must be non-NULL.
- * "testDate"
- * Address of PKIX_PL_Date for verifying time cache validity.
- * Must be non-NULL. If testDate is NULL, this cache item won't be out
- * dated.
- * "pFound"
- * Address of KPKIX_Boolean indicating valid data is found.
- * Must be non-NULL.
- * "pCerts"
- * Address PKIX_List where the CertChain will be stored. Must be no-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CacheCert_Lookup(
- PKIX_CertStore *store,
- PKIX_ComCertSelParams *certSelParams,
- PKIX_PL_Date *testDate,
- PKIX_Boolean *pFound,
- PKIX_List** pCerts,
- void *plContext)
-{
- PKIX_PL_Cert *cert = NULL;
- PKIX_List *cachedKeys = NULL;
- PKIX_List *cachedValues = NULL;
- PKIX_List *cachedCertList = NULL;
- PKIX_List *selCertList = NULL;
- PKIX_PL_X500Name *subject = NULL;
- PKIX_PL_Date *invalidAfterDate = NULL;
- PKIX_PL_Date *cacheValidUntilDate = NULL;
- PKIX_CertSelector *certSel = NULL;
- PKIX_Error *cachedCertError = NULL;
- PKIX_Error *selectorError = NULL;
- PKIX_CertSelector_MatchCallback selectorMatch = NULL;
- PKIX_Int32 cmpValidTimeResult = PKIX_FALSE;
- PKIX_Int32 cmpCacheTimeResult = 0;
- PKIX_UInt32 numItems = 0;
- PKIX_UInt32 i;
-
- PKIX_ENTER(BUILD, "pkix_CacheCert_Lookup");
- PKIX_NULLCHECK_TWO(store, certSelParams);
- PKIX_NULLCHECK_TWO(pFound, pCerts);
-
- *pFound = PKIX_FALSE;
-
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)store, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
- (certSelParams, &subject, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
-
- PKIX_NULLCHECK_ONE(subject);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)subject, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- cachedCertError = PKIX_PL_HashTable_Lookup
- (cachedCertTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object **) &cachedValues,
- plContext);
- pkix_cLookupCount++;
-
- if (cachedValues != NULL && cachedCertError == NULL) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 0,
- (PKIX_PL_Object **) &cacheValidUntilDate,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- if (testDate) {
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)testDate,
- (PKIX_PL_Object *)cacheValidUntilDate,
- &cmpCacheTimeResult,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
- }
-
- if (cmpCacheTimeResult <= 0) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (cachedValues,
- 1,
- (PKIX_PL_Object **) &cachedCertList,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- /*
- * Certs put on cache satifies only for Subject,
- * user selector and ComCertSelParams to filter.
- */
- PKIX_CHECK(PKIX_CertSelector_Create
- (NULL, NULL, &certSel, plContext),
- PKIX_CERTSELECTORCREATEFAILED);
-
- PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams
- (certSel, certSelParams, plContext),
- PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
-
- PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
- (certSel, &selectorMatch, plContext),
- PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
-
- PKIX_CHECK(PKIX_List_Create(&selCertList, plContext),
- PKIX_LISTCREATEFAILED);
-
- /*
- * If any of the Cert on the list is out-dated, invalidate
- * this cache item.
- */
- PKIX_CHECK(PKIX_List_GetLength
- (cachedCertList, &numItems, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numItems; i++){
-
- PKIX_CHECK(PKIX_List_GetItem
- (cachedCertList,
- i,
- (PKIX_PL_Object **)&cert,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetValidityNotAfter
- (cert, &invalidAfterDate, plContext),
- PKIX_CERTGETVALIDITYNOTAFTERFAILED);
-
- if (testDate) {
- PKIX_CHECK(PKIX_PL_Object_Compare
- ((PKIX_PL_Object *)invalidAfterDate,
- (PKIX_PL_Object *)testDate,
- &cmpValidTimeResult,
- plContext),
- PKIX_OBJECTCOMPARATORFAILED);
- }
-
- if (cmpValidTimeResult < 0) {
-
- pkix_cRemoveCount++;
- *pFound = PKIX_FALSE;
-
- /* one cert is out-dated, remove item from cache */
- PKIX_CHECK(PKIX_PL_HashTable_Remove
- (cachedCertTable,
- (PKIX_PL_Object *) cachedKeys,
- plContext),
- PKIX_HASHTABLEREMOVEFAILED);
- goto cleanup;
- }
-
- selectorError = selectorMatch(certSel, cert, plContext);
- if (!selectorError){
- /* put on the return list */
- PKIX_CHECK(PKIX_List_AppendItem
- (selCertList,
- (PKIX_PL_Object *)cert,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- } else {
- PKIX_DECREF(selectorError);
- }
-
- PKIX_DECREF(cert);
- PKIX_DECREF(invalidAfterDate);
-
- }
-
- if (*pFound) {
- PKIX_INCREF(selCertList);
- *pCerts = selCertList;
- }
-
- } else {
-
- pkix_cRemoveCount++;
- *pFound = PKIX_FALSE;
- /* cache item is out-dated, remove it from cache */
- PKIX_CHECK(PKIX_PL_HashTable_Remove
- (cachedCertTable,
- (PKIX_PL_Object *) cachedKeys,
- plContext),
- PKIX_HASHTABLEREMOVEFAILED);
- }
-
- }
-
-cleanup:
-
- PKIX_DECREF(subject);
- PKIX_DECREF(certSel);
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedValues);
- PKIX_DECREF(cacheValidUntilDate);
- PKIX_DECREF(cert);
- PKIX_DECREF(cachedCertList);
- PKIX_DECREF(selCertList);
- PKIX_DECREF(invalidAfterDate);
- PKIX_DECREF(cachedCertError);
- PKIX_DECREF(selectorError);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_CacheCert_Add
- * DESCRIPTION:
- *
- * Add Cert Hash Table for a cached item based on "store" and Subject in
- * "certSelParams" as the hash keys and have "certs" as the key value.
- * This hashtable is maintained in the following ways:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- * 2) A PKIX_PL_Date created with current time offset by constant
- * CACHE_ITEM_PERIOD_SECONDS is attached to each item in the Hash Table.
- * If the CertStore this Cert is from is a trusted one, the cache period is
- * shorter so cache can be updated more frequently.
- * When an item is retrieved, this date is compared against "testDate" for
- * validity. If comparison indicates this item is expired, the item is
- * removed from the bucket.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore as key to retrieve this CertChain. Must be
- * non-NULL.
- * "certSelParams"
- * Address of ComCertSelParams that its subject is used as key to retrieve
- * this CertChain. Must be non-NULL.
- * "certs"
- * Address PKIX_List of Certs will be stored. Must be no-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CacheCert_Add(
- PKIX_CertStore *store,
- PKIX_ComCertSelParams *certSelParams,
- PKIX_List* certs,
- void *plContext)
-{
- PKIX_List *cachedKeys = NULL;
- PKIX_List *cachedValues = NULL;
- PKIX_PL_Date *cacheValidUntilDate = NULL;
- PKIX_PL_X500Name *subject = NULL;
- PKIX_Error *cachedCertError = NULL;
- PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
- PKIX_UInt32 cachePeriod = CACHE_ITEM_PERIOD_SECONDS;
- PKIX_UInt32 numCerts = 0;
-
- PKIX_ENTER(BUILD, "pkix_CacheCert_Add");
- PKIX_NULLCHECK_THREE(store, certSelParams, certs);
-
- PKIX_CHECK(PKIX_List_GetLength(certs, &numCerts,
- plContext),
- PKIX_LISTGETLENGTHFAILED);
- if (numCerts == 0) {
- /* Don't want to add an empty list. */
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)store, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
- (certSelParams, &subject, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
-
- PKIX_NULLCHECK_ONE(subject);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)subject, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_Create(&cachedValues, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_CertStore_GetTrustCallback
- (store, &trustCallback, plContext),
- PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
-
- if (trustCallback) {
- cachePeriod = CACHE_TRUST_ITEM_PERIOD_SECONDS;
- }
-
- PKIX_CHECK(PKIX_PL_Date_Create_CurrentOffBySeconds
- (cachePeriod, &cacheValidUntilDate, plContext),
- PKIX_DATECREATECURRENTOFFBYSECONDSFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues,
- (PKIX_PL_Object *)cacheValidUntilDate,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedValues,
- (PKIX_PL_Object *)certs,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- cachedCertError = PKIX_PL_HashTable_Add
- (cachedCertTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object *) cachedValues,
- plContext);
-
- pkix_cAddCount++;
-
- if (cachedCertError != NULL) {
- PKIX_DEBUG("PKIX_PL_HashTable_Add for Certs skipped: "
- "entry existed\n");
- }
-
-cleanup:
-
- PKIX_DECREF(subject);
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedValues);
- PKIX_DECREF(cacheValidUntilDate);
- PKIX_DECREF(cachedCertError);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_CacheCrlEntry_Lookup
- * DESCRIPTION:
- *
- * Look up CrlEntry Hash Table for a cached item based on "store",
- * "certIssuer" and "certSerialNumber" as the hash keys and returns values
- * "pCrls". If there isn't an item to match the key, a PKIX_FALSE is
- * returned at "pFound".
- * This hashtable is maintained in the following way:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore as key to retrieve this CertChain. Must be
- * non-NULL.
- * "certIssuer"
- * Address of X500Name that is used as key to retrieve the CRLEntries.
- * Must be non-NULL.
- * "certSerialNumber"
- * Address of BigInt that is used as key to retrieve the CRLEntries.
- * Must be non-NULL.
- * "pFound"
- * Address of KPKIX_Boolean indicating valid data is found.
- * Must be non-NULL.
- * "pCrls"
- * Address PKIX_List where the CRLEntry will be stored. Must be no-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CacheCrlEntry_Lookup(
- PKIX_CertStore *store,
- PKIX_PL_X500Name *certIssuer,
- PKIX_PL_BigInt *certSerialNumber,
- PKIX_Boolean *pFound,
- PKIX_List** pCrls,
- void *plContext)
-{
- PKIX_List *cachedKeys = NULL;
- PKIX_List *cachedCrlEntryList = NULL;
- PKIX_Error *cachedCrlEntryError = NULL;
-
- PKIX_ENTER(BUILD, "pkix_CacheCrlEntry_Lookup");
- PKIX_NULLCHECK_THREE(store, certIssuer, certSerialNumber);
- PKIX_NULLCHECK_TWO(pFound, pCrls);
-
- *pFound = PKIX_FALSE;
-
- /* Find CrlEntry(s) by issuer and serial number */
-
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)store, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)certIssuer, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)certSerialNumber,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- cachedCrlEntryError = PKIX_PL_HashTable_Lookup
- (cachedCrlEntryTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object **) &cachedCrlEntryList,
- plContext);
- pkix_ceLookupCount++;
-
- /*
- * We don't need check Date to invalidate this cache item,
- * the item is uniquely defined and won't be reverted. Let
- * the FIFO for cleaning up.
- */
-
- if (cachedCrlEntryList != NULL && cachedCrlEntryError == NULL ) {
-
- PKIX_INCREF(cachedCrlEntryList);
- *pCrls = cachedCrlEntryList;
-
- *pFound = PKIX_TRUE;
-
- } else {
-
- *pFound = PKIX_FALSE;
- }
-
-cleanup:
-
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedCrlEntryList);
- PKIX_DECREF(cachedCrlEntryError);
-
- PKIX_RETURN(BUILD);
-}
-
-/*
- * FUNCTION: pkix_CacheCrlEntry_Add
- * DESCRIPTION:
- *
- * Look up CrlEntry Hash Table for a cached item based on "store",
- * "certIssuer" and "certSerialNumber" as the hash keys and have "pCrls" as
- * the hash value. If there isn't an item to match the key, a PKIX_FALSE is
- * returned at "pFound".
- * This hashtable is maintained in the following way:
- * 1) When creating the hashtable, maximum bucket size can be specified (0 for
- * unlimited). If items in a bucket reaches its full size, an new addition
- * will trigger the removal of the old as FIFO sequence.
- *
- * PARAMETERS:
- * "store"
- * Address of CertStore as key to retrieve this CertChain. Must be
- * non-NULL.
- * "certIssuer"
- * Address of X500Name that is used as key to retrieve the CRLEntries.
- * Must be non-NULL.
- * "certSerialNumber"
- * Address of BigInt that is used as key to retrieve the CRLEntries.
- * Must be non-NULL.
- * "crls"
- * Address PKIX_List where the CRLEntry is stored. Must be no-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Error Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_CacheCrlEntry_Add(
- PKIX_CertStore *store,
- PKIX_PL_X500Name *certIssuer,
- PKIX_PL_BigInt *certSerialNumber,
- PKIX_List* crls,
- void *plContext)
-{
- PKIX_List *cachedKeys = NULL;
- PKIX_Error *cachedCrlEntryError = NULL;
-
- PKIX_ENTER(BUILD, "pkix_CacheCrlEntry_Add");
- PKIX_NULLCHECK_THREE(store, certIssuer, certSerialNumber);
- PKIX_NULLCHECK_ONE(crls);
-
- /* Add CrlEntry(s) by issuer and serial number */
-
- PKIX_CHECK(PKIX_List_Create(&cachedKeys, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)store, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys, (PKIX_PL_Object *)certIssuer, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (cachedKeys,
- (PKIX_PL_Object *)certSerialNumber,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- cachedCrlEntryError = PKIX_PL_HashTable_Add
- (cachedCrlEntryTable,
- (PKIX_PL_Object *) cachedKeys,
- (PKIX_PL_Object *) crls,
- plContext);
- pkix_ceAddCount++;
-
-cleanup:
-
- PKIX_DECREF(cachedKeys);
- PKIX_DECREF(cachedCrlEntryError);
-
- PKIX_RETURN(BUILD);
-}
-
-#ifdef PKIX_OBJECT_LEAK_TEST
-
-/* TEST_START_FN and testStartFnStackPosition define at what state
- * of the stack the object leak testing should begin. The condition
- * in pkix_CheckForGeneratedError works the following way: do leak
- * testing if at position testStartFnStackPosition in stack array
- * (fnStackNameArr) we have called function TEST_START_FN.
- * Note, that stack array get filled only when executing libpkix
- * functions.
- * */
-#define TEST_START_FN "PKIX_BuildChain"
-
-PKIX_Error*
-pkix_CheckForGeneratedError(PKIX_StdVars * stdVars,
- PKIX_ERRORCLASS errClass,
- char * fnName,
- PKIX_Boolean *errSetFlag,
- void * plContext)
-{
- PKIX_Error *genErr = NULL;
- PKIX_UInt32 pos = 0;
- PKIX_UInt32 strLen = 0;
-
- if (fnName) {
- if (fnStackNameArr[testStartFnStackPosition] == NULL ||
- strcmp(fnStackNameArr[testStartFnStackPosition], TEST_START_FN)
- ) {
- /* return with out error if not with in boundary */
- return NULL;
- }
- if (!strcmp(fnName, TEST_START_FN)) {
- *errSetFlag = PKIX_TRUE;
- noErrorState = PKIX_FALSE;
- errorGenerated = PKIX_FALSE;
- }
- }
-
- if (noErrorState || errorGenerated) return NULL;
-
- if (fnName && (
- !strcmp(fnName, "PKIX_PL_Object_DecRef") ||
- !strcmp(fnName, "PKIX_PL_Object_Unlock") ||
- !strcmp(fnName, "pkix_UnlockObject") ||
- !strcmp(fnName, "pkix_Throw") ||
- !strcmp(fnName, "pkix_trace_dump_cert") ||
- !strcmp(fnName, "PKIX_PL_Free"))) {
- /* do not generate error for this functions */
- noErrorState = PKIX_TRUE;
- *errSetFlag = PKIX_TRUE;
- return NULL;
- }
-
- if (PL_HashTableLookup(fnInvTable, &fnStackInvCountArr[stackPosition - 1])) {
- return NULL;
- }
-
- PL_HashTableAdd(fnInvTable, &fnStackInvCountArr[stackPosition - 1], nonNullValue);
- errorGenerated = PKIX_TRUE;
- noErrorState = PKIX_TRUE;
- genErr = PKIX_DoThrow(stdVars, errClass, PKIX_MEMLEAKGENERATEDERROR,
- errClass, plContext);
- while(fnStackNameArr[pos]) {
- strLen += PORT_Strlen(fnStackNameArr[pos++]) + 1;
- }
- strLen += 1; /* end of line. */
- pos = 0;
- errorFnStackString = PORT_ZAlloc(strLen);
- while(fnStackNameArr[pos]) {
- strcat(errorFnStackString, "/");
- strcat(errorFnStackString, fnStackNameArr[pos++]);
- }
- noErrorState = PKIX_FALSE;
-
- return genErr;
-}
-#endif /* PKIX_OBJECT_LEAK_TEST */
diff --git a/security/nss/lib/libpkix/pkix/util/pkix_tools.h b/security/nss/lib/libpkix/pkix/util/pkix_tools.h
deleted file mode 100755
index fe6ce6346..000000000
--- a/security/nss/lib/libpkix/pkix/util/pkix_tools.h
+++ /dev/null
@@ -1,1588 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_tools.h
- *
- * Header for Utility Functions and Macros
- *
- */
-
-#ifndef _PKIX_TOOLS_H
-#define _PKIX_TOOLS_H
-
-#include "pkix.h"
-#include <stddef.h>
-#include <stdio.h>
-#include "secport.h"
-#include "prlong.h"
-
-/* private PKIX system headers */
-#include "pkix_basicconstraintschecker.h"
-#include "pkix_buildresult.h"
-#include "pkix_certchainchecker.h"
-#include "pkix_certselector.h"
-#include "pkix_comcertselparams.h"
-#include "pkix_comcrlselparams.h"
-#include "pkix_crlselector.h"
-#include "pkix_error.h"
-#include "pkix_expirationchecker.h"
-#include "pkix_list.h"
-#include "pkix_logger.h"
-#include "pkix_namechainingchecker.h"
-#include "pkix_nameconstraintschecker.h"
-#include "pkix_policychecker.h"
-#include "pkix_policynode.h"
-#include "pkix_procparams.h"
-#include "pkix_resourcelimits.h"
-#include "pkix_revocationmethod.h"
-#include "pkix_revocationchecker.h"
-#include "pkix_crlchecker.h"
-#include "pkix_ocspchecker.h"
-#include "pkix_signaturechecker.h"
-#include "pkix_store.h"
-#include "pkix_targetcertchecker.h"
-#include "pkix_validate.h"
-#include "pkix_valresult.h"
-#include "pkix_verifynode.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct pkixStdVarsStr {
- const char *aMyFuncName;
- PKIX_Error *aPkixErrorResult;
- PKIX_Error *aPkixTempResult;
- PKIX_Error *aPkixReturnResult;
- PKIX_ERRORCODE aPkixErrorCode;
- PKIX_Boolean aPkixErrorReceived;
- PKIX_Boolean aPkixTempErrorReceived;
- PKIX_ERRORCLASS aPkixErrorClass;
- PKIX_UInt32 aPkixType;
- PKIX_PL_Object *aLockedObject;
- PKIX_List *aPkixErrorList;
-} PKIX_StdVars;
-
-#ifdef PKIX_STDVARS_POINTER
-#define myFuncName stdVars->aMyFuncName
-#define pkixErrorResult stdVars->aPkixErrorResult
-#define pkixTempResult stdVars->aPkixTempResult
-#define pkixReturnResult stdVars->aPkixReturnResult
-#define pkixErrorCode stdVars->aPkixErrorCode
-#define pkixErrorReceived stdVars->aPkixErrorReceived
-#define pkixTempErrorReceived stdVars->aPkixTempErrorReceived
-#define pkixErrorClass stdVars->aPkixErrorClass
-#define pkixType stdVars->aPkixType
-#define lockedObject stdVars->aLockedObject
-#define pkixErrorList stdVars->aPkixErrorList
-#define stdVarsPtr stdVars
-#else
-#define myFuncName stdVars.aMyFuncName
-#define pkixErrorResult stdVars.aPkixErrorResult
-#define pkixTempResult stdVars.aPkixTempResult
-#define pkixReturnResult stdVars.aPkixReturnResult
-#define pkixErrorCode stdVars.aPkixErrorCode
-#define pkixErrorReceived stdVars.aPkixErrorReceived
-#define pkixTempErrorReceived stdVars.aPkixTempErrorReceived
-#define pkixErrorClass stdVars.aPkixErrorClass
-#define pkixType stdVars.aPkixType
-#define lockedObject stdVars.aLockedObject
-#define pkixErrorList stdVars.aPkixErrorList
-#define stdVarsPtr &stdVars
-#endif
-
-extern PKIX_Error * PKIX_DoReturn(PKIX_StdVars * stdVars,
- PKIX_ERRORCLASS errClass,
- PKIX_Boolean doLogger,
- void * plContext);
-
-extern PKIX_Error * PKIX_DoThrow(PKIX_StdVars * stdVars,
- PKIX_ERRORCLASS errClass,
- PKIX_ERRORCODE errCode,
- PKIX_ERRORCLASS overrideClass,
- void * plContext);
-
-extern void PKIX_DoAddError(PKIX_StdVars * stdVars,
- PKIX_Error * error,
- void * plContext);
-
-#ifdef PKIX_OBJECT_LEAK_TEST
-extern PKIX_Error * pkix_CheckForGeneratedError(PKIX_StdVars * stdVars,
- PKIX_ERRORCLASS errClass,
- char * fnName,
- PKIX_Boolean *errorStateSet,
- void * plContext);
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
-extern const PKIX_StdVars zeroStdVars;
-
-extern PRLogModuleInfo *pkixLog;
-
-/*
- * UTILITY MACROS
- * Documentation for these common utility macros can be found in the
- * Implementation Guidelines document (Section 4.3)
- *
- * In general, macros with multiple statements (or a single "if" statement)
- * use the "do {<body>} while (0)" technique in order to convert the multiple
- * statements into one statement, thus avoiding the dangling else problem.
- * For macros which ALWAYS exit with a "return" or "goto", there is no
- * need to use this technique (and it yields compiler warnings of "statement
- * not reached"), so we just use "{<body>}" to group the statements together.
- */
-
-#if !defined (PKIX_OBJECT_LEAK_TEST)
-
-#define PKIX_STD_VARS(funcName) \
- static const char cMyFuncName[] = {funcName}; \
- PKIX_StdVars stdVars = zeroStdVars; \
- myFuncName = cMyFuncName
-
-
-#else /* PKIX_OBJECT_LEAK_TEST */
-
-extern char **fnStackNameArr;
-extern PKIX_UInt32 *fnStackInvCountArr;
-extern PKIX_UInt32 stackPosition;
-extern PKIX_Boolean noErrorState;
-extern PKIX_Boolean errorGenerated;
-extern PKIX_Boolean runningLeakTest;
-extern PLHashTable *fnInvTable;
-extern PKIX_UInt32 testStartFnStackPosition;
-extern char *errorFnStackString;
-
-extern PLHashNumber PR_CALLBACK pkix_ErrorGen_Hash (const void *key);
-
-#define PKIX_STD_VARS(funcName) \
- static const char cMyFuncName[] = {funcName}; \
- PKIX_StdVars stdVars = zeroStdVars; \
- PKIX_Boolean errorSetFlag = PKIX_FALSE; \
- myFuncName = cMyFuncName; \
- if (runningLeakTest) { \
- if (fnStackNameArr) { \
- fnStackInvCountArr[stackPosition] += 1; \
- stackPosition += 1; \
- fnStackInvCountArr[stackPosition] = 0; \
- fnStackNameArr[stackPosition] = (char*)myFuncName; \
- fnStackNameArr[stackPosition + 1] = NULL; \
- PR_LOG(pkixLog, 5, \
- ("%s%*s+> %s(%d) - %s\n", (errorGenerated ? "*" : " "), \
- stackPosition, " ", fnStackNameArr[stackPosition], \
- stackPosition, myFuncName)); \
- } \
- do { \
- pkixErrorResult = pkix_CheckForGeneratedError(&stdVars, PKIX_MEM_ERROR, \
- funcName, &errorSetFlag, \
- plContext); \
- if (pkixErrorResult) { \
- PR_LOG(pkixLog, 5, \
- ("%s%*s<- %s(%d) - %s\n", (errorGenerated ? "*" : " "), \
- stackPosition, " ", fnStackNameArr[stackPosition], \
- stackPosition, myFuncName)); \
- fnStackNameArr[stackPosition--] = NULL; \
- if (errorSetFlag) { \
- noErrorState = (noErrorState) ? PKIX_FALSE : PKIX_TRUE; \
- } \
- return pkixErrorResult; \
- } \
- } while (0); \
- }
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
-#ifdef DEBUG
-#define _PKIX_DEBUG_TRACE(cond, prefix, level) \
- do { \
- if (cond) { \
- pkix_Logger_Check(pkixLoggersDebugTrace, myFuncName, \
- prefix, pkixType, level, plContext); \
- } \
- } while (0)
-#else
-#define _PKIX_DEBUG_TRACE(cond, prefix, level)
-#endif
-
-#define _PKIX_LOG_ERROR(code, level) \
- { \
- if (pkixLoggersErrors) { \
- pkix_Logger_CheckWithCode(pkixLoggersErrors, code, \
- NULL, pkixType, level, plContext); \
- } \
- }
-
-#define PKIX_ENTER(type, funcName) \
- PKIX_STD_VARS(funcName); \
- pkixType = PKIX_ ## type ## _ERROR; \
- PKIX_DEBUG_ENTER(type); \
- _PKIX_DEBUG_TRACE(pkixLoggersDebugTrace, ">>>", PKIX_LOGGER_LEVEL_TRACE);
-
-#define PKIX_ENTER_NO_LOGGER(type, funcName) \
- PKIX_STD_VARS(funcName); \
- pkixType = PKIX_ ## type ## _ERROR; \
- PKIX_DEBUG_ENTER(type);
-
-#define PKIX_DEBUG_ENTER(type) \
- PKIX_ ## type ## _DEBUG_ARG("( Entering %s).\n", myFuncName)
-
-#define PKIX_DEBUG_EXIT(type) \
- PKIX_ ## type ## _DEBUG_ARG("( Exiting %s).\n", myFuncName)
-
-#define PKIX_OBJECT_UNLOCK(obj) \
- do { \
- if (obj && lockedObject == (PKIX_PL_Object *)(obj)){ \
- pkixTempResult = \
- PKIX_PL_Object_Unlock \
- ((PKIX_PL_Object *)(obj), plContext); \
- if (pkixTempResult) { \
- PKIX_DoAddError(stdVarsPtr, pkixTempResult, plContext); \
- pkixTempResult = NULL; \
- } \
- lockedObject = NULL; \
- } else { \
- PORT_Assert(lockedObject == NULL); \
- } \
- } while (0)
-
-#define PKIX_DECREF(obj) \
- do { \
- if (obj){ \
- pkixTempResult = PKIX_PL_Object_DecRef \
- ((PKIX_PL_Object *)(obj), plContext); \
- if (pkixTempResult) { \
- PKIX_DoAddError(stdVarsPtr, pkixTempResult, plContext); \
- pkixTempResult = NULL; \
- } \
- obj = NULL; \
- } \
- } while (0)
-
-#define PKIX_THROW(type, descNum) \
- return PKIX_DoThrow(&stdVars, (PKIX_ ## type ## _ERROR), descNum, \
- pkixErrorClass, plContext);
-
-#ifdef PKIX_OBJECT_LEAK_TEST
-#define PKIX_RETURN(type) \
- if (runningLeakTest && fnStackNameArr) { \
- PR_LOG(pkixLog, 5, \
- ("%s%*s<- %s(%d) - %s\n", (errorGenerated ? "*" : " "), \
- stackPosition, " ", fnStackNameArr[stackPosition], \
- stackPosition, myFuncName)); \
- fnStackNameArr[stackPosition--] = NULL; \
- if (errorSetFlag) noErrorState = (noErrorState) ? PKIX_FALSE : PKIX_TRUE; \
- } \
- return PKIX_DoReturn(&stdVars, (PKIX_ ## type ## _ERROR), PKIX_TRUE, plContext);
-#else
-#define PKIX_RETURN(type) \
- return PKIX_DoReturn(&stdVars, (PKIX_ ## type ## _ERROR), PKIX_TRUE, plContext);
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
-
-#if defined(DEBUG) && !defined(DEBUG_nb95248)
-#define PKIX_RETURN_NO_LOGGER(type) \
- { \
- PKIX_OBJECT_UNLOCK(lockedObject); \
- if ((pkixErrorReceived) || (pkixErrorResult) || pkixErrorList) \
- PKIX_THROW(type, pkixErrorCode); \
- PKIX_DEBUG_EXIT(type); \
- return NULL; \
- }
-#else
-#define PKIX_RETURN_NO_LOGGER(type) \
- return PKIX_DoReturn(&stdVars, (PKIX_ ## type ## _ERROR), PKIX_FALSE, plContext);
-#endif
-
-/* disable to disable ;-) */
-/* #define WANT_TRACE_CHECK_FAILURES */
-
-#ifdef WANT_TRACE_CHECK_FAILURES
-#define TRACE_CHECK_FAILURE(what, errorstring) \
- if (pkixLog) { \
- PR_LOG(pkixLog, PR_LOG_DEBUG, \
- ("====> [%s] failed: %s\n", #what, errorstring)); \
- }
-#else
-#define TRACE_CHECK_FAILURE(what, errorstring)
-#endif
-
-#define PKIX_CHECK(func, descNum) \
- do { \
- pkixErrorResult = (func); \
- if (pkixErrorResult) { \
- TRACE_CHECK_FAILURE((func), PKIX_ErrorText[descNum]) \
- pkixErrorClass = pkixErrorResult->errClass; \
- pkixErrorCode = descNum; \
- goto cleanup; \
- } \
- } while (0)
-
-/* like PKIX_CHECK but without goto cleanup */
-#define PKIX_CHECK_NO_GOTO(func, descNum) \
- do { \
- pkixErrorResult = (func); \
- if (pkixErrorResult) { \
- TRACE_CHECK_FAILURE((func), PKIX_ErrorText[descNum]) \
- pkixErrorClass = pkixErrorResult->errClass; \
- pkixErrorCode = descNum; \
- } \
- } while (0)
-
-#define PKIX_CHECK_ONLY_FATAL(func, descNum) \
- do { \
- pkixTempErrorReceived = PKIX_FALSE; \
- pkixErrorResult = (func); \
- if (pkixErrorResult) { \
- TRACE_CHECK_FAILURE((func), PKIX_ErrorText[descNum]) \
- pkixTempErrorReceived = PKIX_TRUE; \
- pkixErrorClass = pkixErrorResult->errClass; \
- if (pkixErrorClass == PKIX_FATAL_ERROR) { \
- goto cleanup; \
- } \
- PKIX_DECREF(pkixErrorResult); \
- } \
- } while (0)
-
-#define PKIX_LOG_ERROR(descNum) \
- _PKIX_LOG_ERROR(descNum, PKIX_LOGGER_LEVEL_ERROR)
-
-#define PKIX_ERROR(descNum) \
- { \
- PKIX_LOG_ERROR(descNum) \
- pkixErrorReceived = PKIX_TRUE; \
- pkixErrorCode = descNum; \
- goto cleanup; \
- }
-
-#define PKIX_ERROR_ALLOC_ERROR() \
- { \
- PKIX_LOG_ERROR(PKIX_ALLOCERROR) \
- pkixErrorReceived = PKIX_TRUE; \
- pkixErrorResult = PKIX_ALLOC_ERROR(); \
- goto cleanup; \
- }
-
-#define PKIX_ERROR_FATAL(descNum) \
- { \
- pkixErrorReceived = PKIX_TRUE; \
- pkixErrorCode = descNum; \
- pkixErrorClass = PKIX_FATAL_ERROR; \
- _PKIX_LOG_ERROR(pkixErrorCode, PKIX_LOGGER_LEVEL_FATALERROR); \
- goto cleanup; \
- }
-
-#define PKIX_CHECK_FATAL(func, descNum) \
- do { \
- pkixErrorResult = (func); \
- if (pkixErrorResult) { \
- TRACE_CHECK_FAILURE((func), PKIX_ErrorText[descNum]) \
- pkixErrorReceived = PKIX_TRUE; \
- pkixErrorCode = descNum; \
- pkixErrorClass = PKIX_FATAL_ERROR; \
- _PKIX_LOG_ERROR(pkixErrorCode, PKIX_LOGGER_LEVEL_FATALERROR); \
- goto fatal; \
- } \
- } while (0)
-
-#define PKIX_NULLCHECK_ONE(a) \
- do { \
- if ((a) == NULL){ \
- pkixErrorReceived = PKIX_TRUE; \
- pkixErrorCode = PKIX_NULLARGUMENT; \
- PKIX_RETURN(FATAL); \
- } \
- } while (0)
-
-#define PKIX_NULLCHECK_TWO(a, b) \
- do { \
- if (((a) == NULL) || ((b) == NULL)){ \
- pkixErrorReceived = PKIX_TRUE; \
- pkixErrorCode = PKIX_NULLARGUMENT; \
- PKIX_RETURN(FATAL); \
- } \
- } while (0)
-
-#define PKIX_NULLCHECK_THREE(a, b, c) \
- do { \
- if (((a) == NULL) || ((b) == NULL) || ((c) == NULL)){ \
- pkixErrorReceived = PKIX_TRUE; \
- pkixErrorCode = PKIX_NULLARGUMENT; \
- PKIX_RETURN(FATAL); \
- } \
- } while (0)
-
-#define PKIX_NULLCHECK_FOUR(a, b, c, d) \
- do { \
- if (((a) == NULL) || ((b) == NULL) || \
- ((c) == NULL) || ((d) == NULL)){ \
- pkixErrorReceived = PKIX_TRUE; \
- pkixErrorCode = PKIX_NULLARGUMENT; \
- PKIX_RETURN(FATAL); \
- } \
- } while (0)
-
-#define PKIX_OBJECT_LOCK(obj) \
- do { \
- if (obj) { \
- pkixTempResult = \
- PKIX_PL_Object_Lock((PKIX_PL_Object*)(obj), plContext); \
- if (pkixTempResult) { \
- PKIX_DoAddError(stdVarsPtr, pkixTempResult, plContext); \
- pkixTempResult = NULL; \
- pkixErrorCode = PKIX_OBJECTLOCKFAILED; \
- goto cleanup; \
- } \
- lockedObject = (PKIX_PL_Object *)(obj); \
- } \
- } while (0)
-
-#define PKIX_ERROR_CREATE(type, descNum, error) \
- { \
- pkixTempResult = (PKIX_Error*)pkix_Throw \
- (PKIX_ ## type ## _ERROR, myFuncName, \
- descNum, PKIX_ ## type ## _ERROR, pkixErrorResult, \
- &error, plContext); \
- if (pkixTempResult) { \
- error = pkixTempResult; \
- pkixTempResult = NULL; \
- } \
- }
-
-
-#define PKIX_ERROR_RECEIVED \
- (pkixErrorReceived || pkixErrorResult || pkixTempErrorReceived || \
- pkixErrorList)
-
-#define PKIX_INCREF(obj) \
- do { \
- if (obj){ \
- pkixTempResult = PKIX_PL_Object_IncRef \
- ((PKIX_PL_Object *)(obj), plContext); \
- if (pkixTempResult) { \
- PKIX_DoAddError(&stdVars, pkixTempResult, plContext); \
- pkixTempResult = NULL; \
- goto cleanup; \
- } \
- } \
- } while (0)
-
-#define PKIX_FREE(obj) \
- do { \
- if (obj) { \
- pkixTempResult = PKIX_PL_Free((obj), plContext); \
- if (pkixTempResult) { \
- PKIX_DoAddError(&stdVars, pkixTempResult, plContext); \
- pkixTempResult = NULL; \
- } \
- obj = NULL; \
- } \
- } while (0)
-
-#define PKIX_EXACTLY_ONE_NULL(a, b) (((a) && !(b)) || ((b) && !(a)))
-
-/* DIGIT MACROS */
-
-#define PKIX_ISDIGIT(c) (((c) >= '0') && ((c) <= '9'))
-
-#define PKIX_ISXDIGIT(c) \
- (PKIX_ISDIGIT(c) || ( (((c)|0x20) >= 'a') && (((c)|0x20) <= 'f') ))
-
-#define PKIX_TOSTRING(a, b, c, d) \
- do { \
- int descNum; \
- if ((a) != NULL) { \
- pkixErrorResult = \
- PKIX_PL_Object_ToString((PKIX_PL_Object *)(a), (b), (c)); \
- descNum = (d); \
- } else { \
- pkixErrorResult = \
- PKIX_PL_String_Create(PKIX_ESCASCII, "(null)", 0, (b), (c)); \
- descNum = PKIX_STRINGCREATEFAILED; \
- } \
- PKIX_CHECK(pkixErrorResult, descNum); \
- } while (0)
-
-#define PKIX_EQUALS(a, b, c, d, e) \
- do { \
- if ((a) != NULL && (b) != NULL) { \
- PKIX_CHECK(PKIX_PL_Object_Equals\
- ((PKIX_PL_Object *)(a), \
- (PKIX_PL_Object*)(b), \
- (c), \
- (d)), \
- (e)); \
- } else if ((a) == NULL && (b) == NULL) { \
- *(c) = PKIX_TRUE; \
- } else { \
- *(c) = PKIX_FALSE; \
- } \
- } while (0)
-
-#define PKIX_HASHCODE(a, b, c, d) \
- do { \
- if ((a) != NULL) { \
- PKIX_CHECK(PKIX_PL_Object_Hashcode\
- ((PKIX_PL_Object *)(a), (b), (c)), (d)); \
- } else { \
- *(b) = 0; \
- } \
- } while (0)
-
-#define PKIX_DUPLICATE(a, b, c, d) \
- do { \
- if ((a) != NULL) { \
- PKIX_CHECK(PKIX_PL_Object_Duplicate\
- ((PKIX_PL_Object *)(a), \
- (PKIX_PL_Object **)(b), \
- (c)), \
- (d)); \
- } else { \
- *(b) = (a); \
- } \
- } while (0)
-
-/*
- * DEBUG MACROS
- *
- * Each type has an associated debug flag, which can
- * be set on the compiler line using "-D<debugflag>". For convenience,
- * "-DPKIX_DEBUGALL" turns on debug for all the components.
- *
- * If a type's debug flag is defined, then its two associated macros
- * are defined: PKIX_type_DEBUG(expr) and PKIX_type_DEBUG_ARG(expr, arg),
- * which call PKIX_DEBUG(expr) and PKIX_DEBUG_ARG(expr, arg) respectively,
- * which, in turn, enable standard and consistently formatted output.
- *
- * If a type's debug flag is not defined, the two associated macros
- * are defined as a NO-OP. As such, any PKIX_type_DEBUG or PKIX_type_DEBUG_ARG
- * macros for an undefined type will be stripped from the code during
- * pre-processing, thereby reducing code size.
- */
-
-#ifdef PKIX_DEBUGALL
-#define PKIX_REFCOUNTDEBUG 1
-#define PKIX_MEMDEBUG 1
-#define PKIX_MUTEXDEBUG 1
-#define PKIX_OBJECTDEBUG 1
-#define PKIX_STRINGDEBUG 1
-#define PKIX_OIDDEBUG 1
-#define PKIX_LISTDEBUG 1
-#define PKIX_ERRORDEBUG 1
-#define PKIX_BYTEARRAYDEBUG 1
-#define PKIX_RWLOCKDEBUG 1
-#define PKIX_BIGINTDEBUG 1
-#define PKIX_HASHTABLEDEBUG 1
-#define PKIX_X500NAMEDEBUG 1
-#define PKIX_GENERALNAMEDEBUG 1
-#define PKIX_PUBLICKEYDEBUG 1
-#define PKIX_CERTDEBUG 1
-#define PKIX_HTTPCLIENTDEBUG 1
-#define PKIX_DATEDEBUG 1
-#define PKIX_TRUSTANCHORDEBUG 1
-#define PKIX_PROCESSINGPARAMSDEBUG 1
-#define PKIX_VALIDATEPARAMSDEBUG 1
-#define PKIX_VALIDATERESULTDEBUG 1
-#define PKIX_VALIDATEDEBUG 1
-#define PKIX_CERTCHAINCHECKERDEBUG 1
-#define PKIX_REVOCATIONCHECKERDEBUG 1
-#define PKIX_CERTSELECTORDEBUG 1
-#define PKIX_COMCERTSELPARAMSDEBUG 1
-#define PKIX_TARGETCERTCHECKERSTATEDEBUG 1
-#define PKIX_INITIALIZEPARAMSDEBUG 1
-#define PKIX_CERTBASICCONSTRAINTSDEBUG 1
-#define PKIX_CERTNAMECONSTRAINTSDEBUG 1
-#define PKIX_CERTNAMECONSTRAINTSCHECKERSTATEDEBUG 1
-#define PKIX_SUBJALTNAMECHECKERSTATEDEBUG 1
-
-#define PKIX_CERTPOLICYQUALIFIERDEBUG 1
-#define PKIX_CERTPOLICYINFODEBUG 1
-#define PKIX_CERTPOLICYNODEDEBUG 1
-#define PKIX_CERTPOLICYCHECKERSTATEDEBUG 1
-#define PKIX_LIFECYCLEDEBUG 1
-#define PKIX_BASICCONSTRAINTSCHECKERSTATEDEBUG 1
-#define PKIX_CRLDEBUG 1
-#define PKIX_CRLENTRYDEBUG 1
-#define PKIX_CRLSELECTORDEBUG 1
-#define PKIX_COMCRLSELPARAMSDEBUG 1
-#define PKIX_CERTSTOREDEBUG 1
-#define PKIX_COLLECTIONCERTSTORECONTEXTDEBUG 1
-#define PKIX_DEFAULTCRLCHECKERSTATEDEBUG 1
-#define PKIX_CERTPOLICYMAPDEBUG 1
-#define PKIX_BUILDDEBUG 1
-#define PKIX_BUILDRESULTDEBUG 1
-#define PKIX_FORWARDBUILDERSTATEDEBUG 1
-#define PKIX_SIGNATURECHECKERSTATEDEBUG 1
-#define PKIX_USERDEFINEDMODULESDEBUG 1
-#define PKIX_CONTEXTDEBUG 1
-#define PKIX_DEFAULTREVOCATIONCHECKERDEBUG 1
-#define PKIX_LDAPREQUESTDEBUG 1
-#define PKIX_LDAPRESPONSEDEBUG 1
-#define PKIX_LDAPCLIENTDEBUG 1
-#define PKIX_LDAPDEFAULTCLIENTDEBUG 1
-#define PKIX_SOCKETDEBUG 1
-#define PKIX_RESOURCELIMITSDEBUG 1
-#define PKIX_LOGGERDEBUG 1
-#define PKIX_MONITORLOCKDEBUG 1
-#define PKIX_INFOACCESSDEBUG 1
-#define PKIX_AIAMGRDEBUG 1
-#define PKIX_OCSPCHECKERDEBUG 1
-#define PKIX_OCSPREQUESTDEBUG 1
-#define PKIX_OCSPRESPONSEDEBUG 1
-#define PKIX_HTTPDEFAULTCLIENTDEBUG 1
-#define PKIX_HTTPCERTSTORECONTEXTDEBUG 1
-#define PKIX_VERIFYNODEDEBUG 1
-#endif
-
-/*
- * XXX Both PKIX_DEBUG and PKIX_DEBUG_ARG currently use printf.
- * This needs to be replaced with Loggers.
- */
-
-#ifdef DEBUG
-#define PKIX_DEBUG(expr) \
- do { \
- _PKIX_DEBUG_TRACE(pkixLoggersErrors, expr, PKIX_LOGGER_LEVEL_DEBUG); \
- (void) fprintf(stderr, "(%s: ", myFuncName); \
- (void) fprintf(stderr, expr); \
- } while (0)
-#else
-#define PKIX_DEBUG(expr)
-#endif
-
-/* Logging doesn't support DEBUG with ARG: cannot convert control and arg */
-#define PKIX_DEBUG_ARG(expr, arg) \
- do { \
- (void) printf("(%s: ", myFuncName); \
- (void) printf(expr, arg); \
- } while (0)
-
-#if PKIX_FATALDEBUG
-#define PKIX_FATAL_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_FATAL_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_FATAL_DEBUG(expr)
-#define PKIX_FATAL_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_REFCOUNTDEBUG
-#define PKIX_REF_COUNT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_REF_COUNT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_REF_COUNT_DEBUG(expr)
-#define PKIX_REF_COUNT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_MEMDEBUG
-#define PKIX_MEM_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_MEM_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_MEM_DEBUG(expr)
-#define PKIX_MEM_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_MUTEXDEBUG
-#define PKIX_MUTEX_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_MUTEX_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_MUTEX_DEBUG(expr)
-#define PKIX_MUTEX_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_OBJECTDEBUG
-#define PKIX_OBJECT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_OBJECT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_OBJECT_DEBUG(expr)
-#define PKIX_OBJECT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_ERRORDEBUG
-#define PKIX_ERROR_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_ERROR_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_ERROR_DEBUG(expr)
-#define PKIX_ERROR_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_STRINGDEBUG
-#define PKIX_STRING_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_STRING_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_STRING_DEBUG(expr)
-#define PKIX_STRING_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_OIDDEBUG
-#define PKIX_OID_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_OID_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_OID_DEBUG(expr)
-#define PKIX_OID_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_LISTDEBUG
-#define PKIX_LIST_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_LIST_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_LIST_DEBUG(expr)
-#define PKIX_LIST_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_RWLOCKDEBUG
-#define PKIX_RWLOCK_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_RWLOCK_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_RWLOCK_DEBUG(expr)
-#define PKIX_RWLOCK_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_BYTEARRAYDEBUG
-#define PKIX_BYTEARRAY_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_BYTEARRAY_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_BYTEARRAY_DEBUG(expr)
-#define PKIX_BYTEARRAY_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_HASHTABLEDEBUG
-#define PKIX_HASHTABLE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_HASHTABLE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_HASHTABLE_DEBUG(expr)
-#define PKIX_HASHTABLE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_X500NAMEDEBUG
-#define PKIX_X500NAME_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_X500NAME_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_X500NAME_DEBUG(expr)
-#define PKIX_X500NAME_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_GENERALNAMEDEBUG
-#define PKIX_GENERALNAME_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_GENERALNAME_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_GENERALNAME_DEBUG(expr)
-#define PKIX_GENERALNAME_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_PUBLICKEYDEBUG
-#define PKIX_PUBLICKEY_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_PUBLICKEY_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_PUBLICKEY_DEBUG(expr)
-#define PKIX_PUBLICKEY_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTDEBUG
-#define PKIX_CERT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERT_DEBUG(expr)
-#define PKIX_CERT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CRLDPDEBUG
-#define PKIX_CRLDP_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CRLDP_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CRLDP_DEBUG(expr)
-#define PKIX_CRLDP_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_HTTPCLIENTDEBUG
-#define PKIX_HTTPCLIENT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_HTTPCLIENT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_HTTPCLIENT_DEBUG(expr)
-#define PKIX_HTTPCLIENT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_BIGINTDEBUG
-#define PKIX_BIGINT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_BIGINT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_BIGINT_DEBUG(expr)
-#define PKIX_BIGINT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_DATEDEBUG
-#define PKIX_DATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_DATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_DATE_DEBUG(expr)
-#define PKIX_DATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_TRUSTANCHORDEBUG
-#define PKIX_TRUSTANCHOR_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_TRUSTANCHOR_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_TRUSTANCHOR_DEBUG(expr)
-#define PKIX_TRUSTANCHOR_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_PROCESSINGPARAMSDEBUG
-#define PKIX_PROCESSINGPARAMS_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_PROCESSINGPARAMS_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_PROCESSINGPARAMS_DEBUG(expr)
-#define PKIX_PROCESSINGPARAMS_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_VALIDATEPARAMSDEBUG
-#define PKIX_VALIDATEPARAMS_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_VALIDATEPARAMS_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_VALIDATEPARAMS_DEBUG(expr)
-#define PKIX_VALIDATEPARAMS_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_VALIDATERESULTDEBUG
-#define PKIX_VALIDATERESULT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_VALIDATERESULT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_VALIDATERESULT_DEBUG(expr)
-#define PKIX_VALIDATERESULT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_VALIDATEDEBUG
-#define PKIX_VALIDATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_VALIDATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_VALIDATE_DEBUG(expr)
-#define PKIX_VALIDATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_BUILDDEBUG
-#define PKIX_BUILD_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_BUILD_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_BUILD_DEBUG(expr)
-#define PKIX_BUILD_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTCHAINCHECKERDEBUG
-#define PKIX_CERTCHAINCHECKER_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTCHAINCHECKER_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTCHAINCHECKER_DEBUG(expr)
-#define PKIX_CERTCHAINCHECKER_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_REVOCATIONCHECKERDEBUG
-#define PKIX_REVOCATIONCHECKER_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_REVOCATIONCHECKER_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_REVOCATIONCHECKER_DEBUG(expr)
-#define PKIX_REVOCATIONCHECKER_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_REVOCATIONMETHODDEBUG
-#define PKIX_REVOCATIONMETHOD_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_REVOCATIONMETHOD_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_REVOCATIONMETHOD_DEBUG(expr)
-#define PKIX_REVOCATIONMETHOD_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTSELECTORDEBUG
-#define PKIX_CERTSELECTOR_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTSELECTOR_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTSELECTOR_DEBUG(expr)
-#define PKIX_CERTSELECTOR_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_COMCERTSELPARAMSDEBUG
-#define PKIX_COMCERTSELPARAMS_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_COMCERTSELPARAMS_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_COMCERTSELPARAMS_DEBUG(expr)
-#define PKIX_COMCERTSELPARAMS_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_TARGETCERTCHECKERSTATEDEBUG
-#define PKIX_TARGETCERTCHECKERSTATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_TARGETCERTCHECKERSTATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_TARGETCERTCHECKERSTATE_DEBUG(expr)
-#define PKIX_TARGETCERTCHECKERSTATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_BASICCONSTRAINTSCHECKERSTATEDEBUG
-#define PKIX_BASICCONSTRAINTSCHECKERSTATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_BASICCONSTRAINTSCHECKERSTATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_BASICCONSTRAINTSCHECKERSTATE_DEBUG(expr)
-#define PKIX_BASICCONSTRAINTSCHECKERSTATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_INITIALIZEPARAMSDEBUG
-#define PKIX_INITIALIZEPARAMS_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_INITIALIZEPARAMS_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_INITIALIZEPARAMS_DEBUG(expr)
-#define PKIX_INITIALIZEPARAMS_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTBASICCONSTRAINTSDEBUG
-#define PKIX_CERTBASICCONSTRAINTS_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTBASICCONSTRAINTS_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTBASICCONSTRAINTS_DEBUG(expr)
-#define PKIX_CERTBASICCONSTRAINTS_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTNAMECONSTRAINTSDEBUG
-#define PKIX_CERTNAMECONSTRAINTS_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTNAMECONSTRAINTS_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTNAMECONSTRAINTS_DEBUG(expr)
-#define PKIX_CERTNAMECONSTRAINTS_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTNAMECONSTRAINTSCHECKERSTATEDEBUG
-#define PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_DEBUG(expr)
-#define PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_SUBJALTNAMECHECKERSTATEDEBUG
-#define PKIX_SUBJALTNAMECHECKERSTATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_SUBJALTNAMECHECKERSTATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_SUBJALTNAMECHECKERSTATE_DEBUG(expr)
-#define PKIX_SUBJALTNAMECHECKERSTATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTPOLICYQUALIFIERDEBUG
-#define PKIX_CERTPOLICYQUALIFIER_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTPOLICYQUALIFIER_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTPOLICYQUALIFIER_DEBUG(expr)
-#define PKIX_CERTPOLICYQUALIFIER_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTPOLICYINFODEBUG
-#define PKIX_CERTPOLICYINFO_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTPOLICYINFO_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTPOLICYINFO_DEBUG(expr)
-#define PKIX_CERTPOLICYINFO_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTPOLICYNODEDEBUG
-#define PKIX_CERTPOLICYNODE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTPOLICYNODE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTPOLICYNODE_DEBUG(expr)
-#define PKIX_CERTPOLICYNODE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTPOLICYCHECKERSTATEDEBUG
-#define PKIX_CERTPOLICYCHECKERSTATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTPOLICYCHECKERSTATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTPOLICYCHECKERSTATE_DEBUG(expr)
-#define PKIX_CERTPOLICYCHECKERSTATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_LIFECYCLEDEBUG
-#define PKIX_LIFECYCLE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_LIFECYCLE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_LIFECYCLE_DEBUG(expr)
-#define PKIX_LIFECYCLE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_BASICCONSTRAINTSCHECKERSTATEDEBUG
-#define PKIX_BASICCONSTRAINTSCHECKERSTATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_BASICCONSTRAINTSCHECKERSTATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_BASICCONSTRAINTSCHECKERSTATE_DEBUG(expr)
-#define PKIX_BASICCONSTRAINTSCHECKERSTATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CRLDEBUG
-#define PKIX_CRL_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CRL_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CRL_DEBUG(expr)
-#define PKIX_CRL_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CRLENTRYDEBUG
-#define PKIX_CRLENTRY_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CRLENTRY_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CRLENTRY_DEBUG(expr)
-#define PKIX_CRLENTRY_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CRLSELECTORDEBUG
-#define PKIX_CRLSELECTOR_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CRLSELECTOR_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CRLSELECTOR_DEBUG(expr)
-#define PKIX_CRLSELECTOR_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_COMCRLSELPARAMSDEBUG
-#define PKIX_COMCRLSELPARAMS_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_COMCRLSELPARAMS_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_COMCRLSELPARAMS_DEBUG(expr)
-#define PKIX_COMCRLSELPARAMS_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTSTOREDEBUG
-#define PKIX_CERTSTORE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTSTORE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTSTORE_DEBUG(expr)
-#define PKIX_CERTSTORE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_COLLECTIONCERTSTORECONTEXTDEBUG
-#define PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG(expr)
-#define PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CRLCHECKERDEBUG
-#define PKIX_CRLCHECKER_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CRLCHECKER_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CRLCHECKER_DEBUG(expr)
-#define PKIX_CRLCHECKER_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTPOLICYMAPDEBUG
-#define PKIX_CERTPOLICYMAP_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTPOLICYMAP_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTPOLICYMAP_DEBUG(expr)
-#define PKIX_CERTPOLICYMAP_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_BUILDRESULTDEBUG
-#define PKIX_BUILDRESULT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_BUILDRESULT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_BUILDRESULT_DEBUG(expr)
-#define PKIX_BUILDRESULT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_FORWARDBUILDERSTATEDEBUG
-#define PKIX_FORWARDBUILDERSTATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_FORWARDBUILDERSTATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_FORWARDBUILDERSTATE_DEBUG(expr)
-#define PKIX_FORWARDBUILDERSTATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_SIGNATURECHECKERSTATEDEBUG
-#define PKIX_SIGNATURECHECKERSTATE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_SIGNATURECHECKERSTATE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_SIGNATURECHECKERSTATE_DEBUG(expr)
-#define PKIX_SIGNATURECHECKERSTATE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_USERDEFINEDMODULESDEBUG
-#define PKIX_USERDEFINEDMODULES_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_USERDEFINEDMODULES_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_USERDEFINEDMODULES_DEBUG(expr)
-#define PKIX_USERDEFINEDMODULES_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CONTEXTDEBUG
-#define PKIX_CONTEXT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CONTEXT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CONTEXT_DEBUG(expr)
-#define PKIX_CONTEXT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_REVOCATIONCHECKERDEBUG
-#define PKIX_REVOCATIONCHECKER_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_REVOCATIONCHECKER_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_REVOCATIONCHECKER_DEBUG(expr)
-#define PKIX_REVOCATIONCHECKER_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_LDAPREQUESTDEBUG
-#define PKIX_LDAPREQUEST_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_LDAPREQUEST_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_LDAPREQUEST_DEBUG(expr)
-#define PKIX_LDAPREQUEST_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_LDAPRESPONSEDEBUG
-#define PKIX_LDAPRESPONSE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_LDAPRESPONSE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_LDAPRESPONSE_DEBUG(expr)
-#define PKIX_LDAPRESPONSE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_LDAPCLIENTDEBUG
-#define PKIX_LDAPCLIENT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_LDAPCLIENT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_LDAPCLIENT_DEBUG(expr)
-#define PKIX_LDAPCLIENT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_LDAPDEFAULTCLIENTDEBUG
-#define PKIX_LDAPDEFAULTCLIENT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_LDAPDEFAULTCLIENT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_LDAPDEFAULTCLIENT_DEBUG(expr)
-#define PKIX_LDAPDEFAULTCLIENT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_SOCKETDEBUG
-#define PKIX_SOCKET_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_SOCKET_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_SOCKET_DEBUG(expr)
-#define PKIX_SOCKET_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_RESOURCELIMITSDEBUG
-#define PKIX_RESOURCELIMITS_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_RESOURCELIMITS_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_RESOURCELIMITS_DEBUG(expr)
-#define PKIX_RESOURCELIMITS_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_LOGGERDEBUG
-#define PKIX_LOGGER_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_LOGGER_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_LOGGER_DEBUG(expr)
-#define PKIX_LOGGER_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_MONITORLOCKDEBUG
-#define PKIX_MONITORLOCK_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_MONITORLOCK_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_MONITORLOCK_DEBUG(expr)
-#define PKIX_MONITORLOCK_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_INFOACCESSDEBUG
-#define PKIX_INFOACCESS_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_INFOACCESS_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_INFOACCESS_DEBUG(expr)
-#define PKIX_INFOACCESS_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_AIAMGRDEBUG
-#define PKIX_AIAMGR_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_AIAMGR_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_AIAMGR_DEBUG(expr)
-#define PKIX_AIAMGR_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_OCSPCHECKERDEBUG
-#define PKIX_OCSPCHECKER_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_OCSPCHECKER_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_OCSPCHECKER_DEBUG(expr)
-#define PKIX_OCSPCHECKER_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_OCSPCERTIDDEBUG
-#define PKIX_OCSPCERTID_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_OCSPCERTID_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_OCSPCERTID_DEBUG(expr)
-#define PKIX_OCSPCERTID_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_OCSPREQUESTDEBUG
-#define PKIX_OCSPREQUEST_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_OCSPREQUEST_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_OCSPREQUEST_DEBUG(expr)
-#define PKIX_OCSPREQUEST_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_OCSPRESPONSEDEBUG
-#define PKIX_OCSPRESPONSE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_OCSPRESPONSE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_OCSPRESPONSE_DEBUG(expr)
-#define PKIX_OCSPRESPONSE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_HTTPDEFAULTCLIENTDEBUG
-#define PKIX_HTTPDEFAULTCLIENT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_HTTPDEFAULTCLIENT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_HTTPDEFAULTCLIENT_DEBUG(expr)
-#define PKIX_HTTPDEFAULTCLIENT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_HTTPCERTSTORECONTEXTDEBUG
-#define PKIX_HTTPCERTSTORECONTEXT_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_HTTPCERTSTORECONTEXT_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_HTTPCERTSTORECONTEXT_DEBUG(expr)
-#define PKIX_HTTPCERTSTORECONTEXT_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_VERIFYNODEDEBUG
-#define PKIX_VERIFYNODE_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_VERIFYNODE_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_VERIFYNODE_DEBUG(expr)
-#define PKIX_VERIFYNODE_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_EKUCHECKER
-#define PKIX_EKUCHECKER_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_EKUCHECKER_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_EKUCHECKER_DEBUG(expr)
-#define PKIX_EKUCHECKER_DEBUG_ARG(expr, arg)
-#endif
-
-#if PKIX_CERTVFYPKIXDEBUG
-#define PKIX_CERTVFYPKIX_DEBUG(expr) \
- PKIX_DEBUG(expr)
-#define PKIX_CERTVFYPKIX_DEBUG_ARG(expr, arg) \
- PKIX_DEBUG_ARG(expr, arg)
-#else
-#define PKIX_CERTVFYPKIX_DEBUG(expr)
-#define PKIX_CERTVFYPKIX_DEBUG_ARG(expr, arg)
-#endif
-
-/*
- * All object types register themselves with the system using a
- * pkix_ClassTable_Entry, which consists of a set of functions for that
- * type and an ASCII string (char *) which is used by the default
- * ToStringCallback (if necessary). System types register themselves directly
- * when their respective PKIX_"type"_RegisterSelf functions are called.
- * User-defined types can be registered using PKIX_PL_Object_RegisterType.
- * (see comments in pkix_pl_system.h)
- */
-
-typedef struct pkix_ClassTable_EntryStruct pkix_ClassTable_Entry;
-struct pkix_ClassTable_EntryStruct {
- char *description;
- PKIX_Int32 objCounter;
- PKIX_Int32 typeObjectSize;
- PKIX_PL_DestructorCallback destructor;
- PKIX_PL_EqualsCallback equalsFunction;
- PKIX_PL_HashcodeCallback hashcodeFunction;
- PKIX_PL_ToStringCallback toStringFunction;
- PKIX_PL_ComparatorCallback comparator;
- PKIX_PL_DuplicateCallback duplicateFunction;
-};
-
-/*
- * PKIX_ERRORCLASSNAMES is an array of strings, with each string holding a
- * descriptive name for an error code. This is used by the default
- * PKIX_PL_Error_ToString function.
- */
-extern const char *PKIX_ERRORCLASSNAMES[PKIX_NUMERRORCLASSES];
-
-#define MAX_STACK_DEPTH 1000
-
-extern PRLogModuleInfo *pkixLog;
-
-#define PKIX_MAGIC_HEADER LL_INIT(0xFEEDC0FF, 0xEEFACADE)
-#define PKIX_MAGIC_HEADER_DESTROYED LL_INIT(0xBAADF00D, 0xDEADBEEF)
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_IsCertSelfIssued(
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pSelfIssued,
- void *plContext);
-
-PKIX_Error *
-pkix_Throw(
- PKIX_ERRORCLASS errClass,
- const char *funcName,
- PKIX_ERRORCODE errorTextCode,
- PKIX_ERRORCLASS overrideClass,
- PKIX_Error *cause,
- PKIX_Error **pError,
- void *plContext);
-
-PKIX_Error *
-pkix_CheckTypes(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_UInt32 type,
- void *plContext);
-
-PKIX_Error *
-pkix_CheckType(
- PKIX_PL_Object *object,
- PKIX_UInt32 type,
- void *plContext);
-
-PKIX_Error *
-pkix_hash(
- const unsigned char *bytes,
- PKIX_UInt32 length,
- PKIX_UInt32 *hash,
- void *plContext);
-
-PKIX_Error *
-pkix_duplicateImmutable(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext);
-
-PKIX_UInt32
-pkix_countArray(void **array);
-
-PKIX_UInt32
-pkix_hex2i(char c);
-
-char
-pkix_i2hex(char c);
-
-PKIX_Boolean
-pkix_isPlaintext(unsigned char c, PKIX_Boolean debug);
-
-PKIX_Error *
-pkix_CacheCertChain_Lookup(
- PKIX_PL_Cert* targetCert,
- PKIX_List* anchors,
- PKIX_PL_Date *testDate,
- PKIX_Boolean *pFound,
- PKIX_BuildResult **pBuildResult,
- void *plContext);
-
-PKIX_Error *
-pkix_CacheCertChain_Remove(
- PKIX_PL_Cert* targetCert,
- PKIX_List* anchors,
- void *plContext);
-
-PKIX_Error *
-pkix_CacheCertChain_Add(
- PKIX_PL_Cert* targetCert,
- PKIX_List* anchors,
- PKIX_PL_Date *validityDate,
- PKIX_BuildResult *buildResult,
- void *plContext);
-
-PKIX_Error *
-pkix_CacheCert_Lookup(
- PKIX_CertStore *store,
- PKIX_ComCertSelParams *certSelParams,
- PKIX_PL_Date *testDate,
- PKIX_Boolean *pFound,
- PKIX_List** pCerts,
- void *plContext);
-
-PKIX_Error *
-pkix_CacheCert_Add(
- PKIX_CertStore *store,
- PKIX_ComCertSelParams *certSelParams,
- PKIX_List* certs,
- void *plContext);
-
-PKIX_Error *
-pkix_CacheCrlEntry_Lookup(
- PKIX_CertStore *store,
- PKIX_PL_X500Name *certIssuer,
- PKIX_PL_BigInt *certSerialNumber,
- PKIX_Boolean *pFound,
- PKIX_List** pCrlEntryList,
- void *plContext);
-
-PKIX_Error *
-pkix_CacheCrlEntry_Add(
- PKIX_CertStore *store,
- PKIX_PL_X500Name *certIssuer,
- PKIX_PL_BigInt *certSerialNumber,
- PKIX_List* crlEntryList,
- void *plContext);
-
-#ifdef PR_LOGGING
-void
-pkix_trace_dump_cert(
- const char *info,
- PKIX_PL_Cert *cert,
- void *plContext);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_TOOLS_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/Makefile b/security/nss/lib/libpkix/pkix_pl_nss/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/config.mk b/security/nss/lib/libpkix/pkix_pl_nss/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/manifest.mn b/security/nss/lib/libpkix/pkix_pl_nss/manifest.mn
deleted file mode 100755
index f8d71ed77..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/manifest.mn
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../..
-DEPTH = ../../../..
-
-#
-DIRS = pki system module \
- $(NULL)
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/Makefile b/security/nss/lib/libpkix/pkix_pl_nss/module/Makefile
deleted file mode 100755
index 36524f56a..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/config.mk b/security/nss/lib/libpkix/pkix_pl_nss/module/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/manifest.mn b/security/nss/lib/libpkix/pkix_pl_nss/module/manifest.mn
deleted file mode 100755
index 7b9860135..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/manifest.mn
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_pl_aiamgr.h \
- pkix_pl_colcertstore.h \
- pkix_pl_httpcertstore.h \
- pkix_pl_httpdefaultclient.h \
- pkix_pl_ldapt.h \
- pkix_pl_ldapcertstore.h \
- pkix_pl_ldapresponse.h \
- pkix_pl_ldaprequest.h \
- pkix_pl_ldapdefaultclient.h \
- pkix_pl_nsscontext.h \
- pkix_pl_pk11certstore.h \
- pkix_pl_socket.h \
- $(NULL)
-
-MODULE = nss
-
-DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" -DSHLIB_VERSION=\"$(LIBRARY_VERSION)\"
-
-
-CSRCS = \
- pkix_pl_aiamgr.c \
- pkix_pl_colcertstore.c \
- pkix_pl_httpcertstore.c \
- pkix_pl_httpdefaultclient.c \
- pkix_pl_ldaptemplates.c \
- pkix_pl_ldapcertstore.c \
- pkix_pl_ldapresponse.c \
- pkix_pl_ldaprequest.c \
- pkix_pl_ldapdefaultclient.c \
- pkix_pl_nsscontext.c \
- pkix_pl_pk11certstore.c \
- pkix_pl_socket.c \
- $(NULL)
-
-LIBRARY_NAME = pkixmodule
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
deleted file mode 100644
index 10c31ee42..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_aiamgr.c
- *
- * AIAMgr Object Definitions
- *
- */
-
-#include "pkix_pl_aiamgr.h"
-extern PKIX_PL_HashTable *aiaConnectionCache;
-
-/* --Virtual-LdapClient-Functions------------------------------------ */
-
-PKIX_Error *
-PKIX_PL_LdapClient_InitiateRequest(
- PKIX_PL_LdapClient *client,
- LDAPRequestParams *requestParams,
- void **pNBIO,
- PKIX_List **pResponse,
- void *plContext)
-{
- PKIX_ENTER(LDAPCLIENT, "PKIX_PL_LdapClient_InitiateRequest");
- PKIX_NULLCHECK_TWO(client, client->initiateFcn);
-
- PKIX_CHECK(client->initiateFcn
- (client, requestParams, pNBIO, pResponse, plContext),
- PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
-cleanup:
-
- PKIX_RETURN(LDAPCLIENT);
-
-}
-
-PKIX_Error *
-PKIX_PL_LdapClient_ResumeRequest(
- PKIX_PL_LdapClient *client,
- void **pNBIO,
- PKIX_List **pResponse,
- void *plContext)
-{
- PKIX_ENTER(LDAPCLIENT, "PKIX_PL_LdapClient_ResumeRequest");
- PKIX_NULLCHECK_TWO(client, client->resumeFcn);
-
- PKIX_CHECK(client->resumeFcn
- (client, pNBIO, pResponse, plContext),
- PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
-cleanup:
-
- PKIX_RETURN(LDAPCLIENT);
-
-}
-
-/* --Private-AIAMgr-Functions----------------------------------*/
-
-/*
- * FUNCTION: pkix_pl_AIAMgr_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_pki.h)
- */
-static PKIX_Error *
-pkix_pl_AIAMgr_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_AIAMgr *aiaMgr = NULL;
-
- PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_AIAMGR_TYPE, plContext),
- PKIX_OBJECTNOTAIAMGR);
-
- aiaMgr = (PKIX_PL_AIAMgr *)object;
-
- /* pointer to cert cache */
- /* pointer to crl cache */
- aiaMgr->method = 0;
- aiaMgr->aiaIndex = 0;
- aiaMgr->numAias = 0;
- PKIX_DECREF(aiaMgr->aia);
- PKIX_DECREF(aiaMgr->location);
- PKIX_DECREF(aiaMgr->results);
- PKIX_DECREF(aiaMgr->client.ldapClient);
-
-cleanup:
-
- PKIX_RETURN(AIAMGR);
-}
-
-/*
- * FUNCTION: pkix_pl_AIAMgr_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_AIAMGR_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_AIAMgr_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry *entry = &systemClasses[PKIX_AIAMGR_TYPE];
-
- PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_RegisterSelf");
-
- entry->description = "AIAMgr";
- entry->typeObjectSize = sizeof(PKIX_PL_AIAMgr);
- entry->destructor = pkix_pl_AIAMgr_Destroy;
-
- PKIX_RETURN(AIAMGR);
-}
-
-/*
- * FUNCTION: pkix_pl_AiaMgr_FindLDAPClient
- * DESCRIPTION:
- *
- * This function checks the collection of LDAPClient connections held by the
- * AIAMgr pointed to by "aiaMgr" for one matching the domain name given by
- * "domainName". The string may include a port number: e.g., "betty.nist.gov"
- * or "nss.red.iplanet.com:1389". If a match is found, that LDAPClient is
- * stored at "pClient". Otherwise, an LDAPClient is created and added to the
- * collection, and then stored at "pClient".
- *
- * PARAMETERS:
- * "aiaMgr"
- * The AIAMgr whose LDAPClient connected are to be managed. Must be
- * non-NULL.
- * "domainName"
- * Address of a string pointing to a server name. Must be non-NULL.
- * "pClient"
- * Address at which the returned LDAPClient is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an AIAMgr Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_AiaMgr_FindLDAPClient(
- PKIX_PL_AIAMgr *aiaMgr,
- char *domainName,
- PKIX_PL_LdapClient **pClient,
- void *plContext)
-{
- PKIX_PL_String *domainString = NULL;
- PKIX_PL_LdapDefaultClient *client = NULL;
-
- PKIX_ENTER(AIAMGR, "pkix_pl_AiaMgr_FindLDAPClient");
- PKIX_NULLCHECK_THREE(aiaMgr, domainName, pClient);
-
- /* create PKIX_PL_String from domain name */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, domainName, 0, &domainString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- /* Is this domainName already in cache? */
- PKIX_CHECK(PKIX_PL_HashTable_Lookup
- (aiaConnectionCache,
- (PKIX_PL_Object *)domainString,
- (PKIX_PL_Object **)&client,
- plContext),
- PKIX_HASHTABLELOOKUPFAILED);
-
- if (client == NULL) {
-
- /* No, create a connection (and cache it) */
- PKIX_CHECK(PKIX_PL_LdapDefaultClient_CreateByName
- (domainName,
- /* Do not use NBIO until we verify, that
- * it is working. For now use 1 min timeout. */
- PR_SecondsToInterval(
- ((PKIX_PL_NssContext*)plContext)->timeoutSeconds),
- NULL,
- &client,
- plContext),
- PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED);
-
- PKIX_CHECK(PKIX_PL_HashTable_Add
- (aiaConnectionCache,
- (PKIX_PL_Object *)domainString,
- (PKIX_PL_Object *)client,
- plContext),
- PKIX_HASHTABLEADDFAILED);
-
- }
-
- *pClient = (PKIX_PL_LdapClient *)client;
-
-cleanup:
-
- PKIX_DECREF(domainString);
-
- PKIX_RETURN(AIAMGR);
-}
-
-PKIX_Error *
-pkix_pl_AIAMgr_GetHTTPCerts(
- PKIX_PL_AIAMgr *aiaMgr,
- PKIX_PL_InfoAccess *ia,
- void **pNBIOContext,
- PKIX_List **pCerts,
- void *plContext)
-{
- PKIX_PL_GeneralName *location = NULL;
- PKIX_PL_String *locationString = NULL;
- PKIX_UInt32 len = 0;
- PRUint16 port = 0;
- const SEC_HttpClientFcn *httpClient = NULL;
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
- SECStatus rv = SECFailure;
- SEC_HTTP_SERVER_SESSION serverSession = NULL;
- SEC_HTTP_REQUEST_SESSION requestSession = NULL;
- char *path = NULL;
- char *hostname = NULL;
- char *locationAscii = NULL;
- void *nbio = NULL;
- PRUint16 responseCode = 0;
- const char *responseContentType = NULL;
- const char *responseData = NULL;
-
- PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetHTTPCerts");
- PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts);
-
- nbio = *pNBIOContext;
- *pNBIOContext = NULL;
- *pCerts = NULL;
-
- if (nbio == NULL) { /* a new request */
-
- PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation
- (ia, &location, plContext),
- PKIX_INFOACCESSGETLOCATIONFAILED);
-
- /* find or create httpClient = default client */
- httpClient = SEC_GetRegisteredHttpClient();
- aiaMgr->client.hdata.httpClient = httpClient;
- if (!httpClient)
- PKIX_ERROR(PKIX_OUTOFMEMORY);
-
- if (httpClient->version == 1) {
-
- PKIX_UInt32 timeout =
- ((PKIX_PL_NssContext*)plContext)->timeoutSeconds;
-
- hcv1 = &(httpClient->fcnTable.ftable1);
-
- /* create server session */
- PKIX_TOSTRING(location, &locationString, plContext,
- PKIX_GENERALNAMETOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (locationString,
- PKIX_ESCASCII,
- (void **)&locationAscii,
- &len,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- rv = CERT_ParseURL(locationAscii, &hostname, &port,
- &path);
- if ((rv != SECSuccess) ||
- (hostname == NULL) ||
- (path == NULL)) {
- PKIX_ERROR(PKIX_URLPARSINGFAILED);
- }
-
- rv = (*hcv1->createSessionFcn)(hostname, port,
- &serverSession);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED);
- }
-
- aiaMgr->client.hdata.serverSession = serverSession;
-
- /* create request session */
- rv = (*hcv1->createFcn)(serverSession, "http", path,
- "GET", PR_SecondsToInterval(timeout),
- &requestSession);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_HTTPSERVERERROR);
- }
-
- aiaMgr->client.hdata.requestSession = requestSession;
- } else {
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
- }
- }
-
- httpClient = aiaMgr->client.hdata.httpClient;
-
- if (httpClient->version == 1) {
- PRUint32 responseDataLen =
- ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
-
- hcv1 = &(httpClient->fcnTable.ftable1);
- requestSession = aiaMgr->client.hdata.requestSession;
-
- /* trySendAndReceive */
- rv = (*hcv1->trySendAndReceiveFcn)(requestSession,
- (PRPollDesc **)&nbio,
- &responseCode,
- (const char **)&responseContentType,
- NULL, /* &responseHeaders */
- (const char **)&responseData,
- &responseDataLen);
-
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_HTTPSERVERERROR);
- }
-
- if (nbio != 0) {
- *pNBIOContext = nbio;
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
- (responseCode,
- responseContentType,
- responseData,
- responseDataLen,
- pCerts,
- plContext),
- PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
-
- /* Session and request cleanup in case of success */
- if (aiaMgr->client.hdata.requestSession != NULL) {
- (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession);
- aiaMgr->client.hdata.requestSession = NULL;
- }
- if (aiaMgr->client.hdata.serverSession != NULL) {
- (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession);
- aiaMgr->client.hdata.serverSession = NULL;
- }
- aiaMgr->client.hdata.httpClient = 0; /* callback fn */
-
- } else {
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
- }
-
-cleanup:
- /* Session and request cleanup in case of error. Passing through without cleanup
- * if interrupted by blocked IO. */
- if (PKIX_ERROR_RECEIVED && aiaMgr) {
- if (aiaMgr->client.hdata.requestSession != NULL) {
- (*hcv1->freeFcn)(aiaMgr->client.hdata.requestSession);
- aiaMgr->client.hdata.requestSession = NULL;
- }
- if (aiaMgr->client.hdata.serverSession != NULL) {
- (*hcv1->freeSessionFcn)(aiaMgr->client.hdata.serverSession);
- aiaMgr->client.hdata.serverSession = NULL;
- }
- aiaMgr->client.hdata.httpClient = 0; /* callback fn */
- }
-
- PKIX_DECREF(location);
- PKIX_DECREF(locationString);
-
- if (locationAscii) {
- PORT_Free(locationAscii);
- }
- if (hostname) {
- PORT_Free(hostname);
- }
- if (path) {
- PORT_Free(path);
- }
-
- PKIX_RETURN(AIAMGR);
-}
-
-PKIX_Error *
-pkix_pl_AIAMgr_GetLDAPCerts(
- PKIX_PL_AIAMgr *aiaMgr,
- PKIX_PL_InfoAccess *ia,
- void **pNBIOContext,
- PKIX_List **pCerts,
- void *plContext)
-{
- PKIX_List *result = NULL;
- PKIX_PL_GeneralName *location = NULL;
- PKIX_PL_LdapClient *client = NULL;
- LDAPRequestParams request;
- PRArenaPool *arena = NULL;
- char *domainName = NULL;
- void *nbio = NULL;
-
- PKIX_ENTER(AIAMGR, "pkix_pl_AIAMgr_GetLDAPCerts");
- PKIX_NULLCHECK_FOUR(aiaMgr, ia, pNBIOContext, pCerts);
-
- nbio = *pNBIOContext;
- *pNBIOContext = NULL;
- *pCerts = NULL;
-
- if (nbio == NULL) { /* a new request */
-
- /* Initiate an LDAP request */
-
- request.scope = WHOLE_SUBTREE;
- request.derefAliases = NEVER_DEREF;
- request.sizeLimit = 0;
- request.timeLimit = 0;
-
- PKIX_CHECK(PKIX_PL_InfoAccess_GetLocation
- (ia, &location, plContext),
- PKIX_INFOACCESSGETLOCATIONFAILED);
-
- /*
- * Get a short-lived arena. We'll be done with
- * this space once the request is encoded.
- */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena) {
- PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
- }
-
- PKIX_CHECK(pkix_pl_InfoAccess_ParseLocation
- (location, arena, &request, &domainName, plContext),
- PKIX_INFOACCESSPARSELOCATIONFAILED);
-
- PKIX_DECREF(location);
-
- /* Find or create a connection to LDAP server */
- PKIX_CHECK(pkix_pl_AiaMgr_FindLDAPClient
- (aiaMgr, domainName, &client, plContext),
- PKIX_AIAMGRFINDLDAPCLIENTFAILED);
-
- aiaMgr->client.ldapClient = client;
-
- PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
- (aiaMgr->client.ldapClient,
- &request,
- &nbio,
- &result,
- plContext),
- PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
-
- PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE));
-
- } else {
-
- PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
- (aiaMgr->client.ldapClient, &nbio, &result, plContext),
- PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
-
- }
-
- if (nbio != NULL) { /* WOULDBLOCK */
- *pNBIOContext = nbio;
- *pCerts = NULL;
- goto cleanup;
- }
-
- PKIX_DECREF(aiaMgr->client.ldapClient);
-
- if (result == NULL) {
- *pCerts = NULL;
- } else {
- PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
- (result, pCerts, plContext),
- PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);
- }
-
- *pNBIOContext = nbio;
-
-cleanup:
-
- if (arena && (PKIX_ERROR_RECEIVED)) {
- PKIX_PL_NSSCALL(AIAMGR, PORT_FreeArena, (arena, PR_FALSE));
- }
-
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(aiaMgr->client.ldapClient);
- }
-
- PKIX_DECREF(location);
-
- PKIX_RETURN(AIAMGR);
-}
-
-/*
- * FUNCTION: PKIX_PL_AIAMgr_Create
- * DESCRIPTION:
- *
- * This function creates an AIAMgr, storing the result at "pAIAMgr".
- *
- * PARAMETERS:
- * "pAIAMGR"
- * Address at which the returned AIAMgr is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an AIAMgr Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_AIAMgr_Create(
- PKIX_PL_AIAMgr **pAIAMgr,
- void *plContext)
-{
- PKIX_PL_AIAMgr *aiaMgr = NULL;
-
- PKIX_ENTER(AIAMGR, "PKIX_PL_AIAMgr_Create");
- PKIX_NULLCHECK_ONE(pAIAMgr);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_AIAMGR_TYPE,
- sizeof(PKIX_PL_AIAMgr),
- (PKIX_PL_Object **)&aiaMgr,
- plContext),
- PKIX_COULDNOTCREATEAIAMGROBJECT);
- /* pointer to cert cache */
- /* pointer to crl cache */
- aiaMgr->method = 0;
- aiaMgr->aiaIndex = 0;
- aiaMgr->numAias = 0;
- aiaMgr->aia = NULL;
- aiaMgr->location = NULL;
- aiaMgr->results = NULL;
- aiaMgr->client.hdata.httpClient = NULL;
- aiaMgr->client.hdata.serverSession = NULL;
- aiaMgr->client.hdata.requestSession = NULL;
-
- *pAIAMgr = aiaMgr;
-
-cleanup:
-
- PKIX_RETURN(AIAMGR);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_AIAMgr_GetAIACerts (see description in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_AIAMgr_GetAIACerts(
- PKIX_PL_AIAMgr *aiaMgr,
- PKIX_PL_Cert *prevCert,
- void **pNBIOContext,
- PKIX_List **pCerts,
- void *plContext)
-{
- PKIX_UInt32 numAias = 0;
- PKIX_UInt32 aiaIndex = 0;
- PKIX_UInt32 iaType = PKIX_INFOACCESS_LOCATION_UNKNOWN;
- PKIX_List *certs = NULL;
- PKIX_PL_InfoAccess *ia = NULL;
- void *nbio = NULL;
-
- PKIX_ENTER(AIAMGR, "PKIX_PL_AIAMgr_GetAIACerts");
- PKIX_NULLCHECK_FOUR(aiaMgr, prevCert, pNBIOContext, pCerts);
-
- nbio = *pNBIOContext;
- *pCerts = NULL;
- *pNBIOContext = NULL;
-
- if (nbio == NULL) { /* a new request */
-
- /* Does this Cert have an AIA extension? */
- PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess
- (prevCert, &aiaMgr->aia, plContext),
- PKIX_CERTGETAUTHORITYINFOACCESSFAILED);
-
- if (aiaMgr->aia != NULL) {
- PKIX_CHECK(PKIX_List_GetLength
- (aiaMgr->aia, &numAias, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- /* And if so, does it have any entries? */
- if ((aiaMgr->aia == NULL) || (numAias == 0)) {
- *pCerts = NULL;
- goto cleanup;
- }
-
- aiaMgr->aiaIndex = 0;
- aiaMgr->numAias = numAias;
- aiaMgr->results = NULL;
-
- }
-
- for (aiaIndex = aiaMgr->aiaIndex;
- aiaIndex < aiaMgr->numAias;
- aiaIndex ++) {
- PKIX_UInt32 method = 0;
-
- PKIX_CHECK(PKIX_List_GetItem
- (aiaMgr->aia,
- aiaIndex,
- (PKIX_PL_Object **)&ia,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(PKIX_PL_InfoAccess_GetMethod
- (ia, &method, plContext),
- PKIX_INFOACCESSGETMETHODFAILED);
-
- if (method != PKIX_INFOACCESS_CA_ISSUERS &&
- method != PKIX_INFOACCESS_CA_REPOSITORY) {
- PKIX_DECREF(ia);
- continue;
- }
-
- PKIX_CHECK(PKIX_PL_InfoAccess_GetLocationType
- (ia, &iaType, plContext),
- PKIX_INFOACCESSGETLOCATIONTYPEFAILED);
-
- if (iaType == PKIX_INFOACCESS_LOCATION_HTTP) {
- PKIX_CHECK(pkix_pl_AIAMgr_GetHTTPCerts
- (aiaMgr, ia, &nbio, &certs, plContext),
- PKIX_AIAMGRGETHTTPCERTSFAILED);
- } else if (iaType == PKIX_INFOACCESS_LOCATION_LDAP) {
- PKIX_CHECK(pkix_pl_AIAMgr_GetLDAPCerts
- (aiaMgr, ia, &nbio, &certs, plContext),
- PKIX_AIAMGRGETLDAPCERTSFAILED);
- } else {
- /* We only support http and ldap requests. */
- PKIX_DECREF(ia);
- continue;
- }
-
- if (nbio != NULL) { /* WOULDBLOCK */
- aiaMgr->aiaIndex = aiaIndex;
- *pNBIOContext = nbio;
- *pCerts = NULL;
- goto cleanup;
- }
-
- /*
- * We can't just use and modify the List we received.
- * Because it's cached, it's set immutable.
- */
- if (aiaMgr->results == NULL) {
- PKIX_CHECK(PKIX_List_Create
- (&(aiaMgr->results), plContext),
- PKIX_LISTCREATEFAILED);
- }
- PKIX_CHECK(pkix_List_AppendList
- (aiaMgr->results, certs, plContext),
- PKIX_APPENDLISTFAILED);
- PKIX_DECREF(certs);
-
- PKIX_DECREF(ia);
- }
-
- PKIX_DECREF(aiaMgr->aia);
-
- *pNBIOContext = NULL;
- *pCerts = aiaMgr->results;
- aiaMgr->results = NULL;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(aiaMgr->aia);
- PKIX_DECREF(aiaMgr->results);
- PKIX_DECREF(aiaMgr->client.ldapClient);
- }
-
- PKIX_DECREF(certs);
- PKIX_DECREF(ia);
-
- PKIX_RETURN(AIAMGR);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h
deleted file mode 100644
index 00b872f58..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_aiamgr.h
- *
- * AIAMgr Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_AIAMGR_H
-#define _PKIX_PL_AIAMGR_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_AIAMgrStruct {
- /* pointer to cert cache */
- /* pointer to crl cache */
- PKIX_UInt32 method;
- PKIX_UInt32 aiaIndex;
- PKIX_UInt32 numAias;
- PKIX_List *aia;
- PKIX_PL_GeneralName *location;
- PKIX_List *results;
- union {
- PKIX_PL_LdapClient *ldapClient;
- struct {
- const SEC_HttpClientFcn *httpClient;
- SEC_HTTP_SERVER_SESSION serverSession;
- SEC_HTTP_REQUEST_SESSION requestSession;
- char *path;
- } hdata;
- } client;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_AIAMgr_RegisterSelf(void *plContext);
-
-PKIX_Error *PKIX_PL_LdapClient_InitiateRequest(
- PKIX_PL_LdapClient *client,
- LDAPRequestParams *requestParams,
- void **pPollDesc,
- PKIX_List **pResponse,
- void *plContext);
-
-PKIX_Error *PKIX_PL_LdapClient_ResumeRequest(
- PKIX_PL_LdapClient *client,
- void **pPollDesc,
- PKIX_List **pResponse,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_AIAMGR_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.c
deleted file mode 100755
index 57004b770..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.c
+++ /dev/null
@@ -1,1282 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_colcertstore.c
- *
- * CollectionCertStore Function Definitions
- *
- */
-
-#include "pkix_pl_colcertstore.h"
-
-/*
- * This Object is going to be taken out from libpkix SOON. The following
- * function is copied from nss/cmd library, but not supported by NSS as
- * public API. We use it since ColCertStore are read in Cert/Crl from
- * files and need this support.
- */
-
-static SECStatus
-SECU_FileToItem(SECItem *dst, PRFileDesc *src)
-{
- PRFileInfo info;
- PRInt32 numBytes;
- PRStatus prStatus;
-
- prStatus = PR_GetOpenFileInfo(src, &info);
-
- if (prStatus != PR_SUCCESS) {
- PORT_SetError(SEC_ERROR_IO);
- return SECFailure;
- }
-
- /* XXX workaround for 3.1, not all utils zero dst before sending */
- dst->data = 0;
- if (!SECITEM_AllocItem(NULL, dst, info.size))
- goto loser;
-
- numBytes = PR_Read(src, dst->data, info.size);
- if (numBytes != info.size) {
- PORT_SetError(SEC_ERROR_IO);
- goto loser;
- }
-
- return SECSuccess;
-loser:
- SECITEM_FreeItem(dst, PR_FALSE);
- return SECFailure;
-}
-
-static SECStatus
-SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii)
-{
- SECStatus rv;
- if (ascii) {
- /* First convert ascii to binary */
- SECItem filedata;
- char *asc, *body;
-
- /* Read in ascii data */
- rv = SECU_FileToItem(&filedata, inFile);
- asc = (char *)filedata.data;
- if (!asc) {
- fprintf(stderr, "unable to read data from input file\n");
- return SECFailure;
- }
-
- /* check for headers and trailers and remove them */
- if ((body = strstr(asc, "-----BEGIN")) != NULL) {
- char *trailer = NULL;
- asc = body;
- body = PORT_Strchr(body, '\n');
- if (!body)
- body = PORT_Strchr(asc, '\r'); /* maybe this is a MAC file */
- if (body)
- trailer = strstr(++body, "-----END");
- if (trailer != NULL) {
- *trailer = '\0';
- } else {
- fprintf(stderr, "input has header but no trailer\n");
- PORT_Free(filedata.data);
- return SECFailure;
- }
- } else {
- body = asc;
- }
-
- /* Convert to binary */
- rv = ATOB_ConvertAsciiToItem(der, body);
- if (rv) {
- return SECFailure;
- }
-
- PORT_Free(filedata.data);
- } else {
- /* Read in binary der */
- rv = SECU_FileToItem(der, inFile);
- if (rv) {
- return SECFailure;
- }
- }
- return SECSuccess;
-}
-
-/*
- * FUNCTION: PKIX_PL_CollectionCertStoreContext_Create
- * DESCRIPTION:
- *
- * Creates a new CollectionCertStoreContext using the String pointed to
- * by "storeDir" and stores it at "pColCertStoreContext".
- *
- * PARAMETERS:
- * "storeDir"
- * The absolute path where *.crl and *.crt files are located.
- * "pColCertStoreContext"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CollectionCertStoreContext Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_Create(
- PKIX_PL_String *storeDir,
- PKIX_PL_CollectionCertStoreContext **pColCertStoreContext,
- void *plContext)
-{
- PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_Create");
- PKIX_NULLCHECK_TWO(storeDir, pColCertStoreContext);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_COLLECTIONCERTSTORECONTEXT_TYPE,
- sizeof (PKIX_PL_CollectionCertStoreContext),
- (PKIX_PL_Object **)&colCertStoreContext,
- plContext),
- PKIX_COULDNOTCREATECOLLECTIONCERTSTORECONTEXTOBJECT);
-
- PKIX_INCREF(storeDir);
- colCertStoreContext->storeDir = storeDir;
-
- colCertStoreContext->crlList = NULL;
- colCertStoreContext->certList = NULL;
-
- *pColCertStoreContext = colCertStoreContext;
- colCertStoreContext = NULL;
-
-cleanup:
-
- PKIX_DECREF(colCertStoreContext);
-
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_COLLECTIONCERTSTORECONTEXT_TYPE, plContext),
- PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT);
-
- colCertStoreContext = (PKIX_PL_CollectionCertStoreContext *)object;
-
- PKIX_DECREF(colCertStoreContext->storeDir);
- PKIX_DECREF(colCertStoreContext->crlList);
- PKIX_DECREF(colCertStoreContext->certList);
-
-cleanup:
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_CollectionCertStoreContext *collectionCSContext = NULL;
- PKIX_UInt32 tempHash = 0;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType
- (object,
- PKIX_COLLECTIONCERTSTORECONTEXT_TYPE,
- plContext),
- PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT);
-
- collectionCSContext = (PKIX_PL_CollectionCertStoreContext *)object;
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *) collectionCSContext->storeDir,
- &tempHash,
- plContext),
- PKIX_STRINGHASHCODEFAILED);
-
- *pHashcode = tempHash << 7;
-
- /* should not hash on crlList and certList, values are dynamic */
-
-cleanup:
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PKIX_PL_CollectionCertStoreContext *firstCCSContext = NULL;
- PKIX_PL_CollectionCertStoreContext *secondCCSContext = NULL;
- PKIX_Boolean cmpResult = 0;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- PKIX_CHECK(pkix_CheckTypes
- (firstObject,
- secondObject,
- PKIX_COLLECTIONCERTSTORECONTEXT_TYPE,
- plContext),
- PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT);
-
- firstCCSContext = (PKIX_PL_CollectionCertStoreContext *)firstObject;
- secondCCSContext = (PKIX_PL_CollectionCertStoreContext *)secondObject;
-
- if (firstCCSContext->storeDir == secondCCSContext->storeDir) {
-
- cmpResult = PKIX_TRUE;
-
- } else {
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *) firstCCSContext->storeDir,
- (PKIX_PL_Object *) secondCCSContext->storeDir,
- &cmpResult,
- plContext),
- PKIX_STRINGEQUALSFAILED);
- }
-
- *pResult = cmpResult;
-
- /* should not check equal on crlList and certList, data are dynamic */
-
-cleanup:
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStore_CheckTrust
- * DESCRIPTION:
- * This function checks the trust status of this "cert" that was retrieved
- * from the CertStore "store" and returns its trust status at "pTrusted".
- *
- * PARAMETERS:
- * "store"
- * Address of the CertStore. Must be non-NULL.
- * "cert"
- * Address of the Cert. Must be non-NULL.
- * "pTrusted"
- * Address of PKIX_Boolean where the "cert" trust status is returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStore_CheckTrust(
- PKIX_CertStore *store,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pTrusted,
- void *plContext)
-{
- PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_CheckTrust");
- PKIX_NULLCHECK_THREE(store, cert, pTrusted);
-
- *pTrusted = PKIX_TRUE;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_CreateCert
- * DESCRIPTION:
- *
- * Creates Cert using data file path name pointed to by "certFileName" and
- * stores it at "pCert". If the Cert can not be decoded, NULL is stored
- * at "pCert".
- *
- * PARAMETERS
- * "certFileName" - Address of Cert data file path name. Must be non-NULL.
- * "pCert" - Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CollectionCertStoreContext Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_CreateCert(
- const char *certFileName,
- PKIX_PL_Cert **pCert,
- void *plContext)
-{
- PKIX_PL_ByteArray *byteArray = NULL;
- PKIX_PL_Cert *cert = NULL;
- PRFileDesc *inFile = NULL;
- SECItem certDER;
- void *buf = NULL;
- PKIX_UInt32 len;
- SECStatus rv;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_CreateCert");
- PKIX_NULLCHECK_TWO(certFileName, pCert);
-
- *pCert = NULL;
- certDER.data = NULL;
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_Open.\n");
- inFile = PR_Open(certFileName, PR_RDONLY, 0);
-
- if (!inFile){
- PKIX_ERROR(PKIX_UNABLETOOPENCERTFILE);
- } else {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling SECU_ReadDerFromFile.\n");
- rv = SECU_ReadDERFromFile(&certDER, inFile, PR_FALSE);
- if (!rv){
- buf = (void *)certDER.data;
- len = certDER.len;
-
- PKIX_CHECK(PKIX_PL_ByteArray_Create
- (buf, len, &byteArray, plContext),
- PKIX_BYTEARRAYCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_Create
- (byteArray, &cert, plContext),
- PKIX_CERTCREATEFAILED);
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling SECITEM_FreeItem.\n");
- SECITEM_FreeItem(&certDER, PR_FALSE);
-
- } else {
- PKIX_ERROR(PKIX_UNABLETOREADDERFROMCERTFILE);
- }
- }
-
- *pCert = cert;
-
-cleanup:
- if (inFile){
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_CloseDir.\n");
- PR_Close(inFile);
- }
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling SECITEM_FreeItem).\n");
- SECITEM_FreeItem(&certDER, PR_FALSE);
-
- PKIX_DECREF(cert);
- }
- PKIX_DECREF(byteArray);
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_CreateCRL
- * DESCRIPTION:
- *
- * Creates CRL using data file path name pointed to by "crlFileName" and
- * stores it at "pCrl". If the CRL can not be decoded, NULL is stored
- * at "pCrl".
- *
- * PARAMETERS
- * "crlFileName" - Address of CRL data file path name. Must be non-NULL.
- * "pCrl" - Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CollectionCertStoreContext Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_CreateCRL(
- const char *crlFileName,
- PKIX_PL_CRL **pCrl,
- void *plContext)
-{
- PKIX_PL_ByteArray *byteArray = NULL;
- PKIX_PL_CRL *crl = NULL;
- PRFileDesc *inFile = NULL;
- SECItem crlDER;
- void *buf = NULL;
- PKIX_UInt32 len;
- SECStatus rv;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_CreateCRL");
- PKIX_NULLCHECK_TWO(crlFileName, pCrl);
-
- *pCrl = NULL;
- crlDER.data = NULL;
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_Open.\n");
- inFile = PR_Open(crlFileName, PR_RDONLY, 0);
-
- if (!inFile){
- PKIX_ERROR(PKIX_UNABLETOOPENCRLFILE);
- } else {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling SECU_ReadDerFromFile.\n");
- rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE);
- if (!rv){
- buf = (void *)crlDER.data;
- len = crlDER.len;
-
- PKIX_CHECK(PKIX_PL_ByteArray_Create
- (buf, len, &byteArray, plContext),
- PKIX_BYTEARRAYCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_CRL_Create
- (byteArray, &crl, plContext),
- PKIX_CRLCREATEFAILED);
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling SECITEM_FreeItem.\n");
- SECITEM_FreeItem(&crlDER, PR_FALSE);
-
- } else {
- PKIX_ERROR(PKIX_UNABLETOREADDERFROMCRLFILE);
- }
- }
-
- *pCrl = crl;
-
-cleanup:
- if (inFile){
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_CloseDir.\n");
- PR_Close(inFile);
- }
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling SECITEM_FreeItem).\n");
- SECITEM_FreeItem(&crlDER, PR_FALSE);
-
- PKIX_DECREF(crl);
- if (crlDER.data != NULL) {
- SECITEM_FreeItem(&crlDER, PR_FALSE);
- }
- }
-
- PKIX_DECREF(byteArray);
-
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCert
- * DESCRIPTION:
- *
- * Create list of Certs from *.crt files at directory specified in dirName,
- * Not recursive to sub-directory. Also assume the directory contents are
- * not changed dynamically.
- *
- * PARAMETERS
- * "colCertStoreContext" - Address of CollectionCertStoreContext
- * where the dirName is specified and where the return
- * Certs are stored as a list. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Not Thread Safe - A lock at top level is required.
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CollectionCertStoreContext Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_PopulateCert(
- PKIX_PL_CollectionCertStoreContext *colCertStoreContext,
- void *plContext)
-{
- PKIX_List *certList = NULL;
- PKIX_PL_Cert *certItem = NULL;
- char *dirName = NULL;
- char *pathName = NULL;
- PKIX_UInt32 dirNameLen = 0;
- PRErrorCode prError = 0;
- PRDir *dir = NULL;
- PRDirEntry *dirEntry = NULL;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_PopulateCert");
- PKIX_NULLCHECK_ONE(colCertStoreContext);
-
- /* convert directory to ascii */
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (colCertStoreContext->storeDir,
- PKIX_ESCASCII,
- (void **)&dirName,
- &dirNameLen,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- /* create cert list, if no cert file, should return an empty list */
-
- PKIX_CHECK(PKIX_List_Create(&certList, plContext),
- PKIX_LISTCREATEFAILED);
-
- /* open directory and read in .crt files */
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n");
- dir = PR_OpenDir(dirName);
-
- if (!dir) {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG
- ("\t\t Directory Name:%s\n", dirName);
- PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY);
- }
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n");
- dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);
-
- if (!dirEntry) {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Empty directory.\n");
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_GetError.\n");
- prError = PR_GetError();
- }
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n");
- PR_SetError(0, 0);
-
- while (dirEntry != NULL && prError == 0) {
- if (PL_strrstr(dirEntry->name, ".crt") ==
- dirEntry->name + PL_strlen(dirEntry->name) - 4) {
-
- PKIX_CHECK_ONLY_FATAL
- (PKIX_PL_Malloc
- (dirNameLen + PL_strlen(dirEntry->name) + 2,
- (void **)&pathName,
- plContext),
- PKIX_MALLOCFAILED);
-
- if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PL_strcpy for dirName.\n");
- PL_strcpy(pathName, dirName);
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PL_strcat for dirName.\n");
- PL_strcat(pathName, "/");
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PL_strcat for /.\n");
- PL_strcat(pathName, dirEntry->name);
-
- PKIX_CHECK_ONLY_FATAL
- (pkix_pl_CollectionCertStoreContext_CreateCert
- (pathName, &certItem, plContext),
- PKIX_COLLECTIONCERTSTORECONTEXTCREATECERTFAILED);
-
- if (!PKIX_ERROR_RECEIVED){
- PKIX_CHECK_ONLY_FATAL
- (PKIX_List_AppendItem
- (certList,
- (PKIX_PL_Object *)certItem,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
- }
-
- PKIX_DECREF(certItem);
- PKIX_FREE(pathName);
- }
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_SetError.\n");
- PR_SetError(0, 0);
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_ReadDir.\n");
- dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);
-
- if (!dirEntry) {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_GetError.\n");
- prError = PR_GetError();
- }
- }
-
- if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) {
- PKIX_ERROR(PKIX_COLLECTIONCERTSTOREPOPULATECERTFAILED);
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable(certList, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- PKIX_INCREF(certList);
- colCertStoreContext->certList = certList;
-
-cleanup:
- if (dir) {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_CloseDir.\n");
- PR_CloseDir(dir);
- }
-
- PKIX_FREE(pathName);
- PKIX_FREE(dirName);
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(certList);
- }
-
- PKIX_DECREF(certItem);
- PKIX_DECREF(certList);
-
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCRL
- * DESCRIPTION:
- *
- * Create list of CRLs from *.crl files at directory specified in dirName,
- * Not recursive to sub-dirctory. Also assume the directory contents are
- * not changed dynamically.
- *
- * PARAMETERS
- * "colCertStoreContext" - Address of CollectionCertStoreContext
- * where the dirName is specified and where the return
- * CRLs are stored as a list. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Not Thread Safe - A lock at top level is required.
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CollectionCertStoreContext Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_PopulateCRL(
- PKIX_PL_CollectionCertStoreContext *colCertStoreContext,
- void *plContext)
-{
- PKIX_List *crlList = NULL;
- PKIX_PL_CRL *crlItem = NULL;
- char *dirName = NULL;
- char *pathName = NULL;
- PKIX_UInt32 dirNameLen = 0;
- PRErrorCode prError = 0;
- PRDir *dir = NULL;
- PRDirEntry *dirEntry = NULL;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_PopulateCRL");
- PKIX_NULLCHECK_ONE(colCertStoreContext);
-
- /* convert directory to ascii */
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (colCertStoreContext->storeDir,
- PKIX_ESCASCII,
- (void **)&dirName,
- &dirNameLen,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- /* create CRL list, if no CRL file, should return an empty list */
-
- PKIX_CHECK(PKIX_List_Create(&crlList, plContext),
- PKIX_LISTCREATEFAILED);
-
- /* open directory and read in .crl files */
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n");
- dir = PR_OpenDir(dirName);
-
- if (!dir) {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG
- ("\t\t Directory Name:%s\n", dirName);
- PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY);
- }
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n");
- dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);
-
- if (!dirEntry) {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Empty directory.\n");
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_GetError.\n");
- prError = PR_GetError();
- }
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n");
- PR_SetError(0, 0);
-
- while (dirEntry != NULL && prError == 0) {
- if (PL_strrstr(dirEntry->name, ".crl") ==
- dirEntry->name + PL_strlen(dirEntry->name) - 4) {
-
- PKIX_CHECK_ONLY_FATAL
- (PKIX_PL_Malloc
- (dirNameLen + PL_strlen(dirEntry->name) + 2,
- (void **)&pathName,
- plContext),
- PKIX_MALLOCFAILED);
-
- if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PL_strcpy for dirName.\n");
- PL_strcpy(pathName, dirName);
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PL_strcat for dirName.\n");
- PL_strcat(pathName, "/");
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PL_strcat for /.\n");
- PL_strcat(pathName, dirEntry->name);
-
- PKIX_CHECK_ONLY_FATAL
- (pkix_pl_CollectionCertStoreContext_CreateCRL
- (pathName, &crlItem, plContext),
- PKIX_COLLECTIONCERTSTORECONTEXTCREATECRLFAILED);
-
- if (!PKIX_ERROR_RECEIVED){
- PKIX_CHECK_ONLY_FATAL
- (PKIX_List_AppendItem
- (crlList,
- (PKIX_PL_Object *)crlItem,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
- }
-
- PKIX_DECREF(crlItem);
- PKIX_FREE(pathName);
- }
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_SetError.\n");
- PR_SetError(0, 0);
-
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_ReadDir.\n");
- dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);
-
- if (!dirEntry) {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_GetError.\n");
- prError = PR_GetError();
- }
- }
-
- if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) {
- PKIX_ERROR(PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED);
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable(crlList, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- PKIX_INCREF(crlList);
- colCertStoreContext->crlList = crlList;
-
-cleanup:
- if (dir) {
- PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
- ("\t\t Calling PR_CloseDir.\n");
- PR_CloseDir(dir);
- }
-
- PKIX_FREE(pathName);
- PKIX_FREE(dirName);
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(crlList);
- }
-
- PKIX_DECREF(crlItem);
- PKIX_DECREF(crlList);
-
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_GetSelectedCert
- * DESCRIPTION:
- *
- * Finds the Certs that match the criterion of the CertSelector pointed
- * to by "selector" using the List of Certs pointed to by "certList" and
- * stores the matching Certs at "pSelectedCertList".
- *
- * Not recursive to sub-directory.
- *
- * PARAMETERS
- * "certList" - Address of List of Certs to be searched. Must be non-NULL.
- * "colCertStoreContext" - Address of CollectionCertStoreContext
- * where the cached Certs are stored.
- * "selector" - CertSelector for chosing Cert based on Params set
- * "pSelectedCertList" - Certs that qualified by selector.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Not Thread Safe - A lock at top level is required.
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CollectionCertStoreContext Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_GetSelectedCert(
- PKIX_List *certList,
- PKIX_CertSelector *selector,
- PKIX_List **pSelectedCertList,
- void *plContext)
-{
- PKIX_List *selectCertList = NULL;
- PKIX_PL_Cert *certItem = NULL;
- PKIX_CertSelector_MatchCallback certSelectorMatch = NULL;
- PKIX_UInt32 numCerts = 0;
- PKIX_UInt32 i = 0;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_GetSelectedCert");
- PKIX_NULLCHECK_THREE(certList, selector, pSelectedCertList);
-
- PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
- (selector, &certSelectorMatch, plContext),
- PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(certList, &numCerts, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (certSelectorMatch) {
-
- PKIX_CHECK(PKIX_List_Create(&selectCertList, plContext),
- PKIX_LISTCREATEFAILED);
-
- for (i = 0; i < numCerts; i++) {
- PKIX_CHECK_ONLY_FATAL
- (PKIX_List_GetItem
- (certList,
- i,
- (PKIX_PL_Object **) &certItem,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- if (!PKIX_ERROR_RECEIVED){
- PKIX_CHECK_ONLY_FATAL
- (certSelectorMatch
- (selector, certItem, plContext),
- PKIX_CERTSELECTORMATCHFAILED);
-
- if (!PKIX_ERROR_RECEIVED){
- PKIX_CHECK_ONLY_FATAL
- (PKIX_List_AppendItem
- (selectCertList,
- (PKIX_PL_Object *)certItem,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
- }
-
- PKIX_DECREF(certItem);
- }
-
- } else {
-
- PKIX_INCREF(certList);
-
- selectCertList = certList;
- }
-
- *pSelectedCertList = selectCertList;
-
-cleanup:
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_GetSelectedCRL
- * DESCRIPTION:
- *
- * Finds the CRLs that match the criterion of the CRLSelector pointed
- * to by "selector" using the List of CRLs pointed to by "crlList" and
- * stores the matching CRLs at "pSelectedCrlList".
- *
- * Not recursive to sub-directory.
- *
- * PARAMETERS
- * "crlList" - Address of List of CRLs to be searched. Must be non-NULL
- * "selector" - CRLSelector for chosing CRL based on Params set
- * "pSelectedCrlList" - CRLs that qualified by selector.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Not Thread Safe - A lock at top level is required.
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CollectionCertStoreContext Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CollectionCertStoreContext_GetSelectedCRL(
- PKIX_List *crlList,
- PKIX_CRLSelector *selector,
- PKIX_List **pSelectedCrlList,
- void *plContext)
-{
- PKIX_List *selectCrlList = NULL;
- PKIX_PL_CRL *crlItem = NULL;
- PKIX_CRLSelector_MatchCallback crlSelectorMatch = NULL;
- PKIX_UInt32 numCrls = 0;
- PKIX_UInt32 i = 0;
- PKIX_Boolean match = PKIX_FALSE;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_GetSelectedCRL");
- PKIX_NULLCHECK_THREE(crlList, selector, pSelectedCrlList);
-
- PKIX_CHECK(PKIX_CRLSelector_GetMatchCallback
- (selector, &crlSelectorMatch, plContext),
- PKIX_CRLSELECTORGETMATCHCALLBACKFAILED);
-
- PKIX_CHECK(PKIX_List_GetLength(crlList, &numCrls, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (crlSelectorMatch) {
-
- PKIX_CHECK(PKIX_List_Create(&selectCrlList, plContext),
- PKIX_LISTCREATEFAILED);
-
- for (i = 0; i < numCrls; i++) {
- PKIX_CHECK_ONLY_FATAL(PKIX_List_GetItem
- (crlList,
- i,
- (PKIX_PL_Object **) &crlItem,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- if (!PKIX_ERROR_RECEIVED){
- PKIX_CHECK_ONLY_FATAL
- (crlSelectorMatch
- (selector, crlItem, &match, plContext),
- PKIX_CRLSELECTORMATCHFAILED);
-
- if (!(PKIX_ERROR_RECEIVED) && match) {
- PKIX_CHECK_ONLY_FATAL
- (PKIX_List_AppendItem
- (selectCrlList,
- (PKIX_PL_Object *)crlItem,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- }
- }
-
- PKIX_DECREF(crlItem);
- }
- } else {
-
- PKIX_INCREF(crlList);
-
- selectCrlList = crlList;
- }
-
- /* Don't throw away the list if one CRL was bad! */
- pkixTempErrorReceived = PKIX_FALSE;
-
- *pSelectedCrlList = selectCrlList;
-
-cleanup:
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStore_GetCert
- * DESCRIPTION:
- *
- * Retrieve Certs in a list of PKIX_PL_Cert object.
- *
- * PARAMETERS:
- * "colCertStoreContext"
- * The object CertStore is the object passed in by checker call.
- * "crlSelector"
- * CRLSelector specifies criteria for chosing CRL's
- * "pNBIOContext"
- * Address where platform-dependent information is returned for CertStores
- * that use non-blocking I/O. Must be non-NULL.
- * "pCertList"
- * Address where object pointer will be returned. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CollectionCertStore_GetCert(
- PKIX_CertStore *certStore,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *verifyNode,
- void **pNBIOContext,
- PKIX_List **pCerts,
- void *plContext)
-{
- PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
- PKIX_List *selectedCerts = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_GetCert");
- PKIX_NULLCHECK_FOUR(certStore, selector, pNBIOContext, pCerts);
-
- *pNBIOContext = NULL; /* We don't use non-blocking I/O */
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (certStore,
- (PKIX_PL_Object **) &colCertStoreContext,
- plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- if (colCertStoreContext->certList == NULL) {
-
- PKIX_OBJECT_LOCK(colCertStoreContext);
-
- /*
- * Certs in the directory are cached based on the
- * assumption that the directory contents won't be
- * changed dynamically.
- */
- if (colCertStoreContext->certList == NULL){
- PKIX_CHECK(pkix_pl_CollectionCertStoreContext_PopulateCert
- (colCertStoreContext, plContext),
- PKIX_COLLECTIONCERTSTORECONTEXTPOPULATECERTFAILED);
- }
-
- PKIX_OBJECT_UNLOCK(colCertStoreContext);
- }
-
- PKIX_CHECK(pkix_pl_CollectionCertStoreContext_GetSelectedCert
- (colCertStoreContext->certList,
- selector,
- &selectedCerts,
- plContext),
- PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCERTFAILED);
-
- *pCerts = selectedCerts;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_DECREF(colCertStoreContext);
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStore_GetCRL
- * DESCRIPTION:
- *
- * Retrieve CRL's in a list of PKIX_PL_CRL object.
- *
- * PARAMETERS:
- * "colCertStoreContext"
- * The object CertStore is passed in by checker call.
- * "crlSelector"
- * CRLSelector specifies criteria for chosing CRL's
- * "pNBIOContext"
- * Address where platform-dependent information is returned for CertStores
- * that use non-blocking I/O. Must be non-NULL.
- * "pCrlList"
- * Address where object pointer will be returned. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CollectionCertStore_GetCRL(
- PKIX_CertStore *certStore,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrlList,
- void *plContext)
-{
- PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
- PKIX_List *selectCrl = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_GetCRL");
- PKIX_NULLCHECK_FOUR(certStore, selector, pNBIOContext, pCrlList);
-
- *pNBIOContext = NULL; /* We don't use non-blocking I/O */
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (certStore,
- (PKIX_PL_Object **) &colCertStoreContext,
- plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- if (colCertStoreContext->crlList == NULL) {
-
- PKIX_OBJECT_LOCK(colCertStoreContext);
-
- /*
- * CRLs in the directory are cached based on the
- * assumption that the directory contents won't be
- * changed dynamically.
- */
- if (colCertStoreContext->crlList == NULL){
- PKIX_CHECK(pkix_pl_CollectionCertStoreContext_PopulateCRL
- (colCertStoreContext, plContext),
- PKIX_COLLECTIONCERTSTORECONTEXTPOPULATECRLFAILED);
- }
-
- PKIX_OBJECT_UNLOCK(colCertStoreContext);
-
- }
-
- PKIX_CHECK(pkix_pl_CollectionCertStoreContext_GetSelectedCRL
- (colCertStoreContext->crlList,
- selector,
- &selectCrl,
- plContext),
- PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED);
-
- *pCrlList = selectCrl;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_DECREF(colCertStoreContext);
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_CollectionCertStoreContext_RegisterSelf
- * DESCRIPTION:
- *
- * Registers PKIX_PL_COLLECTIONCERTSTORECONTEXT_TYPE and its related
- * functions with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_CollectionCertStoreContext_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
- "pkix_pl_CollectionCertStoreContext_RegisterSelf");
-
- entry.description = "CollectionCertStoreContext";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_CollectionCertStoreContext);
- entry.destructor = pkix_pl_CollectionCertStoreContext_Destroy;
- entry.equalsFunction = pkix_pl_CollectionCertStoreContext_Equals;
- entry.hashcodeFunction = pkix_pl_CollectionCertStoreContext_Hashcode;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_COLLECTIONCERTSTORECONTEXT_TYPE] = entry;
-
- PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
-}
-
-/* --Public-CollectionCertStoreContext-Functions--------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_CollectionCertStore_Create
- * (see comments in pkix_samples_modules.h)
- */
-PKIX_Error *
-PKIX_PL_CollectionCertStore_Create(
- PKIX_PL_String *storeDir,
- PKIX_CertStore **pCertStore,
- void *plContext)
-{
- PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;
- PKIX_CertStore *certStore = NULL;
-
- PKIX_ENTER(CERTSTORE, "PKIX_PL_CollectionCertStore_Create");
- PKIX_NULLCHECK_TWO(storeDir, pCertStore);
-
- PKIX_CHECK(pkix_pl_CollectionCertStoreContext_Create
- (storeDir, &colCertStoreContext, plContext),
- PKIX_COULDNOTCREATECOLLECTIONCERTSTORECONTEXTOBJECT);
-
- PKIX_CHECK(PKIX_CertStore_Create
- (pkix_pl_CollectionCertStore_GetCert,
- pkix_pl_CollectionCertStore_GetCRL,
- NULL, /* GetCertContinue */
- NULL, /* GetCRLContinue */
- pkix_pl_CollectionCertStore_CheckTrust,
- NULL, /* can not store crls */
- NULL, /* can not do revocation check */
- (PKIX_PL_Object *)colCertStoreContext,
- PKIX_TRUE, /* cache flag */
- PKIX_TRUE, /* local - no network I/O */
- &certStore,
- plContext),
- PKIX_CERTSTORECREATEFAILED);
-
- PKIX_DECREF(colCertStoreContext);
-
- *pCertStore = certStore;
-
-cleanup:
- PKIX_RETURN(CERTSTORE);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.h
deleted file mode 100755
index f41e6fa5e..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_colcertstore.h
- *
- * CollectionCertstore Object Type Definition
- *
- */
-
-#ifndef _PKIX_PL_COLCERTSTORE_H
-#define _PKIX_PL_COLCERTSTORE_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_CollectionCertStoreContext {
- PKIX_PL_String *storeDir;
- PKIX_List *crlList;
- PKIX_List *certList;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_CollectionCertStoreContext_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_COLCERTSTORE_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
deleted file mode 100755
index 30aefb817..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c
+++ /dev/null
@@ -1,1147 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_httpcertstore.c
- *
- * HTTPCertStore Function Definitions
- *
- */
-
-/* We can't decode the length of a message without at least this many bytes */
-
-#include "pkix_pl_httpcertstore.h"
-extern PKIX_PL_HashTable *httpSocketCache;
-SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
-SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate)
-
-SEC_ASN1_CHOOSER_DECLARE(CERT_IssuerAndSNTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SECOID_AlgorithmIDTemplate)
-/* SEC_ASN1_CHOOSER_DECLARE(SEC_SetOfAnyTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_SetOfSignedCrlTemplate)
-
-const SEC_ASN1Template CERT_IssuerAndSNTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(CERTIssuerAndSN) },
- { SEC_ASN1_SAVE,
- offsetof(CERTIssuerAndSN,derIssuer) },
- { SEC_ASN1_INLINE,
- offsetof(CERTIssuerAndSN,issuer),
- CERT_NameTemplate },
- { SEC_ASN1_INTEGER,
- offsetof(CERTIssuerAndSN,serialNumber) },
- { 0 }
-};
-
-const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECAlgorithmID) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
-}; */
-
-/* --Private-HttpCertStoreContext-Object Functions----------------------- */
-
-/*
- * FUNCTION: pkix_pl_HttpCertStoreContext_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_HttpCertStoreContext_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
- PKIX_PL_HttpCertStoreContext *context = NULL;
-
- PKIX_ENTER
- (HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStoreContext_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_HTTPCERTSTORECONTEXT_TYPE, plContext),
- PKIX_OBJECTNOTANHTTPCERTSTORECONTEXT);
-
- context = (PKIX_PL_HttpCertStoreContext *)object;
- hcv1 = (const SEC_HttpClientFcnV1 *)(context->client);
- if (context->requestSession != NULL) {
- (*hcv1->freeFcn)(context->requestSession);
- context->requestSession = NULL;
- }
- if (context->serverSession != NULL) {
- (*hcv1->freeSessionFcn)(context->serverSession);
- context->serverSession = NULL;
- }
- if (context->path != NULL) {
- PORT_Free(context->path);
- context->path = NULL;
- }
-
-cleanup:
-
- PKIX_RETURN(HTTPCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpCertStoreContext_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related
- * functions with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_HttpCertStoreContext_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry *entry = &systemClasses[PKIX_HTTPCERTSTORECONTEXT_TYPE];
-
- PKIX_ENTER(HTTPCERTSTORECONTEXT,
- "pkix_pl_HttpCertStoreContext_RegisterSelf");
-
- entry->description = "HttpCertStoreContext";
- entry->typeObjectSize = sizeof(PKIX_PL_HttpCertStoreContext);
- entry->destructor = pkix_pl_HttpCertStoreContext_Destroy;
-
- PKIX_RETURN(HTTPCERTSTORECONTEXT);
-}
-
-
-/* --Private-Http-CertStore-Database-Functions----------------------- */
-
-typedef struct callbackContextStruct {
- PKIX_List *pkixCertList;
- PKIX_Error *error;
- void *plContext;
-} callbackContext;
-
-
-/*
- * FUNCTION: certCallback
- * DESCRIPTION:
- *
- * This function processes the null-terminated array of SECItems produced by
- * extracting the contents of a signedData message received in response to an
- * HTTP cert query. Its address is supplied as a callback function to
- * CERT_DecodeCertPackage; it is not expected to be called directly.
- *
- * Note that it does not conform to the libpkix API standard of returning
- * a PKIX_Error*. It returns a SECStatus.
- *
- * PARAMETERS:
- * "arg"
- * The address of the callbackContext provided as a void* argument to
- * CERT_DecodeCertPackage. Must be non-NULL.
- * "secitemCerts"
- * The address of the null-terminated array of SECItems. Must be non-NULL.
- * "numcerts"
- * The number of SECItems found in the signedData. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns SECSuccess if the function succeeds.
- * Returns SECFailure if the function fails.
- */
-static SECStatus
-certCallback(void *arg, SECItem **secitemCerts, int numcerts)
-{
- callbackContext *cbContext;
- PKIX_List *pkixCertList = NULL;
- PKIX_Error *error = NULL;
- void *plContext = NULL;
- int itemNum = 0;
-
- if ((arg == NULL) || (secitemCerts == NULL)) {
- return (SECFailure);
- }
-
- cbContext = (callbackContext *)arg;
- plContext = cbContext->plContext;
- pkixCertList = cbContext->pkixCertList;
-
- for (; itemNum < numcerts; itemNum++ ) {
- error = pkix_pl_Cert_CreateToList(secitemCerts[itemNum],
- pkixCertList, plContext);
- if (error != NULL) {
- if (error->errClass == PKIX_FATAL_ERROR) {
- cbContext->error = error;
- return SECFailure;
- }
- /* reuse "error" since we could not destruct the old *
- * value */
- error = PKIX_PL_Object_DecRef((PKIX_PL_Object *)error,
- plContext);
- if (error) {
- /* Treat decref failure as a fatal error.
- * In this case will leak error, but can not do
- * anything about it. */
- error->errClass = PKIX_FATAL_ERROR;
- cbContext->error = error;
- return SECFailure;
- }
- }
- }
-
- return SECSuccess;
-}
-
-
-typedef SECStatus (*pkix_DecodeCertsFunc)(char *certbuf, int certlen,
- CERTImportCertificateFunc f, void *arg);
-
-
-struct pkix_DecodeFuncStr {
- pkix_DecodeCertsFunc func; /* function pointer to the
- * CERT_DecodeCertPackage function */
- PRLibrary *smimeLib; /* Pointer to the smime shared lib*/
- PRCallOnceType once;
-};
-
-static struct pkix_DecodeFuncStr pkix_decodeFunc;
-static const PRCallOnceType pkix_pristine;
-
-#define SMIME_LIB_NAME SHLIB_PREFIX"smime3."SHLIB_SUFFIX
-
-/*
- * load the smime library and look up the SEC_ReadPKCS7Certs function.
- * we do this so we don't have a circular depenency on the smime library,
- * and also so we don't have to load the smime library in applications that
- * don't use it.
- */
-static PRStatus PR_CALLBACK pkix_getDecodeFunction(void)
-{
- pkix_decodeFunc.smimeLib =
- PR_LoadLibrary(SHLIB_PREFIX"smime3."SHLIB_SUFFIX);
- if (pkix_decodeFunc.smimeLib == NULL) {
- return PR_FAILURE;
- }
-
- pkix_decodeFunc.func = (pkix_DecodeCertsFunc) PR_FindFunctionSymbol(
- pkix_decodeFunc.smimeLib, "CERT_DecodeCertPackage");
- if (!pkix_decodeFunc.func) {
- return PR_FAILURE;
- }
- return PR_SUCCESS;
-
-}
-
-/*
- * clears our global state on shutdown.
- */
-void
-pkix_pl_HttpCertStore_Shutdown(void *plContext)
-{
- if (pkix_decodeFunc.smimeLib) {
- PR_UnloadLibrary(pkix_decodeFunc.smimeLib);
- pkix_decodeFunc.smimeLib = NULL;
- }
- /* the function pointer just need to be cleared, not freed */
- pkix_decodeFunc.func = NULL;
- pkix_decodeFunc.once = pkix_pristine;
-}
-
-/*
- * This function is based on CERT_DecodeCertPackage from lib/pkcs7/certread.c
- * read an old style ascii or binary certificate chain
- */
-PKIX_Error *
-pkix_pl_HttpCertStore_DecodeCertPackage
- (const char *certbuf,
- int certlen,
- CERTImportCertificateFunc f,
- void *arg,
- void *plContext)
-{
-
- PRStatus status;
- SECStatus rv;
-
- PKIX_ENTER
- (HTTPCERTSTORECONTEXT,
- "pkix_pl_HttpCertStore_DecodeCertPackage");
- PKIX_NULLCHECK_TWO(certbuf, f);
-
- status = PR_CallOnce(&pkix_decodeFunc.once, pkix_getDecodeFunction);
-
- if (status != PR_SUCCESS) {
- PKIX_ERROR(PKIX_CANTLOADLIBSMIME);
- }
-
- /* paranoia, shouldn't happen if status == PR_SUCCESS); */
- if (!pkix_decodeFunc.func) {
- PKIX_ERROR(PKIX_CANTLOADLIBSMIME);
- }
-
- rv = (*pkix_decodeFunc.func)((char*)certbuf, certlen, f, arg);
-
- if (rv != SECSuccess) {
- PKIX_ERROR (PKIX_SECREADPKCS7CERTSFAILED);
- }
-
-
-cleanup:
-
- PKIX_RETURN(HTTPCERTSTORECONTEXT);
-}
-
-
-/*
- * FUNCTION: pkix_pl_HttpCertStore_ProcessCertResponse
- * DESCRIPTION:
- *
- * This function verifies that the response code pointed to by "responseCode"
- * and the content type pointed to by "responseContentType" are as expected,
- * and then decodes the data pointed to by "responseData", of length
- * "responseDataLen", into a List of Certs, possibly empty, which is returned
- * at "pCertList".
- *
- * PARAMETERS:
- * "responseCode"
- * The value of the HTTP response code.
- * "responseContentType"
- * The address of the Content-type string. Must be non-NULL.
- * "responseData"
- * The address of the message data. Must be non-NULL.
- * "responseDataLen"
- * The length of the message data.
- * "pCertList"
- * The address of the List that is created. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpCertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_HttpCertStore_ProcessCertResponse(
- PRUint16 responseCode,
- const char *responseContentType,
- const char *responseData,
- PRUint32 responseDataLen,
- PKIX_List **pCertList,
- void *plContext)
-{
- callbackContext cbContext;
-
- PKIX_ENTER(HTTPCERTSTORECONTEXT,
- "pkix_pl_HttpCertStore_ProcessCertResponse");
-
- cbContext.error = NULL;
- cbContext.plContext = plContext;
- cbContext.pkixCertList = NULL;
-
- PKIX_NULLCHECK_ONE(pCertList);
-
- if (responseCode != 200) {
- PKIX_ERROR(PKIX_BADHTTPRESPONSE);
- }
-
- /* check that response type is application/pkcs7-mime */
- if (responseContentType == NULL) {
- PKIX_ERROR(PKIX_NOCONTENTTYPEINHTTPRESPONSE);
- }
-
- if (responseData == NULL) {
- PKIX_ERROR(PKIX_NORESPONSEDATAINHTTPRESPONSE);
- }
-
- PKIX_CHECK(
- PKIX_List_Create(&cbContext.pkixCertList, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK_ONLY_FATAL(
- pkix_pl_HttpCertStore_DecodeCertPackage(responseData,
- responseDataLen,
- certCallback,
- &cbContext,
- plContext),
- PKIX_HTTPCERTSTOREDECODECERTPACKAGEFAILED);
- if (cbContext.error) {
- /* Aborting on a fatal error(See certCallback fn) */
- pkixErrorResult = cbContext.error;
- goto cleanup;
- }
-
- *pCertList = cbContext.pkixCertList;
- cbContext.pkixCertList = NULL;
-
-cleanup:
-
- PKIX_DECREF(cbContext.pkixCertList);
-
- PKIX_RETURN(HTTPCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpCertStore_ProcessCrlResponse
- * DESCRIPTION:
- *
- * This function verifies that the response code pointed to by "responseCode"
- * and the content type pointed to by "responseContentType" are as expected,
- * and then decodes the data pointed to by "responseData", of length
- * "responseDataLen", into a List of Crls, possibly empty, which is returned
- * at "pCrlList".
- *
- * PARAMETERS:
- * "responseCode"
- * The value of the HTTP response code.
- * "responseContentType"
- * The address of the Content-type string. Must be non-NULL.
- * "responseData"
- * The address of the message data. Must be non-NULL.
- * "responseDataLen"
- * The length of the message data.
- * "pCrlList"
- * The address of the List that is created. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpCertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_HttpCertStore_ProcessCrlResponse(
- PRUint16 responseCode,
- const char *responseContentType,
- const char *responseData,
- PRUint32 responseDataLen,
- PKIX_List **pCrlList,
- void *plContext)
-{
- SECItem encodedResponse;
- PRInt16 compareVal = 0;
- PKIX_List *crls = NULL;
- SECItem *derCrlCopy = NULL;
- CERTSignedCrl *nssCrl = NULL;
- PKIX_PL_CRL *crl = NULL;
-
- PKIX_ENTER(HTTPCERTSTORECONTEXT,
- "pkix_pl_HttpCertStore_ProcessCrlResponse");
- PKIX_NULLCHECK_ONE(pCrlList);
-
- if (responseCode != 200) {
- PKIX_ERROR(PKIX_BADHTTPRESPONSE);
- }
-
- /* check that response type is application/pkix-crl */
- if (responseContentType == NULL) {
- PKIX_ERROR(PKIX_NOCONTENTTYPEINHTTPRESPONSE);
- }
-
- compareVal = PORT_Strcasecmp(responseContentType,
- "application/pkix-crl");
- if (compareVal != 0) {
- PKIX_ERROR(PKIX_CONTENTTYPENOTPKIXCRL);
- }
- encodedResponse.type = siBuffer;
- encodedResponse.data = (void*)responseData;
- encodedResponse.len = responseDataLen;
-
- derCrlCopy = SECITEM_DupItem(&encodedResponse);
- if (!derCrlCopy) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- /* crl will be based on derCrlCopy, but will not own the der. */
- nssCrl =
- CERT_DecodeDERCrlWithFlags(NULL, derCrlCopy, SEC_CRL_TYPE,
- CRL_DECODE_DONT_COPY_DER |
- CRL_DECODE_SKIP_ENTRIES);
- if (!nssCrl) {
- PKIX_ERROR(PKIX_FAILEDTODECODECRL);
- }
- /* pkix crls own the der. */
- PKIX_CHECK(
- pkix_pl_CRL_CreateWithSignedCRL(nssCrl, derCrlCopy, NULL,
- &crl, plContext),
- PKIX_CRLCREATEWITHSIGNEDCRLFAILED);
- /* Left control over memory pointed by derCrlCopy and
- * nssCrl to pkix crl. */
- derCrlCopy = NULL;
- nssCrl = NULL;
- PKIX_CHECK(PKIX_List_Create(&crls, plContext),
- PKIX_LISTCREATEFAILED);
- PKIX_CHECK(PKIX_List_AppendItem
- (crls, (PKIX_PL_Object *) crl, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- *pCrlList = crls;
- crls = NULL;
-cleanup:
- if (derCrlCopy) {
- SECITEM_FreeItem(derCrlCopy, PR_TRUE);
- }
- if (nssCrl) {
- SEC_DestroyCrl(nssCrl);
- }
- PKIX_DECREF(crl);
- PKIX_DECREF(crls);
-
- PKIX_RETURN(HTTPCERTSTORECONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpCertStore_CreateRequestSession
- * DESCRIPTION:
- *
- * This function takes elements from the HttpCertStoreContext pointed to by
- * "context" (path, client, and serverSession) and creates a RequestSession.
- * See the HTTPClient API described in ocspt.h for further details.
- *
- * PARAMETERS:
- * "context"
- * The address of the HttpCertStoreContext. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpCertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_HttpCertStore_CreateRequestSession(
- PKIX_PL_HttpCertStoreContext *context,
- void *plContext)
-{
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
- SECStatus rv = SECFailure;
-
- PKIX_ENTER
- (HTTPCERTSTORECONTEXT,
- "pkix_pl_HttpCertStore_CreateRequestSession");
- PKIX_NULLCHECK_TWO(context, context->serverSession);
-
- if (context->client->version != 1) {
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
- }
-
- hcv1 = &(context->client->fcnTable.ftable1);
- if (context->requestSession != NULL) {
- (*hcv1->freeFcn)(context->requestSession);
- context->requestSession = 0;
- }
-
- rv = (*hcv1->createFcn)(context->serverSession, "http",
- context->path, "GET",
- PR_SecondsToInterval(
- ((PKIX_PL_NssContext*)plContext)->timeoutSeconds),
- &(context->requestSession));
-
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_HTTPSERVERERROR);
- }
-cleanup:
-
- PKIX_RETURN(HTTPCERTSTORECONTEXT);
-
-}
-
-/*
- * FUNCTION: pkix_pl_HttpCertStore_GetCert
- * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
- */
-PKIX_Error *
-pkix_pl_HttpCertStore_GetCert(
- PKIX_CertStore *store,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *verifyNode,
- void **pNBIOContext,
- PKIX_List **pCertList,
- void *plContext)
-{
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
- PKIX_PL_HttpCertStoreContext *context = NULL;
- void *nbioContext = NULL;
- SECStatus rv = SECFailure;
- PRUint16 responseCode = 0;
- const char *responseContentType = NULL;
- const char *responseData = NULL;
- PRUint32 responseDataLen = 0;
- PKIX_List *certList = NULL;
-
- PKIX_ENTER(HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStore_GetCert");
- PKIX_NULLCHECK_THREE(store, selector, pCertList);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (store, (PKIX_PL_Object **)&context, plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- if (context->client->version != 1) {
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
- }
-
- hcv1 = &(context->client->fcnTable.ftable1);
-
- PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
- (context, plContext),
- PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED);
-
- responseDataLen =
- ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
-
- rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
- (PRPollDesc **)&nbioContext,
- &responseCode,
- (const char **)&responseContentType,
- NULL, /* &responseHeaders */
- (const char **)&responseData,
- &responseDataLen);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_HTTPSERVERERROR);
- }
-
- if (nbioContext != 0) {
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
- (responseCode,
- responseContentType,
- responseData,
- responseDataLen,
- &certList,
- plContext),
- PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
-
- *pCertList = certList;
-
-cleanup:
- PKIX_DECREF(context);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpCertStore_GetCertContinue
- * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
- */
-PKIX_Error *
-pkix_pl_HttpCertStore_GetCertContinue(
- PKIX_CertStore *store,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *verifyNode,
- void **pNBIOContext,
- PKIX_List **pCertList,
- void *plContext)
-{
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
- PKIX_PL_HttpCertStoreContext *context = NULL;
- void *nbioContext = NULL;
- SECStatus rv = SECFailure;
- PRUint16 responseCode = 0;
- const char *responseContentType = NULL;
- const char *responseData = NULL;
- PRUint32 responseDataLen = 0;
- PKIX_List *certList = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCertContinue");
- PKIX_NULLCHECK_THREE(store, selector, pCertList);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (store, (PKIX_PL_Object **)&context, plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- if (context->client->version != 1) {
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
- }
-
- hcv1 = &(context->client->fcnTable.ftable1);
- PKIX_NULLCHECK_ONE(context->requestSession);
-
- responseDataLen =
- ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
-
- rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
- (PRPollDesc **)&nbioContext,
- &responseCode,
- (const char **)&responseContentType,
- NULL, /* &responseHeaders */
- (const char **)&responseData,
- &responseDataLen);
-
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_HTTPSERVERERROR);
- }
-
- if (nbioContext != 0) {
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
- (responseCode,
- responseContentType,
- responseData,
- responseDataLen,
- &certList,
- plContext),
- PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
-
- *pCertList = certList;
-
-cleanup:
- PKIX_DECREF(context);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpCertStore_GetCRL
- * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
- */
-PKIX_Error *
-pkix_pl_HttpCertStore_GetCRL(
- PKIX_CertStore *store,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrlList,
- void *plContext)
-{
-
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
- PKIX_PL_HttpCertStoreContext *context = NULL;
- void *nbioContext = NULL;
- SECStatus rv = SECFailure;
- PRUint16 responseCode = 0;
- const char *responseContentType = NULL;
- const char *responseData = NULL;
- PRUint32 responseDataLen = 0;
- PKIX_List *crlList = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCRL");
- PKIX_NULLCHECK_THREE(store, selector, pCrlList);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (store, (PKIX_PL_Object **)&context, plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- if (context->client->version != 1) {
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
- }
-
- hcv1 = &(context->client->fcnTable.ftable1);
- PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
- (context, plContext),
- PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED);
-
- responseDataLen =
- ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
-
- rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
- (PRPollDesc **)&nbioContext,
- &responseCode,
- (const char **)&responseContentType,
- NULL, /* &responseHeaders */
- (const char **)&responseData,
- &responseDataLen);
-
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_HTTPSERVERERROR);
- }
-
- if (nbioContext != 0) {
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCrlResponse
- (responseCode,
- responseContentType,
- responseData,
- responseDataLen,
- &crlList,
- plContext),
- PKIX_HTTPCERTSTOREPROCESSCRLRESPONSEFAILED);
-
- *pCrlList = crlList;
-
-cleanup:
- PKIX_DECREF(context);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpCertStore_GetCRLContinue
- * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
- */
-PKIX_Error *
-pkix_pl_HttpCertStore_GetCRLContinue(
- PKIX_CertStore *store,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrlList,
- void *plContext)
-{
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
- PKIX_PL_HttpCertStoreContext *context = NULL;
- void *nbioContext = NULL;
- SECStatus rv = SECFailure;
- PRUint16 responseCode = 0;
- const char *responseContentType = NULL;
- const char *responseData = NULL;
- PRUint32 responseDataLen = 0;
- PKIX_List *crlList = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCRLContinue");
- PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCrlList);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (store, (PKIX_PL_Object **)&context, plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- if (context->client->version != 1) {
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
- }
- hcv1 = &(context->client->fcnTable.ftable1);
-
- PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
- (context, plContext),
- PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED);
-
- responseDataLen =
- ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
-
- rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
- (PRPollDesc **)&nbioContext,
- &responseCode,
- (const char **)&responseContentType,
- NULL, /* &responseHeaders */
- (const char **)&responseData,
- &responseDataLen);
-
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_HTTPSERVERERROR);
- }
-
- if (nbioContext != 0) {
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCrlResponse
- (responseCode,
- responseContentType,
- responseData,
- responseDataLen,
- &crlList,
- plContext),
- PKIX_HTTPCERTSTOREPROCESSCRLRESPONSEFAILED);
-
- *pCrlList = crlList;
-
-cleanup:
- PKIX_DECREF(context);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/* --Public-HttpCertStore-Functions----------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_HttpCertStore_CreateWithAsciiName
- * DESCRIPTION:
- *
- * This function uses the HttpClient pointed to by "client" and the string
- * (hostname:portnum/path, with portnum optional) pointed to by "locationAscii"
- * to create an HttpCertStore connected to the desired location, storing the
- * created CertStore at "pCertStore".
- *
- * PARAMETERS:
- * "client"
- * The address of the HttpClient. Must be non-NULL.
- * "locationAscii"
- * The address of the character string indicating the hostname, port, and
- * path to be queried for Certs or Crls. Must be non-NULL.
- * "pCertStore"
- * The address in which the object is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpCertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_HttpCertStore_CreateWithAsciiName(
- PKIX_PL_HttpClient *client,
- char *locationAscii,
- PKIX_CertStore **pCertStore,
- void *plContext)
-{
- const SEC_HttpClientFcn *clientFcn = NULL;
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
- PKIX_PL_HttpCertStoreContext *httpCertStore = NULL;
- PKIX_CertStore *certStore = NULL;
- char *hostname = NULL;
- char *path = NULL;
- PRUint16 port = 0;
- SECStatus rv = SECFailure;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_CreateWithAsciiName");
- PKIX_NULLCHECK_TWO(locationAscii, pCertStore);
-
- if (client == NULL) {
- clientFcn = SEC_GetRegisteredHttpClient();
- if (clientFcn == NULL) {
- PKIX_ERROR(PKIX_NOREGISTEREDHTTPCLIENT);
- }
- } else {
- clientFcn = (const SEC_HttpClientFcn *)client;
- }
-
- if (clientFcn->version != 1) {
- PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
- }
-
- /* create a PKIX_PL_HttpCertStore object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_HTTPCERTSTORECONTEXT_TYPE,
- sizeof (PKIX_PL_HttpCertStoreContext),
- (PKIX_PL_Object **)&httpCertStore,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- /* Initialize fields */
- httpCertStore->client = clientFcn; /* not a PKIX object! */
-
- /* parse location -> hostname, port, path */
- rv = CERT_ParseURL(locationAscii, &hostname, &port, &path);
- if (rv == SECFailure || hostname == NULL || path == NULL) {
- PKIX_ERROR(PKIX_URLPARSINGFAILED);
- }
-
- httpCertStore->path = path;
- path = NULL;
-
- hcv1 = &(clientFcn->fcnTable.ftable1);
- rv = (*hcv1->createSessionFcn)(hostname, port,
- &(httpCertStore->serverSession));
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED);
- }
-
- httpCertStore->requestSession = NULL;
-
- PKIX_CHECK(PKIX_CertStore_Create
- (pkix_pl_HttpCertStore_GetCert,
- pkix_pl_HttpCertStore_GetCRL,
- pkix_pl_HttpCertStore_GetCertContinue,
- pkix_pl_HttpCertStore_GetCRLContinue,
- NULL, /* don't support trust */
- NULL, /* can not store crls */
- NULL, /* can not do revocation check */
- (PKIX_PL_Object *)httpCertStore,
- PKIX_TRUE, /* cache flag */
- PKIX_FALSE, /* not local */
- &certStore,
- plContext),
- PKIX_CERTSTORECREATEFAILED);
-
- *pCertStore = certStore;
- certStore = NULL;
-
-cleanup:
- PKIX_DECREF(httpCertStore);
- if (hostname) {
- PORT_Free(hostname);
- }
- if (path) {
- PORT_Free(path);
- }
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: PKIX_PL_HttpCertStore_Create
- * (see comments in pkix_samples_modules.h)
- */
-PKIX_Error *
-PKIX_PL_HttpCertStore_Create(
- PKIX_PL_HttpClient *client,
- PKIX_PL_GeneralName *location,
- PKIX_CertStore **pCertStore,
- void *plContext)
-{
- PKIX_PL_String *locationString = NULL;
- char *locationAscii = NULL;
- PKIX_UInt32 len = 0;
-
- PKIX_ENTER(CERTSTORE, "PKIX_PL_HttpCertStore_Create");
- PKIX_NULLCHECK_TWO(location, pCertStore);
-
- PKIX_TOSTRING(location, &locationString, plContext,
- PKIX_GENERALNAMETOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (locationString,
- PKIX_ESCASCII,
- (void **)&locationAscii,
- &len,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_CHECK(pkix_pl_HttpCertStore_CreateWithAsciiName
- (client, locationAscii, pCertStore, plContext),
- PKIX_HTTPCERTSTORECREATEWITHASCIINAMEFAILED);
-
-cleanup:
-
- PKIX_DECREF(locationString);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_HttpCertStore_FindSocketConnection
- * DESCRIPTION:
- *
- PRIntervalTime timeout,
- char *hostname,
- PRUint16 portnum,
- PRErrorCode *pStatus,
- PKIX_PL_Socket **pSocket,
-
- * This function checks for an existing socket, creating a new one if unable
- * to find an existing one, for the host pointed to by "hostname" and the port
- * pointed to by "portnum". If a new socket is created the PRIntervalTime in
- * "timeout" will be used for the timeout value and a creation status is
- * returned at "pStatus". The address of the socket is stored at "pSocket".
- *
- * PARAMETERS:
- * "timeout"
- * The PRIntervalTime of the timeout value.
- * "hostname"
- * The address of the string containing the hostname. Must be non-NULL.
- * "portnum"
- * The port number for the desired socket.
- * "pStatus"
- * The address at which the status is stored. Must be non-NULL.
- * "pSocket"
- * The address at which the socket is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpCertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_HttpCertStore_FindSocketConnection(
- PRIntervalTime timeout,
- char *hostname,
- PRUint16 portnum,
- PRErrorCode *pStatus,
- PKIX_PL_Socket **pSocket,
- void *plContext)
-{
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *hostString = NULL;
- PKIX_PL_String *domainString = NULL;
- PKIX_PL_Socket *socket = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_HttpCertStore_FindSocketConnection");
- PKIX_NULLCHECK_THREE(hostname, pStatus, pSocket);
-
- *pStatus = 0;
-
- /* create PKIX_PL_String from hostname and port */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "%s:%d", 0, &formatString, plContext),
- PKIX_STRINGCREATEFAILED);
-
-#if 0
-hostname = "variation.red.iplanet.com";
-portnum = 2001;
-#endif
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, hostname, 0, &hostString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&domainString, plContext, formatString, hostString, portnum),
- PKIX_STRINGCREATEFAILED);
-
-#ifdef PKIX_SOCKETCACHE
- /* Is this domainName already in cache? */
- PKIX_CHECK(PKIX_PL_HashTable_Lookup
- (httpSocketCache,
- (PKIX_PL_Object *)domainString,
- (PKIX_PL_Object **)&socket,
- plContext),
- PKIX_HASHTABLELOOKUPFAILED);
-#endif
- if (socket == NULL) {
-
- /* No, create a connection (and cache it) */
- PKIX_CHECK(pkix_pl_Socket_CreateByHostAndPort
- (PKIX_FALSE, /* create a client, not a server */
- timeout,
- hostname,
- portnum,
- pStatus,
- &socket,
- plContext),
- PKIX_SOCKETCREATEBYHOSTANDPORTFAILED);
-
-#ifdef PKIX_SOCKETCACHE
- PKIX_CHECK(PKIX_PL_HashTable_Add
- (httpSocketCache,
- (PKIX_PL_Object *)domainString,
- (PKIX_PL_Object *)socket,
- plContext),
- PKIX_HASHTABLEADDFAILED);
-#endif
- }
-
- *pSocket = socket;
- socket = NULL;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(hostString);
- PKIX_DECREF(domainString);
- PKIX_DECREF(socket);
-
- PKIX_RETURN(CERTSTORE);
-}
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h
deleted file mode 100644
index a03ea94d8..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_httpcertstore.h
- *
- * HTTPCertstore Object Type Definition
- *
- */
-
-#ifndef _PKIX_PL_HTTPCERTSTORE_H
-#define _PKIX_PL_HTTPCERTSTORE_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_HttpCertStoreContextStruct {
- const SEC_HttpClientFcn *client;
- SEC_HTTP_SERVER_SESSION serverSession;
- SEC_HTTP_REQUEST_SESSION requestSession;
- char *path;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_HttpCertStoreContext_RegisterSelf(void *plContext);
-
-void pkix_pl_HttpCertStore_Shutdown(void *plContext);
-
-PKIX_Error *
-pkix_pl_HttpCertStore_CreateWithAsciiName(
- PKIX_PL_HttpClient *client,
- char *locationAscii,
- PKIX_CertStore **pCertStore,
- void *plContext);
-
-PKIX_Error *
-pkix_HttpCertStore_FindSocketConnection(
- PRIntervalTime timeout,
- char *hostname,
- PRUint16 portnum,
- PRErrorCode *pStatus,
- PKIX_PL_Socket **pSocket,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_HttpCertStore_ProcessCertResponse(
- PRUint16 responseCode,
- const char *responseContentType,
- const char *responseData,
- PRUint32 responseDataLen,
- PKIX_List **pCertList,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_HTTPCERTSTORE_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
deleted file mode 100644
index 697151548..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
+++ /dev/null
@@ -1,1662 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_httpdefaultclient.c
- *
- * HTTPDefaultClient Function Definitions
- *
- */
-
-#include "pkix_pl_httpdefaultclient.h"
-
-static void *plContext = NULL;
-
-/*
- * The interface specification for an http client requires that it register
- * a function table of type SEC_HttpClientFcn, which is defined as a union
- * of tables, of which only version 1 is defined at present.
- *
- * Note: these functions violate the PKIX calling conventions, in that they
- * return SECStatus rather than PKIX_Error*, and that they do not provide a
- * plContext argument. They are implemented here as calls to PKIX functions,
- * but the plContext value is circularly defined - a true kludge. Its value
- * is saved at the time of the call to pkix_pl_HttpDefaultClient_Create for
- * subsequent use, but since that initial call comes from the
- * pkix_pl_HttpDefaultClient_CreateSessionFcn, it's not really getting saved.
- */
-static SEC_HttpClientFcnV1 vtable = {
- pkix_pl_HttpDefaultClient_CreateSessionFcn,
- pkix_pl_HttpDefaultClient_KeepAliveSessionFcn,
- pkix_pl_HttpDefaultClient_FreeSessionFcn,
- pkix_pl_HttpDefaultClient_RequestCreateFcn,
- pkix_pl_HttpDefaultClient_SetPostDataFcn,
- pkix_pl_HttpDefaultClient_AddHeaderFcn,
- pkix_pl_HttpDefaultClient_TrySendAndReceiveFcn,
- pkix_pl_HttpDefaultClient_CancelFcn,
- pkix_pl_HttpDefaultClient_FreeFcn
-};
-
-static SEC_HttpClientFcn httpClient;
-
-static const char *eohMarker = "\r\n\r\n";
-static const PKIX_UInt32 eohMarkLen = 4; /* strlen(eohMarker) */
-static const char *crlf = "\r\n";
-static const PKIX_UInt32 crlfLen = 2; /* strlen(crlf) */
-static const char *httpprotocol = "HTTP/";
-static const PKIX_UInt32 httpprotocolLen = 5; /* strlen(httpprotocol) */
-
-
-#define HTTP_UNKNOWN_CONTENT_LENGTH -1
-
-/* --Private-HttpDefaultClient-Functions------------------------- */
-
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_HdrCheckComplete
- * DESCRIPTION:
- *
- * This function determines whether the headers in the current receive buffer
- * in the HttpDefaultClient pointed to by "client" are complete. If so, the
- * input data is checked for status code, content-type and content-length are
- * extracted, and the client is set up to read the body of the response.
- * Otherwise, the client is set up to continue reading header data.
- *
- * PARAMETERS:
- * "client"
- * The address of the HttpDefaultClient object. Must be non-NULL.
- * "bytesRead"
- * The UInt32 number of bytes received in the latest read.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_HdrCheckComplete(
- PKIX_PL_HttpDefaultClient *client,
- PKIX_UInt32 bytesRead,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_UInt32 alreadyScanned = 0;
- PKIX_UInt32 comp = 0;
- PKIX_UInt32 headerLength = 0;
- PKIX_Int32 contentLength = HTTP_UNKNOWN_CONTENT_LENGTH;
- char *eoh = NULL;
- char *statusLineEnd = NULL;
- char *space = NULL;
- char *nextHeader = NULL;
- const char *httpcode = NULL;
- char *thisHeaderEnd = NULL;
- char *value = NULL;
- char *colon = NULL;
- char *copy = NULL;
- char *body = NULL;
-
- PKIX_ENTER
- (HTTPDEFAULTCLIENT,
- "pkix_pl_HttpDefaultClient_HdrCheckComplete");
- PKIX_NULLCHECK_TWO(client, pKeepGoing);
-
- *pKeepGoing = PKIX_FALSE;
-
- /* Does buffer contain end-of-header marker? */
-
- /* Copy number of scanned bytes into a variable. */
- alreadyScanned = client->filledupBytes;
- /*
- * If this is the initial buffer, we have to scan from the beginning.
- * If we scanned, failed to find eohMarker, and read some more, we
- * only have to scan from where we left off.
- */
- if (alreadyScanned > eohMarkLen) {
- /* Back up and restart scanning over a few bytes that were
- * scanned before */
- PKIX_UInt32 searchStartPos = alreadyScanned - eohMarkLen;
- eoh = PL_strnstr(&(client->rcvBuf[searchStartPos]), eohMarker,
- bytesRead + searchStartPos);
- } else {
- /* A search from the beginning of the buffer. */
- eoh = PL_strnstr(client->rcvBuf, eohMarker, bytesRead);
- }
-
- client->filledupBytes += bytesRead;
-
- if (eoh == NULL) { /* did we see end-of-header? */
- /* No. Continue to read header data */
- client->connectStatus = HTTP_RECV_HDR;
- *pKeepGoing = PKIX_TRUE;
- goto cleanup;
- }
-
- /* Yes. Calculate how many bytes in header (not counting eohMarker) */
- headerLength = (eoh - client->rcvBuf);
-
- /* allocate space to copy header (and for the NULL terminator) */
- PKIX_CHECK(PKIX_PL_Malloc(headerLength + 1, (void **)&copy, plContext),
- PKIX_MALLOCFAILED);
-
- /* copy header data before we corrupt it (by storing NULLs) */
- PORT_Memcpy(copy, client->rcvBuf, headerLength);
- /* Store the NULL terminator */
- copy[headerLength] = '\0';
- client->rcvHeaders = copy;
-
- /* Did caller want a pointer to header? */
- if (client->rcv_http_headers != NULL) {
- /* store pointer for caller */
- *(client->rcv_http_headers) = copy;
- }
-
- /* Check that message status is okay. */
- statusLineEnd = PL_strnstr(client->rcvBuf, crlf, client->capacity);
- if (statusLineEnd == NULL) {
- client->connectStatus = HTTP_ERROR;
- PORT_SetError(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
- goto cleanup;
- }
-
- *statusLineEnd = '\0';
-
- space = strchr((const char *)client->rcvBuf, ' ');
- if (space == NULL) {
- client->connectStatus = HTTP_ERROR;
- goto cleanup;
- }
-
- comp = PORT_Strncasecmp((const char *)client->rcvBuf, httpprotocol,
- httpprotocolLen);
- if (comp != 0) {
- client->connectStatus = HTTP_ERROR;
- goto cleanup;
- }
-
- httpcode = space + 1;
- space = strchr(httpcode, ' ');
- if (space == NULL) {
- client->connectStatus = HTTP_ERROR;
- goto cleanup;
- }
- *space = '\0';
-
- client->responseCode = atoi(httpcode);
- if (client->responseCode != 200) {
- client->connectStatus = HTTP_ERROR;
- goto cleanup;
- }
-
- /* Find the content-type and content-length */
- nextHeader = statusLineEnd + crlfLen;
- *eoh = '\0';
- do {
- thisHeaderEnd = NULL;
- value = NULL;
-
- colon = strchr(nextHeader, ':');
- if (colon == NULL) {
- client->connectStatus = HTTP_ERROR;
- goto cleanup;
- }
- *colon = '\0';
- value = colon + 1;
- if (*value != ' ') {
- client->connectStatus = HTTP_ERROR;
- goto cleanup;
- }
- value++;
- thisHeaderEnd = strstr(value, crlf);
- if (thisHeaderEnd != NULL) {
- *thisHeaderEnd = '\0';
- }
- comp = PORT_Strcasecmp(nextHeader, "content-type");
- if (comp == 0) {
- client->rcvContentType = PORT_Strdup(value);
- } else {
- comp = PORT_Strcasecmp(nextHeader, "content-length");
- if (comp == 0) {
- contentLength = atoi(value);
- }
- }
- if (thisHeaderEnd != NULL) {
- nextHeader = thisHeaderEnd + crlfLen;
- } else {
- nextHeader = NULL;
- }
- } while ((nextHeader != NULL) && (nextHeader < (eoh + crlfLen)));
-
- /* Did caller provide a pointer to return content-type? */
- if (client->rcv_http_content_type != NULL) {
- *(client->rcv_http_content_type) = client->rcvContentType;
- }
-
- if (client->rcvContentType == NULL) {
- client->connectStatus = HTTP_ERROR;
- goto cleanup;
- }
-
- /* How many bytes remain in current buffer, beyond the header? */
- headerLength += eohMarkLen;
- client->filledupBytes -= headerLength;
-
- /*
- * The headers have passed validation. Now figure out whether the
- * message is within the caller's size limit (if one was specified).
- */
- switch (contentLength) {
- case 0:
- client->rcv_http_data_len = 0;
- client->connectStatus = HTTP_COMPLETE;
- *pKeepGoing = PKIX_FALSE;
- break;
-
- case HTTP_UNKNOWN_CONTENT_LENGTH:
- /* Unknown contentLength indicator.Will be set by
- * pkix_pl_HttpDefaultClient_RecvBody whey connection get closed */
- client->rcv_http_data_len = HTTP_UNKNOWN_CONTENT_LENGTH;
- contentLength = /* Try to reserve 4K+ buffer */
- client->filledupBytes + HTTP_DATA_BUFSIZE;
- if (client->maxResponseLen > 0 &&
- contentLength > client->maxResponseLen) {
- if (client->filledupBytes < client->maxResponseLen) {
- contentLength = client->maxResponseLen;
- } else {
- client->connectStatus = HTTP_ERROR;
- goto cleanup;
- }
- }
- /* set available number of bytes in the buffer */
- client->capacity = contentLength;
- client->connectStatus = HTTP_RECV_BODY;
- *pKeepGoing = PKIX_TRUE;
- break;
-
- default:
- client->rcv_http_data_len = contentLength;
- if (client->maxResponseLen > 0 &&
- client->maxResponseLen < contentLength) {
- client->connectStatus = HTTP_ERROR;
- goto cleanup;
- }
-
- /*
- * Do we have all of the message body, or do we need to read some more?
- */
- if (client->filledupBytes < contentLength) {
- client->connectStatus = HTTP_RECV_BODY;
- *pKeepGoing = PKIX_TRUE;
- } else {
- client->connectStatus = HTTP_COMPLETE;
- *pKeepGoing = PKIX_FALSE;
- }
- }
-
- if (contentLength > 0) {
- /* allocate a buffer of size contentLength for the content */
- PKIX_CHECK(PKIX_PL_Malloc(contentLength, (void **)&body, plContext),
- PKIX_MALLOCFAILED);
-
- /* copy any remaining bytes in current buffer into new buffer */
- if (client->filledupBytes > 0) {
- PORT_Memcpy(body, &(client->rcvBuf[headerLength]),
- client->filledupBytes);
- }
- }
-
- PKIX_CHECK(PKIX_PL_Free(client->rcvBuf, plContext),
- PKIX_FREEFAILED);
- client->rcvBuf = body;
-
-cleanup:
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: PKIX_PL_HttpDefaultClient_Create
- * DESCRIPTION:
- *
- * This function creates a new HttpDefaultClient, and stores the result at
- * "pClient".
- *
- * The HttpClient API does not include a plContext argument in its
- * function calls. Its value at the time of this Create call must be the
- * same as when the client is invoked.
- *
- * PARAMETERS:
- * "host"
- * The name of the server with which we hope to exchange messages. Must
- * be non-NULL.
- * "portnum"
- * The port number to be used for our connection to the server.
- * "pClient"
- * The address at which the created HttpDefaultClient is to be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpDefaultClient Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_Create(
- const char *host,
- PRUint16 portnum,
- PKIX_PL_HttpDefaultClient **pClient,
- void *plContext)
-{
- PKIX_PL_HttpDefaultClient *client = NULL;
-
- PKIX_ENTER(HTTPDEFAULTCLIENT, "PKIX_PL_HttpDefaultClient_Create");
- PKIX_NULLCHECK_TWO(pClient, host);
-
- /* allocate an HttpDefaultClient */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_HTTPDEFAULTCLIENT_TYPE,
- sizeof (PKIX_PL_HttpDefaultClient),
- (PKIX_PL_Object **)&client,
- plContext),
- PKIX_COULDNOTCREATEHTTPDEFAULTCLIENTOBJECT);
-
- /* Client timeout is overwritten in HttpDefaultClient_RequestCreate
- * function. Default value will be ignored. */
- client->timeout = 0;
- client->connectStatus = HTTP_NOT_CONNECTED;
- client->portnum = portnum;
- client->bytesToWrite = 0;
- client->send_http_data_len = 0;
- client->rcv_http_data_len = 0;
- client->capacity = 0;
- client->filledupBytes = 0;
- client->responseCode = 0;
- client->maxResponseLen = 0;
- client->GETLen = 0;
- client->POSTLen = 0;
- client->pRcv_http_data_len = NULL;
- client->callbackList = NULL;
- client->GETBuf = NULL;
- client->POSTBuf = NULL;
- client->rcvBuf = NULL;
- /* "host" is a parsing result by CERT_GetURL function that adds
- * "end of line" to the value. OK to dup the string. */
- client->host = PORT_Strdup(host);
- if (!client->host) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- client->path = NULL;
- client->rcvContentType = NULL;
- client->rcvHeaders = NULL;
- client->send_http_method = HTTP_POST_METHOD;
- client->send_http_content_type = NULL;
- client->send_http_data = NULL;
- client->rcv_http_response_code = NULL;
- client->rcv_http_content_type = NULL;
- client->rcv_http_headers = NULL;
- client->rcv_http_data = NULL;
- client->socket = NULL;
-
- /*
- * The HttpClient API does not include a plContext argument in its
- * function calls. Save it here.
- */
- client->plContext = plContext;
-
- *pClient = client;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(client);
- }
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_HttpDefaultClient *client = NULL;
-
- PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_HTTPDEFAULTCLIENT_TYPE, plContext),
- PKIX_OBJECTNOTANHTTPDEFAULTCLIENT);
-
- client = (PKIX_PL_HttpDefaultClient *)object;
-
- if (client->rcvHeaders) {
- PKIX_PL_Free(client->rcvHeaders, plContext);
- client->rcvHeaders = NULL;
- }
- if (client->rcvContentType) {
- PORT_Free(client->rcvContentType);
- client->rcvContentType = NULL;
- }
- if (client->GETBuf != NULL) {
- PR_smprintf_free(client->GETBuf);
- client->GETBuf = NULL;
- }
- if (client->POSTBuf != NULL) {
- PKIX_PL_Free(client->POSTBuf, plContext);
- client->POSTBuf = NULL;
- }
- if (client->rcvBuf != NULL) {
- PKIX_PL_Free(client->rcvBuf, plContext);
- client->rcvBuf = NULL;
- }
- if (client->host) {
- PORT_Free(client->host);
- client->host = NULL;
- }
- if (client->path) {
- PORT_Free(client->path);
- client->path = NULL;
- }
- PKIX_DECREF(client->socket);
-
-cleanup:
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_PL_HTTPDEFAULTCLIENT_TYPE and its related
- * functions with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_HttpDefaultClient_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry *entry =
- &systemClasses[PKIX_HTTPDEFAULTCLIENT_TYPE];
-
- PKIX_ENTER(HTTPDEFAULTCLIENT,
- "pkix_pl_HttpDefaultClient_RegisterSelf");
-
- entry->description = "HttpDefaultClient";
- entry->typeObjectSize = sizeof(PKIX_PL_HttpDefaultClient);
- entry->destructor = pkix_pl_HttpDefaultClient_Destroy;
-
- httpClient.version = 1;
- httpClient.fcnTable.ftable1 = vtable;
- (void)SEC_RegisterDefaultHttpClient(&httpClient);
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/* --Private-HttpDefaultClient-I/O-Functions---------------------------- */
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_ConnectContinue
- * DESCRIPTION:
- *
- * This function determines whether a socket Connect initiated earlier for the
- * HttpDefaultClient "client" has completed, and stores in "pKeepGoing" a flag
- * indicating whether processing can continue without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the HttpDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_ConnectContinue(
- PKIX_PL_HttpDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PRErrorCode status;
- PKIX_Boolean keepGoing = PKIX_FALSE;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER
- (HTTPDEFAULTCLIENT,
- "pkix_pl_HttpDefaultClient_ConnectContinue");
- PKIX_NULLCHECK_ONE(client);
-
- callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
-
- PKIX_CHECK(callbackList->connectcontinueCallback
- (client->socket, &status, plContext),
- PKIX_SOCKETCONNECTCONTINUEFAILED);
-
- if (status == 0) {
- client->connectStatus = HTTP_CONNECTED;
- keepGoing = PKIX_TRUE;
- } else if (status != PR_IN_PROGRESS_ERROR) {
- PKIX_ERROR(PKIX_UNEXPECTEDERRORINESTABLISHINGCONNECTION);
- }
-
- *pKeepGoing = keepGoing;
-
-cleanup:
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_Send
- * DESCRIPTION:
- *
- * This function creates and sends HTTP-protocol headers and, if applicable,
- * data, for the HttpDefaultClient "client", and stores in "pKeepGoing" a flag
- * indicating whether processing can continue without further input, and at
- * "pBytesTransferred" the number of bytes sent.
- *
- * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
- * and that transmission has not completed.
- *
- * PARAMETERS:
- * "client"
- * The address of the HttpDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "pBytesTransferred"
- * The address at which the number of bytes sent is stored. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_Send(
- PKIX_PL_HttpDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- PKIX_UInt32 *pBytesTransferred,
- void *plContext)
-{
- PKIX_Int32 bytesWritten = 0;
- PKIX_Int32 lenToWrite = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
- char *dataToWrite = NULL;
-
- PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Send");
- PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);
-
- *pKeepGoing = PKIX_FALSE;
-
- /* Do we have anything waiting to go? */
- if ((client->GETBuf) || (client->POSTBuf)) {
-
- if (client->GETBuf) {
- dataToWrite = client->GETBuf;
- lenToWrite = client->GETLen;
- } else {
- dataToWrite = client->POSTBuf;
- lenToWrite = client->POSTLen;
- }
-
- callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
-
- PKIX_CHECK(callbackList->sendCallback
- (client->socket,
- dataToWrite,
- lenToWrite,
- &bytesWritten,
- plContext),
- PKIX_SOCKETSENDFAILED);
-
- client->rcvBuf = NULL;
- client->capacity = 0;
- client->filledupBytes = 0;
-
- /*
- * If the send completed we can proceed to try for the
- * response. If the send did not complete we will have
- * to poll for completion later.
- */
- if (bytesWritten >= 0) {
- client->connectStatus = HTTP_RECV_HDR;
- *pKeepGoing = PKIX_TRUE;
- } else {
- client->connectStatus = HTTP_SEND_PENDING;
- *pKeepGoing = PKIX_FALSE;
- }
-
- }
-
- *pBytesTransferred = bytesWritten;
-
-cleanup:
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_SendContinue
- * DESCRIPTION:
- *
- * This function determines whether the sending of the HTTP message for the
- * HttpDefaultClient "client" has completed, and stores in "pKeepGoing" a
- * flag indicating whether processing can continue without further input, and
- * at "pBytesTransferred" the number of bytes sent.
- *
- * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
- * and that transmission has not completed.
- *
- * PARAMETERS:
- * "client"
- * The address of the HttpDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "pBytesTransferred"
- * The address at which the number of bytes sent is stored. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_SendContinue(
- PKIX_PL_HttpDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- PKIX_UInt32 *pBytesTransferred,
- void *plContext)
-{
- PKIX_Int32 bytesWritten = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_SendContinue");
- PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);
-
- *pKeepGoing = PKIX_FALSE;
-
- callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
-
- PKIX_CHECK(callbackList->pollCallback
- (client->socket, &bytesWritten, NULL, plContext),
- PKIX_SOCKETPOLLFAILED);
-
- /*
- * If the send completed we can proceed to try for the
- * response. If the send did not complete we will have
- * continue to poll.
- */
- if (bytesWritten >= 0) {
- client->connectStatus = HTTP_RECV_HDR;
- *pKeepGoing = PKIX_TRUE;
- }
-
- *pBytesTransferred = bytesWritten;
-
-cleanup:
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_RecvHdr
- * DESCRIPTION:
- *
- * This function receives HTTP headers for the HttpDefaultClient "client", and
- * stores in "pKeepGoing" a flag indicating whether processing can continue
- * without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the HttpDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_RecvHdr(
- PKIX_PL_HttpDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_UInt32 bytesToRead = 0;
- PKIX_Int32 bytesRead = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_RecvHdr");
- PKIX_NULLCHECK_TWO(client, pKeepGoing);
-
- /*
- * rcvbuf, capacity, and filledupBytes were
- * initialized when we wrote the headers. We begin by reading
- * HTTP_HEADER_BUFSIZE bytes, repeatedly increasing the buffersize and
- * reading again if necessary, until we have read the end-of-header
- * marker, "\r\n\r\n", or have reached our maximum.
- */
- client->capacity += HTTP_HEADER_BUFSIZE;
- PKIX_CHECK(PKIX_PL_Realloc
- (client->rcvBuf,
- client->capacity,
- (void **)&(client->rcvBuf),
- plContext),
- PKIX_REALLOCFAILED);
-
- bytesToRead = client->capacity - client->filledupBytes;
-
- callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
-
- PKIX_CHECK(callbackList->recvCallback
- (client->socket,
- (void *)&(client->rcvBuf[client->filledupBytes]),
- bytesToRead,
- &bytesRead,
- plContext),
- PKIX_SOCKETRECVFAILED);
-
- if (bytesRead > 0) {
- /* client->filledupBytes will be adjusted by
- * pkix_pl_HttpDefaultClient_HdrCheckComplete */
- PKIX_CHECK(
- pkix_pl_HttpDefaultClient_HdrCheckComplete(client, bytesRead,
- pKeepGoing,
- plContext),
- PKIX_HTTPDEFAULTCLIENTHDRCHECKCOMPLETEFAILED);
- } else {
- client->connectStatus = HTTP_RECV_HDR_PENDING;
- *pKeepGoing = PKIX_FALSE;
- }
-
-cleanup:
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_RecvHdrContinue
- * DESCRIPTION:
- *
- * This function determines whether the receiving of the HTTP headers for the
- * HttpDefaultClient "client" has completed, and stores in "pKeepGoing" a flag
- * indicating whether processing can continue without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the HttpDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_RecvHdrContinue(
- PKIX_PL_HttpDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_Int32 bytesRead = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER
- (HTTPDEFAULTCLIENT,
- "pkix_pl_HttpDefaultClient_RecvHdrContinue");
- PKIX_NULLCHECK_TWO(client, pKeepGoing);
-
- callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
-
- PKIX_CHECK(callbackList->pollCallback
- (client->socket, NULL, &bytesRead, plContext),
- PKIX_SOCKETPOLLFAILED);
-
- if (bytesRead > 0) {
- client->filledupBytes += bytesRead;
-
- PKIX_CHECK(pkix_pl_HttpDefaultClient_HdrCheckComplete
- (client, bytesRead, pKeepGoing, plContext),
- PKIX_HTTPDEFAULTCLIENTHDRCHECKCOMPLETEFAILED);
-
- } else {
-
- *pKeepGoing = PKIX_FALSE;
-
- }
-
-cleanup:
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_RecvBody
- * DESCRIPTION:
- *
- * This function processes the contents of the first buffer of a received
- * HTTP-protocol message for the HttpDefaultClient "client", and stores in
- * "pKeepGoing" a flag indicating whether processing can continue without
- * further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the HttpDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_RecvBody(
- PKIX_PL_HttpDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_Int32 bytesRead = 0;
- PKIX_Int32 bytesToRead = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_RecvBody");
- PKIX_NULLCHECK_TWO(client, pKeepGoing);
-
- callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
-
- if (client->rcv_http_data_len != HTTP_UNKNOWN_CONTENT_LENGTH) {
- bytesToRead = client->rcv_http_data_len -
- client->filledupBytes;
- } else {
- /* Reading till the EOF. Context length is not known.*/
- /* Check the buffer capacity: increase and
- * reallocate if it is low. */
- int freeBuffSize = client->capacity - client->filledupBytes;
- if (freeBuffSize < HTTP_MIN_AVAILABLE_BUFFER_SIZE) {
- /* New length will be consist of available(downloaded) bytes,
- * plus remaining capacity, plus new expansion. */
- int currBuffSize = client->capacity;
- /* Try to increase the buffer by 4K */
- int newLength = currBuffSize + HTTP_DATA_BUFSIZE;
- if (client->maxResponseLen > 0 &&
- newLength > client->maxResponseLen) {
- newLength = client->maxResponseLen;
- }
- /* Check if we can grow the buffer and report an error if
- * new size is not larger than the current size of the buffer.*/
- if (newLength <= client->filledupBytes) {
- client->rcv_http_data_len = client->filledupBytes;
- client->connectStatus = HTTP_ERROR;
- *pKeepGoing = PKIX_FALSE;
- goto cleanup;
- }
- if (client->capacity < newLength) {
- client->capacity = newLength;
- PKIX_CHECK(
- PKIX_PL_Realloc(client->rcvBuf, newLength,
- (void**)&client->rcvBuf, plContext),
- PKIX_REALLOCFAILED);
- freeBuffSize = client->capacity -
- client->filledupBytes;
- }
- }
- bytesToRead = freeBuffSize;
- }
-
- /* Use poll callback if waiting on non-blocking IO */
- if (client->connectStatus == HTTP_RECV_BODY_PENDING) {
- PKIX_CHECK(callbackList->pollCallback
- (client->socket, NULL, &bytesRead, plContext),
- PKIX_SOCKETPOLLFAILED);
- } else {
- PKIX_CHECK(callbackList->recvCallback
- (client->socket,
- (void *)&(client->rcvBuf[client->filledupBytes]),
- bytesToRead,
- &bytesRead,
- plContext),
- PKIX_SOCKETRECVFAILED);
- }
-
- /* If bytesRead < 0, an error will be thrown by recvCallback, so
- * need to handle >= 0 cases. */
-
- /* bytesRead == 0 - IO was blocked. */
- if (bytesRead == 0) {
- client->connectStatus = HTTP_RECV_BODY_PENDING;
- *pKeepGoing = PKIX_TRUE;
- goto cleanup;
- }
-
- /* We got something. Did we get it all? */
- client->filledupBytes += bytesRead;
-
- /* continue if not enough bytes read or if complete size of
- * transfer is unknown */
- if (bytesToRead > bytesRead ||
- client->rcv_http_data_len == HTTP_UNKNOWN_CONTENT_LENGTH) {
- *pKeepGoing = PKIX_TRUE;
- goto cleanup;
- }
- client->connectStatus = HTTP_COMPLETE;
- *pKeepGoing = PKIX_FALSE;
-
-cleanup:
- if (pkixErrorResult && pkixErrorResult->errCode ==
- PKIX_PRRECVREPORTSNETWORKCONNECTIONCLOSED) {
- if (client->rcv_http_data_len == HTTP_UNKNOWN_CONTENT_LENGTH) {
- client->rcv_http_data_len = client->filledupBytes;
- client->connectStatus = HTTP_COMPLETE;
- *pKeepGoing = PKIX_FALSE;
- PKIX_DECREF(pkixErrorResult);
- } else {
- client->connectStatus = HTTP_ERROR;
- }
- }
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_HttpDefaultClient_Dispatch
- * DESCRIPTION:
- *
- * This function is the state machine dispatcher for the HttpDefaultClient
- * pointed to by "client". Results are returned by changes to various fields
- * in the context.
- *
- * PARAMETERS:
- * "client"
- * The address of the HttpDefaultClient object. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HttpDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_HttpDefaultClient_Dispatch(
- PKIX_PL_HttpDefaultClient *client,
- void *plContext)
-{
- PKIX_UInt32 bytesTransferred = 0;
- PKIX_Boolean keepGoing = PKIX_TRUE;
-
- PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Dispatch");
- PKIX_NULLCHECK_ONE(client);
-
- while (keepGoing) {
- switch (client->connectStatus) {
- case HTTP_CONNECT_PENDING:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_ConnectContinue
- (client, &keepGoing, plContext),
- PKIX_HTTPDEFAULTCLIENTCONNECTCONTINUEFAILED);
- break;
- case HTTP_CONNECTED:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_Send
- (client, &keepGoing, &bytesTransferred, plContext),
- PKIX_HTTPDEFAULTCLIENTSENDFAILED);
- break;
- case HTTP_SEND_PENDING:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_SendContinue
- (client, &keepGoing, &bytesTransferred, plContext),
- PKIX_HTTPDEFAULTCLIENTSENDCONTINUEFAILED);
- break;
- case HTTP_RECV_HDR:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvHdr
- (client, &keepGoing, plContext),
- PKIX_HTTPDEFAULTCLIENTRECVHDRFAILED);
- break;
- case HTTP_RECV_HDR_PENDING:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvHdrContinue
- (client, &keepGoing, plContext),
- PKIX_HTTPDEFAULTCLIENTRECVHDRCONTINUEFAILED);
- break;
- case HTTP_RECV_BODY:
- case HTTP_RECV_BODY_PENDING:
- PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvBody
- (client, &keepGoing, plContext),
- PKIX_HTTPDEFAULTCLIENTRECVBODYFAILED);
- break;
- case HTTP_ERROR:
- case HTTP_COMPLETE:
- keepGoing = PKIX_FALSE;
- break;
- case HTTP_NOT_CONNECTED:
- default:
- PKIX_ERROR(PKIX_HTTPDEFAULTCLIENTINILLEGALSTATE);
- }
- }
-
-cleanup:
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-}
-
-/*
- * --HttpClient vtable functions
- * See comments in ocspt.h for the function (wrappers) that return SECStatus.
- * The functions that return PKIX_Error* are the libpkix implementations.
- */
-
-PKIX_Error *
-pkix_pl_HttpDefaultClient_CreateSession(
- const char *host,
- PRUint16 portnum,
- SEC_HTTP_SERVER_SESSION *pSession,
- void *plContext)
-{
- PKIX_PL_HttpDefaultClient *client = NULL;
-
- PKIX_ENTER
- (HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_CreateSession");
- PKIX_NULLCHECK_TWO(host, pSession);
-
- PKIX_CHECK(pkix_pl_HttpDefaultClient_Create
- (host, portnum, &client, plContext),
- PKIX_HTTPDEFAULTCLIENTCREATEFAILED);
-
- *pSession = (SEC_HTTP_SERVER_SESSION)client;
-
-cleanup:
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-
-}
-
-PKIX_Error *
-pkix_pl_HttpDefaultClient_KeepAliveSession(
- SEC_HTTP_SERVER_SESSION session,
- PRPollDesc **pPollDesc,
- void *plContext)
-{
- PKIX_PL_HttpDefaultClient *client = NULL;
-
- PKIX_ENTER
- (HTTPDEFAULTCLIENT,
- "pkix_pl_HttpDefaultClient_KeepAliveSession");
- PKIX_NULLCHECK_TWO(session, pPollDesc);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)session,
- PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
- PKIX_SESSIONNOTANHTTPDEFAULTCLIENT);
-
- client = (PKIX_PL_HttpDefaultClient *)session;
-
- /* XXX Not implemented */
-
-cleanup:
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-
-}
-
-PKIX_Error *
-pkix_pl_HttpDefaultClient_RequestCreate(
- SEC_HTTP_SERVER_SESSION session,
- const char *http_protocol_variant, /* usually "http" */
- const char *path_and_query_string,
- const char *http_request_method,
- const PRIntervalTime timeout,
- SEC_HTTP_REQUEST_SESSION *pRequest,
- void *plContext)
-{
- PKIX_PL_HttpDefaultClient *client = NULL;
- PKIX_PL_Socket *socket = NULL;
- PKIX_PL_Socket_Callback *callbackList = NULL;
- PRFileDesc *fileDesc = NULL;
- PRErrorCode status = 0;
-
- PKIX_ENTER
- (HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_RequestCreate");
- PKIX_NULLCHECK_TWO(session, pRequest);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)session,
- PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
- PKIX_SESSIONNOTANHTTPDEFAULTCLIENT);
-
- client = (PKIX_PL_HttpDefaultClient *)session;
-
- /* We only know how to do http */
- if (PORT_Strncasecmp(http_protocol_variant, "http", 4) != 0) {
- PKIX_ERROR(PKIX_UNRECOGNIZEDPROTOCOLREQUESTED);
- }
-
- if (PORT_Strncasecmp(http_request_method, "POST", 4) == 0) {
- client->send_http_method = HTTP_POST_METHOD;
- } else if (PORT_Strncasecmp(http_request_method, "GET", 3) == 0) {
- client->send_http_method = HTTP_GET_METHOD;
- } else {
- /* We only know how to do POST and GET */
- PKIX_ERROR(PKIX_UNRECOGNIZEDREQUESTMETHOD);
- }
-
- if (path_and_query_string) {
- /* "path_and_query_string" is a parsing result by CERT_GetURL
- * function that adds "end of line" to the value. OK to dup
- * the string. */
- client->path = PORT_Strdup(path_and_query_string);
- if (!client->path) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- }
-
- client->timeout = timeout;
-
-#if 0
- PKIX_CHECK(pkix_HttpCertStore_FindSocketConnection
- (timeout,
- "variation.red.iplanet.com", /* (char *)client->host, */
- 2001, /* client->portnum, */
- &status,
- &socket,
- plContext),
- PKIX_HTTPCERTSTOREFINDSOCKETCONNECTIONFAILED);
-#else
- PKIX_CHECK(pkix_HttpCertStore_FindSocketConnection
- (timeout,
- (char *)client->host,
- client->portnum,
- &status,
- &socket,
- plContext),
- PKIX_HTTPCERTSTOREFINDSOCKETCONNECTIONFAILED);
-#endif
-
- client->socket = socket;
-
- PKIX_CHECK(pkix_pl_Socket_GetCallbackList
- (socket, &callbackList, plContext),
- PKIX_SOCKETGETCALLBACKLISTFAILED);
-
- client->callbackList = (void *)callbackList;
-
- PKIX_CHECK(pkix_pl_Socket_GetPRFileDesc
- (socket, &fileDesc, plContext),
- PKIX_SOCKETGETPRFILEDESCFAILED);
-
- client->pollDesc.fd = fileDesc;
- client->pollDesc.in_flags = 0;
- client->pollDesc.out_flags = 0;
-
- client->send_http_data = NULL;
- client->send_http_data_len = 0;
- client->send_http_content_type = NULL;
-
- client->connectStatus =
- ((status == 0) ? HTTP_CONNECTED : HTTP_CONNECT_PENDING);
-
- /* Request object is the same object as Session object */
- PKIX_INCREF(client);
- *pRequest = client;
-
-cleanup:
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-
-}
-
-PKIX_Error *
-pkix_pl_HttpDefaultClient_SetPostData(
- SEC_HTTP_REQUEST_SESSION request,
- const char *http_data,
- const PRUint32 http_data_len,
- const char *http_content_type,
- void *plContext)
-{
- PKIX_PL_HttpDefaultClient *client = NULL;
-
- PKIX_ENTER
- (HTTPDEFAULTCLIENT,
- "pkix_pl_HttpDefaultClient_SetPostData");
- PKIX_NULLCHECK_ONE(request);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)request,
- PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
- PKIX_REQUESTNOTANHTTPDEFAULTCLIENT);
-
- client = (PKIX_PL_HttpDefaultClient *)request;
-
- client->send_http_data = http_data;
- client->send_http_data_len = http_data_len;
- client->send_http_content_type = http_content_type;
-
- /* Caller is allowed to give NULL or empty string for content_type */
- if ((client->send_http_content_type == NULL) ||
- (*(client->send_http_content_type) == '\0')) {
- client->send_http_content_type = "application/ocsp-request";
- }
-
-cleanup:
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-
-}
-
-PKIX_Error *
-pkix_pl_HttpDefaultClient_TrySendAndReceive(
- SEC_HTTP_REQUEST_SESSION request,
- PRUint16 *http_response_code,
- const char **http_response_content_type,
- const char **http_response_headers,
- const char **http_response_data,
- PRUint32 *http_response_data_len,
- PRPollDesc **pPollDesc,
- SECStatus *pSECReturn,
- void *plContext)
-{
- PKIX_PL_HttpDefaultClient *client = NULL;
- PKIX_UInt32 postLen = 0;
- PRPollDesc *pollDesc = NULL;
- char *sendbuf = NULL;
- char portstr[16];
-
- PKIX_ENTER
- (HTTPDEFAULTCLIENT,
- "pkix_pl_HttpDefaultClient_TrySendAndReceive");
-
- PKIX_NULLCHECK_ONE(request);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)request,
- PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
- PKIX_REQUESTNOTANHTTPDEFAULTCLIENT);
-
- client = (PKIX_PL_HttpDefaultClient *)request;
-
- if (!pPollDesc && client->timeout == 0) {
- PKIX_ERROR_FATAL(PKIX_NULLARGUMENT);
- }
-
- if (pPollDesc) {
- pollDesc = *pPollDesc;
- }
-
- /* if not continuing from an earlier WOULDBLOCK return... */
- if (pollDesc == NULL) {
-
- if (!((client->connectStatus == HTTP_CONNECTED) ||
- (client->connectStatus == HTTP_CONNECT_PENDING))) {
- PKIX_ERROR(PKIX_HTTPCLIENTININVALIDSTATE);
- }
-
- /* Did caller provide a value for response length? */
- if (http_response_data_len != NULL) {
- client->pRcv_http_data_len = http_response_data_len;
- client->maxResponseLen = *http_response_data_len;
- }
-
- client->rcv_http_response_code = http_response_code;
- client->rcv_http_content_type = http_response_content_type;
- client->rcv_http_headers = http_response_headers;
- client->rcv_http_data = http_response_data;
-
- /* prepare the message */
- portstr[0] = '\0';
- if (client->portnum != 80) {
- PR_snprintf(portstr, sizeof(portstr), ":%d",
- client->portnum);
- }
-
- if (client->send_http_method == HTTP_POST_METHOD) {
- sendbuf = PR_smprintf
- ("POST %s HTTP/1.0\r\nHost: %s%s\r\n"
- "Content-Type: %s\r\nContent-Length: %u\r\n\r\n",
- client->path,
- client->host,
- portstr,
- client->send_http_content_type,
- client->send_http_data_len);
- postLen = PORT_Strlen(sendbuf);
-
- client->POSTLen = postLen + client->send_http_data_len;
-
- /* allocate postBuffer big enough for header + data */
- PKIX_CHECK(PKIX_PL_Malloc
- (client->POSTLen,
- (void **)&(client->POSTBuf),
- plContext),
- PKIX_MALLOCFAILED);
-
- /* copy header into postBuffer */
- PORT_Memcpy(client->POSTBuf, sendbuf, postLen);
-
- /* append data after header */
- PORT_Memcpy(&client->POSTBuf[postLen],
- client->send_http_data,
- client->send_http_data_len);
-
- /* PR_smprintf_free original header buffer */
- PR_smprintf_free(sendbuf);
- sendbuf = NULL;
-
- } else if (client->send_http_method == HTTP_GET_METHOD) {
- client->GETBuf = PR_smprintf
- ("GET %s HTTP/1.0\r\nHost: %s%s\r\n\r\n",
- client->path,
- client->host,
- portstr);
- client->GETLen = PORT_Strlen(client->GETBuf);
- }
-
- }
-
- /* continue according to state */
- PKIX_CHECK(pkix_pl_HttpDefaultClient_Dispatch(client, plContext),
- PKIX_HTTPDEFAULTCLIENTDISPATCHFAILED);
-
- switch (client->connectStatus) {
- case HTTP_CONNECT_PENDING:
- case HTTP_SEND_PENDING:
- case HTTP_RECV_HDR_PENDING:
- case HTTP_RECV_BODY_PENDING:
- pollDesc = &(client->pollDesc);
- *pSECReturn = SECWouldBlock;
- break;
- case HTTP_ERROR:
- /* Did caller provide a pointer for length? */
- if (client->pRcv_http_data_len != NULL) {
- /* Was error "response too big?" */
- if (client->rcv_http_data_len !=
- HTTP_UNKNOWN_CONTENT_LENGTH &&
- client->maxResponseLen >=
- client->rcv_http_data_len) {
- /* Yes, report needed space */
- *(client->pRcv_http_data_len) =
- client->rcv_http_data_len;
- } else {
- /* No, report problem other than size */
- *(client->pRcv_http_data_len) = 0;
- }
- }
-
- pollDesc = NULL;
- *pSECReturn = SECFailure;
- break;
- case HTTP_COMPLETE:
- *(client->rcv_http_response_code) =
- client->responseCode;
- if (client->pRcv_http_data_len != NULL) {
- *http_response_data_len =
- client->rcv_http_data_len;
- }
- if (client->rcv_http_data != NULL) {
- *(client->rcv_http_data) = client->rcvBuf;
- }
- pollDesc = NULL;
- *pSECReturn = SECSuccess;
- break;
- case HTTP_NOT_CONNECTED:
- case HTTP_CONNECTED:
- case HTTP_RECV_HDR:
- case HTTP_RECV_BODY:
- default:
- pollDesc = NULL;
- *pSECReturn = SECFailure;
- PKIX_ERROR(PKIX_HTTPCLIENTININVALIDSTATE);
- break;
- }
-
- if (pPollDesc) {
- *pPollDesc = pollDesc;
- }
-
-cleanup:
- if (sendbuf) {
- PR_smprintf_free(sendbuf);
- }
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-
-}
-
-PKIX_Error *
-pkix_pl_HttpDefaultClient_Cancel(
- SEC_HTTP_REQUEST_SESSION request,
- void *plContext)
-{
- PKIX_PL_HttpDefaultClient *client = NULL;
-
- PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Cancel");
- PKIX_NULLCHECK_ONE(request);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)request,
- PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
- PKIX_REQUESTNOTANHTTPDEFAULTCLIENT);
-
- client = (PKIX_PL_HttpDefaultClient *)request;
-
- /* XXX Not implemented */
-
-cleanup:
-
- PKIX_RETURN(HTTPDEFAULTCLIENT);
-
-}
-
-SECStatus
-pkix_pl_HttpDefaultClient_CreateSessionFcn(
- const char *host,
- PRUint16 portnum,
- SEC_HTTP_SERVER_SESSION *pSession)
-{
- PKIX_Error *err = pkix_pl_HttpDefaultClient_CreateSession
- (host, portnum, pSession, plContext);
-
- if (err) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-pkix_pl_HttpDefaultClient_KeepAliveSessionFcn(
- SEC_HTTP_SERVER_SESSION session,
- PRPollDesc **pPollDesc)
-{
- PKIX_Error *err = pkix_pl_HttpDefaultClient_KeepAliveSession
- (session, pPollDesc, plContext);
-
- if (err) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-pkix_pl_HttpDefaultClient_FreeSessionFcn(
- SEC_HTTP_SERVER_SESSION session)
-{
- PKIX_Error *err =
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)(session), plContext);
-
- if (err) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-pkix_pl_HttpDefaultClient_RequestCreateFcn(
- SEC_HTTP_SERVER_SESSION session,
- const char *http_protocol_variant, /* usually "http" */
- const char *path_and_query_string,
- const char *http_request_method,
- const PRIntervalTime timeout,
- SEC_HTTP_REQUEST_SESSION *pRequest)
-{
- PKIX_Error *err = pkix_pl_HttpDefaultClient_RequestCreate
- (session,
- http_protocol_variant,
- path_and_query_string,
- http_request_method,
- timeout,
- pRequest,
- plContext);
-
- if (err) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-pkix_pl_HttpDefaultClient_SetPostDataFcn(
- SEC_HTTP_REQUEST_SESSION request,
- const char *http_data,
- const PRUint32 http_data_len,
- const char *http_content_type)
-{
- PKIX_Error *err =
- pkix_pl_HttpDefaultClient_SetPostData(request, http_data,
- http_data_len,
- http_content_type,
- plContext);
- if (err) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-pkix_pl_HttpDefaultClient_AddHeaderFcn(
- SEC_HTTP_REQUEST_SESSION request,
- const char *http_header_name,
- const char *http_header_value)
-{
- /* Not supported */
- return SECFailure;
-}
-
-SECStatus
-pkix_pl_HttpDefaultClient_TrySendAndReceiveFcn(
- SEC_HTTP_REQUEST_SESSION request,
- PRPollDesc **pPollDesc,
- PRUint16 *http_response_code,
- const char **http_response_content_type,
- const char **http_response_headers,
- const char **http_response_data,
- PRUint32 *http_response_data_len)
-{
- SECStatus rv = SECFailure;
-
- PKIX_Error *err = pkix_pl_HttpDefaultClient_TrySendAndReceive
- (request,
- http_response_code,
- http_response_content_type,
- http_response_headers,
- http_response_data,
- http_response_data_len,
- pPollDesc,
- &rv,
- plContext);
-
- if (err) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
- return rv;
- }
- return SECSuccess;
-}
-
-SECStatus
-pkix_pl_HttpDefaultClient_CancelFcn(
- SEC_HTTP_REQUEST_SESSION request)
-{
- PKIX_Error *err = pkix_pl_HttpDefaultClient_Cancel(request, plContext);
-
- if (err) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-pkix_pl_HttpDefaultClient_FreeFcn(
- SEC_HTTP_REQUEST_SESSION request)
-{
- PKIX_Error *err =
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)(request), plContext);
-
- if (err) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object *)err, plContext);
- return SECFailure;
- }
- return SECSuccess;
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.h
deleted file mode 100644
index 91916a0ab..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_httpdefaultclient.h
- *
- * HTTPDefaultClient Object Type Definition
- *
- */
-
-#ifndef _PKIX_PL_HTTPDEFAULTCLIENT_H
-#define _PKIX_PL_HTTPDEFAULTCLIENT_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define HTTP_DATA_BUFSIZE 4096
-#define HTTP_HEADER_BUFSIZE 1024
-#define HTTP_MIN_AVAILABLE_BUFFER_SIZE 512
-
-typedef enum {
- HTTP_NOT_CONNECTED,
- HTTP_CONNECT_PENDING,
- HTTP_CONNECTED,
- HTTP_SEND_PENDING,
- HTTP_RECV_HDR,
- HTTP_RECV_HDR_PENDING,
- HTTP_RECV_BODY,
- HTTP_RECV_BODY_PENDING,
- HTTP_COMPLETE,
- HTTP_ERROR
-} HttpConnectStatus;
-
-typedef enum {
- HTTP_POST_METHOD,
- HTTP_GET_METHOD
-} HttpMethod;
-
-struct PKIX_PL_HttpDefaultClientStruct {
- HttpConnectStatus connectStatus;
- PRUint16 portnum;
- PRIntervalTime timeout;
- PKIX_UInt32 bytesToWrite;
- PKIX_UInt32 send_http_data_len;
- PKIX_UInt32 rcv_http_data_len;
- PKIX_UInt32 capacity;
- PKIX_UInt32 filledupBytes;
- PKIX_UInt32 responseCode;
- PKIX_UInt32 maxResponseLen;
- PKIX_UInt32 GETLen;
- PKIX_UInt32 POSTLen;
- PRUint32 *pRcv_http_data_len;
- PRPollDesc pollDesc;
- void *callbackList; /* cast this to (PKIX_PL_Socket_Callback *) */
- char *GETBuf;
- char *POSTBuf;
- char *rcvBuf;
- char *host;
- char *path;
- char *rcvContentType;
- void *rcvHeaders;
- HttpMethod send_http_method;
- const char *send_http_content_type;
- const char *send_http_data;
- PRUint16 *rcv_http_response_code;
- const char **rcv_http_content_type;
- const char **rcv_http_headers;
- const char **rcv_http_data;
- PKIX_PL_Socket *socket;
- void *plContext;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_HttpDefaultClient_RegisterSelf(void *plContext);
-
-SECStatus
-pkix_pl_HttpDefaultClient_CreateSessionFcn(
- const char *host,
- PRUint16 portnum,
- SEC_HTTP_SERVER_SESSION *pSession);
-
-SECStatus
-pkix_pl_HttpDefaultClient_KeepAliveSessionFcn(
- SEC_HTTP_SERVER_SESSION session,
- PRPollDesc **pPollDesc);
-
-SECStatus
-pkix_pl_HttpDefaultClient_FreeSessionFcn(
- SEC_HTTP_SERVER_SESSION session);
-
-SECStatus
-pkix_pl_HttpDefaultClient_RequestCreateFcn(
- SEC_HTTP_SERVER_SESSION session,
- const char *http_protocol_variant, /* usually "http" */
- const char *path_and_query_string,
- const char *http_request_method,
- const PRIntervalTime timeout,
- SEC_HTTP_REQUEST_SESSION *pRequest);
-
-SECStatus
-pkix_pl_HttpDefaultClient_SetPostDataFcn(
- SEC_HTTP_REQUEST_SESSION request,
- const char *http_data,
- const PRUint32 http_data_len,
- const char *http_content_type);
-
-SECStatus
-pkix_pl_HttpDefaultClient_AddHeaderFcn(
- SEC_HTTP_REQUEST_SESSION request,
- const char *http_header_name,
- const char *http_header_value);
-
-SECStatus
-pkix_pl_HttpDefaultClient_TrySendAndReceiveFcn(
- SEC_HTTP_REQUEST_SESSION request,
- PRPollDesc **pPollDesc,
- PRUint16 *http_response_code,
- const char **http_response_content_type,
- const char **http_response_headers,
- const char **http_response_data,
- PRUint32 *http_response_data_len);
-
-SECStatus
-pkix_pl_HttpDefaultClient_CancelFcn(
- SEC_HTTP_REQUEST_SESSION request);
-
-SECStatus
-pkix_pl_HttpDefaultClient_FreeFcn(
- SEC_HTTP_REQUEST_SESSION request);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_HTTPDEFAULTCLIENT_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.c
deleted file mode 100644
index b3ac8ce19..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.c
+++ /dev/null
@@ -1,1116 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ldapcertstore.c
- *
- * LDAPCertStore Function Definitions
- *
- */
-
-/* We can't decode the length of a message without at least this many bytes */
-#define MINIMUM_MSG_LENGTH 5
-
-#include "pkix_pl_ldapcertstore.h"
-
-/* --Private-Ldap-CertStore-Database-Functions----------------------- */
-
-/*
- * FUNCTION: pkix_pl_LdapCertStore_DecodeCrossCertPair
- * DESCRIPTION:
- *
- * This function decodes a DER-encoded CrossCertPair pointed to by
- * "responseList" and extracts and decodes the Certificates in that pair,
- * adding the resulting Certs, if the decoding was successful, to the List
- * (possibly empty) pointed to by "certList". If none of the objects
- * can be decoded into a Cert, the List is returned unchanged.
- *
- * PARAMETERS:
- * "derCCPItem"
- * The address of the SECItem containing the DER representation of the
- * CrossCertPair. Must be non-NULL.
- * "certList"
- * The address of the List to which the decoded Certs are added. May be
- * empty, but must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapCertStore_DecodeCrossCertPair(
- SECItem *derCCPItem,
- PKIX_List *certList,
- void *plContext)
-{
- LDAPCertPair certPair = {{ siBuffer, NULL, 0 }, { siBuffer, NULL, 0 }};
- SECStatus rv = SECFailure;
-
- PRArenaPool *tempArena = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_DecodeCrossCertPair");
- PKIX_NULLCHECK_TWO(derCCPItem, certList);
-
- tempArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!tempArena) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- rv = SEC_ASN1DecodeItem(tempArena, &certPair, PKIX_PL_LDAPCrossCertPairTemplate,
- derCCPItem);
- if (rv != SECSuccess) {
- goto cleanup;
- }
-
- if (certPair.forward.data != NULL) {
-
- PKIX_CHECK(
- pkix_pl_Cert_CreateToList(&certPair.forward, certList,
- plContext),
- PKIX_CERTCREATETOLISTFAILED);
- }
-
- if (certPair.reverse.data != NULL) {
-
- PKIX_CHECK(
- pkix_pl_Cert_CreateToList(&certPair.reverse, certList,
- plContext),
- PKIX_CERTCREATETOLISTFAILED);
- }
-
-cleanup:
- if (tempArena) {
- PORT_FreeArena(tempArena, PR_FALSE);
- }
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapCertStore_BuildCertList
- * DESCRIPTION:
- *
- * This function takes a List of LdapResponse objects pointed to by
- * "responseList" and extracts and decodes the Certificates in those responses,
- * storing the List of those Certificates at "pCerts". If none of the objects
- * can be decoded into a Cert, the returned List is empty.
- *
- * PARAMETERS:
- * "responseList"
- * The address of the List of LdapResponses. Must be non-NULL.
- * "pCerts"
- * The address at which the result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapCertStore_BuildCertList(
- PKIX_List *responseList,
- PKIX_List **pCerts,
- void *plContext)
-{
- PKIX_UInt32 numResponses = 0;
- PKIX_UInt32 respIx = 0;
- LdapAttrMask attrBits = 0;
- PKIX_PL_LdapResponse *response = NULL;
- PKIX_List *certList = NULL;
- LDAPMessage *message = NULL;
- LDAPSearchResponseEntry *sre = NULL;
- LDAPSearchResponseAttr **sreAttrArray = NULL;
- LDAPSearchResponseAttr *sreAttr = NULL;
- SECItem *attrType = NULL;
- SECItem **attrVal = NULL;
- SECItem *derCertItem = NULL;
-
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_BuildCertList");
- PKIX_NULLCHECK_TWO(responseList, pCerts);
-
- PKIX_CHECK(PKIX_List_Create(&certList, plContext),
- PKIX_LISTCREATEFAILED);
-
- /* extract certs from response */
- PKIX_CHECK(PKIX_List_GetLength
- (responseList, &numResponses, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (respIx = 0; respIx < numResponses; respIx++) {
- PKIX_CHECK(PKIX_List_GetItem
- (responseList,
- respIx,
- (PKIX_PL_Object **)&response,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_pl_LdapResponse_GetMessage
- (response, &message, plContext),
- PKIX_LDAPRESPONSEGETMESSAGEFAILED);
-
- sre = &(message->protocolOp.op.searchResponseEntryMsg);
- sreAttrArray = sre->attributes;
-
- /* Get next element of null-terminated array */
- sreAttr = *sreAttrArray++;
- while (sreAttr != NULL) {
- attrType = &(sreAttr->attrType);
- PKIX_CHECK(pkix_pl_LdapRequest_AttrTypeToBit
- (attrType, &attrBits, plContext),
- PKIX_LDAPREQUESTATTRTYPETOBITFAILED);
- /* Is this attrVal a Certificate? */
- if (((LDAPATTR_CACERT | LDAPATTR_USERCERT) &
- attrBits) == attrBits) {
- attrVal = sreAttr->val;
- derCertItem = *attrVal++;
- while (derCertItem != 0) {
- /* create a PKIX_PL_Cert from derCert */
- PKIX_CHECK(pkix_pl_Cert_CreateToList
- (derCertItem, certList, plContext),
- PKIX_CERTCREATETOLISTFAILED);
- derCertItem = *attrVal++;
- }
- } else if ((LDAPATTR_CROSSPAIRCERT & attrBits) == attrBits){
- /* Is this attrVal a CrossPairCertificate? */
- attrVal = sreAttr->val;
- derCertItem = *attrVal++;
- while (derCertItem != 0) {
- /* create PKIX_PL_Certs from derCert */
- PKIX_CHECK(pkix_pl_LdapCertStore_DecodeCrossCertPair
- (derCertItem, certList, plContext),
- PKIX_LDAPCERTSTOREDECODECROSSCERTPAIRFAILED);
- derCertItem = *attrVal++;
- }
- }
- sreAttr = *sreAttrArray++;
- }
- PKIX_DECREF(response);
- }
-
- *pCerts = certList;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(certList);
- }
-
- PKIX_DECREF(response);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapCertStore_BuildCrlList
- * DESCRIPTION:
- *
- * This function takes a List of LdapResponse objects pointed to by
- * "responseList" and extracts and decodes the CRLs in those responses, storing
- * the List of those CRLs at "pCrls". If none of the objects can be decoded
- * into a CRL, the returned List is empty.
- *
- * PARAMETERS:
- * "responseList"
- * The address of the List of LdapResponses. Must be non-NULL.
- * "pCrls"
- * The address at which the result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapCertStore_BuildCrlList(
- PKIX_List *responseList,
- PKIX_List **pCrls,
- void *plContext)
-{
- PKIX_UInt32 numResponses = 0;
- PKIX_UInt32 respIx = 0;
- LdapAttrMask attrBits = 0;
- CERTSignedCrl *nssCrl = NULL;
- PKIX_PL_LdapResponse *response = NULL;
- PKIX_List *crlList = NULL;
- PKIX_PL_CRL *crl = NULL;
- LDAPMessage *message = NULL;
- LDAPSearchResponseEntry *sre = NULL;
- LDAPSearchResponseAttr **sreAttrArray = NULL;
- LDAPSearchResponseAttr *sreAttr = NULL;
- SECItem *attrType = NULL;
- SECItem **attrVal = NULL;
- SECItem *derCrlCopy = NULL;
- SECItem *derCrlItem = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_BuildCrlList");
- PKIX_NULLCHECK_TWO(responseList, pCrls);
-
- PKIX_CHECK(PKIX_List_Create(&crlList, plContext),
- PKIX_LISTCREATEFAILED);
-
- /* extract crls from response */
- PKIX_CHECK(PKIX_List_GetLength
- (responseList, &numResponses, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (respIx = 0; respIx < numResponses; respIx++) {
- PKIX_CHECK(PKIX_List_GetItem
- (responseList,
- respIx,
- (PKIX_PL_Object **)&response,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_pl_LdapResponse_GetMessage
- (response, &message, plContext),
- PKIX_LDAPRESPONSEGETMESSAGEFAILED);
-
- sre = &(message->protocolOp.op.searchResponseEntryMsg);
- sreAttrArray = sre->attributes;
-
- /* Get next element of null-terminated array */
- sreAttr = *sreAttrArray++;
- while (sreAttr != NULL) {
- attrType = &(sreAttr->attrType);
- PKIX_CHECK(pkix_pl_LdapRequest_AttrTypeToBit
- (attrType, &attrBits, plContext),
- PKIX_LDAPREQUESTATTRTYPETOBITFAILED);
- /* Is this attrVal a Revocation List? */
- if (((LDAPATTR_CERTREVLIST | LDAPATTR_AUTHREVLIST) &
- attrBits) == attrBits) {
- attrVal = sreAttr->val;
- derCrlItem = *attrVal++;
- while (derCrlItem != 0) {
- /* create a PKIX_PL_Crl from derCrl */
- derCrlCopy = SECITEM_DupItem(derCrlItem);
- if (!derCrlCopy) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- /* crl will be based on derCrlCopy, but wont
- * own the der. */
- nssCrl =
- CERT_DecodeDERCrlWithFlags(NULL, derCrlCopy,
- SEC_CRL_TYPE,
- CRL_DECODE_DONT_COPY_DER |
- CRL_DECODE_SKIP_ENTRIES);
- if (!nssCrl) {
- SECITEM_FreeItem(derCrlCopy, PKIX_TRUE);
- continue;
- }
- /* pkix crl own the der. */
- PKIX_CHECK(
- pkix_pl_CRL_CreateWithSignedCRL(nssCrl,
- derCrlCopy, NULL, &crl, plContext),
- PKIX_CRLCREATEWITHSIGNEDCRLFAILED);
- /* Left control over memory pointed by derCrlCopy and
- * nssCrl to pkix crl. */
- derCrlCopy = NULL;
- nssCrl = NULL;
- PKIX_CHECK(PKIX_List_AppendItem
- (crlList, (PKIX_PL_Object *) crl, plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_DECREF(crl);
- derCrlItem = *attrVal++;
- }
- /* Clean up after PKIX_CHECK_ONLY_FATAL */
- pkixTempErrorReceived = PKIX_FALSE;
- }
- sreAttr = *sreAttrArray++;
- }
- PKIX_DECREF(response);
- }
-
- *pCrls = crlList;
- crlList = NULL;
-cleanup:
- if (derCrlCopy) {
- SECITEM_FreeItem(derCrlCopy, PKIX_TRUE);
- }
- if (nssCrl) {
- SEC_DestroyCrl(nssCrl);
- }
- PKIX_DECREF(crl);
- PKIX_DECREF(crlList);
- PKIX_DECREF(response);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapCertStore_DestroyAVAList
- * DESCRIPTION:
- *
- * This function frees the space allocated for the components of the
- * equalFilters that make up the andFilter pointed to by "filter".
- *
- * PARAMETERS:
- * "requestParams"
- * The address of the andFilter whose components are to be freed. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapCertStore_DestroyAVAList(
- LDAPNameComponent **nameComponents,
- void *plContext)
-{
- LDAPNameComponent **currentNC = NULL;
- unsigned char *component = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_DestroyAVAList");
- PKIX_NULLCHECK_ONE(nameComponents);
-
- /* Set currentNC to point to first AVA pointer */
- currentNC = nameComponents;
-
- while ((*currentNC) != NULL) {
- component = (*currentNC)->attrValue;
- if (component != NULL) {
- PORT_Free(component);
- }
- currentNC++;
- }
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapCertStore_MakeNameAVAList
- * DESCRIPTION:
- *
- * This function allocates space from the arena pointed to by "arena" to
- * construct a filter that will match components of the X500Name pointed to
- * by "name", and stores the resulting filter at "pFilter".
- *
- * "name" is checked for commonName and organizationName components (cn=,
- * and o=). The component strings are extracted using the family of
- * CERT_Get* functions, and each must be freed with PORT_Free.
- *
- * It is not clear which components should be in a request, so, for now,
- * we stop adding components after we have found one.
- *
- * PARAMETERS:
- * "arena"
- * The address of the PRArenaPool used in creating the filter. Must be
- * non-NULL.
- * "name"
- * The address of the X500Name whose components define the desired
- * matches. Must be non-NULL.
- * "pList"
- * The address at which the result is stored.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapCertStore_MakeNameAVAList(
- PRArenaPool *arena,
- PKIX_PL_X500Name *subjectName,
- LDAPNameComponent ***pList,
- void *plContext)
-{
- LDAPNameComponent **setOfNameComponents;
- LDAPNameComponent *currentNameComponent = NULL;
- PKIX_UInt32 componentsPresent = 0;
- void *v = NULL;
- unsigned char *component = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_MakeNameAVAList");
- PKIX_NULLCHECK_THREE(arena, subjectName, pList);
-
- /* Increase this if additional components may be extracted */
-#define MAX_NUM_COMPONENTS 3
-
- /* Space for (MAX_NUM_COMPONENTS + 1) pointers to LDAPNameComponents */
- PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZAlloc,
- (arena, (MAX_NUM_COMPONENTS + 1)*sizeof(LDAPNameComponent *)));
- setOfNameComponents = (LDAPNameComponent **)v;
-
- /* Space for MAX_NUM_COMPONENTS LDAPNameComponents */
- PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZNewArray,
- (arena, LDAPNameComponent, MAX_NUM_COMPONENTS));
-
- currentNameComponent = (LDAPNameComponent *)v;
-
- /* Try for commonName */
- PKIX_CHECK(pkix_pl_X500Name_GetCommonName
- (subjectName, &component, plContext),
- PKIX_X500NAMEGETCOMMONNAMEFAILED);
- if (component) {
- setOfNameComponents[componentsPresent] = currentNameComponent;
- currentNameComponent->attrType = (unsigned char *)"cn";
- currentNameComponent->attrValue = component;
- componentsPresent++;
- currentNameComponent++;
- }
-
- /*
- * The LDAP specification says we can send multiple name components
- * in an "AND" filter, but the LDAP Servers don't seem to be able to
- * handle such requests. So we'll quit after the cn component.
- */
-#if 0
- /* Try for orgName */
- PKIX_CHECK(pkix_pl_X500Name_GetOrgName
- (subjectName, &component, plContext),
- PKIX_X500NAMEGETORGNAMEFAILED);
- if (component) {
- setOfNameComponents[componentsPresent] = currentNameComponent;
- currentNameComponent->attrType = (unsigned char *)"o";
- currentNameComponent->attrValue = component;
- componentsPresent++;
- currentNameComponent++;
- }
-
- /* Try for countryName */
- PKIX_CHECK(pkix_pl_X500Name_GetCountryName
- (subjectName, &component, plContext),
- PKIX_X500NAMEGETCOUNTRYNAMEFAILED);
- if (component) {
- setOfNameComponents[componentsPresent] = currentNameComponent;
- currentNameComponent->attrType = (unsigned char *)"c";
- currentNameComponent->attrValue = component;
- componentsPresent++;
- currentNameComponent++;
- }
-#endif
-
- setOfNameComponents[componentsPresent] = NULL;
-
- *pList = setOfNameComponents;
-
-cleanup:
-
- PKIX_RETURN(CERTSTORE);
-
-}
-
-#if 0
-/*
- * FUNCTION: pkix_pl_LdapCertstore_ConvertCertResponses
- * DESCRIPTION:
- *
- * This function processes the List of LDAPResponses pointed to by "responses"
- * into a List of resulting Certs, storing the result at "pCerts". If there
- * are no responses converted successfully, a NULL may be stored.
- *
- * PARAMETERS:
- * "responses"
- * The LDAPResponses whose contents are to be converted. Must be non-NULL.
- * "pCerts"
- * Address at which the returned List is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapCertStore_ConvertCertResponses(
- PKIX_List *responses,
- PKIX_List **pCerts,
- void *plContext)
-{
- PKIX_List *unfiltered = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_ConvertCertResponses");
- PKIX_NULLCHECK_TWO(responses, pCerts);
-
- /*
- * We have a List of LdapResponse objects that have to be
- * turned into Certs.
- */
- PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
- (responses, &unfiltered, plContext),
- PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);
-
- *pCerts = unfiltered;
-
-cleanup:
-
- PKIX_RETURN(CERTSTORE);
-}
-#endif
-
-/*
- * FUNCTION: pkix_pl_LdapCertStore_GetCert
- * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
- */
-PKIX_Error *
-pkix_pl_LdapCertStore_GetCert(
- PKIX_CertStore *store,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *verifyNode,
- void **pNBIOContext,
- PKIX_List **pCertList,
- void *plContext)
-{
- PRArenaPool *requestArena = NULL;
- LDAPRequestParams requestParams;
- void *pollDesc = NULL;
- PKIX_Int32 minPathLen = 0;
- PKIX_Boolean cacheFlag = PKIX_FALSE;
- PKIX_ComCertSelParams *params = NULL;
- PKIX_PL_LdapCertStoreContext *lcs = NULL;
- PKIX_List *responses = NULL;
- PKIX_List *unfilteredCerts = NULL;
- PKIX_List *filteredCerts = NULL;
- PKIX_PL_X500Name *subjectName = 0;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCert");
- PKIX_NULLCHECK_THREE(store, selector, pCertList);
-
- requestParams.baseObject = "c=US";
- requestParams.scope = WHOLE_SUBTREE;
- requestParams.derefAliases = NEVER_DEREF;
- requestParams.sizeLimit = 0;
- requestParams.timeLimit = 0;
-
- /* Prepare elements for request filter */
-
- /*
- * Get a short-lived arena. We'll be done with this space once
- * the request is encoded.
- */
- requestArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!requestArena) {
- PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
- }
-
- PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
- (selector, &params, plContext),
- PKIX_CERTSELECTORGETCOMCERTSELPARAMSFAILED);
-
- /*
- * If we have the subject name for the desired subject,
- * ask the server for Certs with that subject.
- */
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
- (params, &subjectName, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetBasicConstraints
- (params, &minPathLen, plContext),
- PKIX_COMCERTSELPARAMSGETBASICCONSTRAINTSFAILED);
-
- if (subjectName) {
- PKIX_CHECK(pkix_pl_LdapCertStore_MakeNameAVAList
- (requestArena,
- subjectName,
- &(requestParams.nc),
- plContext),
- PKIX_LDAPCERTSTOREMAKENAMEAVALISTFAILED);
-
- if (*requestParams.nc == NULL) {
- /*
- * The subjectName may not include any components
- * that we know how to encode. We do not return
- * an error, because the caller did not necessarily
- * do anything wrong, but we return an empty List.
- */
- PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena,
- (requestArena, PR_FALSE));
-
- PKIX_CHECK(PKIX_List_Create(&filteredCerts, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_SetImmutable
- (filteredCerts, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- *pNBIOContext = NULL;
- *pCertList = filteredCerts;
- filteredCerts = NULL;
- goto cleanup;
- }
- } else {
- PKIX_ERROR(PKIX_INSUFFICIENTCRITERIAFORCERTQUERY);
- }
-
- /* Prepare attribute field of request */
-
- requestParams.attributes = 0;
-
- if (minPathLen < 0) {
- requestParams.attributes |= LDAPATTR_USERCERT;
- }
-
- if (minPathLen > -2) {
- requestParams.attributes |=
- LDAPATTR_CACERT | LDAPATTR_CROSSPAIRCERT;
- }
-
- /* All request fields are done */
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (store, (PKIX_PL_Object **)&lcs, plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
- ((PKIX_PL_LdapClient *)lcs,
- &requestParams,
- &pollDesc,
- &responses,
- plContext),
- PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
-
- PKIX_CHECK(pkix_pl_LdapCertStore_DestroyAVAList
- (requestParams.nc, plContext),
- PKIX_LDAPCERTSTOREDESTROYAVALISTFAILED);
-
- if (requestArena) {
- PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena,
- (requestArena, PR_FALSE));
- requestArena = NULL;
- }
-
- if (pollDesc != NULL) {
- /* client is waiting for non-blocking I/O to complete */
- *pNBIOContext = (void *)pollDesc;
- *pCertList = NULL;
- goto cleanup;
- }
- /* LdapClient has given us a response! */
-
- if (responses) {
- PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
- (store, &cacheFlag, plContext),
- PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED);
-
- PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
- (responses, &unfilteredCerts, plContext),
- PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Select
- (selector, unfilteredCerts, &filteredCerts, plContext),
- PKIX_CERTSELECTORSELECTFAILED);
- }
-
- *pNBIOContext = NULL;
- *pCertList = filteredCerts;
- filteredCerts = NULL;
-
-cleanup:
-
- PKIX_DECREF(params);
- PKIX_DECREF(subjectName);
- PKIX_DECREF(responses);
- PKIX_DECREF(unfilteredCerts);
- PKIX_DECREF(filteredCerts);
- PKIX_DECREF(lcs);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapCertStore_GetCertContinue
- * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
- */
-PKIX_Error *
-pkix_pl_LdapCertStore_GetCertContinue(
- PKIX_CertStore *store,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *verifyNode,
- void **pNBIOContext,
- PKIX_List **pCertList,
- void *plContext)
-{
- PKIX_Boolean cacheFlag = PKIX_FALSE;
- PKIX_PL_LdapCertStoreContext *lcs = NULL;
- void *pollDesc = NULL;
- PKIX_List *responses = NULL;
- PKIX_List *unfilteredCerts = NULL;
- PKIX_List *filteredCerts = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCertContinue");
- PKIX_NULLCHECK_THREE(store, selector, pCertList);
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (store, (PKIX_PL_Object **)&lcs, plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
- ((PKIX_PL_LdapClient *)lcs, &pollDesc, &responses, plContext),
- PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
-
- if (pollDesc != NULL) {
- /* client is waiting for non-blocking I/O to complete */
- *pNBIOContext = (void *)pollDesc;
- *pCertList = NULL;
- goto cleanup;
- }
- /* LdapClient has given us a response! */
-
- if (responses) {
- PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
- (store, &cacheFlag, plContext),
- PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED);
-
- PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
- (responses, &unfilteredCerts, plContext),
- PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);
-
- PKIX_CHECK(pkix_CertSelector_Select
- (selector, unfilteredCerts, &filteredCerts, plContext),
- PKIX_CERTSELECTORSELECTFAILED);
- }
-
- *pNBIOContext = NULL;
- *pCertList = filteredCerts;
-
-cleanup:
-
- PKIX_DECREF(responses);
- PKIX_DECREF(unfilteredCerts);
- PKIX_DECREF(lcs);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapCertStore_GetCRL
- * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
- */
-PKIX_Error *
-pkix_pl_LdapCertStore_GetCRL(
- PKIX_CertStore *store,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrlList,
- void *plContext)
-{
- LDAPRequestParams requestParams;
- void *pollDesc = NULL;
- PRArenaPool *requestArena = NULL;
- PKIX_UInt32 numNames = 0;
- PKIX_UInt32 thisName = 0;
- PKIX_PL_CRL *candidate = NULL;
- PKIX_List *responses = NULL;
- PKIX_List *issuerNames = NULL;
- PKIX_List *filteredCRLs = NULL;
- PKIX_List *unfilteredCRLs = NULL;
- PKIX_PL_X500Name *issuer = NULL;
- PKIX_PL_LdapCertStoreContext *lcs = NULL;
- PKIX_ComCRLSelParams *params = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCRL");
- PKIX_NULLCHECK_THREE(store, selector, pCrlList);
-
- requestParams.baseObject = "c=US";
- requestParams.scope = WHOLE_SUBTREE;
- requestParams.derefAliases = NEVER_DEREF;
- requestParams.sizeLimit = 0;
- requestParams.timeLimit = 0;
- requestParams.attributes = LDAPATTR_CERTREVLIST | LDAPATTR_AUTHREVLIST;
- /* Prepare elements for request filter */
-
- /* XXX Place CRLDP code here. Handle the case when */
- /* RFC 5280. Paragraph: 4.2.1.13: */
- /* If the distributionPoint field contains a directoryName, the entry */
- /* for that directoryName contains the current CRL for the associated */
- /* reasons and the CRL is issued by the associated cRLIssuer. The CRL */
- /* may be stored in either the certificateRevocationList or */
- /* authorityRevocationList attribute. The CRL is to be obtained by the */
- /* application from whatever directory server is locally configured. */
- /* The protocol the application uses to access the directory (e.g., DAP */
- /* or LDAP) is a local matter. */
-
-
-
- /*
- * Get a short-lived arena. We'll be done with this space once
- * the request is encoded.
- */
- PKIX_PL_NSSCALLRV
- (CERTSTORE, requestArena, PORT_NewArena, (DER_DEFAULT_CHUNKSIZE));
-
- if (!requestArena) {
- PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
- }
-
- PKIX_CHECK(PKIX_CRLSelector_GetCommonCRLSelectorParams
- (selector, &params, plContext),
- PKIX_CRLSELECTORGETCOMCERTSELPARAMSFAILED);
-
- PKIX_CHECK(PKIX_ComCRLSelParams_GetIssuerNames
- (params, &issuerNames, plContext),
- PKIX_COMCRLSELPARAMSGETISSUERNAMESFAILED);
-
- /*
- * The specification for PKIX_ComCRLSelParams_GetIssuerNames in
- * pkix_crlsel.h says that if the criterion is not set we get a null
- * pointer. If we get an empty List the criterion is impossible to
- * meet ("must match at least one of the names in the List").
- */
- if (issuerNames) {
-
- PKIX_CHECK(PKIX_List_GetLength
- (issuerNames, &numNames, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- if (numNames > 0) {
- for (thisName = 0; thisName < numNames; thisName++) {
- PKIX_CHECK(PKIX_List_GetItem
- (issuerNames,
- thisName,
- (PKIX_PL_Object **)&issuer,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK
- (pkix_pl_LdapCertStore_MakeNameAVAList
- (requestArena,
- issuer,
- &(requestParams.nc),
- plContext),
- PKIX_LDAPCERTSTOREMAKENAMEAVALISTFAILED);
-
- PKIX_DECREF(issuer);
-
- if (*requestParams.nc == NULL) {
- /*
- * The issuer may not include any
- * components that we know how to
- * encode. We do not return an error,
- * because the caller did not
- * necessarily do anything wrong, but
- * we return an empty List.
- */
- PKIX_PL_NSSCALL
- (CERTSTORE, PORT_FreeArena,
- (requestArena, PR_FALSE));
-
- PKIX_CHECK(PKIX_List_Create
- (&filteredCRLs, plContext),
- PKIX_LISTCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_SetImmutable
- (filteredCRLs, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- *pNBIOContext = NULL;
- *pCrlList = filteredCRLs;
- goto cleanup;
- }
-
- /*
- * LDAP Servers don't seem to be able to handle
- * requests with more than more than one name.
- */
- break;
- }
- } else {
- PKIX_ERROR(PKIX_IMPOSSIBLECRITERIONFORCRLQUERY);
- }
- } else {
- PKIX_ERROR(PKIX_IMPOSSIBLECRITERIONFORCRLQUERY);
- }
-
- /* All request fields are done */
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (store, (PKIX_PL_Object **)&lcs, plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- PKIX_CHECK(PKIX_PL_LdapClient_InitiateRequest
- ((PKIX_PL_LdapClient *)lcs,
- &requestParams,
- &pollDesc,
- &responses,
- plContext),
- PKIX_LDAPCLIENTINITIATEREQUESTFAILED);
-
- PKIX_CHECK(pkix_pl_LdapCertStore_DestroyAVAList
- (requestParams.nc, plContext),
- PKIX_LDAPCERTSTOREDESTROYAVALISTFAILED);
-
- if (requestArena) {
- PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena,
- (requestArena, PR_FALSE));
- }
-
- if (pollDesc != NULL) {
- /* client is waiting for non-blocking I/O to complete */
- *pNBIOContext = (void *)pollDesc;
- *pCrlList = NULL;
- goto cleanup;
- }
- /* client has finished! */
-
- if (responses) {
-
- /*
- * We have a List of LdapResponse objects that still have to be
- * turned into Crls.
- */
- PKIX_CHECK(pkix_pl_LdapCertStore_BuildCrlList
- (responses, &unfilteredCRLs, plContext),
- PKIX_LDAPCERTSTOREBUILDCRLLISTFAILED);
-
- PKIX_CHECK(pkix_CRLSelector_Select
- (selector, unfilteredCRLs, &filteredCRLs, plContext),
- PKIX_CRLSELECTORSELECTFAILED);
-
- }
-
- /* Don't throw away the list if one CRL was bad! */
- pkixTempErrorReceived = PKIX_FALSE;
-
- *pNBIOContext = NULL;
- *pCrlList = filteredCRLs;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(filteredCRLs);
- }
-
- PKIX_DECREF(params);
- PKIX_DECREF(issuerNames);
- PKIX_DECREF(issuer);
- PKIX_DECREF(candidate);
- PKIX_DECREF(responses);
- PKIX_DECREF(unfilteredCRLs);
- PKIX_DECREF(lcs);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapCertStore_GetCRLContinue
- * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
- */
-PKIX_Error *
-pkix_pl_LdapCertStore_GetCRLContinue(
- PKIX_CertStore *store,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrlList,
- void *plContext)
-{
- void *nbio = NULL;
- PKIX_PL_CRL *candidate = NULL;
- PKIX_List *responses = NULL;
- PKIX_PL_LdapCertStoreContext *lcs = NULL;
- PKIX_List *filteredCRLs = NULL;
- PKIX_List *unfilteredCRLs = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCRLContinue");
- PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCrlList);
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
- (store, (PKIX_PL_Object **)&lcs, plContext),
- PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
-
- PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
- ((PKIX_PL_LdapClient *)lcs, &nbio, &responses, plContext),
- PKIX_LDAPCLIENTRESUMEREQUESTFAILED);
-
- if (nbio != NULL) {
- /* client is waiting for non-blocking I/O to complete */
- *pNBIOContext = (void *)nbio;
- *pCrlList = NULL;
- goto cleanup;
- }
- /* client has finished! */
-
- if (responses) {
-
- /*
- * We have a List of LdapResponse objects that still have to be
- * turned into Crls.
- */
- PKIX_CHECK(pkix_pl_LdapCertStore_BuildCrlList
- (responses, &unfilteredCRLs, plContext),
- PKIX_LDAPCERTSTOREBUILDCRLLISTFAILED);
-
- PKIX_CHECK(pkix_CRLSelector_Select
- (selector, unfilteredCRLs, &filteredCRLs, plContext),
- PKIX_CRLSELECTORSELECTFAILED);
-
- PKIX_CHECK(PKIX_List_SetImmutable(filteredCRLs, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- }
-
- /* Don't throw away the list if one CRL was bad! */
- pkixTempErrorReceived = PKIX_FALSE;
-
- *pCrlList = filteredCRLs;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(filteredCRLs);
- }
-
- PKIX_DECREF(candidate);
- PKIX_DECREF(responses);
- PKIX_DECREF(unfilteredCRLs);
- PKIX_DECREF(lcs);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/* --Public-LdapCertStore-Functions----------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_LdapCertStore_Create
- * (see comments in pkix_samples_modules.h)
- */
-PKIX_Error *
-PKIX_PL_LdapCertStore_Create(
- PKIX_PL_LdapClient *client,
- PKIX_CertStore **pCertStore,
- void *plContext)
-{
- PKIX_CertStore *certStore = NULL;
-
- PKIX_ENTER(CERTSTORE, "PKIX_PL_LdapCertStore_Create");
- PKIX_NULLCHECK_TWO(client, pCertStore);
-
- PKIX_CHECK(PKIX_CertStore_Create
- (pkix_pl_LdapCertStore_GetCert,
- pkix_pl_LdapCertStore_GetCRL,
- pkix_pl_LdapCertStore_GetCertContinue,
- pkix_pl_LdapCertStore_GetCRLContinue,
- NULL, /* don't support trust */
- NULL, /* can not store crls */
- NULL, /* can not do revocation check */
- (PKIX_PL_Object *)client,
- PKIX_TRUE, /* cache flag */
- PKIX_FALSE, /* not local */
- &certStore,
- plContext),
- PKIX_CERTSTORECREATEFAILED);
-
- *pCertStore = certStore;
-
-cleanup:
-
- PKIX_RETURN(CERTSTORE);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.h
deleted file mode 100644
index 5bbe5385c..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapcertstore.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ldapcertstore.h
- *
- * LDAPCertstore Object Type Definition
- *
- */
-
-#ifndef _PKIX_PL_LDAPCERTSTORE_H
-#define _PKIX_PL_LDAPCERTSTORE_H
-
-#include "pkix_pl_ldapt.h"
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * At the time of this version, there are unresolved questions about the LDAP
- * protocol. Although RFC1777 describes a BIND and UNBIND message, it is not
- * clear whether they are appropriate to this application. We have tested only
- * using servers that do not expect authentication, and that reject BIND
- * messages. It is not clear what values might be appropriate for the bindname
- * and authentication fields, which are currently implemented as char strings
- * supplied by the caller. (If this changes, the API and possibly the templates
- * will have to change.) Therefore the CertStore_Create API contains a BindAPI
- * structure, a union, which will have to be revised and extended when this
- * area of the protocol is better understood.
- *
- * It is further assumed that a given LdapCertStore will connect only to a
- * single server, and that the creation of the socket will initiate the
- * CONNECT. Therefore the LdapCertStore handles only the case of continuing
- * the connection, if nonblocking I/O is being used.
- */
-
-typedef enum {
- LDAP_CONNECT_PENDING,
- LDAP_CONNECTED,
- LDAP_BIND_PENDING,
- LDAP_BIND_RESPONSE,
- LDAP_BIND_RESPONSE_PENDING,
- LDAP_BOUND,
- LDAP_SEND_PENDING,
- LDAP_RECV,
- LDAP_RECV_PENDING,
- LDAP_RECV_INITIAL,
- LDAP_RECV_NONINITIAL,
- LDAP_ABANDON_PENDING
-} LDAPConnectStatus;
-
-#define LDAP_CACHEBUCKETS 128
-#define RCVBUFSIZE 512
-
-struct PKIX_PL_LdapCertStoreContext {
- PKIX_PL_LdapClient *client;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_LdapCertStoreContext_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapCertStore_BuildCertList(
- PKIX_List *responseList,
- PKIX_List **pCerts,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_LDAPCERTSTORE_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c
deleted file mode 100644
index af425cb0b..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.c
+++ /dev/null
@@ -1,2493 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ldapdefaultclient.c
- *
- * LDAPDefaultClient Function Definitions
- *
- */
-
-/* We can't decode the length of a message without at least this many bytes */
-#define MINIMUM_MSG_LENGTH 5
-
-#include "pkix_pl_ldapdefaultclient.h"
-
-/* --Private-LdapDefaultClient-Message-Building-Functions---------------- */
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_MakeBind
- * DESCRIPTION:
- *
- * This function creates and encodes a Bind message, using the arena pointed
- * to by "arena", the version number contained in "versionData", the
- * LDAPBindAPI pointed to by "bindAPI", and the messageID contained in
- * "msgNum", and stores a pointer to the encoded string at "pBindMsg".
- *
- * See pkix_pl_ldaptemplates.c for the ASN.1 description of a Bind message.
- *
- * This code is not used if the DefaultClient was created with a NULL pointer
- * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be
- * expected for anonymous Search requests.)
- *
- * PARAMETERS:
- * "arena"
- * The address of the PRArenaPool used in encoding the message. Must be
- * non-NULL.
- * "versionData"
- * The Int32 containing the version number to be encoded in the Bind
- * message.
- * "bindAPI"
- * The address of the LDAPBindAPI to be encoded in the Bind message. Must
- * be non-NULL.
- * "msgNum"
- * The Int32 containing the MessageID to be encoded in the Bind message.
- * "pBindMsg"
- * The address at which the encoded Bind message will be stored. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_MakeBind(
- PRArenaPool *arena,
- PKIX_Int32 versionData,
- LDAPBindAPI *bindAPI,
- PKIX_UInt32 msgNum,
- SECItem **pBindMsg,
- void *plContext)
-{
- LDAPMessage msg;
- char version = '\0';
- SECItem *encoded = NULL;
- PKIX_UInt32 len = 0;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeBind");
- PKIX_NULLCHECK_TWO(arena, pBindMsg);
-
- PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset,
- (&msg, 0, sizeof (LDAPMessage)));
-
- version = (char)versionData;
-
- msg.messageID.type = siUnsignedInteger;
- msg.messageID.data = (void*)&msgNum;
- msg.messageID.len = sizeof (msgNum);
-
- msg.protocolOp.selector = LDAP_BIND_TYPE;
-
- msg.protocolOp.op.bindMsg.version.type = siUnsignedInteger;
- msg.protocolOp.op.bindMsg.version.data = (void *)&version;
- msg.protocolOp.op.bindMsg.version.len = sizeof (char);
-
- /*
- * XXX At present we only know how to handle anonymous requests (no
- * authentication), and we are guessing how to do simple authentication.
- * This section will need to be revised and extended when other
- * authentication is needed.
- */
- if (bindAPI->selector == SIMPLE_AUTH) {
- msg.protocolOp.op.bindMsg.bindName.type = siAsciiString;
- msg.protocolOp.op.bindMsg.bindName.data =
- (void *)bindAPI->chooser.simple.bindName;
- len = PL_strlen(bindAPI->chooser.simple.bindName);
- msg.protocolOp.op.bindMsg.bindName.len = len;
-
- msg.protocolOp.op.bindMsg.authentication.type = siAsciiString;
- msg.protocolOp.op.bindMsg.authentication.data =
- (void *)bindAPI->chooser.simple.authentication;
- len = PL_strlen(bindAPI->chooser.simple.authentication);
- msg.protocolOp.op.bindMsg.authentication.len = len;
- }
-
- PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem,
- (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
- if (!encoded) {
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
- }
-
- *pBindMsg = encoded;
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_MakeUnbind
- * DESCRIPTION:
- *
- * This function creates and encodes a Unbind message, using the arena pointed
- * to by "arena" and the messageID contained in "msgNum", and stores a pointer
- * to the encoded string at "pUnbindMsg".
- *
- * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Unbind message.
- *
- * This code is not used if the DefaultClient was created with a NULL pointer
- * supplied for the LDAPBindAPI structure. (Bind and Unbind do not seem to be
- * expected for anonymous Search requests.)
- *
- * PARAMETERS:
- * "arena"
- * The address of the PRArenaPool used in encoding the message. Must be
- * non-NULL.
- * "msgNum"
- * The Int32 containing the MessageID to be encoded in the Unbind message.
- * "pUnbindMsg"
- * The address at which the encoded Unbind message will be stored. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_MakeUnbind(
- PRArenaPool *arena,
- PKIX_UInt32 msgNum,
- SECItem **pUnbindMsg,
- void *plContext)
-{
- LDAPMessage msg;
- SECItem *encoded = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeUnbind");
- PKIX_NULLCHECK_TWO(arena, pUnbindMsg);
-
- PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset,
- (&msg, 0, sizeof (LDAPMessage)));
-
- msg.messageID.type = siUnsignedInteger;
- msg.messageID.data = (void*)&msgNum;
- msg.messageID.len = sizeof (msgNum);
-
- msg.protocolOp.selector = LDAP_UNBIND_TYPE;
-
- msg.protocolOp.op.unbindMsg.dummy.type = siBuffer;
- msg.protocolOp.op.unbindMsg.dummy.data = NULL;
- msg.protocolOp.op.unbindMsg.dummy.len = 0;
-
- PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem,
- (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
- if (!encoded) {
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
- }
-
- *pUnbindMsg = encoded;
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_MakeAbandon
- * DESCRIPTION:
- *
- * This function creates and encodes a Abandon message, using the arena pointed
- * to by "arena" and the messageID contained in "msgNum", and stores a pointer
- * to the encoded string at "pAbandonMsg".
- *
- * See pkix_pl_ldaptemplates.c for the ASN.1 description of an Abandon message.
- *
- * PARAMETERS:
- * "arena"
- * The address of the PRArenaPool used in encoding the message. Must be
- * non-NULL.
- * "msgNum"
- * The Int32 containing the MessageID to be encoded in the Abandon message.
- * "pAbandonMsg"
- * The address at which the encoded Abandon message will be stored. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_MakeAbandon(
- PRArenaPool *arena,
- PKIX_UInt32 msgNum,
- SECItem **pAbandonMsg,
- void *plContext)
-{
- LDAPMessage msg;
- SECItem *encoded = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_MakeAbandon");
- PKIX_NULLCHECK_TWO(arena, pAbandonMsg);
-
- PKIX_PL_NSSCALL(LDAPDEFAULTCLIENT, PORT_Memset,
- (&msg, 0, sizeof (LDAPMessage)));
-
- msg.messageID.type = siUnsignedInteger;
- msg.messageID.data = (void*)&msgNum;
- msg.messageID.len = sizeof (msgNum);
-
- msg.protocolOp.selector = LDAP_ABANDONREQUEST_TYPE;
-
- msg.protocolOp.op.abandonRequestMsg.messageID.type = siBuffer;
- msg.protocolOp.op.abandonRequestMsg.messageID.data = (void*)&msgNum;
- msg.protocolOp.op.abandonRequestMsg.messageID.len = sizeof (msgNum);
-
- PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, encoded, SEC_ASN1EncodeItem,
- (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
- if (!encoded) {
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
- }
-
- *pAbandonMsg = encoded;
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_DecodeBindResponse
- * DESCRIPTION:
- *
- * This function decodes the encoded data pointed to by "src", using the arena
- * pointed to by "arena", storing the decoded LDAPMessage at "pBindResponse"
- * and the decoding status at "pStatus".
- *
- * PARAMETERS:
- * "arena"
- * The address of the PRArenaPool to be used in decoding the message. Must
- * be non-NULL.
- * "src"
- * The address of the SECItem containing the DER- (or BER-)encoded string.
- * Must be non-NULL.
- * "pBindResponse"
- * The address at which the LDAPMessage is stored, if the decoding is
- * successful (the returned status is SECSuccess). Must be non-NULL.
- * "pStatus"
- * The address at which the decoding status is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_DecodeBindResponse(
- PRArenaPool *arena,
- SECItem *src,
- LDAPMessage *pBindResponse,
- SECStatus *pStatus,
- void *plContext)
-{
- SECStatus rv = SECFailure;
- LDAPMessage response;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT,
- "pkix_pl_LdapDefaultClient_DecodeBindResponse");
- PKIX_NULLCHECK_FOUR(arena, src, pBindResponse, pStatus);
-
- PKIX_PL_NSSCALL
- (LDAPDEFAULTCLIENT,
- PORT_Memset,
- (&response, 0, sizeof (LDAPMessage)));
-
- PKIX_PL_NSSCALLRV(LDAPDEFAULTCLIENT, rv, SEC_ASN1DecodeItem,
- (arena, &response, PKIX_PL_LDAPMessageTemplate, src));
-
- if (rv == SECSuccess) {
- *pBindResponse = response;
- }
-
- *pStatus = rv;
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_VerifyBindResponse
- * DESCRIPTION:
- *
- * This function verifies that the contents of the message in the rcvbuf of
- * the LdapDefaultClient object pointed to by "client", and whose length is
- * provided by "buflen", is a response to a successful Bind.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "buflen"
- * The value of the number of bytes in the receive buffer.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_VerifyBindResponse(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_UInt32 bufLen,
- void *plContext)
-{
- SECItem decode = {siBuffer, NULL, 0};
- SECStatus rv = SECFailure;
- LDAPMessage msg;
- LDAPBindResponse *ldapBindResponse = NULL;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT,
- "pkix_pl_LdapDefaultClient_VerifyBindResponse");
- PKIX_NULLCHECK_TWO(client, client->rcvBuf);
-
- decode.data = (void *)(client->rcvBuf);
- decode.len = bufLen;
-
- PKIX_CHECK(pkix_pl_LdapDefaultClient_DecodeBindResponse
- (client->arena, &decode, &msg, &rv, plContext),
- PKIX_LDAPDEFAULTCLIENTDECODEBINDRESPONSEFAILED);
-
- if (rv == SECSuccess) {
- ldapBindResponse = &msg.protocolOp.op.bindResponseMsg;
- if (*(ldapBindResponse->resultCode.data) == SUCCESS) {
- client->connectStatus = BOUND;
- } else {
- PKIX_ERROR(PKIX_BINDREJECTEDBYSERVER);
- }
- } else {
- PKIX_ERROR(PKIX_CANTDECODEBINDRESPONSEFROMSERVER);
- }
-
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_RecvCheckComplete
- * DESCRIPTION:
- *
- * This function determines whether the current response in the
- * LdapDefaultClient pointed to by "client" is complete, in the sense that all
- * bytes required to satisfy the message length field in the encoding have been
- * received. If so, the pointer to input data is updated to reflect the number
- * of bytes consumed, provided by "bytesProcessed". The state machine flag
- * pointed to by "pKeepGoing" is updated to indicate whether processing can
- * continue without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "bytesProcessed"
- * The UInt32 value of the number of bytes consumed from the current
- * buffer.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_RecvCheckComplete(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_UInt32 bytesProcessed,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_Boolean complete = PKIX_FALSE;
- SECStatus rv = SECFailure;
- LDAPMessageType messageType = 0;
- LDAPResultCode resultCode = 0;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT,
- "pkix_pl_LdapDefaultClient_RecvCheckComplete");
- PKIX_NULLCHECK_TWO(client, pKeepGoing);
-
- PKIX_CHECK(pkix_pl_LdapResponse_IsComplete
- (client->currentResponse, &complete, plContext),
- PKIX_LDAPRESPONSEISCOMPLETEFAILED);
-
- if (complete) {
- PKIX_CHECK(pkix_pl_LdapResponse_Decode
- (client->arena, client->currentResponse, &rv, plContext),
- PKIX_LDAPRESPONSEDECODEFAILED);
-
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_CANTDECODESEARCHRESPONSEFROMSERVER);
- }
-
- PKIX_CHECK(pkix_pl_LdapResponse_GetMessageType
- (client->currentResponse, &messageType, plContext),
- PKIX_LDAPRESPONSEGETMESSAGETYPEFAILED);
-
- if (messageType == LDAP_SEARCHRESPONSEENTRY_TYPE) {
-
- if (client->entriesFound == NULL) {
- PKIX_CHECK(PKIX_List_Create
- (&(client->entriesFound), plContext),
- PKIX_LISTCREATEFAILED);
- }
-
- PKIX_CHECK(PKIX_List_AppendItem
- (client->entriesFound,
- (PKIX_PL_Object *)client->currentResponse,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(client->currentResponse);
-
- /* current receive buffer empty? */
- if (client->currentBytesAvailable == 0) {
- client->connectStatus = RECV;
- *pKeepGoing = PKIX_TRUE;
- } else {
- client->connectStatus = RECV_INITIAL;
- client->currentInPtr = &((char *)
- (client->currentInPtr))[bytesProcessed];
- *pKeepGoing = PKIX_TRUE;
- }
-
- } else if (messageType == LDAP_SEARCHRESPONSERESULT_TYPE) {
- PKIX_CHECK(pkix_pl_LdapResponse_GetResultCode
- (client->currentResponse,
- &resultCode,
- plContext),
- PKIX_LDAPRESPONSEGETRESULTCODEFAILED);
-
- if ((client->entriesFound == NULL) &&
- ((resultCode == SUCCESS) ||
- (resultCode == NOSUCHOBJECT))) {
- PKIX_CHECK(PKIX_List_Create
- (&(client->entriesFound), plContext),
- PKIX_LISTCREATEFAILED);
- } else if (resultCode == SUCCESS) {
- PKIX_CHECK(PKIX_List_SetImmutable
- (client->entriesFound, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
- PKIX_CHECK(PKIX_PL_HashTable_Add
- (client->cachePtr,
- (PKIX_PL_Object *)client->currentRequest,
- (PKIX_PL_Object *)client->entriesFound,
- plContext),
- PKIX_HASHTABLEADDFAILED);
- } else {
- PKIX_ERROR(PKIX_UNEXPECTEDRESULTCODEINRESPONSE);
- }
-
- client->connectStatus = BOUND;
- *pKeepGoing = PKIX_FALSE;
- PKIX_DECREF(client->currentResponse);
-
- } else {
- PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE);
- }
- } else {
- client->connectStatus = RECV;
- *pKeepGoing = PKIX_TRUE;
- }
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/* --Private-LdapDefaultClient-Object-Functions------------------------- */
-
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_InitiateRequest(
- PKIX_PL_LdapClient *client,
- LDAPRequestParams *requestParams,
- void **pPollDesc,
- PKIX_List **pResponse,
- void *plContext);
-
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_ResumeRequest(
- PKIX_PL_LdapClient *client,
- void **pPollDesc,
- PKIX_List **pResponse,
- void *plContext);
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_CreateHelper
- * DESCRIPTION:
- *
- * This function creates a new LdapDefaultClient using the Socket pointed to
- * by "socket", the PRIntervalTime pointed to by "timeout", and the
- * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
- *
- * A value of zero for "timeout" means the LDAPClient will use non-blocking
- * I/O.
- *
- * PARAMETERS:
- * "socket"
- * Address of the Socket to be used for the client. Must be non-NULL.
- * "bindAPI"
- * The address of the LDAPBindAPI containing the Bind information to be
- * encoded in the Bind message.
- * "pClient"
- * The address at which the created LdapDefaultClient is to be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapDefaultClient_CreateHelper(
- PKIX_PL_Socket *socket,
- LDAPBindAPI *bindAPI,
- PKIX_PL_LdapDefaultClient **pClient,
- void *plContext)
-{
- PKIX_PL_HashTable *ht;
- PKIX_PL_LdapDefaultClient *ldapDefaultClient = NULL;
- PKIX_PL_Socket_Callback *callbackList;
- PRFileDesc *fileDesc = NULL;
- PRArenaPool *arena = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_CreateHelper");
- PKIX_NULLCHECK_TWO(socket, pClient);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_LDAPDEFAULTCLIENT_TYPE,
- sizeof (PKIX_PL_LdapDefaultClient),
- (PKIX_PL_Object **)&ldapDefaultClient,
- plContext),
- PKIX_COULDNOTCREATELDAPDEFAULTCLIENTOBJECT);
-
- ldapDefaultClient->vtable.initiateFcn =
- pkix_pl_LdapDefaultClient_InitiateRequest;
- ldapDefaultClient->vtable.resumeFcn =
- pkix_pl_LdapDefaultClient_ResumeRequest;
-
- PKIX_CHECK(pkix_pl_Socket_GetPRFileDesc
- (socket, &fileDesc, plContext),
- PKIX_SOCKETGETPRFILEDESCFAILED);
-
- ldapDefaultClient->pollDesc.fd = fileDesc;
- ldapDefaultClient->pollDesc.in_flags = 0;
- ldapDefaultClient->pollDesc.out_flags = 0;
-
- ldapDefaultClient->bindAPI = bindAPI;
-
- PKIX_CHECK(PKIX_PL_HashTable_Create
- (LDAP_CACHEBUCKETS, 0, &ht, plContext),
- PKIX_HASHTABLECREATEFAILED);
-
- ldapDefaultClient->cachePtr = ht;
-
- PKIX_CHECK(pkix_pl_Socket_GetCallbackList
- (socket, &callbackList, plContext),
- PKIX_SOCKETGETCALLBACKLISTFAILED);
-
- ldapDefaultClient->callbackList = callbackList;
-
- PKIX_INCREF(socket);
- ldapDefaultClient->clientSocket = socket;
-
- ldapDefaultClient->messageID = 0;
-
- ldapDefaultClient->bindAPI = bindAPI;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena) {
- PKIX_ERROR_FATAL(PKIX_OUTOFMEMORY);
- }
- ldapDefaultClient->arena = arena;
-
- ldapDefaultClient->sendBuf = NULL;
- ldapDefaultClient->bytesToWrite = 0;
-
- PKIX_CHECK(PKIX_PL_Malloc
- (RCVBUFSIZE, &ldapDefaultClient->rcvBuf, plContext),
- PKIX_MALLOCFAILED);
- ldapDefaultClient->capacity = RCVBUFSIZE;
-
- ldapDefaultClient->bindMsg = NULL;
- ldapDefaultClient->bindMsgLen = 0;
-
- ldapDefaultClient->entriesFound = NULL;
- ldapDefaultClient->currentRequest = NULL;
- ldapDefaultClient->currentResponse = NULL;
-
- *pClient = ldapDefaultClient;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(ldapDefaultClient);
- }
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: PKIX_PL_LdapDefaultClient_Create
- * DESCRIPTION:
- *
- * This function creates a new LdapDefaultClient using the PRNetAddr pointed to
- * by "sockaddr", the PRIntervalTime pointed to by "timeout", and the
- * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
- *
- * A value of zero for "timeout" means the LDAPClient will use non-blocking
- * I/O.
- *
- * PARAMETERS:
- * "sockaddr"
- * Address of the PRNetAddr to be used for the socket connection. Must be
- * non-NULL.
- * "timeout"
- * The PRIntervalTime to be used in I/O requests for this client.
- * "bindAPI"
- * The address of the LDAPBindAPI containing the Bind information to be
- * encoded in the Bind message.
- * "pClient"
- * The address at which the created LdapDefaultClient is to be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_LdapDefaultClient_Create(
- PRNetAddr *sockaddr,
- PRIntervalTime timeout,
- LDAPBindAPI *bindAPI,
- PKIX_PL_LdapDefaultClient **pClient,
- void *plContext)
-{
- PRErrorCode status = 0;
- PKIX_PL_Socket *socket = NULL;
- PKIX_PL_LdapDefaultClient *client = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "PKIX_PL_LdapDefaultClient_Create");
- PKIX_NULLCHECK_TWO(sockaddr, pClient);
-
- PKIX_CHECK(pkix_pl_Socket_Create
- (PKIX_FALSE, timeout, sockaddr, &status, &socket, plContext),
- PKIX_SOCKETCREATEFAILED);
-
- PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper
- (socket, bindAPI, &client, plContext),
- PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED);
-
- /* Did Socket_Create say the connection was made? */
- if (status == 0) {
- if (client->bindAPI != NULL) {
- client->connectStatus = CONNECTED;
- } else {
- client->connectStatus = BOUND;
- }
- } else {
- client->connectStatus = CONNECT_PENDING;
- }
-
- *pClient = client;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(client);
- }
-
- PKIX_DECREF(socket);
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: PKIX_PL_LdapDefaultClient_CreateByName
- * DESCRIPTION:
- *
- * This function creates a new LdapDefaultClient using the hostname pointed to
- * by "hostname", the PRIntervalTime pointed to by "timeout", and the
- * LDAPBindAPI pointed to by "bindAPI", and stores the result at "pClient".
- *
- * A value of zero for "timeout" means the LDAPClient will use non-blocking
- * I/O.
- *
- * PARAMETERS:
- * "hostname"
- * Address of the hostname to be used for the socket connection. Must be
- * non-NULL.
- * "timeout"
- * The PRIntervalTime to be used in I/O requests for this client.
- * "bindAPI"
- * The address of the LDAPBindAPI containing the Bind information to be
- * encoded in the Bind message.
- * "pClient"
- * The address at which the created LdapDefaultClient is to be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_LdapDefaultClient_CreateByName(
- char *hostname,
- PRIntervalTime timeout,
- LDAPBindAPI *bindAPI,
- PKIX_PL_LdapDefaultClient **pClient,
- void *plContext)
-{
- PRErrorCode status = 0;
- PKIX_PL_Socket *socket = NULL;
- PKIX_PL_LdapDefaultClient *client = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "PKIX_PL_LdapDefaultClient_CreateByName");
- PKIX_NULLCHECK_TWO(hostname, pClient);
-
- PKIX_CHECK(pkix_pl_Socket_CreateByName
- (PKIX_FALSE, timeout, hostname, &status, &socket, plContext),
- PKIX_SOCKETCREATEBYNAMEFAILED);
-
- PKIX_CHECK(pkix_pl_LdapDefaultClient_CreateHelper
- (socket, bindAPI, &client, plContext),
- PKIX_LDAPDEFAULTCLIENTCREATEHELPERFAILED);
-
- /* Did Socket_Create say the connection was made? */
- if (status == 0) {
- if (client->bindAPI != NULL) {
- client->connectStatus = CONNECTED;
- } else {
- client->connectStatus = BOUND;
- }
- } else {
- client->connectStatus = CONNECT_PENDING;
- }
-
- *pClient = client;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(client);
- }
-
- PKIX_DECREF(socket);
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_Int32 bytesWritten = 0;
- PKIX_PL_LdapDefaultClient *client = NULL;
- PKIX_PL_Socket_Callback *callbackList = NULL;
- SECItem *encoded = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT,
- "pkix_pl_LdapDefaultClient_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_LDAPDEFAULTCLIENT_TYPE, plContext),
- PKIX_OBJECTNOTANLDAPDEFAULTCLIENT);
-
- client = (PKIX_PL_LdapDefaultClient *)object;
-
- switch (client->connectStatus) {
- case CONNECT_PENDING:
- break;
- case CONNECTED:
- case BIND_PENDING:
- case BIND_RESPONSE:
- case BIND_RESPONSE_PENDING:
- case BOUND:
- case SEND_PENDING:
- case RECV:
- case RECV_PENDING:
- case RECV_INITIAL:
- case RECV_NONINITIAL:
- case ABANDON_PENDING:
- if (client->bindAPI != NULL) {
- PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeUnbind
- (client->arena,
- ++(client->messageID),
- &encoded,
- plContext),
- PKIX_LDAPDEFAULTCLIENTMAKEUNBINDFAILED);
-
- callbackList =
- (PKIX_PL_Socket_Callback *)(client->callbackList);
- PKIX_CHECK(callbackList->sendCallback
- (client->clientSocket,
- encoded->data,
- encoded->len,
- &bytesWritten,
- plContext),
- PKIX_SOCKETSENDFAILED);
- }
- break;
- default:
- PKIX_ERROR(PKIX_LDAPDEFAULTCLIENTINILLEGALSTATE);
- }
-
- PKIX_DECREF(client->cachePtr);
- PKIX_DECREF(client->clientSocket);
- PKIX_DECREF(client->entriesFound);
- PKIX_DECREF(client->currentRequest);
- PKIX_DECREF(client->currentResponse);
-
- PKIX_CHECK(PKIX_PL_Free
- (client->rcvBuf, plContext), PKIX_FREEFAILED);
-
- PKIX_PL_NSSCALL
- (LDAPDEFAULTCLIENT,
- PORT_FreeArena,
- (client->arena, PR_FALSE));
-
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_LdapDefaultClient *ldapDefaultClient = NULL;
- PKIX_UInt32 tempHash = 0;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_LDAPDEFAULTCLIENT_TYPE, plContext),
- PKIX_OBJECTNOTANLDAPDEFAULTCLIENT);
-
- ldapDefaultClient = (PKIX_PL_LdapDefaultClient *)object;
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)ldapDefaultClient->clientSocket,
- &tempHash,
- plContext),
- PKIX_SOCKETHASHCODEFAILED);
-
- if (ldapDefaultClient->bindAPI != NULL) {
- tempHash = (tempHash << 7) +
- ldapDefaultClient->bindAPI->selector;
- }
-
- *pHashcode = tempHash;
-
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PKIX_PL_LdapDefaultClient *firstClientContext = NULL;
- PKIX_PL_LdapDefaultClient *secondClientContext = NULL;
- PKIX_Int32 compare = 0;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- *pResult = PKIX_FALSE;
-
- PKIX_CHECK(pkix_CheckTypes
- (firstObject,
- secondObject,
- PKIX_LDAPDEFAULTCLIENT_TYPE,
- plContext),
- PKIX_OBJECTNOTANLDAPDEFAULTCLIENT);
-
- firstClientContext = (PKIX_PL_LdapDefaultClient *)firstObject;
- secondClientContext = (PKIX_PL_LdapDefaultClient *)secondObject;
-
- if (firstClientContext == secondClientContext) {
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstClientContext->clientSocket,
- (PKIX_PL_Object *)secondClientContext->clientSocket,
- &compare,
- plContext),
- PKIX_SOCKETEQUALSFAILED);
-
- if (!compare) {
- goto cleanup;
- }
-
- if (PKIX_EXACTLY_ONE_NULL
- (firstClientContext->bindAPI, secondClientContext->bindAPI)) {
- goto cleanup;
- }
-
- if (firstClientContext->bindAPI) {
- if (firstClientContext->bindAPI->selector !=
- secondClientContext->bindAPI->selector) {
- goto cleanup;
- }
- }
-
- *pResult = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_PL_LDAPDEFAULTCLIENT_TYPE and its related
- * functions with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_LdapDefaultClient_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT,
- "pkix_pl_LdapDefaultClient_RegisterSelf");
-
- entry.description = "LdapDefaultClient";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_LdapDefaultClient);
- entry.destructor = pkix_pl_LdapDefaultClient_Destroy;
- entry.equalsFunction = pkix_pl_LdapDefaultClient_Equals;
- entry.hashcodeFunction = pkix_pl_LdapDefaultClient_Hashcode;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_LDAPDEFAULTCLIENT_TYPE] = entry;
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_GetPollDesc
- * DESCRIPTION:
- *
- * This function retrieves the PRPollDesc from the LdapDefaultClient
- * pointed to by "context" and stores the address at "pPollDesc".
- *
- * PARAMETERS:
- * "context"
- * The LdapDefaultClient whose PRPollDesc is desired. Must be non-NULL.
- * "pPollDesc"
- * Address where PRPollDesc will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapDefaultClient_GetPollDesc(
- PKIX_PL_LdapDefaultClient *context,
- PRPollDesc **pPollDesc,
- void *plContext)
-{
- PKIX_ENTER
- (LDAPDEFAULTCLIENT,
- "pkix_pl_LdapDefaultClient_GetPollDesc");
- PKIX_NULLCHECK_TWO(context, pPollDesc);
-
- *pPollDesc = &(context->pollDesc);
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/* --Private-Ldap-CertStore-I/O-Functions---------------------------- */
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_ConnectContinue
- * DESCRIPTION:
- *
- * This function determines whether a socket Connect initiated earlier for the
- * CertStore embodied in the LdapDefaultClient "client" has completed, and
- * stores in "pKeepGoing" a flag indicating whether processing can continue
- * without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_ConnectContinue(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_PL_Socket_Callback *callbackList;
- PRErrorCode status;
- PKIX_Boolean keepGoing = PKIX_FALSE;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT,
- "pkix_pl_LdapDefaultClient_ConnectContinue");
- PKIX_NULLCHECK_ONE(client);
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- PKIX_CHECK(callbackList->connectcontinueCallback
- (client->clientSocket, &status, plContext),
- PKIX_SOCKETCONNECTCONTINUEFAILED);
-
- if (status == 0) {
- if (client->bindAPI != NULL) {
- client->connectStatus = CONNECTED;
- } else {
- client->connectStatus = BOUND;
- }
- keepGoing = PKIX_FALSE;
- } else if (status != PR_IN_PROGRESS_ERROR) {
- PKIX_ERROR(PKIX_UNEXPECTEDERRORINESTABLISHINGCONNECTION);
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- *pKeepGoing = keepGoing;
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_Bind
- * DESCRIPTION:
- *
- * This function creates and sends the LDAP-protocol Bind message for the
- * CertStore embodied in the LdapDefaultClient "client", and stores in
- * "pKeepGoing" a flag indicating whether processing can continue without
- * further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_Bind(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- SECItem *encoded = NULL;
- PKIX_Int32 bytesWritten = 0;
- PKIX_PL_Socket_Callback *callbackList;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Bind");
- PKIX_NULLCHECK_ONE(client);
-
- /* if we have not yet constructed the BIND message, build it now */
- if (!(client->bindMsg)) {
- PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeBind
- (client->arena,
- 3,
- client->bindAPI,
- client->messageID,
- &encoded,
- plContext),
- PKIX_LDAPDEFAULTCLIENTMAKEBINDFAILED);
- client->bindMsg = encoded->data;
- client->bindMsgLen = encoded->len;
- }
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- PKIX_CHECK(callbackList->sendCallback
- (client->clientSocket,
- client->bindMsg,
- client->bindMsgLen,
- &bytesWritten,
- plContext),
- PKIX_SOCKETSENDFAILED);
-
- client->lastIO = PR_Now();
-
- if (bytesWritten < 0) {
- client->connectStatus = BIND_PENDING;
- *pKeepGoing = PKIX_FALSE;
- } else {
- client->connectStatus = BIND_RESPONSE;
- *pKeepGoing = PKIX_TRUE;
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_BindContinue
- * DESCRIPTION:
- *
- * This function determines whether the LDAP-protocol Bind message for the
- * CertStore embodied in the LdapDefaultClient "client" has completed, and
- * stores in "pKeepGoing" a flag indicating whether processing can continue
- * without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *pkix_pl_LdapDefaultClient_BindContinue(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_Int32 bytesWritten = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_BindContinue");
- PKIX_NULLCHECK_ONE(client);
-
- *pKeepGoing = PKIX_FALSE;
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- PKIX_CHECK(callbackList->pollCallback
- (client->clientSocket, &bytesWritten, NULL, plContext),
- PKIX_SOCKETPOLLFAILED);
-
- /*
- * If the send completed we can proceed to try for the
- * response. If the send did not complete we will have
- * continue to poll.
- */
- if (bytesWritten >= 0) {
-
- client->connectStatus = BIND_RESPONSE;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- *pKeepGoing = PKIX_TRUE;
- }
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_BindResponse
- * DESCRIPTION:
- *
- * This function attempts to read the LDAP-protocol BindResponse message for
- * the CertStore embodied in the LdapDefaultClient "client", and stores in
- * "pKeepGoing" a flag indicating whether processing can continue without
- * further input.
- *
- * If a BindResponse is received with a Result code of 0 (success), we
- * continue with the connection. If a non-zero Result code is received,
- * we throw an Error. Some more sophisticated handling of that condition
- * might be in order in the future.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_BindResponse(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_Int32 bytesRead = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_BindResponse");
- PKIX_NULLCHECK_TWO(client, client->rcvBuf);
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- PKIX_CHECK(callbackList->recvCallback
- (client->clientSocket,
- client->rcvBuf,
- client->capacity,
- &bytesRead,
- plContext),
- PKIX_SOCKETRECVFAILED);
-
- client->lastIO = PR_Now();
-
- if (bytesRead > 0) {
- PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse
- (client, bytesRead, plContext),
- PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED);
- /*
- * XXX What should we do if failure? At present if
- * VerifyBindResponse throws an Error, we do too.
- */
- client->connectStatus = BOUND;
- } else {
- client->connectStatus = BIND_RESPONSE_PENDING;
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- *pKeepGoing = PKIX_TRUE;
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_BindResponseContinue
- * DESCRIPTION:
- *
- * This function determines whether the LDAP-protocol BindResponse message for
- * the CertStore embodied in the LdapDefaultClient "client" has completed, and
- * stores in "pKeepGoing" a flag indicating whether processing can continue
- * without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_BindResponseContinue(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_Int32 bytesRead = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT,
- "pkix_pl_LdapDefaultClient_BindResponseContinue");
- PKIX_NULLCHECK_ONE(client);
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- PKIX_CHECK(callbackList->pollCallback
- (client->clientSocket, NULL, &bytesRead, plContext),
- PKIX_SOCKETPOLLFAILED);
-
- if (bytesRead > 0) {
- PKIX_CHECK(pkix_pl_LdapDefaultClient_VerifyBindResponse
- (client, bytesRead, plContext),
- PKIX_LDAPDEFAULTCLIENTVERIFYBINDRESPONSEFAILED);
- client->connectStatus = BOUND;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- *pKeepGoing = PKIX_TRUE;
- } else {
- *pKeepGoing = PKIX_FALSE;
- }
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_Send
- * DESCRIPTION:
- *
- * This function creates and sends an LDAP-protocol message for the
- * CertStore embodied in the LdapDefaultClient "client", and stores in
- * "pKeepGoing" a flag indicating whether processing can continue without
- * further input, and at "pBytesTransferred" the number of bytes sent.
- *
- * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
- * and that transmission has not completed.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "pBytesTransferred"
- * The address at which the number of bytes sent is stored. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_Send(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- PKIX_UInt32 *pBytesTransferred,
- void *plContext)
-{
- PKIX_Int32 bytesWritten = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Send");
- PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);
-
- *pKeepGoing = PKIX_FALSE;
-
- /* Do we have anything waiting to go? */
- if (client->sendBuf) {
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- PKIX_CHECK(callbackList->sendCallback
- (client->clientSocket,
- client->sendBuf,
- client->bytesToWrite,
- &bytesWritten,
- plContext),
- PKIX_SOCKETSENDFAILED);
-
- client->lastIO = PR_Now();
-
- /*
- * If the send completed we can proceed to try for the
- * response. If the send did not complete we will have
- * to poll for completion later.
- */
- if (bytesWritten >= 0) {
- client->sendBuf = NULL;
- client->connectStatus = RECV;
- *pKeepGoing = PKIX_TRUE;
-
- } else {
- *pKeepGoing = PKIX_FALSE;
- client->connectStatus = SEND_PENDING;
- }
-
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- *pBytesTransferred = bytesWritten;
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_SendContinue
- * DESCRIPTION:
- *
- * This function determines whether the sending of the LDAP-protocol message
- * for the CertStore embodied in the LdapDefaultClient "client" has completed,
- * and stores in "pKeepGoing" a flag indicating whether processing can continue
- * without further input, and at "pBytesTransferred" the number of bytes sent.
- *
- * If "pBytesTransferred" is zero, it indicates that non-blocking I/O is in use
- * and that transmission has not completed.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "pBytesTransferred"
- * The address at which the number of bytes sent is stored. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_SendContinue(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- PKIX_UInt32 *pBytesTransferred,
- void *plContext)
-{
- PKIX_Int32 bytesWritten = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_SendContinue");
- PKIX_NULLCHECK_THREE(client, pKeepGoing, pBytesTransferred);
-
- *pKeepGoing = PKIX_FALSE;
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- PKIX_CHECK(callbackList->pollCallback
- (client->clientSocket, &bytesWritten, NULL, plContext),
- PKIX_SOCKETPOLLFAILED);
-
- /*
- * If the send completed we can proceed to try for the
- * response. If the send did not complete we will have
- * continue to poll.
- */
- if (bytesWritten >= 0) {
- client->sendBuf = NULL;
- client->connectStatus = RECV;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
- *pKeepGoing = PKIX_TRUE;
- }
-
- *pBytesTransferred = bytesWritten;
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_Recv
- * DESCRIPTION:
- *
- * This function receives an LDAP-protocol message for the CertStore embodied
- * in the LdapDefaultClient "client", and stores in "pKeepGoing" a flag
- * indicating whether processing can continue without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_Recv(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_Int32 bytesRead = 0;
- PKIX_UInt32 bytesToRead = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Recv");
- PKIX_NULLCHECK_THREE(client, pKeepGoing, client->rcvBuf);
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- /*
- * If we attempt to fill our buffer with every read, we increase
- * the risk of an ugly situation: one or two bytes of a new message
- * left over at the end of processing one message. With such a
- * fragment, we can't decode a byte count and so won't know how much
- * space to allocate for the next LdapResponse. We try to avoid that
- * case by reading just enough to complete the current message, unless
- * there will be at least MINIMUM_MSG_LENGTH bytes left over.
- */
- if (client->currentResponse) {
- PKIX_CHECK(pkix_pl_LdapResponse_GetCapacity
- (client->currentResponse, &bytesToRead, plContext),
- PKIX_LDAPRESPONSEGETCAPACITYFAILED);
- if ((bytesToRead > client->capacity) ||
- ((bytesToRead + MINIMUM_MSG_LENGTH) < client->capacity)) {
- bytesToRead = client->capacity;
- }
- } else {
- bytesToRead = client->capacity;
- }
-
- client->currentBytesAvailable = 0;
-
- PKIX_CHECK(callbackList->recvCallback
- (client->clientSocket,
- (void *)client->rcvBuf,
- bytesToRead,
- &bytesRead,
- plContext),
- PKIX_SOCKETRECVFAILED);
-
- client->currentInPtr = client->rcvBuf;
- client->lastIO = PR_Now();
-
- if (bytesRead > 0) {
- client->currentBytesAvailable = bytesRead;
- client->connectStatus = RECV_INITIAL;
- *pKeepGoing = PKIX_TRUE;
- } else {
- client->connectStatus = RECV_PENDING;
- *pKeepGoing = PKIX_FALSE;
- }
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_RecvContinue
- * DESCRIPTION:
- *
- * This function determines whether the receiving of the LDAP-protocol message
- * for the CertStore embodied in the LdapDefaultClient "client" has completed,
- * and stores in "pKeepGoing" a flag indicating whether processing can continue
- * without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_RecvContinue(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_Int32 bytesRead = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvContinue");
- PKIX_NULLCHECK_TWO(client, pKeepGoing);
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- PKIX_CHECK(callbackList->pollCallback
- (client->clientSocket, NULL, &bytesRead, plContext),
- PKIX_SOCKETPOLLFAILED);
-
- if (bytesRead > 0) {
- client->currentBytesAvailable += bytesRead;
- client->connectStatus = RECV_INITIAL;
- *pKeepGoing = PKIX_TRUE;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
- } else {
- *pKeepGoing = PKIX_FALSE;
- }
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_AbandonContinue
- * DESCRIPTION:
- *
- * This function determines whether the abandon-message request of the
- * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient
- * "client" has completed, and stores in "pKeepGoing" a flag indicating whether
- * processing can continue without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_AbandonContinue(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- PKIX_Int32 bytesWritten = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_AbandonContinue");
- PKIX_NULLCHECK_TWO(client, pKeepGoing);
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
-
- PKIX_CHECK(callbackList->pollCallback
- (client->clientSocket, &bytesWritten, NULL, plContext),
- PKIX_SOCKETPOLLFAILED);
-
- if (bytesWritten > 0) {
- client->connectStatus = BOUND;
- *pKeepGoing = PKIX_TRUE;
-
- PKIX_CHECK(PKIX_PL_Object_InvalidateCache
- ((PKIX_PL_Object *)client, plContext),
- PKIX_OBJECTINVALIDATECACHEFAILED);
- } else {
- *pKeepGoing = PKIX_FALSE;
- }
-
-cleanup:
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_RecvInitial
- * DESCRIPTION:
- *
- * This function processes the contents of the first buffer of a received
- * LDAP-protocol message for the CertStore embodied in the LdapDefaultClient
- * "client", and stores in "pKeepGoing" a flag indicating whether processing can
- * continue without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_RecvInitial(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
- unsigned char *msgBuf = NULL;
- unsigned char *to = NULL;
- unsigned char *from = NULL;
- PKIX_UInt32 dataIndex = 0;
- PKIX_UInt32 messageIdLen = 0;
- PKIX_UInt32 messageLength = 0;
- PKIX_UInt32 sizeofLength = 0;
- PKIX_UInt32 bytesProcessed = 0;
- unsigned char messageChar = 0;
- LDAPMessageType messageType = 0;
- PKIX_Int32 bytesRead = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvInitial");
- PKIX_NULLCHECK_TWO(client, pKeepGoing);
-
- /*
- * Is there an LDAPResponse in progress? I.e., have we
- * already processed the tag and length at the beginning of
- * the message?
- */
- if (client->currentResponse) {
- client->connectStatus = RECV_NONINITIAL;
- *pKeepGoing = PKIX_TRUE;
- goto cleanup;
- }
- msgBuf = client->currentInPtr;
-
- /* Do we have enough of the message to decode the message length? */
- if (client->currentBytesAvailable < MINIMUM_MSG_LENGTH) {
- /*
- * No! Move these few bytes to the beginning of rcvBuf
- * and hang another read.
- */
-
- to = (unsigned char *)client->rcvBuf;
- from = client->currentInPtr;
- for (dataIndex = 0;
- dataIndex < client->currentBytesAvailable;
- dataIndex++) {
- *to++ = *from++;
- }
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
- PKIX_CHECK(callbackList->recvCallback
- (client->clientSocket,
- (void *)to,
- client->capacity - client->currentBytesAvailable,
- &bytesRead,
- plContext),
- PKIX_SOCKETRECVFAILED);
-
- client->currentInPtr = client->rcvBuf;
- client->lastIO = PR_Now();
-
- if (bytesRead <= 0) {
- client->connectStatus = RECV_PENDING;
- *pKeepGoing = PKIX_FALSE;
- goto cleanup;
- } else {
- client->currentBytesAvailable += bytesRead;
- }
- }
-
- /*
- * We have to determine whether the response is an entry, with
- * application-specific tag LDAP_SEARCHRESPONSEENTRY_TYPE, or a
- * resultCode, with application tag LDAP_SEARCHRESPONSERESULT_TYPE.
- * First, we have to figure out where to look for the tag.
- */
-
- /* Is the message length short form (one octet) or long form? */
- if ((msgBuf[1] & 0x80) != 0) {
- sizeofLength = msgBuf[1] & 0x7F;
- for (dataIndex = 0; dataIndex < sizeofLength; dataIndex++) {
- messageLength =
- (messageLength << 8) + msgBuf[dataIndex + 2];
- }
- } else {
- messageLength = msgBuf[1];
- }
-
- /* How many bytes did the messageID require? */
- messageIdLen = msgBuf[dataIndex + 3];
-
- messageChar = msgBuf[dataIndex + messageIdLen + 4];
-
- /* Are we looking at an Entry message or a ResultCode message? */
- if ((SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION |
- LDAP_SEARCHRESPONSEENTRY_TYPE) == messageChar) {
-
- messageType = LDAP_SEARCHRESPONSEENTRY_TYPE;
-
- } else if ((SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION |
- LDAP_SEARCHRESPONSERESULT_TYPE) == messageChar) {
-
- messageType = LDAP_SEARCHRESPONSERESULT_TYPE;
-
- } else {
-
- PKIX_ERROR(PKIX_SEARCHRESPONSEPACKETOFUNKNOWNTYPE);
-
- }
-
- /*
- * messageLength is the length from (tag, length, value).
- * We have to allocate space for the tag and length bits too.
- */
- PKIX_CHECK(pkix_pl_LdapResponse_Create
- (messageType,
- messageLength + dataIndex + 2,
- client->currentBytesAvailable,
- msgBuf,
- &bytesProcessed,
- &(client->currentResponse),
- plContext),
- PKIX_LDAPRESPONSECREATEFAILED);
-
- client->currentBytesAvailable -= bytesProcessed;
-
- PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete
- (client, bytesProcessed, pKeepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED);
-
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_RecvNonInitial
- * DESCRIPTION:
- *
- * This function processes the contents of buffers, after the first, of a
- * received LDAP-protocol message for the CertStore embodied in the
- * LdapDefaultClient "client", and stores in "pKeepGoing" a flag indicating
- * whether processing can continue without further input.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pKeepGoing"
- * The address at which the Boolean state machine flag is stored to
- * indicate whether processing can continue without further input.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_RecvNonInitial(
- PKIX_PL_LdapDefaultClient *client,
- PKIX_Boolean *pKeepGoing,
- void *plContext)
-{
-
- PKIX_UInt32 bytesProcessed = 0;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_RecvNonInitial");
- PKIX_NULLCHECK_TWO(client, pKeepGoing);
-
- PKIX_CHECK(pkix_pl_LdapResponse_Append
- (client->currentResponse,
- client->currentBytesAvailable,
- client->currentInPtr,
- &bytesProcessed,
- plContext),
- PKIX_LDAPRESPONSEAPPENDFAILED);
-
- client->currentBytesAvailable -= bytesProcessed;
-
- PKIX_CHECK(pkix_pl_LdapDefaultClient_RecvCheckComplete
- (client, bytesProcessed, pKeepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTRECVCHECKCOMPLETEFAILED);
-
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_Dispatch
- * DESCRIPTION:
- *
- * This function is the state machine dispatcher for the CertStore embodied in
- * the LdapDefaultClient pointed to by "client". Results are returned by
- * changes to various fields in the context.
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_Dispatch(
- PKIX_PL_LdapDefaultClient *client,
- void *plContext)
-{
- PKIX_UInt32 bytesTransferred = 0;
- PKIX_Boolean keepGoing = PKIX_TRUE;
-
- PKIX_ENTER(LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_Dispatch");
- PKIX_NULLCHECK_ONE(client);
-
- while (keepGoing) {
- switch (client->connectStatus) {
- case CONNECT_PENDING:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_ConnectContinue
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTCONNECTCONTINUEFAILED);
- break;
- case CONNECTED:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_Bind
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTBINDFAILED);
- break;
- case BIND_PENDING:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_BindContinue
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTBINDCONTINUEFAILED);
- break;
- case BIND_RESPONSE:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_BindResponse
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTBINDRESPONSEFAILED);
- break;
- case BIND_RESPONSE_PENDING:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_BindResponseContinue
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTBINDRESPONSECONTINUEFAILED);
- break;
- case BOUND:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_Send
- (client, &keepGoing, &bytesTransferred, plContext),
- PKIX_LDAPDEFAULTCLIENTSENDFAILED);
- break;
- case SEND_PENDING:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_SendContinue
- (client, &keepGoing, &bytesTransferred, plContext),
- PKIX_LDAPDEFAULTCLIENTSENDCONTINUEFAILED);
- break;
- case RECV:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_Recv
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTRECVFAILED);
- break;
- case RECV_PENDING:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_RecvContinue
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTRECVCONTINUEFAILED);
- break;
- case RECV_INITIAL:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_RecvInitial
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTRECVINITIALFAILED);
- break;
- case RECV_NONINITIAL:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_RecvNonInitial
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTRECVNONINITIALFAILED);
- break;
- case ABANDON_PENDING:
- PKIX_CHECK
- (pkix_pl_LdapDefaultClient_AbandonContinue
- (client, &keepGoing, plContext),
- PKIX_LDAPDEFAULTCLIENTABANDONCONTINUEFAILED);
- break;
- default:
- PKIX_ERROR(PKIX_LDAPCERTSTOREINILLEGALSTATE);
- }
- }
-
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_MakeAndFilter
- * DESCRIPTION:
- *
- * This function allocates space from the arena pointed to by "arena" to
- * construct a filter that will match components of the X500Name pointed to by
- * XXX...
- *
- * PARAMETERS:
- * "arena"
- * The address of the PRArenaPool used in creating the filter. Must be
- * non-NULL.
- * "nameComponent"
- * The address of a NULL-terminated list of LDAPNameComponents
- * Must be non-NULL.
- * "pFilter"
- * The address at which the result is stored.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_MakeAndFilter(
- PRArenaPool *arena,
- LDAPNameComponent **nameComponents,
- LDAPFilter **pFilter,
- void *plContext)
-{
- LDAPFilter **setOfFilter;
- LDAPFilter *andFilter = NULL;
- LDAPFilter *currentFilter = NULL;
- PKIX_UInt32 componentsPresent = 0;
- void *v = NULL;
- unsigned char *component = NULL;
- LDAPNameComponent **componentP = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_LdapDefaultClient_MakeAndFilter");
- PKIX_NULLCHECK_THREE(arena, nameComponents, pFilter);
-
- /* count how many components we were provided */
- for (componentP = nameComponents, componentsPresent = 0;
- *(componentP++) != NULL;
- componentsPresent++) {}
-
- /* Space for (componentsPresent + 1) pointers to LDAPFilter */
- PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZAlloc,
- (arena, (componentsPresent + 1)*sizeof(LDAPFilter *)));
- setOfFilter = (LDAPFilter **)v;
-
- /* Space for AndFilter and <componentsPresent> EqualFilters */
- PKIX_PL_NSSCALLRV(CERTSTORE, v, PORT_ArenaZNewArray,
- (arena, LDAPFilter, componentsPresent + 1));
- setOfFilter[0] = (LDAPFilter *)v;
-
- /* Claim the first array element for the ANDFilter */
- andFilter = setOfFilter[0];
-
- /* Set ANDFilter to point to the first EqualFilter pointer */
- andFilter->selector = LDAP_ANDFILTER_TYPE;
- andFilter->filter.andFilter.filters = setOfFilter;
-
- currentFilter = andFilter + 1;
-
- for (componentP = nameComponents, componentsPresent = 0;
- *(componentP) != NULL; componentP++) {
- setOfFilter[componentsPresent++] = currentFilter;
- currentFilter->selector = LDAP_EQUALFILTER_TYPE;
- component = (*componentP)->attrType;
- currentFilter->filter.equalFilter.attrType.data = component;
- currentFilter->filter.equalFilter.attrType.len =
- PL_strlen((const char *)component);
- component = (*componentP)->attrValue;
- currentFilter->filter.equalFilter.attrValue.data = component;
- currentFilter->filter.equalFilter.attrValue.len =
- PL_strlen((const char *)component);
- currentFilter++;
- }
-
- setOfFilter[componentsPresent] = NULL;
-
- *pFilter = andFilter;
-
- PKIX_RETURN(CERTSTORE);
-
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_InitiateRequest
- * DESCRIPTION:
- *
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "requestParams"
- * The address of an LdapClientParams object. Must be non-NULL.
- * "pPollDesc"
- * The location where the address of the PRPollDesc is stored, if the
- * client returns with I/O pending.
- * "pResponse"
- * The address where the List of LDAPResponses, or NULL for an
- * unfinished request, is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_InitiateRequest(
- PKIX_PL_LdapClient *genericClient,
- LDAPRequestParams *requestParams,
- void **pPollDesc,
- PKIX_List **pResponse,
- void *plContext)
-{
- PKIX_List *searchResponseList = NULL;
- SECItem *encoded = NULL;
- LDAPFilter *filter = NULL;
- PKIX_PL_LdapDefaultClient *client = 0;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT,
- "pkix_pl_LdapDefaultClient_InitiateRequest");
- PKIX_NULLCHECK_FOUR(genericClient, requestParams, pPollDesc, pResponse);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)genericClient,
- PKIX_LDAPDEFAULTCLIENT_TYPE,
- plContext),
- PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT);
-
- client = (PKIX_PL_LdapDefaultClient *)genericClient;
-
- PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAndFilter
- (client->arena, requestParams->nc, &filter, plContext),
- PKIX_LDAPDEFAULTCLIENTMAKEANDFILTERFAILED);
-
- PKIX_CHECK(pkix_pl_LdapRequest_Create
- (client->arena,
- client->messageID++,
- requestParams->baseObject,
- requestParams->scope,
- requestParams->derefAliases,
- requestParams->sizeLimit,
- requestParams->timeLimit,
- PKIX_FALSE, /* attrs only */
- filter,
- requestParams->attributes,
- &client->currentRequest,
- plContext),
- PKIX_LDAPREQUESTCREATEFAILED);
-
- /* check hashtable for matching request */
- PKIX_CHECK(PKIX_PL_HashTable_Lookup
- (client->cachePtr,
- (PKIX_PL_Object *)(client->currentRequest),
- (PKIX_PL_Object **)&searchResponseList,
- plContext),
- PKIX_HASHTABLELOOKUPFAILED);
-
- if (searchResponseList != NULL) {
- *pPollDesc = NULL;
- *pResponse = searchResponseList;
- PKIX_DECREF(client->currentRequest);
- goto cleanup;
- }
-
- /* It wasn't cached. We'll have to actually send it. */
-
- PKIX_CHECK(pkix_pl_LdapRequest_GetEncoded
- (client->currentRequest, &encoded, plContext),
- PKIX_LDAPREQUESTGETENCODEDFAILED);
-
- client->sendBuf = encoded->data;
- client->bytesToWrite = encoded->len;
-
- PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client, plContext),
- PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED);
-
- /*
- * It's not enough that we may be done with a particular read.
- * We're still processing the transaction until we've gotten the
- * SearchResponseResult message and returned to the BOUND state.
- * Otherwise we must still have a read pending, and must hold off
- * on returning results.
- */
- if ((client->connectStatus == BOUND) &&
- (client->entriesFound != NULL)) {
- *pPollDesc = NULL;
- *pResponse = client->entriesFound;
- client->entriesFound = NULL;
- PKIX_DECREF(client->currentRequest);
- } else {
- *pPollDesc = &client->pollDesc;
- *pResponse = NULL;
- }
-
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-
-}
-
-/*
- * FUNCTION: pkix_pl_LdapDefaultClient_ResumeRequest
- * DESCRIPTION:
- *
- *
- * PARAMETERS:
- * "client"
- * The address of the LdapDefaultClient object. Must be non-NULL.
- * "pPollDesc"
- * The location where the address of the PRPollDesc is stored, if the
- * client returns with I/O pending.
- * "pResponse"
- * The address where the List of LDAPResponses, or NULL for an
- * unfinished request, is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a LdapDefaultClient Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapDefaultClient_ResumeRequest(
- PKIX_PL_LdapClient *genericClient,
- void **pPollDesc,
- PKIX_List **pResponse,
- void *plContext)
-{
- PKIX_PL_LdapDefaultClient *client = 0;
-
- PKIX_ENTER
- (LDAPDEFAULTCLIENT, "pkix_pl_LdapDefaultClient_ResumeRequest");
- PKIX_NULLCHECK_THREE(genericClient, pPollDesc, pResponse);
-
- PKIX_CHECK(pkix_CheckType
- ((PKIX_PL_Object *)genericClient,
- PKIX_LDAPDEFAULTCLIENT_TYPE,
- plContext),
- PKIX_GENERICCLIENTNOTANLDAPDEFAULTCLIENT);
-
- client = (PKIX_PL_LdapDefaultClient *)genericClient;
-
- PKIX_CHECK(pkix_pl_LdapDefaultClient_Dispatch(client, plContext),
- PKIX_LDAPDEFAULTCLIENTDISPATCHFAILED);
-
- /*
- * It's not enough that we may be done with a particular read.
- * We're still processing the transaction until we've gotten the
- * SearchResponseResult message and returned to the BOUND state.
- * Otherwise we must still have a read pending, and must hold off
- * on returning results.
- */
- if ((client->connectStatus == BOUND) &&
- (client->entriesFound != NULL)) {
- *pPollDesc = NULL;
- *pResponse = client->entriesFound;
- client->entriesFound = NULL;
- PKIX_DECREF(client->currentRequest);
- } else {
- *pPollDesc = &client->pollDesc;
- *pResponse = NULL;
- }
-
-cleanup:
-
- PKIX_RETURN(LDAPDEFAULTCLIENT);
-
-}
-
-/* --Public-LdapDefaultClient-Functions----------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_LdapDefaultClient_AbandonRequest
- * DESCRIPTION:
- *
- * This function creates and sends an LDAP-protocol "Abandon" message to the
- * server connected to the LdapDefaultClient pointed to by "client".
- *
- * PARAMETERS:
- * "client"
- * The LdapDefaultClient whose connection is to be abandoned. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_LdapDefaultClient_AbandonRequest(
- PKIX_PL_LdapDefaultClient *client,
- void *plContext)
-{
- PKIX_Int32 bytesWritten = 0;
- PKIX_PL_Socket_Callback *callbackList = NULL;
- SECItem *encoded = NULL;
-
- PKIX_ENTER(CERTSTORE, "PKIX_PL_LdapDefaultClient_AbandonRequest");
- PKIX_NULLCHECK_ONE(client);
-
- if (client->connectStatus == RECV_PENDING) {
- PKIX_CHECK(pkix_pl_LdapDefaultClient_MakeAbandon
- (client->arena,
- (client->messageID) - 1,
- &encoded,
- plContext),
- PKIX_LDAPDEFAULTCLIENTMAKEABANDONFAILED);
-
- callbackList = (PKIX_PL_Socket_Callback *)(client->callbackList);
- PKIX_CHECK(callbackList->sendCallback
- (client->clientSocket,
- encoded->data,
- encoded->len,
- &bytesWritten,
- plContext),
- PKIX_SOCKETSENDFAILED);
-
- if (bytesWritten < 0) {
- client->connectStatus = ABANDON_PENDING;
- } else {
- client->connectStatus = BOUND;
- }
- }
-
- PKIX_DECREF(client->entriesFound);
- PKIX_DECREF(client->currentRequest);
- PKIX_DECREF(client->currentResponse);
-
-cleanup:
-
- PKIX_DECREF(client);
-
- PKIX_RETURN(CERTSTORE);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.h
deleted file mode 100644
index 591edd1a9..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapdefaultclient.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ldapdefaultclient.h
- *
- * LDAPDefaultClient Object Type Definition
- *
- */
-
-#ifndef _PKIX_PL_LDAPDEFAULTCLIENT_H
-#define _PKIX_PL_LDAPDEFAULTCLIENT_H
-
-#include "pkix_pl_ldapt.h"
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * At the time of this version, there are unresolved questions about the LDAP
- * protocol. Although RFC1777 describes a BIND and UNBIND message, it is not
- * clear whether they are appropriate to this application. We have tested only
- * using servers that do not expect authentication, and that reject BIND
- * messages. It is not clear what values might be appropriate for the bindname
- * and authentication fields, which are currently implemented as char strings
- * supplied by the caller. (If this changes, the API and possibly the templates
- * will have to change.) Therefore the LDAPClient_Create API contains a
- * BindAPI structure, a union, which will have to be revised and extended when
- * this area of the protocol is better understood.
- *
- */
-
-typedef enum {
- CONNECT_PENDING,
- CONNECTED,
- BIND_PENDING,
- BIND_RESPONSE,
- BIND_RESPONSE_PENDING,
- BOUND,
- SEND_PENDING,
- RECV,
- RECV_PENDING,
- RECV_INITIAL,
- RECV_NONINITIAL,
- ABANDON_PENDING
-} LdapClientConnectStatus;
-
-struct PKIX_PL_LdapDefaultClientStruct {
- PKIX_PL_LdapClient vtable;
- LdapClientConnectStatus connectStatus;
- PKIX_UInt32 messageID;
- PKIX_PL_HashTable *cachePtr;
- PKIX_PL_Socket *clientSocket;
- PRPollDesc pollDesc;
- void *callbackList; /* cast this to (PKIX_PL_Socket_Callback *) */
- LDAPBindAPI *bindAPI;
- PRArenaPool *arena;
- PRTime lastIO;
- void *sendBuf;
- PKIX_UInt32 bytesToWrite;
- void *rcvBuf;
- PKIX_UInt32 capacity;
- void *currentInPtr;
- PKIX_UInt32 currentBytesAvailable;
- void *bindMsg;
- PKIX_UInt32 bindMsgLen;
- PKIX_List *entriesFound;
- PKIX_PL_LdapRequest *currentRequest;
- PKIX_PL_LdapResponse *currentResponse;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_LdapDefaultClient_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_LDAPDEFAULTCLIENT_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.c
deleted file mode 100644
index 2f2e07fb1..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ldaprequest.c
- *
- */
-
-#include "pkix_pl_ldaprequest.h"
-
-/* --Private-LdapRequest-Functions------------------------------------- */
-
-/* Note: lengths do not include the NULL terminator */
-static const char caAttr[] = "caCertificate;binary";
-static unsigned int caAttrLen = sizeof(caAttr) - 1;
-static const char uAttr[] = "userCertificate;binary";
-static unsigned int uAttrLen = sizeof(uAttr) - 1;
-static const char ccpAttr[] = "crossCertificatePair;binary";
-static unsigned int ccpAttrLen = sizeof(ccpAttr) - 1;
-static const char crlAttr[] = "certificateRevocationList;binary";
-static unsigned int crlAttrLen = sizeof(crlAttr) - 1;
-static const char arlAttr[] = "authorityRevocationList;binary";
-static unsigned int arlAttrLen = sizeof(arlAttr) - 1;
-
-/*
- * XXX If this function were moved into pkix_pl_ldapcertstore.c then all of
- * LdapRequest and LdapResponse could be considered part of the LDAP client.
- * But the constants, above, would have to be copied as well, and they are
- * also needed in pkix_pl_LdapRequest_EncodeAttrs. So there would have to be
- * two copies.
- */
-
-/*
- * FUNCTION: pkix_pl_LdapRequest_AttrTypeToBit
- * DESCRIPTION:
- *
- * This function creates an attribute mask bit corresponding to the SECItem
- * pointed to by "attrType", storing the result at "pAttrBit". The comparison
- * is case-insensitive. If "attrType" does not match any of the known types,
- * zero is stored at "pAttrBit".
- *
- * PARAMETERS
- * "attrType"
- * The address of the SECItem whose string contents are to be compared to
- * the various known attribute types. Must be non-NULL.
- * "pAttrBit"
- * The address where the result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapRequest Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapRequest_AttrTypeToBit(
- SECItem *attrType,
- LdapAttrMask *pAttrBit,
- void *plContext)
-{
- LdapAttrMask attrBit = 0;
- unsigned int attrLen = 0;
- const char *s = NULL;
-
- PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrTypeToBit");
- PKIX_NULLCHECK_TWO(attrType, pAttrBit);
-
- s = (const char *)attrType->data;
- attrLen = attrType->len;
-
- /*
- * Taking note of the fact that all of the comparand strings are
- * different lengths, we do a slight optimization. If a string
- * length matches but the string does not match, we skip comparing
- * to the other strings. If new strings are added to the comparand
- * list, and any are of equal length, be careful to change the
- * grouping of tests accordingly.
- */
- if (attrLen == caAttrLen) {
- if (PORT_Strncasecmp(caAttr, s, attrLen) == 0) {
- attrBit = LDAPATTR_CACERT;
- }
- } else if (attrLen == uAttrLen) {
- if (PORT_Strncasecmp(uAttr, s, attrLen) == 0) {
- attrBit = LDAPATTR_USERCERT;
- }
- } else if (attrLen == ccpAttrLen) {
- if (PORT_Strncasecmp(ccpAttr, s, attrLen) == 0) {
- attrBit = LDAPATTR_CROSSPAIRCERT;
- }
- } else if (attrLen == crlAttrLen) {
- if (PORT_Strncasecmp(crlAttr, s, attrLen) == 0) {
- attrBit = LDAPATTR_CERTREVLIST;
- }
- } else if (attrLen == arlAttrLen) {
- if (PORT_Strncasecmp(arlAttr, s, attrLen) == 0) {
- attrBit = LDAPATTR_AUTHREVLIST;
- }
- }
-
- *pAttrBit = attrBit;
-
- PKIX_RETURN(LDAPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapRequest_AttrStringToBit
- * DESCRIPTION:
- *
- * This function creates an attribute mask bit corresponding to the null-
- * terminated string pointed to by "attrString", storing the result at
- * "pAttrBit". The comparison is case-insensitive. If "attrString" does not
- * match any of the known types, zero is stored at "pAttrBit".
- *
- * PARAMETERS
- * "attrString"
- * The address of the null-terminated string whose contents are to be compared to
- * the various known attribute types. Must be non-NULL.
- * "pAttrBit"
- * The address where the result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapRequest Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapRequest_AttrStringToBit(
- char *attrString,
- LdapAttrMask *pAttrBit,
- void *plContext)
-{
- LdapAttrMask attrBit = 0;
- unsigned int attrLen = 0;
-
- PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_AttrStringToBit");
- PKIX_NULLCHECK_TWO(attrString, pAttrBit);
-
- attrLen = PL_strlen(attrString);
-
- /*
- * Taking note of the fact that all of the comparand strings are
- * different lengths, we do a slight optimization. If a string
- * length matches but the string does not match, we skip comparing
- * to the other strings. If new strings are added to the comparand
- * list, and any are of equal length, be careful to change the
- * grouping of tests accordingly.
- */
- if (attrLen == caAttrLen) {
- if (PORT_Strncasecmp(caAttr, attrString, attrLen) == 0) {
- attrBit = LDAPATTR_CACERT;
- }
- } else if (attrLen == uAttrLen) {
- if (PORT_Strncasecmp(uAttr, attrString, attrLen) == 0) {
- attrBit = LDAPATTR_USERCERT;
- }
- } else if (attrLen == ccpAttrLen) {
- if (PORT_Strncasecmp(ccpAttr, attrString, attrLen) == 0) {
- attrBit = LDAPATTR_CROSSPAIRCERT;
- }
- } else if (attrLen == crlAttrLen) {
- if (PORT_Strncasecmp(crlAttr, attrString, attrLen) == 0) {
- attrBit = LDAPATTR_CERTREVLIST;
- }
- } else if (attrLen == arlAttrLen) {
- if (PORT_Strncasecmp(arlAttr, attrString, attrLen) == 0) {
- attrBit = LDAPATTR_AUTHREVLIST;
- }
- }
-
- *pAttrBit = attrBit;
-
- PKIX_RETURN(LDAPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapRequest_EncodeAttrs
- * DESCRIPTION:
- *
- * This function obtains the attribute mask bits from the LdapRequest pointed
- * to by "request", creates the corresponding array of AttributeTypes for the
- * encoding of the SearchRequest message.
- *
- * PARAMETERS
- * "request"
- * The address of the LdapRequest whose attributes are to be encoded. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapRequest Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_LdapRequest_EncodeAttrs(
- PKIX_PL_LdapRequest *request,
- void *plContext)
-{
- SECItem **attrArray = NULL;
- PKIX_UInt32 attrIndex = 0;
- LdapAttrMask attrBits;
-
- PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_EncodeAttrs");
- PKIX_NULLCHECK_ONE(request);
-
- /* construct "attrs" according to bits in request->attrBits */
- attrBits = request->attrBits;
- attrArray = request->attrArray;
- if ((attrBits & LDAPATTR_CACERT) == LDAPATTR_CACERT) {
- attrArray[attrIndex] = &(request->attributes[attrIndex]);
- request->attributes[attrIndex].type = siAsciiString;
- request->attributes[attrIndex].data = (unsigned char *)caAttr;
- request->attributes[attrIndex].len = caAttrLen;
- attrIndex++;
- }
- if ((attrBits & LDAPATTR_USERCERT) == LDAPATTR_USERCERT) {
- attrArray[attrIndex] = &(request->attributes[attrIndex]);
- request->attributes[attrIndex].type = siAsciiString;
- request->attributes[attrIndex].data = (unsigned char *)uAttr;
- request->attributes[attrIndex].len = uAttrLen;
- attrIndex++;
- }
- if ((attrBits & LDAPATTR_CROSSPAIRCERT) == LDAPATTR_CROSSPAIRCERT) {
- attrArray[attrIndex] = &(request->attributes[attrIndex]);
- request->attributes[attrIndex].type = siAsciiString;
- request->attributes[attrIndex].data = (unsigned char *)ccpAttr;
- request->attributes[attrIndex].len = ccpAttrLen;
- attrIndex++;
- }
- if ((attrBits & LDAPATTR_CERTREVLIST) == LDAPATTR_CERTREVLIST) {
- attrArray[attrIndex] = &(request->attributes[attrIndex]);
- request->attributes[attrIndex].type = siAsciiString;
- request->attributes[attrIndex].data = (unsigned char *)crlAttr;
- request->attributes[attrIndex].len = crlAttrLen;
- attrIndex++;
- }
- if ((attrBits & LDAPATTR_AUTHREVLIST) == LDAPATTR_AUTHREVLIST) {
- attrArray[attrIndex] = &(request->attributes[attrIndex]);
- request->attributes[attrIndex].type = siAsciiString;
- request->attributes[attrIndex].data = (unsigned char *)arlAttr;
- request->attributes[attrIndex].len = arlAttrLen;
- attrIndex++;
- }
- attrArray[attrIndex] = (SECItem *)NULL;
-
- PKIX_RETURN(LDAPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapRequest_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_LdapRequest_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_LdapRequest *ldapRq = NULL;
-
- PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext),
- PKIX_OBJECTNOTLDAPREQUEST);
-
- ldapRq = (PKIX_PL_LdapRequest *)object;
-
- /*
- * All dynamic fields in an LDAPRequest are allocated
- * in an arena, and will be freed when the arena is destroyed.
- */
-
-cleanup:
-
- PKIX_RETURN(LDAPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapRequest_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_LdapRequest_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_UInt32 dataLen = 0;
- PKIX_UInt32 dindex = 0;
- PKIX_UInt32 sizeOfLength = 0;
- PKIX_UInt32 idLen = 0;
- const unsigned char *msgBuf = NULL;
- PKIX_PL_LdapRequest *ldapRq = NULL;
-
- PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPREQUEST_TYPE, plContext),
- PKIX_OBJECTNOTLDAPREQUEST);
-
- ldapRq = (PKIX_PL_LdapRequest *)object;
-
- *pHashcode = 0;
-
- /*
- * Two requests that differ only in msgnum are a match! Therefore,
- * start hashcoding beyond the encoded messageID field.
- */
- if (ldapRq->encoded) {
- msgBuf = (const unsigned char *)ldapRq->encoded->data;
- /* Is message length short form (one octet) or long form? */
- if ((msgBuf[1] & 0x80) != 0) {
- sizeOfLength = msgBuf[1] & 0x7F;
- for (dindex = 0; dindex < sizeOfLength; dindex++) {
- dataLen = (dataLen << 8) + msgBuf[dindex + 2];
- }
- } else {
- dataLen = msgBuf[1];
- }
-
- /* How many bytes for the messageID? (Assume short form) */
- idLen = msgBuf[dindex + 3] + 2;
- dindex += idLen;
- dataLen -= idLen;
- msgBuf = &msgBuf[dindex + 2];
-
- PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext),
- PKIX_HASHFAILED);
- }
-
-cleanup:
-
- PKIX_RETURN(LDAPREQUEST);
-
-}
-
-/*
- * FUNCTION: pkix_pl_LdapRequest_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_LdapRequest_Equals(
- PKIX_PL_Object *firstObj,
- PKIX_PL_Object *secondObj,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_LdapRequest *firstReq = NULL;
- PKIX_PL_LdapRequest *secondReq = NULL;
- PKIX_UInt32 secondType = 0;
- PKIX_UInt32 firstLen = 0;
- const unsigned char *firstData = NULL;
- const unsigned char *secondData = NULL;
- PKIX_UInt32 sizeOfLength = 0;
- PKIX_UInt32 dindex = 0;
- PKIX_UInt32 i = 0;
-
- PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Equals");
- PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
-
- /* test that firstObj is a LdapRequest */
- PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPREQUEST_TYPE, plContext),
- PKIX_FIRSTOBJARGUMENTNOTLDAPREQUEST);
-
- /*
- * Since we know firstObj is a LdapRequest, if both references are
- * identical, they must be equal
- */
- if (firstObj == secondObj){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObj isn't a LdapRequest, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObj, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_LDAPREQUEST_TYPE) {
- goto cleanup;
- }
-
- firstReq = (PKIX_PL_LdapRequest *)firstObj;
- secondReq = (PKIX_PL_LdapRequest *)secondObj;
-
- /* If either lacks an encoded string, they cannot be compared */
- if (!(firstReq->encoded) || !(secondReq->encoded)) {
- goto cleanup;
- }
-
- if (firstReq->encoded->len != secondReq->encoded->len) {
- goto cleanup;
- }
-
- firstData = (const unsigned char *)firstReq->encoded->data;
- secondData = (const unsigned char *)secondReq->encoded->data;
-
- /*
- * Two requests that differ only in msgnum are equal! Therefore,
- * start the byte comparison beyond the encoded messageID field.
- */
-
- /* Is message length short form (one octet) or long form? */
- if ((firstData[1] & 0x80) != 0) {
- sizeOfLength = firstData[1] & 0x7F;
- for (dindex = 0; dindex < sizeOfLength; dindex++) {
- firstLen = (firstLen << 8) + firstData[dindex + 2];
- }
- } else {
- firstLen = firstData[1];
- }
-
- /* How many bytes for the messageID? (Assume short form) */
- i = firstData[dindex + 3] + 2;
- dindex += i;
- firstLen -= i;
- firstData = &firstData[dindex + 2];
-
- /*
- * In theory, we have to calculate where the second message data
- * begins by checking its length encodings. But if these messages
- * are equal, we can re-use the calculation we already did. If they
- * are not equal, the byte comparisons will surely fail.
- */
-
- secondData = &secondData[dindex + 2];
-
- for (i = 0; i < firstLen; i++) {
- if (firstData[i] != secondData[i]) {
- goto cleanup;
- }
- }
-
- *pResult = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(LDAPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapRequest_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_LDAPREQUEST_TYPE and its related functions with
- * systemClasses[]
- * PARAMETERS:
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_LdapRequest_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_RegisterSelf");
-
- entry.description = "LdapRequest";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_LdapRequest);
- entry.destructor = pkix_pl_LdapRequest_Destroy;
- entry.equalsFunction = pkix_pl_LdapRequest_Equals;
- entry.hashcodeFunction = pkix_pl_LdapRequest_Hashcode;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_LDAPREQUEST_TYPE] = entry;
-
- PKIX_RETURN(LDAPREQUEST);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_LdapRequest_Create
- * DESCRIPTION:
- *
- * This function creates an LdapRequest using the PRArenaPool pointed to by
- * "arena", a message number whose value is "msgnum", a base object pointed to
- * by "issuerDN", a scope whose value is "scope", a derefAliases flag whose
- * value is "derefAliases", a sizeLimit whose value is "sizeLimit", a timeLimit
- * whose value is "timeLimit", an attrsOnly flag whose value is "attrsOnly", a
- * filter whose value is "filter", and attribute bits whose value is
- * "attrBits"; storing the result at "pRequestMsg".
- *
- * See pkix_pl_ldaptemplates.c (and below) for the ASN.1 representation of
- * message components, and see pkix_pl_ldapt.h for data types.
- *
- * PARAMETERS
- * "arena"
- * The address of the PRArenaPool to be used in the encoding. Must be
- * non-NULL.
- * "msgnum"
- * The UInt32 message number to be used for the messageID component of the
- * LDAP message exchange.
- * "issuerDN"
- * The address of the string to be used for the baseObject component of the
- * LDAP SearchRequest message. Must be non-NULL.
- * "scope"
- * The (enumerated) ScopeType to be used for the scope component of the
- * LDAP SearchRequest message
- * "derefAliases"
- * The (enumerated) DerefType to be used for the derefAliases component of
- * the LDAP SearchRequest message
- * "sizeLimit"
- * The UInt32 value to be used for the sizeLimit component of the LDAP
- * SearchRequest message
- * "timeLimit"
- * The UInt32 value to be used for the timeLimit component of the LDAP
- * SearchRequest message
- * "attrsOnly"
- * The Boolean value to be used for the attrsOnly component of the LDAP
- * SearchRequest message
- * "filter"
- * The filter to be used for the filter component of the LDAP
- * SearchRequest message
- * "attrBits"
- * The LdapAttrMask bits indicating the attributes to be included in the
- * attributes sequence of the LDAP SearchRequest message
- * "pRequestMsg"
- * The address at which the address of the LdapRequest is stored. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapRequest Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-/*
- * SearchRequest ::=
- * [APPLICATION 3] SEQUENCE {
- * baseObject LDAPDN,
- * scope ENUMERATED {
- * baseObject (0),
- * singleLevel (1),
- * wholeSubtree (2)
- * },
- * derefAliases ENUMERATED {
- * neverDerefAliases (0),
- * derefInSearching (1),
- * derefFindingBaseObj (2),
- * alwaysDerefAliases (3)
- * },
- * sizeLimit INTEGER (0 .. MAXINT),
- * -- value of 0 implies no sizeLimit
- * timeLimit INTEGER (0 .. MAXINT),
- * -- value of 0 implies no timeLimit
- * attrsOnly BOOLEAN,
- * -- TRUE, if only attributes (without values)
- * -- to be returned
- * filter Filter,
- * attributes SEQUENCE OF AttributeType
- * }
- *
- * Filter ::=
- * CHOICE {
- * and [0] SET OF Filter,
- * or [1] SET OF Filter,
- * not [2] Filter,
- * equalityMatch [3] AttributeValueAssertion,
- * substrings [4] SubstringFilter,
- * greaterOrEqual [5] AttributeValueAssertion,
- * lessOrEqual [6] AttributeValueAssertion,
- * present [7] AttributeType,
- * approxMatch [8] AttributeValueAssertion
- * }
- *
- * SubstringFilter ::=
- * SEQUENCE {
- * type AttributeType,
- * SEQUENCE OF CHOICE {
- * initial [0] LDAPString,
- * any [1] LDAPString,
- * final [2] LDAPString,
- * }
- * }
- *
- * AttributeValueAssertion ::=
- * SEQUENCE {
- * attributeType AttributeType,
- * attributeValue AttributeValue,
- * }
- *
- * AttributeValue ::= OCTET STRING
- *
- * AttributeType ::= LDAPString
- * -- text name of the attribute, or dotted
- * -- OID representation
- *
- * LDAPDN ::= LDAPString
- *
- * LDAPString ::= OCTET STRING
- *
- */
-PKIX_Error *
-pkix_pl_LdapRequest_Create(
- PRArenaPool *arena,
- PKIX_UInt32 msgnum,
- char *issuerDN,
- ScopeType scope,
- DerefType derefAliases,
- PKIX_UInt32 sizeLimit,
- PKIX_UInt32 timeLimit,
- char attrsOnly,
- LDAPFilter *filter,
- LdapAttrMask attrBits,
- PKIX_PL_LdapRequest **pRequestMsg,
- void *plContext)
-{
- LDAPMessage msg;
- LDAPSearch *search;
- PKIX_PL_LdapRequest *ldapRequest = NULL;
- char scopeTypeAsChar;
- char derefAliasesTypeAsChar;
- SECItem *attrArray[MAX_LDAPATTRS + 1];
-
- PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_Create");
- PKIX_NULLCHECK_THREE(arena, issuerDN, pRequestMsg);
-
- /* create a PKIX_PL_LdapRequest object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_LDAPREQUEST_TYPE,
- sizeof (PKIX_PL_LdapRequest),
- (PKIX_PL_Object **)&ldapRequest,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- ldapRequest->arena = arena;
- ldapRequest->msgnum = msgnum;
- ldapRequest->issuerDN = issuerDN;
- ldapRequest->scope = scope;
- ldapRequest->derefAliases = derefAliases;
- ldapRequest->sizeLimit = sizeLimit;
- ldapRequest->timeLimit = timeLimit;
- ldapRequest->attrsOnly = attrsOnly;
- ldapRequest->filter = filter;
- ldapRequest->attrBits = attrBits;
-
- ldapRequest->attrArray = attrArray;
-
- PKIX_CHECK(pkix_pl_LdapRequest_EncodeAttrs
- (ldapRequest, plContext),
- PKIX_LDAPREQUESTENCODEATTRSFAILED);
-
- PKIX_PL_NSSCALL
- (LDAPREQUEST, PORT_Memset, (&msg, 0, sizeof (LDAPMessage)));
-
- msg.messageID.type = siUnsignedInteger;
- msg.messageID.data = (void*)&msgnum;
- msg.messageID.len = sizeof (msgnum);
-
- msg.protocolOp.selector = LDAP_SEARCH_TYPE;
-
- search = &(msg.protocolOp.op.searchMsg);
-
- search->baseObject.type = siAsciiString;
- search->baseObject.data = (void *)issuerDN;
- search->baseObject.len = PL_strlen(issuerDN);
- scopeTypeAsChar = (char)scope;
- search->scope.type = siUnsignedInteger;
- search->scope.data = (void *)&scopeTypeAsChar;
- search->scope.len = sizeof (scopeTypeAsChar);
- derefAliasesTypeAsChar = (char)derefAliases;
- search->derefAliases.type = siUnsignedInteger;
- search->derefAliases.data =
- (void *)&derefAliasesTypeAsChar;
- search->derefAliases.len =
- sizeof (derefAliasesTypeAsChar);
- search->sizeLimit.type = siUnsignedInteger;
- search->sizeLimit.data = (void *)&sizeLimit;
- search->sizeLimit.len = sizeof (PKIX_UInt32);
- search->timeLimit.type = siUnsignedInteger;
- search->timeLimit.data = (void *)&timeLimit;
- search->timeLimit.len = sizeof (PKIX_UInt32);
- search->attrsOnly.type = siBuffer;
- search->attrsOnly.data = (void *)&attrsOnly;
- search->attrsOnly.len = sizeof (attrsOnly);
-
- PKIX_PL_NSSCALL
- (LDAPREQUEST,
- PORT_Memcpy,
- (&search->filter, filter, sizeof (LDAPFilter)));
-
- search->attributes = attrArray;
-
- PKIX_PL_NSSCALLRV
- (LDAPREQUEST, ldapRequest->encoded, SEC_ASN1EncodeItem,
- (arena, NULL, (void *)&msg, PKIX_PL_LDAPMessageTemplate));
-
- if (!(ldapRequest->encoded)) {
- PKIX_ERROR(PKIX_FAILEDINENCODINGSEARCHREQUEST);
- }
-
- *pRequestMsg = ldapRequest;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(ldapRequest);
- }
-
- PKIX_RETURN(LDAPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapRequest_GetEncoded
- * DESCRIPTION:
- *
- * This function obtains the encoded message from the LdapRequest pointed to
- * by "request", storing the result at "pRequestBuf".
- *
- * PARAMETERS
- * "request"
- * The address of the LdapRequest whose encoded message is to be
- * retrieved. Must be non-NULL.
- * "pRequestBuf"
- * The address at which is stored the address of the encoded message. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapRequest Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapRequest_GetEncoded(
- PKIX_PL_LdapRequest *request,
- SECItem **pRequestBuf,
- void *plContext)
-{
- PKIX_ENTER(LDAPREQUEST, "pkix_pl_LdapRequest_GetEncoded");
- PKIX_NULLCHECK_TWO(request, pRequestBuf);
-
- *pRequestBuf = request->encoded;
-
- PKIX_RETURN(LDAPREQUEST);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.h
deleted file mode 100644
index 7367d25d2..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaprequest.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ldaprequest.h
- *
- * LdapRequest Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_LDAPREQUEST_H
-#define _PKIX_PL_LDAPREQUEST_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- USER_CERT,
- CA_CERT,
- CROSS_CERT,
- CRL,
- ARL,
- DELTA_CRL
-} PKIX_PL_LdapAttr;
-
-struct PKIX_PL_LdapRequestStruct{
- PRArenaPool *arena;
- PKIX_UInt32 msgnum;
- char *issuerDN;
- ScopeType scope;
- DerefType derefAliases;
- PKIX_UInt32 sizeLimit;
- PKIX_UInt32 timeLimit;
- char attrsOnly;
- LDAPFilter *filter;
- LdapAttrMask attrBits;
- SECItem attributes[MAX_LDAPATTRS];
- SECItem **attrArray;
- SECItem *encoded;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_LdapRequest_Create(
- PRArenaPool *arena,
- PKIX_UInt32 msgnum,
- char *issuerDN,
- ScopeType scope,
- DerefType derefAliases,
- PKIX_UInt32 sizeLimit,
- PKIX_UInt32 timeLimit,
- char attrsOnly,
- LDAPFilter *filter,
- LdapAttrMask attrBits,
- PKIX_PL_LdapRequest **pRequestMsg,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapRequest_AttrTypeToBit(
- SECItem *attrType,
- LdapAttrMask *pAttrBit,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapRequest_AttrStringToBit(
- char *attrString,
- LdapAttrMask *pAttrBit,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapRequest_GetEncoded(
- PKIX_PL_LdapRequest *request,
- SECItem **pRequestBuf,
- void *plContext);
-
-PKIX_Error *pkix_pl_LdapRequest_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_LDAPREQUEST_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.c
deleted file mode 100644
index 941990511..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.c
+++ /dev/null
@@ -1,786 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ldapresponse.c
- *
- */
-
-#include <fcntl.h>
-#include "pkix_pl_ldapresponse.h"
-
-/* --Private-LdapResponse-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_LdapResponse_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_LdapResponse *ldapRsp = NULL;
- LDAPMessage *m = NULL;
- LDAPSearchResponseEntry *entry = NULL;
- LDAPSearchResponseResult *result = NULL;
- LDAPSearchResponseAttr **attributes = NULL;
- LDAPSearchResponseAttr *attr = NULL;
- SECItem **valp = NULL;
- SECItem *val = NULL;
-
- PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPRESPONSE_TYPE, plContext),
- PKIX_OBJECTNOTLDAPRESPONSE);
-
- ldapRsp = (PKIX_PL_LdapResponse *)object;
-
- m = &ldapRsp->decoded;
-
- if (m->messageID.data != NULL) {
- PR_Free(m->messageID.data);
- }
-
- if (m->protocolOp.selector ==
- LDAP_SEARCHRESPONSEENTRY_TYPE) {
- entry = &m->protocolOp.op.searchResponseEntryMsg;
- if (entry->objectName.data != NULL) {
- PR_Free(entry->objectName.data);
- }
- if (entry->attributes != NULL) {
- for (attributes = entry->attributes;
- *attributes != NULL;
- attributes++) {
- attr = *attributes;
- PR_Free(attr->attrType.data);
- for (valp = attr->val; *valp != NULL; valp++) {
- val = *valp;
- if (val->data != NULL) {
- PR_Free(val->data);
- }
- PR_Free(val);
- }
- PR_Free(attr->val);
- PR_Free(attr);
- }
- PR_Free(entry->attributes);
- }
- } else if (m->protocolOp.selector ==
- LDAP_SEARCHRESPONSERESULT_TYPE) {
- result = &m->protocolOp.op.searchResponseResultMsg;
- if (result->resultCode.data != NULL) {
- PR_Free(result->resultCode.data);
- }
- }
-
- PKIX_FREE(ldapRsp->derEncoded.data);
-
-cleanup:
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_LdapResponse_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_UInt32 dataLen = 0;
- PKIX_UInt32 dindex = 0;
- PKIX_UInt32 sizeOfLength = 0;
- PKIX_UInt32 idLen = 0;
- const unsigned char *msgBuf = NULL;
- PKIX_PL_LdapResponse *ldapRsp = NULL;
-
- PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_LDAPRESPONSE_TYPE, plContext),
- PKIX_OBJECTNOTLDAPRESPONSE);
-
- ldapRsp = (PKIX_PL_LdapResponse *)object;
-
- *pHashcode = 0;
-
- /*
- * Two responses that differ only in msgnum are a match! Therefore,
- * start hashcoding beyond the encoded messageID field.
- */
- if (ldapRsp->derEncoded.data) {
- msgBuf = (const unsigned char *)ldapRsp->derEncoded.data;
- /* Is message length short form (one octet) or long form? */
- if ((msgBuf[1] & 0x80) != 0) {
- sizeOfLength = msgBuf[1] & 0x7F;
- for (dindex = 0; dindex < sizeOfLength; dindex++) {
- dataLen = (dataLen << 8) + msgBuf[dindex + 2];
- }
- } else {
- dataLen = msgBuf[1];
- }
-
- /* How many bytes for the messageID? (Assume short form) */
- idLen = msgBuf[dindex + 3] + 2;
- dindex += idLen;
- dataLen -= idLen;
- msgBuf = &msgBuf[dindex + 2];
-
- PKIX_CHECK(pkix_hash(msgBuf, dataLen, pHashcode, plContext),
- PKIX_HASHFAILED);
- }
-
-cleanup:
-
- PKIX_RETURN(LDAPRESPONSE);
-
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_LdapResponse_Equals(
- PKIX_PL_Object *firstObj,
- PKIX_PL_Object *secondObj,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_LdapResponse *rsp1 = NULL;
- PKIX_PL_LdapResponse *rsp2 = NULL;
- PKIX_UInt32 secondType = 0;
- PKIX_UInt32 firstLen = 0;
- const unsigned char *firstData = NULL;
- const unsigned char *secondData = NULL;
- PKIX_UInt32 sizeOfLength = 0;
- PKIX_UInt32 dindex = 0;
- PKIX_UInt32 i = 0;
-
- PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_Equals");
- PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
-
- /* test that firstObj is a LdapResponse */
- PKIX_CHECK(pkix_CheckType(firstObj, PKIX_LDAPRESPONSE_TYPE, plContext),
- PKIX_FIRSTOBJARGUMENTNOTLDAPRESPONSE);
-
- /*
- * Since we know firstObj is a LdapResponse, if both references are
- * identical, they must be equal
- */
- if (firstObj == secondObj){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObj isn't a LdapResponse, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType(secondObj, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_LDAPRESPONSE_TYPE) {
- goto cleanup;
- }
-
- rsp1 = (PKIX_PL_LdapResponse *)firstObj;
- rsp2 = (PKIX_PL_LdapResponse *)secondObj;
-
- /* If either lacks an encoded string, they cannot be compared */
- if (!(rsp1->derEncoded.data) || !(rsp2->derEncoded.data)) {
- goto cleanup;
- }
-
- if (rsp1->derEncoded.len != rsp2->derEncoded.len) {
- goto cleanup;
- }
-
- firstData = (const unsigned char *)rsp1->derEncoded.data;
- secondData = (const unsigned char *)rsp2->derEncoded.data;
-
- /*
- * Two responses that differ only in msgnum are equal! Therefore,
- * start the byte comparison beyond the encoded messageID field.
- */
-
- /* Is message length short form (one octet) or long form? */
- if ((firstData[1] & 0x80) != 0) {
- sizeOfLength = firstData[1] & 0x7F;
- for (dindex = 0; dindex < sizeOfLength; dindex++) {
- firstLen = (firstLen << 8) + firstData[dindex + 2];
- }
- } else {
- firstLen = firstData[1];
- }
-
- /* How many bytes for the messageID? (Assume short form) */
- i = firstData[dindex + 3] + 2;
- dindex += i;
- firstLen -= i;
- firstData = &firstData[dindex + 2];
-
- /*
- * In theory, we have to calculate where the second message data
- * begins by checking its length encodings. But if these messages
- * are equal, we can re-use the calculation we already did. If they
- * are not equal, the byte comparisons will surely fail.
- */
-
- secondData = &secondData[dindex + 2];
-
- for (i = 0; i < firstLen; i++) {
- if (firstData[i] != secondData[i]) {
- goto cleanup;
- }
- }
-
- *pResult = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_LDAPRESPONSE_TYPE and its related functions with
- * systemClasses[]
- * PARAMETERS:
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(LDAPRESPONSE, "pkix_pl_LdapResponse_RegisterSelf");
-
- entry.description = "LdapResponse";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_LdapResponse);
- entry.destructor = pkix_pl_LdapResponse_Destroy;
- entry.equalsFunction = pkix_pl_LdapResponse_Equals;
- entry.hashcodeFunction = pkix_pl_LdapResponse_Hashcode;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_LDAPRESPONSE_TYPE] = entry;
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_Create
- * DESCRIPTION:
- *
- * This function creates an LdapResponse for the LDAPMessageType provided in
- * "responseType" and a buffer capacity provided by "totalLength". It copies
- * into its buffer either "totalLength" or "bytesAvailable" bytes, whichever
- * is less, from the buffer pointed to by "partialData", storing the number of
- * bytes copied at "pBytesConsumed" and storing the address of the LdapResponse
- * at "pLdapResponse".
- *
- * If a message is complete in a single I/O buffer, the LdapResponse will be
- * complete when this function returns. If the message carries over into
- * additional buffers, their contents will be added to the LdapResponse by
- * susequent calls to pkix_pl_LdapResponse_Append.
- *
- * PARAMETERS
- * "responseType"
- * The value of the message type (LDAP_SEARCHRESPONSEENTRY_TYPE or
- * LDAP_SEARCHRESPONSERESULT_TYPE) for the LdapResponse being created
- * "totalLength"
- * The UInt32 value for the total length of the encoded message to be
- * stored in the LdapResponse
- * "bytesAvailable"
- * The UInt32 value for the number of bytes of data available in the
- * current buffer.
- * "partialData"
- * The address from which data is to be copied.
- * "pBytesConsumed"
- * The address at which is stored the UInt32 number of bytes taken from the
- * current buffer. If this number is less than "bytesAvailable", then bytes
- * remain in the buffer for the next LdapResponse. Must be non-NULL.
- * "pLdapResponse"
- * The address where the created LdapResponse is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_Create(
- LDAPMessageType responseType,
- PKIX_UInt32 totalLength,
- PKIX_UInt32 bytesAvailable,
- void *partialData,
- PKIX_UInt32 *pBytesConsumed,
- PKIX_PL_LdapResponse **pLdapResponse,
- void *plContext)
-{
- PKIX_UInt32 bytesConsumed = 0;
- PKIX_PL_LdapResponse *ldapResponse = NULL;
- void *data = NULL;
-
- PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Create");
- PKIX_NULLCHECK_ONE(pLdapResponse);
-
- if (bytesAvailable <= totalLength) {
- bytesConsumed = bytesAvailable;
- } else {
- bytesConsumed = totalLength;
- }
-
- /* create a PKIX_PL_LdapResponse object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_LDAPRESPONSE_TYPE,
- sizeof (PKIX_PL_LdapResponse),
- (PKIX_PL_Object **)&ldapResponse,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- ldapResponse->decoded.protocolOp.selector = responseType;
- ldapResponse->totalLength = totalLength;
- ldapResponse->partialLength = bytesConsumed;
-
- if (totalLength != 0){
- /* Alloc space for array */
- PKIX_NULLCHECK_ONE(partialData);
-
- PKIX_CHECK(PKIX_PL_Malloc
- (totalLength,
- &data,
- plContext),
- PKIX_MALLOCFAILED);
-
- PKIX_PL_NSSCALL
- (LDAPRESPONSE,
- PORT_Memcpy,
- (data, partialData, bytesConsumed));
- }
-
- ldapResponse->derEncoded.type = siBuffer;
- ldapResponse->derEncoded.data = data;
- ldapResponse->derEncoded.len = totalLength;
- *pBytesConsumed = bytesConsumed;
- *pLdapResponse = ldapResponse;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(ldapResponse);
- }
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_Append
- * DESCRIPTION:
- *
- * This function updates the LdapResponse pointed to by "response" with up to
- * "incrLength" from the buffer pointer to by "incrData", storing the number of
- * bytes copied at "pBytesConsumed".
- *
- * PARAMETERS
- * "response"
- * The address of the LdapResponse being updated. Must be non-zero.
- * "incrLength"
- * The UInt32 value for the number of bytes of data available in the
- * current buffer.
- * "incrData"
- * The address from which data is to be copied.
- * "pBytesConsumed"
- * The address at which is stored the UInt32 number of bytes taken from the
- * current buffer. If this number is less than "incrLength", then bytes
- * remain in the buffer for the next LdapResponse. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_Append(
- PKIX_PL_LdapResponse *response,
- PKIX_UInt32 incrLength,
- void *incrData,
- PKIX_UInt32 *pBytesConsumed,
- void *plContext)
-{
- PKIX_UInt32 newPartialLength = 0;
- PKIX_UInt32 bytesConsumed = 0;
- void *dest = NULL;
-
- PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Append");
- PKIX_NULLCHECK_TWO(response, pBytesConsumed);
-
- if (incrLength > 0) {
-
- /* Calculate how many bytes we have room for. */
- bytesConsumed =
- response->totalLength - response->partialLength;
-
- if (bytesConsumed > incrLength) {
- bytesConsumed = incrLength;
- }
-
- newPartialLength = response->partialLength + bytesConsumed;
-
- PKIX_NULLCHECK_ONE(incrData);
-
- dest = &(((char *)response->derEncoded.data)[
- response->partialLength]);
-
- PKIX_PL_NSSCALL
- (LDAPRESPONSE,
- PORT_Memcpy,
- (dest, incrData, bytesConsumed));
-
- response->partialLength = newPartialLength;
- }
-
- *pBytesConsumed = bytesConsumed;
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_IsComplete
- * DESCRIPTION:
- *
- * This function determines whether the LdapResponse pointed to by "response"
- * contains all the data called for by the "totalLength" parameter provided
- * when it was created, storing PKIX_TRUE at "pIsComplete" if so, and
- * PKIX_FALSE otherwise.
- *
- * PARAMETERS
- * "response"
- * The address of the LdapResponse being evaluaTED. Must be non-zero.
- * "incrLength"
- * The UInt32 value for the number of bytes of data available in the
- * current buffer.
- * "incrData"
- * The address from which data is to be copied.
- * "pIsComplete"
- * The address at which is stored the Boolean indication of whether the
- * LdapResponse is complete. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_IsComplete(
- PKIX_PL_LdapResponse *response,
- PKIX_Boolean *pIsComplete,
- void *plContext)
-{
- PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_IsComplete");
- PKIX_NULLCHECK_TWO(response, pIsComplete);
-
- if (response->totalLength == response->partialLength) {
- *pIsComplete = PKIX_TRUE;
- } else {
- *pIsComplete = PKIX_FALSE;
- }
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_Decode
- * DESCRIPTION:
- *
- * This function decodes the DER data contained in the LdapResponse pointed to
- * by "response", using the arena pointed to by "arena", and storing at
- * "pStatus" SECSuccess if the decoding was successful and SECFailure
- * otherwise. The decoded message is stored in an element of "response".
- *
- * PARAMETERS
- * "arena"
- * The address of the PRArenaPool to be used in the decoding. Must be
- * non-NULL.
- * "response"
- * The address of the LdapResponse whose DER data is to be decoded. Must
- * be non-NULL.
- * "pStatus"
- * The address at which is stored the status from the decoding, SECSuccess
- * if successful, SECFailure otherwise. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_Decode(
- PRArenaPool *arena,
- PKIX_PL_LdapResponse *response,
- SECStatus *pStatus,
- void *plContext)
-{
- LDAPMessage *msg;
- SECStatus rv = SECFailure;
-
- PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_Decode");
- PKIX_NULLCHECK_THREE(arena, response, pStatus);
-
- if (response->totalLength != response->partialLength) {
- PKIX_ERROR(PKIX_ATTEMPTTODECODEANINCOMPLETERESPONSE);
- }
-
- msg = &(response->decoded);
-
- PKIX_PL_NSSCALL
- (LDAPRESPONSE, PORT_Memset, (msg, 0, sizeof (LDAPMessage)));
-
- PKIX_PL_NSSCALLRV(LDAPRESPONSE, rv, SEC_ASN1DecodeItem,
- (NULL, msg, PKIX_PL_LDAPMessageTemplate, &(response->derEncoded)));
-
- *pStatus = rv;
-cleanup:
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_GetMessage
- * DESCRIPTION:
- *
- * This function obtains the decoded message from the LdapResponse pointed to
- * by "response", storing the result at "pMessage".
- *
- * PARAMETERS
- * "response"
- * The address of the LdapResponse whose decoded message is to be
- * retrieved. Must be non-NULL.
- * "pMessage"
- * The address at which is stored the address of the decoded message. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_GetMessage(
- PKIX_PL_LdapResponse *response,
- LDAPMessage **pMessage,
- void *plContext)
-{
- PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessage");
- PKIX_NULLCHECK_TWO(response, pMessage);
-
- *pMessage = &response->decoded;
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_GetCapacity
- * DESCRIPTION:
- *
- * This function obtains from the LdapResponse pointed to by "response" the
- * number of bytes remaining to be read, based on the totalLength that was
- * provided to LdapResponse_Create and the data subsequently provided to
- * LdapResponse_Append, storing the result at "pMessage".
- *
- * PARAMETERS
- * "response"
- * The address of the LdapResponse whose remaining capacity is to be
- * retrieved. Must be non-NULL.
- * "pCapacity"
- * The address at which is stored the address of the decoded message. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_GetCapacity(
- PKIX_PL_LdapResponse *response,
- PKIX_UInt32 *pCapacity,
- void *plContext)
-{
- PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetCapacity");
- PKIX_NULLCHECK_TWO(response, pCapacity);
-
- *pCapacity = response->totalLength - response->partialLength;
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_GetMessageType
- * DESCRIPTION:
- *
- * This function obtains the message type from the LdapResponse pointed to
- * by "response", storing the result at "pMessageType".
- *
- * PARAMETERS
- * "response"
- * The address of the LdapResponse whose message type is to be
- * retrieved. Must be non-NULL.
- * "pMessageType"
- * The address at which is stored the type of the response message. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_GetMessageType(
- PKIX_PL_LdapResponse *response,
- LDAPMessageType *pMessageType,
- void *plContext)
-{
- PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetMessageType");
- PKIX_NULLCHECK_TWO(response, pMessageType);
-
- *pMessageType = response->decoded.protocolOp.selector;
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_GetResultCode
- * DESCRIPTION:
- *
- * This function obtains the result code from the LdapResponse pointed to
- * by "response", storing the result at "pResultCode".
- *
- * PARAMETERS
- * "response"
- * The address of the LdapResponse whose result code is to be
- * retrieved. Must be non-NULL.
- * "pResultCode"
- * The address at which is stored the address of the decoded message. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_GetResultCode(
- PKIX_PL_LdapResponse *response,
- LDAPResultCode *pResultCode,
- void *plContext)
-{
- LDAPMessageType messageType = 0;
- LDAPSearchResponseResult *resultMsg = NULL;
-
- PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode");
- PKIX_NULLCHECK_TWO(response, pResultCode);
-
- messageType = response->decoded.protocolOp.selector;
-
- if (messageType != LDAP_SEARCHRESPONSERESULT_TYPE) {
- PKIX_ERROR(PKIX_GETRESULTCODECALLEDFORNONRESULTMESSAGE);
- }
-
- resultMsg = &response->decoded.protocolOp.op.searchResponseResultMsg;
-
- *pResultCode = *(char *)(resultMsg->resultCode.data);
-
-cleanup:
-
- PKIX_RETURN(LDAPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_LdapResponse_GetAttributes
- * DESCRIPTION:
- *
- * This function obtains the attributes from the LdapResponse pointed to
- * by "response", storing the result at "pAttributes".
- *
- * PARAMETERS
- * "response"
- * The address of the LdapResponse whose decoded message is to be
- * retrieved. Must be non-NULL.
- * "pAttributes"
- * The address at which is stored the attributes of the message. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an LdapResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_LdapResponse_GetAttributes(
- PKIX_PL_LdapResponse *response,
- LDAPSearchResponseAttr ***pAttributes,
- void *plContext)
-{
- LDAPMessageType messageType = 0;
-
- PKIX_ENTER(LDAPRESPONSE, "PKIX_PL_LdapResponse_GetResultCode");
- PKIX_NULLCHECK_TWO(response, pAttributes);
-
- messageType = response->decoded.protocolOp.selector;
-
- if (messageType != LDAP_SEARCHRESPONSEENTRY_TYPE) {
- PKIX_ERROR(PKIX_GETATTRIBUTESCALLEDFORNONENTRYMESSAGE);
- }
-
- *pAttributes = response->
- decoded.protocolOp.op.searchResponseEntryMsg.attributes;
-
-cleanup:
-
- PKIX_RETURN(LDAPRESPONSE);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.h
deleted file mode 100644
index c8ef05355..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapresponse.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ldapresponse.h
- *
- * LdapResponse Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_LDAPRESPONSE_H
-#define _PKIX_PL_LDAPRESPONSE_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_LdapResponseStruct{
- LDAPMessage decoded;
- PKIX_UInt32 partialLength;
- PKIX_UInt32 totalLength;
- SECItem derEncoded;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_LdapResponse_Create(
- LDAPMessageType responseType,
- PKIX_UInt32 totalLength,
- PKIX_UInt32 bytesAvailable,
- void *partialData,
- PKIX_UInt32 *pBytesConsumed,
- PKIX_PL_LdapResponse **pResponse,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapResponse_Append(
- PKIX_PL_LdapResponse *response,
- PKIX_UInt32 partialLength,
- void *partialData,
- PKIX_UInt32 *bytesConsumed,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapResponse_IsComplete(
- PKIX_PL_LdapResponse *response,
- PKIX_Boolean *pIsComplete,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapResponse_Decode(
- PRArenaPool *arena,
- PKIX_PL_LdapResponse *response,
- SECStatus *pStatus,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapResponse_GetMessage(
- PKIX_PL_LdapResponse *response,
- LDAPMessage **pMessage,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapResponse_GetMessageType(
- PKIX_PL_LdapResponse *response,
- LDAPMessageType *pMessageType,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapResponse_GetCapacity(
- PKIX_PL_LdapResponse *response,
- PKIX_UInt32 *pCapacity,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapResponse_GetResultCode(
- PKIX_PL_LdapResponse *response,
- LDAPResultCode *pResultCode,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_LdapResponse_GetAttributes(
- PKIX_PL_LdapResponse *response,
- LDAPSearchResponseAttr ***pAttributes,
- void *plContext);
-
-PKIX_Error *pkix_pl_LdapResponse_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_LDAPRESPONSE_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapt.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapt.h
deleted file mode 100644
index b7dad6c26..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldapt.h
+++ /dev/null
@@ -1,314 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _LDAP_H_
-#define _LDAP_H_
-
-#include "certt.h"
-#include "pkixt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern const SEC_ASN1Template PKIX_PL_LDAPCrossCertPairTemplate[];
-SEC_ASN1_CHOOSER_DECLARE(PKIX_PL_LDAPCrossCertPairTemplate)
-extern const SEC_ASN1Template PKIX_PL_LDAPMessageTemplate[];
-SEC_ASN1_CHOOSER_DECLARE(PKIX_PL_LDAPMessageTemplate)
-extern const SEC_ASN1Template LDAPFilterTemplate[];
-SEC_ASN1_CHOOSER_DECLARE(LDAPFilterTemplate)
-
-/* ********************************************************************** */
-
-#define SEC_ASN1_LDAP_STRING SEC_ASN1_OCTET_STRING
-
-#define LDAPATTR_CACERT (1<<0)
-#define LDAPATTR_USERCERT (1<<1)
-#define LDAPATTR_CROSSPAIRCERT (1<<2)
-#define LDAPATTR_CERTREVLIST (1<<3)
-#define LDAPATTR_AUTHREVLIST (1<<4)
-#define MAX_LDAPATTRS 5
-typedef PKIX_UInt32 LdapAttrMask;
-
-typedef enum {
- SIMPLE_AUTH = 0,
- KRBV42LDAP_AUTH = 1,
- KRBV42DSA_AUTH = 2
-} AuthType;
-
-typedef enum {
- BASE_OBJECT = 0,
- SINGLE_LEVEL = 1,
- WHOLE_SUBTREE = 2
-} ScopeType;
-
-typedef enum {
- NEVER_DEREF = 0,
- DEREF_IN_SEARCHING = 1,
- DEREF_FINDING_BASEOBJ = 2,
- ALWAYS_DEREF = 3
-} DerefType;
-
-typedef enum {
- LDAP_INITIALSUBSTRING_TYPE = 0,
- LDAP_ANYSUBSTRING_TYPE = 1,
- LDAP_FINALSUBSTRING_TYPE = 2
-} LDAPSubstringFilterType;
-
-typedef enum {
- LDAP_ANDFILTER_TYPE = 0,
- LDAP_ORFILTER_TYPE = 1,
- LDAP_NOTFILTER_TYPE = 2,
- LDAP_EQUALFILTER_TYPE = 3,
- LDAP_SUBSTRINGFILTER_TYPE = 4,
- LDAP_GREATEROREQUALFILTER_TYPE = 5,
- LDAP_LESSOREQUALFILTER_TYPE = 6,
- LDAP_PRESENTFILTER_TYPE = 7,
- LDAP_APPROXMATCHFILTER_TYPE = 8
-} LDAPFilterType;
-
-typedef enum {
- LDAP_BIND_TYPE = 0,
- LDAP_BINDRESPONSE_TYPE = 1,
- LDAP_UNBIND_TYPE = 2,
- LDAP_SEARCH_TYPE = 3,
- LDAP_SEARCHRESPONSEENTRY_TYPE = 4,
- LDAP_SEARCHRESPONSERESULT_TYPE = 5,
- LDAP_ABANDONREQUEST_TYPE = 16
-} LDAPMessageType;
-
-typedef enum {
- SUCCESS = 0,
- OPERATIONSERROR = 1,
- PROTOCOLERROR = 2,
- TIMELIMITEXCEEDED = 3,
- SIZELIMITEXCEEDED = 4,
- COMPAREFALSE = 5,
- COMPARETRUE = 6,
- AUTHMETHODNOTSUPPORTED = 7,
- STRONGAUTHREQUIRED = 8,
- NOSUCHATTRIBUTE = 16,
- UNDEFINEDATTRIBUTETYPE = 17,
- INAPPROPRIATEMATCHING = 18,
- CONSTRAINTVIOLATION = 19,
- ATTRIBUTEORVALUEEXISTS = 20,
- INVALIDATTRIBUTESYNTAX = 21,
- NOSUCHOBJECT = 32,
- ALIASPROBLEM = 33,
- INVALIDDNSYNTAX = 34,
- ISLEAF = 35,
- ALIASDEREFERENCINGPROBLEM = 36,
- INAPPROPRIATEAUTHENTICATION = 48,
- INVALIDCREDENTIALS = 49,
- INSUFFICIENTACCESSRIGHTS = 50,
- BUSY = 51,
- UNAVAILABLE = 52,
- UNWILLINGTOPERFORM = 53,
- LOOPDETECT = 54,
- NAMINGVIOLATION = 64,
- OBJECTCLASSVIOLATION = 65,
- NOTALLOWEDONNONLEAF = 66,
- NOTALLOWEDONRDN = 67,
- ENTRYALREADYEXISTS = 68,
- OBJECTCLASSMODSPROHIBITED = 69,
- OTHER = 80
-} LDAPResultCode;
-
-typedef struct LDAPLocationStruct LDAPLocation;
-typedef struct LDAPCertPairStruct LDAPCertPair;
-typedef struct LDAPSimpleBindStruct LDAPSimpleBind;
-typedef struct LDAPBindAPIStruct LDAPBindAPI;
-typedef struct LDAPBindStruct LDAPBind;
-typedef struct LDAPResultStruct LDAPBindResponse;
-typedef struct LDAPResultStruct LDAPResult;
-typedef struct LDAPSearchResponseAttrStruct LDAPSearchResponseAttr;
-typedef struct LDAPSearchResponseEntryStruct LDAPSearchResponseEntry;
-typedef struct LDAPResultStruct LDAPSearchResponseResult;
-typedef struct LDAPUnbindStruct LDAPUnbind;
-typedef struct LDAPFilterStruct LDAPFilter;
-typedef struct LDAPAndFilterStruct LDAPAndFilter;
-typedef struct LDAPNotFilterStruct LDAPNotFilter;
-typedef struct LDAPSubstringStruct LDAPSubstring;
-typedef struct LDAPSubstringFilterStruct LDAPSubstringFilter;
-typedef struct LDAPPresentFilterStruct LDAPPresentFilter;
-typedef struct LDAPAttributeValueAssertionStruct LDAPAttributeValueAssertion;
-typedef struct LDAPNameComponentStruct LDAPNameComponent;
-typedef struct LDAPRequestParamsStruct LDAPRequestParams;
-typedef struct LDAPSearchStruct LDAPSearch;
-typedef struct LDAPAbandonRequestStruct LDAPAbandonRequest;
-typedef struct protocolOpStruct LDAPProtocolOp;
-typedef struct LDAPMessageStruct LDAPMessage;
-typedef LDAPAndFilter LDAPOrFilter;
-typedef LDAPAttributeValueAssertion LDAPEqualFilter;
-typedef LDAPAttributeValueAssertion LDAPGreaterOrEqualFilter;
-typedef LDAPAttributeValueAssertion LDAPLessOrEqualFilter;
-typedef LDAPAttributeValueAssertion LDAPApproxMatchFilter;
-
-struct LDAPLocationStruct {
- PRArenaPool *arena;
- void *serverSite;
- void **filterString;
- void **attrBitString;
-};
-
-struct LDAPCertPairStruct {
- SECItem forward;
- SECItem reverse;
-};
-
-struct LDAPSimpleBindStruct {
- char *bindName;
- char *authentication;
-};
-
-struct LDAPBindAPIStruct {
- AuthType selector;
- union {
- LDAPSimpleBind simple;
- } chooser;
-};
-
-struct LDAPBindStruct {
- SECItem version;
- SECItem bindName;
- SECItem authentication;
-};
-
-struct LDAPResultStruct {
- SECItem resultCode;
- SECItem matchedDN;
- SECItem errorMessage;
-};
-
-struct LDAPSearchResponseAttrStruct {
- SECItem attrType;
- SECItem **val;
-};
-
-struct LDAPSearchResponseEntryStruct {
- SECItem objectName;
- LDAPSearchResponseAttr **attributes;
-};
-
-struct LDAPUnbindStruct {
- SECItem dummy;
-};
-
-struct LDAPAndFilterStruct {
- LDAPFilter **filters;
-};
-
-struct LDAPNotFilterStruct {
- LDAPFilter *filter;
-};
-
-struct LDAPSubstringStruct {
- LDAPSubstringFilterType selector;
- SECItem item;
-};
-
-struct LDAPSubstringFilterStruct {
- SECItem attrType;
- LDAPSubstring *strings;
-};
-
-struct LDAPPresentFilterStruct {
- SECItem attrType;
-};
-
-struct LDAPAttributeValueAssertionStruct {
- SECItem attrType;
- SECItem attrValue;
-};
-
-struct LDAPFilterStruct {
- LDAPFilterType selector;
- union {
- LDAPAndFilter andFilter;
- LDAPOrFilter orFilter;
- LDAPNotFilter notFilter;
- LDAPEqualFilter equalFilter;
- LDAPSubstringFilter substringFilter;
- LDAPGreaterOrEqualFilter greaterOrEqualFilter;
- LDAPLessOrEqualFilter lessOrEqualFilter;
- LDAPPresentFilter presentFilter;
- LDAPApproxMatchFilter approxMatchFilter;
- } filter;
-};
-
-struct LDAPNameComponentStruct {
- unsigned char *attrType;
- unsigned char *attrValue;
-};
-
-struct LDAPRequestParamsStruct {
- char *baseObject; /* e.g. "c=US" */
- ScopeType scope;
- DerefType derefAliases;
- PKIX_UInt32 sizeLimit; /* 0 = no limit */
- PRIntervalTime timeLimit; /* 0 = no limit */
- LDAPNameComponent **nc; /* e.g. {{"cn","xxx"},{"o","yyy"},NULL} */
- LdapAttrMask attributes;
-};
-
-struct LDAPSearchStruct {
- SECItem baseObject;
- SECItem scope;
- SECItem derefAliases;
- SECItem sizeLimit;
- SECItem timeLimit;
- SECItem attrsOnly;
- LDAPFilter filter;
- SECItem **attributes;
-};
-
-struct LDAPAbandonRequestStruct {
- SECItem messageID;
-};
-
-struct protocolOpStruct {
- LDAPMessageType selector;
- union {
- LDAPBind bindMsg;
- LDAPBindResponse bindResponseMsg;
- LDAPUnbind unbindMsg;
- LDAPSearch searchMsg;
- LDAPSearchResponseEntry searchResponseEntryMsg;
- LDAPSearchResponseResult searchResponseResultMsg;
- LDAPAbandonRequest abandonRequestMsg;
- } op;
-};
-
-struct LDAPMessageStruct {
- SECItem messageID;
- LDAPProtocolOp protocolOp;
-};
-
-typedef struct PKIX_PL_LdapClientStruct PKIX_PL_LdapClient;
-
-typedef PKIX_Error *
-(*PKIX_PL_LdapClient_InitiateFcn)(
- PKIX_PL_LdapClient *client,
- LDAPRequestParams *requestParams,
- void **pNBIO,
- PKIX_List **pResponse,
- void *plContext);
-
-typedef PKIX_Error *
-(*PKIX_PL_LdapClient_ResumeFcn)(
- PKIX_PL_LdapClient *client,
- void **pNBIO,
- PKIX_List **pResponse,
- void *plContext);
-
-struct PKIX_PL_LdapClientStruct {
- PKIX_PL_LdapClient_InitiateFcn initiateFcn;
- PKIX_PL_LdapClient_ResumeFcn resumeFcn;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaptemplates.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaptemplates.c
deleted file mode 100644
index ecb681929..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_ldaptemplates.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "pkix_pl_ldapt.h"
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(SEC_NullTemplate)
-SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
-
-/*
- * CertificatePair ::= SEQUENCE {
- * forward [0] Certificate OPTIONAL,
- * reverse [1] Certificate OPTIONAL
- * -- at least one of the pair shall be present --
- * }
- */
-
-const SEC_ASN1Template PKIX_PL_LDAPCrossCertPairTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(LDAPCertPair) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0,
- offsetof(LDAPCertPair, forward), SEC_ASN1_SUB(SEC_AnyTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 1,
- offsetof(LDAPCertPair, reverse), SEC_ASN1_SUB(SEC_AnyTemplate) },
- { 0 }
-};
-
-/*
- * BindRequest ::=
- * [APPLICATION 0] SEQUENCE {
- * version INTEGER (1..127),
- * name LDAPDN,
- * authentication CHOICE {
- * simple [0] OCTET STRING,
- * krbv42LDAP [1] OCTET STRING,
- * krbv42DSA [2] OCTET STRING
- * }
- * }
- *
- * LDAPDN ::= LDAPString
- *
- * LDAPString ::= OCTET STRING
- */
-
-#define LDAPStringTemplate SEC_ASN1_SUB(SEC_OctetStringTemplate)
-
-static const SEC_ASN1Template LDAPBindApplTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL },
- { SEC_ASN1_INTEGER, offsetof(LDAPBind, version) },
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPBind, bindName) },
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPBind, authentication) },
- { 0 }
-};
-
-static const SEC_ASN1Template LDAPBindTemplate[] = {
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_BIND_TYPE, 0,
- LDAPBindApplTemplate, sizeof (LDAPBind) }
-};
-
-/*
- * BindResponse ::= [APPLICATION 1] LDAPResult
- *
- * LDAPResult ::=
- * SEQUENCE {
- * resultCode ENUMERATED {
- * success (0),
- * operationsError (1),
- * protocolError (2),
- * timeLimitExceeded (3),
- * sizeLimitExceeded (4),
- * compareFalse (5),
- * compareTrue (6),
- * authMethodNotSupported (7),
- * strongAuthRequired (8),
- * noSuchAttribute (16),
- * undefinedAttributeType (17),
- * inappropriateMatching (18),
- * constraintViolation (19),
- * attributeOrValueExists (20),
- * invalidAttributeSyntax (21),
- * noSuchObject (32),
- * aliasProblem (33),
- * invalidDNSyntax (34),
- * isLeaf (35),
- * aliasDereferencingProblem (36),
- * inappropriateAuthentication (48),
- * invalidCredentials (49),
- * insufficientAccessRights (50),
- * busy (51),
- * unavailable (52),
- * unwillingToPerform (53),
- * loopDetect (54),
- * namingViolation (64),
- * objectClassViolation (65),
- * notAllowedOnNonLeaf (66),
- * notAllowedOnRDN (67),
- * entryAlreadyExists (68),
- * objectClassModsProhibited (69),
- * other (80)
- * },
- * matchedDN LDAPDN,
- * errorMessage LDAPString
- * }
- */
-
-static const SEC_ASN1Template LDAPResultTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL },
- { SEC_ASN1_ENUMERATED, offsetof(LDAPResult, resultCode) },
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPResult, matchedDN) },
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPResult, errorMessage) },
- { 0 }
-};
-
-static const SEC_ASN1Template LDAPBindResponseTemplate[] = {
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_BINDRESPONSE_TYPE, 0,
- LDAPResultTemplate, sizeof (LDAPBindResponse) }
-};
-
-/*
- * UnbindRequest ::= [APPLICATION 2] NULL
- */
-
-static const SEC_ASN1Template LDAPUnbindTemplate[] = {
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | SEC_ASN1_XTRN |
- LDAP_UNBIND_TYPE , 0, SEC_ASN1_SUB(SEC_NullTemplate) }
-};
-
-/*
- * AttributeValueAssertion ::=
- * SEQUENCE {
- * attributeType AttributeType,
- * attributeValue AttributeValue,
- * }
- *
- * AttributeType ::= LDAPString
- * -- text name of the attribute, or dotted
- * -- OID representation
- *
- * AttributeValue ::= OCTET STRING
- */
-
-#define LDAPAttributeTypeTemplate LDAPStringTemplate
-
-/*
- * SubstringFilter ::=
- * SEQUENCE {
- * type AttributeType,
- * SEQUENCE OF CHOICE {
- * initial [0] LDAPString,
- * any [1] LDAPString,
- * final [2] LDAPString,
- * }
- * }
- */
-
-#define LDAPSubstringFilterInitialTemplate LDAPStringTemplate
-#define LDAPSubstringFilterAnyTemplate LDAPStringTemplate
-#define LDAPSubstringFilterFinalTemplate LDAPStringTemplate
-
-static const SEC_ASN1Template LDAPSubstringFilterChoiceTemplate[] = {
- { SEC_ASN1_CHOICE, offsetof(LDAPSubstring, selector), 0,
- sizeof (LDAPFilter) },
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(LDAPSubstring, item),
- LDAPSubstringFilterInitialTemplate,
- LDAP_INITIALSUBSTRING_TYPE },
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- offsetof(LDAPSubstring, item),
- LDAPSubstringFilterAnyTemplate,
- LDAP_ANYSUBSTRING_TYPE },
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
- offsetof(LDAPSubstring, item),
- LDAPSubstringFilterFinalTemplate,
- LDAP_FINALSUBSTRING_TYPE },
- { 0 }
-};
-
-/*
- * Filter ::=
- * CHOICE {
- * and [0] SET OF Filter,
- * or [1] SET OF Filter,
- * not [2] Filter,
- * equalityMatch [3] AttributeValueAssertion,
- * substrings [4] SubstringFilter,
- * greaterOrEqual [5] AttributeValueAssertion,
- * lessOrEqual [6] AttributeValueAssertion,
- * present [7] AttributeType,
- * approxMatch [8] AttributeValueAssertion
- }
- */
-
-static const SEC_ASN1Template LDAPSubstringFilterTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (LDAPSubstringFilter) },
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPSubstringFilter, attrType) },
- { SEC_ASN1_SEQUENCE_OF, offsetof(LDAPSubstringFilter, strings),
- LDAPSubstringFilterChoiceTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template LDAPFilterTemplate[]; /* forward reference */
-
-static const SEC_ASN1Template LDAPSetOfFiltersTemplate[] = {
- { SEC_ASN1_SET_OF, 0, LDAPFilterTemplate }
-};
-
-static const SEC_ASN1Template LDAPAVAFilterTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (LDAPAttributeValueAssertion) },
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPAttributeValueAssertion, attrType) },
- { SEC_ASN1_OCTET_STRING, offsetof(LDAPAttributeValueAssertion, attrValue) },
- { 0 }
-};
-
-static const SEC_ASN1Template LDAPPresentFilterTemplate[] = {
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPPresentFilter, attrType) }
-};
-
-#define LDAPEqualFilterTemplate LDAPAVAFilterTemplate
-#define LDAPGreaterOrEqualFilterTemplate LDAPAVAFilterTemplate
-#define LDAPLessOrEqualFilterTemplate LDAPAVAFilterTemplate
-#define LDAPApproxMatchFilterTemplate LDAPAVAFilterTemplate
-
-const SEC_ASN1Template LDAPFilterTemplate[] = {
- { SEC_ASN1_CHOICE, offsetof(LDAPFilter, selector), 0, sizeof(LDAPFilter) },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- LDAP_ANDFILTER_TYPE,
- offsetof(LDAPFilter, filter.andFilter.filters),
- LDAPSetOfFiltersTemplate, LDAP_ANDFILTER_TYPE },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- LDAP_ORFILTER_TYPE,
- offsetof(LDAPFilter, filter.orFilter.filters),
- LDAPSetOfFiltersTemplate, LDAP_ORFILTER_TYPE },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- LDAP_NOTFILTER_TYPE | SEC_ASN1_POINTER,
- offsetof(LDAPFilter, filter.notFilter),
- LDAPFilterTemplate, LDAP_NOTFILTER_TYPE },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- LDAP_EQUALFILTER_TYPE,
- offsetof(LDAPFilter, filter.equalFilter),
- LDAPEqualFilterTemplate, LDAP_EQUALFILTER_TYPE },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- LDAP_SUBSTRINGFILTER_TYPE, offsetof(LDAPFilter, filter.substringFilter),
- LDAPSubstringFilterTemplate, LDAP_SUBSTRINGFILTER_TYPE },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- LDAP_GREATEROREQUALFILTER_TYPE,
- offsetof(LDAPFilter, filter.greaterOrEqualFilter),
- LDAPGreaterOrEqualFilterTemplate, LDAP_GREATEROREQUALFILTER_TYPE },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- LDAP_LESSOREQUALFILTER_TYPE,
- offsetof(LDAPFilter, filter.lessOrEqualFilter),
- LDAPLessOrEqualFilterTemplate, LDAP_LESSOREQUALFILTER_TYPE },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- LDAP_PRESENTFILTER_TYPE,
- offsetof(LDAPFilter, filter.presentFilter),
- LDAPPresentFilterTemplate, LDAP_PRESENTFILTER_TYPE },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- LDAP_APPROXMATCHFILTER_TYPE,
- offsetof(LDAPFilter, filter.approxMatchFilter),
- LDAPApproxMatchFilterTemplate, LDAP_APPROXMATCHFILTER_TYPE },
- { 0 }
-};
-
-/*
- * SearchRequest ::=
- * [APPLICATION 3] SEQUENCE {
- * baseObject LDAPDN,
- * scope ENUMERATED {
- * baseObject (0),
- * singleLevel (1),
- * wholeSubtree (2)
- * },
- * derefAliases ENUMERATED {
- * neverDerefAliases (0),
- * derefInSearching (1),
- * derefFindingBaseObj (2),
- * alwaysDerefAliases (3)
- * },
- * sizeLimit INTEGER (0 .. MAXINT),
- * -- value of 0 implies no sizeLimit
- * timeLimit INTEGER (0 .. MAXINT),
- * -- value of 0 implies no timeLimit
- * attrsOnly BOOLEAN,
- * -- TRUE, if only attributes (without values)
- * -- to be returned
- * filter Filter,
- * attributes SEQUENCE OF AttributeType
- * }
- */
-
-static const SEC_ASN1Template LDAPAttributeTemplate[] = {
- { SEC_ASN1_LDAP_STRING, 0, NULL, sizeof (SECItem) }
-};
-
-static const SEC_ASN1Template LDAPSearchApplTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL },
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPSearch, baseObject) },
- { SEC_ASN1_ENUMERATED, offsetof(LDAPSearch, scope) },
- { SEC_ASN1_ENUMERATED, offsetof(LDAPSearch, derefAliases) },
- { SEC_ASN1_INTEGER, offsetof(LDAPSearch, sizeLimit) },
- { SEC_ASN1_INTEGER, offsetof(LDAPSearch, timeLimit) },
- { SEC_ASN1_BOOLEAN, offsetof(LDAPSearch, attrsOnly) },
- { SEC_ASN1_INLINE, offsetof(LDAPSearch, filter), LDAPFilterTemplate },
- { SEC_ASN1_SEQUENCE_OF, offsetof(LDAPSearch, attributes), LDAPAttributeTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template LDAPSearchTemplate[] = {
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_SEARCH_TYPE, 0,
- LDAPSearchApplTemplate, sizeof (LDAPSearch) }
-};
-
-/*
- * SearchResponse ::=
- * CHOICE {
- * entry [APPLICATION 4] SEQUENCE {
- * objectName LDAPDN,
- * attributes SEQUENCE OF SEQUENCE {
- * AttributeType,
- * SET OF AttributeValue
- * }
- * }
- * resultCode [APPLICATION 5] LDAPResult
- * }
- */
-
-static const SEC_ASN1Template LDAPSearchResponseAttrTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(LDAPSearchResponseAttr) },
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPSearchResponseAttr, attrType) },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(LDAPSearchResponseAttr, val),
- LDAPStringTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template LDAPEntryTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL },
- { SEC_ASN1_LDAP_STRING, offsetof(LDAPSearchResponseEntry, objectName) },
- { SEC_ASN1_SEQUENCE_OF, offsetof(LDAPSearchResponseEntry, attributes),
- LDAPSearchResponseAttrTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template LDAPSearchResponseEntryTemplate[] = {
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_SEARCHRESPONSEENTRY_TYPE, 0,
- LDAPEntryTemplate, sizeof (LDAPSearchResponseEntry) }
-};
-
-static const SEC_ASN1Template LDAPSearchResponseResultTemplate[] = {
- { SEC_ASN1_APPLICATION | LDAP_SEARCHRESPONSERESULT_TYPE, 0,
- LDAPResultTemplate, sizeof (LDAPSearchResponseResult) }
-};
-
-/*
- * AbandonRequest ::=
- * [APPLICATION 16] MessageID
- */
-
-static const SEC_ASN1Template LDAPAbandonTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(LDAPAbandonRequest, messageID) }
-};
-
-static const SEC_ASN1Template LDAPAbandonRequestTemplate[] = {
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_APPLICATION | LDAP_ABANDONREQUEST_TYPE, 0,
- LDAPAbandonTemplate, sizeof (LDAPAbandonRequest) }
-};
-
-/*
- * LDAPMessage ::=
- * SEQUENCE {
- * messageID MessageID,
- * protocolOp CHOICE {
- * bindRequest BindRequest,
- * bindResponse BindResponse,
- * unbindRequest UnbindRequest,
- * searchRequest SearchRequest,
- * searchResponse SearchResponse,
- * abandonRequest AbandonRequest
- * }
- * }
- *
- * (other choices exist, not shown)
- *
- * MessageID ::= INTEGER (0 .. maxInt)
- */
-
-static const SEC_ASN1Template LDAPMessageProtocolOpTemplate[] = {
- { SEC_ASN1_CHOICE, offsetof(LDAPProtocolOp, selector), 0, sizeof (LDAPProtocolOp) },
- { SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.bindMsg),
- LDAPBindTemplate, LDAP_BIND_TYPE },
- { SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.bindResponseMsg),
- LDAPBindResponseTemplate, LDAP_BINDRESPONSE_TYPE },
- { SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.unbindMsg),
- LDAPUnbindTemplate, LDAP_UNBIND_TYPE },
- { SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.searchMsg),
- LDAPSearchTemplate, LDAP_SEARCH_TYPE },
- { SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.searchResponseEntryMsg),
- LDAPSearchResponseEntryTemplate, LDAP_SEARCHRESPONSEENTRY_TYPE },
- { SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.searchResponseResultMsg),
- LDAPSearchResponseResultTemplate, LDAP_SEARCHRESPONSERESULT_TYPE },
- { SEC_ASN1_INLINE, offsetof(LDAPProtocolOp, op.abandonRequestMsg),
- LDAPAbandonRequestTemplate, LDAP_ABANDONREQUEST_TYPE },
- { 0 }
-};
-
-const SEC_ASN1Template PKIX_PL_LDAPMessageTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL },
- { SEC_ASN1_INTEGER, offsetof(LDAPMessage, messageID) },
- { SEC_ASN1_INLINE, offsetof(LDAPMessage, protocolOp),
- LDAPMessageProtocolOpTemplate },
- { 0 }
-};
-
-/* This function simply returns the address of the message template.
- * This is necessary for Windows DLLs.
- */
-SEC_ASN1_CHOOSER_IMPLEMENT(PKIX_PL_LDAPMessageTemplate)
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.c
deleted file mode 100755
index 4935a4654..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_nsscontext.c
- *
- * NSSContext Function Definitions
- *
- */
-
-
-#include "pkix_pl_nsscontext.h"
-
-#define PKIX_DEFAULT_MAX_RESPONSE_LENGTH 64 * 1024
-#define PKIX_DEFAULT_COMM_TIMEOUT_SECONDS 60
-
-#define PKIX_DEFAULT_CRL_RELOAD_DELAY_SECONDS 6 * 24 * 60 * 60
-#define PKIX_DEFAULT_BAD_CRL_RELOAD_DELAY_SECONDS 60 * 60
-
-/* --Public-NSSContext-Functions--------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_NssContext_Create
- * (see comments in pkix_samples_modules.h)
- */
-PKIX_Error *
-PKIX_PL_NssContext_Create(
- PKIX_UInt32 certificateUsage,
- PKIX_Boolean useNssArena,
- void *wincx,
- void **pNssContext)
-{
- PKIX_PL_NssContext *context = NULL;
- PRArenaPool *arena = NULL;
- void *plContext = NULL;
-
- PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_Create");
- PKIX_NULLCHECK_ONE(pNssContext);
-
- PKIX_CHECK(PKIX_PL_Malloc
- (sizeof(PKIX_PL_NssContext), (void **)&context, NULL),
- PKIX_MALLOCFAILED);
-
- if (useNssArena == PKIX_TRUE) {
- PKIX_CONTEXT_DEBUG("\t\tCalling PORT_NewArena\n");
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- }
-
- context->arena = arena;
- context->certificateUsage = (SECCertificateUsage)certificateUsage;
- context->wincx = wincx;
- context->timeoutSeconds = PKIX_DEFAULT_COMM_TIMEOUT_SECONDS;
- context->maxResponseLength = PKIX_DEFAULT_MAX_RESPONSE_LENGTH;
- context->crlReloadDelay = PKIX_DEFAULT_CRL_RELOAD_DELAY_SECONDS;
- context->badDerCrlReloadDelay =
- PKIX_DEFAULT_BAD_CRL_RELOAD_DELAY_SECONDS;
- context->chainVerifyCallback.isChainValid = NULL;
- context->chainVerifyCallback.isChainValidArg = NULL;
- *pNssContext = context;
-
-cleanup:
-
- PKIX_RETURN(CONTEXT);
-}
-
-
-/*
- * FUNCTION: PKIX_PL_NssContext_Destroy
- * (see comments in pkix_samples_modules.h)
- */
-PKIX_Error *
-PKIX_PL_NssContext_Destroy(
- void *nssContext)
-{
- void *plContext = NULL;
- PKIX_PL_NssContext *context = NULL;
-
- PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_Destroy");
- PKIX_NULLCHECK_ONE(nssContext);
-
- context = (PKIX_PL_NssContext*)nssContext;
-
- if (context->arena != NULL) {
- PKIX_CONTEXT_DEBUG("\t\tCalling PORT_FreeArena\n");
- PORT_FreeArena(context->arena, PKIX_FALSE);
- }
-
- PKIX_PL_Free(nssContext, NULL);
-
- PKIX_RETURN(CONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_NssContext_GetCertUsage
- * DESCRIPTION:
- *
- * This function obtains the platform-dependent SECCertificateUsage parameter
- * from the context object pointed to by "nssContext", storing the result at
- * "pCertUsage".
- *
- * PARAMETERS:
- * "nssContext"
- * The address of the context object whose wincx parameter is to be
- * obtained. Must be non-NULL.
- * "pCertUsage"
- * The address where the result is stored. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_NssContext_GetCertUsage(
- PKIX_PL_NssContext *nssContext,
- SECCertificateUsage *pCertUsage)
-{
- void *plContext = NULL;
-
- PKIX_ENTER(CONTEXT, "pkix_pl_NssContext_GetCertUsage");
- PKIX_NULLCHECK_TWO(nssContext, pCertUsage);
-
- *pCertUsage = nssContext->certificateUsage;
-
- PKIX_RETURN(CONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_NssContext_SetCertUsage
- * DESCRIPTION:
- *
- * This function sets the platform-dependent SECCertificateUsage parameter in
- * the context object pointed to by "nssContext" to the value provided in
- * "certUsage".
- *
- * PARAMETERS:
- * "certUsage"
- * Platform-dependent value to be stored.
- * "nssContext"
- * The address of the context object whose wincx parameter is to be
- * obtained. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_NssContext_SetCertUsage(
- SECCertificateUsage certUsage,
- PKIX_PL_NssContext *nssContext)
-{
- void *plContext = NULL;
-
- PKIX_ENTER(CONTEXT, "pkix_pl_NssContext_SetCertUsage");
- PKIX_NULLCHECK_ONE(nssContext);
-
- nssContext->certificateUsage = certUsage;
-
- PKIX_RETURN(CONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_NssContext_GetWincx
- * DESCRIPTION:
- *
- * This function obtains the platform-dependent wincx parameter from the
- * context object pointed to by "nssContext", storing the result at "pWincx".
- *
- * PARAMETERS:
- * "nssContext"
- * The address of the context object whose wincx parameter is to be
- * obtained. Must be non-NULL.
- * "pWincx"
- * The address where the result is stored. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_NssContext_GetWincx(
- PKIX_PL_NssContext *nssContext,
- void **pWincx)
-{
- void *plContext = NULL;
- PKIX_PL_NssContext *context = NULL;
-
- PKIX_ENTER(CONTEXT, "pkix_pl_NssContext_GetWincx");
- PKIX_NULLCHECK_TWO(nssContext, pWincx);
-
- context = (PKIX_PL_NssContext *)nssContext;
-
- *pWincx = context->wincx;
-
- PKIX_RETURN(CONTEXT);
-}
-
-/*
- * FUNCTION: pkix_pl_NssContext_SetWincx
- * DESCRIPTION:
- *
- * This function sets the platform-dependent wincx parameter in the context
- * object pointed to by "nssContext" to the value provided in "wincx".
- *
- * PARAMETERS:
- * "wincx"
- * Platform-dependent value to be stored.
- * "nssContext"
- * The address of the context object whose wincx parameter is to be
- * obtained. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_NssContext_SetWincx(
- void *wincx,
- PKIX_PL_NssContext *nssContext)
-{
- void *plContext = NULL;
-
- PKIX_ENTER(CONTEXT, "pkix_pl_NssContext_SetWincx");
- PKIX_NULLCHECK_ONE(nssContext);
-
- nssContext->wincx = wincx;
-
- PKIX_RETURN(CONTEXT);
-}
-
-/*
- * FUNCTION: PKIX_PL_NssContext_SetTimeout
- * DESCRIPTION:
- *
- * Sets user defined socket timeout for the validation
- * session. Default is 60 seconds.
- *
- */
-PKIX_Error *
-PKIX_PL_NssContext_SetTimeout(PKIX_UInt32 timeout,
- PKIX_PL_NssContext *nssContext)
-{
- void *plContext = NULL;
-
- PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_SetTimeout");
- PKIX_NULLCHECK_ONE(nssContext);
-
- nssContext->timeoutSeconds = timeout;
-
- PKIX_RETURN(CONTEXT);
-}
-
-/*
- * FUNCTION: PKIX_PL_NssContext_SetMaxResponseLen
- * DESCRIPTION:
- *
- * Sets user defined maximum transmission length of a message.
- *
- */
-PKIX_Error *
-PKIX_PL_NssContext_SetMaxResponseLen(PKIX_UInt32 len,
- PKIX_PL_NssContext *nssContext)
-{
- void *plContext = NULL;
-
- PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_SetMaxResponseLen");
- PKIX_NULLCHECK_ONE(nssContext);
-
- nssContext->maxResponseLength = len;
-
- PKIX_RETURN(CONTEXT);
-}
-
-/*
- * FUNCTION: PKIX_PL_NssContext_SetCrlReloadDelay
- * DESCRIPTION:
- *
- * Sets user defined delay between attempts to load crl using
- * CRLDP.
- *
- */
-PKIX_Error *
-PKIX_PL_NssContext_SetCrlReloadDelay(PKIX_UInt32 delay,
- PKIX_PL_NssContext *nssContext)
-{
- void *plContext = NULL;
-
- PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_SetCrlReloadDelay");
- PKIX_NULLCHECK_ONE(nssContext);
-
- nssContext->crlReloadDelay = delay;
-
- PKIX_RETURN(CONTEXT);
-}
-
-/*
- * FUNCTION: PKIX_PL_NssContext_SetBadDerCrlReloadDelay
- * DESCRIPTION:
- *
- * Sets user defined delay between attempts to load crl that
- * failed to decode.
- *
- */
-PKIX_Error *
-PKIX_PL_NssContext_SetBadDerCrlReloadDelay(PKIX_UInt32 delay,
- PKIX_PL_NssContext *nssContext)
-{
- void *plContext = NULL;
-
- PKIX_ENTER(CONTEXT, "PKIX_PL_NssContext_SetBadDerCrlReloadDelay");
- PKIX_NULLCHECK_ONE(nssContext);
-
- nssContext->badDerCrlReloadDelay = delay;
-
- PKIX_RETURN(CONTEXT);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.h
deleted file mode 100755
index 0ab764534..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_nsscontext.h
- *
- * NSSContext Object Type Definition
- *
- */
-
-
-#ifndef _PKIX_PL_NSSCONTEXT_H
-#define _PKIX_PL_NSSCONTEXT_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_NssContextStruct {
- SECCertificateUsage certificateUsage;
- PRArenaPool *arena;
- void *wincx;
- PKIX_UInt32 timeoutSeconds;
- PKIX_UInt32 maxResponseLength;
- PRTime crlReloadDelay;
- PRTime badDerCrlReloadDelay;
- CERTChainVerifyCallback chainVerifyCallback;
-};
-
-PKIX_Error *
-pkix_pl_NssContext_GetCertUsage
- (PKIX_PL_NssContext *nssContext, SECCertificateUsage *pCertUsage);
-
-/* XXX move the setter into the public header. */
-PKIX_Error *
-pkix_pl_NssContext_SetCertUsage
- (SECCertificateUsage certUsage, PKIX_PL_NssContext *nssContext);
-
-PKIX_Error *
-pkix_pl_NssContext_GetWincx(PKIX_PL_NssContext *nssContext, void **pWincx);
-
-/* XXX move the setter into the public header. */
-PKIX_Error *
-pkix_pl_NssContext_SetWincx(void *wincx, PKIX_PL_NssContext *nssContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_NSSCONTEXT_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c
deleted file mode 100755
index 6be69ac2c..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c
+++ /dev/null
@@ -1,1049 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_pk11certstore.c
- *
- * PKCS11CertStore Function Definitions
- *
- */
-
-#include "pkix_pl_pk11certstore.h"
-
-/*
- * PKIX_DEFAULT_MAX_RESPONSE_LENGTH (64 * 1024) is too small for downloading
- * CRLs. We observed CRLs of sizes 338759 and 439035 in practice. So we
- * need to use a higher max response length for CRLs.
- */
-#define PKIX_DEFAULT_MAX_CRL_RESPONSE_LENGTH (512 * 1024)
-
-/* --Private-Pk11CertStore-Functions---------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_Pk11CertStore_CheckTrust
- * DESCRIPTION:
- * This function checks the trust status of this "cert" that was retrieved
- * from the CertStore "store" and returns its trust status at "pTrusted".
- *
- * PARAMETERS:
- * "store"
- * Address of the CertStore. Must be non-NULL.
- * "cert"
- * Address of the Cert. Must be non-NULL.
- * "pTrusted"
- * Address of PKIX_Boolean where the "cert" trust status is returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Pk11CertStore_CheckTrust(
- PKIX_CertStore *store,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pTrusted,
- void *plContext)
-{
- SECStatus rv = SECFailure;
- PKIX_Boolean trusted = PKIX_FALSE;
- SECCertUsage certUsage = 0;
- SECCertificateUsage certificateUsage;
- unsigned int requiredFlags;
- SECTrustType trustType;
- CERTCertTrust trust;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_CheckTrust");
- PKIX_NULLCHECK_THREE(store, cert, pTrusted);
- PKIX_NULLCHECK_ONE(cert->nssCert);
-
- certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
-
- /* ensure we obtained a single usage bit only */
- PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
-
- /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
- while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
-
- rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, &trustType);
- if (rv == SECSuccess) {
- rv = CERT_GetCertTrust(cert->nssCert, &trust);
- }
-
- if (rv == SECSuccess) {
- unsigned int certFlags;
-
- if (certUsage != certUsageAnyCA &&
- certUsage != certUsageStatusResponder) {
- CERTCertificate *nssCert = cert->nssCert;
-
- if (certUsage == certUsageVerifyCA) {
- if (nssCert->nsCertType & NS_CERT_TYPE_EMAIL_CA) {
- trustType = trustEmail;
- } else if (nssCert->nsCertType & NS_CERT_TYPE_SSL_CA) {
- trustType = trustSSL;
- } else {
- trustType = trustObjectSigning;
- }
- }
-
- certFlags = SEC_GET_TRUST_FLAGS((&trust), trustType);
- if ((certFlags & requiredFlags) == requiredFlags) {
- trusted = PKIX_TRUE;
- }
- } else {
- for (trustType = trustSSL; trustType < trustTypeNone;
- trustType++) {
- certFlags =
- SEC_GET_TRUST_FLAGS((&trust), trustType);
- if ((certFlags & requiredFlags) == requiredFlags) {
- trusted = PKIX_TRUE;
- break;
- }
- }
- }
- }
-
- *pTrusted = trusted;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_Pk11CertStore_CertQuery
- * DESCRIPTION:
- *
- * This function obtains from the database the Certs specified by the
- * ComCertSelParams pointed to by "params" and stores the resulting
- * List at "pSelected". If no matching Certs are found, a NULL pointer
- * will be stored.
- *
- * This function uses a "smart" database query if the Subject has been set
- * in ComCertSelParams. Otherwise, it uses a very inefficient call to
- * retrieve all Certs in the database (and run them through the selector).
- *
- * PARAMETERS:
- * "params"
- * Address of the ComCertSelParams. Must be non-NULL.
- * "pSelected"
- * Address at which List will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Pk11CertStore_CertQuery(
- PKIX_ComCertSelParams *params,
- PKIX_List **pSelected,
- void *plContext)
-{
- PRBool validOnly = PR_FALSE;
- PRTime prtime = 0;
- PKIX_PL_X500Name *subjectName = NULL;
- PKIX_PL_Date *certValid = NULL;
- PKIX_List *certList = NULL;
- PKIX_PL_Cert *cert = NULL;
- CERTCertList *pk11CertList = NULL;
- CERTCertListNode *node = NULL;
- CERTCertificate *nssCert = NULL;
- CERTCertDBHandle *dbHandle = NULL;
-
- PRArenaPool *arena = NULL;
- SECItem *nameItem = NULL;
- void *wincx = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_CertQuery");
- PKIX_NULLCHECK_TWO(params, pSelected);
-
- /* avoid multiple calls to retrieve a constant */
- PKIX_PL_NSSCALLRV(CERTSTORE, dbHandle, CERT_GetDefaultCertDB, ());
-
- /*
- * Any of the ComCertSelParams may be obtained and used to constrain
- * the database query, to allow the use of a "smart" query. See
- * pkix_certsel.h for a list of the PKIX_ComCertSelParams_Get*
- * calls available. No corresponding "smart" queries exist at present,
- * except for CERT_CreateSubjectCertList based on Subject. When others
- * are added, corresponding code should be added to
- * pkix_pl_Pk11CertStore_CertQuery to use them when appropriate
- * selector parameters have been set.
- */
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetSubject
- (params, &subjectName, plContext),
- PKIX_COMCERTSELPARAMSGETSUBJECTFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_GetCertificateValid
- (params, &certValid, plContext),
- PKIX_COMCERTSELPARAMSGETCERTIFICATEVALIDFAILED);
-
- /* If caller specified a Date, convert it to PRTime */
- if (certValid) {
- PKIX_CHECK(pkix_pl_Date_GetPRTime
- (certValid, &prtime, plContext),
- PKIX_DATEGETPRTIMEFAILED);
- validOnly = PR_TRUE;
- }
-
- /*
- * If we have the subject name for the desired subject,
- * ask the database for Certs with that subject. Otherwise
- * ask the database for all Certs.
- */
- if (subjectName) {
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena) {
-
- PKIX_CHECK(pkix_pl_X500Name_GetDERName
- (subjectName, arena, &nameItem, plContext),
- PKIX_X500NAMEGETSECNAMEFAILED);
-
- if (nameItem) {
-
- PKIX_PL_NSSCALLRV
- (CERTSTORE,
- pk11CertList,
- CERT_CreateSubjectCertList,
- (NULL, dbHandle, nameItem, prtime, validOnly));
- }
- PKIX_PL_NSSCALL
- (CERTSTORE, PORT_FreeArena, (arena, PR_FALSE));
- arena = NULL;
- }
-
- } else {
-
- PKIX_CHECK(pkix_pl_NssContext_GetWincx
- ((PKIX_PL_NssContext *)plContext, &wincx),
- PKIX_NSSCONTEXTGETWINCXFAILED);
-
- PKIX_PL_NSSCALLRV
- (CERTSTORE,
- pk11CertList,
- PK11_ListCerts,
- (PK11CertListAll, wincx));
- }
-
- if (pk11CertList) {
-
- PKIX_CHECK(PKIX_List_Create(&certList, plContext),
- PKIX_LISTCREATEFAILED);
-
- for (node = CERT_LIST_HEAD(pk11CertList);
- !(CERT_LIST_END(node, pk11CertList));
- node = CERT_LIST_NEXT(node)) {
-
- PKIX_PL_NSSCALLRV
- (CERTSTORE,
- nssCert,
- CERT_DupCertificate,
- (node->cert));
-
- if (!nssCert) {
- continue; /* just skip bad certs */
- }
-
- PKIX_CHECK_ONLY_FATAL(pkix_pl_Cert_CreateWithNSSCert
- (nssCert, &cert, plContext),
- PKIX_CERTCREATEWITHNSSCERTFAILED);
-
- if (PKIX_ERROR_RECEIVED) {
- CERT_DestroyCertificate(nssCert);
- nssCert = NULL;
- continue; /* just skip bad certs */
- }
-
- PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem
- (certList, (PKIX_PL_Object *)cert, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(cert);
-
- }
-
- /* Don't throw away the list if one cert was bad! */
- pkixTempErrorReceived = PKIX_FALSE;
- }
-
- *pSelected = certList;
- certList = NULL;
-
-cleanup:
-
- if (pk11CertList) {
- CERT_DestroyCertList(pk11CertList);
- }
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PKIX_DECREF(subjectName);
- PKIX_DECREF(certValid);
- PKIX_DECREF(cert);
- PKIX_DECREF(certList);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_Pk11CertStore_ImportCrl
- * DESCRIPTION:
- *
- * PARAMETERS:
- * "params"
- * Address of the ComCRLSelParams. Must be non-NULL.
- * "pSelected"
- * Address at which List will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Pk11CertStore_ImportCrl(
- PKIX_CertStore *store,
- PKIX_PL_X500Name *issuerName,
- PKIX_List *crlList,
- void *plContext)
-{
- CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
- PKIX_PL_CRL *crl = NULL;
- SECItem *derCrl = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_ImportCrl");
- PKIX_NULLCHECK_TWO(store, plContext);
-
- if (!crlList) {
- goto cleanup;
- }
- while (crlList->length > 0) {
- PKIX_CHECK(
- PKIX_List_GetItem(crlList, 0, (PKIX_PL_Object**)&crl,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- /* Delete crl from the list to keep controll of the
- * last reference. crl need to be destroyed right after
- * it released the ownership of the crl der. */
- PKIX_CHECK(
- PKIX_List_DeleteItem(crlList, 0, plContext),
- PKIX_LISTDELETEITEMFAILED);
-
- /* acquire the crlder ownership */
- pkixErrorResult =
- PKIX_PL_CRL_ReleaseDerCrl(crl, &derCrl, plContext);
- PORT_Assert(!pkixErrorResult && derCrl);
- if (pkixErrorResult || !derCrl) {
- /* All pkix delivered crls should be able to
- * release their ders. */
- PKIX_DECREF(pkixErrorResult);
- PKIX_DECREF(crl);
- continue;
- }
- cert_CacheCRLByGeneralName(certHandle, derCrl,
- crl->derGenName);
- /* Do not check the status. If it is a SECFailure,
- * derCrl is already destroyed. */
- derCrl = NULL;
- PKIX_DECREF(crl);
- }
-
-cleanup:
- PKIX_DECREF(crl);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-static PKIX_Error *
-NameCacheHasFetchedCrlInfo(PKIX_PL_Cert *pkixCert,
- PRTime time,
- PKIX_Boolean *pHasFetchedCrlInCache,
- void *plContext)
-{
- /* Returning true result in this case will mean, that case info
- * is currect and should used as is. */
- NamedCRLCache* nameCrlCache = NULL;
- PKIX_Boolean hasFetchedCrlInCache = PKIX_TRUE;
- PKIX_List *dpList = NULL;
- pkix_pl_CrlDp *dp = NULL;
- CERTCertificate *cert;
- PKIX_UInt32 dpIndex = 0;
- SECStatus rv = SECSuccess;
- PRTime reloadDelay = 0, badCrlInvalDelay = 0;
-
- PKIX_ENTER(CERTSTORE, "ChechCacheHasFetchedCrl");
-
- cert = pkixCert->nssCert;
- reloadDelay =
- ((PKIX_PL_NssContext*)plContext)->crlReloadDelay *
- PR_USEC_PER_SEC;
- badCrlInvalDelay =
- ((PKIX_PL_NssContext*)plContext)->badDerCrlReloadDelay *
- PR_USEC_PER_SEC;
- if (!time) {
- time = PR_Now();
- }
- /* If we already download the crl and inserted into the cache, then
- * there is no need to check for fetched crl. We have what we have. */
- PKIX_CHECK(
- PKIX_PL_Cert_GetCrlDp(pkixCert, &dpList, plContext),
- PKIX_CERTGETCRLDPFAILED);
- if (dpList && dpList->length) {
- hasFetchedCrlInCache = PKIX_FALSE;
- rv = cert_AcquireNamedCRLCache(&nameCrlCache);
- if (rv != SECSuccess) {
- PKIX_DECREF(dpList);
- }
- } else {
- /* If no dp then treat it as if we already have
- * a fetched crl. */
- PKIX_DECREF(dpList);
- }
- for (;!hasFetchedCrlInCache &&
- dpList && dpIndex < dpList->length;dpIndex++) {
- SECItem **derDpNames = NULL;
- pkixErrorResult =
- PKIX_List_GetItem(dpList, dpIndex, (PKIX_PL_Object **)&dp,
- plContext);
- if (pkixErrorResult) {
- PKIX_DECREF(pkixErrorResult);
- continue;
- }
- if (dp->nssdp->distPointType == generalName) {
- /* dp can only be created from nssdp. */
- derDpNames = dp->nssdp->derFullName;
- }
- while (derDpNames && *derDpNames != NULL) {
- NamedCRLCacheEntry* cacheEntry = NULL;
- const SECItem *derDpName = *derDpNames++;
- rv = cert_FindCRLByGeneralName(nameCrlCache, derDpName,
- &cacheEntry);
- if (rv == SECSuccess && cacheEntry) {
- if ((cacheEntry->inCRLCache &&
- (cacheEntry->successfulInsertionTime + reloadDelay > time ||
- (cacheEntry->dupe &&
- cacheEntry->lastAttemptTime + reloadDelay > time))) ||
- (cacheEntry->badDER &&
- cacheEntry->lastAttemptTime + badCrlInvalDelay > time)) {
- hasFetchedCrlInCache = PKIX_TRUE;
- break;
- }
- }
- }
- PKIX_DECREF(dp);
- }
-cleanup:
- *pHasFetchedCrlInCache = hasFetchedCrlInCache;
- if (nameCrlCache) {
- cert_ReleaseNamedCRLCache(nameCrlCache);
- }
- PKIX_DECREF(dpList);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_Pk11CertStore_CheckCrl
- * DESCRIPTION:
- *
- * PARAMETERS:
- * "params"
- * Address of the ComCRLSelParams. Must be non-NULL.
- * "pSelected"
- * Address at which List will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertStore Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Pk11CertStore_CheckRevByCrl(
- PKIX_CertStore *store,
- PKIX_PL_Cert *pkixCert,
- PKIX_PL_Cert *pkixIssuer,
- PKIX_PL_Date *date,
- PKIX_Boolean crlDownloadDone,
- PKIX_UInt32 *pReasonCode,
- PKIX_RevocationStatus *pStatus,
- void *plContext)
-{
- PKIX_RevocationStatus pkixRevStatus = PKIX_RevStatus_NoInfo;
- CERTRevocationStatus revStatus = certRevocationStatusUnknown;
- PKIX_Boolean hasFetchedCrlInCache = PKIX_TRUE;
- CERTCertificate *cert = NULL, *issuer = NULL;
- SECStatus rv = SECSuccess;
- void *wincx = NULL;
- PRTime time = 0;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_CheckRevByCrl");
- PKIX_NULLCHECK_FOUR(store, pkixCert, pkixIssuer, plContext);
-
- cert = pkixCert->nssCert;
- issuer = pkixIssuer->nssCert;
- if (date) {
- PKIX_CHECK(
- pkix_pl_Date_GetPRTime(date, &time, plContext),
- PKIX_DATEGETPRTIMEFAILED);
- }
- PKIX_CHECK(
- pkix_pl_NssContext_GetWincx((PKIX_PL_NssContext*)plContext,
- &wincx),
- PKIX_NSSCONTEXTGETWINCXFAILED);
- /* No need to check any cDPs, since partitioned crls are not
- * supported. If a ds does not point to partitioned crl, then
- * the crl should be in issuer cache that is unrelated to any
- * dp. Using NULL as a dp pointer to check it.*/
- rv = cert_CheckCertRevocationStatus(cert, issuer, NULL,
- /* Will not validate the signature
- * on the crl if time is not specified.*/
- time, wincx, &revStatus, pReasonCode);
- if (rv == SECFailure) {
- pkixRevStatus = PKIX_RevStatus_Revoked;
- goto cleanup;
- }
- if (crlDownloadDone) {
- if (revStatus == certRevocationStatusRevoked) {
- pkixRevStatus = PKIX_RevStatus_Revoked;
- } else if (revStatus == certRevocationStatusValid) {
- pkixRevStatus = PKIX_RevStatus_Success;
- }
- } else {
- pkixErrorResult =
- NameCacheHasFetchedCrlInfo(pkixCert, time, &hasFetchedCrlInCache,
- plContext);
- if (pkixErrorResult) {
- goto cleanup;
- }
- if (revStatus == certRevocationStatusRevoked &&
- (hasFetchedCrlInCache ||
- *pReasonCode != crlEntryReasoncertificatedHold)) {
- pkixRevStatus = PKIX_RevStatus_Revoked;
- } else if (revStatus == certRevocationStatusValid &&
- hasFetchedCrlInCache) {
- pkixRevStatus = PKIX_RevStatus_Success;
- }
- }
-cleanup:
- *pStatus = pkixRevStatus;
-
- PKIX_RETURN(CERTSTORE);
-}
-
-
-/*
- * FUNCTION: pkix_pl_Pk11CertStore_GetCert
- * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
- */
-PKIX_Error *
-pkix_pl_Pk11CertStore_GetCert(
- PKIX_CertStore *store,
- PKIX_CertSelector *selector,
- PKIX_VerifyNode *parentVerifyNode,
- void **pNBIOContext,
- PKIX_List **pCertList,
- void *plContext)
-{
- PKIX_UInt32 i = 0;
- PKIX_UInt32 numFound = 0;
- PKIX_PL_Cert *candidate = NULL;
- PKIX_List *selected = NULL;
- PKIX_List *filtered = NULL;
- PKIX_CertSelector_MatchCallback selectorCallback = NULL;
- PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
- PKIX_ComCertSelParams *params = NULL;
- PKIX_Boolean cacheFlag = PKIX_FALSE;
- PKIX_VerifyNode *verifyNode = NULL;
- PKIX_Error *selectorError = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_GetCert");
- PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCertList);
-
- *pNBIOContext = NULL; /* We don't use non-blocking I/O */
-
- PKIX_CHECK(PKIX_CertSelector_GetMatchCallback
- (selector, &selectorCallback, plContext),
- PKIX_CERTSELECTORGETMATCHCALLBACKFAILED);
-
- PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
- (selector, &params, plContext),
- PKIX_CERTSELECTORGETCOMCERTSELPARAMSFAILED);
-
- PKIX_CHECK(pkix_pl_Pk11CertStore_CertQuery
- (params, &selected, plContext),
- PKIX_PK11CERTSTORECERTQUERYFAILED);
-
- if (selected) {
- PKIX_CHECK(PKIX_List_GetLength(selected, &numFound, plContext),
- PKIX_LISTGETLENGTHFAILED);
- }
-
- PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
- (store, &cacheFlag, plContext),
- PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED);
-
- PKIX_CHECK(PKIX_CertStore_GetTrustCallback
- (store, &trustCallback, plContext),
- PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
-
- PKIX_CHECK(PKIX_List_Create(&filtered, plContext),
- PKIX_LISTCREATEFAILED);
-
- for (i = 0; i < numFound; i++) {
- PKIX_CHECK_ONLY_FATAL(PKIX_List_GetItem
- (selected,
- i,
- (PKIX_PL_Object **)&candidate,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- if (PKIX_ERROR_RECEIVED) {
- continue; /* just skip bad certs */
- }
-
- selectorError =
- selectorCallback(selector, candidate, plContext);
- if (!selectorError) {
- PKIX_CHECK(PKIX_PL_Cert_SetCacheFlag
- (candidate, cacheFlag, plContext),
- PKIX_CERTSETCACHEFLAGFAILED);
-
- if (trustCallback) {
- PKIX_CHECK(PKIX_PL_Cert_SetTrustCertStore
- (candidate, store, plContext),
- PKIX_CERTSETTRUSTCERTSTOREFAILED);
- }
-
- PKIX_CHECK_ONLY_FATAL(PKIX_List_AppendItem
- (filtered,
- (PKIX_PL_Object *)candidate,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- } else if (parentVerifyNode) {
- PKIX_CHECK_FATAL(
- pkix_VerifyNode_Create(candidate, 0, selectorError,
- &verifyNode, plContext),
- PKIX_VERIFYNODECREATEFAILED);
- PKIX_CHECK_FATAL(
- pkix_VerifyNode_AddToTree(parentVerifyNode,
- verifyNode,
- plContext),
- PKIX_VERIFYNODEADDTOTREEFAILED);
- PKIX_DECREF(verifyNode);
- }
- PKIX_DECREF(selectorError);
- PKIX_DECREF(candidate);
- }
-
- /* Don't throw away the list if one cert was bad! */
- pkixTempErrorReceived = PKIX_FALSE;
-
- *pCertList = filtered;
- filtered = NULL;
-
-cleanup:
-fatal:
- PKIX_DECREF(filtered);
- PKIX_DECREF(candidate);
- PKIX_DECREF(selected);
- PKIX_DECREF(params);
- PKIX_DECREF(verifyNode);
- PKIX_DECREF(selectorError);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-static PKIX_Error *
-RemovePartitionedDpsFromList(PKIX_List *dpList, PKIX_PL_Date *date,
- void *plContext)
-{
- NamedCRLCache* nameCrlCache = NULL;
- pkix_pl_CrlDp *dp = NULL;
- int dpIndex = 0;
- PRTime time;
- PRTime reloadDelay = 0, badCrlInvalDelay = 0;
- SECStatus rv;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_ListRemovePrtDp");
-
- if (!dpList || !dpList->length) {
- PKIX_RETURN(CERTSTORE);
- }
- reloadDelay =
- ((PKIX_PL_NssContext*)plContext)->crlReloadDelay *
- PR_USEC_PER_SEC;
- badCrlInvalDelay =
- ((PKIX_PL_NssContext*)plContext)->badDerCrlReloadDelay *
- PR_USEC_PER_SEC;
- PKIX_CHECK(pkix_pl_Date_GetPRTime(date, &time, plContext),
- PKIX_DATEGETPRTIMEFAILED);
- rv = cert_AcquireNamedCRLCache(&nameCrlCache);
- if (rv == SECFailure) {
- /* Baling out. Wont find out any thing useful. */
- PKIX_RETURN(CERTSTORE);
- }
- while (dpIndex < dpList->length) {
- SECItem **derDpNames = NULL;
- PKIX_Boolean removeDp = PKIX_FALSE;
-
- PKIX_CHECK(
- PKIX_List_GetItem(dpList, dpIndex, (PKIX_PL_Object **)&dp,
- plContext),
- PKIX_LISTGETITEMFAILED);
- if (!dp->isPartitionedByReasonCode) {
- /* See if we know about this dp anything why we should
- * not use it to download a crl. */
- if (dp->nssdp->distPointType == generalName) {
- /* dp can only be created from nssdp. */
- derDpNames = dp->nssdp->derFullName;
- } else {
- removeDp = PKIX_TRUE;
- }
- while (derDpNames && *derDpNames != NULL) {
- NamedCRLCacheEntry* cacheEntry = NULL;
- const SECItem *derDpName = *derDpNames++;
- /* Removing from the list all dps that we know about. */
- rv = cert_FindCRLByGeneralName(nameCrlCache, derDpName,
- &cacheEntry);
- if (rv && cacheEntry) {
- if (cacheEntry->unsupported ||
- (cacheEntry->inCRLCache &&
- (cacheEntry->successfulInsertionTime + reloadDelay > time ||
- (cacheEntry->dupe &&
- cacheEntry->lastAttemptTime + reloadDelay > time))) ||
- (cacheEntry->badDER &&
- cacheEntry->lastAttemptTime + badCrlInvalDelay > time)) {
- removeDp = PKIX_TRUE;
- }
- }
- }
- } else {
- /* Remove dp that point to a partitioned crl . RFC 5280
- * recommends against crl partitioned by reason code.
- * Will skip such crls */
- removeDp = PKIX_TRUE;
- }
- if (removeDp) {
- PKIX_CHECK_ONLY_FATAL(
- pkix_List_Remove(dpList,(PKIX_PL_Object*)dp,
- plContext),
- PKIX_LISTGETITEMFAILED);
- } else {
- dpIndex += 1;
- }
- PKIX_DECREF(dp);
- }
-
-cleanup:
- if (nameCrlCache) {
- cert_ReleaseNamedCRLCache(nameCrlCache);
- }
- PKIX_DECREF(dp);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_Pk11CertStore_DownloadCrl
- */
-static PKIX_Error *
-DownloadCrl(pkix_pl_CrlDp *dp, PKIX_PL_CRL **crl,
- const SEC_HttpClientFcnV1 *hcv1, void *plContext)
-{
- char *location = NULL;
- char *hostname = NULL;
- char *path = NULL;
- PRUint16 port;
- SEC_HTTP_SERVER_SESSION pServerSession = NULL;
- SEC_HTTP_REQUEST_SESSION pRequestSession = NULL;
- PRUint16 myHttpResponseCode;
- const char *myHttpResponseData = NULL;
- PRUint32 myHttpResponseDataLen;
- SECItem *uri = NULL;
- SECItem *derCrlCopy = NULL;
- CERTSignedCrl *nssCrl = NULL;
- CERTGeneralName *genName = NULL;
- PKIX_Int32 savedError = -1;
- SECItem **derGenNames = NULL;
- SECItem *derGenName = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_DownloadCrl");
-
- /* Do not support dps others than a one with GeneralName
- * name type. */
- if (dp->distPointType != generalName ||
- !dp->nssdp->derFullName) {
- PKIX_ERROR(PKIX_UNSUPPORTEDCRLDPTYPE);
- }
- genName = dp->name.fullName;
- derGenNames = dp->nssdp->derFullName;
- do {
- derGenName = *derGenNames;
- do {
- if (!derGenName ||
- !genName->name.other.data) {
- /* get to next name if no data. */
- savedError = PKIX_UNSUPPORTEDCRLDPTYPE;
- break;
- }
- uri = &genName->name.other;
- location = (char*)PR_Malloc(1 + uri->len);
- if (!location) {
- savedError = PKIX_ALLOCERROR;
- break;
- }
- PORT_Memcpy(location, uri->data, uri->len);
- location[uri->len] = 0;
- if (CERT_ParseURL(location, &hostname,
- &port, &path) != SECSuccess) {
- PORT_SetError(SEC_ERROR_BAD_CRL_DP_URL);
- savedError = PKIX_URLPARSINGFAILED;
- break;
- }
-
- PORT_Assert(hostname != NULL);
- PORT_Assert(path != NULL);
-
- if ((*hcv1->createSessionFcn)(hostname, port,
- &pServerSession) != SECSuccess) {
- PORT_SetError(SEC_ERROR_BAD_CRL_DP_URL);
- savedError = PKIX_URLPARSINGFAILED;
- break;
- }
-
- if ((*hcv1->createFcn)(pServerSession, "http", path, "GET",
- /* Users with slow connections might not get CRL revocation
- checking for certs that use big CRLs because of the timeout
- We absolutely need code that limits our retry attempts.
- */
- PR_SecondsToInterval(
- ((PKIX_PL_NssContext*)plContext)->timeoutSeconds),
- &pRequestSession) != SECSuccess) {
- savedError = PKIX_HTTPSERVERERROR;
- break;
- }
-
- myHttpResponseDataLen =
- ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
- if (myHttpResponseDataLen < PKIX_DEFAULT_MAX_CRL_RESPONSE_LENGTH)
- myHttpResponseDataLen = PKIX_DEFAULT_MAX_CRL_RESPONSE_LENGTH;
-
- /* We use a non-zero timeout, which means:
- - the client will use blocking I/O
- - TryFcn will not return WOULD_BLOCK nor a poll descriptor
- - it's sufficient to call TryFcn once
- */
- /* we don't want result objects larger than this: */
- if ((*hcv1->trySendAndReceiveFcn)(
- pRequestSession,
- NULL,
- &myHttpResponseCode,
- NULL,
- NULL,
- &myHttpResponseData,
- &myHttpResponseDataLen) != SECSuccess) {
- savedError = PKIX_HTTPSERVERERROR;
- break;
- }
-
- if (myHttpResponseCode != 200) {
- savedError = PKIX_HTTPSERVERERROR;
- break;
- }
- } while(0);
- if (!myHttpResponseData) {
- /* Going to the next one. */
- genName = CERT_GetNextGeneralName(genName);
- derGenNames++;
- }
- /* Staing in the loop through all the names until
- * we have a successful download. */
- } while (!myHttpResponseData && *derGenNames &&
- genName != dp->name.fullName);
- /* Need this name to track the crl source location. */
- PORT_Assert(derGenName);
-
- if (!myHttpResponseData) {
- /* Generating fake bad CRL to keep track of this dp */
- SECItem derCrl = {siBuffer, (void*)"BadCrl", 6 };
-
- derCrlCopy = SECITEM_DupItem(&derCrl);
- if (!derCrlCopy) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- derGenName = *dp->nssdp->derFullName;
- } else {
- SECItem derCrl = { siBuffer,
- (void*)myHttpResponseData,
- myHttpResponseDataLen };
- derCrlCopy = SECITEM_DupItem(&derCrl);
- if (!derCrlCopy) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- /* crl will be based on derCrlCopy, but will not own the der. */
- nssCrl =
- CERT_DecodeDERCrlWithFlags(NULL, derCrlCopy, SEC_CRL_TYPE,
- CRL_DECODE_DONT_COPY_DER |
- CRL_DECODE_SKIP_ENTRIES);
- }
- /* pkix crl owns the der. */
- PKIX_CHECK(
- pkix_pl_CRL_CreateWithSignedCRL(nssCrl, derCrlCopy,
- derGenName,
- crl, plContext),
- PKIX_CRLCREATEWITHSIGNEDCRLFAILED);
- /* pkix crl now own both objects. */
- derCrlCopy = NULL;
- nssCrl = NULL;
-
-cleanup:
- if (derCrlCopy)
- PORT_Free(derCrlCopy);
- if (nssCrl)
- SEC_DestroyCrl(nssCrl);
- if (pRequestSession != NULL)
- (*hcv1->freeFcn)(pRequestSession);
- if (pServerSession != NULL)
- (*hcv1->freeSessionFcn)(pServerSession);
- if (path != NULL)
- PORT_Free(path);
- if (hostname != NULL)
- PORT_Free(hostname);
- if (location) {
- PORT_Free(location);
- }
-
- PKIX_RETURN(CERTSTORE);
-}
-
-/*
- * FUNCTION: pkix_pl_Pk11CertStore_GetCRL
- * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
- */
-static PKIX_Error *
-pkix_pl_Pk11CertStore_GetCRL(
- PKIX_CertStore *store,
- PKIX_CRLSelector *selector,
- void **pNBIOContext,
- PKIX_List **pCrlList,
- void *plContext)
-{
- PKIX_UInt32 dpIndex = 0;
- PKIX_PL_CRL *crl = NULL;
- PKIX_List *crlList = NULL;
- PKIX_List *dpList = NULL;
- pkix_pl_CrlDp *dp = NULL;
- PKIX_PL_Date *date = NULL;
- const SEC_HttpClientFcn *registeredHttpClient = NULL;
-
- PKIX_ENTER(CERTSTORE, "pkix_pl_Pk11CertStore_GetCRL");
- PKIX_NULLCHECK_THREE(store, pNBIOContext, pCrlList);
- PKIX_NULLCHECK_TWO(selector, selector->params);
-
- registeredHttpClient = SEC_GetRegisteredHttpClient();
- if (!registeredHttpClient || registeredHttpClient->version != 1) {
- goto cleanup;
- }
- dpList = selector->params->crldpList;
- date = selector->params->date;
- PKIX_CHECK(
- RemovePartitionedDpsFromList(dpList, date,
- plContext),
- PKIX_FAILTOREMOVEDPFROMLIST);
- for (;dpIndex < dpList->length;dpIndex++) {
- PKIX_DECREF(dp);
- pkixErrorResult =
- PKIX_List_GetItem(dpList, dpIndex,
- (PKIX_PL_Object **)&dp,
- plContext);
- if (pkixErrorResult) {
- PKIX_DECREF(pkixErrorResult);
- continue;
- }
- pkixErrorResult =
- DownloadCrl(dp, &crl,
- &registeredHttpClient->fcnTable.ftable1,
- plContext);
- if (pkixErrorResult || !crl) {
- /* continue to next dp in case of unsuccesfull
- * download attempt. */
- PKIX_DECREF(pkixErrorResult);
- continue;
- }
- if (!crlList) {
- PKIX_CHECK(PKIX_List_Create(&crlList, plContext),
- PKIX_LISTCREATEFAILED);
- }
- pkixErrorResult =
- PKIX_List_AppendItem(crlList, (PKIX_PL_Object *)crl,
- plContext);
- if (pkixErrorResult) {
- PKIX_DECREF(pkixErrorResult);
- }
- PKIX_DECREF(crl);
- }
- *pCrlList = crlList;
- crlList = NULL;
-
-cleanup:
- PKIX_DECREF(dp);
- PKIX_DECREF(crl);
- PKIX_DECREF(crlList);
-
- PKIX_RETURN(CERTSTORE);
-}
-
-
-/* --Public-Pk11CertStore-Functions----------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_Pk11CertStore_Create
- * (see comments in pkix_samples_modules.h)
- */
-PKIX_Error *
-PKIX_PL_Pk11CertStore_Create(
- PKIX_CertStore **pCertStore,
- void *plContext)
-{
- PKIX_CertStore *certStore = NULL;
-
- PKIX_ENTER(CERTSTORE, "PKIX_PL_Pk11CertStore_Create");
- PKIX_NULLCHECK_ONE(pCertStore);
-
- PKIX_CHECK(PKIX_CertStore_Create
- (pkix_pl_Pk11CertStore_GetCert,
- pkix_pl_Pk11CertStore_GetCRL,
- NULL, /* getCertContinue */
- NULL, /* getCrlContinue */
- pkix_pl_Pk11CertStore_CheckTrust,
- pkix_pl_Pk11CertStore_ImportCrl,
- pkix_pl_Pk11CertStore_CheckRevByCrl,
- NULL,
- PKIX_TRUE, /* cache flag */
- PKIX_TRUE, /* local - no network I/O */
- &certStore,
- plContext),
- PKIX_CERTSTORECREATEFAILED);
-
- *pCertStore = certStore;
-
-cleanup:
-
- PKIX_RETURN(CERTSTORE);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.h
deleted file mode 100755
index 506707683..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_pk11certstore.h
- *
- * PK11Certstore Object Type Definition
- *
- */
-
-#ifndef _PKIX_PL_PK11CERTSTORE_H
-#define _PKIX_PL_PK11CERTSTORE_H
-
-#include "pkix_pl_common.h"
-#include "certi.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* see source file for function documentation */
-PKIX_Error *
-PKIX_PL_Pk11CertStore_Create(
- PKIX_CertStore **pCertStore,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_PK11CERTSTORE_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c
deleted file mode 100644
index 2afd680c6..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c
+++ /dev/null
@@ -1,1690 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_socket.c
- *
- * Socket Function Definitions
- *
- */
-
-/*
- * If Socket Tracing is active, messages sent and received will be
- * timestamped and dumped (to stdout) in standard hex-dump format. E.g.,
- *
- * 1116612359156140:
- * 28F0: 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 00 Hello, world!.
- *
- * The timestamp is not formatted to be meaningful except as an increasing
- * value of seconds.microseconds, which is good enough to correlate two
- * sides of a message exchange and to figure durations.
- *
- * Code to perform Socket tracing will be compiled in if PKIX_SOCKETTRACE
- * is defined, but that doesn't mean socket tracing is active. Tracing also
- * requires that the Boolean socketTraceFlag is set to PKIX_TRUE. That is
- * the default value, but it can be overridden by using the debugger to
- * change its value -- allowing tracing to be turned on and off at various
- * breakpoints -- or by setting the environment variable SOCKETTRACE. A
- * value of 1 sets socketTraceFlag to PKIX_TRUE (tracing on), and any other
- * value sets socketTraceFlag to PKIX_FALSE (tracing off). The environment
- * value is checked during system initialization.
- */
-#ifndef BUILD_OPT
-#define PKIX_SOCKETTRACE 1
-#endif
-
-#ifdef PKIX_SOCKETDEBUG
-#define PKIX_SOCKETTRACE 1
-#endif
-
-#include "pkix_pl_socket.h"
-
-/* --Private-Socket-Functions---------------------------------- */
-
-#ifdef PKIX_SOCKETTRACE
-static PKIX_Boolean socketTraceFlag = PKIX_FALSE;
-
-/*
- * FUNCTION: pkix_pl_socket_timestamp
- * DESCRIPTION:
- *
- * This functions prints to stdout the time of day, as obtained from the
- * system function gettimeofday, as seconds.microseconds. Its resolution
- * is whatever the system call provides.
- *
- * PARAMETERS:
- * none
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static void pkix_pl_socket_timestamp() {
- PRInt64 prTime;
- prTime = PR_Now();
- printf("%lld:\n", prTime);
-}
-
-/*
- * FUNCTION: pkix_pl_socket_hexDigit
- * DESCRIPTION:
- *
- * This functions prints to stdout the byte "byteVal" as two hex digits.
- *
- * PARAMETERS:
- * "byteVal"
- * The value to be printed.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static void pkix_pl_socket_hexDigit(char byteVal) {
- int n = 0;
- char cHi = '\0';
- char cLow = '\0';
- n = ((byteVal >> 4) & 0xf);
- if (n > 9) {
- cHi = (char) ((n - 10) + 'A');
- } else {
- cHi = (char) (n + '0');
- }
- n = byteVal & 0xf;
- if (n > 9) {
- cLow = (char) ((n - 10) + 'A');
- } else {
- cLow = (char) (n + '0');
- }
- (void) printf("%c%c", cHi, cLow);
-}
-
-/*
- * FUNCTION: pkix_pl_socket_linePrefix
- * DESCRIPTION:
- *
- * This functions prints to stdout the address provided by "addr" as four
- * hexadecimal digits followed by a colon and a space.
- *
- * PARAMETERS:
- * "addr"
- * The address to be printed
- * none
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static void pkix_pl_socket_linePrefix(PKIX_UInt32 addr) {
- pkix_pl_socket_hexDigit((char)((addr >> 8) & 0xff));
- pkix_pl_socket_hexDigit((char)(addr & 0xff));
- (void) printf(": ");
-}
-
-/*
- * FUNCTION: pkix_pl_socket_traceLine
- * DESCRIPTION:
- *
- * This functions prints to stdout the sixteen bytes beginning at the
- * address pointed to by "ptr". The bytes are printed as sixteen pairs
- * of hexadecimal characters followed by an ascii interpretation, in which
- * characters from 0x20 to 0x7d are shown as their ascii equivalents, and
- * other values are represented as periods.
- *
- * PARAMETERS:
- * "ptr"
- * The address of the first of the bytes to be printed
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static void pkix_pl_socket_traceLine(char *ptr) {
- PKIX_UInt32 i = 0;
- pkix_pl_socket_linePrefix((PKIX_UInt32)ptr);
- for (i = 0; i < 16; i++) {
- printf(" ");
- pkix_pl_socket_hexDigit(ptr[i]);
- if (i == 7) {
- printf(" ");
- }
- }
- printf(" ");
- for (i = 0; i < 16; i++) {
- if ((ptr[i] < ' ') || (ptr[i] > '}')) {
- printf(".");
- } else {
- printf("%c", ptr[i]);
- }
- }
- printf("\n");
-}
-
-/*
- * FUNCTION: pkix_pl_socket_tracePartialLine
- * DESCRIPTION:
- *
- * This functions prints to stdout the number of bytes given by "nBytes",
- * beginning at the address pointed to by "ptr". The bytes are printed as
- * pairs of hexadecimal characters followed by an ascii interpretation, in
- * which characters from 0x20 to 0x7d are shown as their ascii equivalents,
- * and other values are represented as periods.
- *
- * PARAMETERS:
- * "ptr"
- * The address of the first of the bytes to be printed
- * "nBytes"
- * The Int32 value giving the number of bytes to be printed. If "nBytes"
- * is greater than sixteen, the results will be unattractive.
- * none
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static void pkix_pl_socket_tracePartialLine(char *ptr, PKIX_UInt32 nBytes) {
- PKIX_UInt32 i = 0;
- if (nBytes > 0) {
- pkix_pl_socket_linePrefix((PKIX_UInt32)ptr);
- }
- for (i = 0; i < nBytes; i++) {
- printf(" ");
- pkix_pl_socket_hexDigit(ptr[i]);
- if (i == 7) {
- printf(" ");
- }
- }
- for (i = nBytes; i < 16; i++) {
- printf(" ");
- if (i == 7) {
- printf(" ");
- }
- }
- printf(" ");
- for (i = 0; i < nBytes; i++) {
- if ((ptr[i] < ' ') || (ptr[i] > '}')) {
- printf(".");
- } else {
- printf("%c", ptr[i]);
- }
- }
- printf("\n");
-}
-
-/*
- * FUNCTION: pkix_pl_socket_tracebuff
- * DESCRIPTION:
- *
- * This functions prints to stdout the number of bytes given by "nBytes",
- * beginning with the byte pointed to by "buf". The output is preceded by
- * a timestamp, and each group of sixteen (and a remainder, if any) is
- * preceded by its address. The contents are shown in hexadecimal and as
- * ascii characters. If "nBytes" is zero, the timestamp and starting
- * address are displayed.
- *
- * PARAMETERS:
- * "buf"
- * The starting address of the bytes to be printed
- * "nBytes"
- * The number of bytes to be printed
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-void pkix_pl_socket_tracebuff(void *buf, PKIX_UInt32 nBytes) {
- PKIX_UInt32 bytesRemaining = nBytes;
- PKIX_UInt32 offset = 0;
- char *bufptr = (char *)buf;
-
- if (socketTraceFlag == PKIX_FALSE) return;
-
- pkix_pl_socket_timestamp();
- /*
- * Special case: if called with length of zero, just do address
- */
- if (nBytes == 0) {
- pkix_pl_socket_linePrefix((PKIX_UInt32)buf);
- printf("\n");
- } else {
- while (bytesRemaining >= 16) {
- pkix_pl_socket_traceLine(&bufptr[offset]);
- bytesRemaining -= 16;
- offset += 16;
- }
- pkix_pl_socket_tracePartialLine
- (&bufptr[offset], bytesRemaining);
- }
-}
-
-#endif
-
-/*
- * FUNCTION: pkix_pl_Socket_SetNonBlocking
- * DESCRIPTION:
- *
- * This functions sets the socket represented by the PRFileDesc "fileDesc"
- * to nonblocking mode.
- *
- * PARAMETERS:
- * "fileDesc"
- * The address of the PRFileDesc whose I/O mode is to be set
- * non-blocking. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_SetNonBlocking(
- PRFileDesc *fileDesc,
- void *plContext)
-{
- PRStatus rv = PR_FAILURE;
- PRSocketOptionData sockOptionData;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_SetNonBlocking");
- PKIX_NULLCHECK_ONE(fileDesc);
-
- sockOptionData.option = PR_SockOpt_Nonblocking;
- sockOptionData.value.non_blocking = PR_TRUE;
-
- PKIX_PL_NSSCALLRV(SOCKET, rv, fileDesc->methods->setsocketoption,
- (fileDesc, &sockOptionData));
-
- if (rv != PR_SUCCESS) {
- PKIX_ERROR(PKIX_UNABLETOSETSOCKETTONONBLOCKING);
- }
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_CreateClient
- * DESCRIPTION:
- *
- * This functions creates a client socket for the PKIX_PL_Socket pointed to
- * by "socket". If "socket" was created with a timeout value of zero, the
- * client socket is set to use nonblocking I/O.
- *
- * PARAMETERS:
- * "socket"
- * The address of the Socket for which a client socket is to be
- * created. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-
-static PKIX_Error *
-pkix_pl_Socket_CreateClient(
- PKIX_PL_Socket *socket,
- void *plContext)
-{
-#ifdef PKIX_SOCKETDEBUG
- PRErrorCode errorcode = 0;
-#endif
- PRFileDesc *mySock = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_CreateClient");
- PKIX_NULLCHECK_ONE(socket);
-
- PKIX_PL_NSSCALLRV(SOCKET, mySock, PR_NewTCPSocket, ());
- if (!mySock) {
-#ifdef PKIX_SOCKETDEBUG
- errorcode = PR_GetError();
- printf
- ("pkix_pl_Socket_CreateClient: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRNEWTCPSOCKETFAILED);
- }
-
-#ifdef PKIX_SOCKETDEBUG
- printf("Created socket, PRFileDesc @ %#X\n", mySock);
-#endif
-
- socket->clientSock = mySock;
- socket->status = SOCKET_UNCONNECTED;
- if (socket->timeout == 0) {
- PKIX_CHECK(pkix_pl_Socket_SetNonBlocking(mySock, plContext),
- PKIX_SOCKETSETNONBLOCKINGFAILED);
- }
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_CreateServer
- * DESCRIPTION:
- *
- * This functions creates a server socket for the PKIX_PL_Socket pointed to
- * by "socket". If "socket" was created with a timeout value of zero, the
- * server socket is set to use nonblocking I/O.
- *
- * Warning: there seems to be a problem with operating a server socket in
- * non-blocking mode. If the server calls Recv prior to a corresponding
- * Send, the message may be lost.
- *
- * PARAMETERS:
- * "socket"
- * The address of the Socket for which a server socket is to be
- * created. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_CreateServer(
- PKIX_PL_Socket *socket,
- void *plContext)
-{
-/* #ifdef PKIX_SOCKETDEBUG */
- PRErrorCode errorcode = 0;
-/* #endif */
- PRStatus rv = PR_FAILURE;
- PRFileDesc *serverSock = NULL;
- PRSocketOptionData sockOptionData;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_CreateServer");
- PKIX_NULLCHECK_ONE(socket);
-
- PKIX_PL_NSSCALLRV(SOCKET, serverSock, PR_NewTCPSocket, ());
- if (!serverSock) {
-#ifdef PKIX_SOCKETDEBUG
- errorcode = PR_GetError();
- printf
- ("pkix_pl_Socket_CreateServer: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRNEWTCPSOCKETFAILED);
- }
-
- socket->serverSock = serverSock;
-
-#ifdef PKIX_SOCKETDEBUG
- printf("Created socket, PRFileDesc @ %#X\n", serverSock);
-#endif
-
- if (socket->timeout == 0) {
- PKIX_CHECK(pkix_pl_Socket_SetNonBlocking(serverSock, plContext),
- PKIX_SOCKETSETNONBLOCKINGFAILED);
- }
-
- sockOptionData.option = PR_SockOpt_Reuseaddr;
- sockOptionData.value.reuse_addr = PR_TRUE;
-
- PKIX_PL_NSSCALLRV(SOCKET, rv, serverSock->methods->setsocketoption,
- (serverSock, &sockOptionData));
-
- if (rv != PR_SUCCESS) {
- PKIX_ERROR(PKIX_UNABLETOSETSOCKETTONONBLOCKING);
- }
-
- PKIX_PL_NSSCALLRV(SOCKET, rv, PR_Bind, (serverSock, socket->netAddr));
-
- if (rv == PR_FAILURE) {
-/* #ifdef PKIX_SOCKETDEBUG */
- errorcode = PR_GetError();
- printf
- ("pkix_pl_Socket_CreateServer: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-/* #endif */
- PKIX_ERROR(PKIX_PRBINDFAILED);
- }
-
-#ifdef PKIX_SOCKETDEBUG
- printf("Successful bind!\n");
-#endif
-
- socket->status = SOCKET_BOUND;
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Connect
- * DESCRIPTION:
- *
- * This functions performs the connect function for the client socket
- * specified in "socket", storing the status at "pStatus".
- *
- * PARAMETERS:
- * "socket"
- * The address of the Socket for which a connect is to be performed.
- * Must be non-NULL.
- * "pStatus"
- * The address at which the connection status is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_Connect(
- PKIX_PL_Socket *socket,
- PRErrorCode *pStatus,
- void *plContext)
-{
- PRStatus rv = PR_FAILURE;
- PRErrorCode errorcode = 0;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Connect");
- PKIX_NULLCHECK_TWO(socket, socket->clientSock);
-
- PKIX_PL_NSSCALLRV(SOCKET, rv, PR_Connect,
- (socket->clientSock, socket->netAddr, socket->timeout));
-
- if (rv == PR_FAILURE) {
- errorcode = PR_GetError();
- *pStatus = errorcode;
- if (errorcode == PR_IN_PROGRESS_ERROR) {
- socket->status = SOCKET_CONNECTPENDING;
- goto cleanup;
- } else {
-#ifdef PKIX_SOCKETDEBUG
- printf
- ("pkix_pl_Socket_Connect: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRCONNECTFAILED);
- }
- }
-
-#ifdef PKIX_SOCKETDEBUG
- printf("Successful connect!\n");
-#endif
-
- *pStatus = 0;
- socket->status = SOCKET_CONNECTED;
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_ConnectContinue
- * DESCRIPTION:
- *
- * This functions continues the connect function for the client socket
- * specified in "socket", storing the status at "pStatus". It is expected that
- * the non-blocking connect has returned PR_IN_PROGRESS_ERROR.
- *
- * PARAMETERS:
- * "socket"
- * The address of the Socket for which a connect is to be continued.
- * Must be non-NULL.
- * "pStatus"
- * The address at which the connection status is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_ConnectContinue(
- PKIX_PL_Socket *socket,
- PRErrorCode *pStatus,
- void *plContext)
-{
- PRStatus rv = PR_FAILURE;
- PRErrorCode errorcode = 0;
- PRPollDesc pollDesc;
- PRInt32 numEvents = 0;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_ConnectContinue");
- PKIX_NULLCHECK_TWO(socket, socket->clientSock);
-
- pollDesc.fd = socket->clientSock;
- pollDesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
- pollDesc.out_flags = 0;
- PKIX_PL_NSSCALLRV(SOCKET, numEvents, PR_Poll, (&pollDesc, 1, 0));
- if (numEvents < 0) {
- PKIX_ERROR(PKIX_PRPOLLFAILED);
- }
-
- if (numEvents == 0) {
- *pStatus = PR_IN_PROGRESS_ERROR;
- goto cleanup;
- }
-
- PKIX_PL_NSSCALLRV(SOCKET, rv, PR_ConnectContinue,
- (socket->clientSock, pollDesc.out_flags));
-
- /*
- * PR_ConnectContinue sometimes lies. It returns PR_SUCCESS
- * even though the connection is not yet ready. But its deceit
- * is betrayed by the contents of out_flags!
- */
- if ((rv == PR_SUCCESS) && (pollDesc.out_flags == PR_POLL_ERR)) {
- *pStatus = PR_IN_PROGRESS_ERROR;
- goto cleanup;
- }
-
- if (rv == PR_FAILURE) {
- errorcode = PR_GetError();
- *pStatus = errorcode;
- if (errorcode == PR_IN_PROGRESS_ERROR) {
- goto cleanup;
- } else {
-#ifdef PKIX_SOCKETDEBUG
- printf
- ("pkix_pl_Socket_ConnectContinue: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRCONNECTCONTINUEFAILED);
- }
- }
-
-#ifdef PKIX_SOCKETDEBUG
- printf("Successful connect!\n");
-#endif
-
- *pStatus = 0;
- socket->status = SOCKET_CONNECTED;
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Socket_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_Socket *socket = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_SOCKET_TYPE, plContext),
- PKIX_OBJECTNOTANSOCKET);
-
- socket = (PKIX_PL_Socket *)object;
-
- if (socket->isServer) {
- if (socket->serverSock) {
- PR_Close(socket->serverSock);
- }
- } else {
- if (socket->clientSock) {
- PR_Close(socket->clientSock);
- }
- }
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Socket_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_Socket *socket = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_SOCKET_TYPE, plContext),
- PKIX_OBJECTNOTSOCKET);
-
- socket = (PKIX_PL_Socket *)object;
-
- *pHashcode = (((socket->timeout << 3) +
- (socket->netAddr->inet.family << 3)) +
- (*((PKIX_UInt32 *)&(socket->netAddr->inet.ip)))) +
- socket->netAddr->inet.port;
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Socket_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PKIX_PL_Socket *firstSocket = NULL;
- PKIX_PL_Socket *secondSocket = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- *pResult = PKIX_FALSE;
-
- PKIX_CHECK(pkix_CheckTypes
- (firstObject, secondObject, PKIX_SOCKET_TYPE, plContext),
- PKIX_OBJECTNOTSOCKET);
-
- firstSocket = (PKIX_PL_Socket *)firstObject;
- secondSocket = (PKIX_PL_Socket *)secondObject;
-
- if (firstSocket->timeout != secondSocket->timeout) {
- goto cleanup;
- }
-
- if (firstSocket->netAddr == secondSocket->netAddr) {
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- if ((firstSocket->netAddr->inet.family !=
- secondSocket->netAddr->inet.family) ||
- (*((PKIX_UInt32 *)&(firstSocket->netAddr->inet.ip)) !=
- *((PKIX_UInt32 *)&(secondSocket->netAddr->inet.ip))) ||
- (firstSocket->netAddr->inet.port !=
- secondSocket->netAddr->inet.port)) {
-
- goto cleanup;
-
- }
-
- *pResult = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_PL_SOCKET_TYPE and its related
- * functions with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_Socket_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_RegisterSelf");
-
- entry.description = "Socket";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_Socket);
- entry.destructor = pkix_pl_Socket_Destroy;
- entry.equalsFunction = pkix_pl_Socket_Equals;
- entry.hashcodeFunction = pkix_pl_Socket_Hashcode;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_SOCKET_TYPE] = entry;
-
-#ifdef PKIX_SOCKETTRACE
- {
- char *val = NULL;
- val = PR_GetEnv("SOCKETTRACE");
- /* Is SOCKETTRACE set in the environment? */
- if ((val != NULL) && (*val != '\0')) {
- socketTraceFlag =
- ((*val == '1')?PKIX_TRUE:PKIX_FALSE);
- }
- }
-#endif
-
- PKIX_RETURN(SOCKET);
-}
-
-/* --Public-Socket-Functions----------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_Socket_Listen
- * DESCRIPTION:
- *
- * This functions establishes a listening queue for the server Socket
- * pointed to by "socket".
- *
- * PARAMETERS:
- * "socket"
- * The address of the server socket for which the queue is to be
- * established. Must be non-NULL.
- * "backlog"
- * The UInt32 value of the length of the queue to be established.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_Listen(
- PKIX_PL_Socket *socket,
- PKIX_UInt32 backlog,
- void *plContext)
-{
-#ifdef PKIX_SOCKETDEBUG
- PRErrorCode errorcode = 0;
-#endif
- PRStatus rv = PR_FAILURE;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Listen");
- PKIX_NULLCHECK_TWO(socket, socket->serverSock);
-
- PKIX_PL_NSSCALLRV(SOCKET, rv, PR_Listen,
- (socket->serverSock, (PRIntn)backlog));
-
- if (rv == PR_FAILURE) {
-#ifdef PKIX_SOCKETDEBUG
- errorcode = PR_GetError();
- printf
- ("pkix_pl_Socket_Listen: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRLISTENFAILED);
- }
-
-#ifdef PKIX_SOCKETDEBUG
- printf("Successful listen!\n");
-#endif
-
- socket->status = SOCKET_LISTENING;
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Shutdown
- * DESCRIPTION:
- *
- * This functions performs the shutdown of any connections controlled by the
- * socket pointed to by "socket".
- *
- * PARAMETERS:
- * "socket"
- * The address of the socket to be shut down. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_Shutdown(
- PKIX_PL_Socket *socket,
- void *plContext)
-{
-#ifdef PKIX_SOCKETDEBUG
- PRErrorCode errorcode = 0;
-#endif
- PRStatus rv = PR_FAILURE;
- PRFileDesc *fileDesc = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Shutdown");
- PKIX_NULLCHECK_ONE(socket);
-
- fileDesc =
- (socket->isServer)?(socket->serverSock):(socket->clientSock);
-
- PKIX_PL_NSSCALLRV(SOCKET, rv, PR_Shutdown,
- (fileDesc, PR_SHUTDOWN_BOTH));
-
- if (rv == PR_FAILURE) {
-#ifdef PKIX_SOCKETDEBUG
- errorcode = PR_GetError();
- printf
- ("pkix_pl_Socket_Shutdown: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRSHUTDOWNFAILED);
- }
- socket->status = SOCKET_SHUTDOWN;
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Send
- * DESCRIPTION:
- *
- * This functions sends a message using the socket pointed to by "sendSock",
- * from the buffer pointed to by "buf", of the number of bytes given by
- * "bytesToWrite", storing the number of bytes actually written at
- * "pBytesWritten". If "socket" is in non-blocking mode, the send operation
- * may store -1 at "pBytesWritten" and the write is not complete until a
- * corresponding pkix_pl_Poll call has indicated its completion by returning
- * a non-negative value for bytes written.
- *
- * PARAMETERS:
- * "sendSock"
- * The address of the Socket on which the message is to be sent. Must
- * be non-NULL.
- * "buf"
- * The address of the data to be sent. Must be non-NULL.
- * "bytesToWrite""
- * The UInt32 value indicating the number of bytes to write.
- * "pBytesWritten"
- * The address at which the Int32 value indicating the number of bytes
- * actually written is to be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_Send(
- PKIX_PL_Socket *sendSock,
- void *buf,
- PKIX_UInt32 bytesToWrite,
- PKIX_Int32 *pBytesWritten,
- void *plContext)
-{
- PRInt32 bytesWritten = 0;
- PRErrorCode errorcode = 0;
- PRFileDesc *fd = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Send");
- PKIX_NULLCHECK_TWO(buf, pBytesWritten);
-
- fd = sendSock->clientSock;
-
- PKIX_PL_NSSCALLRV(SOCKET, bytesWritten, PR_Send,
- (fd, buf, (PRInt32)bytesToWrite, 0, sendSock->timeout));
-
- if (bytesWritten >= 0) {
- if (sendSock->status == SOCKET_SENDRCVPENDING) {
- sendSock->status = SOCKET_RCVPENDING;
- } else {
- sendSock->status = SOCKET_CONNECTED;
- }
-#ifdef PKIX_SOCKETTRACE
- pkix_pl_socket_tracebuff(buf, bytesWritten);
-#endif
- } else {
- errorcode = PR_GetError();
- if (errorcode != PR_WOULD_BLOCK_ERROR) {
-#ifdef PKIX_SOCKETDEBUG
- printf
- ("pkix_pl_Socket_Send: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRSENDFAILED);
- }
-
- sendSock->writeBuf = buf;
- sendSock->writeBufSize = bytesToWrite;
- if (sendSock->status == SOCKET_RCVPENDING) {
- sendSock->status = SOCKET_SENDRCVPENDING;
- } else {
- sendSock->status = SOCKET_SENDPENDING;
- }
- }
-
- *pBytesWritten = (PKIX_Int32)bytesWritten;
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Recv
- * DESCRIPTION:
- *
- * This functions receives a message on the socket pointed to by "rcvSock",
- * into the buffer pointed to by "buf", of capacity given by "capacity",
- * storing the number of bytes actually received at "pBytesRead". If "socket"
- * is in non-blocking mode, the receive operation may store -1 at
- * "pBytesWritten". In that case the write is not complete until a
- * corresponding pkix_pl_Poll call has indicated its completion by returning
- * a non-negative value for bytes read.
- *
- * PARAMETERS:
- * "rcvSock"
- * The address of the Socket on which the message is to be received.
- * Must be non-NULL.
- * "buf"
- * The address of the buffer into which the message is to be received.
- * Must be non-NULL.
- * "capacity"
- * The UInt32 value of the size of the buffer; that is, the maximum
- * number of bytes that can be received.
- * "pBytesRead"
- * The address at which is stored the Int32 value of the number of bytes
- * actually received.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_Recv(
- PKIX_PL_Socket *rcvSock,
- void *buf,
- PKIX_UInt32 capacity,
- PKIX_Int32 *pBytesRead,
- void *plContext)
-{
- PRErrorCode errorcode = 0;
- PRInt32 bytesRead = 0;
- PRFileDesc *fd = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Recv");
- PKIX_NULLCHECK_THREE(rcvSock, buf, pBytesRead);
-
- fd = rcvSock->clientSock;
-
- PKIX_PL_NSSCALLRV(SOCKET, bytesRead, PR_Recv,
- (fd, buf, (PRInt32)capacity, 0, rcvSock->timeout));
-
- if (bytesRead > 0) {
- if (rcvSock->status == SOCKET_SENDRCVPENDING) {
- rcvSock->status = SOCKET_SENDPENDING;
- } else {
- rcvSock->status = SOCKET_CONNECTED;
- }
-#ifdef PKIX_SOCKETTRACE
- pkix_pl_socket_tracebuff(buf, bytesRead);
-#endif
- } else if (bytesRead == 0) {
- PKIX_ERROR(PKIX_PRRECVREPORTSNETWORKCONNECTIONCLOSED);
- } else {
- errorcode = PR_GetError();
- if (errorcode != PR_WOULD_BLOCK_ERROR) {
-#ifdef PKIX_SOCKETDEBUG
- printf
- ("pkix_pl_Socket_Recv: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRRECVFAILED);
- }
- rcvSock->readBuf = buf;
- rcvSock->readBufSize = capacity;
- if (rcvSock->status == SOCKET_SENDPENDING) {
- rcvSock->status = SOCKET_SENDRCVPENDING;
- } else {
- rcvSock->status = SOCKET_RCVPENDING;
- }
-
- }
-
- *pBytesRead = (PKIX_Int32)bytesRead;
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Poll
- * DESCRIPTION:
- *
- * This functions checks for completion of an earlier Send or Recv on the
- * socket pointed to by "sock", storing in "pBytesWritten" the number of bytes
- * written by a completed Send and in "pBytesRead" the number of bytes
- * received in a completed Recv. A value of -1 returned indicates the
- * operation has still not completed. A NULL pointer may be supplied for
- * "pBytesWritten" to avoid checking for completion of a Send. A NULL pointer
- * may be supplied for "pBytesRead" to avoid checking for completion of a Recv.
- *
- * PARAMETERS:
- * "sock"
- * The address of the socket for which completions are to be checked.
- * "pBytesWritten"
- * The address at which the number of bytes written is to be stored, if
- * a pending Send has completed. If NULL, Sends are not checked.
- * "pBytesRead"
- * The address at which the number of bytes read is to be stored, if
- * a pending Recv has completed. If NULL, Recvs are not checked.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_Poll(
- PKIX_PL_Socket *sock,
- PKIX_Int32 *pBytesWritten,
- PKIX_Int32 *pBytesRead,
- void *plContext)
-{
- PRPollDesc pollDesc;
- PRInt32 numEvents = 0;
- PKIX_Int32 bytesRead = 0;
- PKIX_Int32 bytesWritten = 0;
- PRErrorCode errorcode = 0;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Poll");
- PKIX_NULLCHECK_ONE(sock);
-
- pollDesc.fd = sock->clientSock;
- pollDesc.in_flags = 0;
- pollDesc.out_flags = 0;
-
- if ((pBytesWritten) &&
- ((sock->status == SOCKET_SENDPENDING) ||
- (sock->status == SOCKET_SENDRCVPENDING))) {
- pollDesc.in_flags = PR_POLL_WRITE;
- }
-
- if ((pBytesRead) &&
- ((sock->status == SOCKET_RCVPENDING) ||
- (sock->status == SOCKET_SENDRCVPENDING))) {
- pollDesc.in_flags |= PR_POLL_READ;
- }
-
- PKIX_PL_NSSCALLRV(SOCKET, numEvents, PR_Poll, (&pollDesc, 1, 0));
-
- if (numEvents < 0) {
- PKIX_ERROR(PKIX_PRPOLLFAILED);
- } else if (numEvents > 0) {
- if (pollDesc.out_flags & PR_POLL_WRITE) {
- PKIX_CHECK(pkix_pl_Socket_Send
- (sock,
- sock->writeBuf,
- sock->writeBufSize,
- &bytesWritten,
- plContext),
- PKIX_SOCKETSENDFAILED);
- *pBytesWritten = (PKIX_Int32)bytesWritten;
- if (bytesWritten >= 0) {
- sock->writeBuf = NULL;
- sock->writeBufSize = 0;
- }
- }
-
- if (pollDesc.out_flags & PR_POLL_READ) {
- PKIX_CHECK(pkix_pl_Socket_Recv
- (sock,
- sock->readBuf,
- sock->readBufSize,
- &bytesRead,
- plContext),
- PKIX_SOCKETRECVFAILED);
- *pBytesRead = (PKIX_Int32)bytesRead;
- if (bytesRead >= 0) {
- sock->readBuf = NULL;
- sock->readBufSize = 0;
- }
- }
- } else if (numEvents == 0) {
- errorcode = PR_GetError();
- if (errorcode != PR_WOULD_BLOCK_ERROR) {
-#ifdef PKIX_SOCKETDEBUG
- printf
- ("pkix_pl_Socket_Poll: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRPOLLFAILED);
- }
- if (pBytesWritten) {
- *pBytesWritten = 0;
- }
- if (pBytesRead) {
- *pBytesRead = 0;
- }
- }
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Accept
- * DESCRIPTION:
- *
- * This functions accepts a client connection for the server Socket pointed
- * to by "serverSocket", creating a new Socket and storing the result at
- * "pRendezvousSocket". If "serverSocket" is in non-blocking mode, this
- * function will return NULL if there is no client connection to accept.
- * Otherwise this function will block until a connection is available.
- * When a client connection is available the new Socket will have the same
- * blocking/non-blocking property as "serverSocket".
- *
- * PARAMETERS:
- * "serverSocket"
- * The address of the Socket for which a client connection is to be
- * accepted. Must be non-NULL.
- * "pRendezvousSocket"
- * The address at which the created Socket is stored, when a client
- * connection is available, or at which NULL is stored, if no connection
- * is available for a non-blocking "serverSocket". Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety definitions in Programmer's Guide)
- * RETURNS:
- * none
- */
-static PKIX_Error *
-pkix_pl_Socket_Accept(
- PKIX_PL_Socket *serverSocket,
- PKIX_PL_Socket **pRendezvousSocket,
- void *plContext)
-{
- PRErrorCode errorcode = 0;
- PRFileDesc *rendezvousSock = NULL;
- PRNetAddr *clientAddr = NULL;
- PKIX_PL_Socket *newSocket = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Accept");
- PKIX_NULLCHECK_TWO(serverSocket, pRendezvousSocket);
-
- PKIX_PL_NSSCALLRV(SOCKET, rendezvousSock, PR_Accept,
- (serverSocket->serverSock, clientAddr, serverSocket->timeout));
-
- if (!rendezvousSock) {
- errorcode = PR_GetError();
- if (errorcode != PR_WOULD_BLOCK_ERROR) {
-#ifdef PKIX_SOCKETDEBUG
- printf
- ("pkix_pl_Socket_Accept: %s\n",
- PR_ErrorToString(errorcode, PR_LANGUAGE_EN));
-#endif
- PKIX_ERROR(PKIX_PRACCEPTFAILED);
- }
- serverSocket->status = SOCKET_ACCEPTPENDING;
- *pRendezvousSocket = NULL;
- goto cleanup;
-
- }
-
-#ifdef PKIX_SOCKETDEBUG
- printf("Successful accept!\n");
-#endif
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_SOCKET_TYPE,
- sizeof (PKIX_PL_Socket),
- (PKIX_PL_Object **)&newSocket,
- plContext),
- PKIX_COULDNOTCREATESOCKETOBJECT);
-
- newSocket->isServer = PKIX_FALSE;
- newSocket->timeout = serverSocket->timeout;
- newSocket->clientSock = rendezvousSock;
- newSocket->serverSock = NULL;
- newSocket->netAddr = NULL;
- newSocket->status = SOCKET_CONNECTED;
- newSocket->callbackList.shutdownCallback = pkix_pl_Socket_Shutdown;
- newSocket->callbackList.listenCallback = pkix_pl_Socket_Listen;
- newSocket->callbackList.acceptCallback = pkix_pl_Socket_Accept;
- newSocket->callbackList.connectcontinueCallback =
- pkix_pl_Socket_ConnectContinue;
- newSocket->callbackList.sendCallback = pkix_pl_Socket_Send;
- newSocket->callbackList.recvCallback = pkix_pl_Socket_Recv;
- newSocket->callbackList.pollCallback = pkix_pl_Socket_Poll;
-
- if (serverSocket->timeout == 0) {
- PKIX_CHECK(pkix_pl_Socket_SetNonBlocking
- (rendezvousSock, plContext),
- PKIX_SOCKETSETNONBLOCKINGFAILED);
- }
-
- *pRendezvousSocket = newSocket;
-
-cleanup:
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_Create
- * DESCRIPTION:
- *
- * This function creates a new Socket, setting it to be a server or a client
- * according to the value of "isServer", setting its timeout value from
- * "timeout" and server address from "netAddr", and stores the created Socket
- * at "pSocket".
- *
- * PARAMETERS:
- * "isServer"
- * The Boolean value indicating if PKIX_TRUE, that a server socket (using
- * Bind, Listen, and Accept) is to be created, or if PKIX_FALSE, that a
- * client socket (using Connect) is to be created.
- * "timeout"
- * A PRTimeInterval value to be used for I/O waits for this socket. If
- * zero, non-blocking I/O is to be used.
- * "netAddr"
- * The PRNetAddr to be used for the Bind function, if this is a server
- * socket, or for the Connect, if this is a client socket.
- * "pSocket"
- * The address at which the Socket is to be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Socket Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Socket_Create(
- PKIX_Boolean isServer,
- PRIntervalTime timeout,
- PRNetAddr *netAddr,
- PRErrorCode *status,
- PKIX_PL_Socket **pSocket,
- void *plContext)
-{
- PKIX_PL_Socket *socket = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_Create");
- PKIX_NULLCHECK_ONE(pSocket);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_SOCKET_TYPE,
- sizeof (PKIX_PL_Socket),
- (PKIX_PL_Object **)&socket,
- plContext),
- PKIX_COULDNOTCREATESOCKETOBJECT);
-
- socket->isServer = isServer;
- socket->timeout = timeout;
- socket->clientSock = NULL;
- socket->serverSock = NULL;
- socket->netAddr = netAddr;
-
- socket->callbackList.listenCallback = pkix_pl_Socket_Listen;
- socket->callbackList.acceptCallback = pkix_pl_Socket_Accept;
- socket->callbackList.connectcontinueCallback =
- pkix_pl_Socket_ConnectContinue;
- socket->callbackList.sendCallback = pkix_pl_Socket_Send;
- socket->callbackList.recvCallback = pkix_pl_Socket_Recv;
- socket->callbackList.pollCallback = pkix_pl_Socket_Poll;
- socket->callbackList.shutdownCallback = pkix_pl_Socket_Shutdown;
-
- if (isServer) {
- PKIX_CHECK(pkix_pl_Socket_CreateServer(socket, plContext),
- PKIX_SOCKETCREATESERVERFAILED);
- *status = 0;
- } else {
- socket->timeout = timeout;
- PKIX_CHECK(pkix_pl_Socket_CreateClient(socket, plContext),
- PKIX_SOCKETCREATECLIENTFAILED);
- PKIX_CHECK(pkix_pl_Socket_Connect(socket, status, plContext),
- PKIX_SOCKETCONNECTFAILED);
- }
-
- *pSocket = socket;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(socket);
- }
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_CreateByName
- * DESCRIPTION:
- *
- * This function creates a new Socket, setting it to be a server or a client
- * according to the value of "isServer", setting its timeout value from
- * "timeout" and server address and port number from "serverName", and stores
- * the status at "pStatus" and the created Socket at "pSocket".
- *
- * If isServer is PKIX_TRUE, it is attempted to create the socket with an ip
- * address of PR_INADDR_ANY.
- *
- * PARAMETERS:
- * "isServer"
- * The Boolean value indicating if PKIX_TRUE, that a server socket (using
- * Bind, Listen, and Accept) is to be created, or if PKIX_FALSE, that a
- * client socket (using Connect) is to be created.
- * "timeout"
- * A PRTimeInterval value to be used for I/O waits for this socket. If
- * zero, non-blocking I/O is to be used.
- * "serverName"
- * Address of a character string consisting of the server's domain name
- * followed by a colon and a port number for the desired socket.
- * "pStatus"
- * Address at which the PRErrorCode resulting from the create is
- * stored. Must be non-NULL.
- * "pSocket"
- * The address at which the Socket is to be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Socket Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Socket_CreateByName(
- PKIX_Boolean isServer,
- PRIntervalTime timeout,
- char *serverName,
- PRErrorCode *pStatus,
- PKIX_PL_Socket **pSocket,
- void *plContext)
-{
- PRNetAddr netAddr;
- PKIX_PL_Socket *socket = NULL;
- char *sepPtr = NULL;
- PRHostEnt hostent;
- PRIntn hostenum;
- PRStatus prstatus = PR_FAILURE;
- char buf[PR_NETDB_BUF_SIZE];
- PRUint16 portNum = 0;
- char *localCopyName = NULL;
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_CreateByName");
- PKIX_NULLCHECK_TWO(serverName, pSocket);
-
- localCopyName = PL_strdup(serverName);
-
- sepPtr = strchr(localCopyName, ':');
- /* First strip off the portnum, if present, from the end of the name */
- if (sepPtr) {
- *sepPtr++ = '\0';
- portNum = (PRUint16)atoi(sepPtr);
- } else {
- portNum = (PRUint16)LDAP_PORT;
- }
-
- prstatus = PR_GetHostByName(localCopyName, buf, sizeof(buf), &hostent);
-
- if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) {
- /*
- * The hostname may be a fully-qualified name. Try using just
- * the leftmost component in our lookup.
- */
- sepPtr = strchr(localCopyName, '.');
- if (sepPtr) {
- *sepPtr++ = '\0';
- }
- prstatus = PR_GetHostByName
- (localCopyName, buf, sizeof(buf), &hostent);
-
- if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) {
- PKIX_ERROR
- (PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT);
- }
- }
-
- netAddr.inet.family = PR_AF_INET;
- netAddr.inet.port = PR_htons(portNum);
-
- if (isServer) {
-
- netAddr.inet.ip = PR_INADDR_ANY;
-
- } else {
-
- hostenum = PR_EnumerateHostEnt(0, &hostent, portNum, &netAddr);
- if (hostenum == -1) {
- PKIX_ERROR(PKIX_PRENUMERATEHOSTENTFAILED);
- }
- }
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_SOCKET_TYPE,
- sizeof (PKIX_PL_Socket),
- (PKIX_PL_Object **)&socket,
- plContext),
- PKIX_COULDNOTCREATESOCKETOBJECT);
-
- socket->isServer = isServer;
- socket->timeout = timeout;
- socket->clientSock = NULL;
- socket->serverSock = NULL;
- socket->netAddr = &netAddr;
-
- socket->callbackList.listenCallback = pkix_pl_Socket_Listen;
- socket->callbackList.acceptCallback = pkix_pl_Socket_Accept;
- socket->callbackList.connectcontinueCallback =
- pkix_pl_Socket_ConnectContinue;
- socket->callbackList.sendCallback = pkix_pl_Socket_Send;
- socket->callbackList.recvCallback = pkix_pl_Socket_Recv;
- socket->callbackList.pollCallback = pkix_pl_Socket_Poll;
- socket->callbackList.shutdownCallback = pkix_pl_Socket_Shutdown;
-
- if (isServer) {
- PKIX_CHECK(pkix_pl_Socket_CreateServer(socket, plContext),
- PKIX_SOCKETCREATESERVERFAILED);
- *pStatus = 0;
- } else {
- PKIX_CHECK(pkix_pl_Socket_CreateClient(socket, plContext),
- PKIX_SOCKETCREATECLIENTFAILED);
- PKIX_CHECK(pkix_pl_Socket_Connect(socket, pStatus, plContext),
- PKIX_SOCKETCONNECTFAILED);
- }
-
- *pSocket = socket;
-
-cleanup:
- PL_strfree(localCopyName);
-
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(socket);
- }
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_CreateByHostAndPort
- * DESCRIPTION:
- *
- * This function creates a new Socket, setting it to be a server or a client
- * according to the value of "isServer", setting its timeout value from
- * "timeout", host from "hostname", and port number from "portNum", and stores
- * the status at "pStatus" and the created Socket at "pSocket".
- *
- * If isServer is PKIX_TRUE, it is attempted to create the socket with an ip
- * address of PR_INADDR_ANY.
- *
- * PARAMETERS:
- * "isServer"
- * The Boolean value indicating if PKIX_TRUE, that a server socket (using
- * Bind, Listen, and Accept) is to be created, or if PKIX_FALSE, that a
- * client socket (using Connect) is to be created.
- * "timeout"
- * A PRTimeInterval value to be used for I/O waits for this socket. If
- * zero, non-blocking I/O is to be used.
- * "hostname"
- * Address of a character string consisting of the server's domain name.
- * "portNum"
- * UInt16 value of the port number for the desired socket.
- * "pStatus"
- * Address at which the PRErrorCode resulting from the create is
- * stored. Must be non-NULL.
- * "pSocket"
- * The address at which the Socket is to be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Socket Error if the function fails in
- * a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Socket_CreateByHostAndPort(
- PKIX_Boolean isServer,
- PRIntervalTime timeout,
- char *hostname,
- PRUint16 portnum,
- PRErrorCode *pStatus,
- PKIX_PL_Socket **pSocket,
- void *plContext)
-{
- PRNetAddr netAddr;
- PKIX_PL_Socket *socket = NULL;
- char *sepPtr = NULL;
- PRHostEnt hostent;
- PRIntn hostenum;
- PRStatus prstatus = PR_FAILURE;
- char buf[PR_NETDB_BUF_SIZE];
-
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_CreateByHostAndPort");
- PKIX_NULLCHECK_THREE(hostname, pStatus, pSocket);
-
-
- prstatus = PR_GetHostByName(hostname, buf, sizeof(buf), &hostent);
-
- if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) {
- /*
- * The hostname may be a fully-qualified name. Try using just
- * the leftmost component in our lookup.
- */
- sepPtr = strchr(hostname, '.');
- if (sepPtr) {
- *sepPtr++ = '\0';
- }
- prstatus = PR_GetHostByName(hostname, buf, sizeof(buf), &hostent);
-
- if ((prstatus != PR_SUCCESS) || (hostent.h_length != 4)) {
- PKIX_ERROR
- (PKIX_PRGETHOSTBYNAMEREJECTSHOSTNAMEARGUMENT);
- }
- }
-
- netAddr.inet.family = PR_AF_INET;
- netAddr.inet.port = PR_htons(portnum);
-
- if (isServer) {
-
- netAddr.inet.ip = PR_INADDR_ANY;
-
- } else {
-
- hostenum = PR_EnumerateHostEnt(0, &hostent, portnum, &netAddr);
- if (hostenum == -1) {
- PKIX_ERROR(PKIX_PRENUMERATEHOSTENTFAILED);
- }
- }
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_SOCKET_TYPE,
- sizeof (PKIX_PL_Socket),
- (PKIX_PL_Object **)&socket,
- plContext),
- PKIX_COULDNOTCREATESOCKETOBJECT);
-
- socket->isServer = isServer;
- socket->timeout = timeout;
- socket->clientSock = NULL;
- socket->serverSock = NULL;
- socket->netAddr = &netAddr;
-
- socket->callbackList.listenCallback = pkix_pl_Socket_Listen;
- socket->callbackList.acceptCallback = pkix_pl_Socket_Accept;
- socket->callbackList.connectcontinueCallback =
- pkix_pl_Socket_ConnectContinue;
- socket->callbackList.sendCallback = pkix_pl_Socket_Send;
- socket->callbackList.recvCallback = pkix_pl_Socket_Recv;
- socket->callbackList.pollCallback = pkix_pl_Socket_Poll;
- socket->callbackList.shutdownCallback = pkix_pl_Socket_Shutdown;
-
- if (isServer) {
- PKIX_CHECK(pkix_pl_Socket_CreateServer(socket, plContext),
- PKIX_SOCKETCREATESERVERFAILED);
- *pStatus = 0;
- } else {
- PKIX_CHECK(pkix_pl_Socket_CreateClient(socket, plContext),
- PKIX_SOCKETCREATECLIENTFAILED);
- PKIX_CHECK(pkix_pl_Socket_Connect(socket, pStatus, plContext),
- PKIX_SOCKETCONNECTFAILED);
- }
-
- *pSocket = socket;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- PKIX_DECREF(socket);
- }
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_GetCallbackList
- */
-PKIX_Error *
-pkix_pl_Socket_GetCallbackList(
- PKIX_PL_Socket *socket,
- PKIX_PL_Socket_Callback **pCallbackList,
- void *plContext)
-{
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_GetCallbackList");
- PKIX_NULLCHECK_TWO(socket, pCallbackList);
-
- *pCallbackList = &(socket->callbackList);
-
- PKIX_RETURN(SOCKET);
-}
-
-/*
- * FUNCTION: pkix_pl_Socket_GetPRFileDesc
- */
-PKIX_Error *
-pkix_pl_Socket_GetPRFileDesc(
- PKIX_PL_Socket *socket,
- PRFileDesc **pDesc,
- void *plContext)
-{
- PKIX_ENTER(SOCKET, "pkix_pl_Socket_GetPRFileDesc");
- PKIX_NULLCHECK_TWO(socket, pDesc);
-
- *pDesc = socket->clientSock;
-
- PKIX_RETURN(SOCKET);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.h b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.h
deleted file mode 100644
index abf6628b3..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_socket.h
- *
- * Socket Object Type Definition
- *
- */
-
-#ifndef _PKIX_PL_SOCKET_H
-#define _PKIX_PL_SOCKET_H
-
-#include <errno.h>
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- SOCKET_BOUND,
- SOCKET_LISTENING,
- SOCKET_ACCEPTPENDING,
- SOCKET_UNCONNECTED,
- SOCKET_CONNECTPENDING,
- SOCKET_CONNECTED,
- SOCKET_SENDPENDING,
- SOCKET_RCVPENDING,
- SOCKET_SENDRCVPENDING,
- SOCKET_SHUTDOWN
-} SockStatus;
-
-/* This is the default port number, if none is supplied to CreateByName. */
-#define LDAP_PORT 389
-
-/*
- * These callbacks allow a user to substitute a counterfeit socket in places
- * where a PKIX_PL_Socket is expected. A conforming usage will use the
- * ListenCallback function instead of Listen, AcceptCallback instead of Accept,
- * etc. The counterfeit socket may have special capabilites such as the
- * ability to do proxy authentication, etc.
- */
-
-typedef PKIX_Error *
-(*pkix_pl_Socket_ListenCallback)(
- PKIX_PL_Socket *socket,
- PKIX_UInt32 backlog,
- void *plContext);
-
-typedef PKIX_Error *
-(*pkix_pl_Socket_AcceptCallback)(
- PKIX_PL_Socket *socket,
- PKIX_PL_Socket **pRendezvousSock,
- void *plContext);
-
-typedef PKIX_Error *
-(*pkix_pl_Socket_ConnectContinueCallback)(
- PKIX_PL_Socket *socket,
- PRErrorCode *pStatus,
- void *plContext);
-
-typedef PKIX_Error *
-(*pkix_pl_Socket_SendCallback)(
- PKIX_PL_Socket *sendSock,
- void *buf,
- PKIX_UInt32 bytesToWrite,
- PKIX_Int32 *pBytesWritten,
- void *plContext);
-
-typedef PKIX_Error *
-(*pkix_pl_Socket_RecvCallback)(
- PKIX_PL_Socket *rcvSock,
- void *buf,
- PKIX_UInt32 capacity,
- PKIX_Int32 *pBytesRead,
- void *plContext);
-
-typedef PKIX_Error *
-(*pkix_pl_Socket_PollCallback)(
- PKIX_PL_Socket *sock,
- PKIX_Int32 *pBytesWritten,
- PKIX_Int32 *pBytesRead,
- void *plContext);
-
-typedef PKIX_Error *
-(*pkix_pl_Socket_ShutdownCallback)(
- PKIX_PL_Socket *socket, void *plContext);
-
-typedef struct PKIX_PL_Socket_CallbackStruct {
- pkix_pl_Socket_ListenCallback listenCallback;
- pkix_pl_Socket_AcceptCallback acceptCallback;
- pkix_pl_Socket_ConnectContinueCallback connectcontinueCallback;
- pkix_pl_Socket_SendCallback sendCallback;
- pkix_pl_Socket_RecvCallback recvCallback;
- pkix_pl_Socket_PollCallback pollCallback;
- pkix_pl_Socket_ShutdownCallback shutdownCallback;
-} PKIX_PL_Socket_Callback;
-
-struct PKIX_PL_SocketStruct {
- PKIX_Boolean isServer;
- PRIntervalTime timeout; /* zero for non-blocking I/O */
- SockStatus status;
- PRFileDesc *clientSock;
- PRFileDesc *serverSock;
- void *readBuf;
- void *writeBuf;
- PKIX_UInt32 readBufSize;
- PKIX_UInt32 writeBufSize;
- PRNetAddr *netAddr;
- PKIX_PL_Socket_Callback callbackList;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_Socket_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_pl_Socket_Create(
- PKIX_Boolean isServer,
- PRIntervalTime timeout, /* zero for non-blocking I/O */
- PRNetAddr *netAddr,
- PRErrorCode *status,
- PKIX_PL_Socket **pSocket,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_Socket_CreateByName(
- PKIX_Boolean isServer,
- PRIntervalTime timeout,
- char *serverName,
- PRErrorCode *pStatus,
- PKIX_PL_Socket **pSocket,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_Socket_CreateByHostAndPort(
- PKIX_Boolean isServer,
- PRIntervalTime timeout,
- char *hostname,
- PRUint16 portnum,
- PRErrorCode *pStatus,
- PKIX_PL_Socket **pSocket,
- void *plContext);
-
-/* Do not use these functions directly; use their callback variants instead
- * static PKIX_Error *
- * pkix_pl_Socket_Listen(
- * PKIX_PL_Socket *socket,
- * PKIX_UInt32 backlog,
- * void *plContext);
- *
- * static PKIX_Error *
- * pkix_pl_Socket_Accept(
- * PKIX_PL_Socket *socket,
- * PKIX_PL_Socket **pRendezvousSock,
- * void *plContext);
- *
- * static PKIX_Error *
- * pkix_pl_Socket_ConnectContinue(
- * PKIX_PL_Socket *socket,
- * PRErrorCode *pStatus,
- * void *plContext);
- *
- * static PKIX_Error *
- * pkix_pl_Socket_Send(
- * PKIX_PL_Socket *sendSock,
- * void *buf,
- * PKIX_UInt32 bytesToWrite,
- * PKIX_Int32 *pBytesWritten,
- * void *plContext);
- *
- * static PKIX_Error *
- * pkix_pl_Socket_Recv(
- * PKIX_PL_Socket *rcvSock,
- * void *buf,
- * PKIX_UInt32 capacity,
- * PKIX_Int32 *pBytesRead,
- * void *plContext);
- *
- * static PKIX_Error *
- * pkix_pl_Socket_Poll(
- * PKIX_PL_Socket *sock,
- * PKIX_Int32 *pBytesWritten,
- * PKIX_Int32 *pBytesRead,
- * void *plContext);
- *
- * static PKIX_Error *
- * pkix_pl_Socket_Shutdown(
- * PKIX_PL_Socket *socket, void *plContext);
- */
-
-PKIX_Error *
-pkix_pl_Socket_GetCallbackList(
- PKIX_PL_Socket *socket,
- PKIX_PL_Socket_Callback **pCallbackList,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_Socket_GetPRFileDesc(
- PKIX_PL_Socket *socket,
- PRFileDesc **pDesc,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_SOCKET_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/Makefile b/security/nss/lib/libpkix/pkix_pl_nss/pki/Makefile
deleted file mode 100755
index 0fb6c9058..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/config.mk b/security/nss/lib/libpkix/pkix_pl_nss/pki/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn b/security/nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn
deleted file mode 100755
index e49d21806..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/manifest.mn
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_pl_basicconstraints.h \
- pkix_pl_cert.h \
- pkix_pl_certpolicyinfo.h \
- pkix_pl_certpolicymap.h \
- pkix_pl_certpolicyqualifier.h \
- pkix_pl_crl.h \
- pkix_pl_crldp.h \
- pkix_pl_crlentry.h \
- pkix_pl_date.h \
- pkix_pl_generalname.h \
- pkix_pl_infoaccess.h \
- pkix_pl_nameconstraints.h \
- pkix_pl_ocsprequest.h \
- pkix_pl_ocspresponse.h \
- pkix_pl_publickey.h \
- pkix_pl_x500name.h \
- pkix_pl_ocspcertid.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_pl_basicconstraints.c \
- pkix_pl_cert.c \
- pkix_pl_certpolicyinfo.c \
- pkix_pl_certpolicymap.c \
- pkix_pl_certpolicyqualifier.c \
- pkix_pl_crl.c \
- pkix_pl_crldp.c \
- pkix_pl_crlentry.c \
- pkix_pl_date.c \
- pkix_pl_generalname.c \
- pkix_pl_infoaccess.c \
- pkix_pl_nameconstraints.c \
- pkix_pl_ocsprequest.c \
- pkix_pl_ocspresponse.c \
- pkix_pl_publickey.c \
- pkix_pl_x500name.c \
- pkix_pl_ocspcertid.c \
- $(NULL)
-
-LIBRARY_NAME = pkixpki
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.c
deleted file mode 100644
index 81615da37..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_basicconstraints.c
- *
- * BasicConstraints Object Functions
- *
- */
-
-#include "pkix_pl_basicconstraints.h"
-
-/*
- * FUNCTION: pkix_pl_CertBasicConstraints_Create
- * DESCRIPTION:
- *
- * Creates a new CertBasicConstraints object whose CA Flag has the value
- * given by the Boolean value of "isCA" and whose path length field has the
- * value given by the "pathLen" argument and stores it at "pObject".
- *
- * PARAMETERS
- * "isCA"
- * Boolean value with the desired value of CA Flag.
- * "pathLen"
- * a PKIX_Int32 with the desired value of path length
- * "pObject"
- * Address of object pointer's destination. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertBasicConstraints Error if the function fails
- * in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CertBasicConstraints_Create(
- PKIX_Boolean isCA,
- PKIX_Int32 pathLen,
- PKIX_PL_CertBasicConstraints **pObject,
- void *plContext)
-{
- PKIX_PL_CertBasicConstraints *basic = NULL;
-
- PKIX_ENTER(CERTBASICCONSTRAINTS,
- "pkix_pl_CertBasicConstraints_Create");
- PKIX_NULLCHECK_ONE(pObject);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTBASICCONSTRAINTS_TYPE,
- sizeof (PKIX_PL_CertBasicConstraints),
- (PKIX_PL_Object **)&basic,
- plContext),
- PKIX_COULDNOTCREATECERTBASICCONSTRAINTSOBJECT);
-
- basic->isCA = isCA;
-
- /* pathLen has meaning only for CAs, but it's not worth checking */
- basic->pathLen = pathLen;
-
- *pObject = basic;
-
-cleanup:
-
- PKIX_RETURN(CERTBASICCONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertBasicConstraints_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertBasicConstraints_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_CertBasicConstraints *certB = NULL;
-
- PKIX_ENTER(CERTBASICCONSTRAINTS,
- "pkix_pl_CertBasicConstraints_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
- PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
-
- certB = (PKIX_PL_CertBasicConstraints*)object;
-
- certB->isCA = PKIX_FALSE;
- certB->pathLen = 0;
-
-cleanup:
-
- PKIX_RETURN(CERTBASICCONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertBasicConstraints_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertBasicConstraints_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *certBasicConstraintsString = NULL;
- PKIX_PL_CertBasicConstraints *certB = NULL;
- PKIX_Boolean isCA = PKIX_FALSE;
- PKIX_Int32 pathLen = 0;
- PKIX_PL_String *outString = NULL;
- char *fmtString = NULL;
- PKIX_Boolean pathlenArg = PKIX_FALSE;
-
- PKIX_ENTER(CERTBASICCONSTRAINTS,
- "pkix_pl_CertBasicConstraints_toString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
- PKIX_FIRSTARGUMENTNOTCERTBASICCONSTRAINTSOBJECT);
-
- certB = (PKIX_PL_CertBasicConstraints *)object;
-
- /*
- * if CA == TRUE
- * if pathLen == CERT_UNLIMITED_PATH_CONSTRAINT
- * print "CA(-1)"
- * else print "CA(nnn)"
- * if CA == FALSE, print "~CA"
- */
-
- isCA = certB->isCA;
-
- if (isCA) {
- pathLen = certB->pathLen;
-
- if (pathLen == CERT_UNLIMITED_PATH_CONSTRAINT) {
- /* print "CA(-1)" */
- fmtString = "CA(-1)";
- pathlenArg = PKIX_FALSE;
- } else {
- /* print "CA(pathLen)" */
- fmtString = "CA(%d)";
- pathlenArg = PKIX_TRUE;
- }
- } else {
- /* print "~CA" */
- fmtString = "~CA";
- pathlenArg = PKIX_FALSE;
- }
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- fmtString,
- 0,
- &certBasicConstraintsString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- if (pathlenArg) {
- PKIX_CHECK(PKIX_PL_Sprintf
- (&outString,
- plContext,
- certBasicConstraintsString,
- pathLen),
- PKIX_SPRINTFFAILED);
- } else {
- PKIX_CHECK(PKIX_PL_Sprintf
- (&outString,
- plContext,
- certBasicConstraintsString),
- PKIX_SPRINTFFAILED);
- }
-
- *pString = outString;
-
-cleanup:
-
- PKIX_DECREF(certBasicConstraintsString);
-
- PKIX_RETURN(CERTBASICCONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertBasicConstraints_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertBasicConstraints_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_CertBasicConstraints *certB = NULL;
- PKIX_Boolean isCA = PKIX_FALSE;
- PKIX_Int32 pathLen = 0;
- PKIX_Int32 hashInput = 0;
- PKIX_UInt32 cbcHash = 0;
-
- PKIX_ENTER(CERTBASICCONSTRAINTS,
- "pkix_pl_CertBasicConstraints_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
- PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
-
- certB = (PKIX_PL_CertBasicConstraints *)object;
-
- /*
- * if CA == TRUE
- * hash(pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT)
- * if CA == FALSE, hash(0)
- */
-
- isCA = certB->isCA;
-
- if (isCA) {
- pathLen = certB->pathLen;
-
- hashInput = pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT;
- }
-
- PKIX_CHECK(pkix_hash
- ((const unsigned char *)&hashInput,
- sizeof (hashInput),
- &cbcHash,
- plContext),
- PKIX_HASHFAILED);
-
- *pHashcode = cbcHash;
-
-cleanup:
-
- PKIX_RETURN(CERTBASICCONSTRAINTS);
-}
-
-
-/*
- * FUNCTION: pkix_pl_CertBasicConstraints_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertBasicConstraints_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_CertBasicConstraints *firstCBC = NULL;
- PKIX_PL_CertBasicConstraints *secondCBC = NULL;
- PKIX_UInt32 secondType;
- PKIX_Boolean firstIsCA = PKIX_FALSE;
- PKIX_Boolean secondIsCA = PKIX_FALSE;
- PKIX_Int32 firstPathLen = 0;
- PKIX_Int32 secondPathLen = 0;
-
- PKIX_ENTER(CERTBASICCONSTRAINTS,
- "pkix_pl_CertBasicConstraints_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a CertBasicConstraints */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCERTBASICCONSTRAINTS);
-
- /*
- * Since we know firstObject is a CertBasicConstraints,
- * if both references are identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a CertBasicConstraints, we
- * don't throw an error. We simply return FALSE.
- */
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_CERTBASICCONSTRAINTS_TYPE) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- firstCBC = (PKIX_PL_CertBasicConstraints *)firstObject;
- secondCBC = (PKIX_PL_CertBasicConstraints *)secondObject;
-
- /*
- * Compare the value of the CAFlag components
- */
-
- firstIsCA = firstCBC->isCA;
-
- /*
- * Failure here would be an error, not merely a miscompare,
- * since we know second is a CertBasicConstraints.
- */
- secondIsCA = secondCBC->isCA;
-
- /*
- * If isCA flags differ, the objects are not equal.
- */
- if (secondIsCA != firstIsCA) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- /*
- * If isCA was FALSE, the objects are equal, because
- * pathLen is meaningless in that case.
- */
- if (!firstIsCA) {
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- firstPathLen = firstCBC->pathLen;
- secondPathLen = secondCBC->pathLen;
-
- *pResult = (secondPathLen == firstPathLen);
-
-cleanup:
-
- PKIX_RETURN(CERTBASICCONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertBasicConstraints_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERTBASICCONSTRAINTS_TYPE and its related
- * functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize,
- * which should only be called once, it is acceptable that
- * this function is not thread-safe.
- */
-PKIX_Error *
-pkix_pl_CertBasicConstraints_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTBASICCONSTRAINTS,
- "pkix_pl_CertBasicConstraints_RegisterSelf");
-
- entry.description = "CertBasicConstraints";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_CertBasicConstraints);
- entry.destructor = pkix_pl_CertBasicConstraints_Destroy;
- entry.equalsFunction = pkix_pl_CertBasicConstraints_Equals;
- entry.hashcodeFunction = pkix_pl_CertBasicConstraints_Hashcode;
- entry.toStringFunction = pkix_pl_CertBasicConstraints_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_CERTBASICCONSTRAINTS_TYPE] = entry;
-
- PKIX_RETURN(CERTBASICCONSTRAINTS);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_BasicConstraints_GetCAFlag
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_BasicConstraints_GetCAFlag(
- PKIX_PL_CertBasicConstraints *basicConstraints,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_ENTER(CERTBASICCONSTRAINTS,
- "PKIX_PL_BasicConstraintsGetCAFlag");
- PKIX_NULLCHECK_TWO(basicConstraints, pResult);
-
- *pResult = basicConstraints->isCA;
-
- PKIX_RETURN(CERTBASICCONSTRAINTS);
-}
-
-/*
- * FUNCTION: PKIX_PL_BasicConstraints_GetPathLenConstraint
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_BasicConstraints_GetPathLenConstraint(
- PKIX_PL_CertBasicConstraints *basicConstraints,
- PKIX_Int32 *pPathLenConstraint,
- void *plContext)
-{
- PKIX_ENTER(CERTBASICCONSTRAINTS,
- "PKIX_PL_BasicConstraintsGetPathLenConstraint");
- PKIX_NULLCHECK_TWO(basicConstraints, pPathLenConstraint);
-
- *pPathLenConstraint = basicConstraints->pathLen;
-
- PKIX_RETURN(CERTBASICCONSTRAINTS);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.h
deleted file mode 100644
index 857529c95..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_basicconstraints.h
- *
- * BasicConstraints Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_BASICCONSTRAINTS_H
-#define _PKIX_PL_BASICCONSTRAINTS_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This structure reflects the contents of the basic constraints
- * extension as described in Section 4.2.1.10 of RFC 3280.
- * The cA flag indicates whether the public key in this certificate
- * belongs to a certification authority. The pathLen constraint
- * gives the maximum number of non-self-issued intermediate certificates
- * that may follow this certificate in a valid certification path.
- */
-struct PKIX_PL_CertBasicConstraintsStruct {
- PKIX_Boolean isCA;
- PKIX_Int32 pathLen;
-};
-
-PKIX_Error *
-pkix_pl_CertBasicConstraints_Create(
- PKIX_Boolean isCA,
- PKIX_Int32 pathLen,
- PKIX_PL_CertBasicConstraints **object,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_CertBasicConstraints_RegisterSelf(
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_BASICCONSTRAINTS_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
deleted file mode 100644
index 147e03de2..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c
+++ /dev/null
@@ -1,3710 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_cert.c
- *
- * Certificate Object Functions
- *
- */
-
-#include "pkix_pl_cert.h"
-
-extern PKIX_PL_HashTable *cachedCertSigTable;
-
-/* --Private-Cert-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_Cert_IsExtensionCritical
- * DESCRIPTION:
- *
- * Checks the Cert specified by "cert" to determine whether the extension
- * whose tag is the UInt32 value given by "tag" is marked as a critical
- * extension, and stores the result in "pCritical".
- *
- * Tags are the index into the table "oids" of SECOidData defined in the
- * file secoid.c. Constants, such as SEC_OID_X509_CERTIFICATE_POLICIES, are
- * are defined in secoidt.h for most of the table entries.
- *
- * If the specified tag is invalid (not in the list of tags) or if the
- * extension is not found in the certificate, PKIX_FALSE is stored.
- *
- * PARAMETERS
- * "cert"
- * Address of Cert whose extensions are to be examined. Must be non-NULL.
- * "tag"
- * The UInt32 value of the tag for the extension whose criticality is
- * to be determined
- * "pCritical"
- * Address where the Boolean value will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Cert_IsExtensionCritical(
- PKIX_PL_Cert *cert,
- PKIX_UInt32 tag,
- PKIX_Boolean *pCritical,
- void *plContext)
-{
- PKIX_Boolean criticality = PKIX_FALSE;
- CERTCertExtension **extensions = NULL;
- SECStatus rv;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_IsExtensionCritical");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCritical);
-
- extensions = cert->nssCert->extensions;
- PKIX_NULLCHECK_ONE(extensions);
-
- PKIX_CERT_DEBUG("\t\tCalling CERT_GetExtenCriticality).\n");
- rv = CERT_GetExtenCriticality(extensions, tag, &criticality);
- if (SECSuccess == rv) {
- *pCritical = criticality;
- } else {
- *pCritical = PKIX_FALSE;
- }
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_DecodePolicyInfo
- * DESCRIPTION:
- *
- * Decodes the contents of the CertificatePolicy extension in the
- * CERTCertificate pointed to by "nssCert", to create a List of
- * CertPolicyInfos, which is stored at the address "pCertPolicyInfos".
- * A CERTCertificate contains the DER representation of the Cert.
- * If this certificate does not have a CertificatePolicy extension,
- * NULL will be stored. If a List is returned, it will be immutable.
- *
- * PARAMETERS
- * "nssCert"
- * Address of the Cert data whose extension is to be examined. Must be
- * non-NULL.
- * "pCertPolicyInfos"
- * Address where the List of CertPolicyInfos will be stored. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Cert_DecodePolicyInfo(
- CERTCertificate *nssCert,
- PKIX_List **pCertPolicyInfos,
- void *plContext)
-{
-
- SECStatus rv;
- SECItem encodedCertPolicyInfo;
-
- /* Allocated in the arena; freed in CERT_Destroy... */
- CERTCertificatePolicies *certPol = NULL;
- CERTPolicyInfo **policyInfos = NULL;
-
- /* Holder for the return value */
- PKIX_List *infos = NULL;
-
- PKIX_PL_OID *pkixOID = NULL;
- PKIX_List *qualifiers = NULL;
- PKIX_PL_CertPolicyInfo *certPolicyInfo = NULL;
- PKIX_PL_CertPolicyQualifier *certPolicyQualifier = NULL;
- PKIX_PL_ByteArray *qualifierArray = NULL;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyInfo");
- PKIX_NULLCHECK_TWO(nssCert, pCertPolicyInfos);
-
- /* get PolicyInfo as a SECItem */
- PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
- rv = CERT_FindCertExtension
- (nssCert,
- SEC_OID_X509_CERTIFICATE_POLICIES,
- &encodedCertPolicyInfo);
- if (SECSuccess != rv) {
- *pCertPolicyInfos = NULL;
- goto cleanup;
- }
-
- /* translate PolicyInfo to CERTCertificatePolicies */
- PKIX_CERT_DEBUG("\t\tCERT_DecodeCertificatePoliciesExtension).\n");
- certPol = CERT_DecodeCertificatePoliciesExtension
- (&encodedCertPolicyInfo);
-
- PORT_Free(encodedCertPolicyInfo.data);
-
- if (NULL == certPol) {
- PKIX_ERROR(PKIX_CERTDECODECERTIFICATEPOLICIESEXTENSIONFAILED);
- }
-
- /*
- * Check whether there are any policyInfos, so we can
- * avoid creating an unnecessary List
- */
- policyInfos = certPol->policyInfos;
- if (!policyInfos) {
- *pCertPolicyInfos = NULL;
- goto cleanup;
- }
-
- /* create a List of CertPolicyInfo Objects */
- PKIX_CHECK(PKIX_List_Create(&infos, plContext),
- PKIX_LISTCREATEFAILED);
-
- /*
- * Traverse the CERTCertificatePolicies structure,
- * building each PKIX_PL_CertPolicyInfo object in turn
- */
- while (*policyInfos != NULL) {
- CERTPolicyInfo *policyInfo = *policyInfos;
- CERTPolicyQualifier **policyQualifiers =
- policyInfo->policyQualifiers;
- if (policyQualifiers) {
- /* create a PKIX_List of PKIX_PL_CertPolicyQualifiers */
- PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext),
- PKIX_LISTCREATEFAILED);
-
- while (*policyQualifiers != NULL) {
- CERTPolicyQualifier *policyQualifier =
- *policyQualifiers;
-
- /* create the qualifier's OID object */
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
- (&policyQualifier->qualifierID,
- &pkixOID, plContext),
- PKIX_OIDCREATEFAILED);
-
- /* create qualifier's ByteArray object */
-
- PKIX_CHECK(PKIX_PL_ByteArray_Create
- (policyQualifier->qualifierValue.data,
- policyQualifier->qualifierValue.len,
- &qualifierArray,
- plContext),
- PKIX_BYTEARRAYCREATEFAILED);
-
- /* create a CertPolicyQualifier object */
-
- PKIX_CHECK(pkix_pl_CertPolicyQualifier_Create
- (pkixOID,
- qualifierArray,
- &certPolicyQualifier,
- plContext),
- PKIX_CERTPOLICYQUALIFIERCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (qualifiers,
- (PKIX_PL_Object *)certPolicyQualifier,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(pkixOID);
- PKIX_DECREF(qualifierArray);
- PKIX_DECREF(certPolicyQualifier);
-
- policyQualifiers++;
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable
- (qualifiers, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
- }
-
-
- /*
- * Create an OID object pkixOID from policyInfo->policyID.
- * (The CERTPolicyInfo structure has an oid field, but it
- * is of type SECOidTag. This function wants a SECItem.)
- */
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
- (&policyInfo->policyID, &pkixOID, plContext),
- PKIX_OIDCREATEFAILED);
-
- /* Create a CertPolicyInfo object */
- PKIX_CHECK(pkix_pl_CertPolicyInfo_Create
- (pkixOID, qualifiers, &certPolicyInfo, plContext),
- PKIX_CERTPOLICYINFOCREATEFAILED);
-
- /* Append the new CertPolicyInfo object to the list */
- PKIX_CHECK(PKIX_List_AppendItem
- (infos, (PKIX_PL_Object *)certPolicyInfo, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(pkixOID);
- PKIX_DECREF(qualifiers);
- PKIX_DECREF(certPolicyInfo);
-
- policyInfos++;
- }
-
- /*
- * If there were no policies, we went straight to
- * cleanup, so we don't have to NULLCHECK infos.
- */
- PKIX_CHECK(PKIX_List_SetImmutable(infos, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- *pCertPolicyInfos = infos;
- infos = NULL;
-
-cleanup:
- if (certPol) {
- PKIX_CERT_DEBUG
- ("\t\tCalling CERT_DestroyCertificatePoliciesExtension).\n");
- CERT_DestroyCertificatePoliciesExtension(certPol);
- }
-
- PKIX_DECREF(infos);
- PKIX_DECREF(pkixOID);
- PKIX_DECREF(qualifiers);
- PKIX_DECREF(certPolicyInfo);
- PKIX_DECREF(certPolicyQualifier);
- PKIX_DECREF(qualifierArray);
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_DecodePolicyMapping
- * DESCRIPTION:
- *
- * Decodes the contents of the PolicyMapping extension of the CERTCertificate
- * pointed to by "nssCert", storing the resulting List of CertPolicyMaps at
- * the address pointed to by "pCertPolicyMaps". If this certificate does not
- * have a PolicyMapping extension, NULL will be stored. If a List is returned,
- * it will be immutable.
- *
- * PARAMETERS
- * "nssCert"
- * Address of the Cert data whose extension is to be examined. Must be
- * non-NULL.
- * "pCertPolicyMaps"
- * Address where the List of CertPolicyMaps will be stored. Must be
- * non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Cert_DecodePolicyMapping(
- CERTCertificate *nssCert,
- PKIX_List **pCertPolicyMaps,
- void *plContext)
-{
- SECStatus rv;
- SECItem encodedCertPolicyMaps;
-
- /* Allocated in the arena; freed in CERT_Destroy... */
- CERTCertificatePolicyMappings *certPolMaps = NULL;
- CERTPolicyMap **policyMaps = NULL;
-
- /* Holder for the return value */
- PKIX_List *maps = NULL;
-
- PKIX_PL_OID *issuerDomainOID = NULL;
- PKIX_PL_OID *subjectDomainOID = NULL;
- PKIX_PL_CertPolicyMap *certPolicyMap = NULL;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyMapping");
- PKIX_NULLCHECK_TWO(nssCert, pCertPolicyMaps);
-
- /* get PolicyMappings as a SECItem */
- PKIX_CERT_DEBUG("\t\tCERT_FindCertExtension).\n");
- rv = CERT_FindCertExtension
- (nssCert, SEC_OID_X509_POLICY_MAPPINGS, &encodedCertPolicyMaps);
- if (SECSuccess != rv) {
- *pCertPolicyMaps = NULL;
- goto cleanup;
- }
-
- /* translate PolicyMaps to CERTCertificatePolicyMappings */
- certPolMaps = CERT_DecodePolicyMappingsExtension
- (&encodedCertPolicyMaps);
-
- PORT_Free(encodedCertPolicyMaps.data);
-
- if (!certPolMaps) {
- PKIX_ERROR(PKIX_CERTDECODEPOLICYMAPPINGSEXTENSIONFAILED);
- }
-
- PKIX_NULLCHECK_ONE(certPolMaps->policyMaps);
-
- policyMaps = certPolMaps->policyMaps;
-
- /* create a List of CertPolicyMap Objects */
- PKIX_CHECK(PKIX_List_Create(&maps, plContext),
- PKIX_LISTCREATEFAILED);
-
- /*
- * Traverse the CERTCertificatePolicyMappings structure,
- * building each CertPolicyMap object in turn
- */
- do {
- CERTPolicyMap *policyMap = *policyMaps;
-
- /* create the OID for the issuer Domain Policy */
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
- (&policyMap->issuerDomainPolicy,
- &issuerDomainOID, plContext),
- PKIX_OIDCREATEFAILED);
-
- /* create the OID for the subject Domain Policy */
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
- (&policyMap->subjectDomainPolicy,
- &subjectDomainOID, plContext),
- PKIX_OIDCREATEFAILED);
-
- /* create the CertPolicyMap */
-
- PKIX_CHECK(pkix_pl_CertPolicyMap_Create
- (issuerDomainOID,
- subjectDomainOID,
- &certPolicyMap,
- plContext),
- PKIX_CERTPOLICYMAPCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (maps, (PKIX_PL_Object *)certPolicyMap, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(issuerDomainOID);
- PKIX_DECREF(subjectDomainOID);
- PKIX_DECREF(certPolicyMap);
-
- policyMaps++;
- } while (*policyMaps != NULL);
-
- PKIX_CHECK(PKIX_List_SetImmutable(maps, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- *pCertPolicyMaps = maps;
- maps = NULL;
-
-cleanup:
- if (certPolMaps) {
- PKIX_CERT_DEBUG
- ("\t\tCalling CERT_DestroyPolicyMappingsExtension).\n");
- CERT_DestroyPolicyMappingsExtension(certPolMaps);
- }
-
- PKIX_DECREF(maps);
- PKIX_DECREF(issuerDomainOID);
- PKIX_DECREF(subjectDomainOID);
- PKIX_DECREF(certPolicyMap);
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_DecodePolicyConstraints
- * DESCRIPTION:
- *
- * Decodes the contents of the PolicyConstraints extension in the
- * CERTCertificate pointed to by "nssCert", to obtain SkipCerts values
- * which are stored at the addresses "pExplicitPolicySkipCerts" and
- * "pInhibitMappingSkipCerts", respectively. If this certificate does
- * not have an PolicyConstraints extension, or if either of the optional
- * components is not supplied, this function stores a value of -1 for any
- * missing component.
- *
- * PARAMETERS
- * "nssCert"
- * Address of the Cert data whose extension is to be examined. Must be
- * non-NULL.
- * "pExplicitPolicySkipCerts"
- * Address where the SkipCert value for the requireExplicitPolicy
- * component will be stored. Must be non-NULL.
- * "pInhibitMappingSkipCerts"
- * Address where the SkipCert value for the inhibitPolicyMapping
- * component will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Cert_DecodePolicyConstraints(
- CERTCertificate *nssCert,
- PKIX_Int32 *pExplicitPolicySkipCerts,
- PKIX_Int32 *pInhibitMappingSkipCerts,
- void *plContext)
-{
- CERTCertificatePolicyConstraints policyConstraints;
- SECStatus rv;
- SECItem encodedCertPolicyConstraints;
- PKIX_Int32 explicitPolicySkipCerts = -1;
- PKIX_Int32 inhibitMappingSkipCerts = -1;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_DecodePolicyConstraints");
- PKIX_NULLCHECK_THREE
- (nssCert, pExplicitPolicySkipCerts, pInhibitMappingSkipCerts);
-
- /* get the two skipCert values as SECItems */
- PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
- rv = CERT_FindCertExtension
- (nssCert,
- SEC_OID_X509_POLICY_CONSTRAINTS,
- &encodedCertPolicyConstraints);
-
- if (rv == SECSuccess) {
-
- policyConstraints.explicitPolicySkipCerts.data =
- (unsigned char *)&explicitPolicySkipCerts;
- policyConstraints.inhibitMappingSkipCerts.data =
- (unsigned char *)&inhibitMappingSkipCerts;
-
- /* translate DER to CERTCertificatePolicyConstraints */
- rv = CERT_DecodePolicyConstraintsExtension
- (&policyConstraints, &encodedCertPolicyConstraints);
-
- PORT_Free(encodedCertPolicyConstraints.data);
-
- if (rv != SECSuccess) {
- PKIX_ERROR
- (PKIX_CERTDECODEPOLICYCONSTRAINTSEXTENSIONFAILED);
- }
- }
-
- *pExplicitPolicySkipCerts = explicitPolicySkipCerts;
- *pInhibitMappingSkipCerts = inhibitMappingSkipCerts;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_DecodeInhibitAnyPolicy
- * DESCRIPTION:
- *
- * Decodes the contents of the InhibitAnyPolicy extension in the
- * CERTCertificate pointed to by "nssCert", to obtain a SkipCerts value,
- * which is stored at the address "pSkipCerts". If this certificate does
- * not have an InhibitAnyPolicy extension, -1 will be stored.
- *
- * PARAMETERS
- * "nssCert"
- * Address of the Cert data whose InhibitAnyPolicy extension is to be
- * processed. Must be non-NULL.
- * "pSkipCerts"
- * Address where the SkipCert value from the InhibitAnyPolicy extension
- * will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Cert_DecodeInhibitAnyPolicy(
- CERTCertificate *nssCert,
- PKIX_Int32 *pSkipCerts,
- void *plContext)
-{
- CERTCertificateInhibitAny inhibitAny;
- SECStatus rv;
- SECItem encodedCertInhibitAny;
- PKIX_Int32 skipCerts = -1;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_DecodeInhibitAnyPolicy");
- PKIX_NULLCHECK_TWO(nssCert, pSkipCerts);
-
- /* get InhibitAny as a SECItem */
- PKIX_CERT_DEBUG("\t\tCalling CERT_FindCertExtension).\n");
- rv = CERT_FindCertExtension
- (nssCert, SEC_OID_X509_INHIBIT_ANY_POLICY, &encodedCertInhibitAny);
-
- if (rv == SECSuccess) {
- inhibitAny.inhibitAnySkipCerts.data =
- (unsigned char *)&skipCerts;
-
- /* translate DER to CERTCertificateInhibitAny */
- rv = CERT_DecodeInhibitAnyExtension
- (&inhibitAny, &encodedCertInhibitAny);
-
- PORT_Free(encodedCertInhibitAny.data);
-
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_CERTDECODEINHIBITANYEXTENSIONFAILED);
- }
- }
-
- *pSkipCerts = skipCerts;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_GetNssSubjectAltNames
- * DESCRIPTION:
- *
- * Retrieves the Subject Alternative Names of the certificate specified by
- * "cert" and stores it at "pNssSubjAltNames". If the Subject Alternative
- * Name extension is not present, NULL is returned at "pNssSubjAltNames".
- * If the Subject Alternative Names has not been previously decoded, it is
- * decoded here with lock on the "cert" unless the flag "hasLock" indicates
- * the lock had been obtained at a higher call level.
- *
- * PARAMETERS
- * "cert"
- * Address of the certificate whose Subject Alternative Names extensions
- * is retrieved. Must be non-NULL.
- * "hasLock"
- * Boolean indicates caller has acquired a lock.
- * Must be non-NULL.
- * "pNssSubjAltNames"
- * Address where the returned Subject Alternative Names will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Cert_GetNssSubjectAltNames(
- PKIX_PL_Cert *cert,
- PKIX_Boolean hasLock,
- CERTGeneralName **pNssSubjAltNames,
- void *plContext)
-{
- CERTCertificate *nssCert = NULL;
- CERTGeneralName *nssOriginalAltName = NULL;
- PLArenaPool *arena = NULL;
- SECItem altNameExtension = {siBuffer, NULL, 0};
- SECStatus rv = SECFailure;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_GetNssSubjectAltNames");
- PKIX_NULLCHECK_THREE(cert, pNssSubjAltNames, cert->nssCert);
-
- nssCert = cert->nssCert;
-
- if ((cert->nssSubjAltNames == NULL) && (!cert->subjAltNamesAbsent)){
-
- if (!hasLock) {
- PKIX_OBJECT_LOCK(cert);
- }
-
- if ((cert->nssSubjAltNames == NULL) &&
- (!cert->subjAltNamesAbsent)){
-
- PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension,
- (nssCert,
- SEC_OID_X509_SUBJECT_ALT_NAME,
- &altNameExtension));
-
- if (rv != SECSuccess) {
- *pNssSubjAltNames = NULL;
- cert->subjAltNamesAbsent = PKIX_TRUE;
- goto cleanup;
- }
-
- if (cert->arenaNameConstraints == NULL) {
- PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena,
- (DER_DEFAULT_CHUNKSIZE));
-
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
- cert->arenaNameConstraints = arena;
- }
-
- PKIX_PL_NSSCALLRV
- (CERT,
- nssOriginalAltName,
- (CERTGeneralName *) CERT_DecodeAltNameExtension,
- (cert->arenaNameConstraints, &altNameExtension));
-
- PKIX_PL_NSSCALL(CERT, PORT_Free, (altNameExtension.data));
-
- if (nssOriginalAltName == NULL) {
- PKIX_ERROR(PKIX_CERTDECODEALTNAMEEXTENSIONFAILED);
- }
- cert->nssSubjAltNames = nssOriginalAltName;
-
- }
-
- if (!hasLock) {
- PKIX_OBJECT_UNLOCK(cert);
- }
- }
-
- *pNssSubjAltNames = cert->nssSubjAltNames;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_CheckExtendKeyUsage
- * DESCRIPTION:
- *
- * For each of the ON bit in "requiredExtendedKeyUsages" that represents its
- * SECCertUsageEnum type, this function checks "cert"'s certType (extended
- * key usage) and key usage with what is required for SECCertUsageEnum type.
- *
- * PARAMETERS
- * "cert"
- * Address of the certificate whose Extended Key Usage extensions
- * is retrieved. Must be non-NULL.
- * "requiredExtendedKeyUsages"
- * An unsigned integer, its bit location is ON based on the required key
- * usage value representing in SECCertUsageEnum.
- * "pPass"
- * Address where the return value, indicating key usage check passed, is
- * stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Cert_CheckExtendedKeyUsage(
- PKIX_PL_Cert *cert,
- PKIX_UInt32 requiredExtendedKeyUsages,
- PKIX_Boolean *pPass,
- void *plContext)
-{
- PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
- PKIX_UInt32 certType = 0;
- PKIX_UInt32 requiredKeyUsage = 0;
- PKIX_UInt32 requiredCertType = 0;
- PKIX_UInt32 requiredExtendedKeyUsage = 0;
- PKIX_UInt32 i;
- PKIX_Boolean isCA = PKIX_FALSE;
- SECStatus rv = SECFailure;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_CheckExtendKeyUsage");
- PKIX_NULLCHECK_THREE(cert, pPass, cert->nssCert);
-
- *pPass = PKIX_FALSE;
-
- PKIX_CERT_DEBUG("\t\tCalling cert_GetCertType).\n");
- cert_GetCertType(cert->nssCert);
- certType = cert->nssCert->nsCertType;
-
- PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
- (cert,
- &basicConstraints,
- plContext),
- PKIX_CERTGETBASICCONSTRAINTFAILED);
-
- if (basicConstraints != NULL) {
- PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
- (basicConstraints, &isCA, plContext),
- PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
- }
-
- i = 0;
- while (requiredExtendedKeyUsages != 0) {
-
- /* Find the bit location of the right-most non-zero bit */
- while (requiredExtendedKeyUsages != 0) {
- if (((1 << i) & requiredExtendedKeyUsages) != 0) {
- requiredExtendedKeyUsage = 1 << i;
- break;
- }
- i++;
- }
- requiredExtendedKeyUsages ^= requiredExtendedKeyUsage;
-
- requiredExtendedKeyUsage = i;
-
- PKIX_PL_NSSCALLRV(CERT, rv, CERT_KeyUsageAndTypeForCertUsage,
- (requiredExtendedKeyUsage,
- isCA,
- &requiredKeyUsage,
- &requiredCertType));
-
- if (!(certType & requiredCertType)) {
- goto cleanup;
- }
-
- PKIX_PL_NSSCALLRV(CERT, rv, CERT_CheckKeyUsage,
- (cert->nssCert, requiredKeyUsage));
- if (rv != SECSuccess) {
- goto cleanup;
- }
- i++;
-
- }
-
- *pPass = PKIX_TRUE;
-
-cleanup:
- PKIX_DECREF(basicConstraints);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_ToString_Helper
- * DESCRIPTION:
- *
- * Helper function that creates a string representation of the Cert pointed
- * to by "cert" and stores it at "pString", where the value of
- * "partialString" determines whether a full or partial representation of
- * the Cert is stored.
- *
- * PARAMETERS
- * "cert"
- * Address of Cert whose string representation is desired.
- * Must be non-NULL.
- * "partialString"
- * Boolean indicating whether a partial Cert representation is desired.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Cert_ToString_Helper(
- PKIX_PL_Cert *cert,
- PKIX_Boolean partialString,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *certString = NULL;
- char *asciiFormat = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_UInt32 certVersion;
- PKIX_PL_BigInt *certSN = NULL;
- PKIX_PL_String *certSNString = NULL;
- PKIX_PL_X500Name *certIssuer = NULL;
- PKIX_PL_String *certIssuerString = NULL;
- PKIX_PL_X500Name *certSubject = NULL;
- PKIX_PL_String *certSubjectString = NULL;
- PKIX_PL_String *notBeforeString = NULL;
- PKIX_PL_String *notAfterString = NULL;
- PKIX_List *subjAltNames = NULL;
- PKIX_PL_String *subjAltNamesString = NULL;
- PKIX_PL_ByteArray *authKeyId = NULL;
- PKIX_PL_String *authKeyIdString = NULL;
- PKIX_PL_ByteArray *subjKeyId = NULL;
- PKIX_PL_String *subjKeyIdString = NULL;
- PKIX_PL_PublicKey *nssPubKey = NULL;
- PKIX_PL_String *nssPubKeyString = NULL;
- PKIX_List *critExtOIDs = NULL;
- PKIX_PL_String *critExtOIDsString = NULL;
- PKIX_List *extKeyUsages = NULL;
- PKIX_PL_String *extKeyUsagesString = NULL;
- PKIX_PL_CertBasicConstraints *basicConstraint = NULL;
- PKIX_PL_String *certBasicConstraintsString = NULL;
- PKIX_List *policyInfo = NULL;
- PKIX_PL_String *certPolicyInfoString = NULL;
- PKIX_List *certPolicyMappings = NULL;
- PKIX_PL_String *certPolicyMappingsString = NULL;
- PKIX_Int32 certExplicitPolicy = 0;
- PKIX_Int32 certInhibitMapping = 0;
- PKIX_Int32 certInhibitAnyPolicy = 0;
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
- PKIX_PL_String *nameConstraintsString = NULL;
- PKIX_List *authorityInfoAccess = NULL;
- PKIX_PL_String *authorityInfoAccessString = NULL;
- PKIX_List *subjectInfoAccess = NULL;
- PKIX_PL_String *subjectInfoAccessString = NULL;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_ToString_Helper");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pString);
-
- /*
- * XXX Add to this format as certificate components are developed.
- */
-
- if (partialString){
- asciiFormat =
- "\t[Issuer: %s\n"
- "\t Subject: %s]";
- } else {
- asciiFormat =
- "[\n"
- "\tVersion: v%d\n"
- "\tSerialNumber: %s\n"
- "\tIssuer: %s\n"
- "\tSubject: %s\n"
- "\tValidity: [From: %s\n"
- "\t To: %s]\n"
- "\tSubjectAltNames: %s\n"
- "\tAuthorityKeyId: %s\n"
- "\tSubjectKeyId: %s\n"
- "\tSubjPubKeyAlgId: %s\n"
- "\tCritExtOIDs: %s\n"
- "\tExtKeyUsages: %s\n"
- "\tBasicConstraint: %s\n"
- "\tCertPolicyInfo: %s\n"
- "\tPolicyMappings: %s\n"
- "\tExplicitPolicy: %d\n"
- "\tInhibitMapping: %d\n"
- "\tInhibitAnyPolicy:%d\n"
- "\tNameConstraints: %s\n"
- "\tAuthorityInfoAccess: %s\n"
- "\tSubjectInfoAccess: %s\n"
- "\tCacheFlag: %d\n"
- "]\n";
- }
-
-
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- /* Issuer */
- PKIX_CHECK(PKIX_PL_Cert_GetIssuer
- (cert, &certIssuer, plContext),
- PKIX_CERTGETISSUERFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)certIssuer, &certIssuerString, plContext),
- PKIX_X500NAMETOSTRINGFAILED);
-
- /* Subject */
- PKIX_CHECK(PKIX_PL_Cert_GetSubject(cert, &certSubject, plContext),
- PKIX_CERTGETSUBJECTFAILED);
-
- PKIX_TOSTRING(certSubject, &certSubjectString, plContext,
- PKIX_X500NAMETOSTRINGFAILED);
-
- if (partialString){
- PKIX_CHECK(PKIX_PL_Sprintf
- (&certString,
- plContext,
- formatString,
- certIssuerString,
- certSubjectString),
- PKIX_SPRINTFFAILED);
-
- *pString = certString;
- goto cleanup;
- }
-
- /* Version */
- PKIX_CHECK(PKIX_PL_Cert_GetVersion(cert, &certVersion, plContext),
- PKIX_CERTGETVERSIONFAILED);
-
- /* SerialNumber */
- PKIX_CHECK(PKIX_PL_Cert_GetSerialNumber(cert, &certSN, plContext),
- PKIX_CERTGETSERIALNUMBERFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)certSN, &certSNString, plContext),
- PKIX_BIGINTTOSTRINGFAILED);
-
- /* Validity: NotBefore */
- PKIX_CHECK(pkix_pl_Date_ToString_Helper
- (&(cert->nssCert->validity.notBefore),
- &notBeforeString,
- plContext),
- PKIX_DATETOSTRINGHELPERFAILED);
-
- /* Validity: NotAfter */
- PKIX_CHECK(pkix_pl_Date_ToString_Helper
- (&(cert->nssCert->validity.notAfter),
- &notAfterString,
- plContext),
- PKIX_DATETOSTRINGHELPERFAILED);
-
- /* SubjectAltNames */
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames
- (cert, &subjAltNames, plContext),
- PKIX_CERTGETSUBJECTALTNAMESFAILED);
-
- PKIX_TOSTRING(subjAltNames, &subjAltNamesString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- /* AuthorityKeyIdentifier */
- PKIX_CHECK(PKIX_PL_Cert_GetAuthorityKeyIdentifier
- (cert, &authKeyId, plContext),
- PKIX_CERTGETAUTHORITYKEYIDENTIFIERFAILED);
-
- PKIX_TOSTRING(authKeyId, &authKeyIdString, plContext,
- PKIX_BYTEARRAYTOSTRINGFAILED);
-
- /* SubjectKeyIdentifier */
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectKeyIdentifier
- (cert, &subjKeyId, plContext),
- PKIX_CERTGETSUBJECTKEYIDENTIFIERFAILED);
-
- PKIX_TOSTRING(subjKeyId, &subjKeyIdString, plContext,
- PKIX_BYTEARRAYTOSTRINGFAILED);
-
- /* SubjectPublicKey */
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
- (cert, &nssPubKey, plContext),
- PKIX_CERTGETSUBJECTPUBLICKEYFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)nssPubKey, &nssPubKeyString, plContext),
- PKIX_PUBLICKEYTOSTRINGFAILED);
-
- /* CriticalExtensionOIDs */
- PKIX_CHECK(PKIX_PL_Cert_GetCriticalExtensionOIDs
- (cert, &critExtOIDs, plContext),
- PKIX_CERTGETCRITICALEXTENSIONOIDSFAILED);
-
- PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- /* ExtendedKeyUsages */
- PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage
- (cert, &extKeyUsages, plContext),
- PKIX_CERTGETEXTENDEDKEYUSAGEFAILED);
-
- PKIX_TOSTRING(extKeyUsages, &extKeyUsagesString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- /* CertBasicConstraints */
- PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
- (cert, &basicConstraint, plContext),
- PKIX_CERTGETBASICCONSTRAINTSFAILED);
-
- PKIX_TOSTRING(basicConstraint, &certBasicConstraintsString, plContext,
- PKIX_CERTBASICCONSTRAINTSTOSTRINGFAILED);
-
- /* CertPolicyInfo */
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyInformation
- (cert, &policyInfo, plContext),
- PKIX_CERTGETPOLICYINFORMATIONFAILED);
-
- PKIX_TOSTRING(policyInfo, &certPolicyInfoString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- /* Advanced Policies */
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappings
- (cert, &certPolicyMappings, plContext),
- PKIX_CERTGETPOLICYMAPPINGSFAILED);
-
- PKIX_TOSTRING(certPolicyMappings, &certPolicyMappingsString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetRequireExplicitPolicy
- (cert, &certExplicitPolicy, plContext),
- PKIX_CERTGETREQUIREEXPLICITPOLICYFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetPolicyMappingInhibited
- (cert, &certInhibitMapping, plContext),
- PKIX_CERTGETPOLICYMAPPINGINHIBITEDFAILED);
-
- PKIX_CHECK(PKIX_PL_Cert_GetInhibitAnyPolicy
- (cert, &certInhibitAnyPolicy, plContext),
- PKIX_CERTGETINHIBITANYPOLICYFAILED);
-
- /* Name Constraints */
- PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
- (cert, &nameConstraints, plContext),
- PKIX_CERTGETNAMECONSTRAINTSFAILED);
-
- PKIX_TOSTRING(nameConstraints, &nameConstraintsString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- /* Authority Information Access */
- PKIX_CHECK(PKIX_PL_Cert_GetAuthorityInfoAccess
- (cert, &authorityInfoAccess, plContext),
- PKIX_CERTGETAUTHORITYINFOACCESSFAILED);
-
- PKIX_TOSTRING(authorityInfoAccess, &authorityInfoAccessString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- /* Subject Information Access */
- PKIX_CHECK(PKIX_PL_Cert_GetSubjectInfoAccess
- (cert, &subjectInfoAccess, plContext),
- PKIX_CERTGETSUBJECTINFOACCESSFAILED);
-
- PKIX_TOSTRING(subjectInfoAccess, &subjectInfoAccessString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&certString,
- plContext,
- formatString,
- certVersion + 1,
- certSNString,
- certIssuerString,
- certSubjectString,
- notBeforeString,
- notAfterString,
- subjAltNamesString,
- authKeyIdString,
- subjKeyIdString,
- nssPubKeyString,
- critExtOIDsString,
- extKeyUsagesString,
- certBasicConstraintsString,
- certPolicyInfoString,
- certPolicyMappingsString,
- certExplicitPolicy, /* an Int32, not a String */
- certInhibitMapping, /* an Int32, not a String */
- certInhibitAnyPolicy, /* an Int32, not a String */
- nameConstraintsString,
- authorityInfoAccessString,
- subjectInfoAccessString,
- cert->cacheFlag), /* a boolean */
- PKIX_SPRINTFFAILED);
-
- *pString = certString;
-
-cleanup:
- PKIX_DECREF(certSN);
- PKIX_DECREF(certSNString);
- PKIX_DECREF(certIssuer);
- PKIX_DECREF(certIssuerString);
- PKIX_DECREF(certSubject);
- PKIX_DECREF(certSubjectString);
- PKIX_DECREF(notBeforeString);
- PKIX_DECREF(notAfterString);
- PKIX_DECREF(subjAltNames);
- PKIX_DECREF(subjAltNamesString);
- PKIX_DECREF(authKeyId);
- PKIX_DECREF(authKeyIdString);
- PKIX_DECREF(subjKeyId);
- PKIX_DECREF(subjKeyIdString);
- PKIX_DECREF(nssPubKey);
- PKIX_DECREF(nssPubKeyString);
- PKIX_DECREF(critExtOIDs);
- PKIX_DECREF(critExtOIDsString);
- PKIX_DECREF(extKeyUsages);
- PKIX_DECREF(extKeyUsagesString);
- PKIX_DECREF(basicConstraint);
- PKIX_DECREF(certBasicConstraintsString);
- PKIX_DECREF(policyInfo);
- PKIX_DECREF(certPolicyInfoString);
- PKIX_DECREF(certPolicyMappings);
- PKIX_DECREF(certPolicyMappingsString);
- PKIX_DECREF(nameConstraints);
- PKIX_DECREF(nameConstraintsString);
- PKIX_DECREF(authorityInfoAccess);
- PKIX_DECREF(authorityInfoAccessString);
- PKIX_DECREF(subjectInfoAccess);
- PKIX_DECREF(subjectInfoAccessString);
- PKIX_DECREF(formatString);
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Cert_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_Cert *cert = NULL;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
- PKIX_OBJECTNOTCERT);
-
- cert = (PKIX_PL_Cert*)object;
-
- PKIX_DECREF(cert->subject);
- PKIX_DECREF(cert->issuer);
- PKIX_DECREF(cert->subjAltNames);
- PKIX_DECREF(cert->publicKeyAlgId);
- PKIX_DECREF(cert->publicKey);
- PKIX_DECREF(cert->serialNumber);
- PKIX_DECREF(cert->critExtOids);
- PKIX_DECREF(cert->authKeyId);
- PKIX_DECREF(cert->subjKeyId);
- PKIX_DECREF(cert->extKeyUsages);
- PKIX_DECREF(cert->certBasicConstraints);
- PKIX_DECREF(cert->certPolicyInfos);
- PKIX_DECREF(cert->certPolicyMappings);
- PKIX_DECREF(cert->nameConstraints);
- PKIX_DECREF(cert->store);
- PKIX_DECREF(cert->authorityInfoAccess);
- PKIX_DECREF(cert->subjectInfoAccess);
- PKIX_DECREF(cert->crldpList);
-
- if (cert->arenaNameConstraints){
- /* This arena was allocated for SubjectAltNames */
- PKIX_PL_NSSCALL(CERT, PORT_FreeArena,
- (cert->arenaNameConstraints, PR_FALSE));
-
- cert->arenaNameConstraints = NULL;
- cert->nssSubjAltNames = NULL;
- }
-
- CERT_DestroyCertificate(cert->nssCert);
- cert->nssCert = NULL;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Cert_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *certString = NULL;
- PKIX_PL_Cert *pkixCert = NULL;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_toString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
- PKIX_OBJECTNOTCERT);
-
- pkixCert = (PKIX_PL_Cert *)object;
-
- PKIX_CHECK(pkix_pl_Cert_ToString_Helper
- (pkixCert, PKIX_FALSE, &certString, plContext),
- PKIX_CERTTOSTRINGHELPERFAILED);
-
- *pString = certString;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Cert_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_Cert *pkixCert = NULL;
- CERTCertificate *nssCert = NULL;
- unsigned char *derBytes = NULL;
- PKIX_UInt32 derLength;
- PKIX_UInt32 certHash;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERT_TYPE, plContext),
- PKIX_OBJECTNOTCERT);
-
- pkixCert = (PKIX_PL_Cert *)object;
-
- nssCert = pkixCert->nssCert;
- derBytes = (nssCert->derCert).data;
- derLength = (nssCert->derCert).len;
-
- PKIX_CHECK(pkix_hash(derBytes, derLength, &certHash, plContext),
- PKIX_HASHFAILED);
-
- *pHashcode = certHash;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-
-/*
- * FUNCTION: pkix_pl_Cert_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Cert_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- CERTCertificate *firstCert = NULL;
- CERTCertificate *secondCert = NULL;
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a Cert */
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CERT_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCERT);
-
- /*
- * Since we know firstObject is a Cert, if both references are
- * identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a Cert, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_CERT_TYPE) goto cleanup;
-
- firstCert = ((PKIX_PL_Cert *)firstObject)->nssCert;
- secondCert = ((PKIX_PL_Cert *)secondObject)->nssCert;
-
- PKIX_NULLCHECK_TWO(firstCert, secondCert);
-
- /* CERT_CompareCerts does byte comparison on DER encodings of certs */
- PKIX_CERT_DEBUG("\t\tCalling CERT_CompareCerts).\n");
- cmpResult = CERT_CompareCerts(firstCert, secondCert);
-
- *pResult = cmpResult;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_Cert_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_RegisterSelf");
-
- entry.description = "Cert";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_Cert);
- entry.destructor = pkix_pl_Cert_Destroy;
- entry.equalsFunction = pkix_pl_Cert_Equals;
- entry.hashcodeFunction = pkix_pl_Cert_Hashcode;
- entry.toStringFunction = pkix_pl_Cert_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_CERT_TYPE] = entry;
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_CreateWithNSSCert
- * DESCRIPTION:
- *
- * Creates a new certificate using the CERTCertificate pointed to by "nssCert"
- * and stores it at "pCert". Once created, a Cert is immutable.
- *
- * This function is primarily used as a convenience function for the
- * performance tests that have easy access to a CERTCertificate.
- *
- * PARAMETERS:
- * "nssCert"
- * Address of CERTCertificate representing the NSS certificate.
- * Must be non-NULL.
- * "pCert"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Cert_CreateWithNSSCert(
- CERTCertificate *nssCert,
- PKIX_PL_Cert **pCert,
- void *plContext)
-{
- PKIX_PL_Cert *cert = NULL;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_CreateWithNSSCert");
- PKIX_NULLCHECK_TWO(pCert, nssCert);
-
- /* create a PKIX_PL_Cert object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERT_TYPE,
- sizeof (PKIX_PL_Cert),
- (PKIX_PL_Object **)&cert,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- /* populate the nssCert field */
- cert->nssCert = nssCert;
-
- /* initialize remaining fields */
- /*
- * Fields ending with Absent are initialized to PKIX_FALSE so that the
- * first time we need the value we will look for it. If we find it is
- * actually absent, the flag will at that time be set to PKIX_TRUE to
- * prevent searching for it later.
- * Fields ending with Processed are those where a value is defined
- * for the Absent case, and a value of zero is possible. When the
- * flag is still true we have to look for the field, set the default
- * value if necessary, and set the Processed flag to PKIX_TRUE.
- */
- cert->subject = NULL;
- cert->issuer = NULL;
- cert->subjAltNames = NULL;
- cert->subjAltNamesAbsent = PKIX_FALSE;
- cert->publicKeyAlgId = NULL;
- cert->publicKey = NULL;
- cert->serialNumber = NULL;
- cert->critExtOids = NULL;
- cert->subjKeyId = NULL;
- cert->subjKeyIdAbsent = PKIX_FALSE;
- cert->authKeyId = NULL;
- cert->authKeyIdAbsent = PKIX_FALSE;
- cert->extKeyUsages = NULL;
- cert->extKeyUsagesAbsent = PKIX_FALSE;
- cert->certBasicConstraints = NULL;
- cert->basicConstraintsAbsent = PKIX_FALSE;
- cert->certPolicyInfos = NULL;
- cert->policyInfoAbsent = PKIX_FALSE;
- cert->policyMappingsAbsent = PKIX_FALSE;
- cert->certPolicyMappings = NULL;
- cert->policyConstraintsProcessed = PKIX_FALSE;
- cert->policyConstraintsExplicitPolicySkipCerts = 0;
- cert->policyConstraintsInhibitMappingSkipCerts = 0;
- cert->inhibitAnyPolicyProcessed = PKIX_FALSE;
- cert->inhibitAnySkipCerts = 0;
- cert->nameConstraints = NULL;
- cert->nameConstraintsAbsent = PKIX_FALSE;
- cert->arenaNameConstraints = NULL;
- cert->nssSubjAltNames = NULL;
- cert->cacheFlag = PKIX_FALSE;
- cert->store = NULL;
- cert->authorityInfoAccess = NULL;
- cert->subjectInfoAccess = NULL;
- cert->isUserTrustAnchor = PKIX_FALSE;
- cert->crldpList = NULL;
-
- *pCert = cert;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: pkix_pl_Cert_CreateToList
- * DESCRIPTION:
- *
- * Creates a new certificate using the DER-encoding pointed to by "derCertItem"
- * and appends it to the list pointed to by "certList". If Cert creation fails,
- * the function returns with certList unchanged, but any decoding Error is
- * discarded.
- *
- * PARAMETERS:
- * "derCertItem"
- * Address of SECItem containing the DER representation of a certificate.
- * Must be non-NULL.
- * "certList"
- * Address of List to which the Cert will be appended, if successfully
- * created. May be empty, but must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Cert_CreateToList(
- SECItem *derCertItem,
- PKIX_List *certList,
- void *plContext)
-{
- CERTCertificate *nssCert = NULL;
- PKIX_PL_Cert *cert = NULL;
- CERTCertDBHandle *handle;
-
- PKIX_ENTER(CERT, "pkix_pl_Cert_CreateToList");
- PKIX_NULLCHECK_TWO(derCertItem, certList);
-
- handle = CERT_GetDefaultCertDB();
- nssCert = CERT_NewTempCertificate(handle, derCertItem,
- /* nickname */ NULL,
- /* isPerm */ PR_FALSE,
- /* copyDer */ PR_TRUE);
- if (!nssCert) {
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
- (nssCert, &cert, plContext),
- PKIX_CERTCREATEWITHNSSCERTFAILED);
-
- nssCert = NULL;
-
- PKIX_CHECK(PKIX_List_AppendItem
- (certList, (PKIX_PL_Object *) cert, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
-cleanup:
- if (nssCert) {
- CERT_DestroyCertificate(nssCert);
- }
-
- PKIX_DECREF(cert);
- PKIX_RETURN(CERT);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_Cert_Create (see comments in pkix_pl_pki.h)
- * XXX We may want to cache the cert after parsing it, so it can be reused
- * XXX Are the NSS/NSPR functions thread safe
- */
-PKIX_Error *
-PKIX_PL_Cert_Create(
- PKIX_PL_ByteArray *byteArray,
- PKIX_PL_Cert **pCert,
- void *plContext)
-{
- CERTCertificate *nssCert = NULL;
- SECItem *derCertItem = NULL;
- void *derBytes = NULL;
- PKIX_UInt32 derLength;
- PKIX_Boolean copyDER;
- PKIX_PL_Cert *cert = NULL;
- CERTCertDBHandle *handle;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_Create");
- PKIX_NULLCHECK_TWO(pCert, byteArray);
-
- PKIX_CHECK(PKIX_PL_ByteArray_GetPointer
- (byteArray, &derBytes, plContext),
- PKIX_BYTEARRAYGETPOINTERFAILED);
-
- PKIX_CHECK(PKIX_PL_ByteArray_GetLength
- (byteArray, &derLength, plContext),
- PKIX_BYTEARRAYGETLENGTHFAILED);
-
- derCertItem = SECITEM_AllocItem(NULL, NULL, derLength);
- if (derCertItem == NULL){
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- (void) PORT_Memcpy(derCertItem->data, derBytes, derLength);
-
- /*
- * setting copyDER to true forces NSS to make its own copy of the DER,
- * allowing us to free our copy without worrying about whether NSS
- * is still using it
- */
- copyDER = PKIX_TRUE;
- handle = CERT_GetDefaultCertDB();
- nssCert = CERT_NewTempCertificate(handle, derCertItem,
- /* nickname */ NULL,
- /* isPerm */ PR_FALSE,
- /* copyDer */ PR_TRUE);
- if (!nssCert){
- PKIX_ERROR(PKIX_CERTDECODEDERCERTIFICATEFAILED);
- }
-
- PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
- (nssCert, &cert, plContext),
- PKIX_CERTCREATEWITHNSSCERTFAILED);
-
- *pCert = cert;
-
-cleanup:
- if (derCertItem){
- SECITEM_FreeItem(derCertItem, PKIX_TRUE);
- }
-
- if (nssCert && PKIX_ERROR_RECEIVED){
- PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n");
- CERT_DestroyCertificate(nssCert);
- nssCert = NULL;
- }
-
- PKIX_FREE(derBytes);
- PKIX_RETURN(CERT);
-}
-
-
-/*
- * FUNCTION: PKIX_PL_Cert_CreateFromCERTCertificate
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_CreateFromCERTCertificate(
- const CERTCertificate *nssCert,
- PKIX_PL_Cert **pCert,
- void *plContext)
-{
- void *buf = NULL;
- PKIX_UInt32 len;
- PKIX_PL_ByteArray *byteArray = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_CreateWithNssCert");
- PKIX_NULLCHECK_TWO(pCert, nssCert);
-
- buf = (void*)nssCert->derCert.data;
- len = nssCert->derCert.len;
-
- PKIX_CHECK(
- PKIX_PL_ByteArray_Create(buf, len, &byteArray, plContext),
- PKIX_BYTEARRAYCREATEFAILED);
-
- PKIX_CHECK(
- PKIX_PL_Cert_Create(byteArray, pCert, plContext),
- PKIX_CERTCREATEWITHNSSCERTFAILED);
-
-#ifdef PKIX_UNDEF
- /* will be tested and used as a patch for bug 391612 */
- nssCert = CERT_DupCertificate(nssInCert);
-
- PKIX_CHECK(pkix_pl_Cert_CreateWithNSSCert
- (nssCert, &cert, plContext),
- PKIX_CERTCREATEWITHNSSCERTFAILED);
-#endif /* PKIX_UNDEF */
-
-cleanup:
-
-#ifdef PKIX_UNDEF
- if (nssCert && PKIX_ERROR_RECEIVED){
- PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyCertificate).\n");
- CERT_DestroyCertificate(nssCert);
- nssCert = NULL;
- }
-#endif /* PKIX_UNDEF */
-
- PKIX_DECREF(byteArray);
- PKIX_RETURN(CERT);
-}
-
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetVersion (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetVersion(
- PKIX_PL_Cert *cert,
- PKIX_UInt32 *pVersion,
- void *plContext)
-{
- CERTCertificate *nssCert = NULL;
- PKIX_UInt32 myVersion = 0; /* v1 */
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetVersion");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pVersion);
-
- nssCert = cert->nssCert;
- if (nssCert->version.len != 0) {
- myVersion = *(nssCert->version.data);
- }
-
- if (myVersion > 2){
- PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1V2ORV3);
- }
-
- *pVersion = myVersion;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSerialNumber (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSerialNumber(
- PKIX_PL_Cert *cert,
- PKIX_PL_BigInt **pSerialNumber,
- void *plContext)
-{
- CERTCertificate *nssCert = NULL;
- SECItem serialNumItem;
- PKIX_PL_BigInt *serialNumber = NULL;
- char *bytes = NULL;
- PKIX_UInt32 length;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSerialNumber");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSerialNumber);
-
- if (cert->serialNumber == NULL){
-
- PKIX_OBJECT_LOCK(cert);
-
- if (cert->serialNumber == NULL){
-
- nssCert = cert->nssCert;
- serialNumItem = nssCert->serialNumber;
-
- length = serialNumItem.len;
- bytes = (char *)serialNumItem.data;
-
- PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
- (bytes, length, &serialNumber, plContext),
- PKIX_BIGINTCREATEWITHBYTESFAILED);
-
- /* save a cached copy in case it is asked for again */
- cert->serialNumber = serialNumber;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->serialNumber);
- *pSerialNumber = cert->serialNumber;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubject (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubject(
- PKIX_PL_Cert *cert,
- PKIX_PL_X500Name **pCertSubject,
- void *plContext)
-{
- PKIX_PL_X500Name *pkixSubject = NULL;
- CERTName *subjName = NULL;
- SECItem *derSubjName = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubject");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertSubject);
-
- /* if we don't have a cached copy from before, we create one */
- if (cert->subject == NULL){
-
- PKIX_OBJECT_LOCK(cert);
-
- if (cert->subject == NULL){
-
- subjName = &cert->nssCert->subject;
- derSubjName = &cert->nssCert->derSubject;
-
- /* if there is no subject name */
- if (derSubjName->data == NULL) {
-
- pkixSubject = NULL;
-
- } else {
- PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName
- (derSubjName, subjName, &pkixSubject,
- plContext),
- PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
-
- }
- /* save a cached copy in case it is asked for again */
- cert->subject = pkixSubject;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->subject);
- *pCertSubject = cert->subject;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetIssuer (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetIssuer(
- PKIX_PL_Cert *cert,
- PKIX_PL_X500Name **pCertIssuer,
- void *plContext)
-{
- PKIX_PL_X500Name *pkixIssuer = NULL;
- SECItem *derIssuerName = NULL;
- CERTName *issuerName = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetIssuer");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pCertIssuer);
-
- /* if we don't have a cached copy from before, we create one */
- if (cert->issuer == NULL){
-
- PKIX_OBJECT_LOCK(cert);
-
- if (cert->issuer == NULL){
-
- issuerName = &cert->nssCert->issuer;
- derIssuerName = &cert->nssCert->derIssuer;
-
- /* if there is no subject name */
- PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName
- (derIssuerName, issuerName,
- &pkixIssuer, plContext),
- PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
-
- /* save a cached copy in case it is asked for again */
- cert->issuer = pkixIssuer;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->issuer);
- *pCertIssuer = cert->issuer;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectAltNames (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectAltNames(
- PKIX_PL_Cert *cert,
- PKIX_List **pSubjectAltNames, /* list of PKIX_PL_GeneralName */
- void *plContext)
-{
- PKIX_PL_GeneralName *pkixAltName = NULL;
- PKIX_List *altNamesList = NULL;
-
- CERTGeneralName *nssOriginalAltName = NULL;
- CERTGeneralName *nssTempAltName = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectAltNames");
- PKIX_NULLCHECK_TWO(cert, pSubjectAltNames);
-
- /* if we don't have a cached copy from before, we create one */
- if ((cert->subjAltNames == NULL) && (!cert->subjAltNamesAbsent)){
-
- PKIX_OBJECT_LOCK(cert);
-
- if ((cert->subjAltNames == NULL) &&
- (!cert->subjAltNamesAbsent)){
-
- PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
- (cert,
- PKIX_TRUE,
- &nssOriginalAltName,
- plContext),
- PKIX_CERTGETNSSSUBJECTALTNAMESFAILED);
-
- if (nssOriginalAltName == NULL) {
- cert->subjAltNamesAbsent = PKIX_TRUE;
- pSubjectAltNames = NULL;
- goto cleanup;
- }
-
- nssTempAltName = nssOriginalAltName;
-
- PKIX_CHECK(PKIX_List_Create(&altNamesList, plContext),
- PKIX_LISTCREATEFAILED);
-
- do {
- PKIX_CHECK(pkix_pl_GeneralName_Create
- (nssTempAltName, &pkixAltName, plContext),
- PKIX_GENERALNAMECREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (altNamesList,
- (PKIX_PL_Object *)pkixAltName,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(pkixAltName);
-
- PKIX_CERT_DEBUG
- ("\t\tCalling CERT_GetNextGeneralName).\n");
- nssTempAltName = CERT_GetNextGeneralName
- (nssTempAltName);
-
- } while (nssTempAltName != nssOriginalAltName);
-
- /* save a cached copy in case it is asked for again */
- cert->subjAltNames = altNamesList;
- PKIX_CHECK(PKIX_List_SetImmutable
- (cert->subjAltNames, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->subjAltNames);
-
- *pSubjectAltNames = cert->subjAltNames;
-
-cleanup:
- PKIX_DECREF(pkixAltName);
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(altNamesList);
- }
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetAllSubjectNames (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetAllSubjectNames(
- PKIX_PL_Cert *cert,
- PKIX_List **pAllSubjectNames, /* list of PKIX_PL_GeneralName */
- void *plContext)
-{
- CERTGeneralName *nssOriginalSubjectName = NULL;
- CERTGeneralName *nssTempSubjectName = NULL;
- PKIX_List *allSubjectNames = NULL;
- PKIX_PL_GeneralName *pkixSubjectName = NULL;
- PLArenaPool *arena = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAllSubjectNames");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAllSubjectNames);
-
-
- if (cert->nssCert->subjectName == NULL){
- /* if there is no subject DN, just get altnames */
-
- PKIX_CHECK(pkix_pl_Cert_GetNssSubjectAltNames
- (cert,
- PKIX_FALSE, /* hasLock */
- &nssOriginalSubjectName,
- plContext),
- PKIX_CERTGETNSSSUBJECTALTNAMESFAILED);
-
- } else { /* get subject DN and altnames */
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- /* This NSS call returns both Subject and Subject Alt Names */
- PKIX_CERT_DEBUG("\t\tCalling CERT_GetCertificateNames\n");
- nssOriginalSubjectName =
- CERT_GetCertificateNames(cert->nssCert, arena);
- }
-
- if (nssOriginalSubjectName == NULL) {
- pAllSubjectNames = NULL;
- goto cleanup;
- }
-
- nssTempSubjectName = nssOriginalSubjectName;
-
- PKIX_CHECK(PKIX_List_Create(&allSubjectNames, plContext),
- PKIX_LISTCREATEFAILED);
-
- do {
- PKIX_CHECK(pkix_pl_GeneralName_Create
- (nssTempSubjectName, &pkixSubjectName, plContext),
- PKIX_GENERALNAMECREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (allSubjectNames,
- (PKIX_PL_Object *)pkixSubjectName,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(pkixSubjectName);
-
- PKIX_CERT_DEBUG
- ("\t\tCalling CERT_GetNextGeneralName).\n");
- nssTempSubjectName = CERT_GetNextGeneralName
- (nssTempSubjectName);
- } while (nssTempSubjectName != nssOriginalSubjectName);
-
- *pAllSubjectNames = allSubjectNames;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(allSubjectNames);
- }
-
- if (arena){
- PORT_FreeArena(arena, PR_FALSE);
- }
- PKIX_DECREF(pkixSubjectName);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKeyAlgId
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectPublicKeyAlgId(
- PKIX_PL_Cert *cert,
- PKIX_PL_OID **pSubjKeyAlgId,
- void *plContext)
-{
- PKIX_PL_OID *pubKeyAlgId = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKeyAlgId");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyAlgId);
-
- /* if we don't have a cached copy from before, we create one */
- if (cert->publicKeyAlgId == NULL){
- PKIX_OBJECT_LOCK(cert);
- if (cert->publicKeyAlgId == NULL){
- CERTCertificate *nssCert = cert->nssCert;
- SECAlgorithmID *algorithm;
- SECItem *algBytes;
-
- algorithm = &nssCert->subjectPublicKeyInfo.algorithm;
- algBytes = &algorithm->algorithm;
- if (!algBytes->data || !algBytes->len) {
- PKIX_ERROR_FATAL(PKIX_ALGORITHMBYTESLENGTH0);
- }
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
- (algBytes, &pubKeyAlgId, plContext),
- PKIX_OIDCREATEFAILED);
-
- /* save a cached copy in case it is asked for again */
- cert->publicKeyAlgId = pubKeyAlgId;
- pubKeyAlgId = NULL;
- }
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->publicKeyAlgId);
- *pSubjKeyAlgId = cert->publicKeyAlgId;
-
-cleanup:
- PKIX_DECREF(pubKeyAlgId);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectPublicKey (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectPublicKey(
- PKIX_PL_Cert *cert,
- PKIX_PL_PublicKey **pPublicKey,
- void *plContext)
-{
- PKIX_PL_PublicKey *pkixPubKey = NULL;
- SECStatus rv;
-
- CERTSubjectPublicKeyInfo *from = NULL;
- CERTSubjectPublicKeyInfo *to = NULL;
- SECItem *fromItem = NULL;
- SECItem *toItem = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectPublicKey");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPublicKey);
-
- /* if we don't have a cached copy from before, we create one */
- if (cert->publicKey == NULL){
-
- PKIX_OBJECT_LOCK(cert);
-
- if (cert->publicKey == NULL){
-
- /* create a PKIX_PL_PublicKey object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_PUBLICKEY_TYPE,
- sizeof (PKIX_PL_PublicKey),
- (PKIX_PL_Object **)&pkixPubKey,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- /* initialize fields */
- pkixPubKey->nssSPKI = NULL;
-
- /* populate the SPKI field */
- PKIX_CHECK(PKIX_PL_Malloc
- (sizeof (CERTSubjectPublicKeyInfo),
- (void **)&pkixPubKey->nssSPKI,
- plContext),
- PKIX_MALLOCFAILED);
-
- to = pkixPubKey->nssSPKI;
- from = &cert->nssCert->subjectPublicKeyInfo;
-
- PKIX_NULLCHECK_TWO(to, from);
-
- PKIX_CERT_DEBUG
- ("\t\tCalling SECOID_CopyAlgorithmID).\n");
- rv = SECOID_CopyAlgorithmID
- (NULL, &to->algorithm, &from->algorithm);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_SECOIDCOPYALGORITHMIDFAILED);
- }
-
- /*
- * NSS stores the length of subjectPublicKey in bits.
- * Therefore, we use that length converted to bytes
- * using ((length+7)>>3) before calling PORT_Memcpy
- * in order to avoid "read from uninitialized memory"
- * errors.
- */
-
- toItem = &to->subjectPublicKey;
- fromItem = &from->subjectPublicKey;
-
- PKIX_NULLCHECK_TWO(toItem, fromItem);
-
- toItem->type = fromItem->type;
-
- toItem->data =
- (unsigned char*) PORT_ZAlloc(fromItem->len);
- if (!toItem->data){
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- (void) PORT_Memcpy(toItem->data,
- fromItem->data,
- (fromItem->len + 7)>>3);
- toItem->len = fromItem->len;
-
- /* save a cached copy in case it is asked for again */
- cert->publicKey = pkixPubKey;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->publicKey);
- *pPublicKey = cert->publicKey;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED && pkixPubKey){
- PKIX_DECREF(pkixPubKey);
- cert->publicKey = NULL;
- }
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetCriticalExtensionOIDs
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetCriticalExtensionOIDs(
- PKIX_PL_Cert *cert,
- PKIX_List **pList, /* list of PKIX_PL_OID */
- void *plContext)
-{
- PKIX_List *oidsList = NULL;
- CERTCertExtension **extensions = NULL;
- CERTCertificate *nssCert = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCriticalExtensionOIDs");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pList);
-
- /* if we don't have a cached copy from before, we create one */
- if (cert->critExtOids == NULL) {
-
- PKIX_OBJECT_LOCK(cert);
-
- if (cert->critExtOids == NULL) {
-
- nssCert = cert->nssCert;
-
- /*
- * ASN.1 for Extension
- *
- * Extension ::= SEQUENCE {
- * extnID OBJECT IDENTIFIER,
- * critical BOOLEAN DEFAULT FALSE,
- * extnValue OCTET STRING }
- *
- */
-
- extensions = nssCert->extensions;
-
- PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
- (extensions, &oidsList, plContext),
- PKIX_GETCRITICALEXTENSIONOIDSFAILED);
-
- /* save a cached copy in case it is asked for again */
- cert->critExtOids = oidsList;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- /* We should return a copy of the List since this list changes */
- PKIX_DUPLICATE(cert->critExtOids, pList, plContext,
- PKIX_OBJECTDUPLICATELISTFAILED);
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetAuthorityKeyIdentifier
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetAuthorityKeyIdentifier(
- PKIX_PL_Cert *cert,
- PKIX_PL_ByteArray **pAuthKeyId,
- void *plContext)
-{
- PKIX_PL_ByteArray *authKeyId = NULL;
- CERTCertificate *nssCert = NULL;
- CERTAuthKeyID *authKeyIdExtension = NULL;
- PLArenaPool *arena = NULL;
- SECItem retItem;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityKeyIdentifier");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAuthKeyId);
-
- /* if we don't have a cached copy from before, we create one */
- if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){
-
- PKIX_OBJECT_LOCK(cert);
-
- if ((cert->authKeyId == NULL) && (!cert->authKeyIdAbsent)){
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- nssCert = cert->nssCert;
-
- authKeyIdExtension =
- CERT_FindAuthKeyIDExten(arena, nssCert);
- if (authKeyIdExtension == NULL){
- cert->authKeyIdAbsent = PKIX_TRUE;
- *pAuthKeyId = NULL;
- goto cleanup;
- }
-
- retItem = authKeyIdExtension->keyID;
-
- if (retItem.len == 0){
- cert->authKeyIdAbsent = PKIX_TRUE;
- *pAuthKeyId = NULL;
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_PL_ByteArray_Create
- (retItem.data,
- retItem.len,
- &authKeyId,
- plContext),
- PKIX_BYTEARRAYCREATEFAILED);
-
- /* save a cached copy in case it is asked for again */
- cert->authKeyId = authKeyId;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->authKeyId);
- *pAuthKeyId = cert->authKeyId;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- if (arena){
- PORT_FreeArena(arena, PR_FALSE);
- }
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectKeyIdentifier
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectKeyIdentifier(
- PKIX_PL_Cert *cert,
- PKIX_PL_ByteArray **pSubjKeyId,
- void *plContext)
-{
- PKIX_PL_ByteArray *subjKeyId = NULL;
- CERTCertificate *nssCert = NULL;
- SECItem *retItem = NULL;
- SECStatus status;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectKeyIdentifier");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSubjKeyId);
-
- /* if we don't have a cached copy from before, we create one */
- if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){
-
- PKIX_OBJECT_LOCK(cert);
-
- if ((cert->subjKeyId == NULL) && (!cert->subjKeyIdAbsent)){
-
- retItem = SECITEM_AllocItem(NULL, NULL, 0);
- if (retItem == NULL){
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- nssCert = cert->nssCert;
-
- status = CERT_FindSubjectKeyIDExtension
- (nssCert, retItem);
- if (status != SECSuccess) {
- cert->subjKeyIdAbsent = PKIX_TRUE;
- *pSubjKeyId = NULL;
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_PL_ByteArray_Create
- (retItem->data,
- retItem->len,
- &subjKeyId,
- plContext),
- PKIX_BYTEARRAYCREATEFAILED);
-
- /* save a cached copy in case it is asked for again */
- cert->subjKeyId = subjKeyId;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->subjKeyId);
- *pSubjKeyId = cert->subjKeyId;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- if (retItem){
- SECITEM_FreeItem(retItem, PKIX_TRUE);
- }
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetExtendedKeyUsage (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetExtendedKeyUsage(
- PKIX_PL_Cert *cert,
- PKIX_List **pKeyUsage, /* list of PKIX_PL_OID */
- void *plContext)
-{
- CERTOidSequence *extKeyUsage = NULL;
- CERTCertificate *nssCert = NULL;
- PKIX_PL_OID *pkixOID = NULL;
- PKIX_List *oidsList = NULL;
- SECItem **oids = NULL;
- SECItem encodedExtKeyUsage;
- SECStatus rv;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetExtendedKeyUsage");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pKeyUsage);
-
- /* if we don't have a cached copy from before, we create one */
- if ((cert->extKeyUsages == NULL) && (!cert->extKeyUsagesAbsent)){
-
- PKIX_OBJECT_LOCK(cert);
-
- if ((cert->extKeyUsages == NULL) &&
- (!cert->extKeyUsagesAbsent)){
-
- nssCert = cert->nssCert;
-
- rv = CERT_FindCertExtension
- (nssCert, SEC_OID_X509_EXT_KEY_USAGE,
- &encodedExtKeyUsage);
- if (rv != SECSuccess){
- cert->extKeyUsagesAbsent = PKIX_TRUE;
- *pKeyUsage = NULL;
- goto cleanup;
- }
-
- extKeyUsage =
- CERT_DecodeOidSequence(&encodedExtKeyUsage);
- if (extKeyUsage == NULL){
- PKIX_ERROR(PKIX_CERTDECODEOIDSEQUENCEFAILED);
- }
-
- PORT_Free(encodedExtKeyUsage.data);
-
- oids = extKeyUsage->oids;
-
- if (!oids){
- /* no extended key usage extensions found */
- cert->extKeyUsagesAbsent = PKIX_TRUE;
- *pKeyUsage = NULL;
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_List_Create(&oidsList, plContext),
- PKIX_LISTCREATEFAILED);
-
- while (*oids){
- SECItem *oid = *oids++;
-
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
- (oid, &pkixOID, plContext),
- PKIX_OIDCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (oidsList,
- (PKIX_PL_Object *)pkixOID,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_DECREF(pkixOID);
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable
- (oidsList, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- /* save a cached copy in case it is asked for again */
- cert->extKeyUsages = oidsList;
- oidsList = NULL;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->extKeyUsages);
- *pKeyUsage = cert->extKeyUsages;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
-
- PKIX_DECREF(pkixOID);
- PKIX_DECREF(oidsList);
- CERT_DestroyOidSequence(extKeyUsage);
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetBasicConstraints
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetBasicConstraints(
- PKIX_PL_Cert *cert,
- PKIX_PL_CertBasicConstraints **pBasicConstraints,
- void *plContext)
-{
- CERTCertificate *nssCert = NULL;
- CERTBasicConstraints nssBasicConstraint;
- SECStatus rv;
- PKIX_PL_CertBasicConstraints *basic;
- PKIX_Int32 pathLen = 0;
- PKIX_Boolean isCA = PKIX_FALSE;
- enum {
- realBC, synthBC, absentBC
- } constraintSource = absentBC;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetBasicConstraints");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pBasicConstraints);
-
- /* if we don't have a cached copy from before, we create one */
- if ((cert->certBasicConstraints == NULL) &&
- (!cert->basicConstraintsAbsent)) {
-
- PKIX_OBJECT_LOCK(cert);
-
- if ((cert->certBasicConstraints == NULL) &&
- (!cert->basicConstraintsAbsent)) {
-
- nssCert = cert->nssCert;
-
- PKIX_CERT_DEBUG(
- "\t\tCalling Cert_FindBasicConstraintExten\n");
- rv = CERT_FindBasicConstraintExten
- (nssCert, &nssBasicConstraint);
- if (rv == SECSuccess) {
- constraintSource = realBC;
- }
-
- if (constraintSource == absentBC) {
- /* can we deduce it's a CA and create a
- synthetic constraint?
- */
- CERTCertTrust trust;
- rv = CERT_GetCertTrust(nssCert, &trust);
- if (rv == SECSuccess) {
- int anyWantedFlag = CERTDB_TRUSTED_CA | CERTDB_VALID_CA;
- if ((trust.sslFlags & anyWantedFlag)
- || (trust.emailFlags & anyWantedFlag)
- || (trust.objectSigningFlags & anyWantedFlag)) {
-
- constraintSource = synthBC;
- }
- }
- }
-
- if (constraintSource == absentBC) {
- cert->basicConstraintsAbsent = PKIX_TRUE;
- *pBasicConstraints = NULL;
- goto cleanup;
- }
- }
-
- if (constraintSource == synthBC) {
- isCA = PKIX_TRUE;
- pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT;
- } else {
- isCA = (nssBasicConstraint.isCA)?PKIX_TRUE:PKIX_FALSE;
-
- /* The pathLen has meaning only for CAs */
- if (isCA) {
- if (CERT_UNLIMITED_PATH_CONSTRAINT ==
- nssBasicConstraint.pathLenConstraint) {
- pathLen = PKIX_UNLIMITED_PATH_CONSTRAINT;
- } else {
- pathLen = nssBasicConstraint.pathLenConstraint;
- }
- }
- }
-
- PKIX_CHECK(pkix_pl_CertBasicConstraints_Create
- (isCA, pathLen, &basic, plContext),
- PKIX_CERTBASICCONSTRAINTSCREATEFAILED);
-
- /* save a cached copy in case it is asked for again */
- cert->certBasicConstraints = basic;
- }
-
- PKIX_INCREF(cert->certBasicConstraints);
- *pBasicConstraints = cert->certBasicConstraints;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetPolicyInformation
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetPolicyInformation(
- PKIX_PL_Cert *cert,
- PKIX_List **pPolicyInfo,
- void *plContext)
-{
- PKIX_List *policyList = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyInformation");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyInfo);
-
- /* if we don't have a cached copy from before, we create one */
- if ((cert->certPolicyInfos == NULL) &&
- (!cert->policyInfoAbsent)) {
-
- PKIX_OBJECT_LOCK(cert);
-
- if ((cert->certPolicyInfos == NULL) &&
- (!cert->policyInfoAbsent)) {
-
- PKIX_CHECK(pkix_pl_Cert_DecodePolicyInfo
- (cert->nssCert, &policyList, plContext),
- PKIX_CERTDECODEPOLICYINFOFAILED);
-
- if (!policyList) {
- cert->policyInfoAbsent = PKIX_TRUE;
- *pPolicyInfo = NULL;
- goto cleanup;
- }
- }
-
- PKIX_OBJECT_UNLOCK(cert);
-
- /* save a cached copy in case it is asked for again */
- cert->certPolicyInfos = policyList;
- policyList = NULL;
- }
-
- PKIX_INCREF(cert->certPolicyInfos);
- *pPolicyInfo = cert->certPolicyInfos;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
-
- PKIX_DECREF(policyList);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetPolicyMappings (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetPolicyMappings(
- PKIX_PL_Cert *cert,
- PKIX_List **pPolicyMappings, /* list of PKIX_PL_CertPolicyMap */
- void *plContext)
-{
- PKIX_List *policyMappings = NULL; /* list of PKIX_PL_CertPolicyMap */
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappings");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pPolicyMappings);
-
- /* if we don't have a cached copy from before, we create one */
- if (!(cert->certPolicyMappings) && !(cert->policyMappingsAbsent)) {
-
- PKIX_OBJECT_LOCK(cert);
-
- if (!(cert->certPolicyMappings) &&
- !(cert->policyMappingsAbsent)) {
-
- PKIX_CHECK(pkix_pl_Cert_DecodePolicyMapping
- (cert->nssCert, &policyMappings, plContext),
- PKIX_CERTDECODEPOLICYMAPPINGFAILED);
-
- if (!policyMappings) {
- cert->policyMappingsAbsent = PKIX_TRUE;
- *pPolicyMappings = NULL;
- goto cleanup;
- }
- }
-
- PKIX_OBJECT_UNLOCK(cert);
-
- /* save a cached copy in case it is asked for again */
- cert->certPolicyMappings = policyMappings;
- policyMappings = NULL;
- }
-
- PKIX_INCREF(cert->certPolicyMappings);
- *pPolicyMappings = cert->certPolicyMappings;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
-
- PKIX_DECREF(policyMappings);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetRequireExplicitPolicy
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetRequireExplicitPolicy(
- PKIX_PL_Cert *cert,
- PKIX_Int32 *pSkipCerts,
- void *plContext)
-{
- PKIX_Int32 explicitPolicySkipCerts = 0;
- PKIX_Int32 inhibitMappingSkipCerts = 0;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetRequireExplicitPolicy");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
-
- if (!(cert->policyConstraintsProcessed)) {
- PKIX_OBJECT_LOCK(cert);
-
- if (!(cert->policyConstraintsProcessed)) {
-
- /*
- * If we can't process it now, we probably will be
- * unable to process it later. Set the default value.
- */
- cert->policyConstraintsProcessed = PKIX_TRUE;
- cert->policyConstraintsExplicitPolicySkipCerts = -1;
- cert->policyConstraintsInhibitMappingSkipCerts = -1;
-
- PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
- (cert->nssCert,
- &explicitPolicySkipCerts,
- &inhibitMappingSkipCerts,
- plContext),
- PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED);
-
- cert->policyConstraintsExplicitPolicySkipCerts =
- explicitPolicySkipCerts;
- cert->policyConstraintsInhibitMappingSkipCerts =
- inhibitMappingSkipCerts;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- *pSkipCerts = cert->policyConstraintsExplicitPolicySkipCerts;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetPolicyMappingInhibited
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetPolicyMappingInhibited(
- PKIX_PL_Cert *cert,
- PKIX_Int32 *pSkipCerts,
- void *plContext)
-{
- PKIX_Int32 explicitPolicySkipCerts = 0;
- PKIX_Int32 inhibitMappingSkipCerts = 0;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetPolicyMappingInhibited");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
-
- if (!(cert->policyConstraintsProcessed)) {
- PKIX_OBJECT_LOCK(cert);
-
- if (!(cert->policyConstraintsProcessed)) {
-
- /*
- * If we can't process it now, we probably will be
- * unable to process it later. Set the default value.
- */
- cert->policyConstraintsProcessed = PKIX_TRUE;
- cert->policyConstraintsExplicitPolicySkipCerts = -1;
- cert->policyConstraintsInhibitMappingSkipCerts = -1;
-
- PKIX_CHECK(pkix_pl_Cert_DecodePolicyConstraints
- (cert->nssCert,
- &explicitPolicySkipCerts,
- &inhibitMappingSkipCerts,
- plContext),
- PKIX_CERTDECODEPOLICYCONSTRAINTSFAILED);
-
- cert->policyConstraintsExplicitPolicySkipCerts =
- explicitPolicySkipCerts;
- cert->policyConstraintsInhibitMappingSkipCerts =
- inhibitMappingSkipCerts;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- *pSkipCerts = cert->policyConstraintsInhibitMappingSkipCerts;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetInhibitAnyPolicy (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetInhibitAnyPolicy(
- PKIX_PL_Cert *cert,
- PKIX_Int32 *pSkipCerts,
- void *plContext)
-{
- PKIX_Int32 skipCerts = 0;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetInhibitAnyPolicy");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSkipCerts);
-
- if (!(cert->inhibitAnyPolicyProcessed)) {
-
- PKIX_OBJECT_LOCK(cert);
-
- if (!(cert->inhibitAnyPolicyProcessed)) {
-
- /*
- * If we can't process it now, we probably will be
- * unable to process it later. Set the default value.
- */
- cert->inhibitAnyPolicyProcessed = PKIX_TRUE;
- cert->inhibitAnySkipCerts = -1;
-
- PKIX_CHECK(pkix_pl_Cert_DecodeInhibitAnyPolicy
- (cert->nssCert, &skipCerts, plContext),
- PKIX_CERTDECODEINHIBITANYPOLICYFAILED);
-
- cert->inhibitAnySkipCerts = skipCerts;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- *pSkipCerts = cert->inhibitAnySkipCerts;
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_AreCertPoliciesCritical
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_AreCertPoliciesCritical(
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pCritical,
- void *plContext)
-{
- PKIX_Boolean criticality = PKIX_FALSE;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_AreCertPoliciesCritical");
- PKIX_NULLCHECK_TWO(cert, pCritical);
-
- PKIX_CHECK(pkix_pl_Cert_IsExtensionCritical(
- cert,
- SEC_OID_X509_CERTIFICATE_POLICIES,
- &criticality,
- plContext),
- PKIX_CERTISEXTENSIONCRITICALFAILED);
-
- *pCritical = criticality;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_VerifySignature (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_VerifySignature(
- PKIX_PL_Cert *cert,
- PKIX_PL_PublicKey *pubKey,
- void *plContext)
-{
- CERTCertificate *nssCert = NULL;
- SECKEYPublicKey *nssPubKey = NULL;
- CERTSignedData *tbsCert = NULL;
- PKIX_PL_Cert *cachedCert = NULL;
- PKIX_Error *verifySig = NULL;
- PKIX_Error *cachedSig = NULL;
- SECStatus status;
- PKIX_Boolean certEqual = PKIX_FALSE;
- PKIX_Boolean certInHash = PKIX_FALSE;
- void* wincx = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifySignature");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pubKey);
-
- verifySig = PKIX_PL_HashTable_Lookup
- (cachedCertSigTable,
- (PKIX_PL_Object *) pubKey,
- (PKIX_PL_Object **) &cachedCert,
- plContext);
-
- if (cachedCert != NULL && verifySig == NULL) {
- /* Cached Signature Table lookup succeed */
- PKIX_EQUALS(cert, cachedCert, &certEqual, plContext,
- PKIX_OBJECTEQUALSFAILED);
- if (certEqual == PKIX_TRUE) {
- goto cleanup;
- }
- /* Different PubKey may hash to same value, skip add */
- certInHash = PKIX_TRUE;
- }
-
- nssCert = cert->nssCert;
- tbsCert = &nssCert->signatureWrap;
-
- PKIX_CERT_DEBUG("\t\tCalling SECKEY_ExtractPublicKey).\n");
- nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI);
- if (!nssPubKey){
- PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED);
- }
-
- PKIX_CERT_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey).\n");
-
- PKIX_CHECK(pkix_pl_NssContext_GetWincx
- ((PKIX_PL_NssContext *)plContext, &wincx),
- PKIX_NSSCONTEXTGETWINCXFAILED);
-
- status = CERT_VerifySignedDataWithPublicKey(tbsCert, nssPubKey, wincx);
-
- if (status != SECSuccess) {
- if (PORT_GetError() != SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- }
- PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY);
- }
-
- if (certInHash == PKIX_FALSE) {
- cachedSig = PKIX_PL_HashTable_Add
- (cachedCertSigTable,
- (PKIX_PL_Object *) pubKey,
- (PKIX_PL_Object *) cert,
- plContext);
-
- if (cachedSig != NULL) {
- PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n");
- }
- }
-
-cleanup:
- if (nssPubKey){
- PKIX_CERT_DEBUG("\t\tCalling SECKEY_DestroyPublicKey).\n");
- SECKEY_DestroyPublicKey(nssPubKey);
- }
-
- PKIX_DECREF(cachedCert);
- PKIX_DECREF(verifySig);
- PKIX_DECREF(cachedSig);
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_CheckValidity (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_CheckValidity(
- PKIX_PL_Cert *cert,
- PKIX_PL_Date *date,
- void *plContext)
-{
- SECCertTimeValidity val;
- PRTime timeToCheck;
- PKIX_Boolean allowOverride;
- SECCertificateUsage requiredUsages;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckValidity");
- PKIX_NULLCHECK_ONE(cert);
-
- /* if the caller supplies a date, we use it; else, use current time */
- if (date != NULL){
- PKIX_CHECK(pkix_pl_Date_GetPRTime
- (date, &timeToCheck, plContext),
- PKIX_DATEGETPRTIMEFAILED);
- } else {
- timeToCheck = PR_Now();
- }
-
- requiredUsages = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
- allowOverride =
- (PRBool)((requiredUsages & certificateUsageSSLServer) ||
- (requiredUsages & certificateUsageSSLServerWithStepUp));
- val = CERT_CheckCertValidTimes(cert->nssCert, timeToCheck, allowOverride);
- if (val != secCertTimeValid){
- PKIX_ERROR(PKIX_CERTCHECKCERTVALIDTIMESFAILED);
- }
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetValidityNotAfter (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetValidityNotAfter(
- PKIX_PL_Cert *cert,
- PKIX_PL_Date **pDate,
- void *plContext)
-{
- PRTime prtime;
- SECStatus rv = SECFailure;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetValidityNotAfter");
- PKIX_NULLCHECK_TWO(cert, pDate);
-
- PKIX_DATE_DEBUG("\t\tCalling DER_DecodeTimeChoice).\n");
- rv = DER_DecodeTimeChoice(&prtime, &(cert->nssCert->validity.notAfter));
- if (rv != SECSuccess){
- PKIX_ERROR(PKIX_DERDECODETIMECHOICEFAILED);
- }
-
- PKIX_CHECK(pkix_pl_Date_CreateFromPRTime
- (prtime, pDate, plContext),
- PKIX_DATECREATEFROMPRTIMEFAILED);
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_VerifyCertAndKeyType (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_VerifyCertAndKeyType(
- PKIX_PL_Cert *cert,
- PKIX_Boolean isChainCert,
- void *plContext)
-{
- PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
- SECCertificateUsage certificateUsage;
- SECCertUsage certUsage = 0;
- unsigned int requiredKeyUsage;
- unsigned int requiredCertType;
- unsigned int certType;
- SECStatus rv = SECSuccess;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifyCertType");
- PKIX_NULLCHECK_TWO(cert, plContext);
-
- certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
-
- /* ensure we obtained a single usage bit only */
- PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
-
- /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
- while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
-
- /* check key usage and netscape cert type */
- cert_GetCertType(cert->nssCert);
- certType = cert->nssCert->nsCertType;
- if (isChainCert ||
- (certUsage != certUsageVerifyCA && certUsage != certUsageAnyCA)) {
- rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, isChainCert,
- &requiredKeyUsage,
- &requiredCertType);
- if (rv == SECFailure) {
- PKIX_ERROR(PKIX_UNSUPPORTEDCERTUSAGE);
- }
- } else {
- /* use this key usage and cert type for certUsageAnyCA and
- * certUsageVerifyCA. */
- requiredKeyUsage = KU_KEY_CERT_SIGN;
- requiredCertType = NS_CERT_TYPE_CA;
- }
- if (CERT_CheckKeyUsage(cert->nssCert, requiredKeyUsage) != SECSuccess) {
- PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED);
- }
- if (!(certType & requiredCertType)) {
- PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED);
- }
-cleanup:
- PKIX_DECREF(basicConstraints);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_VerifyKeyUsage (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_VerifyKeyUsage(
- PKIX_PL_Cert *cert,
- PKIX_UInt32 keyUsage,
- void *plContext)
-{
- CERTCertificate *nssCert = NULL;
- PKIX_UInt32 nssKeyUsage = 0;
- SECStatus status;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_VerifyKeyUsage");
- PKIX_NULLCHECK_TWO(cert, cert->nssCert);
-
- nssCert = cert->nssCert;
-
- /* if cert doesn't have keyUsage extension, all keyUsages are valid */
- if (!nssCert->keyUsagePresent){
- goto cleanup;
- }
-
- if (keyUsage & PKIX_DIGITAL_SIGNATURE){
- nssKeyUsage = nssKeyUsage | KU_DIGITAL_SIGNATURE;
- }
-
- if (keyUsage & PKIX_NON_REPUDIATION){
- nssKeyUsage = nssKeyUsage | KU_NON_REPUDIATION;
- }
-
- if (keyUsage & PKIX_KEY_ENCIPHERMENT){
- nssKeyUsage = nssKeyUsage | KU_KEY_ENCIPHERMENT;
- }
-
- if (keyUsage & PKIX_DATA_ENCIPHERMENT){
- nssKeyUsage = nssKeyUsage | KU_DATA_ENCIPHERMENT;
- }
-
- if (keyUsage & PKIX_KEY_AGREEMENT){
- nssKeyUsage = nssKeyUsage | KU_KEY_AGREEMENT;
- }
-
- if (keyUsage & PKIX_KEY_CERT_SIGN){
- nssKeyUsage = nssKeyUsage | KU_KEY_CERT_SIGN;
- }
-
- if (keyUsage & PKIX_CRL_SIGN){
- nssKeyUsage = nssKeyUsage | KU_CRL_SIGN;
- }
-
- if (keyUsage & PKIX_ENCIPHER_ONLY){
- nssKeyUsage = nssKeyUsage | 0x01;
- }
-
- if (keyUsage & PKIX_DECIPHER_ONLY){
- /* XXX we should support this once it is fixed in NSS */
- PKIX_ERROR(PKIX_DECIPHERONLYKEYUSAGENOTSUPPORTED);
- }
-
- status = CERT_CheckKeyUsage(nssCert, nssKeyUsage);
- if (status != SECSuccess) {
- PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED);
- }
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetNameConstraints
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetNameConstraints(
- PKIX_PL_Cert *cert,
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNameConstraints");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pNameConstraints);
-
- /* if we don't have a cached copy from before, we create one */
- if (cert->nameConstraints == NULL && !cert->nameConstraintsAbsent) {
-
- PKIX_OBJECT_LOCK(cert);
-
- if (cert->nameConstraints == NULL &&
- !cert->nameConstraintsAbsent) {
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_Create
- (cert->nssCert, &nameConstraints, plContext),
- PKIX_CERTNAMECONSTRAINTSCREATEFAILED);
-
- if (nameConstraints == NULL) {
- cert->nameConstraintsAbsent = PKIX_TRUE;
- }
-
- cert->nameConstraints = nameConstraints;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
-
- }
-
- PKIX_INCREF(cert->nameConstraints);
-
- *pNameConstraints = cert->nameConstraints;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_CheckNameConstraints
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_CheckNameConstraints(
- PKIX_PL_Cert *cert,
- PKIX_PL_CertNameConstraints *nameConstraints,
- void *plContext)
-{
- PKIX_Boolean checkPass = PKIX_TRUE;
- CERTGeneralName *nssSubjectNames = NULL;
- PLArenaPool *arena = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_CheckNameConstraints");
- PKIX_NULLCHECK_ONE(cert);
-
- if (nameConstraints != NULL) {
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- /* This NSS call returns both Subject and Subject Alt Names */
- PKIX_CERT_DEBUG
- ("\t\tCalling CERT_GetConstrainedCertificateNames\n");
- nssSubjectNames = CERT_GetConstrainedCertificateNames
- (cert->nssCert, arena, PR_TRUE);
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_CheckNameSpaceNssNames
- (nssSubjectNames,
- nameConstraints,
- &checkPass,
- plContext),
- PKIX_CERTNAMECONSTRAINTSCHECKNAMESPACENSSNAMESFAILED);
-
- if (checkPass != PKIX_TRUE) {
- PKIX_ERROR(PKIX_CERTFAILEDNAMECONSTRAINTSCHECKING);
- }
- }
-
-cleanup:
- if (arena){
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_MergeNameConstraints
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_MergeNameConstraints(
- PKIX_PL_CertNameConstraints *firstNC,
- PKIX_PL_CertNameConstraints *secondNC,
- PKIX_PL_CertNameConstraints **pResultNC,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *mergedNC = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_MergeNameConstraints");
- PKIX_NULLCHECK_TWO(firstNC, pResultNC);
-
- if (secondNC == NULL) {
-
- PKIX_INCREF(firstNC);
- *pResultNC = firstNC;
-
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_Merge
- (firstNC, secondNC, &mergedNC, plContext),
- PKIX_CERTNAMECONSTRAINTSMERGEFAILED);
-
- *pResultNC = mergedNC;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * Find out the state of the NSS trust bits for the requested usage.
- * Returns SECFailure if the cert is explicitly distrusted.
- * Returns SECSuccess if the cert can be used to form a chain (normal case),
- * or it is explicitly trusted. The trusted bool is set to true if it is
- * explicitly trusted.
- */
-static SECStatus
-pkix_pl_Cert_GetTrusted(void *plContext,
- PKIX_PL_Cert *cert,
- PKIX_Boolean *trusted,
- PKIX_Boolean isCA)
-{
- SECStatus rv;
- CERTCertificate *nssCert = NULL;
- SECCertUsage certUsage = 0;
- SECCertificateUsage certificateUsage;
- SECTrustType trustType;
- unsigned int trustFlags;
- unsigned int requiredFlags;
- CERTCertTrust trust;
-
- *trusted = PKIX_FALSE;
-
- /* no key usage information */
- if (plContext == NULL) {
- return SECSuccess;
- }
-
- certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
-
- /* ensure we obtained a single usage bit only */
- PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
-
- /* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
- while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
-
- nssCert = cert->nssCert;
-
- if (!isCA) {
- PRBool prTrusted;
- unsigned int failedFlags;
- rv = cert_CheckLeafTrust(nssCert, certUsage,
- &failedFlags, &prTrusted);
- *trusted = (PKIX_Boolean) prTrusted;
- return rv;
- }
- rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,
- &trustType);
- if (rv != SECSuccess) {
- return SECSuccess;
- }
-
- rv = CERT_GetCertTrust(nssCert, &trust);
- if (rv != SECSuccess) {
- return SECSuccess;
- }
- trustFlags = SEC_GET_TRUST_FLAGS(&trust, trustType);
- /* normally trustTypeNone usages accept any of the given trust bits
- * being on as acceptable. If any are distrusted (and none are trusted),
- * then we will also distrust the cert */
- if ((trustFlags == 0) && (trustType == trustTypeNone)) {
- trustFlags = trust.sslFlags | trust.emailFlags |
- trust.objectSigningFlags;
- }
- if ((trustFlags & requiredFlags) == requiredFlags) {
- *trusted = PKIX_TRUE;
- return SECSuccess;
- }
- if ((trustFlags & CERTDB_TERMINAL_RECORD) &&
- ((trustFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_IsCertTrusted
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_IsCertTrusted(
- PKIX_PL_Cert *cert,
- PKIX_Boolean trustOnlyUserAnchors,
- PKIX_Boolean *pTrusted,
- void *plContext)
-{
- PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
- PKIX_Boolean trusted = PKIX_FALSE;
- SECStatus rv = SECFailure;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_IsCertTrusted");
- PKIX_NULLCHECK_TWO(cert, pTrusted);
-
- /* Call GetTrusted first to see if we are going to distrust the
- * certificate */
- rv = pkix_pl_Cert_GetTrusted(plContext, cert, &trusted, PKIX_TRUE);
- if (rv != SECSuccess) {
- /* Failure means the cert is explicitly distrusted,
- * let the next level know not to use it. */
- *pTrusted = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED);
- }
-
- if (trustOnlyUserAnchors || cert->isUserTrustAnchor) {
- /* discard our |trusted| value since we are using the anchors */
- *pTrusted = cert->isUserTrustAnchor;
- goto cleanup;
- }
-
- /* no key usage information or store is not trusted */
- if (plContext == NULL || cert->store == NULL) {
- *pTrusted = PKIX_FALSE;
- goto cleanup;
- }
-
- PKIX_CHECK(PKIX_CertStore_GetTrustCallback
- (cert->store, &trustCallback, plContext),
- PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
-
- PKIX_CHECK_ONLY_FATAL(trustCallback
- (cert->store, cert, &trusted, plContext),
- PKIX_CHECKTRUSTCALLBACKFAILED);
-
- /* allow trust store to override if we can trust the trust
- * bits */
- if (PKIX_ERROR_RECEIVED || (trusted == PKIX_FALSE)) {
- *pTrusted = PKIX_FALSE;
- goto cleanup;
- }
-
- *pTrusted = trusted;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_IsLeafCertTrusted
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_IsLeafCertTrusted(
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pTrusted,
- void *plContext)
-{
- SECStatus rv;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_IsLeafCertTrusted");
- PKIX_NULLCHECK_TWO(cert, pTrusted);
-
- *pTrusted = PKIX_FALSE;
-
- rv = pkix_pl_Cert_GetTrusted(plContext, cert, pTrusted, PKIX_FALSE);
- if (rv != SECSuccess) {
- /* Failure means the cert is explicitly distrusted,
- * let the next level know not to use it. */
- *pTrusted = PKIX_FALSE;
- PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED);
- }
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/* FUNCTION: PKIX_PL_Cert_SetAsTrustAnchor */
-PKIX_Error*
-PKIX_PL_Cert_SetAsTrustAnchor(PKIX_PL_Cert *cert,
- void *plContext)
-{
- PKIX_ENTER(CERT, "PKIX_PL_Cert_SetAsTrustAnchor");
- PKIX_NULLCHECK_ONE(cert);
-
- cert->isUserTrustAnchor = PKIX_TRUE;
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetCacheFlag (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetCacheFlag(
- PKIX_PL_Cert *cert,
- PKIX_Boolean *pCacheFlag,
- void *plContext)
-{
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCacheFlag");
- PKIX_NULLCHECK_TWO(cert, pCacheFlag);
-
- *pCacheFlag = cert->cacheFlag;
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_SetCacheFlag (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_SetCacheFlag(
- PKIX_PL_Cert *cert,
- PKIX_Boolean cacheFlag,
- void *plContext)
-{
- PKIX_ENTER(CERT, "PKIX_PL_Cert_SetCacheFlag");
- PKIX_NULLCHECK_ONE(cert);
-
- cert->cacheFlag = cacheFlag;
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetTrustCertStore (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetTrustCertStore(
- PKIX_PL_Cert *cert,
- PKIX_CertStore **pTrustCertStore,
- void *plContext)
-{
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetTrustCertStore");
- PKIX_NULLCHECK_TWO(cert, pTrustCertStore);
-
- PKIX_INCREF(cert->store);
- *pTrustCertStore = cert->store;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_SetTrustCertStore (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_SetTrustCertStore(
- PKIX_PL_Cert *cert,
- PKIX_CertStore *trustCertStore,
- void *plContext)
-{
- PKIX_ENTER(CERT, "PKIX_PL_Cert_SetTrustCertStore");
- PKIX_NULLCHECK_TWO(cert, trustCertStore);
-
- PKIX_INCREF(trustCertStore);
- cert->store = trustCertStore;
-
-cleanup:
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetAuthorityInfoAccess
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetAuthorityInfoAccess(
- PKIX_PL_Cert *cert,
- PKIX_List **pAiaList, /* of PKIX_PL_InfoAccess */
- void *plContext)
-{
- PKIX_List *aiaList = NULL; /* of PKIX_PL_InfoAccess */
- SECItem *encodedAIA = NULL;
- CERTAuthInfoAccess **aia = NULL;
- PLArenaPool *arena = NULL;
- SECStatus rv;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetAuthorityInfoAccess");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pAiaList);
-
- /* if we don't have a cached copy from before, we create one */
- if (cert->authorityInfoAccess == NULL) {
-
- PKIX_OBJECT_LOCK(cert);
-
- if (cert->authorityInfoAccess == NULL) {
-
- PKIX_PL_NSSCALLRV(CERT, encodedAIA, SECITEM_AllocItem,
- (NULL, NULL, 0));
-
- if (encodedAIA == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- PKIX_PL_NSSCALLRV(CERT, rv, CERT_FindCertExtension,
- (cert->nssCert,
- SEC_OID_X509_AUTH_INFO_ACCESS,
- encodedAIA));
-
- if (rv == SECFailure) {
- goto cleanup;
- }
-
- PKIX_PL_NSSCALLRV(CERT, arena, PORT_NewArena,
- (DER_DEFAULT_CHUNKSIZE));
-
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- PKIX_PL_NSSCALLRV
- (CERT, aia, CERT_DecodeAuthInfoAccessExtension,
- (arena, encodedAIA));
-
- PKIX_CHECK(pkix_pl_InfoAccess_CreateList
- (aia, &aiaList, plContext),
- PKIX_INFOACCESSCREATELISTFAILED);
-
- cert->authorityInfoAccess = aiaList;
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->authorityInfoAccess);
-
- *pAiaList = cert->authorityInfoAccess;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- if (encodedAIA != NULL) {
- SECITEM_FreeItem(encodedAIA, PR_TRUE);
- }
-
- PKIX_RETURN(CERT);
-}
-
-/* XXX Following defines belongs to NSS */
-static const unsigned char siaOIDString[] = {0x2b, 0x06, 0x01, 0x05, 0x05,
- 0x07, 0x01, 0x0b};
-#define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetSubjectInfoAccess
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetSubjectInfoAccess(
- PKIX_PL_Cert *cert,
- PKIX_List **pSiaList, /* of PKIX_PL_InfoAccess */
- void *plContext)
-{
- PKIX_List *siaList; /* of PKIX_PL_InfoAccess */
- SECItem siaOID = OI(siaOIDString);
- SECItem *encodedSubjInfoAccess = NULL;
- CERTAuthInfoAccess **subjInfoAccess = NULL;
- PLArenaPool *arena = NULL;
- SECStatus rv;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetSubjectInfoAccess");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pSiaList);
-
- /* XXX
- * Codes to deal with SubjectInfoAccess OID should be moved to
- * NSS soon. I implemented them here so we don't touch NSS
- * source tree, from JP's suggestion.
- */
-
- /* if we don't have a cached copy from before, we create one */
- if (cert->subjectInfoAccess == NULL) {
-
- PKIX_OBJECT_LOCK(cert);
-
- if (cert->subjectInfoAccess == NULL) {
-
- encodedSubjInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
- if (encodedSubjInfoAccess == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- PKIX_CERT_DEBUG
- ("\t\tCalling CERT_FindCertExtensionByOID).\n");
- rv = CERT_FindCertExtensionByOID
- (cert->nssCert, &siaOID, encodedSubjInfoAccess);
-
- if (rv == SECFailure) {
- goto cleanup;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- /* XXX
- * Decode Subject Information Access -
- * since its type is the same as Authority Information
- * Access, reuse the call. NSS- change name to avoid
- * confusion.
- */
- PKIX_CERT_DEBUG
- ("\t\tCalling CERT_DecodeAuthInfoAccessExtension).\n");
- subjInfoAccess = CERT_DecodeAuthInfoAccessExtension
- (arena, encodedSubjInfoAccess);
-
- PKIX_CHECK(pkix_pl_InfoAccess_CreateList
- (subjInfoAccess, &siaList, plContext),
- PKIX_INFOACCESSCREATELISTFAILED);
-
- cert->subjectInfoAccess = siaList;
-
- }
-
- PKIX_OBJECT_UNLOCK(cert);
- }
-
- PKIX_INCREF(cert->subjectInfoAccess);
- *pSiaList = cert->subjectInfoAccess;
-
-cleanup:
- PKIX_OBJECT_UNLOCK(lockedObject);
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- if (encodedSubjInfoAccess != NULL) {
- SECITEM_FreeItem(encodedSubjInfoAccess, PR_TRUE);
- }
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetCrlDp
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetCrlDp(
- PKIX_PL_Cert *cert,
- PKIX_List **pDpList,
- void *plContext)
-{
- PKIX_UInt32 dpIndex = 0;
- pkix_pl_CrlDp *dp = NULL;
- CERTCrlDistributionPoints *dpoints = NULL;
-
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetCrlDp");
- PKIX_NULLCHECK_THREE(cert, cert->nssCert, pDpList);
-
- /* if we don't have a cached copy from before, we create one */
- if (cert->crldpList == NULL) {
- PKIX_OBJECT_LOCK(cert);
- if (cert->crldpList != NULL) {
- goto cleanup;
- }
- PKIX_CHECK(PKIX_List_Create(&cert->crldpList, plContext),
- PKIX_LISTCREATEFAILED);
- dpoints = CERT_FindCRLDistributionPoints(cert->nssCert);
- if (!dpoints || !dpoints->distPoints) {
- goto cleanup;
- }
- for (;dpoints->distPoints[dpIndex];dpIndex++) {
- PKIX_CHECK(
- pkix_pl_CrlDp_Create(dpoints->distPoints[dpIndex],
- &cert->nssCert->issuer,
- &dp, plContext),
- PKIX_CRLDPCREATEFAILED);
- /* Create crldp list in reverse order in attempt to get
- * to the whole crl first. */
- PKIX_CHECK(
- PKIX_List_InsertItem(cert->crldpList, 0,
- (PKIX_PL_Object*)dp,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_DECREF(dp);
- }
- }
-cleanup:
- PKIX_INCREF(cert->crldpList);
- *pDpList = cert->crldpList;
-
- PKIX_OBJECT_UNLOCK(lockedObject);
- PKIX_DECREF(dp);
-
- PKIX_RETURN(CERT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Cert_GetCERTCertificate
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Cert_GetCERTCertificate(
- PKIX_PL_Cert *cert,
- CERTCertificate **pnssCert,
- void *plContext)
-{
- PKIX_ENTER(CERT, "PKIX_PL_Cert_GetNssCert");
- PKIX_NULLCHECK_TWO(cert, pnssCert);
-
- *pnssCert = CERT_DupCertificate(cert->nssCert);
-
- PKIX_RETURN(CERT);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h
deleted file mode 100644
index 56fe64228..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_cert.h
- *
- * Certificate Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_CERT_H
-#define _PKIX_PL_CERT_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_CertStruct {
- CERTCertificate *nssCert; /* Must be the first field. The
- * cert_NSSCertFromPKIXCert function in
- * lib/certhigh/certvfypkix.c depends on
- * this. */
- CERTGeneralName *nssSubjAltNames;
- PLArenaPool *arenaNameConstraints;
- PKIX_PL_X500Name *issuer;
- PKIX_PL_X500Name *subject;
- PKIX_List *subjAltNames;
- PKIX_Boolean subjAltNamesAbsent;
- PKIX_PL_OID *publicKeyAlgId;
- PKIX_PL_PublicKey *publicKey;
- PKIX_PL_BigInt *serialNumber;
- PKIX_List *critExtOids;
- PKIX_PL_ByteArray *subjKeyId;
- PKIX_Boolean subjKeyIdAbsent;
- PKIX_PL_ByteArray *authKeyId;
- PKIX_Boolean authKeyIdAbsent;
- PKIX_List *extKeyUsages;
- PKIX_Boolean extKeyUsagesAbsent;
- PKIX_PL_CertBasicConstraints *certBasicConstraints;
- PKIX_Boolean basicConstraintsAbsent;
- PKIX_List *certPolicyInfos;
- PKIX_Boolean policyInfoAbsent;
- PKIX_Boolean policyMappingsAbsent;
- PKIX_List *certPolicyMappings; /* List of PKIX_PL_CertPolicyMap */
- PKIX_Boolean policyConstraintsProcessed;
- PKIX_Int32 policyConstraintsExplicitPolicySkipCerts;
- PKIX_Int32 policyConstraintsInhibitMappingSkipCerts;
- PKIX_Boolean inhibitAnyPolicyProcessed;
- PKIX_Int32 inhibitAnySkipCerts;
- PKIX_PL_CertNameConstraints *nameConstraints;
- PKIX_Boolean nameConstraintsAbsent;
- PKIX_Boolean cacheFlag;
- PKIX_CertStore *store;
- PKIX_List *authorityInfoAccess; /* list of PKIX_PL_InfoAccess */
- PKIX_List *subjectInfoAccess; /* list of PKIX_PL_InfoAccess */
- PKIX_Boolean isUserTrustAnchor;
- PKIX_List *crldpList; /* list of CRL DPs based on der in nssCert arena.
- * Destruction is needed for pkix object and
- * not for undelying der as it is a part
- * nssCert arena. */
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_Cert_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_pl_Cert_CreateWithNSSCert(
- CERTCertificate *nssCert,
- PKIX_PL_Cert **pCert,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_Cert_CreateToList(
- SECItem *derCertItem,
- PKIX_List *certList,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_Cert_CheckSubjectAltNameConstraints(
- PKIX_PL_Cert *cert,
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_Boolean matchAll,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_Cert_ToString_Helper(
- PKIX_PL_Cert *cert,
- PKIX_Boolean partialString,
- PKIX_PL_String **pString,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_Cert_CheckExtendedKeyUsage(
- PKIX_PL_Cert *cert,
- PKIX_UInt32 requiredExtendedKeyUsages,
- PKIX_Boolean *pPass,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_CERT_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.c
deleted file mode 100644
index a44ac6590..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_certpolicyinfo.c
- *
- * CertPolicyInfo Type Functions
- *
- */
-
-#include "pkix_pl_certpolicyinfo.h"
-
-/*
- * FUNCTION: pkix_pl_CertPolicyInfo_Create
- * DESCRIPTION:
- *
- * Creates a new CertPolicyInfo Object using the OID pointed to by "oid" and
- * the List of CertPolicyQualifiers pointed to by "qualifiers", and stores it
- * at "pObject". If a non-NULL list is provided, the caller is expected to
- * have already set it to be immutable. The caller may provide an empty List,
- * but a NULL List is preferable so a user does not need to call
- * List_GetLength to get the number of qualifiers.
- *
- * PARAMETERS
- * "oid"
- * OID of the desired PolicyInfo ID; must be non-NULL
- * "qualifiers"
- * List of CertPolicyQualifiers; may be NULL or empty
- * "pObject"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CertPolicyInfo_Create(
- PKIX_PL_OID *oid,
- PKIX_List *qualifiers,
- PKIX_PL_CertPolicyInfo **pObject,
- void *plContext)
-{
- PKIX_PL_CertPolicyInfo *policyInfo = NULL;
-
- PKIX_ENTER(CERTPOLICYINFO, "pkix_pl_CertPolicyInfo_Create");
-
- PKIX_NULLCHECK_TWO(oid, pObject);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTPOLICYINFO_TYPE,
- sizeof (PKIX_PL_CertPolicyInfo),
- (PKIX_PL_Object **)&policyInfo,
- plContext),
- PKIX_COULDNOTCREATECERTPOLICYINFOOBJECT);
-
- PKIX_INCREF(oid);
- policyInfo->cpID = oid;
-
- PKIX_INCREF(qualifiers);
- policyInfo->policyQualifiers = qualifiers;
-
- *pObject = policyInfo;
- policyInfo = NULL;
-
-cleanup:
- PKIX_DECREF(policyInfo);
-
- PKIX_RETURN(CERTPOLICYINFO);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyInfo_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyInfo_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_CertPolicyInfo *certPI = NULL;
-
- PKIX_ENTER(CERTPOLICYINFO, "pkix_pl_CertPolicyInfo_Destroy");
-
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYINFO_TYPE, plContext),
- PKIX_OBJECTNOTCERTPOLICYINFO);
-
- certPI = (PKIX_PL_CertPolicyInfo*)object;
-
- PKIX_DECREF(certPI->cpID);
- PKIX_DECREF(certPI->policyQualifiers);
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYINFO);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyInfo_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyInfo_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_CertPolicyInfo *certPI = NULL;
- PKIX_PL_String *oidString = NULL;
- PKIX_PL_String *listString = NULL;
- PKIX_PL_String *format = NULL;
- PKIX_PL_String *outString = NULL;
-
- PKIX_ENTER(CERTPOLICYINFO, "pkix_pl_CertPolicyInfo_ToString");
-
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYINFO_TYPE, plContext),
- PKIX_OBJECTNOTCERTPOLICYINFO);
-
- certPI = (PKIX_PL_CertPolicyInfo *)object;
-
- PKIX_NULLCHECK_ONE(certPI->cpID);
-
- PKIX_TOSTRING
- (certPI->cpID,
- &oidString,
- plContext,
- PKIX_OIDTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (certPI->policyQualifiers,
- &listString,
- plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- /* Put them together in the form OID[Qualifiers] */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "%s[%s]", 0, &format, plContext),
- PKIX_ERRORINSTRINGCREATE);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&outString, plContext, format, oidString, listString),
- PKIX_ERRORINSPRINTF);
-
- *pString = outString;
-
-cleanup:
-
- PKIX_DECREF(oidString);
- PKIX_DECREF(listString);
- PKIX_DECREF(format);
- PKIX_RETURN(CERTPOLICYINFO);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyInfo_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyInfo_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_CertPolicyInfo *certPI = NULL;
- PKIX_UInt32 oidHash = 0;
- PKIX_UInt32 listHash = 0;
-
- PKIX_ENTER(CERTPOLICYINFO, "pkix_pl_CertPolicyInfo_Hashcode");
-
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYINFO_TYPE, plContext),
- PKIX_OBJECTNOTCERTPOLICYINFO);
-
- certPI = (PKIX_PL_CertPolicyInfo *)object;
-
- PKIX_NULLCHECK_ONE(certPI->cpID);
-
- PKIX_HASHCODE
- (certPI->cpID,
- &oidHash,
- plContext,
- PKIX_ERRORINOIDHASHCODE);
-
- PKIX_HASHCODE
- (certPI->policyQualifiers,
- &listHash,
- plContext,
- PKIX_ERRORINLISTHASHCODE);
-
- *pHashcode = (31 * oidHash) + listHash;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYINFO);
-}
-
-
-/*
- * FUNCTION: pkix_pl_CertPolicyInfo_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyInfo_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_CertPolicyInfo *firstCPI = NULL;
- PKIX_PL_CertPolicyInfo *secondCPI = NULL;
- PKIX_UInt32 secondType = 0;
- PKIX_Boolean compare = PKIX_FALSE;
-
- PKIX_ENTER(CERTPOLICYINFO, "pkix_pl_CertPolicyInfo_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a CertPolicyInfo */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_CERTPOLICYINFO_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCERTPOLICYINFO);
-
- /*
- * Since we know firstObject is a CertPolicyInfo,
- * if both references are identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a CertPolicyInfo, we
- * don't throw an error. We simply return FALSE.
- */
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_CERTPOLICYINFO_TYPE) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- firstCPI = (PKIX_PL_CertPolicyInfo *)firstObject;
- secondCPI = (PKIX_PL_CertPolicyInfo *)secondObject;
-
- /*
- * Compare the value of the OID components
- */
-
- PKIX_NULLCHECK_TWO(firstCPI->cpID, secondCPI->cpID);
-
- PKIX_EQUALS
- (firstCPI->cpID,
- secondCPI->cpID,
- &compare,
- plContext,
- PKIX_OIDEQUALSFAILED);
-
- /*
- * If the OIDs did not match, we don't need to
- * compare the Lists. If the OIDs did match,
- * the return value is the value of the
- * List comparison.
- */
- if (compare) {
- PKIX_EQUALS
- (firstCPI->policyQualifiers,
- secondCPI->policyQualifiers,
- &compare,
- plContext,
- PKIX_LISTEQUALSFAILED);
- }
-
- *pResult = compare;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYINFO);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyInfo_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERTPOLICYINFO_TYPE and its related
- * functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize,
- * which should only be called once, it is acceptable that
- * this function is not thread-safe.
- */
-PKIX_Error *
-pkix_pl_CertPolicyInfo_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTPOLICYINFO, "pkix_pl_CertPolicyInfo_RegisterSelf");
-
- entry.description = "CertPolicyInfo";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_CertPolicyInfo);
- entry.destructor = pkix_pl_CertPolicyInfo_Destroy;
- entry.equalsFunction = pkix_pl_CertPolicyInfo_Equals;
- entry.hashcodeFunction = pkix_pl_CertPolicyInfo_Hashcode;
- entry.toStringFunction = pkix_pl_CertPolicyInfo_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_CERTPOLICYINFO_TYPE] = entry;
-
- PKIX_RETURN(CERTPOLICYINFO);
-}
-
-/* --Public-CertPolicyInfo-Functions------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_CertPolicyInfo_GetPolicyId
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CertPolicyInfo_GetPolicyId(
- PKIX_PL_CertPolicyInfo *policyInfo,
- PKIX_PL_OID **pPolicyId,
- void *plContext)
-{
- PKIX_ENTER(CERTPOLICYINFO, "PKIX_PL_CertPolicyInfo_GetPolicyId");
-
- PKIX_NULLCHECK_TWO(policyInfo, pPolicyId);
-
- PKIX_INCREF(policyInfo->cpID);
-
- *pPolicyId = policyInfo->cpID;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYINFO);
-}
-
-/*
- * FUNCTION: PKIX_PL_CertPolicyInfo_GetPolQualifiers
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CertPolicyInfo_GetPolQualifiers(
- PKIX_PL_CertPolicyInfo *policyInfo,
- PKIX_List **pQuals,
- void *plContext)
-{
- PKIX_ENTER(CERTPOLICYINFO, "PKIX_PL_CertPolicyInfo_GetPolQualifiers");
-
- PKIX_NULLCHECK_TWO(policyInfo, pQuals);
-
- PKIX_INCREF(policyInfo->policyQualifiers);
-
- /*
- * This List is created in PKIX_PL_Cert_DecodePolicyInfo
- * and is set immutable immediately after being created.
- */
- *pQuals = policyInfo->policyQualifiers;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYINFO);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h
deleted file mode 100644
index 5c324e6cd..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_certpolicyinfo.h
- *
- * PolicyInfo Type Definitions
- *
- */
-
-#ifndef _PKIX_PL_POLICYINFO_H
-#define _PKIX_PL_POLICYINFO_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * This structure reflects the contents of the policy info extension as
- * described in Section 4.2.1.5 of RFC3280.
- *
- * PolicyInformation ::= SEQUENCE {
- * policyIdentifier CertPolicyId,
- * PolicyQualifiers SEQUENCE SIZE (1..MAX) OF
- * PolicyQualifierInfo OPTIONAL }
- *
- */
-struct PKIX_PL_CertPolicyInfoStruct {
- PKIX_PL_OID *cpID;
- PKIX_List *policyQualifiers; /* LIST of PKIX_PL_CertPolicyQualifier */
-};
-
-PKIX_Error *
-pkix_pl_CertPolicyInfo_Create(
- PKIX_PL_OID *oid,
- PKIX_List *qualifiers,
- PKIX_PL_CertPolicyInfo **pObject,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_CertPolicyInfo_RegisterSelf(
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_POLICYINFO_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.c
deleted file mode 100644
index 08b1ca9df..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_certpolicymap.c
- *
- * CertPolicyMap Type Functions
- *
- */
-
-#include "pkix_pl_certpolicymap.h"
-
-/*
- * FUNCTION: pkix_pl_CertPolicyMap_Create
- * DESCRIPTION:
- *
- * Creates a new CertPolicyMap Object pairing the OID given by
- * "issuerDomainPolicy" with the OID given by "subjectDomainPolicy", and
- * stores the result at "pCertPolicyMap".
- *
- * PARAMETERS
- * "issuerDomainPolicy"
- * Address of the OID of the IssuerDomainPolicy. Must be non-NULL.
- * "subjectDomainPolicy"
- * Address of the OID of the SubjectDomainPolicy. Must be non-NULL.
- * "pCertPolicyMap"
- * Address where CertPolicyMap pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CertPolicyMap Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CertPolicyMap_Create(
- PKIX_PL_OID *issuerDomainPolicy,
- PKIX_PL_OID *subjectDomainPolicy,
- PKIX_PL_CertPolicyMap **pCertPolicyMap,
- void *plContext)
-{
- PKIX_PL_CertPolicyMap *policyMap = NULL;
-
- PKIX_ENTER(CERTPOLICYMAP, "pkix_pl_CertPolicyMap_Create");
-
- PKIX_NULLCHECK_THREE
- (issuerDomainPolicy, subjectDomainPolicy, pCertPolicyMap);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTPOLICYMAP_TYPE,
- sizeof (PKIX_PL_CertPolicyMap),
- (PKIX_PL_Object **)&policyMap,
- plContext),
- PKIX_COULDNOTCREATECERTPOLICYMAPOBJECT);
-
- PKIX_INCREF(issuerDomainPolicy);
- policyMap->issuerDomainPolicy = issuerDomainPolicy;
-
- PKIX_INCREF(subjectDomainPolicy);
- policyMap->subjectDomainPolicy = subjectDomainPolicy;
-
- *pCertPolicyMap = policyMap;
- policyMap = NULL;
-
-cleanup:
- PKIX_DECREF(policyMap);
-
- PKIX_RETURN(CERTPOLICYMAP);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyMap_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyMap_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_CertPolicyMap *certMap = NULL;
-
- PKIX_ENTER(CERTPOLICYMAP, "pkix_pl_CertPolicyMap_Destroy");
-
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYMAP_TYPE, plContext),
- PKIX_OBJECTNOTCERTPOLICYMAP);
-
- certMap = (PKIX_PL_CertPolicyMap*)object;
-
- PKIX_DECREF(certMap->issuerDomainPolicy);
- PKIX_DECREF(certMap->subjectDomainPolicy);
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYMAP);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyMap_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyMap_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_CertPolicyMap *certMap = NULL;
- PKIX_PL_String *format = NULL;
- PKIX_PL_String *outString = NULL;
- PKIX_PL_String *issuerString = NULL;
- PKIX_PL_String *subjectString = NULL;
-
- PKIX_ENTER(CERTPOLICYMAP, "pkix_pl_CertPolicyMap_ToString");
-
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYMAP_TYPE, plContext),
- PKIX_OBJECTNOTCERTPOLICYMAP);
-
- certMap = (PKIX_PL_CertPolicyMap *)object;
-
- PKIX_TOSTRING
- (certMap->issuerDomainPolicy,
- &issuerString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- PKIX_TOSTRING
- (certMap->subjectDomainPolicy,
- &subjectString,
- plContext,
- PKIX_OBJECTTOSTRINGFAILED);
-
- /* Put them together in the form issuerPolicy=>subjectPolicy */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "%s=>%s", 0, &format, plContext),
- PKIX_ERRORINSTRINGCREATE);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&outString, plContext, format, issuerString, subjectString),
- PKIX_ERRORINSPRINTF);
-
- *pString = outString;
-
-cleanup:
- PKIX_DECREF(format);
- PKIX_DECREF(issuerString);
- PKIX_DECREF(subjectString);
-
- PKIX_RETURN(CERTPOLICYMAP);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyMap_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyMap_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_UInt32 issuerHash = 0;
- PKIX_UInt32 subjectHash = 0;
- PKIX_PL_CertPolicyMap *certMap = NULL;
-
- PKIX_ENTER(CERTPOLICYMAP, "pkix_pl_CertPolicyMap_Hashcode");
-
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYMAP_TYPE, plContext),
- PKIX_OBJECTNOTCERTPOLICYMAP);
-
- certMap = (PKIX_PL_CertPolicyMap *)object;
-
- PKIX_HASHCODE
- (certMap->issuerDomainPolicy,
- &issuerHash,
- plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_HASHCODE
- (certMap->subjectDomainPolicy,
- &subjectHash,
- plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- *pHashcode = issuerHash*31 + subjectHash;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYMAP);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyMap_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyMap_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_CertPolicyMap *firstCertMap = NULL;
- PKIX_PL_CertPolicyMap *secondCertMap = NULL;
- PKIX_UInt32 secondType = 0;
- PKIX_Boolean compare = PKIX_FALSE;
-
- PKIX_ENTER(CERTPOLICYMAP, "pkix_pl_CertPolicyMap_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a CertPolicyMap */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_CERTPOLICYMAP_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCERTPOLICYMAP);
-
- /*
- * Since we know firstObject is a CertPolicyMap,
- * if both references are identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a CertPolicyMap, we
- * don't throw an error. We simply return FALSE.
- */
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_CERTPOLICYMAP_TYPE) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- firstCertMap = (PKIX_PL_CertPolicyMap *)firstObject;
- secondCertMap = (PKIX_PL_CertPolicyMap *)secondObject;
-
- PKIX_EQUALS
- (firstCertMap->issuerDomainPolicy,
- secondCertMap->issuerDomainPolicy,
- &compare,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (compare) {
- PKIX_EQUALS
- (firstCertMap->subjectDomainPolicy,
- secondCertMap->subjectDomainPolicy,
- &compare,
- plContext,
- PKIX_OBJECTEQUALSFAILED);
- }
-
- *pResult = compare;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYMAP);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyMap_Duplicate
- * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyMap_Duplicate(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_PL_CertPolicyMap *original = NULL;
- PKIX_PL_CertPolicyMap *copy = NULL;
-
- PKIX_ENTER(CERTPOLICYMAP, "pkix_pl_CertPolicyMap_Duplicate");
-
- PKIX_NULLCHECK_TWO(object, pNewObject);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTPOLICYMAP_TYPE, plContext),
- PKIX_OBJECTARGUMENTNOTPOLICYMAP);
-
- original = (PKIX_PL_CertPolicyMap *)object;
-
- PKIX_CHECK(pkix_pl_CertPolicyMap_Create
- (original->issuerDomainPolicy,
- original->subjectDomainPolicy,
- &copy,
- plContext),
- PKIX_CERTPOLICYMAPCREATEFAILED);
-
- *pNewObject = (PKIX_PL_Object *)copy;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYMAP);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyMap_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERTPOLICYMAP_TYPE and its related
- * functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize,
- * which should only be called once, it is acceptable that
- * this function is not thread-safe.
- */
-PKIX_Error *
-pkix_pl_CertPolicyMap_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTPOLICYMAP, "pkix_pl_CertPolicyMap_RegisterSelf");
-
- entry.description = "CertPolicyMap";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_CertPolicyMap);
- entry.destructor = pkix_pl_CertPolicyMap_Destroy;
- entry.equalsFunction = pkix_pl_CertPolicyMap_Equals;
- entry.hashcodeFunction = pkix_pl_CertPolicyMap_Hashcode;
- entry.toStringFunction = pkix_pl_CertPolicyMap_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_pl_CertPolicyMap_Duplicate;
-
- systemClasses[PKIX_CERTPOLICYMAP_TYPE] = entry;
-
- PKIX_RETURN(CERTPOLICYMAP);
-}
-
-/* --Public-CertPolicyMap-Functions------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy(
- PKIX_PL_CertPolicyMap *policyMapping,
- PKIX_PL_OID **pIssuerDomainPolicy,
- void *plContext)
-{
- PKIX_ENTER
- (CERTPOLICYMAP, "PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy");
-
- PKIX_NULLCHECK_TWO(policyMapping, pIssuerDomainPolicy);
-
- PKIX_INCREF(policyMapping->issuerDomainPolicy);
- *pIssuerDomainPolicy = policyMapping->issuerDomainPolicy;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYMAP);
-}
-
-/*
- * FUNCTION: PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy(
- PKIX_PL_CertPolicyMap *policyMapping,
- PKIX_PL_OID **pSubjectDomainPolicy,
- void *plContext)
-{
- PKIX_ENTER
- (CERTPOLICYMAP, "PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy");
-
- PKIX_NULLCHECK_TWO(policyMapping, pSubjectDomainPolicy);
-
- PKIX_INCREF(policyMapping->subjectDomainPolicy);
- *pSubjectDomainPolicy = policyMapping->subjectDomainPolicy;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYMAP);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.h
deleted file mode 100644
index a03bce2c8..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_certpolicymap.h
- *
- * CertPolicyMap Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_CERTPOLICYMAP_H
-#define _PKIX_PL_CERTPOLICYMAP_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * This structure reflects the contents of the policy mapping extension as
- * described in Section 4.2.1.6 of RFC3280.
- *
- * PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
- * issuerDomainPolicy CertPolicyId,
- * subjectDomainPolicy CertPolicyId }
- *
- */
-struct PKIX_PL_CertPolicyMapStruct {
- PKIX_PL_OID *issuerDomainPolicy;
- PKIX_PL_OID *subjectDomainPolicy;
-};
-
-PKIX_Error *
-pkix_pl_CertPolicyMap_Create(
- PKIX_PL_OID *issuerDomainPolicy,
- PKIX_PL_OID *subjectDomainPolicy,
- PKIX_PL_CertPolicyMap **pObject,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_CertPolicyMap_RegisterSelf(
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_CERTPOLICYMAP_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.c
deleted file mode 100644
index b57623d26..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_certpolicyqualifier.c
- *
- * CertPolicyQualifier Type Functions
- *
- */
-
-#include "pkix_pl_certpolicyqualifier.h"
-
-/*
- * FUNCTION: pkix_pl_CertPolicyQualifier_Create
- * DESCRIPTION:
- *
- * Creates a CertPolicyQualifier object with the OID given by "oid"
- * and the ByteArray given by "qualifier", and stores it at "pObject".
- *
- * PARAMETERS
- * "oid"
- * Address of OID of the desired policyQualifierId; must be non-NULL
- * "qualifier"
- * Address of ByteArray with the desired value of the qualifier;
- * must be non-NULL
- * "pObject"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CertPolicyQualifier_Create(
- PKIX_PL_OID *oid,
- PKIX_PL_ByteArray *qualifier,
- PKIX_PL_CertPolicyQualifier **pObject,
- void *plContext)
-{
- PKIX_PL_CertPolicyQualifier *qual = NULL;
-
- PKIX_ENTER(CERTPOLICYQUALIFIER, "pkix_pl_CertPolicyQualifier_Create");
-
- PKIX_NULLCHECK_THREE(oid, qualifier, pObject);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTPOLICYQUALIFIER_TYPE,
- sizeof (PKIX_PL_CertPolicyQualifier),
- (PKIX_PL_Object **)&qual,
- plContext),
- PKIX_COULDNOTCREATECERTPOLICYQUALIFIEROBJECT);
-
- PKIX_INCREF(oid);
- qual->policyQualifierId = oid;
-
- PKIX_INCREF(qualifier);
- qual->qualifier = qualifier;
-
- *pObject = qual;
- qual = NULL;
-
-cleanup:
- PKIX_DECREF(qual);
-
- PKIX_RETURN(CERTPOLICYQUALIFIER);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyQualifier_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyQualifier_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_CertPolicyQualifier *certPQ = NULL;
-
- PKIX_ENTER(CERTPOLICYQUALIFIER, "pkix_pl_CertPolicyQualifier_Destroy");
-
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTPOLICYQUALIFIER_TYPE, plContext),
- PKIX_OBJECTNOTCERTPOLICYQUALIFIER);
-
- certPQ = (PKIX_PL_CertPolicyQualifier*)object;
-
- PKIX_DECREF(certPQ->policyQualifierId);
- PKIX_DECREF(certPQ->qualifier);
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYQUALIFIER);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyQualifier_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyQualifier_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_CertPolicyQualifier *certPQ = NULL;
- char *asciiFormat = "%s:%s";
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *pqIDString = NULL;
- PKIX_PL_String *pqValString = NULL;
- PKIX_PL_String *outString = NULL;
-
- PKIX_ENTER(CERTPOLICYQUALIFIER, "pkix_pl_CertPolicyQualifier_ToString");
-
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTPOLICYQUALIFIER_TYPE, plContext),
- PKIX_OBJECTNOTCERTPOLICYQUALIFIER);
-
- certPQ = (PKIX_PL_CertPolicyQualifier *)object;
-
- /*
- * The policyQualifierId is required. If there is no qualifier,
- * we should have a ByteArray of zero length.
- */
- PKIX_NULLCHECK_TWO(certPQ->policyQualifierId, certPQ->qualifier);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_TOSTRING(certPQ->policyQualifierId, &pqIDString, plContext,
- PKIX_OIDTOSTRINGFAILED);
-
- PKIX_CHECK(pkix_pl_ByteArray_ToHexString
- (certPQ->qualifier, &pqValString, plContext),
- PKIX_BYTEARRAYTOHEXSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&outString, plContext, formatString, pqIDString, pqValString),
- PKIX_SPRINTFFAILED);
-
- *pString = outString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(pqIDString);
- PKIX_DECREF(pqValString);
- PKIX_RETURN(CERTPOLICYQUALIFIER);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyQualifier_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyQualifier_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_CertPolicyQualifier *certPQ = NULL;
- PKIX_UInt32 cpidHash = 0;
- PKIX_UInt32 cpqHash = 0;
-
- PKIX_ENTER(CERTPOLICYQUALIFIER, "pkix_pl_CertPolicyQualifier_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTPOLICYQUALIFIER_TYPE, plContext),
- PKIX_OBJECTNOTCERTPOLICYQUALIFIER);
-
- certPQ = (PKIX_PL_CertPolicyQualifier *)object;
-
- PKIX_NULLCHECK_TWO(certPQ->policyQualifierId, certPQ->qualifier);
-
- PKIX_HASHCODE(certPQ->policyQualifierId, &cpidHash, plContext,
- PKIX_ERRORINOIDHASHCODE);
-
- PKIX_HASHCODE(certPQ->qualifier, &cpqHash, plContext,
- PKIX_ERRORINBYTEARRAYHASHCODE);
-
- *pHashcode = cpidHash*31 + cpqHash;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYQUALIFIER);
-}
-
-
-/*
- * FUNCTION: pkix_pl_CertPolicyQualifier_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertPolicyQualifier_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_CertPolicyQualifier *firstCPQ = NULL;
- PKIX_PL_CertPolicyQualifier *secondCPQ = NULL;
- PKIX_UInt32 secondType = 0;
- PKIX_Boolean compare = PKIX_FALSE;
-
- PKIX_ENTER(CERTPOLICYQUALIFIER, "pkix_pl_CertPolicyQualifier_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a CertPolicyQualifier */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_CERTPOLICYQUALIFIER_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCERTPOLICYQUALIFIER);
-
- /*
- * Since we know firstObject is a CertPolicyQualifier,
- * if both references are identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a CertPolicyQualifier, we
- * don't throw an error. We simply return FALSE.
- */
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_CERTPOLICYQUALIFIER_TYPE) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- firstCPQ = (PKIX_PL_CertPolicyQualifier *)firstObject;
- secondCPQ = (PKIX_PL_CertPolicyQualifier *)secondObject;
-
- /*
- * Compare the value of the OID components
- */
-
- PKIX_NULLCHECK_TWO
- (firstCPQ->policyQualifierId, secondCPQ->policyQualifierId);
-
- PKIX_EQUALS
- (firstCPQ->policyQualifierId,
- secondCPQ->policyQualifierId,
- &compare,
- plContext,
- PKIX_OIDEQUALSFAILED);
-
- /*
- * If the OIDs did not match, we don't need to
- * compare the ByteArrays. If the OIDs did match,
- * the return value is the value of the
- * ByteArray comparison.
- */
- if (compare) {
- PKIX_NULLCHECK_TWO(firstCPQ->qualifier, secondCPQ->qualifier);
-
- PKIX_EQUALS
- (firstCPQ->qualifier,
- secondCPQ->qualifier,
- &compare,
- plContext,
- PKIX_BYTEARRAYEQUALSFAILED);
- }
-
- *pResult = compare;
-
-cleanup:
-
- PKIX_RETURN(CERTPOLICYQUALIFIER);
-}
-
-/*
- * FUNCTION: pkix_pl_CertPolicyQualifier_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERTPOLICYQUALIFIER_TYPE and its related
- * functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize,
- * which should only be called once, it is acceptable that
- * this function is not thread-safe.
- */
-PKIX_Error *
-pkix_pl_CertPolicyQualifier_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTPOLICYQUALIFIER,
- "pkix_pl_CertPolicyQualifier_RegisterSelf");
-
- entry.description = "CertPolicyQualifier";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_CertPolicyQualifier);
- entry.destructor = pkix_pl_CertPolicyQualifier_Destroy;
- entry.equalsFunction = pkix_pl_CertPolicyQualifier_Equals;
- entry.hashcodeFunction = pkix_pl_CertPolicyQualifier_Hashcode;
- entry.toStringFunction = pkix_pl_CertPolicyQualifier_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_CERTPOLICYQUALIFIER_TYPE] = entry;
-
- PKIX_RETURN(CERTPOLICYQUALIFIER);
-}
-
-/* --Public-CertPolicyQualifier-Functions------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_PolicyQualifier_GetPolicyQualifierId
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_PolicyQualifier_GetPolicyQualifierId(
- PKIX_PL_CertPolicyQualifier *policyQualifierInfo,
- PKIX_PL_OID **pPolicyQualifierId,
- void *plContext)
-{
- PKIX_ENTER(CERTPOLICYQUALIFIER,
- "PKIX_PL_PolicyQualifier_GetPolicyQualifierId");
-
- PKIX_NULLCHECK_TWO(policyQualifierInfo, pPolicyQualifierId);
-
- PKIX_INCREF(policyQualifierInfo->policyQualifierId);
-
- *pPolicyQualifierId = policyQualifierInfo->policyQualifierId;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYQUALIFIER);
-}
-
-/*
- * FUNCTION: PKIX_PL_PolicyQualifier_GetQualifier
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_PolicyQualifier_GetQualifier(
- PKIX_PL_CertPolicyQualifier *policyQualifierInfo,
- PKIX_PL_ByteArray **pQualifier,
- void *plContext)
-{
- PKIX_ENTER(CERTPOLICYQUALIFIER, "PKIX_PL_PolicyQualifier_GetQualifier");
-
- PKIX_NULLCHECK_TWO(policyQualifierInfo, pQualifier);
-
- PKIX_INCREF(policyQualifierInfo->qualifier);
-
- *pQualifier = policyQualifierInfo->qualifier;
-
-cleanup:
- PKIX_RETURN(CERTPOLICYQUALIFIER);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.h
deleted file mode 100644
index 4c6c8a21b..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_certpolicyqualifier.h
- *
- * PolicyQualifier Type Definitions
- *
- */
-
-#ifndef _PKIX_PL_POLICYQUALIFIER_H
-#define _PKIX_PL_POLICYQUALIFIER_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * This structure reflects the contents of the policy qualifier extension as
- * described in Section 4.2.1.5 of RFC3280.
- *
- * PolicyQualifierInfo ::= SEQUENCE {
- * policyQualifierId PolicyQualifierId,
- * qualifier ANY DEFINED BY policyQualifierId }
- *
- * PolicyQualifierId ::=
- * OBJECT IDENTIFIER (id-qt-cps | id-qt-unotice)
- *
- */
-struct PKIX_PL_CertPolicyQualifierStruct {
- PKIX_PL_OID *policyQualifierId;
- PKIX_PL_ByteArray *qualifier;
-};
-
-PKIX_Error *
-pkix_pl_CertPolicyQualifier_Create(
- PKIX_PL_OID *oid,
- PKIX_PL_ByteArray *qualifierArray,
- PKIX_PL_CertPolicyQualifier **pObject,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_CertPolicyQualifier_RegisterSelf(
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_POLICYQUALIFIER_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c
deleted file mode 100644
index 0f6d78333..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c
+++ /dev/null
@@ -1,1068 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_crl.c
- *
- * CRL Function Definitions
- *
- */
-
-#include "pkix_pl_crl.h"
-#include "certxutl.h"
-
-extern PKIX_PL_HashTable *cachedCrlSigTable;
-
-/* --Private-CRL-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_CRL_GetVersion
- * DESCRIPTION:
- *
- * Retrieves the version of the CRL pointed to by "crl" and stores it at
- * "pVersion". The version number will either be 0 or 1 (corresponding to
- * v1 or v2, respectively).
- *
- * Version ::= INTEGER { v1(0), v2(1), v3(2) }
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose version is to be stored. Must be non-NULL.
- * "pVersion"
- * Address where a version will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CRL_GetVersion(
- PKIX_PL_CRL *crl,
- PKIX_UInt32 *pVersion,
- void *plContext)
-{
- PKIX_UInt32 myVersion;
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_GetVersion");
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pVersion);
-
- PKIX_NULLCHECK_ONE(crl->nssSignedCrl->crl.version.data);
-
- myVersion = *(crl->nssSignedCrl->crl.version.data);
-
- if (myVersion > 1) {
- PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1ORV2);
- }
-
- *pVersion = myVersion;
-
-cleanup:
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: PKIX_PL_CRL_GetCRLNumber (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CRL_GetCRLNumber(
- PKIX_PL_CRL *crl,
- PKIX_PL_BigInt **pCrlNumber,
- void *plContext)
-{
- PKIX_PL_BigInt *crlNumber = NULL;
- SECItem nssCrlNumber;
- PLArenaPool *arena = NULL;
- SECStatus status;
- PKIX_UInt32 length = 0;
- char *bytes = NULL;
-
- PKIX_ENTER(CRL, "PKIX_PL_CRL_GetCRLNumber");
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCrlNumber);
-
- /* Can call this function only with der been adopted. */
- PORT_Assert(crl->adoptedDerCrl);
-
- if (!crl->crlNumberAbsent && crl->crlNumber == NULL) {
-
- PKIX_OBJECT_LOCK(crl);
-
- if (!crl->crlNumberAbsent && crl->crlNumber == NULL) {
-
- nssCrlNumber.type = 0;
- nssCrlNumber.len = 0;
- nssCrlNumber.data = NULL;
-
- PKIX_CRL_DEBUG("\t\tCalling PORT_NewArena).\n");
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- PKIX_CRL_DEBUG("\t\tCalling CERT_FindCRLNumberExten\n");
- status = CERT_FindCRLNumberExten
- (arena, &crl->nssSignedCrl->crl, &nssCrlNumber);
-
- if (status == SECSuccess) {
- /* Get data in bytes then convert to bigint */
- length = nssCrlNumber.len;
- bytes = (char *)nssCrlNumber.data;
-
- PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
- (bytes, length, &crlNumber, plContext),
- PKIX_BIGINTCREATEWITHBYTESFAILED);
-
- /* arena release does the job
- PKIX_CRL_DEBUG("\t\tCalling SECITEM_FreeItem\n");
- SECITEM_FreeItem(&nssCrlNumber, PKIX_FALSE);
- */
- crl->crlNumber = crlNumber;
-
- } else {
-
- crl->crlNumberAbsent = PKIX_TRUE;
- }
- }
-
- PKIX_OBJECT_UNLOCK(crl);
-
- }
-
- PKIX_INCREF(crl->crlNumber);
-
- *pCrlNumber = crl->crlNumber;
-
-cleanup:
-
- if (arena){
- PKIX_CRL_DEBUG("\t\tCalling PORT_FreeArena).\n");
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: pkix_pl_CRL_GetSignatureAlgId
- *
- * DESCRIPTION:
- * Retrieves a pointer to the OID that represents the signature algorithm of
- * the CRL pointed to by "crl" and stores it at "pSignatureAlgId".
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL }
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose signature algorithm OID is to be stored.
- * Must be non-NULL.
- * "pSignatureAlgId"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CRL_GetSignatureAlgId(
- PKIX_PL_CRL *crl,
- PKIX_PL_OID **pSignatureAlgId,
- void *plContext)
-{
- PKIX_PL_OID *signatureAlgId = NULL;
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_GetSignatureAlgId");
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pSignatureAlgId);
-
- /* if we don't have a cached copy from before, we create one */
- if (crl->signatureAlgId == NULL){
- PKIX_OBJECT_LOCK(crl);
- if (crl->signatureAlgId == NULL){
- CERTCrl *nssCrl = &(crl->nssSignedCrl->crl);
- SECAlgorithmID *algorithm = &nssCrl->signatureAlg;
- SECItem *algBytes = &algorithm->algorithm;
-
- if (!algBytes->data || !algBytes->len) {
- PKIX_ERROR(PKIX_OIDBYTESLENGTH0);
- }
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
- (algBytes, &signatureAlgId, plContext),
- PKIX_OIDCREATEFAILED);
-
- /* save a cached copy in case it is asked for again */
- crl->signatureAlgId = signatureAlgId;
- signatureAlgId = NULL;
- }
- PKIX_OBJECT_UNLOCK(crl);
- }
- PKIX_INCREF(crl->signatureAlgId);
- *pSignatureAlgId = crl->signatureAlgId;
-cleanup:
- PKIX_DECREF(signatureAlgId);
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: pkix_pl_CRL_GetCRLEntries
- * DESCRIPTION:
- *
- * Retrieves a pointer to the List of CRLEntries found in the CRL pointed to
- * by "crl" and stores it at "pCRLEntries". If there are no CRLEntries,
- * this functions stores NULL at "pCRLEntries".
- *
- * PARAMETERS:
- * "crl"
- * Address of CRL whose CRL Entries are to be retrieved. Must be non-NULL.
- * "pCRLEntries"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CRL_GetCRLEntries(
- PKIX_PL_CRL *crl,
- PKIX_List **pCrlEntries,
- void *plContext)
-{
- PKIX_List *entryList = NULL;
- CERTCrl *nssCrl = NULL;
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_GetCRLEntries");
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCrlEntries);
-
- /* if we don't have a cached copy from before, we create one */
- if (crl->crlEntryList == NULL) {
-
- PKIX_OBJECT_LOCK(crl);
-
- if (crl->crlEntryList == NULL){
-
- nssCrl = &(crl->nssSignedCrl->crl);
-
- PKIX_CHECK(pkix_pl_CRLEntry_Create
- (nssCrl->entries, &entryList, plContext),
- PKIX_CRLENTRYCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_SetImmutable
- (entryList, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- crl->crlEntryList = entryList;
- }
-
- PKIX_OBJECT_UNLOCK(crl);
-
- }
-
- PKIX_INCREF(crl->crlEntryList);
-
- *pCrlEntries = crl->crlEntryList;
-
-cleanup:
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: pkix_pl_CRL_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CRL_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_CRL *crl = NULL;
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext),
- PKIX_OBJECTNOTCRL);
-
- crl = (PKIX_PL_CRL*)object;
-
- PKIX_CRL_DEBUG("\t\tCalling CERT_DestroyCrl\n");
- if (crl->nssSignedCrl) {
- CERT_DestroyCrl(crl->nssSignedCrl);
- }
- if (crl->adoptedDerCrl) {
- SECITEM_FreeItem(crl->adoptedDerCrl, PR_TRUE);
- }
- crl->nssSignedCrl = NULL;
- crl->adoptedDerCrl = NULL;
- crl->crlNumberAbsent = PKIX_FALSE;
-
- PKIX_DECREF(crl->issuer);
- PKIX_DECREF(crl->signatureAlgId);
- PKIX_DECREF(crl->crlNumber);
- PKIX_DECREF(crl->crlEntryList);
- PKIX_DECREF(crl->critExtOids);
- if (crl->derGenName) {
- SECITEM_FreeItem(crl->derGenName, PR_TRUE);
- }
-
-cleanup:
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: pkix_pl_CRL_ToString_Helper
- * DESCRIPTION:
- *
- * Helper function that creates a string representation of the CRL pointed
- * to by "crl" and stores it at "pString".
- *
- * PARAMETERS
- * "crl"
- * Address of CRL whose string representation is desired.
- * Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CRL_ToString_Helper(
- PKIX_PL_CRL *crl,
- PKIX_PL_String **pString,
- void *plContext)
-{
- char *asciiFormat = NULL;
- PKIX_UInt32 crlVersion;
- PKIX_PL_X500Name *crlIssuer = NULL;
- PKIX_PL_OID *nssSignatureAlgId = NULL;
- PKIX_PL_BigInt *crlNumber = NULL;
- PKIX_List *crlEntryList = NULL;
- PKIX_List *critExtOIDs = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *crlIssuerString = NULL;
- PKIX_PL_String *lastUpdateString = NULL;
- PKIX_PL_String *nextUpdateString = NULL;
- PKIX_PL_String *nssSignatureAlgIdString = NULL;
- PKIX_PL_String *crlNumberString = NULL;
- PKIX_PL_String *crlEntryListString = NULL;
- PKIX_PL_String *critExtOIDsString = NULL;
- PKIX_PL_String *crlString = NULL;
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_ToString_Helper");
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pString);
-
- asciiFormat =
- "[\n"
- "\tVersion: v%d\n"
- "\tIssuer: %s\n"
- "\tUpdate: [Last: %s\n"
- "\t Next: %s]\n"
- "\tSignatureAlgId: %s\n"
- "\tCRL Number : %s\n"
- "\n"
- "\tEntry List: %s\n"
- "\n"
- "\tCritExtOIDs: %s\n"
- "]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- /* Version */
- PKIX_CHECK(pkix_pl_CRL_GetVersion(crl, &crlVersion, plContext),
- PKIX_CRLGETVERSIONFAILED);
-
- /* Issuer */
- PKIX_CHECK(PKIX_PL_CRL_GetIssuer(crl, &crlIssuer, plContext),
- PKIX_CRLGETISSUERFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)crlIssuer, &crlIssuerString, plContext),
- PKIX_X500NAMETOSTRINGFAILED);
-
- /* This update - No Date object created, use nss data directly */
- PKIX_CHECK(pkix_pl_Date_ToString_Helper
- (&(crl->nssSignedCrl->crl.lastUpdate),
- &lastUpdateString,
- plContext),
- PKIX_DATETOSTRINGHELPERFAILED);
-
- /* Next update - No Date object created, use nss data directly */
- PKIX_CHECK(pkix_pl_Date_ToString_Helper
- (&(crl->nssSignedCrl->crl.nextUpdate),
- &nextUpdateString,
- plContext),
- PKIX_DATETOSTRINGHELPERFAILED);
-
- /* Signature Algorithm Id */
- PKIX_CHECK(pkix_pl_CRL_GetSignatureAlgId
- (crl, &nssSignatureAlgId, plContext),
- PKIX_CRLGETSIGNATUREALGIDFAILED);
-
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)nssSignatureAlgId,
- &nssSignatureAlgIdString,
- plContext),
- PKIX_OIDTOSTRINGFAILED);
-
- /* CRL Number */
- PKIX_CHECK(PKIX_PL_CRL_GetCRLNumber
- (crl, &crlNumber, plContext),
- PKIX_CRLGETCRLNUMBERFAILED);
-
- PKIX_TOSTRING(crlNumber, &crlNumberString, plContext,
- PKIX_BIGINTTOSTRINGFAILED);
-
- /* CRL Entries */
- PKIX_CHECK(pkix_pl_CRL_GetCRLEntries(crl, &crlEntryList, plContext),
- PKIX_CRLGETCRLENTRIESFAILED);
-
- PKIX_TOSTRING(crlEntryList, &crlEntryListString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- /* CriticalExtensionOIDs */
- PKIX_CHECK(PKIX_PL_CRL_GetCriticalExtensionOIDs
- (crl, &critExtOIDs, plContext),
- PKIX_CRLGETCRITICALEXTENSIONOIDSFAILED);
-
- PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&crlString,
- plContext,
- formatString,
- crlVersion + 1,
- crlIssuerString,
- lastUpdateString,
- nextUpdateString,
- nssSignatureAlgIdString,
- crlNumberString,
- crlEntryListString,
- critExtOIDsString),
- PKIX_SPRINTFFAILED);
-
- *pString = crlString;
-
-cleanup:
-
- PKIX_DECREF(crlIssuer);
- PKIX_DECREF(nssSignatureAlgId);
- PKIX_DECREF(crlNumber);
- PKIX_DECREF(crlEntryList);
- PKIX_DECREF(critExtOIDs);
- PKIX_DECREF(crlIssuerString);
- PKIX_DECREF(lastUpdateString);
- PKIX_DECREF(nextUpdateString);
- PKIX_DECREF(nssSignatureAlgIdString);
- PKIX_DECREF(crlNumberString);
- PKIX_DECREF(crlEntryListString);
- PKIX_DECREF(critExtOIDsString);
- PKIX_DECREF(formatString);
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: pkix_pl_CRL_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CRL_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *crlString = NULL;
- PKIX_PL_CRL *crl = NULL;
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext),
- PKIX_OBJECTNOTCRL);
-
- crl = (PKIX_PL_CRL *) object;
-
- PKIX_CHECK(pkix_pl_CRL_ToString_Helper(crl, &crlString, plContext),
- PKIX_CRLTOSTRINGHELPERFAILED);
-
- *pString = crlString;
-
-cleanup:
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: pkix_pl_CRL_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CRL_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_CRL *crl = NULL;
- PKIX_UInt32 certHash;
- SECItem *crlDer = NULL;
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext),
- PKIX_OBJECTNOTCRL);
-
- crl = (PKIX_PL_CRL *)object;
- if (crl->adoptedDerCrl) {
- crlDer = crl->adoptedDerCrl;
- } else if (crl->nssSignedCrl && crl->nssSignedCrl->derCrl) {
- crlDer = crl->nssSignedCrl->derCrl;
- }
- if (!crlDer || !crlDer->data) {
- PKIX_ERROR(PKIX_CANNOTAQUIRECRLDER);
- }
-
- PKIX_CHECK(pkix_hash(crlDer->data, crlDer->len,
- &certHash, plContext),
- PKIX_ERRORINHASH);
-
- *pHashcode = certHash;
-
-cleanup:
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: pkix_pl_CRL_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CRL_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_CRL *firstCrl = NULL;
- PKIX_PL_CRL *secondCrl = NULL;
- SECItem *crlDerOne = NULL, *crlDerTwo = NULL;
- PKIX_UInt32 secondType;
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a CRL */
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CRL_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCRL);
-
- firstCrl = (PKIX_PL_CRL *)firstObject;
- secondCrl = (PKIX_PL_CRL *)secondObject;
-
- /*
- * Since we know firstObject is a CRL, if both references are
- * identical, they must be equal
- */
- if (firstCrl == secondCrl){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondCrl isn't a CRL, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- ((PKIX_PL_Object *)secondCrl, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_CRL_TYPE) goto cleanup;
-
- if (firstCrl->adoptedDerCrl) {
- crlDerOne = firstCrl->adoptedDerCrl;
- } else if (firstCrl->nssSignedCrl && firstCrl->nssSignedCrl->derCrl) {
- crlDerOne = firstCrl->nssSignedCrl->derCrl;
- }
-
- if (secondCrl->adoptedDerCrl) {
- crlDerTwo = secondCrl->adoptedDerCrl;
- } else if (secondCrl->nssSignedCrl && secondCrl->nssSignedCrl->derCrl) {
- crlDerTwo = secondCrl->nssSignedCrl->derCrl;
- }
-
- if (SECITEM_CompareItem(crlDerOne, crlDerTwo) == SECEqual) {
- *pResult = PKIX_TRUE;
- }
-
-cleanup:
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: pkix_pl_CRL_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_CRL_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- *
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_CRL_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry *entry = &systemClasses[PKIX_CRL_TYPE];
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_RegisterSelf");
-
- entry->description = "CRL";
- entry->typeObjectSize = sizeof(PKIX_PL_CRL);
- entry->destructor = pkix_pl_CRL_Destroy;
- entry->equalsFunction = pkix_pl_CRL_Equals;
- entry->hashcodeFunction = pkix_pl_CRL_Hashcode;
- entry->toStringFunction = pkix_pl_CRL_ToString;
- entry->duplicateFunction = pkix_duplicateImmutable;
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: PKIX_PL_CRL_VerifyUpdateTime (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CRL_VerifyUpdateTime(
- PKIX_PL_CRL *crl,
- PKIX_PL_Date *date,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PRTime timeToCheck;
- PRTime nextUpdate;
- PRTime lastUpdate;
- SECStatus status;
- CERTCrl *nssCrl = NULL;
- SECItem *nextUpdateDer = NULL;
- PKIX_Boolean haveNextUpdate = PR_FALSE;
-
- PKIX_ENTER(CRL, "PKIX_PL_CRL_VerifyUpdateTime");
- PKIX_NULLCHECK_FOUR(crl, crl->nssSignedCrl, date, pResult);
-
- /* Can call this function only with der been adopted. */
- PORT_Assert(crl->adoptedDerCrl);
-
- nssCrl = &(crl->nssSignedCrl->crl);
- timeToCheck = date->nssTime;
-
- /* nextUpdate can be NULL. Checking before using it */
- nextUpdateDer = &nssCrl->nextUpdate;
- if (nextUpdateDer->data && nextUpdateDer->len) {
- haveNextUpdate = PR_TRUE;
- status = DER_DecodeTimeChoice(&nextUpdate, nextUpdateDer);
- if (status != SECSuccess) {
- PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORNEXTUPDATEFAILED);
- }
- }
-
- status = DER_DecodeTimeChoice(&lastUpdate, &(nssCrl->lastUpdate));
- if (status != SECSuccess) {
- PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORLASTUPDATEFAILED);
- }
-
- if (!haveNextUpdate || nextUpdate < timeToCheck) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- if (lastUpdate <= timeToCheck) {
- *pResult = PKIX_TRUE;
- } else {
- *pResult = PKIX_FALSE;
- }
-
-cleanup:
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: pkix_pl_CRL_CreateWithSignedCRL
- * DESCRIPTION:
- *
- * Creates a new CRL using the CERTSignedCrl pointed to by "nssSignedCrl"
- * and stores it at "pCRL". If the decoding of the CERTSignedCrl fails,
- * a PKIX_Error is returned.
- *
- * PARAMETERS:
- * "nssSignedCrl"
- * Address of CERTSignedCrl. Must be non-NULL.
- * "adoptedDerCrl"
- * SECItem ponter that if not NULL is indicating that memory used
- * for der should be adopted by crl that is about to be created.
- * "pCRL"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CRL_CreateWithSignedCRL(
- CERTSignedCrl *nssSignedCrl,
- SECItem *adoptedDerCrl,
- SECItem *derGenName,
- PKIX_PL_CRL **pCrl,
- void *plContext)
-{
- PKIX_PL_CRL *crl = NULL;
-
- PKIX_ENTER(CRL, "pkix_pl_CRL_CreateWithSignedCRL");
- PKIX_NULLCHECK_ONE(pCrl);
-
- /* create a PKIX_PL_CRL object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CRL_TYPE,
- sizeof (PKIX_PL_CRL),
- (PKIX_PL_Object **)&crl,
- plContext),
- PKIX_COULDNOTCREATECRLOBJECT);
-
- /* populate the nssSignedCrl field */
- crl->nssSignedCrl = nssSignedCrl;
- crl->adoptedDerCrl = adoptedDerCrl;
- crl->issuer = NULL;
- crl->signatureAlgId = NULL;
- crl->crlNumber = NULL;
- crl->crlNumberAbsent = PKIX_FALSE;
- crl->crlEntryList = NULL;
- crl->critExtOids = NULL;
- if (derGenName) {
- crl->derGenName =
- SECITEM_DupItem(derGenName);
- if (!crl->derGenName) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- }
-
- *pCrl = crl;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(crl);
- }
-
- PKIX_RETURN(CRL);
-}
-
-/* --Public-CRL-Functions------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_CRL_Create (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CRL_Create(
- PKIX_PL_ByteArray *byteArray,
- PKIX_PL_CRL **pCrl,
- void *plContext)
-{
- CERTSignedCrl *nssSignedCrl = NULL;
- SECItem derItem, *derCrl = NULL;
- PKIX_PL_CRL *crl = NULL;
-
- PKIX_ENTER(CRL, "PKIX_PL_CRL_Create");
- PKIX_NULLCHECK_TWO(byteArray, pCrl);
-
- if (byteArray->length == 0){
- PKIX_ERROR(PKIX_ZEROLENGTHBYTEARRAYFORCRLENCODING);
- }
- derItem.type = siBuffer;
- derItem.data = byteArray->array;
- derItem.len = byteArray->length;
- derCrl = SECITEM_DupItem(&derItem);
- if (!derCrl) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- nssSignedCrl =
- CERT_DecodeDERCrlWithFlags(NULL, derCrl, SEC_CRL_TYPE,
- CRL_DECODE_DONT_COPY_DER |
- CRL_DECODE_SKIP_ENTRIES);
- if (!nssSignedCrl) {
- PKIX_ERROR(PKIX_CERTDECODEDERCRLFAILED);
- }
- PKIX_CHECK(
- pkix_pl_CRL_CreateWithSignedCRL(nssSignedCrl, derCrl, NULL,
- &crl, plContext),
- PKIX_CRLCREATEWITHSIGNEDCRLFAILED);
- nssSignedCrl = NULL;
- derCrl = NULL;
- *pCrl = crl;
-
-cleanup:
- if (derCrl) {
- SECITEM_FreeItem(derCrl, PR_TRUE);
- }
- if (nssSignedCrl) {
- SEC_DestroyCrl(nssSignedCrl);
- }
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: PKIX_PL_CRL_GetIssuer (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CRL_GetIssuer(
- PKIX_PL_CRL *crl,
- PKIX_PL_X500Name **pCRLIssuer,
- void *plContext)
-{
- PKIX_PL_String *crlString = NULL;
- PKIX_PL_X500Name *issuer = NULL;
- SECItem *derIssuerName = NULL;
- CERTName *issuerName = NULL;
-
- PKIX_ENTER(CRL, "PKIX_PL_CRL_GetIssuer");
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCRLIssuer);
-
- /* Can call this function only with der been adopted. */
- PORT_Assert(crl->adoptedDerCrl);
-
- /* if we don't have a cached copy from before, we create one */
- if (crl->issuer == NULL){
-
- PKIX_OBJECT_LOCK(crl);
-
- if (crl->issuer == NULL) {
-
- issuerName = &crl->nssSignedCrl->crl.name;
- derIssuerName = &crl->nssSignedCrl->crl.derName;
-
- PKIX_CHECK(
- PKIX_PL_X500Name_CreateFromCERTName(derIssuerName,
- issuerName,
- &issuer,
- plContext),
- PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
-
- /* save a cached copy in case it is asked for again */
- crl->issuer = issuer;
- }
-
- PKIX_OBJECT_UNLOCK(crl);
-
- }
-
- PKIX_INCREF(crl->issuer);
-
- *pCRLIssuer = crl->issuer;
-
-cleanup:
-
- PKIX_DECREF(crlString);
-
- PKIX_RETURN(CRL);
-}
-
-
-/*
- * FUNCTION: PKIX_PL_CRL_GetCriticalExtensionOIDs
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CRL_GetCriticalExtensionOIDs(
- PKIX_PL_CRL *crl,
- PKIX_List **pExtensions, /* list of PKIX_PL_OID */
- void *plContext)
-{
- PKIX_List *oidsList = NULL;
- CERTCertExtension **extensions = NULL;
- CERTCrl *nssSignedCrl = NULL;
-
- PKIX_ENTER(CRL, "PKIX_PL_CRL_GetCriticalExtensionOIDs");
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pExtensions);
-
- /* Can call this function only with der been adopted. */
- PORT_Assert(crl->adoptedDerCrl);
-
- /* if we don't have a cached copy from before, we create one */
- if (crl->critExtOids == NULL) {
-
- PKIX_OBJECT_LOCK(crl);
-
- nssSignedCrl = &(crl->nssSignedCrl->crl);
- extensions = nssSignedCrl->extensions;
-
- if (crl->critExtOids == NULL) {
-
- PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
- (extensions, &oidsList, plContext),
- PKIX_GETCRITICALEXTENSIONOIDSFAILED);
-
- crl->critExtOids = oidsList;
- }
-
- PKIX_OBJECT_UNLOCK(crl);
-
- }
-
- /* We should return a copy of the List since this list changes */
- PKIX_DUPLICATE(crl->critExtOids, pExtensions, plContext,
- PKIX_OBJECTDUPLICATELISTFAILED);
-
-cleanup:
-
- PKIX_RETURN(CRL);
-}
-
-/*
- * FUNCTION: PKIX_PL_CRL_VerifySignature (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CRL_VerifySignature(
- PKIX_PL_CRL *crl,
- PKIX_PL_PublicKey *pubKey,
- void *plContext)
-{
- PKIX_PL_CRL *cachedCrl = NULL;
- PKIX_Error *verifySig = NULL;
- PKIX_Error *cachedSig = NULL;
- PKIX_Boolean crlEqual = PKIX_FALSE;
- PKIX_Boolean crlInHash= PKIX_FALSE;
- CERTSignedCrl *nssSignedCrl = NULL;
- SECKEYPublicKey *nssPubKey = NULL;
- CERTSignedData *tbsCrl = NULL;
- void* wincx = NULL;
- SECStatus status;
-
- PKIX_ENTER(CRL, "PKIX_PL_CRL_VerifySignature");
- PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pubKey);
-
- /* Can call this function only with der been adopted. */
- PORT_Assert(crl->adoptedDerCrl);
-
- verifySig = PKIX_PL_HashTable_Lookup
- (cachedCrlSigTable,
- (PKIX_PL_Object *) pubKey,
- (PKIX_PL_Object **) &cachedCrl,
- plContext);
-
- if (cachedCrl != NULL && verifySig == NULL) {
- /* Cached Signature Table lookup succeed */
- PKIX_EQUALS(crl, cachedCrl, &crlEqual, plContext,
- PKIX_OBJECTEQUALSFAILED);
- if (crlEqual == PKIX_TRUE) {
- goto cleanup;
- }
- /* Different PubKey may hash to same value, skip add */
- crlInHash = PKIX_TRUE;
- }
-
- nssSignedCrl = crl->nssSignedCrl;
- tbsCrl = &nssSignedCrl->signatureWrap;
-
- PKIX_CRL_DEBUG("\t\tCalling SECKEY_ExtractPublicKey\n");
- nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI);
- if (!nssPubKey){
- PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED);
- }
-
- PKIX_CHECK(pkix_pl_NssContext_GetWincx
- ((PKIX_PL_NssContext *)plContext, &wincx),
- PKIX_NSSCONTEXTGETWINCXFAILED);
-
- PKIX_CRL_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey\n");
- status = CERT_VerifySignedDataWithPublicKey(tbsCrl, nssPubKey, wincx);
-
- if (status != SECSuccess) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY);
- }
-
- if (crlInHash == PKIX_FALSE) {
- cachedSig = PKIX_PL_HashTable_Add
- (cachedCrlSigTable,
- (PKIX_PL_Object *) pubKey,
- (PKIX_PL_Object *) crl,
- plContext);
-
- if (cachedSig != NULL) {
- PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n");
- }
- }
-
-cleanup:
-
- if (nssPubKey){
- PKIX_CRL_DEBUG("\t\tCalling SECKEY_DestroyPublicKey\n");
- SECKEY_DestroyPublicKey(nssPubKey);
- nssPubKey = NULL;
- }
-
- PKIX_DECREF(cachedCrl);
- PKIX_DECREF(verifySig);
- PKIX_DECREF(cachedSig);
-
- PKIX_RETURN(CRL);
-}
-
-PKIX_Error*
-PKIX_PL_CRL_ReleaseDerCrl(PKIX_PL_CRL *crl,
- SECItem **derCrl,
- void *plContext)
-{
- PKIX_ENTER(CRL, "PKIX_PL_CRL_ReleaseDerCrl");
- *derCrl = crl->adoptedDerCrl;
- crl->adoptedDerCrl = NULL;
-
- PKIX_RETURN(CRL);
-}
-
-PKIX_Error*
-PKIX_PL_CRL_AdoptDerCrl(PKIX_PL_CRL *crl,
- SECItem *derCrl,
- void *plContext)
-{
- PKIX_ENTER(CRL, "PKIX_PL_CRL_AquireDerCrl");
- if (crl->adoptedDerCrl) {
- PKIX_ERROR(PKIX_CANNOTAQUIRECRLDER);
- }
- crl->adoptedDerCrl = derCrl;
-cleanup:
- PKIX_RETURN(CRL);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h
deleted file mode 100644
index a45059ea0..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_crl.h
- *
- * CRL Object Type Definitions
- *
- */
-
-#ifndef _PKIX_PL_CRL_H
-#define _PKIX_PL_CRL_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_CRLStruct {
- CERTSignedCrl *nssSignedCrl;
- PKIX_PL_X500Name *issuer;
- PKIX_PL_OID *signatureAlgId;
- PKIX_PL_BigInt *crlNumber;
- PKIX_Boolean crlNumberAbsent;
- PKIX_List *crlEntryList; /* list of PKIX_PL_CRLEntry */
- PKIX_List *critExtOids;
- SECItem *adoptedDerCrl;
- SECItem *derGenName; /* der of general name which was used
- * to download the crl. */
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_CRL_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_pl_CRL_CreateWithSignedCRL(CERTSignedCrl *nssSignedCrl,
- SECItem *derCrl,
- SECItem *derGenName,
- PKIX_PL_CRL **pCrl,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_CRL_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c
deleted file mode 100644
index dfe557100..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_crldp.c
- *
- * Crl DP Object Functions
- *
- */
-
-#include "pkix_pl_crldp.h"
-
-static PKIX_Error *
-pkix_pl_CrlDp_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- pkix_pl_CrlDp *crldp = NULL;
-
- PKIX_ENTER(CRLCHECKER, "pkix_CrlDp_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Check that this object is a default CRL checker state */
- PKIX_CHECK(
- pkix_CheckType(object, PKIX_CRLDP_TYPE, plContext),
- PKIX_OBJECTNOTCRLCHECKER);
-
- crldp = (pkix_pl_CrlDp *)object;
- if (crldp->distPointType == relativeDistinguishedName) {
- CERT_DestroyName(crldp->name.issuerName);
- crldp->name.issuerName = NULL;
- }
- crldp->nssdp = NULL;
-cleanup:
- PKIX_RETURN(CRLCHECKER);
-}
-
-/*
- * FUNCTION: pkix_pl_CrlDp_RegisterSelf
- *
- * DESCRIPTION:
- * Registers PKIX_CRLDP_TYPE and its related functions
- * with systemClasses[]
- *
- * THREAD SAFETY:
- * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_CrlDp_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry* entry = &systemClasses[PKIX_CRLDP_TYPE];
-
- PKIX_ENTER(CRLCHECKER, "pkix_CrlDp_RegisterSelf");
-
- entry->description = "CrlDistPoint";
- entry->typeObjectSize = sizeof(pkix_pl_CrlDp);
- entry->destructor = pkix_pl_CrlDp_Destroy;
- entry->duplicateFunction = pkix_duplicateImmutable;
-
- PKIX_RETURN(CRLCHECKER);
-}
-
-
-
-PKIX_Error *
-pkix_pl_CrlDp_Create(
- const CRLDistributionPoint *dp,
- const CERTName *certIssuerName,
- pkix_pl_CrlDp **pPkixDP,
- void *plContext)
-{
- PRArenaPool *rdnArena = NULL;
- CERTName *issuerNameCopy = NULL;
- pkix_pl_CrlDp *dpl = NULL;
-
- /* Need to save the following info to update crl cache:
- * - reasons if partitioned(but can not return revocation check
- * success if not all crl are downloaded)
- * - issuer name if different from issuer of the cert
- * - url to upload a crl if needed.
- * */
- PKIX_ENTER(CRLDP, "pkix_pl_CrlDp_Create");
- PKIX_NULLCHECK_ONE(dp);
-
- PKIX_CHECK(
- PKIX_PL_Object_Alloc(PKIX_CRLDP_TYPE,
- sizeof (pkix_pl_CrlDp),
- (PKIX_PL_Object **)&dpl,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- dpl->nssdp = dp;
- dpl->isPartitionedByReasonCode = PKIX_FALSE;
- if (dp->reasons.data) {
- dpl->isPartitionedByReasonCode = PKIX_TRUE;
- }
- if (dp->distPointType == generalName) {
- dpl->distPointType = generalName;
- dpl->name.fullName = dp->distPoint.fullName;
- } else {
- SECStatus rv;
- const CERTName *issuerName = NULL;
- const CERTRDN *relName = &dp->distPoint.relativeName;
-
- if (dp->crlIssuer) {
- if (dp->crlIssuer->l.next) {
- /* Violate RFC 5280: in this case crlIssuer
- * should have only one name and should be
- * a distinguish name. */
- PKIX_ERROR(PKIX_NOTCONFORMINGCRLDP);
- }
- issuerName = &dp->crlIssuer->name.directoryName;
- } else {
- issuerName = certIssuerName;
- }
- rdnArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!rdnArena) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
- issuerNameCopy = (CERTName *)PORT_ArenaZNew(rdnArena, CERTName*);
- if (!issuerNameCopy) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- rv = CERT_CopyName(rdnArena, issuerNameCopy, (CERTName*)issuerName);
- if (rv == SECFailure) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- rv = CERT_AddRDN(issuerNameCopy, (CERTRDN*)relName);
- if (rv == SECFailure) {
- PKIX_ERROR(PKIX_ALLOCERROR);
- }
- dpl->distPointType = relativeDistinguishedName;
- dpl->name.issuerName = issuerNameCopy;
- rdnArena = NULL;
- }
- *pPkixDP = dpl;
- dpl = NULL;
-
-cleanup:
- if (rdnArena) {
- PORT_FreeArena(rdnArena, PR_FALSE);
- }
- PKIX_DECREF(dpl);
-
- PKIX_RETURN(CRLDP);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.h
deleted file mode 100644
index 621999203..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_crldp.h
- *
- * Crp DP Object Definitions
- *
- */
-#include "pkix_pl_common.h"
-
-#ifndef _PKIX_PL_CRLDP_H
-#define _PKIX_PL_CRLDP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* CRLDP object can not be used without holding a reference
- * to the pkix certificate they belong to. The memory for dp der
- * object is allocated on nssCert certificate - a member of
- * PKIX_PL_Cert struct. */
-typedef struct pkix_pl_CrlDpStruct {
- /* reference to decoded crldp that allocated on nssCert arena. */
- const CRLDistributionPoint *nssdp;
- DistributionPointTypes distPointType;
- union {
- CERTGeneralName *fullName;
- /* if dp is a relative name, the issuerName is a merged value
- * of crlIssuer and a relative name. Must be destroyed by CrlDp
- * destructor. */
- CERTName *issuerName;
- } name;
- PKIX_Boolean isPartitionedByReasonCode;
-} pkix_pl_CrlDp;
-
-
-PKIX_Error *
-pkix_pl_CrlDp_RegisterSelf(void *plContext);
-
-/* Parses CRLDistributionPoint structure and creaetes
- * pkix_pl_CrlDp object. */
-PKIX_Error *
-pkix_pl_CrlDp_Create(const CRLDistributionPoint *dp,
- const CERTName *certIssuerName,
- pkix_pl_CrlDp **pPkixDP,
- void *plContext);
-#endif /* _PKIX_PL_CRLDP_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c
deleted file mode 100644
index 2cd1cad9c..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c
+++ /dev/null
@@ -1,880 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_crlentry.c
- *
- * CRLENTRY Function Definitions
- *
- */
-
-#include "pkix_pl_crlentry.h"
-
-/* --Private-CRLEntry-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_CRLEntry_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CRLEntry_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_CRLEntry *crlEntry = NULL;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext),
- PKIX_OBJECTNOTCRLENTRY);
-
- crlEntry = (PKIX_PL_CRLEntry*)object;
-
- /* crlEntry->nssCrlEntry is freed by NSS when freeing CRL */
- crlEntry->userReasonCode = 0;
- crlEntry->userReasonCodeAbsent = PKIX_FALSE;
- crlEntry->nssCrlEntry = NULL;
- PKIX_DECREF(crlEntry->serialNumber);
- PKIX_DECREF(crlEntry->critExtOids);
-
-cleanup:
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: pkix_pl_CRLEntry_ToString_Helper
- *
- * DESCRIPTION:
- * Helper function that creates a string representation of the CRLEntry
- * pointed to by "crlEntry" and stores it at "pString".
- *
- * PARAMETERS
- * "crlEntry"
- * Address of CRLEntry whose string representation is desired.
- * Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLEntry Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CRLEntry_ToString_Helper(
- PKIX_PL_CRLEntry *crlEntry,
- PKIX_PL_String **pString,
- void *plContext)
-{
- char *asciiFormat = NULL;
- PKIX_List *critExtOIDs = NULL;
- PKIX_PL_String *crlEntryString = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *crlSerialNumberString = NULL;
- PKIX_PL_String *crlRevocationDateString = NULL;
- PKIX_PL_String *critExtOIDsString = NULL;
- PKIX_Int32 reasonCode = 0;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString_Helper");
- PKIX_NULLCHECK_FOUR
- (crlEntry,
- crlEntry->serialNumber,
- crlEntry->nssCrlEntry,
- pString);
-
- asciiFormat =
- "\n\t[\n"
- "\tSerialNumber: %s\n"
- "\tReasonCode: %d\n"
- "\tRevocationDate: %s\n"
- "\tCritExtOIDs: %s\n"
- "\t]\n\t";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- /* SerialNumber */
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)crlEntry->serialNumber,
- &crlSerialNumberString,
- plContext),
- PKIX_BIGINTTOSTRINGHELPERFAILED);
-
- /* RevocationDate - No Date object created, use nss data directly */
- PKIX_CHECK(pkix_pl_Date_ToString_Helper
- (&(crlEntry->nssCrlEntry->revocationDate),
- &crlRevocationDateString,
- plContext),
- PKIX_DATETOSTRINGHELPERFAILED);
-
- /* CriticalExtensionOIDs */
- PKIX_CHECK(PKIX_PL_CRLEntry_GetCriticalExtensionOIDs
- (crlEntry, &critExtOIDs, plContext),
- PKIX_CRLENTRYGETCRITICALEXTENSIONOIDSFAILED);
-
- PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- /* Revocation Reason Code */
- PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode
- (crlEntry, &reasonCode, plContext),
- PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&crlEntryString,
- plContext,
- formatString,
- crlSerialNumberString,
- reasonCode,
- crlRevocationDateString,
- critExtOIDsString),
- PKIX_SPRINTFFAILED);
-
- *pString = crlEntryString;
-
-cleanup:
-
- PKIX_DECREF(critExtOIDs);
- PKIX_DECREF(crlSerialNumberString);
- PKIX_DECREF(crlRevocationDateString);
- PKIX_DECREF(critExtOIDsString);
- PKIX_DECREF(formatString);
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: pkix_pl_CRLEntry_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CRLEntry_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *crlEntryString = NULL;
- PKIX_PL_CRLEntry *crlEntry = NULL;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext),
- PKIX_OBJECTNOTCRLENTRY);
-
- crlEntry = (PKIX_PL_CRLEntry *) object;
-
- PKIX_CHECK(pkix_pl_CRLEntry_ToString_Helper
- (crlEntry, &crlEntryString, plContext),
- PKIX_CRLENTRYTOSTRINGHELPERFAILED);
-
- *pString = crlEntryString;
-
-cleanup:
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: pkix_pl_CRLEntry_Extensions_Hashcode
- * DESCRIPTION:
- *
- * For each CRL Entry extension stored at NSS structure CERTCertExtension,
- * get its derbyte data and do the hash.
- *
- * PARAMETERS
- * "extensions"
- * Address of arrray of CERTCertExtension whose hash value is desired.
- * Must be non-NULL.
- * "pHashValue"
- * Address where the final hash value is returned. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditional Thread Safe
- * Though the value of extensions once created is not supposed to change,
- * it may be de-allocated while we are accessing it. But since we are
- * validating the object, it is unlikely we or someone is de-allocating
- * at the moment.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OID Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CRLEntry_Extensions_Hashcode(
- CERTCertExtension **extensions,
- PKIX_UInt32 *pHashValue,
- void *plContext)
-{
- CERTCertExtension *extension = NULL;
- PRArenaPool *arena = NULL;
- PKIX_UInt32 extHash = 0;
- PKIX_UInt32 hashValue = 0;
- SECItem *derBytes = NULL;
- SECItem *resultSecItem = NULL;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Hashcode");
- PKIX_NULLCHECK_TWO(extensions, pHashValue);
-
- if (extensions) {
-
- PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n");
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- while (*extensions) {
-
- extension = *extensions++;
-
- PKIX_NULLCHECK_ONE(extension);
-
- PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
- derBytes = PORT_ArenaZNew(arena, SECItem);
- if (derBytes == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- PKIX_CRLENTRY_DEBUG
- ("\t\tCalling SEC_ASN1EncodeItem\n");
- resultSecItem = SEC_ASN1EncodeItem
- (arena,
- derBytes,
- extension,
- CERT_CertExtensionTemplate);
-
- if (resultSecItem == NULL){
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
- }
-
- PKIX_CHECK(pkix_hash
- (derBytes->data,
- derBytes->len,
- &extHash,
- plContext),
- PKIX_HASHFAILED);
-
- hashValue += (extHash << 7);
-
- }
- }
-
- *pHashValue = hashValue;
-
-cleanup:
-
- if (arena){
- /* Note that freeing the arena also frees derBytes */
- PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n");
- PORT_FreeArena(arena, PR_FALSE);
- arena = NULL;
- }
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: pkix_pl_CRLEntry_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CRLEntry_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- SECItem *nssDate = NULL;
- PKIX_PL_CRLEntry *crlEntry = NULL;
- PKIX_UInt32 crlEntryHash;
- PKIX_UInt32 hashValue;
- PKIX_Int32 reasonCode = 0;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_CRLENTRY_TYPE, plContext),
- PKIX_OBJECTNOTCRLENTRY);
-
- crlEntry = (PKIX_PL_CRLEntry *)object;
-
- PKIX_NULLCHECK_ONE(crlEntry->nssCrlEntry);
- nssDate = &(crlEntry->nssCrlEntry->revocationDate);
-
- PKIX_NULLCHECK_ONE(nssDate->data);
-
- PKIX_CHECK(pkix_hash
- ((const unsigned char *)nssDate->data,
- nssDate->len,
- &crlEntryHash,
- plContext),
- PKIX_ERRORGETTINGHASHCODE);
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)crlEntry->serialNumber,
- &hashValue,
- plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- crlEntryHash += (hashValue << 7);
-
- hashValue = 0;
-
- if (crlEntry->nssCrlEntry->extensions) {
-
- PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Hashcode
- (crlEntry->nssCrlEntry->extensions, &hashValue, plContext),
- PKIX_CRLENTRYEXTENSIONSHASHCODEFAILED);
- }
-
- crlEntryHash += (hashValue << 7);
-
- PKIX_CHECK(PKIX_PL_CRLEntry_GetCRLEntryReasonCode
- (crlEntry, &reasonCode, plContext),
- PKIX_CRLENTRYGETCRLENTRYREASONCODEFAILED);
-
- crlEntryHash += (reasonCode + 777) << 3;
-
- *pHashcode = crlEntryHash;
-
-cleanup:
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: pkix_pl_CRLENTRY_Extensions_Equals
- * DESCRIPTION:
- *
- * Compare each extension's DERbyte data in "firstExtensions" with extension
- * in "secondExtensions" in sequential order and store the result in
- * "pResult".
- *
- * PARAMETERS
- * "firstExtensions"
- * Address of first NSS structure CERTCertExtension to be compared.
- * Must be non-NULL.
- * "secondExtensions"
- * Address of second NSS structure CERTCertExtension to be compared.
- * Must be non-NULL.
- * "pResult"
- * Address where the comparison result is returned. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * Though the value of extensions once created is not supposed to change,
- * it may be de-allocated while we are accessing it. But since we are
- * validating the object, it is unlikely we or someone is de-allocating
- * at the moment.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OID Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CRLEntry_Extensions_Equals(
- CERTCertExtension **extensions1,
- CERTCertExtension **extensions2,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- CERTCertExtension **firstExtensions;
- CERTCertExtension **secondExtensions;
- CERTCertExtension *firstExtension = NULL;
- CERTCertExtension *secondExtension = NULL;
- PRArenaPool *arena = NULL;
- PKIX_Boolean cmpResult = PKIX_FALSE;
- SECItem *firstDerBytes = NULL;
- SECItem *secondDerBytes = NULL;
- SECItem *firstResultSecItem = NULL;
- SECItem *secondResultSecItem = NULL;
- PKIX_UInt32 firstNumExt = 0;
- PKIX_UInt32 secondNumExt = 0;
- SECComparison secResult;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Extensions_Equals");
- PKIX_NULLCHECK_THREE(extensions1, extensions2, pResult);
-
- firstExtensions = extensions1;
- secondExtensions = extensions2;
-
- if (firstExtensions) {
- while (*firstExtensions) {
- firstExtension = *firstExtensions++;
- firstNumExt++;
- }
- }
-
- if (secondExtensions) {
- while (*secondExtensions) {
- secondExtension = *secondExtensions++;
- secondNumExt++;
- }
- }
-
- if (firstNumExt != secondNumExt) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- if (firstNumExt == 0 && secondNumExt == 0) {
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /* now have equal number, but non-zero extension items to compare */
-
- firstExtensions = extensions1;
- secondExtensions = extensions2;
-
- cmpResult = PKIX_TRUE;
-
- PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_NewArena\n");
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE*2);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- while (firstNumExt--) {
-
- firstExtension = *firstExtensions++;
- secondExtension = *secondExtensions++;
-
- PKIX_NULLCHECK_TWO(firstExtension, secondExtension);
-
- PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
- firstDerBytes = PORT_ArenaZNew(arena, SECItem);
- if (firstDerBytes == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_ArenaZNew\n");
- secondDerBytes = PORT_ArenaZNew(arena, SECItem);
- if (secondDerBytes == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- PKIX_CRLENTRY_DEBUG
- ("\t\tCalling SEC_ASN1EncodeItem\n");
- firstResultSecItem = SEC_ASN1EncodeItem
- (arena,
- firstDerBytes,
- firstExtension,
- CERT_CertExtensionTemplate);
-
- if (firstResultSecItem == NULL){
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
- }
-
- PKIX_CRLENTRY_DEBUG
- ("\t\tCalling SEC_ASN1EncodeItem\n");
- secondResultSecItem = SEC_ASN1EncodeItem
- (arena,
- secondDerBytes,
- secondExtension,
- CERT_CertExtensionTemplate);
-
- if (secondResultSecItem == NULL){
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
- }
-
- PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
- secResult = SECITEM_CompareItem
- (firstResultSecItem, secondResultSecItem);
-
- if (secResult != SECEqual) {
- cmpResult = PKIX_FALSE;
- break;
- }
-
- }
-
- *pResult = cmpResult;
-
-cleanup:
-
- if (arena){
- /* Note that freeing the arena also frees derBytes */
- PKIX_CRLENTRY_DEBUG("\t\tCalling PORT_FreeArena\n");
- PORT_FreeArena(arena, PR_FALSE);
- arena = NULL;
- }
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: pkix_pl_CRLEntry_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CRLEntry_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_CRLEntry *firstCrlEntry = NULL;
- PKIX_PL_CRLEntry *secondCrlEntry = NULL;
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult = PKIX_FALSE;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a CRLEntry */
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CRLENTRY_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCRLENTRY);
-
- firstCrlEntry = (PKIX_PL_CRLEntry *)firstObject;
- secondCrlEntry = (PKIX_PL_CRLEntry *)secondObject;
-
- PKIX_NULLCHECK_TWO
- (firstCrlEntry->nssCrlEntry, secondCrlEntry->nssCrlEntry);
-
- /*
- * Since we know firstObject is a CRLEntry, if both references are
- * identical, they must be equal
- */
- if (firstCrlEntry == secondCrlEntry){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondCrlEntry isn't a CRL Entry, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- ((PKIX_PL_Object *)secondCrlEntry, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_CRLENTRY_TYPE) goto cleanup;
-
- /* Compare userSerialNumber */
- PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
- if (SECITEM_CompareItem(
- &(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry->serialNumber),
- &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry->serialNumber))
- != SECEqual) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- /* Compare revocationDate */
- PKIX_CRLENTRY_DEBUG("\t\tCalling SECITEM_CompareItem\n");
- if (SECITEM_CompareItem
- (&(((PKIX_PL_CRLEntry *)firstCrlEntry)->nssCrlEntry->
- revocationDate),
- &(((PKIX_PL_CRLEntry *)secondCrlEntry)->nssCrlEntry->
- revocationDate))
- != SECEqual) {
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- /* Compare Critical Extension List */
- PKIX_CHECK(pkix_pl_CRLEntry_Extensions_Equals
- (firstCrlEntry->nssCrlEntry->extensions,
- secondCrlEntry->nssCrlEntry->extensions,
- &cmpResult,
- plContext),
- PKIX_CRLENTRYEXTENSIONSEQUALSFAILED);
-
- if (cmpResult != PKIX_TRUE){
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
-
- cmpResult = (firstCrlEntry->userReasonCode ==
- secondCrlEntry->userReasonCode);
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: pkix_pl_CRLEntry_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CRLEntry_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_CRLEntry_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_RegisterSelf");
-
- entry.description = "CRLEntry";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_CRLEntry);
- entry.destructor = pkix_pl_CRLEntry_Destroy;
- entry.equalsFunction = pkix_pl_CRLEntry_Equals;
- entry.hashcodeFunction = pkix_pl_CRLEntry_Hashcode;
- entry.toStringFunction = pkix_pl_CRLEntry_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_CRLENTRY_TYPE] = entry;
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: pkix_pl_CRLEntry_CreateEntry
- * DESCRIPTION:
- *
- * Creates a new CRLEntry using the CertCrlEntry pointed to by "nssCrlEntry"
- * and stores it at "pCrlEntry". Once created, a CRLEntry is immutable.
- *
- * revokedCertificates SEQUENCE OF SEQUENCE {
- * userCertificate CertificateSerialNumber,
- * revocationDate Time,
- * crlEntryExtensions Extensions OPTIONAL
- * -- if present, MUST be v2
- *
- * PARAMETERS:
- * "nssCrlEntry"
- * Address of CERTCrlEntry representing an NSS CRL entry.
- * Must be non-NULL.
- * "pCrlEntry"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLEntry Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CRLEntry_CreateEntry(
- CERTCrlEntry *nssCrlEntry, /* entry data to be created from */
- PKIX_PL_CRLEntry **pCrlEntry,
- void *plContext)
-{
- PKIX_PL_CRLEntry *crlEntry = NULL;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_CreateEntry");
- PKIX_NULLCHECK_TWO(nssCrlEntry, pCrlEntry);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CRLENTRY_TYPE,
- sizeof (PKIX_PL_CRLEntry),
- (PKIX_PL_Object **)&crlEntry,
- plContext),
- PKIX_COULDNOTCREATECRLENTRYOBJECT);
-
- crlEntry->nssCrlEntry = nssCrlEntry;
- crlEntry->serialNumber = NULL;
- crlEntry->critExtOids = NULL;
- crlEntry->userReasonCode = 0;
- crlEntry->userReasonCodeAbsent = PKIX_FALSE;
-
- *pCrlEntry = crlEntry;
-
-cleanup:
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: pkix_pl_CRLEntry_Create
- * DESCRIPTION:
- *
- * Creates a List of CRLEntries using the array of CERTCrlEntries pointed to
- * by "nssCrlEntries" and stores it at "pCrlEntryList". If "nssCrlEntries" is
- * NULL, this function stores an empty List at "pCrlEntryList".
- * }
- * PARAMETERS:
- * "nssCrlEntries"
- * Address of array of CERTCrlEntries representing NSS CRL entries.
- * Can be NULL if CRL has no NSS CRL entries.
- * "pCrlEntryList"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRLEntry Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CRLEntry_Create(
- CERTCrlEntry **nssCrlEntries, /* head of entry list */
- PKIX_List **pCrlEntryList,
- void *plContext)
-{
- PKIX_List *entryList = NULL;
- PKIX_PL_CRLEntry *crlEntry = NULL;
- CERTCrlEntry **entries = NULL;
- SECItem serialNumberItem;
- PKIX_PL_BigInt *serialNumber;
- char *bytes = NULL;
- PKIX_UInt32 length;
-
- PKIX_ENTER(CRLENTRY, "pkix_pl_CRLEntry_Create");
- PKIX_NULLCHECK_ONE(pCrlEntryList);
-
- entries = nssCrlEntries;
-
- PKIX_CHECK(PKIX_List_Create(&entryList, plContext),
- PKIX_LISTCREATEFAILED);
-
- if (entries) {
- while (*entries){
- PKIX_CHECK(pkix_pl_CRLEntry_CreateEntry
- (*entries, &crlEntry, plContext),
- PKIX_COULDNOTCREATECRLENTRYOBJECT);
-
- /* Get Serial Number */
- serialNumberItem = (*entries)->serialNumber;
- length = serialNumberItem.len;
- bytes = (char *)serialNumberItem.data;
-
- PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
- (bytes, length, &serialNumber, plContext),
- PKIX_BIGINTCREATEWITHBYTESFAILED);
-
- crlEntry->serialNumber = serialNumber;
- crlEntry->nssCrlEntry = *entries;
-
- PKIX_CHECK(PKIX_List_AppendItem
- (entryList, (PKIX_PL_Object *)crlEntry, plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(crlEntry);
-
- entries++;
- }
- }
-
- *pCrlEntryList = entryList;
-
-cleanup:
- PKIX_DECREF(crlEntry);
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(entryList);
- }
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/* --Public-CRLENTRY-Functions------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_CRLEntry_GetCRLEntryReasonCode
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CRLEntry_GetCRLEntryReasonCode (
- PKIX_PL_CRLEntry *crlEntry,
- PKIX_Int32 *pReason,
- void *plContext)
-{
- SECStatus status;
- CERTCRLEntryReasonCode nssReasonCode;
-
- PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCRLEntryReasonCode");
- PKIX_NULLCHECK_TWO(crlEntry, pReason);
-
- if (!crlEntry->userReasonCodeAbsent && crlEntry->userReasonCode == 0) {
-
- PKIX_OBJECT_LOCK(crlEntry);
-
- if (!crlEntry->userReasonCodeAbsent &&
- crlEntry->userReasonCode == 0) {
-
- /* reason code has not been cached in */
- PKIX_CRLENTRY_DEBUG("\t\tCERT_FindCRLEntryReasonExten.\n");
- status = CERT_FindCRLEntryReasonExten
- (crlEntry->nssCrlEntry, &nssReasonCode);
-
- if (status == SECSuccess) {
- crlEntry->userReasonCode = (PKIX_Int32) nssReasonCode;
- } else {
- crlEntry->userReasonCodeAbsent = PKIX_TRUE;
- }
- }
-
- PKIX_OBJECT_UNLOCK(crlEntry);
-
- }
-
- *pReason = crlEntry->userReasonCode;
-
-cleanup:
-
- PKIX_RETURN(CRLENTRY);
-}
-
-/*
- * FUNCTION: PKIX_PL_CRLEntry_GetCriticalExtensionOIDs
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_CRLEntry_GetCriticalExtensionOIDs (
- PKIX_PL_CRLEntry *crlEntry,
- PKIX_List **pList, /* list of PKIX_PL_OID */
- void *plContext)
-{
- PKIX_List *oidsList = NULL;
- CERTCertExtension **extensions;
-
- PKIX_ENTER(CRLENTRY, "PKIX_PL_CRLEntry_GetCriticalExtensionOIDs");
- PKIX_NULLCHECK_THREE(crlEntry, crlEntry->nssCrlEntry, pList);
-
- /* if we don't have a cached copy from before, we create one */
- if (crlEntry->critExtOids == NULL) {
-
- PKIX_OBJECT_LOCK(crlEntry);
-
- if (crlEntry->critExtOids == NULL) {
-
- extensions = crlEntry->nssCrlEntry->extensions;
-
- PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
- (extensions, &oidsList, plContext),
- PKIX_GETCRITICALEXTENSIONOIDSFAILED);
-
- crlEntry->critExtOids = oidsList;
- }
-
- PKIX_OBJECT_UNLOCK(crlEntry);
-
- }
-
- /* We should return a copy of the List since this list changes */
- PKIX_DUPLICATE(crlEntry->critExtOids, pList, plContext,
- PKIX_OBJECTDUPLICATELISTFAILED);
-
-cleanup:
-
- PKIX_RETURN(CRLENTRY);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.h
deleted file mode 100644
index 9cdb6bc92..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_crlentry.h
- *
- * CRL Entry Type Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_CRLENTRY_H
-#define _PKIX_PL_CRLENTRY_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PKIX_PL_CRL_REASONCODE_NOTSET (-1)
-
-struct PKIX_PL_CRLEntryStruct {
- CERTCrlEntry *nssCrlEntry;
- PKIX_PL_BigInt *serialNumber;
- PKIX_List *critExtOids;
- PKIX_Int32 userReasonCode;
- PKIX_Boolean userReasonCodeAbsent;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_CRLEntry_RegisterSelf(void *plContext);
-
-/* following functions are called by CRL only hence not public */
-
-PKIX_Error *
-pkix_pl_CRLEntry_Create(
- CERTCrlEntry **nssCrlEntry, /* head of entry list */
- PKIX_List **pCrlEntryList,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_CRLENTRY_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.c
deleted file mode 100644
index 4b5016bd0..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_date.c
- *
- * Date Object Definitions
- *
- */
-
-#include "pkix_pl_date.h"
-
-/* --Private-Date-Functions------------------------------------- */
-/*
- * FUNCTION: pkix_pl_Date_GetPRTime
- * DESCRIPTION:
- *
- * Translates into a PRTime the Date embodied by the Date object pointed to
- * by "date", and stores it at "pPRTime".
- *
- * PARAMETERS
- * "date"
- * Address of Date whose PRTime representation is desired. Must be
- * non-NULL.
- * "pPRTime"
- * Address where PRTime value will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Date Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Date_GetPRTime(
- PKIX_PL_Date *date,
- PRTime *pPRTime,
- void *plContext)
-{
- PKIX_ENTER(DATE, "PKIX_PL_Date_GetPRTime");
- PKIX_NULLCHECK_TWO(date, pPRTime);
-
- *pPRTime = date->nssTime;
-
- PKIX_RETURN(DATE);
-}
-
-/*
- * FUNCTION: pkix_pl_Date_CreateFromPRTime
- * DESCRIPTION:
- *
- * Creates a new Date from the PRTime whose value is "prtime", and stores the
- * result at "pDate".
- *
- * PARAMETERS
- * "prtime"
- * The PRTime value to be embodied in the new Date object.
- * "pDate"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Date Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Date_CreateFromPRTime(
- PRTime prtime,
- PKIX_PL_Date **pDate,
- void *plContext)
-{
- PKIX_PL_Date *date = NULL;
-
- PKIX_ENTER(DATE, "PKIX_PL_Date_CreateFromPRTime");
- PKIX_NULLCHECK_ONE(pDate);
-
- /* create a PKIX_PL_Date object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_DATE_TYPE,
- sizeof (PKIX_PL_Date),
- (PKIX_PL_Object **)&date,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
- /* populate the nssTime field */
- date->nssTime = prtime;
- *pDate = date;
-cleanup:
- PKIX_RETURN(DATE);
-}
-
-/*
- * FUNCTION: pkix_pl_Date_ToString_Helper
- * DESCRIPTION:
- *
- * Helper function that creates a string representation of the SECItem pointed
- * to by "nssTime" (which represents a date) and stores it at "pString".
- *
- * PARAMETERS
- * "nssTime"
- * Address of SECItem whose string representation is desired.
- * Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Date Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Date_ToString_Helper(
- SECItem *nssTime,
- PKIX_PL_String **pString,
- void *plContext)
-{
- char *asciiDate = NULL;
-
- PKIX_ENTER(DATE, "pkix_pl_Date_ToString_Helper");
- PKIX_NULLCHECK_TWO(nssTime, pString);
-
- switch (nssTime->type) {
- case siUTCTime:
- PKIX_PL_NSSCALLRV
- (DATE, asciiDate, DER_UTCDayToAscii, (nssTime));
- if (!asciiDate){
- PKIX_ERROR(PKIX_DERUTCTIMETOASCIIFAILED);
- }
- break;
- case siGeneralizedTime:
- /*
- * we don't currently have any way to create GeneralizedTime.
- * this code is only here so that it will be in place when
- * we do have the capability to create GeneralizedTime.
- */
- PKIX_PL_NSSCALLRV
- (DATE, asciiDate, DER_GeneralizedDayToAscii, (nssTime));
- if (!asciiDate){
- PKIX_ERROR(PKIX_DERGENERALIZEDDAYTOASCIIFAILED);
- }
- break;
- default:
- PKIX_ERROR(PKIX_UNRECOGNIZEDTIMETYPE);
- }
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, asciiDate, 0, pString, plContext),
- PKIX_STRINGCREATEFAILED);
-
-cleanup:
- PR_Free(asciiDate);
-
- PKIX_RETURN(DATE);
-}
-
-
-/*
- * FUNCTION: pkix_pl_Date_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Date_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ENTER(DATE, "pkix_pl_Date_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_DATE_TYPE, plContext),
- PKIX_OBJECTNOTDATE);
-cleanup:
- PKIX_RETURN(DATE);
-}
-
-/*
- * FUNCTION: pkix_pl_Date_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Date_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_Date *date = NULL;
- SECItem nssTime = {siBuffer, NULL, 0};
- SECStatus rv;
-
- PKIX_ENTER(DATE, "pkix_pl_Date_toString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_DATE_TYPE, plContext),
- PKIX_OBJECTNOTDATE);
-
- date = (PKIX_PL_Date *)object;
- rv = DER_EncodeTimeChoice(NULL, &nssTime, date->nssTime);
- if (rv == SECFailure) {
- PKIX_ERROR(PKIX_DERENCODETIMECHOICEFAILED);
- }
- PKIX_CHECK(pkix_pl_Date_ToString_Helper
- (&nssTime, pString, plContext),
- PKIX_DATETOSTRINGHELPERFAILED);
-cleanup:
- if (nssTime.data) {
- SECITEM_FreeItem(&nssTime, PR_FALSE);
- }
-
- PKIX_RETURN(DATE);
-}
-
-/*
- * FUNCTION: pkix_pl_Date_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Date_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_Date *date = NULL;
- PKIX_UInt32 dateHash;
-
- PKIX_ENTER(DATE, "pkix_pl_Date_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_DATE_TYPE, plContext),
- PKIX_OBJECTNOTDATE);
-
- date = (PKIX_PL_Date *)object;
-
- PKIX_CHECK(pkix_hash
- ((const unsigned char *)&date->nssTime,
- sizeof(date->nssTime),
- &dateHash,
- plContext),
- PKIX_HASHFAILED);
-
- *pHashcode = dateHash;
-
-cleanup:
-
- PKIX_RETURN(DATE);
-
-}
-
-/*
- * FUNCTION: pkix_pl_Date_Comparator
- * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Date_Comparator(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PRTime firstTime;
- PRTime secondTime;
- SECComparison cmpResult;
-
- PKIX_ENTER(DATE, "pkix_pl_Date_Comparator");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- PKIX_CHECK(pkix_CheckTypes
- (firstObject, secondObject, PKIX_DATE_TYPE, plContext),
- PKIX_ARGUMENTSNOTDATES);
-
- firstTime = ((PKIX_PL_Date *)firstObject)->nssTime;
- secondTime = ((PKIX_PL_Date *)secondObject)->nssTime;
-
- if (firstTime == secondTime)
- cmpResult = SECEqual;
- else if (firstTime < secondTime)
- cmpResult = SECLessThan;
- else
- cmpResult = SECGreaterThan;
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(DATE);
-}
-
-/*
- * FUNCTION: pkix_pl_Date_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Date_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_ENTER(DATE, "pkix_pl_Date_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a Date */
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_DATE_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTDATE);
-
- /*
- * Since we know firstObject is a Date, if both references are
- * identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- *pResult = PKIX_FALSE;
- pkixErrorResult =
- pkix_pl_Date_Comparator(firstObject, secondObject,
- pResult, plContext);
- if (pkixErrorResult) {
- PKIX_DECREF(pkixErrorResult);
- }
-
-cleanup:
-
- PKIX_RETURN(DATE);
-}
-
-/*
- * FUNCTION: pkix_pl_Date_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_DATE_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_Date_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry* entry = &systemClasses[PKIX_DATE_TYPE];
-
- PKIX_ENTER(CRLCHECKER, "pkix_CrlDp_RegisterSelf");
-
- entry->description = "Date";
- entry->typeObjectSize = sizeof(PKIX_PL_Date);
- entry->destructor = pkix_pl_Date_Destroy;
- entry->equalsFunction = pkix_pl_Date_Equals;
- entry->hashcodeFunction = pkix_pl_Date_Hashcode;
- entry->toStringFunction = pkix_pl_Date_ToString;
- entry->comparator = pkix_pl_Date_Comparator;
- entry->duplicateFunction = pkix_duplicateImmutable;
-
- PKIX_RETURN(DATE);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_Date_Create_UTCTime (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Date_Create_UTCTime(
- PKIX_PL_String *stringRep,
- PKIX_PL_Date **pDate,
- void *plContext)
-{
- PKIX_PL_Date *date = NULL;
- char *asciiString = NULL;
- PKIX_UInt32 escAsciiLength;
- SECStatus rv;
- PRTime time;
-
- PKIX_ENTER(DATE, "PKIX_PL_Date_Create_UTCTime");
- PKIX_NULLCHECK_ONE(pDate);
-
- if (stringRep == NULL){
- PKIX_DATE_DEBUG("\t\tCalling PR_Now).\n");
- time = PR_Now();
- } else {
- /* convert the input PKIX_PL_String to PKIX_ESCASCII */
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stringRep,
- PKIX_ESCASCII,
- (void **)&asciiString,
- &escAsciiLength,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_DATE_DEBUG("\t\tCalling DER_AsciiToTime).\n");
- /* DER_AsciiToTime only supports UTCTime (2-digit years) */
- rv = DER_AsciiToTime(&time, asciiString);
- if (rv != SECSuccess){
- PKIX_ERROR(PKIX_DERASCIITOTIMEFAILED);
- }
- }
-
- /* create a PKIX_PL_Date object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_DATE_TYPE,
- sizeof (PKIX_PL_Date),
- (PKIX_PL_Object **)&date,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- /* populate the nssTime field */
- date->nssTime = time;
- *pDate = date;
-
-cleanup:
- PKIX_FREE(asciiString);
-
- PKIX_RETURN(DATE);
-}
-
-/*
- * FUNCTION: PKIX_PL_Date_Create_CurrentOffBySeconds
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_Date_Create_CurrentOffBySeconds(
- PKIX_Int32 secondsOffset,
- PKIX_PL_Date **pDate,
- void *plContext)
-{
- PKIX_PL_Date *date = NULL;
- PRTime time;
-
- PKIX_ENTER(DATE, "PKIX_PL_Date_Create_CurrentOffBySeconds");
- PKIX_NULLCHECK_ONE(pDate);
-
- time = PR_Now() + PR_SecondsToInterval(secondsOffset);
- /* create a PKIX_PL_Date object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_DATE_TYPE,
- sizeof (PKIX_PL_Date),
- (PKIX_PL_Object **)&date,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- /* populate the nssTime field */
- date->nssTime = time;
- *pDate = date;
-
-cleanup:
- PKIX_RETURN(DATE);
-}
-
-PKIX_Error *
-PKIX_PL_Date_CreateFromPRTime(
- PRTime prtime,
- PKIX_PL_Date **pDate,
- void *plContext)
-{
- PKIX_ENTER(DATE, "PKIX_PL_Date_CreateFromPRTime");
- PKIX_CHECK(
- pkix_pl_Date_CreateFromPRTime(prtime, pDate, plContext),
- PKIX_DATECREATEFROMPRTIMEFAILED);
-
-cleanup:
- PKIX_RETURN(DATE);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.h
deleted file mode 100644
index 415597580..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_date.h
- *
- * Date Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_DATE_H
-#define _PKIX_PL_DATE_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_DateStruct{
- PRTime nssTime;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_Date_ToString_Helper(
- SECItem *nssTime,
- PKIX_PL_String **pString,
- void *plContext);
-
-PKIX_Error *pkix_pl_Date_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_pl_Date_GetPRTime(
- PKIX_PL_Date *date,
- PRTime *pPRTime,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_Date_CreateFromPRTime(
- PRTime prtime,
- PKIX_PL_Date **pDate,
- void *plContext);
-
-PKIX_Error *
-PKIX_PL_Date_CreateFromPRTime(
- PRTime prtime,
- PKIX_PL_Date **pDate,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_DATE_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.c
deleted file mode 100644
index 9e9a74c78..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.c
+++ /dev/null
@@ -1,873 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_generalname.c
- *
- * GeneralName Object Definitions
- *
- */
-
-#include "pkix_pl_generalname.h"
-
-/* --Private-GeneralName-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_GeneralName_GetNssGeneralName
- * DESCRIPTION:
- *
- * Retrieves the NSS representation of the PKIX_PL_GeneralName pointed by
- * "genName" and stores it at "pNssGenName". The NSS data type CERTGeneralName
- * is stored in this object when the object was created.
- *
- * PARAMETERS:
- * "genName"
- * Address of PKIX_PL_GeneralName. Must be non-NULL.
- * "pNssGenName"
- * Address where CERTGeneralName will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a GeneralName Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_GeneralName_GetNssGeneralName(
- PKIX_PL_GeneralName *genName,
- CERTGeneralName **pNssGenName,
- void *plContext)
-{
- CERTGeneralName *nssGenName = NULL;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_GetNssGeneralName");
- PKIX_NULLCHECK_THREE(genName, pNssGenName, genName->nssGeneralNameList);
-
- nssGenName = genName->nssGeneralNameList->name;
-
- *pNssGenName = nssGenName;
-
- PKIX_RETURN(GENERALNAME);
-}
-
-/*
- * FUNCTION: pkix_pl_OtherName_Create
- * DESCRIPTION:
- *
- * Creates new OtherName which represents the CERTGeneralName pointed to by
- * "nssAltName" and stores it at "pOtherName".
- *
- * PARAMETERS:
- * "nssAltName"
- * Address of CERTGeneralName. Must be non-NULL.
- * "pOtherName"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a GeneralName Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_OtherName_Create(
- CERTGeneralName *nssAltName,
- OtherName **pOtherName,
- void *plContext)
-{
- OtherName *otherName = NULL;
- SECItem secItemName;
- SECItem secItemOID;
- SECStatus rv;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_OtherName_Create");
- PKIX_NULLCHECK_TWO(nssAltName, pOtherName);
-
- PKIX_CHECK(PKIX_PL_Malloc
- (sizeof (OtherName), (void **)&otherName, plContext),
- PKIX_MALLOCFAILED);
-
- /* make a copy of the name field */
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n");
- rv = SECITEM_CopyItem
- (NULL, &otherName->name, &nssAltName->name.OthName.name);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- /* make a copy of the oid field */
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n");
- rv = SECITEM_CopyItem
- (NULL, &otherName->oid, &nssAltName->name.OthName.oid);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- *pOtherName = otherName;
-
-cleanup:
-
- if (otherName && PKIX_ERROR_RECEIVED){
- secItemName = otherName->name;
- secItemOID = otherName->oid;
-
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
- SECITEM_FreeItem(&secItemName, PR_FALSE);
-
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
- SECITEM_FreeItem(&secItemOID, PR_FALSE);
-
- PKIX_FREE(otherName);
- otherName = NULL;
- }
-
- PKIX_RETURN(GENERALNAME);
-}
-
-/*
- * FUNCTION: pkix_pl_DirectoryName_Create
- * DESCRIPTION:
- *
- * Creates a new X500Name which represents the directoryName component of the
- * CERTGeneralName pointed to by "nssAltName" and stores it at "pX500Name".
- *
- * PARAMETERS:
- * "nssAltName"
- * Address of CERTGeneralName. Must be non-NULL.
- * "pX500Name"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a GeneralName Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_DirectoryName_Create(
- CERTGeneralName *nssAltName,
- PKIX_PL_X500Name **pX500Name,
- void *plContext)
-{
- PKIX_PL_X500Name *pkixDN = NULL;
- CERTName *dirName = NULL;
- PKIX_PL_String *pkixDNString = NULL;
- char *utf8String = NULL;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_DirectoryName_Create");
- PKIX_NULLCHECK_TWO(nssAltName, pX500Name);
-
- dirName = &nssAltName->name.directoryName;
-
- PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName(NULL, dirName,
- &pkixDN, plContext),
- PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
-
- *pX500Name = pkixDN;
-
-cleanup:
-
- PR_Free(utf8String);
- PKIX_DECREF(pkixDNString);
-
- PKIX_RETURN(GENERALNAME);
-}
-
-/*
- * FUNCTION: pkix_pl_GeneralName_Create
- * DESCRIPTION:
- *
- * Creates new GeneralName which represents the CERTGeneralName pointed to by
- * "nssAltName" and stores it at "pGenName".
- *
- * PARAMETERS:
- * "nssAltName"
- * Address of CERTGeneralName. Must be non-NULL.
- * "pGenName"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a GeneralName Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_GeneralName_Create(
- CERTGeneralName *nssAltName,
- PKIX_PL_GeneralName **pGenName,
- void *plContext)
-{
- PKIX_PL_GeneralName *genName = NULL;
- PKIX_PL_X500Name *pkixDN = NULL;
- PKIX_PL_OID *pkixOID = NULL;
- OtherName *otherName = NULL;
- CERTGeneralNameList *nssGenNameList = NULL;
- CERTGeneralNameType nameType;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Create");
- PKIX_NULLCHECK_TWO(nssAltName, pGenName);
-
- /* create a PKIX_PL_GeneralName object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_GENERALNAME_TYPE,
- sizeof (PKIX_PL_GeneralName),
- (PKIX_PL_Object **)&genName,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- nameType = nssAltName->type;
-
- /*
- * We use CERT_CreateGeneralNameList to create just one CERTGeneralName
- * item for memory allocation reason. If we want to just create one
- * item, we have to use the calling path CERT_NewGeneralName, then
- * CERT_CopyOneGeneralName. With this calling path, if we pass
- * the arena argument as NULL, in CERT_CopyOneGeneralName's subsequent
- * call to CERT_CopyName, it assumes arena should be valid, hence
- * segmentation error (not sure this is a NSS bug, certainly it is
- * not consistent). But on the other hand, we don't want to keep an
- * arena record here explicitely for every PKIX_PL_GeneralName.
- * So I concluded it is better to use CERT_CreateGeneralNameList,
- * which keeps an arena pointer in its data structure and also masks
- * out details calls from this libpkix level.
- */
-
- PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n");
- nssGenNameList = CERT_CreateGeneralNameList(nssAltName);
-
- if (nssGenNameList == NULL) {
- PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED);
- }
-
- genName->nssGeneralNameList = nssGenNameList;
-
- /* initialize fields */
- genName->type = nameType;
- genName->directoryName = NULL;
- genName->OthName = NULL;
- genName->other = NULL;
- genName->oid = NULL;
-
- switch (nameType){
- case certOtherName:
-
- PKIX_CHECK(pkix_pl_OtherName_Create
- (nssAltName, &otherName, plContext),
- PKIX_OTHERNAMECREATEFAILED);
-
- genName->OthName = otherName;
- break;
-
- case certDirectoryName:
-
- PKIX_CHECK(pkix_pl_DirectoryName_Create
- (nssAltName, &pkixDN, plContext),
- PKIX_DIRECTORYNAMECREATEFAILED);
-
- genName->directoryName = pkixDN;
- break;
- case certRegisterID:
- PKIX_CHECK(PKIX_PL_OID_CreateBySECItem(&nssAltName->name.other,
- &pkixOID, plContext),
- PKIX_OIDCREATEFAILED);
-
- genName->oid = pkixOID;
- break;
- case certDNSName:
- case certEDIPartyName:
- case certIPAddress:
- case certRFC822Name:
- case certX400Address:
- case certURI:
- genName->other = SECITEM_DupItem(&nssAltName->name.other);
- if (!genName->other) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
- break;
- default:
- PKIX_ERROR(PKIX_NAMETYPENOTSUPPORTED);
- }
-
- *pGenName = genName;
- genName = NULL;
-
-cleanup:
- PKIX_DECREF(genName);
-
- PKIX_RETURN(GENERALNAME);
-}
-
-/*
- * FUNCTION: pkix_pl_GeneralName_ToString_Helper
- * DESCRIPTION:
- *
- * Helper function that creates a string representation of the GeneralName
- * pointed to by "name" and stores it at "pString" Different mechanisms are
- * used to create the string, depending on the type of the GeneralName.
- *
- * PARAMETERS
- * "name"
- * Address of GeneralName whose string representation is desired.
- * Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a GeneralName Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_GeneralName_ToString_Helper(
- PKIX_PL_GeneralName *name,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_X500Name *pkixDN = NULL;
- PKIX_PL_OID *pkixOID = NULL;
- char *x400AsciiName = NULL;
- char *ediPartyName = NULL;
- char *asciiName = NULL;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_ToString_Helper");
- PKIX_NULLCHECK_TWO(name, pString);
-
- switch (name->type) {
- case certRFC822Name:
- case certDNSName:
- case certURI:
- /*
- * Note that we can't use PKIX_ESCASCII here because
- * name->other->data is not guaranteed to be null-terminated.
- */
-
- PKIX_NULLCHECK_ONE(name->other);
-
- PKIX_CHECK(PKIX_PL_String_Create(PKIX_UTF8,
- (name->other)->data,
- (name->other)->len,
- pString,
- plContext),
- PKIX_STRINGCREATEFAILED);
- break;
- case certEDIPartyName:
- /* XXX print out the actual bytes */
- ediPartyName = "EDIPartyName: <DER-encoded value>";
- PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
- ediPartyName,
- 0,
- pString,
- plContext),
- PKIX_STRINGCREATEFAILED);
- break;
- case certX400Address:
- /* XXX print out the actual bytes */
- x400AsciiName = "X400Address: <DER-encoded value>";
- PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
- x400AsciiName,
- 0,
- pString,
- plContext),
- PKIX_STRINGCREATEFAILED);
- break;
- case certIPAddress:
- PKIX_CHECK(pkix_pl_ipAddrBytes2Ascii
- (name->other, &asciiName, plContext),
- PKIX_IPADDRBYTES2ASCIIFAILED);
-
- PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
- asciiName,
- 0,
- pString,
- plContext),
- PKIX_STRINGCREATEFAILED);
- break;
- case certOtherName:
- PKIX_NULLCHECK_ONE(name->OthName);
-
- /* we only print type-id - don't know how to print value */
- /* XXX print out the bytes of the value */
- PKIX_CHECK(pkix_pl_oidBytes2Ascii
- (&name->OthName->oid, &asciiName, plContext),
- PKIX_OIDBYTES2ASCIIFAILED);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiName,
- 0,
- pString,
- plContext),
- PKIX_STRINGCREATEFAILED);
- break;
- case certRegisterID:
- pkixOID = name->oid;
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)pkixOID, pString, plContext),
- PKIX_OIDTOSTRINGFAILED);
- break;
- case certDirectoryName:
- pkixDN = name->directoryName;
- PKIX_CHECK(PKIX_PL_Object_ToString
- ((PKIX_PL_Object *)pkixDN, pString, plContext),
- PKIX_X500NAMETOSTRINGFAILED);
- break;
- default:
- PKIX_ERROR
- (PKIX_TOSTRINGFORTHISGENERALNAMETYPENOTSUPPORTED);
- }
-
-cleanup:
-
- PKIX_FREE(asciiName);
-
- PKIX_RETURN(GENERALNAME);
-}
-
-/*
- * FUNCTION: pkix_pl_GeneralName_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_GeneralName_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_GeneralName *name = NULL;
- SECItem secItemName;
- SECItem secItemOID;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
- PKIX_OBJECTNOTGENERALNAME);
-
- name = (PKIX_PL_GeneralName *)object;
-
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
- SECITEM_FreeItem(name->other, PR_TRUE);
- name->other = NULL;
-
- if (name->OthName){
- secItemName = name->OthName->name;
- secItemOID = name->OthName->oid;
-
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
- SECITEM_FreeItem(&secItemName, PR_FALSE);
-
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
- SECITEM_FreeItem(&secItemOID, PR_FALSE);
-
- PKIX_FREE(name->OthName);
- name->OthName = NULL;
- }
-
- if (name->nssGeneralNameList != NULL) {
- PKIX_GENERALNAME_DEBUG
- ("\t\tCalling CERT_DestroyGeneralNameList).\n");
- CERT_DestroyGeneralNameList(name->nssGeneralNameList);
- }
-
- PKIX_DECREF(name->directoryName);
- PKIX_DECREF(name->oid);
-
-cleanup:
-
- PKIX_RETURN(GENERALNAME);
-}
-
-/*
- * FUNCTION: pkix_pl_GeneralName_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_GeneralName_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *nameString = NULL;
- PKIX_PL_GeneralName *name = NULL;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_toString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
- PKIX_OBJECTNOTGENERALNAME);
-
- name = (PKIX_PL_GeneralName *)object;
-
- PKIX_CHECK(pkix_pl_GeneralName_ToString_Helper
- (name, &nameString, plContext),
- PKIX_GENERALNAMETOSTRINGHELPERFAILED);
-
- *pString = nameString;
-
-cleanup:
-
-
-
- PKIX_RETURN(GENERALNAME);
-}
-
-/*
- * FUNCTION: pkix_pl_GeneralName_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_GeneralName_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_GeneralName *name = NULL;
- PKIX_UInt32 firstHash, secondHash, nameHash;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
- PKIX_OBJECTNOTGENERALNAME);
-
- name = (PKIX_PL_GeneralName *)object;
-
- switch (name->type) {
- case certRFC822Name:
- case certDNSName:
- case certX400Address:
- case certEDIPartyName:
- case certURI:
- case certIPAddress:
- PKIX_NULLCHECK_ONE(name->other);
- PKIX_CHECK(pkix_hash
- ((const unsigned char *)
- name->other->data,
- name->other->len,
- &nameHash,
- plContext),
- PKIX_HASHFAILED);
- break;
- case certRegisterID:
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)name->oid,
- &nameHash,
- plContext),
- PKIX_OIDHASHCODEFAILED);
- break;
- case certOtherName:
- PKIX_NULLCHECK_ONE(name->OthName);
- PKIX_CHECK(pkix_hash
- ((const unsigned char *)
- name->OthName->oid.data,
- name->OthName->oid.len,
- &firstHash,
- plContext),
- PKIX_HASHFAILED);
-
- PKIX_CHECK(pkix_hash
- ((const unsigned char *)
- name->OthName->name.data,
- name->OthName->name.len,
- &secondHash,
- plContext),
- PKIX_HASHFAILED);
-
- nameHash = firstHash + secondHash;
- break;
- case certDirectoryName:
- PKIX_CHECK(PKIX_PL_Object_Hashcode
- ((PKIX_PL_Object *)
- name->directoryName,
- &nameHash,
- plContext),
- PKIX_X500NAMEHASHCODEFAILED);
- break;
- }
-
- *pHashcode = nameHash;
-
-cleanup:
-
- PKIX_RETURN(GENERALNAME);
-
-}
-
-/*
- * FUNCTION: pkix_pl_GeneralName_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_GeneralName_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_GeneralName *firstName = NULL;
- PKIX_PL_GeneralName *secondName = NULL;
- PKIX_UInt32 secondType;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a GeneralName */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_GENERALNAME_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTGENERALNAME);
-
- /*
- * Since we know firstObject is a GeneralName, if both references are
- * identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a GeneralName, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_GENERALNAME_TYPE){
- goto cleanup;
- }
-
- firstName = (PKIX_PL_GeneralName *)firstObject;
- secondName = (PKIX_PL_GeneralName *)secondObject;
-
- if (firstName->type != secondName->type){
- goto cleanup;
- }
-
- switch (firstName->type) {
- case certRFC822Name:
- case certDNSName:
- case certX400Address:
- case certEDIPartyName:
- case certURI:
- case certIPAddress:
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n");
- if (SECITEM_CompareItem(firstName->other,
- secondName->other) != SECEqual) {
- goto cleanup;
- }
- break;
- case certRegisterID:
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstName->oid,
- (PKIX_PL_Object *)secondName->oid,
- pResult,
- plContext),
- PKIX_OIDEQUALSFAILED);
- goto cleanup;
- case certOtherName:
- PKIX_NULLCHECK_TWO(firstName->OthName, secondName->OthName);
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n");
- if (SECITEM_CompareItem(&firstName->OthName->oid,
- &secondName->OthName->oid)
- != SECEqual ||
- SECITEM_CompareItem(&firstName->OthName->name,
- &secondName->OthName->name)
- != SECEqual) {
- goto cleanup;
- }
- break;
- case certDirectoryName:
- PKIX_CHECK(PKIX_PL_Object_Equals
- ((PKIX_PL_Object *)firstName->directoryName,
- (PKIX_PL_Object *)secondName->directoryName,
- pResult,
- plContext),
- PKIX_X500NAMEEQUALSFAILED);
- goto cleanup;
- }
-
- *pResult = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(GENERALNAME);
-}
-
-/*
- * FUNCTION: pkix_pl_GeneralName_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_GENERALNAME_TYPE and related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_GeneralName_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_RegisterSelf");
-
- entry.description = "GeneralName";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_GeneralName);
- entry.destructor = pkix_pl_GeneralName_Destroy;
- entry.equalsFunction = pkix_pl_GeneralName_Equals;
- entry.hashcodeFunction = pkix_pl_GeneralName_Hashcode;
- entry.toStringFunction = pkix_pl_GeneralName_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_GENERALNAME_TYPE] = entry;
-
- PKIX_RETURN(GENERALNAME);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-#ifdef BUILD_LIBPKIX_TESTS
-/*
- * FUNCTION: PKIX_PL_GeneralName_Create (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_GeneralName_Create(
- PKIX_UInt32 nameType,
- PKIX_PL_String *stringRep,
- PKIX_PL_GeneralName **pGName,
- void *plContext)
-{
- PKIX_PL_X500Name *pkixDN = NULL;
- PKIX_PL_OID *pkixOID = NULL;
- SECItem *secItem = NULL;
- char *asciiString = NULL;
- PKIX_UInt32 length = 0;
- PKIX_PL_GeneralName *genName = NULL;
- CERTGeneralName *nssGenName = NULL;
- CERTGeneralNameList *nssGenNameList = NULL;
- CERTName *nssCertName = NULL;
- PLArenaPool *arena = NULL;
-
- PKIX_ENTER(GENERALNAME, "PKIX_PL_GeneralName_Create");
- PKIX_NULLCHECK_TWO(pGName, stringRep);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stringRep,
- PKIX_ESCASCII,
- (void **)&asciiString,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- /* Create a temporary CERTGeneralName */
- PKIX_GENERALNAME_DEBUG("\t\tCalling PL_strlen).\n");
- length = PL_strlen(asciiString);
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
- secItem = SECITEM_AllocItem(NULL, NULL, length);
- PKIX_GENERALNAME_DEBUG("\t\tCalling PORT_Memcpy).\n");
- (void) PORT_Memcpy(secItem->data, asciiString, length);
- PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena).\n");
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
- PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_NewGeneralName).\n");
- nssGenName = CERT_NewGeneralName(arena, nameType);
- if (nssGenName == NULL) {
- PKIX_ERROR(PKIX_ALLOCATENEWCERTGENERALNAMEFAILED);
- }
-
- switch (nameType) {
- case certRFC822Name:
- case certDNSName:
- case certURI:
- nssGenName->name.other = *secItem;
- break;
-
- case certDirectoryName:
-
- PKIX_CHECK(PKIX_PL_X500Name_Create
- (stringRep, &pkixDN, plContext),
- PKIX_X500NAMECREATEFAILED);
-
- PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_AsciiToName).\n");
- nssCertName = CERT_AsciiToName(asciiString);
- nssGenName->name.directoryName = *nssCertName;
- break;
-
- case certRegisterID:
- PKIX_CHECK(PKIX_PL_OID_Create
- (asciiString, &pkixOID, plContext),
- PKIX_OIDCREATEFAILED);
- nssGenName->name.other = *secItem;
- break;
- default:
- /* including IPAddress, EDIPartyName, OtherName, X400Address */
- PKIX_ERROR(PKIX_UNABLETOCREATEGENERALNAMEOFTHISTYPE);
- }
-
- /* create a PKIX_PL_GeneralName object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_GENERALNAME_TYPE,
- sizeof (PKIX_PL_GeneralName),
- (PKIX_PL_Object **)&genName,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- /* create a CERTGeneralNameList */
- nssGenName->type = nameType;
- PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n");
- nssGenNameList = CERT_CreateGeneralNameList(nssGenName);
- if (nssGenNameList == NULL) {
- PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED);
- }
- genName->nssGeneralNameList = nssGenNameList;
-
- /* initialize fields */
- genName->type = nameType;
- genName->directoryName = pkixDN;
- genName->OthName = NULL;
- genName->other = secItem;
- genName->oid = pkixOID;
-
- *pGName = genName;
-cleanup:
-
- PKIX_FREE(asciiString);
-
- if (nssCertName != NULL) {
- PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyName).\n");
- CERT_DestroyName(nssCertName);
- }
-
- if (arena){ /* will free nssGenName */
- PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(pkixDN);
- PKIX_DECREF(pkixOID);
-
- PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
- if (secItem){
- SECITEM_FreeItem(secItem, PR_TRUE);
- secItem = NULL;
- }
- }
-
- PKIX_RETURN(GENERALNAME);
-}
-
-#endif /* BUILD_LIBPKIX_TESTS */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.h
deleted file mode 100644
index 3cb5264d5..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_generalname.h
- *
- * GeneralName Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_GENERALNAME_H
-#define _PKIX_PL_GENERALNAME_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_GeneralNameStruct{
- CERTGeneralNameList *nssGeneralNameList;
- CERTGeneralNameType type;
- PKIX_PL_X500Name *directoryName;
- PKIX_PL_OID *oid;
- OtherName *OthName;
- SECItem *other;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_GeneralName_Create(
- CERTGeneralName *nssAltName,
- PKIX_PL_GeneralName **pGenName,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_GeneralName_GetNssGeneralName(
- PKIX_PL_GeneralName *genName,
- CERTGeneralName **pNssGenName,
- void *plContext);
-
-PKIX_Error *pkix_pl_GeneralName_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_GENERALNAME_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c
deleted file mode 100644
index c2786be8e..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c
+++ /dev/null
@@ -1,870 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_infoaccess.c
- *
- * InfoAccess Object Definitions
- *
- */
-
-#include "pkix_pl_infoaccess.h"
-
-/* --Private-InfoAccess-Functions----------------------------------*/
-
-/*
- * FUNCTION: pkix_pl_InfoAccess_Create
- * DESCRIPTION:
- *
- * This function creates an InfoAccess from the method provided in "method" and
- * the GeneralName provided in "generalName" and stores the result at
- * "pInfoAccess".
- *
- * PARAMETERS
- * "method"
- * The UInt32 value to be stored as the method field of the InfoAccess.
- * "generalName"
- * The GeneralName to be stored as the generalName field of the InfoAccess.
- * Must be non-NULL.
- * "pInfoAccess"
- * Address where the result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_InfoAccess_Create(
- PKIX_UInt32 method,
- PKIX_PL_GeneralName *generalName,
- PKIX_PL_InfoAccess **pInfoAccess,
- void *plContext)
-{
-
- PKIX_PL_InfoAccess *infoAccess = NULL;
-
- PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Create");
- PKIX_NULLCHECK_TWO(generalName, pInfoAccess);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_INFOACCESS_TYPE,
- sizeof (PKIX_PL_InfoAccess),
- (PKIX_PL_Object **)&infoAccess,
- plContext),
- PKIX_COULDNOTCREATEINFOACCESSOBJECT);
-
- infoAccess->method = method;
-
- PKIX_INCREF(generalName);
- infoAccess->location = generalName;
-
- *pInfoAccess = infoAccess;
- infoAccess = NULL;
-
-cleanup:
- PKIX_DECREF(infoAccess);
-
- PKIX_RETURN(INFOACCESS);
-}
-
-/*
- * FUNCTION: pkix_pl_InfoAccess_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_pki.h)
- */
-static PKIX_Error *
-pkix_pl_InfoAccess_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_InfoAccess *infoAccess = NULL;
-
- PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_INFOACCESS_TYPE, plContext),
- PKIX_OBJECTNOTANINFOACCESS);
-
- infoAccess = (PKIX_PL_InfoAccess *)object;
-
- PKIX_DECREF(infoAccess->location);
-
-cleanup:
-
- PKIX_RETURN(INFOACCESS);
-}
-
-/*
- * FUNCTION: pkix_pl_InfoAccess_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_pki.h)
- */
-static PKIX_Error *
-pkix_pl_InfoAccess_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_InfoAccess *infoAccess;
- PKIX_PL_String *infoAccessString = NULL;
- char *asciiFormat = NULL;
- char *asciiMethod = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *methodString = NULL;
- PKIX_PL_String *locationString = NULL;
-
- PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_INFOACCESS_TYPE, plContext),
- PKIX_OBJECTNOTINFOACCESS);
-
- infoAccess = (PKIX_PL_InfoAccess *)object;
-
- asciiFormat =
- "["
- "method:%s, "
- "location:%s"
- "]";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- switch(infoAccess->method) {
- case PKIX_INFOACCESS_CA_ISSUERS:
- asciiMethod = "caIssuers";
- break;
- case PKIX_INFOACCESS_OCSP:
- asciiMethod = "ocsp";
- break;
- case PKIX_INFOACCESS_TIMESTAMPING:
- asciiMethod = "timestamping";
- break;
- case PKIX_INFOACCESS_CA_REPOSITORY:
- asciiMethod = "caRepository";
- break;
- default:
- asciiMethod = "unknown";
- }
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiMethod,
- 0,
- &methodString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_TOSTRING(infoAccess->location, &locationString, plContext,
- PKIX_GENERALNAMETOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&infoAccessString,
- plContext,
- formatString,
- methodString,
- locationString),
- PKIX_SPRINTFFAILED);
-
- *pString = infoAccessString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(methodString);
- PKIX_DECREF(locationString);
-
- PKIX_RETURN(INFOACCESS);
-}
-
-/*
- * FUNCTION: pkix_pl_InfoAccess_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_pki.h)
- */
-static PKIX_Error *
-pkix_pl_InfoAccess_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_InfoAccess *infoAccess = NULL;
- PKIX_UInt32 infoAccessHash;
-
- PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_INFOACCESS_TYPE, plContext),
- PKIX_OBJECTNOTINFOACCESS);
-
- infoAccess = (PKIX_PL_InfoAccess *)object;
-
- PKIX_HASHCODE(infoAccess->location, &infoAccessHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- infoAccessHash += (infoAccess->method << 7);
-
- *pHashcode = infoAccessHash;
-
-cleanup:
-
- PKIX_RETURN(INFOACCESS);
-
-}
-
-/*
- * FUNCTION: pkix_pl_InfoAccess_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_pki.h)
- */
-static PKIX_Error *
-pkix_pl_InfoAccess_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_InfoAccess *firstInfoAccess = NULL;
- PKIX_PL_InfoAccess *secondInfoAccess = NULL;
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult;
-
- PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a InfoAccess */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_INFOACCESS_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTINFOACCESS);
-
- /*
- * Since we know firstObject is a InfoAccess, if both references are
- * identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a InfoAccess, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_INFOACCESS_TYPE) goto cleanup;
-
- firstInfoAccess = (PKIX_PL_InfoAccess *)firstObject;
- secondInfoAccess = (PKIX_PL_InfoAccess *)secondObject;
-
- *pResult = PKIX_FALSE;
-
- if (firstInfoAccess->method != secondInfoAccess->method) {
- goto cleanup;
- }
-
- PKIX_EQUALS(firstInfoAccess, secondInfoAccess, &cmpResult, plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- *pResult = cmpResult;
-
-cleanup:
-
- PKIX_RETURN(INFOACCESS);
-}
-
-/*
- * FUNCTION: pkix_pl_InfoAccess_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_INFOACCESS_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_InfoAccess_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(INFOACCESS,
- "pkix_pl_InfoAccess_RegisterSelf");
-
- entry.description = "InfoAccess";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_InfoAccess);
- entry.destructor = pkix_pl_InfoAccess_Destroy;
- entry.equalsFunction = pkix_pl_InfoAccess_Equals;
- entry.hashcodeFunction = pkix_pl_InfoAccess_Hashcode;
- entry.toStringFunction = pkix_pl_InfoAccess_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_INFOACCESS_TYPE] = entry;
-
- PKIX_RETURN(INFOACCESS);
-}
-
-/*
- * FUNCTION: pkix_pl_InfoAccess_CreateList
- * DESCRIPTION:
- *
- * Based on data in CERTAuthInfoAccess array "nssInfoAccess", this function
- * creates and returns a PKIX_List of PKIX_PL_InfoAccess at "pInfoAccessList".
- *
- * PARAMETERS
- * "nssInfoAccess"
- * The pointer array of CERTAuthInfoAccess that contains access data.
- * May be NULL.
- * "pInfoAccessList"
- * Address where a list of PKIX_PL_InfoAccess is returned.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_InfoAccess_CreateList(
- CERTAuthInfoAccess **nssInfoAccess,
- PKIX_List **pInfoAccessList, /* of PKIX_PL_InfoAccess */
- void *plContext)
-{
- PKIX_List *infoAccessList = NULL;
- PKIX_PL_InfoAccess *infoAccess = NULL;
- PKIX_PL_GeneralName *location = NULL;
- PKIX_UInt32 method;
- int i;
-
- PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_CreateList");
- PKIX_NULLCHECK_ONE(pInfoAccessList);
-
- PKIX_CHECK(PKIX_List_Create(&infoAccessList, plContext),
- PKIX_LISTCREATEFAILED);
-
- if (nssInfoAccess == NULL) {
- goto cleanup;
- }
-
- for (i = 0; nssInfoAccess[i] != NULL; i++) {
-
- if (nssInfoAccess[i]->location == NULL) {
- continue;
- }
-
- PKIX_CHECK(pkix_pl_GeneralName_Create
- (nssInfoAccess[i]->location, &location, plContext),
- PKIX_GENERALNAMECREATEFAILED);
-
- PKIX_CERT_DEBUG("\t\tCalling SECOID_FindOIDTag).\n");
- method = SECOID_FindOIDTag(&nssInfoAccess[i]->method);
- /* Map NSS access method value into PKIX constant */
- switch(method) {
- case SEC_OID_PKIX_CA_ISSUERS:
- method = PKIX_INFOACCESS_CA_ISSUERS;
- break;
- case SEC_OID_PKIX_OCSP:
- method = PKIX_INFOACCESS_OCSP;
- break;
- case SEC_OID_PKIX_TIMESTAMPING:
- method = PKIX_INFOACCESS_TIMESTAMPING;
- break;
- case SEC_OID_PKIX_CA_REPOSITORY:
- method = PKIX_INFOACCESS_CA_REPOSITORY;
- break;
- default:
- PKIX_ERROR(PKIX_UNKNOWNINFOACCESSMETHOD);
- }
-
- PKIX_CHECK(pkix_pl_InfoAccess_Create
- (method, location, &infoAccess, plContext),
- PKIX_INFOACCESSCREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (infoAccessList,
- (PKIX_PL_Object *)infoAccess,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_DECREF(infoAccess);
- PKIX_DECREF(location);
- }
-
- *pInfoAccessList = infoAccessList;
- infoAccessList = NULL;
-
-cleanup:
-
- PKIX_DECREF(infoAccessList);
- PKIX_DECREF(infoAccess);
- PKIX_DECREF(location);
-
- PKIX_RETURN(INFOACCESS);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_InfoAccess_GetMethod (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_InfoAccess_GetMethod(
- PKIX_PL_InfoAccess *infoAccess,
- PKIX_UInt32 *pMethod,
- void *plContext)
-{
- PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetMethod");
- PKIX_NULLCHECK_TWO(infoAccess, pMethod);
-
- *pMethod = infoAccess->method;
-
- PKIX_RETURN(INFOACCESS);
-}
-
-/*
- * FUNCTION: PKIX_PL_InfoAccess_GetLocation (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_InfoAccess_GetLocation(
- PKIX_PL_InfoAccess *infoAccess,
- PKIX_PL_GeneralName **pLocation,
- void *plContext)
-{
- PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetLocation");
- PKIX_NULLCHECK_TWO(infoAccess, pLocation);
-
- PKIX_INCREF(infoAccess->location);
-
- *pLocation = infoAccess->location;
-
-cleanup:
- PKIX_RETURN(INFOACCESS);
-}
-
-/*
- * FUNCTION: PKIX_PL_InfoAccess_GetLocationType (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_InfoAccess_GetLocationType(
- PKIX_PL_InfoAccess *infoAccess,
- PKIX_UInt32 *pType,
- void *plContext)
-{
- PKIX_PL_String *locationString = NULL;
- PKIX_UInt32 type = PKIX_INFOACCESS_LOCATION_UNKNOWN;
- PKIX_UInt32 len = 0;
- void *location = NULL;
-
- PKIX_ENTER(INFOACCESS, "PKIX_PL_InfoAccess_GetLocationType");
- PKIX_NULLCHECK_TWO(infoAccess, pType);
-
- if (infoAccess->location != NULL) {
-
- PKIX_TOSTRING(infoAccess->location, &locationString, plContext,
- PKIX_GENERALNAMETOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (locationString, PKIX_ESCASCII, &location, &len, plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_OID_DEBUG("\tCalling PORT_Strcmp).\n");
- if (PORT_Strncmp(location, "ldap:", 5) == 0){
- type = PKIX_INFOACCESS_LOCATION_LDAP;
- } else
- if (PORT_Strncmp(location, "http:", 5) == 0){
- type = PKIX_INFOACCESS_LOCATION_HTTP;
- }
- }
-
- *pType = type;
-
-cleanup:
-
- PKIX_PL_Free(location, plContext);
- PKIX_DECREF(locationString);
-
- PKIX_RETURN(INFOACCESS);
-}
-
-/*
- * FUNCTION: pkix_pl_InfoAccess_ParseTokens
- * DESCRIPTION:
- *
- * This function parses the string beginning at "startPos" into tokens using
- * the separator contained in "separator" and the terminator contained in
- * "terminator", copying the tokens into space allocated from the arena
- * pointed to by "arena". It stores in "tokens" a null-terminated array of
- * pointers to those tokens.
- *
- * PARAMETERS
- * "arena"
- * Address of a PRArenaPool to be used in populating the LDAPLocation.
- * Must be non-NULL.
- * "startPos"
- * The address of char string that contains a subset of ldap location.
- * "tokens"
- * The address of an array of char string for storing returned tokens.
- * Must be non-NULL.
- * "separator"
- * The character that is taken as token separator. Must be non-NULL.
- * "terminator"
- * The character that is taken as parsing terminator. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an InfoAccess Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_InfoAccess_ParseTokens(
- PRArenaPool *arena,
- char **startPos, /* return update */
- char ***tokens,
- char separator,
- char terminator,
- void *plContext)
-{
- PKIX_UInt32 numFilters = 0;
- char *endPos = NULL;
- char **filterP = NULL;
-
- PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ParseTokens");
- PKIX_NULLCHECK_THREE(arena, startPos, tokens);
-
- endPos = *startPos;
-
- /* First pass: parse to <terminator> to count number of components */
- numFilters = 0;
- while (*endPos != terminator && *endPos != '\0') {
- endPos++;
- if (*endPos == separator) {
- numFilters++;
- }
- }
-
- if (*endPos != terminator) {
- PKIX_ERROR(PKIX_LOCATIONSTRINGNOTPROPERLYTERMINATED);
- }
-
- /* Last component doesn't need a separator, although we allow it */
- if (endPos > *startPos && *(endPos-1) != separator) {
- numFilters++;
- }
-
- /*
- * If string is a=xx, b=yy, c=zz, etc., use a=xx for filter,
- * and everything else for the base
- */
- if (numFilters > 2) numFilters = 2;
-
- filterP = PORT_ArenaZNewArray(arena, char*, numFilters+1);
- if (filterP == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- /* Second pass: parse to fill in components in token array */
- *tokens = filterP;
- endPos = *startPos;
-
- while (numFilters) {
- if (*endPos == separator || *endPos == terminator) {
- PKIX_UInt32 len = endPos - *startPos;
- char *p = PORT_ArenaZAlloc(arena, len+1);
- if (p == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- PORT_Memcpy(p, *startPos, len);
- p[len] = '\0';
-
- *filterP = p;
- filterP++;
- numFilters--;
-
- separator = terminator;
-
- if (*endPos == '\0') {
- *startPos = endPos;
- break;
- } else {
- endPos++;
- *startPos = endPos;
- continue;
- }
- }
- endPos++;
- }
-
- *filterP = NULL;
-
-cleanup:
-
- PKIX_RETURN(INFOACCESS);
-}
-
-static int
-pkix_pl_HexDigitToInt(
- int ch)
-{
- if (isdigit(ch)) {
- ch = ch - '0';
- } else if (isupper(ch)) {
- ch = ch - 'A' + 10;
- } else {
- ch = ch - 'a' + 10;
- }
- return ch;
-}
-
-/*
- * Convert the "%" hex hex escape sequences in the URL 'location' in place.
- */
-static void
-pkix_pl_UnescapeURL(
- char *location)
-{
- const char *src;
- char *dst;
-
- for (src = dst = location; *src != '\0'; src++, dst++) {
- if (*src == '%' && isxdigit((unsigned char)*(src+1)) &&
- isxdigit((unsigned char)*(src+2))) {
- *dst = pkix_pl_HexDigitToInt((unsigned char)*(src+1));
- *dst *= 16;
- *dst += pkix_pl_HexDigitToInt((unsigned char)*(src+2));
- src += 2;
- } else {
- *dst = *src;
- }
- }
- *dst = *src; /* the terminating null */
-}
-
-/*
- * FUNCTION: pkix_pl_InfoAccess_ParseLocation
- * DESCRIPTION:
- *
- * This function parses the GeneralName pointed to by "generalName" into the
- * fields of the LDAPRequestParams pointed to by "request" and a domainName
- * pointed to by "pDomainName", using the PRArenaPool pointed to by "arena" to
- * allocate storage for the request components and for the domainName string.
- *
- * The expected GeneralName string should be in the format described by the
- * following BNF:
- *
- * ldap://<ldap-server-site>/[cn=<cname>][,o=<org>][,c=<country>]?
- * [caCertificate|crossCertificatPair|certificateRevocationList];
- * [binary|<other-type>]
- * [[,caCertificate|crossCertificatPair|certificateRevocationList]
- * [binary|<other-type>]]*
- *
- * PARAMETERS
- * "generalName"
- * Address of the GeneralName whose LDAPLocation is to be parsed. Must be
- * non-NULL.
- * "arena"
- * Address of PRArenaPool to be used for the domainName and for components
- * of the LDAPRequest. Must be non-NULL.
- * "request"
- * Address of the LDAPRequestParams into which request components are
- * stored. Must be non-NULL.
- * *pDomainName"
- * Address at which the domainName is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an InfoAccess Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_InfoAccess_ParseLocation(
- PKIX_PL_GeneralName *generalName,
- PRArenaPool *arena,
- LDAPRequestParams *request,
- char **pDomainName,
- void *plContext)
-{
- PKIX_PL_String *locationString = NULL;
- PKIX_UInt32 len = 0;
- PKIX_UInt32 ncIndex = 0;
- char *domainName = NULL;
- char **avaArray = NULL;
- char **attrArray = NULL;
- char *attr = NULL;
- char *locationAscii = NULL;
- char *startPos = NULL;
- char *endPos = NULL;
- char *avaPtr = NULL;
- LdapAttrMask attrBit = 0;
- LDAPNameComponent **setOfNameComponent = NULL;
- LDAPNameComponent *nameComponent = NULL;
-
- PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ParseLocation");
- PKIX_NULLCHECK_FOUR(generalName, arena, request, pDomainName);
-
- PKIX_TOSTRING(generalName, &locationString, plContext,
- PKIX_GENERALNAMETOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (locationString,
- PKIX_ESCASCII,
- (void **)&locationAscii,
- &len,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- pkix_pl_UnescapeURL(locationAscii);
-
- /* Skip "ldap:" */
- endPos = locationAscii;
- while (*endPos != ':' && *endPos != '\0') {
- endPos++;
- }
- if (*endPos == '\0') {
- PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGLOCATIONTYPE);
- }
-
- /* Skip "//" */
- endPos++;
- if (*endPos != '\0' && *(endPos+1) != '0' &&
- *endPos == '/' && *(endPos+1) == '/') {
- endPos += 2;
- } else {
- PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGDOUBLESLASH);
- }
-
- /* Get the server-site */
- startPos = endPos;
- while(*endPos != '/' && *(endPos) != '\0') {
- endPos++;
- }
- if (*endPos == '\0') {
- PKIX_ERROR(PKIX_GENERALNAMESTRINGMISSINGSERVERSITE);
- }
-
- len = endPos - startPos;
- endPos++;
-
- domainName = PORT_ArenaZAlloc(arena, len + 1);
- if (!domainName) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- PORT_Memcpy(domainName, startPos, len);
-
- domainName[len] = '\0';
-
- *pDomainName = domainName;
-
- /*
- * Get a list of AttrValueAssertions (such as
- * "cn=CommonName, o=Organization, c=US" into a null-terminated array
- */
- startPos = endPos;
- PKIX_CHECK(pkix_pl_InfoAccess_ParseTokens
- (arena,
- &startPos,
- (char ***) &avaArray,
- ',',
- '?',
- plContext),
- PKIX_INFOACCESSPARSETOKENSFAILED);
-
- /* Count how many AVAs we have */
- for (len = 0; avaArray[len] != NULL; len++) {}
-
- if (len < 2) {
- PKIX_ERROR(PKIX_NOTENOUGHNAMECOMPONENTSINGENERALNAME);
- }
-
- /* Use last name component for baseObject */
- request->baseObject = avaArray[len - 1];
-
- /* Use only one component for filter. LDAP servers aren't too smart. */
- len = 2; /* Eliminate this when servers get smarter. */
-
- avaArray[len - 1] = NULL;
-
- /* Get room for null-terminated array of (LdapNameComponent *) */
- setOfNameComponent = PORT_ArenaZNewArray(arena, LDAPNameComponent *, len);
- if (setOfNameComponent == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- /* Get room for the remaining LdapNameComponents */
- nameComponent = PORT_ArenaZNewArray(arena, LDAPNameComponent, --len);
- if (nameComponent == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- /* Convert remaining AVAs to LDAPNameComponents */
- for (ncIndex = 0; ncIndex < len; ncIndex ++) {
- setOfNameComponent[ncIndex] = nameComponent;
- avaPtr = avaArray[ncIndex];
- nameComponent->attrType = (unsigned char *)avaPtr;
- while ((*avaPtr != '=') && (*avaPtr != '\0')) {
- avaPtr++;
- if (*avaPtr == '\0') {
- PKIX_ERROR(PKIX_NAMECOMPONENTWITHNOEQ);
- }
- }
- *(avaPtr++) = '\0';
- nameComponent->attrValue = (unsigned char *)avaPtr;
- nameComponent++;
- }
-
- setOfNameComponent[len] = NULL;
- request->nc = setOfNameComponent;
-
- /*
- * Get a list of AttrTypes (such as
- * "caCertificate;binary, crossCertificatePair;binary") into
- * a null-terminated array
- */
-
- PKIX_CHECK(pkix_pl_InfoAccess_ParseTokens
- (arena,
- (char **) &startPos,
- (char ***) &attrArray,
- ',',
- '\0',
- plContext),
- PKIX_INFOACCESSPARSETOKENSFAILED);
-
- /* Convert array of Attr Types into a bit mask */
- request->attributes = 0;
- attr = attrArray[0];
- while (attr != NULL) {
- PKIX_CHECK(pkix_pl_LdapRequest_AttrStringToBit
- (attr, &attrBit, plContext),
- PKIX_LDAPREQUESTATTRSTRINGTOBITFAILED);
- request->attributes |= attrBit;
- attr = *(++attrArray);
- }
-
-cleanup:
-
- PKIX_PL_Free(locationAscii, plContext);
- PKIX_DECREF(locationString);
-
- PKIX_RETURN(INFOACCESS);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.h
deleted file mode 100644
index e364e3d7f..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_infoaccess.h
- *
- * InfoAccess Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_INFOACCESS_H
-#define _PKIX_PL_INFOACCESS_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_InfoAccessStruct{
- PKIX_UInt32 method;
- PKIX_PL_GeneralName *location;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_InfoAccess_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_pl_InfoAccess_CreateList(
- CERTAuthInfoAccess **authInfoAccess,
- PKIX_List **pAiaList, /* of PKIX_PL_InfoAccess */
- void *plContext);
-
-PKIX_Error *
-pkix_pl_InfoAccess_ParseLocation(
- PKIX_PL_GeneralName *generalName,
- PRArenaPool *arena,
- LDAPRequestParams *request,
- char **pDomainName,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_INFOACCESS_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c
deleted file mode 100644
index b9557211e..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c
+++ /dev/null
@@ -1,1274 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_nameconstraints.c
- *
- * Name Constraints Object Functions Definitions
- *
- */
-
-#include "pkix_pl_nameconstraints.h"
-
-
-/* --Private-NameConstraints-Functions----------------------------- */
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_GetPermitted
- * DESCRIPTION:
- *
- * This function retrieve name constraints permitted list from NSS
- * data in "nameConstraints" and returns a PKIX_PL_GeneralName list
- * in "pPermittedList".
- *
- * PARAMETERS
- * "nameConstraints"
- * Address of CertNameConstraints which has a pointer to
- * CERTNameConstraints data. Must be non-NULL.
- * "pPermittedList"
- * Address where returned permitted name list is stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_GetPermitted(
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_List **pPermittedList,
- void *plContext)
-{
- CERTNameConstraints *nssNameConstraints = NULL;
- CERTNameConstraints **nssNameConstraintsList = NULL;
- CERTNameConstraint *nssPermitted = NULL;
- CERTNameConstraint *firstPermitted = NULL;
- PKIX_List *permittedList = NULL;
- PKIX_PL_GeneralName *name = NULL;
- PKIX_UInt32 numItems = 0;
- PKIX_UInt32 i;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS,
- "pkix_pl_CertNameConstraints_GetPermitted");
- PKIX_NULLCHECK_TWO(nameConstraints, pPermittedList);
-
- /*
- * nssNameConstraints is an array of CERTNameConstraints
- * pointers where CERTNameConstraints keep its permitted and excluded
- * lists as pointer array of CERTNameConstraint.
- */
-
- if (nameConstraints->permittedList == NULL) {
-
- PKIX_OBJECT_LOCK(nameConstraints);
-
- if (nameConstraints->permittedList == NULL) {
-
- PKIX_CHECK(PKIX_List_Create(&permittedList, plContext),
- PKIX_LISTCREATEFAILED);
-
- numItems = nameConstraints->numNssNameConstraints;
- nssNameConstraintsList =
- nameConstraints->nssNameConstraintsList;
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_NULLCHECK_ONE(nssNameConstraintsList);
- nssNameConstraints = *(nssNameConstraintsList + i);
- PKIX_NULLCHECK_ONE(nssNameConstraints);
-
- if (nssNameConstraints->permited != NULL) {
-
- nssPermitted = nssNameConstraints->permited;
- firstPermitted = nssPermitted;
-
- do {
-
- PKIX_CHECK(pkix_pl_GeneralName_Create
- (&nssPermitted->name, &name, plContext),
- PKIX_GENERALNAMECREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (permittedList,
- (PKIX_PL_Object *)name,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(name);
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_GetNextNameConstraint\n");
- nssPermitted = CERT_GetNextNameConstraint
- (nssPermitted);
-
- } while (nssPermitted != firstPermitted);
-
- }
- }
-
- PKIX_CHECK(PKIX_List_SetImmutable(permittedList, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- nameConstraints->permittedList = permittedList;
-
- }
-
- PKIX_OBJECT_UNLOCK(nameConstraints);
-
- }
-
- PKIX_INCREF(nameConstraints->permittedList);
-
- *pPermittedList = nameConstraints->permittedList;
-
-cleanup:
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_GetExcluded
- * DESCRIPTION:
- *
- * This function retrieve name constraints excluded list from NSS
- * data in "nameConstraints" and returns a PKIX_PL_GeneralName list
- * in "pExcludedList".
- *
- * PARAMETERS
- * "nameConstraints"
- * Address of CertNameConstraints which has a pointer to NSS data.
- * Must be non-NULL.
- * "pPermittedList"
- * Address where returned excluded name list is stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_GetExcluded(
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_List **pExcludedList,
- void *plContext)
-{
- CERTNameConstraints *nssNameConstraints = NULL;
- CERTNameConstraints **nssNameConstraintsList = NULL;
- CERTNameConstraint *nssExcluded = NULL;
- CERTNameConstraint *firstExcluded = NULL;
- PKIX_List *excludedList = NULL;
- PKIX_PL_GeneralName *name = NULL;
- PKIX_UInt32 numItems = 0;
- PKIX_UInt32 i;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS,
- "pkix_pl_CertNameConstraints_GetExcluded");
- PKIX_NULLCHECK_TWO(nameConstraints, pExcludedList);
-
- if (nameConstraints->excludedList == NULL) {
-
- PKIX_OBJECT_LOCK(nameConstraints);
-
- if (nameConstraints->excludedList == NULL) {
-
- PKIX_CHECK(PKIX_List_Create(&excludedList, plContext),
- PKIX_LISTCREATEFAILED);
-
- numItems = nameConstraints->numNssNameConstraints;
- nssNameConstraintsList =
- nameConstraints->nssNameConstraintsList;
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_NULLCHECK_ONE(nssNameConstraintsList);
- nssNameConstraints = *(nssNameConstraintsList + i);
- PKIX_NULLCHECK_ONE(nssNameConstraints);
-
- if (nssNameConstraints->excluded != NULL) {
-
- nssExcluded = nssNameConstraints->excluded;
- firstExcluded = nssExcluded;
-
- do {
-
- PKIX_CHECK(pkix_pl_GeneralName_Create
- (&nssExcluded->name, &name, plContext),
- PKIX_GENERALNAMECREATEFAILED);
-
- PKIX_CHECK(PKIX_List_AppendItem
- (excludedList,
- (PKIX_PL_Object *)name,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
-
- PKIX_DECREF(name);
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_GetNextNameConstraint\n");
- nssExcluded = CERT_GetNextNameConstraint
- (nssExcluded);
-
- } while (nssExcluded != firstExcluded);
-
- }
-
- }
- PKIX_CHECK(PKIX_List_SetImmutable(excludedList, plContext),
- PKIX_LISTSETIMMUTABLEFAILED);
-
- nameConstraints->excludedList = excludedList;
-
- }
-
- PKIX_OBJECT_UNLOCK(nameConstraints);
- }
-
- PKIX_INCREF(nameConstraints->excludedList);
-
- *pExcludedList = nameConstraints->excludedList;
-
-cleanup:
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_CheckNameSpaceNssNames
- * DESCRIPTION:
- *
- * This function checks if CERTGeneralNames in "nssSubjectNames" comply
- * with the permitted and excluded names in "nameConstraints". It returns
- * PKIX_TRUE in "pCheckPass", if the Names satify the name space of the
- * permitted list and if the Names are not in the excluded list. Otherwise,
- * it returns PKIX_FALSE.
- *
- * PARAMETERS
- * "nssSubjectNames"
- * List of CERTGeneralName that nameConstraints verification is based on.
- * "nameConstraints"
- * Address of CertNameConstraints that provides lists of permitted
- * and excluded names. Must be non-NULL.
- * "pCheckPass"
- * Address where PKIX_TRUE is returned if the all names in "nameList" are
- * valid.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CertNameConstraints_CheckNameSpaceNssNames(
- CERTGeneralName *nssSubjectNames,
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_Boolean *pCheckPass,
- void *plContext)
-{
- CERTNameConstraints **nssNameConstraintsList = NULL;
- CERTNameConstraints *nssNameConstraints = NULL;
- CERTGeneralName *nssMatchName = NULL;
- PRArenaPool *arena = NULL;
- PKIX_UInt32 numItems = 0;
- PKIX_UInt32 i;
- SECStatus status = SECSuccess;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS,
- "pkix_pl_CertNameConstraints_CheckNameSpaceNssNames");
- PKIX_NULLCHECK_THREE(nssSubjectNames, nameConstraints, pCheckPass);
-
- *pCheckPass = PKIX_TRUE;
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena\n");
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- nssMatchName = nssSubjectNames;
- nssNameConstraintsList = nameConstraints->nssNameConstraintsList;
-
- /*
- * CERTNameConstraint items in each permitted or excluded list
- * is verified as OR condition. That means, if one item matched,
- * then the checking on the remaining items on the list is skipped.
- * (see NSS cert_CompareNameWithConstraints(...)).
- * Items on PKIX_PL_NameConstraint's nssNameConstraints are verified
- * as AND condition. PKIX_PL_NameConstraint keeps an array of pointers
- * of CERTNameConstraints resulting from merging multiple
- * PKIX_PL_NameConstraints. Since each CERTNameConstraint are created
- * for different entity, a union condition of these entities then is
- * performed.
- */
-
- do {
-
- numItems = nameConstraints->numNssNameConstraints;
-
- for (i = 0; i < numItems; i++) {
-
- PKIX_NULLCHECK_ONE(nssNameConstraintsList);
- nssNameConstraints = *(nssNameConstraintsList + i);
- PKIX_NULLCHECK_ONE(nssNameConstraints);
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_CheckNameSpace\n");
- status = CERT_CheckNameSpace
- (arena, nssNameConstraints, nssMatchName);
- if (status != SECSuccess) {
- break;
- }
-
- }
-
- if (status != SECSuccess) {
- break;
- }
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_GetNextGeneralName\n");
- nssMatchName = CERT_GetNextGeneralName(nssMatchName);
-
- } while (nssMatchName != nssSubjectNames);
-
- if (status == SECFailure) {
-
- *pCheckPass = PKIX_FALSE;
- }
-
-cleanup:
-
- if (arena){
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling PORT_FreeArena).\n");
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_NameConstraints_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext),
- PKIX_OBJECTNOTCERTNAMECONSTRAINTS);
-
- nameConstraints = (PKIX_PL_CertNameConstraints *)object;
-
- PKIX_CHECK(PKIX_PL_Free
- (nameConstraints->nssNameConstraintsList, plContext),
- PKIX_FREEFAILED);
-
- if (nameConstraints->arena){
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling PORT_FreeArena).\n");
- PORT_FreeArena(nameConstraints->arena, PR_FALSE);
- nameConstraints->arena = NULL;
- }
-
- PKIX_DECREF(nameConstraints->permittedList);
- PKIX_DECREF(nameConstraints->excludedList);
-
-cleanup:
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_ToString_Helper
- * DESCRIPTION:
- *
- * Helper function that creates a string representation of the object
- * NameConstraints and stores it at "pString".
- *
- * PARAMETERS
- * "nameConstraints"
- * Address of CertNameConstraints whose string representation is
- * desired. Must be non-NULL.
- * "pString"
- * Address where string object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a
- * non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_ToString_Helper(
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_PL_String **pString,
- void *plContext)
-{
- char *asciiFormat = NULL;
- PKIX_PL_String *formatString = NULL;
- PKIX_List *permittedList = NULL;
- PKIX_List *excludedList = NULL;
- PKIX_PL_String *permittedListString = NULL;
- PKIX_PL_String *excludedListString = NULL;
- PKIX_PL_String *nameConstraintsString = NULL;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS,
- "pkix_pl_CertNameConstraints_ToString_Helper");
- PKIX_NULLCHECK_TWO(nameConstraints, pString);
-
- asciiFormat =
- "[\n"
- "\t\tPermitted Name: %s\n"
- "\t\tExcluded Name: %s\n"
- "\t]\n";
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- asciiFormat,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
- (nameConstraints, &permittedList, plContext),
- PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED);
-
- PKIX_TOSTRING(permittedList, &permittedListString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
- (nameConstraints, &excludedList, plContext),
- PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED);
-
- PKIX_TOSTRING(excludedList, &excludedListString, plContext,
- PKIX_LISTTOSTRINGFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (&nameConstraintsString,
- plContext,
- formatString,
- permittedListString,
- excludedListString),
- PKIX_SPRINTFFAILED);
-
- *pString = nameConstraintsString;
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(permittedList);
- PKIX_DECREF(excludedList);
- PKIX_DECREF(permittedListString);
- PKIX_DECREF(excludedListString);
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *nameConstraintsString = NULL;
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(
- object, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext),
- PKIX_OBJECTNOTCERTNAMECONSTRAINTS);
-
- nameConstraints = (PKIX_PL_CertNameConstraints *)object;
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_ToString_Helper
- (nameConstraints, &nameConstraintsString, plContext),
- PKIX_CERTNAMECONSTRAINTSTOSTRINGHELPERFAILED);
-
- *pString = nameConstraintsString;
-
-cleanup:
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
- PKIX_List *permittedList = NULL;
- PKIX_List *excludedList = NULL;
- PKIX_UInt32 permitHash = 0;
- PKIX_UInt32 excludeHash = 0;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType
- (object, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext),
- PKIX_OBJECTNOTCERTNAMECONSTRAINTS);
-
- nameConstraints = (PKIX_PL_CertNameConstraints *)object;
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
- (nameConstraints, &permittedList, plContext),
- PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED);
-
- PKIX_HASHCODE(permittedList, &permitHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
- (nameConstraints, &excludedList, plContext),
- PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED);
-
- PKIX_HASHCODE(excludedList, &excludeHash, plContext,
- PKIX_OBJECTHASHCODEFAILED);
-
- *pHashcode = (((permitHash << 7) + excludeHash) << 7) +
- nameConstraints->numNssNameConstraints;
-
-cleanup:
-
- PKIX_DECREF(permittedList);
- PKIX_DECREF(excludedList);
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *firstNC = NULL;
- PKIX_PL_CertNameConstraints *secondNC = NULL;
- PKIX_List *firstPermittedList = NULL;
- PKIX_List *secondPermittedList = NULL;
- PKIX_List *firstExcludedList = NULL;
- PKIX_List *secondExcludedList = NULL;
- PKIX_UInt32 secondType;
- PKIX_Boolean cmpResult = PKIX_FALSE;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a CertNameConstraints */
- PKIX_CHECK(pkix_CheckType
- (firstObject, PKIX_CERTNAMECONSTRAINTS_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTCERTNAMECONSTRAINTS);
-
- firstNC = (PKIX_PL_CertNameConstraints *)firstObject;
- secondNC = (PKIX_PL_CertNameConstraints *)secondObject;
-
- /*
- * Since we know firstObject is a CertNameConstraints, if both
- * references are identical, they must be equal
- */
- if (firstNC == secondNC){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondNC isn't a CertNameConstraints, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
-
- PKIX_CHECK(PKIX_PL_Object_GetType
- ((PKIX_PL_Object *)secondNC, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- if (secondType != PKIX_CERTNAMECONSTRAINTS_TYPE) {
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
- (firstNC, &firstPermittedList, plContext),
- PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED);
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
- (secondNC, &secondPermittedList, plContext),
- PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED);
-
- PKIX_EQUALS
- (firstPermittedList, secondPermittedList, &cmpResult, plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (cmpResult != PKIX_TRUE) {
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
- (firstNC, &firstExcludedList, plContext),
- PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED);
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
- (secondNC, &secondExcludedList, plContext),
- PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED);
-
- PKIX_EQUALS
- (firstExcludedList, secondExcludedList, &cmpResult, plContext,
- PKIX_OBJECTEQUALSFAILED);
-
- if (cmpResult != PKIX_TRUE) {
- goto cleanup;
- }
-
- /*
- * numNssNameConstraints is not checked because it is basically a
- * merge count, it cannot determine the data equality.
- */
-
- *pResult = PKIX_TRUE;
-
-cleanup:
-
- PKIX_DECREF(firstPermittedList);
- PKIX_DECREF(secondPermittedList);
- PKIX_DECREF(firstExcludedList);
- PKIX_DECREF(secondExcludedList);
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_CERTNAMECONSTRAINTS_TYPE and its related functions with
- * systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_CertNameConstraints_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS,
- "pkix_pl_CertNameConstraints_RegisterSelf");
-
- entry.description = "CertNameConstraints";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_CertNameConstraints);
- entry.destructor = pkix_pl_CertNameConstraints_Destroy;
- entry.equalsFunction = pkix_pl_CertNameConstraints_Equals;
- entry.hashcodeFunction = pkix_pl_CertNameConstraints_Hashcode;
- entry.toStringFunction = pkix_pl_CertNameConstraints_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_CERTNAMECONSTRAINTS_TYPE] = entry;
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_Create_Helper
- *
- * DESCRIPTION:
- * This function retrieves name constraints in "nssNameConstraints",
- * converts and stores the result in a PKIX_PL_CertNameConstraints object.
- *
- * PARAMETERS
- * "nssNameConstraints"
- * Address of CERTNameConstraints that contains this object's data.
- * Must be non-NULL.
- * "pNameConstraints"
- * Address where object pointer will be stored. Must be non-NULL.
- * A NULL value will be returned if there is no Name Constraints extension.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_Create_Helper(
- CERTNameConstraints *nssNameConstraints,
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
- CERTNameConstraints **nssNameConstraintPtr = NULL;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS,
- "pkix_pl_CertNameConstraints_Create_Helper");
- PKIX_NULLCHECK_TWO(nssNameConstraints, pNameConstraints);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_CERTNAMECONSTRAINTS_TYPE,
- sizeof (PKIX_PL_CertNameConstraints),
- (PKIX_PL_Object **)&nameConstraints,
- plContext),
- PKIX_COULDNOTCREATECERTNAMECONSTRAINTSOBJECT);
-
- PKIX_CHECK(PKIX_PL_Malloc
- (sizeof (CERTNameConstraint *),
- (void *)&nssNameConstraintPtr,
- plContext),
- PKIX_MALLOCFAILED);
-
- nameConstraints->numNssNameConstraints = 1;
- nameConstraints->nssNameConstraintsList = nssNameConstraintPtr;
- *nssNameConstraintPtr = nssNameConstraints;
-
- nameConstraints->permittedList = NULL;
- nameConstraints->excludedList = NULL;
- nameConstraints->arena = NULL;
-
- *pNameConstraints = nameConstraints;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(nameConstraints);
- }
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_Create
- *
- * DESCRIPTION:
- * function that allocates and initialize the object CertNameConstraints.
- *
- * PARAMETERS
- * "nssCert"
- * Address of CERT that contains this object's data.
- * Must be non-NULL.
- * "pNameConstraints"
- * Address where object pointer will be stored. Must be non-NULL.
- * A NULL value will be returned if there is no Name Constraints extension.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CertNameConstraints_Create(
- CERTCertificate *nssCert,
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
- CERTNameConstraints *nssNameConstraints = NULL;
- PLArenaPool *arena = NULL;
- SECStatus status;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Create");
- PKIX_NULLCHECK_THREE(nssCert, pNameConstraints, nssCert->arena);
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n");
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_FindNameConstraintsExten\n");
- status = CERT_FindNameConstraintsExten
- (arena, nssCert, &nssNameConstraints);
-
- if (status != SECSuccess) {
- PKIX_ERROR(PKIX_DECODINGCERTNAMECONSTRAINTSFAILED);
- }
-
- if (nssNameConstraints == NULL) {
- *pNameConstraints = NULL;
- if (arena){
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling PORT_FreeArena).\n");
- PORT_FreeArena(arena, PR_FALSE);
- }
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper
- (nssNameConstraints, &nameConstraints, plContext),
- PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED);
-
- nameConstraints->arena = arena;
-
- *pNameConstraints = nameConstraints;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- if (arena){
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling PORT_FreeArena).\n");
- PORT_FreeArena(arena, PR_FALSE);
- }
- }
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_CreateByMerge
- *
- * DESCRIPTION:
- *
- * This function allocates and creates a PKIX_PL_NameConstraint object
- * for merging. It also allocates CERTNameConstraints data space for the
- * merged NSS NameConstraints data.
- *
- * PARAMETERS
- * "pNameConstraints"
- * Address where object pointer will be stored and returned.
- * Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_CreateByMerge(
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
- CERTNameConstraints *nssNameConstraints = NULL;
- PLArenaPool *arena = NULL;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS,
- "pkix_pl_CertNameConstraints_CreateByMerge");
- PKIX_NULLCHECK_ONE(pNameConstraints);
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n");
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n");
- nssNameConstraints = PORT_ArenaZNew(arena, CERTNameConstraints);
- if (nssNameConstraints == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- nssNameConstraints->permited = NULL;
- nssNameConstraints->excluded = NULL;
- nssNameConstraints->DERPermited = NULL;
- nssNameConstraints->DERExcluded = NULL;
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper
- (nssNameConstraints, &nameConstraints, plContext),
- PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED);
-
- nameConstraints->arena = arena;
-
- *pNameConstraints = nameConstraints;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- if (arena){
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling PORT_FreeArena).\n");
- PORT_FreeArena(arena, PR_FALSE);
- }
- }
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_CopyNssNameConstraints
- *
- * DESCRIPTION:
- *
- * This function allocates and copies data to a NSS CERTNameConstraints from
- * the NameConstraints given by "srcNC" and stores the result at "pDestNC". It
- * copies items on both the permitted and excluded lists, but not the
- * DERPermited and DERExcluded.
- *
- * PARAMETERS
- * "arena"
- * Memory pool where object data is allocated from. Must be non-NULL.
- * "srcNC"
- * Address of the NameConstraints to copy from. Must be non-NULL.
- * "pDestNC"
- * Address where new copied object is stored and returned.
- * Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_CertNameConstraints_CopyNssNameConstraints(
- PLArenaPool *arena,
- CERTNameConstraints *srcNC,
- CERTNameConstraints **pDestNC,
- void *plContext)
-{
- CERTNameConstraints *nssNameConstraints = NULL;
- CERTNameConstraint *nssNameConstraintHead = NULL;
- CERTNameConstraint *nssCurrent = NULL;
- CERTNameConstraint *nssCopyTo = NULL;
- CERTNameConstraint *nssCopyFrom = NULL;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS,
- "pkix_pl_CertNameConstraints_CopyNssNameConstraints");
- PKIX_NULLCHECK_THREE(arena, srcNC, pDestNC);
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n");
- nssNameConstraints = PORT_ArenaZNew(arena, CERTNameConstraints);
- if (nssNameConstraints == NULL) {
- PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
- }
-
- if (srcNC->permited) {
-
- nssCopyFrom = srcNC->permited;
-
- do {
-
- nssCopyTo = NULL;
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_CopyNameConstraint).\n");
- nssCopyTo = CERT_CopyNameConstraint
- (arena, nssCopyTo, nssCopyFrom);
- if (nssCopyTo == NULL) {
- PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED);
- }
- if (nssCurrent == NULL) {
- nssCurrent = nssNameConstraintHead = nssCopyTo;
- } else {
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_AddNameConstraint).\n");
- nssCurrent = CERT_AddNameConstraint
- (nssCurrent, nssCopyTo);
- }
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_GetNextNameConstrain).\n");
- nssCopyFrom = CERT_GetNextNameConstraint(nssCopyFrom);
-
- } while (nssCopyFrom != srcNC->permited);
-
- nssNameConstraints->permited = nssNameConstraintHead;
- }
-
- if (srcNC->excluded) {
-
- nssCurrent = NULL;
- nssCopyFrom = srcNC->excluded;
-
- do {
-
- /*
- * Cannot use CERT_DupGeneralNameList, which just increments
- * refcount. We need our own copy since arena is for each
- * PKIX_PL_NameConstraints. Perhaps contribute this code
- * as CERT_CopyGeneralNameList (in the future).
- */
- nssCopyTo = NULL;
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_CopyNameConstraint).\n");
- nssCopyTo = CERT_CopyNameConstraint
- (arena, nssCopyTo, nssCopyFrom);
- if (nssCopyTo == NULL) {
- PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED);
- }
- if (nssCurrent == NULL) {
- nssCurrent = nssNameConstraintHead = nssCopyTo;
- } else {
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_AddNameConstraint).\n");
- nssCurrent = CERT_AddNameConstraint
- (nssCurrent, nssCopyTo);
- }
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_GetNextNameConstrain).\n");
- nssCopyFrom = CERT_GetNextNameConstraint(nssCopyFrom);
-
- } while (nssCopyFrom != srcNC->excluded);
-
- nssNameConstraints->excluded = nssNameConstraintHead;
- }
-
- *pDestNC = nssNameConstraints;
-
-cleanup:
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/*
- * FUNCTION: pkix_pl_CertNameConstraints_Merge
- *
- * DESCRIPTION:
- *
- * This function merges two NameConstraints pointed to by "firstNC" and
- * "secondNC" and stores the result in "pMergedNC".
- *
- * PARAMETERS
- * "firstNC"
- * Address of the first NameConstraints to be merged. Must be non-NULL.
- * "secondNC"
- * Address of the second NameConstraints to be merged. Must be non-NULL.
- * "pMergedNC"
- * Address where the merge result is stored and returned. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a NameConstraints Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_CertNameConstraints_Merge(
- PKIX_PL_CertNameConstraints *firstNC,
- PKIX_PL_CertNameConstraints *secondNC,
- PKIX_PL_CertNameConstraints **pMergedNC,
- void *plContext)
-{
- PKIX_PL_CertNameConstraints *nameConstraints = NULL;
- CERTNameConstraints **nssNCto = NULL;
- CERTNameConstraints **nssNCfrom = NULL;
- CERTNameConstraints *nssNameConstraints = NULL;
- PKIX_UInt32 numNssItems = 0;
- PKIX_UInt32 i;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS, "pkix_pl_CertNameConstraints_Merge");
- PKIX_NULLCHECK_THREE(firstNC, secondNC, pMergedNC);
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_CreateByMerge
- (&nameConstraints, plContext),
- PKIX_CERTNAMECONSTRAINTSCREATEBYMERGEFAILED);
-
- /* Merge NSSCertConstraint lists */
-
- numNssItems = firstNC->numNssNameConstraints +
- secondNC->numNssNameConstraints;
-
- /* Free the default space (only one entry) allocated by create */
- PKIX_CHECK(PKIX_PL_Free
- (nameConstraints->nssNameConstraintsList, plContext),
- PKIX_FREEFAILED);
-
- /* Reallocate the size we need */
- PKIX_CHECK(PKIX_PL_Malloc
- (numNssItems * sizeof (CERTNameConstraint *),
- (void *)&nssNCto,
- plContext),
- PKIX_MALLOCFAILED);
-
- nameConstraints->nssNameConstraintsList = nssNCto;
-
- nssNCfrom = firstNC->nssNameConstraintsList;
-
- for (i = 0; i < firstNC->numNssNameConstraints; i++) {
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints
- (nameConstraints->arena,
- *nssNCfrom,
- &nssNameConstraints,
- plContext),
- PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED);
-
- *nssNCto = nssNameConstraints;
-
- nssNCto++;
- nssNCfrom++;
- }
-
- nssNCfrom = secondNC->nssNameConstraintsList;
-
- for (i = 0; i < secondNC->numNssNameConstraints; i++) {
-
- PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints
- (nameConstraints->arena,
- *nssNCfrom,
- &nssNameConstraints,
- plContext),
- PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED);
-
- *nssNCto = nssNameConstraints;
-
- nssNCto++;
- nssNCfrom++;
- }
-
- nameConstraints->numNssNameConstraints = numNssItems;
- nameConstraints->permittedList = NULL;
- nameConstraints->excludedList = NULL;
-
- *pMergedNC = nameConstraints;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(nameConstraints);
- }
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
-
-/* --Public-NameConstraints-Functions-------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
- * (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_CertNameConstraints_CheckNamesInNameSpace(
- PKIX_List *nameList, /* List of PKIX_PL_GeneralName */
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_Boolean *pCheckPass,
- void *plContext)
-{
- CERTNameConstraints **nssNameConstraintsList = NULL;
- CERTNameConstraints *nssNameConstraints = NULL;
- CERTGeneralName *nssMatchName = NULL;
- PRArenaPool *arena = NULL;
- PKIX_PL_GeneralName *name = NULL;
- PKIX_UInt32 numNameItems = 0;
- PKIX_UInt32 numNCItems = 0;
- PKIX_UInt32 i, j;
- SECStatus status = SECSuccess;
-
- PKIX_ENTER(CERTNAMECONSTRAINTS,
- "PKIX_PL_CertNameConstraints_CheckNamesInNameSpace");
- PKIX_NULLCHECK_TWO(nameConstraints, pCheckPass);
-
- *pCheckPass = PKIX_TRUE;
-
- if (nameList != NULL) {
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena\n");
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- nssNameConstraintsList =
- nameConstraints->nssNameConstraintsList;
- PKIX_NULLCHECK_ONE(nssNameConstraintsList);
- numNCItems = nameConstraints->numNssNameConstraints;
-
- PKIX_CHECK(PKIX_List_GetLength
- (nameList, &numNameItems, plContext),
- PKIX_LISTGETLENGTHFAILED);
-
- for (i = 0; i < numNameItems; i++) {
-
- PKIX_CHECK(PKIX_List_GetItem
- (nameList,
- i,
- (PKIX_PL_Object **) &name,
- plContext),
- PKIX_LISTGETITEMFAILED);
-
- PKIX_CHECK(pkix_pl_GeneralName_GetNssGeneralName
- (name, &nssMatchName, plContext),
- PKIX_GENERALNAMEGETNSSGENERALNAMEFAILED);
-
- PKIX_DECREF(name);
-
- for (j = 0; j < numNCItems; j++) {
-
- nssNameConstraints = *(nssNameConstraintsList + j);
- PKIX_NULLCHECK_ONE(nssNameConstraints);
-
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling CERT_CheckNameSpace\n");
- status = CERT_CheckNameSpace
- (arena, nssNameConstraints, nssMatchName);
- if (status != SECSuccess) {
- break;
- }
-
- }
-
- if (status != SECSuccess) {
- break;
- }
-
- }
- }
-
- if (status == SECFailure) {
- *pCheckPass = PKIX_FALSE;
- }
-
-cleanup:
-
- if (arena){
- PKIX_CERTNAMECONSTRAINTS_DEBUG
- ("\t\tCalling PORT_FreeArena).\n");
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PKIX_RETURN(CERTNAMECONSTRAINTS);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.h
deleted file mode 100644
index 2f305ac10..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_nameconstraints.h
- *
- * Name Constraints Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_NAMECONSTRAINTS_H
-#define _PKIX_PL_NAMECONSTRAINTS_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_CertNameConstraintsStruct {
- PLArenaPool *arena;
- CERTNameConstraints **nssNameConstraintsList;
- PKIX_UInt32 numNssNameConstraints;
- PKIX_List *permittedList; /* list of PKIX_PL_GeneralName */
- PKIX_List *excludedList; /* list of PKIX_PL_GeneralName */
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_CertNameConstraints_RegisterSelf(void *plContext);
-
-PKIX_Error *pkix_pl_CertNameConstraints_Create(
- CERTCertificate *nssCert,
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_CertNameConstraints_CreateWithNames(
- PKIX_List *names, /* List of PKIX_PL_GeneralName */
- PKIX_PL_CertNameConstraints **pNameConstraints,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_CertNameConstraints_CheckNameSpaceNssNames(
- CERTGeneralName *nssSubjectNames,
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_Boolean *pCheckPass,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_CertNameConstraints_CheckNameSpacePkixNames(
- PKIX_List *nameList,
- PKIX_PL_CertNameConstraints *nameConstraints,
- PKIX_Boolean *pCheckPass,
- void *plContext);
-
-
-PKIX_Error *pkix_pl_CertNameConstraints_Merge(
- PKIX_PL_CertNameConstraints *firstNC,
- PKIX_PL_CertNameConstraints *secondNC,
- PKIX_PL_CertNameConstraints **pMergedNC,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_NAMECONSTRAINTS_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c
deleted file mode 100644
index 1f51e773b..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ocspcertid.c
- *
- * Certificate ID Object for OCSP
- *
- */
-
-#include "pkix_pl_ocspcertid.h"
-
-/* --Private-Cert-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_OcspCertID_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OcspCertID_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_OcspCertID *certID = NULL;
-
- PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_Destroy");
-
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPCERTID_TYPE, plContext),
- PKIX_OBJECTNOTOCSPCERTID);
-
- certID = (PKIX_PL_OcspCertID *)object;
-
- if (certID->certID) {
- CERT_DestroyOCSPCertID(certID->certID);
- }
-
-cleanup:
-
- PKIX_RETURN(OCSPCERTID);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspCertID_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_PUBLICKEY_TYPE and its related functions
- * with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_OcspCertID_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_RegisterSelf");
-
- entry.description = "OcspCertID";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_OcspCertID);
- entry.destructor = pkix_pl_OcspCertID_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
- systemClasses[PKIX_OCSPCERTID_TYPE] = entry;
-
- PKIX_RETURN(OCSPCERTID);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_OcspCertID_Create
- * DESCRIPTION:
- *
- * This function creates an OcspCertID for a given certificate,
- * to be used with OCSP transactions.
- *
- * If a Date is provided in "validity" it may be used in the search for the
- * issuer of "cert" but has no effect on the request itself.
- *
- * PARAMETERS:
- * "cert"
- * Address of the Cert for which an OcspCertID is to be created. Must be
- * non-NULL.
- * "validity"
- * Address of the Date for which the Cert's validity is to be determined.
- * May be NULL.
- * "object"
- * Address at which the result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OcspCertID Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_OcspCertID_Create(
- PKIX_PL_Cert *cert,
- PKIX_PL_Date *validity,
- PKIX_PL_OcspCertID **object,
- void *plContext)
-{
- PKIX_PL_OcspCertID *cid = NULL;
- int64 time = 0;
-
- PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_Create");
- PKIX_NULLCHECK_TWO(cert, object);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_OCSPCERTID_TYPE,
- sizeof (PKIX_PL_OcspCertID),
- (PKIX_PL_Object **)&cid,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- if (validity != NULL) {
- PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
- PKIX_DATEGETPRTIMEFAILED);
- } else {
- time = PR_Now();
- }
-
- cid->certID = CERT_CreateOCSPCertID(cert->nssCert, time);
- if (!cid->certID) {
- PKIX_ERROR(PKIX_COULDNOTCREATEOBJECT);
- }
-
- *object = cid;
- cid = NULL;
-cleanup:
- PKIX_DECREF(cid);
- PKIX_RETURN(OCSPCERTID);
-}
-
-/*
- * FUNCTION: PKIX_PL_OcspCertID_GetFreshCacheStatus
- * DESCRIPTION:
- *
- * This function may return cached OCSP results for the provided
- * certificate, but only if stored information is still considered to be
- * fresh.
- *
- * PARAMETERS
- * "cid"
- * A certificate ID as used by OCSP
- * "validity"
- * Optional date parameter to request validity for a specifc time.
- * "hasFreshStatus"
- * Output parameter, if the function successed to find fresh cached
- * information, this will be set to true. Must be non-NULL.
- * "statusIsGood"
- * The good/bad result stored in the cache. Must be non-NULL.
- * "missingResponseError"
- * If OCSP status is "bad", this variable may indicate the exact
- * reason why the previous OCSP request had failed.
- * "plContext"
- * Platform-specific context pointer.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OcspCertID Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_OcspCertID_GetFreshCacheStatus(
- PKIX_PL_OcspCertID *cid,
- PKIX_PL_Date *validity,
- PKIX_Boolean *hasFreshStatus,
- PKIX_Boolean *statusIsGood,
- SECErrorCodes *missingResponseError,
- void *plContext)
-{
- int64 time = 0;
- SECStatus rv;
- SECStatus rvOcsp;
-
- PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_GetFreshCacheStatus");
- PKIX_NULLCHECK_THREE(cid, hasFreshStatus, statusIsGood);
-
- if (validity != NULL) {
- PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
- PKIX_DATEGETPRTIMEFAILED);
- } else {
- time = PR_Now();
- }
-
- rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
- cid->certID, time, PR_TRUE, /*ignoreGlobalOcspFailureSetting*/
- &rvOcsp, missingResponseError);
-
- *hasFreshStatus = (rv == SECSuccess);
- if (*hasFreshStatus) {
- *statusIsGood = (rvOcsp == SECSuccess);
- }
-cleanup:
- PKIX_RETURN(OCSPCERTID);
-}
-
-/*
- * FUNCTION: PKIX_PL_OcspCertID_RememberOCSPProcessingFailure
- * DESCRIPTION:
- *
- * Information about the current failure associated to the given certID
- * will be remembered in the cache, potentially allowing future calls
- * to prevent repetitive OCSP requests.
- * After this function got called, it may no longer be safe to
- * use the provided cid parameter, because ownership might have been
- * transfered to the cache. This status will be recorded inside the
- * cid object.
- *
- * PARAMETERS
- * "cid"
- * The certificate ID associated to a failed OCSP processing.
- * "plContext"
- * Platform-specific context pointer.
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OcspCertID Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
- PKIX_PL_OcspCertID *cid,
- void *plContext)
-{
- PRBool certIDWasConsumed = PR_FALSE;
-
- PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_RememberOCSPProcessingFailure");
- PKIX_NULLCHECK_TWO(cid, cid->certID);
-
- cert_RememberOCSPProcessingFailure(cid->certID, &certIDWasConsumed);
-
- if (certIDWasConsumed) {
- cid->certID = NULL;
- }
-
- PKIX_RETURN(OCSPCERTID);
-}
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h
deleted file mode 100644
index 772a12b25..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ocspcertid.h
- *
- * Public Key Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_OCSPCERTID_H
-#define _PKIX_PL_OCSPCERTID_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_OcspCertIDStruct {
- CERTOCSPCertID *certID;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_OcspCertID_RegisterSelf(void *plContext);
-
-PKIX_Error *
-PKIX_PL_OcspCertID_Create(
- PKIX_PL_Cert *cert,
- PKIX_PL_Date *validity,
- PKIX_PL_OcspCertID **object,
- void *plContext);
-
-PKIX_Error *
-PKIX_PL_OcspCertID_GetFreshCacheStatus(
- PKIX_PL_OcspCertID *cid,
- PKIX_PL_Date *validity,
- PKIX_Boolean *hasFreshStatus,
- PKIX_Boolean *statusIsGood,
- SECErrorCodes *missingResponseError,
- void *plContext);
-
-PKIX_Error *
-PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
- PKIX_PL_OcspCertID *cid,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_OCSPCERTID_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c
deleted file mode 100644
index c825d2eaf..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ocsprequest.c
- *
- */
-
-#include "pkix_pl_ocsprequest.h"
-
-/* --Private-OcspRequest-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_OcspRequest_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OcspRequest_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_OcspRequest *ocspReq = NULL;
-
- PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPREQUEST_TYPE, plContext),
- PKIX_OBJECTNOTOCSPREQUEST);
-
- ocspReq = (PKIX_PL_OcspRequest *)object;
-
- if (ocspReq->decoded != NULL) {
- CERT_DestroyOCSPRequest(ocspReq->decoded);
- }
-
- if (ocspReq->encoded != NULL) {
- SECITEM_FreeItem(ocspReq->encoded, PR_TRUE);
- }
-
- if (ocspReq->location != NULL) {
- PORT_Free(ocspReq->location);
- }
-
- PKIX_DECREF(ocspReq->cert);
- PKIX_DECREF(ocspReq->validity);
- PKIX_DECREF(ocspReq->signerCert);
-
-cleanup:
-
- PKIX_RETURN(OCSPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspRequest_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OcspRequest_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_UInt32 certHash = 0;
- PKIX_UInt32 dateHash = 0;
- PKIX_UInt32 extensionHash = 0;
- PKIX_UInt32 signerHash = 0;
- PKIX_PL_OcspRequest *ocspRq = NULL;
-
- PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPREQUEST_TYPE, plContext),
- PKIX_OBJECTNOTOCSPREQUEST);
-
- ocspRq = (PKIX_PL_OcspRequest *)object;
-
- *pHashcode = 0;
-
- PKIX_HASHCODE(ocspRq->cert, &certHash, plContext,
- PKIX_CERTHASHCODEFAILED);
-
- PKIX_HASHCODE(ocspRq->validity, &dateHash, plContext,
- PKIX_DATEHASHCODEFAILED);
-
- if (ocspRq->addServiceLocator == PKIX_TRUE) {
- extensionHash = 0xff;
- }
-
- PKIX_HASHCODE(ocspRq->signerCert, &signerHash, plContext,
- PKIX_CERTHASHCODEFAILED);
-
- *pHashcode = (((((extensionHash << 8) || certHash) << 8) ||
- dateHash) << 8) || signerHash;
-
-cleanup:
-
- PKIX_RETURN(OCSPREQUEST);
-
-}
-
-/*
- * FUNCTION: pkix_pl_OcspRequest_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OcspRequest_Equals(
- PKIX_PL_Object *firstObj,
- PKIX_PL_Object *secondObj,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_Boolean match = PKIX_FALSE;
- PKIX_UInt32 secondType = 0;
- PKIX_PL_OcspRequest *firstReq = NULL;
- PKIX_PL_OcspRequest *secondReq = NULL;
-
- PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_Equals");
- PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
-
- /* test that firstObj is a OcspRequest */
- PKIX_CHECK(pkix_CheckType(firstObj, PKIX_OCSPREQUEST_TYPE, plContext),
- PKIX_FIRSTOBJARGUMENTNOTOCSPREQUEST);
-
- /*
- * Since we know firstObj is a OcspRequest, if both references are
- * identical, they must be equal
- */
- if (firstObj == secondObj){
- match = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObj isn't a OcspRequest, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObj, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_OCSPREQUEST_TYPE) {
- goto cleanup;
- }
-
- firstReq = (PKIX_PL_OcspRequest *)firstObj;
- secondReq = (PKIX_PL_OcspRequest *)secondObj;
-
- if (firstReq->addServiceLocator != secondReq->addServiceLocator) {
- goto cleanup;
- }
-
- PKIX_EQUALS(firstReq->cert, secondReq->cert, &match, plContext,
- PKIX_CERTEQUALSFAILED);
-
- if (match == PKIX_FALSE) {
- goto cleanup;
- }
-
- PKIX_EQUALS(firstReq->validity, secondReq->validity, &match, plContext,
- PKIX_DATEEQUALSFAILED);
-
- if (match == PKIX_FALSE) {
- goto cleanup;
- }
-
- PKIX_EQUALS
- (firstReq->signerCert, secondReq->signerCert, &match, plContext,
- PKIX_CERTEQUALSFAILED);
-
-cleanup:
-
- *pResult = match;
-
- PKIX_RETURN(OCSPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspRequest_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_OCSPREQUEST_TYPE and its related functions with
- * systemClasses[]
- * PARAMETERS:
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_OcspRequest_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_RegisterSelf");
-
- entry.description = "OcspRequest";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_OcspRequest);
- entry.destructor = pkix_pl_OcspRequest_Destroy;
- entry.equalsFunction = pkix_pl_OcspRequest_Equals;
- entry.hashcodeFunction = pkix_pl_OcspRequest_Hashcode;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_OCSPREQUEST_TYPE] = entry;
-
- PKIX_RETURN(OCSPREQUEST);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_OcspRequest_Create
- * DESCRIPTION:
- *
- * This function creates an OcspRequest to be used in validating the Cert
- * pointed to by "cert" and storing the result at "pRequest". If a URI
- * is found for an OCSP responder, PKIX_TRUE is stored at "pURIFound". If no
- * URI is found, PKIX_FALSE is stored.
- *
- * If a Date is provided in "validity" it may be used in the search for the
- * issuer of "cert" but has no effect on the request itself. If
- * "addServiceLocator" is TRUE, the AddServiceLocator extension will be
- * included in the Request. If "signerCert" is provided it will be used to sign
- * the Request. (Note: this signed request feature is not currently supported.)
- *
- * PARAMETERS:
- * "cert"
- * Address of the Cert for which an OcspRequest is to be created. Must be
- * non-NULL.
- * "validity"
- * Address of the Date for which the Cert's validity is to be determined.
- * May be NULL.
- * "signerCert"
- * Address of the Cert to be used, if present, in signing the request.
- * May be NULL.
- * "pRequest"
- * Address at which the result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OcspRequest Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_OcspRequest_Create(
- PKIX_PL_Cert *cert,
- PKIX_PL_OcspCertID *cid,
- PKIX_PL_Date *validity,
- PKIX_PL_Cert *signerCert,
- PKIX_UInt32 methodFlags,
- PKIX_Boolean *pURIFound,
- PKIX_PL_OcspRequest **pRequest,
- void *plContext)
-{
- PKIX_PL_OcspRequest *ocspRequest = NULL;
-
- CERTCertDBHandle *handle = NULL;
- SECStatus rv = SECFailure;
- SECItem *encoding = NULL;
- CERTOCSPRequest *certRequest = NULL;
- int64 time = 0;
- PRBool addServiceLocatorExtension = PR_FALSE;
- CERTCertificate *nssCert = NULL;
- CERTCertificate *nssSignerCert = NULL;
- char *location = NULL;
- PRErrorCode locError = 0;
- PKIX_Boolean canUseDefaultSource = PKIX_FALSE;
-
- PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_Create");
- PKIX_NULLCHECK_TWO(cert, pRequest);
-
- /* create a PKIX_PL_OcspRequest object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_OCSPREQUEST_TYPE,
- sizeof (PKIX_PL_OcspRequest),
- (PKIX_PL_Object **)&ocspRequest,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- PKIX_INCREF(cert);
- ocspRequest->cert = cert;
-
- PKIX_INCREF(validity);
- ocspRequest->validity = validity;
-
- PKIX_INCREF(signerCert);
- ocspRequest->signerCert = signerCert;
-
- ocspRequest->decoded = NULL;
- ocspRequest->encoded = NULL;
-
- ocspRequest->location = NULL;
-
- nssCert = cert->nssCert;
-
- /*
- * Does this Cert have an Authority Information Access extension with
- * the URI of an OCSP responder?
- */
- handle = CERT_GetDefaultCertDB();
-
- if (!(methodFlags & PKIX_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE)) {
- canUseDefaultSource = PKIX_TRUE;
- }
- location = ocsp_GetResponderLocation(handle, nssCert,
- canUseDefaultSource,
- &addServiceLocatorExtension);
- if (location == NULL) {
- locError = PORT_GetError();
- if (locError == SEC_ERROR_EXTENSION_NOT_FOUND ||
- locError == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) {
- PORT_SetError(0);
- *pURIFound = PKIX_FALSE;
- goto cleanup;
- }
- PKIX_ERROR(PKIX_ERRORFINDINGORPROCESSINGURI);
- }
-
- ocspRequest->location = location;
- *pURIFound = PKIX_TRUE;
-
- if (signerCert != NULL) {
- nssSignerCert = signerCert->nssCert;
- }
-
- if (validity != NULL) {
- PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
- PKIX_DATEGETPRTIMEFAILED);
- } else {
- time = PR_Now();
- }
-
- certRequest = cert_CreateSingleCertOCSPRequest(
- cid->certID, cert->nssCert, time,
- addServiceLocatorExtension, nssSignerCert);
-
- ocspRequest->decoded = certRequest;
-
- if (certRequest == NULL) {
- PKIX_ERROR(PKIX_UNABLETOCREATECERTOCSPREQUEST);
- }
-
- rv = CERT_AddOCSPAcceptableResponses(
- certRequest, SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
-
- if (rv == SECFailure) {
- PKIX_ERROR(PKIX_UNABLETOADDACCEPTABLERESPONSESTOREQUEST);
- }
-
- encoding = CERT_EncodeOCSPRequest(NULL, certRequest, NULL);
-
- ocspRequest->encoded = encoding;
-
- *pRequest = ocspRequest;
- ocspRequest = NULL;
-
-cleanup:
- PKIX_DECREF(ocspRequest);
-
- PKIX_RETURN(OCSPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspRequest_GetEncoded
- * DESCRIPTION:
- *
- * This function obtains the encoded message from the OcspRequest pointed to
- * by "request", storing the result at "pRequest".
- *
- * PARAMETERS
- * "request"
- * The address of the OcspRequest whose encoded message is to be
- * retrieved. Must be non-NULL.
- * "pRequest"
- * The address at which is stored the address of the encoded message. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_OcspRequest_GetEncoded(
- PKIX_PL_OcspRequest *request,
- SECItem **pRequest,
- void *plContext)
-{
- PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_GetEncoded");
- PKIX_NULLCHECK_TWO(request, pRequest);
-
- *pRequest = request->encoded;
-
- PKIX_RETURN(OCSPREQUEST);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspRequest_GetLocation
- * DESCRIPTION:
- *
- * This function obtains the location from the OcspRequest pointed to
- * by "request", storing the result at "pLocation".
- *
- * PARAMETERS
- * "request"
- * The address of the OcspRequest whose encoded message is to be
- * retrieved. Must be non-NULL.
- * "pLocation"
- * The address at which is stored the address of the location. Must
- * be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_OcspRequest_GetLocation(
- PKIX_PL_OcspRequest *request,
- char **pLocation,
- void *plContext)
-{
- PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_GetLocation");
- PKIX_NULLCHECK_TWO(request, pLocation);
-
- *pLocation = request->location;
-
- PKIX_RETURN(OCSPREQUEST);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h
deleted file mode 100644
index fa79266ee..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ocsprequest.h
- *
- * OcspRequest Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_OCSPREQUEST_H
-#define _PKIX_PL_OCSPREQUEST_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_OcspRequestStruct{
- PKIX_PL_Cert *cert;
- PKIX_PL_Date *validity;
- PKIX_Boolean addServiceLocator;
- PKIX_PL_Cert *signerCert;
- CERTOCSPRequest *decoded;
- SECItem *encoded;
- char *location;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_OcspRequest_Create(
- PKIX_PL_Cert *cert,
- PKIX_PL_OcspCertID *cid,
- PKIX_PL_Date *validity,
- PKIX_PL_Cert *signerCert,
- PKIX_UInt32 methodFlags,
- PKIX_Boolean *pURIFound,
- PKIX_PL_OcspRequest **pRequest,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_OcspRequest_GetEncoded(
- PKIX_PL_OcspRequest *request,
- SECItem **pRequest,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_OcspRequest_GetLocation(
- PKIX_PL_OcspRequest *request,
- char **pLocation,
- void *plContext);
-
-PKIX_Error *pkix_pl_OcspRequest_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_OCSPREQUEST_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
deleted file mode 100644
index 20c30f59b..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
+++ /dev/null
@@ -1,989 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ocspresponse.c
- *
- */
-
-#include "pkix_pl_ocspresponse.h"
-
-/* ----Public functions------------------------------------- */
-/*
- * This is the libpkix replacement for CERT_VerifyOCSPResponseSignature.
- * It is used if it has been set as the verifyFcn member of ocspChecker.
- */
-PKIX_Error *
-PKIX_PL_OcspResponse_UseBuildChain(
- PKIX_PL_Cert *signerCert,
- PKIX_PL_Date *producedAt,
- PKIX_ProcessingParams *procParams,
- void **pNBIOContext,
- void **pState,
- PKIX_BuildResult **pBuildResult,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext)
-{
- PKIX_ProcessingParams *caProcParams = NULL;
- PKIX_PL_Date *date = NULL;
- PKIX_ComCertSelParams *certSelParams = NULL;
- PKIX_CertSelector *certSelector = NULL;
- void *nbioContext = NULL;
- PKIX_Error *buildError = NULL;
-
- PKIX_ENTER(OCSPRESPONSE, "pkix_OcspResponse_UseBuildChain");
- PKIX_NULLCHECK_THREE(signerCert, producedAt, procParams);
- PKIX_NULLCHECK_THREE(pNBIOContext, pState, pBuildResult);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- /* Are we resuming after a WOULDBLOCK return, or starting anew ? */
- if (nbioContext == NULL) {
- /* Starting anew */
- PKIX_CHECK(PKIX_PL_Object_Duplicate
- ((PKIX_PL_Object *)procParams,
- (PKIX_PL_Object **)&caProcParams,
- plContext),
- PKIX_OBJECTDUPLICATEFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_SetDate(procParams, date, plContext),
- PKIX_PROCESSINGPARAMSSETDATEFAILED);
-
- /* create CertSelector with target certificate in params */
-
- PKIX_CHECK(PKIX_CertSelector_Create
- (NULL, NULL, &certSelector, plContext),
- PKIX_CERTSELECTORCREATEFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_Create
- (&certSelParams, plContext),
- PKIX_COMCERTSELPARAMSCREATEFAILED);
-
- PKIX_CHECK(PKIX_ComCertSelParams_SetCertificate
- (certSelParams, signerCert, plContext),
- PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED);
-
- PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParams
- (certSelector, certSelParams, plContext),
- PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
-
- PKIX_CHECK(PKIX_ProcessingParams_SetTargetCertConstraints
- (caProcParams, certSelector, plContext),
- PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED);
- }
-
- buildError = PKIX_BuildChain
- (caProcParams,
- &nbioContext,
- pState,
- pBuildResult,
- pVerifyTree,
- plContext);
-
- /* non-null nbioContext means the build would block */
- if (nbioContext != NULL) {
-
- *pNBIOContext = nbioContext;
-
- /* no buildResult means the build has failed */
- } else if (buildError) {
- pkixErrorResult = buildError;
- buildError = NULL;
- } else {
- PKIX_DECREF(*pState);
- }
-
-cleanup:
-
- PKIX_DECREF(caProcParams);
- PKIX_DECREF(date);
- PKIX_DECREF(certSelParams);
- PKIX_DECREF(certSelector);
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-/* --Private-OcspResponse-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_OcspResponse_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OcspResponse_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_OcspResponse *ocspRsp = NULL;
- const SEC_HttpClientFcn *httpClient = NULL;
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
-
- PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPRESPONSE_TYPE, plContext),
- PKIX_OBJECTNOTANOCSPRESPONSE);
-
- ocspRsp = (PKIX_PL_OcspResponse *)object;
-
- if (ocspRsp->nssOCSPResponse != NULL) {
- CERT_DestroyOCSPResponse(ocspRsp->nssOCSPResponse);
- ocspRsp->nssOCSPResponse = NULL;
- }
-
- if (ocspRsp->signerCert != NULL) {
- CERT_DestroyCertificate(ocspRsp->signerCert);
- ocspRsp->signerCert = NULL;
- }
-
- httpClient = (const SEC_HttpClientFcn *)(ocspRsp->httpClient);
-
- if (httpClient && (httpClient->version == 1)) {
-
- hcv1 = &(httpClient->fcnTable.ftable1);
-
- if (ocspRsp->sessionRequest != NULL) {
- (*hcv1->freeFcn)(ocspRsp->sessionRequest);
- ocspRsp->sessionRequest = NULL;
- }
-
- if (ocspRsp->serverSession != NULL) {
- (*hcv1->freeSessionFcn)(ocspRsp->serverSession);
- ocspRsp->serverSession = NULL;
- }
- }
-
- if (ocspRsp->arena != NULL) {
- PORT_FreeArena(ocspRsp->arena, PR_FALSE);
- ocspRsp->arena = NULL;
- }
-
- PKIX_DECREF(ocspRsp->producedAtDate);
- PKIX_DECREF(ocspRsp->pkixSignerCert);
- PKIX_DECREF(ocspRsp->request);
-
-cleanup:
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspResponse_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OcspResponse_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_OcspResponse *ocspRsp = NULL;
-
- PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPRESPONSE_TYPE, plContext),
- PKIX_OBJECTNOTANOCSPRESPONSE);
-
- ocspRsp = (PKIX_PL_OcspResponse *)object;
-
- if (ocspRsp->encodedResponse->data == NULL) {
- *pHashcode = 0;
- } else {
- PKIX_CHECK(pkix_hash
- (ocspRsp->encodedResponse->data,
- ocspRsp->encodedResponse->len,
- pHashcode,
- plContext),
- PKIX_HASHFAILED);
- }
-
-cleanup:
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspResponse_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OcspResponse_Equals(
- PKIX_PL_Object *firstObj,
- PKIX_PL_Object *secondObj,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType = 0;
- PKIX_UInt32 firstLen = 0;
- PKIX_UInt32 i = 0;
- PKIX_PL_OcspResponse *rsp1 = NULL;
- PKIX_PL_OcspResponse *rsp2 = NULL;
- const unsigned char *firstData = NULL;
- const unsigned char *secondData = NULL;
-
- PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Equals");
- PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
-
- /* test that firstObj is a OcspResponse */
- PKIX_CHECK(pkix_CheckType(firstObj, PKIX_OCSPRESPONSE_TYPE, plContext),
- PKIX_FIRSTOBJARGUMENTNOTANOCSPRESPONSE);
-
- /*
- * Since we know firstObj is a OcspResponse, if both references are
- * identical, they must be equal
- */
- if (firstObj == secondObj){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObj isn't a OcspResponse, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType(secondObj, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_OCSPRESPONSE_TYPE) {
- goto cleanup;
- }
-
- rsp1 = (PKIX_PL_OcspResponse *)firstObj;
- rsp2 = (PKIX_PL_OcspResponse *)secondObj;
-
- /* If either lacks an encoded string, they cannot be compared */
- firstData = (const unsigned char *)rsp1->encodedResponse->data;
- secondData = (const unsigned char *)rsp2->encodedResponse->data;
- if ((firstData == NULL) || (secondData == NULL)) {
- goto cleanup;
- }
-
- firstLen = rsp1->encodedResponse->len;
-
- if (firstLen != rsp2->encodedResponse->len) {
- goto cleanup;
- }
-
- for (i = 0; i < firstLen; i++) {
- if (*firstData++ != *secondData++) {
- goto cleanup;
- }
- }
-
- *pResult = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspResponse_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_OCSPRESPONSE_TYPE and its related functions with
- * systemClasses[]
- * PARAMETERS:
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_OcspResponse_RegisterSelf(void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry *entry = &systemClasses[PKIX_OCSPRESPONSE_TYPE];
-
- PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_RegisterSelf");
-
- entry->description = "OcspResponse";
- entry->typeObjectSize = sizeof(PKIX_PL_OcspResponse);
- entry->destructor = pkix_pl_OcspResponse_Destroy;
- entry->equalsFunction = pkix_pl_OcspResponse_Equals;
- entry->hashcodeFunction = pkix_pl_OcspResponse_Hashcode;
- entry->duplicateFunction = pkix_duplicateImmutable;
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_OcspResponse_Create
- * DESCRIPTION:
- *
- * This function transmits the OcspRequest pointed to by "request" and obtains
- * an OcspResponse, which it stores at "pOcspResponse". If the HTTPClient
- * supports non-blocking I/O this function may store a non-NULL value at
- * "pNBIOContext" (the WOULDBLOCK condition). In that case the caller should
- * make a subsequent call with the same value in "pNBIOContext" and
- * "pOcspResponse" to resume the operation. Additional WOULDBLOCK returns may
- * occur; the caller should persist until a return occurs with NULL stored at
- * "pNBIOContext".
- *
- * If a SEC_HttpClientFcn "responder" is supplied, it is used as the client
- * to which the OCSP query is sent. If none is supplied, the default responder
- * is used.
- *
- * If an OcspResponse_VerifyCallback "verifyFcn" is supplied, it is used to
- * verify the Cert received from the responder as the signer. If none is
- * supplied, the default verification function is used.
- *
- * The contents of "request" are ignored on calls subsequent to a WOULDBLOCK
- * return, and the caller is permitted to supply NULL.
- *
- * PARAMETERS
- * "request"
- * Address of the OcspRequest for which a response is desired.
- * "responder"
- * Address, if non-NULL, of the SEC_HttpClientFcn to be sent the OCSP
- * query.
- * "verifyFcn"
- * Address, if non-NULL, of the OcspResponse_VerifyCallback function to be
- * used to verify the Cert of the OCSP responder.
- * "pNBIOContext"
- * Address at which platform-dependent information is stored for handling
- * of non-blocking I/O. Must be non-NULL.
- * "pOcspResponse"
- * The address where the created OcspResponse is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OcspResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_OcspResponse_Create(
- PKIX_PL_OcspRequest *request,
- void *responder,
- PKIX_PL_VerifyCallback verifyFcn,
- void **pNBIOContext,
- PKIX_PL_OcspResponse **pResponse,
- void *plContext)
-{
- void *nbioContext = NULL;
- PKIX_PL_OcspResponse *ocspResponse = NULL;
- const SEC_HttpClientFcn *httpClient = NULL;
- const SEC_HttpClientFcnV1 *hcv1 = NULL;
- SECStatus rv = SECFailure;
- char *location = NULL;
- char *hostname = NULL;
- char *path = NULL;
- char *responseContentType = NULL;
- PRUint16 port = 0;
- SEC_HTTP_SERVER_SESSION serverSession = NULL;
- SEC_HTTP_REQUEST_SESSION sessionRequest = NULL;
- SECItem *encodedRequest = NULL;
- PRUint16 responseCode = 0;
- char *responseData = NULL;
-
- PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Create");
- PKIX_NULLCHECK_TWO(pNBIOContext, pResponse);
-
- nbioContext = *pNBIOContext;
- *pNBIOContext = NULL;
-
- if (nbioContext != NULL) {
-
- ocspResponse = *pResponse;
- PKIX_NULLCHECK_ONE(ocspResponse);
-
- httpClient = ocspResponse->httpClient;
- serverSession = ocspResponse->serverSession;
- sessionRequest = ocspResponse->sessionRequest;
- PKIX_NULLCHECK_THREE(httpClient, serverSession, sessionRequest);
-
- } else {
- PKIX_UInt32 timeout =
- ((PKIX_PL_NssContext*)plContext)->timeoutSeconds;
-
- PKIX_NULLCHECK_ONE(request);
-
- PKIX_CHECK(pkix_pl_OcspRequest_GetEncoded
- (request, &encodedRequest, plContext),
- PKIX_OCSPREQUESTGETENCODEDFAILED);
-
- /* prepare initial message to HTTPClient */
-
- /* Is there a default responder and is it enabled? */
- if (responder) {
- httpClient = (const SEC_HttpClientFcn *)responder;
- } else {
- httpClient = SEC_GetRegisteredHttpClient();
- }
-
- if (httpClient && (httpClient->version == 1)) {
-
- hcv1 = &(httpClient->fcnTable.ftable1);
-
- PKIX_CHECK(pkix_pl_OcspRequest_GetLocation
- (request, &location, plContext),
- PKIX_OCSPREQUESTGETLOCATIONFAILED);
-
- /* parse location -> hostname, port, path */
- rv = CERT_ParseURL(location, &hostname, &port, &path);
- if (rv == SECFailure || hostname == NULL || path == NULL) {
- PKIX_ERROR(PKIX_URLPARSINGFAILED);
- }
-
- rv = (*hcv1->createSessionFcn)(hostname, port,
- &serverSession);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_OCSPSERVERERROR);
- }
-
- rv = (*hcv1->createFcn)(serverSession, "http", path,
- "POST",
- PR_SecondsToInterval(timeout),
- &sessionRequest);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_OCSPSERVERERROR);
- }
-
- rv = (*hcv1->setPostDataFcn)(sessionRequest,
- (char *)encodedRequest->data,
- encodedRequest->len,
- "application/ocsp-request");
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_OCSPSERVERERROR);
- }
-
- /* create a PKIX_PL_OcspResponse object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_OCSPRESPONSE_TYPE,
- sizeof (PKIX_PL_OcspResponse),
- (PKIX_PL_Object **)&ocspResponse,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- PKIX_INCREF(request);
- ocspResponse->request = request;
- ocspResponse->httpClient = httpClient;
- ocspResponse->serverSession = serverSession;
- serverSession = NULL;
- ocspResponse->sessionRequest = sessionRequest;
- sessionRequest = NULL;
- ocspResponse->verifyFcn = verifyFcn;
- ocspResponse->handle = CERT_GetDefaultCertDB();
- ocspResponse->encodedResponse = NULL;
- ocspResponse->arena = NULL;
- ocspResponse->producedAt = 0;
- ocspResponse->producedAtDate = NULL;
- ocspResponse->pkixSignerCert = NULL;
- ocspResponse->nssOCSPResponse = NULL;
- ocspResponse->signerCert = NULL;
- }
- }
-
- /* begin or resume IO to HTTPClient */
- if (httpClient && (httpClient->version == 1)) {
- PRUint32 responseDataLen =
- ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
-
- hcv1 = &(httpClient->fcnTable.ftable1);
-
- rv = (*hcv1->trySendAndReceiveFcn)(ocspResponse->sessionRequest,
- (PRPollDesc **)&nbioContext,
- &responseCode,
- (const char **)&responseContentType,
- NULL, /* responseHeaders */
- (const char **)&responseData,
- &responseDataLen);
-
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_OCSPSERVERERROR);
- }
- /* responseContentType is a pointer to the null-terminated
- * string returned by httpclient. Memory allocated for context
- * type will be freed with freeing of the HttpClient struct. */
- if (PORT_Strcasecmp(responseContentType,
- "application/ocsp-response")) {
- PKIX_ERROR(PKIX_OCSPSERVERERROR);
- }
- if (nbioContext != NULL) {
- *pNBIOContext = nbioContext;
- goto cleanup;
- }
- if (responseCode != 200) {
- PKIX_ERROR(PKIX_OCSPBADHTTPRESPONSE);
- }
- ocspResponse->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (ocspResponse->arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
- ocspResponse->encodedResponse = SECITEM_AllocItem
- (ocspResponse->arena, NULL, responseDataLen);
- if (ocspResponse->encodedResponse == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
- PORT_Memcpy(ocspResponse->encodedResponse->data,
- responseData, responseDataLen);
- }
- *pResponse = ocspResponse;
- ocspResponse = NULL;
-
-cleanup:
-
- if (path != NULL) {
- PORT_Free(path);
- }
- if (hostname != NULL) {
- PORT_Free(hostname);
- }
- if (ocspResponse) {
- PKIX_DECREF(ocspResponse);
- }
- if (serverSession) {
- hcv1->freeSessionFcn(serverSession);
- }
- if (sessionRequest) {
- hcv1->freeFcn(sessionRequest);
- }
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspResponse_Decode
- * DESCRIPTION:
- *
- * This function decodes the DER data contained in the OcspResponse pointed to
- * by "response", storing PKIX_TRUE at "pPassed" if the decoding was
- * successful, and PKIX_FALSE otherwise.
- *
- * PARAMETERS
- * "response"
- * The address of the OcspResponse whose DER data is to be decoded. Must
- * be non-NULL.
- * "pPassed"
- * Address at which the Boolean result is stored. Must be non-NULL.
- * "pReturnCode"
- * Address at which the SECErrorCodes result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OcspResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-
-PKIX_Error *
-pkix_pl_OcspResponse_Decode(
- PKIX_PL_OcspResponse *response,
- PKIX_Boolean *pPassed,
- SECErrorCodes *pReturnCode,
- void *plContext)
-{
-
- PKIX_ENTER(OCSPRESPONSE, "PKIX_PL_OcspResponse_Decode");
- PKIX_NULLCHECK_TWO(response, response->encodedResponse);
-
- response->nssOCSPResponse =
- CERT_DecodeOCSPResponse(response->encodedResponse);
-
- if (response->nssOCSPResponse != NULL) {
- *pPassed = PKIX_TRUE;
- *pReturnCode = 0;
- } else {
- *pPassed = PKIX_FALSE;
- *pReturnCode = PORT_GetError();
- }
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspResponse_GetStatus
- * DESCRIPTION:
- *
- * This function checks the response status of the OcspResponse pointed to
- * by "response", storing PKIX_TRUE at "pPassed" if the responder understood
- * the request and considered it valid, and PKIX_FALSE otherwise.
- *
- * PARAMETERS
- * "response"
- * The address of the OcspResponse whose status is to be retrieved. Must
- * be non-NULL.
- * "pPassed"
- * Address at which the Boolean result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OcspResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-
-PKIX_Error *
-pkix_pl_OcspResponse_GetStatus(
- PKIX_PL_OcspResponse *response,
- PKIX_Boolean *pPassed,
- SECErrorCodes *pReturnCode,
- void *plContext)
-{
- SECStatus rv = SECFailure;
-
- PKIX_ENTER(OCSPRESPONSE, "PKIX_PL_OcspResponse_GetStatus");
- PKIX_NULLCHECK_FOUR(response, response->nssOCSPResponse, pPassed, pReturnCode);
-
- rv = CERT_GetOCSPResponseStatus(response->nssOCSPResponse);
-
- if (rv == SECSuccess) {
- *pPassed = PKIX_TRUE;
- *pReturnCode = 0;
- } else {
- *pPassed = PKIX_FALSE;
- *pReturnCode = PORT_GetError();
- }
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-
-static PKIX_Error*
-pkix_pl_OcspResponse_VerifyResponse(
- PKIX_PL_OcspResponse *response,
- PKIX_ProcessingParams *procParams,
- SECCertUsage certUsage,
- void **state,
- PKIX_BuildResult **buildResult,
- void **pNBIOContext,
- void *plContext)
-{
- SECStatus rv = SECFailure;
-
- PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_VerifyResponse");
-
- if (response->verifyFcn != NULL) {
- void *lplContext = NULL;
-
- PKIX_CHECK(
- PKIX_PL_NssContext_Create(((SECCertificateUsage)1) << certUsage,
- PKIX_FALSE, NULL, &lplContext),
- PKIX_NSSCONTEXTCREATEFAILED);
-
- PKIX_CHECK(
- (response->verifyFcn)((PKIX_PL_Object*)response->pkixSignerCert,
- NULL, response->producedAtDate,
- procParams, pNBIOContext,
- state, buildResult,
- NULL, lplContext),
- PKIX_CERTVERIFYKEYUSAGEFAILED);
- rv = SECSuccess;
- } else {
- rv = CERT_VerifyCert(response->handle, response->signerCert, PKIX_TRUE,
- certUsage, response->producedAt, NULL, NULL);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_CERTVERIFYKEYUSAGEFAILED);
- }
- }
-
-cleanup:
- if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
- }
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspResponse_VerifySignature
- * DESCRIPTION:
- *
- * This function verifies the ocspResponse signature field in the OcspResponse
- * pointed to by "response", storing PKIX_TRUE at "pPassed" if verification
- * is successful and PKIX_FALSE otherwise. If verification is unsuccessful an
- * error code (an enumeration of type SECErrorCodes) is stored at *pReturnCode.
- *
- * PARAMETERS
- * "response"
- * The address of the OcspResponse whose signature field is to be
- * retrieved. Must be non-NULL.
- * "cert"
- * The address of the Cert for which the OCSP query was made. Must be
- * non-NULL.
- * "procParams"
- * Address of ProcessingParams used to initialize the ExpirationChecker
- * and TargetCertChecker. Must be non-NULL.
- * "pPassed"
- * Address at which the Boolean result is stored. Must be non-NULL.
- * "pNBIOContext"
- * Address at which the NBIOContext is stored indicating whether the
- * checking is complete. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OcspResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_OcspResponse_VerifySignature(
- PKIX_PL_OcspResponse *response,
- PKIX_PL_Cert *cert,
- PKIX_ProcessingParams *procParams,
- PKIX_Boolean *pPassed,
- void **pNBIOContext,
- void *plContext)
-{
- SECStatus rv = SECFailure;
- CERTOCSPResponse *nssOCSPResponse = NULL;
- CERTCertificate *issuerCert = NULL;
- PKIX_BuildResult *buildResult = NULL;
- void *nbio = NULL;
- void *state = NULL;
-
- ocspSignature *signature = NULL;
- ocspResponseData *tbsData = NULL;
- SECItem *tbsResponseDataDER = NULL;
-
-
- PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_VerifySignature");
- PKIX_NULLCHECK_FOUR(response, cert, pPassed, pNBIOContext);
-
- nbio = *pNBIOContext;
- *pNBIOContext = NULL;
-
- nssOCSPResponse = response->nssOCSPResponse;
- if (nssOCSPResponse == NULL) {
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- goto cleanup;
- }
-
- tbsData =
- ocsp_GetResponseData(nssOCSPResponse, &tbsResponseDataDER);
-
- signature = ocsp_GetResponseSignature(nssOCSPResponse);
-
-
- /* Are we resuming after a WOULDBLOCK response? */
- if (nbio == NULL) {
- /* No, this is a new query */
-
- issuerCert = CERT_FindCertIssuer(cert->nssCert, PR_Now(),
- certUsageAnyCA);
-
- /*
- * If this signature has already gone through verification,
- * just return the cached result.
- */
- if (signature->wasChecked) {
- if (signature->status == SECSuccess) {
- response->signerCert =
- CERT_DupCertificate(signature->cert);
- } else {
- PORT_SetError(signature->failureReason);
- goto cleanup;
- }
- }
-
- response->signerCert =
- ocsp_GetSignerCertificate(response->handle, tbsData,
- signature, issuerCert);
-
- if (response->signerCert == NULL) {
- PORT_SetError(SEC_ERROR_UNKNOWN_SIGNER);
- goto cleanup;
- }
-
- PKIX_CHECK(
- PKIX_PL_Cert_CreateFromCERTCertificate(response->signerCert,
- &(response->pkixSignerCert),
- plContext),
- PKIX_CERTCREATEWITHNSSCERTFAILED);
-
- /*
- * We could mark this true at the top of this function, or
- * always below at "finish", but if the problem was just that
- * we could not find the signer's cert, leave that as if the
- * signature hasn't been checked. Maybe a subsequent call will
- * have better luck.
- */
- signature->wasChecked = PR_TRUE;
-
- /*
- * We are about to verify the signer certificate; we need to
- * specify *when* that certificate must be valid -- for our
- * purposes we expect it to be valid when the response was
- * signed. The value of "producedAt" is the signing time.
- */
- rv = DER_GeneralizedTimeToTime(&response->producedAt,
- &tbsData->producedAt);
- if (rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
- goto cleanup;
- }
-
- /*
- * We need producedAtDate and pkixSignerCert if we are calling a
- * user-supplied verification function. Let's put their
- * creation before the code that gets repeated when
- * non-blocking I/O is used.
- */
-
- PKIX_CHECK(
- pkix_pl_Date_CreateFromPRTime((PRTime)response->producedAt,
- &(response->producedAtDate),
- plContext),
- PKIX_DATECREATEFROMPRTIMEFAILED);
-
- }
-
- /*
- * Just because we have a cert does not mean it is any good; check
- * it for validity, trust and usage. Use the caller-supplied
- * verification function, if one was supplied.
- */
- if (ocsp_CertIsOCSPDefaultResponder(response->handle,
- response->signerCert)) {
- rv = SECSuccess;
- } else {
- SECCertUsage certUsage;
- if (CERT_IsCACert(response->signerCert, NULL)) {
- certUsage = certUsageAnyCA;
- } else {
- certUsage = certUsageStatusResponder;
- }
- PKIX_CHECK_ONLY_FATAL(
- pkix_pl_OcspResponse_VerifyResponse(response, procParams,
- certUsage, &state,
- &buildResult, &nbio,
- plContext),
- PKIX_CERTVERIFYKEYUSAGEFAILED);
- if (pkixTempErrorReceived) {
- rv = SECFailure;
- goto cleanup;
- }
- if (nbio != NULL) {
- *pNBIOContext = nbio;
- goto cleanup;
- }
- }
-
- rv = ocsp_VerifyResponseSignature(response->signerCert, signature,
- tbsResponseDataDER, NULL);
-
-cleanup:
- if (rv == SECSuccess) {
- *pPassed = PKIX_TRUE;
- } else {
- *pPassed = PKIX_FALSE;
- }
-
- if (signature) {
- if (signature->wasChecked) {
- signature->status = rv;
- }
-
- if (rv != SECSuccess) {
- signature->failureReason = PORT_GetError();
- if (response->signerCert != NULL) {
- CERT_DestroyCertificate(response->signerCert);
- response->signerCert = NULL;
- }
- } else {
- /* Save signer's certificate in signature. */
- signature->cert = CERT_DupCertificate(response->signerCert);
- }
- }
-
- if (issuerCert)
- CERT_DestroyCertificate(issuerCert);
-
- PKIX_RETURN(OCSPRESPONSE);
-}
-
-/*
- * FUNCTION: pkix_pl_OcspResponse_GetStatusForCert
- * DESCRIPTION:
- *
- * This function checks the revocation status of the Cert for which the
- * OcspResponse was obtained, storing PKIX_TRUE at "pPassed" if the Cert has
- * not been revoked and PKIX_FALSE otherwise.
- *
- * PARAMETERS
- * "response"
- * The address of the OcspResponse whose certificate status is to be
- * retrieved. Must be non-NULL.
- * "pPassed"
- * Address at which the Boolean result is stored. Must be non-NULL.
- * "pReturnCode"
- * Address at which the SECErrorCodes result is stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OcspResponse Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_OcspResponse_GetStatusForCert(
- PKIX_PL_OcspCertID *cid,
- PKIX_PL_OcspResponse *response,
- PKIX_PL_Date *validity,
- PKIX_Boolean *pPassed,
- SECErrorCodes *pReturnCode,
- void *plContext)
-{
- PRTime time = 0;
- SECStatus rv = SECFailure;
- SECStatus rvCache;
- PRBool certIDWasConsumed = PR_FALSE;
-
- PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_GetStatusForCert");
- PKIX_NULLCHECK_THREE(response, pPassed, pReturnCode);
-
- /*
- * It is an error to call this function except following a successful
- * return from pkix_pl_OcspResponse_VerifySignature, which would have
- * set response->signerCert.
- */
- PKIX_NULLCHECK_TWO(response->signerCert, response->request);
- PKIX_NULLCHECK_TWO(cid, cid->certID);
-
- if (validity != NULL) {
- PKIX_Error *er = pkix_pl_Date_GetPRTime(validity, &time, plContext);
- PKIX_DECREF(er);
- }
- if (!time) {
- time = PR_Now();
- }
-
- rv = cert_ProcessOCSPResponse(response->handle,
- response->nssOCSPResponse,
- cid->certID,
- response->signerCert,
- time,
- &certIDWasConsumed,
- &rvCache);
- if (certIDWasConsumed) {
- cid->certID = NULL;
- }
-
- if (rv == SECSuccess) {
- *pPassed = PKIX_TRUE;
- *pReturnCode = 0;
- } else {
- *pPassed = PKIX_FALSE;
- *pReturnCode = PORT_GetError();
- }
-
- PKIX_RETURN(OCSPRESPONSE);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h
deleted file mode 100644
index f73f5819c..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_ocspresponse.h
- *
- * OcspResponse Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_OCSPRESPONSE_H
-#define _PKIX_PL_OCSPRESPONSE_H
-
-#include "pkix_pl_common.h"
-#include "pkix_pl_ocspcertid.h"
-#include "hasht.h"
-#include "cryptohi.h"
-#include "ocspti.h"
-#include "ocspi.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAX_OCSP_RESPONSE_LEN (64*1024)
-
-struct PKIX_PL_OcspResponseStruct{
- PRArenaPool *arena;
- const PKIX_PL_OcspRequest *request;
- const SEC_HttpClientFcn *httpClient;
- SEC_HTTP_SERVER_SESSION serverSession;
- SEC_HTTP_REQUEST_SESSION sessionRequest;
- PKIX_PL_VerifyCallback verifyFcn;
- SECItem *encodedResponse;
- CERTCertDBHandle *handle;
- int64 producedAt;
- PKIX_PL_Date *producedAtDate;
- PKIX_PL_Cert *pkixSignerCert;
- CERTOCSPResponse *nssOCSPResponse;
- CERTCertificate *signerCert;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_OcspResponse_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_pl_OcspResponse_Create(
- PKIX_PL_OcspRequest *request,
- void *responder,
- PKIX_PL_VerifyCallback verifyFcn,
- void **pNBIOContext,
- PKIX_PL_OcspResponse **pResponse,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_OcspResponse_Decode(
- PKIX_PL_OcspResponse *response,
- PKIX_Boolean *passed,
- SECErrorCodes *pReturnCode,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_OcspResponse_GetStatus(
- PKIX_PL_OcspResponse *response,
- PKIX_Boolean *passed,
- SECErrorCodes *pReturnCode,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_OcspResponse_VerifySignature(
- PKIX_PL_OcspResponse *response,
- PKIX_PL_Cert *cert,
- PKIX_ProcessingParams *procParams,
- PKIX_Boolean *pPassed,
- void **pNBIOContext,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_OcspResponse_GetStatusForCert(
- PKIX_PL_OcspCertID *cid,
- PKIX_PL_OcspResponse *response,
- PKIX_PL_Date *validity,
- PKIX_Boolean *pPassed,
- SECErrorCodes *pReturnCode,
- void *plContext);
-
-PKIX_Error *
-PKIX_PL_OcspResponse_UseBuildChain(
- PKIX_PL_Cert *signerCert,
- PKIX_PL_Date *producedAt,
- PKIX_ProcessingParams *procParams,
- void **pNBIOContext,
- void **pState,
- PKIX_BuildResult **pBuildResult,
- PKIX_VerifyNode **pVerifyTree,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_OCSPRESPONSE_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c
deleted file mode 100644
index 48d810feb..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_publickey.c
- *
- * Certificate Object Functions
- *
- */
-
-#include "pkix_pl_publickey.h"
-
-/* --Private-Cert-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_PublicKey_ToString_Helper
- * DESCRIPTION:
- *
- * Helper function that creates a string representation of the PublicKey
- * pointed to by "pkixPubKey" and stores it at "pString".
- *
- * PARAMETERS
- * "pkixPubKey"
- * Address of PublicKey whose string representation is desired.
- * Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a PublicKey Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_PublicKey_ToString_Helper(
- PKIX_PL_PublicKey *pkixPubKey,
- PKIX_PL_String **pString,
- void *plContext)
-{
- SECAlgorithmID algorithm;
- SECOidTag pubKeyTag;
- char *asciiOID = NULL;
- PKIX_Boolean freeAsciiOID = PKIX_FALSE;
- SECItem oidBytes;
-
- PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_ToString_Helper");
- PKIX_NULLCHECK_THREE(pkixPubKey, pkixPubKey->nssSPKI, pString);
-
- /*
- * XXX for now, we print out public key algorithm's
- * description - add params and bytes later
- */
-
- /*
- * If the algorithm OID is known to NSS,
- * we print out the ASCII description that is
- * registered with NSS. Otherwise, if unknown,
- * we print out the OID numbers (eg. "1.2.840.3")
- */
-
- algorithm = pkixPubKey->nssSPKI->algorithm;
-
- PKIX_PUBLICKEY_DEBUG("\t\tCalling SECOID_GetAlgorithmTag).\n");
- pubKeyTag = SECOID_GetAlgorithmTag(&algorithm);
- if (pubKeyTag != SEC_OID_UNKNOWN){
- PKIX_PUBLICKEY_DEBUG
- ("\t\tCalling SECOID_FindOIDTagDescription).\n");
- asciiOID = (char *)SECOID_FindOIDTagDescription(pubKeyTag);
- if (!asciiOID){
- PKIX_ERROR(PKIX_SECOIDFINDOIDTAGDESCRIPTIONFAILED);
- }
- } else { /* pubKeyTag == SEC_OID_UNKNOWN */
- oidBytes = algorithm.algorithm;
- PKIX_CHECK(pkix_pl_oidBytes2Ascii
- (&oidBytes, &asciiOID, plContext),
- PKIX_OIDBYTES2ASCIIFAILED);
- freeAsciiOID = PKIX_TRUE;
- }
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, (void *)asciiOID, 0, pString, plContext),
- PKIX_UNABLETOCREATEPSTRING);
-
-cleanup:
-
- /*
- * we only free asciiOID if it was malloc'ed by pkix_pl_oidBytes2Ascii
- */
- if (freeAsciiOID){
- PKIX_FREE(asciiOID);
- }
-
- PKIX_RETURN(PUBLICKEY);
-}
-
-/*
- * FUNCTION: pkix_pl_DestroySPKI
- * DESCRIPTION:
- * Frees all memory associated with the CERTSubjectPublicKeyInfo pointed to
- * by "nssSPKI".
- * PARAMETERS
- * "nssSPKI"
- * Address of CERTSubjectPublicKeyInfo. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_DestroySPKI(
- CERTSubjectPublicKeyInfo *nssSPKI,
- void *plContext)
-{
- PKIX_ENTER(PUBLICKEY, "pkix_pl_DestroySPKI");
-
- PKIX_NULLCHECK_ONE(nssSPKI);
-
- PKIX_PUBLICKEY_DEBUG("\t\tCalling SECOID_DestroyAlgorithmID).\n");
- SECOID_DestroyAlgorithmID(&nssSPKI->algorithm, PKIX_FALSE);
-
- PKIX_PUBLICKEY_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
- SECITEM_FreeItem(&nssSPKI->subjectPublicKey, PKIX_FALSE);
-
- PKIX_RETURN(PUBLICKEY);
-}
-
-/*
- * FUNCTION: pkix_pl_PublicKey_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_PublicKey_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_PublicKey *pubKey = NULL;
-
- PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_Destroy");
-
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_PUBLICKEY_TYPE, plContext),
- PKIX_OBJECTNOTPUBLICKEY);
-
- pubKey = (PKIX_PL_PublicKey *)object;
-
- if (pubKey->nssSPKI) {
-
- PKIX_CHECK(pkix_pl_DestroySPKI(pubKey->nssSPKI, plContext),
- PKIX_DESTROYSPKIFAILED);
-
- PKIX_FREE(pubKey->nssSPKI);
- }
-
-cleanup:
-
- PKIX_RETURN(PUBLICKEY);
-}
-
-/*
- * FUNCTION: pkix_pl_PublicKey_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_PublicKey_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_PublicKey *pkixPubKey = NULL;
- PKIX_PL_String *pubKeyString = NULL;
-
- PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_toString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_PUBLICKEY_TYPE, plContext),
- PKIX_OBJECTNOTPUBLICKEY);
-
- pkixPubKey = (PKIX_PL_PublicKey *)object;
-
- PKIX_CHECK(pkix_pl_PublicKey_ToString_Helper
- (pkixPubKey, &pubKeyString, plContext),
- PKIX_PUBLICKEYTOSTRINGHELPERFAILED);
-
- *pString = pubKeyString;
-
-cleanup:
-
- PKIX_RETURN(PUBLICKEY);
-}
-
-/*
- * FUNCTION: pkix_pl_PublicKey_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_PublicKey_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_PublicKey *pkixPubKey = NULL;
- SECItem algOID;
- SECItem algParams;
- SECItem nssPubKey;
- PKIX_UInt32 algOIDHash;
- PKIX_UInt32 algParamsHash;
- PKIX_UInt32 pubKeyHash;
- PKIX_UInt32 fullHash;
-
- PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_PUBLICKEY_TYPE, plContext),
- PKIX_OBJECTNOTPUBLICKEY);
-
- pkixPubKey = (PKIX_PL_PublicKey *)object;
-
- PKIX_NULLCHECK_ONE(pkixPubKey->nssSPKI);
-
- algOID = pkixPubKey->nssSPKI->algorithm.algorithm;
- algParams = pkixPubKey->nssSPKI->algorithm.parameters;
- nssPubKey = pkixPubKey->nssSPKI->subjectPublicKey;
-
- PKIX_CHECK(pkix_hash
- (algOID.data, algOID.len, &algOIDHash, plContext),
- PKIX_HASHFAILED);
-
- PKIX_CHECK(pkix_hash
- (algParams.data, algParams.len, &algParamsHash, plContext),
- PKIX_HASHFAILED);
-
- PKIX_CHECK(pkix_hash
- (nssPubKey.data, nssPubKey.len, &pubKeyHash, plContext),
- PKIX_HASHFAILED);
-
- fullHash = algOIDHash + algParamsHash + pubKeyHash;
-
- *pHashcode = pubKeyHash;
-
-cleanup:
-
- PKIX_RETURN(PUBLICKEY);
-}
-
-
-/*
- * FUNCTION: pkix_pl_PublicKey_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_PublicKey_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_PublicKey *firstPKIXPubKey = NULL;
- PKIX_PL_PublicKey *secondPKIXPubKey = NULL;
- CERTSubjectPublicKeyInfo *firstSPKI = NULL;
- CERTSubjectPublicKeyInfo *secondSPKI = NULL;
- SECComparison cmpResult;
- PKIX_UInt32 secondType;
-
- PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is a PublicKey */
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_PUBLICKEY_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTPUBLICKEY);
-
- /*
- * Since we know firstObject is a PublicKey, if both references are
- * identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't a PublicKey, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_PUBLICKEY_TYPE) goto cleanup;
-
- firstPKIXPubKey = ((PKIX_PL_PublicKey *)firstObject);
- secondPKIXPubKey = (PKIX_PL_PublicKey *)secondObject;
-
- firstSPKI = firstPKIXPubKey->nssSPKI;
- secondSPKI = secondPKIXPubKey->nssSPKI;
-
- PKIX_NULLCHECK_TWO(firstSPKI, secondSPKI);
-
- PKIX_PL_NSSCALLRV(PUBLICKEY, cmpResult, SECOID_CompareAlgorithmID,
- (&firstSPKI->algorithm, &secondSPKI->algorithm));
-
- if (cmpResult == SECEqual){
- PKIX_PUBLICKEY_DEBUG("\t\tCalling SECITEM_CompareItem).\n");
- cmpResult = SECITEM_CompareItem
- (&firstSPKI->subjectPublicKey,
- &secondSPKI->subjectPublicKey);
- }
-
- *pResult = (cmpResult == SECEqual)?PKIX_TRUE:PKIX_FALSE;
-
-cleanup:
-
- PKIX_RETURN(PUBLICKEY);
-}
-
-/*
- * FUNCTION: pkix_pl_PublicKey_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_PUBLICKEY_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_PublicKey_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_RegisterSelf");
-
- entry.description = "PublicKey";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_PublicKey);
- entry.destructor = pkix_pl_PublicKey_Destroy;
- entry.equalsFunction = pkix_pl_PublicKey_Equals;
- entry.hashcodeFunction = pkix_pl_PublicKey_Hashcode;
- entry.toStringFunction = pkix_pl_PublicKey_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
- systemClasses[PKIX_PUBLICKEY_TYPE] = entry;
-
- PKIX_RETURN(PUBLICKEY);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_PublicKey_NeedsDSAParameters
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_PublicKey_NeedsDSAParameters(
- PKIX_PL_PublicKey *pubKey,
- PKIX_Boolean *pNeedsParams,
- void *plContext)
-{
- CERTSubjectPublicKeyInfo *nssSPKI = NULL;
- KeyType pubKeyType;
- PKIX_Boolean needsParams = PKIX_FALSE;
-
- PKIX_ENTER(PUBLICKEY, "PKIX_PL_PublicKey_NeedsDSAParameters");
- PKIX_NULLCHECK_TWO(pubKey, pNeedsParams);
-
- nssSPKI = pubKey->nssSPKI;
-
- PKIX_PUBLICKEY_DEBUG("\t\tCalling CERT_GetCertKeyType).\n");
- pubKeyType = CERT_GetCertKeyType(nssSPKI);
- if (!pubKeyType){
- PKIX_ERROR(PKIX_PUBKEYTYPENULLKEY);
- }
-
- if ((pubKeyType == dsaKey) &&
- (nssSPKI->algorithm.parameters.len == 0)){
- needsParams = PKIX_TRUE;
- }
-
- *pNeedsParams = needsParams;
-
-cleanup:
-
- PKIX_RETURN(PUBLICKEY);
-}
-
-/*
- * FUNCTION: PKIX_PL_PublicKey_MakeInheritedDSAPublicKey
- * (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_PublicKey_MakeInheritedDSAPublicKey(
- PKIX_PL_PublicKey *firstKey,
- PKIX_PL_PublicKey *secondKey,
- PKIX_PL_PublicKey **pResultKey,
- void *plContext)
-{
- CERTSubjectPublicKeyInfo *firstSPKI = NULL;
- CERTSubjectPublicKeyInfo *secondSPKI = NULL;
- CERTSubjectPublicKeyInfo *thirdSPKI = NULL;
- PKIX_PL_PublicKey *resultKey = NULL;
- KeyType firstPubKeyType;
- KeyType secondPubKeyType;
- SECStatus rv;
-
- PKIX_ENTER(PUBLICKEY, "PKIX_PL_PublicKey_MakeInheritedDSAPublicKey");
- PKIX_NULLCHECK_THREE(firstKey, secondKey, pResultKey);
- PKIX_NULLCHECK_TWO(firstKey->nssSPKI, secondKey->nssSPKI);
-
- firstSPKI = firstKey->nssSPKI;
- secondSPKI = secondKey->nssSPKI;
-
- PKIX_PUBLICKEY_DEBUG("\t\tCalling CERT_GetCertKeyType).\n");
- firstPubKeyType = CERT_GetCertKeyType(firstSPKI);
- if (!firstPubKeyType){
- PKIX_ERROR(PKIX_FIRSTPUBKEYTYPENULLKEY);
- }
-
- PKIX_PUBLICKEY_DEBUG("\t\tCalling CERT_GetCertKeyType).\n");
- secondPubKeyType = CERT_GetCertKeyType(secondSPKI);
- if (!secondPubKeyType){
- PKIX_ERROR(PKIX_SECONDPUBKEYTYPENULLKEY);
- }
-
- if ((firstPubKeyType == dsaKey) &&
- (firstSPKI->algorithm.parameters.len == 0)){
- if (secondPubKeyType != dsaKey) {
- PKIX_ERROR(PKIX_SECONDKEYNOTDSAPUBLICKEY);
- } else if (secondSPKI->algorithm.parameters.len == 0) {
- PKIX_ERROR
- (PKIX_SECONDKEYDSAPUBLICKEY);
- } else {
- PKIX_CHECK(PKIX_PL_Calloc
- (1,
- sizeof (CERTSubjectPublicKeyInfo),
- (void **)&thirdSPKI,
- plContext),
- PKIX_CALLOCFAILED);
-
- PKIX_PUBLICKEY_DEBUG
- ("\t\tCalling"
- "SECKEY_CopySubjectPublicKeyInfo).\n");
- rv = SECKEY_CopySubjectPublicKeyInfo
- (NULL, thirdSPKI, firstSPKI);
- if (rv != SECSuccess) {
- PKIX_ERROR
- (PKIX_SECKEYCOPYSUBJECTPUBLICKEYINFOFAILED);
- }
-
- PKIX_PUBLICKEY_DEBUG
- ("\t\tCalling SECITEM_CopyItem).\n");
- rv = SECITEM_CopyItem(NULL,
- &thirdSPKI->algorithm.parameters,
- &secondSPKI->algorithm.parameters);
-
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- /* create a PKIX_PL_PublicKey object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_PUBLICKEY_TYPE,
- sizeof (PKIX_PL_PublicKey),
- (PKIX_PL_Object **)&resultKey,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- /* populate the SPKI field */
- resultKey->nssSPKI = thirdSPKI;
- *pResultKey = resultKey;
- }
- } else {
- *pResultKey = NULL;
- }
-
-cleanup:
-
- if (thirdSPKI && PKIX_ERROR_RECEIVED){
- PKIX_CHECK(pkix_pl_DestroySPKI(thirdSPKI, plContext),
- PKIX_DESTROYSPKIFAILED);
- PKIX_FREE(thirdSPKI);
- }
-
- PKIX_RETURN(PUBLICKEY);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.h
deleted file mode 100644
index 8918859d2..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_publickey.h
- *
- * Public Key Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_PUBLICKEY_H
-#define _PKIX_PL_PUBLICKEY_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_PublicKeyStruct {
- CERTSubjectPublicKeyInfo *nssSPKI;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_PublicKey_RegisterSelf(void *plContext);
-
-PKIX_Error *
-PKIX_PL_PublicKey_NeedsDSAParameters(
- PKIX_PL_PublicKey *pubKey,
- PKIX_Boolean *pNeedsParams,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_PUBLICKEY_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c
deleted file mode 100644
index 05685171b..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_x500name.c
- *
- * X500Name Object Functions
- *
- */
-
-#include "pkix_pl_x500name.h"
-
-/* --Private-X500Name-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_X500Name_ToString_Helper
- * DESCRIPTION:
- *
- * Helper function that creates a string representation of the X500Name
- * pointed to by "name" and stores it at "pString".
- *
- * PARAMETERS
- * "name"
- * Address of X500Name whose string representation is desired.
- * Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a X500Name Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_X500Name_ToString_Helper(
- PKIX_PL_X500Name *name,
- PKIX_PL_String **pString,
- void *plContext)
-{
- CERTName *nssDN = NULL;
- char *utf8String = NULL;
- PKIX_UInt32 utf8Length;
-
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_ToString_Helper");
- PKIX_NULLCHECK_TWO(name, pString);
- nssDN = &name->nssDN;
-
- /* this should really be called CERT_NameToUTF8 */
- utf8String = CERT_NameToAsciiInvertible(nssDN, CERT_N2A_INVERTIBLE);
- if (!utf8String){
- PKIX_ERROR(PKIX_CERTNAMETOASCIIFAILED);
- }
-
- PKIX_X500NAME_DEBUG("\t\tCalling PL_strlen).\n");
- utf8Length = PL_strlen(utf8String);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_UTF8, utf8String, utf8Length, pString, plContext),
- PKIX_STRINGCREATEFAILED);
-
-cleanup:
-
- PR_Free(utf8String);
-
- PKIX_RETURN(X500NAME);
-}
-
-/*
- * FUNCTION: pkix_pl_X500Name_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_X500Name_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_X500Name *name = NULL;
-
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_X500NAME_TYPE, plContext),
- PKIX_OBJECTNOTANX500NAME);
-
- name = (PKIX_PL_X500Name *)object;
-
- /* PORT_FreeArena will destroy arena, and, allocated on it, CERTName
- * and SECItem */
- if (name->arena) {
- PORT_FreeArena(name->arena, PR_FALSE);
- name->arena = NULL;
- }
-
-cleanup:
-
- PKIX_RETURN(X500NAME);
-}
-
-/*
- * FUNCTION: pkix_pl_X500Name_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_X500Name_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_X500Name *name = NULL;
- char *string = NULL;
- PKIX_UInt32 strLength = 0;
-
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_toString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_X500NAME_TYPE, plContext),
- PKIX_OBJECTNOTANX500NAME);
-
- name = (PKIX_PL_X500Name *)object;
- string = CERT_NameToAscii(&name->nssDN);
- if (!string){
- PKIX_ERROR(PKIX_CERTNAMETOASCIIFAILED);
- }
- strLength = PL_strlen(string);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, string, strLength, pString, plContext),
- PKIX_STRINGCREATEFAILED);
-
-cleanup:
-
- PKIX_RETURN(X500NAME);
-}
-
-/*
- * FUNCTION: pkix_pl_X500Name_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_X500Name_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_X500Name *name = NULL;
- SECItem *derBytes = NULL;
- PKIX_UInt32 nameHash;
-
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_X500NAME_TYPE, plContext),
- PKIX_OBJECTNOTANX500NAME);
-
- name = (PKIX_PL_X500Name *)object;
-
- /* we hash over the bytes in the DER encoding */
-
- derBytes = &name->derName;
-
- PKIX_CHECK(pkix_hash
- (derBytes->data, derBytes->len, &nameHash, plContext),
- PKIX_HASHFAILED);
-
- *pHashcode = nameHash;
-
-cleanup:
-
- PKIX_RETURN(X500NAME);
-}
-
-
-/*
- * FUNCTION: pkix_pl_X500Name_Equals
- * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_X500Name_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
-
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* test that firstObject is an X500Name */
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_X500NAME_TYPE, plContext),
- PKIX_FIRSTOBJECTARGUMENTNOTANX500NAME);
-
- /*
- * Since we know firstObject is an X500Name, if both references are
- * identical, they must be equal
- */
- if (firstObject == secondObject){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- /*
- * If secondObject isn't an X500Name, we don't throw an error.
- * We simply return a Boolean result of FALSE
- */
- *pResult = PKIX_FALSE;
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
- if (secondType != PKIX_X500NAME_TYPE) goto cleanup;
-
- PKIX_CHECK(
- PKIX_PL_X500Name_Match((PKIX_PL_X500Name *)firstObject,
- (PKIX_PL_X500Name *)secondObject,
- pResult, plContext),
- PKIX_X500NAMEMATCHFAILED);
-
-cleanup:
-
- PKIX_RETURN(X500NAME);
-}
-
-/*
- * FUNCTION: pkix_pl_X500Name_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_X500NAME_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_X500Name_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_RegisterSelf");
-
- entry.description = "X500Name";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_X500Name);
- entry.destructor = pkix_pl_X500Name_Destroy;
- entry.equalsFunction = pkix_pl_X500Name_Equals;
- entry.hashcodeFunction = pkix_pl_X500Name_Hashcode;
- entry.toStringFunction = pkix_pl_X500Name_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_X500NAME_TYPE] = entry;
-
- PKIX_RETURN(X500NAME);
-}
-
-#ifdef BUILD_LIBPKIX_TESTS
-/*
- * FUNCTION: pkix_pl_X500Name_CreateFromUtf8
- *
- * DESCRIPTION:
- * Creates an X500Name object from the RFC1485 string representation pointed
- * to by "stringRep", and stores the result at "pName". If the string cannot
- * be successfully converted, a non-fatal error is returned.
- *
- * NOTE: ifdefed BUILD_LIBPKIX_TESTS function: this function is allowed to be
- * called only by pkix tests programs.
- *
- * PARAMETERS:
- * "stringRep"
- * Address of the RFC1485 string to be converted. Must be non-NULL.
- * "pName"
- * Address where the X500Name result will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an X500NAME Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_X500Name_CreateFromUtf8(
- char *stringRep,
- PKIX_PL_X500Name **pName,
- void *plContext)
-{
- PKIX_PL_X500Name *x500Name = NULL;
- PRArenaPool *arena = NULL;
- CERTName *nssDN = NULL;
- SECItem *resultSecItem = NULL;
-
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_CreateFromUtf8");
- PKIX_NULLCHECK_TWO(pName, stringRep);
-
- nssDN = CERT_AsciiToName(stringRep);
- if (nssDN == NULL) {
- PKIX_ERROR(PKIX_COULDNOTCREATENSSDN);
- }
-
- arena = nssDN->arena;
-
- /* create a PKIX_PL_X500Name object */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_X500NAME_TYPE,
- sizeof (PKIX_PL_X500Name),
- (PKIX_PL_Object **)&x500Name,
- plContext),
- PKIX_COULDNOTCREATEX500NAMEOBJECT);
-
- /* populate the nssDN field */
- x500Name->arena = arena;
- x500Name->nssDN.arena = arena;
- x500Name->nssDN.rdns = nssDN->rdns;
-
- resultSecItem =
- SEC_ASN1EncodeItem(arena, &x500Name->derName, nssDN,
- CERT_NameTemplate);
-
- if (resultSecItem == NULL){
- PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED);
- }
-
- *pName = x500Name;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- if (x500Name) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)x500Name,
- plContext);
- } else if (nssDN) {
- CERT_DestroyName(nssDN);
- }
- }
-
- PKIX_RETURN(X500NAME);
-}
-#endif /* BUILD_LIBPKIX_TESTS */
-
-/*
- * FUNCTION: pkix_pl_X500Name_GetCERTName
- *
- * DESCRIPTION:
- *
- * Returns the pointer to CERTName member of X500Name structure.
- *
- * Returned pointed should not be freed.2
- *
- * PARAMETERS:
- * "xname"
- * Address of X500Name whose OrganizationName is to be extracted. Must be
- * non-NULL.
- * "pCERTName"
- * Address where result will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_X500Name_GetCERTName(
- PKIX_PL_X500Name *xname,
- CERTName **pCERTName,
- void *plContext)
-{
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetCERTName");
- PKIX_NULLCHECK_TWO(xname, pCERTName);
-
- *pCERTName = &xname->nssDN;
-
- PKIX_RETURN(X500NAME);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_X500Name_CreateFromCERTName (see comments in pkix_pl_pki.h)
- */
-
-PKIX_Error *
-PKIX_PL_X500Name_CreateFromCERTName(
- SECItem *derName,
- CERTName *name,
- PKIX_PL_X500Name **pName,
- void *plContext)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv = SECFailure;
- PKIX_PL_X500Name *x500Name = NULL;
-
- PKIX_ENTER(X500NAME, "PKIX_PL_X500Name_CreateFromCERTName");
- PKIX_NULLCHECK_ONE(pName);
- if (derName == NULL && name == NULL) {
- PKIX_ERROR(PKIX_NULLARGUMENT);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_X500NAME_TYPE,
- sizeof (PKIX_PL_X500Name),
- (PKIX_PL_Object **)&x500Name,
- plContext),
- PKIX_COULDNOTCREATEX500NAMEOBJECT);
-
- x500Name->arena = arena;
- x500Name->nssDN.arena = NULL;
-
- if (derName != NULL) {
- rv = SECITEM_CopyItem(arena, &x500Name->derName, derName);
- if (rv == SECFailure) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
- }
-
- if (name != NULL) {
- rv = CERT_CopyName(arena, &x500Name->nssDN, name);
- if (rv == SECFailure) {
- PKIX_ERROR(PKIX_CERTCOPYNAMEFAILED);
- }
- } else {
- rv = SEC_QuickDERDecodeItem(arena, &x500Name->nssDN,
- CERT_NameTemplate,
- &x500Name->derName);
- if (rv == SECFailure) {
- PKIX_ERROR(PKIX_SECQUICKDERDECODERFAILED);
- }
- }
-
- *pName = x500Name;
-
-cleanup:
- if (PKIX_ERROR_RECEIVED) {
- if (x500Name) {
- PKIX_PL_Object_DecRef((PKIX_PL_Object*)x500Name,
- plContext);
- } else if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- }
-
- PKIX_RETURN(X500NAME);
-}
-
-#ifdef BUILD_LIBPKIX_TESTS
-/*
- * FUNCTION: PKIX_PL_X500Name_Create (see comments in pkix_pl_pki.h)
- *
- * NOTE: ifdefed BUILD_LIBPKIX_TESTS function: this function is allowed
- * to be called only by pkix tests programs.
- */
-PKIX_Error *
-PKIX_PL_X500Name_Create(
- PKIX_PL_String *stringRep,
- PKIX_PL_X500Name **pName,
- void *plContext)
-{
- char *utf8String = NULL;
- PKIX_UInt32 utf8Length = 0;
-
- PKIX_ENTER(X500NAME, "PKIX_PL_X500Name_Create");
- PKIX_NULLCHECK_TWO(pName, stringRep);
-
- /*
- * convert the input PKIX_PL_String to PKIX_UTF8_NULL_TERM.
- * we need to use this format specifier because
- * CERT_AsciiToName expects a NULL-terminated UTF8 string.
- * Since UTF8 allow NUL characters in the middle of the
- * string, this is buggy. However, as a workaround, using
- * PKIX_UTF8_NULL_TERM gives us a NULL-terminated UTF8 string.
- */
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stringRep,
- PKIX_UTF8_NULL_TERM,
- (void **)&utf8String,
- &utf8Length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_CHECK(
- pkix_pl_X500Name_CreateFromUtf8(utf8String,
- pName, plContext),
- PKIX_X500NAMECREATEFROMUTF8FAILED);
-
-cleanup:
- PKIX_FREE(utf8String);
-
- PKIX_RETURN(X500NAME);
-}
-#endif /* BUILD_LIBPKIX_TESTS */
-
-/*
- * FUNCTION: PKIX_PL_X500Name_Match (see comments in pkix_pl_pki.h)
- */
-PKIX_Error *
-PKIX_PL_X500Name_Match(
- PKIX_PL_X500Name *firstX500Name,
- PKIX_PL_X500Name *secondX500Name,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- SECItem *firstDerName = NULL;
- SECItem *secondDerName = NULL;
- SECComparison cmpResult;
-
- PKIX_ENTER(X500NAME, "PKIX_PL_X500Name_Match");
- PKIX_NULLCHECK_THREE(firstX500Name, secondX500Name, pResult);
-
- if (firstX500Name == secondX500Name){
- *pResult = PKIX_TRUE;
- goto cleanup;
- }
-
- firstDerName = &firstX500Name->derName;
- secondDerName = &secondX500Name->derName;
-
- PKIX_NULLCHECK_TWO(firstDerName->data, secondDerName->data);
-
- cmpResult = SECITEM_CompareItem(firstDerName, secondDerName);
- if (cmpResult != SECEqual) {
- cmpResult = CERT_CompareName(&firstX500Name->nssDN,
- &secondX500Name->nssDN);
- }
-
- *pResult = (cmpResult == SECEqual);
-
-cleanup:
-
- PKIX_RETURN(X500NAME);
-}
-
-/*
- * FUNCTION: pkix_pl_X500Name_GetSECName
- *
- * DESCRIPTION:
- * Returns a copy of CERTName DER representation allocated on passed in arena.
- * If allocation on arena can not be done, NULL is stored at "pSECName".
- *
- * PARAMETERS:
- * "xname"
- * Address of X500Name whose CERTName flag is to be encoded. Must be
- * non-NULL.
- * "arena"
- * Address of the PRArenaPool to be used in the encoding, and in which
- * "pSECName" will be allocated. Must be non-NULL.
- * "pSECName"
- * Address where result will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_X500Name_GetDERName(
- PKIX_PL_X500Name *xname,
- PRArenaPool *arena,
- SECItem **pDERName,
- void *plContext)
-{
- SECItem *derName = NULL;
-
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetDERName");
-
- PKIX_NULLCHECK_THREE(xname, arena, pDERName);
-
- /* Return NULL is X500Name was not created from DER */
- if (xname->derName.data == NULL) {
- *pDERName = NULL;
- goto cleanup;
- }
-
- derName = SECITEM_ArenaDupItem(arena, &xname->derName);
- if (derName == NULL) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- *pDERName = derName;
-cleanup:
-
- PKIX_RETURN(X500NAME);
-}
-
-/*
- * FUNCTION: pkix_pl_X500Name_GetCommonName
- *
- * DESCRIPTION:
- * Extracts the CommonName component of the X500Name object pointed to by
- * "xname", and stores the result at "pCommonName". If the CommonName cannot
- * be successfully extracted, NULL is stored at "pCommonName".
- *
- * The returned string must be freed with PORT_Free.
- *
- * PARAMETERS:
- * "xname"
- * Address of X500Name whose CommonName is to be extracted. Must be
- * non-NULL.
- * "pCommonName"
- * Address where result will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_X500Name_GetCommonName(
- PKIX_PL_X500Name *xname,
- unsigned char **pCommonName,
- void *plContext)
-{
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetCommonName");
- PKIX_NULLCHECK_TWO(xname, pCommonName);
-
- *pCommonName = (unsigned char *)CERT_GetCommonName(&xname->nssDN);
-
- PKIX_RETURN(X500NAME);
-}
-
-/*
- * FUNCTION: pkix_pl_X500Name_GetCountryName
- *
- * DESCRIPTION:
- * Extracts the CountryName component of the X500Name object pointed to by
- * "xname", and stores the result at "pCountryName". If the CountryName cannot
- * be successfully extracted, NULL is stored at "pCountryName".
- *
- * The returned string must be freed with PORT_Free.
- *
- * PARAMETERS:
- * "xname"
- * Address of X500Name whose CountryName is to be extracted. Must be
- * non-NULL.
- * "pCountryName"
- * Address where result will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_X500Name_GetCountryName(
- PKIX_PL_X500Name *xname,
- unsigned char **pCountryName,
- void *plContext)
-{
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetCountryName");
- PKIX_NULLCHECK_TWO(xname, pCountryName);
-
- *pCountryName = (unsigned char*)CERT_GetCountryName(&xname->nssDN);
-
- PKIX_RETURN(X500NAME);
-}
-
-/*
- * FUNCTION: pkix_pl_X500Name_GetOrgName
- *
- * DESCRIPTION:
- * Extracts the OrganizationName component of the X500Name object pointed to by
- * "xname", and stores the result at "pOrgName". If the OrganizationName cannot
- * be successfully extracted, NULL is stored at "pOrgName".
- *
- * The returned string must be freed with PORT_Free.
- *
- * PARAMETERS:
- * "xname"
- * Address of X500Name whose OrganizationName is to be extracted. Must be
- * non-NULL.
- * "pOrgName"
- * Address where result will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- *
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- *
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_X500Name_GetOrgName(
- PKIX_PL_X500Name *xname,
- unsigned char **pOrgName,
- void *plContext)
-{
- PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetOrgName");
- PKIX_NULLCHECK_TWO(xname, pOrgName);
-
- *pOrgName = (unsigned char*)CERT_GetOrgName(&xname->nssDN);
-
- PKIX_RETURN(X500NAME);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.h b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.h
deleted file mode 100644
index 5869c58bc..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_x500name.h
- *
- * X500Name Object Type Definitions
- *
- */
-
-#ifndef _PKIX_PL_X500NAME_H
-#define _PKIX_PL_X500NAME_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-struct PKIX_PL_X500NameStruct{
- PRArenaPool *arena; /* X500Name arena. Shared arena with nssDN
- * and derName */
- CERTName nssDN;
- SECItem derName; /* adding DER encoded CERTName to the structure
- * to avoid unnecessary name encoding when pass
- * der name to cert finder */
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *pkix_pl_X500Name_RegisterSelf(void *plContext);
-
-PKIX_Error *pkix_pl_X500Name_GetDERName(
- PKIX_PL_X500Name *xname,
- PRArenaPool *arena,
- SECItem **pSECName,
- void *plContext);
-
-#ifdef BUILD_LIBPKIX_TESTS
-PKIX_Error * pkix_pl_X500Name_CreateFromUtf8(
- char *stringRep,
- PKIX_PL_X500Name **pName,
- void *plContext);
-#endif /* BUILD_LIBPKIX_TESTS */
-
-PKIX_Error *pkix_pl_X500Name_GetCommonName(
- PKIX_PL_X500Name *xname,
- unsigned char **pCommonName,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_X500Name_GetCountryName(
- PKIX_PL_X500Name *xname,
- unsigned char **pCountryName,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_X500Name_GetOrgName(
- PKIX_PL_X500Name *xname,
- unsigned char **pOrgName,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_X500Name_GetCERTName(
- PKIX_PL_X500Name *xname,
- CERTName **pCERTName,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_X500NAME_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/Makefile b/security/nss/lib/libpkix/pkix_pl_nss/system/Makefile
deleted file mode 100755
index 0fb6c9058..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/config.mk b/security/nss/lib/libpkix/pkix_pl_nss/system/config.mk
deleted file mode 100755
index b8c03de79..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/manifest.mn b/security/nss/lib/libpkix/pkix_pl_nss/system/manifest.mn
deleted file mode 100755
index bae5a4a5f..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/manifest.mn
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../../..
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- pkix_pl_common.h \
- pkix_pl_mem.h \
- pkix_pl_object.h \
- pkix_pl_string.h \
- pkix_pl_primhash.h \
- pkix_pl_bigint.h \
- pkix_pl_mutex.h \
- pkix_pl_bytearray.h \
- pkix_pl_lifecycle.h \
- pkix_pl_oid.h \
- pkix_pl_hashtable.h \
- pkix_pl_rwlock.h \
- pkix_pl_monitorlock.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- pkix_pl_bigint.c \
- pkix_pl_bytearray.c \
- pkix_pl_common.c \
- pkix_pl_error.c \
- pkix_pl_hashtable.c \
- pkix_pl_lifecycle.c \
- pkix_pl_mem.c \
- pkix_pl_monitorlock.c \
- pkix_pl_mutex.c \
- pkix_pl_object.c \
- pkix_pl_oid.c \
- pkix_pl_primhash.c \
- pkix_pl_rwlock.c \
- pkix_pl_string.c \
- $(NULL)
-
-LIBRARY_NAME = pkixsystem
-
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.c
deleted file mode 100755
index cd8e15ee4..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_bigint.c
- *
- * BigInt Object Functions
- *
- */
-
-#include "pkix_pl_bigint.h"
-
-/* --Private-Big-Int-Functions------------------------------------ */
-
-/*
- * FUNCTION: pkix_pl_BigInt_Comparator
- * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_BigInt_Comparator(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PKIX_PL_BigInt *firstBigInt = NULL;
- PKIX_PL_BigInt *secondBigInt = NULL;
- char *firstPtr = NULL;
- char *secondPtr = NULL;
- PKIX_UInt32 firstLen, secondLen;
-
- PKIX_ENTER(BIGINT, "pkix_pl_BigInt_Comparator");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- PKIX_CHECK(pkix_CheckTypes
- (firstObject, secondObject, PKIX_BIGINT_TYPE, plContext),
- PKIX_ARGUMENTSNOTBIGINTS);
-
- /* It's safe to cast */
- firstBigInt = (PKIX_PL_BigInt*)firstObject;
- secondBigInt = (PKIX_PL_BigInt*)secondObject;
-
- *pResult = 0;
- firstPtr = firstBigInt->dataRep;
- secondPtr = secondBigInt->dataRep;
- firstLen = firstBigInt->length;
- secondLen = secondBigInt->length;
-
- if (firstLen < secondLen) {
- *pResult = -1;
- } else if (firstLen > secondLen) {
- *pResult = 1;
- } else if (firstLen == secondLen) {
- PKIX_BIGINT_DEBUG("\t\tCalling PORT_Memcmp).\n");
- *pResult = PORT_Memcmp(firstPtr, secondPtr, firstLen);
- }
-
-cleanup:
-
- PKIX_RETURN(BIGINT);
-}
-
-/*
- * FUNCTION: pkix_pl_BigInt_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_BigInt_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_BigInt *bigInt = NULL;
-
- PKIX_ENTER(BIGINT, "pkix_pl_BigInt_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BIGINT_TYPE, plContext),
- PKIX_OBJECTNOTBIGINT);
-
- bigInt = (PKIX_PL_BigInt*)object;
-
- PKIX_FREE(bigInt->dataRep);
- bigInt->dataRep = NULL;
- bigInt->length = 0;
-
-cleanup:
-
- PKIX_RETURN(BIGINT);
-}
-
-
-/*
- * FUNCTION: pkix_pl_BigInt_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_BigInt_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_BigInt *bigInt = NULL;
- char *outputText = NULL;
- PKIX_UInt32 i, j, lengthChars;
-
- PKIX_ENTER(BIGINT, "pkix_pl_BigInt_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BIGINT_TYPE, plContext),
- PKIX_OBJECTNOTBIGINT);
-
- bigInt = (PKIX_PL_BigInt*)object;
-
- /* number of chars = 2 * (number of bytes) + null terminator */
- lengthChars = (bigInt->length * 2) + 1;
-
- PKIX_CHECK(PKIX_PL_Malloc
- (lengthChars, (void **)&outputText, plContext),
- PKIX_MALLOCFAILED);
-
- for (i = 0, j = 0; i < bigInt->length; i += 1, j += 2){
- outputText[j] = pkix_i2hex
- ((char) ((*(bigInt->dataRep+i) & 0xf0) >> 4));
- outputText[j+1] = pkix_i2hex
- ((char) (*(bigInt->dataRep+i) & 0x0f));
- }
-
- outputText[lengthChars-1] = '\0';
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- outputText,
- 0,
- pString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
-cleanup:
-
- PKIX_FREE(outputText);
-
- PKIX_RETURN(BIGINT);
-}
-
-
-/*
- * FUNCTION: pkix_pl_BigInt_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_BigInt_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_BigInt *bigInt = NULL;
-
- PKIX_ENTER(BIGINT, "pkix_pl_BigInt_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BIGINT_TYPE, plContext),
- PKIX_OBJECTNOTBIGINT);
-
- bigInt = (PKIX_PL_BigInt*)object;
-
- PKIX_CHECK(pkix_hash
- ((void *)bigInt->dataRep,
- bigInt->length,
- pHashcode,
- plContext),
- PKIX_HASHFAILED);
-
-cleanup:
-
- PKIX_RETURN(BIGINT);
-}
-
-/*
- * FUNCTION: pkix_pl_BigInt_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_BigInt_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Int32 cmpResult = 0;
-
- PKIX_ENTER(BIGINT, "pkix_pl_BigInt_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- PKIX_CHECK(pkix_CheckType(first, PKIX_BIGINT_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTBIGINT);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- *pResult = PKIX_FALSE;
-
- if (secondType != PKIX_BIGINT_TYPE) goto cleanup;
-
- PKIX_CHECK(pkix_pl_BigInt_Comparator
- (first, second, &cmpResult, plContext),
- PKIX_BIGINTCOMPARATORFAILED);
-
- *pResult = (cmpResult == 0);
-
-cleanup:
-
- PKIX_RETURN(BIGINT);
-}
-
-/*
- * FUNCTION: pkix_pl_BigInt_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_BIGINT_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_BigInt_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(BIGINT, "pkix_pl_BigInt_RegisterSelf");
-
- entry.description = "BigInt";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_BigInt);
- entry.destructor = pkix_pl_BigInt_Destroy;
- entry.equalsFunction = pkix_pl_BigInt_Equals;
- entry.hashcodeFunction = pkix_pl_BigInt_Hashcode;
- entry.toStringFunction = pkix_pl_BigInt_ToString;
- entry.comparator = pkix_pl_BigInt_Comparator;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_BIGINT_TYPE] = entry;
-
- PKIX_RETURN(BIGINT);
-}
-
-/*
- * FUNCTION: pkix_pl_BigInt_CreateWithBytes
- * DESCRIPTION:
- *
- * Creates a new BigInt of size "length" representing the array of bytes
- * pointed to by "bytes" and stores it at "pBigInt". The caller should make
- * sure that the first byte is not 0x00 (unless it is the the only byte).
- * This function does not do that checking.
- *
- * Once created, a PKIX_PL_BigInt object is immutable.
- *
- * PARAMETERS:
- * "bytes"
- * Address of array of bytes. Must be non-NULL.
- * "length"
- * Length of the array. Must be non-zero.
- * "pBigInt"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext" - Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_BigInt_CreateWithBytes(
- char *bytes,
- PKIX_UInt32 length,
- PKIX_PL_BigInt **pBigInt,
- void *plContext)
-{
- PKIX_PL_BigInt *bigInt = NULL;
-
- PKIX_ENTER(BIGINT, "pkix_pl_BigInt_CreateWithBytes");
- PKIX_NULLCHECK_TWO(pBigInt, bytes);
-
- if (length == 0) {
- PKIX_ERROR(PKIX_BIGINTLENGTH0INVALID)
- }
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_BIGINT_TYPE,
- sizeof (PKIX_PL_BigInt),
- (PKIX_PL_Object **)&bigInt,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- PKIX_CHECK(PKIX_PL_Malloc
- (length, (void **)&(bigInt->dataRep), plContext),
- PKIX_MALLOCFAILED);
-
- PKIX_BIGINT_DEBUG("\t\tCalling PORT_Memcpy).\n");
- (void) PORT_Memcpy(bigInt->dataRep, bytes, length);
-
- bigInt->length = length;
-
- *pBigInt = bigInt;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(bigInt);
- }
-
- PKIX_RETURN(BIGINT);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_BigInt_Create (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_BigInt_Create(
- PKIX_PL_String *stringRep,
- PKIX_PL_BigInt **pBigInt,
- void *plContext)
-{
- PKIX_PL_BigInt *bigInt = NULL;
- char *asciiString = NULL;
- PKIX_UInt32 lengthBytes;
- PKIX_UInt32 lengthString;
- PKIX_UInt32 i;
- char currChar;
-
- PKIX_ENTER(BIGINT, "PKIX_PL_BigInt_Create");
- PKIX_NULLCHECK_TWO(pBigInt, stringRep);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (stringRep,
- PKIX_ESCASCII,
- (void **)&asciiString,
- &lengthString,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- if ((lengthString == 0) || ((lengthString % 2) != 0)){
- PKIX_ERROR(PKIX_SOURCESTRINGHASINVALIDLENGTH);
- }
-
- if (lengthString != 2){
- if ((asciiString[0] == '0') && (asciiString[1] == '0')){
- PKIX_ERROR(PKIX_FIRSTDOUBLEHEXMUSTNOTBE00);
- }
- }
-
- for (i = 0; i < lengthString; i++) {
- currChar = asciiString[i];
- if (!PKIX_ISXDIGIT(currChar)){
- PKIX_ERROR(PKIX_INVALIDCHARACTERINBIGINT);
- }
- }
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_BIGINT_TYPE,
- sizeof (PKIX_PL_BigInt),
- (PKIX_PL_Object **)&bigInt,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
-
- /* number of bytes = 0.5 * (number of chars) */
- lengthBytes = lengthString/2;
-
- PKIX_CHECK(PKIX_PL_Malloc
- (lengthBytes, (void **)&(bigInt->dataRep), plContext),
- PKIX_MALLOCFAILED);
-
- for (i = 0; i < lengthString; i += 2){
- (bigInt->dataRep)[i/2] =
- (pkix_hex2i(asciiString[i])<<4) |
- pkix_hex2i(asciiString[i+1]);
- }
-
- bigInt->length = lengthBytes;
-
- *pBigInt = bigInt;
-
-cleanup:
-
- PKIX_FREE(asciiString);
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(bigInt);
- }
-
- PKIX_RETURN(BIGINT);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.h
deleted file mode 100755
index b3df808a8..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_bigint.h
- *
- * Bigint Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_BIGINT_H
-#define _PKIX_PL_BIGINT_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_BigIntStruct {
- char *dataRep;
- PKIX_UInt32 length;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_BigInt_CreateWithBytes(
- char *bytes,
- PKIX_UInt32 length,
- PKIX_PL_BigInt **pBigInt,
- void *plContext);
-
-PKIX_Error *pkix_pl_BigInt_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_BIGINT_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.c
deleted file mode 100755
index 0a2e9c08f..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.c
+++ /dev/null
@@ -1,504 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_bytearray.c
- *
- * ByteArray Object Functions
- *
- */
-
-#include "pkix_pl_bytearray.h"
-
-/* --Private-ByteArray-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_ByteArray_ToHexString
- * DESCRIPTION:
- *
- * Creates a hex-String representation of the ByteArray pointed to by "array"
- * and stores the result at "pString". The hex-String consists of hex-digit
- * pairs separated by spaces, and the entire string enclosed within square
- * brackets, e.g. [43 61 6E 20 79 6F 75 20 72 65 61 64 20 74 68 69 73 3F].
- * A zero-length ByteArray is represented as [].
- * PARAMETERS
- * "array"
- * ByteArray to be represented by the hex-String; must be non-NULL
- * "pString"
- * Address where String will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Cert Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_ByteArray_ToHexString(
- PKIX_PL_ByteArray *array,
- PKIX_PL_String **pString,
- void *plContext)
-{
- char *tempText = NULL;
- char *stringText = NULL; /* "[XX XX XX ...]" */
- PKIX_UInt32 i, outputLen, bufferSize;
-
- PKIX_ENTER(BYTEARRAY, "pkix_pl_ByteArray_ToHexString");
- PKIX_NULLCHECK_TWO(array, pString);
-
- if ((array->length) == 0) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "[]", 0, pString, plContext),
- PKIX_COULDNOTCREATESTRING);
- } else {
- /*
- * Allocate space for format string
- * '[' + "XX" + (n-1)*" XX" + ']' + '\0'
- */
- bufferSize = 2 + (3*(array->length));
-
- PKIX_CHECK(PKIX_PL_Malloc
- (bufferSize, (void **)&stringText, plContext),
- PKIX_COULDNOTALLOCATEMEMORY);
-
- stringText[0] = 0;
- outputLen = 0;
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PR_smprintf).\n");
- tempText = PR_smprintf
- ("[%02X", (0x0FF&((char *)(array->array))[0]));
- PKIX_BYTEARRAY_DEBUG("\tCalling PL_strlen).\n");
- outputLen += PL_strlen(tempText);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PL_strcat).\n");
- stringText = PL_strcat(stringText, tempText);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PR_smprintf_free).\n");
- PR_smprintf_free(tempText);
-
- for (i = 1; i < array->length; i++) {
- PKIX_BYTEARRAY_DEBUG("\tCalling PR_smprintf).\n");
- tempText = PR_smprintf
- (" %02X", (0x0FF&((char *)(array->array))[i]));
-
- if (tempText == NULL){
- PKIX_ERROR(PKIX_PRSMPRINTFFAILED);
- }
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PL_strlen).\n");
- outputLen += PL_strlen(tempText);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PL_strcat).\n");
- stringText = PL_strcat(stringText, tempText);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PR_smprintf_free).\n");
- PR_smprintf_free(tempText);
- tempText = NULL;
- }
-
- stringText[outputLen++] = ']';
- stringText[outputLen] = 0;
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- stringText,
- 0,
- pString,
- plContext),
- PKIX_COULDNOTCREATESTRING);
- }
-
-cleanup:
-
- PKIX_FREE(stringText);
- PKIX_RETURN(BYTEARRAY);
-}
-
-/*
- * FUNCTION: pkix_pl_ByteArray_Comparator
- * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
- *
- * NOTE:
- * It is not clear that this definition of comparing byte arrays makes
- * sense. It does allow you to tell whether two blocks of memory are
- * identical, so we only use it for the Equals function (i.e. we don't
- * register it as a Compare function for ByteArray).
- */
-static PKIX_Error *
-pkix_pl_ByteArray_Comparator(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PKIX_PL_ByteArray *firstByteArray = NULL;
- PKIX_PL_ByteArray *secondByteArray = NULL;
- unsigned char *firstData = NULL;
- unsigned char *secondData = NULL;
- PKIX_UInt32 i;
-
- PKIX_ENTER(BYTEARRAY, "pkix_pl_ByteArray_Comparator");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- PKIX_CHECK(pkix_CheckTypes
- (firstObject, secondObject, PKIX_BYTEARRAY_TYPE, plContext),
- PKIX_ARGUMENTSNOTBYTEARRAYS);
-
- /* It's safe to cast */
- firstByteArray = (PKIX_PL_ByteArray *)firstObject;
- secondByteArray = (PKIX_PL_ByteArray *)secondObject;
-
- *pResult = 0;
- firstData = (unsigned char *)firstByteArray->array;
- secondData = (unsigned char *)secondByteArray->array;
-
- if (firstByteArray->length < secondByteArray->length) {
- *pResult = -1;
- } else if (firstByteArray->length > secondByteArray->length) {
- *pResult = 1;
- } else if (firstByteArray->length == secondByteArray->length) {
- /* Check if both array contents are identical */
- for (i = 0;
- (i < firstByteArray->length) && (*pResult == 0);
- i++) {
- if (firstData[i] < secondData[i]) {
- *pResult = -1;
- } else if (firstData[i] > secondData[i]) {
- *pResult = 1;
- }
- }
- }
-
-cleanup:
-
- PKIX_RETURN(BYTEARRAY);
-}
-
-/*
- * FUNCTION: pkix_pl_ByteArray_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_ByteArray_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_ByteArray *array = NULL;
- char *tempText = NULL;
- char *stringText = NULL; /* "[OOO, OOO, ... OOO]" */
- PKIX_UInt32 i, outputLen, bufferSize;
-
- PKIX_ENTER(BYTEARRAY, "pkix_pl_ByteArray_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BYTEARRAY_TYPE, plContext),
- PKIX_OBJECTNOTBYTEARRAY);
-
- array = (PKIX_PL_ByteArray *)object;
-
- if ((array->length) == 0) {
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, "[]", 0, pString, plContext),
- PKIX_COULDNOTCREATESTRING);
- } else {
- /* Allocate space for "XXX, ". */
- bufferSize = 2+5*array->length;
-
- /* Allocate space for format string */
- PKIX_CHECK(PKIX_PL_Malloc
- (bufferSize, (void **)&stringText, plContext),
- PKIX_MALLOCFAILED);
-
- stringText[0] = 0;
- outputLen = 0;
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PR_smprintf).\n");
- tempText =
- PR_smprintf
- ("[%03u", (0x0FF&((char *)(array->array))[0]));
- PKIX_BYTEARRAY_DEBUG("\tCalling PL_strlen).\n");
- outputLen += PL_strlen(tempText);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PL_strcat).\n");
- stringText = PL_strcat(stringText, tempText);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PR_smprintf_free).\n");
- PR_smprintf_free(tempText);
-
- for (i = 1; i < array->length; i++) {
- PKIX_BYTEARRAY_DEBUG("\tCalling PR_smprintf).\n");
- tempText = PR_smprintf
- (", %03u",
- (0x0FF&((char *)(array->array))[i]));
-
- if (tempText == NULL){
- PKIX_ERROR(PKIX_PRSMPRINTFFAILED);
- }
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PL_strlen).\n");
- outputLen += PL_strlen(tempText);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PL_strcat).\n");
- stringText = PL_strcat(stringText, tempText);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PR_smprintf_free).\n");
- PR_smprintf_free(tempText);
- tempText = NULL;
- }
-
- stringText[outputLen++] = ']';
- stringText[outputLen] = 0;
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, stringText, 0, pString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- }
-
-cleanup:
-
- PKIX_FREE(stringText);
- PKIX_RETURN(BYTEARRAY);
-}
-
-/*
- * FUNCTION: pkix_pl_ByteArray_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_ByteArray_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Int32 cmpResult = 0;
-
- PKIX_ENTER(BYTEARRAY, "pkix_pl_ByteArray_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- /* Sanity check: Test that "first" is a ByteArray */
- PKIX_CHECK(pkix_CheckType(first, PKIX_BYTEARRAY_TYPE, plContext),
- PKIX_FIRSTARGUMENTNOTBYTEARRAY);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- /* If types differ, then we will return false */
- *pResult = PKIX_FALSE;
-
- /* Second type may not be a BA */
- if (secondType != PKIX_BYTEARRAY_TYPE) goto cleanup;
-
- /* It's safe to cast here */
- PKIX_CHECK(pkix_pl_ByteArray_Comparator
- (first, second, &cmpResult, plContext),
- PKIX_BYTEARRAYCOMPARATORFAILED);
-
- /* ByteArrays are equal iff Comparator Result is 0 */
- *pResult = (cmpResult == 0);
-
-cleanup:
-
- PKIX_RETURN(BYTEARRAY);
-}
-
-/*
- * FUNCTION: pkix_pl_ByteArray_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_ByteArray_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_ByteArray *array = NULL;
-
- PKIX_ENTER(BYTEARRAY, "pkix_pl_ByteArray_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BYTEARRAY_TYPE, plContext),
- PKIX_OBJECTNOTBYTEARRAY);
-
- array = (PKIX_PL_ByteArray*)object;
-
- PKIX_FREE(array->array);
- array->array = NULL;
- array->length = 0;
-
-cleanup:
-
- PKIX_RETURN(BYTEARRAY);
-}
-
-/*
- * FUNCTION: pkix_pl_ByteArray_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_ByteArray_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_ByteArray *array = NULL;
-
- PKIX_ENTER(BYTEARRAY, "pkix_pl_ByteArray_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_BYTEARRAY_TYPE, plContext),
- PKIX_OBJECTNOTBYTEARRAY);
-
- array = (PKIX_PL_ByteArray*)object;
-
- PKIX_CHECK(pkix_hash
- ((const unsigned char *)array->array,
- array->length,
- pHashcode,
- plContext),
- PKIX_HASHFAILED);
-
-cleanup:
-
- PKIX_RETURN(BYTEARRAY);
-}
-
-/*
- * FUNCTION: pkix_pl_ByteArray_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_BYTEARRAY_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_ByteArray_RegisterSelf(void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(BYTEARRAY, "pkix_pl_ByteArray_RegisterSelf");
-
- entry.description = "ByteArray";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_ByteArray);
- entry.destructor = pkix_pl_ByteArray_Destroy;
- entry.equalsFunction = pkix_pl_ByteArray_Equals;
- entry.hashcodeFunction = pkix_pl_ByteArray_Hashcode;
- entry.toStringFunction = pkix_pl_ByteArray_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_BYTEARRAY_TYPE] = entry;
-
- PKIX_RETURN(BYTEARRAY);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_ByteArray_Create (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_ByteArray_Create(
- void *array,
- PKIX_UInt32 length,
- PKIX_PL_ByteArray **pByteArray,
- void *plContext)
-{
- PKIX_PL_ByteArray *byteArray = NULL;
-
- PKIX_ENTER(BYTEARRAY, "PKIX_PL_ByteArray_Create");
- PKIX_NULLCHECK_ONE(pByteArray);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_BYTEARRAY_TYPE,
- sizeof (PKIX_PL_ByteArray),
- (PKIX_PL_Object **)&byteArray,
- plContext),
- PKIX_COULDNOTCREATEOBJECTSTORAGE);
-
- byteArray->length = length;
- byteArray->array = NULL;
-
- if (length != 0){
- /* Alloc space for array */
- PKIX_NULLCHECK_ONE(array);
-
- PKIX_CHECK(PKIX_PL_Malloc
- (length, (void**)&(byteArray->array), plContext),
- PKIX_MALLOCFAILED);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PORT_Memcpy).\n");
- (void) PORT_Memcpy(byteArray->array, array, length);
- }
-
- *pByteArray = byteArray;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(byteArray);
- }
-
- PKIX_RETURN(BYTEARRAY);
-}
-
-/*
- * FUNCTION: PKIX_PL_ByteArray_GetPointer (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_ByteArray_GetPointer(
- PKIX_PL_ByteArray *byteArray,
- void **pArray,
- void *plContext)
-{
- void *bytes = NULL;
- PKIX_ENTER(BYTEARRAY, "PKIX_PL_ByteArray_GetPointer");
- PKIX_NULLCHECK_TWO(byteArray, pArray);
-
- if (byteArray->length != 0){
- PKIX_CHECK(PKIX_PL_Malloc
- (byteArray->length, &bytes, plContext),
- PKIX_MALLOCFAILED);
-
- PKIX_BYTEARRAY_DEBUG("\tCalling PORT_Memcpy).\n");
- (void) PORT_Memcpy
- (bytes, byteArray->array, byteArray->length);
- }
-
- *pArray = bytes;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_FREE(bytes);
- }
-
- PKIX_RETURN(BYTEARRAY);
-}
-
-/*
- * FUNCTION: PKIX_PL_ByteArray_GetLength (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_ByteArray_GetLength(
- PKIX_PL_ByteArray *byteArray,
- PKIX_UInt32 *pLength,
- void *plContext)
-{
- PKIX_ENTER(BYTEARRAY, "PKIX_PL_ByteArray_GetLength");
- PKIX_NULLCHECK_TWO(byteArray, pLength);
-
- *pLength = byteArray->length;
-
- PKIX_RETURN(BYTEARRAY);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.h
deleted file mode 100755
index 4ba18eed7..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_bytearray.h
- *
- * ByteArray Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_BYTEARRAY_H
-#define _PKIX_PL_BYTEARRAY_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_ByteArrayStruct {
- void *array;
- PKIX_UInt32 length;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_ByteArray_ToHexString(
- PKIX_PL_ByteArray *array,
- PKIX_PL_String **pString,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_ByteArray_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_BYTEARRAY_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.c
deleted file mode 100755
index 831ce538d..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.c
+++ /dev/null
@@ -1,1073 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_common.c
- *
- * Common utility functions used by various PKIX_PL functions
- *
- */
-
-#include "pkix_pl_common.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_LockObject
- * DESCRIPTION:
- *
- * Locks the object pointed to by "object".
- *
- * PARAMETERS:
- * "object"
- * Address of object. Must be non-NULL
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_LockObject(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_Object *objectHeader;
-
- PKIX_ENTER(OBJECT, "pkix_LockObject");
- PKIX_NULLCHECK_ONE(object);
-
- if (object == (PKIX_PL_Object *)PKIX_ALLOC_ERROR()) {
- goto cleanup;
- }
-
- PKIX_OBJECT_DEBUG("\tShifting object pointer).\n");
- /* The header is sizeof(PKIX_PL_Object) before the object pointer */
-
- objectHeader = object-1;
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(objectHeader->lock);
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: pkix_UnlockObject
- * DESCRIPTION:
- *
- * Unlocks the object pointed to by "object".
- *
- * PARAMETERS:
- * "object"
- * Address of Object. Must be non-NULL
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_UnlockObject(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_Object *objectHeader;
- PRStatus result;
-
- PKIX_ENTER(OBJECT, "pkix_UnlockObject");
- PKIX_NULLCHECK_ONE(object);
-
- if (object == (PKIX_PL_Object *)PKIX_ALLOC_ERROR()) {
- goto cleanup;
- }
-
- PKIX_OBJECT_DEBUG("\tShifting object pointer).\n");
- /* The header is sizeof(PKIX_PL_Object) before the object pointer */
-
- objectHeader = object-1;
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- result = PR_Unlock(objectHeader->lock);
-
- if (result == PR_FAILURE) {
- PKIX_OBJECT_DEBUG("\tPR_Unlock failed.).\n");
- PKIX_ERROR_FATAL(PKIX_ERRORUNLOCKINGOBJECT);
- }
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: pkix_pl_UInt32_Overflows
- * DESCRIPTION:
- *
- * Returns a PKIX_Boolean indicating whether the unsigned integer
- * represented by "string" is too large to fit in 32-bits (i.e.
- * whether it overflows). With the exception of the string "0",
- * all other strings are stripped of any leading zeros. It is assumed
- * that every character in "string" is from the set {'0' - '9'}.
- *
- * PARAMETERS
- * "string"
- * Address of array of bytes representing PKIX_UInt32 that's being tested
- * for 32-bit overflow
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * PKIX_TRUE if PKIX_UInt32 represented by "string" overflows;
- * PKIX_FALSE otherwise
- */
-PKIX_Boolean
-pkix_pl_UInt32_Overflows(char *string){
- char *firstNonZero = NULL;
- PKIX_UInt32 length, i;
- char *MAX_UINT32_STRING = "4294967295";
-
- PKIX_DEBUG_ENTER(OID);
-
- PKIX_OID_DEBUG("\tCalling PL_strlen).\n");
- length = PL_strlen(string);
-
- if (length < MAX_DIGITS_32){
- return (PKIX_FALSE);
- }
-
- firstNonZero = string;
- for (i = 0; i < length; i++){
- if (*string == '0'){
- firstNonZero++;
- }
- }
-
- PKIX_OID_DEBUG("\tCalling PL_strlen).\n");
- length = PL_strlen(firstNonZero);
-
- if (length > MAX_DIGITS_32){
- return (PKIX_TRUE);
- }
-
- PKIX_OID_DEBUG("\tCalling PL_strlen).\n");
- if (length == MAX_DIGITS_32){
- PKIX_OID_DEBUG("\tCalling PORT_Strcmp).\n");
- if (PORT_Strcmp(firstNonZero, MAX_UINT32_STRING) > 0){
- return (PKIX_TRUE);
- }
- }
-
- return (PKIX_FALSE);
-}
-
-/*
- * FUNCTION: pkix_pl_getOIDToken
- * DESCRIPTION:
- *
- * Takes the array of DER-encoded bytes pointed to by "derBytes"
- * (representing an OID) and the value of "index" representing the index into
- * the array, and decodes the bytes until an integer token is retrieved. If
- * successful, this function stores the integer component at "pToken" and
- * stores the index representing the next byte in the array at "pIndex"
- * (following the last byte that was used in the decoding). This new output
- * index can be used in subsequent calls as an input index, allowing each
- * token of the OID to be retrieved consecutively. Note that there is a
- * special case for the first byte, in that it encodes two separate integer
- * tokens. For example, the byte {2a} represents the integer tokens {1,2}.
- * This special case is not handled here and must be handled by the caller.
- *
- * PARAMETERS
- * "derBytes"
- * Address of array of bytes representing a DER-encoded OID.
- * Must be non-NULL.
- * "index"
- * Index into the array that this function will begin decoding at.
- * "pToken"
- * Destination for decoded OID token. Must be non-NULL.
- * "pIndex"
- * Destination for index of next byte following last byte used.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_getOIDToken(
- char *derBytes,
- PKIX_UInt32 index,
- PKIX_UInt32 *pToken,
- PKIX_UInt32 *pIndex,
- void *plContext)
-{
- PKIX_UInt32 retval, i, tmp;
-
- PKIX_ENTER(OID, "pkix_pl_getOIDToken");
- PKIX_NULLCHECK_THREE(derBytes, pToken, pIndex);
-
- /*
- * We should only need to parse a maximum of four bytes, because
- * RFC 3280 "mandates support for OIDs which have arc elements
- * with values that are less than 2^28, that is, they MUST be between
- * 0 and 268,435,455, inclusive. This allows each arc element to be
- * represented within a single 32 bit word."
- */
-
- for (i = 0, retval = 0; i < 4; i++) {
- retval <<= 7;
- tmp = derBytes[index];
- index++;
- retval |= (tmp & 0x07f);
- if ((tmp & 0x080) == 0){
- *pToken = retval;
- *pIndex = index;
- goto cleanup;
- }
- }
-
- PKIX_ERROR(PKIX_INVALIDENCODINGOIDTOKENVALUETOOBIG);
-
-cleanup:
-
- PKIX_RETURN(OID);
-
-}
-
-/*
- * FUNCTION: pkix_pl_helperBytes2Ascii
- * DESCRIPTION:
- *
- * Converts an array of integers pointed to by "tokens" with a length of
- * "numTokens", to an ASCII string consisting of those integers with dots in
- * between them and stores the result at "pAscii". The ASCII representation is
- * guaranteed to end with a NUL character. This is particularly useful for
- * OID's and IP Addresses.
- *
- * The return value "pAscii" is not reference-counted and will need to
- * be freed with PKIX_PL_Free.
- *
- * PARAMETERS
- * "tokens"
- * Address of array of integers. Must be non-NULL.
- * "numTokens"
- * Length of array of integers. Must be non-zero.
- * "pAscii"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_helperBytes2Ascii(
- PKIX_UInt32 *tokens,
- PKIX_UInt32 numTokens,
- char **pAscii,
- void *plContext)
-{
- char *tempString = NULL;
- char *outputString = NULL;
- char *format = "%d";
- PKIX_UInt32 i = 0;
- PKIX_UInt32 outputLen = 0;
- PKIX_Int32 error;
-
- PKIX_ENTER(OBJECT, "pkix_pl_helperBytes2Ascii");
- PKIX_NULLCHECK_TWO(tokens, pAscii);
-
- if (numTokens == 0) {
- PKIX_ERROR_FATAL(PKIX_HELPERBYTES2ASCIINUMTOKENSZERO);
- }
-
- /*
- * tempString will hold the string representation of a PKIX_UInt32 type
- * The maximum value that can be held by an unsigned 32-bit integer
- * is (2^32 - 1) = 4294967295 (which is ten digits long)
- * Since tempString will hold the string representation of a
- * PKIX_UInt32, we allocate 11 bytes for it (1 byte for '\0')
- */
-
- PKIX_CHECK(PKIX_PL_Malloc
- (MAX_DIGITS_32 + 1, (void **)&tempString, plContext),
- PKIX_MALLOCFAILED);
-
- for (i = 0; i < numTokens; i++){
- PKIX_OBJECT_DEBUG("\tCalling PR_snprintf).\n");
- error = PR_snprintf(tempString,
- MAX_DIGITS_32 + 1,
- format,
- tokens[i]);
- if (error == -1){
- PKIX_ERROR(PKIX_PRSNPRINTFFAILED);
- }
-
- PKIX_OBJECT_DEBUG("\tCalling PL_strlen).\n");
- outputLen += PL_strlen(tempString);
-
- /* Include a dot to separate each number */
- outputLen++;
- }
-
- /* Allocate space for the destination string */
- PKIX_CHECK(PKIX_PL_Malloc
- (outputLen, (void **)&outputString, plContext),
- PKIX_MALLOCFAILED);
-
- *outputString = '\0';
-
- /* Concatenate all strings together */
- for (i = 0; i < numTokens; i++){
-
- PKIX_OBJECT_DEBUG("\tCalling PR_snprintf).\n");
- error = PR_snprintf(tempString,
- MAX_DIGITS_32 + 1,
- format,
- tokens[i]);
- if (error == -1){
- PKIX_ERROR(PKIX_PRSNPRINTFFAILED);
- }
-
- PKIX_OBJECT_DEBUG("\tCalling PL_strcat).\n");
- (void) PL_strcat(outputString, tempString);
-
- /* we don't want to put a "." at the very end */
- if (i < (numTokens - 1)){
- PKIX_OBJECT_DEBUG("\tCalling PL_strcat).\n");
- (void) PL_strcat(outputString, ".");
- }
- }
-
- /* Ensure output string ends with terminating null */
- outputString[outputLen-1] = '\0';
-
- *pAscii = outputString;
- outputString = NULL;
-
-cleanup:
-
- PKIX_FREE(outputString);
- PKIX_FREE(tempString);
-
- PKIX_RETURN(OBJECT);
-
-}
-
-/*
- * FUNCTION: pkix_pl_ipAddrBytes2Ascii
- * DESCRIPTION:
- *
- * Converts the DER encoding of an IPAddress pointed to by "secItem" to an
- * ASCII representation and stores the result at "pAscii". The ASCII
- * representation is guaranteed to end with a NUL character. The input
- * SECItem must contain non-NULL data and must have a positive length.
- *
- * The return value "pAscii" is not reference-counted and will need to
- * be freed with PKIX_PL_Free.
- * XXX this function assumes that IPv4 addresses are being used
- * XXX what about IPv6? can NSS tell the difference
- *
- * PARAMETERS
- * "secItem"
- * Address of SECItem which contains bytes and length of DER encoding.
- * Must be non-NULL.
- * "pAscii"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_ipAddrBytes2Ascii(
- SECItem *secItem,
- char **pAscii,
- void *plContext)
-{
- char *data = NULL;
- PKIX_UInt32 *tokens = NULL;
- PKIX_UInt32 numTokens = 0;
- PKIX_UInt32 i = 0;
- char *asciiString = NULL;
-
- PKIX_ENTER(OBJECT, "pkix_pl_ipAddrBytes2Ascii");
- PKIX_NULLCHECK_THREE(secItem, pAscii, secItem->data);
-
- if (secItem->len == 0) {
- PKIX_ERROR_FATAL(PKIX_IPADDRBYTES2ASCIIDATALENGTHZERO);
- }
-
- data = (char *)(secItem->data);
- numTokens = secItem->len;
-
- /* allocate space for array of integers */
- PKIX_CHECK(PKIX_PL_Malloc
- (numTokens * sizeof (PKIX_UInt32),
- (void **)&tokens,
- plContext),
- PKIX_MALLOCFAILED);
-
- /* populate array of integers */
- for (i = 0; i < numTokens; i++){
- tokens[i] = data[i];
- }
-
- /* convert array of integers to ASCII */
- PKIX_CHECK(pkix_pl_helperBytes2Ascii
- (tokens, numTokens, &asciiString, plContext),
- PKIX_HELPERBYTES2ASCIIFAILED);
-
- *pAscii = asciiString;
-
-cleanup:
-
- PKIX_FREE(tokens);
-
- PKIX_RETURN(OBJECT);
-}
-
-
-/*
- * FUNCTION: pkix_pl_oidBytes2Ascii
- * DESCRIPTION:
- *
- * Converts the DER encoding of an OID pointed to by "secItem" to an ASCII
- * representation and stores it at "pAscii". The ASCII representation is
- * guaranteed to end with a NUL character. The input SECItem must contain
- * non-NULL data and must have a positive length.
- *
- * Example: the six bytes {2a 86 48 86 f7 0d} represent the
- * four integer tokens {1, 2, 840, 113549}, which we will convert
- * into ASCII yielding "1.2.840.113549"
- *
- * The return value "pAscii" is not reference-counted and will need to
- * be freed with PKIX_PL_Free.
- *
- * PARAMETERS
- * "secItem"
- * Address of SECItem which contains bytes and length of DER encoding.
- * Must be non-NULL.
- * "pAscii"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an OID Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_oidBytes2Ascii(
- SECItem *secItem,
- char **pAscii,
- void *plContext)
-{
- char *data = NULL;
- PKIX_UInt32 *tokens = NULL;
- PKIX_UInt32 token = 0;
- PKIX_UInt32 numBytes = 0;
- PKIX_UInt32 numTokens = 0;
- PKIX_UInt32 i = 0, x = 0, y = 0;
- PKIX_UInt32 index = 0;
- char *asciiString = NULL;
-
- PKIX_ENTER(OID, "pkix_pl_oidBytes2Ascii");
- PKIX_NULLCHECK_THREE(secItem, pAscii, secItem->data);
-
- if (secItem->len == 0) {
- PKIX_ERROR_FATAL(PKIX_OIDBYTES2ASCIIDATALENGTHZERO);
- }
-
- data = (char *)(secItem->data);
- numBytes = secItem->len;
- numTokens = 0;
-
- /* calculate how many integer tokens are represented by the bytes. */
- for (i = 0; i < numBytes; i++){
- if ((data[i] & 0x080) == 0){
- numTokens++;
- }
- }
-
- /* if we are unable to retrieve any tokens at all, we throw an error */
- if (numTokens == 0){
- PKIX_ERROR(PKIX_INVALIDDERENCODINGFOROID);
- }
-
- /* add one more token b/c the first byte always contains two tokens */
- numTokens++;
-
- /* allocate space for array of integers */
- PKIX_CHECK(PKIX_PL_Malloc
- (numTokens * sizeof (PKIX_UInt32),
- (void **)&tokens,
- plContext),
- PKIX_MALLOCFAILED);
-
- /* populate array of integers */
- for (i = 0; i < numTokens; i++){
-
- /* retrieve integer token */
- PKIX_CHECK(pkix_pl_getOIDToken
- (data, index, &token, &index, plContext),
- PKIX_GETOIDTOKENFAILED);
-
- if (i == 0){
-
- /*
- * special case: the first DER-encoded byte represents
- * two tokens. We take advantage of fact that first
- * token must be 0, 1, or 2; and second token must be
- * between {0, 39} inclusive if first token is 0 or 1.
- */
-
- if (token < 40)
- x = 0;
- else if (token < 80)
- x = 1;
- else
- x = 2;
- y = token - (x * 40);
-
- tokens[0] = x;
- tokens[1] = y;
- i++;
- } else {
- tokens[i] = token;
- }
- }
-
- /* convert array of integers to ASCII */
- PKIX_CHECK(pkix_pl_helperBytes2Ascii
- (tokens, numTokens, &asciiString, plContext),
- PKIX_HELPERBYTES2ASCIIFAILED);
-
- *pAscii = asciiString;
-
-cleanup:
-
- PKIX_FREE(tokens);
- PKIX_RETURN(OID);
-
-}
-
-/*
- * FUNCTION: pkix_UTF16_to_EscASCII
- * DESCRIPTION:
- *
- * Converts array of bytes pointed to by "utf16String" with length of
- * "utf16Length" (which must be even) into a freshly allocated Escaped ASCII
- * string and stores a pointer to that string at "pDest" and stores the
- * string's length at "pLength". The Escaped ASCII string's length does not
- * include the final NUL character. The caller is responsible for freeing
- * "pDest" using PKIX_PL_Free. If "debug" is set, uses EscASCII_Debug
- * encoding.
- *
- * PARAMETERS:
- * "utf16String"
- * Address of array of bytes representing data source. Must be non-NULL.
- * "utf16Length"
- * Length of data source. Must be even.
- * "debug"
- * Boolean value indicating whether debug mode is desired.
- * "pDest"
- * Address where data will be stored. Must be non-NULL.
- * "pLength"
- * Address where data length will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a String Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_UTF16_to_EscASCII(
- const void *utf16String,
- PKIX_UInt32 utf16Length,
- PKIX_Boolean debug,
- char **pDest,
- PKIX_UInt32 *pLength,
- void *plContext)
-{
- char *destPtr = NULL;
- PKIX_UInt32 i, charLen;
- PKIX_UInt32 x = 0, y = 0, z = 0;
- unsigned char *utf16Char = (unsigned char *)utf16String;
-
- PKIX_ENTER(STRING, "pkix_UTF16_to_EscASCII");
- PKIX_NULLCHECK_THREE(utf16String, pDest, pLength);
-
- /* Assume every pair of bytes becomes &#xNNNN; */
- charLen = 4*utf16Length;
-
- /* utf16Lenght must be even */
- if ((utf16Length % 2) != 0){
- PKIX_ERROR(PKIX_UTF16ALIGNMENTERROR);
- }
-
- /* Count how many bytes we need */
- for (i = 0; i < utf16Length; i += 2) {
- if ((utf16Char[i] == 0x00)&&
- pkix_isPlaintext(utf16Char[i+1], debug)) {
- if (utf16Char[i+1] == '&') {
- /* Need to convert this to &amp; */
- charLen -= 3;
- } else {
- /* We can fit this into one char */
- charLen -= 7;
- }
- } else if ((utf16Char[i] >= 0xD8) && (utf16Char[i] <= 0xDB)) {
- if ((i+3) >= utf16Length) {
- PKIX_ERROR(PKIX_UTF16HIGHZONEALIGNMENTERROR);
- } else if ((utf16Char[i+2] >= 0xDC)&&
- (utf16Char[i+2] <= 0xDF)) {
- /* Quartet of bytes will become &#xNNNNNNNN; */
- charLen -= 4;
- /* Quartet of bytes will produce 12 chars */
- i += 2;
- } else {
- /* Second pair should be DC00-DFFF */
- PKIX_ERROR(PKIX_UTF16LOWZONEERROR);
- }
- }
- }
-
- *pLength = charLen;
-
- /* Ensure this string is null terminated */
- charLen++;
-
- /* Allocate space for character array */
- PKIX_CHECK(PKIX_PL_Malloc(charLen, (void **)pDest, plContext),
- PKIX_MALLOCFAILED);
-
- destPtr = *pDest;
- for (i = 0; i < utf16Length; i += 2) {
- if ((utf16Char[i] == 0x00)&&
- pkix_isPlaintext(utf16Char[i+1], debug)) {
- /* Write a single character */
- *destPtr++ = utf16Char[i+1];
- } else if ((utf16Char[i+1] == '&') && (utf16Char[i] == 0x00)){
- *destPtr++ = '&';
- *destPtr++ = 'a';
- *destPtr++ = 'm';
- *destPtr++ = 'p';
- *destPtr++ = ';';
- } else if ((utf16Char[i] >= 0xD8)&&
- (utf16Char[i] <= 0xDB)&&
- (utf16Char[i+2] >= 0xDC)&&
- (utf16Char[i+2] <= 0xDF)) {
- /*
- * Special UTF pairs are of the form:
- * x = D800..DBFF; y = DC00..DFFF;
- * The result is of the form:
- * ((x - D800) * 400 + (y - DC00)) + 0001 0000
- */
- x = 0x0FFFF & ((utf16Char[i]<<8) | utf16Char[i+1]);
- y = 0x0FFFF & ((utf16Char[i+2]<<8) | utf16Char[i+3]);
- z = ((x - 0xD800) * 0x400 + (y - 0xDC00)) + 0x00010000;
-
- /* Sprintf &#xNNNNNNNN; */
- PKIX_STRING_DEBUG("\tCalling PR_snprintf).\n");
- if (PR_snprintf(destPtr, 13, "&#x%08X;", z) ==
- (PKIX_UInt32)(-1)) {
- PKIX_ERROR(PKIX_PRSNPRINTFFAILED);
- }
- i += 2;
- destPtr += 12;
- } else {
- /* Sprintf &#xNNNN; */
- PKIX_STRING_DEBUG("\tCalling PR_snprintf).\n");
- if (PR_snprintf
- (destPtr,
- 9,
- "&#x%02X%02X;",
- utf16Char[i],
- utf16Char[i+1]) ==
- (PKIX_UInt32)(-1)) {
- PKIX_ERROR(PKIX_PRSNPRINTFFAILED);
- }
- destPtr += 8;
- }
- }
- *destPtr = '\0';
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_FREE(*pDest);
- }
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: pkix_EscASCII_to_UTF16
- * DESCRIPTION:
- *
- * Converts array of bytes pointed to by "escAsciiString" with length of
- * "escAsciiLength" into a freshly allocated UTF-16 string and stores a
- * pointer to that string at "pDest" and stores the string's length at
- * "pLength". The caller is responsible for freeing "pDest" using
- * PKIX_PL_Free. If "debug" is set, uses EscASCII_Debug encoding.
- *
- * PARAMETERS:
- * "escAsciiString"
- * Address of array of bytes representing data source. Must be non-NULL.
- * "escAsciiLength"
- * Length of data source. Must be even.
- * "debug"
- * Boolean value indicating whether debug mode is desired.
- * "pDest"
- * Address where data will be stored. Must be non-NULL.
- * "pLength"
- * Address where data length will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a String Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_EscASCII_to_UTF16(
- const char *escAsciiString,
- PKIX_UInt32 escAsciiLen,
- PKIX_Boolean debug,
- void **pDest,
- PKIX_UInt32 *pLength,
- void *plContext)
-{
- PKIX_UInt32 newLen, i, j, charSize;
- PKIX_UInt32 x = 0, y = 0, z = 0;
- unsigned char *destPtr = NULL;
- unsigned char testChar, testChar2;
- unsigned char *stringData = (unsigned char *)escAsciiString;
-
- PKIX_ENTER(STRING, "pkix_EscASCII_to_UTF16");
- PKIX_NULLCHECK_THREE(escAsciiString, pDest, pLength);
-
- if (escAsciiLen == 0) {
- PKIX_CHECK(PKIX_PL_Malloc(escAsciiLen, pDest, plContext),
- PKIX_MALLOCFAILED);
- goto cleanup;
- }
-
- /* Assume each unicode character takes two bytes */
- newLen = escAsciiLen*2;
-
- /* Count up number of unicode encoded characters */
- for (i = 0; i < escAsciiLen; i++) {
- if (!pkix_isPlaintext(stringData[i], debug)&&
- (stringData[i] != '&')) {
- PKIX_ERROR(PKIX_ILLEGALCHARACTERINESCAPEDASCII);
- } else if (PL_strstr(escAsciiString+i, "&amp;") ==
- escAsciiString+i) {
- /* Convert EscAscii "&amp;" to two bytes */
- newLen -= 8;
- i += 4;
- } else if ((PL_strstr(escAsciiString+i, "&#x") ==
- escAsciiString+i)||
- (PL_strstr(escAsciiString+i, "&#X") ==
- escAsciiString+i)) {
- if (((i+7) <= escAsciiLen)&&
- (escAsciiString[i+7] == ';')) {
- /* Convert &#xNNNN; to two bytes */
- newLen -= 14;
- i += 7;
- } else if (((i+11) <= escAsciiLen)&&
- (escAsciiString[i+11] == ';')) {
- /* Convert &#xNNNNNNNN; to four bytes */
- newLen -= 20;
- i += 11;
- } else {
- PKIX_ERROR(PKIX_ILLEGALUSEOFAMP);
- }
- }
- }
-
- PKIX_CHECK(PKIX_PL_Malloc(newLen, pDest, plContext),
- PKIX_MALLOCFAILED);
-
- /* Copy into newly allocated space */
- destPtr = (unsigned char *)*pDest;
-
- i = 0;
- while (i < escAsciiLen) {
- /* Copy each byte until you hit a &amp; */
- if (pkix_isPlaintext(escAsciiString[i], debug)) {
- *destPtr++ = 0x00;
- *destPtr++ = escAsciiString[i++];
- } else if (PL_strstr(escAsciiString+i, "&amp;") ==
- escAsciiString+i) {
- /* Convert EscAscii "&amp;" to two bytes */
- *destPtr++ = 0x00;
- *destPtr++ = '&';
- i += 5;
- } else if (((PL_strstr(escAsciiString+i, "&#x") ==
- escAsciiString+i)||
- (PL_strstr(escAsciiString+i, "&#X") ==
- escAsciiString+i))&&
- ((i+7) <= escAsciiLen)) {
-
- /* We're either looking at &#xNNNN; or &#xNNNNNNNN; */
- charSize = (escAsciiString[i+7] == ';')?4:8;
-
- /* Skip past the &#x */
- i += 3;
-
- /* Make sure there is a terminating semi-colon */
- if (((i+charSize) > escAsciiLen)||
- (escAsciiString[i+charSize] != ';')) {
- PKIX_ERROR(PKIX_TRUNCATEDUNICODEINESCAPEDASCII);
- }
-
- for (j = 0; j < charSize; j++) {
- if (!PKIX_ISXDIGIT
- (escAsciiString[i+j])) {
- PKIX_ERROR(PKIX_ILLEGALUNICODECHARACTER);
- } else if (charSize == 8) {
- x |= (pkix_hex2i
- (escAsciiString[i+j]))
- <<(4*(7-j));
- }
- }
-
- testChar =
- (pkix_hex2i(escAsciiString[i])<<4)|
- pkix_hex2i(escAsciiString[i+1]);
- testChar2 =
- (pkix_hex2i(escAsciiString[i+2])<<4)|
- pkix_hex2i(escAsciiString[i+3]);
-
- if (charSize == 4) {
- if ((testChar >= 0xD8)&&
- (testChar <= 0xDF)) {
- PKIX_ERROR(PKIX_ILLEGALSURROGATEPAIR);
- } else if ((testChar == 0x00)&&
- pkix_isPlaintext(testChar2, debug)) {
- PKIX_ERROR(
- PKIX_ILLEGALCHARACTERINESCAPEDASCII);
- }
- *destPtr++ = testChar;
- *destPtr++ = testChar2;
- } else if (charSize == 8) {
- /* First two chars must be 0001-0010 */
- if (!((testChar == 0x00)&&
- ((testChar2 >= 0x01)&&
- (testChar2 <= 0x10)))) {
- PKIX_ERROR(
- PKIX_ILLEGALCHARACTERINESCAPEDASCII);
- }
- /*
- * Unicode Strings of the form:
- * x = 0001 0000..0010 FFFF
- * Encoded as pairs of UTF-16 where
- * y = ((x - 0001 0000) / 400) + D800
- * z = ((x - 0001 0000) % 400) + DC00
- */
- x -= 0x00010000;
- y = (x/0x400)+ 0xD800;
- z = (x%0x400)+ 0xDC00;
-
- /* Copy four bytes */
- *destPtr++ = (y&0xFF00)>>8;
- *destPtr++ = (y&0x00FF);
- *destPtr++ = (z&0xFF00)>>8;
- *destPtr++ = (z&0x00FF);
- }
- /* Move past the Hex digits and the semi-colon */
- i += charSize+1;
- } else {
- /* Do not allow any other non-plaintext character */
- PKIX_ERROR(PKIX_ILLEGALCHARACTERINESCAPEDASCII);
- }
- }
-
- *pLength = newLen;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_FREE(*pDest);
- }
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: pkix_UTF16_to_UTF8
- * DESCRIPTION:
- *
- * Converts array of bytes pointed to by "utf16String" with length of
- * "utf16Length" into a freshly allocated UTF-8 string and stores a pointer
- * to that string at "pDest" and stores the string's length at "pLength" (not
- * counting the null terminator, if requested. The caller is responsible for
- * freeing "pDest" using PKIX_PL_Free.
- *
- * PARAMETERS:
- * "utf16String"
- * Address of array of bytes representing data source. Must be non-NULL.
- * "utf16Length"
- * Length of data source. Must be even.
- * "null-term"
- * Boolean value indicating whether output should be null-terminated.
- * "pDest"
- * Address where data will be stored. Must be non-NULL.
- * "pLength"
- * Address where data length will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a String Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_UTF16_to_UTF8(
- const void *utf16String,
- PKIX_UInt32 utf16Length,
- PKIX_Boolean null_term,
- void **pDest,
- PKIX_UInt32 *pLength,
- void *plContext)
-{
- PKIX_Boolean result;
- PKIX_UInt32 reallocLen;
- char *endPtr = NULL;
-
- PKIX_ENTER(STRING, "pkix_UTF16_to_UTF8");
- PKIX_NULLCHECK_THREE(utf16String, pDest, pLength);
-
- /* XXX How big can a UTF8 string be compared to a UTF16? */
- PKIX_CHECK(PKIX_PL_Calloc(1, utf16Length*2, pDest, plContext),
- PKIX_CALLOCFAILED);
-
- PKIX_STRING_DEBUG("\tCalling PORT_UCS2_UTF8Conversion).\n");
- result = PORT_UCS2_UTF8Conversion
- (PKIX_FALSE, /* False = From UCS2 */
- (unsigned char *)utf16String,
- utf16Length,
- (unsigned char *)*pDest,
- utf16Length*2, /* Max Size */
- pLength);
- if (result == PR_FALSE){
- PKIX_ERROR(PKIX_PORTUCS2UTF8CONVERSIONFAILED);
- }
-
- reallocLen = *pLength;
-
- if (null_term){
- reallocLen++;
- }
-
- PKIX_CHECK(PKIX_PL_Realloc(*pDest, reallocLen, pDest, plContext),
- PKIX_REALLOCFAILED);
-
- if (null_term){
- endPtr = (char*)*pDest + reallocLen - 1;
- *endPtr = '\0';
- }
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_FREE(*pDest);
- }
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: pkix_UTF8_to_UTF16
- * DESCRIPTION:
- *
- * Converts array of bytes pointed to by "utf8String" with length of
- * "utf8Length" into a freshly allocated UTF-16 string and stores a pointer
- * to that string at "pDest" and stores the string's length at "pLength". The
- * caller is responsible for freeing "pDest" using PKIX_PL_Free.
- *
- * PARAMETERS:
- * "utf8String"
- * Address of array of bytes representing data source. Must be non-NULL.
- * "utf8Length"
- * Length of data source. Must be even.
- * "pDest"
- * Address where data will be stored. Must be non-NULL.
- * "pLength"
- * Address where data length will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a String Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_UTF8_to_UTF16(
- const void *utf8String,
- PKIX_UInt32 utf8Length,
- void **pDest,
- PKIX_UInt32 *pLength,
- void *plContext)
-{
- PKIX_Boolean result;
-
- PKIX_ENTER(STRING, "pkix_UTF8_to_UTF16");
- PKIX_NULLCHECK_THREE(utf8String, pDest, pLength);
-
- /* XXX How big can a UTF8 string be compared to a UTF16? */
- PKIX_CHECK(PKIX_PL_Calloc(1, utf8Length*2, pDest, plContext),
- PKIX_MALLOCFAILED);
-
- PKIX_STRING_DEBUG("\tCalling PORT_UCS2_UTF8Conversion).\n");
- result = PORT_UCS2_UTF8Conversion
- (PKIX_TRUE, /* True = From UTF8 */
- (unsigned char *)utf8String,
- utf8Length,
- (unsigned char *)*pDest,
- utf8Length*2, /* Max Size */
- pLength);
- if (result == PR_FALSE){
- PKIX_ERROR(PKIX_PORTUCS2UTF8CONVERSIONFAILED);
- }
-
- PKIX_CHECK(PKIX_PL_Realloc(*pDest, *pLength, pDest, plContext),
- PKIX_REALLOCFAILED);
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_FREE(*pDest);
- }
-
- PKIX_RETURN(STRING);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h
deleted file mode 100755
index e1cb0283a..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_common.h
- *
- * Common central header file included by all PL source files
- *
- */
-
-#ifndef _PKIX_PL_COMMON_H
-#define _PKIX_PL_COMMON_H
-
-/* PKIX HEADERS */
-#include "pkix_tools.h"
-
-/* NSS headers */
-#include "nss.h"
-#include "secport.h"
-#include "secasn1.h"
-#include "secerr.h"
-#include "base64.h"
-#include "cert.h"
-#include "certdb.h"
-#include "genname.h"
-#include "xconst.h"
-#include "keyhi.h"
-#include "ocsp.h"
-#include "ocspt.h"
-#include "pk11pub.h"
-#include "pkcs11.h"
-#include "pkcs11t.h"
-#include "prio.h"
-
-/* NSPR headers */
-#include "nspr.h"
-
-/* private PKIX_PL_NSS system headers */
-#include "pkix_pl_object.h"
-#include "pkix_pl_string.h"
-#include "pkix_pl_ldapt.h"
-#include "pkix_pl_aiamgr.h"
-#include "pkix_pl_bigint.h"
-#include "pkix_pl_oid.h"
-#include "pkix_pl_x500name.h"
-#include "pkix_pl_generalname.h"
-#include "pkix_pl_publickey.h"
-#include "pkix_pl_bytearray.h"
-#include "pkix_pl_date.h"
-#include "pkix_pl_primhash.h"
-#include "pkix_pl_basicconstraints.h"
-#include "pkix_pl_bytearray.h"
-#include "pkix_pl_cert.h"
-#include "pkix_pl_certpolicyinfo.h"
-#include "pkix_pl_certpolicymap.h"
-#include "pkix_pl_certpolicyqualifier.h"
-#include "pkix_pl_crldp.h"
-#include "pkix_pl_crl.h"
-#include "pkix_pl_crlentry.h"
-#include "pkix_pl_nameconstraints.h"
-#include "pkix_pl_ocsprequest.h"
-#include "pkix_pl_ocspresponse.h"
-#include "pkix_pl_pk11certstore.h"
-#include "pkix_pl_socket.h"
-#include "pkix_pl_ldapcertstore.h"
-#include "pkix_pl_ldaprequest.h"
-#include "pkix_pl_ldapresponse.h"
-#include "pkix_pl_nsscontext.h"
-#include "pkix_pl_httpcertstore.h"
-#include "pkix_pl_httpdefaultclient.h"
-#include "pkix_pl_infoaccess.h"
-#include "pkix_sample_modules.h"
-
-#define MAX_DIGITS_32 (PKIX_UInt32) 10
-
-#define PKIX_PL_NSSCALL(type, func, args) \
- PKIX_ ## type ## _DEBUG_ARG("( Calling %s).\n", #func); \
- (func args)
-
-#define PKIX_PL_NSSCALLRV(type, lvalue, func, args) \
- PKIX_ ## type ## _DEBUG_ARG("( Calling %s).\n", #func); \
- lvalue = (func args)
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_LockObject(
- PKIX_PL_Object *object,
- void *plContext);
-
-PKIX_Error *
-pkix_UnlockObject(
- PKIX_PL_Object *object,
- void *plContext);
-
-PKIX_Boolean
-pkix_pl_UInt32_Overflows(char *string);
-
-PKIX_Error *
-pkix_pl_helperBytes2Ascii(
- PKIX_UInt32 *tokens,
- PKIX_UInt32 numTokens,
- char **pAscii,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_ipAddrBytes2Ascii(
- SECItem *secItem,
- char **pAscii,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_oidBytes2Ascii(
- SECItem *secItem,
- char **pAscii,
- void *plContext);
-
-/* --String-Encoding-Conversion-Functions------------------------ */
-
-PKIX_Error *
-pkix_UTF16_to_EscASCII(
- const void *utf16String,
- PKIX_UInt32 utf16Length,
- PKIX_Boolean debug,
- char **pDest,
- PKIX_UInt32 *pLength,
- void *plContext);
-
-PKIX_Error *
-pkix_EscASCII_to_UTF16(
- const char *escAsciiString,
- PKIX_UInt32 escAsciiLen,
- PKIX_Boolean debug,
- void **pDest,
- PKIX_UInt32 *pLength,
- void *plContext);
-
-PKIX_Error *
-pkix_UTF16_to_UTF8(
- const void *utf16String,
- PKIX_UInt32 utf16Length,
- PKIX_Boolean null_Term,
- void **pDest,
- PKIX_UInt32 *pLength,
- void *plContext);
-
-PKIX_Error *
-pkix_UTF8_to_UTF16(
- const void *utf8Source,
- PKIX_UInt32 utf8Length,
- void **pDest,
- PKIX_UInt32 *pLength,
- void *plContext);
-
-#endif /* _PKIX_PL_COMMON_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_error.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_error.c
deleted file mode 100644
index 2631aed03..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_error.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_error.c
- *
- * PL error functions
- *
- */
-
-#include "pkix_pl_common.h"
-
-#undef PKIX_ERRORENTRY
-
-#define PKIX_ERRORENTRY(name,desc,plerr) plerr
-
-const PKIX_Int32 PKIX_PLErrorIndex[] =
-{
-#include "pkix_errorstrings.h"
-};
-
-int
-PKIX_PL_GetPLErrorCode()
-{
- return PORT_GetError();
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.c
deleted file mode 100755
index 260365375..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_hashtable.c
- *
- * Hashtable Object Functions
- *
- */
-
-#include "pkix_pl_hashtable.h"
-
-/* --Private-Structure-------------------------------------------- */
-
-struct PKIX_PL_HashTableStruct {
- pkix_pl_PrimHashTable *primHash;
- PKIX_PL_Mutex *tableLock;
- PKIX_UInt32 maxEntriesPerBucket;
-};
-
-/* --Private-Functions-------------------------------------------- */
-
-#define PKIX_MUTEX_UNLOCK(mutex) \
- do { \
- if (mutex && lockedMutex == (PKIX_PL_Mutex *)(mutex)) { \
- pkixTempResult = \
- PKIX_PL_Mutex_Unlock((mutex), plContext); \
- PORT_Assert(pkixTempResult == NULL); \
- if (pkixTempResult) { \
- PKIX_DoAddError(&stdVars, pkixTempResult, plContext); \
- pkixTempResult = NULL; \
- } \
- lockedMutex = NULL; \
- } else { \
- PORT_Assert(lockedMutex == NULL); \
- }\
- } while (0)
-
-
-#define PKIX_MUTEX_LOCK(mutex) \
- do { \
- if (mutex){ \
- PORT_Assert(lockedMutex == NULL); \
- PKIX_CHECK(PKIX_PL_Mutex_Lock((mutex), plContext), \
- PKIX_MUTEXLOCKFAILED); \
- lockedMutex = (mutex); \
- } \
- } while (0)
-
-/*
- * FUNCTION: pkix_pl_HashTable_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_HashTable_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_HashTable *ht = NULL;
- pkix_pl_HT_Elem *item = NULL;
- PKIX_UInt32 i;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_HashTable_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_HASHTABLE_TYPE, plContext),
- PKIX_OBJECTNOTHASHTABLE);
-
- ht = (PKIX_PL_HashTable*) object;
-
- /* DecRef every object in the primitive hash table */
- for (i = 0; i < ht->primHash->size; i++) {
- for (item = ht->primHash->buckets[i];
- item != NULL;
- item = item->next) {
- PKIX_DECREF(item->key);
- PKIX_DECREF(item->value);
- }
- }
-
- PKIX_CHECK(pkix_pl_PrimHashTable_Destroy(ht->primHash, plContext),
- PKIX_PRIMHASHTABLEDESTROYFAILED);
-
- PKIX_DECREF(ht->tableLock);
-
-cleanup:
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/*
- * FUNCTION: pkix_pl_HashTable_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_HASHTABLE_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_HashTable_RegisterSelf(
- void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_HashTable_RegisterSelf");
-
- entry.description = "HashTable";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_HashTable);
- entry.destructor = pkix_pl_HashTable_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_HASHTABLE_TYPE] = entry;
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_HashTable_Create (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_HashTable_Create(
- PKIX_UInt32 numBuckets,
- PKIX_UInt32 maxEntriesPerBucket,
- PKIX_PL_HashTable **pResult,
- void *plContext)
-{
- PKIX_PL_HashTable *hashTable = NULL;
-
- PKIX_ENTER(HASHTABLE, "PKIX_PL_HashTable_Create");
- PKIX_NULLCHECK_ONE(pResult);
-
- if (numBuckets == 0) {
- PKIX_ERROR(PKIX_NUMBUCKETSEQUALSZERO);
- }
-
- /* Allocate a new hashtable */
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_HASHTABLE_TYPE,
- sizeof (PKIX_PL_HashTable),
- (PKIX_PL_Object **)&hashTable,
- plContext),
- PKIX_COULDNOTCREATEHASHTABLEOBJECT);
-
- /* Create the underlying primitive hash table type */
- PKIX_CHECK(pkix_pl_PrimHashTable_Create
- (numBuckets, &hashTable->primHash, plContext),
- PKIX_PRIMHASHTABLECREATEFAILED);
-
- /* Create a lock for this table */
- PKIX_CHECK(PKIX_PL_Mutex_Create(&hashTable->tableLock, plContext),
- PKIX_ERRORCREATINGTABLELOCK);
-
- hashTable->maxEntriesPerBucket = maxEntriesPerBucket;
-
- *pResult = hashTable;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(hashTable);
- }
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/*
- * FUNCTION: PKIX_PL_HashTable_Add (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_HashTable_Add(
- PKIX_PL_HashTable *ht,
- PKIX_PL_Object *key,
- PKIX_PL_Object *value,
- void *plContext)
-{
- PKIX_PL_Mutex *lockedMutex = NULL;
- PKIX_PL_Object *deletedKey = NULL;
- PKIX_PL_Object *deletedValue = NULL;
- PKIX_UInt32 hashCode;
- PKIX_PL_EqualsCallback keyComp;
- PKIX_UInt32 bucketSize = 0;
-
- PKIX_ENTER(HASHTABLE, "PKIX_PL_HashTable_Add");
-
-#if !defined(PKIX_OBJECT_LEAK_TEST)
- PKIX_NULLCHECK_THREE(ht, key, value);
-#else
- PKIX_NULLCHECK_TWO(key, value);
-
- if (ht == NULL) {
- PKIX_RETURN(HASHTABLE);
- }
-#endif
- /* Insert into primitive hashtable */
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode(key, &hashCode, plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_CHECK(pkix_pl_Object_RetrieveEqualsCallback
- (key, &keyComp, plContext),
- PKIX_OBJECTRETRIEVEEQUALSCALLBACKFAILED);
-
- PKIX_MUTEX_LOCK(ht->tableLock);
-
- PKIX_CHECK(pkix_pl_PrimHashTable_GetBucketSize
- (ht->primHash,
- hashCode,
- &bucketSize,
- plContext),
- PKIX_PRIMHASHTABLEGETBUCKETSIZEFAILED);
-
- if (ht->maxEntriesPerBucket != 0 &&
- bucketSize >= ht->maxEntriesPerBucket) {
- /* drop the last one in the bucket */
- PKIX_CHECK(pkix_pl_PrimHashTable_RemoveFIFO
- (ht->primHash,
- hashCode,
- (void **) &deletedKey,
- (void **) &deletedValue,
- plContext),
- PKIX_PRIMHASHTABLEGETBUCKETSIZEFAILED);
- PKIX_DECREF(deletedKey);
- PKIX_DECREF(deletedValue);
- }
-
- PKIX_CHECK(pkix_pl_PrimHashTable_Add
- (ht->primHash,
- (void *)key,
- (void *)value,
- hashCode,
- keyComp,
- plContext),
- PKIX_PRIMHASHTABLEADDFAILED);
-
- PKIX_INCREF(key);
- PKIX_INCREF(value);
- PKIX_MUTEX_UNLOCK(ht->tableLock);
-
- /*
- * we don't call PKIX_PL_InvalidateCache here b/c we have
- * not implemented toString or hashcode for this Object
- */
-
-cleanup:
-
- PKIX_MUTEX_UNLOCK(ht->tableLock);
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/*
- * FUNCTION: PKIX_PL_HashTable_Remove (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_HashTable_Remove(
- PKIX_PL_HashTable *ht,
- PKIX_PL_Object *key,
- void *plContext)
-{
- PKIX_PL_Mutex *lockedMutex = NULL;
- PKIX_PL_Object *origKey = NULL;
- PKIX_PL_Object *value = NULL;
- PKIX_UInt32 hashCode;
- PKIX_PL_EqualsCallback keyComp;
-
- PKIX_ENTER(HASHTABLE, "PKIX_PL_HashTable_Remove");
-
-#if !defined(PKIX_OBJECT_LEAK_TEST)
- PKIX_NULLCHECK_TWO(ht, key);
-#else
- PKIX_NULLCHECK_ONE(key);
-
- if (ht == NULL) {
- PKIX_RETURN(HASHTABLE);
- }
-#endif
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode(key, &hashCode, plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_CHECK(pkix_pl_Object_RetrieveEqualsCallback
- (key, &keyComp, plContext),
- PKIX_OBJECTRETRIEVEEQUALSCALLBACKFAILED);
-
- PKIX_MUTEX_LOCK(ht->tableLock);
-
- /* Remove from primitive hashtable */
- PKIX_CHECK(pkix_pl_PrimHashTable_Remove
- (ht->primHash,
- (void *)key,
- hashCode,
- keyComp,
- (void **)&origKey,
- (void **)&value,
- plContext),
- PKIX_PRIMHASHTABLEREMOVEFAILED);
-
- PKIX_MUTEX_UNLOCK(ht->tableLock);
-
- PKIX_DECREF(origKey);
- PKIX_DECREF(value);
-
- /*
- * we don't call PKIX_PL_InvalidateCache here b/c we have
- * not implemented toString or hashcode for this Object
- */
-
-cleanup:
-
- PKIX_MUTEX_UNLOCK(ht->tableLock);
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/*
- * FUNCTION: PKIX_PL_HashTable_Lookup (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_HashTable_Lookup(
- PKIX_PL_HashTable *ht,
- PKIX_PL_Object *key,
- PKIX_PL_Object **pResult,
- void *plContext)
-{
- PKIX_PL_Mutex *lockedMutex = NULL;
- PKIX_UInt32 hashCode;
- PKIX_PL_EqualsCallback keyComp;
- PKIX_PL_Object *result = NULL;
-
- PKIX_ENTER(HASHTABLE, "PKIX_PL_HashTable_Lookup");
-
-#if !defined(PKIX_OBJECT_LEAK_TEST)
- PKIX_NULLCHECK_THREE(ht, key, pResult);
-#else
- PKIX_NULLCHECK_TWO(key, pResult);
-
- if (ht == NULL) {
- PKIX_RETURN(HASHTABLE);
- }
-#endif
-
- PKIX_CHECK(PKIX_PL_Object_Hashcode(key, &hashCode, plContext),
- PKIX_OBJECTHASHCODEFAILED);
-
- PKIX_CHECK(pkix_pl_Object_RetrieveEqualsCallback
- (key, &keyComp, plContext),
- PKIX_OBJECTRETRIEVEEQUALSCALLBACKFAILED);
-
- PKIX_MUTEX_LOCK(ht->tableLock);
-
- /* Lookup in primitive hashtable */
- PKIX_CHECK(pkix_pl_PrimHashTable_Lookup
- (ht->primHash,
- (void *)key,
- hashCode,
- keyComp,
- (void **)&result,
- plContext),
- PKIX_PRIMHASHTABLELOOKUPFAILED);
-
- PKIX_INCREF(result);
- PKIX_MUTEX_UNLOCK(ht->tableLock);
-
- *pResult = result;
-
-cleanup:
-
- PKIX_MUTEX_UNLOCK(ht->tableLock);
-
- PKIX_RETURN(HASHTABLE);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.h
deleted file mode 100755
index 479c62373..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_hashtable.h
- *
- * Hashtable Object Definition
- *
- */
-
-#ifndef _PKIX_PL_HASHTABLE_H
-#define _PKIX_PL_HASHTABLE_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_HashTable_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_HASHTABLE_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
deleted file mode 100755
index 33381e63f..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_lifecycle.c
- *
- * Lifecycle Functions for the PKIX PL library.
- *
- */
-
-#include "pkix_pl_lifecycle.h"
-
-PKIX_Boolean pkix_pl_initialized = PKIX_FALSE;
-pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
-PRLock *classTableLock;
-PRLogModuleInfo *pkixLog = NULL;
-
-/*
- * PKIX_ALLOC_ERROR is a special error object hard-coded into the
- * pkix_error.o object file. It is thrown if system memory cannot be
- * allocated. PKIX_ALLOC_ERROR is immutable.
- * IncRef, DecRef, and Settor functions cannot be called.
- */
-
-/* Keep this structure definition here for its is used only once here */
-struct PKIX_Alloc_Error_ObjectStruct {
- PKIX_PL_Object header;
- PKIX_Error error;
-};
-typedef struct PKIX_Alloc_Error_ObjectStruct PKIX_Alloc_Error_Object;
-
-static const PKIX_Alloc_Error_Object pkix_Alloc_Error_Data = {
- {
- PKIX_MAGIC_HEADER, /* PRUint64 magicHeader */
- (PKIX_UInt32)PKIX_ERROR_TYPE, /* PKIX_UInt32 type */
- (PKIX_UInt32)1, /* PKIX_UInt32 references */
- /* Warning! Cannot Ref Count with NULL lock */
- (void *)0, /* PRLock *lock */
- (PKIX_PL_String *)0, /* PKIX_PL_String *stringRep */
- (PKIX_UInt32)0, /* PKIX_UInt32 hashcode */
- (PKIX_Boolean)PKIX_FALSE, /* PKIX_Boolean hashcodeCached */
- }, {
- (PKIX_ERRORCODE)0, /* PKIX_ERRORCODE errCode; */
- (PKIX_ERRORCLASS)PKIX_FATAL_ERROR,/* PKIX_ERRORCLASS errClass */
- (PKIX_UInt32)SEC_ERROR_LIBPKIX_INTERNAL, /* default PL Error Code */
- (PKIX_Error *)0, /* PKIX_Error *cause */
- (PKIX_PL_Object *)0, /* PKIX_PL_Object *info */
- }
-};
-
-PKIX_Error* PKIX_ALLOC_ERROR(void)
-{
- return (PKIX_Error *)&pkix_Alloc_Error_Data.error;
-}
-
-#ifdef PKIX_OBJECT_LEAK_TEST
-SECStatus
-pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable)
-{
- int typeCounter = 0;
-
- for (; typeCounter < PKIX_NUMTYPES; typeCounter++) {
- pkix_ClassTable_Entry *entry = &systemClasses[typeCounter];
-
- objCountTable[typeCounter] = entry->objCounter;
- }
-
- return SECSuccess;
-}
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
-
-PKIX_UInt32
-pkix_pl_lifecycle_ObjectLeakCheck(int *initObjCountTable)
-{
- int typeCounter = 0;
- PKIX_UInt32 numObjects = 0;
- char classNameBuff[128];
- char *className = NULL;
-
- for (; typeCounter < PKIX_NUMTYPES; typeCounter++) {
- pkix_ClassTable_Entry *entry = &systemClasses[typeCounter];
- PKIX_UInt32 objCountDiff = entry->objCounter;
-
- if (initObjCountTable) {
- PKIX_UInt32 initialCount = initObjCountTable[typeCounter];
- objCountDiff = (entry->objCounter > initialCount) ?
- entry->objCounter - initialCount : 0;
- }
-
- numObjects += objCountDiff;
-
- if (!pkixLog || !objCountDiff) {
- continue;
- }
- className = entry->description;
- if (!className) {
- className = classNameBuff;
- PR_snprintf(className, 128, "Unknown(ref %d)",
- entry->objCounter);
- }
-
- PR_LOG(pkixLog, 1, ("Class %s leaked %d objects of "
- "size %d bytes, total = %d bytes\n", className,
- objCountDiff, entry->typeObjectSize,
- objCountDiff * entry->typeObjectSize));
- }
-
- return numObjects;
-}
-
-/*
- * PKIX_PL_Initialize (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Initialize(
- PKIX_Boolean platformInitNeeded,
- PKIX_Boolean useArenas,
- void **pPlContext)
-{
- void *plContext = NULL;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Initialize");
-
- /*
- * This function can only be called once. If it has already been
- * called, we return a positive status.
- */
- if (pkix_pl_initialized) {
- PKIX_RETURN(OBJECT);
- }
-
- classTableLock = PR_NewLock();
- if (classTableLock == NULL) {
- return PKIX_ALLOC_ERROR();
- }
-
- if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
- pkixLog = PR_NewLogModule("pkix");
- }
- /*
- * Register Object, it is the base object of all other objects.
- */
- pkix_pl_Object_RegisterSelf(plContext);
-
- /*
- * Register Error and String, since they will be needed if
- * there is a problem in registering any other type.
- */
- pkix_Error_RegisterSelf(plContext);
- pkix_pl_String_RegisterSelf(plContext);
-
-
- /*
- * We register all other system types
- * (They don't need to be in order, but it's
- * easier to keep track of what types are registered
- * if we register them in the same order as their
- * numbers, defined in pkixt.h.
- */
- pkix_pl_BigInt_RegisterSelf(plContext); /* 1-10 */
- pkix_pl_ByteArray_RegisterSelf(plContext);
- pkix_pl_HashTable_RegisterSelf(plContext);
- pkix_List_RegisterSelf(plContext);
- pkix_Logger_RegisterSelf(plContext);
- pkix_pl_Mutex_RegisterSelf(plContext);
- pkix_pl_OID_RegisterSelf(plContext);
- pkix_pl_RWLock_RegisterSelf(plContext);
-
- pkix_pl_CertBasicConstraints_RegisterSelf(plContext); /* 11-20 */
- pkix_pl_Cert_RegisterSelf(plContext);
- pkix_pl_CRL_RegisterSelf(plContext);
- pkix_pl_CRLEntry_RegisterSelf(plContext);
- pkix_pl_Date_RegisterSelf(plContext);
- pkix_pl_GeneralName_RegisterSelf(plContext);
- pkix_pl_CertNameConstraints_RegisterSelf(plContext);
- pkix_pl_PublicKey_RegisterSelf(plContext);
- pkix_TrustAnchor_RegisterSelf(plContext);
-
- pkix_pl_X500Name_RegisterSelf(plContext); /* 21-30 */
- pkix_pl_HttpCertStoreContext_RegisterSelf(plContext);
- pkix_BuildResult_RegisterSelf(plContext);
- pkix_ProcessingParams_RegisterSelf(plContext);
- pkix_ValidateParams_RegisterSelf(plContext);
- pkix_ValidateResult_RegisterSelf(plContext);
- pkix_CertStore_RegisterSelf(plContext);
- pkix_CertChainChecker_RegisterSelf(plContext);
- pkix_RevocationChecker_RegisterSelf(plContext);
- pkix_CertSelector_RegisterSelf(plContext);
-
- pkix_ComCertSelParams_RegisterSelf(plContext); /* 31-40 */
- pkix_CRLSelector_RegisterSelf(plContext);
- pkix_ComCRLSelParams_RegisterSelf(plContext);
- pkix_pl_CertPolicyInfo_RegisterSelf(plContext);
- pkix_pl_CertPolicyQualifier_RegisterSelf(plContext);
- pkix_pl_CertPolicyMap_RegisterSelf(plContext);
- pkix_PolicyNode_RegisterSelf(plContext);
- pkix_TargetCertCheckerState_RegisterSelf(plContext);
- pkix_BasicConstraintsCheckerState_RegisterSelf(plContext);
- pkix_PolicyCheckerState_RegisterSelf(plContext);
-
- pkix_pl_CollectionCertStoreContext_RegisterSelf(plContext); /* 41-50 */
- pkix_CrlChecker_RegisterSelf(plContext);
- pkix_ForwardBuilderState_RegisterSelf(plContext);
- pkix_SignatureCheckerState_RegisterSelf(plContext);
- pkix_NameConstraintsCheckerState_RegisterSelf(plContext);
- pkix_pl_LdapRequest_RegisterSelf(plContext);
- pkix_pl_LdapResponse_RegisterSelf(plContext);
- pkix_pl_LdapDefaultClient_RegisterSelf(plContext);
- pkix_pl_Socket_RegisterSelf(plContext);
-
- pkix_ResourceLimits_RegisterSelf(plContext); /* 51-59 */
- pkix_pl_MonitorLock_RegisterSelf(plContext);
- pkix_pl_InfoAccess_RegisterSelf(plContext);
- pkix_pl_AIAMgr_RegisterSelf(plContext);
- pkix_OcspChecker_RegisterSelf(plContext);
- pkix_pl_OcspCertID_RegisterSelf(plContext);
- pkix_pl_OcspRequest_RegisterSelf(plContext);
- pkix_pl_OcspResponse_RegisterSelf(plContext);
- pkix_pl_HttpDefaultClient_RegisterSelf(plContext);
- pkix_VerifyNode_RegisterSelf(plContext);
- pkix_EkuChecker_RegisterSelf(plContext);
- pkix_pl_CrlDp_RegisterSelf(plContext);
-
- if (pPlContext) {
- PKIX_CHECK(PKIX_PL_NssContext_Create
- (0, useArenas, NULL, &plContext),
- PKIX_NSSCONTEXTCREATEFAILED);
-
- *pPlContext = plContext;
- }
-
- pkix_pl_initialized = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * PKIX_PL_Shutdown (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Shutdown(void *plContext)
-{
- PKIX_UInt32 numLeakedObjects = 0;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Shutdown");
-
- if (!pkix_pl_initialized) {
- /* The library was not initilized */
- PKIX_RETURN(OBJECT);
- }
-
- PR_DestroyLock(classTableLock);
-
- pkix_pl_HttpCertStore_Shutdown(plContext);
-
- numLeakedObjects = pkix_pl_lifecycle_ObjectLeakCheck(NULL);
- if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
- PORT_Assert(numLeakedObjects == 0);
- }
-
- if (plContext != NULL) {
- PKIX_PL_NssContext_Destroy(plContext);
- }
-
- pkix_pl_initialized = PKIX_FALSE;
-
- PKIX_RETURN(OBJECT);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
deleted file mode 100755
index 21c20333e..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_lifecycle.h
- *
- * Lifecycle Definitions
- *
- */
-
-#ifndef _PKIX_PL_LIFECYCLE_H
-#define _PKIX_PL_LIFECYCLE_H
-
-#include "pkix_pl_common.h"
-#include "pkix_pl_oid.h"
-#include "pkix_pl_aiamgr.h"
-#include "pkix_pl_bigint.h"
-#include "pkix_pl_bytearray.h"
-#include "pkix_pl_hashtable.h"
-#include "pkix_pl_mutex.h"
-#include "pkix_pl_rwlock.h"
-#include "pkix_pl_monitorlock.h"
-#include "pkix_pl_string.h"
-#include "pkix_pl_cert.h"
-#include "pkix_pl_x500name.h"
-#include "pkix_pl_generalname.h"
-#include "pkix_pl_publickey.h"
-#include "pkix_pl_date.h"
-#include "pkix_pl_basicconstraints.h"
-#include "pkix_pl_certpolicyinfo.h"
-#include "pkix_pl_certpolicymap.h"
-#include "pkix_pl_certpolicyqualifier.h"
-#include "pkix_pl_crlentry.h"
-#include "pkix_pl_crl.h"
-#include "pkix_pl_colcertstore.h"
-#include "pkix_pl_ldapcertstore.h"
-#include "pkix_pl_ldapdefaultclient.h"
-#include "pkix_pl_ldaprequest.h"
-#include "pkix_pl_ldapresponse.h"
-#include "pkix_pl_socket.h"
-#include "pkix_pl_infoaccess.h"
-#include "pkix_store.h"
-#include "pkix_error.h"
-#include "pkix_logger.h"
-#include "pkix_list.h"
-#include "pkix_trustanchor.h"
-#include "pkix_procparams.h"
-#include "pkix_valparams.h"
-#include "pkix_valresult.h"
-#include "pkix_verifynode.h"
-#include "pkix_resourcelimits.h"
-#include "pkix_certchainchecker.h"
-#include "pkix_revocationchecker.h"
-#include "pkix_certselector.h"
-#include "pkix_comcertselparams.h"
-#include "pkix_crlselector.h"
-#include "pkix_comcrlselparams.h"
-#include "pkix_targetcertchecker.h"
-#include "pkix_basicconstraintschecker.h"
-#include "pkix_policynode.h"
-#include "pkix_policychecker.h"
-#include "pkix_crlchecker.h"
-#include "pkix_signaturechecker.h"
-#include "pkix_buildresult.h"
-#include "pkix_build.h"
-#include "pkix_pl_nameconstraints.h"
-#include "pkix_nameconstraintschecker.h"
-#include "pkix_ocspchecker.h"
-#include "pkix_pl_ocspcertid.h"
-#include "pkix_pl_ocsprequest.h"
-#include "pkix_pl_ocspresponse.h"
-#include "pkix_pl_httpdefaultclient.h"
-#include "pkix_pl_httpcertstore.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_InitializeParamsStruct {
- PKIX_List *loggers;
- PKIX_UInt32 majorVersion;
- PKIX_UInt32 minorVersion;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_LIFECYCLE_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.c
deleted file mode 100755
index d75c0be26..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_mem.c
- *
- * Memory Management Functions
- *
- */
-
-#include "pkix_pl_mem.h"
-
-/*
- * FUNCTION: PKIX_PL_Malloc (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Malloc(
- PKIX_UInt32 size,
- void **pMemory,
- void *plContext)
-{
- PKIX_PL_NssContext *nssContext = NULL;
- void *result = NULL;
-
- PKIX_ENTER(MEM, "PKIX_PL_Malloc");
- PKIX_NULLCHECK_ONE(pMemory);
-
- if (size == 0){
- *pMemory = NULL;
- } else {
-
- nssContext = (PKIX_PL_NssContext *)plContext;
-
- if (nssContext != NULL && nssContext->arena != NULL) {
- PKIX_MEM_DEBUG("\tCalling PORT_ArenaAlloc.\n");
- *pMemory = PORT_ArenaAlloc(nssContext->arena, size);
- } else {
- PKIX_MEM_DEBUG("\tCalling PR_Malloc.\n");
- result = (void *) PR_Malloc(size);
-
- if (result == NULL) {
- PKIX_MEM_DEBUG("Fatal Error Occurred: "
- "PR_Malloc failed.\n");
- PKIX_ERROR_ALLOC_ERROR();
- } else {
- *pMemory = result;
- }
- }
- }
-
-cleanup:
- PKIX_RETURN(MEM);
-}
-
-/*
- * FUNCTION: PKIX_PL_Calloc (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Calloc(
- PKIX_UInt32 nElem,
- PKIX_UInt32 elSize,
- void **pMemory,
- void *plContext)
-{
- PKIX_PL_NssContext *nssContext = NULL;
- void *result = NULL;
-
- PKIX_ENTER(MEM, "PKIX_PL_Calloc");
- PKIX_NULLCHECK_ONE(pMemory);
-
- if ((nElem == 0) || (elSize == 0)){
- *pMemory = NULL;
- } else {
-
- nssContext = (PKIX_PL_NssContext *)plContext;
-
- if (nssContext != NULL && nssContext->arena != NULL) {
- PKIX_MEM_DEBUG("\tCalling PORT_ArenaAlloc.\n");
- *pMemory = PORT_ArenaAlloc(nssContext->arena, elSize);
- } else {
- PKIX_MEM_DEBUG("\tCalling PR_Calloc.\n");
- result = (void *) PR_Calloc(nElem, elSize);
-
- if (result == NULL) {
- PKIX_MEM_DEBUG("Fatal Error Occurred: "
- "PR_Calloc failed.\n");
- PKIX_ERROR_ALLOC_ERROR();
- } else {
- *pMemory = result;
- }
- }
- }
-
-cleanup:
-
- PKIX_RETURN(MEM);
-}
-
-/*
- * FUNCTION: PKIX_PL_Realloc (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Realloc(
- void *ptr,
- PKIX_UInt32 size,
- void **pMemory,
- void *plContext)
-{
- PKIX_PL_NssContext *nssContext = NULL;
- void *result = NULL;
-
- PKIX_ENTER(MEM, "PKIX_PL_Realloc");
- PKIX_NULLCHECK_ONE(pMemory);
-
- nssContext = (PKIX_PL_NssContext *)plContext;
-
- if (nssContext != NULL && nssContext->arena != NULL) {
- PKIX_MEM_DEBUG("\tCalling PORT_ArenaAlloc.\n");
- result = PORT_ArenaAlloc(nssContext->arena, size);
-
- if (result){
- PKIX_MEM_DEBUG("\tCalling PORT_Memcpy.\n");
- PORT_Memcpy(result, ptr, size);
- }
- *pMemory = result;
- } else {
- PKIX_MEM_DEBUG("\tCalling PR_Realloc.\n");
- result = (void *) PR_Realloc(ptr, size);
-
- if (result == NULL) {
- if (size == 0){
- *pMemory = NULL;
- } else {
- PKIX_MEM_DEBUG
- ("Fatal Error Occurred: "
- "PR_Realloc failed.\n");
- PKIX_ERROR_ALLOC_ERROR();
- }
- } else {
- *pMemory = result;
- }
- }
-
-cleanup:
-
- PKIX_RETURN(MEM);
-}
-
-/*
- * FUNCTION: PKIX_PL_Free (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Free(
- void *ptr,
- /* ARGSUSED */ void *plContext)
-{
- PKIX_PL_NssContext *context = NULL;
-
- PKIX_ENTER(MEM, "PKIX_PL_Free");
-
- context = (PKIX_PL_NssContext *) plContext;
- if (context == NULL || context->arena == NULL) {
- PKIX_MEM_DEBUG("\tCalling PR_Free.\n");
- (void) PR_Free(ptr);
- }
-
- PKIX_RETURN(MEM);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.h
deleted file mode 100755
index eaec6246c..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_mem.h
- *
- * Memory Management Definitions
- *
- */
-
-#ifndef _PKIX_PL_MEM_H
-#define _PKIX_PL_MEM_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_MEM_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.c
deleted file mode 100755
index a5d2fc962..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_monitorlock.c
- *
- * Read/Write Lock Functions
- *
- */
-
-#include "pkix_pl_monitorlock.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-static PKIX_Error *
-pkix_pl_MonitorLock_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_MonitorLock* monitorLock = NULL;
-
- PKIX_ENTER(MONITORLOCK, "pkix_pl_MonitorLock_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_MONITORLOCK_TYPE, plContext),
- PKIX_OBJECTNOTMONITORLOCK);
-
- monitorLock = (PKIX_PL_MonitorLock*) object;
-
- PKIX_MONITORLOCK_DEBUG("Calling PR_DestroyMonitor)\n");
- PR_DestroyMonitor(monitorLock->lock);
- monitorLock->lock = NULL;
-
-cleanup:
-
- PKIX_RETURN(MONITORLOCK);
-}
-
-/*
- * FUNCTION: pkix_pl_MonitorLock_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_MONITORLOCK_TYPE and its related functions with
- * systemClasses[].
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_MonitorLock_RegisterSelf(
- void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(MONITORLOCK, "pkix_pl_MonitorLock_RegisterSelf");
-
- entry.description = "MonitorLock";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_MonitorLock);
- entry.destructor = pkix_pl_MonitorLock_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_MONITORLOCK_TYPE] = entry;
-
- PKIX_RETURN(MONITORLOCK);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-PKIX_Error *
-PKIX_PL_MonitorLock_Create(
- PKIX_PL_MonitorLock **pNewLock,
- void *plContext)
-{
- PKIX_PL_MonitorLock *monitorLock = NULL;
-
- PKIX_ENTER(MONITORLOCK, "PKIX_PL_MonitorLock_Create");
- PKIX_NULLCHECK_ONE(pNewLock);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_MONITORLOCK_TYPE,
- sizeof (PKIX_PL_MonitorLock),
- (PKIX_PL_Object **)&monitorLock,
- plContext),
- PKIX_ERRORALLOCATINGMONITORLOCK);
-
- PKIX_MONITORLOCK_DEBUG("\tCalling PR_NewMonitor)\n");
- monitorLock->lock = PR_NewMonitor();
-
- if (monitorLock->lock == NULL) {
- PKIX_DECREF(monitorLock);
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- *pNewLock = monitorLock;
-
-cleanup:
-
- PKIX_RETURN(MONITORLOCK);
-}
-
-PKIX_Error *
-PKIX_PL_MonitorLock_Enter(
- PKIX_PL_MonitorLock *monitorLock,
- void *plContext)
-{
- PKIX_ENTER_NO_LOGGER(MONITORLOCK, "PKIX_PL_MonitorLock_Enter");
- PKIX_NULLCHECK_ONE(monitorLock);
-
- PKIX_MONITORLOCK_DEBUG("\tCalling PR_EnterMonitor)\n");
- (void) PR_EnterMonitor(monitorLock->lock);
-
- PKIX_RETURN_NO_LOGGER(MONITORLOCK);
-}
-
-PKIX_Error *
-PKIX_PL_MonitorLock_Exit(
- PKIX_PL_MonitorLock *monitorLock,
- void *plContext)
-{
- PKIX_ENTER_NO_LOGGER(MONITORLOCK, "PKIX_PL_MonitorLock_Exit");
- PKIX_NULLCHECK_ONE(monitorLock);
-
- PKIX_MONITORLOCK_DEBUG("\tCalling PR_ExitMonitor)\n");
- PR_ExitMonitor(monitorLock->lock);
-
- PKIX_RETURN_NO_LOGGER(MONITORLOCK);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.h
deleted file mode 100755
index 76ac539ad..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_monitorlock.h
- *
- * Read/Write Lock Definition
- *
- */
-
-#ifndef _PKIX_PL_MONITORLOCK_H
-#define _PKIX_PL_MONITORLOCK_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_MonitorLockStruct {
- PRMonitor* lock;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_MonitorLock_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_MONITORLOCK_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.c
deleted file mode 100755
index 07d13695b..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_mutex.c
- *
- * Mutual Exclusion (Lock) Object Functions
- *
- */
-
-#include "pkix_pl_mutex.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_Mutex_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_Mutex_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_Mutex *mutex = NULL;
-
- PKIX_ENTER(MUTEX, "pkix_pl_Mutex_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- /* Sanity check: Test that "object" is a mutex */
- PKIX_CHECK(pkix_CheckType(object, PKIX_MUTEX_TYPE, plContext),
- PKIX_OBJECTNOTMUTEX);
-
- mutex = (PKIX_PL_Mutex*) object;
-
- PKIX_MUTEX_DEBUG("\tCalling PR_DestroyLock).\n");
- PR_DestroyLock(mutex->lock);
- mutex->lock = NULL;
-
-cleanup:
-
- PKIX_RETURN(MUTEX);
-}
-
-/*
- * FUNCTION: pkix_pl_Mutex_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_MUTEX_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_Mutex_RegisterSelf(
- /* ARGSUSED */ void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(MUTEX, "pkix_pl_Mutex_RegisterSelf");
-
- entry.description = "Mutex";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_Mutex);
- entry.destructor = pkix_pl_Mutex_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_MUTEX_TYPE] = entry;
-
- PKIX_RETURN(MUTEX);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_Mutex_Create (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Mutex_Create(
- PKIX_PL_Mutex **pNewLock,
- void *plContext)
-{
- PKIX_PL_Mutex *mutex = NULL;
-
- PKIX_ENTER(MUTEX, "PKIX_PL_Mutex_Create");
- PKIX_NULLCHECK_ONE(pNewLock);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_MUTEX_TYPE,
- sizeof (PKIX_PL_Mutex),
- (PKIX_PL_Object **)&mutex,
- plContext),
- PKIX_COULDNOTCREATELOCKOBJECT);
-
- PKIX_MUTEX_DEBUG("\tCalling PR_NewLock).\n");
- mutex->lock = PR_NewLock();
-
- /* If an error occurred in NSPR, report it here */
- if (mutex->lock == NULL) {
- PKIX_DECREF(mutex);
- PKIX_ERROR_ALLOC_ERROR();
- }
-
- *pNewLock = mutex;
-
-cleanup:
-
- PKIX_RETURN(MUTEX);
-}
-
-/*
- * FUNCTION: PKIX_PL_Mutex_Lock (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Mutex_Lock(
- PKIX_PL_Mutex *mutex,
- void *plContext)
-{
- PKIX_ENTER(MUTEX, "PKIX_PL_Mutex_Lock");
- PKIX_NULLCHECK_ONE(mutex);
-
- PKIX_MUTEX_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(mutex->lock);
-
- PKIX_MUTEX_DEBUG_ARG("(Thread %u just acquired the lock)\n",
- (PKIX_UInt32)PR_GetCurrentThread());
-
- PKIX_RETURN(MUTEX);
-}
-
-/*
- * FUNCTION: PKIX_PL_Mutex_Unlock (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Mutex_Unlock(
- PKIX_PL_Mutex *mutex,
- void *plContext)
-{
- PRStatus result;
-
- PKIX_ENTER(MUTEX, "PKIX_PL_Mutex_Unlock");
- PKIX_NULLCHECK_ONE(mutex);
-
- PKIX_MUTEX_DEBUG("\tCalling PR_Unlock).\n");
- result = PR_Unlock(mutex->lock);
-
- PKIX_MUTEX_DEBUG_ARG("(Thread %u just released the lock)\n",
- (PKIX_UInt32)PR_GetCurrentThread());
-
- if (result == PR_FAILURE) {
- PKIX_ERROR_FATAL(PKIX_ERRORUNLOCKINGMUTEX);
- }
-
-cleanup:
- PKIX_RETURN(MUTEX);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.h
deleted file mode 100755
index baf16fea9..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_mutex.h
- *
- * Mutual Exclusion (Lock) Object Type Definition
- *
- */
-
-#ifndef _PKIX_PL_MUTEX_H
-#define _PKIX_PL_MUTEX_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_MutexStruct {
- PRLock* lock;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_Mutex_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_MUTEX_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c
deleted file mode 100755
index 881a1ed54..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c
+++ /dev/null
@@ -1,1440 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_object.c
- *
- * Object Construction, Destruction and Callback Functions
- *
- */
-
-#include "pkix_pl_object.h"
-
-#ifdef PKIX_USER_OBJECT_TYPE
-/* --Class-Table-Initializers------------------------------------ */
-
-/*
- * Create storage space for 20 Class Table buckets.
- * These are only for user-defined types. System types are registered
- * separately by PKIX_PL_Initialize.
- */
-
-static pkix_pl_HT_Elem*
-pkix_Raw_ClassTable_Buckets[] = {
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-/*
- * Allocate static memory for a ClassTable.
- * XXX This assumes the bucket pointer will fit into a PKIX_UInt32
- */
-static pkix_pl_PrimHashTable pkix_Raw_ClassTable = {
- (void *)pkix_Raw_ClassTable_Buckets, /* Buckets */
- 20 /* Number of Buckets */
-};
-static pkix_pl_PrimHashTable * classTable = &pkix_Raw_ClassTable;
-#endif /* PKIX_USER_OBJECT_TYPE */
-
-/* --Private-Functions-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_Object_GetHeader
- * DESCRIPTION:
- *
- * Shifts Object pointed to by "object" by the sizeof(PKIX_PL_Object) and
- * stores the value at "pObjectHeader".
- *
- * PARAMETERS:
- * "object"
- * Address of Object to shift. Must be non-NULL.
- * "pObjectHeader"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Object_GetHeader(
- PKIX_PL_Object *object,
- PKIX_PL_Object **pObjectHeader,
- void *plContext)
-{
- PKIX_PL_Object *header = NULL;
- PKIX_UInt32 objType;
-
- PKIX_ENTER(OBJECT, "pkix_pl_Object_GetHeader");
- PKIX_NULLCHECK_TWO(object, pObjectHeader);
-
- PKIX_OBJECT_DEBUG("\tShifting object pointer).\n");
-
- /* The header is sizeof(PKIX_PL_Object) before the object pointer */
- header = (PKIX_PL_Object *)((char *)object - sizeof(PKIX_PL_Object));
-
- objType = header->type;
-
- if (objType >= PKIX_NUMTYPES) { /* if this is a user-defined type */
-#ifdef PKIX_USER_OBJECT_TYPE
- pkix_ClassTable_Entry *ctEntry = NULL;
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
-
- PKIX_CHECK(pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext),
- PKIX_ERRORGETTINGCLASSTABLEENTRY);
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
-
- if (ctEntry == NULL) {
- PKIX_ERROR_FATAL(PKIX_UNKNOWNOBJECTTYPE);
- }
-#else
- PORT_Assert(objType < PKIX_NUMTYPES);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- }
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- PORT_Assert(header && header->magicHeader == PKIX_MAGIC_HEADER);
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- if ((header == NULL)||
- (header->magicHeader != PKIX_MAGIC_HEADER)) {
- PKIX_ERROR_ALLOC_ERROR();
- }
-
- *pObjectHeader = header;
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: pkix_Destroy_Object
- * DESCRIPTION:
- *
- * Destroys and deallocates Object pointed to by "object". The caller is
- * assumed to hold the Object's lock, which is acquired in
- * PKIX_PL_Object_DecRef().
- *
- * PARAMETERS:
- * "object"
- * Address of Object to destroy. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Object_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_Object *objectHeader = NULL;
-
- PKIX_ENTER(OBJECT, "pkix_pl_Object_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- PKIX_CHECK_FATAL(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-#else
- PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- /* Attempt to delete an object still being used */
- if (objectHeader->references != 0) {
- PKIX_ERROR_FATAL(PKIX_OBJECTSTILLREFERENCED);
- }
-
- PKIX_DECREF(objectHeader->stringRep);
-
- /* Destroy this object's lock */
- PKIX_OBJECT_DEBUG("\tCalling PR_DestroyLock).\n");
- PR_DestroyLock(objectHeader->lock);
- objectHeader->lock = NULL;
- object = NULL;
-
- objectHeader->magicHeader = PKIX_MAGIC_HEADER_DESTROYED;
-
-#ifdef PKIX_OBJECT_LEAK_TEST
- memset(objectHeader, 0xbf, systemClasses[PKIX_OBJECT_TYPE].typeObjectSize);
-#endif
-
- PKIX_FREE(objectHeader);
-
-cleanup:
-#ifdef PKIX_OBJECT_LEAK_TEST
-fatal:
-#endif
-
- PKIX_RETURN(OBJECT);
-}
-
-/* --Default-Callbacks-------------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_Object_Equals_Default
- * DESCRIPTION:
- *
- * Default Object_Equals callback: Compares the address of the Object pointed
- * to by "firstObject" with the address of the Object pointed to by
- * "secondObject" and stores the Boolean result at "pResult".
- *
- * PARAMETERS:
- * "firstObject"
- * Address of first Object to compare. Must be non-NULL.
- * "secondObject"
- * Address of second Object to compare. Must be non-NULL.
- * "pResult"
- * Address where Boolean result will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Object_Equals_Default(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_ENTER(OBJECT, "pkix_pl_Object_Equals_Default");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* Just compare pointer values */
- *pResult = (firstObject == secondObject)?PKIX_TRUE:PKIX_FALSE;
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: pkix_pl_Object_ToString_Default
- * DESCRIPTION:
- *
- * Default Object_ToString callback: Creates a string consisting of the
- * typename and address of the Object pointed to by "object" and stores
- * the result at "pString". The format for the string is
- * "TypeName@Address: <address>", where the default typename is "Object".
- *
- * PARAMETERS:
- * "object"
- * Address of Object to convert to a string. Must be non-NULL.
- * "pString"
- * Address where object pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Object_ToString_Default(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *formatString = NULL;
- PKIX_PL_String *descString = NULL;
- char *format = "%s@Address: %x";
- char *description = NULL;
- PKIX_UInt32 objType;
-
- PKIX_ENTER(OBJECT, "pkix_pl_Object_ToString_Default");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(object, &objType, plContext),
- PKIX_OBJECTGETTYPEFAILED);
-
- if (objType >= PKIX_NUMTYPES){
-#ifdef PKIX_USER_OBJECT_TYPE
- pkix_ClassTable_Entry *ctEntry = NULL;
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
- if (pkixErrorResult){
- PKIX_ERROR_FATAL(PKIX_ERRORGETTINGCLASSTABLEENTRY);
- }
-
- if (ctEntry == NULL){
- PKIX_ERROR_FATAL(PKIX_UNDEFINEDCLASSTABLEENTRY);
- } else {
- description = ctEntry->description;
- if (description == NULL) {
- description = "User Type Object";
- }
- }
-#else
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- } else {
- description = systemClasses[objType].description;
- }
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- (void *)format,
- 0,
- &formatString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII,
- (void *)description,
- 0,
- &descString,
- plContext),
- PKIX_STRINGCREATEFAILED);
-
- PKIX_CHECK(PKIX_PL_Sprintf
- (pString,
- plContext,
- formatString,
- descString,
- object),
- PKIX_SPRINTFFAILED);
-
-cleanup:
-
- PKIX_DECREF(formatString);
- PKIX_DECREF(descString);
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: pkix_pl_Object_Hashcode_Default
- * DESCRIPTION:
- *
- * Default Object_Hashcode callback. Creates the a hashcode value using the
- * address of the Object pointed to by "object" and stores the result at
- * "pValue".
- *
- * XXX This isn't great since addresses are not uniformly distributed.
- *
- * PARAMETERS:
- * "object"
- * Address of Object to compute hashcode for. Must be non-NULL.
- * "pValue"
- * Address where PKIX_UInt32 will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_Object_Hashcode_Default(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pValue,
- void *plContext)
-{
- PKIX_ENTER(OBJECT, "pkix_pl_Object_Hashcode_Default");
- PKIX_NULLCHECK_TWO(object, pValue);
-
- *pValue = (PKIX_UInt32)object;
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: pkix_pl_Object_RetrieveEqualsCallback
- * DESCRIPTION:
- *
- * Retrieves Equals callback function of Object pointed to by "object and
- * stores it at "pEqualsCallback". If the object's type is one of the system
- * types, its callback function is retrieved from the systemClasses array;
- * otherwise, its callback function is retrieve from the classTable hash
- * table where user-defined types are stored.
- *
- * PARAMETERS:
- * "object"
- * Address of Object whose equals callback is desired. Must be non-NULL.
- * "pEqualsCallback"
- * Address where EqualsCallback function pointer will be stored.
- * Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns an Object Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_Object_RetrieveEqualsCallback(
- PKIX_PL_Object *object,
- PKIX_PL_EqualsCallback *pEqualsCallback,
- void *plContext)
-{
- PKIX_PL_Object *objectHeader = NULL;
- PKIX_PL_EqualsCallback func = NULL;
- pkix_ClassTable_Entry entry;
- PKIX_UInt32 objType;
-
- PKIX_ENTER(OBJECT, "pkix_pl_Object_RetrieveEqualsCallback");
- PKIX_NULLCHECK_TWO(object, pEqualsCallback);
-
- PKIX_CHECK(pkix_pl_Object_GetHeader
- (object, &objectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- objType = objectHeader->type;
-
- if (objType >= PKIX_NUMTYPES){
-#ifdef PKIX_USER_OBJECT_TYPE
- pkix_ClassTable_Entry *ctEntry = NULL;
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
- if (pkixErrorResult){
- PKIX_ERROR(PKIX_ERRORGETTINGCLASSTABLEENTRY);
- }
-
- if ((ctEntry == NULL) || (ctEntry->equalsFunction == NULL)) {
- PKIX_ERROR(PKIX_UNDEFINEDEQUALSCALLBACK);
- } else {
- *pEqualsCallback = ctEntry->equalsFunction;
- }
-#else
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- } else {
- entry = systemClasses[objType];
- func = entry.equalsFunction;
- if (func == NULL){
- func = pkix_pl_Object_Equals_Default;
- }
- *pEqualsCallback = func;
- }
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: pkix_pl_Object_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_OBJECT_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- *
- * PKIX_PL_Object should have all function pointes to be to NULL: they
- * work as proxy function to a real objects.
- *
- */
-PKIX_Error *
-pkix_pl_Object_RegisterSelf(void *plContext)
-{
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(ERROR, "pkix_pl_Object_RegisterSelf");
-
- entry.description = "Object";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_Object);
- entry.destructor = NULL;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_OBJECT_TYPE] = entry;
-
- PKIX_RETURN(ERROR);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_Object_Alloc (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_Alloc(
- PKIX_TYPENUM objType,
- PKIX_UInt32 size,
- PKIX_PL_Object **pObject,
- void *plContext)
-{
- PKIX_PL_Object *object = NULL;
- pkix_ClassTable_Entry *ctEntry = NULL;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_Alloc");
- PKIX_NULLCHECK_ONE(pObject);
-
- /*
- * We need to ensure that user-defined types have been registered.
- * All system types have already been registered by PKIX_PL_Initialize.
- */
-
- if (objType >= PKIX_NUMTYPES) { /* i.e. if this is a user-defined type */
-#ifdef PKIX_USER_OBJECT_TYPE
- PKIX_Boolean typeRegistered;
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
- if (pkixErrorResult){
- PKIX_ERROR_FATAL(PKIX_COULDNOTLOOKUPINHASHTABLE);
- }
-
- typeRegistered = (ctEntry != NULL);
-
- if (!typeRegistered) {
- PKIX_ERROR_FATAL(PKIX_UNKNOWNTYPEARGUMENT);
- }
-#else
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- } else {
- ctEntry = &systemClasses[objType];
- }
-
- PORT_Assert(size == ctEntry->typeObjectSize);
-
- /* Allocate space for the object header and the requested size */
-#ifdef PKIX_OBJECT_LEAK_TEST
- PKIX_CHECK(PKIX_PL_Calloc
- (1,
- ((PKIX_UInt32)sizeof (PKIX_PL_Object))+size,
- (void **)&object,
- plContext),
- PKIX_MALLOCFAILED);
-#else
- PKIX_CHECK(PKIX_PL_Malloc
- (((PKIX_UInt32)sizeof (PKIX_PL_Object))+size,
- (void **)&object,
- plContext),
- PKIX_MALLOCFAILED);
-#endif /* PKIX_OBJECT_LEAK_TEST */
-
- /* Initialize all object fields */
- object->magicHeader = PKIX_MAGIC_HEADER;
- object->type = objType;
- object->references = 1; /* Default to a single reference */
- object->stringRep = NULL;
- object->hashcode = 0;
- object->hashcodeCached = 0;
-
- /* Cannot use PKIX_PL_Mutex because it depends on Object */
- /* Using NSPR Locks instead */
- PKIX_OBJECT_DEBUG("\tCalling PR_NewLock).\n");
- object->lock = PR_NewLock();
- if (object->lock == NULL) {
- PKIX_ERROR_ALLOC_ERROR();
- }
-
- PKIX_OBJECT_DEBUG("\tShifting object pointer).\n");
-
-
- /* Return a pointer to the user data. Need to offset by object size */
- *pObject = object + 1;
- object = NULL;
-
- /* Atomically increment object counter */
- PR_ATOMIC_INCREMENT(&ctEntry->objCounter);
-
-cleanup:
-
- PKIX_FREE(object);
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Object_IsTypeRegistered (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_IsTypeRegistered(
- PKIX_UInt32 objType,
- PKIX_Boolean *pBool,
- void *plContext)
-{
-#ifdef PKIX_USER_OBJECT_TYPE
- pkix_ClassTable_Entry *ctEntry = NULL;
-#endif
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_IsTypeRegistered");
- PKIX_NULLCHECK_ONE(pBool);
-
- /* first, we handle the system types */
- if (objType < PKIX_NUMTYPES) {
- *pBool = PKIX_TRUE;
- goto cleanup;
- }
-
-#ifndef PKIX_USER_OBJECT_TYPE
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
-#else
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
-
- if (pkixErrorResult){
- PKIX_ERROR_FATAL(PKIX_COULDNOTLOOKUPINHASHTABLE);
- }
-
- *pBool = (ctEntry != NULL);
-#endif /* PKIX_USER_OBJECT_TYPE */
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-#ifdef PKIX_USER_OBJECT_TYPE
-/*
- * FUNCTION: PKIX_PL_Object_RegisterType (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_RegisterType(
- PKIX_UInt32 objType,
- char *description,
- PKIX_PL_DestructorCallback destructor,
- PKIX_PL_EqualsCallback equalsFunction,
- PKIX_PL_HashcodeCallback hashcodeFunction,
- PKIX_PL_ToStringCallback toStringFunction,
- PKIX_PL_ComparatorCallback comparator,
- PKIX_PL_DuplicateCallback duplicateFunction,
- void *plContext)
-{
- pkix_ClassTable_Entry *ctEntry = NULL;
- pkix_pl_Integer *key = NULL;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_RegisterType");
-
- /*
- * System types are registered on startup by PKIX_PL_Initialize.
- * These can not be overwritten.
- */
-
- if (objType < PKIX_NUMTYPES) { /* if this is a system type */
- PKIX_ERROR(PKIX_CANTREREGISTERSYSTEMTYPE);
- }
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- PKIX_CHECK(pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext),
- PKIX_PRIMHASHTABLELOOKUPFAILED);
-
- /* If the type is already registered, throw an error */
- if (ctEntry) {
- PKIX_ERROR(PKIX_TYPEALREADYREGISTERED);
- }
-
- PKIX_CHECK(PKIX_PL_Malloc
- (((PKIX_UInt32)sizeof (pkix_ClassTable_Entry)),
- (void **)&ctEntry,
- plContext),
- PKIX_MALLOCFAILED);
-
- /* Set Default Values if none specified */
-
- if (description == NULL){
- description = "Object";
- }
-
- if (equalsFunction == NULL) {
- equalsFunction = pkix_pl_Object_Equals_Default;
- }
-
- if (toStringFunction == NULL) {
- toStringFunction = pkix_pl_Object_ToString_Default;
- }
-
- if (hashcodeFunction == NULL) {
- hashcodeFunction = pkix_pl_Object_Hashcode_Default;
- }
-
- ctEntry->destructor = destructor;
- ctEntry->equalsFunction = equalsFunction;
- ctEntry->toStringFunction = toStringFunction;
- ctEntry->hashcodeFunction = hashcodeFunction;
- ctEntry->comparator = comparator;
- ctEntry->duplicateFunction = duplicateFunction;
- ctEntry->description = description;
-
- PKIX_CHECK(PKIX_PL_Malloc
- (((PKIX_UInt32)sizeof (pkix_pl_Integer)),
- (void **)&key,
- plContext),
- PKIX_COULDNOTMALLOCNEWKEY);
-
- key->ht_int = objType;
-
- PKIX_CHECK(pkix_pl_PrimHashTable_Add
- (classTable,
- (void *)key,
- (void *)ctEntry,
- objType,
- NULL,
- plContext),
- PKIX_PRIMHASHTABLEADDFAILED);
-
-cleanup:
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
-
- PKIX_RETURN(OBJECT);
-}
-#endif /* PKIX_USER_OBJECT_TYPE */
-
-/*
- * FUNCTION: PKIX_PL_Object_IncRef (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_IncRef(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_Object *objectHeader = NULL;
- PKIX_PL_NssContext *context = NULL;
- PKIX_Int32 refCount = 0;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_IncRef");
- PKIX_NULLCHECK_ONE(object);
-
- if (plContext){
- /*
- * PKIX_PL_NssContext is not a complete PKIX Type, it doesn't
- * have a header therefore we cannot verify its type before
- * casting.
- */
- context = (PKIX_PL_NssContext *) plContext;
- if (context->arena != NULL) {
- goto cleanup;
- }
- }
-
- if (object == (PKIX_PL_Object*)PKIX_ALLOC_ERROR()) {
- goto cleanup;
- }
-
- /* Shift pointer from user data to object header */
- PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- /* This object should never have zero references */
- refCount = PR_ATOMIC_INCREMENT(&objectHeader->references);
-
- if (refCount <= 1) {
- PKIX_THROW(FATAL, PKIX_OBJECTWITHNONPOSITIVEREFERENCES);
- }
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Object_DecRef (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_DecRef(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_Int32 refCount = 0;
- PKIX_PL_Object *objectHeader = NULL;
- PKIX_PL_NssContext *context = NULL;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_DecRef");
- PKIX_NULLCHECK_ONE(object);
-
- if (plContext){
- /*
- * PKIX_PL_NssContext is not a complete PKIX Type, it doesn't
- * have a header therefore we cannot verify its type before
- * casting.
- */
- context = (PKIX_PL_NssContext *) plContext;
- if (context->arena != NULL) {
- goto cleanup;
- }
- }
-
- if (object == (PKIX_PL_Object*)PKIX_ALLOC_ERROR()) {
- goto cleanup;
- }
-
- /* Shift pointer from user data to object header */
- PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- refCount = PR_ATOMIC_DECREMENT(&objectHeader->references);
-
- if (refCount == 0) {
- PKIX_PL_DestructorCallback destructor = NULL;
- pkix_ClassTable_Entry *ctEntry = NULL;
- PKIX_UInt32 objType = objectHeader->type;
-
- /* first, special handling for system types */
- if (objType >= PKIX_NUMTYPES){
-#ifdef PKIX_USER_OBJECT_TYPE
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG
- ("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
- if (pkixErrorResult){
- PKIX_ERROR_FATAL
- (PKIX_ERRORINGETTINGDESTRUCTOR);
- }
-
- if (ctEntry != NULL){
- destructor = ctEntry->destructor;
- }
-#else
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- } else {
- ctEntry = &systemClasses[objType];
- destructor = ctEntry->destructor;
- }
-
- if (destructor != NULL){
- /* Call destructor on user data if necessary */
- pkixErrorResult = destructor(object, plContext);
- if (pkixErrorResult) {
- pkixErrorClass = PKIX_FATAL_ERROR;
- PKIX_DoAddError(stdVarsPtr, pkixErrorResult, plContext);
- pkixErrorResult = NULL;
- }
- }
-
- /* Atomically decrement object counter */
- PR_ATOMIC_DECREMENT(&ctEntry->objCounter);
-
- /* pkix_pl_Object_Destroy assumes the lock is held */
- /* It will call unlock and destroy the object */
- pkixErrorResult = pkix_pl_Object_Destroy(object, plContext);
- goto cleanup;
- }
-
- if (refCount < 0) {
- PKIX_ERROR_ALLOC_ERROR();
- }
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-
-
-/*
- * FUNCTION: PKIX_PL_Object_Equals (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_PL_Object *firstObjectHeader = NULL;
- PKIX_PL_Object *secondObjectHeader = NULL;
- PKIX_PL_EqualsCallback func = NULL;
- pkix_ClassTable_Entry entry;
- PKIX_UInt32 objType;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- PKIX_CHECK(pkix_pl_Object_GetHeader
- (firstObject, &firstObjectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- PKIX_CHECK(pkix_pl_Object_GetHeader
- (secondObject, &secondObjectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- /* if hashcodes are cached but not equal, objects can't be equal */
- if (firstObjectHeader->hashcodeCached &&
- secondObjectHeader->hashcodeCached){
- if (firstObjectHeader->hashcode !=
- secondObjectHeader->hashcode){
- *pResult = PKIX_FALSE;
- goto cleanup;
- }
- }
-
- objType = firstObjectHeader->type;
-
- if (objType >= PKIX_NUMTYPES) {
-#ifdef PKIX_USER_OBJECT_TYPE
- pkix_ClassTable_Entry *ctEntry = NULL;
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&firstObjectHeader->type,
- firstObjectHeader->type,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
-
- if (pkixErrorResult){
- PKIX_ERROR_FATAL(PKIX_ERRORGETTINGCLASSTABLEENTRY);
- }
-
- if ((ctEntry == NULL) || (ctEntry->equalsFunction == NULL)) {
- PKIX_ERROR_FATAL(PKIX_UNDEFINEDCALLBACK);
- } else {
- func = ctEntry->equalsFunction;
- }
-#else
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- } else {
- entry = systemClasses[objType];
- func = entry.equalsFunction;
- if (func == NULL){
- func = pkix_pl_Object_Equals_Default;
- }
- }
-
- PKIX_CHECK(func(firstObject, secondObject, pResult, plContext),
- PKIX_OBJECTSPECIFICFUNCTIONFAILED);
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Object_Duplicate (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_Duplicate(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object **pNewObject,
- void *plContext)
-{
- PKIX_PL_Object *firstObjectHeader = NULL;
- PKIX_PL_DuplicateCallback func = NULL;
- pkix_ClassTable_Entry entry;
- PKIX_UInt32 objType;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_Duplicate");
- PKIX_NULLCHECK_TWO(firstObject, pNewObject);
-
- PKIX_CHECK(pkix_pl_Object_GetHeader
- (firstObject, &firstObjectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- objType = firstObjectHeader->type;
-
- if (objType >= PKIX_NUMTYPES) {
-#ifdef PKIX_USER_OBJECT_TYPE
- pkix_ClassTable_Entry *ctEntry = NULL;
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
-
- if (pkixErrorResult){
- PKIX_ERROR_FATAL(PKIX_ERRORGETTINGCLASSTABLEENTRY);
- }
-
- if ((ctEntry == NULL) || (ctEntry->duplicateFunction == NULL)) {
- PKIX_ERROR_FATAL(PKIX_UNDEFINEDCALLBACK);
- } else {
- func = ctEntry->duplicateFunction;
- }
-#else
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- } else {
- entry = systemClasses[objType];
- func = entry.duplicateFunction;
- if (!func){
- PKIX_ERROR_FATAL(PKIX_UNDEFINEDDUPLICATEFUNCTION);
- }
- }
-
- PKIX_CHECK(func(firstObject, pNewObject, plContext),
- PKIX_OBJECTSPECIFICFUNCTIONFAILED);
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Object_Hashcode (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pValue,
- void *plContext)
-{
- PKIX_PL_Object *objectHeader = NULL;
- PKIX_PL_HashcodeCallback func = NULL;
- pkix_ClassTable_Entry entry;
- PKIX_UInt32 objectHash;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_Hashcode");
- PKIX_NULLCHECK_TWO(object, pValue);
-
- /* Shift pointer from user data to object header */
- PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- /* if we don't have a cached copy from before, we create one */
- if (!objectHeader->hashcodeCached){
-
- PKIX_UInt32 objType = objectHeader->type;
-
- /* first, special handling for system types */
- if (objType >= PKIX_NUMTYPES){
-#ifdef PKIX_USER_OBJECT_TYPE
- pkix_ClassTable_Entry *ctEntry = NULL;
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
-
- if (pkixErrorResult){
- PKIX_ERROR_FATAL
- (PKIX_ERRORGETTINGCLASSTABLEENTRY);
- }
-
- if ((ctEntry == NULL) ||
- (ctEntry->hashcodeFunction == NULL)) {
- PKIX_ERROR_FATAL(PKIX_UNDEFINEDCALLBACK);
- }
-
- func = ctEntry->hashcodeFunction;
-#else
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- } else {
- entry = systemClasses[objType];
- func = entry.hashcodeFunction;
- if (func == NULL){
- func = pkix_pl_Object_Hashcode_Default;
- }
- }
-
- PKIX_CHECK(func(object, &objectHash, plContext),
- PKIX_OBJECTSPECIFICFUNCTIONFAILED);
-
- if (!objectHeader->hashcodeCached){
-
- PKIX_CHECK(pkix_LockObject(object, plContext),
- PKIX_ERRORLOCKINGOBJECT);
-
- if (!objectHeader->hashcodeCached){
- /* save cached copy in case we need it again */
- objectHeader->hashcode = objectHash;
- objectHeader->hashcodeCached = PKIX_TRUE;
- }
-
- PKIX_CHECK(pkix_UnlockObject(object, plContext),
- PKIX_ERRORUNLOCKINGOBJECT);
- }
- }
-
- *pValue = objectHeader->hashcode;
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Object_ToString (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_Object *objectHeader = NULL;
- PKIX_PL_ToStringCallback func = NULL;
- pkix_ClassTable_Entry entry;
- PKIX_PL_String *objectString = NULL;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- /* Shift pointer from user data to object header */
- PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- /* if we don't have a cached copy from before, we create one */
- if (!objectHeader->stringRep){
-
- PKIX_UInt32 objType = objectHeader->type;
-
- if (objType >= PKIX_NUMTYPES){
-#ifdef PKIX_USER_OBJECT_TYPE
- pkix_ClassTable_Entry *ctEntry = NULL;
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
- if (pkixErrorResult){
- PKIX_ERROR_FATAL
- (PKIX_ERRORGETTINGCLASSTABLEENTRY);
- }
-
- if ((ctEntry == NULL) ||
- (ctEntry->toStringFunction == NULL)) {
- PKIX_ERROR_FATAL(PKIX_UNDEFINEDCALLBACK);
- }
-
- func = ctEntry->toStringFunction;
-#else
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- } else {
- entry = systemClasses[objType];
- func = entry.toStringFunction;
- if (func == NULL){
- func = pkix_pl_Object_ToString_Default;
- }
- }
-
- PKIX_CHECK(func(object, &objectString, plContext),
- PKIX_OBJECTSPECIFICFUNCTIONFAILED);
-
- if (!objectHeader->stringRep){
-
- PKIX_CHECK(pkix_LockObject(object, plContext),
- PKIX_ERRORLOCKINGOBJECT);
-
- if (!objectHeader->stringRep){
- /* save a cached copy */
- objectHeader->stringRep = objectString;
- objectString = NULL;
- }
-
- PKIX_CHECK(pkix_UnlockObject(object, plContext),
- PKIX_ERRORUNLOCKINGOBJECT);
- }
- }
-
-
- *pString = objectHeader->stringRep;
- objectHeader->stringRep = NULL;
-
-cleanup:
- if (objectHeader) {
- PKIX_DECREF(objectHeader->stringRep);
- }
- PKIX_DECREF(objectString);
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Object_InvalidateCache (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_InvalidateCache(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_Object *objectHeader = NULL;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_InvalidateCache");
- PKIX_NULLCHECK_ONE(object);
-
- /* Shift pointer from user data to object header */
- PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- PKIX_CHECK(pkix_LockObject(object, plContext),
- PKIX_ERRORLOCKINGOBJECT);
-
- /* invalidate hashcode */
- objectHeader->hashcode = 0;
- objectHeader->hashcodeCached = PKIX_FALSE;
-
- PKIX_DECREF(objectHeader->stringRep);
-
- PKIX_CHECK(pkix_UnlockObject(object, plContext),
- PKIX_ERRORUNLOCKINGOBJECT);
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Object_Compare (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_Compare(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PKIX_PL_Object *firstObjectHeader = NULL;
- PKIX_PL_Object *secondObjectHeader = NULL;
- PKIX_PL_ComparatorCallback func = NULL;
- pkix_ClassTable_Entry entry;
- PKIX_UInt32 objType;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_Compare");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* Shift pointer from user data to object header */
- PKIX_CHECK(pkix_pl_Object_GetHeader
- (firstObject, &firstObjectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- /* Shift pointer from user data to object header */
- PKIX_CHECK(pkix_pl_Object_GetHeader
- (secondObject, &secondObjectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- objType = firstObjectHeader->type;
-
- if (objType >= PKIX_NUMTYPES){
-#ifdef PKIX_USER_OBJECT_TYPE
- pkix_ClassTable_Entry *ctEntry = NULL;
-
- PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
- PR_Lock(classTableLock);
- pkixErrorResult = pkix_pl_PrimHashTable_Lookup
- (classTable,
- (void *)&objType,
- objType,
- NULL,
- (void **)&ctEntry,
- plContext);
- PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
- PR_Unlock(classTableLock);
- if (pkixErrorResult){
- PKIX_ERROR_FATAL(PKIX_ERRORGETTINGCLASSTABLEENTRY);
- }
-
- if ((ctEntry == NULL) || (ctEntry->comparator == NULL)) {
- PKIX_ERROR_FATAL(PKIX_UNDEFINEDCOMPARATOR);
- }
-
- func = ctEntry->comparator;
-#else
- PORT_Assert (0);
- pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
- pkixErrorClass = PKIX_FATAL_ERROR;
- goto cleanup;
-#endif /* PKIX_USER_OBJECT_TYPE */
- } else {
- /* special handling for system types */
- entry = systemClasses[objType];
- func = entry.comparator;
- if (!func){
- PKIX_ERROR(PKIX_UNDEFINEDCOMPARATOR);
- }
- }
-
- PKIX_CHECK(func(firstObject, secondObject, pResult, plContext),
- PKIX_OBJECTSPECIFICFUNCTIONFAILED);
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Object_Lock (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_Lock(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_Lock");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_LockObject(object, plContext),
- PKIX_LOCKOBJECTFAILED);
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-/*
- * FUNCTION: PKIX_PL_Object_Unlock (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_Unlock(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_Unlock");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_UnlockObject(object, plContext),
- PKIX_UNLOCKOBJECTFAILED);
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
-
-
-/*
- * FUNCTION: PKIX_PL_Object_GetType (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Object_GetType(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pType,
- void *plContext)
-{
- PKIX_PL_Object *objectHeader = NULL;
-
- PKIX_ENTER(OBJECT, "PKIX_PL_Object_GetType");
- PKIX_NULLCHECK_TWO(object, pType);
-
- /* Shift pointer from user data to object header */
- PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
- PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
-
- *pType = objectHeader->type;
-
-cleanup:
-
- PKIX_RETURN(OBJECT);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.h
deleted file mode 100755
index 0133c43ee..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_object.h
- *
- * Object Construction, Destruction and Callback Definitions
- *
- */
-
-#ifndef _PKIX_PL_OBJECT_H
-#define _PKIX_PL_OBJECT_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Object Implementation Notes:
- *
- * Allocating a new object creates an object header and a block of
- * uninitialized user data. A pointer to this uninitialized data is
- * returned to the user. The structure looks as follows:
- *
- * +--------------------+
- * | MAGIC HEADER |
- * | (object header) |
- * +--------------------+
- * | user data | -- pointer returned from PKIX_PL_Object_Alloc
- * +--------------------+
- *
- * Object operations receive a pointer to raw user data as an argument.
- * The macro HEADER(object) returns a pointer to the object header.
- * An assertion then verifies that the first field is the MAGIC_HEADER.
- */
-
-/* PKIX_PL_Object Structure Definition */
-struct PKIX_PL_ObjectStruct {
- PRUint64 magicHeader;
- PKIX_UInt32 type;
- PKIX_Int32 references;
- PRLock *lock;
- PKIX_PL_String *stringRep;
- PKIX_UInt32 hashcode;
- PKIX_Boolean hashcodeCached;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_Object_RetrieveEqualsCallback(
- PKIX_PL_Object *object,
- PKIX_PL_EqualsCallback *equalsCallback,
- void *plContext);
-
-extern PKIX_Boolean initializing;
-extern PKIX_Boolean initialized;
-
-#ifdef PKIX_USER_OBJECT_TYPE
-
-extern PRLock *classTableLock;
-
-#endif
-
-extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
-
-PKIX_Error *
-pkix_pl_Object_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_OBJECT_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.c
deleted file mode 100755
index e628c0256..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_oid.c
- *
- * OID Object Functions
- *
- */
-
-#include "pkix_pl_oid.h"
-
-/* --Private-OID-Functions---------------------------------------- */
-
- /*
- * FUNCTION: pkix_pl_OID_Comparator
- * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OID_Comparator(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Int32 *pRes,
- void *plContext)
-{
- PKIX_PL_OID *firstOID = NULL;
- PKIX_PL_OID *secondOID = NULL;
-
- PKIX_ENTER(OID, "pkix_pl_OID_Comparator");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pRes);
-
- PKIX_CHECK(pkix_CheckTypes
- (firstObject, secondObject, PKIX_OID_TYPE, plContext),
- PKIX_ARGUMENTSNOTOIDS);
-
- firstOID = (PKIX_PL_OID*)firstObject;
- secondOID = (PKIX_PL_OID*)secondObject;
-
- *pRes = (PKIX_Int32)SECITEM_CompareItem(&firstOID->derOid,
- &secondOID->derOid);
-cleanup:
- PKIX_RETURN(OID);
-}
-
-/*
- * FUNCTION: pkix_pl_OID_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OID_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_OID *oid = NULL;
-
- PKIX_ENTER(OID, "pkix_pl_OID_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_OID_TYPE, plContext),
- PKIX_OBJECTNOTANOID);
- oid = (PKIX_PL_OID*)object;
- SECITEM_FreeItem(&oid->derOid, PR_FALSE);
-
-cleanup:
- PKIX_RETURN(OID);
-}
-
-/*
- * FUNCTION: pkix_pl_OID_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OID_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_OID *oid = NULL;
-
- PKIX_ENTER(OID, "pkix_pl_OID_HashCode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_OID_TYPE, plContext),
- PKIX_OBJECTNOTANOID);
-
- oid = (PKIX_PL_OID *)object;
-
- PKIX_CHECK(pkix_hash
- ((unsigned char *)oid->derOid.data,
- oid->derOid.len * sizeof (char),
- pHashcode,
- plContext),
- PKIX_HASHFAILED);
-cleanup:
-
- PKIX_RETURN(OID);
-}
-
-/*
- * FUNCTION: pkix_pl_OID_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_OID_Equals(
- PKIX_PL_Object *first,
- PKIX_PL_Object *second,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- SECComparison cmpResult;
-
- PKIX_ENTER(OID, "pkix_pl_OID_Equals");
- PKIX_NULLCHECK_THREE(first, second, pResult);
-
- PKIX_CHECK(pkix_CheckType(first, PKIX_OID_TYPE, plContext),
- PKIX_FIRSTARGUMENTNOTANOID);
-
- PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- *pResult = PKIX_FALSE;
-
- /*
- * Do a quick check that the second object is an OID.
- * If so, check that their lengths are equal.
- */
- if (secondType != PKIX_OID_TYPE) {
- goto cleanup;
- }
-
- PKIX_CHECK(pkix_pl_OID_Comparator
- (first, second, &cmpResult, plContext),
- PKIX_OIDCOMPARATORFAILED);
-
- *pResult = (cmpResult == SECEqual);
-cleanup:
-
- PKIX_RETURN(OID);
-}
-
-/*
- * FUNCTION: pkix_pl_OID_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- * Use this function only for printing OIDs and not to make any
- * critical security decision.
- */
-static PKIX_Error *
-pkix_pl_OID_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_OID *oid = NULL;
- char *oidString = NULL;
-
- PKIX_ENTER(OID, "pkix_pl_OID_toString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_OID_TYPE, plContext),
- PKIX_OBJECTNOTANOID);
- oid = (PKIX_PL_OID*)object;
- oidString = CERT_GetOidString(&oid->derOid);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, oidString , 0, pString, plContext),
- PKIX_STRINGCREATEFAILED);
-cleanup:
- PR_smprintf_free(oidString);
-
- PKIX_RETURN(OID);
-}
-
-/*
- * FUNCTION: pkix_pl_OID_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_OID_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_OID_RegisterSelf(
- void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry *entry = &systemClasses[PKIX_OID_TYPE];
-
- PKIX_ENTER(OID, "pkix_pl_OID_RegisterSelf");
-
- entry->description = "OID";
- entry->typeObjectSize = sizeof(PKIX_PL_OID);
- entry->destructor = pkix_pl_OID_Destroy;
- entry->equalsFunction = pkix_pl_OID_Equals;
- entry->hashcodeFunction = pkix_pl_OID_Hashcode;
- entry->toStringFunction = pkix_pl_OID_ToString;
- entry->comparator = pkix_pl_OID_Comparator;
- entry->duplicateFunction = pkix_duplicateImmutable;
-
- PKIX_RETURN(OID);
-}
-
-/*
- * FUNCTION: pkix_pl_OID_GetCriticalExtensionOIDs
- * DESCRIPTION:
- *
- * Converts the extensions in "extensions" array that are critical to
- * PKIX_PL_OID and returns the result as a PKIX_List in "pPidList".
- * If there is no critical extension, an empty list is returned.
- *
- * PARAMETERS
- * "extension"
- * an array of extension pointers. May be NULL.
- * "pOidsList"
- * Address where the list of OIDs is returned. Must be non-NULL.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a CRL Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_OID_GetCriticalExtensionOIDs(
- CERTCertExtension **extensions,
- PKIX_List **pOidsList,
- void *plContext)
-{
- PKIX_List *oidsList = NULL;
- PKIX_PL_OID *pkixOID = NULL;
-
- PKIX_ENTER(OID, "pkix_pl_OID_GetCriticalExtensionOIDs");
- PKIX_NULLCHECK_ONE(pOidsList);
-
- PKIX_CHECK(PKIX_List_Create(&oidsList, plContext),
- PKIX_LISTCREATEFAILED);
-
- if (extensions) {
- while (*extensions) {
- CERTCertExtension *extension = NULL;
- SECItem *critical = NULL;
- SECItem *oid = NULL;
-
- extension = *extensions++;
- /* extension is critical ? */
- critical = &extension->critical;
- if (critical->len == 0 || critical->data[0] == 0) {
- continue;
- }
- oid = &extension->id;
- PKIX_CHECK(
- PKIX_PL_OID_CreateBySECItem(oid, &pkixOID, plContext),
- PKIX_OIDCREATEFAILED);
- PKIX_CHECK(
- PKIX_List_AppendItem(oidsList, (PKIX_PL_Object *)pkixOID,
- plContext),
- PKIX_LISTAPPENDITEMFAILED);
- PKIX_DECREF(pkixOID);
- }
- }
-
- *pOidsList = oidsList;
- oidsList = NULL;
-
-cleanup:
- PKIX_DECREF(oidsList);
- PKIX_DECREF(pkixOID);
- PKIX_RETURN(OID);
-}
-
-/* --Public-Functions------------------------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_OID_CreateBySECItem (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_OID_CreateBySECItem(
- SECItem *derOid,
- PKIX_PL_OID **pOID,
- void *plContext)
-{
- PKIX_PL_OID *oid = NULL;
- SECStatus rv;
-
- PKIX_ENTER(OID, "PKIX_PL_OID_CreateBySECItem");
- PKIX_NULLCHECK_TWO(pOID, derOid);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_OID_TYPE,
- sizeof (PKIX_PL_OID),
- (PKIX_PL_Object **)&oid,
- plContext),
- PKIX_COULDNOTCREATEOBJECT);
- rv = SECITEM_CopyItem(NULL, &oid->derOid, derOid);
- if (rv != SECSuccess) {
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
- *pOID = oid;
- oid = NULL;
-
-cleanup:
- PKIX_DECREF(oid);
-
- PKIX_RETURN(OID);
-}
-
-/*
- * FUNCTION: PKIX_PL_OID_Create (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_OID_Create(
- SECOidTag idtag,
- PKIX_PL_OID **pOID,
- void *plContext)
-{
- SECOidData *oidData = NULL;
-
- PKIX_ENTER(OID, "PKIX_PL_OID_Create");
- PKIX_NULLCHECK_ONE(pOID);
-
- oidData = SECOID_FindOIDByTag((SECOidTag)idtag);
- if (!oidData) {
- PKIX_ERROR(PKIX_SECOIDFINDOIDTAGDESCRIPTIONFAILED);
- }
-
- pkixErrorResult =
- PKIX_PL_OID_CreateBySECItem(&oidData->oid, pOID, plContext);
-cleanup:
- PKIX_RETURN(OID);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.h
deleted file mode 100755
index 0229194d8..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_oid.h
- *
- * OID Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_OID_H
-#define _PKIX_PL_OID_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_OIDStruct {
- SECItem derOid;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_OID_RegisterSelf(void *plContext);
-
-PKIX_Error *
-pkix_pl_OID_GetCriticalExtensionOIDs(
- CERTCertExtension **extensions,
- PKIX_List **pOidsList,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_OID_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.c
deleted file mode 100755
index c920533d3..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.c
+++ /dev/null
@@ -1,584 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_primhash.c
- *
- * Primitive (non-object) Hashtable Functions
- *
- */
-
-#include "pkix_pl_primhash.h"
-
-/* --Private-Functions---------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_KeyComparator_Default
- * DESCRIPTION:
- *
- * Compares the integer pointed to by "firstKey" with the integer pointed to
- * by "secondKey" for equality and stores the Boolean result at "pResult".
- * This default key comparator assumes each key is a PKIX_UInt32, and it
- * simply tests them for equality.
- *
- * PARAMETERS:
- * "firstKey"
- * Address of the first integer key to compare. Must be non-NULL.
- * The EqualsCallback for this Object will be called.
- * "secondKey"
- * Address of the second integer key to compare. Must be non-NULL.
- * "pResult"
- * Address where Boolean will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-static PKIX_Error *
-pkix_pl_KeyComparator_Default(
- PKIX_UInt32 *firstKey,
- PKIX_UInt32 *secondKey,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- /* Assume both keys are pointers to PKIX_UInt32 */
- PKIX_UInt32 firstInt, secondInt;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_KeyComparator_Default");
- PKIX_NULLCHECK_THREE(firstKey, secondKey, pResult);
-
- firstInt = *firstKey;
- secondInt = *secondKey;
-
- *pResult = (firstInt == secondInt)?PKIX_TRUE:PKIX_FALSE;
-
- PKIX_RETURN(HASHTABLE);
-}
-
-
-/*
- * FUNCTION: pkix_pl_PrimHashTable_Create
- * DESCRIPTION:
- *
- * Creates a new PrimHashtable object with a number of buckets equal to
- * "numBuckets" and stores the result at "pResult".
- *
- * PARAMETERS:
- * "numBuckets"
- * The number of hash table buckets. Must be non-zero.
- * "pResult"
- * Address where PrimHashTable pointer will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_PrimHashTable_Create(
- PKIX_UInt32 numBuckets,
- pkix_pl_PrimHashTable **pResult,
- void *plContext)
-{
- pkix_pl_PrimHashTable *primHashTable = NULL;
- PKIX_UInt32 i;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Create");
- PKIX_NULLCHECK_ONE(pResult);
-
- if (numBuckets == 0) {
- PKIX_ERROR(PKIX_NUMBUCKETSEQUALSZERO);
- }
-
- /* Allocate a new hashtable */
- PKIX_CHECK(PKIX_PL_Malloc
- (sizeof (pkix_pl_PrimHashTable),
- (void **)&primHashTable,
- plContext),
- PKIX_MALLOCFAILED);
-
- primHashTable->size = numBuckets;
-
- /* Allocate space for the buckets */
- PKIX_CHECK(PKIX_PL_Malloc
- (numBuckets * sizeof (pkix_pl_HT_Elem*),
- (void **)&primHashTable->buckets,
- plContext),
- PKIX_MALLOCFAILED);
-
- for (i = 0; i < numBuckets; i++) {
- primHashTable->buckets[i] = NULL;
- }
-
- *pResult = primHashTable;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_FREE(primHashTable);
- }
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/*
- * FUNCTION: pkix_pl_PrimHashTable_Add
- * DESCRIPTION:
- *
- * Adds the value pointed to by "value" to the PrimHashTable pointed to by
- * "ht" using the key pointed to by "key" and the hashCode value equal to
- * "hashCode", using the function pointed to by "keyComp" to compare keys.
- * Assumes the key is either a PKIX_UInt32 or a PKIX_PL_Object. If the value
- * already exists in the hashtable, this function returns a non-fatal error.
- *
- * PARAMETERS:
- * "ht"
- * Address of PrimHashtable to insert into. Must be non-NULL.
- * "key"
- * Address of key. Typically a PKIX_UInt32 or PKIX_PL_Object.
- * Must be non-NULL.
- * "value"
- * Address of Object to be added to PrimHashtable. Must be non-NULL.
- * "hashCode"
- * Hashcode value of the key.
- * "keyComp"
- * Address of function used to determine if two keys are equal.
- * If NULL, pkix_pl_KeyComparator_Default is used.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "ht"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HashTable Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_PrimHashTable_Add(
- pkix_pl_PrimHashTable *ht,
- void *key,
- void *value,
- PKIX_UInt32 hashCode,
- PKIX_PL_EqualsCallback keyComp,
- void *plContext)
-{
- pkix_pl_HT_Elem **elemPtr = NULL;
- pkix_pl_HT_Elem *element = NULL;
- PKIX_Boolean compResult = PKIX_FALSE;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Add");
- PKIX_NULLCHECK_THREE(ht, key, value);
-
- for (elemPtr = &((ht->buckets)[hashCode%ht->size]), element = *elemPtr;
- element != NULL; elemPtr = &(element->next), element = *elemPtr) {
-
- if (element->hashCode != hashCode){
- /* no possibility of a match */
- continue;
- }
-
- if (keyComp == NULL){
- PKIX_CHECK(pkix_pl_KeyComparator_Default
- ((PKIX_UInt32 *)key,
- (PKIX_UInt32 *)(element->key),
- &compResult,
- plContext),
- PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
- } else {
- PKIX_CHECK(keyComp
- ((PKIX_PL_Object *)key,
- (PKIX_PL_Object *)(element->key),
- &compResult,
- plContext),
- PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
- }
-
- if ((element->hashCode == hashCode) &&
- (compResult == PKIX_TRUE)){
- /* Same key already exists in the table */
- PKIX_ERROR(PKIX_ATTEMPTTOADDDUPLICATEKEY);
- }
- }
-
- /* Next Element should be NULL at this point */
- if (element != NULL) {
- PKIX_ERROR(PKIX_ERRORTRAVERSINGBUCKET);
- }
-
- /* Create a new HT_Elem */
- PKIX_CHECK(PKIX_PL_Malloc
- (sizeof (pkix_pl_HT_Elem), (void **)elemPtr, plContext),
- PKIX_MALLOCFAILED);
-
- element = *elemPtr;
-
- element->key = key;
- element->value = value;
- element->hashCode = hashCode;
- element->next = NULL;
-
-cleanup:
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/*
- * FUNCTION: pkix_pl_PrimHashTable_Remove
- * DESCRIPTION:
- *
- * Removes any objects with the key pointed to by "key" and hashCode value
- * equal to "hashCode" from the PrimHashtable pointed to by "ht", using the
- * function pointed to by "keyComp" to compare keys, and stores the object's
- * value at "pResult". Assumes "key" is a PKIX_UInt32 or a PKIX_PL_Object.
- * This function sets "pResult" to NULL if the key is not in the hashtable.
- *
- * PARAMETERS:
- * "ht"
- * Address of PrimHashtable to remove object. Must be non-NULL.
- * "key"
- * Address of key for lookup. Typically a PKIX_UInt32 or PKIX_PL_Object.
- * Must be non-NULL.
- * "value"
- * Address of Object to be added to PrimHashtable. Must be non-NULL.
- * "hashCode"
- * Hashcode value of the key.
- * "keyComp"
- * Address of function used to determine if two keys are equal.
- * If NULL, pkix_pl_KeyComparator_Default is used.
- * "pResult"
- * Address where value will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "ht"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HashTable Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_PrimHashTable_Remove(
- pkix_pl_PrimHashTable *ht,
- void *key,
- PKIX_UInt32 hashCode,
- PKIX_PL_EqualsCallback keyComp,
- void **pKey,
- void **pValue,
- void *plContext)
-{
- pkix_pl_HT_Elem *element = NULL;
- pkix_pl_HT_Elem *prior = NULL;
- PKIX_Boolean compResult;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Remove");
- PKIX_NULLCHECK_FOUR(ht, key, pKey, pValue);
-
- *pKey = NULL;
- *pValue = NULL;
-
- for (element = ht->buckets[hashCode%ht->size], prior = element;
- (element != NULL);
- prior = element, element = element->next) {
-
- if (element->hashCode != hashCode){
- /* no possibility of a match */
- continue;
- }
-
- if (keyComp == NULL){
- PKIX_CHECK(pkix_pl_KeyComparator_Default
- ((PKIX_UInt32 *)key,
- (PKIX_UInt32 *)(element->key),
- &compResult,
- plContext),
- PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
- } else {
- PKIX_CHECK(keyComp
- ((PKIX_PL_Object *)key,
- (PKIX_PL_Object *)(element->key),
- &compResult,
- plContext),
- PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
- }
-
- if ((element->hashCode == hashCode) &&
- (compResult == PKIX_TRUE)){
- if (element != prior) {
- prior->next = element->next;
- } else {
- ht->buckets[hashCode%ht->size] = element->next;
- }
- *pKey = element->key;
- *pValue = element->value;
- element->key = NULL;
- element->value = NULL;
- element->next = NULL;
- PKIX_FREE(element);
- goto cleanup;
- }
- }
-
-cleanup:
-
- PKIX_RETURN(HASHTABLE);
-}
-
-
-/*
- * FUNCTION: pkix_pl_HashTableLookup
- * DESCRIPTION:
- *
- * Looks up object using the key pointed to by "key" and hashCode value
- * equal to "hashCode" from the PrimHashtable pointed to by "ht", using the
- * function pointed to by "keyComp" to compare keys, and stores the object's
- * value at "pResult". Assumes "key" is a PKIX_UInt32 or a PKIX_PL_Object.
- * This function sets "pResult" to NULL if the key is not in the hashtable.
- *
- * PARAMETERS:
- * "ht"
- * Address of PrimHashtable to lookup object from. Must be non-NULL.
- * "key"
- * Address of key for lookup. Typically a PKIX_UInt32 or PKIX_PL_Object.
- * Must be non-NULL.
- * "keyComp"
- * Address of function used to determine if two keys are equal.
- * If NULL, pkix_pl_KeyComparator_Default is used.
- * "hashCode"
- * Hashcode value of the key.
- * "pResult"
- * Address where value will be stored. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Conditionally Thread Safe
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_PrimHashTable_Lookup(
- pkix_pl_PrimHashTable *ht,
- void *key,
- PKIX_UInt32 hashCode,
- PKIX_PL_EqualsCallback keyComp,
- void **pResult,
- void *plContext)
-{
- pkix_pl_HT_Elem *element = NULL;
- PKIX_Boolean compResult = PKIX_FALSE;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Lookup");
- PKIX_NULLCHECK_THREE(ht, key, pResult);
-
- *pResult = NULL;
-
- for (element = (ht->buckets)[hashCode%ht->size];
- (element != NULL) && (*pResult == NULL);
- element = element->next) {
-
- if (element->hashCode != hashCode){
- /* no possibility of a match */
- continue;
- }
-
- if (keyComp == NULL){
- PKIX_CHECK(pkix_pl_KeyComparator_Default
- ((PKIX_UInt32 *)key,
- (PKIX_UInt32 *)(element->key),
- &compResult,
- plContext),
- PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
- } else {
- pkixErrorResult =
- keyComp((PKIX_PL_Object *)key,
- (PKIX_PL_Object *)(element->key),
- &compResult,
- plContext);
- if (pkixErrorResult) {
- pkixErrorClass = PKIX_FATAL_ERROR;
- pkixErrorCode = PKIX_COULDNOTTESTWHETHERKEYSEQUAL;
- goto cleanup;
- }
- }
-
- if ((element->hashCode == hashCode) &&
- (compResult == PKIX_TRUE)){
- *pResult = element->value;
- goto cleanup;
- }
- }
-
- /* if we've reached here, specified key doesn't exist in hashtable */
- *pResult = NULL;
-
-cleanup:
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/*
- * FUNCTION: pkix_pl_PrimHashTable_Destroy
- *
- * Destroys PrimHashTable pointed to by "ht".
- *
- * PARAMETERS:
- * "ht"
- * Address of PrimHashtable to free. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "ht"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS
- * Returns NULL if the function succeeds.
- * Returns a HashTable Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_PrimHashTable_Destroy(
- pkix_pl_PrimHashTable *ht,
- void *plContext)
-{
- pkix_pl_HT_Elem *element = NULL;
- pkix_pl_HT_Elem *temp = NULL;
- PKIX_UInt32 i;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Destroy");
- PKIX_NULLCHECK_ONE(ht);
-
- /* Free each element (list) */
- for (i = 0; i < ht->size; i++) {
- for (element = ht->buckets[i];
- element != NULL;
- element = temp) {
- temp = element->next;
- element->value = NULL;
- element->key = NULL;
- element->hashCode = 0;
- element->next = NULL;
- PKIX_FREE(element);
- }
- }
-
- /* Free the pointer to the list array */
- PKIX_FREE(ht->buckets);
- ht->size = 0;
-
- /* Free the table itself */
- PKIX_FREE(ht);
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/*
- * FUNCTION: pkix_pl_PrimHashTable_GetBucketSize
- * DESCRIPTION:
- *
- * Retruns number of entries in the bucket the "hashCode" is designated in
- * the hashtable "ht" in the address "pBucketSize".
- *
- * PARAMETERS:
- * "ht"
- * Address of PrimHashtable to get entries count. Must be non-NULL.
- * "hashCode"
- * Hashcode value of the key.
- * "pBucketSize"
- * Address that an PKIX_UInt32 is returned for number of entries in the
- * bucket associated with the hashCode. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "ht"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HashTable Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_PrimHashTable_GetBucketSize(
- pkix_pl_PrimHashTable *ht,
- PKIX_UInt32 hashCode,
- PKIX_UInt32 *pBucketSize,
- void *plContext)
-{
- pkix_pl_HT_Elem **elemPtr = NULL;
- pkix_pl_HT_Elem *element = NULL;
- PKIX_UInt32 bucketSize = 0;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_GetBucketSize");
- PKIX_NULLCHECK_TWO(ht, pBucketSize);
-
- for (elemPtr = &((ht->buckets)[hashCode%ht->size]), element = *elemPtr;
- element != NULL; elemPtr = &(element->next), element = *elemPtr) {
- bucketSize++;
- }
-
- *pBucketSize = bucketSize;
-
- PKIX_RETURN(HASHTABLE);
-}
-
-/*
- * FUNCTION: pkix_pl_PrimHashTable_RemoveFIFO
- * DESCRIPTION:
- *
- * Remove the first entry in the bucket the "hashCode" is designated in
- * the hashtable "ht". Since new entry is added at end of the link list
- * the first one is the oldest (FI) therefore removed first (FO).
- *
- * PARAMETERS:
- * "ht"
- * Address of PrimHashtable to get entries count. Must be non-NULL.
- * "hashCode"
- * Hashcode value of the key.
- * "pKey"
- * Address of key of the entry deleted. Must be non-NULL.
- * "pValue"
- * Address of Value of the entry deleted. Must be non-NULL.
- * "plContext"
- * Platform-specific context pointer.
- * THREAD SAFETY:
- * Not Thread Safe - assumes exclusive access to "ht"
- * (see Thread Safety Definitions in Programmer's Guide)
- * RETURNS:
- * Returns NULL if the function succeeds.
- * Returns a HashTable Error if the function fails in a non-fatal way.
- * Returns a Fatal Error if the function fails in an unrecoverable way.
- */
-PKIX_Error *
-pkix_pl_PrimHashTable_RemoveFIFO(
- pkix_pl_PrimHashTable *ht,
- PKIX_UInt32 hashCode,
- void **pKey,
- void **pValue,
- void *plContext)
-{
- pkix_pl_HT_Elem *element = NULL;
-
- PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Remove");
- PKIX_NULLCHECK_THREE(ht, pKey, pValue);
-
- element = (ht->buckets)[hashCode%ht->size];
-
- if (element != NULL) {
-
- *pKey = element->key;
- *pValue = element->value;
- ht->buckets[hashCode%ht->size] = element->next;
- element->key = NULL;
- element->value = NULL;
- element->next = NULL;
- PKIX_FREE(element);
- }
-
- PKIX_RETURN(HASHTABLE);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.h
deleted file mode 100755
index b889e2e91..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_primhash.h
- *
- * Primitive Hashtable Definition
- *
- */
-
-#ifndef _PKIX_PL_PRIMHASH_H
-#define _PKIX_PL_PRIMHASH_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct pkix_pl_HT_Elem pkix_pl_HT_Elem;
-
-typedef struct pkix_pl_PrimHashTable pkix_pl_PrimHashTable;
-
-typedef struct pkix_pl_Integer pkix_pl_Integer;
-
-struct pkix_pl_Integer{
- PKIX_UInt32 ht_int;
-};
-
-struct pkix_pl_HT_Elem {
- void *key;
- void *value;
- PKIX_UInt32 hashCode;
- pkix_pl_HT_Elem *next;
-};
-
-struct pkix_pl_PrimHashTable {
- pkix_pl_HT_Elem **buckets;
- PKIX_UInt32 size;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_PrimHashTable_Create(
- PKIX_UInt32 numBuckets,
- pkix_pl_PrimHashTable **pResult,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_PrimHashTable_Add(
- pkix_pl_PrimHashTable *ht,
- void *key,
- void *value,
- PKIX_UInt32 hashCode,
- PKIX_PL_EqualsCallback keyComp,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_PrimHashTable_Remove(
- pkix_pl_PrimHashTable *ht,
- void *key,
- PKIX_UInt32 hashCode,
- PKIX_PL_EqualsCallback keyComp,
- void **pKey,
- void **pValue,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_PrimHashTable_Lookup(
- pkix_pl_PrimHashTable *ht,
- void *key,
- PKIX_UInt32 hashCode,
- PKIX_PL_EqualsCallback keyComp,
- void **pResult,
- void *plContext);
-
-PKIX_Error*
-pkix_pl_PrimHashTable_Destroy(
- pkix_pl_PrimHashTable *ht,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_PrimHashTable_GetBucketSize(
- pkix_pl_PrimHashTable *ht,
- PKIX_UInt32 hashCode,
- PKIX_UInt32 *pBucketSize,
- void *plContext);
-
-PKIX_Error *
-pkix_pl_PrimHashTable_RemoveFIFO(
- pkix_pl_PrimHashTable *ht,
- PKIX_UInt32 hashCode,
- void **pKey,
- void **pValue,
- void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_PRIMHASH_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.c
deleted file mode 100755
index 662931e98..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_rwlock.c
- *
- * Read/Write Lock Functions
- *
- */
-
-#include "pkix_pl_rwlock.h"
-
-/* --Private-Functions-------------------------------------------- */
-
-static PKIX_Error *
-pkix_pl_RWLock_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_RWLock* rwlock = NULL;
-
- PKIX_ENTER(RWLOCK, "pkix_pl_RWLock_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_RWLOCK_TYPE, plContext),
- PKIX_OBJECTNOTRWLOCK);
-
- rwlock = (PKIX_PL_RWLock*) object;
-
- PKIX_RWLOCK_DEBUG("Calling PR_DestroyRWLock)\n");
- PR_DestroyRWLock(rwlock->lock);
- rwlock->lock = NULL;
-
-cleanup:
-
- PKIX_RETURN(RWLOCK);
-}
-
-/*
- * FUNCTION: pkix_pl_RWLock_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_RWLOCK_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_RWLock_RegisterSelf(
- void *plContext)
-{
-
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(RWLOCK, "pkix_pl_RWLock_RegisterSelf");
-
- entry.description = "RWLock";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_RWLock);
- entry.destructor = pkix_pl_RWLock_Destroy;
- entry.equalsFunction = NULL;
- entry.hashcodeFunction = NULL;
- entry.toStringFunction = NULL;
- entry.comparator = NULL;
- entry.duplicateFunction = NULL;
-
- systemClasses[PKIX_RWLOCK_TYPE] = entry;
-
- PKIX_RETURN(RWLOCK);
-}
-
-/* --Public-Functions--------------------------------------------- */
-
-PKIX_Error *
-PKIX_PL_RWLock_Create(
- PKIX_PL_RWLock **pNewLock,
- void *plContext)
-{
- PKIX_PL_RWLock *rwLock = NULL;
-
- PKIX_ENTER(RWLOCK, "PKIX_PL_RWLock_Create");
- PKIX_NULLCHECK_ONE(pNewLock);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_RWLOCK_TYPE,
- sizeof (PKIX_PL_RWLock),
- (PKIX_PL_Object **)&rwLock,
- plContext),
- PKIX_ERRORALLOCATINGRWLOCK);
-
- PKIX_RWLOCK_DEBUG("\tCalling PR_NewRWLock)\n");
- rwLock->lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "PKIX RWLock");
-
- if (rwLock->lock == NULL) {
- PKIX_DECREF(rwLock);
- PKIX_ERROR(PKIX_OUTOFMEMORY);
- }
-
- rwLock->readCount = 0;
- rwLock->writeLocked = PKIX_FALSE;
-
- *pNewLock = rwLock;
-
-cleanup:
-
- PKIX_RETURN(RWLOCK);
-}
-
-PKIX_Error *
-PKIX_PL_AcquireReaderLock(
- PKIX_PL_RWLock *lock,
- void *plContext)
-{
- PKIX_ENTER(RWLOCK, "PKIX_PL_AcquireReaderLock");
- PKIX_NULLCHECK_ONE(lock);
-
- PKIX_RWLOCK_DEBUG("\tCalling PR_RWLock_Rlock)\n");
- (void) PR_RWLock_Rlock(lock->lock);
-
- lock->readCount++;
-
- PKIX_RETURN(RWLOCK);
-}
-
-PKIX_Error *
-PKIX_PL_ReleaseReaderLock(
- PKIX_PL_RWLock *lock,
- void *plContext)
-{
- PKIX_ENTER(RWLOCK, "PKIX_PL_ReleaseReaderLock");
- PKIX_NULLCHECK_ONE(lock);
-
- PKIX_RWLOCK_DEBUG("\tCalling PR_RWLock_Unlock)\n");
- (void) PR_RWLock_Unlock(lock->lock);
-
- lock->readCount--;
-
- PKIX_RETURN(RWLOCK);
-}
-
-PKIX_Error *
-PKIX_PL_IsReaderLockHeld(
- PKIX_PL_RWLock *lock,
- PKIX_Boolean *pIsHeld,
- void *plContext)
-{
- PKIX_ENTER(RWLOCK, "PKIX_PL_IsReaderLockHeld");
- PKIX_NULLCHECK_TWO(lock, pIsHeld);
-
- *pIsHeld = (lock->readCount > 0)?PKIX_TRUE:PKIX_FALSE;
-
- PKIX_RETURN(RWLOCK);
-}
-
-PKIX_Error *
-PKIX_PL_AcquireWriterLock(
- PKIX_PL_RWLock *lock,
- void *plContext)
-{
- PKIX_ENTER(RWLOCK, "PKIX_PL_AcquireWriterLock");
- PKIX_NULLCHECK_ONE(lock);
-
- PKIX_RWLOCK_DEBUG("\tCalling PR_RWLock_Wlock\n");
- (void) PR_RWLock_Wlock(lock->lock);
-
- if (lock->readCount > 0) {
- PKIX_ERROR(PKIX_LOCKHASNONZEROREADCOUNT);
- }
-
- /* We should never acquire a write lock if the lock is held */
- lock->writeLocked = PKIX_TRUE;
-
-cleanup:
-
- PKIX_RETURN(RWLOCK);
-}
-
-PKIX_Error *
-PKIX_PL_ReleaseWriterLock(
- PKIX_PL_RWLock *lock,
- void *plContext)
-{
- PKIX_ENTER(RWLOCK, "PKIX_PL_ReleaseWriterLock");
- PKIX_NULLCHECK_ONE(lock);
-
- if (lock->readCount > 0) {
- PKIX_ERROR(PKIX_LOCKHASNONZEROREADCOUNT);
- }
-
- PKIX_RWLOCK_DEBUG("\tCalling PR_RWLock_Unlock)\n");
- (void) PR_RWLock_Unlock(lock->lock);
-
- /* XXX Need to think about thread safety here */
- /* There should be a single lock holder */
- lock->writeLocked = PKIX_FALSE;
-
-cleanup:
-
- PKIX_RETURN(RWLOCK);
-}
-
-PKIX_Error *
-PKIX_PL_IsWriterLockHeld(
- PKIX_PL_RWLock *lock,
- PKIX_Boolean *pIsHeld,
- void *plContext)
-{
- PKIX_ENTER(RWLOCK, "PKIX_PL_IsWriterLockHeld");
- PKIX_NULLCHECK_TWO(lock, pIsHeld);
-
- *pIsHeld = lock->writeLocked;
-
- PKIX_RETURN(RWLOCK);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.h
deleted file mode 100755
index fd6465950..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_rwlock.h
- *
- * Read/Write Lock Definition
- *
- */
-
-#ifndef _PKIX_PL_RWLOCK_H
-#define _PKIX_PL_RWLOCK_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_RWLockStruct {
- PRRWLock* lock;
- PKIX_UInt32 readCount;
- PKIX_Boolean writeLocked;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_RWLock_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_RWLOCK_H */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.c
deleted file mode 100755
index 8bfa2c996..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_string.c
- *
- * String Object Functions
- *
- */
-
-#include "pkix_pl_string.h"
-
-/* --Private-String-Functions------------------------------------- */
-
-/*
- * FUNCTION: pkix_pl_String_Comparator
- * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
- *
- * NOTE:
- * This function is a utility function called by pkix_pl_String_Equals().
- * It is not officially registered as a comparator.
- */
-static PKIX_Error *
-pkix_pl_String_Comparator(
- PKIX_PL_String *firstString,
- PKIX_PL_String *secondString,
- PKIX_Int32 *pResult,
- void *plContext)
-{
- PKIX_UInt32 i;
- PKIX_Int32 result;
- unsigned char *p1 = NULL;
- unsigned char *p2 = NULL;
-
- PKIX_ENTER(STRING, "pkix_pl_String_Comparator");
- PKIX_NULLCHECK_THREE(firstString, secondString, pResult);
-
- result = 0;
-
- p1 = (unsigned char*) firstString->utf16String;
- p2 = (unsigned char*) secondString->utf16String;
-
- /* Compare characters until you find a difference */
- for (i = 0; ((i < firstString->utf16Length) &&
- (i < secondString->utf16Length) &&
- result == 0); i++, p1++, p2++) {
- if (*p1 < *p2){
- result = -1;
- } else if (*p1 > *p2){
- result = 1;
- }
- }
-
- /* If two arrays are identical so far, the longer one is greater */
- if (result == 0) {
- if (firstString->utf16Length < secondString->utf16Length) {
- result = -1;
- } else if (firstString->utf16Length >
- secondString->utf16Length) {
- result = 1;
- }
- }
-
- *pResult = result;
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: pkix_pl_String_Destroy
- * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_String_Destroy(
- PKIX_PL_Object *object,
- void *plContext)
-{
- PKIX_PL_String *string = NULL;
-
- PKIX_ENTER(STRING, "pkix_pl_String_Destroy");
- PKIX_NULLCHECK_ONE(object);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_STRING_TYPE, plContext),
- PKIX_ARGUMENTNOTSTRING);
-
- string = (PKIX_PL_String*)object;
-
- /* XXX For debugging Destroy EscASCII String */
- if (string->escAsciiString != NULL) {
- PKIX_FREE(string->escAsciiString);
- string->escAsciiString = NULL;
- string->escAsciiLength = 0;
- }
-
- /* Destroy UTF16 String */
- if (string->utf16String != NULL) {
- PKIX_FREE(string->utf16String);
- string->utf16String = NULL;
- string->utf16Length = 0;
- }
-
-cleanup:
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: pkix_pl_String_ToString
- * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_String_ToString(
- PKIX_PL_Object *object,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *string = NULL;
- char *ascii = NULL;
- PKIX_UInt32 length;
-
- PKIX_ENTER(STRING, "pkix_pl_String_ToString");
- PKIX_NULLCHECK_TWO(object, pString);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_STRING_TYPE, plContext),
- PKIX_ARGUMENTNOTSTRING);
-
- string = (PKIX_PL_String*)object;
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- (string, PKIX_ESCASCII, (void **)&ascii, &length, plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, ascii, 0, pString, plContext),
- PKIX_STRINGCREATEFAILED);
-
- goto cleanup;
-
-cleanup:
-
- PKIX_FREE(ascii);
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: pkix_pl_String_Equals
- * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_String_Equals(
- PKIX_PL_Object *firstObject,
- PKIX_PL_Object *secondObject,
- PKIX_Boolean *pResult,
- void *plContext)
-{
- PKIX_UInt32 secondType;
- PKIX_Int32 cmpResult = 0;
-
- PKIX_ENTER(STRING, "pkix_pl_String_Equals");
- PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
-
- /* Sanity check: Test that "firstObject" is a Strings */
- PKIX_CHECK(pkix_CheckType(firstObject, PKIX_STRING_TYPE, plContext),
- PKIX_FIRSTOBJECTNOTSTRING);
-
- /* "SecondObject" doesn't have to be a string */
- PKIX_CHECK(PKIX_PL_Object_GetType
- (secondObject, &secondType, plContext),
- PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
-
- /* If types differ, then we will return false */
- *pResult = PKIX_FALSE;
-
- if (secondType != PKIX_STRING_TYPE) goto cleanup;
-
- /* It's safe to cast here */
- PKIX_CHECK(pkix_pl_String_Comparator
- ((PKIX_PL_String*)firstObject,
- (PKIX_PL_String*)secondObject,
- &cmpResult,
- plContext),
- PKIX_STRINGCOMPARATORFAILED);
-
- /* Strings are equal iff Comparator Result is 0 */
- *pResult = (cmpResult == 0);
-
-cleanup:
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: pkix_pl_String_Hashcode
- * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
- */
-static PKIX_Error *
-pkix_pl_String_Hashcode(
- PKIX_PL_Object *object,
- PKIX_UInt32 *pHashcode,
- void *plContext)
-{
- PKIX_PL_String *string = NULL;
-
- PKIX_ENTER(STRING, "pkix_pl_String_Hashcode");
- PKIX_NULLCHECK_TWO(object, pHashcode);
-
- PKIX_CHECK(pkix_CheckType(object, PKIX_STRING_TYPE, plContext),
- PKIX_OBJECTNOTSTRING);
-
- string = (PKIX_PL_String*)object;
-
- PKIX_CHECK(pkix_hash
- ((const unsigned char *)string->utf16String,
- string->utf16Length,
- pHashcode,
- plContext),
- PKIX_HASHFAILED);
-
-cleanup:
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: pkix_pl_String_RegisterSelf
- * DESCRIPTION:
- * Registers PKIX_STRING_TYPE and its related functions with systemClasses[]
- * THREAD SAFETY:
- * Not Thread Safe - for performance and complexity reasons
- *
- * Since this function is only called by PKIX_PL_Initialize, which should
- * only be called once, it is acceptable that this function is not
- * thread-safe.
- */
-PKIX_Error *
-pkix_pl_String_RegisterSelf(
- void *plContext)
-{
- extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
- pkix_ClassTable_Entry entry;
-
- PKIX_ENTER(STRING, "pkix_pl_String_RegisterSelf");
-
- entry.description = "String";
- entry.objCounter = 0;
- entry.typeObjectSize = sizeof(PKIX_PL_String);
- entry.destructor = pkix_pl_String_Destroy;
- entry.equalsFunction = pkix_pl_String_Equals;
- entry.hashcodeFunction = pkix_pl_String_Hashcode;
- entry.toStringFunction = pkix_pl_String_ToString;
- entry.comparator = NULL;
- entry.duplicateFunction = pkix_duplicateImmutable;
-
- systemClasses[PKIX_STRING_TYPE] = entry;
-
- PKIX_RETURN(STRING);
-}
-
-
-/* --Public-String-Functions----------------------------------------- */
-
-/*
- * FUNCTION: PKIX_PL_String_Create (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_String_Create(
- PKIX_UInt32 fmtIndicator,
- const void *stringRep,
- PKIX_UInt32 stringLen,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_PL_String *string = NULL;
- unsigned char *utf16Char = NULL;
- PKIX_UInt32 i;
-
- PKIX_ENTER(STRING, "PKIX_PL_String_Create");
- PKIX_NULLCHECK_TWO(pString, stringRep);
-
- PKIX_CHECK(PKIX_PL_Object_Alloc
- (PKIX_STRING_TYPE,
- sizeof (PKIX_PL_String),
- (PKIX_PL_Object **)&string,
- plContext),
- PKIX_COULDNOTALLOCATENEWSTRINGOBJECT);
-
- string->utf16String = NULL;
- string->utf16Length = 0;
-
- /* XXX For Debugging */
- string->escAsciiString = NULL;
- string->escAsciiLength = 0;
-
- switch (fmtIndicator) {
- case PKIX_ESCASCII: case PKIX_ESCASCII_DEBUG:
- PKIX_STRING_DEBUG("\tCalling PL_strlen).\n");
- string->escAsciiLength = PL_strlen(stringRep);
-
- /* XXX Cache for Debugging */
- PKIX_CHECK(PKIX_PL_Malloc
- ((string->escAsciiLength)+1,
- (void **)&string->escAsciiString,
- plContext),
- PKIX_MALLOCFAILED);
-
- (void) PORT_Memcpy
- (string->escAsciiString,
- (void *)((char *)stringRep),
- (string->escAsciiLength)+1);
-
- /* Convert the EscASCII string to UTF16 */
- PKIX_CHECK(pkix_EscASCII_to_UTF16
- (string->escAsciiString,
- string->escAsciiLength,
- (fmtIndicator == PKIX_ESCASCII_DEBUG),
- &string->utf16String,
- &string->utf16Length,
- plContext),
- PKIX_ESCASCIITOUTF16FAILED);
- break;
- case PKIX_UTF8:
- /* Convert the UTF8 string to UTF16 */
- PKIX_CHECK(pkix_UTF8_to_UTF16
- (stringRep,
- stringLen,
- &string->utf16String,
- &string->utf16Length,
- plContext),
- PKIX_UTF8TOUTF16FAILED);
- break;
- case PKIX_UTF16:
- /* UTF16 Strings must be even in length */
- if (stringLen%2 == 1) {
- PKIX_DECREF(string);
- PKIX_ERROR(PKIX_UTF16ALIGNMENTERROR);
- }
-
- utf16Char = (unsigned char *)stringRep;
-
- /* Make sure this is a valid UTF-16 String */
- for (i = 0; \
- (i < stringLen) && (pkixErrorResult == NULL); \
- i += 2) {
- /* Check that surrogate pairs are valid */
- if ((utf16Char[i] >= 0xD8)&&
- (utf16Char[i] <= 0xDB)) {
- if ((i+2) >= stringLen) {
- PKIX_ERROR(PKIX_UTF16HIGHZONEALIGNMENTERROR);
- /* Second pair should be DC00-DFFF */
- } else if (!((utf16Char[i+2] >= 0xDC)&&
- (utf16Char[i+2] <= 0xDF))) {
- PKIX_ERROR(PKIX_UTF16LOWZONEERROR);
- } else {
- /* Surrogate quartet is valid. */
- i += 2;
- }
- }
- }
-
- /* Create UTF16 String */
- string->utf16Length = stringLen;
-
- /* Alloc space for string */
- PKIX_CHECK(PKIX_PL_Malloc
- (stringLen, &string->utf16String, plContext),
- PKIX_MALLOCFAILED);
-
- PKIX_STRING_DEBUG("\tCalling PORT_Memcpy).\n");
- (void) PORT_Memcpy
- (string->utf16String, stringRep, stringLen);
- break;
-
- default:
- PKIX_ERROR(PKIX_UNKNOWNFORMAT);
- }
-
- *pString = string;
-
-cleanup:
-
- if (PKIX_ERROR_RECEIVED){
- PKIX_DECREF(string);
- }
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: PKIX_PL_Sprintf (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_Sprintf(
- PKIX_PL_String **pOut,
- void *plContext,
- const PKIX_PL_String *fmt,
- ...)
-{
- PKIX_PL_String *tempString = NULL;
- PKIX_UInt32 tempUInt = 0;
- void *pArg = NULL;
- char *asciiText = NULL;
- char *asciiFormat = NULL;
- char *convertedAsciiFormat = NULL;
- char *convertedAsciiFormatBase = NULL;
- va_list args;
- PKIX_UInt32 length, i, j, dummyLen;
-
- PKIX_ENTER(STRING, "PKIX_PL_Sprintf");
- PKIX_NULLCHECK_TWO(pOut, fmt);
-
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- ((PKIX_PL_String *)fmt,
- PKIX_ESCASCII,
- (void **)&asciiFormat,
- &length,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
-
- PKIX_STRING_DEBUG("\tCalling PR_Malloc).\n");
- convertedAsciiFormat = PR_Malloc(length + 1);
- if (convertedAsciiFormat == NULL)
- PKIX_ERROR_ALLOC_ERROR();
-
- convertedAsciiFormatBase = convertedAsciiFormat;
-
- PKIX_STRING_DEBUG("\tCalling va_start).\n");
- va_start(args, fmt);
-
- i = 0;
- j = 0;
- while (i < length) {
- if ((asciiFormat[i] == '%')&&((i+1) < length)) {
- switch (asciiFormat[i+1]) {
- case 's':
- convertedAsciiFormat[j++] = asciiFormat[i++];
- convertedAsciiFormat[j++] = asciiFormat[i++];
- convertedAsciiFormat[j] = '\0';
-
- tempString = va_arg(args, PKIX_PL_String *);
- if (tempString != NULL) {
- PKIX_CHECK(PKIX_PL_String_GetEncoded
- ((PKIX_PL_String*)
- tempString,
- PKIX_ESCASCII,
- &pArg,
- &dummyLen,
- plContext),
- PKIX_STRINGGETENCODEDFAILED);
- } else {
- /* there may be a NULL in var_args */
- pArg = NULL;
- }
- if (asciiText != NULL) {
- asciiText = PR_sprintf_append(asciiText,
- (const char *)convertedAsciiFormat,
- pArg);
- } else {
- asciiText = PR_smprintf
- ((const char *)convertedAsciiFormat,
- pArg);
- }
- if (pArg != NULL) {
- PKIX_PL_Free(pArg, plContext);
- pArg = NULL;
- }
- convertedAsciiFormat += j;
- j = 0;
- break;
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- convertedAsciiFormat[j++] = asciiFormat[i++];
- convertedAsciiFormat[j++] = asciiFormat[i++];
- convertedAsciiFormat[j] = '\0';
-
- tempUInt = va_arg(args, PKIX_UInt32);
- if (asciiText != NULL) {
- asciiText = PR_sprintf_append(asciiText,
- (const char *)convertedAsciiFormat,
- tempUInt);
- } else {
- asciiText = PR_smprintf
- ((const char *)convertedAsciiFormat,
- tempUInt);
- }
- convertedAsciiFormat += j;
- j = 0;
- break;
- default:
- convertedAsciiFormat[j++] = asciiFormat[i++];
- convertedAsciiFormat[j++] = asciiFormat[i++];
- break;
- }
- } else {
- convertedAsciiFormat[j++] = asciiFormat[i++];
- }
- }
-
- /* for constant string value at end of fmt */
- if (j > 0) {
- convertedAsciiFormat[j] = '\0';
- if (asciiText != NULL) {
- asciiText = PR_sprintf_append(asciiText,
- (const char *)convertedAsciiFormat);
- } else {
- asciiText = PR_smprintf((const char *)convertedAsciiFormat);
- }
- }
-
- va_end(args);
-
- /* Copy temporary char * into a string object */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, (void *)asciiText, 0, pOut, plContext),
- PKIX_STRINGCREATEFAILED);
-
-cleanup:
-
- PKIX_FREE(asciiFormat);
-
- if (convertedAsciiFormatBase){
- PR_Free(convertedAsciiFormatBase);
- }
-
- if (asciiText){
- PKIX_STRING_DEBUG("\tCalling PR_smprintf_free).\n");
- PR_smprintf_free(asciiText);
- }
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: PKIX_PL_GetString (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_GetString(
- /* ARGSUSED */ PKIX_UInt32 stringID,
- char *defaultString,
- PKIX_PL_String **pString,
- void *plContext)
-{
- PKIX_ENTER(STRING, "PKIX_PL_GetString");
- PKIX_NULLCHECK_TWO(pString, defaultString);
-
- /* XXX Optimization - use stringID for caching */
- PKIX_CHECK(PKIX_PL_String_Create
- (PKIX_ESCASCII, defaultString, 0, pString, plContext),
- PKIX_STRINGCREATEFAILED);
-
-cleanup:
-
- PKIX_RETURN(STRING);
-}
-
-/*
- * FUNCTION: PKIX_PL_String_GetEncoded (see comments in pkix_pl_system.h)
- */
-PKIX_Error *
-PKIX_PL_String_GetEncoded(
- PKIX_PL_String *string,
- PKIX_UInt32 fmtIndicator,
- void **pStringRep,
- PKIX_UInt32 *pLength,
- void *plContext)
-{
- PKIX_ENTER(STRING, "PKIX_PL_String_GetEncoded");
- PKIX_NULLCHECK_THREE(string, pStringRep, pLength);
-
- switch (fmtIndicator) {
- case PKIX_ESCASCII: case PKIX_ESCASCII_DEBUG:
- PKIX_CHECK(pkix_UTF16_to_EscASCII
- (string->utf16String,
- string->utf16Length,
- (fmtIndicator == PKIX_ESCASCII_DEBUG),
- (char **)pStringRep,
- pLength,
- plContext),
- PKIX_UTF16TOESCASCIIFAILED);
- break;
- case PKIX_UTF8:
- PKIX_CHECK(pkix_UTF16_to_UTF8
- (string->utf16String,
- string->utf16Length,
- PKIX_FALSE,
- pStringRep,
- pLength,
- plContext),
- PKIX_UTF16TOUTF8FAILED);
- break;
- case PKIX_UTF8_NULL_TERM:
- PKIX_CHECK(pkix_UTF16_to_UTF8
- (string->utf16String,
- string->utf16Length,
- PKIX_TRUE,
- pStringRep,
- pLength,
- plContext),
- PKIX_UTF16TOUTF8FAILED);
- break;
- case PKIX_UTF16:
- *pLength = string->utf16Length;
-
- PKIX_CHECK(PKIX_PL_Malloc(*pLength, pStringRep, plContext),
- PKIX_MALLOCFAILED);
-
- PKIX_STRING_DEBUG("\tCalling PORT_Memcpy).\n");
- (void) PORT_Memcpy(*pStringRep, string->utf16String, *pLength);
- break;
- default:
- PKIX_ERROR(PKIX_UNKNOWNFORMAT);
- }
-
-cleanup:
-
- PKIX_RETURN(STRING);
-}
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.h b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.h
deleted file mode 100755
index 9270e4c56..000000000
--- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * pkix_pl_string.h
- *
- * String Object Definitions
- *
- */
-
-#ifndef _PKIX_PL_STRING_H
-#define _PKIX_PL_STRING_H
-
-#include "pkix_pl_common.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct PKIX_PL_StringStruct {
- void* utf16String;
- PKIX_UInt32 utf16Length;
- /* XXX For Debugging */
- char* escAsciiString;
- PKIX_UInt32 escAsciiLength;
-};
-
-/* see source file for function documentation */
-
-PKIX_Error *
-pkix_pl_String_RegisterSelf(void *plContext);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PKIX_PL_STRING_H */
diff --git a/security/nss/lib/manifest.mn b/security/nss/lib/manifest.mn
deleted file mode 100644
index 6ef8fb998..000000000
--- a/security/nss/lib/manifest.mn
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../..
-DEPTH = ../..
-
-#
-# organized by DLL
-#
-# softoken and prereqs.
-# stan (not a separate dll yet)
-# libpkix (not a separate dll)
-# nss base (traditional)
-# ssl
-# smime
-# ckfw (builtins module)
-# crmf jar (not dll's)
-DIRS = util freebl $(SQLITE_SRCDIR) softoken \
- base dev pki \
- libpkix \
- certdb certhigh pk11wrap cryptohi nss \
- $(ZLIB_SRCDIR) ssl \
- pkcs12 pkcs7 smime \
- crmf jar \
- ckfw $(SYSINIT_SRCDIR) \
- $(NULL)
-
-# fortcrypt is no longer built
-
-#
-# these dirs are not built at the moment
-#
-#NOBUILD_DIRS = jar
diff --git a/security/nss/lib/nss/Makefile b/security/nss/lib/nss/Makefile
deleted file mode 100644
index 3a8e22f0a..000000000
--- a/security/nss/lib/nss/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk
deleted file mode 100644
index 170e99922..000000000
--- a/security/nss/lib/nss/config.mk
+++ /dev/null
@@ -1,102 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
-
-RES = $(OBJDIR)/$(LIBRARY_NAME).res
-RESNAME = $(LIBRARY_NAME).rc
-
-ifdef NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4\
- $(NULL)
-else # ! NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- $(DIST)/lib/nssutil3.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-
-else
-
-# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
-# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-
-endif
-
-
-# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
-SHARED_LIBRARY_LIBS = \
- $(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)certsel.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)checker.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)params.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)results.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)top.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)util.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)crlsel.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)store.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)pki.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)system.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)module.$(LIB_SUFFIX) \
- $(NULL)
-
-SHARED_LIBRARY_DIRS = \
- ../certhigh \
- ../cryptohi \
- ../pk11wrap \
- ../certdb \
- ../pki \
- ../dev \
- ../base \
- ../libpkix/pkix/certsel \
- ../libpkix/pkix/checker \
- ../libpkix/pkix/params \
- ../libpkix/pkix/results \
- ../libpkix/pkix/top \
- ../libpkix/pkix/util \
- ../libpkix/pkix/crlsel \
- ../libpkix/pkix/store \
- ../libpkix/pkix_pl_nss/pki \
- ../libpkix/pkix_pl_nss/system \
- ../libpkix/pkix_pl_nss/module \
- $(NULL)
-
-ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
-ifndef NS_USE_GCC
-# Export 'mktemp' to be backward compatible with NSS 3.2.x and 3.3.x
-# but do not put it in the import library. See bug 142575.
-DEFINES += -DWIN32_NSS3_DLL_COMPAT
-DLLFLAGS += -EXPORT:mktemp=nss_mktemp,PRIVATE
-endif
-endif
diff --git a/security/nss/lib/nss/manifest.mn b/security/nss/lib/nss/manifest.mn
deleted file mode 100644
index 005be6dd6..000000000
--- a/security/nss/lib/nss/manifest.mn
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-
-PRIVATE_EXPORTS = \
- nssrenam.h \
- $(NULL)
-
-EXPORTS = \
- nss.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- nssinit.c \
- nssver.c \
- utilwrap.c \
- $(NULL)
-
-MAPFILE = $(OBJDIR)/nss.def
-
-LIBRARY_NAME = nss
-LIBRARY_VERSION = 3
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def
deleted file mode 100644
index 31a616396..000000000
--- a/security/nss/lib/nss/nss.def
+++ /dev/null
@@ -1,1029 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+NSS_3.2 { # NSS 3.2 release
-;+ global:
-LIBRARY nss3 ;-
-EXPORTS ;-
-ATOB_AsciiToData;
-BTOA_ConvertItemToAscii;
-BTOA_DataToAscii;
-CERT_AsciiToName;
-CERT_CertTimesValid;
-CERT_CheckCertValidTimes;
-CERT_CreateCertificateRequest;
-CERT_ChangeCertTrust;
-CERT_DecodeDERCrl;
-CERT_DestroyCertificateRequest;
-CERT_DestroyCertList;
-CERT_DestroyName;
-CERT_EnableOCSPChecking;
-CERT_FormatName;
-CERT_DestroyCertificate;
-CERT_DupCertificate;
-CERT_FreeDistNames;
-CERT_FreeNicknames;
-CERT_GetAVATag;
-CERT_GetCertEmailAddress;
-CERT_GetCertNicknames;
-CERT_GetCertIssuerAndSN;
-CERT_GetCertTrust;
-CERT_GetCertUid;
-CERT_GetCommonName;
-CERT_GetCountryName;
-CERT_GetDBContentVersion;
-CERT_GetDefaultCertDB;
-CERT_GetDomainComponentName;
-CERT_GetLocalityName;
-CERT_GetOrgName;
-CERT_GetOrgUnitName;
-CERT_GetSSLCACerts;
-CERT_GetSlopTime;
-CERT_GetStateName;
-CERT_ImportCAChain;
-CERT_NameToAscii;
-CERT_RFC1485_EscapeAndQuote;
-CERT_SetSlopTime;
-CERT_VerifyCertName;
-CERT_VerifyCertNow;
-DER_UTCDayToAscii;
-DER_UTCTimeToAscii;
-DER_GeneralizedTimeToTime;
-NSS_Init;
-NSS_Initialize;
-NSS_InitReadWrite;
-NSS_NoDB_Init;
-NSS_Shutdown;
-NSS_VersionCheck;
-PK11_Authenticate;
-PK11_ChangePW;
-PK11_CheckUserPassword;
-PK11_CipherOp;
-PK11_CloneContext;
-PK11_ConfigurePKCS11;
-PK11_CreateContextBySymKey;
-PK11_CreateDigestContext;
-PK11_DestroyContext;
-PK11_DestroyTokenObject;
-PK11_DigestBegin;
-PK11_DigestOp;
-PK11_DigestFinal;
-PK11_DoesMechanism;
-PK11_FindCertFromNickname;
-PK11_FindCertFromDERCert;
-PK11_FindCertByIssuerAndSN;
-PK11_FindKeyByAnyCert;
-PK11_FindKeyByDERCert;
-PK11_FindSlotByName;
-PK11_Finalize;
-PK11_FortezzaHasKEA;
-PK11_FreeSlot;
-PK11_FreeSlotList;
-PK11_FreeSymKey;
-PK11_GenerateKeyPair;
-PK11_GenerateRandom;
-PK11_GenerateNewParam;
-PK11_GetAllTokens;
-PK11_GetBlockSize;
-PK11_GetFirstSafe;
-PK11_GetInternalKeySlot;
-PK11_GetInternalSlot;
-PK11_GetSlotName;
-PK11_GetTokenName;
-PK11_HashBuf;
-PK11_IsFIPS;
-PK11_IsFriendly;
-PK11_IsInternal;
-PK11_IsHW;
-PK11_IsPresent;
-PK11_IsReadOnly;
-PK11_KeyGen;
-PK11_ListCerts;
-PK11_NeedLogin;
-PK11_RandomUpdate;
-PK11_SetPasswordFunc;
-PK11_SetSlotPWValues;
-PORT_Alloc;
-PORT_Free;
-PORT_GetError;
-PORT_SetError;
-PORT_SetUCS4_UTF8ConversionFunction;
-PORT_SetUCS2_UTF8ConversionFunction;
-PORT_SetUCS2_ASCIIConversionFunction;
-SECITEM_CopyItem;
-SECITEM_DupItem;
-SECITEM_FreeItem;
-SECITEM_ZfreeItem;
-SECKEY_ConvertToPublicKey;
-SECKEY_CopyPrivateKey;
-SECKEY_CreateSubjectPublicKeyInfo;
-SECKEY_DestroyPrivateKey;
-SECKEY_DestroySubjectPublicKeyInfo;
-SECMOD_IsModulePresent;
-SECOID_FindOIDTagDescription;
-SECOID_GetAlgorithmTag;
-SEC_DeletePermCertificate;
-SEC_DeletePermCRL;
-SEC_DerSignData;
-SEC_DestroyCrl;
-SEC_FindCrlByDERCert;
-SEC_FindCrlByName;
-SEC_LookupCrls;
-SEC_NewCrl;
-;+#
-;+# The following symbols are exported only to make libssl3.so work.
-;+# These are still private!!!
-;+#
-__CERT_NewTempCertificate;
-__PK11_CreateContextByRawKey;
-__PK11_GetKeyData;
-__nss_InitLock;
-CERT_CertChainFromCert;
-CERT_DestroyCertificateList;
-CERT_DupCertList;
-CERT_ExtractPublicKey;
-CERT_FindCertByName;
-DER_Lengths;
-DSAU_DecodeDerSig;
-DSAU_EncodeDerSig;
-HASH_GetHashObject;
-NSSRWLock_Destroy;
-NSSRWLock_HaveWriteLock;
-NSSRWLock_LockRead;
-NSSRWLock_LockWrite;
-NSSRWLock_New;
-NSSRWLock_UnlockRead;
-NSSRWLock_UnlockWrite;
-NSS_PutEnv;
-PK11_Derive;
-PK11_DeriveWithFlags;
-PK11_DigestKey;
-PK11_FindBestKEAMatch;
-PK11_FindFixedKey;
-PK11_GenerateFortezzaIV;
-PK11_GetBestKeyLength;
-PK11_GetBestSlot;
-PK11_GetBestSlotMultiple;
-PK11_GetBestWrapMechanism;
-PK11_GetCurrentWrapIndex;
-PK11_GetMechanism;
-PK11_GetModuleID;
-PK11_GetPrivateModulusLen;
-PK11_GetSlotFromKey;
-PK11_GetSlotFromPrivateKey;
-PK11_GetSlotID;
-PK11_GetSlotSeries;
-PK11_GetTokenInfo;
-PK11_GetWindow;
-PK11_GetWrapKey;
-PK11_IVFromParam;
-PK11_MakeKEAPubKey;
-PK11_ParamFromIV;
-PK11_PubDecryptRaw;
-PK11_PubDerive;
-PK11_PubEncryptRaw;
-PK11_PubUnwrapSymKey;
-PK11_PubWrapSymKey;
-PK11_ReferenceSymKey;
-PK11_RestoreContext;
-PK11_SaveContext;
-PK11_SetFortezzaHack;
-PK11_SetWrapKey;
-PK11_Sign;
-PK11_SignatureLen;
-PK11_SymKeyFromHandle;
-PK11_TokenExists;
-PK11_UnwrapSymKey;
-PK11_UnwrapSymKeyWithFlags;
-PK11_Verify;
-PK11_VerifyKeyOK;
-PK11_WrapSymKey;
-PORT_ArenaAlloc;
-PORT_ArenaZAlloc;
-PORT_FreeArena;
-PORT_NewArena;
-PORT_Realloc;
-PORT_ZAlloc;
-PORT_ZFree;
-RSA_FormatBlock;
-SECITEM_CompareItem;
-SECKEY_CreateRSAPrivateKey;
-SECKEY_DestroyPublicKey;
-SECKEY_PublicKeyStrength;
-SECKEY_UpdateCertPQG;
-SECMOD_LookupSlot;
-SGN_Begin;
-SGN_DestroyContext;
-SGN_End;
-SGN_NewContext;
-SGN_Update;
-VFY_Begin;
-VFY_CreateContext;
-VFY_DestroyContext;
-VFY_End;
-VFY_Update;
-;+#
-;+# The following symbols are exported only to make libsmime3.so work.
-;+# These are still private!!!
-;+#
-__CERT_ClosePermCertDB;
-__CERT_DecodeDERCertificate;
-__CERT_TraversePermCertsForNickname;
-__CERT_TraversePermCertsForSubject;
-__PBE_CreateContext;
-__PBE_DestroyContext;
-__PBE_GenerateBits;
-ATOB_ConvertAsciiToItem;
-CERT_AddCertToListTail;
-CERT_CertListFromCert;
-CERT_DestroyCertArray;
-CERT_FindCertByDERCert;
-CERT_FindCertByIssuerAndSN;
-CERT_FindSMimeProfile;
-CERT_ImportCerts;
-CERT_NewCertList;
-CERT_OpenCertDBFilename;
-CERT_SaveSMimeProfile;
-CERT_VerifyCert;
-DER_GetInteger;
-DER_TimeToUTCTime;
-DER_UTCTimeToTime;
-PK11_AlgtagToMechanism;
-PK11_BlockData;
-PK11_CreatePBEAlgorithmID;
-PK11_DestroyObject;
-PK11_ExportEncryptedPrivateKeyInfo;
-PK11_ExportPrivateKeyInfo;
-PK11_FindCertAndKeyByRecipientList;
-PK11_FindCertAndKeyByRecipientListNew;
-PK11_FindCertInSlot;
-PK11_FindPrivateKeyFromCert;
-PK11_FortezzaMapSig;
-PK11_GetKeyLength;
-PK11_GetKeyStrength;
-PK11_ImportCertForKeyToSlot;
-PK11_ImportEncryptedPrivateKeyInfo;
-PK11_ImportPrivateKeyInfo;
-PK11_MapPBEMechanismToCryptoMechanism;
-PK11_PBEKeyGen;
-PK11_ParamFromAlgid;
-PK11_ParamToAlgid;
-PK11_TraverseCertsForNicknameInSlot;
-PK11_TraverseCertsForSubjectInSlot;
-PORT_ArenaGrow;
-PORT_ArenaMark;
-PORT_ArenaRelease;
-PORT_ArenaStrdup;
-PORT_ArenaUnmark;
-PORT_UCS2_ASCIIConversion;
-PORT_UCS2_UTF8Conversion;
-SECITEM_AllocItem;
-SECKEY_CopyEncryptedPrivateKeyInfo;
-SECKEY_CopyPrivateKeyInfo;
-SECKEY_DestroyEncryptedPrivateKeyInfo;
-SECKEY_DestroyPrivateKeyInfo;
-SECOID_CompareAlgorithmID;
-SECOID_CopyAlgorithmID;
-SECOID_DestroyAlgorithmID;
-SECOID_FindOID;
-SECOID_FindOIDByTag;
-SECOID_FindOIDTag;
-SECOID_SetAlgorithmID;
-SEC_ASN1DecodeInteger;
-SEC_ASN1DecodeItem;
-SEC_ASN1DecoderClearFilterProc;
-SEC_ASN1DecoderClearNotifyProc;
-SEC_ASN1DecoderFinish;
-SEC_ASN1DecoderSetFilterProc;
-SEC_ASN1DecoderSetNotifyProc;
-SEC_ASN1DecoderStart;
-SEC_ASN1DecoderUpdate;
-SEC_ASN1Encode;
-SEC_ASN1EncodeInteger;
-SEC_ASN1EncodeItem;
-SEC_ASN1EncoderClearNotifyProc;
-SEC_ASN1EncoderClearStreaming;
-SEC_ASN1EncoderClearTakeFromBuf;
-SEC_ASN1EncoderFinish;
-SEC_ASN1EncoderSetNotifyProc;
-SEC_ASN1EncoderSetStreaming;
-SEC_ASN1EncoderSetTakeFromBuf;
-SEC_ASN1EncoderStart;
-SEC_ASN1EncoderUpdate;
-SEC_ASN1LengthLength;
-SEC_PKCS5GetCryptoAlgorithm;
-SEC_PKCS5GetKeyLength;
-SEC_PKCS5GetPBEAlgorithm;
-SEC_PKCS5IsAlgorithmPBEAlg;
-SEC_SignData;
-SGN_CompareDigestInfo;
-SGN_CopyDigestInfo;
-SGN_CreateDigestInfo;
-SGN_DestroyDigestInfo;
-SGN_Digest;
-VFY_VerifyData;
-VFY_VerifyDigest;
-;+#
-;+# Data objects
-;+#
-;+# Don't export these DATA symbols on Windows because they don't work right.
-;+# Use the SEC_ASN1_GET / SEC_ASN1_SUB / SEC_ASN1_XTRN macros to access them.
-;;CERT_CrlTemplate DATA ;
-;;CERT_SignedDataTemplate DATA ;
-;;CERT_CertificateTemplate DATA ;
-;;CERT_CertificateRequestTemplate DATA ;
-;;CERT_IssuerAndSNTemplate DATA ;
-;;CERT_SetOfSignedCrlTemplate DATA ;
-;;SECKEY_DSAPublicKeyTemplate DATA ;
-;;SECKEY_EncryptedPrivateKeyInfoTemplate DATA ;
-;;SECKEY_PointerToEncryptedPrivateKeyInfoTemplate DATA ;
-;;SECKEY_PointerToPrivateKeyInfoTemplate DATA ;
-;;SECKEY_PrivateKeyInfoTemplate DATA ;
-;;SECKEY_RSAPublicKeyTemplate DATA ;
-;;SECOID_AlgorithmIDTemplate DATA ;
-;;SEC_AnyTemplate DATA ;
-;;SEC_BMPStringTemplate DATA ;
-;;SEC_BitStringTemplate DATA ;
-;;SEC_GeneralizedTimeTemplate DATA ;
-;;SEC_IA5StringTemplate DATA ;
-;;SEC_IntegerTemplate DATA ;
-;;SEC_ObjectIDTemplate DATA ;
-;;SEC_OctetStringTemplate DATA ;
-;;SEC_PointerToAnyTemplate DATA ;
-;;SEC_PointerToOctetStringTemplate DATA ;
-;;SEC_SetOfAnyTemplate DATA ;
-;;SEC_UTCTimeTemplate DATA ;
-;;sgn_DigestInfoTemplate DATA ;
-NSS_Get_CERT_CrlTemplate;
-NSS_Get_CERT_SignedDataTemplate;
-NSS_Get_CERT_CertificateTemplate;
-NSS_Get_CERT_CertificateRequestTemplate;
-NSS_Get_CERT_IssuerAndSNTemplate;
-NSS_Get_CERT_SetOfSignedCrlTemplate;
-NSS_Get_SECKEY_DSAPublicKeyTemplate;
-NSS_Get_SECKEY_EncryptedPrivateKeyInfoTemplate;
-NSS_Get_SECKEY_PointerToEncryptedPrivateKeyInfoTemplate;
-NSS_Get_SECKEY_PointerToPrivateKeyInfoTemplate;
-NSS_Get_SECKEY_PrivateKeyInfoTemplate;
-NSS_Get_SECKEY_RSAPublicKeyTemplate;
-NSS_Get_SECOID_AlgorithmIDTemplate;
-NSS_Get_SEC_AnyTemplate;
-NSS_Get_SEC_BMPStringTemplate;
-NSS_Get_SEC_BitStringTemplate;
-NSS_Get_SEC_GeneralizedTimeTemplate;
-NSS_Get_SEC_IA5StringTemplate;
-NSS_Get_SEC_IntegerTemplate;
-NSS_Get_SEC_ObjectIDTemplate;
-NSS_Get_SEC_OctetStringTemplate;
-NSS_Get_SEC_PointerToAnyTemplate;
-NSS_Get_SEC_PointerToOctetStringTemplate;
-NSS_Get_SEC_SetOfAnyTemplate;
-NSS_Get_SEC_UTCTimeTemplate;
-NSS_Get_sgn_DigestInfoTemplate;
-;+# commands
-CERT_DecodeBasicConstraintValue;
-CERT_DecodeOidSequence;
-CERT_DecodeUserNotice;
-CERT_DecodeCertificatePoliciesExtension;
-CERT_DestroyCertificatePoliciesExtension;
-CERT_FindCertByNicknameOrEmailAddr;
-CERT_FindCertByNickname;
-CERT_GenTime2FormattedAscii;
-CERT_Hexify;
-CERT_CompareName;
-PK11SDR_Encrypt;
-PK11SDR_Decrypt;
-NSSBase64Decoder_Create;
-NSSBase64Decoder_Destroy;
-NSSBase64Decoder_Update;
-NSSBase64Encoder_Create;
-NSSBase64Encoder_Destroy;
-NSSBase64Encoder_Update;
-;+#PK11_DoPassword;
-;+#PK11_FindKeyByKeyID;
-PK11_InitPin;
-PK11_NeedUserInit;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.2.1 { # NSS 3.2.1 release
-;+ global:
-CERT_AddRDN;
-CERT_CreateRDN;
-CERT_CreateAVA;
-CERT_CreateName;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.3 { # NSS 3.3. release
-;+ global:
-CERT_CheckCertUsage;
-CERT_FindCertIssuer;
-PK11_GetModule;
-SECKEY_CreateDHPrivateKey;
-SECKEY_GetPublicKeyType;
-SECMOD_AddNewModule;
-;+#
-;+# The following symbols are exported only to make JSS work.
-;+# These are still private!!!
-;+#
-CERT_DisableOCSPChecking;
-CERT_DisableOCSPDefaultResponder;
-CERT_EnableOCSPDefaultResponder;
-CERT_GetCertTimes;
-CERT_ImportCAChainTrusted;
-CERT_ImportCRL;
-CERT_IsCACert;
-CERT_IsCADERCert;
-CERT_SetOCSPDefaultResponder;
-PBE_CreateContext;
-PBE_DestroyContext;
-PBE_GenerateBits;
-PK11_CheckSSOPassword;
-PK11_CopySymKeyForSigning;
-PK11_DeleteTokenCertAndKey;
-PK11_DEREncodePublicKey;
-PK11_ExtractKeyValue;
-PK11_FindCertsFromNickname;
-PK11_FindKeyByKeyID;
-PK11_GetIVLength;
-PK11_GetKeyData;
-PK11_GetKeyType;
-PK11_GetLowLevelKeyIDForCert;
-PK11_GetLowLevelKeyIDForPrivateKey;
-PK11_GetSlotPWValues;
-PK11_ImportCertForKey;
-PK11_ImportDERCertForKey;
-PK11_ImportDERPrivateKeyInfo;
-PK11_ImportSymKey;
-PK11_IsLoggedIn;
-PK11_KeyForDERCertExists;
-PK11_KeyForCertExists;
-PK11_ListPrivateKeysInSlot;
-PK11_ListCertsInSlot;
-PK11_Logout;
-PK11_NeedPWInit;
-PK11_MakeIDFromPubKey;
-PK11_PQG_DestroyParams;
-PK11_PQG_DestroyVerify;
-PK11_PQG_GetBaseFromParams;
-PK11_PQG_GetCounterFromVerify;
-PK11_PQG_GetHFromVerify;
-PK11_PQG_GetPrimeFromParams;
-PK11_PQG_GetSeedFromVerify;
-PK11_PQG_GetSubPrimeFromParams;
-PK11_PQG_NewParams;
-PK11_PQG_NewVerify;
-PK11_PQG_ParamGen;
-PK11_PQG_ParamGenSeedLen;
-PK11_PQG_VerifyParams;
-PK11_ReferenceSlot;
-PK11_SeedRandom;
-PK11_UnwrapPrivKey;
-PK11_VerifyRecover;
-PK11_WrapPrivKey;
-SEC_CertNicknameConflict;
-SEC_PKCS5GetIV;
-SECMOD_DeleteInternalModule;
-SECMOD_DestroyModule;
-SECMOD_GetDefaultModuleList;
-SECMOD_GetDefaultModuleListLock;
-SECMOD_GetInternalModule;
-SECMOD_GetReadLock;
-SECMOD_ReferenceModule;
-SECMOD_ReleaseReadLock;
-SECKEY_AddPrivateKeyToListTail;
-SECKEY_EncodeDERSubjectPublicKeyInfo;
-SECKEY_ExtractPublicKey;
-SECKEY_DestroyPrivateKeyList;
-SECKEY_GetPrivateKeyType;
-SECKEY_HashPassword;
-SECKEY_ImportDERPublicKey;
-SECKEY_NewPrivateKeyList;
-SECKEY_RemovePrivateKeyListNode;
-VFY_EndWithSignature;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.3.1 { # NSS 3.3.1 release
-;+ global:
-;+#
-;+# The following symbols are exported only to make libsmime3.so work.
-;+# These are still private!!!
-;+#
-PK11_CreatePBEParams;
-PK11_DestroyPBEParams;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.4 { # NSS 3.4 release
-;+ global:
-SECMOD_AddNewModuleEx;
-SECMOD_DeleteModule;
-SECMOD_FreeModuleSpecList;
-SECMOD_GetModuleSpecList;
-SECMOD_LoadModule;
-SECMOD_LoadUserModule;
-SECMOD_UnloadUserModule;
-SECMOD_UpdateModule;
-;+# for PKCS #12
-PK11_RawPBEKeyGen;
-;+# for PSM
-__CERT_AddTempCertToPerm;
-CERT_AddOKDomainName;
-CERT_CopyName;
-CERT_CreateSubjectCertList;
-CERT_DecodeAVAValue;
-;+#CERT_DecodeCertFromPackage;
-CERT_DecodeGeneralName;
-CERT_DecodeTrustString;
-CERT_DerNameToAscii;
-CERT_EncodeGeneralName;
-CERT_FilterCertListByCANames;
-CERT_FilterCertListByUsage;
-CERT_FindCertExtension;
-CERT_FindKeyUsageExtension;
-CERT_FindUserCertByUsage;
-CERT_FindUserCertsByUsage;
-CERT_GetCertChainFromCert;
-CERT_GetOCSPAuthorityInfoAccessLocation;
-CERT_KeyFromDERCrl;
-CERT_MakeCANickname;
-CERT_NicknameStringsFromCertList;
-CERT_VerifySignedData;
-DER_Encode;
-HASH_Begin;
-HASH_Create;
-HASH_Destroy;
-HASH_End;
-HASH_ResultLen;
-HASH_Update;
-NSSBase64_DecodeBuffer; # from Stan
-NSSBase64_EncodeItem; # from Stan
-PK11_GetKeyGen;
-PK11_GetMinimumPwdLength;
-PK11_GetNextSafe;
-PK11_GetPadMechanism;
-PK11_GetSlotInfo;
-PK11_HasRootCerts;
-PK11_IsDisabled;
-PK11_LoadPrivKey;
-PK11_LogoutAll;
-PK11_MechanismToAlgtag;
-PK11_ResetToken;
-PK11_TraverseSlotCerts;
-SEC_ASN1Decode;
-SECKEY_CopySubjectPublicKeyInfo;
-SECMOD_CreateModule;
-SECMOD_FindModule;
-SECMOD_FindSlot;
-SECMOD_PubCipherFlagstoInternal;
-SECMOD_PubMechFlagstoInternal;
-;;CERT_NameTemplate DATA ;
-;;CERT_SubjectPublicKeyInfoTemplate DATA ;
-;;SEC_BooleanTemplate DATA ;
-;;SEC_NullTemplate DATA ;
-;;SEC_SignedCertificateTemplate DATA ;
-;;SEC_UTF8StringTemplate DATA ;
-NSS_Get_CERT_NameTemplate;
-NSS_Get_CERT_SubjectPublicKeyInfoTemplate;
-NSS_Get_SEC_BooleanTemplate;
-NSS_Get_SEC_NullTemplate;
-NSS_Get_SEC_SignedCertificateTemplate;
-NSS_Get_SEC_UTF8StringTemplate;
-;+# for JSS
-PK11_DeleteTokenPrivateKey;
-PK11_DeleteTokenPublicKey;
-PK11_DeleteTokenSymKey;
-PK11_GetNextSymKey;
-PK11_GetPQGParamsFromPrivateKey;
-PK11_GetPrivateKeyNickname;
-PK11_GetPublicKeyNickname;
-PK11_GetSymKeyNickname;
-PK11_ImportDERPrivateKeyInfoAndReturnKey;
-PK11_ImportPrivateKeyInfoAndReturnKey;
-PK11_ImportPublicKey;
-PK11_ImportSymKeyWithFlags;
-PK11_ListFixedKeysInSlot;
-PK11_ListPrivKeysInSlot;
-PK11_ListPublicKeysInSlot;
-PK11_ProtectedAuthenticationPath;
-PK11_SetPrivateKeyNickname;
-PK11_SetPublicKeyNickname;
-PK11_SetSymKeyNickname;
-SECKEY_DecodeDERSubjectPublicKeyInfo;
-SECKEY_DestroyPublicKeyList;
-;+# for debugging
-nss_DumpCertificateCacheInfo;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.5 { # cert creation APIs used by certutil
-;+ global:
-CERT_AddExtension;
-CERT_CopyRDN;
-CERT_CreateCertificate;
-CERT_CreateValidity;
-CERT_DestroyValidity;
-CERT_EncodeAndAddBitStrExtension;
-CERT_EncodeAuthKeyID;
-CERT_EncodeBasicConstraintValue;
-CERT_EncodeCRLDistributionPoints;
-CERT_FinishExtensions;
-CERT_StartCertExtensions;
-DER_AsciiToTime;
-PK11_ImportCert;
-PORT_Strdup;
-SECMOD_CanDeleteInternalModule;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.6 { # NSS 3.6 release
-;+ global:
-CERT_AddOCSPAcceptableResponses;
-CERT_CompleteCRLDecodeEntries;
-CERT_CreateOCSPCertID;
-CERT_CreateOCSPRequest;
-CERT_DecodeDERCrlWithFlags;
-CERT_DecodeOCSPResponse;
-CERT_DestroyOCSPCertID;
-CERT_DestroyOCSPRequest;
-CERT_EncodeOCSPRequest;
-CERT_FilterCertListForUserCerts;
-CERT_GetOCSPResponseStatus;
-CERT_GetOCSPStatusForCertID;
-CERT_IsUserCert;
-CERT_RemoveCertListNode;
-CERT_VerifyCACertForUsage;
-CERT_VerifyCertificate;
-CERT_VerifyCertificateNow;
-CERT_VerifyOCSPResponseSignature;
-PK11_ConvertSessionPrivKeyToTokenPrivKey;
-PK11_ConvertSessionSymKeyToTokenSymKey;
-PK11_GetModInfo;
-PK11_GetPBEIV;
-PK11_ImportCRL;
-PK11_ImportDERCert;
-PK11_PubUnwrapSymKeyWithFlags;
-PK11_SaveContextAlloc;
-PK11_TokenKeyGen;
-SEC_QuickDERDecodeItem;
-SECKEY_CopyPublicKey;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.7 { # NSS 3.7 release
-;+ global:
-CERT_CRLCacheRefreshIssuer;
-CERT_DestroyOCSPResponse;
-CERT_EncodeAltNameExtension;
-CERT_FindCertBySubjectKeyID;
-CERT_FindSubjectKeyIDExtension;
-CERT_GetFirstEmailAddress;
-CERT_GetNextEmailAddress;
-CERT_VerifySignedDataWithPublicKey;
-CERT_VerifySignedDataWithPublicKeyInfo;
-PK11_WaitForTokenEvent;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.7.1 { # NSS 3.7.1 release
-;+ global:
-PK11_TokenRefresh;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.8 { # NSS 3.8 release
-;+ global:
-CERT_IsRootDERCert;
-HASH_GetHashObjectByOidTag;
-HASH_GetHashTypeByOidTag;
-PK11_GetDefaultArray;
-PK11_GetDefaultFlags;
-PK11_GetDisabledReason;
-PK11_UpdateSlotAttribute;
-PK11_UserEnableSlot;
-PK11_UserDisableSlot;
-SECITEM_ItemsAreEqual;
-SECKEY_CreateECPrivateKey;
-SECKEY_PublicKeyStrengthInBits;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.9 { # NSS 3.9 release
-;+ global:
-CERT_DestroyOidSequence;
-CERT_GetOidString;
-;;CERT_TimeChoiceTemplate DATA ;
-DER_DecodeTimeChoice;
-DER_EncodeTimeChoice;
-DSAU_DecodeDerSigToLen;
-DSAU_EncodeDerSigWithLen;
-NSS_Get_CERT_TimeChoiceTemplate;
-PK11_DeriveWithFlagsPerm;
-PK11_ExportEncryptedPrivKeyInfo;
-PK11_FindSlotsByNames;
-PK11_GetSymKeyType;
-PK11_MoveSymKey;
-PK11_PubDeriveWithKDF;
-PK11_PubUnwrapSymKeyWithFlagsPerm;
-PK11_UnwrapSymKeyWithFlagsPerm;
-SECITEM_ArenaDupItem;
-SECMOD_GetDBModuleList;
-SECMOD_GetDeadModuleList;
-SEC_ASN1DecoderAbort;
-SEC_ASN1EncoderAbort;
-SEC_DupCrl;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.9.2 { # NSS 3.9.2 release
-;+ global:
-NSS_IsInitialized;
-PK11_DestroyGenericObject;
-PK11_DestroyGenericObjects;
-PK11_FindGenericObjects;
-PK11_GetNextGenericObject;
-PK11_GetPrevGenericObject;
-PK11_LinkGenericObject;
-PK11_ReadRawAttribute;
-PK11_UnlinkGenericObject;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.9.3 { # NSS 3.9.3 release
-;+ global:
-PK11_GetCertFromPrivateKey;
-PK11_PrivDecryptPKCS1;
-PK11_PubEncryptPKCS1;
-SECMOD_CancelWait;
-SECMOD_HasRemovableSlots;
-SECMOD_UpdateSlotList;
-SECMOD_WaitForAnyTokenEvent;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.10 { # NSS 3.10 release
-;+ global:
-CERT_CacheCRL;
-CERT_DecodeAltNameExtension;
-CERT_DecodeAuthInfoAccessExtension;
-CERT_DecodeAuthKeyID;
-CERT_DecodeCRLDistributionPoints;
-CERT_DecodeNameConstraintsExtension;
-CERT_DecodePrivKeyUsagePeriodExtension;
-CERT_DestroyUserNotice;
-CERT_FinishCertificateRequestAttributes;
-CERT_GetCertificateNames;
-CERT_GetCertificateRequestExtensions;
-CERT_GetNextGeneralName;
-CERT_GetNextNameConstraint;
-CERT_GetPrevGeneralName;
-CERT_GetPrevNameConstraint;
-CERT_MergeExtensions;
-CERT_StartCertificateRequestAttributes;
-CERT_StartCRLEntryExtensions;
-CERT_StartCRLExtensions;
-CERT_UncacheCRL;
-HASH_Clone;
-HASH_HashBuf;
-HASH_ResultLenByOidTag;
-HASH_ResultLenContext;
-SEC_GetSignatureAlgorithmOidTag;
-SECKEY_CacheStaticFlags;
-SECOID_AddEntry;
-;+#
-;+# Data objects
-;+#
-;+# Don't export these DATA symbols on Windows because they don't work right.
-;+# Use the SEC_ASN1_GET / SEC_ASN1_SUB / SEC_ASN1_XTRN macros to access them.
-;;CERT_SequenceOfCertExtensionTemplate DATA ;
-;;CERT_SignedCrlTemplate DATA ;
-NSS_Get_CERT_SequenceOfCertExtensionTemplate;
-NSS_Get_CERT_SignedCrlTemplate;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.10.2 { # NSS 3.10.2 release
-;+ global:
-PK11_TokenKeyGenWithFlags;
-PK11_GenerateKeyPairWithFlags;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.11 { # NSS 3.11 release
-;+ global:
-CERT_CompareValidityTimes;
-PK11_CopyTokenPrivKeyToSessionPrivKey;
-PK11_FreeSlotListElement;
-PK11_GenerateRandomOnSlot;
-PK11_GetSymKeyUserData;
-PK11_MapSignKeyType;
-PK11_SetSymKeyUserData;
-SECMOD_CloseUserDB;
-SECMOD_HasRootCerts;
-SECMOD_OpenUserDB;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.11.1 {
-;+ global:
-NSS_RegisterShutdown;
-NSS_UnregisterShutdown;
-SEC_ASN1EncodeUnsignedInteger;
-SEC_RegisterDefaultHttpClient;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.11.2 {
-;+ global:
-SECKEY_SignatureLen;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.11.7 {
-;+ global:
-CERT_SetOCSPFailureMode;
-CERT_OCSPCacheSettings;
-CERT_ClearOCSPCache;
-DER_GeneralizedDayToAscii;
-DER_TimeChoiceDayToAscii;
-DER_TimeToGeneralizedTime;
-DER_TimeToGeneralizedTimeArena;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.11.9 {
-;+ global:
-PK11_UnconfigurePKCS11;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12 { # NSS 3.12 release
-;+ global:
-CERT_CheckNameSpace;
-CERT_EncodeCertPoliciesExtension;
-CERT_EncodeInfoAccessExtension;
-CERT_EncodeInhibitAnyExtension;
-CERT_EncodeNoticeReference;
-CERT_EncodePolicyConstraintsExtension;
-CERT_EncodePolicyMappingExtension;
-CERT_EncodeSubjectKeyID;
-CERT_EncodeUserNotice;
-CERT_FindCRLEntryReasonExten;
-CERT_FindCRLNumberExten;
-CERT_FindNameConstraintsExten;
-CERT_GetClassicOCSPDisabledPolicy;
-CERT_GetClassicOCSPEnabledHardFailurePolicy;
-CERT_GetClassicOCSPEnabledSoftFailurePolicy;
-CERT_GetPKIXVerifyNistRevocationPolicy;
-CERT_GetUsePKIXForValidation;
-CERT_GetValidDNSPatternsFromCert;
-CERT_NewTempCertificate;
-CERT_SetOCSPTimeout;
-CERT_SetUsePKIXForValidation;
-CERT_PKIXVerifyCert;
-HASH_GetType;
-NSS_InitWithMerge;
-PK11_CreateMergeLog;
-PK11_CreateGenericObject;
-PK11_CreatePBEV2AlgorithmID;
-PK11_DestroyMergeLog;
-PK11_GenerateKeyPairWithOpFlags;
-PK11_GetAllSlotsForCert;
-PK11_GetPBECryptoMechanism;
-PK11_IsRemovable;
-PK11_MergeTokens;
-PK11_WriteRawAttribute;
-SECKEY_ECParamsToBasePointOrderLen;
-SECKEY_ECParamsToKeySize;
-SECMOD_DeleteModuleEx;
-SEC_GetRegisteredHttpClient;
-SEC_PKCS5IsAlgorithmPBEAlgTag;
-VFY_CreateContextDirect;
-VFY_CreateContextWithAlgorithmID;
-VFY_VerifyDataDirect;
-VFY_VerifyDataWithAlgorithmID;
-VFY_VerifyDigestDirect;
-VFY_VerifyDigestWithAlgorithmID;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.1 { # NSS 3.12.1 release
-;+ global:
-CERT_NameToAsciiInvertible;
-PK11_FindCertFromDERCertItem;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.3 { # NSS 3.12.3 release
-;+ global:
-CERT_CompareCerts;
-CERT_RegisterAlternateOCSPAIAInfoCallBack;
-PK11_GetSymKeyHandle;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.4 { # NSS 3.12.4 release
-;+ global:
-PK11_IsInternalKeySlot;
-SECMOD_OpenNewSlot;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.5 { # NSS 3.12.5 release
-;+ global:
-CERT_AddCertToListSorted;
-NSS_InitContext;
-NSS_ShutdownContext;
-SECMOD_GetDefaultModDBFlag;
-SECMOD_GetSkipFirstFlag;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.6 { # NSS 3.12.6 release
-;+ global:
-CERT_CacheOCSPResponseFromSideChannel;
-CERT_DistNamesFromCertList;
-CERT_DupDistNames;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.7 { # NSS 3.12.7 release
-;+ global:
-CERT_GetConstrainedCertificateNames;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.9 { # NSS 3.12.9 release
-;+ global:
-CERT_FindCertByNicknameOrEmailAddrForUsage;
-PK11_DeriveWithTemplate;
-PK11_FindCertsFromEmailAddress;
-PK11_KeyGenWithTemplate;
-SECMOD_RestartModules;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.10 { # NSS 3.12.10 release
-;+ global:
-CERT_AllocCERTRevocationFlags;
-CERT_DestroyCERTRevocationFlags;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.13 { # NSS 3.13 release
-;+ global:
-;;SECKEY_RSAPSSParamsTemplate DATA ;
-NSS_Get_SECKEY_RSAPSSParamsTemplate;
-NSS_GetVersion;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.13.2 { # NSS 3.13.2 release
-;+ global:
-PK11_ImportEncryptedPrivateKeyInfoAndReturnKey;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.14 { # NSS 3.14 release
-;+ global:
-CERT_CheckOCSPStatus;
-CERT_DecodeOCSPRequest;
-CERT_GetEncodedOCSPResponse;
-PK11_GetBestSlotWithAttributes;
-PK11_GetBestSlotMultipleWithAttributes;
-PK11_PQG_ParamGenV2;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.14.1 { # NSS 3.14.1 release
-;+ global:
-CERT_CreateEncodedOCSPErrorResponse;
-CERT_CreateEncodedOCSPSuccessResponse;
-CERT_CreateOCSPSingleResponseGood;
-CERT_CreateOCSPSingleResponseUnknown;
-CERT_CreateOCSPSingleResponseRevoked;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.14.3 { # NSS 3.14.3 release
-;+ global:
-PK11_SignWithSymKey;
-;+ local:
-;+ *;
-;+};
diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h
deleted file mode 100644
index ef39fcc18..000000000
--- a/security/nss/lib/nss/nss.h
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * NSS utility functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef __nss_h_
-#define __nss_h_
-
-/* The private macro _NSS_ECC_STRING is for NSS internal use only. */
-#ifdef NSS_ENABLE_ECC
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
-#define _NSS_ECC_STRING " Extended ECC"
-#else
-#define _NSS_ECC_STRING " Basic ECC"
-#endif
-#else
-#define _NSS_ECC_STRING ""
-#endif
-
-/* The private macro _NSS_CUSTOMIZED is for NSS internal use only. */
-#if defined(NSS_ALLOW_UNSUPPORTED_CRITICAL)
-#define _NSS_CUSTOMIZED " (Customized build)"
-#else
-#define _NSS_CUSTOMIZED
-#endif
-
-/*
- * NSS's major version, minor version, patch level, build number, and whether
- * this is a beta release.
- *
- * The format of the version string should be
- * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
- */
-#define NSS_VERSION "3.14.4.0" _NSS_ECC_STRING _NSS_CUSTOMIZED "Beta"
-#define NSS_VMAJOR 3
-#define NSS_VMINOR 14
-#define NSS_VPATCH 4
-#define NSS_VBUILD 0
-#define NSS_BETA PR_TRUE
-
-#ifndef RC_INVOKED
-
-#include "seccomon.h"
-
-typedef struct NSSInitParametersStr NSSInitParameters;
-
-/*
- * parameters used to initialize softoken. Mostly strings used to
- * internationalize softoken. Memory for the strings are owned by the caller,
- * who is free to free them once NSS_ContextInit returns. If the string
- * parameter is NULL (as opposed to empty, zero length), then the softoken
- * default is used. These are equivalent to the parameters for
- * PK11_ConfigurePKCS11().
- *
- * field names match their equivalent parameter names for softoken strings
- * documented at https://developer.mozilla.org/en/PKCS11_Module_Specs.
- *
- * minPWLen
- * Minimum password length in bytes.
- * manufacturerID
- * Override the default manufactureID value for the module returned in
- * the CK_INFO, CK_SLOT_INFO, and CK_TOKEN_INFO structures with an
- * internationalize string (UTF8). This value will be truncated at 32
- * bytes (not including the trailing NULL, partial UTF8 characters will be
- * dropped).
- * libraryDescription
- * Override the default libraryDescription value for the module returned in
- * the CK_INFO structure with an internationalize string (UTF8). This value
- * will be truncated at 32 bytes(not including the trailing NULL, partial
- * UTF8 characters will be dropped).
- * cryptoTokenDescription
- * Override the default label value for the internal crypto token returned
- * in the CK_TOKEN_INFO structure with an internationalize string (UTF8).
- * This value will be truncated at 32 bytes (not including the trailing
- * NULL, partial UTF8 characters will be dropped).
- * dbTokenDescription
- * Override the default label value for the internal DB token returned in
- * the CK_TOKEN_INFO structure with an internationalize string (UTF8). This
- * value will be truncated at 32 bytes (not including the trailing NULL,
- * partial UTF8 characters will be dropped).
- * FIPSTokenDescription
- * Override the default label value for the internal FIPS token returned in
- * the CK_TOKEN_INFO structure with an internationalize string (UTF8). This
- * value will be truncated at 32 bytes (not including the trailing NULL,
- * partial UTF8 characters will be dropped).
- * cryptoSlotDescription
- * Override the default slotDescription value for the internal crypto token
- * returned in the CK_SLOT_INFO structure with an internationalize string
- * (UTF8). This value will be truncated at 64 bytes (not including the
- * trailing NULL, partial UTF8 characters will be dropped).
- * dbSlotDescription
- * Override the default slotDescription value for the internal DB token
- * returned in the CK_SLOT_INFO structure with an internationalize string
- * (UTF8). This value will be truncated at 64 bytes (not including the
- * trailing NULL, partial UTF8 characters will be dropped).
- * FIPSSlotDescription
- * Override the default slotDecription value for the internal FIPS token
- * returned in the CK_SLOT_INFO structure with an internationalize string
- * (UTF8). This value will be truncated at 64 bytes (not including the
- * trailing NULL, partial UTF8 characters will be dropped).
- *
- */
-struct NSSInitParametersStr {
- unsigned int length; /* allow this structure to grow in the future,
- * must be set */
- PRBool passwordRequired;
- int minPWLen;
- char * manufactureID; /* variable names for strings match the */
- char * libraryDescription; /* parameter name in softoken */
- char * cryptoTokenDescription;
- char * dbTokenDescription;
- char * FIPSTokenDescription;
- char * cryptoSlotDescription;
- char * dbSlotDescription;
- char * FIPSSlotDescription;
-};
-
-
-SEC_BEGIN_PROTOS
-
-/*
- * Return a boolean that indicates whether the underlying library
- * will perform as the caller expects.
- *
- * The only argument is a string, which should be the version
- * identifier of the NSS library. That string will be compared
- * against a string that represents the actual build version of
- * the NSS library.
- */
-extern PRBool NSS_VersionCheck(const char *importedVersion);
-
-/*
- * Returns a const string of the NSS library version.
- */
-extern const char *NSS_GetVersion(void);
-
-/*
- * Open the Cert, Key, and Security Module databases, read only.
- * Initialize the Random Number Generator.
- * Does not initialize the cipher policies or enables.
- * Default policy settings disallow all ciphers.
- */
-extern SECStatus NSS_Init(const char *configdir);
-
-/*
- * Returns whether NSS has already been initialized or not.
- */
-extern PRBool NSS_IsInitialized(void);
-
-/*
- * Open the Cert, Key, and Security Module databases, read/write.
- * Initialize the Random Number Generator.
- * Does not initialize the cipher policies or enables.
- * Default policy settings disallow all ciphers.
- */
-extern SECStatus NSS_InitReadWrite(const char *configdir);
-
-/*
- * Open the Cert, Key, and Security Module databases, read/write.
- * Initialize the Random Number Generator.
- * Does not initialize the cipher policies or enables.
- * Default policy settings disallow all ciphers.
- *
- * This allows using application defined prefixes for the cert and key db's
- * and an alternate name for the secmod database. NOTE: In future releases,
- * the database prefixes my not necessarily map to database names.
- *
- * configdir - base directory where all the cert, key, and module datbases live.
- * certPrefix - prefix added to the beginning of the cert database example: "
- * "https-server1-"
- * keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
- * secmodName - name of the security module database (usually "secmod.db").
- * flags - change the open options of NSS_Initialize as follows:
- * NSS_INIT_READONLY - Open the databases read only.
- * NSS_INIT_NOCERTDB - Don't open the cert DB and key DB's, just
- * initialize the volatile certdb.
- * NSS_INIT_NOMODDB - Don't open the security module DB, just
- * initialize the PKCS #11 module.
- * NSS_INIT_FORCEOPEN - Continue to force initializations even if the
- * databases cannot be opened.
- * NSS_INIT_NOROOTINIT - Don't try to look for the root certs module
- * automatically.
- * NSS_INIT_OPTIMIZESPACE - Use smaller tables and caches.
- * NSS_INIT_PK11THREADSAFE - only load PKCS#11 modules that are
- * thread-safe, ie. that support locking - either OS
- * locking or NSS-provided locks . If a PKCS#11
- * module isn't thread-safe, don't serialize its
- * calls; just don't load it instead. This is necessary
- * if another piece of code is using the same PKCS#11
- * modules that NSS is accessing without going through
- * NSS, for example the Java SunPKCS11 provider.
- * NSS_INIT_PK11RELOAD - ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED
- * error when loading PKCS#11 modules. This is necessary
- * if another piece of code is using the same PKCS#11
- * modules that NSS is accessing without going through
- * NSS, for example Java SunPKCS11 provider.
- * NSS_INIT_NOPK11FINALIZE - never call C_Finalize on any
- * PKCS#11 module. This may be necessary in order to
- * ensure continuous operation and proper shutdown
- * sequence if another piece of code is using the same
- * PKCS#11 modules that NSS is accessing without going
- * through NSS, for example Java SunPKCS11 provider.
- * The following limitation applies when this is set :
- * SECMOD_WaitForAnyTokenEvent will not use
- * C_WaitForSlotEvent, in order to prevent the need for
- * C_Finalize. This call will be emulated instead.
- * NSS_INIT_RESERVED - Currently has no effect, but may be used in the
- * future to trigger better cooperation between PKCS#11
- * modules used by both NSS and the Java SunPKCS11
- * provider. This should occur after a new flag is defined
- * for C_Initialize by the PKCS#11 working group.
- * NSS_INIT_COOPERATE - Sets 4 recommended options for applications that
- * use both NSS and the Java SunPKCS11 provider.
- *
- * Also NOTE: This is not the recommended method for initializing NSS.
- * The preferred method is NSS_init().
- */
-#define NSS_INIT_READONLY 0x1
-#define NSS_INIT_NOCERTDB 0x2
-#define NSS_INIT_NOMODDB 0x4
-#define NSS_INIT_FORCEOPEN 0x8
-#define NSS_INIT_NOROOTINIT 0x10
-#define NSS_INIT_OPTIMIZESPACE 0x20
-#define NSS_INIT_PK11THREADSAFE 0x40
-#define NSS_INIT_PK11RELOAD 0x80
-#define NSS_INIT_NOPK11FINALIZE 0x100
-#define NSS_INIT_RESERVED 0x200
-
-#define NSS_INIT_COOPERATE NSS_INIT_PK11THREADSAFE | \
- NSS_INIT_PK11RELOAD | \
- NSS_INIT_NOPK11FINALIZE | \
- NSS_INIT_RESERVED
-
-#define SECMOD_DB "secmod.db"
-
-typedef struct NSSInitContextStr NSSInitContext;
-
-
-extern SECStatus NSS_Initialize(const char *configdir,
- const char *certPrefix, const char *keyPrefix,
- const char *secmodName, PRUint32 flags);
-
-extern NSSInitContext *NSS_InitContext(const char *configdir,
- const char *certPrefix, const char *keyPrefix,
- const char *secmodName, NSSInitParameters *initParams, PRUint32 flags);
-
-extern SECStatus NSS_ShutdownContext(NSSInitContext *);
-
-/*
- * same as NSS_Init, but checks to see if we need to merge an
- * old database in.
- * updatedir is the directory where the old database lives.
- * updCertPrefix is the certPrefix for the old database.
- * updKeyPrefix is the keyPrefix for the old database.
- * updateID is a unique identifier chosen by the application for
- * the specific database.
- * updatName is the name the user will be prompted for when
- * asking to authenticate to the old database */
-extern SECStatus NSS_InitWithMerge(const char *configdir,
- const char *certPrefix, const char *keyPrefix, const char *secmodName,
- const char *updatedir, const char *updCertPrefix,
- const char *updKeyPrefix, const char *updateID,
- const char *updateName, PRUint32 flags);
-/*
- * initialize NSS without a creating cert db's, key db's, or secmod db's.
- */
-SECStatus NSS_NoDB_Init(const char *configdir);
-
-/*
- * Allow applications and libraries to register with NSS so that they are called
- * when NSS shuts down.
- *
- * void *appData application specific data passed in by the application at
- * NSS_RegisterShutdown() time.
- * void *nssData is NULL in this release, but is reserved for future versions of
- * NSS to pass some future status information * back to the shutdown function.
- *
- * If the shutdown function returns SECFailure,
- * Shutdown will still complete, but NSS_Shutdown() will return SECFailure.
- */
-typedef SECStatus (*NSS_ShutdownFunc)(void *appData, void *nssData);
-
-/*
- * Register a shutdown function.
- */
-SECStatus NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData);
-
-/*
- * Remove an existing shutdown function (you may do this if your library is
- * complete and going away, but NSS is still running).
- */
-SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData);
-
-/*
- * Close the Cert, Key databases.
- */
-extern SECStatus NSS_Shutdown(void);
-
-/*
- * set the PKCS #11 strings for the internal token.
- */
-void PK11_ConfigurePKCS11(const char *man, const char *libdesc,
- const char *tokdesc, const char *ptokdesc, const char *slotdesc,
- const char *pslotdesc, const char *fslotdesc, const char *fpslotdesc,
- int minPwd, int pwRequired);
-
-/*
- * Dump the contents of the certificate cache and the temporary cert store.
- * Use to detect leaked references of certs at shutdown time.
- */
-void nss_DumpCertificateCacheInfo(void);
-
-SEC_END_PROTOS
-
-#endif /* RC_INVOKED */
-#endif /* __nss_h_ */
diff --git a/security/nss/lib/nss/nss.rc b/security/nss/lib/nss/nss.rc
deleted file mode 100644
index 6b6fd5f46..000000000
--- a/security/nss/lib/nss/nss.rc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nss.h"
-#include <winver.h>
-
-#define MY_LIBNAME "nss"
-#define MY_FILEDESCRIPTION "NSS Base Library"
-
-#define STRINGIZE(x) #x
-#define STRINGIZE2(x) STRINGIZE(x)
-#define NSS_VMAJOR_STR STRINGIZE2(NSS_VMAJOR)
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if NSS_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME NSS_VMAJOR_STR
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
- PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Mozilla Foundation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", NSS_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", NSS_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c
deleted file mode 100644
index b22fc7d5c..000000000
--- a/security/nss/lib/nss/nssinit.c
+++ /dev/null
@@ -1,1301 +0,0 @@
-/*
- * NSS utility functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <ctype.h>
-#include <string.h>
-#include "seccomon.h"
-#include "prerror.h"
-#include "prinit.h"
-#include "prprf.h"
-#include "prmem.h"
-#include "prtypes.h"
-#include "cert.h"
-#include "key.h"
-#include "secmod.h"
-#include "secoid.h"
-#include "nss.h"
-#include "pk11func.h"
-#include "secerr.h"
-#include "nssbase.h"
-#include "nssutil.h"
-#include "pkixt.h"
-#include "pkix.h"
-#include "pkix_tools.h"
-
-#include "pki3hack.h"
-#include "certi.h"
-#include "secmodi.h"
-#include "ocspti.h"
-#include "ocspi.h"
-#include "utilpars.h"
-
-/*
- * On Windows nss3.dll needs to export the symbol 'mktemp' to be
- * fully backward compatible with the nss3.dll in NSS 3.2.x and
- * 3.3.x. This symbol was unintentionally exported and its
- * definition (in DBM) was moved from nss3.dll to softokn3.dll
- * in NSS 3.4. See bug 142575.
- */
-#ifdef WIN32_NSS3_DLL_COMPAT
-#include <io.h>
-
-/* exported as 'mktemp' */
-char *
-nss_mktemp(char *path)
-{
- return _mktemp(path);
-}
-#endif
-
-#define NSS_MAX_FLAG_SIZE sizeof("readOnly")+sizeof("noCertDB")+ \
- sizeof("noModDB")+sizeof("forceOpen")+sizeof("passwordRequired")+ \
- sizeof ("optimizeSpace")
-#define NSS_DEFAULT_MOD_NAME "NSS Internal Module"
-
-static char *
-nss_makeFlags(PRBool readOnly, PRBool noCertDB,
- PRBool noModDB, PRBool forceOpen,
- PRBool passwordRequired, PRBool optimizeSpace)
-{
- char *flags = (char *)PORT_Alloc(NSS_MAX_FLAG_SIZE);
- PRBool first = PR_TRUE;
-
- PORT_Memset(flags,0,NSS_MAX_FLAG_SIZE);
- if (readOnly) {
- PORT_Strcat(flags,"readOnly");
- first = PR_FALSE;
- }
- if (noCertDB) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"noCertDB");
- first = PR_FALSE;
- }
- if (noModDB) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"noModDB");
- first = PR_FALSE;
- }
- if (forceOpen) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"forceOpen");
- first = PR_FALSE;
- }
- if (passwordRequired) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"passwordRequired");
- first = PR_FALSE;
- }
- if (optimizeSpace) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"optimizeSpace");
- first = PR_FALSE;
- }
- return flags;
-}
-
-
-/*
- * build config string from individual internationalized strings
- */
-char *
-nss_MkConfigString(const char *man, const char *libdesc, const char *tokdesc,
- const char *ptokdesc, const char *slotdesc, const char *pslotdesc,
- const char *fslotdesc, const char *fpslotdesc, int minPwd)
-{
- char *strings = NULL;
- char *newStrings;
-
- /* make sure the internationalization was done correctly... */
- strings = PR_smprintf("");
- if (strings == NULL) return NULL;
-
- if (man) {
- newStrings = PR_smprintf("%s manufacturerID='%s'",strings,man);
- PR_smprintf_free(strings);
- strings = newStrings;
- }
- if (strings == NULL) return NULL;
-
- if (libdesc) {
- newStrings = PR_smprintf("%s libraryDescription='%s'",strings,libdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
- }
- if (strings == NULL) return NULL;
-
- if (tokdesc) {
- newStrings = PR_smprintf("%s cryptoTokenDescription='%s'",strings,
- tokdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
- }
- if (strings == NULL) return NULL;
-
- if (ptokdesc) {
- newStrings = PR_smprintf("%s dbTokenDescription='%s'",strings,ptokdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
- }
- if (strings == NULL) return NULL;
-
- if (slotdesc) {
- newStrings = PR_smprintf("%s cryptoSlotDescription='%s'",strings,
- slotdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
- }
- if (strings == NULL) return NULL;
-
- if (pslotdesc) {
- newStrings = PR_smprintf("%s dbSlotDescription='%s'",strings,pslotdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
- }
- if (strings == NULL) return NULL;
-
- if (fslotdesc) {
- newStrings = PR_smprintf("%s FIPSSlotDescription='%s'",
- strings,fslotdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
- }
- if (strings == NULL) return NULL;
-
- if (fpslotdesc) {
- newStrings = PR_smprintf("%s FIPSTokenDescription='%s'",
- strings,fpslotdesc);
- PR_smprintf_free(strings);
- strings = newStrings;
- }
- if (strings == NULL) return NULL;
-
- newStrings = PR_smprintf("%s minPS=%d", strings, minPwd);
- PR_smprintf_free(strings);
- strings = newStrings;
-
- return(strings);
-}
-
-/*
- * statics to remember the PK11_ConfigurePKCS11()
- * info.
- */
-static char * pk11_config_strings = NULL;
-static char * pk11_config_name = NULL;
-static PRBool pk11_password_required = PR_FALSE;
-
-/*
- * this is a legacy configuration function which used to be part of
- * the PKCS #11 internal token.
- */
-void
-PK11_ConfigurePKCS11(const char *man, const char *libdesc, const char *tokdesc,
- const char *ptokdesc, const char *slotdesc, const char *pslotdesc,
- const char *fslotdesc, const char *fpslotdesc, int minPwd,
- int pwRequired)
-{
- char * strings;
-
- strings = nss_MkConfigString(man,libdesc,tokdesc,ptokdesc,slotdesc,
- pslotdesc,fslotdesc,fpslotdesc,minPwd);
- if (strings == NULL) {
- return;
- }
-
- if (libdesc) {
- if (pk11_config_name != NULL) {
- PORT_Free(pk11_config_name);
- }
- pk11_config_name = PORT_Strdup(libdesc);
- }
-
- if (pk11_config_strings != NULL) {
- PR_smprintf_free(pk11_config_strings);
- }
- pk11_config_strings = strings;
- pk11_password_required = pwRequired;
-
- return;
-}
-
-void PK11_UnconfigurePKCS11(void)
-{
- if (pk11_config_strings != NULL) {
- PR_smprintf_free(pk11_config_strings);
- pk11_config_strings = NULL;
- }
- if (pk11_config_name) {
- PORT_Free(pk11_config_name);
- pk11_config_name = NULL;
- }
-}
-
-/*
- * The following code is an attempt to automagically find the external root
- * module.
- * Note: Keep the #if-defined chunks in order. HPUX must select before UNIX.
- */
-
-static const char *dllname =
-#if defined(XP_WIN32) || defined(XP_OS2)
- "nssckbi.dll";
-#elif defined(HPUX) && !defined(__ia64) /* HP-UX PA-RISC */
- "libnssckbi.sl";
-#elif defined(DARWIN)
- "libnssckbi.dylib";
-#elif defined(XP_UNIX) || defined(XP_BEOS)
- "libnssckbi.so";
-#else
- #error "Uh! Oh! I don't know about this platform."
-#endif
-
-/* Should we have platform ifdefs here??? */
-#define FILE_SEP '/'
-
-static void nss_FindExternalRootPaths(const char *dbpath,
- const char* secmodprefix,
- char** retoldpath, char** retnewpath)
-{
- char *path, *oldpath = NULL, *lastsep;
- int len, path_len, secmod_len, dll_len;
-
- path_len = PORT_Strlen(dbpath);
- secmod_len = secmodprefix ? PORT_Strlen(secmodprefix) : 0;
- dll_len = PORT_Strlen(dllname);
- len = path_len + secmod_len + dll_len + 2; /* FILE_SEP + NULL */
-
- path = PORT_Alloc(len);
- if (path == NULL) return;
-
- /* back up to the top of the directory */
- PORT_Memcpy(path,dbpath,path_len);
- if (path[path_len-1] != FILE_SEP) {
- path[path_len++] = FILE_SEP;
- }
- PORT_Strcpy(&path[path_len],dllname);
- if (secmod_len > 0) {
- lastsep = PORT_Strrchr(secmodprefix, FILE_SEP);
- if (lastsep) {
- int secmoddir_len = lastsep-secmodprefix+1; /* FILE_SEP */
- oldpath = PORT_Alloc(len);
- if (oldpath == NULL) {
- PORT_Free(path);
- return;
- }
- PORT_Memcpy(oldpath,path,path_len);
- PORT_Memcpy(&oldpath[path_len],secmodprefix,secmoddir_len);
- PORT_Strcpy(&oldpath[path_len+secmoddir_len],dllname);
- }
- }
- *retoldpath = oldpath;
- *retnewpath = path;
- return;
-}
-
-static void nss_FreeExternalRootPaths(char* oldpath, char* path)
-{
- if (path) {
- PORT_Free(path);
- }
- if (oldpath) {
- PORT_Free(oldpath);
- }
-}
-
-static void
-nss_FindExternalRoot(const char *dbpath, const char* secmodprefix)
-{
- char *path = NULL;
- char *oldpath = NULL;
- PRBool hasrootcerts = PR_FALSE;
-
- /*
- * 'oldpath' is the external root path in NSS 3.3.x or older.
- * For backward compatibility we try to load the root certs
- * module with the old path first.
- */
- nss_FindExternalRootPaths(dbpath, secmodprefix, &oldpath, &path);
- if (oldpath) {
- (void) SECMOD_AddNewModule("Root Certs",oldpath, 0, 0);
- hasrootcerts = SECMOD_HasRootCerts();
- }
- if (path && !hasrootcerts) {
- (void) SECMOD_AddNewModule("Root Certs",path, 0, 0);
- }
- nss_FreeExternalRootPaths(oldpath, path);
- return;
-}
-
-/*
- * see nss_Init for definitions of the various options.
- *
- * this function builds a moduleSpec string from the options and previously
- * set statics (from PKCS11_Configure, for instance), and uses it to kick off
- * the loading of the various PKCS #11 modules.
- */
-static SECStatus
-nss_InitModules(const char *configdir, const char *certPrefix,
- const char *keyPrefix, const char *secmodName,
- const char *updateDir, const char *updCertPrefix,
- const char *updKeyPrefix, const char *updateID,
- const char *updateName, char *configName, char *configStrings,
- PRBool pwRequired, PRBool readOnly, PRBool noCertDB,
- PRBool noModDB, PRBool forceOpen, PRBool optimizeSpace,
- PRBool isContextInit)
-{
- SECStatus rv = SECFailure;
- char *moduleSpec = NULL;
- char *flags = NULL;
- char *lconfigdir = NULL;
- char *lcertPrefix = NULL;
- char *lkeyPrefix = NULL;
- char *lsecmodName = NULL;
- char *lupdateDir = NULL;
- char *lupdCertPrefix = NULL;
- char *lupdKeyPrefix = NULL;
- char *lupdateID = NULL;
- char *lupdateName = NULL;
-
- if (NSS_InitializePRErrorTable() != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return rv;
- }
-
- flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen,
- pwRequired, optimizeSpace);
- if (flags == NULL) return rv;
-
- /*
- * configdir is double nested, and Windows uses the same character
- * for file seps as we use for escapes! (sigh).
- */
- lconfigdir = NSSUTIL_DoubleEscape(configdir, '\'', '\"');
- if (lconfigdir == NULL) {
- goto loser;
- }
- lcertPrefix = NSSUTIL_DoubleEscape(certPrefix, '\'', '\"');
- if (lcertPrefix == NULL) {
- goto loser;
- }
- lkeyPrefix = NSSUTIL_DoubleEscape(keyPrefix, '\'', '\"');
- if (lkeyPrefix == NULL) {
- goto loser;
- }
- lsecmodName = NSSUTIL_DoubleEscape(secmodName, '\'', '\"');
- if (lsecmodName == NULL) {
- goto loser;
- }
- lupdateDir = NSSUTIL_DoubleEscape(updateDir, '\'', '\"');
- if (lupdateDir == NULL) {
- goto loser;
- }
- lupdCertPrefix = NSSUTIL_DoubleEscape(updCertPrefix, '\'', '\"');
- if (lupdCertPrefix == NULL) {
- goto loser;
- }
- lupdKeyPrefix = NSSUTIL_DoubleEscape(updKeyPrefix, '\'', '\"');
- if (lupdKeyPrefix == NULL) {
- goto loser;
- }
- lupdateID = NSSUTIL_DoubleEscape(updateID, '\'', '\"');
- if (lupdateID == NULL) {
- goto loser;
- }
- lupdateName = NSSUTIL_DoubleEscape(updateName, '\'', '\"');
- if (lupdateName == NULL) {
- goto loser;
- }
-
- moduleSpec = PR_smprintf(
- "name=\"%s\" parameters=\"configdir='%s' certPrefix='%s' keyPrefix='%s' "
- "secmod='%s' flags=%s updatedir='%s' updateCertPrefix='%s' "
- "updateKeyPrefix='%s' updateid='%s' updateTokenDescription='%s' %s\" "
- "NSS=\"flags=internal,moduleDB,moduleDBOnly,critical%s\"",
- configName ? configName : NSS_DEFAULT_MOD_NAME,
- lconfigdir,lcertPrefix,lkeyPrefix,lsecmodName,flags,
- lupdateDir, lupdCertPrefix, lupdKeyPrefix, lupdateID,
- lupdateName, configStrings ? configStrings : "",
- isContextInit ? "" : ",defaultModDB,internalKeySlot");
-
-loser:
- PORT_Free(flags);
- if (lconfigdir) PORT_Free(lconfigdir);
- if (lcertPrefix) PORT_Free(lcertPrefix);
- if (lkeyPrefix) PORT_Free(lkeyPrefix);
- if (lsecmodName) PORT_Free(lsecmodName);
- if (lupdateDir) PORT_Free(lupdateDir);
- if (lupdCertPrefix) PORT_Free(lupdCertPrefix);
- if (lupdKeyPrefix) PORT_Free(lupdKeyPrefix);
- if (lupdateID) PORT_Free(lupdateID);
- if (lupdateName) PORT_Free(lupdateName);
-
- if (moduleSpec) {
- SECMODModule *module = SECMOD_LoadModule(moduleSpec,NULL,PR_TRUE);
- PR_smprintf_free(moduleSpec);
- if (module) {
- if (module->loaded) rv=SECSuccess;
- SECMOD_DestroyModule(module);
- }
- }
- return rv;
-}
-
-/*
- * OK there are now lots of options here, lets go through them all:
- *
- * configdir - base directory where all the cert, key, and module datbases live.
- * certPrefix - prefix added to the beginning of the cert database example: "
- * "https-server1-"
- * keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
- * secmodName - name of the security module database (usually "secmod.db").
- * updateDir - used in initMerge, old directory to update from.
- * updateID - used in initMerge, unique ID to represent the updated directory.
- * updateName - used in initMerge, token name when updating.
- * initContextPtr - used in initContext, pointer to return a unique context
- * value.
- * readOnly - Boolean: true if the databases are to be opened read only.
- * nocertdb - Don't open the cert DB and key DB's, just initialize the
- * Volatile certdb.
- * nomoddb - Don't open the security module DB, just initialize the
- * PKCS #11 module.
- * forceOpen - Continue to force initializations even if the databases cannot
- * be opened.
- * noRootInit - don't try to automatically load the root cert store if one is
- * not found.
- * optimizeSpace - tell NSS to use fewer hash table buckets.
- *
- * The next three options are used in an attempt to share PKCS #11 modules
- * with other loaded, running libraries. PKCS #11 was not designed with this
- * sort of sharing in mind, so use of these options may lead to questionable
- * results. These options are may be incompatible with NSS_LoadContext() calls.
- *
- * noSingleThreadedModules - don't load modules that are not thread safe (many
- * smart card tokens will not work).
- * allowAlreadyInitializedModules - if a module has already been loaded and
- * initialize try to use it.
- * don'tFinalizeModules - dont shutdown modules we may have loaded.
- */
-
-static PRBool nssIsInitted = PR_FALSE;
-static NSSInitContext *nssInitContextList = NULL;
-static void* plContext = NULL;
-
-struct NSSInitContextStr {
- NSSInitContext *next;
- PRUint32 magic;
-};
-
-#define NSS_INIT_MAGIC 0x1413A91C
-static SECStatus nss_InitShutdownList(void);
-
-#ifdef DEBUG
-static CERTCertificate dummyCert;
-#endif
-
-/* All initialized to zero in BSS */
-static PRCallOnceType nssInitOnce;
-static PZLock *nssInitLock;
-static PZCondVar *nssInitCondition;
-static int nssIsInInit;
-
-static PRStatus
-nss_doLockInit(void)
-{
- nssInitLock = PZ_NewLock(nssILockOther);
- if (nssInitLock == NULL) {
- return PR_FAILURE;
- }
- nssInitCondition = PZ_NewCondVar(nssInitLock);
- if (nssInitCondition == NULL) {
- return PR_FAILURE;
- }
- return PR_SUCCESS;
-}
-
-
-static SECStatus
-nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
- const char *secmodName, const char *updateDir,
- const char *updCertPrefix, const char *updKeyPrefix,
- const char *updateID, const char *updateName,
- NSSInitContext ** initContextPtr,
- NSSInitParameters *initParams,
- PRBool readOnly, PRBool noCertDB,
- PRBool noModDB, PRBool forceOpen, PRBool noRootInit,
- PRBool optimizeSpace, PRBool noSingleThreadedModules,
- PRBool allowAlreadyInitializedModules,
- PRBool dontFinalizeModules)
-{
- SECStatus rv = SECFailure;
- PKIX_UInt32 actualMinorVersion = 0;
- PKIX_Error *pkixError = NULL;
- PRBool isReallyInitted;
- char *configStrings = NULL;
- char *configName = NULL;
- PRBool passwordRequired = PR_FALSE;
-
- /* if we are trying to init with a traditional NSS_Init call, maintain
- * the traditional idempotent behavior. */
- if (!initContextPtr && nssIsInitted) {
- return SECSuccess;
- }
-
- /* make sure our lock and condition variable are initialized one and only
- * one time */
- if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
- }
-
- /*
- * if we haven't done basic initialization, single thread the
- * initializations.
- */
- PZ_Lock(nssInitLock);
- isReallyInitted = NSS_IsInitialized();
- if (!isReallyInitted) {
- while (!isReallyInitted && nssIsInInit) {
- PZ_WaitCondVar(nssInitCondition,PR_INTERVAL_NO_TIMEOUT);
- isReallyInitted = NSS_IsInitialized();
- }
- /* once we've completed basic initialization, we can allow more than
- * one process initialize NSS at a time. */
- }
- nssIsInInit++;
- PZ_Unlock(nssInitLock);
-
- /* this tells us whether or not some library has already initialized us.
- * if so, we don't want to double call some of the basic initialization
- * functions */
-
- if (!isReallyInitted) {
- /* New option bits must not change the size of CERTCertificate. */
- PORT_Assert(sizeof(dummyCert.options) == sizeof(void *));
-
- if (SECSuccess != cert_InitLocks()) {
- goto loser;
- }
-
- if (SECSuccess != InitCRLCache()) {
- goto loser;
- }
-
- if (SECSuccess != OCSP_InitGlobal()) {
- goto loser;
- }
- }
-
- if (noSingleThreadedModules || allowAlreadyInitializedModules ||
- dontFinalizeModules) {
- pk11_setGlobalOptions(noSingleThreadedModules,
- allowAlreadyInitializedModules,
- dontFinalizeModules);
- }
-
- if (initContextPtr) {
- *initContextPtr = PORT_ZNew(NSSInitContext);
- if (*initContextPtr == NULL) {
- goto loser;
- }
- /*
- * For traditional NSS_Init, we used the PK11_Configure() call to set
- * globals. with InitContext, we pass those strings in as parameters.
- *
- * This allows old NSS_Init calls to work as before, while at the same
- * time new calls and old calls will not interfere with each other.
- */
- if (initParams) {
- if (initParams->length < sizeof(NSSInitParameters)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
- }
- configStrings = nss_MkConfigString(initParams->manufactureID,
- initParams->libraryDescription,
- initParams->cryptoTokenDescription,
- initParams->dbTokenDescription,
- initParams->cryptoSlotDescription,
- initParams->dbSlotDescription,
- initParams->FIPSSlotDescription,
- initParams->FIPSTokenDescription,
- initParams->minPWLen);
- if (configStrings == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- configName = initParams->libraryDescription;
- passwordRequired = initParams->passwordRequired;
- }
- } else {
- configStrings = pk11_config_strings;
- configName = pk11_config_name;
- passwordRequired = pk11_password_required;
- }
-
- /* Skip the module init if we are already initted and we are trying
- * to init with noCertDB and noModDB */
- if (!(isReallyInitted && noCertDB && noModDB)) {
- rv = nss_InitModules(configdir, certPrefix, keyPrefix, secmodName,
- updateDir, updCertPrefix, updKeyPrefix, updateID,
- updateName, configName, configStrings, passwordRequired,
- readOnly, noCertDB, noModDB, forceOpen, optimizeSpace,
- (initContextPtr != NULL));
-
- if (rv != SECSuccess) {
- goto loser;
- }
- }
-
-
- /* finish up initialization */
- if (!isReallyInitted) {
- if (SECOID_Init() != SECSuccess) {
- goto loser;
- }
- if (STAN_LoadDefaultNSS3TrustDomain() != PR_SUCCESS) {
- goto loser;
- }
- if (nss_InitShutdownList() != SECSuccess) {
- goto loser;
- }
- CERT_SetDefaultCertDB((CERTCertDBHandle *)
- STAN_GetDefaultTrustDomain());
- if ((!noModDB) && (!noCertDB) && (!noRootInit)) {
- if (!SECMOD_HasRootCerts()) {
- const char *dbpath = configdir;
- /* handle supported database modifiers */
- if (strncmp(dbpath, "sql:", 4) == 0) {
- dbpath += 4;
- } else if(strncmp(dbpath, "dbm:", 4) == 0) {
- dbpath += 4;
- } else if(strncmp(dbpath, "extern:", 7) == 0) {
- dbpath += 7;
- } else if(strncmp(dbpath, "rdb:", 4) == 0) {
- /* if rdb: is specified, the configdir isn't really a
- * path. Skip it */
- dbpath = NULL;
- }
- if (dbpath) {
- nss_FindExternalRoot(dbpath, secmodName);
- }
- }
- }
-
- pk11sdr_Init();
- cert_CreateSubjectKeyIDHashTable();
-
- pkixError = PKIX_Initialize
- (PKIX_FALSE, PKIX_MAJOR_VERSION, PKIX_MINOR_VERSION,
- PKIX_MINOR_VERSION, &actualMinorVersion, &plContext);
-
- if (pkixError != NULL) {
- goto loser;
- } else {
- char *ev = getenv("NSS_ENABLE_PKIX_VERIFY");
- if (ev && ev[0]) {
- CERT_SetUsePKIXForValidation(PR_TRUE);
- }
- }
-
-
- }
-
- /*
- * Now mark the appropriate init state. If initContextPtr was passed
- * in, then return the new context pointer and add it to the
- * nssInitContextList. Otherwise set the global nss_isInitted flag
- */
- PZ_Lock(nssInitLock);
- if (!initContextPtr) {
- nssIsInitted = PR_TRUE;
- } else {
- (*initContextPtr)->magic = NSS_INIT_MAGIC;
- (*initContextPtr)->next = nssInitContextList;
- nssInitContextList = (*initContextPtr);
- }
- nssIsInInit--;
- /* now that we are inited, all waiters can move forward */
- PZ_NotifyAllCondVar(nssInitCondition);
- PZ_Unlock(nssInitLock);
-
- if (initContextPtr && configStrings) {
- PR_smprintf_free(configStrings);
- }
-
- return SECSuccess;
-
-loser:
- if (initContextPtr && *initContextPtr) {
- PORT_Free(*initContextPtr);
- *initContextPtr = NULL;
- if (configStrings) {
- PR_smprintf_free(configStrings);
- }
- }
- PZ_Lock(nssInitLock);
- nssIsInInit--;
- /* We failed to init, allow one to move forward */
- PZ_NotifyCondVar(nssInitCondition);
- PZ_Unlock(nssInitLock);
- return SECFailure;
-}
-
-
-SECStatus
-NSS_Init(const char *configdir)
-{
- return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", NULL,
- NULL, PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
- PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
-}
-
-SECStatus
-NSS_InitReadWrite(const char *configdir)
-{
- return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", NULL,
- NULL, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
- PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
-}
-
-/*
- * OK there are now lots of options here, lets go through them all:
- *
- * configdir - base directory where all the cert, key, and module datbases live.
- * certPrefix - prefix added to the beginning of the cert database example: "
- * "https-server1-"
- * keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
- * secmodName - name of the security module database (usually "secmod.db").
- * flags - change the open options of NSS_Initialize as follows:
- * NSS_INIT_READONLY - Open the databases read only.
- * NSS_INIT_NOCERTDB - Don't open the cert DB and key DB's, just
- * initialize the volatile certdb.
- * NSS_INIT_NOMODDB - Don't open the security module DB, just
- * initialize the PKCS #11 module.
- * NSS_INIT_FORCEOPEN - Continue to force initializations even if the
- * databases cannot be opened.
- * NSS_INIT_PK11THREADSAFE - only load PKCS#11 modules that are
- * thread-safe, ie. that support locking - either OS
- * locking or NSS-provided locks . If a PKCS#11
- * module isn't thread-safe, don't serialize its
- * calls; just don't load it instead. This is necessary
- * if another piece of code is using the same PKCS#11
- * modules that NSS is accessing without going through
- * NSS, for example the Java SunPKCS11 provider.
- * NSS_INIT_PK11RELOAD - ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED
- * error when loading PKCS#11 modules. This is necessary
- * if another piece of code is using the same PKCS#11
- * modules that NSS is accessing without going through
- * NSS, for example Java SunPKCS11 provider.
- * NSS_INIT_NOPK11FINALIZE - never call C_Finalize on any
- * PKCS#11 module. This may be necessary in order to
- * ensure continuous operation and proper shutdown
- * sequence if another piece of code is using the same
- * PKCS#11 modules that NSS is accessing without going
- * through NSS, for example Java SunPKCS11 provider.
- * The following limitation applies when this is set :
- * SECMOD_WaitForAnyTokenEvent will not use
- * C_WaitForSlotEvent, in order to prevent the need for
- * C_Finalize. This call will be emulated instead.
- * NSS_INIT_RESERVED - Currently has no effect, but may be used in the
- * future to trigger better cooperation between PKCS#11
- * modules used by both NSS and the Java SunPKCS11
- * provider. This should occur after a new flag is defined
- * for C_Initialize by the PKCS#11 working group.
- * NSS_INIT_COOPERATE - Sets 4 recommended options for applications that
- * use both NSS and the Java SunPKCS11 provider.
- */
-SECStatus
-NSS_Initialize(const char *configdir, const char *certPrefix,
- const char *keyPrefix, const char *secmodName, PRUint32 flags)
-{
- return nss_Init(configdir, certPrefix, keyPrefix, secmodName,
- "", "", "", "", "", NULL, NULL,
- ((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY),
- ((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB),
- ((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
- ((flags & NSS_INIT_FORCEOPEN) == NSS_INIT_FORCEOPEN),
- ((flags & NSS_INIT_NOROOTINIT) == NSS_INIT_NOROOTINIT),
- ((flags & NSS_INIT_OPTIMIZESPACE) == NSS_INIT_OPTIMIZESPACE),
- ((flags & NSS_INIT_PK11THREADSAFE) == NSS_INIT_PK11THREADSAFE),
- ((flags & NSS_INIT_PK11RELOAD) == NSS_INIT_PK11RELOAD),
- ((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE));
-}
-
-NSSInitContext *
-NSS_InitContext(const char *configdir, const char *certPrefix,
- const char *keyPrefix, const char *secmodName,
- NSSInitParameters *initParams, PRUint32 flags)
-{
- SECStatus rv;
- NSSInitContext *context;
-
- rv = nss_Init(configdir, certPrefix, keyPrefix, secmodName,
- "", "", "", "", "", &context, initParams,
- ((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY),
- ((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB),
- ((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
- ((flags & NSS_INIT_FORCEOPEN) == NSS_INIT_FORCEOPEN), PR_TRUE,
- ((flags & NSS_INIT_OPTIMIZESPACE) == NSS_INIT_OPTIMIZESPACE),
- ((flags & NSS_INIT_PK11THREADSAFE) == NSS_INIT_PK11THREADSAFE),
- ((flags & NSS_INIT_PK11RELOAD) == NSS_INIT_PK11RELOAD),
- ((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE));
- return (rv == SECSuccess) ? context : NULL;
-}
-
-SECStatus
-NSS_InitWithMerge(const char *configdir, const char *certPrefix,
- const char *keyPrefix, const char *secmodName,
- const char *updateDir, const char *updCertPrefix,
- const char *updKeyPrefix, const char *updateID,
- const char *updateName, PRUint32 flags)
-{
- return nss_Init(configdir, certPrefix, keyPrefix, secmodName,
- updateDir, updCertPrefix, updKeyPrefix, updateID, updateName,
- NULL, NULL,
- ((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY),
- ((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB),
- ((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
- ((flags & NSS_INIT_FORCEOPEN) == NSS_INIT_FORCEOPEN),
- ((flags & NSS_INIT_NOROOTINIT) == NSS_INIT_NOROOTINIT),
- ((flags & NSS_INIT_OPTIMIZESPACE) == NSS_INIT_OPTIMIZESPACE),
- ((flags & NSS_INIT_PK11THREADSAFE) == NSS_INIT_PK11THREADSAFE),
- ((flags & NSS_INIT_PK11RELOAD) == NSS_INIT_PK11RELOAD),
- ((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE));
-}
-
-/*
- * initialize NSS without a creating cert db's, key db's, or secmod db's.
- */
-SECStatus
-NSS_NoDB_Init(const char * configdir)
-{
- return nss_Init("","","","", "", "", "", "", "", NULL, NULL,
- PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,
- PR_FALSE,PR_FALSE,PR_FALSE);
-}
-
-
-#define NSS_SHUTDOWN_STEP 10
-
-struct NSSShutdownFuncPair {
- NSS_ShutdownFunc func;
- void *appData;
-};
-
-static struct NSSShutdownListStr {
- PZLock *lock;
- int allocatedFuncs;
- int peakFuncs;
- struct NSSShutdownFuncPair *funcs;
-} nssShutdownList = { 0 };
-
-/*
- * find and existing shutdown function
- */
-static int
-nss_GetShutdownEntry(NSS_ShutdownFunc sFunc, void *appData)
-{
- int count, i;
- count = nssShutdownList.peakFuncs;
-
- for (i=0; i < count; i++) {
- if ((nssShutdownList.funcs[i].func == sFunc) &&
- (nssShutdownList.funcs[i].appData == appData)){
- return i;
- }
- }
- return -1;
-}
-
-/*
- * register a callback to be called when NSS shuts down
- */
-SECStatus
-NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
-{
- int i;
-
- /* make sure our lock and condition variable are initialized one and only
- * one time */
- if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
- }
-
- PZ_Lock(nssInitLock);
- if (!NSS_IsInitialized()) {
- PZ_Unlock(nssInitLock);
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
- PZ_Unlock(nssInitLock);
- if (sFunc == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- PORT_Assert(nssShutdownList.lock);
- PZ_Lock(nssShutdownList.lock);
-
- /* make sure we don't have a duplicate */
- i = nss_GetShutdownEntry(sFunc, appData);
- if (i >= 0) {
- PZ_Unlock(nssShutdownList.lock);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- /* find an empty slot */
- i = nss_GetShutdownEntry(NULL, NULL);
- if (i >= 0) {
- nssShutdownList.funcs[i].func = sFunc;
- nssShutdownList.funcs[i].appData = appData;
- PZ_Unlock(nssShutdownList.lock);
- return SECSuccess;
- }
- if (nssShutdownList.allocatedFuncs == nssShutdownList.peakFuncs) {
- struct NSSShutdownFuncPair *funcs =
- (struct NSSShutdownFuncPair *)PORT_Realloc
- (nssShutdownList.funcs,
- (nssShutdownList.allocatedFuncs + NSS_SHUTDOWN_STEP)
- *sizeof(struct NSSShutdownFuncPair));
- if (!funcs) {
- PZ_Unlock(nssShutdownList.lock);
- return SECFailure;
- }
- nssShutdownList.funcs = funcs;
- nssShutdownList.allocatedFuncs += NSS_SHUTDOWN_STEP;
- }
- nssShutdownList.funcs[nssShutdownList.peakFuncs].func = sFunc;
- nssShutdownList.funcs[nssShutdownList.peakFuncs].appData = appData;
- nssShutdownList.peakFuncs++;
- PZ_Unlock(nssShutdownList.lock);
- return SECSuccess;
-}
-
-/*
- * unregister a callback so it won't get called on shutdown.
- */
-SECStatus
-NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
-{
- int i;
-
- /* make sure our lock and condition variable are initialized one and only
- * one time */
- if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
- }
- PZ_Lock(nssInitLock);
- if (!NSS_IsInitialized()) {
- PZ_Unlock(nssInitLock);
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
- PZ_Unlock(nssInitLock);
-
- PORT_Assert(nssShutdownList.lock);
- PZ_Lock(nssShutdownList.lock);
- i = nss_GetShutdownEntry(sFunc, appData);
- if (i >= 0) {
- nssShutdownList.funcs[i].func = NULL;
- nssShutdownList.funcs[i].appData = NULL;
- }
- PZ_Unlock(nssShutdownList.lock);
-
- if (i < 0) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * bring up and shutdown the shutdown list
- */
-static SECStatus
-nss_InitShutdownList(void)
-{
- if (nssShutdownList.lock != NULL) {
- return SECSuccess;
- }
- nssShutdownList.lock = PZ_NewLock(nssILockOther);
- if (nssShutdownList.lock == NULL) {
- return SECFailure;
- }
- nssShutdownList.funcs = PORT_ZNewArray(struct NSSShutdownFuncPair,
- NSS_SHUTDOWN_STEP);
- if (nssShutdownList.funcs == NULL) {
- PZ_DestroyLock(nssShutdownList.lock);
- nssShutdownList.lock = NULL;
- return SECFailure;
- }
- nssShutdownList.allocatedFuncs = NSS_SHUTDOWN_STEP;
- nssShutdownList.peakFuncs = 0;
-
- return SECSuccess;
-}
-
-static SECStatus
-nss_ShutdownShutdownList(void)
-{
- SECStatus rv = SECSuccess;
- int i;
-
- /* call all the registerd functions first */
- for (i=0; i < nssShutdownList.peakFuncs; i++) {
- struct NSSShutdownFuncPair *funcPair = &nssShutdownList.funcs[i];
- if (funcPair->func) {
- if ((*funcPair->func)(funcPair->appData,NULL) != SECSuccess) {
- rv = SECFailure;
- }
- }
- }
-
- nssShutdownList.peakFuncs = 0;
- nssShutdownList.allocatedFuncs = 0;
- PORT_Free(nssShutdownList.funcs);
- nssShutdownList.funcs = NULL;
- if (nssShutdownList.lock) {
- PZ_DestroyLock(nssShutdownList.lock);
- }
- nssShutdownList.lock = NULL;
- return rv;
-}
-
-
-extern const NSSError NSS_ERROR_BUSY;
-
-SECStatus
-nss_Shutdown(void)
-{
- SECStatus shutdownRV = SECSuccess;
- SECStatus rv;
- PRStatus status;
- NSSInitContext *temp;
-
- rv = nss_ShutdownShutdownList();
- if (rv != SECSuccess) {
- shutdownRV = SECFailure;
- }
- cert_DestroyLocks();
- ShutdownCRLCache();
- OCSP_ShutdownGlobal();
- PKIX_Shutdown(plContext);
- SECOID_Shutdown();
- status = STAN_Shutdown();
- cert_DestroySubjectKeyIDHashTable();
- pk11_SetInternalKeySlot(NULL);
- rv = SECMOD_Shutdown();
- if (rv != SECSuccess) {
- shutdownRV = SECFailure;
- }
- pk11sdr_Shutdown();
- /*
- * A thread's error stack is automatically destroyed when the thread
- * terminates, except for the primordial thread, whose error stack is
- * destroyed by PR_Cleanup. Since NSS is usually shut down by the
- * primordial thread and many NSS-based apps don't call PR_Cleanup,
- * we destroy the calling thread's error stack here.
- */
- nss_DestroyErrorStack();
- nssArena_Shutdown();
- if (status == PR_FAILURE) {
- if (NSS_GetError() == NSS_ERROR_BUSY) {
- PORT_SetError(SEC_ERROR_BUSY);
- }
- shutdownRV = SECFailure;
- }
- nssIsInitted = PR_FALSE;
- temp = nssInitContextList;
- nssInitContextList = NULL;
- /* free the old list. This is necessary when we are called from
- * NSS_Shutdown(). */
- while (temp) {
- NSSInitContext *next = temp->next;
- temp->magic = 0;
- PORT_Free(temp);
- temp = next;
- }
- return shutdownRV;
-}
-
-SECStatus
-NSS_Shutdown(void)
-{
- SECStatus rv;
- /* make sure our lock and condition variable are initialized one and only
- * one time */
- if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
- }
- PZ_Lock(nssInitLock);
-
- if (!nssIsInitted) {
- PZ_Unlock(nssInitLock);
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
-
- /* If one or more threads are in the middle of init, wait for them
- * to complete */
- while (nssIsInInit) {
- PZ_WaitCondVar(nssInitCondition,PR_INTERVAL_NO_TIMEOUT);
- }
- rv = nss_Shutdown();
- PZ_Unlock(nssInitLock);
- return rv;
-}
-
-/*
- * remove the context from a list. return true if found, false if not
- */
-PRBool
-nss_RemoveList(NSSInitContext *context) {
- NSSInitContext *this = nssInitContextList;
- NSSInitContext **last = &nssInitContextList;
-
- while (this) {
- if (this == context) {
- *last = this->next;
- this->magic = 0;
- PORT_Free(this);
- return PR_TRUE;
- }
- last = &this->next;
- this=this->next;
- }
- return PR_FALSE;
-}
-
-/*
- * This form of shutdown is safe in the case where we may have multiple
- * entities using NSS in a single process. Each entity calls shutdown with
- * it's own context. The application (which doesn't get a context), calls
- * shutdown with NULL. Once all users have 'checked in' NSS will shutdown.
- * This is different than NSS_Shutdown, where calling it will shutdown NSS
- * irreguardless of who else may have NSS open.
- */
-SECStatus
-NSS_ShutdownContext(NSSInitContext *context)
-{
- SECStatus rv = SECSuccess;
-
- /* make sure our lock and condition variable are initialized one and only
- * one time */
- if (PR_CallOnce(&nssInitOnce, nss_doLockInit) != PR_SUCCESS) {
- return SECFailure;
- }
- PZ_Lock(nssInitLock);
- /* If one or more threads are in the middle of init, wait for them
- * to complete */
- while (nssIsInInit) {
- PZ_WaitCondVar(nssInitCondition,PR_INTERVAL_NO_TIMEOUT);
- }
-
- /* OK, we are the only thread now either initializing or shutting down */
-
- if (!context) {
- if (!nssIsInitted) {
- PZ_Unlock(nssInitLock);
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
- nssIsInitted = 0;
- } else if (! nss_RemoveList(context)) {
- PZ_Unlock(nssInitLock);
- /* context was already freed or wasn't valid */
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
- if ((nssIsInitted == 0) && (nssInitContextList == NULL)) {
- rv = nss_Shutdown();
- }
-
- /* NOTE: we don't try to free the nssInitLocks to prevent races against
- * the locks. There may be a thread, right now, waiting in NSS_Init for us
- * to free the lock below. If we delete the locks, bad things would happen
- * to that thread */
- PZ_Unlock(nssInitLock);
-
- return rv;
-}
-
-PRBool
-NSS_IsInitialized(void)
-{
- return (nssIsInitted) || (nssInitContextList != NULL);
-}
-
-
-extern const char __nss_base_rcsid[];
-extern const char __nss_base_sccsid[];
-
-PRBool
-NSS_VersionCheck(const char *importedVersion)
-{
- /*
- * This is the secret handshake algorithm.
- *
- * This release has a simple version compatibility
- * check algorithm. This release is not backward
- * compatible with previous major releases. It is
- * not compatible with future major, minor, or
- * patch releases or builds.
- */
- int vmajor = 0, vminor = 0, vpatch = 0, vbuild = 0;
- const char *ptr = importedVersion;
- volatile char c; /* force a reference that won't get optimized away */
-
- c = __nss_base_rcsid[0] + __nss_base_sccsid[0];
-
- while (isdigit(*ptr)) {
- vmajor = 10 * vmajor + *ptr - '0';
- ptr++;
- }
- if (*ptr == '.') {
- ptr++;
- while (isdigit(*ptr)) {
- vminor = 10 * vminor + *ptr - '0';
- ptr++;
- }
- if (*ptr == '.') {
- ptr++;
- while (isdigit(*ptr)) {
- vpatch = 10 * vpatch + *ptr - '0';
- ptr++;
- }
- if (*ptr == '.') {
- ptr++;
- while (isdigit(*ptr)) {
- vbuild = 10 * vbuild + *ptr - '0';
- ptr++;
- }
- }
- }
- }
-
- if (vmajor != NSS_VMAJOR) {
- return PR_FALSE;
- }
- if (vmajor == NSS_VMAJOR && vminor > NSS_VMINOR) {
- return PR_FALSE;
- }
- if (vmajor == NSS_VMAJOR && vminor == NSS_VMINOR && vpatch > NSS_VPATCH) {
- return PR_FALSE;
- }
- if (vmajor == NSS_VMAJOR && vminor == NSS_VMINOR &&
- vpatch == NSS_VPATCH && vbuild > NSS_VBUILD) {
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-const char *
-NSS_GetVersion(void)
-{
- return NSS_VERSION;
-}
diff --git a/security/nss/lib/nss/nssrenam.h b/security/nss/lib/nss/nssrenam.h
deleted file mode 100644
index 17f072c89..000000000
--- a/security/nss/lib/nss/nssrenam.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __nssrenam_h_
-#define __nssrenam_h_
-
-#define CERT_AddTempCertToPerm __CERT_AddTempCertToPerm
-#define PK11_CreateContextByRawKey __PK11_CreateContextByRawKey
-#define CERT_ClosePermCertDB __CERT_ClosePermCertDB
-#define CERT_DecodeDERCertificate __CERT_DecodeDERCertificate
-#define CERT_TraversePermCertsForNickname __CERT_TraversePermCertsForNickname
-#define CERT_TraversePermCertsForSubject __CERT_TraversePermCertsForSubject
-
-#endif /* __nssrenam_h_ */
diff --git a/security/nss/lib/nss/nssver.c b/security/nss/lib/nss/nssver.c
deleted file mode 100644
index e2aa0cec5..000000000
--- a/security/nss/lib/nss/nssver.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Library identity and versioning */
-
-#include "nss.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_base_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_base_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/nss/pkixpriv.def b/security/nss/lib/nss/pkixpriv.def
deleted file mode 100644
index 440e6d95c..000000000
--- a/security/nss/lib/nss/pkixpriv.def
+++ /dev/null
@@ -1,322 +0,0 @@
-; This Source Code Form is subject to the terms of the Mozilla Public
-; License, v. 2.0. If a copy of the MPL was not distributed with this
-; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-;+LIBPKIXprivate {
-;+ global:
-;+# libpkix functions
-;+# May not become part of the NSS public API. Needed for unit testing for now.
-NSS_Get_PKIX_PL_LDAPMessageTemplate;
-PKIX_PL_LDAPMessageTemplate;
-PKIX_ALLOC_ERROR;
-PKIX_BuildChain;
-pkix_BuildResult_Create;
-PKIX_BuildResult_GetCertChain;
-PKIX_BuildResult_GetValidateResult;
-PKIX_CertChainChecker_Create;
-PKIX_CertChainChecker_GetCertChainCheckerState;
-PKIX_CertChainChecker_GetCheckCallback;
-PKIX_CertChainChecker_GetSupportedExtensions;
-PKIX_CertChainChecker_IsForwardCheckingSupported;
-PKIX_CertChainChecker_IsForwardDirectionExpected;
-PKIX_CertChainChecker_SetCertChainCheckerState;
-PKIX_CertSelector_Create;
-PKIX_CertSelector_GetCertSelectorContext;
-PKIX_CertSelector_GetCommonCertSelectorParams;
-PKIX_CertSelector_GetMatchCallback;
-PKIX_CertSelector_SetCommonCertSelectorParams;
-PKIX_CertStore_CertContinue;
-PKIX_CertStore_Create;
-PKIX_CertStore_CrlContinue;
-PKIX_CertStore_GetCertCallback;
-PKIX_CertStore_GetCertStoreContext;
-PKIX_CertStore_GetCRLCallback;
-PKIX_CertStore_GetTrustCallback;
-pkix_CheckType;
-PKIX_ComCertSelParams_AddPathToName;
-PKIX_ComCertSelParams_AddSubjAltName;
-PKIX_ComCertSelParams_Create;
-PKIX_ComCertSelParams_GetAuthorityKeyIdentifier;
-PKIX_ComCertSelParams_GetBasicConstraints;
-PKIX_ComCertSelParams_GetCertificate;
-PKIX_ComCertSelParams_GetCertificateValid;
-PKIX_ComCertSelParams_GetExtendedKeyUsage;
-PKIX_ComCertSelParams_GetIssuer;
-PKIX_ComCertSelParams_GetKeyUsage;
-PKIX_ComCertSelParams_GetMatchAllSubjAltNames;
-PKIX_ComCertSelParams_GetNameConstraints;
-PKIX_ComCertSelParams_GetPathToNames;
-PKIX_ComCertSelParams_GetPolicy;
-PKIX_ComCertSelParams_GetSerialNumber;
-PKIX_ComCertSelParams_GetSubjAltNames;
-PKIX_ComCertSelParams_GetSubject;
-PKIX_ComCertSelParams_GetSubjKeyIdentifier;
-PKIX_ComCertSelParams_GetSubjPKAlgId;
-PKIX_ComCertSelParams_GetSubjPubKey;
-PKIX_ComCertSelParams_GetVersion;
-PKIX_ComCertSelParams_SetAuthorityKeyIdentifier;
-PKIX_ComCertSelParams_SetBasicConstraints;
-PKIX_ComCertSelParams_SetCertificate;
-PKIX_ComCertSelParams_SetCertificateValid;
-PKIX_ComCertSelParams_SetExtendedKeyUsage;
-PKIX_ComCertSelParams_SetIssuer;
-PKIX_ComCertSelParams_SetKeyUsage;
-PKIX_ComCertSelParams_SetMatchAllSubjAltNames;
-PKIX_ComCertSelParams_SetNameConstraints;
-PKIX_ComCertSelParams_SetPathToNames;
-PKIX_ComCertSelParams_SetPolicy;
-PKIX_ComCertSelParams_SetSerialNumber;
-PKIX_ComCertSelParams_SetSubjAltNames;
-PKIX_ComCertSelParams_SetSubject;
-PKIX_ComCertSelParams_SetSubjKeyIdentifier;
-PKIX_ComCertSelParams_SetSubjPKAlgId;
-PKIX_ComCertSelParams_SetSubjPubKey;
-PKIX_ComCertSelParams_SetVersion;
-PKIX_ComCRLSelParams_AddIssuerName;
-PKIX_ComCRLSelParams_Create;
-PKIX_ComCRLSelParams_GetCertificateChecking;
-PKIX_ComCRLSelParams_GetDateAndTime;
-PKIX_ComCRLSelParams_GetIssuerNames;
-PKIX_ComCRLSelParams_GetMaxCRLNumber;
-PKIX_ComCRLSelParams_GetMinCRLNumber;
-PKIX_ComCRLSelParams_SetCertificateChecking;
-PKIX_ComCRLSelParams_SetDateAndTime;
-PKIX_ComCRLSelParams_SetIssuerNames;
-PKIX_ComCRLSelParams_SetMaxCRLNumber;
-PKIX_ComCRLSelParams_SetMinCRLNumber;
-PKIX_CRLSelector_Create;
-PKIX_CRLSelector_GetCommonCRLSelectorParams;
-PKIX_CRLSelector_GetCRLSelectorContext;
-PKIX_CRLSelector_GetMatchCallback;
-PKIX_CRLSelector_SetCommonCRLSelectorParams;
-pkix_DefaultRevChecker_Initialize;
-PKIX_Error_Create;
-PKIX_Error_GetCause;
-PKIX_Error_GetDescription;
-PKIX_Error_GetErrorClass;
-PKIX_Error_GetSupplementaryInfo;
-PKIX_ERRORCLASSNAMES DATA ;
-PKIX_Initialize;
-PKIX_Initialize_SetConfigDir;
-PKIX_List_AppendItem;
-PKIX_List_Create;
-PKIX_List_DeleteItem;
-PKIX_List_GetItem;
-PKIX_List_GetLength;
-PKIX_List_InsertItem;
-PKIX_List_IsEmpty;
-PKIX_List_IsImmutable;
-PKIX_List_ReverseList;
-PKIX_List_SetImmutable;
-PKIX_List_SetItem;
-PKIX_AddLogger;
-PKIX_GetLoggers;
-PKIX_SetLoggers;
-PKIX_Logger_Create;
-PKIX_Logger_GetLoggerContext;
-PKIX_Logger_GetLoggingComponent;
-PKIX_Logger_GetLogCallback;
-PKIX_Logger_GetMaxLoggingLevel;
-PKIX_Logger_SetLoggingComponent;
-PKIX_Logger_SetMaxLoggingLevel;
-PKIX_OcspChecker_Initialize;
-PKIX_OcspChecker_SetOCSPResponder;
-PKIX_OcspChecker_SetPasswordInfo;
-PKIX_OcspChecker_SetVerifyFcn;
-PKIX_PL_AcquireReaderLock;
-PKIX_PL_AcquireWriterLock;
-PKIX_PL_BasicConstraints_GetCAFlag;
-PKIX_PL_BasicConstraints_GetPathLenConstraint;
-PKIX_PL_BigInt_Create;
-PKIX_PL_ByteArray_Create;
-PKIX_PL_ByteArray_GetLength;
-PKIX_PL_ByteArray_GetPointer;
-PKIX_PL_Cert_AreCertPoliciesCritical;
-PKIX_PL_Cert_CheckNameConstraints;
-PKIX_PL_Cert_CheckValidity;
-PKIX_PL_Cert_Create;
-pkix_pl_Cert_CreateToList;
-pkix_pl_Cert_CreateWithNSSCert;
-PKIX_PL_Cert_GetAuthorityInfoAccess;
-PKIX_PL_Cert_GetAuthorityKeyIdentifier;
-PKIX_PL_Cert_GetBasicConstraints;
-PKIX_PL_Cert_GetCriticalExtensionOIDs;
-PKIX_PL_Cert_GetExtendedKeyUsage;
-PKIX_PL_Cert_GetInhibitAnyPolicy;
-PKIX_PL_Cert_GetIssuer;
-PKIX_PL_Cert_GetNameConstraints;
-PKIX_PL_Cert_GetPolicyInformation;
-PKIX_PL_Cert_GetPolicyMappingInhibited;
-PKIX_PL_Cert_GetPolicyMappings;
-PKIX_PL_Cert_GetRequireExplicitPolicy;
-PKIX_PL_Cert_GetSerialNumber;
-PKIX_PL_Cert_GetSubject;
-PKIX_PL_Cert_GetSubjectAltNames;
-PKIX_PL_Cert_GetSubjectInfoAccess;
-PKIX_PL_Cert_GetSubjectKeyIdentifier;
-PKIX_PL_Cert_GetSubjectPublicKey;
-PKIX_PL_Cert_GetSubjectPublicKeyAlgId;
-PKIX_PL_Cert_GetVersion;
-PKIX_PL_Cert_IsCertTrusted;
-PKIX_PL_Cert_MergeNameConstraints;
-PKIX_PL_Cert_VerifyKeyUsage;
-PKIX_PL_Cert_VerifySignature;
-PKIX_PL_CertPolicyInfo_GetPolicyId;
-PKIX_PL_CertPolicyInfo_GetPolQualifiers;
-PKIX_PL_CertPolicyMap_GetIssuerDomainPolicy;
-PKIX_PL_CertPolicyMap_GetSubjectDomainPolicy;
-PKIX_PL_CollectionCertStore_Create;
-PKIX_PL_CRL_Create;
-pkix_pl_CRL_CreateToList;
-PKIX_PL_CRL_GetCriticalExtensionOIDs;
-PKIX_PL_CRL_GetCRLEntryForSerialNumber;
-PKIX_PL_CRL_GetIssuer;
-PKIX_PL_CRL_VerifySignature;
-PKIX_PL_CRLEntry_GetCriticalExtensionOIDs;
-PKIX_PL_CRLEntry_GetCRLEntryReasonCode;
-PKIX_PL_Date_Create_UTCTime;
-pkix_pl_Date_CreateFromPRTime;
-pkix_pl_Date_GetPRTime;
-PKIX_PL_EkuChecker_Initialize;
-PKIX_PL_Free;
-PKIX_PL_GeneralName_Create;
-PKIX_PL_GetString;
-PKIX_PL_HashTable_Add;
-PKIX_PL_HashTable_Create;
-PKIX_PL_HashTable_Lookup;
-PKIX_PL_HashTable_Remove;
-PKIX_PL_HttpCertStore_Create;
-pkix_pl_HttpCertStore_CreateWithAsciiName;
-PKIX_PL_Initialize;
-PKIX_PL_InfoAccess_GetMethod;
-PKIX_PL_InfoAccess_GetLocation;
-PKIX_PL_InfoAccess_GetLocationType;
-PKIX_PL_LdapCertStore_Create;
-PKIX_PL_LdapClient_InitiateRequest;
-PKIX_PL_LdapClient_ResumeRequest;
-PKIX_PL_LdapDefaultClient_AbandonRequest;
-PKIX_PL_LdapDefaultClient_Create;
-PKIX_PL_LdapDefaultClient_CreateByName;
-pkix_pl_LdapResponse_Create;
-PKIX_PL_Malloc;
-PKIX_PL_Memcpy;
-PKIX_PL_MonitorLock_Create;
-PKIX_PL_MonitorLock_Enter;
-PKIX_PL_MonitorLock_Exit;
-PKIX_PL_Mutex_Create;
-PKIX_PL_Mutex_Lock;
-PKIX_PL_Mutex_Unlock;
-PKIX_PL_NssContext_Create;
-PKIX_PL_Object_Alloc;
-PKIX_PL_Object_Compare;
-PKIX_PL_Object_DecRef;
-PKIX_PL_Object_Duplicate;
-PKIX_PL_Object_Equals;
-PKIX_PL_Object_GetType;
-PKIX_PL_Object_Hashcode;
-PKIX_PL_Object_IncRef;
-PKIX_PL_Object_IsTypeRegistered;
-PKIX_PL_Object_Lock;
-PKIX_PL_Object_RegisterType;
-PKIX_PL_Object_ToString;
-PKIX_PL_Object_Unlock;
-PKIX_PL_OID_Create;
-pkix_pl_OcspRequest_Create;
-pkix_pl_OcspResponse_Create;
-pkix_pl_OcspResponse_Decode;
-pkix_pl_OcspResponse_GetStatus;
-pkix_pl_OcspResponse_GetStatusForCert;
-PKIX_PL_OcspResponse_UseBuildChain;
-pkix_pl_OcspResponse_VerifySignature;
-PKIX_PL_Pk11CertStore_Create;
-PKIX_PL_PolicyQualifier_GetPolicyQualifierId;
-PKIX_PL_PolicyQualifier_GetQualifier;
-PKIX_PL_PublicKey_MakeInheritedDSAPublicKey;
-PKIX_PL_PublicKey_NeedsDSAParameters;
-PKIX_PL_Realloc;
-PKIX_PL_ReleaseReaderLock;
-PKIX_PL_ReleaseWriterLock;
-PKIX_PL_RWLock_Create;
-PKIX_PL_Shutdown;
-pkix_pl_Socket_Create;
-pkix_pl_Socket_CreateByName;
-pkix_pl_Socket_GetCallbackList;
-PKIX_PL_Sprintf;
-PKIX_PL_String_Create;
-PKIX_PL_String_GetEncoded;
-PKIX_PL_X500Name_Create;
-pkix_pl_X500Name_GetCommonName;
-pkix_pl_X500Name_GetCountryName;
-pkix_pl_X500Name_GetOrgName;
-PKIX_PL_X500Name_Match;
-pkix_PolicyNode_AddToParent;
-pkix_PolicyNode_Create;
-PKIX_PolicyNode_GetChildren;
-PKIX_PolicyNode_GetDepth;
-PKIX_PolicyNode_GetExpectedPolicies;
-PKIX_PolicyNode_GetParent;
-PKIX_PolicyNode_GetPolicyQualifiers;
-PKIX_PolicyNode_GetValidPolicy;
-PKIX_PolicyNode_IsCritical;
-pkix_PolicyNode_Prune;
-PKIX_ProcessingParams_AddCertChainChecker;
-PKIX_ProcessingParams_AddCertStore;
-PKIX_ProcessingParams_AddRevocationChecker;
-PKIX_ProcessingParams_Create;
-PKIX_ProcessingParams_GetCertChainCheckers;
-PKIX_ProcessingParams_GetCertStores;
-PKIX_ProcessingParams_GetDate;
-PKIX_ProcessingParams_GetHintCerts;
-PKIX_ProcessingParams_GetInitialPolicies;
-PKIX_ProcessingParams_GetPolicyQualifiersRejected;
-PKIX_ProcessingParams_GetResourceLimits;
-PKIX_ProcessingParams_GetRevocationCheckers;
-PKIX_ProcessingParams_GetTargetCertConstraints;
-PKIX_ProcessingParams_GetTrustAnchors;
-PKIX_ProcessingParams_IsAnyPolicyInhibited;
-PKIX_ProcessingParams_IsCRLRevocationCheckingEnabled;
-PKIX_ProcessingParams_IsExplicitPolicyRequired;
-PKIX_ProcessingParams_IsPolicyMappingInhibited;
-PKIX_ProcessingParams_SetAnyPolicyInhibited;
-PKIX_ProcessingParams_SetCertChainCheckers;
-PKIX_ProcessingParams_SetCertStores;
-PKIX_ProcessingParams_SetDate;
-PKIX_ProcessingParams_SetExplicitPolicyRequired;
-PKIX_ProcessingParams_SetHintCerts;
-PKIX_ProcessingParams_SetInitialPolicies;
-PKIX_ProcessingParams_SetPolicyMappingInhibited;
-PKIX_ProcessingParams_SetPolicyQualifiersRejected;
-PKIX_ProcessingParams_SetResourceLimits;
-PKIX_ProcessingParams_SetRevocationCheckers;
-PKIX_ProcessingParams_SetRevocationEnabled;
-PKIX_ProcessingParams_SetTargetCertConstraints;
-PKIX_RevocationChecker_Create;
-PKIX_RevocationChecker_GetRevCallback;
-PKIX_RevocationChecker_GetRevCheckerContext;
-PKIX_Shutdown;
-pkix_Throw;
-PKIX_TrustAnchor_CreateWithCert;
-PKIX_TrustAnchor_CreateWithNameKeyPair;
-PKIX_TrustAnchor_GetCAName;
-PKIX_TrustAnchor_GetCAPublicKey;
-PKIX_TrustAnchor_GetNameConstraints;
-PKIX_TrustAnchor_GetTrustedCert;
-PKIX_ValidateChain;
-PKIX_ValidateChain_NB;
-PKIX_ValidateParams_Create;
-PKIX_ValidateParams_GetCertChain;
-PKIX_ValidateParams_GetProcessingParams;
-pkix_ValidateResult_Create;
-PKIX_ValidateResult_GetPolicyTree;
-PKIX_ValidateResult_GetPublicKey;
-PKIX_ValidateResult_GetTrustAnchor;
-pkix_VerifyNode_AddToChain;
-pkix_VerifyNode_Create;
-PKIX_ResourceLimits_Create;
-PKIX_ResourceLimits_GetMaxDepth;
-PKIX_ResourceLimits_GetMaxFanout;
-PKIX_ResourceLimits_GetMaxTime;
-PKIX_ResourceLimits_SetMaxDepth;
-PKIX_ResourceLimits_SetMaxFanout;
-PKIX_ResourceLimits_SetMaxTime;
-;+};
diff --git a/security/nss/lib/nss/utilwrap.c b/security/nss/lib/nss/utilwrap.c
deleted file mode 100644
index a3fa9f97b..000000000
--- a/security/nss/lib/nss/utilwrap.c
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * NSS utility functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secport.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "secdig.h"
-#include "secder.h"
-#include "secasn1.h"
-#include "base64.h"
-#include "nssb64.h"
-#include "nssrwlk.h"
-#include "cert.h"
-#include "prerror.h"
-
-/* wrappers for implementation in libnssutil3 */
-#undef ATOB_AsciiToData
-#undef ATOB_ConvertAsciiToItem
-#undef BTOA_ConvertItemToAscii
-#undef BTOA_DataToAscii
-#undef CERT_GenTime2FormattedAscii
-#undef DER_AsciiToTime
-#undef DER_DecodeTimeChoice
-#undef DER_Encode
-#undef DER_EncodeTimeChoice
-#undef DER_GeneralizedDayToAscii
-#undef DER_GeneralizedTimeToTime
-#undef DER_GetInteger
-#undef DER_Lengths
-#undef DER_TimeChoiceDayToAscii
-#undef DER_TimeToGeneralizedTime
-#undef DER_TimeToGeneralizedTimeArena
-#undef DER_TimeToUTCTime
-#undef DER_UTCDayToAscii
-#undef DER_UTCTimeToAscii
-#undef DER_UTCTimeToTime
-#undef NSS_PutEnv
-#undef NSSBase64_DecodeBuffer
-#undef NSSBase64_EncodeItem
-#undef NSSBase64Decoder_Create
-#undef NSSBase64Decoder_Destroy
-#undef NSSBase64Decoder_Update
-#undef NSSBase64Encoder_Create
-#undef NSSBase64Encoder_Destroy
-#undef NSSBase64Encoder_Update
-#undef NSSRWLock_Destroy
-#undef NSSRWLock_HaveWriteLock
-#undef NSSRWLock_LockRead
-#undef NSSRWLock_LockWrite
-#undef NSSRWLock_New
-#undef NSSRWLock_UnlockRead
-#undef NSSRWLock_UnlockWrite
-#undef PORT_Alloc
-#undef PORT_ArenaAlloc
-#undef PORT_ArenaGrow
-#undef PORT_ArenaMark
-#undef PORT_ArenaRelease
-#undef PORT_ArenaStrdup
-#undef PORT_ArenaUnmark
-#undef PORT_ArenaZAlloc
-#undef PORT_Free
-#undef PORT_FreeArena
-#undef PORT_GetError
-#undef PORT_NewArena
-#undef PORT_Realloc
-#undef PORT_SetError
-#undef PORT_SetUCS2_ASCIIConversionFunction
-#undef PORT_SetUCS2_UTF8ConversionFunction
-#undef PORT_SetUCS4_UTF8ConversionFunction
-#undef PORT_Strdup
-#undef PORT_UCS2_ASCIIConversion
-#undef PORT_UCS2_UTF8Conversion
-#undef PORT_ZAlloc
-#undef PORT_ZFree
-#undef SEC_ASN1Decode
-#undef SEC_ASN1DecodeInteger
-#undef SEC_ASN1DecodeItem
-#undef SEC_ASN1DecoderAbort
-#undef SEC_ASN1DecoderClearFilterProc
-#undef SEC_ASN1DecoderClearNotifyProc
-#undef SEC_ASN1DecoderFinish
-#undef SEC_ASN1DecoderSetFilterProc
-#undef SEC_ASN1DecoderSetNotifyProc
-#undef SEC_ASN1DecoderStart
-#undef SEC_ASN1DecoderUpdate
-#undef SEC_ASN1Encode
-#undef SEC_ASN1EncodeInteger
-#undef SEC_ASN1EncodeItem
-#undef SEC_ASN1EncoderAbort
-#undef SEC_ASN1EncoderClearNotifyProc
-#undef SEC_ASN1EncoderClearStreaming
-#undef SEC_ASN1EncoderClearTakeFromBuf
-#undef SEC_ASN1EncoderFinish
-#undef SEC_ASN1EncoderSetNotifyProc
-#undef SEC_ASN1EncoderSetStreaming
-#undef SEC_ASN1EncoderSetTakeFromBuf
-#undef SEC_ASN1EncoderStart
-#undef SEC_ASN1EncoderUpdate
-#undef SEC_ASN1EncodeUnsignedInteger
-#undef SEC_ASN1LengthLength
-#undef SEC_QuickDERDecodeItem
-#undef SECITEM_AllocItem
-#undef SECITEM_ArenaDupItem
-#undef SECITEM_CompareItem
-#undef SECITEM_CopyItem
-#undef SECITEM_DupItem
-#undef SECITEM_FreeItem
-#undef SECITEM_ItemsAreEqual
-#undef SECITEM_ZfreeItem
-#undef SECOID_AddEntry
-#undef SECOID_CompareAlgorithmID
-#undef SECOID_CopyAlgorithmID
-#undef SECOID_DestroyAlgorithmID
-#undef SECOID_FindOID
-#undef SECOID_FindOIDByTag
-#undef SECOID_FindOIDTag
-#undef SECOID_FindOIDTagDescription
-#undef SECOID_GetAlgorithmTag
-#undef SECOID_SetAlgorithmID
-#undef SGN_CompareDigestInfo
-#undef SGN_CopyDigestInfo
-#undef SGN_CreateDigestInfo
-#undef SGN_DestroyDigestInfo
-
-void *
-PORT_Alloc(size_t bytes)
-{
- return PORT_Alloc_Util(bytes);
-}
-
-void *
-PORT_Realloc(void *oldptr, size_t bytes)
-{
- return PORT_Realloc_Util(oldptr, bytes);
-}
-
-void *
-PORT_ZAlloc(size_t bytes)
-{
- return PORT_ZAlloc_Util(bytes);
-}
-
-void
-PORT_Free(void *ptr)
-{
- PORT_Free_Util(ptr);
-}
-
-void
-PORT_ZFree(void *ptr, size_t len)
-{
- PORT_ZFree_Util(ptr, len);
-}
-
-char *
-PORT_Strdup(const char *str)
-{
- return PORT_Strdup_Util(str);
-}
-
-void
-PORT_SetError(int value)
-{
- PORT_SetError_Util(value);
-}
-
-int
-PORT_GetError(void)
-{
- return PORT_GetError_Util();
-}
-
-PLArenaPool *
-PORT_NewArena(unsigned long chunksize)
-{
- return PORT_NewArena_Util(chunksize);
-}
-
-void *
-PORT_ArenaAlloc(PLArenaPool *arena, size_t size)
-{
- return PORT_ArenaAlloc_Util(arena, size);
-}
-
-void *
-PORT_ArenaZAlloc(PLArenaPool *arena, size_t size)
-{
- return PORT_ArenaZAlloc_Util(arena, size);
-}
-
-void
-PORT_FreeArena(PLArenaPool *arena, PRBool zero)
-{
- PORT_FreeArena_Util(arena, zero);
-}
-
-void *
-PORT_ArenaGrow(PLArenaPool *arena, void *ptr, size_t oldsize, size_t newsize)
-{
- return PORT_ArenaGrow_Util(arena, ptr, oldsize, newsize);
-}
-
-void *
-PORT_ArenaMark(PLArenaPool *arena)
-{
- return PORT_ArenaMark_Util(arena);
-}
-
-void
-PORT_ArenaRelease(PLArenaPool *arena, void *mark)
-{
- PORT_ArenaRelease_Util(arena, mark);
-}
-
-void
-PORT_ArenaUnmark(PLArenaPool *arena, void *mark)
-{
- PORT_ArenaUnmark_Util(arena, mark);
-}
-
-char *
-PORT_ArenaStrdup(PLArenaPool *arena, const char *str)
-{
- return PORT_ArenaStrdup_Util(arena, str);
-}
-
-void
-PORT_SetUCS4_UTF8ConversionFunction(PORTCharConversionFunc convFunc)
-{
- PORT_SetUCS4_UTF8ConversionFunction_Util(convFunc);
-}
-
-void
-PORT_SetUCS2_ASCIIConversionFunction(PORTCharConversionWSwapFunc convFunc)
-{
- PORT_SetUCS2_ASCIIConversionFunction_Util(convFunc);
-}
-
-void
-PORT_SetUCS2_UTF8ConversionFunction(PORTCharConversionFunc convFunc)
-{
- PORT_SetUCS2_UTF8ConversionFunction_Util(convFunc);
-}
-
-PRBool
-PORT_UCS2_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen)
-{
- return PORT_UCS2_UTF8Conversion_Util(toUnicode, inBuf, inBufLen, outBuf,
- maxOutBufLen, outBufLen);
-}
-
-PRBool
-PORT_UCS2_ASCIIConversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen,
- PRBool swapBytes)
-{
- return PORT_UCS2_ASCIIConversion_Util(toUnicode, inBuf, inBufLen, outBuf,
- maxOutBufLen, outBufLen, swapBytes);
-}
-
-int
-NSS_PutEnv(const char * envVarName, const char * envValue)
-{
- return NSS_PutEnv_Util(envVarName, envValue);
-}
-
-SECOidData *SECOID_FindOID( const SECItem *oid)
-{
- return SECOID_FindOID_Util(oid);
-}
-
-SECOidTag SECOID_FindOIDTag(const SECItem *oid)
-{
- return SECOID_FindOIDTag_Util(oid);
-}
-
-SECOidData *SECOID_FindOIDByTag(SECOidTag tagnum)
-{
- return SECOID_FindOIDByTag_Util(tagnum);
-}
-
-SECStatus SECOID_SetAlgorithmID(PRArenaPool *arena, SECAlgorithmID *aid,
- SECOidTag tag, SECItem *params)
-{
- return SECOID_SetAlgorithmID_Util(arena, aid, tag, params);
-}
-
-SECStatus SECOID_CopyAlgorithmID(PRArenaPool *arena, SECAlgorithmID *dest,
- SECAlgorithmID *src)
-{
- return SECOID_CopyAlgorithmID_Util(arena, dest, src);
-}
-
-SECOidTag SECOID_GetAlgorithmTag(SECAlgorithmID *aid)
-{
- return SECOID_GetAlgorithmTag_Util(aid);
-}
-
-void SECOID_DestroyAlgorithmID(SECAlgorithmID *aid, PRBool freeit)
-{
- SECOID_DestroyAlgorithmID_Util(aid, freeit);
-}
-
-SECComparison SECOID_CompareAlgorithmID(SECAlgorithmID *a,
- SECAlgorithmID *b)
-{
- return SECOID_CompareAlgorithmID_Util(a, b);
-}
-
-const char *SECOID_FindOIDTagDescription(SECOidTag tagnum)
-{
- return SECOID_FindOIDTagDescription_Util(tagnum);
-}
-
-SECOidTag SECOID_AddEntry(const SECOidData * src)
-{
- return SECOID_AddEntry_Util(src);
-}
-
-SECItem *SECITEM_AllocItem(PRArenaPool *arena, SECItem *item,
- unsigned int len)
-{
- return SECITEM_AllocItem_Util(arena, item, len);
-}
-
-SECComparison SECITEM_CompareItem(const SECItem *a, const SECItem *b)
-{
- return SECITEM_CompareItem_Util(a, b);
-}
-
-PRBool SECITEM_ItemsAreEqual(const SECItem *a, const SECItem *b)
-{
- return SECITEM_ItemsAreEqual_Util(a, b);
-}
-
-SECStatus SECITEM_CopyItem(PRArenaPool *arena, SECItem *to,
- const SECItem *from)
-{
- return SECITEM_CopyItem_Util(arena, to, from);
-}
-
-SECItem *SECITEM_DupItem(const SECItem *from)
-{
- return SECITEM_DupItem_Util(from);
-}
-
-SECItem *SECITEM_ArenaDupItem(PRArenaPool *arena, const SECItem *from)
-{
- return SECITEM_ArenaDupItem_Util(arena, from);
-}
-
-void SECITEM_FreeItem(SECItem *zap, PRBool freeit)
-{
- SECITEM_FreeItem_Util(zap, freeit);
-}
-
-void SECITEM_ZfreeItem(SECItem *zap, PRBool freeit)
-{
- SECITEM_ZfreeItem_Util(zap, freeit);
-}
-
-SGNDigestInfo *SGN_CreateDigestInfo(SECOidTag algorithm,
- unsigned char *sig,
- unsigned int sigLen)
-{
- return SGN_CreateDigestInfo_Util(algorithm, sig, sigLen);
-}
-
-void SGN_DestroyDigestInfo(SGNDigestInfo *info)
-{
- SGN_DestroyDigestInfo_Util(info);
-}
-
-SECStatus SGN_CopyDigestInfo(PRArenaPool *poolp,
- SGNDigestInfo *a,
- SGNDigestInfo *b)
-{
- return SGN_CopyDigestInfo_Util(poolp, a, b);
-}
-
-SECComparison SGN_CompareDigestInfo(SGNDigestInfo *a, SGNDigestInfo *b)
-{
- return SGN_CompareDigestInfo_Util(a, b);
-}
-
-SECStatus DER_Encode(PRArenaPool *arena, SECItem *dest, DERTemplate *t,
- void *src)
-{
- return DER_Encode_Util(arena, dest, t, src);
-}
-
-SECStatus DER_Lengths(SECItem *item, int *header_len_p,
- PRUint32 *contents_len_p)
-{
- return DER_Lengths_Util(item, header_len_p, contents_len_p);
-}
-
-long DER_GetInteger(SECItem *src)
-{
- return DER_GetInteger_Util(src);
-}
-
-SECStatus DER_TimeToUTCTime(SECItem *result, int64 time)
-{
- return DER_TimeToUTCTime_Util(result, time);
-}
-
-SECStatus DER_AsciiToTime(int64 *result, const char *string)
-{
- return DER_AsciiToTime_Util(result, string);
-}
-
-SECStatus DER_UTCTimeToTime(int64 *result, const SECItem *time)
-{
- return DER_UTCTimeToTime_Util(result, time);
-}
-
-char *DER_UTCTimeToAscii(SECItem *utcTime)
-{
- return DER_UTCTimeToAscii_Util(utcTime);
-}
-
-char *DER_UTCDayToAscii(SECItem *utctime)
-{
- return DER_UTCDayToAscii_Util(utctime);
-}
-
-char *DER_GeneralizedDayToAscii(SECItem *gentime)
-{
- return DER_GeneralizedDayToAscii_Util(gentime);
-}
-
-char *DER_TimeChoiceDayToAscii(SECItem *timechoice)
-{
- return DER_TimeChoiceDayToAscii_Util(timechoice);
-}
-
-SECStatus DER_TimeToGeneralizedTime(SECItem *dst, int64 gmttime)
-{
- return DER_TimeToGeneralizedTime_Util(dst, gmttime);
-}
-
-SECStatus DER_TimeToGeneralizedTimeArena(PRArenaPool* arenaOpt,
- SECItem *dst, int64 gmttime)
-{
- return DER_TimeToGeneralizedTimeArena_Util(arenaOpt, dst, gmttime);
-}
-
-SECStatus DER_GeneralizedTimeToTime(int64 *dst, const SECItem *time)
-{
- return DER_GeneralizedTimeToTime_Util(dst, time);
-}
-
-char *CERT_GenTime2FormattedAscii (int64 genTime, char *format)
-{
- return CERT_GenTime2FormattedAscii_Util(genTime, format);
-}
-
-SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input)
-{
- return DER_DecodeTimeChoice_Util(output, input);
-}
-
-SECStatus DER_EncodeTimeChoice(PRArenaPool* arena, SECItem* output,
- PRTime input)
-{
- return DER_EncodeTimeChoice_Util(arena, output, input);
-}
-
-SEC_ASN1DecoderContext *SEC_ASN1DecoderStart(PRArenaPool *pool,
- void *dest,
- const SEC_ASN1Template *t)
-{
- return SEC_ASN1DecoderStart_Util(pool, dest, t);
-}
-
-SECStatus SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx,
- const char *buf,
- unsigned long len)
-{
- return SEC_ASN1DecoderUpdate_Util(cx, buf, len);
-}
-
-SECStatus SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx)
-{
- return SEC_ASN1DecoderFinish_Util(cx);
-}
-
-void SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error)
-{
- SEC_ASN1DecoderAbort_Util(cx, error);
-}
-
-void SEC_ASN1DecoderSetFilterProc(SEC_ASN1DecoderContext *cx,
- SEC_ASN1WriteProc fn,
- void *arg, PRBool no_store)
-{
- SEC_ASN1DecoderSetFilterProc_Util(cx, fn, arg, no_store);
-}
-
-void SEC_ASN1DecoderClearFilterProc(SEC_ASN1DecoderContext *cx)
-{
- SEC_ASN1DecoderClearFilterProc_Util(cx);
-}
-
-void SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx,
- SEC_ASN1NotifyProc fn,
- void *arg)
-{
- SEC_ASN1DecoderSetNotifyProc_Util(cx, fn, arg);
-}
-
-void SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx)
-{
- SEC_ASN1DecoderClearNotifyProc_Util(cx);
-}
-
-SECStatus SEC_ASN1Decode(PRArenaPool *pool, void *dest,
- const SEC_ASN1Template *t,
- const char *buf, long len)
-{
- return SEC_ASN1Decode_Util(pool, dest, t, buf, len);
-}
-
-SECStatus SEC_ASN1DecodeItem(PRArenaPool *pool, void *dest,
- const SEC_ASN1Template *t,
- const SECItem *src)
-{
- return SEC_ASN1DecodeItem_Util(pool, dest, t, src);
-}
-
-SECStatus SEC_QuickDERDecodeItem(PRArenaPool* arena, void* dest,
- const SEC_ASN1Template* templateEntry,
- const SECItem* src)
-{
- return SEC_QuickDERDecodeItem_Util(arena, dest, templateEntry, src);
-}
-
-SEC_ASN1EncoderContext *SEC_ASN1EncoderStart(const void *src,
- const SEC_ASN1Template *t,
- SEC_ASN1WriteProc fn,
- void *output_arg)
-{
- return SEC_ASN1EncoderStart_Util(src, t, fn, output_arg);
-}
-
-SECStatus SEC_ASN1EncoderUpdate(SEC_ASN1EncoderContext *cx,
- const char *buf,
- unsigned long len)
-{
- return SEC_ASN1EncoderUpdate_Util(cx, buf, len);
-}
-
-void SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx)
-{
- SEC_ASN1EncoderFinish_Util(cx);
-}
-
-void SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error)
-{
- SEC_ASN1EncoderAbort_Util(cx, error);
-}
-
-void SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx,
- SEC_ASN1NotifyProc fn,
- void *arg)
-{
- SEC_ASN1EncoderSetNotifyProc_Util(cx, fn, arg);
-}
-
-void SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx)
-{
- SEC_ASN1EncoderClearNotifyProc_Util(cx);
-}
-
-void SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx)
-{
- SEC_ASN1EncoderSetStreaming_Util(cx);
-}
-
-void SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx)
-{
- SEC_ASN1EncoderClearStreaming_Util(cx);
-}
-
-void SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx)
-{
- SEC_ASN1EncoderSetTakeFromBuf_Util(cx);
-}
-
-void SEC_ASN1EncoderClearTakeFromBuf(SEC_ASN1EncoderContext *cx)
-{
- SEC_ASN1EncoderClearTakeFromBuf_Util(cx);
-}
-
-SECStatus SEC_ASN1Encode(const void *src, const SEC_ASN1Template *t,
- SEC_ASN1WriteProc output_proc,
- void *output_arg)
-{
- return SEC_ASN1Encode_Util(src, t, output_proc, output_arg);
-}
-
-SECItem * SEC_ASN1EncodeItem(PRArenaPool *pool, SECItem *dest,
- const void *src, const SEC_ASN1Template *t)
-{
- return SEC_ASN1EncodeItem_Util(pool, dest, src, t);
-}
-
-SECItem * SEC_ASN1EncodeInteger(PRArenaPool *pool,
- SECItem *dest, long value)
-{
- return SEC_ASN1EncodeInteger_Util(pool, dest, value);
-}
-
-SECItem * SEC_ASN1EncodeUnsignedInteger(PRArenaPool *pool,
- SECItem *dest,
- unsigned long value)
-{
- return SEC_ASN1EncodeUnsignedInteger_Util(pool, dest, value);
-}
-
-SECStatus SEC_ASN1DecodeInteger(SECItem *src,
- unsigned long *value)
-{
- return SEC_ASN1DecodeInteger_Util(src, value);
-}
-
-int SEC_ASN1LengthLength (unsigned long len)
-{
- return SEC_ASN1LengthLength_Util(len);
-}
-
-char *BTOA_DataToAscii(const unsigned char *data, unsigned int len)
-{
- return BTOA_DataToAscii_Util(data, len);
-}
-
-unsigned char *ATOB_AsciiToData(const char *string, unsigned int *lenp)
-{
- return ATOB_AsciiToData_Util(string, lenp);
-}
-
-SECStatus ATOB_ConvertAsciiToItem(SECItem *binary_item, const char *ascii)
-{
- return ATOB_ConvertAsciiToItem_Util(binary_item, ascii);
-}
-
-char *BTOA_ConvertItemToAscii(SECItem *binary_item)
-{
- return BTOA_ConvertItemToAscii_Util(binary_item);
-}
-
-NSSBase64Decoder *
-NSSBase64Decoder_Create (PRInt32 (*output_fn) (void *, const unsigned char *,
- PRInt32),
- void *output_arg)
-{
- return NSSBase64Decoder_Create_Util(output_fn, output_arg);
-}
-
-NSSBase64Encoder *
-NSSBase64Encoder_Create (PRInt32 (*output_fn) (void *, const char *, PRInt32),
- void *output_arg)
-{
- return NSSBase64Encoder_Create_Util(output_fn, output_arg);
-}
-
-SECStatus
-NSSBase64Decoder_Update (NSSBase64Decoder *data, const char *buffer,
- PRUint32 size)
-{
- return NSSBase64Decoder_Update_Util(data, buffer, size);
-}
-
-SECStatus
-NSSBase64Encoder_Update (NSSBase64Encoder *data, const unsigned char *buffer,
- PRUint32 size)
-{
- return NSSBase64Encoder_Update_Util(data, buffer, size);
-}
-
-SECStatus
-NSSBase64Decoder_Destroy (NSSBase64Decoder *data, PRBool abort_p)
-{
- return NSSBase64Decoder_Destroy_Util(data, abort_p);
-}
-
-SECStatus
-NSSBase64Encoder_Destroy (NSSBase64Encoder *data, PRBool abort_p)
-{
- return NSSBase64Encoder_Destroy_Util(data, abort_p);
-}
-
-SECItem *
-NSSBase64_DecodeBuffer (PRArenaPool *arenaOpt, SECItem *outItemOpt,
- const char *inStr, unsigned int inLen)
-{
- return NSSBase64_DecodeBuffer_Util(arenaOpt, outItemOpt, inStr, inLen);
-}
-
-char *
-NSSBase64_EncodeItem (PRArenaPool *arenaOpt, char *outStrOpt,
- unsigned int maxOutLen, SECItem *inItem)
-{
- return NSSBase64_EncodeItem_Util(arenaOpt, outStrOpt, maxOutLen, inItem);
-}
-
-NSSRWLock* NSSRWLock_New(PRUint32 lock_rank, const char *lock_name)
-{
- return NSSRWLock_New_Util(lock_rank, lock_name);
-}
-
-void NSSRWLock_Destroy(NSSRWLock *lock)
-{
- NSSRWLock_Destroy_Util(lock);
-}
-
-void NSSRWLock_LockRead(NSSRWLock *lock)
-{
- NSSRWLock_LockRead_Util(lock);
-}
-
-void NSSRWLock_LockWrite(NSSRWLock *lock)
-{
- NSSRWLock_LockWrite_Util(lock);
-}
-
-void NSSRWLock_UnlockRead(NSSRWLock *lock)
-{
- NSSRWLock_UnlockRead_Util(lock);
-}
-
-void NSSRWLock_UnlockWrite(NSSRWLock *lock)
-{
- NSSRWLock_UnlockWrite_Util(lock);
-}
-
-PRBool NSSRWLock_HaveWriteLock(NSSRWLock *rwlock)
-{
- return NSSRWLock_HaveWriteLock_Util(rwlock);
-}
-
-SECStatus __nss_InitLock( PZLock **ppLock, nssILockType ltype )
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-/* templates duplicated in libnss3 and libnssutil3 */
-
-#undef NSS_Get_SEC_AnyTemplate
-#undef NSS_Get_SEC_BitStringTemplate
-#undef NSS_Get_SEC_BMPStringTemplate
-#undef NSS_Get_SEC_BooleanTemplate
-#undef NSS_Get_SEC_GeneralizedTimeTemplate
-#undef NSS_Get_SEC_IA5StringTemplate
-#undef NSS_Get_SEC_IntegerTemplate
-#undef NSS_Get_SEC_NullTemplate
-#undef NSS_Get_SEC_ObjectIDTemplate
-#undef NSS_Get_SEC_OctetStringTemplate
-#undef NSS_Get_SEC_PointerToAnyTemplate
-#undef NSS_Get_SEC_PointerToOctetStringTemplate
-#undef NSS_Get_SEC_SetOfAnyTemplate
-#undef NSS_Get_SEC_UTCTimeTemplate
-#undef NSS_Get_SEC_UTF8StringTemplate
-#undef NSS_Get_SECOID_AlgorithmIDTemplate
-#undef NSS_Get_sgn_DigestInfoTemplate
-#undef SEC_AnyTemplate
-#undef SEC_BitStringTemplate
-#undef SEC_BMPStringTemplate
-#undef SEC_BooleanTemplate
-#undef SEC_GeneralizedTimeTemplate
-#undef SEC_IA5StringTemplate
-#undef SEC_IntegerTemplate
-#undef SEC_NullTemplate
-#undef SEC_ObjectIDTemplate
-#undef SEC_OctetStringTemplate
-#undef SEC_PointerToAnyTemplate
-#undef SEC_PointerToOctetStringTemplate
-#undef SEC_SetOfAnyTemplate
-#undef SEC_UTCTimeTemplate
-#undef SEC_UTF8StringTemplate
-#undef SECOID_AlgorithmIDTemplate
-#undef sgn_DigestInfoTemplate
-
-#include "templates.c"
-
diff --git a/security/nss/lib/pk11wrap/Makefile b/security/nss/lib/pk11wrap/Makefile
deleted file mode 100644
index 86ab29653..000000000
--- a/security/nss/lib/pk11wrap/Makefile
+++ /dev/null
@@ -1,62 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
--include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
-$(OBJDIR)/pk11load$(OBJ_SUFFIX): debug_module.c
-
-# On AIX 4.3, IBM xlC_r compiler (version 3.6.6) cannot compile
-# pk11slot.c in 64-bit mode for unknown reasons. A workaround is
-# to compile it with optimizations turned on. (Bugzilla bug #63815)
-ifeq ($(OS_TARGET)$(OS_RELEASE),AIX4.3)
-ifeq ($(USE_64),1)
-ifndef BUILD_OPT
-$(OBJDIR)/pk11slot.o: pk11slot.c
- @$(MAKE_OBJDIR)
- $(CC) -o $@ -c -O2 $(CFLAGS) $<
-endif
-endif
-endif
diff --git a/security/nss/lib/pk11wrap/config.mk b/security/nss/lib/pk11wrap/config.mk
deleted file mode 100644
index b8c03de79..000000000
--- a/security/nss/lib/pk11wrap/config.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/pk11wrap/debug_module.c b/security/nss/lib/pk11wrap/debug_module.c
deleted file mode 100644
index 9cc4e0581..000000000
--- a/security/nss/lib/pk11wrap/debug_module.c
+++ /dev/null
@@ -1,2733 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "prlog.h"
-#include <stdio.h>
-#include "cert.h" /* for CERT_DerNameToAscii & CERT_Hexify */
-
-static PRLogModuleInfo *modlog = NULL;
-
-static CK_FUNCTION_LIST_PTR module_functions;
-
-static CK_FUNCTION_LIST debug_functions;
-
-static void print_final_statistics(void);
-
-#define STRING static const char
-
-STRING fmt_flags[] = " flags = 0x%x";
-STRING fmt_hKey[] = " hKey = 0x%x";
-STRING fmt_hObject[] = " hObject = 0x%x";
-STRING fmt_hSession[] = " hSession = 0x%x";
-STRING fmt_manufacturerID[] = " manufacturerID = \"%.32s\"";
-STRING fmt_pData[] = " pData = 0x%p";
-STRING fmt_pDigest[] = " pDigest = 0x%p";
-STRING fmt_pEncryptedData[] = " pEncryptedData = 0x%p";
-STRING fmt_pEncryptedPart[] = " pEncryptedPart = 0x%p";
-STRING fmt_pInfo[] = " pInfo = 0x%p";
-STRING fmt_pMechanism[] = " pMechanism = 0x%p";
-STRING fmt_pOperationState[] = " pOperationState = 0x%p";
-STRING fmt_pPart[] = " pPart = 0x%p";
-STRING fmt_pPin[] = " pPin = 0x%p";
-STRING fmt_pSignature[] = " pSignature = 0x%p";
-STRING fmt_pTemplate[] = " pTemplate = 0x%p";
-STRING fmt_pWrappedKey[] = " pWrappedKey = 0x%p";
-STRING fmt_phKey[] = " phKey = 0x%p";
-STRING fmt_phObject[] = " phObject = 0x%p";
-STRING fmt_pulCount[] = " pulCount = 0x%p";
-STRING fmt_pulDataLen[] = " pulDataLen = 0x%p";
-STRING fmt_pulDigestLen[] = " pulDigestLen = 0x%p";
-STRING fmt_pulEncryptedPartLen[] = " pulEncryptedPartLen = 0x%p";
-STRING fmt_pulPartLen[] = " pulPartLen = 0x%p";
-STRING fmt_pulSignatureLen[] = " pulSignatureLen = 0x%p";
-STRING fmt_slotID[] = " slotID = 0x%x";
-STRING fmt_sphKey[] = " *phKey = 0x%x";
-STRING fmt_spulCount[] = " *pulCount = 0x%x";
-STRING fmt_spulDataLen[] = " *pulDataLen = 0x%x";
-STRING fmt_spulDigestLen[] = " *pulDigestLen = 0x%x";
-STRING fmt_spulEncryptedPartLen[] = " *pulEncryptedPartLen = 0x%x";
-STRING fmt_spulPartLen[] = " *pulPartLen = 0x%x";
-STRING fmt_spulSignatureLen[] = " *pulSignatureLen = 0x%x";
-STRING fmt_ulAttributeCount[] = " ulAttributeCount = %d";
-STRING fmt_ulCount[] = " ulCount = %d";
-STRING fmt_ulDataLen[] = " ulDataLen = %d";
-STRING fmt_ulEncryptedPartLen[] = " ulEncryptedPartLen = %d";
-STRING fmt_ulPartLen[] = " ulPartLen = %d";
-STRING fmt_ulPinLen[] = " ulPinLen = %d";
-STRING fmt_ulSignatureLen[] = " ulSignatureLen = %d";
-
-STRING fmt_fwVersion[] = " firmware version: %d.%d";
-STRING fmt_hwVersion[] = " hardware version: %d.%d";
-STRING fmt_s_qsq_d[] = " %s = \"%s\" [%d]";
-STRING fmt_s_s_d[] = " %s = %s [%d]";
-STRING fmt_s_lu[] = " %s = %lu";
-STRING fmt_invalid_handle[] = " (CK_INVALID_HANDLE)";
-
-
-static void get_attr_type_str(CK_ATTRIBUTE_TYPE atype, char *str, int len)
-{
-#define CASE(attr) case attr: a = #attr ; break
-
- const char * a = NULL;
-
- switch (atype) {
- CASE(CKA_CLASS);
- CASE(CKA_TOKEN);
- CASE(CKA_PRIVATE);
- CASE(CKA_LABEL);
- CASE(CKA_APPLICATION);
- CASE(CKA_VALUE);
- CASE(CKA_OBJECT_ID);
- CASE(CKA_CERTIFICATE_TYPE);
- CASE(CKA_CERTIFICATE_CATEGORY);
- CASE(CKA_ISSUER);
- CASE(CKA_SERIAL_NUMBER);
- CASE(CKA_AC_ISSUER);
- CASE(CKA_OWNER);
- CASE(CKA_ATTR_TYPES);
- CASE(CKA_TRUSTED);
- CASE(CKA_KEY_TYPE);
- CASE(CKA_SUBJECT);
- CASE(CKA_ID);
- CASE(CKA_SENSITIVE);
- CASE(CKA_ENCRYPT);
- CASE(CKA_DECRYPT);
- CASE(CKA_WRAP);
- CASE(CKA_UNWRAP);
- CASE(CKA_SIGN);
- CASE(CKA_SIGN_RECOVER);
- CASE(CKA_VERIFY);
- CASE(CKA_VERIFY_RECOVER);
- CASE(CKA_DERIVE);
- CASE(CKA_START_DATE);
- CASE(CKA_END_DATE);
- CASE(CKA_MODULUS);
- CASE(CKA_MODULUS_BITS);
- CASE(CKA_PUBLIC_EXPONENT);
- CASE(CKA_PRIVATE_EXPONENT);
- CASE(CKA_PRIME_1);
- CASE(CKA_PRIME_2);
- CASE(CKA_EXPONENT_1);
- CASE(CKA_EXPONENT_2);
- CASE(CKA_COEFFICIENT);
- CASE(CKA_PRIME);
- CASE(CKA_SUBPRIME);
- CASE(CKA_BASE);
- CASE(CKA_PRIME_BITS);
- CASE(CKA_SUBPRIME_BITS);
- CASE(CKA_VALUE_BITS);
- CASE(CKA_VALUE_LEN);
- CASE(CKA_EXTRACTABLE);
- CASE(CKA_LOCAL);
- CASE(CKA_NEVER_EXTRACTABLE);
- CASE(CKA_ALWAYS_SENSITIVE);
- CASE(CKA_KEY_GEN_MECHANISM);
- CASE(CKA_MODIFIABLE);
- CASE(CKA_ECDSA_PARAMS);
- CASE(CKA_EC_POINT);
- CASE(CKA_SECONDARY_AUTH);
- CASE(CKA_AUTH_PIN_FLAGS);
- CASE(CKA_HW_FEATURE_TYPE);
- CASE(CKA_RESET_ON_INIT);
- CASE(CKA_HAS_RESET);
- CASE(CKA_VENDOR_DEFINED);
- CASE(CKA_NSS_URL);
- CASE(CKA_NSS_EMAIL);
- CASE(CKA_NSS_SMIME_INFO);
- CASE(CKA_NSS_SMIME_TIMESTAMP);
- CASE(CKA_NSS_PKCS8_SALT);
- CASE(CKA_NSS_PASSWORD_CHECK);
- CASE(CKA_NSS_EXPIRES);
- CASE(CKA_NSS_KRL);
- CASE(CKA_NSS_PQG_COUNTER);
- CASE(CKA_NSS_PQG_SEED);
- CASE(CKA_NSS_PQG_H);
- CASE(CKA_NSS_PQG_SEED_BITS);
- CASE(CKA_TRUST);
- CASE(CKA_TRUST_DIGITAL_SIGNATURE);
- CASE(CKA_TRUST_NON_REPUDIATION);
- CASE(CKA_TRUST_KEY_ENCIPHERMENT);
- CASE(CKA_TRUST_DATA_ENCIPHERMENT);
- CASE(CKA_TRUST_KEY_AGREEMENT);
- CASE(CKA_TRUST_KEY_CERT_SIGN);
- CASE(CKA_TRUST_CRL_SIGN);
- CASE(CKA_TRUST_SERVER_AUTH);
- CASE(CKA_TRUST_CLIENT_AUTH);
- CASE(CKA_TRUST_CODE_SIGNING);
- CASE(CKA_TRUST_EMAIL_PROTECTION);
- CASE(CKA_TRUST_IPSEC_END_SYSTEM);
- CASE(CKA_TRUST_IPSEC_TUNNEL);
- CASE(CKA_TRUST_IPSEC_USER);
- CASE(CKA_TRUST_TIME_STAMPING);
- CASE(CKA_CERT_SHA1_HASH);
- CASE(CKA_CERT_MD5_HASH);
- CASE(CKA_NETSCAPE_DB);
- CASE(CKA_NETSCAPE_TRUST);
- default: break;
- }
- if (a)
- PR_snprintf(str, len, "%s", a);
- else
- PR_snprintf(str, len, "0x%p", atype);
-}
-
-static void get_obj_class(CK_OBJECT_CLASS objClass, char *str, int len)
-{
-
- const char * a = NULL;
-
- switch (objClass) {
- CASE(CKO_DATA);
- CASE(CKO_CERTIFICATE);
- CASE(CKO_PUBLIC_KEY);
- CASE(CKO_PRIVATE_KEY);
- CASE(CKO_SECRET_KEY);
- CASE(CKO_HW_FEATURE);
- CASE(CKO_DOMAIN_PARAMETERS);
- CASE(CKO_NSS_CRL);
- CASE(CKO_NSS_SMIME);
- CASE(CKO_NSS_TRUST);
- CASE(CKO_NSS_BUILTIN_ROOT_LIST);
- default: break;
- }
- if (a)
- PR_snprintf(str, len, "%s", a);
- else
- PR_snprintf(str, len, "0x%p", objClass);
-}
-
-static void get_trust_val(CK_TRUST trust, char *str, int len)
-{
- const char * a = NULL;
-
- switch (trust) {
- CASE(CKT_NSS_TRUSTED);
- CASE(CKT_NSS_TRUSTED_DELEGATOR);
- CASE(CKT_NSS_NOT_TRUSTED);
- CASE(CKT_NSS_MUST_VERIFY_TRUST);
- CASE(CKT_NSS_TRUST_UNKNOWN);
- CASE(CKT_NSS_VALID_DELEGATOR);
- default: break;
- }
- if (a)
- PR_snprintf(str, len, "%s", a);
- else
- PR_snprintf(str, len, "0x%p", trust);
-}
-
-static void log_rv(CK_RV rv)
-{
- const char * a = NULL;
-
- switch (rv) {
- CASE(CKR_OK);
- CASE(CKR_CANCEL);
- CASE(CKR_HOST_MEMORY);
- CASE(CKR_SLOT_ID_INVALID);
- CASE(CKR_GENERAL_ERROR);
- CASE(CKR_FUNCTION_FAILED);
- CASE(CKR_ARGUMENTS_BAD);
- CASE(CKR_NO_EVENT);
- CASE(CKR_NEED_TO_CREATE_THREADS);
- CASE(CKR_CANT_LOCK);
- CASE(CKR_ATTRIBUTE_READ_ONLY);
- CASE(CKR_ATTRIBUTE_SENSITIVE);
- CASE(CKR_ATTRIBUTE_TYPE_INVALID);
- CASE(CKR_ATTRIBUTE_VALUE_INVALID);
- CASE(CKR_DATA_INVALID);
- CASE(CKR_DATA_LEN_RANGE);
- CASE(CKR_DEVICE_ERROR);
- CASE(CKR_DEVICE_MEMORY);
- CASE(CKR_DEVICE_REMOVED);
- CASE(CKR_ENCRYPTED_DATA_INVALID);
- CASE(CKR_ENCRYPTED_DATA_LEN_RANGE);
- CASE(CKR_FUNCTION_CANCELED);
- CASE(CKR_FUNCTION_NOT_PARALLEL);
- CASE(CKR_FUNCTION_NOT_SUPPORTED);
- CASE(CKR_KEY_HANDLE_INVALID);
- CASE(CKR_KEY_SIZE_RANGE);
- CASE(CKR_KEY_TYPE_INCONSISTENT);
- CASE(CKR_KEY_NOT_NEEDED);
- CASE(CKR_KEY_CHANGED);
- CASE(CKR_KEY_NEEDED);
- CASE(CKR_KEY_INDIGESTIBLE);
- CASE(CKR_KEY_FUNCTION_NOT_PERMITTED);
- CASE(CKR_KEY_NOT_WRAPPABLE);
- CASE(CKR_KEY_UNEXTRACTABLE);
- CASE(CKR_MECHANISM_INVALID);
- CASE(CKR_MECHANISM_PARAM_INVALID);
- CASE(CKR_OBJECT_HANDLE_INVALID);
- CASE(CKR_OPERATION_ACTIVE);
- CASE(CKR_OPERATION_NOT_INITIALIZED);
- CASE(CKR_PIN_INCORRECT);
- CASE(CKR_PIN_INVALID);
- CASE(CKR_PIN_LEN_RANGE);
- CASE(CKR_PIN_EXPIRED);
- CASE(CKR_PIN_LOCKED);
- CASE(CKR_SESSION_CLOSED);
- CASE(CKR_SESSION_COUNT);
- CASE(CKR_SESSION_HANDLE_INVALID);
- CASE(CKR_SESSION_PARALLEL_NOT_SUPPORTED);
- CASE(CKR_SESSION_READ_ONLY);
- CASE(CKR_SESSION_EXISTS);
- CASE(CKR_SESSION_READ_ONLY_EXISTS);
- CASE(CKR_SESSION_READ_WRITE_SO_EXISTS);
- CASE(CKR_SIGNATURE_INVALID);
- CASE(CKR_SIGNATURE_LEN_RANGE);
- CASE(CKR_TEMPLATE_INCOMPLETE);
- CASE(CKR_TEMPLATE_INCONSISTENT);
- CASE(CKR_TOKEN_NOT_PRESENT);
- CASE(CKR_TOKEN_NOT_RECOGNIZED);
- CASE(CKR_TOKEN_WRITE_PROTECTED);
- CASE(CKR_UNWRAPPING_KEY_HANDLE_INVALID);
- CASE(CKR_UNWRAPPING_KEY_SIZE_RANGE);
- CASE(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT);
- CASE(CKR_USER_ALREADY_LOGGED_IN);
- CASE(CKR_USER_NOT_LOGGED_IN);
- CASE(CKR_USER_PIN_NOT_INITIALIZED);
- CASE(CKR_USER_TYPE_INVALID);
- CASE(CKR_USER_ANOTHER_ALREADY_LOGGED_IN);
- CASE(CKR_USER_TOO_MANY_TYPES);
- CASE(CKR_WRAPPED_KEY_INVALID);
- CASE(CKR_WRAPPED_KEY_LEN_RANGE);
- CASE(CKR_WRAPPING_KEY_HANDLE_INVALID);
- CASE(CKR_WRAPPING_KEY_SIZE_RANGE);
- CASE(CKR_WRAPPING_KEY_TYPE_INCONSISTENT);
- CASE(CKR_RANDOM_SEED_NOT_SUPPORTED);
- CASE(CKR_RANDOM_NO_RNG);
- CASE(CKR_DOMAIN_PARAMS_INVALID);
- CASE(CKR_BUFFER_TOO_SMALL);
- CASE(CKR_SAVED_STATE_INVALID);
- CASE(CKR_INFORMATION_SENSITIVE);
- CASE(CKR_STATE_UNSAVEABLE);
- CASE(CKR_CRYPTOKI_NOT_INITIALIZED);
- CASE(CKR_CRYPTOKI_ALREADY_INITIALIZED);
- CASE(CKR_MUTEX_BAD);
- CASE(CKR_MUTEX_NOT_LOCKED);
- CASE(CKR_FUNCTION_REJECTED);
- CASE(CKR_KEY_PARAMS_INVALID);
- default: break;
- }
- if (a)
- PR_LOG(modlog, 1, (" rv = %s\n", a));
- else
- PR_LOG(modlog, 1, (" rv = 0x%x\n", rv));
-}
-
-static void log_state(CK_STATE state)
-{
- const char * a = NULL;
-
- switch (state) {
- CASE(CKS_RO_PUBLIC_SESSION);
- CASE(CKS_RO_USER_FUNCTIONS);
- CASE(CKS_RW_PUBLIC_SESSION);
- CASE(CKS_RW_USER_FUNCTIONS);
- CASE(CKS_RW_SO_FUNCTIONS);
- default: break;
- }
- if (a)
- PR_LOG(modlog, 1, (" state = %s\n", a));
- else
- PR_LOG(modlog, 1, (" state = 0x%x\n", state));
-}
-
-static void log_handle(int level, const char * format, CK_ULONG handle)
-{
- char fmtBuf[80];
- if (handle)
- PR_LOG(modlog, level, (format, handle));
- else {
- PL_strncpyz(fmtBuf, format, sizeof fmtBuf);
- PL_strcatn(fmtBuf, sizeof fmtBuf, fmt_invalid_handle);
- PR_LOG(modlog, level, (fmtBuf, handle));
- }
-}
-
-static void print_mechanism(CK_MECHANISM_PTR m)
-{
-
- const char * a = NULL;
-
- switch (m->mechanism) {
- CASE(CKM_AES_CBC);
- CASE(CKM_AES_CBC_ENCRYPT_DATA);
- CASE(CKM_AES_CBC_PAD);
- CASE(CKM_AES_ECB);
- CASE(CKM_AES_ECB_ENCRYPT_DATA);
- CASE(CKM_AES_KEY_GEN);
- CASE(CKM_AES_MAC);
- CASE(CKM_AES_MAC_GENERAL);
- CASE(CKM_CAMELLIA_CBC);
- CASE(CKM_CAMELLIA_CBC_ENCRYPT_DATA);
- CASE(CKM_CAMELLIA_CBC_PAD);
- CASE(CKM_CAMELLIA_ECB);
- CASE(CKM_CAMELLIA_ECB_ENCRYPT_DATA);
- CASE(CKM_CAMELLIA_KEY_GEN);
- CASE(CKM_CAMELLIA_MAC);
- CASE(CKM_CAMELLIA_MAC_GENERAL);
- CASE(CKM_CDMF_CBC);
- CASE(CKM_CDMF_CBC_PAD);
- CASE(CKM_CDMF_ECB);
- CASE(CKM_CDMF_KEY_GEN);
- CASE(CKM_CDMF_MAC);
- CASE(CKM_CDMF_MAC_GENERAL);
- CASE(CKM_CMS_SIG);
- CASE(CKM_CONCATENATE_BASE_AND_DATA);
- CASE(CKM_CONCATENATE_BASE_AND_KEY);
- CASE(CKM_CONCATENATE_DATA_AND_BASE);
- CASE(CKM_DES2_KEY_GEN);
- CASE(CKM_DES3_CBC);
- CASE(CKM_DES3_CBC_ENCRYPT_DATA);
- CASE(CKM_DES3_CBC_PAD);
- CASE(CKM_DES3_ECB);
- CASE(CKM_DES3_ECB_ENCRYPT_DATA);
- CASE(CKM_DES3_KEY_GEN);
- CASE(CKM_DES3_MAC);
- CASE(CKM_DES3_MAC_GENERAL);
- CASE(CKM_DES_CBC);
- CASE(CKM_DES_CBC_ENCRYPT_DATA);
- CASE(CKM_DES_CBC_PAD);
- CASE(CKM_DES_CFB64);
- CASE(CKM_DES_CFB8);
- CASE(CKM_DES_ECB);
- CASE(CKM_DES_ECB_ENCRYPT_DATA);
- CASE(CKM_DES_KEY_GEN);
- CASE(CKM_DES_MAC);
- CASE(CKM_DES_MAC_GENERAL);
- CASE(CKM_DES_OFB64);
- CASE(CKM_DES_OFB8);
- CASE(CKM_DH_PKCS_DERIVE);
- CASE(CKM_DH_PKCS_KEY_PAIR_GEN);
- CASE(CKM_DH_PKCS_PARAMETER_GEN);
- CASE(CKM_DSA);
- CASE(CKM_DSA_KEY_PAIR_GEN);
- CASE(CKM_DSA_PARAMETER_GEN);
- CASE(CKM_DSA_SHA1);
- CASE(CKM_ECDH1_COFACTOR_DERIVE);
- CASE(CKM_ECDH1_DERIVE);
- CASE(CKM_ECDSA);
- CASE(CKM_ECDSA_SHA1);
- CASE(CKM_ECMQV_DERIVE);
- CASE(CKM_EC_KEY_PAIR_GEN); /* also CASE(CKM_ECDSA_KEY_PAIR_GEN); */
- CASE(CKM_EXTRACT_KEY_FROM_KEY);
- CASE(CKM_FASTHASH);
- CASE(CKM_FORTEZZA_TIMESTAMP);
- CASE(CKM_GENERIC_SECRET_KEY_GEN);
- CASE(CKM_IDEA_CBC);
- CASE(CKM_IDEA_CBC_PAD);
- CASE(CKM_IDEA_ECB);
- CASE(CKM_IDEA_KEY_GEN);
- CASE(CKM_IDEA_MAC);
- CASE(CKM_IDEA_MAC_GENERAL);
- CASE(CKM_KEA_KEY_DERIVE);
- CASE(CKM_KEA_KEY_PAIR_GEN);
- CASE(CKM_KEY_WRAP_LYNKS);
- CASE(CKM_KEY_WRAP_SET_OAEP);
- CASE(CKM_MD2);
- CASE(CKM_MD2_HMAC);
- CASE(CKM_MD2_HMAC_GENERAL);
- CASE(CKM_MD2_KEY_DERIVATION);
- CASE(CKM_MD2_RSA_PKCS);
- CASE(CKM_MD5);
- CASE(CKM_MD5_HMAC);
- CASE(CKM_MD5_HMAC_GENERAL);
- CASE(CKM_MD5_KEY_DERIVATION);
- CASE(CKM_MD5_RSA_PKCS);
- CASE(CKM_PBA_SHA1_WITH_SHA1_HMAC);
- CASE(CKM_PBE_MD2_DES_CBC);
- CASE(CKM_PBE_MD5_DES_CBC);
- CASE(CKM_PBE_SHA1_DES2_EDE_CBC);
- CASE(CKM_PBE_SHA1_DES3_EDE_CBC);
- CASE(CKM_PBE_SHA1_RC2_128_CBC);
- CASE(CKM_PBE_SHA1_RC2_40_CBC);
- CASE(CKM_PBE_SHA1_RC4_128);
- CASE(CKM_PBE_SHA1_RC4_40);
- CASE(CKM_PKCS5_PBKD2);
- CASE(CKM_RC2_CBC);
- CASE(CKM_RC2_CBC_PAD);
- CASE(CKM_RC2_ECB);
- CASE(CKM_RC2_KEY_GEN);
- CASE(CKM_RC2_MAC);
- CASE(CKM_RC2_MAC_GENERAL);
- CASE(CKM_RC4);
- CASE(CKM_RC4_KEY_GEN);
- CASE(CKM_RC5_CBC);
- CASE(CKM_RC5_CBC_PAD);
- CASE(CKM_RC5_ECB);
- CASE(CKM_RC5_KEY_GEN);
- CASE(CKM_RC5_MAC);
- CASE(CKM_RC5_MAC_GENERAL);
- CASE(CKM_RIPEMD128);
- CASE(CKM_RIPEMD128_HMAC);
- CASE(CKM_RIPEMD128_HMAC_GENERAL);
- CASE(CKM_RIPEMD128_RSA_PKCS);
- CASE(CKM_RIPEMD160);
- CASE(CKM_RIPEMD160_HMAC);
- CASE(CKM_RIPEMD160_HMAC_GENERAL);
- CASE(CKM_RIPEMD160_RSA_PKCS);
- CASE(CKM_RSA_9796);
- CASE(CKM_RSA_PKCS);
- CASE(CKM_RSA_PKCS_KEY_PAIR_GEN);
- CASE(CKM_RSA_PKCS_OAEP);
- CASE(CKM_RSA_PKCS_PSS);
- CASE(CKM_RSA_X9_31);
- CASE(CKM_RSA_X9_31_KEY_PAIR_GEN);
- CASE(CKM_RSA_X_509);
- CASE(CKM_SHA1_KEY_DERIVATION);
- CASE(CKM_SHA1_RSA_PKCS);
- CASE(CKM_SHA1_RSA_PKCS_PSS);
- CASE(CKM_SHA1_RSA_X9_31);
- CASE(CKM_SHA224);
- CASE(CKM_SHA224_HMAC);
- CASE(CKM_SHA224_HMAC_GENERAL);
- CASE(CKM_SHA224_KEY_DERIVATION);
- CASE(CKM_SHA224_RSA_PKCS);
- CASE(CKM_SHA224_RSA_PKCS_PSS);
- CASE(CKM_SHA256);
- CASE(CKM_SHA256_HMAC);
- CASE(CKM_SHA256_HMAC_GENERAL);
- CASE(CKM_SHA256_KEY_DERIVATION);
- CASE(CKM_SHA256_RSA_PKCS);
- CASE(CKM_SHA256_RSA_PKCS_PSS);
- CASE(CKM_SHA384);
- CASE(CKM_SHA384_HMAC);
- CASE(CKM_SHA384_HMAC_GENERAL);
- CASE(CKM_SHA384_KEY_DERIVATION);
- CASE(CKM_SHA384_RSA_PKCS);
- CASE(CKM_SHA384_RSA_PKCS_PSS);
- CASE(CKM_SHA512);
- CASE(CKM_SHA512_HMAC);
- CASE(CKM_SHA512_HMAC_GENERAL);
- CASE(CKM_SHA512_KEY_DERIVATION);
- CASE(CKM_SHA512_RSA_PKCS);
- CASE(CKM_SHA512_RSA_PKCS_PSS);
- CASE(CKM_SHA_1);
- CASE(CKM_SHA_1_HMAC);
- CASE(CKM_SHA_1_HMAC_GENERAL);
- CASE(CKM_SKIPJACK_CBC64);
- CASE(CKM_SKIPJACK_CFB16);
- CASE(CKM_SKIPJACK_CFB32);
- CASE(CKM_SKIPJACK_CFB64);
- CASE(CKM_SKIPJACK_CFB8);
- CASE(CKM_SKIPJACK_ECB64);
- CASE(CKM_SKIPJACK_KEY_GEN);
- CASE(CKM_SKIPJACK_OFB64);
- CASE(CKM_SKIPJACK_PRIVATE_WRAP);
- CASE(CKM_SKIPJACK_RELAYX);
- CASE(CKM_SKIPJACK_WRAP);
- CASE(CKM_SSL3_KEY_AND_MAC_DERIVE);
- CASE(CKM_SSL3_MASTER_KEY_DERIVE);
- CASE(CKM_SSL3_MASTER_KEY_DERIVE_DH);
- CASE(CKM_SSL3_MD5_MAC);
- CASE(CKM_SSL3_PRE_MASTER_KEY_GEN);
- CASE(CKM_SSL3_SHA1_MAC);
- CASE(CKM_TLS_KEY_AND_MAC_DERIVE);
- CASE(CKM_TLS_MASTER_KEY_DERIVE);
- CASE(CKM_TLS_MASTER_KEY_DERIVE_DH);
- CASE(CKM_TLS_PRE_MASTER_KEY_GEN);
- CASE(CKM_TLS_PRF);
- CASE(CKM_TWOFISH_CBC);
- CASE(CKM_TWOFISH_KEY_GEN);
- CASE(CKM_X9_42_DH_DERIVE);
- CASE(CKM_X9_42_DH_HYBRID_DERIVE);
- CASE(CKM_X9_42_DH_KEY_PAIR_GEN);
- CASE(CKM_X9_42_DH_PARAMETER_GEN);
- CASE(CKM_X9_42_MQV_DERIVE);
- CASE(CKM_XOR_BASE_AND_DATA);
- default: break;
- }
- if (a)
- PR_LOG(modlog, 4, (" mechanism = %s", a));
- else
- PR_LOG(modlog, 4, (" mechanism = 0x%p", m->mechanism));
-}
-
-static void get_key_type(CK_KEY_TYPE keyType, char *str, int len)
-{
-
- const char * a = NULL;
-
- switch (keyType) {
- CASE(CKK_AES);
- CASE(CKK_CAMELLIA);
- CASE(CKK_CDMF);
- CASE(CKK_DES);
- CASE(CKK_DES2);
- CASE(CKK_DES3);
- CASE(CKK_DH);
- CASE(CKK_DSA);
- CASE(CKK_EC); /* also CASE(CKK_ECDSA); */
- CASE(CKK_GENERIC_SECRET);
- CASE(CKK_IDEA);
- CASE(CKK_INVALID_KEY_TYPE);
- CASE(CKK_KEA);
- CASE(CKK_RC2);
- CASE(CKK_RC4);
- CASE(CKK_RC5);
- CASE(CKK_RSA);
- CASE(CKK_SKIPJACK);
- CASE(CKK_TWOFISH);
- CASE(CKK_X9_42_DH);
- default: break;
- }
- if (a)
- PR_snprintf(str, len, "%s", a);
- else
- PR_snprintf(str, len, "0x%p", keyType);
-}
-
-static void print_attr_value(CK_ATTRIBUTE_PTR attr)
-{
- char atype[48];
- char valstr[49];
- int len;
-
- get_attr_type_str(attr->type, atype, sizeof atype);
- switch (attr->type) {
- case CKA_ALWAYS_SENSITIVE:
- case CKA_DECRYPT:
- case CKA_DERIVE:
- case CKA_ENCRYPT:
- case CKA_EXTRACTABLE:
- case CKA_LOCAL:
- case CKA_MODIFIABLE:
- case CKA_NEVER_EXTRACTABLE:
- case CKA_PRIVATE:
- case CKA_SENSITIVE:
- case CKA_SIGN:
- case CKA_SIGN_RECOVER:
- case CKA_TOKEN:
- case CKA_UNWRAP:
- case CKA_VERIFY:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- if (attr->ulValueLen > 0 && attr->pValue) {
- CK_BBOOL tf = *((CK_BBOOL *)attr->pValue);
- PR_LOG(modlog, 4, (fmt_s_s_d,
- atype, tf ? "CK_TRUE" : "CK_FALSE", attr->ulValueLen));
- break;
- }
- case CKA_CLASS:
- if (attr->ulValueLen > 0 && attr->pValue) {
- CK_OBJECT_CLASS objClass = *((CK_OBJECT_CLASS *)attr->pValue);
- get_obj_class(objClass, valstr, sizeof valstr);
- PR_LOG(modlog, 4, (fmt_s_s_d,
- atype, valstr, attr->ulValueLen));
- break;
- }
- case CKA_TRUST_CLIENT_AUTH:
- case CKA_TRUST_CODE_SIGNING:
- case CKA_TRUST_EMAIL_PROTECTION:
- case CKA_TRUST_SERVER_AUTH:
- if (attr->ulValueLen > 0 && attr->pValue) {
- CK_TRUST trust = *((CK_TRUST *)attr->pValue);
- get_trust_val(trust, valstr, sizeof valstr);
- PR_LOG(modlog, 4, (fmt_s_s_d,
- atype, valstr, attr->ulValueLen));
- break;
- }
- case CKA_KEY_TYPE:
- if (attr->ulValueLen > 0 && attr->pValue) {
- CK_KEY_TYPE keyType = *((CK_KEY_TYPE *)attr->pValue);
- get_key_type(keyType, valstr, sizeof valstr);
- PR_LOG(modlog, 4, (fmt_s_s_d,
- atype, valstr, attr->ulValueLen));
- break;
- }
- case CKA_PIXEL_X:
- case CKA_PIXEL_Y:
- case CKA_RESOLUTION:
- case CKA_CHAR_ROWS:
- case CKA_CHAR_COLUMNS:
- case CKA_BITS_PER_PIXEL:
- case CKA_CERTIFICATE_CATEGORY: /* should print as enum/string */
- case CKA_JAVA_MIDP_SECURITY_DOMAIN: /* should print as enum/string */
- case CKA_MODULUS_BITS:
- case CKA_PRIME_BITS:
- case CKA_SUBPRIME_BITS:
- case CKA_VALUE_BITS:
- case CKA_VALUE_LEN:
- if (attr->ulValueLen > 0 && attr->pValue) {
- CK_ULONG valueLen = *((CK_ULONG *)attr->pValue);
- /* XXX check for the special value CK_UNAVAILABLE_INFORMATION */
- PR_LOG(modlog, 4, (fmt_s_lu, atype, (PRUint32)valueLen));
- break;
- }
- case CKA_LABEL:
- case CKA_NSS_EMAIL:
- case CKA_NSS_URL:
- if (attr->ulValueLen > 0 && attr->pValue) {
- len = PR_MIN(attr->ulValueLen + 1, sizeof valstr);
- PR_snprintf(valstr, len, "%s", attr->pValue);
- PR_LOG(modlog, 4, (fmt_s_qsq_d,
- atype, valstr, attr->ulValueLen));
- break;
- }
- case CKA_ISSUER:
- case CKA_SUBJECT:
- if (attr->ulValueLen > 0 && attr->pValue) {
- char * asciiName;
- SECItem derName;
- derName.type = siDERNameBuffer;
- derName.data = attr->pValue;
- derName.len = attr->ulValueLen;
- asciiName = CERT_DerNameToAscii(&derName);
- if (asciiName) {
- PR_LOG(modlog, 4, (fmt_s_s_d,
- atype, asciiName, attr->ulValueLen));
- PORT_Free(asciiName);
- break;
- }
- /* else treat like a binary buffer */
- goto binary_buffer;
- }
- case CKA_ID:
- if (attr->ulValueLen > 0 && attr->pValue) {
- unsigned char * pV = attr->pValue;
- for (len = (int)attr->ulValueLen; len > 0; --len) {
- unsigned int ch = *pV++;
- if (ch >= 0x20 && ch < 0x7f)
- continue;
- if (!ch && len == 1) /* will ignore NUL if last character */
- continue;
- break;
- }
- if (!len) { /* entire string is printable */
- len = PR_MIN(attr->ulValueLen + 1, sizeof valstr);
- PR_snprintf(valstr, len, "%s", attr->pValue);
- PR_LOG(modlog, 4, (fmt_s_qsq_d,
- atype, valstr, attr->ulValueLen));
- break;
- }
- /* else fall through and treat like a binary buffer */
- }
-binary_buffer:
- case CKA_SERIAL_NUMBER:
- default:
- if (attr->ulValueLen > 0 && attr->pValue) {
- char * hexBuf;
- SECItem attrBuf;
- attrBuf.type = siDERNameBuffer;
- attrBuf.data = attr->pValue;
- attrBuf.len = PR_MIN(attr->ulValueLen, (sizeof valstr)/2);
-
- hexBuf = CERT_Hexify(&attrBuf, PR_FALSE);
- if (hexBuf) {
- PR_LOG(modlog, 4, (fmt_s_s_d,
- atype, hexBuf, attr->ulValueLen));
- PORT_Free(hexBuf);
- break;
- }
- /* else fall through and show only the address. :( */
- }
- PR_LOG(modlog, 4, (" %s = [0x%p] [%d]",
- atype, attr->pValue, attr->ulValueLen));
- break;
- }
-}
-
-static void print_template(CK_ATTRIBUTE_PTR templ, CK_ULONG tlen)
-{
- CK_ULONG i;
- for (i=0; i<tlen; i++) {
- print_attr_value(&templ[i]);
- }
-}
-
-struct nssdbg_prof_str {
- PRUint32 time;
- PRUint32 calls;
- char *function;
-};
-
-#define NSSDBG_DEFINE(func) { 0, 0, #func }
-
-struct nssdbg_prof_str nssdbg_prof_data[] = {
-#define FUNC_C_INITIALIZE 0
- NSSDBG_DEFINE(C_Initialize),
-#define FUNC_C_FINALIZE 1
- NSSDBG_DEFINE(C_Finalize),
-#define FUNC_C_GETINFO 2
- NSSDBG_DEFINE(C_GetInfo),
-#define FUNC_C_GETFUNCITONLIST 3
- NSSDBG_DEFINE(C_GetFunctionList),
-#define FUNC_C_GETSLOTLIST 4
- NSSDBG_DEFINE(C_GetSlotList),
-#define FUNC_C_GETSLOTINFO 5
- NSSDBG_DEFINE(C_GetSlotInfo),
-#define FUNC_C_GETTOKENINFO 6
- NSSDBG_DEFINE(C_GetTokenInfo),
-#define FUNC_C_GETMECHANISMLIST 7
- NSSDBG_DEFINE(C_GetMechanismList),
-#define FUNC_C_GETMECHANISMINFO 8
- NSSDBG_DEFINE(C_GetMechanismInfo),
-#define FUNC_C_INITTOKEN 9
- NSSDBG_DEFINE(C_InitToken),
-#define FUNC_C_INITPIN 10
- NSSDBG_DEFINE(C_InitPIN),
-#define FUNC_C_SETPIN 11
- NSSDBG_DEFINE(C_SetPIN),
-#define FUNC_C_OPENSESSION 12
- NSSDBG_DEFINE(C_OpenSession),
-#define FUNC_C_CLOSESESSION 13
- NSSDBG_DEFINE(C_CloseSession),
-#define FUNC_C_CLOSEALLSESSIONS 14
- NSSDBG_DEFINE(C_CloseAllSessions),
-#define FUNC_C_GETSESSIONINFO 15
- NSSDBG_DEFINE(C_GetSessionInfo),
-#define FUNC_C_GETOPERATIONSTATE 16
- NSSDBG_DEFINE(C_GetOperationState),
-#define FUNC_C_SETOPERATIONSTATE 17
- NSSDBG_DEFINE(C_SetOperationState),
-#define FUNC_C_LOGIN 18
- NSSDBG_DEFINE(C_Login),
-#define FUNC_C_LOGOUT 19
- NSSDBG_DEFINE(C_Logout),
-#define FUNC_C_CREATEOBJECT 20
- NSSDBG_DEFINE(C_CreateObject),
-#define FUNC_C_COPYOBJECT 21
- NSSDBG_DEFINE(C_CopyObject),
-#define FUNC_C_DESTROYOBJECT 22
- NSSDBG_DEFINE(C_DestroyObject),
-#define FUNC_C_GETOBJECTSIZE 23
- NSSDBG_DEFINE(C_GetObjectSize),
-#define FUNC_C_GETATTRIBUTEVALUE 24
- NSSDBG_DEFINE(C_GetAttributeValue),
-#define FUNC_C_SETATTRIBUTEVALUE 25
- NSSDBG_DEFINE(C_SetAttributeValue),
-#define FUNC_C_FINDOBJECTSINIT 26
- NSSDBG_DEFINE(C_FindObjectsInit),
-#define FUNC_C_FINDOBJECTS 27
- NSSDBG_DEFINE(C_FindObjects),
-#define FUNC_C_FINDOBJECTSFINAL 28
- NSSDBG_DEFINE(C_FindObjectsFinal),
-#define FUNC_C_ENCRYPTINIT 29
- NSSDBG_DEFINE(C_EncryptInit),
-#define FUNC_C_ENCRYPT 30
- NSSDBG_DEFINE(C_Encrypt),
-#define FUNC_C_ENCRYPTUPDATE 31
- NSSDBG_DEFINE(C_EncryptUpdate),
-#define FUNC_C_ENCRYPTFINAL 32
- NSSDBG_DEFINE(C_EncryptFinal),
-#define FUNC_C_DECRYPTINIT 33
- NSSDBG_DEFINE(C_DecryptInit),
-#define FUNC_C_DECRYPT 34
- NSSDBG_DEFINE(C_Decrypt),
-#define FUNC_C_DECRYPTUPDATE 35
- NSSDBG_DEFINE(C_DecryptUpdate),
-#define FUNC_C_DECRYPTFINAL 36
- NSSDBG_DEFINE(C_DecryptFinal),
-#define FUNC_C_DIGESTINIT 37
- NSSDBG_DEFINE(C_DigestInit),
-#define FUNC_C_DIGEST 38
- NSSDBG_DEFINE(C_Digest),
-#define FUNC_C_DIGESTUPDATE 39
- NSSDBG_DEFINE(C_DigestUpdate),
-#define FUNC_C_DIGESTKEY 40
- NSSDBG_DEFINE(C_DigestKey),
-#define FUNC_C_DIGESTFINAL 41
- NSSDBG_DEFINE(C_DigestFinal),
-#define FUNC_C_SIGNINIT 42
- NSSDBG_DEFINE(C_SignInit),
-#define FUNC_C_SIGN 43
- NSSDBG_DEFINE(C_Sign),
-#define FUNC_C_SIGNUPDATE 44
- NSSDBG_DEFINE(C_SignUpdate),
-#define FUNC_C_SIGNFINAL 45
- NSSDBG_DEFINE(C_SignFinal),
-#define FUNC_C_SIGNRECOVERINIT 46
- NSSDBG_DEFINE(C_SignRecoverInit),
-#define FUNC_C_SIGNRECOVER 47
- NSSDBG_DEFINE(C_SignRecover),
-#define FUNC_C_VERIFYINIT 48
- NSSDBG_DEFINE(C_VerifyInit),
-#define FUNC_C_VERIFY 49
- NSSDBG_DEFINE(C_Verify),
-#define FUNC_C_VERIFYUPDATE 50
- NSSDBG_DEFINE(C_VerifyUpdate),
-#define FUNC_C_VERIFYFINAL 51
- NSSDBG_DEFINE(C_VerifyFinal),
-#define FUNC_C_VERIFYRECOVERINIT 52
- NSSDBG_DEFINE(C_VerifyRecoverInit),
-#define FUNC_C_VERIFYRECOVER 53
- NSSDBG_DEFINE(C_VerifyRecover),
-#define FUNC_C_DIGESTENCRYPTUPDATE 54
- NSSDBG_DEFINE(C_DigestEncryptUpdate),
-#define FUNC_C_DECRYPTDIGESTUPDATE 55
- NSSDBG_DEFINE(C_DecryptDigestUpdate),
-#define FUNC_C_SIGNENCRYPTUPDATE 56
- NSSDBG_DEFINE(C_SignEncryptUpdate),
-#define FUNC_C_DECRYPTVERIFYUPDATE 57
- NSSDBG_DEFINE(C_DecryptVerifyUpdate),
-#define FUNC_C_GENERATEKEY 58
- NSSDBG_DEFINE(C_GenerateKey),
-#define FUNC_C_GENERATEKEYPAIR 59
- NSSDBG_DEFINE(C_GenerateKeyPair),
-#define FUNC_C_WRAPKEY 60
- NSSDBG_DEFINE(C_WrapKey),
-#define FUNC_C_UNWRAPKEY 61
- NSSDBG_DEFINE(C_UnWrapKey),
-#define FUNC_C_DERIVEKEY 62
- NSSDBG_DEFINE(C_DeriveKey),
-#define FUNC_C_SEEDRANDOM 63
- NSSDBG_DEFINE(C_SeedRandom),
-#define FUNC_C_GENERATERANDOM 64
- NSSDBG_DEFINE(C_GenerateRandom),
-#define FUNC_C_GETFUNCTIONSTATUS 65
- NSSDBG_DEFINE(C_GetFunctionStatus),
-#define FUNC_C_CANCELFUNCTION 66
- NSSDBG_DEFINE(C_CancelFunction),
-#define FUNC_C_WAITFORSLOTEVENT 67
- NSSDBG_DEFINE(C_WaitForSlotEvent)
-};
-
-int nssdbg_prof_size = sizeof(nssdbg_prof_data)/sizeof(nssdbg_prof_data[0]);
-
-
-static void nssdbg_finish_time(PRInt32 fun_number, PRIntervalTime start)
-{
- PRIntervalTime ival;
- PRIntervalTime end = PR_IntervalNow();
-
- ival = end-start;
- /* sigh, lie to PRAtomic add and say we are using signed values */
- PR_ATOMIC_ADD((PRInt32 *)&nssdbg_prof_data[fun_number].time, (PRInt32)ival);
-}
-
-static void nssdbg_start_time(PRInt32 fun_number, PRIntervalTime *start)
-{
- PR_ATOMIC_INCREMENT((PRInt32 *)&nssdbg_prof_data[fun_number].calls);
- *start = PR_IntervalNow();
-}
-
-#define COMMON_DEFINITIONS \
- CK_RV rv; \
- PRIntervalTime start
-
-CK_RV NSSDBGC_Initialize(
- CK_VOID_PTR pInitArgs
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_Initialize"));
- PR_LOG(modlog, 3, (" pInitArgs = 0x%p", pInitArgs));
- nssdbg_start_time(FUNC_C_INITIALIZE,&start);
- rv = module_functions->C_Initialize(pInitArgs);
- nssdbg_finish_time(FUNC_C_INITIALIZE,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_Finalize(
- CK_VOID_PTR pReserved
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_Finalize"));
- PR_LOG(modlog, 3, (" pReserved = 0x%p", pReserved));
- nssdbg_start_time(FUNC_C_FINALIZE,&start);
- rv = module_functions->C_Finalize(pReserved);
- nssdbg_finish_time(FUNC_C_FINALIZE,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetInfo(
- CK_INFO_PTR pInfo
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetInfo"));
- PR_LOG(modlog, 3, (fmt_pInfo, pInfo));
- nssdbg_start_time(FUNC_C_GETINFO,&start);
- rv = module_functions->C_GetInfo(pInfo);
- nssdbg_finish_time(FUNC_C_GETINFO,start);
- if (rv == CKR_OK) {
- PR_LOG(modlog, 4, (" cryptoki version: %d.%d",
- pInfo->cryptokiVersion.major,
- pInfo->cryptokiVersion.minor));
- PR_LOG(modlog, 4, (fmt_manufacturerID, pInfo->manufacturerID));
- PR_LOG(modlog, 4, (" library description = \"%.32s\"",
- pInfo->libraryDescription));
- PR_LOG(modlog, 4, (" library version: %d.%d",
- pInfo->libraryVersion.major,
- pInfo->libraryVersion.minor));
- }
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetFunctionList(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetFunctionList"));
- PR_LOG(modlog, 3, (" ppFunctionList = 0x%p", ppFunctionList));
- nssdbg_start_time(FUNC_C_GETFUNCITONLIST,&start);
- rv = module_functions->C_GetFunctionList(ppFunctionList);
- nssdbg_finish_time(FUNC_C_GETFUNCITONLIST,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetSlotList(
- CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount
-)
-{
- COMMON_DEFINITIONS;
-
- CK_ULONG i;
- PR_LOG(modlog, 1, ("C_GetSlotList"));
- PR_LOG(modlog, 3, (" tokenPresent = 0x%x", tokenPresent));
- PR_LOG(modlog, 3, (" pSlotList = 0x%p", pSlotList));
- PR_LOG(modlog, 3, (fmt_pulCount, pulCount));
- nssdbg_start_time(FUNC_C_GETSLOTLIST,&start);
- rv = module_functions->C_GetSlotList(tokenPresent, pSlotList, pulCount);
- nssdbg_finish_time(FUNC_C_GETSLOTLIST,start);
- PR_LOG(modlog, 4, (fmt_spulCount, *pulCount));
- if (pSlotList) {
- for (i=0; i<*pulCount; i++) {
- PR_LOG(modlog, 4, (" slotID[%d] = %x", i, pSlotList[i]));
- }
- }
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetSlotInfo(
- CK_SLOT_ID slotID,
- CK_SLOT_INFO_PTR pInfo
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetSlotInfo"));
- PR_LOG(modlog, 3, (fmt_slotID, slotID));
- PR_LOG(modlog, 3, (fmt_pInfo, pInfo));
- nssdbg_start_time(FUNC_C_GETSLOTINFO,&start);
- rv = module_functions->C_GetSlotInfo(slotID, pInfo);
- nssdbg_finish_time(FUNC_C_GETSLOTINFO,start);
- if (rv == CKR_OK) {
- PR_LOG(modlog, 4, (" slotDescription = \"%.64s\"",
- pInfo->slotDescription));
- PR_LOG(modlog, 4, (fmt_manufacturerID, pInfo->manufacturerID));
- PR_LOG(modlog, 4, (" flags = %s %s %s",
- pInfo->flags & CKF_HW_SLOT ? "CKF_HW_SLOT" : "",
- pInfo->flags & CKF_REMOVABLE_DEVICE ? "CKF_REMOVABLE_DEVICE" : "",
- pInfo->flags & CKF_TOKEN_PRESENT ? "CKF_TOKEN_PRESENT" : ""));
- PR_LOG(modlog, 4, (fmt_hwVersion,
- pInfo->hardwareVersion.major,
- pInfo->hardwareVersion.minor));
- PR_LOG(modlog, 4, (fmt_fwVersion,
- pInfo->firmwareVersion.major,
- pInfo->firmwareVersion.minor));
- }
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetTokenInfo(
- CK_SLOT_ID slotID,
- CK_TOKEN_INFO_PTR pInfo
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetTokenInfo"));
- PR_LOG(modlog, 3, (fmt_slotID, slotID));
- PR_LOG(modlog, 3, (fmt_pInfo, pInfo));
- nssdbg_start_time(FUNC_C_GETTOKENINFO,&start);
- rv = module_functions->C_GetTokenInfo(slotID, pInfo);
- nssdbg_finish_time(FUNC_C_GETTOKENINFO,start);
- if (rv == CKR_OK) {
- PR_LOG(modlog, 4, (" label = \"%.32s\"", pInfo->label));
- PR_LOG(modlog, 4, (fmt_manufacturerID, pInfo->manufacturerID));
- PR_LOG(modlog, 4, (" model = \"%.16s\"", pInfo->model));
- PR_LOG(modlog, 4, (" serial = \"%.16s\"", pInfo->serialNumber));
- PR_LOG(modlog, 4, (" flags = %s %s %s %s",
- pInfo->flags & CKF_RNG ? "CKF_RNG" : "",
- pInfo->flags & CKF_WRITE_PROTECTED ? "CKF_WRITE_PROTECTED" : "",
- pInfo->flags & CKF_LOGIN_REQUIRED ? "CKF_LOGIN_REQUIRED" : "",
- pInfo->flags & CKF_USER_PIN_INITIALIZED ? "CKF_USER_PIN_INIT" : ""));
- PR_LOG(modlog, 4, (" maxSessions = %u, Sessions = %u",
- pInfo->ulMaxSessionCount, pInfo->ulSessionCount));
- PR_LOG(modlog, 4, (" maxRwSessions = %u, RwSessions = %u",
- pInfo->ulMaxRwSessionCount,
- pInfo->ulRwSessionCount));
- /* ignore Max & Min Pin Len, Public and Private Memory */
- PR_LOG(modlog, 4, (fmt_hwVersion,
- pInfo->hardwareVersion.major,
- pInfo->hardwareVersion.minor));
- PR_LOG(modlog, 4, (fmt_fwVersion,
- pInfo->firmwareVersion.major,
- pInfo->firmwareVersion.minor));
- }
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetMechanismList(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetMechanismList"));
- PR_LOG(modlog, 3, (fmt_slotID, slotID));
- PR_LOG(modlog, 3, (" pMechanismList = 0x%p", pMechanismList));
- PR_LOG(modlog, 3, (fmt_pulCount, pulCount));
- nssdbg_start_time(FUNC_C_GETMECHANISMLIST,&start);
- rv = module_functions->C_GetMechanismList(slotID,
- pMechanismList,
- pulCount);
- nssdbg_finish_time(FUNC_C_GETMECHANISMLIST,start);
- PR_LOG(modlog, 4, (fmt_spulCount, *pulCount));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetMechanismInfo(
- CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetMechanismInfo"));
- PR_LOG(modlog, 3, (fmt_slotID, slotID));
- PR_LOG(modlog, 3, (" type = 0x%x", type));
- PR_LOG(modlog, 3, (fmt_pInfo, pInfo));
- nssdbg_start_time(FUNC_C_GETMECHANISMINFO,&start);
- rv = module_functions->C_GetMechanismInfo(slotID,
- type,
- pInfo);
- nssdbg_finish_time(FUNC_C_GETMECHANISMINFO,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_InitToken(
- CK_SLOT_ID slotID,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,
- CK_CHAR_PTR pLabel
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_InitToken"));
- PR_LOG(modlog, 3, (fmt_slotID, slotID));
- PR_LOG(modlog, 3, (fmt_pPin, pPin));
- PR_LOG(modlog, 3, (fmt_ulPinLen, ulPinLen));
- PR_LOG(modlog, 3, (" pLabel = 0x%p", pLabel));
- nssdbg_start_time(FUNC_C_INITTOKEN,&start);
- rv = module_functions->C_InitToken(slotID,
- pPin,
- ulPinLen,
- pLabel);
- nssdbg_finish_time(FUNC_C_INITTOKEN,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_InitPIN(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_InitPIN"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pPin, pPin));
- PR_LOG(modlog, 3, (fmt_ulPinLen, ulPinLen));
- nssdbg_start_time(FUNC_C_INITPIN,&start);
- rv = module_functions->C_InitPIN(hSession,
- pPin,
- ulPinLen);
- nssdbg_finish_time(FUNC_C_INITPIN,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SetPIN(
- CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen,
- CK_CHAR_PTR pNewPin,
- CK_ULONG ulNewLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SetPIN"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (" pOldPin = 0x%p", pOldPin));
- PR_LOG(modlog, 3, (" ulOldLen = %d", ulOldLen));
- PR_LOG(modlog, 3, (" pNewPin = 0x%p", pNewPin));
- PR_LOG(modlog, 3, (" ulNewLen = %d", ulNewLen));
- nssdbg_start_time(FUNC_C_SETPIN,&start);
- rv = module_functions->C_SetPIN(hSession,
- pOldPin,
- ulOldLen,
- pNewPin,
- ulNewLen);
- nssdbg_finish_time(FUNC_C_SETPIN,start);
- log_rv(rv);
- return rv;
-}
-
-static PRUint32 numOpenSessions = 0;
-static PRUint32 maxOpenSessions = 0;
-
-CK_RV NSSDBGC_OpenSession(
- CK_SLOT_ID slotID,
- CK_FLAGS flags,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_SESSION_HANDLE_PTR phSession
-)
-{
- COMMON_DEFINITIONS;
-
- PR_ATOMIC_INCREMENT((PRInt32 *)&numOpenSessions);
- maxOpenSessions = PR_MAX(numOpenSessions, maxOpenSessions);
- PR_LOG(modlog, 1, ("C_OpenSession"));
- PR_LOG(modlog, 3, (fmt_slotID, slotID));
- PR_LOG(modlog, 3, (fmt_flags, flags));
- PR_LOG(modlog, 3, (" pApplication = 0x%p", pApplication));
- PR_LOG(modlog, 3, (" Notify = 0x%x", Notify));
- PR_LOG(modlog, 3, (" phSession = 0x%p", phSession));
- nssdbg_start_time(FUNC_C_OPENSESSION,&start);
- rv = module_functions->C_OpenSession(slotID,
- flags,
- pApplication,
- Notify,
- phSession);
- nssdbg_finish_time(FUNC_C_OPENSESSION,start);
- log_handle(4, " *phSession = 0x%x", *phSession);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_CloseSession(
- CK_SESSION_HANDLE hSession
-)
-{
- COMMON_DEFINITIONS;
-
- PR_ATOMIC_DECREMENT((PRInt32 *)&numOpenSessions);
- PR_LOG(modlog, 1, ("C_CloseSession"));
- log_handle(3, fmt_hSession, hSession);
- nssdbg_start_time(FUNC_C_CLOSESESSION,&start);
- rv = module_functions->C_CloseSession(hSession);
- nssdbg_finish_time(FUNC_C_CLOSESESSION,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_CloseAllSessions(
- CK_SLOT_ID slotID
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_CloseAllSessions"));
- PR_LOG(modlog, 3, (fmt_slotID, slotID));
- nssdbg_start_time(FUNC_C_CLOSEALLSESSIONS,&start);
- rv = module_functions->C_CloseAllSessions(slotID);
- nssdbg_finish_time(FUNC_C_CLOSEALLSESSIONS,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetSessionInfo(
- CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetSessionInfo"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pInfo, pInfo));
- nssdbg_start_time(FUNC_C_GETSESSIONINFO,&start);
- rv = module_functions->C_GetSessionInfo(hSession,
- pInfo);
- nssdbg_finish_time(FUNC_C_GETSESSIONINFO,start);
- if (rv == CKR_OK) {
- PR_LOG(modlog, 4, (fmt_slotID, pInfo->slotID));
- log_state(pInfo->state);
- PR_LOG(modlog, 4, (" flags = %s %s",
- pInfo->flags & CKF_RW_SESSION ? "CKF_RW_SESSION" : "",
- pInfo->flags & CKF_SERIAL_SESSION ? "CKF_SERIAL_SESSION" : ""));
- PR_LOG(modlog, 4, (" deviceError = 0x%x", pInfo->ulDeviceError));
- }
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetOperationState(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG_PTR pulOperationStateLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetOperationState"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pOperationState, pOperationState));
- PR_LOG(modlog, 3, (" pulOperationStateLen = 0x%p", pulOperationStateLen));
- nssdbg_start_time(FUNC_C_GETOPERATIONSTATE,&start);
- rv = module_functions->C_GetOperationState(hSession,
- pOperationState,
- pulOperationStateLen);
- nssdbg_finish_time(FUNC_C_GETOPERATIONSTATE,start);
- PR_LOG(modlog, 4, (" *pulOperationStateLen = 0x%x", *pulOperationStateLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SetOperationState(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey,
- CK_OBJECT_HANDLE hAuthenticationKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SetOperationState"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pOperationState, pOperationState));
- PR_LOG(modlog, 3, (" ulOperationStateLen = %d", ulOperationStateLen));
- log_handle(3, " hEncryptionKey = 0x%x", hEncryptionKey);
- log_handle(3, " hAuthenticationKey = 0x%x", hAuthenticationKey);
- nssdbg_start_time(FUNC_C_SETOPERATIONSTATE,&start);
- rv = module_functions->C_SetOperationState(hSession,
- pOperationState,
- ulOperationStateLen,
- hEncryptionKey,
- hAuthenticationKey);
- nssdbg_finish_time(FUNC_C_SETOPERATIONSTATE,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_Login(
- CK_SESSION_HANDLE hSession,
- CK_USER_TYPE userType,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_Login"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (" userType = 0x%x", userType));
- PR_LOG(modlog, 3, (fmt_pPin, pPin));
- PR_LOG(modlog, 3, (fmt_ulPinLen, ulPinLen));
- nssdbg_start_time(FUNC_C_LOGIN,&start);
- rv = module_functions->C_Login(hSession,
- userType,
- pPin,
- ulPinLen);
- nssdbg_finish_time(FUNC_C_LOGIN,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_Logout(
- CK_SESSION_HANDLE hSession
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_Logout"));
- log_handle(3, fmt_hSession, hSession);
- nssdbg_start_time(FUNC_C_LOGOUT,&start);
- rv = module_functions->C_Logout(hSession);
- nssdbg_finish_time(FUNC_C_LOGOUT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_CreateObject(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_CreateObject"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pTemplate, pTemplate));
- PR_LOG(modlog, 3, (fmt_ulCount, ulCount));
- PR_LOG(modlog, 3, (fmt_phObject, phObject));
- print_template(pTemplate, ulCount);
- nssdbg_start_time(FUNC_C_CREATEOBJECT,&start);
- rv = module_functions->C_CreateObject(hSession,
- pTemplate,
- ulCount,
- phObject);
- nssdbg_finish_time(FUNC_C_CREATEOBJECT,start);
- log_handle(4, " *phObject = 0x%x", *phObject);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_CopyObject(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_CopyObject"));
- log_handle(3, fmt_hSession, hSession);
- log_handle(3, fmt_hObject, hObject);
- PR_LOG(modlog, 3, (fmt_pTemplate, pTemplate));
- PR_LOG(modlog, 3, (fmt_ulCount, ulCount));
- PR_LOG(modlog, 3, (" phNewObject = 0x%p", phNewObject));
- print_template(pTemplate, ulCount);
- nssdbg_start_time(FUNC_C_COPYOBJECT,&start);
- rv = module_functions->C_CopyObject(hSession,
- hObject,
- pTemplate,
- ulCount,
- phNewObject);
- nssdbg_finish_time(FUNC_C_COPYOBJECT,start);
- log_handle(4, " *phNewObject = 0x%x", *phNewObject);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DestroyObject(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DestroyObject"));
- log_handle(3, fmt_hSession, hSession);
- log_handle(3, fmt_hObject, hObject);
- nssdbg_start_time(FUNC_C_DESTROYOBJECT,&start);
- rv = module_functions->C_DestroyObject(hSession,
- hObject);
- nssdbg_finish_time(FUNC_C_DESTROYOBJECT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetObjectSize(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ULONG_PTR pulSize
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetObjectSize"));
- log_handle(3, fmt_hSession, hSession);
- log_handle(3, fmt_hObject, hObject);
- PR_LOG(modlog, 3, (" pulSize = 0x%p", pulSize));
- nssdbg_start_time(FUNC_C_GETOBJECTSIZE,&start);
- rv = module_functions->C_GetObjectSize(hSession,
- hObject,
- pulSize);
- nssdbg_finish_time(FUNC_C_GETOBJECTSIZE,start);
- PR_LOG(modlog, 4, (" *pulSize = 0x%x", *pulSize));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetAttributeValue(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetAttributeValue"));
- log_handle(3, fmt_hSession, hSession);
- log_handle(3, fmt_hObject, hObject);
- PR_LOG(modlog, 3, (fmt_pTemplate, pTemplate));
- PR_LOG(modlog, 3, (fmt_ulCount, ulCount));
- nssdbg_start_time(FUNC_C_GETATTRIBUTEVALUE,&start);
- rv = module_functions->C_GetAttributeValue(hSession,
- hObject,
- pTemplate,
- ulCount);
- nssdbg_finish_time(FUNC_C_GETATTRIBUTEVALUE,start);
- print_template(pTemplate, ulCount);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SetAttributeValue(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SetAttributeValue"));
- log_handle(3, fmt_hSession, hSession);
- log_handle(3, fmt_hObject, hObject);
- PR_LOG(modlog, 3, (fmt_pTemplate, pTemplate));
- PR_LOG(modlog, 3, (fmt_ulCount, ulCount));
- print_template(pTemplate, ulCount);
- nssdbg_start_time(FUNC_C_SETATTRIBUTEVALUE,&start);
- rv = module_functions->C_SetAttributeValue(hSession,
- hObject,
- pTemplate,
- ulCount);
- nssdbg_finish_time(FUNC_C_SETATTRIBUTEVALUE,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_FindObjectsInit(
- CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_FindObjectsInit"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pTemplate, pTemplate));
- PR_LOG(modlog, 3, (fmt_ulCount, ulCount));
- print_template(pTemplate, ulCount);
- nssdbg_start_time(FUNC_C_FINDOBJECTSINIT,&start);
- rv = module_functions->C_FindObjectsInit(hSession,
- pTemplate,
- ulCount);
- nssdbg_finish_time(FUNC_C_FINDOBJECTSINIT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_FindObjects(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,
- CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount
-)
-{
- COMMON_DEFINITIONS;
- CK_ULONG i;
-
- PR_LOG(modlog, 1, ("C_FindObjects"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_phObject, phObject));
- PR_LOG(modlog, 3, (" ulMaxObjectCount = %d", ulMaxObjectCount));
- PR_LOG(modlog, 3, (" pulObjectCount = 0x%p", pulObjectCount));
- nssdbg_start_time(FUNC_C_FINDOBJECTS,&start);
- rv = module_functions->C_FindObjects(hSession,
- phObject,
- ulMaxObjectCount,
- pulObjectCount);
- nssdbg_finish_time(FUNC_C_FINDOBJECTS,start);
- PR_LOG(modlog, 4, (" *pulObjectCount = 0x%x", *pulObjectCount));
- for (i=0; i<*pulObjectCount; i++) {
- PR_LOG(modlog, 4, (" phObject[%d] = 0x%x%s", i, phObject[i],
- phObject[i] ? "" : fmt_invalid_handle));
- }
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_FindObjectsFinal(
- CK_SESSION_HANDLE hSession
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_FindObjectsFinal"));
- log_handle(3, fmt_hSession, hSession);
- nssdbg_start_time(FUNC_C_FINDOBJECTSFINAL,&start);
- rv = module_functions->C_FindObjectsFinal(hSession);
- nssdbg_finish_time(FUNC_C_FINDOBJECTSFINAL,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_EncryptInit(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_EncryptInit"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- log_handle(3, fmt_hKey, hKey);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_ENCRYPTINIT,&start);
- rv = module_functions->C_EncryptInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_ENCRYPTINIT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_Encrypt(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_Encrypt"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pData, pData));
- PR_LOG(modlog, 3, (fmt_ulDataLen, ulDataLen));
- PR_LOG(modlog, 3, (fmt_pEncryptedData, pEncryptedData));
- PR_LOG(modlog, 3, (" pulEncryptedDataLen = 0x%p", pulEncryptedDataLen));
- nssdbg_start_time(FUNC_C_ENCRYPT,&start);
- rv = module_functions->C_Encrypt(hSession,
- pData,
- ulDataLen,
- pEncryptedData,
- pulEncryptedDataLen);
- nssdbg_finish_time(FUNC_C_ENCRYPT,start);
- PR_LOG(modlog, 4, (" *pulEncryptedDataLen = 0x%x", *pulEncryptedDataLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_EncryptUpdate(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_EncryptUpdate"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pPart, pPart));
- PR_LOG(modlog, 3, (fmt_ulPartLen, ulPartLen));
- PR_LOG(modlog, 3, (fmt_pEncryptedPart, pEncryptedPart));
- PR_LOG(modlog, 3, (fmt_pulEncryptedPartLen, pulEncryptedPartLen));
- nssdbg_start_time(FUNC_C_ENCRYPTUPDATE,&start);
- rv = module_functions->C_EncryptUpdate(hSession,
- pPart,
- ulPartLen,
- pEncryptedPart,
- pulEncryptedPartLen);
- nssdbg_finish_time(FUNC_C_ENCRYPTUPDATE,start);
- PR_LOG(modlog, 4, (fmt_spulEncryptedPartLen, *pulEncryptedPartLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_EncryptFinal(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart,
- CK_ULONG_PTR pulLastEncryptedPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_EncryptFinal"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (" pLastEncryptedPart = 0x%p", pLastEncryptedPart));
- PR_LOG(modlog, 3, (" pulLastEncryptedPartLen = 0x%p", pulLastEncryptedPartLen));
- nssdbg_start_time(FUNC_C_ENCRYPTFINAL,&start);
- rv = module_functions->C_EncryptFinal(hSession,
- pLastEncryptedPart,
- pulLastEncryptedPartLen);
- nssdbg_finish_time(FUNC_C_ENCRYPTFINAL,start);
- PR_LOG(modlog, 4, (" *pulLastEncryptedPartLen = 0x%x", *pulLastEncryptedPartLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DecryptInit(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DecryptInit"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- log_handle(3, fmt_hKey, hKey);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_DECRYPTINIT,&start);
- rv = module_functions->C_DecryptInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_DECRYPTINIT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_Decrypt(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_Decrypt"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pEncryptedData, pEncryptedData));
- PR_LOG(modlog, 3, (" ulEncryptedDataLen = %d", ulEncryptedDataLen));
- PR_LOG(modlog, 3, (fmt_pData, pData));
- PR_LOG(modlog, 3, (fmt_pulDataLen, pulDataLen));
- nssdbg_start_time(FUNC_C_DECRYPT,&start);
- rv = module_functions->C_Decrypt(hSession,
- pEncryptedData,
- ulEncryptedDataLen,
- pData,
- pulDataLen);
- nssdbg_finish_time(FUNC_C_DECRYPT,start);
- PR_LOG(modlog, 4, (fmt_spulDataLen, *pulDataLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DecryptUpdate(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DecryptUpdate"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pEncryptedPart, pEncryptedPart));
- PR_LOG(modlog, 3, (fmt_ulEncryptedPartLen, ulEncryptedPartLen));
- PR_LOG(modlog, 3, (fmt_pPart, pPart));
- PR_LOG(modlog, 3, (fmt_pulPartLen, pulPartLen));
- nssdbg_start_time(FUNC_C_DECRYPTUPDATE,&start);
- rv = module_functions->C_DecryptUpdate(hSession,
- pEncryptedPart,
- ulEncryptedPartLen,
- pPart,
- pulPartLen);
- nssdbg_finish_time(FUNC_C_DECRYPTUPDATE,start);
- PR_LOG(modlog, 4, (fmt_spulPartLen, *pulPartLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DecryptFinal(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart,
- CK_ULONG_PTR pulLastPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DecryptFinal"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (" pLastPart = 0x%p", pLastPart));
- PR_LOG(modlog, 3, (" pulLastPartLen = 0x%p", pulLastPartLen));
- nssdbg_start_time(FUNC_C_DECRYPTFINAL,&start);
- rv = module_functions->C_DecryptFinal(hSession,
- pLastPart,
- pulLastPartLen);
- nssdbg_finish_time(FUNC_C_DECRYPTFINAL,start);
- PR_LOG(modlog, 4, (" *pulLastPartLen = 0x%x", *pulLastPartLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DigestInit(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DigestInit"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_DIGESTINIT,&start);
- rv = module_functions->C_DigestInit(hSession,
- pMechanism);
- nssdbg_finish_time(FUNC_C_DIGESTINIT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_Digest(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_Digest"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pData, pData));
- PR_LOG(modlog, 3, (fmt_ulDataLen, ulDataLen));
- PR_LOG(modlog, 3, (fmt_pDigest, pDigest));
- PR_LOG(modlog, 3, (fmt_pulDigestLen, pulDigestLen));
- nssdbg_start_time(FUNC_C_DIGEST,&start);
- rv = module_functions->C_Digest(hSession,
- pData,
- ulDataLen,
- pDigest,
- pulDigestLen);
- nssdbg_finish_time(FUNC_C_DIGEST,start);
- PR_LOG(modlog, 4, (fmt_spulDigestLen, *pulDigestLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DigestUpdate(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DigestUpdate"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pPart, pPart));
- PR_LOG(modlog, 3, (fmt_ulPartLen, ulPartLen));
- nssdbg_start_time(FUNC_C_DIGESTUPDATE,&start);
- rv = module_functions->C_DigestUpdate(hSession,
- pPart,
- ulPartLen);
- nssdbg_finish_time(FUNC_C_DIGESTUPDATE,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DigestKey(
- CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DigestKey"));
- log_handle(3, fmt_hSession, hSession);
- nssdbg_start_time(FUNC_C_DIGESTKEY,&start);
- rv = module_functions->C_DigestKey(hSession,
- hKey);
- nssdbg_finish_time(FUNC_C_DIGESTKEY,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DigestFinal(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DigestFinal"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pDigest, pDigest));
- PR_LOG(modlog, 3, (fmt_pulDigestLen, pulDigestLen));
- nssdbg_start_time(FUNC_C_DIGESTFINAL,&start);
- rv = module_functions->C_DigestFinal(hSession,
- pDigest,
- pulDigestLen);
- nssdbg_finish_time(FUNC_C_DIGESTFINAL,start);
- PR_LOG(modlog, 4, (fmt_spulDigestLen, *pulDigestLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SignInit(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SignInit"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- log_handle(3, fmt_hKey, hKey);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_SIGNINIT,&start);
- rv = module_functions->C_SignInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_SIGNINIT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_Sign(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_Sign"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pData, pData));
- PR_LOG(modlog, 3, (fmt_ulDataLen, ulDataLen));
- PR_LOG(modlog, 3, (fmt_pSignature, pSignature));
- PR_LOG(modlog, 3, (fmt_pulSignatureLen, pulSignatureLen));
- nssdbg_start_time(FUNC_C_SIGN,&start);
- rv = module_functions->C_Sign(hSession,
- pData,
- ulDataLen,
- pSignature,
- pulSignatureLen);
- nssdbg_finish_time(FUNC_C_SIGN,start);
- PR_LOG(modlog, 4, (fmt_spulSignatureLen, *pulSignatureLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SignUpdate(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SignUpdate"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pPart, pPart));
- PR_LOG(modlog, 3, (fmt_ulPartLen, ulPartLen));
- nssdbg_start_time(FUNC_C_SIGNUPDATE,&start);
- rv = module_functions->C_SignUpdate(hSession,
- pPart,
- ulPartLen);
- nssdbg_finish_time(FUNC_C_SIGNUPDATE,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SignFinal(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SignFinal"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pSignature, pSignature));
- PR_LOG(modlog, 3, (fmt_pulSignatureLen, pulSignatureLen));
- nssdbg_start_time(FUNC_C_SIGNFINAL,&start);
- rv = module_functions->C_SignFinal(hSession,
- pSignature,
- pulSignatureLen);
- nssdbg_finish_time(FUNC_C_SIGNFINAL,start);
- PR_LOG(modlog, 4, (fmt_spulSignatureLen, *pulSignatureLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SignRecoverInit(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SignRecoverInit"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- log_handle(3, fmt_hKey, hKey);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_SIGNRECOVERINIT,&start);
- rv = module_functions->C_SignRecoverInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_SIGNRECOVERINIT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SignRecover(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SignRecover"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pData, pData));
- PR_LOG(modlog, 3, (fmt_ulDataLen, ulDataLen));
- PR_LOG(modlog, 3, (fmt_pSignature, pSignature));
- PR_LOG(modlog, 3, (fmt_pulSignatureLen, pulSignatureLen));
- nssdbg_start_time(FUNC_C_SIGNRECOVER,&start);
- rv = module_functions->C_SignRecover(hSession,
- pData,
- ulDataLen,
- pSignature,
- pulSignatureLen);
- nssdbg_finish_time(FUNC_C_SIGNRECOVER,start);
- PR_LOG(modlog, 4, (fmt_spulSignatureLen, *pulSignatureLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_VerifyInit(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_VerifyInit"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- log_handle(3, fmt_hKey, hKey);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_VERIFYINIT,&start);
- rv = module_functions->C_VerifyInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_VERIFYINIT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_Verify(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_Verify"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pData, pData));
- PR_LOG(modlog, 3, (fmt_ulDataLen, ulDataLen));
- PR_LOG(modlog, 3, (fmt_pSignature, pSignature));
- PR_LOG(modlog, 3, (fmt_ulSignatureLen, ulSignatureLen));
- nssdbg_start_time(FUNC_C_VERIFY,&start);
- rv = module_functions->C_Verify(hSession,
- pData,
- ulDataLen,
- pSignature,
- ulSignatureLen);
- nssdbg_finish_time(FUNC_C_VERIFY,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_VerifyUpdate(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_VerifyUpdate"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pPart, pPart));
- PR_LOG(modlog, 3, (fmt_ulPartLen, ulPartLen));
- nssdbg_start_time(FUNC_C_VERIFYUPDATE,&start);
- rv = module_functions->C_VerifyUpdate(hSession,
- pPart,
- ulPartLen);
- nssdbg_finish_time(FUNC_C_VERIFYUPDATE,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_VerifyFinal(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_VerifyFinal"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pSignature, pSignature));
- PR_LOG(modlog, 3, (fmt_ulSignatureLen, ulSignatureLen));
- nssdbg_start_time(FUNC_C_VERIFYFINAL,&start);
- rv = module_functions->C_VerifyFinal(hSession,
- pSignature,
- ulSignatureLen);
- nssdbg_finish_time(FUNC_C_VERIFYFINAL,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_VerifyRecoverInit(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_VerifyRecoverInit"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- log_handle(3, fmt_hKey, hKey);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_VERIFYRECOVERINIT,&start);
- rv = module_functions->C_VerifyRecoverInit(hSession,
- pMechanism,
- hKey);
- nssdbg_finish_time(FUNC_C_VERIFYRECOVERINIT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_VerifyRecover(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_VerifyRecover"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pSignature, pSignature));
- PR_LOG(modlog, 3, (fmt_ulSignatureLen, ulSignatureLen));
- PR_LOG(modlog, 3, (fmt_pData, pData));
- PR_LOG(modlog, 3, (fmt_pulDataLen, pulDataLen));
- nssdbg_start_time(FUNC_C_VERIFYRECOVER,&start);
- rv = module_functions->C_VerifyRecover(hSession,
- pSignature,
- ulSignatureLen,
- pData,
- pulDataLen);
- nssdbg_finish_time(FUNC_C_VERIFYRECOVER,start);
- PR_LOG(modlog, 4, (fmt_spulDataLen, *pulDataLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DigestEncryptUpdate(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DigestEncryptUpdate"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pPart, pPart));
- PR_LOG(modlog, 3, (fmt_ulPartLen, ulPartLen));
- PR_LOG(modlog, 3, (fmt_pEncryptedPart, pEncryptedPart));
- PR_LOG(modlog, 3, (fmt_pulEncryptedPartLen, pulEncryptedPartLen));
- nssdbg_start_time(FUNC_C_DIGESTENCRYPTUPDATE,&start);
- rv = module_functions->C_DigestEncryptUpdate(hSession,
- pPart,
- ulPartLen,
- pEncryptedPart,
- pulEncryptedPartLen);
- nssdbg_finish_time(FUNC_C_DIGESTENCRYPTUPDATE,start);
- PR_LOG(modlog, 4, (fmt_spulEncryptedPartLen, *pulEncryptedPartLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DecryptDigestUpdate(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DecryptDigestUpdate"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pEncryptedPart, pEncryptedPart));
- PR_LOG(modlog, 3, (fmt_ulEncryptedPartLen, ulEncryptedPartLen));
- PR_LOG(modlog, 3, (fmt_pPart, pPart));
- PR_LOG(modlog, 3, (fmt_pulPartLen, pulPartLen));
- nssdbg_start_time(FUNC_C_DECRYPTDIGESTUPDATE,&start);
- rv = module_functions->C_DecryptDigestUpdate(hSession,
- pEncryptedPart,
- ulEncryptedPartLen,
- pPart,
- pulPartLen);
- nssdbg_finish_time(FUNC_C_DECRYPTDIGESTUPDATE,start);
- PR_LOG(modlog, 4, (fmt_spulPartLen, *pulPartLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SignEncryptUpdate(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SignEncryptUpdate"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pPart, pPart));
- PR_LOG(modlog, 3, (fmt_ulPartLen, ulPartLen));
- PR_LOG(modlog, 3, (fmt_pEncryptedPart, pEncryptedPart));
- PR_LOG(modlog, 3, (fmt_pulEncryptedPartLen, pulEncryptedPartLen));
- nssdbg_start_time(FUNC_C_SIGNENCRYPTUPDATE,&start);
- rv = module_functions->C_SignEncryptUpdate(hSession,
- pPart,
- ulPartLen,
- pEncryptedPart,
- pulEncryptedPartLen);
- nssdbg_finish_time(FUNC_C_SIGNENCRYPTUPDATE,start);
- PR_LOG(modlog, 4, (fmt_spulEncryptedPartLen, *pulEncryptedPartLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DecryptVerifyUpdate(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DecryptVerifyUpdate"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pEncryptedPart, pEncryptedPart));
- PR_LOG(modlog, 3, (fmt_ulEncryptedPartLen, ulEncryptedPartLen));
- PR_LOG(modlog, 3, (fmt_pPart, pPart));
- PR_LOG(modlog, 3, (fmt_pulPartLen, pulPartLen));
- nssdbg_start_time(FUNC_C_DECRYPTVERIFYUPDATE,&start);
- rv = module_functions->C_DecryptVerifyUpdate(hSession,
- pEncryptedPart,
- ulEncryptedPartLen,
- pPart,
- pulPartLen);
- nssdbg_finish_time(FUNC_C_DECRYPTVERIFYUPDATE,start);
- PR_LOG(modlog, 4, (fmt_spulPartLen, *pulPartLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GenerateKey(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GenerateKey"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- PR_LOG(modlog, 3, (fmt_pTemplate, pTemplate));
- PR_LOG(modlog, 3, (fmt_ulCount, ulCount));
- PR_LOG(modlog, 3, (fmt_phKey, phKey));
- print_template(pTemplate, ulCount);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_GENERATEKEY,&start);
- rv = module_functions->C_GenerateKey(hSession,
- pMechanism,
- pTemplate,
- ulCount,
- phKey);
- nssdbg_finish_time(FUNC_C_GENERATEKEY,start);
- log_handle(4, fmt_sphKey, *phKey);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GenerateKeyPair(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GenerateKeyPair"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- PR_LOG(modlog, 3, (" pPublicKeyTemplate = 0x%p", pPublicKeyTemplate));
- PR_LOG(modlog, 3, (" ulPublicKeyAttributeCount = %d", ulPublicKeyAttributeCount));
- PR_LOG(modlog, 3, (" pPrivateKeyTemplate = 0x%p", pPrivateKeyTemplate));
- PR_LOG(modlog, 3, (" ulPrivateKeyAttributeCount = %d", ulPrivateKeyAttributeCount));
- PR_LOG(modlog, 3, (" phPublicKey = 0x%p", phPublicKey));
- print_template(pPublicKeyTemplate, ulPublicKeyAttributeCount);
- PR_LOG(modlog, 3, (" phPrivateKey = 0x%p", phPrivateKey));
- print_template(pPrivateKeyTemplate, ulPrivateKeyAttributeCount);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_GENERATEKEYPAIR,&start);
- rv = module_functions->C_GenerateKeyPair(hSession,
- pMechanism,
- pPublicKeyTemplate,
- ulPublicKeyAttributeCount,
- pPrivateKeyTemplate,
- ulPrivateKeyAttributeCount,
- phPublicKey,
- phPrivateKey);
- nssdbg_finish_time(FUNC_C_GENERATEKEYPAIR,start);
- log_handle(4, " *phPublicKey = 0x%x", *phPublicKey);
- log_handle(4, " *phPrivateKey = 0x%x", *phPrivateKey);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_WrapKey(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_WrapKey"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- log_handle(3, " hWrappingKey = 0x%x", hWrappingKey);
- log_handle(3, fmt_hKey, hKey);
- PR_LOG(modlog, 3, (fmt_pWrappedKey, pWrappedKey));
- PR_LOG(modlog, 3, (" pulWrappedKeyLen = 0x%p", pulWrappedKeyLen));
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_WRAPKEY,&start);
- rv = module_functions->C_WrapKey(hSession,
- pMechanism,
- hWrappingKey,
- hKey,
- pWrappedKey,
- pulWrappedKeyLen);
- nssdbg_finish_time(FUNC_C_WRAPKEY,start);
- PR_LOG(modlog, 4, (" *pulWrappedKeyLen = 0x%x", *pulWrappedKeyLen));
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_UnwrapKey(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_UnwrapKey"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- log_handle(3, " hUnwrappingKey = 0x%x", hUnwrappingKey);
- PR_LOG(modlog, 3, (fmt_pWrappedKey, pWrappedKey));
- PR_LOG(modlog, 3, (" ulWrappedKeyLen = %d", ulWrappedKeyLen));
- PR_LOG(modlog, 3, (fmt_pTemplate, pTemplate));
- PR_LOG(modlog, 3, (fmt_ulAttributeCount, ulAttributeCount));
- PR_LOG(modlog, 3, (fmt_phKey, phKey));
- print_template(pTemplate, ulAttributeCount);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_UNWRAPKEY,&start);
- rv = module_functions->C_UnwrapKey(hSession,
- pMechanism,
- hUnwrappingKey,
- pWrappedKey,
- ulWrappedKeyLen,
- pTemplate,
- ulAttributeCount,
- phKey);
- nssdbg_finish_time(FUNC_C_UNWRAPKEY,start);
- log_handle(4, fmt_sphKey, *phKey);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_DeriveKey(
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_DeriveKey"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (fmt_pMechanism, pMechanism));
- log_handle(3, " hBaseKey = 0x%x", hBaseKey);
- PR_LOG(modlog, 3, (fmt_pTemplate, pTemplate));
- PR_LOG(modlog, 3, (fmt_ulAttributeCount, ulAttributeCount));
- PR_LOG(modlog, 3, (fmt_phKey, phKey));
- print_template(pTemplate, ulAttributeCount);
- print_mechanism(pMechanism);
- nssdbg_start_time(FUNC_C_DERIVEKEY,&start);
- rv = module_functions->C_DeriveKey(hSession,
- pMechanism,
- hBaseKey,
- pTemplate,
- ulAttributeCount,
- phKey);
- nssdbg_finish_time(FUNC_C_DERIVEKEY,start);
- log_handle(4, fmt_sphKey, *phKey);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_SeedRandom(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_SeedRandom"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (" pSeed = 0x%p", pSeed));
- PR_LOG(modlog, 3, (" ulSeedLen = %d", ulSeedLen));
- nssdbg_start_time(FUNC_C_SEEDRANDOM,&start);
- rv = module_functions->C_SeedRandom(hSession,
- pSeed,
- ulSeedLen);
- nssdbg_finish_time(FUNC_C_SEEDRANDOM,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GenerateRandom(
- CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR RandomData,
- CK_ULONG ulRandomLen
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GenerateRandom"));
- log_handle(3, fmt_hSession, hSession);
- PR_LOG(modlog, 3, (" RandomData = 0x%p", RandomData));
- PR_LOG(modlog, 3, (" ulRandomLen = %d", ulRandomLen));
- nssdbg_start_time(FUNC_C_GENERATERANDOM,&start);
- rv = module_functions->C_GenerateRandom(hSession,
- RandomData,
- ulRandomLen);
- nssdbg_finish_time(FUNC_C_GENERATERANDOM,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_GetFunctionStatus(
- CK_SESSION_HANDLE hSession
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_GetFunctionStatus"));
- log_handle(3, fmt_hSession, hSession);
- nssdbg_start_time(FUNC_C_GETFUNCTIONSTATUS,&start);
- rv = module_functions->C_GetFunctionStatus(hSession);
- nssdbg_finish_time(FUNC_C_GETFUNCTIONSTATUS,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_CancelFunction(
- CK_SESSION_HANDLE hSession
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_CancelFunction"));
- log_handle(3, fmt_hSession, hSession);
- nssdbg_start_time(FUNC_C_CANCELFUNCTION,&start);
- rv = module_functions->C_CancelFunction(hSession);
- nssdbg_finish_time(FUNC_C_CANCELFUNCTION,start);
- log_rv(rv);
- return rv;
-}
-
-CK_RV NSSDBGC_WaitForSlotEvent(
- CK_FLAGS flags,
- CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pRserved
-)
-{
- COMMON_DEFINITIONS;
-
- PR_LOG(modlog, 1, ("C_WaitForSlotEvent"));
- PR_LOG(modlog, 3, (fmt_flags, flags));
- PR_LOG(modlog, 3, (" pSlot = 0x%p", pSlot));
- PR_LOG(modlog, 3, (" pRserved = 0x%p", pRserved));
- nssdbg_start_time(FUNC_C_WAITFORSLOTEVENT,&start);
- rv = module_functions->C_WaitForSlotEvent(flags,
- pSlot,
- pRserved);
- nssdbg_finish_time(FUNC_C_WAITFORSLOTEVENT,start);
- log_rv(rv);
- return rv;
-}
-
-CK_FUNCTION_LIST_PTR nss_InsertDeviceLog(
- CK_FUNCTION_LIST_PTR devEPV
-)
-{
- module_functions = devEPV;
- modlog = PR_NewLogModule("nss_mod_log");
- debug_functions.C_Initialize = NSSDBGC_Initialize;
- debug_functions.C_Finalize = NSSDBGC_Finalize;
- debug_functions.C_GetInfo = NSSDBGC_GetInfo;
- debug_functions.C_GetFunctionList = NSSDBGC_GetFunctionList;
- debug_functions.C_GetSlotList = NSSDBGC_GetSlotList;
- debug_functions.C_GetSlotInfo = NSSDBGC_GetSlotInfo;
- debug_functions.C_GetTokenInfo = NSSDBGC_GetTokenInfo;
- debug_functions.C_GetMechanismList = NSSDBGC_GetMechanismList;
- debug_functions.C_GetMechanismInfo = NSSDBGC_GetMechanismInfo;
- debug_functions.C_InitToken = NSSDBGC_InitToken;
- debug_functions.C_InitPIN = NSSDBGC_InitPIN;
- debug_functions.C_SetPIN = NSSDBGC_SetPIN;
- debug_functions.C_OpenSession = NSSDBGC_OpenSession;
- debug_functions.C_CloseSession = NSSDBGC_CloseSession;
- debug_functions.C_CloseAllSessions = NSSDBGC_CloseAllSessions;
- debug_functions.C_GetSessionInfo = NSSDBGC_GetSessionInfo;
- debug_functions.C_GetOperationState = NSSDBGC_GetOperationState;
- debug_functions.C_SetOperationState = NSSDBGC_SetOperationState;
- debug_functions.C_Login = NSSDBGC_Login;
- debug_functions.C_Logout = NSSDBGC_Logout;
- debug_functions.C_CreateObject = NSSDBGC_CreateObject;
- debug_functions.C_CopyObject = NSSDBGC_CopyObject;
- debug_functions.C_DestroyObject = NSSDBGC_DestroyObject;
- debug_functions.C_GetObjectSize = NSSDBGC_GetObjectSize;
- debug_functions.C_GetAttributeValue = NSSDBGC_GetAttributeValue;
- debug_functions.C_SetAttributeValue = NSSDBGC_SetAttributeValue;
- debug_functions.C_FindObjectsInit = NSSDBGC_FindObjectsInit;
- debug_functions.C_FindObjects = NSSDBGC_FindObjects;
- debug_functions.C_FindObjectsFinal = NSSDBGC_FindObjectsFinal;
- debug_functions.C_EncryptInit = NSSDBGC_EncryptInit;
- debug_functions.C_Encrypt = NSSDBGC_Encrypt;
- debug_functions.C_EncryptUpdate = NSSDBGC_EncryptUpdate;
- debug_functions.C_EncryptFinal = NSSDBGC_EncryptFinal;
- debug_functions.C_DecryptInit = NSSDBGC_DecryptInit;
- debug_functions.C_Decrypt = NSSDBGC_Decrypt;
- debug_functions.C_DecryptUpdate = NSSDBGC_DecryptUpdate;
- debug_functions.C_DecryptFinal = NSSDBGC_DecryptFinal;
- debug_functions.C_DigestInit = NSSDBGC_DigestInit;
- debug_functions.C_Digest = NSSDBGC_Digest;
- debug_functions.C_DigestUpdate = NSSDBGC_DigestUpdate;
- debug_functions.C_DigestKey = NSSDBGC_DigestKey;
- debug_functions.C_DigestFinal = NSSDBGC_DigestFinal;
- debug_functions.C_SignInit = NSSDBGC_SignInit;
- debug_functions.C_Sign = NSSDBGC_Sign;
- debug_functions.C_SignUpdate = NSSDBGC_SignUpdate;
- debug_functions.C_SignFinal = NSSDBGC_SignFinal;
- debug_functions.C_SignRecoverInit = NSSDBGC_SignRecoverInit;
- debug_functions.C_SignRecover = NSSDBGC_SignRecover;
- debug_functions.C_VerifyInit = NSSDBGC_VerifyInit;
- debug_functions.C_Verify = NSSDBGC_Verify;
- debug_functions.C_VerifyUpdate = NSSDBGC_VerifyUpdate;
- debug_functions.C_VerifyFinal = NSSDBGC_VerifyFinal;
- debug_functions.C_VerifyRecoverInit = NSSDBGC_VerifyRecoverInit;
- debug_functions.C_VerifyRecover = NSSDBGC_VerifyRecover;
- debug_functions.C_DigestEncryptUpdate = NSSDBGC_DigestEncryptUpdate;
- debug_functions.C_DecryptDigestUpdate = NSSDBGC_DecryptDigestUpdate;
- debug_functions.C_SignEncryptUpdate = NSSDBGC_SignEncryptUpdate;
- debug_functions.C_DecryptVerifyUpdate = NSSDBGC_DecryptVerifyUpdate;
- debug_functions.C_GenerateKey = NSSDBGC_GenerateKey;
- debug_functions.C_GenerateKeyPair = NSSDBGC_GenerateKeyPair;
- debug_functions.C_WrapKey = NSSDBGC_WrapKey;
- debug_functions.C_UnwrapKey = NSSDBGC_UnwrapKey;
- debug_functions.C_DeriveKey = NSSDBGC_DeriveKey;
- debug_functions.C_SeedRandom = NSSDBGC_SeedRandom;
- debug_functions.C_GenerateRandom = NSSDBGC_GenerateRandom;
- debug_functions.C_GetFunctionStatus = NSSDBGC_GetFunctionStatus;
- debug_functions.C_CancelFunction = NSSDBGC_CancelFunction;
- debug_functions.C_WaitForSlotEvent = NSSDBGC_WaitForSlotEvent;
- return &debug_functions;
-}
-
-/*
- * scale the time factor up accordingly.
- * This routine tries to keep at least 2 significant figures on output.
- * If the time is 0, then indicate that with a 'z' for units.
- * If the time is greater than 10 minutes, output the time in minutes.
- * If the time is less than 10 minutes but greater than 10 seconds output
- * the time in second.
- * If the time is less than 10 seconds but greater than 10 milliseconds
- * output * the time in millisecond.
- * If the time is less than 10 milliseconds but greater than 0 ticks output
- * the time in microsecond.
- *
- */
-static PRUint32 getPrintTime(PRIntervalTime time ,char **type)
-{
- PRUint32 prTime;
-
- /* detect a programming error by outputting 'bu' to the output stream
- * rather than crashing */
- *type = "bug";
- if (time == 0) {
- *type = "z";
- return 0;
- }
-
- prTime = PR_IntervalToSeconds(time);
-
- if (prTime >= 600) {
- *type="m";
- return prTime/60;
- }
- if (prTime >= 10) {
- *type="s";
- return prTime;
- }
- prTime = PR_IntervalToMilliseconds(time);
- if (prTime >= 10) {
- *type="ms";
- return prTime;
- }
- *type = "us";
- return PR_IntervalToMicroseconds(time);
-}
-
-static void print_final_statistics(void)
-{
- int total_calls = 0;
- PRIntervalTime total_time = 0;
- PRUint32 pr_total_time;
- char *type;
- char *fname;
- FILE *outfile = NULL;
- int i;
-
- fname = PR_GetEnv("NSS_OUTPUT_FILE");
- if (fname) {
- /* need to add an optional process id to the filename */
- outfile = fopen(fname,"w+");
- }
- if (!outfile) {
- outfile = stdout;
- }
-
-
- fprintf(outfile,"%-25s %10s %12s %12s %10s\n", "Function", "# Calls",
- "Time", "Avg.", "% Time");
- fprintf(outfile,"\n");
- for (i=0; i < nssdbg_prof_size; i++) {
- total_calls += nssdbg_prof_data[i].calls;
- total_time += nssdbg_prof_data[i].time;
- }
- for (i=0; i < nssdbg_prof_size; i++) {
- PRIntervalTime time = nssdbg_prof_data[i].time;
- PRUint32 usTime = PR_IntervalToMicroseconds(time);
- PRUint32 prTime = 0;
- PRUint32 calls = nssdbg_prof_data[i].calls;
- /* don't print out functions that weren't even called */
- if (calls == 0) {
- continue;
- }
-
- prTime = getPrintTime(time,&type);
-
- fprintf(outfile,"%-25s %10d %10d%2s ", nssdbg_prof_data[i].function,
- calls, prTime, type);
- /* for now always output the average in microseconds */
- fprintf(outfile,"%10.2f%2s", (float)usTime / (float)calls, "us" );
- fprintf(outfile,"%10.2f%%", ((float)time / (float)total_time) * 100);
- fprintf(outfile,"\n");
- }
- fprintf(outfile,"\n");
-
- pr_total_time = getPrintTime(total_time,&type);
-
- fprintf(outfile,"%25s %10d %10d%2s\n", "Totals", total_calls,
- pr_total_time, type);
- fprintf(outfile,"\n\nMaximum number of concurrent open sessions: %d\n\n",
- maxOpenSessions);
- fflush (outfile);
- if (outfile != stdout) {
- fclose(outfile);
- }
-}
-
diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c
deleted file mode 100644
index 19e9a0c90..000000000
--- a/security/nss/lib/pk11wrap/dev3hack.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef PKIT_H
-#include "pkit.h"
-#endif /* PKIT_H */
-
-#ifndef DEVM_H
-#include "devm.h"
-#endif /* DEVM_H */
-
-#include "pki3hack.h"
-#include "dev3hack.h"
-#include "pkim.h"
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#include "pk11func.h"
-#include "secmodti.h"
-#include "secerr.h"
-
-NSS_IMPLEMENT nssSession *
-nssSession_ImportNSS3Session(NSSArena *arenaOpt,
- CK_SESSION_HANDLE session,
- PZLock *lock, PRBool rw)
-{
- nssSession *rvSession = NULL;
- if (session != CK_INVALID_SESSION) {
- rvSession = nss_ZNEW(arenaOpt, nssSession);
- if (rvSession) {
- rvSession->handle = session;
- rvSession->lock = lock;
- rvSession->ownLock = PR_FALSE;
- rvSession->isRW = rw;
- }
- }
- return rvSession;
-}
-
-NSS_IMPLEMENT nssSession *
-nssSlot_CreateSession
-(
- NSSSlot *slot,
- NSSArena *arenaOpt,
- PRBool readWrite
-)
-{
- nssSession *rvSession;
-
- if (!readWrite) {
- /* nss3hack version only returns rw swssions */
- return NULL;
- }
- rvSession = nss_ZNEW(arenaOpt, nssSession);
- if (!rvSession) {
- return (nssSession *)NULL;
- }
-
- rvSession->handle = PK11_GetRWSession(slot->pk11slot);
- if (rvSession->handle == CK_INVALID_HANDLE) {
- nss_ZFreeIf(rvSession);
- return NULL;
- }
- rvSession->isRW = PR_TRUE;
- rvSession->slot = slot;
- /*
- * The session doesn't need its own lock. Here's why.
- * 1. If we are reusing the default RW session of the slot,
- * the slot lock is already locked to protect the session.
- * 2. If the module is not thread safe, the slot (or rather
- * module) lock is already locked.
- * 3. If the module is thread safe and we are using a new
- * session, no higher-level lock has been locked and we
- * would need a lock for the new session. However, the
- * current usage of the session is that it is always
- * used and destroyed within the same function and never
- * shared with another thread.
- * So the session is either already protected by another
- * lock or only used by one thread.
- */
- rvSession->lock = NULL;
- rvSession->ownLock = PR_FALSE;
- return rvSession;
-}
-
-NSS_IMPLEMENT PRStatus
-nssSession_Destroy
-(
- nssSession *s
-)
-{
- CK_RV ckrv = CKR_OK;
- if (s) {
- if (s->isRW) {
- PK11_RestoreROSession(s->slot->pk11slot, s->handle);
- }
- nss_ZFreeIf(s);
- }
- return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
-}
-
-static NSSSlot *
-nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
-{
- NSSSlot *rvSlot;
- NSSArena *arena;
- arena = nssArena_Create();
- if (!arena) {
- return NULL;
- }
- rvSlot = nss_ZNEW(arena, NSSSlot);
- if (!rvSlot) {
- nssArena_Destroy(arena);
- return NULL;
- }
- rvSlot->base.refCount = 1;
- rvSlot->base.lock = PZ_NewLock(nssILockOther);
- rvSlot->base.arena = arena;
- rvSlot->pk11slot = nss3slot;
- rvSlot->epv = nss3slot->functionList;
- rvSlot->slotID = nss3slot->slotID;
- /* Grab the slot name from the PKCS#11 fixed-length buffer */
- rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena);
- rvSlot->lock = (nss3slot->isThreadSafe) ? NULL : nss3slot->sessionLock;
- return rvSlot;
-}
-
-NSSToken *
-nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
-{
- NSSToken *rvToken;
- NSSArena *arena;
-
- /* Don't create a token object for a disabled slot */
- if (nss3slot->disabled) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return NULL;
- }
- arena = nssArena_Create();
- if (!arena) {
- return NULL;
- }
- rvToken = nss_ZNEW(arena, NSSToken);
- if (!rvToken) {
- nssArena_Destroy(arena);
- return NULL;
- }
- rvToken->base.refCount = 1;
- rvToken->base.lock = PZ_NewLock(nssILockOther);
- if (!rvToken->base.lock) {
- nssArena_Destroy(arena);
- return NULL;
- }
- rvToken->base.arena = arena;
- rvToken->pk11slot = nss3slot;
- rvToken->epv = nss3slot->functionList;
- rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
- nss3slot->session,
- nss3slot->sessionLock,
- nss3slot->defRWSession);
-#if 0 /* we should do this instead of blindly continuing. */
- if (!rvToken->defaultSession) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- goto loser;
- }
-#endif
- if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) {
- rvToken->cache = nssTokenObjectCache_Create(rvToken,
- PR_TRUE, PR_TRUE, PR_TRUE);
- if (!rvToken->cache)
- goto loser;
- }
- rvToken->trustDomain = td;
- /* Grab the token name from the PKCS#11 fixed-length buffer */
- rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
- rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
- if (!rvToken->slot) {
- goto loser;
- }
- rvToken->slot->token = rvToken;
- if (rvToken->defaultSession)
- rvToken->defaultSession->slot = rvToken->slot;
- return rvToken;
-loser:
- PZ_DestroyLock(rvToken->base.lock);
- nssArena_Destroy(arena);
- return NULL;
-}
-
-NSS_IMPLEMENT void
-nssToken_UpdateName(NSSToken *token)
-{
- if (!token) {
- return;
- }
- token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name,token->base.arena);
-}
-
-NSS_IMPLEMENT PRBool
-nssSlot_IsPermanent
-(
- NSSSlot *slot
-)
-{
- return slot->pk11slot->isPerm;
-}
-
-NSS_IMPLEMENT PRBool
-nssSlot_IsFriendly
-(
- NSSSlot *slot
-)
-{
- return PK11_IsFriendly(slot->pk11slot);
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_Refresh(NSSToken *token)
-{
- PK11SlotInfo *nss3slot;
-
- if (!token) {
- return PR_SUCCESS;
- }
- nss3slot = token->pk11slot;
- token->defaultSession =
- nssSession_ImportNSS3Session(token->slot->base.arena,
- nss3slot->session,
- nss3slot->sessionLock,
- nss3slot->defRWSession);
- return token->defaultSession ? PR_SUCCESS : PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-nssSlot_Refresh
-(
- NSSSlot *slot
-)
-{
- PK11SlotInfo *nss3slot = slot->pk11slot;
- PRBool doit = PR_FALSE;
- if (slot->token && slot->token->base.name[0] == 0) {
- doit = PR_TRUE;
- }
- if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
- return PR_FAILURE;
- }
- if (doit) {
- nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain,
- slot->token);
- }
- return nssToken_Refresh(slot->token);
-}
-
-NSS_IMPLEMENT PRStatus
-nssToken_GetTrustOrder
-(
- NSSToken *tok
-)
-{
- PK11SlotInfo *slot;
- SECMODModule *module;
- slot = tok->pk11slot;
- module = PK11_GetModule(slot);
- return module->trustOrder;
-}
-
-NSS_IMPLEMENT PRBool
-nssSlot_IsLoggedIn
-(
- NSSSlot *slot
-)
-{
- if (!slot->pk11slot->needLogin) {
- return PR_TRUE;
- }
- return PK11_IsLoggedIn(slot->pk11slot, NULL);
-}
-
-
-NSSTrustDomain *
-nssToken_GetTrustDomain(NSSToken *token)
-{
- return token->trustDomain;
-}
-
-NSS_EXTERN PRStatus
-nssTrustDomain_RemoveTokenCertsFromCache
-(
- NSSTrustDomain *td,
- NSSToken *token
-);
-
-NSS_IMPLEMENT PRStatus
-nssToken_NotifyCertsNotVisible
-(
- NSSToken *tok
-)
-{
- return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok);
-}
-
diff --git a/security/nss/lib/pk11wrap/dev3hack.h b/security/nss/lib/pk11wrap/dev3hack.h
deleted file mode 100644
index 3ac34215f..000000000
--- a/security/nss/lib/pk11wrap/dev3hack.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef DEVNSS3HACK_H
-#define DEVNSS3HACK_H
-
-#ifdef DEBUG
-static const char DEVNSS3HACK_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "cert.h"
-
-PR_BEGIN_EXTERN_C
-
-NSS_EXTERN NSSToken *
-nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot);
-
-NSS_EXTERN void
-nssToken_UpdateName(NSSToken *);
-
-NSS_EXTERN PRStatus
-nssToken_Refresh(NSSToken *);
-
-NSSTrustDomain *
-nssToken_GetTrustDomain(NSSToken *token);
-
-void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst);
-
-NSSToken * PK11Slot_GetNSSToken(PK11SlotInfo *sl);
-
-PR_END_EXTERN_C
-
-#endif /* DEVNSS3HACK_H */
diff --git a/security/nss/lib/pk11wrap/manifest.mn b/security/nss/lib/pk11wrap/manifest.mn
deleted file mode 100644
index 8c43c7e88..000000000
--- a/security/nss/lib/pk11wrap/manifest.mn
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-
-EXPORTS = \
- secmod.h \
- secmodt.h \
- secpkcs5.h \
- pk11func.h \
- pk11pub.h \
- pk11priv.h \
- pk11sdr.h \
- pk11pqg.h \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- secmodi.h \
- dev3hack.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- dev3hack.c \
- pk11akey.c \
- pk11auth.c \
- pk11cert.c \
- pk11cxt.c \
- pk11err.c \
- pk11kea.c \
- pk11list.c \
- pk11load.c \
- pk11mech.c \
- pk11merge.c \
- pk11nobj.c \
- pk11obj.c \
- pk11pars.c \
- pk11pbe.c \
- pk11pk12.c \
- pk11pqg.c \
- pk11sdr.c \
- pk11skey.c \
- pk11slot.c \
- pk11util.c \
- $(NULL)
-
-LIBRARY_NAME = pk11wrap
-
-LIBRARY_VERSION = 3
-SOFTOKEN_LIBRARY_VERSION = 3
-DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" \
- -DSHLIB_VERSION=\"$(LIBRARY_VERSION)\" \
- -DSOFTOKEN_SHLIB_VERSION=\"$(SOFTOKEN_LIBRARY_VERSION)\"
-
-# only add module debugging in opt builds if DEBUG_PKCS11 is set
-ifdef DEBUG_PKCS11
- DEFINES += -DDEBUG_MODULE -DFORCE_PR_LOG
-endif
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/pk11wrap/pk11akey.c b/security/nss/lib/pk11wrap/pk11akey.c
deleted file mode 100644
index b392ffffe..000000000
--- a/security/nss/lib/pk11wrap/pk11akey.c
+++ /dev/null
@@ -1,2387 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file contains functions to manage asymetric keys, (public and
- * private keys).
- */
-#include "seccomon.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11.h"
-#include "pkcs11t.h"
-#include "pk11func.h"
-#include "cert.h"
-#include "key.h"
-#include "secitem.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "secerr.h"
-#include "sslerr.h"
-#include "sechash.h"
-
-#include "secpkcs5.h"
-#include "blapit.h"
-
-static SECItem *
-pk11_MakeIDFromPublicKey(SECKEYPublicKey *pubKey)
-{
- /* set the ID to the public key so we can find it again */
- SECItem *pubKeyIndex = NULL;
- switch (pubKey->keyType) {
- case rsaKey:
- pubKeyIndex = &pubKey->u.rsa.modulus;
- break;
- case dsaKey:
- pubKeyIndex = &pubKey->u.dsa.publicValue;
- break;
- case dhKey:
- pubKeyIndex = &pubKey->u.dh.publicValue;
- break;
- case ecKey:
- pubKeyIndex = &pubKey->u.ec.publicValue;
- break;
- default:
- return NULL;
- }
- PORT_Assert(pubKeyIndex != NULL);
-
- return PK11_MakeIDFromPubKey(pubKeyIndex);
-}
-
-/*
- * import a public key into the desired slot
- *
- * This function takes a public key structure and creates a public key in a
- * given slot. If isToken is set, then a persistant public key is created.
- *
- * Note: it is possible for this function to return a handle for a key which
- * is persistant, even if isToken is not set.
- */
-CK_OBJECT_HANDLE
-PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
- PRBool isToken)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_OBJECT_HANDLE objectID;
- CK_ATTRIBUTE theTemplate[11];
- CK_ATTRIBUTE *signedattr = NULL;
- CK_ATTRIBUTE *attrs = theTemplate;
- SECItem *ckaId = NULL;
- SECItem *pubValue = NULL;
- int signedcount = 0;
- int templateCount = 0;
- SECStatus rv;
-
- /* if we already have an object in the desired slot, use it */
- if (!isToken && pubKey->pkcs11Slot == slot) {
- return pubKey->pkcs11ID;
- }
-
- /* free the existing key */
- if (pubKey->pkcs11Slot != NULL) {
- PK11SlotInfo *oSlot = pubKey->pkcs11Slot;
- if (!PK11_IsPermObject(pubKey->pkcs11Slot,pubKey->pkcs11ID)) {
- PK11_EnterSlotMonitor(oSlot);
- (void) PK11_GETTAB(oSlot)->C_DestroyObject(oSlot->session,
- pubKey->pkcs11ID);
- PK11_ExitSlotMonitor(oSlot);
- }
- PK11_FreeSlot(oSlot);
- pubKey->pkcs11Slot = NULL;
- }
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, isToken ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL) ); attrs++;
- if (isToken) {
- ckaId = pk11_MakeIDFromPublicKey(pubKey);
- if (ckaId == NULL) {
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return CK_INVALID_HANDLE;
- }
- PK11_SETATTRS(attrs, CKA_ID, ckaId->data, ckaId->len); attrs++;
- }
-
- /* now import the key */
- {
- switch (pubKey->keyType) {
- case rsaKey:
- keyType = CKK_RSA;
- PK11_SETATTRS(attrs, CKA_WRAP, &cktrue, sizeof(CK_BBOOL) ); attrs++;
- PK11_SETATTRS(attrs, CKA_ENCRYPT, &cktrue,
- sizeof(CK_BBOOL) ); attrs++;
- PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); attrs++;
- signedattr = attrs;
- PK11_SETATTRS(attrs, CKA_MODULUS, pubKey->u.rsa.modulus.data,
- pubKey->u.rsa.modulus.len); attrs++;
- PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
- pubKey->u.rsa.publicExponent.data,
- pubKey->u.rsa.publicExponent.len); attrs++;
- break;
- case dsaKey:
- keyType = CKK_DSA;
- PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
- signedattr = attrs;
- PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dsa.params.prime.data,
- pubKey->u.dsa.params.prime.len); attrs++;
- PK11_SETATTRS(attrs,CKA_SUBPRIME,pubKey->u.dsa.params.subPrime.data,
- pubKey->u.dsa.params.subPrime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dsa.params.base.data,
- pubKey->u.dsa.params.base.len); attrs++;
- PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dsa.publicValue.data,
- pubKey->u.dsa.publicValue.len); attrs++;
- break;
- case fortezzaKey:
- keyType = CKK_DSA;
- PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
- signedattr = attrs;
- PK11_SETATTRS(attrs, CKA_PRIME,pubKey->u.fortezza.params.prime.data,
- pubKey->u.fortezza.params.prime.len); attrs++;
- PK11_SETATTRS(attrs,CKA_SUBPRIME,
- pubKey->u.fortezza.params.subPrime.data,
- pubKey->u.fortezza.params.subPrime.len);attrs++;
- PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.fortezza.params.base.data,
- pubKey->u.fortezza.params.base.len); attrs++;
- PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.fortezza.DSSKey.data,
- pubKey->u.fortezza.DSSKey.len); attrs++;
- break;
- case dhKey:
- keyType = CKK_DH;
- PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++;
- signedattr = attrs;
- PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dh.prime.data,
- pubKey->u.dh.prime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dh.base.data,
- pubKey->u.dh.base.len); attrs++;
- PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dh.publicValue.data,
- pubKey->u.dh.publicValue.len); attrs++;
- break;
- case ecKey:
- keyType = CKK_EC;
- PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
- PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++;
- signedattr = attrs;
- PK11_SETATTRS(attrs, CKA_EC_PARAMS,
- pubKey->u.ec.DEREncodedParams.data,
- pubKey->u.ec.DEREncodedParams.len); attrs++;
- if (PR_GetEnv("NSS_USE_DECODED_CKA_EC_POINT")) {
- PK11_SETATTRS(attrs, CKA_EC_POINT,
- pubKey->u.ec.publicValue.data,
- pubKey->u.ec.publicValue.len); attrs++;
- } else {
- pubValue = SEC_ASN1EncodeItem(NULL, NULL,
- &pubKey->u.ec.publicValue,
- SEC_ASN1_GET(SEC_OctetStringTemplate));
- if (pubValue == NULL) {
- if (ckaId) {
- SECITEM_FreeItem(ckaId,PR_TRUE);
- }
- return CK_INVALID_HANDLE;
- }
- PK11_SETATTRS(attrs, CKA_EC_POINT,
- pubValue->data, pubValue->len); attrs++;
- }
- break;
- default:
- if (ckaId) {
- SECITEM_FreeItem(ckaId,PR_TRUE);
- }
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return CK_INVALID_HANDLE;
- }
-
- templateCount = attrs - theTemplate;
- signedcount = attrs - signedattr;
- PORT_Assert(templateCount <= (sizeof(theTemplate)/sizeof(CK_ATTRIBUTE)));
- for (attrs=signedattr; signedcount; attrs++, signedcount--) {
- pk11_SignedToUnsigned(attrs);
- }
- rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate,
- templateCount, isToken, &objectID);
- if (ckaId) {
- SECITEM_FreeItem(ckaId,PR_TRUE);
- }
- if (pubValue) {
- SECITEM_FreeItem(pubValue,PR_TRUE);
- }
- if ( rv != SECSuccess) {
- return CK_INVALID_HANDLE;
- }
- }
-
- pubKey->pkcs11ID = objectID;
- pubKey->pkcs11Slot = PK11_ReferenceSlot(slot);
-
- return objectID;
-}
-
-/*
- * take an attribute and copy it into a secitem
- */
-static CK_RV
-pk11_Attr2SecItem(PRArenaPool *arena, const CK_ATTRIBUTE *attr, SECItem *item)
-{
- item->data = NULL;
-
- (void)SECITEM_AllocItem(arena, item, attr->ulValueLen);
- if (item->data == NULL) {
- return CKR_HOST_MEMORY;
- }
- PORT_Memcpy(item->data, attr->pValue, item->len);
- return CKR_OK;
-}
-
-
-/*
- * get a curve length from a set of ecParams.
- *
- * We need this so we can reliably determine if the ecPoint passed to us
- * was encoded or not. With out this, for many curves, we would incorrectly
- * identify an unencoded curve as an encoded curve 1 in 65536 times, and for
- * a few we would make that same mistake 1 in 32768 times. These are bad
- * numbers since they are rare enough to pass tests, but common enough to
- * be tripped over in the field.
- *
- * This function will only work for curves we recognized as of March 2009.
- * The assumption is curves in use after March of 2009 would be supplied by
- * PKCS #11 modules that already pass the correct encoding to us.
- *
- * Point length = (Roundup(curveLenInBits/8)*2+1)
- */
-static int
-pk11_get_EC_PointLenInBytes(PRArenaPool *arena, const SECItem *ecParams)
-{
- SECItem oid;
- SECOidTag tag;
- SECStatus rv;
-
- /* decode the OID tag */
- rv = SEC_QuickDERDecodeItem(arena, &oid,
- SEC_ASN1_GET(SEC_ObjectIDTemplate), ecParams);
- if (rv != SECSuccess) {
- /* could be explict curves, allow them to work if the
- * PKCS #11 module support them. If we try to parse the
- * explicit curve value in the future, we may return -1 here
- * to indicate an invalid parameter if the explicit curve
- * decode fails. */
- return 0;
- }
-
- tag = SECOID_FindOIDTag(&oid);
- switch (tag) {
- case SEC_OID_SECG_EC_SECP112R1:
- case SEC_OID_SECG_EC_SECP112R2:
- return 29; /* curve len in bytes = 14 bytes */
- case SEC_OID_SECG_EC_SECT113R1:
- case SEC_OID_SECG_EC_SECT113R2:
- return 31; /* curve len in bytes = 15 bytes */
- case SEC_OID_SECG_EC_SECP128R1:
- case SEC_OID_SECG_EC_SECP128R2:
- return 33; /* curve len in bytes = 16 bytes */
- case SEC_OID_SECG_EC_SECT131R1:
- case SEC_OID_SECG_EC_SECT131R2:
- return 35; /* curve len in bytes = 17 bytes */
- case SEC_OID_SECG_EC_SECP160K1:
- case SEC_OID_SECG_EC_SECP160R1:
- case SEC_OID_SECG_EC_SECP160R2:
- return 41; /* curve len in bytes = 20 bytes */
- case SEC_OID_SECG_EC_SECT163K1:
- case SEC_OID_SECG_EC_SECT163R1:
- case SEC_OID_SECG_EC_SECT163R2:
- case SEC_OID_ANSIX962_EC_C2PNB163V1:
- case SEC_OID_ANSIX962_EC_C2PNB163V2:
- case SEC_OID_ANSIX962_EC_C2PNB163V3:
- return 43; /* curve len in bytes = 21 bytes */
- case SEC_OID_ANSIX962_EC_C2PNB176V1:
- return 45; /* curve len in bytes = 22 bytes */
- case SEC_OID_ANSIX962_EC_C2TNB191V1:
- case SEC_OID_ANSIX962_EC_C2TNB191V2:
- case SEC_OID_ANSIX962_EC_C2TNB191V3:
- case SEC_OID_SECG_EC_SECP192K1:
- case SEC_OID_ANSIX962_EC_PRIME192V1:
- case SEC_OID_ANSIX962_EC_PRIME192V2:
- case SEC_OID_ANSIX962_EC_PRIME192V3:
- return 49; /*curve len in bytes = 24 bytes */
- case SEC_OID_SECG_EC_SECT193R1:
- case SEC_OID_SECG_EC_SECT193R2:
- return 51; /*curve len in bytes = 25 bytes */
- case SEC_OID_ANSIX962_EC_C2PNB208W1:
- return 53; /*curve len in bytes = 26 bytes */
- case SEC_OID_SECG_EC_SECP224K1:
- case SEC_OID_SECG_EC_SECP224R1:
- return 57; /*curve len in bytes = 28 bytes */
- case SEC_OID_SECG_EC_SECT233K1:
- case SEC_OID_SECG_EC_SECT233R1:
- case SEC_OID_SECG_EC_SECT239K1:
- case SEC_OID_ANSIX962_EC_PRIME239V1:
- case SEC_OID_ANSIX962_EC_PRIME239V2:
- case SEC_OID_ANSIX962_EC_PRIME239V3:
- case SEC_OID_ANSIX962_EC_C2TNB239V1:
- case SEC_OID_ANSIX962_EC_C2TNB239V2:
- case SEC_OID_ANSIX962_EC_C2TNB239V3:
- return 61; /*curve len in bytes = 30 bytes */
- case SEC_OID_ANSIX962_EC_PRIME256V1:
- case SEC_OID_SECG_EC_SECP256K1:
- return 65; /*curve len in bytes = 32 bytes */
- case SEC_OID_ANSIX962_EC_C2PNB272W1:
- return 69; /*curve len in bytes = 34 bytes */
- case SEC_OID_SECG_EC_SECT283K1:
- case SEC_OID_SECG_EC_SECT283R1:
- return 73; /*curve len in bytes = 36 bytes */
- case SEC_OID_ANSIX962_EC_C2PNB304W1:
- return 77; /*curve len in bytes = 38 bytes */
- case SEC_OID_ANSIX962_EC_C2TNB359V1:
- return 91; /*curve len in bytes = 45 bytes */
- case SEC_OID_ANSIX962_EC_C2PNB368W1:
- return 93; /*curve len in bytes = 46 bytes */
- case SEC_OID_SECG_EC_SECP384R1:
- return 97; /*curve len in bytes = 48 bytes */
- case SEC_OID_SECG_EC_SECT409K1:
- case SEC_OID_SECG_EC_SECT409R1:
- return 105; /*curve len in bytes = 52 bytes */
- case SEC_OID_ANSIX962_EC_C2TNB431R1:
- return 109; /*curve len in bytes = 54 bytes */
- case SEC_OID_SECG_EC_SECP521R1:
- return 133; /*curve len in bytes = 66 bytes */
- case SEC_OID_SECG_EC_SECT571K1:
- case SEC_OID_SECG_EC_SECT571R1:
- return 145; /*curve len in bytes = 72 bytes */
- /* unknown or unrecognized OIDs. return unknown length */
- default:
- break;
- }
- return 0;
-}
-
-/*
- * returns the decoded point. In some cases the point may already be decoded.
- * this function tries to detect those cases and return the point in
- * publicKeyValue. In other cases it's DER encoded. In those cases the point
- * is first decoded and returned. Space for the point is allocated out of
- * the passed in arena.
- */
-static CK_RV
-pk11_get_Decoded_ECPoint(PRArenaPool *arena, const SECItem *ecParams,
- const CK_ATTRIBUTE *ecPoint, SECItem *publicKeyValue)
-{
- SECItem encodedPublicValue;
- SECStatus rv;
- int keyLen;
-
- if (ecPoint->ulValueLen == 0) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /*
- * The PKCS #11 spec requires ecPoints to be encoded as a DER OCTET String.
- * NSS has mistakenly passed unencoded values, and some PKCS #11 vendors
- * followed that mistake. Now we need to detect which encoding we were
- * passed in. The task is made more complicated by the fact the the
- * DER encoding byte (SEC_ASN_OCTET_STRING) is the same as the
- * EC_POINT_FORM_UNCOMPRESSED byte (0x04), so we can't use that to
- * determine which curve we are using.
- */
-
- /* get the expected key length for the passed in curve.
- * pk11_get_EC_PointLenInBytes only returns valid values for curves
- * NSS has traditionally recognized. If the curve is not recognized,
- * it will return '0', and we have to figure out if the key was
- * encoded or not heuristically. If the ecParams are invalid, it
- * will return -1 for the keyLen.
- */
- keyLen = pk11_get_EC_PointLenInBytes(arena, ecParams);
- if (keyLen < 0) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
-
- /* If the point is uncompressed and the lengths match, it
- * must be an unencoded point */
- if ((*((char *)ecPoint->pValue) == EC_POINT_FORM_UNCOMPRESSED)
- && (ecPoint->ulValueLen == keyLen)) {
- return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue);
- }
-
- /* now assume the key passed to us was encoded and decode it */
- if (*((char *)ecPoint->pValue) == SEC_ASN1_OCTET_STRING) {
- /* OK, now let's try to decode it and see if it's valid */
- encodedPublicValue.data = ecPoint->pValue;
- encodedPublicValue.len = ecPoint->ulValueLen;
- rv = SEC_QuickDERDecodeItem(arena, publicKeyValue,
- SEC_ASN1_GET(SEC_OctetStringTemplate), &encodedPublicValue);
-
- /* it coded correctly & we know the key length (and they match)
- * then we are done, return the results. */
- if (keyLen && rv == SECSuccess && publicKeyValue->len == keyLen) {
- return CKR_OK;
- }
-
- /* if we know the key length, one of the above tests should have
- * succeded. If it doesn't the module gave us bad data */
- if (keyLen) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
-
- /* We don't know the key length, so we don't know deterministically
- * which encoding was used. We now will try to pick the most likely
- * form that's correct, with a preference for the encoded form if we
- * can't determine for sure. We do this by checking the key we got
- * back from SEC_QuickDERDecodeItem for defects. If no defects are
- * found, we assume the encoded parameter was was passed to us.
- * our defect tests include:
- * 1) it didn't decode.
- * 2) The decode key had an invalid length (must be odd).
- * 3) The decoded key wasn't an UNCOMPRESSED key.
- * 4) The decoded key didn't include the entire encoded block
- * except the DER encoding values. (fixing DER length to one
- * particular value).
- */
- if ((rv != SECSuccess)
- || ((publicKeyValue->len & 1) != 1)
- || (publicKeyValue->data[0] != EC_POINT_FORM_UNCOMPRESSED)
- || (PORT_Memcmp(&encodedPublicValue.data[encodedPublicValue.len -
- publicKeyValue->len], publicKeyValue->data,
- publicKeyValue->len) != 0)) {
- /* The decoded public key was flawed, the original key must have
- * already been in decoded form. Do a quick sanity check then
- * return the original key value.
- */
- if ((encodedPublicValue.len & 1) == 0) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue);
- }
-
- /* as best we can figure, the passed in key was encoded, and we've
- * now decoded it. Note: there is a chance this could be wrong if the
- * following conditions hold:
- * 1) The first byte or bytes of the X point looks like a valid length
- * of precisely the right size (2*curveSize -1). this means for curves
- * less than 512 bits (64 bytes), this will happen 1 in 256 times*.
- * for curves between 512 and 1024, this will happen 1 in 65,536 times*
- * for curves between 1024 and 256K this will happen 1 in 16 million*
- * 2) The length of the 'DER length field' is odd
- * (making both the encoded and decode
- * values an odd length. this is true of all curves less than 512,
- * as well as curves between 1024 and 256K).
- * 3) The X[length of the 'DER length field'] == 0x04, 1 in 256.
- *
- * (* assuming all values are equally likely in the first byte,
- * This isn't true if the curve length is not a multiple of 8. In these
- * cases, if the DER length is possible, it's more likely,
- * if it's not possible, then we have no false decodes).
- *
- * For reference here are the odds for the various curves we currently
- * have support for (and the only curves SSL will negotiate at this
- * time). NOTE: None of the supported curves will show up here
- * because we return a valid length for all of these curves.
- * The only way to get here is to have some application (not SSL)
- * which supports some unknown curve and have some vendor supplied
- * PKCS #11 module support that curve. NOTE: in this case, one
- * presumes that that pkcs #11 module is likely to be using the
- * correct encodings.
- *
- * Prime Curves (GFp):
- * Bit False Odds of
- * Size DER Len False Decode Positive
- * 112 27 1 in 65536
- * 128 31 1 in 65536
- * 160 39 1 in 65536
- * 192 47 1 in 65536
- * 224 55 1 in 65536
- * 239 59 1 in 32768 (top byte can only be 0-127)
- * 256 63 1 in 65536
- * 521 129,131 0 (decoded value would be even)
- *
- * Binary curves (GF2m).
- * Bit False Odds of
- * Size DER Len False Decode Positive
- * 131 33 0 (top byte can only be 0-7)
- * 163 41 0 (top byte can only be 0-7)
- * 176 43 1 in 65536
- * 191 47 1 in 32768 (top byte can only be 0-127)
- * 193 49 0 (top byte can only be 0-1)
- * 208 51 1 in 65536
- * 233 59 0 (top byte can only be 0-1)
- * 239 59 1 in 32768 (top byte can only be 0-127)
- * 272 67 1 in 65536
- * 283 71 0 (top byte can only be 0-7)
- * 304 75 1 in 65536
- * 359 89 1 in 32768 (top byte can only be 0-127)
- * 368 91 1 in 65536
- * 409 103 0 (top byte can only be 0-1)
- * 431 107 1 in 32768 (top byte can only be 0-127)
- * 571 129,143 0 (decoded value would be even)
- *
- */
-
- return CKR_OK;
- }
-
- /* In theory, we should handle the case where the curve == 0 and
- * the first byte is EC_POINT_FORM_UNCOMPRESSED, (which would be
- * handled by doing a santity check on the key length and returning
- * pk11_Attr2SecItem() to copy the ecPoint to the publicKeyValue).
- *
- * This test is unnecessary, however, due to the fact that
- * EC_POINT_FORM_UNCOMPRESSED == SEC_ASIN1_OCTET_STRING, that case is
- * handled in the above if. That means if we get here, the initial
- * byte of our ecPoint value was invalid, so we can safely return.
- * invalid attribute.
- */
-
- return CKR_ATTRIBUTE_VALUE_INVALID;
-}
-
-/*
- * extract a public key from a slot and id
- */
-SECKEYPublicKey *
-PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
-{
- CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
- PRArenaPool *arena;
- PRArenaPool *tmp_arena;
- SECKEYPublicKey *pubKey;
- int templateCount = 0;
- CK_KEY_TYPE pk11KeyType;
- CK_RV crv;
- CK_ATTRIBUTE template[8];
- CK_ATTRIBUTE *attrs= template;
- CK_ATTRIBUTE *modulus,*exponent,*base,*prime,*subprime,*value;
- CK_ATTRIBUTE *ecparams;
-
- /* if we didn't know the key type, get it */
- if (keyType== nullKey) {
-
- pk11KeyType = PK11_ReadULongAttribute(slot,id,CKA_KEY_TYPE);
- if (pk11KeyType == CK_UNAVAILABLE_INFORMATION) {
- return NULL;
- }
- switch (pk11KeyType) {
- case CKK_RSA:
- keyType = rsaKey;
- break;
- case CKK_DSA:
- keyType = dsaKey;
- break;
- case CKK_DH:
- keyType = dhKey;
- break;
- case CKK_EC:
- keyType = ecKey;
- break;
- default:
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return NULL;
- }
- }
-
-
- /* now we need to create space for the public key */
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return NULL;
- tmp_arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (tmp_arena == NULL) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
- }
-
-
- pubKey = (SECKEYPublicKey *)
- PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
- if (pubKey == NULL) {
- PORT_FreeArena (arena, PR_FALSE);
- PORT_FreeArena (tmp_arena, PR_FALSE);
- return NULL;
- }
-
- pubKey->arena = arena;
- pubKey->keyType = keyType;
- pubKey->pkcs11Slot = PK11_ReferenceSlot(slot);
- pubKey->pkcs11ID = id;
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass,
- sizeof(keyClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &pk11KeyType,
- sizeof(pk11KeyType) ); attrs++;
- switch (pubKey->keyType) {
- case rsaKey:
- modulus = attrs;
- PK11_SETATTRS(attrs, CKA_MODULUS, NULL, 0); attrs++;
- exponent = attrs;
- PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, NULL, 0); attrs++;
-
- templateCount = attrs - template;
- PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
- crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
- if (crv != CKR_OK) break;
-
- if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_RSA)) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- break;
- }
- crv = pk11_Attr2SecItem(arena,modulus,&pubKey->u.rsa.modulus);
- if (crv != CKR_OK) break;
- crv = pk11_Attr2SecItem(arena,exponent,&pubKey->u.rsa.publicExponent);
- if (crv != CKR_OK) break;
- break;
- case dsaKey:
- prime = attrs;
- PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++;
- subprime = attrs;
- PK11_SETATTRS(attrs, CKA_SUBPRIME, NULL, 0); attrs++;
- base = attrs;
- PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++;
- value = attrs;
- PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++;
- templateCount = attrs - template;
- PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
- crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
- if (crv != CKR_OK) break;
-
- if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DSA)) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- break;
- }
- crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dsa.params.prime);
- if (crv != CKR_OK) break;
- crv = pk11_Attr2SecItem(arena,subprime,&pubKey->u.dsa.params.subPrime);
- if (crv != CKR_OK) break;
- crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dsa.params.base);
- if (crv != CKR_OK) break;
- crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dsa.publicValue);
- if (crv != CKR_OK) break;
- break;
- case dhKey:
- prime = attrs;
- PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++;
- base = attrs;
- PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++;
- value =attrs;
- PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++;
- templateCount = attrs - template;
- PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
- crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
- if (crv != CKR_OK) break;
-
- if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DH)) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- break;
- }
- crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dh.prime);
- if (crv != CKR_OK) break;
- crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dh.base);
- if (crv != CKR_OK) break;
- crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dh.publicValue);
- if (crv != CKR_OK) break;
- break;
- case ecKey:
- pubKey->u.ec.size = 0;
- ecparams = attrs;
- PK11_SETATTRS(attrs, CKA_EC_PARAMS, NULL, 0); attrs++;
- value =attrs;
- PK11_SETATTRS(attrs, CKA_EC_POINT, NULL, 0); attrs++;
- templateCount = attrs - template;
- PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
- crv = PK11_GetAttributes(arena,slot,id,template,templateCount);
- if (crv != CKR_OK) break;
-
- if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_EC)) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- break;
- }
-
- crv = pk11_Attr2SecItem(arena,ecparams,
- &pubKey->u.ec.DEREncodedParams);
- if (crv != CKR_OK) break;
- crv = pk11_get_Decoded_ECPoint(arena,
- &pubKey->u.ec.DEREncodedParams, value,
- &pubKey->u.ec.publicValue);
- break;
- case fortezzaKey:
- case nullKey:
- default:
- crv = CKR_OBJECT_HANDLE_INVALID;
- break;
- }
-
- PORT_FreeArena(tmp_arena,PR_FALSE);
-
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- PK11_FreeSlot(slot);
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
- }
-
- return pubKey;
-}
-
-/*
- * Build a Private Key structure from raw PKCS #11 information.
- */
-SECKEYPrivateKey *
-PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
- PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx)
-{
- PRArenaPool *arena;
- SECKEYPrivateKey *privKey;
- PRBool isPrivate;
- SECStatus rv;
-
- /* don't know? look it up */
- if (keyType == nullKey) {
- CK_KEY_TYPE pk11Type = CKK_RSA;
-
- pk11Type = PK11_ReadULongAttribute(slot,privID,CKA_KEY_TYPE);
- isTemp = (PRBool)!PK11_HasAttributeSet(slot,privID,CKA_TOKEN,PR_FALSE);
- switch (pk11Type) {
- case CKK_RSA: keyType = rsaKey; break;
- case CKK_DSA: keyType = dsaKey; break;
- case CKK_DH: keyType = dhKey; break;
- case CKK_KEA: keyType = fortezzaKey; break;
- case CKK_EC: keyType = ecKey; break;
- default:
- break;
- }
- }
-
- /* if the key is private, make sure we are authenticated to the
- * token before we try to use it */
- isPrivate = (PRBool)PK11_HasAttributeSet(slot,privID,CKA_PRIVATE,PR_FALSE);
- if (isPrivate) {
- rv = PK11_Authenticate(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- return NULL;
- }
- }
-
- /* now we need to create space for the private key */
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return NULL;
-
- privKey = (SECKEYPrivateKey *)
- PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey));
- if (privKey == NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
-
- privKey->arena = arena;
- privKey->keyType = keyType;
- privKey->pkcs11Slot = PK11_ReferenceSlot(slot);
- privKey->pkcs11ID = privID;
- privKey->pkcs11IsTemp = isTemp;
- privKey->wincx = wincx;
-
- return privKey;
-}
-
-
-PK11SlotInfo *
-PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key)
-{
- PK11SlotInfo *slot = key->pkcs11Slot;
- slot = PK11_ReferenceSlot(slot);
- return slot;
-}
-
-/*
- * Get the modulus length for raw parsing
- */
-int
-PK11_GetPrivateModulusLen(SECKEYPrivateKey *key)
-{
- CK_ATTRIBUTE theTemplate = { CKA_MODULUS, NULL, 0 };
- PK11SlotInfo *slot = key->pkcs11Slot;
- CK_RV crv;
- int length;
-
- switch (key->keyType) {
- case rsaKey:
- crv = PK11_GetAttributes(NULL, slot, key->pkcs11ID, &theTemplate, 1);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return -1;
- }
- length = theTemplate.ulValueLen;
- if ( *(unsigned char *)theTemplate.pValue == 0) {
- length--;
- }
- if (theTemplate.pValue != NULL)
- PORT_Free(theTemplate.pValue);
- return (int) length;
-
- case fortezzaKey:
- case dsaKey:
- case dhKey:
- default:
- break;
- }
- if (theTemplate.pValue != NULL)
- PORT_Free(theTemplate.pValue);
- PORT_SetError( SEC_ERROR_INVALID_KEY );
- return -1;
-}
-
-
-
-/*
- * take a private key in one pkcs11 module and load it into another:
- * NOTE: the source private key is a rare animal... it can't be sensitive.
- * This is used to do a key gen using one pkcs11 module and storing the
- * result into another.
- */
-static SECKEYPrivateKey *
-pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
- SECKEYPublicKey *pubKey, PK11AttrFlags attrFlags)
-{
- CK_ATTRIBUTE privTemplate[] = {
- /* class must be first */
- { CKA_CLASS, NULL, 0 },
- { CKA_KEY_TYPE, NULL, 0 },
- { CKA_ID, NULL, 0 },
- /* RSA - the attributes below will be replaced for other
- * key types.
- */
- { CKA_MODULUS, NULL, 0 },
- { CKA_PRIVATE_EXPONENT, NULL, 0 },
- { CKA_PUBLIC_EXPONENT, NULL, 0 },
- { CKA_PRIME_1, NULL, 0 },
- { CKA_PRIME_2, NULL, 0 },
- { CKA_EXPONENT_1, NULL, 0 },
- { CKA_EXPONENT_2, NULL, 0 },
- { CKA_COEFFICIENT, NULL, 0 },
- { CKA_DECRYPT, NULL, 0 },
- { CKA_DERIVE, NULL, 0 },
- { CKA_SIGN, NULL, 0 },
- { CKA_SIGN_RECOVER, NULL, 0 },
- { CKA_UNWRAP, NULL, 0 },
- /* reserve space for the attributes that may be
- * specified in attrFlags */
- { CKA_TOKEN, NULL, 0 },
- { CKA_PRIVATE, NULL, 0 },
- { CKA_MODIFIABLE, NULL, 0 },
- { CKA_SENSITIVE, NULL, 0 },
- { CKA_EXTRACTABLE, NULL, 0 },
-#define NUM_RESERVED_ATTRS 5 /* number of reserved attributes above */
- };
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_ATTRIBUTE *attrs = NULL, *ap;
- const int templateSize = sizeof(privTemplate)/sizeof(privTemplate[0]);
- PRArenaPool *arena;
- CK_OBJECT_HANDLE objectID;
- int i, count = 0;
- int extra_count = 0;
- CK_RV crv;
- SECStatus rv;
- PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0);
-
- if (pk11_BadAttrFlags(attrFlags)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- for (i=0; i < templateSize; i++) {
- if (privTemplate[i].type == CKA_MODULUS) {
- attrs= &privTemplate[i];
- count = i;
- break;
- }
- }
- PORT_Assert(attrs != NULL);
- if (attrs == NULL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
-
- ap = attrs;
-
- switch (privKey->keyType) {
- case rsaKey:
- count = templateSize - NUM_RESERVED_ATTRS;
- extra_count = count - (attrs - privTemplate);
- break;
- case dsaKey:
- ap->type = CKA_PRIME; ap++; count++; extra_count++;
- ap->type = CKA_SUBPRIME; ap++; count++; extra_count++;
- ap->type = CKA_BASE; ap++; count++; extra_count++;
- ap->type = CKA_VALUE; ap++; count++; extra_count++;
- ap->type = CKA_SIGN; ap++; count++; extra_count++;
- break;
- case dhKey:
- ap->type = CKA_PRIME; ap++; count++; extra_count++;
- ap->type = CKA_BASE; ap++; count++; extra_count++;
- ap->type = CKA_VALUE; ap++; count++; extra_count++;
- ap->type = CKA_DERIVE; ap++; count++; extra_count++;
- break;
- case ecKey:
- ap->type = CKA_EC_PARAMS; ap++; count++; extra_count++;
- ap->type = CKA_VALUE; ap++; count++; extra_count++;
- ap->type = CKA_DERIVE; ap++; count++; extra_count++;
- ap->type = CKA_SIGN; ap++; count++; extra_count++;
- break;
- default:
- count = 0;
- extra_count = 0;
- break;
- }
-
- if (count == 0) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return NULL;
- /*
- * read out the old attributes.
- */
- crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,
- privTemplate,count);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- PORT_FreeArena(arena, PR_TRUE);
- return NULL;
- }
-
- /* Set token, private, modifiable, sensitive, and extractable */
- count += pk11_AttrFlagsToAttributes(attrFlags, &privTemplate[count],
- &cktrue, &ckfalse);
-
- /* Not everyone can handle zero padded key values, give
- * them the raw data as unsigned */
- for (ap=attrs; extra_count; ap++, extra_count--) {
- pk11_SignedToUnsigned(ap);
- }
-
- /* now Store the puppies */
- rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, privTemplate,
- count, token, &objectID);
- PORT_FreeArena(arena, PR_TRUE);
- if (rv != SECSuccess) {
- return NULL;
- }
-
- /* try loading the public key */
- if (pubKey) {
- PK11_ImportPublicKey(slot, pubKey, token);
- if (pubKey->pkcs11Slot) {
- PK11_FreeSlot(pubKey->pkcs11Slot);
- pubKey->pkcs11Slot = NULL;
- pubKey->pkcs11ID = CK_INVALID_HANDLE;
- }
- }
-
- /* build new key structure */
- return PK11_MakePrivKey(slot, privKey->keyType, !token,
- objectID, privKey->wincx);
-}
-
-static SECKEYPrivateKey *
-pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
- SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
-{
- PK11AttrFlags attrFlags = 0;
- if (token) {
- attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
- } else {
- attrFlags |= (PK11_ATTR_SESSION | PK11_ATTR_PUBLIC);
- }
- if (sensitive) {
- attrFlags |= PK11_ATTR_SENSITIVE;
- } else {
- attrFlags |= PK11_ATTR_INSENSITIVE;
- }
- return pk11_loadPrivKeyWithFlags(slot, privKey, pubKey, attrFlags);
-}
-
-/*
- * export this for PSM
- */
-SECKEYPrivateKey *
-PK11_LoadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
- SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
-{
- return pk11_loadPrivKey(slot,privKey,pubKey,token,sensitive);
-}
-
-
-/*
- * Use the token to generate a key pair.
- */
-SECKEYPrivateKey *
-PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
- void *param, SECKEYPublicKey **pubKey, PK11AttrFlags attrFlags,
- CK_FLAGS opFlags, CK_FLAGS opFlagsMask, void *wincx)
-{
- /* we have to use these native types because when we call PKCS 11 modules
- * we have to make sure that we are using the correct sizes for all the
- * parameters. */
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL cktrue = CK_TRUE;
- CK_ULONG modulusBits;
- CK_BYTE publicExponent[4];
- CK_ATTRIBUTE privTemplate[] = {
- { CKA_SENSITIVE, NULL, 0},
- { CKA_TOKEN, NULL, 0},
- { CKA_PRIVATE, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_UNWRAP, NULL, 0},
- { CKA_SIGN, NULL, 0},
- { CKA_DECRYPT, NULL, 0},
- { CKA_EXTRACTABLE, NULL, 0},
- { CKA_MODIFIABLE, NULL, 0},
- };
- CK_ATTRIBUTE rsaPubTemplate[] = {
- { CKA_MODULUS_BITS, NULL, 0},
- { CKA_PUBLIC_EXPONENT, NULL, 0},
- { CKA_TOKEN, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_WRAP, NULL, 0},
- { CKA_VERIFY, NULL, 0},
- { CKA_VERIFY_RECOVER, NULL, 0},
- { CKA_ENCRYPT, NULL, 0},
- { CKA_MODIFIABLE, NULL, 0},
- };
- CK_ATTRIBUTE dsaPubTemplate[] = {
- { CKA_PRIME, NULL, 0 },
- { CKA_SUBPRIME, NULL, 0 },
- { CKA_BASE, NULL, 0 },
- { CKA_TOKEN, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_WRAP, NULL, 0},
- { CKA_VERIFY, NULL, 0},
- { CKA_VERIFY_RECOVER, NULL, 0},
- { CKA_ENCRYPT, NULL, 0},
- { CKA_MODIFIABLE, NULL, 0},
- };
- CK_ATTRIBUTE dhPubTemplate[] = {
- { CKA_PRIME, NULL, 0 },
- { CKA_BASE, NULL, 0 },
- { CKA_TOKEN, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_WRAP, NULL, 0},
- { CKA_VERIFY, NULL, 0},
- { CKA_VERIFY_RECOVER, NULL, 0},
- { CKA_ENCRYPT, NULL, 0},
- { CKA_MODIFIABLE, NULL, 0},
- };
- CK_ATTRIBUTE ecPubTemplate[] = {
- { CKA_EC_PARAMS, NULL, 0 },
- { CKA_TOKEN, NULL, 0},
- { CKA_DERIVE, NULL, 0},
- { CKA_WRAP, NULL, 0},
- { CKA_VERIFY, NULL, 0},
- { CKA_VERIFY_RECOVER, NULL, 0},
- { CKA_ENCRYPT, NULL, 0},
- { CKA_MODIFIABLE, NULL, 0},
- };
- SECKEYECParams * ecParams;
-
- /*CK_ULONG key_size = 0;*/
- CK_ATTRIBUTE *pubTemplate;
- int privCount = 0;
- int pubCount = 0;
- PK11RSAGenParams *rsaParams;
- SECKEYPQGParams *dsaParams;
- SECKEYDHParams * dhParams;
- CK_MECHANISM mechanism;
- CK_MECHANISM test_mech;
- CK_MECHANISM test_mech2;
- CK_SESSION_HANDLE session_handle;
- CK_RV crv;
- CK_OBJECT_HANDLE privID,pubID;
- SECKEYPrivateKey *privKey;
- KeyType keyType;
- PRBool restore;
- int peCount,i;
- CK_ATTRIBUTE *attrs;
- CK_ATTRIBUTE *privattrs;
- CK_ATTRIBUTE setTemplate;
- CK_MECHANISM_INFO mechanism_info;
- CK_OBJECT_CLASS keyClass;
- SECItem *cka_id;
- PRBool haslock = PR_FALSE;
- PRBool pubIsToken = PR_FALSE;
- PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0);
- /* subset of attrFlags applicable to the public key */
- PK11AttrFlags pubKeyAttrFlags = attrFlags &
- (PK11_ATTR_TOKEN | PK11_ATTR_SESSION
- | PK11_ATTR_MODIFIABLE | PK11_ATTR_UNMODIFIABLE);
-
- if (pk11_BadAttrFlags(attrFlags)) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
- }
-
- if (!param) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
- }
-
- /*
- * The opFlags and opFlagMask parameters allow us to control the
- * settings of the key usage attributes (CKA_ENCRYPT and friends).
- * opFlagMask is set to one if the flag is specified in opFlags and
- * zero if it is to take on a default value calculated by
- * PK11_GenerateKeyPairWithOpFlags.
- * opFlags specifies the actual value of the flag 1 or 0.
- * Bits not corresponding to one bits in opFlagMask should be zero.
- */
-
- /* if we are trying to turn on a flag, it better be in the mask */
- PORT_Assert ((opFlags & ~opFlagsMask) == 0);
- opFlags &= opFlagsMask;
-
- PORT_Assert(slot != NULL);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE);
- return NULL;
- }
-
- /* if our slot really doesn't do this mechanism, Generate the key
- * in our internal token and write it out */
- if (!PK11_DoesMechanism(slot,type)) {
- PK11SlotInfo *int_slot = PK11_GetInternalSlot();
-
- /* don't loop forever looking for a slot */
- if (slot == int_slot) {
- PK11_FreeSlot(int_slot);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
-
- /* if there isn't a suitable slot, then we can't do the keygen */
- if (int_slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
-
- /* generate the temporary key to load */
- privKey = PK11_GenerateKeyPair(int_slot,type, param, pubKey, PR_FALSE,
- PR_FALSE, wincx);
- PK11_FreeSlot(int_slot);
-
- /* if successful, load the temp key into the new token */
- if (privKey != NULL) {
- SECKEYPrivateKey *newPrivKey = pk11_loadPrivKeyWithFlags(slot,
- privKey,*pubKey,attrFlags);
- SECKEY_DestroyPrivateKey(privKey);
- if (newPrivKey == NULL) {
- SECKEY_DestroyPublicKey(*pubKey);
- *pubKey = NULL;
- }
- return newPrivKey;
- }
- return NULL;
- }
-
-
- mechanism.mechanism = type;
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
- test_mech.pParameter = NULL;
- test_mech.ulParameterLen = 0;
- test_mech2.mechanism = CKM_INVALID_MECHANISM;
- test_mech2.pParameter = NULL;
- test_mech2.ulParameterLen = 0;
-
- /* set up the private key template */
- privattrs = privTemplate;
- privattrs += pk11_AttrFlagsToAttributes(attrFlags, privattrs,
- &cktrue, &ckfalse);
-
- /* set up the mechanism specific info */
- switch (type) {
- case CKM_RSA_PKCS_KEY_PAIR_GEN:
- case CKM_RSA_X9_31_KEY_PAIR_GEN:
- rsaParams = (PK11RSAGenParams *)param;
- if (rsaParams->pe == 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- modulusBits = rsaParams->keySizeInBits;
- peCount = 0;
-
- /* convert pe to a PKCS #11 string */
- for (i=0; i < 4; i++) {
- if (peCount || (rsaParams->pe &
- ((unsigned long)0xff000000L >> (i*8)))) {
- publicExponent[peCount] =
- (CK_BYTE)((rsaParams->pe >> (3-i)*8) & 0xff);
- peCount++;
- }
- }
- PORT_Assert(peCount != 0);
- attrs = rsaPubTemplate;
- PK11_SETATTRS(attrs, CKA_MODULUS_BITS,
- &modulusBits, sizeof(modulusBits)); attrs++;
- PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
- publicExponent, peCount);attrs++;
- pubTemplate = rsaPubTemplate;
- keyType = rsaKey;
- test_mech.mechanism = CKM_RSA_PKCS;
- break;
- case CKM_DSA_KEY_PAIR_GEN:
- dsaParams = (SECKEYPQGParams *)param;
- attrs = dsaPubTemplate;
- PK11_SETATTRS(attrs, CKA_PRIME, dsaParams->prime.data,
- dsaParams->prime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_SUBPRIME, dsaParams->subPrime.data,
- dsaParams->subPrime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_BASE, dsaParams->base.data,
- dsaParams->base.len); attrs++;
- pubTemplate = dsaPubTemplate;
- keyType = dsaKey;
- test_mech.mechanism = CKM_DSA;
- break;
- case CKM_DH_PKCS_KEY_PAIR_GEN:
- dhParams = (SECKEYDHParams *)param;
- attrs = dhPubTemplate;
- PK11_SETATTRS(attrs, CKA_PRIME, dhParams->prime.data,
- dhParams->prime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_BASE, dhParams->base.data,
- dhParams->base.len); attrs++;
- pubTemplate = dhPubTemplate;
- keyType = dhKey;
- test_mech.mechanism = CKM_DH_PKCS_DERIVE;
- break;
- case CKM_EC_KEY_PAIR_GEN:
- ecParams = (SECKEYECParams *)param;
- attrs = ecPubTemplate;
- PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data,
- ecParams->len); attrs++;
- pubTemplate = ecPubTemplate;
- keyType = ecKey;
- /*
- * ECC supports 2 different mechanism types (unlike RSA, which
- * supports different usages with the same mechanism).
- * We may need to query both mechanism types and or the results
- * together -- but we only do that if either the user has
- * requested both usages, or not specified any usages.
- */
- if ((opFlags & (CKF_SIGN|CKF_DERIVE)) == (CKF_SIGN|CKF_DERIVE)) {
- /* We've explicitly turned on both flags, use both mechanism */
- test_mech.mechanism = CKM_ECDH1_DERIVE;
- test_mech2.mechanism = CKM_ECDSA;
- } else if (opFlags & CKF_SIGN) {
- /* just do signing */
- test_mech.mechanism = CKM_ECDSA;
- } else if (opFlags & CKF_DERIVE) {
- /* just do ECDH */
- test_mech.mechanism = CKM_ECDH1_DERIVE;
- } else {
- /* neither was specified default to both */
- test_mech.mechanism = CKM_ECDH1_DERIVE;
- test_mech2.mechanism = CKM_ECDSA;
- }
- break;
- default:
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return NULL;
- }
-
- /* now query the slot to find out how "good" a key we can generate */
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
- test_mech.mechanism,&mechanism_info);
- /*
- * EC keys are used in multiple different types of mechanism, if we
- * are using dual use keys, we need to query the second mechanism
- * as well.
- */
- if (test_mech2.mechanism != CKM_INVALID_MECHANISM) {
- CK_MECHANISM_INFO mechanism_info2;
- CK_RV crv2;
-
- if (crv != CKR_OK) {
- /* the first failed, make sure there is no trash in the
- * mechanism flags when we or it below */
- mechanism_info.flags = 0;
- }
- crv2 = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
- test_mech2.mechanism, &mechanism_info2);
- if (crv2 == CKR_OK) {
- crv = CKR_OK; /* succeed if either mechnaism info succeeds */
- /* combine the 2 sets of mechnanism flags */
- mechanism_info.flags |= mechanism_info2.flags;
- }
- }
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if ((crv != CKR_OK) || (mechanism_info.flags == 0)) {
- /* must be old module... guess what it should be... */
- switch (test_mech.mechanism) {
- case CKM_RSA_PKCS:
- mechanism_info.flags = (CKF_SIGN | CKF_DECRYPT |
- CKF_WRAP | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_WRAP);
- break;
- case CKM_DSA:
- mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
- break;
- case CKM_DH_PKCS_DERIVE:
- mechanism_info.flags = CKF_DERIVE;
- break;
- case CKM_ECDH1_DERIVE:
- mechanism_info.flags = CKF_DERIVE;
- if (test_mech2.mechanism == CKM_ECDSA) {
- mechanism_info.flags |= CKF_SIGN | CKF_VERIFY;
- }
- break;
- case CKM_ECDSA:
- mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
- break;
- default:
- break;
- }
- }
- /* now adjust our flags according to the user's key usage passed to us */
- mechanism_info.flags = (mechanism_info.flags & (~opFlagsMask)) | opFlags;
- /* set the public key attributes */
- attrs += pk11_AttrFlagsToAttributes(pubKeyAttrFlags, attrs,
- &cktrue, &ckfalse);
- PK11_SETATTRS(attrs, CKA_DERIVE,
- mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_WRAP,
- mechanism_info.flags & CKF_WRAP ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_VERIFY,
- mechanism_info.flags & CKF_VERIFY ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_VERIFY_RECOVER,
- mechanism_info.flags & CKF_VERIFY_RECOVER ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_ENCRYPT,
- mechanism_info.flags & CKF_ENCRYPT? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); attrs++;
- /* set the private key attributes */
- PK11_SETATTRS(privattrs, CKA_DERIVE,
- mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
- PK11_SETATTRS(privattrs, CKA_UNWRAP,
- mechanism_info.flags & CKF_UNWRAP ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
- PK11_SETATTRS(privattrs, CKA_SIGN,
- mechanism_info.flags & CKF_SIGN ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
- PK11_SETATTRS(privattrs, CKA_DECRYPT,
- mechanism_info.flags & CKF_DECRYPT ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL)); privattrs++;
-
- if (token) {
- session_handle = PK11_GetRWSession(slot);
- haslock = PK11_RWSessionHasLock(slot,session_handle);
- restore = PR_TRUE;
- } else {
- session_handle = slot->session;
- if (session_handle != CK_INVALID_SESSION)
- PK11_EnterSlotMonitor(slot);
- restore = PR_FALSE;
- haslock = PR_TRUE;
- }
-
- if (session_handle == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return NULL;
- }
- privCount = privattrs - privTemplate;
- pubCount = attrs - pubTemplate;
- crv = PK11_GETTAB(slot)->C_GenerateKeyPair(session_handle, &mechanism,
- pubTemplate,pubCount,privTemplate,privCount,&pubID,&privID);
-
- if (crv != CKR_OK) {
- if (restore) {
- PK11_RestoreROSession(slot,session_handle);
- } else PK11_ExitSlotMonitor(slot);
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
- }
- /* This locking code is dangerous and needs to be more thought
- * out... the real problem is that we're holding the mutex open this long
- */
- if (haslock) { PK11_ExitSlotMonitor(slot); }
-
- /* swap around the ID's for older PKCS #11 modules */
- keyClass = PK11_ReadULongAttribute(slot,pubID,CKA_CLASS);
- if (keyClass != CKO_PUBLIC_KEY) {
- CK_OBJECT_HANDLE tmp = pubID;
- pubID = privID;
- privID = tmp;
- }
-
- *pubKey = PK11_ExtractPublicKey(slot, keyType, pubID);
- if (*pubKey == NULL) {
- if (restore) {
- /* we may have to restore the mutex so it get's exited properly
- * in RestoreROSession */
- if (haslock) PK11_EnterSlotMonitor(slot);
- PK11_RestoreROSession(slot,session_handle);
- }
- PK11_DestroyObject(slot,pubID);
- PK11_DestroyObject(slot,privID);
- return NULL;
- }
-
- /* set the ID to the public key so we can find it again */
- cka_id = pk11_MakeIDFromPublicKey(*pubKey);
- pubIsToken = (PRBool)PK11_HasAttributeSet(slot,pubID, CKA_TOKEN,PR_FALSE);
-
- PK11_SETATTRS(&setTemplate, CKA_ID, cka_id->data, cka_id->len);
-
- if (haslock) { PK11_EnterSlotMonitor(slot); }
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, privID,
- &setTemplate, 1);
-
- if (crv == CKR_OK && pubIsToken) {
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, pubID,
- &setTemplate, 1);
- }
-
-
- if (restore) {
- PK11_RestoreROSession(slot,session_handle);
- } else {
- PK11_ExitSlotMonitor(slot);
- }
- SECITEM_FreeItem(cka_id,PR_TRUE);
-
-
- if (crv != CKR_OK) {
- PK11_DestroyObject(slot,pubID);
- PK11_DestroyObject(slot,privID);
- PORT_SetError( PK11_MapError(crv) );
- *pubKey = NULL;
- return NULL;
- }
-
- privKey = PK11_MakePrivKey(slot,keyType,!token,privID,wincx);
- if (privKey == NULL) {
- SECKEY_DestroyPublicKey(*pubKey);
- PK11_DestroyObject(slot,privID);
- *pubKey = NULL;
- return NULL;
- }
-
- return privKey;
-}
-
-SECKEYPrivateKey *
-PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
- void *param, SECKEYPublicKey **pubKey, PK11AttrFlags attrFlags, void *wincx)
-{
- return PK11_GenerateKeyPairWithOpFlags(slot,type,param,pubKey,attrFlags,
- 0, 0, wincx);
-}
-
-/*
- * Use the token to generate a key pair.
- */
-SECKEYPrivateKey *
-PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
- void *param, SECKEYPublicKey **pubKey, PRBool token,
- PRBool sensitive, void *wincx)
-{
- PK11AttrFlags attrFlags = 0;
-
- if (token) {
- attrFlags |= PK11_ATTR_TOKEN;
- } else {
- attrFlags |= PK11_ATTR_SESSION;
- }
- if (sensitive) {
- attrFlags |= (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE);
- } else {
- attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC);
- }
- return PK11_GenerateKeyPairWithFlags(slot, type, param, pubKey,
- attrFlags, wincx);
-}
-
-/* build a public KEA key from the public value */
-SECKEYPublicKey *
-PK11_MakeKEAPubKey(unsigned char *keyData,int length)
-{
- SECKEYPublicKey *pubk;
- SECItem pkData;
- SECStatus rv;
- PRArenaPool *arena;
-
- pkData.data = keyData;
- pkData.len = length;
-
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- return NULL;
-
- pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
- if (pubk == NULL) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
- }
-
- pubk->arena = arena;
- pubk->pkcs11Slot = 0;
- pubk->pkcs11ID = CK_INVALID_HANDLE;
- pubk->keyType = fortezzaKey;
- rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.KEAKey, &pkData);
- if (rv != SECSuccess) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
- }
- return pubk;
-}
-
-/*
- * NOTE: This function doesn't return a SECKEYPrivateKey struct to represent
- * the new private key object. If it were to create a session object that
- * could later be looked up by its nickname, it would leak a SECKEYPrivateKey.
- * So isPerm must be true.
- */
-SECStatus
-PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot,
- SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem,
- SECItem *nickname, SECItem *publicValue, PRBool isPerm,
- PRBool isPrivate, KeyType keyType,
- unsigned int keyUsage, void *wincx)
-{
- if (!isPerm) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- return PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(slot, epki,
- pwitem, nickname, publicValue, isPerm, isPrivate, keyType,
- keyUsage, NULL, wincx);
-}
-
-SECStatus
-PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
- SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem,
- SECItem *nickname, SECItem *publicValue, PRBool isPerm,
- PRBool isPrivate, KeyType keyType,
- unsigned int keyUsage, SECKEYPrivateKey **privk,
- void *wincx)
-{
- CK_MECHANISM_TYPE pbeMechType;
- SECItem *crypto_param = NULL;
- PK11SymKey *key = NULL;
- SECStatus rv = SECSuccess;
- CK_MECHANISM_TYPE cryptoMechType;
- SECKEYPrivateKey *privKey = NULL;
- PRBool faulty3DES = PR_FALSE;
- int usageCount = 0;
- CK_KEY_TYPE key_type;
- CK_ATTRIBUTE_TYPE *usage = NULL;
- CK_ATTRIBUTE_TYPE rsaUsage[] = {
- CKA_UNWRAP, CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER };
- CK_ATTRIBUTE_TYPE dsaUsage[] = { CKA_SIGN };
- CK_ATTRIBUTE_TYPE dhUsage[] = { CKA_DERIVE };
- CK_ATTRIBUTE_TYPE ecUsage[] = { CKA_SIGN, CKA_DERIVE };
- if((epki == NULL) || (pwitem == NULL))
- return SECFailure;
-
- pbeMechType = PK11_AlgtagToMechanism(SECOID_FindOIDTag(
- &epki->algorithm.algorithm));
-
- switch (keyType) {
- default:
- case rsaKey:
- key_type = CKK_RSA;
- switch (keyUsage & (KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE)) {
- case KU_KEY_ENCIPHERMENT:
- usage = rsaUsage;
- usageCount = 2;
- break;
- case KU_DIGITAL_SIGNATURE:
- usage = &rsaUsage[2];
- usageCount = 2;
- break;
- case KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE:
- case 0: /* default to everything */
- usage = rsaUsage;
- usageCount = 4;
- break;
- }
- break;
- case dhKey:
- key_type = CKK_DH;
- usage = dhUsage;
- usageCount = sizeof(dhUsage)/sizeof(dhUsage[0]);
- break;
- case dsaKey:
- key_type = CKK_DSA;
- usage = dsaUsage;
- usageCount = sizeof(dsaUsage)/sizeof(dsaUsage[0]);
- break;
- case ecKey:
- key_type = CKK_EC;
- switch (keyUsage & (KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT)) {
- case KU_DIGITAL_SIGNATURE:
- usage = ecUsage;
- usageCount = 1;
- break;
- case KU_KEY_AGREEMENT:
- usage = &ecUsage[1];
- usageCount = 1;
- break;
- case KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT:
- default: /* default to everything */
- usage = ecUsage;
- usageCount = 2;
- break;
- }
- break;
- }
-
-try_faulty_3des:
-
- key = PK11_PBEKeyGen(slot, &epki->algorithm, pwitem, faulty3DES, wincx);
- if (key == NULL) {
- rv = SECFailure;
- goto done;
- }
- cryptoMechType = pk11_GetPBECryptoMechanism(&epki->algorithm,
- &crypto_param, pwitem, faulty3DES);
- if (cryptoMechType == CKM_INVALID_MECHANISM) {
- rv = SECFailure;
- goto done;
- }
-
-
- cryptoMechType = PK11_GetPadMechanism(cryptoMechType);
-
- PORT_Assert(usage != NULL);
- PORT_Assert(usageCount != 0);
- privKey = PK11_UnwrapPrivKey(slot, key, cryptoMechType,
- crypto_param, &epki->encryptedData,
- nickname, publicValue, isPerm, isPrivate,
- key_type, usage, usageCount, wincx);
- if(privKey) {
- if (privk) {
- *privk = privKey;
- } else {
- SECKEY_DestroyPrivateKey(privKey);
- }
- privKey = NULL;
- rv = SECSuccess;
- goto done;
- }
-
- /* if we are unable to import the key and the pbeMechType is
- * CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, then it is possible that
- * the encrypted blob was created with a buggy key generation method
- * which is described in the PKCS 12 implementation notes. So we
- * need to try importing via that method.
- */
- if((pbeMechType == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC) && (!faulty3DES)) {
- /* clean up after ourselves before redoing the key generation. */
-
- PK11_FreeSymKey(key);
- key = NULL;
-
- if(crypto_param) {
- SECITEM_ZfreeItem(crypto_param, PR_TRUE);
- crypto_param = NULL;
- }
-
- faulty3DES = PR_TRUE;
- goto try_faulty_3des;
- }
-
- /* key import really did fail */
- rv = SECFailure;
-
-done:
- if(crypto_param != NULL) {
- SECITEM_ZfreeItem(crypto_param, PR_TRUE);
- }
-
- if(key != NULL) {
- PK11_FreeSymKey(key);
- }
-
- return rv;
-}
-
-SECKEYPrivateKeyInfo *
-PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx)
-{
- return NULL;
-}
-
-SECKEYEncryptedPrivateKeyInfo *
-PK11_ExportEncryptedPrivKeyInfo(
- PK11SlotInfo *slot, /* optional, encrypt key in this slot */
- SECOidTag algTag, /* encrypt key with this algorithm */
- SECItem *pwitem, /* password for PBE encryption */
- SECKEYPrivateKey *pk, /* encrypt this private key */
- int iteration, /* interations for PBE alg */
- void *wincx) /* context for password callback ? */
-{
- SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- PRArenaPool *arena = NULL;
- SECAlgorithmID *algid;
- SECOidTag pbeAlgTag = SEC_OID_UNKNOWN;
- SECItem *crypto_param = NULL;
- PK11SymKey *key = NULL;
- SECKEYPrivateKey *tmpPK = NULL;
- SECStatus rv = SECSuccess;
- CK_RV crv;
- CK_ULONG encBufLen;
- CK_MECHANISM_TYPE pbeMechType;
- CK_MECHANISM_TYPE cryptoMechType;
- CK_MECHANISM cryptoMech;
-
- if (!pwitem || !pk) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- algid = sec_pkcs5CreateAlgorithmID(algTag, SEC_OID_UNKNOWN, SEC_OID_UNKNOWN,
- &pbeAlgTag, 0, NULL, iteration);
- if (algid == NULL) {
- return NULL;
- }
-
- arena = PORT_NewArena(2048);
- if (arena)
- epki = PORT_ArenaZNew(arena, SECKEYEncryptedPrivateKeyInfo);
- if(epki == NULL) {
- rv = SECFailure;
- goto loser;
- }
- epki->arena = arena;
-
-
- /* if we didn't specify a slot, use the slot the private key was in */
- if (!slot) {
- slot = pk->pkcs11Slot;
- }
-
- /* if we specified a different slot, and the private key slot can do the
- * pbe key gen, generate the key in the private key slot so we don't have
- * to move it later */
- pbeMechType = PK11_AlgtagToMechanism(pbeAlgTag);
- if (slot != pk->pkcs11Slot) {
- if (PK11_DoesMechanism(pk->pkcs11Slot,pbeMechType)) {
- slot = pk->pkcs11Slot;
- }
- }
- key = PK11_PBEKeyGen(slot, algid, pwitem, PR_FALSE, wincx);
- if (key == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- cryptoMechType = PK11_GetPBECryptoMechanism(algid, &crypto_param, pwitem);
- if (cryptoMechType == CKM_INVALID_MECHANISM) {
- rv = SECFailure;
- goto loser;
- }
-
- cryptoMech.mechanism = PK11_GetPadMechanism(cryptoMechType);
- cryptoMech.pParameter = crypto_param ? crypto_param->data : NULL;
- cryptoMech.ulParameterLen = crypto_param ? crypto_param->len : 0;
-
- /* If the key isn't in the private key slot, move it */
- if (key->slot != pk->pkcs11Slot) {
- PK11SymKey *newkey = pk11_CopyToSlot(pk->pkcs11Slot,
- key->type, CKA_WRAP, key);
- if (newkey == NULL) {
- /* couldn't import the wrapping key, try exporting the
- * private key */
- tmpPK = pk11_loadPrivKey(key->slot, pk, NULL, PR_FALSE, PR_TRUE);
- if (tmpPK == NULL) {
- rv = SECFailure;
- goto loser;
- }
- pk = tmpPK;
- } else {
- /* free the old key and use the new key */
- PK11_FreeSymKey(key);
- key = newkey;
- }
- }
-
- /* we are extracting an encrypted privateKey structure.
- * which needs to be freed along with the buffer into which it is
- * returned. eventually, we should retrieve an encrypted key using
- * pkcs8/pkcs5.
- */
- encBufLen = 0;
- PK11_EnterSlotMonitor(pk->pkcs11Slot);
- crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session,
- &cryptoMech, key->objectID, pk->pkcs11ID, NULL,
- &encBufLen);
- PK11_ExitSlotMonitor(pk->pkcs11Slot);
- if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
- }
- epki->encryptedData.data = PORT_ArenaAlloc(arena, encBufLen);
- if (!epki->encryptedData.data) {
- rv = SECFailure;
- goto loser;
- }
- PK11_EnterSlotMonitor(pk->pkcs11Slot);
- crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session,
- &cryptoMech, key->objectID, pk->pkcs11ID,
- epki->encryptedData.data, &encBufLen);
- PK11_ExitSlotMonitor(pk->pkcs11Slot);
- epki->encryptedData.len = (unsigned int) encBufLen;
- if(crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
- }
-
- if(!epki->encryptedData.len) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECOID_CopyAlgorithmID(arena, &epki->algorithm, algid);
-
-loser:
- if(crypto_param != NULL) {
- SECITEM_ZfreeItem(crypto_param, PR_TRUE);
- crypto_param = NULL;
- }
-
- if(key != NULL) {
- PK11_FreeSymKey(key);
- }
- if (tmpPK != NULL) {
- SECKEY_DestroyPrivateKey(tmpPK);
- }
- SECOID_DestroyAlgorithmID(algid, PR_TRUE);
-
- if(rv == SECFailure) {
- if(arena != NULL) {
- PORT_FreeArena(arena, PR_TRUE);
- }
- epki = NULL;
- }
-
- return epki;
-}
-
-SECKEYEncryptedPrivateKeyInfo *
-PK11_ExportEncryptedPrivateKeyInfo(
- PK11SlotInfo *slot, /* optional, encrypt key in this slot */
- SECOidTag algTag, /* encrypt key with this algorithm */
- SECItem *pwitem, /* password for PBE encryption */
- CERTCertificate *cert, /* wrap priv key for this user cert */
- int iteration, /* interations for PBE alg */
- void *wincx) /* context for password callback ? */
-{
- SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, wincx);
- if (pk != NULL) {
- epki = PK11_ExportEncryptedPrivKeyInfo(slot, algTag, pwitem, pk,
- iteration, wincx);
- SECKEY_DestroyPrivateKey(pk);
- }
- return epki;
-}
-
-SECItem*
-PK11_DEREncodePublicKey(SECKEYPublicKey *pubk)
-{
- return SECKEY_EncodeDERSubjectPublicKeyInfo(pubk);
-}
-
-char *
-PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey)
-{
- return PK11_GetObjectNickname(privKey->pkcs11Slot,privKey->pkcs11ID);
-}
-
-char *
-PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey)
-{
- return PK11_GetObjectNickname(pubKey->pkcs11Slot,pubKey->pkcs11ID);
-}
-
-SECStatus
-PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, const char *nickname)
-{
- return PK11_SetObjectNickname(privKey->pkcs11Slot,
- privKey->pkcs11ID,nickname);
-}
-
-SECStatus
-PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, const char *nickname)
-{
- return PK11_SetObjectNickname(pubKey->pkcs11Slot,
- pubKey->pkcs11ID,nickname);
-}
-
-SECKEYPQGParams *
-PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey *privKey)
-{
- CK_ATTRIBUTE pTemplate[] = {
- { CKA_PRIME, NULL, 0 },
- { CKA_SUBPRIME, NULL, 0 },
- { CKA_BASE, NULL, 0 },
- };
- int pTemplateLen = sizeof(pTemplate)/sizeof(pTemplate[0]);
- PRArenaPool *arena = NULL;
- SECKEYPQGParams *params;
- CK_RV crv;
-
-
- arena = PORT_NewArena(2048);
- if (arena == NULL) {
- goto loser;
- }
- params=(SECKEYPQGParams *)PORT_ArenaZAlloc(arena,sizeof(SECKEYPQGParams));
- if (params == NULL) {
- goto loser;
- }
-
- crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,
- pTemplate, pTemplateLen);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
- }
-
- params->arena = arena;
- params->prime.data = pTemplate[0].pValue;
- params->prime.len = pTemplate[0].ulValueLen;
- params->subPrime.data = pTemplate[1].pValue;
- params->subPrime.len = pTemplate[1].ulValueLen;
- params->base.data = pTemplate[2].pValue;
- params->base.len = pTemplate[2].ulValueLen;
-
- return params;
-
-loser:
- if (arena != NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return NULL;
-}
-
-SECKEYPrivateKey*
-PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo *destSlot,
- SECKEYPrivateKey *privKey)
-{
- CK_RV crv;
- CK_OBJECT_HANDLE newKeyID;
-
- static const CK_BBOOL ckfalse = CK_FALSE;
- static const CK_ATTRIBUTE template[1] = {
- { CKA_TOKEN, (CK_BBOOL *)&ckfalse, sizeof ckfalse }
- };
-
- if (destSlot && destSlot != privKey->pkcs11Slot) {
- SECKEYPrivateKey *newKey =
- pk11_loadPrivKey(destSlot,
- privKey,
- NULL, /* pubKey */
- PR_FALSE, /* token */
- PR_FALSE);/* sensitive */
- if (newKey)
- return newKey;
- }
- destSlot = privKey->pkcs11Slot;
- PK11_Authenticate(destSlot, PR_TRUE, privKey->wincx);
- PK11_EnterSlotMonitor(destSlot);
- crv = PK11_GETTAB(destSlot)->C_CopyObject( destSlot->session,
- privKey->pkcs11ID,
- (CK_ATTRIBUTE *)template,
- 1, &newKeyID);
- PK11_ExitSlotMonitor(destSlot);
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
- }
-
- return PK11_MakePrivKey(destSlot, privKey->keyType, PR_TRUE /*isTemp*/,
- newKeyID, privKey->wincx);
-}
-
-SECKEYPrivateKey*
-PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void* wincx)
-{
- PK11SlotInfo* slot = privk->pkcs11Slot;
- CK_ATTRIBUTE template[1];
- CK_ATTRIBUTE *attrs = template;
- CK_BBOOL cktrue = CK_TRUE;
- CK_RV crv;
- CK_OBJECT_HANDLE newKeyID;
- CK_SESSION_HANDLE rwsession;
-
- PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++;
-
- PK11_Authenticate(slot, PR_TRUE, wincx);
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return NULL;
- }
- crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, privk->pkcs11ID,
- template, 1, &newKeyID);
- PK11_RestoreROSession(slot, rwsession);
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
- }
-
- return PK11_MakePrivKey(slot, nullKey /*KeyType*/, PR_FALSE /*isTemp*/,
- newKeyID, NULL /*wincx*/);
-}
-
-/*
- * destroy a private key if there are no matching certs.
- * this function also frees the privKey structure.
- */
-SECStatus
-PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force)
-{
- CERTCertificate *cert=PK11_GetCertFromPrivateKey(privKey);
- SECStatus rv = SECWouldBlock;
-
- if (!cert || force) {
- /* now, then it's safe for the key to go away */
- rv = PK11_DestroyTokenObject(privKey->pkcs11Slot,privKey->pkcs11ID);
- }
- if (cert) {
- CERT_DestroyCertificate(cert);
- }
- SECKEY_DestroyPrivateKey(privKey);
- return rv;
-}
-
-/*
- * destroy a private key if there are no matching certs.
- * this function also frees the privKey structure.
- */
-SECStatus
-PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey)
-{
- /* now, then it's safe for the key to go away */
- if (pubKey->pkcs11Slot == NULL) {
- return SECFailure;
- }
- PK11_DestroyTokenObject(pubKey->pkcs11Slot,pubKey->pkcs11ID);
- SECKEY_DestroyPublicKey(pubKey);
- return SECSuccess;
-}
-
-/*
- * key call back structure.
- */
-typedef struct pk11KeyCallbackStr {
- SECStatus (* callback)(SECKEYPrivateKey *,void *);
- void *callbackArg;
- void *wincx;
-} pk11KeyCallback;
-
-/*
- * callback to map Object Handles to Private Keys;
- */
-SECStatus
-pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg)
-{
- SECStatus rv = SECSuccess;
- SECKEYPrivateKey *privKey;
- pk11KeyCallback *keycb = (pk11KeyCallback *) arg;
- if (!arg) {
- return SECFailure;
- }
-
- privKey = PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,keycb->wincx);
-
- if (privKey == NULL) {
- return SECFailure;
- }
-
- if (keycb->callback) {
- rv = (*keycb->callback)(privKey,keycb->callbackArg);
- }
-
- SECKEY_DestroyPrivateKey(privKey);
- return rv;
-}
-
-/***********************************************************************
- * PK11_TraversePrivateKeysInSlot
- *
- * Traverses all the private keys on a slot.
- *
- * INPUTS
- * slot
- * The PKCS #11 slot whose private keys you want to traverse.
- * callback
- * A callback function that will be called for each key.
- * arg
- * An argument that will be passed to the callback function.
- */
-SECStatus
-PK11_TraversePrivateKeysInSlot( PK11SlotInfo *slot,
- SECStatus(* callback)(SECKEYPrivateKey*, void*), void *arg)
-{
- pk11KeyCallback perKeyCB;
- pk11TraverseSlot perObjectCB;
- CK_OBJECT_CLASS privkClass = CKO_PRIVATE_KEY;
- CK_BBOOL ckTrue = CK_TRUE;
- CK_ATTRIBUTE theTemplate[2];
- int templateSize = 2;
-
- theTemplate[0].type = CKA_CLASS;
- theTemplate[0].pValue = &privkClass;
- theTemplate[0].ulValueLen = sizeof(privkClass);
- theTemplate[1].type = CKA_TOKEN;
- theTemplate[1].pValue = &ckTrue;
- theTemplate[1].ulValueLen = sizeof(ckTrue);
-
- if(slot==NULL) {
- return SECSuccess;
- }
-
- perObjectCB.callback = pk11_DoKeys;
- perObjectCB.callbackArg = &perKeyCB;
- perObjectCB.findTemplate = theTemplate;
- perObjectCB.templateCount = templateSize;
- perKeyCB.callback = callback;
- perKeyCB.callbackArg = arg;
- perKeyCB.wincx = NULL;
-
- return PK11_TraverseSlot(slot, &perObjectCB);
-}
-
-/*
- * return the private key with the given ID
- */
-CK_OBJECT_HANDLE
-pk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot, SECItem *keyID)
-{
- CK_OBJECT_CLASS privKey = CKO_PRIVATE_KEY;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- };
- /* if you change the array, change the variable below as well */
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
- CK_ATTRIBUTE *attrs = theTemplate;
-
- PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len ); attrs++;
- PK11_SETATTRS(attrs, CKA_CLASS, &privKey, sizeof(privKey));
-
- return pk11_FindObjectByTemplate(slot,theTemplate,tsize);
-}
-
-
-SECKEYPrivateKey *
-PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, void *wincx)
-{
- CK_OBJECT_HANDLE keyHandle;
- SECKEYPrivateKey *privKey;
-
- keyHandle = pk11_FindPrivateKeyFromCertID(slot, keyID);
- if (keyHandle == CK_INVALID_HANDLE) {
- return NULL;
- }
- privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
- return privKey;
-}
-
-/*
- * Generate a CKA_ID from the relevant public key data. The CKA_ID is generated
- * from the pubKeyData by SHA1_Hashing it to produce a smaller CKA_ID (to make
- * smart cards happy.
- */
-SECItem *
-PK11_MakeIDFromPubKey(SECItem *pubKeyData)
-{
- PK11Context *context;
- SECItem *certCKA_ID;
- SECStatus rv;
-
- if (pubKeyData->len <= SHA1_LENGTH) {
- /* probably an already hashed value. The strongest known public
- * key values <= 160 bits would be less than 40 bit symetric in
- * strength. Don't hash them, just return the value. There are
- * none at the time of this writing supported by previous versions
- * of NSS, so change is binary compatible safe */
- return SECITEM_DupItem(pubKeyData);
- }
-
- context = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (context == NULL) {
- return NULL;
- }
-
- rv = PK11_DigestBegin(context);
- if (rv == SECSuccess) {
- rv = PK11_DigestOp(context,pubKeyData->data,pubKeyData->len);
- }
- if (rv != SECSuccess) {
- PK11_DestroyContext(context,PR_TRUE);
- return NULL;
- }
-
- certCKA_ID = (SECItem *)PORT_Alloc(sizeof(SECItem));
- if (certCKA_ID == NULL) {
- PK11_DestroyContext(context,PR_TRUE);
- return NULL;
- }
-
- certCKA_ID->len = SHA1_LENGTH;
- certCKA_ID->data = (unsigned char*)PORT_Alloc(certCKA_ID->len);
- if (certCKA_ID->data == NULL) {
- PORT_Free(certCKA_ID);
- PK11_DestroyContext(context,PR_TRUE);
- return NULL;
- }
-
- rv = PK11_DigestFinal(context,certCKA_ID->data,&certCKA_ID->len,
- SHA1_LENGTH);
- PK11_DestroyContext(context,PR_TRUE);
- if (rv != SECSuccess) {
- SECITEM_FreeItem(certCKA_ID,PR_TRUE);
- return NULL;
- }
-
- return certCKA_ID;
-}
-
-/* Looking for PK11_GetKeyIDFromPrivateKey?
- * Call PK11_GetLowLevelKeyIDForPrivateKey instead.
- */
-
-
-SECItem *
-PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *privKey)
-{
- return pk11_GetLowLevelKeyFromHandle(privKey->pkcs11Slot,privKey->pkcs11ID);
-}
-
-static SECStatus
-privateKeyListCallback(SECKEYPrivateKey *key, void *arg)
-{
- SECKEYPrivateKeyList *list = (SECKEYPrivateKeyList*)arg;
- return SECKEY_AddPrivateKeyToListTail(list, SECKEY_CopyPrivateKey(key));
-}
-
-SECKEYPrivateKeyList*
-PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot)
-{
- SECStatus status;
- SECKEYPrivateKeyList *keys;
-
- keys = SECKEY_NewPrivateKeyList();
- if(keys == NULL) return NULL;
-
- status = PK11_TraversePrivateKeysInSlot(slot, privateKeyListCallback,
- (void*)keys);
-
- if( status != SECSuccess ) {
- SECKEY_DestroyPrivateKeyList(keys);
- keys = NULL;
- }
-
- return keys;
-}
-
-SECKEYPublicKeyList*
-PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname)
-{
- CK_ATTRIBUTE findTemp[4];
- CK_ATTRIBUTE *attrs;
- CK_BBOOL ckTrue = CK_TRUE;
- CK_OBJECT_CLASS keyclass = CKO_PUBLIC_KEY;
- int tsize = 0;
- int objCount = 0;
- CK_OBJECT_HANDLE *key_ids;
- SECKEYPublicKeyList *keys;
- int i,len;
-
-
- attrs = findTemp;
- PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
- if (nickname) {
- len = PORT_Strlen(nickname);
- PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++;
- }
- tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
-
- key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount);
- if (key_ids == NULL) {
- return NULL;
- }
- keys = SECKEY_NewPublicKeyList();
- if (keys == NULL) {
- PORT_Free(key_ids);
- return NULL;
- }
-
- for (i=0; i < objCount ; i++) {
- SECKEYPublicKey *pubKey =
- PK11_ExtractPublicKey(slot,nullKey,key_ids[i]);
- if (pubKey) {
- SECKEY_AddPublicKeyToListTail(keys, pubKey);
- }
- }
-
- PORT_Free(key_ids);
- return keys;
-}
-
-SECKEYPrivateKeyList*
-PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
-{
- CK_ATTRIBUTE findTemp[4];
- CK_ATTRIBUTE *attrs;
- CK_BBOOL ckTrue = CK_TRUE;
- CK_OBJECT_CLASS keyclass = CKO_PRIVATE_KEY;
- int tsize = 0;
- int objCount = 0;
- CK_OBJECT_HANDLE *key_ids;
- SECKEYPrivateKeyList *keys;
- int i,len;
-
-
- attrs = findTemp;
- PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
- if (nickname) {
- len = PORT_Strlen(nickname);
- PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++;
- }
- tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
-
- key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount);
- if (key_ids == NULL) {
- return NULL;
- }
- keys = SECKEY_NewPrivateKeyList();
- if (keys == NULL) {
- PORT_Free(key_ids);
- return NULL;
- }
-
- for (i=0; i < objCount ; i++) {
- SECKEYPrivateKey *privKey =
- PK11_MakePrivKey(slot,nullKey,PR_TRUE,key_ids[i],wincx);
- SECKEY_AddPrivateKeyToListTail(keys, privKey);
- }
-
- PORT_Free(key_ids);
- return keys;
-}
-
diff --git a/security/nss/lib/pk11wrap/pk11auth.c b/security/nss/lib/pk11wrap/pk11auth.c
deleted file mode 100644
index 61097d421..000000000
--- a/security/nss/lib/pk11wrap/pk11auth.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file deals with PKCS #11 passwords and authentication.
- */
-#include "seccomon.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11t.h"
-#include "pk11func.h"
-#include "secitem.h"
-#include "secerr.h"
-
-#include "pkim.h"
-
-
-/*************************************************************
- * local static and global data
- *************************************************************/
-/*
- * This structure keeps track of status that spans all the Slots.
- * NOTE: This is a global data structure. It semantics expect thread crosstalk
- * be very careful when you see it used.
- * It's major purpose in life is to allow the user to log in one PER
- * Tranaction, even if a transaction spans threads. The problem is the user
- * may have to enter a password one just to be able to look at the
- * personalities/certificates (s)he can use. Then if Auth every is one, they
- * may have to enter the password again to use the card. See PK11_StartTransac
- * and PK11_EndTransaction.
- */
-static struct PK11GlobalStruct {
- int transaction;
- PRBool inTransaction;
- char *(PR_CALLBACK *getPass)(PK11SlotInfo *,PRBool,void *);
- PRBool (PR_CALLBACK *verifyPass)(PK11SlotInfo *,void *);
- PRBool (PR_CALLBACK *isLoggedIn)(PK11SlotInfo *,void *);
-} PK11_Global = { 1, PR_FALSE, NULL, NULL, NULL };
-
-/***********************************************************
- * Password Utilities
- ***********************************************************/
-/*
- * Check the user's password. Log into the card if it's correct.
- * succeed if the user is already logged in.
- */
-static SECStatus
-pk11_CheckPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
- char *pw, PRBool alreadyLocked, PRBool contextSpecific)
-{
- int len = 0;
- CK_RV crv;
- SECStatus rv;
- int64 currtime = PR_Now();
- PRBool mustRetry;
- int retry = 0;
-
- if (slot->protectedAuthPath) {
- len = 0;
- pw = NULL;
- } else if (pw == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- } else {
- len = PORT_Strlen(pw);
- }
-
- do {
- if (!alreadyLocked) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_Login(session,
- contextSpecific ? CKU_CONTEXT_SPECIFIC : CKU_USER,
- (unsigned char *)pw,len);
- slot->lastLoginCheck = 0;
- mustRetry = PR_FALSE;
- if (!alreadyLocked) PK11_ExitSlotMonitor(slot);
- switch (crv) {
- /* if we're already logged in, we're good to go */
- case CKR_OK:
- /* TODO If it was for CKU_CONTEXT_SPECIFIC should we do this */
- slot->authTransact = PK11_Global.transaction;
- /* Fall through */
- case CKR_USER_ALREADY_LOGGED_IN:
- slot->authTime = currtime;
- rv = SECSuccess;
- break;
- case CKR_PIN_INCORRECT:
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
- break;
- /* someone called reset while we fetched the password, try again once
- * if the token is still there. */
- case CKR_SESSION_HANDLE_INVALID:
- case CKR_SESSION_CLOSED:
- if (session != slot->session) {
- /* don't bother retrying, we were in a middle of an operation,
- * which is now lost. Just fail. */
- PORT_SetError(PK11_MapError(crv));
- rv = SECFailure;
- break;
- }
- if (retry++ == 0) {
- rv = PK11_InitToken(slot,PR_FALSE);
- if (rv == SECSuccess) {
- if (slot->session != CK_INVALID_SESSION) {
- session = slot->session; /* we should have
- * a new session now */
- mustRetry = PR_TRUE;
- } else {
- PORT_SetError(PK11_MapError(crv));
- rv = SECFailure;
- }
- }
- break;
- }
- /* Fall through */
- default:
- PORT_SetError(PK11_MapError(crv));
- rv = SECFailure; /* some failure we can't fix by retrying */
- }
- } while (mustRetry);
- return rv;
-}
-
-/*
- * Check the user's password. Logout before hand to make sure that
- * we are really checking the password.
- */
-SECStatus
-PK11_CheckUserPassword(PK11SlotInfo *slot, const char *pw)
-{
- int len = 0;
- CK_RV crv;
- SECStatus rv;
- int64 currtime = PR_Now();
-
- if (slot->protectedAuthPath) {
- len = 0;
- pw = NULL;
- } else if (pw == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- } else {
- len = PORT_Strlen(pw);
- }
-
- /*
- * If the token doesn't need a login, don't try to relogin because the
- * effect is undefined. It's not clear what it means to check a non-empty
- * password with such a token, so treat that as an error.
- */
- if (!slot->needLogin) {
- if (len == 0) {
- rv = SECSuccess;
- } else {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECFailure;
- }
- return rv;
- }
-
- /* force a logout */
- PK11_EnterSlotMonitor(slot);
- PK11_GETTAB(slot)->C_Logout(slot->session);
-
- crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER,
- (unsigned char *)pw,len);
- slot->lastLoginCheck = 0;
- PK11_ExitSlotMonitor(slot);
- switch (crv) {
- /* if we're already logged in, we're good to go */
- case CKR_OK:
- slot->authTransact = PK11_Global.transaction;
- slot->authTime = currtime;
- rv = SECSuccess;
- break;
- case CKR_PIN_INCORRECT:
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
- break;
- default:
- PORT_SetError(PK11_MapError(crv));
- rv = SECFailure; /* some failure we can't fix by retrying */
- }
- return rv;
-}
-
-SECStatus
-PK11_Logout(PK11SlotInfo *slot)
-{
- CK_RV crv;
-
- /* force a logout */
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_Logout(slot->session);
- slot->lastLoginCheck = 0;
- PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * transaction stuff is for when we test for the need to do every
- * time auth to see if we already did it for this slot/transaction
- */
-void PK11_StartAuthTransaction(void)
-{
-PK11_Global.transaction++;
-PK11_Global.inTransaction = PR_TRUE;
-}
-
-void PK11_EndAuthTransaction(void)
-{
-PK11_Global.transaction++;
-PK11_Global.inTransaction = PR_FALSE;
-}
-
-/*
- * before we do a private key op, we check to see if we
- * need to reauthenticate.
- */
-void
-PK11_HandlePasswordCheck(PK11SlotInfo *slot,void *wincx)
-{
- int askpw = slot->askpw;
- PRBool NeedAuth = PR_FALSE;
-
- if (!slot->needLogin) return;
-
- if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) {
- PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
-
- if (def_slot) {
- askpw = def_slot->askpw;
- PK11_FreeSlot(def_slot);
- }
- }
-
- /* timeouts are handled by isLoggedIn */
- if (!PK11_IsLoggedIn(slot,wincx)) {
- NeedAuth = PR_TRUE;
- } else if (askpw == -1) {
- if (!PK11_Global.inTransaction ||
- (PK11_Global.transaction != slot->authTransact)) {
- PK11_EnterSlotMonitor(slot);
- PK11_GETTAB(slot)->C_Logout(slot->session);
- slot->lastLoginCheck = 0;
- PK11_ExitSlotMonitor(slot);
- NeedAuth = PR_TRUE;
- }
- }
- if (NeedAuth) PK11_DoPassword(slot, slot->session, PR_TRUE,
- wincx, PR_FALSE, PR_FALSE);
-}
-
-void
-PK11_SlotDBUpdate(PK11SlotInfo *slot)
-{
- SECMOD_UpdateModule(slot->module);
-}
-
-/*
- * set new askpw and timeout values
- */
-void
-PK11_SetSlotPWValues(PK11SlotInfo *slot,int askpw, int timeout)
-{
- slot->askpw = askpw;
- slot->timeout = timeout;
- slot->defaultFlags |= PK11_OWN_PW_DEFAULTS;
- PK11_SlotDBUpdate(slot);
-}
-
-/*
- * Get the askpw and timeout values for this slot
- */
-void
-PK11_GetSlotPWValues(PK11SlotInfo *slot,int *askpw, int *timeout)
-{
- *askpw = slot->askpw;
- *timeout = slot->timeout;
-
- if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) {
- PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
-
- if (def_slot) {
- *askpw = def_slot->askpw;
- *timeout = def_slot->timeout;
- PK11_FreeSlot(def_slot);
- }
- }
-}
-
-/*
- * Returns true if the token is needLogin and isn't logged in.
- * This function is used to determine if authentication is needed
- * before attempting a potentially privelleged operation.
- */
-PRBool
-pk11_LoginStillRequired(PK11SlotInfo *slot, void *wincx)
-{
- return slot->needLogin && !PK11_IsLoggedIn(slot,wincx);
-}
-
-/*
- * make sure a slot is authenticated...
- * This function only does the authentication if it is needed.
- */
-SECStatus
-PK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx) {
- if (pk11_LoginStillRequired(slot,wincx)) {
- return PK11_DoPassword(slot, slot->session, loadCerts, wincx,
- PR_FALSE, PR_FALSE);
- }
- return SECSuccess;
-}
-
-/*
- * Authenticate to "unfriendly" tokens (tokens which need to be logged
- * in to find the certs.
- */
-SECStatus
-pk11_AuthenticateUnfriendly(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
-{
- SECStatus rv = SECSuccess;
- if (!PK11_IsFriendly(slot)) {
- rv = PK11_Authenticate(slot, loadCerts, wincx);
- }
- return rv;
-}
-
-
-/*
- * NOTE: this assumes that we are logged out of the card before hand
- */
-SECStatus
-PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw)
-{
- CK_SESSION_HANDLE rwsession;
- CK_RV crv;
- SECStatus rv = SECFailure;
- int len = 0;
-
- /* get a rwsession */
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return rv;
- }
-
- if (slot->protectedAuthPath) {
- len = 0;
- ssopw = NULL;
- } else if (ssopw == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- } else {
- len = PORT_Strlen(ssopw);
- }
-
- /* check the password */
- crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO,
- (unsigned char *)ssopw,len);
- slot->lastLoginCheck = 0;
- switch (crv) {
- /* if we're already logged in, we're good to go */
- case CKR_OK:
- rv = SECSuccess;
- break;
- case CKR_PIN_INCORRECT:
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECWouldBlock; /* everything else is ok, only the pin is bad */
- break;
- default:
- PORT_SetError(PK11_MapError(crv));
- rv = SECFailure; /* some failure we can't fix by retrying */
- }
- PK11_GETTAB(slot)->C_Logout(rwsession);
- slot->lastLoginCheck = 0;
-
- /* release rwsession */
- PK11_RestoreROSession(slot,rwsession);
- return rv;
-}
-
-/*
- * make sure the password conforms to your token's requirements.
- */
-SECStatus
-PK11_VerifyPW(PK11SlotInfo *slot,char *pw)
-{
- int len = PORT_Strlen(pw);
-
- if ((slot->minPassword > len) || (slot->maxPassword < len)) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * initialize a user PIN Value
- */
-SECStatus
-PK11_InitPin(PK11SlotInfo *slot, const char *ssopw, const char *userpw)
-{
- CK_SESSION_HANDLE rwsession = CK_INVALID_SESSION;
- CK_RV crv;
- SECStatus rv = SECFailure;
- int len;
- int ssolen;
-
- if (userpw == NULL) userpw = "";
- if (ssopw == NULL) ssopw = "";
-
- len = PORT_Strlen(userpw);
- ssolen = PORT_Strlen(ssopw);
-
- /* get a rwsession */
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- slot->lastLoginCheck = 0;
- return rv;
- }
-
- if (slot->protectedAuthPath) {
- len = 0;
- ssolen = 0;
- ssopw = NULL;
- userpw = NULL;
- }
-
- /* check the password */
- crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO,
- (unsigned char *)ssopw,ssolen);
- slot->lastLoginCheck = 0;
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- goto done;
- }
-
- crv = PK11_GETTAB(slot)->C_InitPIN(rwsession,(unsigned char *)userpw,len);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- } else {
- rv = SECSuccess;
- }
-
-done:
- PK11_GETTAB(slot)->C_Logout(rwsession);
- slot->lastLoginCheck = 0;
- PK11_RestoreROSession(slot,rwsession);
- if (rv == SECSuccess) {
- /* update our view of the world */
- PK11_InitToken(slot,PR_TRUE);
- if (slot->needLogin) {
- PK11_EnterSlotMonitor(slot);
- PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER,
- (unsigned char *)userpw,len);
- slot->lastLoginCheck = 0;
- PK11_ExitSlotMonitor(slot);
- }
- }
- return rv;
-}
-
-/*
- * Change an existing user password
- */
-SECStatus
-PK11_ChangePW(PK11SlotInfo *slot, const char *oldpw, const char *newpw)
-{
- CK_RV crv;
- SECStatus rv = SECFailure;
- int newLen = 0;
- int oldLen = 0;
- CK_SESSION_HANDLE rwsession;
-
- /* use NULL values to trigger the protected authentication path */
- if (!slot->protectedAuthPath) {
- if (newpw == NULL) newpw = "";
- if (oldpw == NULL) oldpw = "";
- }
- if (newpw) newLen = PORT_Strlen(newpw);
- if (oldpw) oldLen = PORT_Strlen(oldpw);
-
- /* get a rwsession */
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return rv;
- }
-
- crv = PK11_GETTAB(slot)->C_SetPIN(rwsession,
- (unsigned char *)oldpw,oldLen,(unsigned char *)newpw,newLen);
- if (crv == CKR_OK) {
- rv = SECSuccess;
- } else {
- PORT_SetError(PK11_MapError(crv));
- }
-
- PK11_RestoreROSession(slot,rwsession);
-
- /* update our view of the world */
- PK11_InitToken(slot,PR_TRUE);
- return rv;
-}
-
-static char *
-pk11_GetPassword(PK11SlotInfo *slot, PRBool retry, void * wincx)
-{
- if (PK11_Global.getPass == NULL) return NULL;
- return (*PK11_Global.getPass)(slot, retry, wincx);
-}
-
-void
-PK11_SetPasswordFunc(PK11PasswordFunc func)
-{
- PK11_Global.getPass = func;
-}
-
-void
-PK11_SetVerifyPasswordFunc(PK11VerifyPasswordFunc func)
-{
- PK11_Global.verifyPass = func;
-}
-
-void
-PK11_SetIsLoggedInFunc(PK11IsLoggedInFunc func)
-{
- PK11_Global.isLoggedIn = func;
-}
-
-
-/*
- * authenticate to a slot. This loops until we can't recover, the user
- * gives up, or we succeed. If we're already logged in and this function
- * is called we will still prompt for a password, but we will probably
- * succeed no matter what the password was (depending on the implementation
- * of the PKCS 11 module.
- */
-SECStatus
-PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
- PRBool loadCerts, void *wincx, PRBool alreadyLocked,
- PRBool contextSpecific)
-{
- SECStatus rv = SECFailure;
- char * password;
- PRBool attempt = PR_FALSE;
-
- if (PK11_NeedUserInit(slot)) {
- PORT_SetError(SEC_ERROR_IO);
- return SECFailure;
- }
-
-
- /*
- * Central server type applications which control access to multiple
- * slave applications to single crypto devices need to virtuallize the
- * login state. This is done by a callback out of PK11_IsLoggedIn and
- * here. If we are actually logged in, then we got here because the
- * higher level code told us that the particular client application may
- * still need to be logged in. If that is the case, we simply tell the
- * server code that it should now verify the clients password and tell us
- * the results.
- */
- if (PK11_IsLoggedIn(slot,NULL) &&
- (PK11_Global.verifyPass != NULL)) {
- if (!PK11_Global.verifyPass(slot,wincx)) {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- return SECFailure;
- }
- return SECSuccess;
- }
-
- /* get the password. This can drop out of the while loop
- * for the following reasons:
- * (1) the user refused to enter a password.
- * (return error to caller)
- * (2) the token user password is disabled [usually due to
- * too many failed authentication attempts].
- * (return error to caller)
- * (3) the password was successful.
- */
- while ((password = pk11_GetPassword(slot, attempt, wincx)) != NULL) {
- /* if the token has a protectedAuthPath, the application may have
- * already issued the C_Login as part of it's pk11_GetPassword call.
- * In this case the application will tell us what the results were in
- * the password value (retry or the authentication was successful) so
- * we can skip our own C_Login call (which would force the token to
- * try to login again).
- *
- * Applications that don't know about protectedAuthPath will return a
- * password, which we will ignore and trigger the token to
- * 'authenticate' itself anyway. Hopefully the blinking display on
- * the reader, or the flashing light under the thumbprint reader will
- * attract the user's attention */
- attempt = PR_TRUE;
- if (slot->protectedAuthPath) {
- /* application tried to authenticate and failed. it wants to try
- * again, continue looping */
- if (strcmp(password, PK11_PW_RETRY) == 0) {
- rv = SECWouldBlock;
- PORT_Free(password);
- continue;
- }
- /* applicaton tried to authenticate and succeeded we're done */
- if (strcmp(password, PK11_PW_AUTHENTICATED) == 0) {
- rv = SECSuccess;
- PORT_Free(password);
- break;
- }
- }
- rv = pk11_CheckPassword(slot, session, password,
- alreadyLocked, contextSpecific);
- PORT_Memset(password, 0, PORT_Strlen(password));
- PORT_Free(password);
- if (rv != SECWouldBlock) break;
- }
- if (rv == SECSuccess) {
- if (!PK11_IsFriendly(slot)) {
- nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain,
- slot->nssToken);
- }
- } else if (!attempt) PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- return rv;
-}
-
-void PK11_LogoutAll(void)
-{
- SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();
- SECMODModuleList *modList;
- SECMODModuleList *mlp = NULL;
- int i;
-
- /* NSS is not initialized, there are not tokens to log out */
- if (lock == NULL) {
- return;
- }
-
- SECMOD_GetReadLock(lock);
- modList = SECMOD_GetDefaultModuleList();
- /* find the number of entries */
- for (mlp = modList; mlp != NULL; mlp = mlp->next) {
- for (i=0; i < mlp->module->slotCount; i++) {
- PK11_Logout(mlp->module->slots[i]);
- }
- }
-
- SECMOD_ReleaseReadLock(lock);
-}
-
-int
-PK11_GetMinimumPwdLength(PK11SlotInfo *slot)
-{
- return ((int)slot->minPassword);
-}
-
-/* Does this slot have a protected pin path? */
-PRBool
-PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot)
-{
- return slot->protectedAuthPath;
-}
-
-/*
- * we can initialize the password if 1) The toke is not inited
- * (need login == true and see need UserInit) or 2) the token has
- * a NULL password. (slot->needLogin = false & need user Init = false).
- */
-PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot)
-{
- if (slot->needLogin && PK11_NeedUserInit(slot)) {
- return PR_TRUE;
- }
- if (!slot->needLogin && !PK11_NeedUserInit(slot)) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-PRBool PK11_NeedPWInit()
-{
- PK11SlotInfo *slot = PK11_GetInternalKeySlot();
- PRBool ret = PK11_NeedPWInitForSlot(slot);
-
- PK11_FreeSlot(slot);
- return ret;
-}
-
-PRBool
-pk11_InDelayPeriod(PRIntervalTime lastTime, PRIntervalTime delayTime,
- PRIntervalTime *retTime)
-{
- PRIntervalTime time;
-
- *retTime = time = PR_IntervalNow();
- return (PRBool) (lastTime) && ((time-lastTime) < delayTime);
-}
-
-/*
- * Determine if the token is logged in. We have to actually query the token,
- * because it's state can change without intervention from us.
- */
-PRBool
-PK11_IsLoggedIn(PK11SlotInfo *slot,void *wincx)
-{
- CK_SESSION_INFO sessionInfo;
- int askpw = slot->askpw;
- int timeout = slot->timeout;
- CK_RV crv;
- PRIntervalTime curTime;
- static PRIntervalTime login_delay_time = 0;
-
- if (login_delay_time == 0) {
- login_delay_time = PR_SecondsToInterval(1);
- }
-
- /* If we don't have our own password default values, use the system
- * ones */
- if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) {
- PK11SlotInfo *def_slot = PK11_GetInternalKeySlot();
-
- if (def_slot) {
- askpw = def_slot->askpw;
- timeout = def_slot->timeout;
- PK11_FreeSlot(def_slot);
- }
- }
-
- if ((wincx != NULL) && (PK11_Global.isLoggedIn != NULL) &&
- (*PK11_Global.isLoggedIn)(slot, wincx) == PR_FALSE) { return PR_FALSE; }
-
-
- /* forget the password if we've been inactive too long */
- if (askpw == 1) {
- int64 currtime = PR_Now();
- int64 result;
- int64 mult;
-
- LL_I2L(result, timeout);
- LL_I2L(mult, 60*1000*1000);
- LL_MUL(result,result,mult);
- LL_ADD(result, result, slot->authTime);
- if (LL_CMP(result, <, currtime) ) {
- PK11_EnterSlotMonitor(slot);
- PK11_GETTAB(slot)->C_Logout(slot->session);
- slot->lastLoginCheck = 0;
- PK11_ExitSlotMonitor(slot);
- } else {
- slot->authTime = currtime;
- }
- }
-
- PK11_EnterSlotMonitor(slot);
- if (pk11_InDelayPeriod(slot->lastLoginCheck,login_delay_time, &curTime)) {
- sessionInfo.state = slot->lastState;
- crv = CKR_OK;
- } else {
- crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session,&sessionInfo);
- if (crv == CKR_OK) {
- slot->lastState = sessionInfo.state;
- slot->lastLoginCheck = curTime;
- }
- }
- PK11_ExitSlotMonitor(slot);
- /* if we can't get session info, something is really wrong */
- if (crv != CKR_OK) {
- slot->session = CK_INVALID_SESSION;
- return PR_FALSE;
- }
-
- switch (sessionInfo.state) {
- case CKS_RW_PUBLIC_SESSION:
- case CKS_RO_PUBLIC_SESSION:
- default:
- break; /* fail */
- case CKS_RW_USER_FUNCTIONS:
- case CKS_RW_SO_FUNCTIONS:
- case CKS_RO_USER_FUNCTIONS:
- return PR_TRUE;
- }
- return PR_FALSE;
-}
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
deleted file mode 100644
index 39168b96c..000000000
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ /dev/null
@@ -1,2684 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file manages PKCS #11 instances of certificates.
- */
-
-#include "secport.h"
-#include "seccomon.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11.h"
-#include "pk11func.h"
-#include "cert.h"
-#include "certi.h"
-#include "secitem.h"
-#include "key.h"
-#include "secoid.h"
-#include "pkcs7t.h"
-#include "cmsreclist.h"
-
-#include "certdb.h"
-#include "secerr.h"
-#include "sslerr.h"
-
-#include "pki3hack.h"
-#include "dev3hack.h"
-
-#include "devm.h"
-#include "nsspki.h"
-#include "pki.h"
-#include "pkim.h"
-#include "pkitm.h"
-#include "pkistore.h" /* to remove temp cert */
-#include "devt.h"
-
-extern const NSSError NSS_ERROR_NOT_FOUND;
-extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
-
-struct nss3_cert_cbstr {
- SECStatus(* callback)(CERTCertificate*, void *);
- nssList *cached;
- void *arg;
-};
-
-/* Translate from NSSCertificate to CERTCertificate, then pass the latter
- * to a callback.
- */
-static PRStatus convert_cert(NSSCertificate *c, void *arg)
-{
- CERTCertificate *nss3cert;
- SECStatus secrv;
- struct nss3_cert_cbstr *nss3cb = (struct nss3_cert_cbstr *)arg;
- /* 'c' is not adopted. caller will free it */
- nss3cert = STAN_GetCERTCertificate(c);
- if (!nss3cert) return PR_FAILURE;
- secrv = (*nss3cb->callback)(nss3cert, nss3cb->arg);
- return (secrv) ? PR_FAILURE : PR_SUCCESS;
-}
-
-/*
- * build a cert nickname based on the token name and the label of the
- * certificate If the label in NULL, build a label based on the ID.
- */
-static int toHex(int x) { return (x < 10) ? (x+'0') : (x+'a'-10); }
-#define MAX_CERT_ID 4
-#define DEFAULT_STRING "Cert ID "
-static char *
-pk11_buildNickname(PK11SlotInfo *slot,CK_ATTRIBUTE *cert_label,
- CK_ATTRIBUTE *key_label, CK_ATTRIBUTE *cert_id)
-{
- int prefixLen = PORT_Strlen(slot->token_name);
- int suffixLen = 0;
- char *suffix = NULL;
- char buildNew[sizeof(DEFAULT_STRING)+MAX_CERT_ID*2];
- char *next,*nickname;
-
- if (cert_label && (cert_label->ulValueLen)) {
- suffixLen = cert_label->ulValueLen;
- suffix = (char*)cert_label->pValue;
- } else if (key_label && (key_label->ulValueLen)) {
- suffixLen = key_label->ulValueLen;
- suffix = (char*)key_label->pValue;
- } else if (cert_id && cert_id->ulValueLen > 0) {
- int i,first = cert_id->ulValueLen - MAX_CERT_ID;
- int offset = sizeof(DEFAULT_STRING);
- char *idValue = (char *)cert_id->pValue;
-
- PORT_Memcpy(buildNew,DEFAULT_STRING,sizeof(DEFAULT_STRING)-1);
- next = buildNew + offset;
- if (first < 0) first = 0;
- for (i=first; i < (int) cert_id->ulValueLen; i++) {
- *next++ = toHex((idValue[i] >> 4) & 0xf);
- *next++ = toHex(idValue[i] & 0xf);
- }
- *next++ = 0;
- suffix = buildNew;
- suffixLen = PORT_Strlen(buildNew);
- } else {
- PORT_SetError( SEC_ERROR_LIBRARY_FAILURE );
- return NULL;
- }
-
- /* if is internal key slot, add code to skip the prefix!! */
- next = nickname = (char *)PORT_Alloc(prefixLen+1+suffixLen+1);
- if (nickname == NULL) return NULL;
-
- PORT_Memcpy(next,slot->token_name,prefixLen);
- next += prefixLen;
- *next++ = ':';
- PORT_Memcpy(next,suffix,suffixLen);
- next += suffixLen;
- *next++ = 0;
- return nickname;
-}
-
-PRBool
-PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
- CK_OBJECT_HANDLE certID)
-{
- CK_OBJECT_CLASS theClass;
-
- if (slot == NULL) return PR_FALSE;
- if (cert == NULL) return PR_FALSE;
-
- theClass = CKO_PRIVATE_KEY;
- if (pk11_LoginStillRequired(slot,NULL)) {
- theClass = CKO_PUBLIC_KEY;
- }
- if (PK11_MatchItem(slot, certID , theClass) != CK_INVALID_HANDLE) {
- return PR_TRUE;
- }
-
- if (theClass == CKO_PUBLIC_KEY) {
- SECKEYPublicKey *pubKey= CERT_ExtractPublicKey(cert);
- CK_ATTRIBUTE theTemplate;
-
- if (pubKey == NULL) {
- return PR_FALSE;
- }
-
- PK11_SETATTRS(&theTemplate,0,NULL,0);
- switch (pubKey->keyType) {
- case rsaKey:
- PK11_SETATTRS(&theTemplate,CKA_MODULUS, pubKey->u.rsa.modulus.data,
- pubKey->u.rsa.modulus.len);
- break;
- case dsaKey:
- PK11_SETATTRS(&theTemplate,CKA_VALUE, pubKey->u.dsa.publicValue.data,
- pubKey->u.dsa.publicValue.len);
- break;
- case dhKey:
- PK11_SETATTRS(&theTemplate,CKA_VALUE, pubKey->u.dh.publicValue.data,
- pubKey->u.dh.publicValue.len);
- break;
- case ecKey:
- PK11_SETATTRS(&theTemplate,CKA_EC_POINT,
- pubKey->u.ec.publicValue.data,
- pubKey->u.ec.publicValue.len);
- break;
- case keaKey:
- case fortezzaKey:
- case nullKey:
- /* fall through and return false */
- break;
- }
-
- if (theTemplate.ulValueLen == 0) {
- SECKEY_DestroyPublicKey(pubKey);
- return PR_FALSE;
- }
- pk11_SignedToUnsigned(&theTemplate);
- if (pk11_FindObjectByTemplate(slot,&theTemplate,1) != CK_INVALID_HANDLE) {
- SECKEY_DestroyPublicKey(pubKey);
- return PR_TRUE;
- }
- SECKEY_DestroyPublicKey(pubKey);
- }
- return PR_FALSE;
-}
-
-/*
- * Check out if a cert has ID of zero. This is a magic ID that tells
- * NSS that this cert may be an automagically trusted cert.
- * The Cert has to be self signed as well. That check is done elsewhere.
- *
- */
-PRBool
-pk11_isID0(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID)
-{
- CK_ATTRIBUTE keyID = {CKA_ID, NULL, 0};
- PRBool isZero = PR_FALSE;
- int i;
- CK_RV crv;
-
-
- crv = PK11_GetAttributes(NULL,slot,certID,&keyID,1);
- if (crv != CKR_OK) {
- return isZero;
- }
-
- if (keyID.ulValueLen != 0) {
- char *value = (char *)keyID.pValue;
- isZero = PR_TRUE; /* ID exists, may be zero */
- for (i=0; i < (int) keyID.ulValueLen; i++) {
- if (value[i] != 0) {
- isZero = PR_FALSE; /* nope */
- break;
- }
- }
- }
- PORT_Free(keyID.pValue);
- return isZero;
-
-}
-
-/*
- * Create an NSSCertificate from a slot/certID pair, return it as a
- * CERTCertificate. Optionally, output the nickname string.
- */
-static CERTCertificate *
-pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID,
- CK_ATTRIBUTE *privateLabel, char **nickptr)
-{
- NSSCertificate *c;
- nssCryptokiObject *co = NULL;
- nssPKIObject *pkio;
- NSSToken *token;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- PRStatus status;
-
- /* Get the cryptoki object from the handle */
- token = PK11Slot_GetNSSToken(slot);
- if (token->defaultSession) {
- co = nssCryptokiObject_Create(token, token->defaultSession, certID);
- } else {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- }
- if (!co) {
- return NULL;
- }
-
- /* Create a PKI object from the cryptoki instance */
- pkio = nssPKIObject_Create(NULL, co, td, NULL, nssPKIMonitor);
- if (!pkio) {
- nssCryptokiObject_Destroy(co);
- return NULL;
- }
-
- /* Create a certificate */
- c = nssCertificate_Create(pkio);
- if (!c) {
- nssPKIObject_Destroy(pkio);
- return NULL;
- }
-
- /* Build and output a nickname, if desired.
- * This must be done before calling nssTrustDomain_AddCertsToCache
- * because that function may destroy c, pkio and co!
- */
- if ((nickptr) && (co->label)) {
- CK_ATTRIBUTE label, id;
-
- label.type = CKA_LABEL;
- label.pValue = co->label;
- label.ulValueLen = PORT_Strlen(co->label);
-
- id.type = CKA_ID;
- id.pValue = c->id.data;
- id.ulValueLen = c->id.size;
-
- *nickptr = pk11_buildNickname(slot, &label, privateLabel, &id);
- }
-
- /* This function may destroy the cert in "c" and all its subordinate
- * structures, and replace the value in "c" with the address of a
- * different NSSCertificate that it found in the cache.
- * Presumably, the nickname which we just output above remains valid. :)
- */
- status = nssTrustDomain_AddCertsToCache(td, &c, 1);
- return STAN_GetCERTCertificateOrRelease(c);
-}
-
-/*
- * Build an CERTCertificate structure from a PKCS#11 object ID.... certID
- * Must be a CertObject. This code does not explicitly checks that.
- */
-CERTCertificate *
-PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
- CK_ATTRIBUTE *privateLabel)
-{
- char * nickname = NULL;
- CERTCertificate *cert = NULL;
- CERTCertTrust *trust;
- PRBool isFortezzaRootCA = PR_FALSE;
- PRBool swapNickname = PR_FALSE;
-
- cert = pk11_fastCert(slot,certID,privateLabel, &nickname);
- if (cert == NULL)
- goto loser;
-
- if (nickname) {
- if (cert->nickname != NULL) {
- cert->dbnickname = cert->nickname;
- }
- cert->nickname = PORT_ArenaStrdup(cert->arena,nickname);
- PORT_Free(nickname);
- nickname = NULL;
- swapNickname = PR_TRUE;
- }
-
- /* remember where this cert came from.... If we have just looked
- * it up from the database and it already has a slot, don't add a new
- * one. */
- if (cert->slot == NULL) {
- cert->slot = PK11_ReferenceSlot(slot);
- cert->pkcs11ID = certID;
- cert->ownSlot = PR_TRUE;
- cert->series = slot->series;
- }
-
- trust = (CERTCertTrust*)PORT_ArenaAlloc(cert->arena, sizeof(CERTCertTrust));
- if (trust == NULL)
- goto loser;
- PORT_Memset(trust,0, sizeof(CERTCertTrust));
-
- if(! pk11_HandleTrustObject(slot, cert, trust) ) {
- unsigned int type;
-
- /* build some cert trust flags */
- if (CERT_IsCACert(cert, &type)) {
- unsigned int trustflags = CERTDB_VALID_CA;
-
- /* Allow PKCS #11 modules to give us trusted CA's. We only accept
- * valid CA's which are self-signed here. They must have an object
- * ID of '0'. */
- if (pk11_isID0(slot,certID) &&
- cert->isRoot) {
- trustflags |= CERTDB_TRUSTED_CA;
- /* is the slot a fortezza card? allow the user or
- * admin to turn on objectSigning, but don't turn
- * full trust on explicitly */
- if (PK11_DoesMechanism(slot,CKM_KEA_KEY_DERIVE)) {
- trust->objectSigningFlags |= CERTDB_VALID_CA;
- isFortezzaRootCA = PR_TRUE;
- }
- }
- if ((type & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA) {
- trust->sslFlags |= trustflags;
- }
- if ((type & NS_CERT_TYPE_EMAIL_CA) == NS_CERT_TYPE_EMAIL_CA) {
- trust->emailFlags |= trustflags;
- }
- if ((type & NS_CERT_TYPE_OBJECT_SIGNING_CA)
- == NS_CERT_TYPE_OBJECT_SIGNING_CA) {
- trust->objectSigningFlags |= trustflags;
- }
- }
- }
-
- if (PK11_IsUserCert(slot,cert,certID)) {
- trust->sslFlags |= CERTDB_USER;
- trust->emailFlags |= CERTDB_USER;
- /* trust->objectSigningFlags |= CERTDB_USER; */
- }
- CERT_LockCertTrust(cert);
- cert->trust = trust;
- CERT_UnlockCertTrust(cert);
-
- return cert;
-
-loser:
- if (nickname)
- PORT_Free(nickname);
- if (cert)
- CERT_DestroyCertificate(cert);
- return NULL;
-}
-
-
-/*
- * Build get a certificate from a private key
- */
-CERTCertificate *
-PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey)
-{
- PK11SlotInfo *slot = privKey->pkcs11Slot;
- CK_OBJECT_HANDLE handle = privKey->pkcs11ID;
- CK_OBJECT_HANDLE certID =
- PK11_MatchItem(slot,handle,CKO_CERTIFICATE);
- CERTCertificate *cert;
-
- if (certID == CK_INVALID_HANDLE) {
- PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
- return NULL;
- }
- cert = PK11_MakeCertFromHandle(slot,certID,NULL);
- return (cert);
-
-}
-
-/*
- * delete a cert and it's private key (if no other certs are pointing to the
- * private key.
- */
-SECStatus
-PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx)
-{
- SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert,wincx);
- CK_OBJECT_HANDLE pubKey;
- PK11SlotInfo *slot = NULL;
-
- pubKey = pk11_FindPubKeyByAnyCert(cert, &slot, wincx);
- if (privKey) {
- /* For 3.4, utilize the generic cert delete function */
- SEC_DeletePermCertificate(cert);
- PK11_DeleteTokenPrivateKey(privKey, PR_FALSE);
- }
- if ((pubKey != CK_INVALID_HANDLE) && (slot != NULL)) {
- PK11_DestroyTokenObject(slot,pubKey);
- PK11_FreeSlot(slot);
- }
- return SECSuccess;
-}
-
-/*
- * cert callback structure
- */
-typedef struct pk11DoCertCallbackStr {
- SECStatus(* callback)(PK11SlotInfo *slot, CERTCertificate*, void *);
- SECStatus(* noslotcallback)(CERTCertificate*, void *);
- SECStatus(* itemcallback)(CERTCertificate*, SECItem *, void *);
- void *callbackArg;
-} pk11DoCertCallback;
-
-
-typedef struct pk11CertCallbackStr {
- SECStatus(* callback)(CERTCertificate*,SECItem *,void *);
- void *callbackArg;
-} pk11CertCallback;
-
-struct fake_der_cb_argstr
-{
- SECStatus(* callback)(CERTCertificate*, SECItem *, void *);
- void *arg;
-};
-
-static SECStatus fake_der_cb(CERTCertificate *c, void *a)
-{
- struct fake_der_cb_argstr *fda = (struct fake_der_cb_argstr *)a;
- return (*fda->callback)(c, &c->derCert, fda->arg);
-}
-
-/*
- * Extract all the certs on a card from a slot.
- */
-SECStatus
-PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
- void *arg, void *wincx)
-{
- NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
- struct fake_der_cb_argstr fda;
- struct nss3_cert_cbstr pk11cb;
-
- /* authenticate to the tokens first */
- (void) pk11_TraverseAllSlots( NULL, NULL, PR_TRUE, wincx);
-
- fda.callback = callback;
- fda.arg = arg;
- pk11cb.callback = fake_der_cb;
- pk11cb.arg = &fda;
- NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
- return SECSuccess;
-}
-
-static void
-transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
- nssPKIObjectCollection *collection)
-{
- NSSCertificate **certs;
- PRUint32 i, count;
- NSSToken **tokens, **tp;
- count = nssList_Count(certList);
- if (count == 0) {
- return;
- }
- certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
- if (!certs) {
- return;
- }
- nssList_GetArray(certList, (void **)certs, count);
- for (i=0; i<count; i++) {
- tokens = nssPKIObject_GetTokens(&certs[i]->object, NULL);
- if (tokens) {
- for (tp = tokens; *tp; tp++) {
- if (*tp == token) {
- nssPKIObjectCollection_AddObject(collection,
- (nssPKIObject *)certs[i]);
- }
- }
- nssTokenArray_Destroy(tokens);
- }
- CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(certs[i]));
- }
- nss_ZFreeIf(certs);
-}
-
-CERTCertificate *
-PK11_FindCertFromNickname(const char *nickname, void *wincx)
-{
- PRStatus status;
- CERTCertificate *rvCert = NULL;
- NSSCertificate *cert = NULL;
- NSSCertificate **certs = NULL;
- static const NSSUsage usage = {PR_TRUE /* ... */ };
- NSSToken *token;
- NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
- PK11SlotInfo *slot = NULL;
- SECStatus rv;
- char *nickCopy;
- char *delimit = NULL;
- char *tokenName;
-
- nickCopy = PORT_Strdup(nickname);
- if (!nickCopy) {
- /* error code is set */
- return NULL;
- }
- if ((delimit = PORT_Strchr(nickCopy,':')) != NULL) {
- tokenName = nickCopy;
- nickname = delimit + 1;
- *delimit = '\0';
- /* find token by name */
- token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
- if (token) {
- slot = PK11_ReferenceSlot(token->pk11slot);
- } else {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- }
- *delimit = ':';
- } else {
- slot = PK11_GetInternalKeySlot();
- token = PK11Slot_GetNSSToken(slot);
- }
- if (token) {
- nssList *certList;
- nssCryptokiObject **instances;
- nssPKIObjectCollection *collection;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- if (!PK11_IsPresent(slot)) {
- goto loser;
- }
- rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- goto loser;
- }
- collection = nssCertificateCollection_Create(defaultTD, NULL);
- if (!collection) {
- goto loser;
- }
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList) {
- nssPKIObjectCollection_Destroy(collection);
- goto loser;
- }
- (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
- nickname,
- certList);
- transfer_token_certs_to_collection(certList, token, collection);
- instances = nssToken_FindCertificatesByNickname(token,
- NULL,
- nickname,
- tokenOnly,
- 0,
- &status);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
- /* if it wasn't found, repeat the process for email address */
- if (nssPKIObjectCollection_Count(collection) == 0 &&
- PORT_Strchr(nickname, '@') != NULL)
- {
- char* lowercaseName = CERT_FixupEmailAddr(nickname);
- if (lowercaseName) {
- (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
- lowercaseName,
- certList);
- transfer_token_certs_to_collection(certList, token, collection);
- instances = nssToken_FindCertificatesByEmail(token,
- NULL,
- lowercaseName,
- tokenOnly,
- 0,
- &status);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
- PORT_Free(lowercaseName);
- }
- }
- certs = nssPKIObjectCollection_GetCertificates(collection,
- NULL, 0, NULL);
- nssPKIObjectCollection_Destroy(collection);
- if (certs) {
- cert = nssCertificateArray_FindBestCertificate(certs, NULL,
- &usage, NULL);
- if (cert) {
- rvCert = STAN_GetCERTCertificateOrRelease(cert);
- }
- nssCertificateArray_Destroy(certs);
- }
- nssList_Destroy(certList);
- }
- if (slot) {
- PK11_FreeSlot(slot);
- }
- if (nickCopy) PORT_Free(nickCopy);
- return rvCert;
-loser:
- if (slot) {
- PK11_FreeSlot(slot);
- }
- if (nickCopy) PORT_Free(nickCopy);
- return NULL;
-}
-
-/* Traverse slots callback */
-typedef struct FindCertsEmailArgStr {
- char *email;
- CERTCertList *certList;
-} FindCertsEmailArg;
-
-SECStatus
-FindCertsEmailCallback(CERTCertificate *cert, SECItem *item, void *arg)
-{
- FindCertsEmailArg *cbparam = (FindCertsEmailArg *) arg;
- const char *cert_email = CERT_GetFirstEmailAddress(cert);
- PRBool found = PR_FALSE;
-
- /* Email address present in certificate? */
- if (cert_email == NULL){
- return SECSuccess;
- }
-
- /* Parameter correctly set? */
- if (cbparam->email == NULL) {
- return SECFailure;
- }
-
- /* Loop over all email addresses */
- do {
- if (!strcmp(cert_email, cbparam->email)) {
- /* found one matching email address */
- PRTime now = PR_Now();
- found = PR_TRUE;
- CERT_AddCertToListSorted(cbparam->certList,
- CERT_DupCertificate(cert),
- CERT_SortCBValidity, &now);
- }
- cert_email = CERT_GetNextEmailAddress(cert, cert_email);
- } while (cert_email && !found);
-
- return SECSuccess;
-}
-
-/* Find all certificates with matching email address */
-CERTCertList *
-PK11_FindCertsFromEmailAddress(const char *email, void *wincx)
-{
- FindCertsEmailArg cbparam;
- SECStatus rv;
-
- cbparam.certList = CERT_NewCertList();
- if (cbparam.certList == NULL) {
- return NULL;
- }
-
- cbparam.email = CERT_FixupEmailAddr(email);
- if (cbparam.email == NULL) {
- CERT_DestroyCertList(cbparam.certList);
- return NULL;
- }
-
- rv = PK11_TraverseSlotCerts(FindCertsEmailCallback, &cbparam, NULL);
- if (rv != SECSuccess) {
- CERT_DestroyCertList(cbparam.certList);
- PORT_Free(cbparam.email);
- return NULL;
- }
-
- /* empty list? */
- if (CERT_LIST_HEAD(cbparam.certList) == NULL ||
- CERT_LIST_END(CERT_LIST_HEAD(cbparam.certList), cbparam.certList)) {
- CERT_DestroyCertList(cbparam.certList);
- cbparam.certList = NULL;
- }
-
- PORT_Free(cbparam.email);
- return cbparam.certList;
-}
-
-
-CERTCertList *
-PK11_FindCertsFromNickname(const char *nickname, void *wincx)
-{
- char *nickCopy;
- char *delimit = NULL;
- char *tokenName;
- int i;
- CERTCertList *certList = NULL;
- nssPKIObjectCollection *collection = NULL;
- NSSCertificate **foundCerts = NULL;
- NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
- NSSCertificate *c;
- NSSToken *token;
- PK11SlotInfo *slot;
- SECStatus rv;
-
- nickCopy = PORT_Strdup(nickname);
- if (!nickCopy) {
- /* error code is set */
- return NULL;
- }
- if ((delimit = PORT_Strchr(nickCopy,':')) != NULL) {
- tokenName = nickCopy;
- nickname = delimit + 1;
- *delimit = '\0';
- /* find token by name */
- token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
- if (token) {
- slot = PK11_ReferenceSlot(token->pk11slot);
- } else {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- slot = NULL;
- }
- *delimit = ':';
- } else {
- slot = PK11_GetInternalKeySlot();
- token = PK11Slot_GetNSSToken(slot);
- }
- if (token) {
- PRStatus status;
- nssList *nameList;
- nssCryptokiObject **instances;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- PK11_FreeSlot(slot);
- if (nickCopy) PORT_Free(nickCopy);
- return NULL;
- }
- collection = nssCertificateCollection_Create(defaultTD, NULL);
- if (!collection) {
- PK11_FreeSlot(slot);
- if (nickCopy) PORT_Free(nickCopy);
- return NULL;
- }
- nameList = nssList_Create(NULL, PR_FALSE);
- if (!nameList) {
- PK11_FreeSlot(slot);
- if (nickCopy) PORT_Free(nickCopy);
- return NULL;
- }
- (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
- nickname,
- nameList);
- transfer_token_certs_to_collection(nameList, token, collection);
- instances = nssToken_FindCertificatesByNickname(token,
- NULL,
- nickname,
- tokenOnly,
- 0,
- &status);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
-
- /* if it wasn't found, repeat the process for email address */
- if (nssPKIObjectCollection_Count(collection) == 0 &&
- PORT_Strchr(nickname, '@') != NULL)
- {
- char* lowercaseName = CERT_FixupEmailAddr(nickname);
- if (lowercaseName) {
- (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
- lowercaseName,
- nameList);
- transfer_token_certs_to_collection(nameList, token, collection);
- instances = nssToken_FindCertificatesByEmail(token,
- NULL,
- lowercaseName,
- tokenOnly,
- 0,
- &status);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
- PORT_Free(lowercaseName);
- }
- }
-
- nssList_Destroy(nameList);
- foundCerts = nssPKIObjectCollection_GetCertificates(collection,
- NULL, 0, NULL);
- nssPKIObjectCollection_Destroy(collection);
- }
- if (slot) {
- PK11_FreeSlot(slot);
- }
- if (nickCopy) PORT_Free(nickCopy);
- if (foundCerts) {
- PRTime now = PR_Now();
- certList = CERT_NewCertList();
- for (i=0, c = *foundCerts; c; c = foundCerts[++i]) {
- if (certList) {
- CERTCertificate *certCert = STAN_GetCERTCertificateOrRelease(c);
- /* c may be invalid after this, don't reference it */
- if (certCert) {
- /* CERT_AddCertToListSorted adopts certCert */
- CERT_AddCertToListSorted(certList, certCert,
- CERT_SortCBValidity, &now);
- }
- } else {
- nssCertificate_Destroy(c);
- }
- }
- if (certList && CERT_LIST_HEAD(certList) == NULL) {
- CERT_DestroyCertList(certList);
- certList = NULL;
- }
- /* all the certs have been adopted or freed, free the raw array */
- nss_ZFreeIf(foundCerts);
- }
- return certList;
-}
-
-/*
- * extract a key ID for a certificate...
- * NOTE: We call this function from PKCS11.c If we ever use
- * pkcs11 to extract the public key (we currently do not), this will break.
- */
-SECItem *
-PK11_GetPubIndexKeyID(CERTCertificate *cert)
-{
- SECKEYPublicKey *pubk;
- SECItem *newItem = NULL;
-
- pubk = CERT_ExtractPublicKey(cert);
- if (pubk == NULL) return NULL;
-
- switch (pubk->keyType) {
- case rsaKey:
- newItem = SECITEM_DupItem(&pubk->u.rsa.modulus);
- break;
- case dsaKey:
- newItem = SECITEM_DupItem(&pubk->u.dsa.publicValue);
- break;
- case dhKey:
- newItem = SECITEM_DupItem(&pubk->u.dh.publicValue);
- break;
- case ecKey:
- newItem = SECITEM_DupItem(&pubk->u.ec.publicValue);
- break;
- case fortezzaKey:
- default:
- newItem = NULL; /* Fortezza Fix later... */
- }
- SECKEY_DestroyPublicKey(pubk);
- /* make hash of it */
- return newItem;
-}
-
-/*
- * generate a CKA_ID from a certificate.
- */
-SECItem *
-pk11_mkcertKeyID(CERTCertificate *cert)
-{
- SECItem *pubKeyData = PK11_GetPubIndexKeyID(cert) ;
- SECItem *certCKA_ID;
-
- if (pubKeyData == NULL) return NULL;
-
- certCKA_ID = PK11_MakeIDFromPubKey(pubKeyData);
- SECITEM_FreeItem(pubKeyData,PR_TRUE);
- return certCKA_ID;
-}
-
-/*
- * Write the cert into the token.
- */
-SECStatus
-PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
- CK_OBJECT_HANDLE key, const char *nickname,
- PRBool includeTrust)
-{
- PRStatus status;
- NSSCertificate *c;
- nssCryptokiObject *keyobj, *certobj;
- NSSToken *token = PK11Slot_GetNSSToken(slot);
- SECItem *keyID = pk11_mkcertKeyID(cert);
- char *emailAddr = NULL;
- nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
- nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
-
- if (keyID == NULL) {
- goto loser; /* error code should be set already */
- }
- if (!token) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- goto loser;
- }
-
- if (PK11_IsInternal(slot) && cert->emailAddr && cert->emailAddr[0]) {
- emailAddr = cert->emailAddr;
- }
-
- /* need to get the cert as a stan cert */
- if (cert->nssCertificate) {
- c = cert->nssCertificate;
- } else {
- c = STAN_GetNSSCertificate(cert);
- if (c == NULL) {
- goto loser;
- }
- }
-
- /* set the id for the cert */
- nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data);
- if (!c->id.data) {
- goto loser;
- }
-
- if (key != CK_INVALID_HANDLE) {
- /* create an object for the key, ... */
- keyobj = nss_ZNEW(NULL, nssCryptokiObject);
- if (!keyobj) {
- goto loser;
- }
- keyobj->token = nssToken_AddRef(token);
- keyobj->handle = key;
- keyobj->isTokenObject = PR_TRUE;
-
- /* ... in order to set matching attributes for the key */
- status = nssCryptokiPrivateKey_SetCertificate(keyobj, NULL, nickname,
- &c->id, &c->subject);
- nssCryptokiObject_Destroy(keyobj);
- if (status != PR_SUCCESS) {
- goto loser;
- }
- }
-
- /* do the token import */
- certobj = nssToken_ImportCertificate(token, NULL,
- NSSCertificateType_PKIX,
- &c->id,
- nickname,
- &c->encoding,
- &c->issuer,
- &c->subject,
- &c->serial,
- emailAddr,
- PR_TRUE);
- if (!certobj) {
- if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) {
- PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
- SECITEM_FreeItem(keyID,PR_TRUE);
- return SECFailure;
- }
- goto loser;
- }
-
- if (c->object.cryptoContext) {
- /* Delete the temp instance */
- NSSCryptoContext *cc = c->object.cryptoContext;
- nssCertificateStore_Lock(cc->certStore, &lockTrace);
- nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
- nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace);
- c->object.cryptoContext = NULL;
- cert->istemp = PR_FALSE;
- cert->isperm = PR_TRUE;
- }
-
- /* add the new instance to the cert, force an update of the
- * CERTCertificate, and finish
- */
- nssPKIObject_AddInstance(&c->object, certobj);
- nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
- (void)STAN_ForceCERTCertificateUpdate(c);
- SECITEM_FreeItem(keyID,PR_TRUE);
- return SECSuccess;
-loser:
- CERT_MapStanError();
- SECITEM_FreeItem(keyID,PR_TRUE);
- if (PORT_GetError() != SEC_ERROR_TOKEN_NOT_LOGGED_IN) {
- PORT_SetError(SEC_ERROR_ADDING_CERT);
- }
- return SECFailure;
-}
-
-SECStatus
-PK11_ImportDERCert(PK11SlotInfo *slot, SECItem *derCert,
- CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust)
-{
- CERTCertificate *cert;
- SECStatus rv;
-
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- derCert, NULL, PR_FALSE, PR_TRUE);
- if (cert == NULL) return SECFailure;
-
- rv = PK11_ImportCert(slot, cert, key, nickname, includeTrust);
- CERT_DestroyCertificate (cert);
- return rv;
-}
-
-/*
- * get a certificate handle, look at the cached handle first..
- */
-CK_OBJECT_HANDLE
-pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert,
- CK_ATTRIBUTE *theTemplate,int tsize)
-{
- CK_OBJECT_HANDLE certh;
-
- if (cert->slot == slot) {
- certh = cert->pkcs11ID;
- if ((certh == CK_INVALID_HANDLE) ||
- (cert->series != slot->series)) {
- certh = pk11_FindObjectByTemplate(slot,theTemplate,tsize);
- cert->pkcs11ID = certh;
- cert->series = slot->series;
- }
- } else {
- certh = pk11_FindObjectByTemplate(slot,theTemplate,tsize);
- }
- return certh;
-}
-
-/*
- * return the private key From a given Cert
- */
-SECKEYPrivateKey *
-PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert,
- void *wincx)
-{
- int err;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_VALUE, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- /* if you change the array, change the variable below as well */
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
- CK_OBJECT_HANDLE certh;
- CK_OBJECT_HANDLE keyh;
- CK_ATTRIBUTE *attrs = theTemplate;
- PRBool needLogin;
- SECStatus rv;
-
- PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data,
- cert->derCert.len); attrs++;
- PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
-
- /*
- * issue the find
- */
- rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- return NULL;
- }
-
- certh = pk11_getcerthandle(slot,cert,theTemplate,tsize);
- if (certh == CK_INVALID_HANDLE) {
- return NULL;
- }
- /*
- * prevent a login race condition. If slot is logged in between
- * our call to pk11_LoginStillRequired and the
- * PK11_MatchItem. The matchItem call will either succeed, or
- * we will call it one more time after calling PK11_Authenticate
- * (which is a noop on an authenticated token).
- */
- needLogin = pk11_LoginStillRequired(slot,wincx);
- keyh = PK11_MatchItem(slot,certh,CKO_PRIVATE_KEY);
- if ((keyh == CK_INVALID_HANDLE) && needLogin &&
- (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) ||
- SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) {
- /* try it again authenticated */
- rv = PK11_Authenticate(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- return NULL;
- }
- keyh = PK11_MatchItem(slot,certh,CKO_PRIVATE_KEY);
- }
- if (keyh == CK_INVALID_HANDLE) {
- return NULL;
- }
- return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyh, wincx);
-}
-
-/*
- * import a cert for a private key we have already generated. Set the label
- * on both to be the nickname. This is for the Key Gen, orphaned key case.
- */
-PK11SlotInfo *
-PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr,
- void *wincx)
-{
- PK11SlotList *list;
- PK11SlotListElement *le;
- SECItem *keyID;
- CK_OBJECT_HANDLE key;
- PK11SlotInfo *slot = NULL;
- SECStatus rv;
- int err;
-
- keyID = pk11_mkcertKeyID(cert);
- /* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
- if ((keyID == NULL) || (list == NULL)) {
- if (keyID) SECITEM_FreeItem(keyID,PR_TRUE);
- if (list) PK11_FreeSlotList(list);
- return NULL;
- }
-
- /* Look for the slot that holds the Key */
- for (le = list->head ; le; le = le->next) {
- /*
- * prevent a login race condition. If le->slot is logged in between
- * our call to pk11_LoginStillRequired and the
- * pk11_FindPrivateKeyFromCertID, the find will either succeed, or
- * we will call it one more time after calling PK11_Authenticate
- * (which is a noop on an authenticated token).
- */
- PRBool needLogin = pk11_LoginStillRequired(le->slot,wincx);
- key = pk11_FindPrivateKeyFromCertID(le->slot,keyID);
- if ((key == CK_INVALID_HANDLE) && needLogin &&
- (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) ||
- SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) {
- /* authenticate and try again */
- rv = PK11_Authenticate(le->slot, PR_TRUE, wincx);
- if (rv != SECSuccess) continue;
- key = pk11_FindPrivateKeyFromCertID(le->slot,keyID);
- }
- if (key != CK_INVALID_HANDLE) {
- slot = PK11_ReferenceSlot(le->slot);
- if (keyPtr) *keyPtr = key;
- break;
- }
- }
-
- SECITEM_FreeItem(keyID,PR_TRUE);
- PK11_FreeSlotList(list);
- return slot;
-
-}
-/*
- * import a cert for a private key we have already generated. Set the label
- * on both to be the nickname. This is for the Key Gen, orphaned key case.
- */
-PK11SlotInfo *
-PK11_KeyForDERCertExists(SECItem *derCert, CK_OBJECT_HANDLE *keyPtr,
- void *wincx)
-{
- CERTCertificate *cert;
- PK11SlotInfo *slot = NULL;
-
- /* letting this use go -- the only thing that the cert is used for is
- * to get the ID attribute.
- */
- cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
- if (cert == NULL) return NULL;
-
- slot = PK11_KeyForCertExists(cert, keyPtr, wincx);
- CERT_DestroyCertificate (cert);
- return slot;
-}
-
-PK11SlotInfo *
-PK11_ImportCertForKey(CERTCertificate *cert, const char *nickname,
- void *wincx)
-{
- PK11SlotInfo *slot = NULL;
- CK_OBJECT_HANDLE key;
-
- slot = PK11_KeyForCertExists(cert,&key,wincx);
-
- if (slot) {
- if (PK11_ImportCert(slot,cert,key,nickname,PR_FALSE) != SECSuccess) {
- PK11_FreeSlot(slot);
- slot = NULL;
- }
- } else {
- PORT_SetError(SEC_ERROR_ADDING_CERT);
- }
-
- return slot;
-}
-
-PK11SlotInfo *
-PK11_ImportDERCertForKey(SECItem *derCert, char *nickname,void *wincx)
-{
- CERTCertificate *cert;
- PK11SlotInfo *slot = NULL;
-
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- derCert, NULL, PR_FALSE, PR_TRUE);
- if (cert == NULL) return NULL;
-
- slot = PK11_ImportCertForKey(cert, nickname, wincx);
- CERT_DestroyCertificate (cert);
- return slot;
-}
-
-static CK_OBJECT_HANDLE
-pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
- CK_ATTRIBUTE *searchTemplate, int count, void *wincx)
-{
- PK11SlotList *list;
- PK11SlotListElement *le;
- CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
- PK11SlotInfo *slot = NULL;
- SECStatus rv;
-
- *slotPtr = NULL;
-
- /* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
- if (list == NULL) {
- return CK_INVALID_HANDLE;
- }
-
-
- /* Look for the slot that holds the Key */
- for (le = list->head ; le; le = le->next) {
- rv = pk11_AuthenticateUnfriendly(le->slot, PR_TRUE, wincx);
- if (rv != SECSuccess) continue;
-
- certHandle = pk11_FindObjectByTemplate(le->slot,searchTemplate,count);
- if (certHandle != CK_INVALID_HANDLE) {
- slot = PK11_ReferenceSlot(le->slot);
- break;
- }
- }
-
- PK11_FreeSlotList(list);
-
- if (slot == NULL) {
- return CK_INVALID_HANDLE;
- }
- *slotPtr = slot;
- return certHandle;
-}
-
-CERTCertificate *
-PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
- CERTIssuerAndSN *issuerSN, void *wincx)
-{
- CERTCertificate *rvCert = NULL;
- NSSCertificate *cert = NULL;
- NSSDER issuer, serial;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSToken *token = slot->nssToken;
- nssSession *session;
- nssCryptokiObject *instance = NULL;
- nssPKIObject *object = NULL;
- SECItem *derSerial;
- PRStatus status;
-
- if (!issuerSN || !issuerSN->derIssuer.data || !issuerSN->derIssuer.len ||
- !issuerSN->serialNumber.data || !issuerSN->serialNumber.len ||
- issuerSN->derIssuer.len > CERT_MAX_DN_BYTES ||
- issuerSN->serialNumber.len > CERT_MAX_SERIAL_NUMBER_BYTES ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- /* Paranoia */
- if (token == NULL) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return NULL;
- }
-
-
- /* PKCS#11 needs to use DER-encoded serial numbers. Create a
- * CERTIssuerAndSN that actually has the encoded value and pass that
- * to PKCS#11 (and the crypto context).
- */
- derSerial = SEC_ASN1EncodeItem(NULL, NULL,
- &issuerSN->serialNumber,
- SEC_ASN1_GET(SEC_IntegerTemplate));
- if (!derSerial) {
- return NULL;
- }
-
- NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer);
- NSSITEM_FROM_SECITEM(&serial, derSerial);
-
- session = nssToken_GetDefaultSession(token);
- if (!session) {
- goto loser;
- }
-
- instance = nssToken_FindCertificateByIssuerAndSerialNumber(token,session,
- &issuer, &serial, nssTokenSearchType_TokenForced, &status);
-
- SECITEM_FreeItem(derSerial, PR_TRUE);
-
- if (!instance) {
- goto loser;
- }
- object = nssPKIObject_Create(NULL, instance, td, NULL, nssPKIMonitor);
- if (!object) {
- goto loser;
- }
- instance = NULL; /* adopted by the previous call */
- cert = nssCertificate_Create(object);
- if (!cert) {
- goto loser;
- }
- object = NULL; /* adopted by the previous call */
- nssTrustDomain_AddCertsToCache(td, &cert,1);
- /* on failure, cert is freed below */
- rvCert = STAN_GetCERTCertificate(cert);
- if (!rvCert) {
- goto loser;
- }
- return rvCert;
-
-loser:
- if (instance) {
- nssCryptokiObject_Destroy(instance);
- }
- if (object) {
- nssPKIObject_Destroy(object);
- }
- if (cert) {
- nssCertificate_Destroy(cert);
- }
- return NULL;
-}
-
-static PRCallOnceType keyIDHashCallOnce;
-
-static PRStatus PR_CALLBACK
-pk11_keyIDHash_populate(void *wincx)
-{
- CERTCertList *certList;
- CERTCertListNode *node = NULL;
- SECItem subjKeyID = {siBuffer, NULL, 0};
- SECItem *slotid = NULL;
- SECMODModuleList *modules, *mlp;
- SECMODListLock *moduleLock;
- int i;
-
- certList = PK11_ListCerts(PK11CertListUser, wincx);
- if (!certList) {
- return PR_FAILURE;
- }
-
- for (node = CERT_LIST_HEAD(certList);
- !CERT_LIST_END(node, certList);
- node = CERT_LIST_NEXT(node)) {
- if (CERT_FindSubjectKeyIDExtension(node->cert,
- &subjKeyID) == SECSuccess &&
- subjKeyID.data != NULL) {
- cert_AddSubjectKeyIDMapping(&subjKeyID, node->cert);
- SECITEM_FreeItem(&subjKeyID, PR_FALSE);
- }
- }
- CERT_DestroyCertList(certList);
-
- /*
- * Record the state of each slot in a hash. The concatenation of slotID
- * and moduleID is used as its key, with the slot series as its value.
- */
- slotid = SECITEM_AllocItem(NULL, NULL,
- sizeof(CK_SLOT_ID) + sizeof(SECMODModuleID));
- if (!slotid) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return PR_FAILURE;
- }
- moduleLock = SECMOD_GetDefaultModuleListLock();
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return PR_FAILURE;
- }
- SECMOD_GetReadLock(moduleLock);
- modules = SECMOD_GetDefaultModuleList();
- for (mlp = modules; mlp; mlp = mlp->next) {
- for (i = 0; i < mlp->module->slotCount; i++) {
- memcpy(slotid->data, &mlp->module->slots[i]->slotID,
- sizeof(CK_SLOT_ID));
- memcpy(&slotid->data[sizeof(CK_SLOT_ID)], &mlp->module->moduleID,
- sizeof(SECMODModuleID));
- cert_UpdateSubjectKeyIDSlotCheck(slotid,
- mlp->module->slots[i]->series);
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
- SECITEM_FreeItem(slotid, PR_TRUE);
-
- return PR_SUCCESS;
-}
-
-/*
- * We're looking for a cert which we have the private key for that's on the
- * list of recipients. This searches one slot.
- * this is the new version for NSS SMIME code
- * this stuff should REALLY be in the SMIME code, but some things in here are not public
- * (they should be!)
- */
-static CERTCertificate *
-pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipientlist, int *rlIndex, void *pwarg)
-{
- NSSCMSRecipient *ri = NULL;
- int i;
- PRBool tokenRescanDone = PR_FALSE;
- CERTCertTrust trust;
-
- for (i=0; (ri = recipientlist[i]) != NULL; i++) {
- CERTCertificate *cert = NULL;
- if (ri->kind == RLSubjKeyID) {
- SECItem *derCert = cert_FindDERCertBySubjectKeyID(ri->id.subjectKeyID);
- if (!derCert && !tokenRescanDone) {
- /*
- * We didn't find the cert by its key ID. If we have slots
- * with removable tokens, a failure from
- * cert_FindDERCertBySubjectKeyID doesn't necessarily imply
- * that the cert is unavailable - the token might simply
- * have been inserted after the initial run of
- * pk11_keyIDHash_populate (wrapped by PR_CallOnceWithArg),
- * or a different token might have been present in that
- * slot, initially. Let's check for new tokens...
- */
- PK11SlotList *sl = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
- PR_FALSE, PR_FALSE, pwarg);
- if (sl) {
- PK11SlotListElement *le;
- SECItem *slotid = SECITEM_AllocItem(NULL, NULL,
- sizeof(CK_SLOT_ID) + sizeof(SECMODModuleID));
- if (!slotid) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
- for (le = sl->head; le; le = le->next) {
- memcpy(slotid->data, &le->slot->slotID,
- sizeof(CK_SLOT_ID));
- memcpy(&slotid->data[sizeof(CK_SLOT_ID)],
- &le->slot->module->moduleID,
- sizeof(SECMODModuleID));
- /*
- * Any changes with the slot since our last check?
- * If so, re-read the certs in that specific slot.
- */
- if (cert_SubjectKeyIDSlotCheckSeries(slotid)
- != PK11_GetSlotSeries(le->slot)) {
- CERTCertListNode *node = NULL;
- SECItem subjKeyID = {siBuffer, NULL, 0};
- CERTCertList *cl = PK11_ListCertsInSlot(le->slot);
- if (!cl) {
- continue;
- }
- for (node = CERT_LIST_HEAD(cl);
- !CERT_LIST_END(node, cl);
- node = CERT_LIST_NEXT(node)) {
- if (CERT_IsUserCert(node->cert) &&
- CERT_FindSubjectKeyIDExtension(node->cert,
- &subjKeyID) == SECSuccess) {
- if (subjKeyID.data) {
- cert_AddSubjectKeyIDMapping(&subjKeyID,
- node->cert);
- cert_UpdateSubjectKeyIDSlotCheck(slotid,
- PK11_GetSlotSeries(le->slot));
- }
- SECITEM_FreeItem(&subjKeyID, PR_FALSE);
- }
- }
- CERT_DestroyCertList(cl);
- }
- }
- PK11_FreeSlotList(sl);
- SECITEM_FreeItem(slotid, PR_TRUE);
- }
- /* only check once per message/recipientlist */
- tokenRescanDone = PR_TRUE;
- /* do another lookup (hopefully we found that cert...) */
- derCert = cert_FindDERCertBySubjectKeyID(ri->id.subjectKeyID);
- }
- if (derCert) {
- cert = PK11_FindCertFromDERCertItem(slot, derCert, pwarg);
- SECITEM_FreeItem(derCert, PR_TRUE);
- }
- } else {
- cert = PK11_FindCertByIssuerAndSNOnToken(slot, ri->id.issuerAndSN,
- pwarg);
- }
- if (cert) {
- /* this isn't our cert */
- if (CERT_GetCertTrust(cert, &trust) != SECSuccess ||
- ((trust.emailFlags & CERTDB_USER) != CERTDB_USER)) {
- CERT_DestroyCertificate(cert);
- continue;
- }
- ri->slot = PK11_ReferenceSlot(slot);
- *rlIndex = i;
- return cert;
- }
- }
- *rlIndex = -1;
- return NULL;
-}
-
-/*
- * This function is the same as above, but it searches all the slots.
- * this is the new version for NSS SMIME code
- * this stuff should REALLY be in the SMIME code, but some things in here are not public
- * (they should be!)
- */
-static CERTCertificate *
-pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *wincx, int *rlIndex)
-{
- PK11SlotList *list;
- PK11SlotListElement *le;
- CERTCertificate *cert = NULL;
- SECStatus rv;
-
- /* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
- if (list == NULL) {
- return CK_INVALID_HANDLE;
- }
-
- /* Look for the slot that holds the Key */
- for (le = list->head ; le; le = le->next) {
- rv = pk11_AuthenticateUnfriendly(le->slot, PR_TRUE, wincx);
- if (rv != SECSuccess) continue;
-
- cert = pk11_FindCertObjectByRecipientNew(le->slot,
- recipientlist, rlIndex, wincx);
- if (cert)
- break;
- }
-
- PK11_FreeSlotList(list);
-
- return cert;
-}
-
-/*
- * We're looking for a cert which we have the private key for that's on the
- * list of recipients. This searches one slot.
- */
-static CERTCertificate *
-pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
- SEC_PKCS7RecipientInfo **recipientArray,
- SEC_PKCS7RecipientInfo **rip, void *pwarg)
-{
- SEC_PKCS7RecipientInfo *ri = NULL;
- CERTCertTrust trust;
- int i;
-
- for (i=0; (ri = recipientArray[i]) != NULL; i++) {
- CERTCertificate *cert;
-
- cert = PK11_FindCertByIssuerAndSNOnToken(slot, ri->issuerAndSN,
- pwarg);
- if (cert) {
- /* this isn't our cert */
- if (CERT_GetCertTrust(cert, &trust) != SECSuccess ||
- ((trust.emailFlags & CERTDB_USER) != CERTDB_USER)) {
- CERT_DestroyCertificate(cert);
- continue;
- }
- *rip = ri;
- return cert;
- }
-
- }
- *rip = NULL;
- return NULL;
-}
-
-/*
- * This function is the same as above, but it searches all the slots.
- */
-static CERTCertificate *
-pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
- SEC_PKCS7RecipientInfo **recipientArray,SEC_PKCS7RecipientInfo **rip,
- void *wincx)
-{
- PK11SlotList *list;
- PK11SlotListElement *le;
- CERTCertificate * cert = NULL;
- PK11SlotInfo *slot = NULL;
- SECStatus rv;
-
- *slotPtr = NULL;
-
- /* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
- if (list == NULL) {
- return CK_INVALID_HANDLE;
- }
-
- *rip = NULL;
-
- /* Look for the slot that holds the Key */
- for (le = list->head ; le; le = le->next) {
- rv = pk11_AuthenticateUnfriendly(le->slot, PR_TRUE, wincx);
- if (rv != SECSuccess) continue;
-
- cert = pk11_FindCertObjectByRecipient(le->slot, recipientArray,
- rip, wincx);
- if (cert) {
- slot = PK11_ReferenceSlot(le->slot);
- break;
- }
- }
-
- PK11_FreeSlotList(list);
-
- if (slot == NULL) {
- return NULL;
- }
- *slotPtr = slot;
- PORT_Assert(cert != NULL);
- return cert;
-}
-
-/*
- * We need to invert the search logic for PKCS 7 because if we search for
- * each cert on the list over all the slots, we wind up with lots of spurious
- * password prompts. This way we get only one password prompt per slot, at
- * the max, and most of the time we can find the cert, and only prompt for
- * the key...
- */
-CERTCertificate *
-PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
- SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip,
- SECKEYPrivateKey**privKey, void *wincx)
-{
- CERTCertificate *cert = NULL;
-
- *privKey = NULL;
- *slotPtr = NULL;
- cert = pk11_AllFindCertObjectByRecipient(slotPtr,array,rip,wincx);
- if (!cert) {
- return NULL;
- }
-
- *privKey = PK11_FindKeyByAnyCert(cert, wincx);
- if (*privKey == NULL) {
- goto loser;
- }
-
- return cert;
-loser:
- if (cert) CERT_DestroyCertificate(cert);
- if (*slotPtr) PK11_FreeSlot(*slotPtr);
- *slotPtr = NULL;
- return NULL;
-}
-
-/*
- * This is the new version of the above function for NSS SMIME code
- * this stuff should REALLY be in the SMIME code, but some things in here are not public
- * (they should be!)
- */
-int
-PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *wincx)
-{
- CERTCertificate *cert;
- NSSCMSRecipient *rl;
- PRStatus rv;
- int rlIndex;
-
- rv = PR_CallOnceWithArg(&keyIDHashCallOnce, pk11_keyIDHash_populate, wincx);
- if (rv != PR_SUCCESS)
- return -1;
-
- cert = pk11_AllFindCertObjectByRecipientNew(recipientlist, wincx, &rlIndex);
- if (!cert) {
- return -1;
- }
-
- rl = recipientlist[rlIndex];
-
- /* at this point, rl->slot is set */
-
- rl->privkey = PK11_FindKeyByAnyCert(cert, wincx);
- if (rl->privkey == NULL) {
- goto loser;
- }
-
- /* make a cert from the cert handle */
- rl->cert = cert;
- return rlIndex;
-
-loser:
- if (cert) CERT_DestroyCertificate(cert);
- if (rl->slot) PK11_FreeSlot(rl->slot);
- rl->slot = NULL;
- return -1;
-}
-
-CERTCertificate *
-PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
- void *wincx)
-{
- CERTCertificate *rvCert = NULL;
- NSSCertificate *cert;
- NSSDER issuer, serial;
- NSSCryptoContext *cc;
- SECItem *derSerial;
-
- if (!issuerSN || !issuerSN->derIssuer.data || !issuerSN->derIssuer.len ||
- !issuerSN->serialNumber.data || !issuerSN->serialNumber.len ||
- issuerSN->derIssuer.len > CERT_MAX_DN_BYTES ||
- issuerSN->serialNumber.len > CERT_MAX_SERIAL_NUMBER_BYTES ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- if (slotPtr) *slotPtr = NULL;
-
- /* PKCS#11 needs to use DER-encoded serial numbers. Create a
- * CERTIssuerAndSN that actually has the encoded value and pass that
- * to PKCS#11 (and the crypto context).
- */
- derSerial = SEC_ASN1EncodeItem(NULL, NULL,
- &issuerSN->serialNumber,
- SEC_ASN1_GET(SEC_IntegerTemplate));
- if (!derSerial) {
- return NULL;
- }
-
- NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer);
- NSSITEM_FROM_SECITEM(&serial, derSerial);
-
- cc = STAN_GetDefaultCryptoContext();
- cert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(cc,
- &issuer,
- &serial);
- if (cert) {
- SECITEM_FreeItem(derSerial, PR_TRUE);
- return STAN_GetCERTCertificateOrRelease(cert);
- }
-
- do {
- /* free the old cert on retry. Associated slot was not present */
- if (rvCert) {
- CERT_DestroyCertificate(rvCert);
- rvCert = NULL;
- }
-
- cert = NSSTrustDomain_FindCertificateByIssuerAndSerialNumber(
- STAN_GetDefaultTrustDomain(),
- &issuer,
- &serial);
- if (!cert) {
- break;
- }
-
- rvCert = STAN_GetCERTCertificateOrRelease(cert);
- if (rvCert == NULL) {
- break;
- }
-
- /* Check to see if the cert's token is still there */
- } while (!PK11_IsPresent(rvCert->slot));
-
- if (rvCert && slotPtr) *slotPtr = PK11_ReferenceSlot(rvCert->slot);
-
- SECITEM_FreeItem(derSerial, PR_TRUE);
- return rvCert;
-}
-
-CK_OBJECT_HANDLE
-PK11_FindObjectForCert(CERTCertificate *cert, void *wincx, PK11SlotInfo **pSlot)
-{
- CK_OBJECT_HANDLE certHandle;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE *attr;
- CK_ATTRIBUTE searchTemplate[]= {
- { CKA_CLASS, NULL, 0 },
- { CKA_VALUE, NULL, 0 },
- };
- int templateSize = sizeof(searchTemplate)/sizeof(searchTemplate[0]);
-
- attr = searchTemplate;
- PK11_SETATTRS(attr, CKA_CLASS, &certClass, sizeof(certClass)); attr++;
- PK11_SETATTRS(attr, CKA_VALUE, cert->derCert.data, cert->derCert.len);
-
- if (cert->slot) {
- certHandle = pk11_getcerthandle(cert->slot, cert, searchTemplate,
- templateSize);
- if (certHandle != CK_INVALID_HANDLE) {
- *pSlot = PK11_ReferenceSlot(cert->slot);
- return certHandle;
- }
- }
-
- certHandle = pk11_FindCertObjectByTemplate(pSlot, searchTemplate,
- templateSize, wincx);
- if (certHandle != CK_INVALID_HANDLE) {
- if (cert->slot == NULL) {
- cert->slot = PK11_ReferenceSlot(*pSlot);
- cert->pkcs11ID = certHandle;
- cert->ownSlot = PR_TRUE;
- cert->series = cert->slot->series;
- }
- }
-
- return(certHandle);
-}
-
-SECKEYPrivateKey *
-PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx)
-{
- CK_OBJECT_HANDLE certHandle;
- CK_OBJECT_HANDLE keyHandle;
- PK11SlotInfo *slot = NULL;
- SECKEYPrivateKey *privKey = NULL;
- PRBool needLogin;
- SECStatus rv;
- int err;
-
- certHandle = PK11_FindObjectForCert(cert, wincx, &slot);
- if (certHandle == CK_INVALID_HANDLE) {
- return NULL;
- }
- /*
- * prevent a login race condition. If slot is logged in between
- * our call to pk11_LoginStillRequired and the
- * PK11_MatchItem. The matchItem call will either succeed, or
- * we will call it one more time after calling PK11_Authenticate
- * (which is a noop on an authenticated token).
- */
- needLogin = pk11_LoginStillRequired(slot,wincx);
- keyHandle = PK11_MatchItem(slot,certHandle,CKO_PRIVATE_KEY);
- if ((keyHandle == CK_INVALID_HANDLE) && needLogin &&
- (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) ||
- SEC_ERROR_TOKEN_NOT_LOGGED_IN == err ) ) {
- /* authenticate and try again */
- rv = PK11_Authenticate(slot, PR_TRUE, wincx);
- if (rv == SECSuccess) {
- keyHandle = PK11_MatchItem(slot,certHandle,CKO_PRIVATE_KEY);
- }
- }
- if (keyHandle != CK_INVALID_HANDLE) {
- privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
- }
- if (slot) {
- PK11_FreeSlot(slot);
- }
- return privKey;
-}
-
-CK_OBJECT_HANDLE
-pk11_FindPubKeyByAnyCert(CERTCertificate *cert, PK11SlotInfo **slot, void *wincx)
-{
- CK_OBJECT_HANDLE certHandle;
- CK_OBJECT_HANDLE keyHandle;
-
- certHandle = PK11_FindObjectForCert(cert, wincx, slot);
- if (certHandle == CK_INVALID_HANDLE) {
- return CK_INVALID_HANDLE;
- }
- keyHandle = PK11_MatchItem(*slot,certHandle,CKO_PUBLIC_KEY);
- if (keyHandle == CK_INVALID_HANDLE) {
- PK11_FreeSlot(*slot);
- return CK_INVALID_HANDLE;
- }
- return keyHandle;
-}
-
-/*
- * find the number of certs in the slot with the same subject name
- */
-int
-PK11_NumberCertsForCertSubject(CERTCertificate *cert)
-{
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- };
- CK_ATTRIBUTE *attr = theTemplate;
- int templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]);
-
- PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
- PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len);
-
- if (cert->slot == NULL) {
- PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
- PR_FALSE,PR_TRUE,NULL);
- PK11SlotListElement *le;
- int count = 0;
-
- if (!list) {
- /* error code is set */
- return 0;
- }
-
- /* loop through all the fortezza tokens */
- for (le = list->head; le; le = le->next) {
- count += PK11_NumberObjectsFor(le->slot,theTemplate,templateSize);
- }
- PK11_FreeSlotList(list);
- return count;
- }
-
- return PK11_NumberObjectsFor(cert->slot,theTemplate,templateSize);
-}
-
-/*
- * Walk all the certs with the same subject
- */
-SECStatus
-PK11_TraverseCertsForSubject(CERTCertificate *cert,
- SECStatus(* callback)(CERTCertificate*, void *), void *arg)
-{
- if(!cert) {
- return SECFailure;
- }
- if (cert->slot == NULL) {
- PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
- PR_FALSE,PR_TRUE,NULL);
- PK11SlotListElement *le;
-
- if (!list) {
- /* error code is set */
- return SECFailure;
- }
- /* loop through all the tokens */
- for (le = list->head; le; le = le->next) {
- PK11_TraverseCertsForSubjectInSlot(cert,le->slot,callback,arg);
- }
- PK11_FreeSlotList(list);
- return SECSuccess;
-
- }
-
- return PK11_TraverseCertsForSubjectInSlot(cert, cert->slot, callback, arg);
-}
-
-SECStatus
-PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
- SECStatus(* callback)(CERTCertificate*, void *), void *arg)
-{
- PRStatus nssrv = PR_SUCCESS;
- NSSToken *token;
- NSSDER subject;
- NSSTrustDomain *td;
- nssList *subjectList;
- nssPKIObjectCollection *collection;
- nssCryptokiObject **instances;
- NSSCertificate **certs;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- td = STAN_GetDefaultTrustDomain();
- NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
- token = PK11Slot_GetNSSToken(slot);
- if (!nssToken_IsPresent(token)) {
- return SECSuccess;
- }
- collection = nssCertificateCollection_Create(td, NULL);
- if (!collection) {
- return SECFailure;
- }
- subjectList = nssList_Create(NULL, PR_FALSE);
- if (!subjectList) {
- nssPKIObjectCollection_Destroy(collection);
- return SECFailure;
- }
- (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
- subjectList);
- transfer_token_certs_to_collection(subjectList, token, collection);
- instances = nssToken_FindCertificatesBySubject(token, NULL,
- &subject,
- tokenOnly, 0, &nssrv);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
- nssList_Destroy(subjectList);
- certs = nssPKIObjectCollection_GetCertificates(collection,
- NULL, 0, NULL);
- nssPKIObjectCollection_Destroy(collection);
- if (certs) {
- CERTCertificate *oldie;
- NSSCertificate **cp;
- for (cp = certs; *cp; cp++) {
- oldie = STAN_GetCERTCertificate(*cp);
- if (!oldie) {
- continue;
- }
- if ((*callback)(oldie, arg) != SECSuccess) {
- nssrv = PR_FAILURE;
- break;
- }
- }
- nssCertificateArray_Destroy(certs);
- }
- return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-}
-
-SECStatus
-PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
- SECStatus(* callback)(CERTCertificate*, void *), void *arg)
-{
- struct nss3_cert_cbstr pk11cb;
- PRStatus nssrv = PR_SUCCESS;
- NSSToken *token;
- NSSTrustDomain *td;
- NSSUTF8 *nick;
- PRBool created = PR_FALSE;
- nssCryptokiObject **instances;
- nssPKIObjectCollection *collection = NULL;
- NSSCertificate **certs;
- nssList *nameList = NULL;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- pk11cb.callback = callback;
- pk11cb.arg = arg;
- token = PK11Slot_GetNSSToken(slot);
- if (!nssToken_IsPresent(token)) {
- return SECSuccess;
- }
- if (nickname->data[nickname->len-1] != '\0') {
- nick = nssUTF8_Create(NULL, nssStringType_UTF8String,
- nickname->data, nickname->len);
- created = PR_TRUE;
- } else {
- nick = (NSSUTF8 *)nickname->data;
- }
- td = STAN_GetDefaultTrustDomain();
- collection = nssCertificateCollection_Create(td, NULL);
- if (!collection) {
- goto loser;
- }
- nameList = nssList_Create(NULL, PR_FALSE);
- if (!nameList) {
- goto loser;
- }
- (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
- transfer_token_certs_to_collection(nameList, token, collection);
- instances = nssToken_FindCertificatesByNickname(token, NULL,
- nick,
- tokenOnly, 0, &nssrv);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
- nssList_Destroy(nameList);
- certs = nssPKIObjectCollection_GetCertificates(collection,
- NULL, 0, NULL);
- nssPKIObjectCollection_Destroy(collection);
- if (certs) {
- CERTCertificate *oldie;
- NSSCertificate **cp;
- for (cp = certs; *cp; cp++) {
- oldie = STAN_GetCERTCertificate(*cp);
- if (!oldie) {
- continue;
- }
- if ((*callback)(oldie, arg) != SECSuccess) {
- nssrv = PR_FAILURE;
- break;
- }
- }
- nssCertificateArray_Destroy(certs);
- }
- if (created) nss_ZFreeIf(nick);
- return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-loser:
- if (created) {
- nss_ZFreeIf(nick);
- }
- if (collection) {
- nssPKIObjectCollection_Destroy(collection);
- }
- if (nameList) {
- nssList_Destroy(nameList);
- }
- return SECFailure;
-}
-
-SECStatus
-PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
- SECStatus(* callback)(CERTCertificate*, void *), void *arg)
-{
- PRStatus nssrv;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSToken *tok;
- nssList *certList = NULL;
- nssCryptokiObject **instances;
- nssPKIObjectCollection *collection;
- NSSCertificate **certs;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- tok = PK11Slot_GetNSSToken(slot);
- if (!nssToken_IsPresent(tok)) {
- return SECSuccess;
- }
- collection = nssCertificateCollection_Create(td, NULL);
- if (!collection) {
- return SECFailure;
- }
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList) {
- nssPKIObjectCollection_Destroy(collection);
- return SECFailure;
- }
- (void)nssTrustDomain_GetCertsFromCache(td, certList);
- transfer_token_certs_to_collection(certList, tok, collection);
- instances = nssToken_FindObjects(tok, NULL, CKO_CERTIFICATE,
- tokenOnly, 0, &nssrv);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
- nssList_Destroy(certList);
- certs = nssPKIObjectCollection_GetCertificates(collection,
- NULL, 0, NULL);
- nssPKIObjectCollection_Destroy(collection);
- if (certs) {
- CERTCertificate *oldie;
- NSSCertificate **cp;
- for (cp = certs; *cp; cp++) {
- oldie = STAN_GetCERTCertificate(*cp);
- if (!oldie) {
- continue;
- }
- if ((*callback)(oldie, arg) != SECSuccess) {
- nssrv = PR_FAILURE;
- break;
- }
- }
- nssCertificateArray_Destroy(certs);
- }
- return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
-}
-
-/*
- * return the certificate associated with a derCert
- */
-CERTCertificate *
-PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
- void *wincx)
-{
- return PK11_FindCertFromDERCertItem(slot, &cert->derCert, wincx);
-}
-
-CERTCertificate *
-PK11_FindCertFromDERCertItem(PK11SlotInfo *slot, const SECItem *inDerCert,
- void *wincx)
-
-{
- NSSDER derCert;
- NSSToken *tok;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- nssCryptokiObject *co = NULL;
- SECStatus rv;
-
- tok = PK11Slot_GetNSSToken(slot);
- NSSITEM_FROM_SECITEM(&derCert, inDerCert);
- rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- PK11_FreeSlot(slot);
- return NULL;
- }
-
- co = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert,
- nssTokenSearchType_TokenOnly, NULL);
-
- return co ? PK11_MakeCertFromHandle(slot, co->handle, NULL) : NULL;
-
-}
-
-/*
- * import a cert for a private key we have already generated. Set the label
- * on both to be the nickname.
- */
-static CK_OBJECT_HANDLE
-pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
- void *wincx)
-{
- SECItem *keyID;
- CK_OBJECT_HANDLE key;
- SECStatus rv;
- PRBool needLogin;
- int err;
-
- if((slot == NULL) || (cert == NULL)) {
- return CK_INVALID_HANDLE;
- }
-
- keyID = pk11_mkcertKeyID(cert);
- if(keyID == NULL) {
- return CK_INVALID_HANDLE;
- }
-
- /*
- * prevent a login race condition. If slot is logged in between
- * our call to pk11_LoginStillRequired and the
- * pk11_FindPrivateKeyFromCerID. The matchItem call will either succeed, or
- * we will call it one more time after calling PK11_Authenticate
- * (which is a noop on an authenticated token).
- */
- needLogin = pk11_LoginStillRequired(slot,wincx);
- key = pk11_FindPrivateKeyFromCertID(slot, keyID);
- if ((key == CK_INVALID_HANDLE) && needLogin &&
- (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) ||
- SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) {
- /* authenticate and try again */
- rv = PK11_Authenticate(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) goto loser;
- key = pk11_FindPrivateKeyFromCertID(slot, keyID);
- }
-
-loser:
- SECITEM_ZfreeItem(keyID, PR_TRUE);
- return key;
-}
-
-SECKEYPrivateKey *
-PK11_FindKeyByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
- void *wincx)
-{
- CK_OBJECT_HANDLE keyHandle;
-
- if((slot == NULL) || (cert == NULL)) {
- return NULL;
- }
-
- keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
- if (keyHandle == CK_INVALID_HANDLE) {
- return NULL;
- }
-
- return PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,wincx);
-}
-
-SECStatus
-PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
- char *nickname,
- PRBool addCertUsage,void *wincx)
-{
- CK_OBJECT_HANDLE keyHandle;
-
- if((slot == NULL) || (cert == NULL) || (nickname == NULL)) {
- return SECFailure;
- }
-
- keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
- if (keyHandle == CK_INVALID_HANDLE) {
- return SECFailure;
- }
-
- return PK11_ImportCert(slot, cert, keyHandle, nickname, addCertUsage);
-}
-
-
-/* remove when the real version comes out */
-#define SEC_OID_MISSI_KEA 300 /* until we have v3 stuff merged */
-PRBool
-KEAPQGCompare(CERTCertificate *server,CERTCertificate *cert) {
-
- /* not implemented */
- return PR_FALSE;
-}
-
-PRBool
-PK11_FortezzaHasKEA(CERTCertificate *cert)
-{
- /* look at the subject and see if it is a KEA for MISSI key */
- SECOidData *oid;
- CERTCertTrust trust;
-
- if (CERT_GetCertTrust(cert, &trust) != SECSuccess ||
- ((trust.sslFlags & CERTDB_USER) != CERTDB_USER)) {
- return PR_FALSE;
- }
-
- oid = SECOID_FindOID(&cert->subjectPublicKeyInfo.algorithm.algorithm);
- if (!oid) {
- return PR_FALSE;
- }
-
- return (PRBool)((oid->offset == SEC_OID_MISSI_KEA_DSS_OLD) ||
- (oid->offset == SEC_OID_MISSI_KEA_DSS) ||
- (oid->offset == SEC_OID_MISSI_KEA)) ;
-}
-
-/*
- * Find a kea cert on this slot that matches the domain of it's peer
- */
-static CERTCertificate
-*pk11_GetKEAMate(PK11SlotInfo *slot,CERTCertificate *peer)
-{
- int i;
- CERTCertificate *returnedCert = NULL;
-
- for (i=0; i < slot->cert_count; i++) {
- CERTCertificate *cert = slot->cert_array[i];
-
- if (PK11_FortezzaHasKEA(cert) && KEAPQGCompare(peer,cert)) {
- returnedCert = CERT_DupCertificate(cert);
- break;
- }
- }
- return returnedCert;
-}
-
-/*
- * The following is a FORTEZZA only Certificate request. We call this when we
- * are doing a non-client auth SSL connection. We are only interested in the
- * fortezza slots, and we are only interested in certs that share the same root
- * key as the server.
- */
-CERTCertificate *
-PK11_FindBestKEAMatch(CERTCertificate *server, void *wincx)
-{
- PK11SlotList *keaList = PK11_GetAllTokens(CKM_KEA_KEY_DERIVE,
- PR_FALSE,PR_TRUE,wincx);
- PK11SlotListElement *le;
- CERTCertificate *returnedCert = NULL;
- SECStatus rv;
-
- if (!keaList) {
- /* error code is set */
- return NULL;
- }
-
- /* loop through all the fortezza tokens */
- for (le = keaList->head; le; le = le->next) {
- rv = PK11_Authenticate(le->slot, PR_TRUE, wincx);
- if (rv != SECSuccess) continue;
- if (le->slot->session == CK_INVALID_SESSION) {
- continue;
- }
- returnedCert = pk11_GetKEAMate(le->slot,server);
- if (returnedCert) break;
- }
- PK11_FreeSlotList(keaList);
-
- return returnedCert;
-}
-
-/*
- * find a matched pair of kea certs to key exchange parameters from one
- * fortezza card to another as necessary.
- */
-SECStatus
-PK11_GetKEAMatchedCerts(PK11SlotInfo *slot1, PK11SlotInfo *slot2,
- CERTCertificate **cert1, CERTCertificate **cert2)
-{
- CERTCertificate *returnedCert = NULL;
- int i;
-
- for (i=0; i < slot1->cert_count; i++) {
- CERTCertificate *cert = slot1->cert_array[i];
-
- if (PK11_FortezzaHasKEA(cert)) {
- returnedCert = pk11_GetKEAMate(slot2,cert);
- if (returnedCert != NULL) {
- *cert2 = returnedCert;
- *cert1 = CERT_DupCertificate(cert);
- return SECSuccess;
- }
- }
- }
- return SECFailure;
-}
-
-/*
- * return the private key From a given Cert
- */
-CK_OBJECT_HANDLE
-PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx)
-{
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_VALUE, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- /* if you change the array, change the variable below as well */
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
- CK_ATTRIBUTE *attrs = theTemplate;
- SECStatus rv;
-
- PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data,
- cert->derCert.len); attrs++;
- PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
-
- /*
- * issue the find
- */
- rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- return CK_INVALID_HANDLE;
- }
-
- return pk11_getcerthandle(slot,cert,theTemplate,tsize);
-}
-
-/* Looking for PK11_GetKeyIDFromCert?
- * Use PK11_GetLowLevelKeyIDForCert instead.
- */
-
-
-struct listCertsStr {
- PK11CertListType type;
- CERTCertList *certList;
-};
-
-static PRStatus
-pk11ListCertCallback(NSSCertificate *c, void *arg)
-{
- struct listCertsStr *listCertP = (struct listCertsStr *)arg;
- CERTCertificate *newCert = NULL;
- PK11CertListType type = listCertP->type;
- CERTCertList *certList = listCertP->certList;
- PRBool isUnique = PR_FALSE;
- PRBool isCA = PR_FALSE;
- char *nickname = NULL;
- unsigned int certType;
- SECStatus rv;
-
- if ((type == PK11CertListUnique) || (type == PK11CertListRootUnique) ||
- (type == PK11CertListCAUnique) || (type == PK11CertListUserUnique) ) {
- /* only list one instance of each certificate, even if several exist */
- isUnique = PR_TRUE;
- }
- if ((type == PK11CertListCA) || (type == PK11CertListRootUnique) ||
- (type == PK11CertListCAUnique)) {
- isCA = PR_TRUE;
- }
-
- /* if we want user certs and we don't have one skip this cert */
- if ( ( (type == PK11CertListUser) || (type == PK11CertListUserUnique) ) &&
- !NSSCertificate_IsPrivateKeyAvailable(c, NULL,NULL)) {
- return PR_SUCCESS;
- }
-
- /* PK11CertListRootUnique means we want CA certs without a private key.
- * This is for legacy app support . PK11CertListCAUnique should be used
- * instead to get all CA certs, regardless of private key
- */
- if ((type == PK11CertListRootUnique) &&
- NSSCertificate_IsPrivateKeyAvailable(c, NULL,NULL)) {
- return PR_SUCCESS;
- }
-
- /* caller still owns the reference to 'c' */
- newCert = STAN_GetCERTCertificate(c);
- if (!newCert) {
- return PR_SUCCESS;
- }
- /* if we want CA certs and it ain't one, skip it */
- if( isCA && (!CERT_IsCACert(newCert, &certType)) ) {
- return PR_SUCCESS;
- }
- if (isUnique) {
- CERT_DupCertificate(newCert);
-
- nickname = STAN_GetCERTCertificateName(certList->arena, c);
-
- /* put slot certs at the end */
- if (newCert->slot && !PK11_IsInternal(newCert->slot)) {
- rv = CERT_AddCertToListTailWithData(certList,newCert,nickname);
- } else {
- rv = CERT_AddCertToListHeadWithData(certList,newCert,nickname);
- }
- /* if we didn't add the cert to the list, don't leak it */
- if (rv != SECSuccess) {
- CERT_DestroyCertificate(newCert);
- }
- } else {
- /* add multiple instances to the cert list */
- nssCryptokiObject **ip;
- nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
- if (!instances) {
- return PR_SUCCESS;
- }
- for (ip = instances; *ip; ip++) {
- nssCryptokiObject *instance = *ip;
- PK11SlotInfo *slot = instance->token->pk11slot;
-
- /* put the same CERTCertificate in the list for all instances */
- CERT_DupCertificate(newCert);
-
- nickname = STAN_GetCERTCertificateNameForInstance(
- certList->arena, c, instance);
-
- /* put slot certs at the end */
- if (slot && !PK11_IsInternal(slot)) {
- rv = CERT_AddCertToListTailWithData(certList,newCert,nickname);
- } else {
- rv = CERT_AddCertToListHeadWithData(certList,newCert,nickname);
- }
- /* if we didn't add the cert to the list, don't leak it */
- if (rv != SECSuccess) {
- CERT_DestroyCertificate(newCert);
- }
- }
- nssCryptokiObjectArray_Destroy(instances);
- }
- return PR_SUCCESS;
-}
-
-
-CERTCertList *
-PK11_ListCerts(PK11CertListType type, void *pwarg)
-{
- NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
- CERTCertList *certList = NULL;
- struct listCertsStr listCerts;
- certList = CERT_NewCertList();
- listCerts.type = type;
- listCerts.certList = certList;
-
- /* authenticate to the slots */
- (void) pk11_TraverseAllSlots( NULL, NULL, PR_TRUE, pwarg);
- NSSTrustDomain_TraverseCertificates(defaultTD, pk11ListCertCallback,
- &listCerts);
- return certList;
-}
-
-SECItem *
-PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
- CERTCertificate *cert, void *wincx)
-{
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_VALUE, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- /* if you change the array, change the variable below as well */
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
- CK_OBJECT_HANDLE certHandle;
- CK_ATTRIBUTE *attrs = theTemplate;
- PK11SlotInfo *slotRef = NULL;
- SECItem *item;
- SECStatus rv;
-
- if (slot) {
- PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data,
- cert->derCert.len); attrs++;
- PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
-
- rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- return NULL;
- }
- certHandle = pk11_getcerthandle(slot,cert,theTemplate,tsize);
- } else {
- certHandle = PK11_FindObjectForCert(cert, wincx, &slotRef);
- if (certHandle == CK_INVALID_HANDLE) {
- return pk11_mkcertKeyID(cert);
- }
- slot = slotRef;
- }
-
- if (certHandle == CK_INVALID_HANDLE) {
- return NULL;
- }
-
- item = pk11_GetLowLevelKeyFromHandle(slot,certHandle);
- if (slotRef) PK11_FreeSlot(slotRef);
- return item;
-}
-
-/* argument type for listCertsCallback */
-typedef struct {
- CERTCertList *list;
- PK11SlotInfo *slot;
-} ListCertsArg;
-
-static SECStatus
-listCertsCallback(CERTCertificate* cert, void*arg)
-{
- ListCertsArg *cdata = (ListCertsArg*)arg;
- char *nickname = NULL;
- nssCryptokiObject *instance, **ci;
- nssCryptokiObject **instances;
- NSSCertificate *c = STAN_GetNSSCertificate(cert);
- SECStatus rv;
-
- if (c == NULL) {
- return SECFailure;
- }
- instances = nssPKIObject_GetInstances(&c->object);
- if (!instances) {
- return SECFailure;
- }
- instance = NULL;
- for (ci = instances; *ci; ci++) {
- if ((*ci)->token->pk11slot == cdata->slot) {
- instance = *ci;
- break;
- }
- }
- PORT_Assert(instance != NULL);
- if (!instance) {
- nssCryptokiObjectArray_Destroy(instances);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- nickname = STAN_GetCERTCertificateNameForInstance(cdata->list->arena,
- c, instance);
- nssCryptokiObjectArray_Destroy(instances);
-
- CERT_DupCertificate(cert);
- rv = CERT_AddCertToListTailWithData(cdata->list, cert, nickname);
- if (rv != SECSuccess) {
- CERT_DestroyCertificate(cert);
- }
- return rv;
-}
-
-CERTCertList *
-PK11_ListCertsInSlot(PK11SlotInfo *slot)
-{
- SECStatus status;
- CERTCertList *certs;
- ListCertsArg cdata;
-
- certs = CERT_NewCertList();
- if(certs == NULL) return NULL;
- cdata.list = certs;
- cdata.slot = slot;
-
- status = PK11_TraverseCertsInSlot(slot, listCertsCallback,
- &cdata);
-
- if( status != SECSuccess ) {
- CERT_DestroyCertList(certs);
- certs = NULL;
- }
-
- return certs;
-}
-
-PK11SlotList *
-PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg)
-{
- nssCryptokiObject **ip;
- PK11SlotList *slotList;
- NSSCertificate *c;
- nssCryptokiObject **instances;
- PRBool found = PR_FALSE;
-
- if (!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- c = STAN_GetNSSCertificate(cert);
- if (!c) {
- CERT_MapStanError();
- return NULL;
- }
-
- /* add multiple instances to the cert list */
- instances = nssPKIObject_GetInstances(&c->object);
- if (!instances) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return NULL;
- }
-
- slotList = PK11_NewSlotList();
- if (!slotList) {
- nssCryptokiObjectArray_Destroy(instances);
- return NULL;
- }
-
- for (ip = instances; *ip; ip++) {
- nssCryptokiObject *instance = *ip;
- PK11SlotInfo *slot = instance->token->pk11slot;
- if (slot) {
- PK11_AddSlotToList(slotList, slot, PR_TRUE);
- found = PR_TRUE;
- }
- }
- if (!found) {
- PK11_FreeSlotList(slotList);
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- slotList = NULL;
- }
-
- nssCryptokiObjectArray_Destroy(instances);
- return slotList;
-}
diff --git a/security/nss/lib/pk11wrap/pk11cxt.c b/security/nss/lib/pk11wrap/pk11cxt.c
deleted file mode 100644
index 8aeb63ef2..000000000
--- a/security/nss/lib/pk11wrap/pk11cxt.c
+++ /dev/null
@@ -1,1039 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file PK11Contexts which are used in multipart hashing,
- * encryption/decryption, and signing/verication operations.
- */
-
-#include "seccomon.h"
-#include "secmod.h"
-#include "nssilock.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11.h"
-#include "pk11func.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "sechash.h"
-#include "secerr.h"
-
-static const SECItem pk11_null_params = { 0 };
-
-/**********************************************************************
- *
- * Now Deal with Crypto Contexts
- *
- **********************************************************************/
-
-/*
- * the monitors...
- */
-void
-PK11_EnterContextMonitor(PK11Context *cx) {
- /* if we own the session and our slot is ThreadSafe, only monitor
- * the Context */
- if ((cx->ownSession) && (cx->slot->isThreadSafe)) {
- /* Should this use monitors instead? */
- PZ_Lock(cx->sessionLock);
- } else {
- PK11_EnterSlotMonitor(cx->slot);
- }
-}
-
-void
-PK11_ExitContextMonitor(PK11Context *cx) {
- /* if we own the session and our slot is ThreadSafe, only monitor
- * the Context */
- if ((cx->ownSession) && (cx->slot->isThreadSafe)) {
- /* Should this use monitors instead? */
- PZ_Unlock(cx->sessionLock);
- } else {
- PK11_ExitSlotMonitor(cx->slot);
- }
-}
-
-/*
- * Free up a Cipher Context
- */
-void
-PK11_DestroyContext(PK11Context *context, PRBool freeit)
-{
- pk11_CloseSession(context->slot,context->session,context->ownSession);
- /* initialize the critical fields of the context */
- if (context->savedData != NULL ) PORT_Free(context->savedData);
- if (context->key) PK11_FreeSymKey(context->key);
- if (context->param && context->param != &pk11_null_params)
- SECITEM_FreeItem(context->param, PR_TRUE);
- if (context->sessionLock) PZ_DestroyLock(context->sessionLock);
- PK11_FreeSlot(context->slot);
- if (freeit) PORT_Free(context);
-}
-
-/*
- * save the current context. Allocate Space if necessary.
- */
-static unsigned char *
-pk11_saveContextHelper(PK11Context *context, unsigned char *buffer,
- unsigned long *savedLength)
-{
- CK_RV crv;
-
- /* If buffer is NULL, this will get the length */
- crv = PK11_GETTAB(context->slot)->C_GetOperationState(context->session,
- (CK_BYTE_PTR)buffer,
- savedLength);
- if (!buffer || (crv == CKR_BUFFER_TOO_SMALL)) {
- /* the given buffer wasn't big enough (or was NULL), but we
- * have the length, so try again with a new buffer and the
- * correct length
- */
- unsigned long bufLen = *savedLength;
- buffer = PORT_Alloc(bufLen);
- if (buffer == NULL) {
- return (unsigned char *)NULL;
- }
- crv = PK11_GETTAB(context->slot)->C_GetOperationState(
- context->session,
- (CK_BYTE_PTR)buffer,
- savedLength);
- if (crv != CKR_OK) {
- PORT_ZFree(buffer, bufLen);
- }
- }
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return (unsigned char *)NULL;
- }
- return buffer;
-}
-
-void *
-pk11_saveContext(PK11Context *context, void *space, unsigned long *savedLength)
-{
- return pk11_saveContextHelper(context,
- (unsigned char *)space, savedLength);
-}
-
-/*
- * restore the current context
- */
-SECStatus
-pk11_restoreContext(PK11Context *context,void *space, unsigned long savedLength)
-{
- CK_RV crv;
- CK_OBJECT_HANDLE objectID = (context->key) ? context->key->objectID:
- CK_INVALID_HANDLE;
-
- PORT_Assert(space != NULL);
- if (space == NULL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- crv = PK11_GETTAB(context->slot)->C_SetOperationState(context->session,
- (CK_BYTE_PTR)space, savedLength, objectID, 0);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus pk11_Finalize(PK11Context *context);
-
-/*
- * Context initialization. Used by all flavors of CreateContext
- */
-static SECStatus
-pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info)
-{
- CK_RV crv;
- PK11SymKey *symKey = context->key;
- SECStatus rv = SECSuccess;
-
- switch (context->operation) {
- case CKA_ENCRYPT:
- crv=PK11_GETTAB(context->slot)->C_EncryptInit(context->session,
- mech_info, symKey->objectID);
- break;
- case CKA_DECRYPT:
- if (context->fortezzaHack) {
- CK_ULONG count = 0;;
- /* generate the IV for fortezza */
- crv=PK11_GETTAB(context->slot)->C_EncryptInit(context->session,
- mech_info, symKey->objectID);
- if (crv != CKR_OK) break;
- PK11_GETTAB(context->slot)->C_EncryptFinal(context->session,
- NULL, &count);
- }
- crv=PK11_GETTAB(context->slot)->C_DecryptInit(context->session,
- mech_info, symKey->objectID);
- break;
- case CKA_SIGN:
- crv=PK11_GETTAB(context->slot)->C_SignInit(context->session,
- mech_info, symKey->objectID);
- break;
- case CKA_VERIFY:
- crv=PK11_GETTAB(context->slot)->C_SignInit(context->session,
- mech_info, symKey->objectID);
- break;
- case CKA_DIGEST:
- crv=PK11_GETTAB(context->slot)->C_DigestInit(context->session,
- mech_info);
- break;
- default:
- crv = CKR_OPERATION_NOT_INITIALIZED;
- break;
- }
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
-
- /*
- * handle session starvation case.. use our last session to multiplex
- */
- if (!context->ownSession) {
- context->savedData = pk11_saveContext(context,context->savedData,
- &context->savedLength);
- if (context->savedData == NULL) rv = SECFailure;
- /* clear out out session for others to use */
- pk11_Finalize(context);
- }
- return rv;
-}
-
-
-/*
- * Common Helper Function do come up with a new context.
- */
-static PK11Context *pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
- PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey,
- SECItem *param)
-{
- CK_MECHANISM mech_info;
- PK11Context *context;
- SECStatus rv;
-
- PORT_Assert(slot != NULL);
- if (!slot || (!symKey && ((operation != CKA_DIGEST) ||
- (type == CKM_SKIPJACK_CBC64)))) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- context = (PK11Context *) PORT_Alloc(sizeof(PK11Context));
- if (context == NULL) {
- return NULL;
- }
-
- /* now deal with the fortezza hack... the fortezza hack is an attempt
- * to get around the issue of the card not allowing you to do a FORTEZZA
- * LoadIV/Encrypt, which was added because such a combination could be
- * use to circumvent the key escrow system. Unfortunately SSL needs to
- * do this kind of operation, so in SSL we do a loadIV (to verify it),
- * Then GenerateIV, and through away the first 8 bytes on either side
- * of the connection.*/
- context->fortezzaHack = PR_FALSE;
- if (type == CKM_SKIPJACK_CBC64) {
- if (symKey->origin == PK11_OriginFortezzaHack) {
- context->fortezzaHack = PR_TRUE;
- }
- }
-
- /* initialize the critical fields of the context */
- context->operation = operation;
- context->key = symKey ? PK11_ReferenceSymKey(symKey) : NULL;
- context->slot = PK11_ReferenceSlot(slot);
- context->session = pk11_GetNewSession(slot,&context->ownSession);
- context->cx = symKey ? symKey->cx : NULL;
- /* get our session */
- context->savedData = NULL;
-
- /* save the parameters so that some digesting stuff can do multiple
- * begins on a single context */
- context->type = type;
- if (param) {
- if (param->len > 0) {
- context->param = SECITEM_DupItem(param);
- } else {
- context->param = (SECItem *)&pk11_null_params;
- }
- } else {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- context->param = NULL;
- }
- context->init = PR_FALSE;
- context->sessionLock = PZ_NewLock(nssILockPK11cxt);
- if ((context->param == NULL) || (context->sessionLock == NULL)) {
- PK11_DestroyContext(context,PR_TRUE);
- return NULL;
- }
-
- mech_info.mechanism = type;
- mech_info.pParameter = param->data;
- mech_info.ulParameterLen = param->len;
- PK11_EnterContextMonitor(context);
- rv = pk11_context_init(context,&mech_info);
- PK11_ExitContextMonitor(context);
-
- if (rv != SECSuccess) {
- PK11_DestroyContext(context,PR_TRUE);
- return NULL;
- }
- context->init = PR_TRUE;
- return context;
-}
-
-
-/*
- * put together the various PK11_Create_Context calls used by different
- * parts of libsec.
- */
-PK11Context *
-__PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,
- SECItem *param, void *wincx)
-{
- PK11SymKey *symKey = NULL;
- PK11Context *context = NULL;
-
- /* first get a slot */
- if (slot == NULL) {
- slot = PK11_GetBestSlot(type,wincx);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- goto loser;
- }
- } else {
- PK11_ReferenceSlot(slot);
- }
-
- /* now import the key */
- symKey = PK11_ImportSymKey(slot, type, origin, operation, key, wincx);
- if (symKey == NULL) goto loser;
-
- context = PK11_CreateContextBySymKey(type, operation, symKey, param);
-
-loser:
- if (symKey) {
- PK11_FreeSymKey(symKey);
- }
- if (slot) {
- PK11_FreeSlot(slot);
- }
-
- return context;
-}
-
-PK11Context *
-PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,
- SECItem *param, void *wincx)
-{
- return __PK11_CreateContextByRawKey(slot, type, origin, operation,
- key, param, wincx);
-}
-
-
-/*
- * Create a context from a key. We really should make sure we aren't using
- * the same key in multiple session!
- */
-PK11Context *
-PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type,CK_ATTRIBUTE_TYPE operation,
- PK11SymKey *symKey, SECItem *param)
-{
- PK11SymKey *newKey;
- PK11Context *context;
-
- /* if this slot doesn't support the mechanism, go to a slot that does */
- newKey = pk11_ForceSlot(symKey,type,operation);
- if (newKey == NULL) {
- PK11_ReferenceSymKey(symKey);
- } else {
- symKey = newKey;
- }
-
-
- /* Context Adopts the symKey.... */
- context = pk11_CreateNewContextInSlot(type, symKey->slot, operation, symKey,
- param);
- PK11_FreeSymKey(symKey);
- return context;
-}
-
-/*
- * Digest contexts don't need keys, but the do need to find a slot.
- * Macing should use PK11_CreateContextBySymKey.
- */
-PK11Context *
-PK11_CreateDigestContext(SECOidTag hashAlg)
-{
- /* digesting has to work without authentication to the slot */
- CK_MECHANISM_TYPE type;
- PK11SlotInfo *slot;
- PK11Context *context;
- SECItem param;
-
- type = PK11_AlgtagToMechanism(hashAlg);
- slot = PK11_GetBestSlot(type, NULL);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
-
- /* maybe should really be PK11_GenerateNewParam?? */
- param.data = NULL;
- param.len = 0;
- param.type = 0;
-
- context = pk11_CreateNewContextInSlot(type, slot, CKA_DIGEST, NULL, &param);
- PK11_FreeSlot(slot);
- return context;
-}
-
-/*
- * create a new context which is the clone of the state of old context.
- */
-PK11Context * PK11_CloneContext(PK11Context *old)
-{
- PK11Context *newcx;
- PRBool needFree = PR_FALSE;
- SECStatus rv = SECSuccess;
- void *data;
- unsigned long len;
-
- newcx = pk11_CreateNewContextInSlot(old->type, old->slot, old->operation,
- old->key, old->param);
- if (newcx == NULL) return NULL;
-
- /* now clone the save state. First we need to find the save state
- * of the old session. If the old context owns it's session,
- * the state needs to be saved, otherwise the state is in saveData. */
- if (old->ownSession) {
- PK11_EnterContextMonitor(old);
- data=pk11_saveContext(old,NULL,&len);
- PK11_ExitContextMonitor(old);
- needFree = PR_TRUE;
- } else {
- data = old->savedData;
- len = old->savedLength;
- }
-
- if (data == NULL) {
- PK11_DestroyContext(newcx,PR_TRUE);
- return NULL;
- }
-
- /* now copy that state into our new context. Again we have different
- * work if the new context owns it's own session. If it does, we
- * restore the state gathered above. If it doesn't, we copy the
- * saveData pointer... */
- if (newcx->ownSession) {
- PK11_EnterContextMonitor(newcx);
- rv = pk11_restoreContext(newcx,data,len);
- PK11_ExitContextMonitor(newcx);
- } else {
- PORT_Assert(newcx->savedData != NULL);
- if ((newcx->savedData == NULL) || (newcx->savedLength < len)) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- } else {
- PORT_Memcpy(newcx->savedData,data,len);
- newcx->savedLength = len;
- }
- }
-
- if (needFree) PORT_Free(data);
-
- if (rv != SECSuccess) {
- PK11_DestroyContext(newcx,PR_TRUE);
- return NULL;
- }
- return newcx;
-}
-
-/*
- * save the current context state into a variable. Required to make FORTEZZA
- * work.
- */
-SECStatus
-PK11_SaveContext(PK11Context *cx,unsigned char *save,int *len, int saveLength)
-{
- unsigned char * data = NULL;
- CK_ULONG length = saveLength;
-
- if (cx->ownSession) {
- PK11_EnterContextMonitor(cx);
- data = pk11_saveContextHelper(cx, save, &length);
- PK11_ExitContextMonitor(cx);
- if (data) *len = length;
- } else if ((unsigned) saveLength >= cx->savedLength) {
- data = (unsigned char*)cx->savedData;
- if (cx->savedData) {
- PORT_Memcpy(save,cx->savedData,cx->savedLength);
- }
- *len = cx->savedLength;
- }
- if (data != NULL) {
- if (cx->ownSession) {
- PORT_ZFree(data, length);
- }
- return SECSuccess;
- } else {
- return SECFailure;
- }
-}
-
-/* same as above, but may allocate the return buffer. */
-unsigned char *
-PK11_SaveContextAlloc(PK11Context *cx,
- unsigned char *preAllocBuf, unsigned int pabLen,
- unsigned int *stateLen)
-{
- unsigned char *stateBuf = NULL;
- unsigned long length = (unsigned long)pabLen;
-
- if (cx->ownSession) {
- PK11_EnterContextMonitor(cx);
- stateBuf = pk11_saveContextHelper(cx, preAllocBuf, &length);
- PK11_ExitContextMonitor(cx);
- *stateLen = (stateBuf != NULL) ? length : 0;
- } else {
- if (pabLen < cx->savedLength) {
- stateBuf = (unsigned char *)PORT_Alloc(cx->savedLength);
- if (!stateBuf) {
- return (unsigned char *)NULL;
- }
- } else {
- stateBuf = preAllocBuf;
- }
- if (cx->savedData) {
- PORT_Memcpy(stateBuf, cx->savedData, cx->savedLength);
- }
- *stateLen = cx->savedLength;
- }
- return stateBuf;
-}
-
-/*
- * restore the context state into a new running context. Also required for
- * FORTEZZA .
- */
-SECStatus
-PK11_RestoreContext(PK11Context *cx,unsigned char *save,int len)
-{
- SECStatus rv = SECSuccess;
- if (cx->ownSession) {
- PK11_EnterContextMonitor(cx);
- pk11_Finalize(cx);
- rv = pk11_restoreContext(cx,save,len);
- PK11_ExitContextMonitor(cx);
- } else {
- PORT_Assert(cx->savedData != NULL);
- if ((cx->savedData == NULL) || (cx->savedLength < (unsigned) len)) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- } else {
- PORT_Memcpy(cx->savedData,save,len);
- cx->savedLength = len;
- }
- }
- return rv;
-}
-
-/*
- * This is to get FIPS compliance until we can convert
- * libjar to use PK11_ hashing functions. It returns PR_FALSE
- * if we can't get a PK11 Context.
- */
-PRBool
-PK11_HashOK(SECOidTag algID) {
- PK11Context *cx;
-
- cx = PK11_CreateDigestContext(algID);
- if (cx == NULL) return PR_FALSE;
- PK11_DestroyContext(cx, PR_TRUE);
- return PR_TRUE;
-}
-
-
-
-/*
- * start a new digesting or Mac'ing operation on this context
- */
-SECStatus PK11_DigestBegin(PK11Context *cx)
-{
- CK_MECHANISM mech_info;
- SECStatus rv;
-
- if (cx->init == PR_TRUE) {
- return SECSuccess;
- }
-
- /*
- * make sure the old context is clear first
- */
- PK11_EnterContextMonitor(cx);
- pk11_Finalize(cx);
-
- mech_info.mechanism = cx->type;
- mech_info.pParameter = cx->param->data;
- mech_info.ulParameterLen = cx->param->len;
- rv = pk11_context_init(cx,&mech_info);
- PK11_ExitContextMonitor(cx);
-
- if (rv != SECSuccess) {
- return SECFailure;
- }
- cx->init = PR_TRUE;
- return SECSuccess;
-}
-
-SECStatus
-PK11_HashBuf(SECOidTag hashAlg, unsigned char *out, const unsigned char *in,
- PRInt32 len) {
- PK11Context *context;
- unsigned int max_length;
- unsigned int out_length;
- SECStatus rv;
-
- /* len will be passed to PK11_DigestOp as unsigned. */
- if (len < 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- context = PK11_CreateDigestContext(hashAlg);
- if (context == NULL) return SECFailure;
-
- rv = PK11_DigestBegin(context);
- if (rv != SECSuccess) {
- PK11_DestroyContext(context, PR_TRUE);
- return rv;
- }
-
- rv = PK11_DigestOp(context, in, len);
- if (rv != SECSuccess) {
- PK11_DestroyContext(context, PR_TRUE);
- return rv;
- }
-
- /* XXX This really should have been an argument to this function! */
- max_length = HASH_ResultLenByOidTag(hashAlg);
- PORT_Assert(max_length);
- if (!max_length)
- max_length = HASH_LENGTH_MAX;
-
- rv = PK11_DigestFinal(context,out,&out_length,max_length);
- PK11_DestroyContext(context, PR_TRUE);
- return rv;
-}
-
-
-/*
- * execute a bulk encryption operation
- */
-SECStatus
-PK11_CipherOp(PK11Context *context, unsigned char * out, int *outlen,
- int maxout, const unsigned char *in, int inlen)
-{
- CK_RV crv = CKR_OK;
- CK_ULONG length = maxout;
- CK_ULONG offset =0;
- SECStatus rv = SECSuccess;
- unsigned char *saveOut = out;
- unsigned char *allocOut = NULL;
-
- /* if we ran out of session, we need to restore our previously stored
- * state.
- */
- PK11_EnterContextMonitor(context);
- if (!context->ownSession) {
- rv = pk11_restoreContext(context,context->savedData,
- context->savedLength);
- if (rv != SECSuccess) {
- PK11_ExitContextMonitor(context);
- return rv;
- }
- }
-
- /*
- * The fortezza hack is to send 8 extra bytes on the first encrypted and
- * lose them on the first decrypt.
- */
- if (context->fortezzaHack) {
- unsigned char random[8];
- if (context->operation == CKA_ENCRYPT) {
- PK11_ExitContextMonitor(context);
- rv = PK11_GenerateRandom(random,sizeof(random));
- PK11_EnterContextMonitor(context);
-
- /* since we are offseting the output, we can't encrypt back into
- * the same buffer... allocate a temporary buffer just for this
- * call. */
- allocOut = out = (unsigned char*)PORT_Alloc(maxout);
- if (out == NULL) {
- PK11_ExitContextMonitor(context);
- return SECFailure;
- }
- crv = PK11_GETTAB(context->slot)->C_EncryptUpdate(context->session,
- random,sizeof(random),out,&length);
-
- out += length;
- maxout -= length;
- offset = length;
- } else if (context->operation == CKA_DECRYPT) {
- length = sizeof(random);
- crv = PK11_GETTAB(context->slot)->C_DecryptUpdate(context->session,
- (CK_BYTE_PTR)in,sizeof(random),random,&length);
- inlen -= length;
- in += length;
- context->fortezzaHack = PR_FALSE;
- }
- }
-
- switch (context->operation) {
- case CKA_ENCRYPT:
- length = maxout;
- crv=PK11_GETTAB(context->slot)->C_EncryptUpdate(context->session,
- (CK_BYTE_PTR)in, inlen,
- out, &length);
- length += offset;
- break;
- case CKA_DECRYPT:
- length = maxout;
- crv=PK11_GETTAB(context->slot)->C_DecryptUpdate(context->session,
- (CK_BYTE_PTR)in, inlen,
- out, &length);
- break;
- default:
- crv = CKR_OPERATION_NOT_INITIALIZED;
- break;
- }
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- *outlen = 0;
- rv = SECFailure;
- } else {
- *outlen = length;
- }
-
- if (context->fortezzaHack) {
- if (context->operation == CKA_ENCRYPT) {
- PORT_Assert(allocOut);
- PORT_Memcpy(saveOut, allocOut, length);
- PORT_Free(allocOut);
- }
- context->fortezzaHack = PR_FALSE;
- }
-
- /*
- * handle session starvation case.. use our last session to multiplex
- */
- if (!context->ownSession) {
- context->savedData = pk11_saveContext(context,context->savedData,
- &context->savedLength);
- if (context->savedData == NULL) rv = SECFailure;
-
- /* clear out out session for others to use */
- pk11_Finalize(context);
- }
- PK11_ExitContextMonitor(context);
- return rv;
-}
-
-/*
- * execute a digest/signature operation
- */
-SECStatus
-PK11_DigestOp(PK11Context *context, const unsigned char * in, unsigned inLen)
-{
- CK_RV crv = CKR_OK;
- SECStatus rv = SECSuccess;
-
- if (!in) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* if we ran out of session, we need to restore our previously stored
- * state.
- */
- context->init = PR_FALSE;
- PK11_EnterContextMonitor(context);
- if (!context->ownSession) {
- rv = pk11_restoreContext(context,context->savedData,
- context->savedLength);
- if (rv != SECSuccess) {
- PK11_ExitContextMonitor(context);
- return rv;
- }
- }
-
- switch (context->operation) {
- /* also for MAC'ing */
- case CKA_SIGN:
- crv=PK11_GETTAB(context->slot)->C_SignUpdate(context->session,
- (unsigned char *)in,
- inLen);
- break;
- case CKA_VERIFY:
- crv=PK11_GETTAB(context->slot)->C_VerifyUpdate(context->session,
- (unsigned char *)in,
- inLen);
- break;
- case CKA_DIGEST:
- crv=PK11_GETTAB(context->slot)->C_DigestUpdate(context->session,
- (unsigned char *)in,
- inLen);
- break;
- default:
- crv = CKR_OPERATION_NOT_INITIALIZED;
- break;
- }
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- rv = SECFailure;
- }
-
- /*
- * handle session starvation case.. use our last session to multiplex
- */
- if (!context->ownSession) {
- context->savedData = pk11_saveContext(context,context->savedData,
- &context->savedLength);
- if (context->savedData == NULL) rv = SECFailure;
-
- /* clear out out session for others to use */
- pk11_Finalize(context);
- }
- PK11_ExitContextMonitor(context);
- return rv;
-}
-
-/*
- * Digest a key if possible./
- */
-SECStatus
-PK11_DigestKey(PK11Context *context, PK11SymKey *key)
-{
- CK_RV crv = CKR_OK;
- SECStatus rv = SECSuccess;
- PK11SymKey *newKey = NULL;
-
- if (!context || !key) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* if we ran out of session, we need to restore our previously stored
- * state.
- */
- if (context->slot != key->slot) {
- newKey = pk11_CopyToSlot(context->slot,CKM_SSL3_SHA1_MAC,CKA_SIGN,key);
- } else {
- newKey = PK11_ReferenceSymKey(key);
- }
-
- context->init = PR_FALSE;
- PK11_EnterContextMonitor(context);
- if (!context->ownSession) {
- rv = pk11_restoreContext(context,context->savedData,
- context->savedLength);
- if (rv != SECSuccess) {
- PK11_ExitContextMonitor(context);
- PK11_FreeSymKey(newKey);
- return rv;
- }
- }
-
-
- if (newKey == NULL) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- if (key->data.data) {
- crv=PK11_GETTAB(context->slot)->C_DigestUpdate(context->session,
- key->data.data,key->data.len);
- }
- } else {
- crv=PK11_GETTAB(context->slot)->C_DigestKey(context->session,
- newKey->objectID);
- }
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- rv = SECFailure;
- }
-
- /*
- * handle session starvation case.. use our last session to multiplex
- */
- if (!context->ownSession) {
- context->savedData = pk11_saveContext(context,context->savedData,
- &context->savedLength);
- if (context->savedData == NULL) rv = SECFailure;
-
- /* clear out out session for others to use */
- pk11_Finalize(context);
- }
- PK11_ExitContextMonitor(context);
- if (newKey) PK11_FreeSymKey(newKey);
- return rv;
-}
-
-/*
- * externally callable version of the lowercase pk11_finalize().
- */
-SECStatus
-PK11_Finalize(PK11Context *context) {
- SECStatus rv;
-
- PK11_EnterContextMonitor(context);
- rv = pk11_Finalize(context);
- PK11_ExitContextMonitor(context);
- return rv;
-}
-
-/*
- * clean up a cipher operation, so the session can be used by
- * someone new.
- */
-SECStatus
-pk11_Finalize(PK11Context *context)
-{
- CK_ULONG count = 0;
- CK_RV crv;
- unsigned char stackBuf[256];
- unsigned char *buffer = NULL;
-
- if (!context->ownSession) {
- return SECSuccess;
- }
-
-finalize:
- switch (context->operation) {
- case CKA_ENCRYPT:
- crv=PK11_GETTAB(context->slot)->C_EncryptFinal(context->session,
- buffer, &count);
- break;
- case CKA_DECRYPT:
- crv = PK11_GETTAB(context->slot)->C_DecryptFinal(context->session,
- buffer, &count);
- break;
- case CKA_SIGN:
- crv=PK11_GETTAB(context->slot)->C_SignFinal(context->session,
- buffer, &count);
- break;
- case CKA_VERIFY:
- crv=PK11_GETTAB(context->slot)->C_VerifyFinal(context->session,
- buffer, count);
- break;
- case CKA_DIGEST:
- crv=PK11_GETTAB(context->slot)->C_DigestFinal(context->session,
- buffer, &count);
- break;
- default:
- crv = CKR_OPERATION_NOT_INITIALIZED;
- break;
- }
-
- if (crv != CKR_OK) {
- if (buffer != stackBuf) {
- PORT_Free(buffer);
- }
- if (crv == CKR_OPERATION_NOT_INITIALIZED) {
- /* if there's no operation, it is finalized */
- return SECSuccess;
- }
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
-
- /* try to finalize the session with a buffer */
- if (buffer == NULL) {
- if (count <= sizeof stackBuf) {
- buffer = stackBuf;
- } else {
- buffer = PORT_Alloc(count);
- if (buffer == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- }
- goto finalize;
- }
- if (buffer != stackBuf) {
- PORT_Free(buffer);
- }
- return SECSuccess;
-}
-
-/*
- * Return the final digested or signed data...
- * this routine can either take pre initialized data, or allocate data
- * either out of an arena or out of the standard heap.
- */
-SECStatus
-PK11_DigestFinal(PK11Context *context,unsigned char *data,
- unsigned int *outLen, unsigned int length)
-{
- CK_ULONG len;
- CK_RV crv;
- SECStatus rv;
-
-
- /* if we ran out of session, we need to restore our previously stored
- * state.
- */
- PK11_EnterContextMonitor(context);
- if (!context->ownSession) {
- rv = pk11_restoreContext(context,context->savedData,
- context->savedLength);
- if (rv != SECSuccess) {
- PK11_ExitContextMonitor(context);
- return rv;
- }
- }
-
- len = length;
- switch (context->operation) {
- case CKA_SIGN:
- crv=PK11_GETTAB(context->slot)->C_SignFinal(context->session,
- data,&len);
- break;
- case CKA_VERIFY:
- crv=PK11_GETTAB(context->slot)->C_VerifyFinal(context->session,
- data,len);
- break;
- case CKA_DIGEST:
- crv=PK11_GETTAB(context->slot)->C_DigestFinal(context->session,
- data,&len);
- break;
- case CKA_ENCRYPT:
- crv=PK11_GETTAB(context->slot)->C_EncryptFinal(context->session,
- data, &len);
- break;
- case CKA_DECRYPT:
- crv = PK11_GETTAB(context->slot)->C_DecryptFinal(context->session,
- data, &len);
- break;
- default:
- crv = CKR_OPERATION_NOT_INITIALIZED;
- break;
- }
- PK11_ExitContextMonitor(context);
-
- *outLen = (unsigned int) len;
- context->init = PR_FALSE; /* allow Begin to start up again */
-
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- return SECSuccess;
-}
-
diff --git a/security/nss/lib/pk11wrap/pk11err.c b/security/nss/lib/pk11wrap/pk11err.c
deleted file mode 100644
index 7d9ab92f6..000000000
--- a/security/nss/lib/pk11wrap/pk11err.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * this file maps PKCS11 Errors into SECErrors
- * This is an information reducing process, since most errors are reflected
- * back to the user (the user doesn't care about invalid flags, or active
- * operations). If any of these errors need more detail in the upper layers
- * which call PK11 library functions, we can add more SEC_ERROR_XXX functions
- * and change there mappings here.
- *
- * Some PKCS11 errors are mapped to SEC_ERROR_LIBRARY_FAILURE intentionally
- * because they indicate that there is a bug in the library (either NSS or
- * the token).
- */
-#include "pkcs11t.h"
-#include "pk11func.h"
-#include "secerr.h"
-#include "prerror.h"
-
-#ifdef PK11_ERROR_USE_ARRAY
-
-/*
- * build a static array of entries...
- */
-static struct {
- CK_RV pk11_error;
- int sec_error;
-} pk11_error_map = {
-#define MAPERROR(x,y) {x, y},
-
-#else
-
-/* the default is to use a big switch statement */
-int
-PK11_MapError(CK_RV rv) {
-
- switch (rv) {
-#define MAPERROR(x,y) case x: return y;
-
-#endif
-
-/* the guts mapping */
- MAPERROR(CKR_OK, 0)
- MAPERROR(CKR_CANCEL, SEC_ERROR_IO)
- MAPERROR(CKR_HOST_MEMORY, SEC_ERROR_NO_MEMORY)
- MAPERROR(CKR_SLOT_ID_INVALID, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_ARGUMENTS_BAD, SEC_ERROR_INVALID_ARGS)
- MAPERROR(CKR_ATTRIBUTE_READ_ONLY, SEC_ERROR_READ_ONLY)
- MAPERROR(CKR_ATTRIBUTE_SENSITIVE, SEC_ERROR_IO) /* XX SENSITIVE */
- MAPERROR(CKR_ATTRIBUTE_TYPE_INVALID, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_ATTRIBUTE_VALUE_INVALID, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_BUFFER_TOO_SMALL, SEC_ERROR_OUTPUT_LEN)
- MAPERROR(CKR_DATA_INVALID, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_DATA_LEN_RANGE, SEC_ERROR_INPUT_LEN)
- MAPERROR(CKR_DEVICE_ERROR, SEC_ERROR_PKCS11_DEVICE_ERROR)
- MAPERROR(CKR_DEVICE_MEMORY, SEC_ERROR_NO_MEMORY)
- MAPERROR(CKR_DEVICE_REMOVED, SEC_ERROR_NO_TOKEN)
- MAPERROR(CKR_DOMAIN_PARAMS_INVALID, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_ENCRYPTED_DATA_INVALID, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_ENCRYPTED_DATA_LEN_RANGE, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_FUNCTION_CANCELED, SEC_ERROR_LIBRARY_FAILURE)
- MAPERROR(CKR_FUNCTION_FAILED, SEC_ERROR_PKCS11_FUNCTION_FAILED)
- MAPERROR(CKR_FUNCTION_NOT_PARALLEL, SEC_ERROR_LIBRARY_FAILURE)
- MAPERROR(CKR_FUNCTION_NOT_SUPPORTED, PR_NOT_IMPLEMENTED_ERROR)
- MAPERROR(CKR_GENERAL_ERROR, SEC_ERROR_PKCS11_GENERAL_ERROR)
- MAPERROR(CKR_KEY_HANDLE_INVALID, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_MECHANISM_INVALID, SEC_ERROR_INVALID_ALGORITHM)
- MAPERROR(CKR_MECHANISM_PARAM_INVALID, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_NO_EVENT, SEC_ERROR_NO_EVENT)
- MAPERROR(CKR_OBJECT_HANDLE_INVALID, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_OPERATION_ACTIVE, SEC_ERROR_LIBRARY_FAILURE)
- MAPERROR(CKR_OPERATION_NOT_INITIALIZED,SEC_ERROR_LIBRARY_FAILURE )
- MAPERROR(CKR_PIN_INCORRECT, SEC_ERROR_BAD_PASSWORD)
- MAPERROR(CKR_PIN_INVALID, SEC_ERROR_INVALID_PASSWORD)
- MAPERROR(CKR_PIN_LEN_RANGE, SEC_ERROR_INVALID_PASSWORD)
- MAPERROR(CKR_PIN_EXPIRED, SEC_ERROR_EXPIRED_PASSWORD)
- MAPERROR(CKR_PIN_LOCKED, SEC_ERROR_LOCKED_PASSWORD)
- MAPERROR(CKR_SESSION_CLOSED, SEC_ERROR_LIBRARY_FAILURE)
- MAPERROR(CKR_SESSION_COUNT, SEC_ERROR_NO_MEMORY) /* XXXX? */
- MAPERROR(CKR_SESSION_HANDLE_INVALID, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_SESSION_PARALLEL_NOT_SUPPORTED, SEC_ERROR_LIBRARY_FAILURE)
- MAPERROR(CKR_SESSION_READ_ONLY, SEC_ERROR_READ_ONLY)
- MAPERROR(CKR_SIGNATURE_INVALID, SEC_ERROR_BAD_SIGNATURE)
- MAPERROR(CKR_SIGNATURE_LEN_RANGE, SEC_ERROR_BAD_SIGNATURE)
- MAPERROR(CKR_TEMPLATE_INCOMPLETE, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_TEMPLATE_INCONSISTENT, SEC_ERROR_BAD_DATA)
- MAPERROR(CKR_TOKEN_NOT_PRESENT, SEC_ERROR_NO_TOKEN)
- MAPERROR(CKR_TOKEN_NOT_RECOGNIZED, SEC_ERROR_IO)
- MAPERROR(CKR_TOKEN_WRITE_PROTECTED, SEC_ERROR_READ_ONLY)
- MAPERROR(CKR_UNWRAPPING_KEY_HANDLE_INVALID, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_UNWRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_USER_ALREADY_LOGGED_IN, 0)
- MAPERROR(CKR_USER_NOT_LOGGED_IN, SEC_ERROR_TOKEN_NOT_LOGGED_IN)
- MAPERROR(CKR_USER_PIN_NOT_INITIALIZED, SEC_ERROR_NO_TOKEN)
- MAPERROR(CKR_USER_TYPE_INVALID, SEC_ERROR_LIBRARY_FAILURE)
- MAPERROR(CKR_WRAPPED_KEY_INVALID, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_WRAPPED_KEY_LEN_RANGE, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_WRAPPING_KEY_HANDLE_INVALID, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_WRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_WRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY)
- MAPERROR(CKR_VENDOR_DEFINED, SEC_ERROR_LIBRARY_FAILURE)
- MAPERROR(CKR_NETSCAPE_CERTDB_FAILED, SEC_ERROR_BAD_DATABASE)
- MAPERROR(CKR_NETSCAPE_KEYDB_FAILED, SEC_ERROR_BAD_DATABASE)
- MAPERROR(CKR_CANT_LOCK, SEC_ERROR_INCOMPATIBLE_PKCS11)
-
-#ifdef PK11_ERROR_USE_ARRAY
-};
-
-int
-PK11_MapError(CK_RV rv) {
- int size = sizeof(pk11_error_map)/sizeof(pk11_error_map[0]);
-
- for (i=0; i < size; i++) {
- if (pk11_error_map[i].pk11_error == rv) {
- return pk11_error_map[i].sec_error;
- }
- }
- return SEC_ERROR_UNKNOWN_PKCS11_ERROR;
- }
-
-
-#else
-
- default:
- break;
- }
- return SEC_ERROR_UNKNOWN_PKCS11_ERROR;
-}
-
-
-#endif
diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h
deleted file mode 100644
index 331c0eb80..000000000
--- a/security/nss/lib/pk11wrap/pk11func.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _PK11FUNC_H_
-#define _PK11FUNC_H_
-
-/*
- * The original pk11func.h had a mix of public and private functions.
- * Continue to provide those for backward compatibility. New code should
- * include pk11pub.h instead of pk11func.h.
- */
-#include "pk11pub.h"
-#include "pk11priv.h"
-
-#endif
diff --git a/security/nss/lib/pk11wrap/pk11kea.c b/security/nss/lib/pk11wrap/pk11kea.c
deleted file mode 100644
index a7dd4fbbc..000000000
--- a/security/nss/lib/pk11wrap/pk11kea.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file implements the Symkey wrapper and the PKCS context
- * Interfaces.
- */
-
-#include "seccomon.h"
-#include "secmod.h"
-#include "nssilock.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11.h"
-#include "pk11func.h"
-#include "secitem.h"
-#include "key.h"
-#include "secasn1.h"
-#include "sechash.h"
-#include "cert.h"
-#include "secerr.h"
-
-/*
- * find an RSA public key on a card
- */
-static CK_OBJECT_HANDLE
-pk11_FindRSAPubKey(PK11SlotInfo *slot)
-{
- CK_KEY_TYPE key_type = CKK_RSA;
- CK_OBJECT_CLASS class_type = CKO_PUBLIC_KEY;
- CK_ATTRIBUTE theTemplate[2];
- int template_count = sizeof(theTemplate)/sizeof(theTemplate[0]);
- CK_ATTRIBUTE *attrs = theTemplate;
-
- PK11_SETATTRS(attrs,CKA_CLASS,&class_type,sizeof(class_type)); attrs++;
- PK11_SETATTRS(attrs,CKA_KEY_TYPE,&key_type,sizeof(key_type)); attrs++;
- template_count = attrs - theTemplate;
- PR_ASSERT(template_count <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE));
-
- return pk11_FindObjectByTemplate(slot,theTemplate,template_count);
-}
-
-PK11SymKey *
-pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
- CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags,
- PRBool isPerm, PK11SymKey *symKey)
-{
- PK11SymKey *newSymKey = NULL;
- SECStatus rv;
- /* performance improvement can go here --- use a generated key at startup
- * to generate a per token wrapping key. If it exists, use it, otherwise
- * do a full key exchange. */
-
- /* find a common Key Exchange algorithm */
- /* RSA */
- if (PK11_DoesMechanism(symKey->slot, CKM_RSA_PKCS) &&
- PK11_DoesMechanism(slot,CKM_RSA_PKCS)) {
- CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_HANDLE;
- CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_HANDLE;
- SECKEYPublicKey *pubKey = NULL;
- SECKEYPrivateKey *privKey = NULL;
- SECItem wrapData;
- unsigned int symKeyLength = PK11_GetKeyLength(symKey);
-
- wrapData.data = NULL;
-
- /* find RSA Public Key on target */
- pubKeyHandle = pk11_FindRSAPubKey(slot);
- if (pubKeyHandle != CK_INVALID_HANDLE) {
- privKeyHandle = PK11_MatchItem(slot,pubKeyHandle,CKO_PRIVATE_KEY);
- }
-
- /* if no key exists, generate a key pair */
- if (privKeyHandle == CK_INVALID_HANDLE) {
- PK11RSAGenParams rsaParams;
-
- if (symKeyLength > 53) /* bytes */ {
- /* we'd have to generate an RSA key pair > 512 bits long,
- ** and that's too costly. Don't even try.
- */
- PORT_SetError( SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY );
- goto rsa_failed;
- }
- rsaParams.keySizeInBits =
- (symKeyLength > 21 || symKeyLength == 0) ? 512 : 256;
- rsaParams.pe = 0x10001;
- privKey = PK11_GenerateKeyPair(slot,CKM_RSA_PKCS_KEY_PAIR_GEN,
- &rsaParams, &pubKey,PR_FALSE,PR_TRUE,symKey->cx);
- } else {
- /* if keys exist, build SECKEY data structures for them */
- privKey = PK11_MakePrivKey(slot,nullKey, PR_TRUE, privKeyHandle,
- symKey->cx);
- if (privKey != NULL) {
- pubKey = PK11_ExtractPublicKey(slot, rsaKey, pubKeyHandle);
- if (pubKey && pubKey->pkcs11Slot) {
- PK11_FreeSlot(pubKey->pkcs11Slot);
- pubKey->pkcs11Slot = NULL;
- pubKey->pkcs11ID = CK_INVALID_HANDLE;
- }
- }
- }
- if (privKey == NULL) goto rsa_failed;
- if (pubKey == NULL) goto rsa_failed;
-
- wrapData.len = SECKEY_PublicKeyStrength(pubKey);
- if (!wrapData.len) goto rsa_failed;
- wrapData.data = PORT_Alloc(wrapData.len);
- if (wrapData.data == NULL) goto rsa_failed;
-
- /* now wrap the keys in and out */
- rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, pubKey, symKey, &wrapData);
- if (rv == SECSuccess) {
- newSymKey = PK11_PubUnwrapSymKeyWithFlagsPerm(privKey,
- &wrapData,type,operation,symKeyLength,flags,isPerm);
- /* make sure we wound up where we wanted to be! */
- if (newSymKey && newSymKey->slot != slot) {
- PK11_FreeSymKey(newSymKey);
- newSymKey = NULL;
- }
- }
-rsa_failed:
- if (wrapData.data != NULL) PORT_Free(wrapData.data);
- if (privKey != NULL) SECKEY_DestroyPrivateKey(privKey);
- if (pubKey != NULL) SECKEY_DestroyPublicKey(pubKey);
-
- return newSymKey;
- }
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
-}
-
diff --git a/security/nss/lib/pk11wrap/pk11list.c b/security/nss/lib/pk11wrap/pk11list.c
deleted file mode 100644
index 9e324821f..000000000
--- a/security/nss/lib/pk11wrap/pk11list.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Locking and queue management primatives
- *
- */
-
-#include "seccomon.h"
-#include "nssilock.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "nssrwlk.h"
-
-/*
- * create a new lock for a Module List
- */
-SECMODListLock *SECMOD_NewListLock()
-{
- return NSSRWLock_New( 10, "moduleListLock");
-}
-
-/*
- * destroy the lock
- */
-void SECMOD_DestroyListLock(SECMODListLock *lock)
-{
- NSSRWLock_Destroy(lock);
-}
-
-
-/*
- * Lock the List for Read: NOTE: this assumes the reading isn't so common
- * the writing will be starved.
- */
-void SECMOD_GetReadLock(SECMODListLock *modLock)
-{
- NSSRWLock_LockRead(modLock);
-}
-
-/*
- * Release the Read lock
- */
-void SECMOD_ReleaseReadLock(SECMODListLock *modLock)
-{
- NSSRWLock_UnlockRead(modLock);
-}
-
-
-/*
- * lock the list for Write
- */
-void SECMOD_GetWriteLock(SECMODListLock *modLock)
-{
- NSSRWLock_LockWrite(modLock);
-}
-
-
-/*
- * Release the Write Lock: NOTE, this code is pretty inefficient if you have
- * lots of write collisions.
- */
-void SECMOD_ReleaseWriteLock(SECMODListLock *modLock)
-{
- NSSRWLock_UnlockWrite(modLock);
-}
-
-
-/*
- * must Hold the Write lock
- */
-void
-SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child)
-{
- *parent = child->next;
- child->next = NULL;
-}
-
-/*
- * if lock is not specified, it must already be held
- */
-void
-SECMOD_AddList(SECMODModuleList *parent, SECMODModuleList *child,
- SECMODListLock *lock)
-{
- if (lock) { SECMOD_GetWriteLock(lock); }
-
- child->next = parent->next;
- parent->next = child;
-
- if (lock) { SECMOD_ReleaseWriteLock(lock); }
-}
-
-
diff --git a/security/nss/lib/pk11wrap/pk11load.c b/security/nss/lib/pk11wrap/pk11load.c
deleted file mode 100644
index e1e764b16..000000000
--- a/security/nss/lib/pk11wrap/pk11load.c
+++ /dev/null
@@ -1,600 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * The following handles the loading, unloading and management of
- * various PCKS #11 modules
- */
-#define FORCE_PR_LOG 1
-#include "seccomon.h"
-#include "pkcs11.h"
-#include "secmod.h"
-#include "prlink.h"
-#include "pk11func.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "nssilock.h"
-#include "secerr.h"
-#include "prenv.h"
-#include "utilparst.h"
-
-#define DEBUG_MODULE 1
-
-#ifdef DEBUG_MODULE
-static char *modToDBG = NULL;
-
-#include "debug_module.c"
-#endif
-
-/* build the PKCS #11 2.01 lock files */
-CK_RV PR_CALLBACK secmodCreateMutext(CK_VOID_PTR_PTR pmutex) {
- *pmutex = (CK_VOID_PTR) PZ_NewLock(nssILockOther);
- if ( *pmutex ) return CKR_OK;
- return CKR_HOST_MEMORY;
-}
-
-CK_RV PR_CALLBACK secmodDestroyMutext(CK_VOID_PTR mutext) {
- PZ_DestroyLock((PZLock *)mutext);
- return CKR_OK;
-}
-
-CK_RV PR_CALLBACK secmodLockMutext(CK_VOID_PTR mutext) {
- PZ_Lock((PZLock *)mutext);
- return CKR_OK;
-}
-
-CK_RV PR_CALLBACK secmodUnlockMutext(CK_VOID_PTR mutext) {
- PZ_Unlock((PZLock *)mutext);
- return CKR_OK;
-}
-
-static SECMODModuleID nextModuleID = 1;
-static const CK_C_INITIALIZE_ARGS secmodLockFunctions = {
- secmodCreateMutext, secmodDestroyMutext, secmodLockMutext,
- secmodUnlockMutext, CKF_LIBRARY_CANT_CREATE_OS_THREADS|
- CKF_OS_LOCKING_OK
- ,NULL
-};
-
-static PRBool loadSingleThreadedModules = PR_TRUE;
-static PRBool enforceAlreadyInitializedError = PR_TRUE;
-static PRBool finalizeModules = PR_TRUE;
-
-/* set global options for NSS PKCS#11 module loader */
-SECStatus pk11_setGlobalOptions(PRBool noSingleThreadedModules,
- PRBool allowAlreadyInitializedModules,
- PRBool dontFinalizeModules)
-{
- if (noSingleThreadedModules) {
- loadSingleThreadedModules = PR_FALSE;
- } else {
- loadSingleThreadedModules = PR_TRUE;
- }
- if (allowAlreadyInitializedModules) {
- enforceAlreadyInitializedError = PR_FALSE;
- } else {
- enforceAlreadyInitializedError = PR_TRUE;
- }
- if (dontFinalizeModules) {
- finalizeModules = PR_FALSE;
- } else {
- finalizeModules = PR_TRUE;
- }
- return SECSuccess;
-}
-
-PRBool pk11_getFinalizeModulesOption(void)
-{
- return finalizeModules;
-}
-
-/*
- * Allow specification loading the same module more than once at init time.
- * This enables 2 things.
- *
- * 1) we can load additional databases by manipulating secmod.db/pkcs11.txt.
- * 2) we can handle the case where some library has already initialized NSS
- * before the main application.
- *
- * oldModule is the module we have already initialized.
- * char *modulespec is the full module spec for the library we want to
- * initialize.
- */
-static SECStatus
-secmod_handleReload(SECMODModule *oldModule, SECMODModule *newModule)
-{
- PK11SlotInfo *slot;
- char *modulespec;
- char *newModuleSpec;
- char **children;
- CK_SLOT_ID *ids;
- SECMODConfigList *conflist = NULL;
- SECStatus rv = SECFailure;
- int count = 0;
-
- /* first look for tokens= key words from the module spec */
- modulespec = newModule->libraryParams;
- newModuleSpec = secmod_ParseModuleSpecForTokens(PR_TRUE,
- newModule->isFIPS, modulespec, &children, &ids);
- if (!newModuleSpec) {
- return SECFailure;
- }
-
- /*
- * We are now trying to open a new slot on an already loaded module.
- * If that slot represents a cert/key database, we don't want to open
- * multiple copies of that same database. Unfortunately we understand
- * the softoken flags well enough to be able to do this, so we can only get
- * the list of already loaded databases if we are trying to open another
- * internal module.
- */
- if (oldModule->internal) {
- conflist = secmod_GetConfigList(oldModule->isFIPS,
- oldModule->libraryParams, &count);
- }
-
-
- /* don't open multiple of the same db */
- if (conflist && secmod_MatchConfigList(newModuleSpec, conflist, count)) {
- rv = SECSuccess;
- goto loser;
- }
- slot = SECMOD_OpenNewSlot(oldModule, newModuleSpec);
- if (slot) {
- int newID;
- char **thisChild;
- CK_SLOT_ID *thisID;
- char *oldModuleSpec;
-
- if (secmod_IsInternalKeySlot(newModule)) {
- pk11_SetInternalKeySlotIfFirst(slot);
- }
- newID = slot->slotID;
- PK11_FreeSlot(slot);
- for (thisChild=children, thisID=ids; thisChild && *thisChild;
- thisChild++,thisID++) {
- if (conflist &&
- secmod_MatchConfigList(*thisChild, conflist, count)) {
- *thisID = (CK_SLOT_ID) -1;
- continue;
- }
- slot = SECMOD_OpenNewSlot(oldModule, *thisChild);
- if (slot) {
- *thisID = slot->slotID;
- PK11_FreeSlot(slot);
- } else {
- *thisID = (CK_SLOT_ID) -1;
- }
- }
-
- /* update the old module initialization string in case we need to
- * shutdown and reinit the whole mess (this is rare, but can happen
- * when trying to stop smart card insertion/removal threads)... */
- oldModuleSpec = secmod_MkAppendTokensList(oldModule->arena,
- oldModule->libraryParams, newModuleSpec, newID,
- children, ids);
- if (oldModuleSpec) {
- oldModule->libraryParams = oldModuleSpec;
- }
-
- rv = SECSuccess;
- }
-
-loser:
- secmod_FreeChildren(children, ids);
- PORT_Free(newModuleSpec);
- if (conflist) {
- secmod_FreeConfigList(conflist, count);
- }
- return rv;
-}
-
-/*
- * collect the steps we need to initialize a module in a single function
- */
-SECStatus
-secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
- PRBool* alreadyLoaded)
-{
- CK_C_INITIALIZE_ARGS moduleArgs;
- CK_VOID_PTR pInitArgs;
- CK_RV crv;
-
- if (reload) {
- *reload = NULL;
- }
-
- if (!mod || !alreadyLoaded) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (mod->isThreadSafe == PR_FALSE) {
- pInitArgs = NULL;
- } else if (mod->libraryParams == NULL) {
- pInitArgs = (void *) &secmodLockFunctions;
- } else {
- moduleArgs = secmodLockFunctions;
- moduleArgs.LibraryParameters = (void *) mod->libraryParams;
- pInitArgs = &moduleArgs;
- }
- crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
- if (CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) {
- SECMODModule *oldModule = NULL;
-
- /* Library has already been loaded once, if caller expects it, and it
- * has additional configuration, try reloading it as well. */
- if (reload != NULL && mod->libraryParams) {
- oldModule = secmod_FindModuleByFuncPtr(mod->functionList);
- }
- /* Library has been loaded by NSS. It means it may be capable of
- * reloading */
- if (oldModule) {
- SECStatus rv;
- rv = secmod_handleReload(oldModule, mod);
- if (rv == SECSuccess) {
- /* This module should go away soon, since we've
- * simply expanded the slots on the old module.
- * When it goes away, it should not Finalize since
- * that will close our old module as well. Setting
- * the function list to NULL will prevent that close */
- mod->functionList = NULL;
- *reload = oldModule;
- return SECSuccess;
- }
- SECMOD_DestroyModule(oldModule);
- }
- /* reload not possible, fall back to old semantics */
- if (!enforceAlreadyInitializedError) {
- *alreadyLoaded = PR_TRUE;
- return SECSuccess;
- }
- }
- if (crv != CKR_OK) {
- if (pInitArgs == NULL ||
- crv == CKR_NETSCAPE_CERTDB_FAILED ||
- crv == CKR_NETSCAPE_KEYDB_FAILED) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- if (!loadSingleThreadedModules) {
- PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
- return SECFailure;
- }
- mod->isThreadSafe = PR_FALSE;
- crv = PK11_GETTAB(mod)->C_Initialize(NULL);
- if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) &&
- (!enforceAlreadyInitializedError)) {
- *alreadyLoaded = PR_TRUE;
- return SECSuccess;
- }
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- }
- return SECSuccess;
-}
-
-/*
- * set the hasRootCerts flags in the module so it can be stored back
- * into the database.
- */
-void
-SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod) {
- PK11PreSlotInfo *psi = NULL;
- int i;
-
- if (slot->hasRootCerts) {
- for (i=0; i < mod->slotInfoCount; i++) {
- if (slot->slotID == mod->slotInfo[i].slotID) {
- psi = &mod->slotInfo[i];
- break;
- }
- }
- if (psi == NULL) {
- /* allocate more slots */
- PK11PreSlotInfo *psi_list = (PK11PreSlotInfo *)
- PORT_ArenaAlloc(mod->arena,
- (mod->slotInfoCount+1)* sizeof(PK11PreSlotInfo));
- /* copy the old ones */
- if (mod->slotInfoCount > 0) {
- PORT_Memcpy(psi_list,mod->slotInfo,
- (mod->slotInfoCount)*sizeof(PK11PreSlotInfo));
- }
- /* assign psi to the last new slot */
- psi = &psi_list[mod->slotInfoCount];
- psi->slotID = slot->slotID;
- psi->askpw = 0;
- psi->timeout = 0;
- psi ->defaultFlags = 0;
-
- /* increment module count & store new list */
- mod->slotInfo = psi_list;
- mod->slotInfoCount++;
-
- }
- psi->hasRootCerts = 1;
- }
-}
-
-static const char* my_shlib_name =
- SHLIB_PREFIX"nss"SHLIB_VERSION"."SHLIB_SUFFIX;
-static const char* softoken_shlib_name =
- SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX;
-static const PRCallOnceType pristineCallOnce;
-static PRCallOnceType loadSoftokenOnce;
-static PRLibrary* softokenLib;
-static PRInt32 softokenLoadCount;
-
-#include "prio.h"
-#include "prprf.h"
-#include <stdio.h>
-#include "prsystem.h"
-
-/* This function must be run only once. */
-/* determine if hybrid platform, then actually load the DSO. */
-static PRStatus
-softoken_LoadDSO( void )
-{
- PRLibrary * handle;
-
- handle = PORT_LoadLibraryFromOrigin(my_shlib_name,
- (PRFuncPtr) &softoken_LoadDSO,
- softoken_shlib_name);
- if (handle) {
- softokenLib = handle;
- return PR_SUCCESS;
- }
- return PR_FAILURE;
-}
-
-/*
- * load a new module into our address space and initialize it.
- */
-SECStatus
-secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) {
- PRLibrary *library = NULL;
- CK_C_GetFunctionList entry = NULL;
- CK_INFO info;
- CK_ULONG slotCount = 0;
- SECStatus rv;
- PRBool alreadyLoaded = PR_FALSE;
- char *disableUnload = NULL;
-
- if (mod->loaded) return SECSuccess;
-
- /* intenal modules get loaded from their internal list */
- if (mod->internal && (mod->dllName == NULL)) {
- /*
- * Loads softoken as a dynamic library,
- * even though the rest of NSS assumes this as the "internal" module.
- */
- if (!softokenLib &&
- PR_SUCCESS != PR_CallOnce(&loadSoftokenOnce, &softoken_LoadDSO))
- return SECFailure;
-
- PR_ATOMIC_INCREMENT(&softokenLoadCount);
-
- if (mod->isFIPS) {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "FC_GetFunctionList");
- } else {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
- }
-
- if (!entry)
- return SECFailure;
-
- if (mod->isModuleDB) {
- mod->moduleDBFunc = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
- }
-
- if (mod->moduleDBOnly) {
- mod->loaded = PR_TRUE;
- return SECSuccess;
- }
- } else {
- /* Not internal, load the DLL and look up C_GetFunctionList */
- if (mod->dllName == NULL) {
- return SECFailure;
- }
-
- /* load the library. If this succeeds, then we have to remember to
- * unload the library if anything goes wrong from here on out...
- */
- library = PR_LoadLibrary(mod->dllName);
- mod->library = (void *)library;
-
- if (library == NULL) {
- return SECFailure;
- }
-
- /*
- * now we need to get the entry point to find the function pointers
- */
- if (!mod->moduleDBOnly) {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(library, "C_GetFunctionList");
- }
- if (mod->isModuleDB) {
- mod->moduleDBFunc = (void *)
- PR_FindSymbol(library, "NSS_ReturnModuleSpecData");
- }
- if (mod->moduleDBFunc == NULL) mod->isModuleDB = PR_FALSE;
- if (entry == NULL) {
- if (mod->isModuleDB) {
- mod->loaded = PR_TRUE;
- mod->moduleDBOnly = PR_TRUE;
- return SECSuccess;
- }
- PR_UnloadLibrary(library);
- return SECFailure;
- }
- }
-
- /*
- * We need to get the function list
- */
- if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
- goto fail;
-
-#ifdef DEBUG_MODULE
- if (PR_TRUE) {
- modToDBG = PR_GetEnv("NSS_DEBUG_PKCS11_MODULE");
- if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
- mod->functionList = (void *)nss_InsertDeviceLog(
- (CK_FUNCTION_LIST_PTR)mod->functionList);
- }
- }
-#endif
-
- mod->isThreadSafe = PR_TRUE;
-
- /* Now we initialize the module */
- rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
- if (rv != SECSuccess) {
- goto fail;
- }
-
- /* module has been reloaded, this module itself is done,
- * return to the caller */
- if (mod->functionList == NULL) {
- mod->loaded = PR_TRUE; /* technically the module is loaded.. */
- return SECSuccess;
- }
-
- /* check the version number */
- if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2;
- if (info.cryptokiVersion.major != 2) goto fail2;
- /* all 2.0 are a priori *not* thread safe */
- if (info.cryptokiVersion.minor < 1) {
- if (!loadSingleThreadedModules) {
- PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
- goto fail2;
- } else {
- mod->isThreadSafe = PR_FALSE;
- }
- }
- mod->cryptokiVersion = info.cryptokiVersion;
-
- /* If we don't have a common name, get it from the PKCS 11 module */
- if ((mod->commonName == NULL) || (mod->commonName[0] == 0)) {
- mod->commonName = PK11_MakeString(mod->arena,NULL,
- (char *)info.libraryDescription, sizeof(info.libraryDescription));
- if (mod->commonName == NULL) goto fail2;
- }
-
-
- /* initialize the Slots */
- if (PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, NULL, &slotCount) == CKR_OK) {
- CK_SLOT_ID *slotIDs;
- int i;
- CK_RV crv;
-
- mod->slots = (PK11SlotInfo **)PORT_ArenaAlloc(mod->arena,
- sizeof(PK11SlotInfo *) * slotCount);
- if (mod->slots == NULL) goto fail2;
-
- slotIDs = (CK_SLOT_ID *) PORT_Alloc(sizeof(CK_SLOT_ID)*slotCount);
- if (slotIDs == NULL) {
- goto fail2;
- }
- crv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount);
- if (crv != CKR_OK) {
- PORT_Free(slotIDs);
- goto fail2;
- }
-
- /* Initialize each slot */
- for (i=0; i < (int)slotCount; i++) {
- mod->slots[i] = PK11_NewSlotInfo(mod);
- PK11_InitSlot(mod,slotIDs[i],mod->slots[i]);
- /* look down the slot info table */
- PK11_LoadSlotList(mod->slots[i],mod->slotInfo,mod->slotInfoCount);
- SECMOD_SetRootCerts(mod->slots[i],mod);
- /* explicitly mark the internal slot as such if IsInternalKeySlot()
- * is set */
- if (secmod_IsInternalKeySlot(mod) && (i == (mod->isFIPS ? 0 : 1))) {
- pk11_SetInternalKeySlotIfFirst(mod->slots[i]);
- }
- }
- mod->slotCount = slotCount;
- mod->slotInfoCount = 0;
- PORT_Free(slotIDs);
- }
-
- mod->loaded = PR_TRUE;
- mod->moduleID = nextModuleID++;
- return SECSuccess;
-fail2:
- if (enforceAlreadyInitializedError || (!alreadyLoaded)) {
- PK11_GETTAB(mod)->C_Finalize(NULL);
- }
-fail:
- mod->functionList = NULL;
- disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
- if (library && !disableUnload) {
- PR_UnloadLibrary(library);
- }
- return SECFailure;
-}
-
-SECStatus
-SECMOD_UnloadModule(SECMODModule *mod) {
- PRLibrary *library;
- char *disableUnload = NULL;
-
- if (!mod->loaded) {
- return SECFailure;
- }
- if (finalizeModules) {
- if (mod->functionList &&!mod->moduleDBOnly) {
- PK11_GETTAB(mod)->C_Finalize(NULL);
- }
- }
- mod->moduleID = 0;
- mod->loaded = PR_FALSE;
-
- /* do we want the semantics to allow unloading the internal library?
- * if not, we should change this to SECFailure and move it above the
- * mod->loaded = PR_FALSE; */
- if (mod->internal && (mod->dllName == NULL)) {
- if (0 == PR_ATOMIC_DECREMENT(&softokenLoadCount)) {
- if (softokenLib) {
- disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
- if (!disableUnload) {
- PRStatus status = PR_UnloadLibrary(softokenLib);
- PORT_Assert(PR_SUCCESS == status);
- }
- softokenLib = NULL;
- }
- loadSoftokenOnce = pristineCallOnce;
- }
- return SECSuccess;
- }
-
- library = (PRLibrary *)mod->library;
- /* paranoia */
- if (library == NULL) {
- return SECFailure;
- }
-
- disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
- if (!disableUnload) {
- PR_UnloadLibrary(library);
- }
- return SECSuccess;
-}
-
-void
-nss_DumpModuleLog(void)
-{
-#ifdef DEBUG_MODULE
- if (modToDBG) {
- print_final_statistics();
- }
-#endif
-}
diff --git a/security/nss/lib/pk11wrap/pk11mech.c b/security/nss/lib/pk11wrap/pk11mech.c
deleted file mode 100644
index 901a7e87e..000000000
--- a/security/nss/lib/pk11wrap/pk11mech.c
+++ /dev/null
@@ -1,1872 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file maps various PKCS #11 Mechanisms to related mechanisms, key
- * types, and ASN.1 encodings.
- */
-#include "seccomon.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "pkcs11t.h"
-#include "pk11func.h"
-#include "secitem.h"
-#include "secder.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "secerr.h"
-
-/*************************************************************
- * local static and global data
- *************************************************************/
-
-/*
- * Tables used for Extended mechanism mapping (currently not used)
- */
-typedef struct {
- CK_MECHANISM_TYPE keyGen;
- CK_KEY_TYPE keyType;
- CK_MECHANISM_TYPE type;
- CK_MECHANISM_TYPE padType;
- int blockSize;
- int iv;
-} pk11MechanismData;
-
-static pk11MechanismData pk11_default =
- { CKM_GENERIC_SECRET_KEY_GEN, CKK_GENERIC_SECRET,
- CKM_FAKE_RANDOM, CKM_FAKE_RANDOM, 8, 8 };
-static pk11MechanismData *pk11_MechanismTable = NULL;
-static int pk11_MechTableSize = 0;
-static int pk11_MechEntrySize = 0;
-
-/*
- * list of mechanisms we're willing to wrap secret keys with.
- * This list is ordered by preference.
- */
-CK_MECHANISM_TYPE wrapMechanismList[] = {
- CKM_DES3_ECB,
- CKM_CAST5_ECB,
- CKM_AES_ECB,
- CKM_CAMELLIA_ECB,
- CKM_SEED_ECB,
- CKM_CAST5_ECB,
- CKM_DES_ECB,
- CKM_KEY_WRAP_LYNKS,
- CKM_IDEA_ECB,
- CKM_CAST3_ECB,
- CKM_CAST_ECB,
- CKM_RC5_ECB,
- CKM_RC2_ECB,
- CKM_CDMF_ECB,
- CKM_SKIPJACK_WRAP,
-};
-
-int wrapMechanismCount = sizeof(wrapMechanismList)/sizeof(wrapMechanismList[0]);
-
-/*********************************************************************
- * Mechanism Mapping functions
- *********************************************************************/
-
-/*
- * lookup an entry in the mechanism table. If none found, return the
- * default structure.
- */
-static pk11MechanismData *
-pk11_lookup(CK_MECHANISM_TYPE type)
-{
- int i;
- for (i=0; i < pk11_MechEntrySize; i++) {
- if (pk11_MechanismTable[i].type == type) {
- return (&pk11_MechanismTable[i]);
- }
- }
- return &pk11_default;
-}
-
-/*
- * find the best key wrap mechanism for this slot.
- */
-CK_MECHANISM_TYPE
-PK11_GetBestWrapMechanism(PK11SlotInfo *slot)
-{
- int i;
- for (i=0; i < wrapMechanismCount; i++) {
- if (PK11_DoesMechanism(slot,wrapMechanismList[i])) {
- return wrapMechanismList[i];
- }
- }
- return CKM_INVALID_MECHANISM;
-}
-
-/*
- * NOTE: This is not thread safe. Called at init time, and when loading
- * a new Entry. It is reasonably safe as long as it is not re-entered
- * (readers will always see a consistant table)
- *
- * This routine is called to add entries to the mechanism table, once there,
- * they can not be removed.
- */
-void
-PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
- CK_MECHANISM_TYPE keyGen,
- CK_MECHANISM_TYPE padType,
- int ivLen, int blockSize)
-{
- int tableSize = pk11_MechTableSize;
- int size = pk11_MechEntrySize;
- int entry = size++;
- pk11MechanismData *old = pk11_MechanismTable;
- pk11MechanismData *newt = pk11_MechanismTable;
-
-
- if (size > tableSize) {
- int oldTableSize = tableSize;
- tableSize += 10;
- newt = PORT_NewArray(pk11MechanismData, tableSize);
- if (newt == NULL) return;
-
- if (old) PORT_Memcpy(newt, old, oldTableSize*sizeof(*newt));
- } else old = NULL;
-
- newt[entry].type = type;
- newt[entry].keyType = key;
- newt[entry].keyGen = keyGen;
- newt[entry].padType = padType;
- newt[entry].iv = ivLen;
- newt[entry].blockSize = blockSize;
-
- pk11_MechanismTable = newt;
- pk11_MechTableSize = tableSize;
- pk11_MechEntrySize = size;
- if (old) PORT_Free(old);
-}
-
-/*
- * Get the key type needed for the given mechanism
- */
-CK_MECHANISM_TYPE
-PK11_GetKeyMechanism(CK_KEY_TYPE type)
-{
- switch (type) {
- case CKK_SEED:
- return CKM_SEED_CBC;
- case CKK_CAMELLIA:
- return CKM_CAMELLIA_CBC;
- case CKK_AES:
- return CKM_AES_CBC;
- case CKK_DES:
- return CKM_DES_CBC;
- case CKK_DES3:
- return CKM_DES3_KEY_GEN;
- case CKK_DES2:
- return CKM_DES2_KEY_GEN;
- case CKK_CDMF:
- return CKM_CDMF_CBC;
- case CKK_RC2:
- return CKM_RC2_CBC;
- case CKK_RC4:
- return CKM_RC4;
- case CKK_RC5:
- return CKM_RC5_CBC;
- case CKK_SKIPJACK:
- return CKM_SKIPJACK_CBC64;
- case CKK_BATON:
- return CKM_BATON_CBC128;
- case CKK_JUNIPER:
- return CKM_JUNIPER_CBC128;
- case CKK_IDEA:
- return CKM_IDEA_CBC;
- case CKK_CAST:
- return CKM_CAST_CBC;
- case CKK_CAST3:
- return CKM_CAST3_CBC;
- case CKK_CAST5:
- return CKM_CAST5_CBC;
- case CKK_RSA:
- return CKM_RSA_PKCS;
- case CKK_DSA:
- return CKM_DSA;
- case CKK_DH:
- return CKM_DH_PKCS_DERIVE;
- case CKK_KEA:
- return CKM_KEA_KEY_DERIVE;
- case CKK_EC: /* CKK_ECDSA is deprecated */
- return CKM_ECDSA;
- case CKK_GENERIC_SECRET:
- default:
- return CKM_SHA_1_HMAC;
- }
-}
-
-/*
- * Get the key type needed for the given mechanism
- */
-CK_MECHANISM_TYPE
-PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
-{
- switch (type) {
- case CKM_SEED_ECB:
- case CKM_SEED_CBC:
- case CKM_SEED_MAC:
- case CKM_SEED_MAC_GENERAL:
- case CKM_SEED_CBC_PAD:
- case CKM_SEED_KEY_GEN:
- return CKK_SEED;
- case CKM_CAMELLIA_ECB:
- case CKM_CAMELLIA_CBC:
- case CKM_CAMELLIA_MAC:
- case CKM_CAMELLIA_MAC_GENERAL:
- case CKM_CAMELLIA_CBC_PAD:
- case CKM_CAMELLIA_KEY_GEN:
- return CKK_CAMELLIA;
- case CKM_AES_ECB:
- case CKM_AES_CBC:
- case CKM_AES_MAC:
- case CKM_AES_MAC_GENERAL:
- case CKM_AES_CBC_PAD:
- case CKM_AES_KEY_GEN:
- case CKM_NETSCAPE_AES_KEY_WRAP:
- case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
- return CKK_AES;
- case CKM_DES_ECB:
- case CKM_DES_CBC:
- case CKM_DES_MAC:
- case CKM_DES_MAC_GENERAL:
- case CKM_DES_CBC_PAD:
- case CKM_DES_KEY_GEN:
- case CKM_KEY_WRAP_LYNKS:
- case CKM_PBE_MD2_DES_CBC:
- case CKM_PBE_MD5_DES_CBC:
- return CKK_DES;
- case CKM_DES3_ECB:
- case CKM_DES3_CBC:
- case CKM_DES3_MAC:
- case CKM_DES3_MAC_GENERAL:
- case CKM_DES3_CBC_PAD:
- return (len == 16) ? CKK_DES2 : CKK_DES3;
- case CKM_DES2_KEY_GEN:
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- return CKK_DES2;
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- case CKM_DES3_KEY_GEN:
- return CKK_DES3;
- case CKM_CDMF_ECB:
- case CKM_CDMF_CBC:
- case CKM_CDMF_MAC:
- case CKM_CDMF_MAC_GENERAL:
- case CKM_CDMF_CBC_PAD:
- case CKM_CDMF_KEY_GEN:
- return CKK_CDMF;
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- case CKM_RC2_MAC:
- case CKM_RC2_MAC_GENERAL:
- case CKM_RC2_CBC_PAD:
- case CKM_RC2_KEY_GEN:
- case CKM_PBE_SHA1_RC2_128_CBC:
- case CKM_PBE_SHA1_RC2_40_CBC:
- return CKK_RC2;
- case CKM_RC4:
- case CKM_RC4_KEY_GEN:
- return CKK_RC4;
- case CKM_RC5_ECB:
- case CKM_RC5_CBC:
- case CKM_RC5_MAC:
- case CKM_RC5_MAC_GENERAL:
- case CKM_RC5_CBC_PAD:
- case CKM_RC5_KEY_GEN:
- return CKK_RC5;
- case CKM_SKIPJACK_CBC64:
- case CKM_SKIPJACK_ECB64:
- case CKM_SKIPJACK_OFB64:
- case CKM_SKIPJACK_CFB64:
- case CKM_SKIPJACK_CFB32:
- case CKM_SKIPJACK_CFB16:
- case CKM_SKIPJACK_CFB8:
- case CKM_SKIPJACK_KEY_GEN:
- case CKM_SKIPJACK_WRAP:
- case CKM_SKIPJACK_PRIVATE_WRAP:
- return CKK_SKIPJACK;
- case CKM_BATON_ECB128:
- case CKM_BATON_ECB96:
- case CKM_BATON_CBC128:
- case CKM_BATON_COUNTER:
- case CKM_BATON_SHUFFLE:
- case CKM_BATON_WRAP:
- case CKM_BATON_KEY_GEN:
- return CKK_BATON;
- case CKM_JUNIPER_ECB128:
- case CKM_JUNIPER_CBC128:
- case CKM_JUNIPER_COUNTER:
- case CKM_JUNIPER_SHUFFLE:
- case CKM_JUNIPER_WRAP:
- case CKM_JUNIPER_KEY_GEN:
- return CKK_JUNIPER;
- case CKM_IDEA_CBC:
- case CKM_IDEA_ECB:
- case CKM_IDEA_MAC:
- case CKM_IDEA_MAC_GENERAL:
- case CKM_IDEA_CBC_PAD:
- case CKM_IDEA_KEY_GEN:
- return CKK_IDEA;
- case CKM_CAST_ECB:
- case CKM_CAST_CBC:
- case CKM_CAST_MAC:
- case CKM_CAST_MAC_GENERAL:
- case CKM_CAST_CBC_PAD:
- case CKM_CAST_KEY_GEN:
- case CKM_PBE_MD5_CAST_CBC:
- return CKK_CAST;
- case CKM_CAST3_ECB:
- case CKM_CAST3_CBC:
- case CKM_CAST3_MAC:
- case CKM_CAST3_MAC_GENERAL:
- case CKM_CAST3_CBC_PAD:
- case CKM_CAST3_KEY_GEN:
- case CKM_PBE_MD5_CAST3_CBC:
- return CKK_CAST3;
- case CKM_CAST5_ECB:
- case CKM_CAST5_CBC:
- case CKM_CAST5_MAC:
- case CKM_CAST5_MAC_GENERAL:
- case CKM_CAST5_CBC_PAD:
- case CKM_CAST5_KEY_GEN:
- case CKM_PBE_MD5_CAST5_CBC:
- return CKK_CAST5;
- case CKM_RSA_PKCS:
- case CKM_RSA_9796:
- case CKM_RSA_X_509:
- case CKM_MD2_RSA_PKCS:
- case CKM_MD5_RSA_PKCS:
- case CKM_SHA1_RSA_PKCS:
- case CKM_SHA224_RSA_PKCS:
- case CKM_SHA256_RSA_PKCS:
- case CKM_SHA384_RSA_PKCS:
- case CKM_SHA512_RSA_PKCS:
- case CKM_KEY_WRAP_SET_OAEP:
- case CKM_RSA_PKCS_KEY_PAIR_GEN:
- case CKM_RSA_X9_31_KEY_PAIR_GEN:
- return CKK_RSA;
- case CKM_DSA:
- case CKM_DSA_SHA1:
- case CKM_DSA_KEY_PAIR_GEN:
- return CKK_DSA;
- case CKM_DH_PKCS_DERIVE:
- case CKM_DH_PKCS_KEY_PAIR_GEN:
- return CKK_DH;
- case CKM_KEA_KEY_DERIVE:
- case CKM_KEA_KEY_PAIR_GEN:
- return CKK_KEA;
- case CKM_ECDSA:
- case CKM_ECDSA_SHA1:
- case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
- case CKM_ECDH1_DERIVE:
- return CKK_EC; /* CKK_ECDSA is deprecated */
- case CKM_SSL3_PRE_MASTER_KEY_GEN:
- case CKM_GENERIC_SECRET_KEY_GEN:
- case CKM_SSL3_MASTER_KEY_DERIVE:
- case CKM_SSL3_MASTER_KEY_DERIVE_DH:
- case CKM_SSL3_KEY_AND_MAC_DERIVE:
- case CKM_SSL3_SHA1_MAC:
- case CKM_SSL3_MD5_MAC:
- case CKM_TLS_MASTER_KEY_DERIVE:
- case CKM_TLS_MASTER_KEY_DERIVE_DH:
- case CKM_TLS_KEY_AND_MAC_DERIVE:
- case CKM_SHA_1_HMAC:
- case CKM_SHA_1_HMAC_GENERAL:
- case CKM_SHA224_HMAC:
- case CKM_SHA224_HMAC_GENERAL:
- case CKM_SHA256_HMAC:
- case CKM_SHA256_HMAC_GENERAL:
- case CKM_SHA384_HMAC:
- case CKM_SHA384_HMAC_GENERAL:
- case CKM_SHA512_HMAC:
- case CKM_SHA512_HMAC_GENERAL:
- case CKM_MD2_HMAC:
- case CKM_MD2_HMAC_GENERAL:
- case CKM_MD5_HMAC:
- case CKM_MD5_HMAC_GENERAL:
- case CKM_TLS_PRF_GENERAL:
- return CKK_GENERIC_SECRET;
- default:
- return pk11_lookup(type)->keyType;
- }
-}
-
-/*
- * Get the Key Gen Mechanism needed for the given
- * crypto mechanism
- */
-CK_MECHANISM_TYPE
-PK11_GetKeyGen(CK_MECHANISM_TYPE type)
-{
- return PK11_GetKeyGenWithSize(type, 0);
-}
-
-CK_MECHANISM_TYPE
-PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
-{
- switch (type) {
- case CKM_SEED_ECB:
- case CKM_SEED_CBC:
- case CKM_SEED_MAC:
- case CKM_SEED_MAC_GENERAL:
- case CKM_SEED_CBC_PAD:
- case CKM_SEED_KEY_GEN:
- return CKM_SEED_KEY_GEN;
- case CKM_CAMELLIA_ECB:
- case CKM_CAMELLIA_CBC:
- case CKM_CAMELLIA_MAC:
- case CKM_CAMELLIA_MAC_GENERAL:
- case CKM_CAMELLIA_CBC_PAD:
- case CKM_CAMELLIA_KEY_GEN:
- return CKM_CAMELLIA_KEY_GEN;
- case CKM_AES_ECB:
- case CKM_AES_CBC:
- case CKM_AES_MAC:
- case CKM_AES_MAC_GENERAL:
- case CKM_AES_CBC_PAD:
- case CKM_AES_KEY_GEN:
- return CKM_AES_KEY_GEN;
- case CKM_DES_ECB:
- case CKM_DES_CBC:
- case CKM_DES_MAC:
- case CKM_DES_MAC_GENERAL:
- case CKM_KEY_WRAP_LYNKS:
- case CKM_DES_CBC_PAD:
- case CKM_DES_KEY_GEN:
- return CKM_DES_KEY_GEN;
- case CKM_DES3_ECB:
- case CKM_DES3_CBC:
- case CKM_DES3_MAC:
- case CKM_DES3_MAC_GENERAL:
- case CKM_DES3_CBC_PAD:
- return (size == 16) ? CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN;
- case CKM_DES3_KEY_GEN:
- return CKM_DES3_KEY_GEN;
- case CKM_DES2_KEY_GEN:
- return CKM_DES2_KEY_GEN;
- case CKM_CDMF_ECB:
- case CKM_CDMF_CBC:
- case CKM_CDMF_MAC:
- case CKM_CDMF_MAC_GENERAL:
- case CKM_CDMF_CBC_PAD:
- case CKM_CDMF_KEY_GEN:
- return CKM_CDMF_KEY_GEN;
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- case CKM_RC2_MAC:
- case CKM_RC2_MAC_GENERAL:
- case CKM_RC2_CBC_PAD:
- case CKM_RC2_KEY_GEN:
- return CKM_RC2_KEY_GEN;
- case CKM_RC4:
- case CKM_RC4_KEY_GEN:
- return CKM_RC4_KEY_GEN;
- case CKM_RC5_ECB:
- case CKM_RC5_CBC:
- case CKM_RC5_MAC:
- case CKM_RC5_MAC_GENERAL:
- case CKM_RC5_CBC_PAD:
- case CKM_RC5_KEY_GEN:
- return CKM_RC5_KEY_GEN;
- case CKM_SKIPJACK_CBC64:
- case CKM_SKIPJACK_ECB64:
- case CKM_SKIPJACK_OFB64:
- case CKM_SKIPJACK_CFB64:
- case CKM_SKIPJACK_CFB32:
- case CKM_SKIPJACK_CFB16:
- case CKM_SKIPJACK_CFB8:
- case CKM_SKIPJACK_WRAP:
- case CKM_SKIPJACK_KEY_GEN:
- return CKM_SKIPJACK_KEY_GEN;
- case CKM_BATON_ECB128:
- case CKM_BATON_ECB96:
- case CKM_BATON_CBC128:
- case CKM_BATON_COUNTER:
- case CKM_BATON_SHUFFLE:
- case CKM_BATON_WRAP:
- case CKM_BATON_KEY_GEN:
- return CKM_BATON_KEY_GEN;
- case CKM_JUNIPER_ECB128:
- case CKM_JUNIPER_CBC128:
- case CKM_JUNIPER_COUNTER:
- case CKM_JUNIPER_SHUFFLE:
- case CKM_JUNIPER_WRAP:
- case CKM_JUNIPER_KEY_GEN:
- return CKM_JUNIPER_KEY_GEN;
- case CKM_IDEA_CBC:
- case CKM_IDEA_ECB:
- case CKM_IDEA_MAC:
- case CKM_IDEA_MAC_GENERAL:
- case CKM_IDEA_CBC_PAD:
- case CKM_IDEA_KEY_GEN:
- return CKM_IDEA_KEY_GEN;
- case CKM_CAST_ECB:
- case CKM_CAST_CBC:
- case CKM_CAST_MAC:
- case CKM_CAST_MAC_GENERAL:
- case CKM_CAST_CBC_PAD:
- case CKM_CAST_KEY_GEN:
- return CKM_CAST_KEY_GEN;
- case CKM_CAST3_ECB:
- case CKM_CAST3_CBC:
- case CKM_CAST3_MAC:
- case CKM_CAST3_MAC_GENERAL:
- case CKM_CAST3_CBC_PAD:
- case CKM_CAST3_KEY_GEN:
- return CKM_CAST3_KEY_GEN;
- case CKM_CAST5_ECB:
- case CKM_CAST5_CBC:
- case CKM_CAST5_MAC:
- case CKM_CAST5_MAC_GENERAL:
- case CKM_CAST5_CBC_PAD:
- case CKM_CAST5_KEY_GEN:
- return CKM_CAST5_KEY_GEN;
- case CKM_RSA_PKCS:
- case CKM_RSA_9796:
- case CKM_RSA_X_509:
- case CKM_MD2_RSA_PKCS:
- case CKM_MD5_RSA_PKCS:
- case CKM_SHA1_RSA_PKCS:
- case CKM_SHA224_RSA_PKCS:
- case CKM_SHA256_RSA_PKCS:
- case CKM_SHA384_RSA_PKCS:
- case CKM_SHA512_RSA_PKCS:
- case CKM_KEY_WRAP_SET_OAEP:
- case CKM_RSA_PKCS_KEY_PAIR_GEN:
- return CKM_RSA_PKCS_KEY_PAIR_GEN;
- case CKM_RSA_X9_31_KEY_PAIR_GEN:
- return CKM_RSA_X9_31_KEY_PAIR_GEN;
- case CKM_DSA:
- case CKM_DSA_SHA1:
- case CKM_DSA_KEY_PAIR_GEN:
- return CKM_DSA_KEY_PAIR_GEN;
- case CKM_DH_PKCS_DERIVE:
- case CKM_DH_PKCS_KEY_PAIR_GEN:
- return CKM_DH_PKCS_KEY_PAIR_GEN;
- case CKM_KEA_KEY_DERIVE:
- case CKM_KEA_KEY_PAIR_GEN:
- return CKM_KEA_KEY_PAIR_GEN;
- case CKM_ECDSA:
- case CKM_ECDSA_SHA1:
- case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
- case CKM_ECDH1_DERIVE:
- return CKM_EC_KEY_PAIR_GEN;
- case CKM_SSL3_PRE_MASTER_KEY_GEN:
- case CKM_SSL3_MASTER_KEY_DERIVE:
- case CKM_SSL3_KEY_AND_MAC_DERIVE:
- case CKM_SSL3_SHA1_MAC:
- case CKM_SSL3_MD5_MAC:
- case CKM_TLS_MASTER_KEY_DERIVE:
- case CKM_TLS_KEY_AND_MAC_DERIVE:
- return CKM_SSL3_PRE_MASTER_KEY_GEN;
- case CKM_SHA_1_HMAC:
- case CKM_SHA_1_HMAC_GENERAL:
- case CKM_SHA224_HMAC:
- case CKM_SHA224_HMAC_GENERAL:
- case CKM_SHA256_HMAC:
- case CKM_SHA256_HMAC_GENERAL:
- case CKM_SHA384_HMAC:
- case CKM_SHA384_HMAC_GENERAL:
- case CKM_SHA512_HMAC:
- case CKM_SHA512_HMAC_GENERAL:
- case CKM_MD2_HMAC:
- case CKM_MD2_HMAC_GENERAL:
- case CKM_MD5_HMAC:
- case CKM_MD5_HMAC_GENERAL:
- case CKM_TLS_PRF_GENERAL:
- case CKM_GENERIC_SECRET_KEY_GEN:
- return CKM_GENERIC_SECRET_KEY_GEN;
- case CKM_PBE_MD2_DES_CBC:
- case CKM_PBE_MD5_DES_CBC:
- case CKM_PBA_SHA1_WITH_SHA1_HMAC:
- case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
- case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
- case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- case CKM_PBE_SHA1_RC2_40_CBC:
- case CKM_PBE_SHA1_RC2_128_CBC:
- case CKM_PBE_SHA1_RC4_40:
- case CKM_PBE_SHA1_RC4_128:
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- case CKM_PKCS5_PBKD2:
- return type;
- default:
- return pk11_lookup(type)->keyGen;
- }
-}
-
-/*
- * get the mechanism block size
- */
-int
-PK11_GetBlockSize(CK_MECHANISM_TYPE type,SECItem *params)
-{
- CK_RC5_PARAMS *rc5_params;
- CK_RC5_CBC_PARAMS *rc5_cbc_params;
- switch (type) {
- case CKM_RC5_ECB:
- if ((params) && (params->data)) {
- rc5_params = (CK_RC5_PARAMS *) params->data;
- return (rc5_params->ulWordsize)*2;
- }
- return 8;
- case CKM_RC5_CBC:
- case CKM_RC5_CBC_PAD:
- if ((params) && (params->data)) {
- rc5_cbc_params = (CK_RC5_CBC_PARAMS *) params->data;
- return (rc5_cbc_params->ulWordsize)*2;
- }
- return 8;
- case CKM_DES_ECB:
- case CKM_DES3_ECB:
- case CKM_RC2_ECB:
- case CKM_IDEA_ECB:
- case CKM_CAST_ECB:
- case CKM_CAST3_ECB:
- case CKM_CAST5_ECB:
- case CKM_RC2_CBC:
- case CKM_SKIPJACK_CBC64:
- case CKM_SKIPJACK_ECB64:
- case CKM_SKIPJACK_OFB64:
- case CKM_SKIPJACK_CFB64:
- case CKM_DES_CBC:
- case CKM_DES3_CBC:
- case CKM_IDEA_CBC:
- case CKM_CAST_CBC:
- case CKM_CAST3_CBC:
- case CKM_CAST5_CBC:
- case CKM_DES_CBC_PAD:
- case CKM_DES3_CBC_PAD:
- case CKM_RC2_CBC_PAD:
- case CKM_IDEA_CBC_PAD:
- case CKM_CAST_CBC_PAD:
- case CKM_CAST3_CBC_PAD:
- case CKM_CAST5_CBC_PAD:
- case CKM_PBE_MD2_DES_CBC:
- case CKM_PBE_MD5_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- case CKM_PBE_SHA1_RC2_40_CBC:
- case CKM_PBE_SHA1_RC2_128_CBC:
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- return 8;
- case CKM_SKIPJACK_CFB32:
- case CKM_SKIPJACK_CFB16:
- case CKM_SKIPJACK_CFB8:
- return 4;
- case CKM_SEED_ECB:
- case CKM_SEED_CBC:
- case CKM_SEED_CBC_PAD:
- case CKM_CAMELLIA_ECB:
- case CKM_CAMELLIA_CBC:
- case CKM_CAMELLIA_CBC_PAD:
- case CKM_AES_ECB:
- case CKM_AES_CBC:
- case CKM_AES_CBC_PAD:
- case CKM_BATON_ECB128:
- case CKM_BATON_CBC128:
- case CKM_BATON_COUNTER:
- case CKM_BATON_SHUFFLE:
- case CKM_JUNIPER_ECB128:
- case CKM_JUNIPER_CBC128:
- case CKM_JUNIPER_COUNTER:
- case CKM_JUNIPER_SHUFFLE:
- return 16;
- case CKM_BATON_ECB96:
- return 12;
- case CKM_RC4:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- case CKM_PBE_SHA1_RC4_40:
- case CKM_PBE_SHA1_RC4_128:
- return 0;
- case CKM_RSA_PKCS:
- case CKM_RSA_9796:
- case CKM_RSA_X_509:
- /*actually it's the modulus length of the key!*/
- return -1; /* failure */
- default:
- return pk11_lookup(type)->blockSize;
- }
-}
-
-/*
- * get the iv length
- */
-int
-PK11_GetIVLength(CK_MECHANISM_TYPE type)
-{
- switch (type) {
- case CKM_SEED_ECB:
- case CKM_CAMELLIA_ECB:
- case CKM_AES_ECB:
- case CKM_DES_ECB:
- case CKM_DES3_ECB:
- case CKM_RC2_ECB:
- case CKM_IDEA_ECB:
- case CKM_SKIPJACK_WRAP:
- case CKM_BATON_WRAP:
- case CKM_RC5_ECB:
- case CKM_CAST_ECB:
- case CKM_CAST3_ECB:
- case CKM_CAST5_ECB:
- return 0;
- case CKM_RC2_CBC:
- case CKM_DES_CBC:
- case CKM_DES3_CBC:
- case CKM_IDEA_CBC:
- case CKM_PBE_MD2_DES_CBC:
- case CKM_PBE_MD5_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- case CKM_PBE_SHA1_RC2_40_CBC:
- case CKM_PBE_SHA1_RC2_128_CBC:
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- case CKM_RC5_CBC:
- case CKM_CAST_CBC:
- case CKM_CAST3_CBC:
- case CKM_CAST5_CBC:
- case CKM_RC2_CBC_PAD:
- case CKM_DES_CBC_PAD:
- case CKM_DES3_CBC_PAD:
- case CKM_IDEA_CBC_PAD:
- case CKM_RC5_CBC_PAD:
- case CKM_CAST_CBC_PAD:
- case CKM_CAST3_CBC_PAD:
- case CKM_CAST5_CBC_PAD:
- return 8;
- case CKM_SEED_CBC:
- case CKM_SEED_CBC_PAD:
- case CKM_CAMELLIA_CBC:
- case CKM_CAMELLIA_CBC_PAD:
- case CKM_AES_CBC:
- case CKM_AES_CBC_PAD:
- return 16;
- case CKM_SKIPJACK_CBC64:
- case CKM_SKIPJACK_ECB64:
- case CKM_SKIPJACK_OFB64:
- case CKM_SKIPJACK_CFB64:
- case CKM_SKIPJACK_CFB32:
- case CKM_SKIPJACK_CFB16:
- case CKM_SKIPJACK_CFB8:
- case CKM_BATON_ECB128:
- case CKM_BATON_ECB96:
- case CKM_BATON_CBC128:
- case CKM_BATON_COUNTER:
- case CKM_BATON_SHUFFLE:
- case CKM_JUNIPER_ECB128:
- case CKM_JUNIPER_CBC128:
- case CKM_JUNIPER_COUNTER:
- case CKM_JUNIPER_SHUFFLE:
- return 24;
- case CKM_RC4:
- case CKM_RSA_PKCS:
- case CKM_RSA_9796:
- case CKM_RSA_X_509:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- case CKM_PBE_SHA1_RC4_40:
- case CKM_PBE_SHA1_RC4_128:
- return 0;
- default:
- return pk11_lookup(type)->iv;
- }
-}
-
-
-/* These next two utilities are here to help facilitate future
- * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions
- * like SSL and S-MIME to automatically add them.
- */
-SECItem *
-pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type, SECItem *iv, int keyLen)
-{
- CK_RC2_CBC_PARAMS *rc2_params = NULL;
- CK_RC2_PARAMS *rc2_ecb_params = NULL;
- CK_RC5_PARAMS *rc5_params = NULL;
- CK_RC5_CBC_PARAMS *rc5_cbc_params = NULL;
- SECItem *param;
-
- param = (SECItem *)PORT_Alloc(sizeof(SECItem));
- if (param == NULL) return NULL;
- param->data = NULL;
- param->len = 0;
- param->type = 0;
- switch (type) {
- case CKM_SEED_ECB:
- case CKM_CAMELLIA_ECB:
- case CKM_AES_ECB:
- case CKM_DES_ECB:
- case CKM_DES3_ECB:
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- case CKM_RSA_9796:
- case CKM_IDEA_ECB:
- case CKM_CDMF_ECB:
- case CKM_CAST_ECB:
- case CKM_CAST3_ECB:
- case CKM_CAST5_ECB:
- case CKM_RC4:
- break;
- case CKM_RC2_ECB:
- rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS));
- if (rc2_ecb_params == NULL) break;
- /* Maybe we should pass the key size in too to get this value? */
- *rc2_ecb_params = keyLen ? keyLen*8 : 128;
- param->data = (unsigned char *) rc2_ecb_params;
- param->len = sizeof(CK_RC2_PARAMS);
- break;
- case CKM_RC2_CBC:
- case CKM_RC2_CBC_PAD:
- rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS));
- if (rc2_params == NULL) break;
- /* Maybe we should pass the key size in too to get this value? */
- rc2_params->ulEffectiveBits = keyLen ? keyLen*8 : 128;
- if (iv && iv->data)
- PORT_Memcpy(rc2_params->iv,iv->data,sizeof(rc2_params->iv));
- param->data = (unsigned char *) rc2_params;
- param->len = sizeof(CK_RC2_CBC_PARAMS);
- break;
- case CKM_RC5_CBC:
- case CKM_RC5_CBC_PAD:
- rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
- PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0));
- if (rc5_cbc_params == NULL) break;
- if (iv && iv->data && iv->len) {
- rc5_cbc_params->pIv = ((CK_BYTE_PTR) rc5_cbc_params)
- + sizeof(CK_RC5_CBC_PARAMS);
- PORT_Memcpy(rc5_cbc_params->pIv,iv->data,iv->len);
- rc5_cbc_params->ulIvLen = iv->len;
- rc5_cbc_params->ulWordsize = iv->len/2;
- } else {
- rc5_cbc_params->ulWordsize = 4;
- rc5_cbc_params->pIv = NULL;
- rc5_cbc_params->ulIvLen = 0;
- }
- rc5_cbc_params->ulRounds = 16;
- param->data = (unsigned char *) rc5_cbc_params;
- param->len = sizeof(CK_RC5_CBC_PARAMS);
- break;
- case CKM_RC5_ECB:
- rc5_params = (CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS));
- if (rc5_params == NULL) break;
- if (iv && iv->data && iv->len) {
- rc5_params->ulWordsize = iv->len/2;
- } else {
- rc5_params->ulWordsize = 4;
- }
- rc5_params->ulRounds = 16;
- param->data = (unsigned char *) rc5_params;
- param->len = sizeof(CK_RC5_PARAMS);
- break;
-
- case CKM_SEED_CBC:
- case CKM_CAMELLIA_CBC:
- case CKM_AES_CBC:
- case CKM_DES_CBC:
- case CKM_DES3_CBC:
- case CKM_IDEA_CBC:
- case CKM_CDMF_CBC:
- case CKM_CAST_CBC:
- case CKM_CAST3_CBC:
- case CKM_CAST5_CBC:
- case CKM_CAMELLIA_CBC_PAD:
- case CKM_AES_CBC_PAD:
- case CKM_DES_CBC_PAD:
- case CKM_DES3_CBC_PAD:
- case CKM_IDEA_CBC_PAD:
- case CKM_CDMF_CBC_PAD:
- case CKM_CAST_CBC_PAD:
- case CKM_CAST3_CBC_PAD:
- case CKM_CAST5_CBC_PAD:
- case CKM_SKIPJACK_CBC64:
- case CKM_SKIPJACK_ECB64:
- case CKM_SKIPJACK_OFB64:
- case CKM_SKIPJACK_CFB64:
- case CKM_SKIPJACK_CFB32:
- case CKM_SKIPJACK_CFB16:
- case CKM_SKIPJACK_CFB8:
- case CKM_BATON_ECB128:
- case CKM_BATON_ECB96:
- case CKM_BATON_CBC128:
- case CKM_BATON_COUNTER:
- case CKM_BATON_SHUFFLE:
- case CKM_JUNIPER_ECB128:
- case CKM_JUNIPER_CBC128:
- case CKM_JUNIPER_COUNTER:
- case CKM_JUNIPER_SHUFFLE:
- if ((iv == NULL) || (iv->data == NULL)) break;
- param->data = (unsigned char*)PORT_Alloc(iv->len);
- if (param->data != NULL) {
- PORT_Memcpy(param->data,iv->data,iv->len);
- param->len = iv->len;
- }
- break;
- /* unknown mechanism, pass IV in if it's there */
- default:
- if (pk11_lookup(type)->iv == 0) {
- break;
- }
- if ((iv == NULL) || (iv->data == NULL)) {
- break;
- }
- param->data = (unsigned char*)PORT_Alloc(iv->len);
- if (param->data != NULL) {
- PORT_Memcpy(param->data,iv->data,iv->len);
- param->len = iv->len;
- }
- break;
- }
- return param;
-}
-
-/* These next two utilities are here to help facilitate future
- * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions
- * like SSL and S-MIME to automatically add them.
- */
-SECItem *
-PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv)
-{
- return pk11_ParamFromIVWithLen(type, iv, 0);
-}
-
-unsigned char *
-PK11_IVFromParam(CK_MECHANISM_TYPE type,SECItem *param,int *len)
-{
- CK_RC2_CBC_PARAMS *rc2_params;
- CK_RC5_CBC_PARAMS *rc5_cbc_params;
-
- *len = 0;
- switch (type) {
- case CKM_SEED_ECB:
- case CKM_CAMELLIA_ECB:
- case CKM_AES_ECB:
- case CKM_DES_ECB:
- case CKM_DES3_ECB:
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- case CKM_RSA_9796:
- case CKM_IDEA_ECB:
- case CKM_CDMF_ECB:
- case CKM_CAST_ECB:
- case CKM_CAST3_ECB:
- case CKM_CAST5_ECB:
- case CKM_RC4:
- return NULL;
- case CKM_RC2_ECB:
- return NULL;
- case CKM_RC2_CBC:
- case CKM_RC2_CBC_PAD:
- rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
- *len = sizeof(rc2_params->iv);
- return &rc2_params->iv[0];
- case CKM_RC5_CBC:
- case CKM_RC5_CBC_PAD:
- rc5_cbc_params = (CK_RC5_CBC_PARAMS *) param->data;
- *len = rc5_cbc_params->ulIvLen;
- return rc5_cbc_params->pIv;
- case CKM_SEED_CBC:
- case CKM_CAMELLIA_CBC:
- case CKM_AES_CBC:
- case CKM_DES_CBC:
- case CKM_DES3_CBC:
- case CKM_IDEA_CBC:
- case CKM_CDMF_CBC:
- case CKM_CAST_CBC:
- case CKM_CAST3_CBC:
- case CKM_CAST5_CBC:
- case CKM_CAMELLIA_CBC_PAD:
- case CKM_AES_CBC_PAD:
- case CKM_DES_CBC_PAD:
- case CKM_DES3_CBC_PAD:
- case CKM_IDEA_CBC_PAD:
- case CKM_CDMF_CBC_PAD:
- case CKM_CAST_CBC_PAD:
- case CKM_CAST3_CBC_PAD:
- case CKM_CAST5_CBC_PAD:
- case CKM_SKIPJACK_CBC64:
- case CKM_SKIPJACK_ECB64:
- case CKM_SKIPJACK_OFB64:
- case CKM_SKIPJACK_CFB64:
- case CKM_SKIPJACK_CFB32:
- case CKM_SKIPJACK_CFB16:
- case CKM_SKIPJACK_CFB8:
- case CKM_BATON_ECB128:
- case CKM_BATON_ECB96:
- case CKM_BATON_CBC128:
- case CKM_BATON_COUNTER:
- case CKM_BATON_SHUFFLE:
- case CKM_JUNIPER_ECB128:
- case CKM_JUNIPER_CBC128:
- case CKM_JUNIPER_COUNTER:
- case CKM_JUNIPER_SHUFFLE:
- break;
- /* unknown mechanism, pass IV in if it's there */
- default:
- break;
- }
- if (param->data) {
- *len = param->len;
- }
- return param->data;
-}
-
-typedef struct sec_rc5cbcParameterStr {
- SECItem version;
- SECItem rounds;
- SECItem blockSizeInBits;
- SECItem iv;
-} sec_rc5cbcParameter;
-
-static const SEC_ASN1Template sec_rc5ecb_parameter_template[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(sec_rc5cbcParameter) },
- { SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,version) },
- { SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,rounds) },
- { SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,blockSizeInBits) },
- { 0 }
-};
-
-static const SEC_ASN1Template sec_rc5cbc_parameter_template[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(sec_rc5cbcParameter) },
- { SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,version) },
- { SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,rounds) },
- { SEC_ASN1_INTEGER,
- offsetof(sec_rc5cbcParameter,blockSizeInBits) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(sec_rc5cbcParameter,iv) },
- { 0 }
-};
-
-typedef struct sec_rc2cbcParameterStr {
- SECItem rc2ParameterVersion;
- SECItem iv;
-} sec_rc2cbcParameter;
-
-static const SEC_ASN1Template sec_rc2cbc_parameter_template[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(sec_rc2cbcParameter) },
- { SEC_ASN1_INTEGER,
- offsetof(sec_rc2cbcParameter,rc2ParameterVersion) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(sec_rc2cbcParameter,iv) },
- { 0 }
-};
-
-static const SEC_ASN1Template sec_rc2ecb_parameter_template[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(sec_rc2cbcParameter) },
- { SEC_ASN1_INTEGER,
- offsetof(sec_rc2cbcParameter,rc2ParameterVersion) },
- { 0 }
-};
-
-/* S/MIME picked id values to represent differnt keysizes */
-/* I do have a formula, but it ain't pretty, and it only works because you
- * can always match three points to a parabola:) */
-static unsigned char rc2_map(SECItem *version)
-{
- long x;
-
- x = DER_GetInteger(version);
-
- switch (x) {
- case 58: return 128;
- case 120: return 64;
- case 160: return 40;
- }
- return 128;
-}
-
-static unsigned long rc2_unmap(unsigned long x)
-{
- switch (x) {
- case 128: return 58;
- case 64: return 120;
- case 40: return 160;
- }
- return 58;
-}
-
-
-
-/* Generate a mechaism param from a type, and iv. */
-SECItem *
-PK11_ParamFromAlgid(SECAlgorithmID *algid)
-{
- CK_RC2_CBC_PARAMS * rc2_cbc_params = NULL;
- CK_RC2_PARAMS * rc2_ecb_params = NULL;
- CK_RC5_CBC_PARAMS * rc5_cbc_params = NULL;
- CK_RC5_PARAMS * rc5_ecb_params = NULL;
- PRArenaPool * arena = NULL;
- SECItem * mech = NULL;
- SECOidTag algtag;
- SECStatus rv;
- CK_MECHANISM_TYPE type;
- /* initialize these to prevent UMRs in the ASN1 decoder. */
- SECItem iv = {siBuffer, NULL, 0};
- sec_rc2cbcParameter rc2 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0} };
- sec_rc5cbcParameter rc5 = { {siBuffer, NULL, 0}, {siBuffer, NULL, 0},
- {siBuffer, NULL, 0}, {siBuffer, NULL, 0} };
-
- algtag = SECOID_GetAlgorithmTag(algid);
- type = PK11_AlgtagToMechanism(algtag);
-
- mech = PORT_New(SECItem);
- if (mech == NULL) {
- return NULL;
- }
- mech->type = siBuffer;
- mech->data = NULL;
- mech->len = 0;
-
- arena = PORT_NewArena(1024);
- if (!arena) {
- goto loser;
- }
-
- /* handle the complicated cases */
- switch (type) {
- case CKM_RC2_ECB:
- rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2ecb_parameter_template,
- &(algid->parameters));
- if (rv != SECSuccess) {
- goto loser;
- }
- rc2_ecb_params = PORT_New(CK_RC2_PARAMS);
- if (rc2_ecb_params == NULL) {
- goto loser;
- }
- *rc2_ecb_params = rc2_map(&rc2.rc2ParameterVersion);
- mech->data = (unsigned char *) rc2_ecb_params;
- mech->len = sizeof *rc2_ecb_params;
- break;
- case CKM_RC2_CBC:
- case CKM_RC2_CBC_PAD:
- rv = SEC_ASN1DecodeItem(arena, &rc2 ,sec_rc2cbc_parameter_template,
- &(algid->parameters));
- if (rv != SECSuccess) {
- goto loser;
- }
- rc2_cbc_params = PORT_New(CK_RC2_CBC_PARAMS);
- if (rc2_cbc_params == NULL) {
- goto loser;
- }
- mech->data = (unsigned char *) rc2_cbc_params;
- mech->len = sizeof *rc2_cbc_params;
- rc2_cbc_params->ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion);
- if (rc2.iv.len != sizeof rc2_cbc_params->iv) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- goto loser;
- }
- PORT_Memcpy(rc2_cbc_params->iv, rc2.iv.data, rc2.iv.len);
- break;
- case CKM_RC5_ECB:
- rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5ecb_parameter_template,
- &(algid->parameters));
- if (rv != SECSuccess) {
- goto loser;
- }
- rc5_ecb_params = PORT_New(CK_RC5_PARAMS);
- if (rc5_ecb_params == NULL) {
- goto loser;
- }
- rc5_ecb_params->ulRounds = DER_GetInteger(&rc5.rounds);
- rc5_ecb_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
- mech->data = (unsigned char *) rc5_ecb_params;
- mech->len = sizeof *rc5_ecb_params;
- break;
- case CKM_RC5_CBC:
- case CKM_RC5_CBC_PAD:
- rv = SEC_ASN1DecodeItem(arena, &rc5 ,sec_rc5cbc_parameter_template,
- &(algid->parameters));
- if (rv != SECSuccess) {
- goto loser;
- }
- rc5_cbc_params = (CK_RC5_CBC_PARAMS *)
- PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + rc5.iv.len);
- if (rc5_cbc_params == NULL) {
- goto loser;
- }
- mech->data = (unsigned char *) rc5_cbc_params;
- mech->len = sizeof *rc5_cbc_params;
- rc5_cbc_params->ulRounds = DER_GetInteger(&rc5.rounds);
- rc5_cbc_params->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8;
- rc5_cbc_params->pIv = ((CK_BYTE_PTR)rc5_cbc_params)
- + sizeof(CK_RC5_CBC_PARAMS);
- rc5_cbc_params->ulIvLen = rc5.iv.len;
- PORT_Memcpy(rc5_cbc_params->pIv, rc5.iv.data, rc5.iv.len);
- break;
- case CKM_PBE_MD2_DES_CBC:
- case CKM_PBE_MD5_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- case CKM_PBE_SHA1_RC2_40_CBC:
- case CKM_PBE_SHA1_RC2_128_CBC:
- case CKM_PBE_SHA1_RC4_40:
- case CKM_PBE_SHA1_RC4_128:
- case CKM_PKCS5_PBKD2:
- rv = pbe_PK11AlgidToParam(algid,mech);
- if (rv != SECSuccess) {
- goto loser;
- }
- break;
- case CKM_RC4:
- case CKM_SEED_ECB:
- case CKM_CAMELLIA_ECB:
- case CKM_AES_ECB:
- case CKM_DES_ECB:
- case CKM_DES3_ECB:
- case CKM_IDEA_ECB:
- case CKM_CDMF_ECB:
- case CKM_CAST_ECB:
- case CKM_CAST3_ECB:
- case CKM_CAST5_ECB:
- break;
-
- default:
- if (pk11_lookup(type)->iv == 0) {
- break;
- }
- /* FALL THROUGH */
- case CKM_SEED_CBC:
- case CKM_CAMELLIA_CBC:
- case CKM_AES_CBC:
- case CKM_DES_CBC:
- case CKM_DES3_CBC:
- case CKM_IDEA_CBC:
- case CKM_CDMF_CBC:
- case CKM_CAST_CBC:
- case CKM_CAST3_CBC:
- case CKM_CAST5_CBC:
- case CKM_SEED_CBC_PAD:
- case CKM_CAMELLIA_CBC_PAD:
- case CKM_AES_CBC_PAD:
- case CKM_DES_CBC_PAD:
- case CKM_DES3_CBC_PAD:
- case CKM_IDEA_CBC_PAD:
- case CKM_CDMF_CBC_PAD:
- case CKM_CAST_CBC_PAD:
- case CKM_CAST3_CBC_PAD:
- case CKM_CAST5_CBC_PAD:
- case CKM_SKIPJACK_CBC64:
- case CKM_SKIPJACK_ECB64:
- case CKM_SKIPJACK_OFB64:
- case CKM_SKIPJACK_CFB64:
- case CKM_SKIPJACK_CFB32:
- case CKM_SKIPJACK_CFB16:
- case CKM_SKIPJACK_CFB8:
- case CKM_BATON_ECB128:
- case CKM_BATON_ECB96:
- case CKM_BATON_CBC128:
- case CKM_BATON_COUNTER:
- case CKM_BATON_SHUFFLE:
- case CKM_JUNIPER_ECB128:
- case CKM_JUNIPER_CBC128:
- case CKM_JUNIPER_COUNTER:
- case CKM_JUNIPER_SHUFFLE:
- /* simple cases are simply octet string encoded IVs */
- rv = SEC_ASN1DecodeItem(arena, &iv,
- SEC_ASN1_GET(SEC_OctetStringTemplate),
- &(algid->parameters));
- if (rv != SECSuccess || iv.data == NULL) {
- goto loser;
- }
- /* XXX Should be some IV length sanity check here. */
- mech->data = (unsigned char*)PORT_Alloc(iv.len);
- if (mech->data == NULL) {
- goto loser;
- }
- PORT_Memcpy(mech->data, iv.data, iv.len);
- mech->len = iv.len;
- break;
- }
- PORT_FreeArena(arena, PR_FALSE);
- return mech;
-
-loser:
- if (arena)
- PORT_FreeArena(arena, PR_FALSE);
- SECITEM_FreeItem(mech,PR_TRUE);
- return NULL;
-}
-
-/*
- * Generate an IV for the given mechanism
- */
-static SECStatus
-pk11_GenIV(CK_MECHANISM_TYPE type, SECItem *iv) {
- int iv_size = PK11_GetIVLength(type);
- SECStatus rv;
-
- iv->len = iv_size;
- if (iv_size == 0) {
- iv->data = NULL;
- return SECSuccess;
- }
-
- iv->data = (unsigned char *) PORT_Alloc(iv_size);
- if (iv->data == NULL) {
- iv->len = 0;
- return SECFailure;
- }
-
- rv = PK11_GenerateRandom(iv->data,iv->len);
- if (rv != SECSuccess) {
- PORT_Free(iv->data);
- iv->data = NULL; iv->len = 0;
- return SECFailure;
- }
- return SECSuccess;
-}
-
-
-/*
- * create a new parameter block from the passed in MECHANISM and the
- * key. Use Netscape's S/MIME Rules for the New param block.
- */
-SECItem *
-pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen)
-{
- CK_RC2_CBC_PARAMS *rc2_params;
- CK_RC2_PARAMS *rc2_ecb_params;
- SECItem *mech;
- SECItem iv;
- SECStatus rv;
-
-
- mech = (SECItem *) PORT_Alloc(sizeof(SECItem));
- if (mech == NULL) return NULL;
-
- rv = SECSuccess;
- mech->type = siBuffer;
- switch (type) {
- case CKM_RC4:
- case CKM_SEED_ECB:
- case CKM_CAMELLIA_ECB:
- case CKM_AES_ECB:
- case CKM_DES_ECB:
- case CKM_DES3_ECB:
- case CKM_IDEA_ECB:
- case CKM_CDMF_ECB:
- case CKM_CAST_ECB:
- case CKM_CAST3_ECB:
- case CKM_CAST5_ECB:
- mech->data = NULL;
- mech->len = 0;
- break;
- case CKM_RC2_ECB:
- rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS));
- if (rc2_ecb_params == NULL) {
- rv = SECFailure;
- break;
- }
- /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
- * or RC4 key. Of course that wouldn't happen here doing RC2:).*/
- *rc2_ecb_params = keyLen ? keyLen*8 : 128;
- mech->data = (unsigned char *) rc2_ecb_params;
- mech->len = sizeof(CK_RC2_PARAMS);
- break;
- case CKM_RC2_CBC:
- case CKM_RC2_CBC_PAD:
- rv = pk11_GenIV(type,&iv);
- if (rv != SECSuccess) {
- break;
- }
- rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS));
- if (rc2_params == NULL) {
- PORT_Free(iv.data);
- rv = SECFailure;
- break;
- }
- /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5,
- * or RC4 key. Of course that wouldn't happen here doing RC2:).*/
- rc2_params->ulEffectiveBits = keyLen ? keyLen*8 : 128;
- if (iv.data)
- PORT_Memcpy(rc2_params->iv,iv.data,sizeof(rc2_params->iv));
- mech->data = (unsigned char *) rc2_params;
- mech->len = sizeof(CK_RC2_CBC_PARAMS);
- PORT_Free(iv.data);
- break;
- case CKM_RC5_ECB:
- PORT_Free(mech);
- return PK11_ParamFromIV(type,NULL);
- case CKM_RC5_CBC:
- case CKM_RC5_CBC_PAD:
- rv = pk11_GenIV(type,&iv);
- if (rv != SECSuccess) {
- break;
- }
- PORT_Free(mech);
- return PK11_ParamFromIV(type,&iv);
- default:
- if (pk11_lookup(type)->iv == 0) {
- mech->data = NULL;
- mech->len = 0;
- break;
- }
- case CKM_SEED_CBC:
- case CKM_CAMELLIA_CBC:
- case CKM_AES_CBC:
- case CKM_DES_CBC:
- case CKM_DES3_CBC:
- case CKM_IDEA_CBC:
- case CKM_CDMF_CBC:
- case CKM_CAST_CBC:
- case CKM_CAST3_CBC:
- case CKM_CAST5_CBC:
- case CKM_DES_CBC_PAD:
- case CKM_DES3_CBC_PAD:
- case CKM_IDEA_CBC_PAD:
- case CKM_CDMF_CBC_PAD:
- case CKM_CAST_CBC_PAD:
- case CKM_CAST3_CBC_PAD:
- case CKM_CAST5_CBC_PAD:
- case CKM_SKIPJACK_CBC64:
- case CKM_SKIPJACK_ECB64:
- case CKM_SKIPJACK_OFB64:
- case CKM_SKIPJACK_CFB64:
- case CKM_SKIPJACK_CFB32:
- case CKM_SKIPJACK_CFB16:
- case CKM_SKIPJACK_CFB8:
- case CKM_BATON_ECB128:
- case CKM_BATON_ECB96:
- case CKM_BATON_CBC128:
- case CKM_BATON_COUNTER:
- case CKM_BATON_SHUFFLE:
- case CKM_JUNIPER_ECB128:
- case CKM_JUNIPER_CBC128:
- case CKM_JUNIPER_COUNTER:
- case CKM_JUNIPER_SHUFFLE:
- rv = pk11_GenIV(type,&iv);
- if (rv != SECSuccess) {
- break;
- }
- mech->data = (unsigned char*)PORT_Alloc(iv.len);
- if (mech->data == NULL) {
- PORT_Free(iv.data);
- rv = SECFailure;
- break;
- }
- PORT_Memcpy(mech->data,iv.data,iv.len);
- mech->len = iv.len;
- PORT_Free(iv.data);
- break;
- }
- if (rv != SECSuccess) {
- SECITEM_FreeItem(mech,PR_TRUE);
- return NULL;
- }
- return mech;
-
-}
-
-SECItem *
-PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key)
-{
- int keyLen = key ? PK11_GetKeyLength(key) : 0;
-
- return pk11_GenerateNewParamWithKeyLen(type, keyLen);
-}
-
-#define RC5_V10 0x10
-
-/* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */
-SECStatus
-PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
- PRArenaPool *arena, SECAlgorithmID *algid) {
- CK_RC2_CBC_PARAMS *rc2_params;
- sec_rc2cbcParameter rc2;
- CK_RC5_CBC_PARAMS *rc5_params;
- sec_rc5cbcParameter rc5;
- CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(algTag);
- SECItem *newParams = NULL;
- SECStatus rv = SECFailure;
- unsigned long rc2version;
-
- switch (type) {
- case CKM_RC4:
- case CKM_SEED_ECB:
- case CKM_CAMELLIA_ECB:
- case CKM_AES_ECB:
- case CKM_DES_ECB:
- case CKM_DES3_ECB:
- case CKM_IDEA_ECB:
- case CKM_CDMF_ECB:
- case CKM_CAST_ECB:
- case CKM_CAST3_ECB:
- case CKM_CAST5_ECB:
- newParams = NULL;
- rv = SECSuccess;
- break;
- case CKM_RC2_ECB:
- break;
- case CKM_RC2_CBC:
- case CKM_RC2_CBC_PAD:
- rc2_params = (CK_RC2_CBC_PARAMS *)param->data;
- rc2version = rc2_unmap(rc2_params->ulEffectiveBits);
- if (SEC_ASN1EncodeUnsignedInteger (NULL, &(rc2.rc2ParameterVersion),
- rc2version) == NULL)
- break;
- rc2.iv.data = rc2_params->iv;
- rc2.iv.len = sizeof(rc2_params->iv);
- newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc2,
- sec_rc2cbc_parameter_template);
- PORT_Free(rc2.rc2ParameterVersion.data);
- if (newParams == NULL)
- break;
- rv = SECSuccess;
- break;
-
- case CKM_RC5_ECB: /* well not really... */
- break;
- case CKM_RC5_CBC:
- case CKM_RC5_CBC_PAD:
- rc5_params = (CK_RC5_CBC_PARAMS *)param->data;
- if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.version, RC5_V10) == NULL)
- break;
- if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.blockSizeInBits,
- rc5_params->ulWordsize*8) == NULL) {
- PORT_Free(rc5.version.data);
- break;
- }
- if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.rounds,
- rc5_params->ulWordsize*8) == NULL) {
- PORT_Free(rc5.blockSizeInBits.data);
- PORT_Free(rc5.version.data);
- break;
- }
- rc5.iv.data = rc5_params->pIv;
- rc5.iv.len = rc5_params->ulIvLen;
- newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc5,
- sec_rc5cbc_parameter_template);
- PORT_Free(rc5.version.data);
- PORT_Free(rc5.blockSizeInBits.data);
- PORT_Free(rc5.rounds.data);
- if (newParams == NULL)
- break;
- rv = SECSuccess;
- break;
- case CKM_PBE_MD2_DES_CBC:
- case CKM_PBE_MD5_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- case CKM_PBE_SHA1_RC2_40_CBC:
- case CKM_PBE_SHA1_RC2_128_CBC:
- case CKM_PBE_SHA1_RC4_40:
- case CKM_PBE_SHA1_RC4_128:
- return PBE_PK11ParamToAlgid(algTag, param, arena, algid);
- default:
- if (pk11_lookup(type)->iv == 0) {
- rv = SECSuccess;
- newParams = NULL;
- break;
- }
- case CKM_SEED_CBC:
- case CKM_CAMELLIA_CBC:
- case CKM_AES_CBC:
- case CKM_DES_CBC:
- case CKM_DES3_CBC:
- case CKM_IDEA_CBC:
- case CKM_CDMF_CBC:
- case CKM_CAST_CBC:
- case CKM_CAST3_CBC:
- case CKM_CAST5_CBC:
- case CKM_DES_CBC_PAD:
- case CKM_DES3_CBC_PAD:
- case CKM_IDEA_CBC_PAD:
- case CKM_CDMF_CBC_PAD:
- case CKM_CAST_CBC_PAD:
- case CKM_CAST3_CBC_PAD:
- case CKM_CAST5_CBC_PAD:
- case CKM_SKIPJACK_CBC64:
- case CKM_SKIPJACK_ECB64:
- case CKM_SKIPJACK_OFB64:
- case CKM_SKIPJACK_CFB64:
- case CKM_SKIPJACK_CFB32:
- case CKM_SKIPJACK_CFB16:
- case CKM_SKIPJACK_CFB8:
- case CKM_BATON_ECB128:
- case CKM_BATON_ECB96:
- case CKM_BATON_CBC128:
- case CKM_BATON_COUNTER:
- case CKM_BATON_SHUFFLE:
- case CKM_JUNIPER_ECB128:
- case CKM_JUNIPER_CBC128:
- case CKM_JUNIPER_COUNTER:
- case CKM_JUNIPER_SHUFFLE:
- newParams = SEC_ASN1EncodeItem(NULL,NULL,param,
- SEC_ASN1_GET(SEC_OctetStringTemplate) );
- if (newParams == NULL)
- break;
- rv = SECSuccess;
- break;
- }
-
- if (rv != SECSuccess) {
- if (newParams) SECITEM_FreeItem(newParams,PR_TRUE);
- return rv;
- }
-
- rv = SECOID_SetAlgorithmID(arena, algid, algTag, newParams);
- SECITEM_FreeItem(newParams,PR_TRUE);
- return rv;
-}
-
-/* turn an OID algorithm tag into a PKCS #11 mechanism. This allows us to
- * map OID's directly into the PKCS #11 mechanism we want to call. We find
- * this mapping in our standard OID table */
-CK_MECHANISM_TYPE
-PK11_AlgtagToMechanism(SECOidTag algTag) {
- SECOidData *oid = SECOID_FindOIDByTag(algTag);
-
- if (oid) return (CK_MECHANISM_TYPE) oid->mechanism;
- return CKM_INVALID_MECHANISM;
-}
-
-/* turn a mechanism into an oid. */
-SECOidTag
-PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type) {
- SECOidData *oid = SECOID_FindOIDByMechanism((unsigned long)type);
-
- if (oid) return oid->offset;
- return SEC_OID_UNKNOWN;
-}
-
-/* Determine appropriate blocking mechanism, used when wrapping private keys
- * which require PKCS padding. If the mechanism does not map to a padding
- * mechanism, we simply return the mechanism.
- */
-CK_MECHANISM_TYPE
-PK11_GetPadMechanism(CK_MECHANISM_TYPE type) {
- switch(type) {
- case CKM_SEED_CBC:
- return CKM_SEED_CBC_PAD;
- case CKM_CAMELLIA_CBC:
- return CKM_CAMELLIA_CBC_PAD;
- case CKM_AES_CBC:
- return CKM_AES_CBC_PAD;
- case CKM_DES_CBC:
- return CKM_DES_CBC_PAD;
- case CKM_DES3_CBC:
- return CKM_DES3_CBC_PAD;
- case CKM_RC2_CBC:
- return CKM_RC2_CBC_PAD;
- case CKM_CDMF_CBC:
- return CKM_CDMF_CBC_PAD;
- case CKM_CAST_CBC:
- return CKM_CAST_CBC_PAD;
- case CKM_CAST3_CBC:
- return CKM_CAST3_CBC_PAD;
- case CKM_CAST5_CBC:
- return CKM_CAST5_CBC_PAD;
- case CKM_RC5_CBC:
- return CKM_RC5_CBC_PAD;
- case CKM_IDEA_CBC:
- return CKM_IDEA_CBC_PAD;
- default:
- break;
- }
-
- return type;
-}
-
-static PRBool
-pk11_isAllZero(unsigned char *data,int len) {
- while (len--) {
- if (*data++) {
- return PR_FALSE;
- }
- }
- return PR_TRUE;
-}
-
-CK_RV
-PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
- CK_MECHANISM_PTR pCryptoMechanism,
- SECItem *pbe_pwd, PRBool faulty3DES)
-{
- int iv_len = 0;
- CK_PBE_PARAMS_PTR pPBEparams;
- CK_RC2_CBC_PARAMS_PTR rc2_params;
- CK_ULONG rc2_key_len;
-
- if((pPBEMechanism == CK_NULL_PTR) || (pCryptoMechanism == CK_NULL_PTR)) {
- return CKR_HOST_MEMORY;
- }
-
- /* pkcs5 v2 cannot be supported by this interface.
- * use PK11_GetPBECryptoMechanism instead.
- */
- if ((pPBEMechanism->mechanism == CKM_INVALID_MECHANISM) ||
- (pPBEMechanism->mechanism == CKM_PKCS5_PBKD2)) {
- return CKR_MECHANISM_INVALID;
- }
-
- pPBEparams = (CK_PBE_PARAMS_PTR)pPBEMechanism->pParameter;
- iv_len = PK11_GetIVLength(pPBEMechanism->mechanism);
-
- if (iv_len) {
- if (pk11_isAllZero(pPBEparams->pInitVector,iv_len)) {
- SECItem param;
- PK11SymKey *symKey;
- PK11SlotInfo *intSlot = PK11_GetInternalSlot();
-
- if (intSlot == NULL) {
- return CKR_DEVICE_ERROR;
- }
-
- param.data = pPBEMechanism->pParameter;
- param.len = pPBEMechanism->ulParameterLen;
-
- symKey = PK11_RawPBEKeyGen(intSlot,
- pPBEMechanism->mechanism, &param, pbe_pwd, faulty3DES, NULL);
- PK11_FreeSlot(intSlot);
- if (symKey== NULL) {
- return CKR_DEVICE_ERROR; /* sigh */
- }
- PK11_FreeSymKey(symKey);
- }
- }
-
- switch(pPBEMechanism->mechanism) {
- case CKM_PBE_MD2_DES_CBC:
- case CKM_PBE_MD5_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- pCryptoMechanism->mechanism = CKM_DES_CBC;
- goto have_crypto_mechanism;
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- pCryptoMechanism->mechanism = CKM_DES3_CBC;
-have_crypto_mechanism:
- pCryptoMechanism->pParameter = PORT_Alloc(iv_len);
- pCryptoMechanism->ulParameterLen = (CK_ULONG)iv_len;
- if(pCryptoMechanism->pParameter == NULL) {
- return CKR_HOST_MEMORY;
- }
- PORT_Memcpy((unsigned char *)(pCryptoMechanism->pParameter),
- (unsigned char *)(pPBEparams->pInitVector),
- iv_len);
- break;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- case CKM_PBE_SHA1_RC4_40:
- case CKM_PBE_SHA1_RC4_128:
- pCryptoMechanism->mechanism = CKM_RC4;
- pCryptoMechanism->ulParameterLen = 0;
- pCryptoMechanism->pParameter = CK_NULL_PTR;
- break;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- case CKM_PBE_SHA1_RC2_40_CBC:
- rc2_key_len = 40;
- goto have_key_len;
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- rc2_key_len = 128;
-have_key_len:
- pCryptoMechanism->mechanism = CKM_RC2_CBC;
- pCryptoMechanism->ulParameterLen = (CK_ULONG)
- sizeof(CK_RC2_CBC_PARAMS);
- pCryptoMechanism->pParameter = (CK_RC2_CBC_PARAMS_PTR)
- PORT_ZAlloc(sizeof(CK_RC2_CBC_PARAMS));
- if(pCryptoMechanism->pParameter == NULL) {
- return CKR_HOST_MEMORY;
- }
- rc2_params = (CK_RC2_CBC_PARAMS_PTR)pCryptoMechanism->pParameter;
- PORT_Memcpy((unsigned char *)rc2_params->iv,
- (unsigned char *)pPBEparams->pInitVector,
- iv_len);
- rc2_params->ulEffectiveBits = rc2_key_len;
- break;
- default:
- return CKR_MECHANISM_INVALID;
- }
-
- return CKR_OK;
-}
-
-/* Make a Key type to an appropriate signing/verification mechanism */
-CK_MECHANISM_TYPE
-PK11_MapSignKeyType(KeyType keyType)
-{
- switch (keyType) {
- case rsaKey:
- return CKM_RSA_PKCS;
- case fortezzaKey:
- case dsaKey:
- return CKM_DSA;
- case ecKey:
- return CKM_ECDSA;
- case dhKey:
- default:
- break;
- }
- return CKM_INVALID_MECHANISM;
-}
-
-CK_MECHANISM_TYPE
-pk11_mapWrapKeyType(KeyType keyType)
-{
- switch (keyType) {
- case rsaKey:
- return CKM_RSA_PKCS;
- /* Add fortezza?? */
- default:
- break;
- }
- return CKM_INVALID_MECHANISM;
-}
-
-SECOidTag
-PK11_FortezzaMapSig(SECOidTag algTag)
-{
- switch (algTag) {
- case SEC_OID_MISSI_KEA_DSS:
- case SEC_OID_MISSI_DSS:
- case SEC_OID_MISSI_DSS_OLD:
- case SEC_OID_MISSI_KEA_DSS_OLD:
- case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST:
- return SEC_OID_ANSIX9_DSA_SIGNATURE;
- default:
- break;
- }
- return algTag;
-}
diff --git a/security/nss/lib/pk11wrap/pk11merge.c b/security/nss/lib/pk11wrap/pk11merge.c
deleted file mode 100644
index 8c966d2d0..000000000
--- a/security/nss/lib/pk11wrap/pk11merge.c
+++ /dev/null
@@ -1,1419 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Merge the source token into the target token.
- */
-
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pk11pub.h"
-#include "pk11priv.h"
-#include "pkcs11.h"
-#include "seccomon.h"
-#include "secerr.h"
-#include "keyhi.h"
-#include "hasht.h"
-#include "cert.h"
-#include "certdb.h"
-
-/*************************************************************************
- *
- * short utilities to aid in the merge
- *
- *************************************************************************/
-
-/*
- * write a bunch of attributes out to an existing object.
- */
-static SECStatus
-pk11_setAttributes(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE *setTemplate, CK_ULONG setTemplCount)
-{
- CK_RV crv;
- CK_SESSION_HANDLE rwsession;
-
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id,
- setTemplate, setTemplCount);
- PK11_RestoreROSession(slot, rwsession);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-
-/*
- * copy a template of attributes from a source object to a target object.
- * if target object is not given, create it.
- */
-static SECStatus
-pk11_copyAttributes(PRArenaPool *arena,
- PK11SlotInfo *targetSlot, CK_OBJECT_HANDLE targetID,
- PK11SlotInfo *sourceSlot, CK_OBJECT_HANDLE sourceID,
- CK_ATTRIBUTE *copyTemplate, CK_ULONG copyTemplateCount)
-{
- SECStatus rv = PK11_GetAttributes(arena, sourceSlot, sourceID,
- copyTemplate, copyTemplateCount);
- if (rv != SECSuccess) {
- return rv;
- }
- if (targetID == CK_INVALID_HANDLE) {
- /* we need to create the object */
- rv = PK11_CreateNewObject(targetSlot, CK_INVALID_SESSION,
- copyTemplate, copyTemplateCount, PR_TRUE, &targetID);
- } else {
- /* update the existing object with the new attributes */
- rv = pk11_setAttributes(targetSlot, targetID,
- copyTemplate, copyTemplateCount);
- }
- return rv;
-}
-
-/*
- * look for a matching object across tokens.
- */
-static SECStatus
-pk11_matchAcrossTokens(PRArenaPool *arena, PK11SlotInfo *targetSlot,
- PK11SlotInfo *sourceSlot,
- CK_ATTRIBUTE *template, CK_ULONG tsize,
- CK_OBJECT_HANDLE id, CK_OBJECT_HANDLE *peer)
-{
-
- CK_RV crv;
- *peer = CK_INVALID_HANDLE;
-
- crv = PK11_GetAttributes(arena, sourceSlot, id, template, tsize);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
- }
-
- if (template[0].ulValueLen == -1) {
- crv = CKR_ATTRIBUTE_TYPE_INVALID;
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
- }
-
- *peer = pk11_FindObjectByTemplate(targetSlot, template, tsize);
- return SECSuccess;
-
-loser:
- return SECFailure;
-}
-
-/*
- * Encrypt using key and parameters
- */
-SECStatus
-pk11_encrypt(PK11SymKey *symKey, CK_MECHANISM_TYPE mechType, SECItem *param,
- SECItem *input, SECItem **output)
-{
- PK11Context *ctxt = NULL;
- SECStatus rv = SECSuccess;
-
- if (*output) {
- SECITEM_FreeItem(*output,PR_TRUE);
- }
- *output = SECITEM_AllocItem(NULL, NULL, input->len+20 /*slop*/);
- if (!*output) {
- rv = SECFailure;
- goto done;
- }
-
- ctxt = PK11_CreateContextBySymKey(mechType, CKA_ENCRYPT, symKey, param);
- if (ctxt == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- rv = PK11_CipherOp(ctxt, (*output)->data,
- (int *)&((*output)->len),
- (*output)->len, input->data, input->len);
-
-done:
- if (ctxt) {
- PK11_Finalize(ctxt);
- PK11_DestroyContext(ctxt,PR_TRUE);
- }
- if (rv != SECSuccess) {
- if (*output) {
- SECITEM_FreeItem(*output, PR_TRUE);
- *output = NULL;
- }
- }
- return rv;
-}
-
-
-
-/*************************************************************************
- *
- * Private Keys
- *
- *************************************************************************/
-
-/*
- * Fetch the key usage based on the pkcs #11 flags
- */
-unsigned int
-pk11_getPrivateKeyUsage(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
-{
- unsigned int usage = 0;
-
- if ((PK11_HasAttributeSet(slot, id, CKA_UNWRAP,PR_FALSE) ||
- PK11_HasAttributeSet(slot,id, CKA_DECRYPT,PR_FALSE))) {
- usage |= KU_KEY_ENCIPHERMENT;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_DERIVE, PR_FALSE)) {
- usage |= KU_KEY_AGREEMENT;
- }
- if ((PK11_HasAttributeSet(slot, id, CKA_SIGN_RECOVER, PR_FALSE) ||
- PK11_HasAttributeSet(slot, id, CKA_SIGN, PR_FALSE))) {
- usage |= KU_DIGITAL_SIGNATURE;
- }
- return usage;
-}
-
-
-/*
- * merge a private key,
- *
- * Private keys are merged using PBE wrapped keys with a random
- * value as the 'password'. Once the base key is moved, The remaining
- * attributes (SUBJECT) is copied.
- */
-static SECStatus
-pk11_mergePrivateKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- SECKEYPrivateKey *sourceKey = NULL;
- CK_OBJECT_HANDLE targetKeyID;
- SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- char *nickname = NULL;
- SECItem nickItem;
- SECItem pwitem;
- SECItem publicValue;
- PRArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- unsigned int keyUsage;
- unsigned char randomData[SHA1_LENGTH];
- SECOidTag algTag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- CK_ATTRIBUTE privTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- CK_ULONG privTemplateCount = sizeof(privTemplate)/sizeof(privTemplate[0]);
- CK_ATTRIBUTE privCopyTemplate[] = {
- { CKA_SUBJECT, NULL, 0 }
- };
- CK_ULONG privCopyTemplateCount =
- sizeof(privCopyTemplate)/sizeof(privCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* check to see if the key is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, privTemplate,
- privTemplateCount, id, &targetKeyID);
- if (rv != SECSuccess) {
- goto done;
- }
-
- if (targetKeyID != CK_INVALID_HANDLE) {
- /* match found, not an error ... */
- goto done;
- }
-
- /* get an NSS representation of our source key */
- sourceKey = PK11_MakePrivKey(sourceSlot, nullKey, PR_FALSE,
- id, sourcePwArg);
- if (sourceKey == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* Load the private key */
- /* generate a random pwitem */
- rv = PK11_GenerateRandom(randomData, sizeof(randomData));
- if (rv != SECSuccess) {
- goto done;
- }
- pwitem.data = randomData;
- pwitem.len = sizeof(randomData);
- /* fetch the private key encrypted */
- epki = PK11_ExportEncryptedPrivKeyInfo(sourceSlot, algTag, &pwitem,
- sourceKey, 1, sourcePwArg);
- if (epki == NULL) {
- rv = SECFailure;
- goto done;
- }
- nickname = PK11_GetObjectNickname(sourceSlot, id);
- /* NULL nickanme is fine (in fact is often normal) */
- if (nickname) {
- nickItem.data = (unsigned char *)nickname;
- nickItem.len = PORT_Strlen(nickname);
- }
- keyUsage = pk11_getPrivateKeyUsage(sourceSlot, id);
- /* pass in the CKA_ID */
- publicValue.data = privTemplate[0].pValue;
- publicValue.len = privTemplate[0].ulValueLen;
- rv = PK11_ImportEncryptedPrivateKeyInfo(targetSlot, epki, &pwitem,
- nickname? &nickItem : NULL , &publicValue,
- PR_TRUE, PR_TRUE, sourceKey->keyType, keyUsage,
- targetPwArg);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* make sure it made it */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, privTemplate,
- privTemplateCount, id, &targetKeyID);
- if (rv != SECSuccess) {
- goto done;
- }
-
- if (targetKeyID == CK_INVALID_HANDLE) {
- /* this time the key should exist */
- rv = SECFailure;
- goto done;
- }
-
- /* fill in remaining attributes */
- rv = pk11_copyAttributes(arena, targetSlot, targetKeyID, sourceSlot, id,
- privCopyTemplate, privCopyTemplateCount);
-done:
- /* make sure the 'key' is cleared */
- PORT_Memset(randomData, 0, sizeof(randomData));
- if (nickname) {
- PORT_Free(nickname);
- }
- if (sourceKey) {
- SECKEY_DestroyPrivateKey(sourceKey);
- }
- if (epki) {
- SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE);
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-
-/*************************************************************************
- *
- * Secret Keys
- *
- *************************************************************************/
-
-/*
- * we need to find a unique CKA_ID.
- * The basic idea is to just increment the lowest byte.
- * This code also handles the following corner cases:
- * 1) the single byte overflows. On overflow we increment the next byte up
- * and so forth until we have overflowed the entire CKA_ID.
- * 2) If we overflow the entire CKA_ID we expand it by one byte.
- * 3) the CKA_ID is non-existent, we create a new one with one byte.
- * This means no matter what CKA_ID is passed, the result of this function
- * is always a new CKA_ID, and this function will never return the same
- * CKA_ID the it has returned in the passed.
- */
-static SECStatus
-pk11_incrementID(PRArenaPool *arena, CK_ATTRIBUTE *ptemplate)
-{
- unsigned char *buf = ptemplate->pValue;
- CK_ULONG len = ptemplate->ulValueLen;
-
- if (buf == NULL || len == (CK_ULONG)-1) {
- /* we have no valid CKAID, we'll create a basic one byte CKA_ID below */
- len = 0;
- } else {
- CK_ULONG i;
-
- /* walk from the back to front, incrementing
- * the CKA_ID until we no longer have a carry,
- * or have hit the front of the id. */
- for (i=len; i != 0; i--) {
- buf[i-1]++;
- if (buf[i-1] != 0) {
- /* no more carries, the increment is complete */
- return SECSuccess;
- }
- }
- /* we've now overflowed, fall through and expand the CKA_ID by
- * one byte */
- }
- /* if we are here we've run the counter to zero (indicating an overflow).
- * create an CKA_ID that is all zeros, but has one more zero than
- * the previous CKA_ID */
- buf = PORT_ArenaZAlloc(arena, len+1);
- if (buf == NULL) {
- return SECFailure;
- }
- ptemplate->pValue = buf;
- ptemplate->ulValueLen = len+1;
- return SECSuccess;
-}
-
-
-static CK_FLAGS
-pk11_getSecretKeyFlags(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
-{
- CK_FLAGS flags = 0;
-
- if (PK11_HasAttributeSet(slot, id, CKA_UNWRAP, PR_FALSE)) {
- flags |= CKF_UNWRAP;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_WRAP, PR_FALSE)) {
- flags |= CKF_WRAP;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_ENCRYPT, PR_FALSE)) {
- flags |= CKF_ENCRYPT;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_DECRYPT, PR_FALSE)) {
- flags |= CKF_DECRYPT;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_DERIVE, PR_FALSE)) {
- flags |= CKF_DERIVE;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_SIGN, PR_FALSE)) {
- flags |= CKF_SIGN;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_SIGN_RECOVER, PR_FALSE)) {
- flags |= CKF_SIGN_RECOVER;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_VERIFY, PR_FALSE)) {
- flags |= CKF_VERIFY;
- }
- if (PK11_HasAttributeSet(slot, id, CKA_VERIFY_RECOVER, PR_FALSE)) {
- flags |= CKF_VERIFY_RECOVER;
- }
- return flags;
-}
-
-static const char testString[] =
- "My Encrytion Test Data (should be at least 32 bytes long)";
-/*
- * merge a secret key,
- *
- * Secret keys may collide by CKA_ID as we merge 2 token. If we collide
- * on the CKA_ID, we need to make sure we are dealing with different keys.
- * The reason for this is it is possible that we've merged this database
- * before, and this key could have been merged already. If the keys are
- * the same, we are done. If they are not, we need to update the CKA_ID of
- * the source key and try again.
- *
- * Once we know we have a unique key to merge in, we use NSS's underlying
- * key Move function which will do a key exchange if necessary to move
- * the key from one token to another. Then we set the CKA_ID and additional
- * pkcs #11 attributes.
- */
-static SECStatus
-pk11_mergeSecretKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- PK11SymKey *sourceKey = NULL;
- PK11SymKey *targetKey = NULL;
- SECItem *sourceOutput = NULL;
- SECItem *targetOutput = NULL;
- SECItem *param = NULL;
- int blockSize;
- SECItem input;
- CK_OBJECT_HANDLE targetKeyID;
- CK_FLAGS flags;
- PRArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- CK_MECHANISM_TYPE keyMechType, cryptoMechType;
- CK_KEY_TYPE sourceKeyType, targetKeyType;
- CK_ATTRIBUTE symTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- CK_ULONG symTemplateCount = sizeof(symTemplate)/sizeof(symTemplate[0]);
- CK_ATTRIBUTE symCopyTemplate[] = {
- { CKA_LABEL, NULL, 0 }
- };
- CK_ULONG symCopyTemplateCount =
- sizeof(symCopyTemplate)/sizeof(symCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- sourceKeyType = PK11_ReadULongAttribute(sourceSlot, id, CKA_KEY_TYPE);
- if (sourceKeyType == (CK_ULONG) -1) {
- rv = SECFailure;
- goto done;
- }
-
- /* get the key mechanism */
- keyMechType = PK11_GetKeyMechanism(sourceKeyType);
- /* get a mechanism suitable to encryption.
- * PK11_GetKeyMechanism returns a mechanism that is unique to the key
- * type. It tries to return encryption/decryption mechanisms, however
- * CKM_DES3_CBC uses and abmiguous keyType, so keyMechType is returned as
- * 'keygen' mechanism. Detect that case here */
- cryptoMechType = keyMechType;
- if ((keyMechType == CKM_DES3_KEY_GEN) ||
- (keyMechType == CKM_DES2_KEY_GEN)) {
- cryptoMechType = CKM_DES3_CBC;
- }
-
- sourceKey = PK11_SymKeyFromHandle(sourceSlot, NULL, PK11_OriginDerive,
- keyMechType , id, PR_FALSE, sourcePwArg);
- if (sourceKey == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* check to see a key with the same CKA_ID already exists in
- * the target slot. If it does, then we need to verify if the keys
- * really matches. If they don't import the key with a new CKA_ID
- * value. */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot,
- symTemplate, symTemplateCount, id, &targetKeyID);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* set up the input test */
- input.data = (unsigned char *)testString;
- blockSize = PK11_GetBlockSize(cryptoMechType, NULL);
- if (blockSize < 0) {
- rv = SECFailure;
- goto done;
- }
- input.len = blockSize;
- if (input.len == 0) {
- input.len = sizeof (testString);
- }
- while (targetKeyID != CK_INVALID_HANDLE) {
- /* test to see if the keys are identical */
- targetKeyType = PK11_ReadULongAttribute(sourceSlot, id, CKA_KEY_TYPE);
- if (targetKeyType == sourceKeyType) {
- /* same keyType - see if it's the same key */
- targetKey = PK11_SymKeyFromHandle(targetSlot, NULL,
- PK11_OriginDerive, keyMechType, targetKeyID, PR_FALSE,
- targetPwArg);
- /* get a parameter if we don't already have one */
- if (!param) {
- param = PK11_GenerateNewParam(cryptoMechType, sourceKey);
- if (param == NULL) {
- rv = SECFailure;
- goto done;
- }
- }
- /* use the source key to encrypt a reference */
- if (!sourceOutput) {
- rv = pk11_encrypt(sourceKey, cryptoMechType, param, &input,
- &sourceOutput);
- if (rv != SECSuccess) {
- goto done;
- }
- }
- /* encrypt the reference with the target key */
- rv = pk11_encrypt(targetKey, cryptoMechType, param, &input,
- &targetOutput);
- if (rv == SECSuccess) {
- if (SECITEM_ItemsAreEqual(sourceOutput, targetOutput)) {
- /* they produce the same output, they must be the
- * same key */
- goto done;
- }
- SECITEM_FreeItem(targetOutput, PR_TRUE);
- targetOutput = NULL;
- }
- PK11_FreeSymKey(targetKey);
- targetKey = NULL;
- }
- /* keys aren't equal, update the KEY_ID and look again */
- rv = pk11_incrementID(arena, &symTemplate[0]);
- if (rv != SECSuccess) {
- goto done;
- }
- targetKeyID = pk11_FindObjectByTemplate(targetSlot,
- symTemplate, symTemplateCount);
- }
-
- /* we didn't find a matching key, import this one with the new
- * CKAID */
- flags = pk11_getSecretKeyFlags(sourceSlot, id);
- targetKey = PK11_MoveSymKey(targetSlot, PK11_OriginDerive, flags, PR_TRUE,
- sourceKey);
- if (targetKey == NULL) {
- rv = SECFailure;
- goto done;
- }
- /* set the key new CKAID */
- rv = pk11_setAttributes(targetSlot, targetKey->objectID, symTemplate, 1);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* fill in remaining attributes */
- rv = pk11_copyAttributes(arena, targetSlot, targetKey->objectID,
- sourceSlot, id, symCopyTemplate, symCopyTemplateCount);
-done:
- if (sourceKey) {
- PK11_FreeSymKey(sourceKey);
- }
- if (targetKey) {
- PK11_FreeSymKey(targetKey);
- }
- if (sourceOutput) {
- SECITEM_FreeItem(sourceOutput, PR_TRUE);
- }
- if (targetOutput) {
- SECITEM_FreeItem(targetOutput, PR_TRUE);
- }
- if (param) {
- SECITEM_FreeItem(param, PR_TRUE);
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-/*************************************************************************
- *
- * Public Keys
- *
- *************************************************************************/
-
-/*
- * Merge public key
- *
- * Use the high level NSS calls to extract the public key and import it
- * into the token. Extra attributes are then copied to the new token.
- */
-static SECStatus
-pk11_mergePublicKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- SECKEYPublicKey *sourceKey = NULL;
- CK_OBJECT_HANDLE targetKeyID;
- PRArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- CK_ATTRIBUTE pubTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- CK_ULONG pubTemplateCount = sizeof(pubTemplate)/sizeof(pubTemplate[0]);
- CK_ATTRIBUTE pubCopyTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 }
- };
- CK_ULONG pubCopyTemplateCount =
- sizeof(pubCopyTemplate)/sizeof(pubCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
-
-
- /* check to see if the key is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, pubTemplate,
- pubTemplateCount, id, &targetKeyID);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* Key is already in the target slot */
- if (targetKeyID != CK_INVALID_HANDLE) {
- /* not an error ... */
- goto done;
- }
-
- /* fetch an NSS representation of the public key */
- sourceKey = PK11_ExtractPublicKey(sourceSlot, nullKey, id);
- if (sourceKey== NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* load the public key into the target token. */
- targetKeyID = PK11_ImportPublicKey(targetSlot, sourceKey, PR_TRUE);
- if (targetKeyID == CK_INVALID_HANDLE) {
- rv = SECFailure;
- goto done;
- }
-
- /* fill in remaining attributes */
- rv = pk11_copyAttributes(arena, targetSlot, targetKeyID, sourceSlot, id,
- pubCopyTemplate, pubCopyTemplateCount);
-
-
-done:
- if (sourceKey) {
- SECKEY_DestroyPublicKey(sourceKey);
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-/*************************************************************************
- *
- * Certificates
- *
- *************************************************************************/
-
-/*
- * Two copies of the source code for this algorithm exist in NSS.
- * Changes must be made in both copies.
- * The other copy is in sftkdb_resolveConflicts() in softoken/sftkdb.c.
- */
-static char *
-pk11_IncrementNickname(char *nickname)
-{
- char *newNickname = NULL;
- int end;
- int digit;
- int len = strlen(nickname);
-
- /* does nickname end with " #n*" ? */
- for (end = len - 1;
- end >= 2 && (digit = nickname[end]) <= '9' && digit >= '0';
- end--) /* just scan */ ;
- if (len >= 3 &&
- end < (len - 1) /* at least one digit */ &&
- nickname[end] == '#' &&
- nickname[end - 1] == ' ') {
- /* Already has a suitable suffix string */
- } else {
- /* ... append " #2" to the name */
- static const char num2[] = " #2";
- newNickname = PORT_Realloc(nickname, len + sizeof(num2));
- if (newNickname) {
- PORT_Strcat(newNickname, num2);
- } else {
- PORT_Free(nickname);
- }
- return newNickname;
- }
-
- for (end = len - 1;
- end >= 0 && (digit = nickname[end]) <= '9' && digit >= '0';
- end--) {
- if (digit < '9') {
- nickname[end]++;
- return nickname;
- }
- nickname[end] = '0';
- }
-
- /* we overflowed, insert a new '1' for a carry in front of the number */
- newNickname = PORT_Realloc(nickname, len + 2);
- if (newNickname) {
- newNickname[++end] = '1';
- PORT_Memset(&newNickname[end + 1], '0', len - end);
- newNickname[len + 1] = 0;
- } else {
- PORT_Free(nickname);
- }
- return newNickname;
-}
-
-/*
- * merge a certificate object
- *
- * Use the high level NSS calls to extract and import the certificate.
- */
-static SECStatus
-pk11_mergeCert(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- CERTCertificate *sourceCert = NULL;
- CK_OBJECT_HANDLE targetCertID = CK_INVALID_HANDLE;
- char *nickname = NULL;
- SECStatus rv = SECSuccess;
- PRArenaPool *arena = NULL;
- CK_ATTRIBUTE sourceCKAID = {CKA_ID, NULL, 0};
- CK_ATTRIBUTE targetCKAID = {CKA_ID, NULL, 0};
- SECStatus lrv = SECSuccess;
- int error;
-
-
- sourceCert = PK11_MakeCertFromHandle(sourceSlot, id, NULL);
- if (sourceCert == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- nickname = PK11_GetObjectNickname(sourceSlot, id);
-
- /* The database code will prevent nickname collisions for certs with
- * different subjects. This code will prevent us from getting
- * actual import errors */
- if (nickname) {
- const char *tokenName = PK11_GetTokenName(targetSlot);
- char *tokenNickname = NULL;
-
- do {
- tokenNickname = PR_smprintf("%s:%s",tokenName, nickname);
- if (!tokenNickname) {
- break;
- }
- if (!SEC_CertNicknameConflict(tokenNickname,
- &sourceCert->derSubject, CERT_GetDefaultCertDB())) {
- break;
- }
- nickname = pk11_IncrementNickname(nickname);
- if (!nickname) {
- break;
- }
- PR_smprintf_free(tokenNickname);
- } while (1);
- if (tokenNickname) {
- PR_smprintf_free(tokenNickname);
- }
- }
-
-
-
- /* see if the cert is already there */
- targetCertID = PK11_FindCertInSlot(targetSlot, sourceCert, targetPwArg);
- if (targetCertID == CK_INVALID_HANDLE) {
- /* cert doesn't exist load the cert in. */
- /* OK for the nickname to be NULL, not all certs have nicknames */
- rv = PK11_ImportCert(targetSlot, sourceCert, CK_INVALID_HANDLE,
- nickname, PR_FALSE);
- goto done;
- }
-
- /* the cert already exists, see if the nickname and/or CKA_ID need
- * to be updated */
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- /* does our source have a CKA_ID ? */
- rv = PK11_GetAttributes(arena, sourceSlot, id, &sourceCKAID, 1);
- if (rv != SECSuccess) {
- sourceCKAID.ulValueLen = 0;
- }
-
- /* if we have a source CKA_ID, see of we need to update the
- * target's CKA_ID */
- if (sourceCKAID.ulValueLen != 0) {
- rv = PK11_GetAttributes(arena, targetSlot, targetCertID,
- &targetCKAID, 1);
- if (rv != SECSuccess) {
- targetCKAID.ulValueLen = 0;
- }
- /* if the target has no CKA_ID, update it from the source */
- if (targetCKAID.ulValueLen == 0) {
- lrv=pk11_setAttributes(targetSlot, targetCertID, &sourceCKAID, 1);
- if (lrv != SECSuccess) {
- error = PORT_GetError();
- }
- }
- }
- rv = SECSuccess;
-
- /* now check if we need to update the nickname */
- if (nickname && *nickname) {
- char *targetname;
- targetname = PK11_GetObjectNickname(targetSlot, targetCertID);
- if (!targetname || !*targetname) {
- /* target has no nickname, or it's empty, update it */
- rv = PK11_SetObjectNickname(targetSlot, targetCertID, nickname);
- }
- if (targetname) {
- PORT_Free(targetname);
- }
- }
-
- /* restore the error code if CKA_ID failed, but nickname didn't */
- if ((rv == SECSuccess) && (lrv != SECSuccess)) {
- rv = lrv;
- PORT_SetError(error);
- }
-
-done:
- if (nickname) {
- PORT_Free(nickname);
- }
- if (sourceCert) {
- CERT_DestroyCertificate(sourceCert);
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-
-/*************************************************************************
- *
- * Crls
- *
- *************************************************************************/
-
-/*
- * Use the raw PKCS #11 interface to merge the CRLs.
- *
- * In the case where of collision, choose the newest CRL that is valid.
- */
-static SECStatus
-pk11_mergeCrl(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- CK_OBJECT_HANDLE targetCrlID;
- PRArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- CK_ATTRIBUTE crlTemplate[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- { CKA_NSS_KRL, NULL, 0 }
- };
- CK_ULONG crlTemplateCount = sizeof(crlTemplate)/sizeof(crlTemplate[0]);
- CK_ATTRIBUTE crlCopyTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_TOKEN, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_PRIVATE, NULL, 0 },
- { CKA_MODIFIABLE, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- { CKA_NSS_KRL, NULL, 0 },
- { CKA_NSS_URL, NULL, 0 },
- { CKA_VALUE, NULL, 0 }
- };
- CK_ULONG crlCopyTemplateCount =
- sizeof(crlCopyTemplate)/sizeof(crlCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
- /* check to see if the crl is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, crlTemplate,
- crlTemplateCount, id, &targetCrlID);
- if (rv != SECSuccess) {
- goto done;
- }
- if (targetCrlID != CK_INVALID_HANDLE) {
- /* we already have a CRL, check to see which is more up-to-date. */
- goto done;
- }
-
- /* load the CRL into the target token. */
- rv = pk11_copyAttributes(arena, targetSlot, targetCrlID, sourceSlot, id,
- crlCopyTemplate, crlCopyTemplateCount);
-done:
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-/*************************************************************************
- *
- * SMIME objects
- *
- *************************************************************************/
-
-/*
- * use the raw PKCS #11 interface to merge the S/MIME records
- */
-static SECStatus
-pk11_mergeSmime(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- CK_OBJECT_HANDLE targetSmimeID;
- PRArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- CK_ATTRIBUTE smimeTemplate[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_NSS_EMAIL, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- };
- CK_ULONG smimeTemplateCount =
- sizeof(smimeTemplate)/sizeof(smimeTemplate[0]);
- CK_ATTRIBUTE smimeCopyTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_TOKEN, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_PRIVATE, NULL, 0 },
- { CKA_MODIFIABLE, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- { CKA_NSS_EMAIL, NULL, 0 },
- { CKA_NSS_SMIME_TIMESTAMP, NULL, 0 },
- { CKA_VALUE, NULL, 0 }
- };
- CK_ULONG smimeCopyTemplateCount =
- sizeof(smimeCopyTemplate)/sizeof(smimeCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
- /* check to see if the crl is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, smimeTemplate,
- smimeTemplateCount, id, &targetSmimeID);
- if (rv != SECSuccess) {
- goto done;
- }
- if (targetSmimeID != CK_INVALID_HANDLE) {
- /* we already have a SMIME record */
- goto done;
- }
-
- /* load the SMime Record into the target token. */
- rv = pk11_copyAttributes(arena, targetSlot, targetSmimeID, sourceSlot, id,
- smimeCopyTemplate, smimeCopyTemplateCount);
-done:
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return rv;
-}
-
-/*************************************************************************
- *
- * Trust Objects
- *
- *************************************************************************/
-
-
-/*
- * decide which trust record entry wins. PR_TRUE (source) or PR_FALSE (target)
- */
-#define USE_TARGET PR_FALSE
-#define USE_SOURCE PR_TRUE
-PRBool
-pk11_mergeTrustEntry(CK_ATTRIBUTE *target, CK_ATTRIBUTE *source)
-{
- CK_ULONG targetTrust = (target->ulValueLen == sizeof (CK_LONG)) ?
- *(CK_ULONG *)target->pValue : CKT_NSS_TRUST_UNKNOWN;
- CK_ULONG sourceTrust = (source->ulValueLen == sizeof (CK_LONG)) ?
- *(CK_ULONG *)source->pValue : CKT_NSS_TRUST_UNKNOWN;
-
- /*
- * Examine a single entry and deside if the source or target version
- * should win out. When all the entries have been checked, if there is
- * any case we need to update, we will write the whole source record
- * to the target database. That means for each individual record, if the
- * target wins, we need to update the source (in case later we have a
- * case where the source wins). If the source wins, it already
- */
- if (sourceTrust == targetTrust) {
- return USE_TARGET; /* which equates to 'do nothing' */
- }
-
- if (sourceTrust == CKT_NSS_TRUST_UNKNOWN) {
- return USE_TARGET;
- }
-
- /* target has no idea, use the source's idea of the trust value */
- if (targetTrust == CKT_NSS_TRUST_UNKNOWN) {
- /* source overwrites the target */
- return USE_SOURCE;
- }
-
- /* so both the target and the source have some idea of what this
- * trust attribute should be, and neither agree exactly.
- * At this point, we prefer 'hard' attributes over 'soft' ones.
- * 'hard' ones are CKT_NSS_TRUSTED, CKT_NSS_TRUSTED_DELEGATOR, and
- * CKT_NSS_UNTRUTED. Soft ones are ones which don't change the
- * actual trust of the cert (CKT_MUST_VERIFY, CKT_NSS_VALID,
- * CKT_NSS_VALID_DELEGATOR).
- */
- if ((sourceTrust == CKT_NSS_MUST_VERIFY_TRUST)
- || (sourceTrust == CKT_NSS_VALID_DELEGATOR)) {
- return USE_TARGET;
- }
- if ((targetTrust == CKT_NSS_MUST_VERIFY_TRUST)
- || (targetTrust == CKT_NSS_VALID_DELEGATOR)) {
- /* source overrites the target */
- return USE_SOURCE;
- }
-
- /* both have hard attributes, we have a conflict, let the target win. */
- return USE_TARGET;
-}
-/*
- * use the raw PKCS #11 interface to merge the S/MIME records
- */
-static SECStatus
-pk11_mergeTrust(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
- CK_OBJECT_HANDLE targetTrustID;
- PRArenaPool *arena = NULL;
- SECStatus rv = SECSuccess;
- int error = 0;
- CK_ATTRIBUTE trustTemplate[] = {
- { CKA_ISSUER, NULL, 0 },
- { CKA_SERIAL_NUMBER, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- };
- CK_ULONG trustTemplateCount =
- sizeof(trustTemplate)/sizeof(trustTemplate[0]);
- CK_ATTRIBUTE trustCopyTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_TOKEN, NULL, 0 },
- { CKA_LABEL, NULL, 0 },
- { CKA_PRIVATE, NULL, 0 },
- { CKA_MODIFIABLE, NULL, 0 },
- { CKA_ISSUER, NULL, 0},
- { CKA_SERIAL_NUMBER, NULL, 0},
- { CKA_CERT_SHA1_HASH, NULL, 0 },
- { CKA_CERT_MD5_HASH, NULL, 0 },
- { CKA_TRUST_SERVER_AUTH, NULL, 0 },
- { CKA_TRUST_CLIENT_AUTH, NULL, 0 },
- { CKA_TRUST_CODE_SIGNING, NULL, 0 },
- { CKA_TRUST_EMAIL_PROTECTION, NULL, 0 },
- { CKA_TRUST_STEP_UP_APPROVED, NULL, 0 }
- };
- CK_ULONG trustCopyTemplateCount =
- sizeof(trustCopyTemplate)/sizeof(trustCopyTemplate[0]);
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- rv = SECFailure;
- goto done;
- }
- /* check to see if the crl is already in the target slot */
- rv = pk11_matchAcrossTokens(arena, targetSlot, sourceSlot, trustTemplate,
- trustTemplateCount, id, &targetTrustID);
- if (rv != SECSuccess) {
- goto done;
- }
- if (targetTrustID != CK_INVALID_HANDLE) {
- /* a matching trust record already exists, merge it in */
- CK_ATTRIBUTE_TYPE trustAttrs[] = {
- CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH,
- CKA_TRUST_CODE_SIGNING, CKA_TRUST_EMAIL_PROTECTION,
- CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER,
- CKA_TRUST_TIME_STAMPING
- };
- CK_ULONG trustAttrsCount =
- sizeof(trustAttrs)/sizeof(trustAttrs[0]);
-
- CK_ULONG i;
- CK_ATTRIBUTE targetTemplate, sourceTemplate;
-
- /* existing trust record, merge the two together */
- for (i=0; i < trustAttrsCount; i++) {
- targetTemplate.type = sourceTemplate.type = trustAttrs[i];
- targetTemplate.pValue = sourceTemplate.pValue = NULL;
- targetTemplate.ulValueLen = sourceTemplate.ulValueLen = 0;
- PK11_GetAttributes(arena, sourceSlot, id, &sourceTemplate, 1);
- PK11_GetAttributes(arena, targetSlot, targetTrustID,
- &targetTemplate, 1);
- if (pk11_mergeTrustEntry(&targetTemplate, &sourceTemplate)) {
- /* source wins, write out the source attribute to the target */
- SECStatus lrv = pk11_setAttributes(targetSlot, targetTrustID,
- &sourceTemplate, 1);
- if (lrv != SECSuccess) {
- rv = SECFailure;
- error = PORT_GetError();
- }
- }
- }
-
- /* handle step */
- sourceTemplate.type = CKA_TRUST_STEP_UP_APPROVED;
- sourceTemplate.pValue = NULL;
- sourceTemplate.ulValueLen = 0;
-
- /* if the source has steup set, then set it in the target */
- PK11_GetAttributes(arena, sourceSlot, id, &sourceTemplate, 1);
- if ((sourceTemplate.ulValueLen == sizeof(CK_BBOOL)) &&
- (sourceTemplate.pValue) &&
- (*(CK_BBOOL *)sourceTemplate.pValue == CK_TRUE)) {
- SECStatus lrv = pk11_setAttributes(targetSlot, targetTrustID,
- &sourceTemplate, 1);
- if (lrv != SECSuccess) {
- rv = SECFailure;
- error = PORT_GetError();
- }
- }
-
- goto done;
-
- }
-
- /* load the new trust Record into the target token. */
- rv = pk11_copyAttributes(arena, targetSlot, targetTrustID, sourceSlot, id,
- trustCopyTemplate, trustCopyTemplateCount);
-done:
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
-
- /* restore the error code */
- if (rv == SECFailure && error) {
- PORT_SetError(error);
- }
-
- return rv;
-}
-
-/*************************************************************************
- *
- * Central merge code
- *
- *************************************************************************/
-/*
- * merge a single object from sourceToken to targetToken
- */
-static SECStatus
-pk11_mergeObject(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE id, void *targetPwArg, void *sourcePwArg)
-{
-
- CK_OBJECT_CLASS objClass;
-
-
- objClass = PK11_ReadULongAttribute(sourceSlot, id, CKA_CLASS);
- if (objClass == (CK_ULONG) -1) {
- PORT_SetError( SEC_ERROR_UNKNOWN_OBJECT_TYPE );
- return SECFailure;
- }
-
- switch (objClass) {
- case CKO_CERTIFICATE:
- return pk11_mergeCert(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_NSS_TRUST:
- return pk11_mergeTrust(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_PUBLIC_KEY:
- return pk11_mergePublicKey(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_PRIVATE_KEY:
- return pk11_mergePrivateKey(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_SECRET_KEY:
- return pk11_mergeSecretKey(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_NSS_CRL:
- return pk11_mergeCrl(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- case CKO_NSS_SMIME:
- return pk11_mergeSmime(targetSlot, sourceSlot, id,
- targetPwArg, sourcePwArg);
- default:
- break;
- }
-
- PORT_SetError( SEC_ERROR_UNKNOWN_OBJECT_TYPE );
- return SECFailure;
-}
-
-PK11MergeLogNode *
-pk11_newMergeLogNode(PRArenaPool *arena,
- PK11SlotInfo *slot, CK_OBJECT_HANDLE id, int error)
-{
- PK11MergeLogNode *newLog;
- PK11GenericObject *obj;
-
- newLog = PORT_ArenaZNew(arena, PK11MergeLogNode);
- if (newLog == NULL) {
- return NULL;
- }
-
- obj = PORT_ArenaZNew(arena, PK11GenericObject);
- if ( !obj ) {
- return NULL;
- }
-
- /* initialize it */
- obj->slot = slot;
- obj->objectID = id;
-
- newLog->object= obj;
- newLog->error = error;
- return newLog;
-}
-
-/*
- * walk down each entry and merge it. keep track of the errors in the log
- */
-static SECStatus
-pk11_mergeByObjectIDs(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- CK_OBJECT_HANDLE *objectIDs, int count,
- PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
-{
- SECStatus rv = SECSuccess;
- int error, i;
-
- for (i=0; i < count; i++) {
- /* try to update the entire database. On failure, keep going,
- * but remember the error to report back to the caller */
- SECStatus lrv;
- PK11MergeLogNode *newLog;
-
- lrv= pk11_mergeObject(targetSlot, sourceSlot, objectIDs[i],
- targetPwArg, sourcePwArg);
- if (lrv == SECSuccess) {
- /* merged with no problem, go to next object */
- continue;
- }
-
- /* remember that we failed and why */
- rv = SECFailure;
- error = PORT_GetError();
-
- /* log the errors */
- if (!log) {
- /* not logging, go to next entry */
- continue;
- }
- newLog = pk11_newMergeLogNode(log->arena, sourceSlot,
- objectIDs[i], error);
- if (!newLog) {
- /* failed to allocate entry, just keep going */
- continue;
- }
-
- /* link in the errorlog entry */
- newLog->next = NULL;
- if (log->tail) {
- log->tail->next = newLog;
- } else {
- log->head = newLog;
- }
- newLog->prev = log->tail;
- log->tail = newLog;
- }
-
- /* restore the last error code */
- if (rv != SECSuccess) {
- PORT_SetError(error);
- }
- return rv;
-}
-
-/*
- * Merge all the records in sourceSlot that aren't in targetSlot
- *
- * This function will return failure if not all the objects
- * successfully merged.
- *
- * Applications can pass in an optional error log which will record
- * each failing object and why it failed to import. PK11MergeLog
- * is modelled after the CERTVerifyLog.
- */
-SECStatus
-PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- PK11MergeLog *log, void *targetPwArg, void *sourcePwArg)
-{
- SECStatus rv = SECSuccess, lrv = SECSuccess;
- int error, count = 0;
- CK_ATTRIBUTE search[2];
- CK_OBJECT_HANDLE *objectIDs = NULL;
- CK_BBOOL ck_true = CK_TRUE;
- CK_OBJECT_CLASS privKey = CKO_PRIVATE_KEY;
-
- PK11_SETATTRS(&search[0], CKA_TOKEN, &ck_true, sizeof(ck_true));
- PK11_SETATTRS(&search[1], CKA_CLASS, &privKey, sizeof(privKey));
- /*
- * make sure both tokens are already authenticated if need be.
- */
- rv = PK11_Authenticate(targetSlot, PR_TRUE, targetPwArg);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = PK11_Authenticate(sourceSlot, PR_TRUE, sourcePwArg);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* turns out the old DB's are rather fragile if the private keys aren't
- * merged in first, so do the private keys explicity. */
- objectIDs = pk11_FindObjectsByTemplate(sourceSlot, search, 2, &count);
- if (objectIDs) {
- lrv = pk11_mergeByObjectIDs(targetSlot, sourceSlot,
- objectIDs, count, log,
- targetPwArg, sourcePwArg);
- if (lrv != SECSuccess) {
- error = PORT_GetError();
- }
- PORT_Free(objectIDs);
- count = 0;
- }
-
- /* now do the rest (NOTE: this will repeat the private keys, but
- * that shouldnt' be an issue as we will notice they are already
- * merged in */
- objectIDs = pk11_FindObjectsByTemplate(sourceSlot, search, 1, &count);
- if (!objectIDs) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = pk11_mergeByObjectIDs(targetSlot, sourceSlot, objectIDs, count, log,
- targetPwArg, sourcePwArg);
- if (rv == SECSuccess) {
- /* if private keys failed, but the rest succeeded, be sure to let
- * the caller know that private keys failed and why.
- * NOTE: this is highly unlikely since the same keys that failed
- * in the previous merge call will most likely fail in this one */
- if (lrv != SECSuccess) {
- rv = lrv;
- PORT_SetError(error);
- }
- }
-
-loser:
- if (objectIDs) {
- PORT_Free(objectIDs);
- }
- return rv;
-}
-
-PK11MergeLog *
-PK11_CreateMergeLog(void)
-{
- PRArenaPool *arena;
- PK11MergeLog *log;
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return NULL;
- }
-
- log = PORT_ArenaZNew(arena, PK11MergeLog);
- if (log == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
- log->arena = arena;
- log->version = 1;
- return log;
-}
-
-void
-PK11_DestroyMergeLog(PK11MergeLog *log)
-{
- if (log && log->arena) {
- PORT_FreeArena(log->arena, PR_FALSE);
- }
-}
diff --git a/security/nss/lib/pk11wrap/pk11nobj.c b/security/nss/lib/pk11wrap/pk11nobj.c
deleted file mode 100644
index db2b6fb3a..000000000
--- a/security/nss/lib/pk11wrap/pk11nobj.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file manages Netscape specific PKCS #11 objects (CRLs, Trust objects,
- * etc).
- */
-
-#include "secport.h"
-#include "seccomon.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11.h"
-#include "pk11func.h"
-#include "cert.h"
-#include "certi.h"
-#include "secitem.h"
-#include "sechash.h"
-#include "secoid.h"
-
-#include "certdb.h"
-#include "secerr.h"
-#include "sslerr.h"
-
-#include "pki3hack.h"
-#include "dev3hack.h"
-
-#include "devm.h"
-#include "pki.h"
-#include "pkim.h"
-
-extern const NSSError NSS_ERROR_NOT_FOUND;
-
-CK_TRUST
-pk11_GetTrustField(PK11SlotInfo *slot, PRArenaPool *arena,
- CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type)
-{
- CK_TRUST rv = 0;
- SECItem item;
-
- item.data = NULL;
- item.len = 0;
-
- if( SECSuccess == PK11_ReadAttribute(slot, id, type, arena, &item) ) {
- PORT_Assert(item.len == sizeof(CK_TRUST));
- PORT_Memcpy(&rv, item.data, sizeof(CK_TRUST));
- /* Damn, is there an endian problem here? */
- return rv;
- }
-
- return 0;
-}
-
-PRBool
-pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust *trust)
-{
- PRArenaPool *arena;
-
- CK_ATTRIBUTE tobjTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_CERT_SHA1_HASH, NULL, 0 },
- };
-
- CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
- CK_OBJECT_HANDLE tobjID;
- unsigned char sha1_hash[SHA1_LENGTH];
-
- CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth;
-
- PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len);
-
- PK11_SETATTRS(&tobjTemplate[0], CKA_CLASS, &tobjc, sizeof(tobjc));
- PK11_SETATTRS(&tobjTemplate[1], CKA_CERT_SHA1_HASH, sha1_hash,
- SHA1_LENGTH);
-
- tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate,
- sizeof(tobjTemplate)/sizeof(tobjTemplate[0]));
- if( CK_INVALID_HANDLE == tobjID ) {
- return PR_FALSE;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if( NULL == arena ) return PR_FALSE;
-
- /* Unfortunately, it seems that PK11_GetAttributes doesn't deal
- * well with nonexistent attributes. I guess we have to check
- * the trust info fields one at a time.
- */
-
- /* We could verify CKA_CERT_HASH here */
-
- /* We could verify CKA_EXPIRES here */
-
-
- /* "Purpose" trust information */
- serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH);
- clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH);
- codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING);
- emailProtection = pk11_GetTrustField(slot, arena, tobjID,
- CKA_TRUST_EMAIL_PROTECTION);
- /* Here's where the fun logic happens. We have to map back from the
- * key usage, extended key usage, purpose, and possibly other trust values
- * into the old trust-flags bits. */
-
- /* First implementation: keep it simple for testing. We can study what other
- * mappings would be appropriate and add them later.. fgmr 20000724 */
-
- if ( serverAuth == CKT_NSS_TRUSTED ) {
- trust->sslFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
- }
-
- if ( serverAuth == CKT_NSS_TRUSTED_DELEGATOR ) {
- trust->sslFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA |
- CERTDB_NS_TRUSTED_CA;
- }
- if ( clientAuth == CKT_NSS_TRUSTED_DELEGATOR ) {
- trust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA ;
- }
-
- if ( emailProtection == CKT_NSS_TRUSTED ) {
- trust->emailFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
- }
-
- if ( emailProtection == CKT_NSS_TRUSTED_DELEGATOR ) {
- trust->emailFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
- }
-
- if( codeSigning == CKT_NSS_TRUSTED ) {
- trust->objectSigningFlags |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
- }
-
- if( codeSigning == CKT_NSS_TRUSTED_DELEGATOR ) {
- trust->objectSigningFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
- }
-
- /* There's certainly a lot more logic that can go here.. */
-
- PORT_FreeArena(arena, PR_FALSE);
-
- return PR_TRUE;
-}
-
-static SECStatus
-pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
-{
- SECItem derCrl;
- CERTCrlHeadNode *head = (CERTCrlHeadNode *) arg;
- CERTCrlNode *new_node = NULL;
- CK_ATTRIBUTE fetchCrl[3] = {
- { CKA_VALUE, NULL, 0},
- { CKA_NETSCAPE_KRL, NULL, 0},
- { CKA_NETSCAPE_URL, NULL, 0},
- };
- const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]);
- CK_RV crv;
- SECStatus rv = SECFailure;
-
- crv = PK11_GetAttributes(head->arena,slot,crlID,fetchCrl,fetchCrlSize);
- if (CKR_OK != crv) {
- PORT_SetError(PK11_MapError(crv));
- goto loser;
- }
-
- if (!fetchCrl[1].pValue) {
- PORT_SetError(SEC_ERROR_CRL_INVALID);
- goto loser;
- }
-
- new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode));
- if (new_node == NULL) {
- goto loser;
- }
-
- if (*((CK_BBOOL *)fetchCrl[1].pValue))
- new_node->type = SEC_KRL_TYPE;
- else
- new_node->type = SEC_CRL_TYPE;
-
- derCrl.type = siBuffer;
- derCrl.data = (unsigned char *)fetchCrl[0].pValue;
- derCrl.len = fetchCrl[0].ulValueLen;
- new_node->crl=CERT_DecodeDERCrl(head->arena,&derCrl,new_node->type);
- if (new_node->crl == NULL) {
- goto loser;
- }
-
- if (fetchCrl[2].pValue) {
- int nnlen = fetchCrl[2].ulValueLen;
- new_node->crl->url = (char *)PORT_ArenaAlloc(head->arena, nnlen+1);
- if ( !new_node->crl->url ) {
- goto loser;
- }
- PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
- new_node->crl->url[nnlen] = 0;
- } else {
- new_node->crl->url = NULL;
- }
-
-
- new_node->next = NULL;
- if (head->last) {
- head->last->next = new_node;
- head->last = new_node;
- } else {
- head->first = head->last = new_node;
- }
- rv = SECSuccess;
-
-loser:
- return(rv);
-}
-
-/*
- * Return a list of all the CRLs .
- * CRLs are allocated in the list's arena.
- */
-SECStatus
-PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) {
- pk11TraverseSlot creater;
- CK_ATTRIBUTE theTemplate[2];
- CK_ATTRIBUTE *attrs;
- CK_OBJECT_CLASS certClass = CKO_NETSCAPE_CRL;
- CK_BBOOL isKrl = CK_FALSE;
-
- attrs = theTemplate;
- PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++;
- if (type != -1) {
- isKrl = (CK_BBOOL) (type == SEC_KRL_TYPE);
- PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, &isKrl, sizeof(isKrl)); attrs++;
- }
-
- creater.callback = pk11_CollectCrls;
- creater.callbackArg = (void *) nodes;
- creater.findTemplate = theTemplate;
- creater.templateCount = (attrs - theTemplate);
-
- return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
-}
-
-struct crlOptionsStr {
- CERTCrlHeadNode* head;
- PRInt32 decodeOptions;
-};
-
-typedef struct crlOptionsStr crlOptions;
-
-static SECStatus
-pk11_RetrieveCrlsCallback(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID,
- void *arg)
-{
- SECItem* derCrl = NULL;
- crlOptions* options = (crlOptions*) arg;
- CERTCrlHeadNode *head = options->head;
- CERTCrlNode *new_node = NULL;
- CK_ATTRIBUTE fetchCrl[3] = {
- { CKA_VALUE, NULL, 0},
- { CKA_NETSCAPE_KRL, NULL, 0},
- { CKA_NETSCAPE_URL, NULL, 0},
- };
- const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]);
- CK_RV crv;
- SECStatus rv = SECFailure;
- PRBool adopted = PR_FALSE; /* whether the CRL adopted the DER memory
- successfully */
- int i;
-
- crv = PK11_GetAttributes(NULL,slot,crlID,fetchCrl,fetchCrlSize);
- if (CKR_OK != crv) {
- PORT_SetError(PK11_MapError(crv));
- goto loser;
- }
-
- if (!fetchCrl[1].pValue) {
- /* reject KRLs */
- PORT_SetError(SEC_ERROR_CRL_INVALID);
- goto loser;
- }
-
- new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena,
- sizeof(CERTCrlNode));
- if (new_node == NULL) {
- goto loser;
- }
-
- new_node->type = SEC_CRL_TYPE;
-
- derCrl = SECITEM_AllocItem(NULL, NULL, 0);
- if (!derCrl) {
- goto loser;
- }
- derCrl->type = siBuffer;
- derCrl->data = (unsigned char *)fetchCrl[0].pValue;
- derCrl->len = fetchCrl[0].ulValueLen;
- new_node->crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl,new_node->type,
- options->decodeOptions);
- if (new_node->crl == NULL) {
- goto loser;
- }
- adopted = PR_TRUE; /* now that the CRL has adopted the DER memory,
- we won't need to free it upon exit */
-
- if (fetchCrl[2].pValue && fetchCrl[2].ulValueLen) {
- /* copy the URL if there is one */
- int nnlen = fetchCrl[2].ulValueLen;
- new_node->crl->url = (char *)PORT_ArenaAlloc(new_node->crl->arena,
- nnlen+1);
- if ( !new_node->crl->url ) {
- goto loser;
- }
- PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
- new_node->crl->url[nnlen] = 0;
- } else {
- new_node->crl->url = NULL;
- }
-
- new_node->next = NULL;
- if (head->last) {
- head->last->next = new_node;
- head->last = new_node;
- } else {
- head->first = head->last = new_node;
- }
- rv = SECSuccess;
- new_node->crl->slot = PK11_ReferenceSlot(slot);
- new_node->crl->pkcs11ID = crlID;
-
-loser:
- /* free attributes that weren't adopted by the CRL */
- for (i=1;i<fetchCrlSize;i++) {
- if (fetchCrl[i].pValue) {
- PORT_Free(fetchCrl[i].pValue);
- }
- }
- /* free the DER if the CRL object didn't adopt it */
- if (fetchCrl[0].pValue && PR_FALSE == adopted) {
- PORT_Free(fetchCrl[0].pValue);
- }
- if (derCrl && !adopted) {
- /* clear the data fields, which we already took care of above */
- derCrl->data = NULL;
- derCrl->len = 0;
- /* free the memory for the SECItem structure itself */
- SECITEM_FreeItem(derCrl, PR_TRUE);
- }
- return(rv);
-}
-
-/*
- * Return a list of CRLs matching specified issuer and type
- * CRLs are not allocated in the list's arena, but rather in their own,
- * arena, so that they can be used individually in the CRL cache .
- * CRLs are always partially decoded for efficiency.
- */
-SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer,
- void *wincx)
-{
- pk11TraverseSlot creater;
- CK_ATTRIBUTE theTemplate[2];
- CK_ATTRIBUTE *attrs;
- CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
- crlOptions options;
-
- attrs = theTemplate;
- PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;
-
- options.head = nodes;
-
- /* - do a partial decoding - we don't need to decode the entries while
- fetching
- - don't copy the DER for optimal performance - CRL can be very large
- - have the CRL objects adopt the DER, so SEC_DestroyCrl will free it
- - keep bad CRL objects. The CRL cache is interested in them, for
- security purposes. Bad CRL objects are a sign of something amiss.
- */
-
- options.decodeOptions = CRL_DECODE_SKIP_ENTRIES | CRL_DECODE_DONT_COPY_DER |
- CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_KEEP_BAD_CRL;
- if (issuer)
- {
- PK11_SETATTRS(attrs, CKA_SUBJECT, issuer->data, issuer->len); attrs++;
- }
-
- creater.callback = pk11_RetrieveCrlsCallback;
- creater.callbackArg = (void *) &options;
- creater.findTemplate = theTemplate;
- creater.templateCount = (attrs - theTemplate);
-
- return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
-}
-
-/*
- * return the crl associated with a derSubjectName
- */
-SECItem *
-PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
- SECItem *name, int type, char **pUrl)
-{
- NSSCRL **crls, **crlp, *crl = NULL;
- NSSDER subject;
- SECItem *rvItem;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- char * url = NULL;
-
- PORT_SetError(0);
- NSSITEM_FROM_SECITEM(&subject, name);
- if (*slot) {
- nssCryptokiObject **instances;
- nssPKIObjectCollection *collection;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- NSSToken *token = PK11Slot_GetNSSToken(*slot);
- collection = nssCRLCollection_Create(td, NULL);
- if (!collection) {
- goto loser;
- }
- instances = nssToken_FindCRLsBySubject(token, NULL, &subject,
- tokenOnly, 0, NULL);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
- crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
- nssPKIObjectCollection_Destroy(collection);
- } else {
- crls = nssTrustDomain_FindCRLsBySubject(td, &subject);
- }
- if ((!crls) || (*crls == NULL)) {
- if (crls) {
- nssCRLArray_Destroy(crls);
- }
- if (NSS_GetError() == NSS_ERROR_NOT_FOUND) {
- PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
- }
- goto loser;
- }
- for (crlp = crls; *crlp; crlp++) {
- if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) ||
- ((*crlp)->isKRL && type != SEC_CRL_TYPE))
- {
- crl = nssCRL_AddRef(*crlp);
- break;
- }
- }
- nssCRLArray_Destroy(crls);
- if (!crl) {
- /* CRL collection was found, but no interesting CRL's were on it.
- * Not an error */
- PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
- goto loser;
- }
- if (crl->url) {
- url = PORT_Strdup(crl->url);
- if (!url) {
- goto loser;
- }
- }
- rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size);
- if (!rvItem) {
- goto loser;
- }
- memcpy(rvItem->data, crl->encoding.data, crl->encoding.size);
- *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot);
- *crlHandle = crl->object.instances[0]->handle;
- *pUrl = url;
- nssCRL_Destroy(crl);
- return rvItem;
-
-loser:
- if (url)
- PORT_Free(url);
- if (crl)
- nssCRL_Destroy(crl);
- if (PORT_GetError() == 0) {
- PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
- }
- return NULL;
-}
-
-CK_OBJECT_HANDLE
-PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
- char *url, int type)
-{
- NSSItem derCRL, derSubject;
- NSSToken *token = PK11Slot_GetNSSToken(slot);
- nssCryptokiObject *object;
- PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE;
- CK_OBJECT_HANDLE rvH;
-
- NSSITEM_FROM_SECITEM(&derSubject, name);
- NSSITEM_FROM_SECITEM(&derCRL, crl);
-
- object = nssToken_ImportCRL(token, NULL,
- &derSubject, &derCRL, isKRL, url, PR_TRUE);
-
- if (object) {
- rvH = object->handle;
- nssCryptokiObject_Destroy(object);
- } else {
- rvH = CK_INVALID_HANDLE;
- PORT_SetError(SEC_ERROR_CRL_IMPORT_FAILED);
- }
- return rvH;
-}
-
-
-/*
- * delete a crl.
- */
-SECStatus
-SEC_DeletePermCRL(CERTSignedCrl *crl)
-{
- PRStatus status;
- NSSToken *token;
- nssCryptokiObject *object;
- PK11SlotInfo *slot = crl->slot;
-
- if (slot == NULL) {
- PORT_Assert(slot);
- /* shouldn't happen */
- PORT_SetError( SEC_ERROR_CRL_INVALID);
- return SECFailure;
- }
- token = PK11Slot_GetNSSToken(slot);
-
- object = nss_ZNEW(NULL, nssCryptokiObject);
- if (!object) {
- return SECFailure;
- }
- object->token = nssToken_AddRef(token);
- object->handle = crl->pkcs11ID;
- object->isTokenObject = PR_TRUE;
-
- status = nssToken_DeleteStoredObject(object);
-
- nssCryptokiObject_Destroy(object);
- return (status == PR_SUCCESS) ? SECSuccess : SECFailure;
-}
-
-/*
- * return the certificate associated with a derCert
- */
-SECItem *
-PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
- SECItem *name, SECItem **profileTime)
-{
- CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_CLASS, NULL, 0 },
- { CKA_NETSCAPE_EMAIL, NULL, 0 },
- };
- CK_ATTRIBUTE smimeData[] = {
- { CKA_SUBJECT, NULL, 0 },
- { CKA_VALUE, NULL, 0 },
- };
- /* if you change the array, change the variable below as well */
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
- CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
- CK_ATTRIBUTE *attrs = theTemplate;
- CK_RV crv;
- SECItem *emailProfile = NULL;
-
- if (!emailAddr || !emailAddr[0]) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
- PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, strlen(emailAddr));
- attrs++;
-
- if (*slot) {
- smimeh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize);
- } else {
- PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
- PR_FALSE,PR_TRUE,NULL);
- PK11SlotListElement *le;
-
- if (!list) {
- return NULL;
- }
- /* loop through all the slots */
- for (le = list->head; le; le = le->next) {
- smimeh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
- if (smimeh != CK_INVALID_HANDLE) {
- *slot = PK11_ReferenceSlot(le->slot);
- break;
- }
- }
- PK11_FreeSlotList(list);
- }
-
- if (smimeh == CK_INVALID_HANDLE) {
- PORT_SetError(SEC_ERROR_NO_KRL);
- return NULL;
- }
-
- if (profileTime) {
- PK11_SETATTRS(smimeData, CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0);
- }
-
- crv = PK11_GetAttributes(NULL,*slot,smimeh,smimeData,2);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError (crv));
- goto loser;
- }
-
- if (!profileTime) {
- SECItem profileSubject;
-
- profileSubject.data = (unsigned char*) smimeData[0].pValue;
- profileSubject.len = smimeData[0].ulValueLen;
- if (!SECITEM_ItemsAreEqual(&profileSubject,name)) {
- goto loser;
- }
- }
-
- emailProfile = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if (emailProfile == NULL) {
- goto loser;
- }
-
- emailProfile->data = (unsigned char*) smimeData[1].pValue;
- emailProfile->len = smimeData[1].ulValueLen;
-
- if (profileTime) {
- *profileTime = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if (*profileTime) {
- (*profileTime)->data = (unsigned char*) smimeData[0].pValue;
- (*profileTime)->len = smimeData[0].ulValueLen;
- }
- }
-
-loser:
- if (emailProfile == NULL) {
- if (smimeData[1].pValue) {
- PORT_Free(smimeData[1].pValue);
- }
- }
- if (profileTime == NULL || *profileTime == NULL) {
- if (smimeData[0].pValue) {
- PORT_Free(smimeData[0].pValue);
- }
- }
- return emailProfile;
-}
-
-
-SECStatus
-PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
- SECItem *emailProfile, SECItem *profileTime)
-{
- CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
- CK_BBOOL ck_true = CK_TRUE;
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_TOKEN, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 },
- { CKA_NETSCAPE_EMAIL, NULL, 0 },
- { CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0 },
- { CKA_VALUE, NULL, 0 }
- };
- /* if you change the array, change the variable below as well */
- int realSize = 0;
- CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
- CK_ATTRIBUTE *attrs = theTemplate;
- CK_SESSION_HANDLE rwsession;
- PK11SlotInfo *free_slot = NULL;
- CK_RV crv;
-#ifdef DEBUG
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
-#endif
-
- PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true, sizeof(ck_true)); attrs++;
- PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len); attrs++;
- PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL,
- emailAddr, PORT_Strlen(emailAddr)+1); attrs++;
- if (profileTime) {
- PK11_SETATTRS(attrs, CKA_NETSCAPE_SMIME_TIMESTAMP, profileTime->data,
- profileTime->len); attrs++;
- PK11_SETATTRS(attrs, CKA_VALUE,emailProfile->data,
- emailProfile->len); attrs++;
- }
- realSize = attrs - theTemplate;
- PORT_Assert (realSize <= tsize);
-
- if (slot == NULL) {
- free_slot = slot = PK11_GetInternalKeySlot();
- /* we need to free the key slot in the end!!! */
- }
-
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_READ_ONLY);
- if (free_slot) {
- PK11_FreeSlot(free_slot);
- }
- return SECFailure;
- }
-
- crv = PK11_GETTAB(slot)->
- C_CreateObject(rwsession,theTemplate,realSize,&smimeh);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- }
-
- PK11_RestoreROSession(slot,rwsession);
-
- if (free_slot) {
- PK11_FreeSlot(free_slot);
- }
- return SECSuccess;
-}
-
-
-CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot,char *url,
- CERTSignedCrl *newCrl, SECItem *derCrl, int type);
-
-/* import the CRL into the token */
-
-CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url,
- int type, void *wincx, PRInt32 importOptions, PRArenaPool* arena,
- PRInt32 decodeoptions)
-{
- CERTSignedCrl *newCrl, *crl;
- SECStatus rv;
- CERTCertificate *caCert = NULL;
-
- newCrl = crl = NULL;
-
- do {
- newCrl = CERT_DecodeDERCrlWithFlags(arena, derCRL, type,
- decodeoptions);
- if (newCrl == NULL) {
- if (type == SEC_CRL_TYPE) {
- /* only promote error when the error code is too generic */
- if (PORT_GetError () == SEC_ERROR_BAD_DER)
- PORT_SetError(SEC_ERROR_CRL_INVALID);
- } else {
- PORT_SetError(SEC_ERROR_KRL_INVALID);
- }
- break;
- }
-
- if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){
- CERTCertDBHandle* handle = CERT_GetDefaultCertDB();
- PR_ASSERT(handle != NULL);
- caCert = CERT_FindCertByName (handle,
- &newCrl->crl.derName);
- if (caCert == NULL) {
- PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
- break;
- }
-
- /* If caCert is a v3 certificate, make sure that it can be used for
- crl signing purpose */
- rv = CERT_CheckCertUsage (caCert, KU_CRL_SIGN);
- if (rv != SECSuccess) {
- break;
- }
-
- rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert,
- PR_Now(), wincx);
- if (rv != SECSuccess) {
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
- } else {
- PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE);
- }
- break;
- }
- }
-
- crl = crl_storeCRL(slot, url, newCrl, derCRL, type);
-
- } while (0);
-
- if (crl == NULL) {
- SEC_DestroyCrl (newCrl);
- }
- if (caCert) {
- CERT_DestroyCertificate(caCert);
- }
- return (crl);
-}
diff --git a/security/nss/lib/pk11wrap/pk11obj.c b/security/nss/lib/pk11wrap/pk11obj.c
deleted file mode 100644
index 4fa5dde98..000000000
--- a/security/nss/lib/pk11wrap/pk11obj.c
+++ /dev/null
@@ -1,1889 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file manages object type indepentent functions.
- */
-#include "seccomon.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11.h"
-#include "pkcs11t.h"
-#include "pk11func.h"
-#include "key.h"
-#include "secitem.h"
-#include "secerr.h"
-#include "sslerr.h"
-
-#define PK11_SEARCH_CHUNKSIZE 10
-
-/*
- * Build a block big enough to hold the data
- */
-SECItem *
-PK11_BlockData(SECItem *data,unsigned long size) {
- SECItem *newData;
-
- newData = (SECItem *)PORT_Alloc(sizeof(SECItem));
- if (newData == NULL) return NULL;
-
- newData->len = (data->len + (size-1))/size;
- newData->len *= size;
-
- newData->data = (unsigned char *) PORT_ZAlloc(newData->len);
- if (newData->data == NULL) {
- PORT_Free(newData);
- return NULL;
- }
- PORT_Memset(newData->data,newData->len-data->len,newData->len);
- PORT_Memcpy(newData->data,data->data,data->len);
- return newData;
-}
-
-
-SECStatus
-PK11_DestroyObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object) {
- CK_RV crv;
-
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_DestroyObject(slot->session,object);
- PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-PK11_DestroyTokenObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object) {
- CK_RV crv;
- SECStatus rv = SECSuccess;
- CK_SESSION_HANDLE rwsession;
-
-
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
-
- crv = PK11_GETTAB(slot)->C_DestroyObject(rwsession,object);
- if (crv != CKR_OK) {
- rv = SECFailure;
- PORT_SetError(PK11_MapError(crv));
- }
- PK11_RestoreROSession(slot,rwsession);
- return rv;
-}
-
-/*
- * Read in a single attribute into a SECItem. Allocate space for it with
- * PORT_Alloc unless an arena is supplied. In the latter case use the arena
- * to allocate the space.
- */
-SECStatus
-PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE_TYPE type, PRArenaPool *arena, SECItem *result) {
- CK_ATTRIBUTE attr = { 0, NULL, 0 };
- CK_RV crv;
-
- attr.type = type;
-
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1);
- if (crv != CKR_OK) {
- PK11_ExitSlotMonitor(slot);
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- if (arena) {
- attr.pValue = PORT_ArenaAlloc(arena,attr.ulValueLen);
- } else {
- attr.pValue = PORT_Alloc(attr.ulValueLen);
- }
- if (attr.pValue == NULL) {
- PK11_ExitSlotMonitor(slot);
- return SECFailure;
- }
- crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1);
- PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- if (!arena) PORT_Free(attr.pValue);
- return SECFailure;
- }
-
- result->data = (unsigned char*)attr.pValue;
- result->len = attr.ulValueLen;
-
- return SECSuccess;
-}
-
-/*
- * Read in a single attribute into As a Ulong.
- */
-CK_ULONG
-PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE_TYPE type) {
- CK_ATTRIBUTE attr;
- CK_ULONG value = CK_UNAVAILABLE_INFORMATION;
- CK_RV crv;
-
- PK11_SETATTRS(&attr,type,&value,sizeof(value));
-
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1);
- PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- }
- return value;
-}
-
-/*
- * check to see if a bool has been set.
- */
-CK_BBOOL
-PK11_HasAttributeSet( PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE_TYPE type, PRBool haslock )
-{
- CK_BBOOL ckvalue = CK_FALSE;
- CK_ATTRIBUTE theTemplate;
- CK_RV crv;
-
- /* Prepare to retrieve the attribute. */
- PK11_SETATTRS( &theTemplate, type, &ckvalue, sizeof( CK_BBOOL ) );
-
- /* Retrieve attribute value. */
- if (!haslock) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB( slot )->C_GetAttributeValue( slot->session, id,
- &theTemplate, 1 );
- if (!haslock) PK11_ExitSlotMonitor(slot);
- if( crv != CKR_OK ) {
- PORT_SetError( PK11_MapError( crv ) );
- return CK_FALSE;
- }
-
- return ckvalue;
-}
-
-/*
- * returns a full list of attributes. Allocate space for them. If an arena is
- * provided, allocate space out of the arena.
- */
-CK_RV
-PK11_GetAttributes(PRArenaPool *arena,PK11SlotInfo *slot,
- CK_OBJECT_HANDLE obj,CK_ATTRIBUTE *attr, int count)
-{
- int i;
- /* make pedantic happy... note that it's only used arena != NULL */
- void *mark = NULL;
- CK_RV crv;
- PORT_Assert(slot->session != CK_INVALID_SESSION);
- if (slot->session == CK_INVALID_SESSION)
- return CKR_SESSION_HANDLE_INVALID;
-
- /*
- * first get all the lengths of the parameters.
- */
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,obj,attr,count);
- if (crv != CKR_OK) {
- PK11_ExitSlotMonitor(slot);
- return crv;
- }
-
- if (arena) {
- mark = PORT_ArenaMark(arena);
- if (mark == NULL) return CKR_HOST_MEMORY;
- }
-
- /*
- * now allocate space to store the results.
- */
- for (i=0; i < count; i++) {
- if (attr[i].ulValueLen == 0)
- continue;
- if (arena) {
- attr[i].pValue = PORT_ArenaAlloc(arena,attr[i].ulValueLen);
- if (attr[i].pValue == NULL) {
- /* arena failures, just release the mark */
- PORT_ArenaRelease(arena,mark);
- PK11_ExitSlotMonitor(slot);
- return CKR_HOST_MEMORY;
- }
- } else {
- attr[i].pValue = PORT_Alloc(attr[i].ulValueLen);
- if (attr[i].pValue == NULL) {
- /* Separate malloc failures, loop to release what we have
- * so far */
- int j;
- for (j= 0; j < i; j++) {
- PORT_Free(attr[j].pValue);
- /* don't give the caller pointers to freed memory */
- attr[j].pValue = NULL;
- }
- PK11_ExitSlotMonitor(slot);
- return CKR_HOST_MEMORY;
- }
- }
- }
-
- /*
- * finally get the results.
- */
- crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,obj,attr,count);
- PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- if (arena) {
- PORT_ArenaRelease(arena,mark);
- } else {
- for (i= 0; i < count; i++) {
- PORT_Free(attr[i].pValue);
- /* don't give the caller pointers to freed memory */
- attr[i].pValue = NULL;
- }
- }
- } else if (arena && mark) {
- PORT_ArenaUnmark(arena,mark);
- }
- return crv;
-}
-
-PRBool
-PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle)
-{
- return (PRBool) PK11_HasAttributeSet(slot, handle, CKA_TOKEN, PR_FALSE);
-}
-
-char *
-PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
-{
- char *nickname = NULL;
- SECItem result;
- SECStatus rv;
-
- rv = PK11_ReadAttribute(slot,id,CKA_LABEL,NULL,&result);
- if (rv != SECSuccess) {
- return NULL;
- }
-
- nickname = PORT_ZAlloc(result.len+1);
- if (nickname == NULL) {
- PORT_Free(result.data);
- return NULL;
- }
- PORT_Memcpy(nickname, result.data, result.len);
- PORT_Free(result.data);
- return nickname;
-}
-
-SECStatus
-PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- const char *nickname)
-{
- int len = PORT_Strlen(nickname);
- CK_ATTRIBUTE setTemplate;
- CK_RV crv;
- CK_SESSION_HANDLE rwsession;
-
- if (len < 0) {
- return SECFailure;
- }
-
- PK11_SETATTRS(&setTemplate, CKA_LABEL, (CK_CHAR *) nickname, len);
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id,
- &setTemplate, 1);
- PK11_RestoreROSession(slot, rwsession);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * strip leading zero's from key material
- */
-void
-pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib) {
- char *ptr = (char *)attrib->pValue;
- unsigned long len = attrib->ulValueLen;
-
- while ((len > 1) && (*ptr == 0)) {
- len--;
- ptr++;
- }
- attrib->pValue = ptr;
- attrib->ulValueLen = len;
-}
-
-/*
- * get a new session on a slot. If we run out of session, use the slot's
- * 'exclusive' session. In this case owner becomes false.
- */
-CK_SESSION_HANDLE
-pk11_GetNewSession(PK11SlotInfo *slot,PRBool *owner)
-{
- CK_SESSION_HANDLE session;
- *owner = PR_TRUE;
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- if ( PK11_GETTAB(slot)->C_OpenSession(slot->slotID,CKF_SERIAL_SESSION,
- slot,pk11_notify,&session) != CKR_OK) {
- *owner = PR_FALSE;
- session = slot->session;
- }
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
-
- return session;
-}
-
-void
-pk11_CloseSession(PK11SlotInfo *slot,CK_SESSION_HANDLE session,PRBool owner)
-{
- if (!owner) return;
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- (void) PK11_GETTAB(slot)->C_CloseSession(session);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
-}
-
-
-SECStatus
-PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
- const CK_ATTRIBUTE *theTemplate, int count,
- PRBool token, CK_OBJECT_HANDLE *objectID)
-{
- CK_SESSION_HANDLE rwsession;
- CK_RV crv;
- SECStatus rv = SECSuccess;
-
- rwsession = session;
- if (token) {
- rwsession = PK11_GetRWSession(slot);
- } else if (rwsession == CK_INVALID_SESSION) {
- rwsession = slot->session;
- if (rwsession != CK_INVALID_SESSION)
- PK11_EnterSlotMonitor(slot);
- }
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- crv = PK11_GETTAB(slot)->C_CreateObject(rwsession,
- /* cast away const :-( */ (CK_ATTRIBUTE_PTR)theTemplate,
- count, objectID);
- if(crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- rv = SECFailure;
- }
- if (token) {
- PK11_RestoreROSession(slot, rwsession);
- } else if (session == CK_INVALID_SESSION) {
- PK11_ExitSlotMonitor(slot);
- }
-
- return rv;
-}
-
-
-/* This function may add a maximum of 9 attributes. */
-unsigned int
-pk11_OpFlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue)
-{
-
- const static CK_ATTRIBUTE_TYPE attrTypes[12] = {
- CKA_ENCRYPT, CKA_DECRYPT, 0 /* DIGEST */, CKA_SIGN,
- CKA_SIGN_RECOVER, CKA_VERIFY, CKA_VERIFY_RECOVER, 0 /* GEN */,
- 0 /* GEN PAIR */, CKA_WRAP, CKA_UNWRAP, CKA_DERIVE
- };
-
- const CK_ATTRIBUTE_TYPE *pType = attrTypes;
- CK_ATTRIBUTE *attr = attrs;
- CK_FLAGS test = CKF_ENCRYPT;
-
-
- PR_ASSERT(!(flags & ~CKF_KEY_OPERATION_FLAGS));
- flags &= CKF_KEY_OPERATION_FLAGS;
-
- for (; flags && test <= CKF_DERIVE; test <<= 1, ++pType) {
- if (test & flags) {
- flags ^= test;
- PR_ASSERT(*pType);
- PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue);
- ++attr;
- }
- }
- return (attr - attrs);
-}
-
-/*
- * Check for conflicting flags, for example, if both PK11_ATTR_PRIVATE
- * and PK11_ATTR_PUBLIC are set.
- */
-PRBool
-pk11_BadAttrFlags(PK11AttrFlags attrFlags)
-{
- PK11AttrFlags trueFlags = attrFlags & 0x55555555;
- PK11AttrFlags falseFlags = (attrFlags >> 1) & 0x55555555;
- return ((trueFlags & falseFlags) != 0);
-}
-
-/*
- * This function may add a maximum of 5 attributes.
- * The caller must make sure the attribute flags don't have conflicts.
- */
-unsigned int
-pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags, CK_ATTRIBUTE *attrs,
- CK_BBOOL *ckTrue, CK_BBOOL *ckFalse)
-{
- const static CK_ATTRIBUTE_TYPE attrTypes[5] = {
- CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_SENSITIVE,
- CKA_EXTRACTABLE
- };
-
- const CK_ATTRIBUTE_TYPE *pType = attrTypes;
- CK_ATTRIBUTE *attr = attrs;
- PK11AttrFlags test = PK11_ATTR_TOKEN;
-
- PR_ASSERT(!pk11_BadAttrFlags(attrFlags));
-
- /* we test two related bitflags in each iteration */
- for (; attrFlags && test <= PK11_ATTR_EXTRACTABLE; test <<= 2, ++pType) {
- if (test & attrFlags) {
- attrFlags ^= test;
- PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue);
- ++attr;
- } else if ((test << 1) & attrFlags) {
- attrFlags ^= (test << 1);
- PK11_SETATTRS(attr, *pType, ckFalse, sizeof *ckFalse);
- ++attr;
- }
- }
- return (attr - attrs);
-}
-
-/*
- * Some non-compliant PKCS #11 vendors do not give us the modulus, so actually
- * set up a signature to get the signaure length.
- */
-static int
-pk11_backupGetSignLength(SECKEYPrivateKey *key)
-{
- PK11SlotInfo *slot = key->pkcs11Slot;
- CK_MECHANISM mech = {0, NULL, 0 };
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- CK_ULONG len;
- CK_RV crv;
- unsigned char h_data[20] = { 0 };
- unsigned char buf[20]; /* obviously to small */
- CK_ULONG smallLen = sizeof(buf);
-
- mech.mechanism = PK11_MapSignKeyType(key->keyType);
-
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,key->pkcs11ID);
- if (crv != CKR_OK) {
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PORT_SetError( PK11_MapError(crv) );
- return -1;
- }
- len = 0;
- crv = PK11_GETTAB(slot)->C_Sign(session,h_data,sizeof(h_data),
- NULL, &len);
- /* now call C_Sign with too small a buffer to clear the session state */
- (void) PK11_GETTAB(slot)->
- C_Sign(session,h_data,sizeof(h_data),buf,&smallLen);
-
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return -1;
- }
- return len;
-}
-
-/*
- * get the length of a signature object based on the key
- */
-int
-PK11_SignatureLen(SECKEYPrivateKey *key)
-{
- int val;
- SECItem attributeItem = {siBuffer, NULL, 0};
- SECStatus rv;
- int length;
-
- switch (key->keyType) {
- case rsaKey:
- val = PK11_GetPrivateModulusLen(key);
- if (val == -1) {
- return pk11_backupGetSignLength(key);
- }
- return (unsigned long) val;
-
- case fortezzaKey:
- return 40;
-
- case dsaKey:
- rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_SUBPRIME,
- NULL, &attributeItem);
- if (rv == SECSuccess) {
- length = attributeItem.len;
- if ((length > 0) && attributeItem.data[0] == 0) {
- length--;
- }
- PORT_Free(attributeItem.data);
- return length*2;
- }
- return pk11_backupGetSignLength(key);
-
- case ecKey:
- rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_EC_PARAMS,
- NULL, &attributeItem);
- if (rv == SECSuccess) {
- length = SECKEY_ECParamsToBasePointOrderLen(&attributeItem);
- PORT_Free(attributeItem.data);
- if (length != 0) {
- length = ((length + 7)/8) * 2;
- return length;
- }
- }
- return pk11_backupGetSignLength(key);
- default:
- break;
- }
- PORT_SetError( SEC_ERROR_INVALID_KEY );
- return 0;
-}
-
-/*
- * copy a key (or any other object) on a token
- */
-CK_OBJECT_HANDLE
-PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject)
-{
- CK_OBJECT_HANDLE destObject;
- CK_RV crv;
-
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_CopyObject(slot->session,srcObject,NULL,0,
- &destObject);
- PK11_ExitSlotMonitor(slot);
- if (crv == CKR_OK) return destObject;
- PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_HANDLE;
-}
-
-PRBool
-pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr, unsigned int numAttrs,
- CK_ATTRIBUTE_TYPE target)
-{
- for (; numAttrs > 0; ++attr, --numAttrs) {
- if (attr->type == target)
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-/*
- * Recover the Signed data. We need this because our old verify can't
- * figure out which hash algorithm to use until we decryptted this.
- */
-SECStatus
-PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig,
- SECItem *dsig, void *wincx)
-{
- PK11SlotInfo *slot = key->pkcs11Slot;
- CK_OBJECT_HANDLE id = key->pkcs11ID;
- CK_MECHANISM mech = {0, NULL, 0 };
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- CK_ULONG len;
- CK_RV crv;
-
- mech.mechanism = PK11_MapSignKeyType(key->keyType);
-
- if (slot == NULL) {
- slot = PK11_GetBestSlotWithAttributes(mech.mechanism,
- CKF_VERIFY_RECOVER,0,wincx);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return SECFailure;
- }
- id = PK11_ImportPublicKey(slot,key,PR_FALSE);
- } else {
- PK11_ReferenceSlot(slot);
- }
-
- if (id == CK_INVALID_HANDLE) {
- PK11_FreeSlot(slot);
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return SECFailure;
- }
-
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_VerifyRecoverInit(session,&mech,id);
- if (crv != CKR_OK) {
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PORT_SetError( PK11_MapError(crv) );
- PK11_FreeSlot(slot);
- return SECFailure;
- }
- len = dsig->len;
- crv = PK11_GETTAB(slot)->C_VerifyRecover(session,sig->data,
- sig->len, dsig->data, &len);
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- dsig->len = len;
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- PK11_FreeSlot(slot);
- return SECFailure;
- }
- PK11_FreeSlot(slot);
- return SECSuccess;
-}
-
-/*
- * verify a signature from its hash.
- */
-SECStatus
-PK11_Verify(SECKEYPublicKey *key, const SECItem *sig, const SECItem *hash,
- void *wincx)
-{
- PK11SlotInfo *slot = key->pkcs11Slot;
- CK_OBJECT_HANDLE id = key->pkcs11ID;
- CK_MECHANISM mech = {0, NULL, 0 };
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- CK_RV crv;
-
- mech.mechanism = PK11_MapSignKeyType(key->keyType);
-
- if (slot == NULL) {
- unsigned int length = 0;
- if ((mech.mechanism == CKM_DSA) &&
- /* 129 is 1024 bits translated to bytes and
- * padded with an optional '0' to maintain a
- * positive sign */
- (key->u.dsa.params.prime.len > 129)) {
- /* we need to get a slot that not only can do DSA, but can do DSA2
- * key lengths */
- length = key->u.dsa.params.prime.len;
- if (key->u.dsa.params.prime.data[0] == 0) {
- length --;
- }
- }
- slot = PK11_GetBestSlotWithAttributes(mech.mechanism,
- CKF_VERIFY,length,wincx);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return SECFailure;
- }
- id = PK11_ImportPublicKey(slot,key,PR_FALSE);
-
- } else {
- PK11_ReferenceSlot(slot);
- }
-
- if (id == CK_INVALID_HANDLE) {
- PK11_FreeSlot(slot);
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return SECFailure;
- }
-
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_VerifyInit(session,&mech,id);
- if (crv != CKR_OK) {
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PK11_FreeSlot(slot);
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- crv = PK11_GETTAB(slot)->C_Verify(session,hash->data,
- hash->len, sig->data, sig->len);
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PK11_FreeSlot(slot);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * sign a hash. The algorithm is determined by the key.
- */
-SECStatus
-PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, const SECItem *hash)
-{
- PK11SlotInfo *slot = key->pkcs11Slot;
- CK_MECHANISM mech = {0, NULL, 0 };
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- PRBool haslock = PR_FALSE;
- CK_ULONG len;
- CK_RV crv;
-
- mech.mechanism = PK11_MapSignKeyType(key->keyType);
-
- if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_PRIVATE)) {
- PK11_HandlePasswordCheck(slot, key->wincx);
- }
-
- session = pk11_GetNewSession(slot,&owner);
- haslock = (!owner || !(slot->isThreadSafe));
- if (haslock) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,key->pkcs11ID);
- if (crv != CKR_OK) {
- if (haslock) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
-
- /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then
- * do C_Login with CKU_CONTEXT_SPECIFIC
- * between C_SignInit and C_Sign */
- if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) {
- PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE);
- }
-
- len = sig->len;
- crv = PK11_GETTAB(slot)->C_Sign(session,hash->data,
- hash->len, sig->data, &len);
- if (haslock) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- sig->len = len;
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * sign data with a MAC key.
- */
-SECStatus
-PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism,
- SECItem *param, SECItem *sig, const SECItem *data)
-{
- PK11SlotInfo *slot = symKey->slot;
- CK_MECHANISM mech = {0, NULL, 0 };
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- PRBool haslock = PR_FALSE;
- CK_ULONG len;
- CK_RV crv;
-
- mech.mechanism = mechanism;
- if (param) {
- mech.pParameter = param->data;
- mech.ulParameterLen = param->len;
- }
-
- session = pk11_GetNewSession(slot,&owner);
- haslock = (!owner || !(slot->isThreadSafe));
- if (haslock) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,symKey->objectID);
- if (crv != CKR_OK) {
- if (haslock) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
-
- len = sig->len;
- crv = PK11_GETTAB(slot)->C_Sign(session,data->data,
- data->len, sig->data, &len);
- if (haslock) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- sig->len = len;
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * Now SSL 2.0 uses raw RSA stuff. These next to functions *must* use
- * RSA keys, or they'll fail. We do the checks up front. If anyone comes
- * up with a meaning for rawdecrypt for any other public key operation,
- * then we need to move this check into some of PK11_PubDecrypt callers,
- * (namely SSL 2.0).
- */
-static SECStatus
-pk11_PrivDecryptRaw(SECKEYPrivateKey *key, unsigned char *data,
- unsigned *outLen, unsigned int maxLen, unsigned char *enc,
- unsigned encLen, CK_MECHANISM_PTR mech)
-{
- PK11SlotInfo *slot = key->pkcs11Slot;
- CK_ULONG out = maxLen;
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- PRBool haslock = PR_FALSE;
- CK_RV crv;
-
- if (key->keyType != rsaKey) {
- PORT_SetError( SEC_ERROR_INVALID_KEY );
- return SECFailure;
- }
-
- /* Why do we do a PK11_handle check here? for simple
- * decryption? .. because the user may have asked for 'ask always'
- * and this is a private key operation. In practice, thought, it's mute
- * since only servers wind up using this function */
- if (SECKEY_HAS_ATTRIBUTE_SET(key,CKA_PRIVATE)) {
- PK11_HandlePasswordCheck(slot, key->wincx);
- }
- session = pk11_GetNewSession(slot,&owner);
- haslock = (!owner || !(slot->isThreadSafe));
- if (haslock) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_DecryptInit(session, mech, key->pkcs11ID);
- if (crv != CKR_OK) {
- if (haslock) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
-
- /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then
- * do C_Login with CKU_CONTEXT_SPECIFIC
- * between C_DecryptInit and C_Decrypt
- * ... But see note above about servers */
- if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) {
- PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE);
- }
-
- crv = PK11_GETTAB(slot)->C_Decrypt(session,enc, encLen, data, &out);
- if (haslock) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- *outLen = out;
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-PK11_PubDecryptRaw(SECKEYPrivateKey *key, unsigned char *data,
- unsigned *outLen, unsigned int maxLen, unsigned char *enc,
- unsigned encLen)
-{
- CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 };
- return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech);
-}
-
-SECStatus
-PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key, unsigned char *data,
- unsigned *outLen, unsigned int maxLen, unsigned char *enc,
- unsigned encLen)
-{
- CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0 };
- return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech);
-}
-
-static SECStatus
-pk11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc,
- unsigned char *data, unsigned dataLen,
- CK_MECHANISM_PTR mech, void *wincx)
-{
- PK11SlotInfo *slot;
- CK_OBJECT_HANDLE id;
- CK_ULONG out;
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- CK_RV crv;
-
- if (!key || key->keyType != rsaKey) {
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return SECFailure;
- }
- out = SECKEY_PublicKeyStrength(key);
-
- slot = PK11_GetBestSlotWithAttributes(mech->mechanism,CKF_ENCRYPT,0,wincx);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return SECFailure;
- }
-
- id = PK11_ImportPublicKey(slot,key,PR_FALSE);
-
- if (id == CK_INVALID_HANDLE) {
- PK11_FreeSlot(slot);
- PORT_SetError( SEC_ERROR_BAD_KEY );
- return SECFailure;
- }
-
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_EncryptInit(session, mech, id);
- if (crv != CKR_OK) {
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PK11_FreeSlot(slot);
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- crv = PK11_GETTAB(slot)->C_Encrypt(session,data,dataLen,enc,&out);
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PK11_FreeSlot(slot);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-PK11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc,
- unsigned char *data, unsigned dataLen, void *wincx)
-{
- CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 };
- return pk11_PubEncryptRaw(key, enc, data, dataLen, &mech, wincx);
-}
-
-SECStatus
-PK11_PubEncryptPKCS1(SECKEYPublicKey *key, unsigned char *enc,
- unsigned char *data, unsigned dataLen, void *wincx)
-{
- CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0 };
- return pk11_PubEncryptRaw(key, enc, data, dataLen, &mech, wincx);
-}
-
-SECKEYPrivateKey *
-PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
- CK_MECHANISM_TYPE wrapType, SECItem *param,
- SECItem *wrappedKey, SECItem *label,
- SECItem *idValue, PRBool perm, PRBool sensitive,
- CK_KEY_TYPE keyType, CK_ATTRIBUTE_TYPE *usage,
- int usageCount, void *wincx)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
- CK_ATTRIBUTE keyTemplate[15] ;
- int templateCount = 0;
- CK_OBJECT_HANDLE privKeyID;
- CK_MECHANISM mechanism;
- CK_ATTRIBUTE *attrs = keyTemplate;
- SECItem *param_free = NULL, *ck_id = NULL;
- CK_RV crv;
- CK_SESSION_HANDLE rwsession;
- PK11SymKey *newKey = NULL;
- int i;
-
- if(!slot || !wrappedKey || !idValue) {
- /* SET AN ERROR!!! */
- return NULL;
- }
-
- ck_id = PK11_MakeIDFromPubKey(idValue);
- if(!ck_id) {
- return NULL;
- }
-
- PK11_SETATTRS(attrs, CKA_TOKEN, perm ? &cktrue : &ckfalse,
- sizeof(cktrue)); attrs++;
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++;
- PK11_SETATTRS(attrs, CKA_PRIVATE, sensitive ? &cktrue : &ckfalse,
- sizeof(cktrue)); attrs++;
- PK11_SETATTRS(attrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse,
- sizeof(cktrue)); attrs++;
- if (label && label->data) {
- PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++;
- }
- PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); attrs++;
- for (i=0; i < usageCount; i++) {
- PK11_SETATTRS(attrs, usage[i], &cktrue, sizeof(cktrue)); attrs++;
- }
-
- if (PK11_IsInternal(slot)) {
- PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, idValue->data,
- idValue->len); attrs++;
- }
-
- templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount <= (sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)) );
-
- mechanism.mechanism = wrapType;
- if(!param) param = param_free= PK11_ParamFromIV(wrapType, NULL);
- if(param) {
- mechanism.pParameter = param->data;
- mechanism.ulParameterLen = param->len;
- } else {
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
- }
-
- if (wrappingKey->slot != slot) {
- newKey = pk11_CopyToSlot(slot,wrapType,CKA_UNWRAP,wrappingKey);
- } else {
- newKey = PK11_ReferenceSymKey(wrappingKey);
- }
-
- if (newKey) {
- if (perm) {
- /* Get RW Session will either lock the monitor if necessary,
- * or return a thread safe session handle, or fail. */
- rwsession = PK11_GetRWSession(slot);
- } else {
- rwsession = slot->session;
- if (rwsession != CK_INVALID_SESSION)
- PK11_EnterSlotMonitor(slot);
- }
- /* This is a lot a work to deal with fussy PKCS #11 modules
- * that can't bother to return BAD_DATA when presented with an
- * invalid session! */
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- goto loser;
- }
- crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession, &mechanism,
- newKey->objectID,
- wrappedKey->data,
- wrappedKey->len, keyTemplate,
- templateCount, &privKeyID);
-
- if (perm) {
- PK11_RestoreROSession(slot, rwsession);
- } else {
- PK11_ExitSlotMonitor(slot);
- }
- PK11_FreeSymKey(newKey);
- newKey = NULL;
- } else {
- crv = CKR_FUNCTION_NOT_SUPPORTED;
- }
-
- if (ck_id) {
- SECITEM_FreeItem(ck_id, PR_TRUE);
- ck_id = NULL;
- }
-
- if (crv != CKR_OK) {
- /* we couldn't unwrap the key, use the internal module to do the
- * unwrap, then load the new key into the token */
- PK11SlotInfo *int_slot = PK11_GetInternalSlot();
-
- if (int_slot && (slot != int_slot)) {
- SECKEYPrivateKey *privKey = PK11_UnwrapPrivKey(int_slot,
- wrappingKey, wrapType, param, wrappedKey, label,
- idValue, PR_FALSE, PR_FALSE,
- keyType, usage, usageCount, wincx);
- if (privKey) {
- SECKEYPrivateKey *newPrivKey = PK11_LoadPrivKey(slot,privKey,
- NULL,perm,sensitive);
- SECKEY_DestroyPrivateKey(privKey);
- PK11_FreeSlot(int_slot);
- return newPrivKey;
- }
- }
- if (int_slot) PK11_FreeSlot(int_slot);
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
- }
- return PK11_MakePrivKey(slot, nullKey, PR_FALSE, privKeyID, wincx);
-
-loser:
- if (newKey) {
- PK11_FreeSymKey(newKey);
- }
- if (ck_id) {
- SECITEM_FreeItem(ck_id, PR_TRUE);
- }
- return NULL;
-}
-
-/*
- * Now we're going to wrap a SECKEYPrivateKey with a PK11SymKey
- * The strategy is to get both keys to reside in the same slot,
- * one that can perform the desired crypto mechanism and then
- * call C_WrapKey after all the setup has taken place.
- */
-SECStatus
-PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
- SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType,
- SECItem *param, SECItem *wrappedKey, void *wincx)
-{
- PK11SlotInfo *privSlot = privKey->pkcs11Slot; /* The slot where
- * the private key
- * we are going to
- * wrap lives.
- */
- PK11SymKey *newSymKey = NULL;
- SECKEYPrivateKey *newPrivKey = NULL;
- SECItem *param_free = NULL;
- CK_ULONG len = wrappedKey->len;
- CK_MECHANISM mech;
- CK_RV crv;
-
- if (!privSlot || !PK11_DoesMechanism(privSlot, wrapType)) {
- /* Figure out a slot that does the mechanism and try to import
- * the private key onto that slot.
- */
- PK11SlotInfo *int_slot = PK11_GetInternalSlot();
-
- privSlot = int_slot; /* The private key has a new home */
- newPrivKey = PK11_LoadPrivKey(privSlot,privKey,NULL,PR_FALSE,PR_FALSE);
- /* newPrivKey has allocated its own reference to the slot, so it's
- * safe until we destroy newPrivkey.
- */
- PK11_FreeSlot(int_slot);
- if (newPrivKey == NULL) {
- return SECFailure;
- }
- privKey = newPrivKey;
- }
-
- if (privSlot != wrappingKey->slot) {
- newSymKey = pk11_CopyToSlot (privSlot, wrapType, CKA_WRAP,
- wrappingKey);
- wrappingKey = newSymKey;
- }
-
- if (wrappingKey == NULL) {
- if (newPrivKey) {
- SECKEY_DestroyPrivateKey(newPrivKey);
- }
- return SECFailure;
- }
- mech.mechanism = wrapType;
- if (!param) {
- param = param_free = PK11_ParamFromIV(wrapType, NULL);
- }
- if (param) {
- mech.pParameter = param->data;
- mech.ulParameterLen = param->len;
- } else {
- mech.pParameter = NULL;
- mech.ulParameterLen = 0;
- }
-
- PK11_EnterSlotMonitor(privSlot);
- crv = PK11_GETTAB(privSlot)->C_WrapKey(privSlot->session, &mech,
- wrappingKey->objectID,
- privKey->pkcs11ID,
- wrappedKey->data, &len);
- PK11_ExitSlotMonitor(privSlot);
-
- if (newSymKey) {
- PK11_FreeSymKey(newSymKey);
- }
- if (newPrivKey) {
- SECKEY_DestroyPrivateKey(newPrivKey);
- }
- if (param_free) {
- SECITEM_FreeItem(param_free,PR_TRUE);
- }
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
-
- wrappedKey->len = len;
- return SECSuccess;
-}
-
-#if 0
-/*
- * Sample code relating to linked list returned by PK11_FindGenericObjects
- */
-
-/*
- * You can walk the list with the following code:
- */
- firstObj = PK11_FindGenericObjects(slot, objClass);
- for (thisObj=firstObj;
- thisObj;
- thisObj=PK11_GetNextGenericObject(thisObj)) {
- /* operate on thisObj */
- }
-/*
- * If you want a particular object from the list...
- */
- firstObj = PK11_FindGenericObjects(slot, objClass);
- for (thisObj=firstObj;
- thisObj;
- thisObj=PK11_GetNextGenericObject(thisObj)) {
- if (isMyObj(thisObj)) {
- if ( thisObj == firstObj) {
- /* NOTE: firstObj could be NULL at this point */
- firstObj = PK11_GetNextGenericObject(thsObj);
- }
- PK11_UnlinkGenericObject(thisObj);
- myObj = thisObj;
- break;
- }
- }
-
- PK11_DestroyGenericObjects(firstObj);
-
- /* use myObj */
-
- PK11_DestroyGenericObject(myObj);
-#endif /* sample code */
-
-/*
- * return a linked, non-circular list of generic objects.
- * If you are only interested
- * in one object, just use the first object in the list. To find the
- * rest of the list use PK11_GetNextGenericObject() to return the next object.
- */
-PK11GenericObject *
-PK11_FindGenericObjects(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass)
-{
- CK_ATTRIBUTE template[1];
- CK_ATTRIBUTE *attrs = template;
- CK_OBJECT_HANDLE *objectIDs = NULL;
- PK11GenericObject *lastObj = NULL, *obj;
- PK11GenericObject *firstObj = NULL;
- int i, count = 0;
-
-
- PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass)); attrs++;
-
- objectIDs = pk11_FindObjectsByTemplate(slot,template,1,&count);
- if (objectIDs == NULL) {
- return NULL;
- }
-
- /* where we connect our object once we've created it.. */
- for (i=0; i < count; i++) {
- obj = PORT_New(PK11GenericObject);
- if ( !obj ) {
- if (firstObj) {
- PK11_DestroyGenericObjects(firstObj);
- }
- PORT_Free(objectIDs);
- return NULL;
- }
- /* initialize it */
- obj->slot = PK11_ReferenceSlot(slot);
- obj->objectID = objectIDs[i];
- obj->next = NULL;
- obj->prev = NULL;
-
- /* link it in */
- if (firstObj == NULL) {
- firstObj = obj;
- } else {
- PK11_LinkGenericObject(lastObj, obj);
- }
- lastObj = obj;
- }
- PORT_Free(objectIDs);
- return firstObj;
-}
-
-/*
- * get the Next Object in the list.
- */
-PK11GenericObject *
-PK11_GetNextGenericObject(PK11GenericObject *object)
-{
- return object->next;
-}
-
-PK11GenericObject *
-PK11_GetPrevGenericObject(PK11GenericObject *object)
-{
- return object->prev;
-}
-
-/*
- * Link a single object into a new list.
- * if the object is already in another list, remove it first.
- */
-SECStatus
-PK11_LinkGenericObject(PK11GenericObject *list, PK11GenericObject *object)
-{
- PK11_UnlinkGenericObject(object);
- object->prev = list;
- object->next = list->next;
- list->next = object;
- if (object->next != NULL) {
- object->next->prev = object;
- }
- return SECSuccess;
-}
-
-/*
- * remove an object from the list. If the object isn't already in
- * a list unlink becomes a noop.
- */
-SECStatus
-PK11_UnlinkGenericObject(PK11GenericObject *object)
-{
- if (object->prev != NULL) {
- object->prev->next = object->next;
- }
- if (object->next != NULL) {
- object->next->prev = object->prev;
- }
-
- object->next = NULL;
- object->prev = NULL;
- return SECSuccess;
-}
-
-/*
- * This function removes a single object from the list and destroys it.
- * For an already unlinked object there is no difference between
- * PK11_DestroyGenericObject and PK11_DestroyGenericObjects
- */
-SECStatus
-PK11_DestroyGenericObject(PK11GenericObject *object)
-{
- if (object == NULL) {
- return SECSuccess;
- }
-
- PK11_UnlinkGenericObject(object);
- if (object->slot) {
- PK11_FreeSlot(object->slot);
- }
- PORT_Free(object);
- return SECSuccess;
-}
-
-/*
- * walk down a link list of generic objects destroying them.
- * This will destroy all objects in a list that the object is linked into.
- * (the list is traversed in both directions).
- */
-SECStatus
-PK11_DestroyGenericObjects(PK11GenericObject *objects)
-{
- PK11GenericObject *nextObject;
- PK11GenericObject *prevObject;
-
- if (objects == NULL) {
- return SECSuccess;
- }
-
- nextObject = objects->next;
- prevObject = objects->prev;
-
- /* delete all the objects after it in the list */
- for (; objects; objects = nextObject) {
- nextObject = objects->next;
- PK11_DestroyGenericObject(objects);
- }
- /* delete all the objects before it in the list */
- for (objects = prevObject; objects; objects = prevObject) {
- prevObject = objects->prev;
- PK11_DestroyGenericObject(objects);
- }
- return SECSuccess;
-}
-
-
-/*
- * Hand Create a new object and return the Generic object for our new object.
- */
-PK11GenericObject *
-PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
- int count, PRBool token)
-{
- CK_OBJECT_HANDLE objectID;
- PK11GenericObject *obj;
- CK_RV crv;
-
- PK11_EnterSlotMonitor(slot);
- crv = PK11_CreateNewObject(slot, slot->session, pTemplate, count,
- token, &objectID);
- PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return NULL;
- }
-
- obj = PORT_New(PK11GenericObject);
- if ( !obj ) {
- /* error set by PORT_New */
- return NULL;
- }
-
- /* initialize it */
- obj->slot = PK11_ReferenceSlot(slot);
- obj->objectID = objectID;
- obj->next = NULL;
- obj->prev = NULL;
- return obj;
-}
-
-/*
- * Change an attribute on a raw object
- */
-SECStatus
-PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,
- CK_ATTRIBUTE_TYPE attrType, SECItem *item)
-{
- PK11SlotInfo *slot = NULL;
- CK_OBJECT_HANDLE handle;
- CK_ATTRIBUTE setTemplate;
- CK_RV crv;
- CK_SESSION_HANDLE rwsession;
-
- switch (objType) {
- case PK11_TypeGeneric:
- slot = ((PK11GenericObject *)objSpec)->slot;
- handle = ((PK11GenericObject *)objSpec)->objectID;
- break;
- case PK11_TypePrivKey:
- slot = ((SECKEYPrivateKey *)objSpec)->pkcs11Slot;
- handle = ((SECKEYPrivateKey *)objSpec)->pkcs11ID;
- break;
- case PK11_TypePubKey:
- slot = ((SECKEYPublicKey *)objSpec)->pkcs11Slot;
- handle = ((SECKEYPublicKey *)objSpec)->pkcs11ID;
- break;
- case PK11_TypeSymKey:
- slot = ((PK11SymKey *)objSpec)->slot;
- handle = ((PK11SymKey *)objSpec)->objectID;
- break;
- case PK11_TypeCert: /* don't handle cert case for now */
- default:
- break;
- }
- if (slot == NULL) {
- PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
- return SECFailure;
- }
-
- PK11_SETATTRS(&setTemplate, attrType, (CK_CHAR *) item->data, item->len);
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, handle,
- &setTemplate, 1);
- PK11_RestoreROSession(slot, rwsession);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-
-SECStatus
-PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec,
- CK_ATTRIBUTE_TYPE attrType, SECItem *item)
-{
- PK11SlotInfo *slot = NULL;
- CK_OBJECT_HANDLE handle;
-
- switch (objType) {
- case PK11_TypeGeneric:
- slot = ((PK11GenericObject *)objSpec)->slot;
- handle = ((PK11GenericObject *)objSpec)->objectID;
- break;
- case PK11_TypePrivKey:
- slot = ((SECKEYPrivateKey *)objSpec)->pkcs11Slot;
- handle = ((SECKEYPrivateKey *)objSpec)->pkcs11ID;
- break;
- case PK11_TypePubKey:
- slot = ((SECKEYPublicKey *)objSpec)->pkcs11Slot;
- handle = ((SECKEYPublicKey *)objSpec)->pkcs11ID;
- break;
- case PK11_TypeSymKey:
- slot = ((PK11SymKey *)objSpec)->slot;
- handle = ((PK11SymKey *)objSpec)->objectID;
- break;
- case PK11_TypeCert: /* don't handle cert case for now */
- default:
- break;
- }
- if (slot == NULL) {
- PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
- return SECFailure;
- }
-
- return PK11_ReadAttribute(slot, handle, attrType, NULL, item);
-}
-
-
-/*
- * return the object handle that matches the template
- */
-CK_OBJECT_HANDLE
-pk11_FindObjectByTemplate(PK11SlotInfo *slot,CK_ATTRIBUTE *theTemplate,int tsize)
-{
- CK_OBJECT_HANDLE object;
- CK_RV crv = CKR_SESSION_HANDLE_INVALID;
- CK_ULONG objectCount;
-
- /*
- * issue the find
- */
- PK11_EnterSlotMonitor(slot);
- if (slot->session != CK_INVALID_SESSION) {
- crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
- theTemplate, tsize);
- }
- if (crv != CKR_OK) {
- PK11_ExitSlotMonitor(slot);
- PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_HANDLE;
- }
-
- crv=PK11_GETTAB(slot)->C_FindObjects(slot->session,&object,1,&objectCount);
- PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session);
- PK11_ExitSlotMonitor(slot);
- if ((crv != CKR_OK) || (objectCount < 1)) {
- /* shouldn't use SSL_ERROR... here */
- PORT_SetError( crv != CKR_OK ? PK11_MapError(crv) :
- SSL_ERROR_NO_CERTIFICATE);
- return CK_INVALID_HANDLE;
- }
-
- /* blow up if the PKCS #11 module returns us and invalid object handle */
- PORT_Assert(object != CK_INVALID_HANDLE);
- return object;
-}
-
-/*
- * return all the object handles that matches the template
- */
-CK_OBJECT_HANDLE *
-pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
- int templCount, int *object_count)
-{
- CK_OBJECT_HANDLE *objID = NULL;
- CK_ULONG returned_count = 0;
- CK_RV crv = CKR_SESSION_HANDLE_INVALID;
-
- PK11_EnterSlotMonitor(slot);
- if (slot->session != CK_INVALID_SESSION) {
- crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
- findTemplate, templCount);
- }
- if (crv != CKR_OK) {
- PK11_ExitSlotMonitor(slot);
- PORT_SetError( PK11_MapError(crv) );
- *object_count = -1;
- return NULL;
- }
-
-
- /*
- * collect all the Matching Objects
- */
- do {
- CK_OBJECT_HANDLE *oldObjID = objID;
-
- if (objID == NULL) {
- objID = (CK_OBJECT_HANDLE *) PORT_Alloc(sizeof(CK_OBJECT_HANDLE)*
- (*object_count+ PK11_SEARCH_CHUNKSIZE));
- } else {
- objID = (CK_OBJECT_HANDLE *) PORT_Realloc(objID,
- sizeof(CK_OBJECT_HANDLE)*(*object_count+PK11_SEARCH_CHUNKSIZE));
- }
-
- if (objID == NULL) {
- if (oldObjID) PORT_Free(oldObjID);
- break;
- }
- crv = PK11_GETTAB(slot)->C_FindObjects(slot->session,
- &objID[*object_count],PK11_SEARCH_CHUNKSIZE,&returned_count);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- PORT_Free(objID);
- objID = NULL;
- break;
- }
- *object_count += returned_count;
- } while (returned_count == PK11_SEARCH_CHUNKSIZE);
-
- PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session);
- PK11_ExitSlotMonitor(slot);
-
- if (objID && (*object_count == 0)) {
- PORT_Free(objID);
- return NULL;
- }
- if (objID == NULL) *object_count = -1;
- return objID;
-}
-/*
- * given a PKCS #11 object, match it's peer based on the KeyID. searchID
- * is typically a privateKey or a certificate while the peer is the opposite
- */
-CK_OBJECT_HANDLE
-PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID,
- CK_OBJECT_CLASS matchclass)
-{
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_ID, NULL, 0 },
- { CKA_CLASS, NULL, 0 }
- };
- /* if you change the array, change the variable below as well */
- CK_ATTRIBUTE *keyclass = &theTemplate[1];
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
- /* if you change the array, change the variable below as well */
- CK_OBJECT_HANDLE peerID;
- CK_OBJECT_HANDLE parent;
- PRArenaPool *arena;
- CK_RV crv;
-
- /* now we need to create space for the public key */
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return CK_INVALID_HANDLE;
-
- crv = PK11_GetAttributes(arena,slot,searchID,theTemplate,tsize);
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_HANDLE;
- }
-
- if ((theTemplate[0].ulValueLen == 0) || (theTemplate[0].ulValueLen == -1)) {
- PORT_FreeArena(arena,PR_FALSE);
- if (matchclass == CKO_CERTIFICATE)
- PORT_SetError(SEC_ERROR_BAD_KEY);
- else
- PORT_SetError(SEC_ERROR_NO_KEY);
- return CK_INVALID_HANDLE;
- }
-
-
-
- /*
- * issue the find
- */
- parent = *(CK_OBJECT_CLASS *)(keyclass->pValue);
- *(CK_OBJECT_CLASS *)(keyclass->pValue) = matchclass;
-
- peerID = pk11_FindObjectByTemplate(slot,theTemplate,tsize);
- PORT_FreeArena(arena,PR_FALSE);
-
- return peerID;
-}
-
-/*
- * count the number of objects that match the template.
- */
-int
-PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
- int templCount)
-{
- CK_OBJECT_HANDLE objID[PK11_SEARCH_CHUNKSIZE];
- int object_count = 0;
- CK_ULONG returned_count = 0;
- CK_RV crv = CKR_SESSION_HANDLE_INVALID;
-
- PK11_EnterSlotMonitor(slot);
- if (slot->session != CK_INVALID_SESSION) {
- crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
- findTemplate, templCount);
- }
- if (crv != CKR_OK) {
- PK11_ExitSlotMonitor(slot);
- PORT_SetError( PK11_MapError(crv) );
- return object_count;
- }
-
- /*
- * collect all the Matching Objects
- */
- do {
- crv = PK11_GETTAB(slot)->C_FindObjects(slot->session, objID,
- PK11_SEARCH_CHUNKSIZE,
- &returned_count);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- break;
- }
- object_count += returned_count;
- } while (returned_count == PK11_SEARCH_CHUNKSIZE);
-
- PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session);
- PK11_ExitSlotMonitor(slot);
- return object_count;
-}
-
-/*
- * Traverse all the objects in a given slot.
- */
-SECStatus
-PK11_TraverseSlot(PK11SlotInfo *slot, void *arg)
-{
- int i;
- CK_OBJECT_HANDLE *objID = NULL;
- int object_count = 0;
- pk11TraverseSlot *slotcb = (pk11TraverseSlot*) arg;
-
- objID = pk11_FindObjectsByTemplate(slot,slotcb->findTemplate,
- slotcb->templateCount,&object_count);
-
- /*Actually this isn't a failure... there just were no objs to be found*/
- if (object_count == 0) {
- return SECSuccess;
- }
-
- if (objID == NULL) {
- return SECFailure;
- }
-
- for (i=0; i < object_count; i++) {
- (*slotcb->callback)(slot,objID[i],slotcb->callbackArg);
- }
- PORT_Free(objID);
- return SECSuccess;
-}
-
-/*
- * Traverse all the objects in all slots.
- */
-SECStatus
-pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),
- void *arg, PRBool forceLogin, void *wincx) {
- PK11SlotList *list;
- PK11SlotListElement *le;
- SECStatus rv;
-
- /* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,wincx);
- if (list == NULL) return SECFailure;
-
- /* look at each slot and authenticate as necessary */
- for (le = list->head ; le; le = le->next) {
- if (forceLogin) {
- rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx);
- if (rv != SECSuccess) {
- continue;
- }
- }
- if (callback) {
- (*callback)(le->slot,arg);
- }
- }
-
- PK11_FreeSlotList(list);
-
- return SECSuccess;
-}
-
-CK_OBJECT_HANDLE *
-PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
- CK_OBJECT_CLASS objclass, int *returnCount, void *wincx)
-{
- char *tokenName;
- char *delimit;
- PK11SlotInfo *slot;
- CK_OBJECT_HANDLE *objID;
- CK_ATTRIBUTE findTemplate[] = {
- { CKA_LABEL, NULL, 0},
- { CKA_CLASS, NULL, 0},
- };
- int findCount = sizeof(findTemplate)/sizeof(findTemplate[0]);
- SECStatus rv;
- PK11_SETATTRS(&findTemplate[1], CKA_CLASS, &objclass, sizeof(objclass));
-
- *slotptr = slot = NULL;
- *returnCount = 0;
- /* first find the slot associated with this nickname */
- if ((delimit = PORT_Strchr(nickname,':')) != NULL) {
- int len = delimit - nickname;
- tokenName = (char*)PORT_Alloc(len+1);
- PORT_Memcpy(tokenName,nickname,len);
- tokenName[len] = 0;
-
- slot = *slotptr = PK11_FindSlotByName(tokenName);
- PORT_Free(tokenName);
- /* if we couldn't find a slot, assume the nickname is an internal cert
- * with no proceding slot name */
- if (slot == NULL) {
- slot = *slotptr = PK11_GetInternalKeySlot();
- } else {
- nickname = delimit+1;
- }
- } else {
- *slotptr = slot = PK11_GetInternalKeySlot();
- }
- if (slot == NULL) {
- return CK_INVALID_HANDLE;
- }
-
- rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
- if (rv != SECSuccess) {
- PK11_FreeSlot(slot);
- *slotptr = NULL;
- return CK_INVALID_HANDLE;
- }
-
- findTemplate[0].pValue = nickname;
- findTemplate[0].ulValueLen = PORT_Strlen(nickname);
- objID = pk11_FindObjectsByTemplate(slot,findTemplate,findCount,returnCount);
- if (objID == NULL) {
- /* PKCS #11 isn't clear on whether or not the NULL is
- * stored in the template.... try the find again with the
- * full null terminated string. */
- findTemplate[0].ulValueLen += 1;
- objID = pk11_FindObjectsByTemplate(slot,findTemplate,findCount,
- returnCount);
- if (objID == NULL) {
- /* Well that's the best we can do. It's just not here */
- /* what about faked nicknames? */
- PK11_FreeSlot(slot);
- *slotptr = NULL;
- *returnCount = 0;
- }
- }
-
- return objID;
-}
-
-SECItem *
-pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle)
-{
- CK_ATTRIBUTE theTemplate[] = {
- { CKA_ID, NULL, 0 },
- };
- int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
- CK_RV crv;
- SECItem *item;
-
- item = SECITEM_AllocItem(NULL, NULL, 0);
-
- if (item == NULL) {
- return NULL;
- }
-
- crv = PK11_GetAttributes(NULL,slot,handle,theTemplate,tsize);
- if (crv != CKR_OK) {
- SECITEM_FreeItem(item,PR_TRUE);
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
- }
-
- item->data = (unsigned char*) theTemplate[0].pValue;
- item->len =theTemplate[0].ulValueLen;
-
- return item;
-}
-
diff --git a/security/nss/lib/pk11wrap/pk11pars.c b/security/nss/lib/pk11wrap/pk11pars.c
deleted file mode 100644
index 97393381a..000000000
--- a/security/nss/lib/pk11wrap/pk11pars.c
+++ /dev/null
@@ -1,1134 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * The following handles the loading, unloading and management of
- * various PCKS #11 modules
- */
-
-#include <ctype.h>
-#include "pkcs11.h"
-#include "seccomon.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pki3hack.h"
-#include "secerr.h"
-
-#include "utilpars.h"
-
-/* create a new module */
-static SECMODModule *
-secmod_NewModule(void)
-{
- SECMODModule *newMod;
- PRArenaPool *arena;
-
-
- /* create an arena in which dllName and commonName can be
- * allocated.
- */
- arena = PORT_NewArena(512);
- if (arena == NULL) {
- return NULL;
- }
-
- newMod = (SECMODModule *)PORT_ArenaAlloc(arena,sizeof (SECMODModule));
- if (newMod == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
-
- /*
- * initialize of the fields of the module
- */
- newMod->arena = arena;
- newMod->internal = PR_FALSE;
- newMod->loaded = PR_FALSE;
- newMod->isFIPS = PR_FALSE;
- newMod->dllName = NULL;
- newMod->commonName = NULL;
- newMod->library = NULL;
- newMod->functionList = NULL;
- newMod->slotCount = 0;
- newMod->slots = NULL;
- newMod->slotInfo = NULL;
- newMod->slotInfoCount = 0;
- newMod->refCount = 1;
- newMod->ssl[0] = 0;
- newMod->ssl[1] = 0;
- newMod->libraryParams = NULL;
- newMod->moduleDBFunc = NULL;
- newMod->parent = NULL;
- newMod->isCritical = PR_FALSE;
- newMod->isModuleDB = PR_FALSE;
- newMod->moduleDBOnly = PR_FALSE;
- newMod->trustOrder = 0;
- newMod->cipherOrder = 0;
- newMod->evControlMask = 0;
- newMod->refLock = PZ_NewLock(nssILockRefLock);
- if (newMod->refLock == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
- return newMod;
-
-}
-
-/* private flags for isModuleDB (field in SECMODModule). */
-/* The meaing of these flags is as follows:
- *
- * SECMOD_FLAG_MODULE_DB_IS_MODULE_DB - This is a module that accesses the
- * database of other modules to load. Module DBs are loadable modules that
- * tells NSS which PKCS #11 modules to load and when. These module DBs are
- * chainable. That is, one module DB can load another one. NSS system init
- * design takes advantage of this feature. In system NSS, a fixed system
- * module DB loads the system defined libraries, then chains out to the
- * traditional module DBs to load any system or user configured modules
- * (like smart cards). This bit is the same as the already existing meaning
- * of isModuleDB = PR_TRUE. None of the other module db flags should be set
- * if this flag isn't on.
- *
- * SECMOD_FLAG_MODULE_DB_SKIP_FIRST - This flag tells NSS to skip the first
- * PKCS #11 module presented by a module DB. This allows the OS to load a
- * softoken from the system module, then ask the existing module DB code to
- * load the other PKCS #11 modules in that module DB (skipping it's request
- * to load softoken). This gives the system init finer control over the
- * configuration of that softoken module.
- *
- * SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB - This flag allows system init to mark a
- * different module DB as the 'default' module DB (the one in which
- * 'Add module' changes will go). Without this flag NSS takes the first
- * module as the default Module DB, but in system NSS, that first module
- * is the system module, which is likely read only (at least to the user).
- * This allows system NSS to delegate those changes to the user's module DB,
- * preserving the user's ability to load new PKCS #11 modules (which only
- * affect him), from existing applications like Firefox.
- */
-#define SECMOD_FLAG_MODULE_DB_IS_MODULE_DB 0x01 /* must be set if any of the
- *other flags are set */
-#define SECMOD_FLAG_MODULE_DB_SKIP_FIRST 0x02
-#define SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB 0x04
-
-
-/* private flags for internal (field in SECMODModule). */
-/* The meaing of these flags is as follows:
- *
- * SECMOD_FLAG_INTERNAL_IS_INTERNAL - This is a marks the the module is
- * the internal module (that is, softoken). This bit is the same as the
- * already existing meaning of internal = PR_TRUE. None of the other
- * internal flags should be set if this flag isn't on.
- *
- * SECMOD_FLAG_MODULE_INTERNAL_KEY_SLOT - This flag allows system init to mark
- * a different slot returned byt PK11_GetInternalKeySlot(). The 'primary'
- * slot defined by this module will be the new internal key slot.
- */
-#define SECMOD_FLAG_INTERNAL_IS_INTERNAL 0x01 /* must be set if any of
- *the other flags are set */
-#define SECMOD_FLAG_INTERNAL_KEY_SLOT 0x02
-
-/*
- * for 3.4 we continue to use the old SECMODModule structure
- */
-SECMODModule *
-SECMOD_CreateModule(const char *library, const char *moduleName,
- const char *parameters, const char *nss)
-{
- SECMODModule *mod = secmod_NewModule();
- char *slotParams,*ciphers;
- /* pk11pars.h still does not have const char * interfaces */
- char *nssc = (char *)nss;
- if (mod == NULL) return NULL;
-
- mod->commonName = PORT_ArenaStrdup(mod->arena,moduleName ? moduleName : "");
- if (library) {
- mod->dllName = PORT_ArenaStrdup(mod->arena,library);
- }
- /* new field */
- if (parameters) {
- mod->libraryParams = PORT_ArenaStrdup(mod->arena,parameters);
- }
- mod->internal = NSSUTIL_ArgHasFlag("flags","internal",nssc);
- mod->isFIPS = NSSUTIL_ArgHasFlag("flags","FIPS",nssc);
- mod->isCritical = NSSUTIL_ArgHasFlag("flags","critical",nssc);
- slotParams = NSSUTIL_ArgGetParamValue("slotParams",nssc);
- mod->slotInfo = NSSUTIL_ArgParseSlotInfo(mod->arena,slotParams,
- &mod->slotInfoCount);
- if (slotParams) PORT_Free(slotParams);
- /* new field */
- mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder",nssc,
- NSSUTIL_DEFAULT_TRUST_ORDER,NULL);
- /* new field */
- mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder",nssc,
- NSSUTIL_DEFAULT_CIPHER_ORDER,NULL);
- /* new field */
- mod->isModuleDB = NSSUTIL_ArgHasFlag("flags","moduleDB",nssc);
- mod->moduleDBOnly = NSSUTIL_ArgHasFlag("flags","moduleDBOnly",nssc);
- if (mod->moduleDBOnly) mod->isModuleDB = PR_TRUE;
-
- /* we need more bits, but we also want to preserve binary compatibility
- * so we overload the isModuleDB PRBool with additional flags.
- * These flags are only valid if mod->isModuleDB is already set.
- * NOTE: this depends on the fact that PRBool is at least a char on
- * all platforms. These flags are only valid if moduleDB is set, so
- * code checking if (mod->isModuleDB) will continue to work correctly. */
- if (mod->isModuleDB) {
- char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB;
- if (NSSUTIL_ArgHasFlag("flags","skipFirst",nssc)) {
- flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST;
- }
- if (NSSUTIL_ArgHasFlag("flags","defaultModDB",nssc)) {
- flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB;
- }
- /* additional moduleDB flags could be added here in the future */
- mod->isModuleDB = (PRBool) flags;
- }
-
- if (mod->internal) {
- char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL;
-
- if (NSSUTIL_ArgHasFlag("flags", "internalKeySlot", nssc)) {
- flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT;
- }
- mod->internal = (PRBool) flags;
- }
-
- ciphers = NSSUTIL_ArgGetParamValue("ciphers",nssc);
- NSSUTIL_ArgParseCipherFlags(&mod->ssl[0],ciphers);
- if (ciphers) PORT_Free(ciphers);
-
- secmod_PrivateModuleCount++;
-
- return mod;
-}
-
-PRBool
-SECMOD_GetSkipFirstFlag(SECMODModule *mod)
-{
- char flags = (char) mod->isModuleDB;
-
- return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST) ? PR_TRUE : PR_FALSE;
-}
-
-PRBool
-SECMOD_GetDefaultModDBFlag(SECMODModule *mod)
-{
- char flags = (char) mod->isModuleDB;
-
- return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE;
-}
-
-PRBool
-secmod_IsInternalKeySlot(SECMODModule *mod)
-{
- char flags = (char) mod->internal;
-
- return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT) ? PR_TRUE : PR_FALSE;
-}
-
-void
-secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val)
-{
- char flags = (char) mod->internal;
-
- if (val) {
- flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT;
- } else {
- flags &= ~SECMOD_FLAG_INTERNAL_KEY_SLOT;
- }
- mod->internal = flags;
-}
-
-/*
- * copy desc and value into target. Target is known to be big enough to
- * hold desc +2 +value, which is good because the result of this will be
- * *desc"*value". We may, however, have to add some escapes for special
- * characters imbedded into value (rare). This string potentially comes from
- * a user, so we don't want the user overflowing the target buffer by using
- * excessive escapes. To prevent this we count the escapes we need to add and
- * try to expand the buffer with Realloc.
- */
-static char *
-secmod_doDescCopy(char *target, int *targetLen, const char *desc,
- int descLen, char *value)
-{
- int diff, esc_len;
-
- esc_len = NSSUTIL_EscapeSize(value, '\"') - 1;
- diff = esc_len - strlen(value);
- if (diff > 0) {
- /* we need to escape... expand newSpecPtr as well to make sure
- * we don't overflow it */
- char *newPtr = PORT_Realloc(target, *targetLen * diff);
- if (!newPtr) {
- return target; /* not enough space, just drop the whole copy */
- }
- *targetLen += diff;
- target = newPtr;
- value = NSSUTIL_Escape(value, '\"');
- if (value == NULL) {
- return target; /* couldn't escape value, just drop the copy */
- }
- }
- PORT_Memcpy(target, desc, descLen);
- target += descLen;
- *target++='\"';
- PORT_Memcpy(target, value, esc_len);
- target += esc_len;
- *target++='\"';
- if (diff > 0) {
- PORT_Free(value);
- }
- return target;
-}
-
-#define SECMOD_SPEC_COPY(new, start, end) \
- if (end > start) { \
- int _cnt = end - start; \
- PORT_Memcpy(new, start, _cnt); \
- new += _cnt; \
- }
-#define SECMOD_TOKEN_DESCRIPTION "tokenDescription="
-#define SECMOD_SLOT_DESCRIPTION "slotDescription="
-
-
-/*
- * Find any tokens= values in the module spec.
- * Always return a new spec which does not have any tokens= arguments.
- * If tokens= arguments are found, Split the the various tokens defined into
- * an array of child specs to return.
- *
- * Caller is responsible for freeing the child spec and the new token
- * spec.
- */
-char *
-secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
- char *moduleSpec, char ***children,
- CK_SLOT_ID **ids)
-{
- int newSpecLen = PORT_Strlen(moduleSpec)+2;
- char *newSpec = PORT_Alloc(newSpecLen);
- char *newSpecPtr = newSpec;
- char *modulePrev = moduleSpec;
- char *target = NULL;
- char *tmp = NULL;
- char **childArray = NULL;
- char *tokenIndex;
- CK_SLOT_ID *idArray = NULL;
- int tokenCount = 0;
- int i;
-
- if (newSpec == NULL) {
- return NULL;
- }
-
- *children = NULL;
- if (ids) {
- *ids = NULL;
- }
- moduleSpec = NSSUTIL_ArgStrip(moduleSpec);
- SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
-
- /* Notes on 'convert' and 'isFIPS' flags: The base parameters for opening
- * a new softoken module takes the following parameters to name the
- * various tokens:
- *
- * cryptoTokenDescription: name of the non-fips crypto token.
- * cryptoSlotDescription: name of the non-fips crypto slot.
- * dbTokenDescription: name of the non-fips db token.
- * dbSlotDescription: name of the non-fips db slot.
- * FIPSTokenDescription: name of the fips db/crypto token.
- * FIPSSlotDescription: name of the fips db/crypto slot.
- *
- * if we are opening a new slot, we need to have the following
- * parameters:
- * tokenDescription: name of the token.
- * slotDescription: name of the slot.
- *
- *
- * The convert flag tells us to drop the unnecessary *TokenDescription
- * and *SlotDescription arguments and convert the appropriate pair
- * (either db or FIPS based on the isFIPS flag) to tokenDescription and
- * slotDescription).
- */
- /*
- * walk down the list. if we find a tokens= argument, save it,
- * otherise copy the argument.
- */
- while (*moduleSpec) {
- int next;
- modulePrev = moduleSpec;
- NSSUTIL_HANDLE_STRING_ARG(moduleSpec, target, "tokens=",
- modulePrev = moduleSpec; /* skip copying */ )
- NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoTokenDescription=",
- if (convert) { modulePrev = moduleSpec; } );
- NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoSlotDescription=",
- if (convert) { modulePrev = moduleSpec; } );
- NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbTokenDescription=",
- if (convert) {
- modulePrev = moduleSpec;
- if (!isFIPS) {
- newSpecPtr = secmod_doDescCopy(newSpecPtr,
- &newSpecLen, SECMOD_TOKEN_DESCRIPTION,
- sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp);
- }
- });
- NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbSlotDescription=",
- if (convert) {
- modulePrev = moduleSpec; /* skip copying */
- if (!isFIPS) {
- newSpecPtr = secmod_doDescCopy(newSpecPtr,
- &newSpecLen, SECMOD_SLOT_DESCRIPTION,
- sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp);
- }
- } );
- NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSTokenDescription=",
- if (convert) {
- modulePrev = moduleSpec; /* skip copying */
- if (isFIPS) {
- newSpecPtr = secmod_doDescCopy(newSpecPtr,
- &newSpecLen, SECMOD_TOKEN_DESCRIPTION,
- sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp);
- }
- } );
- NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSSlotDescription=",
- if (convert) {
- modulePrev = moduleSpec; /* skip copying */
- if (isFIPS) {
- newSpecPtr = secmod_doDescCopy(newSpecPtr,
- &newSpecLen, SECMOD_SLOT_DESCRIPTION,
- sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp);
- }
- } );
- NSSUTIL_HANDLE_FINAL_ARG(moduleSpec)
- SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
- }
- if (tmp) {
- PORT_Free(tmp);
- tmp = NULL;
- }
- *newSpecPtr = 0;
-
- /* no target found, return the newSpec */
- if (target == NULL) {
- return newSpec;
- }
-
- /* now build the child array from target */
- /*first count them */
- for (tokenIndex = NSSUTIL_ArgStrip(target); *tokenIndex;
- tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) {
- tokenCount++;
- }
-
- childArray = PORT_NewArray(char *, tokenCount+1);
- if (childArray == NULL) {
- /* just return the spec as is then */
- PORT_Free(target);
- return newSpec;
- }
- if (ids) {
- idArray = PORT_NewArray(CK_SLOT_ID, tokenCount+1);
- if (idArray == NULL) {
- PORT_Free(childArray);
- PORT_Free(target);
- return newSpec;
- }
- }
-
- /* now fill them in */
- for (tokenIndex = NSSUTIL_ArgStrip(target), i=0 ;
- *tokenIndex && (i < tokenCount);
- tokenIndex=NSSUTIL_ArgStrip(tokenIndex)) {
- int next;
- char *name = NSSUTIL_ArgGetLabel(tokenIndex, &next);
- tokenIndex += next;
-
- if (idArray) {
- idArray[i] = NSSUTIL_ArgDecodeNumber(name);
- }
-
- PORT_Free(name); /* drop the explicit number */
-
- /* if anything is left, copy the args to the child array */
- if (!NSSUTIL_ArgIsBlank(*tokenIndex)) {
- childArray[i++] = NSSUTIL_ArgFetchValue(tokenIndex, &next);
- tokenIndex += next;
- }
- }
-
- PORT_Free(target);
- childArray[i] = 0;
- if (idArray) {
- idArray[i] = 0;
- }
-
- /* return it */
- *children = childArray;
- if (ids) {
- *ids = idArray;
- }
- return newSpec;
-}
-
-/* get the database and flags from the spec */
-static char *
-secmod_getConfigDir(char *spec, char **certPrefix, char **keyPrefix,
- PRBool *readOnly)
-{
- char * config = NULL;
-
- *certPrefix = NULL;
- *keyPrefix = NULL;
- *readOnly = NSSUTIL_ArgHasFlag("flags","readOnly",spec);
-
- spec = NSSUTIL_ArgStrip(spec);
- while (*spec) {
- int next;
- NSSUTIL_HANDLE_STRING_ARG(spec, config, "configdir=", ;)
- NSSUTIL_HANDLE_STRING_ARG(spec, *certPrefix, "certPrefix=", ;)
- NSSUTIL_HANDLE_STRING_ARG(spec, *keyPrefix, "keyPrefix=", ;)
- NSSUTIL_HANDLE_FINAL_ARG(spec)
- }
- return config;
-}
-
-struct SECMODConfigListStr {
- char *config;
- char *certPrefix;
- char *keyPrefix;
- PRBool isReadOnly;
-};
-
-/*
- * return an array of already openned databases from a spec list.
- */
-SECMODConfigList *
-secmod_GetConfigList(PRBool isFIPS, char *spec, int *count)
-{
- char **children;
- CK_SLOT_ID *ids;
- char *strippedSpec;
- int childCount;
- SECMODConfigList *conflist = NULL;
- int i;
-
- strippedSpec = secmod_ParseModuleSpecForTokens(PR_TRUE, isFIPS,
- spec,&children,&ids);
- if (strippedSpec == NULL) {
- return NULL;
- }
-
- for (childCount=0; children && children[childCount]; childCount++) ;
- *count = childCount+1; /* include strippedSpec */
- conflist = PORT_NewArray(SECMODConfigList,*count);
- if (conflist == NULL) {
- *count = 0;
- goto loser;
- }
-
- conflist[0].config = secmod_getConfigDir(strippedSpec,
- &conflist[0].certPrefix,
- &conflist[0].keyPrefix,
- &conflist[0].isReadOnly);
- for (i=0; i < childCount; i++) {
- conflist[i+1].config = secmod_getConfigDir(children[i],
- &conflist[i+1].certPrefix,
- &conflist[i+1].keyPrefix,
- &conflist[i+1].isReadOnly);
- }
-
-loser:
- secmod_FreeChildren(children, ids);
- PORT_Free(strippedSpec);
- return conflist;
-}
-
-/*
- * determine if we are trying to open an old dbm database. For this test
- * RDB databases should return PR_FALSE.
- */
-static PRBool
-secmod_configIsDBM(char *configDir)
-{
- char *env;
-
- /* explicit dbm open */
- if (strncmp(configDir, "dbm:", 4) == 0) {
- return PR_TRUE;
- }
- /* explicit open of a non-dbm database */
- if ((strncmp(configDir, "sql:",4) == 0)
- || (strncmp(configDir, "rdb:", 4) == 0)
- || (strncmp(configDir, "extern:", 7) == 0)) {
- return PR_FALSE;
- }
- env = PR_GetEnv("NSS_DEFAULT_DB_TYPE");
- /* implicit dbm open */
- if ((env == NULL) || (strcmp(env,"dbm") == 0)) {
- return PR_TRUE;
- }
- /* implicit non-dbm open */
- return PR_FALSE;
-}
-
-/*
- * match two prefixes. prefix may be NULL. NULL patches '\0'
- */
-static PRBool
-secmod_matchPrefix(char *prefix1, char *prefix2)
-{
- if ((prefix1 == NULL) || (*prefix1 == 0)) {
- if ((prefix2 == NULL) || (*prefix2 == 0)) {
- return PR_TRUE;
- }
- return PR_FALSE;
- }
- if (strcmp(prefix1, prefix2) == 0) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-/*
- * return true if we are requesting a database that is already openned.
- */
-PRBool
-secmod_MatchConfigList(char *spec, SECMODConfigList *conflist, int count)
-{
- char *config;
- char *certPrefix;
- char *keyPrefix;
- PRBool isReadOnly;
- PRBool ret=PR_FALSE;
- int i;
-
- config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly);
- if (!config) {
- ret=PR_TRUE;
- goto done;
- }
-
- /* NOTE: we dbm isn't multiple open safe. If we open the same database
- * twice from two different locations, then we can corrupt our database
- * (the cache will be inconsistent). Protect against this by claiming
- * for comparison only that we are always openning dbm databases read only.
- */
- if (secmod_configIsDBM(config)) {
- isReadOnly = 1;
- }
- for (i=0; i < count; i++) {
- if ((strcmp(config,conflist[i].config) == 0) &&
- secmod_matchPrefix(certPrefix, conflist[i].certPrefix) &&
- secmod_matchPrefix(keyPrefix, conflist[i].keyPrefix) &&
- /* this last test -- if we just need the DB open read only,
- * than any open will suffice, but if we requested it read/write
- * and it's only open read only, we need to open it again */
- (isReadOnly || !conflist[i].isReadOnly)) {
- ret = PR_TRUE;
- goto done;
- }
- }
-
- ret = PR_FALSE;
-done:
- PORT_Free(config);
- PORT_Free(certPrefix);
- PORT_Free(keyPrefix);
- return ret;
-}
-
-void
-secmod_FreeConfigList(SECMODConfigList *conflist, int count)
-{
- int i;
- for (i=0; i < count; i++) {
- PORT_Free(conflist[i].config);
- PORT_Free(conflist[i].certPrefix);
- PORT_Free(conflist[i].keyPrefix);
- }
- PORT_Free(conflist);
-}
-
-void
-secmod_FreeChildren(char **children, CK_SLOT_ID *ids)
-{
- char **thisChild;
-
- if (!children) {
- return;
- }
-
- for (thisChild = children; thisChild && *thisChild; thisChild++ ) {
- PORT_Free(*thisChild);
- }
- PORT_Free(children);
- if (ids) {
- PORT_Free(ids);
- }
- return;
-}
-
-/*
- * caclulate the length of each child record:
- * " 0x{id}=<{escaped_child}>"
- */
-static int
-secmod_getChildLength(char *child, CK_SLOT_ID id)
-{
- int length = NSSUTIL_DoubleEscapeSize(child, '>', ']');
- if (id == 0) {
- length++;
- }
- while (id) {
- length++;
- id = id >> 4;
- }
- length += 6; /* {sp}0x[id]=<{child}> */
- return length;
-}
-
-/*
- * Build a child record:
- * " 0x{id}=<{escaped_child}>"
- */
-static SECStatus
-secmod_mkTokenChild(char **next, int *length, char *child, CK_SLOT_ID id)
-{
- int len;
- char *escSpec;
-
- len = PR_snprintf(*next, *length, " 0x%x=<",id);
- if (len < 0) {
- return SECFailure;
- }
- *next += len;
- *length -= len;
- escSpec = NSSUTIL_DoubleEscape(child, '>', ']');
- if (escSpec == NULL) {
- return SECFailure;
- }
- if (*child && (*escSpec == 0)) {
- PORT_Free(escSpec);
- return SECFailure;
- }
- len = strlen(escSpec);
- if (len+1 > *length) {
- PORT_Free(escSpec);
- return SECFailure;
- }
- PORT_Memcpy(*next,escSpec, len);
- *next += len;
- *length -= len;
- PORT_Free(escSpec);
- **next = '>';
- (*next)++;
- (*length)--;
- return SECSuccess;
-}
-
-#define TOKEN_STRING " tokens=["
-
-char *
-secmod_MkAppendTokensList(PRArenaPool *arena, char *oldParam, char *newToken,
- CK_SLOT_ID newID, char **children, CK_SLOT_ID *ids)
-{
- char *rawParam = NULL; /* oldParam with tokens stripped off */
- char *newParam = NULL; /* space for the return parameter */
- char *nextParam = NULL; /* current end of the new parameter */
- char **oldChildren = NULL;
- CK_SLOT_ID *oldIds = NULL;
- void *mark = NULL; /* mark the arena pool in case we need
- * to release it */
- int length, i, tmpLen;
- SECStatus rv;
-
- /* first strip out and save the old tokenlist */
- rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE,PR_FALSE,
- oldParam,&oldChildren,&oldIds);
- if (!rawParam) {
- goto loser;
- }
-
- /* now calculate the total length of the new buffer */
- /* First the 'fixed stuff', length of rawparam (does not include a NULL),
- * length of the token string (does include the NULL), closing bracket */
- length = strlen(rawParam) + sizeof(TOKEN_STRING) + 1;
- /* now add then length of all the old children */
- for (i=0; oldChildren && oldChildren[i]; i++) {
- length += secmod_getChildLength(oldChildren[i], oldIds[i]);
- }
-
- /* add the new token */
- length += secmod_getChildLength(newToken, newID);
-
- /* and it's new children */
- for (i=0; children && children[i]; i++) {
- if (ids[i] == -1) {
- continue;
- }
- length += secmod_getChildLength(children[i], ids[i]);
- }
-
- /* now allocate and build the string */
- mark = PORT_ArenaMark(arena);
- if (!mark) {
- goto loser;
- }
- newParam = PORT_ArenaAlloc(arena,length);
- if (!newParam) {
- goto loser;
- }
-
- PORT_Strcpy(newParam, oldParam);
- tmpLen = strlen(oldParam);
- nextParam = newParam + tmpLen;
- length -= tmpLen;
- PORT_Memcpy(nextParam, TOKEN_STRING, sizeof(TOKEN_STRING)-1);
- nextParam += sizeof(TOKEN_STRING)-1;
- length -= sizeof(TOKEN_STRING)-1;
-
- for (i=0; oldChildren && oldChildren[i]; i++) {
- rv = secmod_mkTokenChild(&nextParam,&length,oldChildren[i],oldIds[i]);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
-
- rv = secmod_mkTokenChild(&nextParam, &length, newToken, newID);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- for (i=0; children && children[i]; i++) {
- if (ids[i] == -1) {
- continue;
- }
- rv = secmod_mkTokenChild(&nextParam, &length, children[i], ids[i]);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
-
- if (length < 2) {
- goto loser;
- }
-
- *nextParam++ = ']';
- *nextParam++ = 0;
-
- /* we are going to return newParam now, don't release the mark */
- PORT_ArenaUnmark(arena, mark);
- mark = NULL;
-
-loser:
- if (mark) {
- PORT_ArenaRelease(arena, mark);
- newParam = NULL; /* if the mark is still active,
- * don't return the param */
- }
- if (rawParam) {
- PORT_Free(rawParam);
- }
- if (oldChildren) {
- secmod_FreeChildren(oldChildren, oldIds);
- }
- return newParam;
-}
-
-static char *
-secmod_mkModuleSpec(SECMODModule * module)
-{
- char *nss = NULL, *modSpec = NULL, **slotStrings = NULL;
- int slotCount, i, si;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
-
- /* allocate target slot info strings */
- slotCount = 0;
-
- SECMOD_GetReadLock(moduleLock);
- if (module->slotCount) {
- for (i=0; i < module->slotCount; i++) {
- if (module->slots[i]->defaultFlags !=0) {
- slotCount++;
- }
- }
- } else {
- slotCount = module->slotInfoCount;
- }
-
- slotStrings = (char **)PORT_ZAlloc(slotCount*sizeof(char *));
- if (slotStrings == NULL) {
- SECMOD_ReleaseReadLock(moduleLock);
- goto loser;
- }
-
-
- /* build the slot info strings */
- if (module->slotCount) {
- for (i=0, si= 0; i < module->slotCount; i++) {
- if (module->slots[i]->defaultFlags) {
- PORT_Assert(si < slotCount);
- if (si >= slotCount) break;
- slotStrings[si] = NSSUTIL_MkSlotString(module->slots[i]->slotID,
- module->slots[i]->defaultFlags,
- module->slots[i]->timeout,
- module->slots[i]->askpw,
- module->slots[i]->hasRootCerts,
- module->slots[i]->hasRootTrust);
- si++;
- }
- }
- } else {
- for (i=0; i < slotCount; i++) {
- slotStrings[i] = NSSUTIL_MkSlotString(
- module->slotInfo[i].slotID,
- module->slotInfo[i].defaultFlags,
- module->slotInfo[i].timeout,
- module->slotInfo[i].askpw,
- module->slotInfo[i].hasRootCerts,
- module->slotInfo[i].hasRootTrust);
- }
- }
-
- SECMOD_ReleaseReadLock(moduleLock);
- nss = NSSUTIL_MkNSSString(slotStrings,slotCount,module->internal,
- module->isFIPS, module->isModuleDB,
- module->moduleDBOnly, module->isCritical,
- module->trustOrder, module->cipherOrder,
- module->ssl[0],module->ssl[1]);
- modSpec= NSSUTIL_MkModuleSpec(module->dllName,module->commonName,
- module->libraryParams,nss);
- PORT_Free(slotStrings);
- PR_smprintf_free(nss);
-loser:
- return (modSpec);
-}
-
-
-char **
-SECMOD_GetModuleSpecList(SECMODModule *module)
-{
- SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc;
- if (func) {
- return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND,
- module->libraryParams,NULL);
- }
- return NULL;
-}
-
-SECStatus
-SECMOD_AddPermDB(SECMODModule *module)
-{
- SECMODModuleDBFunc func;
- char *moduleSpec;
- char **retString;
-
- if (module->parent == NULL) return SECFailure;
-
- func = (SECMODModuleDBFunc) module->parent->moduleDBFunc;
- if (func) {
- moduleSpec = secmod_mkModuleSpec(module);
- retString = (*func)(SECMOD_MODULE_DB_FUNCTION_ADD,
- module->parent->libraryParams,moduleSpec);
- PORT_Free(moduleSpec);
- if (retString != NULL) return SECSuccess;
- }
- return SECFailure;
-}
-
-SECStatus
-SECMOD_DeletePermDB(SECMODModule *module)
-{
- SECMODModuleDBFunc func;
- char *moduleSpec;
- char **retString;
-
- if (module->parent == NULL) return SECFailure;
-
- func = (SECMODModuleDBFunc) module->parent->moduleDBFunc;
- if (func) {
- moduleSpec = secmod_mkModuleSpec(module);
- retString = (*func)(SECMOD_MODULE_DB_FUNCTION_DEL,
- module->parent->libraryParams,moduleSpec);
- PORT_Free(moduleSpec);
- if (retString != NULL) return SECSuccess;
- }
- return SECFailure;
-}
-
-SECStatus
-SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList)
-{
- SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc;
- char **retString;
- if (func) {
- retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE,
- module->libraryParams,moduleSpecList);
- if (retString != NULL) return SECSuccess;
- }
- return SECFailure;
-}
-
-/*
- * load a PKCS#11 module but do not add it to the default NSS trust domain
- */
-SECMODModule *
-SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse)
-{
- char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL;
- SECStatus status;
- SECMODModule *module = NULL;
- SECMODModule *oldModule = NULL;
- SECStatus rv;
-
- /* initialize the underlying module structures */
- SECMOD_Init();
-
- status = NSSUTIL_ArgParseModuleSpec(modulespec, &library, &moduleName,
- &parameters, &nss);
- if (status != SECSuccess) {
- goto loser;
- }
-
- module = SECMOD_CreateModule(library, moduleName, parameters, nss);
- if (library) PORT_Free(library);
- if (moduleName) PORT_Free(moduleName);
- if (parameters) PORT_Free(parameters);
- if (nss) PORT_Free(nss);
- if (!module) {
- goto loser;
- }
- if (parent) {
- module->parent = SECMOD_ReferenceModule(parent);
- if (module->internal && secmod_IsInternalKeySlot(parent)) {
- module->internal = parent->internal;
- }
- }
-
- /* load it */
- rv = secmod_LoadPKCS11Module(module, &oldModule);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* if we just reload an old module, no need to add it to any lists.
- * we simple release all our references */
- if (oldModule) {
- /* This module already exists, don't link it anywhere. This
- * will probably destroy this module */
- SECMOD_DestroyModule(module);
- return oldModule;
- }
-
- if (recurse && module->isModuleDB) {
- char ** moduleSpecList;
- PORT_SetError(0);
-
- moduleSpecList = SECMOD_GetModuleSpecList(module);
- if (moduleSpecList) {
- char **index;
-
- index = moduleSpecList;
- if (*index && SECMOD_GetSkipFirstFlag(module)) {
- index++;
- }
-
- for (; *index; index++) {
- SECMODModule *child;
- if (0 == PORT_Strcmp(*index, modulespec)) {
- /* avoid trivial infinite recursion */
- PORT_SetError(SEC_ERROR_NO_MODULE);
- rv = SECFailure;
- break;
- }
- child = SECMOD_LoadModule(*index,module,PR_TRUE);
- if (!child) break;
- if (child->isCritical && !child->loaded) {
- int err = PORT_GetError();
- if (!err)
- err = SEC_ERROR_NO_MODULE;
- SECMOD_DestroyModule(child);
- PORT_SetError(err);
- rv = SECFailure;
- break;
- }
- SECMOD_DestroyModule(child);
- }
- SECMOD_FreeModuleSpecList(module,moduleSpecList);
- } else {
- if (!PORT_GetError())
- PORT_SetError(SEC_ERROR_NO_MODULE);
- rv = SECFailure;
- }
- }
-
- if (rv != SECSuccess) {
- goto loser;
- }
-
-
- /* inherit the reference */
- if (!module->moduleDBOnly) {
- SECMOD_AddModuleToList(module);
- } else {
- SECMOD_AddModuleToDBOnlyList(module);
- }
-
- /* handle any additional work here */
- return module;
-
-loser:
- if (module) {
- if (module->loaded) {
- SECMOD_UnloadModule(module);
- }
- SECMOD_AddModuleToUnloadList(module);
- }
- return module;
-}
-
-/*
- * load a PKCS#11 module and add it to the default NSS trust domain
- */
-SECMODModule *
-SECMOD_LoadUserModule(char *modulespec,SECMODModule *parent, PRBool recurse)
-{
- SECStatus rv = SECSuccess;
- SECMODModule * newmod = SECMOD_LoadModule(modulespec, parent, recurse);
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
-
- if (newmod) {
- SECMOD_GetReadLock(moduleLock);
- rv = STAN_AddModuleToDefaultTrustDomain(newmod);
- SECMOD_ReleaseReadLock(moduleLock);
- if (SECSuccess != rv) {
- SECMOD_DestroyModule(newmod);
- return NULL;
- }
- }
- return newmod;
-}
-
-/*
- * remove the PKCS#11 module from the default NSS trust domain, call
- * C_Finalize, and destroy the module structure
- */
-SECStatus SECMOD_UnloadUserModule(SECMODModule *mod)
-{
- SECStatus rv = SECSuccess;
- int atype = 0;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
- if (!mod) {
- return SECFailure;
- }
-
- SECMOD_GetReadLock(moduleLock);
- rv = STAN_RemoveModuleFromDefaultTrustDomain(mod);
- SECMOD_ReleaseReadLock(moduleLock);
- if (SECSuccess != rv) {
- return SECFailure;
- }
- return SECMOD_DeleteModuleEx(NULL, mod, &atype, PR_FALSE);
-}
-
diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c
deleted file mode 100644
index 093c3ea9d..000000000
--- a/security/nss/lib/pk11wrap/pk11pbe.c
+++ /dev/null
@@ -1,1432 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "plarena.h"
-
-#include "seccomon.h"
-#include "secitem.h"
-#include "secport.h"
-#include "hasht.h"
-#include "pkcs11t.h"
-#include "sechash.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "secoid.h"
-#include "secerr.h"
-#include "secmod.h"
-#include "pk11func.h"
-#include "secpkcs5.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11.h"
-#include "pk11func.h"
-#include "secitem.h"
-#include "key.h"
-
-typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter;
-struct SEC_PKCS5PBEParameterStr {
- PRArenaPool *poolp;
- SECItem salt; /* octet string */
- SECItem iteration; /* integer */
- SECItem keyLength; /* PKCS5v2 only */
- SECAlgorithmID *pPrfAlgId; /* PKCS5v2 only */
- SECAlgorithmID prfAlgId; /* PKCS5v2 only */
-};
-
-/* PKCS5 V2 has an algorithm ID for the encryption and for
- * the key generation. This is valid for SEC_OID_PKCS5_PBES2
- * and SEC_OID_PKCS5_PBMAC1
- */
-struct sec_pkcs5V2ParameterStr {
- PRArenaPool *poolp;
- SECAlgorithmID pbeAlgId; /* real pbe algorithms */
- SECAlgorithmID cipherAlgId; /* encryption/mac */
-};
-
-typedef struct sec_pkcs5V2ParameterStr sec_pkcs5V2Parameter;
-
-
-/* template for PKCS 5 PBE Parameter. This template has been expanded
- * based upon the additions in PKCS 12. This should eventually be moved
- * if RSA updates PKCS 5.
- */
-const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS5PBEParameter, iteration) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
- { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
- { 0 }
-};
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-/* SECOID_PKCS5_PBKDF2 */
-const SEC_ASN1Template SEC_PKCS5V2PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
- /* This is really a choice, but since we only understand this
- * choice, just inline it */
- { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
- { SEC_ASN1_INTEGER|SEC_ASN1_OPTIONAL,
- offsetof(SEC_PKCS5PBEParameter, keyLength) },
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN | SEC_ASN1_OPTIONAL,
- offsetof(SEC_PKCS5PBEParameter, pPrfAlgId),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { 0 }
-};
-
-/* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */
-const SEC_ASN1Template SEC_PKCS5V2ParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(sec_pkcs5V2Parameter, pbeAlgId),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(sec_pkcs5V2Parameter, cipherAlgId),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { 0 }
-};
-
-
-/*
- * maps a PBE algorithm to a crypto algorithm. for PKCS12 and PKCS5v1
- * for PKCS5v2 it returns SEC_OID_PKCS5_PBKDF2.
- */
-SECOidTag
-sec_pkcs5GetCryptoFromAlgTag(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- return SEC_OID_DES_EDE3_CBC;
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- return SEC_OID_DES_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_RC2_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return SEC_OID_RC4;
- case SEC_OID_PKCS5_PBKDF2:
- case SEC_OID_PKCS5_PBES2:
- case SEC_OID_PKCS5_PBMAC1:
- return SEC_OID_PKCS5_PBKDF2;
- default:
- break;
- }
-
- return SEC_OID_UNKNOWN;
-}
-
-/*
- * get a new PKCS5 V2 Parameter from the algorithm id.
- * if arena is passed in, use it, otherwise create a new arena.
- */
-sec_pkcs5V2Parameter *
-sec_pkcs5_v2_get_v2_param(PRArenaPool *arena, SECAlgorithmID *algid)
-{
- PRArenaPool *localArena = NULL;
- sec_pkcs5V2Parameter *pbeV2_param;
- SECStatus rv;
-
- if (arena == NULL) {
- localArena = arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (arena == NULL) {
- return NULL;
- }
- }
- pbeV2_param = PORT_ArenaZNew(arena, sec_pkcs5V2Parameter);
- if (pbeV2_param == NULL) {
- goto loser;
- }
-
- rv = SEC_ASN1DecodeItem(arena, pbeV2_param,
- SEC_PKCS5V2ParameterTemplate, &algid->parameters);
- if (rv == SECFailure) {
- goto loser;
- }
-
- pbeV2_param->poolp = arena;
- return pbeV2_param;
-loser:
- if (localArena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return NULL;
-}
-
-void
-sec_pkcs5_v2_destroy_v2_param(sec_pkcs5V2Parameter *param)
-{
- if (param && param->poolp) {
- PORT_FreeArena(param->poolp, PR_TRUE);
- }
-}
-
-
-/* maps crypto algorithm from PBE algorithm.
- */
-SECOidTag
-SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid)
-{
-
- SECOidTag pbeAlg;
- SECOidTag cipherAlg;
-
- if(algid == NULL)
- return SEC_OID_UNKNOWN;
-
- pbeAlg = SECOID_GetAlgorithmTag(algid);
- cipherAlg = sec_pkcs5GetCryptoFromAlgTag(pbeAlg);
- if ((cipherAlg == SEC_OID_PKCS5_PBKDF2) &&
- (pbeAlg != SEC_OID_PKCS5_PBKDF2)) {
- sec_pkcs5V2Parameter *pbeV2_param;
- cipherAlg = SEC_OID_UNKNOWN;
-
- pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
- if (pbeV2_param != NULL) {
- cipherAlg = SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId);
- sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
- }
- }
-
- return cipherAlg;
-}
-
-/* check to see if an oid is a pbe algorithm
- */
-PRBool
-SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid)
-{
- return (PRBool)(SEC_PKCS5GetCryptoAlgorithm(algid) != SEC_OID_UNKNOWN);
-}
-
-PRBool
-SEC_PKCS5IsAlgorithmPBEAlgTag(SECOidTag algtag)
-{
- return (PRBool)(sec_pkcs5GetCryptoFromAlgTag(algtag) != SEC_OID_UNKNOWN);
-}
-
-/*
- * find the most appropriate PKCS5v2 overall oid tag from a regular
- * cipher/hash algorithm tag.
- */
-static SECOidTag
-sec_pkcs5v2_get_pbe(SECOidTag algTag)
-{
- /* if it's a valid hash oid... */
- if (HASH_GetHashOidTagByHMACOidTag(algTag) != SEC_OID_UNKNOWN) {
- /* use the MAC tag */
- return SEC_OID_PKCS5_PBMAC1;
- }
- if (HASH_GetHashTypeByOidTag(algTag) != HASH_AlgNULL) {
- /* eliminate Hash algorithms */
- return SEC_OID_UNKNOWN;
- }
- if (PK11_AlgtagToMechanism(algTag) != CKM_INVALID_MECHANISM) {
- /* it's not a hash, if it has a PKCS #11 mechanism associated
- * with it, assume it's a cipher. (NOTE this will generate
- * some false positives). */
- return SEC_OID_PKCS5_PBES2;
- }
- return SEC_OID_UNKNOWN;
-}
-
-/*
- * maps PBE algorithm from crypto algorithm, assumes SHA1 hashing.
- * input keyLen in bits.
- */
-SECOidTag
-SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
-{
- switch(algTag)
- {
- case SEC_OID_DES_EDE3_CBC:
- switch(keyLen) {
- case 168:
- case 192:
- case 0:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- case 128:
- case 92:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
- default:
- break;
- }
- break;
- case SEC_OID_DES_CBC:
- return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
- case SEC_OID_RC2_CBC:
- switch(keyLen) {
- case 40:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- case 128:
- case 0:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- default:
- break;
- }
- break;
- case SEC_OID_RC4:
- switch(keyLen) {
- case 40:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
- case 128:
- case 0:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
- default:
- break;
- }
- break;
- default:
- return sec_pkcs5v2_get_pbe(algTag);
- }
-
- return SEC_OID_UNKNOWN;
-}
-
-/*
- * get the key length in bytes from a PKCS5 PBE
- */
-int
-sec_pkcs5v2_key_length(SECAlgorithmID *algid)
-{
- SECOidTag algorithm;
- PRArenaPool *arena = NULL;
- SEC_PKCS5PBEParameter p5_param;
- SECStatus rv;
- int length = -1;
-
- algorithm = SECOID_GetAlgorithmTag(algid);
- /* sanity check, they should all be PBKDF2 here */
- if (algorithm != SEC_OID_PKCS5_PBKDF2) {
- return -1;
- }
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (arena == NULL) {
- goto loser;
- }
- PORT_Memset(&p5_param, 0, sizeof(p5_param));
- rv = SEC_ASN1DecodeItem(arena,&p5_param,
- SEC_PKCS5V2PBEParameterTemplate, &algid->parameters);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- if (p5_param.keyLength.data != NULL) {
- length = DER_GetInteger(&p5_param.keyLength);
- }
-
-loser:
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return length;
-}
-
-/*
- * get the key length in bytes needed for the PBE algorithm
- */
-int
-SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
-{
-
- SECOidTag algorithm;
-
- if(algid == NULL)
- return SEC_OID_UNKNOWN;
-
- algorithm = SECOID_GetAlgorithmTag(algid);
-
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- return 24;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return 8;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return 5;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- return 16;
- case SEC_OID_PKCS5_PBKDF2:
- return sec_pkcs5v2_key_length(algid);
- case SEC_OID_PKCS5_PBES2:
- case SEC_OID_PKCS5_PBMAC1:
- {
- sec_pkcs5V2Parameter *pbeV2_param;
- int length = -1;
- pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
- if (pbeV2_param != NULL) {
- length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId);
- sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
- }
- return length;
- }
-
- default:
- break;
- }
- return -1;
-}
-
-
-/* the PKCS12 V2 algorithms only encode the salt, there is no iteration
- * count so we need a check for V2 algorithm parameters.
- */
-static PRBool
-sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return PR_TRUE;
- default:
- break;
- }
-
- return PR_FALSE;
-}
-
-static PRBool
-sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS5_PBES2:
- case SEC_OID_PKCS5_PBMAC1:
- case SEC_OID_PKCS5_PBKDF2:
- return PR_TRUE;
- default:
- break;
- }
-
- return PR_FALSE;
-}
-
-/* destroy a pbe parameter. it assumes that the parameter was
- * generated using the appropriate create function and therefor
- * contains an arena pool.
- */
-static void
-sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param)
-{
- if(pbe_param != NULL)
- PORT_FreeArena(pbe_param->poolp, PR_TRUE);
-}
-
-/* creates a PBE parameter based on the PBE algorithm. the only required
- * parameters are algorithm and interation. the return is a PBE parameter
- * which conforms to PKCS 5 parameter unless an extended parameter is needed.
- * this is primarily if keyLength and a variable key length algorithm are
- * specified.
- * salt - if null, a salt will be generated from random bytes.
- * iteration - number of iterations to perform hashing.
- * keyLength - only used in variable key length algorithms. if specified,
- * should be in bytes.
- * once a parameter is allocated, it should be destroyed calling
- * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter.
- */
-#define DEFAULT_SALT_LENGTH 16
-static SEC_PKCS5PBEParameter *
-sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,
- SECItem *salt,
- int iteration,
- int keyLength,
- SECOidTag prfAlg)
-{
- PRArenaPool *poolp = NULL;
- SEC_PKCS5PBEParameter *pbe_param = NULL;
- SECStatus rv= SECSuccess;
- void *dummy = NULL;
-
- if(iteration < 0) {
- return NULL;
- }
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(poolp == NULL)
- return NULL;
-
- pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS5PBEParameter));
- if(!pbe_param) {
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
- }
-
- pbe_param->poolp = poolp;
-
- rv = SECFailure;
- if (salt && salt->data) {
- rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt);
- } else {
- /* sigh, the old interface generated salt on the fly, so we have to
- * preserve the semantics */
- pbe_param->salt.len = DEFAULT_SALT_LENGTH;
- pbe_param->salt.data = PORT_ArenaZAlloc(poolp,DEFAULT_SALT_LENGTH);
- if (pbe_param->salt.data) {
- rv = PK11_GenerateRandom(pbe_param->salt.data,DEFAULT_SALT_LENGTH);
- }
- }
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
- }
-
- /* encode the integer */
- dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,
- iteration);
- rv = (dummy) ? SECSuccess : SECFailure;
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
-
- /*
- * for PKCS5 v2 Add the keylength and the prf
- */
- if (algorithm == SEC_OID_PKCS5_PBKDF2) {
- dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->keyLength,
- keyLength);
- rv = (dummy) ? SECSuccess : SECFailure;
- if (rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
- rv = SECOID_SetAlgorithmID(poolp, &pbe_param->prfAlgId, prfAlg, NULL);
- if (rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
- pbe_param->pPrfAlgId = &pbe_param->prfAlgId;
- }
-
- return pbe_param;
-}
-
-/* creates a algorithm ID containing the PBE algorithm and appropriate
- * parameters. the required parameter is the algorithm. if salt is
- * not specified, it is generated randomly.
- *
- * the returned SECAlgorithmID should be destroyed using
- * SECOID_DestroyAlgorithmID
- */
-SECAlgorithmID *
-sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
- SECOidTag cipherAlgorithm,
- SECOidTag prfAlg,
- SECOidTag *pPbeAlgorithm,
- int keyLength,
- SECItem *salt,
- int iteration)
-{
- PRArenaPool *poolp = NULL;
- SECAlgorithmID *algid, *ret_algid = NULL;
- SECOidTag pbeAlgorithm = algorithm;
- SECItem der_param;
- void *dummy;
- SECStatus rv = SECFailure;
- SEC_PKCS5PBEParameter *pbe_param = NULL;
- sec_pkcs5V2Parameter pbeV2_param;
-
- if(iteration <= 0) {
- return NULL;
- }
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(!poolp) {
- goto loser;
- }
-
- if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm) ||
- sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) {
- /* use PKCS 5 v2 */
- SECItem *cipherParams;
-
- /*
- * if we ask for pkcs5 Algorithms directly, then the
- * application needs to supply the cipher algorithm,
- * otherwise we are implicitly using pkcs5 v2 and the
- * passed in algorithm is the encryption algorithm.
- */
- if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) {
- if (cipherAlgorithm == SEC_OID_UNKNOWN) {
- goto loser;
- }
- } else {
- cipherAlgorithm = algorithm;
- /* force algorithm to be chosen below */
- algorithm = SEC_OID_PKCS5_PBKDF2;
- }
-
- pbeAlgorithm = SEC_OID_PKCS5_PBKDF2;
- /*
- * 'algorithm' is the overall algorithm oid tag used to wrap the
- * entire algoithm ID block. For PKCS5v1 and PKCS12, this
- * algorithm OID has encoded in it both the PBE KDF function
- * and the encryption algorithm. For PKCS 5v2, PBE KDF and
- * encryption/macing oids are encoded as parameters in
- * the algorithm ID block.
- *
- * Thus in PKCS5 v1 and PKCS12, this algorithm maps to a pkcs #11
- * mechanism, where as in PKCS 5v2, this alogithm tag does not map
- * directly to a PKCS #11 mechanim, instead the 2 oids in the
- * algorithm ID block map the the actual PKCS #11 mechanism.
- * gorithm is). We use choose this algorithm oid based on the
- * cipherAlgorithm to determine what this should be (MAC1 or PBES2).
- */
- if (algorithm == SEC_OID_PKCS5_PBKDF2) {
- /* choose mac or pbes */
- algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm);
- }
-
- /* set the PKCS5v2 specific parameters */
- if (keyLength == 0) {
- SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
- if (hashAlg != SEC_OID_UNKNOWN) {
- keyLength = HASH_ResultLenByOidTag(hashAlg);
- } else {
- CK_MECHANISM_TYPE cryptoMech;
- cryptoMech = PK11_AlgtagToMechanism(cipherAlgorithm);
- if (cryptoMech == CKM_INVALID_MECHANISM) {
- goto loser;
- }
- keyLength = PK11_GetMaxKeyLength(cryptoMech);
- }
- if (keyLength == 0) {
- goto loser;
- }
- }
- /* currently only SEC_OID_HMAC_SHA1 is defined */
- if (prfAlg == SEC_OID_UNKNOWN) {
- prfAlg = SEC_OID_HMAC_SHA1;
- }
-
- /* build the PKCS5v2 cipher algorithm id */
- cipherParams = pk11_GenerateNewParamWithKeyLen(
- PK11_AlgtagToMechanism(cipherAlgorithm), keyLength);
- if (!cipherParams) {
- goto loser;
- }
-
- PORT_Memset(&pbeV2_param, 0, sizeof (pbeV2_param));
-
- rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams,
- poolp, &pbeV2_param.cipherAlgId);
- SECITEM_FreeItem(cipherParams, PR_TRUE);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
-
-
- /* generate the parameter */
- pbe_param = sec_pkcs5_create_pbe_parameter(pbeAlgorithm, salt, iteration,
- keyLength, prfAlg);
- if(!pbe_param) {
- goto loser;
- }
-
- /* generate the algorithm id */
- algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
- if(algid == NULL) {
- goto loser;
- }
-
- der_param.data = NULL;
- der_param.len = 0;
- if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) {
- /* first encode the PBE algorithm ID */
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
- SEC_PKCS5V2PBEParameterTemplate);
- if (dummy == NULL) {
- goto loser;
- }
- rv = SECOID_SetAlgorithmID(poolp, &pbeV2_param.pbeAlgId,
- pbeAlgorithm, &der_param);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* now encode the Full PKCS 5 parameter */
- der_param.data = NULL;
- der_param.len = 0;
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, &pbeV2_param,
- SEC_PKCS5V2ParameterTemplate);
- } else if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
- SEC_PKCS5PBEParameterTemplate);
- } else {
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
- SEC_V2PKCS12PBEParameterTemplate);
- }
- if (dummy == NULL) {
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
- if (ret_algid == NULL) {
- goto loser;
- }
-
- rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
- if (rv != SECSuccess) {
- SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
- ret_algid = NULL;
- } else if (pPbeAlgorithm) {
- *pPbeAlgorithm = pbeAlgorithm;
- }
-
-loser:
- if (poolp != NULL) {
- PORT_FreeArena(poolp, PR_TRUE);
- algid = NULL;
- }
-
- if (pbe_param) {
- sec_pkcs5_destroy_pbe_param(pbe_param);
- }
-
- return ret_algid;
-}
-
-SECStatus
-pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech)
-{
- SEC_PKCS5PBEParameter p5_param;
- SECItem *salt = NULL;
- SECOidTag algorithm = SECOID_GetAlgorithmTag(algid);
- PRArenaPool *arena = NULL;
- SECStatus rv = SECFailure;
- unsigned char *paramData = NULL;
- unsigned char *pSalt = NULL;
- CK_ULONG iterations;
- int paramLen = 0;
- int iv_len;
-
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (arena == NULL) {
- goto loser;
- }
-
-
- /*
- * decode the algid based on the pbe type
- */
- PORT_Memset(&p5_param, 0, sizeof(p5_param));
- if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm));
- rv = SEC_ASN1DecodeItem(arena, &p5_param,
- SEC_V2PKCS12PBEParameterTemplate, &algid->parameters);
- } else if (algorithm == SEC_OID_PKCS5_PBKDF2) {
- iv_len = 0;
- rv = SEC_ASN1DecodeItem(arena,&p5_param,
- SEC_PKCS5V2PBEParameterTemplate, &algid->parameters);
- } else {
- iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm));
- rv = SEC_ASN1DecodeItem(arena,&p5_param,SEC_PKCS5PBEParameterTemplate,
- &algid->parameters);
- }
-
- if (iv_len < 0) {
- goto loser;
- }
-
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* get salt */
- salt = &p5_param.salt;
- iterations = (CK_ULONG) DER_GetInteger(&p5_param.iteration);
-
- /* allocate and fill in the PKCS #11 parameters
- * based on the algorithm. */
- if (algorithm == SEC_OID_PKCS5_PBKDF2) {
- SECOidTag prfAlgTag;
- CK_PKCS5_PBKD2_PARAMS *pbeV2_params =
- (CK_PKCS5_PBKD2_PARAMS *)PORT_ZAlloc(
- sizeof(CK_PKCS5_PBKD2_PARAMS)+ salt->len);
-
- if (pbeV2_params == NULL) {
- goto loser;
- }
- paramData = (unsigned char *)pbeV2_params;
- paramLen = sizeof(CK_PKCS5_PBKD2_PARAMS);
-
- /* set the prf */
- prfAlgTag = SEC_OID_HMAC_SHA1;
- if (p5_param.pPrfAlgId &&
- p5_param.pPrfAlgId->algorithm.data != 0) {
- prfAlgTag = SECOID_GetAlgorithmTag(p5_param.pPrfAlgId);
- }
- if (prfAlgTag == SEC_OID_HMAC_SHA1) {
- pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
- } else {
- /* only SHA1_HMAC is currently supported by PKCS #11 */
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- goto loser;
- }
-
- /* probably should fetch these from the prfAlgid */
- pbeV2_params->pPrfData = NULL;
- pbeV2_params->ulPrfDataLen = 0;
- pbeV2_params->saltSource = CKZ_SALT_SPECIFIED;
- pSalt = ((CK_CHAR_PTR) pbeV2_params)+sizeof(CK_PKCS5_PBKD2_PARAMS);
- PORT_Memcpy(pSalt, salt->data, salt->len);
- pbeV2_params->pSaltSourceData = pSalt;
- pbeV2_params->ulSaltSourceDataLen = salt->len;
- pbeV2_params->iterations = iterations;
- } else {
- CK_PBE_PARAMS *pbe_params = NULL;
- pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS)+
- salt->len+iv_len);
- if (pbe_params == NULL) {
- goto loser;
- }
- paramData = (unsigned char *)pbe_params;
- paramLen = sizeof(CK_PBE_PARAMS);
-
- pSalt = ((CK_CHAR_PTR) pbe_params)+sizeof(CK_PBE_PARAMS);
- pbe_params->pSalt = pSalt;
- PORT_Memcpy(pSalt, salt->data, salt->len);
- pbe_params->ulSaltLen = salt->len;
- if (iv_len) {
- pbe_params->pInitVector =
- ((CK_CHAR_PTR) pbe_params)+ sizeof(CK_PBE_PARAMS)+salt->len;
- }
- pbe_params->ulIteration = iterations;
- }
-
- /* copy into the mechanism sec item */
- mech->data = paramData;
- mech->len = paramLen;
- if (arena) {
- PORT_FreeArena(arena,PR_TRUE);
- }
- return SECSuccess;
-
-loser:
- if (paramData) {
- PORT_Free(paramData);
- }
- if (arena) {
- PORT_FreeArena(arena,PR_TRUE);
- }
- return SECFailure;
-}
-
-/*
- * public, deprecated, not valid for pkcs5 v2
- *
- * use PK11_CreatePBEV2AlgorithmID or PK11_CreatePBEAlgorithmID to create
- * PBE algorithmID's directly.
- */
-SECStatus
-PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PRArenaPool *arena,
- SECAlgorithmID *algId)
-{
- CK_PBE_PARAMS *pbe_param;
- SECItem pbeSalt;
- SECAlgorithmID *pbeAlgID = NULL;
- SECStatus rv;
-
- if(!param || !algId) {
- return SECFailure;
- }
-
- pbe_param = (CK_PBE_PARAMS *)param->data;
- pbeSalt.data = (unsigned char *)pbe_param->pSalt;
- pbeSalt.len = pbe_param->ulSaltLen;
- pbeAlgID = sec_pkcs5CreateAlgorithmID(algTag, SEC_OID_UNKNOWN,
- SEC_OID_UNKNOWN, NULL, 0, &pbeSalt, (int)pbe_param->ulIteration);
- if(!pbeAlgID) {
- return SECFailure;
- }
-
- rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID);
- SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE);
- return rv;
-}
-
-/*
- * public, Deprecated, This function is only for binary compatibility with
- * older applications. Does not support PKCS5v2.
- *
- * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for
- * iv values rather than generating PBE bits directly.
- */
-PBEBitGenContext *
-PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations)
-{
- SECItem *context = NULL;
- SECItem mechItem;
- CK_PBE_PARAMS pbe_params;
- CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
- PK11SlotInfo *slot;
- PK11SymKey *symKey = NULL;
- unsigned char ivData[8];
-
-
- /* use the purpose to select the low level keygen algorithm */
- switch (bitGenPurpose) {
- case pbeBitGenIntegrityKey:
- switch (hashAlgorithm) {
- case SEC_OID_SHA1:
- mechanism = CKM_PBA_SHA1_WITH_SHA1_HMAC;
- break;
- case SEC_OID_MD2:
- mechanism = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;
- break;
- case SEC_OID_MD5:
- mechanism = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;
- break;
- default:
- break;
- }
- break;
- case pbeBitGenCipherIV:
- if (bitsNeeded > 64) {
- break;
- }
- if (hashAlgorithm != SEC_OID_SHA1) {
- break;
- }
- mechanism = CKM_PBE_SHA1_DES3_EDE_CBC;
- break;
- case pbeBitGenCipherKey:
- if (hashAlgorithm != SEC_OID_SHA1) {
- break;
- }
- switch (bitsNeeded) {
- case 40:
- mechanism = CKM_PBE_SHA1_RC4_40;
- break;
- case 128:
- mechanism = CKM_PBE_SHA1_RC4_128;
- break;
- default:
- break;
- }
- case pbeBitGenIDNull:
- break;
- }
-
- if (mechanism == CKM_INVALID_MECHANISM) {
- /* we should set an error, but this is a deprecated function, and
- * we are keeping bug for bug compatibility;)... */
- return NULL;
- }
-
- pbe_params.pInitVector = ivData;
- pbe_params.pPassword = pwitem->data;
- pbe_params.ulPasswordLen = pwitem->len;
- pbe_params.pSalt = salt->data;
- pbe_params.ulSaltLen = salt->len;
- pbe_params.ulIteration = iterations;
- mechItem.data = (unsigned char *) &pbe_params;
- mechItem.len = sizeof(pbe_params);
-
-
- slot = PK11_GetInternalSlot();
- symKey = PK11_RawPBEKeyGen(slot,mechanism,
- &mechItem, pwitem, PR_FALSE, NULL);
- PK11_FreeSlot(slot);
- if (symKey != NULL) {
- if (bitGenPurpose == pbeBitGenCipherIV) {
- /* NOTE: this assumes that bitsNeeded is a multiple of 8! */
- SECItem ivItem;
-
- ivItem.data = ivData;
- ivItem.len = bitsNeeded/8;
- context = SECITEM_DupItem(&ivItem);
- } else {
- SECItem *keyData;
- PK11_ExtractKeyValue(symKey);
- keyData = PK11_GetKeyData(symKey);
-
- /* assert bitsNeeded with length? */
- if (keyData) {
- context = SECITEM_DupItem(keyData);
- }
- }
- PK11_FreeSymKey(symKey);
- }
-
- return (PBEBitGenContext *)context;
-}
-
-/*
- * public, Deprecated, This function is only for binary compatibility with
- * older applications. Does not support PKCS5v2.
- *
- * Applications should use PK11_PBEKeyGen() for keys and PK11_GetIV() for
- * iv values rather than generating PBE bits directly.
- */
-SECItem *
-PBE_GenerateBits(PBEBitGenContext *context)
-{
- return (SECItem *)context;
-}
-
-/*
- * public, Deprecated, This function is only for binary compatibility with
- * older applications. Does not support PKCS5v2.
- *
- * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for
- * iv values rather than generating PBE bits directly.
- */
-void
-PBE_DestroyContext(PBEBitGenContext *context)
-{
- SECITEM_FreeItem((SECItem *)context,PR_TRUE);
-}
-
-/*
- * public, deprecated. Replaced with PK11_GetPBEIV().
- */
-SECItem *
-SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
-{
- /* pbe stuff */
- CK_MECHANISM_TYPE type;
- SECItem *param = NULL;
- SECItem *iv = NULL;
- SECItem src;
- int iv_len = 0;
- PK11SymKey *symKey;
- PK11SlotInfo *slot;
- CK_PBE_PARAMS_PTR pPBEparams;
- SECOidTag pbeAlg;
-
- pbeAlg = SECOID_GetAlgorithmTag(algid);
- if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) {
- unsigned char *ivData;
- sec_pkcs5V2Parameter *pbeV2_param = NULL;
-
- /* can only return the IV if the crypto Algorithm exists */
- if (pbeAlg == SEC_OID_PKCS5_PBKDF2) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- goto loser;
- }
- pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
- if (pbeV2_param == NULL) {
- goto loser;
- }
- /* extract the IV from the cipher algid portion of our pkcs 5 v2
- * algorithm id */
- type = PK11_AlgtagToMechanism(
- SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId));
- param = PK11_ParamFromAlgid(&pbeV2_param->cipherAlgId);
- sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
- if (!param) {
- goto loser;
- }
- /* NOTE: NULL is a permissible return here */
- ivData = PK11_IVFromParam(type, param, &iv_len);
- src.data = ivData;
- src.len = iv_len;
- goto done;
- }
-
- type = PK11_AlgtagToMechanism(pbeAlg);
- param = PK11_ParamFromAlgid(algid);
- if (param == NULL) {
- goto done;
- }
- slot = PK11_GetInternalSlot();
- symKey = PK11_RawPBEKeyGen(slot, type, param, pwitem, faulty3DES, NULL);
- PK11_FreeSlot(slot);
- if (symKey == NULL) {
- goto loser;
- }
- PK11_FreeSymKey(symKey);
- pPBEparams = (CK_PBE_PARAMS_PTR)param->data;
- iv_len = PK11_GetIVLength(type);
-
- src.data = (unsigned char *)pPBEparams->pInitVector;
- src.len = iv_len;
-
-done:
- iv = SECITEM_DupItem(&src);
-
-loser:
- if (param) {
- SECITEM_ZfreeItem(param, PR_TRUE);
- }
- return iv;
-}
-
-/*
- * Subs from nss 3.x that are deprecated
- */
-PBEBitGenContext *
-__PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations)
-{
- PORT_Assert("__PBE_CreateContext is Deprecated" == NULL);
- return NULL;
-}
-
-SECItem *
-__PBE_GenerateBits(PBEBitGenContext *context)
-{
- PORT_Assert("__PBE_GenerateBits is Deprecated" == NULL);
- return NULL;
-}
-
-void
-__PBE_DestroyContext(PBEBitGenContext *context)
-{
- PORT_Assert("__PBE_DestroyContext is Deprecated" == NULL);
-}
-
-SECStatus
-RSA_FormatBlock(SECItem *result, unsigned modulusLen,
- int blockType, SECItem *data)
-{
- PORT_Assert("RSA_FormatBlock is Deprecated" == NULL);
- return SECFailure;
-}
-
-/****************************************************************************
- *
- * Now Do The PBE Functions Here...
- *
- ****************************************************************************/
-
-static void
-pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params)
-{
- if (pbe_params) {
- if (pbe_params->pPassword)
- PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen);
- if (pbe_params->pSalt)
- PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen);
- PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS));
- }
-}
-
-/*
- * public, deprecated. use PK11_CreatePBEAlgorithmID or
- * PK11_CreatePBEV2AlgorithmID instead. If you needthe pkcs #11 parameters,
- * use PK11_ParamFromAlgid from the algorithm id you created using
- * PK11_CreatePBEAlgorithmID or PK11_CreatePBEV2AlgorithmID.
- */
-SECItem *
-PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations)
-{
- CK_PBE_PARAMS *pbe_params = NULL;
- SECItem *paramRV = NULL;
-
- paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS));
- if (!paramRV ) {
- goto loser;
- }
- /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */
- PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS));
-
- pbe_params = (CK_PBE_PARAMS *)paramRV->data;
- pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len);
- if (!pbe_params->pPassword) {
- goto loser;
- }
- PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len);
- pbe_params->ulPasswordLen = pwd->len;
-
- pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len);
- if (!pbe_params->pSalt) {
- goto loser;
- }
- PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
- pbe_params->ulSaltLen = salt->len;
-
- pbe_params->ulIteration = (CK_ULONG)iterations;
- return paramRV;
-
-loser:
- if (pbe_params)
- pk11_destroy_ck_pbe_params(pbe_params);
- if (paramRV)
- PORT_ZFree(paramRV, sizeof(SECItem));
- return NULL;
-}
-
-/*
- * public, deprecated.
- */
-void
-PK11_DestroyPBEParams(SECItem *pItem)
-{
- if (pItem) {
- CK_PBE_PARAMS * params = (CK_PBE_PARAMS *)(pItem->data);
- if (params)
- pk11_destroy_ck_pbe_params(params);
- PORT_ZFree(pItem, sizeof(SECItem));
- }
-}
-
-/*
- * public, Partially supports PKCS5 V2 (some parameters are not controllable
- * through this interface). Use PK11_CreatePBEV2AlgorithmID() if you need
- * finer control these.
- */
-SECAlgorithmID *
-PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt)
-{
- SECAlgorithmID *algid = NULL;
- algid = sec_pkcs5CreateAlgorithmID(algorithm,
- SEC_OID_UNKNOWN, SEC_OID_UNKNOWN, NULL, 0, salt, iteration);
- return algid;
-}
-
-/*
- * public, fully support pkcs5v2.
- */
-SECAlgorithmID *
-PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag, SECOidTag cipherAlgTag,
- SECOidTag prfAlgTag, int keyLength, int iteration,
- SECItem *salt)
-{
- SECAlgorithmID *algid = NULL;
- algid = sec_pkcs5CreateAlgorithmID(pbeAlgTag, cipherAlgTag, prfAlgTag,
- NULL, keyLength, salt, iteration);
- return algid;
-}
-
-/*
- * private.
- */
-PK11SymKey *
-pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- SECItem *params, CK_KEY_TYPE keyType, int keyLen,
- SECItem *pwitem, void *wincx)
-{
- CK_ULONG pwLen;
- /* do some sanity checks */
- if ((params == NULL) || (params->data == NULL)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- if (type == CKM_INVALID_MECHANISM) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return NULL;
- }
-
- /* set the password pointer in the parameters... */
- if (type == CKM_PKCS5_PBKD2) {
- CK_PKCS5_PBKD2_PARAMS *pbev2_params;
- if (params->len < sizeof(CK_PKCS5_PBKD2_PARAMS)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- pbev2_params = (CK_PKCS5_PBKD2_PARAMS *)params->data;
- pbev2_params->pPassword = pwitem->data;
- pwLen = pwitem->len;
- pbev2_params->ulPasswordLen = &pwLen;
- } else {
- CK_PBE_PARAMS *pbe_params;
- if (params->len < sizeof(CK_PBE_PARAMS)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- pbe_params = (CK_PBE_PARAMS *)params->data;
- pbe_params->pPassword = pwitem->data;
- pbe_params->ulPasswordLen = pwitem->len;
- }
-
- /* generate the key (and sometimes the IV as a side effect...) */
- return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, params, keyType,
- keyLen, NULL, CKF_SIGN|CKF_ENCRYPT|CKF_DECRYPT|CKF_UNWRAP|CKF_WRAP,
- 0, wincx);
-}
-
-/*
- * public, deprecated. use PK11_PBEKeyGen instead.
- */
-PK11SymKey *
-PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech,
- SECItem *pwitem, PRBool faulty3DES, void *wincx)
-{
- if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
- type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
- }
- return pk11_RawPBEKeyGenWithKeyType(slot, type, mech, -1, 0, pwitem, wincx);
-}
-
-/*
- * pubic, supports pkcs5 v2.
- *
- * Create symkey from a PBE key. The algid can be created with
- * PK11_CreatePBEV2AlgorithmID and PK11_CreatePBEAlgorithmID, or by
- * extraction of der data.
- */
-PK11SymKey *
-PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
- PRBool faulty3DES, void *wincx)
-{
- CK_MECHANISM_TYPE type;
- SECItem *param = NULL;
- PK11SymKey *symKey = NULL;
- SECOidTag pbeAlg;
- CK_KEY_TYPE keyType = -1;
- int keyLen = 0;
-
- pbeAlg = SECOID_GetAlgorithmTag(algid);
- /* if we're using PKCS5v2, extract the additional information we need
- * (key length, key type, and pbeAlg). */
- if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) {
- CK_MECHANISM_TYPE cipherMech;
- sec_pkcs5V2Parameter *pbeV2_param;
-
- pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
- if (pbeV2_param == NULL) {
- return NULL;
- }
- cipherMech = PK11_AlgtagToMechanism(
- SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId));
- pbeAlg = SECOID_GetAlgorithmTag(&pbeV2_param->pbeAlgId);
- param = PK11_ParamFromAlgid(&pbeV2_param->pbeAlgId);
- sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
- keyLen = SEC_PKCS5GetKeyLength(algid);
- if (keyLen == -1) {
- keyLen = 0;
- }
- keyType = PK11_GetKeyType(cipherMech, keyLen);
- } else {
- param = PK11_ParamFromAlgid(algid);
- }
-
- if(param == NULL) {
- goto loser;
- }
-
- type = PK11_AlgtagToMechanism(pbeAlg);
- if (type == CKM_INVALID_MECHANISM) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- goto loser;
- }
- if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
- type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
- }
- symKey = pk11_RawPBEKeyGenWithKeyType(slot, type, param, keyType, keyLen,
- pwitem, wincx);
-
-loser:
- if (param) {
- SECITEM_ZfreeItem(param, PR_TRUE);
- }
- return symKey;
-}
-
-/*
- * public, supports pkcs5v2
- */
-SECItem *
-PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem)
-{
- return SEC_PKCS5GetIV(algid, pwitem, PR_FALSE);
-}
-
-CK_MECHANISM_TYPE
-pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,
- SECItem *pbe_pwd, PRBool faulty3DES)
-{
- int keyLen = 0;
- SECOidTag algTag = SEC_PKCS5GetCryptoAlgorithm(algid);
- CK_MECHANISM_TYPE mech = PK11_AlgtagToMechanism(algTag);
- CK_MECHANISM_TYPE returnedMechanism = CKM_INVALID_MECHANISM;
- SECItem *iv = NULL;
-
- if (mech == CKM_INVALID_MECHANISM) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- goto loser;
- }
- if (PK11_GetIVLength(mech)) {
- iv = SEC_PKCS5GetIV(algid, pbe_pwd, faulty3DES);
- if (iv == NULL) {
- goto loser;
- }
- }
-
- keyLen = SEC_PKCS5GetKeyLength(algid);
-
- *param = pk11_ParamFromIVWithLen(mech, iv, keyLen);
- if (*param == NULL) {
- goto loser;
- }
- returnedMechanism = mech;
-
-loser:
- if (iv) {
- SECITEM_FreeItem(iv,PR_TRUE);
- }
- return returnedMechanism;
-}
-
-/*
- * Public, supports pkcs5 v2
- *
- * Get the crypto mechanism directly from the pbe algorithmid.
- *
- * It's important to go directly from the algorithm id so that we can
- * handle both the PKCS #5 v1, PKCS #12, and PKCS #5 v2 cases.
- *
- * This function returns both the mechanism and the parameter for the mechanism.
- * The caller is responsible for freeing the parameter.
- */
-CK_MECHANISM_TYPE
-PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param,
- SECItem *pbe_pwd)
-{
- return pk11_GetPBECryptoMechanism(algid, param, pbe_pwd, PR_FALSE);
-}
diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c
deleted file mode 100644
index c91ffd21b..000000000
--- a/security/nss/lib/pk11wrap/pk11pk12.c
+++ /dev/null
@@ -1,518 +0,0 @@
-
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file PKCS #12 fuctions that should really be moved to the
- * PKCS #12 directory, however we can't do that in a point release
- * because that will break binary compatibility, so we keep them here for now.
- */
-
-#include "seccomon.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "pkcs11.h"
-#include "pk11func.h"
-#include "secitem.h"
-#include "key.h"
-#include "secoid.h"
-#include "secasn1.h"
-#include "secerr.h"
-
-
-
-/* These data structures should move to a common .h file shared between the
- * wrappers and the pkcs 12 code. */
-
-/*
-** RSA Raw Private Key structures
-*/
-
-/* member names from PKCS#1, section 7.2 */
-struct SECKEYRSAPrivateKeyStr {
- PRArenaPool * arena;
- SECItem version;
- SECItem modulus;
- SECItem publicExponent;
- SECItem privateExponent;
- SECItem prime1;
- SECItem prime2;
- SECItem exponent1;
- SECItem exponent2;
- SECItem coefficient;
-};
-typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey;
-
-
-/*
-** DSA Raw Private Key structures
-*/
-
-struct SECKEYDSAPrivateKeyStr {
- SECKEYPQGParams params;
- SECItem privateValue;
-};
-typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey;
-
-/*
-** Diffie-Hellman Raw Private Key structures
-** Structure member names suggested by PKCS#3.
-*/
-struct SECKEYDHPrivateKeyStr {
- PRArenaPool * arena;
- SECItem prime;
- SECItem base;
- SECItem privateValue;
-};
-typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey;
-
-/*
-** raw private key object
-*/
-struct SECKEYRawPrivateKeyStr {
- PLArenaPool *arena;
- KeyType keyType;
- union {
- SECKEYRSAPrivateKey rsa;
- SECKEYDSAPrivateKey dsa;
- SECKEYDHPrivateKey dh;
- } u;
-};
-typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-/* ASN1 Templates for new decoder/encoder */
-/*
- * Attribute value for PKCS8 entries (static?)
- */
-const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECKEYAttribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(SECKEYAttribute, attrValue),
- SEC_ASN1_SUB(SEC_AnyTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
-};
-
-const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo,version) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SECKEYPrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo,privateKey) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SECKEYPrivateKeyInfo,attributes),
- SECKEY_SetOfAttributeTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate }
-};
-
-const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.version) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.modulus) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.publicExponent) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.privateExponent) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime1) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime2) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent1) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent2) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.coefficient) },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dsa.privateValue) },
-};
-
-const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.privateValue) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.base) },
- { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.prime) },
-};
-
-const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SECKEYEncryptedPrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SECKEYEncryptedPrivateKeyInfo,encryptedData) },
- { 0 }
-};
-
-const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)
-
-/*
- * See bugzilla bug 125359
- * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
- * all of the templates above that en/decode into integers must be converted
- * from ASN.1's signed integer type. This is done by marking either the
- * source or destination (encoding or decoding, respectively) type as
- * siUnsignedInteger.
- */
-
-static void
-prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
-{
- key->u.rsa.modulus.type = siUnsignedInteger;
- key->u.rsa.publicExponent.type = siUnsignedInteger;
- key->u.rsa.privateExponent.type = siUnsignedInteger;
- key->u.rsa.prime1.type = siUnsignedInteger;
- key->u.rsa.prime2.type = siUnsignedInteger;
- key->u.rsa.exponent1.type = siUnsignedInteger;
- key->u.rsa.exponent2.type = siUnsignedInteger;
- key->u.rsa.coefficient.type = siUnsignedInteger;
-}
-
-static void
-prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
-{
- key->u.dsa.privateValue.type = siUnsignedInteger;
- key->u.dsa.params.prime.type = siUnsignedInteger;
- key->u.dsa.params.subPrime.type = siUnsignedInteger;
- key->u.dsa.params.base.type = siUnsignedInteger;
-}
-
-static void
-prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
-{
- key->u.dh.privateValue.type = siUnsignedInteger;
- key->u.dh.prime.type = siUnsignedInteger;
- key->u.dh.base.type = siUnsignedInteger;
-}
-
-
-SECStatus
-PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI,
- SECItem *nickname, SECItem *publicValue, PRBool isPerm,
- PRBool isPrivate, unsigned int keyUsage, void *wincx)
-{
- return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI,
- nickname, publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);
-}
-
-SECStatus
-PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
- SECItem *nickname, SECItem *publicValue, PRBool isPerm,
- PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey** privk,
- void *wincx)
-{
- SECKEYPrivateKeyInfo *pki = NULL;
- PRArenaPool *temparena = NULL;
- SECStatus rv = SECFailure;
-
- temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!temparena)
- return rv;
- pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo);
- if (!pki) {
- PORT_FreeArena(temparena, PR_FALSE);
- return rv;
- }
- pki->arena = temparena;
-
- rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate,
- derPKI);
- if( rv != SECSuccess ) {
- goto finish;
- }
-
- rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
- publicValue, isPerm, isPrivate, keyUsage, privk, wincx);
-
-finish:
- /* this zeroes the key and frees the arena */
- SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/);
- return rv;
-}
-
-SECStatus
-PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
- SECItem *nickname, SECItem *publicValue, PRBool isPerm,
- PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk,
- void *wincx)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
- CK_KEY_TYPE keyType = CKK_RSA;
- CK_OBJECT_HANDLE objectID;
- CK_ATTRIBUTE theTemplate[20];
- int templateCount = 0;
- SECStatus rv = SECFailure;
- CK_ATTRIBUTE *attrs;
- CK_ATTRIBUTE *signedattr = NULL;
- int signedcount = 0;
- CK_ATTRIBUTE *ap;
- SECItem *ck_id = NULL;
-
- attrs = theTemplate;
-
-
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL) ); attrs++;
- PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL) ); attrs++;
- PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse,
- sizeof(CK_BBOOL) ); attrs++;
-
- switch (lpk->keyType) {
- case rsaKey:
- keyType = CKK_RSA;
- PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ?
- &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
- PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ?
- &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
- PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ?
- &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
- PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
- (keyUsage & KU_DIGITAL_SIGNATURE) ?
- &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
- ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus);
- if (ck_id == NULL) {
- goto loser;
- }
- PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++;
- if (nickname) {
- PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); attrs++;
- }
- signedattr = attrs;
- PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data,
- lpk->u.rsa.modulus.len); attrs++;
- PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
- lpk->u.rsa.publicExponent.data,
- lpk->u.rsa.publicExponent.len); attrs++;
- PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT,
- lpk->u.rsa.privateExponent.data,
- lpk->u.rsa.privateExponent.len); attrs++;
- PK11_SETATTRS(attrs, CKA_PRIME_1,
- lpk->u.rsa.prime1.data,
- lpk->u.rsa.prime1.len); attrs++;
- PK11_SETATTRS(attrs, CKA_PRIME_2,
- lpk->u.rsa.prime2.data,
- lpk->u.rsa.prime2.len); attrs++;
- PK11_SETATTRS(attrs, CKA_EXPONENT_1,
- lpk->u.rsa.exponent1.data,
- lpk->u.rsa.exponent1.len); attrs++;
- PK11_SETATTRS(attrs, CKA_EXPONENT_2,
- lpk->u.rsa.exponent2.data,
- lpk->u.rsa.exponent2.len); attrs++;
- PK11_SETATTRS(attrs, CKA_COEFFICIENT,
- lpk->u.rsa.coefficient.data,
- lpk->u.rsa.coefficient.len); attrs++;
- break;
- case dsaKey:
- keyType = CKK_DSA;
- /* To make our intenal PKCS #11 module work correctly with
- * our database, we need to pass in the public key value for
- * this dsa key. We have a netscape only CKA_ value to do this.
- * Only send it to internal slots */
- if( publicValue == NULL ) {
- goto loser;
- }
- if (PK11_IsInternal(slot)) {
- PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
- publicValue->data, publicValue->len); attrs++;
- }
- PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); attrs++;
- PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &cktrue, sizeof(CK_BBOOL)); attrs++;
- if(nickname) {
- PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
- attrs++;
- }
- ck_id = PK11_MakeIDFromPubKey(publicValue);
- if (ck_id == NULL) {
- goto loser;
- }
- PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++;
- signedattr = attrs;
- PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data,
- lpk->u.dsa.params.prime.len); attrs++;
- PK11_SETATTRS(attrs,CKA_SUBPRIME,lpk->u.dsa.params.subPrime.data,
- lpk->u.dsa.params.subPrime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data,
- lpk->u.dsa.params.base.len); attrs++;
- PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data,
- lpk->u.dsa.privateValue.len); attrs++;
- break;
- case dhKey:
- keyType = CKK_DH;
- /* To make our intenal PKCS #11 module work correctly with
- * our database, we need to pass in the public key value for
- * this dh key. We have a netscape only CKA_ value to do this.
- * Only send it to internal slots */
- if (PK11_IsInternal(slot)) {
- PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
- publicValue->data, publicValue->len); attrs++;
- }
- PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); attrs++;
- if(nickname) {
- PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
- attrs++;
- }
- ck_id = PK11_MakeIDFromPubKey(publicValue);
- if (ck_id == NULL) {
- goto loser;
- }
- PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++;
- signedattr = attrs;
- PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data,
- lpk->u.dh.prime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data,
- lpk->u.dh.base.len); attrs++;
- PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data,
- lpk->u.dh.privateValue.len); attrs++;
- break;
- /* what about fortezza??? */
- default:
- PORT_SetError(SEC_ERROR_BAD_KEY);
- goto loser;
- }
- templateCount = attrs - theTemplate;
- PORT_Assert(templateCount <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE));
- PORT_Assert(signedattr != NULL);
- signedcount = attrs - signedattr;
-
- for (ap=signedattr; signedcount; ap++, signedcount--) {
- pk11_SignedToUnsigned(ap);
- }
-
- rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION,
- theTemplate, templateCount, isPerm, &objectID);
-
- /* create and return a SECKEYPrivateKey */
- if( rv == SECSuccess && privk != NULL) {
- *privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx);
- if( *privk == NULL ) {
- rv = SECFailure;
- }
- }
-loser:
- if (ck_id) {
- SECITEM_ZfreeItem(ck_id, PR_TRUE);
- }
- return rv;
-}
-
-SECStatus
-PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
- SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue,
- PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
- SECKEYPrivateKey **privk, void *wincx)
-{
- CK_KEY_TYPE keyType = CKK_RSA;
- SECStatus rv = SECFailure;
- SECKEYRawPrivateKey *lpk = NULL;
- const SEC_ASN1Template *keyTemplate, *paramTemplate;
- void *paramDest = NULL;
- PRArenaPool *arena = NULL;
-
- arena = PORT_NewArena(2048);
- if(!arena) {
- return SECFailure;
- }
-
- /* need to change this to use RSA/DSA keys */
- lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena,
- sizeof(SECKEYRawPrivateKey));
- if(lpk == NULL) {
- goto loser;
- }
- lpk->arena = arena;
-
- switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- prepare_rsa_priv_key_export_for_asn1(lpk);
- keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
- paramTemplate = NULL;
- paramDest = NULL;
- lpk->keyType = rsaKey;
- keyType = CKK_RSA;
- break;
- case SEC_OID_ANSIX9_DSA_SIGNATURE:
- prepare_dsa_priv_key_export_for_asn1(lpk);
- keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
- paramTemplate = SECKEY_PQGParamsTemplate;
- paramDest = &(lpk->u.dsa.params);
- lpk->keyType = dsaKey;
- keyType = CKK_DSA;
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- if(!publicValue) {
- goto loser;
- }
- prepare_dh_priv_key_export_for_asn1(lpk);
- keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
- paramTemplate = NULL;
- paramDest = NULL;
- lpk->keyType = dhKey;
- keyType = CKK_DH;
- break;
-
- default:
- keyTemplate = NULL;
- paramTemplate = NULL;
- paramDest = NULL;
- break;
- }
-
- if(!keyTemplate) {
- goto loser;
- }
-
- /* decode the private key and any algorithm parameters */
- rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
- if(rv != SECSuccess) {
- goto loser;
- }
- if(paramDest && paramTemplate) {
- rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
- &(pki->algorithm.parameters));
- if(rv != SECSuccess) {
- goto loser;
- }
- }
-
- rv = PK11_ImportAndReturnPrivateKey(slot,lpk,nickname,publicValue, isPerm,
- isPrivate, keyUsage, privk, wincx);
-
-
-loser:
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- return rv;
-}
-
-SECStatus
-PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki,
- SECItem *nickname, SECItem *publicValue, PRBool isPerm,
- PRBool isPrivate, unsigned int keyUsage, void *wincx)
-{
- return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
- publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);
-
-}
-
diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c
deleted file mode 100644
index 6827dcdbb..000000000
--- a/security/nss/lib/pk11wrap/pk11pqg.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* Thse functions are stub functions which will get replaced with calls through
- * PKCS #11.
- */
-
-#include "pk11func.h"
-#include "secmod.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11t.h"
-#include "pk11pqg.h"
-#include "secerr.h"
-
-
-/* Generate PQGParams and PQGVerify structs.
- * Length of P specified by L.
- * if L is greater than 1024 then the resulting verify parameters will be
- * DSA2.
- * Length of Q specified by N. If zero, The PKCS #11 module will
- * pick an appropriately sized Q for P. If N is specified and L = 1024, then
- * the resulting verify parameters will be DSA2, Otherwise DSA1 parameters
- * will be returned.
- * Length of SEED in bytes specified in seedBytes.
- *
- * The underlying PKCS #11 module will check the values for L, N,
- * and seedBytes. The rules for softoken are:
- *
- * If L <= 1024, then L must be between 512 and 1024 in increments of 64 bits.
- * If L <= 1024, then N must be 0 or 160.
- * If L >= 1024, then L and N must match the following table:
- * L=1024 N=0 or 160
- * L=2048 N=0 or 224
- * L=2048 N=256
- * L=3072 N=0 or 256
- * if L <= 1024
- * seedBbytes must be in the range [20..256].
- * if L >= 1024
- * seedBbytes must be in the range [20..L/16].
- */
-extern SECStatus
-PK11_PQG_ParamGenV2(unsigned int L, unsigned int N,
- unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy)
-{
- PK11SlotInfo *slot = NULL;
- CK_ATTRIBUTE genTemplate[5];
- CK_ATTRIBUTE *attrs = genTemplate;
- int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
- CK_MECHANISM mechanism;
- CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE;
- CK_RV crv;
- CK_ATTRIBUTE pTemplate[] = {
- { CKA_PRIME, NULL, 0 },
- { CKA_SUBPRIME, NULL, 0 },
- { CKA_BASE, NULL, 0 },
- };
- CK_ATTRIBUTE vTemplate[] = {
- { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
- { CKA_NETSCAPE_PQG_SEED, NULL, 0 },
- { CKA_NETSCAPE_PQG_H, NULL, 0 },
- };
- CK_ULONG primeBits = L;
- CK_ULONG subPrimeBits = N;
- int pTemplateCount = sizeof(pTemplate)/sizeof(pTemplate[0]);
- int vTemplateCount = sizeof(vTemplate)/sizeof(vTemplate[0]);
- PRArenaPool *parena = NULL;
- PRArenaPool *varena = NULL;
- PQGParams *params = NULL;
- PQGVerify *verify = NULL;
- CK_ULONG seedBits = seedBytes*8;
-
- *pParams = NULL;
- *pVfy = NULL;
-
- if (primeBits == (CK_ULONG)-1) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
- }
- PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++;
- if (subPrimeBits != 0) {
- PK11_SETATTRS(attrs, CKA_SUB_PRIME_BITS,
- &subPrimeBits, sizeof(subPrimeBits)); attrs++;
- }
- if (seedBits != 0) {
- PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS,
- &seedBits, sizeof(seedBits)); attrs++;
- }
- count = attrs - genTemplate;
- PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
-
- slot = PK11_GetInternalSlot();
- if (slot == NULL) {
- /* set error */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);/* shouldn't happen */
- goto loser;
- }
-
- /* make sure the internal slot can handle DSA2 type parameters. */
- if (primeBits > 1024) {
- CK_MECHANISM_INFO mechanism_info;
-
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
- CKM_DSA_PARAMETER_GEN, &mechanism_info);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- /* a bug in the old softoken left CKM_DSA_PARAMETER_GEN off of the
- * mechanism List. If we get a failure asking for this value, we know
- * it can't handle DSA2 */
- if ((crv != CKR_OK) || (mechanism_info.ulMaxKeySize < primeBits)) {
- PK11_FreeSlot(slot);
- slot = PK11_GetBestSlotWithAttributes(CKM_DSA_PARAMETER_GEN, 0,
- primeBits, NULL);
- if (slot == NULL) {
- PORT_SetError(SEC_ERROR_NO_TOKEN); /* can happen */
- goto loser;
- }
- /* ditch seedBits in this case, they are NSS specific and at
- * this point we have a token that claims to handle DSA2 */
- if (seedBits) {
- attrs--;
- }
- }
- }
-
- /* Initialize the Key Gen Mechanism */
- mechanism.mechanism = CKM_DSA_PARAMETER_GEN;
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
-
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session,
- &mechanism, genTemplate, count, &objectID);
- PK11_ExitSlotMonitor(slot);
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
- }
-
- parena = PORT_NewArena(60);
- if (!parena) {
- goto loser;
- }
-
- crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
- }
-
-
- params = (PQGParams *)PORT_ArenaAlloc(parena,sizeof(PQGParams));
- if (params == NULL) {
- goto loser;
- }
-
- /* fill in Params */
- params->arena = parena;
- params->prime.type = siUnsignedInteger;
- params->prime.data = pTemplate[0].pValue;
- params->prime.len = pTemplate[0].ulValueLen;
- params->subPrime.type = siUnsignedInteger;
- params->subPrime.data = pTemplate[1].pValue;
- params->subPrime.len = pTemplate[1].ulValueLen;
- params->base.type = siUnsignedInteger;
- params->base.data = pTemplate[2].pValue;
- params->base.len = pTemplate[2].ulValueLen;
-
-
- varena = PORT_NewArena(60);
- if (!varena) {
- goto loser;
- }
-
- crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount);
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- goto loser;
- }
-
-
- verify = (PQGVerify *)PORT_ArenaAlloc(varena,sizeof(PQGVerify));
- if (verify == NULL) {
- goto loser;
- }
- /* fill in Params */
- verify->arena = varena;
- verify->counter = (unsigned int)(*(CK_ULONG*)vTemplate[0].pValue);
- verify->seed.type = siUnsignedInteger;
- verify->seed.data = vTemplate[1].pValue;
- verify->seed.len = vTemplate[1].ulValueLen;
- verify->h.type = siUnsignedInteger;
- verify->h.data = vTemplate[2].pValue;
- verify->h.len = vTemplate[2].ulValueLen;
-
- PK11_DestroyObject(slot,objectID);
- PK11_FreeSlot(slot);
-
- *pParams = params;
- *pVfy = verify;
-
- return SECSuccess;
-
-loser:
- if (objectID != CK_INVALID_HANDLE) {
- PK11_DestroyObject(slot,objectID);
- }
- if (parena != NULL) {
- PORT_FreeArena(parena,PR_FALSE);
- }
- if (varena != NULL) {
- PORT_FreeArena(varena,PR_FALSE);
- }
- if (slot) {
- PK11_FreeSlot(slot);
- }
- return SECFailure;
-}
-
-/* Generate PQGParams and PQGVerify structs.
- * Length of P specified by j. Length of h will match length of P.
- * Length of SEED in bytes specified in seedBytes.
- * seedBbytes must be in the range [20..255] or an error will result.
- */
-extern SECStatus
-PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy)
-{
- unsigned int primeBits = PQG_INDEX_TO_PBITS(j);
- return PK11_PQG_ParamGenV2(primeBits, 0, seedBytes, pParams, pVfy);
-}
-
-/* Generate PQGParams and PQGVerify structs.
- * Length of seed and length of h both equal length of P.
- * All lengths are specified by "j", according to the table above.
- */
-extern SECStatus
-PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy)
-{
- unsigned int primeBits = PQG_INDEX_TO_PBITS(j);
- return PK11_PQG_ParamGenV2(primeBits, 0, 0, pParams, pVfy);
-}
-
-/* Test PQGParams for validity as DSS PQG values.
- * If vfy is non-NULL, test PQGParams to make sure they were generated
- * using the specified seed, counter, and h values.
- *
- * Return value indicates whether Verification operation ran successfully
- * to completion, but does not indicate if PQGParams are valid or not.
- * If return value is SECSuccess, then *pResult has these meanings:
- * SECSuccess: PQGParams are valid.
- * SECFailure: PQGParams are invalid.
- */
-
-extern SECStatus
-PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy,
- SECStatus *result)
-{
- CK_ATTRIBUTE keyTempl[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_KEY_TYPE, NULL, 0 },
- { CKA_PRIME, NULL, 0 },
- { CKA_SUBPRIME, NULL, 0 },
- { CKA_BASE, NULL, 0 },
- { CKA_TOKEN, NULL, 0 },
- { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
- { CKA_NETSCAPE_PQG_SEED, NULL, 0 },
- { CKA_NETSCAPE_PQG_H, NULL, 0 },
- };
- CK_ATTRIBUTE *attrs;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_OBJECT_CLASS class = CKO_KG_PARAMETERS;
- CK_KEY_TYPE keyType = CKK_DSA;
- SECStatus rv = SECSuccess;
- PK11SlotInfo *slot;
- int keyCount;
- CK_OBJECT_HANDLE objectID;
- CK_ULONG counter;
- CK_RV crv;
-
- attrs = keyTempl;
- PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++;
- PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data,
- params->prime.len); attrs++;
- PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data,
- params->subPrime.len); attrs++;
- if (params->base.len) {
- PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len);
- attrs++;
- }
- PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++;
- if (vfy) {
- if (vfy->counter != -1) {
- counter = vfy->counter;
- PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER,
- &counter, sizeof(counter)); attrs++;
- }
- PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED,
- vfy->seed.data, vfy->seed.len); attrs++;
- if (vfy->h.len) {
- PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H,
- vfy->h.data, vfy->h.len); attrs++;
- }
- }
-
- keyCount = attrs - keyTempl;
- PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0]));
-
-
- slot = PK11_GetInternalSlot();
- if (slot == NULL) {
- return SECFailure;
- }
-
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_CreateObject(slot->session, keyTempl, keyCount,
- &objectID);
- PK11_ExitSlotMonitor(slot);
-
- /* throw away the keys, we only wanted the return code */
- PK11_DestroyObject(slot,objectID);
- PK11_FreeSlot(slot);
-
- *result = SECSuccess;
- if (crv == CKR_ATTRIBUTE_VALUE_INVALID) {
- *result = SECFailure;
- } else if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- rv = SECFailure;
- }
- return rv;
-
-}
-
-
-
-/**************************************************************************
- * Free the PQGParams struct and the things it points to. *
- **************************************************************************/
-extern void
-PK11_PQG_DestroyParams(PQGParams *params) {
- if (params == NULL)
- return;
- if (params->arena != NULL) {
- PORT_FreeArena(params->arena, PR_FALSE); /* don't zero it */
- } else {
- SECITEM_FreeItem(&params->prime, PR_FALSE); /* don't free prime */
- SECITEM_FreeItem(&params->subPrime, PR_FALSE); /* don't free subPrime */
- SECITEM_FreeItem(&params->base, PR_FALSE); /* don't free base */
- PORT_Free(params);
- }
-}
-
-/**************************************************************************
- * Free the PQGVerify struct and the things it points to. *
- **************************************************************************/
-extern void
-PK11_PQG_DestroyVerify(PQGVerify *vfy) {
- if (vfy == NULL)
- return;
- if (vfy->arena != NULL) {
- PORT_FreeArena(vfy->arena, PR_FALSE); /* don't zero it */
- } else {
- SECITEM_FreeItem(&vfy->seed, PR_FALSE); /* don't free seed */
- SECITEM_FreeItem(&vfy->h, PR_FALSE); /* don't free h */
- PORT_Free(vfy);
- }
-}
-
-#define PQG_DEFAULT_CHUNKSIZE 2048 /* bytes */
-
-/**************************************************************************
- * Return a pointer to a new PQGParams struct that is constructed from *
- * copies of the arguments passed in. *
- * Return NULL on failure. *
- **************************************************************************/
-extern PQGParams *
-PK11_PQG_NewParams(const SECItem * prime, const SECItem * subPrime,
- const SECItem * base) {
- PRArenaPool *arena;
- PQGParams *dest;
- SECStatus status;
-
- arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- goto loser;
-
- dest = (PQGParams*)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
- if (dest == NULL)
- goto loser;
-
- dest->arena = arena;
-
- status = SECITEM_CopyItem(arena, &dest->prime, prime);
- if (status != SECSuccess)
- goto loser;
-
- status = SECITEM_CopyItem(arena, &dest->subPrime, subPrime);
- if (status != SECSuccess)
- goto loser;
-
- status = SECITEM_CopyItem(arena, &dest->base, base);
- if (status != SECSuccess)
- goto loser;
-
- return dest;
-
-loser:
- if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
-}
-
-
-/**************************************************************************
- * Fills in caller's "prime" SECItem with the prime value in params.
- * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE);
- **************************************************************************/
-extern SECStatus
-PK11_PQG_GetPrimeFromParams(const PQGParams *params, SECItem * prime) {
- return SECITEM_CopyItem(NULL, prime, &params->prime);
-}
-
-
-/**************************************************************************
- * Fills in caller's "subPrime" SECItem with the prime value in params.
- * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE);
- **************************************************************************/
-extern SECStatus
-PK11_PQG_GetSubPrimeFromParams(const PQGParams *params, SECItem * subPrime) {
- return SECITEM_CopyItem(NULL, subPrime, &params->subPrime);
-}
-
-
-/**************************************************************************
- * Fills in caller's "base" SECItem with the base value in params.
- * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE);
- **************************************************************************/
-extern SECStatus
-PK11_PQG_GetBaseFromParams(const PQGParams *params, SECItem *base) {
- return SECITEM_CopyItem(NULL, base, &params->base);
-}
-
-
-/**************************************************************************
- * Return a pointer to a new PQGVerify struct that is constructed from *
- * copies of the arguments passed in. *
- * Return NULL on failure. *
- **************************************************************************/
-extern PQGVerify *
-PK11_PQG_NewVerify(unsigned int counter, const SECItem * seed,
- const SECItem * h) {
- PRArenaPool *arena;
- PQGVerify * dest;
- SECStatus status;
-
- arena = PORT_NewArena(PQG_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- goto loser;
-
- dest = (PQGVerify*)PORT_ArenaZAlloc(arena, sizeof(PQGVerify));
- if (dest == NULL)
- goto loser;
-
- dest->arena = arena;
- dest->counter = counter;
-
- status = SECITEM_CopyItem(arena, &dest->seed, seed);
- if (status != SECSuccess)
- goto loser;
-
- status = SECITEM_CopyItem(arena, &dest->h, h);
- if (status != SECSuccess)
- goto loser;
-
- return dest;
-
-loser:
- if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
-}
-
-
-/**************************************************************************
- * Returns "counter" value from the PQGVerify.
- **************************************************************************/
-extern unsigned int
-PK11_PQG_GetCounterFromVerify(const PQGVerify *verify) {
- return verify->counter;
-}
-
-/**************************************************************************
- * Fills in caller's "seed" SECItem with the seed value in verify.
- * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE);
- **************************************************************************/
-extern SECStatus
-PK11_PQG_GetSeedFromVerify(const PQGVerify *verify, SECItem *seed) {
- return SECITEM_CopyItem(NULL, seed, &verify->seed);
-}
-
-
-/**************************************************************************
- * Fills in caller's "h" SECItem with the h value in verify.
- * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE);
- **************************************************************************/
-extern SECStatus
-PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h) {
- return SECITEM_CopyItem(NULL, h, &verify->h);
-}
diff --git a/security/nss/lib/pk11wrap/pk11pqg.h b/security/nss/lib/pk11wrap/pk11pqg.h
deleted file mode 100644
index 02f9394b6..000000000
--- a/security/nss/lib/pk11wrap/pk11pqg.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* Thse functions are stub functions which will get replaced with calls through
- * PKCS #11.
- */
-
-#ifndef _PK11PQG_H_
-#define _PK11PQG_H_ 1
-
-#include "blapit.h"
-
-SEC_BEGIN_PROTOS
-
-/* Generate PQGParams and PQGVerify structs.
- * Length of seed and length of h both equal length of P.
- * All lengths are specified by "j", according to the table above.
- */
-extern SECStatus PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams,
- PQGVerify **pVfy);
-
-/* Generate PQGParams and PQGVerify structs.
- * Length of P specified by j. Length of h will match length of P.
- * Length of SEED in bytes specified in seedBytes.
- * seedBbytes must be in the range [20..255] or an error will result.
- */
-extern SECStatus PK11_PQG_ParamGenSeedLen( unsigned int j,
- unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy);
-
-
-/* Generate PQGParams and PQGVerify structs.
- * Length of P specified by L.
- * if L is greater than 1024 then the resulting verify parameters will be
- * DSA2.
- * Length of Q specified by N. If zero, The PKCS #11 module will
- * pick an appropriately sized Q for L. If N is specified and L = 1024, then
- * the resulting verify parameters will be DSA2, Otherwise DSA1 parameters
- * will be returned.
- * Length of SEED in bytes specified in seedBytes.
- *
- * The underlying PKCS #11 module will check the values for L, N,
- * and seedBytes. The rules for softoken are:
- *
- * If L <= 1024, then L must be between 512 and 1024 in increments of 64 bits.
- * If L <= 1024, then N must be 0 or 160.
- * If L >= 1024, then L and N must match the following table:
- * L=1024 N=0 or 160
- * L=2048 N=0 or 224
- * L=2048 N=256
- * L=3072 N=0 or 256
- * if L <= 1024
- * seedBbytes must be in the range [20..256].
- * if L >= 1024
- * seedBbytes must be in the range [20..L/16].
- */
-extern SECStatus
-PK11_PQG_ParamGenV2(unsigned int L, unsigned int N, unsigned int seedBytes,
- PQGParams **pParams, PQGVerify **pVfy);
-
-/* Test PQGParams for validity as DSS PQG values.
- * If vfy is non-NULL, test PQGParams to make sure they were generated
- * using the specified seed, counter, and h values.
- *
- * Return value indicates whether Verification operation ran successfully
- * to completion, but does not indicate if PQGParams are valid or not.
- * If return value is SECSuccess, then *pResult has these meanings:
- * SECSuccess: PQGParams are valid.
- * SECFailure: PQGParams are invalid.
- *
- * Verify the following 12 facts about PQG counter SEED g and h
- * These tests are specified in FIPS 186-3 Appendix A.1.1.1, A.1.1.3, and A.2.2
- * PQG_VerifyParams in softoken/freebl will automatically choose the
- * appropriate test.
- */
-extern SECStatus PK11_PQG_VerifyParams(const PQGParams *params,
- const PQGVerify *vfy, SECStatus *result);
-extern void PK11_PQG_DestroyParams(PQGParams *params);
-extern void PK11_PQG_DestroyVerify(PQGVerify *vfy);
-
-/**************************************************************************
- * Return a pointer to a new PQGParams struct that is constructed from *
- * copies of the arguments passed in. *
- * Return NULL on failure. *
- **************************************************************************/
-extern PQGParams * PK11_PQG_NewParams(const SECItem * prime, const
- SECItem * subPrime, const SECItem * base);
-
-
-/**************************************************************************
- * Fills in caller's "prime" SECItem with the prime value in params.
- * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE);
- **************************************************************************/
-extern SECStatus PK11_PQG_GetPrimeFromParams(const PQGParams *params,
- SECItem * prime);
-
-
-/**************************************************************************
- * Fills in caller's "subPrime" SECItem with the prime value in params.
- * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE);
- **************************************************************************/
-extern SECStatus PK11_PQG_GetSubPrimeFromParams(const PQGParams *params,
- SECItem * subPrime);
-
-
-/**************************************************************************
- * Fills in caller's "base" SECItem with the base value in params.
- * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE);
- **************************************************************************/
-extern SECStatus PK11_PQG_GetBaseFromParams(const PQGParams *params,
- SECItem *base);
-
-
-/**************************************************************************
- * Return a pointer to a new PQGVerify struct that is constructed from *
- * copies of the arguments passed in. *
- * Return NULL on failure. *
- **************************************************************************/
-extern PQGVerify * PK11_PQG_NewVerify(unsigned int counter,
- const SECItem * seed, const SECItem * h);
-
-
-/**************************************************************************
- * Returns "counter" value from the PQGVerify.
- **************************************************************************/
-extern unsigned int PK11_PQG_GetCounterFromVerify(const PQGVerify *verify);
-
-/**************************************************************************
- * Fills in caller's "seed" SECItem with the seed value in verify.
- * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE);
- **************************************************************************/
-extern SECStatus PK11_PQG_GetSeedFromVerify(const PQGVerify *verify,
- SECItem *seed);
-
-/**************************************************************************
- * Fills in caller's "h" SECItem with the h value in verify.
- * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE);
- **************************************************************************/
-extern SECStatus PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/pk11wrap/pk11priv.h b/security/nss/lib/pk11wrap/pk11priv.h
deleted file mode 100644
index c68293b0a..000000000
--- a/security/nss/lib/pk11wrap/pk11priv.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _PK11PRIV_H_
-#define _PK11PRIV_H_
-#include "plarena.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "secdert.h"
-#include "keyt.h"
-#include "certt.h"
-#include "pkcs11t.h"
-#include "secmodt.h"
-#include "seccomon.h"
-#include "pkcs7t.h"
-#include "cmsreclist.h"
-
-/*
- * These are the private NSS functions. They are not exported by nss.def, and
- * are not callable outside nss3.dll.
- */
-
-SEC_BEGIN_PROTOS
-
-/************************************************************
- * Generic Slot Lists Management
- ************************************************************/
-PK11SlotList * PK11_NewSlotList(void);
-PK11SlotList * PK11_GetPrivateKeyTokens(CK_MECHANISM_TYPE type,
- PRBool needRW,void *wincx);
-SECStatus PK11_AddSlotToList(PK11SlotList *list,PK11SlotInfo *slot, PRBool sorted);
-SECStatus PK11_DeleteSlotFromList(PK11SlotList *list,PK11SlotListElement *le);
-PK11SlotListElement *PK11_FindSlotElement(PK11SlotList *list,
- PK11SlotInfo *slot);
-PK11SlotInfo *PK11_FindSlotBySerial(char *serial);
-int PK11_GetMaxKeyLength(CK_MECHANISM_TYPE type);
-
-/************************************************************
- * Generic Slot Management
- ************************************************************/
-CK_OBJECT_HANDLE PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject);
-SECStatus PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE_TYPE type, PLArenaPool *arena, SECItem *result);
-CK_ULONG PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE_TYPE type);
-char * PK11_MakeString(PLArenaPool *arena,char *space,char *staticSring,
- int stringLen);
-int PK11_MapError(CK_RV error);
-CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot);
-void PK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession);
-PRBool PK11_RWSessionHasLock(PK11SlotInfo *slot,
- CK_SESSION_HANDLE session_handle);
-PK11SlotInfo *PK11_NewSlotInfo(SECMODModule *mod);
-void PK11_EnterSlotMonitor(PK11SlotInfo *);
-void PK11_ExitSlotMonitor(PK11SlotInfo *);
-void PK11_CleanKeyList(PK11SlotInfo *slot);
-
-
-/************************************************************
- * Slot Password Management
- ************************************************************/
-SECStatus PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
- PRBool loadCerts, void *wincx, PRBool alreadyLocked,
- PRBool contextSpecific);
-SECStatus PK11_VerifyPW(PK11SlotInfo *slot,char *pw);
-void PK11_HandlePasswordCheck(PK11SlotInfo *slot,void *wincx);
-void PK11_SetVerifyPasswordFunc(PK11VerifyPasswordFunc func);
-void PK11_SetIsLoggedInFunc(PK11IsLoggedInFunc func);
-
-/************************************************************
- * Manage the built-In Slot Lists
- ************************************************************/
-SECStatus PK11_InitSlotLists(void);
-void PK11_DestroySlotLists(void);
-PK11SlotList *PK11_GetSlotList(CK_MECHANISM_TYPE type);
-void PK11_LoadSlotList(PK11SlotInfo *slot, PK11PreSlotInfo *psi, int count);
-void PK11_ClearSlotList(PK11SlotInfo *slot);
-
-
-/******************************************************************
- * Slot initialization
- ******************************************************************/
-SECStatus PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts);
-void PK11_InitSlot(SECMODModule *mod,CK_SLOT_ID slotID,PK11SlotInfo *slot);
-PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot);
-SECStatus PK11_ReadSlotCerts(PK11SlotInfo *slot);
-void pk11_SetInternalKeySlot(PK11SlotInfo *slot);
-PK11SlotInfo *pk11_SwapInternalKeySlot(PK11SlotInfo *slot);
-void pk11_SetInternalKeySlotIfFirst(PK11SlotInfo *slot);
-
-/*********************************************************************
- * Mechanism Mapping functions
- *********************************************************************/
-void PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
- CK_MECHANISM_TYPE keygen, CK_MECHANISM_TYPE pad,
- int ivLen, int blocksize);
-CK_MECHANISM_TYPE PK11_GetKeyMechanism(CK_KEY_TYPE type);
-CK_MECHANISM_TYPE PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size);
-
-/**********************************************************************
- * Symetric, Public, and Private Keys
- **********************************************************************/
-/* Key Generation specialized for SDR (fixed DES3 key) */
-PK11SymKey *PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx);
-SECKEYPublicKey *PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType,
- CK_OBJECT_HANDLE id);
-CK_OBJECT_HANDLE PK11_FindObjectForCert(CERTCertificate *cert,
- void *wincx, PK11SlotInfo **pSlot);
-PK11SymKey * pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
- CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey);
-
-/**********************************************************************
- * Certs
- **********************************************************************/
-SECStatus PK11_TraversePrivateKeysInSlot( PK11SlotInfo *slot,
- SECStatus(* callback)(SECKEYPrivateKey*, void*), void *arg);
-SECKEYPrivateKey * PK11_FindPrivateKeyFromNickname(char *nickname, void *wincx);
-CK_OBJECT_HANDLE * PK11_FindObjectsFromNickname(char *nickname,
- PK11SlotInfo **slotptr, CK_OBJECT_CLASS objclass, int *returnCount,
- void *wincx);
-CK_OBJECT_HANDLE PK11_MatchItem(PK11SlotInfo *slot,CK_OBJECT_HANDLE peer,
- CK_OBJECT_CLASS o_class);
-CK_BBOOL PK11_HasAttributeSet( PK11SlotInfo *slot,
- CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE_TYPE type,
- PRBool haslock );
-CK_RV PK11_GetAttributes(PLArenaPool *arena,PK11SlotInfo *slot,
- CK_OBJECT_HANDLE obj,CK_ATTRIBUTE *attr, int count);
-int PK11_NumberCertsForCertSubject(CERTCertificate *cert);
-SECStatus PK11_TraverseCertsForSubject(CERTCertificate *cert,
- SECStatus(*callback)(CERTCertificate *, void *), void *arg);
-SECStatus PK11_GetKEAMatchedCerts(PK11SlotInfo *slot1,
- PK11SlotInfo *slot2, CERTCertificate **cert1, CERTCertificate **cert2);
-SECStatus PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
- SECStatus(* callback)(CERTCertificate*, void *), void *arg);
-SECStatus PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx);
-
-
-/**********************************************************************
- * Crypto Contexts
- **********************************************************************/
-PK11Context * PK11_CreateContextByRawKey(PK11SlotInfo *slot,
- CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation,
- SECItem *key, SECItem *param, void *wincx);
-PRBool PK11_HashOK(SECOidTag hashAlg);
-
-
-/**********************************************************************
- * Functions which are deprecated....
- **********************************************************************/
-
-SECItem *
-PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *handle,
- SECItem *derName, int type, char **url);
-
-CK_OBJECT_HANDLE
-PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl,
- SECItem *name, char *url, int type);
-
-SECItem *
-PK11_FindSMimeProfile(PK11SlotInfo **slotp, char *emailAddr, SECItem *derSubj,
- SECItem **profileTime);
-SECStatus
-PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
- SECItem *emailProfile, SECItem *profileTime);
-
-PRBool PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle);
-
-char * PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id) ;
-SECStatus PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
- const char *nickname) ;
-
-
-/* private */
-SECStatus pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),
- void *cbArg, PRBool forceLogin, void *pwArg);
-
-/* fetch multiple CRLs for a specific issuer */
-SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer,
- void *wincx);
-
-/* set global options for NSS PKCS#11 module loader */
-SECStatus pk11_setGlobalOptions(PRBool noSingleThreadedModules,
- PRBool allowAlreadyInitializedModules,
- PRBool dontFinalizeModules);
-
-/* return whether NSS is allowed to call C_Finalize */
-PRBool pk11_getFinalizeModulesOption(void);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/pk11wrap/pk11pub.h b/security/nss/lib/pk11wrap/pk11pub.h
deleted file mode 100644
index f15d6da81..000000000
--- a/security/nss/lib/pk11wrap/pk11pub.h
+++ /dev/null
@@ -1,830 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _PK11PUB_H_
-#define _PK11PUB_H_
-#include "plarena.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "secdert.h"
-#include "keyt.h"
-#include "certt.h"
-#include "pkcs11t.h"
-#include "secmodt.h"
-#include "seccomon.h"
-#include "pkcs7t.h"
-#include "cmsreclist.h"
-
-/*
- * Exported PK11 wrap functions.
- */
-
-SEC_BEGIN_PROTOS
-
-/************************************************************
- * Generic Slot Lists Management
- ************************************************************/
-void PK11_FreeSlotList(PK11SlotList *list);
-SECStatus PK11_FreeSlotListElement(PK11SlotList *list, PK11SlotListElement *le);
-PK11SlotListElement * PK11_GetFirstSafe(PK11SlotList *list);
-PK11SlotListElement *PK11_GetNextSafe(PK11SlotList *list,
- PK11SlotListElement *le, PRBool restart);
-
-/************************************************************
- * Generic Slot Management
- ************************************************************/
-PK11SlotInfo *PK11_ReferenceSlot(PK11SlotInfo *slot);
-void PK11_FreeSlot(PK11SlotInfo *slot);
-SECStatus PK11_DestroyObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object);
-SECStatus PK11_DestroyTokenObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object);
-PK11SlotInfo *PK11_GetInternalKeySlot(void);
-PK11SlotInfo *PK11_GetInternalSlot(void);
-SECStatus PK11_Logout(PK11SlotInfo *slot);
-void PK11_LogoutAll(void);
-
-
-/************************************************************
- * Slot Password Management
- ************************************************************/
-void PK11_SetSlotPWValues(PK11SlotInfo *slot,int askpw, int timeout);
-void PK11_GetSlotPWValues(PK11SlotInfo *slot,int *askpw, int *timeout);
-SECStatus PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw);
-SECStatus PK11_CheckUserPassword(PK11SlotInfo *slot, const char *pw);
-PRBool PK11_IsLoggedIn(PK11SlotInfo *slot, void *wincx);
-SECStatus PK11_InitPin(PK11SlotInfo *slot,const char *ssopw,
- const char *pk11_userpwd);
-SECStatus PK11_ChangePW(PK11SlotInfo *slot, const char *oldpw,
- const char *newpw);
-void PK11_SetPasswordFunc(PK11PasswordFunc func);
-int PK11_GetMinimumPwdLength(PK11SlotInfo *slot);
-SECStatus PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd);
-SECStatus PK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx);
-SECStatus PK11_TokenRefresh(PK11SlotInfo *slot);
-
-
-/******************************************************************
- * Slot info functions
- ******************************************************************/
-PK11SlotInfo *PK11_FindSlotByName(const char *name);
-/******************************************************************
- * PK11_FindSlotsByNames searches for a PK11SlotInfo using one or
- * more criteria : dllName, slotName and tokenName . In addition, if
- * presentOnly is set , only slots with a token inserted will be
- * returned.
- ******************************************************************/
-PK11SlotList *PK11_FindSlotsByNames(const char *dllName,
- const char* slotName, const char* tokenName, PRBool presentOnly);
-PRBool PK11_IsReadOnly(PK11SlotInfo *slot);
-PRBool PK11_IsInternal(PK11SlotInfo *slot);
-PRBool PK11_IsInternalKeySlot(PK11SlotInfo *slot);
-char * PK11_GetTokenName(PK11SlotInfo *slot);
-char * PK11_GetSlotName(PK11SlotInfo *slot);
-PRBool PK11_NeedLogin(PK11SlotInfo *slot);
-PRBool PK11_IsFriendly(PK11SlotInfo *slot);
-PRBool PK11_IsHW(PK11SlotInfo *slot);
-PRBool PK11_IsRemovable(PK11SlotInfo *slot);
-PRBool PK11_NeedUserInit(PK11SlotInfo *slot);
-PRBool PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot);
-int PK11_GetSlotSeries(PK11SlotInfo *slot);
-int PK11_GetCurrentWrapIndex(PK11SlotInfo *slot);
-unsigned long PK11_GetDefaultFlags(PK11SlotInfo *slot);
-CK_SLOT_ID PK11_GetSlotID(PK11SlotInfo *slot);
-SECMODModuleID PK11_GetModuleID(PK11SlotInfo *slot);
-SECStatus PK11_GetSlotInfo(PK11SlotInfo *slot, CK_SLOT_INFO *info);
-SECStatus PK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info);
-PRBool PK11_IsDisabled(PK11SlotInfo *slot);
-PRBool PK11_HasRootCerts(PK11SlotInfo *slot);
-PK11DisableReasons PK11_GetDisabledReason(PK11SlotInfo *slot);
-/* Prevents the slot from being used, and set disable reason to user-disable */
-/* NOTE: Mechanisms that were ON continue to stay ON */
-/* Therefore, when the slot is enabled, it will remember */
-/* what mechanisms needs to be turned on */
-PRBool PK11_UserDisableSlot(PK11SlotInfo *slot);
-/* Allow all mechanisms that are ON before UserDisableSlot() */
-/* was called to be available again */
-PRBool PK11_UserEnableSlot(PK11SlotInfo *slot);
-/*
- * wait for a specific slot event.
- * event is a specific event to wait for. Currently only
- * PK11TokenChangeOrRemovalEvent and PK11TokenPresentEvents are defined.
- * timeout can be an interval time to wait, PR_INTERVAL_NO_WAIT (meaning only
- * poll once), or PR_INTERVAL_NO_TIMEOUT (meaning block until a change).
- * pollInterval is a suggested pulling interval value. '0' means use the
- * default. Future implementations that don't poll may ignore this value.
- * series is the current series for the last slot. This should be the series
- * value for the slot the last time you read persistant information from the
- * slot. For instance, if you publish a cert from the slot, you should obtain
- * the slot series at that time. Then PK11_WaitForTokenEvent can detect a
- * a change in the slot between the time you publish and the time
- * PK11_WaitForTokenEvent is called, elliminating potential race conditions.
- *
- * The current status that is returned is:
- * PK11TokenNotRemovable - always returned for any non-removable token.
- * PK11TokenPresent - returned when the token is present and we are waiting
- * on a PK11TokenPresentEvent. Then next event to look for is a
- * PK11TokenChangeOrRemovalEvent.
- * PK11TokenChanged - returned when the old token has been removed and a new
- * token ad been inserted, and we are waiting for a
- * PK11TokenChangeOrRemovalEvent. The next event to look for is another
- * PK11TokenChangeOrRemovalEvent.
- * PK11TokenRemoved - returned when the token is not present and we are
- * waiting for a PK11TokenChangeOrRemovalEvent. The next event to look for
- * is a PK11TokenPresentEvent.
- */
-PK11TokenStatus PK11_WaitForTokenEvent(PK11SlotInfo *slot, PK11TokenEvent event,
- PRIntervalTime timeout, PRIntervalTime pollInterval, int series);
-
-PRBool PK11_NeedPWInit(void);
-PRBool PK11_TokenExists(CK_MECHANISM_TYPE);
-SECStatus PK11_GetModInfo(SECMODModule *mod, CK_INFO *info);
-PRBool PK11_IsFIPS(void);
-SECMODModule *PK11_GetModule(PK11SlotInfo *slot);
-
-/*********************************************************************
- * Slot mapping utility functions.
- *********************************************************************/
-PRBool PK11_IsPresent(PK11SlotInfo *slot);
-PRBool PK11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
-PK11SlotList * PK11_GetAllTokens(CK_MECHANISM_TYPE type,PRBool needRW,
- PRBool loadCerts, void *wincx);
-PK11SlotInfo *PK11_GetBestSlotMultipleWithAttributes(CK_MECHANISM_TYPE *type,
- CK_FLAGS *mechFlag, unsigned int *keySize,
- unsigned int count, void *wincx);
-PK11SlotInfo *PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type,
- unsigned int count, void *wincx);
-PK11SlotInfo *PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx);
-PK11SlotInfo *PK11_GetBestSlotWithAttributes(CK_MECHANISM_TYPE type,
- CK_FLAGS mechFlag, unsigned int keySize, void *wincx);
-CK_MECHANISM_TYPE PK11_GetBestWrapMechanism(PK11SlotInfo *slot);
-int PK11_GetBestKeyLength(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
-
-/*
- * Open a new database using the softoken. The caller is responsible for making
- * sure the module spec is correct and usable. The caller should ask for one
- * new database per call if the caller wants to get meaningful information
- * about the new database.
- *
- * moduleSpec is the same data that you would pass to softoken at
- * initialization time under the 'tokens' options. For example, if you were
- * to specify tokens=<0x4=[configdir='./mybackup' tokenDescription='Backup']>
- * You would specify "configdir='./mybackup' tokenDescription='Backup'" as your
- * module spec here. The slot ID will be calculated for you by
- * SECMOD_OpenUserDB().
- *
- * Typical parameters here are configdir, tokenDescription and flags.
- *
- * a Full list is below:
- *
- *
- * configDir - The location of the databases for this token. If configDir is
- * not specified, and noCertDB and noKeyDB is not specified, the load
- * will fail.
- * certPrefix - Cert prefix for this token.
- * keyPrefix - Prefix for the key database for this token. (if not specified,
- * certPrefix will be used).
- * tokenDescription - The label value for this token returned in the
- * CK_TOKEN_INFO structure with an internationalize string (UTF8).
- * This value will be truncated at 32 bytes (no NULL, partial UTF8
- * characters dropped). You should specify a user friendly name here
- * as this is the value the token will be referred to in most
- * application UI's. You should make sure tokenDescription is unique.
- * slotDescription - The slotDescription value for this token returned
- * in the CK_SLOT_INFO structure with an internationalize string
- * (UTF8). This value will be truncated at 64 bytes (no NULL, partial
- * UTF8 characters dropped). This name will not change after the
- * database is closed. It should have some number to make this unique.
- * minPWLen - minimum password length for this token.
- * flags - comma separated list of flag values, parsed case-insensitive.
- * Valid flags are:
- * readOnly - Databases should be opened read only.
- * noCertDB - Don't try to open a certificate database.
- * noKeyDB - Don't try to open a key database.
- * forceOpen - Don't fail to initialize the token if the
- * databases could not be opened.
- * passwordRequired - zero length passwords are not acceptable
- * (valid only if there is a keyDB).
- * optimizeSpace - allocate smaller hash tables and lock tables.
- * When this flag is not specified, Softoken will allocate
- * large tables to prevent lock contention.
- */
-PK11SlotInfo *SECMOD_OpenUserDB(const char *moduleSpec);
-SECStatus SECMOD_CloseUserDB(PK11SlotInfo *slot);
-
-/*
- * This is exactly the same as OpenUserDB except it can be called on any
- * module that understands softoken style new slot entries. The resulting
- * slot can be closed using SECMOD_CloseUserDB above. Value of moduleSpec
- * is token specific.
- */
-PK11SlotInfo *SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec);
-
-
-/*
- * merge the permanent objects from on token to another
- */
-SECStatus PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
- PK11MergeLog *log, void *targetPwArg, void *sourcePwArg);
-
-/*
- * create and destroy merge logs needed by PK11_MergeTokens
- */
-PK11MergeLog * PK11_CreateMergeLog(void);
-void PK11_DestroyMergeLog(PK11MergeLog *log);
-
-
-
-/*********************************************************************
- * Mechanism Mapping functions
- *********************************************************************/
-CK_MECHANISM_TYPE PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len);
-CK_MECHANISM_TYPE PK11_GetKeyGen(CK_MECHANISM_TYPE type);
-int PK11_GetBlockSize(CK_MECHANISM_TYPE type,SECItem *params);
-int PK11_GetIVLength(CK_MECHANISM_TYPE type);
-SECItem *PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv);
-unsigned char *PK11_IVFromParam(CK_MECHANISM_TYPE type,SECItem *param,int *len);
-SECItem * PK11_BlockData(SECItem *data,unsigned long size);
-
-/* PKCS #11 to DER mapping functions */
-SECItem *PK11_ParamFromAlgid(SECAlgorithmID *algid);
-SECItem *PK11_GenerateNewParam(CK_MECHANISM_TYPE, PK11SymKey *);
-CK_MECHANISM_TYPE PK11_AlgtagToMechanism(SECOidTag algTag);
-SECOidTag PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type);
-SECOidTag PK11_FortezzaMapSig(SECOidTag algTag);
-SECStatus PK11_ParamToAlgid(SECOidTag algtag, SECItem *param,
- PLArenaPool *arena, SECAlgorithmID *algid);
-SECStatus PK11_SeedRandom(PK11SlotInfo *,unsigned char *data,int len);
-SECStatus PK11_GenerateRandomOnSlot(PK11SlotInfo *,unsigned char *data,int len);
-SECStatus PK11_RandomUpdate(void *data, size_t bytes);
-SECStatus PK11_GenerateRandom(unsigned char *data,int len);
-
-/* warning: cannot work with pkcs 5 v2
- * use algorithm ID s instead of pkcs #11 mechanism pointers */
-CK_RV PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
- CK_MECHANISM_PTR pCryptoMechanism,
- SECItem *pbe_pwd, PRBool bad3DES);
-CK_MECHANISM_TYPE PK11_GetPadMechanism(CK_MECHANISM_TYPE);
-CK_MECHANISM_TYPE PK11_MapSignKeyType(KeyType keyType);
-
-/**********************************************************************
- * Symetric, Public, and Private Keys
- **********************************************************************/
-void PK11_FreeSymKey(PK11SymKey *key);
-PK11SymKey *PK11_ReferenceSymKey(PK11SymKey *symKey);
-PK11SymKey *PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx);
-PK11SymKey *PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot,
- CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation,
- SECItem *key, CK_FLAGS flags, PRBool isPerm, void *wincx);
-PK11SymKey *PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent,
- PK11Origin origin, CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID,
- PRBool owner, void *wincx);
-PK11SymKey *PK11_GetWrapKey(PK11SlotInfo *slot, int wrap,
- CK_MECHANISM_TYPE type,int series, void *wincx);
-/*
- * This function is not thread-safe. It can only be called when only
- * one thread has a reference to wrapKey.
- */
-void PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey);
-CK_MECHANISM_TYPE PK11_GetMechanism(PK11SymKey *symKey);
-/*
- * import a public key into the desired slot
- *
- * This function takes a public key structure and creates a public key in a
- * given slot. If isToken is set, then a persistant public key is created.
- *
- * Note: it is possible for this function to return a handle for a key which
- * is persistant, even if isToken is not set.
- */
-CK_OBJECT_HANDLE PK11_ImportPublicKey(PK11SlotInfo *slot,
- SECKEYPublicKey *pubKey, PRBool isToken);
-PK11SymKey *PK11_KeyGen(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
- SECItem *param, int keySize,void *wincx);
-PK11SymKey *PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- SECItem *param, int keySize, SECItem *keyid,
- PRBool isToken, void *wincx);
-PK11SymKey *PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot,
- CK_MECHANISM_TYPE type, SECItem *param,
- int keySize, SECItem *keyid, CK_FLAGS opFlags,
- PK11AttrFlags attrFlags, void *wincx);
-/* Generates a key using the exact template supplied by the caller. The other
- * PK11_[Token]KeyGen mechanisms should be used instead of this one whenever
- * they work because they include/exclude the CKA_VALUE_LEN template value
- * based on the mechanism type as required by many tokens.
- *
- * keyGenType should be PK11_GetKeyGenWithSize(type, <key size>) or it should
- * be equal to type if PK11_GetKeyGenWithSize cannot be used (e.g. because
- * pk11wrap does not know about the mechanisms).
- */
-PK11SymKey *PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- CK_MECHANISM_TYPE keyGenType,
- SECItem *param, CK_ATTRIBUTE * attrs,
- unsigned int attrsCount, void *wincx);
-PK11SymKey * PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname,
- void *wincx);
-PK11SymKey *PK11_GetNextSymKey(PK11SymKey *symKey);
-CK_KEY_TYPE PK11_GetSymKeyType(PK11SymKey *key);
-CK_OBJECT_HANDLE PK11_GetSymKeyHandle(PK11SymKey *symKey);
-
-
-/*
- * PK11_SetSymKeyUserData
- * sets generic user data on keys (usually a pointer to a data structure)
- * that can later be retrieved by PK11_GetSymKeyUserData().
- * symKey - key where data will be set.
- * data - data to be set.
- * freefunc - function used to free the data.
- * Setting user data on symKeys with existing user data already set will cause
- * the existing user data to be freed before the new user data is set.
- * Freeing user data is done by calling the user specified freefunc.
- * If freefunc is NULL, the user data is assumed to be global or static an
- * not freed. Passing NULL for user data to PK11_SetSymKeyUserData has the
- * effect of freeing any existing user data, and clearing the user data
- * pointer. If user data exists when the symKey is finally freed, that
- * data will be freed with freefunc.
- *
- * Applications should only use this function on keys which the application
- * has created directly, as there is only one user data value per key.
- */
-void PK11_SetSymKeyUserData(PK11SymKey *symKey, void *data,
- PK11FreeDataFunc freefunc);
-/* PK11_GetSymKeyUserData
- * retrieves generic user data which was set on a key by
- * PK11_SetSymKeyUserData.
- * symKey - key with data to be fetched
- *
- * If no data exists, or the data has been cleared, PK11_GetSymKeyUserData
- * will return NULL. Returned data is still owned and managed by the SymKey,
- * the caller should not free the data.
- *
- */
-void *PK11_GetSymKeyUserData(PK11SymKey *symKey);
-
-SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
- PK11SymKey *symKey, SECItem *wrappedKey);
-SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params,
- PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey);
-/* move a key to 'slot' optionally set the key attributes according to either
- * operation or the flags and making the key permanent at the same time.
- * If the key is moved to the same slot, operation and flags values are
- * currently ignored */
-PK11SymKey *PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
- CK_FLAGS flags, PRBool perm, PK11SymKey *symKey);
-/*
- * derive a new key from the base key.
- * PK11_Derive returns a key which can do exactly one operation, and is
- * ephemeral (session key).
- * PK11_DeriveWithFlags is the same as PK11_Derive, except you can use
- * CKF_ flags to enable more than one operation.
- * PK11_DeriveWithFlagsPerm is the same as PK11_DeriveWithFlags except you can
- * (optionally) make the key permanent (token key).
- */
-PK11SymKey *PK11_Derive(PK11SymKey *baseKey, CK_MECHANISM_TYPE mechanism,
- SECItem *param, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize);
-PK11SymKey *PK11_DeriveWithFlags( PK11SymKey *baseKey,
- CK_MECHANISM_TYPE derive, SECItem *param, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags);
-PK11SymKey * PK11_DeriveWithFlagsPerm( PK11SymKey *baseKey,
- CK_MECHANISM_TYPE derive,
- SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize, CK_FLAGS flags, PRBool isPerm);
-PK11SymKey *
-PK11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
- SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs,
- PRBool isPerm);
-
-
-PK11SymKey *PK11_PubDerive( SECKEYPrivateKey *privKey,
- SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB,
- CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx) ;
-PK11SymKey *PK11_PubDeriveWithKDF( SECKEYPrivateKey *privKey,
- SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB,
- CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize,
- CK_ULONG kdf, SECItem *sharedData, void *wincx);
-
-/*
- * unwrap a new key with a symetric key.
- * PK11_Unwrap returns a key which can do exactly one operation, and is
- * ephemeral (session key).
- * PK11_UnwrapWithFlags is the same as PK11_Unwrap, except you can use
- * CKF_ flags to enable more than one operation.
- * PK11_UnwrapWithFlagsPerm is the same as PK11_UnwrapWithFlags except you can
- * (optionally) make the key permanent (token key).
- */
-PK11SymKey *PK11_UnwrapSymKey(PK11SymKey *key,
- CK_MECHANISM_TYPE wraptype, SECItem *param, SECItem *wrapppedKey,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize);
-PK11SymKey *PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey,
- CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize,
- CK_FLAGS flags);
-PK11SymKey * PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey,
- CK_MECHANISM_TYPE wrapType,
- SECItem *param, SECItem *wrappedKey,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize, CK_FLAGS flags, PRBool isPerm);
-
-/*
- * unwrap a new key with a private key.
- * PK11_PubUnwrap returns a key which can do exactly one operation, and is
- * ephemeral (session key).
- * PK11_PubUnwrapWithFlagsPerm is the same as PK11_PubUnwrap except you can
- * use * CKF_ flags to enable more than one operation, and optionally make
- * the key permanent (token key).
- */
-PK11SymKey *PK11_PubUnwrapSymKey(SECKEYPrivateKey *key, SECItem *wrapppedKey,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize);
-PK11SymKey * PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey,
- SECItem *wrappedKey, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize,
- CK_FLAGS flags, PRBool isPerm);
-PK11SymKey *PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- SECItem *keyID, void *wincx);
-SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey,PRBool force);
-SECStatus PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey);
-SECStatus PK11_DeleteTokenSymKey(PK11SymKey *symKey);
-SECStatus PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx);
-SECKEYPrivateKey * PK11_LoadPrivKey(PK11SlotInfo *slot,
- SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
- PRBool token, PRBool sensitive);
-char * PK11_GetSymKeyNickname(PK11SymKey *symKey);
-char * PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey);
-char * PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey);
-SECStatus PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname);
-SECStatus PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey,
- const char *nickname);
-SECStatus PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey,
- const char *nickname);
-
-/* size to hold key in bytes */
-unsigned int PK11_GetKeyLength(PK11SymKey *key);
-/* size of actual secret parts of key in bits */
-/* algid is because RC4 strength is determined by the effective bits as well
- * as the key bits */
-unsigned int PK11_GetKeyStrength(PK11SymKey *key,SECAlgorithmID *algid);
-SECStatus PK11_ExtractKeyValue(PK11SymKey *symKey);
-SECItem * PK11_GetKeyData(PK11SymKey *symKey);
-PK11SlotInfo * PK11_GetSlotFromKey(PK11SymKey *symKey);
-void *PK11_GetWindow(PK11SymKey *symKey);
-
-/*
- * Explicitly set the key usage for the generated private key.
- *
- * This allows us to specify single use EC and RSA keys whose usage
- * can be regulated by the underlying token.
- *
- * The underlying key usage is set using opFlags. opFlagsMask specifies
- * which operations are specified by opFlags. For instance to turn encrypt
- * on and signing off, opFlags would be CKF_ENCRYPT|CKF_DECRYPT and
- * opFlagsMask would be CKF_ENCRYPT|CKF_DECRYPT|CKF_SIGN|CKF_VERIFY. You
- * need to specify both the public and private key flags,
- * PK11_GenerateKeyPairWithOpFlags will sort out the correct flag to the
- * correct key type. Flags not specified in opFlagMask will be defaulted
- * according to mechanism type and token capabilities.
- */
-SECKEYPrivateKey *PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,
- CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
- PK11AttrFlags attrFlags, CK_FLAGS opFlags, CK_FLAGS opFlagsMask,
- void *wincx);
-/*
- * The attrFlags is the logical OR of the PK11_ATTR_XXX bitflags.
- * These flags apply to the private key. The PK11_ATTR_TOKEN,
- * PK11_ATTR_SESSION, PK11_ATTR_MODIFIABLE, and PK11_ATTR_UNMODIFIABLE
- * flags also apply to the public key.
- */
-SECKEYPrivateKey *PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,
- CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
- PK11AttrFlags attrFlags, void *wincx);
-SECKEYPrivateKey *PK11_GenerateKeyPair(PK11SlotInfo *slot,
- CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
- PRBool isPerm, PRBool isSensitive, void *wincx);
-SECKEYPrivateKey * PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot,
- CERTCertificate *cert, void *wincx);
-SECKEYPrivateKey * PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx);
-SECKEYPrivateKey * PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID,
- void *wincx);
-int PK11_GetPrivateModulusLen(SECKEYPrivateKey *key);
-
-/* note: despite the name, this function takes a private key. */
-SECStatus PK11_PubDecryptRaw(SECKEYPrivateKey *key, unsigned char *data,
- unsigned *outLen, unsigned int maxLen, unsigned char *enc, unsigned encLen);
-#define PK11_PrivDecryptRaw PK11_PubDecryptRaw
-/* The encrypt function that complements the above decrypt function. */
-SECStatus PK11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc,
- unsigned char *data, unsigned dataLen, void *wincx);
-
-SECStatus PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key, unsigned char *data,
- unsigned *outLen, unsigned int maxLen, unsigned char *enc, unsigned encLen);
-/* The encrypt function that complements the above decrypt function. */
-SECStatus PK11_PubEncryptPKCS1(SECKEYPublicKey *key, unsigned char *enc,
- unsigned char *data, unsigned dataLen, void *wincx);
-
-SECStatus PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot,
- SECKEYPrivateKeyInfo *pki, SECItem *nickname,
- SECItem *publicValue, PRBool isPerm, PRBool isPrivate,
- unsigned int usage, void *wincx);
-SECStatus PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
- SECKEYPrivateKeyInfo *pki, SECItem *nickname,
- SECItem *publicValue, PRBool isPerm, PRBool isPrivate,
- unsigned int usage, SECKEYPrivateKey** privk, void *wincx);
-SECStatus PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot,
- SECItem *derPKI, SECItem *nickname,
- SECItem *publicValue, PRBool isPerm, PRBool isPrivate,
- unsigned int usage, void *wincx);
-SECStatus PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
- SECItem *derPKI, SECItem *nickname,
- SECItem *publicValue, PRBool isPerm, PRBool isPrivate,
- unsigned int usage, SECKEYPrivateKey** privk, void *wincx);
-SECStatus PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot,
- SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem,
- SECItem *nickname, SECItem *publicValue, PRBool isPerm,
- PRBool isPrivate, KeyType type,
- unsigned int usage, void *wincx);
-SECStatus PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
- SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem,
- SECItem *nickname, SECItem *publicValue, PRBool isPerm,
- PRBool isPrivate, KeyType type,
- unsigned int usage, SECKEYPrivateKey** privk, void *wincx);
-SECKEYPrivateKeyInfo *PK11_ExportPrivateKeyInfo(
- CERTCertificate *cert, void *wincx);
-SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivKeyInfo(
- PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem,
- SECKEYPrivateKey *pk, int iteration, void *wincx);
-SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivateKeyInfo(
- PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem,
- CERTCertificate *cert, int iteration, void *wincx);
-SECKEYPrivateKey *PK11_FindKeyByDERCert(PK11SlotInfo *slot,
- CERTCertificate *cert, void *wincx);
-SECKEYPublicKey *PK11_MakeKEAPubKey(unsigned char *data, int length);
-SECStatus PK11_DigestKey(PK11Context *context, PK11SymKey *key);
-PRBool PK11_VerifyKeyOK(PK11SymKey *key);
-SECKEYPrivateKey *PK11_UnwrapPrivKey(PK11SlotInfo *slot,
- PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType,
- SECItem *param, SECItem *wrappedKey, SECItem *label,
- SECItem *publicValue, PRBool token, PRBool sensitive,
- CK_KEY_TYPE keyType, CK_ATTRIBUTE_TYPE *usage, int usageCount,
- void *wincx);
-SECStatus PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
- SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType,
- SECItem *param, SECItem *wrappedKey, void *wincx);
-/*
- * The caller of PK11_DEREncodePublicKey should free the returned SECItem with
- * a SECITEM_FreeItem(..., PR_TRUE) call.
- */
-SECItem* PK11_DEREncodePublicKey(SECKEYPublicKey *pubk);
-PK11SymKey* PK11_CopySymKeyForSigning(PK11SymKey *originalKey,
- CK_MECHANISM_TYPE mech);
-SECKEYPrivateKeyList* PK11_ListPrivKeysInSlot(PK11SlotInfo *slot,
- char *nickname, void *wincx);
-SECKEYPublicKeyList* PK11_ListPublicKeysInSlot(PK11SlotInfo *slot,
- char *nickname);
-SECKEYPQGParams *PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey *privKey);
-/* deprecated */
-SECKEYPrivateKeyList* PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot);
-
-PK11SymKey *PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk,
- void *wincx);
-SECKEYPrivateKey *PK11_ConvertSessionPrivKeyToTokenPrivKey(
- SECKEYPrivateKey *privk, void* wincx);
-SECKEYPrivateKey * PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo *destSlot,
- SECKEYPrivateKey *privKey);
-
-/**********************************************************************
- * Certs
- **********************************************************************/
-SECItem *PK11_MakeIDFromPubKey(SECItem *pubKeyData);
-SECStatus PK11_TraverseSlotCerts(
- SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
- void *arg, void *wincx);
-CERTCertificate * PK11_FindCertFromNickname(const char *nickname, void *wincx);
-CERTCertList * PK11_FindCertsFromEmailAddress(const char *email, void *wincx);
-CERTCertList * PK11_FindCertsFromNickname(const char *nickname, void *wincx);
-CERTCertificate *PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey);
-SECStatus PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
- CK_OBJECT_HANDLE key, const char *nickname,
- PRBool includeTrust);
-SECStatus PK11_ImportDERCert(PK11SlotInfo *slot, SECItem *derCert,
- CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust);
-PK11SlotInfo *PK11_ImportCertForKey(CERTCertificate *cert,
- const char *nickname, void *wincx);
-PK11SlotInfo *PK11_ImportDERCertForKey(SECItem *derCert, char *nickname,
- void *wincx);
-PK11SlotInfo *PK11_KeyForCertExists(CERTCertificate *cert,
- CK_OBJECT_HANDLE *keyPtr, void *wincx);
-PK11SlotInfo *PK11_KeyForDERCertExists(SECItem *derCert,
- CK_OBJECT_HANDLE *keyPtr, void *wincx);
-CERTCertificate * PK11_FindCertByIssuerAndSN(PK11SlotInfo **slot,
- CERTIssuerAndSN *sn, void *wincx);
-CERTCertificate * PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slot,
- SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip,
- SECKEYPrivateKey**privKey, void *wincx);
-int PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist,
- void *wincx);
-SECStatus PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert,
- PK11SlotInfo *slot, SECStatus(*callback)(CERTCertificate *, void *),
- void *arg);
-CERTCertificate *PK11_FindCertFromDERCert(PK11SlotInfo *slot,
- CERTCertificate *cert, void *wincx);
-CERTCertificate *PK11_FindCertFromDERCertItem(PK11SlotInfo *slot,
- const SECItem *derCert, void *wincx);
-SECStatus PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
- char *nickname, PRBool addUsage,
- void *wincx);
-CERTCertificate *PK11_FindBestKEAMatch(CERTCertificate *serverCert,void *wincx);
-PRBool PK11_FortezzaHasKEA(CERTCertificate *cert);
-CK_OBJECT_HANDLE PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert,
- void *wincx);
-SECStatus PK11_TraverseCertsForNicknameInSlot(SECItem *nickname,
- PK11SlotInfo *slot, SECStatus(*callback)(CERTCertificate *, void *),
- void *arg);
-CERTCertList * PK11_ListCerts(PK11CertListType type, void *pwarg);
-CERTCertList * PK11_ListCertsInSlot(PK11SlotInfo *slot);
-CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url,
- int type, void *wincx, PRInt32 importOptions, PLArenaPool* arena, PRInt32 decodeOptions);
-
-/**********************************************************************
- * Sign/Verify
- **********************************************************************/
-
-/*
- * Return the length in bytes of a signature generated with the
- * private key.
- *
- * Return 0 or -1 on failure. (XXX Should we fix it to always return
- * -1 on failure?)
- */
-int PK11_SignatureLen(SECKEYPrivateKey *key);
-PK11SlotInfo * PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key);
-SECStatus PK11_Sign(SECKEYPrivateKey *key, SECItem *sig,
- const SECItem *hash);
-SECStatus PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism,
- SECItem *param, SECItem *sig, const SECItem *data);
-SECStatus PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig,
- SECItem *dsig, void * wincx);
-SECStatus PK11_Verify(SECKEYPublicKey *key, const SECItem *sig,
- const SECItem *hash, void *wincx);
-
-
-
-/**********************************************************************
- * Crypto Contexts
- **********************************************************************/
-void PK11_DestroyContext(PK11Context *context, PRBool freeit);
-PK11Context *PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type,
- CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey, SECItem *param);
-PK11Context *PK11_CreateDigestContext(SECOidTag hashAlg);
-PK11Context *PK11_CloneContext(PK11Context *old);
-SECStatus PK11_DigestBegin(PK11Context *cx);
-/*
- * The output buffer 'out' must be big enough to hold the output of
- * the hash algorithm 'hashAlg'.
- */
-SECStatus PK11_HashBuf(SECOidTag hashAlg, unsigned char *out,
- const unsigned char *in, PRInt32 len);
-SECStatus PK11_DigestOp(PK11Context *context, const unsigned char *in,
- unsigned len);
-SECStatus PK11_CipherOp(PK11Context *context, unsigned char * out, int *outlen,
- int maxout, const unsigned char *in, int inlen);
-SECStatus PK11_Finalize(PK11Context *context);
-SECStatus PK11_DigestFinal(PK11Context *context, unsigned char *data,
- unsigned int *outLen, unsigned int length);
-SECStatus PK11_SaveContext(PK11Context *cx,unsigned char *save,
- int *len, int saveLength);
-
-/* Save the context's state, with possible allocation.
- * The caller may supply an already allocated buffer in preAllocBuf,
- * with length pabLen. If the buffer is large enough for the context's
- * state, it will receive the state.
- * If the buffer is not large enough (or NULL), then a new buffer will
- * be allocated with PORT_Alloc.
- * In either case, the state will be returned as a buffer, and the length
- * of the state will be given in *stateLen.
- */
-unsigned char *
-PK11_SaveContextAlloc(PK11Context *cx,
- unsigned char *preAllocBuf, unsigned int pabLen,
- unsigned int *stateLen);
-
-SECStatus PK11_RestoreContext(PK11Context *cx,unsigned char *save,int len);
-SECStatus PK11_GenerateFortezzaIV(PK11SymKey *symKey,unsigned char *iv,int len);
-void PK11_SetFortezzaHack(PK11SymKey *symKey) ;
-
-
-/**********************************************************************
- * PBE functions
- **********************************************************************/
-
-/* This function creates PBE parameters from the given inputs. The result
- * can be used to create a password integrity key for PKCS#12, by sending
- * the return value to PK11_KeyGen along with the appropriate mechanism.
- */
-SECItem *
-PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations);
-
-/* free params created above (can be called after keygen is done */
-void PK11_DestroyPBEParams(SECItem *params);
-
-SECAlgorithmID *
-PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt);
-
-/* use to create PKCS5 V2 algorithms with finder control than that provided
- * by PK11_CreatePBEAlgorithmID. */
-SECAlgorithmID *
-PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag, SECOidTag cipherAlgTag,
- SECOidTag prfAlgTag, int keyLength, int iteration,
- SECItem *salt);
-PK11SymKey *
-PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
- PRBool faulty3DES, void *wincx);
-
-/* warning: cannot work with PKCS 5 v2 use PK11_PBEKeyGen instead */
-PK11SymKey *
-PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *params,
- SECItem *pwitem, PRBool faulty3DES, void *wincx);
-SECItem *
-PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem);
-/*
- * Get the Mechanism and parameter of the base encryption or mac scheme from
- * a PBE algorithm ID.
- * Caller is responsible for freeing the return parameter (param).
- */
-CK_MECHANISM_TYPE
-PK11_GetPBECryptoMechanism(SECAlgorithmID *algid,
- SECItem **param, SECItem *pwd);
-
-/**********************************************************************
- * Functions to manage secmod flags
- **********************************************************************/
-PK11DefaultArrayEntry * PK11_GetDefaultArray(int *);
-SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *, PK11DefaultArrayEntry *,
- PRBool );
-
-/**********************************************************************
- * Functions to look at PKCS #11 dependent data
- **********************************************************************/
-PK11GenericObject *PK11_FindGenericObjects(PK11SlotInfo *slot,
- CK_OBJECT_CLASS objClass);
-PK11GenericObject *PK11_GetNextGenericObject(PK11GenericObject *object);
-PK11GenericObject *PK11_GetPrevGenericObject(PK11GenericObject *object);
-SECStatus PK11_UnlinkGenericObject(PK11GenericObject *object);
-SECStatus PK11_LinkGenericObject(PK11GenericObject *list,
- PK11GenericObject *object);
-SECStatus PK11_DestroyGenericObjects(PK11GenericObject *object);
-SECStatus PK11_DestroyGenericObject(PK11GenericObject *object);
-PK11GenericObject *PK11_CreateGenericObject(PK11SlotInfo *slot,
- const CK_ATTRIBUTE *pTemplate,
- int count, PRBool token);
-
-/*
- * PK11_ReadRawAttribute and PK11_WriteRawAttribute are generic
- * functions to read and modify the actual PKCS #11 attributes of
- * the underlying pkcs #11 object.
- *
- * object is a pointer to an NSS object that represents the underlying
- * PKCS #11 object. It's type must match the type of PK11ObjectType
- * as follows:
- *
- * type object
- * PK11_TypeGeneric PK11GenericObject *
- * PK11_TypePrivKey SECKEYPrivateKey *
- * PK11_TypePubKey SECKEYPublicKey *
- * PK11_TypeSymKey PK11SymKey *
- *
- * All other types are considered invalid. If type does not match the object
- * passed, unpredictable results will occur.
- *
- * PK11_ReadRawAttribute allocates the buffer for returning the attribute
- * value. The caller of PK11_ReadRawAttribute should free the data buffer
- * pointed to by item using a SECITEM_FreeItem(item, PR_FALSE) or
- * PORT_Free(item->data) call.
- */
-SECStatus PK11_ReadRawAttribute(PK11ObjectType type, void *object,
- CK_ATTRIBUTE_TYPE attr, SECItem *item);
-SECStatus PK11_WriteRawAttribute(PK11ObjectType type, void *object,
- CK_ATTRIBUTE_TYPE attr, SECItem *item);
-
-/*
- * PK11_GetAllSlotsForCert returns all the slots that a given certificate
- * exists on, since it's possible for a cert to exist on more than one
- * PKCS#11 token.
- */
-PK11SlotList *
-PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg);
-
-/**********************************************************************
- * New functions which are already deprecated....
- **********************************************************************/
-SECItem *
-PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
- CERTCertificate *cert, void *pwarg);
-SECItem *
-PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *key);
-
-PRBool SECMOD_HasRootCerts(void);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/pk11wrap/pk11sdr.c b/security/nss/lib/pk11wrap/pk11sdr.c
deleted file mode 100644
index 43030b6d8..000000000
--- a/security/nss/lib/pk11wrap/pk11sdr.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "seccomon.h"
-#include "secoid.h"
-#include "secasn1.h"
-#include "pkcs11.h"
-#include "pk11func.h"
-#include "pk11sdr.h"
-
-/*
- * Data structure and template for encoding the result of an SDR operation
- * This is temporary. It should include the algorithm ID of the encryption mechanism
- */
-struct SDRResult
-{
- SECItem keyid;
- SECAlgorithmID alg;
- SECItem data;
-};
-typedef struct SDRResult SDRResult;
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-static SEC_ASN1Template template[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (SDRResult) },
- { SEC_ASN1_OCTET_STRING, offsetof(SDRResult, keyid) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(SDRResult, alg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING, offsetof(SDRResult, data) },
- { 0 }
-};
-
-static unsigned char keyID[] = {
- 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
-};
-
-static SECItem keyIDItem = {
- 0,
- keyID,
- sizeof keyID
-};
-
-/* local utility function for padding an incoming data block
- * to the mechanism block size.
- */
-static SECStatus
-padBlock(SECItem *data, int blockSize, SECItem *result)
-{
- SECStatus rv = SECSuccess;
- int padLength;
- unsigned int i;
-
- result->data = 0;
- result->len = 0;
-
- /* This algorithm always adds to the block (to indicate the number
- * of pad bytes). So allocate a block large enough.
- */
- padLength = blockSize - (data->len % blockSize);
- result->len = data->len + padLength;
- result->data = (unsigned char *)PORT_Alloc(result->len);
-
- /* Copy the data */
- PORT_Memcpy(result->data, data->data, data->len);
-
- /* Add the pad values */
- for(i = data->len; i < result->len; i++)
- result->data[i] = (unsigned char)padLength;
-
- return rv;
-}
-
-static SECStatus
-unpadBlock(SECItem *data, int blockSize, SECItem *result)
-{
- SECStatus rv = SECSuccess;
- int padLength;
- unsigned int i;
-
- result->data = 0;
- result->len = 0;
-
- /* Remove the padding from the end if the input data */
- if (data->len == 0 || data->len % blockSize != 0) { rv = SECFailure; goto loser; }
-
- padLength = data->data[data->len-1];
- if (padLength > blockSize) { rv = SECFailure; goto loser; }
-
- /* verify padding */
- for (i=data->len - padLength; i < data->len; i++) {
- if (data->data[i] != padLength) {
- rv = SECFailure;
- goto loser;
- }
- }
-
- result->len = data->len - padLength;
- result->data = (unsigned char *)PORT_Alloc(result->len);
- if (!result->data) { rv = SECFailure; goto loser; }
-
- PORT_Memcpy(result->data, data->data, result->len);
-
- if (padLength < 2) {
- return SECWouldBlock;
- }
-
-loser:
- return rv;
-}
-
-static PRLock *pk11sdrLock = NULL;
-
-void
-pk11sdr_Init (void)
-{
- pk11sdrLock = PR_NewLock();
-}
-
-void
-pk11sdr_Shutdown(void)
-{
- if (pk11sdrLock) {
- PR_DestroyLock(pk11sdrLock);
- pk11sdrLock = NULL;
- }
-}
-
-/*
- * PK11SDR_Encrypt
- * Encrypt a block of data using the symmetric key identified. The result
- * is an ASN.1 (DER) encoded block of keyid, params and data.
- */
-SECStatus
-PK11SDR_Encrypt(SECItem *keyid, SECItem *data, SECItem *result, void *cx)
-{
- SECStatus rv = SECSuccess;
- PK11SlotInfo *slot = 0;
- PK11SymKey *key = 0;
- SECItem *params = 0;
- PK11Context *ctx = 0;
- CK_MECHANISM_TYPE type;
- SDRResult sdrResult;
- SECItem paddedData;
- SECItem *pKeyID;
- PLArenaPool *arena = 0;
-
- /* Initialize */
- paddedData.len = 0;
- paddedData.data = 0;
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (!arena) { rv = SECFailure; goto loser; }
-
- /* 1. Locate the requested keyid, or the default key (which has a keyid)
- * 2. Create an encryption context
- * 3. Encrypt
- * 4. Encode the results (using ASN.1)
- */
-
- slot = PK11_GetInternalKeySlot();
- if (!slot) { rv = SECFailure; goto loser; }
-
- /* Use triple-DES */
- type = CKM_DES3_CBC;
-
- /*
- * Login to the internal token before we look for the key, otherwise we
- * won't find it.
- */
- rv = PK11_Authenticate(slot, PR_TRUE, cx);
- if (rv != SECSuccess) goto loser;
-
- /* Find the key to use */
- pKeyID = keyid;
- if (pKeyID->len == 0) {
- pKeyID = &keyIDItem; /* Use default value */
-
- /* put in a course lock to prevent a race between not finding the
- * key and creating one.
- */
-
- if (pk11sdrLock) PR_Lock(pk11sdrLock);
-
- /* Try to find the key */
- key = PK11_FindFixedKey(slot, type, pKeyID, cx);
-
- /* If the default key doesn't exist yet, try to create it */
- if (!key) key = PK11_GenDES3TokenKey(slot, pKeyID, cx);
- if (pk11sdrLock) PR_Unlock(pk11sdrLock);
- } else {
- key = PK11_FindFixedKey(slot, type, pKeyID, cx);
- }
-
- if (!key) { rv = SECFailure; goto loser; }
-
- params = PK11_GenerateNewParam(type, key);
- if (!params) { rv = SECFailure; goto loser; }
-
- ctx = PK11_CreateContextBySymKey(type, CKA_ENCRYPT, key, params);
- if (!ctx) { rv = SECFailure; goto loser; }
-
- rv = padBlock(data, PK11_GetBlockSize(type, 0), &paddedData);
- if (rv != SECSuccess) goto loser;
-
- sdrResult.data.len = paddedData.len;
- sdrResult.data.data = (unsigned char *)PORT_ArenaAlloc(arena, sdrResult.data.len);
-
- rv = PK11_CipherOp(ctx, sdrResult.data.data, (int*)&sdrResult.data.len, sdrResult.data.len,
- paddedData.data, paddedData.len);
- if (rv != SECSuccess) goto loser;
-
- PK11_Finalize(ctx);
-
- sdrResult.keyid = *pKeyID;
-
- rv = PK11_ParamToAlgid(SEC_OID_DES_EDE3_CBC, params, arena, &sdrResult.alg);
- if (rv != SECSuccess) goto loser;
-
- if (!SEC_ASN1EncodeItem(0, result, &sdrResult, template)) { rv = SECFailure; goto loser; }
-
-loser:
- SECITEM_ZfreeItem(&paddedData, PR_FALSE);
- if (arena) PORT_FreeArena(arena, PR_TRUE);
- if (ctx) PK11_DestroyContext(ctx, PR_TRUE);
- if (params) SECITEM_ZfreeItem(params, PR_TRUE);
- if (key) PK11_FreeSymKey(key);
- if (slot) PK11_FreeSlot(slot);
-
- return rv;
-}
-
-/* decrypt a block */
-static SECStatus
-pk11Decrypt(PK11SlotInfo *slot, PLArenaPool *arena,
- CK_MECHANISM_TYPE type, PK11SymKey *key,
- SECItem *params, SECItem *in, SECItem *result)
-{
- PK11Context *ctx = 0;
- SECItem paddedResult;
- SECStatus rv;
-
- paddedResult.len = 0;
- paddedResult.data = 0;
-
- ctx = PK11_CreateContextBySymKey(type, CKA_DECRYPT, key, params);
- if (!ctx) { rv = SECFailure; goto loser; }
-
- paddedResult.len = in->len;
- paddedResult.data = PORT_ArenaAlloc(arena, paddedResult.len);
-
- rv = PK11_CipherOp(ctx, paddedResult.data,
- (int*)&paddedResult.len, paddedResult.len,
- in->data, in->len);
- if (rv != SECSuccess) goto loser;
-
- PK11_Finalize(ctx);
-
- /* Remove the padding */
- rv = unpadBlock(&paddedResult, PK11_GetBlockSize(type, 0), result);
- if (rv) goto loser;
-
-loser:
- if (ctx) PK11_DestroyContext(ctx, PR_TRUE);
- return rv;
-}
-
-/*
- * PK11SDR_Decrypt
- * Decrypt a block of data produced by PK11SDR_Encrypt. The key used is identified
- * by the keyid field within the input.
- */
-SECStatus
-PK11SDR_Decrypt(SECItem *data, SECItem *result, void *cx)
-{
- SECStatus rv = SECSuccess;
- PK11SlotInfo *slot = 0;
- PK11SymKey *key = 0;
- CK_MECHANISM_TYPE type;
- SDRResult sdrResult;
- SECItem *params = 0;
- SECItem possibleResult = { 0, NULL, 0 };
- PLArenaPool *arena = 0;
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (!arena) { rv = SECFailure; goto loser; }
-
- /* Decode the incoming data */
- memset(&sdrResult, 0, sizeof sdrResult);
- rv = SEC_QuickDERDecodeItem(arena, &sdrResult, template, data);
- if (rv != SECSuccess) goto loser; /* Invalid format */
-
- /* Find the slot and key for the given keyid */
- slot = PK11_GetInternalKeySlot();
- if (!slot) { rv = SECFailure; goto loser; }
-
- rv = PK11_Authenticate(slot, PR_TRUE, cx);
- if (rv != SECSuccess) goto loser;
-
- /* Get the parameter values from the data */
- params = PK11_ParamFromAlgid(&sdrResult.alg);
- if (!params) { rv = SECFailure; goto loser; }
-
- /* Use triple-DES (Should look up the algorithm) */
- type = CKM_DES3_CBC;
- key = PK11_FindFixedKey(slot, type, &sdrResult.keyid, cx);
- if (!key) {
- rv = SECFailure;
- } else {
- rv = pk11Decrypt(slot, arena, type, key, params,
- &sdrResult.data, result);
- }
-
- /*
- * if the pad value was too small (1 or 2), then it's statistically
- * 'likely' that (1 in 256) that we may not have the correct key.
- * Check the other keys for a better match. If we find none, use
- * this result.
- */
- if (rv == SECWouldBlock) {
- possibleResult = *result;
- }
-
- /*
- * handle the case where your key indicies may have been broken
- */
- if (rv != SECSuccess) {
- PK11SymKey *keyList = PK11_ListFixedKeysInSlot(slot, NULL, cx);
- PK11SymKey *testKey = NULL;
- PK11SymKey *nextKey = NULL;
-
- for (testKey = keyList; testKey;
- testKey = PK11_GetNextSymKey(testKey)) {
- rv = pk11Decrypt(slot, arena, type, testKey, params,
- &sdrResult.data, result);
- if (rv == SECSuccess) {
- break;
- }
- /* found a close match. If it's our first remember it */
- if (rv == SECWouldBlock) {
- if (possibleResult.data) {
- /* this is unlikely but possible. If we hit this condition,
- * we have no way of knowing which possibility to prefer.
- * in this case we just match the key the application
- * thought was the right one */
- SECITEM_ZfreeItem(result, PR_FALSE);
- } else {
- possibleResult = *result;
- }
- }
- }
-
- /* free the list */
- for (testKey = keyList; testKey; testKey = nextKey) {
- nextKey = PK11_GetNextSymKey(testKey);
- PK11_FreeSymKey(testKey);
- }
- }
-
- /* we didn't find a better key, use the one with a small pad value */
- if ((rv != SECSuccess) && (possibleResult.data)) {
- *result = possibleResult;
- possibleResult.data = NULL;
- rv = SECSuccess;
- }
-
-loser:
- if (arena) PORT_FreeArena(arena, PR_TRUE);
- if (key) PK11_FreeSymKey(key);
- if (params) SECITEM_ZfreeItem(params, PR_TRUE);
- if (slot) PK11_FreeSlot(slot);
- if (possibleResult.data) SECITEM_ZfreeItem(&possibleResult, PR_FALSE);
-
- return rv;
-}
diff --git a/security/nss/lib/pk11wrap/pk11sdr.h b/security/nss/lib/pk11wrap/pk11sdr.h
deleted file mode 100644
index 0ffa42534..000000000
--- a/security/nss/lib/pk11wrap/pk11sdr.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _PK11SDR_H_
-#define _PK11SDR_H_
-
-#include "seccomon.h"
-
-SEC_BEGIN_PROTOS
-
-/*
- * PK11SDR_Encrypt - encrypt data using the specified key id or SDR default
- * result should be freed with SECItem_ZfreeItem
- */
-SECStatus
-PK11SDR_Encrypt(SECItem *keyid, SECItem *data, SECItem *result, void *cx);
-
-/*
- * PK11SDR_Decrypt - decrypt data previously encrypted with PK11SDR_Encrypt
- * result should be freed with SECItem_ZfreeItem
- */
-SECStatus
-PK11SDR_Decrypt(SECItem *data, SECItem *result, void *cx);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
deleted file mode 100644
index 4e26e44ac..000000000
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ /dev/null
@@ -1,2668 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file implements the Symkey wrapper and the PKCS context
- * Interfaces.
- */
-
-#include "seccomon.h"
-#include "secmod.h"
-#include "nssilock.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11.h"
-#include "pk11func.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "secerr.h"
-#include "hasht.h"
-
-static void
-pk11_EnterKeyMonitor(PK11SymKey *symKey) {
- if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe))
- PK11_EnterSlotMonitor(symKey->slot);
-}
-
-static void
-pk11_ExitKeyMonitor(PK11SymKey *symKey) {
- if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe))
- PK11_ExitSlotMonitor(symKey->slot);
-}
-
-/*
- * pk11_getKeyFromList returns a symKey that has a session (if needSession
- * was specified), or explicitly does not have a session (if needSession
- * was not specified).
- */
-static PK11SymKey *
-pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession) {
- PK11SymKey *symKey = NULL;
-
- PZ_Lock(slot->freeListLock);
- /* own session list are symkeys with sessions that the symkey owns.
- * 'most' symkeys will own their own session. */
- if (needSession) {
- if (slot->freeSymKeysWithSessionHead) {
- symKey = slot->freeSymKeysWithSessionHead;
- slot->freeSymKeysWithSessionHead = symKey->next;
- slot->keyCount--;
- }
- }
- /* if we don't need a symkey with its own session, or we couldn't find
- * one on the owner list, get one from the non-owner free list. */
- if (!symKey) {
- if (slot->freeSymKeysHead) {
- symKey = slot->freeSymKeysHead;
- slot->freeSymKeysHead = symKey->next;
- slot->keyCount--;
- }
- }
- PZ_Unlock(slot->freeListLock);
- if (symKey) {
- symKey->next = NULL;
- if (!needSession) {
- return symKey;
- }
- /* if we are getting an owner key, make sure we have a valid session.
- * session could be invalid if the token has been removed or because
- * we got it from the non-owner free list */
- if ((symKey->series != slot->series) ||
- (symKey->session == CK_INVALID_SESSION)) {
- symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner);
- }
- PORT_Assert(symKey->session != CK_INVALID_SESSION);
- if (symKey->session != CK_INVALID_SESSION)
- return symKey;
- PK11_FreeSymKey(symKey);
- /* if we are here, we need a session, but couldn't get one, it's
- * unlikely we pk11_GetNewSession will succeed if we call it a second
- * time. */
- return NULL;
- }
-
- symKey = PORT_New(PK11SymKey);
- if (symKey == NULL) {
- return NULL;
- }
-
- symKey->next = NULL;
- if (needSession) {
- symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner);
- PORT_Assert(symKey->session != CK_INVALID_SESSION);
- if (symKey->session == CK_INVALID_SESSION) {
- PK11_FreeSymKey(symKey);
- symKey = NULL;
- }
- } else {
- symKey->session = CK_INVALID_SESSION;
- }
- return symKey;
-}
-
-/* Caller MUST hold slot->freeListLock (or ref count == 0?) !! */
-void
-PK11_CleanKeyList(PK11SlotInfo *slot)
-{
- PK11SymKey *symKey = NULL;
-
- while (slot->freeSymKeysWithSessionHead) {
- symKey = slot->freeSymKeysWithSessionHead;
- slot->freeSymKeysWithSessionHead = symKey->next;
- pk11_CloseSession(slot, symKey->session, symKey->sessionOwner);
- PORT_Free(symKey);
- }
- while (slot->freeSymKeysHead) {
- symKey = slot->freeSymKeysHead;
- slot->freeSymKeysHead = symKey->next;
- pk11_CloseSession(slot, symKey->session, symKey->sessionOwner);
- PORT_Free(symKey);
- }
- return;
-}
-
-/*
- * create a symetric key:
- * Slot is the slot to create the key in.
- * type is the mechanism type
- * owner is does this symKey structure own it's object handle (rare
- * that this is false).
- * needSession means the returned symKey will return with a valid session
- * allocated already.
- */
-static PK11SymKey *
-pk11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- PRBool owner, PRBool needSession, void *wincx)
-{
-
- PK11SymKey *symKey = pk11_getKeyFromList(slot, needSession);
-
- if (symKey == NULL) {
- return NULL;
- }
- /* if needSession was specified, make sure we have a valid session.
- * callers which specify needSession as false should do their own
- * check of the session before returning the symKey */
- if (needSession && symKey->session == CK_INVALID_SESSION) {
- PK11_FreeSymKey(symKey);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
-
- symKey->type = type;
- symKey->data.type = siBuffer;
- symKey->data.data = NULL;
- symKey->data.len = 0;
- symKey->owner = owner;
- symKey->objectID = CK_INVALID_HANDLE;
- symKey->slot = slot;
- symKey->series = slot->series;
- symKey->cx = wincx;
- symKey->size = 0;
- symKey->refCount = 1;
- symKey->origin = PK11_OriginNULL;
- symKey->parent = NULL;
- symKey->freeFunc = NULL;
- symKey->userData = NULL;
- PK11_ReferenceSlot(slot);
- return symKey;
-}
-
-/*
- * destroy a symetric key
- */
-void
-PK11_FreeSymKey(PK11SymKey *symKey)
-{
- PK11SlotInfo *slot;
- PRBool freeit = PR_TRUE;
-
- if (PR_ATOMIC_DECREMENT(&symKey->refCount) == 0) {
- PK11SymKey *parent = symKey->parent;
-
- symKey->parent = NULL;
- if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) {
- pk11_EnterKeyMonitor(symKey);
- (void) PK11_GETTAB(symKey->slot)->
- C_DestroyObject(symKey->session, symKey->objectID);
- pk11_ExitKeyMonitor(symKey);
- }
- if (symKey->data.data) {
- PORT_Memset(symKey->data.data, 0, symKey->data.len);
- PORT_Free(symKey->data.data);
- }
- /* free any existing data */
- if (symKey->userData && symKey->freeFunc) {
- (*symKey->freeFunc)(symKey->userData);
- }
- slot = symKey->slot;
- PZ_Lock(slot->freeListLock);
- if (slot->keyCount < slot->maxKeyCount) {
- /*
- * freeSymkeysWithSessionHead contain a list of reusable
- * SymKey structures with valid sessions.
- * sessionOwner must be true.
- * session must be valid.
- * freeSymKeysHead contain a list of SymKey structures without
- * valid session.
- * session must be CK_INVALID_SESSION.
- * though sessionOwner is false, callers should not depend on
- * this fact.
- */
- if (symKey->sessionOwner) {
- PORT_Assert (symKey->session != CK_INVALID_SESSION);
- symKey->next = slot->freeSymKeysWithSessionHead;
- slot->freeSymKeysWithSessionHead = symKey;
- } else {
- symKey->session = CK_INVALID_SESSION;
- symKey->next = slot->freeSymKeysHead;
- slot->freeSymKeysHead = symKey;
- }
- slot->keyCount++;
- symKey->slot = NULL;
- freeit = PR_FALSE;
- }
- PZ_Unlock(slot->freeListLock);
- if (freeit) {
- pk11_CloseSession(symKey->slot, symKey->session,
- symKey->sessionOwner);
- PORT_Free(symKey);
- }
- PK11_FreeSlot(slot);
-
- if (parent) {
- PK11_FreeSymKey(parent);
- }
- }
-}
-
-PK11SymKey *
-PK11_ReferenceSymKey(PK11SymKey *symKey)
-{
- PR_ATOMIC_INCREMENT(&symKey->refCount);
- return symKey;
-}
-
-/*
- * Accessors
- */
-CK_MECHANISM_TYPE
-PK11_GetMechanism(PK11SymKey *symKey)
-{
- return symKey->type;
-}
-
-/*
- * return the slot associated with a symetric key
- */
-PK11SlotInfo *
-PK11_GetSlotFromKey(PK11SymKey *symKey)
-{
- return PK11_ReferenceSlot(symKey->slot);
-}
-
-CK_KEY_TYPE PK11_GetSymKeyType(PK11SymKey *symKey)
-{
- return PK11_GetKeyType(symKey->type,symKey->size);
-}
-
-PK11SymKey *
-PK11_GetNextSymKey(PK11SymKey *symKey)
-{
- return symKey ? symKey->next : NULL;
-}
-
-char *
-PK11_GetSymKeyNickname(PK11SymKey *symKey)
-{
- return PK11_GetObjectNickname(symKey->slot,symKey->objectID);
-}
-
-SECStatus
-PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname)
-{
- return PK11_SetObjectNickname(symKey->slot,symKey->objectID,nickname);
-}
-
-void *
-PK11_GetSymKeyUserData(PK11SymKey *symKey)
-{
- return symKey->userData;
-}
-
-void
-PK11_SetSymKeyUserData(PK11SymKey *symKey, void *userData,
- PK11FreeDataFunc freeFunc)
-{
- /* free any existing data */
- if (symKey->userData && symKey->freeFunc) {
- (*symKey->freeFunc)(symKey->userData);
- }
- symKey->userData = userData;
- symKey->freeFunc = freeFunc;
- return;
-}
-
-/*
- * turn key handle into an appropriate key object
- */
-PK11SymKey *
-PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
- CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID, PRBool owner, void *wincx)
-{
- PK11SymKey *symKey;
- PRBool needSession = !(owner && parent);
-
- if (keyID == CK_INVALID_HANDLE) {
- return NULL;
- }
-
- symKey = pk11_CreateSymKey(slot, type, owner, needSession, wincx);
- if (symKey == NULL) {
- return NULL;
- }
-
- symKey->objectID = keyID;
- symKey->origin = origin;
-
- /* adopt the parent's session */
- /* This is only used by SSL. What we really want here is a session
- * structure with a ref count so the session goes away only after all the
- * keys do. */
- if (!needSession) {
- symKey->sessionOwner = PR_FALSE;
- symKey->session = parent->session;
- symKey->parent = PK11_ReferenceSymKey(parent);
- /* This is the only case where pk11_CreateSymKey does not explicitly
- * check symKey->session. We need to assert here to make sure.
- * the session isn't invalid. */
- PORT_Assert(parent->session != CK_INVALID_SESSION);
- if (parent->session == CK_INVALID_SESSION) {
- PK11_FreeSymKey(symKey);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
- }
-
- return symKey;
-}
-
-/*
- * turn key handle into an appropriate key object
- */
-PK11SymKey *
-PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
- int series, void *wincx)
-{
- PK11SymKey *symKey = NULL;
-
- if (slot->series != series) return NULL;
- if (slot->refKeys[wrap] == CK_INVALID_HANDLE) return NULL;
- if (type == CKM_INVALID_MECHANISM) type = slot->wrapMechanism;
-
- symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
- slot->wrapMechanism, slot->refKeys[wrap], PR_FALSE, wincx);
- return symKey;
-}
-
-/*
- * This function is not thread-safe because it sets wrapKey->sessionOwner
- * without using a lock or atomic routine. It can only be called when
- * only one thread has a reference to wrapKey.
- */
-void
-PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey)
-{
- /* save the handle and mechanism for the wrapping key */
- /* mark the key and session as not owned by us to they don't get freed
- * when the key goes way... that lets us reuse the key later */
- slot->refKeys[wrap] = wrapKey->objectID;
- wrapKey->owner = PR_FALSE;
- wrapKey->sessionOwner = PR_FALSE;
- slot->wrapMechanism = wrapKey->type;
-}
-
-
-/*
- * figure out if a key is still valid or if it is stale.
- */
-PRBool
-PK11_VerifyKeyOK(PK11SymKey *key) {
- if (!PK11_IsPresent(key->slot)) {
- return PR_FALSE;
- }
- return (PRBool)(key->series == key->slot->series);
-}
-
-static PK11SymKey *
-pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- PK11Origin origin, PRBool isToken, CK_ATTRIBUTE *keyTemplate,
- unsigned int templateCount, SECItem *key, void *wincx)
-{
- PK11SymKey * symKey;
- SECStatus rv;
-
- symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
- if (symKey == NULL) {
- return NULL;
- }
-
- symKey->size = key->len;
-
- PK11_SETATTRS(&keyTemplate[templateCount], CKA_VALUE, key->data, key->len);
- templateCount++;
-
- if (SECITEM_CopyItem(NULL,&symKey->data,key) != SECSuccess) {
- PK11_FreeSymKey(symKey);
- return NULL;
- }
-
- symKey->origin = origin;
-
- /* import the keys */
- rv = PK11_CreateNewObject(slot, symKey->session, keyTemplate,
- templateCount, isToken, &symKey->objectID);
- if ( rv != SECSuccess) {
- PK11_FreeSymKey(symKey);
- return NULL;
- }
-
- return symKey;
-}
-
-/*
- * turn key bits into an appropriate key object
- */
-PK11SymKey *
-PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,void *wincx)
-{
- PK11SymKey * symKey;
- unsigned int templateCount = 0;
- CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_BBOOL cktrue = CK_TRUE; /* sigh */
- CK_ATTRIBUTE keyTemplate[5];
- CK_ATTRIBUTE * attrs = keyTemplate;
-
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;
- PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++;
- templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
-
- keyType = PK11_GetKeyType(type,key->len);
- symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, PR_FALSE,
- keyTemplate, templateCount, key, wincx);
- return symKey;
-}
-
-
-/*
- * turn key bits into an appropriate key object
- */
-PK11SymKey *
-PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,
- CK_FLAGS flags, PRBool isPerm, void *wincx)
-{
- PK11SymKey * symKey;
- unsigned int templateCount = 0;
- CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_BBOOL cktrue = CK_TRUE; /* sigh */
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
- CK_ATTRIBUTE * attrs = keyTemplate;
-
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;
- if (isPerm) {
- PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue) ); attrs++;
- /* sigh some tokens think CKA_PRIVATE = false is a reasonable
- * default for secret keys */
- PK11_SETATTRS(attrs, CKA_PRIVATE, &cktrue, sizeof(cktrue) ); attrs++;
- }
- attrs += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
- if ((operation != CKA_FLAGS_ONLY) &&
- !pk11_FindAttrInTemplate(keyTemplate, attrs-keyTemplate, operation)) {
- PK11_SETATTRS(attrs, operation, &cktrue, sizeof(cktrue)); attrs++;
- }
- templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
-
- keyType = PK11_GetKeyType(type,key->len);
- symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, isPerm,
- keyTemplate, templateCount, key, wincx);
- if (symKey && isPerm) {
- symKey->owner = PR_FALSE;
- }
- return symKey;
-}
-
-
-PK11SymKey *
-PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,
- void *wincx)
-{
- CK_ATTRIBUTE findTemp[4];
- CK_ATTRIBUTE *attrs;
- CK_BBOOL ckTrue = CK_TRUE;
- CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;
- int tsize = 0;
- CK_OBJECT_HANDLE key_id;
-
- attrs = findTemp;
- PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
- if (keyID) {
- PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len); attrs++;
- }
- tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
-
- key_id = pk11_FindObjectByTemplate(slot,findTemp,tsize);
- if (key_id == CK_INVALID_HANDLE) {
- return NULL;
- }
- return PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, type, key_id,
- PR_FALSE, wincx);
-}
-
-PK11SymKey *
-PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
-{
- CK_ATTRIBUTE findTemp[4];
- CK_ATTRIBUTE *attrs;
- CK_BBOOL ckTrue = CK_TRUE;
- CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;
- int tsize = 0;
- int objCount = 0;
- CK_OBJECT_HANDLE *key_ids;
- PK11SymKey *nextKey = NULL;
- PK11SymKey *topKey = NULL;
- int i,len;
-
- attrs = findTemp;
- PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
- PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
- if (nickname) {
- len = PORT_Strlen(nickname);
- PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++;
- }
- tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
-
- key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount);
- if (key_ids == NULL) {
- return NULL;
- }
-
- for (i=0; i < objCount ; i++) {
- SECItem typeData;
- CK_KEY_TYPE type = CKK_GENERIC_SECRET;
- SECStatus rv = PK11_ReadAttribute(slot, key_ids[i],
- CKA_KEY_TYPE, NULL, &typeData);
- if (rv == SECSuccess) {
- if (typeData.len == sizeof(CK_KEY_TYPE)) {
- type = *(CK_KEY_TYPE *)typeData.data;
- }
- PORT_Free(typeData.data);
- }
- nextKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
- PK11_GetKeyMechanism(type), key_ids[i], PR_FALSE, wincx);
- if (nextKey) {
- nextKey->next = topKey;
- topKey = nextKey;
- }
- }
- PORT_Free(key_ids);
- return topKey;
-}
-
-void *
-PK11_GetWindow(PK11SymKey *key)
-{
- return key->cx;
-}
-
-
-/*
- * extract a symetric key value. NOTE: if the key is sensitive, we will
- * not be able to do this operation. This function is used to move
- * keys from one token to another */
-SECStatus
-PK11_ExtractKeyValue(PK11SymKey *symKey)
-{
- SECStatus rv;
-
- if (symKey->data.data != NULL) {
- if (symKey->size == 0) {
- symKey->size = symKey->data.len;
- }
- return SECSuccess;
- }
-
- if (symKey->slot == NULL) {
- PORT_SetError( SEC_ERROR_INVALID_KEY );
- return SECFailure;
- }
-
- rv = PK11_ReadAttribute(symKey->slot,symKey->objectID,CKA_VALUE,NULL,
- &symKey->data);
- if (rv == SECSuccess) {
- symKey->size = symKey->data.len;
- }
- return rv;
-}
-
-SECStatus
-PK11_DeleteTokenSymKey(PK11SymKey *symKey)
-{
- if (!PK11_IsPermObject(symKey->slot, symKey->objectID)) {
- return SECFailure;
- }
- PK11_DestroyTokenObject(symKey->slot,symKey->objectID);
- symKey->objectID = CK_INVALID_HANDLE;
- return SECSuccess;
-}
-
-SECItem *
-PK11_GetKeyData(PK11SymKey *symKey)
-{
- return &symKey->data;
-}
-
-/* This symbol is exported for backward compatibility. */
-SECItem *
-__PK11_GetKeyData(PK11SymKey *symKey)
-{
- return PK11_GetKeyData(symKey);
-}
-
-
-/*
- * PKCS #11 key Types with predefined length
- */
-unsigned int
-pk11_GetPredefinedKeyLength(CK_KEY_TYPE keyType)
-{
- int length = 0;
- switch (keyType) {
- case CKK_DES: length = 8; break;
- case CKK_DES2: length = 16; break;
- case CKK_DES3: length = 24; break;
- case CKK_SKIPJACK: length = 10; break;
- case CKK_BATON: length = 20; break;
- case CKK_JUNIPER: length = 20; break;
- default: break;
- }
- return length;
-}
-
-/* return the keylength if possible. '0' if not */
-unsigned int
-PK11_GetKeyLength(PK11SymKey *key)
-{
- CK_KEY_TYPE keyType;
-
- if (key->size != 0) return key->size;
-
- /* First try to figure out the key length from its type */
- keyType = PK11_ReadULongAttribute(key->slot,key->objectID,CKA_KEY_TYPE);
- key->size = pk11_GetPredefinedKeyLength(keyType);
- if ((keyType == CKK_GENERIC_SECRET) &&
- (key->type == CKM_SSL3_PRE_MASTER_KEY_GEN)) {
- key->size=48;
- }
-
- if( key->size != 0 ) return key->size;
-
- if (key->data.data == NULL) {
- PK11_ExtractKeyValue(key);
- }
- /* key is probably secret. Look up its length */
- /* this is new PKCS #11 version 2.0 functionality. */
- if (key->size == 0) {
- CK_ULONG keyLength;
-
- keyLength = PK11_ReadULongAttribute(key->slot,key->objectID,CKA_VALUE_LEN);
- if (keyLength != CK_UNAVAILABLE_INFORMATION) {
- key->size = (unsigned int)keyLength;
- }
- }
-
- return key->size;
-}
-
-/* return the strength of a key. This is different from length in that
- * 1) it returns the size in bits, and 2) it returns only the secret portions
- * of the key minus any checksums or parity.
- */
-unsigned int
-PK11_GetKeyStrength(PK11SymKey *key, SECAlgorithmID *algid)
-{
- int size=0;
- CK_MECHANISM_TYPE mechanism= CKM_INVALID_MECHANISM; /* RC2 only */
- SECItem *param = NULL; /* RC2 only */
- CK_RC2_CBC_PARAMS *rc2_params = NULL; /* RC2 ONLY */
- unsigned int effectiveBits = 0; /* RC2 ONLY */
-
- switch (PK11_GetKeyType(key->type,0)) {
- case CKK_CDMF:
- return 40;
- case CKK_DES:
- return 56;
- case CKK_DES3:
- case CKK_DES2:
- size = PK11_GetKeyLength(key);
- if (size == 16) {
- /* double des */
- return 112; /* 16*7 */
- }
- return 168;
- /*
- * RC2 has is different than other ciphers in that it allows the user
- * to deprecating keysize while still requiring all the bits for the
- * original key. The info
- * on what the effective key strength is in the parameter for the key.
- * In S/MIME this parameter is stored in the DER encoded algid. In Our
- * other uses of RC2, effectiveBits == keyBits, so this code functions
- * correctly without an algid.
- */
- case CKK_RC2:
- /* if no algid was provided, fall through to default */
- if (!algid) {
- break;
- }
- /* verify that the algid is for RC2 */
- mechanism = PK11_AlgtagToMechanism(SECOID_GetAlgorithmTag(algid));
- if ((mechanism != CKM_RC2_CBC) && (mechanism != CKM_RC2_ECB)) {
- break;
- }
-
- /* now get effective bits from the algorithm ID. */
- param = PK11_ParamFromAlgid(algid);
- /* if we couldn't get memory just use key length */
- if (param == NULL) {
- break;
- }
-
- rc2_params = (CK_RC2_CBC_PARAMS *) param->data;
- /* paranoia... shouldn't happen */
- PORT_Assert(param->data != NULL);
- if (param->data == NULL) {
- SECITEM_FreeItem(param,PR_TRUE);
- break;
- }
- effectiveBits = (unsigned int)rc2_params->ulEffectiveBits;
- SECITEM_FreeItem(param,PR_TRUE);
- param = NULL; rc2_params=NULL; /* paranoia */
-
- /* we have effective bits, is and allocated memory is free, now
- * we need to return the smaller of effective bits and keysize */
- size = PK11_GetKeyLength(key);
- if ((unsigned int)size*8 > effectiveBits) {
- return effectiveBits;
- }
-
- return size*8; /* the actual key is smaller, the strength can't be
- * greater than the actual key size */
-
- default:
- break;
- }
- return PK11_GetKeyLength(key) * 8;
-}
-
-/*
- * The next three utilities are to deal with the fact that a given operation
- * may be a multi-slot affair. This creates a new key object that is copied
- * into the new slot.
- */
-PK11SymKey *
-pk11_CopyToSlotPerm(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
- CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags,
- PRBool isPerm, PK11SymKey *symKey)
-{
- SECStatus rv;
- PK11SymKey *newKey = NULL;
-
- /* Extract the raw key data if possible */
- if (symKey->data.data == NULL) {
- rv = PK11_ExtractKeyValue(symKey);
- /* KEY is sensitive, we're try key exchanging it. */
- if (rv != SECSuccess) {
- return pk11_KeyExchange(slot, type, operation,
- flags, isPerm, symKey);
- }
- }
-
- newKey = PK11_ImportSymKeyWithFlags(slot, type, symKey->origin,
- operation, &symKey->data, flags, isPerm, symKey->cx);
- if (newKey == NULL) {
- newKey = pk11_KeyExchange(slot, type, operation, flags, isPerm, symKey);
- }
- return newKey;
-}
-
-PK11SymKey *
-pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
- CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey)
-{
- return pk11_CopyToSlotPerm(slot, type, operation, 0, PR_FALSE, symKey);
-}
-
-/*
- * Make sure the slot we are in is the correct slot for the operation
- * by verifying that it supports all of the specified mechanism types.
- */
-PK11SymKey *
-pk11_ForceSlotMultiple(PK11SymKey *symKey, CK_MECHANISM_TYPE *type,
- int mechCount, CK_ATTRIBUTE_TYPE operation)
-{
- PK11SlotInfo *slot = symKey->slot;
- PK11SymKey *newKey = NULL;
- PRBool needToCopy = PR_FALSE;
- int i;
-
- if (slot == NULL) {
- needToCopy = PR_TRUE;
- } else {
- i = 0;
- while ((i < mechCount) && (needToCopy == PR_FALSE)) {
- if (!PK11_DoesMechanism(slot,type[i])) {
- needToCopy = PR_TRUE;
- }
- i++;
- }
- }
-
- if (needToCopy == PR_TRUE) {
- slot = PK11_GetBestSlotMultiple(type,mechCount,symKey->cx);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
- newKey = pk11_CopyToSlot(slot, type[0], operation, symKey);
- PK11_FreeSlot(slot);
- }
- return newKey;
-}
-
-/*
- * Make sure the slot we are in is the correct slot for the operation
- */
-PK11SymKey *
-pk11_ForceSlot(PK11SymKey *symKey,CK_MECHANISM_TYPE type,
- CK_ATTRIBUTE_TYPE operation)
-{
- return pk11_ForceSlotMultiple(symKey, &type, 1, operation);
-}
-
-PK11SymKey *
-PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
- CK_FLAGS flags, PRBool perm, PK11SymKey *symKey)
-{
- if (symKey->slot == slot) {
- if (perm) {
- return PK11_ConvertSessionSymKeyToTokenSymKey(symKey,symKey->cx);
- } else {
- return PK11_ReferenceSymKey(symKey);
- }
- }
-
- return pk11_CopyToSlotPerm(slot, symKey->type,
- operation, flags, perm, symKey);
-}
-
-/*
- * Use the token to generate a key.
- *
- * keySize must be 'zero' for fixed key length algorithms. A nonzero
- * keySize causes the CKA_VALUE_LEN attribute to be added to the template
- * for the key. Most PKCS #11 modules fail if you specify the CKA_VALUE_LEN
- * attribute for keys with fixed length. The exception is DES2. If you
- * select a CKM_DES3_CBC mechanism, this code will not add the CKA_VALUE_LEN
- * parameter and use the key size to determine which underlying DES keygen
- * function to use (CKM_DES2_KEY_GEN or CKM_DES3_KEY_GEN).
- *
- * keyType must be -1 for most algorithms. Some PBE algorthims cannot
- * determine the correct key type from the mechanism or the parameters,
- * so key type must be specified. Other PKCS #11 mechanisms may do so in
- * the future. Currently there is no need to export this publically.
- * Keep it private until there is a need in case we need to expand the
- * keygen parameters again...
- *
- * CK_FLAGS flags: key operation flags
- * PK11AttrFlags attrFlags: PK11_ATTR_XXX key attribute flags
- */
-PK11SymKey *
-pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- SECItem *param, CK_KEY_TYPE keyType, int keySize, SECItem *keyid,
- CK_FLAGS opFlags, PK11AttrFlags attrFlags, void *wincx)
-{
- PK11SymKey *symKey;
- CK_ATTRIBUTE genTemplate[MAX_TEMPL_ATTRS];
- CK_ATTRIBUTE *attrs = genTemplate;
- int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
- CK_MECHANISM_TYPE keyGenType;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_ULONG ck_key_size; /* only used for variable-length keys */
-
- if (pk11_BadAttrFlags(attrFlags)) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
- }
-
- if ((keySize != 0) && (type != CKM_DES3_CBC) &&
- (type !=CKM_DES3_CBC_PAD) && (type != CKM_DES3_ECB)) {
- ck_key_size = keySize; /* Convert to PK11 type */
-
- PK11_SETATTRS(attrs, CKA_VALUE_LEN, &ck_key_size, sizeof(ck_key_size));
- attrs++;
- }
-
- if (keyType != -1) {
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(CK_KEY_TYPE));
- attrs++;
- }
-
- /* Include key id value if provided */
- if (keyid) {
- PK11_SETATTRS(attrs, CKA_ID, keyid->data, keyid->len); attrs++;
- }
-
- attrs += pk11_AttrFlagsToAttributes(attrFlags, attrs, &cktrue, &ckfalse);
- attrs += pk11_OpFlagsToAttributes(opFlags, attrs, &cktrue);
-
- count = attrs - genTemplate;
- PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
-
- keyGenType = PK11_GetKeyGenWithSize(type, keySize);
- if (keyGenType == CKM_FAKE_RANDOM) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
- symKey = PK11_KeyGenWithTemplate(slot, type, keyGenType,
- param, genTemplate, count, wincx);
- if (symKey != NULL) {
- symKey->size = keySize;
- }
- return symKey;
-}
-
-/*
- * Use the token to generate a key. - Public
- *
- * keySize must be 'zero' for fixed key length algorithms. A nonzero
- * keySize causes the CKA_VALUE_LEN attribute to be added to the template
- * for the key. Most PKCS #11 modules fail if you specify the CKA_VALUE_LEN
- * attribute for keys with fixed length. The exception is DES2. If you
- * select a CKM_DES3_CBC mechanism, this code will not add the CKA_VALUE_LEN
- * parameter and use the key size to determine which underlying DES keygen
- * function to use (CKM_DES2_KEY_GEN or CKM_DES3_KEY_GEN).
- *
- * CK_FLAGS flags: key operation flags
- * PK11AttrFlags attrFlags: PK11_ATTR_XXX key attribute flags
- */
-PK11SymKey *
-PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- SECItem *param, int keySize, SECItem *keyid, CK_FLAGS opFlags,
- PK11AttrFlags attrFlags, void *wincx)
-{
- return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param, -1, keySize,
- keyid, opFlags, attrFlags, wincx);
-}
-
-/*
- * Use the token to generate a key. keySize must be 'zero' for fixed key
- * length algorithms. A nonzero keySize causes the CKA_VALUE_LEN attribute
- * to be added to the template for the key. PKCS #11 modules fail if you
- * specify the CKA_VALUE_LEN attribute for keys with fixed length.
- * NOTE: this means to generate a DES2 key from this interface you must
- * specify CKM_DES2_KEY_GEN as the mechanism directly; specifying
- * CKM_DES3_CBC as the mechanism and 16 as keySize currently doesn't work.
- */
-PK11SymKey *
-PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
- int keySize, SECItem *keyid, PRBool isToken, void *wincx)
-{
- PK11SymKey *symKey;
- PRBool weird = PR_FALSE; /* hack for fortezza */
- CK_FLAGS opFlags = CKF_SIGN;
- PK11AttrFlags attrFlags = 0;
-
- if ((keySize == -1) && (type == CKM_SKIPJACK_CBC64)) {
- weird = PR_TRUE;
- keySize = 0;
- }
-
- opFlags |= weird ? CKF_DECRYPT : CKF_ENCRYPT;
-
- if (isToken) {
- attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
- }
-
- symKey = pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, param,
- -1, keySize, keyid, opFlags, attrFlags, wincx);
- if (symKey && weird) {
- PK11_SetFortezzaHack(symKey);
- }
-
- return symKey;
-}
-
-PK11SymKey *
-PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
- int keySize, void *wincx)
-{
- return PK11_TokenKeyGen(slot, type, param, keySize, 0, PR_FALSE, wincx);
-}
-
-PK11SymKey *
-PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- CK_MECHANISM_TYPE keyGenType,
- SECItem *param, CK_ATTRIBUTE * attrs,
- unsigned int attrsCount, void *wincx)
-{
- PK11SymKey *symKey;
- CK_SESSION_HANDLE session;
- CK_MECHANISM mechanism;
- CK_RV crv;
- PRBool isToken = CK_FALSE;
- CK_ULONG keySize = 0;
- unsigned i;
-
- /* Extract the template's CKA_VALUE_LEN into keySize and CKA_TOKEN into
- isToken. */
- for (i = 0; i < attrsCount; ++i) {
- switch (attrs[i].type) {
- case CKA_VALUE_LEN:
- if (attrs[i].pValue == NULL ||
- attrs[i].ulValueLen != sizeof(CK_ULONG)) {
- PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT));
- return NULL;
- }
- keySize = * (CK_ULONG *) attrs[i].pValue;
- break;
- case CKA_TOKEN:
- if (attrs[i].pValue == NULL ||
- attrs[i].ulValueLen != sizeof(CK_BBOOL)) {
- PORT_SetError(PK11_MapError(CKR_TEMPLATE_INCONSISTENT));
- return NULL;
- }
- isToken = (*(CK_BBOOL*)attrs[i].pValue) ? PR_TRUE : PR_FALSE;
- break;
- }
- }
-
- /* find a slot to generate the key into */
- /* Only do slot management if this is not a token key */
- if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) {
- PK11SlotInfo *bestSlot = PK11_GetBestSlot(type,wincx);
- if (bestSlot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
- symKey = pk11_CreateSymKey(bestSlot, type, !isToken, PR_TRUE, wincx);
- PK11_FreeSlot(bestSlot);
- } else {
- symKey = pk11_CreateSymKey(slot, type, !isToken, PR_TRUE, wincx);
- }
- if (symKey == NULL) return NULL;
-
- symKey->size = keySize;
- symKey->origin = PK11_OriginGenerated;
-
- /* Set the parameters for the key gen if provided */
- mechanism.mechanism = keyGenType;
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
- if (param) {
- mechanism.pParameter = param->data;
- mechanism.ulParameterLen = param->len;
- }
-
- /* Get session and perform locking */
- if (isToken) {
- PK11_Authenticate(symKey->slot,PR_TRUE,wincx);
- /* Should always be original slot */
- session = PK11_GetRWSession(symKey->slot);
- symKey->owner = PR_FALSE;
- } else {
- session = symKey->session;
- if (session != CK_INVALID_SESSION)
- pk11_EnterKeyMonitor(symKey);
- }
- if (session == CK_INVALID_SESSION) {
- PK11_FreeSymKey(symKey);
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return NULL;
- }
-
- crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session,
- &mechanism, attrs, attrsCount, &symKey->objectID);
-
- /* Release lock and session */
- if (isToken) {
- PK11_RestoreROSession(symKey->slot, session);
- } else {
- pk11_ExitKeyMonitor(symKey);
- }
-
- if (crv != CKR_OK) {
- PK11_FreeSymKey(symKey);
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
- }
-
- return symKey;
-}
-
-
-/* --- */
-PK11SymKey *
-PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx)
-{
- return PK11_TokenKeyGen(slot, CKM_DES3_CBC, 0, 0, keyid, PR_TRUE, cx);
-}
-
-PK11SymKey*
-PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
-{
- PK11SlotInfo* slot = symk->slot;
- CK_ATTRIBUTE template[1];
- CK_ATTRIBUTE *attrs = template;
- CK_BBOOL cktrue = CK_TRUE;
- CK_RV crv;
- CK_OBJECT_HANDLE newKeyID;
- CK_SESSION_HANDLE rwsession;
-
- PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++;
-
- PK11_Authenticate(slot, PR_TRUE, wincx);
- rwsession = PK11_GetRWSession(slot);
- if (rwsession == CK_INVALID_SESSION) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return NULL;
- }
- crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, symk->objectID,
- template, 1, &newKeyID);
- PK11_RestoreROSession(slot, rwsession);
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return NULL;
- }
-
- return PK11_SymKeyFromHandle(slot, NULL /*parent*/, symk->origin,
- symk->type, newKeyID, PR_FALSE /*owner*/, NULL /*wincx*/);
-}
-
-/*
- * This function does a straight public key wrap (which only RSA can do).
- * Use PK11_PubGenKey and PK11_WrapSymKey to implement the FORTEZZA and
- * Diffie-Hellman Ciphers. */
-SECStatus
-PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
- PK11SymKey *symKey, SECItem *wrappedKey)
-{
- PK11SlotInfo *slot;
- CK_ULONG len = wrappedKey->len;
- PK11SymKey *newKey = NULL;
- CK_OBJECT_HANDLE id;
- CK_MECHANISM mechanism;
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- CK_RV crv;
-
- if (symKey == NULL) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return SECFailure;
- }
-
- /* if this slot doesn't support the mechanism, go to a slot that does */
- newKey = pk11_ForceSlot(symKey,type,CKA_ENCRYPT);
- if (newKey != NULL) {
- symKey = newKey;
- }
-
- if (symKey->slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return SECFailure;
- }
-
- slot = symKey->slot;
- mechanism.mechanism = pk11_mapWrapKeyType(pubKey->keyType);
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
-
- id = PK11_ImportPublicKey(slot,pubKey,PR_FALSE);
- if (id == CK_INVALID_HANDLE) {
- if (newKey) {
- PK11_FreeSymKey(newKey);
- }
- return SECFailure; /* Error code has been set. */
- }
-
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_WrapKey(session,&mechanism,
- id,symKey->objectID,wrappedKey->data,&len);
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- if (newKey) {
- PK11_FreeSymKey(newKey);
- }
-
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- wrappedKey->len = len;
- return SECSuccess;
-}
-
-/*
- * this little function uses the Encrypt function to wrap a key, just in
- * case we have problems with the wrap implementation for a token.
- */
-static SECStatus
-pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, CK_MECHANISM_TYPE type,
- SECItem *inKey, SECItem *outKey)
-{
- PK11SlotInfo *slot;
- CK_ULONG len;
- SECItem *data;
- CK_MECHANISM mech;
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- CK_RV crv;
-
- slot = wrappingKey->slot;
- /* use NULL IV's for wrapping */
- mech.mechanism = type;
- if (param) {
- mech.pParameter = param->data;
- mech.ulParameterLen = param->len;
- } else {
- mech.pParameter = NULL;
- mech.ulParameterLen = 0;
- }
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_EncryptInit(session,&mech,
- wrappingKey->objectID);
- if (crv != CKR_OK) {
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
-
- /* keys are almost always aligned, but if we get this far,
- * we've gone above and beyond anyway... */
- data = PK11_BlockData(inKey,PK11_GetBlockSize(type,param));
- if (data == NULL) {
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- len = outKey->len;
- crv = PK11_GETTAB(slot)->C_Encrypt(session,data->data,data->len,
- outKey->data, &len);
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- SECITEM_FreeItem(data,PR_TRUE);
- outKey->len = len;
- if (crv != CKR_OK) {
- PORT_SetError( PK11_MapError(crv) );
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * This function does a symetric based wrap.
- */
-SECStatus
-PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
- PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey)
-{
- PK11SlotInfo *slot;
- CK_ULONG len = wrappedKey->len;
- PK11SymKey *newKey = NULL;
- SECItem *param_save = NULL;
- CK_MECHANISM mechanism;
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
- CK_RV crv;
- SECStatus rv;
-
- /* if this slot doesn't support the mechanism, go to a slot that does */
- /* Force symKey and wrappingKey into the same slot */
- if ((wrappingKey->slot == NULL) || (symKey->slot != wrappingKey->slot)) {
- /* first try copying the wrapping Key to the symKey slot */
- if (symKey->slot && PK11_DoesMechanism(symKey->slot,type)) {
- newKey = pk11_CopyToSlot(symKey->slot,type,CKA_WRAP,wrappingKey);
- }
- /* Nope, try it the other way */
- if (newKey == NULL) {
- if (wrappingKey->slot) {
- newKey = pk11_CopyToSlot(wrappingKey->slot,
- symKey->type, CKA_ENCRYPT, symKey);
- }
- /* just not playing... one last thing, can we get symKey's data?
- * If it's possible, we it should already be in the
- * symKey->data.data pointer because pk11_CopyToSlot would have
- * tried to put it there. */
- if (newKey == NULL) {
- /* Can't get symKey's data: Game Over */
- if (symKey->data.data == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return SECFailure;
- }
- if (param == NULL) {
- param_save = param = PK11_ParamFromIV(type,NULL);
- }
- rv = pk11_HandWrap(wrappingKey, param, type,
- &symKey->data,wrappedKey);
- if (param_save) SECITEM_FreeItem(param_save,PR_TRUE);
- return rv;
- }
- /* we successfully moved the sym Key */
- symKey = newKey;
- } else {
- /* we successfully moved the wrapping Key */
- wrappingKey = newKey;
- }
- }
-
- /* at this point both keys are in the same token */
- slot = wrappingKey->slot;
- mechanism.mechanism = type;
- /* use NULL IV's for wrapping */
- if (param == NULL) {
- param_save = param = PK11_ParamFromIV(type,NULL);
- }
- if (param) {
- mechanism.pParameter = param->data;
- mechanism.ulParameterLen = param->len;
- } else {
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
- }
-
- len = wrappedKey->len;
-
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_WrapKey(session, &mechanism,
- wrappingKey->objectID, symKey->objectID,
- wrappedKey->data, &len);
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- rv = SECSuccess;
- if (crv != CKR_OK) {
- /* can't wrap it? try hand wrapping it... */
- do {
- if (symKey->data.data == NULL) {
- rv = PK11_ExtractKeyValue(symKey);
- if (rv != SECSuccess) break;
- }
- rv = pk11_HandWrap(wrappingKey, param, type, &symKey->data,
- wrappedKey);
- } while (PR_FALSE);
- } else {
- wrappedKey->len = len;
- }
- if (newKey) PK11_FreeSymKey(newKey);
- if (param_save) SECITEM_FreeItem(param_save,PR_TRUE);
- return rv;
-}
-
-/*
- * This Generates a new key based on a symetricKey
- */
-PK11SymKey *
-PK11_Derive( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize)
-{
- return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,
- keySize, NULL, 0, PR_FALSE);
-}
-
-
-PK11SymKey *
-PK11_DeriveWithFlags( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
- SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize, CK_FLAGS flags)
-{
- CK_BBOOL ckTrue = CK_TRUE;
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
- unsigned int templateCount;
-
- templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);
- return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,
- keySize, keyTemplate, templateCount, PR_FALSE);
-}
-
-PK11SymKey *
-PK11_DeriveWithFlagsPerm( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
- SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize, CK_FLAGS flags, PRBool isPerm)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
- CK_ATTRIBUTE *attrs;
- unsigned int templateCount = 0;
-
- attrs = keyTemplate;
- if (isPerm) {
- PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++;
- }
- templateCount = attrs - keyTemplate;
- templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
- return PK11_DeriveWithTemplate(baseKey, derive, param, target, operation,
- keySize, keyTemplate, templateCount, isPerm);
-}
-
-PK11SymKey *
-PK11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
- SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs,
- PRBool isPerm)
-{
- PK11SlotInfo * slot = baseKey->slot;
- PK11SymKey * symKey;
- PK11SymKey * newBaseKey = NULL;
- CK_BBOOL cktrue = CK_TRUE;
- CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_ULONG valueLen = 0;
- CK_MECHANISM mechanism;
- CK_RV crv;
-#define MAX_ADD_ATTRS 4
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS];
-#undef MAX_ADD_ATTRS
- CK_ATTRIBUTE * attrs = keyTemplate;
- CK_SESSION_HANDLE session;
- unsigned int templateCount;
-
- if (numAttrs > MAX_TEMPL_ATTRS) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- /* first copy caller attributes in. */
- for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
- *attrs++ = *userAttr++;
- }
-
- /* We only add the following attributes to the template if the caller
- ** didn't already supply them.
- */
- if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) {
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass);
- attrs++;
- }
- if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) {
- keyType = PK11_GetKeyType(target, keySize);
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType );
- attrs++;
- }
- if (keySize > 0 &&
- !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) {
- valueLen = (CK_ULONG)keySize;
- PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen);
- attrs++;
- }
- if ((operation != CKA_FLAGS_ONLY) &&
- !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) {
- PK11_SETATTRS(attrs, operation, &cktrue, sizeof cktrue); attrs++;
- }
-
- templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
-
- /* move the key to a slot that can do the function */
- if (!PK11_DoesMechanism(slot,derive)) {
- /* get a new base key & slot */
- PK11SlotInfo *newSlot = PK11_GetBestSlot(derive, baseKey->cx);
-
- if (newSlot == NULL) return NULL;
-
- newBaseKey = pk11_CopyToSlot (newSlot, derive, CKA_DERIVE,
- baseKey);
- PK11_FreeSlot(newSlot);
- if (newBaseKey == NULL)
- return NULL;
- baseKey = newBaseKey;
- slot = baseKey->slot;
- }
-
-
- /* get our key Structure */
- symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, baseKey->cx);
- if (symKey == NULL) {
- return NULL;
- }
-
- symKey->size = keySize;
-
- mechanism.mechanism = derive;
- if (param) {
- mechanism.pParameter = param->data;
- mechanism.ulParameterLen = param->len;
- } else {
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
- }
- symKey->origin=PK11_OriginDerive;
-
- if (isPerm) {
- session = PK11_GetRWSession(slot);
- } else {
- pk11_EnterKeyMonitor(symKey);
- session = symKey->session;
- }
- if (session == CK_INVALID_SESSION) {
- if (!isPerm)
- pk11_ExitKeyMonitor(symKey);
- crv = CKR_SESSION_HANDLE_INVALID;
- } else {
- crv = PK11_GETTAB(slot)->C_DeriveKey(session, &mechanism,
- baseKey->objectID, keyTemplate, templateCount, &symKey->objectID);
- if (isPerm) {
- PK11_RestoreROSession(slot, session);
- } else {
- pk11_ExitKeyMonitor(symKey);
- }
- }
- if (newBaseKey)
- PK11_FreeSymKey(newBaseKey);
- if (crv != CKR_OK) {
- PK11_FreeSymKey(symKey);
- return NULL;
- }
- return symKey;
-}
-
-/* Create a new key by concatenating base and data
- */
-static PK11SymKey *pk11_ConcatenateBaseAndData(PK11SymKey *base,
- CK_BYTE *data, CK_ULONG dataLen, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation)
-{
- CK_KEY_DERIVATION_STRING_DATA mechParams;
- SECItem param;
-
- if (base == NULL) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
- }
-
- mechParams.pData = data;
- mechParams.ulLen = dataLen;
- param.data = (unsigned char *)&mechParams;
- param.len = sizeof(CK_KEY_DERIVATION_STRING_DATA);
-
- return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_DATA,
- &param, target, operation, 0);
-}
-
-/* Create a new key by concatenating base and key
- */
-static PK11SymKey *pk11_ConcatenateBaseAndKey(PK11SymKey *base,
- PK11SymKey *key, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, CK_ULONG keySize)
-{
- SECItem param;
-
- if ((base == NULL) || (key == NULL)) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
- }
-
- param.data = (unsigned char *)&(key->objectID);
- param.len = sizeof(CK_OBJECT_HANDLE);
-
- return PK11_Derive(base, CKM_CONCATENATE_BASE_AND_KEY,
- &param, target, operation, keySize);
-}
-
-/* Create a new key whose value is the hash of tobehashed.
- * type is the mechanism for the derived key.
- */
-static PK11SymKey *pk11_HashKeyDerivation(PK11SymKey *toBeHashed,
- CK_MECHANISM_TYPE hashMechanism, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, CK_ULONG keySize)
-{
- return PK11_Derive(toBeHashed, hashMechanism, NULL, target, operation, keySize);
-}
-
-/* This function implements the ANSI X9.63 key derivation function
- */
-static PK11SymKey *pk11_ANSIX963Derive(PK11SymKey *sharedSecret,
- CK_EC_KDF_TYPE kdf, SECItem *sharedData,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- CK_ULONG keySize)
-{
- CK_KEY_TYPE keyType;
- CK_MECHANISM_TYPE hashMechanism, mechanismArray[4];
- CK_ULONG derivedKeySize, HashLen, counter, maxCounter, bufferLen;
- CK_ULONG SharedInfoLen;
- CK_BYTE *buffer = NULL;
- PK11SymKey *toBeHashed, *hashOutput;
- PK11SymKey *newSharedSecret = NULL;
- PK11SymKey *oldIntermediateResult, *intermediateResult = NULL;
-
- if (sharedSecret == NULL) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
- }
-
- switch (kdf) {
- case CKD_SHA1_KDF:
- HashLen = SHA1_LENGTH;
- hashMechanism = CKM_SHA1_KEY_DERIVATION;
- break;
- case CKD_SHA224_KDF:
- HashLen = SHA224_LENGTH;
- hashMechanism = CKM_SHA224_KEY_DERIVATION;
- break;
- case CKD_SHA256_KDF:
- HashLen = SHA256_LENGTH;
- hashMechanism = CKM_SHA256_KEY_DERIVATION;
- break;
- case CKD_SHA384_KDF:
- HashLen = SHA384_LENGTH;
- hashMechanism = CKM_SHA384_KEY_DERIVATION;
- break;
- case CKD_SHA512_KDF:
- HashLen = SHA512_LENGTH;
- hashMechanism = CKM_SHA512_KEY_DERIVATION;
- break;
- default:
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
- }
-
- derivedKeySize = keySize;
- if (derivedKeySize == 0) {
- keyType = PK11_GetKeyType(target,keySize);
- derivedKeySize = pk11_GetPredefinedKeyLength(keyType);
- if (derivedKeySize == 0) {
- derivedKeySize = HashLen;
- }
- }
-
- /* Check that key_len isn't too long. The maximum key length could be
- * greatly increased if the code below did not limit the 4-byte counter
- * to a maximum value of 255. */
- if (derivedKeySize > 254 * HashLen) {
- PORT_SetError( SEC_ERROR_INVALID_ARGS );
- return NULL;
- }
-
- maxCounter = derivedKeySize / HashLen;
- if (derivedKeySize > maxCounter * HashLen)
- maxCounter++;
-
- if ((sharedData == NULL) || (sharedData->data == NULL))
- SharedInfoLen = 0;
- else
- SharedInfoLen = sharedData->len;
-
- bufferLen = SharedInfoLen + 4;
-
- /* Populate buffer with Counter || sharedData
- * where Counter is 0x00000001. */
- buffer = (unsigned char *)PORT_Alloc(bufferLen);
- if (buffer == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- buffer[0] = 0;
- buffer[1] = 0;
- buffer[2] = 0;
- buffer[3] = 1;
- if (SharedInfoLen > 0) {
- PORT_Memcpy(&buffer[4], sharedData->data, SharedInfoLen);
- }
-
- /* Look for a slot that supports the mechanisms needed
- * to implement the ANSI X9.63 KDF as well as the
- * target mechanism.
- */
- mechanismArray[0] = CKM_CONCATENATE_BASE_AND_DATA;
- mechanismArray[1] = hashMechanism;
- mechanismArray[2] = CKM_CONCATENATE_BASE_AND_KEY;
- mechanismArray[3] = target;
-
- newSharedSecret = pk11_ForceSlotMultiple(sharedSecret,
- mechanismArray, 4, operation);
- if (newSharedSecret != NULL) {
- sharedSecret = newSharedSecret;
- }
-
- for(counter=1; counter <= maxCounter; counter++) {
- /* Concatenate shared_secret and buffer */
- toBeHashed = pk11_ConcatenateBaseAndData(sharedSecret, buffer,
- bufferLen, hashMechanism, operation);
- if (toBeHashed == NULL) {
- goto loser;
- }
-
- /* Hash value */
- if (maxCounter == 1) {
- /* In this case the length of the key to be derived is
- * less than or equal to the length of the hash output.
- * So, the output of the hash operation will be the
- * dervied key. */
- hashOutput = pk11_HashKeyDerivation(toBeHashed, hashMechanism,
- target, operation, keySize);
- } else {
- /* In this case, the output of the hash operation will be
- * concatenated with other data to create the derived key. */
- hashOutput = pk11_HashKeyDerivation(toBeHashed, hashMechanism,
- CKM_CONCATENATE_BASE_AND_KEY, operation, 0);
- }
- PK11_FreeSymKey(toBeHashed);
- if (hashOutput == NULL) {
- goto loser;
- }
-
- /* Append result to intermediate result, if necessary */
- oldIntermediateResult = intermediateResult;
-
- if (oldIntermediateResult == NULL) {
- intermediateResult = hashOutput;
- } else {
- if (counter == maxCounter) {
- /* This is the final concatenation, and so the output
- * will be the derived key. */
- intermediateResult =
- pk11_ConcatenateBaseAndKey(oldIntermediateResult,
- hashOutput, target, operation, keySize);
- } else {
- /* The output of this concatenation will be concatenated
- * with other data to create the derived key. */
- intermediateResult =
- pk11_ConcatenateBaseAndKey(oldIntermediateResult,
- hashOutput, CKM_CONCATENATE_BASE_AND_KEY,
- operation, 0);
- }
-
- PK11_FreeSymKey(hashOutput);
- PK11_FreeSymKey(oldIntermediateResult);
- if (intermediateResult == NULL) {
- goto loser;
- }
- }
-
- /* Increment counter (assumes maxCounter < 255) */
- buffer[3]++;
- }
-
- PORT_ZFree(buffer, bufferLen);
- if (newSharedSecret != NULL)
- PK11_FreeSymKey(newSharedSecret);
- return intermediateResult;
-
-loser:
- if (buffer != NULL)
- PORT_ZFree(buffer, bufferLen);
- if (newSharedSecret != NULL)
- PK11_FreeSymKey(newSharedSecret);
- if (intermediateResult != NULL)
- PK11_FreeSymKey(intermediateResult);
- return NULL;
-}
-
-/*
- * This Generates a wrapping key based on a privateKey, publicKey, and two
- * random numbers. For Mail usage RandomB should be NULL. In the Sender's
- * case RandomA is generate, outherwize it is passed.
- */
-static unsigned char *rb_email = NULL;
-
-PK11SymKey *
-PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
- PRBool isSender, SECItem *randomA, SECItem *randomB,
- CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx)
-{
- PK11SlotInfo *slot = privKey->pkcs11Slot;
- CK_MECHANISM mechanism;
- PK11SymKey *symKey;
- CK_RV crv;
-
-
- if (rb_email == NULL) {
- rb_email = PORT_ZAlloc(128);
- if (rb_email == NULL) {
- return NULL;
- }
- rb_email[127] = 1;
- }
-
- /* get our key Structure */
- symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx);
- if (symKey == NULL) {
- return NULL;
- }
-
- symKey->origin = PK11_OriginDerive;
-
- switch (privKey->keyType) {
- case rsaKey:
- case nullKey:
- PORT_SetError(SEC_ERROR_BAD_KEY);
- break;
- case dsaKey:
- case keaKey:
- case fortezzaKey:
- {
- CK_KEA_DERIVE_PARAMS param;
- param.isSender = (CK_BBOOL) isSender;
- param.ulRandomLen = randomA->len;
- param.pRandomA = randomA->data;
- param.pRandomB = rb_email;
- if (randomB)
- param.pRandomB = randomB->data;
- if (pubKey->keyType == fortezzaKey) {
- param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len;
- param.pPublicData = pubKey->u.fortezza.KEAKey.data;
- } else {
- /* assert type == keaKey */
- /* XXX change to match key key types */
- param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len;
- param.pPublicData = pubKey->u.fortezza.KEAKey.data;
- }
-
- mechanism.mechanism = derive;
- mechanism.pParameter = &param;
- mechanism.ulParameterLen = sizeof(param);
-
- /* get a new symKey structure */
- pk11_EnterKeyMonitor(symKey);
- crv=PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,
- privKey->pkcs11ID, NULL, 0, &symKey->objectID);
- pk11_ExitKeyMonitor(symKey);
- if (crv == CKR_OK) return symKey;
- PORT_SetError( PK11_MapError(crv) );
- }
- break;
- case dhKey:
- {
- CK_BBOOL cktrue = CK_TRUE;
- CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_ULONG key_size = 0;
- CK_ATTRIBUTE keyTemplate[4];
- int templateCount;
- CK_ATTRIBUTE *attrs = keyTemplate;
-
- if (pubKey->keyType != dhKey) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- break;
- }
-
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
- attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
- attrs++;
- PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++;
- PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));
- attrs++;
- templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
-
- keyType = PK11_GetKeyType(target,keySize);
- key_size = keySize;
- symKey->size = keySize;
- if (key_size == 0) templateCount--;
-
- mechanism.mechanism = derive;
-
- /* we can undefine these when we define diffie-helman keys */
-
- mechanism.pParameter = pubKey->u.dh.publicValue.data;
- mechanism.ulParameterLen = pubKey->u.dh.publicValue.len;
-
- pk11_EnterKeyMonitor(symKey);
- crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,
- privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID);
- pk11_ExitKeyMonitor(symKey);
- if (crv == CKR_OK) return symKey;
- PORT_SetError( PK11_MapError(crv) );
- }
- break;
- case ecKey:
- {
- CK_BBOOL cktrue = CK_TRUE;
- CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_ULONG key_size = 0;
- CK_ATTRIBUTE keyTemplate[4];
- int templateCount;
- CK_ATTRIBUTE *attrs = keyTemplate;
- CK_ECDH1_DERIVE_PARAMS *mechParams = NULL;
-
- if (pubKey->keyType != ecKey) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- break;
- }
-
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
- attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
- attrs++;
- PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++;
- PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size));
- attrs++;
- templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
-
- keyType = PK11_GetKeyType(target,keySize);
- key_size = keySize;
- if (key_size == 0) {
- if ((key_size = pk11_GetPredefinedKeyLength(keyType))) {
- templateCount --;
- } else {
- /* sigh, some tokens can't figure this out and require
- * CKA_VALUE_LEN to be set */
- key_size = SHA1_LENGTH;
- }
- }
- symKey->size = key_size;
-
- mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS);
- mechParams->kdf = CKD_SHA1_KDF;
- mechParams->ulSharedDataLen = 0;
- mechParams->pSharedData = NULL;
- mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
- mechParams->pPublicData = pubKey->u.ec.publicValue.data;
-
- mechanism.mechanism = derive;
- mechanism.pParameter = mechParams;
- mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS);
-
- pk11_EnterKeyMonitor(symKey);
- crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,
- &mechanism, privKey->pkcs11ID, keyTemplate,
- templateCount, &symKey->objectID);
- pk11_ExitKeyMonitor(symKey);
-
- /* old PKCS #11 spec was ambiguous on what needed to be passed,
- * try this again with and encoded public key */
- if (crv != CKR_OK) {
- SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
- &pubKey->u.ec.publicValue,
- SEC_ASN1_GET(SEC_OctetStringTemplate));
- if (pubValue == NULL) {
- PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));
- break;
- }
- mechParams->ulPublicDataLen = pubValue->len;
- mechParams->pPublicData = pubValue->data;
-
- pk11_EnterKeyMonitor(symKey);
- crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,
- &mechanism, privKey->pkcs11ID, keyTemplate,
- templateCount, &symKey->objectID);
- pk11_ExitKeyMonitor(symKey);
-
- SECITEM_FreeItem(pubValue,PR_TRUE);
- }
-
- PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));
-
- if (crv == CKR_OK) return symKey;
- PORT_SetError( PK11_MapError(crv) );
- }
- }
-
- PK11_FreeSymKey(symKey);
- return NULL;
-}
-
-/* Returns the size of the public key, or 0 if there
- * is an error. */
-static CK_ULONG
-pk11_ECPubKeySize(SECItem *publicValue)
-{
- if (publicValue->data[0] == 0x04) {
- /* key encoded in uncompressed form */
- return((publicValue->len - 1)/2);
- } else if ( (publicValue->data[0] == 0x02) ||
- (publicValue->data[0] == 0x03)) {
- /* key encoded in compressed form */
- return(publicValue->len - 1);
- }
- /* key encoding not recognized */
- return(0);
-}
-
-static PK11SymKey *
-pk11_PubDeriveECKeyWithKDF(
- SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
- PRBool isSender, SECItem *randomA, SECItem *randomB,
- CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize,
- CK_ULONG kdf, SECItem *sharedData, void *wincx)
-{
- PK11SlotInfo *slot = privKey->pkcs11Slot;
- PK11SymKey *symKey;
- PK11SymKey *SharedSecret;
- CK_MECHANISM mechanism;
- CK_RV crv;
- CK_BBOOL cktrue = CK_TRUE;
- CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_ULONG key_size = 0;
- CK_ATTRIBUTE keyTemplate[4];
- int templateCount;
- CK_ATTRIBUTE *attrs = keyTemplate;
- CK_ECDH1_DERIVE_PARAMS *mechParams = NULL;
-
- if (pubKey->keyType != ecKey) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- return NULL;
- }
- if ((kdf != CKD_NULL) && (kdf != CKD_SHA1_KDF) &&
- (kdf != CKD_SHA224_KDF) && (kdf != CKD_SHA256_KDF) &&
- (kdf != CKD_SHA384_KDF) && (kdf != CKD_SHA512_KDF)) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return NULL;
- }
-
- /* get our key Structure */
- symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx);
- if (symKey == NULL) {
- return NULL;
- }
-
- symKey->origin = PK11_OriginDerive;
-
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++;
- PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++;
- PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); attrs++;
- templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
-
- keyType = PK11_GetKeyType(target,keySize);
- key_size = keySize;
- if (key_size == 0) {
- if ((key_size = pk11_GetPredefinedKeyLength(keyType))) {
- templateCount --;
- } else {
- /* sigh, some tokens can't figure this out and require
- * CKA_VALUE_LEN to be set */
- switch (kdf) {
- case CKD_NULL:
- key_size = pk11_ECPubKeySize(&pubKey->u.ec.publicValue);
- if (key_size == 0) {
- PK11_FreeSymKey(symKey);
- return NULL;
- }
- break;
- case CKD_SHA1_KDF:
- key_size = SHA1_LENGTH;
- break;
- case CKD_SHA224_KDF:
- key_size = SHA224_LENGTH;
- break;
- case CKD_SHA256_KDF:
- key_size = SHA256_LENGTH;
- break;
- case CKD_SHA384_KDF:
- key_size = SHA384_LENGTH;
- break;
- case CKD_SHA512_KDF:
- key_size = SHA512_LENGTH;
- break;
- default:
- PORT_Assert(!"Invalid CKD");
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return NULL;
- }
- }
- }
- symKey->size = key_size;
-
- mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS);
- if (!mechParams) {
- PK11_FreeSymKey(symKey);
- return NULL;
- }
- mechParams->kdf = kdf;
- if (sharedData == NULL) {
- mechParams->ulSharedDataLen = 0;
- mechParams->pSharedData = NULL;
- } else {
- mechParams->ulSharedDataLen = sharedData->len;
- mechParams->pSharedData = sharedData->data;
- }
- mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
- mechParams->pPublicData = pubKey->u.ec.publicValue.data;
-
- mechanism.mechanism = derive;
- mechanism.pParameter = mechParams;
- mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS);
-
- pk11_EnterKeyMonitor(symKey);
- crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism,
- privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID);
- pk11_ExitKeyMonitor(symKey);
-
- /* old PKCS #11 spec was ambiguous on what needed to be passed,
- * try this again with an encoded public key */
- if (crv != CKR_OK) {
- SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
- &pubKey->u.ec.publicValue,
- SEC_ASN1_GET(SEC_OctetStringTemplate));
- if (pubValue == NULL) {
- goto loser;
- }
- mechParams->ulPublicDataLen = pubValue->len;
- mechParams->pPublicData = pubValue->data;
-
- pk11_EnterKeyMonitor(symKey);
- crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session,
- &mechanism, privKey->pkcs11ID, keyTemplate,
- templateCount, &symKey->objectID);
- pk11_ExitKeyMonitor(symKey);
-
- if ((crv != CKR_OK) && (kdf != CKD_NULL)) {
- /* Some PKCS #11 libraries cannot perform the key derivation
- * function. So, try calling C_DeriveKey with CKD_NULL and then
- * performing the KDF separately.
- */
- CK_ULONG derivedKeySize = key_size;
-
- keyType = CKK_GENERIC_SECRET;
- key_size = pk11_ECPubKeySize(&pubKey->u.ec.publicValue);
- if (key_size == 0) {
- SECITEM_FreeItem(pubValue,PR_TRUE);
- goto loser;
- }
- SharedSecret = symKey;
- SharedSecret->size = key_size;
-
- mechParams->kdf = CKD_NULL;
- mechParams->ulSharedDataLen = 0;
- mechParams->pSharedData = NULL;
- mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len;
- mechParams->pPublicData = pubKey->u.ec.publicValue.data;
-
- pk11_EnterKeyMonitor(SharedSecret);
- crv = PK11_GETTAB(slot)->C_DeriveKey(SharedSecret->session,
- &mechanism, privKey->pkcs11ID, keyTemplate,
- templateCount, &SharedSecret->objectID);
- pk11_ExitKeyMonitor(SharedSecret);
-
- if (crv != CKR_OK) {
- /* old PKCS #11 spec was ambiguous on what needed to be passed,
- * try this one final time with an encoded public key */
- mechParams->ulPublicDataLen = pubValue->len;
- mechParams->pPublicData = pubValue->data;
-
- pk11_EnterKeyMonitor(SharedSecret);
- crv = PK11_GETTAB(slot)->C_DeriveKey(SharedSecret->session,
- &mechanism, privKey->pkcs11ID, keyTemplate,
- templateCount, &SharedSecret->objectID);
- pk11_ExitKeyMonitor(SharedSecret);
- }
-
- /* Perform KDF. */
- if (crv == CKR_OK) {
- symKey = pk11_ANSIX963Derive(SharedSecret, kdf,
- sharedData, target, operation,
- derivedKeySize);
- PK11_FreeSymKey(SharedSecret);
- if (symKey == NULL) {
- SECITEM_FreeItem(pubValue,PR_TRUE);
- PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));
- return NULL;
- }
- }
- }
- SECITEM_FreeItem(pubValue,PR_TRUE);
- }
-
-loser:
- PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS));
-
- if (crv != CKR_OK) {
- PK11_FreeSymKey(symKey);
- symKey = NULL;
- PORT_SetError( PK11_MapError(crv) );
- }
- return symKey;
-}
-
-PK11SymKey *
-PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
- PRBool isSender, SECItem *randomA, SECItem *randomB,
- CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize,
- CK_ULONG kdf, SECItem *sharedData, void *wincx)
-{
-
- switch (privKey->keyType) {
- case rsaKey:
- case nullKey:
- case dsaKey:
- case keaKey:
- case fortezzaKey:
- case dhKey:
- return PK11_PubDerive(privKey, pubKey, isSender, randomA, randomB,
- derive, target, operation, keySize, wincx);
- case ecKey:
- return pk11_PubDeriveECKeyWithKDF( privKey, pubKey, isSender,
- randomA, randomB, derive, target, operation, keySize,
- kdf, sharedData, wincx);
- default: break;
- }
-
- return NULL;
-}
-
-/*
- * this little function uses the Decrypt function to unwrap a key, just in
- * case we are having problem with unwrap. NOTE: The key size may
- * not be preserved properly for some algorithms!
- */
-static PK11SymKey *
-pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
- CK_MECHANISM *mech, SECItem *inKey, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE *keyTemplate, unsigned int templateCount,
- int key_size, void * wincx, CK_RV *crvp, PRBool isPerm)
-{
- CK_ULONG len;
- SECItem outKey;
- PK11SymKey *symKey;
- CK_RV crv;
- PRBool owner = PR_TRUE;
- CK_SESSION_HANDLE session;
-
- /* remove any VALUE_LEN parameters */
- if (keyTemplate[templateCount-1].type == CKA_VALUE_LEN) {
- templateCount--;
- }
-
- /* keys are almost always aligned, but if we get this far,
- * we've gone above and beyond anyway... */
- outKey.data = (unsigned char*)PORT_Alloc(inKey->len);
- if (outKey.data == NULL) {
- PORT_SetError( SEC_ERROR_NO_MEMORY );
- if (crvp) *crvp = CKR_HOST_MEMORY;
- return NULL;
- }
- len = inKey->len;
-
- /* use NULL IV's for wrapping */
- session = pk11_GetNewSession(slot,&owner);
- if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_DecryptInit(session,mech,wrappingKey);
- if (crv != CKR_OK) {
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- PORT_Free(outKey.data);
- PORT_SetError( PK11_MapError(crv) );
- if (crvp) *crvp =crv;
- return NULL;
- }
- crv = PK11_GETTAB(slot)->C_Decrypt(session,inKey->data,inKey->len,
- outKey.data, &len);
- if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot);
- pk11_CloseSession(slot,session,owner);
- if (crv != CKR_OK) {
- PORT_Free(outKey.data);
- PORT_SetError( PK11_MapError(crv) );
- if (crvp) *crvp =crv;
- return NULL;
- }
-
- outKey.len = (key_size == 0) ? len : key_size;
- outKey.type = siBuffer;
-
- if (PK11_DoesMechanism(slot,target)) {
- symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,
- isPerm, keyTemplate,
- templateCount, &outKey, wincx);
- } else {
- slot = PK11_GetBestSlot(target,wincx);
- if (slot == NULL) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- PORT_Free(outKey.data);
- if (crvp) *crvp = CKR_DEVICE_ERROR;
- return NULL;
- }
- symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap,
- isPerm, keyTemplate,
- templateCount, &outKey, wincx);
- PK11_FreeSlot(slot);
- }
- PORT_Free(outKey.data);
-
- if (crvp) *crvp = symKey? CKR_OK : CKR_DEVICE_ERROR;
- return symKey;
-}
-
-/*
- * The wrap/unwrap function is pretty much the same for private and
- * public keys. It's just getting the Object ID and slot right. This is
- * the combined unwrap function.
- */
-static PK11SymKey *
-pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
- CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize,
- void *wincx, CK_ATTRIBUTE *userAttr, unsigned int numAttrs, PRBool isPerm)
-{
- PK11SymKey * symKey;
- SECItem * param_free = NULL;
- CK_BBOOL cktrue = CK_TRUE;
- CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_ULONG valueLen = 0;
- CK_MECHANISM mechanism;
- CK_SESSION_HANDLE rwsession;
- CK_RV crv;
- CK_MECHANISM_INFO mechanism_info;
-#define MAX_ADD_ATTRS 4
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS + MAX_ADD_ATTRS];
-#undef MAX_ADD_ATTRS
- CK_ATTRIBUTE * attrs = keyTemplate;
- unsigned int templateCount;
-
- if (numAttrs > MAX_TEMPL_ATTRS) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- /* first copy caller attributes in. */
- for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
- *attrs++ = *userAttr++;
- }
-
- /* We only add the following attributes to the template if the caller
- ** didn't already supply them.
- */
- if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) {
- PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass);
- attrs++;
- }
- if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) {
- keyType = PK11_GetKeyType(target, keySize);
- PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType );
- attrs++;
- }
- if ((operation != CKA_FLAGS_ONLY) &&
- !pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) {
- PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++;
- }
-
- /*
- * must be last in case we need to use this template to import the key
- */
- if (keySize > 0 &&
- !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) {
- valueLen = (CK_ULONG)keySize;
- PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen);
- attrs++;
- }
-
- templateCount = attrs - keyTemplate;
- PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE));
-
-
- /* find out if we can do wrap directly. Because the RSA case if *very*
- * common, cache the results for it. */
- if ((wrapType == CKM_RSA_PKCS) && (slot->hasRSAInfo)) {
- mechanism_info.flags = slot->RSAInfoFlags;
- } else {
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,wrapType,
- &mechanism_info);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- mechanism_info.flags = 0;
- }
- if (wrapType == CKM_RSA_PKCS) {
- slot->RSAInfoFlags = mechanism_info.flags;
- slot->hasRSAInfo = PR_TRUE;
- }
- }
-
- /* initialize the mechanism structure */
- mechanism.mechanism = wrapType;
- /* use NULL IV's for wrapping */
- if (param == NULL)
- param = param_free = PK11_ParamFromIV(wrapType,NULL);
- if (param) {
- mechanism.pParameter = param->data;
- mechanism.ulParameterLen = param->len;
- } else {
- mechanism.pParameter = NULL;
- mechanism.ulParameterLen = 0;
- }
-
- if ((mechanism_info.flags & CKF_DECRYPT)
- && !PK11_DoesMechanism(slot,target)) {
- symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey,
- target, keyTemplate, templateCount, keySize,
- wincx, &crv, isPerm);
- if (symKey) {
- if (param_free) SECITEM_FreeItem(param_free,PR_TRUE);
- return symKey;
- }
- /*
- * if the RSA OP simply failed, don't try to unwrap again
- * with this module.
- */
- if (crv == CKR_DEVICE_ERROR){
- if (param_free) SECITEM_FreeItem(param_free,PR_TRUE);
- return NULL;
- }
- /* fall through, maybe they incorrectly set CKF_DECRYPT */
- }
-
- /* get our key Structure */
- symKey = pk11_CreateSymKey(slot, target, !isPerm, PR_TRUE, wincx);
- if (symKey == NULL) {
- if (param_free) SECITEM_FreeItem(param_free,PR_TRUE);
- return NULL;
- }
-
- symKey->size = keySize;
- symKey->origin = PK11_OriginUnwrap;
-
- if (isPerm) {
- rwsession = PK11_GetRWSession(slot);
- } else {
- pk11_EnterKeyMonitor(symKey);
- rwsession = symKey->session;
- }
- PORT_Assert(rwsession != CK_INVALID_SESSION);
- if (rwsession == CK_INVALID_SESSION)
- crv = CKR_SESSION_HANDLE_INVALID;
- else
- crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession,&mechanism,wrappingKey,
- wrappedKey->data, wrappedKey->len, keyTemplate, templateCount,
- &symKey->objectID);
- if (isPerm) {
- if (rwsession != CK_INVALID_SESSION)
- PK11_RestoreROSession(slot, rwsession);
- } else {
- pk11_ExitKeyMonitor(symKey);
- }
- if (param_free) SECITEM_FreeItem(param_free,PR_TRUE);
- if (crv != CKR_OK) {
- PK11_FreeSymKey(symKey);
- symKey = NULL;
- if (crv != CKR_DEVICE_ERROR) {
- /* try hand Unwrapping */
- symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey,
- target, keyTemplate, templateCount,
- keySize, wincx, NULL, isPerm);
- }
- }
-
- return symKey;
-}
-
-/* use a symetric key to unwrap another symetric key */
-PK11SymKey *
-PK11_UnwrapSymKey( PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType,
- SECItem *param, SECItem *wrappedKey,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize)
-{
- return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID,
- wrapType, param, wrappedKey, target, operation, keySize,
- wrappingKey->cx, NULL, 0, PR_FALSE);
-}
-
-/* use a symetric key to unwrap another symetric key */
-PK11SymKey *
-PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType,
- SECItem *param, SECItem *wrappedKey,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize, CK_FLAGS flags)
-{
- CK_BBOOL ckTrue = CK_TRUE;
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
- unsigned int templateCount;
-
- templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);
- return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID,
- wrapType, param, wrappedKey, target, operation, keySize,
- wrappingKey->cx, keyTemplate, templateCount, PR_FALSE);
-}
-
-PK11SymKey *
-PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey,
- CK_MECHANISM_TYPE wrapType,
- SECItem *param, SECItem *wrappedKey,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
- int keySize, CK_FLAGS flags, PRBool isPerm)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
- CK_ATTRIBUTE *attrs;
- unsigned int templateCount;
-
- attrs = keyTemplate;
- if (isPerm) {
- PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++;
- }
- templateCount = attrs-keyTemplate;
- templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
-
- return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID,
- wrapType, param, wrappedKey, target, operation, keySize,
- wrappingKey->cx, keyTemplate, templateCount, isPerm);
-}
-
-
-/* unwrap a symetric key with a private key. */
-PK11SymKey *
-PK11_PubUnwrapSymKey(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey,
- CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize)
-{
- CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
- PK11SlotInfo *slot = wrappingKey->pkcs11Slot;
-
- if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) {
- PK11_HandlePasswordCheck(slot,wrappingKey->wincx);
- }
-
- return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
- wrapType, NULL, wrappedKey, target, operation, keySize,
- wrappingKey->wincx, NULL, 0, PR_FALSE);
-}
-
-/* unwrap a symetric key with a private key. */
-PK11SymKey *
-PK11_PubUnwrapSymKeyWithFlags(SECKEYPrivateKey *wrappingKey,
- SECItem *wrappedKey, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags)
-{
- CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
- CK_BBOOL ckTrue = CK_TRUE;
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
- unsigned int templateCount;
- PK11SlotInfo *slot = wrappingKey->pkcs11Slot;
-
- templateCount = pk11_OpFlagsToAttributes(flags, keyTemplate, &ckTrue);
-
- if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) {
- PK11_HandlePasswordCheck(slot,wrappingKey->wincx);
- }
-
- return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
- wrapType, NULL, wrappedKey, target, operation, keySize,
- wrappingKey->wincx, keyTemplate, templateCount, PR_FALSE);
-}
-
-PK11SymKey *
-PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey,
- SECItem *wrappedKey, CK_MECHANISM_TYPE target,
- CK_ATTRIBUTE_TYPE operation, int keySize,
- CK_FLAGS flags, PRBool isPerm)
-{
- CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
- CK_BBOOL cktrue = CK_TRUE;
- CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
- CK_ATTRIBUTE *attrs;
- unsigned int templateCount;
- PK11SlotInfo *slot = wrappingKey->pkcs11Slot;
-
- attrs = keyTemplate;
- if (isPerm) {
- PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++;
- }
- templateCount = attrs-keyTemplate;
-
- templateCount += pk11_OpFlagsToAttributes(flags, attrs, &cktrue);
-
- if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey,CKA_PRIVATE)) {
- PK11_HandlePasswordCheck(slot,wrappingKey->wincx);
- }
-
- return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
- wrapType, NULL, wrappedKey, target, operation, keySize,
- wrappingKey->wincx, keyTemplate, templateCount, isPerm);
-}
-
-PK11SymKey*
-PK11_CopySymKeyForSigning(PK11SymKey *originalKey, CK_MECHANISM_TYPE mech)
-{
- CK_RV crv;
- CK_ATTRIBUTE setTemplate;
- CK_BBOOL ckTrue = CK_TRUE;
- PK11SlotInfo *slot = originalKey->slot;
-
- /* first just try to set this key up for signing */
- PK11_SETATTRS(&setTemplate, CKA_SIGN, &ckTrue, sizeof(ckTrue));
- pk11_EnterKeyMonitor(originalKey);
- crv = PK11_GETTAB(slot)-> C_SetAttributeValue(originalKey->session,
- originalKey->objectID, &setTemplate, 1);
- pk11_ExitKeyMonitor(originalKey);
- if (crv == CKR_OK) {
- return PK11_ReferenceSymKey(originalKey);
- }
-
- /* nope, doesn't like it, use the pk11 copy object command */
- return pk11_CopyToSlot(slot, mech, CKA_SIGN, originalKey);
-}
-
-void
-PK11_SetFortezzaHack(PK11SymKey *symKey) {
- symKey->origin = PK11_OriginFortezzaHack;
-}
-
-/*
- * This is required to allow FORTEZZA_NULL and FORTEZZA_RC4
- * working. This function simply gets a valid IV for the keys.
- */
-SECStatus
-PK11_GenerateFortezzaIV(PK11SymKey *symKey,unsigned char *iv,int len)
-{
- CK_MECHANISM mech_info;
- CK_ULONG count = 0;
- CK_RV crv;
- SECStatus rv = SECFailure;
-
- mech_info.mechanism = CKM_SKIPJACK_CBC64;
- mech_info.pParameter = iv;
- mech_info.ulParameterLen = len;
-
- /* generate the IV for fortezza */
- PK11_EnterSlotMonitor(symKey->slot);
- crv=PK11_GETTAB(symKey->slot)->C_EncryptInit(symKey->slot->session,
- &mech_info, symKey->objectID);
- if (crv == CKR_OK) {
- PK11_GETTAB(symKey->slot)->C_EncryptFinal(symKey->slot->session,
- NULL, &count);
- rv = SECSuccess;
- }
- PK11_ExitSlotMonitor(symKey->slot);
- return rv;
-}
-
-CK_OBJECT_HANDLE
-PK11_GetSymKeyHandle(PK11SymKey *symKey)
-{
- return symKey->objectID;
-}
-
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
deleted file mode 100644
index 6d6aeb095..000000000
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ /dev/null
@@ -1,2393 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Deal with PKCS #11 Slots.
- */
-#include "seccomon.h"
-#include "secmod.h"
-#include "nssilock.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pkcs11t.h"
-#include "pk11func.h"
-#include "secitem.h"
-#include "secerr.h"
-
-#include "dev.h"
-#include "dev3hack.h"
-#include "pkim.h"
-#include "utilpars.h"
-
-
-/*************************************************************
- * local static and global data
- *************************************************************/
-
-/*
- * This array helps parsing between names, mechanisms, and flags.
- * to make the config files understand more entries, add them
- * to this table.
- */
-PK11DefaultArrayEntry PK11_DefaultArray[] = {
- { "RSA", SECMOD_RSA_FLAG, CKM_RSA_PKCS },
- { "DSA", SECMOD_DSA_FLAG, CKM_DSA },
- { "DH", SECMOD_DH_FLAG, CKM_DH_PKCS_DERIVE },
- { "RC2", SECMOD_RC2_FLAG, CKM_RC2_CBC },
- { "RC4", SECMOD_RC4_FLAG, CKM_RC4 },
- { "DES", SECMOD_DES_FLAG, CKM_DES_CBC },
- { "AES", SECMOD_AES_FLAG, CKM_AES_CBC },
- { "Camellia", SECMOD_CAMELLIA_FLAG, CKM_CAMELLIA_CBC },
- { "SEED", SECMOD_SEED_FLAG, CKM_SEED_CBC },
- { "RC5", SECMOD_RC5_FLAG, CKM_RC5_CBC },
- { "SHA-1", SECMOD_SHA1_FLAG, CKM_SHA_1 },
-/* { "SHA224", SECMOD_SHA256_FLAG, CKM_SHA224 }, */
- { "SHA256", SECMOD_SHA256_FLAG, CKM_SHA256 },
-/* { "SHA384", SECMOD_SHA512_FLAG, CKM_SHA384 }, */
- { "SHA512", SECMOD_SHA512_FLAG, CKM_SHA512 },
- { "MD5", SECMOD_MD5_FLAG, CKM_MD5 },
- { "MD2", SECMOD_MD2_FLAG, CKM_MD2 },
- { "SSL", SECMOD_SSL_FLAG, CKM_SSL3_PRE_MASTER_KEY_GEN },
- { "TLS", SECMOD_TLS_FLAG, CKM_TLS_MASTER_KEY_DERIVE },
- { "SKIPJACK", SECMOD_FORTEZZA_FLAG, CKM_SKIPJACK_CBC64 },
- { "Publicly-readable certs", SECMOD_FRIENDLY_FLAG, CKM_INVALID_MECHANISM },
- { "Random Num Generator", SECMOD_RANDOM_FLAG, CKM_FAKE_RANDOM },
-};
-const int num_pk11_default_mechanisms =
- sizeof(PK11_DefaultArray) / sizeof(PK11_DefaultArray[0]);
-
-PK11DefaultArrayEntry *
-PK11_GetDefaultArray(int *size)
-{
- if (size) {
- *size = num_pk11_default_mechanisms;
- }
- return PK11_DefaultArray;
-}
-
-/*
- * These slotlists are lists of modules which provide default support for
- * a given algorithm or mechanism.
- */
-static PK11SlotList
- pk11_seedSlotList,
- pk11_camelliaSlotList,
- pk11_aesSlotList,
- pk11_desSlotList,
- pk11_rc4SlotList,
- pk11_rc2SlotList,
- pk11_rc5SlotList,
- pk11_sha1SlotList,
- pk11_md5SlotList,
- pk11_md2SlotList,
- pk11_rsaSlotList,
- pk11_dsaSlotList,
- pk11_dhSlotList,
- pk11_ecSlotList,
- pk11_ideaSlotList,
- pk11_sslSlotList,
- pk11_tlsSlotList,
- pk11_randomSlotList,
- pk11_sha256SlotList,
- pk11_sha512SlotList; /* slots do SHA512 and SHA384 */
-
-/************************************************************
- * Generic Slot List and Slot List element manipulations
- ************************************************************/
-
-/*
- * allocate a new list
- */
-PK11SlotList *
-PK11_NewSlotList(void)
-{
- PK11SlotList *list;
-
- list = (PK11SlotList *)PORT_Alloc(sizeof(PK11SlotList));
- if (list == NULL) return NULL;
- list->head = NULL;
- list->tail = NULL;
- list->lock = PZ_NewLock(nssILockList);
- if (list->lock == NULL) {
- PORT_Free(list);
- return NULL;
- }
-
- return list;
-}
-
-/*
- * free a list element when all the references go away.
- */
-SECStatus
-PK11_FreeSlotListElement(PK11SlotList *list, PK11SlotListElement *le)
-{
- PRBool freeit = PR_FALSE;
-
- if (list == NULL || le == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- PZ_Lock(list->lock);
- if (le->refCount-- == 1) {
- freeit = PR_TRUE;
- }
- PZ_Unlock(list->lock);
- if (freeit) {
- PK11_FreeSlot(le->slot);
- PORT_Free(le);
- }
- return SECSuccess;
-}
-
-static void
-pk11_FreeSlotListStatic(PK11SlotList *list)
-{
- PK11SlotListElement *le, *next ;
- if (list == NULL) return;
-
- for (le = list->head ; le; le = next) {
- next = le->next;
- PK11_FreeSlotListElement(list,le);
- }
- if (list->lock) {
- PZ_DestroyLock(list->lock);
- }
- list->lock = NULL;
- list->head = NULL;
-}
-
-/*
- * if we are freeing the list, we must be the only ones with a pointer
- * to the list.
- */
-void
-PK11_FreeSlotList(PK11SlotList *list)
-{
- pk11_FreeSlotListStatic(list);
- PORT_Free(list);
-}
-
-/*
- * add a slot to a list
- * "slot" is the slot to be added. Ownership is not transferred.
- * "sorted" indicates whether or not the slot should be inserted according to
- * cipherOrder of the associated module. PR_FALSE indicates that the slot
- * should be inserted to the head of the list.
- */
-SECStatus
-PK11_AddSlotToList(PK11SlotList *list,PK11SlotInfo *slot, PRBool sorted)
-{
- PK11SlotListElement *le;
- PK11SlotListElement *element;
-
- le = (PK11SlotListElement *) PORT_Alloc(sizeof(PK11SlotListElement));
- if (le == NULL) return SECFailure;
-
- le->slot = PK11_ReferenceSlot(slot);
- le->prev = NULL;
- le->refCount = 1;
- PZ_Lock(list->lock);
- element = list->head;
- /* Insertion sort, with higher cipherOrders are sorted first in the list */
- while (element && sorted && (element->slot->module->cipherOrder >
- le->slot->module->cipherOrder)) {
- element = element->next;
- }
- if (element) {
- le->prev = element->prev;
- element->prev = le;
- le->next = element;
- } else {
- le->prev = list->tail;
- le->next = NULL;
- list->tail = le;
- }
- if (le->prev) le->prev->next = le;
- if (list->head == element) list->head = le;
- PZ_Unlock(list->lock);
-
- return SECSuccess;
-}
-
-/*
- * remove a slot entry from the list
- */
-SECStatus
-PK11_DeleteSlotFromList(PK11SlotList *list,PK11SlotListElement *le)
-{
- PZ_Lock(list->lock);
- if (le->prev) le->prev->next = le->next; else list->head = le->next;
- if (le->next) le->next->prev = le->prev; else list->tail = le->prev;
- le->next = le->prev = NULL;
- PZ_Unlock(list->lock);
- PK11_FreeSlotListElement(list,le);
- return SECSuccess;
-}
-
-/*
- * Move a list to the end of the target list.
- * NOTE: There is no locking here... This assumes BOTH lists are private copy
- * lists. It also does not re-sort the target list.
- */
-SECStatus
-pk11_MoveListToList(PK11SlotList *target,PK11SlotList *src)
-{
- if (src->head == NULL) return SECSuccess;
-
- if (target->tail == NULL) {
- target->head = src->head;
- } else {
- target->tail->next = src->head;
- }
- src->head->prev = target->tail;
- target->tail = src->tail;
- src->head = src->tail = NULL;
- return SECSuccess;
-}
-
-/*
- * get an element from the list with a reference. You must own the list.
- */
-PK11SlotListElement *
-PK11_GetFirstRef(PK11SlotList *list)
-{
- PK11SlotListElement *le;
-
- le = list->head;
- if (le != NULL) (le)->refCount++;
- return le;
-}
-
-/*
- * get the next element from the list with a reference. You must own the list.
- */
-PK11SlotListElement *
-PK11_GetNextRef(PK11SlotList *list, PK11SlotListElement *le, PRBool restart)
-{
- PK11SlotListElement *new_le;
- new_le = le->next;
- if (new_le) new_le->refCount++;
- PK11_FreeSlotListElement(list,le);
- return new_le;
-}
-
-/*
- * get an element safely from the list. This just makes sure that if
- * this element is not deleted while we deal with it.
- */
-PK11SlotListElement *
-PK11_GetFirstSafe(PK11SlotList *list)
-{
- PK11SlotListElement *le;
-
- PZ_Lock(list->lock);
- le = list->head;
- if (le != NULL) (le)->refCount++;
- PZ_Unlock(list->lock);
- return le;
-}
-
-/*
- * NOTE: if this element gets deleted, we can no longer safely traverse using
- * it's pointers. We can either terminate the loop, or restart from the
- * beginning. This is controlled by the restart option.
- */
-PK11SlotListElement *
-PK11_GetNextSafe(PK11SlotList *list, PK11SlotListElement *le, PRBool restart)
-{
- PK11SlotListElement *new_le;
- PZ_Lock(list->lock);
- new_le = le->next;
- if (le->next == NULL) {
- /* if the prev and next fields are NULL then either this element
- * has been removed and we need to walk the list again (if restart
- * is true) or this was the only element on the list */
- if ((le->prev == NULL) && restart && (list->head != le)) {
- new_le = list->head;
- }
- }
- if (new_le) new_le->refCount++;
- PZ_Unlock(list->lock);
- PK11_FreeSlotListElement(list,le);
- return new_le;
-}
-
-
-/*
- * Find the element that holds this slot
- */
-PK11SlotListElement *
-PK11_FindSlotElement(PK11SlotList *list,PK11SlotInfo *slot)
-{
- PK11SlotListElement *le;
-
- for (le = PK11_GetFirstSafe(list); le;
- le = PK11_GetNextSafe(list,le,PR_TRUE)) {
- if (le->slot == slot) return le;
- }
- return NULL;
-}
-
-/************************************************************
- * Generic Slot Utilities
- ************************************************************/
-/*
- * Create a new slot structure
- */
-PK11SlotInfo *
-PK11_NewSlotInfo(SECMODModule *mod)
-{
- PK11SlotInfo *slot;
-
- slot = (PK11SlotInfo *)PORT_Alloc(sizeof(PK11SlotInfo));
- if (slot == NULL) return slot;
-
- slot->sessionLock = mod->isThreadSafe ?
- PZ_NewLock(nssILockSession) : mod->refLock;
- if (slot->sessionLock == NULL) {
- PORT_Free(slot);
- return NULL;
- }
- slot->freeListLock = PZ_NewLock(nssILockFreelist);
- if (slot->freeListLock == NULL) {
- if (mod->isThreadSafe) {
- PZ_DestroyLock(slot->sessionLock);
- }
- PORT_Free(slot);
- return NULL;
- }
- slot->freeSymKeysWithSessionHead = NULL;
- slot->freeSymKeysHead = NULL;
- slot->keyCount = 0;
- slot->maxKeyCount = 0;
- slot->functionList = NULL;
- slot->needTest = PR_TRUE;
- slot->isPerm = PR_FALSE;
- slot->isHW = PR_FALSE;
- slot->isInternal = PR_FALSE;
- slot->isThreadSafe = PR_FALSE;
- slot->disabled = PR_FALSE;
- slot->series = 1;
- slot->wrapKey = 0;
- slot->wrapMechanism = CKM_INVALID_MECHANISM;
- slot->refKeys[0] = CK_INVALID_HANDLE;
- slot->reason = PK11_DIS_NONE;
- slot->readOnly = PR_TRUE;
- slot->needLogin = PR_FALSE;
- slot->hasRandom = PR_FALSE;
- slot->defRWSession = PR_FALSE;
- slot->protectedAuthPath = PR_FALSE;
- slot->flags = 0;
- slot->session = CK_INVALID_SESSION;
- slot->slotID = 0;
- slot->defaultFlags = 0;
- slot->refCount = 1;
- slot->askpw = 0;
- slot->timeout = 0;
- slot->mechanismList = NULL;
- slot->mechanismCount = 0;
- slot->cert_array = NULL;
- slot->cert_count = 0;
- slot->slot_name[0] = 0;
- slot->token_name[0] = 0;
- PORT_Memset(slot->serial,' ',sizeof(slot->serial));
- slot->module = NULL;
- slot->authTransact = 0;
- slot->authTime = LL_ZERO;
- slot->minPassword = 0;
- slot->maxPassword = 0;
- slot->hasRootCerts = PR_FALSE;
- slot->nssToken = NULL;
- return slot;
-}
-
-/* create a new reference to a slot so it doesn't go away */
-PK11SlotInfo *
-PK11_ReferenceSlot(PK11SlotInfo *slot)
-{
- PR_ATOMIC_INCREMENT(&slot->refCount);
- return slot;
-}
-
-/* Destroy all info on a slot we have built up */
-void
-PK11_DestroySlot(PK11SlotInfo *slot)
-{
- /* free up the cached keys and sessions */
- PK11_CleanKeyList(slot);
-
- /* free up all the sessions on this slot */
- if (slot->functionList) {
- PK11_GETTAB(slot)->C_CloseAllSessions(slot->slotID);
- }
-
- if (slot->mechanismList) {
- PORT_Free(slot->mechanismList);
- }
- if (slot->isThreadSafe && slot->sessionLock) {
- PZ_DestroyLock(slot->sessionLock);
- }
- slot->sessionLock = NULL;
- if (slot->freeListLock) {
- PZ_DestroyLock(slot->freeListLock);
- slot->freeListLock = NULL;
- }
-
- /* finally Tell our parent module that we've gone away so it can unload */
- if (slot->module) {
- SECMOD_SlotDestroyModule(slot->module,PR_TRUE);
- }
-
- /* ok, well not quit finally... now we free the memory */
- PORT_Free(slot);
-}
-
-
-/* We're all done with the slot, free it */
-void
-PK11_FreeSlot(PK11SlotInfo *slot)
-{
- if (PR_ATOMIC_DECREMENT(&slot->refCount) == 0) {
- PK11_DestroySlot(slot);
- }
-}
-
-void
-PK11_EnterSlotMonitor(PK11SlotInfo *slot) {
- PZ_Lock(slot->sessionLock);
-}
-
-void
-PK11_ExitSlotMonitor(PK11SlotInfo *slot) {
- PZ_Unlock(slot->sessionLock);
-}
-
-/***********************************************************
- * Functions to find specific slots.
- ***********************************************************/
-PRBool
-SECMOD_HasRootCerts(void)
-{
- SECMODModuleList *mlp;
- SECMODModuleList *modules;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
- int i;
- PRBool found = PR_FALSE;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return found;
- }
-
- /* work through all the slots */
- SECMOD_GetReadLock(moduleLock);
- modules = SECMOD_GetDefaultModuleList();
- for(mlp = modules; mlp != NULL; mlp = mlp->next) {
- for (i=0; i < mlp->module->slotCount; i++) {
- PK11SlotInfo *tmpSlot = mlp->module->slots[i];
- if (PK11_IsPresent(tmpSlot)) {
- if (tmpSlot->hasRootCerts) {
- found = PR_TRUE;
- break;
- }
- }
- }
- if (found) break;
- }
- SECMOD_ReleaseReadLock(moduleLock);
-
- return found;
-}
-
-/***********************************************************
- * Functions to find specific slots.
- ***********************************************************/
-PK11SlotList *
-PK11_FindSlotsByNames(const char *dllName, const char* slotName,
- const char* tokenName, PRBool presentOnly)
-{
- SECMODModuleList *mlp;
- SECMODModuleList *modules;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
- int i;
- PK11SlotList* slotList = NULL;
- PRUint32 slotcount = 0;
- SECStatus rv = SECSuccess;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return slotList;
- }
-
- slotList = PK11_NewSlotList();
- if (!slotList) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return slotList;
- }
-
- if ( ((NULL == dllName) || (0 == *dllName)) &&
- ((NULL == slotName) || (0 == *slotName)) &&
- ((NULL == tokenName) || (0 == *tokenName)) ) {
- /* default to softoken */
- PK11_AddSlotToList(slotList, PK11_GetInternalKeySlot(), PR_TRUE);
- return slotList;
- }
-
- /* work through all the slots */
- SECMOD_GetReadLock(moduleLock);
- modules = SECMOD_GetDefaultModuleList();
- for (mlp = modules; mlp != NULL; mlp = mlp->next) {
- PORT_Assert(mlp->module);
- if (!mlp->module) {
- rv = SECFailure;
- break;
- }
- if ((!dllName) || (mlp->module->dllName &&
- (0 == PORT_Strcmp(mlp->module->dllName, dllName)))) {
- for (i=0; i < mlp->module->slotCount; i++) {
- PK11SlotInfo *tmpSlot = (mlp->module->slots?mlp->module->slots[i]:NULL);
- PORT_Assert(tmpSlot);
- if (!tmpSlot) {
- rv = SECFailure;
- break;
- }
- if ((PR_FALSE == presentOnly || PK11_IsPresent(tmpSlot)) &&
- ( (!tokenName) || (tmpSlot->token_name &&
- (0==PORT_Strcmp(tmpSlot->token_name, tokenName)))) &&
- ( (!slotName) || (tmpSlot->slot_name &&
- (0==PORT_Strcmp(tmpSlot->slot_name, slotName)))) ) {
- if (tmpSlot) {
- PK11_AddSlotToList(slotList, tmpSlot, PR_TRUE);
- slotcount++;
- }
- }
- }
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
-
- if ( (0 == slotcount) || (SECFailure == rv) ) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- PK11_FreeSlotList(slotList);
- slotList = NULL;
- }
-
- if (SECFailure == rv) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- }
-
- return slotList;
-}
-
-PK11SlotInfo *
-PK11_FindSlotByName(const char *name)
-{
- SECMODModuleList *mlp;
- SECMODModuleList *modules;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
- int i;
- PK11SlotInfo *slot = NULL;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return slot;
- }
- if ((name == NULL) || (*name == 0)) {
- return PK11_GetInternalKeySlot();
- }
-
- /* work through all the slots */
- SECMOD_GetReadLock(moduleLock);
- modules = SECMOD_GetDefaultModuleList();
- for(mlp = modules; mlp != NULL; mlp = mlp->next) {
- for (i=0; i < mlp->module->slotCount; i++) {
- PK11SlotInfo *tmpSlot = mlp->module->slots[i];
- if (PK11_IsPresent(tmpSlot)) {
- if (PORT_Strcmp(tmpSlot->token_name,name) == 0) {
- slot = PK11_ReferenceSlot(tmpSlot);
- break;
- }
- }
- }
- if (slot != NULL) break;
- }
- SECMOD_ReleaseReadLock(moduleLock);
-
- if (slot == NULL) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- }
-
- return slot;
-}
-
-
-PK11SlotInfo *
-PK11_FindSlotBySerial(char *serial)
-{
- SECMODModuleList *mlp;
- SECMODModuleList *modules;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
- int i;
- PK11SlotInfo *slot = NULL;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return slot;
- }
- /* work through all the slots */
- SECMOD_GetReadLock(moduleLock);
- modules = SECMOD_GetDefaultModuleList();
- for(mlp = modules; mlp != NULL; mlp = mlp->next) {
- for (i=0; i < mlp->module->slotCount; i++) {
- PK11SlotInfo *tmpSlot = mlp->module->slots[i];
- if (PK11_IsPresent(tmpSlot)) {
- if (PORT_Memcmp(tmpSlot->serial,serial,
- sizeof(tmpSlot->serial)) == 0) {
- slot = PK11_ReferenceSlot(tmpSlot);
- break;
- }
- }
- }
- if (slot != NULL) break;
- }
- SECMOD_ReleaseReadLock(moduleLock);
-
- if (slot == NULL) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- }
-
- return slot;
-}
-
-/*
- * notification stub. If we ever get interested in any events that
- * the pkcs11 functions may pass back to use, we can catch them here...
- * currently pdata is a slotinfo structure.
- */
-CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event,
- CK_VOID_PTR pdata)
-{
- return CKR_OK;
-}
-
-/*
- * grab a new RW session
- * !!! has a side effect of grabbing the Monitor if either the slot's default
- * session is RW or the slot is not thread safe. Monitor is release in function
- * below
- */
-CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot)
-{
- CK_SESSION_HANDLE rwsession;
- CK_RV crv;
- PRBool haveMonitor = PR_FALSE;
-
- if (!slot->isThreadSafe || slot->defRWSession) {
- PK11_EnterSlotMonitor(slot);
- haveMonitor = PR_TRUE;
- }
- if (slot->defRWSession) {
- PORT_Assert(slot->session != CK_INVALID_SESSION);
- if (slot->session != CK_INVALID_SESSION)
- return slot->session;
- }
-
- crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
- CKF_RW_SESSION|CKF_SERIAL_SESSION,
- slot, pk11_notify,&rwsession);
- PORT_Assert(rwsession != CK_INVALID_SESSION || crv != CKR_OK);
- if (crv != CKR_OK || rwsession == CK_INVALID_SESSION) {
- if (crv == CKR_OK)
- crv = CKR_DEVICE_ERROR;
- if (haveMonitor)
- PK11_ExitSlotMonitor(slot);
- PORT_SetError(PK11_MapError(crv));
- return CK_INVALID_SESSION;
- }
- if (slot->defRWSession) { /* we have the monitor */
- slot->session = rwsession;
- }
- return rwsession;
-}
-
-PRBool
-PK11_RWSessionHasLock(PK11SlotInfo *slot,CK_SESSION_HANDLE session_handle)
-{
- PRBool hasLock;
- hasLock = (PRBool)(!slot->isThreadSafe ||
- (slot->defRWSession && slot->session != CK_INVALID_SESSION));
- return hasLock;
-}
-
-static PRBool
-pk11_RWSessionIsDefault(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession)
-{
- PRBool isDefault;
- isDefault = (PRBool)(slot->session == rwsession &&
- slot->defRWSession &&
- slot->session != CK_INVALID_SESSION);
- return isDefault;
-}
-
-/*
- * close the rwsession and restore our readonly session
- * !!! has a side effect of releasing the Monitor if either the slot's default
- * session is RW or the slot is not thread safe.
- */
-void
-PK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession)
-{
- PORT_Assert(rwsession != CK_INVALID_SESSION);
- if (rwsession != CK_INVALID_SESSION) {
- PRBool doExit = PK11_RWSessionHasLock(slot, rwsession);
- if (!pk11_RWSessionIsDefault(slot, rwsession))
- PK11_GETTAB(slot)->C_CloseSession(rwsession);
- if (doExit)
- PK11_ExitSlotMonitor(slot);
- }
-}
-
-/************************************************************
- * Manage the built-In Slot Lists
- ************************************************************/
-
-/* Init the static built int slot list (should actually integrate
- * with PK11_NewSlotList */
-static void
-pk11_InitSlotListStatic(PK11SlotList *list)
-{
- list->lock = PZ_NewLock(nssILockList);
- list->head = NULL;
-}
-
-
-/* initialize the system slotlists */
-SECStatus
-PK11_InitSlotLists(void)
-{
- pk11_InitSlotListStatic(&pk11_seedSlotList);
- pk11_InitSlotListStatic(&pk11_camelliaSlotList);
- pk11_InitSlotListStatic(&pk11_aesSlotList);
- pk11_InitSlotListStatic(&pk11_desSlotList);
- pk11_InitSlotListStatic(&pk11_rc4SlotList);
- pk11_InitSlotListStatic(&pk11_rc2SlotList);
- pk11_InitSlotListStatic(&pk11_rc5SlotList);
- pk11_InitSlotListStatic(&pk11_md5SlotList);
- pk11_InitSlotListStatic(&pk11_md2SlotList);
- pk11_InitSlotListStatic(&pk11_sha1SlotList);
- pk11_InitSlotListStatic(&pk11_rsaSlotList);
- pk11_InitSlotListStatic(&pk11_dsaSlotList);
- pk11_InitSlotListStatic(&pk11_dhSlotList);
- pk11_InitSlotListStatic(&pk11_ecSlotList);
- pk11_InitSlotListStatic(&pk11_ideaSlotList);
- pk11_InitSlotListStatic(&pk11_sslSlotList);
- pk11_InitSlotListStatic(&pk11_tlsSlotList);
- pk11_InitSlotListStatic(&pk11_randomSlotList);
- pk11_InitSlotListStatic(&pk11_sha256SlotList);
- pk11_InitSlotListStatic(&pk11_sha512SlotList);
- return SECSuccess;
-}
-
-void
-PK11_DestroySlotLists(void)
-{
- pk11_FreeSlotListStatic(&pk11_seedSlotList);
- pk11_FreeSlotListStatic(&pk11_camelliaSlotList);
- pk11_FreeSlotListStatic(&pk11_aesSlotList);
- pk11_FreeSlotListStatic(&pk11_desSlotList);
- pk11_FreeSlotListStatic(&pk11_rc4SlotList);
- pk11_FreeSlotListStatic(&pk11_rc2SlotList);
- pk11_FreeSlotListStatic(&pk11_rc5SlotList);
- pk11_FreeSlotListStatic(&pk11_md5SlotList);
- pk11_FreeSlotListStatic(&pk11_md2SlotList);
- pk11_FreeSlotListStatic(&pk11_sha1SlotList);
- pk11_FreeSlotListStatic(&pk11_rsaSlotList);
- pk11_FreeSlotListStatic(&pk11_dsaSlotList);
- pk11_FreeSlotListStatic(&pk11_dhSlotList);
- pk11_FreeSlotListStatic(&pk11_ecSlotList);
- pk11_FreeSlotListStatic(&pk11_ideaSlotList);
- pk11_FreeSlotListStatic(&pk11_sslSlotList);
- pk11_FreeSlotListStatic(&pk11_tlsSlotList);
- pk11_FreeSlotListStatic(&pk11_randomSlotList);
- pk11_FreeSlotListStatic(&pk11_sha256SlotList);
- pk11_FreeSlotListStatic(&pk11_sha512SlotList);
- return;
-}
-
-/* return a system slot list based on mechanism */
-PK11SlotList *
-PK11_GetSlotList(CK_MECHANISM_TYPE type)
-{
-/* XXX a workaround for Bugzilla bug #55267 */
-#if defined(HPUX) && defined(__LP64__)
- if (CKM_INVALID_MECHANISM == type)
- return NULL;
-#endif
- switch (type) {
- case CKM_SEED_CBC:
- case CKM_SEED_ECB:
- return &pk11_seedSlotList;
- case CKM_CAMELLIA_CBC:
- case CKM_CAMELLIA_ECB:
- return &pk11_camelliaSlotList;
- case CKM_AES_CBC:
- case CKM_AES_ECB:
- return &pk11_aesSlotList;
- case CKM_DES_CBC:
- case CKM_DES_ECB:
- case CKM_DES3_ECB:
- case CKM_DES3_CBC:
- return &pk11_desSlotList;
- case CKM_RC4:
- return &pk11_rc4SlotList;
- case CKM_RC5_CBC:
- return &pk11_rc5SlotList;
- case CKM_SHA_1:
- return &pk11_sha1SlotList;
- case CKM_SHA224:
- case CKM_SHA256:
- return &pk11_sha256SlotList;
- case CKM_SHA384:
- case CKM_SHA512:
- return &pk11_sha512SlotList;
- case CKM_MD5:
- return &pk11_md5SlotList;
- case CKM_MD2:
- return &pk11_md2SlotList;
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- return &pk11_rc2SlotList;
- case CKM_RSA_PKCS:
- case CKM_RSA_PKCS_KEY_PAIR_GEN:
- case CKM_RSA_X_509:
- return &pk11_rsaSlotList;
- case CKM_DSA:
- return &pk11_dsaSlotList;
- case CKM_DH_PKCS_KEY_PAIR_GEN:
- case CKM_DH_PKCS_DERIVE:
- return &pk11_dhSlotList;
- case CKM_ECDSA:
- case CKM_ECDSA_SHA1:
- case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
- case CKM_ECDH1_DERIVE:
- return &pk11_ecSlotList;
- case CKM_SSL3_PRE_MASTER_KEY_GEN:
- case CKM_SSL3_MASTER_KEY_DERIVE:
- case CKM_SSL3_SHA1_MAC:
- case CKM_SSL3_MD5_MAC:
- return &pk11_sslSlotList;
- case CKM_TLS_MASTER_KEY_DERIVE:
- case CKM_TLS_KEY_AND_MAC_DERIVE:
- return &pk11_tlsSlotList;
- case CKM_IDEA_CBC:
- case CKM_IDEA_ECB:
- return &pk11_ideaSlotList;
- case CKM_FAKE_RANDOM:
- return &pk11_randomSlotList;
- }
- return NULL;
-}
-
-/*
- * load the static SlotInfo structures used to select a PKCS11 slot.
- * preSlotInfo has a list of all the default flags for the slots on this
- * module.
- */
-void
-PK11_LoadSlotList(PK11SlotInfo *slot, PK11PreSlotInfo *psi, int count)
-{
- int i;
-
- for (i=0; i < count; i++) {
- if (psi[i].slotID == slot->slotID)
- break;
- }
-
- if (i == count) return;
-
- slot->defaultFlags = psi[i].defaultFlags;
- slot->askpw = psi[i].askpw;
- slot->timeout = psi[i].timeout;
- slot->hasRootCerts = psi[i].hasRootCerts;
-
- /* if the slot is already disabled, don't load them into the
- * default slot lists. We get here so we can save the default
- * list value. */
- if (slot->disabled) return;
-
- /* if the user has disabled us, don't load us in */
- if (slot->defaultFlags & PK11_DISABLE_FLAG) {
- slot->disabled = PR_TRUE;
- slot->reason = PK11_DIS_USER_SELECTED;
- /* free up sessions and things?? */
- return;
- }
-
- for (i=0; i < num_pk11_default_mechanisms; i++) {
- if (slot->defaultFlags & PK11_DefaultArray[i].flag) {
- CK_MECHANISM_TYPE mechanism = PK11_DefaultArray[i].mechanism;
- PK11SlotList *slotList = PK11_GetSlotList(mechanism);
-
- if (slotList) PK11_AddSlotToList(slotList,slot,PR_FALSE);
- }
- }
-
- return;
-}
-
-
-/*
- * update a slot to its new attribute according to the slot list
- * returns: SECSuccess if nothing to do or add/delete is successful
- */
-SECStatus
-PK11_UpdateSlotAttribute(PK11SlotInfo *slot, PK11DefaultArrayEntry *entry,
- PRBool add)
- /* add: PR_TRUE if want to turn on */
-{
- SECStatus result = SECSuccess;
- PK11SlotList *slotList = PK11_GetSlotList(entry->mechanism);
-
- if (add) { /* trying to turn on a mechanism */
-
- /* turn on the default flag in the slot */
- slot->defaultFlags |= entry->flag;
-
- /* add this slot to the list */
- if (slotList!=NULL)
- result = PK11_AddSlotToList(slotList, slot, PR_FALSE);
-
- } else { /* trying to turn off */
-
- /* turn OFF the flag in the slot */
- slot->defaultFlags &= ~entry->flag;
-
- if (slotList) {
- /* find the element in the list & delete it */
- PK11SlotListElement *le = PK11_FindSlotElement(slotList, slot);
-
- /* remove the slot from the list */
- if (le)
- result = PK11_DeleteSlotFromList(slotList, le);
- }
- }
- return result;
-}
-
-/*
- * clear a slot off of all of it's default list
- */
-void
-PK11_ClearSlotList(PK11SlotInfo *slot)
-{
- int i;
-
- if (slot->disabled) return;
- if (slot->defaultFlags == 0) return;
-
- for (i=0; i < num_pk11_default_mechanisms; i++) {
- if (slot->defaultFlags & PK11_DefaultArray[i].flag) {
- CK_MECHANISM_TYPE mechanism = PK11_DefaultArray[i].mechanism;
- PK11SlotList *slotList = PK11_GetSlotList(mechanism);
- PK11SlotListElement *le = NULL;
-
- if (slotList) le = PK11_FindSlotElement(slotList,slot);
-
- if (le) {
- PK11_DeleteSlotFromList(slotList,le);
- PK11_FreeSlotListElement(slotList,le);
- }
- }
- }
-}
-
-
-/******************************************************************
- * Slot initialization
- ******************************************************************/
-/*
- * turn a PKCS11 Static Label into a string
- */
-char *
-PK11_MakeString(PRArenaPool *arena,char *space,
- char *staticString,int stringLen)
-{
- int i;
- char *newString;
- for(i=(stringLen-1); i >= 0; i--) {
- if (staticString[i] != ' ') break;
- }
- /* move i to point to the last space */
- i++;
- if (arena) {
- newString = (char*)PORT_ArenaAlloc(arena,i+1 /* space for NULL */);
- } else if (space) {
- newString = space;
- } else {
- newString = (char*)PORT_Alloc(i+1 /* space for NULL */);
- }
- if (newString == NULL) return NULL;
-
- if (i) PORT_Memcpy(newString,staticString, i);
- newString[i] = 0;
-
- return newString;
-}
-
-/*
- * Reads in the slots mechanism list for later use
- */
-SECStatus
-PK11_ReadMechanismList(PK11SlotInfo *slot)
-{
- CK_ULONG count;
- CK_RV crv;
- PRUint32 i;
-
- if (slot->mechanismList) {
- PORT_Free(slot->mechanismList);
- slot->mechanismList = NULL;
- }
- slot->mechanismCount = 0;
-
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetMechanismList(slot->slotID,NULL,&count);
- if (crv != CKR_OK) {
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
-
- slot->mechanismList = (CK_MECHANISM_TYPE *)
- PORT_Alloc(count *sizeof(CK_MECHANISM_TYPE));
- if (slot->mechanismList == NULL) {
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- return SECFailure;
- }
- crv = PK11_GETTAB(slot)->C_GetMechanismList(slot->slotID,
- slot->mechanismList, &count);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_Free(slot->mechanismList);
- slot->mechanismList = NULL;
- PORT_SetError(PK11_MapError(crv));
- return SECSuccess;
- }
- slot->mechanismCount = count;
- PORT_Memset(slot->mechanismBits, 0, sizeof(slot->mechanismBits));
-
- for (i=0; i < count; i++) {
- CK_MECHANISM_TYPE mech = slot->mechanismList[i];
- if (mech < 0x7ff) {
- slot->mechanismBits[mech & 0xff] |= 1 << (mech >> 8);
- }
- }
- return SECSuccess;
-}
-
-/*
- * initialize a new token
- * unlike initialize slot, this can be called multiple times in the lifetime
- * of NSS. It reads the information associated with a card or token,
- * that is not going to change unless the card or token changes.
- */
-SECStatus
-PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
-{
- CK_TOKEN_INFO tokenInfo;
- CK_RV crv;
- char *tmp;
- SECStatus rv;
- PRStatus status;
-
- /* set the slot flags to the current token values */
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID,&tokenInfo);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
-
- /* set the slot flags to the current token values */
- slot->series++; /* allow other objects to detect that the
- * slot is different */
- slot->flags = tokenInfo.flags;
- slot->needLogin = ((tokenInfo.flags & CKF_LOGIN_REQUIRED) ?
- PR_TRUE : PR_FALSE);
- slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ?
- PR_TRUE : PR_FALSE);
-
-
- slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE);
- slot->protectedAuthPath =
- ((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
- ? PR_TRUE : PR_FALSE);
- slot->lastLoginCheck = 0;
- slot->lastState = 0;
- /* on some platforms Active Card incorrectly sets the
- * CKF_PROTECTED_AUTHENTICATION_PATH bit when it doesn't mean to. */
- if (slot->isActiveCard) {
- slot->protectedAuthPath = PR_FALSE;
- }
- tmp = PK11_MakeString(NULL,slot->token_name,
- (char *)tokenInfo.label, sizeof(tokenInfo.label));
- slot->minPassword = tokenInfo.ulMinPinLen;
- slot->maxPassword = tokenInfo.ulMaxPinLen;
- PORT_Memcpy(slot->serial,tokenInfo.serialNumber,sizeof(slot->serial));
-
- nssToken_UpdateName(slot->nssToken);
-
- slot->defRWSession = (PRBool)((!slot->readOnly) &&
- (tokenInfo.ulMaxSessionCount == 1));
- rv = PK11_ReadMechanismList(slot);
- if (rv != SECSuccess) return rv;
-
- slot->hasRSAInfo = PR_FALSE;
- slot->RSAInfoFlags = 0;
-
- /* initialize the maxKeyCount value */
- if (tokenInfo.ulMaxSessionCount == 0) {
- slot->maxKeyCount = 800; /* should be #define or a config param */
- } else if (tokenInfo.ulMaxSessionCount < 20) {
- /* don't have enough sessions to keep that many keys around */
- slot->maxKeyCount = 0;
- } else {
- slot->maxKeyCount = tokenInfo.ulMaxSessionCount/2;
- }
-
- /* Make sure our session handle is valid */
- if (slot->session == CK_INVALID_SESSION) {
- /* we know we don't have a valid session, go get one */
- CK_SESSION_HANDLE session;
-
- /* session should be Readonly, serial */
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
- (slot->defRWSession ? CKF_RW_SESSION : 0) | CKF_SERIAL_SESSION,
- slot,pk11_notify,&session);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- slot->session = session;
- } else {
- /* The session we have may be defunct (the token associated with it)
- * has been removed */
- CK_SESSION_INFO sessionInfo;
-
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session,&sessionInfo);
- if (crv == CKR_DEVICE_ERROR) {
- PK11_GETTAB(slot)->C_CloseSession(slot->session);
- crv = CKR_SESSION_CLOSED;
- }
- if ((crv==CKR_SESSION_CLOSED) || (crv==CKR_SESSION_HANDLE_INVALID)) {
- crv =PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
- (slot->defRWSession ? CKF_RW_SESSION : 0) | CKF_SERIAL_SESSION,
- slot,pk11_notify,&slot->session);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- slot->session = CK_INVALID_SESSION;
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- return SECFailure;
- }
- }
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- }
-
- status = nssToken_Refresh(slot->nssToken);
- if (status != PR_SUCCESS)
- return SECFailure;
-
- if (!(slot->isInternal) && (slot->hasRandom)) {
- /* if this slot has a random number generater, use it to add entropy
- * to the internal slot. */
- PK11SlotInfo *int_slot = PK11_GetInternalSlot();
-
- if (int_slot) {
- unsigned char random_bytes[32];
-
- /* if this slot can issue random numbers, get some entropy from
- * that random number generater and give it to our internal token.
- */
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GenerateRandom
- (slot->session,random_bytes, sizeof(random_bytes));
- PK11_ExitSlotMonitor(slot);
- if (crv == CKR_OK) {
- PK11_EnterSlotMonitor(int_slot);
- PK11_GETTAB(int_slot)->C_SeedRandom(int_slot->session,
- random_bytes, sizeof(random_bytes));
- PK11_ExitSlotMonitor(int_slot);
- }
-
- /* Now return the favor and send entropy to the token's random
- * number generater */
- PK11_EnterSlotMonitor(int_slot);
- crv = PK11_GETTAB(int_slot)->C_GenerateRandom(int_slot->session,
- random_bytes, sizeof(random_bytes));
- PK11_ExitSlotMonitor(int_slot);
- if (crv == CKR_OK) {
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_SeedRandom(slot->session,
- random_bytes, sizeof(random_bytes));
- PK11_ExitSlotMonitor(slot);
- }
- PK11_FreeSlot(int_slot);
- }
- }
- /* work around a problem in softoken where it incorrectly
- * reports databases opened read only as read/write. */
- if (slot->isInternal && !slot->readOnly) {
- CK_SESSION_HANDLE session = CK_INVALID_SESSION;
-
- /* try to open a R/W session */
- crv =PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
- CKF_RW_SESSION|CKF_SERIAL_SESSION, slot, pk11_notify ,&session);
- /* what a well behaved token should return if you open
- * a RW session on a read only token */
- if (crv == CKR_TOKEN_WRITE_PROTECTED) {
- slot->readOnly = PR_TRUE;
- } else if (crv == CKR_OK) {
- CK_SESSION_INFO sessionInfo;
-
- /* Because of a second bug in softoken, which silently returns
- * a RO session, we need to check what type of session we got. */
- crv = PK11_GETTAB(slot)->C_GetSessionInfo(session, &sessionInfo);
- if (crv == CKR_OK) {
- if ((sessionInfo.flags & CKF_RW_SESSION) == 0) {
- /* session was readonly, so this softoken slot must be * readonly */
- slot->readOnly = PR_TRUE;
- }
- }
- PK11_GETTAB(slot)->C_CloseSession(session);
- }
- }
-
- return SECSuccess;
-}
-
-/*
- * initialize a new token
- * unlike initialize slot, this can be called multiple times in the lifetime
- * of NSS. It reads the information associated with a card or token,
- * that is not going to change unless the card or token changes.
- */
-SECStatus
-PK11_TokenRefresh(PK11SlotInfo *slot)
-{
- CK_TOKEN_INFO tokenInfo;
- CK_RV crv;
-
- /* set the slot flags to the current token values */
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID,&tokenInfo);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
-
- slot->flags = tokenInfo.flags;
- slot->needLogin = ((tokenInfo.flags & CKF_LOGIN_REQUIRED) ?
- PR_TRUE : PR_FALSE);
- slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ?
- PR_TRUE : PR_FALSE);
- slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE);
- slot->protectedAuthPath =
- ((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
- ? PR_TRUE : PR_FALSE);
- /* on some platforms Active Card incorrectly sets the
- * CKF_PROTECTED_AUTHENTICATION_PATH bit when it doesn't mean to. */
- if (slot->isActiveCard) {
- slot->protectedAuthPath = PR_FALSE;
- }
- return SECSuccess;
-}
-
-static PRBool
-pk11_isRootSlot(PK11SlotInfo *slot)
-{
- CK_ATTRIBUTE findTemp[1];
- CK_ATTRIBUTE *attrs;
- CK_OBJECT_CLASS oclass = CKO_NETSCAPE_BUILTIN_ROOT_LIST;
- int tsize;
- CK_OBJECT_HANDLE handle;
-
- attrs = findTemp;
- PK11_SETATTRS(attrs, CKA_CLASS, &oclass, sizeof(oclass)); attrs++;
- tsize = attrs - findTemp;
- PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
-
- handle = pk11_FindObjectByTemplate(slot,findTemp,tsize);
- if (handle == CK_INVALID_HANDLE) {
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-/*
- * Initialize the slot :
- * This initialization code is called on each slot a module supports when
- * it is loaded. It does the bringup initialization. The difference between
- * this and InitToken is Init slot does those one time initialization stuff,
- * usually associated with the reader, while InitToken may get called multiple
- * times as tokens are removed and re-inserted.
- */
-void
-PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot)
-{
- SECStatus rv;
- char *tmp;
- CK_SLOT_INFO slotInfo;
-
- slot->functionList = mod->functionList;
- slot->isInternal = mod->internal;
- slot->slotID = slotID;
- slot->isThreadSafe = mod->isThreadSafe;
- slot->hasRSAInfo = PR_FALSE;
-
- if (PK11_GETTAB(slot)->C_GetSlotInfo(slotID,&slotInfo) != CKR_OK) {
- slot->disabled = PR_TRUE;
- slot->reason = PK11_DIS_COULD_NOT_INIT_TOKEN;
- return;
- }
-
- /* test to make sure claimed mechanism work */
- slot->needTest = mod->internal ? PR_FALSE : PR_TRUE;
- slot->module = mod; /* NOTE: we don't make a reference here because
- * modules have references to their slots. This
- * works because modules keep implicit references
- * from their slots, and won't unload and disappear
- * until all their slots have been freed */
- tmp = PK11_MakeString(NULL,slot->slot_name,
- (char *)slotInfo.slotDescription, sizeof(slotInfo.slotDescription));
- slot->isHW = (PRBool)((slotInfo.flags & CKF_HW_SLOT) == CKF_HW_SLOT);
-#define ACTIVE_CARD "ActivCard SA"
- slot->isActiveCard = (PRBool)(PORT_Strncmp((char *)slotInfo.manufacturerID,
- ACTIVE_CARD, sizeof(ACTIVE_CARD)-1) == 0);
- if ((slotInfo.flags & CKF_REMOVABLE_DEVICE) == 0) {
- slot->isPerm = PR_TRUE;
- /* permanment slots must have the token present always */
- if ((slotInfo.flags & CKF_TOKEN_PRESENT) == 0) {
- slot->disabled = PR_TRUE;
- slot->reason = PK11_DIS_TOKEN_NOT_PRESENT;
- return; /* nothing else to do */
- }
- }
- /* if the token is present, initialize it */
- if ((slotInfo.flags & CKF_TOKEN_PRESENT) != 0) {
- rv = PK11_InitToken(slot,PR_TRUE);
- /* the only hard failures are on permanent devices, or function
- * verify failures... function verify failures are already handled
- * by tokenInit */
- if ((rv != SECSuccess) && (slot->isPerm) && (!slot->disabled)) {
- slot->disabled = PR_TRUE;
- slot->reason = PK11_DIS_COULD_NOT_INIT_TOKEN;
- }
- if (rv == SECSuccess && pk11_isRootSlot(slot)) {
- if (!slot->hasRootCerts) {
- slot->module->trustOrder = 100;
- }
- slot->hasRootCerts= PR_TRUE;
- }
- }
-}
-
-
-
-/*********************************************************************
- * Slot mapping utility functions.
- *********************************************************************/
-
-/*
- * determine if the token is present. If the token is present, make sure
- * we have a valid session handle. Also set the value of needLogin
- * appropriately.
- */
-static PRBool
-pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
-{
- CK_SLOT_INFO slotInfo;
- CK_SESSION_INFO sessionInfo;
- CK_RV crv;
-
- /* disabled slots are never present */
- if (slot->disabled) {
- return PR_FALSE;
- }
-
- /* permanent slots are always present */
- if (slot->isPerm && (slot->session != CK_INVALID_SESSION)) {
- return PR_TRUE;
- }
-
- if (slot->nssToken) {
- return nssToken_IsPresent(slot->nssToken);
- }
-
- /* removable slots have a flag that says they are present */
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- if (PK11_GETTAB(slot)->C_GetSlotInfo(slot->slotID,&slotInfo) != CKR_OK) {
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- return PR_FALSE;
- }
- if ((slotInfo.flags & CKF_TOKEN_PRESENT) == 0) {
- /* if the slot is no longer present, close the session */
- if (slot->session != CK_INVALID_SESSION) {
- PK11_GETTAB(slot)->C_CloseSession(slot->session);
- slot->session = CK_INVALID_SESSION;
- }
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- return PR_FALSE;
- }
-
- /* use the session Info to determine if the card has been removed and then
- * re-inserted */
- if (slot->session != CK_INVALID_SESSION) {
- if (slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session, &sessionInfo);
- if (crv != CKR_OK) {
- PK11_GETTAB(slot)->C_CloseSession(slot->session);
- slot->session = CK_INVALID_SESSION;
- }
- if (slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- }
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
-
- /* card has not been removed, current token info is correct */
- if (slot->session != CK_INVALID_SESSION) return PR_TRUE;
-
- /* initialize the token info state */
- if (PK11_InitToken(slot,loadCerts) != SECSuccess) {
- return PR_FALSE;
- }
-
- return PR_TRUE;
-}
-
-/*
- * old version of the routine
- */
-PRBool
-PK11_IsPresent(PK11SlotInfo *slot) {
- return pk11_IsPresentCertLoad(slot,PR_TRUE);
-}
-
-/* is the slot disabled? */
-PRBool
-PK11_IsDisabled(PK11SlotInfo *slot)
-{
- return slot->disabled;
-}
-
-/* and why? */
-PK11DisableReasons
-PK11_GetDisabledReason(PK11SlotInfo *slot)
-{
- return slot->reason;
-}
-
-/* returns PR_TRUE if successfully disable the slot */
-/* returns PR_FALSE otherwise */
-PRBool PK11_UserDisableSlot(PK11SlotInfo *slot) {
-
- slot->defaultFlags |= PK11_DISABLE_FLAG;
- slot->disabled = PR_TRUE;
- slot->reason = PK11_DIS_USER_SELECTED;
-
- return PR_TRUE;
-}
-
-PRBool PK11_UserEnableSlot(PK11SlotInfo *slot) {
-
- slot->defaultFlags &= ~PK11_DISABLE_FLAG;
- slot->disabled = PR_FALSE;
- slot->reason = PK11_DIS_NONE;
- return PR_TRUE;
-}
-
-PRBool PK11_HasRootCerts(PK11SlotInfo *slot) {
- return slot->hasRootCerts;
-}
-
-/* Get the module this slot is attached to */
-SECMODModule *
-PK11_GetModule(PK11SlotInfo *slot)
-{
- return slot->module;
-}
-
-/* return the default flags of a slot */
-unsigned long
-PK11_GetDefaultFlags(PK11SlotInfo *slot)
-{
- return slot->defaultFlags;
-}
-
-/*
- * The following wrapper functions allow us to export an opaque slot
- * function to the rest of libsec and the world... */
-PRBool
-PK11_IsReadOnly(PK11SlotInfo *slot)
-{
- return slot->readOnly;
-}
-
-PRBool
-PK11_IsHW(PK11SlotInfo *slot)
-{
- return slot->isHW;
-}
-
-PRBool
-PK11_IsRemovable(PK11SlotInfo *slot)
-{
- return !slot->isPerm;
-}
-
-PRBool
-PK11_IsInternal(PK11SlotInfo *slot)
-{
- return slot->isInternal;
-}
-
-PRBool
-PK11_IsInternalKeySlot(PK11SlotInfo *slot)
-{
- PK11SlotInfo *int_slot;
- PRBool result;
-
- if (!slot->isInternal) {
- return PR_FALSE;
- }
-
- int_slot = PK11_GetInternalKeySlot();
- result = (int_slot == slot) ? PR_TRUE : PR_FALSE;
- PK11_FreeSlot(int_slot);
- return result;
-}
-
-PRBool
-PK11_NeedLogin(PK11SlotInfo *slot)
-{
- return slot->needLogin;
-}
-
-PRBool
-PK11_IsFriendly(PK11SlotInfo *slot)
-{
- /* internal slot always has public readable certs */
- return (PRBool)(slot->isInternal ||
- ((slot->defaultFlags & SECMOD_FRIENDLY_FLAG) ==
- SECMOD_FRIENDLY_FLAG));
-}
-
-char *
-PK11_GetTokenName(PK11SlotInfo *slot)
-{
- return slot->token_name;
-}
-
-char *
-PK11_GetSlotName(PK11SlotInfo *slot)
-{
- return slot->slot_name;
-}
-
-int
-PK11_GetSlotSeries(PK11SlotInfo *slot)
-{
- return slot->series;
-}
-
-int
-PK11_GetCurrentWrapIndex(PK11SlotInfo *slot)
-{
- return slot->wrapKey;
-}
-
-CK_SLOT_ID
-PK11_GetSlotID(PK11SlotInfo *slot)
-{
- return slot->slotID;
-}
-
-SECMODModuleID
-PK11_GetModuleID(PK11SlotInfo *slot)
-{
- return slot->module->moduleID;
-}
-
-static void
-pk11_zeroTerminatedToBlankPadded(CK_CHAR *buffer, size_t buffer_size)
-{
- CK_CHAR *walk = buffer;
- CK_CHAR *end = buffer + buffer_size;
-
- /* find the NULL */
- while (walk < end && *walk != '\0') {
- walk++;
- }
-
- /* clear out the buffer */
- while (walk < end) {
- *walk++ = ' ';
- }
-}
-
-/* return the slot info structure */
-SECStatus
-PK11_GetSlotInfo(PK11SlotInfo *slot, CK_SLOT_INFO *info)
-{
- CK_RV crv;
-
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- /*
- * some buggy drivers do not fill the buffer completely,
- * erase the buffer first
- */
- PORT_Memset(info->slotDescription,' ',sizeof(info->slotDescription));
- PORT_Memset(info->manufacturerID,' ',sizeof(info->manufacturerID));
- crv = PK11_GETTAB(slot)->C_GetSlotInfo(slot->slotID,info);
- pk11_zeroTerminatedToBlankPadded(info->slotDescription,
- sizeof(info->slotDescription));
- pk11_zeroTerminatedToBlankPadded(info->manufacturerID,
- sizeof(info->manufacturerID));
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/* return the token info structure */
-SECStatus
-PK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info)
-{
- CK_RV crv;
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- /*
- * some buggy drivers do not fill the buffer completely,
- * erase the buffer first
- */
- PORT_Memset(info->label,' ',sizeof(info->label));
- PORT_Memset(info->manufacturerID,' ',sizeof(info->manufacturerID));
- PORT_Memset(info->model,' ',sizeof(info->model));
- PORT_Memset(info->serialNumber,' ',sizeof(info->serialNumber));
- crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID,info);
- pk11_zeroTerminatedToBlankPadded(info->label,sizeof(info->label));
- pk11_zeroTerminatedToBlankPadded(info->manufacturerID,
- sizeof(info->manufacturerID));
- pk11_zeroTerminatedToBlankPadded(info->model,sizeof(info->model));
- pk11_zeroTerminatedToBlankPadded(info->serialNumber,
- sizeof(info->serialNumber));
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/* Find out if we need to initialize the user's pin */
-PRBool
-PK11_NeedUserInit(PK11SlotInfo *slot)
-{
- PRBool needUserInit = (PRBool) ((slot->flags & CKF_USER_PIN_INITIALIZED)
- == 0);
-
- if (needUserInit) {
- CK_TOKEN_INFO info;
- SECStatus rv;
-
- /* see if token has been initialized off line */
- rv = PK11_GetTokenInfo(slot, &info);
- if (rv == SECSuccess) {
- slot->flags = info.flags;
- }
- }
- return (PRBool)((slot->flags & CKF_USER_PIN_INITIALIZED) == 0);
-}
-
-static PK11SlotInfo *pk11InternalKeySlot = NULL;
-
-/*
- * Set a new default internal keyslot. If one has already been set, clear it.
- * Passing NULL falls back to the NSS normally selected default internal key
- * slot.
- */
-void
-pk11_SetInternalKeySlot(PK11SlotInfo *slot)
-{
- if (pk11InternalKeySlot) {
- PK11_FreeSlot(pk11InternalKeySlot);
- }
- pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL;
-}
-
-/*
- * Set a new default internal keyslot if the normal key slot has not already
- * been overridden. Subsequent calls to this function will be ignored unless
- * pk11_SetInternalKeySlot is used to clear the current default.
- */
-void
-pk11_SetInternalKeySlotIfFirst(PK11SlotInfo *slot)
-{
- if (pk11InternalKeySlot) {
- return;
- }
- pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL;
-}
-
-/*
- * Swap out a default internal keyslot. Caller owns the Slot Reference
- */
-PK11SlotInfo *
-pk11_SwapInternalKeySlot(PK11SlotInfo *slot)
-{
- PK11SlotInfo *swap = pk11InternalKeySlot;
-
- pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL;
- return swap;
-}
-
-
-/* get the internal key slot. FIPS has only one slot for both key slots and
- * default slots */
-PK11SlotInfo *
-PK11_GetInternalKeySlot(void)
-{
- SECMODModule *mod;
-
- if (pk11InternalKeySlot) {
- return PK11_ReferenceSlot(pk11InternalKeySlot);
- }
-
- mod = SECMOD_GetInternalModule();
- PORT_Assert(mod != NULL);
- if (!mod) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
- return PK11_ReferenceSlot(mod->isFIPS ? mod->slots[0] : mod->slots[1]);
-}
-
-/* get the internal default slot */
-PK11SlotInfo *
-PK11_GetInternalSlot(void)
-{
- SECMODModule * mod = SECMOD_GetInternalModule();
- PORT_Assert(mod != NULL);
- if (!mod) {
- PORT_SetError( SEC_ERROR_NO_MODULE );
- return NULL;
- }
- if (mod->isFIPS) {
- return PK11_GetInternalKeySlot();
- }
- return PK11_ReferenceSlot(mod->slots[0]);
-}
-
-/*
- * check if a given slot supports the requested mechanism
- */
-PRBool
-PK11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type)
-{
- int i;
-
- /* CKM_FAKE_RANDOM is not a real PKCS mechanism. It's a marker to
- * tell us we're looking form someone that has implemented get
- * random bits */
- if (type == CKM_FAKE_RANDOM) {
- return slot->hasRandom;
- }
-
- /* for most mechanism, bypass the linear lookup */
- if (type < 0x7ff) {
- return (slot->mechanismBits[type & 0xff] & (1 << (type >> 8))) ?
- PR_TRUE : PR_FALSE;
- }
-
- for (i=0; i < (int) slot->mechanismCount; i++) {
- if (slot->mechanismList[i] == type) return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-/*
- * Return true if a token that can do the desired mechanism exists.
- * This allows us to have hardware tokens that can do function XYZ magically
- * allow SSL Ciphers to appear if they are plugged in.
- */
-PRBool
-PK11_TokenExists(CK_MECHANISM_TYPE type)
-{
- SECMODModuleList *mlp;
- SECMODModuleList *modules;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
- PK11SlotInfo *slot;
- PRBool found = PR_FALSE;
- int i;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return found;
- }
- /* we only need to know if there is a token that does this mechanism.
- * check the internal module first because it's fast, and supports
- * almost everything. */
- slot = PK11_GetInternalSlot();
- if (slot) {
- found = PK11_DoesMechanism(slot,type);
- PK11_FreeSlot(slot);
- }
- if (found) return PR_TRUE; /* bypass getting module locks */
-
- SECMOD_GetReadLock(moduleLock);
- modules = SECMOD_GetDefaultModuleList();
- for(mlp = modules; mlp != NULL && (!found); mlp = mlp->next) {
- for (i=0; i < mlp->module->slotCount; i++) {
- slot = mlp->module->slots[i];
- if (PK11_IsPresent(slot)) {
- if (PK11_DoesMechanism(slot,type)) {
- found = PR_TRUE;
- break;
- }
- }
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
- return found;
-}
-
-/*
- * get all the currently available tokens in a list.
- * that can perform the given mechanism. If mechanism is CKM_INVALID_MECHANISM,
- * get all the tokens. Make sure tokens that need authentication are put at
- * the end of this list.
- */
-PK11SlotList *
-PK11_GetAllTokens(CK_MECHANISM_TYPE type, PRBool needRW, PRBool loadCerts,
- void *wincx)
-{
- PK11SlotList * list;
- PK11SlotList * loginList;
- PK11SlotList * friendlyList;
- SECMODModuleList * mlp;
- SECMODModuleList * modules;
- SECMODListLock * moduleLock;
- int i;
-#if defined( XP_WIN32 )
- int j = 0;
- PRInt32 waste[16];
-#endif
-
- moduleLock = SECMOD_GetDefaultModuleListLock();
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return NULL;
- }
-
- list = PK11_NewSlotList();
- loginList = PK11_NewSlotList();
- friendlyList = PK11_NewSlotList();
- if ((list == NULL) || (loginList == NULL) || (friendlyList == NULL)) {
- if (list) PK11_FreeSlotList(list);
- if (loginList) PK11_FreeSlotList(loginList);
- if (friendlyList) PK11_FreeSlotList(friendlyList);
- return NULL;
- }
-
- SECMOD_GetReadLock(moduleLock);
-
- modules = SECMOD_GetDefaultModuleList();
- for(mlp = modules; mlp != NULL; mlp = mlp->next) {
-
-#if defined( XP_WIN32 )
- /* This is works around some horrible cache/page thrashing problems
- ** on Win32. Without this, this loop can take up to 6 seconds at
- ** 100% CPU on a Pentium-Pro 200. The thing this changes is to
- ** increase the size of the stack frame and modify it.
- ** Moving the loop code itself seems to have no effect.
- ** Dunno why this combination makes a difference, but it does.
- */
- waste[ j & 0xf] = j++;
-#endif
-
- for (i = 0; i < mlp->module->slotCount; i++) {
- PK11SlotInfo *slot = mlp->module->slots[i];
-
- if (pk11_IsPresentCertLoad(slot, loadCerts)) {
- if (needRW && slot->readOnly) continue;
- if ((type == CKM_INVALID_MECHANISM)
- || PK11_DoesMechanism(slot, type)) {
- if (pk11_LoginStillRequired(slot,wincx)) {
- if (PK11_IsFriendly(slot)) {
- PK11_AddSlotToList(friendlyList, slot, PR_TRUE);
- } else {
- PK11_AddSlotToList(loginList, slot, PR_TRUE);
- }
- } else {
- PK11_AddSlotToList(list, slot, PR_TRUE);
- }
- }
- }
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
-
- pk11_MoveListToList(list,friendlyList);
- PK11_FreeSlotList(friendlyList);
- pk11_MoveListToList(list,loginList);
- PK11_FreeSlotList(loginList);
-
- return list;
-}
-
-/*
- * NOTE: This routine is working from a private List generated by
- * PK11_GetAllTokens. That is why it does not need to lock.
- */
-PK11SlotList *
-PK11_GetPrivateKeyTokens(CK_MECHANISM_TYPE type,PRBool needRW,void *wincx)
-{
- PK11SlotList *list = PK11_GetAllTokens(type,needRW,PR_TRUE,wincx);
- PK11SlotListElement *le, *next ;
- SECStatus rv;
-
- if (list == NULL) return list;
-
- for (le = list->head ; le; le = next) {
- next = le->next; /* save the pointer here in case we have to
- * free the element later */
- rv = PK11_Authenticate(le->slot,PR_TRUE,wincx);
- if (rv != SECSuccess) {
- PK11_DeleteSlotFromList(list,le);
- continue;
- }
- }
- return list;
-}
-
-/*
- * returns true if the slot doesn't conform to the requested attributes
- */
-PRBool
-pk11_filterSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE mechanism,
- CK_FLAGS mechanismInfoFlags, unsigned int keySize)
-{
- CK_MECHANISM_INFO mechanism_info;
- CK_RV crv = CKR_OK;
-
- /* handle the only case where we don't actually fetch the mechanisms
- * on the fly */
- if ((keySize == 0) && (mechanism == CKM_RSA_PKCS) && (slot->hasRSAInfo)) {
- mechanism_info.flags = slot->RSAInfoFlags;
- } else {
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID, mechanism,
- &mechanism_info);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- /* if we were getting the RSA flags, save them */
- if ((crv == CKR_OK) && (mechanism == CKM_RSA_PKCS)
- && (!slot->hasRSAInfo)) {
- slot->RSAInfoFlags = mechanism_info.flags;
- slot->hasRSAInfo = PR_TRUE;
- }
- }
- /* couldn't get the mechanism info */
- if (crv != CKR_OK ) {
- return PR_TRUE;
- }
- if (keySize && ((mechanism_info.ulMinKeySize > keySize)
- || (mechanism_info.ulMaxKeySize < keySize)) ) {
- /* Token can do mechanism, but not at the key size we
- * want */
- return PR_TRUE;
- }
- if (mechanismInfoFlags && ((mechanism_info.flags & mechanismInfoFlags) !=
- mechanismInfoFlags) ) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-
-/*
- * Find the best slot which supports the given set of mechanisms and key sizes.
- * In normal cases this should grab the first slot on the list with no fuss.
- * The size array is presumed to match one for one with the mechanism type
- * array, which allows you to specify the required key size for each
- * mechanism in the list. Whether key size is in bits or bytes is mechanism
- * dependent. Typically asymetric keys are in bits and symetric keys are in
- * bytes.
- */
-PK11SlotInfo *
-PK11_GetBestSlotMultipleWithAttributes(CK_MECHANISM_TYPE *type,
- CK_FLAGS *mechanismInfoFlags, unsigned int *keySize,
- unsigned int mech_count, void *wincx)
-{
- PK11SlotList *list = NULL;
- PK11SlotListElement *le ;
- PK11SlotInfo *slot = NULL;
- PRBool freeit = PR_FALSE;
- PRBool listNeedLogin = PR_FALSE;
- int i;
- SECStatus rv;
-
- list = PK11_GetSlotList(type[0]);
-
- if ((list == NULL) || (list->head == NULL)) {
- /* We need to look up all the tokens for the mechanism */
- list = PK11_GetAllTokens(type[0],PR_FALSE,PR_TRUE,wincx);
- freeit = PR_TRUE;
- }
-
- /* no one can do it! */
- if (list == NULL) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- return NULL;
- }
-
- PORT_SetError(0);
-
-
- listNeedLogin = PR_FALSE;
- for (i=0; i < mech_count; i++) {
- if ((type[i] != CKM_FAKE_RANDOM) &&
- (type[i] != CKM_SHA_1) &&
- (type[i] != CKM_SHA224) &&
- (type[i] != CKM_SHA256) &&
- (type[i] != CKM_SHA384) &&
- (type[i] != CKM_SHA512) &&
- (type[i] != CKM_MD5) &&
- (type[i] != CKM_MD2)) {
- listNeedLogin = PR_TRUE;
- break;
- }
- }
-
- for (le = PK11_GetFirstSafe(list); le;
- le = PK11_GetNextSafe(list,le,PR_TRUE)) {
- if (PK11_IsPresent(le->slot)) {
- PRBool doExit = PR_FALSE;
- for (i=0; i < mech_count; i++) {
- if (!PK11_DoesMechanism(le->slot,type[i])) {
- doExit = PR_TRUE;
- break;
- }
- if ((mechanismInfoFlags && mechanismInfoFlags[i]) ||
- (keySize && keySize[i])) {
- if (pk11_filterSlot(le->slot, type[i],
- mechanismInfoFlags ? mechanismInfoFlags[i] : 0,
- keySize ? keySize[i] : 0)) {
- doExit = PR_TRUE;
- break;
- }
- }
- }
-
- if (doExit) continue;
-
- if (listNeedLogin && le->slot->needLogin) {
- rv = PK11_Authenticate(le->slot,PR_TRUE,wincx);
- if (rv != SECSuccess) continue;
- }
- slot = le->slot;
- PK11_ReferenceSlot(slot);
- PK11_FreeSlotListElement(list,le);
- if (freeit) { PK11_FreeSlotList(list); }
- return slot;
- }
- }
- if (freeit) { PK11_FreeSlotList(list); }
- if (PORT_GetError() == 0) {
- PORT_SetError(SEC_ERROR_NO_TOKEN);
- }
- return NULL;
-}
-
-PK11SlotInfo *
-PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type,
- unsigned int mech_count, void *wincx)
-{
- return PK11_GetBestSlotMultipleWithAttributes(type, NULL, NULL,
- mech_count, wincx);
-}
-
-/* original get best slot now calls the multiple version with only one type */
-PK11SlotInfo *
-PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx)
-{
- return PK11_GetBestSlotMultipleWithAttributes(&type, NULL, NULL, 1, wincx);
-}
-
-PK11SlotInfo *
-PK11_GetBestSlotWithAttributes(CK_MECHANISM_TYPE type, CK_FLAGS mechanismFlags,
- unsigned int keySize, void *wincx)
-{
- return PK11_GetBestSlotMultipleWithAttributes(&type, &mechanismFlags,
- &keySize, 1, wincx);
-}
-
-int
-PK11_GetBestKeyLength(PK11SlotInfo *slot,CK_MECHANISM_TYPE mechanism)
-{
- CK_MECHANISM_INFO mechanism_info;
- CK_RV crv;
-
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
- mechanism,&mechanism_info);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) return 0;
-
- if (mechanism_info.ulMinKeySize == mechanism_info.ulMaxKeySize)
- return 0;
- return mechanism_info.ulMaxKeySize;
-}
-
-
-/*
- * This function uses the existing PKCS #11 module to find the
- * longest supported key length in the preferred token for a mechanism.
- * This varies from the above function in that 1) it returns the key length
- * even for fixed key algorithms, and 2) it looks through the tokens
- * generally rather than for a specific token. This is used in liu of
- * a PK11_GetKeyLength function in pk11mech.c since we can actually read
- * supported key lengths from PKCS #11.
- *
- * For symmetric key operations the length is returned in bytes.
- */
-int
-PK11_GetMaxKeyLength(CK_MECHANISM_TYPE mechanism)
-{
- CK_MECHANISM_INFO mechanism_info;
- PK11SlotList *list = NULL;
- PK11SlotListElement *le ;
- PRBool freeit = PR_FALSE;
- int keyLength = 0;
-
- list = PK11_GetSlotList(mechanism);
-
- if ((list == NULL) || (list->head == NULL)) {
- /* We need to look up all the tokens for the mechanism */
- list = PK11_GetAllTokens(mechanism,PR_FALSE,PR_FALSE,NULL);
- freeit = PR_TRUE;
- }
-
- /* no tokens recognize this mechanism */
- if (list == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return 0;
- }
-
- for (le = PK11_GetFirstSafe(list); le;
- le = PK11_GetNextSafe(list,le,PR_TRUE)) {
- PK11SlotInfo *slot = le->slot;
- CK_RV crv;
- if (PK11_IsPresent(slot)) {
- if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
- mechanism,&mechanism_info);
- if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
- if ((crv == CKR_OK) && (mechanism_info.ulMaxKeySize != 0)
- && (mechanism_info.ulMaxKeySize != 0xffffffff)) {
- keyLength = mechanism_info.ulMaxKeySize;
- break;
- }
- }
- }
- if (le)
- PK11_FreeSlotListElement(list, le);
- if (freeit)
- PK11_FreeSlotList(list);
- return keyLength;
-}
-
-SECStatus
-PK11_SeedRandom(PK11SlotInfo *slot, unsigned char *data, int len) {
- CK_RV crv;
-
- PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_SeedRandom(slot->session, data, (CK_ULONG)len);
- PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-
-SECStatus
-PK11_GenerateRandomOnSlot(PK11SlotInfo *slot, unsigned char *data, int len) {
- CK_RV crv;
-
- if (!slot->isInternal) PK11_EnterSlotMonitor(slot);
- crv = PK11_GETTAB(slot)->C_GenerateRandom(slot->session,data,
- (CK_ULONG)len);
- if (!slot->isInternal) PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/* Attempts to update the Best Slot for "FAKE RANDOM" generation.
-** If that's not the internal slot, then it also attempts to update the
-** internal slot.
-** The return value indicates if the INTERNAL slot was updated OK.
-*/
-SECStatus
-PK11_RandomUpdate(void *data, size_t bytes)
-{
- PK11SlotInfo *slot;
- PRBool bestIsInternal;
- SECStatus status;
-
- slot = PK11_GetBestSlot(CKM_FAKE_RANDOM, NULL);
- if (slot == NULL) {
- slot = PK11_GetInternalSlot();
- if (!slot)
- return SECFailure;
- }
-
- bestIsInternal = PK11_IsInternal(slot);
- status = PK11_SeedRandom(slot, data, bytes);
- PK11_FreeSlot(slot);
-
- if (!bestIsInternal) {
- /* do internal slot, too. */
- slot = PK11_GetInternalSlot(); /* can't fail */
- status = PK11_SeedRandom(slot, data, bytes);
- PK11_FreeSlot(slot);
- }
- return status;
-}
-
-
-SECStatus
-PK11_GenerateRandom(unsigned char *data,int len) {
- PK11SlotInfo *slot;
- SECStatus rv;
-
- slot = PK11_GetBestSlot(CKM_FAKE_RANDOM,NULL);
- if (slot == NULL) return SECFailure;
-
- rv = PK11_GenerateRandomOnSlot(slot, data, len);
- PK11_FreeSlot(slot);
- return rv;
-}
-
-/*
- * Reset the token to it's initial state. For the internal module, this will
- * Purge your keydb, and reset your cert db certs to USER_INIT.
- */
-SECStatus
-PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
-{
- unsigned char tokenName[32];
- int tokenNameLen;
- CK_RV crv;
-
- /* reconstruct the token name */
- tokenNameLen = PORT_Strlen(slot->token_name);
- if (tokenNameLen > sizeof(tokenName)) {
- tokenNameLen = sizeof(tokenName);
- }
-
- PORT_Memcpy(tokenName,slot->token_name,tokenNameLen);
- if (tokenNameLen < sizeof(tokenName)) {
- PORT_Memset(&tokenName[tokenNameLen],' ',
- sizeof(tokenName)-tokenNameLen);
- }
-
- /* initialize the token */
- PK11_EnterSlotMonitor(slot);
-
- /* first shutdown the token. Existing sessions will get closed here */
- PK11_GETTAB(slot)->C_CloseAllSessions(slot->slotID);
- slot->session = CK_INVALID_SESSION;
-
- /* now re-init the token */
- crv = PK11_GETTAB(slot)->C_InitToken(slot->slotID,
- (unsigned char *)sso_pwd, sso_pwd ? PORT_Strlen(sso_pwd): 0, tokenName);
-
- /* finally bring the token back up */
- PK11_InitToken(slot,PR_TRUE);
- PK11_ExitSlotMonitor(slot);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain,
- slot->nssToken);
- return SECSuccess;
-}
-void
-PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst)
-{
- sl->nssToken = nsst;
-}
-
-NSSToken *
-PK11Slot_GetNSSToken(PK11SlotInfo *sl)
-{
- return sl->nssToken;
-}
-
-/*
- * wait for a token to change it's state. The application passes in the expected
- * new state in event.
- */
-PK11TokenStatus
-PK11_WaitForTokenEvent(PK11SlotInfo *slot, PK11TokenEvent event,
- PRIntervalTime timeout, PRIntervalTime latency, int series)
-{
- PRIntervalTime first_time = 0;
- PRBool first_time_set = PR_FALSE;
- PRBool waitForRemoval;
-
- if (slot->isPerm) {
- return PK11TokenNotRemovable;
- }
- if (latency == 0) {
- latency = PR_SecondsToInterval(5);
- }
- waitForRemoval = (PRBool) (event == PK11TokenRemovedOrChangedEvent);
-
- if (series == 0) {
- series = PK11_GetSlotSeries(slot);
- }
- while (PK11_IsPresent(slot) == waitForRemoval ) {
- PRIntervalTime interval;
-
- if (waitForRemoval && series != PK11_GetSlotSeries(slot)) {
- return PK11TokenChanged;
- }
- if (timeout == PR_INTERVAL_NO_WAIT) {
- return waitForRemoval ? PK11TokenPresent : PK11TokenRemoved;
- }
- if (timeout != PR_INTERVAL_NO_TIMEOUT ) {
- interval = PR_IntervalNow();
- if (!first_time_set) {
- first_time = interval;
- first_time_set = PR_TRUE;
- }
- if ((interval-first_time) > timeout) {
- return waitForRemoval ? PK11TokenPresent : PK11TokenRemoved;
- }
- }
- PR_Sleep(latency);
- }
- return waitForRemoval ? PK11TokenRemoved : PK11TokenPresent;
-}
diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c
deleted file mode 100644
index 31b48496a..000000000
--- a/security/nss/lib/pk11wrap/pk11util.c
+++ /dev/null
@@ -1,1578 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Initialize the PCKS 11 subsystem
- */
-#include "seccomon.h"
-#include "secmod.h"
-#include "nssilock.h"
-#include "secmodi.h"
-#include "secmodti.h"
-#include "pk11func.h"
-#include "pki3hack.h"
-#include "secerr.h"
-#include "dev.h"
-#include "utilpars.h"
-
-/* these are for displaying error messages */
-
-static SECMODModuleList *modules = NULL;
-static SECMODModuleList *modulesDB = NULL;
-static SECMODModuleList *modulesUnload = NULL;
-static SECMODModule *internalModule = NULL;
-static SECMODModule *defaultDBModule = NULL;
-static SECMODModule *pendingModule = NULL;
-static SECMODListLock *moduleLock = NULL;
-
-int secmod_PrivateModuleCount = 0;
-
-extern PK11DefaultArrayEntry PK11_DefaultArray[];
-extern int num_pk11_default_mechanisms;
-
-
-void
-SECMOD_Init()
-{
- /* don't initialize twice */
- if (moduleLock) return;
-
- moduleLock = SECMOD_NewListLock();
- PK11_InitSlotLists();
-}
-
-
-SECStatus
-SECMOD_Shutdown()
-{
- /* destroy the lock */
- if (moduleLock) {
- SECMOD_DestroyListLock(moduleLock);
- moduleLock = NULL;
- }
- /* free the internal module */
- if (internalModule) {
- SECMOD_DestroyModule(internalModule);
- internalModule = NULL;
- }
-
- /* free the default database module */
- if (defaultDBModule) {
- SECMOD_DestroyModule(defaultDBModule);
- defaultDBModule = NULL;
- }
-
- /* destroy the list */
- if (modules) {
- SECMOD_DestroyModuleList(modules);
- modules = NULL;
- }
-
- if (modulesDB) {
- SECMOD_DestroyModuleList(modulesDB);
- modulesDB = NULL;
- }
-
- if (modulesUnload) {
- SECMOD_DestroyModuleList(modulesUnload);
- modulesUnload = NULL;
- }
-
- /* make all the slots and the lists go away */
- PK11_DestroySlotLists();
-
- nss_DumpModuleLog();
-
-#ifdef DEBUG
- if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) {
- PORT_Assert(secmod_PrivateModuleCount == 0);
- }
-#endif
- if (secmod_PrivateModuleCount) {
- PORT_SetError(SEC_ERROR_BUSY);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-
-/*
- * retrieve the internal module
- */
-SECMODModule *
-SECMOD_GetInternalModule(void)
-{
- return internalModule;
-}
-
-
-SECStatus
-secmod_AddModuleToList(SECMODModuleList **moduleList,SECMODModule *newModule)
-{
- SECMODModuleList *mlp, *newListElement, *last = NULL;
-
- newListElement = SECMOD_NewModuleListElement();
- if (newListElement == NULL) {
- return SECFailure;
- }
-
- newListElement->module = SECMOD_ReferenceModule(newModule);
-
- SECMOD_GetWriteLock(moduleLock);
- /* Added it to the end (This is very inefficient, but Adding a module
- * on the fly should happen maybe 2-3 times through the life this program
- * on a given computer, and this list should be *SHORT*. */
- for(mlp = *moduleList; mlp != NULL; mlp = mlp->next) {
- last = mlp;
- }
-
- if (last == NULL) {
- *moduleList = newListElement;
- } else {
- SECMOD_AddList(last,newListElement,NULL);
- }
- SECMOD_ReleaseWriteLock(moduleLock);
- return SECSuccess;
-}
-
-SECStatus
-SECMOD_AddModuleToList(SECMODModule *newModule)
-{
- if (newModule->internal && !internalModule) {
- internalModule = SECMOD_ReferenceModule(newModule);
- }
- return secmod_AddModuleToList(&modules,newModule);
-}
-
-SECStatus
-SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule)
-{
- if (defaultDBModule && SECMOD_GetDefaultModDBFlag(newModule)) {
- SECMOD_DestroyModule(defaultDBModule);
- defaultDBModule = SECMOD_ReferenceModule(newModule);
- } else if (defaultDBModule == NULL) {
- defaultDBModule = SECMOD_ReferenceModule(newModule);
- }
- return secmod_AddModuleToList(&modulesDB,newModule);
-}
-
-SECStatus
-SECMOD_AddModuleToUnloadList(SECMODModule *newModule)
-{
- return secmod_AddModuleToList(&modulesUnload,newModule);
-}
-
-/*
- * get the list of PKCS11 modules that are available.
- */
-SECMODModuleList * SECMOD_GetDefaultModuleList() { return modules; }
-SECMODModuleList *SECMOD_GetDeadModuleList() { return modulesUnload; }
-SECMODModuleList *SECMOD_GetDBModuleList() { return modulesDB; }
-
-/*
- * This lock protects the global module lists.
- * it also protects changes to the slot array (module->slots[]) and slot count
- * (module->slotCount) in each module. It is a read/write lock with multiple
- * readers or one writer. Writes are uncommon.
- * Because of legacy considerations protection of the slot array and count is
- * only necessary in applications if the application calls
- * SECMOD_UpdateSlotList() or SECMOD_WaitForAnyTokenEvent(), though all new
- * applications are encouraged to acquire this lock when reading the
- * slot array information directly.
- */
-SECMODListLock *SECMOD_GetDefaultModuleListLock() { return moduleLock; }
-
-
-
-/*
- * find a module by name, and add a reference to it.
- * return that module.
- */
-SECMODModule *
-SECMOD_FindModule(const char *name)
-{
- SECMODModuleList *mlp;
- SECMODModule *module = NULL;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return module;
- }
- SECMOD_GetReadLock(moduleLock);
- for(mlp = modules; mlp != NULL; mlp = mlp->next) {
- if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
- module = mlp->module;
- SECMOD_ReferenceModule(module);
- break;
- }
- }
- if (module) {
- goto found;
- }
- for(mlp = modulesUnload; mlp != NULL; mlp = mlp->next) {
- if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
- module = mlp->module;
- SECMOD_ReferenceModule(module);
- break;
- }
- }
-
-found:
- SECMOD_ReleaseReadLock(moduleLock);
-
- return module;
-}
-
-/*
- * find a module by ID, and add a reference to it.
- * return that module.
- */
-SECMODModule *
-SECMOD_FindModuleByID(SECMODModuleID id)
-{
- SECMODModuleList *mlp;
- SECMODModule *module = NULL;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return module;
- }
- SECMOD_GetReadLock(moduleLock);
- for(mlp = modules; mlp != NULL; mlp = mlp->next) {
- if (id == mlp->module->moduleID) {
- module = mlp->module;
- SECMOD_ReferenceModule(module);
- break;
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
- if (module == NULL) {
- PORT_SetError(SEC_ERROR_NO_MODULE);
- }
- return module;
-}
-
-/*
- * find the function pointer.
- */
-SECMODModule *
-secmod_FindModuleByFuncPtr(void *funcPtr)
-{
- SECMODModuleList *mlp;
- SECMODModule *module = NULL;
-
- SECMOD_GetReadLock(moduleLock);
- for(mlp = modules; mlp != NULL; mlp = mlp->next) {
- /* paranoia, shouldn't ever happen */
- if (!mlp->module) {
- continue;
- }
- if (funcPtr == mlp->module->functionList) {
- module = mlp->module;
- SECMOD_ReferenceModule(module);
- break;
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
- if (module == NULL) {
- PORT_SetError(SEC_ERROR_NO_MODULE);
- }
- return module;
-}
-
-/*
- * Find the Slot based on ID and the module.
- */
-PK11SlotInfo *
-SECMOD_FindSlotByID(SECMODModule *module, CK_SLOT_ID slotID)
-{
- int i;
- PK11SlotInfo *slot = NULL;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return slot;
- }
- SECMOD_GetReadLock(moduleLock);
- for (i=0; i < module->slotCount; i++) {
- PK11SlotInfo *cSlot = module->slots[i];
-
- if (cSlot->slotID == slotID) {
- slot = PK11_ReferenceSlot(cSlot);
- break;
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
-
- if (slot == NULL) {
- PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
- }
- return slot;
-}
-
-/*
- * lookup the Slot module based on it's module ID and slot ID.
- */
-PK11SlotInfo *
-SECMOD_LookupSlot(SECMODModuleID moduleID,CK_SLOT_ID slotID)
-{
- SECMODModule *module;
- PK11SlotInfo *slot;
-
- module = SECMOD_FindModuleByID(moduleID);
- if (module == NULL) return NULL;
-
- slot = SECMOD_FindSlotByID(module, slotID);
- SECMOD_DestroyModule(module);
- return slot;
-}
-
-
-/*
- * find a module by name or module pointer and delete it off the module list.
- * optionally remove it from secmod.db.
- */
-SECStatus
-SECMOD_DeleteModuleEx(const char *name, SECMODModule *mod,
- int *type, PRBool permdb)
-{
- SECMODModuleList *mlp;
- SECMODModuleList **mlpp;
- SECStatus rv = SECFailure;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return rv;
- }
-
- *type = SECMOD_EXTERNAL;
-
- SECMOD_GetWriteLock(moduleLock);
- for (mlpp = &modules,mlp = modules;
- mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
- if ((name && (PORT_Strcmp(name,mlp->module->commonName) == 0)) ||
- mod == mlp->module) {
- /* don't delete the internal module */
- if (!mlp->module->internal) {
- SECMOD_RemoveList(mlpp,mlp);
- /* delete it after we release the lock */
- rv = STAN_RemoveModuleFromDefaultTrustDomain(mlp->module);
- } else if (mlp->module->isFIPS) {
- *type = SECMOD_FIPS;
- } else {
- *type = SECMOD_INTERNAL;
- }
- break;
- }
- }
- if (mlp) {
- goto found;
- }
- /* not on the internal list, check the unload list */
- for (mlpp = &modulesUnload,mlp = modulesUnload;
- mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
- if ((name && (PORT_Strcmp(name,mlp->module->commonName) == 0)) ||
- mod == mlp->module) {
- /* don't delete the internal module */
- if (!mlp->module->internal) {
- SECMOD_RemoveList(mlpp,mlp);
- rv = SECSuccess;
- } else if (mlp->module->isFIPS) {
- *type = SECMOD_FIPS;
- } else {
- *type = SECMOD_INTERNAL;
- }
- break;
- }
- }
-found:
- SECMOD_ReleaseWriteLock(moduleLock);
-
-
- if (rv == SECSuccess) {
- if (permdb) {
- SECMOD_DeletePermDB(mlp->module);
- }
- SECMOD_DestroyModuleListElement(mlp);
- }
- return rv;
-}
-
-/*
- * find a module by name and delete it off the module list
- */
-SECStatus
-SECMOD_DeleteModule(const char *name, int *type)
-{
- return SECMOD_DeleteModuleEx(name, NULL, type, PR_TRUE);
-}
-
-/*
- * find a module by name and delete it off the module list
- */
-SECStatus
-SECMOD_DeleteInternalModule(const char *name)
-{
- SECMODModuleList *mlp;
- SECMODModuleList **mlpp;
- SECStatus rv = SECFailure;
-
- if (pendingModule) {
- PORT_SetError(SEC_ERROR_MODULE_STUCK);
- return rv;
- }
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return rv;
- }
-
- SECMOD_GetWriteLock(moduleLock);
- for(mlpp = &modules,mlp = modules;
- mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
- if (PORT_Strcmp(name,mlp->module->commonName) == 0) {
- /* don't delete the internal module */
- if (mlp->module->internal) {
- SECMOD_RemoveList(mlpp,mlp);
- rv = STAN_RemoveModuleFromDefaultTrustDomain(mlp->module);
- }
- break;
- }
- }
- SECMOD_ReleaseWriteLock(moduleLock);
-
- if (rv == SECSuccess) {
- SECMODModule *newModule,*oldModule;
-
- if (mlp->module->isFIPS) {
- newModule = SECMOD_CreateModule(NULL, SECMOD_INT_NAME,
- NULL, SECMOD_INT_FLAGS);
- } else {
- newModule = SECMOD_CreateModule(NULL, SECMOD_FIPS_NAME,
- NULL, SECMOD_FIPS_FLAGS);
- }
- if (newModule) {
- PK11SlotInfo *slot;
- newModule->libraryParams =
- PORT_ArenaStrdup(newModule->arena,mlp->module->libraryParams);
- /* if an explicit internal key slot has been set, reset it */
- slot = pk11_SwapInternalKeySlot(NULL);
- if (slot) {
- secmod_SetInternalKeySlotFlag(newModule, PR_TRUE);
- }
- rv = SECMOD_AddModule(newModule);
- if (rv != SECSuccess) {
- /* load failed, restore the internal key slot */
- pk11_SetInternalKeySlot(slot);
- SECMOD_DestroyModule(newModule);
- newModule = NULL;
- }
- /* free the old explicit internal key slot, we now have a new one */
- if (slot) {
- PK11_FreeSlot(slot);
- }
- }
- if (newModule == NULL) {
- SECMODModuleList *last = NULL,*mlp2;
- /* we're in pretty deep trouble if this happens...Security
- * not going to work well... try to put the old module back on
- * the list */
- SECMOD_GetWriteLock(moduleLock);
- for(mlp2 = modules; mlp2 != NULL; mlp2 = mlp->next) {
- last = mlp2;
- }
-
- if (last == NULL) {
- modules = mlp;
- } else {
- SECMOD_AddList(last,mlp,NULL);
- }
- SECMOD_ReleaseWriteLock(moduleLock);
- return SECFailure;
- }
- pendingModule = oldModule = internalModule;
- internalModule = NULL;
- SECMOD_DestroyModule(oldModule);
- SECMOD_DeletePermDB(mlp->module);
- SECMOD_DestroyModuleListElement(mlp);
- internalModule = newModule; /* adopt the module */
- }
- return rv;
-}
-
-SECStatus
-SECMOD_AddModule(SECMODModule *newModule)
-{
- SECStatus rv;
- SECMODModule *oldModule;
-
- /* Test if a module w/ the same name already exists */
- /* and return SECWouldBlock if so. */
- /* We should probably add a new return value such as */
- /* SECDublicateModule, but to minimize ripples, I'll */
- /* give SECWouldBlock a new meaning */
- if ((oldModule = SECMOD_FindModule(newModule->commonName)) != NULL) {
- SECMOD_DestroyModule(oldModule);
- return SECWouldBlock;
- /* module already exists. */
- }
-
- rv = secmod_LoadPKCS11Module(newModule, NULL);
- if (rv != SECSuccess) {
- return rv;
- }
-
- if (newModule->parent == NULL) {
- newModule->parent = SECMOD_ReferenceModule(defaultDBModule);
- }
-
- SECMOD_AddPermDB(newModule);
- SECMOD_AddModuleToList(newModule);
-
- rv = STAN_AddModuleToDefaultTrustDomain(newModule);
-
- return rv;
-}
-
-PK11SlotInfo *
-SECMOD_FindSlot(SECMODModule *module,const char *name)
-{
- int i;
- char *string;
- PK11SlotInfo *retSlot = NULL;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return retSlot;
- }
- SECMOD_GetReadLock(moduleLock);
- for (i=0; i < module->slotCount; i++) {
- PK11SlotInfo *slot = module->slots[i];
-
- if (PK11_IsPresent(slot)) {
- string = PK11_GetTokenName(slot);
- } else {
- string = PK11_GetSlotName(slot);
- }
- if (PORT_Strcmp(name,string) == 0) {
- retSlot = PK11_ReferenceSlot(slot);
- break;
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
-
- if (retSlot == NULL) {
- PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
- }
- return retSlot;
-}
-
-SECStatus
-PK11_GetModInfo(SECMODModule *mod,CK_INFO *info)
-{
- CK_RV crv;
-
- if (mod->functionList == NULL) return SECFailure;
- crv = PK11_GETTAB(mod)->C_GetInfo(info);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- }
- return (crv == CKR_OK) ? SECSuccess : SECFailure;
-}
-
-/* Determine if we have the FIP's module loaded as the default
- * module to trigger other bogus FIPS requirements in PKCS #12 and
- * SSL
- */
-PRBool
-PK11_IsFIPS(void)
-{
- SECMODModule *mod = SECMOD_GetInternalModule();
-
- if (mod && mod->internal) {
- return mod->isFIPS;
- }
-
- return PR_FALSE;
-}
-
-/* combines NewModule() & AddModule */
-/* give a string for the module name & the full-path for the dll, */
-/* installs the PKCS11 module & update registry */
-SECStatus
-SECMOD_AddNewModuleEx(const char* moduleName, const char* dllPath,
- unsigned long defaultMechanismFlags,
- unsigned long cipherEnableFlags,
- char* modparms, char* nssparms)
-{
- SECMODModule *module;
- SECStatus result = SECFailure;
- int s,i;
- PK11SlotInfo* slot;
-
- PR_SetErrorText(0, NULL);
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return result;
- }
-
- module = SECMOD_CreateModule(dllPath, moduleName, modparms, nssparms);
-
- if (module == NULL) {
- return result;
- }
-
- if (module->dllName != NULL) {
- if (module->dllName[0] != 0) {
- result = SECMOD_AddModule(module);
- if (result == SECSuccess) {
- /* turn on SSL cipher enable flags */
- module->ssl[0] = cipherEnableFlags;
-
- SECMOD_GetReadLock(moduleLock);
- /* check each slot to turn on appropriate mechanisms */
- for (s = 0; s < module->slotCount; s++) {
- slot = (module->slots)[s];
- /* for each possible mechanism */
- for (i=0; i < num_pk11_default_mechanisms; i++) {
- /* we are told to turn it on by default ? */
- PRBool add =
- (PK11_DefaultArray[i].flag & defaultMechanismFlags) ?
- PR_TRUE: PR_FALSE;
- result = PK11_UpdateSlotAttribute(slot,
- &(PK11_DefaultArray[i]), add);
- } /* for each mechanism */
- /* disable each slot if the defaultFlags say so */
- if (defaultMechanismFlags & PK11_DISABLE_FLAG) {
- PK11_UserDisableSlot(slot);
- }
- } /* for each slot of this module */
- SECMOD_ReleaseReadLock(moduleLock);
-
- /* delete and re-add module in order to save changes
- * to the module */
- result = SECMOD_UpdateModule(module);
- }
- }
- }
- SECMOD_DestroyModule(module);
- return result;
-}
-
-SECStatus
-SECMOD_AddNewModule(const char* moduleName, const char* dllPath,
- unsigned long defaultMechanismFlags,
- unsigned long cipherEnableFlags)
-{
- return SECMOD_AddNewModuleEx(moduleName, dllPath, defaultMechanismFlags,
- cipherEnableFlags,
- NULL, NULL); /* don't pass module or nss params */
-}
-
-SECStatus
-SECMOD_UpdateModule(SECMODModule *module)
-{
- SECStatus result;
-
- result = SECMOD_DeletePermDB(module);
-
- if (result == SECSuccess) {
- result = SECMOD_AddPermDB(module);
- }
- return result;
-}
-
-/* Public & Internal(Security Library) representation of
- * encryption mechanism flags conversion */
-
-/* Currently, the only difference is that internal representation
- * puts RANDOM_FLAG at bit 31 (Most-significant bit), but
- * public representation puts this bit at bit 28
- */
-unsigned long
-SECMOD_PubMechFlagstoInternal(unsigned long publicFlags)
-{
- unsigned long internalFlags = publicFlags;
-
- if (publicFlags & PUBLIC_MECH_RANDOM_FLAG) {
- internalFlags &= ~PUBLIC_MECH_RANDOM_FLAG;
- internalFlags |= SECMOD_RANDOM_FLAG;
- }
- return internalFlags;
-}
-
-unsigned long
-SECMOD_InternaltoPubMechFlags(unsigned long internalFlags)
-{
- unsigned long publicFlags = internalFlags;
-
- if (internalFlags & SECMOD_RANDOM_FLAG) {
- publicFlags &= ~SECMOD_RANDOM_FLAG;
- publicFlags |= PUBLIC_MECH_RANDOM_FLAG;
- }
- return publicFlags;
-}
-
-
-/* Public & Internal(Security Library) representation of */
-/* cipher flags conversion */
-/* Note: currently they are just stubs */
-unsigned long
-SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags)
-{
- return publicFlags;
-}
-
-unsigned long
-SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags)
-{
- return internalFlags;
-}
-
-/* Funtion reports true if module of modType is installed/configured */
-PRBool
-SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags )
-{
- PRBool result = PR_FALSE;
- SECMODModuleList *mods;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return result;
- }
- SECMOD_GetReadLock(moduleLock);
- mods = SECMOD_GetDefaultModuleList();
- for ( ; mods != NULL; mods = mods->next) {
- if (mods->module->ssl[0] &
- SECMOD_PubCipherFlagstoInternal(pubCipherEnableFlags)) {
- result = PR_TRUE;
- }
- }
-
- SECMOD_ReleaseReadLock(moduleLock);
- return result;
-}
-
-/* create a new ModuleListElement */
-SECMODModuleList *SECMOD_NewModuleListElement(void)
-{
- SECMODModuleList *newModList;
-
- newModList= (SECMODModuleList *) PORT_Alloc(sizeof(SECMODModuleList));
- if (newModList) {
- newModList->next = NULL;
- newModList->module = NULL;
- }
- return newModList;
-}
-
-/*
- * make a new reference to a module so It doesn't go away on us
- */
-SECMODModule *
-SECMOD_ReferenceModule(SECMODModule *module)
-{
- PZ_Lock(module->refLock);
- PORT_Assert(module->refCount > 0);
-
- module->refCount++;
- PZ_Unlock(module->refLock);
- return module;
-}
-
-
-/* destroy an existing module */
-void
-SECMOD_DestroyModule(SECMODModule *module)
-{
- PRBool willfree = PR_FALSE;
- int slotCount;
- int i;
-
- PZ_Lock(module->refLock);
- if (module->refCount-- == 1) {
- willfree = PR_TRUE;
- }
- PORT_Assert(willfree || (module->refCount > 0));
- PZ_Unlock(module->refLock);
-
- if (!willfree) {
- return;
- }
-
- if (module->parent != NULL) {
- SECMODModule *parent = module->parent;
- /* paranoia, don't loop forever if the modules are looped */
- module->parent = NULL;
- SECMOD_DestroyModule(parent);
- }
-
- /* slots can't really disappear until our module starts freeing them,
- * so this check is safe */
- slotCount = module->slotCount;
- if (slotCount == 0) {
- SECMOD_SlotDestroyModule(module,PR_FALSE);
- return;
- }
-
- /* now free all out slots, when they are done, they will cause the
- * module to disappear altogether */
- for (i=0 ; i < slotCount; i++) {
- if (!module->slots[i]->disabled) {
- PK11_ClearSlotList(module->slots[i]);
- }
- PK11_FreeSlot(module->slots[i]);
- }
- /* WARNING: once the last slot has been freed is it possible (even likely)
- * that module is no more... touching it now is a good way to go south */
-}
-
-
-/* we can only get here if we've destroyed the module, or some one has
- * erroneously freed a slot that wasn't referenced. */
-void
-SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot)
-{
- PRBool willfree = PR_FALSE;
- if (fromSlot) {
- PORT_Assert(module->refCount == 0);
- PZ_Lock(module->refLock);
- if (module->slotCount-- == 1) {
- willfree = PR_TRUE;
- }
- PORT_Assert(willfree || (module->slotCount > 0));
- PZ_Unlock(module->refLock);
- if (!willfree) return;
- }
-
- if (module == pendingModule) {
- pendingModule = NULL;
- }
-
- if (module->loaded) {
- SECMOD_UnloadModule(module);
- }
- PZ_DestroyLock(module->refLock);
- PORT_FreeArena(module->arena,PR_FALSE);
- secmod_PrivateModuleCount--;
-}
-
-/* destroy a list element
- * this destroys a single element, and returns the next element
- * on the chain. It makes it easy to implement for loops to delete
- * the chain. It also make deleting a single element easy */
-SECMODModuleList *
-SECMOD_DestroyModuleListElement(SECMODModuleList *element)
-{
- SECMODModuleList *next = element->next;
-
- if (element->module) {
- SECMOD_DestroyModule(element->module);
- element->module = NULL;
- }
- PORT_Free(element);
- return next;
-}
-
-
-/*
- * Destroy an entire module list
- */
-void
-SECMOD_DestroyModuleList(SECMODModuleList *list)
-{
- SECMODModuleList *lp;
-
- for ( lp = list; lp != NULL; lp = SECMOD_DestroyModuleListElement(lp)) ;
-}
-
-PRBool
-SECMOD_CanDeleteInternalModule(void)
-{
- return (PRBool) (pendingModule == NULL);
-}
-
-/*
- * check to see if the module has added new slots. PKCS 11 v2.20 allows for
- * modules to add new slots, but never remove them. Slots cannot be added
- * between a call to C_GetSlotLlist(Flag, NULL, &count) and the subsequent
- * C_GetSlotList(flag, &data, &count) so that the array doesn't accidently
- * grow on the caller. It is permissible for the slots to increase between
- * successive calls with NULL to get the size.
- */
-SECStatus
-SECMOD_UpdateSlotList(SECMODModule *mod)
-{
- CK_RV crv;
- CK_ULONG count;
- CK_ULONG i, oldCount;
- PRBool freeRef = PR_FALSE;
- void *mark = NULL;
- CK_ULONG *slotIDs = NULL;
- PK11SlotInfo **newSlots = NULL;
- PK11SlotInfo **oldSlots = NULL;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
-
- /* C_GetSlotList is not a session function, make sure
- * calls are serialized */
- PZ_Lock(mod->refLock);
- freeRef = PR_TRUE;
- /* see if the number of slots have changed */
- crv = PK11_GETTAB(mod)->C_GetSlotList(PR_FALSE, NULL, &count);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- goto loser;
- }
- /* nothing new, blow out early, we want this function to be quick
- * and cheap in the normal case */
- if (count == mod->slotCount) {
- PZ_Unlock(mod->refLock);
- return SECSuccess;
- }
- if (count < (CK_ULONG)mod->slotCount) {
- /* shouldn't happen with a properly functioning PKCS #11 module */
- PORT_SetError( SEC_ERROR_INCOMPATIBLE_PKCS11 );
- goto loser;
- }
-
- /* get the new slot list */
- slotIDs = PORT_NewArray(CK_SLOT_ID, count);
- if (slotIDs == NULL) {
- goto loser;
- }
-
- crv = PK11_GETTAB(mod)->C_GetSlotList(PR_FALSE, slotIDs, &count);
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- goto loser;
- }
- freeRef = PR_FALSE;
- PZ_Unlock(mod->refLock);
- mark = PORT_ArenaMark(mod->arena);
- if (mark == NULL) {
- goto loser;
- }
- newSlots = PORT_ArenaZNewArray(mod->arena,PK11SlotInfo *,count);
-
- /* walk down the new slot ID list returned from the module. We keep
- * the old slots which match a returned ID, and we initialize the new
- * slots. */
- for (i=0; i < count; i++) {
- PK11SlotInfo *slot = SECMOD_FindSlotByID(mod,slotIDs[i]);
-
- if (!slot) {
- /* we have a new slot create a new slot data structure */
- slot = PK11_NewSlotInfo(mod);
- if (!slot) {
- goto loser;
- }
- PK11_InitSlot(mod, slotIDs[i], slot);
- STAN_InitTokenForSlotInfo(NULL, slot);
- }
- newSlots[i] = slot;
- }
- STAN_ResetTokenInterator(NULL);
- PORT_Free(slotIDs);
- slotIDs = NULL;
- PORT_ArenaUnmark(mod->arena, mark);
-
- /* until this point we're still using the old slot list. Now we update
- * module slot list. We update the slots (array) first then the count,
- * since we've already guarrenteed that count has increased (just in case
- * someone is looking at the slots field of module without holding the
- * moduleLock */
- SECMOD_GetWriteLock(moduleLock);
- oldCount =mod->slotCount;
- oldSlots = mod->slots;
- mod->slots = newSlots; /* typical arena 'leak'... old mod->slots is
- * allocated out of the module arena and won't
- * be freed until the module is freed */
- mod->slotCount = count;
- SECMOD_ReleaseWriteLock(moduleLock);
- /* free our old references before forgetting about oldSlot*/
- for (i=0; i < oldCount; i++) {
- PK11_FreeSlot(oldSlots[i]);
- }
- return SECSuccess;
-
-loser:
- if (freeRef) {
- PZ_Unlock(mod->refLock);
- }
- if (slotIDs) {
- PORT_Free(slotIDs);
- }
- /* free all the slots we allocated. newSlots are part of the
- * mod arena. NOTE: the newSlots array contain both new and old
- * slots, but we kept a reference to the old slots when we built the new
- * array, so we need to free all the slots in newSlots array. */
- if (newSlots) {
- for (i=0; i < count; i++) {
- if (newSlots[i] == NULL) {
- break; /* hit the last one */
- }
- PK11_FreeSlot(newSlots[i]);
- }
- }
- /* must come after freeing newSlots */
- if (mark) {
- PORT_ArenaRelease(mod->arena, mark);
- }
- return SECFailure;
-}
-
-/*
- * this handles modules that do not support C_WaitForSlotEvent().
- * The internal flags are stored. Note that C_WaitForSlotEvent() does not
- * have a timeout, so we don't have one for handleWaitForSlotEvent() either.
- */
-PK11SlotInfo *
-secmod_HandleWaitForSlotEvent(SECMODModule *mod, unsigned long flags,
- PRIntervalTime latency)
-{
- PRBool removableSlotsFound = PR_FALSE;
- int i;
- int error = SEC_ERROR_NO_EVENT;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return NULL;
- }
- PZ_Lock(mod->refLock);
- if (mod->evControlMask & SECMOD_END_WAIT) {
- mod->evControlMask &= ~SECMOD_END_WAIT;
- PZ_Unlock(mod->refLock);
- PORT_SetError(SEC_ERROR_NO_EVENT);
- return NULL;
- }
- mod->evControlMask |= SECMOD_WAIT_SIMULATED_EVENT;
- while (mod->evControlMask & SECMOD_WAIT_SIMULATED_EVENT) {
- PZ_Unlock(mod->refLock);
- /* now is a good time to see if new slots have been added */
- SECMOD_UpdateSlotList(mod);
-
- /* loop through all the slots on a module */
- SECMOD_GetReadLock(moduleLock);
- for (i=0; i < mod->slotCount; i++) {
- PK11SlotInfo *slot = mod->slots[i];
- uint16 series;
- PRBool present;
-
- /* perm modules do not change */
- if (slot->isPerm) {
- continue;
- }
- removableSlotsFound = PR_TRUE;
- /* simulate the PKCS #11 module flags. are the flags different
- * from the last time we called? */
- series = slot->series;
- present = PK11_IsPresent(slot);
- if ((slot->flagSeries != series) || (slot->flagState != present)) {
- slot->flagState = present;
- slot->flagSeries = series;
- SECMOD_ReleaseReadLock(moduleLock);
- PZ_Lock(mod->refLock);
- mod->evControlMask &= ~SECMOD_END_WAIT;
- PZ_Unlock(mod->refLock);
- return PK11_ReferenceSlot(slot);
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
- /* if everything was perm modules, don't lock up forever */
- if ((mod->slotCount !=0) && !removableSlotsFound) {
- error =SEC_ERROR_NO_SLOT_SELECTED;
- PZ_Lock(mod->refLock);
- break;
- }
- if (flags & CKF_DONT_BLOCK) {
- PZ_Lock(mod->refLock);
- break;
- }
- PR_Sleep(latency);
- PZ_Lock(mod->refLock);
- }
- mod->evControlMask &= ~SECMOD_END_WAIT;
- PZ_Unlock(mod->refLock);
- PORT_SetError(error);
- return NULL;
-}
-
-/*
- * this function waits for a token event on any slot of a given module
- * This function should not be called from more than one thread of the
- * same process (though other threads can make other library calls
- * on this module while this call is blocked).
- */
-PK11SlotInfo *
-SECMOD_WaitForAnyTokenEvent(SECMODModule *mod, unsigned long flags,
- PRIntervalTime latency)
-{
- CK_SLOT_ID id;
- CK_RV crv;
- PK11SlotInfo *slot;
-
- if (!pk11_getFinalizeModulesOption() ||
- ((mod->cryptokiVersion.major == 2) &&
- (mod->cryptokiVersion.minor < 1))) {
- /* if we are sharing the module with other software in our
- * address space, we can't reliably use C_WaitForSlotEvent(),
- * and if the module is version 2.0, C_WaitForSlotEvent() doesn't
- * exist */
- return secmod_HandleWaitForSlotEvent(mod, flags, latency);
- }
- /* first the the PKCS #11 call */
- PZ_Lock(mod->refLock);
- if (mod->evControlMask & SECMOD_END_WAIT) {
- goto end_wait;
- }
- mod->evControlMask |= SECMOD_WAIT_PKCS11_EVENT;
- PZ_Unlock(mod->refLock);
- crv = PK11_GETTAB(mod)->C_WaitForSlotEvent(flags, &id, NULL);
- PZ_Lock(mod->refLock);
- mod->evControlMask &= ~SECMOD_WAIT_PKCS11_EVENT;
- /* if we are in end wait, short circuit now, don't even risk
- * going into secmod_HandleWaitForSlotEvent */
- if (mod->evControlMask & SECMOD_END_WAIT) {
- goto end_wait;
- }
- PZ_Unlock(mod->refLock);
- if (crv == CKR_FUNCTION_NOT_SUPPORTED) {
- /* module doesn't support that call, simulate it */
- return secmod_HandleWaitForSlotEvent(mod, flags, latency);
- }
- if (crv != CKR_OK) {
- /* we can get this error if finalize was called while we were
- * still running. This is the only way to force a C_WaitForSlotEvent()
- * to return in PKCS #11. In this case, just return that there
- * was no event. */
- if (crv == CKR_CRYPTOKI_NOT_INITIALIZED) {
- PORT_SetError(SEC_ERROR_NO_EVENT);
- } else {
- PORT_SetError(PK11_MapError(crv));
- }
- return NULL;
- }
- slot = SECMOD_FindSlotByID(mod, id);
- if (slot == NULL) {
- /* possibly a new slot that was added? */
- SECMOD_UpdateSlotList(mod);
- slot = SECMOD_FindSlotByID(mod, id);
- }
- /* if we are in the delay period for the "isPresent" call, reset
- * the delay since we know things have probably changed... */
- if (slot && slot->nssToken && slot->nssToken->slot) {
- nssSlot_ResetDelay(slot->nssToken->slot);
- }
- return slot;
-
- /* must be called with the lock on. */
-end_wait:
- mod->evControlMask &= ~SECMOD_END_WAIT;
- PZ_Unlock(mod->refLock);
- PORT_SetError(SEC_ERROR_NO_EVENT);
- return NULL;
-}
-
-/*
- * This function "wakes up" WaitForAnyTokenEvent. It's a pretty drastic
- * function, possibly bringing down the pkcs #11 module in question. This
- * should be OK because 1) it does reinitialize, and 2) it should only be
- * called when we are on our way to tear the whole system down anyway.
- */
-SECStatus
-SECMOD_CancelWait(SECMODModule *mod)
-{
- unsigned long controlMask = mod->evControlMask;
- SECStatus rv = SECSuccess;
- CK_RV crv;
-
- PZ_Lock(mod->refLock);
- mod->evControlMask |= SECMOD_END_WAIT;
- controlMask = mod->evControlMask;
- if (controlMask & SECMOD_WAIT_PKCS11_EVENT) {
- if (!pk11_getFinalizeModulesOption()) {
- /* can't get here unless pk11_getFinalizeModulesOption is set */
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- goto loser;
- }
- /* NOTE: this call will drop all transient keys, in progress
- * operations, and any authentication. This is the only documented
- * way to get WaitForSlotEvent to return. Also note: for non-thread
- * safe tokens, we need to hold the module lock, this is not yet at
- * system shutdown/startup time, so we need to protect these calls */
- crv = PK11_GETTAB(mod)->C_Finalize(NULL);
- /* ok, we slammed the module down, now we need to reinit it in case
- * we intend to use it again */
- if (CKR_OK == crv) {
- PRBool alreadyLoaded;
- secmod_ModuleInit(mod, NULL, &alreadyLoaded);
- } else {
- /* Finalized failed for some reason, notify the application
- * so maybe it has a prayer of recovering... */
- PORT_SetError(PK11_MapError(crv));
- rv = SECFailure;
- }
- } else if (controlMask & SECMOD_WAIT_SIMULATED_EVENT) {
- mod->evControlMask &= ~SECMOD_WAIT_SIMULATED_EVENT;
- /* Simulated events will eventually timeout
- * and wake up in the loop */
- }
-loser:
- PZ_Unlock(mod->refLock);
- return rv;
-}
-
-/*
- * check to see if the module has removable slots that we may need to
- * watch for.
- */
-PRBool
-SECMOD_HasRemovableSlots(SECMODModule *mod)
-{
- int i;
- PRBool ret = PR_FALSE;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return ret;
- }
- SECMOD_GetReadLock(moduleLock);
- for (i=0; i < mod->slotCount; i++) {
- PK11SlotInfo *slot = mod->slots[i];
- /* perm modules are not inserted or removed */
- if (slot->isPerm) {
- continue;
- }
- ret = PR_TRUE;
- break;
- }
- if (mod->slotCount == 0 ) {
- ret = PR_TRUE;
- }
- SECMOD_ReleaseReadLock(moduleLock);
- return ret;
-}
-
-/*
- * helper function to actually create and destroy user defined slots
- */
-static SECStatus
-secmod_UserDBOp(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass,
- const char *sendSpec)
-{
- CK_OBJECT_HANDLE dummy;
- CK_ATTRIBUTE template[2] ;
- CK_ATTRIBUTE *attrs = template;
- CK_RV crv;
-
- PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_NETSCAPE_MODULE_SPEC , (unsigned char *)sendSpec,
- strlen(sendSpec)+1); attrs++;
-
- PORT_Assert(attrs-template <= 2);
-
-
- PK11_EnterSlotMonitor(slot);
- crv = PK11_CreateNewObject(slot, slot->session,
- template, attrs-template, PR_FALSE, &dummy);
- PK11_ExitSlotMonitor(slot);
-
- if (crv != CKR_OK) {
- PORT_SetError(PK11_MapError(crv));
- return SECFailure;
- }
- return SECMOD_UpdateSlotList(slot->module);
-}
-
-/*
- * return true if the selected slot ID is not present or doesn't exist
- */
-static PRBool
-secmod_SlotIsEmpty(SECMODModule *mod, CK_SLOT_ID slotID)
-{
- PK11SlotInfo *slot = SECMOD_LookupSlot(mod->moduleID, slotID);
- if (slot) {
- PRBool present = PK11_IsPresent(slot);
- PK11_FreeSlot(slot);
- if (present) {
- return PR_FALSE;
- }
- }
- /* it doesn't exist or isn't present, it's available */
- return PR_TRUE;
-}
-
-/*
- * Find an unused slot id in module.
- */
-static CK_SLOT_ID
-secmod_FindFreeSlot(SECMODModule *mod)
-{
- CK_SLOT_ID i, minSlotID, maxSlotID;
-
- /* look for a free slot id on the internal module */
- if (mod->internal && mod->isFIPS) {
- minSlotID = SFTK_MIN_FIPS_USER_SLOT_ID;
- maxSlotID = SFTK_MAX_FIPS_USER_SLOT_ID;
- } else {
- minSlotID = SFTK_MIN_USER_SLOT_ID;
- maxSlotID = SFTK_MAX_USER_SLOT_ID;
- }
- for (i=minSlotID; i < maxSlotID; i++) {
- if (secmod_SlotIsEmpty(mod,i)) {
- return i;
- }
- }
- PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
- return (CK_SLOT_ID) -1;
-}
-
-/*
- * Attempt to open a new slot.
- *
- * This works the same os OpenUserDB except it can be called against
- * any module that understands the softoken protocol for opening new
- * slots, not just the softoken itself. If the selected module does not
- * understand the protocol, C_CreateObject will fail with
- * CKR_INVALID_ATTRIBUTE, and SECMOD_OpenNewSlot will return NULL and set
- * SEC_ERROR_BAD_DATA.
- *
- * NewSlots can be closed with SECMOD_CloseUserDB();
- *
- * Modulespec is module dependent.
- */
-PK11SlotInfo *
-SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec)
-{
- CK_SLOT_ID slotID = 0;
- PK11SlotInfo *slot;
- char *escSpec;
- char *sendSpec;
- SECStatus rv;
-
- slotID = secmod_FindFreeSlot(mod);
- if (slotID == (CK_SLOT_ID) -1) {
- return NULL;
- }
-
- if (mod->slotCount == 0) {
- return NULL;
- }
-
- /* just grab the first slot in the module, any present slot should work */
- slot = PK11_ReferenceSlot(mod->slots[0]);
- if (slot == NULL) {
- return NULL;
- }
-
- /* we've found the slot, now build the moduleSpec */
- escSpec = NSSUTIL_DoubleEscape(moduleSpec, '>', ']');
- if (escSpec == NULL) {
- PK11_FreeSlot(slot);
- return NULL;
- }
- sendSpec = PR_smprintf("tokens=[0x%x=<%s>]", slotID, escSpec);
- PORT_Free(escSpec);
-
- if (sendSpec == NULL) {
- /* PR_smprintf does not set SEC_ERROR_NO_MEMORY on failure. */
- PK11_FreeSlot(slot);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
- rv = secmod_UserDBOp(slot, CKO_NETSCAPE_NEWSLOT, sendSpec);
- PR_smprintf_free(sendSpec);
- PK11_FreeSlot(slot);
- if (rv != SECSuccess) {
- return NULL;
- }
-
- slot = SECMOD_FindSlotByID(mod, slotID);
- if (slot) {
- /* if we are in the delay period for the "isPresent" call, reset
- * the delay since we know things have probably changed... */
- if (slot->nssToken && slot->nssToken->slot) {
- nssSlot_ResetDelay(slot->nssToken->slot);
- }
- /* force the slot info structures to properly reset */
- (void)PK11_IsPresent(slot);
- }
- return slot;
-}
-
-/*
- * Open a new database using the softoken. The caller is responsible for making
- * sure the module spec is correct and usable. The caller should ask for one
- * new database per call if the caller wants to get meaningful information
- * about the new database.
- *
- * moduleSpec is the same data that you would pass to softoken at
- * initialization time under the 'tokens' options. For example, if you were
- * to specify tokens=<0x4=[configdir='./mybackup' tokenDescription='Backup']>
- * You would specify "configdir='./mybackup' tokenDescription='Backup'" as your
- * module spec here. The slot ID will be calculated for you by
- * SECMOD_OpenUserDB().
- *
- * Typical parameters here are configdir, tokenDescription and flags.
- *
- * a Full list is below:
- *
- *
- * configDir - The location of the databases for this token. If configDir is
- * not specified, and noCertDB and noKeyDB is not specified, the load
- * will fail.
- * certPrefix - Cert prefix for this token.
- * keyPrefix - Prefix for the key database for this token. (if not specified,
- * certPrefix will be used).
- * tokenDescription - The label value for this token returned in the
- * CK_TOKEN_INFO structure with an internationalize string (UTF8).
- * This value will be truncated at 32 bytes (no NULL, partial UTF8
- * characters dropped). You should specify a user friendly name here
- * as this is the value the token will be referred to in most
- * application UI's. You should make sure tokenDescription is unique.
- * slotDescription - The slotDescription value for this token returned
- * in the CK_SLOT_INFO structure with an internationalize string
- * (UTF8). This value will be truncated at 64 bytes (no NULL, partial
- * UTF8 characters dropped). This name will not change after the
- * database is closed. It should have some number to make this unique.
- * minPWLen - minimum password length for this token.
- * flags - comma separated list of flag values, parsed case-insensitive.
- * Valid flags are:
- * readOnly - Databases should be opened read only.
- * noCertDB - Don't try to open a certificate database.
- * noKeyDB - Don't try to open a key database.
- * forceOpen - Don't fail to initialize the token if the
- * databases could not be opened.
- * passwordRequired - zero length passwords are not acceptable
- * (valid only if there is a keyDB).
- * optimizeSpace - allocate smaller hash tables and lock tables.
- * When this flag is not specified, Softoken will allocate
- * large tables to prevent lock contention.
- */
-PK11SlotInfo *
-SECMOD_OpenUserDB(const char *moduleSpec)
-{
- SECMODModule *mod;
-
- if (moduleSpec == NULL) {
- return NULL;
- }
-
- /* NOTE: unlike most PK11 function, this does not return a reference
- * to the module */
- mod = SECMOD_GetInternalModule();
- if (!mod) {
- /* shouldn't happen */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
- return SECMOD_OpenNewSlot(mod, moduleSpec);
-}
-
-
-/*
- * close an already opened user database. NOTE: the database must be
- * in the internal token, and must be one created with SECMOD_OpenUserDB().
- * Once the database is closed, the slot will remain as an empty slot
- * until it's used again with SECMOD_OpenUserDB() or SECMOD_OpenNewSlot().
- */
-SECStatus
-SECMOD_CloseUserDB(PK11SlotInfo *slot)
-{
- SECStatus rv;
- char *sendSpec;
-
- sendSpec = PR_smprintf("tokens=[0x%x=<>]", slot->slotID);
- if (sendSpec == NULL) {
- /* PR_smprintf does not set no memory error */
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- rv = secmod_UserDBOp(slot, CKO_NETSCAPE_DELSLOT, sendSpec);
- PR_smprintf_free(sendSpec);
- return rv;
-}
-
-/*
- * Restart PKCS #11 modules after a fork(). See secmod.h for more information.
- */
-SECStatus
-SECMOD_RestartModules(PRBool force)
-{
- SECMODModuleList *mlp;
- SECStatus rrv = SECSuccess;
- int lastError = 0;
-
- if (!moduleLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
-
- /* Only need to restart the PKCS #11 modules that were initialized */
- SECMOD_GetReadLock(moduleLock);
- for (mlp = modules; mlp != NULL; mlp = mlp->next) {
- SECMODModule *mod = mlp->module;
- CK_ULONG count;
- SECStatus rv;
- int i;
-
- /* If the module needs to be reset, do so */
- if (force || (PK11_GETTAB(mod)->
- C_GetSlotList(CK_FALSE, NULL, &count) != CKR_OK)) {
- PRBool alreadyLoaded;
- /* first call Finalize. This is not required by PKCS #11, but some
- * older modules require it, and it doesn't hurt (compliant modules
- * will return CKR_NOT_INITIALIZED */
- (void) PK11_GETTAB(mod)->C_Finalize(NULL);
- /* now initialize the module, this function reinitializes
- * a module in place, preserving existing slots (even if they
- * no longer exist) */
- rv = secmod_ModuleInit(mod, NULL, &alreadyLoaded);
- if (rv != SECSuccess) {
- /* save the last error code */
- lastError = PORT_GetError();
- rrv = rv;
- /* couldn't reinit the module, disable all its slots */
- for (i=0; i < mod->slotCount; i++) {
- mod->slots[i]->disabled = PR_TRUE;
- mod->slots[i]->reason = PK11_DIS_COULD_NOT_INIT_TOKEN;
- }
- continue;
- }
- for (i=0; i < mod->slotCount; i++) {
- /* get new token sessions, bump the series up so that
- * we refresh other old sessions. This will tell much of
- * NSS to flush cached handles it may hold as well */
- rv = PK11_InitToken(mod->slots[i],PR_TRUE);
- /* PK11_InitToken could fail if the slot isn't present.
- * If it is present, though, something is wrong and we should
- * disable the slot and let the caller know. */
- if (rv != SECSuccess && PK11_IsPresent(mod->slots[i])) {
- /* save the last error code */
- lastError = PORT_GetError();
- rrv = rv;
- /* disable the token */
- mod->slots[i]->disabled = PR_TRUE;
- mod->slots[i]->reason = PK11_DIS_COULD_NOT_INIT_TOKEN;
- }
- }
- }
- }
- SECMOD_ReleaseReadLock(moduleLock);
-
- /*
- * on multiple failures, we are only returning the lastError. The caller
- * can determine which slots are bad by calling PK11_IsDisabled().
- */
- if (rrv != SECSuccess) {
- /* restore the last error code */
- PORT_SetError(lastError);
- }
-
- return rrv;
-}
diff --git a/security/nss/lib/pk11wrap/secmod.h b/security/nss/lib/pk11wrap/secmod.h
deleted file mode 100644
index c83d7e39f..000000000
--- a/security/nss/lib/pk11wrap/secmod.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _SECMOD_H_
-#define _SEDMOD_H_
-#include "seccomon.h"
-#include "secmodt.h"
-#include "prinrval.h"
-
-/* These mechanisms flags are visible to all other libraries. */
-/* They must be converted to internal SECMOD_*_FLAG */
-/* if used inside the functions of the security library */
-#define PUBLIC_MECH_RSA_FLAG 0x00000001ul
-#define PUBLIC_MECH_DSA_FLAG 0x00000002ul
-#define PUBLIC_MECH_RC2_FLAG 0x00000004ul
-#define PUBLIC_MECH_RC4_FLAG 0x00000008ul
-#define PUBLIC_MECH_DES_FLAG 0x00000010ul
-#define PUBLIC_MECH_DH_FLAG 0x00000020ul
-#define PUBLIC_MECH_FORTEZZA_FLAG 0x00000040ul
-#define PUBLIC_MECH_RC5_FLAG 0x00000080ul
-#define PUBLIC_MECH_SHA1_FLAG 0x00000100ul
-#define PUBLIC_MECH_MD5_FLAG 0x00000200ul
-#define PUBLIC_MECH_MD2_FLAG 0x00000400ul
-#define PUBLIC_MECH_SSL_FLAG 0x00000800ul
-#define PUBLIC_MECH_TLS_FLAG 0x00001000ul
-#define PUBLIC_MECH_AES_FLAG 0x00002000ul
-#define PUBLIC_MECH_SHA256_FLAG 0x00004000ul
-#define PUBLIC_MECH_SHA512_FLAG 0x00008000ul
-#define PUBLIC_MECH_CAMELLIA_FLAG 0x00010000ul
-#define PUBLIC_MECH_SEED_FLAG 0x00020000ul
-
-#define PUBLIC_MECH_RANDOM_FLAG 0x08000000ul
-#define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul
-#define PUBLIC_OWN_PW_DEFAULTS 0X20000000ul
-#define PUBLIC_DISABLE_FLAG 0x40000000ul
-
-/* warning: reserved means reserved */
-#define PUBLIC_MECH_RESERVED_FLAGS 0x87FF0000ul
-
-/* These cipher flags are visible to all other libraries, */
-/* But they must be converted before used in functions */
-/* withing the security module */
-#define PUBLIC_CIPHER_FORTEZZA_FLAG 0x00000001ul
-
-/* warning: reserved means reserved */
-#define PUBLIC_CIPHER_RESERVED_FLAGS 0xFFFFFFFEul
-
-SEC_BEGIN_PROTOS
-
-/*
- * the following functions are going to be deprecated in NSS 4.0 in
- * favor of the new stan functions.
- */
-
-/* Initialization */
-extern SECMODModule *SECMOD_LoadModule(char *moduleSpec,SECMODModule *parent,
- PRBool recurse);
-
-extern SECMODModule *SECMOD_LoadUserModule(char *moduleSpec,SECMODModule *parent,
- PRBool recurse);
-
-SECStatus SECMOD_UnloadUserModule(SECMODModule *mod);
-
-SECMODModule * SECMOD_CreateModule(const char *lib, const char *name,
- const char *param, const char *nss);
-/*
- * After a fork(), PKCS #11 says we need to call C_Initialize again in
- * the child before we can use the module. This function causes this
- * reinitialization.
- * NOTE: Any outstanding handles will become invalid, which means your
- * keys and contexts will fail, but new ones can be created.
- *
- * Setting 'force' to true means to do the reinitialization even if the
- * PKCS #11 module does not seem to need it. This allows software modules
- * which ignore fork to preserve their keys across the fork().
- */
-SECStatus SECMOD_RestartModules(PRBool force);
-
-
-/* Module Management */
-char **SECMOD_GetModuleSpecList(SECMODModule *module);
-SECStatus SECMOD_FreeModuleSpecList(SECMODModule *module,char **moduleSpecList);
-
-
-/* protoypes */
-/* Get a list of active PKCS #11 modules */
-extern SECMODModuleList *SECMOD_GetDefaultModuleList(void);
-/* Get a list of defined but not loaded PKCS #11 modules */
-extern SECMODModuleList *SECMOD_GetDeadModuleList(void);
-/* Get a list of Modules which define PKCS #11 modules to load */
-extern SECMODModuleList *SECMOD_GetDBModuleList(void);
-
-/* lock to protect all three module lists above */
-extern SECMODListLock *SECMOD_GetDefaultModuleListLock(void);
-
-extern SECStatus SECMOD_UpdateModule(SECMODModule *module);
-
-/* lock management */
-extern void SECMOD_GetReadLock(SECMODListLock *);
-extern void SECMOD_ReleaseReadLock(SECMODListLock *);
-
-/* Operate on modules by name */
-extern SECMODModule *SECMOD_FindModule(const char *name);
-extern SECStatus SECMOD_DeleteModule(const char *name, int *type);
-extern SECStatus SECMOD_DeleteModuleEx(const char * name,
- SECMODModule *mod,
- int *type,
- PRBool permdb);
-extern SECStatus SECMOD_DeleteInternalModule(const char *name);
-extern PRBool SECMOD_CanDeleteInternalModule(void);
-extern SECStatus SECMOD_AddNewModule(const char* moduleName,
- const char* dllPath,
- unsigned long defaultMechanismFlags,
- unsigned long cipherEnableFlags);
-extern SECStatus SECMOD_AddNewModuleEx(const char* moduleName,
- const char* dllPath,
- unsigned long defaultMechanismFlags,
- unsigned long cipherEnableFlags,
- char* modparms,
- char* nssparms);
-
-/* database/memory management */
-extern SECMODModule *SECMOD_GetInternalModule(void);
-extern SECMODModule *SECMOD_ReferenceModule(SECMODModule *module);
-extern void SECMOD_DestroyModule(SECMODModule *module);
-extern PK11SlotInfo *SECMOD_LookupSlot(SECMODModuleID module,
- unsigned long slotID);
-extern PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module,const char *name);
-
-/* Funtion reports true if at least one of the modules */
-/* of modType has been installed */
-PRBool SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags );
-
-/* accessors */
-PRBool SECMOD_GetSkipFirstFlag(SECMODModule *mod);
-PRBool SECMOD_GetDefaultModDBFlag(SECMODModule *mod);
-
-/* Functions used to convert between internal & public representation
- * of Mechanism Flags and Cipher Enable Flags */
-extern unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags);
-extern unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags);
-
-PRBool SECMOD_HasRemovableSlots(SECMODModule *mod);
-PK11SlotInfo *SECMOD_WaitForAnyTokenEvent(SECMODModule *mod,
- unsigned long flags, PRIntervalTime latency);
-/*
- * Warning: the SECMOD_CancelWait function is highly destructive, potentially
- * finalizing the module 'mod' (causing inprogress operations to fail,
- * and session key material to disappear). It should only be called when
- * shutting down the module.
- */
-SECStatus SECMOD_CancelWait(SECMODModule *mod);
-/*
- * check to see if the module has added new slots. PKCS 11 v2.20 allows for
- * modules to add new slots, but never remove them. Slots not be added between
- * a call to C_GetSlotLlist(Flag, NULL, &count) and the corresponding
- * C_GetSlotList(flag, &data, &count) so that the array doesn't accidently
- * grow on the caller. It is permissible for the slots to increase between
- * corresponding calls with NULL to get the size.
- */
-SECStatus SECMOD_UpdateSlotList(SECMODModule *mod);
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/pk11wrap/secmodi.h b/security/nss/lib/pk11wrap/secmodi.h
deleted file mode 100644
index 2959ab5c1..000000000
--- a/security/nss/lib/pk11wrap/secmodi.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Internal header file included only by files in pkcs11 dir, or in
- * pkcs11 specific client and server files.
- */
-#ifndef _SECMODI_H_
-#define _SECMODI_H_ 1
-#include "pkcs11.h"
-#include "nssilock.h"
-#include "secoidt.h"
-#include "secdert.h"
-#include "certt.h"
-#include "secmodt.h"
-#include "keyt.h"
-
-SEC_BEGIN_PROTOS
-
-/* proto-types */
-extern SECStatus SECMOD_DeletePermDB(SECMODModule *module);
-extern SECStatus SECMOD_AddPermDB(SECMODModule *module);
-extern SECStatus SECMOD_Shutdown(void);
-void nss_DumpModuleLog(void);
-
-extern int secmod_PrivateModuleCount;
-
-extern void SECMOD_Init(void);
-SECStatus secmod_ModuleInit(SECMODModule *mod, SECMODModule **oldModule,
- PRBool* alreadyLoaded);
-
-/* list managment */
-extern SECStatus SECMOD_AddModuleToList(SECMODModule *newModule);
-extern SECStatus SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule);
-extern SECStatus SECMOD_AddModuleToUnloadList(SECMODModule *newModule);
-extern void SECMOD_RemoveList(SECMODModuleList **,SECMODModuleList *);
-extern void SECMOD_AddList(SECMODModuleList *,SECMODModuleList *,SECMODListLock *);
-extern SECMODListLock *SECMOD_NewListLock(void);
-extern void SECMOD_DestroyListLock(SECMODListLock *);
-extern void SECMOD_GetWriteLock(SECMODListLock *);
-extern void SECMOD_ReleaseWriteLock(SECMODListLock *);
-
-/* Operate on modules by name */
-extern SECMODModule *SECMOD_FindModuleByID(SECMODModuleID);
-extern SECMODModule *secmod_FindModuleByFuncPtr(void *funcPtr);
-
-/* database/memory management */
-extern SECMODModuleList *SECMOD_NewModuleListElement(void);
-extern SECMODModuleList *SECMOD_DestroyModuleListElement(SECMODModuleList *);
-extern void SECMOD_DestroyModuleList(SECMODModuleList *);
-extern SECStatus SECMOD_AddModule(SECMODModule *newModule);
-
-extern unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags);
-extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags);
-
-/* Library functions */
-SECStatus secmod_LoadPKCS11Module(SECMODModule *, SECMODModule **oldModule);
-SECStatus SECMOD_UnloadModule(SECMODModule *);
-void SECMOD_SetInternalModule(SECMODModule *);
-PRBool secmod_IsInternalKeySlot(SECMODModule *);
-void secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val);
-
-
-/* tools for checking if we are loading the same database twice */
-typedef struct SECMODConfigListStr SECMODConfigList;
-/* collect all the databases in a given spec */
-SECMODConfigList *secmod_GetConfigList(PRBool isFIPS, char *spec, int *count);
-/* see is a spec matches a database on the list */
-PRBool secmod_MatchConfigList(char *spec,
- SECMODConfigList *conflist, int count);
-/* free our list of databases */
-void secmod_FreeConfigList(SECMODConfigList *conflist, int count);
-
-/* parsing parameters */
-/* returned char * must be freed by caller with PORT_Free */
-/* children and ids are null terminated arrays which must be freed with
- * secmod_FreeChildren */
-char *secmod_ParseModuleSpecForTokens(PRBool convert,
- PRBool isFIPS,
- char *moduleSpec,
- char ***children,
- CK_SLOT_ID **ids);
-void secmod_FreeChildren(char **children, CK_SLOT_ID *ids);
-char *secmod_MkAppendTokensList(PRArenaPool *arena, char *origModuleSpec,
- char *newModuleSpec, CK_SLOT_ID newID,
- char **children, CK_SLOT_ID *ids);
-
-
-void SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot);
-CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event,
- CK_VOID_PTR pdata);
-void pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib);
-CK_OBJECT_HANDLE pk11_FindObjectByTemplate(PK11SlotInfo *slot,
- CK_ATTRIBUTE *inTemplate,int tsize);
-CK_OBJECT_HANDLE *pk11_FindObjectsByTemplate(PK11SlotInfo *slot,
- CK_ATTRIBUTE *inTemplate,int tsize, int *objCount);
-SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *slot,
- PK11DefaultArrayEntry *entry, PRBool add);
-
-#define PK11_GETTAB(x) ((CK_FUNCTION_LIST_PTR)((x)->functionList))
-#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
- (x)->pValue=(v); (x)->ulValueLen = (l);
-SECStatus PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
- const CK_ATTRIBUTE *theTemplate, int count,
- PRBool token, CK_OBJECT_HANDLE *objectID);
-
-SECStatus pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech);
-SECStatus PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param,
- PRArenaPool *arena, SECAlgorithmID *algId);
-
-PK11SymKey *pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot,
- CK_MECHANISM_TYPE type, SECItem *param, CK_KEY_TYPE keyType,
- int keySize, SECItem *keyId, CK_FLAGS opFlags,
- PK11AttrFlags attrFlags, void *wincx);
-
-CK_MECHANISM_TYPE pk11_GetPBECryptoMechanism(SECAlgorithmID *algid,
- SECItem **param, SECItem *pwd, PRBool faulty3DES);
-
-
-
-extern void pk11sdr_Init(void);
-extern void pk11sdr_Shutdown(void);
-
-/*
- * Private to pk11wrap.
- */
-
-PRBool pk11_LoginStillRequired(PK11SlotInfo *slot, void *wincx);
-CK_SESSION_HANDLE pk11_GetNewSession(PK11SlotInfo *slot, PRBool *owner);
-void pk11_CloseSession(PK11SlotInfo *slot, CK_SESSION_HANDLE sess, PRBool own);
-PK11SymKey *pk11_ForceSlot(PK11SymKey *symKey, CK_MECHANISM_TYPE type,
- CK_ATTRIBUTE_TYPE operation);
-/* Convert key operation flags to PKCS #11 attributes. */
-unsigned int pk11_OpFlagsToAttributes(CK_FLAGS flags,
- CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue);
-/* Check for bad (conflicting) attribute flags */
-PRBool pk11_BadAttrFlags(PK11AttrFlags attrFlags);
-/* Convert key attribute flags to PKCS #11 attributes. */
-unsigned int pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags,
- CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue, CK_BBOOL *ckFalse);
-PRBool pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr, unsigned int numAttrs,
- CK_ATTRIBUTE_TYPE target);
-
-CK_MECHANISM_TYPE pk11_mapWrapKeyType(KeyType keyType);
-PK11SymKey *pk11_KeyExchange(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
- CK_ATTRIBUTE_TYPE operation, CK_FLAGS flags, PRBool isPerm,
- PK11SymKey *symKey);
-
-PRBool pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert,
- CERTCertTrust *trust);
-CK_OBJECT_HANDLE pk11_FindPubKeyByAnyCert(CERTCertificate *cert,
- PK11SlotInfo **slot, void *wincx);
-SECStatus pk11_AuthenticateUnfriendly(PK11SlotInfo *slot, PRBool loadCerts,
- void *wincx);
-int PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
- int templateCount);
-SECItem *pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot,
- CK_OBJECT_HANDLE handle);
-SECStatus PK11_TraverseSlot(PK11SlotInfo *slot, void *arg);
-CK_OBJECT_HANDLE pk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot,
- SECItem *keyID);
-SECKEYPrivateKey *PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
- PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx);
-CERTCertificate *PK11_MakeCertFromHandle(PK11SlotInfo *slot,
- CK_OBJECT_HANDLE certID, CK_ATTRIBUTE *privateLabel);
-
-SECItem *pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen);
-SECItem *pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type,
- SECItem *iv, int keyLen);
-
-SEC_END_PROTOS
-
-#endif
-
diff --git a/security/nss/lib/pk11wrap/secmodt.h b/security/nss/lib/pk11wrap/secmodt.h
deleted file mode 100644
index 73d2a7ebe..000000000
--- a/security/nss/lib/pk11wrap/secmodt.h
+++ /dev/null
@@ -1,448 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _SECMODT_H_
-#define _SECMODT_H_ 1
-
-#include "nssrwlkt.h"
-#include "nssilckt.h"
-#include "secoid.h"
-#include "secasn1.h"
-#include "pkcs11t.h"
-#include "utilmodt.h"
-
-SEC_BEGIN_PROTOS
-
-/* find a better home for these... */
-extern const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[];
-SEC_ASN1_CHOOSER_DECLARE(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
-extern const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[];
-SEC_ASN1_CHOOSER_DECLARE(SECKEY_EncryptedPrivateKeyInfoTemplate)
-extern const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[];
-SEC_ASN1_CHOOSER_DECLARE(SECKEY_PrivateKeyInfoTemplate)
-extern const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[];
-SEC_ASN1_CHOOSER_DECLARE(SECKEY_PointerToPrivateKeyInfoTemplate)
-
-SEC_END_PROTOS
-
-/* PKCS11 needs to be included */
-typedef struct SECMODModuleStr SECMODModule;
-typedef struct SECMODModuleListStr SECMODModuleList;
-typedef NSSRWLock SECMODListLock;
-typedef struct PK11SlotInfoStr PK11SlotInfo; /* defined in secmodti.h */
-typedef struct NSSUTILPreSlotInfoStr PK11PreSlotInfo; /* defined in secmodti.h */
-typedef struct PK11SymKeyStr PK11SymKey; /* defined in secmodti.h */
-typedef struct PK11ContextStr PK11Context; /* defined in secmodti.h */
-typedef struct PK11SlotListStr PK11SlotList;
-typedef struct PK11SlotListElementStr PK11SlotListElement;
-typedef struct PK11RSAGenParamsStr PK11RSAGenParams;
-typedef unsigned long SECMODModuleID;
-typedef struct PK11DefaultArrayEntryStr PK11DefaultArrayEntry;
-typedef struct PK11GenericObjectStr PK11GenericObject;
-typedef void (*PK11FreeDataFunc)(void *);
-
-struct SECMODModuleStr {
- PLArenaPool *arena;
- PRBool internal; /* true of internally linked modules, false
- * for the loaded modules */
- PRBool loaded; /* Set to true if module has been loaded */
- PRBool isFIPS; /* Set to true if module is finst internal */
- char *dllName; /* name of the shared library which implements
- * this module */
- char *commonName; /* name of the module to display to the user */
- void *library; /* pointer to the library. opaque. used only by
- * pk11load.c */
- void *functionList; /* The PKCS #11 function table */
- PZLock *refLock; /* only used pk11db.c */
- int refCount; /* Module reference count */
- PK11SlotInfo **slots; /* array of slot points attached to this mod*/
- int slotCount; /* count of slot in above array */
- PK11PreSlotInfo *slotInfo; /* special info about slots default settings */
- int slotInfoCount; /* count */
- SECMODModuleID moduleID; /* ID so we can find this module again */
- PRBool isThreadSafe;
- unsigned long ssl[2]; /* SSL cipher enable flags */
- char *libraryParams; /* Module specific parameters */
- void *moduleDBFunc; /* function to return module configuration data*/
- SECMODModule *parent; /* module that loaded us */
- PRBool isCritical; /* This module must load successfully */
- PRBool isModuleDB; /* this module has lists of PKCS #11 modules */
- PRBool moduleDBOnly; /* this module only has lists of PKCS #11 modules */
- int trustOrder; /* order for this module's certificate trust rollup */
- int cipherOrder; /* order for cipher operations */
- unsigned long evControlMask; /* control the running and shutdown of slot
- * events (SECMOD_WaitForAnyTokenEvent) */
- CK_VERSION cryptokiVersion; /* version of this library */
-};
-
-/* evControlMask flags */
-/*
- * These bits tell the current state of a SECMOD_WaitForAnyTokenEvent.
- *
- * SECMOD_WAIT_PKCS11_EVENT - we're waiting in the PKCS #11 module in
- * C_WaitForSlotEvent().
- * SECMOD_WAIT_SIMULATED_EVENT - we're waiting in the NSS simulation code
- * which polls for token insertion and removal events.
- * SECMOD_END_WAIT - SECMOD_CancelWait has been called while the module is
- * waiting in SECMOD_WaitForAnyTokenEvent. SECMOD_WaitForAnyTokenEvent
- * should return immediately to it's caller.
- */
-#define SECMOD_END_WAIT 0x01
-#define SECMOD_WAIT_SIMULATED_EVENT 0x02
-#define SECMOD_WAIT_PKCS11_EVENT 0x04
-
-struct SECMODModuleListStr {
- SECMODModuleList *next;
- SECMODModule *module;
-};
-
-struct PK11SlotListStr {
- PK11SlotListElement *head;
- PK11SlotListElement *tail;
- PZLock *lock;
-};
-
-struct PK11SlotListElementStr {
- PK11SlotListElement *next;
- PK11SlotListElement *prev;
- PK11SlotInfo *slot;
- int refCount;
-};
-
-struct PK11RSAGenParamsStr {
- int keySizeInBits;
- unsigned long pe;
-};
-
-typedef enum {
- PK11CertListUnique = 0, /* get one instance of all certs */
- PK11CertListUser = 1, /* get all instances of user certs */
- PK11CertListRootUnique = 2, /* get one instance of CA certs without a private key.
- * deprecated. Use PK11CertListCAUnique
- */
- PK11CertListCA = 3, /* get all instances of CA certs */
- PK11CertListCAUnique = 4, /* get one instance of CA certs */
- PK11CertListUserUnique = 5, /* get one instance of user certs */
- PK11CertListAll = 6 /* get all instances of all certs */
-} PK11CertListType;
-
-/*
- * Entry into the Array which lists all the legal bits for the default flags
- * in the slot, their definition, and the PKCS #11 mechanism the represent
- * Always Statically allocated.
- */
-struct PK11DefaultArrayEntryStr {
- char *name;
- unsigned long flag;
- unsigned long mechanism; /* this is a long so we don't include the
- * whole pkcs 11 world to use this header */
-};
-
-/*
- * PK11AttrFlags
- *
- * A 32-bit bitmask of PK11_ATTR_XXX flags
- */
-typedef PRUint32 PK11AttrFlags;
-
-/*
- * PK11_ATTR_XXX
- *
- * The following PK11_ATTR_XXX bitflags are used to specify
- * PKCS #11 object attributes that have Boolean values. Some NSS
- * functions have a "PK11AttrFlags attrFlags" parameter whose value
- * is the logical OR of these bitflags. NSS use these bitflags on
- * private keys or secret keys. Some of these bitflags also apply
- * to the public keys associated with the private keys.
- *
- * For each PKCS #11 object attribute, we need two bitflags to
- * specify not only "true" and "false" but also "default". For
- * example, PK11_ATTR_PRIVATE and PK11_ATTR_PUBLIC control the
- * CKA_PRIVATE attribute. If PK11_ATTR_PRIVATE is set, we add
- * { CKA_PRIVATE, &cktrue, sizeof(CK_BBOOL) }
- * to the template. If PK11_ATTR_PUBLIC is set, we add
- * { CKA_PRIVATE, &ckfalse, sizeof(CK_BBOOL) }
- * to the template. If neither flag is set, we don't add any
- * CKA_PRIVATE entry to the template.
- */
-
-/*
- * Attributes for PKCS #11 storage objects, which include not only
- * keys but also certificates and domain parameters.
- */
-
-/*
- * PK11_ATTR_TOKEN
- * PK11_ATTR_SESSION
- *
- * These two flags determine whether the object is a token or
- * session object.
- *
- * These two flags are related and cannot both be set.
- * If the PK11_ATTR_TOKEN flag is set, the object is a token
- * object. If the PK11_ATTR_SESSION flag is set, the object is
- * a session object. If neither flag is set, the object is *by
- * default* a session object.
- *
- * These two flags specify the value of the PKCS #11 CKA_TOKEN
- * attribute.
- */
-#define PK11_ATTR_TOKEN 0x00000001L
-#define PK11_ATTR_SESSION 0x00000002L
-
-/*
- * PK11_ATTR_PRIVATE
- * PK11_ATTR_PUBLIC
- *
- * These two flags determine whether the object is a private or
- * public object. A user may not access a private object until the
- * user has authenticated to the token.
- *
- * These two flags are related and cannot both be set.
- * If the PK11_ATTR_PRIVATE flag is set, the object is a private
- * object. If the PK11_ATTR_PUBLIC flag is set, the object is a
- * public object. If neither flag is set, it is token-specific
- * whether the object is private or public.
- *
- * These two flags specify the value of the PKCS #11 CKA_PRIVATE
- * attribute. NSS only uses this attribute on private and secret
- * keys, so public keys created by NSS get the token-specific
- * default value of the CKA_PRIVATE attribute.
- */
-#define PK11_ATTR_PRIVATE 0x00000004L
-#define PK11_ATTR_PUBLIC 0x00000008L
-
-/*
- * PK11_ATTR_MODIFIABLE
- * PK11_ATTR_UNMODIFIABLE
- *
- * These two flags determine whether the object is modifiable or
- * read-only.
- *
- * These two flags are related and cannot both be set.
- * If the PK11_ATTR_MODIFIABLE flag is set, the object can be
- * modified. If the PK11_ATTR_UNMODIFIABLE flag is set, the object
- * is read-only. If neither flag is set, the object is *by default*
- * modifiable.
- *
- * These two flags specify the value of the PKCS #11 CKA_MODIFIABLE
- * attribute.
- */
-#define PK11_ATTR_MODIFIABLE 0x00000010L
-#define PK11_ATTR_UNMODIFIABLE 0x00000020L
-
-/* Attributes for PKCS #11 key objects. */
-
-/*
- * PK11_ATTR_SENSITIVE
- * PK11_ATTR_INSENSITIVE
- *
- * These two flags are related and cannot both be set.
- * If the PK11_ATTR_SENSITIVE flag is set, the key is sensitive.
- * If the PK11_ATTR_INSENSITIVE flag is set, the key is not
- * sensitive. If neither flag is set, it is token-specific whether
- * the key is sensitive or not.
- *
- * If a key is sensitive, certain attributes of the key cannot be
- * revealed in plaintext outside the token.
- *
- * This flag specifies the value of the PKCS #11 CKA_SENSITIVE
- * attribute. Although the default value of the CKA_SENSITIVE
- * attribute for secret keys is CK_FALSE per PKCS #11, some FIPS
- * tokens set the default value to CK_TRUE because only CK_TRUE
- * is allowed. So in practice the default value of this attribute
- * is token-specific, hence the need for two bitflags.
- */
-#define PK11_ATTR_SENSITIVE 0x00000040L
-#define PK11_ATTR_INSENSITIVE 0x00000080L
-
-/*
- * PK11_ATTR_EXTRACTABLE
- * PK11_ATTR_UNEXTRACTABLE
- *
- * These two flags are related and cannot both be set.
- * If the PK11_ATTR_EXTRACTABLE flag is set, the key is extractable
- * and can be wrapped. If the PK11_ATTR_UNEXTRACTABLE flag is set,
- * the key is not extractable, and certain attributes of the key
- * cannot be revealed in plaintext outside the token (just like a
- * sensitive key). If neither flag is set, it is token-specific
- * whether the key is extractable or not.
- *
- * These two flags specify the value of the PKCS #11 CKA_EXTRACTABLE
- * attribute.
- */
-#define PK11_ATTR_EXTRACTABLE 0x00000100L
-#define PK11_ATTR_UNEXTRACTABLE 0x00000200L
-
-/* Cryptographic module types */
-#define SECMOD_EXTERNAL 0 /* external module */
-#define SECMOD_INTERNAL 1 /* internal default module */
-#define SECMOD_FIPS 2 /* internal fips module */
-
-/* default module configuration strings */
-#define SECMOD_SLOT_FLAGS "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512]"
-
-#define SECMOD_MAKE_NSS_FLAGS(fips,slot) \
-"Flags=internal,critical" fips " slotparams=(" #slot "={" SECMOD_SLOT_FLAGS "})"
-
-#define SECMOD_INT_NAME "NSS Internal PKCS #11 Module"
-#define SECMOD_INT_FLAGS SECMOD_MAKE_NSS_FLAGS("",1)
-#define SECMOD_FIPS_NAME "NSS Internal FIPS PKCS #11 Module"
-#define SECMOD_FIPS_FLAGS SECMOD_MAKE_NSS_FLAGS(",fips",3)
-
-/*
- * What is the origin of a given Key. Normally this doesn't matter, but
- * the fortezza code needs to know if it needs to invoke the SSL3 fortezza
- * hack.
- */
-typedef enum {
- PK11_OriginNULL = 0, /* There is not key, it's a null SymKey */
- PK11_OriginDerive = 1, /* Key was derived from some other key */
- PK11_OriginGenerated = 2, /* Key was generated (also PBE keys) */
- PK11_OriginFortezzaHack = 3,/* Key was marked for fortezza hack */
- PK11_OriginUnwrap = 4 /* Key was unwrapped or decrypted */
-} PK11Origin;
-
-/* PKCS #11 disable reasons */
-typedef enum {
- PK11_DIS_NONE = 0,
- PK11_DIS_USER_SELECTED = 1,
- PK11_DIS_COULD_NOT_INIT_TOKEN = 2,
- PK11_DIS_TOKEN_VERIFY_FAILED = 3,
- PK11_DIS_TOKEN_NOT_PRESENT = 4
-} PK11DisableReasons;
-
-/* types of PKCS #11 objects
- * used to identify which NSS data structure is
- * passed to the PK11_Raw* functions. Types map as follows:
- * PK11_TypeGeneric PK11GenericObject *
- * PK11_TypePrivKey SECKEYPrivateKey *
- * PK11_TypePubKey SECKEYPublicKey *
- * PK11_TypeSymKey PK11SymKey *
- * PK11_TypeCert CERTCertificate * (currently not used).
- */
-typedef enum {
- PK11_TypeGeneric = 0,
- PK11_TypePrivKey = 1,
- PK11_TypePubKey = 2,
- PK11_TypeCert = 3,
- PK11_TypeSymKey = 4
-} PK11ObjectType;
-
-
-
-/* function pointer type for password callback function.
- * This type is passed in to PK11_SetPasswordFunc()
- */
-typedef char *(PR_CALLBACK *PK11PasswordFunc)(PK11SlotInfo *slot, PRBool retry, void *arg);
-typedef PRBool (PR_CALLBACK *PK11VerifyPasswordFunc)(PK11SlotInfo *slot, void *arg);
-typedef PRBool (PR_CALLBACK *PK11IsLoggedInFunc)(PK11SlotInfo *slot, void *arg);
-
-/*
- * Special strings the password callback function can return only if
- * the slot is an protected auth path slot.
- */
-#define PK11_PW_RETRY "RETRY" /* an failed attempt to authenticate
- * has already been made, just retry
- * the operation */
-#define PK11_PW_AUTHENTICATED "AUTH" /* a successful attempt to authenticate
- * has completed. Continue without
- * another call to C_Login */
-/* All other non-null values mean that that NSS could call C_Login to force
- * the authentication. The following define is to aid applications in
- * documenting that is what it's trying to do */
-#define PK11_PW_TRY "TRY" /* Default: a prompt has been presented
- * to the user, initiate a C_Login
- * to authenticate the token */
-
-/*
- * PKCS #11 key structures
- */
-
-/*
-** Attributes
-*/
-struct SECKEYAttributeStr {
- SECItem attrType;
- SECItem **attrValue;
-};
-typedef struct SECKEYAttributeStr SECKEYAttribute;
-
-/*
-** A PKCS#8 private key info object
-*/
-struct SECKEYPrivateKeyInfoStr {
- PLArenaPool *arena;
- SECItem version;
- SECAlgorithmID algorithm;
- SECItem privateKey;
- SECKEYAttribute **attributes;
-};
-typedef struct SECKEYPrivateKeyInfoStr SECKEYPrivateKeyInfo;
-
-/*
-** A PKCS#8 private key info object
-*/
-struct SECKEYEncryptedPrivateKeyInfoStr {
- PLArenaPool *arena;
- SECAlgorithmID algorithm;
- SECItem encryptedData;
-};
-typedef struct SECKEYEncryptedPrivateKeyInfoStr SECKEYEncryptedPrivateKeyInfo;
-
-/*
- * token removal detection
- */
-typedef enum {
- PK11TokenNotRemovable = 0,
- PK11TokenPresent = 1,
- PK11TokenChanged = 2,
- PK11TokenRemoved = 3
-} PK11TokenStatus;
-
-typedef enum {
- PK11TokenRemovedOrChangedEvent = 0,
- PK11TokenPresentEvent = 1
-} PK11TokenEvent;
-
-/*
- * CRL Import Flags
- */
-#define CRL_IMPORT_DEFAULT_OPTIONS 0x00000000
-#define CRL_IMPORT_BYPASS_CHECKS 0x00000001
-
-
-/*
- * Merge Error Log
- */
-typedef struct PK11MergeLogStr PK11MergeLog;
-typedef struct PK11MergeLogNodeStr PK11MergeLogNode;
-
-/* These need to be global, leave some open fields so we can 'expand'
- * these without breaking binary compatibility */
-struct PK11MergeLogNodeStr {
- PK11MergeLogNode *next; /* next entry in the list */
- PK11MergeLogNode *prev; /* last entry in the list */
- PK11GenericObject *object; /* object that failed */
- int error; /* what the error was */
- CK_RV reserved1;
- unsigned long reserved2; /* future flags */
- unsigned long reserved3; /* future scalar */
- void *reserved4; /* future pointer */
- void *reserved5; /* future expansion pointer */
-};
-
-struct PK11MergeLogStr {
- PK11MergeLogNode *head;
- PK11MergeLogNode *tail;
- PLArenaPool *arena;
- int version;
- unsigned long reserved1;
- unsigned long reserved2;
- unsigned long reserved3;
- void *reserverd4;
- void *reserverd5;
-};
-
-
-#endif /*_SECMODT_H_ */
diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h
deleted file mode 100644
index d393c0f8a..000000000
--- a/security/nss/lib/pk11wrap/secmodti.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Internal header file included only by files in pkcs11 dir, or in
- * pkcs11 specific client and server files.
- */
-
-#ifndef _SECMODTI_H_
-#define _SECMODTI_H_ 1
-#include "prmon.h"
-#include "prtypes.h"
-#include "nssilckt.h"
-#include "secmodt.h"
-#include "pkcs11t.h"
-
-#include "nssdevt.h"
-
-/* internal data structures */
-
-/* Traverse slots callback */
-typedef struct pk11TraverseSlotStr {
- SECStatus (*callback)(PK11SlotInfo *,CK_OBJECT_HANDLE, void *);
- void *callbackArg;
- CK_ATTRIBUTE *findTemplate;
- int templateCount;
-} pk11TraverseSlot;
-
-
-/* represent a pkcs#11 slot reference counted. */
-struct PK11SlotInfoStr {
- /* the PKCS11 function list for this slot */
- void *functionList;
- SECMODModule *module; /* our parent module */
- /* Boolean to indicate the current state of this slot */
- PRBool needTest; /* Has this slot been tested for Export complience */
- PRBool isPerm; /* is this slot a permanment device */
- PRBool isHW; /* is this slot a hardware device */
- PRBool isInternal; /* is this slot one of our internal PKCS #11 devices */
- PRBool disabled; /* is this slot disabled... */
- PK11DisableReasons reason; /* Why this slot is disabled */
- PRBool readOnly; /* is the token in this slot read-only */
- PRBool needLogin; /* does the token of the type that needs
- * authentication (still true even if token is logged
- * in) */
- PRBool hasRandom; /* can this token generated random numbers */
- PRBool defRWSession; /* is the default session RW (we open our default
- * session rw if the token can only handle one session
- * at a time. */
- PRBool isThreadSafe; /* copied from the module */
- /* The actual flags (many of which are distilled into the above PRBools) */
- CK_FLAGS flags; /* flags from PKCS #11 token Info */
- /* a default session handle to do quick and dirty functions */
- CK_SESSION_HANDLE session;
- PZLock *sessionLock; /* lock for this session */
- /* our ID */
- CK_SLOT_ID slotID;
- /* persistant flags saved from startup to startup */
- unsigned long defaultFlags;
- /* keep track of who is using us so we don't accidently get freed while
- * still in use */
- PRInt32 refCount; /* to be in/decremented by atomic calls ONLY! */
- PZLock *freeListLock;
- PK11SymKey *freeSymKeysWithSessionHead;
- PK11SymKey *freeSymKeysHead;
- int keyCount;
- int maxKeyCount;
- /* Password control functions for this slot. many of these are only
- * active if the appropriate flag is on in defaultFlags */
- int askpw; /* what our password options are */
- int timeout; /* If we're ask_timeout, what is our timeout time is
- * seconds */
- int authTransact; /* allow multiple authentications off one password if
- * they are all part of the same transaction */
- int64 authTime; /* when were we last authenticated */
- int minPassword; /* smallest legal password */
- int maxPassword; /* largest legal password */
- uint16 series; /* break up the slot info into various groups of
- * inserted tokens so that keys and certs can be
- * invalidated */
- uint16 flagSeries; /* record the last series for the last event
- * returned for this slot */
- PRBool flagState; /* record the state of the last event returned for this
- * slot. */
- uint16 wrapKey; /* current wrapping key for SSL master secrets */
- CK_MECHANISM_TYPE wrapMechanism;
- /* current wrapping mechanism for current wrapKey */
- CK_OBJECT_HANDLE refKeys[1]; /* array of existing wrapping keys for */
- CK_MECHANISM_TYPE *mechanismList; /* list of mechanism supported by this
- * token */
- int mechanismCount;
- /* cache the certificates stored on the token of this slot */
- CERTCertificate **cert_array;
- int array_size;
- int cert_count;
- char serial[16];
- /* since these are odd sizes, keep them last. They are odd sizes to
- * allow them to become null terminated strings */
- char slot_name[65];
- char token_name[33];
- PRBool hasRootCerts;
- PRBool hasRootTrust;
- PRBool hasRSAInfo;
- CK_FLAGS RSAInfoFlags;
- PRBool protectedAuthPath;
- PRBool isActiveCard;
- PRIntervalTime lastLoginCheck;
- unsigned int lastState;
- /* for Stan */
- NSSToken *nssToken;
- /* fast mechanism lookup */
- char mechanismBits[256];
-};
-
-/* Symetric Key structure. Reference Counted */
-struct PK11SymKeyStr {
- CK_MECHANISM_TYPE type; /* type of operation this key was created for*/
- CK_OBJECT_HANDLE objectID; /* object id of this key in the slot */
- PK11SlotInfo *slot; /* Slot this key is loaded into */
- void *cx; /* window context in case we need to loggin */
- PK11SymKey *next;
- PRBool owner;
- SECItem data; /* raw key data if available */
- CK_SESSION_HANDLE session;
- PRBool sessionOwner;
- PRInt32 refCount; /* number of references to this key */
- int size; /* key size in bytes */
- PK11Origin origin; /* where this key came from
- * (see def in secmodt.h) */
- PK11SymKey *parent; /* potential owner key of the session */
- uint16 series; /* break up the slot info into various groups
- * of inserted tokens so that keys and certs
- * can be invalidated */
- void *userData; /* random data the application can attach to
- * this key */
- PK11FreeDataFunc freeFunc; /* function to free the user data */
-};
-
-
-/*
- * hold a hash, encryption or signing context for multi-part operations.
- * hold enough information so that multiple contexts can be interleaved
- * if necessary. ... Not RefCounted.
- */
-struct PK11ContextStr {
- CK_ATTRIBUTE_TYPE operation; /* type of operation this context is doing
- * (CKA_ENCRYPT, CKA_SIGN, CKA_HASH, etc. */
- PK11SymKey *key; /* symetric key used in this context */
- PK11SlotInfo *slot; /* slot this context is operationing on */
- CK_SESSION_HANDLE session; /* session this context is using */
- PZLock *sessionLock; /* lock before accessing a PKCS #11
- * session */
- PRBool ownSession;/* do we own the session? */
- void *cx; /* window context in case we need to loggin*/
- void *savedData;/* save data when we are multiplexing on a
- * single context */
- unsigned long savedLength; /* length of the saved context */
- SECItem *param; /* mechanism parameters used to build this
- context */
- PRBool init; /* has this contexted been initialized */
- CK_MECHANISM_TYPE type; /* what is the PKCS #11 this context is
- * representing (usually what algorithm is
- * being used (CKM_RSA_PKCS, CKM_DES,
- * CKM_SHA, etc.*/
- PRBool fortezzaHack; /*Fortezza SSL has some special
- * non-standard semantics*/
-};
-
-/*
- * structure to hold a pointer to a unique PKCS #11 object
- * (pointer to the slot and the object id).
- */
-struct PK11GenericObjectStr {
- PK11GenericObject *prev;
- PK11GenericObject *next;
- PK11SlotInfo *slot;
- CK_OBJECT_HANDLE objectID;
-};
-
-
-#define MAX_TEMPL_ATTRS 16 /* maximum attributes in template */
-
-/* This mask includes all CK_FLAGs with an equivalent CKA_ attribute. */
-#define CKF_KEY_OPERATION_FLAGS 0x000e7b00UL
-
-
-#endif /* _SECMODTI_H_ */
diff --git a/security/nss/lib/pk11wrap/secpkcs5.h b/security/nss/lib/pk11wrap/secpkcs5.h
deleted file mode 100644
index ac863b166..000000000
--- a/security/nss/lib/pk11wrap/secpkcs5.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _SECPKCS5_H_
-#define _SECPKCS5_H_
-#include "seccomon.h"
-#include "secmodt.h"
-
-/* used for V2 PKCS 12 Draft Spec */
-typedef enum {
- pbeBitGenIDNull = 0,
- pbeBitGenCipherKey = 0x01,
- pbeBitGenCipherIV = 0x02,
- pbeBitGenIntegrityKey = 0x03
-} PBEBitGenID;
-
-typedef struct PBEBitGenContextStr PBEBitGenContext;
-
-SEC_BEGIN_PROTOS
-
-/* private */
-SECAlgorithmID *
-sec_pkcs5CreateAlgorithmID(SECOidTag algorithm, SECOidTag cipherAlgorithm,
- SECOidTag prfAlg, SECOidTag *pPbeAlgorithm,
- int keyLengh, SECItem *salt, int iteration);
-
-/* Get the initialization vector. The password is passed in, hashing
- * is performed, and the initialization vector is returned.
- * algid is a pointer to a PBE algorithm ID
- * pwitem is the password
- * If an error occurs or the algorithm id is not a PBE algrithm,
- * NULL is returned. Otherwise, the iv is returned in a secitem.
- */
-SECItem *
-SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES);
-
-SECOidTag SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid);
-PRBool SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid);
-PRBool SEC_PKCS5IsAlgorithmPBEAlgTag(SECOidTag algTag);
-SECOidTag SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen);
-int SEC_PKCS5GetKeyLength(SECAlgorithmID *algid);
-
-/**********************************************************************
- * Deprecated PBE functions. Use the PBE functions in pk11func.h
- * instead.
- **********************************************************************/
-
-PBEBitGenContext *
-PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations);
-
-void
-PBE_DestroyContext(PBEBitGenContext *context);
-
-
-SECItem *
-PBE_GenerateBits(PBEBitGenContext *context);
-
-SEC_END_PROTOS
-
-#endif /* _SECPKS5_H_ */
diff --git a/security/nss/lib/pkcs12/Makefile b/security/nss/lib/pkcs12/Makefile
deleted file mode 100644
index 8149184b4..000000000
--- a/security/nss/lib/pkcs12/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-
-
diff --git a/security/nss/lib/pkcs12/config.mk b/security/nss/lib/pkcs12/config.mk
deleted file mode 100644
index dc39ee4d6..000000000
--- a/security/nss/lib/pkcs12/config.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/pkcs12/manifest.mn b/security/nss/lib/pkcs12/manifest.mn
deleted file mode 100644
index 1bf972038..000000000
--- a/security/nss/lib/pkcs12/manifest.mn
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-CORE_DEPTH = ../../..
-
-EXPORTS = \
- pkcs12t.h \
- pkcs12.h \
- p12plcy.h \
- p12.h \
- p12t.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- p12local.c \
- p12creat.c \
- p12dec.c \
- p12plcy.c \
- p12tmpl.c \
- p12e.c \
- p12d.c \
- $(NULL)
-
-LIBRARY_NAME = pkcs12
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/pkcs12/p12.h b/security/nss/lib/pkcs12/p12.h
deleted file mode 100644
index e05b030ac..000000000
--- a/security/nss/lib/pkcs12/p12.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#ifndef _P12_H_
-#define _P12_H_
-
-#include "secoid.h"
-#include "key.h"
-#include "secpkcs7.h"
-#include "p12t.h"
-
-typedef int (PR_CALLBACK * PKCS12OpenFunction)(void *arg);
-typedef int (PR_CALLBACK * PKCS12ReadFunction)(void *arg,
- unsigned char *buffer,
- unsigned int *lenRead,
- unsigned int maxLen);
-typedef int (PR_CALLBACK * PKCS12WriteFunction)(void *arg,
- unsigned char *buffer,
- unsigned int *bufLen,
- unsigned int *lenWritten);
-typedef int (PR_CALLBACK * PKCS12CloseFunction)(void *arg);
-typedef SECStatus (PR_CALLBACK * PKCS12UnicodeConvertFunction)(
- PLArenaPool *arena,
- SECItem *dest, SECItem *src,
- PRBool toUnicode,
- PRBool swapBytes);
-typedef void (PR_CALLBACK * SEC_PKCS12EncoderOutputCallback)(
- void *arg, const char *buf,
- unsigned long len);
-typedef void (PR_CALLBACK * SEC_PKCS12DecoderOutputCallback)(
- void *arg, const char *buf,
- unsigned long len);
-/*
- * In NSS 3.12 or later, 'arg' actually points to a CERTCertificate,
- * the 'leafCert' variable in sec_pkcs12_validate_cert in p12d.c.
- * See r1.35 of p12d.c ("Patch 2" in bug 321584).
- */
-typedef SECItem * (PR_CALLBACK * SEC_PKCS12NicknameCollisionCallback)(
- SECItem *old_nickname,
- PRBool *cancel,
- void *arg);
-
-
-
-
-typedef SECStatus (PR_CALLBACK *digestOpenFn)(void *arg, PRBool readData);
-typedef SECStatus (PR_CALLBACK *digestCloseFn)(void *arg, PRBool removeFile);
-typedef int (PR_CALLBACK *digestIOFn)(void *arg, unsigned char *buf,
- unsigned long len);
-
-typedef struct SEC_PKCS12ExportContextStr SEC_PKCS12ExportContext;
-typedef struct SEC_PKCS12SafeInfoStr SEC_PKCS12SafeInfo;
-typedef struct SEC_PKCS12DecoderContextStr SEC_PKCS12DecoderContext;
-typedef struct SEC_PKCS12DecoderItemStr SEC_PKCS12DecoderItem;
-
-struct sec_PKCS12PasswordModeInfo {
- SECItem *password;
- SECOidTag algorithm;
-};
-
-struct sec_PKCS12PublicKeyModeInfo {
- CERTCertificate *cert;
- CERTCertDBHandle *certDb;
- SECOidTag algorithm;
- int keySize;
-};
-
-struct SEC_PKCS12DecoderItemStr {
- SECItem *der;
- SECOidTag type;
- PRBool hasKey;
- SECItem *friendlyName; /* UTF-8 string */
- SECAlgorithmID *shroudAlg;
-};
-
-
-SEC_BEGIN_PROTOS
-
-SEC_PKCS12SafeInfo *
-SEC_PKCS12CreatePubKeyEncryptedSafe(SEC_PKCS12ExportContext *p12ctxt,
- CERTCertDBHandle *certDb,
- CERTCertificate *signer,
- CERTCertificate **recipients,
- SECOidTag algorithm, int keysize);
-
-extern SEC_PKCS12SafeInfo *
-SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt,
- SECItem *pwitem, SECOidTag privAlg);
-
-extern SEC_PKCS12SafeInfo *
-SEC_PKCS12CreateUnencryptedSafe(SEC_PKCS12ExportContext *p12ctxt);
-
-extern SECStatus
-SEC_PKCS12AddPasswordIntegrity(SEC_PKCS12ExportContext *p12ctxt,
- SECItem *pwitem, SECOidTag integAlg);
-extern SECStatus
-SEC_PKCS12AddPublicKeyIntegrity(SEC_PKCS12ExportContext *p12ctxt,
- CERTCertificate *cert, CERTCertDBHandle *certDb,
- SECOidTag algorithm, int keySize);
-
-extern SEC_PKCS12ExportContext *
-SEC_PKCS12CreateExportContext(SECKEYGetPasswordKey pwfn, void *pwfnarg,
- PK11SlotInfo *slot, void *wincx);
-
-extern SECStatus
-SEC_PKCS12AddCert(SEC_PKCS12ExportContext *p12ctxt,
- SEC_PKCS12SafeInfo *safe, void *nestedDest,
- CERTCertificate *cert, CERTCertDBHandle *certDb,
- SECItem *keyId, PRBool includeCertChain);
-
-extern SECStatus
-SEC_PKCS12AddKeyForCert(SEC_PKCS12ExportContext *p12ctxt,
- SEC_PKCS12SafeInfo *safe,
- void *nestedDest, CERTCertificate *cert,
- PRBool shroudKey, SECOidTag algorithm, SECItem *pwitem,
- SECItem *keyId, SECItem *nickName);
-
-extern SECStatus
-SEC_PKCS12AddCertOrChainAndKey(SEC_PKCS12ExportContext *p12ctxt,
- void *certSafe, void *certNestedDest,
- CERTCertificate *cert, CERTCertDBHandle *certDb,
- void *keySafe, void *keyNestedDest, PRBool shroudKey,
- SECItem *pwitem, SECOidTag algorithm,
- PRBool includeCertChain);
-
-
-extern SECStatus
-SEC_PKCS12AddCertAndKey(SEC_PKCS12ExportContext *p12ctxt,
- void *certSafe, void *certNestedDest,
- CERTCertificate *cert, CERTCertDBHandle *certDb,
- void *keySafe, void *keyNestedDest,
- PRBool shroudKey, SECItem *pwitem, SECOidTag algorithm);
-
-extern void *
-SEC_PKCS12CreateNestedSafeContents(SEC_PKCS12ExportContext *p12ctxt,
- void *baseSafe, void *nestedDest);
-
-extern SECStatus
-SEC_PKCS12Encode(SEC_PKCS12ExportContext *p12exp,
- SEC_PKCS12EncoderOutputCallback output, void *outputarg);
-
-extern void
-SEC_PKCS12DestroyExportContext(SEC_PKCS12ExportContext *p12exp);
-
-extern SEC_PKCS12DecoderContext *
-SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
- digestOpenFn dOpen, digestCloseFn dClose,
- digestIOFn dRead, digestIOFn dWrite, void *dArg);
-
-extern SECStatus
-SEC_PKCS12DecoderSetTargetTokenCAs(SEC_PKCS12DecoderContext *p12dcx,
- SECPKCS12TargetTokenCAs tokenCAs);
-
-extern SECStatus
-SEC_PKCS12DecoderUpdate(SEC_PKCS12DecoderContext *p12dcx, unsigned char *data,
- unsigned long len);
-
-extern void
-SEC_PKCS12DecoderFinish(SEC_PKCS12DecoderContext *p12dcx);
-
-extern SECStatus
-SEC_PKCS12DecoderVerify(SEC_PKCS12DecoderContext *p12dcx);
-
-extern SECStatus
-SEC_PKCS12DecoderValidateBags(SEC_PKCS12DecoderContext *p12dcx,
- SEC_PKCS12NicknameCollisionCallback nicknameCb);
-
-extern SECStatus
-SEC_PKCS12DecoderImportBags(SEC_PKCS12DecoderContext *p12dcx);
-
-CERTCertList *
-SEC_PKCS12DecoderGetCerts(SEC_PKCS12DecoderContext *p12dcx);
-
-SECStatus
-SEC_PKCS12DecoderIterateInit(SEC_PKCS12DecoderContext *p12dcx);
-
-SECStatus
-SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
- const SEC_PKCS12DecoderItem **ipp);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/pkcs12/p12creat.c b/security/nss/lib/pkcs12/p12creat.c
deleted file mode 100644
index 4457e1202..000000000
--- a/security/nss/lib/pkcs12/p12creat.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "pkcs12.h"
-#include "secitem.h"
-#include "secport.h"
-#include "secder.h"
-#include "secoid.h"
-#include "p12local.h"
-#include "secerr.h"
-
-
-/* allocate space for a PFX structure and set up initial
- * arena pool. pfx structure is cleared and a pointer to
- * the new structure is returned.
- */
-SEC_PKCS12PFXItem *
-sec_pkcs12_new_pfx(void)
-{
- SEC_PKCS12PFXItem *pfx = NULL;
- PRArenaPool *poolp = NULL;
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); /* XXX Different size? */
- if(poolp == NULL)
- goto loser;
-
- pfx = (SEC_PKCS12PFXItem *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS12PFXItem));
- if(pfx == NULL)
- goto loser;
- pfx->poolp = poolp;
-
- return pfx;
-
-loser:
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
-}
-
-/* allocate space for a PFX structure and set up initial
- * arena pool. pfx structure is cleared and a pointer to
- * the new structure is returned.
- */
-SEC_PKCS12AuthenticatedSafe *
-sec_pkcs12_new_asafe(PRArenaPool *poolp)
-{
- SEC_PKCS12AuthenticatedSafe *asafe = NULL;
- void *mark;
-
- mark = PORT_ArenaMark(poolp);
- asafe = (SEC_PKCS12AuthenticatedSafe *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS12AuthenticatedSafe));
- if(asafe == NULL)
- goto loser;
- asafe->poolp = poolp;
- PORT_Memset(&asafe->old_baggage, 0, sizeof(SEC_PKCS7ContentInfo));
-
- PORT_ArenaUnmark(poolp, mark);
- return asafe;
-
-loser:
- PORT_ArenaRelease(poolp, mark);
- return NULL;
-}
-
-/* create a safe contents structure with a list of
- * length 0 with the first element being NULL
- */
-SEC_PKCS12SafeContents *
-sec_pkcs12_create_safe_contents(PRArenaPool *poolp)
-{
- SEC_PKCS12SafeContents *safe;
- void *mark;
-
- if(poolp == NULL)
- return NULL;
-
- /* allocate structure */
- mark = PORT_ArenaMark(poolp);
- safe = (SEC_PKCS12SafeContents *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS12SafeContents));
- if(safe == NULL)
- {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_ArenaRelease(poolp, mark);
- return NULL;
- }
-
- /* init list */
- safe->contents = (SEC_PKCS12SafeBag**)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS12SafeBag *));
- if(safe->contents == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_ArenaRelease(poolp, mark);
- return NULL;
- }
- safe->contents[0] = NULL;
- safe->poolp = poolp;
- safe->safe_size = 0;
- PORT_ArenaUnmark(poolp, mark);
- return safe;
-}
-
-/* create a new external bag which is appended onto the list
- * of bags in baggage. the bag is created in the same arena
- * as baggage
- */
-SEC_PKCS12BaggageItem *
-sec_pkcs12_create_external_bag(SEC_PKCS12Baggage *luggage)
-{
- void *dummy, *mark;
- SEC_PKCS12BaggageItem *bag;
-
- if(luggage == NULL) {
- return NULL;
- }
-
- mark = PORT_ArenaMark(luggage->poolp);
-
- /* allocate space for null terminated bag list */
- if(luggage->bags == NULL) {
- luggage->bags=(SEC_PKCS12BaggageItem**)PORT_ArenaZAlloc(luggage->poolp,
- sizeof(SEC_PKCS12BaggageItem *));
- if(luggage->bags == NULL) {
- goto loser;
- }
- luggage->luggage_size = 0;
- }
-
- /* grow the list */
- dummy = PORT_ArenaGrow(luggage->poolp, luggage->bags,
- sizeof(SEC_PKCS12BaggageItem *) * (luggage->luggage_size + 1),
- sizeof(SEC_PKCS12BaggageItem *) * (luggage->luggage_size + 2));
- if(dummy == NULL) {
- goto loser;
- }
- luggage->bags = (SEC_PKCS12BaggageItem**)dummy;
-
- luggage->bags[luggage->luggage_size] =
- (SEC_PKCS12BaggageItem *)PORT_ArenaZAlloc(luggage->poolp,
- sizeof(SEC_PKCS12BaggageItem));
- if(luggage->bags[luggage->luggage_size] == NULL) {
- goto loser;
- }
-
- /* create new bag and append it to the end */
- bag = luggage->bags[luggage->luggage_size];
- bag->espvks = (SEC_PKCS12ESPVKItem **)PORT_ArenaZAlloc(
- luggage->poolp,
- sizeof(SEC_PKCS12ESPVKItem *));
- bag->unencSecrets = (SEC_PKCS12SafeBag **)PORT_ArenaZAlloc(
- luggage->poolp,
- sizeof(SEC_PKCS12SafeBag *));
- if((bag->espvks == NULL) || (bag->unencSecrets == NULL)) {
- goto loser;
- }
-
- bag->poolp = luggage->poolp;
- luggage->luggage_size++;
- luggage->bags[luggage->luggage_size] = NULL;
- bag->espvks[0] = NULL;
- bag->unencSecrets[0] = NULL;
- bag->nEspvks = bag->nSecrets = 0;
-
- PORT_ArenaUnmark(luggage->poolp, mark);
- return bag;
-
-loser:
- PORT_ArenaRelease(luggage->poolp, mark);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
-}
-
-/* creates a baggage witha NULL terminated 0 length list */
-SEC_PKCS12Baggage *
-sec_pkcs12_create_baggage(PRArenaPool *poolp)
-{
- SEC_PKCS12Baggage *luggage;
- void *mark;
-
- if(poolp == NULL)
- return NULL;
-
- mark = PORT_ArenaMark(poolp);
-
- /* allocate bag */
- luggage = (SEC_PKCS12Baggage *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS12Baggage));
- if(luggage == NULL)
- {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_ArenaRelease(poolp, mark);
- return NULL;
- }
-
- /* init list */
- luggage->bags = (SEC_PKCS12BaggageItem **)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS12BaggageItem *));
- if(luggage->bags == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_ArenaRelease(poolp, mark);
- return NULL;
- }
-
- luggage->bags[0] = NULL;
- luggage->luggage_size = 0;
- luggage->poolp = poolp;
-
- PORT_ArenaUnmark(poolp, mark);
- return luggage;
-}
-
-/* free pfx structure and associated items in the arena */
-void
-SEC_PKCS12DestroyPFX(SEC_PKCS12PFXItem *pfx)
-{
- if (pfx != NULL && pfx->poolp != NULL)
- {
- PORT_FreeArena(pfx->poolp, PR_TRUE);
- }
-}
diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c
deleted file mode 100644
index 6b2a90044..000000000
--- a/security/nss/lib/pkcs12/p12d.c
+++ /dev/null
@@ -1,3548 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#include "nssrenam.h"
-#include "p12t.h"
-#include "p12.h"
-#include "plarena.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "seccomon.h"
-#include "secport.h"
-#include "cert.h"
-#include "secpkcs7.h"
-#include "secasn1.h"
-#include "secerr.h"
-#include "pk11func.h"
-#include "p12plcy.h"
-#include "p12local.h"
-#include "secder.h"
-#include "secport.h"
-
-#include "certdb.h"
-
-#include "prcpucfg.h"
-
-/* This belongs in secport.h */
-#define PORT_ArenaGrowArray(poolp, oldptr, type, oldnum, newnum) \
- (type *)PORT_ArenaGrow((poolp), (oldptr), \
- (oldnum) * sizeof(type), (newnum) * sizeof(type))
-
-
-typedef struct sec_PKCS12SafeContentsContextStr sec_PKCS12SafeContentsContext;
-
-/* Opaque structure for decoding SafeContents. These are used
- * for each authenticated safe as well as any nested safe contents.
- */
-struct sec_PKCS12SafeContentsContextStr {
- /* the parent decoder context */
- SEC_PKCS12DecoderContext *p12dcx;
-
- /* memory arena to allocate space from */
- PRArenaPool *arena;
-
- /* decoder context and destination for decoding safe contents */
- SEC_ASN1DecoderContext *safeContentsA1Dcx;
- sec_PKCS12SafeContents safeContents;
-
- /* information for decoding safe bags within the safe contents.
- * these variables are updated for each safe bag decoded.
- */
- SEC_ASN1DecoderContext *currentSafeBagA1Dcx;
- sec_PKCS12SafeBag *currentSafeBag;
- PRBool skipCurrentSafeBag;
-
- /* if the safe contents is nested, the parent is pointed to here. */
- sec_PKCS12SafeContentsContext *nestedSafeContentsCtx;
-};
-
-/* opaque decoder context structure. information for decoding a pkcs 12
- * PDU are stored here as well as decoding pointers for intermediary
- * structures which are part of the PKCS 12 PDU. Upon a successful
- * decode, the safe bags containing certificates and keys encountered.
- */
-struct SEC_PKCS12DecoderContextStr {
- PRArenaPool *arena;
- PK11SlotInfo *slot;
- void *wincx;
- PRBool error;
- int errorValue;
-
- /* password */
- SECItem *pwitem;
-
- /* used for decoding the PFX structure */
- SEC_ASN1DecoderContext *pfxA1Dcx;
- sec_PKCS12PFXItem pfx;
-
- /* safe bags found during decoding */
- sec_PKCS12SafeBag **safeBags;
- unsigned int safeBagCount;
-
- /* state variables for decoding authenticated safes. */
- SEC_PKCS7DecoderContext *currentASafeP7Dcx;
- SEC_ASN1DecoderContext *aSafeA1Dcx;
- SEC_PKCS7DecoderContext *aSafeP7Dcx;
- SEC_PKCS7ContentInfo *aSafeCinfo;
- sec_PKCS12AuthenticatedSafe authSafe;
- sec_PKCS12SafeContents safeContents;
-
- /* safe contents info */
- unsigned int safeContentsCnt;
- sec_PKCS12SafeContentsContext **safeContentsList;
-
- /* HMAC info */
- sec_PKCS12MacData macData;
-
- /* routines for reading back the data to be hmac'd */
- /* They are called as follows.
- *
- * Stage 1: decode the aSafes cinfo into a buffer in dArg,
- * which p12d.c sometimes refers to as the "temp file".
- * This occurs during SEC_PKCS12DecoderUpdate calls.
- *
- * dOpen(dArg, PR_FALSE)
- * dWrite(dArg, buf, len)
- * ...
- * dWrite(dArg, buf, len)
- * dClose(dArg, PR_FALSE)
- *
- * Stage 2: verify MAC
- * This occurs SEC_PKCS12DecoderVerify.
- *
- * dOpen(dArg, PR_TRUE)
- * dRead(dArg, buf, IN_BUF_LEN)
- * ...
- * dRead(dArg, buf, IN_BUF_LEN)
- * dClose(dArg, PR_TRUE)
- */
- digestOpenFn dOpen;
- digestCloseFn dClose;
- digestIOFn dRead, dWrite;
- void *dArg;
- PRBool dIsOpen; /* is the temp file created? */
-
- /* helper functions */
- SECKEYGetPasswordKey pwfn;
- void *pwfnarg;
- PRBool swapUnicodeBytes;
-
- /* import information */
- PRBool bagsVerified;
-
- /* buffer management for the default callbacks implementation */
- void *buffer; /* storage area */
- PRInt32 filesize; /* actual data size */
- PRInt32 allocated; /* total buffer size allocated */
- PRInt32 currentpos; /* position counter */
- SECPKCS12TargetTokenCAs tokenCAs;
- sec_PKCS12SafeBag **keyList;/* used by ...IterateNext() */
- unsigned int iteration;
- SEC_PKCS12DecoderItem decitem;
-};
-
-/* forward declarations of functions that are used when decoding
- * safeContents bags which are nested and when decoding the
- * authenticatedSafes.
- */
-static SECStatus
-sec_pkcs12_decoder_begin_nested_safe_contents(sec_PKCS12SafeContentsContext
- *safeContentsCtx);
-static SECStatus
-sec_pkcs12_decoder_finish_nested_safe_contents(sec_PKCS12SafeContentsContext
- *safeContentsCtx);
-
-
-/* make sure that the PFX version being decoded is a version
- * which we support.
- */
-static PRBool
-sec_pkcs12_proper_version(sec_PKCS12PFXItem *pfx)
-{
- /* if no version, assume it is not supported */
- if(pfx->version.len == 0) {
- return PR_FALSE;
- }
-
- if(DER_GetInteger(&pfx->version) > SEC_PKCS12_VERSION) {
- return PR_FALSE;
- }
-
- return PR_TRUE;
-}
-
-/* retrieve the key for decrypting the safe contents */
-static PK11SymKey *
-sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid)
-{
- SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext *) arg;
- PK11SlotInfo *slot;
- PK11SymKey *bulkKey;
-
- if(!p12dcx) {
- return NULL;
- }
-
- /* if no slot specified, use the internal key slot */
- if(p12dcx->slot) {
- slot = PK11_ReferenceSlot(p12dcx->slot);
- } else {
- slot = PK11_GetInternalKeySlot();
- }
-
- bulkKey = PK11_PBEKeyGen(slot, algid, p12dcx->pwitem,
- PR_FALSE, p12dcx->wincx);
- /* some tokens can't generate PBE keys on their own, generate the
- * key in the internal slot, and let the Import code deal with it,
- * (if the slot can't generate PBEs, then we need to use the internal
- * slot anyway to unwrap). */
- if (!bulkKey && !PK11_IsInternal(slot)) {
- PK11_FreeSlot(slot);
- slot = PK11_GetInternalKeySlot();
- bulkKey = PK11_PBEKeyGen(slot, algid, p12dcx->pwitem,
- PR_FALSE, p12dcx->wincx);
- }
- PK11_FreeSlot(slot);
-
- /* set the password data on the key */
- if (bulkKey) {
- PK11_SetSymKeyUserData(bulkKey,p12dcx->pwitem, NULL);
- }
-
-
- return bulkKey;
-}
-
-/* XXX this needs to be modified to handle enveloped data. most
- * likely, it should mirror the routines for SMIME in that regard.
- */
-static PRBool
-sec_pkcs12_decoder_decryption_allowed(SECAlgorithmID *algid,
- PK11SymKey *bulkkey)
-{
- PRBool decryptionAllowed = SEC_PKCS12DecryptionAllowed(algid);
-
- if(!decryptionAllowed) {
- return PR_FALSE;
- }
-
- return PR_TRUE;
-}
-
-/* when we encounter a new safe bag during the decoding, we need
- * to allocate space for the bag to be decoded to and set the
- * state variables appropriately. all of the safe bags are allocated
- * in a buffer in the outer SEC_PKCS12DecoderContext, however,
- * a pointer to the safeBag is also used in the sec_PKCS12SafeContentsContext
- * for the current bag.
- */
-static SECStatus
-sec_pkcs12_decoder_init_new_safe_bag(sec_PKCS12SafeContentsContext
- *safeContentsCtx)
-{
- void *mark = NULL;
- SEC_PKCS12DecoderContext *p12dcx;
-
- /* make sure that the structures are defined, and there has
- * not been an error in the decoding
- */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx
- || safeContentsCtx->p12dcx->error) {
- return SECFailure;
- }
-
- p12dcx = safeContentsCtx->p12dcx;
- mark = PORT_ArenaMark(p12dcx->arena);
-
- /* allocate a new safe bag, if bags already exist, grow the
- * list of bags, otherwise allocate a new list. the list is
- * NULL terminated.
- */
- p12dcx->safeBags = (!p12dcx->safeBagCount)
- ? PORT_ArenaZNewArray(p12dcx->arena, sec_PKCS12SafeBag *, 2)
- : PORT_ArenaGrowArray(p12dcx->arena, p12dcx->safeBags,
- sec_PKCS12SafeBag *, p12dcx->safeBagCount + 1,
- p12dcx->safeBagCount + 2);
-
- if(!p12dcx->safeBags) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
-
- /* append the bag to the end of the list and update the reference
- * in the safeContentsCtx.
- */
- p12dcx->safeBags[p12dcx->safeBagCount] =
- safeContentsCtx->currentSafeBag =
- PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeBag);
- if(!safeContentsCtx->currentSafeBag) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
- p12dcx->safeBags[++p12dcx->safeBagCount] = NULL;
-
- safeContentsCtx->currentSafeBag->slot = safeContentsCtx->p12dcx->slot;
- safeContentsCtx->currentSafeBag->pwitem = safeContentsCtx->p12dcx->pwitem;
- safeContentsCtx->currentSafeBag->swapUnicodeBytes =
- safeContentsCtx->p12dcx->swapUnicodeBytes;
- safeContentsCtx->currentSafeBag->arena = safeContentsCtx->p12dcx->arena;
- safeContentsCtx->currentSafeBag->tokenCAs =
- safeContentsCtx->p12dcx->tokenCAs;
-
- PORT_ArenaUnmark(p12dcx->arena, mark);
- return SECSuccess;
-
-loser:
-
- /* if an error occurred, release the memory and set the error flag
- * the only possible errors triggered by this function are memory
- * related.
- */
- if(mark) {
- PORT_ArenaRelease(p12dcx->arena, mark);
- }
-
- p12dcx->error = PR_TRUE;
- return SECFailure;
-}
-
-/* A wrapper for updating the ASN1 context in which a safeBag is
- * being decoded. This function is called as a callback from
- * secasn1d when decoding SafeContents structures.
- */
-static void
-sec_pkcs12_decoder_safe_bag_update(void *arg, const char *data,
- unsigned long len, int depth,
- SEC_ASN1EncodingPart data_kind)
-{
- sec_PKCS12SafeContentsContext *safeContentsCtx =
- (sec_PKCS12SafeContentsContext *)arg;
- SEC_PKCS12DecoderContext *p12dcx;
- SECStatus rv;
-
- /* make sure that we are not skipping the current safeBag,
- * and that there are no errors. If so, just return rather
- * than continuing to process.
- */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx
- || safeContentsCtx->p12dcx->error
- || safeContentsCtx->skipCurrentSafeBag) {
- return;
- }
- p12dcx = safeContentsCtx->p12dcx;
-
- rv = SEC_ASN1DecoderUpdate(safeContentsCtx->currentSafeBagA1Dcx, data, len);
- if(rv != SECSuccess) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
-
- return;
-
-loser:
- /* set the error, and finish the decoder context. because there
- * is not a way of returning an error message, it may be worth
- * while to do a check higher up and finish any decoding contexts
- * that are still open.
- */
- p12dcx->error = PR_TRUE;
- SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx);
- safeContentsCtx->currentSafeBagA1Dcx = NULL;
- return;
-}
-
-/* notify function for decoding safeBags. This function is
- * used to filter safeBag types which are not supported,
- * initiate the decoding of nested safe contents, and decode
- * safeBags in general. this function is set when the decoder
- * context for the safeBag is first created.
- */
-static void
-sec_pkcs12_decoder_safe_bag_notify(void *arg, PRBool before,
- void *dest, int real_depth)
-{
- sec_PKCS12SafeContentsContext *safeContentsCtx =
- (sec_PKCS12SafeContentsContext *)arg;
- SEC_PKCS12DecoderContext *p12dcx;
- sec_PKCS12SafeBag *bag;
- PRBool after;
-
- /* if an error is encountered, return */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx ||
- safeContentsCtx->p12dcx->error) {
- return;
- }
- p12dcx = safeContentsCtx->p12dcx;
-
- /* to make things more readable */
- if(before)
- after = PR_FALSE;
- else
- after = PR_TRUE;
-
- /* have we determined the safeBagType yet? */
- bag = safeContentsCtx->currentSafeBag;
- if(bag->bagTypeTag == NULL) {
- if(after && (dest == &(bag->safeBagType))) {
- bag->bagTypeTag = SECOID_FindOID(&(bag->safeBagType));
- if(bag->bagTypeTag == NULL) {
- p12dcx->error = PR_TRUE;
- p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
- }
- }
- return;
- }
-
- /* process the safeBag depending on it's type. those
- * which we do not support, are ignored. we start a decoding
- * context for a nested safeContents.
- */
- switch(bag->bagTypeTag->offset) {
- case SEC_OID_PKCS12_V1_KEY_BAG_ID:
- case SEC_OID_PKCS12_V1_CERT_BAG_ID:
- case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
- break;
- case SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID:
- /* if we are just starting to decode the safeContents, initialize
- * a new safeContentsCtx to process it.
- */
- if(before && (dest == &(bag->safeBagContent))) {
- sec_pkcs12_decoder_begin_nested_safe_contents(safeContentsCtx);
- } else if(after && (dest == &(bag->safeBagContent))) {
- /* clean up the nested decoding */
- sec_pkcs12_decoder_finish_nested_safe_contents(safeContentsCtx);
- }
- break;
- case SEC_OID_PKCS12_V1_CRL_BAG_ID:
- case SEC_OID_PKCS12_V1_SECRET_BAG_ID:
- default:
- /* skip any safe bag types we don't understand or handle */
- safeContentsCtx->skipCurrentSafeBag = PR_TRUE;
- break;
- }
-
- return;
-}
-
-/* notify function for decoding safe contents. each entry in the
- * safe contents is a safeBag which needs to be allocated and
- * the decoding context initialized at the beginning and then
- * the context needs to be closed and finished at the end.
- *
- * this function is set when the safeContents decode context is
- * initialized.
- */
-static void
-sec_pkcs12_decoder_safe_contents_notify(void *arg, PRBool before,
- void *dest, int real_depth)
-{
- sec_PKCS12SafeContentsContext *safeContentsCtx =
- (sec_PKCS12SafeContentsContext*)arg;
- SEC_PKCS12DecoderContext *p12dcx;
- SECStatus rv;
-
- /* if there is an error we don't want to continue processing,
- * just return and keep going.
- */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx
- || safeContentsCtx->p12dcx->error) {
- return;
- }
- p12dcx = safeContentsCtx->p12dcx;
-
- /* if we are done with the current safeBag, then we need to
- * finish the context and set the state variables appropriately.
- */
- if(!before) {
- SEC_ASN1DecoderClearFilterProc(safeContentsCtx->safeContentsA1Dcx);
- SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx);
- safeContentsCtx->currentSafeBagA1Dcx = NULL;
- safeContentsCtx->skipCurrentSafeBag = PR_FALSE;
- } else {
- /* we are starting a new safe bag. we need to allocate space
- * for the bag and initialize the decoding context.
- */
- rv = sec_pkcs12_decoder_init_new_safe_bag(safeContentsCtx);
- if(rv != SECSuccess) {
- goto loser;
- }
-
- /* set up the decoder context */
- safeContentsCtx->currentSafeBagA1Dcx =
- SEC_ASN1DecoderStart(p12dcx->arena,
- safeContentsCtx->currentSafeBag,
- sec_PKCS12SafeBagTemplate);
- if(!safeContentsCtx->currentSafeBagA1Dcx) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
-
- /* set the notify and filter procs so that the safe bag
- * data gets sent to the proper location when decoding.
- */
- SEC_ASN1DecoderSetNotifyProc(safeContentsCtx->currentSafeBagA1Dcx,
- sec_pkcs12_decoder_safe_bag_notify,
- safeContentsCtx);
- SEC_ASN1DecoderSetFilterProc(safeContentsCtx->safeContentsA1Dcx,
- sec_pkcs12_decoder_safe_bag_update,
- safeContentsCtx, PR_TRUE);
- }
-
- return;
-
-loser:
- /* in the event of an error, we want to close the decoding
- * context and clear the filter and notify procedures.
- */
- p12dcx->error = PR_TRUE;
-
- if(safeContentsCtx->currentSafeBagA1Dcx) {
- SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx);
- safeContentsCtx->currentSafeBagA1Dcx = NULL;
- }
-
- SEC_ASN1DecoderClearNotifyProc(safeContentsCtx->safeContentsA1Dcx);
- SEC_ASN1DecoderClearFilterProc(safeContentsCtx->safeContentsA1Dcx);
-
- return;
-}
-
-/* initialize the safeContents for decoding. this routine
- * is used for authenticatedSafes as well as nested safeContents.
- */
-static sec_PKCS12SafeContentsContext *
-sec_pkcs12_decoder_safe_contents_init_decode(SEC_PKCS12DecoderContext *p12dcx,
- PRBool nestedSafe)
-{
- sec_PKCS12SafeContentsContext *safeContentsCtx = NULL;
- const SEC_ASN1Template *theTemplate;
-
- if(!p12dcx || p12dcx->error) {
- return NULL;
- }
-
- /* allocate a new safeContents list or grow the existing list and
- * append the new safeContents onto the end.
- */
- p12dcx->safeContentsList = (!p12dcx->safeContentsCnt)
- ? PORT_ArenaZNewArray(p12dcx->arena, sec_PKCS12SafeContentsContext *, 2)
- : PORT_ArenaGrowArray(p12dcx->arena, p12dcx->safeContentsList,
- sec_PKCS12SafeContentsContext *,
- 1 + p12dcx->safeContentsCnt,
- 2 + p12dcx->safeContentsCnt);
-
- if(!p12dcx->safeContentsList) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
-
- p12dcx->safeContentsList[p12dcx->safeContentsCnt] = safeContentsCtx =
- PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeContentsContext);
- if(!p12dcx->safeContentsList[p12dcx->safeContentsCnt]) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
- p12dcx->safeContentsList[++p12dcx->safeContentsCnt] = NULL;
-
- /* set up the state variables */
- safeContentsCtx->p12dcx = p12dcx;
- safeContentsCtx->arena = p12dcx->arena;
-
- /* begin the decoding -- the template is based on whether we are
- * decoding a nested safeContents or not.
- */
- if(nestedSafe == PR_TRUE) {
- theTemplate = sec_PKCS12NestedSafeContentsDecodeTemplate;
- } else {
- theTemplate = sec_PKCS12SafeContentsDecodeTemplate;
- }
-
- /* start the decoder context */
- safeContentsCtx->safeContentsA1Dcx = SEC_ASN1DecoderStart(p12dcx->arena,
- &safeContentsCtx->safeContents,
- theTemplate);
-
- if(!safeContentsCtx->safeContentsA1Dcx) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
-
- /* set the safeContents notify procedure to look for
- * and start the decode of safeBags.
- */
- SEC_ASN1DecoderSetNotifyProc(safeContentsCtx->safeContentsA1Dcx,
- sec_pkcs12_decoder_safe_contents_notify,
- safeContentsCtx);
-
- return safeContentsCtx;
-
-loser:
- /* in the case of an error, we want to finish the decoder
- * context and set the error flag.
- */
- if(safeContentsCtx && safeContentsCtx->safeContentsA1Dcx) {
- SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
- safeContentsCtx->safeContentsA1Dcx = NULL;
- }
-
- p12dcx->error = PR_TRUE;
-
- return NULL;
-}
-
-/* wrapper for updating safeContents. this is set as the filter of
- * safeBag when there is a nested safeContents.
- */
-static void
-sec_pkcs12_decoder_nested_safe_contents_update(void *arg, const char *buf,
- unsigned long len, int depth,
- SEC_ASN1EncodingPart data_kind)
-{
- sec_PKCS12SafeContentsContext *safeContentsCtx =
- (sec_PKCS12SafeContentsContext *)arg;
- SEC_PKCS12DecoderContext *p12dcx;
- SECStatus rv;
-
- /* check for an error */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx
- || safeContentsCtx->p12dcx->error
- || !safeContentsCtx->safeContentsA1Dcx) {
- return;
- }
-
- /* no need to update if no data sent in */
- if(!len || !buf) {
- return;
- }
-
- /* update the decoding context */
- p12dcx = safeContentsCtx->p12dcx;
- rv = SEC_ASN1DecoderUpdate(safeContentsCtx->safeContentsA1Dcx, buf, len);
- if(rv != SECSuccess) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
-
- return;
-
-loser:
- /* handle any errors. If a decoding context is open, close it. */
- p12dcx->error = PR_TRUE;
- if(safeContentsCtx->safeContentsA1Dcx) {
- SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
- safeContentsCtx->safeContentsA1Dcx = NULL;
- }
-}
-
-/* whenever a new safeContentsSafeBag is encountered, we need
- * to init a safeContentsContext.
- */
-static SECStatus
-sec_pkcs12_decoder_begin_nested_safe_contents(sec_PKCS12SafeContentsContext
- *safeContentsCtx)
-{
- /* check for an error */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx ||
- safeContentsCtx->p12dcx->error) {
- return SECFailure;
- }
-
- safeContentsCtx->nestedSafeContentsCtx =
- sec_pkcs12_decoder_safe_contents_init_decode(safeContentsCtx->p12dcx,
- PR_TRUE);
- if(!safeContentsCtx->nestedSafeContentsCtx) {
- return SECFailure;
- }
-
- /* set up new filter proc */
- SEC_ASN1DecoderSetNotifyProc(
- safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx,
- sec_pkcs12_decoder_safe_contents_notify,
- safeContentsCtx->nestedSafeContentsCtx);
-
- SEC_ASN1DecoderSetFilterProc(safeContentsCtx->currentSafeBagA1Dcx,
- sec_pkcs12_decoder_nested_safe_contents_update,
- safeContentsCtx->nestedSafeContentsCtx,
- PR_TRUE);
-
- return SECSuccess;
-}
-
-/* when the safeContents is done decoding, we need to reset the
- * proper filter and notify procs and close the decoding context
- */
-static SECStatus
-sec_pkcs12_decoder_finish_nested_safe_contents(sec_PKCS12SafeContentsContext
- *safeContentsCtx)
-{
- /* check for error */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx ||
- safeContentsCtx->p12dcx->error) {
- return SECFailure;
- }
-
- /* clean up */
- SEC_ASN1DecoderClearFilterProc(safeContentsCtx->currentSafeBagA1Dcx);
- SEC_ASN1DecoderClearNotifyProc(
- safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx);
- SEC_ASN1DecoderFinish(
- safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx);
- safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx = NULL;
- safeContentsCtx->nestedSafeContentsCtx = NULL;
-
- return SECSuccess;
-}
-
-/* wrapper for updating safeContents. This is used when decoding
- * the nested safeContents and any authenticatedSafes.
- */
-static void
-sec_pkcs12_decoder_safe_contents_callback(void *arg, const char *buf,
- unsigned long len)
-{
- SECStatus rv;
- sec_PKCS12SafeContentsContext *safeContentsCtx =
- (sec_PKCS12SafeContentsContext *)arg;
- SEC_PKCS12DecoderContext *p12dcx;
-
- /* check for error */
- if(!safeContentsCtx || !safeContentsCtx->p12dcx
- || safeContentsCtx->p12dcx->error
- || !safeContentsCtx->safeContentsA1Dcx) {
- return;
- }
- p12dcx = safeContentsCtx->p12dcx;
-
- /* update the decoder */
- rv = SEC_ASN1DecoderUpdate(safeContentsCtx->safeContentsA1Dcx, buf, len);
- if(rv != SECSuccess) {
- /* if we fail while trying to decode a 'safe', it's probably because
- * we didn't have the correct password. */
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
- SEC_PKCS7DecoderAbort(p12dcx->currentASafeP7Dcx,SEC_ERROR_BAD_PASSWORD);
- goto loser;
- }
-
- return;
-
-loser:
- /* set the error and finish the context */
- p12dcx->error = PR_TRUE;
- if(safeContentsCtx->safeContentsA1Dcx) {
- SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
- safeContentsCtx->safeContentsA1Dcx = NULL;
- }
-
- return;
-}
-
-/* this is a wrapper for the ASN1 decoder to call SEC_PKCS7DecoderUpdate
- */
-static void
-sec_pkcs12_decoder_wrap_p7_update(void *arg, const char *data,
- unsigned long len, int depth,
- SEC_ASN1EncodingPart data_kind)
-{
- SEC_PKCS7DecoderContext *p7dcx = (SEC_PKCS7DecoderContext *)arg;
-
- SEC_PKCS7DecoderUpdate(p7dcx, data, len);
-}
-
-/* notify function for decoding aSafes. at the beginning,
- * of an authenticatedSafe, we start a decode of a safeContents.
- * at the end, we clean up the safeContents decoder context and
- * reset state variables
- */
-static void
-sec_pkcs12_decoder_asafes_notify(void *arg, PRBool before, void *dest,
- int real_depth)
-{
- SEC_PKCS12DecoderContext *p12dcx;
- sec_PKCS12SafeContentsContext *safeContentsCtx;
-
- /* make sure no error occurred. */
- p12dcx = (SEC_PKCS12DecoderContext *)arg;
- if(!p12dcx || p12dcx->error) {
- return;
- }
-
- if(before) {
-
- /* init a new safeContentsContext */
- safeContentsCtx = sec_pkcs12_decoder_safe_contents_init_decode(p12dcx,
- PR_FALSE);
- if(!safeContentsCtx) {
- goto loser;
- }
-
- /* initiate the PKCS7ContentInfo decode */
- p12dcx->currentASafeP7Dcx = SEC_PKCS7DecoderStart(
- sec_pkcs12_decoder_safe_contents_callback,
- safeContentsCtx,
- p12dcx->pwfn, p12dcx->pwfnarg,
- sec_pkcs12_decoder_get_decrypt_key, p12dcx,
- sec_pkcs12_decoder_decryption_allowed);
- if(!p12dcx->currentASafeP7Dcx) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
- SEC_ASN1DecoderSetFilterProc(p12dcx->aSafeA1Dcx,
- sec_pkcs12_decoder_wrap_p7_update,
- p12dcx->currentASafeP7Dcx, PR_TRUE);
- }
-
- if(!before) {
- /* if one is being decoded, finish the decode */
- if(p12dcx->currentASafeP7Dcx != NULL) {
- SEC_PKCS7ContentInfo * cinfo;
- unsigned int cnt = p12dcx->safeContentsCnt - 1;
- safeContentsCtx = p12dcx->safeContentsList[cnt];
- if (safeContentsCtx->safeContentsA1Dcx) {
- SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
- safeContentsCtx->safeContentsA1Dcx = NULL;
- }
- cinfo = SEC_PKCS7DecoderFinish(p12dcx->currentASafeP7Dcx);
- p12dcx->currentASafeP7Dcx = NULL;
- if(!cinfo) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
- SEC_PKCS7DestroyContentInfo(cinfo); /* don't leak it */
- }
- }
-
-
- return;
-
-loser:
- /* set the error flag */
- p12dcx->error = PR_TRUE;
- return;
-}
-
-/* wrapper for updating asafes decoding context. this function
- * writes data being decoded to disk, so that a mac can be computed
- * later.
- */
-static void
-sec_pkcs12_decoder_asafes_callback(void *arg, const char *buf,
- unsigned long len)
-{
- SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext *)arg;
- SECStatus rv;
-
- if(!p12dcx || p12dcx->error) {
- return;
- }
-
- /* update the context */
- rv = SEC_ASN1DecoderUpdate(p12dcx->aSafeA1Dcx, buf, len);
- if(rv != SECSuccess) {
- p12dcx->errorValue = PORT_GetError();
- p12dcx->error = PR_TRUE;
- goto loser;
- }
-
- /* if we are writing to a file, write out the new information */
- if(p12dcx->dWrite) {
- unsigned long writeLen = (*p12dcx->dWrite)(p12dcx->dArg,
- (unsigned char *)buf, len);
- if(writeLen != len) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
- }
-
- return;
-
-loser:
- /* set the error flag */
- p12dcx->error = PR_TRUE;
- SEC_ASN1DecoderFinish(p12dcx->aSafeA1Dcx);
- p12dcx->aSafeA1Dcx = NULL;
-
- return;
-}
-
-/* start the decode of an authenticatedSafe contentInfo.
- */
-static SECStatus
-sec_pkcs12_decode_start_asafes_cinfo(SEC_PKCS12DecoderContext *p12dcx)
-{
- if(!p12dcx || p12dcx->error) {
- return SECFailure;
- }
-
- /* start the decode context */
- p12dcx->aSafeA1Dcx = SEC_ASN1DecoderStart(p12dcx->arena,
- &p12dcx->authSafe,
- sec_PKCS12AuthenticatedSafeTemplate);
- if(!p12dcx->aSafeA1Dcx) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
-
- /* set the notify function */
- SEC_ASN1DecoderSetNotifyProc(p12dcx->aSafeA1Dcx,
- sec_pkcs12_decoder_asafes_notify, p12dcx);
-
- /* begin the authSafe decoder context */
- p12dcx->aSafeP7Dcx = SEC_PKCS7DecoderStart(
- sec_pkcs12_decoder_asafes_callback, p12dcx,
- p12dcx->pwfn, p12dcx->pwfnarg, NULL, NULL, NULL);
- if(!p12dcx->aSafeP7Dcx) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
-
- /* open the temp file for writing, if the digest functions were set */
- if(p12dcx->dOpen && (*p12dcx->dOpen)(p12dcx->dArg, PR_FALSE)
- != SECSuccess) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
- /* dOpen(dArg, PR_FALSE) creates the temp file */
- p12dcx->dIsOpen = PR_TRUE;
-
- return SECSuccess;
-
-loser:
- p12dcx->error = PR_TRUE;
-
- if(p12dcx->aSafeA1Dcx) {
- SEC_ASN1DecoderFinish(p12dcx->aSafeA1Dcx);
- p12dcx->aSafeA1Dcx = NULL;
- }
-
- if(p12dcx->aSafeP7Dcx) {
- SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
- p12dcx->aSafeP7Dcx = NULL;
- }
-
- return SECFailure;
-}
-
-/* wrapper for updating the safeContents. this function is used as
- * a filter for the pfx when decoding the authenticated safes
- */
-static void
-sec_pkcs12_decode_asafes_cinfo_update(void *arg, const char *buf,
- unsigned long len, int depth,
- SEC_ASN1EncodingPart data_kind)
-{
- SEC_PKCS12DecoderContext *p12dcx;
- SECStatus rv;
-
- p12dcx = (SEC_PKCS12DecoderContext*)arg;
- if(!p12dcx || p12dcx->error) {
- return;
- }
-
- /* update the safeContents decoder */
- rv = SEC_PKCS7DecoderUpdate(p12dcx->aSafeP7Dcx, buf, len);
- if(rv != SECSuccess) {
- p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
- goto loser;
- }
-
- return;
-
-loser:
-
- /* did we find an error? if so, close the context and set the
- * error flag.
- */
- SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
- p12dcx->aSafeP7Dcx = NULL;
- p12dcx->error = PR_TRUE;
-}
-
-/* notify procedure used while decoding the pfx. When we encounter
- * the authSafes, we want to trigger the decoding of authSafes as well
- * as when we encounter the macData, trigger the decoding of it. we do
- * this because we we are streaming the decoder and not decoding in place.
- * the pfx which is the destination, only has the version decoded into it.
- */
-static void
-sec_pkcs12_decoder_pfx_notify_proc(void *arg, PRBool before, void *dest,
- int real_depth)
-{
- SECStatus rv;
- SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext*)arg;
-
- /* if an error occurs, clear the notifyProc and the filterProc
- * and continue.
- */
- if(p12dcx->error) {
- SEC_ASN1DecoderClearNotifyProc(p12dcx->pfxA1Dcx);
- SEC_ASN1DecoderClearFilterProc(p12dcx->pfxA1Dcx);
- return;
- }
-
- if(before && (dest == &p12dcx->pfx.encodedAuthSafe)) {
-
- /* we want to make sure this is a version we support */
- if(!sec_pkcs12_proper_version(&p12dcx->pfx)) {
- p12dcx->errorValue = SEC_ERROR_PKCS12_UNSUPPORTED_VERSION;
- goto loser;
- }
-
- /* start the decode of the aSafes cinfo... */
- rv = sec_pkcs12_decode_start_asafes_cinfo(p12dcx);
- if(rv != SECSuccess) {
- goto loser;
- }
-
- /* set the filter proc to update the authenticated safes. */
- SEC_ASN1DecoderSetFilterProc(p12dcx->pfxA1Dcx,
- sec_pkcs12_decode_asafes_cinfo_update,
- p12dcx, PR_TRUE);
- }
-
- if(!before && (dest == &p12dcx->pfx.encodedAuthSafe)) {
-
- /* we are done decoding the authenticatedSafes, so we need to
- * finish the decoderContext and clear the filter proc
- * and close the hmac callback, if present
- */
- p12dcx->aSafeCinfo = SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
- p12dcx->aSafeP7Dcx = NULL;
- if(!p12dcx->aSafeCinfo) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
- SEC_ASN1DecoderClearFilterProc(p12dcx->pfxA1Dcx);
- if(p12dcx->dClose && ((*p12dcx->dClose)(p12dcx->dArg, PR_FALSE)
- != SECSuccess)) {
- p12dcx->errorValue = PORT_GetError();
- goto loser;
- }
-
- }
-
- return;
-
-loser:
- p12dcx->error = PR_TRUE;
-}
-
-/* default implementations of the open/close/read/write functions for
- SEC_PKCS12DecoderStart
-*/
-
-#define DEFAULT_TEMP_SIZE 4096
-
-static SECStatus
-p12u_DigestOpen(void *arg, PRBool readData)
-{
- SEC_PKCS12DecoderContext* p12cxt = arg;
-
- p12cxt->currentpos = 0;
-
- if (PR_FALSE == readData) {
- /* allocate an initial buffer */
- p12cxt->filesize = 0;
- p12cxt->allocated = DEFAULT_TEMP_SIZE;
- p12cxt->buffer = PORT_Alloc(DEFAULT_TEMP_SIZE);
- PR_ASSERT(p12cxt->buffer);
- }
- else
- {
- PR_ASSERT(p12cxt->buffer);
- if (!p12cxt->buffer) {
- return SECFailure; /* no data to read */
- }
- }
-
- return SECSuccess;
-}
-
-static SECStatus
-p12u_DigestClose(void *arg, PRBool removeFile)
-{
- SEC_PKCS12DecoderContext* p12cxt = arg;
-
- PR_ASSERT(p12cxt);
- if (!p12cxt) {
- return SECFailure;
- }
- p12cxt->currentpos = 0;
-
- if (PR_TRUE == removeFile) {
- PR_ASSERT(p12cxt->buffer);
- if (!p12cxt->buffer) {
- return SECFailure;
- }
- if (p12cxt->buffer) {
- PORT_Free(p12cxt->buffer);
- p12cxt->buffer = NULL;
- p12cxt->allocated = 0;
- p12cxt->filesize = 0;
- }
- }
-
- return SECSuccess;
-}
-
-static int
-p12u_DigestRead(void *arg, unsigned char *buf, unsigned long len)
-{
- int toread = len;
- SEC_PKCS12DecoderContext* p12cxt = arg;
-
- if(!buf || len == 0 || !p12cxt->buffer) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return -1;
- }
-
- if ((p12cxt->filesize - p12cxt->currentpos) < (long)len) {
- /* trying to read past the end of the buffer */
- toread = p12cxt->filesize - p12cxt->currentpos;
- }
- memcpy(buf, (char*)p12cxt->buffer + p12cxt->currentpos, toread);
- p12cxt->currentpos += toread;
- return toread;
-}
-
-static int
-p12u_DigestWrite(void *arg, unsigned char *buf, unsigned long len)
-{
- SEC_PKCS12DecoderContext* p12cxt = arg;
-
- if(!buf || len == 0) {
- return -1;
- }
-
- if (p12cxt->currentpos+(long)len > p12cxt->filesize) {
- p12cxt->filesize = p12cxt->currentpos + len;
- }
- else {
- p12cxt->filesize += len;
- }
- if (p12cxt->filesize > p12cxt->allocated) {
- void* newbuffer;
- size_t newsize = p12cxt->filesize + DEFAULT_TEMP_SIZE;
- newbuffer = PORT_Realloc(p12cxt->buffer, newsize);
- if (NULL == newbuffer) {
- return -1; /* can't extend the buffer */
- }
- p12cxt->buffer = newbuffer;
- p12cxt->allocated = newsize;
- }
- PR_ASSERT(p12cxt->buffer);
- memcpy((char*)p12cxt->buffer + p12cxt->currentpos, buf, len);
- p12cxt->currentpos += len;
- return len;
-}
-
-/* SEC_PKCS12DecoderStart
- * Creates a decoder context for decoding a PKCS 12 PDU objct.
- * This function sets up the initial decoding context for the
- * PFX and sets the needed state variables.
- *
- * pwitem - the password for the hMac and any encoded safes.
- * this should be changed to take a callback which retrieves
- * the password. it may be possible for different safes to
- * have different passwords. also, the password is already
- * in unicode. it should probably be converted down below via
- * a unicode conversion callback.
- * slot - the slot to import the dataa into should multiple slots
- * be supported based on key type and cert type?
- * dOpen, dClose, dRead, dWrite - digest routines for writing data
- * to a file so it could be read back and the hmac recomputed
- * and verified. doesn't seem to be a way for both encoding
- * and decoding to be single pass, thus the need for these
- * routines.
- * dArg - the argument for dOpen, etc.
- *
- * if NULL == dOpen == dClose == dRead == dWrite == dArg, then default
- * implementations using a memory buffer are used
- *
- * This function returns the decoder context, if it was successful.
- * Otherwise, null is returned.
- */
-SEC_PKCS12DecoderContext *
-SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
- digestOpenFn dOpen, digestCloseFn dClose,
- digestIOFn dRead, digestIOFn dWrite, void *dArg)
-{
- SEC_PKCS12DecoderContext *p12dcx;
- PRArenaPool *arena;
-
- arena = PORT_NewArena(2048); /* different size? */
- if(!arena) {
- return NULL; /* error is already set */
- }
-
- /* allocate the decoder context and set the state variables */
- p12dcx = PORT_ArenaZNew(arena, SEC_PKCS12DecoderContext);
- if(!p12dcx) {
- goto loser; /* error is already set */
- }
-
- if (!dOpen && !dClose && !dRead && !dWrite && !dArg) {
- /* use default implementations */
- dOpen = p12u_DigestOpen;
- dClose = p12u_DigestClose;
- dRead = p12u_DigestRead;
- dWrite = p12u_DigestWrite;
- dArg = (void*)p12dcx;
- }
-
- p12dcx->arena = arena;
- p12dcx->pwitem = pwitem;
- p12dcx->slot = (slot ? PK11_ReferenceSlot(slot)
- : PK11_GetInternalKeySlot());
- p12dcx->wincx = wincx;
- p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs;
-#ifdef IS_LITTLE_ENDIAN
- p12dcx->swapUnicodeBytes = PR_TRUE;
-#else
- p12dcx->swapUnicodeBytes = PR_FALSE;
-#endif
- p12dcx->errorValue = 0;
- p12dcx->error = PR_FALSE;
-
- /* start the decoding of the PFX and set the notify proc
- * for the PFX item.
- */
- p12dcx->pfxA1Dcx = SEC_ASN1DecoderStart(p12dcx->arena, &p12dcx->pfx,
- sec_PKCS12PFXItemTemplate);
- if(!p12dcx->pfxA1Dcx) {
- PK11_FreeSlot(p12dcx->slot);
- goto loser;
- }
-
- SEC_ASN1DecoderSetNotifyProc(p12dcx->pfxA1Dcx,
- sec_pkcs12_decoder_pfx_notify_proc,
- p12dcx);
-
- /* set up digest functions */
- p12dcx->dOpen = dOpen;
- p12dcx->dWrite = dWrite;
- p12dcx->dClose = dClose;
- p12dcx->dRead = dRead;
- p12dcx->dArg = dArg;
- p12dcx->dIsOpen = PR_FALSE;
-
- p12dcx->keyList = NULL;
- p12dcx->decitem.type = 0;
- p12dcx->decitem.der = NULL;
- p12dcx->decitem.hasKey = PR_FALSE;
- p12dcx->decitem.friendlyName = NULL;
- p12dcx->iteration = 0;
-
- return p12dcx;
-
-loser:
- PORT_FreeArena(arena, PR_TRUE);
- return NULL;
-}
-
-SECStatus
-SEC_PKCS12DecoderSetTargetTokenCAs(SEC_PKCS12DecoderContext *p12dcx,
- SECPKCS12TargetTokenCAs tokenCAs)
-{
- if (!p12dcx || p12dcx->error) {
- return SECFailure;
- }
- p12dcx->tokenCAs = tokenCAs;
- return SECSuccess;
-}
-
-
-/* SEC_PKCS12DecoderUpdate
- * Streaming update sending more data to the decoder. If
- * an error occurs, SECFailure is returned.
- *
- * p12dcx - the decoder context
- * data, len - the data buffer and length of data to send to
- * the update functions.
- */
-SECStatus
-SEC_PKCS12DecoderUpdate(SEC_PKCS12DecoderContext *p12dcx,
- unsigned char *data, unsigned long len)
-{
- SECStatus rv;
-
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* update the PFX decoder context */
- rv = SEC_ASN1DecoderUpdate(p12dcx->pfxA1Dcx, (const char *)data, len);
- if(rv != SECSuccess) {
- p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
- goto loser;
- }
-
- return SECSuccess;
-
-loser:
-
- p12dcx->error = PR_TRUE;
- return SECFailure;
-}
-
-/* This should be a nice sized buffer for reading in data (potentially large
-** amounts) to be MACed. It should be MUCH larger than HASH_LENGTH_MAX.
-*/
-#define IN_BUF_LEN 1024
-#ifdef DEBUG
-static const char bufferEnd[] = { "BufferEnd" } ;
-#endif
-#define FUDGE 128 /* must be as large as bufferEnd or more. */
-
-/* verify the hmac by reading the data from the temporary file
- * using the routines specified when the decodingContext was
- * created and return SECSuccess if the hmac matches.
- */
-static SECStatus
-sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
-{
- PK11Context * pk11cx = NULL;
- PK11SymKey * symKey = NULL;
- SECItem * params = NULL;
- unsigned char * buf;
- SECStatus rv = SECFailure;
- SECStatus lrv;
- unsigned int bufLen;
- int iteration;
- int bytesRead;
- SECOidTag algtag;
- SECItem hmacRes;
- SECItem ignore = {0};
- CK_MECHANISM_TYPE integrityMech;
-
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- buf = (unsigned char *)PORT_Alloc(IN_BUF_LEN + FUDGE);
- if (!buf)
- return SECFailure; /* error code has been set. */
-
-#ifdef DEBUG
- memcpy(buf + IN_BUF_LEN, bufferEnd, sizeof bufferEnd);
-#endif
-
- /* generate hmac key */
- if(p12dcx->macData.iter.data) {
- iteration = (int)DER_GetInteger(&p12dcx->macData.iter);
- } else {
- iteration = 1;
- }
-
- params = PK11_CreatePBEParams(&p12dcx->macData.macSalt, p12dcx->pwitem,
- iteration);
-
- algtag = SECOID_GetAlgorithmTag(&p12dcx->macData.safeMac.digestAlgorithm);
- switch (algtag) {
- case SEC_OID_SHA1:
- integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN; break;
- case SEC_OID_MD5:
- integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break;
- case SEC_OID_MD2:
- integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break;
- default:
- goto loser;
- }
-
- symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL);
- PK11_DestroyPBEParams(params);
- params = NULL;
- if (!symKey) goto loser;
- /* init hmac */
- pk11cx = PK11_CreateContextBySymKey(sec_pkcs12_algtag_to_mech(algtag),
- CKA_SIGN, symKey, &ignore);
- if(!pk11cx) {
- goto loser;
- }
- lrv = PK11_DigestBegin(pk11cx);
- if (lrv == SECFailure ) {
- goto loser;
- }
-
- /* try to open the data for readback */
- if(p12dcx->dOpen && ((*p12dcx->dOpen)(p12dcx->dArg, PR_TRUE)
- != SECSuccess)) {
- goto loser;
- }
-
- /* read the data back IN_BUF_LEN bytes at a time and recompute
- * the hmac. if fewer bytes are read than are requested, it is
- * assumed that the end of file has been reached. if bytesRead
- * is returned as -1, then an error occurred reading from the
- * file.
- */
- do {
- bytesRead = (*p12dcx->dRead)(p12dcx->dArg, buf, IN_BUF_LEN);
- if (bytesRead < 0) {
- PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_READ);
- goto loser;
- }
- PORT_Assert(bytesRead <= IN_BUF_LEN);
- PORT_Assert(!memcmp(buf + IN_BUF_LEN, bufferEnd, sizeof bufferEnd));
-
- if (bytesRead > IN_BUF_LEN) {
- /* dRead callback overflowed buffer. */
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- goto loser;
- }
-
- if (bytesRead) {
- lrv = PK11_DigestOp(pk11cx, buf, bytesRead);
- if (lrv == SECFailure) {
- goto loser;
- }
- }
- } while (bytesRead == IN_BUF_LEN);
-
- /* finish the hmac context */
- lrv = PK11_DigestFinal(pk11cx, buf, &bufLen, IN_BUF_LEN);
- if (lrv == SECFailure ) {
- goto loser;
- }
-
- hmacRes.data = buf;
- hmacRes.len = bufLen;
-
- /* is the hmac computed the same as the hmac which was decoded? */
- rv = SECSuccess;
- if(SECITEM_CompareItem(&hmacRes, &p12dcx->macData.safeMac.digest)
- != SECEqual) {
- PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC);
- rv = SECFailure;
- }
-
-loser:
- /* close the file and remove it */
- if(p12dcx->dClose) {
- (*p12dcx->dClose)(p12dcx->dArg, PR_TRUE);
- p12dcx->dIsOpen = PR_FALSE;
- }
-
- if(pk11cx) {
- PK11_DestroyContext(pk11cx, PR_TRUE);
- }
- if (params) {
- PK11_DestroyPBEParams(params);
- }
- if (symKey) {
- PK11_FreeSymKey(symKey);
- }
- PORT_ZFree(buf, IN_BUF_LEN + FUDGE);
-
- return rv;
-}
-
-/* SEC_PKCS12DecoderVerify
- * Verify the macData or the signature of the decoded PKCS 12 PDU.
- * If the signature or the macData do not match, SECFailure is
- * returned.
- *
- * p12dcx - the decoder context
- */
-SECStatus
-SEC_PKCS12DecoderVerify(SEC_PKCS12DecoderContext *p12dcx)
-{
- SECStatus rv = SECSuccess;
-
- /* make sure that no errors have occurred... */
- if(!p12dcx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if(p12dcx->error) {
- /* error code is already set! PORT_SetError(p12dcx->errorValue); */
- return SECFailure;
- }
-
- rv = SEC_ASN1DecoderFinish(p12dcx->pfxA1Dcx);
- p12dcx->pfxA1Dcx = NULL;
- if(rv != SECSuccess) {
- return rv;
- }
-
- /* check the signature or the mac depending on the type of
- * integrity used.
- */
- if(p12dcx->pfx.encodedMacData.len) {
- rv = SEC_ASN1DecodeItem(p12dcx->arena, &p12dcx->macData,
- sec_PKCS12MacDataTemplate,
- &p12dcx->pfx.encodedMacData);
- if(rv == SECSuccess) {
- return sec_pkcs12_decoder_verify_mac(p12dcx);
- }
- return rv;
- }
- if (SEC_PKCS7VerifySignature(p12dcx->aSafeCinfo, certUsageEmailSigner,
- PR_FALSE)) {
- return SECSuccess;
- }
- PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC);
- return SECFailure;
-}
-
-/* SEC_PKCS12DecoderFinish
- * Free any open ASN1 or PKCS7 decoder contexts and then
- * free the arena pool which everything should be allocated
- * from. This function should be called upon completion of
- * decoding and installing of a pfx pdu. This should be
- * called even if an error occurs.
- *
- * p12dcx - the decoder context
- */
-void
-SEC_PKCS12DecoderFinish(SEC_PKCS12DecoderContext *p12dcx)
-{
- unsigned int i;
-
- if(!p12dcx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
-
- if(p12dcx->pfxA1Dcx) {
- SEC_ASN1DecoderFinish(p12dcx->pfxA1Dcx);
- p12dcx->pfxA1Dcx = NULL;
- }
-
- if(p12dcx->aSafeA1Dcx) {
- SEC_ASN1DecoderFinish(p12dcx->aSafeA1Dcx);
- p12dcx->aSafeA1Dcx = NULL;
- }
-
- /* cleanup any old ASN1 decoder contexts */
- for (i = 0; i < p12dcx->safeContentsCnt; ++i) {
- sec_PKCS12SafeContentsContext *safeContentsCtx, *nested;
- safeContentsCtx = p12dcx->safeContentsList[i];
- if (safeContentsCtx) {
- nested = safeContentsCtx->nestedSafeContentsCtx;
- while (nested) {
- if (nested->safeContentsA1Dcx) {
- SEC_ASN1DecoderFinish(nested->safeContentsA1Dcx);
- nested->safeContentsA1Dcx = NULL;
- }
- nested = nested->nestedSafeContentsCtx;
- }
- if (safeContentsCtx->safeContentsA1Dcx) {
- SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
- safeContentsCtx->safeContentsA1Dcx = NULL;
- }
- }
- }
-
- if (p12dcx->currentASafeP7Dcx &&
- p12dcx->currentASafeP7Dcx != p12dcx->aSafeP7Dcx) {
- SEC_PKCS7ContentInfo * cinfo;
- cinfo = SEC_PKCS7DecoderFinish(p12dcx->currentASafeP7Dcx);
- if (cinfo) {
- SEC_PKCS7DestroyContentInfo(cinfo); /* don't leak it */
- }
- }
- p12dcx->currentASafeP7Dcx = NULL;
-
- if(p12dcx->aSafeP7Dcx) {
- SEC_PKCS7ContentInfo * cinfo;
- cinfo = SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
- if (cinfo) {
- SEC_PKCS7DestroyContentInfo(cinfo);
- }
- p12dcx->aSafeP7Dcx = NULL;
- }
-
- if(p12dcx->aSafeCinfo) {
- SEC_PKCS7DestroyContentInfo(p12dcx->aSafeCinfo);
- p12dcx->aSafeCinfo = NULL;
- }
-
- if (p12dcx->decitem.type != 0 && p12dcx->decitem.der != NULL) {
- SECITEM_FreeItem(p12dcx->decitem.der, PR_TRUE);
- }
- if (p12dcx->decitem.friendlyName != NULL) {
- SECITEM_FreeItem(p12dcx->decitem.friendlyName, PR_TRUE);
- }
-
- if(p12dcx->slot) {
- PK11_FreeSlot(p12dcx->slot);
- p12dcx->slot = NULL;
- }
-
- if(p12dcx->dIsOpen && p12dcx->dClose) {
- (*p12dcx->dClose)(p12dcx->dArg, PR_TRUE);
- p12dcx->dIsOpen = PR_FALSE;
- }
-
- if(p12dcx->arena) {
- PORT_FreeArena(p12dcx->arena, PR_TRUE);
- }
-}
-
-static SECStatus
-sec_pkcs12_decoder_set_attribute_value(sec_PKCS12SafeBag *bag,
- SECOidTag attributeType,
- SECItem *attrValue)
-{
- int i = 0;
- SECOidData *oid;
-
- if(!bag || !attrValue) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- oid = SECOID_FindOIDByTag(attributeType);
- if(!oid) {
- return SECFailure;
- }
-
- if(!bag->attribs) {
- bag->attribs =
- PORT_ArenaZNewArray(bag->arena, sec_PKCS12Attribute *, 2);
- } else {
- while(bag->attribs[i])
- i++;
- bag->attribs = PORT_ArenaGrowArray(bag->arena, bag->attribs,
- sec_PKCS12Attribute *, i + 1, i + 2);
- }
-
- if(!bag->attribs) {
- return SECFailure;
- }
-
- bag->attribs[i] = PORT_ArenaZNew(bag->arena, sec_PKCS12Attribute);
- if(!bag->attribs) {
- return SECFailure;
- }
-
- bag->attribs[i]->attrValue = PORT_ArenaZNewArray(bag->arena, SECItem *, 2);
- if(!bag->attribs[i]->attrValue) {
- return SECFailure;
- }
-
- bag->attribs[i+1] = NULL;
- bag->attribs[i]->attrValue[0] = attrValue;
- bag->attribs[i]->attrValue[1] = NULL;
-
- return SECITEM_CopyItem(bag->arena, &bag->attribs[i]->attrType, &oid->oid);
-}
-
-static SECItem *
-sec_pkcs12_get_attribute_value(sec_PKCS12SafeBag *bag,
- SECOidTag attributeType)
-{
- int i;
-
- if(!bag->attribs) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- for (i = 0; bag->attribs[i] != NULL; i++) {
- if (SECOID_FindOIDTag(&bag->attribs[i]->attrType) == attributeType) {
- return bag->attribs[i]->attrValue[0];
- }
- }
- return NULL;
-}
-
-/* For now, this function will merely remove any ":"
- * in the nickname which the PK11 functions may have
- * placed there. This will keep dual certs from appearing
- * twice under "Your" certificates when imported onto smart
- * cards. Once with the name "Slot:Cert" and another with
- * the nickname "Slot:Slot:Cert"
- */
-static void
-sec_pkcs12_sanitize_nickname(PK11SlotInfo *slot, SECItem *nick)
-{
- char *nickname;
- char *delimit;
- int delimitlen;
-
- nickname = (char*)nick->data;
- if ((delimit = PORT_Strchr(nickname, ':')) != NULL) {
- char *slotName;
- int slotNameLen;
-
- slotNameLen = delimit-nickname;
- slotName = PORT_NewArray(char, (slotNameLen+1));
- PORT_Assert(slotName);
- if (slotName == NULL) {
- /* What else can we do?*/
- return;
- }
- PORT_Memcpy(slotName, nickname, slotNameLen);
- slotName[slotNameLen] = '\0';
- if (PORT_Strcmp(PK11_GetTokenName(slot), slotName) == 0) {
- delimitlen = PORT_Strlen(delimit+1);
- PORT_Memmove(nickname, delimit+1, delimitlen+1);
- nick->len = delimitlen;
- }
- PORT_Free(slotName);
- }
-
-}
-
-static SECItem *
-sec_pkcs12_get_nickname(sec_PKCS12SafeBag *bag)
-{
- SECItem *src, *dest;
-
- if(!bag) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- src = sec_pkcs12_get_attribute_value(bag, SEC_OID_PKCS9_FRIENDLY_NAME);
-
- /* The return value src is 16-bit Unicode characters, in big-endian format.
- * Check if it is NULL or empty name.
- */
- if(!src || !src->data || src->len < 2 || (!src->data[0] && !src->data[1])) {
- return NULL;
- }
-
- dest = (SECItem*)PORT_ZAlloc(sizeof(SECItem));
- if(!dest) {
- goto loser;
- }
- if(!sec_pkcs12_convert_item_to_unicode(NULL, dest, src, PR_FALSE,
- PR_FALSE, PR_FALSE)) {
- goto loser;
- }
-
- sec_pkcs12_sanitize_nickname(bag->slot, dest);
-
- return dest;
-
-loser:
- if(dest) {
- SECITEM_ZfreeItem(dest, PR_TRUE);
- }
-
- bag->problem = PR_TRUE;
- bag->error = PORT_GetError();
- return NULL;
-}
-
-static SECStatus
-sec_pkcs12_set_nickname(sec_PKCS12SafeBag *bag, SECItem *name)
-{
- sec_PKCS12Attribute *attr = NULL;
- SECOidData *oid = SECOID_FindOIDByTag(SEC_OID_PKCS9_FRIENDLY_NAME);
-
- if(!bag || !bag->arena || !name) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(!bag->attribs) {
- if(!oid) {
- goto loser;
- }
-
- bag->attribs =
- PORT_ArenaZNewArray(bag->arena, sec_PKCS12Attribute *, 2);
- if(!bag->attribs) {
- goto loser;
- }
- bag->attribs[0] = PORT_ArenaZNew(bag->arena, sec_PKCS12Attribute);
- if(!bag->attribs[0]) {
- goto loser;
- }
- bag->attribs[1] = NULL;
-
- attr = bag->attribs[0];
- if(SECITEM_CopyItem(bag->arena, &attr->attrType, &oid->oid)
- != SECSuccess) {
- goto loser;
- }
- } else {
- int i;
- for (i = 0; bag->attribs[i]; i++) {
- if(SECOID_FindOIDTag(&bag->attribs[i]->attrType)
- == SEC_OID_PKCS9_FRIENDLY_NAME) {
- attr = bag->attribs[i];
- break;
- }
- }
- if(!attr) {
- if(!oid) {
- goto loser;
- }
- bag->attribs = PORT_ArenaGrowArray(bag->arena, bag->attribs,
- sec_PKCS12Attribute *, i+1, i+2);
- if(!bag->attribs) {
- goto loser;
- }
- bag->attribs[i] = PORT_ArenaZNew(bag->arena, sec_PKCS12Attribute);
- if(!bag->attribs[i]) {
- goto loser;
- }
- bag->attribs[i+1] = NULL;
- attr = bag->attribs[i];
- if(SECITEM_CopyItem(bag->arena, &attr->attrType, &oid->oid)
- != SECSuccess) {
- goto loser;
- }
- }
- }
-
- PORT_Assert(attr);
- if(!attr->attrValue) {
- attr->attrValue = PORT_ArenaZNewArray(bag->arena, SECItem *, 2);
- if(!attr->attrValue) {
- goto loser;
- }
- attr->attrValue[0] = PORT_ArenaZNew(bag->arena, SECItem);
- if(!attr->attrValue[0]) {
- goto loser;
- }
- attr->attrValue[1] = NULL;
- }
-
- name->len = PORT_Strlen((char *)name->data);
- if(!sec_pkcs12_convert_item_to_unicode(bag->arena, attr->attrValue[0],
- name, PR_FALSE, PR_FALSE, PR_TRUE)) {
- goto loser;
- }
-
- return SECSuccess;
-
-loser:
- bag->problem = PR_TRUE;
- bag->error = PORT_GetError();
- return SECFailure;
-}
-
-static SECStatus
-sec_pkcs12_get_key_info(sec_PKCS12SafeBag *key)
-{
- int i = 0;
- SECKEYPrivateKeyInfo *pki = NULL;
-
- if(!key) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* if the bag does *not* contain an unencrypted PrivateKeyInfo
- * then we cannot convert the attributes. We are propagating
- * attributes within the PrivateKeyInfo to the SafeBag level.
- */
- if(SECOID_FindOIDTag(&(key->safeBagType)) !=
- SEC_OID_PKCS12_V1_KEY_BAG_ID) {
- return SECSuccess;
- }
-
- pki = key->safeBagContent.pkcs8KeyBag;
-
- if(!pki || !pki->attributes) {
- return SECSuccess;
- }
-
- while(pki->attributes[i]) {
- SECOidTag tag = SECOID_FindOIDTag(&pki->attributes[i]->attrType);
-
- if (tag == SEC_OID_PKCS9_LOCAL_KEY_ID ||
- tag == SEC_OID_PKCS9_FRIENDLY_NAME) {
- SECItem *attrValue = sec_pkcs12_get_attribute_value(key, tag);
- if(!attrValue) {
- if(sec_pkcs12_decoder_set_attribute_value(key, tag,
- pki->attributes[i]->attrValue[0])
- != SECSuccess) {
- key->problem = PR_TRUE;
- key->error = PORT_GetError();
- return SECFailure;
- }
- }
- }
- i++;
- }
-
- return SECSuccess;
-}
-
-/* retrieve the nickname for the certificate bag. first look
- * in the cert bag, otherwise get it from the key.
- */
-static SECItem *
-sec_pkcs12_get_nickname_for_cert(sec_PKCS12SafeBag *cert,
- sec_PKCS12SafeBag *key)
-{
- SECItem *nickname;
-
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- nickname = sec_pkcs12_get_nickname(cert);
- if(nickname) {
- return nickname;
- }
-
- if(key) {
- nickname = sec_pkcs12_get_nickname(key);
-
- if(nickname && sec_pkcs12_set_nickname(cert, nickname)
- != SECSuccess) {
- SECITEM_ZfreeItem(nickname, PR_TRUE);
- return NULL;
- }
- }
-
- return nickname;
-}
-
-/* set the nickname for the certificate */
-static SECStatus
-sec_pkcs12_set_nickname_for_cert(sec_PKCS12SafeBag *cert,
- sec_PKCS12SafeBag *key,
- SECItem *nickname)
-{
- if(!nickname || !cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(sec_pkcs12_set_nickname(cert, nickname) != SECSuccess) {
- return SECFailure;
- }
-
- if(key) {
- if(sec_pkcs12_set_nickname(key, nickname) != SECSuccess) {
- cert->problem = PR_TRUE;
- cert->error = key->error;
- return SECFailure;
- }
- }
-
- return SECSuccess;
-}
-
-/* retrieve the DER cert from the cert bag */
-static SECItem *
-sec_pkcs12_get_der_cert(sec_PKCS12SafeBag *cert)
-{
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- if(SECOID_FindOIDTag(&cert->safeBagType) != SEC_OID_PKCS12_V1_CERT_BAG_ID) {
- return NULL;
- }
-
- /* only support X509 certs not SDSI */
- if(SECOID_FindOIDTag(&cert->safeBagContent.certBag->bagID)
- != SEC_OID_PKCS9_X509_CERT) {
- return NULL;
- }
-
- return SECITEM_DupItem(&(cert->safeBagContent.certBag->value.x509Cert));
-}
-
-struct certNickInfo {
- PRArenaPool *arena;
- unsigned int nNicks;
- SECItem **nickList;
- unsigned int error;
-};
-
-/* callback for traversing certificates to gather the nicknames
- * used in a particular traversal. for instance, when using
- * CERT_TraversePermCertsForSubject, gather the nicknames and
- * store them in the certNickInfo for a particular DN.
- *
- * this handles the case where multiple nicknames are allowed
- * for the same dn, which is not currently allowed, but may be
- * in the future.
- */
-static SECStatus
-gatherNicknames(CERTCertificate *cert, void *arg)
-{
- struct certNickInfo *nickArg = (struct certNickInfo *)arg;
- SECItem tempNick;
- unsigned int i;
-
- if(!cert || !nickArg || nickArg->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(!cert->nickname) {
- return SECSuccess;
- }
-
- tempNick.data = (unsigned char *)cert->nickname;
- tempNick.len = PORT_Strlen(cert->nickname) + 1;
-
- /* do we already have the nickname in the list? */
- if(nickArg->nNicks > 0) {
-
- /* nicknames have been encountered, but there is no list -- bad */
- if(!nickArg->nickList) {
- nickArg->error = SEC_ERROR_INVALID_ARGS;
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- for(i = 0; i < nickArg->nNicks; i++) {
- if(SECITEM_CompareItem(nickArg->nickList[i], &tempNick)
- == SECEqual) {
- return SECSuccess;
- }
- }
- }
-
- /* add the nickname to the list */
- nickArg->nickList = (nickArg->nNicks == 0)
- ? PORT_ArenaZNewArray(nickArg->arena, SECItem *, 2)
- : PORT_ArenaGrowArray(nickArg->arena, nickArg->nickList, SECItem *,
- nickArg->nNicks + 1, nickArg->nNicks + 2);
-
- if(!nickArg->nickList) {
- nickArg->error = SEC_ERROR_NO_MEMORY;
- return SECFailure;
- }
-
- nickArg->nickList[nickArg->nNicks] =
- PORT_ArenaZNew(nickArg->arena, SECItem);
- if(!nickArg->nickList[nickArg->nNicks]) {
- nickArg->error = PORT_GetError();
- return SECFailure;
- }
-
-
- if(SECITEM_CopyItem(nickArg->arena, nickArg->nickList[nickArg->nNicks],
- &tempNick) != SECSuccess) {
- nickArg->error = PORT_GetError();
- return SECFailure;
- }
-
- nickArg->nNicks++;
-
- return SECSuccess;
-}
-
-/* traverses the certs in the data base or in the token for the
- * DN to see if any certs currently have a nickname set.
- * If so, return it.
- */
-static SECItem *
-sec_pkcs12_get_existing_nick_for_dn(sec_PKCS12SafeBag *cert)
-{
- struct certNickInfo *nickArg = NULL;
- SECItem *derCert, *returnDn = NULL;
- PRArenaPool *arena = NULL;
- CERTCertificate *tempCert;
-
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- derCert = sec_pkcs12_get_der_cert(cert);
- if(!derCert) {
- return NULL;
- }
-
- tempCert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
- if(!tempCert) {
- returnDn = NULL;
- goto loser;
- }
-
- arena = PORT_NewArena(1024);
- if(!arena) {
- returnDn = NULL;
- goto loser;
- }
- nickArg = PORT_ArenaZNew(arena, struct certNickInfo);
- if(!nickArg) {
- returnDn = NULL;
- goto loser;
- }
- nickArg->error = 0;
- nickArg->nNicks = 0;
- nickArg->nickList = NULL;
- nickArg->arena = arena;
-
- /* if the token is local, first traverse the cert database
- * then traverse the token.
- */
- if(PK11_TraverseCertsForSubjectInSlot(tempCert, cert->slot, gatherNicknames,
- (void *)nickArg) != SECSuccess) {
- returnDn = NULL;
- goto loser;
- }
-
- if(nickArg->error) {
- /* XXX do we want to set the error? */
- returnDn = NULL;
- goto loser;
- }
-
- if(nickArg->nNicks == 0) {
- returnDn = NULL;
- goto loser;
- }
-
- /* set it to the first name, for now. handle multiple names? */
- returnDn = SECITEM_DupItem(nickArg->nickList[0]);
-
-loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- if(tempCert) {
- CERT_DestroyCertificate(tempCert);
- }
-
- if(derCert) {
- SECITEM_FreeItem(derCert, PR_TRUE);
- }
-
- return (returnDn);
-}
-
-/* counts certificates found for a given traversal function */
-static SECStatus
-countCertificate(CERTCertificate *cert, void *arg)
-{
- unsigned int *nCerts = (unsigned int *)arg;
-
- if(!cert || !arg) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- (*nCerts)++;
- return SECSuccess;
-}
-
-static PRBool
-sec_pkcs12_certs_for_nickname_exist(SECItem *nickname, PK11SlotInfo *slot)
-{
- unsigned int nCerts = 0;
-
- if(!nickname || !slot) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return PR_TRUE;
- }
-
- /* we want to check the local database first if we are importing to it */
- PK11_TraverseCertsForNicknameInSlot(nickname, slot, countCertificate,
- (void *)&nCerts);
- return (PRBool)(nCerts != 0);
-}
-
-/* validate cert nickname such that there is a one-to-one relation
- * between nicknames and dn's. we want to enforce the case that the
- * nickname is non-NULL and that there is only one nickname per DN.
- *
- * if there is a problem with a nickname or the nickname is not present,
- * the user will be prompted for it.
- */
-static void
-sec_pkcs12_validate_cert_nickname(sec_PKCS12SafeBag *cert,
- sec_PKCS12SafeBag *key,
- SEC_PKCS12NicknameCollisionCallback nicknameCb,
- CERTCertificate *leafCert)
-{
- SECItem *certNickname, *existingDNNick;
- PRBool setNickname = PR_FALSE, cancel = PR_FALSE;
- SECItem *newNickname = NULL;
-
- if(!cert || !cert->hasKey) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
-
- if(!nicknameCb) {
- cert->problem = PR_TRUE;
- cert->error = SEC_ERROR_INVALID_ARGS;
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
-
- if(cert->hasKey && !key) {
- cert->problem = PR_TRUE;
- cert->error = SEC_ERROR_INVALID_ARGS;
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
-
- certNickname = sec_pkcs12_get_nickname_for_cert(cert, key);
- existingDNNick = sec_pkcs12_get_existing_nick_for_dn(cert);
-
- /* nickname is already used w/ this dn, so it is safe to return */
- if(certNickname && existingDNNick &&
- SECITEM_CompareItem(certNickname, existingDNNick) == SECEqual) {
- goto loser;
- }
-
- /* nickname not set in pkcs 12 bags, but a nick is already used for
- * this dn. set the nicks in the p12 bags and finish.
- */
- if(existingDNNick) {
- sec_pkcs12_set_nickname_for_cert(cert, key, existingDNNick);
- goto loser;
- }
-
- /* at this point, we have a certificate for which the DN is not located
- * on the token. the nickname specified may or may not be NULL. if it
- * is not null, we need to make sure that there are no other certificates
- * with this nickname in the token for it to be valid. this imposes a
- * one to one relationship between DN and nickname.
- *
- * if the nickname is null, we need the user to enter a nickname for
- * the certificate.
- *
- * once we have a nickname, we make sure that the nickname is unique
- * for the DN. if it is not, the user is reprompted to enter a new
- * nickname.
- *
- * in order to exit this loop, the nickname entered is either unique
- * or the user hits cancel and the certificate is not imported.
- */
- setNickname = PR_FALSE;
- while(1) {
- /* we will use the nickname so long as no other certs have the
- * same nickname. and the nickname is not NULL.
- */
- if (certNickname && certNickname->data &&
- !sec_pkcs12_certs_for_nickname_exist(certNickname, cert->slot)) {
- if (setNickname) {
- sec_pkcs12_set_nickname_for_cert(cert, key, certNickname);
- }
- break;
- }
-
- setNickname = PR_FALSE;
- newNickname = (*nicknameCb)(certNickname, &cancel, leafCert);
- if(cancel) {
- cert->problem = PR_TRUE;
- cert->error = SEC_ERROR_USER_CANCELLED;
- break;
- }
-
- if(!newNickname) {
- cert->problem = PR_TRUE;
- cert->error = PORT_GetError();
- break;
- }
-
- /* at this point we have a new nickname, if we have an existing
- * certNickname, we need to free it and assign the new nickname
- * to it to avoid a memory leak. happy?
- */
- if(certNickname) {
- SECITEM_ZfreeItem(certNickname, PR_TRUE);
- certNickname = NULL;
- }
-
- certNickname = newNickname;
- setNickname = PR_TRUE;
- /* go back and recheck the new nickname */
- }
-
-loser:
- if(certNickname) {
- SECITEM_ZfreeItem(certNickname, PR_TRUE);
- }
-
- if(existingDNNick) {
- SECITEM_ZfreeItem(existingDNNick, PR_TRUE);
- }
-}
-
-static void
-sec_pkcs12_validate_cert(sec_PKCS12SafeBag *cert,
- sec_PKCS12SafeBag *key,
- SEC_PKCS12NicknameCollisionCallback nicknameCb)
-{
- CERTCertificate *leafCert;
-
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
-
- cert->validated = PR_TRUE;
-
- if(!nicknameCb) {
- cert->noInstall = PR_TRUE;
- cert->problem = PR_TRUE;
- cert->error = SEC_ERROR_INVALID_ARGS;
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
-
- if(!cert->safeBagContent.certBag) {
- cert->noInstall = PR_TRUE;
- cert->problem = PR_TRUE;
- cert->error = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
- return;
- }
-
- cert->noInstall = PR_FALSE;
- cert->unused = PR_FALSE;
- cert->problem = PR_FALSE;
- cert->error = 0;
-
- leafCert = CERT_DecodeDERCertificate(
- &cert->safeBagContent.certBag->value.x509Cert, PR_FALSE, NULL);
- if(!leafCert) {
- cert->noInstall = PR_TRUE;
- cert->problem = PR_TRUE;
- cert->error = PORT_GetError();
- return;
- }
-
- sec_pkcs12_validate_cert_nickname(cert, key, nicknameCb, leafCert);
-
- CERT_DestroyCertificate(leafCert);
-}
-
-static void
-sec_pkcs12_validate_key_by_cert(sec_PKCS12SafeBag *cert, sec_PKCS12SafeBag *key,
- void *wincx)
-{
- CERTCertificate *leafCert;
- SECKEYPrivateKey *privk;
-
- if(!key) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return;
- }
-
- key->validated = PR_TRUE;
-
- if(!cert) {
- key->problem = PR_TRUE;
- key->noInstall = PR_TRUE;
- key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
- return;
- }
-
- leafCert = CERT_DecodeDERCertificate(
- &(cert->safeBagContent.certBag->value.x509Cert), PR_FALSE, NULL);
- if(!leafCert) {
- key->problem = PR_TRUE;
- key->noInstall = PR_TRUE;
- key->error = PORT_GetError();
- return;
- }
-
- privk = PK11_FindPrivateKeyFromCert(key->slot, leafCert, wincx);
- if(!privk) {
- privk = PK11_FindKeyByDERCert(key->slot, leafCert, wincx);
- }
-
- if(privk) {
- SECKEY_DestroyPrivateKey(privk);
- key->noInstall = PR_TRUE;
- }
-
- CERT_DestroyCertificate(leafCert);
-}
-
-static SECStatus
-sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
-{
- SECItem *derCert, *nickName;
- char *nickData = NULL;
- PRBool isIntermediateCA;
- SECStatus rv;
-
- if(!cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(cert->problem || cert->noInstall || cert->installed) {
- return SECSuccess;
- }
-
- derCert = &cert->safeBagContent.certBag->value.x509Cert;
-
- PORT_Assert(!cert->problem && !cert->noInstall);
-
- nickName = sec_pkcs12_get_nickname(cert);
- if(nickName) {
- nickData = (char *)nickName->data;
- }
-
- isIntermediateCA = CERT_IsCADERCert(derCert, NULL) &&
- !CERT_IsRootDERCert(derCert);
-
- if(keyExists) {
- CERTCertificate *newCert;
-
- newCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- derCert, NULL, PR_FALSE, PR_FALSE);
- if(!newCert) {
- if(nickName) SECITEM_ZfreeItem(nickName, PR_TRUE);
- cert->error = PORT_GetError();
- cert->problem = PR_TRUE;
- return SECFailure;
- }
-
- rv = PK11_ImportCertForKeyToSlot(cert->slot, newCert, nickData,
- PR_TRUE, wincx);
- CERT_DestroyCertificate(newCert);
- } else if ((cert->tokenCAs == SECPKCS12TargetTokenNoCAs) ||
- ((cert->tokenCAs == SECPKCS12TargetTokenIntermediateCAs) &&
- !isIntermediateCA)) {
- SECItem *certList[2];
- certList[0] = derCert;
- certList[1] = NULL;
-
- rv = CERT_ImportCerts(CERT_GetDefaultCertDB(), certUsageUserCertImport,
- 1, certList, NULL, PR_TRUE, PR_FALSE, nickData);
- } else {
- rv = PK11_ImportDERCert(cert->slot, derCert, CK_INVALID_HANDLE,
- nickData, PR_FALSE);
- }
- if (rv) {
- cert->problem = 1;
- cert->error = PORT_GetError();
- }
- cert->installed = PR_TRUE;
- if(nickName) SECITEM_ZfreeItem(nickName, PR_TRUE);
- return rv;
-}
-
-static SECItem *
-sec_pkcs12_get_public_value_and_type(SECKEYPublicKey *pubKey, KeyType *type);
-
-static SECStatus
-sec_pkcs12_add_key(sec_PKCS12SafeBag *key, SECKEYPublicKey *pubKey,
- unsigned int keyUsage,
- SECItem *nickName, void *wincx)
-{
- SECStatus rv;
- SECItem *publicValue = NULL;
- KeyType keyType;
-
- /* We should always have values for "key" and "pubKey"
- so they can be dereferenced later. */
- if(!key || !pubKey) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(key->problem || key->noInstall) {
- return SECSuccess;
- }
-
- /* get the value and type from the public key */
- publicValue = sec_pkcs12_get_public_value_and_type(pubKey, &keyType);
- if (!publicValue) {
- key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
- key->problem = PR_TRUE;
- return SECFailure;
- }
-
- switch(SECOID_FindOIDTag(&key->safeBagType))
- {
- case SEC_OID_PKCS12_V1_KEY_BAG_ID:
- rv = PK11_ImportPrivateKeyInfo(key->slot,
- key->safeBagContent.pkcs8KeyBag,
- nickName, publicValue, PR_TRUE, PR_TRUE,
- keyUsage, wincx);
- break;
- case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
- rv = PK11_ImportEncryptedPrivateKeyInfo(key->slot,
- key->safeBagContent.pkcs8ShroudedKeyBag,
- key->pwitem, nickName, publicValue,
- PR_TRUE, PR_TRUE, keyType, keyUsage,
- wincx);
- break;
- default:
- key->error = SEC_ERROR_PKCS12_UNSUPPORTED_VERSION;
- key->problem = PR_TRUE;
- if(nickName) {
- SECITEM_ZfreeItem(nickName, PR_TRUE);
- }
- return SECFailure;
- }
-
- if(rv != SECSuccess) {
- key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
- key->problem = PR_TRUE;
- } else {
- /* try to import the public key. Failure to do so is not fatal,
- * not all tokens can store the public key */
- if (pubKey) {
- PK11_ImportPublicKey(key->slot, pubKey, PR_TRUE);
- }
- key->installed = PR_TRUE;
- }
-
- return rv;
-}
-
-/*
- * The correctness of the code in this file ABSOLUTELY REQUIRES
- * that ALL BAGs share a single common arena.
- *
- * This function allocates the bag list from the arena of whatever bag
- * happens to be passed to it. Each time a new bag is handed to it,
- * it grows (resizes) the arena of the bag that was handed to it.
- * If the bags have different arenas, it will grow the wrong arena.
- *
- * Worse, if the bags had separate arenas, then while destroying the bags
- * in a bag list, when the bag whose arena contained the bag list was
- * destroyed, the baglist itself would be destroyed, making it difficult
- * or impossible to continue to destroy the bags in the destroyed list.
- */
-static SECStatus
-sec_pkcs12_add_item_to_bag_list(sec_PKCS12SafeBag ***bagList,
- sec_PKCS12SafeBag *bag)
-{
- sec_PKCS12SafeBag **newBagList = NULL;
- int i = 0;
-
- if(!bagList || !bag) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(!(*bagList)) {
- newBagList = PORT_ArenaZNewArray(bag->arena, sec_PKCS12SafeBag *, 2);
- } else {
- while((*bagList)[i])
- i++;
- newBagList = PORT_ArenaGrowArray(bag->arena, *bagList,
- sec_PKCS12SafeBag *, i + 1, i + 2);
- }
-
- if(!newBagList) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- newBagList[i] = bag;
- newBagList[i+1] = NULL;
- *bagList = newBagList;
-
- return SECSuccess;
-}
-
-static sec_PKCS12SafeBag **
-sec_pkcs12_find_certs_for_key(sec_PKCS12SafeBag **safeBags,
- sec_PKCS12SafeBag *key )
-{
- sec_PKCS12SafeBag **certList = NULL;
- SECItem *keyId;
- int i;
-
- if(!safeBags || !safeBags[0]) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- keyId = sec_pkcs12_get_attribute_value(key, SEC_OID_PKCS9_LOCAL_KEY_ID);
- if(!keyId) {
- return NULL;
- }
-
- for (i = 0; safeBags[i]; i++) {
- if(SECOID_FindOIDTag(&(safeBags[i]->safeBagType))
- == SEC_OID_PKCS12_V1_CERT_BAG_ID) {
- SECItem *certKeyId = sec_pkcs12_get_attribute_value(safeBags[i],
- SEC_OID_PKCS9_LOCAL_KEY_ID);
-
- if(certKeyId && (SECITEM_CompareItem(certKeyId, keyId)
- == SECEqual)) {
- if(sec_pkcs12_add_item_to_bag_list(&certList, safeBags[i])
- != SECSuccess) {
- /* This would leak the partial list of safeBags,
- * but that list is allocated from the arena of
- * one of the safebags, and will be destroyed when
- * that arena is destroyed. So this is not a real leak.
- */
- return NULL;
- }
- }
- }
- }
-
- return certList;
-}
-
-CERTCertList *
-SEC_PKCS12DecoderGetCerts(SEC_PKCS12DecoderContext *p12dcx)
-{
- CERTCertList *certList = NULL;
- sec_PKCS12SafeBag **safeBags;
- int i;
-
- if (!p12dcx || !p12dcx->safeBags || !p12dcx->safeBags[0]) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- safeBags = p12dcx->safeBags;
- certList = CERT_NewCertList();
-
- if (certList == NULL) {
- return NULL;
- }
-
- for (i = 0; safeBags[i]; i++) {
- if (SECOID_FindOIDTag(&(safeBags[i]->safeBagType))
- == SEC_OID_PKCS12_V1_CERT_BAG_ID) {
- SECItem *derCert = sec_pkcs12_get_der_cert(safeBags[i]) ;
- CERTCertificate *tempCert = NULL;
-
- if (derCert == NULL)
- continue;
- tempCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- derCert, NULL,
- PR_FALSE, PR_TRUE);
-
- if (tempCert) {
- CERT_AddCertToListTail(certList,tempCert);
- }
- SECITEM_FreeItem(derCert,PR_TRUE);
- }
- /* fixed an infinite loop here, by ensuring that i gets incremented
- * if derCert is NULL above.
- */
- }
-
- return certList;
-}
-static sec_PKCS12SafeBag **
-sec_pkcs12_get_key_bags(sec_PKCS12SafeBag **safeBags)
-{
- int i;
- sec_PKCS12SafeBag **keyList = NULL;
- SECOidTag bagType;
-
- if(!safeBags || !safeBags[0]) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- for (i = 0; safeBags[i]; i++) {
- bagType = SECOID_FindOIDTag(&(safeBags[i]->safeBagType));
- switch(bagType) {
- case SEC_OID_PKCS12_V1_KEY_BAG_ID:
- case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
- if(sec_pkcs12_add_item_to_bag_list(&keyList, safeBags[i])
- != SECSuccess) {
- /* This would leak, except that keyList is allocated
- * from the arena shared by all the safeBags.
- */
- return NULL;
- }
- break;
- default:
- break;
- }
- }
-
- return keyList;
-}
-
-/* This function takes two passes over the bags, validating them
- * The two passes are intended to mirror exactly the two passes in
- * sec_pkcs12_install_bags. But they don't. :(
- */
-static SECStatus
-sec_pkcs12_validate_bags(sec_PKCS12SafeBag **safeBags,
- SEC_PKCS12NicknameCollisionCallback nicknameCb,
- void *wincx)
-{
- sec_PKCS12SafeBag **keyList;
- int i;
-
- if(!safeBags || !nicknameCb) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(!safeBags[0]) {
- return SECSuccess;
- }
-
- /* First pass. Find all the key bags.
- * Find the matching cert(s) for each key.
- */
- keyList = sec_pkcs12_get_key_bags(safeBags);
- if(keyList) {
- for (i = 0; keyList[i]; ++i) {
- sec_PKCS12SafeBag *key = keyList[i];
- sec_PKCS12SafeBag **certList =
- sec_pkcs12_find_certs_for_key(safeBags, key);
-
- if(certList) {
- int j;
-
- if(SECOID_FindOIDTag(&(key->safeBagType)) ==
- SEC_OID_PKCS12_V1_KEY_BAG_ID) {
- /* if it is an unencrypted private key then make sure
- * the attributes are propageted to the appropriate
- * level
- */
- if(sec_pkcs12_get_key_info(key) != SECSuccess) {
- return SECFailure;
- }
- }
-
- sec_pkcs12_validate_key_by_cert(certList[0], key, wincx);
- for (j = 0; certList[j]; ++j) {
- sec_PKCS12SafeBag *cert = certList[j];
- cert->hasKey = PR_TRUE;
- if(key->problem) {
- cert->problem = PR_TRUE;
- cert->error = key->error;
- continue;
- }
- sec_pkcs12_validate_cert(cert, key, nicknameCb);
- if(cert->problem) {
- key->problem = cert->problem;
- key->error = cert->error;
- }
- }
- }
- }
- }
-
- /* Now take a second pass over the safebags and mark for installation any
- * certs that were neither installed nor disqualified by the first pass.
- */
- for (i = 0; safeBags[i]; ++i) {
- sec_PKCS12SafeBag *bag = safeBags[i];
-
- if(!bag->validated) {
- SECOidTag bagType = SECOID_FindOIDTag(&bag->safeBagType);
-
- switch(bagType) {
- case SEC_OID_PKCS12_V1_CERT_BAG_ID:
- sec_pkcs12_validate_cert(bag, NULL, nicknameCb);
- break;
- case SEC_OID_PKCS12_V1_KEY_BAG_ID:
- case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
- bag->noInstall = PR_TRUE;
- bag->problem = PR_TRUE;
- bag->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
- break;
- default:
- bag->noInstall = PR_TRUE;
- }
- }
- }
-
- return SECSuccess;
-}
-
-SECStatus
-SEC_PKCS12DecoderValidateBags(SEC_PKCS12DecoderContext *p12dcx,
- SEC_PKCS12NicknameCollisionCallback nicknameCb)
-{
- SECStatus rv;
- int i, noInstallCnt, probCnt, bagCnt, errorVal = 0;
- if(!p12dcx || p12dcx->error || !p12dcx->safeBags) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- rv = sec_pkcs12_validate_bags(p12dcx->safeBags, nicknameCb, p12dcx->wincx);
- if(rv == SECSuccess) {
- p12dcx->bagsVerified = PR_TRUE;
- }
-
- noInstallCnt = probCnt = bagCnt = 0;
- i = 0;
- while(p12dcx->safeBags[i]) {
- bagCnt++;
- if(p12dcx->safeBags[i]->noInstall)
- noInstallCnt++;
- if(p12dcx->safeBags[i]->problem) {
- probCnt++;
- errorVal = p12dcx->safeBags[i]->error;
- }
- i++;
- }
-
- /* formerly was erroneous code here that assumed that if all bags
- * failed to import, then the problem was duplicated data;
- * that is, it assume that the problem must be that the file had
- * previously been successfully imported. But importing a
- * previously imported file causes NO ERRORS at all, and this
- * false assumption caused real errors to be hidden behind false
- * errors about duplicated data.
- */
-
- if(probCnt) {
- PORT_SetError(errorVal);
- return SECFailure;
- }
-
- return rv;
-}
-
-
-static SECKEYPublicKey *
-sec_pkcs12_get_public_key_and_usage(sec_PKCS12SafeBag *certBag,
- unsigned int *usage)
-{
- SECKEYPublicKey *pubKey = NULL;
- CERTCertificate *cert = NULL;
-
- if(!certBag || !usage) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- *usage = 0;
-
- cert = CERT_DecodeDERCertificate(
- &certBag->safeBagContent.certBag->value.x509Cert, PR_FALSE, NULL);
- if(!cert) {
- return NULL;
- }
-
- *usage = cert->keyUsage;
- pubKey = CERT_ExtractPublicKey(cert);
- CERT_DestroyCertificate(cert);
- return pubKey;
-}
-
-static SECItem *
-sec_pkcs12_get_public_value_and_type(SECKEYPublicKey *pubKey,
- KeyType *type)
-{
- SECItem *pubValue = NULL;
-
- if(!type || !pubKey) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- *type = pubKey->keyType;
- switch(pubKey->keyType) {
- case dsaKey:
- pubValue = &pubKey->u.dsa.publicValue;
- break;
- case dhKey:
- pubValue = &pubKey->u.dh.publicValue;
- break;
- case rsaKey:
- pubValue = &pubKey->u.rsa.modulus;
- break;
- case ecKey:
- pubValue = &pubKey->u.ec.publicValue;
- break;
- default:
- pubValue = NULL;
- }
-
- return pubValue;
-}
-
-/* This function takes two passes over the bags, installing them in the
- * desired slot. The two passes are intended to mirror exactly the
- * two passes in sec_pkcs12_validate_bags.
- */
-static SECStatus
-sec_pkcs12_install_bags(sec_PKCS12SafeBag **safeBags, void *wincx)
-{
- sec_PKCS12SafeBag **keyList;
- int i;
- int failedKeys = 0;
-
- if(!safeBags) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(!safeBags[0]) {
- return SECSuccess;
- }
-
- /* First pass. Find all the key bags.
- * Try to install them, and any certs associated with them.
- */
- keyList = sec_pkcs12_get_key_bags(safeBags);
- if(keyList) {
- for (i = 0; keyList[i]; i++) {
- SECStatus rv;
- SECKEYPublicKey *pubKey = NULL;
- SECItem *nickName = NULL;
- sec_PKCS12SafeBag *key = keyList[i];
- sec_PKCS12SafeBag **certList;
- unsigned int keyUsage;
-
- if(key->problem) {
- ++failedKeys;
- continue;
- }
-
- certList = sec_pkcs12_find_certs_for_key(safeBags, key);
- if(certList && certList[0]) {
- pubKey = sec_pkcs12_get_public_key_and_usage(certList[0],
- &keyUsage);
- /* use the cert's nickname, if it has one, else use the
- * key's nickname, else fail.
- */
- nickName = sec_pkcs12_get_nickname_for_cert(certList[0], key);
- } else {
- nickName = sec_pkcs12_get_nickname(key);
- }
- if (!nickName) {
- key->error = SEC_ERROR_BAD_NICKNAME;
- key->problem = PR_TRUE;
- rv = SECFailure;
- } else if (!pubKey) {
- key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
- key->problem = PR_TRUE;
- rv = SECFailure;
- } else {
- rv = sec_pkcs12_add_key(key, pubKey, keyUsage, nickName, wincx);
- }
- if (pubKey) {
- SECKEY_DestroyPublicKey(pubKey);
- pubKey = NULL;
- }
- if (nickName) {
- SECITEM_FreeItem(nickName, PR_TRUE);
- nickName = NULL;
- }
- if(rv != SECSuccess) {
- PORT_SetError(key->error);
- ++failedKeys;
- }
-
- if(certList) {
- int j;
-
- for (j = 0; certList[j]; j++) {
- sec_PKCS12SafeBag *cert = certList[j];
- SECStatus certRv;
-
- if (!cert)
- continue;
- if(rv != SECSuccess) {
- cert->problem = key->problem;
- cert->error = key->error;
- cert->noInstall = PR_TRUE;
- continue;
- }
-
- certRv = sec_pkcs12_add_cert(cert, cert->hasKey, wincx);
- if(certRv != SECSuccess) {
- key->problem = cert->problem;
- key->error = cert->error;
- PORT_SetError(cert->error);
- return SECFailure;
- }
- }
- }
- }
- }
- if (failedKeys)
- return SECFailure;
-
- /* Now take a second pass over the safebags and install any certs
- * that were neither installed nor disqualified by the first pass.
- */
- for (i = 0; safeBags[i]; i++) {
- sec_PKCS12SafeBag *bag = safeBags[i];
-
- if (!bag->installed && !bag->problem && !bag->noInstall) {
- SECStatus rv;
- SECOidTag bagType = SECOID_FindOIDTag(&(bag->safeBagType));
-
- switch(bagType) {
- case SEC_OID_PKCS12_V1_CERT_BAG_ID:
- rv = sec_pkcs12_add_cert(bag, bag->hasKey, wincx);
- if(rv != SECSuccess) {
- PORT_SetError(bag->error);
- return SECFailure;
- }
- break;
- case SEC_OID_PKCS12_V1_KEY_BAG_ID:
- case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
- default:
- break;
- }
- }
- }
-
- return SECSuccess;
-}
-
-SECStatus
-SEC_PKCS12DecoderImportBags(SEC_PKCS12DecoderContext *p12dcx)
-{
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(!p12dcx->bagsVerified) {
- return SECFailure;
- }
-
- return sec_pkcs12_install_bags(p12dcx->safeBags, p12dcx->wincx);
-}
-
-PRBool
-sec_pkcs12_bagHasKey(SEC_PKCS12DecoderContext *p12dcx, sec_PKCS12SafeBag *bag)
-{
- int i;
- SECItem *keyId;
- SECItem *certKeyId;
-
- certKeyId = sec_pkcs12_get_attribute_value(bag, SEC_OID_PKCS9_LOCAL_KEY_ID);
- if (certKeyId == NULL) {
- return PR_FALSE;
- }
-
- for (i=0; p12dcx->keyList && p12dcx->keyList[i]; i++) {
- keyId = sec_pkcs12_get_attribute_value(p12dcx->keyList[i],
- SEC_OID_PKCS9_LOCAL_KEY_ID);
- if(!keyId) {
- continue;
- }
- if(SECITEM_CompareItem(certKeyId, keyId) == SECEqual) {
- return PR_TRUE;
- }
- }
- return PR_FALSE;
-}
-
-SECItem *
-sec_pkcs12_get_friendlyName(sec_PKCS12SafeBag *bag)
-{
- SECItem *friendlyName;
- SECItem *tempnm;
-
- tempnm = sec_pkcs12_get_attribute_value(bag, SEC_OID_PKCS9_FRIENDLY_NAME);
- friendlyName = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if (friendlyName) {
- if (!sec_pkcs12_convert_item_to_unicode(NULL, friendlyName,
- tempnm, PR_TRUE, PR_FALSE, PR_FALSE)) {
- SECITEM_FreeItem(friendlyName, PR_TRUE);
- friendlyName = NULL;
- }
- }
- return friendlyName;
-}
-
-/* Following two functions provide access to selected portions of the safe bags.
- * Iteration is implemented per decoder context and may be accessed after
- * SEC_PKCS12DecoderVerify() returns success.
- * When ...DecoderIterateNext() returns SUCCESS a decoder item has been returned
- * where item.type is always set; item.friendlyName is set if it is non-null;
- * item.der, item.hasKey are set only for SEC_OID_PKCS12_V1_CERT_BAG_ID items.
- * ...DecoderIterateNext() returns FAILURE when the list is exhausted or when
- * arguments are invalid; PORT_GetError() is 0 at end-of-list.
- * Caller has read-only access to decoder items. Any SECItems generated are
- * owned by the decoder context and are freed by ...DecoderFinish().
- */
-SECStatus
-SEC_PKCS12DecoderIterateInit(SEC_PKCS12DecoderContext *p12dcx)
-{
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- p12dcx->iteration = 0;
- return SECSuccess;
-}
-
-SECStatus
-SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
- const SEC_PKCS12DecoderItem **ipp)
-{
- sec_PKCS12SafeBag *bag;
-
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (p12dcx->decitem.type != 0 && p12dcx->decitem.der != NULL) {
- SECITEM_FreeItem(p12dcx->decitem.der, PR_TRUE);
- }
- if (p12dcx->decitem.shroudAlg != NULL) {
- SECOID_DestroyAlgorithmID(p12dcx->decitem.shroudAlg, PR_TRUE);
- }
- if (p12dcx->decitem.friendlyName != NULL) {
- SECITEM_FreeItem(p12dcx->decitem.friendlyName, PR_TRUE);
- }
- p12dcx->decitem.type = 0;
- p12dcx->decitem.der = NULL;
- p12dcx->decitem.shroudAlg = NULL;
- p12dcx->decitem.friendlyName = NULL;
- p12dcx->decitem.hasKey = PR_FALSE;
- *ipp = NULL;
- if (p12dcx->keyList == NULL) {
- p12dcx->keyList = sec_pkcs12_get_key_bags(p12dcx->safeBags);
- }
-
-
- for (; p12dcx->iteration < p12dcx->safeBagCount; p12dcx->iteration++) {
- bag = p12dcx->safeBags[p12dcx->iteration];
- if(bag == NULL || bag->problem) {
- continue;
- }
- p12dcx->decitem.type = SECOID_FindOIDTag(&(bag->safeBagType));
- switch(p12dcx->decitem.type) {
- case SEC_OID_PKCS12_V1_CERT_BAG_ID:
- p12dcx->decitem.der = sec_pkcs12_get_der_cert(bag);
- p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
- p12dcx->decitem.hasKey = sec_pkcs12_bagHasKey(p12dcx, bag);
- break;
- case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
- p12dcx->decitem.shroudAlg = PORT_ZNew(SECAlgorithmID);
- if (p12dcx->decitem.shroudAlg) {
- SECOID_CopyAlgorithmID(NULL, p12dcx->decitem.shroudAlg,
- &bag->safeBagContent.pkcs8ShroudedKeyBag->algorithm);
- }
- case SEC_OID_PKCS12_V1_KEY_BAG_ID:
- p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
- break;
- default:
- /* return these even though we don't expect them */
- break;
- case SEC_OID_UNKNOWN:
- /* ignore these */
- continue;
- }
- *ipp = &p12dcx->decitem;
- p12dcx->iteration++;
- break; /* end for() */
- }
-
- PORT_SetError(0); /* end-of-list is SECFailure with no PORT error */
- return ((p12dcx->decitem.type == 0) ? SECFailure : SECSuccess);
-}
-
-static SECStatus
-sec_pkcs12_decoder_append_bag_to_context(SEC_PKCS12DecoderContext *p12dcx,
- sec_PKCS12SafeBag *bag)
-{
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- p12dcx->safeBags = !p12dcx->safeBagCount
- ? PORT_ArenaZNewArray(p12dcx->arena, sec_PKCS12SafeBag *, 2)
- : PORT_ArenaGrowArray(p12dcx->arena, p12dcx->safeBags,
- sec_PKCS12SafeBag *, p12dcx->safeBagCount + 1,
- p12dcx->safeBagCount + 2);
-
- if(!p12dcx->safeBags) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- p12dcx->safeBags[p12dcx->safeBagCount] = bag;
- p12dcx->safeBags[p12dcx->safeBagCount+1] = NULL;
- p12dcx->safeBagCount++;
-
- return SECSuccess;
-}
-
-static sec_PKCS12SafeBag *
-sec_pkcs12_decoder_convert_old_key(SEC_PKCS12DecoderContext *p12dcx,
- void *key, PRBool isEspvk)
-{
- sec_PKCS12SafeBag *keyBag;
- SECOidData *oid;
- SECOidTag keyTag;
- SECItem *keyID, *nickName, *newNickName;
-
- if(!p12dcx || p12dcx->error || !key) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- newNickName = PORT_ArenaZNew(p12dcx->arena, SECItem);
- keyBag = PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeBag);
- if(!keyBag || !newNickName) {
- return NULL;
- }
-
- keyBag->swapUnicodeBytes = p12dcx->swapUnicodeBytes;
- keyBag->slot = p12dcx->slot;
- keyBag->arena = p12dcx->arena;
- keyBag->pwitem = p12dcx->pwitem;
- keyBag->tokenCAs = p12dcx->tokenCAs;
- keyBag->oldBagType = PR_TRUE;
-
- keyTag = (isEspvk) ? SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID :
- SEC_OID_PKCS12_V1_KEY_BAG_ID;
- oid = SECOID_FindOIDByTag(keyTag);
- if(!oid) {
- return NULL;
- }
-
- if(SECITEM_CopyItem(p12dcx->arena, &keyBag->safeBagType, &oid->oid)
- != SECSuccess) {
- return NULL;
- }
-
- if(isEspvk) {
- SEC_PKCS12ESPVKItem *espvk = (SEC_PKCS12ESPVKItem *)key;
- keyBag->safeBagContent.pkcs8ShroudedKeyBag =
- espvk->espvkCipherText.pkcs8KeyShroud;
- nickName = &(espvk->espvkData.uniNickName);
- if(!espvk->espvkData.assocCerts || !espvk->espvkData.assocCerts[0]) {
- PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
- return NULL;
- }
- keyID = &espvk->espvkData.assocCerts[0]->digest;
- } else {
- SEC_PKCS12PrivateKey *pk = (SEC_PKCS12PrivateKey *)key;
- keyBag->safeBagContent.pkcs8KeyBag = &pk->pkcs8data;
- nickName= &(pk->pvkData.uniNickName);
- if(!pk->pvkData.assocCerts || !pk->pvkData.assocCerts[0]) {
- PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
- return NULL;
- }
- keyID = &pk->pvkData.assocCerts[0]->digest;
- }
-
- if(nickName->len) {
- if(nickName->len >= 2) {
- if(nickName->data[0] && nickName->data[1]) {
- if(!sec_pkcs12_convert_item_to_unicode(p12dcx->arena, newNickName,
- nickName, PR_FALSE, PR_FALSE, PR_TRUE)) {
- return NULL;
- }
- nickName = newNickName;
- } else if(nickName->data[0] && !nickName->data[1]) {
- unsigned int j = 0;
- unsigned char t;
- for(j = 0; j < nickName->len; j+=2) {
- t = nickName->data[j+1];
- nickName->data[j+1] = nickName->data[j];
- nickName->data[j] = t;
- }
- }
- } else {
- if(!sec_pkcs12_convert_item_to_unicode(p12dcx->arena, newNickName,
- nickName, PR_FALSE, PR_FALSE, PR_TRUE)) {
- return NULL;
- }
- nickName = newNickName;
- }
- }
-
- if(sec_pkcs12_decoder_set_attribute_value(keyBag,
- SEC_OID_PKCS9_FRIENDLY_NAME,
- nickName) != SECSuccess) {
- return NULL;
- }
-
- if(sec_pkcs12_decoder_set_attribute_value(keyBag,SEC_OID_PKCS9_LOCAL_KEY_ID,
- keyID) != SECSuccess) {
- return NULL;
- }
-
- return keyBag;
-}
-
-static sec_PKCS12SafeBag *
-sec_pkcs12_decoder_create_cert(SEC_PKCS12DecoderContext *p12dcx,
- SECItem *derCert)
-{
- sec_PKCS12SafeBag *certBag;
- SECOidData *oid;
- SGNDigestInfo *digest;
- SECItem *keyId;
- SECStatus rv;
-
- if(!p12dcx || p12dcx->error || !derCert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- keyId = PORT_ArenaZNew(p12dcx->arena, SECItem);
- if(!keyId) {
- return NULL;
- }
-
- digest = sec_pkcs12_compute_thumbprint(derCert);
- if(!digest) {
- return NULL;
- }
-
- rv = SECITEM_CopyItem(p12dcx->arena, keyId, &digest->digest);
- SGN_DestroyDigestInfo(digest);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- oid = SECOID_FindOIDByTag(SEC_OID_PKCS12_V1_CERT_BAG_ID);
- certBag = PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeBag);
- if(!certBag || !oid || (SECITEM_CopyItem(p12dcx->arena,
- &certBag->safeBagType, &oid->oid) != SECSuccess)) {
- return NULL;
- }
-
- certBag->slot = p12dcx->slot;
- certBag->pwitem = p12dcx->pwitem;
- certBag->swapUnicodeBytes = p12dcx->swapUnicodeBytes;
- certBag->arena = p12dcx->arena;
- certBag->tokenCAs = p12dcx->tokenCAs;
-
- oid = SECOID_FindOIDByTag(SEC_OID_PKCS9_X509_CERT);
- certBag->safeBagContent.certBag =
- PORT_ArenaZNew(p12dcx->arena, sec_PKCS12CertBag);
- if(!certBag->safeBagContent.certBag || !oid ||
- (SECITEM_CopyItem(p12dcx->arena,
- &certBag->safeBagContent.certBag->bagID,
- &oid->oid) != SECSuccess)) {
- return NULL;
- }
-
- if(SECITEM_CopyItem(p12dcx->arena,
- &(certBag->safeBagContent.certBag->value.x509Cert),
- derCert) != SECSuccess) {
- return NULL;
- }
-
- if(sec_pkcs12_decoder_set_attribute_value(certBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
- keyId) != SECSuccess) {
- return NULL;
- }
-
- return certBag;
-}
-
-static sec_PKCS12SafeBag **
-sec_pkcs12_decoder_convert_old_cert(SEC_PKCS12DecoderContext *p12dcx,
- SEC_PKCS12CertAndCRL *oldCert)
-{
- sec_PKCS12SafeBag **certList;
- SECItem **derCertList;
- int i, j;
-
- if(!p12dcx || p12dcx->error || !oldCert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- derCertList = SEC_PKCS7GetCertificateList(&oldCert->value.x509->certOrCRL);
- if(!derCertList) {
- return NULL;
- }
-
- i = 0;
- while(derCertList[i]) i++;
-
- certList = PORT_ArenaZNewArray(p12dcx->arena, sec_PKCS12SafeBag *, (i + 1));
- if(!certList) {
- return NULL;
- }
-
- for(j = 0; j < i; j++) {
- certList[j] = sec_pkcs12_decoder_create_cert(p12dcx, derCertList[j]);
- if(!certList[j]) {
- return NULL;
- }
- }
-
- return certList;
-}
-
-static SECStatus
-sec_pkcs12_decoder_convert_old_key_and_certs(SEC_PKCS12DecoderContext *p12dcx,
- void *oldKey, PRBool isEspvk,
- SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage)
-{
- sec_PKCS12SafeBag *key, **certList;
- SEC_PKCS12CertAndCRL *oldCert;
- SEC_PKCS12PVKSupportingData *pvkData;
- int i;
- SECItem *keyName;
-
- if(!p12dcx || !oldKey) {
- return SECFailure;
- }
-
- if(isEspvk) {
- pvkData = &((SEC_PKCS12ESPVKItem *)(oldKey))->espvkData;
- } else {
- pvkData = &((SEC_PKCS12PrivateKey *)(oldKey))->pvkData;
- }
-
- if(!pvkData->assocCerts || !pvkData->assocCerts[0]) {
- PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
- return SECFailure;
- }
-
- oldCert = (SEC_PKCS12CertAndCRL *)sec_pkcs12_find_object(safe, baggage,
- SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID, NULL,
- pvkData->assocCerts[0]);
- if(!oldCert) {
- PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
- return SECFailure;
- }
-
- key = sec_pkcs12_decoder_convert_old_key(p12dcx,oldKey, isEspvk);
- certList = sec_pkcs12_decoder_convert_old_cert(p12dcx, oldCert);
- if(!key || !certList) {
- return SECFailure;
- }
-
- if(sec_pkcs12_decoder_append_bag_to_context(p12dcx, key) != SECSuccess) {
- return SECFailure;
- }
-
- keyName = sec_pkcs12_get_nickname(key);
- if(!keyName) {
- return SECFailure;
- }
-
- i = 0;
- while(certList[i]) {
- if(sec_pkcs12_decoder_append_bag_to_context(p12dcx, certList[i])
- != SECSuccess) {
- return SECFailure;
- }
- i++;
- }
-
- certList = sec_pkcs12_find_certs_for_key(p12dcx->safeBags, key);
- if(!certList) {
- return SECFailure;
- }
-
- i = 0;
- while(certList[i] != 0) {
- if(sec_pkcs12_set_nickname(certList[i], keyName) != SECSuccess) {
- return SECFailure;
- }
- i++;
- }
-
- return SECSuccess;
-}
-
-static SECStatus
-sec_pkcs12_decoder_convert_old_safe_to_bags(SEC_PKCS12DecoderContext *p12dcx,
- SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage)
-{
- SECStatus rv;
-
- if(!p12dcx || p12dcx->error) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if(safe && safe->contents) {
- int i = 0;
- while(safe->contents[i] != NULL) {
- if(SECOID_FindOIDTag(&safe->contents[i]->safeBagType)
- == SEC_OID_PKCS12_KEY_BAG_ID) {
- int j = 0;
- SEC_PKCS12PrivateKeyBag *privBag =
- safe->contents[i]->safeContent.keyBag;
-
- while(privBag->privateKeys[j] != NULL) {
- SEC_PKCS12PrivateKey *pk = privBag->privateKeys[j];
- rv = sec_pkcs12_decoder_convert_old_key_and_certs(p12dcx,pk,
- PR_FALSE, safe, baggage);
- if(rv != SECSuccess) {
- goto loser;
- }
- j++;
- }
- }
- i++;
- }
- }
-
- if(baggage && baggage->bags) {
- int i = 0;
- while(baggage->bags[i] != NULL) {
- SEC_PKCS12BaggageItem *bag = baggage->bags[i];
- int j = 0;
-
- if(!bag->espvks) {
- i++;
- continue;
- }
-
- while(bag->espvks[j] != NULL) {
- SEC_PKCS12ESPVKItem *espvk = bag->espvks[j];
- rv = sec_pkcs12_decoder_convert_old_key_and_certs(p12dcx, espvk,
- PR_TRUE, safe, baggage);
- if(rv != SECSuccess) {
- goto loser;
- }
- j++;
- }
- i++;
- }
- }
-
- return SECSuccess;
-
-loser:
- return SECFailure;
-}
-
-SEC_PKCS12DecoderContext *
-sec_PKCS12ConvertOldSafeToNew(PRArenaPool *arena, PK11SlotInfo *slot,
- PRBool swapUnicode, SECItem *pwitem,
- void *wincx, SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage)
-{
- SEC_PKCS12DecoderContext *p12dcx;
-
- if(!arena || !slot || !pwitem) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- if(!safe && !baggage) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- p12dcx = PORT_ArenaZNew(arena, SEC_PKCS12DecoderContext);
- if(!p12dcx) {
- return NULL;
- }
-
- p12dcx->arena = arena;
- p12dcx->slot = PK11_ReferenceSlot(slot);
- p12dcx->wincx = wincx;
- p12dcx->error = PR_FALSE;
- p12dcx->swapUnicodeBytes = swapUnicode;
- p12dcx->pwitem = pwitem;
- p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs;
-
- if(sec_pkcs12_decoder_convert_old_safe_to_bags(p12dcx, safe, baggage)
- != SECSuccess) {
- p12dcx->error = PR_TRUE;
- return NULL;
- }
-
- return p12dcx;
-}
diff --git a/security/nss/lib/pkcs12/p12dec.c b/security/nss/lib/pkcs12/p12dec.c
deleted file mode 100644
index 61651b080..000000000
--- a/security/nss/lib/pkcs12/p12dec.c
+++ /dev/null
@@ -1,664 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "pkcs12.h"
-#include "plarena.h"
-#include "secpkcs7.h"
-#include "p12local.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "secport.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "secerr.h"
-#include "cert.h"
-#include "certdb.h"
-#include "p12plcy.h"
-#include "p12.h"
-#include "secpkcs5.h"
-
-/* PFX extraction and validation routines */
-
-/* decode the DER encoded PFX item. if unable to decode, check to see if it
- * is an older PFX item. If that fails, assume the file was not a valid
- * pfx file.
- * the returned pfx structure should be destroyed using SEC_PKCS12DestroyPFX
- */
-static SEC_PKCS12PFXItem *
-sec_pkcs12_decode_pfx(SECItem *der_pfx)
-{
- SEC_PKCS12PFXItem *pfx;
- SECStatus rv;
-
- if(der_pfx == NULL) {
- return NULL;
- }
-
- /* allocate the space for a new PFX item */
- pfx = sec_pkcs12_new_pfx();
- if(pfx == NULL) {
- return NULL;
- }
-
- rv = SEC_ASN1DecodeItem(pfx->poolp, pfx, SEC_PKCS12PFXItemTemplate,
- der_pfx);
-
- /* if a failure occurred, check for older version...
- * we also get rid of the old pfx structure, because we don't
- * know where it failed and what data in may contain
- */
- if(rv != SECSuccess) {
- SEC_PKCS12DestroyPFX(pfx);
- pfx = sec_pkcs12_new_pfx();
- if(pfx == NULL) {
- return NULL;
- }
- rv = SEC_ASN1DecodeItem(pfx->poolp, pfx, SEC_PKCS12PFXItemTemplate_OLD,
- der_pfx);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_PKCS12_DECODING_PFX);
- PORT_FreeArena(pfx->poolp, PR_TRUE);
- return NULL;
- }
- pfx->old = PR_TRUE;
- SGN_CopyDigestInfo(pfx->poolp, &pfx->macData.safeMac, &pfx->old_safeMac);
- SECITEM_CopyItem(pfx->poolp, &pfx->macData.macSalt, &pfx->old_macSalt);
- } else {
- pfx->old = PR_FALSE;
- }
-
- /* convert bit string from bits to bytes */
- pfx->macData.macSalt.len /= 8;
-
- return pfx;
-}
-
-/* validate the integrity MAC used in the PFX. The MAC is generated
- * per the PKCS 12 document. If the MAC is incorrect, it is most likely
- * due to an invalid password.
- * pwitem is the integrity password
- * pfx is the decoded pfx item
- */
-static PRBool
-sec_pkcs12_check_pfx_mac(SEC_PKCS12PFXItem *pfx,
- SECItem *pwitem)
-{
- SECItem *key = NULL, *mac = NULL, *data = NULL;
- SECItem *vpwd = NULL;
- SECOidTag algorithm;
- PRBool ret = PR_FALSE;
-
- if(pfx == NULL) {
- return PR_FALSE;
- }
-
- algorithm = SECOID_GetAlgorithmTag(&pfx->macData.safeMac.digestAlgorithm);
- switch(algorithm) {
- /* only SHA1 hashing supported as a MACing algorithm */
- case SEC_OID_SHA1:
- if(pfx->old == PR_FALSE) {
- pfx->swapUnicode = PR_FALSE;
- }
-
-recheckUnicodePassword:
- vpwd = sec_pkcs12_create_virtual_password(pwitem,
- &pfx->macData.macSalt,
- pfx->swapUnicode);
- if(vpwd == NULL) {
- return PR_FALSE;
- }
-
- key = sec_pkcs12_generate_key_from_password(algorithm,
- &pfx->macData.macSalt,
- (pfx->old ? pwitem : vpwd));
- /* free vpwd only for newer PFX */
- if(vpwd) {
- SECITEM_ZfreeItem(vpwd, PR_TRUE);
- }
- if(key == NULL) {
- return PR_FALSE;
- }
-
- data = SEC_PKCS7GetContent(&pfx->authSafe);
- if(data == NULL) {
- break;
- }
-
- /* check MAC */
- mac = sec_pkcs12_generate_mac(key, data, pfx->old);
- ret = PR_TRUE;
- if(mac) {
- SECItem *safeMac = &pfx->macData.safeMac.digest;
- if(SECITEM_CompareItem(mac, safeMac) != SECEqual) {
-
- /* if we encounter an invalid mac, lets invert the
- * password in case of unicode changes
- */
- if(((!pfx->old) && pfx->swapUnicode) || (pfx->old)){
- PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC);
- ret = PR_FALSE;
- } else {
- SECITEM_ZfreeItem(mac, PR_TRUE);
- pfx->swapUnicode = PR_TRUE;
- goto recheckUnicodePassword;
- }
- }
- SECITEM_ZfreeItem(mac, PR_TRUE);
- } else {
- ret = PR_FALSE;
- }
- break;
- default:
- PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM);
- ret = PR_FALSE;
- break;
- }
-
- /* let success fall through */
- if(key != NULL)
- SECITEM_ZfreeItem(key, PR_TRUE);
-
- return ret;
-}
-
-/* check the validity of the pfx structure. we currently only support
- * password integrity mode, so we check the MAC.
- */
-static PRBool
-sec_pkcs12_validate_pfx(SEC_PKCS12PFXItem *pfx,
- SECItem *pwitem)
-{
- SECOidTag contentType;
-
- contentType = SEC_PKCS7ContentType(&pfx->authSafe);
- switch(contentType)
- {
- case SEC_OID_PKCS7_DATA:
- return sec_pkcs12_check_pfx_mac(pfx, pwitem);
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- default:
- PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE);
- break;
- }
-
- return PR_FALSE;
-}
-
-/* decode and return the valid PFX. if the PFX item is not valid,
- * NULL is returned.
- */
-static SEC_PKCS12PFXItem *
-sec_pkcs12_get_pfx(SECItem *pfx_data,
- SECItem *pwitem)
-{
- SEC_PKCS12PFXItem *pfx;
- PRBool valid_pfx;
-
- if((pfx_data == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- pfx = sec_pkcs12_decode_pfx(pfx_data);
- if(pfx == NULL) {
- return NULL;
- }
-
- valid_pfx = sec_pkcs12_validate_pfx(pfx, pwitem);
- if(valid_pfx != PR_TRUE) {
- SEC_PKCS12DestroyPFX(pfx);
- pfx = NULL;
- }
-
- return pfx;
-}
-
-/* authenticated safe decoding, validation, and access routines
- */
-
-/* convert dogbert beta 3 authenticated safe structure to a post
- * beta three structure, so that we don't have to change more routines.
- */
-static SECStatus
-sec_pkcs12_convert_old_auth_safe(SEC_PKCS12AuthenticatedSafe *asafe)
-{
- SEC_PKCS12Baggage *baggage;
- SEC_PKCS12BaggageItem *bag;
- SECStatus rv = SECSuccess;
-
- if(asafe->old_baggage.espvks == NULL) {
- /* XXX should the ASN1 engine produce a single NULL element list
- * rather than setting the pointer to NULL?
- * There is no need to return an error -- assume that the list
- * was empty.
- */
- return SECSuccess;
- }
-
- baggage = sec_pkcs12_create_baggage(asafe->poolp);
- if(!baggage) {
- return SECFailure;
- }
- bag = sec_pkcs12_create_external_bag(baggage);
- if(!bag) {
- return SECFailure;
- }
-
- PORT_Memcpy(&asafe->baggage, baggage, sizeof(SEC_PKCS12Baggage));
-
- /* if there are shrouded keys, append them to the bag */
- rv = SECSuccess;
- if(asafe->old_baggage.espvks[0] != NULL) {
- int nEspvk = 0;
- rv = SECSuccess;
- while((asafe->old_baggage.espvks[nEspvk] != NULL) &&
- (rv == SECSuccess)) {
- rv = sec_pkcs12_append_shrouded_key(bag,
- asafe->old_baggage.espvks[nEspvk]);
- nEspvk++;
- }
- }
-
- return rv;
-}
-
-/* decodes the authenticated safe item. a return of NULL indicates
- * an error. however, the error will have occurred either in memory
- * allocation or in decoding the authenticated safe.
- *
- * if an old PFX item has been found, we want to convert the
- * old authenticated safe to the new one.
- */
-static SEC_PKCS12AuthenticatedSafe *
-sec_pkcs12_decode_authenticated_safe(SEC_PKCS12PFXItem *pfx)
-{
- SECItem *der_asafe = NULL;
- SEC_PKCS12AuthenticatedSafe *asafe = NULL;
- SECStatus rv;
-
- if(pfx == NULL) {
- return NULL;
- }
-
- der_asafe = SEC_PKCS7GetContent(&pfx->authSafe);
- if(der_asafe == NULL) {
- /* XXX set error ? */
- goto loser;
- }
-
- asafe = sec_pkcs12_new_asafe(pfx->poolp);
- if(asafe == NULL) {
- goto loser;
- }
-
- if(pfx->old == PR_FALSE) {
- rv = SEC_ASN1DecodeItem(pfx->poolp, asafe,
- SEC_PKCS12AuthenticatedSafeTemplate,
- der_asafe);
- asafe->old = PR_FALSE;
- asafe->swapUnicode = pfx->swapUnicode;
- } else {
- /* handle beta exported files */
- rv = SEC_ASN1DecodeItem(pfx->poolp, asafe,
- SEC_PKCS12AuthenticatedSafeTemplate_OLD,
- der_asafe);
- asafe->safe = &(asafe->old_safe);
- rv = sec_pkcs12_convert_old_auth_safe(asafe);
- asafe->old = PR_TRUE;
- }
-
- if(rv != SECSuccess) {
- goto loser;
- }
-
- asafe->poolp = pfx->poolp;
-
- return asafe;
-
-loser:
- return NULL;
-}
-
-/* validates the safe within the authenticated safe item.
- * in order to be valid:
- * 1. the privacy salt must be present
- * 2. the encryption algorithm must be supported (including
- * export policy)
- * PR_FALSE indicates an error, PR_TRUE indicates a valid safe
- */
-static PRBool
-sec_pkcs12_validate_encrypted_safe(SEC_PKCS12AuthenticatedSafe *asafe)
-{
- PRBool valid = PR_FALSE;
- SECAlgorithmID *algid;
-
- if(asafe == NULL) {
- return PR_FALSE;
- }
-
- /* if mode is password privacy, then privacySalt is assumed
- * to be non-zero.
- */
- if(asafe->privacySalt.len != 0) {
- valid = PR_TRUE;
- asafe->privacySalt.len /= 8;
- } else {
- PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
- return PR_FALSE;
- }
-
- /* until spec changes, content will have between 2 and 8 bytes depending
- * upon the algorithm used if certs are unencrypted...
- * also want to support case where content is empty -- which we produce
- */
- if(SEC_PKCS7IsContentEmpty(asafe->safe, 8) == PR_TRUE) {
- asafe->emptySafe = PR_TRUE;
- return PR_TRUE;
- }
-
- asafe->emptySafe = PR_FALSE;
-
- /* make sure that a pbe algorithm is being used */
- algid = SEC_PKCS7GetEncryptionAlgorithm(asafe->safe);
- if(algid != NULL) {
- if(SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
- valid = SEC_PKCS12DecryptionAllowed(algid);
-
- if(valid == PR_FALSE) {
- PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM);
- }
- } else {
- PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM);
- valid = PR_FALSE;
- }
- } else {
- valid = PR_FALSE;
- PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM);
- }
-
- return valid;
-}
-
-/* validates authenticates safe:
- * 1. checks that the version is supported
- * 2. checks that only password privacy mode is used (currently)
- * 3. further, makes sure safe has appropriate policies per above function
- * PR_FALSE indicates failure.
- */
-static PRBool
-sec_pkcs12_validate_auth_safe(SEC_PKCS12AuthenticatedSafe *asafe)
-{
- PRBool valid = PR_TRUE;
- SECOidTag safe_type;
- int version;
-
- if(asafe == NULL) {
- return PR_FALSE;
- }
-
- /* check version, since it is default it may not be present.
- * therefore, assume ok
- */
- if((asafe->version.len > 0) && (asafe->old == PR_FALSE)) {
- version = DER_GetInteger(&asafe->version);
- if(version > SEC_PKCS12_PFX_VERSION) {
- PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION);
- return PR_FALSE;
- }
- }
-
- /* validate password mode is being used */
- safe_type = SEC_PKCS7ContentType(asafe->safe);
- switch(safe_type)
- {
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- valid = sec_pkcs12_validate_encrypted_safe(asafe);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- default:
- PORT_SetError(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE);
- valid = PR_FALSE;
- break;
- }
-
- return valid;
-}
-
-/* retrieves the authenticated safe item from the PFX item
- * before returning the authenticated safe, the validity of the
- * authenticated safe is checked and if valid, returned.
- * a return of NULL indicates that an error occurred.
- */
-static SEC_PKCS12AuthenticatedSafe *
-sec_pkcs12_get_auth_safe(SEC_PKCS12PFXItem *pfx)
-{
- SEC_PKCS12AuthenticatedSafe *asafe;
- PRBool valid_safe;
-
- if(pfx == NULL) {
- return NULL;
- }
-
- asafe = sec_pkcs12_decode_authenticated_safe(pfx);
- if(asafe == NULL) {
- return NULL;
- }
-
- valid_safe = sec_pkcs12_validate_auth_safe(asafe);
- if(valid_safe != PR_TRUE) {
- asafe = NULL;
- } else if(asafe) {
- asafe->baggage.poolp = asafe->poolp;
- }
-
- return asafe;
-}
-
-/* decrypts the authenticated safe.
- * a return of anything but SECSuccess indicates an error. the
- * password is not known to be valid until the call to the
- * function sec_pkcs12_get_safe_contents. If decoding the safe
- * fails, it is assumed the password was incorrect and the error
- * is set then. any failure here is assumed to be due to
- * internal problems in SEC_PKCS7DecryptContents or below.
- */
-static SECStatus
-sec_pkcs12_decrypt_auth_safe(SEC_PKCS12AuthenticatedSafe *asafe,
- SECItem *pwitem,
- void *wincx)
-{
- SECStatus rv = SECFailure;
- SECItem *vpwd = NULL;
-
- if((asafe == NULL) || (pwitem == NULL)) {
- return SECFailure;
- }
-
- if(asafe->old == PR_FALSE) {
- vpwd = sec_pkcs12_create_virtual_password(pwitem, &asafe->privacySalt,
- asafe->swapUnicode);
- if(vpwd == NULL) {
- return SECFailure;
- }
- }
-
- rv = SEC_PKCS7DecryptContents(asafe->poolp, asafe->safe,
- (asafe->old ? pwitem : vpwd), wincx);
-
- if(asafe->old == PR_FALSE) {
- SECITEM_ZfreeItem(vpwd, PR_TRUE);
- }
-
- return rv;
-}
-
-/* extract the safe from the authenticated safe.
- * if we are unable to decode the safe, then it is likely that the
- * safe has not been decrypted or the password used to decrypt
- * the safe was invalid. we assume that the password was invalid and
- * set an error accordingly.
- * a return of NULL indicates that an error occurred.
- */
-static SEC_PKCS12SafeContents *
-sec_pkcs12_get_safe_contents(SEC_PKCS12AuthenticatedSafe *asafe)
-{
- SECItem *src = NULL;
- SEC_PKCS12SafeContents *safe = NULL;
- SECStatus rv = SECFailure;
-
- if(asafe == NULL) {
- return NULL;
- }
-
- safe = (SEC_PKCS12SafeContents *)PORT_ArenaZAlloc(asafe->poolp,
- sizeof(SEC_PKCS12SafeContents));
- if(safe == NULL) {
- return NULL;
- }
- safe->poolp = asafe->poolp;
- safe->old = asafe->old;
- safe->swapUnicode = asafe->swapUnicode;
-
- src = SEC_PKCS7GetContent(asafe->safe);
- if(src != NULL) {
- const SEC_ASN1Template *theTemplate;
- if(asafe->old != PR_TRUE) {
- theTemplate = SEC_PKCS12SafeContentsTemplate;
- } else {
- theTemplate = SEC_PKCS12SafeContentsTemplate_OLD;
- }
-
- rv = SEC_ASN1DecodeItem(asafe->poolp, safe, theTemplate, src);
-
- /* if we could not decode the item, password was probably invalid */
- if(rv != SECSuccess) {
- safe = NULL;
- PORT_SetError(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT);
- }
- } else {
- PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
- rv = SECFailure;
- }
-
- return safe;
-}
-
-/* import PFX item
- * der_pfx is the der encoded pfx structure
- * pbef and pbearg are the integrity/encryption password call back
- * ncCall is the nickname collision calllback
- * slot is the destination token
- * wincx window handler
- *
- * on error, error code set and SECFailure returned
- */
-SECStatus
-SEC_PKCS12PutPFX(SECItem *der_pfx, SECItem *pwitem,
- SEC_PKCS12NicknameCollisionCallback ncCall,
- PK11SlotInfo *slot,
- void *wincx)
-{
- SEC_PKCS12PFXItem *pfx;
- SEC_PKCS12AuthenticatedSafe *asafe;
- SEC_PKCS12SafeContents *safe_contents = NULL;
- SECStatus rv;
-
- if(!der_pfx || !pwitem || !slot) {
- return SECFailure;
- }
-
- /* decode and validate each section */
- rv = SECFailure;
-
- pfx = sec_pkcs12_get_pfx(der_pfx, pwitem);
- if(pfx != NULL) {
- asafe = sec_pkcs12_get_auth_safe(pfx);
- if(asafe != NULL) {
-
- /* decrypt safe -- only if not empty */
- if(asafe->emptySafe != PR_TRUE) {
- rv = sec_pkcs12_decrypt_auth_safe(asafe, pwitem, wincx);
- if(rv == SECSuccess) {
- safe_contents = sec_pkcs12_get_safe_contents(asafe);
- if(safe_contents == NULL) {
- rv = SECFailure;
- }
- }
- } else {
- safe_contents = sec_pkcs12_create_safe_contents(asafe->poolp);
- if(safe_contents == NULL) {
- rv = SECFailure;
- } else {
- safe_contents->swapUnicode = pfx->swapUnicode;
- rv = SECSuccess;
- }
- }
-
- /* get safe contents and begin import */
- if(rv == SECSuccess) {
- SEC_PKCS12DecoderContext *p12dcx;
-
- p12dcx = sec_PKCS12ConvertOldSafeToNew(pfx->poolp, slot,
- pfx->swapUnicode,
- pwitem, wincx, safe_contents,
- &asafe->baggage);
- if(!p12dcx) {
- rv = SECFailure;
- goto loser;
- }
-
- if(SEC_PKCS12DecoderValidateBags(p12dcx, ncCall)
- != SECSuccess) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = SEC_PKCS12DecoderImportBags(p12dcx);
- }
-
- }
- }
-
-loser:
-
- if(pfx) {
- SEC_PKCS12DestroyPFX(pfx);
- }
-
- return rv;
-}
-
-PRBool
-SEC_PKCS12ValidData(char *buf, int bufLen, long int totalLength)
-{
- int lengthLength;
-
- PRBool valid = PR_FALSE;
-
- if(buf == NULL) {
- return PR_FALSE;
- }
-
- /* check for constructed sequence identifier tag */
- if(*buf == (SEC_ASN1_CONSTRUCTED | SEC_ASN1_SEQUENCE)) {
- totalLength--; /* header byte taken care of */
- buf++;
-
- lengthLength = (long int)SEC_ASN1LengthLength(totalLength - 1);
- if(totalLength > 0x7f) {
- lengthLength--;
- *buf &= 0x7f; /* remove bit 8 indicator */
- if((*buf - (char)lengthLength) == 0) {
- valid = PR_TRUE;
- }
- } else {
- lengthLength--;
- if((*buf - (char)lengthLength) == 0) {
- valid = PR_TRUE;
- }
- }
- }
-
- return valid;
-}
diff --git a/security/nss/lib/pkcs12/p12e.c b/security/nss/lib/pkcs12/p12e.c
deleted file mode 100644
index 74bc76cc1..000000000
--- a/security/nss/lib/pkcs12/p12e.c
+++ /dev/null
@@ -1,2079 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "p12t.h"
-#include "p12.h"
-#include "plarena.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "seccomon.h"
-#include "secport.h"
-#include "cert.h"
-#include "secpkcs7.h"
-#include "secasn1.h"
-#include "secerr.h"
-#include "pk11func.h"
-#include "p12plcy.h"
-#include "p12local.h"
-#include "prcpucfg.h"
-
-extern const int NSS_PBE_DEFAULT_ITERATION_COUNT; /* defined in p7create.c */
-
-/*
-** This PKCS12 file encoder uses numerous nested ASN.1 and PKCS7 encoder
-** contexts. It can be difficult to keep straight. Here's a picture:
-**
-** "outer" ASN.1 encoder. The output goes to the library caller's CB.
-** "middle" PKCS7 encoder. Feeds the "outer" ASN.1 encoder.
-** "middle" ASN1 encoder. Encodes the encrypted aSafes.
-** Feeds the "middle" P7 encoder above.
-** "inner" PKCS7 encoder. Encrypts the "authenticated Safes" (aSafes)
-** Feeds the "middle" ASN.1 encoder above.
-** "inner" ASN.1 encoder. Encodes the unencrypted aSafes.
-** Feeds the "inner" P7 enocder above.
-**
-** Buffering has been added at each point where the output of an ASN.1
-** encoder feeds the input of a PKCS7 encoder.
-*/
-
-/*********************************
- * Output buffer object, used to buffer output from ASN.1 encoder
- * before passing data on down to the next PKCS7 encoder.
- *********************************/
-
-#define PK12_OUTPUT_BUFFER_SIZE 8192
-
-struct sec_pkcs12OutputBufferStr {
- SEC_PKCS7EncoderContext * p7eCx;
- PK11Context * hmacCx;
- unsigned int numBytes;
- unsigned int bufBytes;
- char buf[PK12_OUTPUT_BUFFER_SIZE];
-};
-typedef struct sec_pkcs12OutputBufferStr sec_pkcs12OutputBuffer;
-
-/*********************************
- * Structures used in exporting the PKCS 12 blob
- *********************************/
-
-/* A SafeInfo is used for each ContentInfo which makes up the
- * sequence of safes in the AuthenticatedSafe portion of the
- * PFX structure.
- */
-struct SEC_PKCS12SafeInfoStr {
- PRArenaPool *arena;
-
- /* information for setting up password encryption */
- SECItem pwitem;
- SECOidTag algorithm;
- PK11SymKey *encryptionKey;
-
- /* how many items have been stored in this safe,
- * we will skip any safe which does not contain any
- * items
- */
- unsigned int itemCount;
-
- /* the content info for the safe */
- SEC_PKCS7ContentInfo *cinfo;
-
- sec_PKCS12SafeContents *safe;
-};
-
-/* An opaque structure which contains information needed for exporting
- * certificates and keys through PKCS 12.
- */
-struct SEC_PKCS12ExportContextStr {
- PRArenaPool *arena;
- PK11SlotInfo *slot;
- void *wincx;
-
- /* integrity information */
- PRBool integrityEnabled;
- PRBool pwdIntegrity;
- union {
- struct sec_PKCS12PasswordModeInfo pwdInfo;
- struct sec_PKCS12PublicKeyModeInfo pubkeyInfo;
- } integrityInfo;
-
- /* helper functions */
- /* retrieve the password call back */
- SECKEYGetPasswordKey pwfn;
- void *pwfnarg;
-
- /* safe contents bags */
- SEC_PKCS12SafeInfo **safeInfos;
- unsigned int safeInfoCount;
-
- /* the sequence of safes */
- sec_PKCS12AuthenticatedSafe authSafe;
-
- /* information needing deletion */
- CERTCertificate **certList;
-};
-
-/* structures for passing information to encoder callbacks when processing
- * data through the ASN1 engine.
- */
-struct sec_pkcs12_encoder_output {
- SEC_PKCS12EncoderOutputCallback outputfn;
- void *outputarg;
-};
-
-struct sec_pkcs12_hmac_and_output_info {
- void *arg;
- struct sec_pkcs12_encoder_output output;
-};
-
-/* An encoder context which is used for the actual encoding
- * portion of PKCS 12.
- */
-typedef struct sec_PKCS12EncoderContextStr {
- PRArenaPool *arena;
- SEC_PKCS12ExportContext *p12exp;
-
- /* encoder information - this is set up based on whether
- * password based or public key pased privacy is being used
- */
- SEC_ASN1EncoderContext *outerA1ecx;
- union {
- struct sec_pkcs12_hmac_and_output_info hmacAndOutputInfo;
- struct sec_pkcs12_encoder_output encOutput;
- } output;
-
- /* structures for encoding of PFX and MAC */
- sec_PKCS12PFXItem pfx;
- sec_PKCS12MacData mac;
-
- /* authenticated safe encoding tracking information */
- SEC_PKCS7ContentInfo *aSafeCinfo;
- SEC_PKCS7EncoderContext *middleP7ecx;
- SEC_ASN1EncoderContext *middleA1ecx;
- unsigned int currentSafe;
-
- /* hmac context */
- PK11Context *hmacCx;
-
- /* output buffers */
- sec_pkcs12OutputBuffer middleBuf;
- sec_pkcs12OutputBuffer innerBuf;
-
-} sec_PKCS12EncoderContext;
-
-
-/*********************************
- * Export setup routines
- *********************************/
-
-/* SEC_PKCS12CreateExportContext
- * Creates an export context and sets the unicode and password retrieval
- * callbacks. This is the first call which must be made when exporting
- * a PKCS 12 blob.
- *
- * pwfn, pwfnarg - password retrieval callback and argument. these are
- * required for password-authentication mode.
- */
-SEC_PKCS12ExportContext *
-SEC_PKCS12CreateExportContext(SECKEYGetPasswordKey pwfn, void *pwfnarg,
- PK11SlotInfo *slot, void *wincx)
-{
- PRArenaPool *arena = NULL;
- SEC_PKCS12ExportContext *p12ctxt = NULL;
-
- /* allocate the arena and create the context */
- arena = PORT_NewArena(4096);
- if(!arena) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- p12ctxt = (SEC_PKCS12ExportContext *)PORT_ArenaZAlloc(arena,
- sizeof(SEC_PKCS12ExportContext));
- if(!p12ctxt) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* password callback for key retrieval */
- p12ctxt->pwfn = pwfn;
- p12ctxt->pwfnarg = pwfnarg;
-
- p12ctxt->integrityEnabled = PR_FALSE;
- p12ctxt->arena = arena;
- p12ctxt->wincx = wincx;
- p12ctxt->slot = (slot) ? PK11_ReferenceSlot(slot) : PK11_GetInternalSlot();
-
- return p12ctxt;
-
-loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- return NULL;
-}
-
-/*
- * Adding integrity mode
- */
-
-/* SEC_PKCS12AddPasswordIntegrity
- * Add password integrity to the exported data. If an integrity method
- * has already been set, then return an error.
- *
- * p12ctxt - the export context
- * pwitem - the password for integrity mode
- * integAlg - the integrity algorithm to use for authentication.
- */
-SECStatus
-SEC_PKCS12AddPasswordIntegrity(SEC_PKCS12ExportContext *p12ctxt,
- SECItem *pwitem, SECOidTag integAlg)
-{
- if(!p12ctxt || p12ctxt->integrityEnabled) {
- return SECFailure;
- }
-
- /* set up integrity information */
- p12ctxt->pwdIntegrity = PR_TRUE;
- p12ctxt->integrityInfo.pwdInfo.password =
- (SECItem*)PORT_ArenaZAlloc(p12ctxt->arena, sizeof(SECItem));
- if(!p12ctxt->integrityInfo.pwdInfo.password) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- if(SECITEM_CopyItem(p12ctxt->arena,
- p12ctxt->integrityInfo.pwdInfo.password, pwitem)
- != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- p12ctxt->integrityInfo.pwdInfo.algorithm = integAlg;
- p12ctxt->integrityEnabled = PR_TRUE;
-
- return SECSuccess;
-}
-
-/* SEC_PKCS12AddPublicKeyIntegrity
- * Add public key integrity to the exported data. If an integrity method
- * has already been set, then return an error. The certificate must be
- * allowed to be used as a signing cert.
- *
- * p12ctxt - the export context
- * cert - signer certificate
- * certDb - the certificate database
- * algorithm - signing algorithm
- * keySize - size of the signing key (?)
- */
-SECStatus
-SEC_PKCS12AddPublicKeyIntegrity(SEC_PKCS12ExportContext *p12ctxt,
- CERTCertificate *cert, CERTCertDBHandle *certDb,
- SECOidTag algorithm, int keySize)
-{
- if(!p12ctxt) {
- return SECFailure;
- }
-
- p12ctxt->integrityInfo.pubkeyInfo.cert = cert;
- p12ctxt->integrityInfo.pubkeyInfo.certDb = certDb;
- p12ctxt->integrityInfo.pubkeyInfo.algorithm = algorithm;
- p12ctxt->integrityInfo.pubkeyInfo.keySize = keySize;
- p12ctxt->integrityEnabled = PR_TRUE;
-
- return SECSuccess;
-}
-
-
-/*
- * Adding safes - encrypted (password/public key) or unencrypted
- * Each of the safe creation routines return an opaque pointer which
- * are later passed into the routines for exporting certificates and
- * keys.
- */
-
-/* append the newly created safeInfo to list of safeInfos in the export
- * context.
- */
-static SECStatus
-sec_pkcs12_append_safe_info(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *info)
-{
- void *mark = NULL, *dummy1 = NULL, *dummy2 = NULL;
-
- if(!p12ctxt || !info) {
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(p12ctxt->arena);
-
- /* if no safeInfos have been set, create the list, otherwise expand it. */
- if(!p12ctxt->safeInfoCount) {
- p12ctxt->safeInfos = (SEC_PKCS12SafeInfo **)PORT_ArenaZAlloc(p12ctxt->arena,
- 2 * sizeof(SEC_PKCS12SafeInfo *));
- dummy1 = p12ctxt->safeInfos;
- p12ctxt->authSafe.encodedSafes = (SECItem **)PORT_ArenaZAlloc(p12ctxt->arena,
- 2 * sizeof(SECItem *));
- dummy2 = p12ctxt->authSafe.encodedSafes;
- } else {
- dummy1 = PORT_ArenaGrow(p12ctxt->arena, p12ctxt->safeInfos,
- (p12ctxt->safeInfoCount + 1) * sizeof(SEC_PKCS12SafeInfo *),
- (p12ctxt->safeInfoCount + 2) * sizeof(SEC_PKCS12SafeInfo *));
- p12ctxt->safeInfos = (SEC_PKCS12SafeInfo **)dummy1;
- dummy2 = PORT_ArenaGrow(p12ctxt->arena, p12ctxt->authSafe.encodedSafes,
- (p12ctxt->authSafe.safeCount + 1) * sizeof(SECItem *),
- (p12ctxt->authSafe.safeCount + 2) * sizeof(SECItem *));
- p12ctxt->authSafe.encodedSafes = (SECItem**)dummy2;
- }
- if(!dummy1 || !dummy2) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* append the new safeInfo and null terminate the list */
- p12ctxt->safeInfos[p12ctxt->safeInfoCount] = info;
- p12ctxt->safeInfos[++p12ctxt->safeInfoCount] = NULL;
- p12ctxt->authSafe.encodedSafes[p12ctxt->authSafe.safeCount] =
- (SECItem*)PORT_ArenaZAlloc(p12ctxt->arena, sizeof(SECItem));
- if(!p12ctxt->authSafe.encodedSafes[p12ctxt->authSafe.safeCount]) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- p12ctxt->authSafe.encodedSafes[++p12ctxt->authSafe.safeCount] = NULL;
-
- PORT_ArenaUnmark(p12ctxt->arena, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(p12ctxt->arena, mark);
- return SECFailure;
-}
-
-/* SEC_PKCS12CreatePasswordPrivSafe
- * Create a password privacy safe to store exported information in.
- *
- * p12ctxt - export context
- * pwitem - password for encryption
- * privAlg - pbe algorithm through which encryption is done.
- */
-SEC_PKCS12SafeInfo *
-SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt,
- SECItem *pwitem, SECOidTag privAlg)
-{
- SEC_PKCS12SafeInfo *safeInfo = NULL;
- void *mark = NULL;
- PK11SlotInfo *slot = NULL;
- SECAlgorithmID *algId;
- SECItem uniPwitem = {siBuffer, NULL, 0};
-
- if(!p12ctxt) {
- return NULL;
- }
-
- /* allocate the safe info */
- mark = PORT_ArenaMark(p12ctxt->arena);
- safeInfo = (SEC_PKCS12SafeInfo *)PORT_ArenaZAlloc(p12ctxt->arena,
- sizeof(SEC_PKCS12SafeInfo));
- if(!safeInfo) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_ArenaRelease(p12ctxt->arena, mark);
- return NULL;
- }
-
- safeInfo->itemCount = 0;
-
- /* create the encrypted safe */
- safeInfo->cinfo = SEC_PKCS7CreateEncryptedData(privAlg, 0, p12ctxt->pwfn,
- p12ctxt->pwfnarg);
- if(!safeInfo->cinfo) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- safeInfo->arena = p12ctxt->arena;
-
- /* convert the password to unicode */
- if(!sec_pkcs12_convert_item_to_unicode(NULL, &uniPwitem, pwitem,
- PR_TRUE, PR_TRUE, PR_TRUE)) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- if(SECITEM_CopyItem(p12ctxt->arena, &safeInfo->pwitem, &uniPwitem) != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* generate the encryption key */
- slot = PK11_ReferenceSlot(p12ctxt->slot);
- if(!slot) {
- slot = PK11_GetInternalKeySlot();
- if(!slot) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- }
-
- algId = SEC_PKCS7GetEncryptionAlgorithm(safeInfo->cinfo);
- safeInfo->encryptionKey = PK11_PBEKeyGen(slot, algId, &uniPwitem,
- PR_FALSE, p12ctxt->wincx);
- if(!safeInfo->encryptionKey) {
- goto loser;
- }
-
- safeInfo->arena = p12ctxt->arena;
- safeInfo->safe = NULL;
- if(sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
- goto loser;
- }
-
- if(uniPwitem.data) {
- SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
- }
- PORT_ArenaUnmark(p12ctxt->arena, mark);
-
- if (slot) {
- PK11_FreeSlot(slot);
- }
- return safeInfo;
-
-loser:
- if (slot) {
- PK11_FreeSlot(slot);
- }
- if(safeInfo->cinfo) {
- SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
- }
-
- if(uniPwitem.data) {
- SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
- }
-
- PORT_ArenaRelease(p12ctxt->arena, mark);
- return NULL;
-}
-
-/* SEC_PKCS12CreateUnencryptedSafe
- * Creates an unencrypted safe within the export context.
- *
- * p12ctxt - the export context
- */
-SEC_PKCS12SafeInfo *
-SEC_PKCS12CreateUnencryptedSafe(SEC_PKCS12ExportContext *p12ctxt)
-{
- SEC_PKCS12SafeInfo *safeInfo = NULL;
- void *mark = NULL;
-
- if(!p12ctxt) {
- return NULL;
- }
-
- /* create the safe info */
- mark = PORT_ArenaMark(p12ctxt->arena);
- safeInfo = (SEC_PKCS12SafeInfo *)PORT_ArenaZAlloc(p12ctxt->arena,
- sizeof(SEC_PKCS12SafeInfo));
- if(!safeInfo) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- safeInfo->itemCount = 0;
-
- /* create the safe content */
- safeInfo->cinfo = SEC_PKCS7CreateData();
- if(!safeInfo->cinfo) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- if(sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
- goto loser;
- }
-
- PORT_ArenaUnmark(p12ctxt->arena, mark);
- return safeInfo;
-
-loser:
- if(safeInfo->cinfo) {
- SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
- }
-
- PORT_ArenaRelease(p12ctxt->arena, mark);
- return NULL;
-}
-
-/* SEC_PKCS12CreatePubKeyEncryptedSafe
- * Creates a safe which is protected by public key encryption.
- *
- * p12ctxt - the export context
- * certDb - the certificate database
- * signer - the signer's certificate
- * recipients - the list of recipient certificates.
- * algorithm - the encryption algorithm to use
- * keysize - the algorithms key size (?)
- */
-SEC_PKCS12SafeInfo *
-SEC_PKCS12CreatePubKeyEncryptedSafe(SEC_PKCS12ExportContext *p12ctxt,
- CERTCertDBHandle *certDb,
- CERTCertificate *signer,
- CERTCertificate **recipients,
- SECOidTag algorithm, int keysize)
-{
- SEC_PKCS12SafeInfo *safeInfo = NULL;
- void *mark = NULL;
-
- if(!p12ctxt || !signer || !recipients || !(*recipients)) {
- return NULL;
- }
-
- /* allocate the safeInfo */
- mark = PORT_ArenaMark(p12ctxt->arena);
- safeInfo = (SEC_PKCS12SafeInfo *)PORT_ArenaZAlloc(p12ctxt->arena,
- sizeof(SEC_PKCS12SafeInfo));
- if(!safeInfo) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- safeInfo->itemCount = 0;
- safeInfo->arena = p12ctxt->arena;
-
- /* create the enveloped content info using certUsageEmailSigner currently.
- * XXX We need to eventually use something other than certUsageEmailSigner
- */
- safeInfo->cinfo = SEC_PKCS7CreateEnvelopedData(signer, certUsageEmailSigner,
- certDb, algorithm, keysize,
- p12ctxt->pwfn, p12ctxt->pwfnarg);
- if(!safeInfo->cinfo) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* add recipients */
- if(recipients) {
- unsigned int i = 0;
- while(recipients[i] != NULL) {
- SECStatus rv = SEC_PKCS7AddRecipient(safeInfo->cinfo, recipients[i],
- certUsageEmailRecipient, certDb);
- if(rv != SECSuccess) {
- goto loser;
- }
- i++;
- }
- }
-
- if(sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
- goto loser;
- }
-
- PORT_ArenaUnmark(p12ctxt->arena, mark);
- return safeInfo;
-
-loser:
- if(safeInfo->cinfo) {
- SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
- safeInfo->cinfo = NULL;
- }
-
- PORT_ArenaRelease(p12ctxt->arena, mark);
- return NULL;
-}
-
-/*********************************
- * Routines to handle the exporting of the keys and certificates
- *********************************/
-
-/* creates a safe contents which safeBags will be appended to */
-sec_PKCS12SafeContents *
-sec_PKCS12CreateSafeContents(PRArenaPool *arena)
-{
- sec_PKCS12SafeContents *safeContents;
-
- if(arena == NULL) {
- return NULL;
- }
-
- /* create the safe contents */
- safeContents = (sec_PKCS12SafeContents *)PORT_ArenaZAlloc(arena,
- sizeof(sec_PKCS12SafeContents));
- if(!safeContents) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* set up the internal contents info */
- safeContents->safeBags = NULL;
- safeContents->arena = arena;
- safeContents->bagCount = 0;
-
- return safeContents;
-
-loser:
- return NULL;
-}
-
-/* appends a safe bag to a safeContents using the specified arena.
- */
-SECStatus
-sec_pkcs12_append_bag_to_safe_contents(PRArenaPool *arena,
- sec_PKCS12SafeContents *safeContents,
- sec_PKCS12SafeBag *safeBag)
-{
- void *mark = NULL, *dummy = NULL;
-
- if(!arena || !safeBag || !safeContents) {
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(arena);
- if(!mark) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- /* allocate space for the list, or reallocate to increase space */
- if(!safeContents->safeBags) {
- safeContents->safeBags = (sec_PKCS12SafeBag **)PORT_ArenaZAlloc(arena,
- (2 * sizeof(sec_PKCS12SafeBag *)));
- dummy = safeContents->safeBags;
- safeContents->bagCount = 0;
- } else {
- dummy = PORT_ArenaGrow(arena, safeContents->safeBags,
- (safeContents->bagCount + 1) * sizeof(sec_PKCS12SafeBag *),
- (safeContents->bagCount + 2) * sizeof(sec_PKCS12SafeBag *));
- safeContents->safeBags = (sec_PKCS12SafeBag **)dummy;
- }
-
- if(!dummy) {
- PORT_ArenaRelease(arena, mark);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- /* append the bag at the end and null terminate the list */
- safeContents->safeBags[safeContents->bagCount++] = safeBag;
- safeContents->safeBags[safeContents->bagCount] = NULL;
-
- PORT_ArenaUnmark(arena, mark);
-
- return SECSuccess;
-}
-
-/* appends a safeBag to a specific safeInfo.
- */
-SECStatus
-sec_pkcs12_append_bag(SEC_PKCS12ExportContext *p12ctxt,
- SEC_PKCS12SafeInfo *safeInfo, sec_PKCS12SafeBag *safeBag)
-{
- sec_PKCS12SafeContents *dest;
- SECStatus rv = SECFailure;
-
- if(!p12ctxt || !safeBag || !safeInfo) {
- return SECFailure;
- }
-
- if(!safeInfo->safe) {
- safeInfo->safe = sec_PKCS12CreateSafeContents(p12ctxt->arena);
- if(!safeInfo->safe) {
- return SECFailure;
- }
- }
-
- dest = safeInfo->safe;
- rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena, dest, safeBag);
- if(rv == SECSuccess) {
- safeInfo->itemCount++;
- }
-
- return rv;
-}
-
-/* Creates a safeBag of the specified type, and if bagData is specified,
- * the contents are set. The contents could be set later by the calling
- * routine.
- */
-sec_PKCS12SafeBag *
-sec_PKCS12CreateSafeBag(SEC_PKCS12ExportContext *p12ctxt, SECOidTag bagType,
- void *bagData)
-{
- sec_PKCS12SafeBag *safeBag;
- PRBool setName = PR_TRUE;
- void *mark = NULL;
- SECStatus rv = SECSuccess;
- SECOidData *oidData = NULL;
-
- if(!p12ctxt) {
- return NULL;
- }
-
- mark = PORT_ArenaMark(p12ctxt->arena);
- if(!mark) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- safeBag = (sec_PKCS12SafeBag *)PORT_ArenaZAlloc(p12ctxt->arena,
- sizeof(sec_PKCS12SafeBag));
- if(!safeBag) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- /* set the bags content based upon bag type */
- switch(bagType) {
- case SEC_OID_PKCS12_V1_KEY_BAG_ID:
- safeBag->safeBagContent.pkcs8KeyBag =
- (SECKEYPrivateKeyInfo *)bagData;
- break;
- case SEC_OID_PKCS12_V1_CERT_BAG_ID:
- safeBag->safeBagContent.certBag = (sec_PKCS12CertBag *)bagData;
- break;
- case SEC_OID_PKCS12_V1_CRL_BAG_ID:
- safeBag->safeBagContent.crlBag = (sec_PKCS12CRLBag *)bagData;
- break;
- case SEC_OID_PKCS12_V1_SECRET_BAG_ID:
- safeBag->safeBagContent.secretBag = (sec_PKCS12SecretBag *)bagData;
- break;
- case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
- safeBag->safeBagContent.pkcs8ShroudedKeyBag =
- (SECKEYEncryptedPrivateKeyInfo *)bagData;
- break;
- case SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID:
- safeBag->safeBagContent.safeContents =
- (sec_PKCS12SafeContents *)bagData;
- setName = PR_FALSE;
- break;
- default:
- goto loser;
- }
-
- oidData = SECOID_FindOIDByTag(bagType);
- if(oidData) {
- rv = SECITEM_CopyItem(p12ctxt->arena, &safeBag->safeBagType, &oidData->oid);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- } else {
- goto loser;
- }
-
- safeBag->arena = p12ctxt->arena;
- PORT_ArenaUnmark(p12ctxt->arena, mark);
-
- return safeBag;
-
-loser:
- if(mark) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- }
-
- return NULL;
-}
-
-/* Creates a new certificate bag and returns a pointer to it. If an error
- * occurs NULL is returned.
- */
-sec_PKCS12CertBag *
-sec_PKCS12NewCertBag(PRArenaPool *arena, SECOidTag certType)
-{
- sec_PKCS12CertBag *certBag = NULL;
- SECOidData *bagType = NULL;
- SECStatus rv;
- void *mark = NULL;
-
- if(!arena) {
- return NULL;
- }
-
- mark = PORT_ArenaMark(arena);
- certBag = (sec_PKCS12CertBag *)PORT_ArenaZAlloc(arena,
- sizeof(sec_PKCS12CertBag));
- if(!certBag) {
- PORT_ArenaRelease(arena, mark);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- bagType = SECOID_FindOIDByTag(certType);
- if(!bagType) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- rv = SECITEM_CopyItem(arena, &certBag->bagID, &bagType->oid);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- PORT_ArenaUnmark(arena, mark);
- return certBag;
-
-loser:
- PORT_ArenaRelease(arena, mark);
- return NULL;
-}
-
-/* Creates a new CRL bag and returns a pointer to it. If an error
- * occurs NULL is returned.
- */
-sec_PKCS12CRLBag *
-sec_PKCS12NewCRLBag(PRArenaPool *arena, SECOidTag crlType)
-{
- sec_PKCS12CRLBag *crlBag = NULL;
- SECOidData *bagType = NULL;
- SECStatus rv;
- void *mark = NULL;
-
- if(!arena) {
- return NULL;
- }
-
- mark = PORT_ArenaMark(arena);
- crlBag = (sec_PKCS12CRLBag *)PORT_ArenaZAlloc(arena,
- sizeof(sec_PKCS12CRLBag));
- if(!crlBag) {
- PORT_ArenaRelease(arena, mark);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- bagType = SECOID_FindOIDByTag(crlType);
- if(!bagType) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- rv = SECITEM_CopyItem(arena, &crlBag->bagID, &bagType->oid);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- PORT_ArenaUnmark(arena, mark);
- return crlBag;
-
-loser:
- PORT_ArenaRelease(arena, mark);
- return NULL;
-}
-
-/* sec_PKCS12AddAttributeToBag
- * adds an attribute to a safeBag. currently, the only attributes supported
- * are those which are specified within PKCS 12.
- *
- * p12ctxt - the export context
- * safeBag - the safeBag to which attributes are appended
- * attrType - the attribute type
- * attrData - the attribute data
- */
-SECStatus
-sec_PKCS12AddAttributeToBag(SEC_PKCS12ExportContext *p12ctxt,
- sec_PKCS12SafeBag *safeBag, SECOidTag attrType,
- SECItem *attrData)
-{
- sec_PKCS12Attribute *attribute;
- void *mark = NULL, *dummy = NULL;
- SECOidData *oiddata = NULL;
- SECItem unicodeName = { siBuffer, NULL, 0};
- void *src = NULL;
- unsigned int nItems = 0;
- SECStatus rv;
-
- if(!safeBag || !p12ctxt) {
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(safeBag->arena);
-
- /* allocate the attribute */
- attribute = (sec_PKCS12Attribute *)PORT_ArenaZAlloc(safeBag->arena,
- sizeof(sec_PKCS12Attribute));
- if(!attribute) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* set up the attribute */
- oiddata = SECOID_FindOIDByTag(attrType);
- if(!oiddata) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- if(SECITEM_CopyItem(p12ctxt->arena, &attribute->attrType, &oiddata->oid) !=
- SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- nItems = 1;
- switch(attrType) {
- case SEC_OID_PKCS9_LOCAL_KEY_ID:
- {
- src = attrData;
- break;
- }
- case SEC_OID_PKCS9_FRIENDLY_NAME:
- {
- if(!sec_pkcs12_convert_item_to_unicode(p12ctxt->arena,
- &unicodeName, attrData, PR_FALSE,
- PR_FALSE, PR_TRUE)) {
- goto loser;
- }
- src = &unicodeName;
- break;
- }
- default:
- goto loser;
- }
-
- /* append the attribute to the attribute value list */
- attribute->attrValue = (SECItem **)PORT_ArenaZAlloc(p12ctxt->arena,
- ((nItems + 1) * sizeof(SECItem *)));
- if(!attribute->attrValue) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* XXX this will need to be changed if attributes requiring more than
- * one element are ever used.
- */
- attribute->attrValue[0] = (SECItem *)PORT_ArenaZAlloc(p12ctxt->arena,
- sizeof(SECItem));
- if(!attribute->attrValue[0]) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- attribute->attrValue[1] = NULL;
-
- rv = SECITEM_CopyItem(p12ctxt->arena, attribute->attrValue[0],
- (SECItem*)src);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* append the attribute to the safeBag attributes */
- if(safeBag->nAttribs) {
- dummy = PORT_ArenaGrow(p12ctxt->arena, safeBag->attribs,
- ((safeBag->nAttribs + 1) * sizeof(sec_PKCS12Attribute *)),
- ((safeBag->nAttribs + 2) * sizeof(sec_PKCS12Attribute *)));
- safeBag->attribs = (sec_PKCS12Attribute **)dummy;
- } else {
- safeBag->attribs = (sec_PKCS12Attribute **)PORT_ArenaZAlloc(p12ctxt->arena,
- 2 * sizeof(sec_PKCS12Attribute *));
- dummy = safeBag->attribs;
- }
- if(!dummy) {
- goto loser;
- }
-
- safeBag->attribs[safeBag->nAttribs] = attribute;
- safeBag->attribs[++safeBag->nAttribs] = NULL;
-
- PORT_ArenaUnmark(p12ctxt->arena, mark);
- return SECSuccess;
-
-loser:
- if(mark) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- }
-
- return SECFailure;
-}
-
-/* SEC_PKCS12AddCert
- * Adds a certificate to the data being exported.
- *
- * p12ctxt - the export context
- * safe - the safeInfo to which the certificate is placed
- * nestedDest - if the cert is to be placed within a nested safeContents then,
- * this value is to be specified with the destination
- * cert - the cert to export
- * certDb - the certificate database handle
- * keyId - a unique identifier to associate a certificate/key pair
- * includeCertChain - PR_TRUE if the certificate chain is to be included.
- */
-SECStatus
-SEC_PKCS12AddCert(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *safe,
- void *nestedDest, CERTCertificate *cert,
- CERTCertDBHandle *certDb, SECItem *keyId,
- PRBool includeCertChain)
-{
- sec_PKCS12CertBag *certBag;
- sec_PKCS12SafeBag *safeBag;
- void *mark;
- SECStatus rv;
- SECItem nick = {siBuffer, NULL,0};
-
- if(!p12ctxt || !cert) {
- return SECFailure;
- }
- mark = PORT_ArenaMark(p12ctxt->arena);
-
- /* allocate the cert bag */
- certBag = sec_PKCS12NewCertBag(p12ctxt->arena,
- SEC_OID_PKCS9_X509_CERT);
- if(!certBag) {
- goto loser;
- }
-
- if(SECITEM_CopyItem(p12ctxt->arena, &certBag->value.x509Cert,
- &cert->derCert) != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* if the cert chain is to be included, we should only be exporting
- * the cert from our internal database.
- */
- if(includeCertChain) {
- CERTCertificateList *certList = CERT_CertChainFromCert(cert,
- certUsageSSLClient,
- PR_TRUE);
- unsigned int count = 0;
- if(!certList) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* add cert chain */
- for(count = 0; count < (unsigned int)certList->len; count++) {
- if(SECITEM_CompareItem(&certList->certs[count], &cert->derCert)
- != SECEqual) {
- CERTCertificate *tempCert;
-
- /* decode the certificate */
- /* XXX
- * This was rather silly. The chain is constructed above
- * by finding all of the CERTCertificate's in the database.
- * Then the chain is put into a CERTCertificateList, which only
- * contains the DER. Finally, the DER was decoded, and the
- * decoded cert was sent recursively back to this function.
- * Beyond being inefficent, this causes data loss (specifically,
- * the nickname). Instead, for 3.4, we'll do a lookup by the
- * DER, which should return the cached entry.
- */
- tempCert = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),
- &certList->certs[count]);
- if(!tempCert) {
- CERT_DestroyCertificateList(certList);
- goto loser;
- }
-
- /* add the certificate */
- if(SEC_PKCS12AddCert(p12ctxt, safe, nestedDest, tempCert,
- certDb, NULL, PR_FALSE) != SECSuccess) {
- CERT_DestroyCertificate(tempCert);
- CERT_DestroyCertificateList(certList);
- goto loser;
- }
- CERT_DestroyCertificate(tempCert);
- }
- }
- CERT_DestroyCertificateList(certList);
- }
-
- /* if the certificate has a nickname, we will set the friendly name
- * to that.
- */
- if(cert->nickname) {
- if (cert->slot && !PK11_IsInternal(cert->slot)) {
- /*
- * The cert is coming off of an external token,
- * let's strip the token name from the nickname
- * and only add what comes after the colon as the
- * nickname. -javi
- */
- char *delimit;
-
- delimit = PORT_Strchr(cert->nickname,':');
- if (delimit == NULL) {
- nick.data = (unsigned char *)cert->nickname;
- nick.len = PORT_Strlen(cert->nickname);
- } else {
- delimit++;
- nick.data = (unsigned char *)PORT_ArenaStrdup(p12ctxt->arena,
- delimit);
- nick.len = PORT_Strlen(delimit);
- }
- } else {
- nick.data = (unsigned char *)cert->nickname;
- nick.len = PORT_Strlen(cert->nickname);
- }
- }
-
- safeBag = sec_PKCS12CreateSafeBag(p12ctxt, SEC_OID_PKCS12_V1_CERT_BAG_ID,
- certBag);
- if(!safeBag) {
- goto loser;
- }
-
- /* add the friendly name and keyId attributes, if necessary */
- if(nick.data) {
- if(sec_PKCS12AddAttributeToBag(p12ctxt, safeBag,
- SEC_OID_PKCS9_FRIENDLY_NAME, &nick)
- != SECSuccess) {
- goto loser;
- }
- }
-
- if(keyId) {
- if(sec_PKCS12AddAttributeToBag(p12ctxt, safeBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
- keyId) != SECSuccess) {
- goto loser;
- }
- }
-
- /* append the cert safeBag */
- if(nestedDest) {
- rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena,
- (sec_PKCS12SafeContents*)nestedDest,
- safeBag);
- } else {
- rv = sec_pkcs12_append_bag(p12ctxt, safe, safeBag);
- }
-
- if(rv != SECSuccess) {
- goto loser;
- }
-
- PORT_ArenaUnmark(p12ctxt->arena, mark);
- return SECSuccess;
-
-loser:
- if(mark) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- }
-
- return SECFailure;
-}
-
-/* SEC_PKCS12AddKeyForCert
- * Extracts the key associated with a particular certificate and exports
- * it.
- *
- * p12ctxt - the export context
- * safe - the safeInfo to place the key in
- * nestedDest - the nested safeContents to place a key
- * cert - the certificate which the key belongs to
- * shroudKey - encrypt the private key for export. This value should
- * always be true. lower level code will not allow the export
- * of unencrypted private keys.
- * algorithm - the algorithm with which to encrypt the private key
- * pwitem - the password to encrypt the private key with
- * keyId - the keyID attribute
- * nickName - the nickname attribute
- */
-SECStatus
-SEC_PKCS12AddKeyForCert(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *safe,
- void *nestedDest, CERTCertificate *cert,
- PRBool shroudKey, SECOidTag algorithm, SECItem *pwitem,
- SECItem *keyId, SECItem *nickName)
-{
- void *mark;
- void *keyItem;
- SECOidTag keyType;
- SECStatus rv = SECFailure;
- SECItem nickname = {siBuffer,NULL,0}, uniPwitem = {siBuffer, NULL, 0};
- sec_PKCS12SafeBag *returnBag;
-
- if(!p12ctxt || !cert || !safe) {
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(p12ctxt->arena);
-
- /* retrieve the key based upon the type that it is and
- * specify the type of safeBag to store the key in
- */
- if(!shroudKey) {
-
- /* extract the key unencrypted. this will most likely go away */
- SECKEYPrivateKeyInfo *pki = PK11_ExportPrivateKeyInfo(cert,
- p12ctxt->wincx);
- if(!pki) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY);
- return SECFailure;
- }
- keyItem = PORT_ArenaZAlloc(p12ctxt->arena, sizeof(SECKEYPrivateKeyInfo));
- if(!keyItem) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- rv = SECKEY_CopyPrivateKeyInfo(p12ctxt->arena,
- (SECKEYPrivateKeyInfo *)keyItem, pki);
- keyType = SEC_OID_PKCS12_V1_KEY_BAG_ID;
- SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE);
- } else {
-
- /* extract the key encrypted */
- SECKEYEncryptedPrivateKeyInfo *epki = NULL;
- PK11SlotInfo *slot = NULL;
-
- if(!sec_pkcs12_convert_item_to_unicode(p12ctxt->arena, &uniPwitem,
- pwitem, PR_TRUE, PR_TRUE, PR_TRUE)) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* we want to make sure to take the key out of the key slot */
- if(PK11_IsInternal(p12ctxt->slot)) {
- slot = PK11_GetInternalKeySlot();
- } else {
- slot = PK11_ReferenceSlot(p12ctxt->slot);
- }
-
- epki = PK11_ExportEncryptedPrivateKeyInfo(slot, algorithm,
- &uniPwitem, cert,
- NSS_PBE_DEFAULT_ITERATION_COUNT,
- p12ctxt->wincx);
- PK11_FreeSlot(slot);
- if(!epki) {
- PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY);
- goto loser;
- }
-
- keyItem = PORT_ArenaZAlloc(p12ctxt->arena,
- sizeof(SECKEYEncryptedPrivateKeyInfo));
- if(!keyItem) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- rv = SECKEY_CopyEncryptedPrivateKeyInfo(p12ctxt->arena,
- (SECKEYEncryptedPrivateKeyInfo *)keyItem,
- epki);
- keyType = SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID;
- SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE);
- }
-
- if(rv != SECSuccess) {
- goto loser;
- }
-
- /* if no nickname specified, let's see if the certificate has a
- * nickname.
- */
- if(!nickName) {
- if(cert->nickname) {
- nickname.data = (unsigned char *)cert->nickname;
- nickname.len = PORT_Strlen(cert->nickname);
- nickName = &nickname;
- }
- }
-
- /* create the safe bag and set any attributes */
- returnBag = sec_PKCS12CreateSafeBag(p12ctxt, keyType, keyItem);
- if(!returnBag) {
- rv = SECFailure;
- goto loser;
- }
-
- if(nickName) {
- if(sec_PKCS12AddAttributeToBag(p12ctxt, returnBag,
- SEC_OID_PKCS9_FRIENDLY_NAME, nickName)
- != SECSuccess) {
- goto loser;
- }
- }
-
- if(keyId) {
- if(sec_PKCS12AddAttributeToBag(p12ctxt, returnBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
- keyId) != SECSuccess) {
- goto loser;
- }
- }
-
- if(nestedDest) {
- rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena,
- (sec_PKCS12SafeContents*)nestedDest,
- returnBag);
- } else {
- rv = sec_pkcs12_append_bag(p12ctxt, safe, returnBag);
- }
-
-loser:
-
- if (rv != SECSuccess) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- } else {
- PORT_ArenaUnmark(p12ctxt->arena, mark);
- }
-
- return rv;
-}
-
-/* SEC_PKCS12AddCertOrChainAndKey
- * Add a certificate and key pair to be exported.
- *
- * p12ctxt - the export context
- * certSafe - the safeInfo where the cert is stored
- * certNestedDest - the nested safeContents to store the cert
- * keySafe - the safeInfo where the key is stored
- * keyNestedDest - the nested safeContents to store the key
- * shroudKey - extract the private key encrypted?
- * pwitem - the password with which the key is encrypted
- * algorithm - the algorithm with which the key is encrypted
- * includeCertChain - also add certs from chain to bag.
- */
-SECStatus
-SEC_PKCS12AddCertOrChainAndKey(SEC_PKCS12ExportContext *p12ctxt,
- void *certSafe, void *certNestedDest,
- CERTCertificate *cert, CERTCertDBHandle *certDb,
- void *keySafe, void *keyNestedDest,
- PRBool shroudKey, SECItem *pwitem,
- SECOidTag algorithm, PRBool includeCertChain)
-{
- SECStatus rv = SECFailure;
- SGNDigestInfo *digest = NULL;
- void *mark = NULL;
-
- if(!p12ctxt || !certSafe || !keySafe || !cert) {
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(p12ctxt->arena);
-
- /* generate the thumbprint of the cert to use as a keyId */
- digest = sec_pkcs12_compute_thumbprint(&cert->derCert);
- if(!digest) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- return SECFailure;
- }
-
- /* add the certificate */
- rv = SEC_PKCS12AddCert(p12ctxt, (SEC_PKCS12SafeInfo*)certSafe,
- (SEC_PKCS12SafeInfo*)certNestedDest, cert, certDb,
- &digest->digest, includeCertChain);
- if(rv != SECSuccess) {
- goto loser;
- }
-
- /* add the key */
- rv = SEC_PKCS12AddKeyForCert(p12ctxt, (SEC_PKCS12SafeInfo*)keySafe,
- keyNestedDest, cert,
- shroudKey, algorithm, pwitem,
- &digest->digest, NULL );
- if(rv != SECSuccess) {
- goto loser;
- }
-
- SGN_DestroyDigestInfo(digest);
-
- PORT_ArenaUnmark(p12ctxt->arena, mark);
- return SECSuccess;
-
-loser:
- SGN_DestroyDigestInfo(digest);
- PORT_ArenaRelease(p12ctxt->arena, mark);
-
- return SECFailure;
-}
-
-/* like SEC_PKCS12AddCertOrChainAndKey, but always adds cert chain */
-SECStatus
-SEC_PKCS12AddCertAndKey(SEC_PKCS12ExportContext *p12ctxt,
- void *certSafe, void *certNestedDest,
- CERTCertificate *cert, CERTCertDBHandle *certDb,
- void *keySafe, void *keyNestedDest,
- PRBool shroudKey, SECItem *pwItem, SECOidTag algorithm)
-{
- return SEC_PKCS12AddCertOrChainAndKey(p12ctxt, certSafe, certNestedDest,
- cert, certDb, keySafe, keyNestedDest, shroudKey, pwItem,
- algorithm, PR_TRUE);
-}
-
-
-/* SEC_PKCS12CreateNestedSafeContents
- * Allows nesting of safe contents to be implemented. No limit imposed on
- * depth.
- *
- * p12ctxt - the export context
- * baseSafe - the base safeInfo
- * nestedDest - a parent safeContents (?)
- */
-void *
-SEC_PKCS12CreateNestedSafeContents(SEC_PKCS12ExportContext *p12ctxt,
- void *baseSafe, void *nestedDest)
-{
- sec_PKCS12SafeContents *newSafe;
- sec_PKCS12SafeBag *safeContentsBag;
- void *mark;
- SECStatus rv;
-
- if(!p12ctxt || !baseSafe) {
- return NULL;
- }
-
- mark = PORT_ArenaMark(p12ctxt->arena);
-
- newSafe = sec_PKCS12CreateSafeContents(p12ctxt->arena);
- if(!newSafe) {
- PORT_ArenaRelease(p12ctxt->arena, mark);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- /* create the safeContents safeBag */
- safeContentsBag = sec_PKCS12CreateSafeBag(p12ctxt,
- SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID,
- newSafe);
- if(!safeContentsBag) {
- goto loser;
- }
-
- /* append the safeContents to the appropriate area */
- if(nestedDest) {
- rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena,
- (sec_PKCS12SafeContents*)nestedDest,
- safeContentsBag);
- } else {
- rv = sec_pkcs12_append_bag(p12ctxt, (SEC_PKCS12SafeInfo*)baseSafe,
- safeContentsBag);
- }
- if(rv != SECSuccess) {
- goto loser;
- }
-
- PORT_ArenaUnmark(p12ctxt->arena, mark);
- return newSafe;
-
-loser:
- PORT_ArenaRelease(p12ctxt->arena, mark);
- return NULL;
-}
-
-/*********************************
- * Encoding routines
- *********************************/
-
-/* Clean up the resources allocated by a sec_PKCS12EncoderContext. */
-static void
-sec_pkcs12_encoder_destroy_context(sec_PKCS12EncoderContext *p12enc)
-{
- if(p12enc) {
- if(p12enc->outerA1ecx) {
- SEC_ASN1EncoderFinish(p12enc->outerA1ecx);
- p12enc->outerA1ecx = NULL;
- }
- if(p12enc->aSafeCinfo) {
- SEC_PKCS7DestroyContentInfo(p12enc->aSafeCinfo);
- p12enc->aSafeCinfo = NULL;
- }
- if(p12enc->middleP7ecx) {
- SEC_PKCS7EncoderFinish(p12enc->middleP7ecx, p12enc->p12exp->pwfn,
- p12enc->p12exp->pwfnarg);
- p12enc->middleP7ecx = NULL;
- }
- if(p12enc->middleA1ecx) {
- SEC_ASN1EncoderFinish(p12enc->middleA1ecx);
- p12enc->middleA1ecx = NULL;
- }
- if(p12enc->hmacCx) {
- PK11_DestroyContext(p12enc->hmacCx, PR_TRUE);
- p12enc->hmacCx = NULL;
- }
- }
-}
-
-/* set up the encoder context based on information in the export context
- * and return the newly allocated enocoder context. A return of NULL
- * indicates an error occurred.
- */
-static sec_PKCS12EncoderContext *
-sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
-{
- sec_PKCS12EncoderContext *p12enc = NULL;
- unsigned int i, nonEmptyCnt;
- SECStatus rv;
- SECItem ignore = {0};
- void *mark;
-
- if(!p12exp || !p12exp->safeInfos) {
- return NULL;
- }
-
- /* check for any empty safes and skip them */
- i = nonEmptyCnt = 0;
- while(p12exp->safeInfos[i]) {
- if(p12exp->safeInfos[i]->itemCount) {
- nonEmptyCnt++;
- }
- i++;
- }
- if(nonEmptyCnt == 0) {
- return NULL;
- }
- p12exp->authSafe.encodedSafes[nonEmptyCnt] = NULL;
-
- /* allocate the encoder context */
- mark = PORT_ArenaMark(p12exp->arena);
- p12enc = PORT_ArenaZNew(p12exp->arena, sec_PKCS12EncoderContext);
- if(!p12enc) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- p12enc->arena = p12exp->arena;
- p12enc->p12exp = p12exp;
-
- /* set up the PFX version and information */
- PORT_Memset(&p12enc->pfx, 0, sizeof(sec_PKCS12PFXItem));
- if(!SEC_ASN1EncodeInteger(p12exp->arena, &(p12enc->pfx.version),
- SEC_PKCS12_VERSION) ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* set up the authenticated safe content info based on the
- * type of integrity being used. this should be changed to
- * enforce integrity mode, but will not be implemented until
- * it is confirmed that integrity must be in place
- */
- if(p12exp->integrityEnabled && !p12exp->pwdIntegrity) {
- SECStatus rv;
-
- /* create public key integrity mode */
- p12enc->aSafeCinfo = SEC_PKCS7CreateSignedData(
- p12exp->integrityInfo.pubkeyInfo.cert,
- certUsageEmailSigner,
- p12exp->integrityInfo.pubkeyInfo.certDb,
- p12exp->integrityInfo.pubkeyInfo.algorithm,
- NULL,
- p12exp->pwfn,
- p12exp->pwfnarg);
- if(!p12enc->aSafeCinfo) {
- goto loser;
- }
- if(SEC_PKCS7IncludeCertChain(p12enc->aSafeCinfo,NULL) != SECSuccess) {
- goto loser;
- }
- rv = SEC_PKCS7AddSigningTime(p12enc->aSafeCinfo);
- PORT_Assert(rv == SECSuccess);
- } else {
- p12enc->aSafeCinfo = SEC_PKCS7CreateData();
-
- /* init password pased integrity mode */
- if(p12exp->integrityEnabled) {
- SECItem pwd = {siBuffer,NULL, 0};
- SECItem *salt = sec_pkcs12_generate_salt();
- PK11SymKey *symKey;
- SECItem *params;
- CK_MECHANISM_TYPE integrityMechType;
- CK_MECHANISM_TYPE hmacMechType;
-
- /* zero out macData and set values */
- PORT_Memset(&p12enc->mac, 0, sizeof(sec_PKCS12MacData));
-
- if(!salt) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- if(SECITEM_CopyItem(p12exp->arena, &(p12enc->mac.macSalt), salt)
- != SECSuccess) {
- /* XXX salt is leaked */
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- if (!SEC_ASN1EncodeInteger(p12exp->arena, &(p12enc->mac.iter),
- NSS_PBE_DEFAULT_ITERATION_COUNT)) {
- /* XXX salt is leaked */
- goto loser;
- }
-
- /* generate HMAC key */
- if(!sec_pkcs12_convert_item_to_unicode(NULL, &pwd,
- p12exp->integrityInfo.pwdInfo.password, PR_TRUE,
- PR_TRUE, PR_TRUE)) {
- /* XXX salt is leaked */
- goto loser;
- }
- /*
- * This code only works with PKCS #12 Mac using PKCS #5 v1
- * PBA keygens. PKCS #5 v2 support will require a change to
- * the PKCS #12 spec.
- */
- params = PK11_CreatePBEParams(salt, &pwd,
- NSS_PBE_DEFAULT_ITERATION_COUNT);
- SECITEM_ZfreeItem(salt, PR_TRUE);
- SECITEM_ZfreeItem(&pwd, PR_FALSE);
-
- /* get the PBA Mechanism to generate the key */
- switch (p12exp->integrityInfo.pwdInfo.algorithm) {
- case SEC_OID_SHA1:
- integrityMechType = CKM_PBA_SHA1_WITH_SHA1_HMAC; break;
- case SEC_OID_MD5:
- integrityMechType = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break;
- case SEC_OID_MD2:
- integrityMechType = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break;
- default:
- /* XXX params is leaked */
- goto loser;
- }
-
- /* generate the key */
- symKey = PK11_KeyGen(NULL, integrityMechType, params, 20, NULL);
- PK11_DestroyPBEParams(params);
- if(!symKey) {
- goto loser;
- }
-
- /* initialize HMAC */
- /* Get the HMAC mechanism from the hash OID */
- hmacMechType= sec_pkcs12_algtag_to_mech(
- p12exp->integrityInfo.pwdInfo.algorithm);
-
- p12enc->hmacCx = PK11_CreateContextBySymKey( hmacMechType,
- CKA_SIGN, symKey, &ignore);
-
- PK11_FreeSymKey(symKey);
- if(!p12enc->hmacCx) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- rv = PK11_DigestBegin(p12enc->hmacCx);
- if (rv != SECSuccess)
- goto loser;
- }
- }
-
- if(!p12enc->aSafeCinfo) {
- goto loser;
- }
-
- PORT_ArenaUnmark(p12exp->arena, mark);
-
- return p12enc;
-
-loser:
- sec_pkcs12_encoder_destroy_context(p12enc);
- if (p12exp->arena != NULL)
- PORT_ArenaRelease(p12exp->arena, mark);
-
- return NULL;
-}
-
-/* The outermost ASN.1 encoder calls this function for output.
-** This function calls back to the library caller's output routine,
-** which typically writes to a PKCS12 file.
- */
-static void
-sec_P12A1OutputCB_Outer(void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
-{
- struct sec_pkcs12_encoder_output *output;
-
- output = (struct sec_pkcs12_encoder_output*)arg;
- (* output->outputfn)(output->outputarg, buf, len);
-}
-
-/* The "middle" and "inner" ASN.1 encoders call this function to output.
-** This function does HMACing, if appropriate, and then buffers the data.
-** The buffered data is eventually passed down to the underlying PKCS7 encoder.
- */
-static void
-sec_P12A1OutputCB_HmacP7Update(void *arg, const char *buf,
- unsigned long len,
- int depth,
- SEC_ASN1EncodingPart data_kind)
-{
- sec_pkcs12OutputBuffer * bufcx = (sec_pkcs12OutputBuffer *)arg;
-
- if(!buf || !len)
- return;
-
- if (bufcx->hmacCx) {
- PK11_DigestOp(bufcx->hmacCx, (unsigned char *)buf, len);
- }
-
- /* buffer */
- if (bufcx->numBytes > 0) {
- int toCopy;
- if (len + bufcx->numBytes <= bufcx->bufBytes) {
- memcpy(bufcx->buf + bufcx->numBytes, buf, len);
- bufcx->numBytes += len;
- if (bufcx->numBytes < bufcx->bufBytes)
- return;
- SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->bufBytes);
- bufcx->numBytes = 0;
- return;
- }
- toCopy = bufcx->bufBytes - bufcx->numBytes;
- memcpy(bufcx->buf + bufcx->numBytes, buf, toCopy);
- SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->bufBytes);
- bufcx->numBytes = 0;
- len -= toCopy;
- buf += toCopy;
- }
- /* buffer is presently empty */
- if (len >= bufcx->bufBytes) {
- /* Just pass it through */
- SEC_PKCS7EncoderUpdate(bufcx->p7eCx, buf, len);
- } else {
- /* copy it all into the buffer, and return */
- memcpy(bufcx->buf, buf, len);
- bufcx->numBytes = len;
- }
-}
-
-void
-sec_FlushPkcs12OutputBuffer( sec_pkcs12OutputBuffer * bufcx)
-{
- if (bufcx->numBytes > 0) {
- SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->numBytes);
- bufcx->numBytes = 0;
- }
-}
-
-/* Feeds the output of a PKCS7 encoder into the next outward ASN.1 encoder.
-** This function is used by both the inner and middle PCS7 encoders.
-*/
-static void
-sec_P12P7OutputCB_CallA1Update(void *arg, const char *buf, unsigned long len)
-{
- SEC_ASN1EncoderContext *cx = (SEC_ASN1EncoderContext*)arg;
-
- if (!buf || !len)
- return;
-
- SEC_ASN1EncoderUpdate(cx, buf, len);
-}
-
-
-/* this function encodes content infos which are part of the
- * sequence of content infos labeled AuthenticatedSafes
- */
-static SECStatus
-sec_pkcs12_encoder_asafe_process(sec_PKCS12EncoderContext *p12ecx)
-{
- SEC_PKCS7EncoderContext *innerP7ecx;
- SEC_PKCS7ContentInfo *cinfo;
- PK11SymKey *bulkKey = NULL;
- SEC_ASN1EncoderContext *innerA1ecx = NULL;
- SECStatus rv = SECSuccess;
-
- if(p12ecx->currentSafe < p12ecx->p12exp->authSafe.safeCount) {
- SEC_PKCS12SafeInfo *safeInfo;
- SECOidTag cinfoType;
-
- safeInfo = p12ecx->p12exp->safeInfos[p12ecx->currentSafe];
-
- /* skip empty safes */
- if(safeInfo->itemCount == 0) {
- return SECSuccess;
- }
-
- cinfo = safeInfo->cinfo;
- cinfoType = SEC_PKCS7ContentType(cinfo);
-
- /* determine the safe type and set the appropriate argument */
- switch(cinfoType) {
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- bulkKey = safeInfo->encryptionKey;
- PK11_SetSymKeyUserData(bulkKey, &safeInfo->pwitem, NULL);
- break;
- default:
- return SECFailure;
-
- }
-
- /* start the PKCS7 encoder */
- innerP7ecx = SEC_PKCS7EncoderStart(cinfo,
- sec_P12P7OutputCB_CallA1Update,
- p12ecx->middleA1ecx, bulkKey);
- if(!innerP7ecx) {
- goto loser;
- }
-
- /* encode safe contents */
- p12ecx->innerBuf.p7eCx = innerP7ecx;
- p12ecx->innerBuf.hmacCx = NULL;
- p12ecx->innerBuf.numBytes = 0;
- p12ecx->innerBuf.bufBytes = sizeof p12ecx->innerBuf.buf;
-
- innerA1ecx = SEC_ASN1EncoderStart(safeInfo->safe,
- sec_PKCS12SafeContentsTemplate,
- sec_P12A1OutputCB_HmacP7Update,
- &p12ecx->innerBuf);
- if(!innerA1ecx) {
- goto loser;
- }
- rv = SEC_ASN1EncoderUpdate(innerA1ecx, NULL, 0);
- SEC_ASN1EncoderFinish(innerA1ecx);
- sec_FlushPkcs12OutputBuffer( &p12ecx->innerBuf);
- innerA1ecx = NULL;
- if(rv != SECSuccess) {
- goto loser;
- }
-
-
- /* finish up safe content info */
- rv = SEC_PKCS7EncoderFinish(innerP7ecx, p12ecx->p12exp->pwfn,
- p12ecx->p12exp->pwfnarg);
- }
- memset(&p12ecx->innerBuf, 0, sizeof p12ecx->innerBuf);
- return SECSuccess;
-
-loser:
- if(innerP7ecx) {
- SEC_PKCS7EncoderFinish(innerP7ecx, p12ecx->p12exp->pwfn,
- p12ecx->p12exp->pwfnarg);
- }
-
- if(innerA1ecx) {
- SEC_ASN1EncoderFinish(innerA1ecx);
- }
- memset(&p12ecx->innerBuf, 0, sizeof p12ecx->innerBuf);
- return SECFailure;
-}
-
-/* finish the HMAC and encode the macData so that it can be
- * encoded.
- */
-static SECStatus
-sec_Pkcs12FinishMac(sec_PKCS12EncoderContext *p12ecx)
-{
- SECItem hmac = { siBuffer, NULL, 0 };
- SECStatus rv;
- SGNDigestInfo *di = NULL;
- void *dummy;
-
- if(!p12ecx) {
- return SECFailure;
- }
-
- /* make sure we are using password integrity mode */
- if(!p12ecx->p12exp->integrityEnabled) {
- return SECSuccess;
- }
-
- if(!p12ecx->p12exp->pwdIntegrity) {
- return SECSuccess;
- }
-
- /* finish the hmac */
- hmac.data = (unsigned char *)PORT_ZAlloc(SHA1_LENGTH);
- if(!hmac.data) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- rv = PK11_DigestFinal(p12ecx->hmacCx, hmac.data, &hmac.len, SHA1_LENGTH);
-
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* create the digest info */
- di = SGN_CreateDigestInfo(p12ecx->p12exp->integrityInfo.pwdInfo.algorithm,
- hmac.data, hmac.len);
- if(!di) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- goto loser;
- }
-
- rv = SGN_CopyDigestInfo(p12ecx->arena, &p12ecx->mac.safeMac, di);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* encode the mac data */
- dummy = SEC_ASN1EncodeItem(p12ecx->arena, &p12ecx->pfx.encodedMacData,
- &p12ecx->mac, sec_PKCS12MacDataTemplate);
- if(!dummy) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- }
-
-loser:
- if(di) {
- SGN_DestroyDigestInfo(di);
- }
- if(hmac.data) {
- SECITEM_ZfreeItem(&hmac, PR_FALSE);
- }
- PK11_DestroyContext(p12ecx->hmacCx, PR_TRUE);
- p12ecx->hmacCx = NULL;
-
- return rv;
-}
-
-/* pfx notify function for ASN1 encoder.
- * We want to stop encoding once we reach the authenticated safe.
- * At that point, the encoder will be updated via streaming
- * as the authenticated safe is encoded.
- */
-static void
-sec_pkcs12_encoder_pfx_notify(void *arg, PRBool before, void *dest, int real_depth)
-{
- sec_PKCS12EncoderContext *p12ecx;
-
- if(!before) {
- return;
- }
-
- /* look for authenticated safe */
- p12ecx = (sec_PKCS12EncoderContext*)arg;
- if(dest != &p12ecx->pfx.encodedAuthSafe) {
- return;
- }
-
- SEC_ASN1EncoderSetTakeFromBuf(p12ecx->outerA1ecx);
- SEC_ASN1EncoderSetStreaming(p12ecx->outerA1ecx);
- SEC_ASN1EncoderClearNotifyProc(p12ecx->outerA1ecx);
-}
-
-/* SEC_PKCS12Encode
- * Encodes the PFX item and returns it to the output function, via
- * callback. the output function must be capable of multiple updates.
- *
- * p12exp - the export context
- * output - the output function callback, will be called more than once,
- * must be able to accept streaming data.
- * outputarg - argument for the output callback.
- */
-SECStatus
-SEC_PKCS12Encode(SEC_PKCS12ExportContext *p12exp,
- SEC_PKCS12EncoderOutputCallback output, void *outputarg)
-{
- sec_PKCS12EncoderContext *p12enc;
- struct sec_pkcs12_encoder_output outInfo;
- SECStatus rv;
-
- if(!p12exp || !output) {
- return SECFailure;
- }
-
- /* get the encoder context */
- p12enc = sec_pkcs12_encoder_start_context(p12exp);
- if(!p12enc) {
- return SECFailure;
- }
-
- outInfo.outputfn = output;
- outInfo.outputarg = outputarg;
-
- /* set up PFX encoder, the "outer" encoder. Set it for streaming */
- p12enc->outerA1ecx = SEC_ASN1EncoderStart(&p12enc->pfx,
- sec_PKCS12PFXItemTemplate,
- sec_P12A1OutputCB_Outer,
- &outInfo);
- if(!p12enc->outerA1ecx) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- goto loser;
- }
- SEC_ASN1EncoderSetStreaming(p12enc->outerA1ecx);
- SEC_ASN1EncoderSetNotifyProc(p12enc->outerA1ecx,
- sec_pkcs12_encoder_pfx_notify, p12enc);
- rv = SEC_ASN1EncoderUpdate(p12enc->outerA1ecx, NULL, 0);
- if(rv != SECSuccess) {
- rv = SECFailure;
- goto loser;
- }
-
- /* set up asafe cinfo - the output of the encoder feeds the PFX encoder */
- p12enc->middleP7ecx = SEC_PKCS7EncoderStart(p12enc->aSafeCinfo,
- sec_P12P7OutputCB_CallA1Update,
- p12enc->outerA1ecx, NULL);
- if(!p12enc->middleP7ecx) {
- rv = SECFailure;
- goto loser;
- }
-
- /* encode asafe */
- p12enc->middleBuf.p7eCx = p12enc->middleP7ecx;
- p12enc->middleBuf.hmacCx = NULL;
- p12enc->middleBuf.numBytes = 0;
- p12enc->middleBuf.bufBytes = sizeof p12enc->middleBuf.buf;
-
- /* Setup the "inner ASN.1 encoder for Authenticated Safes. */
- if(p12enc->p12exp->integrityEnabled &&
- p12enc->p12exp->pwdIntegrity) {
- p12enc->middleBuf.hmacCx = p12enc->hmacCx;
- }
- p12enc->middleA1ecx = SEC_ASN1EncoderStart(&p12enc->p12exp->authSafe,
- sec_PKCS12AuthenticatedSafeTemplate,
- sec_P12A1OutputCB_HmacP7Update,
- &p12enc->middleBuf);
- if(!p12enc->middleA1ecx) {
- rv = SECFailure;
- goto loser;
- }
- SEC_ASN1EncoderSetStreaming(p12enc->middleA1ecx);
- SEC_ASN1EncoderSetTakeFromBuf(p12enc->middleA1ecx);
-
- /* encode each of the safes */
- while(p12enc->currentSafe != p12enc->p12exp->safeInfoCount) {
- sec_pkcs12_encoder_asafe_process(p12enc);
- p12enc->currentSafe++;
- }
- SEC_ASN1EncoderClearTakeFromBuf(p12enc->middleA1ecx);
- SEC_ASN1EncoderClearStreaming(p12enc->middleA1ecx);
- SEC_ASN1EncoderUpdate(p12enc->middleA1ecx, NULL, 0);
- SEC_ASN1EncoderFinish(p12enc->middleA1ecx);
- p12enc->middleA1ecx = NULL;
-
- sec_FlushPkcs12OutputBuffer( &p12enc->middleBuf);
-
- /* finish the encoding of the authenticated safes */
- rv = SEC_PKCS7EncoderFinish(p12enc->middleP7ecx, p12exp->pwfn,
- p12exp->pwfnarg);
- p12enc->middleP7ecx = NULL;
- if(rv != SECSuccess) {
- goto loser;
- }
-
- SEC_ASN1EncoderClearTakeFromBuf(p12enc->outerA1ecx);
- SEC_ASN1EncoderClearStreaming(p12enc->outerA1ecx);
-
- /* update the mac, if necessary */
- rv = sec_Pkcs12FinishMac(p12enc);
- if(rv != SECSuccess) {
- goto loser;
- }
-
- /* finish encoding the pfx */
- rv = SEC_ASN1EncoderUpdate(p12enc->outerA1ecx, NULL, 0);
-
- SEC_ASN1EncoderFinish(p12enc->outerA1ecx);
- p12enc->outerA1ecx = NULL;
-
-loser:
- sec_pkcs12_encoder_destroy_context(p12enc);
- return rv;
-}
-
-void
-SEC_PKCS12DestroyExportContext(SEC_PKCS12ExportContext *p12ecx)
-{
- int i = 0;
-
- if(!p12ecx) {
- return;
- }
-
- if(p12ecx->safeInfos) {
- i = 0;
- while(p12ecx->safeInfos[i] != NULL) {
- if(p12ecx->safeInfos[i]->encryptionKey) {
- PK11_FreeSymKey(p12ecx->safeInfos[i]->encryptionKey);
- }
- if(p12ecx->safeInfos[i]->cinfo) {
- SEC_PKCS7DestroyContentInfo(p12ecx->safeInfos[i]->cinfo);
- }
- i++;
- }
- }
-
- PK11_FreeSlot(p12ecx->slot);
-
- PORT_FreeArena(p12ecx->arena, PR_TRUE);
-}
diff --git a/security/nss/lib/pkcs12/p12exp.c b/security/nss/lib/pkcs12/p12exp.c
deleted file mode 100644
index 3860c47ac..000000000
--- a/security/nss/lib/pkcs12/p12exp.c
+++ /dev/null
@@ -1,1378 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "plarena.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "seccomon.h"
-#include "secport.h"
-#include "cert.h"
-#include "pkcs12.h"
-#include "p12local.h"
-#include "secpkcs7.h"
-#include "secasn1.h"
-#include "secerr.h"
-#include "p12plcy.h"
-
-/* release the memory taken up by the list of nicknames */
-static void
-sec_pkcs12_destroy_nickname_list(SECItem **nicknames)
-{
- int i = 0;
-
- if(nicknames == NULL) {
- return;
- }
-
- while(nicknames[i] != NULL) {
- SECITEM_FreeItem(nicknames[i], PR_FALSE);
- i++;
- }
-
- PORT_Free(nicknames);
-}
-
-/* release the memory taken up by the list of certificates */
-static void
-sec_pkcs12_destroy_certificate_list(CERTCertificate **ref_certs)
-{
- int i = 0;
-
- if(ref_certs == NULL) {
- return;
- }
-
- while(ref_certs[i] != NULL) {
- CERT_DestroyCertificate(ref_certs[i]);
- i++;
- }
-}
-
-static void
-sec_pkcs12_destroy_cinfos_for_cert_bags(SEC_PKCS12CertAndCRLBag *certBag)
-{
- int j = 0;
- j = 0;
- while(certBag->certAndCRLs[j] != NULL) {
- SECOidTag certType = SECOID_FindOIDTag(&certBag->certAndCRLs[j]->BagID);
- if(certType == SEC_OID_PKCS12_X509_CERT_CRL_BAG) {
- SEC_PKCS12X509CertCRL *x509;
- x509 = certBag->certAndCRLs[j]->value.x509;
- SEC_PKCS7DestroyContentInfo(&x509->certOrCRL);
- }
- j++;
- }
-}
-
-/* destroy all content infos since they were not allocated in common
- * pool
- */
-static void
-sec_pkcs12_destroy_cert_content_infos(SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage)
-{
- int i, j;
-
- if((safe != NULL) && (safe->contents != NULL)) {
- i = 0;
- while(safe->contents[i] != NULL) {
- SECOidTag bagType = SECOID_FindOIDTag(&safe->contents[i]->safeBagType);
- if(bagType == SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID) {
- SEC_PKCS12CertAndCRLBag *certBag;
- certBag = safe->contents[i]->safeContent.certAndCRLBag;
- sec_pkcs12_destroy_cinfos_for_cert_bags(certBag);
- }
- i++;
- }
- }
-
- if((baggage != NULL) && (baggage->bags != NULL)) {
- i = 0;
- while(baggage->bags[i] != NULL) {
- if(baggage->bags[i]->unencSecrets != NULL) {
- j = 0;
- while(baggage->bags[i]->unencSecrets[j] != NULL) {
- SECOidTag bagType;
- bagType = SECOID_FindOIDTag(&baggage->bags[i]->unencSecrets[j]->safeBagType);
- if(bagType == SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID) {
- SEC_PKCS12CertAndCRLBag *certBag;
- certBag = baggage->bags[i]->unencSecrets[j]->safeContent.certAndCRLBag;
- sec_pkcs12_destroy_cinfos_for_cert_bags(certBag);
- }
- j++;
- }
- }
- i++;
- }
- }
-}
-
-/* convert the nickname list from a NULL termincated Char list
- * to a NULL terminated SECItem list
- */
-static SECItem **
-sec_pkcs12_convert_nickname_list(char **nicknames)
-{
- SECItem **nicks;
- int i, j;
- PRBool error = PR_FALSE;
-
- if(nicknames == NULL) {
- return NULL;
- }
-
- i = j = 0;
- while(nicknames[i] != NULL) {
- i++;
- }
-
- /* allocate the space and copy the data */
- nicks = (SECItem **)PORT_ZAlloc(sizeof(SECItem *) * (i + 1));
- if(nicks != NULL) {
- for(j = 0; ((j < i) && (error == PR_FALSE)); j++) {
- nicks[j] = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(nicks[j] != NULL) {
- nicks[j]->data =
- (unsigned char *)PORT_ZAlloc(PORT_Strlen(nicknames[j])+1);
- if(nicks[j]->data != NULL) {
- nicks[j]->len = PORT_Strlen(nicknames[j]);
- PORT_Memcpy(nicks[j]->data, nicknames[j], nicks[j]->len);
- nicks[j]->data[nicks[j]->len] = 0;
- } else {
- error = PR_TRUE;
- }
- } else {
- error = PR_TRUE;
- }
- }
- }
-
- if(error == PR_TRUE) {
- for(i = 0; i < j; i++) {
- SECITEM_FreeItem(nicks[i], PR_TRUE);
- }
- PORT_Free(nicks);
- nicks = NULL;
- }
-
- return nicks;
-}
-
-/* package the certificate add_cert into PKCS12 structures,
- * retrieve the certificate chain for the cert and return
- * the packaged contents.
- * poolp -- common memory pool;
- * add_cert -- certificate to package up
- * nickname for the certificate
- * a return of NULL indicates an error
- */
-static SEC_PKCS12CertAndCRL *
-sec_pkcs12_get_cert(PRArenaPool *poolp,
- CERTCertificate *add_cert,
- SECItem *nickname)
-{
- SEC_PKCS12CertAndCRL *cert;
- SEC_PKCS7ContentInfo *cinfo;
- SGNDigestInfo *t_di;
- void *mark;
- SECStatus rv;
-
- if((poolp == NULL) || (add_cert == NULL) || (nickname == NULL)) {
- return NULL;
- }
- mark = PORT_ArenaMark(poolp);
-
- cert = sec_pkcs12_new_cert_crl(poolp, SEC_OID_PKCS12_X509_CERT_CRL_BAG);
- if(cert != NULL) {
-
- /* copy the nickname */
- rv = SECITEM_CopyItem(poolp, &cert->nickname, nickname);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- cert = NULL;
- } else {
-
- /* package the certificate and cert chain into a NULL signer
- * PKCS 7 SignedData content Info and prepare it for encoding
- * since we cannot use DER_ANY_TEMPLATE
- */
- cinfo = SEC_PKCS7CreateCertsOnly(add_cert, PR_TRUE, NULL);
- rv = SEC_PKCS7PrepareForEncode(cinfo, NULL, NULL, NULL);
-
- /* thumbprint the certificate */
- if((cinfo != NULL) && (rv == SECSuccess))
- {
- PORT_Memcpy(&cert->value.x509->certOrCRL, cinfo, sizeof(*cinfo));
- t_di = sec_pkcs12_compute_thumbprint(&add_cert->derCert);
- if(t_di != NULL)
- {
- /* test */
- rv = SGN_CopyDigestInfo(poolp, &cert->value.x509->thumbprint,
- t_di);
- if(rv != SECSuccess) {
- cert = NULL;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- SGN_DestroyDigestInfo(t_di);
- }
- else
- cert = NULL;
- }
- }
- }
-
- if (cert == NULL) {
- PORT_ArenaRelease(poolp, mark);
- } else {
- PORT_ArenaUnmark(poolp, mark);
- }
-
- return cert;
-}
-
-/* package the private key associated with the certificate and
- * return the appropriate PKCS 12 structure
- * poolp common memory pool
- * nickname key nickname
- * cert -- cert to look up
- * wincx -- window handle
- * an error is indicated by a return of NULL
- */
-static SEC_PKCS12PrivateKey *
-sec_pkcs12_get_private_key(PRArenaPool *poolp,
- SECItem *nickname,
- CERTCertificate *cert,
- void *wincx)
-{
- SECKEYPrivateKeyInfo *pki;
- SEC_PKCS12PrivateKey *pk;
- SECStatus rv;
- void *mark;
-
- if((poolp == NULL) || (nickname == NULL)) {
- return NULL;
- }
-
- mark = PORT_ArenaMark(poolp);
-
- /* retrieve key from the data base */
- pki = PK11_ExportPrivateKeyInfo(nickname, cert, wincx);
- if(pki == NULL) {
- PORT_ArenaRelease(poolp, mark);
- PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY);
- return NULL;
- }
-
- pk = (SEC_PKCS12PrivateKey *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS12PrivateKey));
- if(pk != NULL) {
- rv = sec_pkcs12_init_pvk_data(poolp, &pk->pvkData);
-
- if(rv == SECSuccess) {
- /* copy the key into poolp memory space */
- rv = SECKEY_CopyPrivateKeyInfo(poolp, &pk->pkcs8data, pki);
- if(rv == SECSuccess) {
- rv = SECITEM_CopyItem(poolp, &pk->pvkData.nickname, nickname);
- }
- }
-
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- pk = NULL;
- }
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
-
- /* destroy private key, zeroing out data */
- SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE);
- if (pk == NULL) {
- PORT_ArenaRelease(poolp, mark);
- } else {
- PORT_ArenaUnmark(poolp, mark);
- }
-
- return pk;
-}
-
-/* get a shrouded key item associated with a certificate
- * return the appropriate PKCS 12 structure
- * poolp common memory pool
- * nickname key nickname
- * cert -- cert to look up
- * wincx -- window handle
- * an error is indicated by a return of NULL
- */
-static SEC_PKCS12ESPVKItem *
-sec_pkcs12_get_shrouded_key(PRArenaPool *poolp,
- SECItem *nickname,
- CERTCertificate *cert,
- SECOidTag algorithm,
- SECItem *pwitem,
- PKCS12UnicodeConvertFunction unicodeFn,
- void *wincx)
-{
- SECKEYEncryptedPrivateKeyInfo *epki;
- SEC_PKCS12ESPVKItem *pk;
- void *mark;
- SECStatus rv;
- PK11SlotInfo *slot = NULL;
- PRBool swapUnicodeBytes = PR_FALSE;
-
-#ifdef IS_LITTLE_ENDIAN
- swapUnicodeBytes = PR_TRUE;
-#endif
-
- if((poolp == NULL) || (nickname == NULL))
- return NULL;
-
- mark = PORT_ArenaMark(poolp);
-
- /* use internal key slot */
- slot = PK11_GetInternalKeySlot();
-
- /* retrieve encrypted prviate key */
- epki = PK11_ExportEncryptedPrivateKeyInfo(slot, algorithm, pwitem,
- nickname, cert, 1, 0, NULL);
- PK11_FreeSlot(slot);
- if(epki == NULL) {
- PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY);
- PORT_ArenaRelease(poolp, mark);
- return NULL;
- }
-
- /* create a private key and store the data into the poolp memory space */
- pk = sec_pkcs12_create_espvk(poolp, SEC_OID_PKCS12_PKCS8_KEY_SHROUDING);
- if(pk != NULL) {
- rv = sec_pkcs12_init_pvk_data(poolp, &pk->espvkData);
- rv = SECITEM_CopyItem(poolp, &pk->espvkData.nickname, nickname);
- pk->espvkCipherText.pkcs8KeyShroud =
- (SECKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(poolp,
- sizeof(SECKEYEncryptedPrivateKeyInfo));
- if((pk->espvkCipherText.pkcs8KeyShroud != NULL) && (rv == SECSuccess)) {
- rv = SECKEY_CopyEncryptedPrivateKeyInfo(poolp,
- pk->espvkCipherText.pkcs8KeyShroud, epki);
- if(rv == SECSuccess) {
- rv = (*unicodeFn)(poolp, &pk->espvkData.uniNickName, nickname,
- PR_TRUE, swapUnicodeBytes);
- }
- }
-
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- pk = NULL;
- }
- }
-
- SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE);
- if(pk == NULL) {
- PORT_ArenaRelease(poolp, mark);
- } else {
- PORT_ArenaUnmark(poolp, mark);
- }
-
- return pk;
-}
-
-/* add a thumbprint to a private key associated certs list
- * pvk is the area where the list is stored
- * thumb is the thumbprint to copy
- * a return of SECFailure indicates an error
- */
-static SECStatus
-sec_pkcs12_add_thumbprint(SEC_PKCS12PVKSupportingData *pvk,
- SGNDigestInfo *thumb)
-{
- SGNDigestInfo **thumb_list = NULL;
- int nthumbs, size;
- void *mark, *dummy;
- SECStatus rv = SECFailure;
-
- if((pvk == NULL) || (thumb == NULL)) {
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(pvk->poolp);
-
- thumb_list = pvk->assocCerts;
- nthumbs = pvk->nThumbs;
-
- /* allocate list space needed -- either growing or allocating
- * list must be NULL terminated
- */
- size = sizeof(SGNDigestInfo *);
- dummy = PORT_ArenaGrow(pvk->poolp, thumb_list, (size * (nthumbs + 1)),
- (size * (nthumbs + 2)));
- thumb_list = dummy;
- if(dummy != NULL) {
- thumb_list[nthumbs] = (SGNDigestInfo *)PORT_ArenaZAlloc(pvk->poolp,
- sizeof(SGNDigestInfo));
- if(thumb_list[nthumbs] != NULL) {
- SGN_CopyDigestInfo(pvk->poolp, thumb_list[nthumbs], thumb);
- nthumbs += 1;
- thumb_list[nthumbs] = 0;
- } else {
- dummy = NULL;
- }
- }
-
- if(dummy == NULL) {
- PORT_ArenaRelease(pvk->poolp, mark);
- return SECFailure;
- }
-
- pvk->assocCerts = thumb_list;
- pvk->nThumbs = nthumbs;
-
- PORT_ArenaUnmark(pvk->poolp, mark);
- return SECSuccess;
-}
-
-/* search the list of shrouded keys in the baggage for the desired
- * name. return a pointer to the item. a return of NULL indicates
- * that no match was present or that an error occurred.
- */
-static SEC_PKCS12ESPVKItem *
-sec_pkcs12_get_espvk_by_name(SEC_PKCS12Baggage *luggage,
- SECItem *name)
-{
- PRBool found = PR_FALSE;
- SEC_PKCS12ESPVKItem *espvk = NULL;
- int i, j;
- SECComparison rv = SECEqual;
- SECItem *t_name;
- SEC_PKCS12BaggageItem *bag;
-
- if((luggage == NULL) || (name == NULL)) {
- return NULL;
- }
-
- i = 0;
- while((found == PR_FALSE) && (i < luggage->luggage_size)) {
- j = 0;
- bag = luggage->bags[i];
- while((found == PR_FALSE) && (j < bag->nEspvks)) {
- espvk = bag->espvks[j];
- if(espvk->poolp == NULL) {
- espvk->poolp = luggage->poolp;
- }
- t_name = SECITEM_DupItem(&espvk->espvkData.nickname);
- if(t_name != NULL) {
- rv = SECITEM_CompareItem(name, t_name);
- if(rv == SECEqual) {
- found = PR_TRUE;
- }
- SECITEM_FreeItem(t_name, PR_TRUE);
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
- j++;
- }
- i++;
- }
-
- if(found != PR_TRUE) {
- PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME);
- return NULL;
- }
-
- return espvk;
-}
-
-/* locates a certificate and copies the thumbprint to the
- * appropriate private key
- */
-static SECStatus
-sec_pkcs12_propagate_thumbprints(SECItem **nicknames,
- CERTCertificate **ref_certs,
- SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage)
-{
- SEC_PKCS12CertAndCRL *cert;
- SEC_PKCS12PrivateKey *key;
- SEC_PKCS12ESPVKItem *espvk;
- int i;
- PRBool error = PR_FALSE;
- SECStatus rv = SECFailure;
-
- if((nicknames == NULL) || (safe == NULL)) {
- return SECFailure;
- }
-
- i = 0;
- while((nicknames[i] != NULL) && (error == PR_FALSE)) {
- /* process all certs */
- cert = (SEC_PKCS12CertAndCRL *)sec_pkcs12_find_object(safe, baggage,
- SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID,
- nicknames[i], NULL);
- if(cert != NULL) {
- /* locate key and copy thumbprint */
- key = (SEC_PKCS12PrivateKey *)sec_pkcs12_find_object(safe, baggage,
- SEC_OID_PKCS12_KEY_BAG_ID,
- nicknames[i], NULL);
- if(key != NULL) {
- key->pvkData.poolp = key->poolp;
- rv = sec_pkcs12_add_thumbprint(&key->pvkData,
- &cert->value.x509->thumbprint);
- if(rv == SECFailure)
- error = PR_TRUE; /* XXX Set error? */
- }
-
- /* look in the baggage as well...*/
- if((baggage != NULL) && (error == PR_FALSE)) {
- espvk = sec_pkcs12_get_espvk_by_name(baggage, nicknames[i]);
- if(espvk != NULL) {
- espvk->espvkData.poolp = espvk->poolp;
- rv = sec_pkcs12_add_thumbprint(&espvk->espvkData,
- &cert->value.x509->thumbprint);
- if(rv == SECFailure)
- error = PR_TRUE; /* XXX Set error? */
- }
- }
- }
- i++;
- }
-
- if(error == PR_TRUE) {
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-/* append a safe bag to the end of the safe contents list */
-SECStatus
-sec_pkcs12_append_safe_bag(SEC_PKCS12SafeContents *safe,
- SEC_PKCS12SafeBag *bag)
-{
- int size;
- void *mark = NULL, *dummy = NULL;
-
- if((bag == NULL) || (safe == NULL))
- return SECFailure;
-
- mark = PORT_ArenaMark(safe->poolp);
-
- size = (safe->safe_size * sizeof(SEC_PKCS12SafeBag *));
-
- if(safe->safe_size > 0) {
- dummy = (SEC_PKCS12SafeBag **)PORT_ArenaGrow(safe->poolp,
- safe->contents,
- size,
- (size + sizeof(SEC_PKCS12SafeBag *)));
- safe->contents = dummy;
- } else {
- safe->contents = (SEC_PKCS12SafeBag **)PORT_ArenaZAlloc(safe->poolp,
- (2 * sizeof(SEC_PKCS12SafeBag *)));
- dummy = safe->contents;
- }
-
- if(dummy == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- safe->contents[safe->safe_size] = bag;
- safe->safe_size++;
- safe->contents[safe->safe_size] = NULL;
-
- PORT_ArenaUnmark(safe->poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(safe->poolp, mark);
- return SECFailure;
-}
-
-/* append a certificate onto the end of a cert bag */
-static SECStatus
-sec_pkcs12_append_cert_to_bag(PRArenaPool *arena,
- SEC_PKCS12SafeBag *safebag,
- CERTCertificate *cert,
- SECItem *nickname)
-{
- int size;
- void *dummy = NULL, *mark = NULL;
- SEC_PKCS12CertAndCRL *p12cert;
- SEC_PKCS12CertAndCRLBag *bag;
-
- if((arena == NULL) || (safebag == NULL) ||
- (cert == NULL) || (nickname == NULL)) {
- return SECFailure;
- }
-
- bag = safebag->safeContent.certAndCRLBag;
- if(bag == NULL) {
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(arena);
-
- p12cert = sec_pkcs12_get_cert(arena, cert, nickname);
- if(p12cert == NULL) {
- PORT_ArenaRelease(bag->poolp, mark);
- return SECFailure;
- }
-
- size = bag->bag_size * sizeof(SEC_PKCS12CertAndCRL *);
- if(bag->bag_size > 0) {
- dummy = (SEC_PKCS12CertAndCRL **)PORT_ArenaGrow(bag->poolp,
- bag->certAndCRLs, size, size + sizeof(SEC_PKCS12CertAndCRL *));
- bag->certAndCRLs = dummy;
- } else {
- bag->certAndCRLs = (SEC_PKCS12CertAndCRL **)PORT_ArenaZAlloc(bag->poolp,
- (2 * sizeof(SEC_PKCS12CertAndCRL *)));
- dummy = bag->certAndCRLs;
- }
-
- if(dummy == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- bag->certAndCRLs[bag->bag_size] = p12cert;
- bag->bag_size++;
- bag->certAndCRLs[bag->bag_size] = NULL;
-
- PORT_ArenaUnmark(bag->poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(bag->poolp, mark);
- return SECFailure;
-}
-
-/* append a key onto the end of a list of keys in a key bag */
-SECStatus
-sec_pkcs12_append_key_to_bag(SEC_PKCS12SafeBag *safebag,
- SEC_PKCS12PrivateKey *pk)
-{
- void *mark, *dummy;
- SEC_PKCS12PrivateKeyBag *bag;
- int size;
-
- if((safebag == NULL) || (pk == NULL))
- return SECFailure;
-
- bag = safebag->safeContent.keyBag;
- if(bag == NULL) {
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(bag->poolp);
-
- size = (bag->bag_size * sizeof(SEC_PKCS12PrivateKey *));
-
- if(bag->bag_size > 0) {
- dummy = (SEC_PKCS12PrivateKey **)PORT_ArenaGrow(bag->poolp,
- bag->privateKeys,
- size,
- size + sizeof(SEC_PKCS12PrivateKey *));
- bag->privateKeys = dummy;
- } else {
- bag->privateKeys = (SEC_PKCS12PrivateKey **)PORT_ArenaZAlloc(bag->poolp,
- (2 * sizeof(SEC_PKCS12PrivateKey *)));
- dummy = bag->privateKeys;
- }
-
- if(dummy == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- bag->privateKeys[bag->bag_size] = pk;
- bag->bag_size++;
- bag->privateKeys[bag->bag_size] = NULL;
-
- PORT_ArenaUnmark(bag->poolp, mark);
- return SECSuccess;
-
-loser:
- /* XXX Free memory? */
- PORT_ArenaRelease(bag->poolp, mark);
- return SECFailure;
-}
-
-/* append a safe bag to the baggage area */
-static SECStatus
-sec_pkcs12_append_unshrouded_bag(SEC_PKCS12BaggageItem *bag,
- SEC_PKCS12SafeBag *u_bag)
-{
- int size;
- void *mark = NULL, *dummy = NULL;
-
- if((bag == NULL) || (u_bag == NULL))
- return SECFailure;
-
- mark = PORT_ArenaMark(bag->poolp);
-
- /* dump things into the first bag */
- size = (bag->nSecrets + 1) * sizeof(SEC_PKCS12SafeBag *);
- dummy = PORT_ArenaGrow(bag->poolp,
- bag->unencSecrets, size,
- size + sizeof(SEC_PKCS12SafeBag *));
- bag->unencSecrets = dummy;
- if(dummy == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- bag->unencSecrets[bag->nSecrets] = u_bag;
- bag->nSecrets++;
- bag->unencSecrets[bag->nSecrets] = NULL;
-
- PORT_ArenaUnmark(bag->poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(bag->poolp, mark);
- return SECFailure;
-}
-
-/* gather up all certificates and keys and package them up
- * in the safe, baggage, or both.
- * nicknames is the list of nicknames and corresponding certs in ref_certs
- * ref_certs a null terminated list of certificates
- * rSafe, rBaggage -- return areas for safe and baggage
- * shroud_keys -- store keys externally
- * pwitem -- password for computing integrity mac and encrypting contents
- * wincx -- window handle
- *
- * if a failure occurs, an error is set and SECFailure returned.
- */
-static SECStatus
-sec_pkcs12_package_certs_and_keys(SECItem **nicknames,
- CERTCertificate **ref_certs,
- PRBool unencryptedCerts,
- SEC_PKCS12SafeContents **rSafe,
- SEC_PKCS12Baggage **rBaggage,
- PRBool shroud_keys,
- SECOidTag shroud_alg,
- SECItem *pwitem,
- PKCS12UnicodeConvertFunction unicodeFn,
- void *wincx)
-{
- PRArenaPool *permArena;
- SEC_PKCS12SafeContents *safe = NULL;
- SEC_PKCS12Baggage *baggage = NULL;
-
- SECStatus rv = SECFailure;
- PRBool problem = PR_FALSE;
-
- SEC_PKCS12ESPVKItem *espvk = NULL;
- SEC_PKCS12PrivateKey *pk = NULL;
- CERTCertificate *add_cert = NULL;
- SEC_PKCS12SafeBag *certbag = NULL, *keybag = NULL;
- SEC_PKCS12BaggageItem *external_bag = NULL;
- int ncerts = 0, nkeys = 0;
- int i;
-
- if((nicknames == NULL) || (rSafe == NULL) || (rBaggage == NULL)) {
- return SECFailure;
- }
-
- *rBaggage = baggage;
- *rSafe = safe;
-
- permArena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(permArena == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- /* allocate structures */
- safe = sec_pkcs12_create_safe_contents(permArena);
- if(safe == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- goto loser;
- }
-
- certbag = sec_pkcs12_create_safe_bag(permArena,
- SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID);
- if(certbag == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- if(shroud_keys != PR_TRUE) {
- keybag = sec_pkcs12_create_safe_bag(permArena,
- SEC_OID_PKCS12_KEY_BAG_ID);
- if(keybag == NULL) {
- rv = SECFailure;
- goto loser;
- }
- }
-
- if((shroud_keys == PR_TRUE) || (unencryptedCerts == PR_TRUE)) {
- baggage = sec_pkcs12_create_baggage(permArena);
- if(baggage == NULL) {
- rv = SECFailure;
- goto loser;
- }
- external_bag = sec_pkcs12_create_external_bag(baggage);
- }
-
- /* package keys and certs */
- i = 0;
- while((nicknames[i] != NULL) && (problem == PR_FALSE)) {
- if(ref_certs[i] != NULL) {
- /* append cert to bag o certs */
- rv = sec_pkcs12_append_cert_to_bag(permArena, certbag,
- ref_certs[i],
- nicknames[i]);
- if(rv == SECFailure) {
- problem = PR_FALSE;
- } else {
- ncerts++;
- }
-
- if(rv == SECSuccess) {
- /* package up them keys */
- if(shroud_keys == PR_TRUE) {
- espvk = sec_pkcs12_get_shrouded_key(permArena,
- nicknames[i],
- ref_certs[i],
- shroud_alg,
- pwitem, unicodeFn,
- wincx);
- if(espvk != NULL) {
- rv = sec_pkcs12_append_shrouded_key(external_bag, espvk);
- SECITEM_CopyItem(permArena, &espvk->derCert,
- &ref_certs[i]->derCert);
- } else {
- rv = SECFailure;
- }
- } else {
- pk = sec_pkcs12_get_private_key(permArena, nicknames[i],
- ref_certs[i], wincx);
- if(pk != NULL) {
- rv = sec_pkcs12_append_key_to_bag(keybag, pk);
- SECITEM_CopyItem(permArena, &espvk->derCert,
- &ref_certs[i]->derCert);
- } else {
- rv = SECFailure;
- }
- }
-
- if(rv == SECFailure) {
- problem = PR_TRUE;
- } else {
- nkeys++;
- }
- }
- } else {
- /* handle only keys here ? */
- problem = PR_TRUE;
- }
- i++;
- }
-
- /* let success fall through */
-loser:
- if(problem == PR_FALSE) {
- /* if we have certs, we want to append the cert bag to the
- * appropriate area
- */
- if(ncerts > 0) {
- if(unencryptedCerts != PR_TRUE) {
- rv = sec_pkcs12_append_safe_bag(safe, certbag);
- } else {
- rv = sec_pkcs12_append_unshrouded_bag(external_bag, certbag);
- }
- } else {
- rv = SECSuccess;
- }
-
- /* append key bag, if they are stored in safe contents */
- if((rv == SECSuccess) && (shroud_keys == PR_FALSE) && (nkeys > 0)) {
- rv = sec_pkcs12_append_safe_bag(safe, keybag);
- }
- } else {
- rv = SECFailure;
- }
-
- /* if baggage not used, NULLify it */
- if((shroud_keys == PR_TRUE) || (unencryptedCerts == PR_TRUE)) {
- if(((unencryptedCerts == PR_TRUE) && (ncerts == 0)) &&
- ((shroud_keys == PR_TRUE) && (nkeys == 0)))
- baggage = NULL;
- } else {
- baggage = NULL;
- }
-
- if((problem == PR_TRUE) || (rv == SECFailure)) {
- PORT_FreeArena(permArena, PR_TRUE);
- rv = SECFailure;
- baggage = NULL;
- safe = NULL;
- }
-
- *rBaggage = baggage;
- *rSafe = safe;
-
- return rv;
-}
-
-/* DER encode the safe contents and return a SECItem. if an error
- * occurs, NULL is returned.
- */
-static SECItem *
-sec_pkcs12_encode_safe_contents(SEC_PKCS12SafeContents *safe)
-{
- SECItem *dsafe = NULL, *tsafe;
- void *dummy = NULL;
- PRArenaPool *arena;
-
- if(safe == NULL) {
- return NULL;
- }
-
-/* rv = sec_pkcs12_prepare_for_der_code_safe(safe, PR_TRUE);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }*/
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(arena == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- tsafe = (SECItem *)PORT_ArenaZAlloc(arena, sizeof(SECItem));
- if(tsafe != NULL) {
- dummy = SEC_ASN1EncodeItem(arena, tsafe, safe,
- SEC_PKCS12SafeContentsTemplate);
- if(dummy != NULL) {
- dsafe = SECITEM_DupItem(tsafe);
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
-
- PORT_FreeArena(arena, PR_TRUE);
-
- return dsafe;
-}
-
-/* prepare the authenicated safe for encoding and encode it.
- * baggage is copied to the appropriate area, safe is encoded and
- * encrypted. the version and transport mode are set on the asafe.
- * the whole ball of wax is then der encoded and packaged up into
- * data content info
- * safe -- container of certs and keys, is encrypted.
- * baggage -- container of certs and keys, keys assumed to be encrypted by
- * another method, certs are in the clear
- * algorithm -- algorithm by which to encrypt safe
- * pwitem -- password for encryption
- * wincx - window handle
- *
- * return of NULL is an error condition.
- */
-static SEC_PKCS7ContentInfo *
-sec_pkcs12_get_auth_safe(SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage,
- SECOidTag algorithm,
- SECItem *pwitem,
- PKCS12UnicodeConvertFunction unicodeFn,
- void *wincx)
-{
- SECItem *src = NULL, *dest = NULL, *psalt = NULL;
- PRArenaPool *poolp;
- SEC_PKCS12AuthenticatedSafe *asafe;
- SEC_PKCS7ContentInfo *safe_cinfo = NULL;
- SEC_PKCS7ContentInfo *asafe_cinfo = NULL;
- void *dummy;
- SECStatus rv = SECSuccess;
- PRBool swapUnicodeBytes = PR_FALSE;
-
-#ifdef IS_LITTLE_ENDIAN
- swapUnicodeBytes = PR_TRUE;
-#endif
-
- if(((safe != NULL) && (pwitem == NULL)) && (baggage == NULL))
- return NULL;
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(poolp == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- /* prepare authenticated safe for encode */
- asafe = sec_pkcs12_new_asafe(poolp);
- if(asafe != NULL) {
-
- /* set version */
- dummy = SEC_ASN1EncodeInteger(asafe->poolp, &asafe->version,
- SEC_PKCS12_PFX_VERSION);
- if(dummy == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- goto loser;
- }
-
- /* generate the privacy salt used to create virtual pwd */
- psalt = sec_pkcs12_generate_salt();
- if(psalt != NULL) {
- rv = SECITEM_CopyItem(asafe->poolp, &asafe->privacySalt,
- psalt);
- if(rv == SECSuccess) {
- asafe->privacySalt.len *= 8;
- }
- else {
- SECITEM_ZfreeItem(psalt, PR_TRUE);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- }
-
- if((psalt == NULL) || (rv == SECFailure)) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- goto loser;
- }
-
- /* package up safe contents */
- if(safe != NULL)
- {
- safe_cinfo = SEC_PKCS7CreateEncryptedData(algorithm, NULL, wincx);
- if((safe_cinfo != NULL) && (safe->safe_size > 0)) {
- /* encode the safe and encrypt the contents of the
- * content info
- */
- src = sec_pkcs12_encode_safe_contents(safe);
-
- if(src != NULL) {
- rv = SEC_PKCS7SetContent(safe_cinfo, (char *)src->data, src->len);
- SECITEM_ZfreeItem(src, PR_TRUE);
- if(rv == SECSuccess) {
- SECItem *vpwd;
- vpwd = sec_pkcs12_create_virtual_password(pwitem, psalt,
- unicodeFn, swapUnicodeBytes);
- if(vpwd != NULL) {
- rv = SEC_PKCS7EncryptContents(NULL, safe_cinfo,
- vpwd, wincx);
- SECITEM_ZfreeItem(vpwd, PR_TRUE);
- } else {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- } else {
- rv = SECFailure;
- }
- } else if(safe->safe_size > 0) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- } else {
- /* case where there is NULL content in the safe contents */
- rv = SEC_PKCS7SetContent(safe_cinfo, NULL, 0);
- if(rv != SECFailure) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- }
-
- if(rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo(safe_cinfo);
- safe_cinfo = NULL;
- goto loser;
- }
-
- asafe->safe = safe_cinfo;
- /*
- PORT_Memcpy(&asafe->safe, safe_cinfo, sizeof(*safe_cinfo));
- */
- }
-
- /* copy the baggage to the authenticated safe baggage if present */
- if(baggage != NULL) {
- PORT_Memcpy(&asafe->baggage, baggage, sizeof(*baggage));
- }
-
- /* encode authenticated safe and store it in a Data content info */
- dest = (SECItem *)PORT_ArenaZAlloc(poolp, sizeof(SECItem));
- if(dest != NULL) {
- dummy = SEC_ASN1EncodeItem(poolp, dest, asafe,
- SEC_PKCS12AuthenticatedSafeTemplate);
- if(dummy != NULL) {
- asafe_cinfo = SEC_PKCS7CreateData();
- if(asafe_cinfo != NULL) {
- rv = SEC_PKCS7SetContent(asafe_cinfo,
- (char *)dest->data,
- dest->len);
- if(rv != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- SEC_PKCS7DestroyContentInfo(asafe_cinfo);
- asafe_cinfo = NULL;
- }
- }
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- }
- }
- }
-
-loser:
- PORT_FreeArena(poolp, PR_TRUE);
- if(safe_cinfo != NULL) {
- SEC_PKCS7DestroyContentInfo(safe_cinfo);
- }
- if(psalt != NULL) {
- SECITEM_ZfreeItem(psalt, PR_TRUE);
- }
-
- if(rv == SECFailure) {
- return NULL;
- }
-
- return asafe_cinfo;
-}
-
-/* generates the PFX and computes the mac on the authenticated safe
- * NULL implies an error
- */
-static SEC_PKCS12PFXItem *
-sec_pkcs12_get_pfx(SEC_PKCS7ContentInfo *cinfo,
- PRBool do_mac,
- SECItem *pwitem, PKCS12UnicodeConvertFunction unicodeFn)
-{
- SECItem *dest = NULL, *mac = NULL, *salt = NULL, *key = NULL;
- SEC_PKCS12PFXItem *pfx;
- SECStatus rv = SECFailure;
- SGNDigestInfo *di;
- SECItem *vpwd;
- PRBool swapUnicodeBytes = PR_FALSE;
-
-#ifdef IS_LITTLE_ENDIAN
- swapUnicodeBytes = PR_TRUE;
-#endif
-
- if((cinfo == NULL) || ((do_mac == PR_TRUE) && (pwitem == NULL))) {
- return NULL;
- }
-
- /* allocate new pfx structure */
- pfx = sec_pkcs12_new_pfx();
- if(pfx == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- PORT_Memcpy(&pfx->authSafe, cinfo, sizeof(*cinfo));
- if(do_mac == PR_TRUE) {
-
- /* salt for computing mac */
- salt = sec_pkcs12_generate_salt();
- if(salt != NULL) {
- rv = SECITEM_CopyItem(pfx->poolp, &pfx->macData.macSalt, salt);
- pfx->macData.macSalt.len *= 8;
-
- vpwd = sec_pkcs12_create_virtual_password(pwitem, salt,
- unicodeFn, swapUnicodeBytes);
- if(vpwd == NULL) {
- rv = SECFailure;
- key = NULL;
- } else {
- key = sec_pkcs12_generate_key_from_password(SEC_OID_SHA1,
- salt, vpwd);
- SECITEM_ZfreeItem(vpwd, PR_TRUE);
- }
-
- if((key != NULL) && (rv == SECSuccess)) {
- dest = SEC_PKCS7GetContent(cinfo);
- if(dest != NULL) {
-
- /* compute mac on data -- for password integrity mode */
- mac = sec_pkcs12_generate_mac(key, dest, PR_FALSE);
- if(mac != NULL) {
- di = SGN_CreateDigestInfo(SEC_OID_SHA1,
- mac->data, mac->len);
- if(di != NULL) {
- rv = SGN_CopyDigestInfo(pfx->poolp,
- &pfx->macData.safeMac, di);
- SGN_DestroyDigestInfo(di);
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- SECITEM_ZfreeItem(mac, PR_TRUE);
- }
- } else {
- rv = SECFailure;
- }
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- }
-
- if(key != NULL) {
- SECITEM_ZfreeItem(key, PR_TRUE);
- }
- SECITEM_ZfreeItem(salt, PR_TRUE);
- }
- }
-
- if(rv == SECFailure) {
- SEC_PKCS12DestroyPFX(pfx);
- pfx = NULL;
- }
-
- return pfx;
-}
-
-/* der encode the pfx */
-static SECItem *
-sec_pkcs12_encode_pfx(SEC_PKCS12PFXItem *pfx)
-{
- SECItem *dest;
- void *dummy;
-
- if(pfx == NULL) {
- return NULL;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- dummy = SEC_ASN1EncodeItem(NULL, dest, pfx, SEC_PKCS12PFXItemTemplate);
- if(dummy == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- SECITEM_ZfreeItem(dest, PR_TRUE);
- dest = NULL;
- }
-
- return dest;
-}
-
-SECItem *
-SEC_PKCS12GetPFX(char **nicknames,
- CERTCertificate **ref_certs,
- PRBool shroud_keys,
- SEC_PKCS5GetPBEPassword pbef,
- void *pbearg,
- PKCS12UnicodeConvertFunction unicodeFn,
- void *wincx)
-{
- SECItem **nicks = NULL;
- SEC_PKCS12PFXItem *pfx = NULL;
- SEC_PKCS12Baggage *baggage = NULL;
- SEC_PKCS12SafeContents *safe = NULL;
- SEC_PKCS7ContentInfo *cinfo = NULL;
- SECStatus rv = SECFailure;
- SECItem *dest = NULL, *pwitem = NULL;
- PRBool problem = PR_FALSE;
- PRBool unencryptedCerts;
- SECOidTag shroud_alg, safe_alg;
-
- /* how should we encrypt certs ? */
- unencryptedCerts = !SEC_PKCS12IsEncryptionAllowed();
- if(!unencryptedCerts) {
- safe_alg = SEC_PKCS12GetPreferredEncryptionAlgorithm();
- if(safe_alg == SEC_OID_UNKNOWN) {
- safe_alg = SEC_PKCS12GetStrongestAllowedAlgorithm();
- }
- if(safe_alg == SEC_OID_UNKNOWN) {
- unencryptedCerts = PR_TRUE;
- /* for export where no encryption is allowed, we still need
- * to encrypt the NULL contents per the spec. encrypted info
- * is known plaintext, so it shouldn't be a problem.
- */
- safe_alg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- }
- } else {
- /* for export where no encryption is allowed, we still need
- * to encrypt the NULL contents per the spec. encrypted info
- * is known plaintext, so it shouldn't be a problem.
- */
- safe_alg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- }
-
- /* keys are always stored with triple DES */
- shroud_alg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
-
- /* check for FIPS, if so, do not encrypt certs */
- if(PK11_IsFIPS() && !unencryptedCerts) {
- unencryptedCerts = PR_TRUE;
- }
-
- if((nicknames == NULL) || (pbef == NULL) || (ref_certs == NULL)) {
- problem = PR_TRUE;
- goto loser;
- }
-
-
- /* get password */
- pwitem = (*pbef)(pbearg);
- if(pwitem == NULL) {
- problem = PR_TRUE;
- goto loser;
- }
- nicks = sec_pkcs12_convert_nickname_list(nicknames);
-
- /* get safe and baggage */
- rv = sec_pkcs12_package_certs_and_keys(nicks, ref_certs, unencryptedCerts,
- &safe, &baggage, shroud_keys,
- shroud_alg, pwitem, unicodeFn, wincx);
- if(rv == SECFailure) {
- problem = PR_TRUE;
- }
-
- if((safe != NULL) && (problem == PR_FALSE)) {
- /* copy thumbprints */
- rv = sec_pkcs12_propagate_thumbprints(nicks, ref_certs, safe, baggage);
-
- /* package everything up into AuthenticatedSafe */
- cinfo = sec_pkcs12_get_auth_safe(safe, baggage,
- safe_alg, pwitem, unicodeFn, wincx);
-
- sec_pkcs12_destroy_cert_content_infos(safe, baggage);
-
- /* get the pfx and mac it */
- if(cinfo != NULL) {
- pfx = sec_pkcs12_get_pfx(cinfo, PR_TRUE, pwitem, unicodeFn);
- if(pfx != NULL) {
- dest = sec_pkcs12_encode_pfx(pfx);
- SEC_PKCS12DestroyPFX(pfx);
- }
- SEC_PKCS7DestroyContentInfo(cinfo);
- }
-
- if(safe != NULL) {
- PORT_FreeArena(safe->poolp, PR_TRUE);
- }
- } else {
- if(safe != NULL) {
- PORT_FreeArena(safe->poolp, PR_TRUE);
- }
- }
-
-loser:
- if(nicks != NULL) {
- sec_pkcs12_destroy_nickname_list(nicks);
- }
-
- if(ref_certs != NULL) {
- sec_pkcs12_destroy_certificate_list(ref_certs);
- }
-
- if(pwitem != NULL) {
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
- }
-
- if(problem == PR_TRUE) {
- dest = NULL;
- }
-
- return dest;
-}
diff --git a/security/nss/lib/pkcs12/p12local.c b/security/nss/lib/pkcs12/p12local.c
deleted file mode 100644
index 99aaac926..000000000
--- a/security/nss/lib/pkcs12/p12local.c
+++ /dev/null
@@ -1,1342 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nssrenam.h"
-#include "pkcs12.h"
-#include "secpkcs7.h"
-#include "secasn1.h"
-#include "seccomon.h"
-#include "secoid.h"
-#include "sechash.h"
-#include "secitem.h"
-#include "secerr.h"
-#include "pk11func.h"
-#include "p12local.h"
-#include "p12.h"
-
-#define SALT_LENGTH 16
-
-SEC_ASN1_MKSUB(SECKEY_PrivateKeyInfoTemplate)
-SEC_ASN1_MKSUB(sgn_DigestInfoTemplate)
-
-CK_MECHANISM_TYPE
-sec_pkcs12_algtag_to_mech(SECOidTag algtag)
-{
- switch (algtag) {
- case SEC_OID_MD2:
- return CKM_MD2_HMAC;
- case SEC_OID_MD5:
- return CKM_MD5_HMAC;
- case SEC_OID_SHA1:
- return CKM_SHA_1_HMAC;
- case SEC_OID_SHA224:
- return CKM_SHA224_HMAC;
- case SEC_OID_SHA256:
- return CKM_SHA256_HMAC;
- case SEC_OID_SHA384:
- return CKM_SHA384_HMAC;
- case SEC_OID_SHA512:
- return CKM_SHA512_HMAC;
- default:
- break;
- }
- return CKM_INVALID_MECHANISM;
-}
-
-/* helper functions */
-/* returns proper bag type template based upon object type tag */
-const SEC_ASN1Template *
-sec_pkcs12_choose_bag_type_old(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- SEC_PKCS12SafeBag *safebag;
- SECOidData *oiddata;
-
- if (src_or_dest == NULL) {
- return NULL;
- }
-
- safebag = (SEC_PKCS12SafeBag*)src_or_dest;
-
- oiddata = safebag->safeBagTypeTag;
- if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&safebag->safeBagType);
- safebag->safeBagTypeTag = oiddata;
- }
-
- switch (oiddata->offset) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
- break;
- case SEC_OID_PKCS12_KEY_BAG_ID:
- theTemplate = SEC_PointerToPKCS12KeyBagTemplate;
- break;
- case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID:
- theTemplate = SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD;
- break;
- case SEC_OID_PKCS12_SECRET_BAG_ID:
- theTemplate = SEC_PointerToPKCS12SecretBagTemplate;
- break;
- }
- return theTemplate;
-}
-
-const SEC_ASN1Template *
-sec_pkcs12_choose_bag_type(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- SEC_PKCS12SafeBag *safebag;
- SECOidData *oiddata;
-
- if (src_or_dest == NULL) {
- return NULL;
- }
-
- safebag = (SEC_PKCS12SafeBag*)src_or_dest;
-
- oiddata = safebag->safeBagTypeTag;
- if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&safebag->safeBagType);
- safebag->safeBagTypeTag = oiddata;
- }
-
- switch (oiddata->offset) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
- break;
- case SEC_OID_PKCS12_KEY_BAG_ID:
- theTemplate = SEC_PKCS12PrivateKeyBagTemplate;
- break;
- case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID:
- theTemplate = SEC_PKCS12CertAndCRLBagTemplate;
- break;
- case SEC_OID_PKCS12_SECRET_BAG_ID:
- theTemplate = SEC_PKCS12SecretBagTemplate;
- break;
- }
- return theTemplate;
-}
-
-/* returns proper cert crl template based upon type tag */
-const SEC_ASN1Template *
-sec_pkcs12_choose_cert_crl_type_old(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- SEC_PKCS12CertAndCRL *certbag;
- SECOidData *oiddata;
-
- if (src_or_dest == NULL) {
- return NULL;
- }
-
- certbag = (SEC_PKCS12CertAndCRL*)src_or_dest;
- oiddata = certbag->BagTypeTag;
- if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&certbag->BagID);
- certbag->BagTypeTag = oiddata;
- }
-
- switch (oiddata->offset) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
- break;
- case SEC_OID_PKCS12_X509_CERT_CRL_BAG:
- theTemplate = SEC_PointerToPKCS12X509CertCRLTemplate_OLD;
- break;
- case SEC_OID_PKCS12_SDSI_CERT_BAG:
- theTemplate = SEC_PointerToPKCS12SDSICertTemplate;
- break;
- }
- return theTemplate;
-}
-
-const SEC_ASN1Template *
-sec_pkcs12_choose_cert_crl_type(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- SEC_PKCS12CertAndCRL *certbag;
- SECOidData *oiddata;
-
- if (src_or_dest == NULL) {
- return NULL;
- }
-
- certbag = (SEC_PKCS12CertAndCRL*)src_or_dest;
- oiddata = certbag->BagTypeTag;
- if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&certbag->BagID);
- certbag->BagTypeTag = oiddata;
- }
-
- switch (oiddata->offset) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
- break;
- case SEC_OID_PKCS12_X509_CERT_CRL_BAG:
- theTemplate = SEC_PointerToPKCS12X509CertCRLTemplate;
- break;
- case SEC_OID_PKCS12_SDSI_CERT_BAG:
- theTemplate = SEC_PointerToPKCS12SDSICertTemplate;
- break;
- }
- return theTemplate;
-}
-
-/* returns appropriate shroud template based on object type tag */
-const SEC_ASN1Template *
-sec_pkcs12_choose_shroud_type(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- SEC_PKCS12ESPVKItem *espvk;
- SECOidData *oiddata;
-
- if (src_or_dest == NULL) {
- return NULL;
- }
-
- espvk = (SEC_PKCS12ESPVKItem*)src_or_dest;
- oiddata = espvk->espvkTag;
- if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&espvk->espvkOID);
- espvk->espvkTag = oiddata;
- }
-
- switch (oiddata->offset) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
- break;
- case SEC_OID_PKCS12_PKCS8_KEY_SHROUDING:
- theTemplate =
- SEC_ASN1_GET(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate);
- break;
- }
- return theTemplate;
-}
-
-/* generate SALT placing it into the character array passed in.
- * it is assumed that salt_dest is an array of appropriate size
- * XXX We might want to generate our own random context
- */
-SECItem *
-sec_pkcs12_generate_salt(void)
-{
- SECItem *salt;
-
- salt = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(salt == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
- salt->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- SALT_LENGTH);
- salt->len = SALT_LENGTH;
- if(salt->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- SECITEM_ZfreeItem(salt, PR_TRUE);
- return NULL;
- }
-
- PK11_GenerateRandom(salt->data, salt->len);
-
- return salt;
-}
-
-/* generate KEYS -- as per PKCS12 section 7.
- * only used for MAC
- */
-SECItem *
-sec_pkcs12_generate_key_from_password(SECOidTag algorithm,
- SECItem *salt,
- SECItem *password)
-{
- unsigned char *pre_hash=NULL;
- unsigned char *hash_dest=NULL;
- SECStatus res;
- PRArenaPool *poolp;
- SECItem *key = NULL;
- int key_len = 0;
-
- if((salt == NULL) || (password == NULL)) {
- return NULL;
- }
-
- poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(poolp == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- pre_hash = (unsigned char *)PORT_ArenaZAlloc(poolp, sizeof(char) *
- (salt->len+password->len));
- if(pre_hash == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- hash_dest = (unsigned char *)PORT_ArenaZAlloc(poolp,
- sizeof(unsigned char) * SHA1_LENGTH);
- if(hash_dest == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- PORT_Memcpy(pre_hash, salt->data, salt->len);
- /* handle password of 0 length case */
- if(password->len > 0) {
- PORT_Memcpy(&(pre_hash[salt->len]), password->data, password->len);
- }
-
- res = PK11_HashBuf(SEC_OID_SHA1, hash_dest, pre_hash,
- (salt->len+password->len));
- if(res == SECFailure) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- switch(algorithm) {
- case SEC_OID_SHA1:
- if(key_len == 0)
- key_len = 16;
- key = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(key == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- key->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char)
- * key_len);
- if(key->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- key->len = key_len;
- PORT_Memcpy(key->data, &hash_dest[SHA1_LENGTH-key->len], key->len);
- break;
- default:
- goto loser;
- break;
- }
-
- PORT_FreeArena(poolp, PR_TRUE);
- return key;
-
-loser:
- PORT_FreeArena(poolp, PR_TRUE);
- if(key != NULL) {
- SECITEM_ZfreeItem(key, PR_TRUE);
- }
- return NULL;
-}
-
-/* MAC is generated per PKCS 12 section 6. It is expected that key, msg
- * and mac_dest are pre allocated, non-NULL arrays. msg_len is passed in
- * because it is not known how long the message actually is. String
- * manipulation routines will not necessarily work because msg may have
- * imbedded NULLs
- */
-static SECItem *
-sec_pkcs12_generate_old_mac(SECItem *key,
- SECItem *msg)
-{
- SECStatus res;
- PRArenaPool *temparena = NULL;
- unsigned char *hash_dest=NULL, *hash_src1=NULL, *hash_src2 = NULL;
- int i;
- SECItem *mac = NULL;
-
- if((key == NULL) || (msg == NULL))
- goto loser;
-
- /* allocate return item */
- mac = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(mac == NULL)
- return NULL;
- mac->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char)
- * SHA1_LENGTH);
- mac->len = SHA1_LENGTH;
- if(mac->data == NULL)
- goto loser;
-
- /* allocate temporary items */
- temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(temparena == NULL)
- goto loser;
-
- hash_src1 = (unsigned char *)PORT_ArenaZAlloc(temparena,
- sizeof(unsigned char) * (16+msg->len));
- if(hash_src1 == NULL)
- goto loser;
-
- hash_src2 = (unsigned char *)PORT_ArenaZAlloc(temparena,
- sizeof(unsigned char) * (SHA1_LENGTH+16));
- if(hash_src2 == NULL)
- goto loser;
-
- hash_dest = (unsigned char *)PORT_ArenaZAlloc(temparena,
- sizeof(unsigned char) * SHA1_LENGTH);
- if(hash_dest == NULL)
- goto loser;
-
- /* perform mac'ing as per PKCS 12 */
-
- /* first round of hashing */
- for(i = 0; i < 16; i++)
- hash_src1[i] = key->data[i] ^ 0x36;
- PORT_Memcpy(&(hash_src1[16]), msg->data, msg->len);
- res = PK11_HashBuf(SEC_OID_SHA1, hash_dest, hash_src1, (16+msg->len));
- if(res == SECFailure)
- goto loser;
-
- /* second round of hashing */
- for(i = 0; i < 16; i++)
- hash_src2[i] = key->data[i] ^ 0x5c;
- PORT_Memcpy(&(hash_src2[16]), hash_dest, SHA1_LENGTH);
- res = PK11_HashBuf(SEC_OID_SHA1, mac->data, hash_src2, SHA1_LENGTH+16);
- if(res == SECFailure)
- goto loser;
-
- PORT_FreeArena(temparena, PR_TRUE);
- return mac;
-
-loser:
- if(temparena != NULL)
- PORT_FreeArena(temparena, PR_TRUE);
- if(mac != NULL)
- SECITEM_ZfreeItem(mac, PR_TRUE);
- return NULL;
-}
-
-/* MAC is generated per PKCS 12 section 6. It is expected that key, msg
- * and mac_dest are pre allocated, non-NULL arrays. msg_len is passed in
- * because it is not known how long the message actually is. String
- * manipulation routines will not necessarily work because msg may have
- * imbedded NULLs
- */
-SECItem *
-sec_pkcs12_generate_mac(SECItem *key,
- SECItem *msg,
- PRBool old_method)
-{
- SECStatus res = SECFailure;
- SECItem *mac = NULL;
- PK11Context *pk11cx = NULL;
- SECItem ignore = {0};
-
- if((key == NULL) || (msg == NULL)) {
- return NULL;
- }
-
- if(old_method == PR_TRUE) {
- return sec_pkcs12_generate_old_mac(key, msg);
- }
-
- /* allocate return item */
- mac = SECITEM_AllocItem(NULL, NULL, SHA1_LENGTH);
- if (mac == NULL) {
- return NULL;
- }
-
- pk11cx = PK11_CreateContextByRawKey(NULL, CKM_SHA_1_HMAC, PK11_OriginDerive,
- CKA_SIGN, key, &ignore, NULL);
- if (pk11cx == NULL) {
- goto loser;
- }
-
- res = PK11_DigestBegin(pk11cx);
- if (res == SECFailure) {
- goto loser;
- }
-
- res = PK11_DigestOp(pk11cx, msg->data, msg->len);
- if (res == SECFailure) {
- goto loser;
- }
-
- res = PK11_DigestFinal(pk11cx, mac->data, &mac->len, SHA1_LENGTH);
- if (res == SECFailure) {
- goto loser;
- }
-
- PK11_DestroyContext(pk11cx, PR_TRUE);
- pk11cx = NULL;
-
-loser:
-
- if(res != SECSuccess) {
- SECITEM_ZfreeItem(mac, PR_TRUE);
- mac = NULL;
- if (pk11cx) {
- PK11_DestroyContext(pk11cx, PR_TRUE);
- }
- }
-
- return mac;
-}
-
-/* compute the thumbprint of the DER cert and create a digest info
- * to store it in and return the digest info.
- * a return of NULL indicates an error.
- */
-SGNDigestInfo *
-sec_pkcs12_compute_thumbprint(SECItem *der_cert)
-{
- SGNDigestInfo *thumb = NULL;
- SECItem digest;
- PRArenaPool *temparena = NULL;
- SECStatus rv = SECFailure;
-
- if(der_cert == NULL)
- return NULL;
-
- temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(temparena == NULL) {
- return NULL;
- }
-
- digest.data = (unsigned char *)PORT_ArenaZAlloc(temparena,
- sizeof(unsigned char) *
- SHA1_LENGTH);
- /* digest data and create digest info */
- if(digest.data != NULL) {
- digest.len = SHA1_LENGTH;
- rv = PK11_HashBuf(SEC_OID_SHA1, digest.data, der_cert->data,
- der_cert->len);
- if(rv == SECSuccess) {
- thumb = SGN_CreateDigestInfo(SEC_OID_SHA1,
- digest.data,
- digest.len);
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
-
- PORT_FreeArena(temparena, PR_TRUE);
-
- return thumb;
-}
-
-/* create a virtual password per PKCS 12, the password is converted
- * to unicode, the salt is prepended to it, and then the whole thing
- * is returned */
-SECItem *
-sec_pkcs12_create_virtual_password(SECItem *password, SECItem *salt,
- PRBool swap)
-{
- SECItem uniPwd = {siBuffer, NULL,0}, *retPwd = NULL;
-
- if((password == NULL) || (salt == NULL)) {
- return NULL;
- }
-
- if(password->len == 0) {
- uniPwd.data = (unsigned char*)PORT_ZAlloc(2);
- uniPwd.len = 2;
- if(!uniPwd.data) {
- return NULL;
- }
- } else {
- uniPwd.data = (unsigned char*)PORT_ZAlloc(password->len * 3);
- uniPwd.len = password->len * 3;
- if(!PORT_UCS2_ASCIIConversion(PR_TRUE, password->data, password->len,
- uniPwd.data, uniPwd.len, &uniPwd.len, swap)) {
- SECITEM_ZfreeItem(&uniPwd, PR_FALSE);
- return NULL;
- }
- }
-
- retPwd = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(retPwd == NULL) {
- goto loser;
- }
-
- /* allocate space and copy proper data */
- retPwd->len = uniPwd.len + salt->len;
- retPwd->data = (unsigned char *)PORT_Alloc(retPwd->len);
- if(retPwd->data == NULL) {
- PORT_Free(retPwd);
- goto loser;
- }
-
- PORT_Memcpy(retPwd->data, salt->data, salt->len);
- PORT_Memcpy((retPwd->data + salt->len), uniPwd.data, uniPwd.len);
-
- SECITEM_ZfreeItem(&uniPwd, PR_FALSE);
-
- return retPwd;
-
-loser:
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- SECITEM_ZfreeItem(&uniPwd, PR_FALSE);
- return NULL;
-}
-
-/* appends a shrouded key to a key bag. this is used for exporting
- * to store externally wrapped keys. it is used when importing to convert
- * old items to new
- */
-SECStatus
-sec_pkcs12_append_shrouded_key(SEC_PKCS12BaggageItem *bag,
- SEC_PKCS12ESPVKItem *espvk)
-{
- int size;
- void *mark = NULL, *dummy = NULL;
-
- if((bag == NULL) || (espvk == NULL))
- return SECFailure;
-
- mark = PORT_ArenaMark(bag->poolp);
-
- /* grow the list */
- size = (bag->nEspvks + 1) * sizeof(SEC_PKCS12ESPVKItem *);
- dummy = (SEC_PKCS12ESPVKItem **)PORT_ArenaGrow(bag->poolp,
- bag->espvks, size,
- size + sizeof(SEC_PKCS12ESPVKItem *));
- bag->espvks = (SEC_PKCS12ESPVKItem**)dummy;
- if(dummy == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- bag->espvks[bag->nEspvks] = espvk;
- bag->nEspvks++;
- bag->espvks[bag->nEspvks] = NULL;
-
- PORT_ArenaUnmark(bag->poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(bag->poolp, mark);
- return SECFailure;
-}
-
-/* search a certificate list for a nickname, a thumbprint, or both
- * within a certificate bag. if the certificate could not be
- * found or an error occurs, NULL is returned;
- */
-static SEC_PKCS12CertAndCRL *
-sec_pkcs12_find_cert_in_certbag(SEC_PKCS12CertAndCRLBag *certbag,
- SECItem *nickname, SGNDigestInfo *thumbprint)
-{
- PRBool search_both = PR_FALSE, search_nickname = PR_FALSE;
- int i, j;
-
- if((certbag == NULL) || ((nickname == NULL) && (thumbprint == NULL))) {
- return NULL;
- }
-
- if(thumbprint && nickname) {
- search_both = PR_TRUE;
- }
-
- if(nickname) {
- search_nickname = PR_TRUE;
- }
-
-search_again:
- i = 0;
- while(certbag->certAndCRLs[i] != NULL) {
- SEC_PKCS12CertAndCRL *cert = certbag->certAndCRLs[i];
-
- if(SECOID_FindOIDTag(&cert->BagID) == SEC_OID_PKCS12_X509_CERT_CRL_BAG) {
-
- /* check nicknames */
- if(search_nickname) {
- if(SECITEM_CompareItem(nickname, &cert->nickname) == SECEqual) {
- return cert;
- }
- } else {
- /* check thumbprints */
- SECItem **derCertList;
-
- /* get pointer to certificate list, does not need to
- * be freed since it is within the arena which will
- * be freed later.
- */
- derCertList = SEC_PKCS7GetCertificateList(&cert->value.x509->certOrCRL);
- j = 0;
- if(derCertList != NULL) {
- while(derCertList[j] != NULL) {
- SECComparison eq;
- SGNDigestInfo *di;
- di = sec_pkcs12_compute_thumbprint(derCertList[j]);
- if(di) {
- eq = SGN_CompareDigestInfo(thumbprint, di);
- SGN_DestroyDigestInfo(di);
- if(eq == SECEqual) {
- /* copy the derCert for later reference */
- cert->value.x509->derLeafCert = derCertList[j];
- return cert;
- }
- } else {
- /* an error occurred */
- return NULL;
- }
- j++;
- }
- }
- }
- }
-
- i++;
- }
-
- if(search_both) {
- search_both = PR_FALSE;
- search_nickname = PR_FALSE;
- goto search_again;
- }
-
- return NULL;
-}
-
-/* search a key list for a nickname, a thumbprint, or both
- * within a key bag. if the key could not be
- * found or an error occurs, NULL is returned;
- */
-static SEC_PKCS12PrivateKey *
-sec_pkcs12_find_key_in_keybag(SEC_PKCS12PrivateKeyBag *keybag,
- SECItem *nickname, SGNDigestInfo *thumbprint)
-{
- PRBool search_both = PR_FALSE, search_nickname = PR_FALSE;
- int i, j;
-
- if((keybag == NULL) || ((nickname == NULL) && (thumbprint == NULL))) {
- return NULL;
- }
-
- if(keybag->privateKeys == NULL) {
- return NULL;
- }
-
- if(thumbprint && nickname) {
- search_both = PR_TRUE;
- }
-
- if(nickname) {
- search_nickname = PR_TRUE;
- }
-
-search_again:
- i = 0;
- while(keybag->privateKeys[i] != NULL) {
- SEC_PKCS12PrivateKey *key = keybag->privateKeys[i];
-
- /* check nicknames */
- if(search_nickname) {
- if(SECITEM_CompareItem(nickname, &key->pvkData.nickname) == SECEqual) {
- return key;
- }
- } else {
- /* check digests */
- SGNDigestInfo **assocCerts = key->pvkData.assocCerts;
- if((assocCerts == NULL) || (assocCerts[0] == NULL)) {
- return NULL;
- }
-
- j = 0;
- while(assocCerts[j] != NULL) {
- SECComparison eq;
- eq = SGN_CompareDigestInfo(thumbprint, assocCerts[j]);
- if(eq == SECEqual) {
- return key;
- }
- j++;
- }
- }
- i++;
- }
-
- if(search_both) {
- search_both = PR_FALSE;
- search_nickname = PR_FALSE;
- goto search_again;
- }
-
- return NULL;
-}
-
-/* seach the safe first then try the baggage bag
- * safe and bag contain certs and keys to search
- * objType is the object type to look for
- * bagType is the type of bag that was found by sec_pkcs12_find_object
- * index is the entity in safe->safeContents or bag->unencSecrets which
- * is being searched
- * nickname and thumbprint are the search criteria
- *
- * a return of null indicates no match
- */
-static void *
-sec_pkcs12_try_find(SEC_PKCS12SafeContents *safe,
- SEC_PKCS12BaggageItem *bag,
- SECOidTag objType, SECOidTag bagType, int index,
- SECItem *nickname, SGNDigestInfo *thumbprint)
-{
- PRBool searchSafe;
- int i = index;
-
- if((safe == NULL) && (bag == NULL)) {
- return NULL;
- }
-
- searchSafe = (safe == NULL ? PR_FALSE : PR_TRUE);
- switch(objType) {
- case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID:
- if(objType == bagType) {
- SEC_PKCS12CertAndCRLBag *certBag;
-
- if(searchSafe) {
- certBag = safe->contents[i]->safeContent.certAndCRLBag;
- } else {
- certBag = bag->unencSecrets[i]->safeContent.certAndCRLBag;
- }
- return sec_pkcs12_find_cert_in_certbag(certBag, nickname,
- thumbprint);
- }
- break;
- case SEC_OID_PKCS12_KEY_BAG_ID:
- if(objType == bagType) {
- SEC_PKCS12PrivateKeyBag *keyBag;
-
- if(searchSafe) {
- keyBag = safe->contents[i]->safeContent.keyBag;
- } else {
- keyBag = bag->unencSecrets[i]->safeContent.keyBag;
- }
- return sec_pkcs12_find_key_in_keybag(keyBag, nickname,
- thumbprint);
- }
- break;
- default:
- break;
- }
-
- return NULL;
-}
-
-/* searches both the baggage and the safe areas looking for
- * object of specified type matching either the nickname or the
- * thumbprint specified.
- *
- * safe and baggage store certs and keys
- * objType is the OID for the bag type to be searched:
- * SEC_OID_PKCS12_KEY_BAG_ID, or
- * SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID
- * nickname and thumbprint are the search criteria
- *
- * if no match found, NULL returned and error set
- */
-void *
-sec_pkcs12_find_object(SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage,
- SECOidTag objType,
- SECItem *nickname,
- SGNDigestInfo *thumbprint)
-{
- int i, j;
- void *retItem;
-
- if(((safe == NULL) && (thumbprint == NULL)) ||
- ((nickname == NULL) && (thumbprint == NULL))) {
- return NULL;
- }
-
- i = 0;
- if((safe != NULL) && (safe->contents != NULL)) {
- while(safe->contents[i] != NULL) {
- SECOidTag bagType = SECOID_FindOIDTag(&safe->contents[i]->safeBagType);
- retItem = sec_pkcs12_try_find(safe, NULL, objType, bagType, i,
- nickname, thumbprint);
- if(retItem != NULL) {
- return retItem;
- }
- i++;
- }
- }
-
- if((baggage != NULL) && (baggage->bags != NULL)) {
- i = 0;
- while(baggage->bags[i] != NULL) {
- SEC_PKCS12BaggageItem *xbag = baggage->bags[i];
- j = 0;
- if(xbag->unencSecrets != NULL) {
- while(xbag->unencSecrets[j] != NULL) {
- SECOidTag bagType;
- bagType = SECOID_FindOIDTag(&xbag->unencSecrets[j]->safeBagType);
- retItem = sec_pkcs12_try_find(NULL, xbag, objType, bagType,
- j, nickname, thumbprint);
- if(retItem != NULL) {
- return retItem;
- }
- j++;
- }
- }
- i++;
- }
- }
-
- PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME);
- return NULL;
-}
-
-/* this function converts a password to unicode and encures that the
- * required double 0 byte be placed at the end of the string
- */
-PRBool
-sec_pkcs12_convert_item_to_unicode(PRArenaPool *arena, SECItem *dest,
- SECItem *src, PRBool zeroTerm,
- PRBool asciiConvert, PRBool toUnicode)
-{
- PRBool success = PR_FALSE;
- if(!src || !dest) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return PR_FALSE;
- }
-
- dest->len = src->len * 3 + 2;
- if(arena) {
- dest->data = (unsigned char*)PORT_ArenaZAlloc(arena, dest->len);
- } else {
- dest->data = (unsigned char*)PORT_ZAlloc(dest->len);
- }
-
- if(!dest->data) {
- dest->len = 0;
- return PR_FALSE;
- }
-
- if(!asciiConvert) {
- success = PORT_UCS2_UTF8Conversion(toUnicode, src->data, src->len, dest->data,
- dest->len, &dest->len);
- } else {
-#ifndef IS_LITTLE_ENDIAN
- PRBool swapUnicode = PR_FALSE;
-#else
- PRBool swapUnicode = PR_TRUE;
-#endif
- success = PORT_UCS2_ASCIIConversion(toUnicode, src->data, src->len, dest->data,
- dest->len, &dest->len, swapUnicode);
- }
-
- if(!success) {
- if(!arena) {
- PORT_Free(dest->data);
- dest->data = NULL;
- dest->len = 0;
- }
- return PR_FALSE;
- }
-
- if((dest->data[dest->len-1] || dest->data[dest->len-2]) && zeroTerm) {
- if(dest->len + 2 > 3 * src->len) {
- if(arena) {
- dest->data = (unsigned char*)PORT_ArenaGrow(arena,
- dest->data, dest->len,
- dest->len + 2);
- } else {
- dest->data = (unsigned char*)PORT_Realloc(dest->data,
- dest->len + 2);
- }
-
- if(!dest->data) {
- return PR_FALSE;
- }
- }
- dest->len += 2;
- dest->data[dest->len-1] = dest->data[dest->len-2] = 0;
- }
-
- return PR_TRUE;
-}
-
-/* pkcs 12 templates */
-static const SEC_ASN1TemplateChooserPtr sec_pkcs12_shroud_chooser =
- sec_pkcs12_choose_shroud_type;
-
-const SEC_ASN1Template SEC_PKCS12CodedSafeBagTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SafeBag) },
- { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12SafeBag, safeBagType) },
- { SEC_ASN1_ANY, offsetof(SEC_PKCS12SafeBag, derSafeContent) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12CodedCertBagTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRL) },
- { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12CertAndCRL, BagID) },
- { SEC_ASN1_ANY, offsetof(SEC_PKCS12CertAndCRL, derValue) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12CodedCertAndCRLBagTemplate[] =
-{
- { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12CertAndCRLBag, certAndCRLs),
- SEC_PKCS12CodedCertBagTemplate },
-};
-
-const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate_OLD[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12ESPVKItem) },
- { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12ESPVKItem, espvkOID) },
- { SEC_ASN1_INLINE, offsetof(SEC_PKCS12ESPVKItem, espvkData),
- SEC_PKCS12PVKSupportingDataTemplate_OLD },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_DYNAMIC | 0, offsetof(SEC_PKCS12ESPVKItem, espvkCipherText),
- &sec_pkcs12_shroud_chooser },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12ESPVKItem) },
- { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12ESPVKItem, espvkOID) },
- { SEC_ASN1_INLINE, offsetof(SEC_PKCS12ESPVKItem, espvkData),
- SEC_PKCS12PVKSupportingDataTemplate },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_DYNAMIC | 0, offsetof(SEC_PKCS12ESPVKItem, espvkCipherText),
- &sec_pkcs12_shroud_chooser },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12PVKAdditionalDataTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PVKAdditionalData) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(SEC_PKCS12PVKAdditionalData, pvkAdditionalType) },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SEC_PKCS12PVKAdditionalData, pvkAdditionalContent) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate_OLD[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PVKSupportingData) },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN ,
- offsetof(SEC_PKCS12PVKSupportingData, assocCerts),
- SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN,
- offsetof(SEC_PKCS12PVKSupportingData, regenerable) },
- { SEC_ASN1_PRINTABLE_STRING,
- offsetof(SEC_PKCS12PVKSupportingData, nickname) },
- { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
- offsetof(SEC_PKCS12PVKSupportingData, pvkAdditionalDER) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PVKSupportingData) },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN ,
- offsetof(SEC_PKCS12PVKSupportingData, assocCerts),
- SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN,
- offsetof(SEC_PKCS12PVKSupportingData, regenerable) },
- { SEC_ASN1_BMP_STRING,
- offsetof(SEC_PKCS12PVKSupportingData, uniNickName) },
- { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
- offsetof(SEC_PKCS12PVKSupportingData, pvkAdditionalDER) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12BaggageItemTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12BaggageItem) },
- { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12BaggageItem, espvks),
- SEC_PKCS12ESPVKItemTemplate },
- { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12BaggageItem, unencSecrets),
- SEC_PKCS12SafeBagTemplate },
- /*{ SEC_ASN1_SET_OF, offsetof(SEC_PKCS12BaggageItem, unencSecrets),
- SEC_PKCS12CodedSafeBagTemplate }, */
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12BaggageTemplate[] =
-{
- { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12Baggage, bags),
- SEC_PKCS12BaggageItemTemplate },
-};
-
-const SEC_ASN1Template SEC_PKCS12BaggageTemplate_OLD[] =
-{
- { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12Baggage_OLD, espvks),
- SEC_PKCS12ESPVKItemTemplate_OLD },
-};
-
-static const SEC_ASN1TemplateChooserPtr sec_pkcs12_bag_chooser =
- sec_pkcs12_choose_bag_type;
-
-static const SEC_ASN1TemplateChooserPtr sec_pkcs12_bag_chooser_old =
- sec_pkcs12_choose_bag_type_old;
-
-const SEC_ASN1Template SEC_PKCS12SafeBagTemplate_OLD[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SafeBag) },
- { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12SafeBag, safeBagType) },
- { SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SEC_PKCS12SafeBag, safeContent),
- &sec_pkcs12_bag_chooser_old },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12SafeBagTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SafeBag) },
- { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12SafeBag, safeBagType) },
- { SEC_ASN1_DYNAMIC | SEC_ASN1_POINTER,
- offsetof(SEC_PKCS12SafeBag, safeContent),
- &sec_pkcs12_bag_chooser },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BMP_STRING,
- offsetof(SEC_PKCS12SafeBag, uniSafeBagName) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate_OLD[] =
-{
- { SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS12SafeContents, contents),
- SEC_PKCS12SafeBagTemplate_OLD }
-};
-
-const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate[] =
-{
- { SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS12SafeContents, contents),
- SEC_PKCS12SafeBagTemplate } /* here */
-};
-
-const SEC_ASN1Template SEC_PKCS12PrivateKeyTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PrivateKey) },
- { SEC_ASN1_INLINE, offsetof(SEC_PKCS12PrivateKey, pvkData),
- SEC_PKCS12PVKSupportingDataTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS12PrivateKey, pkcs8data),
- SEC_ASN1_SUB(SECKEY_PrivateKeyInfoTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12PrivateKeyBagTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PrivateKeyBag) },
- { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12PrivateKeyBag, privateKeys),
- SEC_PKCS12PrivateKeyTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate_OLD[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12X509CertCRL) },
- { SEC_ASN1_INLINE, offsetof(SEC_PKCS12X509CertCRL, certOrCRL),
- sec_PKCS7ContentInfoTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN ,
- offsetof(SEC_PKCS12X509CertCRL, thumbprint),
- SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12X509CertCRL) },
- { SEC_ASN1_INLINE, offsetof(SEC_PKCS12X509CertCRL, certOrCRL),
- sec_PKCS7ContentInfoTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12SDSICertTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12X509CertCRL) },
- { SEC_ASN1_IA5_STRING, offsetof(SEC_PKCS12SDSICert, value) },
- { 0 }
-};
-
-static const SEC_ASN1TemplateChooserPtr sec_pkcs12_cert_crl_chooser_old =
- sec_pkcs12_choose_cert_crl_type_old;
-
-static const SEC_ASN1TemplateChooserPtr sec_pkcs12_cert_crl_chooser =
- sec_pkcs12_choose_cert_crl_type;
-
-const SEC_ASN1Template SEC_PKCS12CertAndCRLTemplate_OLD[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRL) },
- { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12CertAndCRL, BagID) },
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT |
- SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | 0,
- offsetof(SEC_PKCS12CertAndCRL, value),
- &sec_pkcs12_cert_crl_chooser_old },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12CertAndCRLTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRL) },
- { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12CertAndCRL, BagID) },
- { SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SEC_PKCS12CertAndCRL, value),
- &sec_pkcs12_cert_crl_chooser },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12CertAndCRLBagTemplate[] =
-{
- { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12CertAndCRLBag, certAndCRLs),
- SEC_PKCS12CertAndCRLTemplate },
-};
-
-const SEC_ASN1Template SEC_PKCS12CertAndCRLBagTemplate_OLD[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRLBag) },
- { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12CertAndCRLBag, certAndCRLs),
- SEC_PKCS12CertAndCRLTemplate_OLD },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12SecretAdditionalTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SecretAdditional) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(SEC_PKCS12SecretAdditional, secretAdditionalType) },
- { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT,
- offsetof(SEC_PKCS12SecretAdditional, secretAdditionalContent) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12SecretTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12Secret) },
- { SEC_ASN1_BMP_STRING, offsetof(SEC_PKCS12Secret, uniSecretName) },
- { SEC_ASN1_ANY, offsetof(SEC_PKCS12Secret, value) },
- { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
- offsetof(SEC_PKCS12Secret, secretAdditional),
- SEC_PKCS12SecretAdditionalTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12SecretItemTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12Secret) },
- { SEC_ASN1_INLINE | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SEC_PKCS12SecretItem, secret), SEC_PKCS12SecretTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(SEC_PKCS12SecretItem, subFolder), SEC_PKCS12SafeBagTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12SecretBagTemplate[] =
-{
- { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12SecretBag, secrets),
- SEC_PKCS12SecretItemTemplate },
-};
-
-const SEC_ASN1Template SEC_PKCS12MacDataTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PFXItem) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN , offsetof(SEC_PKCS12MacData, safeMac),
- SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
- { SEC_ASN1_BIT_STRING, offsetof(SEC_PKCS12MacData, macSalt) },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12PFXItemTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PFXItem) },
- { SEC_ASN1_OPTIONAL |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SEC_PKCS12PFXItem, macData), SEC_PKCS12MacDataTemplate },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(SEC_PKCS12PFXItem, authSafe),
- sec_PKCS7ContentInfoTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12PFXItemTemplate_OLD[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PFXItem) },
- { SEC_ASN1_OPTIONAL |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(SEC_PKCS12PFXItem, old_safeMac),
- SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_BIT_STRING,
- offsetof(SEC_PKCS12PFXItem, old_macSalt) },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(SEC_PKCS12PFXItem, authSafe),
- sec_PKCS7ContentInfoTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12AuthenticatedSafe) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS12AuthenticatedSafe, version) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_OBJECT_ID,
- offsetof(SEC_PKCS12AuthenticatedSafe, transportMode) },
- { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL,
- offsetof(SEC_PKCS12AuthenticatedSafe, privacySalt) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS12AuthenticatedSafe, baggage.bags),
- SEC_PKCS12BaggageItemTemplate },
- { SEC_ASN1_POINTER,
- offsetof(SEC_PKCS12AuthenticatedSafe, safe),
- sec_PKCS7ContentInfoTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate_OLD[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12AuthenticatedSafe) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS12AuthenticatedSafe, version) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS12AuthenticatedSafe, transportMode) },
- { SEC_ASN1_BIT_STRING,
- offsetof(SEC_PKCS12AuthenticatedSafe, privacySalt) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SEC_PKCS12AuthenticatedSafe, old_baggage),
- SEC_PKCS12BaggageTemplate_OLD },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(SEC_PKCS12AuthenticatedSafe, old_safe),
- sec_PKCS7ContentInfoTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template SEC_PointerToPKCS12KeyBagTemplate[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12PrivateKeyBagTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate_OLD }
-};
-
-const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToPKCS12SecretBagTemplate[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12SecretBagTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate_OLD[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate_OLD }
-};
-
-const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToPKCS12SDSICertTemplate[] =
-{
- { SEC_ASN1_POINTER, 0, SEC_PKCS12SDSICertTemplate }
-};
-
-
diff --git a/security/nss/lib/pkcs12/p12local.h b/security/nss/lib/pkcs12/p12local.h
deleted file mode 100644
index 9b9e7adc4..000000000
--- a/security/nss/lib/pkcs12/p12local.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#ifndef _P12LOCAL_H_
-#define _P12LOCAL_H_
-
-#include "plarena.h"
-#include "secoidt.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "certt.h"
-#include "secpkcs7.h"
-#include "pkcs12.h"
-#include "p12.h"
-
-/* helper functions */
-extern const SEC_ASN1Template *
-sec_pkcs12_choose_bag_type(void *src_or_dest, PRBool encoding);
-extern const SEC_ASN1Template *
-sec_pkcs12_choose_cert_crl_type(void *src_or_dest, PRBool encoding);
-extern const SEC_ASN1Template *
-sec_pkcs12_choose_shroud_type(void *src_or_dest, PRBool encoding);
-extern SECItem *sec_pkcs12_generate_salt(void);
-extern SECItem *sec_pkcs12_generate_key_from_password(SECOidTag algorithm,
- SECItem *salt, SECItem *password);
-extern SECItem *sec_pkcs12_generate_mac(SECItem *key, SECItem *msg,
- PRBool old_method);
-extern SGNDigestInfo *sec_pkcs12_compute_thumbprint(SECItem *der_cert);
-extern SECItem *sec_pkcs12_create_virtual_password(SECItem *password,
- SECItem *salt, PRBool swapUnicodeBytes);
-extern SECStatus sec_pkcs12_append_shrouded_key(SEC_PKCS12BaggageItem *bag,
- SEC_PKCS12ESPVKItem *espvk);
-extern void *sec_pkcs12_find_object(SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage, SECOidTag objType,
- SECItem *nickname, SGNDigestInfo *thumbprint);
-extern PRBool sec_pkcs12_convert_item_to_unicode(PRArenaPool *arena, SECItem *dest,
- SECItem *src, PRBool zeroTerm,
- PRBool asciiConvert, PRBool toUnicode);
-extern CK_MECHANISM_TYPE sec_pkcs12_algtag_to_mech(SECOidTag algtag);
-
-/* create functions */
-extern SEC_PKCS12PFXItem *sec_pkcs12_new_pfx(void);
-extern SEC_PKCS12SafeContents *sec_pkcs12_create_safe_contents(
- PRArenaPool *poolp);
-extern SEC_PKCS12Baggage *sec_pkcs12_create_baggage(PRArenaPool *poolp);
-extern SEC_PKCS12BaggageItem *sec_pkcs12_create_external_bag(SEC_PKCS12Baggage *luggage);
-extern void SEC_PKCS12DestroyPFX(SEC_PKCS12PFXItem *pfx);
-extern SEC_PKCS12AuthenticatedSafe *sec_pkcs12_new_asafe(PRArenaPool *poolp);
-
-/* conversion from old to new */
-extern SEC_PKCS12DecoderContext *
-sec_PKCS12ConvertOldSafeToNew(PRArenaPool *arena, PK11SlotInfo *slot,
- PRBool swapUnicode, SECItem *pwitem,
- void *wincx, SEC_PKCS12SafeContents *safe,
- SEC_PKCS12Baggage *baggage);
-
-#endif
diff --git a/security/nss/lib/pkcs12/p12plcy.c b/security/nss/lib/pkcs12/p12plcy.c
deleted file mode 100644
index 0a7608aaa..000000000
--- a/security/nss/lib/pkcs12/p12plcy.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#include "p12plcy.h"
-#include "secoid.h"
-#include "secport.h"
-#include "secpkcs5.h"
-
-#define PKCS12_NULL 0x0000
-
-typedef struct pkcs12SuiteMapStr {
- SECOidTag algTag;
- unsigned int keyLengthBits; /* in bits */
- unsigned long suite;
- PRBool allowed;
- PRBool preferred;
-} pkcs12SuiteMap;
-
-static pkcs12SuiteMap pkcs12SuiteMaps[] = {
- { SEC_OID_RC4, 40, PKCS12_RC4_40, PR_FALSE, PR_FALSE},
- { SEC_OID_RC4, 128, PKCS12_RC4_128, PR_FALSE, PR_FALSE},
- { SEC_OID_RC2_CBC, 40, PKCS12_RC2_CBC_40, PR_FALSE, PR_TRUE},
- { SEC_OID_RC2_CBC, 128, PKCS12_RC2_CBC_128, PR_FALSE, PR_FALSE},
- { SEC_OID_DES_CBC, 64, PKCS12_DES_56, PR_FALSE, PR_FALSE},
- { SEC_OID_DES_EDE3_CBC, 192, PKCS12_DES_EDE3_168, PR_FALSE, PR_FALSE},
- { SEC_OID_UNKNOWN, 0, PKCS12_NULL, PR_FALSE, PR_FALSE},
- { SEC_OID_UNKNOWN, 0, 0L, PR_FALSE, PR_FALSE}
-};
-
-/* determine if algid is an algorithm which is allowed */
-PRBool
-SEC_PKCS12DecryptionAllowed(SECAlgorithmID *algid)
-{
- unsigned int keyLengthBits;
- SECOidTag algId;
- int i;
-
- algId = SEC_PKCS5GetCryptoAlgorithm(algid);
- if(algId == SEC_OID_UNKNOWN) {
- return PR_FALSE;
- }
-
- keyLengthBits = (unsigned int)(SEC_PKCS5GetKeyLength(algid) * 8);
-
- i = 0;
- while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
- if((pkcs12SuiteMaps[i].algTag == algId) &&
- (pkcs12SuiteMaps[i].keyLengthBits == keyLengthBits)) {
-
- return pkcs12SuiteMaps[i].allowed;
- }
- i++;
- }
-
- return PR_FALSE;
-}
-
-/* is any encryption allowed? */
-PRBool
-SEC_PKCS12IsEncryptionAllowed(void)
-{
- int i;
-
- i = 0;
- while(pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN) {
- if(pkcs12SuiteMaps[i].allowed == PR_TRUE) {
- return PR_TRUE;
- }
- i++;
- }
-
- return PR_FALSE;
-}
-
-
-SECStatus
-SEC_PKCS12EnableCipher(long which, int on)
-{
- int i;
-
- i = 0;
- while(pkcs12SuiteMaps[i].suite != 0L) {
- if(pkcs12SuiteMaps[i].suite == (unsigned long)which) {
- if(on) {
- pkcs12SuiteMaps[i].allowed = PR_TRUE;
- } else {
- pkcs12SuiteMaps[i].allowed = PR_FALSE;
- }
- return SECSuccess;
- }
- i++;
- }
-
- return SECFailure;
-}
-
-SECStatus
-SEC_PKCS12SetPreferredCipher(long which, int on)
-{
- int i;
- PRBool turnedOff = PR_FALSE;
- PRBool turnedOn = PR_FALSE;
-
- i = 0;
- while(pkcs12SuiteMaps[i].suite != 0L) {
- if(pkcs12SuiteMaps[i].preferred == PR_TRUE) {
- pkcs12SuiteMaps[i].preferred = PR_FALSE;
- turnedOff = PR_TRUE;
- }
- if(pkcs12SuiteMaps[i].suite == (unsigned long)which) {
- pkcs12SuiteMaps[i].preferred = PR_TRUE;
- turnedOn = PR_TRUE;
- }
- i++;
- }
-
- if((turnedOn) && (turnedOff)) {
- return SECSuccess;
- }
-
- return SECFailure;
-}
-
diff --git a/security/nss/lib/pkcs12/p12plcy.h b/security/nss/lib/pkcs12/p12plcy.h
deleted file mode 100644
index d3f818d49..000000000
--- a/security/nss/lib/pkcs12/p12plcy.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _P12PLCY_H_
-#define _P12PLCY_H_
-
-#include "secoid.h"
-#include "ciferfam.h"
-
-SEC_BEGIN_PROTOS
-
-/* for the algid specified, can we decrypt it ? */
-extern PRBool SEC_PKCS12DecryptionAllowed(SECAlgorithmID *algid);
-
-/* is encryption allowed? */
-extern PRBool SEC_PKCS12IsEncryptionAllowed(void);
-
-/* enable a cipher for encryption/decryption */
-extern SECStatus SEC_PKCS12EnableCipher(long which, int on);
-
-/* return the preferred cipher for encryption */
-extern SECStatus SEC_PKCS12SetPreferredCipher(long which, int on);
-
-SEC_END_PROTOS
-#endif
diff --git a/security/nss/lib/pkcs12/p12t.h b/security/nss/lib/pkcs12/p12t.h
deleted file mode 100644
index d583f7d2f..000000000
--- a/security/nss/lib/pkcs12/p12t.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _P12T_H_
-#define _P12T_H_
-
-#include "secoid.h"
-#include "key.h"
-#include "pkcs11.h"
-#include "secpkcs7.h"
-#include "secdig.h" /* for SGNDigestInfo */
-#include "pkcs12t.h"
-
-#define SEC_PKCS12_VERSION 3
-
-/* structure declarations */
-typedef struct sec_PKCS12PFXItemStr sec_PKCS12PFXItem;
-typedef struct sec_PKCS12MacDataStr sec_PKCS12MacData;
-typedef struct sec_PKCS12AuthenticatedSafeStr sec_PKCS12AuthenticatedSafe;
-typedef struct sec_PKCS12SafeContentsStr sec_PKCS12SafeContents;
-typedef struct sec_PKCS12SafeBagStr sec_PKCS12SafeBag;
-typedef struct sec_PKCS12PKCS8ShroudedKeyBagStr sec_PKCS12PKCS8ShroudedKeyBag;
-typedef struct sec_PKCS12CertBagStr sec_PKCS12CertBag;
-typedef struct sec_PKCS12CRLBagStr sec_PKCS12CRLBag;
-typedef struct sec_PKCS12SecretBag sec_PKCS12SecretBag;
-typedef struct sec_PKCS12AttributeStr sec_PKCS12Attribute;
-
-struct sec_PKCS12CertBagStr {
- /* what type of cert is stored? */
- SECItem bagID;
-
- /* certificate information */
- union {
- SECItem x509Cert;
- SECItem SDSICert;
- } value;
-};
-
-struct sec_PKCS12CRLBagStr {
- /* what type of cert is stored? */
- SECItem bagID;
-
- /* certificate information */
- union {
- SECItem x509CRL;
- } value;
-};
-
-struct sec_PKCS12SecretBag {
- /* what type of secret? */
- SECItem secretType;
-
- /* secret information. ssshhhh be vewy vewy quiet. */
- SECItem secretContent;
-};
-
-struct sec_PKCS12AttributeStr {
- SECItem attrType;
- SECItem **attrValue;
-};
-
-struct sec_PKCS12SafeBagStr {
-
- /* What type of bag are we using? */
- SECItem safeBagType;
-
- /* Dependent upon the type of bag being used. */
- union {
- SECKEYPrivateKeyInfo *pkcs8KeyBag;
- SECKEYEncryptedPrivateKeyInfo *pkcs8ShroudedKeyBag;
- sec_PKCS12CertBag *certBag;
- sec_PKCS12CRLBag *crlBag;
- sec_PKCS12SecretBag *secretBag;
- sec_PKCS12SafeContents *safeContents;
- } safeBagContent;
-
- sec_PKCS12Attribute **attribs;
-
- /* used locally */
- SECOidData *bagTypeTag;
- PLArenaPool *arena;
- unsigned int nAttribs;
-
- /* used for validation/importing */
- PRBool problem, noInstall, validated, hasKey, unused, installed;
- int error;
-
- PRBool swapUnicodeBytes;
- PK11SlotInfo *slot;
- SECItem *pwitem;
- PRBool oldBagType;
- SECPKCS12TargetTokenCAs tokenCAs;
-};
-
-struct sec_PKCS12SafeContentsStr {
- sec_PKCS12SafeBag **safeBags;
- SECItem **encodedSafeBags;
-
- /* used locally */
- PLArenaPool *arena;
- unsigned int bagCount;
-};
-
-struct sec_PKCS12MacDataStr {
- SGNDigestInfo safeMac;
- SECItem macSalt;
- SECItem iter;
-};
-
-struct sec_PKCS12PFXItemStr {
-
- SECItem version;
-
- /* Content type will either be Data (password integrity mode)
- * or signedData (public-key integrity mode)
- */
- SEC_PKCS7ContentInfo *authSafe;
- SECItem encodedAuthSafe;
-
- /* Only present in password integrity mode */
- sec_PKCS12MacData macData;
- SECItem encodedMacData;
-};
-
-struct sec_PKCS12AuthenticatedSafeStr {
- /* Content type will either be encryptedData (password privacy mode)
- * or envelopedData (public-key privacy mode)
- */
- SEC_PKCS7ContentInfo **safes;
- SECItem **encodedSafes;
-
- /* used locally */
- unsigned int safeCount;
- SECItem dummySafe;
-};
-
-extern const SEC_ASN1Template sec_PKCS12PFXItemTemplate[];
-extern const SEC_ASN1Template sec_PKCS12MacDataTemplate[];
-extern const SEC_ASN1Template sec_PKCS12AuthenticatedSafeTemplate[];
-extern const SEC_ASN1Template sec_PKCS12SafeContentsTemplate[];
-extern const SEC_ASN1Template sec_PKCS12SafeContentsDecodeTemplate[];
-extern const SEC_ASN1Template sec_PKCS12NestedSafeContentsDecodeTemplate[];
-extern const SEC_ASN1Template sec_PKCS12CertBagTemplate[];
-extern const SEC_ASN1Template sec_PKCS12CRLBagTemplate[];
-extern const SEC_ASN1Template sec_PKCS12SecretBagTemplate[];
-extern const SEC_ASN1Template sec_PKCS12PointerToCertBagTemplate[];
-extern const SEC_ASN1Template sec_PKCS12PointerToCRLBagTemplate[];
-extern const SEC_ASN1Template sec_PKCS12PointerToSecretBagTemplate[];
-extern const SEC_ASN1Template sec_PKCS12PointerToSafeContentsTemplate[];
-extern const SEC_ASN1Template sec_PKCS12AttributeTemplate[];
-extern const SEC_ASN1Template sec_PKCS12PointerToContentInfoTemplate[];
-extern const SEC_ASN1Template sec_PKCS12SafeBagTemplate[];
-
-#endif
diff --git a/security/nss/lib/pkcs12/p12tmpl.c b/security/nss/lib/pkcs12/p12tmpl.c
deleted file mode 100644
index 184e0d4d8..000000000
--- a/security/nss/lib/pkcs12/p12tmpl.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "plarena.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "seccomon.h"
-#include "secport.h"
-#include "cert.h"
-#include "secpkcs7.h"
-#include "secasn1.h"
-#include "p12t.h"
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(sgn_DigestInfoTemplate)
-
-static const SEC_ASN1Template *
-sec_pkcs12_choose_safe_bag_type(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- sec_PKCS12SafeBag *safeBag;
- SECOidData *oiddata;
-
- if (src_or_dest == NULL) {
- return NULL;
- }
-
- safeBag = (sec_PKCS12SafeBag*)src_or_dest;
-
- oiddata = SECOID_FindOID(&safeBag->safeBagType);
- if(oiddata == NULL) {
- return SEC_ASN1_GET(SEC_AnyTemplate);
- }
-
- switch (oiddata->offset) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
- break;
- case SEC_OID_PKCS12_V1_KEY_BAG_ID:
- theTemplate = SEC_ASN1_GET(SECKEY_PointerToPrivateKeyInfoTemplate);
- break;
- case SEC_OID_PKCS12_V1_CERT_BAG_ID:
- theTemplate = sec_PKCS12PointerToCertBagTemplate;
- break;
- case SEC_OID_PKCS12_V1_CRL_BAG_ID:
- theTemplate = sec_PKCS12PointerToCRLBagTemplate;
- break;
- case SEC_OID_PKCS12_V1_SECRET_BAG_ID:
- theTemplate = sec_PKCS12PointerToSecretBagTemplate;
- break;
- case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
- theTemplate =
- SEC_ASN1_GET(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate);
- break;
- case SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID:
- if(encoding) {
- theTemplate = sec_PKCS12PointerToSafeContentsTemplate;
- } else {
- theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
- }
- break;
- }
- return theTemplate;
-}
-
-static const SEC_ASN1Template *
-sec_pkcs12_choose_crl_bag_type(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- sec_PKCS12CRLBag *crlbag;
- SECOidData *oiddata;
-
- if (src_or_dest == NULL) {
- return NULL;
- }
-
- crlbag = (sec_PKCS12CRLBag*)src_or_dest;
-
- oiddata = SECOID_FindOID(&crlbag->bagID);
- if(oiddata == NULL) {
- return SEC_ASN1_GET(SEC_AnyTemplate);
- }
-
- switch (oiddata->offset) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
- break;
- case SEC_OID_PKCS9_X509_CRL:
- theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate);
- break;
- }
- return theTemplate;
-}
-
-static const SEC_ASN1Template *
-sec_pkcs12_choose_cert_bag_type(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- sec_PKCS12CertBag *certbag;
- SECOidData *oiddata;
-
- if (src_or_dest == NULL) {
- return NULL;
- }
-
- certbag = (sec_PKCS12CertBag*)src_or_dest;
-
- oiddata = SECOID_FindOID(&certbag->bagID);
- if(oiddata == NULL) {
- return SEC_ASN1_GET(SEC_AnyTemplate);
- }
-
- switch (oiddata->offset) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
- break;
- case SEC_OID_PKCS9_X509_CERT:
- theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate);
- break;
- case SEC_OID_PKCS9_SDSI_CERT:
- theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
- break;
- }
- return theTemplate;
-}
-
-static const SEC_ASN1Template *
-sec_pkcs12_choose_attr_type(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- sec_PKCS12Attribute *attr;
- SECOidData *oiddata;
-
- if (src_or_dest == NULL) {
- return NULL;
- }
-
- attr = (sec_PKCS12Attribute*)src_or_dest;
-
- oiddata = SECOID_FindOID(&attr->attrType);
- if(oiddata == NULL) {
- return SEC_ASN1_GET(SEC_AnyTemplate);
- }
-
- switch (oiddata->offset) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
- break;
- case SEC_OID_PKCS9_FRIENDLY_NAME:
- theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate);
- break;
- case SEC_OID_PKCS9_LOCAL_KEY_ID:
- theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate);
- break;
- case SEC_OID_PKCS12_KEY_USAGE:
- theTemplate = SEC_ASN1_GET(SEC_BitStringTemplate);
- break;
- }
-
- return theTemplate;
-}
-
-
-const SEC_ASN1Template sec_PKCS12PointerToContentInfoTemplate[] = {
- { SEC_ASN1_POINTER | SEC_ASN1_MAY_STREAM, 0, sec_PKCS7ContentInfoTemplate }
-};
-
-static const SEC_ASN1TemplateChooserPtr sec_pkcs12_crl_bag_chooser =
- sec_pkcs12_choose_crl_bag_type;
-
-static const SEC_ASN1TemplateChooserPtr sec_pkcs12_cert_bag_chooser =
- sec_pkcs12_choose_cert_bag_type;
-
-static const SEC_ASN1TemplateChooserPtr sec_pkcs12_safe_bag_chooser =
- sec_pkcs12_choose_safe_bag_type;
-
-static const SEC_ASN1TemplateChooserPtr sec_pkcs12_attr_chooser =
- sec_pkcs12_choose_attr_type;
-
-const SEC_ASN1Template sec_PKCS12PointerToCertBagTemplate[] = {
- { SEC_ASN1_POINTER, 0, sec_PKCS12CertBagTemplate }
-};
-
-const SEC_ASN1Template sec_PKCS12PointerToCRLBagTemplate[] = {
- { SEC_ASN1_POINTER, 0, sec_PKCS12CRLBagTemplate }
-};
-
-const SEC_ASN1Template sec_PKCS12PointerToSecretBagTemplate[] = {
- { SEC_ASN1_POINTER, 0, sec_PKCS12SecretBagTemplate }
-};
-
-const SEC_ASN1Template sec_PKCS12PointerToSafeContentsTemplate[] = {
- { SEC_ASN1_POINTER, 0, sec_PKCS12SafeContentsTemplate }
-};
-
-const SEC_ASN1Template sec_PKCS12PFXItemTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, 0, NULL,
- sizeof(sec_PKCS12PFXItem) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
- offsetof(sec_PKCS12PFXItem, version) },
- { SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM,
- offsetof(sec_PKCS12PFXItem, encodedAuthSafe) },
- { SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM,
- offsetof(sec_PKCS12PFXItem, encodedMacData) },
- { 0 }
-};
-
-const SEC_ASN1Template sec_PKCS12MacDataTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12MacData) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN , offsetof(sec_PKCS12MacData, safeMac),
- SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
- { SEC_ASN1_OCTET_STRING, offsetof(sec_PKCS12MacData, macSalt) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER, offsetof(sec_PKCS12MacData, iter) },
- { 0 }
-};
-
-const SEC_ASN1Template sec_PKCS12AuthenticatedSafeTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_MAY_STREAM | SEC_ASN1_XTRN ,
- offsetof(sec_PKCS12AuthenticatedSafe, encodedSafes),
- SEC_ASN1_SUB(SEC_AnyTemplate) }
-};
-
-const SEC_ASN1Template sec_PKCS12SafeBagTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, 0, NULL,
- sizeof(sec_PKCS12SafeBag) },
- { SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12SafeBag, safeBagType) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_MAY_STREAM | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(sec_PKCS12SafeBag, safeBagContent),
- &sec_pkcs12_safe_bag_chooser },
- { SEC_ASN1_SET_OF | SEC_ASN1_OPTIONAL, offsetof(sec_PKCS12SafeBag, attribs),
- sec_PKCS12AttributeTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template sec_PKCS12SafeContentsTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_MAY_STREAM,
- offsetof(sec_PKCS12SafeContents, safeBags),
- sec_PKCS12SafeBagTemplate }
-};
-
-const SEC_ASN1Template sec_PKCS12SequenceOfAnyTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_MAY_STREAM | SEC_ASN1_XTRN , 0,
- SEC_ASN1_SUB(SEC_AnyTemplate) }
-};
-
-const SEC_ASN1Template sec_PKCS12NestedSafeContentsDecodeTemplate[] = {
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
- offsetof(sec_PKCS12SafeContents, encodedSafeBags),
- sec_PKCS12SequenceOfAnyTemplate }
-};
-
-const SEC_ASN1Template sec_PKCS12SafeContentsDecodeTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_MAY_STREAM | SEC_ASN1_XTRN ,
- offsetof(sec_PKCS12SafeContents, encodedSafeBags),
- SEC_ASN1_SUB(SEC_AnyTemplate) }
-};
-
-const SEC_ASN1Template sec_PKCS12CRLBagTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12CRLBag) },
- { SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12CRLBag, bagID) },
- { SEC_ASN1_DYNAMIC | SEC_ASN1_POINTER,
- offsetof(sec_PKCS12CRLBag, value), &sec_pkcs12_crl_bag_chooser },
- { 0 }
-};
-
-const SEC_ASN1Template sec_PKCS12CertBagTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12CertBag) },
- { SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12CertBag, bagID) },
- { SEC_ASN1_DYNAMIC | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(sec_PKCS12CertBag, value), &sec_pkcs12_cert_bag_chooser },
- { 0 }
-};
-
-const SEC_ASN1Template sec_PKCS12SecretBagTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12SecretBag) },
- { SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12SecretBag, secretType) },
- { SEC_ASN1_ANY, offsetof(sec_PKCS12SecretBag, secretContent) },
- { 0 }
-};
-
-const SEC_ASN1Template sec_PKCS12AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(sec_PKCS12Attribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(sec_PKCS12Attribute, attrType) },
- { SEC_ASN1_SET_OF | SEC_ASN1_DYNAMIC,
- offsetof(sec_PKCS12Attribute, attrValue),
- &sec_pkcs12_attr_chooser },
- { 0 }
-};
diff --git a/security/nss/lib/pkcs12/pkcs12.h b/security/nss/lib/pkcs12/pkcs12.h
deleted file mode 100644
index 5c67de543..000000000
--- a/security/nss/lib/pkcs12/pkcs12.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-#ifndef _PKCS12_H_
-#define _PKCS12_H_
-
-#include "pkcs12t.h"
-#include "p12.h"
-
-SEC_BEGIN_PROTOS
-
-typedef SECItem * (* SEC_PKCS12GetPassword)(void *arg);
-
-/* Decode functions */
-/* Import a PFX item.
- * der_pfx is the der-encoded pfx item to import.
- * pbef, and pbefarg are used to retrieve passwords for the HMAC,
- * and any passwords needed for passing to PKCS5 encryption
- * routines.
- * algorithm is the algorithm by which private keys are stored in
- * the key database. this could be a specific algorithm or could
- * be based on a global setting.
- * slot is the slot to where the certificates will be placed. if NULL,
- * the internal key slot is used.
- * If the process is successful, a SECSuccess is returned, otherwise
- * a failure occurred.
- */
-SECStatus
-SEC_PKCS12PutPFX(SECItem *der_pfx, SECItem *pwitem,
- SEC_PKCS12NicknameCollisionCallback ncCall,
- PK11SlotInfo *slot, void *wincx);
-
-/* check the first two bytes of a file to make sure that it matches
- * the desired header for a PKCS 12 file
- */
-PRBool SEC_PKCS12ValidData(char *buf, int bufLen, long int totalLength);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/pkcs12/pkcs12t.h b/security/nss/lib/pkcs12/pkcs12t.h
deleted file mode 100644
index 60cbee76b..000000000
--- a/security/nss/lib/pkcs12/pkcs12t.h
+++ /dev/null
@@ -1,366 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _PKCS12T_H_
-#define _PKCS12T_H_
-
-#include "seccomon.h"
-#include "secoid.h"
-#include "cert.h"
-#include "key.h"
-#include "plarena.h"
-#include "secpkcs7.h"
-#include "secdig.h" /* for SGNDigestInfo */
-
-typedef enum {
- SECPKCS12TargetTokenNoCAs, /* CA get loaded intothe fixed token,
- * User certs go to target token */
- SECPKCS12TargetTokenIntermediateCAs, /* User certs and intermediates go to
- * target token, root certs got to
- * fixed token */
- SECPKCS12TargetTokenAllCAs /* All certs go to target token */
-} SECPKCS12TargetTokenCAs;
-
-/* PKCS12 Structures */
-typedef struct SEC_PKCS12PFXItemStr SEC_PKCS12PFXItem;
-typedef struct SEC_PKCS12MacDataStr SEC_PKCS12MacData;
-typedef struct SEC_PKCS12AuthenticatedSafeStr SEC_PKCS12AuthenticatedSafe;
-typedef struct SEC_PKCS12BaggageItemStr SEC_PKCS12BaggageItem;
-typedef struct SEC_PKCS12BaggageStr SEC_PKCS12Baggage;
-typedef struct SEC_PKCS12Baggage_OLDStr SEC_PKCS12Baggage_OLD;
-typedef struct SEC_PKCS12ESPVKItemStr SEC_PKCS12ESPVKItem;
-typedef struct SEC_PKCS12PVKSupportingDataStr SEC_PKCS12PVKSupportingData;
-typedef struct SEC_PKCS12PVKAdditionalDataStr SEC_PKCS12PVKAdditionalData;
-typedef struct SEC_PKCS12SafeContentsStr SEC_PKCS12SafeContents;
-typedef struct SEC_PKCS12SafeBagStr SEC_PKCS12SafeBag;
-typedef struct SEC_PKCS12PrivateKeyStr SEC_PKCS12PrivateKey;
-typedef struct SEC_PKCS12PrivateKeyBagStr SEC_PKCS12PrivateKeyBag;
-typedef struct SEC_PKCS12CertAndCRLBagStr SEC_PKCS12CertAndCRLBag;
-typedef struct SEC_PKCS12CertAndCRLStr SEC_PKCS12CertAndCRL;
-typedef struct SEC_PKCS12X509CertCRLStr SEC_PKCS12X509CertCRL;
-typedef struct SEC_PKCS12SDSICertStr SEC_PKCS12SDSICert;
-typedef struct SEC_PKCS12SecretStr SEC_PKCS12Secret;
-typedef struct SEC_PKCS12SecretAdditionalStr SEC_PKCS12SecretAdditional;
-typedef struct SEC_PKCS12SecretItemStr SEC_PKCS12SecretItem;
-typedef struct SEC_PKCS12SecretBagStr SEC_PKCS12SecretBag;
-
-typedef SECItem *(* SEC_PKCS12PasswordFunc)(SECItem *args);
-
-/* PKCS12 types */
-
-/* stores shrouded keys */
-struct SEC_PKCS12BaggageStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12BaggageItem **bags;
-
- int luggage_size; /* used locally */
-};
-
-/* additional data to be associated with keys. currently there
- * is nothing defined to be stored here. allows future expansion.
- */
-struct SEC_PKCS12PVKAdditionalDataStr
-{
- PLArenaPool *poolp;
- SECOidData *pvkAdditionalTypeTag; /* used locally */
- SECItem pvkAdditionalType;
- SECItem pvkAdditionalContent;
-};
-
-/* cert and other supporting data for private keys. used
- * for both shrouded and non-shrouded keys.
- */
-struct SEC_PKCS12PVKSupportingDataStr
-{
- PLArenaPool *poolp;
- SGNDigestInfo **assocCerts;
- SECItem regenerable;
- SECItem nickname;
- SEC_PKCS12PVKAdditionalData pvkAdditional;
- SECItem pvkAdditionalDER;
-
- SECItem uniNickName;
- /* used locally */
- int nThumbs;
-};
-
-/* shrouded key structure. supports only pkcs8 shrouding
- * currently.
- */
-struct SEC_PKCS12ESPVKItemStr
-{
- PLArenaPool *poolp; /* used locally */
- SECOidData *espvkTag; /* used locally */
- SECItem espvkOID;
- SEC_PKCS12PVKSupportingData espvkData;
- union
- {
- SECKEYEncryptedPrivateKeyInfo *pkcs8KeyShroud;
- } espvkCipherText;
-
- PRBool duplicate; /* used locally */
- PRBool problem_cert; /* used locally */
- PRBool single_cert; /* used locally */
- int nCerts; /* used locally */
- SECItem derCert; /* used locally */
-};
-
-/* generic bag store for the safe. safeBagType identifies
- * the type of bag stored.
- */
-struct SEC_PKCS12SafeBagStr
-{
- PLArenaPool *poolp;
- SECOidData *safeBagTypeTag; /* used locally */
- SECItem safeBagType;
- union
- {
- SEC_PKCS12PrivateKeyBag *keyBag;
- SEC_PKCS12CertAndCRLBag *certAndCRLBag;
- SEC_PKCS12SecretBag *secretBag;
- } safeContent;
-
- SECItem derSafeContent;
- SECItem safeBagName;
-
- SECItem uniSafeBagName;
-};
-
-/* stores private keys and certificates in a list. each safebag
- * has an ID identifying the type of content stored.
- */
-struct SEC_PKCS12SafeContentsStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12SafeBag **contents;
-
- /* used for tracking purposes */
- int safe_size;
- PRBool old;
- PRBool swapUnicode;
- PRBool possibleSwapUnicode;
-};
-
-/* private key structure which holds encrypted private key and
- * supporting data including nickname and certificate thumbprint.
- */
-struct SEC_PKCS12PrivateKeyStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12PVKSupportingData pvkData;
- SECKEYPrivateKeyInfo pkcs8data; /* borrowed from PKCS 8 */
-
- PRBool duplicate; /* used locally */
- PRBool problem_cert;/* used locally */
- PRBool single_cert; /* used locally */
- int nCerts; /* used locally */
- SECItem derCert; /* used locally */
-};
-
-/* private key bag, holds a (null terminated) list of private key
- * structures.
- */
-struct SEC_PKCS12PrivateKeyBagStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12PrivateKey **privateKeys;
-
- int bag_size; /* used locally */
-};
-
-/* container to hold certificates. currently supports x509
- * and sdsi certificates
- */
-struct SEC_PKCS12CertAndCRLStr
-{
- PLArenaPool *poolp;
- SECOidData *BagTypeTag; /* used locally */
- SECItem BagID;
- union
- {
- SEC_PKCS12X509CertCRL *x509;
- SEC_PKCS12SDSICert *sdsi;
- } value;
-
- SECItem derValue;
- SECItem nickname; /* used locally */
- PRBool duplicate; /* used locally */
-};
-
-/* x509 certificate structure. typically holds the der encoding
- * of the x509 certificate. thumbprint contains a digest of the
- * certificate
- */
-struct SEC_PKCS12X509CertCRLStr
-{
- PLArenaPool *poolp;
- SEC_PKCS7ContentInfo certOrCRL;
- SGNDigestInfo thumbprint;
-
- SECItem *derLeafCert; /* used locally */
-};
-
-/* sdsi certificate structure. typically holds the der encoding
- * of the sdsi certificate. thumbprint contains a digest of the
- * certificate
- */
-struct SEC_PKCS12SDSICertStr
-{
- PLArenaPool *poolp;
- SECItem value;
- SGNDigestInfo thumbprint;
-};
-
-/* contains a null terminated list of certs and crls */
-struct SEC_PKCS12CertAndCRLBagStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12CertAndCRL **certAndCRLs;
-
- int bag_size; /* used locally */
-};
-
-/* additional secret information. currently no information
- * stored in this structure.
- */
-struct SEC_PKCS12SecretAdditionalStr
-{
- PLArenaPool *poolp;
- SECOidData *secretTypeTag; /* used locally */
- SECItem secretAdditionalType;
- SECItem secretAdditionalContent;
-};
-
-/* secrets container. this will be used to contain currently
- * unspecified secrets. (it's a secret)
- */
-struct SEC_PKCS12SecretStr
-{
- PLArenaPool *poolp;
- SECItem secretName;
- SECItem value;
- SEC_PKCS12SecretAdditional secretAdditional;
-
- SECItem uniSecretName;
-};
-
-struct SEC_PKCS12SecretItemStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12Secret secret;
- SEC_PKCS12SafeBag subFolder;
-};
-
-/* a bag of secrets. holds a null terminated list of secrets.
- */
-struct SEC_PKCS12SecretBagStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12SecretItem **secrets;
-
- int bag_size; /* used locally */
-};
-
-struct SEC_PKCS12MacDataStr
-{
- SGNDigestInfo safeMac;
- SECItem macSalt;
-};
-
-/* outer transfer unit */
-struct SEC_PKCS12PFXItemStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12MacData macData;
- SEC_PKCS7ContentInfo authSafe;
-
- /* for compatibility with beta */
- PRBool old;
- SGNDigestInfo old_safeMac;
- SECItem old_macSalt;
-
- /* compatibility between platforms for unicode swapping */
- PRBool swapUnicode;
-};
-
-struct SEC_PKCS12BaggageItemStr {
- PLArenaPool *poolp;
- SEC_PKCS12ESPVKItem **espvks;
- SEC_PKCS12SafeBag **unencSecrets;
-
- int nEspvks;
- int nSecrets;
-};
-
-/* stores shrouded keys */
-struct SEC_PKCS12Baggage_OLDStr
-{
- PLArenaPool *poolp;
- SEC_PKCS12ESPVKItem **espvks;
-
- int luggage_size; /* used locally */
-};
-
-/* authenticated safe, stores certs, keys, and shrouded keys */
-struct SEC_PKCS12AuthenticatedSafeStr
-{
- PLArenaPool *poolp;
- SECItem version;
- SECOidData *transportTypeTag; /* local not part of encoding*/
- SECItem transportMode;
- SECItem privacySalt;
- SEC_PKCS12Baggage baggage;
- SEC_PKCS7ContentInfo *safe;
-
- /* used for beta compatibility */
- PRBool old;
- PRBool emptySafe;
- SEC_PKCS12Baggage_OLD old_baggage;
- SEC_PKCS7ContentInfo old_safe;
- PRBool swapUnicode;
-};
-#define SEC_PKCS12_PFX_VERSION 1 /* what we create */
-
-
-
-/* PKCS 12 Templates */
-extern const SEC_ASN1Template SEC_PKCS12PFXItemTemplate_OLD[];
-extern const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate_OLD[];
-extern const SEC_ASN1Template SEC_PKCS12BaggageTemplate_OLD[];
-extern const SEC_ASN1Template SEC_PKCS12PFXItemTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12MacDataTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12BaggageTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12PVKAdditionalTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate_OLD[];
-extern const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12SafeBagTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12PrivateKeyTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12PrivateKeyBagTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12CertAndCRLTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12CertAndCRLBagTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate_OLD[];
-extern const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12SDSICertTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12SecretBagTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12SecretTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12SecretItemTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12SecretAdditionalTemplate[];
-extern const SEC_ASN1Template SGN_DigestInfoTemplate[];
-extern const SEC_ASN1Template SEC_PointerToPKCS12KeyBagTemplate[];
-extern const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate[];
-extern const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD[];
-extern const SEC_ASN1Template SEC_PointerToPKCS12SecretBagTemplate[];
-extern const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate_OLD[];
-extern const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate[];
-extern const SEC_ASN1Template SEC_PointerToPKCS12SDSICertTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12CodedSafeBagTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12CodedCertBagTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12CodedCertAndCRLBagTemplate[];
-extern const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate_OLD[];
-extern const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate_OLD[];
-#endif
diff --git a/security/nss/lib/pkcs7/Makefile b/security/nss/lib/pkcs7/Makefile
deleted file mode 100644
index a9cebcfec..000000000
--- a/security/nss/lib/pkcs7/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-
-
diff --git a/security/nss/lib/pkcs7/certread.c b/security/nss/lib/pkcs7/certread.c
deleted file mode 100644
index ec4cc938a..000000000
--- a/security/nss/lib/pkcs7/certread.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "cert.h"
-#include "secpkcs7.h"
-#include "base64.h"
-#include "secitem.h"
-#include "secder.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "secerr.h"
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-
-SECStatus
-SEC_ReadPKCS7Certs(SECItem *pkcs7Item, CERTImportCertificateFunc f, void *arg)
-{
- SEC_PKCS7ContentInfo *contentInfo = NULL;
- SECStatus rv;
- SECItem **certs;
- int count;
-
- contentInfo = SEC_PKCS7DecodeItem(pkcs7Item, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL);
- if ( contentInfo == NULL ) {
- goto loser;
- }
-
- if ( SEC_PKCS7ContentType (contentInfo) != SEC_OID_PKCS7_SIGNED_DATA ) {
- goto loser;
- }
-
- certs = contentInfo->content.signedData->rawCerts;
- if ( certs ) {
- count = 0;
-
- while ( *certs ) {
- count++;
- certs++;
- }
- rv = (* f)(arg, contentInfo->content.signedData->rawCerts, count);
- }
-
- rv = SECSuccess;
-
- goto done;
-loser:
- rv = SECFailure;
-
-done:
- if ( contentInfo ) {
- SEC_PKCS7DestroyContentInfo(contentInfo);
- }
-
- return(rv);
-}
-
-const SEC_ASN1Template SEC_CertSequenceTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN, 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
-};
-
-SECStatus
-SEC_ReadCertSequence(SECItem *certsItem, CERTImportCertificateFunc f, void *arg)
-{
- SECStatus rv;
- SECItem **certs;
- int count;
- SECItem **rawCerts = NULL;
- PRArenaPool *arena;
- SEC_PKCS7ContentInfo *contentInfo = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return SECFailure;
- }
-
- contentInfo = SEC_PKCS7DecodeItem(certsItem, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL);
- if ( contentInfo == NULL ) {
- goto loser;
- }
-
- if ( SEC_PKCS7ContentType (contentInfo) != SEC_OID_NS_TYPE_CERT_SEQUENCE ) {
- goto loser;
- }
-
-
- rv = SEC_QuickDERDecodeItem(arena, &rawCerts, SEC_CertSequenceTemplate,
- contentInfo->content.data);
-
- if (rv != SECSuccess) {
- goto loser;
- }
-
- certs = rawCerts;
- if ( certs ) {
- count = 0;
-
- while ( *certs ) {
- count++;
- certs++;
- }
- rv = (* f)(arg, rawCerts, count);
- }
-
- rv = SECSuccess;
-
- goto done;
-loser:
- rv = SECFailure;
-
-done:
- if ( contentInfo ) {
- SEC_PKCS7DestroyContentInfo(contentInfo);
- }
-
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(rv);
-}
-
-CERTCertificate *
-CERT_ConvertAndDecodeCertificate(char *certstr)
-{
- CERTCertificate *cert;
- SECStatus rv;
- SECItem der;
-
- rv = ATOB_ConvertAsciiToItem(&der, certstr);
- if (rv != SECSuccess)
- return NULL;
-
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- &der, NULL, PR_FALSE, PR_TRUE);
-
- PORT_Free(der.data);
- return cert;
-}
-
-static const char NS_CERT_HEADER[] = "-----BEGIN CERTIFICATE-----";
-static const char NS_CERT_TRAILER[] = "-----END CERTIFICATE-----";
-#define NS_CERT_HEADER_LEN ((sizeof NS_CERT_HEADER) - 1)
-#define NS_CERT_TRAILER_LEN ((sizeof NS_CERT_TRAILER) - 1)
-
-/*
- * read an old style ascii or binary certificate chain
- */
-SECStatus
-CERT_DecodeCertPackage(char *certbuf,
- int certlen,
- CERTImportCertificateFunc f,
- void *arg)
-{
- unsigned char *cp;
- unsigned char *bincert = NULL;
- char * ascCert = NULL;
- SECStatus rv;
-
- if ( certbuf == NULL ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return(SECFailure);
- }
- /*
- * Make sure certlen is long enough to handle the longest possible
- * reference in the code below:
- * 0x30 0x84 l1 l2 l3 l4 +
- * tag 9 o1 o2 o3 o4 o5 o6 o7 o8 o9
- * 6 + 11 = 17. 17 bytes is clearly too small to code any kind of
- * certificate (a 128 bit ECC certificate contains at least an 8 byte
- * key and a 16 byte signature, plus coding overhead). Typically a cert
- * is much larger. So it's safe to require certlen to be at least 17
- * bytes.
- */
- if (certlen < 17) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return(SECFailure);
- }
-
- cp = (unsigned char *)certbuf;
-
- /* is a DER encoded certificate of some type? */
- if ( ( *cp & 0x1f ) == SEC_ASN1_SEQUENCE ) {
- SECItem certitem;
- SECItem *pcertitem = &certitem;
- int seqLen, seqLenLen;
-
- cp++;
-
- if ( *cp & 0x80) {
- /* Multibyte length */
- seqLenLen = cp[0] & 0x7f;
-
- switch (seqLenLen) {
- case 4:
- seqLen = ((unsigned long)cp[1]<<24) |
- ((unsigned long)cp[2]<<16) | (cp[3]<<8) | cp[4];
- break;
- case 3:
- seqLen = ((unsigned long)cp[1]<<16) | (cp[2]<<8) | cp[3];
- break;
- case 2:
- seqLen = (cp[1]<<8) | cp[2];
- break;
- case 1:
- seqLen = cp[1];
- break;
- case 0:
- /* indefinite length */
- seqLen = 0;
- break;
- default:
- goto notder;
- }
- cp += ( seqLenLen + 1 );
-
- } else {
- seqLenLen = 0;
- seqLen = *cp;
- cp++;
- }
-
- /* check entire length if definite length */
- if ( seqLen || seqLenLen ) {
- if ( certlen != ( seqLen + seqLenLen + 2 ) ) {
- if (certlen > ( seqLen + seqLenLen + 2 ))
- PORT_SetError(SEC_ERROR_EXTRA_INPUT);
- else
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- goto notder;
- }
- }
-
- /* check the type oid */
- if ( cp[0] == SEC_ASN1_OBJECT_ID ) {
- SECOidData *oiddata;
- SECItem oiditem;
- /* XXX - assume DER encoding of OID len!! */
- oiditem.len = cp[1];
- /* if we add an oid below that is longer than 9 bytes, then we
- * need to change the certlen check at the top of the function
- * to prevent a buffer overflow
- */
- if ( oiditem.len > 9 ) {
- PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
- return(SECFailure);
- }
- oiditem.data = (unsigned char *)&cp[2];
- oiddata = SECOID_FindOID(&oiditem);
- if ( oiddata == NULL ) {
- return(SECFailure);
- }
-
- certitem.data = (unsigned char*)certbuf;
- certitem.len = certlen;
-
- switch ( oiddata->offset ) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- return(SEC_ReadPKCS7Certs(&certitem, f, arg));
- break;
- case SEC_OID_NS_TYPE_CERT_SEQUENCE:
- return(SEC_ReadCertSequence(&certitem, f, arg));
- break;
- default:
- break;
- }
-
- } else {
- /* it had better be a certificate by now!! */
- certitem.data = (unsigned char*)certbuf;
- certitem.len = certlen;
-
- rv = (* f)(arg, &pcertitem, 1);
- return(rv);
- }
- }
-
- /* now look for a netscape base64 ascii encoded cert */
-notder:
- {
- unsigned char *certbegin = NULL;
- unsigned char *certend = NULL;
- char *pc;
- int cl;
-
- /* Convert the ASCII data into a nul-terminated string */
- ascCert = (char *)PORT_Alloc(certlen + 1);
- if (!ascCert) {
- rv = SECFailure;
- goto loser;
- }
-
- PORT_Memcpy(ascCert, certbuf, certlen);
- ascCert[certlen] = '\0';
-
- pc = PORT_Strchr(ascCert, '\n'); /* find an EOL */
- if (!pc) { /* maybe this is a MAC file */
- pc = ascCert;
- while (*pc && NULL != (pc = PORT_Strchr(pc, '\r'))) {
- *pc++ = '\n';
- }
- }
-
- cp = (unsigned char *)ascCert;
- cl = certlen;
-
- /* find the beginning marker */
- while ( cl > NS_CERT_HEADER_LEN ) {
- int found = 0;
- if ( !PORT_Strncasecmp((char *)cp, NS_CERT_HEADER,
- NS_CERT_HEADER_LEN) ) {
- cl -= NS_CERT_HEADER_LEN;
- cp += NS_CERT_HEADER_LEN;
- found = 1;
- }
-
- /* skip to next eol */
- while ( cl && ( *cp != '\n' )) {
- cp++;
- cl--;
- }
-
- /* skip all blank lines */
- while ( cl && ( *cp == '\n' || *cp == '\r' )) {
- cp++;
- cl--;
- }
- if (cl && found) {
- certbegin = cp;
- break;
- }
- }
-
- if ( certbegin ) {
- /* find the ending marker */
- while ( cl >= NS_CERT_TRAILER_LEN ) {
- if ( !PORT_Strncasecmp((char *)cp, NS_CERT_TRAILER,
- NS_CERT_TRAILER_LEN) ) {
- certend = cp;
- break;
- }
-
- /* skip to next eol */
- while ( cl && ( *cp != '\n' )) {
- cp++;
- cl--;
- }
-
- /* skip all blank lines */
- while ( cl && ( *cp == '\n' || *cp == '\r' )) {
- cp++;
- cl--;
- }
- }
- }
-
- if ( certbegin && certend ) {
- unsigned int binLen;
-
- *certend = 0;
- /* convert to binary */
- bincert = ATOB_AsciiToData((char *)certbegin, &binLen);
- if (!bincert) {
- rv = SECFailure;
- goto loser;
- }
-
- /* now recurse to decode the binary */
- rv = CERT_DecodeCertPackage((char *)bincert, binLen, f, arg);
-
- } else {
- PORT_SetError(SEC_ERROR_BAD_DER);
- rv = SECFailure;
- }
- }
-
-loser:
-
- if ( bincert ) {
- PORT_Free(bincert);
- }
-
- if ( ascCert ) {
- PORT_Free(ascCert);
- }
-
- return(rv);
-}
-
-typedef struct {
- PRArenaPool *arena;
- SECItem cert;
-} collect_args;
-
-static SECStatus
-collect_certs(void *arg, SECItem **certs, int numcerts)
-{
- SECStatus rv;
- collect_args *collectArgs;
-
- collectArgs = (collect_args *)arg;
-
- rv = SECITEM_CopyItem(collectArgs->arena, &collectArgs->cert, *certs);
-
- return(rv);
-}
-
-
-/*
- * read an old style ascii or binary certificate
- */
-CERTCertificate *
-CERT_DecodeCertFromPackage(char *certbuf, int certlen)
-{
- collect_args collectArgs;
- SECStatus rv;
- CERTCertificate *cert = NULL;
-
- collectArgs.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
-
- rv = CERT_DecodeCertPackage(certbuf, certlen, collect_certs,
- (void *)&collectArgs);
- if ( rv == SECSuccess ) {
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- &collectArgs.cert, NULL,
- PR_FALSE, PR_TRUE);
- }
-
- PORT_FreeArena(collectArgs.arena, PR_FALSE);
-
- return(cert);
-}
diff --git a/security/nss/lib/pkcs7/config.mk b/security/nss/lib/pkcs7/config.mk
deleted file mode 100644
index 36f063f1d..000000000
--- a/security/nss/lib/pkcs7/config.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
diff --git a/security/nss/lib/pkcs7/manifest.mn b/security/nss/lib/pkcs7/manifest.mn
deleted file mode 100644
index 59bb0519c..000000000
--- a/security/nss/lib/pkcs7/manifest.mn
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-CORE_DEPTH = ../../..
-
-EXPORTS = \
- secmime.h \
- secpkcs7.h \
- pkcs7t.h \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- p7local.h \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- certread.c \
- p7common.c \
- p7create.c \
- p7decode.c \
- p7encode.c \
- p7local.c \
- secmime.c \
- $(NULL)
-
-LIBRARY_NAME = pkcs7
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/pkcs7/p7common.c b/security/nss/lib/pkcs7/p7common.c
deleted file mode 100644
index 8646a23ab..000000000
--- a/security/nss/lib/pkcs7/p7common.c
+++ /dev/null
@@ -1,693 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * PKCS7 implementation -- the exported parts that are used whether
- * creating or decoding.
- *
- * $Id$
- */
-
-#include "p7local.h"
-
-#include "cert.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-
-/*
- * Find out (saving pointer to lookup result for future reference)
- * and return the inner content type.
- */
-SECOidTag
-SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo)
-{
- if (cinfo->contentTypeTag == NULL)
- cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
-
- if (cinfo->contentTypeTag == NULL)
- return SEC_OID_UNKNOWN;
-
- return cinfo->contentTypeTag->offset;
-}
-
-
-/*
- * Destroy a PKCS7 contentInfo and all of its sub-pieces.
- */
-void
-SEC_PKCS7DestroyContentInfo(SEC_PKCS7ContentInfo *cinfo)
-{
- SECOidTag kind;
- CERTCertificate **certs;
- CERTCertificateList **certlists;
- SEC_PKCS7SignerInfo **signerinfos;
- SEC_PKCS7RecipientInfo **recipientinfos;
-
- PORT_Assert (cinfo->refCount > 0);
- if (cinfo->refCount <= 0)
- return;
-
- cinfo->refCount--;
- if (cinfo->refCount > 0)
- return;
-
- certs = NULL;
- certlists = NULL;
- recipientinfos = NULL;
- signerinfos = NULL;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- {
- SEC_PKCS7EnvelopedData *edp;
-
- edp = cinfo->content.envelopedData;
- if (edp != NULL) {
- recipientinfos = edp->recipientInfos;
- }
- }
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sdp;
-
- sdp = cinfo->content.signedData;
- if (sdp != NULL) {
- certs = sdp->certs;
- certlists = sdp->certLists;
- signerinfos = sdp->signerInfos;
- }
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
-
- saedp = cinfo->content.signedAndEnvelopedData;
- if (saedp != NULL) {
- certs = saedp->certs;
- certlists = saedp->certLists;
- recipientinfos = saedp->recipientInfos;
- signerinfos = saedp->signerInfos;
- if (saedp->sigKey != NULL)
- PK11_FreeSymKey (saedp->sigKey);
- }
- }
- break;
- default:
- /* XXX Anything else that needs to be "manually" freed/destroyed? */
- break;
- }
-
- if (certs != NULL) {
- CERTCertificate *cert;
-
- while ((cert = *certs++) != NULL) {
- CERT_DestroyCertificate (cert);
- }
- }
-
- if (certlists != NULL) {
- CERTCertificateList *certlist;
-
- while ((certlist = *certlists++) != NULL) {
- CERT_DestroyCertificateList (certlist);
- }
- }
-
- if (recipientinfos != NULL) {
- SEC_PKCS7RecipientInfo *ri;
-
- while ((ri = *recipientinfos++) != NULL) {
- if (ri->cert != NULL)
- CERT_DestroyCertificate (ri->cert);
- }
- }
-
- if (signerinfos != NULL) {
- SEC_PKCS7SignerInfo *si;
-
- while ((si = *signerinfos++) != NULL) {
- if (si->cert != NULL)
- CERT_DestroyCertificate (si->cert);
- if (si->certList != NULL)
- CERT_DestroyCertificateList (si->certList);
- }
- }
-
- if (cinfo->poolp != NULL) {
- PORT_FreeArena (cinfo->poolp, PR_FALSE); /* XXX clear it? */
- }
-}
-
-
-/*
- * Return a copy of the given contentInfo. The copy may be virtual
- * or may be real -- either way, the result needs to be passed to
- * SEC_PKCS7DestroyContentInfo later (as does the original).
- */
-SEC_PKCS7ContentInfo *
-SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *cinfo)
-{
- if (cinfo == NULL)
- return NULL;
-
- PORT_Assert (cinfo->refCount > 0);
-
- if (cinfo->created) {
- /*
- * Want to do a real copy of these; otherwise subsequent
- * changes made to either copy are likely to be a surprise.
- * XXX I suspect that this will not actually be called for yet,
- * which is why the assert, so to notice if it is...
- */
- PORT_Assert (0);
- /*
- * XXX Create a new pool here, and copy everything from
- * within. For cert stuff, need to call the appropriate
- * copy functions, etc.
- */
- }
-
- cinfo->refCount++;
- return cinfo;
-}
-
-
-/*
- * Return a pointer to the actual content. In the case of those types
- * which are encrypted, this returns the *plain* content.
- * XXX Needs revisiting if/when we handle nested encrypted types.
- */
-SECItem *
-SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo)
-{
- SECOidTag kind;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- case SEC_OID_PKCS7_DATA:
- return cinfo->content.data;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- {
- SEC_PKCS7DigestedData *digd;
-
- digd = cinfo->content.digestedData;
- if (digd == NULL)
- break;
- return SEC_PKCS7GetContent (&(digd->contentInfo));
- }
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- {
- SEC_PKCS7EncryptedData *encd;
-
- encd = cinfo->content.encryptedData;
- if (encd == NULL)
- break;
- return &(encd->encContentInfo.plainContent);
- }
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- {
- SEC_PKCS7EnvelopedData *envd;
-
- envd = cinfo->content.envelopedData;
- if (envd == NULL)
- break;
- return &(envd->encContentInfo.plainContent);
- }
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sigd;
-
- sigd = cinfo->content.signedData;
- if (sigd == NULL)
- break;
- return SEC_PKCS7GetContent (&(sigd->contentInfo));
- }
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saed;
-
- saed = cinfo->content.signedAndEnvelopedData;
- if (saed == NULL)
- break;
- return &(saed->encContentInfo.plainContent);
- }
- default:
- PORT_Assert(0);
- break;
- }
-
- return NULL;
-}
-
-
-/*
- * XXX Fix the placement and formatting of the
- * following routines (i.e. make them consistent with the rest of
- * the pkcs7 code -- I think some/many belong in other files and
- * they all need a formatting/style rehaul)
- */
-
-/* retrieve the algorithm identifier for encrypted data.
- * the identifier returned is a copy of the algorithm identifier
- * in the content info and needs to be freed after being used.
- *
- * cinfo is the content info for which to retrieve the
- * encryption algorithm.
- *
- * if the content info is not encrypted data or an error
- * occurs NULL is returned.
- */
-SECAlgorithmID *
-SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo)
-{
- SECAlgorithmID *alg = 0;
- switch (SEC_PKCS7ContentType(cinfo))
- {
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- alg = &cinfo->content.encryptedData->encContentInfo.contentEncAlg;
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- alg = &cinfo->content.envelopedData->encContentInfo.contentEncAlg;
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- alg = &cinfo->content.signedAndEnvelopedData
- ->encContentInfo.contentEncAlg;
- break;
- default:
- alg = 0;
- break;
- }
-
- return alg;
-}
-
-/* set the content of the content info. For data content infos,
- * the data is set. For encrytped content infos, the plainContent
- * is set, and is expected to be encrypted later.
- *
- * cinfo is the content info where the data will be set
- *
- * buf is a buffer of the data to set
- *
- * len is the length of the data being set.
- *
- * in the event of an error, SECFailure is returned. SECSuccess
- * indicates the content was successfully set.
- */
-SECStatus
-SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo,
- const char *buf,
- unsigned long len)
-{
- SECOidTag cinfo_type;
- SECStatus rv;
- SECItem content;
- SECOidData *contentTypeTag = NULL;
-
- content.type = siBuffer;
- content.data = (unsigned char *)buf;
- content.len = len;
-
- cinfo_type = SEC_PKCS7ContentType(cinfo);
-
- /* set inner content */
- switch(cinfo_type)
- {
- case SEC_OID_PKCS7_SIGNED_DATA:
- if(content.len > 0) {
- /* we "leak" the old content here, but as it's all in the pool */
- /* it does not really matter */
-
- /* create content item if necessary */
- if (cinfo->content.signedData->contentInfo.content.data == NULL)
- cinfo->content.signedData->contentInfo.content.data = SECITEM_AllocItem(cinfo->poolp, NULL, 0);
- rv = SECITEM_CopyItem(cinfo->poolp,
- cinfo->content.signedData->contentInfo.content.data,
- &content);
- } else {
- cinfo->content.signedData->contentInfo.content.data->data = NULL;
- cinfo->content.signedData->contentInfo.content.data->len = 0;
- rv = SECSuccess;
- }
- if(rv == SECFailure)
- goto loser;
-
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- /* XXX this forces the inner content type to be "data" */
- /* do we really want to override without asking or reason? */
- contentTypeTag = SECOID_FindOIDByTag(SEC_OID_PKCS7_DATA);
- if(contentTypeTag == NULL)
- goto loser;
- rv = SECITEM_CopyItem(cinfo->poolp,
- &(cinfo->content.encryptedData->encContentInfo.contentType),
- &(contentTypeTag->oid));
- if(rv == SECFailure)
- goto loser;
- if(content.len > 0) {
- rv = SECITEM_CopyItem(cinfo->poolp,
- &(cinfo->content.encryptedData->encContentInfo.plainContent),
- &content);
- } else {
- cinfo->content.encryptedData->encContentInfo.plainContent.data = NULL;
- cinfo->content.encryptedData->encContentInfo.encContent.data = NULL;
- cinfo->content.encryptedData->encContentInfo.plainContent.len = 0;
- cinfo->content.encryptedData->encContentInfo.encContent.len = 0;
- rv = SECSuccess;
- }
- if(rv == SECFailure)
- goto loser;
- break;
- case SEC_OID_PKCS7_DATA:
- cinfo->content.data = (SECItem *)PORT_ArenaZAlloc(cinfo->poolp,
- sizeof(SECItem));
- if(cinfo->content.data == NULL)
- goto loser;
- if(content.len > 0) {
- rv = SECITEM_CopyItem(cinfo->poolp,
- cinfo->content.data, &content);
- } else {
- /* handle case with NULL content */
- rv = SECSuccess;
- }
- if(rv == SECFailure)
- goto loser;
- break;
- default:
- goto loser;
- }
-
- return SECSuccess;
-
-loser:
-
- return SECFailure;
-}
-
-/* the content of an encrypted data content info is encrypted.
- * it is assumed that for encrypted data, that the data has already
- * been set and is in the "plainContent" field of the content info.
- *
- * cinfo is the content info to encrypt
- *
- * key is the key with which to perform the encryption. if the
- * algorithm is a password based encryption algorithm, the
- * key is actually a password which will be processed per
- * PKCS #5.
- *
- * in the event of an error, SECFailure is returned. SECSuccess
- * indicates a success.
- */
-SECStatus
-SEC_PKCS7EncryptContents(PRArenaPool *poolp,
- SEC_PKCS7ContentInfo *cinfo,
- SECItem *key,
- void *wincx)
-{
- SECAlgorithmID *algid = NULL;
- SECItem * result = NULL;
- SECItem * src;
- SECItem * dest;
- SECItem * blocked_data = NULL;
- void * mark;
- void * cx;
- PK11SymKey * eKey = NULL;
- PK11SlotInfo * slot = NULL;
-
- CK_MECHANISM_TYPE cryptoMechType;
- int bs;
- SECStatus rv = SECFailure;
- SECItem *c_param = NULL;
-
- if((cinfo == NULL) || (key == NULL))
- return SECFailure;
-
- if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
- return SECFailure;
-
- algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
- if(algid == NULL)
- return SECFailure;
-
- if(poolp == NULL)
- poolp = cinfo->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- src = &cinfo->content.encryptedData->encContentInfo.plainContent;
- dest = &cinfo->content.encryptedData->encContentInfo.encContent;
- dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64));
- dest->len = (src->len + 64);
- if(dest->data == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- slot = PK11_GetInternalKeySlot();
- if(slot == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
- if(eKey == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key);
- if (cryptoMechType == CKM_INVALID_MECHANISM) {
- rv = SECFailure;
- goto loser;
- }
-
- /* block according to PKCS 8 */
- bs = PK11_GetBlockSize(cryptoMechType, c_param);
- rv = SECSuccess;
- if(bs) {
- char pad_char;
- pad_char = (char)(bs - (src->len % bs));
- if(src->len % bs) {
- rv = SECSuccess;
- blocked_data = PK11_BlockData(src, bs);
- if(blocked_data) {
- PORT_Memset((blocked_data->data + blocked_data->len
- - (int)pad_char),
- pad_char, (int)pad_char);
- } else {
- rv = SECFailure;
- goto loser;
- }
- } else {
- blocked_data = SECITEM_DupItem(src);
- if(blocked_data) {
- blocked_data->data = (unsigned char*)PORT_Realloc(
- blocked_data->data,
- blocked_data->len + bs);
- if(blocked_data->data) {
- blocked_data->len += bs;
- PORT_Memset((blocked_data->data + src->len), (char)bs, bs);
- } else {
- rv = SECFailure;
- goto loser;
- }
- } else {
- rv = SECFailure;
- goto loser;
- }
- }
- } else {
- blocked_data = SECITEM_DupItem(src);
- if(!blocked_data) {
- rv = SECFailure;
- goto loser;
- }
- }
-
- cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT,
- eKey, c_param);
- if(cx == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len),
- (int)(src->len + 64), blocked_data->data,
- (int)blocked_data->len);
- PK11_DestroyContext((PK11Context*)cx, PR_TRUE);
-
-loser:
- /* let success fall through */
- if(blocked_data != NULL)
- SECITEM_ZfreeItem(blocked_data, PR_TRUE);
-
- if(result != NULL)
- SECITEM_ZfreeItem(result, PR_TRUE);
-
- if(rv == SECFailure)
- PORT_ArenaRelease(poolp, mark);
- else
- PORT_ArenaUnmark(poolp, mark);
-
- if(eKey != NULL)
- PK11_FreeSymKey(eKey);
-
- if(slot != NULL)
- PK11_FreeSlot(slot);
-
- if(c_param != NULL)
- SECITEM_ZfreeItem(c_param, PR_TRUE);
-
- return rv;
-}
-
-/* the content of an encrypted data content info is decrypted.
- * it is assumed that for encrypted data, that the data has already
- * been set and is in the "encContent" field of the content info.
- *
- * cinfo is the content info to decrypt
- *
- * key is the key with which to perform the decryption. if the
- * algorithm is a password based encryption algorithm, the
- * key is actually a password which will be processed per
- * PKCS #5.
- *
- * in the event of an error, SECFailure is returned. SECSuccess
- * indicates a success.
- */
-SECStatus
-SEC_PKCS7DecryptContents(PRArenaPool *poolp,
- SEC_PKCS7ContentInfo *cinfo,
- SECItem *key,
- void *wincx)
-{
- SECAlgorithmID *algid = NULL;
- SECStatus rv = SECFailure;
- SECItem *result = NULL, *dest, *src;
- void *mark;
-
- PK11SymKey *eKey = NULL;
- PK11SlotInfo *slot = NULL;
- CK_MECHANISM_TYPE cryptoMechType;
- void *cx;
- SECItem *c_param = NULL;
- int bs;
-
- if((cinfo == NULL) || (key == NULL))
- return SECFailure;
-
- if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
- return SECFailure;
-
- algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
- if(algid == NULL)
- return SECFailure;
-
- if(poolp == NULL)
- poolp = cinfo->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- src = &cinfo->content.encryptedData->encContentInfo.encContent;
- dest = &cinfo->content.encryptedData->encContentInfo.plainContent;
- dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64));
- dest->len = (src->len + 64);
- if(dest->data == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- slot = PK11_GetInternalKeySlot();
- if(slot == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
- if(eKey == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key);
- if (cryptoMechType == CKM_INVALID_MECHANISM) {
- rv = SECFailure;
- goto loser;
- }
-
- cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT,
- eKey, c_param);
- if(cx == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len),
- (int)(src->len + 64), src->data, (int)src->len);
- PK11_DestroyContext((PK11Context *)cx, PR_TRUE);
-
- bs = PK11_GetBlockSize(cryptoMechType, c_param);
- if(bs) {
- /* check for proper badding in block algorithms. this assumes
- * RC2 cbc or a DES cbc variant. and the padding is thus defined
- */
- if(((int)dest->data[dest->len-1] <= bs) &&
- ((int)dest->data[dest->len-1] > 0)) {
- dest->len -= (int)dest->data[dest->len-1];
- } else {
- rv = SECFailure;
- /* set an error ? */
- }
- }
-
-loser:
- /* let success fall through */
- if(result != NULL)
- SECITEM_ZfreeItem(result, PR_TRUE);
-
- if(rv == SECFailure)
- PORT_ArenaRelease(poolp, mark);
- else
- PORT_ArenaUnmark(poolp, mark);
-
- if(eKey != NULL)
- PK11_FreeSymKey(eKey);
-
- if(slot != NULL)
- PK11_FreeSlot(slot);
-
- if(c_param != NULL)
- SECITEM_ZfreeItem(c_param, PR_TRUE);
-
- return rv;
-}
-
-SECItem **
-SEC_PKCS7GetCertificateList(SEC_PKCS7ContentInfo *cinfo)
-{
- switch(SEC_PKCS7ContentType(cinfo))
- {
- case SEC_OID_PKCS7_SIGNED_DATA:
- return cinfo->content.signedData->rawCerts;
- break;
- default:
- return NULL;
- break;
- }
-}
-
-
-int
-SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo)
-{
- if (cinfo->contentTypeTag->offset == SEC_OID_PKCS7_ENVELOPED_DATA)
- return cinfo->content.envelopedData->encContentInfo.keysize;
- else
- return 0;
-}
-
diff --git a/security/nss/lib/pkcs7/p7create.c b/security/nss/lib/pkcs7/p7create.c
deleted file mode 100644
index 70a747836..000000000
--- a/security/nss/lib/pkcs7/p7create.c
+++ /dev/null
@@ -1,1293 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * PKCS7 creation.
- *
- * $Id$
- */
-
-#include "p7local.h"
-
-#include "cert.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "prtime.h"
-#include "secerr.h"
-#include "secder.h"
-#include "secpkcs5.h"
-
-const int NSS_PBE_DEFAULT_ITERATION_COUNT = 2000; /* used in p12e.c too */
-
-static SECStatus
-sec_pkcs7_init_content_info (SEC_PKCS7ContentInfo *cinfo, PRArenaPool *poolp,
- SECOidTag kind, PRBool detached)
-{
- void *thing;
- int version;
- SECItem *versionp;
- SECStatus rv;
-
- PORT_Assert (cinfo != NULL && poolp != NULL);
- if (cinfo == NULL || poolp == NULL)
- return SECFailure;
-
- cinfo->contentTypeTag = SECOID_FindOIDByTag (kind);
- PORT_Assert (cinfo->contentTypeTag
- && cinfo->contentTypeTag->offset == kind);
-
- rv = SECITEM_CopyItem (poolp, &(cinfo->contentType),
- &(cinfo->contentTypeTag->oid));
- if (rv != SECSuccess)
- return rv;
-
- if (detached)
- return SECSuccess;
-
- switch (kind) {
- default:
- case SEC_OID_PKCS7_DATA:
- thing = PORT_ArenaZAlloc (poolp, sizeof(SECItem));
- cinfo->content.data = (SECItem*)thing;
- versionp = NULL;
- version = -1;
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- thing = PORT_ArenaZAlloc (poolp, sizeof(SEC_PKCS7DigestedData));
- cinfo->content.digestedData = (SEC_PKCS7DigestedData*)thing;
- versionp = &(cinfo->content.digestedData->version);
- version = SEC_PKCS7_DIGESTED_DATA_VERSION;
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- thing = PORT_ArenaZAlloc (poolp, sizeof(SEC_PKCS7EncryptedData));
- cinfo->content.encryptedData = (SEC_PKCS7EncryptedData*)thing;
- versionp = &(cinfo->content.encryptedData->version);
- version = SEC_PKCS7_ENCRYPTED_DATA_VERSION;
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- thing = PORT_ArenaZAlloc (poolp, sizeof(SEC_PKCS7EnvelopedData));
- cinfo->content.envelopedData =
- (SEC_PKCS7EnvelopedData*)thing;
- versionp = &(cinfo->content.envelopedData->version);
- version = SEC_PKCS7_ENVELOPED_DATA_VERSION;
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- thing = PORT_ArenaZAlloc (poolp, sizeof(SEC_PKCS7SignedData));
- cinfo->content.signedData =
- (SEC_PKCS7SignedData*)thing;
- versionp = &(cinfo->content.signedData->version);
- version = SEC_PKCS7_SIGNED_DATA_VERSION;
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- thing = PORT_ArenaZAlloc(poolp,sizeof(SEC_PKCS7SignedAndEnvelopedData));
- cinfo->content.signedAndEnvelopedData =
- (SEC_PKCS7SignedAndEnvelopedData*)thing;
- versionp = &(cinfo->content.signedAndEnvelopedData->version);
- version = SEC_PKCS7_SIGNED_AND_ENVELOPED_DATA_VERSION;
- break;
- }
-
- if (thing == NULL)
- return SECFailure;
-
- if (versionp != NULL) {
- SECItem *dummy;
-
- PORT_Assert (version >= 0);
- dummy = SEC_ASN1EncodeInteger (poolp, versionp, version);
- if (dummy == NULL)
- return SECFailure;
- PORT_Assert (dummy == versionp);
- }
-
- return SECSuccess;
-}
-
-
-static SEC_PKCS7ContentInfo *
-sec_pkcs7_create_content_info (SECOidTag kind, PRBool detached,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg)
-{
- SEC_PKCS7ContentInfo *cinfo;
- PRArenaPool *poolp;
- SECStatus rv;
-
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
- if (poolp == NULL)
- return NULL;
-
- cinfo = (SEC_PKCS7ContentInfo*)PORT_ArenaZAlloc (poolp, sizeof(*cinfo));
- if (cinfo == NULL) {
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
- }
-
- cinfo->poolp = poolp;
- cinfo->pwfn = pwfn;
- cinfo->pwfn_arg = pwfn_arg;
- cinfo->created = PR_TRUE;
- cinfo->refCount = 1;
-
- rv = sec_pkcs7_init_content_info (cinfo, poolp, kind, detached);
- if (rv != SECSuccess) {
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
- }
-
- return cinfo;
-}
-
-
-/*
- * Add a signer to a PKCS7 thing, verifying the signature cert first.
- * Any error returns SECFailure.
- *
- * XXX Right now this only adds the *first* signer. It fails if you try
- * to add a second one -- this needs to be fixed.
- */
-static SECStatus
-sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate * cert,
- SECCertUsage certusage,
- CERTCertDBHandle * certdb,
- SECOidTag digestalgtag,
- SECItem * digestdata)
-{
- SEC_PKCS7SignerInfo *signerinfo, **signerinfos, ***signerinfosp;
- SECAlgorithmID *digestalg, **digestalgs, ***digestalgsp;
- SECItem *digest, **digests, ***digestsp;
- SECItem * dummy;
- void * mark;
- SECStatus rv;
- SECOidTag kind;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sdp;
-
- sdp = cinfo->content.signedData;
- digestalgsp = &(sdp->digestAlgorithms);
- digestsp = &(sdp->digests);
- signerinfosp = &(sdp->signerInfos);
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
-
- saedp = cinfo->content.signedAndEnvelopedData;
- digestalgsp = &(saedp->digestAlgorithms);
- digestsp = &(saedp->digests);
- signerinfosp = &(saedp->signerInfos);
- }
- break;
- default:
- return SECFailure; /* XXX set an error? */
- }
-
- /*
- * XXX I think that CERT_VerifyCert should do this if *it* is passed
- * a NULL database.
- */
- if (certdb == NULL) {
- certdb = CERT_GetDefaultCertDB();
- if (certdb == NULL)
- return SECFailure; /* XXX set an error? */
- }
-
- if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, PR_Now(),
- cinfo->pwfn_arg, NULL) != SECSuccess)
- {
- /* XXX Did CERT_VerifyCert set an error? */
- return SECFailure;
- }
-
- /*
- * XXX This is the check that we do not already have a signer.
- * This is not what we really want -- we want to allow this
- * and *add* the new signer.
- */
- PORT_Assert (*signerinfosp == NULL
- && *digestalgsp == NULL && *digestsp == NULL);
- if (*signerinfosp != NULL || *digestalgsp != NULL || *digestsp != NULL)
- return SECFailure;
-
- mark = PORT_ArenaMark (cinfo->poolp);
-
- signerinfo = (SEC_PKCS7SignerInfo*)PORT_ArenaZAlloc (cinfo->poolp,
- sizeof(SEC_PKCS7SignerInfo));
- if (signerinfo == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
-
- dummy = SEC_ASN1EncodeInteger (cinfo->poolp, &signerinfo->version,
- SEC_PKCS7_SIGNER_INFO_VERSION);
- if (dummy == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
- PORT_Assert (dummy == &signerinfo->version);
-
- signerinfo->cert = CERT_DupCertificate (cert);
- if (signerinfo->cert == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
-
- signerinfo->issuerAndSN = CERT_GetCertIssuerAndSN (cinfo->poolp, cert);
- if (signerinfo->issuerAndSN == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
-
- rv = SECOID_SetAlgorithmID (cinfo->poolp, &signerinfo->digestAlg,
- digestalgtag, NULL);
- if (rv != SECSuccess) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
-
- /*
- * Okay, now signerinfo is all set. We just need to put it and its
- * companions (another copy of the digest algorithm, and the digest
- * itself if given) into the main structure.
- *
- * XXX If we are handling more than one signer, the following code
- * needs to look through the digest algorithms already specified
- * and see if the same one is there already. If it is, it does not
- * need to be added again. Also, if it is there *and* the digest
- * is not null, then the digest given should match the digest already
- * specified -- if not, that is an error. Finally, the new signerinfo
- * should be *added* to the set already found.
- */
-
- signerinfos = (SEC_PKCS7SignerInfo**)PORT_ArenaAlloc (cinfo->poolp,
- 2 * sizeof(SEC_PKCS7SignerInfo *));
- if (signerinfos == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
- signerinfos[0] = signerinfo;
- signerinfos[1] = NULL;
-
- digestalg = PORT_ArenaZAlloc (cinfo->poolp, sizeof(SECAlgorithmID));
- digestalgs = PORT_ArenaAlloc (cinfo->poolp, 2 * sizeof(SECAlgorithmID *));
- if (digestalg == NULL || digestalgs == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
- rv = SECOID_SetAlgorithmID (cinfo->poolp, digestalg, digestalgtag, NULL);
- if (rv != SECSuccess) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
- digestalgs[0] = digestalg;
- digestalgs[1] = NULL;
-
- if (digestdata != NULL) {
- digest = (SECItem*)PORT_ArenaAlloc (cinfo->poolp, sizeof(SECItem));
- digests = (SECItem**)PORT_ArenaAlloc (cinfo->poolp,
- 2 * sizeof(SECItem *));
- if (digest == NULL || digests == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
- rv = SECITEM_CopyItem (cinfo->poolp, digest, digestdata);
- if (rv != SECSuccess) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
- digests[0] = digest;
- digests[1] = NULL;
- } else {
- digests = NULL;
- }
-
- *signerinfosp = signerinfos;
- *digestalgsp = digestalgs;
- *digestsp = digests;
-
- PORT_ArenaUnmark(cinfo->poolp, mark);
- return SECSuccess;
-}
-
-
-/*
- * Helper function for creating an empty signedData.
- */
-static SEC_PKCS7ContentInfo *
-sec_pkcs7_create_signed_data (SECKEYGetPasswordKey pwfn, void *pwfn_arg)
-{
- SEC_PKCS7ContentInfo *cinfo;
- SEC_PKCS7SignedData *sigd;
- SECStatus rv;
-
- cinfo = sec_pkcs7_create_content_info (SEC_OID_PKCS7_SIGNED_DATA, PR_FALSE,
- pwfn, pwfn_arg);
- if (cinfo == NULL)
- return NULL;
-
- sigd = cinfo->content.signedData;
- PORT_Assert (sigd != NULL);
-
- /*
- * XXX Might we want to allow content types other than data?
- * If so, via what interface?
- */
- rv = sec_pkcs7_init_content_info (&(sigd->contentInfo), cinfo->poolp,
- SEC_OID_PKCS7_DATA, PR_TRUE);
- if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
-
- return cinfo;
-}
-
-
-/*
- * Start a PKCS7 signing context.
- *
- * "cert" is the cert that will be used to sign the data. It will be
- * checked for validity.
- *
- * "certusage" describes the signing usage (e.g. certUsageEmailSigner)
- * XXX Maybe SECCertUsage should be split so that our caller just says
- * "email" and *we* add the "signing" part -- otherwise our caller
- * could be lying about the usage; we do not want to allow encryption
- * certs for signing or vice versa.
- *
- * "certdb" is the cert database to use for verifying the cert.
- * It can be NULL if a default database is available (like in the client).
- *
- * "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1).
- *
- * "digest" is the actual digest of the data. It must be provided in
- * the case of detached data or NULL if the content will be included.
- *
- * The return value can be passed to functions which add things to
- * it like attributes, then eventually to SEC_PKCS7Encode() or to
- * SEC_PKCS7EncoderStart() to create the encoded data, and finally to
- * SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateSignedData (CERTCertificate *cert,
- SECCertUsage certusage,
- CERTCertDBHandle *certdb,
- SECOidTag digestalg,
- SECItem *digest,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg)
-{
- SEC_PKCS7ContentInfo *cinfo;
- SECStatus rv;
-
- cinfo = sec_pkcs7_create_signed_data (pwfn, pwfn_arg);
- if (cinfo == NULL)
- return NULL;
-
- rv = sec_pkcs7_add_signer (cinfo, cert, certusage, certdb,
- digestalg, digest);
- if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
-
- return cinfo;
-}
-
-
-static SEC_PKCS7Attribute *
-sec_pkcs7_create_attribute (PRArenaPool *poolp, SECOidTag oidtag,
- SECItem *value, PRBool encoded)
-{
- SEC_PKCS7Attribute *attr;
- SECItem **values;
- void *mark;
-
- PORT_Assert (poolp != NULL);
- mark = PORT_ArenaMark (poolp);
-
- attr = (SEC_PKCS7Attribute*)PORT_ArenaAlloc (poolp,
- sizeof(SEC_PKCS7Attribute));
- if (attr == NULL)
- goto loser;
-
- attr->typeTag = SECOID_FindOIDByTag (oidtag);
- if (attr->typeTag == NULL)
- goto loser;
-
- if (SECITEM_CopyItem (poolp, &(attr->type),
- &(attr->typeTag->oid)) != SECSuccess)
- goto loser;
-
- values = (SECItem**)PORT_ArenaAlloc (poolp, 2 * sizeof(SECItem *));
- if (values == NULL)
- goto loser;
-
- if (value != NULL) {
- SECItem *copy;
-
- copy = (SECItem*)PORT_ArenaAlloc (poolp, sizeof(SECItem));
- if (copy == NULL)
- goto loser;
-
- if (SECITEM_CopyItem (poolp, copy, value) != SECSuccess)
- goto loser;
-
- value = copy;
- }
-
- values[0] = value;
- values[1] = NULL;
- attr->values = values;
- attr->encoded = encoded;
-
- PORT_ArenaUnmark (poolp, mark);
- return attr;
-
-loser:
- PORT_Assert (mark != NULL);
- PORT_ArenaRelease (poolp, mark);
- return NULL;
-}
-
-
-static SECStatus
-sec_pkcs7_add_attribute (SEC_PKCS7ContentInfo *cinfo,
- SEC_PKCS7Attribute ***attrsp,
- SEC_PKCS7Attribute *attr)
-{
- SEC_PKCS7Attribute **attrs;
- SECItem *ct_value;
- void *mark;
-
- PORT_Assert (SEC_PKCS7ContentType (cinfo) == SEC_OID_PKCS7_SIGNED_DATA);
- if (SEC_PKCS7ContentType (cinfo) != SEC_OID_PKCS7_SIGNED_DATA)
- return SECFailure;
-
- attrs = *attrsp;
- if (attrs != NULL) {
- int count;
-
- /*
- * We already have some attributes, and just need to add this
- * new one.
- */
-
- /*
- * We should already have the *required* attributes, which were
- * created/added at the same time the first attribute was added.
- */
- PORT_Assert (sec_PKCS7FindAttribute (attrs,
- SEC_OID_PKCS9_CONTENT_TYPE,
- PR_FALSE) != NULL);
- PORT_Assert (sec_PKCS7FindAttribute (attrs,
- SEC_OID_PKCS9_MESSAGE_DIGEST,
- PR_FALSE) != NULL);
-
- for (count = 0; attrs[count] != NULL; count++)
- ;
- attrs = (SEC_PKCS7Attribute**)PORT_ArenaGrow (cinfo->poolp, attrs,
- (count + 1) * sizeof(SEC_PKCS7Attribute *),
- (count + 2) * sizeof(SEC_PKCS7Attribute *));
- if (attrs == NULL)
- return SECFailure;
-
- attrs[count] = attr;
- attrs[count+1] = NULL;
- *attrsp = attrs;
-
- return SECSuccess;
- }
-
- /*
- * This is the first time an attribute is going in.
- * We need to create and add the required attributes, and then
- * we will also add in the one our caller gave us.
- */
-
- /*
- * There are 2 required attributes, plus the one our caller wants
- * to add, plus we always end with a NULL one. Thus, four slots.
- */
- attrs = (SEC_PKCS7Attribute**)PORT_ArenaAlloc (cinfo->poolp,
- 4 * sizeof(SEC_PKCS7Attribute *));
- if (attrs == NULL)
- return SECFailure;
-
- mark = PORT_ArenaMark (cinfo->poolp);
-
- /*
- * First required attribute is the content type of the data
- * being signed.
- */
- ct_value = &(cinfo->content.signedData->contentInfo.contentType);
- attrs[0] = sec_pkcs7_create_attribute (cinfo->poolp,
- SEC_OID_PKCS9_CONTENT_TYPE,
- ct_value, PR_FALSE);
- /*
- * Second required attribute is the message digest of the data
- * being signed; we leave the value NULL for now (just create
- * the place for it to go), and the encoder will fill it in later.
- */
- attrs[1] = sec_pkcs7_create_attribute (cinfo->poolp,
- SEC_OID_PKCS9_MESSAGE_DIGEST,
- NULL, PR_FALSE);
- if (attrs[0] == NULL || attrs[1] == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
-
- attrs[2] = attr;
- attrs[3] = NULL;
- *attrsp = attrs;
-
- PORT_ArenaUnmark (cinfo->poolp, mark);
- return SECSuccess;
-}
-
-
-/*
- * Add the signing time to the authenticated (i.e. signed) attributes
- * of "cinfo". This is expected to be included in outgoing signed
- * messages for email (S/MIME) but is likely useful in other situations.
- *
- * This should only be added once; a second call will either do
- * nothing or replace an old signing time with a newer one.
- *
- * XXX This will probably just shove the current time into "cinfo"
- * but it will not actually get signed until the entire item is
- * processed for encoding. Is this (expected to be small) delay okay?
- *
- * "cinfo" should be of type signedData (the only kind of pkcs7 data
- * that is allowed authenticated attributes); SECFailure will be returned
- * if it is not.
- */
-SECStatus
-SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo)
-{
- SEC_PKCS7SignerInfo **signerinfos;
- SEC_PKCS7Attribute *attr;
- SECItem stime;
- SECStatus rv;
- int si;
-
- PORT_Assert (SEC_PKCS7ContentType (cinfo) == SEC_OID_PKCS7_SIGNED_DATA);
- if (SEC_PKCS7ContentType (cinfo) != SEC_OID_PKCS7_SIGNED_DATA)
- return SECFailure;
-
- signerinfos = cinfo->content.signedData->signerInfos;
-
- /* There has to be a signer, or it makes no sense. */
- if (signerinfos == NULL || signerinfos[0] == NULL)
- return SECFailure;
-
- rv = DER_EncodeTimeChoice(NULL, &stime, PR_Now());
- if (rv != SECSuccess)
- return rv;
-
- attr = sec_pkcs7_create_attribute (cinfo->poolp,
- SEC_OID_PKCS9_SIGNING_TIME,
- &stime, PR_FALSE);
- SECITEM_FreeItem (&stime, PR_FALSE);
-
- if (attr == NULL)
- return SECFailure;
-
- rv = SECSuccess;
- for (si = 0; signerinfos[si] != NULL; si++) {
- SEC_PKCS7Attribute *oattr;
-
- oattr = sec_PKCS7FindAttribute (signerinfos[si]->authAttr,
- SEC_OID_PKCS9_SIGNING_TIME, PR_FALSE);
- PORT_Assert (oattr == NULL);
- if (oattr != NULL)
- continue; /* XXX or would it be better to replace it? */
-
- rv = sec_pkcs7_add_attribute (cinfo, &(signerinfos[si]->authAttr),
- attr);
- if (rv != SECSuccess)
- break; /* could try to continue, but may as well give up now */
- }
-
- return rv;
-}
-
-
-/*
- * Add the specified attribute to the authenticated (i.e. signed) attributes
- * of "cinfo" -- "oidtag" describes the attribute and "value" is the
- * value to be associated with it. NOTE! "value" must already be encoded;
- * no interpretation of "oidtag" is done. Also, it is assumed that this
- * signedData has only one signer -- if we ever need to add attributes
- * when there is more than one signature, we need a way to specify *which*
- * signature should get the attribute.
- *
- * XXX Technically, a signed attribute can have multiple values; if/when
- * we ever need to support an attribute which takes multiple values, we
- * either need to change this interface or create an AddSignedAttributeValue
- * which can be called subsequently, and would then append a value.
- *
- * "cinfo" should be of type signedData (the only kind of pkcs7 data
- * that is allowed authenticated attributes); SECFailure will be returned
- * if it is not.
- */
-SECStatus
-SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo,
- SECOidTag oidtag,
- SECItem *value)
-{
- SEC_PKCS7SignerInfo **signerinfos;
- SEC_PKCS7Attribute *attr;
-
- PORT_Assert (SEC_PKCS7ContentType (cinfo) == SEC_OID_PKCS7_SIGNED_DATA);
- if (SEC_PKCS7ContentType (cinfo) != SEC_OID_PKCS7_SIGNED_DATA)
- return SECFailure;
-
- signerinfos = cinfo->content.signedData->signerInfos;
-
- /*
- * No signature or more than one means no deal.
- */
- if (signerinfos == NULL || signerinfos[0] == NULL || signerinfos[1] != NULL)
- return SECFailure;
-
- attr = sec_pkcs7_create_attribute (cinfo->poolp, oidtag, value, PR_TRUE);
- if (attr == NULL)
- return SECFailure;
-
- return sec_pkcs7_add_attribute (cinfo, &(signerinfos[0]->authAttr), attr);
-}
-
-
-/*
- * Mark that the signer certificates and their issuing chain should
- * be included in the encoded data. This is expected to be used
- * in outgoing signed messages for email (S/MIME).
- *
- * "certdb" is the cert database to use for finding the chain.
- * It can be NULL, meaning use the default database.
- *
- * "cinfo" should be of type signedData or signedAndEnvelopedData;
- * SECFailure will be returned if it is not.
- */
-SECStatus
-SEC_PKCS7IncludeCertChain (SEC_PKCS7ContentInfo *cinfo,
- CERTCertDBHandle *certdb)
-{
- SECOidTag kind;
- SEC_PKCS7SignerInfo *signerinfo, **signerinfos;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- signerinfos = cinfo->content.signedData->signerInfos;
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- signerinfos = cinfo->content.signedAndEnvelopedData->signerInfos;
- break;
- default:
- return SECFailure; /* XXX set an error? */
- }
-
- if (signerinfos == NULL) /* no signer, no certs? */
- return SECFailure; /* XXX set an error? */
-
- if (certdb == NULL) {
- certdb = CERT_GetDefaultCertDB();
- if (certdb == NULL) {
- PORT_SetError (SEC_ERROR_BAD_DATABASE);
- return SECFailure;
- }
- }
-
- /* XXX Should it be an error if we find no signerinfo or no certs? */
- while ((signerinfo = *signerinfos++) != NULL) {
- if (signerinfo->cert != NULL)
- /* get the cert chain. don't send the root to avoid contamination
- * of old clients with a new root that they don't trust
- */
- signerinfo->certList = CERT_CertChainFromCert (signerinfo->cert,
- certUsageEmailSigner,
- PR_FALSE);
- }
-
- return SECSuccess;
-}
-
-
-/*
- * Helper function to add a certificate chain for inclusion in the
- * bag of certificates in a signedData.
- */
-static SECStatus
-sec_pkcs7_add_cert_chain (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate *cert,
- CERTCertDBHandle *certdb)
-{
- SECOidTag kind;
- CERTCertificateList *certlist, **certlists, ***certlistsp;
- int count;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sdp;
-
- sdp = cinfo->content.signedData;
- certlistsp = &(sdp->certLists);
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
-
- saedp = cinfo->content.signedAndEnvelopedData;
- certlistsp = &(saedp->certLists);
- }
- break;
- default:
- return SECFailure; /* XXX set an error? */
- }
-
- if (certdb == NULL) {
- certdb = CERT_GetDefaultCertDB();
- if (certdb == NULL) {
- PORT_SetError (SEC_ERROR_BAD_DATABASE);
- return SECFailure;
- }
- }
-
- certlist = CERT_CertChainFromCert (cert, certUsageEmailSigner, PR_FALSE);
- if (certlist == NULL)
- return SECFailure;
-
- certlists = *certlistsp;
- if (certlists == NULL) {
- count = 0;
- certlists = (CERTCertificateList**)PORT_ArenaAlloc (cinfo->poolp,
- 2 * sizeof(CERTCertificateList *));
- } else {
- for (count = 0; certlists[count] != NULL; count++)
- ;
- PORT_Assert (count); /* should be at least one already */
- certlists = (CERTCertificateList**)PORT_ArenaGrow (cinfo->poolp,
- certlists,
- (count + 1) * sizeof(CERTCertificateList *),
- (count + 2) * sizeof(CERTCertificateList *));
- }
-
- if (certlists == NULL) {
- CERT_DestroyCertificateList (certlist);
- return SECFailure;
- }
-
- certlists[count] = certlist;
- certlists[count + 1] = NULL;
-
- *certlistsp = certlists;
-
- return SECSuccess;
-}
-
-
-/*
- * Helper function to add a certificate for inclusion in the bag of
- * certificates in a signedData.
- */
-static SECStatus
-sec_pkcs7_add_certificate (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate *cert)
-{
- SECOidTag kind;
- CERTCertificate **certs, ***certsp;
- int count;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sdp;
-
- sdp = cinfo->content.signedData;
- certsp = &(sdp->certs);
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
-
- saedp = cinfo->content.signedAndEnvelopedData;
- certsp = &(saedp->certs);
- }
- break;
- default:
- return SECFailure; /* XXX set an error? */
- }
-
- cert = CERT_DupCertificate (cert);
- if (cert == NULL)
- return SECFailure;
-
- certs = *certsp;
- if (certs == NULL) {
- count = 0;
- certs = (CERTCertificate**)PORT_ArenaAlloc (cinfo->poolp,
- 2 * sizeof(CERTCertificate *));
- } else {
- for (count = 0; certs[count] != NULL; count++)
- ;
- PORT_Assert (count); /* should be at least one already */
- certs = (CERTCertificate**)PORT_ArenaGrow (cinfo->poolp, certs,
- (count + 1) * sizeof(CERTCertificate *),
- (count + 2) * sizeof(CERTCertificate *));
- }
-
- if (certs == NULL) {
- CERT_DestroyCertificate (cert);
- return SECFailure;
- }
-
- certs[count] = cert;
- certs[count + 1] = NULL;
-
- *certsp = certs;
-
- return SECSuccess;
-}
-
-
-/*
- * Create a PKCS7 certs-only container.
- *
- * "cert" is the (first) cert that will be included.
- *
- * "include_chain" specifies whether the entire chain for "cert" should
- * be included.
- *
- * "certdb" is the cert database to use for finding the chain.
- * It can be NULL in when "include_chain" is false, or when meaning
- * use the default database.
- *
- * More certs and chains can be added via AddCertificate and AddCertChain.
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateCertsOnly (CERTCertificate *cert,
- PRBool include_chain,
- CERTCertDBHandle *certdb)
-{
- SEC_PKCS7ContentInfo *cinfo;
- SECStatus rv;
-
- cinfo = sec_pkcs7_create_signed_data (NULL, NULL);
- if (cinfo == NULL)
- return NULL;
-
- if (include_chain)
- rv = sec_pkcs7_add_cert_chain (cinfo, cert, certdb);
- else
- rv = sec_pkcs7_add_certificate (cinfo, cert);
-
- if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
-
- return cinfo;
-}
-
-
-/*
- * Add "cert" and its entire chain to the set of certs included in "cinfo".
- *
- * "certdb" is the cert database to use for finding the chain.
- * It can be NULL, meaning use the default database.
- *
- * "cinfo" should be of type signedData or signedAndEnvelopedData;
- * SECFailure will be returned if it is not.
- */
-SECStatus
-SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate *cert,
- CERTCertDBHandle *certdb)
-{
- SECOidTag kind;
-
- kind = SEC_PKCS7ContentType (cinfo);
- if (kind != SEC_OID_PKCS7_SIGNED_DATA
- && kind != SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA)
- return SECFailure; /* XXX set an error? */
-
- return sec_pkcs7_add_cert_chain (cinfo, cert, certdb);
-}
-
-
-/*
- * Add "cert" to the set of certs included in "cinfo".
- *
- * "cinfo" should be of type signedData or signedAndEnvelopedData;
- * SECFailure will be returned if it is not.
- */
-SECStatus
-SEC_PKCS7AddCertificate (SEC_PKCS7ContentInfo *cinfo, CERTCertificate *cert)
-{
- SECOidTag kind;
-
- kind = SEC_PKCS7ContentType (cinfo);
- if (kind != SEC_OID_PKCS7_SIGNED_DATA
- && kind != SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA)
- return SECFailure; /* XXX set an error? */
-
- return sec_pkcs7_add_certificate (cinfo, cert);
-}
-
-
-static SECStatus
-sec_pkcs7_init_encrypted_content_info (SEC_PKCS7EncryptedContentInfo *enccinfo,
- PRArenaPool *poolp,
- SECOidTag kind, PRBool detached,
- SECOidTag encalg, int keysize)
-{
- SECStatus rv;
-
- PORT_Assert (enccinfo != NULL && poolp != NULL);
- if (enccinfo == NULL || poolp == NULL)
- return SECFailure;
-
- /*
- * XXX Some day we may want to allow for other kinds. That needs
- * more work and modifications to the creation interface, etc.
- * For now, allow but notice callers who pass in other kinds.
- * They are responsible for creating the inner type and encoding,
- * if it is other than DATA.
- */
- PORT_Assert (kind == SEC_OID_PKCS7_DATA);
-
- enccinfo->contentTypeTag = SECOID_FindOIDByTag (kind);
- PORT_Assert (enccinfo->contentTypeTag
- && enccinfo->contentTypeTag->offset == kind);
-
- rv = SECITEM_CopyItem (poolp, &(enccinfo->contentType),
- &(enccinfo->contentTypeTag->oid));
- if (rv != SECSuccess)
- return rv;
-
- /* Save keysize and algorithm for later. */
- enccinfo->keysize = keysize;
- enccinfo->encalg = encalg;
-
- return SECSuccess;
-}
-
-
-/*
- * Add a recipient to a PKCS7 thing, verifying their cert first.
- * Any error returns SECFailure.
- */
-static SECStatus
-sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate *cert,
- SECCertUsage certusage,
- CERTCertDBHandle *certdb)
-{
- SECOidTag kind;
- SEC_PKCS7RecipientInfo *recipientinfo, **recipientinfos, ***recipientinfosp;
- SECItem *dummy;
- void *mark;
- int count;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- {
- SEC_PKCS7EnvelopedData *edp;
-
- edp = cinfo->content.envelopedData;
- recipientinfosp = &(edp->recipientInfos);
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
-
- saedp = cinfo->content.signedAndEnvelopedData;
- recipientinfosp = &(saedp->recipientInfos);
- }
- break;
- default:
- return SECFailure; /* XXX set an error? */
- }
-
- /*
- * XXX I think that CERT_VerifyCert should do this if *it* is passed
- * a NULL database.
- */
- if (certdb == NULL) {
- certdb = CERT_GetDefaultCertDB();
- if (certdb == NULL)
- return SECFailure; /* XXX set an error? */
- }
-
- if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, PR_Now(),
- cinfo->pwfn_arg, NULL) != SECSuccess)
- {
- /* XXX Did CERT_VerifyCert set an error? */
- return SECFailure;
- }
-
- mark = PORT_ArenaMark (cinfo->poolp);
-
- recipientinfo = (SEC_PKCS7RecipientInfo*)PORT_ArenaZAlloc (cinfo->poolp,
- sizeof(SEC_PKCS7RecipientInfo));
- if (recipientinfo == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
-
- dummy = SEC_ASN1EncodeInteger (cinfo->poolp, &recipientinfo->version,
- SEC_PKCS7_RECIPIENT_INFO_VERSION);
- if (dummy == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
- PORT_Assert (dummy == &recipientinfo->version);
-
- recipientinfo->cert = CERT_DupCertificate (cert);
- if (recipientinfo->cert == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
-
- recipientinfo->issuerAndSN = CERT_GetCertIssuerAndSN (cinfo->poolp, cert);
- if (recipientinfo->issuerAndSN == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
-
- /*
- * Okay, now recipientinfo is all set. We just need to put it into
- * the main structure.
- *
- * If this is the first recipient, allocate a new recipientinfos array;
- * otherwise, reallocate the array, making room for the new entry.
- */
- recipientinfos = *recipientinfosp;
- if (recipientinfos == NULL) {
- count = 0;
- recipientinfos = (SEC_PKCS7RecipientInfo **)PORT_ArenaAlloc (
- cinfo->poolp,
- 2 * sizeof(SEC_PKCS7RecipientInfo *));
- } else {
- for (count = 0; recipientinfos[count] != NULL; count++)
- ;
- PORT_Assert (count); /* should be at least one already */
- recipientinfos = (SEC_PKCS7RecipientInfo **)PORT_ArenaGrow (
- cinfo->poolp, recipientinfos,
- (count + 1) * sizeof(SEC_PKCS7RecipientInfo *),
- (count + 2) * sizeof(SEC_PKCS7RecipientInfo *));
- }
-
- if (recipientinfos == NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- return SECFailure;
- }
-
- recipientinfos[count] = recipientinfo;
- recipientinfos[count + 1] = NULL;
-
- *recipientinfosp = recipientinfos;
-
- PORT_ArenaUnmark (cinfo->poolp, mark);
- return SECSuccess;
-}
-
-
-/*
- * Start a PKCS7 enveloping context.
- *
- * "cert" is the cert for the recipient. It will be checked for validity.
- *
- * "certusage" describes the encryption usage (e.g. certUsageEmailRecipient)
- * XXX Maybe SECCertUsage should be split so that our caller just says
- * "email" and *we* add the "recipient" part -- otherwise our caller
- * could be lying about the usage; we do not want to allow encryption
- * certs for signing or vice versa.
- *
- * "certdb" is the cert database to use for verifying the cert.
- * It can be NULL if a default database is available (like in the client).
- *
- * "encalg" specifies the bulk encryption algorithm to use (e.g. SEC_OID_RC2).
- *
- * "keysize" specifies the bulk encryption key size, in bits.
- *
- * The return value can be passed to functions which add things to
- * it like more recipients, then eventually to SEC_PKCS7Encode() or to
- * SEC_PKCS7EncoderStart() to create the encoded data, and finally to
- * SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-extern SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert,
- SECCertUsage certusage,
- CERTCertDBHandle *certdb,
- SECOidTag encalg,
- int keysize,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg)
-{
- SEC_PKCS7ContentInfo *cinfo;
- SEC_PKCS7EnvelopedData *envd;
- SECStatus rv;
-
- cinfo = sec_pkcs7_create_content_info (SEC_OID_PKCS7_ENVELOPED_DATA,
- PR_FALSE, pwfn, pwfn_arg);
- if (cinfo == NULL)
- return NULL;
-
- rv = sec_pkcs7_add_recipient (cinfo, cert, certusage, certdb);
- if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
-
- envd = cinfo->content.envelopedData;
- PORT_Assert (envd != NULL);
-
- /*
- * XXX Might we want to allow content types other than data?
- * If so, via what interface?
- */
- rv = sec_pkcs7_init_encrypted_content_info (&(envd->encContentInfo),
- cinfo->poolp,
- SEC_OID_PKCS7_DATA, PR_FALSE,
- encalg, keysize);
- if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
-
- /* XXX Anything more to do here? */
-
- return cinfo;
-}
-
-
-/*
- * Add another recipient to an encrypted message.
- *
- * "cinfo" should be of type envelopedData or signedAndEnvelopedData;
- * SECFailure will be returned if it is not.
- *
- * "cert" is the cert for the recipient. It will be checked for validity.
- *
- * "certusage" describes the encryption usage (e.g. certUsageEmailRecipient)
- * XXX Maybe SECCertUsage should be split so that our caller just says
- * "email" and *we* add the "recipient" part -- otherwise our caller
- * could be lying about the usage; we do not want to allow encryption
- * certs for signing or vice versa.
- *
- * "certdb" is the cert database to use for verifying the cert.
- * It can be NULL if a default database is available (like in the client).
- */
-SECStatus
-SEC_PKCS7AddRecipient (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate *cert,
- SECCertUsage certusage,
- CERTCertDBHandle *certdb)
-{
- return sec_pkcs7_add_recipient (cinfo, cert, certusage, certdb);
-}
-
-
-/*
- * Create an empty PKCS7 data content info.
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateData (void)
-{
- return sec_pkcs7_create_content_info (SEC_OID_PKCS7_DATA, PR_FALSE,
- NULL, NULL);
-}
-
-
-/*
- * Create an empty PKCS7 encrypted content info.
- *
- * "algorithm" specifies the bulk encryption algorithm to use.
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg)
-{
- SEC_PKCS7ContentInfo *cinfo;
- SECAlgorithmID *algid;
- SEC_PKCS7EncryptedData *enc_data;
- SECStatus rv;
-
- cinfo = sec_pkcs7_create_content_info (SEC_OID_PKCS7_ENCRYPTED_DATA,
- PR_FALSE, pwfn, pwfn_arg);
- if (cinfo == NULL)
- return NULL;
-
- enc_data = cinfo->content.encryptedData;
- algid = &(enc_data->encContentInfo.contentEncAlg);
-
- if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm)) {
- rv = SECOID_SetAlgorithmID (cinfo->poolp, algid, algorithm, NULL);
- } else {
- /* Assume password-based-encryption.
- * Note: we can't generate pkcs5v2 from this interface.
- * PK11_CreateBPEAlgorithmID generates pkcs5v2 by accepting
- * non-PBE oids and assuming that they are pkcs5v2 oids, but
- * NSS_CMSEncryptedData_Create accepts non-PBE oids as regular
- * CMS encrypted data, so we can't tell SEC_PKCS7CreateEncryptedtedData
- * to create pkcs5v2 PBEs */
- SECAlgorithmID *pbe_algid;
- pbe_algid = PK11_CreatePBEAlgorithmID(algorithm,
- NSS_PBE_DEFAULT_ITERATION_COUNT,
- NULL);
- if (pbe_algid == NULL) {
- rv = SECFailure;
- } else {
- rv = SECOID_CopyAlgorithmID (cinfo->poolp, algid, pbe_algid);
- SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE);
- }
- }
-
- if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
-
- rv = sec_pkcs7_init_encrypted_content_info (&(enc_data->encContentInfo),
- cinfo->poolp,
- SEC_OID_PKCS7_DATA, PR_FALSE,
- algorithm, keysize);
- if (rv != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
-
- return cinfo;
-}
-
diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c
deleted file mode 100644
index 9a07b51eb..000000000
--- a/security/nss/lib/pkcs7/p7decode.c
+++ /dev/null
@@ -1,1909 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * PKCS7 decoding, verification.
- *
- * $Id$
- */
-
-#include "p7local.h"
-
-#include "cert.h"
- /* XXX do not want to have to include */
-#include "certdb.h" /* certdb.h -- the trust stuff needed by */
- /* the add certificate code needs to get */
- /* rewritten/abstracted and then this */
- /* include should be removed! */
-/*#include "cdbhdl.h" */
-#include "cryptohi.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "prtime.h"
-#include "secerr.h"
-#include "sechash.h" /* for HASH_GetHashObject() */
-#include "secder.h"
-#include "secpkcs5.h"
-
-struct sec_pkcs7_decoder_worker {
- int depth;
- int digcnt;
- void **digcxs;
- const SECHashObject **digobjs;
- sec_PKCS7CipherObject *decryptobj;
- PRBool saw_contents;
-};
-
-struct SEC_PKCS7DecoderContextStr {
- SEC_ASN1DecoderContext *dcx;
- SEC_PKCS7ContentInfo *cinfo;
- SEC_PKCS7DecoderContentCallback cb;
- void *cb_arg;
- SECKEYGetPasswordKey pwfn;
- void *pwfn_arg;
- struct sec_pkcs7_decoder_worker worker;
- PRArenaPool *tmp_poolp;
- int error;
- SEC_PKCS7GetDecryptKeyCallback dkcb;
- void *dkcb_arg;
- SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb;
-};
-
-/*
- * Handle one worker, decrypting and digesting the data as necessary.
- *
- * XXX If/when we support nested contents, this probably needs to be
- * revised somewhat to get passed the content-info (which unfortunately
- * can be two different types depending on whether it is encrypted or not)
- * corresponding to the given worker.
- */
-static void
-sec_pkcs7_decoder_work_data (SEC_PKCS7DecoderContext *p7dcx,
- struct sec_pkcs7_decoder_worker *worker,
- const unsigned char *data, unsigned long len,
- PRBool final)
-{
- unsigned char *buf = NULL;
- SECStatus rv;
- int i;
-
- /*
- * We should really have data to process, or we should be trying
- * to finish/flush the last block. (This is an overly paranoid
- * check since all callers are in this file and simple inspection
- * proves they do it right. But it could find a bug in future
- * modifications/development, that is why it is here.)
- */
- PORT_Assert ((data != NULL && len) || final);
-
- /*
- * Decrypt this chunk.
- *
- * XXX If we get an error, we do not want to do the digest or callback,
- * but we want to keep decoding. Or maybe we want to stop decoding
- * altogether if there is a callback, because obviously we are not
- * sending the data back and they want to know that.
- */
- if (worker->decryptobj != NULL) {
- /* XXX the following lengths should all be longs? */
- unsigned int inlen; /* length of data being decrypted */
- unsigned int outlen; /* length of decrypted data */
- unsigned int buflen; /* length available for decrypted data */
- SECItem *plain;
-
- inlen = len;
- buflen = sec_PKCS7DecryptLength (worker->decryptobj, inlen, final);
- if (buflen == 0) {
- if (inlen == 0) /* no input and no output */
- return;
- /*
- * No output is expected, but the input data may be buffered
- * so we still have to call Decrypt.
- */
- rv = sec_PKCS7Decrypt (worker->decryptobj, NULL, NULL, 0,
- data, inlen, final);
- if (rv != SECSuccess) {
- p7dcx->error = PORT_GetError();
- return; /* XXX indicate error? */
- }
- return;
- }
-
- if (p7dcx->cb != NULL) {
- buf = (unsigned char *) PORT_Alloc (buflen);
- plain = NULL;
- } else {
- unsigned long oldlen;
-
- /*
- * XXX This assumes one level of content only.
- * See comment above about nested content types.
- * XXX Also, it should work for signedAndEnvelopedData, too!
- */
- plain = &(p7dcx->cinfo->
- content.envelopedData->encContentInfo.plainContent);
-
- oldlen = plain->len;
- if (oldlen == 0) {
- buf = (unsigned char*)PORT_ArenaAlloc (p7dcx->cinfo->poolp,
- buflen);
- } else {
- buf = (unsigned char*)PORT_ArenaGrow (p7dcx->cinfo->poolp,
- plain->data,
- oldlen, oldlen + buflen);
- if (buf != NULL)
- buf += oldlen;
- }
- plain->data = buf;
- }
- if (buf == NULL) {
- p7dcx->error = SEC_ERROR_NO_MEMORY;
- return; /* XXX indicate error? */
- }
- rv = sec_PKCS7Decrypt (worker->decryptobj, buf, &outlen, buflen,
- data, inlen, final);
- if (rv != SECSuccess) {
- p7dcx->error = PORT_GetError();
- return; /* XXX indicate error? */
- }
- if (plain != NULL) {
- PORT_Assert (final || outlen == buflen);
- plain->len += outlen;
- }
- data = buf;
- len = outlen;
- }
-
- /*
- * Update the running digests.
- */
- if (len) {
- for (i = 0; i < worker->digcnt; i++) {
- (* worker->digobjs[i]->update) (worker->digcxs[i], data, len);
- }
- }
-
- /*
- * Pass back the contents bytes, and free the temporary buffer.
- */
- if (p7dcx->cb != NULL) {
- if (len)
- (* p7dcx->cb) (p7dcx->cb_arg, (const char *)data, len);
- if (worker->decryptobj != NULL) {
- PORT_Assert (buf != NULL);
- PORT_Free (buf);
- }
- }
-}
-
-static void
-sec_pkcs7_decoder_filter (void *arg, const char *data, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
-{
- SEC_PKCS7DecoderContext *p7dcx;
- struct sec_pkcs7_decoder_worker *worker;
-
- /*
- * Since we do not handle any nested contents, the only bytes we
- * are really interested in are the actual contents bytes (not
- * the identifier, length, or end-of-contents bytes). If we were
- * handling nested types we would probably need to do something
- * smarter based on depth and data_kind.
- */
- if (data_kind != SEC_ASN1_Contents)
- return;
-
- /*
- * The ASN.1 decoder should not even call us with a length of 0.
- * Just being paranoid.
- */
- PORT_Assert (len);
- if (len == 0)
- return;
-
- p7dcx = (SEC_PKCS7DecoderContext*)arg;
-
- /*
- * Handling nested contents would mean that there is a chain
- * of workers -- one per each level of content. The following
- * would start with the first worker and loop over them.
- */
- worker = &(p7dcx->worker);
-
- worker->saw_contents = PR_TRUE;
-
- sec_pkcs7_decoder_work_data (p7dcx, worker,
- (const unsigned char *) data, len, PR_FALSE);
-}
-
-
-/*
- * Create digest contexts for each algorithm in "digestalgs".
- * No algorithms is not an error, we just do not do anything.
- * An error (like trouble allocating memory), marks the error
- * in "p7dcx" and returns SECFailure, which means that our caller
- * should just give up altogether.
- */
-static SECStatus
-sec_pkcs7_decoder_start_digests (SEC_PKCS7DecoderContext *p7dcx, int depth,
- SECAlgorithmID **digestalgs)
-{
- int i, digcnt;
-
- if (digestalgs == NULL)
- return SECSuccess;
-
- /*
- * Count the algorithms.
- */
- digcnt = 0;
- while (digestalgs[digcnt] != NULL)
- digcnt++;
-
- /*
- * No algorithms means no work to do.
- * Just act as if there were no algorithms specified.
- */
- if (digcnt == 0)
- return SECSuccess;
-
- p7dcx->worker.digcxs = (void**)PORT_ArenaAlloc (p7dcx->tmp_poolp,
- digcnt * sizeof (void *));
- p7dcx->worker.digobjs = (const SECHashObject**)PORT_ArenaAlloc (p7dcx->tmp_poolp,
- digcnt * sizeof (SECHashObject *));
- if (p7dcx->worker.digcxs == NULL || p7dcx->worker.digobjs == NULL) {
- p7dcx->error = SEC_ERROR_NO_MEMORY;
- return SECFailure;
- }
-
- p7dcx->worker.depth = depth;
- p7dcx->worker.digcnt = 0;
-
- /*
- * Create a digest context for each algorithm.
- */
- for (i = 0; i < digcnt; i++) {
- SECAlgorithmID * algid = digestalgs[i];
- SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm));
- const SECHashObject *digobj = HASH_GetHashObjectByOidTag(oidTag);
- void *digcx;
-
- /*
- * Skip any algorithm we do not even recognize; obviously,
- * this could be a problem, but if it is critical then the
- * result will just be that the signature does not verify.
- * We do not necessarily want to error out here, because
- * the particular algorithm may not actually be important,
- * but we cannot know that until later.
- */
- if (digobj == NULL) {
- p7dcx->worker.digcnt--;
- continue;
- }
-
- digcx = (* digobj->create)();
- if (digcx != NULL) {
- (* digobj->begin) (digcx);
- p7dcx->worker.digobjs[p7dcx->worker.digcnt] = digobj;
- p7dcx->worker.digcxs[p7dcx->worker.digcnt] = digcx;
- p7dcx->worker.digcnt++;
- }
- }
-
- if (p7dcx->worker.digcnt != 0)
- SEC_ASN1DecoderSetFilterProc (p7dcx->dcx,
- sec_pkcs7_decoder_filter,
- p7dcx,
- (PRBool)(p7dcx->cb != NULL));
- return SECSuccess;
-}
-
-
-/*
- * Close out all of the digest contexts, storing the results in "digestsp".
- */
-static SECStatus
-sec_pkcs7_decoder_finish_digests (SEC_PKCS7DecoderContext *p7dcx,
- PRArenaPool *poolp,
- SECItem ***digestsp)
-{
- struct sec_pkcs7_decoder_worker *worker;
- const SECHashObject *digobj;
- void *digcx;
- SECItem **digests, *digest;
- int i;
- void *mark;
-
- /*
- * XXX Handling nested contents would mean that there is a chain
- * of workers -- one per each level of content. The following
- * would want to find the last worker in the chain.
- */
- worker = &(p7dcx->worker);
-
- /*
- * If no digests, then we have nothing to do.
- */
- if (worker->digcnt == 0)
- return SECSuccess;
-
- /*
- * No matter what happens after this, we want to stop filtering.
- * XXX If we handle nested contents, we only want to stop filtering
- * if we are finishing off the *last* worker.
- */
- SEC_ASN1DecoderClearFilterProc (p7dcx->dcx);
-
- /*
- * If we ended up with no contents, just destroy each
- * digest context -- they are meaningless and potentially
- * confusing, because their presence would imply some content
- * was digested.
- */
- if (! worker->saw_contents) {
- for (i = 0; i < worker->digcnt; i++) {
- digcx = worker->digcxs[i];
- digobj = worker->digobjs[i];
- (* digobj->destroy) (digcx, PR_TRUE);
- }
- return SECSuccess;
- }
-
- mark = PORT_ArenaMark (poolp);
-
- /*
- * Close out each digest context, saving digest away.
- */
- digests =
- (SECItem**)PORT_ArenaAlloc (poolp,(worker->digcnt+1)*sizeof(SECItem *));
- digest = (SECItem*)PORT_ArenaAlloc (poolp, worker->digcnt*sizeof(SECItem));
- if (digests == NULL || digest == NULL) {
- p7dcx->error = PORT_GetError();
- PORT_ArenaRelease (poolp, mark);
- return SECFailure;
- }
-
- for (i = 0; i < worker->digcnt; i++, digest++) {
- digcx = worker->digcxs[i];
- digobj = worker->digobjs[i];
-
- digest->data = (unsigned char*)PORT_ArenaAlloc (poolp, digobj->length);
- if (digest->data == NULL) {
- p7dcx->error = PORT_GetError();
- PORT_ArenaRelease (poolp, mark);
- return SECFailure;
- }
-
- digest->len = digobj->length;
- (* digobj->end) (digcx, digest->data, &(digest->len), digest->len);
- (* digobj->destroy) (digcx, PR_TRUE);
-
- digests[i] = digest;
- }
- digests[i] = NULL;
- *digestsp = digests;
-
- PORT_ArenaUnmark (poolp, mark);
- return SECSuccess;
-}
-
-/*
- * XXX Need comment explaining following helper function (which is used
- * by sec_pkcs7_decoder_start_decrypt).
- */
-
-static PK11SymKey *
-sec_pkcs7_decoder_get_recipient_key (SEC_PKCS7DecoderContext *p7dcx,
- SEC_PKCS7RecipientInfo **recipientinfos,
- SEC_PKCS7EncryptedContentInfo *enccinfo)
-{
- SEC_PKCS7RecipientInfo *ri;
- CERTCertificate *cert = NULL;
- SECKEYPrivateKey *privkey = NULL;
- PK11SymKey *bulkkey = NULL;
- SECOidTag keyalgtag, bulkalgtag, encalgtag;
- PK11SlotInfo *slot = NULL;
-
- if (recipientinfos == NULL || recipientinfos[0] == NULL) {
- p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT;
- goto no_key_found;
- }
-
- cert = PK11_FindCertAndKeyByRecipientList(&slot,recipientinfos,&ri,
- &privkey, p7dcx->pwfn_arg);
- if (cert == NULL) {
- p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT;
- goto no_key_found;
- }
-
- ri->cert = cert; /* so we can find it later */
- PORT_Assert(privkey != NULL);
-
- keyalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
- encalgtag = SECOID_GetAlgorithmTag (&(ri->keyEncAlg));
- if (keyalgtag != encalgtag) {
- p7dcx->error = SEC_ERROR_PKCS7_KEYALG_MISMATCH;
- goto no_key_found;
- }
- bulkalgtag = SECOID_GetAlgorithmTag (&(enccinfo->contentEncAlg));
-
- switch (encalgtag) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- bulkkey = PK11_PubUnwrapSymKey (privkey, &ri->encKey,
- PK11_AlgtagToMechanism (bulkalgtag),
- CKA_DECRYPT, 0);
- if (bulkkey == NULL) {
- p7dcx->error = PORT_GetError();
- PORT_SetError(0);
- goto no_key_found;
- }
- break;
- default:
- p7dcx->error = SEC_ERROR_UNSUPPORTED_KEYALG;
- break;
- }
-
-no_key_found:
- if (privkey != NULL)
- SECKEY_DestroyPrivateKey (privkey);
- if (slot != NULL)
- PK11_FreeSlot(slot);
-
- return bulkkey;
-}
-
-/*
- * XXX The following comment is old -- the function used to only handle
- * EnvelopedData or SignedAndEnvelopedData but now handles EncryptedData
- * as well (and it had all of the code of the helper function above
- * built into it), though the comment was left as is. Fix it...
- *
- * We are just about to decode the content of an EnvelopedData.
- * Set up a decryption context so we can decrypt as we go.
- * Presumably we are one of the recipients listed in "recipientinfos".
- * (XXX And if we are not, or if we have trouble, what should we do?
- * It would be nice to let the decoding still work. Maybe it should
- * be an error if there is a content callback, but not an error otherwise?)
- * The encryption key and related information can be found in "enccinfo".
- */
-static SECStatus
-sec_pkcs7_decoder_start_decrypt (SEC_PKCS7DecoderContext *p7dcx, int depth,
- SEC_PKCS7RecipientInfo **recipientinfos,
- SEC_PKCS7EncryptedContentInfo *enccinfo,
- PK11SymKey **copy_key_for_signature)
-{
- PK11SymKey *bulkkey = NULL;
- sec_PKCS7CipherObject *decryptobj;
-
- /*
- * If a callback is supplied to retrieve the encryption key,
- * for instance, for Encrypted Content infos, then retrieve
- * the bulkkey from the callback. Otherwise, assume that
- * we are processing Enveloped or SignedAndEnveloped data
- * content infos.
- *
- * XXX Put an assert here?
- */
- if (SEC_PKCS7ContentType(p7dcx->cinfo) == SEC_OID_PKCS7_ENCRYPTED_DATA) {
- if (p7dcx->dkcb != NULL) {
- bulkkey = (*p7dcx->dkcb)(p7dcx->dkcb_arg,
- &(enccinfo->contentEncAlg));
- }
- enccinfo->keysize = 0;
- } else {
- bulkkey = sec_pkcs7_decoder_get_recipient_key (p7dcx, recipientinfos,
- enccinfo);
- if (bulkkey == NULL) goto no_decryption;
- enccinfo->keysize = PK11_GetKeyStrength(bulkkey,
- &(enccinfo->contentEncAlg));
-
- }
-
- /*
- * XXX I think following should set error in p7dcx and clear set error
- * (as used to be done here, or as is done in get_receipient_key above.
- */
- if(bulkkey == NULL) {
- goto no_decryption;
- }
-
- /*
- * We want to make sure decryption is allowed. This is done via
- * a callback specified in SEC_PKCS7DecoderStart().
- */
- if (p7dcx->decrypt_allowed_cb) {
- if ((*p7dcx->decrypt_allowed_cb) (&(enccinfo->contentEncAlg),
- bulkkey) == PR_FALSE) {
- p7dcx->error = SEC_ERROR_DECRYPTION_DISALLOWED;
- goto no_decryption;
- }
- } else {
- p7dcx->error = SEC_ERROR_DECRYPTION_DISALLOWED;
- goto no_decryption;
- }
-
- /*
- * When decrypting a signedAndEnvelopedData, the signature also has
- * to be decrypted with the bulk encryption key; to avoid having to
- * get it all over again later (and do another potentially expensive
- * RSA operation), copy it for later signature verification to use.
- */
- if (copy_key_for_signature != NULL)
- *copy_key_for_signature = PK11_ReferenceSymKey (bulkkey);
-
- /*
- * Now we have the bulk encryption key (in bulkkey) and the
- * the algorithm (in enccinfo->contentEncAlg). Using those,
- * create a decryption context.
- */
- decryptobj = sec_PKCS7CreateDecryptObject (bulkkey,
- &(enccinfo->contentEncAlg));
-
- /*
- * We are done with (this) bulkkey now.
- */
- PK11_FreeSymKey (bulkkey);
-
- if (decryptobj == NULL) {
- p7dcx->error = PORT_GetError();
- PORT_SetError(0);
- goto no_decryption;
- }
-
- SEC_ASN1DecoderSetFilterProc (p7dcx->dcx,
- sec_pkcs7_decoder_filter,
- p7dcx,
- (PRBool)(p7dcx->cb != NULL));
-
- p7dcx->worker.depth = depth;
- p7dcx->worker.decryptobj = decryptobj;
-
- return SECSuccess;
-
-no_decryption:
- /*
- * For some reason (error set already, if appropriate), we cannot
- * decrypt the content. I am not sure what exactly is the right
- * thing to do here; in some cases we want to just stop, and in
- * others we want to let the decoding finish even though we cannot
- * decrypt the content. My current thinking is that if the caller
- * set up a content callback, then they are really interested in
- * getting (decrypted) content, and if they cannot they will want
- * to know about it. However, if no callback was specified, then
- * maybe it is not important that the decryption failed.
- */
- if (p7dcx->cb != NULL)
- return SECFailure;
- else
- return SECSuccess; /* Let the decoding continue. */
-}
-
-
-static SECStatus
-sec_pkcs7_decoder_finish_decrypt (SEC_PKCS7DecoderContext *p7dcx,
- PRArenaPool *poolp,
- SEC_PKCS7EncryptedContentInfo *enccinfo)
-{
- struct sec_pkcs7_decoder_worker *worker;
-
- /*
- * XXX Handling nested contents would mean that there is a chain
- * of workers -- one per each level of content. The following
- * would want to find the last worker in the chain.
- */
- worker = &(p7dcx->worker);
-
- /*
- * If no decryption context, then we have nothing to do.
- */
- if (worker->decryptobj == NULL)
- return SECSuccess;
-
- /*
- * No matter what happens after this, we want to stop filtering.
- * XXX If we handle nested contents, we only want to stop filtering
- * if we are finishing off the *last* worker.
- */
- SEC_ASN1DecoderClearFilterProc (p7dcx->dcx);
-
- /*
- * Handle the last block.
- */
- sec_pkcs7_decoder_work_data (p7dcx, worker, NULL, 0, PR_TRUE);
-
- /*
- * All done, destroy it.
- */
- sec_PKCS7DestroyDecryptObject (worker->decryptobj);
- worker->decryptobj = NULL;
-
- return SECSuccess;
-}
-
-
-static void
-sec_pkcs7_decoder_notify (void *arg, PRBool before, void *dest, int depth)
-{
- SEC_PKCS7DecoderContext *p7dcx;
- SEC_PKCS7ContentInfo *cinfo;
- SEC_PKCS7SignedData *sigd;
- SEC_PKCS7EnvelopedData *envd;
- SEC_PKCS7SignedAndEnvelopedData *saed;
- SEC_PKCS7EncryptedData *encd;
- SEC_PKCS7DigestedData *digd;
- PRBool after;
- SECStatus rv;
-
- /*
- * Just to make the code easier to read, create an "after" variable
- * that is equivalent to "not before".
- * (This used to be just the statement "after = !before", but that
- * causes a warning on the mac; to avoid that, we do it the long way.)
- */
- if (before)
- after = PR_FALSE;
- else
- after = PR_TRUE;
-
- p7dcx = (SEC_PKCS7DecoderContext*)arg;
- cinfo = p7dcx->cinfo;
-
- if (cinfo->contentTypeTag == NULL) {
- if (after && dest == &(cinfo->contentType))
- cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
- return;
- }
-
- switch (cinfo->contentTypeTag->offset) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- sigd = cinfo->content.signedData;
- if (sigd == NULL)
- break;
-
- if (sigd->contentInfo.contentTypeTag == NULL) {
- if (after && dest == &(sigd->contentInfo.contentType))
- sigd->contentInfo.contentTypeTag =
- SECOID_FindOID(&(sigd->contentInfo.contentType));
- break;
- }
-
- /*
- * We only set up a filtering digest if the content is
- * plain DATA; anything else needs more work because a
- * second pass is required to produce a DER encoding from
- * an input that can be BER encoded. (This is a requirement
- * of PKCS7 that is unfortunate, but there you have it.)
- *
- * XXX Also, since we stop here if this is not DATA, the
- * inner content is not getting processed at all. Someday
- * we may want to fix that.
- */
- if (sigd->contentInfo.contentTypeTag->offset != SEC_OID_PKCS7_DATA) {
- /* XXX Set an error in p7dcx->error */
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
- break;
- }
-
- /*
- * Just before the content, we want to set up a digest context
- * for each digest algorithm listed, and start a filter which
- * will run all of the contents bytes through that digest.
- */
- if (before && dest == &(sigd->contentInfo.content)) {
- rv = sec_pkcs7_decoder_start_digests (p7dcx, depth,
- sigd->digestAlgorithms);
- if (rv != SECSuccess)
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
-
- break;
- }
-
- /*
- * XXX To handle nested types, here is where we would want
- * to check for inner boundaries that need handling.
- */
-
- /*
- * Are we done?
- */
- if (after && dest == &(sigd->contentInfo.content)) {
- /*
- * Close out the digest contexts. We ignore any error
- * because we are stopping anyway; the error status left
- * behind in p7dcx will be seen by outer functions.
- */
- (void) sec_pkcs7_decoder_finish_digests (p7dcx, cinfo->poolp,
- &(sigd->digests));
-
- /*
- * XXX To handle nested contents, we would need to remove
- * the worker from the chain (and free it).
- */
-
- /*
- * Stop notify.
- */
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
- }
- break;
-
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- envd = cinfo->content.envelopedData;
- if (envd == NULL)
- break;
-
- if (envd->encContentInfo.contentTypeTag == NULL) {
- if (after && dest == &(envd->encContentInfo.contentType))
- envd->encContentInfo.contentTypeTag =
- SECOID_FindOID(&(envd->encContentInfo.contentType));
- break;
- }
-
- /*
- * Just before the content, we want to set up a decryption
- * context, and start a filter which will run all of the
- * contents bytes through it to determine the plain content.
- */
- if (before && dest == &(envd->encContentInfo.encContent)) {
- rv = sec_pkcs7_decoder_start_decrypt (p7dcx, depth,
- envd->recipientInfos,
- &(envd->encContentInfo),
- NULL);
- if (rv != SECSuccess)
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
-
- break;
- }
-
- /*
- * Are we done?
- */
- if (after && dest == &(envd->encContentInfo.encContent)) {
- /*
- * Close out the decryption context. We ignore any error
- * because we are stopping anyway; the error status left
- * behind in p7dcx will be seen by outer functions.
- */
- (void) sec_pkcs7_decoder_finish_decrypt (p7dcx, cinfo->poolp,
- &(envd->encContentInfo));
-
- /*
- * XXX To handle nested contents, we would need to remove
- * the worker from the chain (and free it).
- */
-
- /*
- * Stop notify.
- */
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
- }
- break;
-
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- saed = cinfo->content.signedAndEnvelopedData;
- if (saed == NULL)
- break;
-
- if (saed->encContentInfo.contentTypeTag == NULL) {
- if (after && dest == &(saed->encContentInfo.contentType))
- saed->encContentInfo.contentTypeTag =
- SECOID_FindOID(&(saed->encContentInfo.contentType));
- break;
- }
-
- /*
- * Just before the content, we want to set up a decryption
- * context *and* digest contexts, and start a filter which
- * will run all of the contents bytes through both.
- */
- if (before && dest == &(saed->encContentInfo.encContent)) {
- rv = sec_pkcs7_decoder_start_decrypt (p7dcx, depth,
- saed->recipientInfos,
- &(saed->encContentInfo),
- &(saed->sigKey));
- if (rv == SECSuccess)
- rv = sec_pkcs7_decoder_start_digests (p7dcx, depth,
- saed->digestAlgorithms);
- if (rv != SECSuccess)
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
-
- break;
- }
-
- /*
- * Are we done?
- */
- if (after && dest == &(saed->encContentInfo.encContent)) {
- /*
- * Close out the decryption and digests contexts.
- * We ignore any errors because we are stopping anyway;
- * the error status left behind in p7dcx will be seen by
- * outer functions.
- *
- * Note that the decrypt stuff must be called first;
- * it may have a last buffer to do which in turn has
- * to be added to the digest.
- */
- (void) sec_pkcs7_decoder_finish_decrypt (p7dcx, cinfo->poolp,
- &(saed->encContentInfo));
- (void) sec_pkcs7_decoder_finish_digests (p7dcx, cinfo->poolp,
- &(saed->digests));
-
- /*
- * XXX To handle nested contents, we would need to remove
- * the worker from the chain (and free it).
- */
-
- /*
- * Stop notify.
- */
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
- }
- break;
-
- case SEC_OID_PKCS7_DIGESTED_DATA:
- digd = cinfo->content.digestedData;
-
- /*
- * XXX Want to do the digest or not? Maybe future enhancement...
- */
- if (before && dest == &(digd->contentInfo.content.data)) {
- SEC_ASN1DecoderSetFilterProc (p7dcx->dcx, sec_pkcs7_decoder_filter,
- p7dcx,
- (PRBool)(p7dcx->cb != NULL));
- break;
- }
-
- /*
- * Are we done?
- */
- if (after && dest == &(digd->contentInfo.content.data)) {
- SEC_ASN1DecoderClearFilterProc (p7dcx->dcx);
- }
- break;
-
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- encd = cinfo->content.encryptedData;
-
- /*
- * XXX If the decryption key callback is set, we want to start
- * the decryption. If the callback is not set, we will treat the
- * content as plain data, since we do not have the key.
- *
- * Is this the proper thing to do?
- */
- if (before && dest == &(encd->encContentInfo.encContent)) {
- /*
- * Start the encryption process if the decryption key callback
- * is present. Otherwise, treat the content like plain data.
- */
- rv = SECSuccess;
- if (p7dcx->dkcb != NULL) {
- rv = sec_pkcs7_decoder_start_decrypt (p7dcx, depth, NULL,
- &(encd->encContentInfo),
- NULL);
- }
-
- if (rv != SECSuccess)
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
-
- break;
- }
-
- /*
- * Are we done?
- */
- if (after && dest == &(encd->encContentInfo.encContent)) {
- /*
- * Close out the decryption context. We ignore any error
- * because we are stopping anyway; the error status left
- * behind in p7dcx will be seen by outer functions.
- */
- (void) sec_pkcs7_decoder_finish_decrypt (p7dcx, cinfo->poolp,
- &(encd->encContentInfo));
-
- /*
- * Stop notify.
- */
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
- }
- break;
-
- case SEC_OID_PKCS7_DATA:
- /*
- * If a output callback has been specified, we want to set the filter
- * to call the callback. This is taken care of in
- * sec_pkcs7_decoder_start_decrypt() or
- * sec_pkcs7_decoder_start_digests() for the other content types.
- */
-
- if (before && dest == &(cinfo->content.data)) {
-
- /*
- * Set the filter proc up.
- */
- SEC_ASN1DecoderSetFilterProc (p7dcx->dcx,
- sec_pkcs7_decoder_filter,
- p7dcx,
- (PRBool)(p7dcx->cb != NULL));
- break;
- }
-
- if (after && dest == &(cinfo->content.data)) {
- /*
- * Time to clean up after ourself, stop the Notify and Filter
- * procedures.
- */
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
- SEC_ASN1DecoderClearFilterProc (p7dcx->dcx);
- }
- break;
-
- default:
- SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx);
- break;
- }
-}
-
-
-SEC_PKCS7DecoderContext *
-SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback cb, void *cb_arg,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg,
- SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb,
- void *decrypt_key_cb_arg,
- SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb)
-{
- SEC_PKCS7DecoderContext *p7dcx;
- SEC_ASN1DecoderContext *dcx;
- SEC_PKCS7ContentInfo *cinfo;
- PRArenaPool *poolp;
-
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
- if (poolp == NULL)
- return NULL;
-
- cinfo = (SEC_PKCS7ContentInfo*)PORT_ArenaZAlloc (poolp, sizeof(*cinfo));
- if (cinfo == NULL) {
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
- }
-
- cinfo->poolp = poolp;
- cinfo->pwfn = pwfn;
- cinfo->pwfn_arg = pwfn_arg;
- cinfo->created = PR_FALSE;
- cinfo->refCount = 1;
-
- p7dcx =
- (SEC_PKCS7DecoderContext*)PORT_ZAlloc (sizeof(SEC_PKCS7DecoderContext));
- if (p7dcx == NULL) {
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
- }
-
- p7dcx->tmp_poolp = PORT_NewArena (1024); /* XXX what is right value? */
- if (p7dcx->tmp_poolp == NULL) {
- PORT_Free (p7dcx);
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
- }
-
- dcx = SEC_ASN1DecoderStart (poolp, cinfo, sec_PKCS7ContentInfoTemplate);
- if (dcx == NULL) {
- PORT_FreeArena (p7dcx->tmp_poolp, PR_FALSE);
- PORT_Free (p7dcx);
- PORT_FreeArena (poolp, PR_FALSE);
- return NULL;
- }
-
- SEC_ASN1DecoderSetNotifyProc (dcx, sec_pkcs7_decoder_notify, p7dcx);
-
- p7dcx->dcx = dcx;
- p7dcx->cinfo = cinfo;
- p7dcx->cb = cb;
- p7dcx->cb_arg = cb_arg;
- p7dcx->pwfn = pwfn;
- p7dcx->pwfn_arg = pwfn_arg;
- p7dcx->dkcb = decrypt_key_cb;
- p7dcx->dkcb_arg = decrypt_key_cb_arg;
- p7dcx->decrypt_allowed_cb = decrypt_allowed_cb;
-
- return p7dcx;
-}
-
-
-/*
- * Do the next chunk of PKCS7 decoding. If there is a problem, set
- * an error and return a failure status. Note that in the case of
- * an error, this routine is still prepared to be called again and
- * again in case that is the easiest route for our caller to take.
- * We simply detect it and do not do anything except keep setting
- * that error in case our caller has not noticed it yet...
- */
-SECStatus
-SEC_PKCS7DecoderUpdate(SEC_PKCS7DecoderContext *p7dcx,
- const char *buf, unsigned long len)
-{
- if (p7dcx->cinfo != NULL && p7dcx->dcx != NULL) {
- PORT_Assert (p7dcx->error == 0);
- if (p7dcx->error == 0) {
- if (SEC_ASN1DecoderUpdate (p7dcx->dcx, buf, len) != SECSuccess) {
- p7dcx->error = PORT_GetError();
- PORT_Assert (p7dcx->error);
- if (p7dcx->error == 0)
- p7dcx->error = -1;
- }
- }
- }
-
- if (p7dcx->error) {
- if (p7dcx->dcx != NULL) {
- (void) SEC_ASN1DecoderFinish (p7dcx->dcx);
- p7dcx->dcx = NULL;
- }
- if (p7dcx->cinfo != NULL) {
- SEC_PKCS7DestroyContentInfo (p7dcx->cinfo);
- p7dcx->cinfo = NULL;
- }
- PORT_SetError (p7dcx->error);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-
-SEC_PKCS7ContentInfo *
-SEC_PKCS7DecoderFinish(SEC_PKCS7DecoderContext *p7dcx)
-{
- SEC_PKCS7ContentInfo *cinfo;
-
- cinfo = p7dcx->cinfo;
- if (p7dcx->dcx != NULL) {
- if (SEC_ASN1DecoderFinish (p7dcx->dcx) != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- cinfo = NULL;
- }
- }
- /* free any NSS data structures */
- if (p7dcx->worker.decryptobj) {
- sec_PKCS7DestroyDecryptObject (p7dcx->worker.decryptobj);
- }
- PORT_FreeArena (p7dcx->tmp_poolp, PR_FALSE);
- PORT_Free (p7dcx);
- return cinfo;
-}
-
-
-SEC_PKCS7ContentInfo *
-SEC_PKCS7DecodeItem(SECItem *p7item,
- SEC_PKCS7DecoderContentCallback cb, void *cb_arg,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg,
- SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb,
- void *decrypt_key_cb_arg,
- SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb)
-{
- SEC_PKCS7DecoderContext *p7dcx;
-
- p7dcx = SEC_PKCS7DecoderStart(cb, cb_arg, pwfn, pwfn_arg, decrypt_key_cb,
- decrypt_key_cb_arg, decrypt_allowed_cb);
- if (!p7dcx) {
- /* error code is set */
- return NULL;
- }
- (void) SEC_PKCS7DecoderUpdate(p7dcx, (char *) p7item->data, p7item->len);
- return SEC_PKCS7DecoderFinish(p7dcx);
-}
-
-/*
- * Abort the ASN.1 stream. Used by pkcs 12
- */
-void
-SEC_PKCS7DecoderAbort(SEC_PKCS7DecoderContext *p7dcx, int error)
-{
- PORT_Assert(p7dcx);
- SEC_ASN1DecoderAbort(p7dcx->dcx, error);
-}
-
-
-/*
- * If the thing contains any certs or crls return true; false otherwise.
- */
-PRBool
-SEC_PKCS7ContainsCertsOrCrls(SEC_PKCS7ContentInfo *cinfo)
-{
- SECOidTag kind;
- SECItem **certs;
- CERTSignedCrl **crls;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- default:
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- return PR_FALSE;
- case SEC_OID_PKCS7_SIGNED_DATA:
- certs = cinfo->content.signedData->rawCerts;
- crls = cinfo->content.signedData->crls;
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- certs = cinfo->content.signedAndEnvelopedData->rawCerts;
- crls = cinfo->content.signedAndEnvelopedData->crls;
- break;
- }
-
- /*
- * I know this could be collapsed, but I was in a mood to be explicit.
- */
- if (certs != NULL && certs[0] != NULL)
- return PR_TRUE;
- else if (crls != NULL && crls[0] != NULL)
- return PR_TRUE;
- else
- return PR_FALSE;
-}
-
-/* return the content length...could use GetContent, however we
- * need the encrypted content length
- */
-PRBool
-SEC_PKCS7IsContentEmpty(SEC_PKCS7ContentInfo *cinfo, unsigned int minLen)
-{
- SECItem *item = NULL;
-
- if(cinfo == NULL) {
- return PR_TRUE;
- }
-
- switch(SEC_PKCS7ContentType(cinfo))
- {
- case SEC_OID_PKCS7_DATA:
- item = cinfo->content.data;
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- item = &cinfo->content.encryptedData->encContentInfo.encContent;
- break;
- default:
- /* add other types */
- return PR_FALSE;
- }
-
- if(!item) {
- return PR_TRUE;
- } else if(item->len <= minLen) {
- return PR_TRUE;
- }
-
- return PR_FALSE;
-}
-
-
-PRBool
-SEC_PKCS7ContentIsEncrypted(SEC_PKCS7ContentInfo *cinfo)
-{
- SECOidTag kind;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- default:
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_SIGNED_DATA:
- return PR_FALSE;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- return PR_TRUE;
- }
-}
-
-
-/*
- * If the PKCS7 content has a signature (not just *could* have a signature)
- * return true; false otherwise. This can/should be called before calling
- * VerifySignature, which will always indicate failure if no signature is
- * present, but that does not mean there even was a signature!
- * Note that the content itself can be empty (detached content was sent
- * another way); it is the presence of the signature that matters.
- */
-PRBool
-SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo)
-{
- SECOidTag kind;
- SEC_PKCS7SignerInfo **signerinfos;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- default:
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- return PR_FALSE;
- case SEC_OID_PKCS7_SIGNED_DATA:
- signerinfos = cinfo->content.signedData->signerInfos;
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- signerinfos = cinfo->content.signedAndEnvelopedData->signerInfos;
- break;
- }
-
- /*
- * I know this could be collapsed; but I kind of think it will get
- * more complicated before I am finished, so...
- */
- if (signerinfos != NULL && signerinfos[0] != NULL)
- return PR_TRUE;
- else
- return PR_FALSE;
-}
-
-
-/*
- * SEC_PKCS7ContentVerifySignature
- * Look at a PKCS7 contentInfo and check if the signature is good.
- * The digest was either calculated earlier (and is stored in the
- * contentInfo itself) or is passed in via "detached_digest".
- *
- * The verification checks that the signing cert is valid and trusted
- * for the purpose specified by "certusage".
- *
- * In addition, if "keepcerts" is true, add any new certificates found
- * into our local database.
- *
- * XXX Each place which returns PR_FALSE should be sure to have a good
- * error set for inspection by the caller. Alternatively, we could create
- * an enumeration of success and each type of failure and return that
- * instead of a boolean. For now, the default in a bad situation is to
- * set the error to SEC_ERROR_PKCS7_BAD_SIGNATURE. But this should be
- * reviewed; better (more specific) errors should be possible (to distinguish
- * a signature failure from a badly-formed pkcs7 signedData, for example).
- * Some of the errors should probably just be SEC_ERROR_BAD_SIGNATURE,
- * but that has a less helpful error string associated with it right now;
- * if/when that changes, review and change these as needed.
- *
- * XXX This is broken wrt signedAndEnvelopedData. In that case, the
- * message digest is doubly encrypted -- first encrypted with the signer
- * private key but then again encrypted with the bulk encryption key used
- * to encrypt the content. So before we can pass the digest to VerifyDigest,
- * we need to decrypt it with the bulk encryption key. Also, in this case,
- * there should be NO authenticatedAttributes (signerinfo->authAttr should
- * be NULL).
- */
-static PRBool
-sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
- SECCertUsage certusage,
- const SECItem *detached_digest,
- HASH_HashType digest_type,
- PRBool keepcerts)
-{
- SECAlgorithmID **digestalgs, *bulkid;
- const SECItem *digest;
- SECItem **digests;
- SECItem **rawcerts;
- CERTSignedCrl **crls;
- SEC_PKCS7SignerInfo **signerinfos, *signerinfo;
- CERTCertificate *cert, **certs;
- PRBool goodsig;
- CERTCertDBHandle *certdb, *defaultdb;
- SECOidTag encTag,digestTag;
- HASH_HashType found_type;
- int i, certcount;
- SECKEYPublicKey *publickey;
- SECItem *content_type;
- PK11SymKey *sigkey;
- SECItem *encoded_stime;
- int64 stime;
- SECStatus rv;
-
- /*
- * Everything needed in order to "goto done" safely.
- */
- goodsig = PR_FALSE;
- certcount = 0;
- cert = NULL;
- certs = NULL;
- certdb = NULL;
- defaultdb = CERT_GetDefaultCertDB();
- publickey = NULL;
-
- if (! SEC_PKCS7ContentIsSigned(cinfo)) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- PORT_Assert (cinfo->contentTypeTag != NULL);
-
- switch (cinfo->contentTypeTag->offset) {
- default:
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- /* Could only get here if SEC_PKCS7ContentIsSigned is broken. */
- PORT_Assert (0);
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sdp;
-
- sdp = cinfo->content.signedData;
- digestalgs = sdp->digestAlgorithms;
- digests = sdp->digests;
- rawcerts = sdp->rawCerts;
- crls = sdp->crls;
- signerinfos = sdp->signerInfos;
- content_type = &(sdp->contentInfo.contentType);
- sigkey = NULL;
- bulkid = NULL;
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
-
- saedp = cinfo->content.signedAndEnvelopedData;
- digestalgs = saedp->digestAlgorithms;
- digests = saedp->digests;
- rawcerts = saedp->rawCerts;
- crls = saedp->crls;
- signerinfos = saedp->signerInfos;
- content_type = &(saedp->encContentInfo.contentType);
- sigkey = saedp->sigKey;
- bulkid = &(saedp->encContentInfo.contentEncAlg);
- }
- break;
- }
-
- if ((signerinfos == NULL) || (signerinfos[0] == NULL)) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- /*
- * XXX Need to handle multiple signatures; checking them is easy,
- * but what should be the semantics here (like, return value)?
- */
- if (signerinfos[1] != NULL) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- signerinfo = signerinfos[0];
-
- /*
- * XXX I would like to just pass the issuerAndSN, along with the rawcerts
- * and crls, to some function that did all of this certificate stuff
- * (open/close the database if necessary, verifying the certs, etc.)
- * and gave me back a cert pointer if all was good.
- */
- certdb = defaultdb;
- if (certdb == NULL) {
- goto done;
- }
-
- certcount = 0;
- if (rawcerts != NULL) {
- for (; rawcerts[certcount] != NULL; certcount++) {
- /* just counting */
- }
- }
-
- /*
- * Note that the result of this is that each cert in "certs"
- * needs to be destroyed.
- */
- rv = CERT_ImportCerts(certdb, certusage, certcount, rawcerts, &certs,
- keepcerts, PR_FALSE, NULL);
- if ( rv != SECSuccess ) {
- goto done;
- }
-
- /*
- * This cert will also need to be freed, but since we save it
- * in signerinfo for later, we do not want to destroy it when
- * we leave this function -- we let the clean-up of the entire
- * cinfo structure later do the destroy of this cert.
- */
- cert = CERT_FindCertByIssuerAndSN(certdb, signerinfo->issuerAndSN);
- if (cert == NULL) {
- goto done;
- }
-
- signerinfo->cert = cert;
-
- /*
- * Get and convert the signing time; if available, it will be used
- * both on the cert verification and for importing the sender
- * email profile.
- */
- encoded_stime = SEC_PKCS7GetSigningTime (cinfo);
- if (encoded_stime != NULL) {
- if (DER_DecodeTimeChoice (&stime, encoded_stime) != SECSuccess)
- encoded_stime = NULL; /* conversion failed, so pretend none */
- }
-
- /*
- * XXX This uses the signing time, if available. Additionally, we
- * might want to, if there is no signing time, get the message time
- * from the mail header itself, and use that. That would require
- * a change to our interface though, and for S/MIME callers to pass
- * in a time (and for non-S/MIME callers to pass in nothing, or
- * maybe make them pass in the current time, always?).
- */
- if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage,
- encoded_stime != NULL ? stime : PR_Now(),
- cinfo->pwfn_arg, NULL) != SECSuccess)
- {
- /*
- * XXX Give the user an option to check the signature anyway?
- * If we want to do this, need to give a way to leave and display
- * some dialog and get the answer and come back through (or do
- * the rest of what we do below elsewhere, maybe by putting it
- * in a function that we call below and could call from a dialog
- * finish handler).
- */
- goto savecert;
- }
-
- publickey = CERT_ExtractPublicKey (cert);
- if (publickey == NULL)
- goto done;
-
- /*
- * XXX No! If digests is empty, see if we can create it now by
- * digesting the contents. This is necessary if we want to allow
- * somebody to do a simple decode (without filtering, etc.) and
- * then later call us here to do the verification.
- * OR, we can just specify that the interface to this routine
- * *requires* that the digest(s) be done before calling and either
- * stashed in the struct itself or passed in explicitly (as would
- * be done for detached contents).
- */
- if ((digests == NULL || digests[0] == NULL)
- && (detached_digest == NULL || detached_digest->data == NULL))
- goto done;
-
- /*
- * Find and confirm digest algorithm.
- */
- digestTag = SECOID_FindOIDTag(&(signerinfo->digestAlg.algorithm));
-
- /* make sure we understand the digest type first */
- found_type = HASH_GetHashTypeByOidTag(digestTag);
- if ((digestTag == SEC_OID_UNKNOWN) || (found_type == HASH_AlgNULL)) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- if (detached_digest != NULL) {
- unsigned int hashLen = HASH_ResultLen(found_type);
-
- if (digest_type != found_type ||
- detached_digest->len != hashLen) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
- digest = detached_digest;
- } else {
- PORT_Assert (digestalgs != NULL && digestalgs[0] != NULL);
- if (digestalgs == NULL || digestalgs[0] == NULL) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- /*
- * pick digest matching signerinfo->digestAlg from digests
- */
- for (i = 0; digestalgs[i] != NULL; i++) {
- if (SECOID_FindOIDTag(&(digestalgs[i]->algorithm)) == digestTag)
- break;
- }
- if (digestalgs[i] == NULL) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- digest = digests[i];
- }
-
- encTag = SECOID_FindOIDTag(&(signerinfo->digestEncAlg.algorithm));
- if (encTag == SEC_OID_UNKNOWN) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
-#ifndef NSS_ECC_MORE_THAN_SUITE_B
- if (encTag == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
- PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-#endif
-
-
- if (signerinfo->authAttr != NULL) {
- SEC_PKCS7Attribute *attr;
- SECItem *value;
- SECItem encoded_attrs;
-
- /*
- * We have a sigkey only for signedAndEnvelopedData, which is
- * not supposed to have any authenticated attributes.
- */
- if (sigkey != NULL) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- /*
- * PKCS #7 says that if there are any authenticated attributes,
- * then there must be one for content type which matches the
- * content type of the content being signed, and there must
- * be one for message digest which matches our message digest.
- * So check these things first.
- * XXX Might be nice to have a compare-attribute-value function
- * which could collapse the following nicely.
- */
- attr = sec_PKCS7FindAttribute (signerinfo->authAttr,
- SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE);
- value = sec_PKCS7AttributeValue (attr);
- if (value == NULL || value->len != content_type->len) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
- if (PORT_Memcmp (value->data, content_type->data, value->len) != 0) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- attr = sec_PKCS7FindAttribute (signerinfo->authAttr,
- SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE);
- value = sec_PKCS7AttributeValue (attr);
- if (value == NULL || value->len != digest->len) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
- if (PORT_Memcmp (value->data, digest->data, value->len) != 0) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- /*
- * Okay, we met the constraints of the basic attributes.
- * Now check the signature, which is based on a digest of
- * the DER-encoded authenticated attributes. So, first we
- * encode and then we digest/verify.
- */
- encoded_attrs.data = NULL;
- encoded_attrs.len = 0;
- if (sec_PKCS7EncodeAttributes (NULL, &encoded_attrs,
- &(signerinfo->authAttr)) == NULL)
- goto done;
-
- if (encoded_attrs.data == NULL || encoded_attrs.len == 0) {
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
-
- goodsig = (PRBool)(VFY_VerifyDataDirect(encoded_attrs.data,
- encoded_attrs.len,
- publickey, &(signerinfo->encDigest),
- encTag, digestTag, NULL,
- cinfo->pwfn_arg) == SECSuccess);
- PORT_Free (encoded_attrs.data);
- } else {
- SECItem *sig;
- SECItem holder;
- SECStatus rv;
-
- /*
- * No authenticated attributes.
- * The signature is based on the plain message digest.
- */
-
- sig = &(signerinfo->encDigest);
- if (sig->len == 0) { /* bad signature */
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- goto done;
- }
-
- if (sigkey != NULL) {
- sec_PKCS7CipherObject *decryptobj;
- unsigned int buflen;
-
- /*
- * For signedAndEnvelopedData, we first must decrypt the encrypted
- * digest with the bulk encryption key. The result is the normal
- * encrypted digest (aka the signature).
- */
- decryptobj = sec_PKCS7CreateDecryptObject (sigkey, bulkid);
- if (decryptobj == NULL)
- goto done;
-
- buflen = sec_PKCS7DecryptLength (decryptobj, sig->len, PR_TRUE);
- PORT_Assert (buflen);
- if (buflen == 0) { /* something is wrong */
- sec_PKCS7DestroyDecryptObject (decryptobj);
- goto done;
- }
-
- holder.data = (unsigned char*)PORT_Alloc (buflen);
- if (holder.data == NULL) {
- sec_PKCS7DestroyDecryptObject (decryptobj);
- goto done;
- }
-
- rv = sec_PKCS7Decrypt (decryptobj, holder.data, &holder.len, buflen,
- sig->data, sig->len, PR_TRUE);
- sec_PKCS7DestroyDecryptObject (decryptobj);
- if (rv != SECSuccess) {
- goto done;
- }
-
- sig = &holder;
- }
-
- goodsig = (PRBool)(VFY_VerifyDigestDirect(digest, publickey, sig,
- encTag, digestTag, cinfo->pwfn_arg)
- == SECSuccess);
-
- if (sigkey != NULL) {
- PORT_Assert (sig == &holder);
- PORT_ZFree (holder.data, holder.len);
- }
- }
-
- if (! goodsig) {
- /*
- * XXX Change the generic error into our specific one, because
- * in that case we get a better explanation out of the Security
- * Advisor. This is really a bug in our error strings (the
- * "generic" error has a lousy/wrong message associated with it
- * which assumes the signature verification was done for the
- * purposes of checking the issuer signature on a certificate)
- * but this is at least an easy workaround and/or in the
- * Security Advisor, which specifically checks for the error
- * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation
- * in that case but does not similarly check for
- * SEC_ERROR_BAD_SIGNATURE. It probably should, but then would
- * probably say the wrong thing in the case that it *was* the
- * certificate signature check that failed during the cert
- * verification done above. Our error handling is really a mess.
- */
- if (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE)
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- }
-
-savecert:
- /*
- * Only save the smime profile if we are checking an email message and
- * the cert has an email address in it.
- */
- if ( cert->emailAddr && cert->emailAddr[0] &&
- ( ( certusage == certUsageEmailSigner ) ||
- ( certusage == certUsageEmailRecipient ) ) ) {
- SECItem *profile = NULL;
- int save_error;
-
- /*
- * Remember the current error set because we do not care about
- * anything set by the functions we are about to call.
- */
- save_error = PORT_GetError();
-
- if (goodsig && (signerinfo->authAttr != NULL)) {
- /*
- * If the signature is good, then we can save the S/MIME profile,
- * if we have one.
- */
- SEC_PKCS7Attribute *attr;
-
- attr = sec_PKCS7FindAttribute (signerinfo->authAttr,
- SEC_OID_PKCS9_SMIME_CAPABILITIES,
- PR_TRUE);
- profile = sec_PKCS7AttributeValue (attr);
- }
-
- rv = CERT_SaveSMimeProfile (cert, profile, encoded_stime);
-
- /*
- * Restore the saved error in case the calls above set a new
- * one that we do not actually care about.
- */
- PORT_SetError (save_error);
-
- /*
- * XXX Failure is not indicated anywhere -- the signature
- * verification itself is unaffected by whether or not the
- * profile was successfully saved.
- */
- }
-
-
-done:
-
- /*
- * See comment above about why we do not want to destroy cert
- * itself here.
- */
-
- if (certs != NULL)
- CERT_DestroyCertArray (certs, certcount);
-
- if (publickey != NULL)
- SECKEY_DestroyPublicKey (publickey);
-
- return goodsig;
-}
-
-/*
- * SEC_PKCS7VerifySignature
- * Look at a PKCS7 contentInfo and check if the signature is good.
- * The verification checks that the signing cert is valid and trusted
- * for the purpose specified by "certusage".
- *
- * In addition, if "keepcerts" is true, add any new certificates found
- * into our local database.
- */
-PRBool
-SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo,
- SECCertUsage certusage,
- PRBool keepcerts)
-{
- return sec_pkcs7_verify_signature (cinfo, certusage,
- NULL, HASH_AlgNULL, keepcerts);
-}
-
-/*
- * SEC_PKCS7VerifyDetachedSignature
- * Look at a PKCS7 contentInfo and check if the signature matches
- * a passed-in digest (calculated, supposedly, from detached contents).
- * The verification checks that the signing cert is valid and trusted
- * for the purpose specified by "certusage".
- *
- * In addition, if "keepcerts" is true, add any new certificates found
- * into our local database.
- */
-PRBool
-SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
- SECCertUsage certusage,
- const SECItem *detached_digest,
- HASH_HashType digest_type,
- PRBool keepcerts)
-{
- return sec_pkcs7_verify_signature (cinfo, certusage,
- detached_digest, digest_type,
- keepcerts);
-}
-
-
-/*
- * Return the asked-for portion of the name of the signer of a PKCS7
- * signed object.
- *
- * Returns a pointer to allocated memory, which must be freed.
- * A NULL return value is an error.
- */
-
-#define sec_common_name 1
-#define sec_email_address 2
-
-static char *
-sec_pkcs7_get_signer_cert_info(SEC_PKCS7ContentInfo *cinfo, int selector)
-{
- SECOidTag kind;
- SEC_PKCS7SignerInfo **signerinfos;
- CERTCertificate *signercert;
- char *container;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- default:
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- PORT_Assert (0);
- return NULL;
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sdp;
-
- sdp = cinfo->content.signedData;
- signerinfos = sdp->signerInfos;
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
-
- saedp = cinfo->content.signedAndEnvelopedData;
- signerinfos = saedp->signerInfos;
- }
- break;
- }
-
- if (signerinfos == NULL || signerinfos[0] == NULL)
- return NULL;
-
- signercert = signerinfos[0]->cert;
-
- /*
- * No cert there; see if we can find one by calling verify ourselves.
- */
- if (signercert == NULL) {
- /*
- * The cert usage does not matter in this case, because we do not
- * actually care about the verification itself, but we have to pick
- * some valid usage to pass in.
- */
- (void) sec_pkcs7_verify_signature (cinfo, certUsageEmailSigner,
- NULL, HASH_AlgNULL, PR_FALSE);
- signercert = signerinfos[0]->cert;
- if (signercert == NULL)
- return NULL;
- }
-
- switch (selector) {
- case sec_common_name:
- container = CERT_GetCommonName (&signercert->subject);
- break;
- case sec_email_address:
- if(signercert->emailAddr && signercert->emailAddr[0]) {
- container = PORT_Strdup(signercert->emailAddr);
- } else {
- container = NULL;
- }
- break;
- default:
- PORT_Assert (0);
- container = NULL;
- break;
- }
-
- return container;
-}
-
-char *
-SEC_PKCS7GetSignerCommonName(SEC_PKCS7ContentInfo *cinfo)
-{
- return sec_pkcs7_get_signer_cert_info(cinfo, sec_common_name);
-}
-
-char *
-SEC_PKCS7GetSignerEmailAddress(SEC_PKCS7ContentInfo *cinfo)
-{
- return sec_pkcs7_get_signer_cert_info(cinfo, sec_email_address);
-}
-
-
-/*
- * Return the signing time, in UTCTime format, of a PKCS7 contentInfo.
- */
-SECItem *
-SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo)
-{
- SEC_PKCS7SignerInfo **signerinfos;
- SEC_PKCS7Attribute *attr;
-
- if (SEC_PKCS7ContentType (cinfo) != SEC_OID_PKCS7_SIGNED_DATA)
- return NULL;
-
- signerinfos = cinfo->content.signedData->signerInfos;
-
- /*
- * No signature, or more than one, means no deal.
- */
- if (signerinfos == NULL || signerinfos[0] == NULL || signerinfos[1] != NULL)
- return NULL;
-
- attr = sec_PKCS7FindAttribute (signerinfos[0]->authAttr,
- SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);
- return sec_PKCS7AttributeValue (attr);
-}
diff --git a/security/nss/lib/pkcs7/p7encode.c b/security/nss/lib/pkcs7/p7encode.c
deleted file mode 100644
index 3a8b47b23..000000000
--- a/security/nss/lib/pkcs7/p7encode.c
+++ /dev/null
@@ -1,1112 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * PKCS7 encoding.
- *
- * $Id$
- */
-
-#include "p7local.h"
-
-#include "cert.h"
-#include "cryptohi.h"
-#include "keyhi.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "pk11func.h"
-#include "secerr.h"
-#include "sechash.h" /* for HASH_GetHashObject() */
-
-struct sec_pkcs7_encoder_output {
- SEC_PKCS7EncoderOutputCallback outputfn;
- void *outputarg;
-};
-
-struct SEC_PKCS7EncoderContextStr {
- SEC_ASN1EncoderContext *ecx;
- SEC_PKCS7ContentInfo *cinfo;
- struct sec_pkcs7_encoder_output output;
- sec_PKCS7CipherObject *encryptobj;
- const SECHashObject *digestobj;
- void *digestcx;
-};
-
-
-/*
- * The little output function that the ASN.1 encoder calls to hand
- * us bytes which we in turn hand back to our caller (via the callback
- * they gave us).
- */
-static void
-sec_pkcs7_encoder_out(void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
-{
- struct sec_pkcs7_encoder_output *output;
-
- output = (struct sec_pkcs7_encoder_output*)arg;
- output->outputfn (output->outputarg, buf, len);
-}
-
-static sec_PKCS7CipherObject *
-sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo,
- PK11SymKey *orig_bulkkey)
-{
- SECOidTag kind;
- sec_PKCS7CipherObject *encryptobj;
- SEC_PKCS7RecipientInfo **recipientinfos, *ri;
- SEC_PKCS7EncryptedContentInfo *enccinfo;
- SECKEYPublicKey *publickey = NULL;
- SECKEYPrivateKey *ourPrivKey = NULL;
- PK11SymKey *bulkkey;
- void *mark, *wincx;
- int i;
- PRArenaPool *arena = NULL;
-
- /* Get the context in case we need it below. */
- wincx = cinfo->pwfn_arg;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- default:
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_SIGNED_DATA:
- recipientinfos = NULL;
- enccinfo = NULL;
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- {
- SEC_PKCS7EncryptedData *encdp;
-
- /* To do EncryptedData we *must* be given a bulk key. */
- PORT_Assert (orig_bulkkey != NULL);
- if (orig_bulkkey == NULL) {
- /* XXX error? */
- return NULL;
- }
-
- encdp = cinfo->content.encryptedData;
- recipientinfos = NULL;
- enccinfo = &(encdp->encContentInfo);
- }
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- {
- SEC_PKCS7EnvelopedData *envdp;
-
- envdp = cinfo->content.envelopedData;
- recipientinfos = envdp->recipientInfos;
- enccinfo = &(envdp->encContentInfo);
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
-
- saedp = cinfo->content.signedAndEnvelopedData;
- recipientinfos = saedp->recipientInfos;
- enccinfo = &(saedp->encContentInfo);
- }
- break;
- }
-
- if (enccinfo == NULL)
- return NULL;
-
- bulkkey = orig_bulkkey;
- if (bulkkey == NULL) {
- CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(enccinfo->encalg);
- PK11SlotInfo *slot;
-
-
- slot = PK11_GetBestSlot(type,cinfo->pwfn_arg);
- if (slot == NULL) {
- return NULL;
- }
- bulkkey = PK11_KeyGen(slot,type,NULL, enccinfo->keysize/8,
- cinfo->pwfn_arg);
- PK11_FreeSlot(slot);
- if (bulkkey == NULL) {
- return NULL;
- }
- }
-
- encryptobj = NULL;
- mark = PORT_ArenaMark (cinfo->poolp);
-
- /*
- * Encrypt the bulk key with the public key of each recipient.
- */
- for (i = 0; recipientinfos && (ri = recipientinfos[i]) != NULL; i++) {
- CERTCertificate *cert;
- SECOidTag certalgtag, encalgtag;
- SECStatus rv;
- int data_len;
- SECItem *params = NULL;
-
- cert = ri->cert;
- PORT_Assert (cert != NULL);
- if (cert == NULL)
- continue;
-
- /*
- * XXX Want an interface that takes a cert and some data and
- * fills in an algorithmID and encrypts the data with the public
- * key from the cert. Or, give me two interfaces -- one which
- * gets the algorithm tag from a cert (I should not have to go
- * down into the subjectPublicKeyInfo myself) and another which
- * takes a public key and algorithm tag and data and encrypts
- * the data. Or something like that. The point is that all
- * of the following hardwired RSA stuff should be done elsewhere.
- */
-
- certalgtag=SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
-
- switch (certalgtag) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- encalgtag = certalgtag;
- publickey = CERT_ExtractPublicKey (cert);
- if (publickey == NULL) goto loser;
-
- data_len = SECKEY_PublicKeyStrength(publickey);
- ri->encKey.data =
- (unsigned char*)PORT_ArenaAlloc(cinfo->poolp ,data_len);
- ri->encKey.len = data_len;
- if (ri->encKey.data == NULL) goto loser;
-
- rv = PK11_PubWrapSymKey(PK11_AlgtagToMechanism(certalgtag),publickey,
- bulkkey,&ri->encKey);
-
- SECKEY_DestroyPublicKey(publickey);
- publickey = NULL;
- if (rv != SECSuccess) goto loser;
- params = NULL; /* paranoia */
- break;
- default:
- PORT_SetError (SEC_ERROR_INVALID_ALGORITHM);
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(cinfo->poolp, &ri->keyEncAlg, encalgtag,
- params);
- if (rv != SECSuccess)
- goto loser;
- if (arena) PORT_FreeArena(arena,PR_FALSE);
- arena = NULL;
- }
-
- encryptobj = sec_PKCS7CreateEncryptObject (cinfo->poolp, bulkkey,
- enccinfo->encalg,
- &(enccinfo->contentEncAlg));
- if (encryptobj != NULL) {
- PORT_ArenaUnmark (cinfo->poolp, mark);
- mark = NULL; /* good one; do not want to release */
- }
- /* fallthru */
-
-loser:
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- if (publickey) {
- SECKEY_DestroyPublicKey(publickey);
- }
- if (ourPrivKey) {
- SECKEY_DestroyPrivateKey(ourPrivKey);
- }
- if (mark != NULL) {
- PORT_ArenaRelease (cinfo->poolp, mark);
- }
- if (orig_bulkkey == NULL) {
- if (bulkkey) PK11_FreeSymKey(bulkkey);
- }
-
- return encryptobj;
-}
-
-
-static void
-sec_pkcs7_encoder_notify (void *arg, PRBool before, void *dest, int depth)
-{
- SEC_PKCS7EncoderContext *p7ecx;
- SEC_PKCS7ContentInfo *cinfo;
- SECOidTag kind;
- PRBool before_content;
-
- /*
- * We want to notice just before the content field. After fields are
- * not interesting to us.
- */
- if (!before)
- return;
-
- p7ecx = (SEC_PKCS7EncoderContext*)arg;
- cinfo = p7ecx->cinfo;
-
- before_content = PR_FALSE;
-
- /*
- * Watch for the content field, at which point we want to instruct
- * the ASN.1 encoder to start taking bytes from the buffer.
- *
- * XXX The following assumes the inner content type is data;
- * if/when we want to handle fully nested types, this will have
- * to recurse until reaching the innermost data content.
- */
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- default:
- case SEC_OID_PKCS7_DATA:
- if (dest == &(cinfo->content.data))
- before_content = PR_TRUE;
- break;
-
- case SEC_OID_PKCS7_DIGESTED_DATA:
- {
- SEC_PKCS7DigestedData *digd;
-
- digd = cinfo->content.digestedData;
- if (digd == NULL)
- break;
-
- if (dest == &(digd->contentInfo.content))
- before_content = PR_TRUE;
- }
- break;
-
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- {
- SEC_PKCS7EncryptedData *encd;
-
- encd = cinfo->content.encryptedData;
- if (encd == NULL)
- break;
-
- if (dest == &(encd->encContentInfo.encContent))
- before_content = PR_TRUE;
- }
- break;
-
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- {
- SEC_PKCS7EnvelopedData *envd;
-
- envd = cinfo->content.envelopedData;
- if (envd == NULL)
- break;
-
- if (dest == &(envd->encContentInfo.encContent))
- before_content = PR_TRUE;
- }
- break;
-
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sigd;
-
- sigd = cinfo->content.signedData;
- if (sigd == NULL)
- break;
-
- if (dest == &(sigd->contentInfo.content))
- before_content = PR_TRUE;
- }
- break;
-
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saed;
-
- saed = cinfo->content.signedAndEnvelopedData;
- if (saed == NULL)
- break;
-
- if (dest == &(saed->encContentInfo.encContent))
- before_content = PR_TRUE;
- }
- break;
- }
-
- if (before_content) {
- /*
- * This will cause the next SEC_ASN1EncoderUpdate to take the
- * contents bytes from the passed-in buffer.
- */
- SEC_ASN1EncoderSetTakeFromBuf (p7ecx->ecx);
- /*
- * And that is all we needed this notify function for.
- */
- SEC_ASN1EncoderClearNotifyProc (p7ecx->ecx);
- }
-}
-
-
-static SEC_PKCS7EncoderContext *
-sec_pkcs7_encoder_start_contexts (SEC_PKCS7ContentInfo *cinfo,
- PK11SymKey *bulkkey)
-{
- SEC_PKCS7EncoderContext *p7ecx;
- SECOidTag kind;
- PRBool encrypt;
- SECItem **digests;
- SECAlgorithmID *digestalg, **digestalgs;
-
- p7ecx =
- (SEC_PKCS7EncoderContext*)PORT_ZAlloc (sizeof(SEC_PKCS7EncoderContext));
- if (p7ecx == NULL)
- return NULL;
-
- digests = NULL;
- digestalg = NULL;
- digestalgs = NULL;
- encrypt = PR_FALSE;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- default:
- case SEC_OID_PKCS7_DATA:
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- digestalg = &(cinfo->content.digestedData->digestAlg);
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- digests = cinfo->content.signedData->digests;
- digestalgs = cinfo->content.signedData->digestAlgorithms;
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- encrypt = PR_TRUE;
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- digests = cinfo->content.signedAndEnvelopedData->digests;
- digestalgs = cinfo->content.signedAndEnvelopedData->digestAlgorithms;
- encrypt = PR_TRUE;
- break;
- }
-
- if (encrypt) {
- p7ecx->encryptobj = sec_pkcs7_encoder_start_encrypt (cinfo, bulkkey);
- if (p7ecx->encryptobj == NULL) {
- PORT_Free (p7ecx);
- return NULL;
- }
- }
-
- if (digestalgs != NULL) {
- if (digests != NULL) {
- /* digests already created (probably for detached data) */
- digestalg = NULL;
- } else {
- /*
- * XXX Some day we should handle multiple digests; for now,
- * assume only one will be done.
- */
- PORT_Assert (digestalgs[0] != NULL && digestalgs[1] == NULL);
- digestalg = digestalgs[0];
- }
- }
-
- if (digestalg != NULL) {
- SECOidTag oidTag = SECOID_FindOIDTag(&(digestalg->algorithm));
-
- p7ecx->digestobj = HASH_GetHashObjectByOidTag(oidTag);
- if (p7ecx->digestobj != NULL) {
- p7ecx->digestcx = (* p7ecx->digestobj->create) ();
- if (p7ecx->digestcx == NULL)
- p7ecx->digestobj = NULL;
- else
- (* p7ecx->digestobj->begin) (p7ecx->digestcx);
- }
- if (p7ecx->digestobj == NULL) {
- if (p7ecx->encryptobj != NULL)
- sec_PKCS7DestroyEncryptObject (p7ecx->encryptobj);
- PORT_Free (p7ecx);
- return NULL;
- }
- }
-
- p7ecx->cinfo = cinfo;
- return p7ecx;
-}
-
-
-SEC_PKCS7EncoderContext *
-SEC_PKCS7EncoderStart (SEC_PKCS7ContentInfo *cinfo,
- SEC_PKCS7EncoderOutputCallback outputfn,
- void *outputarg,
- PK11SymKey *bulkkey)
-{
- SEC_PKCS7EncoderContext *p7ecx;
- SECStatus rv;
-
- p7ecx = sec_pkcs7_encoder_start_contexts (cinfo, bulkkey);
- if (p7ecx == NULL)
- return NULL;
-
- p7ecx->output.outputfn = outputfn;
- p7ecx->output.outputarg = outputarg;
-
- /*
- * Initialize the BER encoder.
- */
- p7ecx->ecx = SEC_ASN1EncoderStart (cinfo, sec_PKCS7ContentInfoTemplate,
- sec_pkcs7_encoder_out, &(p7ecx->output));
- if (p7ecx->ecx == NULL) {
- PORT_Free (p7ecx);
- return NULL;
- }
-
- /*
- * Indicate that we are streaming. We will be streaming until we
- * get past the contents bytes.
- */
- SEC_ASN1EncoderSetStreaming (p7ecx->ecx);
-
- /*
- * The notify function will watch for the contents field.
- */
- SEC_ASN1EncoderSetNotifyProc (p7ecx->ecx, sec_pkcs7_encoder_notify, p7ecx);
-
- /*
- * This will encode everything up to the content bytes. (The notify
- * function will then cause the encoding to stop there.) Then our
- * caller can start passing contents bytes to our Update, which we
- * will pass along.
- */
- rv = SEC_ASN1EncoderUpdate (p7ecx->ecx, NULL, 0);
- if (rv != SECSuccess) {
- PORT_Free (p7ecx);
- return NULL;
- }
-
- return p7ecx;
-}
-
-
-/*
- * XXX If/when we support nested contents, this needs to be revised.
- */
-static SECStatus
-sec_pkcs7_encoder_work_data (SEC_PKCS7EncoderContext *p7ecx, SECItem *dest,
- const unsigned char *data, unsigned long len,
- PRBool final)
-{
- unsigned char *buf = NULL;
- SECStatus rv;
-
-
- rv = SECSuccess; /* may as well be optimistic */
-
- /*
- * We should really have data to process, or we should be trying
- * to finish/flush the last block. (This is an overly paranoid
- * check since all callers are in this file and simple inspection
- * proves they do it right. But it could find a bug in future
- * modifications/development, that is why it is here.)
- */
- PORT_Assert ((data != NULL && len) || final);
-
- /*
- * Update the running digest.
- * XXX This needs modification if/when we handle multiple digests.
- */
- if (len && p7ecx->digestobj != NULL) {
- (* p7ecx->digestobj->update) (p7ecx->digestcx, data, len);
- }
-
- /*
- * Encrypt this chunk.
- */
- if (p7ecx->encryptobj != NULL) {
- /* XXX the following lengths should all be longs? */
- unsigned int inlen; /* length of data being encrypted */
- unsigned int outlen; /* length of encrypted data */
- unsigned int buflen; /* length available for encrypted data */
-
- inlen = len;
- buflen = sec_PKCS7EncryptLength (p7ecx->encryptobj, inlen, final);
- if (buflen == 0) {
- /*
- * No output is expected, but the input data may be buffered
- * so we still have to call Encrypt.
- */
- rv = sec_PKCS7Encrypt (p7ecx->encryptobj, NULL, NULL, 0,
- data, inlen, final);
- if (final) {
- len = 0;
- goto done;
- }
- return rv;
- }
-
- if (dest != NULL)
- buf = (unsigned char*)PORT_ArenaAlloc(p7ecx->cinfo->poolp, buflen);
- else
- buf = (unsigned char*)PORT_Alloc (buflen);
-
- if (buf == NULL) {
- rv = SECFailure;
- } else {
- rv = sec_PKCS7Encrypt (p7ecx->encryptobj, buf, &outlen, buflen,
- data, inlen, final);
- data = buf;
- len = outlen;
- }
- if (rv != SECSuccess) {
- if (final)
- goto done;
- return rv;
- }
- }
-
- if (p7ecx->ecx != NULL) {
- /*
- * Encode the contents bytes.
- */
- if(len) {
- rv = SEC_ASN1EncoderUpdate (p7ecx->ecx, (const char *)data, len);
- }
- }
-
-done:
- if (p7ecx->encryptobj != NULL) {
- if (final)
- sec_PKCS7DestroyEncryptObject (p7ecx->encryptobj);
- if (dest != NULL) {
- dest->data = buf;
- dest->len = len;
- } else if (buf != NULL) {
- PORT_Free (buf);
- }
- }
-
- if (final && p7ecx->digestobj != NULL) {
- SECItem *digest, **digests, ***digestsp;
- unsigned char *digdata;
- SECOidTag kind;
-
- kind = SEC_PKCS7ContentType (p7ecx->cinfo);
- switch (kind) {
- default:
- PORT_Assert (0);
- return SECFailure;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- digest = &(p7ecx->cinfo->content.digestedData->digest);
- digestsp = NULL;
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- digest = NULL;
- digestsp = &(p7ecx->cinfo->content.signedData->digests);
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- digest = NULL;
- digestsp = &(p7ecx->cinfo->content.signedAndEnvelopedData->digests);
- break;
- }
-
- digdata = (unsigned char*)PORT_ArenaAlloc (p7ecx->cinfo->poolp,
- p7ecx->digestobj->length);
- if (digdata == NULL)
- return SECFailure;
-
- if (digestsp != NULL) {
- PORT_Assert (digest == NULL);
-
- digest = (SECItem*)PORT_ArenaAlloc (p7ecx->cinfo->poolp,
- sizeof(SECItem));
- digests = (SECItem**)PORT_ArenaAlloc (p7ecx->cinfo->poolp,
- 2 * sizeof(SECItem *));
- if (digests == NULL || digest == NULL)
- return SECFailure;
-
- digests[0] = digest;
- digests[1] = NULL;
-
- *digestsp = digests;
- }
-
- PORT_Assert (digest != NULL);
-
- digest->data = digdata;
- digest->len = p7ecx->digestobj->length;
-
- (* p7ecx->digestobj->end) (p7ecx->digestcx, digest->data,
- &(digest->len), digest->len);
- (* p7ecx->digestobj->destroy) (p7ecx->digestcx, PR_TRUE);
- }
-
- return rv;
-}
-
-
-SECStatus
-SEC_PKCS7EncoderUpdate (SEC_PKCS7EncoderContext *p7ecx,
- const char *data, unsigned long len)
-{
- /* XXX Error handling needs help. Return what? Do "Finish" on failure? */
- return sec_pkcs7_encoder_work_data (p7ecx, NULL,
- (const unsigned char *)data, len,
- PR_FALSE);
-}
-
-static SECStatus
-sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo,
- SECKEYGetPasswordKey pwfn, void *pwfnarg)
-{
- SECOidTag kind;
- CERTCertificate **certs;
- CERTCertificateList **certlists;
- SECAlgorithmID **digestalgs;
- SECItem **digests;
- SEC_PKCS7SignerInfo *signerinfo, **signerinfos;
- SECItem **rawcerts, ***rawcertsp;
- PRArenaPool *poolp;
- int certcount;
- int ci, cli, rci, si;
-
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- default:
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- certs = NULL;
- certlists = NULL;
- digestalgs = NULL;
- digests = NULL;
- signerinfos = NULL;
- rawcertsp = NULL;
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- {
- SEC_PKCS7SignedData *sdp;
-
- sdp = cinfo->content.signedData;
- certs = sdp->certs;
- certlists = sdp->certLists;
- digestalgs = sdp->digestAlgorithms;
- digests = sdp->digests;
- signerinfos = sdp->signerInfos;
- rawcertsp = &(sdp->rawCerts);
- }
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- {
- SEC_PKCS7SignedAndEnvelopedData *saedp;
-
- saedp = cinfo->content.signedAndEnvelopedData;
- certs = saedp->certs;
- certlists = saedp->certLists;
- digestalgs = saedp->digestAlgorithms;
- digests = saedp->digests;
- signerinfos = saedp->signerInfos;
- rawcertsp = &(saedp->rawCerts);
- }
- break;
- }
-
- if (certs == NULL && certlists == NULL && signerinfos == NULL)
- return SECSuccess; /* nothing for us to do! */
-
- poolp = cinfo->poolp;
- certcount = 0;
-
- if (signerinfos != NULL) {
- SECOidTag digestalgtag;
- int di;
- SECStatus rv;
- CERTCertificate *cert;
- SECKEYPrivateKey *privkey;
- SECItem signature;
- SECOidTag signalgtag;
-
- PORT_Assert (digestalgs != NULL && digests != NULL);
-
- /*
- * If one fails, we bail right then. If we want to continue and
- * try to do subsequent signatures, this loop, and the departures
- * from it, will need to be reworked.
- */
- for (si = 0; signerinfos[si] != NULL; si++) {
-
- signerinfo = signerinfos[si];
-
- /* find right digest */
- digestalgtag = SECOID_GetAlgorithmTag (&(signerinfo->digestAlg));
- for (di = 0; digestalgs[di] != NULL; di++) {
- /* XXX Should I be comparing more than the tag? */
- if (digestalgtag == SECOID_GetAlgorithmTag (digestalgs[di]))
- break;
- }
- if (digestalgs[di] == NULL) {
- /* XXX oops; do what? set an error? */
- return SECFailure;
- }
- PORT_Assert (digests[di] != NULL);
-
- cert = signerinfo->cert;
- privkey = PK11_FindKeyByAnyCert (cert, pwfnarg);
- if (privkey == NULL)
- return SECFailure;
-
- /*
- * XXX I think there should be a cert-level interface for this,
- * so that I do not have to know about subjectPublicKeyInfo...
- */
- signalgtag = SECOID_GetAlgorithmTag (&(cert->subjectPublicKeyInfo.algorithm));
-
- if (signerinfo->authAttr != NULL) {
- SEC_PKCS7Attribute *attr;
- SECItem encoded_attrs;
- SECItem *dummy;
- SECOidTag algid;
-
- /*
- * First, find and fill in the message digest attribute.
- */
- attr = sec_PKCS7FindAttribute (signerinfo->authAttr,
- SEC_OID_PKCS9_MESSAGE_DIGEST,
- PR_TRUE);
- PORT_Assert (attr != NULL);
- if (attr == NULL) {
- SECKEY_DestroyPrivateKey (privkey);
- return SECFailure;
- }
-
- /*
- * XXX The second half of the following assertion prevents
- * the encoder from being called twice on the same content.
- * Either just remove the second half the assertion, or
- * change the code to check if the value already there is
- * the same as digests[di], whichever seems more right.
- */
- PORT_Assert (attr->values != NULL && attr->values[0] == NULL);
- attr->values[0] = digests[di];
-
- /*
- * Before encoding, reorder the attributes so that when they
- * are encoded, they will be conforming DER, which is required
- * to have a specific order and that is what must be used for
- * the hash/signature. We do this here, rather than building
- * it into EncodeAttributes, because we do not want to do
- * such reordering on incoming messages (which also uses
- * EncodeAttributes) or our old signatures (and other "broken"
- * implementations) will not verify. So, we want to guarantee
- * that we send out good DER encodings of attributes, but not
- * to expect to receive them.
- */
- rv = sec_PKCS7ReorderAttributes (signerinfo->authAttr);
- if (rv != SECSuccess) {
- SECKEY_DestroyPrivateKey (privkey);
- return SECFailure;
- }
-
- encoded_attrs.data = NULL;
- encoded_attrs.len = 0;
- dummy = sec_PKCS7EncodeAttributes (NULL, &encoded_attrs,
- &(signerinfo->authAttr));
- if (dummy == NULL) {
- SECKEY_DestroyPrivateKey (privkey);
- return SECFailure;
- }
-
- algid = SEC_GetSignatureAlgorithmOidTag(privkey->keyType,
- digestalgtag);
- if (algid == SEC_OID_UNKNOWN) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- SECKEY_DestroyPrivateKey (privkey);
- return SECFailure;
- }
- rv = SEC_SignData (&signature,
- encoded_attrs.data, encoded_attrs.len,
- privkey,
- algid);
- SECITEM_FreeItem (&encoded_attrs, PR_FALSE);
- } else {
- rv = SGN_Digest (privkey, digestalgtag, &signature,
- digests[di]);
- }
-
- SECKEY_DestroyPrivateKey (privkey);
-
- if (rv != SECSuccess)
- return rv;
-
- rv = SECITEM_CopyItem (poolp, &(signerinfo->encDigest), &signature);
- if (rv != SECSuccess)
- return rv;
-
- SECITEM_FreeItem (&signature, PR_FALSE);
-
- rv = SECOID_SetAlgorithmID (poolp, &(signerinfo->digestEncAlg),
- signalgtag, NULL);
- if (rv != SECSuccess)
- return SECFailure;
-
- /*
- * Count the cert chain for this signer.
- */
- if (signerinfo->certList != NULL)
- certcount += signerinfo->certList->len;
- }
- }
-
- if (certs != NULL) {
- for (ci = 0; certs[ci] != NULL; ci++)
- certcount++;
- }
-
- if (certlists != NULL) {
- for (cli = 0; certlists[cli] != NULL; cli++)
- certcount += certlists[cli]->len;
- }
-
- if (certcount == 0)
- return SECSuccess; /* signing done; no certs */
-
- /*
- * Combine all of the certs and cert chains into rawcerts.
- * Note: certcount is an upper bound; we may not need that many slots
- * but we will allocate anyway to avoid having to do another pass.
- * (The temporary space saving is not worth it.)
- */
- rawcerts = (SECItem**)PORT_ArenaAlloc (poolp,
- (certcount + 1) * sizeof(SECItem *));
- if (rawcerts == NULL)
- return SECFailure;
-
- /*
- * XXX Want to check for duplicates and not add *any* cert that is
- * already in the set. This will be more important when we start
- * dealing with larger sets of certs, dual-key certs (signing and
- * encryption), etc. For the time being we can slide by...
- */
- rci = 0;
- if (signerinfos != NULL) {
- for (si = 0; signerinfos[si] != NULL; si++) {
- signerinfo = signerinfos[si];
- for (ci = 0; ci < signerinfo->certList->len; ci++)
- rawcerts[rci++] = &(signerinfo->certList->certs[ci]);
- }
-
- }
-
- if (certs != NULL) {
- for (ci = 0; certs[ci] != NULL; ci++)
- rawcerts[rci++] = &(certs[ci]->derCert);
- }
-
- if (certlists != NULL) {
- for (cli = 0; certlists[cli] != NULL; cli++) {
- for (ci = 0; ci < certlists[cli]->len; ci++)
- rawcerts[rci++] = &(certlists[cli]->certs[ci]);
- }
- }
-
- rawcerts[rci] = NULL;
- *rawcertsp = rawcerts;
-
- return SECSuccess;
-}
-
-
-SECStatus
-SEC_PKCS7EncoderFinish (SEC_PKCS7EncoderContext *p7ecx,
- SECKEYGetPasswordKey pwfn, void *pwfnarg)
-{
- SECStatus rv;
-
- /*
- * Flush out any remaining data.
- */
- rv = sec_pkcs7_encoder_work_data (p7ecx, NULL, NULL, 0, PR_TRUE);
-
- /*
- * Turn off streaming stuff.
- */
- SEC_ASN1EncoderClearTakeFromBuf (p7ecx->ecx);
- SEC_ASN1EncoderClearStreaming (p7ecx->ecx);
-
- if (rv != SECSuccess)
- goto loser;
-
- rv = sec_pkcs7_encoder_sig_and_certs (p7ecx->cinfo, pwfn, pwfnarg);
- if (rv != SECSuccess)
- goto loser;
-
- rv = SEC_ASN1EncoderUpdate (p7ecx->ecx, NULL, 0);
-
-loser:
- SEC_ASN1EncoderFinish (p7ecx->ecx);
- PORT_Free (p7ecx);
- return rv;
-}
-
-/*
- * Abort the ASN.1 stream. Used by pkcs 12
- */
-void
-SEC_PKCS7EncoderAbort(SEC_PKCS7EncoderContext *p7ecx, int error)
-{
- PORT_Assert(p7ecx);
- SEC_ASN1EncoderAbort(p7ecx->ecx, error);
-}
-
-/*
- * After this routine is called, the entire PKCS7 contentInfo is ready
- * to be encoded. This is used internally, but can also be called from
- * elsewhere for those who want to be able to just have pointers to
- * the ASN1 template for pkcs7 contentInfo built into their own encodings.
- */
-SECStatus
-SEC_PKCS7PrepareForEncode (SEC_PKCS7ContentInfo *cinfo,
- PK11SymKey *bulkkey,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg)
-{
- SEC_PKCS7EncoderContext *p7ecx;
- SECItem *content, *enc_content;
- SECStatus rv;
-
- p7ecx = sec_pkcs7_encoder_start_contexts (cinfo, bulkkey);
- if (p7ecx == NULL)
- return SECFailure;
-
- content = SEC_PKCS7GetContent (cinfo);
-
- if (p7ecx->encryptobj != NULL) {
- SECOidTag kind;
- SEC_PKCS7EncryptedContentInfo *enccinfo;
-
- kind = SEC_PKCS7ContentType (p7ecx->cinfo);
- switch (kind) {
- default:
- PORT_Assert (0);
- rv = SECFailure;
- goto loser;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- enccinfo = &(p7ecx->cinfo->content.encryptedData->encContentInfo);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- enccinfo = &(p7ecx->cinfo->content.envelopedData->encContentInfo);
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- enccinfo = &(p7ecx->cinfo->content.signedAndEnvelopedData->encContentInfo);
- break;
- }
- enc_content = &(enccinfo->encContent);
- } else {
- enc_content = NULL;
- }
-
- if (content != NULL && content->data != NULL && content->len) {
- rv = sec_pkcs7_encoder_work_data (p7ecx, enc_content,
- content->data, content->len, PR_TRUE);
- if (rv != SECSuccess)
- goto loser;
- }
-
- rv = sec_pkcs7_encoder_sig_and_certs (cinfo, pwfn, pwfnarg);
-
-loser:
- PORT_Free (p7ecx);
- return rv;
-}
-
-
-/*
- * Encode a PKCS7 object, in one shot. All necessary components
- * of the object must already be specified. Either the data has
- * already been included (via SetContent), or the data is detached,
- * or there is no data at all (certs-only).
- *
- * "cinfo" specifies the object to be encoded.
- *
- * "outputfn" is where the encoded bytes will be passed.
- *
- * "outputarg" is an opaque argument to the above callback.
- *
- * "bulkkey" specifies the bulk encryption key to use. This argument
- * can be NULL if no encryption is being done, or if the bulk key should
- * be generated internally (usually the case for EnvelopedData but never
- * for EncryptedData, which *must* provide a bulk encryption key).
- *
- * "pwfn" is a callback for getting the password which protects the
- * private key of the signer. This argument can be NULL if it is known
- * that no signing is going to be done.
- *
- * "pwfnarg" is an opaque argument to the above callback.
- */
-SECStatus
-SEC_PKCS7Encode (SEC_PKCS7ContentInfo *cinfo,
- SEC_PKCS7EncoderOutputCallback outputfn,
- void *outputarg,
- PK11SymKey *bulkkey,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg)
-{
- SECStatus rv;
-
- rv = SEC_PKCS7PrepareForEncode (cinfo, bulkkey, pwfn, pwfnarg);
- if (rv == SECSuccess) {
- struct sec_pkcs7_encoder_output outputcx;
-
- outputcx.outputfn = outputfn;
- outputcx.outputarg = outputarg;
-
- rv = SEC_ASN1Encode (cinfo, sec_PKCS7ContentInfoTemplate,
- sec_pkcs7_encoder_out, &outputcx);
- }
-
- return rv;
-}
-
-
-/*
- * Encode a PKCS7 object, in one shot. All necessary components
- * of the object must already be specified. Either the data has
- * already been included (via SetContent), or the data is detached,
- * or there is no data at all (certs-only). The output, rather than
- * being passed to an output function as is done above, is all put
- * into a SECItem.
- *
- * "pool" specifies a pool from which to allocate the result.
- * It can be NULL, in which case memory is allocated generically.
- *
- * "dest" specifies a SECItem in which to put the result data.
- * It can be NULL, in which case the entire item is allocated, too.
- *
- * "cinfo" specifies the object to be encoded.
- *
- * "bulkkey" specifies the bulk encryption key to use. This argument
- * can be NULL if no encryption is being done, or if the bulk key should
- * be generated internally (usually the case for EnvelopedData but never
- * for EncryptedData, which *must* provide a bulk encryption key).
- *
- * "pwfn" is a callback for getting the password which protects the
- * private key of the signer. This argument can be NULL if it is known
- * that no signing is going to be done.
- *
- * "pwfnarg" is an opaque argument to the above callback.
- */
-SECItem *
-SEC_PKCS7EncodeItem (PRArenaPool *pool,
- SECItem *dest,
- SEC_PKCS7ContentInfo *cinfo,
- PK11SymKey *bulkkey,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg)
-{
- SECStatus rv;
-
- rv = SEC_PKCS7PrepareForEncode (cinfo, bulkkey, pwfn, pwfnarg);
- if (rv != SECSuccess)
- return NULL;
-
- return SEC_ASN1EncodeItem (pool, dest, cinfo, sec_PKCS7ContentInfoTemplate);
-}
-
diff --git a/security/nss/lib/pkcs7/p7local.c b/security/nss/lib/pkcs7/p7local.c
deleted file mode 100644
index 35083478c..000000000
--- a/security/nss/lib/pkcs7/p7local.c
+++ /dev/null
@@ -1,1321 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Support routines for PKCS7 implementation, none of which are exported.
- * This file should only contain things that are needed by both the
- * encoding/creation side *and* the decoding/decryption side. Anything
- * else should be static routines in the appropriate file.
- *
- * $Id$
- */
-
-#include "p7local.h"
-
-#include "cryptohi.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "pk11func.h"
-#include "secpkcs5.h"
-#include "secerr.h"
-
-/*
- * -------------------------------------------------------------------
- * Cipher stuff.
- */
-
-typedef SECStatus (*sec_pkcs7_cipher_function) (void *,
- unsigned char *,
- unsigned *,
- unsigned int,
- const unsigned char *,
- unsigned int);
-typedef SECStatus (*sec_pkcs7_cipher_destroy) (void *, PRBool);
-
-#define BLOCK_SIZE 4096
-
-struct sec_pkcs7_cipher_object {
- void *cx;
- sec_pkcs7_cipher_function doit;
- sec_pkcs7_cipher_destroy destroy;
- PRBool encrypt;
- int block_size;
- int pad_size;
- int pending_count;
- unsigned char pending_buf[BLOCK_SIZE];
-};
-
-SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
-SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate)
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
-SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
-
-/*
- * Create a cipher object to do decryption, based on the given bulk
- * encryption key and algorithm identifier (which may include an iv).
- *
- * XXX This interface, or one similar, would be really nice available
- * in general... I tried to keep the pkcs7-specific stuff (mostly
- * having to do with padding) out of here.
- *
- * XXX Once both are working, it might be nice to combine this and the
- * function below (for starting up encryption) into one routine, and just
- * have two simple cover functions which call it.
- */
-sec_PKCS7CipherObject *
-sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid)
-{
- sec_PKCS7CipherObject *result;
- SECOidTag algtag;
- void *ciphercx;
- CK_MECHANISM_TYPE cryptoMechType;
- PK11SlotInfo *slot;
- SECItem *param = NULL;
-
- result = (struct sec_pkcs7_cipher_object*)
- PORT_ZAlloc (sizeof(struct sec_pkcs7_cipher_object));
- if (result == NULL)
- return NULL;
-
- ciphercx = NULL;
- algtag = SECOID_GetAlgorithmTag (algid);
-
- if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
- SECItem *pwitem;
-
- pwitem = (SECItem *)PK11_GetSymKeyUserData(key);
- if (!pwitem) {
- PORT_Free(result);
- return NULL;
- }
-
- cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
- if (cryptoMechType == CKM_INVALID_MECHANISM) {
- PORT_Free(result);
- SECITEM_FreeItem(param,PR_TRUE);
- return NULL;
- }
- } else {
- cryptoMechType = PK11_AlgtagToMechanism(algtag);
- param = PK11_ParamFromAlgid(algid);
- if (param == NULL) {
- PORT_Free(result);
- return NULL;
- }
- }
-
- result->pad_size = PK11_GetBlockSize(cryptoMechType, param);
- slot = PK11_GetSlotFromKey(key);
- result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size;
- PK11_FreeSlot(slot);
- ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT,
- key, param);
- SECITEM_FreeItem(param,PR_TRUE);
- if (ciphercx == NULL) {
- PORT_Free (result);
- return NULL;
- }
-
- result->cx = ciphercx;
- result->doit = (sec_pkcs7_cipher_function) PK11_CipherOp;
- result->destroy = (sec_pkcs7_cipher_destroy) PK11_DestroyContext;
- result->encrypt = PR_FALSE;
- result->pending_count = 0;
-
- return result;
-}
-
-/*
- * Create a cipher object to do encryption, based on the given bulk
- * encryption key and algorithm tag. Fill in the algorithm identifier
- * (which may include an iv) appropriately.
- *
- * XXX This interface, or one similar, would be really nice available
- * in general... I tried to keep the pkcs7-specific stuff (mostly
- * having to do with padding) out of here.
- *
- * XXX Once both are working, it might be nice to combine this and the
- * function above (for starting up decryption) into one routine, and just
- * have two simple cover functions which call it.
- */
-sec_PKCS7CipherObject *
-sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key,
- SECOidTag algtag, SECAlgorithmID *algid)
-{
- sec_PKCS7CipherObject *result;
- void *ciphercx;
- SECStatus rv;
- CK_MECHANISM_TYPE cryptoMechType;
- PK11SlotInfo *slot;
- SECItem *param = NULL;
- PRBool needToEncodeAlgid = PR_FALSE;
-
- result = (struct sec_pkcs7_cipher_object*)
- PORT_ZAlloc (sizeof(struct sec_pkcs7_cipher_object));
- if (result == NULL)
- return NULL;
-
- ciphercx = NULL;
- if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
- SECItem *pwitem;
-
- pwitem = (SECItem *)PK11_GetSymKeyUserData(key);
- if (!pwitem) {
- PORT_Free(result);
- return NULL;
- }
-
- cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
- if (cryptoMechType == CKM_INVALID_MECHANISM) {
- PORT_Free(result);
- SECITEM_FreeItem(param,PR_TRUE);
- return NULL;
- }
- } else {
- cryptoMechType = PK11_AlgtagToMechanism(algtag);
- param = PK11_GenerateNewParam(cryptoMechType, key);
- if (param == NULL) {
- PORT_Free(result);
- return NULL;
- }
- needToEncodeAlgid = PR_TRUE;
- }
-
- result->pad_size = PK11_GetBlockSize(cryptoMechType,param);
- slot = PK11_GetSlotFromKey(key);
- result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size;
- PK11_FreeSlot(slot);
- ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT,
- key, param);
- if (ciphercx == NULL) {
- PORT_Free (result);
- SECITEM_FreeItem(param,PR_TRUE);
- return NULL;
- }
-
- /*
- * These are placed after the CreateContextBySymKey() because some
- * mechanisms have to generate their IVs from their card (i.e. FORTEZZA).
- * Don't move it from here.
- */
- if (needToEncodeAlgid) {
- rv = PK11_ParamToAlgid(algtag,param,poolp,algid);
- if(rv != SECSuccess) {
- PORT_Free (result);
- SECITEM_FreeItem(param,PR_TRUE);
- return NULL;
- }
- }
- SECITEM_FreeItem(param,PR_TRUE);
-
- result->cx = ciphercx;
- result->doit = (sec_pkcs7_cipher_function) PK11_CipherOp;
- result->destroy = (sec_pkcs7_cipher_destroy) PK11_DestroyContext;
- result->encrypt = PR_TRUE;
- result->pending_count = 0;
-
- return result;
-}
-
-
-/*
- * Destroy the cipher object.
- */
-static void
-sec_pkcs7_destroy_cipher (sec_PKCS7CipherObject *obj)
-{
- (* obj->destroy) (obj->cx, PR_TRUE);
- PORT_Free (obj);
-}
-
-void
-sec_PKCS7DestroyDecryptObject (sec_PKCS7CipherObject *obj)
-{
- PORT_Assert (obj != NULL);
- if (obj == NULL)
- return;
- PORT_Assert (! obj->encrypt);
- sec_pkcs7_destroy_cipher (obj);
-}
-
-void
-sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj)
-{
- PORT_Assert (obj != NULL);
- if (obj == NULL)
- return;
- PORT_Assert (obj->encrypt);
- sec_pkcs7_destroy_cipher (obj);
-}
-
-
-/*
- * XXX I think all of the following lengths should be longs instead
- * of ints, but our current crypto interface uses ints, so I did too.
- */
-
-
-/*
- * What will be the output length of the next call to decrypt?
- * Result can be used to perform memory allocations. Note that the amount
- * is exactly accurate only when not doing a block cipher or when final
- * is false, otherwise it is an upper bound on the amount because until
- * we see the data we do not know how many padding bytes there are
- * (always between 1 and bsize).
- *
- * Note that this can return zero, which does not mean that the decrypt
- * operation can be skipped! (It simply means that there are not enough
- * bytes to make up an entire block; the bytes will be reserved until
- * there are enough to encrypt/decrypt at least one block.) However,
- * if zero is returned it *does* mean that no output buffer need be
- * passed in to the subsequent decrypt operation, as no output bytes
- * will be stored.
- */
-unsigned int
-sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
- PRBool final)
-{
- int blocks, block_size;
-
- PORT_Assert (! obj->encrypt);
-
- block_size = obj->block_size;
-
- /*
- * If this is not a block cipher, then we always have the same
- * number of output bytes as we had input bytes.
- */
- if (block_size == 0)
- return input_len;
-
- /*
- * On the final call, we will always use up all of the pending
- * bytes plus all of the input bytes, *but*, there will be padding
- * at the end and we cannot predict how many bytes of padding we
- * will end up removing. The amount given here is actually known
- * to be at least 1 byte too long (because we know we will have
- * at least 1 byte of padding), but seemed clearer/better to me.
- */
- if (final)
- return obj->pending_count + input_len;
-
- /*
- * Okay, this amount is exactly what we will output on the
- * next cipher operation. We will always hang onto the last
- * 1 - block_size bytes for non-final operations. That is,
- * we will do as many complete blocks as we can *except* the
- * last block (complete or partial). (This is because until
- * we know we are at the end, we cannot know when to interpret
- * and removing the padding byte(s), which are guaranteed to
- * be there.)
- */
- blocks = (obj->pending_count + input_len - 1) / block_size;
- return blocks * block_size;
-}
-
-/*
- * What will be the output length of the next call to encrypt?
- * Result can be used to perform memory allocations.
- *
- * Note that this can return zero, which does not mean that the encrypt
- * operation can be skipped! (It simply means that there are not enough
- * bytes to make up an entire block; the bytes will be reserved until
- * there are enough to encrypt/decrypt at least one block.) However,
- * if zero is returned it *does* mean that no output buffer need be
- * passed in to the subsequent encrypt operation, as no output bytes
- * will be stored.
- */
-unsigned int
-sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len,
- PRBool final)
-{
- int blocks, block_size;
- int pad_size;
-
- PORT_Assert (obj->encrypt);
-
- block_size = obj->block_size;
- pad_size = obj->pad_size;
-
- /*
- * If this is not a block cipher, then we always have the same
- * number of output bytes as we had input bytes.
- */
- if (block_size == 0)
- return input_len;
-
- /*
- * On the final call, we only send out what we need for
- * remaining bytes plus the padding. (There is always padding,
- * so even if we have an exact number of blocks as input, we
- * will add another full block that is just padding.)
- */
- if (final) {
- if (pad_size == 0) {
- return obj->pending_count + input_len;
- } else {
- blocks = (obj->pending_count + input_len) / pad_size;
- blocks++;
- return blocks*pad_size;
- }
- }
-
- /*
- * Now, count the number of complete blocks of data we have.
- */
- blocks = (obj->pending_count + input_len) / block_size;
-
-
- return blocks * block_size;
-}
-
-
-/*
- * Decrypt a given length of input buffer (starting at "input" and
- * containing "input_len" bytes), placing the decrypted bytes in
- * "output" and storing the output length in "*output_len_p".
- * "obj" is the return value from sec_PKCS7CreateDecryptObject.
- * When "final" is true, this is the last of the data to be decrypted.
- *
- * This is much more complicated than it sounds when the cipher is
- * a block-type, meaning that the decryption function will only
- * operate on whole blocks. But our caller is operating stream-wise,
- * and can pass in any number of bytes. So we need to keep track
- * of block boundaries. We save excess bytes between calls in "obj".
- * We also need to determine which bytes are padding, and remove
- * them from the output. We can only do this step when we know we
- * have the final block of data. PKCS #7 specifies that the padding
- * used for a block cipher is a string of bytes, each of whose value is
- * the same as the length of the padding, and that all data is padded.
- * (Even data that starts out with an exact multiple of blocks gets
- * added to it another block, all of which is padding.)
- */
-SECStatus
-sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
- unsigned int *output_len_p, unsigned int max_output_len,
- const unsigned char *input, unsigned int input_len,
- PRBool final)
-{
- int blocks, bsize, pcount, padsize;
- unsigned int max_needed, ifraglen, ofraglen, output_len;
- unsigned char *pbuf;
- SECStatus rv;
-
- PORT_Assert (! obj->encrypt);
-
- /*
- * Check that we have enough room for the output. Our caller should
- * already handle this; failure is really an internal error (i.e. bug).
- */
- max_needed = sec_PKCS7DecryptLength (obj, input_len, final);
- PORT_Assert (max_output_len >= max_needed);
- if (max_output_len < max_needed) {
- /* PORT_SetError (XXX); */
- return SECFailure;
- }
-
- /*
- * hardware encryption does not like small decryption sizes here, so we
- * allow both blocking and padding.
- */
- bsize = obj->block_size;
- padsize = obj->pad_size;
-
- /*
- * When no blocking or padding work to do, we can simply call the
- * cipher function and we are done.
- */
- if (bsize == 0) {
- return (* obj->doit) (obj->cx, output, output_len_p, max_output_len,
- input, input_len);
- }
-
- pcount = obj->pending_count;
- pbuf = obj->pending_buf;
-
- output_len = 0;
-
- if (pcount) {
- /*
- * Try to fill in an entire block, starting with the bytes
- * we already have saved away.
- */
- while (input_len && pcount < bsize) {
- pbuf[pcount++] = *input++;
- input_len--;
- }
- /*
- * If we have at most a whole block and this is not our last call,
- * then we are done for now. (We do not try to decrypt a lone
- * single block because we cannot interpret the padding bytes
- * until we know we are handling the very last block of all input.)
- */
- if (input_len == 0 && !final) {
- obj->pending_count = pcount;
- if (output_len_p)
- *output_len_p = 0;
- return SECSuccess;
- }
- /*
- * Given the logic above, we expect to have a full block by now.
- * If we do not, there is something wrong, either with our own
- * logic or with (length of) the data given to us.
- */
- PORT_Assert ((padsize == 0) || (pcount % padsize) == 0);
- if ((padsize != 0) && (pcount % padsize) != 0) {
- PORT_Assert (final);
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- /*
- * Decrypt the block.
- */
- rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len,
- pbuf, pcount);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then sec_PKCS7DecryptLength needs to be made smarter!
- */
- PORT_Assert (ofraglen == pcount);
-
- /*
- * Account for the bytes now in output.
- */
- max_output_len -= ofraglen;
- output_len += ofraglen;
- output += ofraglen;
- }
-
- /*
- * If this is our last call, we expect to have an exact number of
- * blocks left to be decrypted; we will decrypt them all.
- *
- * If not our last call, we always save between 1 and bsize bytes
- * until next time. (We must do this because we cannot be sure
- * that none of the decrypted bytes are padding bytes until we
- * have at least another whole block of data. You cannot tell by
- * looking -- the data could be anything -- you can only tell by
- * context, knowing you are looking at the last block.) We could
- * decrypt a whole block now but it is easier if we just treat it
- * the same way we treat partial block bytes.
- */
- if (final) {
- if (padsize) {
- blocks = input_len / padsize;
- ifraglen = blocks * padsize;
- } else ifraglen = input_len;
- PORT_Assert (ifraglen == input_len);
-
- if (ifraglen != input_len) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- } else {
- blocks = (input_len - 1) / bsize;
- ifraglen = blocks * bsize;
- PORT_Assert (ifraglen < input_len);
-
- pcount = input_len - ifraglen;
- PORT_Memcpy (pbuf, input + ifraglen, pcount);
- obj->pending_count = pcount;
- }
-
- if (ifraglen) {
- rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len,
- input, ifraglen);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then sec_PKCS7DecryptLength needs to be made smarter!
- */
- PORT_Assert (ifraglen == ofraglen);
- if (ifraglen != ofraglen) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
-
- output_len += ofraglen;
- } else {
- ofraglen = 0;
- }
-
- /*
- * If we just did our very last block, "remove" the padding by
- * adjusting the output length.
- */
- if (final && (padsize != 0)) {
- unsigned int padlen = *(output + ofraglen - 1);
- if (padlen == 0 || padlen > padsize) {
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- output_len -= padlen;
- }
-
- PORT_Assert (output_len_p != NULL || output_len == 0);
- if (output_len_p != NULL)
- *output_len_p = output_len;
-
- return SECSuccess;
-}
-
-/*
- * Encrypt a given length of input buffer (starting at "input" and
- * containing "input_len" bytes), placing the encrypted bytes in
- * "output" and storing the output length in "*output_len_p".
- * "obj" is the return value from sec_PKCS7CreateEncryptObject.
- * When "final" is true, this is the last of the data to be encrypted.
- *
- * This is much more complicated than it sounds when the cipher is
- * a block-type, meaning that the encryption function will only
- * operate on whole blocks. But our caller is operating stream-wise,
- * and can pass in any number of bytes. So we need to keep track
- * of block boundaries. We save excess bytes between calls in "obj".
- * We also need to add padding bytes at the end. PKCS #7 specifies
- * that the padding used for a block cipher is a string of bytes,
- * each of whose value is the same as the length of the padding,
- * and that all data is padded. (Even data that starts out with
- * an exact multiple of blocks gets added to it another block,
- * all of which is padding.)
- *
- * XXX I would kind of like to combine this with the function above
- * which does decryption, since they have a lot in common. But the
- * tricky parts about padding and filling blocks would be much
- * harder to read that way, so I left them separate. At least for
- * now until it is clear that they are right.
- */
-SECStatus
-sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
- unsigned int *output_len_p, unsigned int max_output_len,
- const unsigned char *input, unsigned int input_len,
- PRBool final)
-{
- int blocks, bsize, padlen, pcount, padsize;
- unsigned int max_needed, ifraglen, ofraglen, output_len;
- unsigned char *pbuf;
- SECStatus rv;
-
- PORT_Assert (obj->encrypt);
-
- /*
- * Check that we have enough room for the output. Our caller should
- * already handle this; failure is really an internal error (i.e. bug).
- */
- max_needed = sec_PKCS7EncryptLength (obj, input_len, final);
- PORT_Assert (max_output_len >= max_needed);
- if (max_output_len < max_needed) {
- /* PORT_SetError (XXX); */
- return SECFailure;
- }
-
- bsize = obj->block_size;
- padsize = obj->pad_size;
-
- /*
- * When no blocking and padding work to do, we can simply call the
- * cipher function and we are done.
- */
- if (bsize == 0) {
- return (* obj->doit) (obj->cx, output, output_len_p, max_output_len,
- input, input_len);
- }
-
- pcount = obj->pending_count;
- pbuf = obj->pending_buf;
-
- output_len = 0;
-
- if (pcount) {
- /*
- * Try to fill in an entire block, starting with the bytes
- * we already have saved away.
- */
- while (input_len && pcount < bsize) {
- pbuf[pcount++] = *input++;
- input_len--;
- }
- /*
- * If we do not have a full block and we know we will be
- * called again, then we are done for now.
- */
- if (pcount < bsize && !final) {
- obj->pending_count = pcount;
- if (output_len_p != NULL)
- *output_len_p = 0;
- return SECSuccess;
- }
- /*
- * If we have a whole block available, encrypt it.
- */
- if ((padsize == 0) || (pcount % padsize) == 0) {
- rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len,
- pbuf, pcount);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then sec_PKCS7EncryptLength needs to be made smarter!
- */
- PORT_Assert (ofraglen == pcount);
-
- /*
- * Account for the bytes now in output.
- */
- max_output_len -= ofraglen;
- output_len += ofraglen;
- output += ofraglen;
-
- pcount = 0;
- }
- }
-
- if (input_len) {
- PORT_Assert (pcount == 0);
-
- blocks = input_len / bsize;
- ifraglen = blocks * bsize;
-
- if (ifraglen) {
- rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len,
- input, ifraglen);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then sec_PKCS7EncryptLength needs to be made smarter!
- */
- PORT_Assert (ifraglen == ofraglen);
-
- max_output_len -= ofraglen;
- output_len += ofraglen;
- output += ofraglen;
- }
-
- pcount = input_len - ifraglen;
- PORT_Assert (pcount < bsize);
- if (pcount)
- PORT_Memcpy (pbuf, input + ifraglen, pcount);
- }
-
- if (final) {
- padlen = padsize - (pcount % padsize);
- PORT_Memset (pbuf + pcount, padlen, padlen);
- rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len,
- pbuf, pcount+padlen);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then sec_PKCS7EncryptLength needs to be made smarter!
- */
- PORT_Assert (ofraglen == (pcount+padlen));
- output_len += ofraglen;
- } else {
- obj->pending_count = pcount;
- }
-
- PORT_Assert (output_len_p != NULL || output_len == 0);
- if (output_len_p != NULL)
- *output_len_p = output_len;
-
- return SECSuccess;
-}
-
-/*
- * End of cipher stuff.
- * -------------------------------------------------------------------
- */
-
-
-/*
- * -------------------------------------------------------------------
- * XXX The following Attribute stuff really belongs elsewhere.
- * The Attribute type is *not* part of pkcs7 but rather X.501.
- * But for now, since PKCS7 is the only customer of attributes,
- * we define them here. Once there is a use outside of PKCS7,
- * then change the attribute types and functions from internal
- * to external naming convention, and move them elsewhere!
- */
-
-/*
- * Look through a set of attributes and find one that matches the
- * specified object ID. If "only" is true, then make sure that
- * there is not more than one attribute of the same type. Otherwise,
- * just return the first one found. (XXX Does anybody really want
- * that first-found behavior? It was like that when I found it...)
- */
-SEC_PKCS7Attribute *
-sec_PKCS7FindAttribute (SEC_PKCS7Attribute **attrs, SECOidTag oidtag,
- PRBool only)
-{
- SECOidData *oid;
- SEC_PKCS7Attribute *attr1, *attr2;
-
- if (attrs == NULL)
- return NULL;
-
- oid = SECOID_FindOIDByTag(oidtag);
- if (oid == NULL)
- return NULL;
-
- while ((attr1 = *attrs++) != NULL) {
- if (attr1->type.len == oid->oid.len && PORT_Memcmp (attr1->type.data,
- oid->oid.data,
- oid->oid.len) == 0)
- break;
- }
-
- if (attr1 == NULL)
- return NULL;
-
- if (!only)
- return attr1;
-
- while ((attr2 = *attrs++) != NULL) {
- if (attr2->type.len == oid->oid.len && PORT_Memcmp (attr2->type.data,
- oid->oid.data,
- oid->oid.len) == 0)
- break;
- }
-
- if (attr2 != NULL)
- return NULL;
-
- return attr1;
-}
-
-
-/*
- * Return the single attribute value, doing some sanity checking first:
- * - Multiple values are *not* expected.
- * - Empty values are *not* expected.
- */
-SECItem *
-sec_PKCS7AttributeValue(SEC_PKCS7Attribute *attr)
-{
- SECItem *value;
-
- if (attr == NULL)
- return NULL;
-
- value = attr->values[0];
-
- if (value == NULL || value->data == NULL || value->len == 0)
- return NULL;
-
- if (attr->values[1] != NULL)
- return NULL;
-
- return value;
-}
-
-static const SEC_ASN1Template *
-sec_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
-
- SEC_PKCS7Attribute *attribute;
- SECOidData *oiddata;
- PRBool encoded;
-
- PORT_Assert (src_or_dest != NULL);
- if (src_or_dest == NULL)
- return NULL;
-
- attribute = (SEC_PKCS7Attribute*)src_or_dest;
-
- if (encoding && attribute->encoded)
- return SEC_ASN1_GET(SEC_AnyTemplate);
-
- oiddata = attribute->typeTag;
- if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&attribute->type);
- attribute->typeTag = oiddata;
- }
-
- if (oiddata == NULL) {
- encoded = PR_TRUE;
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
- } else {
- switch (oiddata->offset) {
- default:
- encoded = PR_TRUE;
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
- break;
- case SEC_OID_PKCS9_EMAIL_ADDRESS:
- case SEC_OID_RFC1274_MAIL:
- case SEC_OID_PKCS9_UNSTRUCTURED_NAME:
- encoded = PR_FALSE;
- theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
- break;
- case SEC_OID_PKCS9_CONTENT_TYPE:
- encoded = PR_FALSE;
- theTemplate = SEC_ASN1_GET(SEC_ObjectIDTemplate);
- break;
- case SEC_OID_PKCS9_MESSAGE_DIGEST:
- encoded = PR_FALSE;
- theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate);
- break;
- case SEC_OID_PKCS9_SIGNING_TIME:
- encoded = PR_FALSE;
- theTemplate = SEC_ASN1_GET(CERT_TimeChoiceTemplate);
- break;
- /* XXX Want other types here, too */
- }
- }
-
- if (encoding) {
- /*
- * If we are encoding and we think we have an already-encoded value,
- * then the code which initialized this attribute should have set
- * the "encoded" property to true (and we would have returned early,
- * up above). No devastating error, but that code should be fixed.
- * (It could indicate that the resulting encoded bytes are wrong.)
- */
- PORT_Assert (!encoded);
- } else {
- /*
- * We are decoding; record whether the resulting value is
- * still encoded or not.
- */
- attribute->encoded = encoded;
- }
- return theTemplate;
-}
-
-static const SEC_ASN1TemplateChooserPtr sec_attr_chooser
- = sec_attr_choose_attr_value_template;
-
-static const SEC_ASN1Template sec_pkcs7_attribute_template[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SEC_PKCS7Attribute) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(SEC_PKCS7Attribute,type) },
- { SEC_ASN1_DYNAMIC | SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS7Attribute,values),
- &sec_attr_chooser },
- { 0 }
-};
-
-static const SEC_ASN1Template sec_pkcs7_set_of_attribute_template[] = {
- { SEC_ASN1_SET_OF, 0, sec_pkcs7_attribute_template },
-};
-
-/*
- * If you are wondering why this routine does not reorder the attributes
- * first, and might be tempted to make it do so, see the comment by the
- * call to ReorderAttributes in p7encode.c. (Or, see who else calls this
- * and think long and hard about the implications of making it always
- * do the reordering.)
- */
-SECItem *
-sec_PKCS7EncodeAttributes (PRArenaPool *poolp, SECItem *dest, void *src)
-{
- return SEC_ASN1EncodeItem (poolp, dest, src,
- sec_pkcs7_set_of_attribute_template);
-}
-
-/*
- * Make sure that the order of the attributes guarantees valid DER
- * (which must be in lexigraphically ascending order for a SET OF);
- * if reordering is necessary it will be done in place (in attrs).
- */
-SECStatus
-sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs)
-{
- PRArenaPool *poolp;
- int num_attrs, i, pass, besti;
- unsigned int j;
- SECItem **enc_attrs;
- SEC_PKCS7Attribute **new_attrs;
-
- /*
- * I think we should not be called with NULL. But if we are,
- * call it a success anyway, because the order *is* okay.
- */
- PORT_Assert (attrs != NULL);
- if (attrs == NULL)
- return SECSuccess;
-
- /*
- * Count how many attributes we are dealing with here.
- */
- num_attrs = 0;
- while (attrs[num_attrs] != NULL)
- num_attrs++;
-
- /*
- * Again, I think we should have some attributes here.
- * But if we do not, or if there is only one, then call it
- * a success because it also already has a fine order.
- */
- PORT_Assert (num_attrs);
- if (num_attrs == 0 || num_attrs == 1)
- return SECSuccess;
-
- /*
- * Allocate an arena for us to work with, so it is easy to
- * clean up all of the memory (fairly small pieces, really).
- */
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
- if (poolp == NULL)
- return SECFailure; /* no memory; nothing we can do... */
-
- /*
- * Allocate arrays to hold the individual encodings which we will use
- * for comparisons and the reordered attributes as they are sorted.
- */
- enc_attrs=(SECItem**)PORT_ArenaZAlloc(poolp, num_attrs*sizeof(SECItem *));
- new_attrs = (SEC_PKCS7Attribute**)PORT_ArenaZAlloc (poolp,
- num_attrs * sizeof(SEC_PKCS7Attribute *));
- if (enc_attrs == NULL || new_attrs == NULL) {
- PORT_FreeArena (poolp, PR_FALSE);
- return SECFailure;
- }
-
- /*
- * DER encode each individual attribute.
- */
- for (i = 0; i < num_attrs; i++) {
- enc_attrs[i] = SEC_ASN1EncodeItem (poolp, NULL, attrs[i],
- sec_pkcs7_attribute_template);
- if (enc_attrs[i] == NULL) {
- PORT_FreeArena (poolp, PR_FALSE);
- return SECFailure;
- }
- }
-
- /*
- * Now compare and sort them; this is not the most efficient sorting
- * method, but it is just fine for the problem at hand, because the
- * number of attributes is (always) going to be small.
- */
- for (pass = 0; pass < num_attrs; pass++) {
- /*
- * Find the first not-yet-accepted attribute. (Once one is
- * sorted into the other array, it is cleared from enc_attrs.)
- */
- for (i = 0; i < num_attrs; i++) {
- if (enc_attrs[i] != NULL)
- break;
- }
- PORT_Assert (i < num_attrs);
- besti = i;
-
- /*
- * Find the lowest (lexigraphically) encoding. One that is
- * shorter than all the rest is known to be "less" because each
- * attribute is of the same type (a SEQUENCE) and so thus the
- * first octet of each is the same, and the second octet is
- * the length (or the length of the length with the high bit
- * set, followed by the length, which also works out to always
- * order the shorter first). Two (or more) that have the
- * same length need to be compared byte by byte until a mismatch
- * is found.
- */
- for (i = besti + 1; i < num_attrs; i++) {
- if (enc_attrs[i] == NULL) /* slot already handled */
- continue;
-
- if (enc_attrs[i]->len != enc_attrs[besti]->len) {
- if (enc_attrs[i]->len < enc_attrs[besti]->len)
- besti = i;
- continue;
- }
-
- for (j = 0; j < enc_attrs[i]->len; j++) {
- if (enc_attrs[i]->data[j] < enc_attrs[besti]->data[j]) {
- besti = i;
- break;
- }
- }
-
- /*
- * For this not to be true, we would have to have encountered
- * two *identical* attributes, which I think we should not see.
- * So assert if it happens, but even if it does, let it go
- * through; the ordering of the two does not matter.
- */
- PORT_Assert (j < enc_attrs[i]->len);
- }
-
- /*
- * Now we have found the next-lowest one; copy it over and
- * remove it from enc_attrs.
- */
- new_attrs[pass] = attrs[besti];
- enc_attrs[besti] = NULL;
- }
-
- /*
- * Now new_attrs has the attributes in the order we want;
- * copy them back into the attrs array we started with.
- */
- for (i = 0; i < num_attrs; i++)
- attrs[i] = new_attrs[i];
-
- PORT_FreeArena (poolp, PR_FALSE);
- return SECSuccess;
-}
-
-/*
- * End of attribute stuff.
- * -------------------------------------------------------------------
- */
-
-
-/*
- * Templates and stuff. Keep these at the end of the file.
- */
-
-/* forward declaration */
-static const SEC_ASN1Template *
-sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding);
-
-static const SEC_ASN1TemplateChooserPtr sec_pkcs7_chooser
- = sec_pkcs7_choose_content_template;
-
-const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7ContentInfo) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(SEC_PKCS7ContentInfo,contentType) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM
- | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SEC_PKCS7ContentInfo,content),
- &sec_pkcs7_chooser },
- { 0 }
-};
-
-/* XXX These names should change from external to internal convention. */
-
-static const SEC_ASN1Template SEC_PKCS7SignerInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SEC_PKCS7SignerInfo) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7SignerInfo,version) },
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7SignerInfo,issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7SignerInfo,digestAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(SEC_PKCS7SignerInfo,authAttr),
- sec_pkcs7_set_of_attribute_template },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7SignerInfo,digestEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS7SignerInfo,encDigest) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(SEC_PKCS7SignerInfo,unAuthAttr),
- sec_pkcs7_set_of_attribute_template },
- { 0 }
-};
-
-static const SEC_ASN1Template SEC_PKCS7SignedDataTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7SignedData) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7SignedData,version) },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7SignedData,digestAlgorithms),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE,
- offsetof(SEC_PKCS7SignedData,contentInfo),
- sec_PKCS7ContentInfoTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 0,
- offsetof(SEC_PKCS7SignedData,rawCerts),
- SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
- offsetof(SEC_PKCS7SignedData,crls),
- SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
- { SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS7SignedData,signerInfos),
- SEC_PKCS7SignerInfoTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template SEC_PointerToPKCS7SignedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_PKCS7SignedDataTemplate }
-};
-
-static const SEC_ASN1Template SEC_PKCS7RecipientInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SEC_PKCS7RecipientInfo) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7RecipientInfo,version) },
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7RecipientInfo,issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7RecipientInfo,keyEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS7RecipientInfo,encKey) },
- { 0 }
-};
-
-static const SEC_ASN1Template SEC_PKCS7EncryptedContentInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7EncryptedContentInfo) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(SEC_PKCS7EncryptedContentInfo,contentType) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7EncryptedContentInfo,contentEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_MAY_STREAM | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 0,
- offsetof(SEC_PKCS7EncryptedContentInfo,encContent),
- SEC_ASN1_SUB(SEC_OctetStringTemplate) },
- { 0 }
-};
-
-static const SEC_ASN1Template SEC_PKCS7EnvelopedDataTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7EnvelopedData) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7EnvelopedData,version) },
- { SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS7EnvelopedData,recipientInfos),
- SEC_PKCS7RecipientInfoTemplate },
- { SEC_ASN1_INLINE,
- offsetof(SEC_PKCS7EnvelopedData,encContentInfo),
- SEC_PKCS7EncryptedContentInfoTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template SEC_PointerToPKCS7EnvelopedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_PKCS7EnvelopedDataTemplate }
-};
-
-static const SEC_ASN1Template SEC_PKCS7SignedAndEnvelopedDataTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7SignedAndEnvelopedData) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,version) },
- { SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,recipientInfos),
- SEC_PKCS7RecipientInfoTemplate },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,digestAlgorithms),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,encContentInfo),
- SEC_PKCS7EncryptedContentInfoTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 0,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,rawCerts),
- SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,crls),
- SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
- { SEC_ASN1_SET_OF,
- offsetof(SEC_PKCS7SignedAndEnvelopedData,signerInfos),
- SEC_PKCS7SignerInfoTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template
-SEC_PointerToPKCS7SignedAndEnvelopedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_PKCS7SignedAndEnvelopedDataTemplate }
-};
-
-static const SEC_ASN1Template SEC_PKCS7DigestedDataTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7DigestedData) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7DigestedData,version) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(SEC_PKCS7DigestedData,digestAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE,
- offsetof(SEC_PKCS7DigestedData,contentInfo),
- sec_PKCS7ContentInfoTemplate },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS7DigestedData,digest) },
- { 0 }
-};
-
-static const SEC_ASN1Template SEC_PointerToPKCS7DigestedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_PKCS7DigestedDataTemplate }
-};
-
-static const SEC_ASN1Template SEC_PKCS7EncryptedDataTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(SEC_PKCS7EncryptedData) },
- { SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS7EncryptedData,version) },
- { SEC_ASN1_INLINE,
- offsetof(SEC_PKCS7EncryptedData,encContentInfo),
- SEC_PKCS7EncryptedContentInfoTemplate },
- { 0 }
-};
-
-static const SEC_ASN1Template SEC_PointerToPKCS7EncryptedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_PKCS7EncryptedDataTemplate }
-};
-
-static const SEC_ASN1Template *
-sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- SEC_PKCS7ContentInfo *cinfo;
- SECOidTag kind;
-
- PORT_Assert (src_or_dest != NULL);
- if (src_or_dest == NULL)
- return NULL;
-
- cinfo = (SEC_PKCS7ContentInfo*)src_or_dest;
- kind = SEC_PKCS7ContentType (cinfo);
- switch (kind) {
- default:
- theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
- break;
- case SEC_OID_PKCS7_DATA:
- theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- theTemplate = SEC_PointerToPKCS7SignedDataTemplate;
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- theTemplate = SEC_PointerToPKCS7EnvelopedDataTemplate;
- break;
- case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
- theTemplate = SEC_PointerToPKCS7SignedAndEnvelopedDataTemplate;
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- theTemplate = SEC_PointerToPKCS7DigestedDataTemplate;
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- theTemplate = SEC_PointerToPKCS7EncryptedDataTemplate;
- break;
- }
- return theTemplate;
-}
-
-/*
- * End of templates. Do not add stuff after this; put new code
- * up above the start of the template definitions.
- */
diff --git a/security/nss/lib/pkcs7/p7local.h b/security/nss/lib/pkcs7/p7local.h
deleted file mode 100644
index 5139d06e2..000000000
--- a/security/nss/lib/pkcs7/p7local.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Support routines for PKCS7 implementation, none of which are exported.
- * This file should only contain things that are needed by both the
- * encoding/creation side *and* the decoding/decryption side. Anything
- * else should just be static routines in the appropriate file.
- *
- * Do not export this file! If something in here is really needed outside
- * of pkcs7 code, first try to add a PKCS7 interface which will do it for
- * you. If that has a problem, then just move out what you need, changing
- * its name as appropriate!
- *
- * $Id$
- */
-
-#ifndef _P7LOCAL_H_
-#define _P7LOCAL_H_
-
-#include "secpkcs7.h"
-#include "secasn1t.h"
-
-extern const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[];
-
-/* opaque objects */
-typedef struct sec_pkcs7_cipher_object sec_PKCS7CipherObject;
-
-
-/************************************************************************/
-SEC_BEGIN_PROTOS
-
-/*
- * Look through a set of attributes and find one that matches the
- * specified object ID. If "only" is true, then make sure that
- * there is not more than one attribute of the same type. Otherwise,
- * just return the first one found. (XXX Does anybody really want
- * that first-found behavior? It was like that when I found it...)
- */
-extern SEC_PKCS7Attribute *sec_PKCS7FindAttribute (SEC_PKCS7Attribute **attrs,
- SECOidTag oidtag,
- PRBool only);
-/*
- * Return the single attribute value, doing some sanity checking first:
- * - Multiple values are *not* expected.
- * - Empty values are *not* expected.
- */
-extern SECItem *sec_PKCS7AttributeValue (SEC_PKCS7Attribute *attr);
-
-/*
- * Encode a set of attributes (found in "src").
- */
-extern SECItem *sec_PKCS7EncodeAttributes (PRArenaPool *poolp,
- SECItem *dest, void *src);
-
-/*
- * Make sure that the order of the attributes guarantees valid DER
- * (which must be in lexigraphically ascending order for a SET OF);
- * if reordering is necessary it will be done in place (in attrs).
- */
-extern SECStatus sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs);
-
-
-/*
- * Create a context for decrypting, based on the given key and algorithm.
- */
-extern sec_PKCS7CipherObject *
-sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid);
-
-/*
- * Create a context for encrypting, based on the given key and algorithm,
- * and fill in the algorithm id.
- */
-extern sec_PKCS7CipherObject *
-sec_PKCS7CreateEncryptObject (PRArenaPool *poolp, PK11SymKey *key,
- SECOidTag algtag, SECAlgorithmID *algid);
-
-/*
- * Destroy the given decryption or encryption object.
- */
-extern void sec_PKCS7DestroyDecryptObject (sec_PKCS7CipherObject *obj);
-extern void sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj);
-
-/*
- * What will be the output length of the next call to encrypt/decrypt?
- * Result can be used to perform memory allocations. Note that the amount
- * is exactly accurate only when not doing a block cipher or when final
- * is false, otherwise it is an upper bound on the amount because until
- * we see the data we do not know how many padding bytes there are
- * (always between 1 and the cipher block size).
- *
- * Note that this can return zero, which does not mean that the cipher
- * operation can be skipped! (It simply means that there are not enough
- * bytes to make up an entire block; the bytes will be reserved until
- * there are enough to encrypt/decrypt at least one block.) However,
- * if zero is returned it *does* mean that no output buffer need be
- * passed in to the subsequent cipher operation, as no output bytes
- * will be stored.
- */
-extern unsigned int sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj,
- unsigned int input_len,
- PRBool final);
-extern unsigned int sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj,
- unsigned int input_len,
- PRBool final);
-
-/*
- * Decrypt a given length of input buffer (starting at "input" and
- * containing "input_len" bytes), placing the decrypted bytes in
- * "output" and storing the output length in "*output_len_p".
- * "obj" is the return value from sec_PKCS7CreateDecryptObject.
- * When "final" is true, this is the last of the data to be decrypted.
- */
-extern SECStatus sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj,
- unsigned char *output,
- unsigned int *output_len_p,
- unsigned int max_output_len,
- const unsigned char *input,
- unsigned int input_len,
- PRBool final);
-
-/*
- * Encrypt a given length of input buffer (starting at "input" and
- * containing "input_len" bytes), placing the encrypted bytes in
- * "output" and storing the output length in "*output_len_p".
- * "obj" is the return value from sec_PKCS7CreateEncryptObject.
- * When "final" is true, this is the last of the data to be encrypted.
- */
-extern SECStatus sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj,
- unsigned char *output,
- unsigned int *output_len_p,
- unsigned int max_output_len,
- const unsigned char *input,
- unsigned int input_len,
- PRBool final);
-
-/************************************************************************/
-SEC_END_PROTOS
-
-#endif /* _P7LOCAL_H_ */
diff --git a/security/nss/lib/pkcs7/pkcs7t.h b/security/nss/lib/pkcs7/pkcs7t.h
deleted file mode 100644
index 4acb33796..000000000
--- a/security/nss/lib/pkcs7/pkcs7t.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Header for pkcs7 types.
- *
- * $Id$
- */
-
-#ifndef _PKCS7T_H_
-#define _PKCS7T_H_
-
-#include "plarena.h"
-
-#include "seccomon.h"
-#include "secoidt.h"
-#include "certt.h"
-#include "secmodt.h"
-
-/* Opaque objects */
-typedef struct SEC_PKCS7DecoderContextStr SEC_PKCS7DecoderContext;
-typedef struct SEC_PKCS7EncoderContextStr SEC_PKCS7EncoderContext;
-
-/* legacy defines that haven't been active for years */
-typedef void *(*SECKEYGetPasswordKey)(void *arg, void *handle);
-
-
-/* Non-opaque objects. NOTE, though: I want them to be treated as
- * opaque as much as possible. If I could hide them completely,
- * I would. (I tried, but ran into trouble that was taking me too
- * much time to get out of.) I still intend to try to do so.
- * In fact, the only type that "outsiders" should even *name* is
- * SEC_PKCS7ContentInfo, and they should not reference its fields.
- */
-/* rjr: PKCS #11 cert handling (pk11cert.c) does use SEC_PKCS7RecipientInfo's.
- * This is because when we search the recipient list for the cert and key we
- * want, we need to invert the order of the loops we used to have. The old
- * loops were:
- *
- * For each recipient {
- * find_cert = PK11_Find_AllCert(recipient->issuerSN);
- * [which unrolls to... ]
- * For each slot {
- * Log into slot;
- * search slot for cert;
- * }
- * }
- *
- * the new loop searchs all the recipients at once on a slot. this allows
- * PKCS #11 to order slots in such a way that logout slots don't get checked
- * if we can find the cert on a logged in slot. This eliminates lots of
- * spurious password prompts when smart cards are installed... so why this
- * comment? If you make SEC_PKCS7RecipientInfo completely opaque, you need
- * to provide a non-opaque list of issuerSN's (the only field PKCS#11 needs
- * and fix up pk11cert.c first. NOTE: Only S/MIME calls this special PKCS #11
- * function.
- */
-typedef struct SEC_PKCS7ContentInfoStr SEC_PKCS7ContentInfo;
-typedef struct SEC_PKCS7SignedDataStr SEC_PKCS7SignedData;
-typedef struct SEC_PKCS7EncryptedContentInfoStr SEC_PKCS7EncryptedContentInfo;
-typedef struct SEC_PKCS7EnvelopedDataStr SEC_PKCS7EnvelopedData;
-typedef struct SEC_PKCS7SignedAndEnvelopedDataStr
- SEC_PKCS7SignedAndEnvelopedData;
-typedef struct SEC_PKCS7SignerInfoStr SEC_PKCS7SignerInfo;
-typedef struct SEC_PKCS7RecipientInfoStr SEC_PKCS7RecipientInfo;
-typedef struct SEC_PKCS7DigestedDataStr SEC_PKCS7DigestedData;
-typedef struct SEC_PKCS7EncryptedDataStr SEC_PKCS7EncryptedData;
-/*
- * The following is not actually a PKCS7 type, but for now it is only
- * used by PKCS7, so we have adopted it. If someone else *ever* needs
- * it, its name should be changed and it should be moved out of here.
- * Do not dare to use it without doing so!
- */
-typedef struct SEC_PKCS7AttributeStr SEC_PKCS7Attribute;
-
-struct SEC_PKCS7ContentInfoStr {
- PLArenaPool *poolp; /* local; not part of encoding */
- PRBool created; /* local; not part of encoding */
- int refCount; /* local; not part of encoding */
- SECOidData *contentTypeTag; /* local; not part of encoding */
- SECKEYGetPasswordKey pwfn; /* local; not part of encoding */
- void *pwfn_arg; /* local; not part of encoding */
- SECItem contentType;
- union {
- SECItem *data;
- SEC_PKCS7DigestedData *digestedData;
- SEC_PKCS7EncryptedData *encryptedData;
- SEC_PKCS7EnvelopedData *envelopedData;
- SEC_PKCS7SignedData *signedData;
- SEC_PKCS7SignedAndEnvelopedData *signedAndEnvelopedData;
- } content;
-};
-
-struct SEC_PKCS7SignedDataStr {
- SECItem version;
- SECAlgorithmID **digestAlgorithms;
- SEC_PKCS7ContentInfo contentInfo;
- SECItem **rawCerts;
- CERTSignedCrl **crls;
- SEC_PKCS7SignerInfo **signerInfos;
- SECItem **digests; /* local; not part of encoding */
- CERTCertificate **certs; /* local; not part of encoding */
- CERTCertificateList **certLists; /* local; not part of encoding */
-};
-#define SEC_PKCS7_SIGNED_DATA_VERSION 1 /* what we *create* */
-
-struct SEC_PKCS7EncryptedContentInfoStr {
- SECOidData *contentTypeTag; /* local; not part of encoding */
- SECItem contentType;
- SECAlgorithmID contentEncAlg;
- SECItem encContent;
- SECItem plainContent; /* local; not part of encoding */
- /* bytes not encrypted, but encoded */
- int keysize; /* local; not part of encoding */
- /* size of bulk encryption key
- * (only used by creation code) */
- SECOidTag encalg; /* local; not part of encoding */
- /* oid tag of encryption algorithm
- * (only used by creation code) */
-};
-
-struct SEC_PKCS7EnvelopedDataStr {
- SECItem version;
- SEC_PKCS7RecipientInfo **recipientInfos;
- SEC_PKCS7EncryptedContentInfo encContentInfo;
-};
-#define SEC_PKCS7_ENVELOPED_DATA_VERSION 0 /* what we *create* */
-
-struct SEC_PKCS7SignedAndEnvelopedDataStr {
- SECItem version;
- SEC_PKCS7RecipientInfo **recipientInfos;
- SECAlgorithmID **digestAlgorithms;
- SEC_PKCS7EncryptedContentInfo encContentInfo;
- SECItem **rawCerts;
- CERTSignedCrl **crls;
- SEC_PKCS7SignerInfo **signerInfos;
- SECItem **digests; /* local; not part of encoding */
- CERTCertificate **certs; /* local; not part of encoding */
- CERTCertificateList **certLists; /* local; not part of encoding */
- PK11SymKey *sigKey; /* local; not part of encoding */
-};
-#define SEC_PKCS7_SIGNED_AND_ENVELOPED_DATA_VERSION 1 /* what we *create* */
-
-struct SEC_PKCS7SignerInfoStr {
- SECItem version;
- CERTIssuerAndSN *issuerAndSN;
- SECAlgorithmID digestAlg;
- SEC_PKCS7Attribute **authAttr;
- SECAlgorithmID digestEncAlg;
- SECItem encDigest;
- SEC_PKCS7Attribute **unAuthAttr;
- CERTCertificate *cert; /* local; not part of encoding */
- CERTCertificateList *certList; /* local; not part of encoding */
-};
-#define SEC_PKCS7_SIGNER_INFO_VERSION 1 /* what we *create* */
-
-struct SEC_PKCS7RecipientInfoStr {
- SECItem version;
- CERTIssuerAndSN *issuerAndSN;
- SECAlgorithmID keyEncAlg;
- SECItem encKey;
- CERTCertificate *cert; /* local; not part of encoding */
-};
-#define SEC_PKCS7_RECIPIENT_INFO_VERSION 0 /* what we *create* */
-
-struct SEC_PKCS7DigestedDataStr {
- SECItem version;
- SECAlgorithmID digestAlg;
- SEC_PKCS7ContentInfo contentInfo;
- SECItem digest;
-};
-#define SEC_PKCS7_DIGESTED_DATA_VERSION 0 /* what we *create* */
-
-struct SEC_PKCS7EncryptedDataStr {
- SECItem version;
- SEC_PKCS7EncryptedContentInfo encContentInfo;
-};
-#define SEC_PKCS7_ENCRYPTED_DATA_VERSION 0 /* what we *create* */
-
-/*
- * See comment above about this type not really belonging to PKCS7.
- */
-struct SEC_PKCS7AttributeStr {
- /* The following fields make up an encoded Attribute: */
- SECItem type;
- SECItem **values; /* data may or may not be encoded */
- /* The following fields are not part of an encoded Attribute: */
- SECOidData *typeTag;
- PRBool encoded; /* when true, values are encoded */
-};
-
-/*
- * Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart.
- * If specified, this is where the content bytes (only) will be "sent"
- * as they are recovered during the decoding.
- *
- * XXX Should just combine this with SEC_PKCS7EncoderContentCallback type
- * and use a simpler, common name.
- */
-typedef void (* SEC_PKCS7DecoderContentCallback)(void *arg,
- const char *buf,
- unsigned long len);
-
-/*
- * Type of function passed to SEC_PKCS7Encode or SEC_PKCS7EncoderStart.
- * This is where the encoded bytes will be "sent".
- *
- * XXX Should just combine this with SEC_PKCS7DecoderContentCallback type
- * and use a simpler, common name.
- */
-typedef void (* SEC_PKCS7EncoderOutputCallback)(void *arg,
- const char *buf,
- unsigned long len);
-
-
-/*
- * Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart
- * to retrieve the decryption key. This function is inteded to be
- * used for EncryptedData content info's which do not have a key available
- * in a certificate, etc.
- */
-typedef PK11SymKey * (* SEC_PKCS7GetDecryptKeyCallback)(void *arg,
- SECAlgorithmID *algid);
-
-/*
- * Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart.
- * This function in intended to be used to verify that decrypting a
- * particular crypto algorithm is allowed. Content types which do not
- * require decryption will not need the callback. If the callback
- * is not specified for content types which require decryption, the
- * decryption will be disallowed.
- */
-typedef PRBool (* SEC_PKCS7DecryptionAllowedCallback)(SECAlgorithmID *algid,
- PK11SymKey *bulkkey);
-
-#endif /* _PKCS7T_H_ */
diff --git a/security/nss/lib/pkcs7/secmime.c b/security/nss/lib/pkcs7/secmime.c
deleted file mode 100644
index 9ebe66ed7..000000000
--- a/security/nss/lib/pkcs7/secmime.c
+++ /dev/null
@@ -1,824 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Stuff specific to S/MIME policy and interoperability.
- * Depends on PKCS7, but there should be no dependency the other way around.
- *
- * $Id$
- */
-
-#include "secmime.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "ciferfam.h" /* for CIPHER_FAMILY symbols */
-#include "secasn1.h"
-#include "secitem.h"
-#include "cert.h"
-#include "key.h"
-#include "secerr.h"
-
-typedef struct smime_cipher_map_struct {
- unsigned long cipher;
- SECOidTag algtag;
- SECItem *parms;
-} smime_cipher_map;
-
-/*
- * These are macros because I think some subsequent parameters,
- * like those for RC5, will want to use them, too, separately.
- */
-#define SMIME_DER_INTVAL_16 SEC_ASN1_INTEGER, 0x01, 0x10
-#define SMIME_DER_INTVAL_40 SEC_ASN1_INTEGER, 0x01, 0x28
-#define SMIME_DER_INTVAL_64 SEC_ASN1_INTEGER, 0x01, 0x40
-#define SMIME_DER_INTVAL_128 SEC_ASN1_INTEGER, 0x02, 0x00, 0x80
-
-#ifdef SMIME_DOES_RC5 /* will be needed; quiet unused warning for now */
-static unsigned char smime_int16[] = { SMIME_DER_INTVAL_16 };
-#endif
-static unsigned char smime_int40[] = { SMIME_DER_INTVAL_40 };
-static unsigned char smime_int64[] = { SMIME_DER_INTVAL_64 };
-static unsigned char smime_int128[] = { SMIME_DER_INTVAL_128 };
-
-static SECItem smime_rc2p40 = { siBuffer, smime_int40, sizeof(smime_int40) };
-static SECItem smime_rc2p64 = { siBuffer, smime_int64, sizeof(smime_int64) };
-static SECItem smime_rc2p128 = { siBuffer, smime_int128, sizeof(smime_int128) };
-
-static smime_cipher_map smime_cipher_maps[] = {
- { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, &smime_rc2p40 },
- { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, &smime_rc2p64 },
- { SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, &smime_rc2p128 },
-#ifdef SMIME_DOES_RC5
- { SMIME_RC5PAD_64_16_40, SEC_OID_RC5_CBC_PAD, &smime_rc5p40 },
- { SMIME_RC5PAD_64_16_64, SEC_OID_RC5_CBC_PAD, &smime_rc5p64 },
- { SMIME_RC5PAD_64_16_128, SEC_OID_RC5_CBC_PAD, &smime_rc5p128 },
-#endif
- { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL },
- { SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL }
-};
-
-/*
- * Note, the following value really just needs to be an upper bound
- * on the ciphers.
- */
-static const int smime_symmetric_count = sizeof(smime_cipher_maps)
- / sizeof(smime_cipher_map);
-
-static unsigned long *smime_prefs, *smime_newprefs;
-static int smime_current_pref_index = 0;
-static PRBool smime_prefs_complete = PR_FALSE;
-static PRBool smime_prefs_changed = PR_TRUE;
-
-static unsigned long smime_policy_bits = 0;
-
-
-static int
-smime_mapi_by_cipher (unsigned long cipher)
-{
- int i;
-
- for (i = 0; i < smime_symmetric_count; i++) {
- if (smime_cipher_maps[i].cipher == cipher)
- break;
- }
-
- if (i == smime_symmetric_count)
- return -1;
-
- return i;
-}
-
-
-/*
- * this function locally records the user's preference
- */
-SECStatus
-SECMIME_EnableCipher(long which, int on)
-{
- unsigned long mask;
-
- if (smime_newprefs == NULL || smime_prefs_complete) {
- /*
- * This is either the very first time, or we are starting over.
- */
- smime_newprefs = (unsigned long*)PORT_ZAlloc (smime_symmetric_count
- * sizeof(*smime_newprefs));
- if (smime_newprefs == NULL)
- return SECFailure;
- smime_current_pref_index = 0;
- smime_prefs_complete = PR_FALSE;
- }
-
- mask = which & CIPHER_FAMILYID_MASK;
- if (mask == CIPHER_FAMILYID_MASK) {
- /*
- * This call signifies that all preferences have been set.
- * Move "newprefs" over, after checking first whether or
- * not the new ones are different from the old ones.
- */
- if (smime_prefs != NULL) {
- if (PORT_Memcmp (smime_prefs, smime_newprefs,
- smime_symmetric_count * sizeof(*smime_prefs)) == 0)
- smime_prefs_changed = PR_FALSE;
- else
- smime_prefs_changed = PR_TRUE;
- PORT_Free (smime_prefs);
- }
-
- smime_prefs = smime_newprefs;
- smime_prefs_complete = PR_TRUE;
- return SECSuccess;
- }
-
- PORT_Assert (mask == CIPHER_FAMILYID_SMIME);
- if (mask != CIPHER_FAMILYID_SMIME) {
- /* XXX set an error! */
- return SECFailure;
- }
-
- if (on) {
- PORT_Assert (smime_current_pref_index < smime_symmetric_count);
- if (smime_current_pref_index >= smime_symmetric_count) {
- /* XXX set an error! */
- return SECFailure;
- }
-
- smime_newprefs[smime_current_pref_index++] = which;
- }
-
- return SECSuccess;
-}
-
-
-/*
- * this function locally records the export policy
- */
-SECStatus
-SECMIME_SetPolicy(long which, int on)
-{
- unsigned long mask;
-
- PORT_Assert ((which & CIPHER_FAMILYID_MASK) == CIPHER_FAMILYID_SMIME);
- if ((which & CIPHER_FAMILYID_MASK) != CIPHER_FAMILYID_SMIME) {
- /* XXX set an error! */
- return SECFailure;
- }
-
- which &= ~CIPHER_FAMILYID_MASK;
-
- PORT_Assert (which < 32); /* bits in the long */
- if (which >= 32) {
- /* XXX set an error! */
- return SECFailure;
- }
-
- mask = 1UL << which;
-
- if (on) {
- smime_policy_bits |= mask;
- } else {
- smime_policy_bits &= ~mask;
- }
-
- return SECSuccess;
-}
-
-
-/*
- * Based on the given algorithm (including its parameters, in some cases!)
- * and the given key (may or may not be inspected, depending on the
- * algorithm), find the appropriate policy algorithm specification
- * and return it. If no match can be made, -1 is returned.
- */
-static long
-smime_policy_algorithm (SECAlgorithmID *algid, PK11SymKey *key)
-{
- SECOidTag algtag;
-
- algtag = SECOID_GetAlgorithmTag (algid);
- switch (algtag) {
- case SEC_OID_RC2_CBC:
- {
- unsigned int keylen_bits;
-
- keylen_bits = PK11_GetKeyStrength (key, algid);
- switch (keylen_bits) {
- case 40:
- return SMIME_RC2_CBC_40;
- case 64:
- return SMIME_RC2_CBC_64;
- case 128:
- return SMIME_RC2_CBC_128;
- default:
- break;
- }
- }
- break;
- case SEC_OID_DES_CBC:
- return SMIME_DES_CBC_56;
- case SEC_OID_DES_EDE3_CBC:
- return SMIME_DES_EDE3_168;
-#ifdef SMIME_DOES_RC5
- case SEC_OID_RC5_CBC_PAD:
- PORT_Assert (0); /* XXX need to pull out parameters and match */
- break;
-#endif
- default:
- break;
- }
-
- return -1;
-}
-
-
-static PRBool
-smime_cipher_allowed (unsigned long which)
-{
- unsigned long mask;
-
- which &= ~CIPHER_FAMILYID_MASK;
- PORT_Assert (which < 32); /* bits per long (min) */
- if (which >= 32)
- return PR_FALSE;
-
- mask = 1UL << which;
- if ((mask & smime_policy_bits) == 0)
- return PR_FALSE;
-
- return PR_TRUE;
-}
-
-
-PRBool
-SECMIME_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key)
-{
- long which;
-
- which = smime_policy_algorithm (algid, key);
- if (which < 0)
- return PR_FALSE;
-
- return smime_cipher_allowed ((unsigned long)which);
-}
-
-
-/*
- * Does the current policy allow *any* S/MIME encryption (or decryption)?
- *
- * This tells whether or not *any* S/MIME encryption can be done,
- * according to policy. Callers may use this to do nicer user interface
- * (say, greying out a checkbox so a user does not even try to encrypt
- * a message when they are not allowed to) or for any reason they want
- * to check whether S/MIME encryption (or decryption, for that matter)
- * may be done.
- *
- * It takes no arguments. The return value is a simple boolean:
- * PR_TRUE means encryption (or decryption) is *possible*
- * (but may still fail due to other reasons, like because we cannot
- * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee)
- * PR_FALSE means encryption (or decryption) is not permitted
- *
- * There are no errors from this routine.
- */
-PRBool
-SECMIME_EncryptionPossible (void)
-{
- if (smime_policy_bits != 0)
- return PR_TRUE;
-
- return PR_FALSE;
-}
-
-
-/*
- * XXX Would like the "parameters" field to be a SECItem *, but the
- * encoder is having trouble with optional pointers to an ANY. Maybe
- * once that is fixed, can change this back...
- */
-typedef struct smime_capability_struct {
- unsigned long cipher; /* local; not part of encoding */
- SECOidTag capIDTag; /* local; not part of encoding */
- SECItem capabilityID;
- SECItem parameters;
-} smime_capability;
-
-static const SEC_ASN1Template smime_capability_template[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(smime_capability) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(smime_capability,capabilityID), },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(smime_capability,parameters), },
- { 0, }
-};
-
-static const SEC_ASN1Template smime_capabilities_template[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, smime_capability_template }
-};
-
-
-
-static void
-smime_fill_capability (smime_capability *cap)
-{
- unsigned long cipher;
- SECOidTag algtag;
- int i;
-
- algtag = SECOID_FindOIDTag (&(cap->capabilityID));
-
- for (i = 0; i < smime_symmetric_count; i++) {
- if (smime_cipher_maps[i].algtag != algtag)
- continue;
- /*
- * XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing
- * 2 NULLs as equal and NULL and non-NULL as not equal), we could
- * use that here instead of all of the following comparison code.
- */
- if (cap->parameters.data != NULL) {
- if (smime_cipher_maps[i].parms == NULL)
- continue;
- if (cap->parameters.len != smime_cipher_maps[i].parms->len)
- continue;
- if (PORT_Memcmp (cap->parameters.data,
- smime_cipher_maps[i].parms->data,
- cap->parameters.len) == 0)
- break;
- } else if (smime_cipher_maps[i].parms == NULL) {
- break;
- }
- }
-
- if (i == smime_symmetric_count)
- cipher = 0;
- else
- cipher = smime_cipher_maps[i].cipher;
-
- cap->cipher = cipher;
- cap->capIDTag = algtag;
-}
-
-
-static long
-smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts)
-{
- PRArenaPool *poolp;
- long chosen_cipher;
- int *cipher_abilities;
- int *cipher_votes;
- int strong_mapi;
- int rcount, mapi, max;
-
- if (smime_policy_bits == 0) {
- PORT_SetError (SEC_ERROR_BAD_EXPORT_ALGORITHM);
- return -1;
- }
-
- chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
-
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
- if (poolp == NULL)
- goto done;
-
- cipher_abilities = (int*)PORT_ArenaZAlloc (poolp,
- smime_symmetric_count * sizeof(int));
- if (cipher_abilities == NULL)
- goto done;
-
- cipher_votes = (int*)PORT_ArenaZAlloc (poolp,
- smime_symmetric_count * sizeof(int));
- if (cipher_votes == NULL)
- goto done;
-
- /*
- * XXX Should have a #define somewhere which specifies default
- * strong cipher. (Or better, a way to configure.)
- */
-
- /* Make triple-DES the strong cipher. */
- strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
-
- PORT_Assert (strong_mapi >= 0);
-
- for (rcount = 0; rcerts[rcount] != NULL; rcount++) {
- SECItem *profile;
- smime_capability **caps;
- int capi, pref;
- SECStatus dstat;
-
- pref = smime_symmetric_count;
- profile = CERT_FindSMimeProfile (rcerts[rcount]);
- if (profile != NULL && profile->data != NULL && profile->len > 0) {
- caps = NULL;
- dstat = SEC_QuickDERDecodeItem (poolp, &caps,
- smime_capabilities_template,
- profile);
- if (dstat == SECSuccess && caps != NULL) {
- for (capi = 0; caps[capi] != NULL; capi++) {
- smime_fill_capability (caps[capi]);
- mapi = smime_mapi_by_cipher (caps[capi]->cipher);
- if (mapi >= 0) {
- cipher_abilities[mapi]++;
- cipher_votes[mapi] += pref;
- --pref;
- }
- }
- }
- } else {
- SECKEYPublicKey *key;
- unsigned int pklen_bits;
-
- /*
- * XXX This is probably only good for RSA keys. What I would
- * really like is a function to just say; Is the public key in
- * this cert an export-length key? Then I would not have to
- * know things like the value 512, or the kind of key, or what
- * a subjectPublicKeyInfo is, etc.
- */
- key = CERT_ExtractPublicKey (rcerts[rcount]);
- if (key != NULL) {
- pklen_bits = SECKEY_PublicKeyStrength (key) * 8;
- SECKEY_DestroyPublicKey (key);
-
- if (pklen_bits > 512) {
- cipher_abilities[strong_mapi]++;
- cipher_votes[strong_mapi] += pref;
- }
- }
- }
- if (profile != NULL)
- SECITEM_FreeItem (profile, PR_TRUE);
- }
-
- max = 0;
- for (mapi = 0; mapi < smime_symmetric_count; mapi++) {
- if (cipher_abilities[mapi] != rcount)
- continue;
- if (! smime_cipher_allowed (smime_cipher_maps[mapi].cipher))
- continue;
- if (cipher_votes[mapi] > max) {
- chosen_cipher = smime_cipher_maps[mapi].cipher;
- max = cipher_votes[mapi];
- } /* XXX else if a tie, let scert break it? */
- }
-
-done:
- if (poolp != NULL)
- PORT_FreeArena (poolp, PR_FALSE);
-
- return chosen_cipher;
-}
-
-
-/*
- * XXX This is a hack for now to satisfy our current interface.
- * Eventually, with more parameters needing to be specified, just
- * looking up the keysize is not going to be sufficient.
- */
-static int
-smime_keysize_by_cipher (unsigned long which)
-{
- int keysize;
-
- switch (which) {
- case SMIME_RC2_CBC_40:
- keysize = 40;
- break;
- case SMIME_RC2_CBC_64:
- keysize = 64;
- break;
- case SMIME_RC2_CBC_128:
- keysize = 128;
- break;
-#ifdef SMIME_DOES_RC5
- case SMIME_RC5PAD_64_16_40:
- case SMIME_RC5PAD_64_16_64:
- case SMIME_RC5PAD_64_16_128:
- /* XXX See comment above; keysize is not enough... */
- PORT_Assert (0);
- PORT_SetError (SEC_ERROR_INVALID_ALGORITHM);
- keysize = -1;
- break;
-#endif
- case SMIME_DES_CBC_56:
- case SMIME_DES_EDE3_168:
- /*
- * These are special; since the key size is fixed, we actually
- * want to *avoid* specifying a key size.
- */
- keysize = 0;
- break;
- default:
- keysize = -1;
- break;
- }
-
- return keysize;
-}
-
-
-/*
- * Start an S/MIME encrypting context.
- *
- * "scert" is the cert for the sender. It will be checked for validity.
- * "rcerts" are the certs for the recipients. They will also be checked.
- *
- * "certdb" is the cert database to use for verifying the certs.
- * It can be NULL if a default database is available (like in the client).
- *
- * This function already does all of the stuff specific to S/MIME protocol
- * and local policy; the return value just needs to be passed to
- * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
- * and finally to SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-SEC_PKCS7ContentInfo *
-SECMIME_CreateEncrypted(CERTCertificate *scert,
- CERTCertificate **rcerts,
- CERTCertDBHandle *certdb,
- SECKEYGetPasswordKey pwfn,
- void *pwfn_arg)
-{
- SEC_PKCS7ContentInfo *cinfo;
- long cipher;
- SECOidTag encalg;
- int keysize;
- int mapi, rci;
-
- cipher = smime_choose_cipher (scert, rcerts);
- if (cipher < 0)
- return NULL;
-
- mapi = smime_mapi_by_cipher (cipher);
- if (mapi < 0)
- return NULL;
-
- /*
- * XXX This is stretching it -- CreateEnvelopedData should probably
- * take a cipher itself of some sort, because we cannot know what the
- * future will bring in terms of parameters for each type of algorithm.
- * For example, just an algorithm and keysize is *not* sufficient to
- * fully specify the usage of RC5 (which also needs to know rounds and
- * block size). Work this out into a better API!
- */
- encalg = smime_cipher_maps[mapi].algtag;
- keysize = smime_keysize_by_cipher (cipher);
- if (keysize < 0)
- return NULL;
-
- cinfo = SEC_PKCS7CreateEnvelopedData (scert, certUsageEmailRecipient,
- certdb, encalg, keysize,
- pwfn, pwfn_arg);
- if (cinfo == NULL)
- return NULL;
-
- for (rci = 0; rcerts[rci] != NULL; rci++) {
- if (rcerts[rci] == scert)
- continue;
- if (SEC_PKCS7AddRecipient (cinfo, rcerts[rci], certUsageEmailRecipient,
- NULL) != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
- }
-
- return cinfo;
-}
-
-
-static smime_capability **smime_capabilities;
-static SECItem *smime_encoded_caps;
-
-
-static SECStatus
-smime_init_caps (void)
-{
- smime_capability *cap;
- smime_cipher_map *map;
- SECOidData *oiddata;
- SECStatus rv;
- int i;
-
- if (smime_encoded_caps != NULL && (! smime_prefs_changed))
- return SECSuccess;
-
- if (smime_encoded_caps != NULL) {
- SECITEM_FreeItem (smime_encoded_caps, PR_TRUE);
- smime_encoded_caps = NULL;
- }
-
- if (smime_capabilities == NULL) {
- smime_capabilities = (smime_capability**)PORT_ZAlloc (
- (smime_symmetric_count + 1)
- * sizeof(smime_capability *));
- if (smime_capabilities == NULL)
- return SECFailure;
- }
-
- rv = SECFailure;
-
- /*
- The process of creating the encoded PKCS7 cipher capability list
- involves two basic steps:
-
- (a) Convert our internal representation of cipher preferences
- (smime_prefs) into an array containing cipher OIDs and
- parameter data (smime_capabilities). This step is
- performed here.
-
- (b) Encode, using ASN.1, the cipher information in
- smime_capabilities, leaving the encoded result in
- smime_encoded_caps.
-
- (In the process of performing (a), Lisa put in some optimizations
- which allow us to avoid needlessly re-populating elements in
- smime_capabilities as we walk through smime_prefs.)
- */
- for (i = 0; i < smime_current_pref_index; i++) {
- int mapi;
-
- /* Get the next cipher preference in smime_prefs. */
- mapi = smime_mapi_by_cipher (smime_prefs[i]);
- if (mapi < 0)
- break;
-
- /* Find the corresponding entry in the cipher map. */
- PORT_Assert (mapi < smime_symmetric_count);
- map = &(smime_cipher_maps[mapi]);
-
- /*
- * Convert the next preference found in smime_prefs into an
- * smime_capability.
- */
-
- cap = smime_capabilities[i];
- if (cap == NULL) {
- cap = (smime_capability*)PORT_ZAlloc (sizeof(smime_capability));
- if (cap == NULL)
- break;
- smime_capabilities[i] = cap;
- } else if (cap->cipher == smime_prefs[i]) {
- continue; /* no change to this one */
- }
-
- cap->capIDTag = map->algtag;
- oiddata = SECOID_FindOIDByTag (map->algtag);
- if (oiddata == NULL)
- break;
-
- if (cap->capabilityID.data != NULL) {
- SECITEM_FreeItem (&(cap->capabilityID), PR_FALSE);
- cap->capabilityID.data = NULL;
- cap->capabilityID.len = 0;
- }
-
- rv = SECITEM_CopyItem (NULL, &(cap->capabilityID), &(oiddata->oid));
- if (rv != SECSuccess)
- break;
-
- if (map->parms == NULL) {
- cap->parameters.data = NULL;
- cap->parameters.len = 0;
- } else {
- cap->parameters.data = map->parms->data;
- cap->parameters.len = map->parms->len;
- }
-
- cap->cipher = smime_prefs[i];
- }
-
- if (i != smime_current_pref_index)
- return rv;
-
- while (i < smime_symmetric_count) {
- cap = smime_capabilities[i];
- if (cap != NULL) {
- SECITEM_FreeItem (&(cap->capabilityID), PR_FALSE);
- PORT_Free (cap);
- }
- smime_capabilities[i] = NULL;
- i++;
- }
- smime_capabilities[i] = NULL;
-
- smime_encoded_caps = SEC_ASN1EncodeItem (NULL, NULL, &smime_capabilities,
- smime_capabilities_template);
- if (smime_encoded_caps == NULL)
- return SECFailure;
-
- return SECSuccess;
-}
-
-
-static SECStatus
-smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo)
-{
- PORT_Assert (smime_prefs_complete);
- if (! smime_prefs_complete)
- return SECFailure;
-
- /* For that matter, if capabilities haven't been initialized yet,
- do so now. */
- if (smime_encoded_caps == NULL || smime_prefs_changed) {
- SECStatus rv;
-
- rv = smime_init_caps();
- if (rv != SECSuccess)
- return rv;
-
- PORT_Assert (smime_encoded_caps != NULL);
- }
-
- return SEC_PKCS7AddSignedAttribute (cinfo, SEC_OID_PKCS9_SMIME_CAPABILITIES,
- smime_encoded_caps);
-}
-
-
-/*
- * Start an S/MIME signing context.
- *
- * "scert" is the cert that will be used to sign the data. It will be
- * checked for validity.
- *
- * "ecert" is the signer's encryption cert. If it is different from
- * scert, then it will be included in the signed message so that the
- * recipient can save it for future encryptions.
- *
- * "certdb" is the cert database to use for verifying the cert.
- * It can be NULL if a default database is available (like in the client).
- *
- * "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1).
- * XXX There should be SECMIME functions for hashing, or the hashing should
- * be built into this interface, which we would like because we would
- * support more smartcards that way, and then this argument should go away.)
- *
- * "digest" is the actual digest of the data. It must be provided in
- * the case of detached data or NULL if the content will be included.
- *
- * This function already does all of the stuff specific to S/MIME protocol
- * and local policy; the return value just needs to be passed to
- * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
- * and finally to SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-
-SEC_PKCS7ContentInfo *
-SECMIME_CreateSigned (CERTCertificate *scert,
- CERTCertificate *ecert,
- CERTCertDBHandle *certdb,
- SECOidTag digestalg,
- SECItem *digest,
- SECKEYGetPasswordKey pwfn,
- void *pwfn_arg)
-{
- SEC_PKCS7ContentInfo *cinfo;
- SECStatus rv;
-
- /* See note in header comment above about digestalg. */
- /* Doesn't explain this. PORT_Assert (digestalg == SEC_OID_SHA1); */
-
- cinfo = SEC_PKCS7CreateSignedData (scert, certUsageEmailSigner,
- certdb, digestalg, digest,
- pwfn, pwfn_arg);
- if (cinfo == NULL)
- return NULL;
-
- if (SEC_PKCS7IncludeCertChain (cinfo, NULL) != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
-
- /* if the encryption cert and the signing cert differ, then include
- * the encryption cert too.
- */
- /* it is ok to compare the pointers since we ref count, and the same
- * cert will always have the same pointer
- */
- if ( ( ecert != NULL ) && ( ecert != scert ) ) {
- rv = SEC_PKCS7AddCertificate(cinfo, ecert);
- if ( rv != SECSuccess ) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
- }
- /*
- * Add the signing time. But if it fails for some reason,
- * may as well not give up altogether -- just assert.
- */
- rv = SEC_PKCS7AddSigningTime (cinfo);
- PORT_Assert (rv == SECSuccess);
-
- /*
- * Add the email profile. Again, if it fails for some reason,
- * may as well not give up altogether -- just assert.
- */
- rv = smime_add_profile (ecert, cinfo);
- PORT_Assert (rv == SECSuccess);
-
- return cinfo;
-}
diff --git a/security/nss/lib/pkcs7/secmime.h b/security/nss/lib/pkcs7/secmime.h
deleted file mode 100644
index abd896915..000000000
--- a/security/nss/lib/pkcs7/secmime.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Header file for routines specific to S/MIME. Keep things that are pure
- * pkcs7 out of here; this is for S/MIME policy, S/MIME interoperability, etc.
- *
- * $Id$
- */
-
-#ifndef _SECMIME_H_
-#define _SECMIME_H_ 1
-
-#include "secpkcs7.h"
-
-
-/************************************************************************/
-SEC_BEGIN_PROTOS
-
-/*
- * Initialize the local recording of the user S/MIME cipher preferences.
- * This function is called once for each cipher, the order being
- * important (first call records greatest preference, and so on).
- * When finished, it is called with a "which" of CIPHER_FAMILID_MASK.
- * If the function is called again after that, it is assumed that
- * the preferences are being reset, and the old preferences are
- * discarded.
- *
- * XXX This is for a particular user, and right now the storage is
- * XXX local, static. The preference should be stored elsewhere to allow
- * XXX for multiple uses of one library? How does SSL handle this;
- * XXX it has something similar?
- *
- * - The "which" values are defined in ciferfam.h (the SMIME_* values,
- * for example SMIME_DES_CBC_56).
- * - If "on" is non-zero then the named cipher is enabled, otherwise
- * it is disabled. (It is not necessary to call the function for
- * ciphers that are disabled, however, as that is the default.)
- *
- * If the cipher preference is successfully recorded, SECSuccess
- * is returned. Otherwise SECFailure is returned. The only errors
- * are due to failure allocating memory or bad parameters/calls:
- * SEC_ERROR_XXX ("which" is not in the S/MIME cipher family)
- * SEC_ERROR_XXX (function is being called more times than there
- * are known/expected ciphers)
- */
-extern SECStatus SECMIME_EnableCipher(long which, int on);
-
-/*
- * Initialize the local recording of the S/MIME policy.
- * This function is called to enable/disable a particular cipher.
- * (S/MIME encryption or decryption using a particular cipher is only
- * allowed if that cipher is currently enabled.) At startup, all S/MIME
- * ciphers are disabled. From that point, this function can be called
- * to enable a cipher -- it is not necessary to call this to disable
- * a cipher unless that cipher was previously, explicitly enabled via
- * this function.
- *
- * XXX This is for a the current module, I think, so local, static storage
- * XXX is okay. Is that correct, or could multiple uses of the same
- * XXX library expect to operate under different policies?
- *
- * - The "which" values are defined in ciferfam.h (the SMIME_* values,
- * for example SMIME_DES_CBC_56).
- * - If "on" is non-zero then the named cipher is enabled, otherwise
- * it is disabled.
- *
- * If the cipher is successfully enabled/disabled, SECSuccess is
- * returned. Otherwise SECFailure is returned. The only errors
- * are due to bad parameters:
- * SEC_ERROR_XXX ("which" is not in the S/MIME cipher family)
- * SEC_ERROR_XXX ("which" exceeds expected maximum cipher; this is
- * really an internal error)
- */
-extern SECStatus SECMIME_SetPolicy(long which, int on);
-
-/*
- * Does the current policy allow S/MIME decryption of this particular
- * algorithm and keysize?
- */
-extern PRBool SECMIME_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key);
-
-/*
- * Does the current policy allow *any* S/MIME encryption (or decryption)?
- *
- * This tells whether or not *any* S/MIME encryption can be done,
- * according to policy. Callers may use this to do nicer user interface
- * (say, greying out a checkbox so a user does not even try to encrypt
- * a message when they are not allowed to) or for any reason they want
- * to check whether S/MIME encryption (or decryption, for that matter)
- * may be done.
- *
- * It takes no arguments. The return value is a simple boolean:
- * PR_TRUE means encryption (or decryption) is *possible*
- * (but may still fail due to other reasons, like because we cannot
- * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee)
- * PR_FALSE means encryption (or decryption) is not permitted
- *
- * There are no errors from this routine.
- */
-extern PRBool SECMIME_EncryptionPossible(void);
-
-/*
- * Start an S/MIME encrypting context.
- *
- * "scert" is the cert for the sender. It will be checked for validity.
- * "rcerts" are the certs for the recipients. They will also be checked.
- *
- * "certdb" is the cert database to use for verifying the certs.
- * It can be NULL if a default database is available (like in the client).
- *
- * This function already does all of the stuff specific to S/MIME protocol
- * and local policy; the return value just needs to be passed to
- * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
- * and finally to SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-extern SEC_PKCS7ContentInfo *SECMIME_CreateEncrypted(CERTCertificate *scert,
- CERTCertificate **rcerts,
- CERTCertDBHandle *certdb,
- SECKEYGetPasswordKey pwfn,
- void *pwfn_arg);
-
-/*
- * Start an S/MIME signing context.
- *
- * "scert" is the cert that will be used to sign the data. It will be
- * checked for validity.
- *
- * "certdb" is the cert database to use for verifying the cert.
- * It can be NULL if a default database is available (like in the client).
- *
- * "digestalg" names the digest algorithm. (It should be SEC_OID_SHA1;
- * XXX There should be SECMIME functions for hashing, or the hashing should
- * be built into this interface, which we would like because we would
- * support more smartcards that way, and then this argument should go away.)
- *
- * "digest" is the actual digest of the data. It must be provided in
- * the case of detached data or NULL if the content will be included.
- *
- * This function already does all of the stuff specific to S/MIME protocol
- * and local policy; the return value just needs to be passed to
- * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
- * and finally to SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-extern SEC_PKCS7ContentInfo *SECMIME_CreateSigned(CERTCertificate *scert,
- CERTCertificate *ecert,
- CERTCertDBHandle *certdb,
- SECOidTag digestalg,
- SECItem *digest,
- SECKEYGetPasswordKey pwfn,
- void *pwfn_arg);
-
-/************************************************************************/
-SEC_END_PROTOS
-
-#endif /* _SECMIME_H_ */
diff --git a/security/nss/lib/pkcs7/secpkcs7.h b/security/nss/lib/pkcs7/secpkcs7.h
deleted file mode 100644
index d76c10d65..000000000
--- a/security/nss/lib/pkcs7/secpkcs7.h
+++ /dev/null
@@ -1,594 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Interface to the PKCS7 implementation.
- *
- * $Id$
- */
-
-#ifndef _SECPKCS7_H_
-#define _SECPKCS7_H_
-
-#include "seccomon.h"
-
-#include "secoidt.h"
-#include "certt.h"
-#include "keyt.h"
-#include "hasht.h"
-#include "pkcs7t.h"
-
-extern const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[];
-
-/************************************************************************/
-SEC_BEGIN_PROTOS
-
-/************************************************************************
- * Miscellaneous
- ************************************************************************/
-
-/*
- * Returns the content type of the given contentInfo.
- */
-extern SECOidTag SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo);
-
-/*
- * Destroy a PKCS7 contentInfo and all of its sub-pieces.
- */
-extern void SEC_PKCS7DestroyContentInfo(SEC_PKCS7ContentInfo *contentInfo);
-
-/*
- * Copy a PKCS7 contentInfo. A Destroy is needed on *each* copy.
- */
-extern SEC_PKCS7ContentInfo *
-SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *contentInfo);
-
-/*
- * Return a pointer to the actual content. In the case of those types
- * which are encrypted, this returns the *plain* content.
- */
-extern SECItem *SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo);
-
-/************************************************************************
- * PKCS7 Decoding, Verification, etc..
- ************************************************************************/
-
-extern SEC_PKCS7DecoderContext *
-SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback callback,
- void *callback_arg,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg,
- SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb,
- void *decrypt_key_cb_arg,
- SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb);
-
-extern SECStatus
-SEC_PKCS7DecoderUpdate(SEC_PKCS7DecoderContext *p7dcx,
- const char *buf, unsigned long len);
-
-extern SEC_PKCS7ContentInfo *
-SEC_PKCS7DecoderFinish(SEC_PKCS7DecoderContext *p7dcx);
-
-
-/* Abort the underlying ASN.1 stream & set an error */
-void SEC_PKCS7DecoderAbort(SEC_PKCS7DecoderContext *p7dcx, int error);
-
-extern SEC_PKCS7ContentInfo *
-SEC_PKCS7DecodeItem(SECItem *p7item,
- SEC_PKCS7DecoderContentCallback cb, void *cb_arg,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg,
- SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb,
- void *decrypt_key_cb_arg,
- SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb);
-
-extern PRBool SEC_PKCS7ContainsCertsOrCrls(SEC_PKCS7ContentInfo *cinfo);
-
-/* checks to see if the contents of the content info is
- * empty. it so, PR_TRUE is returned. PR_FALSE, otherwise.
- *
- * minLen is used to specify a minimum size. if content size <= minLen,
- * content is assumed empty.
- */
-extern PRBool
-SEC_PKCS7IsContentEmpty(SEC_PKCS7ContentInfo *cinfo, unsigned int minLen);
-
-extern PRBool SEC_PKCS7ContentIsEncrypted(SEC_PKCS7ContentInfo *cinfo);
-
-/*
- * If the PKCS7 content has a signature (not just *could* have a signature)
- * return true; false otherwise. This can/should be called before calling
- * VerifySignature, which will always indicate failure if no signature is
- * present, but that does not mean there even was a signature!
- * Note that the content itself can be empty (detached content was sent
- * another way); it is the presence of the signature that matters.
- */
-extern PRBool SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo);
-
-/*
- * SEC_PKCS7VerifySignature
- * Look at a PKCS7 contentInfo and check if the signature is good.
- * The verification checks that the signing cert is valid and trusted
- * for the purpose specified by "certusage".
- *
- * In addition, if "keepcerts" is true, add any new certificates found
- * into our local database.
- */
-extern PRBool SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo,
- SECCertUsage certusage,
- PRBool keepcerts);
-
-/*
- * SEC_PKCS7VerifyDetachedSignature
- * Look at a PKCS7 contentInfo and check if the signature matches
- * a passed-in digest (calculated, supposedly, from detached contents).
- * The verification checks that the signing cert is valid and trusted
- * for the purpose specified by "certusage".
- *
- * In addition, if "keepcerts" is true, add any new certificates found
- * into our local database.
- */
-extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
- SECCertUsage certusage,
- const SECItem *detached_digest,
- HASH_HashType digest_type,
- PRBool keepcerts);
-
-/*
- * SEC_PKCS7GetSignerCommonName, SEC_PKCS7GetSignerEmailAddress
- * The passed-in contentInfo is espected to be Signed, and these
- * functions return the specified portion of the full signer name.
- *
- * Returns a pointer to allocated memory, which must be freed.
- * A NULL return value is an error.
- */
-extern char *SEC_PKCS7GetSignerCommonName(SEC_PKCS7ContentInfo *cinfo);
-extern char *SEC_PKCS7GetSignerEmailAddress(SEC_PKCS7ContentInfo *cinfo);
-
-/*
- * Return the the signing time, in UTCTime format, of a PKCS7 contentInfo.
- */
-extern SECItem *SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo);
-
-
-/************************************************************************
- * PKCS7 Creation and Encoding.
- ************************************************************************/
-
-/*
- * Start a PKCS7 signing context.
- *
- * "cert" is the cert that will be used to sign the data. It will be
- * checked for validity.
- *
- * "certusage" describes the signing usage (e.g. certUsageEmailSigner)
- * XXX Maybe SECCertUsage should be split so that our caller just says
- * "email" and *we* add the "signing" part -- otherwise our caller
- * could be lying about the usage; we do not want to allow encryption
- * certs for signing or vice versa.
- *
- * "certdb" is the cert database to use for verifying the cert.
- * It can be NULL if a default database is available (like in the client).
- *
- * "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1).
- *
- * "digest" is the actual digest of the data. It must be provided in
- * the case of detached data or NULL if the content will be included.
- *
- * The return value can be passed to functions which add things to
- * it like attributes, then eventually to SEC_PKCS7Encode() or to
- * SEC_PKCS7EncoderStart() to create the encoded data, and finally to
- * SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-extern SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateSignedData (CERTCertificate *cert,
- SECCertUsage certusage,
- CERTCertDBHandle *certdb,
- SECOidTag digestalg,
- SECItem *digest,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg);
-
-/*
- * Create a PKCS7 certs-only container.
- *
- * "cert" is the (first) cert that will be included.
- *
- * "include_chain" specifies whether the entire chain for "cert" should
- * be included.
- *
- * "certdb" is the cert database to use for finding the chain.
- * It can be NULL in when "include_chain" is false, or when meaning
- * use the default database.
- *
- * More certs and chains can be added via AddCertficate and AddCertChain.
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-extern SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateCertsOnly (CERTCertificate *cert,
- PRBool include_chain,
- CERTCertDBHandle *certdb);
-
-/*
- * Start a PKCS7 enveloping context.
- *
- * "cert" is the cert for the recipient. It will be checked for validity.
- *
- * "certusage" describes the encryption usage (e.g. certUsageEmailRecipient)
- * XXX Maybe SECCertUsage should be split so that our caller just says
- * "email" and *we* add the "recipient" part -- otherwise our caller
- * could be lying about the usage; we do not want to allow encryption
- * certs for signing or vice versa.
- *
- * "certdb" is the cert database to use for verifying the cert.
- * It can be NULL if a default database is available (like in the client).
- *
- * "encalg" specifies the bulk encryption algorithm to use (e.g. SEC_OID_RC2).
- *
- * "keysize" specifies the bulk encryption key size, in bits.
- *
- * The return value can be passed to functions which add things to
- * it like more recipients, then eventually to SEC_PKCS7Encode() or to
- * SEC_PKCS7EncoderStart() to create the encoded data, and finally to
- * SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-extern SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert,
- SECCertUsage certusage,
- CERTCertDBHandle *certdb,
- SECOidTag encalg,
- int keysize,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg);
-
-/*
- * XXX There will be a similar routine for creating signedAndEnvelopedData.
- * But its parameters will be different and I have no plans to implement
- * it any time soon because we have no current need for it.
- */
-
-/*
- * Create an empty PKCS7 data content info.
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-extern SEC_PKCS7ContentInfo *SEC_PKCS7CreateData (void);
-
-/*
- * Create an empty PKCS7 encrypted content info.
- *
- * "algorithm" specifies the bulk encryption algorithm to use.
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-extern SEC_PKCS7ContentInfo *
-SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize,
- SECKEYGetPasswordKey pwfn, void *pwfn_arg);
-
-/*
- * All of the following things return SECStatus to signal success or failure.
- * Failure should have a more specific error status available via
- * PORT_GetError()/XP_GetError().
- */
-
-/*
- * Add the specified attribute to the authenticated (i.e. signed) attributes
- * of "cinfo" -- "oidtag" describes the attribute and "value" is the
- * value to be associated with it. NOTE! "value" must already be encoded;
- * no interpretation of "oidtag" is done. Also, it is assumed that this
- * signedData has only one signer -- if we ever need to add attributes
- * when there is more than one signature, we need a way to specify *which*
- * signature should get the attribute.
- *
- * XXX Technically, a signed attribute can have multiple values; if/when
- * we ever need to support an attribute which takes multiple values, we
- * either need to change this interface or create an AddSignedAttributeValue
- * which can be called subsequently, and would then append a value.
- *
- * "cinfo" should be of type signedData (the only kind of pkcs7 data
- * that is allowed authenticated attributes); SECFailure will be returned
- * if it is not.
- */
-extern SECStatus SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo,
- SECOidTag oidtag,
- SECItem *value);
-
-/*
- * Add "cert" and its entire chain to the set of certs included in "cinfo".
- *
- * "certdb" is the cert database to use for finding the chain.
- * It can be NULL, meaning use the default database.
- *
- * "cinfo" should be of type signedData or signedAndEnvelopedData;
- * SECFailure will be returned if it is not.
- */
-extern SECStatus SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate *cert,
- CERTCertDBHandle *certdb);
-
-/*
- * Add "cert" to the set of certs included in "cinfo".
- *
- * "cinfo" should be of type signedData or signedAndEnvelopedData;
- * SECFailure will be returned if it is not.
- */
-extern SECStatus SEC_PKCS7AddCertificate (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate *cert);
-
-/*
- * Add another recipient to an encrypted message.
- *
- * "cinfo" should be of type envelopedData or signedAndEnvelopedData;
- * SECFailure will be returned if it is not.
- *
- * "cert" is the cert for the recipient. It will be checked for validity.
- *
- * "certusage" describes the encryption usage (e.g. certUsageEmailRecipient)
- * XXX Maybe SECCertUsage should be split so that our caller just says
- * "email" and *we* add the "recipient" part -- otherwise our caller
- * could be lying about the usage; we do not want to allow encryption
- * certs for signing or vice versa.
- *
- * "certdb" is the cert database to use for verifying the cert.
- * It can be NULL if a default database is available (like in the client).
- */
-extern SECStatus SEC_PKCS7AddRecipient (SEC_PKCS7ContentInfo *cinfo,
- CERTCertificate *cert,
- SECCertUsage certusage,
- CERTCertDBHandle *certdb);
-
-/*
- * Add the signing time to the authenticated (i.e. signed) attributes
- * of "cinfo". This is expected to be included in outgoing signed
- * messages for email (S/MIME) but is likely useful in other situations.
- *
- * This should only be added once; a second call will either do
- * nothing or replace an old signing time with a newer one.
- *
- * XXX This will probably just shove the current time into "cinfo"
- * but it will not actually get signed until the entire item is
- * processed for encoding. Is this (expected to be small) delay okay?
- *
- * "cinfo" should be of type signedData (the only kind of pkcs7 data
- * that is allowed authenticated attributes); SECFailure will be returned
- * if it is not.
- */
-extern SECStatus SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo);
-
-/*
- * Add the signer's symmetric capabilities to the authenticated
- * (i.e. signed) attributes of "cinfo". This is expected to be
- * included in outgoing signed messages for email (S/MIME).
- *
- * This can only be added once; a second call will return SECFailure.
- *
- * "cinfo" should be of type signedData or signedAndEnvelopedData;
- * SECFailure will be returned if it is not.
- */
-extern SECStatus SEC_PKCS7AddSymmetricCapabilities(SEC_PKCS7ContentInfo *cinfo);
-
-/*
- * Mark that the signer's certificate and its issuing chain should
- * be included in the encoded data. This is expected to be used
- * in outgoing signed messages for email (S/MIME).
- *
- * "certdb" is the cert database to use for finding the chain.
- * It can be NULL, meaning use the default database.
- *
- * "cinfo" should be of type signedData or signedAndEnvelopedData;
- * SECFailure will be returned if it is not.
- */
-extern SECStatus SEC_PKCS7IncludeCertChain (SEC_PKCS7ContentInfo *cinfo,
- CERTCertDBHandle *certdb);
-
-
-/*
- * Set the content; it will be included and also hashed and/or encrypted
- * as appropriate. This is for in-memory content (expected to be "small")
- * that will be included in the PKCS7 object. All others should stream the
- * content through when encoding (see SEC_PKCS7Encoder{Start,Update,Finish}).
- *
- * "buf" points to data of length "len"; it will be copied.
- */
-extern SECStatus SEC_PKCS7SetContent (SEC_PKCS7ContentInfo *cinfo,
- const char *buf, unsigned long len);
-
-/*
- * Encode a PKCS7 object, in one shot. All necessary components
- * of the object must already be specified. Either the data has
- * already been included (via SetContent), or the data is detached,
- * or there is no data at all (certs-only).
- *
- * "cinfo" specifies the object to be encoded.
- *
- * "outputfn" is where the encoded bytes will be passed.
- *
- * "outputarg" is an opaque argument to the above callback.
- *
- * "bulkkey" specifies the bulk encryption key to use. This argument
- * can be NULL if no encryption is being done, or if the bulk key should
- * be generated internally (usually the case for EnvelopedData but never
- * for EncryptedData, which *must* provide a bulk encryption key).
- *
- * "pwfn" is a callback for getting the password which protects the
- * private key of the signer. This argument can be NULL if it is known
- * that no signing is going to be done.
- *
- * "pwfnarg" is an opaque argument to the above callback.
- */
-extern SECStatus SEC_PKCS7Encode (SEC_PKCS7ContentInfo *cinfo,
- SEC_PKCS7EncoderOutputCallback outputfn,
- void *outputarg,
- PK11SymKey *bulkkey,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg);
-
-/*
- * Encode a PKCS7 object, in one shot. All necessary components
- * of the object must already be specified. Either the data has
- * already been included (via SetContent), or the data is detached,
- * or there is no data at all (certs-only). The output, rather than
- * being passed to an output function as is done above, is all put
- * into a SECItem.
- *
- * "pool" specifies a pool from which to allocate the result.
- * It can be NULL, in which case memory is allocated generically.
- *
- * "dest" specifies a SECItem in which to put the result data.
- * It can be NULL, in which case the entire item is allocated, too.
- *
- * "cinfo" specifies the object to be encoded.
- *
- * "bulkkey" specifies the bulk encryption key to use. This argument
- * can be NULL if no encryption is being done, or if the bulk key should
- * be generated internally (usually the case for EnvelopedData but never
- * for EncryptedData, which *must* provide a bulk encryption key).
- *
- * "pwfn" is a callback for getting the password which protects the
- * private key of the signer. This argument can be NULL if it is known
- * that no signing is going to be done.
- *
- * "pwfnarg" is an opaque argument to the above callback.
- */
-extern SECItem *SEC_PKCS7EncodeItem (PLArenaPool *pool,
- SECItem *dest,
- SEC_PKCS7ContentInfo *cinfo,
- PK11SymKey *bulkkey,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg);
-
-/*
- * For those who want to simply point to the pkcs7 contentInfo ASN.1
- * template, and *not* call the encoding functions directly, the
- * following function can be used -- after it is called, the entire
- * PKCS7 contentInfo is ready to be encoded.
- */
-extern SECStatus SEC_PKCS7PrepareForEncode (SEC_PKCS7ContentInfo *cinfo,
- PK11SymKey *bulkkey,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg);
-
-/*
- * Start the process of encoding a PKCS7 object. The first part of
- * the encoded object will be passed to the output function right away;
- * after that it is expected that SEC_PKCS7EncoderUpdate will be called,
- * streaming in the actual content that is getting included as well as
- * signed or encrypted (or both).
- *
- * "cinfo" specifies the object to be encoded.
- *
- * "outputfn" is where the encoded bytes will be passed.
- *
- * "outputarg" is an opaque argument to the above callback.
- *
- * "bulkkey" specifies the bulk encryption key to use. This argument
- * can be NULL if no encryption is being done, or if the bulk key should
- * be generated internally (usually the case for EnvelopedData but never
- * for EncryptedData, which *must* provide a bulk encryption key).
- *
- * Returns an object to be passed to EncoderUpdate and EncoderFinish.
- */
-extern SEC_PKCS7EncoderContext *
-SEC_PKCS7EncoderStart (SEC_PKCS7ContentInfo *cinfo,
- SEC_PKCS7EncoderOutputCallback outputfn,
- void *outputarg,
- PK11SymKey *bulkkey);
-
-/*
- * Encode more contents, hashing and/or encrypting along the way.
- */
-extern SECStatus SEC_PKCS7EncoderUpdate (SEC_PKCS7EncoderContext *p7ecx,
- const char *buf,
- unsigned long len);
-
-/*
- * No more contents; finish the signature creation, if appropriate,
- * and then the encoding.
- *
- * "pwfn" is a callback for getting the password which protects the
- * signer's private key. This argument can be NULL if it is known
- * that no signing is going to be done.
- *
- * "pwfnarg" is an opaque argument to the above callback.
- */
-extern SECStatus SEC_PKCS7EncoderFinish (SEC_PKCS7EncoderContext *p7ecx,
- SECKEYGetPasswordKey pwfn,
- void *pwfnarg);
-
-/* Abort the underlying ASN.1 stream & set an error */
-void SEC_PKCS7EncoderAbort(SEC_PKCS7EncoderContext *p7dcx, int error);
-
-/* retrieve the algorithm ID used to encrypt the content info
- * for encrypted and enveloped data. The SECAlgorithmID pointer
- * returned needs to be freed as it is a copy of the algorithm
- * id in the content info.
- */
-extern SECAlgorithmID *
-SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo);
-
-/* the content of an encrypted data content info is encrypted.
- * it is assumed that for encrypted data, that the data has already
- * been set and is in the "plainContent" field of the content info.
- *
- * cinfo is the content info to encrypt
- *
- * key is the key with which to perform the encryption. if the
- * algorithm is a password based encryption algorithm, the
- * key is actually a password which will be processed per
- * PKCS #5.
- *
- * in the event of an error, SECFailure is returned. SECSuccess
- * indicates a success.
- */
-extern SECStatus
-SEC_PKCS7EncryptContents(PLArenaPool *poolp,
- SEC_PKCS7ContentInfo *cinfo,
- SECItem *key,
- void *wincx);
-
-/* the content of an encrypted data content info is decrypted.
- * it is assumed that for encrypted data, that the data has already
- * been set and is in the "encContent" field of the content info.
- *
- * cinfo is the content info to decrypt
- *
- * key is the key with which to perform the decryption. if the
- * algorithm is a password based encryption algorithm, the
- * key is actually a password which will be processed per
- * PKCS #5.
- *
- * in the event of an error, SECFailure is returned. SECSuccess
- * indicates a success.
- */
-extern SECStatus
-SEC_PKCS7DecryptContents(PLArenaPool *poolp,
- SEC_PKCS7ContentInfo *cinfo,
- SECItem *key,
- void *wincx);
-
-/* retrieve the certificate list from the content info. the list
- * is a pointer to the list in the content info. this should not
- * be deleted or freed in any way short of calling
- * SEC_PKCS7DestroyContentInfo
- */
-extern SECItem **
-SEC_PKCS7GetCertificateList(SEC_PKCS7ContentInfo *cinfo);
-
-/* Returns the key length (in bits) of the algorithm used to encrypt
- this object. Returns 0 if it's not encrypted, or the key length is
- irrelevant. */
-extern int
-SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo);
-
-
-/************************************************************************/
-SEC_END_PROTOS
-
-#endif /* _SECPKCS7_H_ */
diff --git a/security/nss/lib/pki/Makefile b/security/nss/lib/pki/Makefile
deleted file mode 100644
index e0db1be1e..000000000
--- a/security/nss/lib/pki/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-include manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-export:: private_export
diff --git a/security/nss/lib/pki/asymmkey.c b/security/nss/lib/pki/asymmkey.c
deleted file mode 100644
index a88f7fd32..000000000
--- a/security/nss/lib/pki/asymmkey.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-extern const NSSError NSS_ERROR_NOT_FOUND;
-
-NSS_IMPLEMENT PRStatus
-NSSPrivateKey_Destroy (
- NSSPrivateKey *vk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSPrivateKey_DeleteStoredObject (
- NSSPrivateKey *vk,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRUint32
-NSSPrivateKey_GetSignatureLength (
- NSSPrivateKey *vk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return -1;
-}
-
-NSS_IMPLEMENT PRUint32
-NSSPrivateKey_GetPrivateModulusLength (
- NSSPrivateKey *vk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return -1;
-}
-
-NSS_IMPLEMENT PRBool
-NSSPrivateKey_IsStillPresent (
- NSSPrivateKey *vk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FALSE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSPrivateKey_Encode (
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *ap,
- NSSItem *passwordOpt, /* NULL will cause a callback; "" for no password */
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSTrustDomain *
-NSSPrivateKey_GetTrustDomain (
- NSSPrivateKey *vk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSToken *
-NSSPrivateKey_GetToken (
- NSSPrivateKey *vk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSlot *
-NSSPrivateKey_GetSlot (
- NSSPrivateKey *vk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSModule *
-NSSPrivateKey_GetModule (
- NSSPrivateKey *vk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSPrivateKey_Decrypt (
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSPrivateKey_Sign (
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSPrivateKey_SignRecover (
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSPrivateKey_UnwrapSymmetricKey (
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSPrivateKey_DeriveSymmetricKey (
- NSSPrivateKey *vk,
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt, /* zero for best allowed */
- NSSOperations operations,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSPublicKey *
-NSSPrivateKey_FindPublicKey (
- NSSPrivateKey *vk
- /* { don't need the callback here, right? } */
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-NSSPrivateKey_CreateCryptoContext (
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSPrivateKey_FindCertificates (
- NSSPrivateKey *vk,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSPrivateKey_FindBestCertificate (
- NSSPrivateKey *vk,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSPublicKey_Destroy (
- NSSPublicKey *bk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSPublicKey_DeleteStoredObject (
- NSSPublicKey *bk,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSPublicKey_Encode (
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *ap,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSTrustDomain *
-NSSPublicKey_GetTrustDomain (
- NSSPublicKey *bk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSToken *
-NSSPublicKey_GetToken (
- NSSPublicKey *bk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSlot *
-NSSPublicKey_GetSlot (
- NSSPublicKey *bk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSModule *
-NSSPublicKey_GetModule (
- NSSPublicKey *bk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSPublicKey_Encrypt (
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSPublicKey_Verify (
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSPublicKey_VerifyRecover (
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSPublicKey_WrapSymmetricKey (
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-NSSPublicKey_CreateCryptoContext (
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSPublicKey_FindCertificates (
- NSSPublicKey *bk,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSPublicKey_FindBestCertificate (
- NSSPublicKey *bk,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSPrivateKey *
-NSSPublicKey_FindPrivateKey (
- NSSPublicKey *bk,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
diff --git a/security/nss/lib/pki/certdecode.c b/security/nss/lib/pki/certdecode.c
deleted file mode 100644
index c270bd665..000000000
--- a/security/nss/lib/pki/certdecode.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef PKIT_H
-#include "pkit.h"
-#endif /* PKIT_H */
-
-#ifndef PKIM_H
-#include "pkim.h"
-#endif /* PKIM_H */
-
-/* This is defined in pki3hack.c */
-NSS_EXTERN nssDecodedCert *
-nssDecodedPKIXCertificate_Create (
- NSSArena *arenaOpt,
- NSSDER *encoding
-);
-
-NSS_IMPLEMENT PRStatus
-nssDecodedPKIXCertificate_Destroy (
- nssDecodedCert *dc
-);
-
-NSS_IMPLEMENT nssDecodedCert *
-nssDecodedCert_Create (
- NSSArena *arenaOpt,
- NSSDER *encoding,
- NSSCertificateType type
-)
-{
- nssDecodedCert *rvDC = NULL;
- switch(type) {
- case NSSCertificateType_PKIX:
- rvDC = nssDecodedPKIXCertificate_Create(arenaOpt, encoding);
- break;
- default:
-#if 0
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
-#endif
- return (nssDecodedCert *)NULL;
- }
- return rvDC;
-}
-
-NSS_IMPLEMENT PRStatus
-nssDecodedCert_Destroy (
- nssDecodedCert *dc
-)
-{
- if (!dc) {
- return PR_FAILURE;
- }
- switch(dc->type) {
- case NSSCertificateType_PKIX:
- return nssDecodedPKIXCertificate_Destroy(dc);
- default:
-#if 0
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
-#endif
- break;
- }
- return PR_FAILURE;
-}
-
diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c
deleted file mode 100644
index 276733a21..000000000
--- a/security/nss/lib/pki/certificate.c
+++ /dev/null
@@ -1,1176 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-#ifndef PKIT_H
-#include "pkit.h"
-#endif /* PKIT_H */
-
-#ifndef PKIM_H
-#include "pkim.h"
-#endif /* PKIM_H */
-
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
-#include "pkistore.h"
-
-#include "pki3hack.h"
-#include "pk11func.h"
-#include "hasht.h"
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-extern const NSSError NSS_ERROR_NOT_FOUND;
-
-/* Creates a certificate from a base object */
-NSS_IMPLEMENT NSSCertificate *
-nssCertificate_Create (
- nssPKIObject *object
-)
-{
- PRStatus status;
- NSSCertificate *rvCert;
- nssArenaMark * mark;
- NSSArena *arena = object->arena;
- PR_ASSERT(object->instances != NULL && object->numInstances > 0);
- PR_ASSERT(object->lockType == nssPKIMonitor);
- mark = nssArena_Mark(arena);
- rvCert = nss_ZNEW(arena, NSSCertificate);
- if (!rvCert) {
- return (NSSCertificate *)NULL;
- }
- rvCert->object = *object;
- /* XXX should choose instance based on some criteria */
- status = nssCryptokiCertificate_GetAttributes(object->instances[0],
- NULL, /* XXX sessionOpt */
- arena,
- &rvCert->type,
- &rvCert->id,
- &rvCert->encoding,
- &rvCert->issuer,
- &rvCert->serial,
- &rvCert->subject);
- if (status != PR_SUCCESS ||
- !rvCert->encoding.data ||
- !rvCert->encoding.size ||
- !rvCert->issuer.data ||
- !rvCert->issuer.size ||
- !rvCert->serial.data ||
- !rvCert->serial.size) {
- if (mark)
- nssArena_Release(arena, mark);
- return (NSSCertificate *)NULL;
- }
- if (mark)
- nssArena_Unmark(arena, mark);
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-nssCertificate_AddRef (
- NSSCertificate *c
-)
-{
- if (c) {
- nssPKIObject_AddRef(&c->object);
- }
- return c;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCertificate_Destroy (
- NSSCertificate *c
-)
-{
- nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
- nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
-
- if (c) {
- PRUint32 i;
- nssDecodedCert *dc = c->decoding;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSCryptoContext *cc = c->object.cryptoContext;
-
- PR_ASSERT(c->object.refCount > 0);
-
- /* --- LOCK storage --- */
- if (cc) {
- nssCertificateStore_Lock(cc->certStore, &lockTrace);
- } else {
- nssTrustDomain_LockCertCache(td);
- }
- if (PR_ATOMIC_DECREMENT(&c->object.refCount) == 0) {
- /* --- remove cert and UNLOCK storage --- */
- if (cc) {
- nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
- nssCertificateStore_Unlock(cc->certStore, &lockTrace,
- &unlockTrace);
- } else {
- nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
- nssTrustDomain_UnlockCertCache(td);
- }
- /* free cert data */
- for (i=0; i<c->object.numInstances; i++) {
- nssCryptokiObject_Destroy(c->object.instances[i]);
- }
- nssPKIObject_DestroyLock(&c->object);
- nssArena_Destroy(c->object.arena);
- nssDecodedCert_Destroy(dc);
- } else {
- /* --- UNLOCK storage --- */
- if (cc) {
- nssCertificateStore_Unlock(cc->certStore,
- &lockTrace,
- &unlockTrace);
- } else {
- nssTrustDomain_UnlockCertCache(td);
- }
- }
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCertificate_Destroy (
- NSSCertificate *c
-)
-{
- return nssCertificate_Destroy(c);
-}
-
-NSS_IMPLEMENT NSSDER *
-nssCertificate_GetEncoding (
- NSSCertificate *c
-)
-{
- if (c->encoding.size > 0 && c->encoding.data) {
- return &c->encoding;
- } else {
- return (NSSDER *)NULL;
- }
-}
-
-NSS_IMPLEMENT NSSDER *
-nssCertificate_GetIssuer (
- NSSCertificate *c
-)
-{
- if (c->issuer.size > 0 && c->issuer.data) {
- return &c->issuer;
- } else {
- return (NSSDER *)NULL;
- }
-}
-
-NSS_IMPLEMENT NSSDER *
-nssCertificate_GetSerialNumber (
- NSSCertificate *c
-)
-{
- if (c->serial.size > 0 && c->serial.data) {
- return &c->serial;
- } else {
- return (NSSDER *)NULL;
- }
-}
-
-NSS_IMPLEMENT NSSDER *
-nssCertificate_GetSubject (
- NSSCertificate *c
-)
-{
- if (c->subject.size > 0 && c->subject.data) {
- return &c->subject;
- } else {
- return (NSSDER *)NULL;
- }
-}
-
-/* Returns a copy, Caller must free using nss_ZFreeIf */
-NSS_IMPLEMENT NSSUTF8 *
-nssCertificate_GetNickname (
- NSSCertificate *c,
- NSSToken *tokenOpt
-)
-{
- return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
-}
-
-NSS_IMPLEMENT NSSASCII7 *
-nssCertificate_GetEmailAddress (
- NSSCertificate *c
-)
-{
- return c->email;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCertificate_DeleteStoredObject (
- NSSCertificate *c,
- NSSCallback *uhh
-)
-{
- return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCertificate_Validate (
- NSSCertificate *c,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt /* NULL for none */
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT void ** /* void *[] */
-NSSCertificate_ValidateCompletely (
- NSSCertificate *c,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt, /* NULL for none */
- void **rvOpt, /* NULL for allocate */
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt /* NULL for heap */
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCertificate_ValidateAndDiscoverUsagesAndPolicies (
- NSSCertificate *c,
- NSSTime **notBeforeOutOpt,
- NSSTime **notAfterOutOpt,
- void *allowedUsages,
- void *disallowedUsages,
- void *allowedPolicies,
- void *disallowedPolicies,
- /* more args.. work on this fgmr */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSDER *
-NSSCertificate_Encode (
- NSSCertificate *c,
- NSSDER *rvOpt,
- NSSArena *arenaOpt
-)
-{
- /* Item, DER, BER are all typedefs now... */
- return nssItem_Duplicate((NSSItem *)&c->encoding, arenaOpt, rvOpt);
-}
-
-NSS_IMPLEMENT nssDecodedCert *
-nssCertificate_GetDecoding (
- NSSCertificate *c
-)
-{
- nssDecodedCert* deco = NULL;
- if (c->type == NSSCertificateType_PKIX) {
- (void)STAN_GetCERTCertificate(c);
- }
- nssPKIObject_Lock(&c->object);
- if (!c->decoding) {
- deco = nssDecodedCert_Create(NULL, &c->encoding, c->type);
- PORT_Assert(!c->decoding);
- c->decoding = deco;
- } else {
- deco = c->decoding;
- }
- nssPKIObject_Unlock(&c->object);
- return deco;
-}
-
-static NSSCertificate **
-filter_subject_certs_for_id (
- NSSCertificate **subjectCerts,
- void *id
-)
-{
- NSSCertificate **si;
- nssDecodedCert *dcp;
- int nextOpenSlot = 0;
- int i;
- nssCertIDMatch matchLevel = nssCertIDMatch_Unknown;
- nssCertIDMatch match;
-
- /* walk the subject certs */
- for (si = subjectCerts; *si; si++) {
- dcp = nssCertificate_GetDecoding(*si);
- if (!dcp) {
- NSSCertificate_Destroy(*si);
- continue;
- }
- match = dcp->matchIdentifier(dcp, id);
- switch (match) {
- case nssCertIDMatch_Yes:
- if (matchLevel == nssCertIDMatch_Unknown) {
- /* we have non-definitive matches, forget them */
- for (i = 0; i < nextOpenSlot; i++) {
- NSSCertificate_Destroy(subjectCerts[i]);
- subjectCerts[i] = NULL;
- }
- nextOpenSlot = 0;
- /* only keep definitive matches from now on */
- matchLevel = nssCertIDMatch_Yes;
- }
- /* keep the cert */
- subjectCerts[nextOpenSlot++] = *si;
- break;
- case nssCertIDMatch_Unknown:
- if (matchLevel == nssCertIDMatch_Unknown) {
- /* only have non-definitive matches so far, keep it */
- subjectCerts[nextOpenSlot++] = *si;
- break;
- }
- /* else fall through, we have a definitive match already */
- case nssCertIDMatch_No:
- default:
- NSSCertificate_Destroy(*si);
- *si = NULL;
- }
- }
- subjectCerts[nextOpenSlot] = NULL;
- return subjectCerts;
-}
-
-static NSSCertificate **
-filter_certs_for_valid_issuers (
- NSSCertificate **certs
-)
-{
- NSSCertificate **cp;
- nssDecodedCert *dcp;
- int nextOpenSlot = 0;
-
- for (cp = certs; *cp; cp++) {
- dcp = nssCertificate_GetDecoding(*cp);
- if (dcp && dcp->isValidIssuer(dcp)) {
- certs[nextOpenSlot++] = *cp;
- } else {
- NSSCertificate_Destroy(*cp);
- }
- }
- certs[nextOpenSlot] = NULL;
- return certs;
-}
-
-static NSSCertificate *
-find_cert_issuer (
- NSSCertificate *c,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSTrustDomain *td,
- NSSCryptoContext *cc
-)
-{
- NSSArena *arena;
- NSSCertificate **certs = NULL;
- NSSCertificate **ccIssuers = NULL;
- NSSCertificate **tdIssuers = NULL;
- NSSCertificate *issuer = NULL;
-
- if (!cc)
- cc = c->object.cryptoContext;
- if (!td)
- td = NSSCertificate_GetTrustDomain(c);
- arena = nssArena_Create();
- if (!arena) {
- return (NSSCertificate *)NULL;
- }
- if (cc) {
- ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
- &c->issuer,
- NULL,
- 0,
- arena);
- }
- if (td)
- tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
- &c->issuer,
- NULL,
- 0,
- arena);
- certs = nssCertificateArray_Join(ccIssuers, tdIssuers);
- if (certs) {
- nssDecodedCert *dc = NULL;
- void *issuerID = NULL;
- dc = nssCertificate_GetDecoding(c);
- if (dc) {
- issuerID = dc->getIssuerIdentifier(dc);
- }
- /* XXX review based on CERT_FindCertIssuer
- * this function is not using the authCertIssuer field as a fallback
- * if authority key id does not exist
- */
- if (issuerID) {
- certs = filter_subject_certs_for_id(certs, issuerID);
- }
- certs = filter_certs_for_valid_issuers(certs);
- issuer = nssCertificateArray_FindBestCertificate(certs,
- timeOpt,
- usage,
- policiesOpt);
- nssCertificateArray_Destroy(certs);
- }
- nssArena_Destroy(arena);
- return issuer;
-}
-
-/* This function returns the built chain, as far as it gets,
-** even if/when it fails to find an issuer, and returns PR_FAILURE
-*/
-NSS_IMPLEMENT NSSCertificate **
-nssCertificate_BuildChain (
- NSSCertificate *c,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit,
- NSSArena *arenaOpt,
- PRStatus *statusOpt,
- NSSTrustDomain *td,
- NSSCryptoContext *cc
-)
-{
- NSSCertificate **rvChain = NULL;
- NSSUsage issuerUsage = *usage;
- nssPKIObjectCollection *collection = NULL;
- PRUint32 rvCount = 0;
- PRStatus st;
- PRStatus ret = PR_SUCCESS;
-
- if (!c || !cc ||
- (!td && (td = NSSCertificate_GetTrustDomain(c)) == NULL)) {
- goto loser;
- }
- /* bump the usage up to CA level */
- issuerUsage.nss3lookingForCA = PR_TRUE;
- collection = nssCertificateCollection_Create(td, NULL);
- if (!collection)
- goto loser;
- st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
- if (st != PR_SUCCESS)
- goto loser;
- for (rvCount = 1; (!rvLimit || rvCount < rvLimit); ++rvCount) {
- CERTCertificate *cCert = STAN_GetCERTCertificate(c);
- if (cCert->isRoot) {
- /* not including the issuer of the self-signed cert, which is,
- * of course, itself
- */
- break;
- }
- c = find_cert_issuer(c, timeOpt, &issuerUsage, policiesOpt, td, cc);
- if (!c) {
- ret = PR_FAILURE;
- break;
- }
- st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
- nssCertificate_Destroy(c); /* collection has it */
- if (st != PR_SUCCESS)
- goto loser;
- }
- rvChain = nssPKIObjectCollection_GetCertificates(collection,
- rvOpt,
- rvLimit,
- arenaOpt);
- if (rvChain) {
- nssPKIObjectCollection_Destroy(collection);
- if (statusOpt)
- *statusOpt = ret;
- if (ret != PR_SUCCESS)
- nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
- return rvChain;
- }
-
-loser:
- if (collection)
- nssPKIObjectCollection_Destroy(collection);
- if (statusOpt)
- *statusOpt = PR_FAILURE;
- nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
- return rvChain;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSCertificate_BuildChain (
- NSSCertificate *c,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt,
- PRStatus *statusOpt,
- NSSTrustDomain *td,
- NSSCryptoContext *cc
-)
-{
- return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
- rvOpt, rvLimit, arenaOpt, statusOpt,
- td, cc);
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-nssCertificate_GetCryptoContext (
- NSSCertificate *c
-)
-{
- return c->object.cryptoContext;
-}
-
-NSS_IMPLEMENT NSSTrustDomain *
-nssCertificate_GetTrustDomain (
- NSSCertificate *c
-)
-{
- return c->object.trustDomain;
-}
-
-NSS_IMPLEMENT NSSTrustDomain *
-NSSCertificate_GetTrustDomain (
- NSSCertificate *c
-)
-{
- return nssCertificate_GetTrustDomain(c);
-}
-
-NSS_IMPLEMENT NSSToken *
-NSSCertificate_GetToken (
- NSSCertificate *c,
- PRStatus *statusOpt
-)
-{
- return (NSSToken *)NULL;
-}
-
-NSS_IMPLEMENT NSSSlot *
-NSSCertificate_GetSlot (
- NSSCertificate *c,
- PRStatus *statusOpt
-)
-{
- return (NSSSlot *)NULL;
-}
-
-NSS_IMPLEMENT NSSModule *
-NSSCertificate_GetModule (
- NSSCertificate *c,
- PRStatus *statusOpt
-)
-{
- return (NSSModule *)NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCertificate_Encrypt (
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCertificate_Verify (
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCertificate_VerifyRecover (
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCertificate_WrapSymmetricKey (
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-NSSCertificate_CreateCryptoContext (
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSPublicKey *
-NSSCertificate_GetPublicKey (
- NSSCertificate *c
-)
-{
-#if 0
- CK_ATTRIBUTE pubktemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_ID, NULL, 0 },
- { CKA_SUBJECT, NULL, 0 }
- };
- PRStatus nssrv;
- CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
- NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
- if (c->id.size > 0) {
- /* CKA_ID */
- NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]);
- } else {
- /* failure, yes? */
- return (NSSPublicKey *)NULL;
- }
- if (c->subject.size > 0) {
- /* CKA_SUBJECT */
- NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
- } else {
- /* failure, yes? */
- return (NSSPublicKey *)NULL;
- }
- /* Try the cert's token first */
- if (c->token) {
- nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
- }
-#endif
- /* Try all other key tokens */
- return (NSSPublicKey *)NULL;
-}
-
-NSS_IMPLEMENT NSSPrivateKey *
-NSSCertificate_FindPrivateKey (
- NSSCertificate *c,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRBool
-NSSCertificate_IsPrivateKeyAvailable (
- NSSCertificate *c,
- NSSCallback *uhh,
- PRStatus *statusOpt
-)
-{
- PRBool isUser = PR_FALSE;
- nssCryptokiObject **ip;
- nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
- if (!instances) {
- return PR_FALSE;
- }
- for (ip = instances; *ip; ip++) {
- nssCryptokiObject *instance = *ip;
- if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) {
- isUser = PR_TRUE;
- }
- }
- nssCryptokiObjectArray_Destroy(instances);
- return isUser;
-}
-
-/* sort the subject cert list from newest to oldest */
-PRIntn
-nssCertificate_SubjectListSort (
- void *v1,
- void *v2
-)
-{
- NSSCertificate *c1 = (NSSCertificate *)v1;
- NSSCertificate *c2 = (NSSCertificate *)v2;
- nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
- nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
- if (!dc1) {
- return dc2 ? 1 : 0;
- } else if (!dc2) {
- return -1;
- } else {
- return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
- }
-}
-
-NSS_IMPLEMENT PRBool
-NSSUserCertificate_IsStillPresent (
- NSSUserCertificate *uc,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FALSE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSUserCertificate_Decrypt (
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSUserCertificate_Sign (
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSUserCertificate_SignRecover (
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSUserCertificate_UnwrapSymmetricKey (
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSUserCertificate_DeriveSymmetricKey (
- NSSUserCertificate *uc, /* provides private key */
- NSSCertificate *c, /* provides public key */
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt, /* zero for best allowed */
- NSSOperations operations,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT nssSMIMEProfile *
-nssSMIMEProfile_Create (
- NSSCertificate *cert,
- NSSItem *profileTime,
- NSSItem *profileData
-)
-{
- NSSArena *arena;
- nssSMIMEProfile *rvProfile;
- nssPKIObject *object;
- NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
- NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
- arena = nssArena_Create();
- if (!arena) {
- return NULL;
- }
- object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock);
- if (!object) {
- goto loser;
- }
- rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
- if (!rvProfile) {
- goto loser;
- }
- rvProfile->object = *object;
- rvProfile->certificate = cert;
- rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
- rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
- if (profileTime) {
- rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL);
- }
- if (profileData) {
- rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL);
- }
- return rvProfile;
-loser:
- if (object) nssPKIObject_Destroy(object);
- else if (arena) nssArena_Destroy(arena);
- return (nssSMIMEProfile *)NULL;
-}
-
-/* execute a callback function on all members of a cert list */
-NSS_EXTERN PRStatus
-nssCertificateList_DoCallback (
- nssList *certList,
- PRStatus (* callback)(NSSCertificate *c, void *arg),
- void *arg
-)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRStatus nssrv;
- certs = nssList_CreateIterator(certList);
- if (!certs) {
- return PR_FAILURE;
- }
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- nssrv = (*callback)(cert, arg);
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
- return PR_SUCCESS;
-}
-
-static PRStatus add_ref_callback(NSSCertificate *c, void *a)
-{
- nssCertificate_AddRef(c);
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT void
-nssCertificateList_AddReferences (
- nssList *certList
-)
-{
- (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL);
-}
-
-
-/*
- * Is this trust record safe to apply to all certs of the same issuer/SN
- * independent of the cert matching the hash. This is only true is the trust
- * is unknown or distrusted. In general this feature is only useful to
- * explicitly distrusting certs. It is not safe to use to trust certs, so
- * only allow unknown and untrusted trust types.
- */
-PRBool
-nssTrust_IsSafeToIgnoreCertHash(nssTrustLevel serverAuth,
- nssTrustLevel clientAuth, nssTrustLevel codeSigning,
- nssTrustLevel email, PRBool stepup)
-{
- /* step up is a trust type, if it's on, we must have a hash for the cert */
- if (stepup) {
- return PR_FALSE;
- }
- if ((serverAuth != nssTrustLevel_Unknown) &&
- (serverAuth != nssTrustLevel_NotTrusted)) {
- return PR_FALSE;
- }
- if ((clientAuth != nssTrustLevel_Unknown) &&
- (clientAuth != nssTrustLevel_NotTrusted)) {
- return PR_FALSE;
- }
- if ((codeSigning != nssTrustLevel_Unknown) &&
- (codeSigning != nssTrustLevel_NotTrusted)) {
- return PR_FALSE;
- }
- if ((email != nssTrustLevel_Unknown) &&
- (email != nssTrustLevel_NotTrusted)) {
- return PR_FALSE;
- }
- /* record only has Unknown and Untrusted entries, ok to accept without a
- * hash */
- return PR_TRUE;
-}
-
-NSS_IMPLEMENT NSSTrust *
-nssTrust_Create (
- nssPKIObject *object,
- NSSItem *certData
-)
-{
- PRStatus status;
- PRUint32 i;
- PRUint32 lastTrustOrder, myTrustOrder;
- unsigned char sha1_hashcmp[SHA1_LENGTH];
- unsigned char sha1_hashin[SHA1_LENGTH];
- NSSItem sha1_hash;
- NSSTrust *rvt;
- nssCryptokiObject *instance;
- nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
- SECStatus rv; /* Should be stan flavor */
- PRBool stepUp;
-
- lastTrustOrder = 1<<16; /* just make it big */
- PR_ASSERT(object->instances != NULL && object->numInstances > 0);
- rvt = nss_ZNEW(object->arena, NSSTrust);
- if (!rvt) {
- return (NSSTrust *)NULL;
- }
- rvt->object = *object;
-
- /* should be stan flavor of Hashbuf */
- rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size);
- if (rv != SECSuccess) {
- return (NSSTrust *)NULL;
- }
- sha1_hash.data = sha1_hashin;
- sha1_hash.size = sizeof (sha1_hashin);
- /* trust has to peek into the base object members */
- nssPKIObject_Lock(object);
- for (i=0; i<object->numInstances; i++) {
- instance = object->instances[i];
- myTrustOrder = nssToken_GetTrustOrder(instance->token);
- status = nssCryptokiTrust_GetAttributes(instance, NULL,
- &sha1_hash,
- &serverAuth,
- &clientAuth,
- &codeSigning,
- &emailProtection,
- &stepUp);
- if (status != PR_SUCCESS) {
- nssPKIObject_Unlock(object);
- return (NSSTrust *)NULL;
- }
- /* if no hash is specified, then trust applies to all certs with
- * this issuer/SN. NOTE: This is only true for entries that
- * have distrust and unknown record */
- if (!(
- /* we continue if there is no hash, and the trust type is
- * safe to accept without a hash ... or ... */
- ((sha1_hash.size == 0) &&
- nssTrust_IsSafeToIgnoreCertHash(serverAuth,clientAuth,
- codeSigning, emailProtection,stepUp))
- ||
- /* we have a hash of the correct size, and it matches */
- ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin,
- sha1_hashcmp,SHA1_LENGTH) == 0)) )) {
- nssPKIObject_Unlock(object);
- return (NSSTrust *)NULL;
- }
- if (rvt->serverAuth == nssTrustLevel_Unknown ||
- myTrustOrder < lastTrustOrder)
- {
- rvt->serverAuth = serverAuth;
- }
- if (rvt->clientAuth == nssTrustLevel_Unknown ||
- myTrustOrder < lastTrustOrder)
- {
- rvt->clientAuth = clientAuth;
- }
- if (rvt->emailProtection == nssTrustLevel_Unknown ||
- myTrustOrder < lastTrustOrder)
- {
- rvt->emailProtection = emailProtection;
- }
- if (rvt->codeSigning == nssTrustLevel_Unknown ||
- myTrustOrder < lastTrustOrder)
- {
- rvt->codeSigning = codeSigning;
- }
- rvt->stepUpApproved = stepUp;
- lastTrustOrder = myTrustOrder;
- }
- nssPKIObject_Unlock(object);
- return rvt;
-}
-
-NSS_IMPLEMENT NSSTrust *
-nssTrust_AddRef (
- NSSTrust *trust
-)
-{
- if (trust) {
- nssPKIObject_AddRef(&trust->object);
- }
- return trust;
-}
-
-NSS_IMPLEMENT PRStatus
-nssTrust_Destroy (
- NSSTrust *trust
-)
-{
- if (trust) {
- (void)nssPKIObject_Destroy(&trust->object);
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT nssSMIMEProfile *
-nssSMIMEProfile_AddRef (
- nssSMIMEProfile *profile
-)
-{
- if (profile) {
- nssPKIObject_AddRef(&profile->object);
- }
- return profile;
-}
-
-NSS_IMPLEMENT PRStatus
-nssSMIMEProfile_Destroy (
- nssSMIMEProfile *profile
-)
-{
- if (profile) {
- (void)nssPKIObject_Destroy(&profile->object);
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT NSSCRL *
-nssCRL_Create (
- nssPKIObject *object
-)
-{
- PRStatus status;
- NSSCRL *rvCRL;
- NSSArena *arena = object->arena;
- PR_ASSERT(object->instances != NULL && object->numInstances > 0);
- rvCRL = nss_ZNEW(arena, NSSCRL);
- if (!rvCRL) {
- return (NSSCRL *)NULL;
- }
- rvCRL->object = *object;
- /* XXX should choose instance based on some criteria */
- status = nssCryptokiCRL_GetAttributes(object->instances[0],
- NULL, /* XXX sessionOpt */
- arena,
- &rvCRL->encoding,
- NULL, /* subject */
- NULL, /* class */
- &rvCRL->url,
- &rvCRL->isKRL);
- if (status != PR_SUCCESS) {
- return (NSSCRL *)NULL;
- }
- return rvCRL;
-}
-
-NSS_IMPLEMENT NSSCRL *
-nssCRL_AddRef (
- NSSCRL *crl
-)
-{
- if (crl) {
- nssPKIObject_AddRef(&crl->object);
- }
- return crl;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCRL_Destroy (
- NSSCRL *crl
-)
-{
- if (crl) {
- (void)nssPKIObject_Destroy(&crl->object);
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCRL_DeleteStoredObject (
- NSSCRL *crl,
- NSSCallback *uhh
-)
-{
- return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
-}
-
-NSS_IMPLEMENT NSSDER *
-nssCRL_GetEncoding (
- NSSCRL *crl
-)
-{
- if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) {
- return &crl->encoding;
- } else {
- return (NSSDER *)NULL;
- }
-}
diff --git a/security/nss/lib/pki/config.mk b/security/nss/lib/pki/config.mk
deleted file mode 100644
index f2758950c..000000000
--- a/security/nss/lib/pki/config.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-ifdef BUILD_IDG
-DEFINES += -DNSSDEBUG
-endif
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
diff --git a/security/nss/lib/pki/cryptocontext.c b/security/nss/lib/pki/cryptocontext.c
deleted file mode 100644
index bcd184cf2..000000000
--- a/security/nss/lib/pki/cryptocontext.c
+++ /dev/null
@@ -1,986 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
-#ifndef PKIM_H
-#include "pkim.h"
-#endif /* PKIM_H */
-
-#ifndef PKISTORE_H
-#include "pkistore.h"
-#endif /* PKISTORE_H */
-
-extern const NSSError NSS_ERROR_NOT_FOUND;
-extern const NSSError NSS_ERROR_INVALID_ARGUMENT;
-
-NSS_IMPLEMENT NSSCryptoContext *
-nssCryptoContext_Create (
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-)
-{
- NSSArena *arena;
- NSSCryptoContext *rvCC;
- arena = NSSArena_Create();
- if (!arena) {
- return NULL;
- }
- rvCC = nss_ZNEW(arena, NSSCryptoContext);
- if (!rvCC) {
- return NULL;
- }
- rvCC->td = td;
- rvCC->arena = arena;
- rvCC->certStore = nssCertificateStore_Create(rvCC->arena);
- if (!rvCC->certStore) {
- nssArena_Destroy(arena);
- return NULL;
- }
-
- return rvCC;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_Destroy (
- NSSCryptoContext *cc
-)
-{
- PRStatus status = PR_SUCCESS;
- PORT_Assert(cc->certStore);
- if (cc->certStore) {
- status = nssCertificateStore_Destroy(cc->certStore);
- if (status == PR_FAILURE) {
- return status;
- }
- } else {
- status = PR_FAILURE;
- }
- nssArena_Destroy(cc->arena);
- return status;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_SetDefaultCallback (
- NSSCryptoContext *td,
- NSSCallback *newCallback,
- NSSCallback **oldCallbackOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSCallback *
-NSSCryptoContext_GetDefaultCallback (
- NSSCryptoContext *td,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSTrustDomain *
-NSSCryptoContext_GetTrustDomain (
- NSSCryptoContext *td
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindOrImportCertificate (
- NSSCryptoContext *cc,
- NSSCertificate *c
-)
-{
- NSSCertificate *rvCert = NULL;
-
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return rvCert;
- }
- rvCert = nssCertificateStore_FindOrAdd(cc->certStore, c);
- if (rvCert == c && c->object.cryptoContext != cc) {
- PORT_Assert(!c->object.cryptoContext);
- c->object.cryptoContext = cc;
- }
- if (rvCert) {
- /* an NSSCertificate cannot be part of two crypto contexts
- ** simultaneously. If this assertion fails, then there is
- ** a serious Stan design flaw.
- */
- PORT_Assert(cc == c->object.cryptoContext);
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_ImportPKIXCertificate (
- NSSCryptoContext *cc,
- struct NSSPKIXCertificateStr *pc
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_ImportEncodedCertificate (
- NSSCryptoContext *cc,
- NSSBER *ber
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_ImportEncodedPKIXCertificateChain (
- NSSCryptoContext *cc,
- NSSBER *ber
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCryptoContext_ImportTrust (
- NSSCryptoContext *cc,
- NSSTrust *trust
-)
-{
- PRStatus nssrv;
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return PR_FAILURE;
- }
- nssrv = nssCertificateStore_AddTrust(cc->certStore, trust);
-#if 0
- if (nssrv == PR_SUCCESS) {
- trust->object.cryptoContext = cc;
- }
-#endif
- return nssrv;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCryptoContext_ImportSMIMEProfile (
- NSSCryptoContext *cc,
- nssSMIMEProfile *profile
-)
-{
- PRStatus nssrv;
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return PR_FAILURE;
- }
- nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile);
-#if 0
- if (nssrv == PR_SUCCESS) {
- profile->object.cryptoContext = cc;
- }
-#endif
- return nssrv;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestCertificateByNickname (
- NSSCryptoContext *cc,
- const NSSUTF8 *name,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt /* NULL for none */
-)
-{
- NSSCertificate **certs;
- NSSCertificate *rvCert = NULL;
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- certs = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
- name,
- NULL, 0, NULL);
- if (certs) {
- rvCert = nssCertificateArray_FindBestCertificate(certs,
- timeOpt,
- usage,
- policiesOpt);
- nssCertificateArray_Destroy(certs);
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSCryptoContext_FindCertificatesByNickname (
- NSSCryptoContext *cc,
- NSSUTF8 *name,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- NSSCertificate **rvCerts;
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- rvCerts = nssCertificateStore_FindCertificatesByNickname(cc->certStore,
- name,
- rvOpt,
- maximumOpt,
- arenaOpt);
- return rvCerts;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindCertificateByIssuerAndSerialNumber (
- NSSCryptoContext *cc,
- NSSDER *issuer,
- NSSDER *serialNumber
-)
-{
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- return nssCertificateStore_FindCertificateByIssuerAndSerialNumber(
- cc->certStore,
- issuer,
- serialNumber);
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestCertificateBySubject (
- NSSCryptoContext *cc,
- NSSDER *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- NSSCertificate **certs;
- NSSCertificate *rvCert = NULL;
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- certs = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
- subject,
- NULL, 0, NULL);
- if (certs) {
- rvCert = nssCertificateArray_FindBestCertificate(certs,
- timeOpt,
- usage,
- policiesOpt);
- nssCertificateArray_Destroy(certs);
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-nssCryptoContext_FindCertificatesBySubject (
- NSSCryptoContext *cc,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- NSSCertificate **rvCerts;
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- rvCerts = nssCertificateStore_FindCertificatesBySubject(cc->certStore,
- subject,
- rvOpt,
- maximumOpt,
- arenaOpt);
- return rvCerts;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSCryptoContext_FindCertificatesBySubject (
- NSSCryptoContext *cc,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- return nssCryptoContext_FindCertificatesBySubject(cc, subject,
- rvOpt, maximumOpt,
- arenaOpt);
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestCertificateByNameComponents (
- NSSCryptoContext *cc,
- NSSUTF8 *nameComponents,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSCryptoContext_FindCertificatesByNameComponents (
- NSSCryptoContext *cc,
- NSSUTF8 *nameComponents,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindCertificateByEncodedCertificate (
- NSSCryptoContext *cc,
- NSSBER *encodedCertificate
-)
-{
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- return nssCertificateStore_FindCertificateByEncodedCertificate(
- cc->certStore,
- encodedCertificate);
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestCertificateByEmail (
- NSSCryptoContext *cc,
- NSSASCII7 *email,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- NSSCertificate **certs;
- NSSCertificate *rvCert = NULL;
-
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- certs = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
- email,
- NULL, 0, NULL);
- if (certs) {
- rvCert = nssCertificateArray_FindBestCertificate(certs,
- timeOpt,
- usage,
- policiesOpt);
- nssCertificateArray_Destroy(certs);
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSCryptoContext_FindCertificatesByEmail (
- NSSCryptoContext *cc,
- NSSASCII7 *email,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- NSSCertificate **rvCerts;
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- rvCerts = nssCertificateStore_FindCertificatesByEmail(cc->certStore,
- email,
- rvOpt,
- maximumOpt,
- arenaOpt);
- return rvCerts;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindCertificateByOCSPHash (
- NSSCryptoContext *cc,
- NSSItem *hash
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestUserCertificate (
- NSSCryptoContext *cc,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSCryptoContext_FindUserCertificates (
- NSSCryptoContext *cc,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestUserCertificateForSSLClientAuth (
- NSSCryptoContext *cc,
- NSSUTF8 *sslHostOpt,
- NSSDER *rootCAsOpt[], /* null pointer for none */
- PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSCryptoContext_FindUserCertificatesForSSLClientAuth (
- NSSCryptoContext *cc,
- NSSUTF8 *sslHostOpt,
- NSSDER *rootCAsOpt[], /* null pointer for none */
- PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindBestUserCertificateForEmailSigning (
- NSSCryptoContext *cc,
- NSSASCII7 *signerOpt,
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSCryptoContext_FindUserCertificatesForEmailSigning (
- NSSCryptoContext *cc,
- NSSASCII7 *signerOpt, /* fgmr or a more general name? */
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSTrust *
-nssCryptoContext_FindTrustForCertificate (
- NSSCryptoContext *cc,
- NSSCertificate *cert
-)
-{
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- return nssCertificateStore_FindTrustForCertificate(cc->certStore, cert);
-}
-
-NSS_IMPLEMENT nssSMIMEProfile *
-nssCryptoContext_FindSMIMEProfileForCertificate (
- NSSCryptoContext *cc,
- NSSCertificate *cert
-)
-{
- PORT_Assert(cc->certStore);
- if (!cc->certStore) {
- return NULL;
- }
- return nssCertificateStore_FindSMIMEProfileForCertificate(cc->certStore,
- cert);
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_GenerateKeyPair (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *ap,
- NSSPrivateKey **pvkOpt,
- NSSPublicKey **pbkOpt,
- PRBool privateKeyIsSensitive,
- NSSToken *destination,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSCryptoContext_GenerateSymmetricKey (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *ap,
- PRUint32 keysize,
- NSSToken *destination,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSCryptoContext_GenerateSymmetricKeyFromPassword (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *ap,
- NSSUTF8 *passwordOpt, /* if null, prompt */
- NSSToken *destinationOpt,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID (
- NSSCryptoContext *cc,
- NSSOID *algorithm,
- NSSItem *keyID,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-struct token_session_str {
- NSSToken *token;
- nssSession *session;
-};
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_Decrypt (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_BeginDecrypt (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_ContinueDecrypt (
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_FinishDecrypt (
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_Sign (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_BeginSign (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_ContinueSign (
- NSSCryptoContext *cc,
- NSSItem *data
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_FinishSign (
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_SignRecover (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_BeginSignRecover (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_ContinueSignRecover (
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_FinishSignRecover (
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSCryptoContext_UnwrapSymmetricKey (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSCryptoContext_DeriveSymmetricKey (
- NSSCryptoContext *cc,
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt, /* zero for best allowed */
- NSSOperations operations,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_Encrypt (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_BeginEncrypt (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_ContinueEncrypt (
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_FinishEncrypt (
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_Verify (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_BeginVerify (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_ContinueVerify (
- NSSCryptoContext *cc,
- NSSItem *data
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_FinishVerify (
- NSSCryptoContext *cc
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_VerifyRecover (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_BeginVerifyRecover (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_ContinueVerifyRecover (
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_FinishVerifyRecover (
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_WrapSymmetricKey (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_Digest (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- return nssToken_Digest(cc->token, cc->session, apOpt,
- data, rvOpt, arenaOpt);
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_BeginDigest (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-)
-{
- return nssToken_BeginDigest(cc->token, cc->session, apOpt);
-}
-
-NSS_IMPLEMENT PRStatus
-NSSCryptoContext_ContinueDigest (
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *item
-)
-{
- /*
- NSSAlgorithmAndParameters *ap;
- ap = (apOpt) ? apOpt : cc->ap;
- */
- /* why apOpt? can't change it at this point... */
- return nssToken_ContinueDigest(cc->token, cc->session, item);
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSCryptoContext_FinishDigest (
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- return nssToken_FinishDigest(cc->token, cc->session, rvOpt, arenaOpt);
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-NSSCryptoContext_Clone (
- NSSCryptoContext *cc
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
diff --git a/security/nss/lib/pki/doc/standiag.png b/security/nss/lib/pki/doc/standiag.png
deleted file mode 100644
index fe1aca389..000000000
--- a/security/nss/lib/pki/doc/standiag.png
+++ /dev/null
Binary files differ
diff --git a/security/nss/lib/pki/doc/standoc.html b/security/nss/lib/pki/doc/standoc.html
deleted file mode 100644
index 2e110fcbe..000000000
--- a/security/nss/lib/pki/doc/standoc.html
+++ /dev/null
@@ -1,442 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-
- <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
- <title>Stan Design - Work In Progress</title>
-</head>
- <body>
- <br>
- This is a working document for progress on Stan design/development.<br>
- <br>
- Current <a href="#build">build</a>
- and <a href="#test">test</a>
- instructions.<br>
- <br>
- The current set of Stan libraries.<br>
- <a href="#asn1">asn1</a>
- <br>
- <a href="#base">base</a>
- <br>
- <a href="#ckfw">ckfw</a>
- <br>
- <a href="#dev">dev</a>
- <br>
- <a href="#pki">pki</a>
- <br>
- <a href="#pki1">pki1</a>
- <br>
- <a href="#pkix">pkix</a>
- <br>
- <br>
- "Public" types below (those available to consumers of
- NSS) begin with "NSS". &nbsp;"Protected" types (those only available
- within NSS) begin with "nss".<br>
- <br>
- Open issues appears as numbered indents.<br>
- <br>
- <br>
-
-<hr width="100%" size="2" align="Left"><br>
-
-<h3><a name="asn1"></a>
- <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/asn1/">
- ASN.1</a>
- </h3>
- ASN.1 encoder/decoder wrapping around the current
- ASN.1 implementation.<br>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSASN1EncodingType"> NSSASN1EncodingType</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1Item">nssASN1Item</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1Template">nssASN1Template</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1ChooseTemplateFunction">
- nssASN1ChooseTemplateFunction</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1Encoder">nssASN1Encoder</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1Decoder">nssASN1Decoder</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1EncodingPart"> nssASN1EncodingPart</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1NotifyFunction">
- nssASN1NotifyFunction</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1EncoderWriteFunction">
- nssASN1EncoderWriteFunction</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssASN1DecoderFilterFunction">
- nssASN1DecoderFilterFunction</a>
- <br>
- <br>
-
-<hr width="100%" size="2" align="Left">
-<h3><a name="base"></a>
- <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/base/">
- Base</a>
- </h3>
- Set of base utilities for Stan implementation.
-&nbsp;These are all fairly straightforward, except for nssPointerTracker.<br>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSError">NSSError</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSArena">NSSArena</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSItem">NSSItem</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSBER">NSSBER</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSDER">NSSDER</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSBitString">NSSBitString</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSUTF8">NSSUTF8</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSASCII7">NSSASCII7</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssArenaMark">nssArenaMark</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssPointerTracker">nssPointerTracker</a>
- <br>
- This is intended for debug builds only.<br>
-
-<ol>
- <li>Ignored for now.<br>
- </li>
-
-</ol>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssStringType">nssStringType</a>
- <br>
- <br>
- Suggested additions:<br>
-
-<ol>
- <li>nssList - A list that optionally uses a lock. &nbsp;This list would
- manage the currently loaded modules in a trust domain, etc.</li>
-
- <ul>
- <li>SECMODListLock kept track of the number of waiting threads. &nbsp;Will
- this be needed in the trust domain?</li>
-
- </ul>
-
-</ol>
- <br>
-
-<hr width="100%" size="2" align="Left">
-<h3><a name="ckfw"></a>
- <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/">
- CKFW</a>
- </h3>
- The cryptoki framework, used for building cryptoki tokens.
- &nbsp;This needs to be described in a separate document showing how
- to set up a token using CKFW. &nbsp;This code only relates to tokens,
- so it is not relevant here.<br>
- <br>
- <br>
-
-<hr width="100%" size="2" align="Left">
-<h3><a name="dev"></a>
- <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/dev/">
- Device</a>
- </h3>
- Defines cryptoki devices used in NSS. &nbsp;This
- is not part of the exposed API. &nbsp;It is a low-level API allowing
-NSS to manage cryptoki devices.<br>
- <br>
- The relationship is like this:<br>
- <br>
- libpki --&gt; libdev --&gt; cryptoki<br>
- <br>
- As an example,<br>
- <br>
- NSSTrustDomain_FindCertificate --&gt; NSSToken_FindCertificate --&gt;
- C_FindObjects<br>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSModule">NSSModule</a>
- <br>
- Replaces the SECMOD API. &nbsp;The module manages a
-PRLibrary that holds a cryptoki implementation via a number of slots.
-&nbsp;The API should provide the ability to Load and Unload a module,
-Login and Logout to the module (through its slots), and to locate a
-particular slot/token.<br>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSSlot">NSSSlot</a>
- <br>
- This and NSSToken combine to replace the PK11 API parts
- that relate to slot and token management. &nbsp;The slot API should
- provide the ability to Login/Logout to a slot, check the login status,
- determine basic configuration information about the slot, and modify
- the password settings.<br>
-
-<ol>
- <li>Should slots also maintain a default session? &nbsp;This session would
- be used for slot management calls (sections 9.5 and9.6 of PKCS#11). &nbsp;Or
- is the token session sufficient (this would not work if C_GetTokenInfo and
- C_InitToken need to be wrapped in a threadsafe session).<br>
- </li>
-
-</ol>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSToken">NSSToken</a>
- <br>
- Fills in the gaps left by NSSSlot. &nbsp;Much of the
-cryptoki API is directed towards slots. &nbsp;However, some functionality
- clearly belongs with a token type. &nbsp;For example, a certificate
- lives on a token, not a slot, so one would expect a function NSSToken_FindCertificate.
- &nbsp;Thus functions that deal with importing/exporting an object
-and performing actual cryptographic operations belong here.<br>
-
-<ol>
- <li>The distinction between a slot and a token is not clear. &nbsp;Most
- functions take a slotID as an argument, even though it is obvious that
- the event is intended to occur on a token. &nbsp;That leaves various
- possibilities:</li>
-
- <ol>
- <li>Implement the API entirely as NSSToken. &nbsp;If the token is not
- present, some calls will simply fail.</li>
- <li>Divide the API between NSSToken and NSSSlot, as described above.
-&nbsp;NSSSlot would handle cryptoki calls specified as "slot management",
- while NSSToken handles actual token operations.</li>
- <li>Others?</li>
-
- </ol>
- <li>Session management. &nbsp;Tokens needs a threadsafe session handle
- to perform operations. &nbsp;CryptoContexts are meant to provide such sessions,
- but other objects will need access to token functions as well (examples:
-the TrustDomain_Find functions, _Login, _Logout, and others that do not exist
- such as NSSToken_ChangePassword). &nbsp;For those functions, the token could
- maintain a default session. &nbsp;Thus all NSSToken API functions would take
- sessionOpt as an argument. &nbsp;If the caller is going to provide a session,
- it sends an NSSSession there, otherwise it sends NULL and the default session
- is utilized.<br>
- </li>
-
-</ol>
- Proposed:<br>
- NSSSession<br>
- Wraps a Cryptoki session. &nbsp;Created from a slot. &nbsp;Used to manage
- sessions for crypto contexts. &nbsp;Has a lock field, which locks the session
- if the slot is not threadsafe.<br>
- <br>
-
-<hr width="100%" size="2" align="Left"><br>
-
-<h3><a name="pki"></a>
- <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pki/">
- PKI</a>
- </h3>
- The NSS PKI library.<br>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSCertificate">NSS</a>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSCertificate">Certificate</a>
- <br>
-
-<ol>
- <li>The API leaves open the possibility of NSSCertificate meaning various
- certificate types, not just X.509. &nbsp;The way to keep open this possibility
- is to keep only generally useful information in the NSSCertificate type.
-&nbsp;Examples would be the certificate encoding, label, trust (obtained
- from cryptoki calls), an email address, etc. &nbsp;Some type of generic
-reference should be kept to the decoded certificate, which would then be
-accessed by a type-specific API (e.g., NSSX509_GetSubjectName).</li>
-
-</ol>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSUserCertificate">NSSUserCertificate</a>
- <br>
-
-<ol>
- <li>Should this be a typedef of NSSCertificate?&nbsp; This implies that
- any function that requires an NSSUserCertificate would fail when called
- with a certificate lacking a private key. </li>
-
-</ol>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSPrivateKey">NSSPrivateKey</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSPublicKey">NSSPublicKey</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSSymmetricKey">NSSSymmetricKey</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSTrustDomain">NSSTrustDomain</a>
- <br>
- A trust domain is "the field in which certificates may
- be validated." &nbsp;It is a collection of modules capable of performing
- cryptographic operations and storing certs and keys. &nbsp;This collection
- is managed by NSS in a manner opaque to the consumer. &nbsp;The slots
- will have various orderings determining which has preference for a
-given operation. &nbsp;For example, the trust domain may order the storage
- of user certificates one way, and the storage of email certificates in
- another way [is that a good example?].<br>
- <br>
-
-<ol>
- <li> How will ordering work? &nbsp;We already have the suggestion
- that there be two kinds of ordering: storage and search. &nbsp;How
-will they be constructed/managed? &nbsp;Do we want to expose access
-to a token that overrides this ordering (i.e., the download of updated
-root certs may need to override storage order)</li>
- <li>How are certs cached? &nbsp;Nelson wonders what it means to Stan
- when a cert does not live on a token yet. &nbsp;Bob, Terry, and I discussed
- this. &nbsp;My conclusion is that there should be a type, separate
-from NSSCertificate, that holds the decoded cert parts (e.g., NSSX509Certificate,
- or to avoid confusion, NSSX509DecodedParts). &nbsp;NSSCertificate would
- keep a handle to this type, so that it only needs to decode the cert
-once. &nbsp;The NSSTrustDomain would keep a hash table of cached certs,
-some of which may not live on a token yet (i.e., they are only NSSX509DecodedParts).
- &nbsp;This cache could be accessed in the same way the temp db was,
-and when the cert is ready to be moved onto a token a call to NSSTrustDomain_ImportCertificate
- is made. &nbsp;Note that this is essentially the same as CERT_TempCertToPerm.</li>
-
- <ul>
- <li>The hashtable in lib/base (copied from ckfw/hash.c) uses the identity
-hash. &nbsp;Therefore, in a hash of certificates, the key is the certificate
-pointer itself. &nbsp;One possibility is to store the decoded cert (NSSX509DecodedParts
-above) as the value in the {key, value} pair. &nbsp;When a cert is decoded,
-the cert pointer and decoding pointer are added to the hash. &nbsp;Subsequent
-lookups have access to one or both of these pointers. &nbsp;This keeps NSSCertificate
-separate from its decoding, while providing a way to locate it.</li>
-
- </ul>
- <li>The API is designed to keep token details hidden from the user. &nbsp;However,
- it has already been realized that PSM and CMS may need special access to
-tokens. &nbsp;Is this part of the TrustDomain API, or should PSM and CMS
-be allowed to use "friend" headers from the Token API?</li>
- <li>Do we want to allow traversal via NSSTrustDomain_TraverseXXXX?<br>
- </li>
-
-</ol>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSCryptoContext"><br>
- NSSCryptoContext</a>
- <br>
- Analgous to a Cryptoki session. &nbsp;Manages session objects only.<br>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSTime">NSSTime</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSUsage">NSSUsage</a>
- <br>
-
-<ol>
- <li> See Fred's <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pki/nsspkit.h#187">
- comments</a>
- .</li>
-
-</ol>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSPolicies">NSSPolicies</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSAlgorithmAndParameters">
- NSSAlgorithmAndParameters</a>
- <br>
-
-<ol>
- <li> Again, Fred's <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pki/nsspkit.h#215">
- comments</a>
- . &nbsp;The old NSS code had various types related to algorithms
- running around in it. &nbsp;We had SECOidTag, SECAlgorithmID, SECItem's
- for parameters, CK_MECHANISM for cryptoki, etc. &nbsp;This type should
- be able to encapsulate all of those.</li>
-
-</ol>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSCallback">NSSCallback</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSOperations">NSSOperations</a>
- <br>
- <br>
- <br>
-
-<hr width="100%" size="2"><br>
- <br>
- A diagram to suggest a possible TrustDomain architecture.<br>
- <br>
- <img src="./standiag.png" alt="Trust Domain Diagram" width="748" height="367">
- <br>
-
-<hr width="100%" size="2" align="Left"><br>
-
-<h3><a name="pki1"></a>
- <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pki1/">
- PKI1</a>
- </h3>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSOID">NSSOID</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSATAV">NSSATAV</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSRDN">NSSRDN</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSRDNSeq">NSSRDNSeq</a>
- <br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=NSSName">NSSName</a>
- <br>
- NSSNameChoice<br>
- NSSGeneralName<br>
- NSSGeneralNameChoice<br>
- NSSOtherName<br>
- NSSRFC822Name<br>
- NSSDNSName<br>
- NSSX400Address<br>
- NSSEdiParityAddress<br>
- NSSURI<br>
- NSSIPAddress<br>
- NSSRegisteredID<br>
- NSSGeneralNameSeq<br>
- <a href="http://lxr.mozilla.org/mozilla/ident?i=nssAttributeTypeAliasTable">
- nssAttributeTypeAliasTable</a>
- <br>
- <br>
- <br>
-
-<hr width="100%" size="2" align="Left"><br>
-
-<h3><a name="pkix"></a>
- <a href="http://lxr.mozilla.org/mozilla/source/security/nss/lib/pkix/">
- PKIX&nbsp;</a>
- </h3>
- There is a plethora of PKIX related types here.<br>
- <br>
-
-<hr width="100%" size="2" align="Left"><br>
-
-<h3><a name="build"></a>
- Building Stan</h3>
- <br>
- From nss/lib, run "make BUILD_STAN=1"<br>
- <br>
-
-<hr width="100%" size="2" align="Left"><br>
-
-<h3><a name="test"></a>
- Testing Stan</h3>
- A&nbsp;new command line tool, pkiutil, has been created to use only
- the Stan API. &nbsp;It depends on a new library, cmdlib, meant to replace
- the old secutil library. &nbsp;The old library had code used by products
- that needed to be integrated into the main library codebase somehow. &nbsp;The
- goal of the new cmdlib is to have functionality needed strictly for NSS
- tools.<br>
- <br>
- How to build:<br>
-
-<ol>
- <li>cd nss/cmd/cmdlib; make</li>
- <li>cd ../pkiutil; make</li>
-
-</ol>
- pkiutil will give detailed help with either "pkiutil -?" or "pkiutil
- --help".<br>
- <br>
- So far, the only available test is to list certs on the builtins token.
- &nbsp;Copy "libnssckbi.so" (or whatever it is) to cmd/pkiutil. &nbsp;Then
- run "pkiutil -L" or "pkiutil --list". &nbsp;The list of certificate nicknames
- should be displayed.<br>
- <br>
- <br>
-
-</body>
-</html>
diff --git a/security/nss/lib/pki/manifest.mn b/security/nss/lib/pki/manifest.mn
deleted file mode 100644
index 7c0f274bb..000000000
--- a/security/nss/lib/pki/manifest.mn
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$"
-
-CORE_DEPTH = ../../..
-
-PRIVATE_EXPORTS = \
- pki.h \
- pkit.h \
- nsspkit.h \
- nsspki.h \
- pkistore.h \
- pki3hack.h \
- pkitm.h \
- pkim.h \
- $(NULL)
-
-EXPORTS = \
- $(NULL)
-
-MODULE = nss
-
-CSRCS = \
- asymmkey.c \
- certificate.c \
- cryptocontext.c \
- symmkey.c \
- trustdomain.c \
- tdcache.c \
- certdecode.c \
- pkistore.c \
- pkibase.c \
- pki3hack.c \
- $(NULL)
-
-#DEFINES = -DDEBUG_CACHE
-
-REQUIRES = nspr
-
-LIBRARY_NAME = nsspki
-LIBRARY_VERSION = 3
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/pki/nsspki.h b/security/nss/lib/pki/nsspki.h
deleted file mode 100644
index b3b89528e..000000000
--- a/security/nss/lib/pki/nsspki.h
+++ /dev/null
@@ -1,3168 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSPKI_H
-#define NSSPKI_H
-
-#ifdef DEBUG
-static const char NSSPKI_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nsspki.h
- *
- * This file prototypes the methods of the top-level PKI objects.
- */
-
-#ifndef NSSDEVT_H
-#include "nssdevt.h"
-#endif /* NSSDEVT_H */
-
-#ifndef NSSPKIT_H
-#include "nsspkit.h"
-#endif /* NSSPKIT_H */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-PR_BEGIN_EXTERN_C
-
-/*
- * A note about interfaces
- *
- * Although these APIs are specified in C, a language which does
- * not have fancy support for abstract interfaces, this library
- * was designed from an object-oriented perspective. It may be
- * useful to consider the standard interfaces which went into
- * the writing of these APIs.
- *
- * Basic operations on all objects:
- * Destroy -- free a pointer to an object
- * DeleteStoredObject -- delete an object permanently
- *
- * Public Key cryptographic operations:
- * Encrypt
- * Verify
- * VerifyRecover
- * Wrap
- * Derive
- *
- * Private Key cryptographic operations:
- * IsStillPresent
- * Decrypt
- * Sign
- * SignRecover
- * Unwrap
- * Derive
- *
- * Symmetric Key cryptographic operations:
- * IsStillPresent
- * Encrypt
- * Decrypt
- * Sign
- * SignRecover
- * Verify
- * VerifyRecover
- * Wrap
- * Unwrap
- * Derive
- *
- */
-
-/*
- * NSSCertificate
- *
- * These things can do crypto ops like public keys, except that the trust,
- * usage, and other constraints are checked. These objects are "high-level,"
- * so trust, usages, etc. are in the form we throw around (client auth,
- * email signing, etc.). Remember that theoretically another implementation
- * (think PGP) could be beneath this object.
- */
-
-/*
- * NSSCertificate_Destroy
- *
- * Free a pointer to a certificate object.
- */
-
-NSS_EXTERN PRStatus
-NSSCertificate_Destroy
-(
- NSSCertificate *c
-);
-
-/*
- * NSSCertificate_DeleteStoredObject
- *
- * Permanently remove this certificate from storage. If this is the
- * only (remaining) certificate corresponding to a private key,
- * public key, and/or other object; then that object (those objects)
- * are deleted too.
- */
-
-NSS_EXTERN PRStatus
-NSSCertificate_DeleteStoredObject
-(
- NSSCertificate *c,
- NSSCallback *uhh
-);
-
-/*
- * NSSCertificate_Validate
- *
- * Verify that this certificate is trusted, for the specified usage(s),
- * at the specified time, {word word} the specified policies.
- */
-
-NSS_EXTERN PRStatus
-NSSCertificate_Validate
-(
- NSSCertificate *c,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt /* NULL for none */
-);
-
-/*
- * NSSCertificate_ValidateCompletely
- *
- * Verify that this certificate is trusted. The difference between
- * this and the previous call is that NSSCertificate_Validate merely
- * returns success or failure with an appropriate error stack.
- * However, there may be (and often are) multiple problems with a
- * certificate. This routine returns an array of errors, specifying
- * every problem.
- */
-
-/*
- * Return value must be an array of objects, each of which has
- * an NSSError, and any corresponding certificate (in the chain)
- * and/or policy.
- */
-
-NSS_EXTERN void ** /* void *[] */
-NSSCertificate_ValidateCompletely
-(
- NSSCertificate *c,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt, /* NULL for none */
- void **rvOpt, /* NULL for allocate */
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt /* NULL for heap */
-);
-
-/*
- * NSSCertificate_ValidateAndDiscoverUsagesAndPolicies
- *
- * Returns PR_SUCCESS if the certificate is valid for at least something.
- */
-
-NSS_EXTERN PRStatus
-NSSCertificate_ValidateAndDiscoverUsagesAndPolicies
-(
- NSSCertificate *c,
- NSSTime **notBeforeOutOpt,
- NSSTime **notAfterOutOpt,
- void *allowedUsages,
- void *disallowedUsages,
- void *allowedPolicies,
- void *disallowedPolicies,
- /* more args.. work on this fgmr */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCertificate_Encode
- *
- */
-
-NSS_EXTERN NSSDER *
-NSSCertificate_Encode
-(
- NSSCertificate *c,
- NSSDER *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCertificate_BuildChain
- *
- * This routine returns NSSCertificate *'s for each certificate
- * in the "chain" starting from the specified one up to and
- * including the root. The zeroth element in the array is the
- * specified ("leaf") certificate.
- *
- * If statusOpt is supplied, and is returned as PR_FAILURE, possible
- * error values are:
- *
- * NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND - the chain is incomplete
- *
- */
-
-extern const NSSError NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND;
-
-NSS_EXTERN NSSCertificate **
-NSSCertificate_BuildChain
-(
- NSSCertificate *c,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt,
- PRStatus *statusOpt,
- NSSTrustDomain *td,
- NSSCryptoContext *cc
-);
-
-/*
- * NSSCertificate_GetTrustDomain
- *
- */
-
-NSS_EXTERN NSSTrustDomain *
-NSSCertificate_GetTrustDomain
-(
- NSSCertificate *c
-);
-
-/*
- * NSSCertificate_GetToken
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSToken *
-NSSCertificate_GetToken
-(
- NSSCertificate *c,
- PRStatus *statusOpt
-);
-
-/*
- * NSSCertificate_GetSlot
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSSlot *
-NSSCertificate_GetSlot
-(
- NSSCertificate *c,
- PRStatus *statusOpt
-);
-
-/*
- * NSSCertificate_GetModule
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSModule *
-NSSCertificate_GetModule
-(
- NSSCertificate *c,
- PRStatus *statusOpt
-);
-
-/*
- * NSSCertificate_Encrypt
- *
- * Encrypt a single chunk of data with the public key corresponding to
- * this certificate.
- */
-
-NSS_EXTERN NSSItem *
-NSSCertificate_Encrypt
-(
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCertificate_Verify
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCertificate_Verify
-(
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh
-);
-
-/*
- * NSSCertificate_VerifyRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCertificate_VerifyRecover
-(
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCertificate_WrapSymmetricKey
- *
- * This method tries very hard to to succeed, even in situations
- * involving sensitive keys and multiple modules.
- * { relyea: want to add verbiage? }
- */
-
-NSS_EXTERN NSSItem *
-NSSCertificate_WrapSymmetricKey
-(
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCertificate_CreateCryptoContext
- *
- * Create a crypto context, in this certificate's trust domain, with this
- * as the distinguished certificate.
- */
-
-NSS_EXTERN NSSCryptoContext *
-NSSCertificate_CreateCryptoContext
-(
- NSSCertificate *c,
- NSSAlgorithmAndParameters *apOpt,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh
-);
-
-/*
- * NSSCertificate_GetPublicKey
- *
- * Returns the public key corresponding to this certificate.
- */
-
-NSS_EXTERN NSSPublicKey *
-NSSCertificate_GetPublicKey
-(
- NSSCertificate *c
-);
-
-/*
- * NSSCertificate_FindPrivateKey
- *
- * Finds and returns the private key corresponding to this certificate,
- * if it is available.
- *
- * { Should this hang off of NSSUserCertificate? }
- */
-
-NSS_EXTERN NSSPrivateKey *
-NSSCertificate_FindPrivateKey
-(
- NSSCertificate *c,
- NSSCallback *uhh
-);
-
-/*
- * NSSCertificate_IsPrivateKeyAvailable
- *
- * Returns success if the private key corresponding to this certificate
- * is available to be used.
- *
- * { Should *this* hang off of NSSUserCertificate?? }
- */
-
-NSS_EXTERN PRBool
-NSSCertificate_IsPrivateKeyAvailable
-(
- NSSCertificate *c,
- NSSCallback *uhh,
- PRStatus *statusOpt
-);
-
-/*
- * If we make NSSUserCertificate not a typedef of NSSCertificate,
- * then we'll need implementations of the following:
- *
- * NSSUserCertificate_Destroy
- * NSSUserCertificate_DeleteStoredObject
- * NSSUserCertificate_Validate
- * NSSUserCertificate_ValidateCompletely
- * NSSUserCertificate_ValidateAndDiscoverUsagesAndPolicies
- * NSSUserCertificate_Encode
- * NSSUserCertificate_BuildChain
- * NSSUserCertificate_GetTrustDomain
- * NSSUserCertificate_GetToken
- * NSSUserCertificate_GetSlot
- * NSSUserCertificate_GetModule
- * NSSUserCertificate_GetCryptoContext
- * NSSUserCertificate_GetPublicKey
- */
-
-/*
- * NSSUserCertificate_IsStillPresent
- *
- * Verify that if this certificate lives on a token, that the token
- * is still present and the certificate still exists. This is a
- * lightweight call which should be used whenever it should be
- * verified that the user hasn't perhaps popped out his or her
- * token and strolled away.
- */
-
-NSS_EXTERN PRBool
-NSSUserCertificate_IsStillPresent
-(
- NSSUserCertificate *uc,
- PRStatus *statusOpt
-);
-
-/*
- * NSSUserCertificate_Decrypt
- *
- * Decrypt a single chunk of data with the private key corresponding
- * to this certificate.
- */
-
-NSS_EXTERN NSSItem *
-NSSUserCertificate_Decrypt
-(
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSUserCertificate_Sign
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSUserCertificate_Sign
-(
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSUserCertificate_SignRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSUserCertificate_SignRecover
-(
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSUserCertificate_UnwrapSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSUserCertificate_UnwrapSymmetricKey
-(
- NSSUserCertificate *uc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSUserCertificate_DeriveSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSUserCertificate_DeriveSymmetricKey
-(
- NSSUserCertificate *uc, /* provides private key */
- NSSCertificate *c, /* provides public key */
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt, /* zero for best allowed */
- NSSOperations operations,
- NSSCallback *uhh
-);
-
-/* filter-certs function(s) */
-
-/**
- ** fgmr -- trust objects
- **/
-
-/*
- * NSSPrivateKey
- *
- */
-
-/*
- * NSSPrivateKey_Destroy
- *
- * Free a pointer to a private key object.
- */
-
-NSS_EXTERN PRStatus
-NSSPrivateKey_Destroy
-(
- NSSPrivateKey *vk
-);
-
-/*
- * NSSPrivateKey_DeleteStoredObject
- *
- * Permanently remove this object, and any related objects (such as the
- * certificates corresponding to this key).
- */
-
-NSS_EXTERN PRStatus
-NSSPrivateKey_DeleteStoredObject
-(
- NSSPrivateKey *vk,
- NSSCallback *uhh
-);
-
-/*
- * NSSPrivateKey_GetSignatureLength
- *
- */
-
-NSS_EXTERN PRUint32
-NSSPrivateKey_GetSignatureLength
-(
- NSSPrivateKey *vk
-);
-
-/*
- * NSSPrivateKey_GetPrivateModulusLength
- *
- */
-
-NSS_EXTERN PRUint32
-NSSPrivateKey_GetPrivateModulusLength
-(
- NSSPrivateKey *vk
-);
-
-/*
- * NSSPrivateKey_IsStillPresent
- *
- */
-
-NSS_EXTERN PRBool
-NSSPrivateKey_IsStillPresent
-(
- NSSPrivateKey *vk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSPrivateKey_Encode
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSPrivateKey_Encode
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *ap,
- NSSItem *passwordOpt, /* NULL will cause a callback; "" for no password */
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPrivateKey_GetTrustDomain
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSTrustDomain *
-NSSPrivateKey_GetTrustDomain
-(
- NSSPrivateKey *vk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSPrivateKey_GetToken
- *
- */
-
-NSS_EXTERN NSSToken *
-NSSPrivateKey_GetToken
-(
- NSSPrivateKey *vk
-);
-
-/*
- * NSSPrivateKey_GetSlot
- *
- */
-
-NSS_EXTERN NSSSlot *
-NSSPrivateKey_GetSlot
-(
- NSSPrivateKey *vk
-);
-
-/*
- * NSSPrivateKey_GetModule
- *
- */
-
-NSS_EXTERN NSSModule *
-NSSPrivateKey_GetModule
-(
- NSSPrivateKey *vk
-);
-
-/*
- * NSSPrivateKey_Decrypt
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSPrivateKey_Decrypt
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPrivateKey_Sign
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSPrivateKey_Sign
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPrivateKey_SignRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSPrivateKey_SignRecover
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPrivateKey_UnwrapSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSPrivateKey_UnwrapSymmetricKey
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSCallback *uhh
-);
-
-/*
- * NSSPrivateKey_DeriveSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSPrivateKey_DeriveSymmetricKey
-(
- NSSPrivateKey *vk,
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt, /* zero for best allowed */
- NSSOperations operations,
- NSSCallback *uhh
-);
-
-/*
- * NSSPrivateKey_FindPublicKey
- *
- */
-
-NSS_EXTERN NSSPublicKey *
-NSSPrivateKey_FindPublicKey
-(
- NSSPrivateKey *vk
- /* { don't need the callback here, right? } */
-);
-
-/*
- * NSSPrivateKey_CreateCryptoContext
- *
- * Create a crypto context, in this key's trust domain,
- * with this as the distinguished private key.
- */
-
-NSS_EXTERN NSSCryptoContext *
-NSSPrivateKey_CreateCryptoContext
-(
- NSSPrivateKey *vk,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhh
-);
-
-/*
- * NSSPrivateKey_FindCertificates
- *
- * Note that there may be more than one certificate for this
- * private key. { FilterCertificates function to further
- * reduce the list. }
- */
-
-NSS_EXTERN NSSCertificate **
-NSSPrivateKey_FindCertificates
-(
- NSSPrivateKey *vk,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPrivateKey_FindBestCertificate
- *
- * The parameters for this function will depend on what the users
- * need. This is just a starting point.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSPrivateKey_FindBestCertificate
-(
- NSSPrivateKey *vk,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSPublicKey
- *
- * Once you generate, find, or derive one of these, you can use it
- * to perform (simple) cryptographic operations. Though there may
- * be certificates associated with these public keys, they are not
- * verified.
- */
-
-/*
- * NSSPublicKey_Destroy
- *
- * Free a pointer to a public key object.
- */
-
-NSS_EXTERN PRStatus
-NSSPublicKey_Destroy
-(
- NSSPublicKey *bk
-);
-
-/*
- * NSSPublicKey_DeleteStoredObject
- *
- * Permanently remove this object, and any related objects (such as the
- * corresponding private keys and certificates).
- */
-
-NSS_EXTERN PRStatus
-NSSPublicKey_DeleteStoredObject
-(
- NSSPublicKey *bk,
- NSSCallback *uhh
-);
-
-/*
- * NSSPublicKey_Encode
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSPublicKey_Encode
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *ap,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPublicKey_GetTrustDomain
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSTrustDomain *
-NSSPublicKey_GetTrustDomain
-(
- NSSPublicKey *bk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSPublicKey_GetToken
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSToken *
-NSSPublicKey_GetToken
-(
- NSSPublicKey *bk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSPublicKey_GetSlot
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSSlot *
-NSSPublicKey_GetSlot
-(
- NSSPublicKey *bk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSPublicKey_GetModule
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSModule *
-NSSPublicKey_GetModule
-(
- NSSPublicKey *bk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSPublicKey_Encrypt
- *
- * Encrypt a single chunk of data with the public key corresponding to
- * this certificate.
- */
-
-NSS_EXTERN NSSItem *
-NSSPublicKey_Encrypt
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPublicKey_Verify
- *
- */
-
-NSS_EXTERN PRStatus
-NSSPublicKey_Verify
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSCallback *uhh
-);
-
-/*
- * NSSPublicKey_VerifyRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSPublicKey_VerifyRecover
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPublicKey_WrapSymmetricKey
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSPublicKey_WrapSymmetricKey
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPublicKey_CreateCryptoContext
- *
- * Create a crypto context, in this key's trust domain, with this
- * as the distinguished public key.
- */
-
-NSS_EXTERN NSSCryptoContext *
-NSSPublicKey_CreateCryptoContext
-(
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhh
-);
-
-/*
- * NSSPublicKey_FindCertificates
- *
- * Note that there may be more than one certificate for this
- * public key. The current implementation may not find every
- * last certificate available for this public key: that would
- * involve trolling e.g. huge ldap databases, which will be
- * grossly inefficient and not generally useful.
- * { FilterCertificates function to further reduce the list }
- */
-
-NSS_EXTERN NSSCertificate **
-NSSPublicKey_FindCertificates
-(
- NSSPublicKey *bk,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSPrivateKey_FindBestCertificate
- *
- * The parameters for this function will depend on what the users
- * need. This is just a starting point.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSPublicKey_FindBestCertificate
-(
- NSSPublicKey *bk,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSPublicKey_FindPrivateKey
- *
- */
-
-NSS_EXTERN NSSPrivateKey *
-NSSPublicKey_FindPrivateKey
-(
- NSSPublicKey *bk,
- NSSCallback *uhh
-);
-
-/*
- * NSSSymmetricKey
- *
- */
-
-/*
- * NSSSymmetricKey_Destroy
- *
- * Free a pointer to a symmetric key object.
- */
-
-NSS_EXTERN PRStatus
-NSSSymmetricKey_Destroy
-(
- NSSSymmetricKey *mk
-);
-
-/*
- * NSSSymmetricKey_DeleteStoredObject
- *
- * Permanently remove this object.
- */
-
-NSS_EXTERN PRStatus
-NSSSymmetricKey_DeleteStoredObject
-(
- NSSSymmetricKey *mk,
- NSSCallback *uhh
-);
-
-/*
- * NSSSymmetricKey_GetKeyLength
- *
- */
-
-NSS_EXTERN PRUint32
-NSSSymmetricKey_GetKeyLength
-(
- NSSSymmetricKey *mk
-);
-
-/*
- * NSSSymmetricKey_GetKeyStrength
- *
- */
-
-NSS_EXTERN PRUint32
-NSSSymmetricKey_GetKeyStrength
-(
- NSSSymmetricKey *mk
-);
-
-/*
- * NSSSymmetricKey_IsStillPresent
- *
- */
-
-NSS_EXTERN PRStatus
-NSSSymmetricKey_IsStillPresent
-(
- NSSSymmetricKey *mk
-);
-
-/*
- * NSSSymmetricKey_GetTrustDomain
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSTrustDomain *
-NSSSymmetricKey_GetTrustDomain
-(
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSSymmetricKey_GetToken
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSToken *
-NSSSymmetricKey_GetToken
-(
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSSymmetricKey_GetSlot
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSSlot *
-NSSSymmetricKey_GetSlot
-(
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSSymmetricKey_GetModule
- *
- * There doesn't have to be one.
- */
-
-NSS_EXTERN NSSModule *
-NSSSymmetricKey_GetModule
-(
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-);
-
-/*
- * NSSSymmetricKey_Encrypt
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSSymmetricKey_Encrypt
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSSymmetricKey_Decrypt
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSSymmetricKey_Decrypt
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSSymmetricKey_Sign
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSSymmetricKey_Sign
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSSymmetricKey_SignRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSSymmetricKey_SignRecover
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSSymmetricKey_Verify
- *
- */
-
-NSS_EXTERN PRStatus
-NSSSymmetricKey_Verify
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSCallback *uhh
-);
-
-/*
- * NSSSymmetricKey_VerifyRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSSymmetricKey_VerifyRecover
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSSymmetricKey_WrapSymmetricKey
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSSymmetricKey_WrapSymmetricKey
-(
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSSymmetricKey_WrapPrivateKey
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSSymmetricKey_WrapPrivateKey
-(
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSPrivateKey *keyToWrap,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSSymmetricKey_UnwrapSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSSymmetricKey_UnwrapSymmetricKey
-(
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSOID *target,
- PRUint32 keySizeOpt,
- NSSOperations operations,
- NSSCallback *uhh
-);
-
-/*
- * NSSSymmetricKey_UnwrapPrivateKey
- *
- */
-
-NSS_EXTERN NSSPrivateKey *
-NSSSymmetricKey_UnwrapPrivateKey
-(
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSUTF8 *labelOpt,
- NSSItem *keyIDOpt,
- PRBool persistant,
- PRBool sensitive,
- NSSToken *destinationOpt,
- NSSCallback *uhh
-);
-
-/*
- * NSSSymmetricKey_DeriveSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSSymmetricKey_DeriveSymmetricKey
-(
- NSSSymmetricKey *originalKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt,
- NSSOperations operations,
- NSSCallback *uhh
-);
-
-/*
- * NSSSymmetricKey_CreateCryptoContext
- *
- * Create a crypto context, in this key's trust domain,
- * with this as the distinguished symmetric key.
- */
-
-NSS_EXTERN NSSCryptoContext *
-NSSSymmetricKey_CreateCryptoContext
-(
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhh
-);
-
-/*
- * NSSTrustDomain
- *
- */
-
-/*
- * NSSTrustDomain_Create
- *
- * This creates a trust domain, optionally with an initial cryptoki
- * module. If the module name is not null, the module is loaded if
- * needed (using the uriOpt argument), and initialized with the
- * opaqueOpt argument. If mumble mumble priority settings, then
- * module-specification objects in the module can cause the loading
- * and initialization of further modules.
- *
- * The uriOpt is defined to take a URI. At present, we only
- * support file: URLs pointing to platform-native shared libraries.
- * However, by specifying this as a URI, this keeps open the
- * possibility of supporting other, possibly remote, resources.
- *
- * The "reserved" arguments is held for when we figure out the
- * module priority stuff.
- */
-
-NSS_EXTERN NSSTrustDomain *
-NSSTrustDomain_Create
-(
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-);
-
-/*
- * NSSTrustDomain_Destroy
- *
- */
-
-NSS_EXTERN PRStatus
-NSSTrustDomain_Destroy
-(
- NSSTrustDomain *td
-);
-
-/*
- * NSSTrustDomain_SetDefaultCallback
- *
- */
-
-NSS_EXTERN PRStatus
-NSSTrustDomain_SetDefaultCallback
-(
- NSSTrustDomain *td,
- NSSCallback *newCallback,
- NSSCallback **oldCallbackOpt
-);
-
-/*
- * NSSTrustDomain_GetDefaultCallback
- *
- */
-
-NSS_EXTERN NSSCallback *
-NSSTrustDomain_GetDefaultCallback
-(
- NSSTrustDomain *td,
- PRStatus *statusOpt
-);
-
-/*
- * Default policies?
- * Default usage?
- * Default time, for completeness?
- */
-
-/*
- * NSSTrustDomain_LoadModule
- *
- */
-
-NSS_EXTERN PRStatus
-NSSTrustDomain_LoadModule
-(
- NSSTrustDomain *td,
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-);
-
-/*
- * NSSTrustDomain_AddModule
- * NSSTrustDomain_AddSlot
- * NSSTrustDomain_UnloadModule
- * Managing modules, slots, tokens; priorities;
- * Traversing all of the above
- * this needs more work
- */
-
-/*
- * NSSTrustDomain_DisableToken
- *
- */
-
-NSS_EXTERN PRStatus
-NSSTrustDomain_DisableToken
-(
- NSSTrustDomain *td,
- NSSToken *token,
- NSSError why
-);
-
-/*
- * NSSTrustDomain_EnableToken
- *
- */
-
-NSS_EXTERN PRStatus
-NSSTrustDomain_EnableToken
-(
- NSSTrustDomain *td,
- NSSToken *token
-);
-
-/*
- * NSSTrustDomain_IsTokenEnabled
- *
- * If disabled, "why" is always on the error stack.
- * The optional argument is just for convenience.
- */
-
-NSS_EXTERN PRStatus
-NSSTrustDomain_IsTokenEnabled
-(
- NSSTrustDomain *td,
- NSSToken *token,
- NSSError *whyOpt
-);
-
-/*
- * NSSTrustDomain_FindSlotByName
- *
- */
-
-NSS_EXTERN NSSSlot *
-NSSTrustDomain_FindSlotByName
-(
- NSSTrustDomain *td,
- NSSUTF8 *slotName
-);
-
-/*
- * NSSTrustDomain_FindTokenByName
- *
- */
-
-NSS_EXTERN NSSToken *
-NSSTrustDomain_FindTokenByName
-(
- NSSTrustDomain *td,
- NSSUTF8 *tokenName
-);
-
-/*
- * NSSTrustDomain_FindTokenBySlotName
- *
- */
-
-NSS_EXTERN NSSToken *
-NSSTrustDomain_FindTokenBySlotName
-(
- NSSTrustDomain *td,
- NSSUTF8 *slotName
-);
-
-/*
- * NSSTrustDomain_FindBestTokenForAlgorithm
- *
- */
-
-NSS_EXTERN NSSToken *
-NSSTrustDomain_FindTokenForAlgorithm
-(
- NSSTrustDomain *td,
- NSSOID *algorithm
-);
-
-/*
- * NSSTrustDomain_FindBestTokenForAlgorithms
- *
- */
-
-NSS_EXTERN NSSToken *
-NSSTrustDomain_FindBestTokenForAlgorithms
-(
- NSSTrustDomain *td,
- NSSOID *algorithms[], /* may be null-terminated */
- PRUint32 nAlgorithmsOpt /* limits the array if nonzero */
-);
-
-/*
- * NSSTrustDomain_Login
- *
- */
-
-NSS_EXTERN PRStatus
-NSSTrustDomain_Login
-(
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSTrustDomain_Logout
- *
- */
-
-NSS_EXTERN PRStatus
-NSSTrustDomain_Logout
-(
- NSSTrustDomain *td
-);
-
-/* Importing things */
-
-/*
- * NSSTrustDomain_ImportCertificate
- *
- * The implementation will pull some data out of the certificate
- * (e.g. e-mail address) for use in pkcs#11 object attributes.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_ImportCertificate
-(
- NSSTrustDomain *td,
- NSSCertificate *c
-);
-
-/*
- * NSSTrustDomain_ImportPKIXCertificate
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_ImportPKIXCertificate
-(
- NSSTrustDomain *td,
- /* declared as a struct until these "data types" are defined */
- struct NSSPKIXCertificateStr *pc
-);
-
-/*
- * NSSTrustDomain_ImportEncodedCertificate
- *
- * Imports any type of certificate we support.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_ImportEncodedCertificate
-(
- NSSTrustDomain *td,
- NSSBER *ber
-);
-
-/*
- * NSSTrustDomain_ImportEncodedCertificateChain
- *
- * If you just want the leaf, pass in a maximum of one.
- */
-
-NSS_EXTERN NSSCertificate **
-NSSTrustDomain_ImportEncodedCertificateChain
-(
- NSSTrustDomain *td,
- NSSBER *ber,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSTrustDomain_ImportEncodedPrivateKey
- *
- */
-
-NSS_EXTERN NSSPrivateKey *
-NSSTrustDomain_ImportEncodedPrivateKey
-(
- NSSTrustDomain *td,
- NSSBER *ber,
- NSSItem *passwordOpt, /* NULL will cause a callback */
- NSSCallback *uhhOpt,
- NSSToken *destination
-);
-
-/*
- * NSSTrustDomain_ImportEncodedPublicKey
- *
- */
-
-NSS_EXTERN NSSPublicKey *
-NSSTrustDomain_ImportEncodedPublicKey
-(
- NSSTrustDomain *td,
- NSSBER *ber
-);
-
-/* Other importations: S/MIME capabilities */
-
-/*
- * NSSTrustDomain_FindBestCertificateByNickname
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestCertificateByNickname
-(
- NSSTrustDomain *td,
- const NSSUTF8 *name,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt /* NULL for none */
-);
-
-/*
- * NSSTrustDomain_FindCertificatesByNickname
- *
- */
-
-NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindCertificatesByNickname
-(
- NSSTrustDomain *td,
- NSSUTF8 *name,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
-(
- NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serialNumber
-);
-
-/*
- * NSSTrustDomain_FindCertificatesByIssuerAndSerialNumber
- *
- * Theoretically, this should never happen. However, some companies
- * we know have issued duplicate certificates with the same issuer
- * and serial number. Do we just ignore them? I'm thinking yes.
- */
-
-/*
- * NSSTrustDomain_FindBestCertificateBySubject
- *
- * This does not search through alternate names hidden in extensions.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestCertificateBySubject
-(
- NSSTrustDomain *td,
- NSSDER /*NSSUTF8*/ *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSTrustDomain_FindCertificatesBySubject
- *
- * This does not search through alternate names hidden in extensions.
- */
-
-NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindCertificatesBySubject
-(
- NSSTrustDomain *td,
- NSSDER /*NSSUTF8*/ *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSTrustDomain_FindBestCertificateByNameComponents
- *
- * This call does try several tricks, including a pseudo pkcs#11
- * attribute for the ldap module to try as a query. Eventually
- * this call falls back to a traversal if that's what's required.
- * It will search through alternate names hidden in extensions.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestCertificateByNameComponents
-(
- NSSTrustDomain *td,
- NSSUTF8 *nameComponents,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSTrustDomain_FindCertificatesByNameComponents
- *
- * This call, too, tries several tricks. It will stop on the first
- * attempt that generates results, so it won't e.g. traverse the
- * entire ldap database.
- */
-
-NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindCertificatesByNameComponents
-(
- NSSTrustDomain *td,
- NSSUTF8 *nameComponents,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSTrustDomain_FindCertificateByEncodedCertificate
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindCertificateByEncodedCertificate
-(
- NSSTrustDomain *td,
- NSSBER *encodedCertificate
-);
-
-/*
- * NSSTrustDomain_FindBestCertificateByEmail
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindCertificateByEmail
-(
- NSSTrustDomain *td,
- NSSASCII7 *email,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSTrustDomain_FindCertificatesByEmail
- *
- */
-
-NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindCertificatesByEmail
-(
- NSSTrustDomain *td,
- NSSASCII7 *email,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSTrustDomain_FindCertificateByOCSPHash
- *
- * There can be only one.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindCertificateByOCSPHash
-(
- NSSTrustDomain *td,
- NSSItem *hash
-);
-
-/*
- * NSSTrustDomain_TraverseCertificates
- *
- * This function descends from one in older versions of NSS which
- * traverses the certs in the permanent database. That function
- * was used to implement selection routines, but was directly
- * available too. Trust domains are going to contain a lot more
- * certs now (e.g., an ldap server), so we'd really like to
- * discourage traversal. Thus for now, this is commented out.
- * If it's needed, let's look at the situation more closely to
- * find out what the actual requirements are.
- */
-
-/* For now, adding this function. This may only be for debugging
- * purposes.
- * Perhaps some equivalent function, on a specified token, will be
- * needed in a "friend" header file?
- */
-NSS_EXTERN PRStatus *
-NSSTrustDomain_TraverseCertificates
-(
- NSSTrustDomain *td,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-);
-
-/*
- * NSSTrustDomain_FindBestUserCertificate
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestUserCertificate
-(
- NSSTrustDomain *td,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSTrustDomain_FindUserCertificates
- *
- */
-
-NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindUserCertificates
-(
- NSSTrustDomain *td,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSTrustDomain_FindBestUserCertificateForSSLClientAuth
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestUserCertificateForSSLClientAuth
-(
- NSSTrustDomain *td,
- NSSUTF8 *sslHostOpt,
- NSSDER *rootCAsOpt[], /* null pointer for none */
- PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSTrustDomain_FindUserCertificatesForSSLClientAuth
- *
- */
-
-NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindUserCertificatesForSSLClientAuth
-(
- NSSTrustDomain *td,
- NSSUTF8 *sslHostOpt,
- NSSDER *rootCAsOpt[], /* null pointer for none */
- PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSTrustDomain_FindBestUserCertificateForEmailSigning
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSTrustDomain_FindBestUserCertificateForEmailSigning
-(
- NSSTrustDomain *td,
- NSSASCII7 *signerOpt,
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSTrustDomain_FindUserCertificatesForEmailSigning
- *
- */
-
-NSS_EXTERN NSSCertificate **
-NSSTrustDomain_FindUserCertificatesForEmailSigning
-(
- NSSTrustDomain *td,
- NSSASCII7 *signerOpt,
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-);
-
-/*
- * Here is where we'd add more Find[Best]UserCertificate[s]For<usage>
- * routines.
- */
-
-/* Private Keys */
-
-/*
- * NSSTrustDomain_GenerateKeyPair
- *
- * Creates persistant objects. If you want session objects, use
- * NSSCryptoContext_GenerateKeyPair. The destination token is where
- * the keys are stored. If that token can do the required math, then
- * that's where the keys are generated too. Otherwise, the keys are
- * generated elsewhere and moved to that token.
- */
-
-NSS_EXTERN PRStatus
-NSSTrustDomain_GenerateKeyPair
-(
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- NSSPrivateKey **pvkOpt,
- NSSPublicKey **pbkOpt,
- PRBool privateKeyIsSensitive,
- NSSToken *destination,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSTrustDomain_TraversePrivateKeys
- *
- *
- * NSS_EXTERN PRStatus *
- * NSSTrustDomain_TraversePrivateKeys
- * (
- * NSSTrustDomain *td,
- * PRStatus (*callback)(NSSPrivateKey *vk, void *arg),
- * void *arg
- * );
- */
-
-/* Symmetric Keys */
-
-/*
- * NSSTrustDomain_GenerateSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSTrustDomain_GenerateSymmetricKey
-(
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- PRUint32 keysize,
- NSSToken *destination,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSTrustDomain_GenerateSymmetricKeyFromPassword
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSTrustDomain_GenerateSymmetricKeyFromPassword
-(
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- NSSUTF8 *passwordOpt, /* if null, prompt */
- NSSToken *destinationOpt,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSTrustDomain_FindSymmetricKeyByAlgorithm
- *
- * Is this still needed?
- *
- * NSS_EXTERN NSSSymmetricKey *
- * NSSTrustDomain_FindSymmetricKeyByAlgorithm
- * (
- * NSSTrustDomain *td,
- * NSSOID *algorithm,
- * NSSCallback *uhhOpt
- * );
- */
-
-/*
- * NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID
-(
- NSSTrustDomain *td,
- NSSOID *algorithm,
- NSSItem *keyID,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSTrustDomain_TraverseSymmetricKeys
- *
- *
- * NSS_EXTERN PRStatus *
- * NSSTrustDomain_TraverseSymmetricKeys
- * (
- * NSSTrustDomain *td,
- * PRStatus (*callback)(NSSSymmetricKey *mk, void *arg),
- * void *arg
- * );
- */
-
-/*
- * NSSTrustDomain_CreateCryptoContext
- *
- * If a callback object is specified, it becomes the for the crypto
- * context; otherwise, this trust domain's default (if any) is
- * inherited.
- */
-
-NSS_EXTERN NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContext
-(
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSTrustDomain_CreateCryptoContextForAlgorithm
- *
- */
-
-NSS_EXTERN NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContextForAlgorithm
-(
- NSSTrustDomain *td,
- NSSOID *algorithm
-);
-
-/*
- * NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters
- *
- */
-
-NSS_EXTERN NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters
-(
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap
-);
-
-/* find/traverse other objects, e.g. s/mime profiles */
-
-/*
- * NSSCryptoContext
- *
- * A crypto context is sort of a short-term snapshot of a trust domain,
- * used for the life of "one crypto operation." You can also think of
- * it as a "temporary database."
- *
- * Just about all of the things you can do with a trust domain -- importing
- * or creating certs, keys, etc. -- can be done with a crypto context.
- * The difference is that the objects will be temporary ("session") objects.
- *
- * Also, if the context was created for a key, cert, and/or algorithm; or
- * if such objects have been "associated" with the context, then the context
- * can do everything the keys can, like crypto operations.
- *
- * And finally, because it keeps the state of the crypto operations, it
- * can do streaming crypto ops.
- */
-
-/*
- * NSSTrustDomain_Destroy
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_Destroy
-(
- NSSCryptoContext *cc
-);
-
-/* establishing a default callback */
-
-/*
- * NSSCryptoContext_SetDefaultCallback
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_SetDefaultCallback
-(
- NSSCryptoContext *cc,
- NSSCallback *newCallback,
- NSSCallback **oldCallbackOpt
-);
-
-/*
- * NSSCryptoContext_GetDefaultCallback
- *
- */
-
-NSS_EXTERN NSSCallback *
-NSSCryptoContext_GetDefaultCallback
-(
- NSSCryptoContext *cc,
- PRStatus *statusOpt
-);
-
-/*
- * NSSCryptoContext_GetTrustDomain
- *
- */
-
-NSS_EXTERN NSSTrustDomain *
-NSSCryptoContext_GetTrustDomain
-(
- NSSCryptoContext *cc
-);
-
-/* AddModule, etc: should we allow "temporary" changes here? */
-/* DisableToken, etc: ditto */
-/* Ordering of tokens? */
-/* Finding slots+token etc. */
-/* login+logout */
-
-/* Importing things */
-
-/*
- * NSSCryptoContext_FindOrImportCertificate
- *
- * If the certificate store already contains this DER cert, return the
- * address of the matching NSSCertificate that is already in the store,
- * and bump its reference count.
- *
- * If this DER cert is NOT already in the store, then add the new
- * NSSCertificate to the store and bump its reference count,
- * then return its address.
- *
- * if this DER cert is not in the store and cannot be added to it,
- * return NULL;
- *
- * Record the associated crypto context in the certificate.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindOrImportCertificate (
- NSSCryptoContext *cc,
- NSSCertificate *c
-);
-
-/*
- * NSSCryptoContext_ImportPKIXCertificate
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_ImportPKIXCertificate
-(
- NSSCryptoContext *cc,
- struct NSSPKIXCertificateStr *pc
-);
-
-/*
- * NSSCryptoContext_ImportEncodedCertificate
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_ImportEncodedCertificate
-(
- NSSCryptoContext *cc,
- NSSBER *ber
-);
-
-/*
- * NSSCryptoContext_ImportEncodedPKIXCertificateChain
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_ImportEncodedPKIXCertificateChain
-(
- NSSCryptoContext *cc,
- NSSBER *ber
-);
-
-/* Other importations: S/MIME capabilities
- */
-
-/*
- * NSSCryptoContext_FindBestCertificateByNickname
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestCertificateByNickname
-(
- NSSCryptoContext *cc,
- const NSSUTF8 *name,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt /* NULL for none */
-);
-
-/*
- * NSSCryptoContext_FindCertificatesByNickname
- *
- */
-
-NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindCertificatesByNickname
-(
- NSSCryptoContext *cc,
- NSSUTF8 *name,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FindCertificateByIssuerAndSerialNumber
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindCertificateByIssuerAndSerialNumber
-(
- NSSCryptoContext *cc,
- NSSDER *issuer,
- NSSDER *serialNumber
-);
-
-/*
- * NSSCryptoContext_FindBestCertificateBySubject
- *
- * This does not search through alternate names hidden in extensions.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestCertificateBySubject
-(
- NSSCryptoContext *cc,
- NSSDER /*NSSUTF8*/ *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSCryptoContext_FindCertificatesBySubject
- *
- * This does not search through alternate names hidden in extensions.
- */
-
-NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindCertificatesBySubject
-(
- NSSCryptoContext *cc,
- NSSDER /*NSSUTF8*/ *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FindBestCertificateByNameComponents
- *
- * This call does try several tricks, including a pseudo pkcs#11
- * attribute for the ldap module to try as a query. Eventually
- * this call falls back to a traversal if that's what's required.
- * It will search through alternate names hidden in extensions.
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestCertificateByNameComponents
-(
- NSSCryptoContext *cc,
- NSSUTF8 *nameComponents,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSCryptoContext_FindCertificatesByNameComponents
- *
- * This call, too, tries several tricks. It will stop on the first
- * attempt that generates results, so it won't e.g. traverse the
- * entire ldap database.
- */
-
-NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindCertificatesByNameComponents
-(
- NSSCryptoContext *cc,
- NSSUTF8 *nameComponents,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FindCertificateByEncodedCertificate
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindCertificateByEncodedCertificate
-(
- NSSCryptoContext *cc,
- NSSBER *encodedCertificate
-);
-
-/*
- * NSSCryptoContext_FindBestCertificateByEmail
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestCertificateByEmail
-(
- NSSCryptoContext *cc,
- NSSASCII7 *email,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSCryptoContext_FindCertificatesByEmail
- *
- */
-
-NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindCertificatesByEmail
-(
- NSSCryptoContext *cc,
- NSSASCII7 *email,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FindCertificateByOCSPHash
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindCertificateByOCSPHash
-(
- NSSCryptoContext *cc,
- NSSItem *hash
-);
-
-/*
- * NSSCryptoContext_TraverseCertificates
- *
- *
- * NSS_EXTERN PRStatus *
- * NSSCryptoContext_TraverseCertificates
- * (
- * NSSCryptoContext *cc,
- * PRStatus (*callback)(NSSCertificate *c, void *arg),
- * void *arg
- * );
- */
-
-/*
- * NSSCryptoContext_FindBestUserCertificate
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestUserCertificate
-(
- NSSCryptoContext *cc,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSCryptoContext_FindUserCertificates
- *
- */
-
-NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindUserCertificates
-(
- NSSCryptoContext *cc,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FindBestUserCertificateForSSLClientAuth
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestUserCertificateForSSLClientAuth
-(
- NSSCryptoContext *cc,
- NSSUTF8 *sslHostOpt,
- NSSDER *rootCAsOpt[], /* null pointer for none */
- PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSCryptoContext_FindUserCertificatesForSSLClientAuth
- *
- */
-
-NSS_EXTERN NSSCertificate **
-NSSCryptoContext_FindUserCertificatesForSSLClientAuth
-(
- NSSCryptoContext *cc,
- NSSUTF8 *sslHostOpt,
- NSSDER *rootCAsOpt[], /* null pointer for none */
- PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FindBestUserCertificateForEmailSigning
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindBestUserCertificateForEmailSigning
-(
- NSSCryptoContext *cc,
- NSSASCII7 *signerOpt,
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-);
-
-/*
- * NSSCryptoContext_FindUserCertificatesForEmailSigning
- *
- */
-
-NSS_EXTERN NSSCertificate *
-NSSCryptoContext_FindUserCertificatesForEmailSigning
-(
- NSSCryptoContext *cc,
- NSSASCII7 *signerOpt, /* fgmr or a more general name? */
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-);
-
-/* Private Keys */
-
-/*
- * NSSCryptoContext_GenerateKeyPair
- *
- * Creates session objects. If you want persistant objects, use
- * NSSTrustDomain_GenerateKeyPair. The destination token is where
- * the keys are stored. If that token can do the required math, then
- * that's where the keys are generated too. Otherwise, the keys are
- * generated elsewhere and moved to that token.
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_GenerateKeyPair
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *ap,
- NSSPrivateKey **pvkOpt,
- NSSPublicKey **pbkOpt,
- PRBool privateKeyIsSensitive,
- NSSToken *destination,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_TraversePrivateKeys
- *
- *
- * NSS_EXTERN PRStatus *
- * NSSCryptoContext_TraversePrivateKeys
- * (
- * NSSCryptoContext *cc,
- * PRStatus (*callback)(NSSPrivateKey *vk, void *arg),
- * void *arg
- * );
- */
-
-/* Symmetric Keys */
-
-/*
- * NSSCryptoContext_GenerateSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_GenerateSymmetricKey
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *ap,
- PRUint32 keysize,
- NSSToken *destination,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_GenerateSymmetricKeyFromPassword
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_GenerateSymmetricKeyFromPassword
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *ap,
- NSSUTF8 *passwordOpt, /* if null, prompt */
- NSSToken *destinationOpt,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_FindSymmetricKeyByAlgorithm
- *
- *
- * NSS_EXTERN NSSSymmetricKey *
- * NSSCryptoContext_FindSymmetricKeyByType
- * (
- * NSSCryptoContext *cc,
- * NSSOID *type,
- * NSSCallback *uhhOpt
- * );
- */
-
-/*
- * NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_FindSymmetricKeyByAlgorithmAndKeyID
-(
- NSSCryptoContext *cc,
- NSSOID *algorithm,
- NSSItem *keyID,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_TraverseSymmetricKeys
- *
- *
- * NSS_EXTERN PRStatus *
- * NSSCryptoContext_TraverseSymmetricKeys
- * (
- * NSSCryptoContext *cc,
- * PRStatus (*callback)(NSSSymmetricKey *mk, void *arg),
- * void *arg
- * );
- */
-
-/* Crypto ops on distinguished keys */
-
-/*
- * NSSCryptoContext_Decrypt
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_Decrypt
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_BeginDecrypt
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_BeginDecrypt
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_ContinueDecrypt
- *
- */
-
-/*
- * NSSItem semantics:
- *
- * If rvOpt is NULL, a new NSSItem and buffer are allocated.
- * If rvOpt is not null, but the buffer pointer is null,
- * then rvOpt is returned but a new buffer is allocated.
- * In this case, if the length value is not zero, then
- * no more than that much space will be allocated.
- * If rvOpt is not null and the buffer pointer is not null,
- * then that buffer is re-used. No more than the buffer
- * length value will be used; if it's not enough, an
- * error is returned. If less is used, the number is
- * adjusted downwards.
- *
- * Note that although this is short of some ideal "Item"
- * definition, we can usually tell how big these buffers
- * have to be.
- *
- * Feedback is requested; and earlier is better than later.
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_ContinueDecrypt
-(
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FinishDecrypt
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishDecrypt
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_Sign
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_Sign
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_BeginSign
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_BeginSign
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_ContinueSign
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_ContinueSign
-(
- NSSCryptoContext *cc,
- NSSItem *data
-);
-
-/*
- * NSSCryptoContext_FinishSign
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishSign
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_SignRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_SignRecover
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_BeginSignRecover
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_BeginSignRecover
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_ContinueSignRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_ContinueSignRecover
-(
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FinishSignRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishSignRecover
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_UnwrapSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_UnwrapSymmetricKey
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_DeriveSymmetricKey
- *
- */
-
-NSS_EXTERN NSSSymmetricKey *
-NSSCryptoContext_DeriveSymmetricKey
-(
- NSSCryptoContext *cc,
- NSSPublicKey *bk,
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt, /* zero for best allowed */
- NSSOperations operations,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_Encrypt
- *
- * Encrypt a single chunk of data with the distinguished public key
- * of this crypto context.
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_Encrypt
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_BeginEncrypt
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_BeginEncrypt
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_ContinueEncrypt
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_ContinueEncrypt
-(
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FinishEncrypt
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishEncrypt
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_Verify
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_Verify
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_BeginVerify
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_BeginVerify
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_ContinueVerify
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_ContinueVerify
-(
- NSSCryptoContext *cc,
- NSSItem *data
-);
-
-/*
- * NSSCryptoContext_FinishVerify
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_FinishVerify
-(
- NSSCryptoContext *cc
-);
-
-/*
- * NSSCryptoContext_VerifyRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_VerifyRecover
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_BeginVerifyRecover
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_BeginVerifyRecover
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_ContinueVerifyRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_ContinueVerifyRecover
-(
- NSSCryptoContext *cc,
- NSSItem *data,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_FinishVerifyRecover
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishVerifyRecover
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_WrapSymmetricKey
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_WrapSymmetricKey
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_Digest
- *
- * Digest a single chunk of data with the distinguished digest key
- * of this crypto context.
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_Digest
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhhOpt,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * NSSCryptoContext_BeginDigest
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_BeginDigest
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhhOpt
-);
-
-/*
- * NSSCryptoContext_ContinueDigest
- *
- */
-
-NSS_EXTERN PRStatus
-NSSCryptoContext_ContinueDigest
-(
- NSSCryptoContext *cc,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *item
-);
-
-/*
- * NSSCryptoContext_FinishDigest
- *
- */
-
-NSS_EXTERN NSSItem *
-NSSCryptoContext_FinishDigest
-(
- NSSCryptoContext *cc,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-);
-
-/*
- * tbd: Combination ops
- */
-
-/*
- * NSSCryptoContext_Clone
- *
- */
-
-NSS_EXTERN NSSCryptoContext *
-NSSCryptoContext_Clone
-(
- NSSCryptoContext *cc
-);
-
-/*
- * NSSCryptoContext_Save
- * NSSCryptoContext_Restore
- *
- * We need to be able to save and restore the state of contexts.
- * Perhaps a mark-and-release mechanism would be better?
- */
-
-/*
- * ..._SignTBSCertificate
- *
- * This requires feedback from the cert server team.
- */
-
-/*
- * PRBool NSSCertificate_GetIsTrustedFor{xxx}(NSSCertificate *c);
- * PRStatus NSSCertificate_SetIsTrustedFor{xxx}(NSSCertificate *c, PRBool trusted);
- *
- * These will be helper functions which get the trust object for a cert,
- * and then call the corresponding function(s) on it.
- *
- * PKIX trust objects will have methods to manipulate the low-level trust
- * bits (which are based on key usage and extended key usage), and also the
- * conceptual high-level usages (e.g. ssl client auth, email encryption, etc.)
- *
- * Other types of trust objects (if any) might have different low-level
- * representations, but hopefully high-level concepts would map.
- *
- * Only these high-level general routines would be promoted to the
- * general certificate level here. Hence the {xxx} above would be things
- * like "EmailSigning."
- *
- *
- * NSSPKIXTrust *NSSCertificate_GetPKIXTrustObject(NSSCertificate *c);
- * PRStatus NSSCertificate_SetPKIXTrustObject(NSSCertificate *c, NSPKIXTrust *t);
- *
- * I want to hold off on any general trust object until we've investigated
- * other models more thoroughly.
- */
-
-PR_END_EXTERN_C
-
-#endif /* NSSPKI_H */
diff --git a/security/nss/lib/pki/nsspkit.h b/security/nss/lib/pki/nsspkit.h
deleted file mode 100644
index 4e186d9ba..000000000
--- a/security/nss/lib/pki/nsspkit.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSPKIT_H
-#define NSSPKIT_H
-
-#ifdef DEBUG
-static const char NSSPKIT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * nsspkit.h
- *
- * This file defines the types of the top-level PKI objects.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-PR_BEGIN_EXTERN_C
-
-/*
- * NSSCertificate
- *
- * This is the public representation of a Certificate. The certificate
- * may be one found on a smartcard or other token, one decoded from data
- * received as part of a protocol, one constructed from constituent
- * parts, etc. Usually it is associated with ("in") a trust domain; as
- * it can be verified only within a trust domain. The underlying type
- * of certificate may be of any supported standard, e.g. PKIX, PGP, etc.
- *
- * People speak of "verifying (with) the server's, or correspondant's,
- * certificate"; for simple operations we support that simplification
- * by implementing public-key crypto operations as methods on this type.
- */
-
-struct NSSCertificateStr;
-typedef struct NSSCertificateStr NSSCertificate;
-
-/*
- * NSSUserCertificate
- *
- * A ``User'' certificate is one for which the private key is available.
- * People speak of "using my certificate to sign my email" and "using
- * my certificate to authenticate to (or login to) the server"; for
- * simple operations, we support that simplification by implementing
- * private-key crypto operations as methods on this type.
- *
- * The current design only weakly distinguishes between certificates
- * and user certificates: as far as the compiler goes they're
- * interchangeable; debug libraries only have one common pointer-tracker;
- * etc. However, attempts to do private-key operations on a certificate
- * for which the private key is not available will fail.
- *
- * Open design question: should these types be more firmly separated?
- */
-
-typedef NSSCertificate NSSUserCertificate;
-
-/*
- * NSSPrivateKey
- *
- * This is the public representation of a Private Key. In general,
- * the actual value of the key is not available, but operations may
- * be performed with it.
- */
-
-struct NSSPrivateKeyStr;
-typedef struct NSSPrivateKeyStr NSSPrivateKey;
-
-/*
- * NSSPublicKey
- *
- */
-
-struct NSSPublicKeyStr;
-typedef struct NSSPublicKeyStr NSSPublicKey;
-
-/*
- * NSSSymmetricKey
- *
- */
-
-struct NSSSymmetricKeyStr;
-typedef struct NSSSymmetricKeyStr NSSSymmetricKey;
-
-/*
- * NSSTrustDomain
- *
- * A Trust Domain is the field in which certificates may be validated.
- * A trust domain will generally have one or more cryptographic modules
- * open; these modules perform the cryptographic operations, and
- * provide the basic "root" trust information from which the trust in
- * a specific certificate or key depends.
- *
- * A client program, or a simple server, would typically have one
- * trust domain. A server supporting multiple "virtual servers" might
- * have a separate trust domain for each virtual server. The separate
- * trust domains might share some modules (e.g., a hardware crypto
- * accelerator) but not others (e.g., the tokens storing the different
- * servers' private keys, or the databases with each server's trusted
- * root certificates).
- *
- * This object descends from the "permananet database" in the old code.
- */
-
-struct NSSTrustDomainStr;
-typedef struct NSSTrustDomainStr NSSTrustDomain;
-
-/*
- * NSSCryptoContext
- *
- * A Crypto Context is a short-term, "helper" object which is used
- * for the lifetime of one ongoing "crypto operation." Such an
- * operation may be the creation of a signed message, the use of an
- * TLS socket connection, etc. Each crypto context is "in" a
- * specific trust domain, and it may have associated with it a
- * distinguished certificate, public key, private key, and/or
- * symmetric key. It can also temporarily hold and use temporary
- * data (e.g. intermediate certificates) which is not stored
- * permanently in the trust domain.
- *
- * In OO terms, this interface inherits interfaces from the trust
- * domain, the certificates, and the keys. It also provides
- * streaming crypto operations.
- *
- * This object descends from the "temporary database" concept in the
- * old code, but it has changed a lot as a result of what we've
- * learned.
- */
-
-typedef struct NSSCryptoContextStr NSSCryptoContext;
-
-/*
- * fgmr others
- */
-
-/*
- * OBJECT IDENTIFIER
- *
- * This is the basic OID that crops up everywhere.
- */
-
-struct NSSOIDStr; /* unused opaque structure */
-typedef struct NSSOIDStr NSSOID;
-
-/*
- * NSSTime
- *
- * Unfortunately, we need an "exceptional" value to indicate
- * an error upon return, or "no value" on input. Note that zero
- * is a perfectly valid value for both time_t and PRTime.
- *
- * If we were to create a "range" object, with two times for
- * Not Before and Not After, we would have an obvious place for
- * the somewhat arbitrary logic involved in comparing them.
- *
- * Failing that, let's have an NSSTime_CompareRanges function.
- */
-
-struct NSSTimeStr;
-typedef struct NSSTimeStr NSSTime;
-
-struct NSSTrustStr;
-typedef struct NSSTrustStr NSSTrust;
-
-/*
- * NSSUsage
- *
- * This is trickier than originally planned; I'll write up a
- * doc on it.
- *
- * We'd still like nsspki.h to have a list of common usages,
- * e.g.:
- *
- * extern const NSSUsage *NSSUsage_ClientAuth;
- * extern const NSSUsage *NSSUsage_ServerAuth;
- * extern const NSSUsage *NSSUsage_SignEmail;
- * extern const NSSUsage *NSSUsage_EncryptEmail;
- * etc.
- */
-
-struct NSSUsageStr;
-typedef struct NSSUsageStr NSSUsage;
-
-/*
- * NSSPolicies
- *
- * Placeholder, for now.
- */
-
-struct NSSPoliciesStr;
-typedef struct NSSPoliciesStr NSSPolicies;
-
-/*
- * NSSAlgorithmAndParameters
- *
- * Algorithm is an OID
- * Parameters depend on the algorithm
- */
-
-struct NSSAlgorithmAndParametersStr;
-typedef struct NSSAlgorithmAndParametersStr NSSAlgorithmAndParameters;
-
-/*
- * NSSCallback
- *
- * At minimum, a "challenge" method and a closure argument.
- * Usually the challenge will just be prompting for a password.
- * How OO do we want to make it?
- */
-
-typedef struct NSSCallbackStr NSSCallback;
-
-struct NSSCallbackStr {
- /* Prompt for a password to initialize a slot. */
- PRStatus (* getInitPW)(NSSUTF8 *slotName, void *arg,
- NSSUTF8 **ssoPW, NSSUTF8 **userPW);
- /* Prompt for oldPW and newPW in order to change the
- * password on a slot.
- */
- PRStatus (* getNewPW)(NSSUTF8 *slotName, PRUint32 *retries, void *arg,
- NSSUTF8 **oldPW, NSSUTF8 **newPW);
- /* Prompt for slot password. */
- PRStatus (* getPW)(NSSUTF8 *slotName, PRUint32 *retries, void *arg,
- NSSUTF8 **password);
- void *arg;
-};
-
-/* set errors - user cancelled, ... */
-
-typedef PRUint32 NSSOperations;
-/* 1) Do we want these to be preprocessor definitions or constants? */
-/* 2) What is the correct and complete list? */
-
-#define NSSOperations_ENCRYPT 0x0001
-#define NSSOperations_DECRYPT 0x0002
-#define NSSOperations_WRAP 0x0004
-#define NSSOperations_UNWRAP 0x0008
-#define NSSOperations_SIGN 0x0010
-#define NSSOperations_SIGN_RECOVER 0x0020
-#define NSSOperations_VERIFY 0x0040
-#define NSSOperations_VERIFY_RECOVER 0x0080
-
-struct NSSPKIXCertificateStr;
-
-PR_END_EXTERN_C
-
-#endif /* NSSPKIT_H */
diff --git a/security/nss/lib/pki/pki.h b/security/nss/lib/pki/pki.h
deleted file mode 100644
index e836dd422..000000000
--- a/security/nss/lib/pki/pki.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef PKI_H
-#define PKI_H
-
-#ifdef DEBUG
-static const char PKI_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef NSSDEVT_H
-#include "nssdevt.h"
-#endif /* NSSDEVT_H */
-
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-#ifndef PKIT_H
-#include "pkit.h"
-#endif /* PKIT_H */
-
-PR_BEGIN_EXTERN_C
-
-NSS_EXTERN NSSCallback *
-nssTrustDomain_GetDefaultCallback
-(
- NSSTrustDomain *td,
- PRStatus *statusOpt
-);
-
-NSS_EXTERN NSSCertificate **
-nssTrustDomain_FindCertificatesBySubject
-(
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSTrust *
-nssTrustDomain_FindTrustForCertificate
-(
- NSSTrustDomain *td,
- NSSCertificate *c
-);
-
-NSS_EXTERN NSSCertificate *
-nssCertificate_AddRef
-(
- NSSCertificate *c
-);
-
-NSS_EXTERN PRStatus
-nssCertificate_Destroy
-(
- NSSCertificate *c
-);
-
-NSS_EXTERN NSSDER *
-nssCertificate_GetEncoding
-(
- NSSCertificate *c
-);
-
-NSS_EXTERN NSSDER *
-nssCertificate_GetIssuer
-(
- NSSCertificate *c
-);
-
-NSS_EXTERN NSSDER *
-nssCertificate_GetSerialNumber
-(
- NSSCertificate *c
-);
-
-NSS_EXTERN NSSDER *
-nssCertificate_GetSubject
-(
- NSSCertificate *c
-);
-
-/* Returns a copy, Caller must free using nss_ZFreeIf */
-NSS_EXTERN NSSUTF8 *
-nssCertificate_GetNickname
-(
- NSSCertificate *c,
- NSSToken *tokenOpt
-);
-
-NSS_EXTERN NSSASCII7 *
-nssCertificate_GetEmailAddress
-(
- NSSCertificate *c
-);
-
-NSS_EXTERN PRBool
-nssCertificate_IssuerAndSerialEqual
-(
- NSSCertificate *c1,
- NSSCertificate *c2
-);
-
-NSS_EXTERN NSSPrivateKey *
-nssPrivateKey_AddRef
-(
- NSSPrivateKey *vk
-);
-
-NSS_EXTERN PRStatus
-nssPrivateKey_Destroy
-(
- NSSPrivateKey *vk
-);
-
-NSS_EXTERN NSSItem *
-nssPrivateKey_GetID
-(
- NSSPrivateKey *vk
-);
-
-NSS_EXTERN NSSUTF8 *
-nssPrivateKey_GetNickname
-(
- NSSPrivateKey *vk,
- NSSToken *tokenOpt
-);
-
-NSS_EXTERN PRStatus
-nssPublicKey_Destroy
-(
- NSSPublicKey *bk
-);
-
-NSS_EXTERN NSSItem *
-nssPublicKey_GetID
-(
- NSSPublicKey *vk
-);
-
-NSS_EXTERN NSSCertificate **
-nssCryptoContext_FindCertificatesBySubject
-(
- NSSCryptoContext *cc,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/* putting here for now, needs more thought */
-NSS_EXTERN PRStatus
-nssCryptoContext_ImportTrust
-(
- NSSCryptoContext *cc,
- NSSTrust *trust
-);
-
-NSS_EXTERN NSSTrust *
-nssCryptoContext_FindTrustForCertificate
-(
- NSSCryptoContext *cc,
- NSSCertificate *cert
-);
-
-NSS_EXTERN PRStatus
-nssCryptoContext_ImportSMIMEProfile
-(
- NSSCryptoContext *cc,
- nssSMIMEProfile *profile
-);
-
-NSS_EXTERN nssSMIMEProfile *
-nssCryptoContext_FindSMIMEProfileForCertificate
-(
- NSSCryptoContext *cc,
- NSSCertificate *cert
-);
-
-NSS_EXTERN NSSTrust *
-nssTrust_AddRef
-(
- NSSTrust *trust
-);
-
-NSS_EXTERN PRStatus
-nssTrust_Destroy
-(
- NSSTrust *trust
-);
-
-NSS_EXTERN nssSMIMEProfile *
-nssSMIMEProfile_AddRef
-(
- nssSMIMEProfile *profile
-);
-
-NSS_EXTERN PRStatus
-nssSMIMEProfile_Destroy
-(
- nssSMIMEProfile *profile
-);
-
-NSS_EXTERN nssSMIMEProfile *
-nssSMIMEProfile_Create
-(
- NSSCertificate *cert,
- NSSItem *profileTime,
- NSSItem *profileData
-);
-
-PR_END_EXTERN_C
-
-#endif /* PKI_H */
diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c
deleted file mode 100644
index 3bccffb71..000000000
--- a/security/nss/lib/pki/pki3hack.c
+++ /dev/null
@@ -1,1435 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * Hacks to integrate NSS 3.4 and NSS 4.0 certificates.
- */
-
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-#ifndef PKI_H
-#include "pki.h"
-#endif /* PKI_H */
-
-#ifndef PKIM_H
-#include "pkim.h"
-#endif /* PKIM_H */
-
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
-#ifndef DEVNSS3HACK_H
-#include "dev3hack.h"
-#endif /* DEVNSS3HACK_H */
-
-#ifndef PKINSS3HACK_H
-#include "pki3hack.h"
-#endif /* PKINSS3HACK_H */
-
-#include "secitem.h"
-#include "certdb.h"
-#include "certt.h"
-#include "cert.h"
-#include "certi.h"
-#include "pk11func.h"
-#include "pkistore.h"
-#include "secmod.h"
-#include "nssrwlk.h"
-
-NSSTrustDomain *g_default_trust_domain = NULL;
-
-NSSCryptoContext *g_default_crypto_context = NULL;
-
-NSSTrustDomain *
-STAN_GetDefaultTrustDomain()
-{
- return g_default_trust_domain;
-}
-
-NSSCryptoContext *
-STAN_GetDefaultCryptoContext()
-{
- return g_default_crypto_context;
-}
-
-extern const NSSError NSS_ERROR_ALREADY_INITIALIZED;
-extern const NSSError NSS_ERROR_INTERNAL_ERROR;
-
-NSS_IMPLEMENT PRStatus
-STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot)
-{
- NSSToken *token;
- if (!td) {
- td = g_default_trust_domain;
- if (!td) {
- /* we're called while still initting. slot will get added
- * appropriately through normal init processes */
- return PR_SUCCESS;
- }
- }
- token = nssToken_CreateFromPK11SlotInfo(td, slot);
- PK11Slot_SetNSSToken(slot, token);
- /* Don't add nonexistent token to TD's token list */
- if (token) {
- NSSRWLock_LockWrite(td->tokensLock);
- nssList_Add(td->tokenList, token);
- NSSRWLock_UnlockWrite(td->tokensLock);
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-STAN_ResetTokenInterator(NSSTrustDomain *td)
-{
- if (!td) {
- td = g_default_trust_domain;
- if (!td) {
- /* we're called while still initting. slot will get added
- * appropriately through normal init processes */
- return PR_SUCCESS;
- }
- }
- NSSRWLock_LockWrite(td->tokensLock);
- nssListIterator_Destroy(td->tokens);
- td->tokens = nssList_CreateIterator(td->tokenList);
- NSSRWLock_UnlockWrite(td->tokensLock);
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-STAN_LoadDefaultNSS3TrustDomain (
- void
-)
-{
- NSSTrustDomain *td;
- SECMODModuleList *mlp;
- SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
- int i;
-
- if (g_default_trust_domain || g_default_crypto_context) {
- /* Stan is already initialized or a previous shutdown failed. */
- nss_SetError(NSS_ERROR_ALREADY_INITIALIZED);
- return PR_FAILURE;
- }
- td = NSSTrustDomain_Create(NULL, NULL, NULL, NULL);
- if (!td) {
- return PR_FAILURE;
- }
- /*
- * Deadlock warning: we should never acquire the moduleLock while
- * we hold the tokensLock. We can use the NSSRWLock Rank feature to
- * guarrentee this. tokensLock have a higher rank than module lock.
- */
- td->tokenList = nssList_Create(td->arena, PR_TRUE);
- if (!td->tokenList) {
- goto loser;
- }
- SECMOD_GetReadLock(moduleLock);
- NSSRWLock_LockWrite(td->tokensLock);
- for (mlp = SECMOD_GetDefaultModuleList(); mlp != NULL; mlp=mlp->next) {
- for (i=0; i < mlp->module->slotCount; i++) {
- STAN_InitTokenForSlotInfo(td, mlp->module->slots[i]);
- }
- }
- td->tokens = nssList_CreateIterator(td->tokenList);
- NSSRWLock_UnlockWrite(td->tokensLock);
- SECMOD_ReleaseReadLock(moduleLock);
- if (!td->tokens) {
- goto loser;
- }
- g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
- if (!g_default_crypto_context) {
- goto loser;
- }
- g_default_trust_domain = td;
- return PR_SUCCESS;
-
- loser:
- NSSTrustDomain_Destroy(td);
- return PR_FAILURE;
-}
-
-/*
- * must be called holding the ModuleListLock (either read or write).
- */
-NSS_IMPLEMENT SECStatus
-STAN_AddModuleToDefaultTrustDomain (
- SECMODModule *module
-)
-{
- NSSTrustDomain *td;
- int i;
- td = STAN_GetDefaultTrustDomain();
- for (i=0; i<module->slotCount; i++) {
- STAN_InitTokenForSlotInfo(td, module->slots[i]);
- }
- STAN_ResetTokenInterator(td);
- return SECSuccess;
-}
-
-/*
- * must be called holding the ModuleListLock (either read or write).
- */
-NSS_IMPLEMENT SECStatus
-STAN_RemoveModuleFromDefaultTrustDomain (
- SECMODModule *module
-)
-{
- NSSToken *token;
- NSSTrustDomain *td;
- int i;
- td = STAN_GetDefaultTrustDomain();
- NSSRWLock_LockWrite(td->tokensLock);
- for (i=0; i<module->slotCount; i++) {
- token = PK11Slot_GetNSSToken(module->slots[i]);
- if (token) {
- nssToken_NotifyCertsNotVisible(token);
- nssList_Remove(td->tokenList, token);
- PK11Slot_SetNSSToken(module->slots[i], NULL);
- nssToken_Destroy(token);
- }
- }
- nssListIterator_Destroy(td->tokens);
- td->tokens = nssList_CreateIterator(td->tokenList);
- NSSRWLock_UnlockWrite(td->tokensLock);
- return SECSuccess;
-}
-
-NSS_IMPLEMENT PRStatus
-STAN_Shutdown()
-{
- PRStatus status = PR_SUCCESS;
- if (g_default_trust_domain) {
- if (NSSTrustDomain_Destroy(g_default_trust_domain) == PR_SUCCESS) {
- g_default_trust_domain = NULL;
- } else {
- status = PR_FAILURE;
- }
- }
- if (g_default_crypto_context) {
- if (NSSCryptoContext_Destroy(g_default_crypto_context) == PR_SUCCESS) {
- g_default_crypto_context = NULL;
- } else {
- status = PR_FAILURE;
- }
- }
- return status;
-}
-
-/* this function should not be a hack; it will be needed in 4.0 (rename) */
-NSS_IMPLEMENT NSSItem *
-STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der)
-{
- NSSItem *rvKey;
- SECItem secDER;
- SECItem secKey = { 0 };
- SECStatus secrv;
- PRArenaPool *arena;
-
- SECITEM_FROM_NSSITEM(&secDER, der);
-
- /* nss3 call uses nss3 arena's */
- arena = PORT_NewArena(256);
- if (!arena) {
- return NULL;
- }
- secrv = CERT_KeyFromDERCert(arena, &secDER, &secKey);
- if (secrv != SECSuccess) {
- return NULL;
- }
- rvKey = nssItem_Create(arenaOpt, NULL, secKey.len, (void *)secKey.data);
- PORT_FreeArena(arena,PR_FALSE);
- return rvKey;
-}
-
-NSS_IMPLEMENT PRStatus
-nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena,
- NSSDER *issuer, NSSDER *serial)
-{
- SECStatus secrv;
- SECItem derCert;
- SECItem derIssuer = { 0 };
- SECItem derSerial = { 0 };
- SECITEM_FROM_NSSITEM(&derCert, der);
- secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
- if (secrv != SECSuccess) {
- return PR_FAILURE;
- }
- (void)nssItem_Create(arena, serial, derSerial.len, derSerial.data);
- secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
- if (secrv != SECSuccess) {
- PORT_Free(derSerial.data);
- return PR_FAILURE;
- }
- (void)nssItem_Create(arena, issuer, derIssuer.len, derIssuer.data);
- PORT_Free(derSerial.data);
- PORT_Free(derIssuer.data);
- return PR_SUCCESS;
-}
-
-static NSSItem *
-nss3certificate_getIdentifier(nssDecodedCert *dc)
-{
- NSSItem *rvID;
- CERTCertificate *c = (CERTCertificate *)dc->data;
- rvID = nssItem_Create(NULL, NULL, c->certKey.len, c->certKey.data);
- return rvID;
-}
-
-static void *
-nss3certificate_getIssuerIdentifier(nssDecodedCert *dc)
-{
- CERTCertificate *c = (CERTCertificate *)dc->data;
- return (void *)c->authKeyID;
-}
-
-static nssCertIDMatch
-nss3certificate_matchIdentifier(nssDecodedCert *dc, void *id)
-{
- CERTCertificate *c = (CERTCertificate *)dc->data;
- CERTAuthKeyID *authKeyID = (CERTAuthKeyID *)id;
- SECItem skid;
- nssCertIDMatch match = nssCertIDMatch_Unknown;
-
- /* keyIdentifier */
- if (authKeyID->keyID.len > 0 &&
- CERT_FindSubjectKeyIDExtension(c, &skid) == SECSuccess) {
- PRBool skiEqual;
- skiEqual = SECITEM_ItemsAreEqual(&authKeyID->keyID, &skid);
- PORT_Free(skid.data);
- if (skiEqual) {
- /* change the state to positive match, but keep going */
- match = nssCertIDMatch_Yes;
- } else {
- /* exit immediately on failure */
- return nssCertIDMatch_No;
- }
- }
-
- /* issuer/serial (treated as pair) */
- if (authKeyID->authCertIssuer) {
- SECItem *caName = NULL;
- SECItem *caSN = &authKeyID->authCertSerialNumber;
-
- caName = (SECItem *)CERT_GetGeneralNameByType(
- authKeyID->authCertIssuer,
- certDirectoryName, PR_TRUE);
- if (caName != NULL &&
- SECITEM_ItemsAreEqual(&c->derIssuer, caName) &&
- SECITEM_ItemsAreEqual(&c->serialNumber, caSN))
- {
- match = nssCertIDMatch_Yes;
- } else {
- match = nssCertIDMatch_Unknown;
- }
- }
- return match;
-}
-
-static PRBool
-nss3certificate_isValidIssuer(nssDecodedCert *dc)
-{
- CERTCertificate *c = (CERTCertificate *)dc->data;
- unsigned int ignore;
- return CERT_IsCACert(c, &ignore);
-}
-
-static NSSUsage *
-nss3certificate_getUsage(nssDecodedCert *dc)
-{
- /* CERTCertificate *c = (CERTCertificate *)dc->data; */
- return NULL;
-}
-
-static PRBool
-nss3certificate_isValidAtTime(nssDecodedCert *dc, NSSTime *time)
-{
- SECCertTimeValidity validity;
- CERTCertificate *c = (CERTCertificate *)dc->data;
- validity = CERT_CheckCertValidTimes(c, NSSTime_GetPRTime(time), PR_TRUE);
- if (validity == secCertTimeValid) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-static PRBool
-nss3certificate_isNewerThan(nssDecodedCert *dc, nssDecodedCert *cmpdc)
-{
- /* I know this isn't right, but this is glue code anyway */
- if (cmpdc->type == dc->type) {
- CERTCertificate *certa = (CERTCertificate *)dc->data;
- CERTCertificate *certb = (CERTCertificate *)cmpdc->data;
- return CERT_IsNewer(certa, certb);
- }
- return PR_FALSE;
-}
-
-/* CERT_FilterCertListByUsage */
-static PRBool
-nss3certificate_matchUsage(nssDecodedCert *dc, const NSSUsage *usage)
-{
- CERTCertificate *cc;
- unsigned int requiredKeyUsage = 0;
- unsigned int requiredCertType = 0;
- SECStatus secrv;
- PRBool match;
- PRBool ca;
-
- /* This is for NSS 3.3 functions that do not specify a usage */
- if (usage->anyUsage) {
- return PR_TRUE;
- }
- ca = usage->nss3lookingForCA;
- secrv = CERT_KeyUsageAndTypeForCertUsage(usage->nss3usage, ca,
- &requiredKeyUsage,
- &requiredCertType);
- if (secrv != SECSuccess) {
- return PR_FALSE;
- }
- cc = (CERTCertificate *)dc->data;
- secrv = CERT_CheckKeyUsage(cc, requiredKeyUsage);
- match = (PRBool)(secrv == SECSuccess);
- if (match) {
- unsigned int certType = 0;
- if (ca) {
- (void)CERT_IsCACert(cc, &certType);
- } else {
- certType = cc->nsCertType;
- }
- if (!(certType & requiredCertType)) {
- match = PR_FALSE;
- }
- }
- return match;
-}
-
-static PRBool
-nss3certificate_isTrustedForUsage(nssDecodedCert *dc, const NSSUsage *usage)
-{
- CERTCertificate *cc;
- PRBool ca;
- SECStatus secrv;
- unsigned int requiredFlags;
- unsigned int trustFlags;
- SECTrustType trustType;
- CERTCertTrust trust;
-
- /* This is for NSS 3.3 functions that do not specify a usage */
- if (usage->anyUsage) {
- return PR_FALSE; /* XXX is this right? */
- }
- cc = (CERTCertificate *)dc->data;
- ca = usage->nss3lookingForCA;
- if (!ca) {
- PRBool trusted;
- unsigned int failedFlags;
- secrv = cert_CheckLeafTrust(cc, usage->nss3usage,
- &failedFlags, &trusted);
- return secrv == SECSuccess && trusted;
- }
- secrv = CERT_TrustFlagsForCACertUsage(usage->nss3usage, &requiredFlags,
- &trustType);
- if (secrv != SECSuccess) {
- return PR_FALSE;
- }
- secrv = CERT_GetCertTrust(cc, &trust);
- if (secrv != SECSuccess) {
- return PR_FALSE;
- }
- if (trustType == trustTypeNone) {
- /* normally trustTypeNone usages accept any of the given trust bits
- * being on as acceptable. */
- trustFlags = trust.sslFlags | trust.emailFlags |
- trust.objectSigningFlags;
- } else {
- trustFlags = SEC_GET_TRUST_FLAGS(&trust, trustType);
- }
- return (trustFlags & requiredFlags) == requiredFlags;
-}
-
-static NSSASCII7 *
-nss3certificate_getEmailAddress(nssDecodedCert *dc)
-{
- CERTCertificate *cc = (CERTCertificate *)dc->data;
- return (cc && cc->emailAddr && cc->emailAddr[0])
- ? (NSSASCII7 *)cc->emailAddr : NULL;
-}
-
-static PRStatus
-nss3certificate_getDERSerialNumber(nssDecodedCert *dc,
- NSSDER *serial, NSSArena *arena)
-{
- CERTCertificate *cc = (CERTCertificate *)dc->data;
- SECItem derSerial = { 0 };
- SECStatus secrv;
- secrv = CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
- if (secrv == SECSuccess) {
- (void)nssItem_Create(arena, serial, derSerial.len, derSerial.data);
- PORT_Free(derSerial.data);
- return PR_SUCCESS;
- }
- return PR_FAILURE;
-}
-
-/* Returns NULL if "encoding" cannot be decoded. */
-NSS_IMPLEMENT nssDecodedCert *
-nssDecodedPKIXCertificate_Create (
- NSSArena *arenaOpt,
- NSSDER *encoding
-)
-{
- nssDecodedCert *rvDC = NULL;
- CERTCertificate *cert;
- SECItem secDER;
-
- SECITEM_FROM_NSSITEM(&secDER, encoding);
- cert = CERT_DecodeDERCertificate(&secDER, PR_TRUE, NULL);
- if (cert) {
- rvDC = nss_ZNEW(arenaOpt, nssDecodedCert);
- if (rvDC) {
- rvDC->type = NSSCertificateType_PKIX;
- rvDC->data = (void *)cert;
- rvDC->getIdentifier = nss3certificate_getIdentifier;
- rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
- rvDC->matchIdentifier = nss3certificate_matchIdentifier;
- rvDC->isValidIssuer = nss3certificate_isValidIssuer;
- rvDC->getUsage = nss3certificate_getUsage;
- rvDC->isValidAtTime = nss3certificate_isValidAtTime;
- rvDC->isNewerThan = nss3certificate_isNewerThan;
- rvDC->matchUsage = nss3certificate_matchUsage;
- rvDC->isTrustedForUsage = nss3certificate_isTrustedForUsage;
- rvDC->getEmailAddress = nss3certificate_getEmailAddress;
- rvDC->getDERSerialNumber = nss3certificate_getDERSerialNumber;
- } else {
- CERT_DestroyCertificate(cert);
- }
- }
- return rvDC;
-}
-
-static nssDecodedCert *
-create_decoded_pkix_cert_from_nss3cert (
- NSSArena *arenaOpt,
- CERTCertificate *cc
-)
-{
- nssDecodedCert *rvDC = nss_ZNEW(arenaOpt, nssDecodedCert);
- if (rvDC) {
- rvDC->type = NSSCertificateType_PKIX;
- rvDC->data = (void *)cc;
- rvDC->getIdentifier = nss3certificate_getIdentifier;
- rvDC->getIssuerIdentifier = nss3certificate_getIssuerIdentifier;
- rvDC->matchIdentifier = nss3certificate_matchIdentifier;
- rvDC->isValidIssuer = nss3certificate_isValidIssuer;
- rvDC->getUsage = nss3certificate_getUsage;
- rvDC->isValidAtTime = nss3certificate_isValidAtTime;
- rvDC->isNewerThan = nss3certificate_isNewerThan;
- rvDC->matchUsage = nss3certificate_matchUsage;
- rvDC->isTrustedForUsage = nss3certificate_isTrustedForUsage;
- rvDC->getEmailAddress = nss3certificate_getEmailAddress;
- rvDC->getDERSerialNumber = nss3certificate_getDERSerialNumber;
- }
- return rvDC;
-}
-
-NSS_IMPLEMENT PRStatus
-nssDecodedPKIXCertificate_Destroy (
- nssDecodedCert *dc
-)
-{
- CERTCertificate *cert = (CERTCertificate *)dc->data;
-
- /* The decoder may only be half initialized (the case where we find we
- * could not decode the certificate). In this case, there is not cert to
- * free, just free the dc structure. */
- if (cert) {
- PRBool freeSlot = cert->ownSlot;
- PK11SlotInfo *slot = cert->slot;
- PRArenaPool *arena = cert->arena;
- /* zero cert before freeing. Any stale references to this cert
- * after this point will probably cause an exception. */
- PORT_Memset(cert, 0, sizeof *cert);
- /* free the arena that contains the cert. */
- PORT_FreeArena(arena, PR_FALSE);
- if (slot && freeSlot) {
- PK11_FreeSlot(slot);
- }
- }
- nss_ZFreeIf(dc);
- return PR_SUCCESS;
-}
-
-/* see pk11cert.c:pk11_HandleTrustObject */
-static unsigned int
-get_nss3trust_from_nss4trust(nssTrustLevel t)
-{
- unsigned int rt = 0;
- if (t == nssTrustLevel_Trusted) {
- rt |= CERTDB_TERMINAL_RECORD | CERTDB_TRUSTED;
- }
- if (t == nssTrustLevel_TrustedDelegator) {
- rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA;
- }
- if (t == nssTrustLevel_NotTrusted) {
- rt |= CERTDB_TERMINAL_RECORD;
- }
- if (t == nssTrustLevel_ValidDelegator) {
- rt |= CERTDB_VALID_CA;
- }
- return rt;
-}
-
-static CERTCertTrust *
-cert_trust_from_stan_trust(NSSTrust *t, PRArenaPool *arena)
-{
- CERTCertTrust *rvTrust;
- unsigned int client;
- if (!t) {
- return NULL;
- }
- rvTrust = PORT_ArenaAlloc(arena, sizeof(CERTCertTrust));
- if (!rvTrust) return NULL;
- rvTrust->sslFlags = get_nss3trust_from_nss4trust(t->serverAuth);
- client = get_nss3trust_from_nss4trust(t->clientAuth);
- if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) {
- client &= ~(CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA);
- rvTrust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA;
- }
- rvTrust->sslFlags |= client;
- rvTrust->emailFlags = get_nss3trust_from_nss4trust(t->emailProtection);
- rvTrust->objectSigningFlags = get_nss3trust_from_nss4trust(t->codeSigning);
- return rvTrust;
-}
-
-CERTCertTrust *
-nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
-{
- CERTCertTrust *rvTrust = NULL;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSTrust *t;
- t = nssTrustDomain_FindTrustForCertificate(td, c);
- if (t) {
- rvTrust = cert_trust_from_stan_trust(t, cc->arena);
- if (!rvTrust) {
- nssTrust_Destroy(t);
- return NULL;
- }
- nssTrust_Destroy(t);
- } else {
- rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
- if (!rvTrust) {
- return NULL;
- }
- memset(rvTrust, 0, sizeof(*rvTrust));
- }
- if (NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL)) {
- rvTrust->sslFlags |= CERTDB_USER;
- rvTrust->emailFlags |= CERTDB_USER;
- rvTrust->objectSigningFlags |= CERTDB_USER;
- }
- return rvTrust;
-}
-
-static nssCryptokiInstance *
-get_cert_instance(NSSCertificate *c)
-{
- nssCryptokiObject *instance, **ci;
- nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
- if (!instances) {
- return NULL;
- }
- instance = NULL;
- for (ci = instances; *ci; ci++) {
- if (!instance) {
- instance = nssCryptokiObject_Clone(*ci);
- } else {
- /* This only really works for two instances... But 3.4 can't
- * handle more anyway. The logic is, if there are multiple
- * instances, prefer the one that is not internal (e.g., on
- * a hardware device.
- */
- if (PK11_IsInternal(instance->token->pk11slot)) {
- nssCryptokiObject_Destroy(instance);
- instance = nssCryptokiObject_Clone(*ci);
- }
- }
- }
- nssCryptokiObjectArray_Destroy(instances);
- return instance;
-}
-
-char *
-STAN_GetCERTCertificateNameForInstance (
- PLArenaPool *arenaOpt,
- NSSCertificate *c,
- nssCryptokiInstance *instance
-)
-{
- NSSCryptoContext *context = c->object.cryptoContext;
- PRStatus nssrv;
- int nicklen, tokenlen, len;
- NSSUTF8 *tokenName = NULL;
- NSSUTF8 *stanNick = NULL;
- char *nickname = NULL;
- char *nick;
-
- if (instance) {
- stanNick = instance->label;
- } else if (context) {
- stanNick = c->object.tempName;
- }
- if (stanNick) {
- /* fill other fields needed by NSS3 functions using CERTCertificate */
- if (instance && (!PK11_IsInternalKeySlot(instance->token->pk11slot) ||
- PORT_Strchr(stanNick, ':') != NULL) ) {
- tokenName = nssToken_GetName(instance->token);
- tokenlen = nssUTF8_Size(tokenName, &nssrv);
- } else {
- /* don't use token name for internal slot; 3.3 didn't */
- tokenlen = 0;
- }
- nicklen = nssUTF8_Size(stanNick, &nssrv);
- len = tokenlen + nicklen;
- if (arenaOpt) {
- nickname = PORT_ArenaAlloc(arenaOpt, len);
- } else {
- nickname = PORT_Alloc(len);
- }
- nick = nickname;
- if (tokenName) {
- memcpy(nick, tokenName, tokenlen-1);
- nick += tokenlen-1;
- *nick++ = ':';
- }
- memcpy(nick, stanNick, nicklen-1);
- nickname[len-1] = '\0';
- }
- return nickname;
-}
-
-char *
-STAN_GetCERTCertificateName(PLArenaPool *arenaOpt, NSSCertificate *c)
-{
- char * result;
- nssCryptokiInstance *instance = get_cert_instance(c);
- /* It's OK to call this function, even if instance is NULL */
- result = STAN_GetCERTCertificateNameForInstance(arenaOpt, c, instance);
- if (instance)
- nssCryptokiObject_Destroy(instance);
- return result;
-}
-
-static void
-fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced)
-{
- CERTCertTrust* trust = NULL;
- NSSTrust *nssTrust;
- NSSCryptoContext *context = c->object.cryptoContext;
- nssCryptokiInstance *instance;
- NSSUTF8 *stanNick = NULL;
-
- /* We are holding the base class object's lock on entry of this function
- * This lock protects writes to fields of the CERTCertificate .
- * It is also needed by some functions to compute values such as trust.
- */
- instance = get_cert_instance(c);
-
- if (instance) {
- stanNick = instance->label;
- } else if (context) {
- stanNick = c->object.tempName;
- }
- /* fill other fields needed by NSS3 functions using CERTCertificate */
- if ((!cc->nickname && stanNick) || forced) {
- PRStatus nssrv;
- int nicklen, tokenlen, len;
- NSSUTF8 *tokenName = NULL;
- char *nick;
- if (instance &&
- (!PK11_IsInternalKeySlot(instance->token->pk11slot) ||
- (stanNick && PORT_Strchr(stanNick, ':') != NULL))) {
- tokenName = nssToken_GetName(instance->token);
- tokenlen = nssUTF8_Size(tokenName, &nssrv);
- } else {
- /* don't use token name for internal slot; 3.3 didn't */
- tokenlen = 0;
- }
- if (stanNick) {
- nicklen = nssUTF8_Size(stanNick, &nssrv);
- len = tokenlen + nicklen;
- nick = PORT_ArenaAlloc(cc->arena, len);
- if (tokenName) {
- memcpy(nick, tokenName, tokenlen-1);
- nick[tokenlen-1] = ':';
- memcpy(nick+tokenlen, stanNick, nicklen-1);
- } else {
- memcpy(nick, stanNick, nicklen-1);
- }
- nick[len-1] = '\0';
- cc->nickname = nick;
- } else {
- cc->nickname = NULL;
- }
- }
- if (context) {
- /* trust */
- nssTrust = nssCryptoContext_FindTrustForCertificate(context, c);
- if (!nssTrust) {
- /* chicken and egg issue:
- *
- * c->issuer and c->serial are empty at this point, but
- * nssTrustDomain_FindTrustForCertificate use them to look up
- * up the trust object, so we point them to cc->derIssuer and
- * cc->serialNumber.
- *
- * Our caller will fill these in with proper arena copies when we
- * return. */
- c->issuer.data = cc->derIssuer.data;
- c->issuer.size = cc->derIssuer.len;
- c->serial.data = cc->serialNumber.data;
- c->serial.size = cc->serialNumber.len;
- nssTrust = nssTrustDomain_FindTrustForCertificate(context->td, c);
- }
- if (nssTrust) {
- trust = cert_trust_from_stan_trust(nssTrust, cc->arena);
- if (trust) {
- /* we should destroy cc->trust before replacing it, but it's
- allocated in cc->arena, so memory growth will occur on each
- refresh */
- CERT_LockCertTrust(cc);
- cc->trust = trust;
- CERT_UnlockCertTrust(cc);
- }
- nssTrust_Destroy(nssTrust);
- }
- } else if (instance) {
- /* slot */
- if (cc->slot != instance->token->pk11slot) {
- if (cc->slot) {
- PK11_FreeSlot(cc->slot);
- }
- cc->slot = PK11_ReferenceSlot(instance->token->pk11slot);
- }
- cc->ownSlot = PR_TRUE;
- /* pkcs11ID */
- cc->pkcs11ID = instance->handle;
- /* trust */
- trust = nssTrust_GetCERTCertTrustForCert(c, cc);
- if (trust) {
- /* we should destroy cc->trust before replacing it, but it's
- allocated in cc->arena, so memory growth will occur on each
- refresh */
- CERT_LockCertTrust(cc);
- cc->trust = trust;
- CERT_UnlockCertTrust(cc);
- }
- nssCryptokiObject_Destroy(instance);
- }
- /* database handle is now the trust domain */
- cc->dbhandle = c->object.trustDomain;
- /* subjectList ? */
- /* istemp and isperm are supported in NSS 3.4 */
- cc->istemp = PR_FALSE; /* CERT_NewTemp will override this */
- cc->isperm = PR_TRUE; /* by default */
- /* pointer back */
- cc->nssCertificate = c;
- if (trust) {
- /* force the cert type to be recomputed to include trust info */
- PRUint32 nsCertType = cert_ComputeCertType(cc);
-
- /* Assert that it is safe to cast &cc->nsCertType to "PRInt32 *" */
- PORT_Assert(sizeof(cc->nsCertType) == sizeof(PRInt32));
- PR_ATOMIC_SET((PRInt32 *)&cc->nsCertType, nsCertType);
- }
-}
-
-static CERTCertificate *
-stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
-{
- nssDecodedCert *dc = NULL;
- CERTCertificate *cc = NULL;
- CERTCertTrust certTrust;
-
- nssPKIObject_Lock(&c->object);
-
- dc = c->decoding;
- if (!dc) {
- dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding);
- if (!dc) {
- goto loser;
- }
- cc = (CERTCertificate *)dc->data;
- PORT_Assert(cc); /* software error */
- if (!cc) {
- nssDecodedPKIXCertificate_Destroy(dc);
- nss_SetError(NSS_ERROR_INTERNAL_ERROR);
- goto loser;
- }
- PORT_Assert(!c->decoding);
- if (!c->decoding) {
- c->decoding = dc;
- } else {
- /* this should never happen. Fail. */
- nssDecodedPKIXCertificate_Destroy(dc);
- nss_SetError(NSS_ERROR_INTERNAL_ERROR);
- goto loser;
- }
- }
- cc = (CERTCertificate *)dc->data;
- PORT_Assert(cc);
- if (!cc) {
- nss_SetError(NSS_ERROR_INTERNAL_ERROR);
- goto loser;
- }
- if (!cc->nssCertificate || forceUpdate) {
- fill_CERTCertificateFields(c, cc, forceUpdate);
- } else if (CERT_GetCertTrust(cc, &certTrust) != SECSuccess &&
- !c->object.cryptoContext) {
- /* if it's a perm cert, it might have been stored before the
- * trust, so look for the trust again. But a temp cert can be
- * ignored.
- */
- CERTCertTrust* trust = NULL;
- trust = nssTrust_GetCERTCertTrustForCert(c, cc);
-
- CERT_LockCertTrust(cc);
- cc->trust = trust;
- CERT_UnlockCertTrust(cc);
- }
-
- loser:
- nssPKIObject_Unlock(&c->object);
- return cc;
-}
-
-NSS_IMPLEMENT CERTCertificate *
-STAN_ForceCERTCertificateUpdate(NSSCertificate *c)
-{
- if (c->decoding) {
- return stan_GetCERTCertificate(c, PR_TRUE);
- }
- return NULL;
-}
-
-NSS_IMPLEMENT CERTCertificate *
-STAN_GetCERTCertificate(NSSCertificate *c)
-{
- return stan_GetCERTCertificate(c, PR_FALSE);
-}
-/*
- * many callers of STAN_GetCERTCertificate() intend that
- * the CERTCertificate returned inherits the reference to the
- * NSSCertificate. For these callers it's convenient to have
- * this function 'own' the reference and either return a valid
- * CERTCertificate structure which inherits the reference or
- * destroy the reference to NSSCertificate and returns NULL.
- */
-NSS_IMPLEMENT CERTCertificate *
-STAN_GetCERTCertificateOrRelease(NSSCertificate *c)
-{
- CERTCertificate *nss3cert = stan_GetCERTCertificate(c, PR_FALSE);
- if (!nss3cert) {
- nssCertificate_Destroy(c);
- }
- return nss3cert;
-}
-
-static nssTrustLevel
-get_stan_trust(unsigned int t, PRBool isClientAuth)
-{
- if (isClientAuth) {
- if (t & CERTDB_TRUSTED_CLIENT_CA) {
- return nssTrustLevel_TrustedDelegator;
- }
- } else {
- if (t & CERTDB_TRUSTED_CA || t & CERTDB_NS_TRUSTED_CA) {
- return nssTrustLevel_TrustedDelegator;
- }
- }
- if (t & CERTDB_TRUSTED) {
- return nssTrustLevel_Trusted;
- }
- if (t & CERTDB_TERMINAL_RECORD) {
- return nssTrustLevel_NotTrusted;
- }
- if (t & CERTDB_VALID_CA) {
- return nssTrustLevel_ValidDelegator;
- }
- return nssTrustLevel_MustVerify;
-}
-
-NSS_EXTERN NSSCertificate *
-STAN_GetNSSCertificate(CERTCertificate *cc)
-{
- NSSCertificate *c;
- nssCryptokiInstance *instance;
- nssPKIObject *pkiob;
- NSSArena *arena;
- c = cc->nssCertificate;
- if (c) {
- return c;
- }
- /* i don't think this should happen. but if it can, need to create
- * NSSCertificate from CERTCertificate values here. */
- /* Yup, it can happen. */
- arena = NSSArena_Create();
- if (!arena) {
- return NULL;
- }
- c = nss_ZNEW(arena, NSSCertificate);
- if (!c) {
- nssArena_Destroy(arena);
- return NULL;
- }
- NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert);
- c->type = NSSCertificateType_PKIX;
- pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKIMonitor);
- if (!pkiob) {
- nssArena_Destroy(arena);
- return NULL;
- }
- c->object = *pkiob;
- nssItem_Create(arena,
- &c->issuer, cc->derIssuer.len, cc->derIssuer.data);
- nssItem_Create(arena,
- &c->subject, cc->derSubject.len, cc->derSubject.data);
- if (PR_TRUE) {
- /* CERTCertificate stores serial numbers decoded. I need the DER
- * here. sigh.
- */
- SECItem derSerial;
- SECStatus secrv;
- secrv = CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
- if (secrv == SECFailure) {
- nssArena_Destroy(arena);
- return NULL;
- }
- nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data);
- PORT_Free(derSerial.data);
- }
- if (cc->emailAddr && cc->emailAddr[0]) {
- c->email = nssUTF8_Create(arena,
- nssStringType_PrintableString,
- (NSSUTF8 *)cc->emailAddr,
- PORT_Strlen(cc->emailAddr));
- }
- if (cc->slot) {
- instance = nss_ZNEW(arena, nssCryptokiInstance);
- if (!instance) {
- nssArena_Destroy(arena);
- return NULL;
- }
- instance->token = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot));
- instance->handle = cc->pkcs11ID;
- instance->isTokenObject = PR_TRUE;
- if (cc->nickname) {
- instance->label = nssUTF8_Create(arena,
- nssStringType_UTF8String,
- (NSSUTF8 *)cc->nickname,
- PORT_Strlen(cc->nickname));
- }
- nssPKIObject_AddInstance(&c->object, instance);
- }
- c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc);
- cc->nssCertificate = c;
- return c;
-}
-
-static NSSToken*
-stan_GetTrustToken (
- NSSCertificate *c
-)
-{
- NSSToken *ttok = NULL;
- NSSToken *rtok = NULL;
- NSSToken *tok = NULL;
- nssCryptokiObject **ip;
- nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
- if (!instances) {
- return PR_FALSE;
- }
- for (ip = instances; *ip; ip++) {
- nssCryptokiObject *instance = *ip;
- nssCryptokiObject *to =
- nssToken_FindTrustForCertificate(instance->token, NULL,
- &c->encoding, &c->issuer, &c->serial,
- nssTokenSearchType_TokenOnly);
- NSSToken *ctok = instance->token;
- PRBool ro = PK11_IsReadOnly(ctok->pk11slot);
-
- if (to) {
- nssCryptokiObject_Destroy(to);
- ttok = ctok;
- if (!ro) {
- break;
- }
- } else {
- if (!rtok && ro) {
- rtok = ctok;
- }
- if (!tok && !ro) {
- tok = ctok;
- }
- }
- }
- nssCryptokiObjectArray_Destroy(instances);
- return ttok ? ttok : (tok ? tok : rtok);
-}
-
-NSS_EXTERN PRStatus
-STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
-{
- PRStatus nssrv;
- NSSCertificate *c = STAN_GetNSSCertificate(cc);
- NSSToken *tok;
- NSSTrustDomain *td;
- NSSTrust *nssTrust;
- NSSArena *arena;
- CERTCertTrust *oldTrust;
- CERTCertTrust *newTrust;
- nssListIterator *tokens;
- PRBool moving_object;
- nssCryptokiObject *newInstance;
- nssPKIObject *pkiob;
-
- if (c == NULL) {
- return PR_FAILURE;
- }
- oldTrust = nssTrust_GetCERTCertTrustForCert(c, cc);
- if (oldTrust) {
- if (memcmp(oldTrust, trust, sizeof (CERTCertTrust)) == 0) {
- /* ... and the new trust is no different, done) */
- return PR_SUCCESS;
- } else {
- /* take over memory already allocated in cc's arena */
- newTrust = oldTrust;
- }
- } else {
- newTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
- }
- memcpy(newTrust, trust, sizeof(CERTCertTrust));
- CERT_LockCertTrust(cc);
- cc->trust = newTrust;
- CERT_UnlockCertTrust(cc);
- /* Set the NSSCerticate's trust */
- arena = nssArena_Create();
- if (!arena) return PR_FAILURE;
- nssTrust = nss_ZNEW(arena, NSSTrust);
- if (!nssTrust) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
- }
- pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKILock);
- if (!pkiob) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
- }
- nssTrust->object = *pkiob;
- nssTrust->certificate = c;
- nssTrust->serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE);
- nssTrust->clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE);
- nssTrust->emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE);
- nssTrust->codeSigning = get_stan_trust(trust->objectSigningFlags, PR_FALSE);
- nssTrust->stepUpApproved =
- (PRBool)(trust->sslFlags & CERTDB_GOVT_APPROVED_CA);
- if (c->object.cryptoContext != NULL) {
- /* The cert is in a context, set the trust there */
- NSSCryptoContext *cc = c->object.cryptoContext;
- nssrv = nssCryptoContext_ImportTrust(cc, nssTrust);
- if (nssrv != PR_SUCCESS) {
- goto done;
- }
- if (c->object.numInstances == 0) {
- /* The context is the only instance, finished */
- goto done;
- }
- }
- td = STAN_GetDefaultTrustDomain();
- tok = stan_GetTrustToken(c);
- moving_object = PR_FALSE;
- if (tok && PK11_IsReadOnly(tok->pk11slot)) {
- NSSRWLock_LockRead(td->tokensLock);
- tokens = nssList_CreateIterator(td->tokenList);
- if (!tokens) {
- nssrv = PR_FAILURE;
- NSSRWLock_UnlockRead(td->tokensLock);
- goto done;
- }
- for (tok = (NSSToken *)nssListIterator_Start(tokens);
- tok != (NSSToken *)NULL;
- tok = (NSSToken *)nssListIterator_Next(tokens))
- {
- if (!PK11_IsReadOnly(tok->pk11slot)) break;
- }
- nssListIterator_Finish(tokens);
- nssListIterator_Destroy(tokens);
- NSSRWLock_UnlockRead(td->tokensLock);
- moving_object = PR_TRUE;
- }
- if (tok) {
- if (moving_object) {
- /* this is kind of hacky. the softoken needs the cert
- * object in order to store trust. forcing it to be perm
- */
- NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL);
- NSSASCII7 *email = NULL;
-
- if (PK11_IsInternal(tok->pk11slot)) {
- email = c->email;
- }
- newInstance = nssToken_ImportCertificate(tok, NULL,
- NSSCertificateType_PKIX,
- &c->id,
- nickname,
- &c->encoding,
- &c->issuer,
- &c->subject,
- &c->serial,
- email,
- PR_TRUE);
- nss_ZFreeIf(nickname);
- nickname = NULL;
- if (!newInstance) {
- nssrv = PR_FAILURE;
- goto done;
- }
- nssPKIObject_AddInstance(&c->object, newInstance);
- }
- newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding,
- &c->issuer, &c->serial,
- nssTrust->serverAuth,
- nssTrust->clientAuth,
- nssTrust->codeSigning,
- nssTrust->emailProtection,
- nssTrust->stepUpApproved, PR_TRUE);
- /* If the selected token can't handle trust, dump the trust on
- * the internal token */
- if (!newInstance && !PK11_IsInternalKeySlot(tok->pk11slot)) {
- PK11SlotInfo *slot = PK11_GetInternalKeySlot();
- NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL);
- NSSASCII7 *email = c->email;
- tok = PK11Slot_GetNSSToken(slot);
- PK11_FreeSlot(slot);
-
- newInstance = nssToken_ImportCertificate(tok, NULL,
- NSSCertificateType_PKIX,
- &c->id,
- nickname,
- &c->encoding,
- &c->issuer,
- &c->subject,
- &c->serial,
- email,
- PR_TRUE);
- nss_ZFreeIf(nickname);
- nickname = NULL;
- if (!newInstance) {
- nssrv = PR_FAILURE;
- goto done;
- }
- nssPKIObject_AddInstance(&c->object, newInstance);
- newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding,
- &c->issuer, &c->serial,
- nssTrust->serverAuth,
- nssTrust->clientAuth,
- nssTrust->codeSigning,
- nssTrust->emailProtection,
- nssTrust->stepUpApproved, PR_TRUE);
- }
- if (newInstance) {
- nssCryptokiObject_Destroy(newInstance);
- nssrv = PR_SUCCESS;
- } else {
- nssrv = PR_FAILURE;
- }
- } else {
- nssrv = PR_FAILURE;
- }
-done:
- (void)nssTrust_Destroy(nssTrust);
- return nssrv;
-}
-
-/*
-** Delete trust objects matching the given slot.
-** Returns error if a device fails to delete.
-**
-** This function has the side effect of moving the
-** surviving entries to the front of the object list
-** and nullifying the rest.
-*/
-static PRStatus
-DeleteCertTrustMatchingSlot(PK11SlotInfo *pk11slot, nssPKIObject *tObject)
-{
- int numNotDestroyed = 0; /* the ones skipped plus the failures */
- int failureCount = 0; /* actual deletion failures by devices */
- int index;
-
- nssPKIObject_Lock(tObject);
- /* Keep going even if a module fails to delete. */
- for (index = 0; index < tObject->numInstances; index++) {
- nssCryptokiObject *instance = tObject->instances[index];
- if (!instance) {
- continue;
- }
-
- /* ReadOnly and not matched treated the same */
- if (PK11_IsReadOnly(instance->token->pk11slot) ||
- pk11slot != instance->token->pk11slot) {
- tObject->instances[numNotDestroyed++] = instance;
- continue;
- }
-
- /* Here we have found a matching one */
- tObject->instances[index] = NULL;
- if (nssToken_DeleteStoredObject(instance) == PR_SUCCESS) {
- nssCryptokiObject_Destroy(instance);
- } else {
- tObject->instances[numNotDestroyed++] = instance;
- failureCount++;
- }
-
- }
- if (numNotDestroyed == 0) {
- nss_ZFreeIf(tObject->instances);
- tObject->numInstances = 0;
- } else {
- tObject->numInstances = numNotDestroyed;
- }
-
- nssPKIObject_Unlock(tObject);
-
- return failureCount == 0 ? PR_SUCCESS : PR_FAILURE;
-}
-
-/*
-** Delete trust objects matching the slot of the given certificate.
-** Returns an error if any device fails to delete.
-*/
-NSS_EXTERN PRStatus
-STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c)
-{
- PRStatus nssrv = PR_SUCCESS;
-
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c);
- /* caller made sure nssTrust isn't NULL */
- nssPKIObject *tobject = &nssTrust->object;
- nssPKIObject *cobject = &c->object;
- int i;
-
- /* Iterate through the cert and trust object instances looking for
- * those with matching pk11 slots to delete. Even if some device
- * can't delete we keep going. Keeping a status variable for the
- * loop so that once it's failed the other gets set.
- */
- NSSRWLock_LockRead(td->tokensLock);
- nssPKIObject_Lock(cobject);
- for (i = 0; i < cobject->numInstances; i++) {
- nssCryptokiObject *cInstance = cobject->instances[i];
- if (cInstance && !PK11_IsReadOnly(cInstance->token->pk11slot)) {
- PRStatus status;
- if (!tobject->numInstances || !tobject->instances) continue;
- status = DeleteCertTrustMatchingSlot(cInstance->token->pk11slot, tobject);
- if (status == PR_FAILURE) {
- /* set the outer one but keep going */
- nssrv = PR_FAILURE;
- }
- }
- }
- nssPKIObject_Unlock(cobject);
- NSSRWLock_UnlockRead(td->tokensLock);
- return nssrv;
-}
-
-/* CERT_TraversePermCertsForSubject */
-NSS_IMPLEMENT PRStatus
-nssTrustDomain_TraverseCertificatesBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-)
-{
- PRStatus nssrv = PR_SUCCESS;
- NSSArena *tmpArena;
- NSSCertificate **subjectCerts;
- NSSCertificate *c;
- PRIntn i;
- tmpArena = NSSArena_Create();
- if (!tmpArena) {
- return PR_FAILURE;
- }
- subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, subject, NULL,
- 0, tmpArena);
- if (subjectCerts) {
- for (i=0, c = subjectCerts[i]; c; i++) {
- nssrv = callback(c, arg);
- if (nssrv != PR_SUCCESS) break;
- }
- }
- nssArena_Destroy(tmpArena);
- return nssrv;
-}
-
-/* CERT_TraversePermCertsForNickname */
-NSS_IMPLEMENT PRStatus
-nssTrustDomain_TraverseCertificatesByNickname (
- NSSTrustDomain *td,
- NSSUTF8 *nickname,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-)
-{
- PRStatus nssrv = PR_SUCCESS;
- NSSArena *tmpArena;
- NSSCertificate **nickCerts;
- NSSCertificate *c;
- PRIntn i;
- tmpArena = NSSArena_Create();
- if (!tmpArena) {
- return PR_FAILURE;
- }
- nickCerts = NSSTrustDomain_FindCertificatesByNickname(td, nickname, NULL,
- 0, tmpArena);
- if (nickCerts) {
- for (i=0, c = nickCerts[i]; c; i++) {
- nssrv = callback(c, arg);
- if (nssrv != PR_SUCCESS) break;
- }
- }
- nssArena_Destroy(tmpArena);
- return nssrv;
-}
-
-static void cert_dump_iter(const void *k, void *v, void *a)
-{
- NSSCertificate *c = (NSSCertificate *)k;
- CERTCertificate *cert = STAN_GetCERTCertificate(c);
- printf("[%2d] \"%s\"\n", c->object.refCount, cert->subjectName);
-}
-
-void
-nss_DumpCertificateCacheInfo()
-{
- NSSTrustDomain *td;
- NSSCryptoContext *cc;
- td = STAN_GetDefaultTrustDomain();
- cc = STAN_GetDefaultCryptoContext();
- printf("\n\nCertificates in the cache:\n");
- nssTrustDomain_DumpCacheInfo(td, cert_dump_iter, NULL);
- printf("\n\nCertificates in the temporary store:\n");
- if (cc->certStore) {
- nssCertificateStore_DumpStoreInfo(cc->certStore, cert_dump_iter, NULL);
- }
-}
-
diff --git a/security/nss/lib/pki/pki3hack.h b/security/nss/lib/pki/pki3hack.h
deleted file mode 100644
index 3edd26442..000000000
--- a/security/nss/lib/pki/pki3hack.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef PKINSS3HACK_H
-#define PKINSS3HACK_H
-
-#ifdef DEBUG
-static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef NSSDEVT_H
-#include "nssdevt.h"
-#endif /* NSSDEVT_H */
-
-#ifndef DEVT_H
-#include "devt.h"
-#endif /* DEVT_H */
-
-#ifndef NSSPKIT_H
-#include "nsspkit.h"
-#endif /* NSSPKIT_H */
-
-#include "base.h"
-
-#include "cert.h"
-
-PR_BEGIN_EXTERN_C
-
-#define NSSITEM_FROM_SECITEM(nssit, secit) \
- (nssit)->data = (void *)(secit)->data; \
- (nssit)->size = (PRUint32)(secit)->len;
-
-#define SECITEM_FROM_NSSITEM(secit, nssit) \
- (secit)->data = (unsigned char *)(nssit)->data; \
- (secit)->len = (unsigned int)(nssit)->size;
-
-NSS_EXTERN NSSTrustDomain *
-STAN_GetDefaultTrustDomain();
-
-NSS_EXTERN NSSCryptoContext *
-STAN_GetDefaultCryptoContext();
-
-NSS_EXTERN PRStatus
-STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot);
-
-NSS_EXTERN PRStatus
-STAN_ResetTokenInterator(NSSTrustDomain *td);
-
-NSS_EXTERN PRStatus
-STAN_LoadDefaultNSS3TrustDomain(void);
-
-NSS_EXTERN PRStatus
-STAN_Shutdown();
-
-NSS_EXTERN SECStatus
-STAN_AddModuleToDefaultTrustDomain(SECMODModule *module);
-
-NSS_EXTERN SECStatus
-STAN_RemoveModuleFromDefaultTrustDomain(SECMODModule *module);
-
-NSS_EXTERN CERTCertificate *
-STAN_ForceCERTCertificateUpdate(NSSCertificate *c);
-
-NSS_EXTERN CERTCertificate *
-STAN_GetCERTCertificate(NSSCertificate *c);
-
-NSS_EXTERN CERTCertificate *
-STAN_GetCERTCertificateOrRelease(NSSCertificate *c);
-
-NSS_EXTERN NSSCertificate *
-STAN_GetNSSCertificate(CERTCertificate *c);
-
-NSS_EXTERN CERTCertTrust *
-nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc);
-
-NSS_EXTERN PRStatus
-STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c);
-
-NSS_EXTERN PRStatus
-STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust);
-
-NSS_EXTERN PRStatus
-nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena,
- NSSDER *issuer, NSSDER *serial);
-
-NSS_EXTERN char *
-STAN_GetCERTCertificateName(PLArenaPool *arenaOpt, NSSCertificate *c);
-
-NSS_EXTERN char *
-STAN_GetCERTCertificateNameForInstance(PLArenaPool *arenaOpt,
- NSSCertificate *c,
- nssCryptokiInstance *instance);
-
-/* exposing this */
-NSS_EXTERN NSSCertificate *
-NSSCertificate_Create
-(
- NSSArena *arenaOpt
-);
-
-/* This function is being put here because it is a hack for
- * PK11_FindCertFromNickname.
- */
-NSS_EXTERN NSSCertificate *
-nssTrustDomain_FindBestCertificateByNicknameForToken
-(
- NSSTrustDomain *td,
- NSSToken *token,
- NSSUTF8 *name,
- NSSTime *timeOpt, /* NULL for "now" */
- NSSUsage *usage,
- NSSPolicies *policiesOpt /* NULL for none */
-);
-
-/* This function is being put here because it is a hack for
- * PK11_FindCertsFromNickname.
- */
-NSS_EXTERN NSSCertificate **
-nssTrustDomain_FindCertificatesByNicknameForToken
-(
- NSSTrustDomain *td,
- NSSToken *token,
- NSSUTF8 *name,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-);
-
-/* CERT_TraversePermCertsForSubject */
-NSS_EXTERN PRStatus
-nssTrustDomain_TraverseCertificatesBySubject
-(
- NSSTrustDomain *td,
- NSSDER *subject,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-);
-
-/* CERT_TraversePermCertsForNickname */
-NSS_EXTERN PRStatus
-nssTrustDomain_TraverseCertificatesByNickname
-(
- NSSTrustDomain *td,
- NSSUTF8 *nickname,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-);
-
-/* SEC_TraversePermCerts */
-NSS_EXTERN PRStatus
-nssTrustDomain_TraverseCertificates
-(
- NSSTrustDomain *td,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-);
-
-/* CERT_AddTempCertToPerm */
-NSS_EXTERN PRStatus
-nssTrustDomain_AddTempCertToPerm
-(
- NSSCertificate *c
-);
-
-PR_END_EXTERN_C
-
-#endif /* PKINSS3HACK_H */
diff --git a/security/nss/lib/pki/pkibase.c b/security/nss/lib/pki/pkibase.c
deleted file mode 100644
index 69866a4b1..000000000
--- a/security/nss/lib/pki/pkibase.c
+++ /dev/null
@@ -1,1258 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
-#ifndef PKIM_H
-#include "pkim.h"
-#endif /* PKIM_H */
-
-#include "pki3hack.h"
-
-extern const NSSError NSS_ERROR_NOT_FOUND;
-
-NSS_IMPLEMENT void
-nssPKIObject_Lock(nssPKIObject * object)
-{
- switch (object->lockType) {
- case nssPKIMonitor:
- PZ_EnterMonitor(object->sync.mlock);
- break;
- case nssPKILock:
- PZ_Lock(object->sync.lock);
- break;
- default:
- PORT_Assert(0);
- }
-}
-
-NSS_IMPLEMENT void
-nssPKIObject_Unlock(nssPKIObject * object)
-{
- switch (object->lockType) {
- case nssPKIMonitor:
- PZ_ExitMonitor(object->sync.mlock);
- break;
- case nssPKILock:
- PZ_Unlock(object->sync.lock);
- break;
- default:
- PORT_Assert(0);
- }
-}
-
-NSS_IMPLEMENT PRStatus
-nssPKIObject_NewLock(nssPKIObject * object, nssPKILockType lockType)
-{
- object->lockType = lockType;
- switch (lockType) {
- case nssPKIMonitor:
- object->sync.mlock = PZ_NewMonitor(nssILockSSL);
- return (object->sync.mlock ? PR_SUCCESS : PR_FAILURE);
- case nssPKILock:
- object->sync.lock = PZ_NewLock(nssILockSSL);
- return (object->sync.lock ? PR_SUCCESS : PR_FAILURE);
- default:
- PORT_Assert(0);
- return PR_FAILURE;
- }
-}
-
-NSS_IMPLEMENT void
-nssPKIObject_DestroyLock(nssPKIObject * object)
-{
- switch (object->lockType) {
- case nssPKIMonitor:
- PZ_DestroyMonitor(object->sync.mlock);
- object->sync.mlock = NULL;
- break;
- case nssPKILock:
- PZ_DestroyLock(object->sync.lock);
- object->sync.lock = NULL;
- break;
- default:
- PORT_Assert(0);
- }
-}
-
-
-
-NSS_IMPLEMENT nssPKIObject *
-nssPKIObject_Create (
- NSSArena *arenaOpt,
- nssCryptokiObject *instanceOpt,
- NSSTrustDomain *td,
- NSSCryptoContext *cc,
- nssPKILockType lockType
-)
-{
- NSSArena *arena;
- nssArenaMark *mark = NULL;
- nssPKIObject *object;
- if (arenaOpt) {
- arena = arenaOpt;
- mark = nssArena_Mark(arena);
- } else {
- arena = nssArena_Create();
- if (!arena) {
- return (nssPKIObject *)NULL;
- }
- }
- object = nss_ZNEW(arena, nssPKIObject);
- if (!object) {
- goto loser;
- }
- object->arena = arena;
- object->trustDomain = td; /* XXX */
- object->cryptoContext = cc;
- if (PR_SUCCESS != nssPKIObject_NewLock(object, lockType)) {
- goto loser;
- }
- if (instanceOpt) {
- if (nssPKIObject_AddInstance(object, instanceOpt) != PR_SUCCESS) {
- goto loser;
- }
- }
- PR_ATOMIC_INCREMENT(&object->refCount);
- if (mark) {
- nssArena_Unmark(arena, mark);
- }
- return object;
-loser:
- if (mark) {
- nssArena_Release(arena, mark);
- } else {
- nssArena_Destroy(arena);
- }
- return (nssPKIObject *)NULL;
-}
-
-NSS_IMPLEMENT PRBool
-nssPKIObject_Destroy (
- nssPKIObject *object
-)
-{
- PRUint32 i;
- PR_ASSERT(object->refCount > 0);
- if (PR_ATOMIC_DECREMENT(&object->refCount) == 0) {
- for (i=0; i<object->numInstances; i++) {
- nssCryptokiObject_Destroy(object->instances[i]);
- }
- nssPKIObject_DestroyLock(object);
- nssArena_Destroy(object->arena);
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-NSS_IMPLEMENT nssPKIObject *
-nssPKIObject_AddRef (
- nssPKIObject *object
-)
-{
- PR_ATOMIC_INCREMENT(&object->refCount);
- return object;
-}
-
-NSS_IMPLEMENT PRStatus
-nssPKIObject_AddInstance (
- nssPKIObject *object,
- nssCryptokiObject *instance
-)
-{
- nssCryptokiObject **newInstances = NULL;
-
- nssPKIObject_Lock(object);
- if (object->numInstances == 0) {
- newInstances = nss_ZNEWARRAY(object->arena,
- nssCryptokiObject *,
- object->numInstances + 1);
- } else {
- PRBool found = PR_FALSE;
- PRUint32 i;
- for (i=0; i<object->numInstances; i++) {
- if (nssCryptokiObject_Equal(object->instances[i], instance)) {
- found = PR_TRUE;
- break;
- }
- }
- if (found) {
- /* The new instance is identical to one in the array, except
- * perhaps that the label may be different. So replace
- * the label in the array instance with the label from the
- * new instance, and discard the new instance.
- */
- nss_ZFreeIf(object->instances[i]->label);
- object->instances[i]->label = instance->label;
- nssPKIObject_Unlock(object);
- instance->label = NULL;
- nssCryptokiObject_Destroy(instance);
- return PR_SUCCESS;
- }
- newInstances = nss_ZREALLOCARRAY(object->instances,
- nssCryptokiObject *,
- object->numInstances + 1);
- }
- if (newInstances) {
- object->instances = newInstances;
- newInstances[object->numInstances++] = instance;
- }
- nssPKIObject_Unlock(object);
- return (newInstances ? PR_SUCCESS : PR_FAILURE);
-}
-
-NSS_IMPLEMENT PRBool
-nssPKIObject_HasInstance (
- nssPKIObject *object,
- nssCryptokiObject *instance
-)
-{
- PRUint32 i;
- PRBool hasIt = PR_FALSE;;
- nssPKIObject_Lock(object);
- for (i=0; i<object->numInstances; i++) {
- if (nssCryptokiObject_Equal(object->instances[i], instance)) {
- hasIt = PR_TRUE;
- break;
- }
- }
- nssPKIObject_Unlock(object);
- return hasIt;
-}
-
-NSS_IMPLEMENT PRStatus
-nssPKIObject_RemoveInstanceForToken (
- nssPKIObject *object,
- NSSToken *token
-)
-{
- PRUint32 i;
- nssCryptokiObject *instanceToRemove = NULL;
- nssPKIObject_Lock(object);
- if (object->numInstances == 0) {
- nssPKIObject_Unlock(object);
- return PR_SUCCESS;
- }
- for (i=0; i<object->numInstances; i++) {
- if (object->instances[i]->token == token) {
- instanceToRemove = object->instances[i];
- object->instances[i] = object->instances[object->numInstances-1];
- object->instances[object->numInstances-1] = NULL;
- break;
- }
- }
- if (--object->numInstances > 0) {
- nssCryptokiObject **instances = nss_ZREALLOCARRAY(object->instances,
- nssCryptokiObject *,
- object->numInstances);
- if (instances) {
- object->instances = instances;
- }
- } else {
- nss_ZFreeIf(object->instances);
- }
- nssCryptokiObject_Destroy(instanceToRemove);
- nssPKIObject_Unlock(object);
- return PR_SUCCESS;
-}
-
-/* this needs more thought on what will happen when there are multiple
- * instances
- */
-NSS_IMPLEMENT PRStatus
-nssPKIObject_DeleteStoredObject (
- nssPKIObject *object,
- NSSCallback *uhh,
- PRBool isFriendly
-)
-{
- PRUint32 i, numNotDestroyed;
- PRStatus status = PR_SUCCESS;
- numNotDestroyed = 0;
- nssPKIObject_Lock(object);
- for (i=0; i<object->numInstances; i++) {
- nssCryptokiObject *instance = object->instances[i];
- status = nssToken_DeleteStoredObject(instance);
- object->instances[i] = NULL;
- if (status == PR_SUCCESS) {
- nssCryptokiObject_Destroy(instance);
- } else {
- object->instances[numNotDestroyed++] = instance;
- }
- }
- if (numNotDestroyed == 0) {
- nss_ZFreeIf(object->instances);
- object->numInstances = 0;
- } else {
- object->numInstances = numNotDestroyed;
- }
- nssPKIObject_Unlock(object);
- return status;
-}
-
-NSS_IMPLEMENT NSSToken **
-nssPKIObject_GetTokens (
- nssPKIObject *object,
- PRStatus *statusOpt
-)
-{
- NSSToken **tokens = NULL;
- nssPKIObject_Lock(object);
- if (object->numInstances > 0) {
- tokens = nss_ZNEWARRAY(NULL, NSSToken *, object->numInstances + 1);
- if (tokens) {
- PRUint32 i;
- for (i=0; i<object->numInstances; i++) {
- tokens[i] = nssToken_AddRef(object->instances[i]->token);
- }
- }
- }
- nssPKIObject_Unlock(object);
- if (statusOpt) *statusOpt = PR_SUCCESS; /* until more logic here */
- return tokens;
-}
-
-NSS_IMPLEMENT NSSUTF8 *
-nssPKIObject_GetNicknameForToken (
- nssPKIObject *object,
- NSSToken *tokenOpt
-)
-{
- PRUint32 i;
- NSSUTF8 *nickname = NULL;
- nssPKIObject_Lock(object);
- for (i=0; i<object->numInstances; i++) {
- if ((!tokenOpt && object->instances[i]->label) ||
- (object->instances[i]->token == tokenOpt))
- {
- /* Must copy, see bug 745548 */
- nickname = nssUTF8_Duplicate(object->instances[i]->label, NULL);
- break;
- }
- }
- nssPKIObject_Unlock(object);
- return nickname;
-}
-
-NSS_IMPLEMENT nssCryptokiObject **
-nssPKIObject_GetInstances (
- nssPKIObject *object
-)
-{
- nssCryptokiObject **instances = NULL;
- PRUint32 i;
- if (object->numInstances == 0) {
- return (nssCryptokiObject **)NULL;
- }
- nssPKIObject_Lock(object);
- instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *,
- object->numInstances + 1);
- if (instances) {
- for (i=0; i<object->numInstances; i++) {
- instances[i] = nssCryptokiObject_Clone(object->instances[i]);
- }
- }
- nssPKIObject_Unlock(object);
- return instances;
-}
-
-NSS_IMPLEMENT void
-nssCertificateArray_Destroy (
- NSSCertificate **certs
-)
-{
- if (certs) {
- NSSCertificate **certp;
- for (certp = certs; *certp; certp++) {
- if ((*certp)->decoding) {
- CERTCertificate *cc = STAN_GetCERTCertificate(*certp);
- if (cc) {
- CERT_DestroyCertificate(cc);
- }
- continue;
- }
- nssCertificate_Destroy(*certp);
- }
- nss_ZFreeIf(certs);
- }
-}
-
-NSS_IMPLEMENT void
-NSSCertificateArray_Destroy (
- NSSCertificate **certs
-)
-{
- nssCertificateArray_Destroy(certs);
-}
-
-NSS_IMPLEMENT NSSCertificate **
-nssCertificateArray_Join (
- NSSCertificate **certs1,
- NSSCertificate **certs2
-)
-{
- if (certs1 && certs2) {
- NSSCertificate **certs, **cp;
- PRUint32 count = 0;
- PRUint32 count1 = 0;
- cp = certs1;
- while (*cp++) count1++;
- count = count1;
- cp = certs2;
- while (*cp++) count++;
- certs = nss_ZREALLOCARRAY(certs1, NSSCertificate *, count + 1);
- if (!certs) {
- nss_ZFreeIf(certs1);
- nss_ZFreeIf(certs2);
- return (NSSCertificate **)NULL;
- }
- for (cp = certs2; *cp; cp++, count1++) {
- certs[count1] = *cp;
- }
- nss_ZFreeIf(certs2);
- return certs;
- } else if (certs1) {
- return certs1;
- } else {
- return certs2;
- }
-}
-
-NSS_IMPLEMENT NSSCertificate *
-nssCertificateArray_FindBestCertificate (
- NSSCertificate **certs,
- NSSTime *timeOpt,
- const NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- NSSCertificate *bestCert = NULL;
- nssDecodedCert *bestdc = NULL;
- NSSTime *time, sTime;
- PRBool bestCertMatches = PR_FALSE;
- PRBool thisCertMatches;
- PRBool bestCertIsValidAtTime = PR_FALSE;
- PRBool bestCertIsTrusted = PR_FALSE;
-
- if (timeOpt) {
- time = timeOpt;
- } else {
- NSSTime_Now(&sTime);
- time = &sTime;
- }
- if (!certs) {
- return (NSSCertificate *)NULL;
- }
- for (; *certs; certs++) {
- nssDecodedCert *dc;
- NSSCertificate *c = *certs;
- dc = nssCertificate_GetDecoding(c);
- if (!dc) continue;
- thisCertMatches = dc->matchUsage(dc, usage);
- if (!bestCert) {
- /* always take the first cert, but remember whether or not
- * the usage matched
- */
- bestCert = nssCertificate_AddRef(c);
- bestCertMatches = thisCertMatches;
- bestdc = dc;
- continue;
- } else {
- if (bestCertMatches && !thisCertMatches) {
- /* if already have a cert for this usage, and if this cert
- * doesn't have the correct usage, continue
- */
- continue;
- } else if (!bestCertMatches && thisCertMatches) {
- /* this one does match usage, replace the other */
- nssCertificate_Destroy(bestCert);
- bestCert = nssCertificate_AddRef(c);
- bestCertMatches = thisCertMatches;
- bestdc = dc;
- continue;
- }
- /* this cert match as well as any cert we've found so far,
- * defer to time/policies
- * */
- }
- /* time */
- if (bestCertIsValidAtTime || bestdc->isValidAtTime(bestdc, time)) {
- /* The current best cert is valid at time */
- bestCertIsValidAtTime = PR_TRUE;
- if (!dc->isValidAtTime(dc, time)) {
- /* If the new cert isn't valid at time, it's not better */
- continue;
- }
- } else {
- /* The current best cert is not valid at time */
- if (dc->isValidAtTime(dc, time)) {
- /* If the new cert is valid at time, it's better */
- nssCertificate_Destroy(bestCert);
- bestCert = nssCertificate_AddRef(c);
- bestdc = dc;
- bestCertIsValidAtTime = PR_TRUE;
- continue;
- }
- }
- /* Either they are both valid at time, or neither valid.
- * If only one is trusted for this usage, take it.
- */
- if (bestCertIsTrusted || bestdc->isTrustedForUsage(bestdc, usage)) {
- bestCertIsTrusted = PR_TRUE;
- if (!dc->isTrustedForUsage(dc, usage)) {
- continue;
- }
- } else {
- /* The current best cert is not trusted */
- if (dc->isTrustedForUsage(dc, usage)) {
- /* If the new cert is trusted, it's better */
- nssCertificate_Destroy(bestCert);
- bestCert = nssCertificate_AddRef(c);
- bestdc = dc;
- bestCertIsTrusted = PR_TRUE;
- continue;
- }
- }
- /* Otherwise, take the newer one. */
- if (!bestdc->isNewerThan(bestdc, dc)) {
- nssCertificate_Destroy(bestCert);
- bestCert = nssCertificate_AddRef(c);
- bestdc = dc;
- continue;
- }
- /* policies */
- /* XXX later -- defer to policies */
- }
- return bestCert;
-}
-
-NSS_IMPLEMENT PRStatus
-nssCertificateArray_Traverse (
- NSSCertificate **certs,
- PRStatus (* callback)(NSSCertificate *c, void *arg),
- void *arg
-)
-{
- PRStatus status = PR_SUCCESS;
- if (certs) {
- NSSCertificate **certp;
- for (certp = certs; *certp; certp++) {
- status = (*callback)(*certp, arg);
- if (status != PR_SUCCESS) {
- break;
- }
- }
- }
- return status;
-}
-
-
-NSS_IMPLEMENT void
-nssCRLArray_Destroy (
- NSSCRL **crls
-)
-{
- if (crls) {
- NSSCRL **crlp;
- for (crlp = crls; *crlp; crlp++) {
- nssCRL_Destroy(*crlp);
- }
- nss_ZFreeIf(crls);
- }
-}
-
-/*
- * Object collections
- */
-
-typedef enum
-{
- pkiObjectType_Certificate = 0,
- pkiObjectType_CRL = 1,
- pkiObjectType_PrivateKey = 2,
- pkiObjectType_PublicKey = 3
-} pkiObjectType;
-
-/* Each object is defined by a set of items that uniquely identify it.
- * Here are the uid sets:
- *
- * NSSCertificate ==> { issuer, serial }
- * NSSPrivateKey
- * (RSA) ==> { modulus, public exponent }
- *
- */
-#define MAX_ITEMS_FOR_UID 2
-
-/* pkiObjectCollectionNode
- *
- * A node in the collection is the set of unique identifiers for a single
- * object, along with either the actual object or a proto-object.
- */
-typedef struct
-{
- PRCList link;
- PRBool haveObject;
- nssPKIObject *object;
- NSSItem uid[MAX_ITEMS_FOR_UID];
-}
-pkiObjectCollectionNode;
-
-/* nssPKIObjectCollection
- *
- * The collection is the set of all objects, plus the interfaces needed
- * to manage the objects.
- *
- */
-struct nssPKIObjectCollectionStr
-{
- NSSArena *arena;
- NSSTrustDomain *td;
- NSSCryptoContext *cc;
- PRCList head; /* list of pkiObjectCollectionNode's */
- PRUint32 size;
- pkiObjectType objectType;
- void (* destroyObject)(nssPKIObject *o);
- PRStatus (* getUIDFromObject)(nssPKIObject *o, NSSItem *uid);
- PRStatus (* getUIDFromInstance)(nssCryptokiObject *co, NSSItem *uid,
- NSSArena *arena);
- nssPKIObject * (* createObject)(nssPKIObject *o);
- nssPKILockType lockType; /* type of lock to use for new proto-objects */
-};
-
-static nssPKIObjectCollection *
-nssPKIObjectCollection_Create (
- NSSTrustDomain *td,
- NSSCryptoContext *ccOpt,
- nssPKILockType lockType
-)
-{
- NSSArena *arena;
- nssPKIObjectCollection *rvCollection = NULL;
- arena = nssArena_Create();
- if (!arena) {
- return (nssPKIObjectCollection *)NULL;
- }
- rvCollection = nss_ZNEW(arena, nssPKIObjectCollection);
- if (!rvCollection) {
- goto loser;
- }
- PR_INIT_CLIST(&rvCollection->head);
- rvCollection->arena = arena;
- rvCollection->td = td; /* XXX */
- rvCollection->cc = ccOpt;
- rvCollection->lockType = lockType;
- return rvCollection;
-loser:
- nssArena_Destroy(arena);
- return (nssPKIObjectCollection *)NULL;
-}
-
-NSS_IMPLEMENT void
-nssPKIObjectCollection_Destroy (
- nssPKIObjectCollection *collection
-)
-{
- if (collection) {
- PRCList *link;
- pkiObjectCollectionNode *node;
- /* first destroy any objects in the collection */
- link = PR_NEXT_LINK(&collection->head);
- while (link != &collection->head) {
- node = (pkiObjectCollectionNode *)link;
- if (node->haveObject) {
- (*collection->destroyObject)(node->object);
- } else {
- nssPKIObject_Destroy(node->object);
- }
- link = PR_NEXT_LINK(link);
- }
- /* then destroy it */
- nssArena_Destroy(collection->arena);
- }
-}
-
-NSS_IMPLEMENT PRUint32
-nssPKIObjectCollection_Count (
- nssPKIObjectCollection *collection
-)
-{
- return collection->size;
-}
-
-NSS_IMPLEMENT PRStatus
-nssPKIObjectCollection_AddObject (
- nssPKIObjectCollection *collection,
- nssPKIObject *object
-)
-{
- pkiObjectCollectionNode *node;
- node = nss_ZNEW(collection->arena, pkiObjectCollectionNode);
- if (!node) {
- return PR_FAILURE;
- }
- node->haveObject = PR_TRUE;
- node->object = nssPKIObject_AddRef(object);
- (*collection->getUIDFromObject)(object, node->uid);
- PR_INIT_CLIST(&node->link);
- PR_INSERT_BEFORE(&node->link, &collection->head);
- collection->size++;
- return PR_SUCCESS;
-}
-
-static pkiObjectCollectionNode *
-find_instance_in_collection (
- nssPKIObjectCollection *collection,
- nssCryptokiObject *instance
-)
-{
- PRCList *link;
- pkiObjectCollectionNode *node;
- link = PR_NEXT_LINK(&collection->head);
- while (link != &collection->head) {
- node = (pkiObjectCollectionNode *)link;
- if (nssPKIObject_HasInstance(node->object, instance)) {
- return node;
- }
- link = PR_NEXT_LINK(link);
- }
- return (pkiObjectCollectionNode *)NULL;
-}
-
-static pkiObjectCollectionNode *
-find_object_in_collection (
- nssPKIObjectCollection *collection,
- NSSItem *uid
-)
-{
- PRUint32 i;
- PRStatus status;
- PRCList *link;
- pkiObjectCollectionNode *node;
- link = PR_NEXT_LINK(&collection->head);
- while (link != &collection->head) {
- node = (pkiObjectCollectionNode *)link;
- for (i=0; i<MAX_ITEMS_FOR_UID; i++) {
- if (!nssItem_Equal(&node->uid[i], &uid[i], &status)) {
- break;
- }
- }
- if (i == MAX_ITEMS_FOR_UID) {
- return node;
- }
- link = PR_NEXT_LINK(link);
- }
- return (pkiObjectCollectionNode *)NULL;
-}
-
-static pkiObjectCollectionNode *
-add_object_instance (
- nssPKIObjectCollection *collection,
- nssCryptokiObject *instance,
- PRBool *foundIt
-)
-{
- PRUint32 i;
- PRStatus status;
- pkiObjectCollectionNode *node;
- nssArenaMark *mark = NULL;
- NSSItem uid[MAX_ITEMS_FOR_UID];
- nsslibc_memset(uid, 0, sizeof uid);
- /* The list is traversed twice, first (here) looking to match the
- * { token, handle } tuple, and if that is not found, below a search
- * for unique identifier is done. Here, a match means this exact object
- * instance is already in the collection, and we have nothing to do.
- */
- *foundIt = PR_FALSE;
- node = find_instance_in_collection(collection, instance);
- if (node) {
- /* The collection is assumed to take over the instance. Since we
- * are not using it, it must be destroyed.
- */
- nssCryptokiObject_Destroy(instance);
- *foundIt = PR_TRUE;
- return node;
- }
- mark = nssArena_Mark(collection->arena);
- if (!mark) {
- goto loser;
- }
- status = (*collection->getUIDFromInstance)(instance, uid,
- collection->arena);
- if (status != PR_SUCCESS) {
- goto loser;
- }
- /* Search for unique identifier. A match here means the object exists
- * in the collection, but does not have this instance, so the instance
- * needs to be added.
- */
- node = find_object_in_collection(collection, uid);
- if (node) {
- /* This is an object with multiple instances */
- status = nssPKIObject_AddInstance(node->object, instance);
- } else {
- /* This is a completely new object. Create a node for it. */
- node = nss_ZNEW(collection->arena, pkiObjectCollectionNode);
- if (!node) {
- goto loser;
- }
- node->object = nssPKIObject_Create(NULL, instance,
- collection->td, collection->cc,
- collection->lockType);
- if (!node->object) {
- goto loser;
- }
- for (i=0; i<MAX_ITEMS_FOR_UID; i++) {
- node->uid[i] = uid[i];
- }
- node->haveObject = PR_FALSE;
- PR_INIT_CLIST(&node->link);
- PR_INSERT_BEFORE(&node->link, &collection->head);
- collection->size++;
- status = PR_SUCCESS;
- }
- nssArena_Unmark(collection->arena, mark);
- return node;
-loser:
- if (mark) {
- nssArena_Release(collection->arena, mark);
- }
- nssCryptokiObject_Destroy(instance);
- return (pkiObjectCollectionNode *)NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-nssPKIObjectCollection_AddInstances (
- nssPKIObjectCollection *collection,
- nssCryptokiObject **instances,
- PRUint32 numInstances
-)
-{
- PRStatus status = PR_SUCCESS;
- PRUint32 i = 0;
- PRBool foundIt;
- pkiObjectCollectionNode *node;
- if (instances) {
- while ((!numInstances || i < numInstances) && *instances) {
- if (status == PR_SUCCESS) {
- node = add_object_instance(collection, *instances, &foundIt);
- if (node == NULL) {
- /* add_object_instance freed the current instance */
- /* free the remaining instances */
- status = PR_FAILURE;
- }
- } else {
- nssCryptokiObject_Destroy(*instances);
- }
- instances++;
- i++;
- }
- }
- return status;
-}
-
-static void
-nssPKIObjectCollection_RemoveNode (
- nssPKIObjectCollection *collection,
- pkiObjectCollectionNode *node
-)
-{
- PR_REMOVE_LINK(&node->link);
- collection->size--;
-}
-
-static PRStatus
-nssPKIObjectCollection_GetObjects (
- nssPKIObjectCollection *collection,
- nssPKIObject **rvObjects,
- PRUint32 rvSize
-)
-{
- PRUint32 i = 0;
- PRCList *link = PR_NEXT_LINK(&collection->head);
- pkiObjectCollectionNode *node;
- int error=0;
- while ((i < rvSize) && (link != &collection->head)) {
- node = (pkiObjectCollectionNode *)link;
- if (!node->haveObject) {
- /* Convert the proto-object to an object */
- node->object = (*collection->createObject)(node->object);
- if (!node->object) {
- link = PR_NEXT_LINK(link);
- /*remove bogus object from list*/
- nssPKIObjectCollection_RemoveNode(collection,node);
- error++;
- continue;
- }
- node->haveObject = PR_TRUE;
- }
- rvObjects[i++] = nssPKIObject_AddRef(node->object);
- link = PR_NEXT_LINK(link);
- }
- if (!error && *rvObjects == NULL) {
- nss_SetError(NSS_ERROR_NOT_FOUND);
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssPKIObjectCollection_Traverse (
- nssPKIObjectCollection *collection,
- nssPKIObjectCallback *callback
-)
-{
- PRStatus status;
- PRCList *link = PR_NEXT_LINK(&collection->head);
- pkiObjectCollectionNode *node;
- while (link != &collection->head) {
- node = (pkiObjectCollectionNode *)link;
- if (!node->haveObject) {
- node->object = (*collection->createObject)(node->object);
- if (!node->object) {
- link = PR_NEXT_LINK(link);
- /*remove bogus object from list*/
- nssPKIObjectCollection_RemoveNode(collection,node);
- continue;
- }
- node->haveObject = PR_TRUE;
- }
- switch (collection->objectType) {
- case pkiObjectType_Certificate:
- status = (*callback->func.cert)((NSSCertificate *)node->object,
- callback->arg);
- break;
- case pkiObjectType_CRL:
- status = (*callback->func.crl)((NSSCRL *)node->object,
- callback->arg);
- break;
- case pkiObjectType_PrivateKey:
- status = (*callback->func.pvkey)((NSSPrivateKey *)node->object,
- callback->arg);
- break;
- case pkiObjectType_PublicKey:
- status = (*callback->func.pbkey)((NSSPublicKey *)node->object,
- callback->arg);
- break;
- }
- link = PR_NEXT_LINK(link);
- }
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssPKIObjectCollection_AddInstanceAsObject (
- nssPKIObjectCollection *collection,
- nssCryptokiObject *instance
-)
-{
- pkiObjectCollectionNode *node;
- PRBool foundIt;
- node = add_object_instance(collection, instance, &foundIt);
- if (node == NULL) {
- return PR_FAILURE;
- }
- if (!node->haveObject) {
- node->object = (*collection->createObject)(node->object);
- if (!node->object) {
- /*remove bogus object from list*/
- nssPKIObjectCollection_RemoveNode(collection,node);
- return PR_FAILURE;
- }
- node->haveObject = PR_TRUE;
- } else if (!foundIt) {
- /* The instance was added to a pre-existing node. This
- * function is *only* being used for certificates, and having
- * multiple instances of certs in 3.X requires updating the
- * CERTCertificate.
- * But only do it if it was a new instance!!! If the same instance
- * is encountered, we set *foundIt to true. Detect that here and
- * ignore it.
- */
- STAN_ForceCERTCertificateUpdate((NSSCertificate *)node->object);
- }
- return PR_SUCCESS;
-}
-
-/*
- * Certificate collections
- */
-
-static void
-cert_destroyObject(nssPKIObject *o)
-{
- NSSCertificate *c = (NSSCertificate *)o;
- if (c->decoding) {
- CERTCertificate *cc = STAN_GetCERTCertificate(c);
- if (cc) {
- CERT_DestroyCertificate(cc);
- return;
- } /* else destroy it as NSSCertificate below */
- }
- nssCertificate_Destroy(c);
-}
-
-static PRStatus
-cert_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
-{
- NSSCertificate *c = (NSSCertificate *)o;
- /* The builtins are still returning decoded serial numbers. Until
- * this compatibility issue is resolved, use the full DER of the
- * cert to uniquely identify it.
- */
- NSSDER *derCert;
- derCert = nssCertificate_GetEncoding(c);
- uid[0].data = NULL; uid[0].size = 0;
- uid[1].data = NULL; uid[1].size = 0;
- if (derCert != NULL) {
- uid[0] = *derCert;
- }
- return PR_SUCCESS;
-}
-
-static PRStatus
-cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
- NSSArena *arena)
-{
- /* The builtins are still returning decoded serial numbers. Until
- * this compatibility issue is resolved, use the full DER of the
- * cert to uniquely identify it.
- */
- uid[1].data = NULL; uid[1].size = 0;
- return nssCryptokiCertificate_GetAttributes(instance,
- NULL, /* XXX sessionOpt */
- arena, /* arena */
- NULL, /* type */
- NULL, /* id */
- &uid[0], /* encoding */
- NULL, /* issuer */
- NULL, /* serial */
- NULL); /* subject */
-}
-
-static nssPKIObject *
-cert_createObject(nssPKIObject *o)
-{
- NSSCertificate *cert;
- cert = nssCertificate_Create(o);
-/* if (STAN_GetCERTCertificate(cert) == NULL) {
- nssCertificate_Destroy(cert);
- return (nssPKIObject *)NULL;
- } */
- /* In 3.4, have to maintain uniqueness of cert pointers by caching all
- * certs. Cache the cert here, before returning. If it is already
- * cached, take the cached entry.
- */
- {
- NSSTrustDomain *td = o->trustDomain;
- nssTrustDomain_AddCertsToCache(td, &cert, 1);
- }
- return (nssPKIObject *)cert;
-}
-
-NSS_IMPLEMENT nssPKIObjectCollection *
-nssCertificateCollection_Create (
- NSSTrustDomain *td,
- NSSCertificate **certsOpt
-)
-{
- PRStatus status;
- nssPKIObjectCollection *collection;
- collection = nssPKIObjectCollection_Create(td, NULL, nssPKIMonitor);
- collection->objectType = pkiObjectType_Certificate;
- collection->destroyObject = cert_destroyObject;
- collection->getUIDFromObject = cert_getUIDFromObject;
- collection->getUIDFromInstance = cert_getUIDFromInstance;
- collection->createObject = cert_createObject;
- if (certsOpt) {
- for (; *certsOpt; certsOpt++) {
- nssPKIObject *object = (nssPKIObject *)(*certsOpt);
- status = nssPKIObjectCollection_AddObject(collection, object);
- }
- }
- return collection;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-nssPKIObjectCollection_GetCertificates (
- nssPKIObjectCollection *collection,
- NSSCertificate **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
- PRStatus status;
- PRUint32 rvSize;
- PRBool allocated = PR_FALSE;
- if (collection->size == 0) {
- return (NSSCertificate **)NULL;
- }
- if (maximumOpt == 0) {
- rvSize = collection->size;
- } else {
- rvSize = PR_MIN(collection->size, maximumOpt);
- }
- if (!rvOpt) {
- rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvSize + 1);
- if (!rvOpt) {
- return (NSSCertificate **)NULL;
- }
- allocated = PR_TRUE;
- }
- status = nssPKIObjectCollection_GetObjects(collection,
- (nssPKIObject **)rvOpt,
- rvSize);
- if (status != PR_SUCCESS) {
- if (allocated) {
- nss_ZFreeIf(rvOpt);
- }
- return (NSSCertificate **)NULL;
- }
- return rvOpt;
-}
-
-/*
- * CRL/KRL collections
- */
-
-static void
-crl_destroyObject(nssPKIObject *o)
-{
- NSSCRL *crl = (NSSCRL *)o;
- nssCRL_Destroy(crl);
-}
-
-static PRStatus
-crl_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
-{
- NSSCRL *crl = (NSSCRL *)o;
- NSSDER *encoding;
- encoding = nssCRL_GetEncoding(crl);
- if (!encoding) {
- nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
- return PR_FALSE;
- }
- uid[0] = *encoding;
- uid[1].data = NULL; uid[1].size = 0;
- return PR_SUCCESS;
-}
-
-static PRStatus
-crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
- NSSArena *arena)
-{
- return nssCryptokiCRL_GetAttributes(instance,
- NULL, /* XXX sessionOpt */
- arena, /* arena */
- &uid[0], /* encoding */
- NULL, /* subject */
- NULL, /* class */
- NULL, /* url */
- NULL); /* isKRL */
-}
-
-static nssPKIObject *
-crl_createObject(nssPKIObject *o)
-{
- return (nssPKIObject *)nssCRL_Create(o);
-}
-
-NSS_IMPLEMENT nssPKIObjectCollection *
-nssCRLCollection_Create (
- NSSTrustDomain *td,
- NSSCRL **crlsOpt
-)
-{
- PRStatus status;
- nssPKIObjectCollection *collection;
- collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock);
- collection->objectType = pkiObjectType_CRL;
- collection->destroyObject = crl_destroyObject;
- collection->getUIDFromObject = crl_getUIDFromObject;
- collection->getUIDFromInstance = crl_getUIDFromInstance;
- collection->createObject = crl_createObject;
- if (crlsOpt) {
- for (; *crlsOpt; crlsOpt++) {
- nssPKIObject *object = (nssPKIObject *)(*crlsOpt);
- status = nssPKIObjectCollection_AddObject(collection, object);
- }
- }
- return collection;
-}
-
-NSS_IMPLEMENT NSSCRL **
-nssPKIObjectCollection_GetCRLs (
- nssPKIObjectCollection *collection,
- NSSCRL **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
- PRStatus status;
- PRUint32 rvSize;
- PRBool allocated = PR_FALSE;
- if (collection->size == 0) {
- return (NSSCRL **)NULL;
- }
- if (maximumOpt == 0) {
- rvSize = collection->size;
- } else {
- rvSize = PR_MIN(collection->size, maximumOpt);
- }
- if (!rvOpt) {
- rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCRL *, rvSize + 1);
- if (!rvOpt) {
- return (NSSCRL **)NULL;
- }
- allocated = PR_TRUE;
- }
- status = nssPKIObjectCollection_GetObjects(collection,
- (nssPKIObject **)rvOpt,
- rvSize);
- if (status != PR_SUCCESS) {
- if (allocated) {
- nss_ZFreeIf(rvOpt);
- }
- return (NSSCRL **)NULL;
- }
- return rvOpt;
-}
-
-/* how bad would it be to have a static now sitting around, updated whenever
- * this was called? would avoid repeated allocs...
- */
-NSS_IMPLEMENT NSSTime *
-NSSTime_Now (
- NSSTime *timeOpt
-)
-{
- return NSSTime_SetPRTime(timeOpt, PR_Now());
-}
-
-NSS_IMPLEMENT NSSTime *
-NSSTime_SetPRTime (
- NSSTime *timeOpt,
- PRTime prTime
-)
-{
- NSSTime *rvTime;
- rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime);
- if (rvTime) {
- rvTime->prTime = prTime;
- }
- return rvTime;
-}
-
-NSS_IMPLEMENT PRTime
-NSSTime_GetPRTime (
- NSSTime *time
-)
-{
- return time->prTime;
-}
-
diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h
deleted file mode 100644
index 04c0e723e..000000000
--- a/security/nss/lib/pki/pkim.h
+++ /dev/null
@@ -1,699 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef PKIM_H
-#define PKIM_H
-
-#ifdef DEBUG
-static const char PKIM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#ifndef PKI_H
-#include "pki.h"
-#endif /* PKI_H */
-
-#ifndef PKITM_H
-#include "pkitm.h"
-#endif /* PKITM_H */
-
-PR_BEGIN_EXTERN_C
-
-/* nssPKIObject
- *
- * This is the base object class, common to all PKI objects defined in
- * in this module. Each object can be safely 'casted' to an nssPKIObject,
- * then passed to these methods.
- *
- * nssPKIObject_Create
- * nssPKIObject_Destroy
- * nssPKIObject_AddRef
- * nssPKIObject_AddInstance
- * nssPKIObject_HasInstance
- * nssPKIObject_GetTokens
- * nssPKIObject_GetNicknameForToken
- * nssPKIObject_RemoveInstanceForToken
- * nssPKIObject_DeleteStoredObject
- */
-
-NSS_EXTERN void nssPKIObject_Lock (nssPKIObject * object);
-NSS_EXTERN void nssPKIObject_Unlock (nssPKIObject * object);
-NSS_EXTERN PRStatus nssPKIObject_NewLock (nssPKIObject * object,
- nssPKILockType lockType);
-NSS_EXTERN void nssPKIObject_DestroyLock(nssPKIObject * object);
-
-/* nssPKIObject_Create
- *
- * A generic PKI object. It must live in a trust domain. It may be
- * initialized with a token instance, or alternatively in a crypto context.
- */
-NSS_EXTERN nssPKIObject *
-nssPKIObject_Create
-(
- NSSArena *arenaOpt,
- nssCryptokiObject *instanceOpt,
- NSSTrustDomain *td,
- NSSCryptoContext *ccOpt,
- nssPKILockType lockType
-);
-
-/* nssPKIObject_AddRef
- */
-NSS_EXTERN nssPKIObject *
-nssPKIObject_AddRef
-(
- nssPKIObject *object
-);
-
-/* nssPKIObject_Destroy
- *
- * Returns true if object was destroyed. This notifies the subclass that
- * all references are gone and it should delete any members it owns.
- */
-NSS_EXTERN PRBool
-nssPKIObject_Destroy
-(
- nssPKIObject *object
-);
-
-/* nssPKIObject_AddInstance
- *
- * Add a token instance to the object, if it does not have it already.
- */
-NSS_EXTERN PRStatus
-nssPKIObject_AddInstance
-(
- nssPKIObject *object,
- nssCryptokiObject *instance
-);
-
-/* nssPKIObject_HasInstance
- *
- * Query the object for a token instance.
- */
-NSS_EXTERN PRBool
-nssPKIObject_HasInstance
-(
- nssPKIObject *object,
- nssCryptokiObject *instance
-);
-
-/* nssPKIObject_GetTokens
- *
- * Get all tokens which have an instance of the object.
- */
-NSS_EXTERN NSSToken **
-nssPKIObject_GetTokens
-(
- nssPKIObject *object,
- PRStatus *statusOpt
-);
-
-/* nssPKIObject_GetNicknameForToken
- *
- * tokenOpt == NULL means take the first available, otherwise return the
- * nickname for the specified token.
- */
-NSS_EXTERN NSSUTF8 *
-nssPKIObject_GetNicknameForToken
-(
- nssPKIObject *object,
- NSSToken *tokenOpt
-);
-
-/* nssPKIObject_RemoveInstanceForToken
- *
- * Remove the instance of the object on the specified token.
- */
-NSS_EXTERN PRStatus
-nssPKIObject_RemoveInstanceForToken
-(
- nssPKIObject *object,
- NSSToken *token
-);
-
-/* nssPKIObject_DeleteStoredObject
- *
- * Delete all token instances of the object, as well as any crypto context
- * instances (TODO). If any of the instances are read-only, or if the
- * removal fails, the object will keep those instances. 'isFriendly' refers
- * to the object -- can this object be removed from a friendly token without
- * login? For example, certificates are friendly, private keys are not.
- * Note that if the token is not friendly, authentication will be required
- * regardless of the value of 'isFriendly'.
- */
-NSS_EXTERN PRStatus
-nssPKIObject_DeleteStoredObject
-(
- nssPKIObject *object,
- NSSCallback *uhh,
- PRBool isFriendly
-);
-
-NSS_EXTERN nssCryptokiObject **
-nssPKIObject_GetInstances
-(
- nssPKIObject *object
-);
-
-NSS_EXTERN NSSCertificate **
-nssTrustDomain_FindCertificatesByID
-(
- NSSTrustDomain *td,
- NSSItem *id,
- NSSCertificate **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSCRL **
-nssTrustDomain_FindCRLsBySubject
-(
- NSSTrustDomain *td,
- NSSDER *subject
-);
-
-/* module-private nsspki methods */
-
-NSS_EXTERN NSSCryptoContext *
-nssCryptoContext_Create
-(
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-);
-
-/* XXX for the collection */
-NSS_EXTERN NSSCertificate *
-nssCertificate_Create
-(
- nssPKIObject *object
-);
-
-NSS_EXTERN PRStatus
-nssCertificate_SetCertTrust
-(
- NSSCertificate *c,
- NSSTrust *trust
-);
-
-NSS_EXTERN nssDecodedCert *
-nssCertificate_GetDecoding
-(
- NSSCertificate *c
-);
-
-extern PRIntn
-nssCertificate_SubjectListSort
-(
- void *v1,
- void *v2
-);
-
-NSS_EXTERN nssDecodedCert *
-nssDecodedCert_Create
-(
- NSSArena *arenaOpt,
- NSSDER *encoding,
- NSSCertificateType type
-);
-
-NSS_EXTERN PRStatus
-nssDecodedCert_Destroy
-(
- nssDecodedCert *dc
-);
-
-NSS_EXTERN NSSTrust *
-nssTrust_Create
-(
- nssPKIObject *object,
- NSSItem *certData
-);
-
-NSS_EXTERN NSSCRL *
-nssCRL_Create
-(
- nssPKIObject *object
-);
-
-NSS_EXTERN NSSCRL *
-nssCRL_AddRef
-(
- NSSCRL *crl
-);
-
-NSS_EXTERN PRStatus
-nssCRL_Destroy
-(
- NSSCRL *crl
-);
-
-NSS_EXTERN PRStatus
-nssCRL_DeleteStoredObject
-(
- NSSCRL *crl,
- NSSCallback *uhh
-);
-
-NSS_EXTERN NSSPrivateKey *
-nssPrivateKey_Create
-(
- nssPKIObject *o
-);
-
-NSS_EXTERN NSSDER *
-nssCRL_GetEncoding
-(
- NSSCRL *crl
-);
-
-NSS_EXTERN NSSPublicKey *
-nssPublicKey_Create
-(
- nssPKIObject *object
-);
-
-/* nssCertificateArray
- *
- * These are being thrown around a lot, might as well group together some
- * functionality.
- *
- * nssCertificateArray_Destroy
- * nssCertificateArray_Join
- * nssCertificateArray_FindBestCertificate
- * nssCertificateArray_Traverse
- */
-
-/* nssCertificateArray_Destroy
- *
- * Will destroy the array and the certs within it. If the array was created
- * in an arena, will *not* (of course) destroy the arena. However, is safe
- * to call this method on an arena-allocated array.
- */
-NSS_EXTERN void
-nssCertificateArray_Destroy
-(
- NSSCertificate **certs
-);
-
-/* nssCertificateArray_Join
- *
- * Join two arrays into one. The two arrays, certs1 and certs2, should
- * be considered invalid after a call to this function (they may be destroyed
- * as part of the join). certs1 and/or certs2 may be NULL. Safe to
- * call with arrays allocated in an arena, the result will also be in the
- * arena.
- */
-NSS_EXTERN NSSCertificate **
-nssCertificateArray_Join
-(
- NSSCertificate **certs1,
- NSSCertificate **certs2
-);
-
-/* nssCertificateArray_FindBestCertificate
- *
- * Use the usual { time, usage, policies } to find the best cert in the
- * array.
- */
-NSS_EXTERN NSSCertificate *
-nssCertificateArray_FindBestCertificate
-(
- NSSCertificate **certs,
- NSSTime *timeOpt,
- const NSSUsage *usage,
- NSSPolicies *policiesOpt
-);
-
-/* nssCertificateArray_Traverse
- *
- * Do the callback for each cert, terminate the traversal if the callback
- * fails.
- */
-NSS_EXTERN PRStatus
-nssCertificateArray_Traverse
-(
- NSSCertificate **certs,
- PRStatus (* callback)(NSSCertificate *c, void *arg),
- void *arg
-);
-
-NSS_EXTERN void
-nssCRLArray_Destroy
-(
- NSSCRL **crls
-);
-
-/* nssPKIObjectCollection
- *
- * This is a handy way to group objects together and perform operations
- * on them. It can also handle "proto-objects"-- references to
- * objects instances on tokens, where the actual object hasn't
- * been formed yet.
- *
- * nssCertificateCollection_Create
- * nssPrivateKeyCollection_Create
- * nssPublicKeyCollection_Create
- *
- * If this was a language that provided for inheritance, each type would
- * inherit all of the following methods. Instead, there is only one
- * type (nssPKIObjectCollection), shared among all. This may cause
- * confusion; an alternative would be to define all of the methods
- * for each subtype (nssCertificateCollection_Destroy, ...), but that doesn't
- * seem worth the code bloat.. It is left up to the caller to remember
- * what type of collection he/she is dealing with.
- *
- * nssPKIObjectCollection_Destroy
- * nssPKIObjectCollection_Count
- * nssPKIObjectCollection_AddObject
- * nssPKIObjectCollection_AddInstances
- * nssPKIObjectCollection_Traverse
- *
- * Back to type-specific methods.
- *
- * nssPKIObjectCollection_GetCertificates
- * nssPKIObjectCollection_GetCRLs
- * nssPKIObjectCollection_GetPrivateKeys
- * nssPKIObjectCollection_GetPublicKeys
- */
-
-/* nssCertificateCollection_Create
- *
- * Create a collection of certificates in the specified trust domain.
- * Optionally provide a starting set of certs.
- */
-NSS_EXTERN nssPKIObjectCollection *
-nssCertificateCollection_Create
-(
- NSSTrustDomain *td,
- NSSCertificate **certsOpt
-);
-
-/* nssCRLCollection_Create
- *
- * Create a collection of CRLs/KRLs in the specified trust domain.
- * Optionally provide a starting set of CRLs.
- */
-NSS_EXTERN nssPKIObjectCollection *
-nssCRLCollection_Create
-(
- NSSTrustDomain *td,
- NSSCRL **crlsOpt
-);
-
-/* nssPrivateKeyCollection_Create
- *
- * Create a collection of private keys in the specified trust domain.
- * Optionally provide a starting set of keys.
- */
-NSS_EXTERN nssPKIObjectCollection *
-nssPrivateKeyCollection_Create
-(
- NSSTrustDomain *td,
- NSSPrivateKey **pvkOpt
-);
-
-/* nssPublicKeyCollection_Create
- *
- * Create a collection of public keys in the specified trust domain.
- * Optionally provide a starting set of keys.
- */
-NSS_EXTERN nssPKIObjectCollection *
-nssPublicKeyCollection_Create
-(
- NSSTrustDomain *td,
- NSSPublicKey **pvkOpt
-);
-
-/* nssPKIObjectCollection_Destroy
- */
-NSS_EXTERN void
-nssPKIObjectCollection_Destroy
-(
- nssPKIObjectCollection *collection
-);
-
-/* nssPKIObjectCollection_Count
- */
-NSS_EXTERN PRUint32
-nssPKIObjectCollection_Count
-(
- nssPKIObjectCollection *collection
-);
-
-NSS_EXTERN PRStatus
-nssPKIObjectCollection_AddObject
-(
- nssPKIObjectCollection *collection,
- nssPKIObject *object
-);
-
-/* nssPKIObjectCollection_AddInstances
- *
- * Add a set of object instances to the collection. The instances
- * will be sorted into any existing certs/proto-certs that may be in
- * the collection. The instances will be absorbed by the collection,
- * the array should not be used after this call (except to free it).
- *
- * Failure means the collection is in an invalid state.
- *
- * numInstances = 0 means the array is NULL-terminated
- */
-NSS_EXTERN PRStatus
-nssPKIObjectCollection_AddInstances
-(
- nssPKIObjectCollection *collection,
- nssCryptokiObject **instances,
- PRUint32 numInstances
-);
-
-/* nssPKIObjectCollection_Traverse
- */
-NSS_EXTERN PRStatus
-nssPKIObjectCollection_Traverse
-(
- nssPKIObjectCollection *collection,
- nssPKIObjectCallback *callback
-);
-
-/* This function is being added for NSS 3.5. It corresponds to the function
- * nssToken_TraverseCertificates. The idea is to use the collection during
- * a traversal, creating certs each time a new instance is added for which
- * a cert does not already exist.
- */
-NSS_EXTERN PRStatus
-nssPKIObjectCollection_AddInstanceAsObject
-(
- nssPKIObjectCollection *collection,
- nssCryptokiObject *instance
-);
-
-/* nssPKIObjectCollection_GetCertificates
- *
- * Get all of the certificates in the collection.
- */
-NSS_EXTERN NSSCertificate **
-nssPKIObjectCollection_GetCertificates
-(
- nssPKIObjectCollection *collection,
- NSSCertificate **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSCRL **
-nssPKIObjectCollection_GetCRLs
-(
- nssPKIObjectCollection *collection,
- NSSCRL **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSPrivateKey **
-nssPKIObjectCollection_GetPrivateKeys
-(
- nssPKIObjectCollection *collection,
- NSSPrivateKey **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSPublicKey **
-nssPKIObjectCollection_GetPublicKeys
-(
- nssPKIObjectCollection *collection,
- NSSPublicKey **rvOpt,
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSTime *
-NSSTime_Now
-(
- NSSTime *timeOpt
-);
-
-NSS_EXTERN NSSTime *
-NSSTime_SetPRTime
-(
- NSSTime *timeOpt,
- PRTime prTime
-);
-
-NSS_EXTERN PRTime
-NSSTime_GetPRTime
-(
- NSSTime *time
-);
-
-NSS_EXTERN nssHash *
-nssHash_CreateCertificate
-(
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-);
-
-/* 3.4 Certificate cache routines */
-
-NSS_EXTERN PRStatus
-nssTrustDomain_InitializeCache
-(
- NSSTrustDomain *td,
- PRUint32 cacheSize
-);
-
-NSS_EXTERN PRStatus
-nssTrustDomain_AddCertsToCache
-(
- NSSTrustDomain *td,
- NSSCertificate **certs,
- PRUint32 numCerts
-);
-
-NSS_EXTERN void
-nssTrustDomain_RemoveCertFromCacheLOCKED (
- NSSTrustDomain *td,
- NSSCertificate *cert
-);
-
-NSS_EXTERN void
-nssTrustDomain_LockCertCache (
- NSSTrustDomain *td
-);
-
-NSS_EXTERN void
-nssTrustDomain_UnlockCertCache (
- NSSTrustDomain *td
-);
-
-NSS_IMPLEMENT PRStatus
-nssTrustDomain_DestroyCache
-(
- NSSTrustDomain *td
-);
-
-/*
- * Remove all certs for the given token from the cache. This is
- * needed if the token is removed.
- */
-NSS_EXTERN PRStatus
-nssTrustDomain_RemoveTokenCertsFromCache
-(
- NSSTrustDomain *td,
- NSSToken *token
-);
-
-NSS_EXTERN PRStatus
-nssTrustDomain_UpdateCachedTokenCerts
-(
- NSSTrustDomain *td,
- NSSToken *token
-);
-
-/*
- * Find all cached certs with this nickname (label).
- */
-NSS_EXTERN NSSCertificate **
-nssTrustDomain_GetCertsForNicknameFromCache
-(
- NSSTrustDomain *td,
- const NSSUTF8 *nickname,
- nssList *certListOpt
-);
-
-/*
- * Find all cached certs with this email address.
- */
-NSS_EXTERN NSSCertificate **
-nssTrustDomain_GetCertsForEmailAddressFromCache
-(
- NSSTrustDomain *td,
- NSSASCII7 *email,
- nssList *certListOpt
-);
-
-/*
- * Find all cached certs with this subject.
- */
-NSS_EXTERN NSSCertificate **
-nssTrustDomain_GetCertsForSubjectFromCache
-(
- NSSTrustDomain *td,
- NSSDER *subject,
- nssList *certListOpt
-);
-
-/*
- * Look for a specific cert in the cache.
- */
-NSS_EXTERN NSSCertificate *
-nssTrustDomain_GetCertForIssuerAndSNFromCache
-(
- NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serialNum
-);
-
-/*
- * Look for a specific cert in the cache.
- */
-NSS_EXTERN NSSCertificate *
-nssTrustDomain_GetCertByDERFromCache
-(
- NSSTrustDomain *td,
- NSSDER *der
-);
-
-/* Get all certs from the cache */
-/* XXX this is being included to make some old-style calls word, not to
- * say we should keep it
- */
-NSS_EXTERN NSSCertificate **
-nssTrustDomain_GetCertsFromCache
-(
- NSSTrustDomain *td,
- nssList *certListOpt
-);
-
-NSS_EXTERN void
-nssTrustDomain_DumpCacheInfo
-(
- NSSTrustDomain *td,
- void (* cert_dump_iter)(const void *, void *, void *),
- void *arg
-);
-
-NSS_EXTERN void
-nssCertificateList_AddReferences
-(
- nssList *certList
-);
-
-PR_END_EXTERN_C
-
-#endif /* PKIM_H */
diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c
deleted file mode 100644
index 319dd7d43..000000000
--- a/security/nss/lib/pki/pkistore.c
+++ /dev/null
@@ -1,743 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef PKIM_H
-#include "pkim.h"
-#endif /* PKIM_H */
-
-#ifndef PKI_H
-#include "pki.h"
-#endif /* PKI_H */
-
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#ifndef PKISTORE_H
-#include "pkistore.h"
-#endif /* PKISTORE_H */
-
-#include "cert.h"
-
-#include "prbit.h"
-
-/*
- * Certificate Store
- *
- * This differs from the cache in that it is a true storage facility. Items
- * stay in until they are explicitly removed. It is only used by crypto
- * contexts at this time, but may be more generally useful...
- *
- */
-
-struct nssCertificateStoreStr
-{
- PRBool i_alloced_arena;
- NSSArena *arena;
- PZLock *lock;
- nssHash *subject;
- nssHash *issuer_and_serial;
-};
-
-typedef struct certificate_hash_entry_str certificate_hash_entry;
-
-struct certificate_hash_entry_str
-{
- NSSCertificate *cert;
- NSSTrust *trust;
- nssSMIMEProfile *profile;
-};
-
-/* forward static declarations */
-static NSSCertificate *
-nssCertStore_FindCertByIssuerAndSerialNumberLocked (
- nssCertificateStore *store,
- NSSDER *issuer,
- NSSDER *serial
-);
-
-NSS_IMPLEMENT nssCertificateStore *
-nssCertificateStore_Create (
- NSSArena *arenaOpt
-)
-{
- NSSArena *arena;
- nssCertificateStore *store;
- PRBool i_alloced_arena;
- if (arenaOpt) {
- arena = arenaOpt;
- i_alloced_arena = PR_FALSE;
- } else {
- arena = nssArena_Create();
- if (!arena) {
- return NULL;
- }
- i_alloced_arena = PR_TRUE;
- }
- store = nss_ZNEW(arena, nssCertificateStore);
- if (!store) {
- goto loser;
- }
- store->lock = PZ_NewLock(nssILockOther);
- if (!store->lock) {
- goto loser;
- }
- /* Create the issuer/serial --> {cert, trust, S/MIME profile } hash */
- store->issuer_and_serial = nssHash_CreateCertificate(arena, 0);
- if (!store->issuer_and_serial) {
- goto loser;
- }
- /* Create the subject DER --> subject list hash */
- store->subject = nssHash_CreateItem(arena, 0);
- if (!store->subject) {
- goto loser;
- }
- store->arena = arena;
- store->i_alloced_arena = i_alloced_arena;
- return store;
-loser:
- if (store) {
- if (store->lock) {
- PZ_DestroyLock(store->lock);
- }
- if (store->issuer_and_serial) {
- nssHash_Destroy(store->issuer_and_serial);
- }
- if (store->subject) {
- nssHash_Destroy(store->subject);
- }
- }
- if (i_alloced_arena) {
- nssArena_Destroy(arena);
- }
- return NULL;
-}
-
-extern const NSSError NSS_ERROR_BUSY;
-
-NSS_IMPLEMENT PRStatus
-nssCertificateStore_Destroy (
- nssCertificateStore *store
-)
-{
- if (nssHash_Count(store->issuer_and_serial) > 0) {
- nss_SetError(NSS_ERROR_BUSY);
- return PR_FAILURE;
- }
- PZ_DestroyLock(store->lock);
- nssHash_Destroy(store->issuer_and_serial);
- nssHash_Destroy(store->subject);
- if (store->i_alloced_arena) {
- nssArena_Destroy(store->arena);
- } else {
- nss_ZFreeIf(store);
- }
- return PR_SUCCESS;
-}
-
-static PRStatus
-add_certificate_entry (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
-{
- PRStatus nssrv;
- certificate_hash_entry *entry;
- entry = nss_ZNEW(cert->object.arena, certificate_hash_entry);
- if (!entry) {
- return PR_FAILURE;
- }
- entry->cert = cert;
- nssrv = nssHash_Add(store->issuer_and_serial, cert, entry);
- if (nssrv != PR_SUCCESS) {
- nss_ZFreeIf(entry);
- }
- return nssrv;
-}
-
-static PRStatus
-add_subject_entry (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
-{
- PRStatus nssrv;
- nssList *subjectList;
- subjectList = (nssList *)nssHash_Lookup(store->subject, &cert->subject);
- if (subjectList) {
- /* The subject is already in, add this cert to the list */
- nssrv = nssList_AddUnique(subjectList, cert);
- } else {
- /* Create a new subject list for the subject */
- subjectList = nssList_Create(NULL, PR_FALSE);
- if (!subjectList) {
- return PR_FAILURE;
- }
- nssList_SetSortFunction(subjectList, nssCertificate_SubjectListSort);
- /* Add the cert entry to this list of subjects */
- nssrv = nssList_Add(subjectList, cert);
- if (nssrv != PR_SUCCESS) {
- return nssrv;
- }
- /* Add the subject list to the cache */
- nssrv = nssHash_Add(store->subject, &cert->subject, subjectList);
- }
- return nssrv;
-}
-
-/* declared below */
-static void
-remove_certificate_entry (
- nssCertificateStore *store,
- NSSCertificate *cert
-);
-
-/* Caller must hold store->lock */
-static PRStatus
-nssCertificateStore_AddLocked (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
-{
- PRStatus nssrv = add_certificate_entry(store, cert);
- if (nssrv == PR_SUCCESS) {
- nssrv = add_subject_entry(store, cert);
- if (nssrv == PR_FAILURE) {
- remove_certificate_entry(store, cert);
- }
- }
- return nssrv;
-}
-
-
-NSS_IMPLEMENT NSSCertificate *
-nssCertificateStore_FindOrAdd (
- nssCertificateStore *store,
- NSSCertificate *c
-)
-{
- PRStatus nssrv;
- NSSCertificate *rvCert = NULL;
-
- PZ_Lock(store->lock);
- rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked(
- store, &c->issuer, &c->serial);
- if (!rvCert) {
- nssrv = nssCertificateStore_AddLocked(store, c);
- if (PR_SUCCESS == nssrv) {
- rvCert = nssCertificate_AddRef(c);
- }
- }
- PZ_Unlock(store->lock);
- return rvCert;
-}
-
-static void
-remove_certificate_entry (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
-{
- certificate_hash_entry *entry;
- entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, cert);
- if (entry) {
- nssHash_Remove(store->issuer_and_serial, cert);
- if (entry->trust) {
- nssTrust_Destroy(entry->trust);
- }
- if (entry->profile) {
- nssSMIMEProfile_Destroy(entry->profile);
- }
- nss_ZFreeIf(entry);
- }
-}
-
-static void
-remove_subject_entry (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
-{
- nssList *subjectList;
- /* Get the subject list for the cert's subject */
- subjectList = (nssList *)nssHash_Lookup(store->subject, &cert->subject);
- if (subjectList) {
- /* Remove the cert from the subject hash */
- nssList_Remove(subjectList, cert);
- nssHash_Remove(store->subject, &cert->subject);
- if (nssList_Count(subjectList) == 0) {
- nssList_Destroy(subjectList);
- } else {
- /* The cert being released may have keyed the subject entry.
- * Since there are still subject certs around, get another and
- * rekey the entry just in case.
- */
- NSSCertificate *subjectCert;
- (void)nssList_GetArray(subjectList, (void **)&subjectCert, 1);
- nssHash_Add(store->subject, &subjectCert->subject, subjectList);
- }
- }
-}
-
-NSS_IMPLEMENT void
-nssCertificateStore_RemoveCertLOCKED (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
-{
- certificate_hash_entry *entry;
- entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, cert);
- if (entry && entry->cert == cert) {
- remove_certificate_entry(store, cert);
- remove_subject_entry(store, cert);
- }
-}
-
-NSS_IMPLEMENT void
-nssCertificateStore_Lock (
- nssCertificateStore *store, nssCertificateStoreTrace* out
-)
-{
-#ifdef DEBUG
- PORT_Assert(out);
- out->store = store;
- out->lock = store->lock;
- out->locked = PR_TRUE;
- PZ_Lock(out->lock);
-#else
- PZ_Lock(store->lock);
-#endif
-}
-
-NSS_IMPLEMENT void
-nssCertificateStore_Unlock (
- nssCertificateStore *store, const nssCertificateStoreTrace* in,
- nssCertificateStoreTrace* out
-)
-{
-#ifdef DEBUG
- PORT_Assert(in);
- PORT_Assert(out);
- out->store = store;
- out->lock = store->lock;
- PORT_Assert(!out->locked);
- out->unlocked = PR_TRUE;
-
- PORT_Assert(in->store == out->store);
- PORT_Assert(in->lock == out->lock);
- PORT_Assert(in->locked);
- PORT_Assert(!in->unlocked);
-
- PZ_Unlock(out->lock);
-#else
- PZ_Unlock(store->lock);
-#endif
-}
-
-static NSSCertificate **
-get_array_from_list (
- nssList *certList,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
- PRUint32 count;
- NSSCertificate **rvArray = NULL;
- count = nssList_Count(certList);
- if (count == 0) {
- return NULL;
- }
- if (maximumOpt > 0) {
- count = PR_MIN(maximumOpt, count);
- }
- if (rvOpt) {
- nssList_GetArray(certList, (void **)rvOpt, count);
- } else {
- rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
- if (rvArray) {
- nssList_GetArray(certList, (void **)rvArray, count);
- }
- }
- return rvArray;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-nssCertificateStore_FindCertificatesBySubject (
- nssCertificateStore *store,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
- NSSCertificate **rvArray = NULL;
- nssList *subjectList;
- PZ_Lock(store->lock);
- subjectList = (nssList *)nssHash_Lookup(store->subject, subject);
- if (subjectList) {
- nssCertificateList_AddReferences(subjectList);
- rvArray = get_array_from_list(subjectList,
- rvOpt, maximumOpt, arenaOpt);
- }
- PZ_Unlock(store->lock);
- return rvArray;
-}
-
-/* Because only subject indexing is implemented, all other lookups require
- * full traversal (unfortunately, PLHashTable doesn't allow you to exit
- * early from the enumeration). The assumptions are that 1) lookups by
- * fields other than subject will be rare, and 2) the hash will not have
- * a large number of entries. These assumptions will be tested.
- *
- * XXX
- * For NSS 3.4, it is worth consideration to do all forms of indexing,
- * because the only crypto context is global and persistent.
- */
-
-struct nickname_template_str
-{
- NSSUTF8 *nickname;
- nssList *subjectList;
-};
-
-static void match_nickname(const void *k, void *v, void *a)
-{
- PRStatus nssrv;
- NSSCertificate *c;
- NSSUTF8 *nickname;
- nssList *subjectList = (nssList *)v;
- struct nickname_template_str *nt = (struct nickname_template_str *)a;
- nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
- nickname = nssCertificate_GetNickname(c, NULL);
- if (nssrv == PR_SUCCESS && nickname &&
- nssUTF8_Equal(nickname, nt->nickname, &nssrv))
- {
- nt->subjectList = subjectList;
- }
- nss_ZFreeIf(nickname);
-}
-
-/*
- * Find all cached certs with this label.
- */
-NSS_IMPLEMENT NSSCertificate **
-nssCertificateStore_FindCertificatesByNickname (
- nssCertificateStore *store,
- const NSSUTF8 *nickname,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
- NSSCertificate **rvArray = NULL;
- struct nickname_template_str nt;
- nt.nickname = (char*) nickname;
- nt.subjectList = NULL;
- PZ_Lock(store->lock);
- nssHash_Iterate(store->subject, match_nickname, &nt);
- if (nt.subjectList) {
- nssCertificateList_AddReferences(nt.subjectList);
- rvArray = get_array_from_list(nt.subjectList,
- rvOpt, maximumOpt, arenaOpt);
- }
- PZ_Unlock(store->lock);
- return rvArray;
-}
-
-struct email_template_str
-{
- NSSASCII7 *email;
- nssList *emailList;
-};
-
-static void match_email(const void *k, void *v, void *a)
-{
- PRStatus nssrv;
- NSSCertificate *c;
- nssList *subjectList = (nssList *)v;
- struct email_template_str *et = (struct email_template_str *)a;
- nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
- if (nssrv == PR_SUCCESS &&
- nssUTF8_Equal(c->email, et->email, &nssrv))
- {
- nssListIterator *iter = nssList_CreateIterator(subjectList);
- if (iter) {
- for (c = (NSSCertificate *)nssListIterator_Start(iter);
- c != (NSSCertificate *)NULL;
- c = (NSSCertificate *)nssListIterator_Next(iter))
- {
- nssList_Add(et->emailList, c);
- }
- nssListIterator_Finish(iter);
- nssListIterator_Destroy(iter);
- }
- }
-}
-
-/*
- * Find all cached certs with this email address.
- */
-NSS_IMPLEMENT NSSCertificate **
-nssCertificateStore_FindCertificatesByEmail (
- nssCertificateStore *store,
- NSSASCII7 *email,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
- NSSCertificate **rvArray = NULL;
- struct email_template_str et;
- et.email = email;
- et.emailList = nssList_Create(NULL, PR_FALSE);
- if (!et.emailList) {
- return NULL;
- }
- PZ_Lock(store->lock);
- nssHash_Iterate(store->subject, match_email, &et);
- if (et.emailList) {
- /* get references before leaving the store's lock protection */
- nssCertificateList_AddReferences(et.emailList);
- }
- PZ_Unlock(store->lock);
- if (et.emailList) {
- rvArray = get_array_from_list(et.emailList,
- rvOpt, maximumOpt, arenaOpt);
- nssList_Destroy(et.emailList);
- }
- return rvArray;
-}
-
-/* Caller holds store->lock */
-static NSSCertificate *
-nssCertStore_FindCertByIssuerAndSerialNumberLocked (
- nssCertificateStore *store,
- NSSDER *issuer,
- NSSDER *serial
-)
-{
- certificate_hash_entry *entry;
- NSSCertificate *rvCert = NULL;
- NSSCertificate index;
-
- index.issuer = *issuer;
- index.serial = *serial;
- entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, &index);
- if (entry) {
- rvCert = nssCertificate_AddRef(entry->cert);
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-nssCertificateStore_FindCertificateByIssuerAndSerialNumber (
- nssCertificateStore *store,
- NSSDER *issuer,
- NSSDER *serial
-)
-{
- NSSCertificate *rvCert = NULL;
-
- PZ_Lock(store->lock);
- rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked (
- store, issuer, serial);
- PZ_Unlock(store->lock);
- return rvCert;
-}
-
-static PRStatus
-issuer_and_serial_from_encoding (
- NSSBER *encoding,
- NSSDER *issuer,
- NSSDER *serial
-)
-{
- SECItem derCert, derIssuer, derSerial;
- SECStatus secrv;
- derCert.data = (unsigned char *)encoding->data;
- derCert.len = encoding->size;
- secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
- if (secrv != SECSuccess) {
- return PR_FAILURE;
- }
- secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
- if (secrv != SECSuccess) {
- PORT_Free(derIssuer.data);
- return PR_FAILURE;
- }
- issuer->data = derIssuer.data;
- issuer->size = derIssuer.len;
- serial->data = derSerial.data;
- serial->size = derSerial.len;
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-nssCertificateStore_FindCertificateByEncodedCertificate (
- nssCertificateStore *store,
- NSSDER *encoding
-)
-{
- PRStatus nssrv = PR_FAILURE;
- NSSDER issuer, serial;
- NSSCertificate *rvCert = NULL;
- nssrv = issuer_and_serial_from_encoding(encoding, &issuer, &serial);
- if (nssrv != PR_SUCCESS) {
- return NULL;
- }
- rvCert = nssCertificateStore_FindCertificateByIssuerAndSerialNumber(store,
- &issuer,
- &serial);
- PORT_Free(issuer.data);
- PORT_Free(serial.data);
- return rvCert;
-}
-
-NSS_EXTERN PRStatus
-nssCertificateStore_AddTrust (
- nssCertificateStore *store,
- NSSTrust *trust
-)
-{
- NSSCertificate *cert;
- certificate_hash_entry *entry;
- cert = trust->certificate;
- PZ_Lock(store->lock);
- entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, cert);
- if (entry) {
- NSSTrust* newTrust = nssTrust_AddRef(trust);
- if (entry->trust) {
- nssTrust_Destroy(entry->trust);
- }
- entry->trust = newTrust;
- }
- PZ_Unlock(store->lock);
- return (entry) ? PR_SUCCESS : PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSTrust *
-nssCertificateStore_FindTrustForCertificate (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
-{
- certificate_hash_entry *entry;
- NSSTrust *rvTrust = NULL;
- PZ_Lock(store->lock);
- entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, cert);
- if (entry && entry->trust) {
- rvTrust = nssTrust_AddRef(entry->trust);
- }
- PZ_Unlock(store->lock);
- return rvTrust;
-}
-
-NSS_EXTERN PRStatus
-nssCertificateStore_AddSMIMEProfile (
- nssCertificateStore *store,
- nssSMIMEProfile *profile
-)
-{
- NSSCertificate *cert;
- certificate_hash_entry *entry;
- cert = profile->certificate;
- PZ_Lock(store->lock);
- entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, cert);
- if (entry) {
- nssSMIMEProfile* newProfile = nssSMIMEProfile_AddRef(profile);
- if (entry->profile) {
- nssSMIMEProfile_Destroy(entry->profile);
- }
- entry->profile = newProfile;
- }
- PZ_Unlock(store->lock);
- return (entry) ? PR_SUCCESS : PR_FAILURE;
-}
-
-NSS_IMPLEMENT nssSMIMEProfile *
-nssCertificateStore_FindSMIMEProfileForCertificate (
- nssCertificateStore *store,
- NSSCertificate *cert
-)
-{
- certificate_hash_entry *entry;
- nssSMIMEProfile *rvProfile = NULL;
- PZ_Lock(store->lock);
- entry = (certificate_hash_entry *)
- nssHash_Lookup(store->issuer_and_serial, cert);
- if (entry && entry->profile) {
- rvProfile = nssSMIMEProfile_AddRef(entry->profile);
- }
- PZ_Unlock(store->lock);
- return rvProfile;
-}
-
-/* XXX this is also used by cache and should be somewhere else */
-
-static PLHashNumber
-nss_certificate_hash (
- const void *key
-)
-{
- unsigned int i;
- PLHashNumber h;
- NSSCertificate *c = (NSSCertificate *)key;
- h = 0;
- for (i=0; i<c->issuer.size; i++)
- h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)c->issuer.data)[i];
- for (i=0; i<c->serial.size; i++)
- h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)c->serial.data)[i];
- return h;
-}
-
-static int
-nss_compare_certs(const void *v1, const void *v2)
-{
- PRStatus ignore;
- NSSCertificate *c1 = (NSSCertificate *)v1;
- NSSCertificate *c2 = (NSSCertificate *)v2;
- return (int)(nssItem_Equal(&c1->issuer, &c2->issuer, &ignore) &&
- nssItem_Equal(&c1->serial, &c2->serial, &ignore));
-}
-
-NSS_IMPLEMENT nssHash *
-nssHash_CreateCertificate (
- NSSArena *arenaOpt,
- PRUint32 numBuckets
-)
-{
- return nssHash_Create(arenaOpt,
- numBuckets,
- nss_certificate_hash,
- nss_compare_certs,
- PL_CompareValues);
-}
-
-NSS_IMPLEMENT void
-nssCertificateStore_DumpStoreInfo (
- nssCertificateStore *store,
- void (* cert_dump_iter)(const void *, void *, void *),
- void *arg
-)
-{
- PZ_Lock(store->lock);
- nssHash_Iterate(store->issuer_and_serial, cert_dump_iter, arg);
- PZ_Unlock(store->lock);
-}
-
diff --git a/security/nss/lib/pki/pkistore.h b/security/nss/lib/pki/pkistore.h
deleted file mode 100644
index f3ddce262..000000000
--- a/security/nss/lib/pki/pkistore.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef PKISTORE_H
-#define PKISTORE_H
-
-#ifdef DEBUG
-static const char PKISTORE_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef NSSPKIT_H
-#include "nsspkit.h"
-#endif /* NSSPKIT_H */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-PR_BEGIN_EXTERN_C
-
-/*
- * PKI Stores
- *
- * This is a set of routines for managing local stores of PKI objects.
- * Currently, the only application is in crypto contexts, where the
- * certificate store is used. In the future, methods should be added
- * here for storing local references to keys.
- */
-
-/*
- * nssCertificateStore
- *
- * Manages local store of certificate, trust, and S/MIME profile objects.
- * Within a crypto context, mappings of cert to trust and cert to S/MIME
- * profile are always 1-1. Therefore, it is reasonable to store all objects
- * in a single collection, indexed by the certificate.
- */
-
-NSS_EXTERN nssCertificateStore *
-nssCertificateStore_Create
-(
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN PRStatus
-nssCertificateStore_Destroy
-(
- nssCertificateStore *store
-);
-
-/* Atomic Find cert in store, or add this cert to the store.
-** Ref counts properly maintained.
-*/
-NSS_EXTERN NSSCertificate *
-nssCertificateStore_FindOrAdd
-(
- nssCertificateStore *store,
- NSSCertificate *c
-);
-
-NSS_EXTERN void
-nssCertificateStore_RemoveCertLOCKED
-(
- nssCertificateStore *store,
- NSSCertificate *cert
-);
-
-struct nssCertificateStoreTraceStr {
- nssCertificateStore* store;
- PZLock* lock;
- PRBool locked;
- PRBool unlocked;
-};
-
-typedef struct nssCertificateStoreTraceStr nssCertificateStoreTrace;
-
-NSS_EXTERN void
-nssCertificateStore_Lock (
- nssCertificateStore *store, nssCertificateStoreTrace* out
-);
-
-NSS_EXTERN void
-nssCertificateStore_Unlock (
- nssCertificateStore *store, const nssCertificateStoreTrace* in,
- nssCertificateStoreTrace* out
-);
-
-NSS_EXTERN NSSCertificate **
-nssCertificateStore_FindCertificatesBySubject
-(
- nssCertificateStore *store,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSCertificate **
-nssCertificateStore_FindCertificatesByNickname
-(
- nssCertificateStore *store,
- const NSSUTF8 *nickname,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSCertificate **
-nssCertificateStore_FindCertificatesByEmail
-(
- nssCertificateStore *store,
- NSSASCII7 *email,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-);
-
-NSS_EXTERN NSSCertificate *
-nssCertificateStore_FindCertificateByIssuerAndSerialNumber
-(
- nssCertificateStore *store,
- NSSDER *issuer,
- NSSDER *serial
-);
-
-NSS_EXTERN NSSCertificate *
-nssCertificateStore_FindCertificateByEncodedCertificate
-(
- nssCertificateStore *store,
- NSSDER *encoding
-);
-
-NSS_EXTERN PRStatus
-nssCertificateStore_AddTrust
-(
- nssCertificateStore *store,
- NSSTrust *trust
-);
-
-NSS_EXTERN NSSTrust *
-nssCertificateStore_FindTrustForCertificate
-(
- nssCertificateStore *store,
- NSSCertificate *cert
-);
-
-NSS_EXTERN PRStatus
-nssCertificateStore_AddSMIMEProfile
-(
- nssCertificateStore *store,
- nssSMIMEProfile *profile
-);
-
-NSS_EXTERN nssSMIMEProfile *
-nssCertificateStore_FindSMIMEProfileForCertificate
-(
- nssCertificateStore *store,
- NSSCertificate *cert
-);
-
-NSS_EXTERN void
-nssCertificateStore_DumpStoreInfo
-(
- nssCertificateStore *store,
- void (* cert_dump_iter)(const void *, void *, void *),
- void *arg
-);
-
-PR_END_EXTERN_C
-
-#endif /* PKISTORE_H */
diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h
deleted file mode 100644
index d44ffa32c..000000000
--- a/security/nss/lib/pki/pkit.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef PKIT_H
-#define PKIT_H
-
-#ifdef DEBUG
-static const char PKIT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * pkit.h
- *
- * This file contains definitions for the types of the top-level PKI objects.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef BASET_H
-#include "baset.h"
-#endif /* BASET_H */
-
-#include "certt.h"
-#include "pkcs11t.h"
-
-#ifndef NSSPKIT_H
-#include "nsspkit.h"
-#endif /* NSSPKIT_H */
-
-#ifndef NSSDEVT_H
-#include "nssdevt.h"
-#endif /* NSSDEVT_H */
-
-#ifndef DEVT_H
-#include "devt.h"
-#endif /* DEVT_H */
-
-#ifndef nssrwlkt_h__
-#include "nssrwlkt.h"
-#endif /* nssrwlkt_h__ */
-
-PR_BEGIN_EXTERN_C
-
-/*
- * A note on ephemeral certs
- *
- * The key objects defined here can only be created on tokens, and can only
- * exist on tokens. Therefore, any instance of a key object must have
- * a corresponding cryptoki instance. OTOH, certificates created in
- * crypto contexts need not be stored as session objects on the token.
- * There are good performance reasons for not doing so. The certificate
- * and trust objects have been defined with a cryptoContext field to
- * allow for ephemeral certs, which may have a single instance in a crypto
- * context along with any number (including zero) of cryptoki instances.
- * Since contexts may not share objects, there can be only one context
- * for each object.
- */
-
-typedef enum {
- nssPKILock = 1,
- nssPKIMonitor = 2
-} nssPKILockType;
-
-/* nssPKIObject
- *
- * This is the base object class, common to all PKI objects defined in
- * nsspkit.h
- */
-struct nssPKIObjectStr
-{
- /* The arena for all object memory */
- NSSArena *arena;
- /* Atomically incremented/decremented reference counting */
- PRInt32 refCount;
- /* lock protects the array of nssCryptokiInstance's of the object */
- union {
- PZLock* lock;
- PZMonitor *mlock;
- } sync;
- nssPKILockType lockType;
- /* XXX with LRU cache, this cannot be guaranteed up-to-date. It cannot
- * be compared against the update level of the trust domain, since it is
- * also affected by import/export. Where is this array needed?
- */
- nssCryptokiObject **instances;
- PRUint32 numInstances;
- /* The object must live in a trust domain */
- NSSTrustDomain *trustDomain;
- /* The object may live in a crypto context */
- NSSCryptoContext *cryptoContext;
- /* XXX added so temp certs can have nickname, think more ... */
- NSSUTF8 *tempName;
-};
-
-typedef struct nssDecodedCertStr nssDecodedCert;
-
-typedef struct nssCertificateStoreStr nssCertificateStore;
-
-/* How wide is the scope of this? */
-typedef struct nssSMIMEProfileStr nssSMIMEProfile;
-
-typedef struct nssPKIObjectStr nssPKIObject;
-
-struct NSSTrustStr
-{
- nssPKIObject object;
- NSSCertificate *certificate;
- nssTrustLevel serverAuth;
- nssTrustLevel clientAuth;
- nssTrustLevel emailProtection;
- nssTrustLevel codeSigning;
- PRBool stepUpApproved;
-};
-
-struct nssSMIMEProfileStr
-{
- nssPKIObject object;
- NSSCertificate *certificate;
- NSSASCII7 *email;
- NSSDER *subject;
- NSSItem *profileTime;
- NSSItem *profileData;
-};
-
-struct NSSCertificateStr
-{
- nssPKIObject object;
- NSSCertificateType type;
- NSSItem id;
- NSSBER encoding;
- NSSDER issuer;
- NSSDER subject;
- NSSDER serial;
- NSSASCII7 *email;
- nssDecodedCert *decoding;
-};
-
-struct NSSPrivateKeyStr;
-
-struct NSSPublicKeyStr;
-
-struct NSSSymmetricKeyStr;
-
-typedef struct nssTDCertificateCacheStr nssTDCertificateCache;
-
-struct NSSTrustDomainStr {
- PRInt32 refCount;
- NSSArena *arena;
- NSSCallback *defaultCallback;
- nssList *tokenList;
- nssListIterator *tokens;
- nssTDCertificateCache *cache;
- NSSRWLock *tokensLock;
- void *spkDigestInfo;
- CERTStatusConfig *statusConfig;
-};
-
-struct NSSCryptoContextStr
-{
- PRInt32 refCount;
- NSSArena *arena;
- NSSTrustDomain *td;
- NSSToken *token;
- nssSession *session;
- nssCertificateStore *certStore;
-};
-
-struct NSSTimeStr {
- PRTime prTime;
-};
-
-struct NSSCRLStr {
- nssPKIObject object;
- NSSDER encoding;
- NSSUTF8 *url;
- PRBool isKRL;
-};
-
-typedef struct NSSCRLStr NSSCRL;
-
-struct NSSPoliciesStr;
-
-struct NSSAlgorithmAndParametersStr;
-
-struct NSSPKIXCertificateStr;
-
-PR_END_EXTERN_C
-
-#endif /* PKIT_H */
diff --git a/security/nss/lib/pki/pkitm.h b/security/nss/lib/pki/pkitm.h
deleted file mode 100644
index edfeb2f97..000000000
--- a/security/nss/lib/pki/pkitm.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef PKITM_H
-#define PKITM_H
-
-#ifdef DEBUG
-static const char PKITM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * pkitm.h
- *
- * This file contains PKI-module specific types.
- */
-
-#ifndef BASET_H
-#include "baset.h"
-#endif /* BASET_H */
-
-#ifndef PKIT_H
-#include "pkit.h"
-#endif /* PKIT_H */
-
-PR_BEGIN_EXTERN_C
-
-typedef enum nssCertIDMatchEnum {
- nssCertIDMatch_Yes = 0,
- nssCertIDMatch_No = 1,
- nssCertIDMatch_Unknown = 2
-} nssCertIDMatch;
-
-/*
- * nssDecodedCert
- *
- * This is an interface to allow the PKI module access to certificate
- * information that can only be found by decoding. The interface is
- * generic, allowing each certificate type its own way of providing
- * the information
- */
-struct nssDecodedCertStr {
- NSSCertificateType type;
- void *data;
- /* returns the unique identifier for the cert */
- NSSItem * (*getIdentifier)(nssDecodedCert *dc);
- /* returns the unique identifier for this cert's issuer */
- void * (*getIssuerIdentifier)(nssDecodedCert *dc);
- /* is id the identifier for this cert? */
- nssCertIDMatch (*matchIdentifier)(nssDecodedCert *dc, void *id);
- /* is this cert a valid CA cert? */
- PRBool (*isValidIssuer)(nssDecodedCert *dc);
- /* returns the cert usage */
- NSSUsage * (*getUsage)(nssDecodedCert *dc);
- /* is time within the validity period of the cert? */
- PRBool (*isValidAtTime)(nssDecodedCert *dc, NSSTime *time);
- /* is the validity period of this cert newer than cmpdc? */
- PRBool (*isNewerThan)(nssDecodedCert *dc, nssDecodedCert *cmpdc);
- /* does the usage for this cert match the requested usage? */
- PRBool (*matchUsage)(nssDecodedCert *dc, const NSSUsage *usage);
- /* is this cert trusted for the requested usage? */
- PRBool (*isTrustedForUsage)(nssDecodedCert *dc,
- const NSSUsage *usage);
- /* extract the email address */
- NSSASCII7 *(*getEmailAddress)(nssDecodedCert *dc);
- /* extract the DER-encoded serial number */
- PRStatus (*getDERSerialNumber)(nssDecodedCert *dc,
- NSSDER *derSerial, NSSArena *arena);
-};
-
-struct NSSUsageStr {
- PRBool anyUsage;
- SECCertUsage nss3usage;
- PRBool nss3lookingForCA;
-};
-
-typedef struct nssPKIObjectCollectionStr nssPKIObjectCollection;
-
-typedef struct
-{
- union {
- PRStatus (* cert)(NSSCertificate *c, void *arg);
- PRStatus (* crl)(NSSCRL *crl, void *arg);
- PRStatus (* pvkey)(NSSPrivateKey *vk, void *arg);
- PRStatus (* pbkey)(NSSPublicKey *bk, void *arg);
- } func;
- void *arg;
-} nssPKIObjectCallback;
-
-PR_END_EXTERN_C
-
-#endif /* PKITM_H */
diff --git a/security/nss/lib/pki/symmkey.c b/security/nss/lib/pki/symmkey.c
deleted file mode 100644
index 34d43269d..000000000
--- a/security/nss/lib/pki/symmkey.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-extern const NSSError NSS_ERROR_NOT_FOUND;
-
-NSS_IMPLEMENT PRStatus
-NSSSymmetricKey_Destroy (
- NSSSymmetricKey *mk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSSymmetricKey_DeleteStoredObject (
- NSSSymmetricKey *mk,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRUint32
-NSSSymmetricKey_GetKeyLength (
- NSSSymmetricKey *mk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return -1;
-}
-
-NSS_IMPLEMENT PRUint32
-NSSSymmetricKey_GetKeyStrength (
- NSSSymmetricKey *mk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return -1;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSSymmetricKey_IsStillPresent (
- NSSSymmetricKey *mk
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSTrustDomain *
-NSSSymmetricKey_GetTrustDomain (
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSToken *
-NSSSymmetricKey_GetToken (
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSlot *
-NSSSymmetricKey_GetSlot (
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSModule *
-NSSSymmetricKey_GetModule (
- NSSSymmetricKey *mk,
- PRStatus *statusOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSSymmetricKey_Encrypt (
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSSymmetricKey_Decrypt (
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *encryptedData,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSSymmetricKey_Sign (
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSSymmetricKey_SignRecover (
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSSymmetricKey_Verify (
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *data,
- NSSItem *signature,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSSymmetricKey_VerifyRecover (
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *signature,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSSymmetricKey_WrapSymmetricKey (
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSSymmetricKey *keyToWrap,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSItem *
-NSSSymmetricKey_WrapPrivateKey (
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSPrivateKey *keyToWrap,
- NSSCallback *uhh,
- NSSItem *rvOpt,
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSSymmetricKey_UnwrapSymmetricKey (
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSOID *target,
- PRUint32 keySizeOpt,
- NSSOperations operations,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSPrivateKey *
-NSSSymmetricKey_UnwrapPrivateKey (
- NSSSymmetricKey *wrappingKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSItem *wrappedKey,
- NSSUTF8 *labelOpt,
- NSSItem *keyIDOpt,
- PRBool persistant,
- PRBool sensitive,
- NSSToken *destinationOpt,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSSymmetricKey_DeriveSymmetricKey (
- NSSSymmetricKey *originalKey,
- NSSAlgorithmAndParameters *apOpt,
- NSSOID *target,
- PRUint32 keySizeOpt,
- NSSOperations operations,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-NSSSymmetricKey_CreateCryptoContext (
- NSSSymmetricKey *mk,
- NSSAlgorithmAndParameters *apOpt,
- NSSCallback *uhh
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c
deleted file mode 100644
index ff2d09ba1..000000000
--- a/security/nss/lib/pki/tdcache.c
+++ /dev/null
@@ -1,1150 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef PKIM_H
-#include "pkim.h"
-#endif /* PKIM_H */
-
-#ifndef PKIT_H
-#include "pkit.h"
-#endif /* PKIT_H */
-
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-#ifndef PKI_H
-#include "pki.h"
-#endif /* PKI_H */
-
-#ifndef NSSBASE_H
-#include "nssbase.h"
-#endif /* NSSBASE_H */
-
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-
-#include "cert.h"
-#include "dev.h"
-#include "pki3hack.h"
-
-#ifdef DEBUG_CACHE
-static PRLogModuleInfo *s_log = NULL;
-#endif
-
-#ifdef DEBUG_CACHE
-static void log_item_dump(const char *msg, NSSItem *it)
-{
- char buf[33];
- int i, j;
- for (i=0; i<10 && i<it->size; i++) {
- sprintf(&buf[2*i], "%02X", ((PRUint8 *)it->data)[i]);
- }
- if (it->size>10) {
- sprintf(&buf[2*i], "..");
- i += 1;
- for (j=it->size-1; i<=16 && j>10; i++, j--) {
- sprintf(&buf[2*i], "%02X", ((PRUint8 *)it->data)[j]);
- }
- }
- PR_LOG(s_log, PR_LOG_DEBUG, ("%s: %s", msg, buf));
-}
-#endif
-
-#ifdef DEBUG_CACHE
-static void log_cert_ref(const char *msg, NSSCertificate *c)
-{
- PR_LOG(s_log, PR_LOG_DEBUG, ("%s: %s", msg,
- (c->nickname) ? c->nickname : c->email));
- log_item_dump("\tserial", &c->serial);
- log_item_dump("\tsubject", &c->subject);
-}
-#endif
-
-/* Certificate cache routines */
-
-/* XXX
- * Locking is not handled well at all. A single, global lock with sub-locks
- * in the collection types. Cleanup needed.
- */
-
-/* should it live in its own arena? */
-struct nssTDCertificateCacheStr
-{
- PZLock *lock;
- NSSArena *arena;
- nssHash *issuerAndSN;
- nssHash *subject;
- nssHash *nickname;
- nssHash *email;
-};
-
-struct cache_entry_str
-{
- union {
- NSSCertificate *cert;
- nssList *list;
- void *value;
- } entry;
- PRUint32 hits;
- PRTime lastHit;
- NSSArena *arena;
- NSSUTF8 *nickname;
-};
-
-typedef struct cache_entry_str cache_entry;
-
-static cache_entry *
-new_cache_entry(NSSArena *arena, void *value, PRBool ownArena)
-{
- cache_entry *ce = nss_ZNEW(arena, cache_entry);
- if (ce) {
- ce->entry.value = value;
- ce->hits = 1;
- ce->lastHit = PR_Now();
- if (ownArena) {
- ce->arena = arena;
- }
- ce->nickname = NULL;
- }
- return ce;
-}
-
-/* this should not be exposed in a header, but is here to keep the above
- * types/functions static
- */
-NSS_IMPLEMENT PRStatus
-nssTrustDomain_InitializeCache (
- NSSTrustDomain *td,
- PRUint32 cacheSize
-)
-{
- NSSArena *arena;
- nssTDCertificateCache *cache = td->cache;
-#ifdef DEBUG_CACHE
- s_log = PR_NewLogModule("nss_cache");
- PR_ASSERT(s_log);
-#endif
- PR_ASSERT(!cache);
- arena = nssArena_Create();
- if (!arena) {
- return PR_FAILURE;
- }
- cache = nss_ZNEW(arena, nssTDCertificateCache);
- if (!cache) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
- }
- cache->lock = PZ_NewLock(nssILockCache);
- if (!cache->lock) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
- }
- /* Create the issuer and serial DER --> certificate hash */
- cache->issuerAndSN = nssHash_CreateCertificate(arena, cacheSize);
- if (!cache->issuerAndSN) {
- goto loser;
- }
- /* Create the subject DER --> subject list hash */
- cache->subject = nssHash_CreateItem(arena, cacheSize);
- if (!cache->subject) {
- goto loser;
- }
- /* Create the nickname --> subject list hash */
- cache->nickname = nssHash_CreateString(arena, cacheSize);
- if (!cache->nickname) {
- goto loser;
- }
- /* Create the email --> list of subject lists hash */
- cache->email = nssHash_CreateString(arena, cacheSize);
- if (!cache->email) {
- goto loser;
- }
- cache->arena = arena;
- td->cache = cache;
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("Cache initialized."));
-#endif
- return PR_SUCCESS;
-loser:
- PZ_DestroyLock(cache->lock);
- nssArena_Destroy(arena);
- td->cache = NULL;
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("Cache initialization failed."));
-#endif
- return PR_FAILURE;
-}
-
-/* The entries of the hashtable are currently dependent on the certificate(s)
- * that produced them. That is, the entries will be freed when the cert is
- * released from the cache. If there are certs in the cache at any time,
- * including shutdown, the hash table entries will hold memory. In order for
- * clean shutdown, it is necessary for there to be no certs in the cache.
- */
-
-extern const NSSError NSS_ERROR_INTERNAL_ERROR;
-extern const NSSError NSS_ERROR_BUSY;
-
-NSS_IMPLEMENT PRStatus
-nssTrustDomain_DestroyCache (
- NSSTrustDomain *td
-)
-{
- if (!td->cache) {
- nss_SetError(NSS_ERROR_INTERNAL_ERROR);
- return PR_FAILURE;
- }
- if (nssHash_Count(td->cache->issuerAndSN) > 0) {
- nss_SetError(NSS_ERROR_BUSY);
- return PR_FAILURE;
- }
- PZ_DestroyLock(td->cache->lock);
- nssHash_Destroy(td->cache->issuerAndSN);
- nssHash_Destroy(td->cache->subject);
- nssHash_Destroy(td->cache->nickname);
- nssHash_Destroy(td->cache->email);
- nssArena_Destroy(td->cache->arena);
- td->cache = NULL;
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("Cache destroyed."));
-#endif
- return PR_SUCCESS;
-}
-
-static PRStatus
-remove_issuer_and_serial_entry (
- nssTDCertificateCache *cache,
- NSSCertificate *cert
-)
-{
- /* Remove the cert from the issuer/serial hash */
- nssHash_Remove(cache->issuerAndSN, cert);
-#ifdef DEBUG_CACHE
- log_cert_ref("removed issuer/sn", cert);
-#endif
- return PR_SUCCESS;
-}
-
-static PRStatus
-remove_subject_entry (
- nssTDCertificateCache *cache,
- NSSCertificate *cert,
- nssList **subjectList,
- NSSUTF8 **nickname,
- NSSArena **arena
-)
-{
- PRStatus nssrv;
- cache_entry *ce;
- *subjectList = NULL;
- *arena = NULL;
- /* Get the subject list for the cert's subject */
- ce = (cache_entry *)nssHash_Lookup(cache->subject, &cert->subject);
- if (ce) {
- /* Remove the cert from the subject hash */
- nssList_Remove(ce->entry.list, cert);
- *subjectList = ce->entry.list;
- *nickname = ce->nickname;
- *arena = ce->arena;
- nssrv = PR_SUCCESS;
-#ifdef DEBUG_CACHE
- log_cert_ref("removed cert", cert);
- log_item_dump("from subject list", &cert->subject);
-#endif
- } else {
- nssrv = PR_FAILURE;
- }
- return nssrv;
-}
-
-static PRStatus
-remove_nickname_entry (
- nssTDCertificateCache *cache,
- NSSUTF8 *nickname,
- nssList *subjectList
-)
-{
- PRStatus nssrv;
- if (nickname) {
- nssHash_Remove(cache->nickname, nickname);
- nssrv = PR_SUCCESS;
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", nickname));
-#endif
- } else {
- nssrv = PR_FAILURE;
- }
- return nssrv;
-}
-
-static PRStatus
-remove_email_entry (
- nssTDCertificateCache *cache,
- NSSCertificate *cert,
- nssList *subjectList
-)
-{
- PRStatus nssrv = PR_FAILURE;
- cache_entry *ce;
- /* Find the subject list in the email hash */
- if (cert->email) {
- ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email);
- if (ce) {
- nssList *subjects = ce->entry.list;
- /* Remove the subject list from the email hash */
- nssList_Remove(subjects, subjectList);
-#ifdef DEBUG_CACHE
- log_item_dump("removed subject list", &cert->subject);
- PR_LOG(s_log, PR_LOG_DEBUG, ("for email %s", cert->email));
-#endif
- if (nssList_Count(subjects) == 0) {
- /* No more subject lists for email, delete list and
- * remove hash entry
- */
- (void)nssList_Destroy(subjects);
- nssHash_Remove(cache->email, cert->email);
- /* there are no entries left for this address, free space
- * used for email entries
- */
- nssArena_Destroy(ce->arena);
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("removed email %s", cert->email));
-#endif
- }
- nssrv = PR_SUCCESS;
- }
- }
- return nssrv;
-}
-
-NSS_IMPLEMENT void
-nssTrustDomain_RemoveCertFromCacheLOCKED (
- NSSTrustDomain *td,
- NSSCertificate *cert
-)
-{
- nssList *subjectList;
- cache_entry *ce;
- NSSArena *arena;
- NSSUTF8 *nickname;
-
-#ifdef DEBUG_CACHE
- log_cert_ref("attempt to remove cert", cert);
-#endif
- ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert);
- if (!ce || ce->entry.cert != cert) {
- /* If it's not in the cache, or a different cert is (this is really
- * for safety reasons, though it shouldn't happen), do nothing
- */
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("but it wasn't in the cache"));
-#endif
- return;
- }
- (void)remove_issuer_and_serial_entry(td->cache, cert);
- (void)remove_subject_entry(td->cache, cert, &subjectList,
- &nickname, &arena);
- if (nssList_Count(subjectList) == 0) {
- (void)remove_nickname_entry(td->cache, nickname, subjectList);
- (void)remove_email_entry(td->cache, cert, subjectList);
- (void)nssList_Destroy(subjectList);
- nssHash_Remove(td->cache->subject, &cert->subject);
- /* there are no entries left for this subject, free the space used
- * for both the nickname and subject entries
- */
- if (arena) {
- nssArena_Destroy(arena);
- }
- }
-}
-
-NSS_IMPLEMENT void
-nssTrustDomain_LockCertCache (
- NSSTrustDomain *td
-)
-{
- PZ_Lock(td->cache->lock);
-}
-
-NSS_IMPLEMENT void
-nssTrustDomain_UnlockCertCache (
- NSSTrustDomain *td
-)
-{
- PZ_Unlock(td->cache->lock);
-}
-
-struct token_cert_dtor {
- NSSToken *token;
- nssTDCertificateCache *cache;
- NSSCertificate **certs;
- PRUint32 numCerts, arrSize;
-};
-
-static void
-remove_token_certs(const void *k, void *v, void *a)
-{
- NSSCertificate *c = (NSSCertificate *)k;
- nssPKIObject *object = &c->object;
- struct token_cert_dtor *dtor = a;
- PRUint32 i;
- nssPKIObject_Lock(object);
- for (i=0; i<object->numInstances; i++) {
- if (object->instances[i]->token == dtor->token) {
- nssCryptokiObject_Destroy(object->instances[i]);
- object->instances[i] = object->instances[object->numInstances-1];
- object->instances[object->numInstances-1] = NULL;
- object->numInstances--;
- dtor->certs[dtor->numCerts++] = c;
- if (dtor->numCerts == dtor->arrSize) {
- dtor->arrSize *= 2;
- dtor->certs = nss_ZREALLOCARRAY(dtor->certs,
- NSSCertificate *,
- dtor->arrSize);
- }
- break;
- }
- }
- nssPKIObject_Unlock(object);
- return;
-}
-
-/*
- * Remove all certs for the given token from the cache. This is
- * needed if the token is removed.
- */
-NSS_IMPLEMENT PRStatus
-nssTrustDomain_RemoveTokenCertsFromCache (
- NSSTrustDomain *td,
- NSSToken *token
-)
-{
- NSSCertificate **certs;
- PRUint32 i, arrSize = 10;
- struct token_cert_dtor dtor;
- certs = nss_ZNEWARRAY(NULL, NSSCertificate *, arrSize);
- if (!certs) {
- return PR_FAILURE;
- }
- dtor.cache = td->cache;
- dtor.token = token;
- dtor.certs = certs;
- dtor.numCerts = 0;
- dtor.arrSize = arrSize;
- PZ_Lock(td->cache->lock);
- nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, (void *)&dtor);
- for (i=0; i<dtor.numCerts; i++) {
- if (dtor.certs[i]->object.numInstances == 0) {
- nssTrustDomain_RemoveCertFromCacheLOCKED(td, dtor.certs[i]);
- dtor.certs[i] = NULL; /* skip this cert in the second for loop */
- }
- }
- PZ_Unlock(td->cache->lock);
- for (i=0; i<dtor.numCerts; i++) {
- if (dtor.certs[i]) {
- STAN_ForceCERTCertificateUpdate(dtor.certs[i]);
- }
- }
- nss_ZFreeIf(dtor.certs);
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT PRStatus
-nssTrustDomain_UpdateCachedTokenCerts (
- NSSTrustDomain *td,
- NSSToken *token
-)
-{
- NSSCertificate **cp, **cached = NULL;
- nssList *certList;
- PRUint32 count;
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList) return PR_FAILURE;
- (void)nssTrustDomain_GetCertsFromCache(td, certList);
- count = nssList_Count(certList);
- if (count > 0) {
- cached = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
- if (!cached) {
- return PR_FAILURE;
- }
- nssList_GetArray(certList, (void **)cached, count);
- nssList_Destroy(certList);
- for (cp = cached; *cp; cp++) {
- nssCryptokiObject *instance;
- NSSCertificate *c = *cp;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- instance = nssToken_FindCertificateByIssuerAndSerialNumber(
- token,
- NULL,
- &c->issuer,
- &c->serial,
- tokenOnly,
- NULL);
- if (instance) {
- nssPKIObject_AddInstance(&c->object, instance);
- STAN_ForceCERTCertificateUpdate(c);
- }
- }
- nssCertificateArray_Destroy(cached);
- }
- return PR_SUCCESS;
-}
-
-static PRStatus
-add_issuer_and_serial_entry (
- NSSArena *arena,
- nssTDCertificateCache *cache,
- NSSCertificate *cert
-)
-{
- cache_entry *ce;
- ce = new_cache_entry(arena, (void *)cert, PR_FALSE);
-#ifdef DEBUG_CACHE
- log_cert_ref("added to issuer/sn", cert);
-#endif
- return nssHash_Add(cache->issuerAndSN, cert, (void *)ce);
-}
-
-static PRStatus
-add_subject_entry (
- NSSArena *arena,
- nssTDCertificateCache *cache,
- NSSCertificate *cert,
- NSSUTF8 *nickname,
- nssList **subjectList
-)
-{
- PRStatus nssrv;
- nssList *list;
- cache_entry *ce;
- *subjectList = NULL; /* this is only set if a new one is created */
- ce = (cache_entry *)nssHash_Lookup(cache->subject, &cert->subject);
- if (ce) {
- ce->hits++;
- ce->lastHit = PR_Now();
- /* The subject is already in, add this cert to the list */
- nssrv = nssList_AddUnique(ce->entry.list, cert);
-#ifdef DEBUG_CACHE
- log_cert_ref("added to existing subject list", cert);
-#endif
- } else {
- NSSDER *subject;
- /* Create a new subject list for the subject */
- list = nssList_Create(arena, PR_FALSE);
- if (!list) {
- return PR_FAILURE;
- }
- ce = new_cache_entry(arena, (void *)list, PR_TRUE);
- if (!ce) {
- return PR_FAILURE;
- }
- if (nickname) {
- ce->nickname = nssUTF8_Duplicate(nickname, arena);
- }
- nssList_SetSortFunction(list, nssCertificate_SubjectListSort);
- /* Add the cert entry to this list of subjects */
- nssrv = nssList_AddUnique(list, cert);
- if (nssrv != PR_SUCCESS) {
- return nssrv;
- }
- /* Add the subject list to the cache */
- subject = nssItem_Duplicate(&cert->subject, arena, NULL);
- if (!subject) {
- return PR_FAILURE;
- }
- nssrv = nssHash_Add(cache->subject, subject, ce);
- if (nssrv != PR_SUCCESS) {
- return nssrv;
- }
- *subjectList = list;
-#ifdef DEBUG_CACHE
- log_cert_ref("created subject list", cert);
-#endif
- }
- return nssrv;
-}
-
-static PRStatus
-add_nickname_entry (
- NSSArena *arena,
- nssTDCertificateCache *cache,
- NSSUTF8 *certNickname,
- nssList *subjectList
-)
-{
- PRStatus nssrv = PR_SUCCESS;
- cache_entry *ce;
- ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname);
- if (ce) {
- /* This is a collision. A nickname entry already exists for this
- * subject, but a subject entry didn't. This would imply there are
- * two subjects using the same nickname, which is not allowed.
- */
- return PR_FAILURE;
- } else {
- NSSUTF8 *nickname;
- ce = new_cache_entry(arena, subjectList, PR_FALSE);
- if (!ce) {
- return PR_FAILURE;
- }
- nickname = nssUTF8_Duplicate(certNickname, arena);
- if (!nickname) {
- return PR_FAILURE;
- }
- nssrv = nssHash_Add(cache->nickname, nickname, ce);
-#ifdef DEBUG_CACHE
- log_cert_ref("created nickname for", cert);
-#endif
- }
- return nssrv;
-}
-
-static PRStatus
-add_email_entry (
- nssTDCertificateCache *cache,
- NSSCertificate *cert,
- nssList *subjectList
-)
-{
- PRStatus nssrv = PR_SUCCESS;
- nssList *subjects;
- cache_entry *ce;
- ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email);
- if (ce) {
- /* Already have an entry for this email address, but not subject */
- subjects = ce->entry.list;
- nssrv = nssList_AddUnique(subjects, subjectList);
- ce->hits++;
- ce->lastHit = PR_Now();
-#ifdef DEBUG_CACHE
- log_cert_ref("added subject to email for", cert);
-#endif
- } else {
- NSSASCII7 *email;
- NSSArena *arena;
- arena = nssArena_Create();
- if (!arena) {
- return PR_FAILURE;
- }
- /* Create a new list of subject lists, add this subject */
- subjects = nssList_Create(arena, PR_TRUE);
- if (!subjects) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
- }
- /* Add the new subject to the list */
- nssrv = nssList_AddUnique(subjects, subjectList);
- if (nssrv != PR_SUCCESS) {
- nssArena_Destroy(arena);
- return nssrv;
- }
- /* Add the new entry to the cache */
- ce = new_cache_entry(arena, (void *)subjects, PR_TRUE);
- if (!ce) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
- }
- email = nssUTF8_Duplicate(cert->email, arena);
- if (!email) {
- nssArena_Destroy(arena);
- return PR_FAILURE;
- }
- nssrv = nssHash_Add(cache->email, email, ce);
- if (nssrv != PR_SUCCESS) {
- nssArena_Destroy(arena);
- return nssrv;
- }
-#ifdef DEBUG_CACHE
- log_cert_ref("created email for", cert);
-#endif
- }
- return nssrv;
-}
-
-extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
-
-static void
-remove_object_instances (
- nssPKIObject *object,
- nssCryptokiObject **instances,
- int numInstances
-)
-{
- int i;
-
- for (i = 0; i < numInstances; i++) {
- nssPKIObject_RemoveInstanceForToken(object, instances[i]->token);
- }
-}
-
-static SECStatus
-merge_object_instances (
- nssPKIObject *to,
- nssPKIObject *from
-)
-{
- nssCryptokiObject **instances, **ci;
- int i;
- SECStatus rv = SECSuccess;
-
- instances = nssPKIObject_GetInstances(from);
- if (instances == NULL) {
- return SECFailure;
- }
- for (ci = instances, i = 0; *ci; ci++, i++) {
- nssCryptokiObject *instance = nssCryptokiObject_Clone(*ci);
- if (instance) {
- if (nssPKIObject_AddInstance(to, instance) == SECSuccess) {
- continue;
- }
- nssCryptokiObject_Destroy(instance);
- }
- remove_object_instances(to, instances, i);
- rv = SECFailure;
- break;
- }
- nssCryptokiObjectArray_Destroy(instances);
- return rv;
-}
-
-static NSSCertificate *
-add_cert_to_cache (
- NSSTrustDomain *td,
- NSSCertificate *cert
-)
-{
- NSSArena *arena = NULL;
- nssList *subjectList = NULL;
- PRStatus nssrv;
- PRUint32 added = 0;
- cache_entry *ce;
- NSSCertificate *rvCert = NULL;
- NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL);
-
- PZ_Lock(td->cache->lock);
- /* If it exists in the issuer/serial hash, it's already in all */
- ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert);
- if (ce) {
- ce->hits++;
- ce->lastHit = PR_Now();
- rvCert = nssCertificate_AddRef(ce->entry.cert);
-#ifdef DEBUG_CACHE
- log_cert_ref("attempted to add cert already in cache", cert);
-#endif
- PZ_Unlock(td->cache->lock);
- nss_ZFreeIf(certNickname);
- /* collision - somebody else already added the cert
- * to the cache before this thread got around to it.
- */
- /* merge the instances of the cert */
- if (merge_object_instances(&rvCert->object, &cert->object)
- != SECSuccess) {
- nssCertificate_Destroy(rvCert);
- return NULL;
- }
- STAN_ForceCERTCertificateUpdate(rvCert);
- nssCertificate_Destroy(cert);
- return rvCert;
- }
- /* create a new cache entry for this cert within the cert's arena*/
- nssrv = add_issuer_and_serial_entry(cert->object.arena, td->cache, cert);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
- added++;
- /* create an arena for the nickname and subject entries */
- arena = nssArena_Create();
- if (!arena) {
- goto loser;
- }
- /* create a new subject list for this cert, or add to existing */
- nssrv = add_subject_entry(arena, td->cache, cert,
- certNickname, &subjectList);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
- added++;
- /* If a new subject entry was created, also need nickname and/or email */
- if (subjectList != NULL) {
- PRBool handle = PR_FALSE;
- if (certNickname) {
- nssrv = add_nickname_entry(arena, td->cache,
- certNickname, subjectList);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
- handle = PR_TRUE;
- added++;
- }
- if (cert->email) {
- nssrv = add_email_entry(td->cache, cert, subjectList);
- if (nssrv != PR_SUCCESS) {
- goto loser;
- }
- handle = PR_TRUE;
- added += 2;
- }
-#ifdef nodef
- /* I think either a nickname or email address must be associated
- * with the cert. However, certs are passed to NewTemp without
- * either. This worked in the old code, so it must work now.
- */
- if (!handle) {
- /* Require either nickname or email handle */
- nssrv = PR_FAILURE;
- goto loser;
- }
-#endif
- } else {
- /* A new subject entry was not created. arena is unused. */
- nssArena_Destroy(arena);
- }
- rvCert = cert;
- PZ_Unlock(td->cache->lock);
- nss_ZFreeIf(certNickname);
- return rvCert;
-loser:
- nss_ZFreeIf(certNickname);
- certNickname = NULL;
- /* Remove any handles that have been created */
- subjectList = NULL;
- if (added >= 1) {
- (void)remove_issuer_and_serial_entry(td->cache, cert);
- }
- if (added >= 2) {
- (void)remove_subject_entry(td->cache, cert, &subjectList,
- &certNickname, &arena);
- }
- if (added == 3 || added == 5) {
- (void)remove_nickname_entry(td->cache, certNickname, subjectList);
- }
- if (added >= 4) {
- (void)remove_email_entry(td->cache, cert, subjectList);
- }
- if (subjectList) {
- nssHash_Remove(td->cache->subject, &cert->subject);
- nssList_Destroy(subjectList);
- }
- if (arena) {
- nssArena_Destroy(arena);
- }
- PZ_Unlock(td->cache->lock);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-nssTrustDomain_AddCertsToCache (
- NSSTrustDomain *td,
- NSSCertificate **certs,
- PRUint32 numCerts
-)
-{
- PRUint32 i;
- NSSCertificate *c;
- for (i=0; i<numCerts && certs[i]; i++) {
- c = add_cert_to_cache(td, certs[i]);
- if (c == NULL) {
- return PR_FAILURE;
- } else {
- certs[i] = c;
- }
- }
- return PR_SUCCESS;
-}
-
-static NSSCertificate **
-collect_subject_certs (
- nssList *subjectList,
- nssList *rvCertListOpt
-)
-{
- NSSCertificate *c;
- NSSCertificate **rvArray = NULL;
- PRUint32 count;
- nssCertificateList_AddReferences(subjectList);
- if (rvCertListOpt) {
- nssListIterator *iter = nssList_CreateIterator(subjectList);
- if (!iter) {
- return (NSSCertificate **)NULL;
- }
- for (c = (NSSCertificate *)nssListIterator_Start(iter);
- c != (NSSCertificate *)NULL;
- c = (NSSCertificate *)nssListIterator_Next(iter)) {
- nssList_Add(rvCertListOpt, c);
- }
- nssListIterator_Finish(iter);
- nssListIterator_Destroy(iter);
- } else {
- count = nssList_Count(subjectList);
- rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
- if (!rvArray) {
- return (NSSCertificate **)NULL;
- }
- nssList_GetArray(subjectList, (void **)rvArray, count);
- }
- return rvArray;
-}
-
-/*
- * Find all cached certs with this subject.
- */
-NSS_IMPLEMENT NSSCertificate **
-nssTrustDomain_GetCertsForSubjectFromCache (
- NSSTrustDomain *td,
- NSSDER *subject,
- nssList *certListOpt
-)
-{
- NSSCertificate **rvArray = NULL;
- cache_entry *ce;
-#ifdef DEBUG_CACHE
- log_item_dump("looking for cert by subject", subject);
-#endif
- PZ_Lock(td->cache->lock);
- ce = (cache_entry *)nssHash_Lookup(td->cache->subject, subject);
- if (ce) {
- ce->hits++;
- ce->lastHit = PR_Now();
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
-#endif
- rvArray = collect_subject_certs(ce->entry.list, certListOpt);
- }
- PZ_Unlock(td->cache->lock);
- return rvArray;
-}
-
-/*
- * Find all cached certs with this label.
- */
-NSS_IMPLEMENT NSSCertificate **
-nssTrustDomain_GetCertsForNicknameFromCache (
- NSSTrustDomain *td,
- const NSSUTF8 *nickname,
- nssList *certListOpt
-)
-{
- NSSCertificate **rvArray = NULL;
- cache_entry *ce;
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("looking for cert by nick %s", nickname));
-#endif
- PZ_Lock(td->cache->lock);
- ce = (cache_entry *)nssHash_Lookup(td->cache->nickname, nickname);
- if (ce) {
- ce->hits++;
- ce->lastHit = PR_Now();
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
-#endif
- rvArray = collect_subject_certs(ce->entry.list, certListOpt);
- }
- PZ_Unlock(td->cache->lock);
- return rvArray;
-}
-
-/*
- * Find all cached certs with this email address.
- */
-NSS_IMPLEMENT NSSCertificate **
-nssTrustDomain_GetCertsForEmailAddressFromCache (
- NSSTrustDomain *td,
- NSSASCII7 *email,
- nssList *certListOpt
-)
-{
- NSSCertificate **rvArray = NULL;
- cache_entry *ce;
- nssList *collectList = NULL;
- nssListIterator *iter = NULL;
- nssList *subjectList;
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("looking for cert by email %s", email));
-#endif
- PZ_Lock(td->cache->lock);
- ce = (cache_entry *)nssHash_Lookup(td->cache->email, email);
- if (ce) {
- ce->hits++;
- ce->lastHit = PR_Now();
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
-#endif
- /* loop over subject lists and get refs for certs */
- if (certListOpt) {
- collectList = certListOpt;
- } else {
- collectList = nssList_Create(NULL, PR_FALSE);
- if (!collectList) {
- PZ_Unlock(td->cache->lock);
- return NULL;
- }
- }
- iter = nssList_CreateIterator(ce->entry.list);
- if (!iter) {
- PZ_Unlock(td->cache->lock);
- if (!certListOpt) {
- nssList_Destroy(collectList);
- }
- return NULL;
- }
- for (subjectList = (nssList *)nssListIterator_Start(iter);
- subjectList != (nssList *)NULL;
- subjectList = (nssList *)nssListIterator_Next(iter)) {
- (void)collect_subject_certs(subjectList, collectList);
- }
- nssListIterator_Finish(iter);
- nssListIterator_Destroy(iter);
- }
- PZ_Unlock(td->cache->lock);
- if (!certListOpt && collectList) {
- PRUint32 count = nssList_Count(collectList);
- rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
- if (rvArray) {
- nssList_GetArray(collectList, (void **)rvArray, count);
- }
- nssList_Destroy(collectList);
- }
- return rvArray;
-}
-
-/*
- * Look for a specific cert in the cache
- */
-NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_GetCertForIssuerAndSNFromCache (
- NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serial
-)
-{
- NSSCertificate certkey;
- NSSCertificate *rvCert = NULL;
- cache_entry *ce;
- certkey.issuer.data = issuer->data;
- certkey.issuer.size = issuer->size;
- certkey.serial.data = serial->data;
- certkey.serial.size = serial->size;
-#ifdef DEBUG_CACHE
- log_item_dump("looking for cert by issuer/sn, issuer", issuer);
- log_item_dump(" serial", serial);
-#endif
- PZ_Lock(td->cache->lock);
- ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, &certkey);
- if (ce) {
- ce->hits++;
- ce->lastHit = PR_Now();
- rvCert = nssCertificate_AddRef(ce->entry.cert);
-#ifdef DEBUG_CACHE
- PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
-#endif
- }
- PZ_Unlock(td->cache->lock);
- return rvCert;
-}
-
-static PRStatus
-issuer_and_serial_from_encoding (
- NSSBER *encoding,
- NSSDER *issuer,
- NSSDER *serial
-)
-{
- SECItem derCert, derIssuer, derSerial;
- SECStatus secrv;
- derCert.data = (unsigned char *)encoding->data;
- derCert.len = encoding->size;
- secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
- if (secrv != SECSuccess) {
- return PR_FAILURE;
- }
- secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
- if (secrv != SECSuccess) {
- return PR_FAILURE;
- }
- issuer->data = derIssuer.data;
- issuer->size = derIssuer.len;
- serial->data = derSerial.data;
- serial->size = derSerial.len;
- return PR_SUCCESS;
-}
-
-/*
- * Look for a specific cert in the cache
- */
-NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_GetCertByDERFromCache (
- NSSTrustDomain *td,
- NSSDER *der
-)
-{
- PRStatus nssrv = PR_FAILURE;
- NSSDER issuer, serial;
- NSSCertificate *rvCert;
- nssrv = issuer_and_serial_from_encoding(der, &issuer, &serial);
- if (nssrv != PR_SUCCESS) {
- return NULL;
- }
-#ifdef DEBUG_CACHE
- log_item_dump("looking for cert by DER", der);
-#endif
- rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
- &issuer, &serial);
- PORT_Free(issuer.data);
- PORT_Free(serial.data);
- return rvCert;
-}
-
-static void cert_iter(const void *k, void *v, void *a)
-{
- nssList *certList = (nssList *)a;
- NSSCertificate *c = (NSSCertificate *)k;
- nssList_Add(certList, nssCertificate_AddRef(c));
-}
-
-NSS_EXTERN NSSCertificate **
-nssTrustDomain_GetCertsFromCache (
- NSSTrustDomain *td,
- nssList *certListOpt
-)
-{
- NSSCertificate **rvArray = NULL;
- nssList *certList;
- if (certListOpt) {
- certList = certListOpt;
- } else {
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList) {
- return NULL;
- }
- }
- PZ_Lock(td->cache->lock);
- nssHash_Iterate(td->cache->issuerAndSN, cert_iter, (void *)certList);
- PZ_Unlock(td->cache->lock);
- if (!certListOpt) {
- PRUint32 count = nssList_Count(certList);
- rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
- nssList_GetArray(certList, (void **)rvArray, count);
- /* array takes the references */
- nssList_Destroy(certList);
- }
- return rvArray;
-}
-
-NSS_IMPLEMENT void
-nssTrustDomain_DumpCacheInfo (
- NSSTrustDomain *td,
- void (* cert_dump_iter)(const void *, void *, void *),
- void *arg
-)
-{
- PZ_Lock(td->cache->lock);
- nssHash_Iterate(td->cache->issuerAndSN, cert_dump_iter, arg);
- PZ_Unlock(td->cache->lock);
-}
diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c
deleted file mode 100644
index c7b7a429a..000000000
--- a/security/nss/lib/pki/trustdomain.c
+++ /dev/null
@@ -1,1258 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#ifndef DEV_H
-#include "dev.h"
-#endif /* DEV_H */
-
-#ifndef PKIM_H
-#include "pkim.h"
-#endif /* PKIM_H */
-
-#include "cert.h"
-#include "pki3hack.h"
-#include "pk11pub.h"
-#include "nssrwlk.h"
-
-#define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32
-
-extern const NSSError NSS_ERROR_NOT_FOUND;
-
-typedef PRUint32 nssUpdateLevel;
-
-NSS_IMPLEMENT NSSTrustDomain *
-NSSTrustDomain_Create (
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-)
-{
- NSSArena *arena;
- NSSTrustDomain *rvTD;
- arena = NSSArena_Create();
- if(!arena) {
- return (NSSTrustDomain *)NULL;
- }
- rvTD = nss_ZNEW(arena, NSSTrustDomain);
- if (!rvTD) {
- goto loser;
- }
- /* protect the token list and the token iterator */
- rvTD->tokensLock = NSSRWLock_New(100, "tokens");
- if (!rvTD->tokensLock) {
- goto loser;
- }
- nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE);
- rvTD->arena = arena;
- rvTD->refCount = 1;
- rvTD->statusConfig = NULL;
- return rvTD;
-loser:
- if (rvTD && rvTD->tokensLock) {
- NSSRWLock_Destroy(rvTD->tokensLock);
- }
- nssArena_Destroy(arena);
- return (NSSTrustDomain *)NULL;
-}
-
-static void
-token_destructor(void *t)
-{
- NSSToken *tok = (NSSToken *)t;
- /* The token holds the first/last reference to the slot.
- * When the token is actually destroyed (ref count == 0),
- * the slot will also be destroyed.
- */
- nssToken_Destroy(tok);
-}
-
-NSS_IMPLEMENT PRStatus
-NSSTrustDomain_Destroy (
- NSSTrustDomain *td
-)
-{
- PRStatus status = PR_SUCCESS;
- if (--td->refCount == 0) {
- /* Destroy each token in the list of tokens */
- if (td->tokens) {
- nssListIterator_Destroy(td->tokens);
- td->tokens = NULL;
- }
- if (td->tokenList) {
- nssList_Clear(td->tokenList, token_destructor);
- nssList_Destroy(td->tokenList);
- td->tokenList = NULL;
- }
- NSSRWLock_Destroy(td->tokensLock);
- td->tokensLock = NULL;
- status = nssTrustDomain_DestroyCache(td);
- if (status == PR_FAILURE) {
- return status;
- }
- if (td->statusConfig) {
- td->statusConfig->statusDestroy(td->statusConfig);
- td->statusConfig = NULL;
- }
- /* Destroy the trust domain */
- nssArena_Destroy(td->arena);
- }
- return status;
-}
-
-/* XXX uses tokens until slot list is in place */
-static NSSSlot **
-nssTrustDomain_GetActiveSlots (
- NSSTrustDomain *td,
- nssUpdateLevel *updateLevel
-)
-{
- PRUint32 count;
- NSSSlot **slots = NULL;
- NSSToken **tp, **tokens;
- *updateLevel = 1;
- NSSRWLock_LockRead(td->tokensLock);
- count = nssList_Count(td->tokenList);
- tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1);
- if (!tokens) {
- NSSRWLock_UnlockRead(td->tokensLock);
- return NULL;
- }
- slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
- if (!slots) {
- NSSRWLock_UnlockRead(td->tokensLock);
- nss_ZFreeIf(tokens);
- return NULL;
- }
- nssList_GetArray(td->tokenList, (void **)tokens, count);
- NSSRWLock_UnlockRead(td->tokensLock);
- count = 0;
- for (tp = tokens; *tp; tp++) {
- NSSSlot * slot = nssToken_GetSlot(*tp);
- if (!PK11_IsDisabled(slot->pk11slot)) {
- slots[count++] = slot;
- } else {
- nssSlot_Destroy(slot);
- }
- }
- nss_ZFreeIf(tokens);
- if (!count) {
- nss_ZFreeIf(slots);
- slots = NULL;
- }
- return slots;
-}
-
-/* XXX */
-static nssSession *
-nssTrustDomain_GetSessionForToken (
- NSSTrustDomain *td,
- NSSToken *token
-)
-{
- return nssToken_GetDefaultSession(token);
-}
-
-NSS_IMPLEMENT PRStatus
-NSSTrustDomain_SetDefaultCallback (
- NSSTrustDomain *td,
- NSSCallback *newCallback,
- NSSCallback **oldCallbackOpt
-)
-{
- if (oldCallbackOpt) {
- *oldCallbackOpt = td->defaultCallback;
- }
- td->defaultCallback = newCallback;
- return PR_SUCCESS;
-}
-
-NSS_IMPLEMENT NSSCallback *
-nssTrustDomain_GetDefaultCallback (
- NSSTrustDomain *td,
- PRStatus *statusOpt
-)
-{
- if (statusOpt) {
- *statusOpt = PR_SUCCESS;
- }
- return td->defaultCallback;
-}
-
-NSS_IMPLEMENT NSSCallback *
-NSSTrustDomain_GetDefaultCallback (
- NSSTrustDomain *td,
- PRStatus *statusOpt
-)
-{
- return nssTrustDomain_GetDefaultCallback(td, statusOpt);
-}
-
-NSS_IMPLEMENT PRStatus
-NSSTrustDomain_LoadModule (
- NSSTrustDomain *td,
- NSSUTF8 *moduleOpt,
- NSSUTF8 *uriOpt,
- NSSUTF8 *opaqueOpt,
- void *reserved
-)
-{
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSTrustDomain_DisableToken (
- NSSTrustDomain *td,
- NSSToken *token,
- NSSError why
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSTrustDomain_EnableToken (
- NSSTrustDomain *td,
- NSSToken *token
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSTrustDomain_IsTokenEnabled (
- NSSTrustDomain *td,
- NSSToken *token,
- NSSError *whyOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSSlot *
-NSSTrustDomain_FindSlotByName (
- NSSTrustDomain *td,
- NSSUTF8 *slotName
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSToken *
-NSSTrustDomain_FindTokenByName (
- NSSTrustDomain *td,
- NSSUTF8 *tokenName
-)
-{
- PRStatus nssrv;
- NSSUTF8 *myName;
- NSSToken *tok = NULL;
- NSSRWLock_LockRead(td->tokensLock);
- for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
- tok != (NSSToken *)NULL;
- tok = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- if (nssToken_IsPresent(tok)) {
- myName = nssToken_GetName(tok);
- if (nssUTF8_Equal(tokenName, myName, &nssrv)) break;
- }
- }
- nssListIterator_Finish(td->tokens);
- NSSRWLock_UnlockRead(td->tokensLock);
- return tok;
-}
-
-NSS_IMPLEMENT NSSToken *
-NSSTrustDomain_FindTokenBySlotName (
- NSSTrustDomain *td,
- NSSUTF8 *slotName
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSToken *
-NSSTrustDomain_FindTokenForAlgorithm (
- NSSTrustDomain *td,
- NSSOID *algorithm
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSToken *
-NSSTrustDomain_FindBestTokenForAlgorithms (
- NSSTrustDomain *td,
- NSSOID *algorithms[], /* may be null-terminated */
- PRUint32 nAlgorithmsOpt /* limits the array if nonzero */
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSTrustDomain_Login (
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSTrustDomain_Logout (
- NSSTrustDomain *td
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_ImportCertificate (
- NSSTrustDomain *td,
- NSSCertificate *c
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_ImportPKIXCertificate (
- NSSTrustDomain *td,
- /* declared as a struct until these "data types" are defined */
- struct NSSPKIXCertificateStr *pc
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_ImportEncodedCertificate (
- NSSTrustDomain *td,
- NSSBER *ber
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_ImportEncodedCertificateChain (
- NSSTrustDomain *td,
- NSSBER *ber,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSPrivateKey *
-NSSTrustDomain_ImportEncodedPrivateKey (
- NSSTrustDomain *td,
- NSSBER *ber,
- NSSItem *passwordOpt, /* NULL will cause a callback */
- NSSCallback *uhhOpt,
- NSSToken *destination
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSPublicKey *
-NSSTrustDomain_ImportEncodedPublicKey (
- NSSTrustDomain *td,
- NSSBER *ber
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-static NSSCertificate **
-get_certs_from_list(nssList *list)
-{
- PRUint32 count = nssList_Count(list);
- NSSCertificate **certs = NULL;
- if (count > 0) {
- certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
- if (certs) {
- nssList_GetArray(list, (void **)certs, count);
- }
- }
- return certs;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-nssTrustDomain_FindCertificatesByNickname (
- NSSTrustDomain *td,
- const NSSUTF8 *name,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- NSSToken *token = NULL;
- NSSSlot **slots = NULL;
- NSSSlot **slotp;
- NSSCertificate **rvCerts = NULL;
- nssPKIObjectCollection *collection = NULL;
- nssUpdateLevel updateLevel;
- nssList *nameList;
- PRUint32 numRemaining = maximumOpt;
- PRUint32 collectionCount = 0;
- PRUint32 errors = 0;
-
- /* First, grab from the cache */
- nameList = nssList_Create(NULL, PR_FALSE);
- if (!nameList) {
- return NULL;
- }
- (void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
- rvCerts = get_certs_from_list(nameList);
- /* initialize the collection of token certificates with the set of
- * cached certs (if any).
- */
- collection = nssCertificateCollection_Create(td, rvCerts);
- nssCertificateArray_Destroy(rvCerts);
- nssList_Destroy(nameList);
- if (!collection) {
- return (NSSCertificate **)NULL;
- }
- /* obtain the current set of active slots in the trust domain */
- slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
- if (!slots) {
- goto loser;
- }
- /* iterate over the slots */
- for (slotp = slots; *slotp; slotp++) {
- token = nssSlot_GetToken(*slotp);
- if (token) {
- nssSession *session;
- nssCryptokiObject **instances = NULL;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- PRStatus status = PR_FAILURE;
-
- session = nssTrustDomain_GetSessionForToken(td, token);
- if (session) {
- instances = nssToken_FindCertificatesByNickname(token,
- session,
- name,
- tokenOnly,
- numRemaining,
- &status);
- }
- nssToken_Destroy(token);
- if (status != PR_SUCCESS) {
- errors++;
- continue;
- }
- if (instances) {
- status = nssPKIObjectCollection_AddInstances(collection,
- instances, 0);
- nss_ZFreeIf(instances);
- if (status != PR_SUCCESS) {
- errors++;
- continue;
- }
- collectionCount = nssPKIObjectCollection_Count(collection);
- if (maximumOpt > 0) {
- if (collectionCount >= maximumOpt)
- break;
- numRemaining = maximumOpt - collectionCount;
- }
- }
- }
- }
- if (!collectionCount && errors)
- goto loser;
- /* Grab the certs collected in the search. */
- rvCerts = nssPKIObjectCollection_GetCertificates(collection,
- rvOpt, maximumOpt,
- arenaOpt);
- /* clean up */
- nssPKIObjectCollection_Destroy(collection);
- nssSlotArray_Destroy(slots);
- return rvCerts;
-loser:
- if (slots) {
- nssSlotArray_Destroy(slots);
- }
- if (collection) {
- nssPKIObjectCollection_Destroy(collection);
- }
- return (NSSCertificate **)NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindCertificatesByNickname (
- NSSTrustDomain *td,
- NSSUTF8 *name,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- return nssTrustDomain_FindCertificatesByNickname(td,
- name,
- rvOpt,
- maximumOpt,
- arenaOpt);
-}
-
-NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_FindBestCertificateByNickname (
- NSSTrustDomain *td,
- const NSSUTF8 *name,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- NSSCertificate **nicknameCerts;
- NSSCertificate *rvCert = NULL;
- nicknameCerts = nssTrustDomain_FindCertificatesByNickname(td, name,
- NULL,
- 0,
- NULL);
- if (nicknameCerts) {
- rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts,
- timeOpt,
- usage,
- policiesOpt);
- nssCertificateArray_Destroy(nicknameCerts);
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateByNickname (
- NSSTrustDomain *td,
- const NSSUTF8 *name,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- return nssTrustDomain_FindBestCertificateByNickname(td,
- name,
- timeOpt,
- usage,
- policiesOpt);
-}
-
-NSS_IMPLEMENT NSSCertificate **
-nssTrustDomain_FindCertificatesBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- NSSToken *token = NULL;
- NSSSlot **slots = NULL;
- NSSSlot **slotp;
- NSSCertificate **rvCerts = NULL;
- nssPKIObjectCollection *collection = NULL;
- nssUpdateLevel updateLevel;
- nssList *subjectList;
- PRUint32 numRemaining = maximumOpt;
- PRUint32 collectionCount = 0;
- PRUint32 errors = 0;
-
- /* look in cache */
- subjectList = nssList_Create(NULL, PR_FALSE);
- if (!subjectList) {
- return NULL;
- }
- (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
- rvCerts = get_certs_from_list(subjectList);
- collection = nssCertificateCollection_Create(td, rvCerts);
- nssCertificateArray_Destroy(rvCerts);
- nssList_Destroy(subjectList);
- if (!collection) {
- return (NSSCertificate **)NULL;
- }
- slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
- if (!slots) {
- goto loser;
- }
- for (slotp = slots; *slotp; slotp++) {
- token = nssSlot_GetToken(*slotp);
- if (token) {
- nssSession *session;
- nssCryptokiObject **instances = NULL;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- PRStatus status = PR_FAILURE;
-
- session = nssTrustDomain_GetSessionForToken(td, token);
- if (session) {
- instances = nssToken_FindCertificatesBySubject(token,
- session,
- subject,
- tokenOnly,
- numRemaining,
- &status);
- }
- nssToken_Destroy(token);
- if (status != PR_SUCCESS) {
- errors++;
- continue;
- }
- if (instances) {
- status = nssPKIObjectCollection_AddInstances(collection,
- instances, 0);
- nss_ZFreeIf(instances);
- if (status != PR_SUCCESS) {
- errors++;
- continue;
- }
- collectionCount = nssPKIObjectCollection_Count(collection);
- if (maximumOpt > 0) {
- if (collectionCount >= maximumOpt)
- break;
- numRemaining = maximumOpt - collectionCount;
- }
- }
- }
- }
- if (!collectionCount && errors)
- goto loser;
- rvCerts = nssPKIObjectCollection_GetCertificates(collection,
- rvOpt, maximumOpt,
- arenaOpt);
- nssPKIObjectCollection_Destroy(collection);
- nssSlotArray_Destroy(slots);
- return rvCerts;
-loser:
- if (slots) {
- nssSlotArray_Destroy(slots);
- }
- if (collection) {
- nssPKIObjectCollection_Destroy(collection);
- }
- return (NSSCertificate **)NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindCertificatesBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt,
- NSSArena *arenaOpt
-)
-{
- return nssTrustDomain_FindCertificatesBySubject(td,
- subject,
- rvOpt,
- maximumOpt,
- arenaOpt);
-}
-
-NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_FindBestCertificateBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- NSSCertificate **subjectCerts;
- NSSCertificate *rvCert = NULL;
- subjectCerts = nssTrustDomain_FindCertificatesBySubject(td, subject,
- NULL,
- 0,
- NULL);
- if (subjectCerts) {
- rvCert = nssCertificateArray_FindBestCertificate(subjectCerts,
- timeOpt,
- usage,
- policiesOpt);
- nssCertificateArray_Destroy(subjectCerts);
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateBySubject (
- NSSTrustDomain *td,
- NSSDER *subject,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- return nssTrustDomain_FindBestCertificateBySubject(td,
- subject,
- timeOpt,
- usage,
- policiesOpt);
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateByNameComponents (
- NSSTrustDomain *td,
- NSSUTF8 *nameComponents,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindCertificatesByNameComponents (
- NSSTrustDomain *td,
- NSSUTF8 *nameComponents,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-/* This returns at most a single certificate, so it can stop the loop
- * when one is found.
- */
-NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_FindCertificateByIssuerAndSerialNumber (
- NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serial
-)
-{
- NSSSlot **slots = NULL;
- NSSSlot **slotp;
- NSSCertificate *rvCert = NULL;
- nssPKIObjectCollection *collection = NULL;
- nssUpdateLevel updateLevel;
-
- /* see if this search is already cached */
- rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
- issuer,
- serial);
- if (rvCert) {
- return rvCert;
- }
- slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
- if (slots) {
- for (slotp = slots; *slotp; slotp++) {
- NSSToken *token = nssSlot_GetToken(*slotp);
- nssSession *session;
- nssCryptokiObject *instance;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- PRStatus status = PR_FAILURE;
-
- if (!token)
- continue;
- session = nssTrustDomain_GetSessionForToken(td, token);
- if (session) {
- instance = nssToken_FindCertificateByIssuerAndSerialNumber(
- token,
- session,
- issuer,
- serial,
- tokenOnly,
- &status);
- }
- nssToken_Destroy(token);
- if (status != PR_SUCCESS) {
- continue;
- }
- if (instance) {
- if (!collection) {
- collection = nssCertificateCollection_Create(td, NULL);
- if (!collection) {
- break; /* don't keep looping if out if memory */
- }
- }
- status = nssPKIObjectCollection_AddInstances(collection,
- &instance, 1);
- if (status == PR_SUCCESS) {
- (void)nssPKIObjectCollection_GetCertificates(
- collection, &rvCert, 1, NULL);
- }
- if (rvCert) {
- break; /* found one cert, all done */
- }
- }
- }
- }
- if (collection) {
- nssPKIObjectCollection_Destroy(collection);
- }
- if (slots) {
- nssSlotArray_Destroy(slots);
- }
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindCertificateByIssuerAndSerialNumber (
- NSSTrustDomain *td,
- NSSDER *issuer,
- NSSDER *serial
-)
-{
- return nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
- issuer,
- serial);
-}
-
-NSS_IMPLEMENT NSSCertificate *
-nssTrustDomain_FindCertificateByEncodedCertificate (
- NSSTrustDomain *td,
- NSSBER *ber
-)
-{
- PRStatus status;
- NSSCertificate *rvCert = NULL;
- NSSDER issuer = { 0 };
- NSSDER serial = { 0 };
- NSSArena *arena = nssArena_Create();
- if (!arena) {
- return (NSSCertificate *)NULL;
- }
- /* XXX this is not generic... will any cert crack into issuer/serial? */
- status = nssPKIX509_GetIssuerAndSerialFromDER(ber, arena, &issuer, &serial);
- if (status != PR_SUCCESS) {
- goto finish;
- }
- rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td,
- &issuer,
- &serial);
-finish:
- nssArena_Destroy(arena);
- return rvCert;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindCertificateByEncodedCertificate (
- NSSTrustDomain *td,
- NSSBER *ber
-)
-{
- return nssTrustDomain_FindCertificateByEncodedCertificate(td, ber);
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateByEmail (
- NSSTrustDomain *td,
- NSSASCII7 *email,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- return 0;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindCertificatesByEmail (
- NSSTrustDomain *td,
- NSSASCII7 *email,
- NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindCertificateByOCSPHash (
- NSSTrustDomain *td,
- NSSItem *hash
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestUserCertificate (
- NSSTrustDomain *td,
- NSSTime *timeOpt,
- NSSUsage *usage,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindUserCertificates (
- NSSTrustDomain *td,
- NSSTime *timeOpt,
- NSSUsage *usageOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestUserCertificateForSSLClientAuth (
- NSSTrustDomain *td,
- NSSUTF8 *sslHostOpt,
- NSSDER *rootCAsOpt[], /* null pointer for none */
- PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindUserCertificatesForSSLClientAuth (
- NSSTrustDomain *td,
- NSSUTF8 *sslHostOpt,
- NSSDER *rootCAsOpt[], /* null pointer for none */
- PRUint32 rootCAsMaxOpt, /* zero means list is null-terminated */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestUserCertificateForEmailSigning (
- NSSTrustDomain *td,
- NSSASCII7 *signerOpt,
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindUserCertificatesForEmailSigning (
- NSSTrustDomain *td,
- NSSASCII7 *signerOpt,
- NSSASCII7 *recipientOpt,
- /* anything more here? */
- NSSAlgorithmAndParameters *apOpt,
- NSSPolicies *policiesOpt,
- NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
- NSSArena *arenaOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-static PRStatus
-collector(nssCryptokiObject *instance, void *arg)
-{
- nssPKIObjectCollection *collection = (nssPKIObjectCollection *)arg;
- return nssPKIObjectCollection_AddInstanceAsObject(collection, instance);
-}
-
-NSS_IMPLEMENT PRStatus *
-NSSTrustDomain_TraverseCertificates (
- NSSTrustDomain *td,
- PRStatus (*callback)(NSSCertificate *c, void *arg),
- void *arg
-)
-{
- PRStatus status = PR_FAILURE;
- NSSToken *token = NULL;
- NSSSlot **slots = NULL;
- NSSSlot **slotp;
- nssPKIObjectCollection *collection = NULL;
- nssPKIObjectCallback pkiCallback;
- nssUpdateLevel updateLevel;
- NSSCertificate **cached = NULL;
- nssList *certList;
-
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList)
- return NULL;
- (void)nssTrustDomain_GetCertsFromCache(td, certList);
- cached = get_certs_from_list(certList);
- collection = nssCertificateCollection_Create(td, cached);
- nssCertificateArray_Destroy(cached);
- nssList_Destroy(certList);
- if (!collection) {
- return (PRStatus *)NULL;
- }
- /* obtain the current set of active slots in the trust domain */
- slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
- if (!slots) {
- goto loser;
- }
- /* iterate over the slots */
- for (slotp = slots; *slotp; slotp++) {
- /* get the token for the slot, if present */
- token = nssSlot_GetToken(*slotp);
- if (token) {
- nssSession *session;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
- /* get a session for the token */
- session = nssTrustDomain_GetSessionForToken(td, token);
- if (session) {
- /* perform the traversal */
- status = nssToken_TraverseCertificates(token,
- session,
- tokenOnly,
- collector,
- collection);
- }
- nssToken_Destroy(token);
- }
- }
-
- /* Traverse the collection */
- pkiCallback.func.cert = callback;
- pkiCallback.arg = arg;
- status = nssPKIObjectCollection_Traverse(collection, &pkiCallback);
-loser:
- if (slots) {
- nssSlotArray_Destroy(slots);
- }
- if (collection) {
- nssPKIObjectCollection_Destroy(collection);
- }
- return NULL;
-}
-
-
-NSS_IMPLEMENT NSSTrust *
-nssTrustDomain_FindTrustForCertificate (
- NSSTrustDomain *td,
- NSSCertificate *c
-)
-{
- NSSSlot **slots;
- NSSSlot **slotp;
- nssCryptokiObject *to = NULL;
- nssPKIObject *pkio = NULL;
- NSSTrust *rvt = NULL;
- nssUpdateLevel updateLevel;
- slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
- if (!slots) {
- return (NSSTrust *)NULL;
- }
- for (slotp = slots; *slotp; slotp++) {
- NSSToken *token = nssSlot_GetToken(*slotp);
-
- if (token) {
- to = nssToken_FindTrustForCertificate(token, NULL,
- &c->encoding,
- &c->issuer,
- &c->serial,
- nssTokenSearchType_TokenOnly);
- if (to) {
- PRStatus status;
- if (!pkio) {
- pkio = nssPKIObject_Create(NULL, to, td, NULL, nssPKILock);
- status = pkio ? PR_SUCCESS : PR_FAILURE;
- } else {
- status = nssPKIObject_AddInstance(pkio, to);
- }
- if (status != PR_SUCCESS) {
- nssCryptokiObject_Destroy(to);
- }
- }
- nssToken_Destroy(token);
- }
- }
- if (pkio) {
- rvt = nssTrust_Create(pkio, &c->encoding);
- if (rvt) {
- pkio = NULL; /* rvt object now owns the pkio reference */
- }
- }
- nssSlotArray_Destroy(slots);
- if (pkio) {
- nssPKIObject_Destroy(pkio);
- }
- return rvt;
-}
-
-NSS_IMPLEMENT NSSCRL **
-nssTrustDomain_FindCRLsBySubject (
- NSSTrustDomain *td,
- NSSDER *subject
-)
-{
- NSSSlot **slots;
- NSSSlot **slotp;
- NSSToken *token;
- nssUpdateLevel updateLevel;
- nssPKIObjectCollection *collection;
- NSSCRL **rvCRLs = NULL;
- collection = nssCRLCollection_Create(td, NULL);
- if (!collection) {
- return (NSSCRL **)NULL;
- }
- slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
- if (!slots) {
- goto loser;
- }
- for (slotp = slots; *slotp; slotp++) {
- token = nssSlot_GetToken(*slotp);
- if (token) {
- PRStatus status = PR_FAILURE;
- nssSession *session;
- nssCryptokiObject **instances = NULL;
- nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
-
- /* get a session for the token */
- session = nssTrustDomain_GetSessionForToken(td, token);
- if (session) {
- /* perform the traversal */
- instances = nssToken_FindCRLsBySubject(token, session, subject,
- tokenOnly, 0, &status);
- }
- nssToken_Destroy(token);
- if (status == PR_SUCCESS) {
- /* add the found CRL's to the collection */
- status = nssPKIObjectCollection_AddInstances(collection,
- instances, 0);
- }
- nss_ZFreeIf(instances);
- }
- }
- rvCRLs = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
-loser:
- nssPKIObjectCollection_Destroy(collection);
- nssSlotArray_Destroy(slots);
- return rvCRLs;
-}
-
-NSS_IMPLEMENT PRStatus
-NSSTrustDomain_GenerateKeyPair (
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- NSSPrivateKey **pvkOpt,
- NSSPublicKey **pbkOpt,
- PRBool privateKeyIsSensitive,
- NSSToken *destination,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return PR_FAILURE;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSTrustDomain_GenerateSymmetricKey (
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- PRUint32 keysize,
- NSSToken *destination,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSTrustDomain_GenerateSymmetricKeyFromPassword (
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap,
- NSSUTF8 *passwordOpt, /* if null, prompt */
- NSSToken *destinationOpt,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSSymmetricKey *
-NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID (
- NSSTrustDomain *td,
- NSSOID *algorithm,
- NSSItem *keyID,
- NSSCallback *uhhOpt
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-nssTrustDomain_CreateCryptoContext (
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-)
-{
- return nssCryptoContext_Create(td, uhhOpt);
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContext (
- NSSTrustDomain *td,
- NSSCallback *uhhOpt
-)
-{
- return nssTrustDomain_CreateCryptoContext(td, uhhOpt);
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContextForAlgorithm (
- NSSTrustDomain *td,
- NSSOID *algorithm
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
-NSS_IMPLEMENT NSSCryptoContext *
-NSSTrustDomain_CreateCryptoContextForAlgorithmAndParameters (
- NSSTrustDomain *td,
- NSSAlgorithmAndParameters *ap
-)
-{
- nss_SetError(NSS_ERROR_NOT_FOUND);
- return NULL;
-}
-
diff --git a/security/nss/lib/smime/Makefile b/security/nss/lib/smime/Makefile
deleted file mode 100644
index a9cebcfec..000000000
--- a/security/nss/lib/smime/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-
-
diff --git a/security/nss/lib/smime/cms.h b/security/nss/lib/smime/cms.h
deleted file mode 100644
index c63cbfd5c..000000000
--- a/security/nss/lib/smime/cms.h
+++ /dev/null
@@ -1,1155 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Interfaces of the CMS implementation.
- *
- * $Id$
- */
-
-#ifndef _CMS_H_
-#define _CMS_H_
-
-#include "seccomon.h"
-
-#include "secoidt.h"
-#include "certt.h"
-#include "keyt.h"
-#include "hasht.h"
-#include "cmst.h"
-
-/************************************************************************/
-SEC_BEGIN_PROTOS
-
-/************************************************************************
- * cmsdecode.c - CMS decoding
- ************************************************************************/
-
-/*
- * NSS_CMSDecoder_Start - set up decoding of a DER-encoded CMS message
- *
- * "poolp" - pointer to arena for message, or NULL if new pool should be created
- * "cb", "cb_arg" - callback function and argument for delivery of inner content
- * inner content will be stored in the message if cb is NULL.
- * "pwfn", pwfn_arg" - callback function for getting token password
- * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
- */
-extern NSSCMSDecoderContext *
-NSS_CMSDecoder_Start(PLArenaPool *poolp,
- NSSCMSContentCallback cb, void *cb_arg,
- PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg);
-
-/*
- * NSS_CMSDecoder_Update - feed DER-encoded data to decoder
- */
-extern SECStatus
-NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf, unsigned long len);
-
-/*
- * NSS_CMSDecoder_Cancel - cancel a decoding process
- */
-extern void
-NSS_CMSDecoder_Cancel(NSSCMSDecoderContext *p7dcx);
-
-/*
- * NSS_CMSDecoder_Finish - mark the end of inner content and finish decoding
- */
-extern NSSCMSMessage *
-NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx);
-
-/*
- * NSS_CMSMessage_CreateFromDER - decode a CMS message from DER encoded data
- */
-extern NSSCMSMessage *
-NSS_CMSMessage_CreateFromDER(SECItem *DERmessage,
- NSSCMSContentCallback cb, void *cb_arg,
- PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg);
-
-/************************************************************************
- * cmsencode.c - CMS encoding
- ************************************************************************/
-
-/*
- * NSS_CMSEncoder_Start - set up encoding of a CMS message
- *
- * "cmsg" - message to encode
- * "outputfn", "outputarg" - callback function for delivery of DER-encoded output
- * will not be called if NULL.
- * "dest" - if non-NULL, pointer to SECItem that will hold the DER-encoded output
- * "destpoolp" - pool to allocate DER-encoded output in
- * "pwfn", pwfn_arg" - callback function for getting token password
- * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
- * "detached_digestalgs", "detached_digests" - digests from detached content
- */
-extern NSSCMSEncoderContext *
-NSS_CMSEncoder_Start(NSSCMSMessage *cmsg,
- NSSCMSContentCallback outputfn, void *outputarg,
- SECItem *dest, PLArenaPool *destpoolp,
- PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg,
- SECAlgorithmID **detached_digestalgs, SECItem **detached_digests);
-
-/*
- * NSS_CMSEncoder_Update - take content data delivery from the user
- *
- * "p7ecx" - encoder context
- * "data" - content data
- * "len" - length of content data
- */
-extern SECStatus
-NSS_CMSEncoder_Update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len);
-
-/*
- * NSS_CMSEncoder_Cancel - stop all encoding
- */
-extern SECStatus
-NSS_CMSEncoder_Cancel(NSSCMSEncoderContext *p7ecx);
-
-/*
- * NSS_CMSEncoder_Finish - signal the end of data
- *
- * we need to walk down the chain of encoders and the finish them from the innermost out
- */
-extern SECStatus
-NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx);
-
-/************************************************************************
- * cmsmessage.c - CMS message object
- ************************************************************************/
-
-/*
- * NSS_CMSMessage_Create - create a CMS message object
- *
- * "poolp" - arena to allocate memory from, or NULL if new arena should be created
- */
-extern NSSCMSMessage *
-NSS_CMSMessage_Create(PLArenaPool *poolp);
-
-/*
- * NSS_CMSMessage_SetEncodingParams - set up a CMS message object for encoding or decoding
- *
- * "cmsg" - message object
- * "pwfn", pwfn_arg" - callback function for getting token password
- * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
- * "detached_digestalgs", "detached_digests" - digests from detached content
- *
- * used internally.
- */
-extern void
-NSS_CMSMessage_SetEncodingParams(NSSCMSMessage *cmsg,
- PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg,
- SECAlgorithmID **detached_digestalgs, SECItem **detached_digests);
-
-/*
- * NSS_CMSMessage_Destroy - destroy a CMS message and all of its sub-pieces.
- */
-extern void
-NSS_CMSMessage_Destroy(NSSCMSMessage *cmsg);
-
-/*
- * NSS_CMSMessage_Copy - return a copy of the given message.
- *
- * The copy may be virtual or may be real -- either way, the result needs
- * to be passed to NSS_CMSMessage_Destroy later (as does the original).
- */
-extern NSSCMSMessage *
-NSS_CMSMessage_Copy(NSSCMSMessage *cmsg);
-
-/*
- * NSS_CMSMessage_GetArena - return a pointer to the message's arena pool
- */
-extern PLArenaPool *
-NSS_CMSMessage_GetArena(NSSCMSMessage *cmsg);
-
-/*
- * NSS_CMSMessage_GetContentInfo - return a pointer to the top level contentInfo
- */
-extern NSSCMSContentInfo *
-NSS_CMSMessage_GetContentInfo(NSSCMSMessage *cmsg);
-
-/*
- * Return a pointer to the actual content.
- * In the case of those types which are encrypted, this returns the *plain* content.
- * In case of nested contentInfos, this descends and retrieves the innermost content.
- */
-extern SECItem *
-NSS_CMSMessage_GetContent(NSSCMSMessage *cmsg);
-
-/*
- * NSS_CMSMessage_ContentLevelCount - count number of levels of CMS content objects in this message
- *
- * CMS data content objects do not count.
- */
-extern int
-NSS_CMSMessage_ContentLevelCount(NSSCMSMessage *cmsg);
-
-/*
- * NSS_CMSMessage_ContentLevel - find content level #n
- *
- * CMS data content objects do not count.
- */
-extern NSSCMSContentInfo *
-NSS_CMSMessage_ContentLevel(NSSCMSMessage *cmsg, int n);
-
-/*
- * NSS_CMSMessage_ContainsCertsOrCrls - see if message contains certs along the way
- */
-extern PRBool
-NSS_CMSMessage_ContainsCertsOrCrls(NSSCMSMessage *cmsg);
-
-/*
- * NSS_CMSMessage_IsEncrypted - see if message contains a encrypted submessage
- */
-extern PRBool
-NSS_CMSMessage_IsEncrypted(NSSCMSMessage *cmsg);
-
-/*
- * NSS_CMSMessage_IsSigned - see if message contains a signed submessage
- *
- * If the CMS message has a SignedData with a signature (not just a SignedData)
- * return true; false otherwise. This can/should be called before calling
- * VerifySignature, which will always indicate failure if no signature is
- * present, but that does not mean there even was a signature!
- * Note that the content itself can be empty (detached content was sent
- * another way); it is the presence of the signature that matters.
- */
-extern PRBool
-NSS_CMSMessage_IsSigned(NSSCMSMessage *cmsg);
-
-/*
- * NSS_CMSMessage_IsContentEmpty - see if content is empty
- *
- * returns PR_TRUE is innermost content length is < minLen
- * XXX need the encrypted content length (why?)
- */
-extern PRBool
-NSS_CMSMessage_IsContentEmpty(NSSCMSMessage *cmsg, unsigned int minLen);
-
-/************************************************************************
- * cmscinfo.c - CMS contentInfo methods
- ************************************************************************/
-
-/*
- * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces.
- */
-extern void
-NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo);
-
-/*
- * NSS_CMSContentInfo_GetChildContentInfo - get content's contentInfo (if it exists)
- */
-extern NSSCMSContentInfo *
-NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo);
-
-/*
- * NSS_CMSContentInfo_SetContent - set cinfo's content type & content to CMS object
- */
-extern SECStatus
-NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr);
-
-/*
- * NSS_CMSContentInfo_SetContent_XXXX - typesafe wrappers for NSS_CMSContentInfo_SetType
- * set cinfo's content type & content to CMS object
- */
-extern SECStatus
-NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached);
-
-extern SECStatus
-NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd);
-
-extern SECStatus
-NSS_CMSContentInfo_SetContent_EnvelopedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd);
-
-extern SECStatus
-NSS_CMSContentInfo_SetContent_DigestedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd);
-
-extern SECStatus
-NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd);
-
-/*
- * turn off streaming for this content type.
- * This could fail with SEC_ERROR_NO_MEMORY in memory constrained conditions.
- */
-extern SECStatus
-NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream);
-
-
-/*
- * NSS_CMSContentInfo_GetContent - get pointer to inner content
- *
- * needs to be casted...
- */
-extern void *
-NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo);
-
-/*
- * NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content
- *
- * this is typically only called by NSS_CMSMessage_GetContent()
- */
-extern SECItem *
-NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo);
-
-/*
- * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result
- * for future reference) and return the inner content type.
- */
-extern SECOidTag
-NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo);
-
-extern SECItem *
-NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo);
-
-/*
- * NSS_CMSContentInfo_GetContentEncAlgTag - find out (saving pointer to lookup result
- * for future reference) and return the content encryption algorithm tag.
- */
-extern SECOidTag
-NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo);
-
-/*
- * NSS_CMSContentInfo_GetContentEncAlg - find out and return the content encryption algorithm tag.
- */
-extern SECAlgorithmID *
-NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo);
-
-extern SECStatus
-NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
- SECOidTag bulkalgtag, SECItem *parameters, int keysize);
-
-extern SECStatus
-NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
- SECAlgorithmID *algid, int keysize);
-
-extern void
-NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey);
-
-extern PK11SymKey *
-NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo);
-
-extern int
-NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo);
-
-/************************************************************************
- * cmsutil.c - CMS misc utility functions
- ************************************************************************/
-
-/*
- * NSS_CMSArray_SortByDER - sort array of objects by objects' DER encoding
- *
- * make sure that the order of the objects guarantees valid DER (which must be
- * in lexigraphically ascending order for a SET OF); if reordering is necessary it
- * will be done in place (in objs).
- */
-extern SECStatus
-NSS_CMSArray_SortByDER(void **objs, const SEC_ASN1Template *objtemplate, void **objs2);
-
-/*
- * NSS_CMSUtil_DERCompare - for use with NSS_CMSArray_Sort to
- * sort arrays of SECItems containing DER
- */
-extern int
-NSS_CMSUtil_DERCompare(void *a, void *b);
-
-/*
- * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of
- * algorithms.
- *
- * algorithmArray - array of algorithm IDs
- * algid - algorithmid of algorithm to pick
- *
- * Returns:
- * An integer containing the index of the algorithm in the array or -1 if
- * algorithm was not found.
- */
-extern int
-NSS_CMSAlgArray_GetIndexByAlgID(SECAlgorithmID **algorithmArray, SECAlgorithmID *algid);
-
-/*
- * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of
- * algorithms.
- *
- * algorithmArray - array of algorithm IDs
- * algiddata - id of algorithm to pick
- *
- * Returns:
- * An integer containing the index of the algorithm in the array or -1 if
- * algorithm was not found.
- */
-extern int
-NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray, SECOidTag algtag);
-
-extern const SECHashObject *
-NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid);
-
-extern const SEC_ASN1Template *
-NSS_CMSUtil_GetTemplateByTypeTag(SECOidTag type);
-
-extern size_t
-NSS_CMSUtil_GetSizeByTypeTag(SECOidTag type);
-
-extern NSSCMSContentInfo *
-NSS_CMSContent_GetContentInfo(void *msg, SECOidTag type);
-
-extern const char *
-NSS_CMSUtil_VerificationStatusToString(NSSCMSVerificationStatus vs);
-
-/************************************************************************
- * cmssigdata.c - CMS signedData methods
- ************************************************************************/
-
-extern NSSCMSSignedData *
-NSS_CMSSignedData_Create(NSSCMSMessage *cmsg);
-
-extern void
-NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd);
-
-/*
- * NSS_CMSSignedData_Encode_BeforeStart - do all the necessary things to a SignedData
- * before start of encoding.
- *
- * In detail:
- * - find out about the right value to put into sigd->version
- * - come up with a list of digestAlgorithms (which should be the union of the algorithms
- * in the signerinfos).
- * If we happen to have a pre-set list of algorithms (and digest values!), we
- * check if we have all the signerinfos' algorithms. If not, this is an error.
- */
-extern SECStatus
-NSS_CMSSignedData_Encode_BeforeStart(NSSCMSSignedData *sigd);
-
-extern SECStatus
-NSS_CMSSignedData_Encode_BeforeData(NSSCMSSignedData *sigd);
-
-/*
- * NSS_CMSSignedData_Encode_AfterData - do all the necessary things to a SignedData
- * after all the encapsulated data was passed through the encoder.
- *
- * In detail:
- * - create the signatures in all the SignerInfos
- *
- * Please note that nothing is done to the Certificates and CRLs in the message - this
- * is entirely the responsibility of our callers.
- */
-extern SECStatus
-NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd);
-
-extern SECStatus
-NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd);
-
-/*
- * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a SignedData
- * after all the encapsulated data was passed through the decoder.
- */
-extern SECStatus
-NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd);
-
-/*
- * NSS_CMSSignedData_Decode_AfterEnd - do all the necessary things to a SignedData
- * after all decoding is finished.
- */
-extern SECStatus
-NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd);
-
-/*
- * NSS_CMSSignedData_GetSignerInfos - retrieve the SignedData's signer list
- */
-extern NSSCMSSignerInfo **
-NSS_CMSSignedData_GetSignerInfos(NSSCMSSignedData *sigd);
-
-extern int
-NSS_CMSSignedData_SignerInfoCount(NSSCMSSignedData *sigd);
-
-extern NSSCMSSignerInfo *
-NSS_CMSSignedData_GetSignerInfo(NSSCMSSignedData *sigd, int i);
-
-/*
- * NSS_CMSSignedData_GetDigestAlgs - retrieve the SignedData's digest algorithm list
- */
-extern SECAlgorithmID **
-NSS_CMSSignedData_GetDigestAlgs(NSSCMSSignedData *sigd);
-
-/*
- * NSS_CMSSignedData_GetContentInfo - return pointer to this signedData's contentinfo
- */
-extern NSSCMSContentInfo *
-NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd);
-
-/*
- * NSS_CMSSignedData_GetCertificateList - retrieve the SignedData's certificate list
- */
-extern SECItem **
-NSS_CMSSignedData_GetCertificateList(NSSCMSSignedData *sigd);
-
-extern SECStatus
-NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb,
- SECCertUsage certusage, PRBool keepcerts);
-
-/*
- * NSS_CMSSignedData_HasDigests - see if we have digests in place
- */
-extern PRBool
-NSS_CMSSignedData_HasDigests(NSSCMSSignedData *sigd);
-
-/*
- * NSS_CMSSignedData_VerifySignerInfo - check a signature.
- *
- * The digests were either calculated during decoding (and are stored in the
- * signedData itself) or set after decoding using NSS_CMSSignedData_SetDigests.
- *
- * The verification checks if the signing cert is valid and has a trusted chain
- * for the purpose specified by "certusage".
- */
-extern SECStatus
-NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i, CERTCertDBHandle *certdb,
- SECCertUsage certusage);
-
-/*
- * NSS_CMSSignedData_VerifyCertsOnly - verify the certs in a certs-only message
-*/
-extern SECStatus
-NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
- CERTCertDBHandle *certdb,
- SECCertUsage usage);
-
-extern SECStatus
-NSS_CMSSignedData_AddCertList(NSSCMSSignedData *sigd, CERTCertificateList *certlist);
-
-/*
- * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs
- */
-extern SECStatus
-NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert);
-
-extern SECStatus
-NSS_CMSSignedData_AddCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert);
-
-extern PRBool
-NSS_CMSSignedData_ContainsCertsOrCrls(NSSCMSSignedData *sigd);
-
-extern SECStatus
-NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
- NSSCMSSignerInfo *signerinfo);
-
-extern SECStatus
-NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
- SECAlgorithmID **digestalgs,
- SECItem **digests);
-
-extern SECStatus
-NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd,
- SECOidTag digestalgtag,
- SECItem *digestdata);
-
-extern SECStatus
-NSS_CMSSignedData_AddDigest(PLArenaPool *poolp,
- NSSCMSSignedData *sigd,
- SECOidTag digestalgtag,
- SECItem *digest);
-
-extern SECItem *
-NSS_CMSSignedData_GetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag);
-
-/*
- * NSS_CMSSignedData_CreateCertsOnly - create a certs-only SignedData.
- *
- * cert - base certificates that will be included
- * include_chain - if true, include the complete cert chain for cert
- *
- * More certs and chains can be added via AddCertificate and AddCertChain.
- *
- * An error results in a return value of NULL and an error set.
- */
-extern NSSCMSSignedData *
-NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PRBool include_chain);
-
-/************************************************************************
- * cmssiginfo.c - signerinfo methods
- ************************************************************************/
-
-extern NSSCMSSignerInfo *
-NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag);
-extern NSSCMSSignerInfo *
-NSS_CMSSignerInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, SECItem *subjKeyID, SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag);
-
-/*
- * NSS_CMSSignerInfo_Destroy - destroy a SignerInfo data structure
- */
-extern void
-NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si);
-
-/*
- * NSS_CMSSignerInfo_Sign - sign something
- *
- */
-extern SECStatus
-NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType);
-
-extern SECStatus
-NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb,
- SECCertUsage certusage);
-
-/*
- * NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo
- *
- * Just verifies the signature. The assumption is that verification of the certificate
- * is done already.
- */
-extern SECStatus
-NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType);
-
-extern NSSCMSVerificationStatus
-NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo);
-
-extern SECOidData *
-NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo);
-
-extern SECOidTag
-NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo);
-
-extern int
-NSS_CMSSignerInfo_GetVersion(NSSCMSSignerInfo *signerinfo);
-
-extern CERTCertificateList *
-NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo);
-
-/*
- * NSS_CMSSignerInfo_GetSigningTime - return the signing time,
- * in UTCTime format, of a CMS signerInfo.
- *
- * sinfo - signerInfo data for this signer
- *
- * Returns a pointer to XXXX (what?)
- * A return value of NULL is an error.
- */
-extern SECStatus
-NSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime);
-
-/*
- * Return the signing cert of a CMS signerInfo.
- *
- * the certs in the enclosing SignedData must have been imported already
- */
-extern CERTCertificate *
-NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb);
-
-/*
- * NSS_CMSSignerInfo_GetSignerCommonName - return the common name of the signer
- *
- * sinfo - signerInfo data for this signer
- *
- * Returns a pointer to allocated memory, which must be freed with PORT_Free.
- * A return value of NULL is an error.
- */
-extern char *
-NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo);
-
-/*
- * NSS_CMSSignerInfo_GetSignerEmailAddress - return the common name of the signer
- *
- * sinfo - signerInfo data for this signer
- *
- * Returns a pointer to allocated memory, which must be freed.
- * A return value of NULL is an error.
- */
-extern char *
-NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo);
-
-/*
- * NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
- */
-extern SECStatus
-NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr);
-
-/*
- * NSS_CMSSignerInfo_AddUnauthAttr - add an attribute to the
- * unauthenticated attributes of "signerinfo".
- */
-extern SECStatus
-NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr);
-
-/*
- * NSS_CMSSignerInfo_AddSigningTime - add the signing time to the
- * authenticated (i.e. signed) attributes of "signerinfo".
- *
- * This is expected to be included in outgoing signed
- * messages for email (S/MIME) but is likely useful in other situations.
- *
- * This should only be added once; a second call will do nothing.
- *
- * XXX This will probably just shove the current time into "signerinfo"
- * but it will not actually get signed until the entire item is
- * processed for encoding. Is this (expected to be small) delay okay?
- */
-extern SECStatus
-NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t);
-
-/*
- * NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
- *
- * This is expected to be included in outgoing signed
- * messages for email (S/MIME).
- */
-extern SECStatus
-NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo);
-
-/*
- * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
- *
- * This is expected to be included in outgoing signed messages for email (S/MIME).
- */
-SECStatus
-NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb);
-
-/*
- * NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo", using the OID preferred by Microsoft.
- *
- * This is expected to be included in outgoing signed messages for email (S/MIME),
- * if compatibility with Microsoft mail clients is wanted.
- */
-SECStatus
-NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb);
-
-/*
- * NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo
- */
-extern SECStatus
-NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo,
- SECOidTag digestalg, CERTCertificate signingcert);
-
-/*
- * XXXX the following needs to be done in the S/MIME layer code
- * after signature of a signerinfo is verified
- */
-extern SECStatus
-NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo);
-
-/*
- * NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer
- */
-extern SECStatus
-NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage);
-
-/************************************************************************
- * cmsenvdata.c - CMS envelopedData methods
- ************************************************************************/
-
-/*
- * NSS_CMSEnvelopedData_Create - create an enveloped data message
- */
-extern NSSCMSEnvelopedData *
-NSS_CMSEnvelopedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize);
-
-/*
- * NSS_CMSEnvelopedData_Destroy - destroy an enveloped data message
- */
-extern void
-NSS_CMSEnvelopedData_Destroy(NSSCMSEnvelopedData *edp);
-
-/*
- * NSS_CMSEnvelopedData_GetContentInfo - return pointer to this envelopedData's contentinfo
- */
-extern NSSCMSContentInfo *
-NSS_CMSEnvelopedData_GetContentInfo(NSSCMSEnvelopedData *envd);
-
-/*
- * NSS_CMSEnvelopedData_AddRecipient - add a recipientinfo to the enveloped data msg
- *
- * rip must be created on the same pool as edp - this is not enforced, though.
- */
-extern SECStatus
-NSS_CMSEnvelopedData_AddRecipient(NSSCMSEnvelopedData *edp, NSSCMSRecipientInfo *rip);
-
-/*
- * NSS_CMSEnvelopedData_Encode_BeforeStart - prepare this envelopedData for encoding
- *
- * at this point, we need
- * - recipientinfos set up with recipient's certificates
- * - a content encryption algorithm (if none, 3DES will be used)
- *
- * this function will generate a random content encryption key (aka bulk key),
- * initialize the recipientinfos with certificate identification and wrap the bulk key
- * using the proper algorithm for every certificiate.
- * it will finally set the bulk algorithm and key so that the encode step can find it.
- */
-extern SECStatus
-NSS_CMSEnvelopedData_Encode_BeforeStart(NSSCMSEnvelopedData *envd);
-
-/*
- * NSS_CMSEnvelopedData_Encode_BeforeData - set up encryption
- */
-extern SECStatus
-NSS_CMSEnvelopedData_Encode_BeforeData(NSSCMSEnvelopedData *envd);
-
-/*
- * NSS_CMSEnvelopedData_Encode_AfterData - finalize this envelopedData for encoding
- */
-extern SECStatus
-NSS_CMSEnvelopedData_Encode_AfterData(NSSCMSEnvelopedData *envd);
-
-/*
- * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo,
- * derive bulk key & set up our contentinfo
- */
-extern SECStatus
-NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd);
-
-/*
- * NSS_CMSEnvelopedData_Decode_AfterData - finish decrypting this envelopedData's content
- */
-extern SECStatus
-NSS_CMSEnvelopedData_Decode_AfterData(NSSCMSEnvelopedData *envd);
-
-/*
- * NSS_CMSEnvelopedData_Decode_AfterEnd - finish decoding this envelopedData
- */
-extern SECStatus
-NSS_CMSEnvelopedData_Decode_AfterEnd(NSSCMSEnvelopedData *envd);
-
-
-/************************************************************************
- * cmsrecinfo.c - CMS recipientInfo methods
- ************************************************************************/
-
-/*
- * NSS_CMSRecipientInfo_Create - create a recipientinfo
- *
- * we currently do not create KeyAgreement recipientinfos with multiple recipientEncryptedKeys
- * the certificate is supposed to have been verified by the caller
- */
-extern NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert);
-
-extern NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
- SECItem *subjKeyID,
- SECKEYPublicKey *pubKey);
-
-extern NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg,
- CERTCertificate *cert);
-
-/*
- * NSS_CMSRecipientInfo_CreateNew - create a blank recipientinfo for
- * applications which want to encode their own CMS structures and
- * key exchange types.
- */
-extern NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateNew(void* pwfn_arg);
-
-/*
- * NSS_CMSRecipientInfo_CreateFromDER - create a recipientinfo from partially
- * decoded DER data for applications which want to encode their own CMS
- * structures and key exchange types.
- */
-extern NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateFromDER(SECItem* input, void* pwfn_arg);
-
-extern void
-NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri);
-
-/*
- * NSS_CMSRecipientInfo_GetCertAndKey - retrieve the cert and key from the
- * recipientInfo struct. If retcert or retkey are NULL, the cert or
- * key (respectively) would not be returned). This function is a no-op if both
- * retcert and retkey are NULL. Caller inherits ownership of the cert and key
- * he requested (and is responsible to free them).
- */
-SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
- CERTCertificate** retcert, SECKEYPrivateKey** retkey);
-
-extern int
-NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri);
-
-extern SECItem *
-NSS_CMSRecipientInfo_GetEncryptedKey(NSSCMSRecipientInfo *ri, int subIndex);
-
-/*
- * NSS_CMSRecipientInfo_Encode - encode an NSS_CMSRecipientInfo as ASN.1
- */
-SECStatus NSS_CMSRecipientInfo_Encode(PLArenaPool* poolp,
- const NSSCMSRecipientInfo *src,
- SECItem* returned);
-
-extern SECOidTag
-NSS_CMSRecipientInfo_GetKeyEncryptionAlgorithmTag(NSSCMSRecipientInfo *ri);
-
-extern SECStatus
-NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey, SECOidTag bulkalgtag);
-
-extern PK11SymKey *
-NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
- CERTCertificate *cert, SECKEYPrivateKey *privkey, SECOidTag bulkalgtag);
-
-/************************************************************************
- * cmsencdata.c - CMS encryptedData methods
- ************************************************************************/
-/*
- * NSS_CMSEncryptedData_Create - create an empty encryptedData object.
- *
- * "algorithm" specifies the bulk encryption algorithm to use.
- * "keysize" is the key size.
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-extern NSSCMSEncryptedData *
-NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize);
-
-/*
- * NSS_CMSEncryptedData_Destroy - destroy an encryptedData object
- */
-extern void
-NSS_CMSEncryptedData_Destroy(NSSCMSEncryptedData *encd);
-
-/*
- * NSS_CMSEncryptedData_GetContentInfo - return pointer to encryptedData object's contentInfo
- */
-extern NSSCMSContentInfo *
-NSS_CMSEncryptedData_GetContentInfo(NSSCMSEncryptedData *encd);
-
-/*
- * NSS_CMSEncryptedData_Encode_BeforeStart - do all the necessary things to a EncryptedData
- * before encoding begins.
- *
- * In particular:
- * - set the correct version value.
- * - get the encryption key
- */
-extern SECStatus
-NSS_CMSEncryptedData_Encode_BeforeStart(NSSCMSEncryptedData *encd);
-
-/*
- * NSS_CMSEncryptedData_Encode_BeforeData - set up encryption
- */
-extern SECStatus
-NSS_CMSEncryptedData_Encode_BeforeData(NSSCMSEncryptedData *encd);
-
-/*
- * NSS_CMSEncryptedData_Encode_AfterData - finalize this encryptedData for encoding
- */
-extern SECStatus
-NSS_CMSEncryptedData_Encode_AfterData(NSSCMSEncryptedData *encd);
-
-/*
- * NSS_CMSEncryptedData_Decode_BeforeData - find bulk key & set up decryption
- */
-extern SECStatus
-NSS_CMSEncryptedData_Decode_BeforeData(NSSCMSEncryptedData *encd);
-
-/*
- * NSS_CMSEncryptedData_Decode_AfterData - finish decrypting this encryptedData's content
- */
-extern SECStatus
-NSS_CMSEncryptedData_Decode_AfterData(NSSCMSEncryptedData *encd);
-
-/*
- * NSS_CMSEncryptedData_Decode_AfterEnd - finish decoding this encryptedData
- */
-extern SECStatus
-NSS_CMSEncryptedData_Decode_AfterEnd(NSSCMSEncryptedData *encd);
-
-/************************************************************************
- * cmsdigdata.c - CMS encryptedData methods
- ************************************************************************/
-/*
- * NSS_CMSDigestedData_Create - create a digestedData object (presumably for encoding)
- *
- * version will be set by NSS_CMSDigestedData_Encode_BeforeStart
- * digestAlg is passed as parameter
- * contentInfo must be filled by the user
- * digest will be calculated while encoding
- */
-extern NSSCMSDigestedData *
-NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg);
-
-/*
- * NSS_CMSDigestedData_Destroy - destroy a digestedData object
- */
-extern void
-NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd);
-
-/*
- * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo
- */
-extern NSSCMSContentInfo *
-NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd);
-
-/*
- * NSS_CMSDigestedData_Encode_BeforeStart - do all the necessary things to a DigestedData
- * before encoding begins.
- *
- * In particular:
- * - set the right version number. The contentInfo's content type must be set up already.
- */
-extern SECStatus
-NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd);
-
-/*
- * NSS_CMSDigestedData_Encode_BeforeData - do all the necessary things to a DigestedData
- * before the encapsulated data is passed through the encoder.
- *
- * In detail:
- * - set up the digests if necessary
- */
-extern SECStatus
-NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd);
-
-/*
- * NSS_CMSDigestedData_Encode_AfterData - do all the necessary things to a DigestedData
- * after all the encapsulated data was passed through the encoder.
- *
- * In detail:
- * - finish the digests
- */
-extern SECStatus
-NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd);
-
-/*
- * NSS_CMSDigestedData_Decode_BeforeData - do all the necessary things to a DigestedData
- * before the encapsulated data is passed through the encoder.
- *
- * In detail:
- * - set up the digests if necessary
- */
-extern SECStatus
-NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd);
-
-/*
- * NSS_CMSDigestedData_Decode_AfterData - do all the necessary things to a DigestedData
- * after all the encapsulated data was passed through the encoder.
- *
- * In detail:
- * - finish the digests
- */
-extern SECStatus
-NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd);
-
-/*
- * NSS_CMSDigestedData_Decode_AfterEnd - finalize a digestedData.
- *
- * In detail:
- * - check the digests for equality
- */
-extern SECStatus
-NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData *digd);
-
-/************************************************************************
- * cmsdigest.c - digestion routines
- ************************************************************************/
-
-/*
- * NSS_CMSDigestContext_StartMultiple - start digest calculation using all the
- * digest algorithms in "digestalgs" in parallel.
- */
-extern NSSCMSDigestContext *
-NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs);
-
-/*
- * NSS_CMSDigestContext_StartSingle - same as NSS_CMSDigestContext_StartMultiple, but
- * only one algorithm.
- */
-extern NSSCMSDigestContext *
-NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg);
-
-/*
- * NSS_CMSDigestContext_Update - feed more data into the digest machine
- */
-extern void
-NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx, const unsigned char *data, int len);
-
-/*
- * NSS_CMSDigestContext_Cancel - cancel digesting operation
- */
-extern void
-NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx);
-
-/*
- * NSS_CMSDigestContext_FinishMultiple - finish the digests and put them
- * into an array of SECItems (allocated on poolp)
- */
-extern SECStatus
-NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp,
- SECItem ***digestsp);
-
-/*
- * NSS_CMSDigestContext_FinishSingle - same as NSS_CMSDigestContext_FinishMultiple,
- * but for one digest.
- */
-extern SECStatus
-NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp,
- SECItem *digest);
-
-/************************************************************************
- *
- ************************************************************************/
-
-/* shortcuts for basic use */
-
-/*
- * NSS_CMSDEREncode - DER Encode a CMS message, with input being
- * the plaintext message and derOut being the output,
- * stored in arena's pool.
- */
-extern SECStatus
-NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut,
- PLArenaPool *arena);
-
-
-/************************************************************************
- *
- ************************************************************************/
-
-/*
- * define new S/MIME content type entries
- *
- * S/MIME uses the builtin PKCS7 oid types for encoding and decoding the
- * various S/MIME content. Some applications have their own content type
- * which is different from the standard content type defined by S/MIME.
- *
- * This function allows you to register new content types. There are basically
- * Two different types of content, Wrappping content, and Data.
- *
- * For data types, All the functions below can be zero or NULL excext
- * type and is isData, which should be your oid tag and PR_FALSE respectively
- *
- * For wrapping types, everything must be provided, or you will get encoder
- * failures.
- *
- * If NSS doesn't already define the OID that you need, you can register
- * your own with SECOID_AddEntry.
- *
- * Once you have defined your new content type, you can pass your new content
- * type to NSS_CMSContentInfo_SetContent().
- *
- * If you are using a wrapping type you can pass your own data structure in
- * the ptr field, but it must contain and embedded NSSCMSGenericWrappingData
- * structure as the first element. The size you pass to
- * NSS_CMSType_RegisterContentType is the total size of your self defined
- * data structure. NSS_CMSContentInfo_GetContent will return that data
- * structure from the content info. Your ASN1Template will be evaluated
- * against that data structure.
- */
-SECStatus NSS_CMSType_RegisterContentType(SECOidTag type,
- SEC_ASN1Template *asn1Template, size_t size,
- NSSCMSGenericWrapperDataDestroy destroy,
- NSSCMSGenericWrapperDataCallback decode_before,
- NSSCMSGenericWrapperDataCallback decode_after,
- NSSCMSGenericWrapperDataCallback decode_end,
- NSSCMSGenericWrapperDataCallback encode_start,
- NSSCMSGenericWrapperDataCallback encode_before,
- NSSCMSGenericWrapperDataCallback encode_after,
- PRBool isData);
-
-/************************************************************************/
-SEC_END_PROTOS
-
-#endif /* _CMS_H_ */
diff --git a/security/nss/lib/smime/cmsarray.c b/security/nss/lib/smime/cmsarray.c
deleted file mode 100644
index 323d654c8..000000000
--- a/security/nss/lib/smime/cmsarray.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS array functions.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "secerr.h"
-
-/*
- * ARRAY FUNCTIONS
- *
- * In NSS, arrays are rather primitive arrays of pointers.
- * Makes it easy to walk the array, but hard to count elements
- * and manage the storage.
- *
- * This is a feeble attempt to encapsulate the functionality
- * and get rid of hundreds of lines of similar code
- */
-
-/*
- * NSS_CMSArray_Alloc - allocate an array in an arena
- *
- * This allocates space for the array of pointers
- */
-void **
-NSS_CMSArray_Alloc(PRArenaPool *poolp, int n)
-{
- return (void **)PORT_ArenaZAlloc(poolp, n * sizeof(void *));
-}
-
-/*
- * NSS_CMSArray_Add - add an element to the end of an array
- *
- * The array of pointers is either created (if array was empty before) or grown.
- */
-SECStatus
-NSS_CMSArray_Add(PRArenaPool *poolp, void ***array, void *obj)
-{
- void **p;
- int n;
- void **dest;
-
- PORT_Assert(array != NULL);
- if (array == NULL)
- return SECFailure;
-
- if (*array == NULL) {
- dest = (void **)PORT_ArenaAlloc(poolp, 2 * sizeof(void *));
- n = 0;
- } else {
- n = 0; p = *array;
- while (*p++)
- n++;
- dest = (void **)PORT_ArenaGrow (poolp,
- *array,
- (n + 1) * sizeof(void *),
- (n + 2) * sizeof(void *));
- }
-
- if (dest == NULL)
- return SECFailure;
-
- dest[n] = obj;
- dest[n+1] = NULL;
- *array = dest;
- return SECSuccess;
-}
-
-/*
- * NSS_CMSArray_IsEmpty - check if array is empty
- */
-PRBool
-NSS_CMSArray_IsEmpty(void **array)
-{
- return (array == NULL || array[0] == NULL);
-}
-
-/*
- * NSS_CMSArray_Count - count number of elements in array
- */
-int
-NSS_CMSArray_Count(void **array)
-{
- int n = 0;
-
- if (array == NULL)
- return 0;
-
- while (*array++ != NULL)
- n++;
-
- return n;
-}
-
-/*
- * NSS_CMSArray_Sort - sort an array in place
- *
- * If "secondary" or "tertiary are not NULL, it must be arrays with the same
- * number of elements as "primary". The same reordering will get applied to it.
- *
- * "compare" is a function that returns
- * < 0 when the first element is less than the second
- * = 0 when the first element is equal to the second
- * > 0 when the first element is greater than the second
- * to acheive ascending ordering.
- */
-void
-NSS_CMSArray_Sort(void **primary, int (*compare)(void *,void *), void **secondary, void **tertiary)
-{
- int n, i, limit, lastxchg;
- void *tmp;
-
- n = NSS_CMSArray_Count(primary);
-
- PORT_Assert(secondary == NULL || NSS_CMSArray_Count(secondary) == n);
- PORT_Assert(tertiary == NULL || NSS_CMSArray_Count(tertiary) == n);
-
- if (n <= 1) /* ordering is fine */
- return;
-
- /* yes, ladies and gentlemen, it's BUBBLE SORT TIME! */
- limit = n - 1;
- while (1) {
- lastxchg = 0;
- for (i = 0; i < limit; i++) {
- if ((*compare)(primary[i], primary[i+1]) > 0) {
- /* exchange the neighbours */
- tmp = primary[i+1];
- primary[i+1] = primary[i];
- primary[i] = tmp;
- if (secondary) { /* secondary array? */
- tmp = secondary[i+1]; /* exchange there as well */
- secondary[i+1] = secondary[i];
- secondary[i] = tmp;
- }
- if (tertiary) { /* tertiary array? */
- tmp = tertiary[i+1]; /* exchange there as well */
- tertiary[i+1] = tertiary[i];
- tertiary[i] = tmp;
- }
- lastxchg = i+1; /* index of the last element bubbled up */
- }
- }
- if (lastxchg == 0) /* no exchanges, so array is sorted */
- break; /* we're done */
- limit = lastxchg; /* array is sorted up to [limit] */
- }
-}
-
-#if 0
-
-/* array iterator stuff... not used */
-
-typedef void **NSSCMSArrayIterator;
-
-/* iterator */
-NSSCMSArrayIterator
-NSS_CMSArray_First(void **array)
-{
- if (array == NULL || array[0] == NULL)
- return NULL;
- return (NSSCMSArrayIterator)&(array[0]);
-}
-
-void *
-NSS_CMSArray_Obj(NSSCMSArrayIterator iter)
-{
- void **p = (void **)iter;
-
- return *iter; /* which is NULL if we are at the end of the array */
-}
-
-NSSCMSArrayIterator
-NSS_CMSArray_Next(NSSCMSArrayIterator iter)
-{
- void **p = (void **)iter;
-
- return (NSSCMSArrayIterator)(p + 1);
-}
-
-#endif
diff --git a/security/nss/lib/smime/cmsasn1.c b/security/nss/lib/smime/cmsasn1.c
deleted file mode 100644
index 9a9c763db..000000000
--- a/security/nss/lib/smime/cmsasn1.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS ASN.1 templates
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "prtime.h"
-#include "secerr.h"
-
-
-extern const SEC_ASN1Template nss_cms_set_of_attribute_template[];
-
-SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
-SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate)
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-SEC_ASN1_MKSUB(SEC_BitStringTemplate)
-SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
-SEC_ASN1_MKSUB(SEC_PointerToOctetStringTemplate)
-SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
-
-/* -----------------------------------------------------------------------------
- * MESSAGE
- * (uses NSSCMSContentInfo)
- */
-
-/* forward declaration */
-static const SEC_ASN1Template *
-nss_cms_choose_content_template(void *src_or_dest, PRBool encoding);
-
-static const SEC_ASN1TemplateChooserPtr nss_cms_chooser
- = nss_cms_choose_content_template;
-
-const SEC_ASN1Template NSSCMSMessageTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSMessage) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(NSSCMSMessage,contentInfo.contentType) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM
- | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSCMSMessage,contentInfo.content),
- &nss_cms_chooser },
- { 0 }
-};
-
-static const SEC_ASN1Template NSS_PointerToCMSMessageTemplate[] = {
- { SEC_ASN1_POINTER, 0, NSSCMSMessageTemplate }
-};
-
-/* -----------------------------------------------------------------------------
- * ENCAPSULATED & ENCRYPTED CONTENTINFO
- * (both use a NSSCMSContentInfo)
- */
-static const SEC_ASN1Template NSSCMSEncapsulatedContentInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSContentInfo) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(NSSCMSContentInfo,contentType) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_MAY_STREAM |
- SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(NSSCMSContentInfo,rawContent),
- SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) },
- { 0 }
-};
-
-static const SEC_ASN1Template NSSCMSEncryptedContentInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSContentInfo) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(NSSCMSContentInfo,contentType) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSContentInfo,contentEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_MAY_STREAM |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(NSSCMSContentInfo,rawContent),
- SEC_ASN1_SUB(SEC_OctetStringTemplate) },
- { 0 }
-};
-
-/* -----------------------------------------------------------------------------
- * SIGNED DATA
- */
-
-const SEC_ASN1Template NSSCMSSignerInfoTemplate[];
-
-const SEC_ASN1Template NSSCMSSignedDataTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSSignedData) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSCMSSignedData,version) },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
- offsetof(NSSCMSSignedData,digestAlgorithms),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSSignedData,contentInfo),
- NSSCMSEncapsulatedContentInfoTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 0,
- offsetof(NSSCMSSignedData,rawCerts),
- SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
- offsetof(NSSCMSSignedData,crls),
- SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
- { SEC_ASN1_SET_OF,
- offsetof(NSSCMSSignedData,signerInfos),
- NSSCMSSignerInfoTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template NSS_PointerToCMSSignedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, NSSCMSSignedDataTemplate }
-};
-
-/* -----------------------------------------------------------------------------
- * signeridentifier
- */
-
-static const SEC_ASN1Template NSSCMSSignerIdentifierTemplate[] = {
- { SEC_ASN1_CHOICE,
- offsetof(NSSCMSSignerIdentifier,identifierType), NULL,
- sizeof(NSSCMSSignerIdentifier) },
- { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(NSSCMSSignerIdentifier,id.subjectKeyID),
- SEC_ASN1_SUB(SEC_OctetStringTemplate) ,
- NSSCMSRecipientID_SubjectKeyID },
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(NSSCMSSignerIdentifier,id.issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
- NSSCMSRecipientID_IssuerSN },
- { 0 }
-};
-
-/* -----------------------------------------------------------------------------
- * signerinfo
- */
-
-const SEC_ASN1Template NSSCMSSignerInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSSignerInfo) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSCMSSignerInfo,version) },
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSSignerInfo,signerIdentifier),
- NSSCMSSignerIdentifierTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSSignerInfo,digestAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSCMSSignerInfo,authAttr),
- nss_cms_set_of_attribute_template },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSSignerInfo,digestEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSSignerInfo,encDigest) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(NSSCMSSignerInfo,unAuthAttr),
- nss_cms_set_of_attribute_template },
- { 0 }
-};
-
-/* -----------------------------------------------------------------------------
- * ENVELOPED DATA
- */
-
-static const SEC_ASN1Template NSSCMSOriginatorInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSOriginatorInfo) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 0,
- offsetof(NSSCMSOriginatorInfo,rawCerts),
- SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
- offsetof(NSSCMSOriginatorInfo,crls),
- SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
-
-const SEC_ASN1Template NSSCMSEnvelopedDataTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSEnvelopedData) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSCMSEnvelopedData,version) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSCMSEnvelopedData,originatorInfo),
- NSSCMSOriginatorInfoTemplate },
- { SEC_ASN1_SET_OF,
- offsetof(NSSCMSEnvelopedData,recipientInfos),
- NSSCMSRecipientInfoTemplate },
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSEnvelopedData,contentInfo),
- NSSCMSEncryptedContentInfoTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(NSSCMSEnvelopedData,unprotectedAttr),
- nss_cms_set_of_attribute_template },
- { 0 }
-};
-
-const SEC_ASN1Template NSS_PointerToCMSEnvelopedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, NSSCMSEnvelopedDataTemplate }
-};
-
-/* here come the 15 gazillion templates for all the v3 varieties of RecipientInfo */
-
-/* -----------------------------------------------------------------------------
- * key transport recipient info
- */
-
-static const SEC_ASN1Template NSSCMSRecipientIdentifierTemplate[] = {
- { SEC_ASN1_CHOICE,
- offsetof(NSSCMSRecipientIdentifier,identifierType), NULL,
- sizeof(NSSCMSRecipientIdentifier) },
- { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(NSSCMSRecipientIdentifier,id.subjectKeyID),
- SEC_ASN1_SUB(SEC_OctetStringTemplate) ,
- NSSCMSRecipientID_SubjectKeyID },
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(NSSCMSRecipientIdentifier,id.issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
- NSSCMSRecipientID_IssuerSN },
- { 0 }
-};
-
-
-static const SEC_ASN1Template NSSCMSKeyTransRecipientInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSKeyTransRecipientInfo) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSCMSKeyTransRecipientInfo,version) },
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSKeyTransRecipientInfo,recipientIdentifier),
- NSSCMSRecipientIdentifierTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSKeyTransRecipientInfo,keyEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKeyTransRecipientInfo,encKey) },
- { 0 }
-};
-
-/* -----------------------------------------------------------------------------
- * key agreement recipient info
- */
-
-static const SEC_ASN1Template NSSCMSOriginatorPublicKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSOriginatorPublicKey) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSOriginatorPublicKey,algorithmIdentifier),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSOriginatorPublicKey,publicKey),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { 0 }
-};
-
-
-static const SEC_ASN1Template NSSCMSOriginatorIdentifierOrKeyTemplate[] = {
- { SEC_ASN1_CHOICE,
- offsetof(NSSCMSOriginatorIdentifierOrKey,identifierType), NULL,
- sizeof(NSSCMSOriginatorIdentifierOrKey) },
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(NSSCMSOriginatorIdentifierOrKey,id.issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
- NSSCMSOriginatorIDOrKey_IssuerSN },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
- offsetof(NSSCMSOriginatorIdentifierOrKey,id.subjectKeyID),
- SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) ,
- NSSCMSOriginatorIDOrKey_SubjectKeyID },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
- offsetof(NSSCMSOriginatorIdentifierOrKey,id.originatorPublicKey),
- NSSCMSOriginatorPublicKeyTemplate,
- NSSCMSOriginatorIDOrKey_OriginatorPublicKey },
- { 0 }
-};
-
-const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSRecipientKeyIdentifier) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSRecipientKeyIdentifier,subjectKeyIdentifier) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSRecipientKeyIdentifier,date) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSRecipientKeyIdentifier,other) },
- { 0 }
-};
-
-
-static const SEC_ASN1Template NSSCMSKeyAgreeRecipientIdentifierTemplate[] = {
- { SEC_ASN1_CHOICE,
- offsetof(NSSCMSKeyAgreeRecipientIdentifier,identifierType), NULL,
- sizeof(NSSCMSKeyAgreeRecipientIdentifier) },
- { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
- offsetof(NSSCMSKeyAgreeRecipientIdentifier,id.issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
- NSSCMSKeyAgreeRecipientID_IssuerSN },
- { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSCMSKeyAgreeRecipientIdentifier,id.recipientKeyIdentifier),
- NSSCMSRecipientKeyIdentifierTemplate,
- NSSCMSKeyAgreeRecipientID_RKeyID },
- { 0 }
-};
-
-static const SEC_ASN1Template NSSCMSRecipientEncryptedKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSRecipientEncryptedKey) },
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSRecipientEncryptedKey,recipientIdentifier),
- NSSCMSKeyAgreeRecipientIdentifierTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSRecipientEncryptedKey,encKey),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { 0 }
-};
-
-static const SEC_ASN1Template NSSCMSKeyAgreeRecipientInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSKeyAgreeRecipientInfo) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSCMSKeyAgreeRecipientInfo,version) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSCMSKeyAgreeRecipientInfo,originatorIdentifierOrKey),
- NSSCMSOriginatorIdentifierOrKeyTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
- SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
- offsetof(NSSCMSKeyAgreeRecipientInfo,ukm),
- SEC_ASN1_SUB(SEC_OctetStringTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSKeyAgreeRecipientInfo,keyEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_SEQUENCE_OF,
- offsetof(NSSCMSKeyAgreeRecipientInfo,recipientEncryptedKeys),
- NSSCMSRecipientEncryptedKeyTemplate },
- { 0 }
-};
-
-/* -----------------------------------------------------------------------------
- * KEK recipient info
- */
-
-static const SEC_ASN1Template NSSCMSKEKIdentifierTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSKEKIdentifier) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKIdentifier,keyIdentifier) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKIdentifier,date) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKIdentifier,other) },
- { 0 }
-};
-
-static const SEC_ASN1Template NSSCMSKEKRecipientInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSKEKRecipientInfo) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSCMSKEKRecipientInfo,version) },
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSKEKRecipientInfo,kekIdentifier),
- NSSCMSKEKIdentifierTemplate },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSKEKRecipientInfo,keyEncAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKRecipientInfo,encKey) },
- { 0 }
-};
-
-/* -----------------------------------------------------------------------------
- * recipient info
- */
-const SEC_ASN1Template NSSCMSRecipientInfoTemplate[] = {
- { SEC_ASN1_CHOICE,
- offsetof(NSSCMSRecipientInfo,recipientInfoType), NULL,
- sizeof(NSSCMSRecipientInfo) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(NSSCMSRecipientInfo,ri.keyAgreeRecipientInfo),
- NSSCMSKeyAgreeRecipientInfoTemplate,
- NSSCMSRecipientInfoID_KeyAgree },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
- offsetof(NSSCMSRecipientInfo,ri.kekRecipientInfo),
- NSSCMSKEKRecipientInfoTemplate,
- NSSCMSRecipientInfoID_KEK },
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSRecipientInfo,ri.keyTransRecipientInfo),
- NSSCMSKeyTransRecipientInfoTemplate,
- NSSCMSRecipientInfoID_KeyTrans },
- { 0 }
-};
-
-/* -----------------------------------------------------------------------------
- *
- */
-
-const SEC_ASN1Template NSSCMSDigestedDataTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSDigestedData) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSCMSDigestedData,version) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSCMSDigestedData,digestAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSDigestedData,contentInfo),
- NSSCMSEncapsulatedContentInfoTemplate },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSDigestedData,digest) },
- { 0 }
-};
-
-const SEC_ASN1Template NSS_PointerToCMSDigestedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, NSSCMSDigestedDataTemplate }
-};
-
-const SEC_ASN1Template NSSCMSEncryptedDataTemplate[] = {
- { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
- 0, NULL, sizeof(NSSCMSEncryptedData) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSCMSEncryptedData,version) },
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSEncryptedData,contentInfo),
- NSSCMSEncryptedContentInfoTemplate },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
- offsetof(NSSCMSEncryptedData,unprotectedAttr),
- nss_cms_set_of_attribute_template },
- { 0 }
-};
-
-const SEC_ASN1Template NSS_PointerToCMSEncryptedDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, NSSCMSEncryptedDataTemplate }
-};
-
-const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[] = {
- { SEC_ASN1_INLINE,
- offsetof(NSSCMSGenericWrapperData,contentInfo),
- NSSCMSEncapsulatedContentInfoTemplate },
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(NSSCMSGenericWrapperDataTemplate)
-
-const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[] = {
- { SEC_ASN1_POINTER, 0, NSSCMSGenericWrapperDataTemplate }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(NSS_PointerToCMSGenericWrapperDataTemplate)
-
-/* -----------------------------------------------------------------------------
- *
- */
-static const SEC_ASN1Template *
-nss_cms_choose_content_template(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- NSSCMSContentInfo *cinfo;
- SECOidTag type;
-
- PORT_Assert (src_or_dest != NULL);
- if (src_or_dest == NULL)
- return NULL;
-
- cinfo = (NSSCMSContentInfo *)src_or_dest;
- type = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
- switch (type) {
- default:
- theTemplate = NSS_CMSType_GetTemplate(type);
- break;
- case SEC_OID_PKCS7_DATA:
- theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- theTemplate = NSS_PointerToCMSSignedDataTemplate;
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- theTemplate = NSS_PointerToCMSEnvelopedDataTemplate;
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- theTemplate = NSS_PointerToCMSDigestedDataTemplate;
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- theTemplate = NSS_PointerToCMSEncryptedDataTemplate;
- break;
- }
- return theTemplate;
-}
diff --git a/security/nss/lib/smime/cmsattr.c b/security/nss/lib/smime/cmsattr.c
deleted file mode 100644
index 141beba4a..000000000
--- a/security/nss/lib/smime/cmsattr.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS attributes.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "prtime.h"
-#include "secerr.h"
-
-/*
- * -------------------------------------------------------------------
- * XXX The following Attribute stuff really belongs elsewhere.
- * The Attribute type is *not* part of CMS but rather X.501.
- * But for now, since CMS is the only customer of attributes,
- * we define them here. Once there is a use outside of CMS,
- * then change the attribute types and functions from internal
- * to external naming convention, and move them elsewhere!
- */
-
-
-/*
- * NSS_CMSAttribute_Create - create an attribute
- *
- * if value is NULL, the attribute won't have a value. It can be added later
- * with NSS_CMSAttribute_AddValue.
- */
-NSSCMSAttribute *
-NSS_CMSAttribute_Create(PRArenaPool *poolp, SECOidTag oidtag, SECItem *value, PRBool encoded)
-{
- NSSCMSAttribute *attr;
- SECItem *copiedvalue;
- void *mark;
-
- PORT_Assert (poolp != NULL);
-
- mark = PORT_ArenaMark (poolp);
-
- attr = (NSSCMSAttribute *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSAttribute));
- if (attr == NULL)
- goto loser;
-
- attr->typeTag = SECOID_FindOIDByTag(oidtag);
- if (attr->typeTag == NULL)
- goto loser;
-
- if (SECITEM_CopyItem(poolp, &(attr->type), &(attr->typeTag->oid)) != SECSuccess)
- goto loser;
-
- if (value != NULL) {
- if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL)
- goto loser;
-
- if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess)
- goto loser;
- }
-
- attr->encoded = encoded;
-
- PORT_ArenaUnmark (poolp, mark);
-
- return attr;
-
-loser:
- PORT_Assert (mark != NULL);
- PORT_ArenaRelease (poolp, mark);
- return NULL;
-}
-
-/*
- * NSS_CMSAttribute_AddValue - add another value to an attribute
- */
-SECStatus
-NSS_CMSAttribute_AddValue(PLArenaPool *poolp, NSSCMSAttribute *attr, SECItem *value)
-{
- SECItem *copiedvalue;
- void *mark;
-
- PORT_Assert (poolp != NULL);
-
- mark = PORT_ArenaMark(poolp);
-
- if (value == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
- }
-
- if ((copiedvalue = SECITEM_ArenaDupItem(poolp, value)) == NULL)
- goto loser;
-
- if (NSS_CMSArray_Add(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_Assert (mark != NULL);
- PORT_ArenaRelease (poolp, mark);
- return SECFailure;
-}
-
-/*
- * NSS_CMSAttribute_GetType - return the OID tag
- */
-SECOidTag
-NSS_CMSAttribute_GetType(NSSCMSAttribute *attr)
-{
- SECOidData *typetag;
-
- typetag = SECOID_FindOID(&(attr->type));
- if (typetag == NULL)
- return SEC_OID_UNKNOWN;
-
- return typetag->offset;
-}
-
-/*
- * NSS_CMSAttribute_GetValue - return the first attribute value
- *
- * We do some sanity checking first:
- * - Multiple values are *not* expected.
- * - Empty values are *not* expected.
- */
-SECItem *
-NSS_CMSAttribute_GetValue(NSSCMSAttribute *attr)
-{
- SECItem *value;
-
- if (attr == NULL)
- return NULL;
-
- value = attr->values[0];
-
- if (value == NULL || value->data == NULL || value->len == 0)
- return NULL;
-
- if (attr->values[1] != NULL)
- return NULL;
-
- return value;
-}
-
-/*
- * NSS_CMSAttribute_CompareValue - compare the attribute's first value against data
- */
-PRBool
-NSS_CMSAttribute_CompareValue(NSSCMSAttribute *attr, SECItem *av)
-{
- SECItem *value;
-
- if (attr == NULL)
- return PR_FALSE;
-
- value = NSS_CMSAttribute_GetValue(attr);
-
- return (value != NULL && value->len == av->len &&
- PORT_Memcmp (value->data, av->data, value->len) == 0);
-}
-
-/*
- * templates and functions for separate ASN.1 encoding of attributes
- *
- * used in NSS_CMSAttributeArray_Reorder
- */
-
-/*
- * helper function for dynamic template determination of the attribute value
- */
-static const SEC_ASN1Template *
-cms_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding)
-{
- const SEC_ASN1Template *theTemplate;
- NSSCMSAttribute *attribute;
- SECOidData *oiddata;
- PRBool encoded;
-
- PORT_Assert (src_or_dest != NULL);
- if (src_or_dest == NULL)
- return NULL;
-
- attribute = (NSSCMSAttribute *)src_or_dest;
-
- if (encoding && (!attribute->values || !attribute->values[0] ||
- attribute->encoded)) {
- /* we're encoding, and the attribute has no value or the attribute
- * value is already encoded. */
- return SEC_ASN1_GET(SEC_AnyTemplate);
- }
-
- /* get attribute's typeTag */
- oiddata = attribute->typeTag;
- if (oiddata == NULL) {
- oiddata = SECOID_FindOID(&attribute->type);
- attribute->typeTag = oiddata;
- }
-
- if (oiddata == NULL) {
- /* still no OID tag? OID is unknown then. en/decode value as ANY. */
- encoded = PR_TRUE;
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
- } else {
- switch (oiddata->offset) {
- case SEC_OID_PKCS9_SMIME_CAPABILITIES:
- case SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE:
- /* these guys need to stay DER-encoded */
- default:
- /* same goes for OIDs that are not handled here */
- encoded = PR_TRUE;
- theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
- break;
- /* otherwise choose proper template */
- case SEC_OID_PKCS9_EMAIL_ADDRESS:
- case SEC_OID_RFC1274_MAIL:
- case SEC_OID_PKCS9_UNSTRUCTURED_NAME:
- encoded = PR_FALSE;
- theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
- break;
- case SEC_OID_PKCS9_CONTENT_TYPE:
- encoded = PR_FALSE;
- theTemplate = SEC_ASN1_GET(SEC_ObjectIDTemplate);
- break;
- case SEC_OID_PKCS9_MESSAGE_DIGEST:
- encoded = PR_FALSE;
- theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate);
- break;
- case SEC_OID_PKCS9_SIGNING_TIME:
- encoded = PR_FALSE;
- theTemplate = SEC_ASN1_GET(CERT_TimeChoiceTemplate);
- break;
- /* XXX Want other types here, too */
- }
- }
-
- if (encoding) {
- /*
- * If we are encoding and we think we have an already-encoded value,
- * then the code which initialized this attribute should have set
- * the "encoded" property to true (and we would have returned early,
- * up above). No devastating error, but that code should be fixed.
- * (It could indicate that the resulting encoded bytes are wrong.)
- */
- PORT_Assert (!encoded);
- } else {
- /*
- * We are decoding; record whether the resulting value is
- * still encoded or not.
- */
- attribute->encoded = encoded;
- }
- return theTemplate;
-}
-
-static const SEC_ASN1TemplateChooserPtr cms_attr_chooser
- = cms_attr_choose_attr_value_template;
-
-const SEC_ASN1Template nss_cms_attribute_template[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSCMSAttribute) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(NSSCMSAttribute,type) },
- { SEC_ASN1_DYNAMIC | SEC_ASN1_SET_OF,
- offsetof(NSSCMSAttribute,values),
- &cms_attr_chooser },
- { 0 }
-};
-
-const SEC_ASN1Template nss_cms_set_of_attribute_template[] = {
- { SEC_ASN1_SET_OF, 0, nss_cms_attribute_template },
-};
-
-/* =============================================================================
- * Attribute Array methods
- */
-
-/*
- * NSS_CMSAttributeArray_Encode - encode an Attribute array as SET OF Attributes
- *
- * If you are wondering why this routine does not reorder the attributes
- * first, and might be tempted to make it do so, see the comment by the
- * call to ReorderAttributes in cmsencode.c. (Or, see who else calls this
- * and think long and hard about the implications of making it always
- * do the reordering.)
- */
-SECItem *
-NSS_CMSAttributeArray_Encode(PRArenaPool *poolp, NSSCMSAttribute ***attrs, SECItem *dest)
-{
- return SEC_ASN1EncodeItem (poolp, dest, (void *)attrs, nss_cms_set_of_attribute_template);
-}
-
-/*
- * NSS_CMSAttributeArray_Reorder - sort attribute array by attribute's DER encoding
- *
- * make sure that the order of the attributes guarantees valid DER (which must be
- * in lexigraphically ascending order for a SET OF); if reordering is necessary it
- * will be done in place (in attrs).
- */
-SECStatus
-NSS_CMSAttributeArray_Reorder(NSSCMSAttribute **attrs)
-{
- return NSS_CMSArray_SortByDER((void **)attrs, nss_cms_attribute_template, NULL);
-}
-
-/*
- * NSS_CMSAttributeArray_FindAttrByOidTag - look through a set of attributes and
- * find one that matches the specified object ID.
- *
- * If "only" is true, then make sure that there is not more than one attribute
- * of the same type. Otherwise, just return the first one found. (XXX Does
- * anybody really want that first-found behavior? It was like that when I found it...)
- */
-NSSCMSAttribute *
-NSS_CMSAttributeArray_FindAttrByOidTag(NSSCMSAttribute **attrs, SECOidTag oidtag, PRBool only)
-{
- SECOidData *oid;
- NSSCMSAttribute *attr1, *attr2;
-
- if (attrs == NULL)
- return NULL;
-
- oid = SECOID_FindOIDByTag(oidtag);
- if (oid == NULL)
- return NULL;
-
- while ((attr1 = *attrs++) != NULL) {
- if (attr1->type.len == oid->oid.len && PORT_Memcmp (attr1->type.data,
- oid->oid.data,
- oid->oid.len) == 0)
- break;
- }
-
- if (attr1 == NULL)
- return NULL;
-
- if (!only)
- return attr1;
-
- while ((attr2 = *attrs++) != NULL) {
- if (attr2->type.len == oid->oid.len && PORT_Memcmp (attr2->type.data,
- oid->oid.data,
- oid->oid.len) == 0)
- break;
- }
-
- if (attr2 != NULL)
- return NULL;
-
- return attr1;
-}
-
-/*
- * NSS_CMSAttributeArray_AddAttr - add an attribute to an
- * array of attributes.
- */
-SECStatus
-NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSCMSAttribute *attr)
-{
- NSSCMSAttribute *oattr;
- void *mark;
- SECOidTag type;
-
- mark = PORT_ArenaMark(poolp);
-
- /* find oidtag of attr */
- type = NSS_CMSAttribute_GetType(attr);
-
- /* see if we have one already */
- oattr = NSS_CMSAttributeArray_FindAttrByOidTag(*attrs, type, PR_FALSE);
- PORT_Assert (oattr == NULL);
- if (oattr != NULL)
- goto loser; /* XXX or would it be better to replace it? */
-
- /* no, shove it in */
- if (NSS_CMSArray_Add(poolp, (void ***)attrs, (void *)attr) != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-/*
- * NSS_CMSAttributeArray_SetAttr - set an attribute's value in a set of attributes
- */
-SECStatus
-NSS_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, SECOidTag type, SECItem *value, PRBool encoded)
-{
- NSSCMSAttribute *attr;
- void *mark;
-
- mark = PORT_ArenaMark(poolp);
-
- /* see if we have one already */
- attr = NSS_CMSAttributeArray_FindAttrByOidTag(*attrs, type, PR_FALSE);
- if (attr == NULL) {
- /* not found? create one! */
- attr = NSS_CMSAttribute_Create(poolp, type, value, encoded);
- if (attr == NULL)
- goto loser;
- /* and add it to the list */
- if (NSS_CMSArray_Add(poolp, (void ***)attrs, (void *)attr) != SECSuccess)
- goto loser;
- } else {
- /* found, shove it in */
- /* XXX we need a decent memory model @#$#$!#!!! */
- attr->values[0] = value;
- attr->encoded = encoded;
- }
-
- PORT_ArenaUnmark (poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease (poolp, mark);
- return SECFailure;
-}
-
diff --git a/security/nss/lib/smime/cmscinfo.c b/security/nss/lib/smime/cmscinfo.c
deleted file mode 100644
index e7f9cfd33..000000000
--- a/security/nss/lib/smime/cmscinfo.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS contentInfo methods.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "pk11func.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "secerr.h"
-
-
-/*
- * NSS_CMSContentInfo_Create - create a content info
- *
- * version is set in the _Finalize procedures for each content type
- */
-SECStatus
-NSS_CMSContentInfo_Private_Init(NSSCMSContentInfo *cinfo)
-{
- if (cinfo->privateInfo) {
- return SECSuccess;
- }
- cinfo->privateInfo = PORT_ZNew(NSSCMSContentInfoPrivate);
- return (cinfo->privateInfo) ? SECSuccess : SECFailure;
-}
-
-
-static void
-nss_cmsContentInfo_private_destroy(NSSCMSContentInfoPrivate *privateInfo)
-{
- if (privateInfo->digcx) {
- /* must destroy digest objects */
- NSS_CMSDigestContext_Cancel(privateInfo->digcx);
- privateInfo->digcx = NULL;
- }
- if (privateInfo->ciphcx) {
- NSS_CMSCipherContext_Destroy(privateInfo->ciphcx);
- privateInfo->ciphcx = NULL;
- }
- PORT_Free(privateInfo);
-}
-
-/*
- * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces.
- */
-void
-NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
-{
- SECOidTag kind;
-
- kind = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
- switch (kind) {
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- NSS_CMSEnvelopedData_Destroy(cinfo->content.envelopedData);
- break;
- case SEC_OID_PKCS7_SIGNED_DATA:
- NSS_CMSSignedData_Destroy(cinfo->content.signedData);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- NSS_CMSEncryptedData_Destroy(cinfo->content.encryptedData);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- NSS_CMSDigestedData_Destroy(cinfo->content.digestedData);
- break;
- default:
- NSS_CMSGenericWrapperData_Destroy(kind, cinfo->content.genericData);
- /* XXX Anything else that needs to be "manually" freed/destroyed? */
- break;
- }
- if (cinfo->privateInfo) {
- nss_cmsContentInfo_private_destroy(cinfo->privateInfo);
- cinfo->privateInfo = NULL;
- }
- if (cinfo->bulkkey) {
- PK11_FreeSymKey(cinfo->bulkkey);
- }
-}
-
-/*
- * NSS_CMSContentInfo_GetChildContentInfo - get content's contentInfo (if it exists)
- */
-NSSCMSContentInfo *
-NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo)
-{
- NSSCMSContentInfo * ccinfo = NULL;
- SECOidTag tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
- switch (tag) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- if (cinfo->content.signedData != NULL) {
- ccinfo = &(cinfo->content.signedData->contentInfo);
- }
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- if (cinfo->content.envelopedData != NULL) {
- ccinfo = &(cinfo->content.envelopedData->contentInfo);
- }
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- if (cinfo->content.digestedData != NULL) {
- ccinfo = &(cinfo->content.digestedData->contentInfo);
- }
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- if (cinfo->content.encryptedData != NULL) {
- ccinfo = &(cinfo->content.encryptedData->contentInfo);
- }
- break;
- case SEC_OID_PKCS7_DATA:
- default:
- if (NSS_CMSType_IsWrapper(tag)) {
- if (cinfo->content.genericData != NULL) {
- ccinfo = &(cinfo->content.genericData->contentInfo);
- }
- }
- break;
- }
- if (ccinfo && !ccinfo->privateInfo) {
- NSS_CMSContentInfo_Private_Init(ccinfo);
- }
- return ccinfo;
-}
-
-SECStatus
-NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream)
-{
- SECStatus rv;
-
- rv = NSS_CMSContentInfo_Private_Init(cinfo);
- if (rv != SECSuccess) {
- /* default is streaming, failure to get ccinfo will not effect this */
- return dontStream ? SECFailure : SECSuccess ;
- }
- cinfo->privateInfo->dontStream = dontStream;
- return SECSuccess;
-}
-
-/*
- * NSS_CMSContentInfo_SetContent - set content type & content
- */
-SECStatus
-NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr)
-{
- SECStatus rv;
-
- cinfo->contentTypeTag = SECOID_FindOIDByTag(type);
- if (cinfo->contentTypeTag == NULL)
- return SECFailure;
-
- /* do not copy the oid, just create a reference */
- rv = SECITEM_CopyItem (cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid));
- if (rv != SECSuccess)
- return SECFailure;
-
- cinfo->content.pointer = ptr;
-
- if (NSS_CMSType_IsData(type) && ptr) {
- cinfo->rawContent = ptr;
- } else {
- /* as we always have some inner data,
- * we need to set it to something, just to fool the encoder enough to work on it
- * and get us into nss_cms_encoder_notify at that point */
- cinfo->rawContent = SECITEM_AllocItem(cmsg->poolp, NULL, 1);
- if (cinfo->rawContent == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- }
-
- return SECSuccess;
-}
-
-/*
- * NSS_CMSContentInfo_SetContent_XXXX - typesafe wrappers for NSS_CMSContentInfo_SetContent
- */
-
-/*
- * data == NULL -> pass in data via NSS_CMSEncoder_Update
- * data != NULL -> take this data
- */
-SECStatus
-NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached)
-{
- if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess)
- return SECFailure;
- if (detached) {
- cinfo->rawContent = NULL;
- }
-
- return SECSuccess;
-}
-
-SECStatus
-NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd)
-{
- return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_SIGNED_DATA, (void *)sigd);
-}
-
-SECStatus
-NSS_CMSContentInfo_SetContent_EnvelopedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd)
-{
- return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENVELOPED_DATA, (void *)envd);
-}
-
-SECStatus
-NSS_CMSContentInfo_SetContent_DigestedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd)
-{
- return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DIGESTED_DATA, (void *)digd);
-}
-
-SECStatus
-NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd)
-{
- return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENCRYPTED_DATA, (void *)encd);
-}
-
-
-/*
- * NSS_CMSContentInfo_GetContent - get pointer to inner content
- *
- * needs to be casted...
- */
-void *
-NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo)
-{
- SECOidTag tag = (cinfo && cinfo->contentTypeTag)
- ? cinfo->contentTypeTag->offset
- : SEC_OID_UNKNOWN;
- switch (tag) {
- case SEC_OID_PKCS7_DATA:
- case SEC_OID_PKCS7_SIGNED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- return cinfo->content.pointer;
- default:
- return NSS_CMSType_IsWrapper(tag) ? cinfo->content.pointer : (NSS_CMSType_IsData(tag) ? cinfo->rawContent : NULL);
- }
-}
-
-/*
- * NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content
- *
- * this is typically only called by NSS_CMSMessage_GetContent()
- */
-
-SECItem *
-NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo)
-{
- NSSCMSContentInfo *ccinfo;
- SECOidTag tag;
- SECItem *pItem = NULL;
-
- tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
- if (NSS_CMSType_IsData(tag)) {
- pItem = cinfo->content.data;
- } else if (NSS_CMSType_IsWrapper(tag)) {
- ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
- if (ccinfo != NULL) {
- pItem = NSS_CMSContentInfo_GetContent(ccinfo);
- }
- } else {
- PORT_Assert(0);
- }
-
- return pItem;
-}
-
-
-/*
- * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result
- * for future reference) and return the inner content type.
- */
-SECOidTag
-NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo)
-{
- if (cinfo->contentTypeTag == NULL)
- cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
-
- if (cinfo->contentTypeTag == NULL)
- return SEC_OID_UNKNOWN;
-
- return cinfo->contentTypeTag->offset;
-}
-
-SECItem *
-NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo)
-{
- if (cinfo->contentTypeTag == NULL)
- cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
-
- if (cinfo->contentTypeTag == NULL)
- return NULL;
-
- return &(cinfo->contentTypeTag->oid);
-}
-
-/*
- * NSS_CMSContentInfo_GetContentEncAlgTag - find out (saving pointer to lookup result
- * for future reference) and return the content encryption algorithm tag.
- */
-SECOidTag
-NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo)
-{
- if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN)
- cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg));
-
- return cinfo->contentEncAlgTag;
-}
-
-/*
- * NSS_CMSContentInfo_GetContentEncAlg - find out and return the content encryption algorithm tag.
- */
-SECAlgorithmID *
-NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo)
-{
- return &(cinfo->contentEncAlg);
-}
-
-SECStatus
-NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
- SECOidTag bulkalgtag, SECItem *parameters, int keysize)
-{
- SECStatus rv;
-
- rv = SECOID_SetAlgorithmID(poolp, &(cinfo->contentEncAlg), bulkalgtag, parameters);
- if (rv != SECSuccess)
- return SECFailure;
- cinfo->keysize = keysize;
- return SECSuccess;
-}
-
-SECStatus
-NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
- SECAlgorithmID *algid, int keysize)
-{
- SECStatus rv;
-
- rv = SECOID_CopyAlgorithmID(poolp, &(cinfo->contentEncAlg), algid);
- if (rv != SECSuccess)
- return SECFailure;
- if (keysize >= 0)
- cinfo->keysize = keysize;
- return SECSuccess;
-}
-
-void
-NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey)
-{
- cinfo->bulkkey = PK11_ReferenceSymKey(bulkkey);
- cinfo->keysize = PK11_GetKeyStrength(cinfo->bulkkey, &(cinfo->contentEncAlg));
-}
-
-PK11SymKey *
-NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo)
-{
- if (cinfo->bulkkey == NULL)
- return NULL;
-
- return PK11_ReferenceSymKey(cinfo->bulkkey);
-}
-
-int
-NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo)
-{
- return cinfo->keysize;
-}
diff --git a/security/nss/lib/smime/cmscipher.c b/security/nss/lib/smime/cmscipher.c
deleted file mode 100644
index c9bcb1895..000000000
--- a/security/nss/lib/smime/cmscipher.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Encryption/decryption routines for CMS implementation, none of which are exported.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "secoid.h"
-#include "secitem.h"
-#include "pk11func.h"
-#include "secerr.h"
-#include "secpkcs5.h"
-
-/*
- * -------------------------------------------------------------------
- * Cipher stuff.
- */
-
-typedef SECStatus (*nss_cms_cipher_function) (void *, unsigned char *, unsigned int *,
- unsigned int, const unsigned char *, unsigned int);
-typedef SECStatus (*nss_cms_cipher_destroy) (void *, PRBool);
-
-#define BLOCK_SIZE 4096
-
-struct NSSCMSCipherContextStr {
- void * cx; /* PK11 cipher context */
- nss_cms_cipher_function doit;
- nss_cms_cipher_destroy destroy;
- PRBool encrypt; /* encrypt / decrypt switch */
- int block_size; /* block & pad sizes for cipher */
- int pad_size;
- int pending_count; /* pending data (not yet en/decrypted */
- unsigned char pending_buf[BLOCK_SIZE];/* because of blocking */
-};
-
-/*
- * NSS_CMSCipherContext_StartDecrypt - create a cipher context to do decryption
- * based on the given bulk encryption key and algorithm identifier (which
- * may include an iv).
- *
- * XXX Once both are working, it might be nice to combine this and the
- * function below (for starting up encryption) into one routine, and just
- * have two simple cover functions which call it.
- */
-NSSCMSCipherContext *
-NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid)
-{
- NSSCMSCipherContext *cc;
- void *ciphercx;
- CK_MECHANISM_TYPE cryptoMechType;
- PK11SlotInfo *slot;
- SECOidTag algtag;
- SECItem *param = NULL;
-
- algtag = SECOID_GetAlgorithmTag(algid);
-
- /* set param and mechanism */
- if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
- SECItem *pwitem;
-
- pwitem = PK11_GetSymKeyUserData(key);
- if (!pwitem)
- return NULL;
-
- cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
- if (cryptoMechType == CKM_INVALID_MECHANISM) {
- SECITEM_FreeItem(param,PR_TRUE);
- return NULL;
- }
-
- } else {
- cryptoMechType = PK11_AlgtagToMechanism(algtag);
- if ((param = PK11_ParamFromAlgid(algid)) == NULL)
- return NULL;
- }
-
- cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext));
- if (cc == NULL) {
- SECITEM_FreeItem(param,PR_TRUE);
- return NULL;
- }
-
- /* figure out pad and block sizes */
- cc->pad_size = PK11_GetBlockSize(cryptoMechType, param);
- slot = PK11_GetSlotFromKey(key);
- cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size;
- PK11_FreeSlot(slot);
-
- /* create PK11 cipher context */
- ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT,
- key, param);
- SECITEM_FreeItem(param, PR_TRUE);
- if (ciphercx == NULL) {
- PORT_Free (cc);
- return NULL;
- }
-
- cc->cx = ciphercx;
- cc->doit = (nss_cms_cipher_function) PK11_CipherOp;
- cc->destroy = (nss_cms_cipher_destroy) PK11_DestroyContext;
- cc->encrypt = PR_FALSE;
- cc->pending_count = 0;
-
- return cc;
-}
-
-/*
- * NSS_CMSCipherContext_StartEncrypt - create a cipher object to do encryption,
- * based on the given bulk encryption key and algorithm tag. Fill in the
- * algorithm identifier (which may include an iv) appropriately.
- *
- * XXX Once both are working, it might be nice to combine this and the
- * function above (for starting up decryption) into one routine, and just
- * have two simple cover functions which call it.
- */
-NSSCMSCipherContext *
-NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgorithmID *algid)
-{
- NSSCMSCipherContext *cc;
- void *ciphercx;
- SECStatus rv;
- CK_MECHANISM_TYPE cryptoMechType;
- PK11SlotInfo *slot;
- SECItem *param = NULL;
- PRBool needToEncodeAlgid = PR_FALSE;
- SECOidTag algtag = SECOID_GetAlgorithmTag(algid);
-
- /* set param and mechanism */
- if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
- SECItem *pwitem;
-
- pwitem = PK11_GetSymKeyUserData(key);
- if (!pwitem)
- return NULL;
-
- cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
- if (cryptoMechType == CKM_INVALID_MECHANISM) {
- SECITEM_FreeItem(param,PR_TRUE);
- return NULL;
- }
- } else {
- cryptoMechType = PK11_AlgtagToMechanism(algtag);
- if ((param = PK11_GenerateNewParam(cryptoMechType, key)) == NULL)
- return NULL;
- needToEncodeAlgid = PR_TRUE;
- }
-
- cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext));
- if (cc == NULL) {
- goto loser;
- }
-
- /* now find pad and block sizes for our mechanism */
- cc->pad_size = PK11_GetBlockSize(cryptoMechType, param);
- slot = PK11_GetSlotFromKey(key);
- cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size;
- PK11_FreeSlot(slot);
-
- /* and here we go, creating a PK11 cipher context */
- ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT,
- key, param);
- if (ciphercx == NULL) {
- PORT_Free(cc);
- cc = NULL;
- goto loser;
- }
-
- /*
- * These are placed after the CreateContextBySymKey() because some
- * mechanisms have to generate their IVs from their card (i.e. FORTEZZA).
- * Don't move it from here.
- * XXX is that right? the purpose of this is to get the correct algid
- * containing the IVs etc. for encoding. this means we need to set this up
- * BEFORE encoding the algid in the contentInfo, right?
- */
- if (needToEncodeAlgid) {
- rv = PK11_ParamToAlgid(algtag, param, poolp, algid);
- if(rv != SECSuccess) {
- PORT_Free(cc);
- cc = NULL;
- goto loser;
- }
- }
-
- cc->cx = ciphercx;
- cc->doit = (nss_cms_cipher_function)PK11_CipherOp;
- cc->destroy = (nss_cms_cipher_destroy)PK11_DestroyContext;
- cc->encrypt = PR_TRUE;
- cc->pending_count = 0;
-
-loser:
- SECITEM_FreeItem(param, PR_TRUE);
-
- return cc;
-}
-
-void
-NSS_CMSCipherContext_Destroy(NSSCMSCipherContext *cc)
-{
- PORT_Assert(cc != NULL);
- if (cc == NULL)
- return;
- (*cc->destroy)(cc->cx, PR_TRUE);
- PORT_Free(cc);
-}
-
-/*
- * NSS_CMSCipherContext_DecryptLength - find the output length of the next call to decrypt.
- *
- * cc - the cipher context
- * input_len - number of bytes used as input
- * final - true if this is the final chunk of data
- *
- * Result can be used to perform memory allocations. Note that the amount
- * is exactly accurate only when not doing a block cipher or when final
- * is false, otherwise it is an upper bound on the amount because until
- * we see the data we do not know how many padding bytes there are
- * (always between 1 and bsize).
- *
- * Note that this can return zero, which does not mean that the decrypt
- * operation can be skipped! (It simply means that there are not enough
- * bytes to make up an entire block; the bytes will be reserved until
- * there are enough to encrypt/decrypt at least one block.) However,
- * if zero is returned it *does* mean that no output buffer need be
- * passed in to the subsequent decrypt operation, as no output bytes
- * will be stored.
- */
-unsigned int
-NSS_CMSCipherContext_DecryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final)
-{
- int blocks, block_size;
-
- PORT_Assert (! cc->encrypt);
-
- block_size = cc->block_size;
-
- /*
- * If this is not a block cipher, then we always have the same
- * number of output bytes as we had input bytes.
- */
- if (block_size == 0)
- return input_len;
-
- /*
- * On the final call, we will always use up all of the pending
- * bytes plus all of the input bytes, *but*, there will be padding
- * at the end and we cannot predict how many bytes of padding we
- * will end up removing. The amount given here is actually known
- * to be at least 1 byte too long (because we know we will have
- * at least 1 byte of padding), but seemed clearer/better to me.
- */
- if (final)
- return cc->pending_count + input_len;
-
- /*
- * Okay, this amount is exactly what we will output on the
- * next cipher operation. We will always hang onto the last
- * 1 - block_size bytes for non-final operations. That is,
- * we will do as many complete blocks as we can *except* the
- * last block (complete or partial). (This is because until
- * we know we are at the end, we cannot know when to interpret
- * and removing the padding byte(s), which are guaranteed to
- * be there.)
- */
- blocks = (cc->pending_count + input_len - 1) / block_size;
- return blocks * block_size;
-}
-
-/*
- * NSS_CMSCipherContext_EncryptLength - find the output length of the next call to encrypt.
- *
- * cc - the cipher context
- * input_len - number of bytes used as input
- * final - true if this is the final chunk of data
- *
- * Result can be used to perform memory allocations.
- *
- * Note that this can return zero, which does not mean that the encrypt
- * operation can be skipped! (It simply means that there are not enough
- * bytes to make up an entire block; the bytes will be reserved until
- * there are enough to encrypt/decrypt at least one block.) However,
- * if zero is returned it *does* mean that no output buffer need be
- * passed in to the subsequent encrypt operation, as no output bytes
- * will be stored.
- */
-unsigned int
-NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final)
-{
- int blocks, block_size;
- int pad_size;
-
- PORT_Assert (cc->encrypt);
-
- block_size = cc->block_size;
- pad_size = cc->pad_size;
-
- /*
- * If this is not a block cipher, then we always have the same
- * number of output bytes as we had input bytes.
- */
- if (block_size == 0)
- return input_len;
-
- /*
- * On the final call, we only send out what we need for
- * remaining bytes plus the padding. (There is always padding,
- * so even if we have an exact number of blocks as input, we
- * will add another full block that is just padding.)
- */
- if (final) {
- if (pad_size == 0) {
- return cc->pending_count + input_len;
- } else {
- blocks = (cc->pending_count + input_len) / pad_size;
- blocks++;
- return blocks*pad_size;
- }
- }
-
- /*
- * Now, count the number of complete blocks of data we have.
- */
- blocks = (cc->pending_count + input_len) / block_size;
-
-
- return blocks * block_size;
-}
-
-
-/*
- * NSS_CMSCipherContext_Decrypt - do the decryption
- *
- * cc - the cipher context
- * output - buffer for decrypted result bytes
- * output_len_p - number of bytes in output
- * max_output_len - upper bound on bytes to put into output
- * input - pointer to input bytes
- * input_len - number of input bytes
- * final - true if this is the final chunk of data
- *
- * Decrypts a given length of input buffer (starting at "input" and
- * containing "input_len" bytes), placing the decrypted bytes in
- * "output" and storing the output length in "*output_len_p".
- * "cc" is the return value from NSS_CMSCipher_StartDecrypt.
- * When "final" is true, this is the last of the data to be decrypted.
- *
- * This is much more complicated than it sounds when the cipher is
- * a block-type, meaning that the decryption function will only
- * operate on whole blocks. But our caller is operating stream-wise,
- * and can pass in any number of bytes. So we need to keep track
- * of block boundaries. We save excess bytes between calls in "cc".
- * We also need to determine which bytes are padding, and remove
- * them from the output. We can only do this step when we know we
- * have the final block of data. PKCS #7 specifies that the padding
- * used for a block cipher is a string of bytes, each of whose value is
- * the same as the length of the padding, and that all data is padded.
- * (Even data that starts out with an exact multiple of blocks gets
- * added to it another block, all of which is padding.)
- */
-SECStatus
-NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,
- unsigned int *output_len_p, unsigned int max_output_len,
- const unsigned char *input, unsigned int input_len,
- PRBool final)
-{
- int blocks, bsize, pcount, padsize;
- unsigned int max_needed, ifraglen, ofraglen, output_len;
- unsigned char *pbuf;
- SECStatus rv;
-
- PORT_Assert (! cc->encrypt);
-
- /*
- * Check that we have enough room for the output. Our caller should
- * already handle this; failure is really an internal error (i.e. bug).
- */
- max_needed = NSS_CMSCipherContext_DecryptLength(cc, input_len, final);
- PORT_Assert (max_output_len >= max_needed);
- if (max_output_len < max_needed) {
- /* PORT_SetError (XXX); */
- return SECFailure;
- }
-
- /*
- * hardware encryption does not like small decryption sizes here, so we
- * allow both blocking and padding.
- */
- bsize = cc->block_size;
- padsize = cc->pad_size;
-
- /*
- * When no blocking or padding work to do, we can simply call the
- * cipher function and we are done.
- */
- if (bsize == 0) {
- return (* cc->doit) (cc->cx, output, output_len_p, max_output_len,
- input, input_len);
- }
-
- pcount = cc->pending_count;
- pbuf = cc->pending_buf;
-
- output_len = 0;
-
- if (pcount) {
- /*
- * Try to fill in an entire block, starting with the bytes
- * we already have saved away.
- */
- while (input_len && pcount < bsize) {
- pbuf[pcount++] = *input++;
- input_len--;
- }
- /*
- * If we have at most a whole block and this is not our last call,
- * then we are done for now. (We do not try to decrypt a lone
- * single block because we cannot interpret the padding bytes
- * until we know we are handling the very last block of all input.)
- */
- if (input_len == 0 && !final) {
- cc->pending_count = pcount;
- if (output_len_p)
- *output_len_p = 0;
- return SECSuccess;
- }
- /*
- * Given the logic above, we expect to have a full block by now.
- * If we do not, there is something wrong, either with our own
- * logic or with (length of) the data given to us.
- */
- if ((padsize != 0) && (pcount % padsize) != 0) {
- PORT_Assert (final);
- PORT_SetError (SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- /*
- * Decrypt the block.
- */
- rv = (*cc->doit)(cc->cx, output, &ofraglen, max_output_len,
- pbuf, pcount);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then NSS_CMSCipherContext_DecryptLength needs to be made smarter!
- */
- PORT_Assert(ofraglen == pcount);
-
- /*
- * Account for the bytes now in output.
- */
- max_output_len -= ofraglen;
- output_len += ofraglen;
- output += ofraglen;
- }
-
- /*
- * If this is our last call, we expect to have an exact number of
- * blocks left to be decrypted; we will decrypt them all.
- *
- * If not our last call, we always save between 1 and bsize bytes
- * until next time. (We must do this because we cannot be sure
- * that none of the decrypted bytes are padding bytes until we
- * have at least another whole block of data. You cannot tell by
- * looking -- the data could be anything -- you can only tell by
- * context, knowing you are looking at the last block.) We could
- * decrypt a whole block now but it is easier if we just treat it
- * the same way we treat partial block bytes.
- */
- if (final) {
- if (padsize) {
- blocks = input_len / padsize;
- ifraglen = blocks * padsize;
- } else ifraglen = input_len;
- PORT_Assert (ifraglen == input_len);
-
- if (ifraglen != input_len) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- } else {
- blocks = (input_len - 1) / bsize;
- ifraglen = blocks * bsize;
- PORT_Assert (ifraglen < input_len);
-
- pcount = input_len - ifraglen;
- PORT_Memcpy (pbuf, input + ifraglen, pcount);
- cc->pending_count = pcount;
- }
-
- if (ifraglen) {
- rv = (* cc->doit)(cc->cx, output, &ofraglen, max_output_len,
- input, ifraglen);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then sec_PKCS7DecryptLength needs to be made smarter!
- */
- PORT_Assert (ifraglen == ofraglen);
- if (ifraglen != ofraglen) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
-
- output_len += ofraglen;
- } else {
- ofraglen = 0;
- }
-
- /*
- * If we just did our very last block, "remove" the padding by
- * adjusting the output length.
- */
- if (final && (padsize != 0)) {
- unsigned int padlen = *(output + ofraglen - 1);
-
- if (padlen == 0 || padlen > padsize) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- output_len -= padlen;
- }
-
- PORT_Assert (output_len_p != NULL || output_len == 0);
- if (output_len_p != NULL)
- *output_len_p = output_len;
-
- return SECSuccess;
-}
-
-/*
- * NSS_CMSCipherContext_Encrypt - do the encryption
- *
- * cc - the cipher context
- * output - buffer for decrypted result bytes
- * output_len_p - number of bytes in output
- * max_output_len - upper bound on bytes to put into output
- * input - pointer to input bytes
- * input_len - number of input bytes
- * final - true if this is the final chunk of data
- *
- * Encrypts a given length of input buffer (starting at "input" and
- * containing "input_len" bytes), placing the encrypted bytes in
- * "output" and storing the output length in "*output_len_p".
- * "cc" is the return value from NSS_CMSCipher_StartEncrypt.
- * When "final" is true, this is the last of the data to be encrypted.
- *
- * This is much more complicated than it sounds when the cipher is
- * a block-type, meaning that the encryption function will only
- * operate on whole blocks. But our caller is operating stream-wise,
- * and can pass in any number of bytes. So we need to keep track
- * of block boundaries. We save excess bytes between calls in "cc".
- * We also need to add padding bytes at the end. PKCS #7 specifies
- * that the padding used for a block cipher is a string of bytes,
- * each of whose value is the same as the length of the padding,
- * and that all data is padded. (Even data that starts out with
- * an exact multiple of blocks gets added to it another block,
- * all of which is padding.)
- *
- * XXX I would kind of like to combine this with the function above
- * which does decryption, since they have a lot in common. But the
- * tricky parts about padding and filling blocks would be much
- * harder to read that way, so I left them separate. At least for
- * now until it is clear that they are right.
- */
-SECStatus
-NSS_CMSCipherContext_Encrypt(NSSCMSCipherContext *cc, unsigned char *output,
- unsigned int *output_len_p, unsigned int max_output_len,
- const unsigned char *input, unsigned int input_len,
- PRBool final)
-{
- int blocks, bsize, padlen, pcount, padsize;
- unsigned int max_needed, ifraglen, ofraglen, output_len;
- unsigned char *pbuf;
- SECStatus rv;
-
- PORT_Assert (cc->encrypt);
-
- /*
- * Check that we have enough room for the output. Our caller should
- * already handle this; failure is really an internal error (i.e. bug).
- */
- max_needed = NSS_CMSCipherContext_EncryptLength (cc, input_len, final);
- PORT_Assert (max_output_len >= max_needed);
- if (max_output_len < max_needed) {
- /* PORT_SetError (XXX); */
- return SECFailure;
- }
-
- bsize = cc->block_size;
- padsize = cc->pad_size;
-
- /*
- * When no blocking and padding work to do, we can simply call the
- * cipher function and we are done.
- */
- if (bsize == 0) {
- return (*cc->doit)(cc->cx, output, output_len_p, max_output_len,
- input, input_len);
- }
-
- pcount = cc->pending_count;
- pbuf = cc->pending_buf;
-
- output_len = 0;
-
- if (pcount) {
- /*
- * Try to fill in an entire block, starting with the bytes
- * we already have saved away.
- */
- while (input_len && pcount < bsize) {
- pbuf[pcount++] = *input++;
- input_len--;
- }
- /*
- * If we do not have a full block and we know we will be
- * called again, then we are done for now.
- */
- if (pcount < bsize && !final) {
- cc->pending_count = pcount;
- if (output_len_p != NULL)
- *output_len_p = 0;
- return SECSuccess;
- }
- /*
- * If we have a whole block available, encrypt it.
- */
- if ((padsize == 0) || (pcount % padsize) == 0) {
- rv = (* cc->doit) (cc->cx, output, &ofraglen, max_output_len,
- pbuf, pcount);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then sec_PKCS7EncryptLength needs to be made smarter!
- */
- PORT_Assert (ofraglen == pcount);
-
- /*
- * Account for the bytes now in output.
- */
- max_output_len -= ofraglen;
- output_len += ofraglen;
- output += ofraglen;
-
- pcount = 0;
- }
- }
-
- if (input_len) {
- PORT_Assert (pcount == 0);
-
- blocks = input_len / bsize;
- ifraglen = blocks * bsize;
-
- if (ifraglen) {
- rv = (* cc->doit) (cc->cx, output, &ofraglen, max_output_len,
- input, ifraglen);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then sec_PKCS7EncryptLength needs to be made smarter!
- */
- PORT_Assert (ifraglen == ofraglen);
-
- max_output_len -= ofraglen;
- output_len += ofraglen;
- output += ofraglen;
- }
-
- pcount = input_len - ifraglen;
- PORT_Assert (pcount < bsize);
- if (pcount)
- PORT_Memcpy (pbuf, input + ifraglen, pcount);
- }
-
- if (final) {
- padlen = padsize - (pcount % padsize);
- PORT_Memset (pbuf + pcount, padlen, padlen);
- rv = (* cc->doit) (cc->cx, output, &ofraglen, max_output_len,
- pbuf, pcount+padlen);
- if (rv != SECSuccess)
- return rv;
-
- /*
- * For now anyway, all of our ciphers have the same number of
- * bytes of output as they do input. If this ever becomes untrue,
- * then sec_PKCS7EncryptLength needs to be made smarter!
- */
- PORT_Assert (ofraglen == (pcount+padlen));
- output_len += ofraglen;
- } else {
- cc->pending_count = pcount;
- }
-
- PORT_Assert (output_len_p != NULL || output_len == 0);
- if (output_len_p != NULL)
- *output_len_p = output_len;
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/smime/cmsdecode.c b/security/nss/lib/smime/cmsdecode.c
deleted file mode 100644
index b4f85eaa7..000000000
--- a/security/nss/lib/smime/cmsdecode.c
+++ /dev/null
@@ -1,741 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS decoding.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "prtime.h"
-#include "secerr.h"
-
-struct NSSCMSDecoderContextStr {
- SEC_ASN1DecoderContext * dcx; /* ASN.1 decoder context */
- NSSCMSMessage * cmsg; /* backpointer to the root message */
- SECOidTag type; /* type of message */
- NSSCMSContent content; /* pointer to message */
- NSSCMSDecoderContext * childp7dcx; /* inner CMS decoder context */
- PRBool saw_contents;
- int error;
- NSSCMSContentCallback cb;
- void * cb_arg;
- PRBool first_decoded;
- PRBool need_indefinite_finish;
-};
-
-struct NSSCMSDecoderDataStr {
- SECItem data; /* must be first */
- unsigned int totalBufferSize;
-};
-
-typedef struct NSSCMSDecoderDataStr NSSCMSDecoderData;
-
-static void nss_cms_decoder_update_filter (void *arg, const char *data,
- unsigned long len, int depth, SEC_ASN1EncodingPart data_kind);
-static SECStatus nss_cms_before_data(NSSCMSDecoderContext *p7dcx);
-static SECStatus nss_cms_after_data(NSSCMSDecoderContext *p7dcx);
-static SECStatus nss_cms_after_end(NSSCMSDecoderContext *p7dcx);
-static void nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
- const unsigned char *data, unsigned long len, PRBool final);
-static NSSCMSDecoderData *nss_cms_create_decoder_data(PRArenaPool *poolp);
-
-extern const SEC_ASN1Template NSSCMSMessageTemplate[];
-
-static NSSCMSDecoderData *
-nss_cms_create_decoder_data(PRArenaPool *poolp)
-{
- NSSCMSDecoderData *decoderData = NULL;
-
- decoderData = (NSSCMSDecoderData *)
- PORT_ArenaAlloc(poolp,sizeof(NSSCMSDecoderData));
- if (!decoderData) {
- return NULL;
- }
- decoderData->data.data = NULL;
- decoderData->data.len = 0;
- decoderData->totalBufferSize = 0;
- return decoderData;
-}
-
-/*
- * nss_cms_decoder_notify -
- * this is the driver of the decoding process. It gets called by the ASN.1
- * decoder before and after an object is decoded.
- * at various points in the decoding process, we intercept to set up and do
- * further processing.
- */
-static void
-nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth)
-{
- NSSCMSDecoderContext *p7dcx;
- NSSCMSContentInfo *rootcinfo, *cinfo;
- PRBool after = !before;
-
- p7dcx = (NSSCMSDecoderContext *)arg;
- rootcinfo = &(p7dcx->cmsg->contentInfo);
-
- /* XXX error handling: need to set p7dcx->error */
-
-#ifdef CMSDEBUG
- fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" : "after", dest, depth);
-#endif
-
- /* so what are we working on right now? */
- if (p7dcx->type == SEC_OID_UNKNOWN) {
- /*
- * right now, we are still decoding the OUTER (root) cinfo
- * As soon as we know the inner content type, set up the info,
- * but NO inner decoder or filter. The root decoder handles the first
- * level children by itself - only for encapsulated contents (which
- * are encoded as DER inside of an OCTET STRING) we need to set up a
- * child decoder...
- */
- if (after && dest == &(rootcinfo->contentType)) {
- p7dcx->type = NSS_CMSContentInfo_GetContentTypeTag(rootcinfo);
- p7dcx->content = rootcinfo->content;
- /* is this ready already ? need to alloc? */
- /* XXX yes we need to alloc -- continue here */
- }
- } else if (NSS_CMSType_IsData(p7dcx->type)) {
- /* this can only happen if the outermost cinfo has DATA in it */
- /* otherwise, we handle this type implicitely in the inner decoders */
-
- if (before && dest == &(rootcinfo->content)) {
- /* cause the filter to put the data in the right place...
- ** We want the ASN.1 decoder to deliver the decoded bytes to us
- ** from now on
- */
- SEC_ASN1DecoderSetFilterProc(p7dcx->dcx,
- nss_cms_decoder_update_filter,
- p7dcx,
- (PRBool)(p7dcx->cb != NULL));
- } else if (after && dest == &(rootcinfo->content.data)) {
- /* remove the filter */
- SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
- }
- } else if (NSS_CMSType_IsWrapper(p7dcx->type)) {
- if (!before || dest != &(rootcinfo->content)) {
-
- if (p7dcx->content.pointer == NULL)
- p7dcx->content = rootcinfo->content;
-
- /* get this data type's inner contentInfo */
- cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer,
- p7dcx->type);
-
- if (before && dest == &(cinfo->contentType)) {
- /* at this point, set up the &%$&$ back pointer */
- /* we cannot do it later, because the content itself
- * is optional! */
- switch (p7dcx->type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- p7dcx->content.signedData->cmsg = p7dcx->cmsg;
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- p7dcx->content.digestedData->cmsg = p7dcx->cmsg;
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- p7dcx->content.envelopedData->cmsg = p7dcx->cmsg;
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- p7dcx->content.encryptedData->cmsg = p7dcx->cmsg;
- break;
- default:
- p7dcx->content.genericData->cmsg = p7dcx->cmsg;
- break;
- }
- }
-
- if (before && dest == &(cinfo->rawContent)) {
- /* we want the ASN.1 decoder to deliver the decoded bytes to us
- ** from now on
- */
- SEC_ASN1DecoderSetFilterProc(p7dcx->dcx,
- nss_cms_decoder_update_filter,
- p7dcx, (PRBool)(p7dcx->cb != NULL));
-
-
- /* we're right in front of the data */
- if (nss_cms_before_data(p7dcx) != SECSuccess) {
- SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
- /* stop all processing */
- p7dcx->error = PORT_GetError();
- }
- }
- if (after && dest == &(cinfo->rawContent)) {
- /* we're right after of the data */
- if (nss_cms_after_data(p7dcx) != SECSuccess)
- p7dcx->error = PORT_GetError();
-
- /* we don't need to see the contents anymore */
- SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
- }
- }
- } else {
- /* unsupported or unknown message type - fail gracefully */
- p7dcx->error = SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE;
- }
-}
-
-/*
- * nss_cms_before_data - set up the current encoder to receive data
- */
-static SECStatus
-nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
-{
- SECStatus rv;
- SECOidTag childtype;
- PLArenaPool *poolp;
- NSSCMSDecoderContext *childp7dcx;
- NSSCMSContentInfo *cinfo;
- const SEC_ASN1Template *template;
- void *mark = NULL;
- size_t size;
-
- poolp = p7dcx->cmsg->poolp;
-
- /* call _Decode_BeforeData handlers */
- switch (p7dcx->type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- /* we're decoding a signedData, so set up the digests */
- rv = NSS_CMSSignedData_Decode_BeforeData(p7dcx->content.signedData);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- /* we're encoding a digestedData, so set up the digest */
- rv = NSS_CMSDigestedData_Decode_BeforeData(p7dcx->content.digestedData);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- rv = NSS_CMSEnvelopedData_Decode_BeforeData(
- p7dcx->content.envelopedData);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- rv = NSS_CMSEncryptedData_Decode_BeforeData(
- p7dcx->content.encryptedData);
- break;
- default:
- rv = NSS_CMSGenericWrapperData_Decode_BeforeData(p7dcx->type,
- p7dcx->content.genericData);
- }
- if (rv != SECSuccess)
- return SECFailure;
-
- /* ok, now we have a pointer to cinfo */
- /* find out what kind of data is encapsulated */
-
- cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, p7dcx->type);
- childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
-
- if (NSS_CMSType_IsData(childtype)) {
- cinfo->content.pointer = (void *) nss_cms_create_decoder_data(poolp);
- if (cinfo->content.pointer == NULL)
- /* set memory error */
- return SECFailure;
-
- p7dcx->childp7dcx = NULL;
- return SECSuccess;
- }
-
- /* set up inner decoder */
-
- if ((template = NSS_CMSUtil_GetTemplateByTypeTag(childtype)) == NULL)
- return SECFailure;
-
- childp7dcx = PORT_ZNew(NSSCMSDecoderContext);
- if (childp7dcx == NULL)
- return SECFailure;
-
- mark = PORT_ArenaMark(poolp);
-
- /* allocate space for the stuff we're creating */
- size = NSS_CMSUtil_GetSizeByTypeTag(childtype);
- childp7dcx->content.pointer = (void *)PORT_ArenaZAlloc(poolp, size);
- if (childp7dcx->content.pointer == NULL)
- goto loser;
-
- /* give the parent a copy of the pointer so that it doesn't get lost */
- cinfo->content.pointer = childp7dcx->content.pointer;
-
- /* start the child decoder */
- childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer,
- template);
- if (childp7dcx->dcx == NULL)
- goto loser;
-
- /* the new decoder needs to notify, too */
- SEC_ASN1DecoderSetNotifyProc(childp7dcx->dcx, nss_cms_decoder_notify,
- childp7dcx);
-
- /* tell the parent decoder that it needs to feed us the content data */
- p7dcx->childp7dcx = childp7dcx;
-
- childp7dcx->type = childtype; /* our type */
-
- childp7dcx->cmsg = p7dcx->cmsg; /* backpointer to root message */
-
- /* should the child decoder encounter real data,
- ** it must give it to the caller
- */
- childp7dcx->cb = p7dcx->cb;
- childp7dcx->cb_arg = p7dcx->cb_arg;
- childp7dcx->first_decoded = PR_FALSE;
- childp7dcx->need_indefinite_finish = PR_FALSE;
- if (childtype == SEC_OID_PKCS7_SIGNED_DATA) {
- childp7dcx->first_decoded = PR_TRUE;
- }
-
- /* now set up the parent to hand decoded data to the next level decoder */
- p7dcx->cb = (NSSCMSContentCallback)NSS_CMSDecoder_Update;
- p7dcx->cb_arg = childp7dcx;
-
- PORT_ArenaUnmark(poolp, mark);
-
- return SECSuccess;
-
-loser:
- if (mark)
- PORT_ArenaRelease(poolp, mark);
- if (childp7dcx)
- PORT_Free(childp7dcx);
- p7dcx->childp7dcx = NULL;
- return SECFailure;
-}
-
-static SECStatus
-nss_cms_after_data(NSSCMSDecoderContext *p7dcx)
-{
- NSSCMSDecoderContext *childp7dcx;
- SECStatus rv = SECFailure;
-
- /* Handle last block. This is necessary to flush out the last bytes
- * of a possibly incomplete block */
- nss_cms_decoder_work_data(p7dcx, NULL, 0, PR_TRUE);
-
- /* finish any "inner" decoders - there's no more data coming... */
- if (p7dcx->childp7dcx != NULL) {
- childp7dcx = p7dcx->childp7dcx;
- if (childp7dcx->dcx != NULL) {
- /* we started and indefinite sequence somewhere, not complete it */
- if (childp7dcx->need_indefinite_finish) {
- static const char lbuf[2] = { 0, 0 };
- NSS_CMSDecoder_Update(childp7dcx, lbuf, sizeof(lbuf));
- childp7dcx->need_indefinite_finish = PR_FALSE;
- }
-
- if (SEC_ASN1DecoderFinish(childp7dcx->dcx) != SECSuccess) {
- /* do what? free content? */
- rv = SECFailure;
- } else {
- rv = nss_cms_after_end(childp7dcx);
- }
- if (rv != SECSuccess)
- goto done;
- }
- PORT_Free(p7dcx->childp7dcx);
- p7dcx->childp7dcx = NULL;
- }
-
- switch (p7dcx->type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- /* this will finish the digests and verify */
- rv = NSS_CMSSignedData_Decode_AfterData(p7dcx->content.signedData);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- rv = NSS_CMSEnvelopedData_Decode_AfterData(
- p7dcx->content.envelopedData);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- rv = NSS_CMSDigestedData_Decode_AfterData(
- p7dcx->content.digestedData);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- rv = NSS_CMSEncryptedData_Decode_AfterData(
- p7dcx->content.encryptedData);
- break;
- case SEC_OID_PKCS7_DATA:
- /* do nothing */
- break;
- default:
- rv = NSS_CMSGenericWrapperData_Decode_AfterData(p7dcx->type,
- p7dcx->content.genericData);
- break;
- }
-done:
- return rv;
-}
-
-static SECStatus
-nss_cms_after_end(NSSCMSDecoderContext *p7dcx)
-{
- SECStatus rv = SECSuccess;
-
- switch (p7dcx->type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- if (p7dcx->content.signedData)
- rv = NSS_CMSSignedData_Decode_AfterEnd(p7dcx->content.signedData);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- if (p7dcx->content.envelopedData)
- rv = NSS_CMSEnvelopedData_Decode_AfterEnd(
- p7dcx->content.envelopedData);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- if (p7dcx->content.digestedData)
- rv = NSS_CMSDigestedData_Decode_AfterEnd(
- p7dcx->content.digestedData);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- if (p7dcx->content.encryptedData)
- rv = NSS_CMSEncryptedData_Decode_AfterEnd(
- p7dcx->content.encryptedData);
- break;
- case SEC_OID_PKCS7_DATA:
- break;
- default:
- rv = NSS_CMSGenericWrapperData_Decode_AfterEnd(p7dcx->type,
- p7dcx->content.genericData);
- break;
- }
- return rv;
-}
-
-/*
- * nss_cms_decoder_work_data - handle decoded data bytes.
- *
- * This function either decrypts the data if needed, and/or calculates digests
- * on it, then either stores it or passes it on to the next level decoder.
- */
-static void
-nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
- const unsigned char *data, unsigned long len,
- PRBool final)
-{
- NSSCMSContentInfo *cinfo;
- unsigned char *buf = NULL;
- unsigned char *dest;
- unsigned int offset;
- SECStatus rv;
-
- /*
- * We should really have data to process, or we should be trying
- * to finish/flush the last block. (This is an overly paranoid
- * check since all callers are in this file and simple inspection
- * proves they do it right. But it could find a bug in future
- * modifications/development, that is why it is here.)
- */
- PORT_Assert ((data != NULL && len) || final);
-
- cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, p7dcx->type);
- if (!cinfo) {
- /* The original programmer didn't expect this to happen */
- p7dcx->error = SEC_ERROR_LIBRARY_FAILURE;
- goto loser;
- }
-
- if (cinfo->privateInfo && cinfo->privateInfo->ciphcx != NULL) {
- /*
- * we are decrypting.
- *
- * XXX If we get an error, we do not want to do the digest or callback,
- * but we want to keep decoding. Or maybe we want to stop decoding
- * altogether if there is a callback, because obviously we are not
- * sending the data back and they want to know that.
- */
-
- unsigned int outlen = 0; /* length of decrypted data */
- unsigned int buflen; /* length available for decrypted data */
-
- /* find out about the length of decrypted data */
- buflen = NSS_CMSCipherContext_DecryptLength(cinfo->privateInfo->ciphcx, len, final);
-
- /*
- * it might happen that we did not provide enough data for a full
- * block (decryption unit), and that there is no output available
- */
-
- /* no output available, AND no input? */
- if (buflen == 0 && len == 0)
- goto loser; /* bail out */
-
- /*
- * have inner decoder: pass the data on (means inner content type is NOT data)
- * no inner decoder: we have DATA in here: either call callback or store
- */
- if (buflen != 0) {
- /* there will be some output - need to make room for it */
- /* allocate buffer from the heap */
- buf = (unsigned char *)PORT_Alloc(buflen);
- if (buf == NULL) {
- p7dcx->error = SEC_ERROR_NO_MEMORY;
- goto loser;
- }
- }
-
- /*
- * decrypt incoming data
- * buf can still be NULL here (and buflen == 0) here if we don't expect
- * any output (see above), but we still need to call NSS_CMSCipherContext_Decrypt to
- * keep track of incoming data
- */
- rv = NSS_CMSCipherContext_Decrypt(cinfo->privateInfo->ciphcx, buf, &outlen, buflen,
- data, len, final);
- if (rv != SECSuccess) {
- p7dcx->error = PORT_GetError();
- goto loser;
- }
-
- PORT_Assert (final || outlen == buflen);
-
- /* swap decrypted data in */
- data = buf;
- len = outlen;
- }
-
- if (len == 0)
- goto done; /* nothing more to do */
-
- /*
- * Update the running digests with plaintext bytes (if we need to).
- */
- if (cinfo->privateInfo && cinfo->privateInfo->digcx)
- NSS_CMSDigestContext_Update(cinfo->privateInfo->digcx, data, len);
-
- /* at this point, we have the plain decoded & decrypted data
- ** which is either more encoded DER (which we need to hand to the child
- ** decoder) or data we need to hand back to our caller
- */
-
- /* pass the content back to our caller or */
- /* feed our freshly decrypted and decoded data into child decoder */
- if (p7dcx->cb != NULL) {
- (*p7dcx->cb)(p7dcx->cb_arg, (const char *)data, len);
- }
-#if 1
- else
-#endif
- if (NSS_CMSContentInfo_GetContentTypeTag(cinfo) == SEC_OID_PKCS7_DATA) {
- /* store it in "inner" data item as well */
- /* find the DATA item in the encapsulated cinfo and store it there */
- NSSCMSDecoderData *decoderData =
- (NSSCMSDecoderData *)cinfo->content.pointer;
- SECItem *dataItem = &decoderData->data;
-
- offset = dataItem->len;
- if (dataItem->len+len > decoderData->totalBufferSize) {
- int needLen = (dataItem->len+len) * 2;
- dest = (unsigned char *)
- PORT_ArenaAlloc(p7dcx->cmsg->poolp, needLen);
- if (dest == NULL) {
- p7dcx->error = SEC_ERROR_NO_MEMORY;
- goto loser;
- }
-
- if (dataItem->len) {
- PORT_Memcpy(dest, dataItem->data, dataItem->len);
- }
- decoderData->totalBufferSize = needLen;
- dataItem->data = dest;
- }
-
- /* copy it in */
- PORT_Memcpy(dataItem->data + offset, data, len);
- dataItem->len += len;
- }
-
-done:
-loser:
- if (buf)
- PORT_Free (buf);
-}
-
-/*
- * nss_cms_decoder_update_filter - process ASN.1 data
- *
- * once we have set up a filter in nss_cms_decoder_notify(),
- * all data processed by the ASN.1 decoder is also passed through here.
- * we pass the content bytes (as opposed to length and tag bytes) on to
- * nss_cms_decoder_work_data().
- */
-static void
-nss_cms_decoder_update_filter (void *arg, const char *data, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
-{
- NSSCMSDecoderContext *p7dcx;
-
- PORT_Assert (len); /* paranoia */
- if (len == 0)
- return;
-
- p7dcx = (NSSCMSDecoderContext*)arg;
-
- p7dcx->saw_contents = PR_TRUE;
-
- /* pass on the content bytes only */
- if (data_kind == SEC_ASN1_Contents)
- nss_cms_decoder_work_data(p7dcx, (const unsigned char *) data, len,
- PR_FALSE);
-}
-
-/*
- * NSS_CMSDecoder_Start - set up decoding of a DER-encoded CMS message
- *
- * "poolp" - pointer to arena for message, or NULL if new pool should be created
- * "cb", "cb_arg" - callback function and argument for delivery of inner content
- * "pwfn", pwfn_arg" - callback function for getting token password
- * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
- */
-NSSCMSDecoderContext *
-NSS_CMSDecoder_Start(PRArenaPool *poolp,
- NSSCMSContentCallback cb, void *cb_arg,
- PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb,
- void *decrypt_key_cb_arg)
-{
- NSSCMSDecoderContext *p7dcx;
- NSSCMSMessage *cmsg;
-
- cmsg = NSS_CMSMessage_Create(poolp);
- if (cmsg == NULL)
- return NULL;
-
- NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb,
- decrypt_key_cb_arg, NULL, NULL);
-
- p7dcx = PORT_ZNew(NSSCMSDecoderContext);
- if (p7dcx == NULL) {
- NSS_CMSMessage_Destroy(cmsg);
- return NULL;
- }
-
- p7dcx->dcx = SEC_ASN1DecoderStart(cmsg->poolp, cmsg, NSSCMSMessageTemplate);
- if (p7dcx->dcx == NULL) {
- PORT_Free (p7dcx);
- NSS_CMSMessage_Destroy(cmsg);
- return NULL;
- }
-
- SEC_ASN1DecoderSetNotifyProc (p7dcx->dcx, nss_cms_decoder_notify, p7dcx);
-
- p7dcx->cmsg = cmsg;
- p7dcx->type = SEC_OID_UNKNOWN;
-
- p7dcx->cb = cb;
- p7dcx->cb_arg = cb_arg;
- p7dcx->first_decoded = PR_FALSE;
- p7dcx->need_indefinite_finish = PR_FALSE;
- return p7dcx;
-}
-
-/*
- * NSS_CMSDecoder_Update - feed DER-encoded data to decoder
- */
-SECStatus
-NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf,
- unsigned long len)
-{
- SECStatus rv = SECSuccess;
- if (p7dcx->dcx != NULL && p7dcx->error == 0) {
- /* if error is set already, don't bother */
- if ((p7dcx->type == SEC_OID_PKCS7_SIGNED_DATA)
- && (p7dcx->first_decoded==PR_TRUE)
- && (buf[0] == SEC_ASN1_INTEGER)) {
- /* Microsoft Windows 2008 left out the Sequence wrapping in some
- * of their kerberos replies. If we are here, we most likely are
- * dealing with one of those replies. Supply the Sequence wrap
- * as indefinite encoding (since we don't know the total length
- * yet) */
- static const char lbuf[2] =
- { SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED, 0x80 };
- rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, lbuf, sizeof(lbuf));
- if (rv != SECSuccess) {
- goto loser;
- }
- /* ok, we're going to need the indefinite finish when we are done */
- p7dcx->need_indefinite_finish = PR_TRUE;
- }
-
- rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, buf, len);
- }
-
-loser:
- p7dcx->first_decoded = PR_FALSE;
- if (rv != SECSuccess) {
- p7dcx->error = PORT_GetError();
- PORT_Assert (p7dcx->error);
- if (p7dcx->error == 0)
- p7dcx->error = -1;
- }
-
- if (p7dcx->error == 0)
- return SECSuccess;
-
- /* there has been a problem, let's finish the decoder */
- if (p7dcx->dcx != NULL) {
- (void) SEC_ASN1DecoderFinish (p7dcx->dcx);
- p7dcx->dcx = NULL;
- }
- PORT_SetError (p7dcx->error);
-
- return SECFailure;
-}
-
-/*
- * NSS_CMSDecoder_Cancel - stop decoding in case of error
- */
-void
-NSS_CMSDecoder_Cancel(NSSCMSDecoderContext *p7dcx)
-{
- if (p7dcx->dcx != NULL)
- (void)SEC_ASN1DecoderFinish(p7dcx->dcx);
- NSS_CMSMessage_Destroy(p7dcx->cmsg);
- PORT_Free(p7dcx);
-}
-
-/*
- * NSS_CMSDecoder_Finish - mark the end of inner content and finish decoding
- */
-NSSCMSMessage *
-NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx)
-{
- NSSCMSMessage *cmsg;
-
- cmsg = p7dcx->cmsg;
-
- if (p7dcx->dcx == NULL ||
- SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess ||
- nss_cms_after_end(p7dcx) != SECSuccess)
- {
- NSS_CMSMessage_Destroy(cmsg); /* get rid of pool if it's ours */
- cmsg = NULL;
- }
-
- PORT_Free(p7dcx);
- return cmsg;
-}
-
-NSSCMSMessage *
-NSS_CMSMessage_CreateFromDER(SECItem *DERmessage,
- NSSCMSContentCallback cb, void *cb_arg,
- PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb,
- void *decrypt_key_cb_arg)
-{
- NSSCMSDecoderContext *p7dcx;
-
- /* first arg(poolp) == NULL => create our own pool */
- p7dcx = NSS_CMSDecoder_Start(NULL, cb, cb_arg, pwfn, pwfn_arg,
- decrypt_key_cb, decrypt_key_cb_arg);
- if (p7dcx == NULL)
- return NULL;
- NSS_CMSDecoder_Update(p7dcx, (char *)DERmessage->data, DERmessage->len);
- return NSS_CMSDecoder_Finish(p7dcx);
-}
-
diff --git a/security/nss/lib/smime/cmsdigdata.c b/security/nss/lib/smime/cmsdigdata.c
deleted file mode 100644
index 4b759bc0d..000000000
--- a/security/nss/lib/smime/cmsdigdata.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS digestedData methods.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "secitem.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "secerr.h"
-
-/*
- * NSS_CMSDigestedData_Create - create a digestedData object (presumably for encoding)
- *
- * version will be set by NSS_CMSDigestedData_Encode_BeforeStart
- * digestAlg is passed as parameter
- * contentInfo must be filled by the user
- * digest will be calculated while encoding
- */
-NSSCMSDigestedData *
-NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg)
-{
- void *mark;
- NSSCMSDigestedData *digd;
- PLArenaPool *poolp;
-
- poolp = cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData));
- if (digd == NULL)
- goto loser;
-
- digd->cmsg = cmsg;
-
- if (SECOID_CopyAlgorithmID (poolp, &(digd->digestAlg), digestalg) != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark(poolp, mark);
- return digd;
-
-loser:
- PORT_ArenaRelease(poolp, mark);
- return NULL;
-}
-
-/*
- * NSS_CMSDigestedData_Destroy - destroy a digestedData object
- */
-void
-NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd)
-{
- /* everything's in a pool, so don't worry about the storage */
- NSS_CMSContentInfo_Destroy(&(digd->contentInfo));
- return;
-}
-
-/*
- * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo
- */
-NSSCMSContentInfo *
-NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd)
-{
- return &(digd->contentInfo);
-}
-
-/*
- * NSS_CMSDigestedData_Encode_BeforeStart - do all the necessary things to a DigestedData
- * before encoding begins.
- *
- * In particular:
- * - set the right version number. The contentInfo's content type must be set up already.
- */
-SECStatus
-NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd)
-{
- unsigned long version;
- SECItem *dummy;
-
- version = NSS_CMS_DIGESTED_DATA_VERSION_DATA;
- if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag(
- &(digd->contentInfo))))
- version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP;
-
- dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version);
- return (dummy == NULL) ? SECFailure : SECSuccess;
-}
-
-/*
- * NSS_CMSDigestedData_Encode_BeforeData - do all the necessary things to a DigestedData
- * before the encapsulated data is passed through the encoder.
- *
- * In detail:
- * - set up the digests if necessary
- */
-SECStatus
-NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd)
-{
- SECStatus rv =NSS_CMSContentInfo_Private_Init(&digd->contentInfo);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
- /* set up the digests */
- if (digd->digestAlg.algorithm.len != 0 && digd->digest.len == 0) {
- /* if digest is already there, do nothing */
- digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg));
- if (digd->contentInfo.privateInfo->digcx == NULL)
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * NSS_CMSDigestedData_Encode_AfterData - do all the necessary things to a DigestedData
- * after all the encapsulated data was passed through the encoder.
- *
- * In detail:
- * - finish the digests
- */
-SECStatus
-NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd)
-{
- SECStatus rv = SECSuccess;
- /* did we have digest calculation going on? */
- if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) {
- rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx,
- digd->cmsg->poolp,
- &(digd->digest));
- /* error has been set by NSS_CMSDigestContext_FinishSingle */
- digd->contentInfo.privateInfo->digcx = NULL;
- }
-
- return rv;
-}
-
-/*
- * NSS_CMSDigestedData_Decode_BeforeData - do all the necessary things to a DigestedData
- * before the encapsulated data is passed through the encoder.
- *
- * In detail:
- * - set up the digests if necessary
- */
-SECStatus
-NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd)
-{
- SECStatus rv;
-
- /* is there a digest algorithm yet? */
- if (digd->digestAlg.algorithm.len == 0)
- return SECFailure;
-
- rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
- digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg));
- if (digd->contentInfo.privateInfo->digcx == NULL)
- return SECFailure;
-
- return SECSuccess;
-}
-
-/*
- * NSS_CMSDigestedData_Decode_AfterData - do all the necessary things to a DigestedData
- * after all the encapsulated data was passed through the encoder.
- *
- * In detail:
- * - finish the digests
- */
-SECStatus
-NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd)
-{
- SECStatus rv = SECSuccess;
- /* did we have digest calculation going on? */
- if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) {
- rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx,
- digd->cmsg->poolp,
- &(digd->cdigest));
- /* error has been set by NSS_CMSDigestContext_FinishSingle */
- digd->contentInfo.privateInfo->digcx = NULL;
- }
-
- return rv;
-}
-
-/*
- * NSS_CMSDigestedData_Decode_AfterEnd - finalize a digestedData.
- *
- * In detail:
- * - check the digests for equality
- */
-SECStatus
-NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData *digd)
-{
- /* did we have digest calculation going on? */
- if (digd->cdigest.len != 0) {
- /* XXX comparision btw digest & cdigest */
- /* XXX set status */
- /* TODO!!!! */
- }
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/smime/cmsdigest.c b/security/nss/lib/smime/cmsdigest.c
deleted file mode 100644
index db312c9e9..000000000
--- a/security/nss/lib/smime/cmsdigest.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS digesting.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "prtime.h"
-#include "secerr.h"
-
-/* #define CMS_FIND_LEAK_MULTIPLE 1 */
-#ifdef CMS_FIND_LEAK_MULTIPLE
-static int stop_on_err = 1;
-static int global_num_digests = 0;
-#endif
-
-struct digestPairStr {
- const SECHashObject * digobj;
- void * digcx;
-};
-typedef struct digestPairStr digestPair;
-
-struct NSSCMSDigestContextStr {
- PRBool saw_contents;
- PLArenaPool * pool;
- int digcnt;
- digestPair * digPairs;
-};
-
-
-/*
- * NSS_CMSDigestContext_StartMultiple - start digest calculation using all the
- * digest algorithms in "digestalgs" in parallel.
- */
-NSSCMSDigestContext *
-NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs)
-{
- PLArenaPool * pool;
- NSSCMSDigestContext *cmsdigcx;
- int digcnt;
- int i;
-
-#ifdef CMS_FIND_LEAK_MULTIPLE
- PORT_Assert(global_num_digests == 0 || !stop_on_err);
-#endif
-
- digcnt = (digestalgs == NULL) ? 0 : NSS_CMSArray_Count((void **)digestalgs);
- /* It's OK if digcnt is zero. We have to allow this for "certs only"
- ** messages.
- */
- pool = PORT_NewArena(2048);
- if (!pool)
- return NULL;
-
- cmsdigcx = PORT_ArenaNew(pool, NSSCMSDigestContext);
- if (cmsdigcx == NULL)
- goto loser;
-
- cmsdigcx->saw_contents = PR_FALSE;
- cmsdigcx->pool = pool;
- cmsdigcx->digcnt = digcnt;
-
- cmsdigcx->digPairs = PORT_ArenaZNewArray(pool, digestPair, digcnt);
- if (cmsdigcx->digPairs == NULL) {
- goto loser;
- }
-
- /*
- * Create a digest object context for each algorithm.
- */
- for (i = 0; i < digcnt; i++) {
- const SECHashObject *digobj;
- void *digcx;
-
- digobj = NSS_CMSUtil_GetHashObjByAlgID(digestalgs[i]);
- /*
- * Skip any algorithm we do not even recognize; obviously,
- * this could be a problem, but if it is critical then the
- * result will just be that the signature does not verify.
- * We do not necessarily want to error out here, because
- * the particular algorithm may not actually be important,
- * but we cannot know that until later.
- */
- if (digobj == NULL)
- continue;
-
- digcx = (*digobj->create)();
- if (digcx != NULL) {
- (*digobj->begin) (digcx);
- cmsdigcx->digPairs[i].digobj = digobj;
- cmsdigcx->digPairs[i].digcx = digcx;
-#ifdef CMS_FIND_LEAK_MULTIPLE
- global_num_digests++;
-#endif
- }
- }
- return cmsdigcx;
-
-loser:
- /* no digest objects have been created, or need to be destroyed. */
- if (pool) {
- PORT_FreeArena(pool, PR_FALSE);
- }
- return NULL;
-}
-
-/*
- * NSS_CMSDigestContext_StartSingle - same as
- * NSS_CMSDigestContext_StartMultiple, but only one algorithm.
- */
-NSSCMSDigestContext *
-NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg)
-{
- SECAlgorithmID *digestalgs[] = { NULL, NULL }; /* fake array */
-
- digestalgs[0] = digestalg;
- return NSS_CMSDigestContext_StartMultiple(digestalgs);
-}
-
-/*
- * NSS_CMSDigestContext_Update - feed more data into the digest machine
- */
-void
-NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx,
- const unsigned char *data, int len)
-{
- int i;
- digestPair *pair = cmsdigcx->digPairs;
-
- cmsdigcx->saw_contents = PR_TRUE;
-
- for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
- if (pair->digcx) {
- (*pair->digobj->update)(pair->digcx, data, len);
- }
- }
-}
-
-/*
- * NSS_CMSDigestContext_Cancel - cancel digesting operation
- */
-void
-NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx)
-{
- int i;
- digestPair *pair = cmsdigcx->digPairs;
-
- for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
- if (pair->digcx) {
- (*pair->digobj->destroy)(pair->digcx, PR_TRUE);
-#ifdef CMS_FIND_LEAK_MULTIPLE
- --global_num_digests;
-#endif
- }
- }
-#ifdef CMS_FIND_LEAK_MULTIPLE
- PORT_Assert(global_num_digests == 0 || !stop_on_err);
-#endif
- PORT_FreeArena(cmsdigcx->pool, PR_FALSE);
-}
-
-/*
- * NSS_CMSDigestContext_FinishMultiple - finish the digests and put them
- * into an array of SECItems (allocated on poolp)
- */
-SECStatus
-NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx,
- PLArenaPool *poolp,
- SECItem ***digestsp)
-{
- SECItem ** digests = NULL;
- digestPair *pair;
- void * mark;
- int i;
- SECStatus rv;
-
- /* no contents? do not finish digests */
- if (digestsp == NULL || !cmsdigcx->saw_contents) {
- rv = SECSuccess;
- goto cleanup;
- }
-
- mark = PORT_ArenaMark (poolp);
-
- /* allocate digest array & SECItems on arena */
- digests = PORT_ArenaNewArray( poolp, SECItem *, cmsdigcx->digcnt + 1);
-
- rv = ((digests == NULL) ? SECFailure : SECSuccess);
- pair = cmsdigcx->digPairs;
- for (i = 0; rv == SECSuccess && i < cmsdigcx->digcnt; i++, pair++) {
- SECItem digest;
- unsigned char hash[HASH_LENGTH_MAX];
-
- if (!pair->digcx) {
- digests[i] = NULL;
- continue;
- }
-
- digest.type = siBuffer;
- digest.data = hash;
- digest.len = pair->digobj->length;
- (* pair->digobj->end)(pair->digcx, hash, &digest.len, digest.len);
- digests[i] = SECITEM_ArenaDupItem(poolp, &digest);
- if (!digests[i]) {
- rv = SECFailure;
- }
- }
- digests[i] = NULL;
- if (rv == SECSuccess) {
- PORT_ArenaUnmark(poolp, mark);
- } else
- PORT_ArenaRelease(poolp, mark);
-
-cleanup:
- NSS_CMSDigestContext_Cancel(cmsdigcx);
- /* Don't change the caller's digests pointer if we have no digests.
- ** NSS_CMSSignedData_Encode_AfterData depends on this behavior.
- */
- if (rv == SECSuccess && digestsp && digests) {
- *digestsp = digests;
- }
- return rv;
-}
-
-/*
- * NSS_CMSDigestContext_FinishSingle - same as
- * NSS_CMSDigestContext_FinishMultiple, but for one digest.
- */
-SECStatus
-NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx,
- PLArenaPool *poolp,
- SECItem *digest)
-{
- SECStatus rv = SECFailure;
- SECItem **dp;
- PLArenaPool *arena = NULL;
-
- if ((arena = PORT_NewArena(1024)) == NULL)
- goto loser;
-
- /* get the digests into arena, then copy the first digest into poolp */
- rv = NSS_CMSDigestContext_FinishMultiple(cmsdigcx, arena, &dp);
- if (rv == SECSuccess) {
- /* now copy it into poolp */
- rv = SECITEM_CopyItem(poolp, digest, dp[0]);
- }
-loser:
- if (arena)
- PORT_FreeArena(arena, PR_FALSE);
-
- return rv;
-}
diff --git a/security/nss/lib/smime/cmsencdata.c b/security/nss/lib/smime/cmsencdata.c
deleted file mode 100644
index f0668ea7e..000000000
--- a/security/nss/lib/smime/cmsencdata.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS encryptedData methods.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "prtime.h"
-#include "secerr.h"
-#include "secpkcs5.h"
-
-/*
- * NSS_CMSEncryptedData_Create - create an empty encryptedData object.
- *
- * "algorithm" specifies the bulk encryption algorithm to use.
- * "keysize" is the key size.
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-NSSCMSEncryptedData *
-NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm,
- int keysize)
-{
- void *mark;
- NSSCMSEncryptedData *encd;
- PLArenaPool *poolp;
- SECAlgorithmID *pbe_algid;
- SECStatus rv;
-
- poolp = cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- encd = PORT_ArenaZNew(poolp, NSSCMSEncryptedData);
- if (encd == NULL)
- goto loser;
-
- encd->cmsg = cmsg;
-
- /* version is set in NSS_CMSEncryptedData_Encode_BeforeStart() */
-
- if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm)) {
- rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(encd->contentInfo),
- algorithm, NULL, keysize);
- } else {
- /* Assume password-based-encryption.
- * Note: we can't generate pkcs5v2 from this interface.
- * PK11_CreateBPEAlgorithmID generates pkcs5v2 by accepting
- * non-PBE oids and assuming that they are pkcs5v2 oids, but
- * NSS_CMSEncryptedData_Create accepts non-PBE oids as regular
- * CMS encrypted data, so we can't tell NSS_CMS_EncryptedData_Create
- * to create pkcs5v2 PBEs */
- pbe_algid = PK11_CreatePBEAlgorithmID(algorithm, 1, NULL);
- if (pbe_algid == NULL) {
- rv = SECFailure;
- } else {
- rv = NSS_CMSContentInfo_SetContentEncAlgID(poolp,
- &(encd->contentInfo), pbe_algid, keysize);
- SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE);
- }
- }
- if (rv != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark(poolp, mark);
- return encd;
-
-loser:
- PORT_ArenaRelease(poolp, mark);
- return NULL;
-}
-
-/*
- * NSS_CMSEncryptedData_Destroy - destroy an encryptedData object
- */
-void
-NSS_CMSEncryptedData_Destroy(NSSCMSEncryptedData *encd)
-{
- /* everything's in a pool, so don't worry about the storage */
- NSS_CMSContentInfo_Destroy(&(encd->contentInfo));
- return;
-}
-
-/*
- * NSS_CMSEncryptedData_GetContentInfo - return pointer to encryptedData object's contentInfo
- */
-NSSCMSContentInfo *
-NSS_CMSEncryptedData_GetContentInfo(NSSCMSEncryptedData *encd)
-{
- return &(encd->contentInfo);
-}
-
-/*
- * NSS_CMSEncryptedData_Encode_BeforeStart - do all the necessary things to a EncryptedData
- * before encoding begins.
- *
- * In particular:
- * - set the correct version value.
- * - get the encryption key
- */
-SECStatus
-NSS_CMSEncryptedData_Encode_BeforeStart(NSSCMSEncryptedData *encd)
-{
- int version;
- PK11SymKey *bulkkey = NULL;
- SECItem *dummy;
- NSSCMSContentInfo *cinfo = &(encd->contentInfo);
-
- if (NSS_CMSArray_IsEmpty((void **)encd->unprotectedAttr))
- version = NSS_CMS_ENCRYPTED_DATA_VERSION;
- else
- version = NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR;
-
- dummy = SEC_ASN1EncodeInteger (encd->cmsg->poolp, &(encd->version), version);
- if (dummy == NULL)
- return SECFailure;
-
- /* now get content encryption key (bulk key) by using our cmsg callback */
- if (encd->cmsg->decrypt_key_cb)
- bulkkey = (*encd->cmsg->decrypt_key_cb)(encd->cmsg->decrypt_key_cb_arg,
- NSS_CMSContentInfo_GetContentEncAlg(cinfo));
- if (bulkkey == NULL)
- return SECFailure;
-
- /* store the bulk key in the contentInfo so that the encoder can find it */
- NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
- PK11_FreeSymKey (bulkkey);
-
- return SECSuccess;
-}
-
-/*
- * NSS_CMSEncryptedData_Encode_BeforeData - set up encryption
- */
-SECStatus
-NSS_CMSEncryptedData_Encode_BeforeData(NSSCMSEncryptedData *encd)
-{
- NSSCMSContentInfo *cinfo;
- PK11SymKey *bulkkey;
- SECAlgorithmID *algid;
- SECStatus rv;
-
- cinfo = &(encd->contentInfo);
-
- /* find bulkkey and algorithm - must have been set by NSS_CMSEncryptedData_Encode_BeforeStart */
- bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo);
- if (bulkkey == NULL)
- return SECFailure;
- algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
- if (algid == NULL)
- return SECFailure;
-
- rv = NSS_CMSContentInfo_Private_Init(cinfo);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* this may modify algid (with IVs generated in a token).
- * it is therefore essential that algid is a pointer to the "real" contentEncAlg,
- * not just to a copy */
- cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(encd->cmsg->poolp, bulkkey, algid);
- PK11_FreeSymKey(bulkkey);
- if (cinfo->privateInfo->ciphcx == NULL)
- return SECFailure;
-
- return SECSuccess;
-}
-
-/*
- * NSS_CMSEncryptedData_Encode_AfterData - finalize this encryptedData for encoding
- */
-SECStatus
-NSS_CMSEncryptedData_Encode_AfterData(NSSCMSEncryptedData *encd)
-{
- if (encd->contentInfo.privateInfo && encd->contentInfo.privateInfo->ciphcx) {
- NSS_CMSCipherContext_Destroy(encd->contentInfo.privateInfo->ciphcx);
- encd->contentInfo.privateInfo->ciphcx = NULL;
- }
-
- /* nothing to do after data */
- return SECSuccess;
-}
-
-
-/*
- * NSS_CMSEncryptedData_Decode_BeforeData - find bulk key & set up decryption
- */
-SECStatus
-NSS_CMSEncryptedData_Decode_BeforeData(NSSCMSEncryptedData *encd)
-{
- PK11SymKey *bulkkey = NULL;
- NSSCMSContentInfo *cinfo;
- SECAlgorithmID *bulkalg;
- SECStatus rv = SECFailure;
-
- cinfo = &(encd->contentInfo);
-
- bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
-
- if (encd->cmsg->decrypt_key_cb == NULL) /* no callback? no key../ */
- goto loser;
-
- bulkkey = (*encd->cmsg->decrypt_key_cb)(encd->cmsg->decrypt_key_cb_arg, bulkalg);
- if (bulkkey == NULL)
- /* no success finding a bulk key */
- goto loser;
-
- NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
-
- rv = NSS_CMSContentInfo_Private_Init(cinfo);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECFailure;
-
- cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg);
- if (cinfo->privateInfo->ciphcx == NULL)
- goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */
-
-
- /* we are done with (this) bulkkey now. */
- PK11_FreeSymKey(bulkkey);
-
- rv = SECSuccess;
-
-loser:
- return rv;
-}
-
-/*
- * NSS_CMSEncryptedData_Decode_AfterData - finish decrypting this encryptedData's content
- */
-SECStatus
-NSS_CMSEncryptedData_Decode_AfterData(NSSCMSEncryptedData *encd)
-{
- if (encd->contentInfo.privateInfo && encd->contentInfo.privateInfo->ciphcx) {
- NSS_CMSCipherContext_Destroy(encd->contentInfo.privateInfo->ciphcx);
- encd->contentInfo.privateInfo->ciphcx = NULL;
- }
-
- return SECSuccess;
-}
-
-/*
- * NSS_CMSEncryptedData_Decode_AfterEnd - finish decoding this encryptedData
- */
-SECStatus
-NSS_CMSEncryptedData_Decode_AfterEnd(NSSCMSEncryptedData *encd)
-{
- /* apply final touches */
- return SECSuccess;
-}
diff --git a/security/nss/lib/smime/cmsencode.c b/security/nss/lib/smime/cmsencode.c
deleted file mode 100644
index 1211d0ffa..000000000
--- a/security/nss/lib/smime/cmsencode.c
+++ /dev/null
@@ -1,750 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS encoding.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "pk11func.h"
-#include "secerr.h"
-
-struct nss_cms_encoder_output {
- NSSCMSContentCallback outputfn;
- void *outputarg;
- PLArenaPool *destpoolp;
- SECItem *dest;
-};
-
-struct NSSCMSEncoderContextStr {
- SEC_ASN1EncoderContext * ecx; /* ASN.1 encoder context */
- PRBool ecxupdated; /* true if data was handed in */
- NSSCMSMessage * cmsg; /* pointer to the root message */
- SECOidTag type; /* type tag of the current content */
- NSSCMSContent content; /* pointer to current content */
- struct nss_cms_encoder_output output; /* output function */
- int error; /* error code */
- NSSCMSEncoderContext * childp7ecx; /* link to child encoder context */
-};
-
-static SECStatus nss_cms_before_data(NSSCMSEncoderContext *p7ecx);
-static SECStatus nss_cms_after_data(NSSCMSEncoderContext *p7ecx);
-static SECStatus nss_cms_encoder_update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len);
-static SECStatus nss_cms_encoder_work_data(NSSCMSEncoderContext *p7ecx, SECItem *dest,
- const unsigned char *data, unsigned long len,
- PRBool final, PRBool innermost);
-
-extern const SEC_ASN1Template NSSCMSMessageTemplate[];
-
-/*
- * The little output function that the ASN.1 encoder calls to hand
- * us bytes which we in turn hand back to our caller (via the callback
- * they gave us).
- */
-static void
-nss_cms_encoder_out(void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
-{
- struct nss_cms_encoder_output *output = (struct nss_cms_encoder_output *)arg;
- unsigned char *dest;
- unsigned long offset;
-
-#ifdef CMSDEBUG
- int i;
- const char *data_name = "unknown";
-
- switch (data_kind) {
- case SEC_ASN1_Identifier:
- data_name = "identifier";
- break;
- case SEC_ASN1_Length:
- data_name = "length";
- break;
- case SEC_ASN1_Contents:
- data_name = "contents";
- break;
- case SEC_ASN1_EndOfContents:
- data_name = "end-of-contents";
- break;
- }
- fprintf(stderr, "kind = %s, depth = %d, len = %d\n", data_name, depth, len);
- for (i=0; i < len; i++) {
- fprintf(stderr, " %02x%s", (unsigned int)buf[i] & 0xff, ((i % 16) == 15) ? "\n" : "");
- }
- if ((i % 16) != 0)
- fprintf(stderr, "\n");
-#endif
-
- if (output->outputfn != NULL)
- /* call output callback with DER data */
- output->outputfn(output->outputarg, buf, len);
-
- if (output->dest != NULL) {
- /* store DER data in SECItem */
- offset = output->dest->len;
- if (offset == 0) {
- dest = (unsigned char *)PORT_ArenaAlloc(output->destpoolp, len);
- } else {
- dest = (unsigned char *)PORT_ArenaGrow(output->destpoolp,
- output->dest->data,
- output->dest->len,
- output->dest->len + len);
- }
- if (dest == NULL)
- /* oops */
- return;
-
- output->dest->data = dest;
- output->dest->len += len;
-
- /* copy it in */
- PORT_Memcpy(output->dest->data + offset, buf, len);
- }
-}
-
-/*
- * nss_cms_encoder_notify - ASN.1 encoder callback
- *
- * this function is called by the ASN.1 encoder before and after the encoding of
- * every object. here, it is used to keep track of data structures, set up
- * encryption and/or digesting and possibly set up child encoders.
- */
-static void
-nss_cms_encoder_notify(void *arg, PRBool before, void *dest, int depth)
-{
- NSSCMSEncoderContext *p7ecx;
- NSSCMSContentInfo *rootcinfo, *cinfo;
- PRBool after = !before;
- PLArenaPool *poolp;
- SECOidTag childtype;
- SECItem *item;
-
- p7ecx = (NSSCMSEncoderContext *)arg;
- PORT_Assert(p7ecx != NULL);
-
- rootcinfo = &(p7ecx->cmsg->contentInfo);
- poolp = p7ecx->cmsg->poolp;
-
-#ifdef CMSDEBUG
- fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" : "after", dest, depth);
-#endif
-
- /*
- * Watch for the content field, at which point we want to instruct
- * the ASN.1 encoder to start taking bytes from the buffer.
- */
- if (NSS_CMSType_IsData(p7ecx->type)) {
- cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
- if (before && dest == &(cinfo->rawContent)) {
- /* just set up encoder to grab from user - no encryption or digesting */
- if ((item = cinfo->content.data) != NULL)
- (void)nss_cms_encoder_work_data(p7ecx, NULL, item->data, item->len, PR_TRUE, PR_TRUE);
- else
- SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx);
- SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */
- }
- } else if (NSS_CMSType_IsWrapper(p7ecx->type)) {
- /* when we know what the content is, we encode happily until we reach the inner content */
- cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
- childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
-
- if (after && dest == &(cinfo->contentType)) {
- /* we're right before encoding the data (if we have some or not) */
- /* (for encrypted data, we're right before the contentEncAlg which may change */
- /* in nss_cms_before_data because of IV calculation when setting up encryption) */
- if (nss_cms_before_data(p7ecx) != SECSuccess)
- p7ecx->error = PORT_GetError();
- }
- if (before && dest == &(cinfo->rawContent)) {
- if (p7ecx->childp7ecx == NULL) {
- if ((NSS_CMSType_IsData(childtype) && (item = cinfo->content.data) != NULL)) {
- /* we are the innermost non-data and we have data - feed it in */
- (void)nss_cms_encoder_work_data(p7ecx, NULL, item->data, item->len, PR_TRUE, PR_TRUE);
- } else {
- /* else we'll have to get data from user */
- SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx);
- }
- } else {
- /* if we have a nested encoder, wait for its data */
- SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx);
- }
- }
- if (after && dest == &(cinfo->rawContent)) {
- if (nss_cms_after_data(p7ecx) != SECSuccess)
- p7ecx->error = PORT_GetError();
- SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */
- }
- } else {
- /* we're still in the root message */
- if (after && dest == &(rootcinfo->contentType)) {
- /* got the content type OID now - so find out the type tag */
- p7ecx->type = NSS_CMSContentInfo_GetContentTypeTag(rootcinfo);
- /* set up a pointer to our current content */
- p7ecx->content = rootcinfo->content;
- }
- }
-}
-
-/*
- * nss_cms_before_data - setup the current encoder to receive data
- */
-static SECStatus
-nss_cms_before_data(NSSCMSEncoderContext *p7ecx)
-{
- SECStatus rv;
- SECOidTag childtype;
- NSSCMSContentInfo *cinfo;
- PLArenaPool *poolp;
- NSSCMSEncoderContext *childp7ecx;
- const SEC_ASN1Template *template;
-
- poolp = p7ecx->cmsg->poolp;
-
- /* call _Encode_BeforeData handlers */
- switch (p7ecx->type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- /* we're encoding a signedData, so set up the digests */
- rv = NSS_CMSSignedData_Encode_BeforeData(p7ecx->content.signedData);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- /* we're encoding a digestedData, so set up the digest */
- rv = NSS_CMSDigestedData_Encode_BeforeData(p7ecx->content.digestedData);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- rv = NSS_CMSEnvelopedData_Encode_BeforeData(p7ecx->content.envelopedData);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- rv = NSS_CMSEncryptedData_Encode_BeforeData(p7ecx->content.encryptedData);
- break;
- default:
- if (NSS_CMSType_IsWrapper(p7ecx->type)) {
- rv = NSS_CMSGenericWrapperData_Encode_BeforeData(p7ecx->type, p7ecx->content.genericData);
- } else {
- rv = SECFailure;
- }
- }
- if (rv != SECSuccess)
- return SECFailure;
-
- /* ok, now we have a pointer to cinfo */
- /* find out what kind of data is encapsulated */
-
- cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
- childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
-
- if (NSS_CMSType_IsWrapper(childtype)) {
- /* in these cases, we need to set up a child encoder! */
- /* create new encoder context */
- childp7ecx = PORT_ZAlloc(sizeof(NSSCMSEncoderContext));
- if (childp7ecx == NULL)
- return SECFailure;
-
- /* the CHILD encoder needs to hand its encoded data to the CURRENT encoder
- * (which will encrypt and/or digest it)
- * this needs to route back into our update function
- * which finds the lowest encoding context & encrypts and computes digests */
- childp7ecx->type = childtype;
- childp7ecx->content = cinfo->content;
- /* use the non-recursive update function here, of course */
- childp7ecx->output.outputfn = (NSSCMSContentCallback)nss_cms_encoder_update;
- childp7ecx->output.outputarg = p7ecx;
- childp7ecx->output.destpoolp = NULL;
- childp7ecx->output.dest = NULL;
- childp7ecx->cmsg = p7ecx->cmsg;
- childp7ecx->ecxupdated = PR_FALSE;
- childp7ecx->childp7ecx = NULL;
-
- template = NSS_CMSUtil_GetTemplateByTypeTag(childtype);
- if (template == NULL)
- goto loser; /* cannot happen */
-
- /* now initialize the data for encoding the first third */
- switch (childp7ecx->type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- rv = NSS_CMSSignedData_Encode_BeforeStart(cinfo->content.signedData);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- rv = NSS_CMSEnvelopedData_Encode_BeforeStart(cinfo->content.envelopedData);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- rv = NSS_CMSDigestedData_Encode_BeforeStart(cinfo->content.digestedData);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- rv = NSS_CMSEncryptedData_Encode_BeforeStart(cinfo->content.encryptedData);
- break;
- default:
- rv = NSS_CMSGenericWrapperData_Encode_BeforeStart(childp7ecx->type, cinfo->content.genericData);
- break;
- }
- if (rv != SECSuccess)
- goto loser;
-
- /*
- * Initialize the BER encoder.
- */
- childp7ecx->ecx = SEC_ASN1EncoderStart(cinfo->content.pointer, template,
- nss_cms_encoder_out, &(childp7ecx->output));
- if (childp7ecx->ecx == NULL)
- goto loser;
-
- /*
- * Indicate that we are streaming. We will be streaming until we
- * get past the contents bytes.
- */
- if (!cinfo->privateInfo || !cinfo->privateInfo->dontStream)
- SEC_ASN1EncoderSetStreaming(childp7ecx->ecx);
-
- /*
- * The notify function will watch for the contents field.
- */
- p7ecx->childp7ecx = childp7ecx;
- SEC_ASN1EncoderSetNotifyProc(childp7ecx->ecx, nss_cms_encoder_notify, childp7ecx);
-
- /* please note that we are NOT calling SEC_ASN1EncoderUpdate here to kick off the */
- /* encoding process - we'll do that from the update function instead */
- /* otherwise we'd be encoding data from a call of the notify function of the */
- /* parent encoder (which would not work) */
-
- } else if (NSS_CMSType_IsData(childtype)) {
- p7ecx->childp7ecx = NULL;
- } else {
- /* we do not know this type */
- p7ecx->error = SEC_ERROR_BAD_DER;
- }
-
- return SECSuccess;
-
-loser:
- if (childp7ecx) {
- if (childp7ecx->ecx)
- SEC_ASN1EncoderFinish(childp7ecx->ecx);
- PORT_Free(childp7ecx);
- p7ecx->childp7ecx = NULL;
- }
- return SECFailure;
-}
-
-static SECStatus
-nss_cms_after_data(NSSCMSEncoderContext *p7ecx)
-{
- SECStatus rv = SECFailure;
-
- switch (p7ecx->type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- /* this will finish the digests and sign */
- rv = NSS_CMSSignedData_Encode_AfterData(p7ecx->content.signedData);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- rv = NSS_CMSEnvelopedData_Encode_AfterData(p7ecx->content.envelopedData);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- rv = NSS_CMSDigestedData_Encode_AfterData(p7ecx->content.digestedData);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- rv = NSS_CMSEncryptedData_Encode_AfterData(p7ecx->content.encryptedData);
- break;
- default:
- if (NSS_CMSType_IsWrapper(p7ecx->type)) {
- rv = NSS_CMSGenericWrapperData_Encode_AfterData(p7ecx->type, p7ecx->content.genericData);
- } else {
- rv = SECFailure;
- }
- break;
- }
- return rv;
-}
-
-/*
- * nss_cms_encoder_work_data - process incoming data
- *
- * (from the user or the next encoding layer)
- * Here, we need to digest and/or encrypt, then pass it on
- */
-static SECStatus
-nss_cms_encoder_work_data(NSSCMSEncoderContext *p7ecx, SECItem *dest,
- const unsigned char *data, unsigned long len,
- PRBool final, PRBool innermost)
-{
- unsigned char *buf = NULL;
- SECStatus rv;
- NSSCMSContentInfo *cinfo;
-
- rv = SECSuccess; /* may as well be optimistic */
-
- /*
- * We should really have data to process, or we should be trying
- * to finish/flush the last block. (This is an overly paranoid
- * check since all callers are in this file and simple inspection
- * proves they do it right. But it could find a bug in future
- * modifications/development, that is why it is here.)
- */
- PORT_Assert ((data != NULL && len) || final);
-
- /* we got data (either from the caller, or from a lower level encoder) */
- cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
- if (!cinfo) {
- /* The original programmer didn't expect this to happen */
- p7ecx->error = SEC_ERROR_LIBRARY_FAILURE;
- return SECFailure;
- }
-
- /* Update the running digest. */
- if (len && cinfo->privateInfo && cinfo->privateInfo->digcx != NULL)
- NSS_CMSDigestContext_Update(cinfo->privateInfo->digcx, data, len);
-
- /* Encrypt this chunk. */
- if (cinfo->privateInfo && cinfo->privateInfo->ciphcx != NULL) {
- unsigned int inlen; /* length of data being encrypted */
- unsigned int outlen; /* length of encrypted data */
- unsigned int buflen; /* length available for encrypted data */
-
- inlen = len;
- buflen = NSS_CMSCipherContext_EncryptLength(cinfo->privateInfo->ciphcx, inlen, final);
- if (buflen == 0) {
- /*
- * No output is expected, but the input data may be buffered
- * so we still have to call Encrypt.
- */
- rv = NSS_CMSCipherContext_Encrypt(cinfo->privateInfo->ciphcx, NULL, NULL, 0,
- data, inlen, final);
- if (final) {
- len = 0;
- goto done;
- }
- return rv;
- }
-
- if (dest != NULL)
- buf = (unsigned char*)PORT_ArenaAlloc(p7ecx->cmsg->poolp, buflen);
- else
- buf = (unsigned char*)PORT_Alloc(buflen);
-
- if (buf == NULL) {
- rv = SECFailure;
- } else {
- rv = NSS_CMSCipherContext_Encrypt(cinfo->privateInfo->ciphcx, buf, &outlen, buflen,
- data, inlen, final);
- data = buf;
- len = outlen;
- }
- if (rv != SECSuccess)
- /* encryption or malloc failed? */
- return rv;
- }
-
-
- /*
- * at this point (data,len) has everything we'd like to give to the CURRENT encoder
- * (which will encode it, then hand it back to the user or the parent encoder)
- * We don't encode the data if we're innermost and we're told not to include the data
- */
- if (p7ecx->ecx != NULL && len && (!innermost || cinfo->rawContent != cinfo->content.pointer))
- rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, (const char *)data, len);
-
-done:
-
- if (cinfo->privateInfo && cinfo->privateInfo->ciphcx != NULL) {
- if (dest != NULL) {
- dest->data = buf;
- dest->len = len;
- } else if (buf != NULL) {
- PORT_Free (buf);
- }
- }
- return rv;
-}
-
-/*
- * nss_cms_encoder_update - deliver encoded data to the next higher level
- *
- * no recursion here because we REALLY want to end up at the next higher encoder!
- */
-static SECStatus
-nss_cms_encoder_update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len)
-{
- /* XXX Error handling needs help. Return what? Do "Finish" on failure? */
- return nss_cms_encoder_work_data (p7ecx, NULL, (const unsigned char *)data, len, PR_FALSE, PR_FALSE);
-}
-
-/*
- * NSS_CMSEncoder_Start - set up encoding of a CMS message
- *
- * "cmsg" - message to encode
- * "outputfn", "outputarg" - callback function for delivery of DER-encoded output
- * will not be called if NULL.
- * "dest" - if non-NULL, pointer to SECItem that will hold the DER-encoded output
- * "destpoolp" - pool to allocate DER-encoded output in
- * "pwfn", pwfn_arg" - callback function for getting token password
- * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
- * "detached_digestalgs", "detached_digests" - digests from detached content
- */
-NSSCMSEncoderContext *
-NSS_CMSEncoder_Start(NSSCMSMessage *cmsg,
- NSSCMSContentCallback outputfn, void *outputarg,
- SECItem *dest, PLArenaPool *destpoolp,
- PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg,
- SECAlgorithmID **detached_digestalgs, SECItem **detached_digests)
-{
- NSSCMSEncoderContext *p7ecx;
- SECStatus rv;
- NSSCMSContentInfo *cinfo;
- SECOidTag tag;
-
- NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg,
- detached_digestalgs, detached_digests);
-
- p7ecx = (NSSCMSEncoderContext *)PORT_ZAlloc(sizeof(NSSCMSEncoderContext));
- if (p7ecx == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- p7ecx->cmsg = cmsg;
- p7ecx->output.outputfn = outputfn;
- p7ecx->output.outputarg = outputarg;
- p7ecx->output.dest = dest;
- p7ecx->output.destpoolp = destpoolp;
- p7ecx->type = SEC_OID_UNKNOWN;
-
- cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
-
- tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
- switch (tag) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- rv = NSS_CMSSignedData_Encode_BeforeStart(cinfo->content.signedData);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- rv = NSS_CMSEnvelopedData_Encode_BeforeStart(cinfo->content.envelopedData);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- rv = NSS_CMSDigestedData_Encode_BeforeStart(cinfo->content.digestedData);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- rv = NSS_CMSEncryptedData_Encode_BeforeStart(cinfo->content.encryptedData);
- break;
- default:
- if (NSS_CMSType_IsWrapper(tag)) {
- rv = NSS_CMSGenericWrapperData_Encode_BeforeStart(tag,
- p7ecx->content.genericData);
- } else {
- rv = SECFailure;
- }
- break;
- }
- if (rv != SECSuccess) {
- PORT_Free(p7ecx);
- return NULL;
- }
-
- /* Initialize the BER encoder.
- * Note that this will not encode anything until the first call to SEC_ASN1EncoderUpdate */
- p7ecx->ecx = SEC_ASN1EncoderStart(cmsg, NSSCMSMessageTemplate,
- nss_cms_encoder_out, &(p7ecx->output));
- if (p7ecx->ecx == NULL) {
- PORT_Free (p7ecx);
- return NULL;
- }
- p7ecx->ecxupdated = PR_FALSE;
-
- /*
- * Indicate that we are streaming. We will be streaming until we
- * get past the contents bytes.
- */
- if (!cinfo->privateInfo || !cinfo->privateInfo->dontStream)
- SEC_ASN1EncoderSetStreaming(p7ecx->ecx);
-
- /*
- * The notify function will watch for the contents field.
- */
- SEC_ASN1EncoderSetNotifyProc(p7ecx->ecx, nss_cms_encoder_notify, p7ecx);
-
- /* this will kick off the encoding process & encode everything up to the content bytes,
- * at which point the notify function sets streaming mode (and possibly creates
- * a child encoder). */
- p7ecx->ecxupdated = PR_TRUE;
- if (SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0) != SECSuccess) {
- PORT_Free (p7ecx);
- return NULL;
- }
-
- return p7ecx;
-}
-
-/*
- * NSS_CMSEncoder_Update - take content data delivery from the user
- *
- * "p7ecx" - encoder context
- * "data" - content data
- * "len" - length of content data
- *
- * need to find the lowest level (and call SEC_ASN1EncoderUpdate on the way down),
- * then hand the data to the work_data fn
- */
-SECStatus
-NSS_CMSEncoder_Update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len)
-{
- SECStatus rv;
- NSSCMSContentInfo *cinfo;
- SECOidTag childtype;
-
- if (p7ecx->error)
- return SECFailure;
-
- /* hand data to the innermost decoder */
- if (p7ecx->childp7ecx) {
- /* tell the child to start encoding, up to its first data byte, if it
- * hasn't started yet */
- if (!p7ecx->childp7ecx->ecxupdated) {
- p7ecx->childp7ecx->ecxupdated = PR_TRUE;
- if (SEC_ASN1EncoderUpdate(p7ecx->childp7ecx->ecx, NULL, 0) != SECSuccess)
- return SECFailure;
- }
- /* recursion here */
- rv = NSS_CMSEncoder_Update(p7ecx->childp7ecx, data, len);
- } else {
- /* we are at innermost decoder */
- /* find out about our inner content type - must be data */
- cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
- if (!cinfo) {
- /* The original programmer didn't expect this to happen */
- p7ecx->error = SEC_ERROR_LIBRARY_FAILURE;
- return SECFailure;
- }
-
- childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
- if (!NSS_CMSType_IsData(childtype))
- return SECFailure;
- /* and we must not have preset data */
- if (cinfo->content.data != NULL)
- return SECFailure;
-
- /* hand it the data so it can encode it (let DER trickle up the chain) */
- rv = nss_cms_encoder_work_data(p7ecx, NULL, (const unsigned char *)data, len, PR_FALSE, PR_TRUE);
- }
- return rv;
-}
-
-/*
- * NSS_CMSEncoder_Cancel - stop all encoding
- *
- * we need to walk down the chain of encoders and the finish them from the innermost out
- */
-SECStatus
-NSS_CMSEncoder_Cancel(NSSCMSEncoderContext *p7ecx)
-{
- SECStatus rv = SECFailure;
-
- /* XXX do this right! */
-
- /*
- * Finish any inner decoders before us so that all the encoded data is flushed
- * This basically finishes all the decoders from the innermost to the outermost.
- * Finishing an inner decoder may result in data being updated to the outer decoder
- * while we are already in NSS_CMSEncoder_Finish, but that's allright.
- */
- if (p7ecx->childp7ecx) {
- rv = NSS_CMSEncoder_Cancel(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */
- /* remember rv for now */
- }
-
- /*
- * On the way back up, there will be no more data (if we had an
- * inner encoder, it is done now!)
- * Flush out any remaining data and/or finish digests.
- */
- rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL));
- if (rv != SECSuccess)
- goto loser;
-
- p7ecx->childp7ecx = NULL;
-
- /* kick the encoder back into working mode again.
- * We turn off streaming stuff (which will cause the encoder to continue
- * encoding happily, now that we have all the data (like digests) ready for it).
- */
- SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx);
- SEC_ASN1EncoderClearStreaming(p7ecx->ecx);
-
- /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */
- rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);
-
-loser:
- SEC_ASN1EncoderFinish(p7ecx->ecx);
- PORT_Free (p7ecx);
- return rv;
-}
-
-/*
- * NSS_CMSEncoder_Finish - signal the end of data
- *
- * we need to walk down the chain of encoders and the finish them from the innermost out
- */
-SECStatus
-NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx)
-{
- SECStatus rv = SECFailure;
- NSSCMSContentInfo *cinfo;
-
- /*
- * Finish any inner decoders before us so that all the encoded data is flushed
- * This basically finishes all the decoders from the innermost to the outermost.
- * Finishing an inner decoder may result in data being updated to the outer decoder
- * while we are already in NSS_CMSEncoder_Finish, but that's allright.
- */
- if (p7ecx->childp7ecx) {
- /* tell the child to start encoding, up to its first data byte, if it
- * hasn't yet */
- if (!p7ecx->childp7ecx->ecxupdated) {
- p7ecx->childp7ecx->ecxupdated = PR_TRUE;
- rv = SEC_ASN1EncoderUpdate(p7ecx->childp7ecx->ecx, NULL, 0);
- if (rv != SECSuccess) {
- NSS_CMSEncoder_Finish(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */
- goto loser;
- }
- }
- rv = NSS_CMSEncoder_Finish(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */
- if (rv != SECSuccess)
- goto loser;
- }
-
- /*
- * On the way back up, there will be no more data (if we had an
- * inner encoder, it is done now!)
- * Flush out any remaining data and/or finish digests.
- */
- rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL));
- if (rv != SECSuccess)
- goto loser;
-
- p7ecx->childp7ecx = NULL;
-
- cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
- if (!cinfo) {
- /* The original programmer didn't expect this to happen */
- p7ecx->error = SEC_ERROR_LIBRARY_FAILURE;
- rv = SECFailure;
- goto loser;
- }
- SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx);
- SEC_ASN1EncoderClearStreaming(p7ecx->ecx);
- /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */
- rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);
-
- if (p7ecx->error)
- rv = SECFailure;
-
-loser:
- SEC_ASN1EncoderFinish(p7ecx->ecx);
- PORT_Free (p7ecx);
- return rv;
-}
diff --git a/security/nss/lib/smime/cmsenvdata.c b/security/nss/lib/smime/cmsenvdata.c
deleted file mode 100644
index 129991ffc..000000000
--- a/security/nss/lib/smime/cmsenvdata.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS envelopedData methods.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "secerr.h"
-#include "secpkcs5.h"
-
-/*
- * NSS_CMSEnvelopedData_Create - create an enveloped data message
- */
-NSSCMSEnvelopedData *
-NSS_CMSEnvelopedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize)
-{
- void *mark;
- NSSCMSEnvelopedData *envd;
- PLArenaPool *poolp;
- SECStatus rv;
-
- poolp = cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- envd = (NSSCMSEnvelopedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEnvelopedData));
- if (envd == NULL)
- goto loser;
-
- envd->cmsg = cmsg;
-
- /* version is set in NSS_CMSEnvelopedData_Encode_BeforeStart() */
-
- rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(envd->contentInfo), algorithm, NULL, keysize);
- if (rv != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark(poolp, mark);
- return envd;
-
-loser:
- PORT_ArenaRelease(poolp, mark);
- return NULL;
-}
-
-/*
- * NSS_CMSEnvelopedData_Destroy - destroy an enveloped data message
- */
-void
-NSS_CMSEnvelopedData_Destroy(NSSCMSEnvelopedData *edp)
-{
- NSSCMSRecipientInfo **recipientinfos;
- NSSCMSRecipientInfo *ri;
-
- if (edp == NULL)
- return;
-
- recipientinfos = edp->recipientInfos;
- if (recipientinfos == NULL)
- return;
-
- while ((ri = *recipientinfos++) != NULL)
- NSS_CMSRecipientInfo_Destroy(ri);
-
- NSS_CMSContentInfo_Destroy(&(edp->contentInfo));
-
-}
-
-/*
- * NSS_CMSEnvelopedData_GetContentInfo - return pointer to this envelopedData's contentinfo
- */
-NSSCMSContentInfo *
-NSS_CMSEnvelopedData_GetContentInfo(NSSCMSEnvelopedData *envd)
-{
- return &(envd->contentInfo);
-}
-
-/*
- * NSS_CMSEnvelopedData_AddRecipient - add a recipientinfo to the enveloped data msg
- *
- * rip must be created on the same pool as edp - this is not enforced, though.
- */
-SECStatus
-NSS_CMSEnvelopedData_AddRecipient(NSSCMSEnvelopedData *edp, NSSCMSRecipientInfo *rip)
-{
- void *mark;
- SECStatus rv;
-
- /* XXX compare pools, if not same, copy rip into edp's pool */
-
- PR_ASSERT(edp != NULL);
- PR_ASSERT(rip != NULL);
-
- mark = PORT_ArenaMark(edp->cmsg->poolp);
-
- rv = NSS_CMSArray_Add(edp->cmsg->poolp, (void ***)&(edp->recipientInfos), (void *)rip);
- if (rv != SECSuccess) {
- PORT_ArenaRelease(edp->cmsg->poolp, mark);
- return SECFailure;
- }
-
- PORT_ArenaUnmark (edp->cmsg->poolp, mark);
- return SECSuccess;
-}
-
-/*
- * NSS_CMSEnvelopedData_Encode_BeforeStart - prepare this envelopedData for encoding
- *
- * at this point, we need
- * - recipientinfos set up with recipient's certificates
- * - a content encryption algorithm (if none, 3DES will be used)
- *
- * this function will generate a random content encryption key (aka bulk key),
- * initialize the recipientinfos with certificate identification and wrap the bulk key
- * using the proper algorithm for every certificiate.
- * it will finally set the bulk algorithm and key so that the encode step can find it.
- */
-SECStatus
-NSS_CMSEnvelopedData_Encode_BeforeStart(NSSCMSEnvelopedData *envd)
-{
- int version;
- NSSCMSRecipientInfo **recipientinfos;
- NSSCMSContentInfo *cinfo;
- PK11SymKey *bulkkey = NULL;
- SECOidTag bulkalgtag;
- CK_MECHANISM_TYPE type;
- PK11SlotInfo *slot;
- SECStatus rv;
- SECItem *dummy;
- PLArenaPool *poolp;
- extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
- void *mark = NULL;
- int i;
-
- poolp = envd->cmsg->poolp;
- cinfo = &(envd->contentInfo);
-
- recipientinfos = envd->recipientInfos;
- if (recipientinfos == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
-#if 0
- PORT_SetErrorString("Cannot find recipientinfos to encode.");
-#endif
- goto loser;
- }
-
- version = NSS_CMS_ENVELOPED_DATA_VERSION_REG;
- if (envd->originatorInfo != NULL || envd->unprotectedAttr != NULL) {
- version = NSS_CMS_ENVELOPED_DATA_VERSION_ADV;
- } else {
- for (i = 0; recipientinfos[i] != NULL; i++) {
- if (NSS_CMSRecipientInfo_GetVersion(recipientinfos[i]) != 0) {
- version = NSS_CMS_ENVELOPED_DATA_VERSION_ADV;
- break;
- }
- }
- }
- dummy = SEC_ASN1EncodeInteger(poolp, &(envd->version), version);
- if (dummy == NULL)
- goto loser;
-
- /* now we need to have a proper content encryption algorithm
- * on the SMIME level, we would figure one out by looking at SMIME capabilities
- * we cannot do that on our level, so if none is set already, we'll just go
- * with one of the mandatory algorithms (3DES) */
- if ((bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo)) == SEC_OID_UNKNOWN) {
- rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, cinfo, SEC_OID_DES_EDE3_CBC, NULL, 168);
- if (rv != SECSuccess)
- goto loser;
- bulkalgtag = SEC_OID_DES_EDE3_CBC;
- }
-
- /* generate a random bulk key suitable for content encryption alg */
- type = PK11_AlgtagToMechanism(bulkalgtag);
- slot = PK11_GetBestSlot(type, envd->cmsg->pwfn_arg);
- if (slot == NULL)
- goto loser; /* error has been set by PK11_GetBestSlot */
-
- /* this is expensive... */
- bulkkey = PK11_KeyGen(slot, type, NULL, NSS_CMSContentInfo_GetBulkKeySize(cinfo) / 8, envd->cmsg->pwfn_arg);
- PK11_FreeSlot(slot);
- if (bulkkey == NULL)
- goto loser; /* error has been set by PK11_KeyGen */
-
- mark = PORT_ArenaMark(poolp);
-
- /* Encrypt the bulk key with the public key of each recipient. */
- for (i = 0; recipientinfos[i] != NULL; i++) {
- rv = NSS_CMSRecipientInfo_WrapBulkKey(recipientinfos[i], bulkkey, bulkalgtag);
- if (rv != SECSuccess)
- goto loser; /* error has been set by NSS_CMSRecipientInfo_EncryptBulkKey */
- /* could be: alg not supported etc. */
- }
-
- /* the recipientinfos are all finished. now sort them by DER for SET OF encoding */
- rv = NSS_CMSArray_SortByDER((void **)envd->recipientInfos, NSSCMSRecipientInfoTemplate, NULL);
- if (rv != SECSuccess)
- goto loser; /* error has been set by NSS_CMSArray_SortByDER */
-
- /* store the bulk key in the contentInfo so that the encoder can find it */
- NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
-
- PORT_ArenaUnmark(poolp, mark);
-
- PK11_FreeSymKey(bulkkey);
-
- return SECSuccess;
-
-loser:
- if (mark != NULL)
- PORT_ArenaRelease (poolp, mark);
- if (bulkkey)
- PK11_FreeSymKey(bulkkey);
-
- return SECFailure;
-}
-
-/*
- * NSS_CMSEnvelopedData_Encode_BeforeData - set up encryption
- *
- * it is essential that this is called before the contentEncAlg is encoded, because
- * setting up the encryption may generate IVs and thus change it!
- */
-SECStatus
-NSS_CMSEnvelopedData_Encode_BeforeData(NSSCMSEnvelopedData *envd)
-{
- NSSCMSContentInfo *cinfo;
- PK11SymKey *bulkkey;
- SECAlgorithmID *algid;
- SECStatus rv;
-
- cinfo = &(envd->contentInfo);
-
- /* find bulkkey and algorithm - must have been set by NSS_CMSEnvelopedData_Encode_BeforeStart */
- bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo);
- if (bulkkey == NULL)
- return SECFailure;
- algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
- if (algid == NULL)
- return SECFailure;
-
- rv = NSS_CMSContentInfo_Private_Init(cinfo);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* this may modify algid (with IVs generated in a token).
- * it is essential that algid is a pointer to the contentEncAlg data, not a
- * pointer to a copy! */
- cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(envd->cmsg->poolp, bulkkey, algid);
- PK11_FreeSymKey(bulkkey);
- if (cinfo->privateInfo->ciphcx == NULL)
- return SECFailure;
-
- return SECSuccess;
-}
-
-/*
- * NSS_CMSEnvelopedData_Encode_AfterData - finalize this envelopedData for encoding
- */
-SECStatus
-NSS_CMSEnvelopedData_Encode_AfterData(NSSCMSEnvelopedData *envd)
-{
- if (envd->contentInfo.privateInfo && envd->contentInfo.privateInfo->ciphcx) {
- NSS_CMSCipherContext_Destroy(envd->contentInfo.privateInfo->ciphcx);
- envd->contentInfo.privateInfo->ciphcx = NULL;
- }
-
- /* nothing else to do after data */
- return SECSuccess;
-}
-
-/*
- * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo,
- * derive bulk key & set up our contentinfo
- */
-SECStatus
-NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd)
-{
- NSSCMSRecipientInfo *ri;
- PK11SymKey *bulkkey = NULL;
- SECOidTag bulkalgtag;
- SECAlgorithmID *bulkalg;
- SECStatus rv = SECFailure;
- NSSCMSContentInfo *cinfo;
- NSSCMSRecipient **recipient_list = NULL;
- NSSCMSRecipient *recipient;
- int rlIndex;
-
- if (NSS_CMSArray_Count((void **)envd->recipientInfos) == 0) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
-#if 0
- PORT_SetErrorString("No recipient data in envelope.");
-#endif
- goto loser;
- }
-
- /* look if one of OUR cert's issuerSN is on the list of recipients, and if so, */
- /* get the cert and private key for it right away */
- recipient_list = nss_cms_recipient_list_create(envd->recipientInfos);
- if (recipient_list == NULL)
- goto loser;
-
- /* what about multiple recipientInfos that match?
- * especially if, for some reason, we could not produce a bulk key with the first match?!
- * we could loop & feed partial recipient_list to PK11_FindCertAndKeyByRecipientList...
- * maybe later... */
- rlIndex = PK11_FindCertAndKeyByRecipientListNew(recipient_list, envd->cmsg->pwfn_arg);
-
- /* if that fails, then we're not an intended recipient and cannot decrypt */
- if (rlIndex < 0) {
- PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT);
-#if 0
- PORT_SetErrorString("Cannot decrypt data because proper key cannot be found.");
-#endif
- goto loser;
- }
-
- recipient = recipient_list[rlIndex];
- if (!recipient->cert || !recipient->privkey) {
- /* XXX should set an error code ?!? */
- goto loser;
- }
- /* get a pointer to "our" recipientinfo */
- ri = envd->recipientInfos[recipient->riIndex];
-
- cinfo = &(envd->contentInfo);
- bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo);
- if (bulkalgtag == SEC_OID_UNKNOWN) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- } else
- bulkkey =
- NSS_CMSRecipientInfo_UnwrapBulkKey(ri,recipient->subIndex,
- recipient->cert,
- recipient->privkey,
- bulkalgtag);
- if (bulkkey == NULL) {
- /* no success finding a bulk key */
- goto loser;
- }
-
- NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
-
- bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
-
- rv = NSS_CMSContentInfo_Private_Init(cinfo);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECFailure;
- cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg);
- if (cinfo->privateInfo->ciphcx == NULL)
- goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */
-
-
- rv = SECSuccess;
-
-loser:
- if (bulkkey)
- PK11_FreeSymKey(bulkkey);
- if (recipient_list != NULL)
- nss_cms_recipient_list_destroy(recipient_list);
- return rv;
-}
-
-/*
- * NSS_CMSEnvelopedData_Decode_AfterData - finish decrypting this envelopedData's content
- */
-SECStatus
-NSS_CMSEnvelopedData_Decode_AfterData(NSSCMSEnvelopedData *envd)
-{
- if (envd && envd->contentInfo.privateInfo && envd->contentInfo.privateInfo->ciphcx) {
- NSS_CMSCipherContext_Destroy(envd->contentInfo.privateInfo->ciphcx);
- envd->contentInfo.privateInfo->ciphcx = NULL;
- }
-
- return SECSuccess;
-}
-
-/*
- * NSS_CMSEnvelopedData_Decode_AfterEnd - finish decoding this envelopedData
- */
-SECStatus
-NSS_CMSEnvelopedData_Decode_AfterEnd(NSSCMSEnvelopedData *envd)
-{
- /* apply final touches */
- return SECSuccess;
-}
-
diff --git a/security/nss/lib/smime/cmslocal.h b/security/nss/lib/smime/cmslocal.h
deleted file mode 100644
index 9105ba489..000000000
--- a/security/nss/lib/smime/cmslocal.h
+++ /dev/null
@@ -1,355 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Support routines for CMS implementation, none of which are exported.
- *
- * Do not export this file! If something in here is really needed outside
- * of smime code, first try to add a CMS interface which will do it for
- * you. If that has a problem, then just move out what you need, changing
- * its name as appropriate!
- *
- * $Id$
- */
-
-#ifndef _CMSLOCAL_H_
-#define _CMSLOCAL_H_
-
-#include "cms.h"
-#include "cmsreclist.h"
-#include "secasn1t.h"
-
-extern const SEC_ASN1Template NSSCMSContentInfoTemplate[];
-
-struct NSSCMSContentInfoPrivateStr {
- NSSCMSCipherContext *ciphcx;
- NSSCMSDigestContext *digcx;
- PRBool dontStream;
-};
-
-/************************************************************************/
-SEC_BEGIN_PROTOS
-
-/*
- * private content Info stuff
- */
-
-/* initialize the private content info field. If this returns
- * SECSuccess, the cinfo->private field is safe to dereference.
- */
-SECStatus NSS_CMSContentInfo_Private_Init(NSSCMSContentInfo *cinfo);
-
-
-/***********************************************************************
- * cmscipher.c - en/decryption routines
- ***********************************************************************/
-
-/*
- * NSS_CMSCipherContext_StartDecrypt - create a cipher context to do decryption
- * based on the given bulk * encryption key and algorithm identifier (which may include an iv).
- */
-extern NSSCMSCipherContext *
-NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid);
-
-/*
- * NSS_CMSCipherContext_StartEncrypt - create a cipher object to do encryption,
- * based on the given bulk encryption key and algorithm tag. Fill in the algorithm
- * identifier (which may include an iv) appropriately.
- */
-extern NSSCMSCipherContext *
-NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgorithmID *algid);
-
-extern void
-NSS_CMSCipherContext_Destroy(NSSCMSCipherContext *cc);
-
-/*
- * NSS_CMSCipherContext_DecryptLength - find the output length of the next call to decrypt.
- *
- * cc - the cipher context
- * input_len - number of bytes used as input
- * final - true if this is the final chunk of data
- *
- * Result can be used to perform memory allocations. Note that the amount
- * is exactly accurate only when not doing a block cipher or when final
- * is false, otherwise it is an upper bound on the amount because until
- * we see the data we do not know how many padding bytes there are
- * (always between 1 and bsize).
- */
-extern unsigned int
-NSS_CMSCipherContext_DecryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final);
-
-/*
- * NSS_CMSCipherContext_EncryptLength - find the output length of the next call to encrypt.
- *
- * cc - the cipher context
- * input_len - number of bytes used as input
- * final - true if this is the final chunk of data
- *
- * Result can be used to perform memory allocations.
- */
-extern unsigned int
-NSS_CMSCipherContext_EncryptLength(NSSCMSCipherContext *cc, unsigned int input_len, PRBool final);
-
-/*
- * NSS_CMSCipherContext_Decrypt - do the decryption
- *
- * cc - the cipher context
- * output - buffer for decrypted result bytes
- * output_len_p - number of bytes in output
- * max_output_len - upper bound on bytes to put into output
- * input - pointer to input bytes
- * input_len - number of input bytes
- * final - true if this is the final chunk of data
- *
- * Decrypts a given length of input buffer (starting at "input" and
- * containing "input_len" bytes), placing the decrypted bytes in
- * "output" and storing the output length in "*output_len_p".
- * "cc" is the return value from NSS_CMSCipher_StartDecrypt.
- * When "final" is true, this is the last of the data to be decrypted.
- */
-extern SECStatus
-NSS_CMSCipherContext_Decrypt(NSSCMSCipherContext *cc, unsigned char *output,
- unsigned int *output_len_p, unsigned int max_output_len,
- const unsigned char *input, unsigned int input_len,
- PRBool final);
-
-/*
- * NSS_CMSCipherContext_Encrypt - do the encryption
- *
- * cc - the cipher context
- * output - buffer for decrypted result bytes
- * output_len_p - number of bytes in output
- * max_output_len - upper bound on bytes to put into output
- * input - pointer to input bytes
- * input_len - number of input bytes
- * final - true if this is the final chunk of data
- *
- * Encrypts a given length of input buffer (starting at "input" and
- * containing "input_len" bytes), placing the encrypted bytes in
- * "output" and storing the output length in "*output_len_p".
- * "cc" is the return value from NSS_CMSCipher_StartEncrypt.
- * When "final" is true, this is the last of the data to be encrypted.
- */
-extern SECStatus
-NSS_CMSCipherContext_Encrypt(NSSCMSCipherContext *cc, unsigned char *output,
- unsigned int *output_len_p, unsigned int max_output_len,
- const unsigned char *input, unsigned int input_len,
- PRBool final);
-
-/************************************************************************
- * cmspubkey.c - public key operations
- ************************************************************************/
-
-/*
- * NSS_CMSUtil_EncryptSymKey_RSA - wrap a symmetric key with RSA
- *
- * this function takes a symmetric key and encrypts it using an RSA public key
- * according to PKCS#1 and RFC2633 (S/MIME)
- */
-extern SECStatus
-NSS_CMSUtil_EncryptSymKey_RSA(PLArenaPool *poolp, CERTCertificate *cert,
- PK11SymKey *key,
- SECItem *encKey);
-
-extern SECStatus
-NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLArenaPool *poolp,
- SECKEYPublicKey *publickey,
- PK11SymKey *bulkkey, SECItem *encKey);
-
-/*
- * NSS_CMSUtil_DecryptSymKey_RSA - unwrap a RSA-wrapped symmetric key
- *
- * this function takes an RSA-wrapped symmetric key and unwraps it, returning a symmetric
- * key handle. Please note that the actual unwrapped key data may not be allowed to leave
- * a hardware token...
- */
-extern PK11SymKey *
-NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOidTag bulkalgtag);
-
-extern SECStatus
-NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
- SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
- SECItem *originatorPubKey);
-
-extern PK11SymKey *
-NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey,
- SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg);
-
-/************************************************************************
- * cmsreclist.c - recipient list stuff
- ************************************************************************/
-extern NSSCMSRecipient **nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos);
-extern void nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list);
-extern NSSCMSRecipientEncryptedKey *NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp);
-
-/************************************************************************
- * cmsarray.c - misc array functions
- ************************************************************************/
-/*
- * NSS_CMSArray_Alloc - allocate an array in an arena
- */
-extern void **
-NSS_CMSArray_Alloc(PRArenaPool *poolp, int n);
-
-/*
- * NSS_CMSArray_Add - add an element to the end of an array
- */
-extern SECStatus
-NSS_CMSArray_Add(PRArenaPool *poolp, void ***array, void *obj);
-
-/*
- * NSS_CMSArray_IsEmpty - check if array is empty
- */
-extern PRBool
-NSS_CMSArray_IsEmpty(void **array);
-
-/*
- * NSS_CMSArray_Count - count number of elements in array
- */
-extern int
-NSS_CMSArray_Count(void **array);
-
-/*
- * NSS_CMSArray_Sort - sort an array ascending, in place
- *
- * If "secondary" is not NULL, the same reordering gets applied to it.
- * If "tertiary" is not NULL, the same reordering gets applied to it.
- * "compare" is a function that returns
- * < 0 when the first element is less than the second
- * = 0 when the first element is equal to the second
- * > 0 when the first element is greater than the second
- */
-extern void
-NSS_CMSArray_Sort(void **primary, int (*compare)(void *,void *), void **secondary, void **tertiary);
-
-/************************************************************************
- * cmsattr.c - misc attribute functions
- ************************************************************************/
-/*
- * NSS_CMSAttribute_Create - create an attribute
- *
- * if value is NULL, the attribute won't have a value. It can be added later
- * with NSS_CMSAttribute_AddValue.
- */
-extern NSSCMSAttribute *
-NSS_CMSAttribute_Create(PRArenaPool *poolp, SECOidTag oidtag, SECItem *value, PRBool encoded);
-
-/*
- * NSS_CMSAttribute_AddValue - add another value to an attribute
- */
-extern SECStatus
-NSS_CMSAttribute_AddValue(PLArenaPool *poolp, NSSCMSAttribute *attr, SECItem *value);
-
-/*
- * NSS_CMSAttribute_GetType - return the OID tag
- */
-extern SECOidTag
-NSS_CMSAttribute_GetType(NSSCMSAttribute *attr);
-
-/*
- * NSS_CMSAttribute_GetValue - return the first attribute value
- *
- * We do some sanity checking first:
- * - Multiple values are *not* expected.
- * - Empty values are *not* expected.
- */
-extern SECItem *
-NSS_CMSAttribute_GetValue(NSSCMSAttribute *attr);
-
-/*
- * NSS_CMSAttribute_CompareValue - compare the attribute's first value against data
- */
-extern PRBool
-NSS_CMSAttribute_CompareValue(NSSCMSAttribute *attr, SECItem *av);
-
-/*
- * NSS_CMSAttributeArray_Encode - encode an Attribute array as SET OF Attributes
- *
- * If you are wondering why this routine does not reorder the attributes
- * first, and might be tempted to make it do so, see the comment by the
- * call to ReorderAttributes in cmsencode.c. (Or, see who else calls this
- * and think long and hard about the implications of making it always
- * do the reordering.)
- */
-extern SECItem *
-NSS_CMSAttributeArray_Encode(PRArenaPool *poolp, NSSCMSAttribute ***attrs, SECItem *dest);
-
-/*
- * NSS_CMSAttributeArray_Reorder - sort attribute array by attribute's DER encoding
- *
- * make sure that the order of the attributes guarantees valid DER (which must be
- * in lexigraphically ascending order for a SET OF); if reordering is necessary it
- * will be done in place (in attrs).
- */
-extern SECStatus
-NSS_CMSAttributeArray_Reorder(NSSCMSAttribute **attrs);
-
-/*
- * NSS_CMSAttributeArray_FindAttrByOidTag - look through a set of attributes and
- * find one that matches the specified object ID.
- *
- * If "only" is true, then make sure that there is not more than one attribute
- * of the same type. Otherwise, just return the first one found. (XXX Does
- * anybody really want that first-found behavior? It was like that when I found it...)
- */
-extern NSSCMSAttribute *
-NSS_CMSAttributeArray_FindAttrByOidTag(NSSCMSAttribute **attrs, SECOidTag oidtag, PRBool only);
-
-/*
- * NSS_CMSAttributeArray_AddAttr - add an attribute to an
- * array of attributes.
- */
-extern SECStatus
-NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSCMSAttribute *attr);
-
-/*
- * NSS_CMSAttributeArray_SetAttr - set an attribute's value in a set of attributes
- */
-extern SECStatus
-NSS_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, SECOidTag type, SECItem *value, PRBool encoded);
-
-/*
- * NSS_CMSSignedData_AddTempCertificate - add temporary certificate references.
- * They may be needed for signature verification on the data, for example.
- */
-extern SECStatus
-NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert);
-
-/*
- * local function to handle compatibility issues
- * by mapping a signature algorithm back to a digest.
- */
-SECOidTag NSS_CMSUtil_MapSignAlgs(SECOidTag signAlg);
-
-
-/************************************************************************/
-
-/*
- * local functions to handle user defined S/MIME content types
- */
-
-
-PRBool NSS_CMSType_IsWrapper(SECOidTag type);
-PRBool NSS_CMSType_IsData(SECOidTag type);
-size_t NSS_CMSType_GetContentSize(SECOidTag type);
-const SEC_ASN1Template * NSS_CMSType_GetTemplate(SECOidTag type);
-
-void NSS_CMSGenericWrapperData_Destroy(SECOidTag type,
- NSSCMSGenericWrapperData *gd);
-SECStatus NSS_CMSGenericWrapperData_Decode_BeforeData(SECOidTag type,
- NSSCMSGenericWrapperData *gd);
-SECStatus NSS_CMSGenericWrapperData_Decode_AfterData(SECOidTag type,
- NSSCMSGenericWrapperData *gd);
-SECStatus NSS_CMSGenericWrapperData_Decode_AfterEnd(SECOidTag type,
- NSSCMSGenericWrapperData *gd);
-SECStatus NSS_CMSGenericWrapperData_Encode_BeforeStart(SECOidTag type,
- NSSCMSGenericWrapperData *gd);
-SECStatus NSS_CMSGenericWrapperData_Encode_BeforeData(SECOidTag type,
- NSSCMSGenericWrapperData *gd);
-SECStatus NSS_CMSGenericWrapperData_Encode_AfterData(SECOidTag type,
- NSSCMSGenericWrapperData *gd);
-
-SEC_END_PROTOS
-
-#endif /* _CMSLOCAL_H_ */
diff --git a/security/nss/lib/smime/cmsmessage.c b/security/nss/lib/smime/cmsmessage.c
deleted file mode 100644
index c38e4c526..000000000
--- a/security/nss/lib/smime/cmsmessage.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS message methods.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "secerr.h"
-
-/*
- * NSS_CMSMessage_Create - create a CMS message object
- *
- * "poolp" - arena to allocate memory from, or NULL if new arena should be created
- */
-NSSCMSMessage *
-NSS_CMSMessage_Create(PLArenaPool *poolp)
-{
- void *mark = NULL;
- NSSCMSMessage *cmsg;
- PRBool poolp_is_ours = PR_FALSE;
-
- if (poolp == NULL) {
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
- if (poolp == NULL)
- return NULL;
- poolp_is_ours = PR_TRUE;
- }
-
- if (!poolp_is_ours)
- mark = PORT_ArenaMark(poolp);
-
- cmsg = (NSSCMSMessage *)PORT_ArenaZAlloc (poolp, sizeof(NSSCMSMessage));
- if (cmsg == NULL) {
- if (!poolp_is_ours) {
- if (mark) {
- PORT_ArenaRelease(poolp, mark);
- }
- } else
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
- NSS_CMSContentInfo_Private_Init(&(cmsg->contentInfo));
-
- cmsg->poolp = poolp;
- cmsg->poolp_is_ours = poolp_is_ours;
- cmsg->refCount = 1;
-
- if (mark)
- PORT_ArenaUnmark(poolp, mark);
-
- return cmsg;
-}
-
-/*
- * NSS_CMSMessage_SetEncodingParams - set up a CMS message object for encoding or decoding
- *
- * "cmsg" - message object
- * "pwfn", pwfn_arg" - callback function for getting token password
- * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
- * "detached_digestalgs", "detached_digests" - digests from detached content
- */
-void
-NSS_CMSMessage_SetEncodingParams(NSSCMSMessage *cmsg,
- PK11PasswordFunc pwfn, void *pwfn_arg,
- NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg,
- SECAlgorithmID **detached_digestalgs, SECItem **detached_digests)
-{
- if (pwfn)
- PK11_SetPasswordFunc(pwfn);
- cmsg->pwfn_arg = pwfn_arg;
- cmsg->decrypt_key_cb = decrypt_key_cb;
- cmsg->decrypt_key_cb_arg = decrypt_key_cb_arg;
- cmsg->detached_digestalgs = detached_digestalgs;
- cmsg->detached_digests = detached_digests;
-}
-
-/*
- * NSS_CMSMessage_Destroy - destroy a CMS message and all of its sub-pieces.
- */
-void
-NSS_CMSMessage_Destroy(NSSCMSMessage *cmsg)
-{
- PORT_Assert (cmsg->refCount > 0);
- if (cmsg->refCount <= 0) /* oops */
- return;
-
- cmsg->refCount--; /* thread safety? */
- if (cmsg->refCount > 0)
- return;
-
- NSS_CMSContentInfo_Destroy(&(cmsg->contentInfo));
-
- /* if poolp is not NULL, cmsg is the owner of its arena */
- if (cmsg->poolp_is_ours)
- PORT_FreeArena (cmsg->poolp, PR_FALSE); /* XXX clear it? */
-}
-
-/*
- * NSS_CMSMessage_Copy - return a copy of the given message.
- *
- * The copy may be virtual or may be real -- either way, the result needs
- * to be passed to NSS_CMSMessage_Destroy later (as does the original).
- */
-NSSCMSMessage *
-NSS_CMSMessage_Copy(NSSCMSMessage *cmsg)
-{
- if (cmsg == NULL)
- return NULL;
-
- PORT_Assert (cmsg->refCount > 0);
-
- cmsg->refCount++; /* XXX chrisk thread safety? */
- return cmsg;
-}
-
-/*
- * NSS_CMSMessage_GetArena - return a pointer to the message's arena pool
- */
-PLArenaPool *
-NSS_CMSMessage_GetArena(NSSCMSMessage *cmsg)
-{
- return cmsg->poolp;
-}
-
-/*
- * NSS_CMSMessage_GetContentInfo - return a pointer to the top level contentInfo
- */
-NSSCMSContentInfo *
-NSS_CMSMessage_GetContentInfo(NSSCMSMessage *cmsg)
-{
- return &(cmsg->contentInfo);
-}
-
-/*
- * Return a pointer to the actual content.
- * In the case of those types which are encrypted, this returns the *plain* content.
- * In case of nested contentInfos, this descends and retrieves the innermost content.
- */
-SECItem *
-NSS_CMSMessage_GetContent(NSSCMSMessage *cmsg)
-{
- /* this is a shortcut */
- NSSCMSContentInfo * cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
- SECItem * pItem = NSS_CMSContentInfo_GetInnerContent(cinfo);
- return pItem;
-}
-
-/*
- * NSS_CMSMessage_ContentLevelCount - count number of levels of CMS content objects in this message
- *
- * CMS data content objects do not count.
- */
-int
-NSS_CMSMessage_ContentLevelCount(NSSCMSMessage *cmsg)
-{
- int count = 0;
- NSSCMSContentInfo *cinfo;
-
- /* walk down the chain of contentinfos */
- for (cinfo = &(cmsg->contentInfo); cinfo != NULL; ) {
- count++;
- cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
- }
- return count;
-}
-
-/*
- * NSS_CMSMessage_ContentLevel - find content level #n
- *
- * CMS data content objects do not count.
- */
-NSSCMSContentInfo *
-NSS_CMSMessage_ContentLevel(NSSCMSMessage *cmsg, int n)
-{
- int count = 0;
- NSSCMSContentInfo *cinfo;
-
- /* walk down the chain of contentinfos */
- for (cinfo = &(cmsg->contentInfo); cinfo != NULL && count < n; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) {
- count++;
- }
-
- return cinfo;
-}
-
-/*
- * NSS_CMSMessage_ContainsCertsOrCrls - see if message contains certs along the way
- */
-PRBool
-NSS_CMSMessage_ContainsCertsOrCrls(NSSCMSMessage *cmsg)
-{
- NSSCMSContentInfo *cinfo;
-
- /* descend into CMS message */
- for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) {
- if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag(cinfo)))
- continue; /* next level */
-
- if (NSS_CMSSignedData_ContainsCertsOrCrls(cinfo->content.signedData))
- return PR_TRUE;
- /* callback here for generic wrappers? */
- }
- return PR_FALSE;
-}
-
-/*
- * NSS_CMSMessage_IsEncrypted - see if message contains a encrypted submessage
- */
-PRBool
-NSS_CMSMessage_IsEncrypted(NSSCMSMessage *cmsg)
-{
- NSSCMSContentInfo *cinfo;
-
- /* walk down the chain of contentinfos */
- for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo))
- {
- switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) {
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- return PR_TRUE;
- default:
- /* callback here for generic wrappers? */
- break;
- }
- }
- return PR_FALSE;
-}
-
-/*
- * NSS_CMSMessage_IsSigned - see if message contains a signed submessage
- *
- * If the CMS message has a SignedData with a signature (not just a SignedData)
- * return true; false otherwise. This can/should be called before calling
- * VerifySignature, which will always indicate failure if no signature is
- * present, but that does not mean there even was a signature!
- * Note that the content itself can be empty (detached content was sent
- * another way); it is the presence of the signature that matters.
- */
-PRBool
-NSS_CMSMessage_IsSigned(NSSCMSMessage *cmsg)
-{
- NSSCMSContentInfo *cinfo;
-
- /* walk down the chain of contentinfos */
- for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo))
- {
- switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- if (!NSS_CMSArray_IsEmpty((void **)cinfo->content.signedData->signerInfos))
- return PR_TRUE;
- break;
- default:
- /* callback here for generic wrappers? */
- break;
- }
- }
- return PR_FALSE;
-}
-
-/*
- * NSS_CMSMessage_IsContentEmpty - see if content is empty
- *
- * returns PR_TRUE is innermost content length is < minLen
- * XXX need the encrypted content length (why?)
- */
-PRBool
-NSS_CMSMessage_IsContentEmpty(NSSCMSMessage *cmsg, unsigned int minLen)
-{
- SECItem *item = NULL;
-
- if (cmsg == NULL)
- return PR_TRUE;
-
- item = NSS_CMSContentInfo_GetContent(NSS_CMSMessage_GetContentInfo(cmsg));
-
- if (!item) {
- return PR_TRUE;
- } else if(item->len <= minLen) {
- return PR_TRUE;
- }
-
- return PR_FALSE;
-}
diff --git a/security/nss/lib/smime/cmspubkey.c b/security/nss/lib/smime/cmspubkey.c
deleted file mode 100644
index fae24a719..000000000
--- a/security/nss/lib/smime/cmspubkey.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS public key crypto
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "secerr.h"
-
-/* ====== RSA ======================================================================= */
-
-/*
- * NSS_CMSUtil_EncryptSymKey_RSA - wrap a symmetric key with RSA
- *
- * this function takes a symmetric key and encrypts it using an RSA public key
- * according to PKCS#1 and RFC2633 (S/MIME)
- */
-SECStatus
-NSS_CMSUtil_EncryptSymKey_RSA(PLArenaPool *poolp, CERTCertificate *cert,
- PK11SymKey *bulkkey,
- SECItem *encKey)
-{
- SECStatus rv;
- SECKEYPublicKey *publickey;
-
- publickey = CERT_ExtractPublicKey(cert);
- if (publickey == NULL)
- return SECFailure;
-
- rv = NSS_CMSUtil_EncryptSymKey_RSAPubKey(poolp, publickey, bulkkey, encKey);
- SECKEY_DestroyPublicKey(publickey);
- return rv;
-}
-
-SECStatus
-NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLArenaPool *poolp,
- SECKEYPublicKey *publickey,
- PK11SymKey *bulkkey, SECItem *encKey)
-{
- SECStatus rv;
- int data_len;
- KeyType keyType;
- void *mark = NULL;
-
-
- mark = PORT_ArenaMark(poolp);
- if (!mark)
- goto loser;
-
- /* sanity check */
- keyType = SECKEY_GetPublicKeyType(publickey);
- PORT_Assert(keyType == rsaKey);
- if (keyType != rsaKey) {
- goto loser;
- }
- /* allocate memory for the encrypted key */
- data_len = SECKEY_PublicKeyStrength(publickey); /* block size (assumed to be > keylen) */
- encKey->data = (unsigned char*)PORT_ArenaAlloc(poolp, data_len);
- encKey->len = data_len;
- if (encKey->data == NULL)
- goto loser;
-
- /* encrypt the key now */
- rv = PK11_PubWrapSymKey(PK11_AlgtagToMechanism(SEC_OID_PKCS1_RSA_ENCRYPTION),
- publickey, bulkkey, encKey);
-
- if (rv != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
-loser:
- if (mark) {
- PORT_ArenaRelease(poolp, mark);
- }
- return SECFailure;
-}
-
-/*
- * NSS_CMSUtil_DecryptSymKey_RSA - unwrap a RSA-wrapped symmetric key
- *
- * this function takes an RSA-wrapped symmetric key and unwraps it, returning a symmetric
- * key handle. Please note that the actual unwrapped key data may not be allowed to leave
- * a hardware token...
- */
-PK11SymKey *
-NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOidTag bulkalgtag)
-{
- /* that's easy */
- CK_MECHANISM_TYPE target;
- PORT_Assert(bulkalgtag != SEC_OID_UNKNOWN);
- target = PK11_AlgtagToMechanism(bulkalgtag);
- if (bulkalgtag == SEC_OID_UNKNOWN || target == CKM_INVALID_MECHANISM) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return NULL;
- }
- return PK11_PubUnwrapSymKey(privkey, encKey, target, CKA_DECRYPT, 0);
-}
-
-/* ====== ESDH (Ephemeral-Static Diffie-Hellman) ==================================== */
-
-SECStatus
-NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
- SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
- SECItem *pubKey)
-{
-#if 0 /* not yet done */
- SECOidTag certalgtag; /* the certificate's encryption algorithm */
- SECOidTag encalgtag; /* the algorithm used for key exchange/agreement */
- SECStatus rv;
- SECItem *params = NULL;
- int data_len;
- SECStatus err;
- PK11SymKey *tek;
- CERTCertificate *ourCert;
- SECKEYPublicKey *ourPubKey;
- NSSCMSKEATemplateSelector whichKEA = NSSCMSKEAInvalid;
-
- certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
- PORT_Assert(certalgtag == SEC_OID_X942_DIFFIE_HELMAN_KEY);
-
- /* We really want to show our KEA tag as the key exchange algorithm tag. */
- encalgtag = SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN;
-
- /* Get the public key of the recipient. */
- publickey = CERT_ExtractPublicKey(cert);
- if (publickey == NULL) goto loser;
-
- /* XXXX generate a DH key pair on a PKCS11 module (XXX which parameters?) */
- /* XXXX */ourCert = PK11_FindBestKEAMatch(cert, wincx);
- if (ourCert == NULL) goto loser;
-
- arena = PORT_NewArena(1024);
- if (arena == NULL) goto loser;
-
- /* While we're here, extract the key pair's public key data and copy it into */
- /* the outgoing parameters. */
- /* XXXX */ourPubKey = CERT_ExtractPublicKey(ourCert);
- if (ourPubKey == NULL)
- {
- goto loser;
- }
- SECITEM_CopyItem(arena, pubKey, /* XXX */&(ourPubKey->u.fortezza.KEAKey));
- SECKEY_DestroyPublicKey(ourPubKey); /* we only need the private key from now on */
- ourPubKey = NULL;
-
- /* Extract our private key in order to derive the KEA key. */
- ourPrivKey = PK11_FindKeyByAnyCert(ourCert,wincx);
- CERT_DestroyCertificate(ourCert); /* we're done with this */
- if (!ourPrivKey) goto loser;
-
- /* If ukm desired, prepare it - allocate enough space (filled with zeros). */
- if (ukm) {
- ukm->data = (unsigned char*)PORT_ArenaZAlloc(arena,/* XXXX */);
- ukm->len = /* XXXX */;
- }
-
- /* Generate the KEK (key exchange key) according to RFC2631 which we use
- * to wrap the bulk encryption key. */
- kek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE,
- ukm, NULL,
- /* XXXX */CKM_KEA_KEY_DERIVE, /* XXXX */CKM_SKIPJACK_WRAP,
- CKA_WRAP, 0, wincx);
-
- SECKEY_DestroyPublicKey(publickey);
- SECKEY_DestroyPrivateKey(ourPrivKey);
- publickey = NULL;
- ourPrivKey = NULL;
-
- if (!kek)
- goto loser;
-
- /* allocate space for the encrypted CEK (bulk key) */
- encKey->data = (unsigned char*)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE);
- encKey->len = SMIME_FORTEZZA_MAX_KEY_SIZE;
-
- if (encKey->data == NULL)
- {
- PK11_FreeSymKey(kek);
- goto loser;
- }
-
-
- /* Wrap the bulk key using CMSRC2WRAP or CMS3DESWRAP, depending on the */
- /* bulk encryption algorithm */
- switch (/* XXXX */PK11_AlgtagToMechanism(enccinfo->encalg))
- {
- case /* XXXX */CKM_SKIPJACK_CFB8:
- err = PK11_WrapSymKey(/* XXXX */CKM_CMS3DES_WRAP, NULL, kek, bulkkey, encKey);
- whichKEA = NSSCMSKEAUsesSkipjack;
- break;
- case /* XXXX */CKM_SKIPJACK_CFB8:
- err = PK11_WrapSymKey(/* XXXX */CKM_CMSRC2_WRAP, NULL, kek, bulkkey, encKey);
- whichKEA = NSSCMSKEAUsesSkipjack;
- break;
- default:
- /* XXXX what do we do here? Neither RC2 nor 3DES... */
- err = SECFailure;
- /* set error */
- break;
- }
-
- PK11_FreeSymKey(kek); /* we do not need the KEK anymore */
- if (err != SECSuccess)
- goto loser;
-
- PORT_Assert(whichKEA != NSSCMSKEAInvalid);
-
- /* see RFC2630 12.3.1.1 "keyEncryptionAlgorithm must be ..." */
- /* params is the DER encoded key wrap algorithm (with parameters!) (XXX) */
- params = SEC_ASN1EncodeItem(arena, NULL, &keaParams, sec_pkcs7_get_kea_template(whichKEA));
- if (params == NULL)
- goto loser;
-
- /* now set keyEncAlg */
- rv = SECOID_SetAlgorithmID(poolp, keyEncAlg, SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN, params);
- if (rv != SECSuccess)
- goto loser;
-
- /* XXXXXXX this is not right yet */
-loser:
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- if (publickey) {
- SECKEY_DestroyPublicKey(publickey);
- }
- if (ourPrivKey) {
- SECKEY_DestroyPrivateKey(ourPrivKey);
- }
-#endif
- return SECFailure;
-}
-
-PK11SymKey *
-NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey, SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg)
-{
-#if 0 /* not yet done */
- SECStatus err;
- CK_MECHANISM_TYPE bulkType;
- PK11SymKey *tek;
- SECKEYPublicKey *originatorPubKey;
- NSSCMSSMIMEKEAParameters keaParams;
-
- /* XXXX get originator's public key */
- originatorPubKey = PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data,
- keaParams.originatorKEAKey.len);
- if (originatorPubKey == NULL)
- goto loser;
-
- /* Generate the TEK (token exchange key) which we use to unwrap the bulk encryption key.
- The Derive function generates a shared secret and combines it with the originatorRA
- data to come up with an unique session key */
- tek = PK11_PubDerive(privkey, originatorPubKey, PR_FALSE,
- &keaParams.originatorRA, NULL,
- CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
- CKA_WRAP, 0, pwfn_arg);
- SECKEY_DestroyPublicKey(originatorPubKey); /* not needed anymore */
- if (tek == NULL)
- goto loser;
-
- /* Now that we have the TEK, unwrap the bulk key
- with which to decrypt the message. */
- /* Skipjack is being used as the bulk encryption algorithm.*/
- /* Unwrap the bulk key. */
- bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL,
- encKey, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
-
- return bulkkey;
-
-loser:
-#endif
- return NULL;
-}
-
diff --git a/security/nss/lib/smime/cmsrecinfo.c b/security/nss/lib/smime/cmsrecinfo.c
deleted file mode 100644
index 9cbf4054a..000000000
--- a/security/nss/lib/smime/cmsrecinfo.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS recipientInfo methods.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "secerr.h"
-
-PRBool
-nss_cmsrecipientinfo_usessubjectkeyid(NSSCMSRecipientInfo *ri)
-{
- if (ri->recipientInfoType == NSSCMSRecipientInfoID_KeyTrans) {
- NSSCMSRecipientIdentifier *rid;
- rid = &ri->ri.keyTransRecipientInfo.recipientIdentifier;
- if (rid->identifierType == NSSCMSRecipientID_SubjectKeyID) {
- return PR_TRUE;
- }
- }
- return PR_FALSE;
-}
-
-/*
- * NOTE: fakeContent marks CMSMessage structure which is only used as a carrier
- * of pwfn_arg and arena pools. In an ideal world, NSSCMSMessage would not have
- * been exported, and we would have added an ordinary enum to handle this
- * check. Unfortunatly wo don't have that luxury so we are overloading the
- * contentTypeTag field. NO code should every try to interpret this content tag
- * as a real OID tag, or use any fields other than pwfn_arg or poolp of this
- * CMSMessage for that matter */
-static const SECOidData fakeContent;
-NSSCMSRecipientInfo *
-nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg,
- NSSCMSRecipientIDSelector type,
- CERTCertificate *cert,
- SECKEYPublicKey *pubKey,
- SECItem *subjKeyID,
- void* pwfn_arg,
- SECItem* DERinput)
-{
- NSSCMSRecipientInfo *ri;
- void *mark;
- SECOidTag certalgtag;
- SECStatus rv = SECSuccess;
- NSSCMSRecipientEncryptedKey *rek;
- NSSCMSOriginatorIdentifierOrKey *oiok;
- unsigned long version;
- SECItem *dummy;
- PLArenaPool *poolp;
- CERTSubjectPublicKeyInfo *spki, *freeSpki = NULL;
- NSSCMSRecipientIdentifier *rid;
- extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
-
- if (!cmsg) {
- /* a CMSMessage wasn't supplied, create a fake one to hold the pwfunc
- * and a private arena pool */
- cmsg = NSS_CMSMessage_Create(NULL);
- cmsg->pwfn_arg = pwfn_arg;
- /* mark it as a special cms message */
- cmsg->contentInfo.contentTypeTag = (SECOidData *)&fakeContent;
- }
-
- poolp = cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- ri = (NSSCMSRecipientInfo *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSRecipientInfo));
- if (ri == NULL)
- goto loser;
-
- ri->cmsg = cmsg;
-
- if (DERinput) {
- /* decode everything from DER */
- SECItem newinput;
- SECStatus rv = SECITEM_CopyItem(poolp, &newinput, DERinput);
- if (SECSuccess != rv)
- goto loser;
- rv = SEC_QuickDERDecodeItem(poolp, ri, NSSCMSRecipientInfoTemplate, &newinput);
- if (SECSuccess != rv)
- goto loser;
- }
-
- switch (type) {
- case NSSCMSRecipientID_IssuerSN:
- {
- ri->cert = CERT_DupCertificate(cert);
- if (NULL == ri->cert)
- goto loser;
- spki = &(cert->subjectPublicKeyInfo);
- break;
- }
-
- case NSSCMSRecipientID_SubjectKeyID:
- {
- PORT_Assert(pubKey);
- spki = freeSpki = SECKEY_CreateSubjectPublicKeyInfo(pubKey);
- break;
- }
-
- case NSSCMSRecipientID_BrandNew:
- goto done;
- break;
-
- default:
- /* unkown type */
- goto loser;
- break;
- }
-
- certalgtag = SECOID_GetAlgorithmTag(&(spki->algorithm));
-
- rid = &ri->ri.keyTransRecipientInfo.recipientIdentifier;
- switch (certalgtag) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- ri->recipientInfoType = NSSCMSRecipientInfoID_KeyTrans;
- rid->identifierType = type;
- if (type == NSSCMSRecipientID_IssuerSN) {
- rid->id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert);
- if (rid->id.issuerAndSN == NULL) {
- break;
- }
- } else if (type == NSSCMSRecipientID_SubjectKeyID){
- NSSCMSKeyTransRecipientInfoEx *riExtra;
-
- rid->id.subjectKeyID = PORT_ArenaNew(poolp, SECItem);
- if (rid->id.subjectKeyID == NULL) {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- break;
- }
- SECITEM_CopyItem(poolp, rid->id.subjectKeyID, subjKeyID);
- if (rid->id.subjectKeyID->data == NULL) {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- break;
- }
- riExtra = &ri->ri.keyTransRecipientInfoEx;
- riExtra->version = 0;
- riExtra->pubKey = SECKEY_CopyPublicKey(pubKey);
- if (riExtra->pubKey == NULL) {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- break;
- }
- } else {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */
- PORT_Assert(type == NSSCMSRecipientID_IssuerSN);
- if (type != NSSCMSRecipientID_IssuerSN) {
- rv = SECFailure;
- break;
- }
- /* a key agreement op */
- ri->recipientInfoType = NSSCMSRecipientInfoID_KeyAgree;
-
- if (ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN == NULL) {
- rv = SECFailure;
- break;
- }
- /* we do not support the case where multiple recipients
- * share the same KeyAgreeRecipientInfo and have multiple RecipientEncryptedKeys
- * in this case, we would need to walk all the recipientInfos, take the
- * ones that do KeyAgreement algorithms and join them, algorithm by algorithm
- * Then, we'd generate ONE ukm and OriginatorIdentifierOrKey */
-
- /* only epheremal-static Diffie-Hellman is supported for now
- * this is the only form of key agreement that provides potential anonymity
- * of the sender, plus we do not have to include certs in the message */
-
- /* force single recipientEncryptedKey for now */
- if ((rek = NSS_CMSRecipientEncryptedKey_Create(poolp)) == NULL) {
- rv = SECFailure;
- break;
- }
-
- /* hardcoded IssuerSN choice for now */
- rek->recipientIdentifier.identifierType = NSSCMSKeyAgreeRecipientID_IssuerSN;
- if ((rek->recipientIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert)) == NULL) {
- rv = SECFailure;
- break;
- }
-
- oiok = &(ri->ri.keyAgreeRecipientInfo.originatorIdentifierOrKey);
-
- /* see RFC2630 12.3.1.1 */
- oiok->identifierType = NSSCMSOriginatorIDOrKey_OriginatorPublicKey;
-
- rv = NSS_CMSArray_Add(poolp, (void ***)&ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys,
- (void *)rek);
-
- break;
- default:
- /* other algorithms not supported yet */
- /* NOTE that we do not support any KEK algorithm */
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- rv = SECFailure;
- break;
- }
-
- if (rv == SECFailure)
- goto loser;
-
- /* set version */
- switch (ri->recipientInfoType) {
- case NSSCMSRecipientInfoID_KeyTrans:
- if (ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType == NSSCMSRecipientID_IssuerSN)
- version = NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN;
- else
- version = NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY;
- dummy = SEC_ASN1EncodeInteger(poolp, &(ri->ri.keyTransRecipientInfo.version), version);
- if (dummy == NULL)
- goto loser;
- break;
- case NSSCMSRecipientInfoID_KeyAgree:
- dummy = SEC_ASN1EncodeInteger(poolp, &(ri->ri.keyAgreeRecipientInfo.version),
- NSS_CMS_KEYAGREE_RECIPIENT_INFO_VERSION);
- if (dummy == NULL)
- goto loser;
- break;
- case NSSCMSRecipientInfoID_KEK:
- /* NOTE: this cannot happen as long as we do not support any KEK algorithm */
- dummy = SEC_ASN1EncodeInteger(poolp, &(ri->ri.kekRecipientInfo.version),
- NSS_CMS_KEK_RECIPIENT_INFO_VERSION);
- if (dummy == NULL)
- goto loser;
- break;
-
- }
-
-done:
- PORT_ArenaUnmark (poolp, mark);
- if (freeSpki)
- SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
- return ri;
-
-loser:
- if (ri && ri->cert) {
- CERT_DestroyCertificate(ri->cert);
- }
- if (freeSpki) {
- SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
- }
- PORT_ArenaRelease (poolp, mark);
- if (cmsg->contentInfo.contentTypeTag == &fakeContent) {
- NSS_CMSMessage_Destroy(cmsg);
- }
- return NULL;
-}
-
-/*
- * NSS_CMSRecipientInfo_Create - create a recipientinfo
- *
- * we currently do not create KeyAgreement recipientinfos with multiple
- * recipientEncryptedKeys the certificate is supposed to have been
- * verified by the caller
- */
-NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert)
-{
- return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_IssuerSN, cert,
- NULL, NULL, NULL, NULL);
-}
-
-NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateNew(void* pwfn_arg)
-{
- return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL,
- NULL, NULL, pwfn_arg, NULL);
-}
-
-NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateFromDER(SECItem* input, void* pwfn_arg)
-{
- return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL,
- NULL, NULL, pwfn_arg, input);
-}
-
-
-NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
- SECItem *subjKeyID,
- SECKEYPublicKey *pubKey)
-{
- return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_SubjectKeyID,
- NULL, pubKey, subjKeyID, NULL, NULL);
-}
-
-NSSCMSRecipientInfo *
-NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg,
- CERTCertificate *cert)
-{
- SECKEYPublicKey *pubKey = NULL;
- SECItem subjKeyID = {siBuffer, NULL, 0};
- NSSCMSRecipientInfo *retVal = NULL;
-
- if (!cmsg || !cert) {
- return NULL;
- }
- pubKey = CERT_ExtractPublicKey(cert);
- if (!pubKey) {
- goto done;
- }
- if (CERT_FindSubjectKeyIDExtension(cert, &subjKeyID) != SECSuccess ||
- subjKeyID.data == NULL) {
- goto done;
- }
- retVal = NSS_CMSRecipientInfo_CreateWithSubjKeyID(cmsg, &subjKeyID, pubKey);
-done:
- if (pubKey)
- SECKEY_DestroyPublicKey(pubKey);
-
- if (subjKeyID.data)
- SECITEM_FreeItem(&subjKeyID, PR_FALSE);
-
- return retVal;
-}
-
-void
-NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri)
-{
- if (!ri) {
- return;
- }
- /* version was allocated on the pool, so no need to destroy it */
- /* issuerAndSN was allocated on the pool, so no need to destroy it */
- if (ri->cert != NULL)
- CERT_DestroyCertificate(ri->cert);
-
- if (nss_cmsrecipientinfo_usessubjectkeyid(ri)) {
- NSSCMSKeyTransRecipientInfoEx *extra;
- extra = &ri->ri.keyTransRecipientInfoEx;
- if (extra->pubKey)
- SECKEY_DestroyPublicKey(extra->pubKey);
- }
- if (ri->cmsg && ri->cmsg->contentInfo.contentTypeTag == &fakeContent) {
- NSS_CMSMessage_Destroy(ri->cmsg);
- }
-
- /* we're done. */
-}
-
-int
-NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri)
-{
- unsigned long version;
- SECItem *versionitem = NULL;
-
- switch (ri->recipientInfoType) {
- case NSSCMSRecipientInfoID_KeyTrans:
- /* ignore subIndex */
- versionitem = &(ri->ri.keyTransRecipientInfo.version);
- break;
- case NSSCMSRecipientInfoID_KEK:
- /* ignore subIndex */
- versionitem = &(ri->ri.kekRecipientInfo.version);
- break;
- case NSSCMSRecipientInfoID_KeyAgree:
- versionitem = &(ri->ri.keyAgreeRecipientInfo.version);
- break;
- }
-
- PORT_Assert(versionitem);
- if (versionitem == NULL)
- return 0;
-
- /* always take apart the SECItem */
- if (SEC_ASN1DecodeInteger(versionitem, &version) != SECSuccess)
- return 0;
- else
- return (int)version;
-}
-
-SECItem *
-NSS_CMSRecipientInfo_GetEncryptedKey(NSSCMSRecipientInfo *ri, int subIndex)
-{
- SECItem *enckey = NULL;
-
- switch (ri->recipientInfoType) {
- case NSSCMSRecipientInfoID_KeyTrans:
- /* ignore subIndex */
- enckey = &(ri->ri.keyTransRecipientInfo.encKey);
- break;
- case NSSCMSRecipientInfoID_KEK:
- /* ignore subIndex */
- enckey = &(ri->ri.kekRecipientInfo.encKey);
- break;
- case NSSCMSRecipientInfoID_KeyAgree:
- enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey);
- break;
- }
- return enckey;
-}
-
-
-SECOidTag
-NSS_CMSRecipientInfo_GetKeyEncryptionAlgorithmTag(NSSCMSRecipientInfo *ri)
-{
- SECOidTag encalgtag = SEC_OID_UNKNOWN; /* an invalid encryption alg */
-
- switch (ri->recipientInfoType) {
- case NSSCMSRecipientInfoID_KeyTrans:
- encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg));
- break;
- case NSSCMSRecipientInfoID_KeyAgree:
- encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg));
- break;
- case NSSCMSRecipientInfoID_KEK:
- encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.kekRecipientInfo.keyEncAlg));
- break;
- }
- return encalgtag;
-}
-
-SECStatus
-NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey,
- SECOidTag bulkalgtag)
-{
- CERTCertificate *cert;
- SECOidTag certalgtag;
- SECStatus rv = SECSuccess;
- NSSCMSRecipientEncryptedKey *rek;
- NSSCMSOriginatorIdentifierOrKey *oiok;
- CERTSubjectPublicKeyInfo *spki, *freeSpki = NULL;
- PLArenaPool *poolp;
- NSSCMSKeyTransRecipientInfoEx *extra = NULL;
- PRBool usesSubjKeyID;
-
- poolp = ri->cmsg->poolp;
- cert = ri->cert;
- usesSubjKeyID = nss_cmsrecipientinfo_usessubjectkeyid(ri);
- if (cert) {
- spki = &cert->subjectPublicKeyInfo;
- certalgtag = SECOID_GetAlgorithmTag(&(spki->algorithm));
- } else if (usesSubjKeyID) {
- extra = &ri->ri.keyTransRecipientInfoEx;
- /* sanity check */
- PORT_Assert(extra->pubKey);
- if (!extra->pubKey) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- spki = freeSpki = SECKEY_CreateSubjectPublicKeyInfo(extra->pubKey);
- certalgtag = SECOID_GetAlgorithmTag(&spki->algorithm);
- } else {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* XXX set ri->recipientInfoType to the proper value here */
- /* or should we look if it's been set already ? */
-
- certalgtag = SECOID_GetAlgorithmTag(&spki->algorithm);
- switch (certalgtag) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- /* wrap the symkey */
- if (cert) {
- rv = NSS_CMSUtil_EncryptSymKey_RSA(poolp, cert, bulkkey,
- &ri->ri.keyTransRecipientInfo.encKey);
- if (rv != SECSuccess)
- break;
- } else if (usesSubjKeyID) {
- PORT_Assert(extra != NULL);
- rv = NSS_CMSUtil_EncryptSymKey_RSAPubKey(poolp, extra->pubKey,
- bulkkey, &ri->ri.keyTransRecipientInfo.encKey);
- if (rv != SECSuccess)
- break;
- }
-
- rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, NULL);
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */
- rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[0];
- if (rek == NULL) {
- rv = SECFailure;
- break;
- }
-
- oiok = &(ri->ri.keyAgreeRecipientInfo.originatorIdentifierOrKey);
- PORT_Assert(oiok->identifierType == NSSCMSOriginatorIDOrKey_OriginatorPublicKey);
-
- /* see RFC2630 12.3.1.1 */
- if (SECOID_SetAlgorithmID(poolp, &oiok->id.originatorPublicKey.algorithmIdentifier,
- SEC_OID_X942_DIFFIE_HELMAN_KEY, NULL) != SECSuccess) {
- rv = SECFailure;
- break;
- }
-
- /* this will generate a key pair, compute the shared secret, */
- /* derive a key and ukm for the keyEncAlg out of it, encrypt the bulk key with */
- /* the keyEncAlg, set encKey, keyEncAlg, publicKey etc. */
- rv = NSS_CMSUtil_EncryptSymKey_ESDH(poolp, cert, bulkkey,
- &rek->encKey,
- &ri->ri.keyAgreeRecipientInfo.ukm,
- &ri->ri.keyAgreeRecipientInfo.keyEncAlg,
- &oiok->id.originatorPublicKey.publicKey);
-
- break;
- default:
- /* other algorithms not supported yet */
- /* NOTE that we do not support any KEK algorithm */
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- rv = SECFailure;
- break;
- }
- if (freeSpki)
- SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
-
- return rv;
-}
-
-PK11SymKey *
-NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
- CERTCertificate *cert, SECKEYPrivateKey *privkey, SECOidTag bulkalgtag)
-{
- PK11SymKey *bulkkey = NULL;
- SECAlgorithmID *encalg;
- SECOidTag encalgtag;
- SECItem *enckey;
- int error;
-
- ri->cert = CERT_DupCertificate(cert);
- /* mark the recipientInfo so we can find it later */
-
- switch (ri->recipientInfoType) {
- case NSSCMSRecipientInfoID_KeyTrans:
- encalg = &(ri->ri.keyTransRecipientInfo.keyEncAlg);
- encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg));
- enckey = &(ri->ri.keyTransRecipientInfo.encKey); /* ignore subIndex */
- switch (encalgtag) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- /* RSA encryption algorithm: */
- /* get the symmetric (bulk) key by unwrapping it using our private key */
- bulkkey = NSS_CMSUtil_DecryptSymKey_RSA(privkey, enckey, bulkalgtag);
- break;
- default:
- error = SEC_ERROR_UNSUPPORTED_KEYALG;
- goto loser;
- }
- break;
- case NSSCMSRecipientInfoID_KeyAgree:
- encalg = &(ri->ri.keyAgreeRecipientInfo.keyEncAlg);
- encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg));
- enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey);
- switch (encalgtag) {
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- /* Diffie-Helman key exchange */
- /* XXX not yet implemented */
- /* XXX problem: SEC_OID_X942_DIFFIE_HELMAN_KEY points to a PKCS3 mechanism! */
- /* we support ephemeral-static DH only, so if the recipientinfo */
- /* has originator stuff in it, we punt (or do we? shouldn't be that hard...) */
- /* first, we derive the KEK (a symkey!) using a Derive operation, then we get the */
- /* content encryption key using a Unwrap op */
- /* the derive operation has to generate the key using the algorithm in RFC2631 */
- error = SEC_ERROR_UNSUPPORTED_KEYALG;
- goto loser;
- break;
- default:
- error = SEC_ERROR_UNSUPPORTED_KEYALG;
- goto loser;
- }
- break;
- case NSSCMSRecipientInfoID_KEK:
- encalg = &(ri->ri.kekRecipientInfo.keyEncAlg);
- encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.kekRecipientInfo.keyEncAlg));
- enckey = &(ri->ri.kekRecipientInfo.encKey);
- /* not supported yet */
- error = SEC_ERROR_UNSUPPORTED_KEYALG;
- goto loser;
- break;
- }
- /* XXXX continue here */
- return bulkkey;
-
-loser:
- PORT_SetError(error);
- return NULL;
-}
-
-SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
- CERTCertificate** retcert,
- SECKEYPrivateKey** retkey)
-{
- CERTCertificate* cert = NULL;
- NSSCMSRecipient** recipients = NULL;
- NSSCMSRecipientInfo* recipientInfos[2];
- SECStatus rv = SECSuccess;
- SECKEYPrivateKey* key = NULL;
-
- if (!ri)
- return SECFailure;
-
- if (!retcert && !retkey) {
- /* nothing requested, nothing found, success */
- return SECSuccess;
- }
-
- if (retcert) {
- *retcert = NULL;
- }
- if (retkey) {
- *retkey = NULL;
- }
-
- if (ri->cert) {
- cert = CERT_DupCertificate(ri->cert);
- if (!cert) {
- rv = SECFailure;
- }
- }
- if (SECSuccess == rv && !cert) {
- /* we don't have the cert, we have to look for it */
- /* first build an NSS_CMSRecipient */
- recipientInfos[0] = ri;
- recipientInfos[1] = NULL;
-
- recipients = nss_cms_recipient_list_create(recipientInfos);
- if (recipients) {
- /* now look for the cert and key */
- if (0 == PK11_FindCertAndKeyByRecipientListNew(recipients,
- ri->cmsg->pwfn_arg)) {
- cert = CERT_DupCertificate(recipients[0]->cert);
- key = SECKEY_CopyPrivateKey(recipients[0]->privkey);
- } else {
- rv = SECFailure;
- }
-
- nss_cms_recipient_list_destroy(recipients);
- }
- else {
- rv = SECFailure;
- }
- } else if (SECSuccess == rv && cert && retkey) {
- /* we have the cert, we just need the key now */
- key = PK11_FindPrivateKeyFromCert(cert->slot, cert, ri->cmsg->pwfn_arg);
- }
- if (retcert) {
- *retcert = cert;
- } else {
- if (cert) {
- CERT_DestroyCertificate(cert);
- }
- }
- if (retkey) {
- *retkey = key;
- } else {
- if (key) {
- SECKEY_DestroyPrivateKey(key);
- }
- }
-
- return rv;
-}
-
-SECStatus NSS_CMSRecipientInfo_Encode(PRArenaPool* poolp,
- const NSSCMSRecipientInfo *src,
- SECItem* returned)
-{
- extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
- SECStatus rv = SECFailure;
- if (!src || !returned) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- } else if (SEC_ASN1EncodeItem(poolp, returned, src,
- NSSCMSRecipientInfoTemplate)) {
- rv = SECSuccess;
- }
- return rv;
-}
diff --git a/security/nss/lib/smime/cmsreclist.c b/security/nss/lib/smime/cmsreclist.c
deleted file mode 100644
index 514679752..000000000
--- a/security/nss/lib/smime/cmsreclist.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS recipient list functions
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "prtime.h"
-#include "secerr.h"
-
-static int
-nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipient **recipient_list)
-{
- int count = 0;
- int rlindex = 0;
- int i, j;
- NSSCMSRecipient *rle;
- NSSCMSRecipientInfo *ri;
- NSSCMSRecipientEncryptedKey *rek;
-
- for (i = 0; recipientinfos[i] != NULL; i++) {
- ri = recipientinfos[i];
- switch (ri->recipientInfoType) {
- case NSSCMSRecipientInfoID_KeyTrans:
- if (recipient_list) {
- NSSCMSRecipientIdentifier *recipId =
- &ri->ri.keyTransRecipientInfo.recipientIdentifier;
-
- if (recipId->identifierType != NSSCMSRecipientID_IssuerSN &&
- recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return -1;
- }
- /* alloc one & fill it out */
- rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
- if (!rle)
- return -1;
-
- rle->riIndex = i;
- rle->subIndex = -1;
- switch (recipId->identifierType) {
- case NSSCMSRecipientID_IssuerSN:
- rle->kind = RLIssuerSN;
- rle->id.issuerAndSN = recipId->id.issuerAndSN;
- break;
- case NSSCMSRecipientID_SubjectKeyID:
- rle->kind = RLSubjKeyID;
- rle->id.subjectKeyID = recipId->id.subjectKeyID;
- break;
- default: /* we never get here because of identifierType check
- we done before. Leaving it to kill compiler warning */
- break;
- }
- recipient_list[rlindex++] = rle;
- } else {
- count++;
- }
- break;
- case NSSCMSRecipientInfoID_KeyAgree:
- if (ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys == NULL)
- break;
- for (j=0; ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j] != NULL; j++) {
- if (recipient_list) {
- rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j];
- /* alloc one & fill it out */
- rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
- if (!rle)
- return -1;
-
- rle->riIndex = i;
- rle->subIndex = j;
- switch (rek->recipientIdentifier.identifierType) {
- case NSSCMSKeyAgreeRecipientID_IssuerSN:
- rle->kind = RLIssuerSN;
- rle->id.issuerAndSN = rek->recipientIdentifier.id.issuerAndSN;
- break;
- case NSSCMSKeyAgreeRecipientID_RKeyID:
- rle->kind = RLSubjKeyID;
- rle->id.subjectKeyID = rek->recipientIdentifier.id.recipientKeyIdentifier.subjectKeyIdentifier;
- break;
- }
- recipient_list[rlindex++] = rle;
- } else {
- count++;
- }
- }
- break;
- case NSSCMSRecipientInfoID_KEK:
- /* KEK is not implemented */
- break;
- }
- }
- /* if we have a recipient list, we return on success (-1, above, on failure) */
- /* otherwise, we return the count. */
- if (recipient_list) {
- recipient_list[rlindex] = NULL;
- return 0;
- } else {
- return count;
- }
-}
-
-NSSCMSRecipient **
-nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos)
-{
- int count, rv;
- NSSCMSRecipient **recipient_list;
-
- /* count the number of recipient identifiers */
- count = nss_cms_recipients_traverse(recipientinfos, NULL);
- if (count <= 0) {
- /* no recipients? */
- PORT_SetError(SEC_ERROR_BAD_DATA);
-#if 0
- PORT_SetErrorString("Cannot find recipient data in envelope.");
-#endif
- return NULL;
- }
-
- /* allocate an array of pointers */
- recipient_list = (NSSCMSRecipient **)
- PORT_ZAlloc((count + 1) * sizeof(NSSCMSRecipient *));
- if (recipient_list == NULL)
- return NULL;
-
- /* now fill in the recipient_list */
- rv = nss_cms_recipients_traverse(recipientinfos, recipient_list);
- if (rv < 0) {
- nss_cms_recipient_list_destroy(recipient_list);
- return NULL;
- }
- return recipient_list;
-}
-
-void
-nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list)
-{
- int i;
- NSSCMSRecipient *recipient;
-
- for (i=0; recipient_list[i] != NULL; i++) {
- recipient = recipient_list[i];
- if (recipient->cert)
- CERT_DestroyCertificate(recipient->cert);
- if (recipient->privkey)
- SECKEY_DestroyPrivateKey(recipient->privkey);
- if (recipient->slot)
- PK11_FreeSlot(recipient->slot);
- PORT_Free(recipient);
- }
- PORT_Free(recipient_list);
-}
-
-NSSCMSRecipientEncryptedKey *
-NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp)
-{
- return (NSSCMSRecipientEncryptedKey *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSRecipientEncryptedKey));
-}
diff --git a/security/nss/lib/smime/cmsreclist.h b/security/nss/lib/smime/cmsreclist.h
deleted file mode 100644
index 435d2d618..000000000
--- a/security/nss/lib/smime/cmsreclist.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * $Id$
- */
-
-#ifndef _CMSRECLIST_H
-#define _CMSRECLIST_H
-
-struct NSSCMSRecipientStr {
- int riIndex; /* this recipient's index in recipientInfo array */
- int subIndex; /* index into recipientEncryptedKeys */
- /* (only in NSSCMSKeyAgreeRecipientInfoStr) */
- enum {RLIssuerSN=0, RLSubjKeyID=1} kind; /* for conversion recipientinfos -> recipientlist */
- union {
- CERTIssuerAndSN * issuerAndSN;
- SECItem * subjectKeyID;
- } id;
-
- /* result data (filled out for each recipient that's us) */
- CERTCertificate * cert;
- SECKEYPrivateKey * privkey;
- PK11SlotInfo * slot;
-};
-
-typedef struct NSSCMSRecipientStr NSSCMSRecipient;
-
-#endif /* _CMSRECLIST_H */
diff --git a/security/nss/lib/smime/cmssigdata.c b/security/nss/lib/smime/cmssigdata.c
deleted file mode 100644
index 9ceaa7d28..000000000
--- a/security/nss/lib/smime/cmssigdata.c
+++ /dev/null
@@ -1,1143 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS signedData methods.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-/*#include "cdbhdl.h"*/
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "secerr.h"
-
-NSSCMSSignedData *
-NSS_CMSSignedData_Create(NSSCMSMessage *cmsg)
-{
- void *mark;
- NSSCMSSignedData *sigd;
- PLArenaPool *poolp;
-
- if (!cmsg) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- poolp = cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- sigd = (NSSCMSSignedData *)PORT_ArenaZAlloc (poolp, sizeof(NSSCMSSignedData));
- if (sigd == NULL)
- goto loser;
-
- sigd->cmsg = cmsg;
-
- /* signerInfos, certs, certlists, crls are all empty */
- /* version is set in NSS_CMSSignedData_Finalize() */
-
- PORT_ArenaUnmark(poolp, mark);
- return sigd;
-
-loser:
- PORT_ArenaRelease(poolp, mark);
- return NULL;
-}
-
-void
-NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd)
-{
- CERTCertificate **certs, **tempCerts, *cert;
- CERTCertificateList **certlists, *certlist;
- NSSCMSSignerInfo **signerinfos, *si;
-
- if (sigd == NULL)
- return;
-
- certs = sigd->certs;
- tempCerts = sigd->tempCerts;
- certlists = sigd->certLists;
- signerinfos = sigd->signerInfos;
-
- if (certs != NULL) {
- while ((cert = *certs++) != NULL)
- CERT_DestroyCertificate (cert);
- }
-
- if (tempCerts != NULL) {
- while ((cert = *tempCerts++) != NULL)
- CERT_DestroyCertificate (cert);
- }
-
- if (certlists != NULL) {
- while ((certlist = *certlists++) != NULL)
- CERT_DestroyCertificateList (certlist);
- }
-
- if (signerinfos != NULL) {
- while ((si = *signerinfos++) != NULL)
- NSS_CMSSignerInfo_Destroy(si);
- }
-
- /* everything's in a pool, so don't worry about the storage */
- NSS_CMSContentInfo_Destroy(&(sigd->contentInfo));
-
-}
-
-/*
- * NSS_CMSSignedData_Encode_BeforeStart - do all the necessary things to a SignedData
- * before start of encoding.
- *
- * In detail:
- * - find out about the right value to put into sigd->version
- * - come up with a list of digestAlgorithms (which should be the union of the algorithms
- * in the signerinfos).
- * If we happen to have a pre-set list of algorithms (and digest values!), we
- * check if we have all the signerinfos' algorithms. If not, this is an error.
- */
-SECStatus
-NSS_CMSSignedData_Encode_BeforeStart(NSSCMSSignedData *sigd)
-{
- NSSCMSSignerInfo *signerinfo;
- SECOidTag digestalgtag;
- SECItem *dummy;
- int version;
- SECStatus rv;
- PRBool haveDigests = PR_FALSE;
- int n, i;
- PLArenaPool *poolp;
-
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- poolp = sigd->cmsg->poolp;
-
- /* we assume that we have precomputed digests if there is a list of algorithms, and */
- /* a chunk of data for each of those algorithms */
- if (sigd->digestAlgorithms != NULL && sigd->digests != NULL) {
- for (i=0; sigd->digestAlgorithms[i] != NULL; i++) {
- if (sigd->digests[i] == NULL)
- break;
- }
- if (sigd->digestAlgorithms[i] == NULL) /* reached the end of the array? */
- haveDigests = PR_TRUE; /* yes: we must have all the digests */
- }
-
- version = NSS_CMS_SIGNED_DATA_VERSION_BASIC;
-
- /* RFC2630 5.1 "version is the syntax version number..." */
- if (NSS_CMSContentInfo_GetContentTypeTag(&(sigd->contentInfo)) != SEC_OID_PKCS7_DATA)
- version = NSS_CMS_SIGNED_DATA_VERSION_EXT;
-
- /* prepare all the SignerInfos (there may be none) */
- for (i=0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) {
- signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i);
-
- /* RFC2630 5.1 "version is the syntax version number..." */
- if (NSS_CMSSignerInfo_GetVersion(signerinfo) != NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN)
- version = NSS_CMS_SIGNED_DATA_VERSION_EXT;
-
- /* collect digestAlgorithms from SignerInfos */
- /* (we need to know which algorithms we have when the content comes in) */
- /* do not overwrite any existing digestAlgorithms (and digest) */
- digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
- n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
- if (n < 0 && haveDigests) {
- /* oops, there is a digestalg we do not have a digest for */
- /* but we were supposed to have all the digests already... */
- goto loser;
- } else if (n < 0) {
- /* add the digestAlgorithm & a NULL digest */
- rv = NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, NULL);
- if (rv != SECSuccess)
- goto loser;
- } else {
- /* found it, nothing to do */
- }
- }
-
- dummy = SEC_ASN1EncodeInteger(poolp, &(sigd->version), (long)version);
- if (dummy == NULL)
- return SECFailure;
-
- /* this is a SET OF, so we need to sort them guys */
- rv = NSS_CMSArray_SortByDER((void **)sigd->digestAlgorithms,
- SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
- (void **)sigd->digests);
- if (rv != SECSuccess)
- return SECFailure;
-
- return SECSuccess;
-
-loser:
- return SECFailure;
-}
-
-SECStatus
-NSS_CMSSignedData_Encode_BeforeData(NSSCMSSignedData *sigd)
-{
- SECStatus rv;
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* set up the digests */
- if (sigd->digests && sigd->digests[0]) {
- sigd->contentInfo.privateInfo->digcx = NULL; /* don't attempt to make new ones. */
- } else if (sigd->digestAlgorithms != NULL) {
- sigd->contentInfo.privateInfo->digcx =
- NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms);
- if (sigd->contentInfo.privateInfo->digcx == NULL)
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * NSS_CMSSignedData_Encode_AfterData - do all the necessary things to a SignedData
- * after all the encapsulated data was passed through the encoder.
- *
- * In detail:
- * - create the signatures in all the SignerInfos
- *
- * Please note that nothing is done to the Certificates and CRLs in the message - this
- * is entirely the responsibility of our callers.
- */
-SECStatus
-NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd)
-{
- NSSCMSSignerInfo **signerinfos, *signerinfo;
- NSSCMSContentInfo *cinfo;
- SECOidTag digestalgtag;
- SECStatus ret = SECFailure;
- SECStatus rv;
- SECItem *contentType;
- int certcount;
- int i, ci, cli, n, rci, si;
- PLArenaPool *poolp;
- CERTCertificateList *certlist;
- extern const SEC_ASN1Template NSSCMSSignerInfoTemplate[];
-
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- poolp = sigd->cmsg->poolp;
- cinfo = &(sigd->contentInfo);
-
- /* did we have digest calculation going on? */
- if (cinfo->privateInfo && cinfo->privateInfo->digcx) {
- rv = NSS_CMSDigestContext_FinishMultiple(cinfo->privateInfo->digcx, poolp,
- &(sigd->digests));
- /* error has been set by NSS_CMSDigestContext_FinishMultiple */
- cinfo->privateInfo->digcx = NULL;
- if (rv != SECSuccess)
- goto loser;
- }
-
- signerinfos = sigd->signerInfos;
- certcount = 0;
-
- /* prepare all the SignerInfos (there may be none) */
- for (i=0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) {
- signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i);
-
- /* find correct digest for this signerinfo */
- digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
- n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
- if (n < 0 || sigd->digests == NULL || sigd->digests[n] == NULL) {
- /* oops - digest not found */
- PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
- goto loser;
- }
-
- /* XXX if our content is anything else but data, we need to force the
- * presence of signed attributes (RFC2630 5.3 "signedAttributes is a
- * collection...") */
-
- /* pass contentType here as we want a contentType attribute */
- if ((contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo)) == NULL)
- goto loser;
-
- /* sign the thing */
- rv = NSS_CMSSignerInfo_Sign(signerinfo, sigd->digests[n], contentType);
- if (rv != SECSuccess)
- goto loser;
-
- /* while we're at it, count number of certs in certLists */
- certlist = NSS_CMSSignerInfo_GetCertList(signerinfo);
- if (certlist)
- certcount += certlist->len;
- }
-
- /* this is a SET OF, so we need to sort them guys */
- rv = NSS_CMSArray_SortByDER((void **)signerinfos, NSSCMSSignerInfoTemplate, NULL);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- * now prepare certs & crls
- */
-
- /* count the rest of the certs */
- if (sigd->certs != NULL) {
- for (ci = 0; sigd->certs[ci] != NULL; ci++)
- certcount++;
- }
-
- if (sigd->certLists != NULL) {
- for (cli = 0; sigd->certLists[cli] != NULL; cli++)
- certcount += sigd->certLists[cli]->len;
- }
-
- if (certcount == 0) {
- sigd->rawCerts = NULL;
- } else {
- /*
- * Combine all of the certs and cert chains into rawcerts.
- * Note: certcount is an upper bound; we may not need that many slots
- * but we will allocate anyway to avoid having to do another pass.
- * (The temporary space saving is not worth it.)
- *
- * XXX ARGH - this NEEDS to be fixed. need to come up with a decent
- * SetOfDERcertficates implementation
- */
- sigd->rawCerts = (SECItem **)PORT_ArenaAlloc(poolp, (certcount + 1) * sizeof(SECItem *));
- if (sigd->rawCerts == NULL)
- return SECFailure;
-
- /*
- * XXX Want to check for duplicates and not add *any* cert that is
- * already in the set. This will be more important when we start
- * dealing with larger sets of certs, dual-key certs (signing and
- * encryption), etc. For the time being we can slide by...
- *
- * XXX ARGH - this NEEDS to be fixed. need to come up with a decent
- * SetOfDERcertficates implementation
- */
- rci = 0;
- if (signerinfos != NULL) {
- for (si = 0; signerinfos[si] != NULL; si++) {
- signerinfo = signerinfos[si];
- for (ci = 0; ci < signerinfo->certList->len; ci++)
- sigd->rawCerts[rci++] = &(signerinfo->certList->certs[ci]);
- }
- }
-
- if (sigd->certs != NULL) {
- for (ci = 0; sigd->certs[ci] != NULL; ci++)
- sigd->rawCerts[rci++] = &(sigd->certs[ci]->derCert);
- }
-
- if (sigd->certLists != NULL) {
- for (cli = 0; sigd->certLists[cli] != NULL; cli++) {
- for (ci = 0; ci < sigd->certLists[cli]->len; ci++)
- sigd->rawCerts[rci++] = &(sigd->certLists[cli]->certs[ci]);
- }
- }
-
- sigd->rawCerts[rci] = NULL;
-
- /* this is a SET OF, so we need to sort them guys - we have the DER already, though */
- NSS_CMSArray_Sort((void **)sigd->rawCerts, NSS_CMSUtil_DERCompare, NULL, NULL);
- }
-
- ret = SECSuccess;
-
-loser:
- return ret;
-}
-
-SECStatus
-NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd)
-{
- SECStatus rv;
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- rv = NSS_CMSContentInfo_Private_Init(&sigd->contentInfo);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* handle issue with Windows 2003 servers and kerberos */
- if (sigd->digestAlgorithms != NULL) {
- int i;
- for (i=0; sigd->digestAlgorithms[i] != NULL; i++) {
- SECAlgorithmID *algid = sigd->digestAlgorithms[i];
- SECOidTag senttag= SECOID_FindOIDTag(&algid->algorithm);
- SECOidTag maptag = NSS_CMSUtil_MapSignAlgs(senttag);
-
- if (maptag != senttag) {
- SECOidData *hashoid = SECOID_FindOIDByTag(maptag);
- rv = SECITEM_CopyItem(sigd->cmsg->poolp, &algid->algorithm
- ,&hashoid->oid);
- if (rv != SECSuccess) {
- return rv;
- }
- }
- }
- }
-
- /* set up the digests */
- if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) {
- /* if digests are already there, do nothing */
- sigd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms);
- if (sigd->contentInfo.privateInfo->digcx == NULL)
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a
- * SignedData after all the encapsulated data was passed through the decoder.
- */
-SECStatus
-NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd)
-{
- SECStatus rv = SECSuccess;
-
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* did we have digest calculation going on? */
- if (sigd->contentInfo.privateInfo && sigd->contentInfo.privateInfo->digcx) {
- rv = NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.privateInfo->digcx,
- sigd->cmsg->poolp, &(sigd->digests));
- /* error set by NSS_CMSDigestContext_FinishMultiple */
- sigd->contentInfo.privateInfo->digcx = NULL;
- }
- return rv;
-}
-
-/*
- * NSS_CMSSignedData_Decode_AfterEnd - do all the necessary things to a SignedData
- * after all decoding is finished.
- */
-SECStatus
-NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd)
-{
- NSSCMSSignerInfo **signerinfos = NULL;
- int i;
-
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* set cmsg for all the signerinfos */
- signerinfos = sigd->signerInfos;
-
- /* set cmsg for all the signerinfos */
- if (signerinfos) {
- for (i = 0; signerinfos[i] != NULL; i++)
- signerinfos[i]->cmsg = sigd->cmsg;
- }
-
- return SECSuccess;
-}
-
-/*
- * NSS_CMSSignedData_GetSignerInfos - retrieve the SignedData's signer list
- */
-NSSCMSSignerInfo **
-NSS_CMSSignedData_GetSignerInfos(NSSCMSSignedData *sigd)
-{
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- return sigd->signerInfos;
-}
-
-int
-NSS_CMSSignedData_SignerInfoCount(NSSCMSSignedData *sigd)
-{
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return 0;
- }
- return NSS_CMSArray_Count((void **)sigd->signerInfos);
-}
-
-NSSCMSSignerInfo *
-NSS_CMSSignedData_GetSignerInfo(NSSCMSSignedData *sigd, int i)
-{
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- return sigd->signerInfos[i];
-}
-
-/*
- * NSS_CMSSignedData_GetDigestAlgs - retrieve the SignedData's digest algorithm list
- */
-SECAlgorithmID **
-NSS_CMSSignedData_GetDigestAlgs(NSSCMSSignedData *sigd)
-{
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- return sigd->digestAlgorithms;
-}
-
-/*
- * NSS_CMSSignedData_GetContentInfo - return pointer to this signedData's contentinfo
- */
-NSSCMSContentInfo *
-NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd)
-{
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- return &(sigd->contentInfo);
-}
-
-/*
- * NSS_CMSSignedData_GetCertificateList - retrieve the SignedData's certificate list
- */
-SECItem **
-NSS_CMSSignedData_GetCertificateList(NSSCMSSignedData *sigd)
-{
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- return sigd->rawCerts;
-}
-
-SECStatus
-NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb,
- SECCertUsage certusage, PRBool keepcerts)
-{
- int certcount;
- CERTCertificate **certArray = NULL;
- CERTCertList *certList = NULL;
- CERTCertListNode *node;
- SECStatus rv;
- SECItem **rawArray;
- int i;
- PRTime now;
-
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- certcount = NSS_CMSArray_Count((void **)sigd->rawCerts);
-
- /* get the certs in the temp DB */
- rv = CERT_ImportCerts(certdb, certusage, certcount, sigd->rawCerts,
- &certArray, PR_FALSE, PR_FALSE, NULL);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* save the certs so they don't get destroyed */
- for (i=0; i < certcount; i++) {
- CERTCertificate *cert = certArray[i];
- if (cert)
- NSS_CMSSignedData_AddTempCertificate(sigd, cert);
- }
-
- if (!keepcerts) {
- goto done;
- }
-
- /* build a CertList for filtering */
- certList = CERT_NewCertList();
- if (certList == NULL) {
- rv = SECFailure;
- goto loser;
- }
- for (i=0; i < certcount; i++) {
- CERTCertificate *cert = certArray[i];
- if (cert)
- cert = CERT_DupCertificate(cert);
- if (cert)
- CERT_AddCertToListTail(certList,cert);
- }
-
- /* filter out the certs we don't want */
- rv = CERT_FilterCertListByUsage(certList,certusage, PR_FALSE);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* go down the remaining list of certs and verify that they have
- * valid chains, then import them.
- */
- now = PR_Now();
- for (node = CERT_LIST_HEAD(certList) ; !CERT_LIST_END(node,certList);
- node= CERT_LIST_NEXT(node)) {
- CERTCertificateList *certChain;
-
- if (CERT_VerifyCert(certdb, node->cert,
- PR_TRUE, certusage, now, NULL, NULL) != SECSuccess) {
- continue;
- }
-
- certChain = CERT_CertChainFromCert(node->cert, certusage, PR_FALSE);
- if (!certChain) {
- continue;
- }
-
- /*
- * CertChain returns an array of SECItems, import expects an array of
- * SECItem pointers. Create the SECItem Pointers from the array of
- * SECItems.
- */
- rawArray = (SECItem **)PORT_Alloc(certChain->len*sizeof (SECItem *));
- if (!rawArray) {
- CERT_DestroyCertificateList(certChain);
- continue;
- }
- for (i=0; i < certChain->len; i++) {
- rawArray[i] = &certChain->certs[i];
- }
- (void )CERT_ImportCerts(certdb, certusage, certChain->len,
- rawArray, NULL, keepcerts, PR_FALSE, NULL);
- PORT_Free(rawArray);
- CERT_DestroyCertificateList(certChain);
- }
-
- rv = SECSuccess;
-
- /* XXX CRL handling */
-
-done:
- if (sigd->signerInfos != NULL) {
- /* fill in all signerinfo's certs */
- for (i = 0; sigd->signerInfos[i] != NULL; i++)
- (void)NSS_CMSSignerInfo_GetSigningCertificate(
- sigd->signerInfos[i], certdb);
- }
-
-loser:
- /* now free everything */
- if (certArray) {
- CERT_DestroyCertArray(certArray,certcount);
- }
- if (certList) {
- CERT_DestroyCertList(certList);
- }
-
- return rv;
-}
-
-/*
- * XXX the digests need to be passed in BETWEEN the decoding and the verification in case
- * of external signatures!
- */
-
-/*
- * NSS_CMSSignedData_VerifySignerInfo - check the signatures.
- *
- * The digests were either calculated during decoding (and are stored in the
- * signedData itself) or set after decoding using NSS_CMSSignedData_SetDigests.
- *
- * The verification checks if the signing cert is valid and has a trusted chain
- * for the purpose specified by "certusage".
- */
-SECStatus
-NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i,
- CERTCertDBHandle *certdb, SECCertUsage certusage)
-{
- NSSCMSSignerInfo *signerinfo;
- NSSCMSContentInfo *cinfo;
- SECOidData *algiddata;
- SECItem *contentType, *digest;
- SECOidTag oidTag;
- SECStatus rv;
-
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- cinfo = &(sigd->contentInfo);
-
- signerinfo = sigd->signerInfos[i];
-
- /* verify certificate */
- rv = NSS_CMSSignerInfo_VerifyCertificate(signerinfo, certdb, certusage);
- if (rv != SECSuccess)
- return rv; /* error is set */
-
- /* find digest and contentType for signerinfo */
- algiddata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
- oidTag = algiddata ? algiddata->offset : SEC_OID_UNKNOWN;
- digest = NSS_CMSSignedData_GetDigestValue(sigd, oidTag);
- /* NULL digest is acceptable. */
- contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo);
- /* NULL contentType is acceptable. */
-
- /* now verify signature */
- rv = NSS_CMSSignerInfo_Verify(signerinfo, digest, contentType);
- return rv;
-}
-
-/*
- * NSS_CMSSignedData_VerifyCertsOnly - verify the certs in a certs-only message
- */
-SECStatus
-NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
- CERTCertDBHandle *certdb,
- SECCertUsage usage)
-{
- CERTCertificate *cert;
- SECStatus rv = SECSuccess;
- int i;
- int count;
- PRTime now;
-
- if (!sigd || !certdb || !sigd->rawCerts) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- count = NSS_CMSArray_Count((void**)sigd->rawCerts);
- now = PR_Now();
- for (i=0; i < count; i++) {
- if (sigd->certs && sigd->certs[i]) {
- cert = CERT_DupCertificate(sigd->certs[i]);
- } else {
- cert = CERT_FindCertByDERCert(certdb, sigd->rawCerts[i]);
- if (!cert) {
- rv = SECFailure;
- break;
- }
- }
- rv |= CERT_VerifyCert(certdb, cert, PR_TRUE, usage, now,
- NULL, NULL);
- CERT_DestroyCertificate(cert);
- }
-
- return rv;
-}
-
-/*
- * NSS_CMSSignedData_HasDigests - see if we have digests in place
- */
-PRBool
-NSS_CMSSignedData_HasDigests(NSSCMSSignedData *sigd)
-{
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return PR_FALSE;
- }
- return (sigd->digests != NULL);
-}
-
-SECStatus
-NSS_CMSSignedData_AddCertList(NSSCMSSignedData *sigd, CERTCertificateList *certlist)
-{
- SECStatus rv;
-
- if (!sigd || !certlist) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* XXX memory?? a certlist has an arena of its own and is not refcounted!?!? */
- rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->certLists), (void *)certlist);
-
- return rv;
-}
-
-/*
- * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs
- */
-SECStatus
-NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert)
-{
- CERTCertificateList *certlist;
- SECCertUsage usage;
- SECStatus rv;
-
- usage = certUsageEmailSigner;
-
- if (!sigd || !cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* do not include root */
- certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE);
- if (certlist == NULL)
- return SECFailure;
-
- rv = NSS_CMSSignedData_AddCertList(sigd, certlist);
-
- return rv;
-}
-
-extern SECStatus
-NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert)
-{
- CERTCertificate *c;
- SECStatus rv;
-
- if (!sigd || !cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- c = CERT_DupCertificate(cert);
- rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->tempCerts), (void *)c);
- return rv;
-}
-
-SECStatus
-NSS_CMSSignedData_AddCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert)
-{
- CERTCertificate *c;
- SECStatus rv;
-
- if (!sigd || !cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- c = CERT_DupCertificate(cert);
- rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->certs), (void *)c);
- return rv;
-}
-
-PRBool
-NSS_CMSSignedData_ContainsCertsOrCrls(NSSCMSSignedData *sigd)
-{
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return PR_FALSE;
- }
- if (sigd->rawCerts != NULL && sigd->rawCerts[0] != NULL)
- return PR_TRUE;
- else if (sigd->crls != NULL && sigd->crls[0] != NULL)
- return PR_TRUE;
- else
- return PR_FALSE;
-}
-
-SECStatus
-NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
- NSSCMSSignerInfo *signerinfo)
-{
- void *mark;
- SECStatus rv;
- SECOidTag digestalgtag;
- PLArenaPool *poolp;
-
- if (!sigd || !signerinfo) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- poolp = sigd->cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- /* add signerinfo */
- rv = NSS_CMSArray_Add(poolp, (void ***)&(sigd->signerInfos), (void *)signerinfo);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- * add empty digest
- * Empty because we don't have it yet. Either it gets created during encoding
- * (if the data is present) or has to be set externally.
- * XXX maybe pass it in optionally?
- */
- digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
- rv = NSS_CMSSignedData_SetDigestValue(sigd, digestalgtag, NULL);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- * The last thing to get consistency would be adding the digest.
- */
-
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease (poolp, mark);
- return SECFailure;
-}
-
-/*
- * NSS_CMSSignedData_SetDigests - set a signedData's digests member
- *
- * "digestalgs" - array of digest algorithm IDs
- * "digests" - array of digests corresponding to the digest algorithms
- */
-SECStatus
-NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
- SECAlgorithmID **digestalgs,
- SECItem **digests)
-{
- int cnt, i, idx;
-
- if (!sigd || !digestalgs || !digests) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (sigd->digestAlgorithms == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* we assume that the digests array is just not there yet */
- PORT_Assert(sigd->digests == NULL);
- if (sigd->digests != NULL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- /* now allocate one (same size as digestAlgorithms) */
- cnt = NSS_CMSArray_Count((void **)sigd->digestAlgorithms);
- sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(SECItem *));
- if (sigd->digests == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- for (i = 0; sigd->digestAlgorithms[i] != NULL; i++) {
- /* try to find the sigd's i'th digest algorithm in the array we passed in */
- idx = NSS_CMSAlgArray_GetIndexByAlgID(digestalgs, sigd->digestAlgorithms[i]);
- if (idx < 0) {
- PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
- return SECFailure;
- }
- if (!digests[idx]) {
- /* We have no digest for this algorithm, probably because it is
- ** unrecognized or unsupported. We'll ignore this here. If this
- ** digest is needed later, an error will be be generated then.
- */
- continue;
- }
-
- /* found it - now set it */
- if ((sigd->digests[i] = SECITEM_AllocItem(sigd->cmsg->poolp, NULL, 0)) == NULL ||
- SECITEM_CopyItem(sigd->cmsg->poolp, sigd->digests[i], digests[idx]) != SECSuccess)
- {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd,
- SECOidTag digestalgtag,
- SECItem *digestdata)
-{
- SECItem *digest = NULL;
- PLArenaPool *poolp;
- void *mark;
- int n, cnt;
-
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- poolp = sigd->cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
-
- if (digestdata) {
- digest = (SECItem *) PORT_ArenaZAlloc(poolp,sizeof(SECItem));
-
- /* copy digestdata item to arena (in case we have it and are not only making room) */
- if (SECITEM_CopyItem(poolp, digest, digestdata) != SECSuccess)
- goto loser;
- }
-
- /* now allocate one (same size as digestAlgorithms) */
- if (sigd->digests == NULL) {
- cnt = NSS_CMSArray_Count((void **)sigd->digestAlgorithms);
- sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(SECItem *));
- if (sigd->digests == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- }
-
- n = -1;
- if (sigd->digestAlgorithms != NULL)
- n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
-
- /* if not found, add a digest */
- if (n < 0) {
- if (NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, digest) != SECSuccess)
- goto loser;
- } else {
- /* replace NULL pointer with digest item (and leak previous value) */
- sigd->digests[n] = digest;
- }
-
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-SECStatus
-NSS_CMSSignedData_AddDigest(PRArenaPool *poolp,
- NSSCMSSignedData *sigd,
- SECOidTag digestalgtag,
- SECItem *digest)
-{
- SECAlgorithmID *digestalg;
- void *mark;
-
- if (!sigd || !poolp) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- mark = PORT_ArenaMark(poolp);
-
- digestalg = PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
- if (digestalg == NULL)
- goto loser;
-
- if (SECOID_SetAlgorithmID (poolp, digestalg, digestalgtag, NULL) != SECSuccess) /* no params */
- goto loser;
-
- if (NSS_CMSArray_Add(poolp, (void ***)&(sigd->digestAlgorithms), (void *)digestalg) != SECSuccess ||
- /* even if digest is NULL, add dummy to have same-size array */
- NSS_CMSArray_Add(poolp, (void ***)&(sigd->digests), (void *)digest) != SECSuccess)
- {
- goto loser;
- }
-
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
-}
-
-/* XXX This function doesn't set the error code on failure. */
-SECItem *
-NSS_CMSSignedData_GetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag)
-{
- int n;
-
- if (!sigd) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- if (sigd->digestAlgorithms == NULL || sigd->digests == NULL) {
- PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
- return NULL;
- }
-
- n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
-
- return (n < 0) ? NULL : sigd->digests[n];
-}
-
-/* =============================================================================
- * Misc. utility functions
- */
-
-/*
- * NSS_CMSSignedData_CreateCertsOnly - create a certs-only SignedData.
- *
- * cert - base certificates that will be included
- * include_chain - if true, include the complete cert chain for cert
- *
- * More certs and chains can be added via AddCertificate and AddCertChain.
- *
- * An error results in a return value of NULL and an error set.
- *
- * XXXX CRLs
- */
-NSSCMSSignedData *
-NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PRBool include_chain)
-{
- NSSCMSSignedData *sigd;
- void *mark;
- PLArenaPool *poolp;
- SECStatus rv;
-
- if (!cmsg || !cert) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- poolp = cmsg->poolp;
- mark = PORT_ArenaMark(poolp);
-
- sigd = NSS_CMSSignedData_Create(cmsg);
- if (sigd == NULL)
- goto loser;
-
- /* no signerinfos, thus no digestAlgorithms */
-
- /* but certs */
- if (include_chain) {
- rv = NSS_CMSSignedData_AddCertChain(sigd, cert);
- } else {
- rv = NSS_CMSSignedData_AddCertificate(sigd, cert);
- }
- if (rv != SECSuccess)
- goto loser;
-
- /* RFC2630 5.2 sez:
- * In the degenerate case where there are no signers, the
- * EncapsulatedContentInfo value being "signed" is irrelevant. In this
- * case, the content type within the EncapsulatedContentInfo value being
- * "signed" should be id-data (as defined in section 4), and the content
- * field of the EncapsulatedContentInfo value should be omitted.
- */
- rv = NSS_CMSContentInfo_SetContent_Data(cmsg, &(sigd->contentInfo), NULL, PR_TRUE);
- if (rv != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark(poolp, mark);
- return sigd;
-
-loser:
- if (sigd)
- NSS_CMSSignedData_Destroy(sigd);
- PORT_ArenaRelease(poolp, mark);
- return NULL;
-}
-
-/* TODO:
- * NSS_CMSSignerInfo_GetReceiptRequest()
- * NSS_CMSSignedData_HasReceiptRequest()
- * easy way to iterate over signers
- */
-
diff --git a/security/nss/lib/smime/cmssiginfo.c b/security/nss/lib/smime/cmssiginfo.c
deleted file mode 100644
index effac244b..000000000
--- a/security/nss/lib/smime/cmssiginfo.c
+++ /dev/null
@@ -1,1023 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS signerInfo methods.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "prtime.h"
-#include "secerr.h"
-#include "secder.h"
-#include "cryptohi.h"
-
-#include "smime.h"
-
-/* =============================================================================
- * SIGNERINFO
- */
-NSSCMSSignerInfo *
-nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type,
- CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey,
- SECKEYPrivateKey *signingKey, SECOidTag digestalgtag);
-
-NSSCMSSignerInfo *
-NSS_CMSSignerInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, SECItem *subjKeyID,
- SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag)
-{
- return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_SubjectKeyID, NULL, subjKeyID, pubKey, signingKey, digestalgtag);
-}
-
-NSSCMSSignerInfo *
-NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag)
-{
- return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_IssuerSN, cert, NULL, NULL, NULL, digestalgtag);
-}
-
-NSSCMSSignerInfo *
-nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type,
- CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey,
- SECKEYPrivateKey *signingKey, SECOidTag digestalgtag)
-{
- void *mark;
- NSSCMSSignerInfo *signerinfo;
- int version;
- PLArenaPool *poolp;
-
- poolp = cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- signerinfo = (NSSCMSSignerInfo *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSSignerInfo));
- if (signerinfo == NULL) {
- PORT_ArenaRelease(poolp, mark);
- return NULL;
- }
-
-
- signerinfo->cmsg = cmsg;
-
- switch(type) {
- case NSSCMSSignerID_IssuerSN:
- signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_IssuerSN;
- if ((signerinfo->cert = CERT_DupCertificate(cert)) == NULL)
- goto loser;
- if ((signerinfo->signerIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert)) == NULL)
- goto loser;
- break;
- case NSSCMSSignerID_SubjectKeyID:
- signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_SubjectKeyID;
- PORT_Assert(subjKeyID);
- if (!subjKeyID)
- goto loser;
-
- signerinfo->signerIdentifier.id.subjectKeyID = PORT_ArenaNew(poolp, SECItem);
- SECITEM_CopyItem(poolp, signerinfo->signerIdentifier.id.subjectKeyID,
- subjKeyID);
- signerinfo->signingKey = SECKEY_CopyPrivateKey(signingKey);
- if (!signerinfo->signingKey)
- goto loser;
- signerinfo->pubKey = SECKEY_CopyPublicKey(pubKey);
- if (!signerinfo->pubKey)
- goto loser;
- break;
- default:
- goto loser;
- }
-
- /* set version right now */
- version = NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN;
- /* RFC2630 5.3 "version is the syntax version number. If the .... " */
- if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID)
- version = NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY;
- (void)SEC_ASN1EncodeInteger(poolp, &(signerinfo->version), (long)version);
-
- if (SECOID_SetAlgorithmID(poolp, &signerinfo->digestAlg, digestalgtag, NULL) != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark(poolp, mark);
- return signerinfo;
-
-loser:
- PORT_ArenaRelease(poolp, mark);
- return NULL;
-}
-
-/*
- * NSS_CMSSignerInfo_Destroy - destroy a SignerInfo data structure
- */
-void
-NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si)
-{
- if (si->cert != NULL)
- CERT_DestroyCertificate(si->cert);
-
- if (si->certList != NULL)
- CERT_DestroyCertificateList(si->certList);
-
- /* XXX storage ??? */
-}
-
-/*
- * NSS_CMSSignerInfo_Sign - sign something
- *
- */
-SECStatus
-NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest,
- SECItem *contentType)
-{
- CERTCertificate *cert;
- SECKEYPrivateKey *privkey = NULL;
- SECOidTag digestalgtag;
- SECOidTag pubkAlgTag;
- SECItem signature = { 0 };
- SECStatus rv;
- PLArenaPool *poolp, *tmppoolp = NULL;
- SECAlgorithmID *algID, freeAlgID;
- CERTSubjectPublicKeyInfo *spki;
-
- PORT_Assert (digest != NULL);
-
- poolp = signerinfo->cmsg->poolp;
-
- switch (signerinfo->signerIdentifier.identifierType) {
- case NSSCMSSignerID_IssuerSN:
- cert = signerinfo->cert;
-
- privkey = PK11_FindKeyByAnyCert(cert, signerinfo->cmsg->pwfn_arg);
- if (privkey == NULL)
- goto loser;
- algID = &cert->subjectPublicKeyInfo.algorithm;
- break;
- case NSSCMSSignerID_SubjectKeyID:
- privkey = signerinfo->signingKey;
- signerinfo->signingKey = NULL;
- spki = SECKEY_CreateSubjectPublicKeyInfo(signerinfo->pubKey);
- SECKEY_DestroyPublicKey(signerinfo->pubKey);
- signerinfo->pubKey = NULL;
- SECOID_CopyAlgorithmID(NULL, &freeAlgID, &spki->algorithm);
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- algID = &freeAlgID;
- break;
- default:
- goto loser;
- }
- digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
- /*
- * XXX I think there should be a cert-level interface for this,
- * so that I do not have to know about subjectPublicKeyInfo...
- */
- pubkAlgTag = SECOID_GetAlgorithmTag(algID);
- if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) {
- SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE);
- }
-
- if (signerinfo->authAttr != NULL) {
- SECOidTag signAlgTag;
- SECItem encoded_attrs;
-
- /* find and fill in the message digest attribute. */
- rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr),
- SEC_OID_PKCS9_MESSAGE_DIGEST, digest, PR_FALSE);
- if (rv != SECSuccess)
- goto loser;
-
- if (contentType != NULL) {
- /* if the caller wants us to, find and fill in the content type attribute. */
- rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr),
- SEC_OID_PKCS9_CONTENT_TYPE, contentType, PR_FALSE);
- if (rv != SECSuccess)
- goto loser;
- }
-
- if ((tmppoolp = PORT_NewArena (1024)) == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /*
- * Before encoding, reorder the attributes so that when they
- * are encoded, they will be conforming DER, which is required
- * to have a specific order and that is what must be used for
- * the hash/signature. We do this here, rather than building
- * it into EncodeAttributes, because we do not want to do
- * such reordering on incoming messages (which also uses
- * EncodeAttributes) or our old signatures (and other "broken"
- * implementations) will not verify. So, we want to guarantee
- * that we send out good DER encodings of attributes, but not
- * to expect to receive them.
- */
- if (NSS_CMSAttributeArray_Reorder(signerinfo->authAttr) != SECSuccess)
- goto loser;
-
- encoded_attrs.data = NULL;
- encoded_attrs.len = 0;
- if (NSS_CMSAttributeArray_Encode(tmppoolp, &(signerinfo->authAttr),
- &encoded_attrs) == NULL)
- goto loser;
-
- signAlgTag = SEC_GetSignatureAlgorithmOidTag(privkey->keyType,
- digestalgtag);
- if (signAlgTag == SEC_OID_UNKNOWN) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- goto loser;
- }
-
- rv = SEC_SignData(&signature, encoded_attrs.data, encoded_attrs.len,
- privkey, signAlgTag);
- PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */
- tmppoolp = 0;
- } else {
- rv = SGN_Digest(privkey, digestalgtag, &signature, digest);
- }
- SECKEY_DestroyPrivateKey(privkey);
- privkey = NULL;
-
- if (rv != SECSuccess)
- goto loser;
-
- if (SECITEM_CopyItem(poolp, &(signerinfo->encDigest), &signature)
- != SECSuccess)
- goto loser;
-
- SECITEM_FreeItem(&signature, PR_FALSE);
-
- if (SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg), pubkAlgTag,
- NULL) != SECSuccess)
- goto loser;
-
- return SECSuccess;
-
-loser:
- if (signature.len != 0)
- SECITEM_FreeItem (&signature, PR_FALSE);
- if (privkey)
- SECKEY_DestroyPrivateKey(privkey);
- if (tmppoolp)
- PORT_FreeArena(tmppoolp, PR_FALSE);
- return SECFailure;
-}
-
-SECStatus
-NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb,
- SECCertUsage certusage)
-{
- CERTCertificate *cert;
- int64 stime;
-
- if ((cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb)) == NULL) {
- signerinfo->verificationStatus = NSSCMSVS_SigningCertNotFound;
- return SECFailure;
- }
-
- /*
- * Get and convert the signing time; if available, it will be used
- * both on the cert verification and for importing the sender
- * email profile.
- */
- if (NSS_CMSSignerInfo_GetSigningTime (signerinfo, &stime) != SECSuccess)
- stime = PR_Now(); /* not found or conversion failed, so check against now */
-
- /*
- * XXX This uses the signing time, if available. Additionally, we
- * might want to, if there is no signing time, get the message time
- * from the mail header itself, and use that. That would require
- * a change to our interface though, and for S/MIME callers to pass
- * in a time (and for non-S/MIME callers to pass in nothing, or
- * maybe make them pass in the current time, always?).
- */
- if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, stime,
- signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
- signerinfo->verificationStatus = NSSCMSVS_SigningCertNotTrusted;
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo
- *
- * Just verifies the signature. The assumption is that verification of
- * the certificate is done already.
- */
-SECStatus
-NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
- SECItem *digest, /* may be NULL */
- SECItem *contentType) /* may be NULL */
-{
- SECKEYPublicKey *publickey = NULL;
- NSSCMSAttribute *attr;
- SECItem encoded_attrs;
- CERTCertificate *cert;
- NSSCMSVerificationStatus vs = NSSCMSVS_Unverified;
- PLArenaPool *poolp;
- SECOidTag digestalgtag;
- SECOidTag pubkAlgTag;
-
- if (signerinfo == NULL)
- return SECFailure;
-
- /* NSS_CMSSignerInfo_GetSigningCertificate will fail if 2nd parm is NULL
- ** and cert has not been verified
- */
- cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, NULL);
- if (cert == NULL) {
- vs = NSSCMSVS_SigningCertNotFound;
- goto loser;
- }
-
- if ((publickey = CERT_ExtractPublicKey(cert)) == NULL) {
- vs = NSSCMSVS_ProcessingError;
- goto loser;
- }
-
- digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
- pubkAlgTag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg));
- if ((pubkAlgTag == SEC_OID_UNKNOWN) || (digestalgtag == SEC_OID_UNKNOWN)) {
- vs = NSSCMSVS_SignatureAlgorithmUnknown;
- goto loser;
- }
-
-#ifndef NSS_ECC_MORE_THAN_SUITE_B
- if (pubkAlgTag == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
- vs = NSSCMSVS_SignatureAlgorithmUnknown;
- goto loser;
- }
-#endif
-
- if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
- if (contentType) {
- /*
- * Check content type
- *
- * RFC2630 sez that if there are any authenticated attributes,
- * then there must be one for content type which matches the
- * content type of the content being signed, and there must
- * be one for message digest which matches our message digest.
- * So check these things first.
- */
- attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
- SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE);
- if (attr == NULL) {
- vs = NSSCMSVS_MalformedSignature;
- goto loser;
- }
-
- if (NSS_CMSAttribute_CompareValue(attr, contentType) == PR_FALSE) {
- vs = NSSCMSVS_MalformedSignature;
- goto loser;
- }
- }
-
- /*
- * Check digest
- */
- attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
- SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE);
- if (attr == NULL) {
- vs = NSSCMSVS_MalformedSignature;
- goto loser;
- }
- if (!digest ||
- NSS_CMSAttribute_CompareValue(attr, digest) == PR_FALSE) {
- vs = NSSCMSVS_DigestMismatch;
- goto loser;
- }
-
- if ((poolp = PORT_NewArena (1024)) == NULL) {
- vs = NSSCMSVS_ProcessingError;
- goto loser;
- }
-
- /*
- * Check signature
- *
- * The signature is based on a digest of the DER-encoded authenticated
- * attributes. So, first we encode and then we digest/verify.
- * we trust the decoder to have the attributes in the right (sorted)
- * order
- */
- encoded_attrs.data = NULL;
- encoded_attrs.len = 0;
-
- if (NSS_CMSAttributeArray_Encode(poolp, &(signerinfo->authAttr),
- &encoded_attrs) == NULL ||
- encoded_attrs.data == NULL || encoded_attrs.len == 0) {
- vs = NSSCMSVS_ProcessingError;
- goto loser;
- }
-
- vs = (VFY_VerifyDataDirect(encoded_attrs.data, encoded_attrs.len,
- publickey, &(signerinfo->encDigest), pubkAlgTag,
- digestalgtag, NULL, signerinfo->cmsg->pwfn_arg) != SECSuccess)
- ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
-
- PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */
-
- } else {
- SECItem *sig;
-
- /* No authenticated attributes.
- ** The signature is based on the plain message digest.
- */
- sig = &(signerinfo->encDigest);
- if (sig->len == 0)
- goto loser;
-
- vs = (!digest ||
- VFY_VerifyDigestDirect(digest, publickey, sig, pubkAlgTag,
- digestalgtag, signerinfo->cmsg->pwfn_arg) != SECSuccess)
- ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
- }
-
- if (vs == NSSCMSVS_BadSignature) {
- int error = PORT_GetError();
- /*
- * XXX Change the generic error into our specific one, because
- * in that case we get a better explanation out of the Security
- * Advisor. This is really a bug in the PSM error strings (the
- * "generic" error has a lousy/wrong message associated with it
- * which assumes the signature verification was done for the
- * purposes of checking the issuer signature on a certificate)
- * but this is at least an easy workaround and/or in the
- * Security Advisor, which specifically checks for the error
- * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation
- * in that case but does not similarly check for
- * SEC_ERROR_BAD_SIGNATURE. It probably should, but then would
- * probably say the wrong thing in the case that it *was* the
- * certificate signature check that failed during the cert
- * verification done above. Our error handling is really a mess.
- */
- if (error == SEC_ERROR_BAD_SIGNATURE)
- PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
- /*
- * map algorithm failures to NSSCMSVS values
- */
- if ((error == SEC_ERROR_PKCS7_KEYALG_MISMATCH) ||
- (error == SEC_ERROR_INVALID_ALGORITHM)) {
- /* keep the same error code as 3.11 and before */
- PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
- vs = NSSCMSVS_SignatureAlgorithmUnsupported;
- }
- }
-
- if (publickey != NULL)
- SECKEY_DestroyPublicKey (publickey);
-
- signerinfo->verificationStatus = vs;
-
- return (vs == NSSCMSVS_GoodSignature) ? SECSuccess : SECFailure;
-
-loser:
- if (publickey != NULL)
- SECKEY_DestroyPublicKey (publickey);
-
- signerinfo->verificationStatus = vs;
-
- PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
- return SECFailure;
-}
-
-NSSCMSVerificationStatus
-NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo)
-{
- return signerinfo->verificationStatus;
-}
-
-SECOidData *
-NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo)
-{
- SECOidData *algdata;
- SECOidTag algtag;
-
- algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
- if (algdata == NULL) {
- return algdata;
- }
- /* Windows may have given us a signer algorithm oid instead of a digest
- * algorithm oid. This call will map to a signer oid to a digest one,
- * otherwise it leaves the oid alone and let the chips fall as they may
- * if it's not a digest oid.
- */
- algtag = NSS_CMSUtil_MapSignAlgs(algdata->offset);
- if (algtag != algdata->offset) {
- /* if the tags don't match, then we must have received a signer
- * algorithID. Now we need to get the oid data for the digest
- * oid, which the rest of the code is expecting */
- algdata = SECOID_FindOIDByTag(algtag);
- }
-
- return algdata;
-
-}
-
-SECOidTag
-NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo)
-{
- SECOidData *algdata;
-
- if (!signerinfo) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SEC_OID_UNKNOWN;
- }
-
- algdata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
- if (algdata != NULL)
- return algdata->offset;
- else
- return SEC_OID_UNKNOWN;
-}
-
-CERTCertificateList *
-NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo)
-{
- return signerinfo->certList;
-}
-
-int
-NSS_CMSSignerInfo_GetVersion(NSSCMSSignerInfo *signerinfo)
-{
- unsigned long version;
-
- /* always take apart the SECItem */
- if (SEC_ASN1DecodeInteger(&(signerinfo->version), &version) != SECSuccess)
- return 0;
- else
- return (int)version;
-}
-
-/*
- * NSS_CMSSignerInfo_GetSigningTime - return the signing time,
- * in UTCTime or GeneralizedTime format,
- * of a CMS signerInfo.
- *
- * sinfo - signerInfo data for this signer
- *
- * Returns a pointer to XXXX (what?)
- * A return value of NULL is an error.
- */
-SECStatus
-NSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime)
-{
- NSSCMSAttribute *attr;
- SECItem *value;
-
- if (sinfo == NULL)
- return SECFailure;
-
- if (sinfo->signingTime != 0) {
- *stime = sinfo->signingTime; /* cached copy */
- return SECSuccess;
- }
-
- attr = NSS_CMSAttributeArray_FindAttrByOidTag(sinfo->authAttr, SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);
- /* XXXX multi-valued attributes NIH */
- if (attr == NULL || (value = NSS_CMSAttribute_GetValue(attr)) == NULL)
- return SECFailure;
- if (DER_DecodeTimeChoice(stime, value) != SECSuccess)
- return SECFailure;
- sinfo->signingTime = *stime; /* make cached copy */
- return SECSuccess;
-}
-
-/*
- * Return the signing cert of a CMS signerInfo.
- *
- * the certs in the enclosing SignedData must have been imported already
- */
-CERTCertificate *
-NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb)
-{
- CERTCertificate *cert;
- NSSCMSSignerIdentifier *sid;
-
- if (signerinfo->cert != NULL)
- return signerinfo->cert;
-
- /* no certdb, and cert hasn't been set yet? */
- if (certdb == NULL)
- return NULL;
-
- /*
- * This cert will also need to be freed, but since we save it
- * in signerinfo for later, we do not want to destroy it when
- * we leave this function -- we let the clean-up of the entire
- * cinfo structure later do the destroy of this cert.
- */
- sid = &signerinfo->signerIdentifier;
- switch (sid->identifierType) {
- case NSSCMSSignerID_IssuerSN:
- cert = CERT_FindCertByIssuerAndSN(certdb, sid->id.issuerAndSN);
- break;
- case NSSCMSSignerID_SubjectKeyID:
- cert = CERT_FindCertBySubjectKeyID(certdb, sid->id.subjectKeyID);
- break;
- default:
- cert = NULL;
- break;
- }
-
- /* cert can be NULL at that point */
- signerinfo->cert = cert; /* earmark it */
-
- return cert;
-}
-
-/*
- * NSS_CMSSignerInfo_GetSignerCommonName - return the common name of the signer
- *
- * sinfo - signerInfo data for this signer
- *
- * Returns a pointer to allocated memory, which must be freed with PORT_Free.
- * A return value of NULL is an error.
- */
-char *
-NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo)
-{
- CERTCertificate *signercert;
-
- /* will fail if cert is not verified */
- if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
- return NULL;
-
- return (CERT_GetCommonName(&signercert->subject));
-}
-
-/*
- * NSS_CMSSignerInfo_GetSignerEmailAddress - return the common name of the signer
- *
- * sinfo - signerInfo data for this signer
- *
- * Returns a pointer to allocated memory, which must be freed.
- * A return value of NULL is an error.
- */
-char *
-NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo)
-{
- CERTCertificate *signercert;
-
- if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
- return NULL;
-
- if (!signercert->emailAddr || !signercert->emailAddr[0])
- return NULL;
-
- return (PORT_Strdup(signercert->emailAddr));
-}
-
-/*
- * NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
- */
-SECStatus
-NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
-{
- return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->authAttr), attr);
-}
-
-/*
- * NSS_CMSSignerInfo_AddUnauthAttr - add an attribute to the
- * unauthenticated attributes of "signerinfo".
- */
-SECStatus
-NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
-{
- return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->unAuthAttr), attr);
-}
-
-/*
- * NSS_CMSSignerInfo_AddSigningTime - add the signing time to the
- * authenticated (i.e. signed) attributes of "signerinfo".
- *
- * This is expected to be included in outgoing signed
- * messages for email (S/MIME) but is likely useful in other situations.
- *
- * This should only be added once; a second call will do nothing.
- *
- * XXX This will probably just shove the current time into "signerinfo"
- * but it will not actually get signed until the entire item is
- * processed for encoding. Is this (expected to be small) delay okay?
- */
-SECStatus
-NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t)
-{
- NSSCMSAttribute *attr;
- SECItem stime;
- void *mark;
- PLArenaPool *poolp;
-
- poolp = signerinfo->cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- /* create new signing time attribute */
- if (DER_EncodeTimeChoice(NULL, &stime, t) != SECSuccess)
- goto loser;
-
- if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) {
- SECITEM_FreeItem (&stime, PR_FALSE);
- goto loser;
- }
-
- SECITEM_FreeItem (&stime, PR_FALSE);
-
- if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark (poolp, mark);
-
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease (poolp, mark);
- return SECFailure;
-}
-
-/*
- * NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
- *
- * This is expected to be included in outgoing signed
- * messages for email (S/MIME).
- */
-SECStatus
-NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo)
-{
- NSSCMSAttribute *attr;
- SECItem *smimecaps = NULL;
- void *mark;
- PLArenaPool *poolp;
-
- poolp = signerinfo->cmsg->poolp;
-
- mark = PORT_ArenaMark(poolp);
-
- smimecaps = SECITEM_AllocItem(poolp, NULL, 0);
- if (smimecaps == NULL)
- goto loser;
-
- /* create new signing time attribute */
- if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps) != SECSuccess)
- goto loser;
-
- if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL)
- goto loser;
-
- if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark (poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease (poolp, mark);
- return SECFailure;
-}
-
-/*
- * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo".
- *
- * This is expected to be included in outgoing signed messages for email (S/MIME).
- */
-SECStatus
-NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb)
-{
- NSSCMSAttribute *attr;
- SECItem *smimeekp = NULL;
- void *mark;
- PLArenaPool *poolp;
-
- /* verify this cert for encryption */
- if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
- return SECFailure;
- }
-
- poolp = signerinfo->cmsg->poolp;
- mark = PORT_ArenaMark(poolp);
-
- smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
- if (smimeekp == NULL)
- goto loser;
-
- /* create new signing time attribute */
- if (NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
- goto loser;
-
- if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
- goto loser;
-
- if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark (poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease (poolp, mark);
- return SECFailure;
-}
-
-/*
- * NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
- * authenticated (i.e. signed) attributes of "signerinfo", using the OID preferred by Microsoft.
- *
- * This is expected to be included in outgoing signed messages for email (S/MIME),
- * if compatibility with Microsoft mail clients is wanted.
- */
-SECStatus
-NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb)
-{
- NSSCMSAttribute *attr;
- SECItem *smimeekp = NULL;
- void *mark;
- PLArenaPool *poolp;
-
- /* verify this cert for encryption */
- if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
- return SECFailure;
- }
-
- poolp = signerinfo->cmsg->poolp;
- mark = PORT_ArenaMark(poolp);
-
- smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
- if (smimeekp == NULL)
- goto loser;
-
- /* create new signing time attribute */
- if (NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
- goto loser;
-
- if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
- goto loser;
-
- if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
- goto loser;
-
- PORT_ArenaUnmark (poolp, mark);
- return SECSuccess;
-
-loser:
- PORT_ArenaRelease (poolp, mark);
- return SECFailure;
-}
-
-/*
- * NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo
- *
- * 1. digest the DER-encoded signature value of the original signerinfo
- * 2. create new signerinfo with correct version, sid, digestAlg
- * 3. add message-digest authAttr, but NO content-type
- * 4. sign the authAttrs
- * 5. DER-encode the new signerInfo
- * 6. add the whole thing to original signerInfo's unAuthAttrs
- * as a SEC_OID_PKCS9_COUNTER_SIGNATURE attribute
- *
- * XXXX give back the new signerinfo?
- */
-SECStatus
-NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo,
- SECOidTag digestalg, CERTCertificate signingcert)
-{
- /* XXXX TBD XXXX */
- return SECFailure;
-}
-
-/*
- * XXXX the following needs to be done in the S/MIME layer code
- * after signature of a signerinfo is verified
- */
-SECStatus
-NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo)
-{
- CERTCertificate *cert = NULL;
- SECItem *profile = NULL;
- NSSCMSAttribute *attr;
- SECItem *stime = NULL;
- SECItem *ekp;
- CERTCertDBHandle *certdb;
- int save_error;
- SECStatus rv;
- PRBool must_free_cert = PR_FALSE;
-
- certdb = CERT_GetDefaultCertDB();
-
- /* sanity check - see if verification status is ok (unverified does not count...) */
- if (signerinfo->verificationStatus != NSSCMSVS_GoodSignature)
- return SECFailure;
-
- /* find preferred encryption cert */
- if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr) &&
- (attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
- SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, PR_TRUE)) != NULL)
- { /* we have a SMIME_ENCRYPTION_KEY_PREFERENCE attribute! */
- ekp = NSS_CMSAttribute_GetValue(attr);
- if (ekp == NULL)
- return SECFailure;
-
- /* we assume that all certs coming with the message have been imported to the */
- /* temporary database */
- cert = NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(certdb, ekp);
- if (cert == NULL)
- return SECFailure;
- must_free_cert = PR_TRUE;
- }
-
- if (cert == NULL) {
- /* no preferred cert found?
- * find the cert the signerinfo is signed with instead */
- cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb);
- if (cert == NULL || cert->emailAddr == NULL || !cert->emailAddr[0])
- return SECFailure;
- }
-
- /* verify this cert for encryption (has been verified for signing so far) */
- /* don't verify this cert for encryption. It may just be a signing cert.
- * that's OK, we can still save the S/MIME profile. The encryption cert
- * should have already been saved */
-#ifdef notdef
- if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
- if (must_free_cert)
- CERT_DestroyCertificate(cert);
- return SECFailure;
- }
-#endif
-
- /* XXX store encryption cert permanently? */
-
- /*
- * Remember the current error set because we do not care about
- * anything set by the functions we are about to call.
- */
- save_error = PORT_GetError();
-
- if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
- attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
- SEC_OID_PKCS9_SMIME_CAPABILITIES,
- PR_TRUE);
- profile = NSS_CMSAttribute_GetValue(attr);
- attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
- SEC_OID_PKCS9_SIGNING_TIME,
- PR_TRUE);
- stime = NSS_CMSAttribute_GetValue(attr);
- }
-
- rv = CERT_SaveSMimeProfile (cert, profile, stime);
- if (must_free_cert)
- CERT_DestroyCertificate(cert);
-
- /*
- * Restore the saved error in case the calls above set a new
- * one that we do not actually care about.
- */
- PORT_SetError (save_error);
-
- return rv;
-}
-
-/*
- * NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer
- */
-SECStatus
-NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage)
-{
- if (signerinfo->cert == NULL)
- return SECFailure;
-
- /* don't leak if we get called twice */
- if (signerinfo->certList != NULL) {
- CERT_DestroyCertificateList(signerinfo->certList);
- signerinfo->certList = NULL;
- }
-
- switch (cm) {
- case NSSCMSCM_None:
- signerinfo->certList = NULL;
- break;
- case NSSCMSCM_CertOnly:
- signerinfo->certList = CERT_CertListFromCert(signerinfo->cert);
- break;
- case NSSCMSCM_CertChain:
- signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE);
- break;
- case NSSCMSCM_CertChainWithRoot:
- signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE);
- break;
- }
-
- if (cm != NSSCMSCM_None && signerinfo->certList == NULL)
- return SECFailure;
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/smime/cmst.h b/security/nss/lib/smime/cmst.h
deleted file mode 100644
index 12d05fdae..000000000
--- a/security/nss/lib/smime/cmst.h
+++ /dev/null
@@ -1,498 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Header for CMS types.
- *
- * $Id$
- */
-
-#ifndef _CMST_H_
-#define _CMST_H_
-
-#include "seccomon.h"
-#include "secoidt.h"
-#include "certt.h"
-#include "secmodt.h"
-#include "secmodt.h"
-
-#include "plarena.h"
-
-/* Non-opaque objects. NOTE, though: I want them to be treated as
- * opaque as much as possible. If I could hide them completely,
- * I would. (I tried, but ran into trouble that was taking me too
- * much time to get out of.) I still intend to try to do so.
- * In fact, the only type that "outsiders" should even *name* is
- * NSSCMSMessage, and they should not reference its fields.
- */
-/* rjr: PKCS #11 cert handling (pk11cert.c) does use NSSCMSRecipientInfo's.
- * This is because when we search the recipient list for the cert and key we
- * want, we need to invert the order of the loops we used to have. The old
- * loops were:
- *
- * For each recipient {
- * find_cert = PK11_Find_AllCert(recipient->issuerSN);
- * [which unrolls to... ]
- * For each slot {
- * Log into slot;
- * search slot for cert;
- * }
- * }
- *
- * the new loop searchs all the recipients at once on a slot. this allows
- * PKCS #11 to order slots in such a way that logout slots don't get checked
- * if we can find the cert on a logged in slot. This eliminates lots of
- * spurious password prompts when smart cards are installed... so why this
- * comment? If you make NSSCMSRecipientInfo completely opaque, you need
- * to provide a non-opaque list of issuerSN's (the only field PKCS#11 needs
- * and fix up pk11cert.c first. NOTE: Only S/MIME calls this special PKCS #11
- * function.
- */
-
-typedef struct NSSCMSMessageStr NSSCMSMessage;
-
-typedef union NSSCMSContentUnion NSSCMSContent;
-typedef struct NSSCMSContentInfoStr NSSCMSContentInfo;
-
-typedef struct NSSCMSSignedDataStr NSSCMSSignedData;
-typedef struct NSSCMSSignerInfoStr NSSCMSSignerInfo;
-typedef struct NSSCMSSignerIdentifierStr NSSCMSSignerIdentifier;
-
-typedef struct NSSCMSEnvelopedDataStr NSSCMSEnvelopedData;
-typedef struct NSSCMSOriginatorInfoStr NSSCMSOriginatorInfo;
-typedef struct NSSCMSRecipientInfoStr NSSCMSRecipientInfo;
-
-typedef struct NSSCMSDigestedDataStr NSSCMSDigestedData;
-typedef struct NSSCMSEncryptedDataStr NSSCMSEncryptedData;
-
-typedef struct NSSCMSGenericWrapperDataStr NSSCMSGenericWrapperData;
-
-typedef struct NSSCMSAttributeStr NSSCMSAttribute;
-
-typedef struct NSSCMSDecoderContextStr NSSCMSDecoderContext;
-typedef struct NSSCMSEncoderContextStr NSSCMSEncoderContext;
-
-typedef struct NSSCMSCipherContextStr NSSCMSCipherContext;
-typedef struct NSSCMSDigestContextStr NSSCMSDigestContext;
-
-typedef struct NSSCMSContentInfoPrivateStr NSSCMSContentInfoPrivate;
-
-typedef SECStatus (*NSSCMSGenericWrapperDataCallback)
- (NSSCMSGenericWrapperData *);
-typedef void (*NSSCMSGenericWrapperDataDestroy)
- (NSSCMSGenericWrapperData *);
-
-extern const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[];
-extern const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[];
-
-SEC_ASN1_CHOOSER_DECLARE(NSS_PointerToCMSGenericWrapperDataTemplate)
-SEC_ASN1_CHOOSER_DECLARE(NSSCMSGenericWrapperDataTemplate)
-
-
-
-/*
- * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart.
- * If specified, this is where the content bytes (only) will be "sent"
- * as they are recovered during the decoding.
- * And:
- * Type of function passed to NSSCMSEncode or NSSCMSEncoderStart.
- * This is where the DER-encoded bytes will be "sent".
- *
- * XXX Should just combine this with NSSCMSEncoderContentCallback type
- * and use a simpler, common name.
- */
-typedef void (*NSSCMSContentCallback)(void *arg, const char *buf, unsigned long len);
-
-/*
- * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart
- * to retrieve the decryption key. This function is intended to be
- * used for EncryptedData content info's which do not have a key available
- * in a certificate, etc.
- */
-typedef PK11SymKey *(*NSSCMSGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid);
-
-
-/* =============================================================================
- * ENCAPSULATED CONTENTINFO & CONTENTINFO
- */
-
-union NSSCMSContentUnion {
- /* either unstructured */
- SECItem * data;
- /* or structured data */
- NSSCMSDigestedData * digestedData;
- NSSCMSEncryptedData * encryptedData;
- NSSCMSEnvelopedData * envelopedData;
- NSSCMSSignedData * signedData;
- NSSCMSGenericWrapperData * genericData;
- /* or anonymous pointer to something */
- void * pointer;
-};
-
-struct NSSCMSContentInfoStr {
- SECItem contentType;
- NSSCMSContent content;
- /* --------- local; not part of encoding --------- */
- SECOidData * contentTypeTag;
-
- /* additional info for encryptedData and envelopedData */
- /* we waste this space for signedData and digestedData. sue me. */
-
- SECAlgorithmID contentEncAlg;
- SECItem * rawContent; /* encrypted DER, optional */
- /* XXXX bytes not encrypted, but encoded? */
- /* --------- local; not part of encoding --------- */
- PK11SymKey * bulkkey; /* bulk encryption key */
- int keysize; /* size of bulk encryption key
- * (only used by creation code) */
- SECOidTag contentEncAlgTag; /* oid tag of encryption algorithm
- * (only used by creation code) */
- NSSCMSContentInfoPrivate *privateInfo; /* place for NSS private info */
- void *reserved; /* keep binary compatibility */
-};
-
-/* =============================================================================
- * MESSAGE
- */
-
-struct NSSCMSMessageStr {
- NSSCMSContentInfo contentInfo; /* "outer" cinfo */
- /* --------- local; not part of encoding --------- */
- PLArenaPool * poolp;
- PRBool poolp_is_ours;
- int refCount;
- /* properties of the "inner" data */
- SECAlgorithmID ** detached_digestalgs;
- SECItem ** detached_digests;
- void * pwfn_arg;
- NSSCMSGetDecryptKeyCallback decrypt_key_cb;
- void * decrypt_key_cb_arg;
-};
-
-/* ============================================================================
- * GENERIC WRAPPER
- *
- * used for user defined types.
- */
-struct NSSCMSGenericWrapperDataStr {
- NSSCMSContentInfo contentInfo;
- /* ---- local; not part of encoding ------ */
- NSSCMSMessage * cmsg;
- /* wrapperspecific data starts here */
-};
-
-/* =============================================================================
- * SIGNEDDATA
- */
-
-struct NSSCMSSignedDataStr {
- SECItem version;
- SECAlgorithmID ** digestAlgorithms;
- NSSCMSContentInfo contentInfo;
- SECItem ** rawCerts;
- CERTSignedCrl ** crls;
- NSSCMSSignerInfo ** signerInfos;
- /* --------- local; not part of encoding --------- */
- NSSCMSMessage * cmsg; /* back pointer to message */
- SECItem ** digests;
- CERTCertificate ** certs;
- CERTCertificateList ** certLists;
- CERTCertificate ** tempCerts; /* temporary certs, needed
- * for example for signature
- * verification */
-};
-#define NSS_CMS_SIGNED_DATA_VERSION_BASIC 1 /* what we *create* */
-#define NSS_CMS_SIGNED_DATA_VERSION_EXT 3 /* what we *create* */
-
-typedef enum {
- NSSCMSVS_Unverified = 0,
- NSSCMSVS_GoodSignature = 1,
- NSSCMSVS_BadSignature = 2,
- NSSCMSVS_DigestMismatch = 3,
- NSSCMSVS_SigningCertNotFound = 4,
- NSSCMSVS_SigningCertNotTrusted = 5,
- NSSCMSVS_SignatureAlgorithmUnknown = 6,
- NSSCMSVS_SignatureAlgorithmUnsupported = 7,
- NSSCMSVS_MalformedSignature = 8,
- NSSCMSVS_ProcessingError = 9
-} NSSCMSVerificationStatus;
-
-typedef enum {
- NSSCMSSignerID_IssuerSN = 0,
- NSSCMSSignerID_SubjectKeyID = 1
-} NSSCMSSignerIDSelector;
-
-struct NSSCMSSignerIdentifierStr {
- NSSCMSSignerIDSelector identifierType;
- union {
- CERTIssuerAndSN *issuerAndSN;
- SECItem *subjectKeyID;
- } id;
-};
-
-struct NSSCMSSignerInfoStr {
- SECItem version;
- NSSCMSSignerIdentifier signerIdentifier;
- SECAlgorithmID digestAlg;
- NSSCMSAttribute ** authAttr;
- SECAlgorithmID digestEncAlg;
- SECItem encDigest;
- NSSCMSAttribute ** unAuthAttr;
- /* --------- local; not part of encoding --------- */
- NSSCMSMessage * cmsg; /* back pointer to message */
- CERTCertificate * cert;
- CERTCertificateList * certList;
- PRTime signingTime;
- NSSCMSVerificationStatus verificationStatus;
- SECKEYPrivateKey * signingKey; /* Used if we're using subjKeyID*/
- SECKEYPublicKey * pubKey;
-};
-#define NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */
-#define NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */
-
-typedef enum {
- NSSCMSCM_None = 0,
- NSSCMSCM_CertOnly = 1,
- NSSCMSCM_CertChain = 2,
- NSSCMSCM_CertChainWithRoot = 3
-} NSSCMSCertChainMode;
-
-/* =============================================================================
- * ENVELOPED DATA
- */
-struct NSSCMSEnvelopedDataStr {
- SECItem version;
- NSSCMSOriginatorInfo * originatorInfo; /* optional */
- NSSCMSRecipientInfo ** recipientInfos;
- NSSCMSContentInfo contentInfo;
- NSSCMSAttribute ** unprotectedAttr;
- /* --------- local; not part of encoding --------- */
- NSSCMSMessage * cmsg; /* back pointer to message */
-};
-#define NSS_CMS_ENVELOPED_DATA_VERSION_REG 0 /* what we *create* */
-#define NSS_CMS_ENVELOPED_DATA_VERSION_ADV 2 /* what we *create* */
-
-struct NSSCMSOriginatorInfoStr {
- SECItem ** rawCerts;
- CERTSignedCrl ** crls;
- /* --------- local; not part of encoding --------- */
- CERTCertificate ** certs;
-};
-
-/* -----------------------------------------------------------------------------
- * key transport recipient info
- */
-typedef enum {
- NSSCMSRecipientID_IssuerSN = 0,
- NSSCMSRecipientID_SubjectKeyID = 1,
- NSSCMSRecipientID_BrandNew = 2
-} NSSCMSRecipientIDSelector;
-
-struct NSSCMSRecipientIdentifierStr {
- NSSCMSRecipientIDSelector identifierType;
- union {
- CERTIssuerAndSN *issuerAndSN;
- SECItem *subjectKeyID;
- } id;
-};
-typedef struct NSSCMSRecipientIdentifierStr NSSCMSRecipientIdentifier;
-
-struct NSSCMSKeyTransRecipientInfoStr {
- SECItem version;
- NSSCMSRecipientIdentifier recipientIdentifier;
- SECAlgorithmID keyEncAlg;
- SECItem encKey;
-};
-typedef struct NSSCMSKeyTransRecipientInfoStr NSSCMSKeyTransRecipientInfo;
-
-/*
- * View comments before NSSCMSRecipientInfoStr for purpose of this
- * structure.
- */
-struct NSSCMSKeyTransRecipientInfoExStr {
- NSSCMSKeyTransRecipientInfo recipientInfo;
- int version; /* version of this structure (0) */
- SECKEYPublicKey *pubKey;
-};
-
-typedef struct NSSCMSKeyTransRecipientInfoExStr NSSCMSKeyTransRecipientInfoEx;
-
-#define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN 0 /* what we *create* */
-#define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY 2 /* what we *create* */
-
-/* -----------------------------------------------------------------------------
- * key agreement recipient info
- */
-struct NSSCMSOriginatorPublicKeyStr {
- SECAlgorithmID algorithmIdentifier;
- SECItem publicKey; /* bit string! */
-};
-typedef struct NSSCMSOriginatorPublicKeyStr NSSCMSOriginatorPublicKey;
-
-typedef enum {
- NSSCMSOriginatorIDOrKey_IssuerSN = 0,
- NSSCMSOriginatorIDOrKey_SubjectKeyID = 1,
- NSSCMSOriginatorIDOrKey_OriginatorPublicKey = 2
-} NSSCMSOriginatorIDOrKeySelector;
-
-struct NSSCMSOriginatorIdentifierOrKeyStr {
- NSSCMSOriginatorIDOrKeySelector identifierType;
- union {
- CERTIssuerAndSN *issuerAndSN; /* static-static */
- SECItem *subjectKeyID; /* static-static */
- NSSCMSOriginatorPublicKey originatorPublicKey; /* ephemeral-static */
- } id;
-};
-typedef struct NSSCMSOriginatorIdentifierOrKeyStr NSSCMSOriginatorIdentifierOrKey;
-
-struct NSSCMSRecipientKeyIdentifierStr {
- SECItem * subjectKeyIdentifier;
- SECItem * date; /* optional */
- SECItem * other; /* optional */
-};
-typedef struct NSSCMSRecipientKeyIdentifierStr NSSCMSRecipientKeyIdentifier;
-
-typedef enum {
- NSSCMSKeyAgreeRecipientID_IssuerSN = 0,
- NSSCMSKeyAgreeRecipientID_RKeyID = 1
-} NSSCMSKeyAgreeRecipientIDSelector;
-
-struct NSSCMSKeyAgreeRecipientIdentifierStr {
- NSSCMSKeyAgreeRecipientIDSelector identifierType;
- union {
- CERTIssuerAndSN *issuerAndSN;
- NSSCMSRecipientKeyIdentifier recipientKeyIdentifier;
- } id;
-};
-typedef struct NSSCMSKeyAgreeRecipientIdentifierStr NSSCMSKeyAgreeRecipientIdentifier;
-
-struct NSSCMSRecipientEncryptedKeyStr {
- NSSCMSKeyAgreeRecipientIdentifier recipientIdentifier;
- SECItem encKey;
-};
-typedef struct NSSCMSRecipientEncryptedKeyStr NSSCMSRecipientEncryptedKey;
-
-struct NSSCMSKeyAgreeRecipientInfoStr {
- SECItem version;
- NSSCMSOriginatorIdentifierOrKey originatorIdentifierOrKey;
- SECItem * ukm; /* optional */
- SECAlgorithmID keyEncAlg;
- NSSCMSRecipientEncryptedKey ** recipientEncryptedKeys;
-};
-typedef struct NSSCMSKeyAgreeRecipientInfoStr NSSCMSKeyAgreeRecipientInfo;
-
-#define NSS_CMS_KEYAGREE_RECIPIENT_INFO_VERSION 3 /* what we *create* */
-
-/* -----------------------------------------------------------------------------
- * KEK recipient info
- */
-struct NSSCMSKEKIdentifierStr {
- SECItem keyIdentifier;
- SECItem * date; /* optional */
- SECItem * other; /* optional */
-};
-typedef struct NSSCMSKEKIdentifierStr NSSCMSKEKIdentifier;
-
-struct NSSCMSKEKRecipientInfoStr {
- SECItem version;
- NSSCMSKEKIdentifier kekIdentifier;
- SECAlgorithmID keyEncAlg;
- SECItem encKey;
-};
-typedef struct NSSCMSKEKRecipientInfoStr NSSCMSKEKRecipientInfo;
-
-#define NSS_CMS_KEK_RECIPIENT_INFO_VERSION 4 /* what we *create* */
-
-/* -----------------------------------------------------------------------------
- * recipient info
- */
-
-typedef enum {
- NSSCMSRecipientInfoID_KeyTrans = 0,
- NSSCMSRecipientInfoID_KeyAgree = 1,
- NSSCMSRecipientInfoID_KEK = 2
-} NSSCMSRecipientInfoIDSelector;
-
-/*
- * In order to preserve backwards binary compatibility when implementing
- * creation of Recipient Info's that uses subjectKeyID in the
- * keyTransRecipientInfo we need to stash a public key pointer in this
- * structure somewhere. We figured out that NSSCMSKeyTransRecipientInfo
- * is the smallest member of the ri union. We're in luck since that's
- * the very structure that would need to use the public key. So we created
- * a new structure NSSCMSKeyTransRecipientInfoEx which has a member
- * NSSCMSKeyTransRecipientInfo as the first member followed by a version
- * and a public key pointer. This way we can keep backwards compatibility
- * without changing the size of this structure.
- *
- * BTW, size of structure:
- * NSSCMSKeyTransRecipientInfo: 9 ints, 4 pointers
- * NSSCMSKeyAgreeRecipientInfo: 12 ints, 8 pointers
- * NSSCMSKEKRecipientInfo: 10 ints, 7 pointers
- *
- * The new structure:
- * NSSCMSKeyTransRecipientInfoEx: sizeof(NSSCMSKeyTransRecipientInfo) +
- * 1 int, 1 pointer
- */
-
-struct NSSCMSRecipientInfoStr {
- NSSCMSRecipientInfoIDSelector recipientInfoType;
- union {
- NSSCMSKeyTransRecipientInfo keyTransRecipientInfo;
- NSSCMSKeyAgreeRecipientInfo keyAgreeRecipientInfo;
- NSSCMSKEKRecipientInfo kekRecipientInfo;
- NSSCMSKeyTransRecipientInfoEx keyTransRecipientInfoEx;
- } ri;
- /* --------- local; not part of encoding --------- */
- NSSCMSMessage * cmsg; /* back pointer to message */
- CERTCertificate * cert; /* recipient's certificate */
-};
-
-/* =============================================================================
- * DIGESTED DATA
- */
-struct NSSCMSDigestedDataStr {
- SECItem version;
- SECAlgorithmID digestAlg;
- NSSCMSContentInfo contentInfo;
- SECItem digest;
- /* --------- local; not part of encoding --------- */
- NSSCMSMessage * cmsg; /* back pointer */
- SECItem cdigest; /* calculated digest */
-};
-#define NSS_CMS_DIGESTED_DATA_VERSION_DATA 0 /* what we *create* */
-#define NSS_CMS_DIGESTED_DATA_VERSION_ENCAP 2 /* what we *create* */
-
-/* =============================================================================
- * ENCRYPTED DATA
- */
-struct NSSCMSEncryptedDataStr {
- SECItem version;
- NSSCMSContentInfo contentInfo;
- NSSCMSAttribute ** unprotectedAttr; /* optional */
- /* --------- local; not part of encoding --------- */
- NSSCMSMessage * cmsg; /* back pointer */
-};
-#define NSS_CMS_ENCRYPTED_DATA_VERSION 0 /* what we *create* */
-#define NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR 2 /* what we *create* */
-
-/*
- * *****************************************************************************
- * *****************************************************************************
- * *****************************************************************************
- */
-
-/*
- * See comment above about this type not really belonging to CMS.
- */
-struct NSSCMSAttributeStr {
- /* The following fields make up an encoded Attribute: */
- SECItem type;
- SECItem ** values; /* data may or may not be encoded */
- /* The following fields are not part of an encoded Attribute: */
- SECOidData * typeTag;
- PRBool encoded; /* when true, values are encoded */
-};
-
-#endif /* _CMST_H_ */
diff --git a/security/nss/lib/smime/cmsudf.c b/security/nss/lib/smime/cmsudf.c
deleted file mode 100644
index ee55398a3..000000000
--- a/security/nss/lib/smime/cmsudf.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS User Define Types
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "prinit.h"
-#include "pk11func.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "secerr.h"
-#include "nss.h"
-
-typedef struct nsscmstypeInfoStr nsscmstypeInfo;
-struct nsscmstypeInfoStr {
- SECOidTag type;
- SEC_ASN1Template *template;
- size_t size;
- PRBool isData;
- NSSCMSGenericWrapperDataDestroy destroy;
- NSSCMSGenericWrapperDataCallback decode_before;
- NSSCMSGenericWrapperDataCallback decode_after;
- NSSCMSGenericWrapperDataCallback decode_end;
- NSSCMSGenericWrapperDataCallback encode_start;
- NSSCMSGenericWrapperDataCallback encode_before;
- NSSCMSGenericWrapperDataCallback encode_after;
-};
-
-/* make sure the global tables are only initialized once */
-static PRCallOnceType nsscmstypeOnce;
-static PRCallOnceType nsscmstypeClearOnce;
-/* lock for adding a new entry */
-static PRLock *nsscmstypeAddLock;
-/* lock for the hash table */
-static PRLock *nsscmstypeHashLock;
-/* the hash table itself */
-static PLHashTable *nsscmstypeHash;
-/* arena to hold all the hash table data */
-static PRArenaPool *nsscmstypeArena;
-
-/*
- * clean up our global tables
- */
-SECStatus
-nss_cmstype_shutdown(void *appData, void *reserved)
-{
- if (nsscmstypeHashLock) {
- PR_Lock(nsscmstypeHashLock);
- }
- if (nsscmstypeHash) {
- PL_HashTableDestroy(nsscmstypeHash);
- nsscmstypeHash = NULL;
- }
- if (nsscmstypeArena) {
- PORT_FreeArena(nsscmstypeArena, PR_FALSE);
- nsscmstypeArena = NULL;
- }
- if (nsscmstypeAddLock) {
- PR_DestroyLock(nsscmstypeAddLock);
- }
- if (nsscmstypeHashLock) {
- PRLock *oldLock = nsscmstypeHashLock;
- nsscmstypeHashLock = NULL;
- PR_Unlock(oldLock);
- PR_DestroyLock(oldLock);
- }
-
- /* don't clear out the PR_ONCE data if we failed our inital call */
- if (appData == NULL) {
- nsscmstypeOnce = nsscmstypeClearOnce;
- }
- return SECSuccess;
-}
-
-static PLHashNumber
-nss_cmstype_hash_key(const void *key)
-{
- return (PLHashNumber) key;
-}
-
-static PRIntn
-nss_cmstype_compare_keys(const void *v1, const void *v2)
-{
- PLHashNumber value1 = (PLHashNumber) v1;
- PLHashNumber value2 = (PLHashNumber) v2;
-
- return (value1 == value2);
-}
-
-/*
- * initialize our hash tables, called once on the first attemat to register
- * a new SMIME type.
- */
-static PRStatus
-nss_cmstype_init(void)
-{
- SECStatus rv;
-
- nsscmstypeHashLock = PR_NewLock();
- if (nsscmstypeHashLock == NULL) {
- return PR_FAILURE;
- }
- nsscmstypeAddLock = PR_NewLock();
- if (nsscmstypeHashLock == NULL) {
- goto fail;
- }
- nsscmstypeHash = PL_NewHashTable(64, nss_cmstype_hash_key,
- nss_cmstype_compare_keys, PL_CompareValues, NULL, NULL);
- if (nsscmstypeHash == NULL) {
- goto fail;
- }
- nsscmstypeArena = PORT_NewArena(2048);
- if (nsscmstypeArena == NULL) {
- goto fail;
- }
- rv = NSS_RegisterShutdown(nss_cmstype_shutdown, NULL);
- if (rv != SECSuccess) {
- goto fail;
- }
- return PR_SUCCESS;
-
-fail:
- nss_cmstype_shutdown(&nsscmstypeOnce, NULL);
- return PR_FAILURE;
-}
-
-
-/*
- * look up and registered SIME type
- */
-static const nsscmstypeInfo *
-nss_cmstype_lookup(SECOidTag type)
-{
- nsscmstypeInfo *typeInfo = NULL;;
- if (!nsscmstypeHash) {
- return NULL;
- }
- PR_Lock(nsscmstypeHashLock);
- if (nsscmstypeHash) {
- typeInfo = PL_HashTableLookupConst(nsscmstypeHash, (void *)type);
- }
- PR_Unlock(nsscmstypeHashLock);
- return typeInfo;
-}
-
-/*
- * add a new type to the SMIME type table
- */
-static SECStatus
-nss_cmstype_add(SECOidTag type, nsscmstypeInfo *typeinfo)
-{
- PLHashEntry *entry;
-
- if (!nsscmstypeHash) {
- /* assert? this shouldn't happen */
- return SECFailure;
- }
- PR_Lock(nsscmstypeHashLock);
- /* this is really paranoia. If we really are racing nsscmstypeHash, we'll
- * also be racing nsscmstypeHashLock... */
- if (!nsscmstypeHash) {
- PR_Unlock(nsscmstypeHashLock);
- return SECFailure;
- }
- entry = PL_HashTableAdd(nsscmstypeHash, (void *)type, typeinfo);
- PR_Unlock(nsscmstypeHashLock);
- return entry ? SECSuccess : SECFailure;
-}
-
-
-/* helper functions to manage new content types
- */
-
-PRBool
-NSS_CMSType_IsWrapper(SECOidTag type)
-{
- const nsscmstypeInfo *typeInfo = NULL;
-
- switch (type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- case SEC_OID_PKCS7_DIGESTED_DATA:
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- return PR_TRUE;
- default:
- typeInfo = nss_cmstype_lookup(type);
- if (typeInfo && !typeInfo->isData) {
- return PR_TRUE;
- }
- }
- return PR_FALSE;
-}
-
-PRBool
-NSS_CMSType_IsData(SECOidTag type)
-{
- const nsscmstypeInfo *typeInfo = NULL;
-
- switch (type) {
- case SEC_OID_PKCS7_DATA:
- return PR_TRUE;
- default:
- typeInfo = nss_cmstype_lookup(type);
- if (typeInfo && typeInfo->isData) {
- return PR_TRUE;
- }
- }
- return PR_FALSE;
-}
-
-const SEC_ASN1Template *
-NSS_CMSType_GetTemplate(SECOidTag type)
-{
- const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type);
-
- if (typeInfo && typeInfo->template) {
- return typeInfo->template;
- }
- return SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
-}
-
-size_t
-NSS_CMSType_GetContentSize(SECOidTag type)
-{
- const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type);
-
- if (typeInfo) {
- return typeInfo->size;
- }
- return sizeof(SECItem *);
-
-}
-
-void
-NSS_CMSGenericWrapperData_Destroy(SECOidTag type, NSSCMSGenericWrapperData *gd)
-{
- const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type);
-
- if (typeInfo && typeInfo->destroy) {
- (*typeInfo->destroy)(gd);
- }
-
-}
-
-
-SECStatus
-NSS_CMSGenericWrapperData_Decode_BeforeData(SECOidTag type,
- NSSCMSGenericWrapperData *gd)
-{
- const nsscmstypeInfo *typeInfo;
-
- /* short cut common case */
- if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
- }
-
- typeInfo = nss_cmstype_lookup(type);
- if (typeInfo) {
- if (typeInfo->decode_before) {
- return (*typeInfo->decode_before)(gd);
- }
- /* decoder ops optional for data tags */
- if (typeInfo->isData) {
- return SECSuccess;
- }
- }
- /* expected a function, but none existed */
- return SECFailure;
-
-}
-
-SECStatus
-NSS_CMSGenericWrapperData_Decode_AfterData(SECOidTag type,
- NSSCMSGenericWrapperData *gd)
-{
- const nsscmstypeInfo *typeInfo;
-
- /* short cut common case */
- if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
- }
-
- typeInfo = nss_cmstype_lookup(type);
- if (typeInfo) {
- if (typeInfo->decode_after) {
- return (*typeInfo->decode_after)(gd);
- }
- /* decoder ops optional for data tags */
- if (typeInfo->isData) {
- return SECSuccess;
- }
- }
- /* expected a function, but none existed */
- return SECFailure;
-}
-
-SECStatus
-NSS_CMSGenericWrapperData_Decode_AfterEnd(SECOidTag type,
- NSSCMSGenericWrapperData *gd)
-{
- const nsscmstypeInfo *typeInfo;
-
- /* short cut common case */
- if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
- }
-
- typeInfo = nss_cmstype_lookup(type);
- if (typeInfo) {
- if (typeInfo->decode_end) {
- return (*typeInfo->decode_end)(gd);
- }
- /* decoder ops optional for data tags */
- if (typeInfo->isData) {
- return SECSuccess;
- }
- }
- /* expected a function, but none existed */
- return SECFailure;
-}
-
-SECStatus
-NSS_CMSGenericWrapperData_Encode_BeforeStart(SECOidTag type,
- NSSCMSGenericWrapperData *gd)
-{
- const nsscmstypeInfo *typeInfo;
-
- /* short cut common case */
- if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
- }
-
- typeInfo = nss_cmstype_lookup(type);
- if (typeInfo) {
- if (typeInfo->encode_start) {
- return (*typeInfo->encode_start)(gd);
- }
- /* decoder ops optional for data tags */
- if (typeInfo->isData) {
- return SECSuccess;
- }
- }
- /* expected a function, but none existed */
- return SECFailure;
-}
-
-SECStatus
-NSS_CMSGenericWrapperData_Encode_BeforeData(SECOidTag type,
- NSSCMSGenericWrapperData *gd)
-{
- const nsscmstypeInfo *typeInfo;
-
- /* short cut common case */
- if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
- }
-
- typeInfo = nss_cmstype_lookup(type);
- if (typeInfo) {
- if (typeInfo->encode_before) {
- return (*typeInfo->encode_before)(gd);
- }
- /* decoder ops optional for data tags */
- if (typeInfo->isData) {
- return SECSuccess;
- }
- }
- /* expected a function, but none existed */
- return SECFailure;
-}
-
-SECStatus
-NSS_CMSGenericWrapperData_Encode_AfterData(SECOidTag type,
- NSSCMSGenericWrapperData *gd)
-{
- const nsscmstypeInfo *typeInfo;
-
- /* short cut common case */
- if (type == SEC_OID_PKCS7_DATA) {
- return SECSuccess;
- }
-
- typeInfo = nss_cmstype_lookup(type);
- if (typeInfo) {
- if (typeInfo->encode_after) {
- return (*typeInfo->encode_after)(gd);
- }
- /* decoder ops optional for data tags */
- if (typeInfo->isData) {
- return SECSuccess;
- }
- }
- /* expected a function, but none existed */
- return SECFailure;
-}
-
-
-SECStatus
-NSS_CMSType_RegisterContentType(SECOidTag type,
- SEC_ASN1Template *asn1Template, size_t size,
- NSSCMSGenericWrapperDataDestroy destroy,
- NSSCMSGenericWrapperDataCallback decode_before,
- NSSCMSGenericWrapperDataCallback decode_after,
- NSSCMSGenericWrapperDataCallback decode_end,
- NSSCMSGenericWrapperDataCallback encode_start,
- NSSCMSGenericWrapperDataCallback encode_before,
- NSSCMSGenericWrapperDataCallback encode_after,
- PRBool isData)
-{
- PRStatus rc;
- SECStatus rv;
- nsscmstypeInfo *typeInfo;
- const nsscmstypeInfo *exists;
-
- rc = PR_CallOnce( &nsscmstypeOnce, nss_cmstype_init);
- if (rc == PR_FAILURE) {
- return SECFailure;
- }
- PR_Lock(nsscmstypeAddLock);
- exists = nss_cmstype_lookup(type);
- if (exists) {
- PR_Unlock(nsscmstypeAddLock);
- /* already added */
- return SECSuccess;
- }
- typeInfo = PORT_ArenaNew(nsscmstypeArena, nsscmstypeInfo);
- typeInfo->type = type;
- typeInfo->size = size;
- typeInfo->isData = isData;
- typeInfo->template = asn1Template;
- typeInfo->destroy = destroy;
- typeInfo->decode_before = decode_before;
- typeInfo->decode_after = decode_after;
- typeInfo->decode_end = decode_end;
- typeInfo->encode_start = encode_start;
- typeInfo->encode_before = encode_before;
- typeInfo->encode_after = encode_after;
- rv = nss_cmstype_add(type, typeInfo);
- PR_Unlock(nsscmstypeAddLock);
- return rv;
-}
-
diff --git a/security/nss/lib/smime/cmsutil.c b/security/nss/lib/smime/cmsutil.c
deleted file mode 100644
index 7ee74af71..000000000
--- a/security/nss/lib/smime/cmsutil.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * CMS miscellaneous utility functions.
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "secerr.h"
-#include "sechash.h"
-
-/*
- * NSS_CMSArray_SortByDER - sort array of objects by objects' DER encoding
- *
- * make sure that the order of the objects guarantees valid DER (which must be
- * in lexigraphically ascending order for a SET OF); if reordering is necessary it
- * will be done in place (in objs).
- */
-SECStatus
-NSS_CMSArray_SortByDER(void **objs, const SEC_ASN1Template *objtemplate, void **objs2)
-{
- PRArenaPool *poolp;
- int num_objs;
- SECItem **enc_objs;
- SECStatus rv = SECFailure;
- int i;
-
- if (objs == NULL) /* already sorted */
- return SECSuccess;
-
- num_objs = NSS_CMSArray_Count((void **)objs);
- if (num_objs == 0 || num_objs == 1) /* already sorted. */
- return SECSuccess;
-
- poolp = PORT_NewArena (1024); /* arena for temporaries */
- if (poolp == NULL)
- return SECFailure; /* no memory; nothing we can do... */
-
- /*
- * Allocate arrays to hold the individual encodings which we will use
- * for comparisons and the reordered attributes as they are sorted.
- */
- enc_objs = (SECItem **)PORT_ArenaZAlloc(poolp, (num_objs + 1) * sizeof(SECItem *));
- if (enc_objs == NULL)
- goto loser;
-
- /* DER encode each individual object. */
- for (i = 0; i < num_objs; i++) {
- enc_objs[i] = SEC_ASN1EncodeItem(poolp, NULL, objs[i], objtemplate);
- if (enc_objs[i] == NULL)
- goto loser;
- }
- enc_objs[num_objs] = NULL;
-
- /* now compare and sort objs by the order of enc_objs */
- NSS_CMSArray_Sort((void **)enc_objs, NSS_CMSUtil_DERCompare, objs, objs2);
-
- rv = SECSuccess;
-
-loser:
- PORT_FreeArena (poolp, PR_FALSE);
- return rv;
-}
-
-/*
- * NSS_CMSUtil_DERCompare - for use with NSS_CMSArray_Sort to
- * sort arrays of SECItems containing DER
- */
-int
-NSS_CMSUtil_DERCompare(void *a, void *b)
-{
- SECItem *der1 = (SECItem *)a;
- SECItem *der2 = (SECItem *)b;
- unsigned int j;
-
- /*
- * Find the lowest (lexigraphically) encoding. One that is
- * shorter than all the rest is known to be "less" because each
- * attribute is of the same type (a SEQUENCE) and so thus the
- * first octet of each is the same, and the second octet is
- * the length (or the length of the length with the high bit
- * set, followed by the length, which also works out to always
- * order the shorter first). Two (or more) that have the
- * same length need to be compared byte by byte until a mismatch
- * is found.
- */
- if (der1->len != der2->len)
- return (der1->len < der2->len) ? -1 : 1;
-
- for (j = 0; j < der1->len; j++) {
- if (der1->data[j] == der2->data[j])
- continue;
- return (der1->data[j] < der2->data[j]) ? -1 : 1;
- }
- return 0;
-}
-
-/*
- * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of
- * algorithms.
- *
- * algorithmArray - array of algorithm IDs
- * algid - algorithmid of algorithm to pick
- *
- * Returns:
- * An integer containing the index of the algorithm in the array or -1 if
- * algorithm was not found.
- */
-int
-NSS_CMSAlgArray_GetIndexByAlgID(SECAlgorithmID **algorithmArray, SECAlgorithmID *algid)
-{
- int i;
-
- if (algorithmArray == NULL || algorithmArray[0] == NULL)
- return -1;
-
- for (i = 0; algorithmArray[i] != NULL; i++) {
- if (SECOID_CompareAlgorithmID(algorithmArray[i], algid) == SECEqual)
- break; /* bingo */
- }
-
- if (algorithmArray[i] == NULL)
- return -1; /* not found */
-
- return i;
-}
-
-/*
- * NSS_CMSAlgArray_GetIndexByAlgTag - find a specific algorithm in an array of
- * algorithms.
- *
- * algorithmArray - array of algorithm IDs
- * algtag - algorithm tag of algorithm to pick
- *
- * Returns:
- * An integer containing the index of the algorithm in the array or -1 if
- * algorithm was not found.
- */
-int
-NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray,
- SECOidTag algtag)
-{
- SECOidData *algid;
- int i = -1;
-
- if (algorithmArray == NULL || algorithmArray[0] == NULL)
- return i;
-
-#ifdef ORDER_N_SQUARED
- for (i = 0; algorithmArray[i] != NULL; i++) {
- algid = SECOID_FindOID(&(algorithmArray[i]->algorithm));
- if (algid->offset == algtag)
- break; /* bingo */
- }
-#else
- algid = SECOID_FindOIDByTag(algtag);
- if (!algid)
- return i;
- for (i = 0; algorithmArray[i] != NULL; i++) {
- if (SECITEM_ItemsAreEqual(&algorithmArray[i]->algorithm, &algid->oid))
- break; /* bingo */
- }
-#endif
-
- if (algorithmArray[i] == NULL)
- return -1; /* not found */
-
- return i;
-}
-
-/*
- * Map a sign algorithm to a digest algorithm.
- * This is used to handle incorrectly formatted packages sent to us
- * from Windows 2003.
- */
-SECOidTag
-NSS_CMSUtil_MapSignAlgs(SECOidTag signAlg)
-{
- switch (signAlg) {
- case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
- return SEC_OID_MD2;
- break;
- case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
- return SEC_OID_MD5;
- break;
- case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
- case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
- case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
- return SEC_OID_SHA1;
- break;
- case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
- case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
- return SEC_OID_SHA256;
- break;
- case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
- case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
- return SEC_OID_SHA384;
- break;
- case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
- case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
- return SEC_OID_SHA512;
- break;
- default:
- break;
- }
- /* not one of the algtags incorrectly sent to us*/
- return signAlg;
-}
-
-const SECHashObject *
-NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid)
-{
- SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm));
- const SECHashObject *digobj = HASH_GetHashObjectByOidTag(oidTag);
-
- return digobj;
-}
-
-const SEC_ASN1Template *
-NSS_CMSUtil_GetTemplateByTypeTag(SECOidTag type)
-{
- const SEC_ASN1Template *template;
- extern const SEC_ASN1Template NSSCMSSignedDataTemplate[];
- extern const SEC_ASN1Template NSSCMSEnvelopedDataTemplate[];
- extern const SEC_ASN1Template NSSCMSEncryptedDataTemplate[];
- extern const SEC_ASN1Template NSSCMSDigestedDataTemplate[];
-
- switch (type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- template = NSSCMSSignedDataTemplate;
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- template = NSSCMSEnvelopedDataTemplate;
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- template = NSSCMSEncryptedDataTemplate;
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- template = NSSCMSDigestedDataTemplate;
- break;
- default:
- template = NSS_CMSType_GetTemplate(type);
- break;
- }
- return template;
-}
-
-size_t
-NSS_CMSUtil_GetSizeByTypeTag(SECOidTag type)
-{
- size_t size;
-
- switch (type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- size = sizeof(NSSCMSSignedData);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- size = sizeof(NSSCMSEnvelopedData);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- size = sizeof(NSSCMSEncryptedData);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- size = sizeof(NSSCMSDigestedData);
- break;
- default:
- size = NSS_CMSType_GetContentSize(type);
- break;
- }
- return size;
-}
-
-NSSCMSContentInfo *
-NSS_CMSContent_GetContentInfo(void *msg, SECOidTag type)
-{
- NSSCMSContent c;
- NSSCMSContentInfo *cinfo = NULL;
-
- if (!msg)
- return cinfo;
- c.pointer = msg;
- switch (type) {
- case SEC_OID_PKCS7_SIGNED_DATA:
- cinfo = &(c.signedData->contentInfo);
- break;
- case SEC_OID_PKCS7_ENVELOPED_DATA:
- cinfo = &(c.envelopedData->contentInfo);
- break;
- case SEC_OID_PKCS7_ENCRYPTED_DATA:
- cinfo = &(c.encryptedData->contentInfo);
- break;
- case SEC_OID_PKCS7_DIGESTED_DATA:
- cinfo = &(c.digestedData->contentInfo);
- break;
- default:
- cinfo = NULL;
- if (NSS_CMSType_IsWrapper(type)) {
- cinfo = &(c.genericData->contentInfo);
- }
- }
- return cinfo;
-}
-
-const char *
-NSS_CMSUtil_VerificationStatusToString(NSSCMSVerificationStatus vs)
-{
- switch (vs) {
- case NSSCMSVS_Unverified: return "Unverified";
- case NSSCMSVS_GoodSignature: return "GoodSignature";
- case NSSCMSVS_BadSignature: return "BadSignature";
- case NSSCMSVS_DigestMismatch: return "DigestMismatch";
- case NSSCMSVS_SigningCertNotFound: return "SigningCertNotFound";
- case NSSCMSVS_SigningCertNotTrusted: return "SigningCertNotTrusted";
- case NSSCMSVS_SignatureAlgorithmUnknown: return "SignatureAlgorithmUnknown";
- case NSSCMSVS_SignatureAlgorithmUnsupported: return "SignatureAlgorithmUnsupported";
- case NSSCMSVS_MalformedSignature: return "MalformedSignature";
- case NSSCMSVS_ProcessingError: return "ProcessingError";
- default: return "Unknown";
- }
-}
-
-SECStatus
-NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut,
- PLArenaPool *arena)
-{
- NSSCMSEncoderContext *ecx;
- SECStatus rv = SECSuccess;
- if (!cmsg || !derOut || !arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- ecx = NSS_CMSEncoder_Start(cmsg, 0, 0, derOut, arena, 0, 0, 0, 0, 0, 0);
- if (!ecx) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (input) {
- rv = NSS_CMSEncoder_Update(ecx, (const char*)input->data, input->len);
- if (rv) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- }
- }
- rv |= NSS_CMSEncoder_Finish(ecx);
- if (rv) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- }
- return rv;
-}
-
diff --git a/security/nss/lib/smime/config.mk b/security/nss/lib/smime/config.mk
deleted file mode 100644
index 85d39e825..000000000
--- a/security/nss/lib/smime/config.mk
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-RELEASE_LIBS = $(TARGETS)
-
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
-
-RES = $(OBJDIR)/smime.res
-RESNAME = smime.rc
-
-ifdef NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -lnss3 \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-else # ! NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- $(DIST)/lib/nss3.lib \
- $(DIST)/lib/nssutil3.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-
-else
-
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -lnss3 \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-
-endif
-
-
-SHARED_LIBRARY_LIBS = \
- $(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \
- $(NULL)
-
-SHARED_LIBRARY_DIRS = \
- ../pkcs12 \
- ../pkcs7 \
- $(NULL)
-
diff --git a/security/nss/lib/smime/manifest.mn b/security/nss/lib/smime/manifest.mn
deleted file mode 100644
index d8658268a..000000000
--- a/security/nss/lib/smime/manifest.mn
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-CORE_DEPTH = ../../..
-
-EXPORTS = \
- cms.h \
- cmst.h \
- smime.h \
- cmsreclist.h \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- cmslocal.h \
- $(NULL)
-
-MODULE = nss
-MAPFILE = $(OBJDIR)/smime.def
-
-CSRCS = \
- cmsarray.c \
- cmsasn1.c \
- cmsattr.c \
- cmscinfo.c \
- cmscipher.c \
- cmsdecode.c \
- cmsdigdata.c \
- cmsdigest.c \
- cmsencdata.c \
- cmsencode.c \
- cmsenvdata.c \
- cmsmessage.c \
- cmspubkey.c \
- cmsrecinfo.c \
- cmsreclist.c \
- cmssigdata.c \
- cmssiginfo.c \
- cmsudf.c \
- cmsutil.c \
- smimemessage.c \
- smimeutil.c \
- smimever.c \
- $(NULL)
-
-LIBRARY_NAME = smime
-LIBRARY_VERSION = 3
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/smime/smime.def b/security/nss/lib/smime/smime.def
deleted file mode 100644
index 623eaa460..000000000
--- a/security/nss/lib/smime/smime.def
+++ /dev/null
@@ -1,269 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+
-;+NSS_3.2 { # NSS 3.2 release
-;+ global:
-LIBRARY smime3 ;-
-EXPORTS ;-
-NSS_CMSContentInfo_GetBulkKey;
-NSS_CMSContentInfo_GetBulkKeySize;
-NSS_CMSContentInfo_GetContent;
-NSS_CMSContentInfo_GetContentEncAlgTag;
-NSS_CMSContentInfo_GetContentTypeTag;
-NSS_CMSContentInfo_SetBulkKey;
-NSS_CMSContentInfo_SetContent;
-NSS_CMSContentInfo_SetContentEncAlg;
-NSS_CMSContentInfo_SetContent_Data;
-NSS_CMSContentInfo_SetContent_DigestedData;
-NSS_CMSContentInfo_SetContent_EncryptedData;
-NSS_CMSContentInfo_SetContent_EnvelopedData;
-NSS_CMSContentInfo_SetContent_SignedData;
-NSS_CMSDEREncode;
-NSS_CMSDecoder_Cancel;
-NSS_CMSDecoder_Finish;
-NSS_CMSDecoder_Start;
-NSS_CMSDecoder_Update;
-NSS_CMSDigestContext_Cancel;
-NSS_CMSDigestContext_FinishMultiple;
-NSS_CMSDigestContext_FinishSingle;
-NSS_CMSDigestContext_StartMultiple;
-NSS_CMSDigestContext_StartSingle;
-NSS_CMSDigestContext_Update;
-NSS_CMSDigestedData_Create;
-NSS_CMSDigestedData_Destroy;
-NSS_CMSDigestedData_GetContentInfo;
-NSS_CMSEncoder_Cancel;
-NSS_CMSEncoder_Finish;
-NSS_CMSEncoder_Start;
-NSS_CMSEncoder_Update;
-NSS_CMSEncryptedData_Create;
-NSS_CMSEncryptedData_Destroy;
-NSS_CMSEncryptedData_GetContentInfo;
-NSS_CMSEnvelopedData_AddRecipient;
-NSS_CMSEnvelopedData_Create;
-NSS_CMSEnvelopedData_Destroy;
-NSS_CMSEnvelopedData_GetContentInfo;
-NSS_CMSMessage_ContentLevel;
-NSS_CMSMessage_ContentLevelCount;
-NSS_CMSMessage_Copy;
-NSS_CMSMessage_Create;
-NSS_CMSMessage_CreateFromDER;
-NSS_CMSMessage_Destroy;
-NSS_CMSMessage_GetContent;
-NSS_CMSMessage_GetContentInfo;
-NSS_CMSRecipientInfo_Create;
-NSS_CMSRecipientInfo_Destroy;
-NSS_CMSSignedData_AddCertChain;
-NSS_CMSSignedData_AddCertList;
-NSS_CMSSignedData_AddCertificate;
-NSS_CMSSignedData_AddDigest;
-NSS_CMSSignedData_AddSignerInfo;
-NSS_CMSSignedData_Create;
-NSS_CMSSignedData_CreateCertsOnly;
-NSS_CMSSignedData_Destroy;
-NSS_CMSSignedData_GetContentInfo;
-NSS_CMSSignedData_GetDigestAlgs;
-NSS_CMSSignedData_GetSignerInfo;
-NSS_CMSSignedData_HasDigests;
-NSS_CMSSignedData_ImportCerts;
-NSS_CMSSignedData_SetDigests;
-NSS_CMSSignedData_SignerInfoCount;
-NSS_CMSSignedData_VerifyCertsOnly;
-NSS_CMSSignedData_VerifySignerInfo;
-NSS_CMSSignerInfo_AddSMIMECaps;
-NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs;
-NSS_CMSSignerInfo_AddSigningTime;
-NSS_CMSSignerInfo_Create;
-NSS_CMSSignerInfo_Destroy;
-NSS_CMSSignerInfo_GetCertList;
-NSS_CMSSignerInfo_GetSignerCommonName;
-NSS_CMSSignerInfo_GetSignerEmailAddress;
-NSS_CMSSignerInfo_GetSigningCertificate;
-NSS_CMSSignerInfo_GetSigningTime;
-NSS_CMSSignerInfo_GetVerificationStatus;
-NSS_CMSSignerInfo_GetVersion;
-NSS_CMSSignerInfo_IncludeCerts;
-NSS_CMSUtil_VerificationStatusToString;
-NSS_SMIMEUtil_FindBulkAlgForRecipients;
-CERT_DecodeCertPackage;
-SEC_PKCS7AddRecipient;
-SEC_PKCS7AddSigningTime;
-SEC_PKCS7ContentType;
-SEC_PKCS7CreateData;
-SEC_PKCS7CreateEncryptedData;
-SEC_PKCS7CreateEnvelopedData;
-SEC_PKCS7CreateSignedData;
-SEC_PKCS7DecodeItem;
-SEC_PKCS7DecoderFinish;
-SEC_PKCS7DecoderStart;
-SEC_PKCS7DecoderUpdate;
-SEC_PKCS7DecryptContents;
-SEC_PKCS7DestroyContentInfo;
-SEC_PKCS7EncoderFinish;
-SEC_PKCS7EncoderStart;
-SEC_PKCS7EncoderUpdate;
-SEC_PKCS7GetCertificateList;
-SEC_PKCS7GetContent;
-SEC_PKCS7GetEncryptionAlgorithm;
-SEC_PKCS7IncludeCertChain;
-SEC_PKCS7IsContentEmpty;
-SEC_PKCS7VerifySignature;
-SEC_PKCS12AddCertAndKey;
-SEC_PKCS12AddPasswordIntegrity;
-SEC_PKCS12CreateExportContext;
-SEC_PKCS12CreatePasswordPrivSafe;
-SEC_PKCS12CreateUnencryptedSafe;
-SEC_PKCS12EnableCipher;
-SEC_PKCS12Encode;
-SEC_PKCS12DecoderImportBags;
-SEC_PKCS12DecoderFinish;
-SEC_PKCS12DecoderStart;
-SEC_PKCS12DecoderUpdate;
-SEC_PKCS12DecoderValidateBags;
-SEC_PKCS12DecoderVerify;
-SEC_PKCS12DestroyExportContext;
-SEC_PKCS12IsEncryptionAllowed;
-SEC_PKCS12SetPreferredCipher;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.2.1 { # NSS 3.2.1 release
-;+ global:
-NSSSMIME_VersionCheck;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.3 { # NSS 3.3 release
-;+ global:
-SEC_PKCS7AddCertificate;
-SEC_PKCS7CreateCertsOnly;
-SEC_PKCS7Encode;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.4 { # NSS 3.4 release
-;+ global:
-CERT_DecodeCertFromPackage;
-NSS_CMSMessage_IsSigned;
-NSS_CMSSignedData_SetDigestValue;
-NSS_SMIMESignerInfo_SaveSMIMEProfile;
-SEC_PKCS12DecoderGetCerts;
-SEC_PKCS7ContainsCertsOrCrls;
-SEC_PKCS7ContentIsEncrypted;
-SEC_PKCS7ContentIsSigned;
-SEC_PKCS7CopyContentInfo;
-SEC_PKCS7GetSignerCommonName;
-SEC_PKCS7GetSignerEmailAddress;
-SEC_PKCS7GetSigningTime;
-SEC_PKCS7SetContent;
-SEC_PKCS7VerifyDetachedSignature;
-SECMIME_DecryptionAllowed;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.4.1 { # NSS 3.4.1 release
-;+ global:
-NSS_CMSMessage_IsEncrypted;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.6 { # NSS 3.6 release
-;+ global:
-NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs;
-NSS_CMSSignerInfo_CreateWithSubjKeyID;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.7 { # NSS 3.7 release
-;+ global:
-NSS_CMSRecipientInfo_CreateWithSubjKeyID;
-NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.7.2 { # NSS 3.7.2 release
-;+ global:
-NSS_CMSRecipientInfo_WrapBulkKey;
-NSS_CMSRecipientInfo_UnwrapBulkKey;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.8 { # NSS 3.8 release
-;+ global:
-NSS_CMSRecipientInfo_CreateNew;
-NSS_CMSRecipientInfo_CreateFromDER;
-NSS_CMSRecipientInfo_Encode;
-NSS_CMSRecipientInfo_GetCertAndKey;
-SEC_PKCS12DecoderSetTargetTokenCAs;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.9 { # NSS 3.9 release
-;+ global:
-SEC_PKCS7DecoderAbort;
-SEC_PKCS7EncoderAbort;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.9.3 { # NSS 3.9.3 release
-;+ global:
-CERT_ConvertAndDecodeCertificate;
-SEC_PKCS7EncodeItem;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.10 { # NSS 3.10 release
-;+ global:
-SEC_PKCS12DecoderIterateInit;
-SEC_PKCS12DecoderIterateNext;
-SEC_PKCS12DecryptionAllowed;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.2 { # NSS 3.12.2 release
-;+ global:
-SEC_PKCS12AddCertOrChainAndKey;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.12.10 { # NSS 3.12.10 release
-;+ global:
-NSS_CMSType_RegisterContentType;
-NSS_CMSContentInfo_SetDontStream;
-NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs;
-;+#
-;+# Data objects
-;+#
-;+# Don't export these DATA symbols on Windows because they don't work right.
-;+# Use the SEC_ASN1_GET / SEC_ASN1_SUB / SEC_ASN1_XTRN macros to access them.
-;+#
-;+# See nssutil for other examples.
-;+#
-;;NSSCMSGenericWrapperDataTemplate DATA ;
-;;NSS_PointerToCMSGenericWrapperDataTemplate DATA ;
-NSS_Get_NSSCMSGenericWrapperDataTemplate;
-NSS_Get_NSS_PointerToCMSGenericWrapperDataTemplate;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.13 { # NSS 3.13 release
-;+ global:
-NSSSMIME_GetVersion;
-;+ local:
-;+ *;
-;+};
diff --git a/security/nss/lib/smime/smime.h b/security/nss/lib/smime/smime.h
deleted file mode 100644
index c1926b3f4..000000000
--- a/security/nss/lib/smime/smime.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Header file for routines specific to S/MIME. Keep things that are pure
- * pkcs7 out of here; this is for S/MIME policy, S/MIME interoperability, etc.
- *
- * $Id$
- */
-
-#ifndef _SECMIME_H_
-#define _SECMIME_H_ 1
-
-#include "cms.h"
-
-
-/************************************************************************/
-SEC_BEGIN_PROTOS
-
-/*
- * Initialize the local recording of the user S/MIME cipher preferences.
- * This function is called once for each cipher, the order being
- * important (first call records greatest preference, and so on).
- * When finished, it is called with a "which" of CIPHER_FAMILID_MASK.
- * If the function is called again after that, it is assumed that
- * the preferences are being reset, and the old preferences are
- * discarded.
- *
- * XXX This is for a particular user, and right now the storage is
- * XXX local, static. The preference should be stored elsewhere to allow
- * XXX for multiple uses of one library? How does SSL handle this;
- * XXX it has something similar?
- *
- * - The "which" values are defined in ciferfam.h (the SMIME_* values,
- * for example SMIME_DES_CBC_56).
- * - If "on" is non-zero then the named cipher is enabled, otherwise
- * it is disabled. (It is not necessary to call the function for
- * ciphers that are disabled, however, as that is the default.)
- *
- * If the cipher preference is successfully recorded, SECSuccess
- * is returned. Otherwise SECFailure is returned. The only errors
- * are due to failure allocating memory or bad parameters/calls:
- * SEC_ERROR_XXX ("which" is not in the S/MIME cipher family)
- * SEC_ERROR_XXX (function is being called more times than there
- * are known/expected ciphers)
- */
-extern SECStatus NSS_SMIMEUtil_EnableCipher(long which, int on);
-
-/*
- * Initialize the local recording of the S/MIME policy.
- * This function is called to allow/disallow a particular cipher.
- *
- * XXX This is for the current module, I think, so local, static storage
- * XXX is okay. Is that correct, or could multiple uses of the same
- * XXX library expect to operate under different policies?
- *
- * - The "which" values are defined in ciferfam.h (the SMIME_* values,
- * for example SMIME_DES_CBC_56).
- * - If "on" is non-zero then the named cipher is enabled, otherwise
- * it is disabled.
- */
-extern SECStatus NSS_SMIMEUtils_AllowCipher(long which, int on);
-
-/*
- * Does the current policy allow S/MIME decryption of this particular
- * algorithm and keysize?
- */
-extern PRBool NSS_SMIMEUtil_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key);
-
-/*
- * Does the current policy allow *any* S/MIME encryption (or decryption)?
- *
- * This tells whether or not *any* S/MIME encryption can be done,
- * according to policy. Callers may use this to do nicer user interface
- * (say, greying out a checkbox so a user does not even try to encrypt
- * a message when they are not allowed to) or for any reason they want
- * to check whether S/MIME encryption (or decryption, for that matter)
- * may be done.
- *
- * It takes no arguments. The return value is a simple boolean:
- * PR_TRUE means encryption (or decryption) is *possible*
- * (but may still fail due to other reasons, like because we cannot
- * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee)
- * PR_FALSE means encryption (or decryption) is not permitted
- *
- * There are no errors from this routine.
- */
-extern PRBool NSS_SMIMEUtil_EncryptionPossible(void);
-
-/*
- * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities attr value
- *
- * scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
- * S/MIME capabilities attribute value.
- */
-extern SECStatus NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest);
-
-/*
- * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value
- */
-extern SECStatus NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert);
-
-/*
- * NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value using MS oid
- */
-extern SECStatus NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert);
-
-/*
- * NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference - find cert marked by EncryptionKeyPreference
- * attribute
- */
-extern CERTCertificate *NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECItem *DERekp);
-
-/*
- * NSS_SMIMEUtil_FindBulkAlgForRecipients - find bulk algorithm suitable for all recipients
- */
-extern SECStatus
-NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulkalgtag, int *keysize);
-
-/*
- * Return a boolean that indicates whether the underlying library
- * will perform as the caller expects.
- *
- * The only argument is a string, which should be the version
- * identifier of the NSS library. That string will be compared
- * against a string that represents the actual build version of
- * the S/MIME library.
- */
-extern PRBool NSSSMIME_VersionCheck(const char *importedVersion);
-
-/*
- * Returns a const string of the S/MIME library version.
- */
-extern const char *NSSSMIME_GetVersion(void);
-
-/************************************************************************/
-SEC_END_PROTOS
-
-#endif /* _SECMIME_H_ */
diff --git a/security/nss/lib/smime/smime.rc b/security/nss/lib/smime/smime.rc
deleted file mode 100644
index ad24732e4..000000000
--- a/security/nss/lib/smime/smime.rc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nss.h"
-#include <winver.h>
-
-#define MY_LIBNAME "smime"
-#define MY_FILEDESCRIPTION "NSS S/MIME Library"
-
-#define STRINGIZE(x) #x
-#define STRINGIZE2(x) STRINGIZE(x)
-#define NSS_VMAJOR_STR STRINGIZE2(NSS_VMAJOR)
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if NSS_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME NSS_VMAJOR_STR
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
- PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Mozilla Foundation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", NSS_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", NSS_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/smime/smimemessage.c b/security/nss/lib/smime/smimemessage.c
deleted file mode 100644
index db7391237..000000000
--- a/security/nss/lib/smime/smimemessage.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * SMIME message methods
- *
- * $Id$
- */
-
-#include "cmslocal.h"
-#include "smime.h"
-
-#include "cert.h"
-#include "key.h"
-#include "secasn1.h"
-#include "secitem.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "prtime.h"
-#include "secerr.h"
-
-
-#if 0
-/*
- * NSS_SMIMEMessage_CreateEncrypted - start an S/MIME encrypting context.
- *
- * "scert" is the cert for the sender. It will be checked for validity.
- * "rcerts" are the certs for the recipients. They will also be checked.
- *
- * "certdb" is the cert database to use for verifying the certs.
- * It can be NULL if a default database is available (like in the client).
- *
- * This function already does all of the stuff specific to S/MIME protocol
- * and local policy; the return value just needs to be passed to
- * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
- * and finally to SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-NSSCMSMessage *
-NSS_SMIMEMessage_CreateEncrypted(CERTCertificate *scert,
- CERTCertificate **rcerts,
- CERTCertDBHandle *certdb,
- PK11PasswordFunc pwfn,
- void *pwfn_arg)
-{
- NSSCMSMessage *cmsg;
- long cipher;
- SECOidTag encalg;
- int keysize;
- int mapi, rci;
-
- cipher = smime_choose_cipher (scert, rcerts);
- if (cipher < 0)
- return NULL;
-
- mapi = smime_mapi_by_cipher (cipher);
- if (mapi < 0)
- return NULL;
-
- /*
- * XXX This is stretching it -- CreateEnvelopedData should probably
- * take a cipher itself of some sort, because we cannot know what the
- * future will bring in terms of parameters for each type of algorithm.
- * For example, just an algorithm and keysize is *not* sufficient to
- * fully specify the usage of RC5 (which also needs to know rounds and
- * block size). Work this out into a better API!
- */
- encalg = smime_cipher_map[mapi].algtag;
- keysize = smime_keysize_by_cipher (cipher);
- if (keysize < 0)
- return NULL;
-
- cinfo = SEC_PKCS7CreateEnvelopedData (scert, certUsageEmailRecipient,
- certdb, encalg, keysize,
- pwfn, pwfn_arg);
- if (cinfo == NULL)
- return NULL;
-
- for (rci = 0; rcerts[rci] != NULL; rci++) {
- if (rcerts[rci] == scert)
- continue;
- if (SEC_PKCS7AddRecipient (cinfo, rcerts[rci], certUsageEmailRecipient,
- NULL) != SECSuccess) {
- SEC_PKCS7DestroyContentInfo (cinfo);
- return NULL;
- }
- }
-
- return cinfo;
-}
-
-
-/*
- * Start an S/MIME signing context.
- *
- * "scert" is the cert that will be used to sign the data. It will be
- * checked for validity.
- *
- * "ecert" is the signer's encryption cert. If it is different from
- * scert, then it will be included in the signed message so that the
- * recipient can save it for future encryptions.
- *
- * "certdb" is the cert database to use for verifying the cert.
- * It can be NULL if a default database is available (like in the client).
- *
- * "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1).
- * XXX There should be SECMIME functions for hashing, or the hashing should
- * be built into this interface, which we would like because we would
- * support more smartcards that way, and then this argument should go away.)
- *
- * "digest" is the actual digest of the data. It must be provided in
- * the case of detached data or NULL if the content will be included.
- *
- * This function already does all of the stuff specific to S/MIME protocol
- * and local policy; the return value just needs to be passed to
- * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
- * and finally to SEC_PKCS7DestroyContentInfo().
- *
- * An error results in a return value of NULL and an error set.
- * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
- */
-
-NSSCMSMessage *
-NSS_SMIMEMessage_CreateSigned(CERTCertificate *scert,
- CERTCertificate *ecert,
- CERTCertDBHandle *certdb,
- SECOidTag digestalgtag,
- SECItem *digest,
- PK11PasswordFunc pwfn,
- void *pwfn_arg)
-{
- NSSCMSMessage *cmsg;
- NSSCMSSignedData *sigd;
- NSSCMSSignerInfo *signerinfo;
-
- /* See note in header comment above about digestalg. */
- /* Doesn't explain this. PORT_Assert (digestalgtag == SEC_OID_SHA1); */
-
- cmsg = NSS_CMSMessage_Create(NULL);
- if (cmsg == NULL)
- return NULL;
-
- sigd = NSS_CMSSignedData_Create(cmsg);
- if (sigd == NULL)
- goto loser;
-
- /* create just one signerinfo */
- signerinfo = NSS_CMSSignerInfo_Create(cmsg, scert, digestalgtag);
- if (signerinfo == NULL)
- goto loser;
-
- /* Add the signing time to the signerinfo. */
- if (NSS_CMSSignerInfo_AddSigningTime(signerinfo, PR_Now()) != SECSuccess)
- goto loser;
-
- /* and add the SMIME profile */
- if (NSS_SMIMESignerInfo_AddSMIMEProfile(signerinfo, scert) != SECSuccess)
- goto loser;
-
- /* now add the signerinfo to the signeddata */
- if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess)
- goto loser;
-
- /* include the signing cert and its entire chain */
- /* note that there are no checks for duplicate certs in place, as all the */
- /* essential data structures (like set of certificate) are not there */
- if (NSS_CMSSignedData_AddCertChain(sigd, scert) != SECSuccess)
- goto loser;
-
- /* If the encryption cert and the signing cert differ, then include
- * the encryption cert too. */
- if ( ( ecert != NULL ) && ( ecert != scert ) ) {
- if (NSS_CMSSignedData_AddCertificate(sigd, ecert) != SECSuccess)
- goto loser;
- }
-
- return cmsg;
-loser:
- if (cmsg)
- NSS_CMSMessage_Destroy(cmsg);
- return NULL;
-}
-#endif
diff --git a/security/nss/lib/smime/smimesym.c b/security/nss/lib/smime/smimesym.c
deleted file mode 100644
index 8ed6cbf9a..000000000
--- a/security/nss/lib/smime/smimesym.c
+++ /dev/null
@@ -1,12 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-extern void SEC_PKCS7DecodeItem();
-extern void SEC_PKCS7DestroyContentInfo();
-
-smime_CMDExports() {
- SEC_PKCS7DecodeItem();
- SEC_PKCS7DestroyContentInfo();
-}
-
diff --git a/security/nss/lib/smime/smimeutil.c b/security/nss/lib/smime/smimeutil.c
deleted file mode 100644
index 63e73efb5..000000000
--- a/security/nss/lib/smime/smimeutil.c
+++ /dev/null
@@ -1,783 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Stuff specific to S/MIME policy and interoperability.
- *
- * $Id$
- */
-
-#include "secmime.h"
-#include "secoid.h"
-#include "pk11func.h"
-#include "ciferfam.h" /* for CIPHER_FAMILY symbols */
-#include "secasn1.h"
-#include "secitem.h"
-#include "cert.h"
-#include "key.h"
-#include "secerr.h"
-#include "cms.h"
-#include "nss.h"
-
-SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
-SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
-SEC_ASN1_CHOOSER_DECLARE(CERT_IssuerAndSNTemplate)
-
-/* various integer's ASN.1 encoding */
-static unsigned char asn1_int40[] = { SEC_ASN1_INTEGER, 0x01, 0x28 };
-static unsigned char asn1_int64[] = { SEC_ASN1_INTEGER, 0x01, 0x40 };
-static unsigned char asn1_int128[] = { SEC_ASN1_INTEGER, 0x02, 0x00, 0x80 };
-
-/* RC2 algorithm parameters (used in smime_cipher_map) */
-static SECItem param_int40 = { siBuffer, asn1_int40, sizeof(asn1_int40) };
-static SECItem param_int64 = { siBuffer, asn1_int64, sizeof(asn1_int64) };
-static SECItem param_int128 = { siBuffer, asn1_int128, sizeof(asn1_int128) };
-
-/*
- * XXX Would like the "parameters" field to be a SECItem *, but the
- * encoder is having trouble with optional pointers to an ANY. Maybe
- * once that is fixed, can change this back...
- */
-typedef struct {
- SECItem capabilityID;
- SECItem parameters;
- long cipher; /* optimization */
-} NSSSMIMECapability;
-
-static const SEC_ASN1Template NSSSMIMECapabilityTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSSMIMECapability) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(NSSSMIMECapability,capabilityID), },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(NSSSMIMECapability,parameters), },
- { 0, }
-};
-
-static const SEC_ASN1Template NSSSMIMECapabilitiesTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, NSSSMIMECapabilityTemplate }
-};
-
-/*
- * NSSSMIMEEncryptionKeyPreference - if we find one of these, it needs to prompt us
- * to store this and only this certificate permanently for the sender email address.
- */
-typedef enum {
- NSSSMIMEEncryptionKeyPref_IssuerSN,
- NSSSMIMEEncryptionKeyPref_RKeyID,
- NSSSMIMEEncryptionKeyPref_SubjectKeyID
-} NSSSMIMEEncryptionKeyPrefSelector;
-
-typedef struct {
- NSSSMIMEEncryptionKeyPrefSelector selector;
- union {
- CERTIssuerAndSN *issuerAndSN;
- NSSCMSRecipientKeyIdentifier *recipientKeyID;
- SECItem *subjectKeyID;
- } id;
-} NSSSMIMEEncryptionKeyPreference;
-
-extern const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[];
-
-static const SEC_ASN1Template smime_encryptionkeypref_template[] = {
- { SEC_ASN1_CHOICE,
- offsetof(NSSSMIMEEncryptionKeyPreference,selector), NULL,
- sizeof(NSSSMIMEEncryptionKeyPreference) },
- { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0
- | SEC_ASN1_CONSTRUCTED,
- offsetof(NSSSMIMEEncryptionKeyPreference,id.issuerAndSN),
- SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
- NSSSMIMEEncryptionKeyPref_IssuerSN },
- { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1
- | SEC_ASN1_CONSTRUCTED,
- offsetof(NSSSMIMEEncryptionKeyPreference,id.recipientKeyID),
- NSSCMSRecipientKeyIdentifierTemplate,
- NSSSMIMEEncryptionKeyPref_RKeyID },
- { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2
- | SEC_ASN1_CONSTRUCTED,
- offsetof(NSSSMIMEEncryptionKeyPreference,id.subjectKeyID),
- SEC_ASN1_SUB(SEC_OctetStringTemplate),
- NSSSMIMEEncryptionKeyPref_SubjectKeyID },
- { 0, }
-};
-
-/* smime_cipher_map - map of SMIME symmetric "ciphers" to algtag & parameters */
-typedef struct {
- unsigned long cipher;
- SECOidTag algtag;
- SECItem *parms;
- PRBool enabled; /* in the user's preferences */
- PRBool allowed; /* per export policy */
-} smime_cipher_map_entry;
-
-/* global: list of supported SMIME symmetric ciphers, ordered roughly by increasing strength */
-static smime_cipher_map_entry smime_cipher_map[] = {
-/* cipher algtag parms enabled allowed */
-/* ---------------------------------------------------------------------------------- */
- { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, &param_int40, PR_TRUE, PR_TRUE },
- { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL, PR_TRUE, PR_TRUE },
- { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, &param_int64, PR_TRUE, PR_TRUE },
- { SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, &param_int128, PR_TRUE, PR_TRUE },
- { SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL, PR_TRUE, PR_TRUE },
- { SMIME_AES_CBC_128, SEC_OID_AES_128_CBC, NULL, PR_TRUE, PR_TRUE },
- { SMIME_AES_CBC_256, SEC_OID_AES_256_CBC, NULL, PR_TRUE, PR_TRUE }
-};
-static const int smime_cipher_map_count = sizeof(smime_cipher_map) / sizeof(smime_cipher_map_entry);
-
-/*
- * smime_mapi_by_cipher - find index into smime_cipher_map by cipher
- */
-static int
-smime_mapi_by_cipher(unsigned long cipher)
-{
- int i;
-
- for (i = 0; i < smime_cipher_map_count; i++) {
- if (smime_cipher_map[i].cipher == cipher)
- return i; /* bingo */
- }
- return -1; /* should not happen if we're consistent, right? */
-}
-
-/*
- * NSS_SMIME_EnableCipher - this function locally records the user's preference
- */
-SECStatus
-NSS_SMIMEUtil_EnableCipher(unsigned long which, PRBool on)
-{
- unsigned long mask;
- int mapi;
-
- mask = which & CIPHER_FAMILYID_MASK;
-
- PORT_Assert (mask == CIPHER_FAMILYID_SMIME);
- if (mask != CIPHER_FAMILYID_SMIME)
- /* XXX set an error! */
- return SECFailure;
-
- mapi = smime_mapi_by_cipher(which);
- if (mapi < 0)
- /* XXX set an error */
- return SECFailure;
-
- /* do we try to turn on a forbidden cipher? */
- if (!smime_cipher_map[mapi].allowed && on) {
- PORT_SetError (SEC_ERROR_BAD_EXPORT_ALGORITHM);
- return SECFailure;
- }
-
- if (smime_cipher_map[mapi].enabled != on)
- smime_cipher_map[mapi].enabled = on;
-
- return SECSuccess;
-}
-
-
-/*
- * this function locally records the export policy
- */
-SECStatus
-NSS_SMIMEUtil_AllowCipher(unsigned long which, PRBool on)
-{
- unsigned long mask;
- int mapi;
-
- mask = which & CIPHER_FAMILYID_MASK;
-
- PORT_Assert (mask == CIPHER_FAMILYID_SMIME);
- if (mask != CIPHER_FAMILYID_SMIME)
- /* XXX set an error! */
- return SECFailure;
-
- mapi = smime_mapi_by_cipher(which);
- if (mapi < 0)
- /* XXX set an error */
- return SECFailure;
-
- if (smime_cipher_map[mapi].allowed != on)
- smime_cipher_map[mapi].allowed = on;
-
- return SECSuccess;
-}
-
-/*
- * Based on the given algorithm (including its parameters, in some cases!)
- * and the given key (may or may not be inspected, depending on the
- * algorithm), find the appropriate policy algorithm specification
- * and return it. If no match can be made, -1 is returned.
- */
-static SECStatus
-nss_smime_get_cipher_for_alg_and_key(SECAlgorithmID *algid, PK11SymKey *key, unsigned long *cipher)
-{
- SECOidTag algtag;
- unsigned int keylen_bits;
- unsigned long c;
-
- algtag = SECOID_GetAlgorithmTag(algid);
- switch (algtag) {
- case SEC_OID_RC2_CBC:
- keylen_bits = PK11_GetKeyStrength(key, algid);
- switch (keylen_bits) {
- case 40:
- c = SMIME_RC2_CBC_40;
- break;
- case 64:
- c = SMIME_RC2_CBC_64;
- break;
- case 128:
- c = SMIME_RC2_CBC_128;
- break;
- default:
- return SECFailure;
- }
- break;
- case SEC_OID_DES_CBC:
- c = SMIME_DES_CBC_56;
- break;
- case SEC_OID_DES_EDE3_CBC:
- c = SMIME_DES_EDE3_168;
- break;
- case SEC_OID_AES_128_CBC:
- c = SMIME_AES_CBC_128;
- break;
- case SEC_OID_AES_256_CBC:
- c = SMIME_AES_CBC_256;
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
- *cipher = c;
- return SECSuccess;
-}
-
-static PRBool
-nss_smime_cipher_allowed(unsigned long which)
-{
- int mapi;
-
- mapi = smime_mapi_by_cipher(which);
- if (mapi < 0)
- return PR_FALSE;
- return smime_cipher_map[mapi].allowed;
-}
-
-PRBool
-NSS_SMIMEUtil_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key)
-{
- unsigned long which;
-
- if (nss_smime_get_cipher_for_alg_and_key(algid, key, &which) != SECSuccess)
- return PR_FALSE;
-
- return nss_smime_cipher_allowed(which);
-}
-
-
-/*
- * NSS_SMIME_EncryptionPossible - check if any encryption is allowed
- *
- * This tells whether or not *any* S/MIME encryption can be done,
- * according to policy. Callers may use this to do nicer user interface
- * (say, greying out a checkbox so a user does not even try to encrypt
- * a message when they are not allowed to) or for any reason they want
- * to check whether S/MIME encryption (or decryption, for that matter)
- * may be done.
- *
- * It takes no arguments. The return value is a simple boolean:
- * PR_TRUE means encryption (or decryption) is *possible*
- * (but may still fail due to other reasons, like because we cannot
- * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee)
- * PR_FALSE means encryption (or decryption) is not permitted
- *
- * There are no errors from this routine.
- */
-PRBool
-NSS_SMIMEUtil_EncryptionPossible(void)
-{
- int i;
-
- for (i = 0; i < smime_cipher_map_count; i++) {
- if (smime_cipher_map[i].allowed)
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-
-static int
-nss_SMIME_FindCipherForSMIMECap(NSSSMIMECapability *cap)
-{
- int i;
- SECOidTag capIDTag;
-
- /* we need the OIDTag here */
- capIDTag = SECOID_FindOIDTag(&(cap->capabilityID));
-
- /* go over all the SMIME ciphers we know and see if we find a match */
- for (i = 0; i < smime_cipher_map_count; i++) {
- if (smime_cipher_map[i].algtag != capIDTag)
- continue;
- /*
- * XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing
- * 2 NULLs as equal and NULL and non-NULL as not equal), we could
- * use that here instead of all of the following comparison code.
- */
- if (!smime_cipher_map[i].parms) {
- if (!cap->parameters.data || !cap->parameters.len)
- break; /* both empty: bingo */
- if (cap->parameters.len == 2 &&
- cap->parameters.data[0] == SEC_ASN1_NULL &&
- cap->parameters.data[1] == 0)
- break; /* DER NULL == NULL, bingo */
- } else if (cap->parameters.data != NULL &&
- cap->parameters.len == smime_cipher_map[i].parms->len &&
- PORT_Memcmp (cap->parameters.data, smime_cipher_map[i].parms->data,
- cap->parameters.len) == 0)
- {
- break; /* both not empty, same length & equal content: bingo */
- }
- }
-
- if (i == smime_cipher_map_count)
- return 0; /* no match found */
- return smime_cipher_map[i].cipher; /* match found, point to cipher */
-}
-
-/*
- * smime_choose_cipher - choose a cipher that works for all the recipients
- *
- * "scert" - sender's certificate
- * "rcerts" - recipient's certificates
- */
-static long
-smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
-{
- PRArenaPool *poolp;
- long cipher;
- long chosen_cipher;
- int *cipher_abilities;
- int *cipher_votes;
- int weak_mapi;
- int strong_mapi;
- int aes128_mapi;
- int aes256_mapi;
- int rcount, mapi, max, i;
-
- chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
- weak_mapi = smime_mapi_by_cipher(chosen_cipher);
- aes128_mapi = smime_mapi_by_cipher(SMIME_AES_CBC_128);
- aes256_mapi = smime_mapi_by_cipher(SMIME_AES_CBC_256);
-
- poolp = PORT_NewArena (1024); /* XXX what is right value? */
- if (poolp == NULL)
- goto done;
-
- cipher_abilities = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int));
- cipher_votes = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int));
- if (cipher_votes == NULL || cipher_abilities == NULL)
- goto done;
-
- /* Make triple-DES the strong cipher. */
- strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
-
- /* walk all the recipient's certs */
- for (rcount = 0; rcerts[rcount] != NULL; rcount++) {
- SECItem *profile;
- NSSSMIMECapability **caps;
- int pref;
-
- /* the first cipher that matches in the user's SMIME profile gets
- * "smime_cipher_map_count" votes; the next one gets "smime_cipher_map_count" - 1
- * and so on. If every cipher matches, the last one gets 1 (one) vote */
- pref = smime_cipher_map_count;
-
- /* find recipient's SMIME profile */
- profile = CERT_FindSMimeProfile(rcerts[rcount]);
-
- if (profile != NULL && profile->data != NULL && profile->len > 0) {
- /* we have a profile (still DER-encoded) */
- caps = NULL;
- /* decode it */
- if (SEC_QuickDERDecodeItem(poolp, &caps,
- NSSSMIMECapabilitiesTemplate, profile) == SECSuccess &&
- caps != NULL)
- {
- /* walk the SMIME capabilities for this recipient */
- for (i = 0; caps[i] != NULL; i++) {
- cipher = nss_SMIME_FindCipherForSMIMECap(caps[i]);
- mapi = smime_mapi_by_cipher(cipher);
- if (mapi >= 0) {
- /* found the cipher */
- cipher_abilities[mapi]++;
- cipher_votes[mapi] += pref;
- --pref;
- }
- }
- }
- } else {
- /* no profile found - so we can only assume that the user can do
- * the mandatory algorithms which are RC2-40 (weak crypto) and
- * 3DES (strong crypto), unless the user has an elliptic curve
- * key. For elliptic curve keys, RFC 5753 mandates support
- * for AES 128 CBC. */
- SECKEYPublicKey *key;
- unsigned int pklen_bits;
- KeyType key_type;
-
- /*
- * if recipient's public key length is > 512, vote for a strong cipher
- * please not that the side effect of this is that if only one recipient
- * has an export-level public key, the strong cipher is disabled.
- *
- * XXX This is probably only good for RSA keys. What I would
- * really like is a function to just say; Is the public key in
- * this cert an export-length key? Then I would not have to
- * know things like the value 512, or the kind of key, or what
- * a subjectPublicKeyInfo is, etc.
- */
- key = CERT_ExtractPublicKey(rcerts[rcount]);
- pklen_bits = 0;
- if (key != NULL) {
- pklen_bits = SECKEY_PublicKeyStrengthInBits (key);
- key_type = SECKEY_GetPublicKeyType(key);
- SECKEY_DestroyPublicKey (key);
- }
-
- if (key_type == ecKey) {
- /* While RFC 5753 mandates support for AES-128 CBC, should use
- * AES 256 if user's key provides more than 128 bits of
- * security strength so that symmetric key is not weak link. */
-
- /* RC2-40 is not compatible with elliptic curve keys. */
- chosen_cipher = SMIME_DES_EDE3_168;
- if (pklen_bits > 256) {
- cipher_abilities[aes256_mapi]++;
- cipher_votes[aes256_mapi] += pref;
- pref--;
- }
- cipher_abilities[aes128_mapi]++;
- cipher_votes[aes128_mapi] += pref;
- pref--;
- cipher_abilities[strong_mapi]++;
- cipher_votes[strong_mapi] += pref;
- pref--;
- } else {
- if (pklen_bits > 512) {
- /* cast votes for the strong algorithm */
- cipher_abilities[strong_mapi]++;
- cipher_votes[strong_mapi] += pref;
- pref--;
- }
-
- /* always cast (possibly less) votes for the weak algorithm */
- cipher_abilities[weak_mapi]++;
- cipher_votes[weak_mapi] += pref;
- }
- }
- if (profile != NULL)
- SECITEM_FreeItem(profile, PR_TRUE);
- }
-
- /* find cipher that is agreeable by all recipients and that has the most votes */
- max = 0;
- for (mapi = 0; mapi < smime_cipher_map_count; mapi++) {
- /* if not all of the recipients can do this, forget it */
- if (cipher_abilities[mapi] != rcount)
- continue;
- /* if cipher is not enabled or not allowed by policy, forget it */
- if (!smime_cipher_map[mapi].enabled || !smime_cipher_map[mapi].allowed)
- continue;
- /* now see if this one has more votes than the last best one */
- if (cipher_votes[mapi] >= max) {
- /* if equal number of votes, prefer the ones further down in the list */
- /* with the expectation that these are higher rated ciphers */
- chosen_cipher = smime_cipher_map[mapi].cipher;
- max = cipher_votes[mapi];
- }
- }
- /* if no common cipher was found, chosen_cipher stays at the default */
-
-done:
- if (poolp != NULL)
- PORT_FreeArena (poolp, PR_FALSE);
-
- return chosen_cipher;
-}
-
-/*
- * XXX This is a hack for now to satisfy our current interface.
- * Eventually, with more parameters needing to be specified, just
- * looking up the keysize is not going to be sufficient.
- */
-static int
-smime_keysize_by_cipher (unsigned long which)
-{
- int keysize;
-
- switch (which) {
- case SMIME_RC2_CBC_40:
- keysize = 40;
- break;
- case SMIME_RC2_CBC_64:
- keysize = 64;
- break;
- case SMIME_RC2_CBC_128:
- case SMIME_AES_CBC_128:
- keysize = 128;
- break;
- case SMIME_AES_CBC_256:
- keysize = 256;
- break;
- case SMIME_DES_CBC_56:
- case SMIME_DES_EDE3_168:
- /*
- * These are special; since the key size is fixed, we actually
- * want to *avoid* specifying a key size.
- */
- keysize = 0;
- break;
- default:
- keysize = -1;
- break;
- }
-
- return keysize;
-}
-
-/*
- * NSS_SMIMEUtil_FindBulkAlgForRecipients - find bulk algorithm suitable for all recipients
- *
- * it would be great for UI purposes if there would be a way to find out which recipients
- * prevented a strong cipher from being used...
- */
-SECStatus
-NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulkalgtag, int *keysize)
-{
- unsigned long cipher;
- int mapi;
-
- cipher = smime_choose_cipher(NULL, rcerts);
- mapi = smime_mapi_by_cipher(cipher);
-
- *bulkalgtag = smime_cipher_map[mapi].algtag;
- *keysize = smime_keysize_by_cipher(smime_cipher_map[mapi].cipher);
-
- return SECSuccess;
-}
-
-/*
- * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities for this instance of NSS
- *
- * scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
- * S/MIME capabilities attribute value.
- *
- * XXX Please note that, in contradiction to RFC2633 2.5.2, the capabilities only include
- * symmetric ciphers, NO signature algorithms or key encipherment algorithms.
- *
- * "poolp" - arena pool to create the S/MIME capabilities data on
- * "dest" - SECItem to put the data in
- */
-SECStatus
-NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest)
-{
- NSSSMIMECapability *cap;
- NSSSMIMECapability **smime_capabilities;
- smime_cipher_map_entry *map;
- SECOidData *oiddata;
- SECItem *dummy;
- int i, capIndex;
-
- /* if we have an old NSSSMIMECapability array, we'll reuse it (has the right size) */
- /* smime_cipher_map_count + 1 is an upper bound - we might end up with less */
- smime_capabilities = (NSSSMIMECapability **)PORT_ZAlloc((smime_cipher_map_count + 1)
- * sizeof(NSSSMIMECapability *));
- if (smime_capabilities == NULL)
- return SECFailure;
-
- capIndex = 0;
-
- /* Add all the symmetric ciphers
- * We walk the cipher list backwards, as it is ordered by increasing strength,
- * we prefer the stronger cipher over a weaker one, and we have to list the
- * preferred algorithm first */
- for (i = smime_cipher_map_count - 1; i >= 0; i--) {
- /* Find the corresponding entry in the cipher map. */
- map = &(smime_cipher_map[i]);
- if (!map->enabled)
- continue;
-
- /* get next SMIME capability */
- cap = (NSSSMIMECapability *)PORT_ZAlloc(sizeof(NSSSMIMECapability));
- if (cap == NULL)
- break;
- smime_capabilities[capIndex++] = cap;
-
- oiddata = SECOID_FindOIDByTag(map->algtag);
- if (oiddata == NULL)
- break;
-
- cap->capabilityID.data = oiddata->oid.data;
- cap->capabilityID.len = oiddata->oid.len;
- cap->parameters.data = map->parms ? map->parms->data : NULL;
- cap->parameters.len = map->parms ? map->parms->len : 0;
- cap->cipher = smime_cipher_map[i].cipher;
- }
-
- /* XXX add signature algorithms */
- /* XXX add key encipherment algorithms */
-
- smime_capabilities[capIndex] = NULL; /* last one - now encode */
- dummy = SEC_ASN1EncodeItem(poolp, dest, &smime_capabilities, NSSSMIMECapabilitiesTemplate);
-
- /* now that we have the proper encoded SMIMECapabilities (or not),
- * free the work data */
- for (i = 0; smime_capabilities[i] != NULL; i++)
- PORT_Free(smime_capabilities[i]);
- PORT_Free(smime_capabilities);
-
- return (dummy == NULL) ? SECFailure : SECSuccess;
-}
-
-/*
- * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value
- *
- * "poolp" - arena pool to create the attr value on
- * "dest" - SECItem to put the data in
- * "cert" - certificate that should be marked as preferred encryption key
- * cert is expected to have been verified for EmailRecipient usage.
- */
-SECStatus
-NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert)
-{
- NSSSMIMEEncryptionKeyPreference ekp;
- SECItem *dummy = NULL;
- PLArenaPool *tmppoolp = NULL;
-
- if (cert == NULL)
- goto loser;
-
- tmppoolp = PORT_NewArena(1024);
- if (tmppoolp == NULL)
- goto loser;
-
- /* XXX hardcoded IssuerSN choice for now */
- ekp.selector = NSSSMIMEEncryptionKeyPref_IssuerSN;
- ekp.id.issuerAndSN = CERT_GetCertIssuerAndSN(tmppoolp, cert);
- if (ekp.id.issuerAndSN == NULL)
- goto loser;
-
- dummy = SEC_ASN1EncodeItem(poolp, dest, &ekp, smime_encryptionkeypref_template);
-
-loser:
- if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
-
- return (dummy == NULL) ? SECFailure : SECSuccess;
-}
-
-/*
- * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value using MS oid
- *
- * "poolp" - arena pool to create the attr value on
- * "dest" - SECItem to put the data in
- * "cert" - certificate that should be marked as preferred encryption key
- * cert is expected to have been verified for EmailRecipient usage.
- */
-SECStatus
-NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert)
-{
- SECItem *dummy = NULL;
- PLArenaPool *tmppoolp = NULL;
- CERTIssuerAndSN *isn;
-
- if (cert == NULL)
- goto loser;
-
- tmppoolp = PORT_NewArena(1024);
- if (tmppoolp == NULL)
- goto loser;
-
- isn = CERT_GetCertIssuerAndSN(tmppoolp, cert);
- if (isn == NULL)
- goto loser;
-
- dummy = SEC_ASN1EncodeItem(poolp, dest, isn, SEC_ASN1_GET(CERT_IssuerAndSNTemplate));
-
-loser:
- if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
-
- return (dummy == NULL) ? SECFailure : SECSuccess;
-}
-
-/*
- * NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference -
- * find cert marked by EncryptionKeyPreference attribute
- *
- * "certdb" - handle for the cert database to look in
- * "DERekp" - DER-encoded value of S/MIME Encryption Key Preference attribute
- *
- * if certificate is supposed to be found among the message's included certificates,
- * they are assumed to have been imported already.
- */
-CERTCertificate *
-NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECItem *DERekp)
-{
- PLArenaPool *tmppoolp = NULL;
- CERTCertificate *cert = NULL;
- NSSSMIMEEncryptionKeyPreference ekp;
-
- tmppoolp = PORT_NewArena(1024);
- if (tmppoolp == NULL)
- return NULL;
-
- /* decode DERekp */
- if (SEC_QuickDERDecodeItem(tmppoolp, &ekp, smime_encryptionkeypref_template,
- DERekp) != SECSuccess)
- goto loser;
-
- /* find cert */
- switch (ekp.selector) {
- case NSSSMIMEEncryptionKeyPref_IssuerSN:
- cert = CERT_FindCertByIssuerAndSN(certdb, ekp.id.issuerAndSN);
- break;
- case NSSSMIMEEncryptionKeyPref_RKeyID:
- case NSSSMIMEEncryptionKeyPref_SubjectKeyID:
- /* XXX not supported yet - we need to be able to look up certs by SubjectKeyID */
- break;
- default:
- PORT_Assert(0);
- }
-loser:
- if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
-
- return cert;
-}
-
-extern const char __nss_smime_rcsid[];
-extern const char __nss_smime_sccsid[];
-
-PRBool
-NSSSMIME_VersionCheck(const char *importedVersion)
-{
- /*
- * This is the secret handshake algorithm.
- *
- * This release has a simple version compatibility
- * check algorithm. This release is not backward
- * compatible with previous major releases. It is
- * not compatible with future major, minor, or
- * patch releases.
- */
- volatile char c; /* force a reference that won't get optimized away */
-
- c = __nss_smime_rcsid[0] + __nss_smime_sccsid[0];
-
- return NSS_VersionCheck(importedVersion);
-}
-
-const char *
-NSSSMIME_GetVersion(void)
-{
- return NSS_VERSION;
-}
diff --git a/security/nss/lib/smime/smimever.c b/security/nss/lib/smime/smimever.c
deleted file mode 100644
index 917bbf59d..000000000
--- a/security/nss/lib/smime/smimever.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Library identity and versioning */
-
-#include "nss.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_smime_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_smime_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/softoken/Makefile b/security/nss/lib/softoken/Makefile
deleted file mode 100644
index b2f33e260..000000000
--- a/security/nss/lib/softoken/Makefile
+++ /dev/null
@@ -1,68 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-ifdef NSS_DISABLE_DBM
-DIRS=
-endif
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
-# indicates dependency on freebl static lib
-$(SHARED_LIBRARY): $(CRYPTOLIB)
-
-# On AIX 4.3, IBM xlC_r compiler (version 3.6.6) cannot compile
-# pkcs11c.c in 64-bit mode for unknown reasons. A workaround is
-# to compile it with optimizations turned on. (Bugzilla bug #63815)
-ifeq ($(OS_TARGET)$(OS_RELEASE),AIX4.3)
-ifeq ($(USE_64),1)
-ifndef BUILD_OPT
-$(OBJDIR)/pkcs11.o: pkcs11.c
- @$(MAKE_OBJDIR)
- $(CC) -o $@ -c -O2 $(CFLAGS) $<
-$(OBJDIR)/pkcs11c.o: pkcs11c.c
- @$(MAKE_OBJDIR)
- $(CC) -o $@ -c -O2 $(CFLAGS) $<
-endif
-endif
-endif
diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk
deleted file mode 100644
index 908d1d97e..000000000
--- a/security/nss/lib/softoken/config.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
-CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX)
-
-EXTRA_LIBS += \
- $(CRYPTOLIB) \
- $(NULL)
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
-
-RES = $(OBJDIR)/$(LIBRARY_NAME).res
-RESNAME = $(LIBRARY_NAME).rc
-
-ifdef NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -l$(SQLITE_LIB_NAME) \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-else # ! NS_USE_GCC
-
-EXTRA_SHARED_LIBS += \
- $(DIST)/lib/$(SQLITE_LIB_NAME).lib \
- $(NSSUTIL_LIB_DIR)/nssutil3.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-
-else
-
-# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
-# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -l$(SQLITE_LIB_NAME) \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-endif
-
-ifeq ($(OS_TARGET),AIX)
-OS_LIBS += -lpthread
-endif
-
-ifeq ($(OS_TARGET),SunOS)
-OS_LIBS += -lbsm
-endif
diff --git a/security/nss/lib/softoken/ecdecode.c b/security/nss/lib/softoken/ecdecode.c
deleted file mode 100644
index ead09f58b..000000000
--- a/security/nss/lib/softoken/ecdecode.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef NSS_ENABLE_ECC
-
-#include "blapi.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "secerr.h"
-#include "ec.h"
-#include "ecl-curve.h"
-
-#define CHECK_OK(func) if (func == NULL) goto cleanup
-#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
-
-/*
- * Initializes a SECItem from a hexadecimal string
- *
- * Warning: This function ignores leading 00's, so any leading 00's
- * in the hexadecimal string must be optional.
- */
-static SECItem *
-hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str)
-{
- int i = 0;
- int byteval = 0;
- int tmp = PORT_Strlen(str);
-
- if ((tmp % 2) != 0) return NULL;
-
- /* skip leading 00's unless the hex string is "00" */
- while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
- str += 2;
- tmp -= 2;
- }
-
- item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2);
- if (item->data == NULL) return NULL;
- item->len = tmp/2;
-
- while (str[i]) {
- if ((str[i] >= '0') && (str[i] <= '9'))
- tmp = str[i] - '0';
- else if ((str[i] >= 'a') && (str[i] <= 'f'))
- tmp = str[i] - 'a' + 10;
- else if ((str[i] >= 'A') && (str[i] <= 'F'))
- tmp = str[i] - 'A' + 10;
- else
- return NULL;
-
- byteval = byteval * 16 + tmp;
- if ((i % 2) != 0) {
- item->data[i/2] = byteval;
- byteval = 0;
- }
- i++;
- }
-
- return item;
-}
-
-/* Copy all of the fields from srcParams into dstParams
- */
-SECStatus
-EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
- const ECParams *srcParams)
-{
- SECStatus rv = SECFailure;
-
- dstParams->arena = arena;
- dstParams->type = srcParams->type;
- dstParams->fieldID.size = srcParams->fieldID.size;
- dstParams->fieldID.type = srcParams->fieldID.type;
- if (srcParams->fieldID.type == ec_field_GFp) {
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.prime,
- &srcParams->fieldID.u.prime));
- } else {
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.poly,
- &srcParams->fieldID.u.poly));
- }
- dstParams->fieldID.k1 = srcParams->fieldID.k1;
- dstParams->fieldID.k2 = srcParams->fieldID.k2;
- dstParams->fieldID.k3 = srcParams->fieldID.k3;
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.a,
- &srcParams->curve.a));
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.b,
- &srcParams->curve.b));
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.seed,
- &srcParams->curve.seed));
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->base,
- &srcParams->base));
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->order,
- &srcParams->order));
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->DEREncoding,
- &srcParams->DEREncoding));
- dstParams->name = srcParams->name;
- CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curveOID,
- &srcParams->curveOID));
- dstParams->cofactor = srcParams->cofactor;
-
- return SECSuccess;
-
-cleanup:
- return SECFailure;
-}
-
-static SECStatus
-gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params)
-{
- SECStatus rv = SECFailure;
- const ECCurveParams *curveParams;
- /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
- char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
-
- if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup;
- params->name = name;
- curveParams = ecCurve_map[params->name];
- CHECK_OK(curveParams);
- params->fieldID.size = curveParams->size;
- params->fieldID.type = field_type;
- if (field_type == ec_field_GFp) {
- CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime,
- curveParams->irr));
- } else {
- CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.poly,
- curveParams->irr));
- }
- CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
- curveParams->curvea));
- CHECK_OK(hexString2SECItem(params->arena, &params->curve.b,
- curveParams->curveb));
- genenc[0] = '0';
- genenc[1] = '4';
- genenc[2] = '\0';
- strcat(genenc, curveParams->genx);
- strcat(genenc, curveParams->geny);
- CHECK_OK(hexString2SECItem(params->arena, &params->base, genenc));
- CHECK_OK(hexString2SECItem(params->arena, &params->order,
- curveParams->order));
- params->cofactor = curveParams->cofactor;
-
- rv = SECSuccess;
-
-cleanup:
- return rv;
-}
-
-SECStatus
-EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
- ECParams *params)
-{
- SECStatus rv = SECFailure;
- SECOidTag tag;
- SECItem oid = { siBuffer, NULL, 0};
-
-#if EC_DEBUG
- int i;
-
- printf("Encoded params in EC_DecodeParams: ");
- for (i = 0; i < encodedParams->len; i++) {
- printf("%02x:", encodedParams->data[i]);
- }
- printf("\n");
-#endif
-
- if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
- (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- return SECFailure;
- };
-
- oid.len = encodedParams->len - 2;
- oid.data = encodedParams->data + 2;
- if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
- ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- return SECFailure;
- }
-
- params->arena = arena;
- params->cofactor = 0;
- params->type = ec_params_named;
- params->name = ECCurve_noName;
-
- /* For named curves, fill out curveOID */
- params->curveOID.len = oid.len;
- params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len);
- if (params->curveOID.data == NULL) goto cleanup;
- memcpy(params->curveOID.data, oid.data, oid.len);
-
-#if EC_DEBUG
- printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
-#endif
-
- switch (tag) {
-
- /* Binary curves */
-
- case SEC_OID_ANSIX962_EC_C2PNB163V1:
- /* Populate params for c2pnb163v1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2PNB163V2:
- /* Populate params for c2pnb163v2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2PNB163V3:
- /* Populate params for c2pnb163v3 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2PNB176V1:
- /* Populate params for c2pnb176v1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2TNB191V1:
- /* Populate params for c2tnb191v1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2TNB191V2:
- /* Populate params for c2tnb191v2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2TNB191V3:
- /* Populate params for c2tnb191v3 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2PNB208W1:
- /* Populate params for c2pnb208w1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2TNB239V1:
- /* Populate params for c2tnb239v1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2TNB239V2:
- /* Populate params for c2tnb239v2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2TNB239V3:
- /* Populate params for c2tnb239v3 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2PNB272W1:
- /* Populate params for c2pnb272w1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2PNB304W1:
- /* Populate params for c2pnb304w1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2TNB359V1:
- /* Populate params for c2tnb359v1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2PNB368W1:
- /* Populate params for c2pnb368w1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_C2TNB431R1:
- /* Populate params for c2tnb431r1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT113R1:
- /* Populate params for sect113r1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT113R2:
- /* Populate params for sect113r2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT131R1:
- /* Populate params for sect131r1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT131R2:
- /* Populate params for sect131r2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT163K1:
- /* Populate params for sect163k1
- * (the NIST K-163 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT163R1:
- /* Populate params for sect163r1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT163R2:
- /* Populate params for sect163r2
- * (the NIST B-163 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT193R1:
- /* Populate params for sect193r1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT193R2:
- /* Populate params for sect193r2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT233K1:
- /* Populate params for sect233k1
- * (the NIST K-233 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT233R1:
- /* Populate params for sect233r1
- * (the NIST B-233 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT239K1:
- /* Populate params for sect239k1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT283K1:
- /* Populate params for sect283k1
- * (the NIST K-283 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT283R1:
- /* Populate params for sect283r1
- * (the NIST B-283 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT409K1:
- /* Populate params for sect409k1
- * (the NIST K-409 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT409R1:
- /* Populate params for sect409r1
- * (the NIST B-409 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT571K1:
- /* Populate params for sect571k1
- * (the NIST K-571 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECT571R1:
- /* Populate params for sect571r1
- * (the NIST B-571 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,
- params) );
- break;
-
- /* Prime curves */
-
- case SEC_OID_ANSIX962_EC_PRIME192V1:
- /* Populate params for prime192v1 aka secp192r1
- * (the NIST P-192 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_PRIME192V2:
- /* Populate params for prime192v2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_PRIME192V3:
- /* Populate params for prime192v3 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_PRIME239V1:
- /* Populate params for prime239v1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_PRIME239V2:
- /* Populate params for prime239v2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_PRIME239V3:
- /* Populate params for prime239v3 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_ANSIX962_EC_PRIME256V1:
- /* Populate params for prime256v1 aka secp256r1
- * (the NIST P-256 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP112R1:
- /* Populate params for secp112r1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP112R2:
- /* Populate params for secp112r2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP128R1:
- /* Populate params for secp128r1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP128R2:
- /* Populate params for secp128r2 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP160K1:
- /* Populate params for secp160k1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP160R1:
- /* Populate params for secp160r1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP160R2:
- /* Populate params for secp160r1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP192K1:
- /* Populate params for secp192k1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP224K1:
- /* Populate params for secp224k1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP224R1:
- /* Populate params for secp224r1
- * (the NIST P-224 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP256K1:
- /* Populate params for secp256k1 */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP384R1:
- /* Populate params for secp384r1
- * (the NIST P-384 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
- params) );
- break;
-
- case SEC_OID_SECG_EC_SECP521R1:
- /* Populate params for secp521r1
- * (the NIST P-521 curve)
- */
- CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
- params) );
- break;
-
- default:
- break;
- };
-
-cleanup:
- if (!params->cofactor) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
-#if EC_DEBUG
- printf("Unrecognized curve, returning NULL params\n");
-#endif
- }
-
- return rv;
-}
-
-SECStatus
-EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams)
-{
- PRArenaPool *arena;
- ECParams *params;
- SECStatus rv = SECFailure;
-
- /* Initialize an arena for the ECParams structure */
- if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
- return SECFailure;
-
- params = (ECParams *)PORT_ArenaZAlloc(arena, sizeof(ECParams));
- if (!params) {
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
- }
-
- /* Copy the encoded params */
- SECITEM_AllocItem(arena, &(params->DEREncoding),
- encodedParams->len);
- memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
-
- /* Fill out the rest of the ECParams structure based on
- * the encoded params
- */
- rv = EC_FillParams(arena, encodedParams, params);
- if (rv == SECFailure) {
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
- } else {
- *ecparams = params;;
- return SECSuccess;
- }
-}
-
-#endif /* NSS_ENABLE_ECC */
diff --git a/security/nss/lib/softoken/fipsaudt.c b/security/nss/lib/softoken/fipsaudt.c
deleted file mode 100644
index b026374b3..000000000
--- a/security/nss/lib/softoken/fipsaudt.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * This file implements audit logging required by FIPS 140-2 Security
- * Level 2.
- */
-
-#include "prprf.h"
-#include "softoken.h"
-
-/*
- * Print the value of the returned object handle in the output buffer
- * on a successful return of the PKCS #11 function. If the PKCS #11
- * function failed or the pointer to object handle is NULL (which is
- * the case for C_DeriveKey with CKM_TLS_KEY_AND_MAC_DERIVE), an empty
- * string is stored in the output buffer.
- *
- * out: the output buffer
- * outlen: the length of the output buffer
- * argName: the name of the "pointer to object handle" argument
- * phObject: the pointer to object handle
- * rv: the return value of the PKCS #11 function
- */
-static void sftk_PrintReturnedObjectHandle(char *out, PRUint32 outlen,
- const char *argName, CK_OBJECT_HANDLE_PTR phObject, CK_RV rv)
-{
- if ((rv == CKR_OK) && phObject) {
- PR_snprintf(out, outlen,
- " *%s=0x%08lX", argName, (PRUint32)*phObject);
- } else {
- PORT_Assert(outlen != 0);
- out[0] = '\0';
- }
-}
-
-/*
- * MECHANISM_BUFSIZE needs to be large enough for sftk_PrintMechanism,
- * which uses <= 49 bytes.
- */
-#define MECHANISM_BUFSIZE 64
-
-static void sftk_PrintMechanism(char *out, PRUint32 outlen,
- CK_MECHANISM_PTR pMechanism)
-{
- if (pMechanism) {
- /*
- * If we change the format string, we need to make sure
- * MECHANISM_BUFSIZE is still large enough. We allow
- * 20 bytes for %p on a 64-bit platform.
- */
- PR_snprintf(out, outlen, "%p {mechanism=0x%08lX, ...}",
- pMechanism, (PRUint32)pMechanism->mechanism);
- } else {
- PR_snprintf(out, outlen, "%p", pMechanism);
- }
-}
-
-void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject, CK_RV rv)
-{
- char msg[256];
- char shObject[32];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- sftk_PrintReturnedObjectHandle(shObject, sizeof shObject,
- "phObject", phObject, rv);
- PR_snprintf(msg, sizeof msg,
- "C_CreateObject(hSession=0x%08lX, pTemplate=%p, ulCount=%lu, "
- "phObject=%p)=0x%08lX%s",
- (PRUint32)hSession, pTemplate, (PRUint32)ulCount,
- phObject, (PRUint32)rv, shObject);
- sftk_LogAuditMessage(severity, NSS_AUDIT_LOAD_KEY, msg);
-}
-
-void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv)
-{
- char msg[256];
- char shNewObject[32];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- sftk_PrintReturnedObjectHandle(shNewObject, sizeof shNewObject,
- "phNewObject", phNewObject, rv);
- PR_snprintf(msg, sizeof msg,
- "C_CopyObject(hSession=0x%08lX, hObject=0x%08lX, "
- "pTemplate=%p, ulCount=%lu, phNewObject=%p)=0x%08lX%s",
- (PRUint32)hSession, (PRUint32)hObject,
- pTemplate, (PRUint32)ulCount, phNewObject, (PRUint32)rv, shNewObject);
- sftk_LogAuditMessage(severity, NSS_AUDIT_COPY_KEY, msg);
-}
-
-/* WARNING: hObject has been destroyed and can only be printed. */
-void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_RV rv)
-{
- char msg[256];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- PR_snprintf(msg, sizeof msg,
- "C_DestroyObject(hSession=0x%08lX, hObject=0x%08lX)=0x%08lX",
- (PRUint32)hSession, (PRUint32)hObject, (PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_DESTROY_KEY, msg);
-}
-
-void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize, CK_RV rv)
-{
- char msg[256];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- PR_snprintf(msg, sizeof msg,
- "C_GetObjectSize(hSession=0x%08lX, hObject=0x%08lX, "
- "pulSize=%p)=0x%08lX",
- (PRUint32)hSession, (PRUint32)hObject,
- pulSize, (PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_ACCESS_KEY, msg);
-}
-
-void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount, CK_RV rv)
-{
- char msg[256];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- PR_snprintf(msg, sizeof msg,
- "C_GetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, "
- "pTemplate=%p, ulCount=%lu)=0x%08lX",
- (PRUint32)hSession, (PRUint32)hObject,
- pTemplate, (PRUint32)ulCount, (PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_ACCESS_KEY, msg);
-}
-
-void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount, CK_RV rv)
-{
- char msg[256];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- PR_snprintf(msg, sizeof msg,
- "C_SetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, "
- "pTemplate=%p, ulCount=%lu)=0x%08lX",
- (PRUint32)hSession, (PRUint32)hObject,
- pTemplate, (PRUint32)ulCount, (PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_CHANGE_KEY, msg);
-}
-
-void sftk_AuditCryptInit(const char *opName, CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_RV rv)
-{
- char msg[256];
- char mech[MECHANISM_BUFSIZE];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- sftk_PrintMechanism(mech, sizeof mech, pMechanism);
- PR_snprintf(msg, sizeof msg,
- "C_%sInit(hSession=0x%08lX, pMechanism=%s, "
- "hKey=0x%08lX)=0x%08lX",
- opName, (PRUint32)hSession, mech,
- (PRUint32)hKey, (PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_CRYPT, msg);
-}
-
-void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey, CK_RV rv)
-{
- char msg[256];
- char mech[MECHANISM_BUFSIZE];
- char shKey[32];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- sftk_PrintMechanism(mech, sizeof mech, pMechanism);
- sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv);
- PR_snprintf(msg, sizeof msg,
- "C_GenerateKey(hSession=0x%08lX, pMechanism=%s, "
- "pTemplate=%p, ulCount=%lu, phKey=%p)=0x%08lX%s",
- (PRUint32)hSession, mech,
- pTemplate, (PRUint32)ulCount, phKey, (PRUint32)rv, shKey);
- sftk_LogAuditMessage(severity, NSS_AUDIT_GENERATE_KEY, msg);
-}
-
-void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv)
-{
- char msg[512];
- char mech[MECHANISM_BUFSIZE];
- char shPublicKey[32];
- char shPrivateKey[32];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- sftk_PrintMechanism(mech, sizeof mech, pMechanism);
- sftk_PrintReturnedObjectHandle(shPublicKey, sizeof shPublicKey,
- "phPublicKey", phPublicKey, rv);
- sftk_PrintReturnedObjectHandle(shPrivateKey, sizeof shPrivateKey,
- "phPrivateKey", phPrivateKey, rv);
- PR_snprintf(msg, sizeof msg,
- "C_GenerateKeyPair(hSession=0x%08lX, pMechanism=%s, "
- "pPublicKeyTemplate=%p, ulPublicKeyAttributeCount=%lu, "
- "pPrivateKeyTemplate=%p, ulPrivateKeyAttributeCount=%lu, "
- "phPublicKey=%p, phPrivateKey=%p)=0x%08lX%s%s",
- (PRUint32)hSession, mech,
- pPublicKeyTemplate, (PRUint32)ulPublicKeyAttributeCount,
- pPrivateKeyTemplate, (PRUint32)ulPrivateKeyAttributeCount,
- phPublicKey, phPrivateKey, (PRUint32)rv, shPublicKey, shPrivateKey);
- sftk_LogAuditMessage(severity, NSS_AUDIT_GENERATE_KEY, msg);
-}
-
-void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv)
-{
- char msg[256];
- char mech[MECHANISM_BUFSIZE];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- sftk_PrintMechanism(mech, sizeof mech, pMechanism);
- PR_snprintf(msg, sizeof msg,
- "C_WrapKey(hSession=0x%08lX, pMechanism=%s, hWrappingKey=0x%08lX, "
- "hKey=0x%08lX, pWrappedKey=%p, pulWrappedKeyLen=%p)=0x%08lX",
- (PRUint32)hSession, mech, (PRUint32)hWrappingKey,
- (PRUint32)hKey, pWrappedKey, pulWrappedKeyLen, (PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_WRAP_KEY, msg);
-}
-
-void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey, CK_RV rv)
-{
- char msg[256];
- char mech[MECHANISM_BUFSIZE];
- char shKey[32];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- sftk_PrintMechanism(mech, sizeof mech, pMechanism);
- sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv);
- PR_snprintf(msg, sizeof msg,
- "C_UnwrapKey(hSession=0x%08lX, pMechanism=%s, "
- "hUnwrappingKey=0x%08lX, pWrappedKey=%p, ulWrappedKeyLen=%lu, "
- "pTemplate=%p, ulAttributeCount=%lu, phKey=%p)=0x%08lX%s",
- (PRUint32)hSession, mech,
- (PRUint32)hUnwrappingKey, pWrappedKey, (PRUint32)ulWrappedKeyLen,
- pTemplate, (PRUint32)ulAttributeCount, phKey, (PRUint32)rv, shKey);
- sftk_LogAuditMessage(severity, NSS_AUDIT_UNWRAP_KEY, msg);
-}
-
-void sftk_AuditDeriveKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey, CK_RV rv)
-{
- char msg[512];
- char mech[MECHANISM_BUFSIZE];
- char shKey[32];
- char sTlsKeys[128];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- sftk_PrintMechanism(mech, sizeof mech, pMechanism);
- sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv);
- if ((rv == CKR_OK) &&
- (pMechanism->mechanism == CKM_TLS_KEY_AND_MAC_DERIVE)) {
- CK_SSL3_KEY_MAT_PARAMS *param =
- (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter;
- CK_SSL3_KEY_MAT_OUT *keymat = param->pReturnedKeyMaterial;
- PR_snprintf(sTlsKeys, sizeof sTlsKeys,
- " hClientMacSecret=0x%08lX hServerMacSecret=0x%08lX"
- " hClientKey=0x%08lX hServerKey=0x%08lX",
- (PRUint32)keymat->hClientMacSecret,
- (PRUint32)keymat->hServerMacSecret,
- (PRUint32)keymat->hClientKey,
- (PRUint32)keymat->hServerKey);
- } else {
- sTlsKeys[0] = '\0';
- }
- PR_snprintf(msg, sizeof msg,
- "C_DeriveKey(hSession=0x%08lX, pMechanism=%s, "
- "hBaseKey=0x%08lX, pTemplate=%p, ulAttributeCount=%lu, "
- "phKey=%p)=0x%08lX%s%s",
- (PRUint32)hSession, mech,
- (PRUint32)hBaseKey, pTemplate,(PRUint32)ulAttributeCount,
- phKey, (PRUint32)rv, shKey, sTlsKeys);
- sftk_LogAuditMessage(severity, NSS_AUDIT_DERIVE_KEY, msg);
-}
-
-void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey, CK_RV rv)
-{
- char msg[256];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
-
- PR_snprintf(msg, sizeof msg,
- "C_DigestKey(hSession=0x%08lX, hKey=0x%08lX)=0x%08lX",
- (PRUint32)hSession, (PRUint32)hKey, (PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_DIGEST_KEY, msg);
-}
diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c
deleted file mode 100644
index c73a79c65..000000000
--- a/security/nss/lib/softoken/fipstest.c
+++ /dev/null
@@ -1,2101 +0,0 @@
-/*
- * PKCS #11 FIPS Power-Up Self Test.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "softoken.h" /* Required for RC2-ECB, RC2-CBC, RC4, DES-ECB, */
- /* DES-CBC, DES3-ECB, DES3-CBC, RSA */
- /* and DSA. */
-#include "seccomon.h" /* Required for RSA and DSA. */
-#include "lowkeyi.h" /* Required for RSA and DSA. */
-#include "pkcs11.h" /* Required for PKCS #11. */
-#include "secerr.h"
-
-#ifdef NSS_ENABLE_ECC
-#include "ec.h" /* Required for ECDSA */
-#endif
-
-
-/* FIPS preprocessor directives for RC2-ECB and RC2-CBC. */
-#define FIPS_RC2_KEY_LENGTH 5 /* 40-bits */
-#define FIPS_RC2_ENCRYPT_LENGTH 8 /* 64-bits */
-#define FIPS_RC2_DECRYPT_LENGTH 8 /* 64-bits */
-
-
-/* FIPS preprocessor directives for RC4. */
-#define FIPS_RC4_KEY_LENGTH 5 /* 40-bits */
-#define FIPS_RC4_ENCRYPT_LENGTH 8 /* 64-bits */
-#define FIPS_RC4_DECRYPT_LENGTH 8 /* 64-bits */
-
-
-/* FIPS preprocessor directives for DES-ECB and DES-CBC. */
-#define FIPS_DES_ENCRYPT_LENGTH 8 /* 64-bits */
-#define FIPS_DES_DECRYPT_LENGTH 8 /* 64-bits */
-
-
-/* FIPS preprocessor directives for DES3-CBC and DES3-ECB. */
-#define FIPS_DES3_ENCRYPT_LENGTH 8 /* 64-bits */
-#define FIPS_DES3_DECRYPT_LENGTH 8 /* 64-bits */
-
-
-/* FIPS preprocessor directives for AES-ECB and AES-CBC. */
-#define FIPS_AES_BLOCK_SIZE 16 /* 128-bits */
-#define FIPS_AES_ENCRYPT_LENGTH 16 /* 128-bits */
-#define FIPS_AES_DECRYPT_LENGTH 16 /* 128-bits */
-#define FIPS_AES_128_KEY_SIZE 16 /* 128-bits */
-#define FIPS_AES_192_KEY_SIZE 24 /* 192-bits */
-#define FIPS_AES_256_KEY_SIZE 32 /* 256-bits */
-
-
-/* FIPS preprocessor directives for message digests */
-#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
-
-
-/* FIPS preprocessor directives for RSA. */
-#define FIPS_RSA_TYPE siBuffer
-#define FIPS_RSA_PUBLIC_EXPONENT_LENGTH 3 /* 24-bits */
-#define FIPS_RSA_PRIVATE_VERSION_LENGTH 1 /* 8-bits */
-#define FIPS_RSA_MESSAGE_LENGTH 256 /* 2048-bits */
-#define FIPS_RSA_COEFFICIENT_LENGTH 128 /* 1024-bits */
-#define FIPS_RSA_PRIME0_LENGTH 128 /* 1024-bits */
-#define FIPS_RSA_PRIME1_LENGTH 128 /* 1024-bits */
-#define FIPS_RSA_EXPONENT0_LENGTH 128 /* 1024-bits */
-#define FIPS_RSA_EXPONENT1_LENGTH 128 /* 1024-bits */
-#define FIPS_RSA_PRIVATE_EXPONENT_LENGTH 256 /* 2048-bits */
-#define FIPS_RSA_ENCRYPT_LENGTH 256 /* 2048-bits */
-#define FIPS_RSA_DECRYPT_LENGTH 256 /* 2048-bits */
-#define FIPS_RSA_SIGNATURE_LENGTH 256 /* 2048-bits */
-#define FIPS_RSA_MODULUS_LENGTH 256 /* 2048-bits */
-
-
-/* FIPS preprocessor directives for DSA. */
-#define FIPS_DSA_TYPE siBuffer
-#define FIPS_DSA_DIGEST_LENGTH 20 /* 160-bits */
-#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */
-#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */
-#define FIPS_DSA_PRIME_LENGTH 128 /* 1024-bits */
-#define FIPS_DSA_BASE_LENGTH 128 /* 1024-bits */
-
-/* FIPS preprocessor directives for RNG. */
-#define FIPS_RNG_XKEY_LENGTH 32 /* 256-bits */
-
-static CK_RV
-sftk_fips_RC2_PowerUpSelfTest( void )
-{
- /* RC2 Known Key (40-bits). */
- static const PRUint8 rc2_known_key[] = { "RSARC" };
-
- /* RC2-CBC Known Initialization Vector (64-bits). */
- static const PRUint8 rc2_cbc_known_initialization_vector[] = {"Security"};
-
- /* RC2 Known Plaintext (64-bits). */
- static const PRUint8 rc2_ecb_known_plaintext[] = {"Netscape"};
- static const PRUint8 rc2_cbc_known_plaintext[] = {"Netscape"};
-
- /* RC2 Known Ciphertext (64-bits). */
- static const PRUint8 rc2_ecb_known_ciphertext[] = {
- 0x1a,0x71,0x33,0x54,0x8d,0x5c,0xd2,0x30};
- static const PRUint8 rc2_cbc_known_ciphertext[] = {
- 0xff,0x41,0xdb,0x94,0x8a,0x4c,0x33,0xb3};
-
- /* RC2 variables. */
- PRUint8 rc2_computed_ciphertext[FIPS_RC2_ENCRYPT_LENGTH];
- PRUint8 rc2_computed_plaintext[FIPS_RC2_DECRYPT_LENGTH];
- RC2Context * rc2_context;
- unsigned int rc2_bytes_encrypted;
- unsigned int rc2_bytes_decrypted;
- SECStatus rc2_status;
-
-
- /******************************************************/
- /* RC2-ECB Single-Round Known Answer Encryption Test: */
- /******************************************************/
-
- rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH,
- NULL, NSS_RC2,
- FIPS_RC2_KEY_LENGTH );
-
- if( rc2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc2_status = RC2_Encrypt( rc2_context, rc2_computed_ciphertext,
- &rc2_bytes_encrypted, FIPS_RC2_ENCRYPT_LENGTH,
- rc2_ecb_known_plaintext,
- FIPS_RC2_DECRYPT_LENGTH );
-
- RC2_DestroyContext( rc2_context, PR_TRUE );
-
- if( ( rc2_status != SECSuccess ) ||
- ( rc2_bytes_encrypted != FIPS_RC2_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc2_computed_ciphertext, rc2_ecb_known_ciphertext,
- FIPS_RC2_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* RC2-ECB Single-Round Known Answer Decryption Test: */
- /******************************************************/
-
- rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH,
- NULL, NSS_RC2,
- FIPS_RC2_KEY_LENGTH );
-
- if( rc2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc2_status = RC2_Decrypt( rc2_context, rc2_computed_plaintext,
- &rc2_bytes_decrypted, FIPS_RC2_DECRYPT_LENGTH,
- rc2_ecb_known_ciphertext,
- FIPS_RC2_ENCRYPT_LENGTH );
-
- RC2_DestroyContext( rc2_context, PR_TRUE );
-
- if( ( rc2_status != SECSuccess ) ||
- ( rc2_bytes_decrypted != FIPS_RC2_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc2_computed_plaintext, rc2_ecb_known_plaintext,
- FIPS_RC2_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* RC2-CBC Single-Round Known Answer Encryption Test: */
- /******************************************************/
-
- rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH,
- rc2_cbc_known_initialization_vector,
- NSS_RC2_CBC, FIPS_RC2_KEY_LENGTH );
-
- if( rc2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc2_status = RC2_Encrypt( rc2_context, rc2_computed_ciphertext,
- &rc2_bytes_encrypted, FIPS_RC2_ENCRYPT_LENGTH,
- rc2_cbc_known_plaintext,
- FIPS_RC2_DECRYPT_LENGTH );
-
- RC2_DestroyContext( rc2_context, PR_TRUE );
-
- if( ( rc2_status != SECSuccess ) ||
- ( rc2_bytes_encrypted != FIPS_RC2_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc2_computed_ciphertext, rc2_cbc_known_ciphertext,
- FIPS_RC2_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* RC2-CBC Single-Round Known Answer Decryption Test: */
- /******************************************************/
-
- rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH,
- rc2_cbc_known_initialization_vector,
- NSS_RC2_CBC, FIPS_RC2_KEY_LENGTH );
-
- if( rc2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc2_status = RC2_Decrypt( rc2_context, rc2_computed_plaintext,
- &rc2_bytes_decrypted, FIPS_RC2_DECRYPT_LENGTH,
- rc2_cbc_known_ciphertext,
- FIPS_RC2_ENCRYPT_LENGTH );
-
- RC2_DestroyContext( rc2_context, PR_TRUE );
-
- if( ( rc2_status != SECSuccess ) ||
- ( rc2_bytes_decrypted != FIPS_RC2_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc2_computed_plaintext, rc2_ecb_known_plaintext,
- FIPS_RC2_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-sftk_fips_RC4_PowerUpSelfTest( void )
-{
- /* RC4 Known Key (40-bits). */
- static const PRUint8 rc4_known_key[] = { "RSARC" };
-
- /* RC4 Known Plaintext (64-bits). */
- static const PRUint8 rc4_known_plaintext[] = { "Netscape" };
-
- /* RC4 Known Ciphertext (64-bits). */
- static const PRUint8 rc4_known_ciphertext[] = {
- 0x29,0x33,0xc7,0x9a,0x9d,0x6c,0x09,0xdd};
-
- /* RC4 variables. */
- PRUint8 rc4_computed_ciphertext[FIPS_RC4_ENCRYPT_LENGTH];
- PRUint8 rc4_computed_plaintext[FIPS_RC4_DECRYPT_LENGTH];
- RC4Context * rc4_context;
- unsigned int rc4_bytes_encrypted;
- unsigned int rc4_bytes_decrypted;
- SECStatus rc4_status;
-
-
- /**************************************************/
- /* RC4 Single-Round Known Answer Encryption Test: */
- /**************************************************/
-
- rc4_context = RC4_CreateContext( rc4_known_key, FIPS_RC4_KEY_LENGTH );
-
- if( rc4_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc4_status = RC4_Encrypt( rc4_context, rc4_computed_ciphertext,
- &rc4_bytes_encrypted, FIPS_RC4_ENCRYPT_LENGTH,
- rc4_known_plaintext, FIPS_RC4_DECRYPT_LENGTH );
-
- RC4_DestroyContext( rc4_context, PR_TRUE );
-
- if( ( rc4_status != SECSuccess ) ||
- ( rc4_bytes_encrypted != FIPS_RC4_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc4_computed_ciphertext, rc4_known_ciphertext,
- FIPS_RC4_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /**************************************************/
- /* RC4 Single-Round Known Answer Decryption Test: */
- /**************************************************/
-
- rc4_context = RC4_CreateContext( rc4_known_key, FIPS_RC4_KEY_LENGTH );
-
- if( rc4_context == NULL )
- return( CKR_HOST_MEMORY );
-
- rc4_status = RC4_Decrypt( rc4_context, rc4_computed_plaintext,
- &rc4_bytes_decrypted, FIPS_RC4_DECRYPT_LENGTH,
- rc4_known_ciphertext, FIPS_RC4_ENCRYPT_LENGTH );
-
- RC4_DestroyContext( rc4_context, PR_TRUE );
-
- if( ( rc4_status != SECSuccess ) ||
- ( rc4_bytes_decrypted != FIPS_RC4_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( rc4_computed_plaintext, rc4_known_plaintext,
- FIPS_RC4_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-sftk_fips_DES_PowerUpSelfTest( void )
-{
- /* DES Known Key (56-bits). */
- static const PRUint8 des_known_key[] = { "ANSI DES" };
-
- /* DES-CBC Known Initialization Vector (64-bits). */
- static const PRUint8 des_cbc_known_initialization_vector[] = { "Security" };
-
- /* DES Known Plaintext (64-bits). */
- static const PRUint8 des_ecb_known_plaintext[] = { "Netscape" };
- static const PRUint8 des_cbc_known_plaintext[] = { "Netscape" };
-
- /* DES Known Ciphertext (64-bits). */
- static const PRUint8 des_ecb_known_ciphertext[] = {
- 0x26,0x14,0xe9,0xc3,0x28,0x80,0x50,0xb0};
- static const PRUint8 des_cbc_known_ciphertext[] = {
- 0x5e,0x95,0x94,0x5d,0x76,0xa2,0xd3,0x7d};
-
- /* DES variables. */
- PRUint8 des_computed_ciphertext[FIPS_DES_ENCRYPT_LENGTH];
- PRUint8 des_computed_plaintext[FIPS_DES_DECRYPT_LENGTH];
- DESContext * des_context;
- unsigned int des_bytes_encrypted;
- unsigned int des_bytes_decrypted;
- SECStatus des_status;
-
-
- /******************************************************/
- /* DES-ECB Single-Round Known Answer Encryption Test: */
- /******************************************************/
-
- des_context = DES_CreateContext( des_known_key, NULL, NSS_DES, PR_TRUE );
-
- if( des_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des_status = DES_Encrypt( des_context, des_computed_ciphertext,
- &des_bytes_encrypted, FIPS_DES_ENCRYPT_LENGTH,
- des_ecb_known_plaintext,
- FIPS_DES_DECRYPT_LENGTH );
-
- DES_DestroyContext( des_context, PR_TRUE );
-
- if( ( des_status != SECSuccess ) ||
- ( des_bytes_encrypted != FIPS_DES_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( des_computed_ciphertext, des_ecb_known_ciphertext,
- FIPS_DES_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* DES-ECB Single-Round Known Answer Decryption Test: */
- /******************************************************/
-
- des_context = DES_CreateContext( des_known_key, NULL, NSS_DES, PR_FALSE );
-
- if( des_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des_status = DES_Decrypt( des_context, des_computed_plaintext,
- &des_bytes_decrypted, FIPS_DES_DECRYPT_LENGTH,
- des_ecb_known_ciphertext,
- FIPS_DES_ENCRYPT_LENGTH );
-
- DES_DestroyContext( des_context, PR_TRUE );
-
- if( ( des_status != SECSuccess ) ||
- ( des_bytes_decrypted != FIPS_DES_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( des_computed_plaintext, des_ecb_known_plaintext,
- FIPS_DES_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* DES-CBC Single-Round Known Answer Encryption Test. */
- /******************************************************/
-
- des_context = DES_CreateContext( des_known_key,
- des_cbc_known_initialization_vector,
- NSS_DES_CBC, PR_TRUE );
-
- if( des_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des_status = DES_Encrypt( des_context, des_computed_ciphertext,
- &des_bytes_encrypted, FIPS_DES_ENCRYPT_LENGTH,
- des_cbc_known_plaintext,
- FIPS_DES_DECRYPT_LENGTH );
-
- DES_DestroyContext( des_context, PR_TRUE );
-
- if( ( des_status != SECSuccess ) ||
- ( des_bytes_encrypted != FIPS_DES_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( des_computed_ciphertext, des_cbc_known_ciphertext,
- FIPS_DES_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* DES-CBC Single-Round Known Answer Decryption Test. */
- /******************************************************/
-
- des_context = DES_CreateContext( des_known_key,
- des_cbc_known_initialization_vector,
- NSS_DES_CBC, PR_FALSE );
-
- if( des_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des_status = DES_Decrypt( des_context, des_computed_plaintext,
- &des_bytes_decrypted, FIPS_DES_DECRYPT_LENGTH,
- des_cbc_known_ciphertext,
- FIPS_DES_ENCRYPT_LENGTH );
-
- DES_DestroyContext( des_context, PR_TRUE );
-
- if( ( des_status != SECSuccess ) ||
- ( des_bytes_decrypted != FIPS_DES_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( des_computed_plaintext, des_cbc_known_plaintext,
- FIPS_DES_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-sftk_fips_DES3_PowerUpSelfTest( void )
-{
- /* DES3 Known Key (56-bits). */
- static const PRUint8 des3_known_key[] = { "ANSI Triple-DES Key Data" };
-
- /* DES3-CBC Known Initialization Vector (64-bits). */
- static const PRUint8 des3_cbc_known_initialization_vector[] = { "Security" };
-
- /* DES3 Known Plaintext (64-bits). */
- static const PRUint8 des3_ecb_known_plaintext[] = { "Netscape" };
- static const PRUint8 des3_cbc_known_plaintext[] = { "Netscape" };
-
- /* DES3 Known Ciphertext (64-bits). */
- static const PRUint8 des3_ecb_known_ciphertext[] = {
- 0x55,0x8e,0xad,0x3c,0xee,0x49,0x69,0xbe};
- static const PRUint8 des3_cbc_known_ciphertext[] = {
- 0x43,0xdc,0x6a,0xc1,0xaf,0xa6,0x32,0xf5};
-
- /* DES3 variables. */
- PRUint8 des3_computed_ciphertext[FIPS_DES3_ENCRYPT_LENGTH];
- PRUint8 des3_computed_plaintext[FIPS_DES3_DECRYPT_LENGTH];
- DESContext * des3_context;
- unsigned int des3_bytes_encrypted;
- unsigned int des3_bytes_decrypted;
- SECStatus des3_status;
-
-
- /*******************************************************/
- /* DES3-ECB Single-Round Known Answer Encryption Test. */
- /*******************************************************/
-
- des3_context = DES_CreateContext( des3_known_key, NULL,
- NSS_DES_EDE3, PR_TRUE );
-
- if( des3_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des3_status = DES_Encrypt( des3_context, des3_computed_ciphertext,
- &des3_bytes_encrypted, FIPS_DES3_ENCRYPT_LENGTH,
- des3_ecb_known_plaintext,
- FIPS_DES3_DECRYPT_LENGTH );
-
- DES_DestroyContext( des3_context, PR_TRUE );
-
- if( ( des3_status != SECSuccess ) ||
- ( des3_bytes_encrypted != FIPS_DES3_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( des3_computed_ciphertext, des3_ecb_known_ciphertext,
- FIPS_DES3_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /*******************************************************/
- /* DES3-ECB Single-Round Known Answer Decryption Test. */
- /*******************************************************/
-
- des3_context = DES_CreateContext( des3_known_key, NULL,
- NSS_DES_EDE3, PR_FALSE );
-
- if( des3_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des3_status = DES_Decrypt( des3_context, des3_computed_plaintext,
- &des3_bytes_decrypted, FIPS_DES3_DECRYPT_LENGTH,
- des3_ecb_known_ciphertext,
- FIPS_DES3_ENCRYPT_LENGTH );
-
- DES_DestroyContext( des3_context, PR_TRUE );
-
- if( ( des3_status != SECSuccess ) ||
- ( des3_bytes_decrypted != FIPS_DES3_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( des3_computed_plaintext, des3_ecb_known_plaintext,
- FIPS_DES3_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /*******************************************************/
- /* DES3-CBC Single-Round Known Answer Encryption Test. */
- /*******************************************************/
-
- des3_context = DES_CreateContext( des3_known_key,
- des3_cbc_known_initialization_vector,
- NSS_DES_EDE3_CBC, PR_TRUE );
-
- if( des3_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des3_status = DES_Encrypt( des3_context, des3_computed_ciphertext,
- &des3_bytes_encrypted, FIPS_DES3_ENCRYPT_LENGTH,
- des3_cbc_known_plaintext,
- FIPS_DES3_DECRYPT_LENGTH );
-
- DES_DestroyContext( des3_context, PR_TRUE );
-
- if( ( des3_status != SECSuccess ) ||
- ( des3_bytes_encrypted != FIPS_DES3_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( des3_computed_ciphertext, des3_cbc_known_ciphertext,
- FIPS_DES3_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /*******************************************************/
- /* DES3-CBC Single-Round Known Answer Decryption Test. */
- /*******************************************************/
-
- des3_context = DES_CreateContext( des3_known_key,
- des3_cbc_known_initialization_vector,
- NSS_DES_EDE3_CBC, PR_FALSE );
-
- if( des3_context == NULL )
- return( CKR_HOST_MEMORY );
-
- des3_status = DES_Decrypt( des3_context, des3_computed_plaintext,
- &des3_bytes_decrypted, FIPS_DES3_DECRYPT_LENGTH,
- des3_cbc_known_ciphertext,
- FIPS_DES3_ENCRYPT_LENGTH );
-
- DES_DestroyContext( des3_context, PR_TRUE );
-
- if( ( des3_status != SECSuccess ) ||
- ( des3_bytes_decrypted != FIPS_DES3_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( des3_computed_plaintext, des3_cbc_known_plaintext,
- FIPS_DES3_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-/* AES self-test for 128-bit, 192-bit, or 256-bit key sizes*/
-static CK_RV
-sftk_fips_AES_PowerUpSelfTest( int aes_key_size )
-{
- /* AES Known Key (up to 256-bits). */
- static const PRUint8 aes_known_key[] =
- { "AES-128 RIJNDAELLEADNJIR 821-SEA" };
-
- /* AES-CBC Known Initialization Vector (128-bits). */
- static const PRUint8 aes_cbc_known_initialization_vector[] =
- { "SecurityytiruceS" };
-
- /* AES Known Plaintext (128-bits). (blocksize is 128-bits) */
- static const PRUint8 aes_known_plaintext[] = { "NetscapeepacsteN" };
-
- /* AES Known Ciphertext (128-bit key). */
- static const PRUint8 aes_ecb128_known_ciphertext[] = {
- 0x3c,0xa5,0x96,0xf3,0x34,0x6a,0x96,0xc1,
- 0x03,0x88,0x16,0x7b,0x20,0xbf,0x35,0x47 };
-
- static const PRUint8 aes_cbc128_known_ciphertext[] = {
- 0xcf,0x15,0x1d,0x4f,0x96,0xe4,0x4f,0x63,
- 0x15,0x54,0x14,0x1d,0x4e,0xd8,0xd5,0xea };
-
- /* AES Known Ciphertext (192-bit key). */
- static const PRUint8 aes_ecb192_known_ciphertext[] = {
- 0xa0,0x18,0x62,0xed,0x88,0x19,0xcb,0x62,
- 0x88,0x1d,0x4d,0xfe,0x84,0x02,0x89,0x0e };
-
- static const PRUint8 aes_cbc192_known_ciphertext[] = {
- 0x83,0xf7,0xa4,0x76,0xd1,0x6f,0x07,0xbe,
- 0x07,0xbc,0x43,0x2f,0x6d,0xad,0x29,0xe1 };
-
- /* AES Known Ciphertext (256-bit key). */
- static const PRUint8 aes_ecb256_known_ciphertext[] = {
- 0xdb,0xa6,0x52,0x01,0x8a,0x70,0xae,0x66,
- 0x3a,0x99,0xd8,0x95,0x7f,0xfb,0x01,0x67 };
-
- static const PRUint8 aes_cbc256_known_ciphertext[] = {
- 0x37,0xea,0x07,0x06,0x31,0x1c,0x59,0x27,
- 0xc5,0xc5,0x68,0x71,0x6e,0x34,0x40,0x16 };
-
- const PRUint8 *aes_ecb_known_ciphertext =
- ( aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_ecb128_known_ciphertext :
- ( aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_ecb192_known_ciphertext :
- aes_ecb256_known_ciphertext;
-
- const PRUint8 *aes_cbc_known_ciphertext =
- ( aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_cbc128_known_ciphertext :
- ( aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_cbc192_known_ciphertext :
- aes_cbc256_known_ciphertext;
-
- /* AES variables. */
- PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH];
- PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH];
- AESContext * aes_context;
- unsigned int aes_bytes_encrypted;
- unsigned int aes_bytes_decrypted;
- SECStatus aes_status;
-
- /*check if aes_key_size is 128, 192, or 256 bits */
- if ((aes_key_size != FIPS_AES_128_KEY_SIZE) &&
- (aes_key_size != FIPS_AES_192_KEY_SIZE) &&
- (aes_key_size != FIPS_AES_256_KEY_SIZE))
- return( CKR_DEVICE_ERROR );
-
- /******************************************************/
- /* AES-ECB Single-Round Known Answer Encryption Test: */
- /******************************************************/
-
- aes_context = AES_CreateContext( aes_known_key, NULL, NSS_AES, PR_TRUE,
- aes_key_size, FIPS_AES_BLOCK_SIZE );
-
- if( aes_context == NULL )
- return( CKR_HOST_MEMORY );
-
- aes_status = AES_Encrypt( aes_context, aes_computed_ciphertext,
- &aes_bytes_encrypted, FIPS_AES_ENCRYPT_LENGTH,
- aes_known_plaintext,
- FIPS_AES_DECRYPT_LENGTH );
-
- AES_DestroyContext( aes_context, PR_TRUE );
-
- if( ( aes_status != SECSuccess ) ||
- ( aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( aes_computed_ciphertext, aes_ecb_known_ciphertext,
- FIPS_AES_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* AES-ECB Single-Round Known Answer Decryption Test: */
- /******************************************************/
-
- aes_context = AES_CreateContext( aes_known_key, NULL, NSS_AES, PR_FALSE,
- aes_key_size, FIPS_AES_BLOCK_SIZE );
-
- if( aes_context == NULL )
- return( CKR_HOST_MEMORY );
-
- aes_status = AES_Decrypt( aes_context, aes_computed_plaintext,
- &aes_bytes_decrypted, FIPS_AES_DECRYPT_LENGTH,
- aes_ecb_known_ciphertext,
- FIPS_AES_ENCRYPT_LENGTH );
-
- AES_DestroyContext( aes_context, PR_TRUE );
-
- if( ( aes_status != SECSuccess ) ||
- ( aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( aes_computed_plaintext, aes_known_plaintext,
- FIPS_AES_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* AES-CBC Single-Round Known Answer Encryption Test. */
- /******************************************************/
-
- aes_context = AES_CreateContext( aes_known_key,
- aes_cbc_known_initialization_vector,
- NSS_AES_CBC, PR_TRUE, aes_key_size,
- FIPS_AES_BLOCK_SIZE );
-
- if( aes_context == NULL )
- return( CKR_HOST_MEMORY );
-
- aes_status = AES_Encrypt( aes_context, aes_computed_ciphertext,
- &aes_bytes_encrypted, FIPS_AES_ENCRYPT_LENGTH,
- aes_known_plaintext,
- FIPS_AES_DECRYPT_LENGTH );
-
- AES_DestroyContext( aes_context, PR_TRUE );
-
- if( ( aes_status != SECSuccess ) ||
- ( aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH ) ||
- ( PORT_Memcmp( aes_computed_ciphertext, aes_cbc_known_ciphertext,
- FIPS_AES_ENCRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
-
- /******************************************************/
- /* AES-CBC Single-Round Known Answer Decryption Test. */
- /******************************************************/
-
- aes_context = AES_CreateContext( aes_known_key,
- aes_cbc_known_initialization_vector,
- NSS_AES_CBC, PR_FALSE, aes_key_size,
- FIPS_AES_BLOCK_SIZE );
-
- if( aes_context == NULL )
- return( CKR_HOST_MEMORY );
-
- aes_status = AES_Decrypt( aes_context, aes_computed_plaintext,
- &aes_bytes_decrypted, FIPS_AES_DECRYPT_LENGTH,
- aes_cbc_known_ciphertext,
- FIPS_AES_ENCRYPT_LENGTH );
-
- AES_DestroyContext( aes_context, PR_TRUE );
-
- if( ( aes_status != SECSuccess ) ||
- ( aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH ) ||
- ( PORT_Memcmp( aes_computed_plaintext, aes_known_plaintext,
- FIPS_AES_DECRYPT_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-/* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */
-static const PRUint8 known_hash_message[] = {
- "The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
-
-
-static CK_RV
-sftk_fips_MD2_PowerUpSelfTest( void )
-{
- /* MD2 Known Digest Message (128-bits). */
- static const PRUint8 md2_known_digest[] = {
- 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
- 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
-
- /* MD2 variables. */
- MD2Context * md2_context;
- unsigned int md2_bytes_hashed;
- PRUint8 md2_computed_digest[MD2_LENGTH];
-
-
- /***********************************************/
- /* MD2 Single-Round Known Answer Hashing Test. */
- /***********************************************/
-
- md2_context = MD2_NewContext();
-
- if( md2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- MD2_Begin( md2_context );
-
- MD2_Update( md2_context, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
-
- MD2_DestroyContext( md2_context , PR_TRUE );
-
- if( ( md2_bytes_hashed != MD2_LENGTH ) ||
- ( PORT_Memcmp( md2_computed_digest, md2_known_digest,
- MD2_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-sftk_fips_MD5_PowerUpSelfTest( void )
-{
- /* MD5 Known Digest Message (128-bits). */
- static const PRUint8 md5_known_digest[] = {
- 0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28,
- 0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d};
-
- /* MD5 variables. */
- PRUint8 md5_computed_digest[MD5_LENGTH];
- SECStatus md5_status;
-
-
- /***********************************************/
- /* MD5 Single-Round Known Answer Hashing Test. */
- /***********************************************/
-
- md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( md5_status != SECSuccess ) ||
- ( PORT_Memcmp( md5_computed_digest, md5_known_digest,
- MD5_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-/****************************************************/
-/* Single Round HMAC SHA-X test */
-/****************************************************/
-static SECStatus
-sftk_fips_HMAC(unsigned char *hmac_computed,
- const PRUint8 *secret_key,
- unsigned int secret_key_length,
- const PRUint8 *message,
- unsigned int message_length,
- HASH_HashType hashAlg )
-{
- SECStatus hmac_status = SECFailure;
- HMACContext *cx = NULL;
- SECHashObject *hashObj = NULL;
- unsigned int bytes_hashed = 0;
-
- hashObj = (SECHashObject *) HASH_GetRawHashObject(hashAlg);
-
- if (!hashObj)
- return( SECFailure );
-
- cx = HMAC_Create(hashObj, secret_key,
- secret_key_length,
- PR_TRUE); /* PR_TRUE for in FIPS mode */
-
- if (cx == NULL)
- return( SECFailure );
-
- HMAC_Begin(cx);
- HMAC_Update(cx, message, message_length);
- hmac_status = HMAC_Finish(cx, hmac_computed, &bytes_hashed,
- hashObj->length);
-
- HMAC_Destroy(cx, PR_TRUE);
-
- return( hmac_status );
-}
-
-static CK_RV
-sftk_fips_HMAC_PowerUpSelfTest( void )
-{
- static const PRUint8 HMAC_known_secret_key[] = {
- "Firefox and ThunderBird are awesome!"};
-
- static const PRUint8 HMAC_known_secret_key_length
- = sizeof HMAC_known_secret_key;
-
- /* known SHA1 hmac (20 bytes) */
- static const PRUint8 known_SHA1_hmac[] = {
- 0xd5, 0x85, 0xf6, 0x5b, 0x39, 0xfa, 0xb9, 0x05,
- 0x3b, 0x57, 0x1d, 0x61, 0xe7, 0xb8, 0x84, 0x1e,
- 0x5d, 0x0e, 0x1e, 0x11};
-
- /* known SHA224 hmac (28 bytes) */
- static const PRUint8 known_SHA224_hmac[] = {
- 0x1c, 0xc3, 0x06, 0x8e, 0xce, 0x37, 0x68, 0xfb,
- 0x1a, 0x82, 0x4a, 0xbe, 0x2b, 0x00, 0x51, 0xf8,
- 0x9d, 0xb6, 0xe0, 0x90, 0x0d, 0x00, 0xc9, 0x64,
- 0x9a, 0xb8, 0x98, 0x4e};
-
- /* known SHA256 hmac (32 bytes) */
- static const PRUint8 known_SHA256_hmac[] = {
- 0x05, 0x75, 0x9a, 0x9e, 0x70, 0x5e, 0xe7, 0x44,
- 0xe2, 0x46, 0x4b, 0x92, 0x22, 0x14, 0x22, 0xe0,
- 0x1b, 0x92, 0x8a, 0x0c, 0xfe, 0xf5, 0x49, 0xe9,
- 0xa7, 0x1b, 0x56, 0x7d, 0x1d, 0x29, 0x40, 0x48};
-
- /* known SHA384 hmac (48 bytes) */
- static const PRUint8 known_SHA384_hmac[] = {
- 0xcd, 0x56, 0x14, 0xec, 0x05, 0x53, 0x06, 0x2b,
- 0x7e, 0x9c, 0x8a, 0x18, 0x5e, 0xea, 0xf3, 0x91,
- 0x33, 0xfb, 0x64, 0xf6, 0xe3, 0x9f, 0x89, 0x0b,
- 0xaf, 0xbe, 0x83, 0x4d, 0x3f, 0x3c, 0x43, 0x4d,
- 0x4a, 0x0c, 0x56, 0x98, 0xf8, 0xca, 0xb4, 0xaa,
- 0x9a, 0xf4, 0x0a, 0xaf, 0x4f, 0x69, 0xca, 0x87};
-
- /* known SHA512 hmac (64 bytes) */
- static const PRUint8 known_SHA512_hmac[] = {
- 0xf6, 0x0e, 0x97, 0x12, 0x00, 0x67, 0x6e, 0xb9,
- 0x0c, 0xb2, 0x63, 0xf0, 0x60, 0xac, 0x75, 0x62,
- 0x70, 0x95, 0x2a, 0x52, 0x22, 0xee, 0xdd, 0xd2,
- 0x71, 0xb1, 0xe8, 0x26, 0x33, 0xd3, 0x13, 0x27,
- 0xcb, 0xff, 0x44, 0xef, 0x87, 0x97, 0x16, 0xfb,
- 0xd3, 0x0b, 0x48, 0xbe, 0x12, 0x4e, 0xda, 0xb1,
- 0x89, 0x90, 0xfb, 0x06, 0x0c, 0xbe, 0xe5, 0xc4,
- 0xff, 0x24, 0x37, 0x3d, 0xc7, 0xe4, 0xe4, 0x37};
-
- SECStatus hmac_status;
- PRUint8 hmac_computed[HASH_LENGTH_MAX];
-
- /***************************************************/
- /* HMAC SHA-1 Single-Round Known Answer HMAC Test. */
- /***************************************************/
-
- hmac_status = sftk_fips_HMAC(hmac_computed,
- HMAC_known_secret_key,
- HMAC_known_secret_key_length,
- known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH,
- HASH_AlgSHA1);
-
- if( ( hmac_status != SECSuccess ) ||
- ( PORT_Memcmp( hmac_computed, known_SHA1_hmac,
- SHA1_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* HMAC SHA-224 Single-Round Known Answer Test. */
- /***************************************************/
-
- hmac_status = sftk_fips_HMAC(hmac_computed,
- HMAC_known_secret_key,
- HMAC_known_secret_key_length,
- known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH,
- HASH_AlgSHA224);
-
- if( ( hmac_status != SECSuccess ) ||
- ( PORT_Memcmp( hmac_computed, known_SHA224_hmac,
- SHA224_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* HMAC SHA-256 Single-Round Known Answer Test. */
- /***************************************************/
-
- hmac_status = sftk_fips_HMAC(hmac_computed,
- HMAC_known_secret_key,
- HMAC_known_secret_key_length,
- known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH,
- HASH_AlgSHA256);
-
- if( ( hmac_status != SECSuccess ) ||
- ( PORT_Memcmp( hmac_computed, known_SHA256_hmac,
- SHA256_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* HMAC SHA-384 Single-Round Known Answer Test. */
- /***************************************************/
-
- hmac_status = sftk_fips_HMAC(hmac_computed,
- HMAC_known_secret_key,
- HMAC_known_secret_key_length,
- known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH,
- HASH_AlgSHA384);
-
- if( ( hmac_status != SECSuccess ) ||
- ( PORT_Memcmp( hmac_computed, known_SHA384_hmac,
- SHA384_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* HMAC SHA-512 Single-Round Known Answer Test. */
- /***************************************************/
-
- hmac_status = sftk_fips_HMAC(hmac_computed,
- HMAC_known_secret_key,
- HMAC_known_secret_key_length,
- known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH,
- HASH_AlgSHA512);
-
- if( ( hmac_status != SECSuccess ) ||
- ( PORT_Memcmp( hmac_computed, known_SHA512_hmac,
- SHA512_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-static CK_RV
-sftk_fips_SHA_PowerUpSelfTest( void )
-{
- /* SHA-1 Known Digest Message (160-bits). */
- static const PRUint8 sha1_known_digest[] = {
- 0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b,
- 0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0,
- 0xe0,0x68,0x47,0x7a};
-
- /* SHA-224 Known Digest Message (224-bits). */
- static const PRUint8 sha224_known_digest[] = {
- 0x89,0x5e,0x7f,0xfd,0x0e,0xd8,0x35,0x6f,
- 0x64,0x6d,0xf2,0xde,0x5e,0xed,0xa6,0x7f,
- 0x29,0xd1,0x12,0x73,0x42,0x84,0x95,0x4f,
- 0x8e,0x08,0xe5,0xcb};
-
- /* SHA-256 Known Digest Message (256-bits). */
- static const PRUint8 sha256_known_digest[] = {
- 0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61,
- 0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d,
- 0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9,
- 0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79};
-
- /* SHA-384 Known Digest Message (384-bits). */
- static const PRUint8 sha384_known_digest[] = {
- 0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3,
- 0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe,
- 0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8,
- 0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b,
- 0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3,
- 0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72};
-
- /* SHA-512 Known Digest Message (512-bits). */
- static const PRUint8 sha512_known_digest[] = {
- 0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf,
- 0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb,
- 0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99,
- 0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28,
- 0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12,
- 0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f,
- 0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a,
- 0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07};
-
- /* SHA-X variables. */
- PRUint8 sha_computed_digest[HASH_LENGTH_MAX];
- SECStatus sha_status;
-
- /*************************************************/
- /* SHA-1 Single-Round Known Answer Hashing Test. */
- /*************************************************/
-
- sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha1_known_digest,
- SHA1_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-224 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA224_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha224_known_digest,
- SHA224_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-256 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha256_known_digest,
- SHA256_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-384 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha384_known_digest,
- SHA384_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-512 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha512_known_digest,
- SHA512_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-/*
-* Single round RSA Signature Known Answer Test
-*/
-static SECStatus
-sftk_fips_RSA_PowerUpSigSelfTest (HASH_HashType shaAlg,
- NSSLOWKEYPublicKey *rsa_public_key,
- NSSLOWKEYPrivateKey *rsa_private_key,
- const unsigned char *rsa_known_msg,
- const unsigned int rsa_kmsg_length,
- const unsigned char *rsa_known_signature)
-{
- SECOidTag shaOid; /* SHA OID */
- unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
- unsigned int shaLength = 0; /* length of SHA */
- unsigned int rsa_bytes_signed;
- unsigned char rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH];
- SECStatus rv;
-
- if (shaAlg == HASH_AlgSHA1) {
- if (SHA1_HashBuf(sha, rsa_known_msg, rsa_kmsg_length)
- != SECSuccess) {
- goto loser;
- }
- shaLength = SHA1_LENGTH;
- shaOid = SEC_OID_SHA1;
- } else if (shaAlg == HASH_AlgSHA256) {
- if (SHA256_HashBuf(sha, rsa_known_msg, rsa_kmsg_length)
- != SECSuccess) {
- goto loser;
- }
- shaLength = SHA256_LENGTH;
- shaOid = SEC_OID_SHA256;
- } else if (shaAlg == HASH_AlgSHA384) {
- if (SHA384_HashBuf(sha, rsa_known_msg, rsa_kmsg_length)
- != SECSuccess) {
- goto loser;
- }
- shaLength = SHA384_LENGTH;
- shaOid = SEC_OID_SHA384;
- } else if (shaAlg == HASH_AlgSHA512) {
- if (SHA512_HashBuf(sha, rsa_known_msg, rsa_kmsg_length)
- != SECSuccess) {
- goto loser;
- }
- shaLength = SHA512_LENGTH;
- shaOid = SEC_OID_SHA512;
- } else {
- goto loser;
- }
-
- /*************************************************/
- /* RSA Single-Round Known Answer Signature Test. */
- /*************************************************/
-
- /* Perform RSA signature with the RSA private key. */
- rv = RSA_HashSign( shaOid,
- rsa_private_key,
- rsa_computed_signature,
- &rsa_bytes_signed,
- FIPS_RSA_SIGNATURE_LENGTH,
- sha,
- shaLength);
-
- if( ( rv != SECSuccess ) ||
- ( rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH ) ||
- ( PORT_Memcmp( rsa_computed_signature, rsa_known_signature,
- FIPS_RSA_SIGNATURE_LENGTH ) != 0 ) ) {
- goto loser;
- }
-
- /****************************************************/
- /* RSA Single-Round Known Answer Verification Test. */
- /****************************************************/
-
- /* Perform RSA verification with the RSA public key. */
- rv = RSA_HashCheckSign( shaOid,
- rsa_public_key,
- rsa_computed_signature,
- rsa_bytes_signed,
- sha,
- shaLength);
-
- if( rv != SECSuccess ) {
- goto loser;
- }
- return( SECSuccess );
-
-loser:
-
- return( SECFailure );
-
-}
-
-static CK_RV
-sftk_fips_RSA_PowerUpSelfTest( void )
-{
- /* RSA Known Modulus used in both Public/Private Key Values (2048-bits). */
- static const PRUint8 rsa_modulus[FIPS_RSA_MODULUS_LENGTH] = {
- 0xb8, 0x15, 0x00, 0x33, 0xda, 0x0c, 0x9d, 0xa5,
- 0x14, 0x8c, 0xde, 0x1f, 0x23, 0x07, 0x54, 0xe2,
- 0xc6, 0xb9, 0x51, 0x04, 0xc9, 0x65, 0x24, 0x6e,
- 0x0a, 0x46, 0x34, 0x5c, 0x37, 0x86, 0x6b, 0x88,
- 0x24, 0x27, 0xac, 0xa5, 0x02, 0x79, 0xfb, 0xed,
- 0x75, 0xc5, 0x3f, 0x6e, 0xdf, 0x05, 0x5f, 0x0f,
- 0x20, 0x70, 0xa0, 0x5b, 0x85, 0xdb, 0xac, 0xb9,
- 0x5f, 0x02, 0xc2, 0x64, 0x1e, 0x84, 0x5b, 0x3e,
- 0xad, 0xbf, 0xf6, 0x2e, 0x51, 0xd6, 0xad, 0xf7,
- 0xa7, 0x86, 0x75, 0x86, 0xec, 0xa7, 0xe1, 0xf7,
- 0x08, 0xbf, 0xdc, 0x56, 0xb1, 0x3b, 0xca, 0xd8,
- 0xfc, 0x51, 0xdf, 0x9a, 0x2a, 0x37, 0x06, 0xf2,
- 0xd1, 0x6b, 0x9a, 0x5e, 0x2a, 0xe5, 0x20, 0x57,
- 0x35, 0x9f, 0x1f, 0x98, 0xcf, 0x40, 0xc7, 0xd6,
- 0x98, 0xdb, 0xde, 0xf5, 0x64, 0x53, 0xf7, 0x9d,
- 0x45, 0xf3, 0xd6, 0x78, 0xb9, 0xe3, 0xa3, 0x20,
- 0xcd, 0x79, 0x43, 0x35, 0xef, 0xd7, 0xfb, 0xb9,
- 0x80, 0x88, 0x27, 0x2f, 0x63, 0xa8, 0x67, 0x3d,
- 0x4a, 0xfa, 0x06, 0xc6, 0xd2, 0x86, 0x0b, 0xa7,
- 0x28, 0xfd, 0xe0, 0x1e, 0x93, 0x4b, 0x17, 0x2e,
- 0xb0, 0x11, 0x6f, 0xc6, 0x2b, 0x98, 0x0f, 0x15,
- 0xe3, 0x87, 0x16, 0x7a, 0x7c, 0x67, 0x3e, 0x12,
- 0x2b, 0xf8, 0xbe, 0x48, 0xc1, 0x97, 0x47, 0xf4,
- 0x1f, 0x81, 0x80, 0x12, 0x28, 0xe4, 0x7b, 0x1e,
- 0xb7, 0x00, 0xa4, 0xde, 0xaa, 0xfb, 0x0f, 0x77,
- 0x84, 0xa3, 0xd6, 0xb2, 0x03, 0x48, 0xdd, 0x53,
- 0x8b, 0x46, 0x41, 0x28, 0x52, 0xc4, 0x53, 0xf0,
- 0x1c, 0x95, 0xd9, 0x36, 0xe0, 0x0f, 0x26, 0x46,
- 0x9c, 0x61, 0x0e, 0x80, 0xca, 0x86, 0xaf, 0x39,
- 0x95, 0xe5, 0x60, 0x43, 0x61, 0x3e, 0x2b, 0xb4,
- 0xe8, 0xbd, 0x8d, 0x77, 0x62, 0xf5, 0x32, 0x43,
- 0x2f, 0x4b, 0x65, 0x82, 0x14, 0xdd, 0x29, 0x5b};
-
- /* RSA Known Public Key Values (24-bits). */
- static const PRUint8 rsa_public_exponent[FIPS_RSA_PUBLIC_EXPONENT_LENGTH]
- = { 0x01, 0x00, 0x01 };
- /* RSA Known Private Key Values (version is 8-bits), */
- /* (private exponent is 2048-bits), */
- /* (private prime0 is 1024-bits), */
- /* (private prime1 is 1024-bits), */
- /* (private prime exponent0 is 1024-bits), */
- /* (private prime exponent1 is 1024-bits), */
- /* and (private coefficient is 1024-bits). */
- static const PRUint8 rsa_version[] = { 0x00 };
-
- static const PRUint8 rsa_private_exponent[FIPS_RSA_PRIVATE_EXPONENT_LENGTH]
- = {0x29, 0x08, 0x05, 0x53, 0x89, 0x76, 0xe6, 0x6c,
- 0xb5, 0x77, 0xf0, 0xca, 0xdf, 0xf3, 0xf2, 0x67,
- 0xda, 0x03, 0xd4, 0x9b, 0x4c, 0x88, 0xce, 0xe5,
- 0xf8, 0x44, 0x4d, 0xc7, 0x80, 0x58, 0xe5, 0xff,
- 0x22, 0x8f, 0xf5, 0x5b, 0x92, 0x81, 0xbe, 0x35,
- 0xdf, 0xda, 0x67, 0x99, 0x3e, 0xfc, 0xe3, 0x83,
- 0x6b, 0xa7, 0xaf, 0x16, 0xb7, 0x6f, 0x8f, 0xc0,
- 0x81, 0xfd, 0x0b, 0x77, 0x65, 0x95, 0xfb, 0x00,
- 0xad, 0x99, 0xec, 0x35, 0xc6, 0xe8, 0x23, 0x3e,
- 0xe0, 0x88, 0x88, 0x09, 0xdb, 0x16, 0x50, 0xb7,
- 0xcf, 0xab, 0x74, 0x61, 0x9e, 0x7f, 0xc5, 0x67,
- 0x38, 0x56, 0xc7, 0x90, 0x85, 0x78, 0x5e, 0x84,
- 0x21, 0x49, 0xea, 0xce, 0xb2, 0xa0, 0xff, 0xe4,
- 0x70, 0x7f, 0x57, 0x7b, 0xa8, 0x36, 0xb8, 0x54,
- 0x8d, 0x1d, 0xf5, 0x44, 0x9d, 0x68, 0x59, 0xf9,
- 0x24, 0x6e, 0x85, 0x8f, 0xc3, 0x5f, 0x8a, 0x2c,
- 0x94, 0xb7, 0xbc, 0x0e, 0xa5, 0xef, 0x93, 0x06,
- 0x38, 0xcd, 0x07, 0x0c, 0xae, 0xb8, 0x44, 0x1a,
- 0xd8, 0xe7, 0xf5, 0x9a, 0x1e, 0x9c, 0x18, 0xc7,
- 0x6a, 0xc2, 0x7f, 0x28, 0x01, 0x4f, 0xb4, 0xb8,
- 0x90, 0x97, 0x5a, 0x43, 0x38, 0xad, 0xe8, 0x95,
- 0x68, 0x83, 0x1a, 0x1b, 0x10, 0x07, 0xe6, 0x02,
- 0x52, 0x1f, 0xbf, 0x76, 0x6b, 0x46, 0xd6, 0xfb,
- 0xc3, 0xbe, 0xb5, 0xac, 0x52, 0x53, 0x01, 0x1c,
- 0xf3, 0xc5, 0xeb, 0x64, 0xf2, 0x1e, 0xc4, 0x38,
- 0xe9, 0xaa, 0xd9, 0xc3, 0x72, 0x51, 0xa5, 0x44,
- 0x58, 0x69, 0x0b, 0x1b, 0x98, 0x7f, 0xf2, 0x23,
- 0xff, 0xeb, 0xf0, 0x75, 0x24, 0xcf, 0xc5, 0x1e,
- 0xb8, 0x6a, 0xc5, 0x2f, 0x4f, 0x23, 0x50, 0x7d,
- 0x15, 0x9d, 0x19, 0x7a, 0x0b, 0x82, 0xe0, 0x21,
- 0x5b, 0x5f, 0x9d, 0x50, 0x2b, 0x83, 0xe4, 0x48,
- 0xcc, 0x39, 0xe5, 0xfb, 0x13, 0x7b, 0x6f, 0x81 };
-
- static const PRUint8 rsa_prime0[FIPS_RSA_PRIME0_LENGTH] = {
- 0xe4, 0xbf, 0x21, 0x62, 0x9b, 0xa9, 0x77, 0x40,
- 0x8d, 0x2a, 0xce, 0xa1, 0x67, 0x5a, 0x4c, 0x96,
- 0x45, 0x98, 0x67, 0xbd, 0x75, 0x22, 0x33, 0x6f,
- 0xe6, 0xcb, 0x77, 0xde, 0x9e, 0x97, 0x7d, 0x96,
- 0x8c, 0x5e, 0x5d, 0x34, 0xfb, 0x27, 0xfc, 0x6d,
- 0x74, 0xdb, 0x9d, 0x2e, 0x6d, 0xf6, 0xea, 0xfc,
- 0xce, 0x9e, 0xda, 0xa7, 0x25, 0xa2, 0xf4, 0x58,
- 0x6d, 0x0a, 0x3f, 0x01, 0xc2, 0xb4, 0xab, 0x38,
- 0xc1, 0x14, 0x85, 0xb6, 0xfa, 0x94, 0xc3, 0x85,
- 0xf9, 0x3c, 0x2e, 0x96, 0x56, 0x01, 0xe7, 0xd6,
- 0x14, 0x71, 0x4f, 0xfb, 0x4c, 0x85, 0x52, 0xc4,
- 0x61, 0x1e, 0xa5, 0x1e, 0x96, 0x13, 0x0d, 0x8f,
- 0x66, 0xae, 0xa0, 0xcd, 0x7d, 0x25, 0x66, 0x19,
- 0x15, 0xc2, 0xcf, 0xc3, 0x12, 0x3c, 0xe8, 0xa4,
- 0x52, 0x4c, 0xcb, 0x28, 0x3c, 0xc4, 0xbf, 0x95,
- 0x33, 0xe3, 0x81, 0xea, 0x0c, 0x6c, 0xa2, 0x05};
- static const PRUint8 rsa_prime1[FIPS_RSA_PRIME1_LENGTH] = {
- 0xce, 0x03, 0x94, 0xf4, 0xa9, 0x2c, 0x1e, 0x06,
- 0xe7, 0x40, 0x30, 0x01, 0xf7, 0xbb, 0x68, 0x8c,
- 0x27, 0xd2, 0x15, 0xe3, 0x28, 0x49, 0x5b, 0xa8,
- 0xc1, 0x9a, 0x42, 0x7e, 0x31, 0xf9, 0x08, 0x34,
- 0x81, 0xa2, 0x0f, 0x04, 0x61, 0x34, 0xe3, 0x36,
- 0x92, 0xb1, 0x09, 0x2b, 0xe9, 0xef, 0x84, 0x88,
- 0xbe, 0x9c, 0x98, 0x60, 0xa6, 0x60, 0x84, 0xe9,
- 0x75, 0x6f, 0xcc, 0x81, 0xd1, 0x96, 0xef, 0xdd,
- 0x2e, 0xca, 0xc4, 0xf5, 0x42, 0xfb, 0x13, 0x2b,
- 0x57, 0xbf, 0x14, 0x5e, 0xc2, 0x7f, 0x77, 0x35,
- 0x29, 0xc4, 0xe5, 0xe0, 0xf9, 0x6d, 0x15, 0x4a,
- 0x42, 0x56, 0x1c, 0x3e, 0x0c, 0xc5, 0xce, 0x70,
- 0x08, 0x63, 0x1e, 0x73, 0xdb, 0x7e, 0x74, 0x05,
- 0x32, 0x01, 0xc6, 0x36, 0x32, 0x75, 0x6b, 0xed,
- 0x9d, 0xfe, 0x7c, 0x7e, 0xa9, 0x57, 0xb4, 0xe9,
- 0x22, 0xe4, 0xe7, 0xfe, 0x36, 0x07, 0x9b, 0xdf};
- static const PRUint8 rsa_exponent0[FIPS_RSA_EXPONENT0_LENGTH] = {
- 0x04, 0x5a, 0x3a, 0xa9, 0x64, 0xaa, 0xd9, 0xd1,
- 0x09, 0x9e, 0x99, 0xe5, 0xea, 0x50, 0x86, 0x8a,
- 0x89, 0x72, 0x77, 0xee, 0xdb, 0xee, 0xb5, 0xa9,
- 0xd8, 0x6b, 0x60, 0xb1, 0x84, 0xb4, 0xff, 0x37,
- 0xc1, 0x1d, 0xfe, 0x8a, 0x06, 0x89, 0x61, 0x3d,
- 0x37, 0xef, 0x01, 0xd3, 0xa3, 0x56, 0x02, 0x6c,
- 0xa3, 0x05, 0xd4, 0xc5, 0x3f, 0x6b, 0x15, 0x59,
- 0x25, 0x61, 0xff, 0x86, 0xea, 0x0c, 0x84, 0x01,
- 0x85, 0x72, 0xfd, 0x84, 0x58, 0xca, 0x41, 0xda,
- 0x27, 0xbe, 0xe4, 0x68, 0x09, 0xe4, 0xe9, 0x63,
- 0x62, 0x6a, 0x31, 0x8a, 0x67, 0x8f, 0x55, 0xde,
- 0xd4, 0xb6, 0x3f, 0x90, 0x10, 0x6c, 0xf6, 0x62,
- 0x17, 0x23, 0x15, 0x7e, 0x33, 0x76, 0x65, 0xb5,
- 0xee, 0x7b, 0x11, 0x76, 0xf5, 0xbe, 0xe0, 0xf2,
- 0x57, 0x7a, 0x8c, 0x97, 0x0c, 0x68, 0xf5, 0xf8,
- 0x41, 0xcf, 0x7f, 0x66, 0x53, 0xac, 0x31, 0x7d};
- static const PRUint8 rsa_exponent1[FIPS_RSA_EXPONENT1_LENGTH] = {
- 0x93, 0x54, 0x14, 0x6e, 0x73, 0x9d, 0x4d, 0x4b,
- 0xfa, 0x8c, 0xf8, 0xc8, 0x2f, 0x76, 0x22, 0xea,
- 0x38, 0x80, 0x11, 0x8f, 0x05, 0xfc, 0x90, 0x44,
- 0x3b, 0x50, 0x2a, 0x45, 0x3d, 0x4f, 0xaf, 0x02,
- 0x7d, 0xc2, 0x7b, 0xa2, 0xd2, 0x31, 0x94, 0x5c,
- 0x2e, 0xc3, 0xd4, 0x9f, 0x47, 0x09, 0x37, 0x6a,
- 0xe3, 0x85, 0xf1, 0xa3, 0x0c, 0xd8, 0xf1, 0xb4,
- 0x53, 0x7b, 0xc4, 0x71, 0x02, 0x86, 0x42, 0xbb,
- 0x96, 0xff, 0x03, 0xa3, 0xb2, 0x67, 0x03, 0xea,
- 0x77, 0x31, 0xfb, 0x4b, 0x59, 0x24, 0xf7, 0x07,
- 0x59, 0xfb, 0xa9, 0xba, 0x1e, 0x26, 0x58, 0x97,
- 0x66, 0xa1, 0x56, 0x49, 0x39, 0xb1, 0x2c, 0x55,
- 0x0a, 0x6a, 0x78, 0x18, 0xba, 0xdb, 0xcf, 0xf4,
- 0xf7, 0x32, 0x35, 0xa2, 0x04, 0xab, 0xdc, 0xa7,
- 0x6d, 0xd9, 0xd5, 0x06, 0x6f, 0xec, 0x7d, 0x40,
- 0x4c, 0xe8, 0x0e, 0xd0, 0xc9, 0xaa, 0xdf, 0x59};
- static const PRUint8 rsa_coefficient[FIPS_RSA_COEFFICIENT_LENGTH] = {
- 0x17, 0xd7, 0xf5, 0x0a, 0xf0, 0x68, 0x97, 0x96,
- 0xc4, 0x29, 0x18, 0x77, 0x9a, 0x1f, 0xe3, 0xf3,
- 0x12, 0x13, 0x0f, 0x7e, 0x7b, 0xb9, 0xc1, 0x91,
- 0xf9, 0xc7, 0x08, 0x56, 0x5c, 0xa4, 0xbc, 0x83,
- 0x71, 0xf9, 0x78, 0xd9, 0x2b, 0xec, 0xfe, 0x6b,
- 0xdc, 0x2f, 0x63, 0xc9, 0xcd, 0x50, 0x14, 0x5b,
- 0xd3, 0x6e, 0x85, 0x4d, 0x0c, 0xa2, 0x0b, 0xa0,
- 0x09, 0xb6, 0xca, 0x34, 0x9c, 0xc2, 0xc1, 0x4a,
- 0xb0, 0xbc, 0x45, 0x93, 0xa5, 0x7e, 0x99, 0xb5,
- 0xbd, 0xe4, 0x69, 0x29, 0x08, 0x28, 0xd2, 0xcd,
- 0xab, 0x24, 0x78, 0x48, 0x41, 0x26, 0x0b, 0x37,
- 0xa3, 0x43, 0xd1, 0x95, 0x1a, 0xd6, 0xee, 0x22,
- 0x1c, 0x00, 0x0b, 0xc2, 0xb7, 0xa4, 0xa3, 0x21,
- 0xa9, 0xcd, 0xe4, 0x69, 0xd3, 0x45, 0x02, 0xb1,
- 0xb7, 0x3a, 0xbf, 0x51, 0x35, 0x1b, 0x78, 0xc2,
- 0xcf, 0x0c, 0x0d, 0x60, 0x09, 0xa9, 0x44, 0x02};
-
- /* RSA Known Plaintext Message (1024-bits). */
- static const PRUint8 rsa_known_plaintext_msg[FIPS_RSA_MESSAGE_LENGTH] = {
- "Known plaintext message utilized"
- "for RSA Encryption & Decryption"
- "blocks SHA256, SHA384 and "
- "SHA512 RSA Signature KAT tests. "
- "Known plaintext message utilized"
- "for RSA Encryption & Decryption"
- "blocks SHA256, SHA384 and "
- "SHA512 RSA Signature KAT tests."};
-
- /* RSA Known Ciphertext (2048-bits). */
- static const PRUint8 rsa_known_ciphertext[] = {
- 0x04, 0x12, 0x46, 0xe3, 0x6a, 0xee, 0xde, 0xdd,
- 0x49, 0xa1, 0xd9, 0x83, 0xf7, 0x35, 0xf9, 0x70,
- 0x88, 0x03, 0x2d, 0x01, 0x8b, 0xd1, 0xbf, 0xdb,
- 0xe5, 0x1c, 0x85, 0xbe, 0xb5, 0x0b, 0x48, 0x45,
- 0x7a, 0xf0, 0xa0, 0xe3, 0xa2, 0xbb, 0x4b, 0xf6,
- 0x27, 0xd0, 0x1b, 0x12, 0xe3, 0x77, 0x52, 0x34,
- 0x9e, 0x8e, 0x03, 0xd2, 0xf8, 0x79, 0x6e, 0x39,
- 0x79, 0x53, 0x3c, 0x44, 0x14, 0x94, 0xbb, 0x8d,
- 0xaa, 0x14, 0x44, 0xa0, 0x7b, 0xa5, 0x8c, 0x93,
- 0x5f, 0x99, 0xa4, 0xa3, 0x6e, 0x7a, 0x38, 0x40,
- 0x78, 0xfa, 0x36, 0x91, 0x5e, 0x9a, 0x9c, 0xba,
- 0x1e, 0xd4, 0xf9, 0xda, 0x4b, 0x0f, 0xa8, 0xa3,
- 0x1c, 0xf3, 0x3a, 0xd1, 0xa5, 0xb4, 0x51, 0x16,
- 0xed, 0x4b, 0xcf, 0xec, 0x93, 0x7b, 0x90, 0x21,
- 0xbc, 0x3a, 0xf4, 0x0b, 0xd1, 0x3a, 0x2b, 0xba,
- 0xa6, 0x7d, 0x5b, 0x53, 0xd8, 0x64, 0xf9, 0x29,
- 0x7b, 0x7f, 0x77, 0x3e, 0x51, 0x4c, 0x9a, 0x94,
- 0xd2, 0x4b, 0x4a, 0x8d, 0x61, 0x74, 0x97, 0xae,
- 0x53, 0x6a, 0xf4, 0x90, 0xc2, 0x2c, 0x49, 0xe2,
- 0xfa, 0xeb, 0x91, 0xc5, 0xe5, 0x83, 0x13, 0xc9,
- 0x44, 0x4b, 0x95, 0x2c, 0x57, 0x70, 0x15, 0x5c,
- 0x64, 0x8d, 0x1a, 0xfd, 0x2a, 0xc7, 0xb2, 0x9c,
- 0x5c, 0x99, 0xd3, 0x4a, 0xfd, 0xdd, 0xf6, 0x82,
- 0x87, 0x8c, 0x5a, 0xc4, 0xa8, 0x0d, 0x2a, 0xef,
- 0xc3, 0xa2, 0x7e, 0x8e, 0x67, 0x9f, 0x6f, 0x63,
- 0xdb, 0xbb, 0x1d, 0x31, 0xc4, 0xbb, 0xbc, 0x13,
- 0x3f, 0x54, 0xc6, 0xf6, 0xc5, 0x28, 0x32, 0xab,
- 0x96, 0x42, 0x10, 0x36, 0x40, 0x92, 0xbb, 0x57,
- 0x55, 0x38, 0xf5, 0x43, 0x7e, 0x43, 0xc4, 0x65,
- 0x47, 0x64, 0xaa, 0x0f, 0x4c, 0xe9, 0x49, 0x16,
- 0xec, 0x6a, 0x50, 0xfd, 0x14, 0x49, 0xca, 0xdb,
- 0x44, 0x54, 0xca, 0xbe, 0xa3, 0x0e, 0x5f, 0xef};
-
- /* RSA Known Signed Hash (2048-bits). */
- static const PRUint8 rsa_known_sha256_signature[] = {
- 0x8c, 0x2d, 0x2e, 0xfb, 0x37, 0xb5, 0x6f, 0x38,
- 0x9f, 0x06, 0x5a, 0xf3, 0x8c, 0xa0, 0xd0, 0x7a,
- 0xde, 0xcf, 0xf9, 0x14, 0x95, 0x59, 0xd3, 0x5f,
- 0x51, 0x5d, 0x5d, 0xad, 0xd8, 0x71, 0x33, 0x50,
- 0x1d, 0x03, 0x3b, 0x3a, 0x32, 0x00, 0xb4, 0xde,
- 0x7f, 0xe4, 0xb1, 0xe5, 0x6b, 0x83, 0xf4, 0x80,
- 0x10, 0x3b, 0xb8, 0x8a, 0xdb, 0xe8, 0x0a, 0x42,
- 0x9e, 0x8d, 0xd7, 0xbe, 0xed, 0xde, 0x5a, 0x3d,
- 0xc6, 0xdb, 0xfe, 0x49, 0x6a, 0xe9, 0x1e, 0x75,
- 0x66, 0xf1, 0x3f, 0x9e, 0x3f, 0xff, 0x05, 0x65,
- 0xde, 0xca, 0x62, 0x62, 0xf3, 0xec, 0x53, 0x09,
- 0xa0, 0x37, 0xd5, 0x66, 0x62, 0x72, 0x14, 0xb6,
- 0x51, 0x32, 0x67, 0x50, 0xc1, 0xe1, 0x2f, 0x9e,
- 0x98, 0x4e, 0x53, 0x96, 0x55, 0x4b, 0xc4, 0x92,
- 0xc3, 0xb4, 0x80, 0xf0, 0x35, 0xc9, 0x00, 0x4b,
- 0x5c, 0x85, 0x92, 0xb1, 0xe8, 0x6e, 0xa5, 0x51,
- 0x38, 0x9f, 0xc9, 0x11, 0xb6, 0x14, 0xdf, 0x34,
- 0x64, 0x40, 0x82, 0x82, 0xde, 0x16, 0x69, 0x93,
- 0x89, 0x4e, 0x5c, 0x32, 0xf2, 0x0a, 0x4e, 0x9e,
- 0xbd, 0x63, 0x99, 0x4f, 0xf3, 0x15, 0x90, 0xc2,
- 0xfe, 0x6f, 0xb7, 0xf4, 0xad, 0xd4, 0x8e, 0x0b,
- 0xd2, 0xf5, 0x22, 0xd2, 0x71, 0x65, 0x13, 0xf7,
- 0x82, 0x7b, 0x75, 0xb6, 0xc1, 0xb4, 0x45, 0xbd,
- 0x8f, 0x95, 0xcf, 0x5b, 0x95, 0x32, 0xef, 0x18,
- 0x5f, 0xd3, 0xdf, 0x7e, 0x22, 0xdd, 0x25, 0xeb,
- 0xe1, 0xbf, 0x3b, 0x9a, 0x55, 0x75, 0x4f, 0x3c,
- 0x38, 0x67, 0x57, 0x04, 0x04, 0x57, 0x27, 0xf6,
- 0x34, 0x0e, 0x57, 0x8a, 0x7c, 0xff, 0x7d, 0xca,
- 0x8c, 0x06, 0xf8, 0x9d, 0xdb, 0xe4, 0xd8, 0x19,
- 0xdd, 0x4d, 0xfd, 0x8f, 0xa0, 0x06, 0x53, 0xe8,
- 0x33, 0x00, 0x70, 0x3f, 0x6b, 0xc3, 0xbd, 0x9a,
- 0x78, 0xb5, 0xa9, 0xef, 0x6d, 0xda, 0x67, 0x92};
-
- /* RSA Known Signed Hash (2048-bits). */
- static const PRUint8 rsa_known_sha384_signature[] = {
- 0x20, 0x2d, 0x21, 0x3a, 0xaa, 0x1e, 0x05, 0x15,
- 0x5c, 0xca, 0x84, 0x86, 0xc0, 0x15, 0x81, 0xdf,
- 0xd4, 0x06, 0x9f, 0xe0, 0xc1, 0xed, 0xef, 0x0f,
- 0xfe, 0xb3, 0xc3, 0xbb, 0x28, 0xa5, 0x56, 0xbf,
- 0xe3, 0x11, 0x5c, 0xc2, 0xc0, 0x0b, 0xfa, 0xfa,
- 0x3d, 0xd3, 0x06, 0x20, 0xe2, 0xc9, 0xe4, 0x66,
- 0x28, 0xb7, 0xc0, 0x3b, 0x3c, 0x96, 0xc6, 0x49,
- 0x3b, 0xcf, 0x86, 0x49, 0x31, 0xaf, 0x5b, 0xa3,
- 0xec, 0x63, 0x10, 0xdf, 0xda, 0x2f, 0x68, 0xac,
- 0x7b, 0x3a, 0x49, 0xfa, 0xe6, 0x0d, 0xfe, 0x37,
- 0x17, 0x56, 0x8e, 0x5c, 0x48, 0x97, 0x43, 0xf7,
- 0xa0, 0xbc, 0xe3, 0x4b, 0x42, 0xde, 0x58, 0x1d,
- 0xd9, 0x5d, 0xb3, 0x08, 0x35, 0xbd, 0xa4, 0xe1,
- 0x80, 0xc3, 0x64, 0xab, 0x21, 0x97, 0xad, 0xfb,
- 0x71, 0xee, 0xa3, 0x3d, 0x9c, 0xaa, 0xfa, 0x16,
- 0x60, 0x46, 0x32, 0xda, 0x44, 0x2e, 0x10, 0x92,
- 0x20, 0xd8, 0x98, 0x80, 0x84, 0x75, 0x5b, 0x70,
- 0x91, 0x00, 0x33, 0x19, 0x69, 0xc9, 0x2a, 0xec,
- 0x3d, 0xe5, 0x5f, 0x0f, 0x9a, 0xa7, 0x97, 0x1f,
- 0x79, 0xc3, 0x1d, 0x65, 0x74, 0x62, 0xc5, 0xa1,
- 0x23, 0x65, 0x4b, 0x84, 0xa1, 0x03, 0x98, 0xf3,
- 0xf1, 0x02, 0x24, 0xca, 0xe5, 0xd4, 0xc8, 0xa2,
- 0x30, 0xad, 0x72, 0x7d, 0x29, 0x60, 0x1a, 0x8e,
- 0x6f, 0x23, 0xa4, 0xda, 0x68, 0xa4, 0x45, 0x9c,
- 0x39, 0x70, 0x44, 0x18, 0x4b, 0x73, 0xfe, 0xf8,
- 0x33, 0x53, 0x1d, 0x7e, 0x93, 0x93, 0xac, 0xc7,
- 0x1e, 0x6e, 0x6b, 0xfd, 0x9e, 0xba, 0xa6, 0x71,
- 0x70, 0x47, 0x6a, 0xd6, 0x82, 0x32, 0xa2, 0x6e,
- 0x20, 0x72, 0xb0, 0xba, 0xec, 0x91, 0xbb, 0x6b,
- 0xcc, 0x84, 0x0a, 0x33, 0x2b, 0x8a, 0x8d, 0xeb,
- 0x71, 0xcd, 0xca, 0x67, 0x1b, 0xad, 0x10, 0xd4,
- 0xce, 0x4f, 0xc0, 0x29, 0xec, 0xfa, 0xed, 0xfa};
-
- /* RSA Known Signed Hash (2048-bits). */
- static const PRUint8 rsa_known_sha512_signature[] = {
- 0x35, 0x0e, 0x74, 0x9d, 0xeb, 0xc7, 0x67, 0x31,
- 0x9f, 0xff, 0x0b, 0xbb, 0x5e, 0x66, 0xb4, 0x2f,
- 0xbf, 0x72, 0x60, 0x4f, 0xe9, 0xbd, 0xec, 0xc8,
- 0x17, 0x79, 0x5f, 0x39, 0x83, 0xb4, 0x54, 0x2e,
- 0x01, 0xb9, 0xd3, 0x20, 0x47, 0xcb, 0xd4, 0x42,
- 0xf2, 0x6e, 0x36, 0xc1, 0x97, 0xad, 0xef, 0x8e,
- 0xe6, 0x51, 0xee, 0x5e, 0x9e, 0x88, 0xb4, 0x9d,
- 0xda, 0x3e, 0x77, 0x4b, 0xe8, 0xae, 0x48, 0x53,
- 0x2c, 0xc4, 0xd3, 0x25, 0x6b, 0x23, 0xb7, 0x54,
- 0x3c, 0x95, 0x8f, 0xfb, 0x6f, 0x6d, 0xc5, 0x56,
- 0x39, 0x69, 0x28, 0x0e, 0x74, 0x9b, 0x31, 0xe8,
- 0x76, 0x77, 0x2b, 0xc1, 0x44, 0x89, 0x81, 0x93,
- 0xfc, 0xf6, 0xec, 0x5f, 0x8f, 0x89, 0xfc, 0x1d,
- 0xa4, 0x53, 0x58, 0x8c, 0xe9, 0xc0, 0xc0, 0x26,
- 0xe6, 0xdf, 0x6d, 0x27, 0xb1, 0x8e, 0x3e, 0xb6,
- 0x47, 0xe1, 0x02, 0x96, 0xc2, 0x5f, 0x7f, 0x3d,
- 0xc5, 0x6c, 0x2f, 0xea, 0xaa, 0x5e, 0x39, 0xfc,
- 0x77, 0xca, 0x00, 0x02, 0x5c, 0x64, 0x7c, 0xce,
- 0x7d, 0x63, 0x82, 0x05, 0xed, 0xf7, 0x5b, 0x55,
- 0x58, 0xc0, 0xeb, 0x76, 0xd7, 0x95, 0x55, 0x37,
- 0x85, 0x7d, 0x17, 0xad, 0xd2, 0x11, 0xfd, 0x97,
- 0x48, 0xb5, 0xc2, 0x5e, 0xc7, 0x62, 0xc0, 0xe0,
- 0x68, 0xa8, 0x61, 0x14, 0x41, 0xca, 0x25, 0x3a,
- 0xec, 0x48, 0x54, 0x22, 0x83, 0x2b, 0x69, 0x54,
- 0xfd, 0xc8, 0x99, 0x9a, 0xee, 0x37, 0x03, 0xa3,
- 0x8f, 0x0f, 0x32, 0xb0, 0xaa, 0x74, 0x39, 0x04,
- 0x7c, 0xd9, 0xc2, 0x8f, 0xbe, 0xf2, 0xc4, 0xbe,
- 0xdd, 0x7a, 0x7a, 0x7f, 0x72, 0xd3, 0x80, 0x59,
- 0x18, 0xa0, 0xa1, 0x2d, 0x6f, 0xa3, 0xa9, 0x48,
- 0xed, 0x20, 0xa6, 0xea, 0xaa, 0x10, 0x83, 0x98,
- 0x0c, 0x13, 0x69, 0x6e, 0xcd, 0x31, 0x6b, 0xd0,
- 0x66, 0xa6, 0x5e, 0x30, 0x0c, 0x82, 0xd5, 0x81};
-
- static const RSAPublicKey bl_public_key = { NULL,
- { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus,
- FIPS_RSA_MODULUS_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent,
- FIPS_RSA_PUBLIC_EXPONENT_LENGTH }
- };
- static const RSAPrivateKey bl_private_key = { NULL,
- { FIPS_RSA_TYPE, (unsigned char *)rsa_version,
- FIPS_RSA_PRIVATE_VERSION_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus,
- FIPS_RSA_MODULUS_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent,
- FIPS_RSA_PUBLIC_EXPONENT_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_private_exponent,
- FIPS_RSA_PRIVATE_EXPONENT_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_prime0,
- FIPS_RSA_PRIME0_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_prime1,
- FIPS_RSA_PRIME1_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent0,
- FIPS_RSA_EXPONENT0_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent1,
- FIPS_RSA_EXPONENT1_LENGTH },
- { FIPS_RSA_TYPE, (unsigned char *)rsa_coefficient,
- FIPS_RSA_COEFFICIENT_LENGTH }
- };
-
- /* RSA variables. */
-#ifdef CREATE_TEMP_ARENAS
- PLArenaPool * rsa_public_arena;
- PLArenaPool * rsa_private_arena;
-#endif
- NSSLOWKEYPublicKey * rsa_public_key;
- NSSLOWKEYPrivateKey * rsa_private_key;
- SECStatus rsa_status;
-
- NSSLOWKEYPublicKey low_public_key = { NULL, NSSLOWKEYRSAKey, };
- NSSLOWKEYPrivateKey low_private_key = { NULL, NSSLOWKEYRSAKey, };
- PRUint8 rsa_computed_ciphertext[FIPS_RSA_ENCRYPT_LENGTH];
- PRUint8 rsa_computed_plaintext[FIPS_RSA_DECRYPT_LENGTH];
-
- /****************************************/
- /* Compose RSA Public/Private Key Pair. */
- /****************************************/
-
- low_public_key.u.rsa = bl_public_key;
- low_private_key.u.rsa = bl_private_key;
-
- rsa_public_key = &low_public_key;
- rsa_private_key = &low_private_key;
-
-#ifdef CREATE_TEMP_ARENAS
- /* Create some space for the RSA public key. */
- rsa_public_arena = PORT_NewArena( NSS_SOFTOKEN_DEFAULT_CHUNKSIZE );
-
- if( rsa_public_arena == NULL ) {
- PORT_SetError( SEC_ERROR_NO_MEMORY );
- return( CKR_HOST_MEMORY );
- }
-
- /* Create some space for the RSA private key. */
- rsa_private_arena = PORT_NewArena( NSS_SOFTOKEN_DEFAULT_CHUNKSIZE );
-
- if( rsa_private_arena == NULL ) {
- PORT_FreeArena( rsa_public_arena, PR_TRUE );
- PORT_SetError( SEC_ERROR_NO_MEMORY );
- return( CKR_HOST_MEMORY );
- }
-
- rsa_public_key->arena = rsa_public_arena;
- rsa_private_key->arena = rsa_private_arena;
-#endif
-
- /**************************************************/
- /* RSA Single-Round Known Answer Encryption Test. */
- /**************************************************/
-
- /* Perform RSA Public Key Encryption. */
- rsa_status = RSA_PublicKeyOp(&rsa_public_key->u.rsa,
- rsa_computed_ciphertext,
- rsa_known_plaintext_msg);
-
- if( ( rsa_status != SECSuccess ) ||
- ( PORT_Memcmp( rsa_computed_ciphertext, rsa_known_ciphertext,
- FIPS_RSA_ENCRYPT_LENGTH ) != 0 ) )
- goto rsa_loser;
-
- /**************************************************/
- /* RSA Single-Round Known Answer Decryption Test. */
- /**************************************************/
-
- /* Perform RSA Private Key Decryption. */
- rsa_status = RSA_PrivateKeyOp(&rsa_private_key->u.rsa,
- rsa_computed_plaintext,
- rsa_known_ciphertext);
-
- if( ( rsa_status != SECSuccess ) ||
- ( PORT_Memcmp( rsa_computed_plaintext, rsa_known_plaintext_msg,
- FIPS_RSA_DECRYPT_LENGTH ) != 0 ) )
- goto rsa_loser;
-
- rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA256,
- rsa_public_key, rsa_private_key,
- rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH,
- rsa_known_sha256_signature);
- if( rsa_status != SECSuccess )
- goto rsa_loser;
-
- rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA384,
- rsa_public_key, rsa_private_key,
- rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH,
- rsa_known_sha384_signature);
- if( rsa_status != SECSuccess )
- goto rsa_loser;
-
- rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA512,
- rsa_public_key, rsa_private_key,
- rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH,
- rsa_known_sha512_signature);
- if( rsa_status != SECSuccess )
- goto rsa_loser;
-
- /* Dispose of all RSA key material. */
- nsslowkey_DestroyPublicKey( rsa_public_key );
- nsslowkey_DestroyPrivateKey( rsa_private_key );
-
- return( CKR_OK );
-
-rsa_loser:
-
- nsslowkey_DestroyPublicKey( rsa_public_key );
- nsslowkey_DestroyPrivateKey( rsa_private_key );
-
- return( CKR_DEVICE_ERROR );
-}
-
-#ifdef NSS_ENABLE_ECC
-
-static CK_RV
-sftk_fips_ECDSA_Test(const PRUint8 *encodedParams,
- unsigned int encodedParamsLen,
- const PRUint8 *knownSignature,
- unsigned int knownSignatureLen) {
-
- /* ECDSA Known Seed info for curves nistp256 and nistk283 */
- static const PRUint8 ecdsa_Known_Seed[] = {
- 0x6a, 0x9b, 0xf6, 0xf7, 0xce, 0xed, 0x79, 0x11,
- 0xf0, 0xc7, 0xc8, 0x9a, 0xa5, 0xd1, 0x57, 0xb1,
- 0x7b, 0x5a, 0x3b, 0x76, 0x4e, 0x7b, 0x7c, 0xbc,
- 0xf2, 0x76, 0x1c, 0x1c, 0x7f, 0xc5, 0x53, 0x2f};
-
- static const PRUint8 msg[] = {
- "Firefox and ThunderBird are awesome!"};
-
- unsigned char sha1[SHA1_LENGTH]; /* SHA-1 hash (160 bits) */
- unsigned char sig[2*MAX_ECKEY_LEN];
- SECItem signature, digest;
- SECItem encodedparams;
- ECParams *ecparams = NULL;
- ECPrivateKey *ecdsa_private_key = NULL;
- ECPublicKey ecdsa_public_key;
- SECStatus ecdsaStatus = SECSuccess;
-
- /* construct the ECDSA private/public key pair */
- encodedparams.type = siBuffer;
- encodedparams.data = (unsigned char *) encodedParams;
- encodedparams.len = encodedParamsLen;
-
- if (EC_DecodeParams(&encodedparams, &ecparams) != SECSuccess) {
- return( CKR_DEVICE_ERROR );
- }
-
- /* Generates a new EC key pair. The private key is a supplied
- * random value (in seed) and the public key is the result of
- * performing a scalar point multiplication of that value with
- * the curve's base point.
- */
- ecdsaStatus = EC_NewKeyFromSeed(ecparams, &ecdsa_private_key,
- ecdsa_Known_Seed,
- sizeof(ecdsa_Known_Seed));
- /* free the ecparams they are no longer needed */
- PORT_FreeArena(ecparams->arena, PR_FALSE);
- ecparams = NULL;
- if (ecdsaStatus != SECSuccess) {
- return ( CKR_DEVICE_ERROR );
- }
-
- /* construct public key from private key. */
- ecdsaStatus = EC_CopyParams(ecdsa_private_key->ecParams.arena,
- &ecdsa_public_key.ecParams,
- &ecdsa_private_key->ecParams);
- if (ecdsaStatus != SECSuccess) {
- goto loser;
- }
- ecdsa_public_key.publicValue = ecdsa_private_key->publicValue;
-
- /* validate public key value */
- ecdsaStatus = EC_ValidatePublicKey(&ecdsa_public_key.ecParams,
- &ecdsa_public_key.publicValue);
- if (ecdsaStatus != SECSuccess) {
- goto loser;
- }
-
- /* validate public key value */
- ecdsaStatus = EC_ValidatePublicKey(&ecdsa_private_key->ecParams,
- &ecdsa_private_key->publicValue);
- if (ecdsaStatus != SECSuccess) {
- goto loser;
- }
-
- /***************************************************/
- /* ECDSA Single-Round Known Answer Signature Test. */
- /***************************************************/
-
- ecdsaStatus = SHA1_HashBuf(sha1, msg, sizeof msg);
- if (ecdsaStatus != SECSuccess) {
- goto loser;
- }
- digest.type = siBuffer;
- digest.data = sha1;
- digest.len = SHA1_LENGTH;
-
- memset(sig, 0, sizeof sig);
- signature.type = siBuffer;
- signature.data = sig;
- signature.len = sizeof sig;
-
- ecdsaStatus = ECDSA_SignDigestWithSeed(ecdsa_private_key, &signature,
- &digest, ecdsa_Known_Seed, sizeof ecdsa_Known_Seed);
- if (ecdsaStatus != SECSuccess) {
- goto loser;
- }
-
- if( ( signature.len != knownSignatureLen ) ||
- ( PORT_Memcmp( signature.data, knownSignature,
- knownSignatureLen ) != 0 ) ) {
- ecdsaStatus = SECFailure;
- goto loser;
- }
-
- /******************************************************/
- /* ECDSA Single-Round Known Answer Verification Test. */
- /******************************************************/
-
- /* Perform ECDSA verification process. */
- ecdsaStatus = ECDSA_VerifyDigest(&ecdsa_public_key, &signature, &digest);
-
-loser:
- /* free the memory for the private key arena*/
- if (ecdsa_private_key != NULL) {
- PORT_FreeArena(ecdsa_private_key->ecParams.arena, PR_FALSE);
- }
-
- if (ecdsaStatus != SECSuccess) {
- return CKR_DEVICE_ERROR ;
- }
- return( CKR_OK );
-}
-
-static CK_RV
-sftk_fips_ECDSA_PowerUpSelfTest() {
-
- /* ECDSA Known curve nistp256 == SEC_OID_SECG_EC_SECP256R1 params */
- static const PRUint8 ecdsa_known_P256_EncodedParams[] = {
- 0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03,
- 0x01,0x07};
-
- static const PRUint8 ecdsa_known_P256_signature[] = {
- 0x07,0xb1,0xcb,0x57,0x20,0xa7,0x10,0xd6,
- 0x9d,0x37,0x4b,0x1c,0xdc,0x35,0x90,0xff,
- 0x1a,0x2d,0x98,0x95,0x1b,0x2f,0xeb,0x7f,
- 0xbb,0x81,0xca,0xc0,0x69,0x75,0xea,0xc5,
- 0x59,0x6a,0x62,0x49,0x3d,0x50,0xc9,0xe1,
- 0x27,0x3b,0xff,0x9b,0x13,0x66,0x67,0xdd,
- 0x7d,0xd1,0x0d,0x2d,0x7c,0x44,0x04,0x1b,
- 0x16,0x21,0x12,0xc5,0xcb,0xbd,0x9e,0x75};
-
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
- /* ECDSA Known curve nistk283 == SEC_OID_SECG_EC_SECT283K1 params */
- static const PRUint8 ecdsa_known_K283_EncodedParams[] = {
- 0x06,0x05,0x2b,0x81,0x04,0x00,0x10};
-
- static const PRUint8 ecdsa_known_K283_signature[] = {
- 0x00,0x45,0x88,0xc0,0x79,0x09,0x07,0xd1,
- 0x4e,0x88,0xe6,0xd5,0x2f,0x22,0x04,0x74,
- 0x35,0x24,0x65,0xe8,0x15,0xde,0x90,0x66,
- 0x94,0x70,0xdd,0x3a,0x14,0x70,0x02,0xd1,
- 0xef,0x86,0xbd,0x15,0x00,0xd9,0xdc,0xfc,
- 0x87,0x2e,0x7c,0x99,0xe2,0xe3,0x79,0xb8,
- 0xd9,0x10,0x49,0x78,0x4b,0x59,0x8b,0x05,
- 0x77,0xec,0x6c,0xe8,0x35,0xe6,0x2e,0xa9,
- 0xf9,0x77,0x1f,0x71,0x86,0xa5,0x4a,0xd0};
-#endif
-
- CK_RV crv;
-
- /* ECDSA GF(p) prime field curve test */
- crv = sftk_fips_ECDSA_Test(ecdsa_known_P256_EncodedParams,
- sizeof ecdsa_known_P256_EncodedParams,
- ecdsa_known_P256_signature,
- sizeof ecdsa_known_P256_signature );
- if (crv != CKR_OK) {
- return( CKR_DEVICE_ERROR );
- }
-
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
- /* ECDSA GF(2m) binary field curve test */
- crv = sftk_fips_ECDSA_Test(ecdsa_known_K283_EncodedParams,
- sizeof ecdsa_known_K283_EncodedParams,
- ecdsa_known_K283_signature,
- sizeof ecdsa_known_K283_signature );
- if (crv != CKR_OK) {
- return( CKR_DEVICE_ERROR );
- }
-#endif
-
- return( CKR_OK );
-}
-
-#endif /* NSS_ENABLE_ECC */
-
-static CK_RV
-sftk_fips_DSA_PowerUpSelfTest( void )
-{
- /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */
- static const PRUint8 dsa_P[] = {
- 0x80,0xb0,0xd1,0x9d,0x6e,0xa4,0xf3,0x28,
- 0x9f,0x24,0xa9,0x8a,0x49,0xd0,0x0c,0x63,
- 0xe8,0x59,0x04,0xf9,0x89,0x4a,0x5e,0xc0,
- 0x6d,0xd2,0x67,0x6b,0x37,0x81,0x83,0x0c,
- 0xfe,0x3a,0x8a,0xfd,0xa0,0x3b,0x08,0x91,
- 0x1c,0xcb,0xb5,0x63,0xb0,0x1c,0x70,0xd0,
- 0xae,0xe1,0x60,0x2e,0x12,0xeb,0x54,0xc7,
- 0xcf,0xc6,0xcc,0xae,0x97,0x52,0x32,0x63,
- 0xd3,0xeb,0x55,0xea,0x2f,0x4c,0xd5,0xd7,
- 0x3f,0xda,0xec,0x49,0x27,0x0b,0x14,0x56,
- 0xc5,0x09,0xbe,0x4d,0x09,0x15,0x75,0x2b,
- 0xa3,0x42,0x0d,0x03,0x71,0xdf,0x0f,0xf4,
- 0x0e,0xe9,0x0c,0x46,0x93,0x3d,0x3f,0xa6,
- 0x6c,0xdb,0xca,0xe5,0xac,0x96,0xc8,0x64,
- 0x5c,0xec,0x4b,0x35,0x65,0xfc,0xfb,0x5a,
- 0x1b,0x04,0x1b,0xa1,0x0e,0xfd,0x88,0x15};
-
- static const PRUint8 dsa_Q[] = {
- 0xad,0x22,0x59,0xdf,0xe5,0xec,0x4c,0x6e,
- 0xf9,0x43,0xf0,0x4b,0x2d,0x50,0x51,0xc6,
- 0x91,0x99,0x8b,0xcf};
-
- static const PRUint8 dsa_G[] = {
- 0x78,0x6e,0xa9,0xd8,0xcd,0x4a,0x85,0xa4,
- 0x45,0xb6,0x6e,0x5d,0x21,0x50,0x61,0xf6,
- 0x5f,0xdf,0x5c,0x7a,0xde,0x0d,0x19,0xd3,
- 0xc1,0x3b,0x14,0xcc,0x8e,0xed,0xdb,0x17,
- 0xb6,0xca,0xba,0x86,0xa9,0xea,0x51,0x2d,
- 0xc1,0xa9,0x16,0xda,0xf8,0x7b,0x59,0x8a,
- 0xdf,0xcb,0xa4,0x67,0x00,0x44,0xea,0x24,
- 0x73,0xe5,0xcb,0x4b,0xaf,0x2a,0x31,0x25,
- 0x22,0x28,0x3f,0x16,0x10,0x82,0xf7,0xeb,
- 0x94,0x0d,0xdd,0x09,0x22,0x14,0x08,0x79,
- 0xba,0x11,0x0b,0xf1,0xff,0x2d,0x67,0xac,
- 0xeb,0xb6,0x55,0x51,0x69,0x97,0xa7,0x25,
- 0x6b,0x9c,0xa0,0x9b,0xd5,0x08,0x9b,0x27,
- 0x42,0x1c,0x7a,0x69,0x57,0xe6,0x2e,0xed,
- 0xa9,0x5b,0x25,0xe8,0x1f,0xd2,0xed,0x1f,
- 0xdf,0xe7,0x80,0x17,0xba,0x0d,0x4d,0x38};
-
- /* DSA Known Random Values (known random key block is 160-bits) */
- /* and (known random signature block is 160-bits). */
- static const PRUint8 dsa_known_random_key_block[] = {
- "Mozilla Rules World!"};
- static const PRUint8 dsa_known_random_signature_block[] = {
- "Random DSA Signature"};
-
- /* DSA Known Digest (160-bits) */
- static const PRUint8 dsa_known_digest[] = { "DSA Signature Digest" };
-
- /* DSA Known Signature (320-bits). */
- static const PRUint8 dsa_known_signature[] = {
- 0x25,0x7c,0x3a,0x79,0x32,0x45,0xb7,0x32,
- 0x70,0xca,0x62,0x63,0x2b,0xf6,0x29,0x2c,
- 0x22,0x2a,0x03,0xce,0x48,0x15,0x11,0x72,
- 0x7b,0x7e,0xf5,0x7a,0xf3,0x10,0x3b,0xde,
- 0x34,0xc1,0x9e,0xd7,0x27,0x9e,0x77,0x38};
-
- /* DSA variables. */
- DSAPrivateKey * dsa_private_key;
- SECStatus dsa_status;
- SECItem dsa_signature_item;
- SECItem dsa_digest_item;
- DSAPublicKey dsa_public_key;
- PRUint8 dsa_computed_signature[FIPS_DSA_SIGNATURE_LENGTH];
- static const PQGParams dsa_pqg = { NULL,
- { FIPS_DSA_TYPE, (unsigned char *)dsa_P, FIPS_DSA_PRIME_LENGTH },
- { FIPS_DSA_TYPE, (unsigned char *)dsa_Q, FIPS_DSA_SUBPRIME_LENGTH },
- { FIPS_DSA_TYPE, (unsigned char *)dsa_G, FIPS_DSA_BASE_LENGTH }};
-
- /*******************************************/
- /* Generate a DSA public/private key pair. */
- /*******************************************/
-
- /* Generate a DSA public/private key pair. */
- dsa_status = DSA_NewKeyFromSeed(&dsa_pqg, dsa_known_random_key_block,
- &dsa_private_key);
-
- if( dsa_status != SECSuccess )
- return( CKR_HOST_MEMORY );
-
- /* construct public key from private key. */
- dsa_public_key.params = dsa_private_key->params;
- dsa_public_key.publicValue = dsa_private_key->publicValue;
-
- /*************************************************/
- /* DSA Single-Round Known Answer Signature Test. */
- /*************************************************/
-
- dsa_signature_item.data = dsa_computed_signature;
- dsa_signature_item.len = sizeof dsa_computed_signature;
-
- dsa_digest_item.data = (unsigned char *)dsa_known_digest;
- dsa_digest_item.len = SHA1_LENGTH;
-
- /* Perform DSA signature process. */
- dsa_status = DSA_SignDigestWithSeed( dsa_private_key,
- &dsa_signature_item,
- &dsa_digest_item,
- dsa_known_random_signature_block );
-
- if( ( dsa_status != SECSuccess ) ||
- ( dsa_signature_item.len != FIPS_DSA_SIGNATURE_LENGTH ) ||
- ( PORT_Memcmp( dsa_computed_signature, dsa_known_signature,
- FIPS_DSA_SIGNATURE_LENGTH ) != 0 ) ) {
- dsa_status = SECFailure;
- } else {
-
- /****************************************************/
- /* DSA Single-Round Known Answer Verification Test. */
- /****************************************************/
-
- /* Perform DSA verification process. */
- dsa_status = DSA_VerifyDigest( &dsa_public_key,
- &dsa_signature_item,
- &dsa_digest_item);
- }
-
- PORT_FreeArena(dsa_private_key->params.arena, PR_TRUE);
- /* Don't free public key, it uses same arena as private key */
-
- /* Verify DSA signature. */
- if( dsa_status != SECSuccess )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-
-
-}
-
-static CK_RV
-sftk_fips_RNG_PowerUpSelfTest( void )
-{
- static const PRUint8 Q[] = {
- 0x85,0x89,0x9c,0x77,0xa3,0x79,0xff,0x1a,
- 0x86,0x6f,0x2f,0x3e,0x2e,0xf9,0x8c,0x9c,
- 0x9d,0xef,0xeb,0xed};
- static const PRUint8 GENX[] = {
- 0x65,0x48,0xe3,0xca,0xac,0x64,0x2d,0xf7,
- 0x7b,0xd3,0x4e,0x79,0xc9,0x7d,0xa6,0xa8,
- 0xa2,0xc2,0x1f,0x8f,0xe9,0xb9,0xd3,0xa1,
- 0x3f,0xf7,0x0c,0xcd,0xa6,0xca,0xbf,0xce,
- 0x84,0x0e,0xb6,0xf1,0x0d,0xbe,0xa9,0xa3};
- static const PRUint8 rng_known_DSAX[] = {
- 0x7a,0x86,0xf1,0x7f,0xbd,0x4e,0x6e,0xd9,
- 0x0a,0x26,0x21,0xd0,0x19,0xcb,0x86,0x73,
- 0x10,0x1f,0x60,0xd7};
-
-
-
- SECStatus rng_status = SECSuccess;
- PRUint8 DSAX[FIPS_DSA_SUBPRIME_LENGTH];
-
- /*******************************************/
- /* Run the SP 800-90 Health tests */
- /*******************************************/
- rng_status = PRNGTEST_RunHealthTests();
- if (rng_status != SECSuccess) {
- return (CKR_DEVICE_ERROR);
- }
-
- /*******************************************/
- /* Generate DSAX fow given Q. */
- /*******************************************/
-
- rng_status = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
-
- /* Verify DSAX to perform the RNG integrity check */
- if( ( rng_status != SECSuccess ) ||
- ( PORT_Memcmp( DSAX, rng_known_DSAX,
- (FIPS_DSA_SUBPRIME_LENGTH) ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-static CK_RV
-sftk_fipsSoftwareIntegrityTest(void)
-{
- CK_RV crv = CKR_OK;
-
- /* make sure that our check file signatures are OK */
- if( !BLAPI_VerifySelf( NULL ) ||
- !BLAPI_SHVerify( SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_fips_HMAC ) ) {
- crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
- }
- return crv;
-}
-
-CK_RV
-sftk_fipsPowerUpSelfTest( void )
-{
- CK_RV rv;
-
- /* RC2 Power-Up SelfTest(s). */
- rv = sftk_fips_RC2_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* RC4 Power-Up SelfTest(s). */
- rv = sftk_fips_RC4_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* DES Power-Up SelfTest(s). */
- rv = sftk_fips_DES_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* DES3 Power-Up SelfTest(s). */
- rv = sftk_fips_DES3_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* AES Power-Up SelfTest(s) for 128-bit key. */
- rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_128_KEY_SIZE);
-
- if( rv != CKR_OK )
- return rv;
-
- /* AES Power-Up SelfTest(s) for 192-bit key. */
- rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_192_KEY_SIZE);
-
- if( rv != CKR_OK )
- return rv;
-
- /* AES Power-Up SelfTest(s) for 256-bit key. */
- rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_256_KEY_SIZE);
-
- if( rv != CKR_OK )
- return rv;
-
- /* MD2 Power-Up SelfTest(s). */
- rv = sftk_fips_MD2_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* MD5 Power-Up SelfTest(s). */
- rv = sftk_fips_MD5_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* SHA-X Power-Up SelfTest(s). */
- rv = sftk_fips_SHA_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* HMAC SHA-X Power-Up SelfTest(s). */
- rv = sftk_fips_HMAC_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* RSA Power-Up SelfTest(s). */
- rv = sftk_fips_RSA_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* DSA Power-Up SelfTest(s). */
- rv = sftk_fips_DSA_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* RNG Power-Up SelfTest(s). */
- rv = sftk_fips_RNG_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
-#ifdef NSS_ENABLE_ECC
- /* ECDSA Power-Up SelfTest(s). */
- rv = sftk_fips_ECDSA_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-#endif
-
- /* Software/Firmware Integrity Test. */
- rv = sftk_fipsSoftwareIntegrityTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* Passed Power-Up SelfTest(s). */
- return( CKR_OK );
-}
-
diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c
deleted file mode 100644
index 1381e6a96..000000000
--- a/security/nss/lib/softoken/fipstokn.c
+++ /dev/null
@@ -1,1575 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file implements PKCS 11 on top of our existing security modules
- *
- * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
- * This implementation has two slots:
- * slot 1 is our generic crypto support. It does not require login
- * (unless you've enabled FIPS). It supports Public Key ops, and all they
- * bulk ciphers and hashes. It can also support Private Key ops for imported
- * Private keys. It does not have any token storage.
- * slot 2 is our private key support. It requires a login before use. It
- * can store Private Keys and Certs as token objects. Currently only private
- * keys and their associated Certificates are saved on the token.
- *
- * In this implementation, session objects are only visible to the session
- * that created or generated them.
- */
-#include "seccomon.h"
-#include "softoken.h"
-#include "lowkeyi.h"
-#include "pkcs11.h"
-#include "pkcs11i.h"
-#include "prenv.h"
-#include "prprf.h"
-
-#include <ctype.h>
-
-#ifdef XP_UNIX
-#define NSS_AUDIT_WITH_SYSLOG 1
-#include <syslog.h>
-#include <unistd.h>
-#endif
-
-#ifdef SOLARIS
-#include <bsm/libbsm.h>
-#define AUE_FIPS_AUDIT 34444
-#endif
-
-#ifdef LINUX
-#include <pthread.h>
-#include <dlfcn.h>
-#define LIBAUDIT_NAME "libaudit.so.0"
-#ifndef AUDIT_CRYPTO_TEST_USER
-#define AUDIT_CRYPTO_TEST_USER 2400 /* Crypto test results */
-#define AUDIT_CRYPTO_PARAM_CHANGE_USER 2401 /* Crypto attribute change */
-#define AUDIT_CRYPTO_LOGIN 2402 /* Logged in as crypto officer */
-#define AUDIT_CRYPTO_LOGOUT 2403 /* Logged out from crypto */
-#define AUDIT_CRYPTO_KEY_USER 2404 /* Create,delete,negotiate */
-#define AUDIT_CRYPTO_FAILURE_USER 2405 /* Fail decrypt,encrypt,randomize */
-#endif
-static void *libaudit_handle;
-static int (*audit_open_func)(void);
-static void (*audit_close_func)(int fd);
-static int (*audit_log_user_message_func)(int audit_fd, int type,
- const char *message, const char *hostname, const char *addr,
- const char *tty, int result);
-static int (*audit_send_user_message_func)(int fd, int type,
- const char *message);
-
-static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT;
-
-static void
-libaudit_init(void)
-{
- libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY);
- if (!libaudit_handle) {
- return;
- }
- audit_open_func = dlsym(libaudit_handle, "audit_open");
- audit_close_func = dlsym(libaudit_handle, "audit_close");
- /*
- * audit_send_user_message is the older function.
- * audit_log_user_message, if available, is preferred.
- */
- audit_log_user_message_func = dlsym(libaudit_handle,
- "audit_log_user_message");
- if (!audit_log_user_message_func) {
- audit_send_user_message_func = dlsym(libaudit_handle,
- "audit_send_user_message");
- }
- if (!audit_open_func || !audit_close_func ||
- (!audit_log_user_message_func && !audit_send_user_message_func)) {
- dlclose(libaudit_handle);
- libaudit_handle = NULL;
- audit_open_func = NULL;
- audit_close_func = NULL;
- audit_log_user_message_func = NULL;
- audit_send_user_message_func = NULL;
- }
-}
-#endif /* LINUX */
-
-
-/*
- * ******************** Password Utilities *******************************
- */
-static PRBool isLoggedIn = PR_FALSE;
-PRBool sftk_fatalError = PR_FALSE;
-
-/*
- * This function returns
- * - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string
- * - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not
- * consist of characters from three or more character classes.
- * - CKR_OK otherwise
- *
- * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters.
- * We define five character classes: digits (0-9), ASCII lowercase letters,
- * ASCII uppercase letters, ASCII non-alphanumeric characters (such as
- * space and punctuation marks), and non-ASCII characters. If an ASCII
- * uppercase letter is the first character of the password/PIN, the
- * uppercase letter is not counted toward its character class. Similarly,
- * if a digit is the last character of the password/PIN, the digit is not
- * counted toward its character class.
- *
- * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum
- * password/PIN length checks, they check the length in bytes as opposed
- * to characters. To meet the minimum password/PIN guessing probability
- * requirements in FIPS 140-2, we need to check the length in characters.
- */
-static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
- unsigned int i;
- int nchar = 0; /* number of characters */
- int ntrail = 0; /* number of trailing bytes to follow */
- int ndigit = 0; /* number of decimal digits */
- int nlower = 0; /* number of ASCII lowercase letters */
- int nupper = 0; /* number of ASCII uppercase letters */
- int nnonalnum = 0; /* number of ASCII non-alphanumeric characters */
- int nnonascii = 0; /* number of non-ASCII characters */
- int nclass; /* number of character classes */
-
- for (i = 0; i < ulPinLen; i++) {
- unsigned int byte = pPin[i];
-
- if (ntrail) {
- if ((byte & 0xc0) != 0x80) {
- /* illegal */
- nchar = -1;
- break;
- }
- if (--ntrail == 0) {
- nchar++;
- nnonascii++;
- }
- continue;
- }
- if ((byte & 0x80) == 0x00) {
- /* single-byte (ASCII) character */
- nchar++;
- if (isdigit(byte)) {
- if (i < ulPinLen - 1) {
- ndigit++;
- }
- } else if (islower(byte)) {
- nlower++;
- } else if (isupper(byte)) {
- if (i > 0) {
- nupper++;
- }
- } else {
- nnonalnum++;
- }
- } else if ((byte & 0xe0) == 0xc0) {
- /* leading byte of two-byte character */
- ntrail = 1;
- } else if ((byte & 0xf0) == 0xe0) {
- /* leading byte of three-byte character */
- ntrail = 2;
- } else if ((byte & 0xf8) == 0xf0) {
- /* leading byte of four-byte character */
- ntrail = 3;
- } else {
- /* illegal */
- nchar = -1;
- break;
- }
- }
- if (nchar == -1) {
- /* illegal UTF8 string */
- return CKR_PIN_INVALID;
- }
- if (nchar < FIPS_MIN_PIN) {
- return CKR_PIN_LEN_RANGE;
- }
- nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) +
- (nnonalnum != 0) + (nnonascii != 0);
- if (nclass < 3) {
- return CKR_PIN_LEN_RANGE;
- }
- return CKR_OK;
-}
-
-
-/* FIPS required checks before any useful cryptographic services */
-static CK_RV sftk_fipsCheck(void) {
- if (sftk_fatalError)
- return CKR_DEVICE_ERROR;
- if (!isLoggedIn)
- return CKR_USER_NOT_LOGGED_IN;
- return CKR_OK;
-}
-
-
-#define SFTK_FIPSCHECK() \
- CK_RV rv; \
- if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
-
-#define SFTK_FIPSFATALCHECK() \
- if (sftk_fatalError) return CKR_DEVICE_ERROR;
-
-
-/* grab an attribute out of a raw template */
-void *
-fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type)
-{
- int i;
-
- for (i=0; i < (int) ulCount; i++) {
- if (pTemplate[i].type == type) {
- return pTemplate[i].pValue;
- }
- }
- return NULL;
-}
-
-
-#define __PASTE(x,y) x##y
-
-/* ------------- forward declare all the NSC_ functions ------------- */
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS,name)
-#define CK_NEED_ARG_LIST 1
-
-#include "pkcs11f.h"
-
-/* ------------- forward declare all the FIPS functions ------------- */
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F,name)
-#define CK_NEED_ARG_LIST 1
-
-#include "pkcs11f.h"
-
-/* ------------- build the CK_CRYPTO_TABLE ------------------------- */
-static CK_FUNCTION_LIST sftk_fipsTable = {
- { 1, 10 },
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-#define CK_PKCS11_FUNCTION_INFO(name) __PASTE(F,name),
-
-
-#include "pkcs11f.h"
-
-};
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-#undef __PASTE
-
-/* CKO_NOT_A_KEY can be any object class that's not a key object. */
-#define CKO_NOT_A_KEY CKO_DATA
-
-#define SFTK_IS_KEY_OBJECT(objClass) \
- (((objClass) == CKO_PUBLIC_KEY) || \
- ((objClass) == CKO_PRIVATE_KEY) || \
- ((objClass) == CKO_SECRET_KEY))
-
-#define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \
- (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY))
-
-static CK_RV
-sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass)
-{
- CK_RV rv;
- CK_ATTRIBUTE class;
- class.type = CKA_CLASS;
- class.pValue = pObjClass;
- class.ulValueLen = sizeof(*pObjClass);
- rv = NSC_GetAttributeValue(hSession, hObject, &class, 1);
- if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) {
- rv = sftk_fipsCheck();
- }
- return rv;
-}
-
-#ifdef LINUX
-
-int
-sftk_mapLinuxAuditType(NSSAuditSeverity severity, NSSAuditType auditType)
-{
- switch (auditType) {
- case NSS_AUDIT_ACCESS_KEY:
- case NSS_AUDIT_CHANGE_KEY:
- case NSS_AUDIT_COPY_KEY:
- case NSS_AUDIT_DERIVE_KEY:
- case NSS_AUDIT_DESTROY_KEY:
- case NSS_AUDIT_DIGEST_KEY:
- case NSS_AUDIT_GENERATE_KEY:
- case NSS_AUDIT_LOAD_KEY:
- case NSS_AUDIT_UNWRAP_KEY:
- case NSS_AUDIT_WRAP_KEY:
- return AUDIT_CRYPTO_KEY_USER;
- case NSS_AUDIT_CRYPT:
- return (severity == NSS_AUDIT_ERROR) ? AUDIT_CRYPTO_FAILURE_USER :
- AUDIT_CRYPTO_KEY_USER;
- case NSS_AUDIT_FIPS_STATE:
- case NSS_AUDIT_INIT_PIN:
- case NSS_AUDIT_INIT_TOKEN:
- case NSS_AUDIT_SET_PIN:
- return AUDIT_CRYPTO_PARAM_CHANGE_USER;
- case NSS_AUDIT_SELF_TEST:
- return AUDIT_CRYPTO_TEST_USER;
- case NSS_AUDIT_LOGIN:
- return AUDIT_CRYPTO_LOGIN;
- case NSS_AUDIT_LOGOUT:
- return AUDIT_CRYPTO_LOGOUT;
- /* we skip the fault case here so we can get compiler
- * warnings if new 'NSSAuditType's are added without
- * added them to this list, defaults fall through */
- }
- /* default */
- return AUDIT_CRYPTO_PARAM_CHANGE_USER;
-}
-#endif
-
-
-/**********************************************************************
- *
- * FIPS 140 auditable event logging
- *
- **********************************************************************/
-
-PRBool sftk_audit_enabled = PR_FALSE;
-
-/*
- * Each audit record must have the following information:
- * - Date and time of the event
- * - Type of event
- * - user (subject) identity
- * - outcome (success or failure) of the event
- * - process ID
- * - name (ID) of the object
- * - for changes to data (except for authentication data and CSPs), the new
- * and old values of the data
- * - for authentication attempts, the origin of the attempt (e.g., terminal
- * identifier)
- * - for assuming a role, the type of role, and the location of the request
- */
-void
-sftk_LogAuditMessage(NSSAuditSeverity severity, NSSAuditType auditType,
- const char *msg)
-{
-#ifdef NSS_AUDIT_WITH_SYSLOG
- int level;
-
- switch (severity) {
- case NSS_AUDIT_ERROR:
- level = LOG_ERR;
- break;
- case NSS_AUDIT_WARNING:
- level = LOG_WARNING;
- break;
- default:
- level = LOG_INFO;
- break;
- }
- /* timestamp is provided by syslog in the message header */
- syslog(level | LOG_USER /* facility */,
- "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s",
- (int)getpid(), (int)getuid(), msg);
-#ifdef LINUX
- if (pthread_once(&libaudit_once_control, libaudit_init) != 0) {
- return;
- }
- if (libaudit_handle) {
- int audit_fd;
- int linuxAuditType;
- int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */
- char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg);
- if (!message) {
- return;
- }
- audit_fd = audit_open_func();
- if (audit_fd < 0) {
- PR_smprintf_free(message);
- return;
- }
- linuxAuditType = sftk_mapLinuxAuditType(severity, auditType);
- if (audit_log_user_message_func) {
- audit_log_user_message_func(audit_fd, linuxAuditType, message,
- NULL, NULL, NULL, result);
- } else {
- audit_send_user_message_func(audit_fd, linuxAuditType, message);
- }
- audit_close_func(audit_fd);
- PR_smprintf_free(message);
- }
-#endif /* LINUX */
-#ifdef SOLARIS
- {
- int rd;
- char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg);
-
- if (!message) {
- return;
- }
-
- /* open the record descriptor */
- if ((rd = au_open()) == -1) {
- PR_smprintf_free(message);
- return;
- }
-
- /* write the audit tokens to the audit record */
- if (au_write(rd, au_to_text(message))) {
- (void)au_close(rd, AU_TO_NO_WRITE, AUE_FIPS_AUDIT);
- PR_smprintf_free(message);
- return;
- }
-
- /* close the record and send it to the audit trail */
- (void)au_close(rd, AU_TO_WRITE, AUE_FIPS_AUDIT);
-
- PR_smprintf_free(message);
- }
-#endif /* SOLARIS */
-#else
- /* do nothing */
-#endif
-}
-
-
-/**********************************************************************
- *
- * Start of PKCS 11 functions
- *
- **********************************************************************/
-/* return the function list */
-CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
-
- CHECK_FORK();
-
- *pFunctionList = &sftk_fipsTable;
- return CKR_OK;
-}
-
-/* sigh global so pkcs11 can read it */
-PRBool nsf_init = PR_FALSE;
-
-/* FC_Initialize initializes the PKCS #11 library. */
-CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
- const char *envp;
- CK_RV crv;
-
- sftk_ForkReset(pReserved, &crv);
-
- if (nsf_init) {
- return CKR_CRYPTOKI_ALREADY_INITIALIZED;
- }
-
- if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) {
- sftk_audit_enabled = (atoi(envp) == 1);
- }
-
- crv = nsc_CommonInitialize(pReserved, PR_TRUE);
-
- /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/
- if (crv != CKR_OK) {
- sftk_fatalError = PR_TRUE;
- return crv;
- }
-
- sftk_fatalError = PR_FALSE; /* any error has been reset */
-
- crv = sftk_fipsPowerUpSelfTest();
- if (crv != CKR_OK) {
- nsc_CommonFinalize(NULL, PR_TRUE);
- sftk_fatalError = PR_TRUE;
- if (sftk_audit_enabled) {
- char msg[128];
- PR_snprintf(msg,sizeof msg,
- "C_Initialize()=0x%08lX "
- "power-up self-tests failed",
- (PRUint32)crv);
- sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
- }
- return crv;
- }
- nsf_init = PR_TRUE;
-
- return CKR_OK;
-}
-
-/*FC_Finalize indicates that an application is done with the PKCS #11 library.*/
-CK_RV FC_Finalize (CK_VOID_PTR pReserved) {
- CK_RV crv;
-
- if (sftk_ForkReset(pReserved, &crv)) {
- return crv;
- }
-
- if (!nsf_init) {
- return CKR_OK;
- }
-
- crv = nsc_CommonFinalize (pReserved, PR_TRUE);
-
- nsf_init = (PRBool) !(crv == CKR_OK);
- return crv;
-}
-
-
-/* FC_GetInfo returns general information about PKCS #11. */
-CK_RV FC_GetInfo(CK_INFO_PTR pInfo) {
- CHECK_FORK();
-
- return NSC_GetInfo(pInfo);
-}
-
-/* FC_GetSlotList obtains a list of slots in the system. */
-CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
- CHECK_FORK();
-
- return nsc_CommonGetSlotList(tokenPresent,pSlotList,pulCount,
- NSC_FIPS_MODULE);
-}
-
-/* FC_GetSlotInfo obtains information about a particular slot in the system. */
-CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
- CHECK_FORK();
-
- return NSC_GetSlotInfo(slotID,pInfo);
-}
-
-
-/*FC_GetTokenInfo obtains information about a particular token in the system.*/
- CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) {
- CK_RV crv;
-
- CHECK_FORK();
-
- crv = NSC_GetTokenInfo(slotID,pInfo);
- if (crv == CKR_OK)
- pInfo->flags |= CKF_LOGIN_REQUIRED;
- return crv;
-
-}
-
-
-
-/*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/
- CK_RV FC_GetMechanismList(CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) {
- CHECK_FORK();
-
- SFTK_FIPSFATALCHECK();
- if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
- /* FIPS Slot supports all functions */
- return NSC_GetMechanismList(slotID,pMechanismList,pusCount);
-}
-
-
-/* FC_GetMechanismInfo obtains information about a particular mechanism
- * possibly supported by a token. */
- CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo) {
- CHECK_FORK();
-
- SFTK_FIPSFATALCHECK();
- if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
- /* FIPS Slot supports all functions */
- return NSC_GetMechanismInfo(slotID,type,pInfo);
-}
-
-
-/* FC_InitToken initializes a token. */
- CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
- CK_ULONG usPinLen,CK_CHAR_PTR pLabel) {
- CK_RV crv;
-
- CHECK_FORK();
-
- crv = NSC_InitToken(slotID,pPin,usPinLen,pLabel);
- if (sftk_audit_enabled) {
- char msg[128];
- NSSAuditSeverity severity = (crv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
- /* pLabel points to a 32-byte label, which is not null-terminated */
- PR_snprintf(msg,sizeof msg,
- "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX",
- (PRUint32)slotID,pLabel,(PRUint32)crv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_TOKEN, msg);
- }
- return crv;
-}
-
-
-/* FC_InitPIN initializes the normal user's PIN. */
- CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin, CK_ULONG ulPinLen) {
- CK_RV rv;
-
- CHECK_FORK();
-
- if (sftk_fatalError) return CKR_DEVICE_ERROR;
- if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) {
- rv = NSC_InitPIN(hSession,pPin,ulPinLen);
- }
- if (sftk_audit_enabled) {
- char msg[128];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
- PR_snprintf(msg,sizeof msg,
- "C_InitPIN(hSession=0x%08lX)=0x%08lX",
- (PRUint32)hSession,(PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_PIN, msg);
- }
- return rv;
-}
-
-
-/* FC_SetPIN modifies the PIN of user that is currently logged in. */
-/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
- CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
- CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) {
- CK_RV rv;
-
- CHECK_FORK();
-
- if ((rv = sftk_fipsCheck()) == CKR_OK &&
- (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) {
- rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen);
- }
- if (sftk_audit_enabled) {
- char msg[128];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
- PR_snprintf(msg,sizeof msg,
- "C_SetPIN(hSession=0x%08lX)=0x%08lX",
- (PRUint32)hSession,(PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_SET_PIN, msg);
- }
- return rv;
-}
-
-/* FC_OpenSession opens a session between an application and a token. */
- CK_RV FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
- CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession) {
- SFTK_FIPSFATALCHECK();
-
- CHECK_FORK();
-
- return NSC_OpenSession(slotID,flags,pApplication,Notify,phSession);
-}
-
-
-/* FC_CloseSession closes a session between an application and a token. */
- CK_RV FC_CloseSession(CK_SESSION_HANDLE hSession) {
- CHECK_FORK();
-
- return NSC_CloseSession(hSession);
-}
-
-
-/* FC_CloseAllSessions closes all sessions with a token. */
- CK_RV FC_CloseAllSessions (CK_SLOT_ID slotID) {
-
- CHECK_FORK();
-
- return NSC_CloseAllSessions (slotID);
-}
-
-
-/* FC_GetSessionInfo obtains information about the session. */
- CK_RV FC_GetSessionInfo(CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo) {
- CK_RV rv;
- SFTK_FIPSFATALCHECK();
-
- CHECK_FORK();
-
- rv = NSC_GetSessionInfo(hSession,pInfo);
- if (rv == CKR_OK) {
- if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) {
- pInfo->state = CKS_RO_USER_FUNCTIONS;
- }
- if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) {
- pInfo->state = CKS_RW_USER_FUNCTIONS;
- }
- }
- return rv;
-}
-
-/* FC_Login logs a user into a token. */
- CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
- CK_CHAR_PTR pPin, CK_ULONG usPinLen) {
- CK_RV rv;
- PRBool successful;
- if (sftk_fatalError) return CKR_DEVICE_ERROR;
- rv = NSC_Login(hSession,userType,pPin,usPinLen);
- successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN);
- if (successful)
- isLoggedIn = PR_TRUE;
- if (sftk_audit_enabled) {
- char msg[128];
- NSSAuditSeverity severity;
- severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
- PR_snprintf(msg,sizeof msg,
- "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX",
- (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_LOGIN, msg);
- }
- return rv;
-}
-
-/* FC_Logout logs a user out from a token. */
- CK_RV FC_Logout(CK_SESSION_HANDLE hSession) {
- CK_RV rv;
-
- CHECK_FORK();
-
- if ((rv = sftk_fipsCheck()) == CKR_OK) {
- rv = NSC_Logout(hSession);
- isLoggedIn = PR_FALSE;
- }
- if (sftk_audit_enabled) {
- char msg[128];
- NSSAuditSeverity severity = (rv == CKR_OK) ?
- NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
- PR_snprintf(msg,sizeof msg,
- "C_Logout(hSession=0x%08lX)=0x%08lX",
- (PRUint32)hSession,(PRUint32)rv);
- sftk_LogAuditMessage(severity, NSS_AUDIT_LOGOUT, msg);
- }
- return rv;
-}
-
-
-/* FC_CreateObject creates a new object. */
- CK_RV FC_CreateObject(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject) {
- CK_OBJECT_CLASS * classptr;
-
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate,ulCount,CKA_CLASS);
- if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE;
-
- /* FIPS can't create keys from raw key material */
- if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) {
- rv = CKR_ATTRIBUTE_VALUE_INVALID;
- } else {
- rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject);
- }
- if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) {
- sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv);
- }
- return rv;
-}
-
-
-
-
-
-/* FC_CopyObject copies an object, creating a new object for the copy. */
- CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject) {
- CK_RV rv;
- CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
-
- CHECK_FORK();
-
- SFTK_FIPSFATALCHECK();
- rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
- if (rv == CKR_OK) {
- rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject);
- }
- if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
- sftk_AuditCopyObject(hSession,
- hObject,pTemplate,ulCount,phNewObject,rv);
- }
- return rv;
-}
-
-
-/* FC_DestroyObject destroys an object. */
- CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject) {
- CK_RV rv;
- CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
-
- CHECK_FORK();
-
- SFTK_FIPSFATALCHECK();
- rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
- if (rv == CKR_OK) {
- rv = NSC_DestroyObject(hSession,hObject);
- }
- if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
- sftk_AuditDestroyObject(hSession,hObject,rv);
- }
- return rv;
-}
-
-
-/* FC_GetObjectSize gets the size of an object in bytes. */
- CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) {
- CK_RV rv;
- CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
-
- CHECK_FORK();
-
- SFTK_FIPSFATALCHECK();
- rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
- if (rv == CKR_OK) {
- rv = NSC_GetObjectSize(hSession, hObject, pulSize);
- }
- if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
- sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv);
- }
- return rv;
-}
-
-
-/* FC_GetAttributeValue obtains the value of one or more object attributes. */
- CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
- CK_RV rv;
- CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
-
- CHECK_FORK();
-
- SFTK_FIPSFATALCHECK();
- rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
- if (rv == CKR_OK) {
- rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount);
- }
- if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
- sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
- }
- return rv;
-}
-
-
-/* FC_SetAttributeValue modifies the value of one or more object attributes */
- CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) {
- CK_RV rv;
- CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY;
-
- CHECK_FORK();
-
- SFTK_FIPSFATALCHECK();
- rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass);
- if (rv == CKR_OK) {
- rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount);
- }
- if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) {
- sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv);
- }
- return rv;
-}
-
-
-
-/* FC_FindObjectsInit initializes a search for token and session objects
- * that match a template. */
- CK_RV FC_FindObjectsInit(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) {
- /* let publically readable object be found */
- unsigned int i;
- CK_RV rv;
- PRBool needLogin = PR_FALSE;
-
-
- CHECK_FORK();
-
- SFTK_FIPSFATALCHECK();
-
- for (i=0; i < usCount; i++) {
- CK_OBJECT_CLASS class;
- if (pTemplate[i].type != CKA_CLASS) {
- continue;
- }
- if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) {
- continue;
- }
- if (pTemplate[i].pValue == NULL) {
- continue;
- }
- class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
- if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) {
- needLogin = PR_TRUE;
- break;
- }
- }
- if (needLogin) {
- if ((rv = sftk_fipsCheck()) != CKR_OK) return rv;
- }
- return NSC_FindObjectsInit(hSession,pTemplate,usCount);
-}
-
-
-/* FC_FindObjects continues a search for token and session objects
- * that match a template, obtaining additional object handles. */
- CK_RV FC_FindObjects(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,CK_ULONG usMaxObjectCount,
- CK_ULONG_PTR pusObjectCount) {
- CHECK_FORK();
-
- /* let publically readable object be found */
- SFTK_FIPSFATALCHECK();
- return NSC_FindObjects(hSession,phObject,usMaxObjectCount,
- pusObjectCount);
-}
-
-
-/*
- ************** Crypto Functions: Encrypt ************************
- */
-
-/* FC_EncryptInit initializes an encryption operation. */
- CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- rv = NSC_EncryptInit(hSession,pMechanism,hKey);
- if (sftk_audit_enabled) {
- sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv);
- }
- return rv;
-}
-
-/* FC_Encrypt encrypts single-part data. */
- CK_RV FC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pusEncryptedDataLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_Encrypt(hSession,pData,usDataLen,pEncryptedData,
- pusEncryptedDataLen);
-}
-
-
-/* FC_EncryptUpdate continues a multiple-part encryption operation. */
- CK_RV FC_EncryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pusEncryptedPartLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_EncryptUpdate(hSession,pPart,usPartLen,pEncryptedPart,
- pusEncryptedPartLen);
-}
-
-
-/* FC_EncryptFinal finishes a multiple-part encryption operation. */
- CK_RV FC_EncryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_EncryptFinal(hSession,pLastEncryptedPart,
- pusLastEncryptedPartLen);
-}
-
-/*
- ************** Crypto Functions: Decrypt ************************
- */
-
-
-/* FC_DecryptInit initializes a decryption operation. */
- CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- rv = NSC_DecryptInit(hSession,pMechanism,hKey);
- if (sftk_audit_enabled) {
- sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv);
- }
- return rv;
-}
-
-/* FC_Decrypt decrypts encrypted data in a single part. */
- CK_RV FC_Decrypt(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,CK_ULONG usEncryptedDataLen,CK_BYTE_PTR pData,
- CK_ULONG_PTR pusDataLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_Decrypt(hSession,pEncryptedData,usEncryptedDataLen,pData,
- pusDataLen);
-}
-
-
-/* FC_DecryptUpdate continues a multiple-part decryption operation. */
- CK_RV FC_DecryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen,
- CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_DecryptUpdate(hSession,pEncryptedPart,usEncryptedPartLen,
- pPart,pusPartLen);
-}
-
-
-/* FC_DecryptFinal finishes a multiple-part decryption operation. */
- CK_RV FC_DecryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_DecryptFinal(hSession,pLastPart,pusLastPartLen);
-}
-
-
-/*
- ************** Crypto Functions: Digest (HASH) ************************
- */
-
-/* FC_DigestInit initializes a message-digesting operation. */
- CK_RV FC_DigestInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism) {
- SFTK_FIPSFATALCHECK();
- CHECK_FORK();
-
- return NSC_DigestInit(hSession, pMechanism);
-}
-
-
-/* FC_Digest digests data in a single part. */
- CK_RV FC_Digest(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pusDigestLen) {
- SFTK_FIPSFATALCHECK();
- CHECK_FORK();
-
- return NSC_Digest(hSession,pData,usDataLen,pDigest,pusDigestLen);
-}
-
-
-/* FC_DigestUpdate continues a multiple-part message-digesting operation. */
- CK_RV FC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG usPartLen) {
- SFTK_FIPSFATALCHECK();
- CHECK_FORK();
-
- return NSC_DigestUpdate(hSession,pPart,usPartLen);
-}
-
-
-/* FC_DigestFinal finishes a multiple-part message-digesting operation. */
- CK_RV FC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pusDigestLen) {
- SFTK_FIPSFATALCHECK();
- CHECK_FORK();
-
- return NSC_DigestFinal(hSession,pDigest,pusDigestLen);
-}
-
-
-/*
- ************** Crypto Functions: Sign ************************
- */
-
-/* FC_SignInit initializes a signature (private key encryption) operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_SignInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- rv = NSC_SignInit(hSession,pMechanism,hKey);
- if (sftk_audit_enabled) {
- sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv);
- }
- return rv;
-}
-
-
-/* FC_Sign signs (encrypts with private key) data in a single part,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_Sign(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,CK_ULONG usDataLen,CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pusSignatureLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_Sign(hSession,pData,usDataLen,pSignature,pusSignatureLen);
-}
-
-
-/* FC_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG usPartLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_SignUpdate(hSession,pPart,usPartLen);
-}
-
-
-/* FC_SignFinal finishes a multiple-part signature operation,
- * returning the signature. */
- CK_RV FC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pusSignatureLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_SignFinal(hSession,pSignature,pusSignatureLen);
-}
-
-/*
- ************** Crypto Functions: Sign Recover ************************
- */
-/* FC_SignRecoverInit initializes a signature operation,
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
- CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- rv = NSC_SignRecoverInit(hSession,pMechanism,hKey);
- if (sftk_audit_enabled) {
- sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv);
- }
- return rv;
-}
-
-
-/* FC_SignRecover signs data in a single operation
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
- CK_RV FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_SignRecover(hSession,pData,usDataLen,pSignature,pusSignatureLen);
-}
-
-/*
- ************** Crypto Functions: verify ************************
- */
-
-/* FC_VerifyInit initializes a verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature (e.g. DSA) */
- CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- rv = NSC_VerifyInit(hSession,pMechanism,hKey);
- if (sftk_audit_enabled) {
- sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv);
- }
- return rv;
-}
-
-
-/* FC_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) {
- /* make sure we're legal */
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_Verify(hSession,pData,usDataLen,pSignature,usSignatureLen);
-}
-
-
-/* FC_VerifyUpdate continues a multiple-part verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature */
- CK_RV FC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG usPartLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_VerifyUpdate(hSession,pPart,usPartLen);
-}
-
-
-/* FC_VerifyFinal finishes a multiple-part verification operation,
- * checking the signature. */
- CK_RV FC_VerifyFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_VerifyFinal(hSession,pSignature,usSignatureLen);
-}
-
-/*
- ************** Crypto Functions: Verify Recover ************************
- */
-
-/* FC_VerifyRecoverInit initializes a signature verification operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
- CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey);
- if (sftk_audit_enabled) {
- sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv);
- }
- return rv;
-}
-
-
-/* FC_VerifyRecover verifies a signature in a single-part operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
- CK_RV FC_VerifyRecover(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen,
- CK_BYTE_PTR pData,CK_ULONG_PTR pusDataLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_VerifyRecover(hSession,pSignature,usSignatureLen,pData,
- pusDataLen);
-}
-
-/*
- **************************** Key Functions: ************************
- */
-
-/* FC_GenerateKey generates a secret key, creating a new key object. */
- CK_RV FC_GenerateKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey) {
- CK_BBOOL *boolptr;
-
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- /* all secret keys must be sensitive, if the upper level code tries to say
- * otherwise, reject it. */
- boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE);
- if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
-
- rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey);
- if (sftk_audit_enabled) {
- sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv);
- }
- return rv;
-}
-
-
-/* FC_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
- CK_RV FC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey) {
- CK_BBOOL *boolptr;
- CK_RV crv;
-
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
-
- /* all private keys must be sensitive, if the upper level code tries to say
- * otherwise, reject it. */
- boolptr = (CK_BBOOL *) fc_getAttribute(pPrivateKeyTemplate,
- usPrivateKeyAttributeCount, CKA_SENSITIVE);
- if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
- crv = NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate,
- usPublicKeyAttributeCount,pPrivateKeyTemplate,
- usPrivateKeyAttributeCount,phPublicKey,phPrivateKey);
- if (crv == CKR_GENERAL_ERROR) {
- /* pairwise consistency check failed. */
- sftk_fatalError = PR_TRUE;
- }
- if (sftk_audit_enabled) {
- sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate,
- usPublicKeyAttributeCount,pPrivateKeyTemplate,
- usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv);
- }
- return crv;
-}
-
-
-/* FC_WrapKey wraps (i.e., encrypts) a key. */
- CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- rv = NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
- pulWrappedKeyLen);
- if (sftk_audit_enabled) {
- sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey,
- pulWrappedKeyLen,rv);
- }
- return rv;
-}
-
-
-/* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
- CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey) {
- CK_BBOOL *boolptr;
-
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- /* all secret keys must be sensitive, if the upper level code tries to say
- * otherwise, reject it. */
- boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
- ulAttributeCount, CKA_SENSITIVE);
- if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
- rv = NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
- ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey);
- if (sftk_audit_enabled) {
- sftk_AuditUnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey,
- ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey,rv);
- }
- return rv;
-}
-
-
-/* FC_DeriveKey derives a key from a base key, creating a new key object. */
- CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey) {
- CK_BBOOL *boolptr;
-
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- /* all secret keys must be sensitive, if the upper level code tries to say
- * otherwise, reject it. */
- boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate,
- ulAttributeCount, CKA_SENSITIVE);
- if (boolptr != NULL) {
- if (!(*boolptr)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
- rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
- ulAttributeCount, phKey);
- if (sftk_audit_enabled) {
- sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate,
- ulAttributeCount,phKey,rv);
- }
- return rv;
-}
-
-/*
- **************************** Radom Functions: ************************
- */
-
-/* FC_SeedRandom mixes additional seed material into the token's random number
- * generator. */
- CK_RV FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
- CK_ULONG usSeedLen) {
- CK_RV crv;
-
- SFTK_FIPSFATALCHECK();
- CHECK_FORK();
-
- crv = NSC_SeedRandom(hSession,pSeed,usSeedLen);
- if (crv != CKR_OK) {
- sftk_fatalError = PR_TRUE;
- }
- return crv;
-}
-
-
-/* FC_GenerateRandom generates random data. */
- CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) {
- CK_RV crv;
-
- CHECK_FORK();
-
- SFTK_FIPSFATALCHECK();
- crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen);
- if (crv != CKR_OK) {
- sftk_fatalError = PR_TRUE;
- if (sftk_audit_enabled) {
- char msg[128];
- PR_snprintf(msg,sizeof msg,
- "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, "
- "ulRandomLen=%lu)=0x%08lX "
- "self-test: continuous RNG test failed",
- (PRUint32)hSession,pRandomData,
- (PRUint32)ulRandomLen,(PRUint32)crv);
- sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
- }
- }
- return crv;
-}
-
-
-/* FC_GetFunctionStatus obtains an updated status of a function running
- * in parallel with an application. */
- CK_RV FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_GetFunctionStatus(hSession);
-}
-
-
-/* FC_CancelFunction cancels a function running in parallel */
- CK_RV FC_CancelFunction(CK_SESSION_HANDLE hSession) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_CancelFunction(hSession);
-}
-
-/*
- **************************** Version 1.1 Functions: ************************
- */
-
-/* FC_GetOperationState saves the state of the cryptographic
- *operation in a session. */
-CK_RV FC_GetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) {
- SFTK_FIPSFATALCHECK();
- CHECK_FORK();
-
- return NSC_GetOperationState(hSession,pOperationState,pulOperationStateLen);
-}
-
-
-/* FC_SetOperationState restores the state of the cryptographic operation
- * in a session. */
-CK_RV FC_SetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) {
- SFTK_FIPSFATALCHECK();
- CHECK_FORK();
-
- return NSC_SetOperationState(hSession,pOperationState,ulOperationStateLen,
- hEncryptionKey,hAuthenticationKey);
-}
-
-/* FC_FindObjectsFinal finishes a search for token and session objects. */
-CK_RV FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
- /* let publically readable object be found */
- SFTK_FIPSFATALCHECK();
- CHECK_FORK();
-
- return NSC_FindObjectsFinal(hSession);
-}
-
-
-/* Dual-function cryptographic operations */
-
-/* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption
- * operation. */
-CK_RV FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_DigestEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
- pulEncryptedPartLen);
-}
-
-
-/* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting
- * operation. */
-CK_RV FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_DecryptDigestUpdate(hSession, pEncryptedPart,ulEncryptedPartLen,
- pPart,pulPartLen);
-}
-
-/* FC_SignEncryptUpdate continues a multiple-part signing and encryption
- * operation. */
-CK_RV FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_SignEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart,
- pulEncryptedPartLen);
-}
-
-/* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify
- * operation. */
-CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- return NSC_DecryptVerifyUpdate(hSession,pEncryptedData,ulEncryptedDataLen,
- pData,pulDataLen);
-}
-
-
-/* FC_DigestKey continues a multi-part message-digesting operation,
- * by digesting the value of a secret key as part of the data already digested.
- */
-CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) {
- SFTK_FIPSCHECK();
- CHECK_FORK();
-
- rv = NSC_DigestKey(hSession,hKey);
- if (sftk_audit_enabled) {
- sftk_AuditDigestKey(hSession,hKey,rv);
- }
- return rv;
-}
-
-
-CK_RV FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pReserved)
-{
- CHECK_FORK();
-
- return NSC_WaitForSlotEvent(flags, pSlot, pReserved);
-}
diff --git a/security/nss/lib/softoken/jpakesftk.c b/security/nss/lib/softoken/jpakesftk.c
deleted file mode 100644
index 4f91c7283..000000000
--- a/security/nss/lib/softoken/jpakesftk.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "seccomon.h"
-#include "secerr.h"
-#include "blapi.h"
-#include "pkcs11i.h"
-#include "softoken.h"
-
-static CK_RV
-jpake_mapStatus(SECStatus rv, CK_RV invalidArgsMapping) {
- int err;
- if (rv == SECSuccess)
- return CKR_OK;
- err = PORT_GetError();
- switch (err) {
- /* XXX: SEC_ERROR_INVALID_ARGS might be caused by invalid template
- parameters. */
- case SEC_ERROR_INVALID_ARGS: return invalidArgsMapping;
- case SEC_ERROR_BAD_SIGNATURE: return CKR_SIGNATURE_INVALID;
- case SEC_ERROR_NO_MEMORY: return CKR_HOST_MEMORY;
- }
- return CKR_FUNCTION_FAILED;
-}
-
-/* If key is not NULL then the gx value will be stored as an attribute with
- the type given by the gxAttrType parameter. */
-static CK_RV
-jpake_Sign(PLArenaPool * arena, const PQGParams * pqg, HASH_HashType hashType,
- const SECItem * signerID, const SECItem * x,
- CK_NSS_JPAKEPublicValue * out)
-{
- SECItem gx, gv, r;
- CK_RV crv;
-
- PORT_Assert(arena != NULL);
-
- gx.data = NULL;
- gv.data = NULL;
- r.data = NULL;
- crv = jpake_mapStatus(JPAKE_Sign(arena, pqg, hashType, signerID, x, NULL,
- NULL, &gx, &gv, &r),
- CKR_MECHANISM_PARAM_INVALID);
- if (crv == CKR_OK) {
- if ((out->pGX != NULL && out->ulGXLen >= gx.len) ||
- (out->pGV != NULL && out->ulGVLen >= gv.len) ||
- (out->pR != NULL && out->ulRLen >= r.len)) {
- PORT_Memcpy(out->pGX, gx.data, gx.len);
- PORT_Memcpy(out->pGV, gv.data, gv.len);
- PORT_Memcpy(out->pR, r.data, r.len);
- out->ulGXLen = gx.len;
- out->ulGVLen = gv.len;
- out->ulRLen = r.len;
- } else {
- crv = CKR_MECHANISM_PARAM_INVALID;
- }
- }
- return crv;
-}
-
-static CK_RV
-jpake_Verify(PLArenaPool * arena, const PQGParams * pqg,
- HASH_HashType hashType, const SECItem * signerID,
- const CK_BYTE * peerIDData, CK_ULONG peerIDLen,
- const CK_NSS_JPAKEPublicValue * publicValueIn)
-{
- SECItem peerID, gx, gv, r;
- peerID.data = (unsigned char *) peerIDData; peerID.len = peerIDLen;
- gx.data = publicValueIn->pGX; gx.len = publicValueIn->ulGXLen;
- gv.data = publicValueIn->pGV; gv.len = publicValueIn->ulGVLen;
- r.data = publicValueIn->pR; r.len = publicValueIn->ulRLen;
- return jpake_mapStatus(JPAKE_Verify(arena, pqg, hashType, signerID, &peerID,
- &gx, &gv, &r),
- CKR_MECHANISM_PARAM_INVALID);
-}
-
-#define NUM_ELEM(x) (sizeof (x) / sizeof (x)[0])
-
-/* If the template has the key type set, ensure that it was set to the correct
- * value. If the template did not have the key type set, set it to the
- * correct value.
- */
-static CK_RV
-jpake_enforceKeyType(SFTKObject * key, CK_KEY_TYPE keyType) {
- CK_RV crv;
- SFTKAttribute * keyTypeAttr = sftk_FindAttribute(key, CKA_KEY_TYPE);
- if (keyTypeAttr != NULL) {
- crv = *(CK_KEY_TYPE *)keyTypeAttr->attrib.pValue == keyType
- ? CKR_OK
- : CKR_TEMPLATE_INCONSISTENT;
- sftk_FreeAttribute(keyTypeAttr);
- } else {
- crv = sftk_forceAttribute(key, CKA_KEY_TYPE, &keyType, sizeof keyType);
- }
- return crv;
-}
-
-static CK_RV
-jpake_MultipleSecItem2Attribute(SFTKObject * key, const SFTKItemTemplate * attrs,
- size_t attrsCount)
-{
- size_t i;
-
- for (i = 0; i < attrsCount; ++i) {
- CK_RV crv = sftk_forceAttribute(key, attrs[i].type, attrs[i].item->data,
- attrs[i].item->len);
- if (crv != CKR_OK)
- return crv;
- }
- return CKR_OK;
-}
-
-CK_RV
-jpake_Round1(HASH_HashType hashType, CK_NSS_JPAKERound1Params * params,
- SFTKObject * key)
-{
- CK_RV crv;
- PQGParams pqg;
- PLArenaPool * arena;
- SECItem signerID;
- SFTKItemTemplate templateAttrs[] = {
- { CKA_PRIME, &pqg.prime },
- { CKA_SUBPRIME, &pqg.subPrime },
- { CKA_BASE, &pqg.base },
- { CKA_NSS_JPAKE_SIGNERID, &signerID }
- };
- SECItem x2, gx1, gx2;
- const SFTKItemTemplate generatedAttrs[] = {
- { CKA_NSS_JPAKE_X2, &x2 },
- { CKA_NSS_JPAKE_GX1, &gx1 },
- { CKA_NSS_JPAKE_GX2, &gx2 },
- };
- SECItem x1;
-
- PORT_Assert(params != NULL);
- PORT_Assert(key != NULL);
-
- arena = PORT_NewArena(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- crv = CKR_HOST_MEMORY;
-
- crv = sftk_MultipleAttribute2SecItem(arena, key, templateAttrs,
- NUM_ELEM(templateAttrs));
-
- if (crv == CKR_OK && (signerID.data == NULL || signerID.len == 0))
- crv = CKR_TEMPLATE_INCOMPLETE;
-
- /* generate x1, g^x1 and the proof of knowledge of x1 */
- if (crv == CKR_OK) {
- x1.data = NULL;
- crv = jpake_mapStatus(DSA_NewRandom(arena, &pqg.subPrime, &x1),
- CKR_TEMPLATE_INCONSISTENT);
- }
- if (crv == CKR_OK)
- crv = jpake_Sign(arena, &pqg, hashType, &signerID, &x1, &params->gx1);
-
- /* generate x2, g^x2 and the proof of knowledge of x2 */
- if (crv == CKR_OK) {
- x2.data = NULL;
- crv = jpake_mapStatus(DSA_NewRandom(arena, &pqg.subPrime, &x2),
- CKR_TEMPLATE_INCONSISTENT);
- }
- if (crv == CKR_OK)
- crv = jpake_Sign(arena, &pqg, hashType, &signerID, &x2, &params->gx2);
-
- /* Save the values needed for round 2 into CKA_VALUE */
- if (crv == CKR_OK) {
- gx1.data = params->gx1.pGX;
- gx1.len = params->gx1.ulGXLen;
- gx2.data = params->gx2.pGX;
- gx2.len = params->gx2.ulGXLen;
- crv = jpake_MultipleSecItem2Attribute(key, generatedAttrs,
- NUM_ELEM(generatedAttrs));
- }
-
- PORT_FreeArena(arena, PR_TRUE);
- return crv;
-}
-
-CK_RV
-jpake_Round2(HASH_HashType hashType, CK_NSS_JPAKERound2Params * params,
- SFTKObject * sourceKey, SFTKObject * key)
-{
- CK_RV crv;
- PLArenaPool * arena;
- PQGParams pqg;
- SECItem signerID, x2, gx1, gx2;
- SFTKItemTemplate sourceAttrs[] = {
- { CKA_PRIME, &pqg.prime },
- { CKA_SUBPRIME, &pqg.subPrime },
- { CKA_BASE, &pqg.base },
- { CKA_NSS_JPAKE_SIGNERID, &signerID },
- { CKA_NSS_JPAKE_X2, &x2 },
- { CKA_NSS_JPAKE_GX1, &gx1 },
- { CKA_NSS_JPAKE_GX2, &gx2 },
- };
- SECItem x2s, gx3, gx4;
- const SFTKItemTemplate copiedAndGeneratedAttrs[] = {
- { CKA_NSS_JPAKE_SIGNERID, &signerID },
- { CKA_PRIME, &pqg.prime },
- { CKA_SUBPRIME, &pqg.subPrime },
- { CKA_NSS_JPAKE_X2, &x2 },
- { CKA_NSS_JPAKE_X2S, &x2s },
- { CKA_NSS_JPAKE_GX1, &gx1 },
- { CKA_NSS_JPAKE_GX2, &gx2 },
- { CKA_NSS_JPAKE_GX3, &gx3 },
- { CKA_NSS_JPAKE_GX4, &gx4 }
- };
- SECItem peerID;
-
- PORT_Assert(params != NULL);
- PORT_Assert(sourceKey != NULL);
- PORT_Assert(key != NULL);
-
- arena = PORT_NewArena(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- crv = CKR_HOST_MEMORY;
-
- /* TODO: check CKK_NSS_JPAKE_ROUND1 */
-
- crv = sftk_MultipleAttribute2SecItem(arena, sourceKey, sourceAttrs,
- NUM_ELEM(sourceAttrs));
-
- /* Get the peer's ID out of the template and sanity-check it. */
- if (crv == CKR_OK)
- crv = sftk_Attribute2SecItem(arena, &peerID, key,
- CKA_NSS_JPAKE_PEERID);
- if (crv == CKR_OK && (peerID.data == NULL || peerID.len == 0))
- crv = CKR_TEMPLATE_INCOMPLETE;
- if (crv == CKR_OK && SECITEM_CompareItem(&signerID, &peerID) == SECEqual)
- crv = CKR_TEMPLATE_INCONSISTENT;
-
- /* Verify zero-knowledge proofs for g^x3 and g^x4 */
- if (crv == CKR_OK)
- crv = jpake_Verify(arena, &pqg, hashType, &signerID,
- peerID.data, peerID.len, &params->gx3);
- if (crv == CKR_OK)
- crv = jpake_Verify(arena, &pqg, hashType, &signerID,
- peerID.data, peerID.len, &params->gx4);
-
- /* Calculate the base and x2s for A=base^x2s */
- if (crv == CKR_OK) {
- SECItem s;
- s.data = params->pSharedKey;
- s.len = params->ulSharedKeyLen;
- gx3.data = params->gx3.pGX;
- gx3.len = params->gx3.ulGXLen;
- gx4.data = params->gx4.pGX;
- gx4.len = params->gx4.ulGXLen;
- pqg.base.data = NULL;
- x2s.data = NULL;
- crv = jpake_mapStatus(JPAKE_Round2(arena, &pqg.prime, &pqg.subPrime,
- &gx1, &gx3, &gx4, &pqg.base,
- &x2, &s, &x2s),
- CKR_MECHANISM_PARAM_INVALID);
- }
-
- /* Generate A=base^x2s and its zero-knowledge proof. */
- if (crv == CKR_OK)
- crv = jpake_Sign(arena, &pqg, hashType, &signerID, &x2s, &params->A);
-
- /* Copy P and Q from the ROUND1 key to the ROUND2 key and save the values
- needed for the final key material derivation into CKA_VALUE. */
- if (crv == CKR_OK)
- crv = sftk_forceAttribute(key, CKA_PRIME, pqg.prime.data,
- pqg.prime.len);
- if (crv == CKR_OK)
- crv = sftk_forceAttribute(key, CKA_SUBPRIME, pqg.subPrime.data,
- pqg.subPrime.len);
- if (crv == CKR_OK) {
- crv = jpake_MultipleSecItem2Attribute(key, copiedAndGeneratedAttrs,
- NUM_ELEM(copiedAndGeneratedAttrs));
- }
-
- if (crv == CKR_OK)
- crv = jpake_enforceKeyType(key, CKK_NSS_JPAKE_ROUND2);
-
- PORT_FreeArena(arena, PR_TRUE);
- return crv;
-}
-
-CK_RV
-jpake_Final(HASH_HashType hashType, const CK_NSS_JPAKEFinalParams * param,
- SFTKObject * sourceKey, SFTKObject * key)
-{
- PLArenaPool * arena;
- SECItem K;
- PQGParams pqg;
- CK_RV crv;
- SECItem peerID, signerID, x2s, x2, gx1, gx2, gx3, gx4;
- SFTKItemTemplate sourceAttrs[] = {
- { CKA_NSS_JPAKE_PEERID, &peerID },
- { CKA_NSS_JPAKE_SIGNERID, &signerID },
- { CKA_PRIME, &pqg.prime },
- { CKA_SUBPRIME, &pqg.subPrime },
- { CKA_NSS_JPAKE_X2, &x2 },
- { CKA_NSS_JPAKE_X2S, &x2s },
- { CKA_NSS_JPAKE_GX1, &gx1 },
- { CKA_NSS_JPAKE_GX2, &gx2 },
- { CKA_NSS_JPAKE_GX3, &gx3 },
- { CKA_NSS_JPAKE_GX4, &gx4 }
- };
-
- PORT_Assert(param != NULL);
- PORT_Assert(sourceKey != NULL);
- PORT_Assert(key != NULL);
-
- arena = PORT_NewArena(NSS_SOFTOKEN_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- crv = CKR_HOST_MEMORY;
-
- /* TODO: verify key type CKK_NSS_JPAKE_ROUND2 */
-
- crv = sftk_MultipleAttribute2SecItem(arena, sourceKey, sourceAttrs,
- NUM_ELEM(sourceAttrs));
-
- /* Calculate base for B=base^x4s */
- if (crv == CKR_OK) {
- pqg.base.data = NULL;
- crv = jpake_mapStatus(JPAKE_Round2(arena, &pqg.prime, &pqg.subPrime,
- &gx1, &gx2, &gx3, &pqg.base,
- NULL, NULL, NULL),
- CKR_MECHANISM_PARAM_INVALID);
- }
-
- /* Verify zero-knowledge proof for B */
- if (crv == CKR_OK)
- crv = jpake_Verify(arena, &pqg, hashType, &signerID,
- peerID.data, peerID.len, &param->B);
- if (crv == CKR_OK) {
- SECItem B;
- B.data = param->B.pGX;
- B.len = param->B.ulGXLen;
- K.data = NULL;
- crv = jpake_mapStatus(JPAKE_Final(arena, &pqg.prime, &pqg.subPrime,
- &x2, &gx4, &x2s, &B, &K),
- CKR_MECHANISM_PARAM_INVALID);
- }
-
- /* Save key material into CKA_VALUE. */
- if (crv == CKR_OK)
- crv = sftk_forceAttribute(key, CKA_VALUE, K.data, K.len);
-
- if (crv == CKR_OK)
- crv = jpake_enforceKeyType(key, CKK_GENERIC_SECRET);
-
- PORT_FreeArena(arena, PR_TRUE);
- return crv;
-}
diff --git a/security/nss/lib/softoken/legacydb/Makefile b/security/nss/lib/softoken/legacydb/Makefile
deleted file mode 100644
index 616c65fbd..000000000
--- a/security/nss/lib/softoken/legacydb/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
-# indicates dependency on freebl static lib
-$(SHARED_LIBRARY): $(CRYPTOLIB)
diff --git a/security/nss/lib/softoken/legacydb/cdbhdl.h b/security/nss/lib/softoken/legacydb/cdbhdl.h
deleted file mode 100644
index 659887ff6..000000000
--- a/security/nss/lib/softoken/legacydb/cdbhdl.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * cdbhdl.h - certificate database handle
- * private to the certdb module
- *
- * $Id$
- */
-#ifndef _CDBHDL_H_
-#define _CDBHDL_H_
-
-#include "nspr.h"
-#include "mcom_db.h"
-#include "pcertt.h"
-#include "prtypes.h"
-
-/*
- * Handle structure for open certificate databases
- */
-struct NSSLOWCERTCertDBHandleStr {
- DB *permCertDB;
- PZMonitor *dbMon;
- PRBool dbVerify;
- PRInt32 ref; /* reference count */
-};
-
-#ifdef DBM_USING_NSPR
-#define NO_RDONLY PR_RDONLY
-#define NO_RDWR PR_RDWR
-#define NO_CREATE (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE)
-#else
-#define NO_RDONLY O_RDONLY
-#define NO_RDWR O_RDWR
-#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC)
-#endif
-
-typedef DB * (*rdbfunc)(const char *appName, const char *prefix,
- const char *type, int flags);
-typedef int (*rdbstatusfunc)(void);
-
-#define RDB_FAIL 1
-#define RDB_RETRY 2
-
-DB * rdbopen(const char *appName, const char *prefix,
- const char *type, int flags, int *status);
-
-DB *dbsopen (const char *dbname , int flags, int mode, DBTYPE type,
- const void * appData);
-SECStatus db_Copy(DB *dest,DB *src);
-int db_InitComplete(DB *db);
-
-#endif
diff --git a/security/nss/lib/softoken/legacydb/config.mk b/security/nss/lib/softoken/legacydb/config.mk
deleted file mode 100644
index 4835ae2ed..000000000
--- a/security/nss/lib/softoken/legacydb/config.mk
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
-CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX)
-
-EXTRA_LIBS += \
- $(CRYPTOLIB) \
- $(DIST)/lib/$(LIB_PREFIX)dbm.$(LIB_SUFFIX) \
- $(NULL)
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
-
-RES = $(OBJDIR)/$(LIBRARY_NAME).res
-RESNAME = $(LIBRARY_NAME).rc
-
-ifdef NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-else # ! NS_USE_GCC
-
-EXTRA_SHARED_LIBS += \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(DIST)/lib/nssutil3.lib \
- $(NULL)
-endif # NS_USE_GCC
-
-else
-
-# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
-# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-endif
-
-ifeq ($(OS_TARGET),SunOS)
-OS_LIBS += -lbsm
-endif
diff --git a/security/nss/lib/softoken/legacydb/dbmshim.c b/security/nss/lib/softoken/legacydb/dbmshim.c
deleted file mode 100644
index 6d2cdd32a..000000000
--- a/security/nss/lib/softoken/legacydb/dbmshim.c
+++ /dev/null
@@ -1,615 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Berkeley DB 1.85 Shim code to handle blobs.
- *
- * $Id$
- */
-#include "mcom_db.h"
-#include "secitem.h"
-#include "nssb64.h"
-#include "blapi.h"
-#include "secerr.h"
-
-#include "lgdb.h"
-
-/*
- * Blob block:
- * Byte 0 CERTDB Version -+ -+
- * Byte 1 certDBEntryTypeBlob | BLOB_HEAD_LEN |
- * Byte 2 flags (always '0'); | |
- * Byte 3 reserved (always '0'); -+ |
- * Byte 4 LSB length | <--BLOB_LENGTH_START | BLOB_BUF_LEN
- * Byte 5 . | |
- * Byte 6 . | BLOB_LENGTH_LEN |
- * Byte 7 MSB length | |
- * Byte 8 blob_filename -+ -+ <-- BLOB_NAME_START |
- * Byte 9 . | BLOB_NAME_LEN |
- * . . | |
- * Byte 37 . -+ -+
- */
-#define DBS_BLOCK_SIZE (16*1024) /* 16 k */
-#define DBS_MAX_ENTRY_SIZE (DBS_BLOCK_SIZE - (2048)) /* 14 k */
-#define DBS_CACHE_SIZE DBS_BLOCK_SIZE*8
-#define ROUNDDIV(x,y) (x+(y-1))/y
-#define BLOB_HEAD_LEN 4
-#define BLOB_LENGTH_START BLOB_HEAD_LEN
-#define BLOB_LENGTH_LEN 4
-#define BLOB_NAME_START BLOB_LENGTH_START+BLOB_LENGTH_LEN
-#define BLOB_NAME_LEN 1+ROUNDDIV(SHA1_LENGTH,3)*4+1
-#define BLOB_BUF_LEN BLOB_HEAD_LEN+BLOB_LENGTH_LEN+BLOB_NAME_LEN
-
-/* a Shim data structure. This data structure has a db built into it. */
-typedef struct DBSStr DBS;
-
-struct DBSStr {
- DB db;
- char *blobdir;
- int mode;
- PRBool readOnly;
- PRFileMap *dbs_mapfile;
- unsigned char *dbs_addr;
- PRUint32 dbs_len;
- char staticBlobArea[BLOB_BUF_LEN];
-};
-
-
-
-/*
- * return true if the Datablock contains a blobtype
- */
-static PRBool
-dbs_IsBlob(DBT *blobData)
-{
- unsigned char *addr = (unsigned char *)blobData->data;
- if (blobData->size < BLOB_BUF_LEN) {
- return PR_FALSE;
- }
- return addr && ((certDBEntryType) addr[1] == certDBEntryTypeBlob);
-}
-
-/*
- * extract the filename in the blob of the real data set.
- * This value is not malloced (does not need to be freed by the caller.
- */
-static const char *
-dbs_getBlobFileName(DBT *blobData)
-{
- char *addr = (char *)blobData->data;
-
- return &addr[BLOB_NAME_START];
-}
-
-/*
- * extract the size of the actual blob from the blob record
- */
-static PRUint32
-dbs_getBlobSize(DBT *blobData)
-{
- unsigned char *addr = (unsigned char *)blobData->data;
-
- return (PRUint32)(addr[BLOB_LENGTH_START+3] << 24) |
- (addr[BLOB_LENGTH_START+2] << 16) |
- (addr[BLOB_LENGTH_START+1] << 8) |
- addr[BLOB_LENGTH_START];
-}
-
-
-/* We are using base64 data for the filename, but base64 data can include a
- * '/' which is interpreted as a path separator on many platforms. Replace it
- * with an inocuous '-'. We don't need to convert back because we never actual
- * decode the filename.
- */
-
-static void
-dbs_replaceSlash(char *cp, int len)
-{
- while (len--) {
- if (*cp == '/') *cp = '-';
- cp++;
- }
-}
-
-/*
- * create a blob record from a key, data and return it in blobData.
- * NOTE: The data element is static data (keeping with the dbm model).
- */
-static void
-dbs_mkBlob(DBS *dbsp,const DBT *key, const DBT *data, DBT *blobData)
-{
- unsigned char sha1_data[SHA1_LENGTH];
- char *b = dbsp->staticBlobArea;
- PRUint32 length = data->size;
- SECItem sha1Item;
-
- b[0] = CERT_DB_FILE_VERSION; /* certdb version number */
- b[1] = (char) certDBEntryTypeBlob; /* type */
- b[2] = 0; /* flags */
- b[3] = 0; /* reserved */
- b[BLOB_LENGTH_START] = length & 0xff;
- b[BLOB_LENGTH_START+1] = (length >> 8) & 0xff;
- b[BLOB_LENGTH_START+2] = (length >> 16) & 0xff;
- b[BLOB_LENGTH_START+3] = (length >> 24) & 0xff;
- sha1Item.data = sha1_data;
- sha1Item.len = SHA1_LENGTH;
- SHA1_HashBuf(sha1_data,key->data,key->size);
- b[BLOB_NAME_START]='b'; /* Make sure we start with a alpha */
- NSSBase64_EncodeItem(NULL,&b[BLOB_NAME_START+1],BLOB_NAME_LEN-1,&sha1Item);
- b[BLOB_BUF_LEN-1] = 0;
- dbs_replaceSlash(&b[BLOB_NAME_START+1],BLOB_NAME_LEN-1);
- blobData->data = b;
- blobData->size = BLOB_BUF_LEN;
- return;
-}
-
-
-/*
- * construct a path to the actual blob. The string returned must be
- * freed by the caller with PR_smprintf_free.
- *
- * Note: this file does lots of consistancy checks on the DBT. The
- * routines that call this depend on these checks, so they don't worry
- * about them (success of this routine implies a good blobdata record).
- */
-static char *
-dbs_getBlobFilePath(char *blobdir,DBT *blobData)
-{
- const char *name;
-
- if (blobdir == NULL) {
- PR_SetError(SEC_ERROR_BAD_DATABASE,0);
- return NULL;
- }
- if (!dbs_IsBlob(blobData)) {
- PR_SetError(SEC_ERROR_BAD_DATABASE,0);
- return NULL;
- }
- name = dbs_getBlobFileName(blobData);
- if (!name || *name == 0) {
- PR_SetError(SEC_ERROR_BAD_DATABASE,0);
- return NULL;
- }
- return PR_smprintf("%s" PATH_SEPARATOR "%s", blobdir, name);
-}
-
-/*
- * Delete a blob file pointed to by the blob record.
- */
-static void
-dbs_removeBlob(DBS *dbsp, DBT *blobData)
-{
- char *file;
-
- file = dbs_getBlobFilePath(dbsp->blobdir, blobData);
- if (!file) {
- return;
- }
- PR_Delete(file);
- PR_smprintf_free(file);
-}
-
-/*
- * Directory modes are slightly different, the 'x' bit needs to be on to
- * access them. Copy all the read bits to 'x' bits
- */
-static int
-dbs_DirMode(int mode)
-{
- int x_bits = (mode >> 2) & 0111;
- return mode | x_bits;
-}
-
-/*
- * write a data blob to it's file. blobdData is the blob record that will be
- * stored in the database. data is the actual data to go out on disk.
- */
-static int
-dbs_writeBlob(DBS *dbsp, int mode, DBT *blobData, const DBT *data)
-{
- char *file = NULL;
- PRFileDesc *filed;
- PRStatus status;
- int len;
- int error = 0;
-
- file = dbs_getBlobFilePath(dbsp->blobdir, blobData);
- if (!file) {
- goto loser;
- }
- if (PR_Access(dbsp->blobdir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
- status = PR_MkDir(dbsp->blobdir,dbs_DirMode(mode));
- if (status != PR_SUCCESS) {
- goto loser;
- }
- }
- filed = PR_OpenFile(file,PR_CREATE_FILE|PR_TRUNCATE|PR_WRONLY, mode);
- if (filed == NULL) {
- error = PR_GetError();
- goto loser;
- }
- len = PR_Write(filed,data->data,data->size);
- error = PR_GetError();
- PR_Close(filed);
- if (len < (int)data->size) {
- goto loser;
- }
- PR_smprintf_free(file);
- return 0;
-
-loser:
- if (file) {
- PR_Delete(file);
- PR_smprintf_free(file);
- }
- /* don't let close or delete reset the error */
- PR_SetError(error,0);
- return -1;
-}
-
-
-/*
- * we need to keep a address map in memory between calls to DBM.
- * remember what we have mapped can close it when we get another dbm
- * call.
- *
- * NOTE: Not all platforms support mapped files. This code is designed to
- * detect this at runtime. If map files aren't supported the OS will indicate
- * this by failing the PR_Memmap call. In this case we emulate mapped files
- * by just reading in the file into regular memory. We signal this state by
- * making dbs_mapfile NULL and dbs_addr non-NULL.
- */
-
-static void
-dbs_freemap(DBS *dbsp)
-{
- if (dbsp->dbs_mapfile) {
- PR_MemUnmap(dbsp->dbs_addr,dbsp->dbs_len);
- PR_CloseFileMap(dbsp->dbs_mapfile);
- dbsp->dbs_mapfile = NULL;
- dbsp->dbs_addr = NULL;
- dbsp->dbs_len = 0;
- } else if (dbsp->dbs_addr) {
- PORT_Free(dbsp->dbs_addr);
- dbsp->dbs_addr = NULL;
- dbsp->dbs_len = 0;
- }
- return;
-}
-
-static void
-dbs_setmap(DBS *dbsp, PRFileMap *mapfile, unsigned char *addr, PRUint32 len)
-{
- dbsp->dbs_mapfile = mapfile;
- dbsp->dbs_addr = addr;
- dbsp->dbs_len = len;
-}
-
-/*
- * platforms that cannot map the file need to read it into a temp buffer.
- */
-static unsigned char *
-dbs_EmulateMap(PRFileDesc *filed, int len)
-{
- unsigned char *addr;
- PRInt32 dataRead;
-
- addr = PORT_Alloc(len);
- if (addr == NULL) {
- return NULL;
- }
-
- dataRead = PR_Read(filed,addr,len);
- if (dataRead != len) {
- PORT_Free(addr);
- if (dataRead > 0) {
- /* PR_Read didn't set an error, we need to */
- PR_SetError(SEC_ERROR_BAD_DATABASE,0);
- }
- return NULL;
- }
-
- return addr;
-}
-
-
-/*
- * pull a database record off the disk
- * data points to the blob record on input and the real record (if we could
- * read it) on output. if there is an error data is not modified.
- */
-static int
-dbs_readBlob(DBS *dbsp, DBT *data)
-{
- char *file = NULL;
- PRFileDesc *filed = NULL;
- PRFileMap *mapfile = NULL;
- unsigned char *addr = NULL;
- int error;
- int len = -1;
-
- file = dbs_getBlobFilePath(dbsp->blobdir, data);
- if (!file) {
- goto loser;
- }
- filed = PR_OpenFile(file,PR_RDONLY,0);
- PR_smprintf_free(file); file = NULL;
- if (filed == NULL) {
- goto loser;
- }
-
- len = dbs_getBlobSize(data);
- mapfile = PR_CreateFileMap(filed, len, PR_PROT_READONLY);
- if (mapfile == NULL) {
- /* USE PR_GetError instead of PORT_GetError here
- * because we are getting the error from PR_xxx
- * function */
- if (PR_GetError() != PR_NOT_IMPLEMENTED_ERROR) {
- goto loser;
- }
- addr = dbs_EmulateMap(filed, len);
- } else {
- addr = PR_MemMap(mapfile, 0, len);
- }
- if (addr == NULL) {
- goto loser;
- }
- PR_Close(filed);
- dbs_setmap(dbsp,mapfile,addr,len);
-
- data->data = addr;
- data->size = len;
- return 0;
-
-loser:
- /* preserve the error code */
- error = PR_GetError();
- if (mapfile) {
- PR_CloseFileMap(mapfile);
- }
- if (filed) {
- PR_Close(filed);
- }
- PR_SetError(error,0);
- return -1;
-}
-
-/*
- * actual DBM shims
- */
-static int
-dbs_get(const DB *dbs, const DBT *key, DBT *data, unsigned int flags)
-{
- int ret;
- DBS *dbsp = (DBS *)dbs;
- DB *db = (DB *)dbs->internal;
-
-
- dbs_freemap(dbsp);
-
- ret = (* db->get)(db, key, data, flags);
- if ((ret == 0) && dbs_IsBlob(data)) {
- ret = dbs_readBlob(dbsp,data);
- }
-
- return(ret);
-}
-
-static int
-dbs_put(const DB *dbs, DBT *key, const DBT *data, unsigned int flags)
-{
- DBT blob;
- int ret = 0;
- DBS *dbsp = (DBS *)dbs;
- DB *db = (DB *)dbs->internal;
-
- dbs_freemap(dbsp);
-
- /* If the db is readonly, just pass the data down to rdb and let it fail */
- if (!dbsp->readOnly) {
- DBT oldData;
- int ret1;
-
- /* make sure the current record is deleted if it's a blob */
- ret1 = (*db->get)(db,key,&oldData,0);
- if ((ret1 == 0) && flags == R_NOOVERWRITE) {
- /* let DBM return the error to maintain consistancy */
- return (* db->put)(db, key, data, flags);
- }
- if ((ret1 == 0) && dbs_IsBlob(&oldData)) {
- dbs_removeBlob(dbsp, &oldData);
- }
-
- if (data->size > DBS_MAX_ENTRY_SIZE) {
- dbs_mkBlob(dbsp,key,data,&blob);
- ret = dbs_writeBlob(dbsp, dbsp->mode, &blob, data);
- data = &blob;
- }
- }
-
- if (ret == 0) {
- ret = (* db->put)(db, key, data, flags);
- }
- return(ret);
-}
-
-static int
-dbs_sync(const DB *dbs, unsigned int flags)
-{
- DB *db = (DB *)dbs->internal;
- DBS *dbsp = (DBS *)dbs;
-
- dbs_freemap(dbsp);
-
- return (* db->sync)(db, flags);
-}
-
-static int
-dbs_del(const DB *dbs, const DBT *key, unsigned int flags)
-{
- int ret;
- DBS *dbsp = (DBS *)dbs;
- DB *db = (DB *)dbs->internal;
-
- dbs_freemap(dbsp);
-
- if (!dbsp->readOnly) {
- DBT oldData;
- ret = (*db->get)(db,key,&oldData,0);
- if ((ret == 0) && dbs_IsBlob(&oldData)) {
- dbs_removeBlob(dbsp,&oldData);
- }
- }
-
- return (* db->del)(db, key, flags);
-}
-
-static int
-dbs_seq(const DB *dbs, DBT *key, DBT *data, unsigned int flags)
-{
- int ret;
- DBS *dbsp = (DBS *)dbs;
- DB *db = (DB *)dbs->internal;
-
- dbs_freemap(dbsp);
-
- ret = (* db->seq)(db, key, data, flags);
- if ((ret == 0) && dbs_IsBlob(data)) {
- /* don't return a blob read as an error so traversals keep going */
- (void) dbs_readBlob(dbsp,data);
- }
-
- return(ret);
-}
-
-static int
-dbs_close(DB *dbs)
-{
- DBS *dbsp = (DBS *)dbs;
- DB *db = (DB *)dbs->internal;
- int ret;
-
- dbs_freemap(dbsp);
- ret = (* db->close)(db);
- PORT_Free(dbsp->blobdir);
- PORT_Free(dbsp);
- return ret;
-}
-
-static int
-dbs_fd(const DB *dbs)
-{
- DB *db = (DB *)dbs->internal;
-
- return (* db->fd)(db);
-}
-
-/*
- * the naming convention we use is
- * change the .xxx into .dir. (for nss it's always .db);
- * if no .extension exists or is equal to .dir, add a .dir
- * the returned data must be freed.
- */
-#define DIRSUFFIX ".dir"
-static char *
-dbs_mkBlobDirName(const char *dbname)
-{
- int dbname_len = PORT_Strlen(dbname);
- int dbname_end = dbname_len;
- const char *cp;
- char *blobDir = NULL;
-
- /* scan back from the end looking for either a directory separator, a '.',
- * or the end of the string. NOTE: Windows should check for both separators
- * here. For now this is safe because we know NSS always uses a '.'
- */
- for (cp = &dbname[dbname_len];
- (cp > dbname) && (*cp != '.') && (*cp != *PATH_SEPARATOR) ;
- cp--)
- /* Empty */ ;
- if (*cp == '.') {
- dbname_end = cp - dbname;
- if (PORT_Strcmp(cp,DIRSUFFIX) == 0) {
- dbname_end = dbname_len;
- }
- }
- blobDir = PORT_ZAlloc(dbname_end+sizeof(DIRSUFFIX));
- if (blobDir == NULL) {
- return NULL;
- }
- PORT_Memcpy(blobDir,dbname,dbname_end);
- PORT_Memcpy(&blobDir[dbname_end],DIRSUFFIX,sizeof(DIRSUFFIX));
- return blobDir;
-}
-
-#define DBM_DEFAULT 0
-static const HASHINFO dbs_hashInfo = {
- DBS_BLOCK_SIZE, /* bucket size, must be greater than = to
- * or maximum entry size (+ header)
- * we allow before blobing */
- DBM_DEFAULT, /* Fill Factor */
- DBM_DEFAULT, /* number of elements */
- DBS_CACHE_SIZE, /* cache size */
- DBM_DEFAULT, /* hash function */
- DBM_DEFAULT, /* byte order */
-};
-
-/*
- * the open function. NOTE: this is the only exposed function in this file.
- * everything else is called through the function table pointer.
- */
-DB *
-dbsopen(const char *dbname, int flags, int mode, DBTYPE type,
- const void *userData)
-{
- DB *db = NULL,*dbs = NULL;
- DBS *dbsp = NULL;
-
- /* NOTE: we are overriding userData with dbs_hashInfo. since all known
- * callers pass 0, this is ok, otherwise we should merge the two */
-
- dbsp = (DBS *)PORT_ZAlloc(sizeof(DBS));
- if (!dbsp) {
- return NULL;
- }
- dbs = &dbsp->db;
-
- dbsp->blobdir=dbs_mkBlobDirName(dbname);
- if (dbsp->blobdir == NULL) {
- goto loser;
- }
- dbsp->mode = mode;
- dbsp->readOnly = (PRBool)(flags == NO_RDONLY);
- dbsp->dbs_mapfile = NULL;
- dbsp->dbs_addr = NULL;
- dbsp->dbs_len = 0;
-
- /* the real dbm call */
- db = dbopen(dbname, flags, mode, type, &dbs_hashInfo);
- if (db == NULL) {
- goto loser;
- }
- dbs->internal = (void *) db;
- dbs->type = type;
- dbs->close = dbs_close;
- dbs->get = dbs_get;
- dbs->del = dbs_del;
- dbs->put = dbs_put;
- dbs->seq = dbs_seq;
- dbs->sync = dbs_sync;
- dbs->fd = dbs_fd;
-
- return dbs;
-loser:
- if (db) {
- (*db->close)(db);
- }
- if (dbsp) {
- if (dbsp->blobdir) {
- PORT_Free(dbsp->blobdir);
- }
- PORT_Free(dbsp);
- }
- return NULL;
-}
diff --git a/security/nss/lib/softoken/legacydb/keydb.c b/security/nss/lib/softoken/legacydb/keydb.c
deleted file mode 100644
index 9b3bc0514..000000000
--- a/security/nss/lib/softoken/legacydb/keydb.c
+++ /dev/null
@@ -1,2268 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "lowkeyi.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "secoid.h"
-#include "blapi.h"
-#include "secitem.h"
-#include "pcert.h"
-#include "mcom_db.h"
-#include "secerr.h"
-
-#include "keydbi.h"
-#include "lgdb.h"
-
-/*
- * Record keys for keydb
- */
-#define SALT_STRING "global-salt"
-#define VERSION_STRING "Version"
-#define KEYDB_PW_CHECK_STRING "password-check"
-#define KEYDB_PW_CHECK_LEN 14
-#define KEYDB_FAKE_PW_CHECK_STRING "fake-password-check"
-#define KEYDB_FAKE_PW_CHECK_LEN 19
-
-/* Size of the global salt for key database */
-#define SALT_LENGTH 16
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYEncryptedPrivateKeyInfo) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSLOWKEYEncryptedPrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSLOWKEYEncryptedPrivateKeyInfo,encryptedData) },
- { 0 }
-};
-
-const SEC_ASN1Template nsslowkey_PointerToEncryptedPrivateKeyInfoTemplate[] = {
- { SEC_ASN1_POINTER, 0, nsslowkey_EncryptedPrivateKeyInfoTemplate }
-};
-
-
-/* ====== Default key databse encryption algorithm ====== */
-static void
-sec_destroy_dbkey(NSSLOWKEYDBKey *dbkey)
-{
- if ( dbkey && dbkey->arena ) {
- PORT_FreeArena(dbkey->arena, PR_FALSE);
- }
-}
-
-static void
-free_dbt(DBT *dbt)
-{
- if ( dbt ) {
- PORT_Free(dbt->data);
- PORT_Free(dbt);
- }
-
- return;
-}
-
-static int keydb_Get(NSSLOWKEYDBHandle *db, DBT *key, DBT *data,
- unsigned int flags);
-static int keydb_Put(NSSLOWKEYDBHandle *db, DBT *key, DBT *data,
- unsigned int flags);
-static int keydb_Sync(NSSLOWKEYDBHandle *db, unsigned int flags);
-static int keydb_Del(NSSLOWKEYDBHandle *db, DBT *key, unsigned int flags);
-static int keydb_Seq(NSSLOWKEYDBHandle *db, DBT *key, DBT *data,
- unsigned int flags);
-static void keydb_Close(NSSLOWKEYDBHandle *db);
-
-/*
- * format of key database entries for version 3 of database:
- * byte offset field
- * ----------- -----
- * 0 version
- * 1 salt-len
- * 2 nn-len
- * 3.. salt-data
- * ... nickname
- * ... encrypted-key-data
- */
-static DBT *
-encode_dbkey(NSSLOWKEYDBKey *dbkey,unsigned char version)
-{
- DBT *bufitem = NULL;
- unsigned char *buf;
- int nnlen;
- char *nn;
-
- bufitem = (DBT *)PORT_ZAlloc(sizeof(DBT));
- if ( bufitem == NULL ) {
- goto loser;
- }
-
- if ( dbkey->nickname ) {
- nn = dbkey->nickname;
- nnlen = PORT_Strlen(nn) + 1;
- } else {
- nn = "";
- nnlen = 1;
- }
-
- /* compute the length of the record */
- /* 1 + 1 + 1 == version number header + salt length + nn len */
- bufitem->size = dbkey->salt.len + nnlen + dbkey->derPK.len + 1 + 1 + 1;
-
- bufitem->data = (void *)PORT_ZAlloc(bufitem->size);
- if ( bufitem->data == NULL ) {
- goto loser;
- }
-
- buf = (unsigned char *)bufitem->data;
-
- /* set version number */
- buf[0] = version;
-
- /* set length of salt */
- PORT_Assert(dbkey->salt.len < 256);
- buf[1] = dbkey->salt.len;
-
- /* set length of nickname */
- PORT_Assert(nnlen < 256);
- buf[2] = nnlen;
-
- /* copy salt */
- PORT_Memcpy(&buf[3], dbkey->salt.data, dbkey->salt.len);
-
- /* copy nickname */
- PORT_Memcpy(&buf[3 + dbkey->salt.len], nn, nnlen);
-
- /* copy encrypted key */
- PORT_Memcpy(&buf[3 + dbkey->salt.len + nnlen], dbkey->derPK.data,
- dbkey->derPK.len);
-
- return(bufitem);
-
-loser:
- if ( bufitem ) {
- free_dbt(bufitem);
- }
-
- return(NULL);
-}
-
-static NSSLOWKEYDBKey *
-decode_dbkey(DBT *bufitem, int expectedVersion)
-{
- NSSLOWKEYDBKey *dbkey;
- PLArenaPool *arena = NULL;
- unsigned char *buf;
- int version;
- int keyoff;
- int nnlen;
- int saltoff;
-
- buf = (unsigned char *)bufitem->data;
-
- version = buf[0];
-
- if ( version != expectedVersion ) {
- goto loser;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey));
- if ( dbkey == NULL ) {
- goto loser;
- }
-
- dbkey->arena = arena;
- dbkey->salt.data = NULL;
- dbkey->derPK.data = NULL;
-
- dbkey->salt.len = buf[1];
- dbkey->salt.data = (unsigned char *)PORT_ArenaZAlloc(arena, dbkey->salt.len);
- if ( dbkey->salt.data == NULL ) {
- goto loser;
- }
-
- saltoff = 2;
- keyoff = 2 + dbkey->salt.len;
-
- if ( expectedVersion >= 3 ) {
- nnlen = buf[2];
- if ( nnlen ) {
- dbkey->nickname = (char *)PORT_ArenaZAlloc(arena, nnlen + 1);
- if ( dbkey->nickname ) {
- PORT_Memcpy(dbkey->nickname, &buf[keyoff+1], nnlen);
- }
- }
- keyoff += ( nnlen + 1 );
- saltoff = 3;
- }
-
- PORT_Memcpy(dbkey->salt.data, &buf[saltoff], dbkey->salt.len);
-
- dbkey->derPK.len = bufitem->size - keyoff;
- dbkey->derPK.data = (unsigned char *)PORT_ArenaZAlloc(arena,dbkey->derPK.len);
- if ( dbkey->derPK.data == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(dbkey->derPK.data, &buf[keyoff], dbkey->derPK.len);
-
- return(dbkey);
-
-loser:
-
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-static NSSLOWKEYDBKey *
-get_dbkey(NSSLOWKEYDBHandle *handle, DBT *index)
-{
- NSSLOWKEYDBKey *dbkey;
- DBT entry;
- int ret;
-
- /* get it from the database */
- ret = keydb_Get(handle, index, &entry, 0);
- if ( ret ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return NULL;
- }
-
- /* set up dbkey struct */
-
- dbkey = decode_dbkey(&entry, handle->version);
-
- return(dbkey);
-}
-
-static SECStatus
-put_dbkey(NSSLOWKEYDBHandle *handle, DBT *index, NSSLOWKEYDBKey *dbkey, PRBool update)
-{
- DBT *keydata = NULL;
- int status;
-
- keydata = encode_dbkey(dbkey, handle->version);
- if ( keydata == NULL ) {
- goto loser;
- }
-
- /* put it in the database */
- if ( update ) {
- status = keydb_Put(handle, index, keydata, 0);
- } else {
- status = keydb_Put(handle, index, keydata, R_NOOVERWRITE);
- }
-
- if ( status ) {
- goto loser;
- }
-
- /* sync the database */
- status = keydb_Sync(handle, 0);
- if ( status ) {
- goto loser;
- }
-
- free_dbt(keydata);
- return(SECSuccess);
-
-loser:
- if ( keydata ) {
- free_dbt(keydata);
- }
-
- return(SECFailure);
-}
-
-SECStatus
-nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
- SECStatus (* keyfunc)(DBT *k, DBT *d, void *pdata),
- void *udata )
-{
- DBT data;
- DBT key;
- SECStatus status;
- int ret;
-
- if (handle == NULL) {
- return(SECFailure);
- }
-
- ret = keydb_Seq(handle, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
- }
-
- do {
- /* skip version record */
- if ( data.size > 1 ) {
- if ( key.size == ( sizeof(SALT_STRING) - 1 ) ) {
- if ( PORT_Memcmp(key.data, SALT_STRING, key.size) == 0 ) {
- continue;
- }
- }
-
- /* skip password check */
- if ( key.size == KEYDB_PW_CHECK_LEN ) {
- if ( PORT_Memcmp(key.data, KEYDB_PW_CHECK_STRING,
- KEYDB_PW_CHECK_LEN) == 0 ) {
- continue;
- }
- }
-
- status = (* keyfunc)(&key, &data, udata);
- if (status != SECSuccess) {
- return(status);
- }
- }
- } while ( keydb_Seq(handle, &key, &data, R_NEXT) == 0 );
-
- return(SECSuccess);
-}
-
-#ifdef notdef
-typedef struct keyNode {
- struct keyNode *next;
- DBT key;
-} keyNode;
-
-typedef struct {
- PLArenaPool *arena;
- keyNode *head;
-} keyList;
-
-static SECStatus
-sec_add_key_to_list(DBT *key, DBT *data, void *arg)
-{
- keyList *keylist;
- keyNode *node;
- void *keydata;
-
- keylist = (keyList *)arg;
-
- /* allocate the node struct */
- node = (keyNode*)PORT_ArenaZAlloc(keylist->arena, sizeof(keyNode));
- if ( node == NULL ) {
- return(SECFailure);
- }
-
- /* allocate room for key data */
- keydata = PORT_ArenaZAlloc(keylist->arena, key->size);
- if ( keydata == NULL ) {
- return(SECFailure);
- }
-
- /* link node into list */
- node->next = keylist->head;
- keylist->head = node;
-
- /* copy key into node */
- PORT_Memcpy(keydata, key->data, key->size);
- node->key.size = key->size;
- node->key.data = keydata;
-
- return(SECSuccess);
-}
-#endif
-
-static SECItem *
-decodeKeyDBGlobalSalt(DBT *saltData)
-{
- SECItem *saltitem;
-
- saltitem = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if ( saltitem == NULL ) {
- return(NULL);
- }
-
- saltitem->data = (unsigned char *)PORT_ZAlloc(saltData->size);
- if ( saltitem->data == NULL ) {
- PORT_Free(saltitem);
- return(NULL);
- }
-
- saltitem->len = saltData->size;
- PORT_Memcpy(saltitem->data, saltData->data, saltitem->len);
-
- return(saltitem);
-}
-
-static SECItem *
-GetKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle)
-{
- DBT saltKey;
- DBT saltData;
- int ret;
-
- saltKey.data = SALT_STRING;
- saltKey.size = sizeof(SALT_STRING) - 1;
-
- ret = keydb_Get(handle, &saltKey, &saltData, 0);
- if ( ret ) {
- return(NULL);
- }
-
- return(decodeKeyDBGlobalSalt(&saltData));
-}
-
-static SECStatus
-StoreKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle, SECItem *salt)
-{
- DBT saltKey;
- DBT saltData;
- int status;
-
- saltKey.data = SALT_STRING;
- saltKey.size = sizeof(SALT_STRING) - 1;
-
- saltData.data = (void *)salt->data;
- saltData.size = salt->len;
-
- /* put global salt into the database now */
- status = keydb_Put(handle, &saltKey, &saltData, 0);
- if ( status ) {
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-static SECStatus
-makeGlobalVersion(NSSLOWKEYDBHandle *handle)
-{
- unsigned char version;
- DBT versionData;
- DBT versionKey;
- int status;
-
- version = NSSLOWKEY_DB_FILE_VERSION;
- versionData.data = &version;
- versionData.size = 1;
- versionKey.data = VERSION_STRING;
- versionKey.size = sizeof(VERSION_STRING)-1;
-
- /* put version string into the database now */
- status = keydb_Put(handle, &versionKey, &versionData, 0);
- if ( status ) {
- return(SECFailure);
- }
- handle->version = version;
-
- return(SECSuccess);
-}
-
-
-static SECStatus
-makeGlobalSalt(NSSLOWKEYDBHandle *handle)
-{
- DBT saltKey;
- DBT saltData;
- unsigned char saltbuf[16];
- int status;
-
- saltKey.data = SALT_STRING;
- saltKey.size = sizeof(SALT_STRING) - 1;
-
- saltData.data = (void *)saltbuf;
- saltData.size = sizeof(saltbuf);
- RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf));
-
- /* put global salt into the database now */
- status = keydb_Put(handle, &saltKey, &saltData, 0);
- if ( status ) {
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-static SECStatus
-encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg,
- SECItem *encCheck);
-
-static unsigned char
-nsslowkey_version(NSSLOWKEYDBHandle *handle)
-{
- DBT versionKey;
- DBT versionData;
- int ret;
- versionKey.data = VERSION_STRING;
- versionKey.size = sizeof(VERSION_STRING)-1;
-
- if (handle->db == NULL) {
- return 255;
- }
-
- /* lookup version string in database */
- ret = keydb_Get( handle, &versionKey, &versionData, 0 );
-
- /* error accessing the database */
- if ( ret < 0 ) {
- return 255;
- }
-
- if ( ret >= 1 ) {
- return 0;
- }
- return *( (unsigned char *)versionData.data);
-}
-
-static PRBool
-seckey_HasAServerKey(NSSLOWKEYDBHandle *handle)
-{
- DBT key;
- DBT data;
- int ret;
- PRBool found = PR_FALSE;
-
- ret = keydb_Seq(handle, &key, &data, R_FIRST);
- if ( ret ) {
- return PR_FALSE;
- }
-
- do {
- /* skip version record */
- if ( data.size > 1 ) {
- /* skip salt */
- if ( key.size == ( sizeof(SALT_STRING) - 1 ) ) {
- if ( PORT_Memcmp(key.data, SALT_STRING, key.size) == 0 ) {
- continue;
- }
- }
- /* skip pw check entry */
- if ( key.size == KEYDB_PW_CHECK_LEN ) {
- if ( PORT_Memcmp(key.data, KEYDB_PW_CHECK_STRING,
- KEYDB_PW_CHECK_LEN) == 0 ) {
- continue;
- }
- }
-
- /* keys stored by nickname will have 0 as the last byte of the
- * db key. Other keys must be stored by modulus. We will not
- * update those because they are left over from a keygen that
- * never resulted in a cert.
- */
- if ( ((unsigned char *)key.data)[key.size-1] != 0 ) {
- continue;
- }
-
- if (PORT_Strcmp(key.data,"Server-Key") == 0) {
- found = PR_TRUE;
- break;
- }
-
- }
- } while ( keydb_Seq(handle, &key, &data, R_NEXT) == 0 );
-
- return found;
-}
-
-/* forward declare local create function */
-static NSSLOWKEYDBHandle * nsslowkey_NewHandle(DB *dbHandle);
-
-/*
- * currently updates key database from v2 to v3
- */
-static SECStatus
-nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
-{
- SECStatus rv;
- DBT checkKey;
- DBT checkData;
- DBT saltKey;
- DBT saltData;
- DBT key;
- DBT data;
- unsigned char version;
- NSSLOWKEYDBKey *dbkey = NULL;
- NSSLOWKEYDBHandle *update = NULL;
- SECItem *oldSalt = NULL;
- int ret;
- SECItem checkitem;
-
- if ( handle->updatedb == NULL ) {
- return SECSuccess;
- }
-
- /* create a full DB Handle for our update so we
- * can use the correct locks for the db primatives */
- update = nsslowkey_NewHandle(handle->updatedb);
- if ( update == NULL) {
- return SECSuccess;
- }
-
- /* update has now inherited the database handle */
- handle->updatedb = NULL;
-
- /*
- * check the version record
- */
- version = nsslowkey_version(update);
- if (version != 2) {
- goto done;
- }
-
- saltKey.data = SALT_STRING;
- saltKey.size = sizeof(SALT_STRING) - 1;
-
- ret = keydb_Get(update, &saltKey, &saltData, 0);
- if ( ret ) {
- /* no salt in old db, so it is corrupted */
- goto done;
- }
-
- oldSalt = decodeKeyDBGlobalSalt(&saltData);
- if ( oldSalt == NULL ) {
- /* bad salt in old db, so it is corrupted */
- goto done;
- }
-
- /*
- * look for a pw check entry
- */
- checkKey.data = KEYDB_PW_CHECK_STRING;
- checkKey.size = KEYDB_PW_CHECK_LEN;
-
- ret = keydb_Get(update, &checkKey, &checkData, 0 );
- if (ret) {
- /*
- * if we have a key, but no KEYDB_PW_CHECK_STRING, then this must
- * be an old server database, and it does have a password associated
- * with it. Put a fake entry in so we can identify this db when we do
- * get the password for it.
- */
- if (seckey_HasAServerKey(update)) {
- DBT fcheckKey;
- DBT fcheckData;
-
- /*
- * include a fake string
- */
- fcheckKey.data = KEYDB_FAKE_PW_CHECK_STRING;
- fcheckKey.size = KEYDB_FAKE_PW_CHECK_LEN;
- fcheckData.data = "1";
- fcheckData.size = 1;
- /* put global salt into the new database now */
- ret = keydb_Put( handle, &saltKey, &saltData, 0);
- if ( ret ) {
- goto done;
- }
- ret = keydb_Put( handle, &fcheckKey, &fcheckData, 0);
- if ( ret ) {
- goto done;
- }
- } else {
- goto done;
- }
- } else {
- /* put global salt into the new database now */
- ret = keydb_Put( handle, &saltKey, &saltData, 0);
- if ( ret ) {
- goto done;
- }
-
- dbkey = decode_dbkey(&checkData, 2);
- if ( dbkey == NULL ) {
- goto done;
- }
- checkitem = dbkey->derPK;
- dbkey->derPK.data = NULL;
-
- /* format the new pw check entry */
- rv = encodePWCheckEntry(NULL, &dbkey->derPK, SEC_OID_RC4, &checkitem);
- if ( rv != SECSuccess ) {
- goto done;
- }
-
- rv = put_dbkey(handle, &checkKey, dbkey, PR_TRUE);
- if ( rv != SECSuccess ) {
- goto done;
- }
-
- /* free the dbkey */
- sec_destroy_dbkey(dbkey);
- dbkey = NULL;
- }
-
-
- /* now traverse the database */
- ret = keydb_Seq(update, &key, &data, R_FIRST);
- if ( ret ) {
- goto done;
- }
-
- do {
- /* skip version record */
- if ( data.size > 1 ) {
- /* skip salt */
- if ( key.size == ( sizeof(SALT_STRING) - 1 ) ) {
- if ( PORT_Memcmp(key.data, SALT_STRING, key.size) == 0 ) {
- continue;
- }
- }
- /* skip pw check entry */
- if ( key.size == checkKey.size ) {
- if ( PORT_Memcmp(key.data, checkKey.data, key.size) == 0 ) {
- continue;
- }
- }
-
- /* keys stored by nickname will have 0 as the last byte of the
- * db key. Other keys must be stored by modulus. We will not
- * update those because they are left over from a keygen that
- * never resulted in a cert.
- */
- if ( ((unsigned char *)key.data)[key.size-1] != 0 ) {
- continue;
- }
-
- dbkey = decode_dbkey(&data, 2);
- if ( dbkey == NULL ) {
- continue;
- }
-
- /* This puts the key into the new database with the same
- * index (nickname) that it had before. The second pass
- * of the update will have the password. It will decrypt
- * and re-encrypt the entries using a new algorithm.
- */
- dbkey->nickname = (char *)key.data;
- rv = put_dbkey(handle, &key, dbkey, PR_FALSE);
- dbkey->nickname = NULL;
-
- sec_destroy_dbkey(dbkey);
- }
- } while ( keydb_Seq(update, &key, &data, R_NEXT) == 0 );
-
- dbkey = NULL;
-
-done:
- /* sync the database */
- ret = keydb_Sync(handle, 0);
-
- nsslowkey_CloseKeyDB(update);
-
- if ( oldSalt ) {
- SECITEM_FreeItem(oldSalt, PR_TRUE);
- }
-
- if ( dbkey ) {
- sec_destroy_dbkey(dbkey);
- }
-
- return(SECSuccess);
-}
-
-static SECStatus
-openNewDB(const char *appName, const char *prefix, const char *dbname,
- NSSLOWKEYDBHandle *handle, NSSLOWKEYDBNameFunc namecb, void *cbarg)
-{
- SECStatus rv = SECFailure;
- int status = RDB_FAIL;
- char *updname = NULL;
- DB *updatedb = NULL;
- PRBool updated = PR_FALSE;
- int ret;
-
- if (appName) {
- handle->db = rdbopen( appName, prefix, "key", NO_CREATE, &status);
- } else {
- handle->db = dbopen( dbname, NO_CREATE, 0600, DB_HASH, 0 );
- }
- /* if create fails then we lose */
- if ( handle->db == NULL ) {
- return (status == RDB_RETRY) ? SECWouldBlock: SECFailure;
- }
-
- /* force a transactional read, which will verify that one and only one
- * process attempts the update. */
- if (nsslowkey_version(handle) == NSSLOWKEY_DB_FILE_VERSION) {
- /* someone else has already updated the database for us */
- db_InitComplete(handle->db);
- return SECSuccess;
- }
-
- /*
- * if we are creating a multiaccess database, see if there is a
- * local database we can update from.
- */
- if (appName) {
- NSSLOWKEYDBHandle *updateHandle;
- updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 );
- if (!updatedb) {
- goto noupdate;
- }
-
- /* nsslowkey_version needs a full handle because it calls
- * the kdb_Get() function, which needs to lock.
- */
- updateHandle = nsslowkey_NewHandle(updatedb);
- if (!updateHandle) {
- updatedb->close(updatedb);
- goto noupdate;
- }
-
- handle->version = nsslowkey_version(updateHandle);
- if (handle->version != NSSLOWKEY_DB_FILE_VERSION) {
- nsslowkey_CloseKeyDB(updateHandle);
- goto noupdate;
- }
-
- /* copy the new DB from the old one */
- db_Copy(handle->db, updatedb);
- nsslowkey_CloseKeyDB(updateHandle);
- db_InitComplete(handle->db);
- return SECSuccess;
- }
-noupdate:
-
- /* update the version number */
- rv = makeGlobalVersion(handle);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /*
- * try to update from v2 db
- */
- updname = (*namecb)(cbarg, 2);
- if ( updname != NULL ) {
- handle->updatedb = dbopen( updname, NO_RDONLY, 0600, DB_HASH, 0 );
- PORT_Free( updname );
-
- if ( handle->updatedb ) {
- /*
- * Try to update the db using a null password. If the db
- * doesn't have a password, then this will work. If it does
- * have a password, then this will fail and we will do the
- * update later
- */
- rv = nsslowkey_UpdateKeyDBPass1(handle);
- if ( rv == SECSuccess ) {
- updated = PR_TRUE;
- }
- }
-
- }
-
- /* we are using the old salt if we updated from an old db */
- if ( ! updated ) {
- rv = makeGlobalSalt(handle);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- /* sync the database */
- ret = keydb_Sync(handle, 0);
- if ( ret ) {
- rv = SECFailure;
- goto loser;
- }
- rv = SECSuccess;
-
-loser:
- db_InitComplete(handle->db);
- return rv;
-}
-
-
-static DB *
-openOldDB(const char *appName, const char *prefix, const char *dbname,
- PRBool openflags) {
- DB *db = NULL;
-
- if (appName) {
- db = rdbopen( appName, prefix, "key", openflags, NULL);
- } else {
- db = dbopen( dbname, openflags, 0600, DB_HASH, 0 );
- }
-
- return db;
-}
-
-/* check for correct version number */
-static PRBool
-verifyVersion(NSSLOWKEYDBHandle *handle)
-{
- int version = nsslowkey_version(handle);
-
- handle->version = version;
- if (version != NSSLOWKEY_DB_FILE_VERSION ) {
- if (handle->db) {
- keydb_Close(handle);
- handle->db = NULL;
- }
- }
- return handle->db != NULL;
-}
-
-static NSSLOWKEYDBHandle *
-nsslowkey_NewHandle(DB *dbHandle)
-{
- NSSLOWKEYDBHandle *handle;
- handle = (NSSLOWKEYDBHandle *)PORT_ZAlloc (sizeof(NSSLOWKEYDBHandle));
- if (handle == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- handle->appname = NULL;
- handle->dbname = NULL;
- handle->global_salt = NULL;
- handle->updatedb = NULL;
- handle->db = dbHandle;
- handle->ref = 1;
- handle->lock = PZ_NewLock(nssILockKeyDB);
-
- return handle;
-}
-
-NSSLOWKEYDBHandle *
-nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix,
- NSSLOWKEYDBNameFunc namecb, void *cbarg)
-{
- NSSLOWKEYDBHandle *handle = NULL;
- SECStatus rv;
- int openflags;
- char *dbname = NULL;
-
-
- handle = nsslowkey_NewHandle(NULL);
-
- openflags = readOnly ? NO_RDONLY : NO_RDWR;
-
-
- dbname = (*namecb)(cbarg, NSSLOWKEY_DB_FILE_VERSION);
- if ( dbname == NULL ) {
- goto loser;
- }
- handle->appname = appName ? PORT_Strdup(appName) : NULL ;
- handle->dbname = (appName == NULL) ? PORT_Strdup(dbname) :
- (prefix ? PORT_Strdup(prefix) : NULL);
- handle->readOnly = readOnly;
-
-
-
- handle->db = openOldDB(appName, prefix, dbname, openflags);
- if (handle->db) {
- verifyVersion(handle);
- if (handle->version == 255) {
- goto loser;
- }
- }
-
- /* if first open fails, try to create a new DB */
- if ( handle->db == NULL ) {
- if ( readOnly ) {
- goto loser;
- }
-
- rv = openNewDB(appName, prefix, dbname, handle, namecb, cbarg);
- /* two processes started to initialize the database at the same time.
- * The multiprocess code blocked the second one, then had it retry to
- * see if it can just open the database normally */
- if (rv == SECWouldBlock) {
- handle->db = openOldDB(appName,prefix,dbname, openflags);
- verifyVersion(handle);
- if (handle->db == NULL) {
- goto loser;
- }
- } else if (rv != SECSuccess) {
- goto loser;
- }
- }
-
- handle->global_salt = GetKeyDBGlobalSalt(handle);
- if ( dbname )
- PORT_Free( dbname );
- return handle;
-
-loser:
-
- if ( dbname )
- PORT_Free( dbname );
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- nsslowkey_CloseKeyDB(handle);
- return NULL;
-}
-
-/*
- * Close the database
- */
-void
-nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle)
-{
- if (handle != NULL) {
- if (handle->db != NULL) {
- keydb_Close(handle);
- }
- if (handle->updatedb) {
- handle->updatedb->close(handle->updatedb);
- }
- if (handle->dbname) PORT_Free(handle->dbname);
- if (handle->appname) PORT_Free(handle->appname);
- if (handle->global_salt) {
- SECITEM_FreeItem(handle->global_salt,PR_TRUE);
- }
- if (handle->lock != NULL) {
- SKIP_AFTER_FORK(PZ_DestroyLock(handle->lock));
- }
-
- PORT_Free(handle);
- }
-}
-
-/* Get the key database version */
-int
-nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle)
-{
- PORT_Assert(handle != NULL);
-
- return handle->version;
-}
-
-/*
- * Delete a private key that was stored in the database
- */
-SECStatus
-nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle, const SECItem *pubkey)
-{
- DBT namekey;
- int ret;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
- }
-
- /* set up db key and data */
- namekey.data = pubkey->data;
- namekey.size = pubkey->len;
-
- /* delete it from the database */
- ret = keydb_Del(handle, &namekey, 0);
- if ( ret ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
- }
-
- /* sync the database */
- ret = keydb_Sync(handle, 0);
- if ( ret ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-/*
- * Store a key in the database, indexed by its public key modulus.(value!)
- */
-SECStatus
-nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle,
- NSSLOWKEYPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SDB *sdb)
-{
- return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
- nickname, sdb, PR_FALSE);
-}
-
-SECStatus
-nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle,
- NSSLOWKEYPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SDB *sdb)
-{
- return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
- nickname, sdb, PR_TRUE);
-}
-
-/* see if the symetric CKA_ID already Exists.
- */
-PRBool
-nsslowkey_KeyForIDExists(NSSLOWKEYDBHandle *handle, SECItem *id)
-{
- DBT namekey;
- DBT dummy;
- int status;
-
- namekey.data = (char *)id->data;
- namekey.size = id->len;
- status = keydb_Get(handle, &namekey, &dummy, 0);
- if ( status ) {
- return PR_FALSE;
- }
-
- return PR_TRUE;
-}
-
-/* see if the public key for this cert is in the database filed
- * by modulus
- */
-PRBool
-nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cert)
-{
- NSSLOWKEYPublicKey *pubkey = NULL;
- DBT namekey;
- DBT dummy;
- int status;
-
- /* get cert's public key */
- pubkey = nsslowcert_ExtractPublicKey(cert);
- if ( pubkey == NULL ) {
- return PR_FALSE;
- }
-
- /* TNH - make key from NSSLOWKEYPublicKey */
- switch (pubkey->keyType) {
- case NSSLOWKEYRSAKey:
- namekey.data = pubkey->u.rsa.modulus.data;
- namekey.size = pubkey->u.rsa.modulus.len;
- break;
- case NSSLOWKEYDSAKey:
- namekey.data = pubkey->u.dsa.publicValue.data;
- namekey.size = pubkey->u.dsa.publicValue.len;
- break;
- case NSSLOWKEYDHKey:
- namekey.data = pubkey->u.dh.publicValue.data;
- namekey.size = pubkey->u.dh.publicValue.len;
- break;
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- namekey.data = pubkey->u.ec.publicValue.data;
- namekey.size = pubkey->u.ec.publicValue.len;
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- /* XXX We don't do Fortezza or DH yet. */
- return PR_FALSE;
- }
-
- if (handle->version != 3) {
- unsigned char buf[SHA1_LENGTH];
- SHA1_HashBuf(buf,namekey.data,namekey.size);
- /* NOTE: don't use pubkey after this! it's now thrashed */
- PORT_Memcpy(namekey.data,buf,sizeof(buf));
- namekey.size = sizeof(buf);
- }
-
- status = keydb_Get(handle, &namekey, &dummy, 0);
- /* some databases have the key stored as a signed value */
- if (status) {
- unsigned char *buf = (unsigned char *)PORT_Alloc(namekey.size+1);
- if (buf) {
- PORT_Memcpy(&buf[1], namekey.data, namekey.size);
- buf[0] = 0;
- namekey.data = buf;
- namekey.size ++;
- status = keydb_Get(handle, &namekey, &dummy, 0);
- PORT_Free(buf);
- }
- }
- lg_nsslowkey_DestroyPublicKey(pubkey);
- if ( status ) {
- return PR_FALSE;
- }
-
- return PR_TRUE;
-}
-
-typedef struct NSSLowPasswordDataParamStr {
- SECItem salt;
- SECItem iter;
-} NSSLowPasswordDataParam;
-
-static const SEC_ASN1Template NSSLOWPasswordParamTemplate[] =
-{
- {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLowPasswordDataParam) },
- {SEC_ASN1_OCTET_STRING, offsetof(NSSLowPasswordDataParam, salt) },
- {SEC_ASN1_INTEGER, offsetof(NSSLowPasswordDataParam, iter) },
- {0}
-};
-struct LGEncryptedDataInfoStr {
- SECAlgorithmID algorithm;
- SECItem encryptedData;
-};
-typedef struct LGEncryptedDataInfoStr LGEncryptedDataInfo;
-
-const SEC_ASN1Template lg_EncryptedDataInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(LGEncryptedDataInfo) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(LGEncryptedDataInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(LGEncryptedDataInfo,encryptedData) },
- { 0 }
-};
-
-static SECItem *
-nsslowkey_EncodePW(SECOidTag alg, const SECItem *salt, SECItem *data)
-{
- NSSLowPasswordDataParam param;
- LGEncryptedDataInfo edi;
- PLArenaPool *arena;
- unsigned char one = 1;
- SECItem *epw = NULL;
- SECItem *encParam;
- SECStatus rv;
-
- param.salt = *salt;
- param.iter.type = siBuffer; /* encode as signed integer */
- param.iter.data = &one;
- param.iter.len = 1;
- edi.encryptedData = *data;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return NULL;
- }
-
- encParam = SEC_ASN1EncodeItem(arena, NULL, &param,
- NSSLOWPasswordParamTemplate);
- if (encParam == NULL) {
- goto loser;
- }
- rv = SECOID_SetAlgorithmID(arena, &edi.algorithm, alg, encParam);
- if (rv != SECSuccess) {
- goto loser;
- }
- epw = SEC_ASN1EncodeItem(NULL, NULL, &edi, lg_EncryptedDataInfoTemplate);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return epw;
-}
-
-static SECItem *
-nsslowkey_DecodePW(const SECItem *derData, SECOidTag *alg, SECItem *salt)
-{
- NSSLowPasswordDataParam param;
- LGEncryptedDataInfo edi;
- PLArenaPool *arena;
- SECItem *pwe = NULL;
- SECStatus rv;
-
- salt->data = NULL;
- param.iter.type = siBuffer; /* decode as signed integer */
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return NULL;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, &edi, lg_EncryptedDataInfoTemplate,
- derData);
- if (rv != SECSuccess) {
- goto loser;
- }
- *alg = SECOID_GetAlgorithmTag(&edi.algorithm);
- rv = SEC_QuickDERDecodeItem(arena, &param, NSSLOWPasswordParamTemplate,
- &edi.algorithm.parameters);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECITEM_CopyItem(NULL, salt, &param.salt);
- if (rv != SECSuccess) {
- goto loser;
- }
- pwe = SECITEM_DupItem(&edi.encryptedData);
-
-loser:
- if (!pwe && salt->data) {
- PORT_Free(salt->data);
- salt->data = NULL;
- }
- PORT_FreeArena(arena, PR_FALSE);
- return pwe;
-}
-
-
-/*
- * check to see if the user has a password
- */
-static SECStatus
-nsslowkey_GetPWCheckEntry(NSSLOWKEYDBHandle *handle,NSSLOWKEYPasswordEntry *entry)
-{
- DBT checkkey; /*, checkdata; */
- NSSLOWKEYDBKey *dbkey = NULL;
- SECItem *global_salt = NULL;
- SECItem *item = NULL;
- SECItem entryData, oid;
- SECItem none = { siBuffer, NULL, 0 };
- SECStatus rv = SECFailure;
- SECOidTag algorithm;
-
- if (handle == NULL) {
- /* PORT_SetError */
- return(SECFailure);
- }
-
- global_salt = GetKeyDBGlobalSalt(handle);
- if (!global_salt) {
- global_salt = &none;
- }
- if (global_salt->len > sizeof(entry->data)) {
- /* PORT_SetError */
- goto loser;
- }
-
- PORT_Memcpy(entry->data, global_salt->data, global_salt->len);
- entry->salt.data = entry->data;
- entry->salt.len = global_salt->len;
- entry->value.data = &entry->data[entry->salt.len];
-
- checkkey.data = KEYDB_PW_CHECK_STRING;
- checkkey.size = KEYDB_PW_CHECK_LEN;
- dbkey = get_dbkey(handle, &checkkey);
- if (dbkey == NULL) {
- /* handle 'FAKE' check here */
- goto loser;
- }
-
- oid.len = dbkey->derPK.data[0];
- oid.data = &dbkey->derPK.data[1];
-
- if (dbkey->derPK.len < (KEYDB_PW_CHECK_LEN + 1 +oid.len)) {
- goto loser;
- }
- algorithm = SECOID_FindOIDTag(&oid);
- entryData.type = siBuffer;
- entryData.len = dbkey->derPK.len - (oid.len+1);
- entryData.data = &dbkey->derPK.data[oid.len+1];
-
- item = nsslowkey_EncodePW(algorithm, &dbkey->salt, &entryData);
- if (!item || (item->len + entry->salt.len) > sizeof(entry->data)) {
- goto loser;
- }
- PORT_Memcpy(entry->value.data, item->data, item->len);
- entry->value.len = item->len;
- rv = SECSuccess;
-
-loser:
- if (item) {
- SECITEM_FreeItem(item, PR_TRUE);
- }
- if (dbkey) {
- sec_destroy_dbkey(dbkey);
- }
- if (global_salt != &none) {
- SECITEM_FreeItem(global_salt,PR_TRUE);
- }
- return rv;
-}
-
-/*
- * check to see if the user has a password
- */
-static SECStatus
-nsslowkey_PutPWCheckEntry(NSSLOWKEYDBHandle *handle,NSSLOWKEYPasswordEntry *entry)
-{
- DBT checkkey;
- NSSLOWKEYDBKey *dbkey = NULL;
- SECItem *item = NULL;
- SECItem salt;
- SECOidTag algid;
- SECStatus rv = SECFailure;
- PLArenaPool *arena;
- int ret;
-
- if (handle == NULL) {
- /* PORT_SetError */
- return(SECFailure);
- }
-
- checkkey.data = KEYDB_PW_CHECK_STRING;
- checkkey.size = KEYDB_PW_CHECK_LEN;
-
- salt.data = NULL;
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return SECFailure;
- }
-
- item = nsslowkey_DecodePW(&entry->value, &algid, &salt);
- if (item == NULL) {
- goto loser;
- }
-
- dbkey = PORT_ArenaZNew(arena, NSSLOWKEYDBKey);
- if (dbkey == NULL) {
- goto loser;
- }
-
- dbkey->arena = arena;
-
- rv = SECITEM_CopyItem(arena, &dbkey->salt, &salt);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = encodePWCheckEntry(arena, &dbkey->derPK, algid, item);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = put_dbkey(handle, &checkkey, dbkey, PR_TRUE);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- if (handle->global_salt) {
- SECITEM_FreeItem(handle->global_salt, PR_TRUE);
- handle->global_salt = NULL;
- }
- rv = StoreKeyDBGlobalSalt(handle, &entry->salt);
- if (rv != SECSuccess) {
- goto loser;
- }
- ret = keydb_Sync(handle, 0);
- if ( ret ) {
- rv = SECFailure;
- goto loser;
- }
- handle->global_salt = GetKeyDBGlobalSalt(handle);
-
-loser:
- if (item) {
- SECITEM_FreeItem(item, PR_TRUE);
- }
- if (arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
- if (salt.data) {
- PORT_Free(salt.data);
- }
- return rv;
-}
-
-#ifdef EC_DEBUG
-#define SEC_PRINT(str1, str2, num, sitem) \
- printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \
- str1, str2, num, sitem->len); \
- for (i = 0; i < sitem->len; i++) { \
- printf("%02x:", sitem->data[i]); \
- } \
- printf("\n")
-#else
-#define SEC_PRINT(a, b, c, d)
-#endif /* EC_DEBUG */
-
-
-SECStatus
-seckey_encrypt_private_key( PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk,
- SDB *sdbpw, SECItem *result)
-{
- NSSLOWKEYPrivateKeyInfo *pki = NULL;
- SECStatus rv = SECFailure;
- PLArenaPool *temparena = NULL;
- SECItem *der_item = NULL;
- SECItem *cipherText = NULL;
- SECItem *dummy = NULL;
-#ifdef NSS_ENABLE_ECC
- SECItem *fordebug = NULL;
- int savelen;
-#endif
-
- temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(temparena == NULL)
- goto loser;
-
- /* allocate structures */
- pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
- sizeof(NSSLOWKEYPrivateKeyInfo));
- der_item = (SECItem *)PORT_ArenaZAlloc(temparena, sizeof(SECItem));
- if((pki == NULL) || (der_item == NULL))
- goto loser;
-
-
- /* setup private key info */
- dummy = SEC_ASN1EncodeInteger(temparena, &(pki->version),
- NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
- if(dummy == NULL)
- goto loser;
-
- /* Encode the key, and set the algorithm (with params) */
- switch (pk->keyType) {
- case NSSLOWKEYRSAKey:
- lg_prepare_low_rsa_priv_key_for_asn1(pk);
- dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- lg_nsslowkey_RSAPrivateKeyTemplate);
- if (dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
- SEC_OID_PKCS1_RSA_ENCRYPTION, 0);
- if (rv == SECFailure) {
- goto loser;
- }
-
- break;
- case NSSLOWKEYDSAKey:
- lg_prepare_low_dsa_priv_key_for_asn1(pk);
- dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- lg_nsslowkey_DSAPrivateKeyTemplate);
- if (dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- lg_prepare_low_pqg_params_for_asn1(&pk->u.dsa.params);
- dummy = SEC_ASN1EncodeItem(temparena, NULL, &pk->u.dsa.params,
- lg_nsslowkey_PQGParamsTemplate);
- if (dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
- SEC_OID_ANSIX9_DSA_SIGNATURE, dummy);
- if (rv == SECFailure) {
- goto loser;
- }
-
- break;
- case NSSLOWKEYDHKey:
- lg_prepare_low_dh_priv_key_for_asn1(pk);
- dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- lg_nsslowkey_DHPrivateKeyTemplate);
- if (dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
- SEC_OID_X942_DIFFIE_HELMAN_KEY, dummy);
- if (rv == SECFailure) {
- goto loser;
- }
- break;
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- lg_prepare_low_ec_priv_key_for_asn1(pk);
- /* Public value is encoded as a bit string so adjust length
- * to be in bits before ASN encoding and readjust
- * immediately after.
- *
- * Since the SECG specification recommends not including the
- * parameters as part of ECPrivateKey, we zero out the curveOID
- * length before encoding and restore it later.
- */
- pk->u.ec.publicValue.len <<= 3;
- savelen = pk->u.ec.ecParams.curveOID.len;
- pk->u.ec.ecParams.curveOID.len = 0;
- dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk,
- lg_nsslowkey_ECPrivateKeyTemplate);
- pk->u.ec.ecParams.curveOID.len = savelen;
- pk->u.ec.publicValue.len >>= 3;
-
- if (dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- dummy = &pk->u.ec.ecParams.DEREncoding;
-
- /* At this point dummy should contain the encoded params */
- rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm),
- SEC_OID_ANSIX962_EC_PUBLIC_KEY, dummy);
-
- if (rv == SECFailure) {
- goto loser;
- }
-
- fordebug = &(pki->privateKey);
- SEC_PRINT("seckey_encrypt_private_key()", "PrivateKey",
- pk->keyType, fordebug);
-
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- /* We don't support DH or Fortezza private keys yet */
- PORT_Assert(PR_FALSE);
- break;
- }
-
- /* setup encrypted private key info */
- dummy = SEC_ASN1EncodeItem(temparena, der_item, pki,
- lg_nsslowkey_PrivateKeyInfoTemplate);
-
- SEC_PRINT("seckey_encrypt_private_key()", "PrivateKeyInfo",
- pk->keyType, der_item);
-
- if(dummy == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = lg_util_encrypt(temparena, sdbpw, dummy, &cipherText);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- rv = SECITEM_CopyItem ( permarena, result, cipherText);
-
-loser:
-
- if(temparena != NULL)
- PORT_FreeArena(temparena, PR_TRUE);
-
- return rv;
-}
-
-static SECStatus
-seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SDB *sdbpw,
- NSSLOWKEYPrivateKey *pk, char *nickname, PRBool update)
-{
- NSSLOWKEYDBKey *dbkey = NULL;
- PLArenaPool *arena = NULL;
- SECStatus rv = SECFailure;
-
- if((keydb == NULL) || (index == NULL) || (sdbpw == NULL) ||
- (pk == NULL))
- return SECFailure;
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(arena == NULL)
- return SECFailure;
-
- dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey));
- if(dbkey == NULL)
- goto loser;
- dbkey->arena = arena;
- dbkey->nickname = nickname;
-
- rv = seckey_encrypt_private_key(arena, pk, sdbpw, &dbkey->derPK);
- if(rv != SECSuccess)
- goto loser;
-
- rv = put_dbkey(keydb, index, dbkey, update);
-
- /* let success fall through */
-loser:
- if(arena != NULL)
- PORT_FreeArena(arena, PR_TRUE);
-
- return rv;
-}
-
-/*
- * Store a key in the database, indexed by its public key modulus.
- * Note that the nickname is optional. It was only used by keyutil.
- */
-SECStatus
-nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
- NSSLOWKEYPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SDB *sdbpw,
- PRBool update)
-{
- DBT namekey;
- SECStatus rv;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
- }
-
- /* set up db key and data */
- namekey.data = pubKeyData->data;
- namekey.size = pubKeyData->len;
-
- /* encrypt the private key */
- rv = seckey_put_private_key(handle, &namekey, sdbpw, privkey, nickname,
- update);
-
- return(rv);
-}
-
-static NSSLOWKEYPrivateKey *
-seckey_decrypt_private_key(SECItem*epki,
- SDB *sdbpw)
-{
- NSSLOWKEYPrivateKey *pk = NULL;
- NSSLOWKEYPrivateKeyInfo *pki = NULL;
- SECStatus rv = SECFailure;
- PLArenaPool *temparena = NULL, *permarena = NULL;
- SECItem *dest = NULL;
-#ifdef NSS_ENABLE_ECC
- SECItem *fordebug = NULL;
-#endif
-
- if((epki == NULL) || (sdbpw == NULL))
- goto loser;
-
- temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if((temparena == NULL) || (permarena == NULL))
- goto loser;
-
- /* allocate temporary items */
- pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena,
- sizeof(NSSLOWKEYPrivateKeyInfo));
-
- /* allocate permanent arena items */
- pk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(permarena,
- sizeof(NSSLOWKEYPrivateKey));
-
- if((pk == NULL) || (pki == NULL))
- goto loser;
-
- pk->arena = permarena;
-
- rv = lg_util_decrypt(sdbpw, epki, &dest);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- if(dest != NULL)
- {
- SECItem newPrivateKey;
- SECItem newAlgParms;
-
- SEC_PRINT("seckey_decrypt_private_key()", "PrivateKeyInfo", -1,
- dest);
-
- rv = SEC_QuickDERDecodeItem(temparena, pki,
- lg_nsslowkey_PrivateKeyInfoTemplate, dest);
- if(rv == SECSuccess)
- {
- switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
- case SEC_OID_X500_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- pk->keyType = NSSLOWKEYRSAKey;
- lg_prepare_low_rsa_priv_key_for_asn1(pk);
- if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey,
- &pki->privateKey) ) break;
- rv = SEC_QuickDERDecodeItem(permarena, pk,
- lg_nsslowkey_RSAPrivateKeyTemplate,
- &newPrivateKey);
- if (rv == SECSuccess) {
- break;
- }
- /* Try decoding with the alternative template, but only allow
- * a zero-length modulus for a secret key object.
- * See bug 715073.
- */
- rv = SEC_QuickDERDecodeItem(permarena, pk,
- lg_nsslowkey_RSAPrivateKeyTemplate2,
- &newPrivateKey);
- /* A publicExponent of 0 is the defining property of a secret
- * key disguised as an RSA key. When decoding with the
- * alternative template, only accept a secret key with an
- * improperly encoded modulus and a publicExponent of 0.
- */
- if (rv == SECSuccess) {
- if (pk->u.rsa.modulus.len == 2 &&
- pk->u.rsa.modulus.data[0] == SEC_ASN1_INTEGER &&
- pk->u.rsa.modulus.data[1] == 0 &&
- pk->u.rsa.publicExponent.len == 1 &&
- pk->u.rsa.publicExponent.data[0] == 0) {
- /* Fix the zero-length integer by setting it to 0. */
- pk->u.rsa.modulus.data = pk->u.rsa.publicExponent.data;
- pk->u.rsa.modulus.len = pk->u.rsa.publicExponent.len;
- } else {
- PORT_SetError(SEC_ERROR_BAD_DER);
- rv = SECFailure;
- }
- }
- break;
- case SEC_OID_ANSIX9_DSA_SIGNATURE:
- pk->keyType = NSSLOWKEYDSAKey;
- lg_prepare_low_dsa_priv_key_for_asn1(pk);
- if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey,
- &pki->privateKey) ) break;
- rv = SEC_QuickDERDecodeItem(permarena, pk,
- lg_nsslowkey_DSAPrivateKeyTemplate,
- &newPrivateKey);
- if (rv != SECSuccess)
- goto loser;
- lg_prepare_low_pqg_params_for_asn1(&pk->u.dsa.params);
- if (SECSuccess != SECITEM_CopyItem(permarena, &newAlgParms,
- &pki->algorithm.parameters) ) break;
- rv = SEC_QuickDERDecodeItem(permarena, &pk->u.dsa.params,
- lg_nsslowkey_PQGParamsTemplate,
- &newAlgParms);
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- pk->keyType = NSSLOWKEYDHKey;
- lg_prepare_low_dh_priv_key_for_asn1(pk);
- if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey,
- &pki->privateKey) ) break;
- rv = SEC_QuickDERDecodeItem(permarena, pk,
- lg_nsslowkey_DHPrivateKeyTemplate,
- &newPrivateKey);
- break;
-#ifdef NSS_ENABLE_ECC
- case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
- pk->keyType = NSSLOWKEYECKey;
- lg_prepare_low_ec_priv_key_for_asn1(pk);
-
- fordebug = &pki->privateKey;
- SEC_PRINT("seckey_decrypt_private_key()", "PrivateKey",
- pk->keyType, fordebug);
- if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey,
- &pki->privateKey) ) break;
- rv = SEC_QuickDERDecodeItem(permarena, pk,
- lg_nsslowkey_ECPrivateKeyTemplate,
- &newPrivateKey);
- if (rv != SECSuccess)
- goto loser;
-
- lg_prepare_low_ecparams_for_asn1(&pk->u.ec.ecParams);
-
- rv = SECITEM_CopyItem(permarena,
- &pk->u.ec.ecParams.DEREncoding,
- &pki->algorithm.parameters);
-
- if (rv != SECSuccess)
- goto loser;
-
- /* Fill out the rest of EC params */
- rv = LGEC_FillParams(permarena, &pk->u.ec.ecParams.DEREncoding,
- &pk->u.ec.ecParams);
-
- if (rv != SECSuccess)
- goto loser;
-
- if (pk->u.ec.publicValue.len != 0) {
- pk->u.ec.publicValue.len >>= 3;
- }
-
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- rv = SECFailure;
- break;
- }
- }
- else if(PORT_GetError() == SEC_ERROR_BAD_DER)
- {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- goto loser;
- }
- }
-
- /* let success fall through */
-loser:
- if(temparena != NULL)
- PORT_FreeArena(temparena, PR_TRUE);
- if(dest != NULL)
- SECITEM_ZfreeItem(dest, PR_TRUE);
-
- if(rv != SECSuccess)
- {
- if(permarena != NULL)
- PORT_FreeArena(permarena, PR_TRUE);
- pk = NULL;
- }
-
- return pk;
-}
-
-static NSSLOWKEYPrivateKey *
-seckey_decode_encrypted_private_key(NSSLOWKEYDBKey *dbkey, SDB *sdbpw)
-{
- if( ( dbkey == NULL ) || ( sdbpw == NULL ) ) {
- return NULL;
- }
-
- return seckey_decrypt_private_key(&(dbkey->derPK), sdbpw);
-}
-
-static NSSLOWKEYPrivateKey *
-seckey_get_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, char **nickname,
- SDB *sdbpw)
-{
- NSSLOWKEYDBKey *dbkey = NULL;
- NSSLOWKEYPrivateKey *pk = NULL;
-
- if( ( keydb == NULL ) || ( index == NULL ) || ( sdbpw == NULL ) ) {
- return NULL;
- }
-
- dbkey = get_dbkey(keydb, index);
- if(dbkey == NULL) {
- goto loser;
- }
-
- if ( nickname ) {
- if ( dbkey->nickname && ( dbkey->nickname[0] != 0 ) ) {
- *nickname = PORT_Strdup(dbkey->nickname);
- } else {
- *nickname = NULL;
- }
- }
-
- pk = seckey_decode_encrypted_private_key(dbkey, sdbpw);
-
- /* let success fall through */
-loser:
-
- if ( dbkey != NULL ) {
- sec_destroy_dbkey(dbkey);
- }
-
- return pk;
-}
-
-/*
- * Find a key in the database, indexed by its public key modulus
- * This is used to find keys that have been stored before their
- * certificate arrives. Once the certificate arrives the key
- * is looked up by the public modulus in the certificate, and the
- * re-stored by its nickname.
- */
-NSSLOWKEYPrivateKey *
-nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
- SDB *sdbpw)
-{
- DBT namekey;
- NSSLOWKEYPrivateKey *pk = NULL;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return NULL;
- }
-
- /* set up db key */
- namekey.data = modulus->data;
- namekey.size = modulus->len;
-
- pk = seckey_get_private_key(handle, &namekey, NULL, sdbpw);
-
- /* no need to free dbkey, since its on the stack, and the data it
- * points to is owned by the database
- */
- return(pk);
-}
-
-char *
-nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle,
- SECItem *modulus, SDB *sdbpw)
-{
- DBT namekey;
- NSSLOWKEYPrivateKey *pk = NULL;
- char *nickname = NULL;
-
- if (handle == NULL) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return NULL;
- }
-
- /* set up db key */
- namekey.data = modulus->data;
- namekey.size = modulus->len;
-
- pk = seckey_get_private_key(handle, &namekey, &nickname, sdbpw);
- if (pk) {
- lg_nsslowkey_DestroyPrivateKey(pk);
- }
-
- /* no need to free dbkey, since its on the stack, and the data it
- * points to is owned by the database
- */
- return(nickname);
-}
-/* ===== ENCODING ROUTINES ===== */
-
-static SECStatus
-encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg,
- SECItem *encCheck)
-{
- SECOidData *oidData;
- SECStatus rv;
-
- oidData = SECOID_FindOIDByTag(alg);
- if ( oidData == NULL ) {
- rv = SECFailure;
- goto loser;
- }
-
- entry->len = 1 + oidData->oid.len + encCheck->len;
- if ( arena ) {
- entry->data = (unsigned char *)PORT_ArenaAlloc(arena, entry->len);
- } else {
- entry->data = (unsigned char *)PORT_Alloc(entry->len);
- }
-
- if ( entry->data == NULL ) {
- goto loser;
- }
-
- /* first length of oid */
- entry->data[0] = (unsigned char)oidData->oid.len;
- /* next oid itself */
- PORT_Memcpy(&entry->data[1], oidData->oid.data, oidData->oid.len);
- /* finally the encrypted check string */
- PORT_Memcpy(&entry->data[1+oidData->oid.len], encCheck->data,
- encCheck->len);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-
-#define MAX_DB_SIZE 0xffff
-/*
- * Clear out all the keys in the existing database
- */
-static SECStatus
-nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle)
-{
- SECStatus rv;
- int ret;
- int errors = 0;
-
- if ( handle->db == NULL ) {
- return(SECSuccess);
- }
-
- if (handle->readOnly) {
- /* set an error code */
- return SECFailure;
- }
-
- if (handle->appname == NULL && handle->dbname == NULL) {
- return SECFailure;
- }
-
- keydb_Close(handle);
- if (handle->appname) {
- handle->db=
- rdbopen(handle->appname, handle->dbname, "key", NO_CREATE, NULL);
- } else {
- handle->db = dbopen( handle->dbname, NO_CREATE, 0600, DB_HASH, 0 );
- }
- if (handle->db == NULL) {
- /* set an error code */
- return SECFailure;
- }
-
- rv = makeGlobalVersion(handle);
- if ( rv != SECSuccess ) {
- errors++;
- goto done;
- }
-
- if (handle->global_salt) {
- rv = StoreKeyDBGlobalSalt(handle, handle->global_salt);
- } else {
- rv = makeGlobalSalt(handle);
- if ( rv == SECSuccess ) {
- handle->global_salt = GetKeyDBGlobalSalt(handle);
- }
- }
- if ( rv != SECSuccess ) {
- errors++;
- }
-
-done:
- /* sync the database */
- ret = keydb_Sync(handle, 0);
- db_InitComplete(handle->db);
-
- return (errors == 0 ? SECSuccess : SECFailure);
-}
-
-static int
-keydb_Get(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
- PRLock *kdbLock = kdb->lock;
- DB *db = kdb->db;
-
- PORT_Assert(kdbLock != NULL);
- PZ_Lock(kdbLock);
-
- ret = (* db->get)(db, key, data, flags);
-
- prstat = PZ_Unlock(kdbLock);
-
- return(ret);
-}
-
-static int
-keydb_Put(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
-{
- PRStatus prstat;
- int ret = 0;
- PRLock *kdbLock = kdb->lock;
- DB *db = kdb->db;
-
- PORT_Assert(kdbLock != NULL);
- PZ_Lock(kdbLock);
-
- ret = (* db->put)(db, key, data, flags);
-
- prstat = PZ_Unlock(kdbLock);
-
- return(ret);
-}
-
-static int
-keydb_Sync(NSSLOWKEYDBHandle *kdb, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
- PRLock *kdbLock = kdb->lock;
- DB *db = kdb->db;
-
- PORT_Assert(kdbLock != NULL);
- PZ_Lock(kdbLock);
-
- ret = (* db->sync)(db, flags);
-
- prstat = PZ_Unlock(kdbLock);
-
- return(ret);
-}
-
-static int
-keydb_Del(NSSLOWKEYDBHandle *kdb, DBT *key, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
- PRLock *kdbLock = kdb->lock;
- DB *db = kdb->db;
-
- PORT_Assert(kdbLock != NULL);
- PZ_Lock(kdbLock);
-
- ret = (* db->del)(db, key, flags);
-
- prstat = PZ_Unlock(kdbLock);
-
- return(ret);
-}
-
-static int
-keydb_Seq(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
- PRLock *kdbLock = kdb->lock;
- DB *db = kdb->db;
-
- PORT_Assert(kdbLock != NULL);
- PZ_Lock(kdbLock);
-
- ret = (* db->seq)(db, key, data, flags);
-
- prstat = PZ_Unlock(kdbLock);
-
- return(ret);
-}
-
-static void
-keydb_Close(NSSLOWKEYDBHandle *kdb)
-{
- PRStatus prstat;
- PRLock *kdbLock = kdb->lock;
- DB *db = kdb->db;
-
- PORT_Assert(kdbLock != NULL);
- SKIP_AFTER_FORK(PZ_Lock(kdbLock));
-
- (* db->close)(db);
-
- SKIP_AFTER_FORK(prstat = PZ_Unlock(kdbLock));
-
- return;
-}
-
-/*
- * SDB Entry Points for the Key DB
- */
-
-CK_RV
-lg_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2)
-{
- NSSLOWKEYDBHandle *keydb;
- NSSLOWKEYPasswordEntry entry;
- SECStatus rv;
-
- keydb = lg_getKeyDB(sdb);
- if (keydb == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
- if (PORT_Strcmp(id,"password") != 0) {
- /* shouldn't happen */
- return CKR_GENERAL_ERROR; /* no extra data stored */
- }
- rv = nsslowkey_GetPWCheckEntry(keydb, &entry);
- if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR;
- }
- item1->len = entry.salt.len;
- PORT_Memcpy(item1->data, entry.salt.data, item1->len);
- item2->len = entry.value.len;
- PORT_Memcpy(item2->data, entry.value.data, item2->len);
- return CKR_OK;
-}
-
-CK_RV
-lg_PutMetaData(SDB *sdb, const char *id,
- const SECItem *item1, const SECItem *item2)
-{
- NSSLOWKEYDBHandle *keydb;
- NSSLOWKEYPasswordEntry entry;
- SECStatus rv;
-
- keydb = lg_getKeyDB(sdb);
- if (keydb == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
- if (PORT_Strcmp(id,"password") != 0) {
- /* shouldn't happen */
- return CKR_GENERAL_ERROR; /* no extra data stored */
- }
- entry.salt = *item1;
- entry.value = *item2;
- rv = nsslowkey_PutPWCheckEntry(keydb, &entry);
- if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR;
- }
- return CKR_OK;
-}
-
-CK_RV
-lg_Reset(SDB *sdb)
-{
- NSSLOWKEYDBHandle *keydb;
- SECStatus rv;
-
- keydb = lg_getKeyDB(sdb);
- if (keydb == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
- rv = nsslowkey_ResetKeyDB(keydb);
- if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR;
- }
- return CKR_OK;
-}
-
diff --git a/security/nss/lib/softoken/legacydb/keydbi.h b/security/nss/lib/softoken/legacydb/keydbi.h
deleted file mode 100644
index 2f70ef351..000000000
--- a/security/nss/lib/softoken/legacydb/keydbi.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * private.h - Private data structures for the software token library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _KEYDBI_H_
-#define _KEYDBI_H_
-
-#include "nspr.h"
-#include "seccomon.h"
-#include "mcom_db.h"
-
-/*
- * Handle structure for open key databases
- */
-struct NSSLOWKEYDBHandleStr {
- DB *db;
- DB *updatedb; /* used when updating an old version */
- SECItem *global_salt; /* password hashing salt for this db */
- int version; /* version of the database */
- char *appname; /* multiaccess app name */
- char *dbname; /* name of the openned DB */
- PRBool readOnly; /* is the DB read only */
- PRLock *lock;
- PRInt32 ref; /* reference count */
-};
-
-/*
-** Typedef for callback for traversing key database.
-** "key" is the key used to index the data in the database (nickname)
-** "data" is the key data
-** "pdata" is the user's data
-*/
-typedef SECStatus (* NSSLOWKEYTraverseKeysFunc)(DBT *key, DBT *data, void *pdata);
-
-
-SEC_BEGIN_PROTOS
-
-/*
-** Traverse the entire key database, and pass the nicknames and keys to a
-** user supplied function.
-** "f" is the user function to call for each key
-** "udata" is the user's data, which is passed through to "f"
-*/
-extern SECStatus nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle,
- NSSLOWKEYTraverseKeysFunc f,
- void *udata);
-
-SEC_END_PROTOS
-
-#endif /* _KEYDBI_H_ */
diff --git a/security/nss/lib/softoken/legacydb/lgattr.c b/security/nss/lib/softoken/legacydb/lgattr.c
deleted file mode 100644
index abdbeff57..000000000
--- a/security/nss/lib/softoken/legacydb/lgattr.c
+++ /dev/null
@@ -1,1790 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Internal PKCS #11 functions. Should only be called by pkcs11.c
- */
-#include "pkcs11.h"
-#include "lgdb.h"
-
-#include "pcertt.h"
-#include "lowkeyi.h"
-#include "pcert.h"
-#include "blapi.h"
-#include "secerr.h"
-#include "secasn1.h"
-
-/*
- * Cache the object we are working on during Set's and Get's
- */
-typedef struct LGObjectCacheStr {
- CK_OBJECT_CLASS objclass;
- CK_OBJECT_HANDLE handle;
- SDB *sdb;
- void *objectInfo;
- LGFreeFunc infoFree;
- SECItem dbKey;
-} LGObjectCache;
-
-static const CK_OBJECT_HANDLE lg_classArray[] = {
- 0, CKO_PRIVATE_KEY, CKO_PUBLIC_KEY, CKO_SECRET_KEY,
- CKO_NSS_TRUST, CKO_NSS_CRL, CKO_NSS_SMIME,
- CKO_CERTIFICATE };
-
-#define handleToClass(handle) \
- lg_classArray[((handle & LG_TOKEN_TYPE_MASK))>>LG_TOKEN_TYPE_SHIFT]
-
-
-static void lg_DestroyObjectCache(LGObjectCache *obj);
-
-static LGObjectCache *
-lg_NewObjectCache(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE handle)
-{
- LGObjectCache *obj = NULL;
- SECStatus rv;
-
- obj = PORT_New(LGObjectCache);
- if (obj == NULL) {
- return NULL;
- }
-
- obj->objclass = handleToClass(handle);
- obj->handle = handle;
- obj->sdb = sdb;
- obj->objectInfo = NULL;
- obj->infoFree = NULL;
- obj->dbKey.data = NULL;
- obj->dbKey.len = 0;
- lg_DBLock(sdb);
- if (dbKey == NULL) {
- dbKey = lg_lookupTokenKeyByHandle(sdb,handle);
- }
- if (dbKey == NULL) {
- lg_DBUnlock(sdb);
- goto loser;
- }
- rv = SECITEM_CopyItem(NULL,&obj->dbKey,dbKey);
- lg_DBUnlock(sdb);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- return obj;
-loser:
- if (obj) {
- (void) lg_DestroyObjectCache(obj);
- }
- return NULL;
-
-}
-
-/*
- * free all the data associated with an object. Object reference count must
- * be 'zero'.
- */
-static void
-lg_DestroyObjectCache(LGObjectCache *obj)
-{
- if (obj->dbKey.data) {
- PORT_Free(obj->dbKey.data);
- obj->dbKey.data = NULL;
- }
- if (obj->objectInfo) {
- (*obj->infoFree)(obj->objectInfo);
- obj->objectInfo = NULL;
- obj->infoFree = NULL;
- }
- PORT_Free(obj);
-}
-/*
- * ******************** Attribute Utilities *******************************
- */
-
-static CK_RV
-lg_ULongAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, CK_ULONG value)
-{
- unsigned char *data;
- int i;
-
- if (attr->pValue == NULL) {
- attr->ulValueLen = 4;
- return CKR_OK;
- }
- if (attr->ulValueLen < 4) {
- attr->ulValueLen = (CK_ULONG) -1;
- return CKR_BUFFER_TOO_SMALL;
- }
-
- data = (unsigned char *)attr->pValue;
- for (i=0; i < 4; i++) {
- data[i] = (value >> ((3-i)*8)) & 0xff;
- }
- attr->ulValueLen = 4;
- return CKR_OK;
-}
-
-static CK_RV
-lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type,
- CK_VOID_PTR value, CK_ULONG len)
-{
-
- if (attr->pValue == NULL) {
- attr->ulValueLen = len;
- return CKR_OK;
- }
- if (attr->ulValueLen < len) {
- attr->ulValueLen = (CK_ULONG) -1;
- return CKR_BUFFER_TOO_SMALL;
- }
- PORT_Memcpy(attr->pValue,value,len);
- attr->ulValueLen = len;
- return CKR_OK;
-}
-
-static CK_RV
-lg_CopyAttributeSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
- void *value, CK_ULONG len)
-{
- unsigned char * dval = (unsigned char *)value;
- if (*dval == 0) {
- dval++;
- len--;
- }
- return lg_CopyAttribute(attribute,type,dval,len);
-}
-
-static CK_RV
-lg_CopyPrivAttribute(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
- void *value, CK_ULONG len, SDB *sdbpw)
-{
- SECItem plainText, *cipherText = NULL;
- CK_RV crv = CKR_USER_NOT_LOGGED_IN;
- SECStatus rv;
-
- plainText.data = value;
- plainText.len = len;
- rv = lg_util_encrypt(NULL, sdbpw, &plainText, &cipherText);
- if (rv != SECSuccess) {
- goto loser;
- }
- crv = lg_CopyAttribute(attribute,type,cipherText->data,cipherText->len);
-loser:
- if (cipherText) {
- SECITEM_FreeItem(cipherText,PR_TRUE);
- }
- return crv;
-}
-
-static CK_RV
-lg_CopyPrivAttrSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
- void *value, CK_ULONG len, SDB *sdbpw)
-{
- unsigned char * dval = (unsigned char *)value;
-
- if (*dval == 0) {
- dval++;
- len--;
- }
- return lg_CopyPrivAttribute(attribute,type,dval,len,sdbpw);
-}
-
-static CK_RV
-lg_invalidAttribute(CK_ATTRIBUTE *attr)
-{
- attr->ulValueLen = (CK_ULONG) -1;
- return CKR_ATTRIBUTE_TYPE_INVALID;
-}
-
-
-#define LG_DEF_ATTRIBUTE(value,len) \
- { 0, value, len }
-
-#define LG_CLONE_ATTR(attribute, type, staticAttr) \
- lg_CopyAttribute(attribute, type, staticAttr.pValue, staticAttr.ulValueLen)
-
-CK_BBOOL lg_staticTrueValue = CK_TRUE;
-CK_BBOOL lg_staticFalseValue = CK_FALSE;
-static const CK_ATTRIBUTE lg_StaticTrueAttr =
- LG_DEF_ATTRIBUTE(&lg_staticTrueValue,sizeof(lg_staticTrueValue));
-static const CK_ATTRIBUTE lg_StaticFalseAttr =
- LG_DEF_ATTRIBUTE(&lg_staticFalseValue,sizeof(lg_staticFalseValue));
-static const CK_ATTRIBUTE lg_StaticNullAttr = LG_DEF_ATTRIBUTE(NULL,0);
-char lg_StaticOneValue = 1;
-static const CK_ATTRIBUTE lg_StaticOneAttr =
- LG_DEF_ATTRIBUTE(&lg_StaticOneValue,sizeof(lg_StaticOneValue));
-
-/*
- * helper functions which get the database and call the underlying
- * low level database function.
- */
-static char *
-lg_FindKeyNicknameByPublicKey(SDB *sdb, SECItem *dbKey)
-{
- NSSLOWKEYDBHandle *keyHandle;
- char * label;
-
- keyHandle = lg_getKeyDB(sdb);
- if (!keyHandle) {
- return NULL;
- }
-
- label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey,
- sdb);
- return label;
-}
-
-
-NSSLOWKEYPrivateKey *
-lg_FindKeyByPublicKey(SDB *sdb, SECItem *dbKey)
-{
- NSSLOWKEYPrivateKey *privKey;
- NSSLOWKEYDBHandle *keyHandle;
-
- keyHandle = lg_getKeyDB(sdb);
- if (keyHandle == NULL) {
- return NULL;
- }
- privKey = nsslowkey_FindKeyByPublicKey(keyHandle, dbKey, sdb);
- if (privKey == NULL) {
- return NULL;
- }
- return privKey;
-}
-
-static certDBEntrySMime *
-lg_getSMime(LGObjectCache *obj)
-{
- certDBEntrySMime *entry;
- NSSLOWCERTCertDBHandle *certHandle;
-
- if (obj->objclass != CKO_NSS_SMIME) {
- return NULL;
- }
- if (obj->objectInfo) {
- return (certDBEntrySMime *)obj->objectInfo;
- }
-
- certHandle = lg_getCertDB(obj->sdb);
- if (!certHandle) {
- return NULL;
- }
- entry = nsslowcert_ReadDBSMimeEntry(certHandle, (char *)obj->dbKey.data);
- obj->objectInfo = (void *)entry;
- obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry;
- return entry;
-}
-
-static certDBEntryRevocation *
-lg_getCrl(LGObjectCache *obj)
-{
- certDBEntryRevocation *crl;
- PRBool isKrl;
- NSSLOWCERTCertDBHandle *certHandle;
-
- if (obj->objclass != CKO_NSS_CRL) {
- return NULL;
- }
- if (obj->objectInfo) {
- return (certDBEntryRevocation *)obj->objectInfo;
- }
-
- isKrl = (PRBool) (obj->handle == LG_TOKEN_KRL_HANDLE);
- certHandle = lg_getCertDB(obj->sdb);
- if (!certHandle) {
- return NULL;
- }
-
- crl = nsslowcert_FindCrlByKey(certHandle, &obj->dbKey, isKrl);
- obj->objectInfo = (void *)crl;
- obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry;
- return crl;
-}
-
-static NSSLOWCERTCertificate *
-lg_getCert(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
-{
- NSSLOWCERTCertificate *cert;
- CK_OBJECT_CLASS objClass = obj->objclass;
-
- if ((objClass != CKO_CERTIFICATE) && (objClass != CKO_NSS_TRUST)) {
- return NULL;
- }
- if (objClass == CKO_CERTIFICATE && obj->objectInfo) {
- return (NSSLOWCERTCertificate *)obj->objectInfo;
- }
- cert = nsslowcert_FindCertByKey(certHandle, &obj->dbKey);
- if (objClass == CKO_CERTIFICATE) {
- obj->objectInfo = (void *)cert;
- obj->infoFree = (LGFreeFunc) nsslowcert_DestroyCertificate ;
- }
- return cert;
-}
-
-static NSSLOWCERTTrust *
-lg_getTrust(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
-{
- NSSLOWCERTTrust *trust;
-
- if (obj->objclass != CKO_NSS_TRUST) {
- return NULL;
- }
- if (obj->objectInfo) {
- return (NSSLOWCERTTrust *)obj->objectInfo;
- }
- trust = nsslowcert_FindTrustByKey(certHandle, &obj->dbKey);
- obj->objectInfo = (void *)trust;
- obj->infoFree = (LGFreeFunc) nsslowcert_DestroyTrust ;
- return trust;
-}
-
-static NSSLOWKEYPublicKey *
-lg_GetPublicKey(LGObjectCache *obj)
-{
- NSSLOWKEYPublicKey *pubKey;
- NSSLOWKEYPrivateKey *privKey;
-
- if (obj->objclass != CKO_PUBLIC_KEY) {
- return NULL;
- }
- if (obj->objectInfo) {
- return (NSSLOWKEYPublicKey *)obj->objectInfo;
- }
- privKey = lg_FindKeyByPublicKey(obj->sdb, &obj->dbKey);
- if (privKey == NULL) {
- return NULL;
- }
- pubKey = lg_nsslowkey_ConvertToPublicKey(privKey);
- lg_nsslowkey_DestroyPrivateKey(privKey);
- obj->objectInfo = (void *) pubKey;
- obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPublicKey ;
- return pubKey;
-}
-
-/*
- * we need two versions of lg_GetPrivateKey. One version that takes the
- * DB handle so we can pass the handle we have already acquired in,
- * rather than going through the 'getKeyDB' code again,
- * which may fail the second time and another which just aquires
- * the key handle from the sdb (where we don't already have a key handle.
- * This version does the former.
- */
-static NSSLOWKEYPrivateKey *
-lg_GetPrivateKeyWithDB(LGObjectCache *obj, NSSLOWKEYDBHandle *keyHandle)
-{
- NSSLOWKEYPrivateKey *privKey;
-
- if ((obj->objclass != CKO_PRIVATE_KEY) &&
- (obj->objclass != CKO_SECRET_KEY)) {
- return NULL;
- }
- if (obj->objectInfo) {
- return (NSSLOWKEYPrivateKey *)obj->objectInfo;
- }
- privKey = nsslowkey_FindKeyByPublicKey(keyHandle, &obj->dbKey, obj->sdb);
- if (privKey == NULL) {
- return NULL;
- }
- obj->objectInfo = (void *) privKey;
- obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPrivateKey ;
- return privKey;
-}
-
-/* this version does the latter */
-static NSSLOWKEYPrivateKey *
-lg_GetPrivateKey(LGObjectCache *obj)
-{
- NSSLOWKEYDBHandle *keyHandle;
- NSSLOWKEYPrivateKey *privKey;
-
- keyHandle = lg_getKeyDB(obj->sdb);
- if (!keyHandle) {
- return NULL;
- }
- privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
- return privKey;
-}
-
-/* lg_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
-static SECItem *
-lg_GetPubItem(NSSLOWKEYPublicKey *pubKey) {
- SECItem *pubItem = NULL;
- /* get value to compare from the cert's public key */
- switch ( pubKey->keyType ) {
- case NSSLOWKEYRSAKey:
- pubItem = &pubKey->u.rsa.modulus;
- break;
- case NSSLOWKEYDSAKey:
- pubItem = &pubKey->u.dsa.publicValue;
- break;
- case NSSLOWKEYDHKey:
- pubItem = &pubKey->u.dh.publicValue;
- break;
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- pubItem = &pubKey->u.ec.publicValue;
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- break;
- }
- return pubItem;
-}
-
-static const SEC_ASN1Template lg_SerialTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(NSSLOWCERTCertificate,serialNumber) },
- { 0 }
-};
-
-static CK_RV
-lg_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- unsigned char hash[SHA1_LENGTH];
- CK_KEY_TYPE keyType = CKK_RSA;
-
- switch (type) {
- case CKA_KEY_TYPE:
- return lg_ULongAttribute(attribute, type, keyType);
- case CKA_ID:
- SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
- return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
- case CKA_DERIVE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_ENCRYPT:
- case CKA_VERIFY:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_MODULUS:
- return lg_CopyAttributeSigned(attribute,type,key->u.rsa.modulus.data,
- key->u.rsa.modulus.len);
- case CKA_PUBLIC_EXPONENT:
- return lg_CopyAttributeSigned(attribute, type,
- key->u.rsa.publicExponent.data,
- key->u.rsa.publicExponent.len);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- unsigned char hash[SHA1_LENGTH];
- CK_KEY_TYPE keyType = CKK_DSA;
-
- switch (type) {
- case CKA_KEY_TYPE:
- return lg_ULongAttribute(attribute, type, keyType);
- case CKA_ID:
- SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
- key->u.dsa.publicValue.len);
- return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
- case CKA_DERIVE:
- case CKA_ENCRYPT:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_VERIFY:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_VALUE:
- return lg_CopyAttributeSigned(attribute,type,
- key->u.dsa.publicValue.data,
- key->u.dsa.publicValue.len);
- case CKA_PRIME:
- return lg_CopyAttributeSigned(attribute,type,
- key->u.dsa.params.prime.data,
- key->u.dsa.params.prime.len);
- case CKA_SUBPRIME:
- return lg_CopyAttributeSigned(attribute,type,
- key->u.dsa.params.subPrime.data,
- key->u.dsa.params.subPrime.len);
- case CKA_BASE:
- return lg_CopyAttributeSigned(attribute,type,
- key->u.dsa.params.base.data,
- key->u.dsa.params.base.len);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- unsigned char hash[SHA1_LENGTH];
- CK_KEY_TYPE keyType = CKK_DH;
-
- switch (type) {
- case CKA_KEY_TYPE:
- return lg_ULongAttribute(attribute, type, keyType);
- case CKA_ID:
- SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
- return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
- case CKA_DERIVE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_ENCRYPT:
- case CKA_VERIFY:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_VALUE:
- return lg_CopyAttributeSigned(attribute,type,
- key->u.dh.publicValue.data,
- key->u.dh.publicValue.len);
- case CKA_PRIME:
- return lg_CopyAttributeSigned(attribute,type,key->u.dh.prime.data,
- key->u.dh.prime.len);
- case CKA_BASE:
- return lg_CopyAttributeSigned(attribute,type,key->u.dh.base.data,
- key->u.dh.base.len);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-#ifdef NSS_ENABLE_ECC
-static CK_RV
-lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- unsigned char hash[SHA1_LENGTH];
- CK_KEY_TYPE keyType = CKK_EC;
-
- switch (type) {
- case CKA_KEY_TYPE:
- return lg_ULongAttribute(attribute, type, keyType);
- case CKA_ID:
- SHA1_HashBuf(hash, key->u.ec.publicValue.data,
- key->u.ec.publicValue.len);
- return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
- case CKA_DERIVE:
- case CKA_VERIFY:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_ENCRYPT:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_EC_PARAMS:
- return lg_CopyAttributeSigned(attribute,type,
- key->u.ec.ecParams.DEREncoding.data,
- key->u.ec.ecParams.DEREncoding.len);
- case CKA_EC_POINT:
- if (getenv("NSS_USE_DECODED_CKA_EC_POINT")) {
- return lg_CopyAttributeSigned(attribute, type,
- key->u.ec.publicValue.data,
- key->u.ec.publicValue.len);
- } else {
- SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
- &(key->u.ec.publicValue),
- SEC_ASN1_GET(SEC_OctetStringTemplate));
- CK_RV crv;
- if (!pubValue) {
- return CKR_HOST_MEMORY;
- }
- crv = lg_CopyAttributeSigned(attribute, type,
- pubValue->data,
- pubValue->len);
- SECITEM_FreeItem(pubValue, PR_TRUE);
- return crv;
- }
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-#endif /* NSS_ENABLE_ECC */
-
-
-static CK_RV
-lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- NSSLOWKEYPublicKey *key;
- CK_RV crv;
- char *label;
-
- switch (type) {
- case CKA_PRIVATE:
- case CKA_SENSITIVE:
- case CKA_ALWAYS_SENSITIVE:
- case CKA_NEVER_EXTRACTABLE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_MODIFIABLE:
- case CKA_EXTRACTABLE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_SUBJECT:
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- case CKA_START_DATE:
- case CKA_END_DATE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- case CKA_LABEL:
- label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
- if (label == NULL) {
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- }
- crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
- PORT_Free(label);
- return crv;
- default:
- break;
- }
-
- key = lg_GetPublicKey(obj);
- if (key == NULL) {
- if (type == CKA_ID) {
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- }
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- switch (key->keyType) {
- case NSSLOWKEYRSAKey:
- return lg_FindRSAPublicKeyAttribute(key,type,attribute);
- case NSSLOWKEYDSAKey:
- return lg_FindDSAPublicKeyAttribute(key,type,attribute);
- case NSSLOWKEYDHKey:
- return lg_FindDHPublicKeyAttribute(key,type,attribute);
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- return lg_FindECPublicKeyAttribute(key,type,attribute);
-#endif /* NSS_ENABLE_ECC */
- default:
- break;
- }
-
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- NSSLOWKEYPrivateKey *key;
- char *label;
- unsigned char *keyString;
- CK_RV crv;
- int keyTypeLen;
- CK_ULONG keyLen;
- CK_KEY_TYPE keyType;
- PRUint32 keyTypeStorage;
-
- switch (type) {
- case CKA_PRIVATE:
- case CKA_SENSITIVE:
- case CKA_ALWAYS_SENSITIVE:
- case CKA_EXTRACTABLE:
- case CKA_DERIVE:
- case CKA_ENCRYPT:
- case CKA_DECRYPT:
- case CKA_SIGN:
- case CKA_VERIFY:
- case CKA_WRAP:
- case CKA_UNWRAP:
- case CKA_MODIFIABLE:
- case CKA_LOCAL:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_NEVER_EXTRACTABLE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_START_DATE:
- case CKA_END_DATE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- case CKA_LABEL:
- label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
- if (label == NULL) {
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- }
- crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
- PORT_Free(label);
- return crv;
- case CKA_ID:
- return lg_CopyAttribute(attribute,type,obj->dbKey.data,
- obj->dbKey.len);
- case CKA_KEY_TYPE:
- case CKA_VALUE_LEN:
- case CKA_VALUE:
- break;
- default:
- return lg_invalidAttribute(attribute);
- }
-
- key = lg_GetPrivateKey(obj);
- if (key == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
- switch (type) {
- case CKA_KEY_TYPE:
- /* handle legacy databases. In legacy databases key_type was stored
- * in host order, with any leading zeros stripped off. Only key types
- * under 0x1f (AES) were stored. We assume that any values which are
- * either 1 byte long (big endian), or have byte[0] between 0 and
- * 0x7f and bytes[1]-bytes[3] equal to '0' (little endian). All other
- * values are assumed to be from the new database, which is always 4
- * bytes in network order */
- keyType=0;
- keyString = key->u.rsa.coefficient.data;
- keyTypeLen = key->u.rsa.coefficient.len;
-
-
- /*
- * Because of various endian and word lengths The database may have
- * stored the keyType value in one of the following formats:
- * (kt) <= 0x1f
- * length data
- * Big Endian, pre-3.9, all lengths: 1 (kt)
- * Little Endian, pre-3.9, 32 bits: 4 (kt) 0 0 0
- * Little Endian, pre-3.9, 64 bits: 8 (kt) 0 0 0 0 0 0 0
- * All platforms, 3.9, 32 bits: 4 0 0 0 (kt)
- * Big Endian, 3.9, 64 bits: 8 0 0 0 (kt) 0 0 0 0
- * Little Endian, 3.9, 64 bits: 8 0 0 0 0 0 0 0 (kt)
- * All platforms, >= 3.9.1, all lengths: 4 (a) k1 k2 k3
- * where (a) is 0 or >= 0x80. currently (a) can only be 0.
- */
- /*
- * this key was written on a 64 bit platform with a using NSS 3.9
- * or earlier. Reduce the 64 bit possibilities above. When we are
- * through, we will only have:
- *
- * Big Endian, pre-3.9, all lengths: 1 (kt)
- * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
- * All platforms, 3.9, all lengths: 4 0 0 0 (kt)
- * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3
- */
- if (keyTypeLen == 8) {
- keyTypeStorage = *(PRUint32 *) keyString;
- if (keyTypeStorage == 0) {
- keyString += sizeof(PRUint32);
- }
- keyTypeLen = 4;
- }
- /*
- * Now Handle:
- *
- * All platforms, 3.9, all lengths: 4 0 0 0 (kt)
- * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3
- *
- * NOTE: if kt == 0 or ak1k2k3 == 0, the test fails and
- * we handle it as:
- *
- * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
- */
- if (keyTypeLen == sizeof(keyTypeStorage) &&
- (((keyString[0] & 0x80) == 0x80) ||
- !((keyString[1] == 0) && (keyString[2] == 0)
- && (keyString[3] == 0))) ) {
- PORT_Memcpy(&keyTypeStorage, keyString, sizeof(keyTypeStorage));
- keyType = (CK_KEY_TYPE) PR_ntohl(keyTypeStorage);
- } else {
- /*
- * Now Handle:
- *
- * Big Endian, pre-3.9, all lengths: 1 (kt)
- * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
- * -- KeyType == 0 all other cases ---: 4 0 0 0 0
- */
- keyType = (CK_KEY_TYPE) keyString[0] ;
- }
- return lg_ULongAttribute(attribute, type, keyType);
- case CKA_VALUE:
- return lg_CopyPrivAttribute(attribute,type,key->u.rsa.privateExponent.data,
- key->u.rsa.privateExponent.len, obj->sdb);
- case CKA_VALUE_LEN:
- keyLen=key->u.rsa.privateExponent.len;
- return lg_ULongAttribute(attribute,type, keyLen);
- }
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute, SDB *sdbpw)
-{
- unsigned char hash[SHA1_LENGTH];
- CK_KEY_TYPE keyType = CKK_RSA;
-
- switch (type) {
- case CKA_KEY_TYPE:
- return lg_ULongAttribute(attribute, type, keyType);
- case CKA_ID:
- SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
- return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
- case CKA_DERIVE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_DECRYPT:
- case CKA_SIGN:
- case CKA_SIGN_RECOVER:
- case CKA_UNWRAP:
- return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr);
- case CKA_MODULUS:
- return lg_CopyAttributeSigned(attribute,type,key->u.rsa.modulus.data,
- key->u.rsa.modulus.len);
- case CKA_PUBLIC_EXPONENT:
- return lg_CopyAttributeSigned(attribute, type,
- key->u.rsa.publicExponent.data,
- key->u.rsa.publicExponent.len);
- case CKA_PRIVATE_EXPONENT:
- return lg_CopyPrivAttrSigned(attribute,type,
- key->u.rsa.privateExponent.data,
- key->u.rsa.privateExponent.len, sdbpw);
- case CKA_PRIME_1:
- return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime1.data,
- key->u.rsa.prime1.len, sdbpw);
- case CKA_PRIME_2:
- return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime2.data,
- key->u.rsa.prime2.len, sdbpw);
- case CKA_EXPONENT_1:
- return lg_CopyPrivAttrSigned(attribute, type,
- key->u.rsa.exponent1.data,
- key->u.rsa.exponent1.len, sdbpw);
- case CKA_EXPONENT_2:
- return lg_CopyPrivAttrSigned(attribute, type,
- key->u.rsa.exponent2.data,
- key->u.rsa.exponent2.len, sdbpw);
- case CKA_COEFFICIENT:
- return lg_CopyPrivAttrSigned(attribute, type,
- key->u.rsa.coefficient.data,
- key->u.rsa.coefficient.len, sdbpw);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute, SDB *sdbpw)
-{
- unsigned char hash[SHA1_LENGTH];
- CK_KEY_TYPE keyType = CKK_DSA;
-
- switch (type) {
- case CKA_KEY_TYPE:
- return lg_ULongAttribute(attribute, type, keyType);
- case CKA_ID:
- SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
- key->u.dsa.publicValue.len);
- return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
- case CKA_DERIVE:
- case CKA_DECRYPT:
- case CKA_SIGN_RECOVER:
- case CKA_UNWRAP:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_SIGN:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_VALUE:
- return lg_CopyPrivAttrSigned(attribute, type,
- key->u.dsa.privateValue.data,
- key->u.dsa.privateValue.len, sdbpw);
- case CKA_PRIME:
- return lg_CopyAttributeSigned(attribute, type,
- key->u.dsa.params.prime.data,
- key->u.dsa.params.prime.len);
- case CKA_SUBPRIME:
- return lg_CopyAttributeSigned(attribute, type,
- key->u.dsa.params.subPrime.data,
- key->u.dsa.params.subPrime.len);
- case CKA_BASE:
- return lg_CopyAttributeSigned(attribute, type,
- key->u.dsa.params.base.data,
- key->u.dsa.params.base.len);
- case CKA_NETSCAPE_DB:
- return lg_CopyAttributeSigned(attribute, type,
- key->u.dsa.publicValue.data,
- key->u.dsa.publicValue.len);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute, SDB *sdbpw)
-{
- unsigned char hash[SHA1_LENGTH];
- CK_KEY_TYPE keyType = CKK_DH;
-
- switch (type) {
- case CKA_KEY_TYPE:
- return lg_ULongAttribute(attribute, type, keyType);
- case CKA_ID:
- SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
- return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
- case CKA_DERIVE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_DECRYPT:
- case CKA_SIGN:
- case CKA_SIGN_RECOVER:
- case CKA_UNWRAP:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_VALUE:
- return lg_CopyPrivAttrSigned(attribute, type,
- key->u.dh.privateValue.data,
- key->u.dh.privateValue.len, sdbpw);
- case CKA_PRIME:
- return lg_CopyAttributeSigned(attribute, type, key->u.dh.prime.data,
- key->u.dh.prime.len);
- case CKA_BASE:
- return lg_CopyAttributeSigned(attribute, type, key->u.dh.base.data,
- key->u.dh.base.len);
- case CKA_NETSCAPE_DB:
- return lg_CopyAttributeSigned(attribute, type,
- key->u.dh.publicValue.data,
- key->u.dh.publicValue.len);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-#ifdef NSS_ENABLE_ECC
-static CK_RV
-lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute, SDB *sdbpw)
-{
- unsigned char hash[SHA1_LENGTH];
- CK_KEY_TYPE keyType = CKK_EC;
-
- switch (type) {
- case CKA_KEY_TYPE:
- return lg_ULongAttribute(attribute, type, keyType);
- case CKA_ID:
- SHA1_HashBuf(hash,key->u.ec.publicValue.data,key->u.ec.publicValue.len);
- return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
- case CKA_DERIVE:
- case CKA_SIGN:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_DECRYPT:
- case CKA_SIGN_RECOVER:
- case CKA_UNWRAP:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_VALUE:
- return lg_CopyPrivAttrSigned(attribute, type,
- key->u.ec.privateValue.data,
- key->u.ec.privateValue.len, sdbpw);
- case CKA_EC_PARAMS:
- return lg_CopyAttributeSigned(attribute, type,
- key->u.ec.ecParams.DEREncoding.data,
- key->u.ec.ecParams.DEREncoding.len);
- case CKA_NETSCAPE_DB:
- return lg_CopyAttributeSigned(attribute, type,
- key->u.ec.publicValue.data,
- key->u.ec.publicValue.len);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-#endif /* NSS_ENABLE_ECC */
-
-static CK_RV
-lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- NSSLOWKEYPrivateKey *key;
- char *label;
- CK_RV crv;
-
- switch (type) {
- case CKA_PRIVATE:
- case CKA_SENSITIVE:
- case CKA_ALWAYS_SENSITIVE:
- case CKA_EXTRACTABLE:
- case CKA_MODIFIABLE:
- case CKA_LOCAL:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_NEVER_EXTRACTABLE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_SUBJECT:
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- case CKA_START_DATE:
- case CKA_END_DATE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- case CKA_LABEL:
- label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
- if (label == NULL) {
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- }
- crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
- PORT_Free(label);
- return crv;
- default:
- break;
- }
- key = lg_GetPrivateKey(obj);
- if (key == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
- switch (key->keyType) {
- case NSSLOWKEYRSAKey:
- return lg_FindRSAPrivateKeyAttribute(key,type,attribute,obj->sdb);
- case NSSLOWKEYDSAKey:
- return lg_FindDSAPrivateKeyAttribute(key,type,attribute,obj->sdb);
- case NSSLOWKEYDHKey:
- return lg_FindDHPrivateKeyAttribute(key,type,attribute,obj->sdb);
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- return lg_FindECPrivateKeyAttribute(key,type,attribute,obj->sdb);
-#endif /* NSS_ENABLE_ECC */
- default:
- break;
- }
-
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindSMIMEAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- certDBEntrySMime *entry;
- switch (type) {
- case CKA_PRIVATE:
- case CKA_MODIFIABLE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_NSS_EMAIL:
- return lg_CopyAttribute(attribute,type,obj->dbKey.data,
- obj->dbKey.len-1);
- case CKA_NSS_SMIME_TIMESTAMP:
- case CKA_SUBJECT:
- case CKA_VALUE:
- break;
- default:
- return lg_invalidAttribute(attribute);
- }
- entry = lg_getSMime(obj);
- if (entry == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
- switch (type) {
- case CKA_NSS_SMIME_TIMESTAMP:
- return lg_CopyAttribute(attribute,type,entry->optionsDate.data,
- entry->optionsDate.len);
- case CKA_SUBJECT:
- return lg_CopyAttribute(attribute,type,entry->subjectName.data,
- entry->subjectName.len);
- case CKA_VALUE:
- return lg_CopyAttribute(attribute,type,entry->smimeOptions.data,
- entry->smimeOptions.len);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindTrustAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- NSSLOWCERTTrust *trust;
- NSSLOWCERTCertDBHandle *certHandle;
- NSSLOWCERTCertificate *cert;
- unsigned char hash[SHA1_LENGTH];
- unsigned int trustFlags;
- CK_RV crv;
-
- switch (type) {
- case CKA_PRIVATE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_MODIFIABLE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_CERT_SHA1_HASH:
- case CKA_CERT_MD5_HASH:
- case CKA_TRUST_CLIENT_AUTH:
- case CKA_TRUST_SERVER_AUTH:
- case CKA_TRUST_EMAIL_PROTECTION:
- case CKA_TRUST_CODE_SIGNING:
- case CKA_TRUST_STEP_UP_APPROVED:
- case CKA_ISSUER:
- case CKA_SERIAL_NUMBER:
- break;
- default:
- return lg_invalidAttribute(attribute);
- }
- certHandle = lg_getCertDB(obj->sdb);
- if (!certHandle) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
- trust = lg_getTrust(obj, certHandle);
- if (trust == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
- switch (type) {
- case CKA_CERT_SHA1_HASH:
- SHA1_HashBuf(hash,trust->derCert->data,trust->derCert->len);
- return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
- case CKA_CERT_MD5_HASH:
- MD5_HashBuf(hash,trust->derCert->data,trust->derCert->len);
- return lg_CopyAttribute(attribute, type, hash, MD5_LENGTH);
- case CKA_TRUST_CLIENT_AUTH:
- trustFlags = trust->trust->sslFlags & CERTDB_TRUSTED_CLIENT_CA ?
- trust->trust->sslFlags | CERTDB_TRUSTED_CA : 0 ;
- goto trust;
- case CKA_TRUST_SERVER_AUTH:
- trustFlags = trust->trust->sslFlags;
- goto trust;
- case CKA_TRUST_EMAIL_PROTECTION:
- trustFlags = trust->trust->emailFlags;
- goto trust;
- case CKA_TRUST_CODE_SIGNING:
- trustFlags = trust->trust->objectSigningFlags;
-trust:
- if (trustFlags & CERTDB_TRUSTED_CA ) {
- return lg_ULongAttribute(attribute, type,
- CKT_NSS_TRUSTED_DELEGATOR);
- }
- if (trustFlags & CERTDB_TRUSTED) {
- return lg_ULongAttribute(attribute, type, CKT_NSS_TRUSTED);
- }
- if (trustFlags & CERTDB_MUST_VERIFY) {
- return lg_ULongAttribute(attribute, type,
- CKT_NSS_MUST_VERIFY_TRUST);
- }
- if (trustFlags & CERTDB_TRUSTED_UNKNOWN) {
- return lg_ULongAttribute(attribute, type, CKT_NSS_TRUST_UNKNOWN);
- }
- if (trustFlags & CERTDB_VALID_CA) {
- return lg_ULongAttribute(attribute, type, CKT_NSS_VALID_DELEGATOR);
- }
- if (trustFlags & CERTDB_TERMINAL_RECORD) {
- return lg_ULongAttribute(attribute, type, CKT_NSS_NOT_TRUSTED);
- }
- return lg_ULongAttribute(attribute, type, CKT_NSS_TRUST_UNKNOWN);
- case CKA_TRUST_STEP_UP_APPROVED:
- if (trust->trust->sslFlags & CERTDB_GOVT_APPROVED_CA) {
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- } else {
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- }
- default:
- break;
- }
-
-
- switch (type) {
- case CKA_ISSUER:
- cert = lg_getCert(obj, certHandle);
- if (cert == NULL) break;
- crv = lg_CopyAttribute(attribute,type,cert->derIssuer.data,
- cert->derIssuer.len);
- break;
- case CKA_SERIAL_NUMBER:
- cert = lg_getCert(obj, certHandle);
- if (cert == NULL) break;
- crv = lg_CopyAttribute(attribute,type,cert->derSN.data,
- cert->derSN.len);
- break;
- default:
- cert = NULL;
- break;
- }
- if (cert) {
- nsslowcert_DestroyCertificate(cert);
- return crv;
- }
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindCrlAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- certDBEntryRevocation *crl;
-
- switch (type) {
- case CKA_PRIVATE:
- case CKA_MODIFIABLE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_NSS_KRL:
- return ((obj->handle == LG_TOKEN_KRL_HANDLE)
- ? LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr)
- : LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr));
- case CKA_SUBJECT:
- return lg_CopyAttribute(attribute,type,obj->dbKey.data,
- obj->dbKey.len);
- case CKA_NSS_URL:
- case CKA_VALUE:
- break;
- default:
- return lg_invalidAttribute(attribute);
- }
- crl = lg_getCrl(obj);
- if (!crl) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
- switch (type) {
- case CKA_NSS_URL:
- if (crl->url == NULL) {
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- }
- return lg_CopyAttribute(attribute, type, crl->url,
- PORT_Strlen(crl->url)+1);
- case CKA_VALUE:
- return lg_CopyAttribute(attribute, type, crl->derCrl.data,
- crl->derCrl.len);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-static CK_RV
-lg_FindCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *attribute)
-{
- NSSLOWCERTCertificate *cert;
- NSSLOWCERTCertDBHandle *certHandle;
- NSSLOWKEYPublicKey *pubKey;
- unsigned char hash[SHA1_LENGTH];
- SECItem *item;
-
- switch (type) {
- case CKA_PRIVATE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
- case CKA_MODIFIABLE:
- return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
- case CKA_CERTIFICATE_TYPE:
- /* hardcoding X.509 into here */
- return lg_ULongAttribute(attribute, type, CKC_X_509);
- case CKA_VALUE:
- case CKA_ID:
- case CKA_LABEL:
- case CKA_SUBJECT:
- case CKA_ISSUER:
- case CKA_SERIAL_NUMBER:
- case CKA_NSS_EMAIL:
- break;
- default:
- return lg_invalidAttribute(attribute);
- }
-
- certHandle = lg_getCertDB(obj->sdb);
- if (certHandle == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- cert = lg_getCert(obj, certHandle);
- if (cert == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
- switch (type) {
- case CKA_VALUE:
- return lg_CopyAttribute(attribute,type,cert->derCert.data,
- cert->derCert.len);
- case CKA_ID:
- if (((cert->trust->sslFlags & CERTDB_USER) == 0) &&
- ((cert->trust->emailFlags & CERTDB_USER) == 0) &&
- ((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) {
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- }
- pubKey = nsslowcert_ExtractPublicKey(cert);
- if (pubKey == NULL) break;
- item = lg_GetPubItem(pubKey);
- if (item == NULL) {
- lg_nsslowkey_DestroyPublicKey(pubKey);
- break;
- }
- SHA1_HashBuf(hash,item->data,item->len);
- /* item is imbedded in pubKey, just free the key */
- lg_nsslowkey_DestroyPublicKey(pubKey);
- return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
- case CKA_LABEL:
- return cert->nickname
- ? lg_CopyAttribute(attribute, type, cert->nickname,
- PORT_Strlen(cert->nickname))
- : LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- case CKA_SUBJECT:
- return lg_CopyAttribute(attribute,type,cert->derSubject.data,
- cert->derSubject.len);
- case CKA_ISSUER:
- return lg_CopyAttribute(attribute,type,cert->derIssuer.data,
- cert->derIssuer.len);
- case CKA_SERIAL_NUMBER:
- return lg_CopyAttribute(attribute,type,cert->derSN.data,
- cert->derSN.len);
- case CKA_NSS_EMAIL:
- return (cert->emailAddr && cert->emailAddr[0])
- ? lg_CopyAttribute(attribute, type, cert->emailAddr,
- PORT_Strlen(cert->emailAddr))
- : LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-CK_RV
-lg_GetSingleAttribute(LGObjectCache *obj, CK_ATTRIBUTE *attribute)
-{
- /* handle the common ones */
- CK_ATTRIBUTE_TYPE type = attribute->type;
- switch (type) {
- case CKA_CLASS:
- return lg_ULongAttribute(attribute,type,obj->objclass);
- case CKA_TOKEN:
- return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr);
- case CKA_LABEL:
- if ( (obj->objclass == CKO_CERTIFICATE)
- || (obj->objclass == CKO_PRIVATE_KEY)
- || (obj->objclass == CKO_PUBLIC_KEY)
- || (obj->objclass == CKO_SECRET_KEY)) {
- break;
- }
- return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
- default:
- break;
- }
- switch (obj->objclass) {
- case CKO_CERTIFICATE:
- return lg_FindCertAttribute(obj,type,attribute);
- case CKO_NSS_CRL:
- return lg_FindCrlAttribute(obj,type,attribute);
- case CKO_NSS_TRUST:
- return lg_FindTrustAttribute(obj,type,attribute);
- case CKO_NSS_SMIME:
- return lg_FindSMIMEAttribute(obj,type,attribute);
- case CKO_PUBLIC_KEY:
- return lg_FindPublicKeyAttribute(obj,type,attribute);
- case CKO_PRIVATE_KEY:
- return lg_FindPrivateKeyAttribute(obj,type,attribute);
- case CKO_SECRET_KEY:
- return lg_FindSecretKeyAttribute(obj,type,attribute);
- default:
- break;
- }
- return lg_invalidAttribute(attribute);
-}
-
-/*
- * Fill in the attribute template based on the data in the database.
- */
-CK_RV
-lg_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE *templ,
- CK_ULONG count)
-{
- LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK);
- CK_RV crv, crvCollect = CKR_OK;
- int i;
-
- if (obj == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- for (i=0; i < count; i++) {
- crv = lg_GetSingleAttribute(obj, &templ[i]);
- if (crvCollect == CKR_OK) crvCollect = crv;
- }
-
- lg_DestroyObjectCache(obj);
- return crvCollect;
-}
-
-PRBool
-lg_cmpAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attribute)
-{
- unsigned char buf[LG_BUF_SPACE];
- CK_ATTRIBUTE testAttr;
- unsigned char *tempBuf = NULL;
- PRBool match = PR_TRUE;
- CK_RV crv;
-
- /* we're going to compare 'attribute' with the actual attribute from
- * the object. We'll use the length of 'attribute' to decide how much
- * space we need to read the test attribute. If 'attribute' doesn't give
- * enough space, then we know the values don't match and that will
- * show up as ckr != CKR_OK */
- testAttr = *attribute;
- testAttr.pValue = buf;
-
- /* if we don't have enough space, malloc it */
- if (attribute->ulValueLen > LG_BUF_SPACE) {
- tempBuf = PORT_Alloc(attribute->ulValueLen);
- if (!tempBuf) {
- return PR_FALSE;
- }
- testAttr.pValue = tempBuf;
- }
-
- /* get the attribute */
- crv = lg_GetSingleAttribute(obj, &testAttr);
- /* if the attribute was read OK, compare it */
- if ((crv != CKR_OK) || (attribute->ulValueLen != testAttr.ulValueLen) ||
- (PORT_Memcmp(attribute->pValue,testAttr.pValue,testAttr.ulValueLen)!= 0)){
- /* something didn't match, this isn't the object we are looking for */
- match = PR_FALSE;
- }
- /* free the buffer we may have allocated */
- if (tempBuf) {
- PORT_Free(tempBuf);
- }
- return match;
-}
-
-PRBool
-lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class,
- const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- PRBool match = PR_TRUE;
- LGObjectCache *obj = lg_NewObjectCache(sdb, dbKey, class);
- int i;
-
- if (obj == NULL) {
- return PR_FALSE;
- }
-
- for (i=0; i < count; i++) {
- match = lg_cmpAttribute(obj, &templ[i]);
- if (!match) {
- break;
- }
- }
-
- /* done looking, free up our cache */
- lg_DestroyObjectCache(obj);
-
- /* if we get through the whole list without finding a mismatched attribute,
- * then this object fits the criteria we are matching */
- return match;
-}
-
-static CK_RV
-lg_SetCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len)
-{
- NSSLOWCERTCertificate *cert;
- NSSLOWCERTCertDBHandle *certHandle;
- char *nickname = NULL;
- SECStatus rv;
- CK_RV crv;
-
- /* we can't change the EMAIL values, but let the
- * upper layers feel better about the fact we tried to set these */
- if (type == CKA_NSS_EMAIL) {
- return CKR_OK;
- }
-
- certHandle = lg_getCertDB(obj->sdb);
- if (certHandle == NULL) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- goto done;
- }
-
- if ((type != CKA_LABEL) && (type != CKA_ID)) {
- crv = CKR_ATTRIBUTE_READ_ONLY;
- goto done;
- }
-
- cert = lg_getCert(obj, certHandle);
- if (cert == NULL) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- goto done;
- }
-
- /* if the app is trying to set CKA_ID, it's probably because it just
- * imported the key. Look to see if we need to set the CERTDB_USER bits.
- */
- if (type == CKA_ID) {
- if (((cert->trust->sslFlags & CERTDB_USER) == 0) &&
- ((cert->trust->emailFlags & CERTDB_USER) == 0) &&
- ((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) {
- NSSLOWKEYDBHandle *keyHandle;
-
- keyHandle = lg_getKeyDB(obj->sdb);
- if (keyHandle) {
- if (nsslowkey_KeyForCertExists(keyHandle, cert)) {
- NSSLOWCERTCertTrust trust = *cert->trust;
- trust.sslFlags |= CERTDB_USER;
- trust.emailFlags |= CERTDB_USER;
- trust.objectSigningFlags |= CERTDB_USER;
- nsslowcert_ChangeCertTrust(certHandle,cert,&trust);
- }
- }
- }
- crv = CKR_OK;
- goto done;
- }
-
- /* must be CKA_LABEL */
- if (value != NULL) {
- nickname = PORT_ZAlloc(len+1);
- if (nickname == NULL) {
- crv = CKR_HOST_MEMORY;
- goto done;
- }
- PORT_Memcpy(nickname,value,len);
- nickname[len] = 0;
- }
- rv = nsslowcert_AddPermNickname(certHandle, cert, nickname);
- crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-
-done:
- if (nickname) {
- PORT_Free(nickname);
- }
- return crv;
-}
-
-static CK_RV
-lg_SetPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len,
- PRBool *writePrivate)
-{
- NSSLOWKEYPrivateKey *privKey;
- NSSLOWKEYDBHandle *keyHandle;
- char *nickname = NULL;
- SECStatus rv;
- CK_RV crv;
-
- /* we can't change the ID and we don't store the subject, but let the
- * upper layers feel better about the fact we tried to set these */
- if ((type == CKA_ID) || (type == CKA_SUBJECT) ||
- (type == CKA_LOCAL) || (type == CKA_NEVER_EXTRACTABLE) ||
- (type == CKA_ALWAYS_SENSITIVE)) {
- return CKR_OK;
- }
-
- keyHandle = lg_getKeyDB(obj->sdb);
- if (keyHandle == NULL) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- goto done;
- }
-
- privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
- if (privKey == NULL) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- goto done;
- }
-
- crv = CKR_ATTRIBUTE_READ_ONLY;
- switch(type) {
- case CKA_LABEL:
- if (value != NULL) {
- nickname = PORT_ZAlloc(len+1);
- if (nickname == NULL) {
- crv = CKR_HOST_MEMORY;
- goto done;
- }
- PORT_Memcpy(nickname,value,len);
- nickname[len] = 0;
- }
- rv = nsslowkey_UpdateNickname(keyHandle, privKey, &obj->dbKey,
- nickname, obj->sdb);
- crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
- break;
- case CKA_UNWRAP:
- case CKA_SIGN:
- case CKA_DERIVE:
- case CKA_SIGN_RECOVER:
- case CKA_DECRYPT:
- /* ignore attempts to change restrict these.
- * legacyDB ignore these flags and always presents all of them
- * that are valid as true.
- * NOTE: We only get here if the current value and the new value do
- * not match. */
- if (*(char *)value == 0) {
- crv = CKR_OK;
- }
- break;
- case CKA_VALUE:
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- /* We aren't really changing these values, we are just triggering
- * the database to update it's entry */
- *writePrivate = PR_TRUE;
- crv = CKR_OK;
- break;
- default:
- crv = CKR_ATTRIBUTE_READ_ONLY;
- break;
- }
-done:
- if (nickname) {
- PORT_Free(nickname);
- }
- return crv;
-}
-
-static CK_RV
-lg_SetPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len,
- PRBool *writePrivate)
-{
- /* we can't change the ID and we don't store the subject, but let the
- * upper layers feel better about the fact we tried to set these */
- if ((type == CKA_ID) || (type == CKA_SUBJECT) || (type == CKA_LABEL)) {
- return CKR_OK;
- }
- return CKR_ATTRIBUTE_READ_ONLY;
-}
-
-static CK_RV
-lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr)
-{
- unsigned int flags;
- CK_TRUST trust;
- NSSLOWCERTCertificate *cert;
- NSSLOWCERTCertDBHandle *certHandle;
- NSSLOWCERTCertTrust dbTrust;
- SECStatus rv;
- CK_RV crv;
-
- if (attr->type == CKA_LABEL) {
- return CKR_OK;
- }
-
- crv = lg_GetULongAttribute(attr->type, attr, 1, &trust);
- if (crv != CKR_OK) {
- return crv;
- }
- flags = lg_MapTrust(trust, (PRBool) (attr->type == CKA_TRUST_CLIENT_AUTH));
-
- certHandle = lg_getCertDB(obj->sdb);
-
- if (certHandle == NULL) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- goto done;
- }
-
- cert = lg_getCert(obj, certHandle);
- if (cert == NULL) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- goto done;
- }
- dbTrust = *cert->trust;
-
- switch (attr->type) {
- case CKA_TRUST_EMAIL_PROTECTION:
- dbTrust.emailFlags = flags |
- (cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS);
- break;
- case CKA_TRUST_CODE_SIGNING:
- dbTrust.objectSigningFlags = flags |
- (cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS);
- break;
- case CKA_TRUST_CLIENT_AUTH:
- dbTrust.sslFlags = flags | (cert->trust->sslFlags &
- (CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CA));
- break;
- case CKA_TRUST_SERVER_AUTH:
- dbTrust.sslFlags = flags | (cert->trust->sslFlags &
- (CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CLIENT_CA));
- break;
- default:
- crv = CKR_ATTRIBUTE_READ_ONLY;
- goto done;
- }
-
- rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust);
- crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
-done:
- return crv;
-}
-
-static CK_RV
-lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr,
- PRBool *writePrivate)
-{
- CK_ATTRIBUTE attribLocal;
- CK_RV crv;
-
- if ((attr->type == CKA_NETSCAPE_DB) && (obj->objclass == CKO_PRIVATE_KEY)) {
- *writePrivate = PR_TRUE;
- return CKR_OK;
- }
-
- /* Make sure the attribute exists first */
- attribLocal.type = attr->type;
- attribLocal.pValue = NULL;
- attribLocal.ulValueLen = 0;
- crv = lg_GetSingleAttribute(obj, &attribLocal);
- if (crv != CKR_OK) {
- return crv;
- }
-
- /* if we are just setting it to the value we already have,
- * allow it to happen. Let label setting go through so
- * we have the opportunity to repair any database corruption. */
- if (attr->type != CKA_LABEL) {
- if (lg_cmpAttribute(obj,attr)) {
- return CKR_OK;
- }
- }
-
- crv = CKR_ATTRIBUTE_READ_ONLY;
- switch (obj->objclass) {
- case CKO_CERTIFICATE:
- /* change NICKNAME, EMAIL, */
- crv = lg_SetCertAttribute(obj,attr->type,
- attr->pValue,attr->ulValueLen);
- break;
- case CKO_NSS_CRL:
- /* change URL */
- break;
- case CKO_NSS_TRUST:
- crv = lg_SetTrustAttribute(obj,attr);
- break;
- case CKO_PRIVATE_KEY:
- case CKO_SECRET_KEY:
- crv = lg_SetPrivateKeyAttribute(obj,attr->type,
- attr->pValue,attr->ulValueLen, writePrivate);
- break;
- case CKO_PUBLIC_KEY:
- crv = lg_SetPublicKeyAttribute(obj,attr->type,
- attr->pValue,attr->ulValueLen, writePrivate);
- break;
- }
- return crv;
-}
-
-/*
- * Fill in the attribute template based on the data in the database.
- */
-CK_RV
-lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle,
- const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK);
- CK_RV crv, crvCollect = CKR_OK;
- PRBool writePrivate = PR_FALSE;
- int i;
-
- if (obj == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- for (i=0; i < count; i++) {
- crv = lg_SetSingleAttribute(obj, &templ[i], &writePrivate);
- if (crvCollect == CKR_OK) crvCollect = crv;
- }
-
- /* Write any collected changes out for private and secret keys.
- * don't do the write for just the label */
- if (writePrivate) {
- NSSLOWKEYPrivateKey *privKey = lg_GetPrivateKey(obj);
- SECStatus rv = SECFailure;
- char * label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
-
- if (privKey) {
- rv = nsslowkey_StoreKeyByPublicKeyAlg(lg_getKeyDB(sdb), privKey,
- &obj->dbKey, label, sdb, PR_TRUE );
- }
- if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- }
- }
-
- lg_DestroyObjectCache(obj);
- return crvCollect;
-}
diff --git a/security/nss/lib/softoken/legacydb/lgcreate.c b/security/nss/lib/softoken/legacydb/lgcreate.c
deleted file mode 100644
index e4f659c71..000000000
--- a/security/nss/lib/softoken/legacydb/lgcreate.c
+++ /dev/null
@@ -1,981 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "secitem.h"
-#include "pkcs11.h"
-#include "lgdb.h"
-#include "pcert.h"
-#include "lowkeyi.h"
-#include "blapi.h"
-#include "secder.h"
-#include "secasn1.h"
-
-#include "keydbi.h"
-
-/*
- * ******************** Object Creation Utilities ***************************
- */
-
-/*
- * check the consistancy and initialize a Certificate Object
- */
-static CK_RV
-lg_createCertObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
- const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- SECItem derCert;
- NSSLOWCERTCertificate *cert;
- NSSLOWCERTCertTrust *trust = NULL;
- NSSLOWCERTCertTrust userTrust =
- { CERTDB_USER, CERTDB_USER, CERTDB_USER };
- NSSLOWCERTCertTrust defTrust =
- { CERTDB_TRUSTED_UNKNOWN,
- CERTDB_TRUSTED_UNKNOWN, CERTDB_TRUSTED_UNKNOWN };
- char *label = NULL;
- char *email = NULL;
- SECStatus rv;
- CK_RV crv;
- PRBool inDB = PR_TRUE;
- NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb);
- NSSLOWKEYDBHandle *keyHandle = NULL;
- CK_CERTIFICATE_TYPE type;
- const CK_ATTRIBUTE *attribute;
-
- /* we can't store any certs private */
- if (lg_isTrue(CKA_PRIVATE, templ, count)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* We only support X.509 Certs for now */
- crv = lg_GetULongAttribute(CKA_CERTIFICATE_TYPE, templ, count, &type);
- if (crv != CKR_OK) {
- return crv;
- }
-
- if (type != CKC_X_509) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* X.509 Certificate */
-
-
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* get the der cert */
- attribute = lg_FindAttribute(CKA_VALUE, templ, count);
- if (!attribute) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- derCert.type = 0;
- derCert.data = (unsigned char *)attribute->pValue;
- derCert.len = attribute->ulValueLen ;
-
- label = lg_getString(CKA_LABEL, templ, count);
-
- cert = nsslowcert_FindCertByDERCert(certHandle, &derCert);
- if (cert == NULL) {
- cert = nsslowcert_DecodeDERCertificate(&derCert, label);
- inDB = PR_FALSE;
- }
- if (cert == NULL) {
- if (label) PORT_Free(label);
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- keyHandle = lg_getKeyDB(sdb);
- if (keyHandle) {
- if (nsslowkey_KeyForCertExists(keyHandle,cert)) {
- trust = &userTrust;
- }
- }
-
- if (!inDB) {
- if (!trust) trust = &defTrust;
- rv = nsslowcert_AddPermCert(certHandle, cert, label, trust);
- } else {
- rv = trust ? nsslowcert_ChangeCertTrust(certHandle,cert,trust) :
- SECSuccess;
- }
-
- if (label) PORT_Free(label);
-
- if (rv != SECSuccess) {
- nsslowcert_DestroyCertificate(cert);
- return CKR_DEVICE_ERROR;
- }
-
- /*
- * Add a NULL S/MIME profile if necessary.
- */
- email = lg_getString(CKA_NSS_EMAIL, templ, count);
- if (email) {
- certDBEntrySMime *entry;
-
- entry = nsslowcert_ReadDBSMimeEntry(certHandle,email);
- if (!entry) {
- nsslowcert_SaveSMimeProfile(certHandle, email,
- &cert->derSubject, NULL, NULL);
- } else {
- nsslowcert_DestroyDBEntry((certDBEntry *)entry);
- }
- PORT_Free(email);
- }
- *handle=lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_CERT);
- nsslowcert_DestroyCertificate(cert);
-
- return CKR_OK;
-}
-
-unsigned int
-lg_MapTrust(CK_TRUST trust, PRBool clientAuth)
-{
- unsigned int trustCA = clientAuth ? CERTDB_TRUSTED_CLIENT_CA :
- CERTDB_TRUSTED_CA;
- switch (trust) {
- case CKT_NSS_TRUSTED:
- return CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED;
- case CKT_NSS_TRUSTED_DELEGATOR:
- return CERTDB_VALID_CA|trustCA;
- case CKT_NSS_MUST_VERIFY_TRUST:
- return CERTDB_MUST_VERIFY;
- case CKT_NSS_NOT_TRUSTED:
- return CERTDB_TERMINAL_RECORD;
- case CKT_NSS_VALID_DELEGATOR: /* implies must verify */
- return CERTDB_VALID_CA;
- default:
- break;
- }
- return CERTDB_TRUSTED_UNKNOWN;
-}
-
-
-/*
- * check the consistancy and initialize a Trust Object
- */
-static CK_RV
-lg_createTrustObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
- const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- const CK_ATTRIBUTE *issuer = NULL;
- const CK_ATTRIBUTE *serial = NULL;
- NSSLOWCERTCertificate *cert = NULL;
- const CK_ATTRIBUTE *trust;
- CK_TRUST sslTrust = CKT_NSS_TRUST_UNKNOWN;
- CK_TRUST clientTrust = CKT_NSS_TRUST_UNKNOWN;
- CK_TRUST emailTrust = CKT_NSS_TRUST_UNKNOWN;
- CK_TRUST signTrust = CKT_NSS_TRUST_UNKNOWN;
- CK_BBOOL stepUp;
- NSSLOWCERTCertTrust dbTrust = { 0 };
- SECStatus rv;
- NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb);
- NSSLOWCERTIssuerAndSN issuerSN;
-
- /* we can't store any certs private */
- if (lg_isTrue(CKA_PRIVATE, templ, count)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- issuer = lg_FindAttribute(CKA_ISSUER, templ, count);
- serial = lg_FindAttribute(CKA_SERIAL_NUMBER, templ, count);
-
- if (issuer && serial) {
- issuerSN.derIssuer.data = (unsigned char *)issuer->pValue;
- issuerSN.derIssuer.len = issuer->ulValueLen ;
-
- issuerSN.serialNumber.data = (unsigned char *)serial->pValue;
- issuerSN.serialNumber.len = serial->ulValueLen ;
-
- cert = nsslowcert_FindCertByIssuerAndSN(certHandle,&issuerSN);
- }
-
- if (cert == NULL) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- lg_GetULongAttribute(CKA_TRUST_SERVER_AUTH, templ, count, &sslTrust);
- lg_GetULongAttribute(CKA_TRUST_CLIENT_AUTH, templ, count, &clientTrust);
- lg_GetULongAttribute(CKA_TRUST_EMAIL_PROTECTION, templ, count, &emailTrust);
- lg_GetULongAttribute(CKA_TRUST_CODE_SIGNING, templ, count, &signTrust);
- stepUp = CK_FALSE;
- trust = lg_FindAttribute(CKA_TRUST_STEP_UP_APPROVED, templ, count);
- if (trust) {
- if (trust->ulValueLen == sizeof(CK_BBOOL)) {
- stepUp = *(CK_BBOOL*)trust->pValue;
- }
- }
-
- /* preserve certain old fields */
- if (cert->trust) {
- dbTrust.sslFlags = cert->trust->sslFlags & CERTDB_PRESERVE_TRUST_BITS;
- dbTrust.emailFlags=
- cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS;
- dbTrust.objectSigningFlags =
- cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS;
- }
-
- dbTrust.sslFlags |= lg_MapTrust(sslTrust,PR_FALSE);
- dbTrust.sslFlags |= lg_MapTrust(clientTrust,PR_TRUE);
- dbTrust.emailFlags |= lg_MapTrust(emailTrust,PR_FALSE);
- dbTrust.objectSigningFlags |= lg_MapTrust(signTrust,PR_FALSE);
- if (stepUp) {
- dbTrust.sslFlags |= CERTDB_GOVT_APPROVED_CA;
- }
-
- rv = nsslowcert_ChangeCertTrust(certHandle,cert,&dbTrust);
- *handle=lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_TRUST);
- nsslowcert_DestroyCertificate(cert);
- if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
- }
-
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Trust Object
- */
-static CK_RV
-lg_createSMimeObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
- const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- SECItem derSubj,rawProfile,rawTime,emailKey;
- SECItem *pRawProfile = NULL;
- SECItem *pRawTime = NULL;
- char *email = NULL;
- const CK_ATTRIBUTE *subject = NULL,
- *profile = NULL,
- *time = NULL;
- SECStatus rv;
- NSSLOWCERTCertDBHandle *certHandle;
- CK_RV ck_rv = CKR_OK;
-
- /* we can't store any certs private */
- if (lg_isTrue(CKA_PRIVATE,templ,count)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- certHandle = lg_getCertDB(sdb);
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* lookup SUBJECT */
- subject = lg_FindAttribute(CKA_SUBJECT,templ,count);
- PORT_Assert(subject);
- if (!subject) {
- ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
-
- derSubj.data = (unsigned char *)subject->pValue;
- derSubj.len = subject->ulValueLen ;
- derSubj.type = 0;
-
- /* lookup VALUE */
- profile = lg_FindAttribute(CKA_VALUE,templ,count);
- if (profile) {
- rawProfile.data = (unsigned char *)profile->pValue;
- rawProfile.len = profile->ulValueLen ;
- rawProfile.type = siBuffer;
- pRawProfile = &rawProfile;
- }
-
- /* lookup Time */
- time = lg_FindAttribute(CKA_NSS_SMIME_TIMESTAMP,templ,count);
- if (time) {
- rawTime.data = (unsigned char *)time->pValue;
- rawTime.len = time->ulValueLen ;
- rawTime.type = siBuffer;
- pRawTime = &rawTime;
- }
-
-
- email = lg_getString(CKA_NSS_EMAIL,templ,count);
- if (!email) {
- ck_rv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
-
- /* Store S/MIME Profile by SUBJECT */
- rv = nsslowcert_SaveSMimeProfile(certHandle, email, &derSubj,
- pRawProfile,pRawTime);
- if (rv != SECSuccess) {
- ck_rv = CKR_DEVICE_ERROR;
- goto loser;
- }
- emailKey.data = (unsigned char *)email;
- emailKey.len = PORT_Strlen(email)+1;
-
- *handle = lg_mkHandle(sdb, &emailKey, LG_TOKEN_TYPE_SMIME);
-
-loser:
- if (email) PORT_Free(email);
-
- return ck_rv;
-}
-
-/*
- * check the consistancy and initialize a Trust Object
- */
-static CK_RV
-lg_createCrlObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
- const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- PRBool isKRL = PR_FALSE;
- SECItem derSubj,derCrl;
- char *url = NULL;
- const CK_ATTRIBUTE *subject,*crl;
- SECStatus rv;
- NSSLOWCERTCertDBHandle *certHandle;
-
- certHandle = lg_getCertDB(sdb);
-
- /* we can't store any private crls */
- if (lg_isTrue(CKA_PRIVATE,templ,count)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* lookup SUBJECT */
- subject = lg_FindAttribute(CKA_SUBJECT,templ,count);
- if (!subject) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- derSubj.data = (unsigned char *)subject->pValue;
- derSubj.len = subject->ulValueLen ;
-
- /* lookup VALUE */
- crl = lg_FindAttribute(CKA_VALUE,templ,count);
- PORT_Assert(crl);
- if (!crl) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- derCrl.data = (unsigned char *)crl->pValue;
- derCrl.len = crl->ulValueLen ;
-
- url = lg_getString(CKA_NSS_URL,templ,count);
- isKRL = lg_isTrue(CKA_NSS_KRL,templ,count);
-
- /* Store CRL by SUBJECT */
- rv = nsslowcert_AddCrl(certHandle, &derCrl, &derSubj, url, isKRL);
-
- if (url) {
- PORT_Free(url);
- }
- if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
- }
-
- /* if we overwrote the existing CRL, poison the handle entry so we get
- * a new object handle */
- (void) lg_poisonHandle(sdb, &derSubj,
- isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL);
- *handle = lg_mkHandle(sdb, &derSubj,
- isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL);
-
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Public Key Object
- */
-static CK_RV
-lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
- CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE;
- CK_RV crv = CKR_OK;
- NSSLOWKEYPrivateKey *priv;
- SECItem pubKeySpace = {siBuffer, NULL, 0};
- SECItem *pubKey;
-#ifdef NSS_ENABLE_ECC
- SECItem pubKey2Space = {siBuffer, NULL, 0};
- PRArenaPool *arena = NULL;
-#endif /* NSS_ENABLE_ECC */
- NSSLOWKEYDBHandle *keyHandle = NULL;
-
-
- switch (key_type) {
- case CKK_RSA:
- pubKeyAttr = CKA_MODULUS;
- break;
-#ifdef NSS_ENABLE_ECC
- case CKK_EC:
- pubKeyAttr = CKA_EC_POINT;
- break;
-#endif /* NSS_ENABLE_ECC */
- case CKK_DSA:
- case CKK_DH:
- break;
- default:
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
-
- pubKey = &pubKeySpace;
- crv = lg_Attribute2SSecItem(NULL,pubKeyAttr,templ,count,pubKey);
- if (crv != CKR_OK) return crv;
-
-#ifdef NSS_ENABLE_ECC
- if (key_type == CKK_EC) {
- SECStatus rv;
- /*
- * for ECC, use the decoded key first.
- */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- crv = CKR_HOST_MEMORY;
- goto done;
- }
- rv= SEC_QuickDERDecodeItem(arena, &pubKey2Space,
- SEC_ASN1_GET(SEC_OctetStringTemplate),
- pubKey);
- if (rv != SECSuccess) {
- /* decode didn't work, just try the pubKey */
- PORT_FreeArena(arena, PR_FALSE);
- arena = NULL;
- } else {
- /* try the decoded pub key first */
- pubKey = &pubKey2Space;
- }
- }
-#endif /* NSS_ENABLE_ECC */
-
- PORT_Assert(pubKey->data);
- if (pubKey->data == NULL) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto done;
- }
- keyHandle = lg_getKeyDB(sdb);
- if (keyHandle == NULL) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- goto done;
- }
- if (keyHandle->version != 3) {
- unsigned char buf[SHA1_LENGTH];
- SHA1_HashBuf(buf,pubKey->data,pubKey->len);
- PORT_Memcpy(pubKey->data,buf,sizeof(buf));
- pubKey->len = sizeof(buf);
- }
- /* make sure the associated private key already exists */
- /* only works if we are logged in */
- priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/);
-#ifdef NSS_ENABLE_ECC
- if (priv == NULL && pubKey == &pubKey2Space) {
- /* no match on the decoded key, match the original pubkey */
- pubKey = &pubKeySpace;
- priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey,
- sdb /*password*/);
- }
-#endif
- if (priv == NULL) {
- /* the legacy database can only 'store' public keys which already
- * have their corresponding private keys in the database */
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto done;
- }
- lg_nsslowkey_DestroyPrivateKey(priv);
- crv = CKR_OK;
-
- *handle = lg_mkHandle(sdb, pubKey, LG_TOKEN_TYPE_PUB);
-
-done:
- PORT_Free(pubKeySpace.data);
-#ifdef NSS_ENABLE_ECC
- if (arena)
- PORT_FreeArena(arena, PR_FALSE);
-#endif
-
- return crv;
-}
-
-/* make a private key from a verified object */
-static NSSLOWKEYPrivateKey *
-lg_mkPrivKey(SDB *sdb, const CK_ATTRIBUTE *templ, CK_ULONG count,
- CK_KEY_TYPE key_type, CK_RV *crvp)
-{
- NSSLOWKEYPrivateKey *privKey;
- PLArenaPool *arena;
- CK_RV crv = CKR_OK;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- *crvp = CKR_HOST_MEMORY;
- return NULL;
- }
-
- privKey = (NSSLOWKEYPrivateKey *)
- PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
- if (privKey == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- *crvp = CKR_HOST_MEMORY;
- return NULL;
- }
-
- /* in future this would be a switch on key_type */
- privKey->arena = arena;
- switch (key_type) {
- case CKK_RSA:
- privKey->keyType = NSSLOWKEYRSAKey;
- crv=lg_Attribute2SSecItem(arena,CKA_MODULUS,templ,count,
- &privKey->u.rsa.modulus);
- if (crv != CKR_OK) break;
- crv=lg_Attribute2SSecItem(arena,CKA_PUBLIC_EXPONENT,templ,count,
- &privKey->u.rsa.publicExponent);
- if (crv != CKR_OK) break;
- crv=lg_PrivAttr2SSecItem(arena,CKA_PRIVATE_EXPONENT,templ,count,
- &privKey->u.rsa.privateExponent, sdb);
- if (crv != CKR_OK) break;
- crv=lg_PrivAttr2SSecItem(arena,CKA_PRIME_1,templ,count,
- &privKey->u.rsa.prime1, sdb);
- if (crv != CKR_OK) break;
- crv=lg_PrivAttr2SSecItem(arena,CKA_PRIME_2,templ,count,
- &privKey->u.rsa.prime2, sdb);
- if (crv != CKR_OK) break;
- crv=lg_PrivAttr2SSecItem(arena,CKA_EXPONENT_1,templ,count,
- &privKey->u.rsa.exponent1, sdb);
- if (crv != CKR_OK) break;
- crv=lg_PrivAttr2SSecItem(arena,CKA_EXPONENT_2,templ,count,
- &privKey->u.rsa.exponent2, sdb);
- if (crv != CKR_OK) break;
- crv=lg_PrivAttr2SSecItem(arena,CKA_COEFFICIENT,templ,count,
- &privKey->u.rsa.coefficient, sdb);
- if (crv != CKR_OK) break;
- rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,
- NSSLOWKEY_VERSION);
- if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
- break;
-
- case CKK_DSA:
- privKey->keyType = NSSLOWKEYDSAKey;
- crv = lg_Attribute2SSecItem(arena,CKA_PRIME,templ,count,
- &privKey->u.dsa.params.prime);
- if (crv != CKR_OK) break;
- crv = lg_Attribute2SSecItem(arena,CKA_SUBPRIME,templ,count,
- &privKey->u.dsa.params.subPrime);
- if (crv != CKR_OK) break;
- crv = lg_Attribute2SSecItem(arena,CKA_BASE,templ,count,
- &privKey->u.dsa.params.base);
- if (crv != CKR_OK) break;
- crv = lg_PrivAttr2SSecItem(arena,CKA_VALUE,templ,count,
- &privKey->u.dsa.privateValue, sdb);
- if (crv != CKR_OK) break;
- if (lg_hasAttribute(CKA_NETSCAPE_DB, templ,count)) {
- crv = lg_Attribute2SSecItem(arena, CKA_NETSCAPE_DB,templ,count,
- &privKey->u.dsa.publicValue);
- /* privKey was zero'd so public value is already set to NULL, 0
- * if we don't set it explicitly */
- }
- break;
-
- case CKK_DH:
- privKey->keyType = NSSLOWKEYDHKey;
- crv = lg_Attribute2SSecItem(arena,CKA_PRIME,templ,count,
- &privKey->u.dh.prime);
- if (crv != CKR_OK) break;
- crv = lg_Attribute2SSecItem(arena,CKA_BASE,templ,count,
- &privKey->u.dh.base);
- if (crv != CKR_OK) break;
- crv = lg_PrivAttr2SSecItem(arena,CKA_VALUE,templ,count,
- &privKey->u.dh.privateValue, sdb);
- if (crv != CKR_OK) break;
- if (lg_hasAttribute(CKA_NETSCAPE_DB, templ, count)) {
- crv = lg_Attribute2SSecItem(arena, CKA_NETSCAPE_DB,templ,count,
- &privKey->u.dh.publicValue);
- /* privKey was zero'd so public value is already set to NULL, 0
- * if we don't set it explicitly */
- }
- break;
-
-#ifdef NSS_ENABLE_ECC
- case CKK_EC:
- privKey->keyType = NSSLOWKEYECKey;
- crv = lg_Attribute2SSecItem(arena, CKA_EC_PARAMS,templ,count,
- &privKey->u.ec.ecParams.DEREncoding);
- if (crv != CKR_OK) break;
-
- /* Fill out the rest of the ecParams structure
- * based on the encoded params
- */
- if (LGEC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding,
- &privKey->u.ec.ecParams) != SECSuccess) {
- crv = CKR_DOMAIN_PARAMS_INVALID;
- break;
- }
- crv = lg_PrivAttr2SSecItem(arena,CKA_VALUE,templ,count,
- &privKey->u.ec.privateValue, sdb);
- if (crv != CKR_OK) break;
- if (lg_hasAttribute(CKA_NETSCAPE_DB,templ,count)) {
- crv = lg_Attribute2SSecItem(arena, CKA_NETSCAPE_DB,templ,count,
- &privKey->u.ec.publicValue);
- if (crv != CKR_OK) break;
- /* privKey was zero'd so public value is already set to NULL, 0
- * if we don't set it explicitly */
- }
- rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version,
- NSSLOWKEY_EC_PRIVATE_KEY_VERSION);
- if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
- break;
-#endif /* NSS_ENABLE_ECC */
-
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- *crvp = crv;
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
- return privKey;
-}
-
-/*
- * check the consistancy and initialize a Private Key Object
- */
-static CK_RV
-lg_createPrivateKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
- CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- NSSLOWKEYPrivateKey *privKey;
- char *label;
- SECStatus rv = SECSuccess;
- CK_RV crv = CKR_DEVICE_ERROR;
- SECItem pubKey;
- NSSLOWKEYDBHandle *keyHandle = lg_getKeyDB(sdb);
-
- if (keyHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- privKey=lg_mkPrivKey(sdb, templ,count,key_type,&crv);
- if (privKey == NULL) return crv;
- label = lg_getString(CKA_LABEL,templ,count);
-
- crv = lg_Attribute2SSecItem(NULL,CKA_NETSCAPE_DB,templ,count,&pubKey);
- if (crv != CKR_OK) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- rv = SECFailure;
- goto fail;
- }
-#ifdef notdef
- if (keyHandle->version != 3) {
- unsigned char buf[SHA1_LENGTH];
- SHA1_HashBuf(buf,pubKey.data,pubKey.len);
- PORT_Memcpy(pubKey.data,buf,sizeof(buf));
- pubKey.len = sizeof(buf);
- }
-#endif
- /* get the key type */
- if (key_type == CKK_RSA) {
- rv = RSA_PrivateKeyCheck(&privKey->u.rsa);
- if (rv == SECFailure) {
- goto fail;
- }
- }
- rv = nsslowkey_StoreKeyByPublicKey(keyHandle, privKey, &pubKey,
- label, sdb /*->password*/);
-
-fail:
- if (label) PORT_Free(label);
- *handle = lg_mkHandle(sdb,&pubKey,LG_TOKEN_TYPE_PRIV);
- if (pubKey.data) PORT_Free(pubKey.data);
- lg_nsslowkey_DestroyPrivateKey(privKey);
- if (rv != SECSuccess) return crv;
-
- return CKR_OK;
-}
-
-
-#define LG_KEY_MAX_RETRIES 10 /* don't hang if we are having problems with the rng */
-#define LG_KEY_ID_SIZE 18 /* don't use either SHA1 or MD5 sizes */
-/*
- * Secret keys must have a CKA_ID value to be stored in the database. This code
- * will generate one if there wasn't one already.
- */
-static CK_RV
-lg_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label)
-{
- unsigned int retries;
- SECStatus rv = SECSuccess;
- CK_RV crv = CKR_OK;
-
- id->data = NULL;
- if (label) {
- id->data = (unsigned char *)PORT_Strdup(label);
- if (id->data == NULL) {
- return CKR_HOST_MEMORY;
- }
- id->len = PORT_Strlen(label)+1;
- if (!nsslowkey_KeyForIDExists(handle,id)) {
- return CKR_OK;
- }
- PORT_Free(id->data);
- id->data = NULL;
- id->len = 0;
- }
- id->data = (unsigned char *)PORT_Alloc(LG_KEY_ID_SIZE);
- if (id->data == NULL) {
- return CKR_HOST_MEMORY;
- }
- id->len = LG_KEY_ID_SIZE;
-
- retries = 0;
- do {
- rv = RNG_GenerateGlobalRandomBytes(id->data,id->len);
- } while (rv == SECSuccess && nsslowkey_KeyForIDExists(handle,id) &&
- (++retries <= LG_KEY_MAX_RETRIES));
-
- if ((rv != SECSuccess) || (retries > LG_KEY_MAX_RETRIES)) {
- crv = CKR_DEVICE_ERROR; /* random number generator is bad */
- PORT_Free(id->data);
- id->data = NULL;
- id->len = 0;
- }
- return crv;
-}
-
-
-static NSSLOWKEYPrivateKey *lg_mkSecretKeyRep(const CK_ATTRIBUTE *templ,
- CK_ULONG count, CK_KEY_TYPE key_type,
- SECItem *pubkey, SDB *sdbpw)
-{
- NSSLOWKEYPrivateKey *privKey = 0;
- PLArenaPool *arena = 0;
- CK_KEY_TYPE keyType;
- PRUint32 keyTypeStorage;
- SECItem keyTypeItem;
- CK_RV crv;
- SECStatus rv;
- static unsigned char derZero[1] = { 0 };
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
-
- privKey = (NSSLOWKEYPrivateKey *)
- PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
- if (privKey == NULL) { crv = CKR_HOST_MEMORY; goto loser; }
-
- privKey->arena = arena;
-
- /* Secret keys are represented in the database as "fake" RSA keys.
- * The RSA key is marked as a secret key representation by setting the
- * public exponent field to 0, which is an invalid RSA exponent.
- * The other fields are set as follows:
- * modulus - CKA_ID value for the secret key
- * private exponent - CKA_VALUE (the key itself)
- * coefficient - CKA_KEY_TYPE, which indicates what encryption algorithm
- * is used for the key.
- * all others - set to integer 0
- */
- privKey->keyType = NSSLOWKEYRSAKey;
-
- /* The modulus is set to the key id of the symmetric key */
- privKey->u.rsa.modulus.data =
- (unsigned char *) PORT_ArenaAlloc(arena, pubkey->len);
- if (privKey->u.rsa.modulus.data == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- privKey->u.rsa.modulus.len = pubkey->len;
- PORT_Memcpy(privKey->u.rsa.modulus.data, pubkey->data, pubkey->len);
-
- /* The public exponent is set to 0 to indicate a special key */
- privKey->u.rsa.publicExponent.len = sizeof derZero;
- privKey->u.rsa.publicExponent.data = derZero;
-
- /* The private exponent is the actual key value */
- crv = lg_PrivAttr2SecItem(arena, CKA_VALUE, templ, count,
- &privKey->u.rsa.privateExponent, sdbpw);
- if (crv != CKR_OK) goto loser;
-
- /* All other fields empty - needs testing */
- privKey->u.rsa.prime1.len = sizeof derZero;
- privKey->u.rsa.prime1.data = derZero;
-
- privKey->u.rsa.prime2.len = sizeof derZero;
- privKey->u.rsa.prime2.data = derZero;
-
- privKey->u.rsa.exponent1.len = sizeof derZero;
- privKey->u.rsa.exponent1.data = derZero;
-
- privKey->u.rsa.exponent2.len = sizeof derZero;
- privKey->u.rsa.exponent2.data = derZero;
-
- /* Coeficient set to KEY_TYPE */
- crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &keyType);
- if (crv != CKR_OK) goto loser;
- /* on 64 bit platforms, we still want to store 32 bits of keyType (This is
- * safe since the PKCS #11 defines for all types are 32 bits or less). */
- keyTypeStorage = (PRUint32) keyType;
- keyTypeStorage = PR_htonl(keyTypeStorage);
- keyTypeItem.data = (unsigned char *)&keyTypeStorage;
- keyTypeItem.len = sizeof (keyTypeStorage);
- rv = SECITEM_CopyItem(arena, &privKey->u.rsa.coefficient, &keyTypeItem);
- if (rv != SECSuccess) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
-
- /* Private key version field set normally for compatibility */
- rv = DER_SetUInteger(privKey->arena,
- &privKey->u.rsa.version, NSSLOWKEY_VERSION);
- if (rv != SECSuccess) { crv = CKR_HOST_MEMORY; goto loser; }
-
-loser:
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- privKey = 0;
- }
-
- return privKey;
-}
-
-/*
- * check the consistancy and initialize a Secret Key Object
- */
-static CK_RV
-lg_createSecretKeyObject(SDB *sdb, CK_KEY_TYPE key_type,
- CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- CK_RV crv;
- NSSLOWKEYPrivateKey *privKey = NULL;
- NSSLOWKEYDBHandle *keyHandle = NULL;
- SECItem pubKey;
- char *label = NULL;
- SECStatus rv = SECSuccess;
-
- pubKey.data = 0;
-
- /* If the object is a TOKEN object, store in the database */
- keyHandle = lg_getKeyDB(sdb);
-
- if (keyHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- label = lg_getString(CKA_LABEL,templ,count);
-
- crv = lg_Attribute2SecItem(NULL,CKA_ID,templ,count,&pubKey);
- /* Should this be ID? */
- if (crv != CKR_OK) goto loser;
-
- /* if we don't have an ID, generate one */
- if (pubKey.len == 0) {
- if (pubKey.data) {
- PORT_Free(pubKey.data);
- pubKey.data = NULL;
- }
- crv = lg_GenerateSecretCKA_ID(keyHandle, &pubKey, label);
- if (crv != CKR_OK) goto loser;
- }
-
- privKey = lg_mkSecretKeyRep(templ, count, key_type, &pubKey, sdb);
- if (privKey == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
-
- rv = nsslowkey_StoreKeyByPublicKey(keyHandle,
- privKey, &pubKey, label, sdb /*->password*/);
- if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- *handle = lg_mkHandle(sdb, &pubKey, LG_TOKEN_TYPE_KEY);
-
-loser:
- if (label) PORT_Free(label);
- if (privKey) lg_nsslowkey_DestroyPrivateKey(privKey);
- if (pubKey.data) PORT_Free(pubKey.data);
-
- return crv;
-}
-
-/*
- * check the consistancy and initialize a Key Object
- */
-static CK_RV
-lg_createKeyObject(SDB *sdb, CK_OBJECT_CLASS objclass,
- CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- CK_RV crv;
- CK_KEY_TYPE key_type;
-
- /* get the key type */
- crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &key_type);
- if (crv != CKR_OK) {
- return crv;
- }
-
- switch (objclass) {
- case CKO_PUBLIC_KEY:
- return lg_createPublicKeyObject(sdb,key_type,handle,templ,count);
- case CKO_PRIVATE_KEY:
- return lg_createPrivateKeyObject(sdb,key_type,handle,templ,count);
- case CKO_SECRET_KEY:
- return lg_createSecretKeyObject(sdb,key_type,handle,templ,count);
- default:
- break;
- }
- return CKR_ATTRIBUTE_VALUE_INVALID;
-}
-
-/*
- * Parse the template and create an object stored in the DB that reflects.
- * the object specified in the database.
- */
-CK_RV
-lg_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
- const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- CK_RV crv;
- CK_OBJECT_CLASS objclass;
-
- /* get the object class */
- crv = lg_GetULongAttribute(CKA_CLASS, templ, count, &objclass);
- if (crv != CKR_OK) {
- return crv;
- }
-
- /* Now handle the specific object class.
- */
- switch (objclass) {
- case CKO_CERTIFICATE:
- crv = lg_createCertObject(sdb,handle,templ,count);
- break;
- case CKO_NSS_TRUST:
- crv = lg_createTrustObject(sdb,handle,templ,count);
- break;
- case CKO_NSS_CRL:
- crv = lg_createCrlObject(sdb,handle,templ,count);
- break;
- case CKO_NSS_SMIME:
- crv = lg_createSMimeObject(sdb,handle,templ,count);
- break;
- case CKO_PRIVATE_KEY:
- case CKO_PUBLIC_KEY:
- case CKO_SECRET_KEY:
- crv = lg_createKeyObject(sdb,objclass,handle,templ,count);
- break;
- default:
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- break;
- }
-
- return crv;
-}
-
diff --git a/security/nss/lib/softoken/legacydb/lgdb.h b/security/nss/lib/softoken/legacydb/lgdb.h
deleted file mode 100644
index c67bffa5e..000000000
--- a/security/nss/lib/softoken/legacydb/lgdb.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Internal data structures and functions used by pkcs11.c
- */
-#ifndef _LGDB_H_
-#define _LGDB_H_ 1
-
-#include "nssilock.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "lowkeyti.h"
-#include "pkcs11t.h"
-#include "sdb.h"
-#include "cdbhdl.h"
-
-
-#define MULTIACCESS "multiaccess:"
-
-
-/* path stuff (was machine dependent) used by dbinit.c and pk11db.c */
-#define PATH_SEPARATOR "/"
-#define SECMOD_DB "secmod.db"
-#define CERT_DB_FMT "%scert%s.db"
-#define KEY_DB_FMT "%skey%s.db"
-
-SEC_BEGIN_PROTOS
-
-
-/* internal utility functions used by pkcs11.c */
-extern const CK_ATTRIBUTE *lg_FindAttribute(CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count);
-extern CK_RV lg_Attribute2SecItem(PLArenaPool *,CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- SECItem *item);
-extern CK_RV lg_Attribute2SSecItem(PLArenaPool *,CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- SECItem *item);
-extern CK_RV lg_PrivAttr2SecItem(PLArenaPool *,CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- SECItem *item, SDB *sdbpw);
-extern CK_RV lg_PrivAttr2SSecItem(PLArenaPool *,CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- SECItem *item, SDB *sdbpw);
-extern CK_RV lg_GetULongAttribute(CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- CK_ULONG *out);
-extern PRBool lg_hasAttribute(CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count);
-extern PRBool lg_isTrue(CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count);
-extern PRBool lg_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass);
-extern char *lg_getString(CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count);
-extern unsigned int lg_MapTrust(CK_TRUST trust, PRBool clientAuth);
-
-/* clear out all the existing object ID to database key mappings.
- * used to reinit a token */
-extern CK_RV lg_ClearTokenKeyHashTable(SDB *sdb);
-
-
-extern void lg_FreeSearch(SDBFind *search);
-
-NSSLOWCERTCertDBHandle *lg_getCertDB(SDB *sdb);
-NSSLOWKEYDBHandle *lg_getKeyDB(SDB *sdb);
-
-const char *lg_EvaluateConfigDir(const char *configdir, char **domain);
-
-
-/*
- * object handle modifiers
- */
-#define LG_TOKEN_MASK 0xc0000000L
-#define LG_TOKEN_TYPE_MASK 0x38000000L
-#define LG_TOKEN_TYPE_SHIFT 27
-/* keydb (high bit == 0) */
-#define LG_TOKEN_TYPE_PRIV 0x08000000L
-#define LG_TOKEN_TYPE_PUB 0x10000000L
-#define LG_TOKEN_TYPE_KEY 0x18000000L
-/* certdb (high bit == 1) */
-#define LG_TOKEN_TYPE_TRUST 0x20000000L
-#define LG_TOKEN_TYPE_CRL 0x28000000L
-#define LG_TOKEN_TYPE_SMIME 0x30000000L
-#define LG_TOKEN_TYPE_CERT 0x38000000L
-
-#define LG_TOKEN_KRL_HANDLE (LG_TOKEN_TYPE_CRL|1)
-
-#define LG_SEARCH_BLOCK_SIZE 10
-#define LG_BUF_SPACE 50
-#define LG_STRICT PR_FALSE
-
-/*
- * token object utilities
- */
-void lg_addHandle(SDBFind *search, CK_OBJECT_HANDLE handle);
-PRBool lg_poisonHandle(SDB *sdb, SECItem *dbkey, CK_OBJECT_HANDLE handle);
-PRBool lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class,
- const CK_ATTRIBUTE *templ, CK_ULONG count);
-const SECItem *lg_lookupTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle);
-CK_OBJECT_HANDLE lg_mkHandle(SDB *sdb, SECItem *dbKey, CK_OBJECT_HANDLE class);
-SECStatus lg_deleteTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle);
-
-SECStatus lg_util_encrypt(PLArenaPool *arena, SDB *sdbpw,
- SECItem *plainText, SECItem **cipherText);
-SECStatus lg_util_decrypt(SDB *sdbpw,
- SECItem *cipherText, SECItem **plainText);
-PLHashTable *lg_GetHashTable(SDB *sdb);
-void lg_DBLock(SDB *sdb);
-void lg_DBUnlock(SDB *sdb);
-
-typedef void (*LGFreeFunc)(void *);
-
-
-/*
- * database functions
- */
-
-/* lg_FindObjectsInit initializes a search for token and session objects
- * that match a template. */
-CK_RV lg_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *pTemplate,
- CK_ULONG ulCount, SDBFind **search);
-/* lg_FindObjects continues a search for token and session objects
- * that match a template, obtaining additional object handles. */
-CK_RV lg_FindObjects(SDB *sdb, SDBFind *search,
- CK_OBJECT_HANDLE *phObject,CK_ULONG ulMaxObjectCount,
- CK_ULONG *pulObjectCount);
-
-/* lg_FindObjectsFinal finishes a search for token and session objects. */
-CK_RV lg_FindObjectsFinal(SDB* lgdb, SDBFind *search);
-
-/* lg_CreateObject parses the template and create an object stored in the
- * DB that reflects the object specified in the template. */
-CK_RV lg_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *handle,
- const CK_ATTRIBUTE *templ, CK_ULONG count);
-
-CK_RV lg_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
- CK_ATTRIBUTE *template, CK_ULONG count);
-CK_RV lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
- const CK_ATTRIBUTE *template, CK_ULONG count);
-CK_RV lg_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id);
-
-CK_RV lg_Close(SDB *sdb);
-CK_RV lg_Reset(SDB *sdb);
-
-/*
- * The old database doesn't share and doesn't support
- * transactions.
- */
-CK_RV lg_Begin(SDB *sdb);
-CK_RV lg_Commit(SDB *sdb);
-CK_RV lg_Abort(SDB *sdb);
-CK_RV lg_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2);
-CK_RV lg_PutMetaData(SDB *sdb, const char *id,
- const SECItem *item1, const SECItem *item2);
-
-SEC_END_PROTOS
-
-#ifndef XP_UNIX
-
-#define NO_FORK_CHECK
-
-#endif
-
-#ifndef NO_FORK_CHECK
-
-extern PRBool lg_parentForkedAfterC_Initialize;
-#define SKIP_AFTER_FORK(x) if (!lg_parentForkedAfterC_Initialize) x
-
-#else
-
-#define SKIP_AFTER_FORK(x) x
-
-#endif /* NO_FORK_CHECK */
-
-#endif /* _LGDB_H_ */
-
diff --git a/security/nss/lib/softoken/legacydb/lgdestroy.c b/security/nss/lib/softoken/legacydb/lgdestroy.c
deleted file mode 100644
index 914da5151..000000000
--- a/security/nss/lib/softoken/legacydb/lgdestroy.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Internal PKCS #11 functions. Should only be called by pkcs11.c
- */
-#include "pkcs11.h"
-#include "lgdb.h"
-#include "pcert.h"
-#include "lowkeyi.h"
-
-/*
- * remove an object.
- */
-CK_RV
-lg_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id)
-{
- CK_RV crv = CKR_OK;
- SECStatus rv;
- NSSLOWCERTCertificate *cert;
- NSSLOWCERTCertTrust tmptrust;
- PRBool isKrl;
- NSSLOWKEYDBHandle *keyHandle;
- NSSLOWCERTCertDBHandle *certHandle;
- const SECItem *dbKey;
-
- object_id &= ~LG_TOKEN_MASK;
- dbKey = lg_lookupTokenKeyByHandle(sdb,object_id);
- if (dbKey == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- /* remove the objects from the real data base */
- switch (object_id & LG_TOKEN_TYPE_MASK) {
- case LG_TOKEN_TYPE_PRIV:
- case LG_TOKEN_TYPE_KEY:
- /* KEYID is the public KEY for DSA and DH, and the MODULUS for
- * RSA */
- keyHandle = lg_getKeyDB(sdb);
- if (!keyHandle) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- break;
- }
- rv = nsslowkey_DeleteKey(keyHandle, dbKey);
- if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- }
- break;
- case LG_TOKEN_TYPE_PUB:
- break; /* public keys only exist at the behest of the priv key */
- case LG_TOKEN_TYPE_CERT:
- certHandle = lg_getCertDB(sdb);
- if (!certHandle) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- break;
- }
- cert = nsslowcert_FindCertByKey(certHandle,dbKey);
- if (cert == NULL) {
- crv = CKR_DEVICE_ERROR;
- break;
- }
- rv = nsslowcert_DeletePermCertificate(cert);
- if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- }
- nsslowcert_DestroyCertificate(cert);
- break;
- case LG_TOKEN_TYPE_CRL:
- certHandle = lg_getCertDB(sdb);
- if (!certHandle) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- break;
- }
- isKrl = (PRBool) (object_id == LG_TOKEN_KRL_HANDLE);
- rv = nsslowcert_DeletePermCRL(certHandle, dbKey, isKrl);
- if (rv == SECFailure) crv = CKR_DEVICE_ERROR;
- break;
- case LG_TOKEN_TYPE_TRUST:
- certHandle = lg_getCertDB(sdb);
- if (!certHandle) {
- crv = CKR_TOKEN_WRITE_PROTECTED;
- break;
- }
- cert = nsslowcert_FindCertByKey(certHandle, dbKey);
- if (cert == NULL) {
- crv = CKR_DEVICE_ERROR;
- break;
- }
- tmptrust = *cert->trust;
- tmptrust.sslFlags &= CERTDB_PRESERVE_TRUST_BITS;
- tmptrust.emailFlags &= CERTDB_PRESERVE_TRUST_BITS;
- tmptrust.objectSigningFlags &= CERTDB_PRESERVE_TRUST_BITS;
- tmptrust.sslFlags |= CERTDB_TRUSTED_UNKNOWN;
- tmptrust.emailFlags |= CERTDB_TRUSTED_UNKNOWN;
- tmptrust.objectSigningFlags |= CERTDB_TRUSTED_UNKNOWN;
- rv = nsslowcert_ChangeCertTrust(certHandle, cert, &tmptrust);
- if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
- nsslowcert_DestroyCertificate(cert);
- break;
- default:
- break;
- }
- lg_DBLock(sdb);
- lg_deleteTokenKeyByHandle(sdb,object_id);
- lg_DBUnlock(sdb);
-
- return crv;
-}
-
-
-
diff --git a/security/nss/lib/softoken/legacydb/lgfind.c b/security/nss/lib/softoken/legacydb/lgfind.c
deleted file mode 100644
index a512cba42..000000000
--- a/security/nss/lib/softoken/legacydb/lgfind.c
+++ /dev/null
@@ -1,915 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "secitem.h"
-#include "pkcs11.h"
-#include "lgdb.h"
-#include "lowkeyi.h"
-#include "pcert.h"
-#include "blapi.h"
-
-#include "keydbi.h"
-
-/*
- * This code maps PKCS #11 Finds to legacy database searches. This code
- * was orginally in pkcs11.c in previous versions of NSS.
- */
-
-struct SDBFindStr {
- CK_OBJECT_HANDLE *handles;
- int size;
- int index;
- int array_size;
-};
-
-
-/*
- * free a search structure
- */
-void
-lg_FreeSearch(SDBFind *search)
-{
- if (search->handles) {
- PORT_Free(search->handles);
- }
- PORT_Free(search);
-}
-
-void
-lg_addHandle(SDBFind *search, CK_OBJECT_HANDLE handle)
-{
- if (search->handles == NULL) {
- return;
- }
- if (search->size >= search->array_size) {
- search->array_size += LG_SEARCH_BLOCK_SIZE;
- search->handles = (CK_OBJECT_HANDLE *) PORT_Realloc(search->handles,
- sizeof(CK_OBJECT_HANDLE)* search->array_size);
- if (search->handles == NULL) {
- return;
- }
- }
- search->handles[search->size] = handle;
- search->size++;
-}
-
-/*
- * find any certs that may match the template and load them.
- */
-#define LG_CERT 0x00000001
-#define LG_TRUST 0x00000002
-#define LG_CRL 0x00000004
-#define LG_SMIME 0x00000008
-#define LG_PRIVATE 0x00000010
-#define LG_PUBLIC 0x00000020
-#define LG_KEY 0x00000040
-
-/*
- * structure to collect key handles.
- */
-typedef struct lgEntryDataStr {
- SDB *sdb;
- SDBFind *searchHandles;
- const CK_ATTRIBUTE *template;
- CK_ULONG templ_count;
-} lgEntryData;
-
-
-static SECStatus
-lg_crl_collect(SECItem *data, SECItem *key, certDBEntryType type, void *arg)
-{
- lgEntryData *crlData;
- CK_OBJECT_HANDLE class_handle;
- SDB *sdb;
-
- crlData = (lgEntryData *)arg;
- sdb = crlData->sdb;
-
- class_handle = (type == certDBEntryTypeRevocation) ? LG_TOKEN_TYPE_CRL :
- LG_TOKEN_KRL_HANDLE;
- if (lg_tokenMatch(sdb, key, class_handle,
- crlData->template, crlData->templ_count)) {
- lg_addHandle(crlData->searchHandles,
- lg_mkHandle(sdb,key,class_handle));
- }
- return(SECSuccess);
-}
-
-static void
-lg_searchCrls(SDB *sdb, SECItem *derSubject, PRBool isKrl,
- unsigned long classFlags, SDBFind *search,
- const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
-{
- NSSLOWCERTCertDBHandle *certHandle = NULL;
-
- certHandle = lg_getCertDB(sdb);
- if (certHandle == NULL) {
- return;
- }
- if (derSubject->data != NULL) {
- certDBEntryRevocation *crl =
- nsslowcert_FindCrlByKey(certHandle, derSubject, isKrl);
-
- if (crl != NULL) {
- lg_addHandle(search, lg_mkHandle(sdb, derSubject,
- isKrl ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL));
- nsslowcert_DestroyDBEntry((certDBEntry *)crl);
- }
- } else {
- lgEntryData crlData;
-
- /* traverse */
- crlData.sdb = sdb;
- crlData.searchHandles = search;
- crlData.template = pTemplate;
- crlData.templ_count = ulCount;
- nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeRevocation,
- lg_crl_collect, (void *)&crlData);
- nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeKeyRevocation,
- lg_crl_collect, (void *)&crlData);
- }
-}
-
-/*
- * structure to collect key handles.
- */
-typedef struct lgKeyDataStr {
- SDB *sdb;
- NSSLOWKEYDBHandle *keyHandle;
- SDBFind *searchHandles;
- SECItem *id;
- const CK_ATTRIBUTE *template;
- CK_ULONG templ_count;
- unsigned long classFlags;
- PRBool strict;
-} lgKeyData;
-
-static PRBool
-isSecretKey(NSSLOWKEYPrivateKey *privKey)
-{
- if (privKey->keyType == NSSLOWKEYRSAKey &&
- privKey->u.rsa.publicExponent.len == 1 &&
- privKey->u.rsa.publicExponent.data[0] == 0)
- return PR_TRUE;
-
- return PR_FALSE;
-}
-
-
-
-static SECStatus
-lg_key_collect(DBT *key, DBT *data, void *arg)
-{
- lgKeyData *keyData;
- NSSLOWKEYPrivateKey *privKey = NULL;
- SECItem tmpDBKey;
- SDB *sdb;
- unsigned long classFlags;
-
- keyData = (lgKeyData *)arg;
- sdb = keyData->sdb;
- classFlags = keyData->classFlags;
-
- tmpDBKey.data = key->data;
- tmpDBKey.len = key->size;
- tmpDBKey.type = siBuffer;
-
- PORT_Assert(keyData->keyHandle);
- if (!keyData->strict && keyData->id && keyData->id->data) {
- SECItem result;
- PRBool haveMatch= PR_FALSE;
- unsigned char hashKey[SHA1_LENGTH];
- result.data = hashKey;
- result.len = sizeof(hashKey);
-
- if (keyData->id->len == 0) {
- /* Make sure this isn't a LG_KEY */
- privKey = nsslowkey_FindKeyByPublicKey(keyData->keyHandle,
- &tmpDBKey, keyData->sdb/*->password*/);
- if (privKey) {
- /* turn off the unneeded class flags */
- classFlags &= isSecretKey(privKey) ? ~(LG_PRIVATE|LG_PUBLIC) :
- ~LG_KEY;
- haveMatch = (PRBool)
- ((classFlags & (LG_KEY|LG_PRIVATE|LG_PUBLIC)) != 0);
- lg_nsslowkey_DestroyPrivateKey(privKey);
- }
- } else {
- SHA1_HashBuf( hashKey, key->data, key->size ); /* match id */
- haveMatch = SECITEM_ItemsAreEqual(keyData->id,&result);
- if (!haveMatch && ((unsigned char *)key->data)[0] == 0) {
- /* This is a fix for backwards compatibility. The key
- * database indexes private keys by the public key, and
- * versions of NSS prior to 3.4 stored the public key as
- * a signed integer. The public key is now treated as an
- * unsigned integer, with no leading zero. In order to
- * correctly compute the hash of an old key, it is necessary
- * to fallback and detect the leading zero.
- */
- SHA1_HashBuf(hashKey,
- (unsigned char *)key->data + 1, key->size - 1);
- haveMatch = SECITEM_ItemsAreEqual(keyData->id,&result);
- }
- }
- if (haveMatch) {
- if (classFlags & LG_PRIVATE) {
- lg_addHandle(keyData->searchHandles,
- lg_mkHandle(sdb,&tmpDBKey,LG_TOKEN_TYPE_PRIV));
- }
- if (classFlags & LG_PUBLIC) {
- lg_addHandle(keyData->searchHandles,
- lg_mkHandle(sdb,&tmpDBKey,LG_TOKEN_TYPE_PUB));
- }
- if (classFlags & LG_KEY) {
- lg_addHandle(keyData->searchHandles,
- lg_mkHandle(sdb,&tmpDBKey,LG_TOKEN_TYPE_KEY));
- }
- }
- return SECSuccess;
- }
-
- privKey = nsslowkey_FindKeyByPublicKey(keyData->keyHandle, &tmpDBKey,
- keyData->sdb/*->password*/);
- if ( privKey == NULL ) {
- goto loser;
- }
-
- if (isSecretKey(privKey)) {
- if ((classFlags & LG_KEY) &&
- lg_tokenMatch(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_KEY,
- keyData->template, keyData->templ_count)) {
- lg_addHandle(keyData->searchHandles,
- lg_mkHandle(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_KEY));
- }
- } else {
- if ((classFlags & LG_PRIVATE) &&
- lg_tokenMatch(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_PRIV,
- keyData->template, keyData->templ_count)) {
- lg_addHandle(keyData->searchHandles,
- lg_mkHandle(keyData->sdb,&tmpDBKey,LG_TOKEN_TYPE_PRIV));
- }
- if ((classFlags & LG_PUBLIC) &&
- lg_tokenMatch(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_PUB,
- keyData->template, keyData->templ_count)) {
- lg_addHandle(keyData->searchHandles,
- lg_mkHandle(keyData->sdb, &tmpDBKey,LG_TOKEN_TYPE_PUB));
- }
- }
-
-loser:
- if ( privKey ) {
- lg_nsslowkey_DestroyPrivateKey(privKey);
- }
- return(SECSuccess);
-}
-
-static void
-lg_searchKeys(SDB *sdb, SECItem *key_id,
- unsigned long classFlags, SDBFind *search, PRBool mustStrict,
- const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
-{
- NSSLOWKEYDBHandle *keyHandle = NULL;
- NSSLOWKEYPrivateKey *privKey;
- lgKeyData keyData;
- PRBool found = PR_FALSE;
-
- keyHandle = lg_getKeyDB(sdb);
- if (keyHandle == NULL) {
- return;
- }
-
- if (key_id->data) {
- privKey = nsslowkey_FindKeyByPublicKey(keyHandle, key_id, sdb);
- if (privKey) {
- if ((classFlags & LG_KEY) && isSecretKey(privKey)) {
- lg_addHandle(search,
- lg_mkHandle(sdb,key_id,LG_TOKEN_TYPE_KEY));
- found = PR_TRUE;
- }
- if ((classFlags & LG_PRIVATE) && !isSecretKey(privKey)) {
- lg_addHandle(search,
- lg_mkHandle(sdb,key_id,LG_TOKEN_TYPE_PRIV));
- found = PR_TRUE;
- }
- if ((classFlags & LG_PUBLIC) && !isSecretKey(privKey)) {
- lg_addHandle(search,
- lg_mkHandle(sdb,key_id,LG_TOKEN_TYPE_PUB));
- found = PR_TRUE;
- }
- lg_nsslowkey_DestroyPrivateKey(privKey);
- }
- /* don't do the traversal if we have an up to date db */
- if (keyHandle->version != 3) {
- goto loser;
- }
- /* don't do the traversal if it can't possibly be the correct id */
- /* all soft token id's are SHA1_HASH_LEN's */
- if (key_id->len != SHA1_LENGTH) {
- goto loser;
- }
- if (found) {
- /* if we already found some keys, don't do the traversal */
- goto loser;
- }
- }
- keyData.sdb = sdb;
- keyData.keyHandle = keyHandle;
- keyData.searchHandles = search;
- keyData.id = key_id;
- keyData.template = pTemplate;
- keyData.templ_count = ulCount;
- keyData.classFlags = classFlags;
- keyData.strict = mustStrict ? mustStrict : LG_STRICT;
-
- nsslowkey_TraverseKeys(keyHandle, lg_key_collect, &keyData);
-
-loser:
- return;
-}
-
-/*
- * structure to collect certs into
- */
-typedef struct lgCertDataStr {
- SDB *sdb;
- int cert_count;
- int max_cert_count;
- NSSLOWCERTCertificate **certs;
- const CK_ATTRIBUTE *template;
- CK_ULONG templ_count;
- unsigned long classFlags;
- PRBool strict;
-} lgCertData;
-
-/*
- * collect all the certs from the traverse call.
- */
-static SECStatus
-lg_cert_collect(NSSLOWCERTCertificate *cert,void *arg)
-{
- lgCertData *cd = (lgCertData *)arg;
-
- if (cert == NULL) {
- return SECSuccess;
- }
-
- if (cd->certs == NULL) {
- return SECFailure;
- }
-
- if (cd->strict) {
- if ((cd->classFlags & LG_CERT) && !lg_tokenMatch(cd->sdb,
- &cert->certKey, LG_TOKEN_TYPE_CERT, cd->template,cd->templ_count)) {
- return SECSuccess;
- }
- if ((cd->classFlags & LG_TRUST) && !lg_tokenMatch(cd->sdb,
- &cert->certKey, LG_TOKEN_TYPE_TRUST,
- cd->template, cd->templ_count)) {
- return SECSuccess;
- }
- }
-
- /* allocate more space if we need it. This should only happen in
- * the general traversal case */
- if (cd->cert_count >= cd->max_cert_count) {
- int size;
- cd->max_cert_count += LG_SEARCH_BLOCK_SIZE;
- size = cd->max_cert_count * sizeof (NSSLOWCERTCertificate *);
- cd->certs = (NSSLOWCERTCertificate **)PORT_Realloc(cd->certs,size);
- if (cd->certs == NULL) {
- return SECFailure;
- }
- }
-
- cd->certs[cd->cert_count++] = nsslowcert_DupCertificate(cert);
- return SECSuccess;
-}
-
-/* provide impedence matching ... */
-static SECStatus
-lg_cert_collect2(NSSLOWCERTCertificate *cert, SECItem *dymmy, void *arg)
-{
- return lg_cert_collect(cert, arg);
-}
-
-static void
-lg_searchSingleCert(lgCertData *certData,NSSLOWCERTCertificate *cert)
-{
- if (cert == NULL) {
- return;
- }
- if (certData->strict &&
- !lg_tokenMatch(certData->sdb, &cert->certKey, LG_TOKEN_TYPE_CERT,
- certData->template,certData->templ_count)) {
- nsslowcert_DestroyCertificate(cert);
- return;
- }
- certData->certs = (NSSLOWCERTCertificate **)
- PORT_Alloc(sizeof (NSSLOWCERTCertificate *));
- if (certData->certs == NULL) {
- nsslowcert_DestroyCertificate(cert);
- return;
- }
- certData->certs[0] = cert;
- certData->cert_count = 1;
-}
-
-static void
-lg_CertSetupData(lgCertData *certData,int count)
-{
- certData->max_cert_count = count;
-
- if (certData->max_cert_count <= 0) {
- return;
- }
- certData->certs = (NSSLOWCERTCertificate **)
- PORT_Alloc( count * sizeof(NSSLOWCERTCertificate *));
- return;
-}
-
-static void
-lg_searchCertsAndTrust(SDB *sdb, SECItem *derCert, SECItem *name,
- SECItem *derSubject, NSSLOWCERTIssuerAndSN *issuerSN,
- SECItem *email,
- unsigned long classFlags, SDBFind *handles,
- const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
-{
- NSSLOWCERTCertDBHandle *certHandle = NULL;
- lgCertData certData;
- int i;
-
- certHandle = lg_getCertDB(sdb);
- if (certHandle == NULL) return;
-
- certData.sdb = sdb;
- certData.max_cert_count = 0;
- certData.certs = NULL;
- certData.cert_count = 0;
- certData.template = pTemplate;
- certData.templ_count = ulCount;
- certData.classFlags = classFlags;
- certData.strict = LG_STRICT;
-
-
- /*
- * Find the Cert.
- */
- if (derCert->data != NULL) {
- NSSLOWCERTCertificate *cert =
- nsslowcert_FindCertByDERCert(certHandle,derCert);
- lg_searchSingleCert(&certData,cert);
- } else if (name->data != NULL) {
- char *tmp_name = (char*)PORT_Alloc(name->len+1);
- int count;
-
- if (tmp_name == NULL) {
- return;
- }
- PORT_Memcpy(tmp_name,name->data,name->len);
- tmp_name[name->len] = 0;
-
- count= nsslowcert_NumPermCertsForNickname(certHandle,tmp_name);
- lg_CertSetupData(&certData,count);
- nsslowcert_TraversePermCertsForNickname(certHandle,tmp_name,
- lg_cert_collect, &certData);
- PORT_Free(tmp_name);
- } else if (derSubject->data != NULL) {
- int count;
-
- count = nsslowcert_NumPermCertsForSubject(certHandle,derSubject);
- lg_CertSetupData(&certData,count);
- nsslowcert_TraversePermCertsForSubject(certHandle,derSubject,
- lg_cert_collect, &certData);
- } else if ((issuerSN->derIssuer.data != NULL) &&
- (issuerSN->serialNumber.data != NULL)) {
- if (classFlags & LG_CERT) {
- NSSLOWCERTCertificate *cert =
- nsslowcert_FindCertByIssuerAndSN(certHandle,issuerSN);
-
- lg_searchSingleCert(&certData,cert);
- }
- if (classFlags & LG_TRUST) {
- NSSLOWCERTTrust *trust =
- nsslowcert_FindTrustByIssuerAndSN(certHandle, issuerSN);
-
- if (trust) {
- lg_addHandle(handles,
- lg_mkHandle(sdb,&trust->dbKey,LG_TOKEN_TYPE_TRUST));
- nsslowcert_DestroyTrust(trust);
- }
- }
- } else if (email->data != NULL) {
- char *tmp_name = (char*)PORT_Alloc(email->len+1);
- certDBEntrySMime *entry = NULL;
-
- if (tmp_name == NULL) {
- return;
- }
- PORT_Memcpy(tmp_name,email->data,email->len);
- tmp_name[email->len] = 0;
-
- entry = nsslowcert_ReadDBSMimeEntry(certHandle,tmp_name);
- if (entry) {
- int count;
- SECItem *subjectName = &entry->subjectName;
-
- count = nsslowcert_NumPermCertsForSubject(certHandle, subjectName);
- lg_CertSetupData(&certData,count);
- nsslowcert_TraversePermCertsForSubject(certHandle, subjectName,
- lg_cert_collect, &certData);
-
- nsslowcert_DestroyDBEntry((certDBEntry *)entry);
- }
- PORT_Free(tmp_name);
- } else {
- /* we aren't filtering the certs, we are working on all, so turn
- * on the strict filters. */
- certData.strict = PR_TRUE;
- lg_CertSetupData(&certData,LG_SEARCH_BLOCK_SIZE);
- nsslowcert_TraversePermCerts(certHandle, lg_cert_collect2, &certData);
- }
-
- /*
- * build the handles
- */
- for (i=0 ; i < certData.cert_count ; i++) {
- NSSLOWCERTCertificate *cert = certData.certs[i];
-
- /* if we filtered it would have been on the stuff above */
- if (classFlags & LG_CERT) {
- lg_addHandle(handles,
- lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_CERT));
- }
- if ((classFlags & LG_TRUST) && nsslowcert_hasTrust(cert->trust)) {
- lg_addHandle(handles,
- lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_TRUST));
- }
- nsslowcert_DestroyCertificate(cert);
- }
-
- if (certData.certs) PORT_Free(certData.certs);
- return;
-}
-
-static SECStatus
-lg_smime_collect(SECItem *data, SECItem *key, certDBEntryType type, void *arg)
-{
- lgEntryData *smimeData;
- SDB *sdb;
-
- smimeData = (lgEntryData *)arg;
- sdb = smimeData->sdb;
-
- if (lg_tokenMatch(sdb, key, LG_TOKEN_TYPE_SMIME,
- smimeData->template, smimeData->templ_count)) {
- lg_addHandle(smimeData->searchHandles,
- lg_mkHandle(sdb,key,LG_TOKEN_TYPE_SMIME));
- }
- return(SECSuccess);
-}
-
-static void
-lg_searchSMime(SDB *sdb, SECItem *email, SDBFind *handles,
- const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
-{
- NSSLOWCERTCertDBHandle *certHandle = NULL;
- certDBEntrySMime *entry;
-
- certHandle = lg_getCertDB(sdb);
- if (certHandle == NULL) return;
-
- if (email->data != NULL) {
- char *tmp_name = (char*)PORT_Alloc(email->len+1);
-
- if (tmp_name == NULL) {
- return;
- }
- PORT_Memcpy(tmp_name,email->data,email->len);
- tmp_name[email->len] = 0;
-
- entry = nsslowcert_ReadDBSMimeEntry(certHandle,tmp_name);
- if (entry) {
- SECItem emailKey;
-
- emailKey.data = (unsigned char *)tmp_name;
- emailKey.len = PORT_Strlen(tmp_name)+1;
- emailKey.type = 0;
- lg_addHandle(handles,
- lg_mkHandle(sdb,&emailKey,LG_TOKEN_TYPE_SMIME));
- nsslowcert_DestroyDBEntry((certDBEntry *)entry);
- }
- PORT_Free(tmp_name);
- } else {
- /* traverse */
- lgEntryData smimeData;
-
- /* traverse */
- smimeData.sdb = sdb;
- smimeData.searchHandles = handles;
- smimeData.template = pTemplate;
- smimeData.templ_count = ulCount;
- nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeSMimeProfile,
- lg_smime_collect, (void *)&smimeData);
- }
- return;
-}
-
-static CK_RV
-lg_searchTokenList(SDB *sdb, SDBFind *search,
- const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
-{
- int i;
- PRBool isKrl = PR_FALSE;
- SECItem derCert = { siBuffer, NULL, 0 };
- SECItem derSubject = { siBuffer, NULL, 0 };
- SECItem name = { siBuffer, NULL, 0 };
- SECItem email = { siBuffer, NULL, 0 };
- SECItem key_id = { siBuffer, NULL, 0 };
- SECItem cert_sha1_hash = { siBuffer, NULL, 0 };
- SECItem cert_md5_hash = { siBuffer, NULL, 0 };
- NSSLOWCERTIssuerAndSN issuerSN = {
- { siBuffer, NULL, 0 },
- { siBuffer, NULL, 0 }
- };
- SECItem *copy = NULL;
- CK_CERTIFICATE_TYPE certType;
- CK_OBJECT_CLASS objectClass;
- CK_RV crv;
- unsigned long classFlags;
-
- if (lg_getCertDB(sdb) == NULL) {
- classFlags = LG_PRIVATE|LG_KEY;
- } else {
- classFlags = LG_CERT|LG_TRUST|LG_PUBLIC|LG_SMIME|LG_CRL;
- }
-
- /*
- * look for things to search on token objects for. If the right options
- * are specified, we can use them as direct indeces into the database
- * (rather than using linear searches. We can also use the attributes to
- * limit the kinds of objects we are searching for. Later we can use this
- * array to filter the remaining objects more finely.
- */
- for (i=0 ;classFlags && i < (int)ulCount; i++) {
-
- switch (pTemplate[i].type) {
- case CKA_SUBJECT:
- copy = &derSubject;
- classFlags &= (LG_CERT|LG_PRIVATE|LG_PUBLIC|LG_SMIME|LG_CRL);
- break;
- case CKA_ISSUER:
- copy = &issuerSN.derIssuer;
- classFlags &= (LG_CERT|LG_TRUST);
- break;
- case CKA_SERIAL_NUMBER:
- copy = &issuerSN.serialNumber;
- classFlags &= (LG_CERT|LG_TRUST);
- break;
- case CKA_VALUE:
- copy = &derCert;
- classFlags &= (LG_CERT|LG_CRL|LG_SMIME);
- break;
- case CKA_LABEL:
- copy = &name;
- break;
- case CKA_NETSCAPE_EMAIL:
- copy = &email;
- classFlags &= LG_SMIME|LG_CERT;
- break;
- case CKA_NETSCAPE_SMIME_TIMESTAMP:
- classFlags &= LG_SMIME;
- break;
- case CKA_CLASS:
- crv = lg_GetULongAttribute(CKA_CLASS,&pTemplate[i],1, &objectClass);
- if (crv != CKR_OK) {
- classFlags = 0;
- break;
- }
- switch (objectClass) {
- case CKO_CERTIFICATE:
- classFlags &= LG_CERT;
- break;
- case CKO_NETSCAPE_TRUST:
- classFlags &= LG_TRUST;
- break;
- case CKO_NETSCAPE_CRL:
- classFlags &= LG_CRL;
- break;
- case CKO_NETSCAPE_SMIME:
- classFlags &= LG_SMIME;
- break;
- case CKO_PRIVATE_KEY:
- classFlags &= LG_PRIVATE;
- break;
- case CKO_PUBLIC_KEY:
- classFlags &= LG_PUBLIC;
- break;
- case CKO_SECRET_KEY:
- classFlags &= LG_KEY;
- break;
- default:
- classFlags = 0;
- break;
- }
- break;
- case CKA_PRIVATE:
- if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- classFlags = 0;
- break;
- }
- if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
- classFlags &= (LG_PRIVATE|LG_KEY);
- } else {
- classFlags &= ~(LG_PRIVATE|LG_KEY);
- }
- break;
- case CKA_SENSITIVE:
- if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- classFlags = 0;
- break;
- }
- if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
- classFlags &= (LG_PRIVATE|LG_KEY);
- } else {
- classFlags = 0;
- }
- break;
- case CKA_TOKEN:
- if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- classFlags = 0;
- break;
- }
- if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_TRUE) {
- classFlags = 0;
- }
- break;
- case CKA_CERT_SHA1_HASH:
- classFlags &= LG_TRUST;
- copy = &cert_sha1_hash; break;
- case CKA_CERT_MD5_HASH:
- classFlags &= LG_TRUST;
- copy = &cert_md5_hash; break;
- case CKA_CERTIFICATE_TYPE:
- crv = lg_GetULongAttribute(CKA_CERTIFICATE_TYPE,&pTemplate[i],
- 1,&certType);
- if (crv != CKR_OK) {
- classFlags = 0;
- break;
- }
- classFlags &= LG_CERT;
- if (certType != CKC_X_509) {
- classFlags = 0;
- }
- break;
- case CKA_ID:
- copy = &key_id;
- classFlags &= (LG_CERT|LG_PRIVATE|LG_KEY|LG_PUBLIC);
- break;
- case CKA_NETSCAPE_KRL:
- if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- classFlags = 0;
- break;
- }
- classFlags &= LG_CRL;
- isKrl = (PRBool)(*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE);
- break;
- case CKA_MODIFIABLE:
- break;
- case CKA_KEY_TYPE:
- case CKA_DERIVE:
- classFlags &= LG_PUBLIC|LG_PRIVATE|LG_KEY;
- break;
- case CKA_VERIFY_RECOVER:
- classFlags &= LG_PUBLIC;
- break;
- case CKA_SIGN_RECOVER:
- classFlags &= LG_PRIVATE;
- break;
- case CKA_ENCRYPT:
- case CKA_VERIFY:
- case CKA_WRAP:
- classFlags &= LG_PUBLIC|LG_KEY;
- break;
- case CKA_DECRYPT:
- case CKA_SIGN:
- case CKA_UNWRAP:
- case CKA_ALWAYS_SENSITIVE:
- case CKA_EXTRACTABLE:
- case CKA_NEVER_EXTRACTABLE:
- classFlags &= LG_PRIVATE|LG_KEY;
- break;
- /* can't be a certificate if it doesn't match one of the above
- * attributes */
- default:
- classFlags = 0;
- break;
- }
- if (copy) {
- copy->data = (unsigned char*)pTemplate[i].pValue;
- copy->len = pTemplate[i].ulValueLen;
- }
- copy = NULL;
- }
-
- /* certs */
- if (classFlags & (LG_CERT|LG_TRUST)) {
- lg_searchCertsAndTrust(sdb,&derCert,&name,&derSubject,
- &issuerSN, &email,classFlags,search,
- pTemplate, ulCount);
- }
-
- /* keys */
- if (classFlags & (LG_PRIVATE|LG_PUBLIC|LG_KEY)) {
- PRBool mustStrict = (name.len != 0);
- lg_searchKeys(sdb, &key_id, classFlags, search,
- mustStrict, pTemplate, ulCount);
- }
-
- /* crl's */
- if (classFlags & LG_CRL) {
- lg_searchCrls(sdb, &derSubject, isKrl, classFlags, search,
- pTemplate, ulCount);
- }
- /* Add S/MIME entry stuff */
- if (classFlags & LG_SMIME) {
- lg_searchSMime(sdb, &email, search, pTemplate, ulCount);
- }
- return CKR_OK;
-}
-
-
-/* lg_FindObjectsInit initializes a search for token and session objects
- * that match a template. */
-CK_RV lg_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *pTemplate,
- CK_ULONG ulCount, SDBFind **retSearch)
-{
- SDBFind *search;
- CK_RV crv = CKR_OK;
-
- *retSearch = NULL;
-
- search = (SDBFind *)PORT_Alloc(sizeof(SDBFind));
- if (search == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- search->handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * LG_SEARCH_BLOCK_SIZE);
- if (search->handles == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- search->index = 0;
- search->size = 0;
- search->array_size = LG_SEARCH_BLOCK_SIZE;
- /* FIXME - do we still need to get Login state? */
-
- crv = lg_searchTokenList(sdb, search, pTemplate, ulCount);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- *retSearch = search;
- return CKR_OK;
-
-loser:
- if (search) {
- lg_FreeSearch(search);
- }
- return crv;
-}
-
-
-/* lg_FindObjects continues a search for token and session objects
- * that match a template, obtaining additional object handles. */
-CK_RV lg_FindObjects(SDB *sdb, SDBFind *search,
- CK_OBJECT_HANDLE *phObject,CK_ULONG ulMaxObjectCount,
- CK_ULONG *pulObjectCount)
-{
- int transfer;
- int left;
-
- *pulObjectCount = 0;
- left = search->size - search->index;
- transfer = ((int)ulMaxObjectCount > left) ? left : ulMaxObjectCount;
- if (transfer > 0) {
- PORT_Memcpy(phObject,&search->handles[search->index],
- transfer*sizeof(CK_OBJECT_HANDLE));
- } else {
- *phObject = CK_INVALID_HANDLE;
- }
-
- search->index += transfer;
- *pulObjectCount = transfer;
- return CKR_OK;
-}
-
-/* lg_FindObjectsFinal finishes a search for token and session objects. */
-CK_RV lg_FindObjectsFinal(SDB* lgdb, SDBFind *search)
-{
-
- if (search != NULL) {
- lg_FreeSearch(search);
- }
- return CKR_OK;
-}
diff --git a/security/nss/lib/softoken/legacydb/lginit.c b/security/nss/lib/softoken/legacydb/lginit.c
deleted file mode 100644
index aa1677162..000000000
--- a/security/nss/lib/softoken/legacydb/lginit.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * NSS utility functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "lowkeyi.h"
-#include "pcert.h"
-#include "keydbi.h"
-#include "lgdb.h"
-#include "secoid.h"
-#include "prenv.h"
-#include "softkver.h"
-
-/* Library identity and versioning */
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_dbm_rcsid[] = "$Header: NSS " SOFTOKEN_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_dbm_sccsid[] = "@(#)NSS " SOFTOKEN_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
-
-typedef struct LGPrivateStr {
- NSSLOWCERTCertDBHandle *certDB;
- NSSLOWKEYDBHandle *keyDB;
- PRLock *dbLock;
- PLHashTable *hashTable;
-} LGPrivate;
-
-static char *
-lg_certdb_name_cb(void *arg, int dbVersion)
-{
- const char *configdir = (const char *)arg;
- const char *dbver;
- char *smpname = NULL;
- char *dbname = NULL;
-
- switch (dbVersion) {
- case 8:
- dbver = "8";
- break;
- case 7:
- dbver = "7";
- break;
- case 6:
- dbver = "6";
- break;
- case 5:
- dbver = "5";
- break;
- case 4:
- default:
- dbver = "";
- break;
- }
-
- /* make sure we return something allocated with PORT_ so we have properly
- * matched frees at the end */
- smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver);
- if (smpname) {
- dbname = PORT_Strdup(smpname);
- PR_smprintf_free(smpname);
- }
- return dbname;
-}
-
-static char *
-lg_keydb_name_cb(void *arg, int dbVersion)
-{
- const char *configdir = (const char *)arg;
- const char *dbver;
- char *smpname = NULL;
- char *dbname = NULL;
-
- switch (dbVersion) {
- case 4:
- dbver = "4";
- break;
- case 3:
- dbver = "3";
- break;
- case 1:
- dbver = "1";
- break;
- case 2:
- default:
- dbver = "";
- break;
- }
-
- smpname = PR_smprintf(KEY_DB_FMT, configdir, dbver);
- if (smpname) {
- dbname = PORT_Strdup(smpname);
- PR_smprintf_free(smpname);
- }
- return dbname;
-}
-
-const char *
-lg_EvaluateConfigDir(const char *configdir,char **appName)
-{
- if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) {
- char *cdir;
-
- *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1);
- if (*appName == NULL) {
- return configdir;
- }
- cdir = *appName;
- while (*cdir && *cdir != ':') {
- cdir++;
- }
- if (*cdir == ':') {
- *cdir = 0;
- cdir++;
- }
- configdir = cdir;
- }
- return configdir;
-}
-
-static int rdbmapflags(int flags);
-static rdbfunc lg_rdbfunc = NULL;
-static rdbstatusfunc lg_rdbstatusfunc = NULL;
-
-/* NOTE: SHLIB_SUFFIX is defined on the command line */
-#define RDBLIB SHLIB_PREFIX"rdb."SHLIB_SUFFIX
-
-DB * rdbopen(const char *appName, const char *prefix,
- const char *type, int flags, int *status)
-{
- PRLibrary *lib;
- DB *db;
- char *disableUnload = NULL;
-
- if (lg_rdbfunc) {
- db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
- if (!db && status && lg_rdbstatusfunc) {
- *status = (*lg_rdbstatusfunc)();
- }
- return db;
- }
-
- /*
- * try to open the library.
- */
- lib = PR_LoadLibrary(RDBLIB);
-
- if (!lib) {
- return NULL;
- }
-
- /* get the entry points */
- lg_rdbstatusfunc = (rdbstatusfunc) PR_FindSymbol(lib,"rdbstatus");
- lg_rdbfunc = (rdbfunc) PR_FindSymbol(lib,"rdbopen");
- if (lg_rdbfunc) {
- db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags));
- if (!db && status && lg_rdbstatusfunc) {
- *status = (*lg_rdbstatusfunc)();
- }
- return db;
- }
-
- /* couldn't find the entry point, unload the library and fail */
- disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
- if (!disableUnload) {
- PR_UnloadLibrary(lib);
- }
- return NULL;
-}
-
-/*
- * the following data structures are from rdb.h.
- */
-struct RDBStr {
- DB db;
- int (*xactstart)(DB *db);
- int (*xactdone)(DB *db, PRBool abort);
- int version;
- int (*dbinitcomplete)(DB *db);
-};
-
-#define DB_RDB ((DBTYPE) 0xff)
-#define RDB_RDONLY 1
-#define RDB_RDWR 2
-#define RDB_CREATE 4
-
-static int
-rdbmapflags(int flags) {
- switch (flags) {
- case NO_RDONLY:
- return RDB_RDONLY;
- case NO_RDWR:
- return RDB_RDWR;
- case NO_CREATE:
- return RDB_CREATE;
- default:
- break;
- }
- return 0;
-}
-
-PRBool
-db_IsRDB(DB *db)
-{
- return (PRBool) db->type == DB_RDB;
-}
-
-int
-db_BeginTransaction(DB *db)
-{
- struct RDBStr *rdb = (struct RDBStr *)db;
- if (db->type != DB_RDB) {
- return 0;
- }
-
- return rdb->xactstart(db);
-}
-
-int
-db_FinishTransaction(DB *db, PRBool abort)
-{
- struct RDBStr *rdb = (struct RDBStr *)db;
- if (db->type != DB_RDB) {
- return 0;
- }
-
- return rdb->xactdone(db, abort);
-}
-
-static DB *
-lg_getRawDB(SDB *sdb)
-{
- NSSLOWCERTCertDBHandle *certDB;
- NSSLOWKEYDBHandle *keyDB;
-
- certDB = lg_getCertDB(sdb);
- if (certDB) {
- return certDB->permCertDB;
- }
- keyDB = lg_getKeyDB(sdb);
- if (keyDB) {
- return keyDB->db;
- }
- return NULL;
-}
-
-CK_RV
-lg_Begin(SDB *sdb)
-{
- DB *db = lg_getRawDB(sdb);
- int ret;
-
- if (db == NULL) {
- return CKR_GENERAL_ERROR; /* shouldn't happen */
- }
- ret = db_BeginTransaction(db);
- if (ret != 0) {
- return CKR_GENERAL_ERROR; /* could happen */
- }
- return CKR_OK;
-}
-
-CK_RV
-lg_Commit(SDB *sdb)
-{
- DB *db = lg_getRawDB(sdb);
- int ret;
-
- if (db == NULL) {
- return CKR_GENERAL_ERROR; /* shouldn't happen */
- }
- ret = db_FinishTransaction(db, PR_FALSE);
- if (ret != 0) {
- return CKR_GENERAL_ERROR; /* could happen */
- }
- return CKR_OK;
-}
-
-CK_RV
-lg_Abort(SDB *sdb)
-{
- DB *db = lg_getRawDB(sdb);
- int ret;
-
- if (db == NULL) {
- return CKR_GENERAL_ERROR; /* shouldn't happen */
- }
- ret = db_FinishTransaction(db, PR_TRUE);
- if (ret != 0) {
- return CKR_GENERAL_ERROR; /* could happen */
- }
- return CKR_OK;
-}
-
-int
-db_InitComplete(DB *db)
-{
- struct RDBStr *rdb = (struct RDBStr *)db;
- if (db->type != DB_RDB) {
- return 0;
- }
- /* we should have added a version number to the RDBS structure. Since we
- * didn't, we detect that we have and 'extended' structure if the rdbstatus
- * func exists */
- if (!lg_rdbstatusfunc) {
- return 0;
- }
-
- return rdb->dbinitcomplete(db);
-}
-
-
-
-SECStatus
-db_Copy(DB *dest,DB *src)
-{
- int ret;
- DBT key,data;
- ret = (*src->seq)(src, &key, &data, R_FIRST);
- if (ret) {
- return SECSuccess;
- }
-
- do {
- (void)(*dest->put)(dest,&key,&data, R_NOOVERWRITE);
- } while ( (*src->seq)(src, &key, &data, R_NEXT) == 0);
- (void)(*dest->sync)(dest,0);
-
- return SECSuccess;
-}
-
-
-static CK_RV
-lg_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
- NSSLOWCERTCertDBHandle **certdbPtr)
-{
- NSSLOWCERTCertDBHandle *certdb = NULL;
- CK_RV crv = CKR_NETSCAPE_CERTDB_FAILED;
- SECStatus rv;
- char * name = NULL;
- char * appName = NULL;
-
- if (prefix == NULL) {
- prefix = "";
- }
-
- configdir = lg_EvaluateConfigDir(configdir, &appName);
-
- name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
- if (name == NULL) goto loser;
-
- certdb = (NSSLOWCERTCertDBHandle*)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle));
- if (certdb == NULL)
- goto loser;
-
- certdb->ref = 1;
-/* fix when we get the DB in */
- rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix,
- lg_certdb_name_cb, (void *)name, PR_FALSE);
- if (rv == SECSuccess) {
- crv = CKR_OK;
- *certdbPtr = certdb;
- certdb = NULL;
- }
-loser:
- if (certdb) PR_Free(certdb);
- if (name) PR_smprintf_free(name);
- if (appName) PORT_Free(appName);
- return crv;
-}
-
-static CK_RV
-lg_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly,
- NSSLOWKEYDBHandle **keydbPtr)
-{
- NSSLOWKEYDBHandle *keydb;
- char * name = NULL;
- char * appName = NULL;
-
- if (prefix == NULL) {
- prefix = "";
- }
- configdir = lg_EvaluateConfigDir(configdir, &appName);
-
- name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
- if (name == NULL)
- return CKR_HOST_MEMORY;
- keydb = nsslowkey_OpenKeyDB(readOnly, appName, prefix,
- lg_keydb_name_cb, (void *)name);
- PR_smprintf_free(name);
- if (appName) PORT_Free(appName);
- if (keydb == NULL)
- return CKR_NETSCAPE_KEYDB_FAILED;
- *keydbPtr = keydb;
-
- return CKR_OK;
-}
-
-/*
- * Accessors for the private parts of the sdb structure.
- */
-void
-lg_DBLock(SDB *sdb)
-{
- LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
- SKIP_AFTER_FORK(PR_Lock(lgdb_p->dbLock));
-}
-
-void
-lg_DBUnlock(SDB *sdb)
-{
- LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
- SKIP_AFTER_FORK(PR_Unlock(lgdb_p->dbLock));
-}
-
-PLHashTable *
-lg_GetHashTable(SDB *sdb)
-{
- LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
- return lgdb_p->hashTable;
-}
-
-NSSLOWCERTCertDBHandle *
-lg_getCertDB(SDB *sdb)
-{
- LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
-
- return lgdb_p->certDB;
-}
-
-NSSLOWKEYDBHandle *
-lg_getKeyDB(SDB *sdb)
-{
- LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
-
- return lgdb_p->keyDB;
-}
-
-PRBool lg_parentForkedAfterC_Initialize;
-
-void lg_SetForkState(PRBool forked)
-{
- lg_parentForkedAfterC_Initialize = forked;
-}
-
-CK_RV
-lg_Close(SDB *sdb)
-{
- LGPrivate *lgdb_p = (LGPrivate *)sdb->private;
- lg_ClearTokenKeyHashTable(sdb);
- if (lgdb_p) {
- if (lgdb_p->certDB) {
- nsslowcert_ClosePermCertDB(lgdb_p->certDB);
- } else if (lgdb_p->keyDB) {
- nsslowkey_CloseKeyDB(lgdb_p->keyDB);
- }
- if (lgdb_p->dbLock) {
- SKIP_AFTER_FORK(PR_DestroyLock(lgdb_p->dbLock));
- }
- if (lgdb_p->hashTable) {
- PL_HashTableDestroy(lgdb_p->hashTable);
- }
- PORT_Free(lgdb_p);
- }
- PORT_Free(sdb);
- return CKR_OK;
-}
-
-static PLHashNumber
-lg_HashNumber(const void *key)
-{
- return (PLHashNumber) key;
-}
-
-PRIntn
-lg_CompareValues(const void *v1, const void *v2)
-{
- PLHashNumber value1 = (PLHashNumber) v1;
- PLHashNumber value2 = (PLHashNumber) v2;
- return (value1 == value2);
-}
-
-/*
- * helper function to wrap a NSSLOWCERTCertDBHandle or a NSSLOWKEYDBHandle
- * with and sdb structure.
- */
-CK_RV
-lg_init(SDB **pSdb, int flags, NSSLOWCERTCertDBHandle *certdbPtr,
- NSSLOWKEYDBHandle *keydbPtr)
-{
- SDB *sdb = NULL;
- LGPrivate *lgdb_p = NULL;
- CK_RV error = CKR_HOST_MEMORY;
-
- *pSdb = NULL;
- sdb = (SDB *) PORT_Alloc(sizeof(SDB));
- if (sdb == NULL) {
- goto loser;
- }
- lgdb_p = (LGPrivate *) PORT_Alloc(sizeof(LGPrivate));
- if (lgdb_p == NULL) {
- goto loser;
- }
- /* invariant fields */
- lgdb_p->certDB = certdbPtr;
- lgdb_p->keyDB = keydbPtr;
- lgdb_p->dbLock = PR_NewLock();
- if (lgdb_p->dbLock == NULL) {
- goto loser;
- }
- lgdb_p->hashTable = PL_NewHashTable(64, lg_HashNumber, lg_CompareValues,
- SECITEM_HashCompare, NULL, 0);
- if (lgdb_p->hashTable == NULL) {
- goto loser;
- }
-
- sdb->private = lgdb_p;
- sdb->version = 0;
- /*sdb->sdb_type = SDB_LEGACY; */
- sdb->sdb_flags = flags;
- sdb->app_private = NULL;
- sdb->sdb_FindObjectsInit = lg_FindObjectsInit;
- sdb->sdb_FindObjects = lg_FindObjects;
- sdb->sdb_FindObjectsFinal = lg_FindObjectsFinal;
- sdb->sdb_GetAttributeValue = lg_GetAttributeValue;
- sdb->sdb_SetAttributeValue = lg_SetAttributeValue;
- sdb->sdb_CreateObject = lg_CreateObject;
- sdb->sdb_DestroyObject = lg_DestroyObject;
- sdb->sdb_GetMetaData = lg_GetMetaData;
- sdb->sdb_PutMetaData = lg_PutMetaData;
- sdb->sdb_Begin = lg_Begin;
- sdb->sdb_Commit = lg_Commit;
- sdb->sdb_Abort = lg_Abort;
- sdb->sdb_Reset = lg_Reset;
- sdb->sdb_Close = lg_Close;
- sdb->sdb_SetForkState = lg_SetForkState;
-
- *pSdb = sdb;
- return CKR_OK;
-
-loser:
- if (sdb) {
- PORT_Free(sdb);
- }
- if (lgdb_p) {
- if (lgdb_p->dbLock) {
- PR_DestroyLock(lgdb_p->dbLock);
- }
- if (lgdb_p->hashTable) {
- PL_HashTableDestroy(lgdb_p->hashTable);
- }
- PORT_Free(lgdb_p);
- }
- return error;
-
-}
-
-/*
- * OK there are now lots of options here, lets go through them all:
- *
- * configdir - base directory where all the cert, key, and module datbases live.
- * certPrefix - prefix added to the beginning of the cert database example: "
- * "https-server1-"
- * keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
- * secmodName - name of the security module database (usually "secmod.db").
- * readOnly - Boolean: true if the databases are to be openned read only.
- * nocertdb - Don't open the cert DB and key DB's, just initialize the
- * Volatile certdb.
- * nomoddb - Don't open the security module DB, just initialize the
- * PKCS #11 module.
- * forceOpen - Continue to force initializations even if the databases cannot
- * be opened.
- */
-CK_RV
-legacy_Open(const char *configdir, const char *certPrefix,
- const char *keyPrefix, int certVersion, int keyVersion,
- int flags, SDB **certDB, SDB **keyDB)
-{
- CK_RV crv = CKR_OK;
- SECStatus rv;
- PRBool readOnly = (flags == SDB_RDONLY)? PR_TRUE: PR_FALSE;
- volatile char c; /* force a reference that won't get optimized away */
-
- c = __nss_dbm_rcsid[0] + __nss_dbm_sccsid[0];
-
- rv = SECOID_Init();
- if (SECSuccess != rv) {
- return CKR_DEVICE_ERROR;
- }
- nsslowcert_InitLocks();
-
- if (keyDB) *keyDB = NULL;
- if (certDB) *certDB = NULL;
-
- if (certDB) {
- NSSLOWCERTCertDBHandle *certdbPtr;
-
- crv = lg_OpenCertDB(configdir, certPrefix, readOnly, &certdbPtr);
- if (crv != CKR_OK) {
- goto loser;
- }
- crv = lg_init(certDB, flags, certdbPtr, NULL);
- if (crv != CKR_OK) {
- nsslowcert_ClosePermCertDB(certdbPtr);
- goto loser;
- }
- }
- if (keyDB) {
- NSSLOWKEYDBHandle *keydbPtr;
-
- crv = lg_OpenKeyDB(configdir, keyPrefix, readOnly, &keydbPtr);
- if (crv != CKR_OK) {
- goto loser;
- }
- crv = lg_init(keyDB, flags, NULL, keydbPtr);
- if (crv != CKR_OK) {
- nsslowkey_CloseKeyDB(keydbPtr);
- goto loser;
- }
- if (certDB && *certDB) {
- LGPrivate *lgdb_p = (LGPrivate *)(*certDB)->private;
- lgdb_p->keyDB = keydbPtr;
- }
- }
-
-loser:
- if (crv != CKR_OK) {
- if (keyDB && *keyDB) {
- lg_Close(*keyDB);
- *keyDB = NULL;
- }
- if (certDB && *certDB) {
- lg_Close(*certDB);
- *certDB = NULL;
- }
- }
- return crv;
-}
-
-CK_RV
-legacy_Shutdown(PRBool forked)
-{
- lg_SetForkState(forked);
- nsslowcert_DestroyFreeLists();
- nsslowcert_DestroyGlobalLocks();
- SECOID_Shutdown();
- lg_SetForkState(PR_FALSE);
- return CKR_OK;
-}
-
diff --git a/security/nss/lib/softoken/legacydb/lgutil.c b/security/nss/lib/softoken/legacydb/lgutil.c
deleted file mode 100644
index 1b9600f05..000000000
--- a/security/nss/lib/softoken/legacydb/lgutil.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "lgdb.h"
-#include "secerr.h"
-#include "lgglue.h"
-
-/*
- * ******************** Attribute Utilities *******************************
- */
-
-/*
- * look up and attribute structure from a type and Object structure.
- * The returned attribute is referenced and needs to be freed when
- * it is no longer needed.
- */
-const CK_ATTRIBUTE *
-lg_FindAttribute(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ,
- CK_ULONG count )
-{
- int i;
-
- for (i=0; i < count; i++) {
- if (templ[i].type == type) {
- return &templ[i];
- }
- }
- return NULL;
-}
-
-
-/*
- * return true if object has attribute
- */
-PRBool
-lg_hasAttribute(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ,
- CK_ULONG count )
-{
- if (lg_FindAttribute(type, templ, count) == NULL) {
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-/*
- * copy an attribute into a SECItem. Secitem is allocated in the specified
- * arena.
- */
-CK_RV
-lg_Attribute2SecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- SECItem *item)
-{
- int len;
- const CK_ATTRIBUTE *attribute;
-
- attribute = lg_FindAttribute(type, templ, count);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- len = attribute->ulValueLen;
-
- if (arena) {
- item->data = (unsigned char *) PORT_ArenaAlloc(arena,len);
- } else {
- item->data = (unsigned char *) PORT_Alloc(len);
- }
- if (item->data == NULL) {
- return CKR_HOST_MEMORY;
- }
- item->len = len;
- PORT_Memcpy(item->data, attribute->pValue, len);
- return CKR_OK;
-}
-
-
-/*
- * copy an unsigned attribute into a SECItem. Secitem is allocated in
- * the specified arena.
- */
-CK_RV
-lg_Attribute2SSecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- SECItem *item)
-{
- const CK_ATTRIBUTE *attribute;
- item->data = NULL;
-
- attribute = lg_FindAttribute(type, templ, count);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
-
- (void)SECITEM_AllocItem(arena, item, attribute->ulValueLen);
- if (item->data == NULL) {
- return CKR_HOST_MEMORY;
- }
- PORT_Memcpy(item->data, attribute->pValue, item->len);
- return CKR_OK;
-}
-
-/*
- * copy an unsigned attribute into a SECItem. Secitem is allocated in
- * the specified arena.
- */
-CK_RV
-lg_PrivAttr2SSecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- SECItem *item, SDB *sdbpw)
-{
- const CK_ATTRIBUTE *attribute;
- SECItem epki, *dest = NULL;
- SECStatus rv;
-
- item->data = NULL;
-
- attribute = lg_FindAttribute(type, templ, count);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
-
- epki.data = attribute->pValue;
- epki.len = attribute->ulValueLen;
-
- rv = lg_util_decrypt(sdbpw, &epki, &dest);
- if (rv != SECSuccess) {
- return CKR_USER_NOT_LOGGED_IN;
- }
- (void)SECITEM_AllocItem(arena, item, dest->len);
- if (item->data == NULL) {
- SECITEM_FreeItem(dest, PR_TRUE);
- return CKR_HOST_MEMORY;
- }
-
- PORT_Memcpy(item->data, dest->data, item->len);
- SECITEM_FreeItem(dest, PR_TRUE);
- return CKR_OK;
-}
-
-CK_RV
-lg_PrivAttr2SecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type,
- const CK_ATTRIBUTE *templ, CK_ULONG count,
- SECItem *item, SDB *sdbpw)
-{
- return lg_PrivAttr2SSecItem(arena, type, templ, count, item, sdbpw);
-}
-
-/*
- * this is only valid for CK_BBOOL type attributes. Return the state
- * of that attribute.
- */
-PRBool
-lg_isTrue(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- const CK_ATTRIBUTE *attribute;
- PRBool tok = PR_FALSE;
-
- attribute=lg_FindAttribute(type, templ, count);
- if (attribute == NULL) { return PR_FALSE; }
- tok = (PRBool)(*(CK_BBOOL *)attribute->pValue);
-
- return tok;
-}
-
-/*
- * return a null terminated string from attribute 'type'. This string
- * is allocated and needs to be freed with PORT_Free() When complete.
- */
-char *
-lg_getString(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ, CK_ULONG count)
-{
- const CK_ATTRIBUTE *attribute;
- char *label = NULL;
-
- attribute = lg_FindAttribute(type, templ, count);
- if (attribute == NULL) return NULL;
-
- if (attribute->pValue != NULL) {
- label = (char *) PORT_Alloc(attribute->ulValueLen+1);
- if (label == NULL) {
- return NULL;
- }
-
- PORT_Memcpy(label,attribute->pValue, attribute->ulValueLen);
- label[attribute->ulValueLen] = 0;
- }
- return label;
-}
-
-CK_RV
-lg_GetULongAttribute(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ,
- CK_ULONG count, CK_ULONG *longData)
-{
- const CK_ATTRIBUTE *attribute;
- CK_ULONG value = 0;
- const unsigned char *data;
- int i;
-
- attribute = lg_FindAttribute(type, templ, count);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
-
- if (attribute->ulValueLen != 4) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- data = (const unsigned char *)attribute->pValue;
- for (i=0; i < 4; i++) {
- value |= (CK_ULONG)(data[i]) << ((3-i)*8);
- }
-
- *longData = value;
- return CKR_OK;
-}
-
-/*
- * ******************** Object Utilities *******************************
- */
-
-SECStatus
-lg_deleteTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle)
-{
- SECItem *item;
- PRBool rem;
- PLHashTable *hashTable= lg_GetHashTable(sdb);
-
- item = (SECItem *)PL_HashTableLookup(hashTable, (void *)handle);
- rem = PL_HashTableRemove(hashTable,(void *)handle) ;
- if (rem && item) {
- SECITEM_FreeItem(item,PR_TRUE);
- }
- return rem ? SECSuccess : SECFailure;
-}
-
-/* must be called holding lg_DBLock(sdb) */
-static SECStatus
-lg_addTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle, SECItem *key)
-{
- PLHashEntry *entry;
- SECItem *item;
- PLHashTable *hashTable= lg_GetHashTable(sdb);
-
- item = SECITEM_DupItem(key);
- if (item == NULL) {
- return SECFailure;
- }
- entry = PL_HashTableAdd(hashTable,(void *)handle,item);
- if (entry == NULL) {
- SECITEM_FreeItem(item,PR_TRUE);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/* must be called holding lg_DBLock(sdb) */
-const SECItem *
-lg_lookupTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle)
-{
- PLHashTable *hashTable= lg_GetHashTable(sdb);
- return (const SECItem *)PL_HashTableLookup(hashTable, (void *)handle);
-}
-
-
-static PRIntn
-lg_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg)
-{
- SECItem *item = (SECItem *)entry->value;
-
- SECITEM_FreeItem(item, PR_TRUE);
- return HT_ENUMERATE_NEXT;
-}
-
-CK_RV
-lg_ClearTokenKeyHashTable(SDB *sdb)
-{
- PLHashTable *hashTable;
- lg_DBLock(sdb);
- hashTable= lg_GetHashTable(sdb);
- PL_HashTableEnumerateEntries(hashTable, lg_freeHashItem, NULL);
- lg_DBUnlock(sdb);
- return CKR_OK;
-}
-
-/*
- * handle Token Object stuff
- */
-static void
-lg_XORHash(unsigned char *key, unsigned char *dbkey, int len)
-{
- int i;
-
- PORT_Memset(key, 0, 4);
-
- for (i=0; i < len-4; i += 4) {
- key[0] ^= dbkey[i];
- key[1] ^= dbkey[i+1];
- key[2] ^= dbkey[i+2];
- key[3] ^= dbkey[i+3];
- }
-}
-
-/* Make a token handle for an object and record it so we can find it again */
-CK_OBJECT_HANDLE
-lg_mkHandle(SDB *sdb, SECItem *dbKey, CK_OBJECT_HANDLE class)
-{
- unsigned char hashBuf[4];
- CK_OBJECT_HANDLE handle;
- const SECItem *key;
-
- handle = class;
- /* there is only one KRL, use a fixed handle for it */
- if (handle != LG_TOKEN_KRL_HANDLE) {
- lg_XORHash(hashBuf,dbKey->data,dbKey->len);
- handle = (hashBuf[0] << 24) | (hashBuf[1] << 16) |
- (hashBuf[2] << 8) | hashBuf[3];
- handle = class | (handle & ~(LG_TOKEN_TYPE_MASK|LG_TOKEN_MASK));
- /* we have a CRL who's handle has randomly matched the reserved KRL
- * handle, increment it */
- if (handle == LG_TOKEN_KRL_HANDLE) {
- handle++;
- }
- }
-
- lg_DBLock(sdb);
- while ((key = lg_lookupTokenKeyByHandle(sdb,handle)) != NULL) {
- if (SECITEM_ItemsAreEqual(key,dbKey)) {
- lg_DBUnlock(sdb);
- return handle;
- }
- handle++;
- }
- lg_addTokenKeyByHandle(sdb,handle,dbKey);
- lg_DBUnlock(sdb);
- return handle;
-}
-
-PRBool
-lg_poisonHandle(SDB *sdb, SECItem *dbKey, CK_OBJECT_HANDLE class)
-{
- unsigned char hashBuf[4];
- CK_OBJECT_HANDLE handle;
- const SECItem *key;
-
- handle = class;
- /* there is only one KRL, use a fixed handle for it */
- if (handle != LG_TOKEN_KRL_HANDLE) {
- lg_XORHash(hashBuf,dbKey->data,dbKey->len);
- handle = (hashBuf[0] << 24) | (hashBuf[1] << 16) |
- (hashBuf[2] << 8) | hashBuf[3];
- handle = class | (handle & ~(LG_TOKEN_TYPE_MASK|LG_TOKEN_MASK));
- /* we have a CRL who's handle has randomly matched the reserved KRL
- * handle, increment it */
- if (handle == LG_TOKEN_KRL_HANDLE) {
- handle++;
- }
- }
- lg_DBLock(sdb);
- while ((key = lg_lookupTokenKeyByHandle(sdb,handle)) != NULL) {
- if (SECITEM_ItemsAreEqual(key,dbKey)) {
- key->data[0] ^= 0x80;
- lg_DBUnlock(sdb);
- return PR_TRUE;
- }
- handle++;
- }
- lg_DBUnlock(sdb);
- return PR_FALSE;
-}
-
-static LGEncryptFunc lg_encrypt_stub = NULL;
-static LGDecryptFunc lg_decrypt_stub = NULL;
-
-void
-legacy_SetCryptFunctions(LGEncryptFunc enc, LGDecryptFunc dec)
-{
- lg_encrypt_stub = enc;
- lg_decrypt_stub = dec;
-}
-
-SECStatus lg_util_encrypt(PLArenaPool *arena, SDB *sdb,
- SECItem *plainText, SECItem **cipherText)
-{
- if (lg_encrypt_stub == NULL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- return (*lg_encrypt_stub)(arena, sdb, plainText, cipherText);
-}
-
-SECStatus lg_util_decrypt(SDB *sdb, SECItem *cipherText, SECItem **plainText)
-{
- if (lg_decrypt_stub == NULL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- return (*lg_decrypt_stub)(sdb, cipherText, plainText);
-}
-
-
diff --git a/security/nss/lib/softoken/legacydb/lowcert.c b/security/nss/lib/softoken/legacydb/lowcert.c
deleted file mode 100644
index ee6c6a0e7..000000000
--- a/security/nss/lib/softoken/legacydb/lowcert.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Certificate handling code
- *
- * $Id$
- */
-
-#include "seccomon.h"
-#include "secder.h"
-#include "nssilock.h"
-#include "lowkeyi.h"
-#include "secasn1.h"
-#include "secoid.h"
-#include "secerr.h"
-#include "pcert.h"
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-static const SEC_ASN1Template nsslowcert_SubjectPublicKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTSubjectPublicKeyInfo) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSLOWCERTSubjectPublicKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_BIT_STRING,
- offsetof(NSSLOWCERTSubjectPublicKeyInfo,subjectPublicKey), },
- { 0, }
-};
-
-static const SEC_ASN1Template nsslowcert_RSAPublicKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPublicKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.rsa.modulus), },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.rsa.publicExponent), },
- { 0, }
-};
-static const SEC_ASN1Template nsslowcert_DSAPublicKeyTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.dsa.publicValue), },
- { 0, }
-};
-static const SEC_ASN1Template nsslowcert_DHPublicKeyTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.dh.publicValue), },
- { 0, }
-};
-
-/*
- * See bugzilla bug 125359
- * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
- * all of the templates above that en/decode into integers must be converted
- * from ASN.1's signed integer type. This is done by marking either the
- * source or destination (encoding or decoding, respectively) type as
- * siUnsignedInteger.
- */
-
-static void
-prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
-{
- pubk->u.rsa.modulus.type = siUnsignedInteger;
- pubk->u.rsa.publicExponent.type = siUnsignedInteger;
-}
-
-static void
-prepare_low_dsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
-{
- pubk->u.dsa.publicValue.type = siUnsignedInteger;
- pubk->u.dsa.params.prime.type = siUnsignedInteger;
- pubk->u.dsa.params.subPrime.type = siUnsignedInteger;
- pubk->u.dsa.params.base.type = siUnsignedInteger;
-}
-
-static void
-prepare_low_dh_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk)
-{
- pubk->u.dh.prime.type = siUnsignedInteger;
- pubk->u.dh.base.type = siUnsignedInteger;
- pubk->u.dh.publicValue.type = siUnsignedInteger;
-}
-
-/*
- * simple cert decoder to avoid the cost of asn1 engine
- */
-static unsigned char *
-nsslowcert_dataStart(unsigned char *buf, unsigned int length,
- unsigned int *data_length, PRBool includeTag,
- unsigned char* rettag) {
- unsigned char tag;
- unsigned int used_length= 0;
-
- /* need at least a tag and a 1 byte length */
- if (length < 2) {
- return NULL;
- }
-
- tag = buf[used_length++];
-
- if (rettag) {
- *rettag = tag;
- }
-
- /* blow out when we come to the end */
- if (tag == 0) {
- return NULL;
- }
-
- *data_length = buf[used_length++];
-
- if (*data_length&0x80) {
- int len_count = *data_length & 0x7f;
-
- if (len_count+used_length > length) {
- return NULL;
- }
-
- *data_length = 0;
-
- while (len_count-- > 0) {
- *data_length = (*data_length << 8) | buf[used_length++];
- }
- }
-
- if (*data_length > (length-used_length) ) {
- *data_length = length-used_length;
- return NULL;
- }
- if (includeTag) *data_length += used_length;
-
- return (buf + (includeTag ? 0 : used_length));
-}
-
-static void SetTimeType(SECItem* item, unsigned char tagtype)
-{
- switch (tagtype) {
- case SEC_ASN1_UTC_TIME:
- item->type = siUTCTime;
- break;
-
- case SEC_ASN1_GENERALIZED_TIME:
- item->type = siGeneralizedTime;
- break;
-
- default:
- PORT_Assert(0);
- break;
- }
-}
-
-static int
-nsslowcert_GetValidityFields(unsigned char *buf,int buf_length,
- SECItem *notBefore, SECItem *notAfter)
-{
- unsigned char tagtype;
- notBefore->data = nsslowcert_dataStart(buf,buf_length,
- &notBefore->len,PR_FALSE, &tagtype);
- if (notBefore->data == NULL) return SECFailure;
- SetTimeType(notBefore, tagtype);
- buf_length -= (notBefore->data-buf) + notBefore->len;
- buf = notBefore->data + notBefore->len;
- notAfter->data = nsslowcert_dataStart(buf,buf_length,
- &notAfter->len,PR_FALSE, &tagtype);
- if (notAfter->data == NULL) return SECFailure;
- SetTimeType(notAfter, tagtype);
- return SECSuccess;
-}
-
-static int
-nsslowcert_GetCertFields(unsigned char *cert,int cert_length,
- SECItem *issuer, SECItem *serial, SECItem *derSN, SECItem *subject,
- SECItem *valid, SECItem *subjkey, SECItem *extensions)
-{
- unsigned char *buf;
- unsigned int buf_length;
- unsigned char *dummy;
- unsigned int dummylen;
-
- /* get past the signature wrap */
- buf = nsslowcert_dataStart(cert,cert_length,&buf_length,PR_FALSE, NULL);
- if (buf == NULL) return SECFailure;
- /* get into the raw cert data */
- buf = nsslowcert_dataStart(buf,buf_length,&buf_length,PR_FALSE, NULL);
- if (buf == NULL) return SECFailure;
- /* skip past any optional version number */
- if ((buf[0] & 0xa0) == 0xa0) {
- dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE, NULL);
- if (dummy == NULL) return SECFailure;
- buf_length -= (dummy-buf) + dummylen;
- buf = dummy + dummylen;
- }
- /* serial number */
- if (derSN) {
- derSN->data=nsslowcert_dataStart(buf,buf_length,&derSN->len,PR_TRUE, NULL);
- /* derSN->data doesn't need to be checked because if it fails so will
- * serial->data below. The only difference between the two calls is
- * whether or not the tags are included in the returned buffer */
- }
- serial->data = nsslowcert_dataStart(buf,buf_length,&serial->len,PR_FALSE, NULL);
- if (serial->data == NULL) return SECFailure;
- buf_length -= (serial->data-buf) + serial->len;
- buf = serial->data + serial->len;
- /* skip the OID */
- dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE, NULL);
- if (dummy == NULL) return SECFailure;
- buf_length -= (dummy-buf) + dummylen;
- buf = dummy + dummylen;
- /* issuer */
- issuer->data = nsslowcert_dataStart(buf,buf_length,&issuer->len,PR_TRUE, NULL);
- if (issuer->data == NULL) return SECFailure;
- buf_length -= (issuer->data-buf) + issuer->len;
- buf = issuer->data + issuer->len;
-
- /* only wanted issuer/SN */
- if (valid == NULL) {
- return SECSuccess;
- }
- /* validity */
- valid->data = nsslowcert_dataStart(buf,buf_length,&valid->len,PR_FALSE, NULL);
- if (valid->data == NULL) return SECFailure;
- buf_length -= (valid->data-buf) + valid->len;
- buf = valid->data + valid->len;
- /*subject */
- subject->data=nsslowcert_dataStart(buf,buf_length,&subject->len,PR_TRUE, NULL);
- if (subject->data == NULL) return SECFailure;
- buf_length -= (subject->data-buf) + subject->len;
- buf = subject->data + subject->len;
- /* subject key info */
- subjkey->data=nsslowcert_dataStart(buf,buf_length,&subjkey->len,PR_TRUE, NULL);
- if (subjkey->data == NULL) return SECFailure;
- buf_length -= (subjkey->data-buf) + subjkey->len;
- buf = subjkey->data + subjkey->len;
-
- extensions->data = NULL;
- extensions->len = 0;
- while (buf_length > 0) {
- /* EXTENSIONS */
- if (buf[0] == 0xa3) {
- extensions->data = nsslowcert_dataStart(buf,buf_length,
- &extensions->len, PR_FALSE, NULL);
- /* if the DER is bad, we should fail. Previously we accepted
- * bad DER here and treated the extension as missin */
- if (extensions->data == NULL ||
- (extensions->data - buf) + extensions->len != buf_length)
- return SECFailure;
- buf = extensions->data;
- buf_length = extensions->len;
- /* now parse the SEQUENCE holding the extensions. */
- dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE,NULL);
- if (dummy == NULL ||
- (dummy - buf) + dummylen != buf_length)
- return SECFailure;
- buf_length -= (dummy - buf);
- buf = dummy;
- /* Now parse the extensions inside this sequence */
- }
- dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE,NULL);
- if (dummy == NULL) return SECFailure;
- buf_length -= (dummy - buf) + dummylen;
- buf = dummy + dummylen;
- }
- return SECSuccess;
-}
-
-static SECStatus
-nsslowcert_GetCertTimes(NSSLOWCERTCertificate *c, PRTime *notBefore, PRTime *notAfter)
-{
- int rv;
- NSSLOWCERTValidity validity;
-
- rv = nsslowcert_GetValidityFields(c->validity.data,c->validity.len,
- &validity.notBefore,&validity.notAfter);
- if (rv != SECSuccess) {
- return rv;
- }
-
- /* convert DER not-before time */
- rv = DER_DecodeTimeChoice(notBefore, &validity.notBefore);
- if (rv) {
- return(SECFailure);
- }
-
- /* convert DER not-after time */
- rv = DER_DecodeTimeChoice(notAfter, &validity.notAfter);
- if (rv) {
- return(SECFailure);
- }
-
- return(SECSuccess);
-}
-
-/*
- * is certa newer than certb? If one is expired, pick the other one.
- */
-PRBool
-nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb)
-{
- PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now;
- SECStatus rv;
- PRBool newerbefore, newerafter;
-
- rv = nsslowcert_GetCertTimes(certa, &notBeforeA, &notAfterA);
- if ( rv != SECSuccess ) {
- return(PR_FALSE);
- }
-
- rv = nsslowcert_GetCertTimes(certb, &notBeforeB, &notAfterB);
- if ( rv != SECSuccess ) {
- return(PR_TRUE);
- }
-
- newerbefore = PR_FALSE;
- if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
- newerbefore = PR_TRUE;
- }
-
- newerafter = PR_FALSE;
- if ( LL_CMP(notAfterA, >, notAfterB) ) {
- newerafter = PR_TRUE;
- }
-
- if ( newerbefore && newerafter ) {
- return(PR_TRUE);
- }
-
- if ( ( !newerbefore ) && ( !newerafter ) ) {
- return(PR_FALSE);
- }
-
- /* get current time */
- now = PR_Now();
-
- if ( newerbefore ) {
- /* cert A was issued after cert B, but expires sooner */
- /* if A is expired, then pick B */
- if ( LL_CMP(notAfterA, <, now ) ) {
- return(PR_FALSE);
- }
- return(PR_TRUE);
- } else {
- /* cert B was issued after cert A, but expires sooner */
- /* if B is expired, then pick A */
- if ( LL_CMP(notAfterB, <, now ) ) {
- return(PR_TRUE);
- }
- return(PR_FALSE);
- }
-}
-
-#define SOFT_DEFAULT_CHUNKSIZE 2048
-
-static SECStatus
-nsslowcert_KeyFromIssuerAndSN(PRArenaPool *arena,
- SECItem *issuer, SECItem *sn, SECItem *key)
-{
- unsigned int len = sn->len + issuer->len;
-
- if (!arena) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
- }
- if (len > NSS_MAX_LEGACY_DB_KEY_SIZE) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- goto loser;
- }
- key->data = (unsigned char*)PORT_ArenaAlloc(arena, len);
- if ( !key->data ) {
- goto loser;
- }
-
- key->len = len;
- /* copy the serialNumber */
- PORT_Memcpy(key->data, sn->data, sn->len);
-
- /* copy the issuer */
- PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-nsslowcert_KeyFromIssuerAndSNStatic(unsigned char *space,
- int spaceLen, SECItem *issuer, SECItem *sn, SECItem *key)
-{
- unsigned int len = sn->len + issuer->len;
-
- key->data = pkcs11_allocStaticData(len, space, spaceLen);
- if ( !key->data ) {
- goto loser;
- }
-
- key->len = len;
- /* copy the serialNumber */
- PORT_Memcpy(key->data, sn->data, sn->len);
-
- /* copy the issuer */
- PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-
-static char *
-nsslowcert_EmailName(SECItem *derDN, char *space, unsigned int len)
-{
- unsigned char *buf;
- unsigned int buf_length;
-
- /* unwrap outer sequence */
- buf=nsslowcert_dataStart(derDN->data,derDN->len,&buf_length,PR_FALSE,NULL);
- if (buf == NULL) return NULL;
-
- /* Walk each RDN */
- while (buf_length > 0) {
- unsigned char *rdn;
- unsigned int rdn_length;
-
- /* grab next rdn */
- rdn=nsslowcert_dataStart(buf, buf_length, &rdn_length, PR_FALSE, NULL);
- if (rdn == NULL) { return NULL; }
- buf_length -= (rdn - buf) + rdn_length;
- buf = rdn+rdn_length;
-
- while (rdn_length > 0) {
- unsigned char *ava;
- unsigned int ava_length;
- unsigned char *oid;
- unsigned int oid_length;
- unsigned char *name;
- unsigned int name_length;
- SECItem oidItem;
- SECOidTag type;
-
- /* unwrap the ava */
- ava=nsslowcert_dataStart(rdn, rdn_length, &ava_length, PR_FALSE,
- NULL);
- if (ava == NULL) return NULL;
- rdn_length -= (ava-rdn)+ava_length;
- rdn = ava + ava_length;
-
- oid=nsslowcert_dataStart(ava, ava_length, &oid_length, PR_FALSE,
- NULL);
- if (oid == NULL) { return NULL; }
- ava_length -= (oid-ava)+oid_length;
- ava = oid+oid_length;
-
- name=nsslowcert_dataStart(ava, ava_length, &name_length, PR_FALSE,
- NULL);
- if (oid == NULL) { return NULL; }
- ava_length -= (name-ava)+name_length;
- ava = name+name_length;
-
- oidItem.data = oid;
- oidItem.len = oid_length;
- type = SECOID_FindOIDTag(&oidItem);
- if ((type == SEC_OID_PKCS9_EMAIL_ADDRESS) ||
- (type == SEC_OID_RFC1274_MAIL)) {
- /* Email is supposed to be IA5String, so no
- * translation necessary */
- char *emailAddr;
- emailAddr = (char *)pkcs11_copyStaticData(name,name_length+1,
- (unsigned char *)space,len);
- if (emailAddr) {
- emailAddr[name_length] = 0;
- }
- return emailAddr;
- }
- }
- }
- return NULL;
-}
-
-static char *
-nsslowcert_EmailAltName(NSSLOWCERTCertificate *cert, char *space,
- unsigned int len)
-{
- unsigned char *exts;
- unsigned int exts_length;
-
- /* unwrap the sequence */
- exts = nsslowcert_dataStart(cert->extensions.data, cert->extensions.len,
- &exts_length, PR_FALSE, NULL);
- /* loop through extension */
- while (exts && exts_length > 0) {
- unsigned char * ext;
- unsigned int ext_length;
- unsigned char *oid;
- unsigned int oid_length;
- unsigned char *nameList;
- unsigned int nameList_length;
- SECItem oidItem;
- SECOidTag type;
-
- ext = nsslowcert_dataStart(exts, exts_length, &ext_length,
- PR_FALSE, NULL);
- if (ext == NULL) { break; }
- exts_length -= (ext - exts) + ext_length;
- exts = ext+ext_length;
-
- oid=nsslowcert_dataStart(ext, ext_length, &oid_length, PR_FALSE, NULL);
- if (oid == NULL) { break; }
- ext_length -= (oid - ext) + oid_length;
- ext = oid+oid_length;
- oidItem.data = oid;
- oidItem.len = oid_length;
- type = SECOID_FindOIDTag(&oidItem);
-
- /* get Alt Extension */
- if (type != SEC_OID_X509_SUBJECT_ALT_NAME) {
- continue;
- }
-
- /* skip passed the critical flag */
- if (ext[0] == 0x01) { /* BOOLEAN */
- unsigned char *dummy;
- unsigned int dummy_length;
- dummy = nsslowcert_dataStart(ext, ext_length, &dummy_length,
- PR_FALSE, NULL);
- if (dummy == NULL) { break; }
- ext_length -= (dummy - ext) + dummy_length;
- ext = dummy+dummy_length;
- }
-
-
- /* unwrap the name list */
- nameList = nsslowcert_dataStart(ext, ext_length, &nameList_length,
- PR_FALSE, NULL);
- if (nameList == NULL) { break; }
- ext_length -= (nameList - ext) + nameList_length;
- ext = nameList+nameList_length;
- nameList = nsslowcert_dataStart(nameList, nameList_length,
- &nameList_length, PR_FALSE, NULL);
- /* loop through the name list */
- while (nameList && nameList_length > 0) {
- unsigned char *thisName;
- unsigned int thisName_length;
-
- thisName = nsslowcert_dataStart(nameList, nameList_length,
- &thisName_length, PR_FALSE, NULL);
- if (thisName == NULL) { break; }
- if (nameList[0] == 0xa2) { /* DNS Name */
- SECItem dn;
- char *emailAddr;
-
- dn.data = thisName;
- dn.len = thisName_length;
- emailAddr = nsslowcert_EmailName(&dn, space, len);
- if (emailAddr) {
- return emailAddr;
- }
- }
- if (nameList[0] == 0x81) { /* RFC 822name */
- char *emailAddr;
- emailAddr = (char *)pkcs11_copyStaticData(thisName,
- thisName_length+1, (unsigned char *)space,len);
- if (emailAddr) {
- emailAddr[thisName_length] = 0;
- }
- return emailAddr;
- }
- nameList_length -= (thisName-nameList) + thisName_length;
- nameList = thisName + thisName_length;
- }
- break;
- }
- return NULL;
-}
-
-static char *
-nsslowcert_GetCertificateEmailAddress(NSSLOWCERTCertificate *cert)
-{
- char *emailAddr = NULL;
- char *str;
-
- emailAddr = nsslowcert_EmailName(&cert->derSubject,cert->emailAddrSpace,
- sizeof(cert->emailAddrSpace));
- /* couldn't find the email address in the DN, check the subject Alt name */
- if (!emailAddr && cert->extensions.data) {
- emailAddr = nsslowcert_EmailAltName(cert, cert->emailAddrSpace,
- sizeof(cert->emailAddrSpace));
- }
-
-
- /* make it lower case */
- str = emailAddr;
- while ( str && *str ) {
- *str = tolower( *str );
- str++;
- }
- return emailAddr;
-
-}
-
-/*
- * take a DER certificate and decode it into a certificate structure
- */
-NSSLOWCERTCertificate *
-nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, char *nickname)
-{
- NSSLOWCERTCertificate *cert;
- int rv;
-
- /* allocate the certificate structure */
- cert = nsslowcert_CreateCert();
-
- if ( !cert ) {
- goto loser;
- }
-
- /* point to passed in DER data */
- cert->derCert = *derSignedCert;
- cert->nickname = NULL;
- cert->certKey.data = NULL;
- cert->referenceCount = 1;
-
- /* decode the certificate info */
- rv = nsslowcert_GetCertFields(cert->derCert.data, cert->derCert.len,
- &cert->derIssuer, &cert->serialNumber, &cert->derSN, &cert->derSubject,
- &cert->validity, &cert->derSubjKeyInfo, &cert->extensions);
-
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* cert->subjectKeyID; x509v3 subject key identifier */
- cert->subjectKeyID.data = NULL;
- cert->subjectKeyID.len = 0;
- cert->dbEntry = NULL;
- cert ->trust = NULL;
- cert ->dbhandle = NULL;
-
- /* generate and save the database key for the cert */
- rv = nsslowcert_KeyFromIssuerAndSNStatic(cert->certKeySpace,
- sizeof(cert->certKeySpace), &cert->derIssuer,
- &cert->serialNumber, &cert->certKey);
- if ( rv ) {
- goto loser;
- }
-
- /* set the nickname */
- if ( nickname == NULL ) {
- cert->nickname = NULL;
- } else {
- /* copy and install the nickname */
- cert->nickname = pkcs11_copyNickname(nickname,cert->nicknameSpace,
- sizeof(cert->nicknameSpace));
- }
-
-#ifdef FIXME
- /* initialize the subjectKeyID */
- rv = cert_GetKeyID(cert);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-#endif
-
- /* set the email address */
- cert->emailAddr = nsslowcert_GetCertificateEmailAddress(cert);
-
-
- cert->referenceCount = 1;
-
- return(cert);
-
-loser:
- if (cert) {
- nsslowcert_DestroyCertificate(cert);
- }
-
- return(0);
-}
-
-char *
-nsslowcert_FixupEmailAddr(char *emailAddr)
-{
- char *retaddr;
- char *str;
-
- if ( emailAddr == NULL ) {
- return(NULL);
- }
-
- /* copy the string */
- str = retaddr = PORT_Strdup(emailAddr);
- if ( str == NULL ) {
- return(NULL);
- }
-
- /* make it lower case */
- while ( *str ) {
- *str = tolower( *str );
- str++;
- }
-
- return(retaddr);
-}
-
-
-/*
- * Generate a database key, based on serial number and issuer, from a
- * DER certificate.
- */
-SECStatus
-nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key)
-{
- int rv;
- NSSLOWCERTCertKey certkey;
-
- PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey));
-
- rv = nsslowcert_GetCertFields(derCert->data, derCert->len,
- &certkey.derIssuer, &certkey.serialNumber, NULL, NULL,
- NULL, NULL, NULL);
-
- if ( rv ) {
- goto loser;
- }
-
- return(nsslowcert_KeyFromIssuerAndSN(arena, &certkey.derIssuer,
- &certkey.serialNumber, key));
-loser:
- return(SECFailure);
-}
-
-NSSLOWKEYPublicKey *
-nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
-{
- NSSLOWCERTSubjectPublicKeyInfo spki;
- NSSLOWKEYPublicKey *pubk;
- SECItem os;
- SECStatus rv;
- PRArenaPool *arena;
- SECOidTag tag;
- SECItem newDerSubjKeyInfo;
-
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- return NULL;
-
- pubk = (NSSLOWKEYPublicKey *)
- PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey));
- if (pubk == NULL) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
- }
-
- pubk->arena = arena;
- PORT_Memset(&spki,0,sizeof(spki));
-
- /* copy the DER into the arena, since Quick DER returns data that points
- into the DER input, which may get freed by the caller */
- rv = SECITEM_CopyItem(arena, &newDerSubjKeyInfo, &cert->derSubjKeyInfo);
- if ( rv != SECSuccess ) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
- }
-
- /* we haven't bothered decoding the spki struct yet, do it now */
- rv = SEC_QuickDERDecodeItem(arena, &spki,
- nsslowcert_SubjectPublicKeyInfoTemplate, &newDerSubjKeyInfo);
- if (rv != SECSuccess) {
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
- }
-
- /* Convert bit string length from bits to bytes */
- os = spki.subjectPublicKey;
- DER_ConvertBitString (&os);
-
- tag = SECOID_GetAlgorithmTag(&spki.algorithm);
- switch ( tag ) {
- case SEC_OID_X500_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- pubk->keyType = NSSLOWKEYRSAKey;
- prepare_low_rsa_pub_key_for_asn1(pubk);
- rv = SEC_QuickDERDecodeItem(arena, pubk,
- nsslowcert_RSAPublicKeyTemplate, &os);
- if (rv == SECSuccess)
- return pubk;
- break;
- case SEC_OID_ANSIX9_DSA_SIGNATURE:
- pubk->keyType = NSSLOWKEYDSAKey;
- prepare_low_dsa_pub_key_for_asn1(pubk);
- rv = SEC_QuickDERDecodeItem(arena, pubk,
- nsslowcert_DSAPublicKeyTemplate, &os);
- if (rv == SECSuccess) return pubk;
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- pubk->keyType = NSSLOWKEYDHKey;
- prepare_low_dh_pub_key_for_asn1(pubk);
- rv = SEC_QuickDERDecodeItem(arena, pubk,
- nsslowcert_DHPublicKeyTemplate, &os);
- if (rv == SECSuccess) return pubk;
- break;
-#ifdef NSS_ENABLE_ECC
- case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
- pubk->keyType = NSSLOWKEYECKey;
- /* Since PKCS#11 directly takes the DER encoding of EC params
- * and public value, we don't need any decoding here.
- */
- rv = SECITEM_CopyItem(arena, &pubk->u.ec.ecParams.DEREncoding,
- &spki.algorithm.parameters);
- if ( rv != SECSuccess )
- break;
-
- /* Fill out the rest of the ecParams structure
- * based on the encoded params
- */
- if (LGEC_FillParams(arena, &pubk->u.ec.ecParams.DEREncoding,
- &pubk->u.ec.ecParams) != SECSuccess)
- break;
-
- rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &os);
- if (rv == SECSuccess) return pubk;
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- rv = SECFailure;
- break;
- }
-
- lg_nsslowkey_DestroyPublicKey (pubk);
- return NULL;
-}
-
diff --git a/security/nss/lib/softoken/legacydb/lowkey.c b/security/nss/lib/softoken/legacydb/lowkey.c
deleted file mode 100644
index 453248330..000000000
--- a/security/nss/lib/softoken/legacydb/lowkey.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "lowkeyi.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "secder.h"
-#include "secasn1.h"
-#include "secerr.h"
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(SEC_BitStringTemplate)
-SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-static const SEC_ASN1Template nsslowkey_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYAttribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(NSSLOWKEYAttribute, attrValue),
- SEC_ASN1_SUB(SEC_AnyTemplate) },
- { 0 }
-};
-
-static const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate },
-};
-/* ASN1 Templates for new decoder/encoder */
-const SEC_ASN1Template lg_nsslowkey_PrivateKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSLOWKEYPrivateKeyInfo,version) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
- nsslowkey_SetOfAttributeTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template lg_nsslowkey_PQGParamsTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) },
- { SEC_ASN1_INTEGER, offsetof(PQGParams,prime) },
- { SEC_ASN1_INTEGER, offsetof(PQGParams,subPrime) },
- { SEC_ASN1_INTEGER, offsetof(PQGParams,base) },
- { 0, }
-};
-
-const SEC_ASN1Template lg_nsslowkey_RSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) },
- { 0 }
-};
-
-/*
- * Allows u.rsa.modulus to be zero length for secret keys with an empty
- * CKA_ID incorrectly generated in NSS 3.13.3 or earlier. Only used for
- * decoding. See bug 715073.
- */
-const SEC_ASN1Template lg_nsslowkey_RSAPrivateKeyTemplate2[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) },
- { SEC_ASN1_ANY, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) },
- { 0 }
-};
-
-const SEC_ASN1Template lg_nsslowkey_DSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.publicValue) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
- { 0, }
-};
-
-const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.publicValue) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.privateValue) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.base) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.prime) },
- { 0, }
-};
-
-#ifdef NSS_ENABLE_ECC
-
-/* XXX This is just a placeholder for later when we support
- * generic curves and need full-blown support for parsing EC
- * parameters. For now, we only support named curves in which
- * EC params are simply encoded as an object ID and we don't
- * use lg_nsslowkey_ECParamsTemplate.
- */
-const SEC_ASN1Template lg_nsslowkey_ECParamsTemplate[] = {
- { SEC_ASN1_CHOICE, offsetof(ECParams,type), NULL, sizeof(ECParams) },
- { SEC_ASN1_OBJECT_ID, offsetof(ECParams,curveOID), NULL, ec_params_named },
- { 0, }
-};
-
-
-/* NOTE: The SECG specification allows the private key structure
- * to contain curve parameters but recommends that they be stored
- * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo
- * instead.
- */
-const SEC_ASN1Template lg_nsslowkey_ECPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.ec.version) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSLOWKEYPrivateKey,u.ec.privateValue) },
- /* XXX The following template works for now since we only
- * support named curves for which the parameters are
- * encoded as an object ID. When we support generic curves,
- * we'll need to define lg_nsslowkey_ECParamsTemplate
- */
-#if 1
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
- offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams.curveOID),
- SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
-#else
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams),
- lg_nsslowkey_ECParamsTemplate },
-#endif
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
- offsetof(NSSLOWKEYPrivateKey,u.ec.publicValue),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { 0, }
-};
-
-
-/*
- * smaller version of EC_FillParams. In this code, we only need
- * oid and DER data.
- */
-SECStatus
-LGEC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
- ECParams *params)
-{
- SECOidTag tag;
- SECItem oid = { siBuffer, NULL, 0};
-
-#if EC_DEBUG
- int i;
-
- printf("Encoded params in EC_DecodeParams: ");
- for (i = 0; i < encodedParams->len; i++) {
- printf("%02x:", encodedParams->data[i]);
- }
- printf("\n");
-#endif
-
- oid.len = encodedParams->len - 2;
- oid.data = encodedParams->data + 2;
- if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
- ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- return SECFailure;
- }
-
- params->arena = arena;
-
- /* For named curves, fill out curveOID */
- params->curveOID.len = oid.len;
- params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len);
- if (params->curveOID.data == NULL) {
- return SECFailure;
- }
- memcpy(params->curveOID.data, oid.data, oid.len);
-
- return SECSuccess;
-}
-
-/* Copy all of the fields from srcParams into dstParams
- */
-SECStatus
-LGEC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
- const ECParams *srcParams)
-{
- SECStatus rv = SECFailure;
-
- dstParams->arena = arena;
- rv = SECITEM_CopyItem(arena, &dstParams->DEREncoding,
- &srcParams->DEREncoding);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv =SECITEM_CopyItem(arena, &dstParams->curveOID,
- &srcParams->curveOID);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- return SECSuccess;
-
-loser:
- return SECFailure;
-}
-#endif /* NSS_ENABLE_ECC */
-/*
- * See bugzilla bug 125359
- * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
- * all of the templates above that en/decode into integers must be converted
- * from ASN.1's signed integer type. This is done by marking either the
- * source or destination (encoding or decoding, respectively) type as
- * siUnsignedInteger.
- */
-
-void
-lg_prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
-{
- key->u.rsa.modulus.type = siUnsignedInteger;
- key->u.rsa.publicExponent.type = siUnsignedInteger;
- key->u.rsa.privateExponent.type = siUnsignedInteger;
- key->u.rsa.prime1.type = siUnsignedInteger;
- key->u.rsa.prime2.type = siUnsignedInteger;
- key->u.rsa.exponent1.type = siUnsignedInteger;
- key->u.rsa.exponent2.type = siUnsignedInteger;
- key->u.rsa.coefficient.type = siUnsignedInteger;
-}
-
-void
-lg_prepare_low_pqg_params_for_asn1(PQGParams *params)
-{
- params->prime.type = siUnsignedInteger;
- params->subPrime.type = siUnsignedInteger;
- params->base.type = siUnsignedInteger;
-}
-
-void
-lg_prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
-{
- key->u.dsa.publicValue.type = siUnsignedInteger;
- key->u.dsa.privateValue.type = siUnsignedInteger;
- key->u.dsa.params.prime.type = siUnsignedInteger;
- key->u.dsa.params.subPrime.type = siUnsignedInteger;
- key->u.dsa.params.base.type = siUnsignedInteger;
-}
-
-void
-lg_prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
-{
- key->u.dh.prime.type = siUnsignedInteger;
- key->u.dh.base.type = siUnsignedInteger;
- key->u.dh.publicValue.type = siUnsignedInteger;
- key->u.dh.privateValue.type = siUnsignedInteger;
-}
-
-#ifdef NSS_ENABLE_ECC
-void
-lg_prepare_low_ecparams_for_asn1(ECParams *params)
-{
- params->DEREncoding.type = siUnsignedInteger;
- params->curveOID.type = siUnsignedInteger;
-}
-
-void
-lg_prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
-{
- key->u.ec.version.type = siUnsignedInteger;
- key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger;
- key->u.ec.ecParams.curveOID.type = siUnsignedInteger;
- key->u.ec.privateValue.type = siUnsignedInteger;
- key->u.ec.publicValue.type = siUnsignedInteger;
-}
-#endif /* NSS_ENABLE_ECC */
-
-void
-lg_nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
-{
- if (privk && privk->arena) {
- PORT_FreeArena(privk->arena, PR_TRUE);
- }
-}
-
-void
-lg_nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
-{
- if (pubk && pubk->arena) {
- PORT_FreeArena(pubk->arena, PR_FALSE);
- }
-}
-
-NSSLOWKEYPublicKey *
-lg_nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
-{
- NSSLOWKEYPublicKey *pubk;
- PLArenaPool *arena;
-
-
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- switch(privk->keyType) {
- case NSSLOWKEYRSAKey:
- case NSSLOWKEYNullKey:
- pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof (NSSLOWKEYPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- if (privk->keyType == NSSLOWKEYNullKey) return pubk;
- rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus,
- &privk->u.rsa.modulus);
- if (rv == SECSuccess) {
- rv = SECITEM_CopyItem (arena, &pubk->u.rsa.publicExponent,
- &privk->u.rsa.publicExponent);
- if (rv == SECSuccess)
- return pubk;
- }
- } else {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- }
- break;
- case NSSLOWKEYDSAKey:
- pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue,
- &privk->u.dsa.publicValue);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,
- &privk->u.dsa.params.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,
- &privk->u.dsa.params.subPrime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,
- &privk->u.dsa.params.base);
- if (rv == SECSuccess) return pubk;
- }
- break;
- case NSSLOWKEYDHKey:
- pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
- &privk->u.dh.publicValue);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime,
- &privk->u.dh.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dh.base,
- &privk->u.dh.base);
- if (rv == SECSuccess) return pubk;
- }
- break;
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue,
- &privk->u.ec.publicValue);
- if (rv != SECSuccess) break;
- pubk->u.ec.ecParams.arena = arena;
- /* Copy the rest of the params */
- rv = LGEC_CopyParams(arena, &(pubk->u.ec.ecParams),
- &(privk->u.ec.ecParams));
- if (rv == SECSuccess) return pubk;
- }
- break;
-#endif /* NSS_ENABLE_ECC */
- /* No Fortezza in Low Key implementations (Fortezza keys aren't
- * stored in our data base */
- default:
- break;
- }
-
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
-}
-
diff --git a/security/nss/lib/softoken/legacydb/lowkeyi.h b/security/nss/lib/softoken/legacydb/lowkeyi.h
deleted file mode 100644
index 1aa461ba7..000000000
--- a/security/nss/lib/softoken/legacydb/lowkeyi.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _LOWKEYI_H_
-#define _LOWKEYI_H_
-
-#include "prtypes.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "pcertt.h"
-#include "lowkeyti.h"
-#include "sdb.h"
-
-SEC_BEGIN_PROTOS
-
-/*
- * See bugzilla bug 125359
- * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
- * all of the templates above that en/decode into integers must be converted
- * from ASN.1's signed integer type. This is done by marking either the
- * source or destination (encoding or decoding, respectively) type as
- * siUnsignedInteger.
- */
-extern void lg_prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
-extern void lg_prepare_low_pqg_params_for_asn1(PQGParams *params);
-extern void lg_prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
-extern void lg_prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
-#ifdef NSS_ENABLE_ECC
-extern void lg_prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
-extern void lg_prepare_low_ecparams_for_asn1(ECParams *params);
-#endif /* NSS_ENABLE_ECC */
-
-typedef char * (* NSSLOWKEYDBNameFunc)(void *arg, int dbVersion);
-
-/*
-** Open a key database.
-*/
-extern NSSLOWKEYDBHandle *nsslowkey_OpenKeyDB(PRBool readOnly,
- const char *domain,
- const char *prefix,
- NSSLOWKEYDBNameFunc namecb,
- void *cbarg);
-
-/*
-** Close the specified key database.
-*/
-extern void nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle);
-
-/*
- * Get the version number of the database
- */
-extern int nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle);
-
-/*
-** Delete a key from the database
-*/
-extern SECStatus nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle,
- const SECItem *pubkey);
-
-/*
-** Store a key in the database, indexed by its public key modulus.
-** "pk" is the private key to store
-** "f" is the callback function for getting the password
-** "arg" is the argument for the callback
-*/
-extern SECStatus nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle,
- NSSLOWKEYPrivateKey *pk,
- SECItem *pubKeyData,
- char *nickname,
- SDB *sdb);
-
-/* does the key for this cert exist in the database filed by modulus */
-extern PRBool nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle,
- NSSLOWCERTCertificate *cert);
-/* does a key with this ID already exist? */
-extern PRBool nsslowkey_KeyForIDExists(NSSLOWKEYDBHandle *handle, SECItem *id);
-
-/*
-** Destroy a private key object.
-** "key" the object
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void lg_nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *key);
-
-/*
-** Destroy a public key object.
-** "key" the object
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void lg_nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *key);
-
-
-/*
-** Convert a low private key "privateKey" into a public low key
-*/
-extern NSSLOWKEYPublicKey
- *lg_nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privateKey);
-
-
-SECStatus
-nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle,
- NSSLOWKEYPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SDB *sdb);
-
-/* Store key by modulus and specify an encryption algorithm to use.
- * handle is the pointer to the key database,
- * privkey is the private key to be stored,
- * f and arg are the function and arguments to the callback
- * to get a password,
- * algorithm is the algorithm which the privKey is to be stored.
- * A return of anything but SECSuccess indicates failure.
- */
-extern SECStatus
-nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
- NSSLOWKEYPrivateKey *privkey,
- SECItem *pubKeyData,
- char *nickname,
- SDB *sdb,
- PRBool update);
-
-/* Find key by modulus. This function is the inverse of store key
- * by modulus. An attempt to locate the key with "modulus" is
- * performed. If the key is found, the private key is returned,
- * else NULL is returned.
- * modulus is the modulus to locate
- */
-extern NSSLOWKEYPrivateKey *
-nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
- SDB *sdb);
-
-extern char *
-nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle,
- SECItem *modulus, SDB *sdb);
-
-#ifdef NSS_ENABLE_ECC
-/*
- * smaller version of EC_FillParams. In this code, we only need
- * oid and DER data.
- */
-SECStatus LGEC_FillParams(PRArenaPool *arena, const SECItem *encodedParams,
- ECParams *params);
-
-/* Copy all of the fields from srcParams into dstParams */
-SECStatus LGEC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
- const ECParams *srcParams);
-#endif
-SEC_END_PROTOS
-
-#endif /* _LOWKEYI_H_ */
diff --git a/security/nss/lib/softoken/legacydb/lowkeyti.h b/security/nss/lib/softoken/legacydb/lowkeyti.h
deleted file mode 100644
index 5be6b0a55..000000000
--- a/security/nss/lib/softoken/legacydb/lowkeyti.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _LOWKEYTI_H_
-#define _LOWKEYTI_H_ 1
-
-#include "blapit.h"
-#include "prtypes.h"
-#include "plarena.h"
-#include "secitem.h"
-#include "secasn1t.h"
-#include "secoidt.h"
-
-
-/*
- * a key in/for the data base
- */
-struct NSSLOWKEYDBKeyStr {
- PLArenaPool *arena;
- int version;
- char *nickname;
- SECItem salt;
- SECItem derPK;
-};
-typedef struct NSSLOWKEYDBKeyStr NSSLOWKEYDBKey;
-
-typedef struct NSSLOWKEYDBHandleStr NSSLOWKEYDBHandle;
-
-#ifdef NSS_USE_KEY4_DB
-#define NSSLOWKEY_DB_FILE_VERSION 4
-#else
-#define NSSLOWKEY_DB_FILE_VERSION 3
-#endif
-
-#define NSSLOWKEY_VERSION 0 /* what we *create* */
-
-/*
-** Typedef for callback to get a password "key".
-*/
-extern const SEC_ASN1Template lg_nsslowkey_PQGParamsTemplate[];
-extern const SEC_ASN1Template lg_nsslowkey_RSAPrivateKeyTemplate[];
-extern const SEC_ASN1Template lg_nsslowkey_RSAPrivateKeyTemplate2[];
-extern const SEC_ASN1Template lg_nsslowkey_DSAPrivateKeyTemplate[];
-extern const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyTemplate[];
-extern const SEC_ASN1Template lg_nsslowkey_DHPrivateKeyExportTemplate[];
-#ifdef NSS_ENABLE_ECC
-#define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */
-extern const SEC_ASN1Template lg_nsslowkey_ECParamsTemplate[];
-extern const SEC_ASN1Template lg_nsslowkey_ECPrivateKeyTemplate[];
-#endif /* NSS_ENABLE_ECC */
-
-extern const SEC_ASN1Template lg_nsslowkey_PrivateKeyInfoTemplate[];
-extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[];
-
-/*
- * PKCS #8 attributes
- */
-struct NSSLOWKEYAttributeStr {
- SECItem attrType;
- SECItem *attrValue;
-};
-typedef struct NSSLOWKEYAttributeStr NSSLOWKEYAttribute;
-
-/*
-** A PKCS#8 private key info object
-*/
-struct NSSLOWKEYPrivateKeyInfoStr {
- PLArenaPool *arena;
- SECItem version;
- SECAlgorithmID algorithm;
- SECItem privateKey;
- NSSLOWKEYAttribute **attributes;
-};
-typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
-#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
-
-/*
-** A PKCS#8 private key info object
-*/
-struct NSSLOWKEYEncryptedPrivateKeyInfoStr {
- PLArenaPool *arena;
- SECAlgorithmID algorithm;
- SECItem encryptedData;
-};
-typedef struct NSSLOWKEYEncryptedPrivateKeyInfoStr NSSLOWKEYEncryptedPrivateKeyInfo;
-
-
-typedef enum {
- NSSLOWKEYNullKey = 0,
- NSSLOWKEYRSAKey = 1,
- NSSLOWKEYDSAKey = 2,
- NSSLOWKEYDHKey = 4,
- NSSLOWKEYECKey = 5
-} NSSLOWKEYType;
-
-/*
-** An RSA public key object.
-*/
-struct NSSLOWKEYPublicKeyStr {
- PLArenaPool *arena;
- NSSLOWKEYType keyType ;
- union {
- RSAPublicKey rsa;
- DSAPublicKey dsa;
- DHPublicKey dh;
- ECPublicKey ec;
- } u;
-};
-typedef struct NSSLOWKEYPublicKeyStr NSSLOWKEYPublicKey;
-
-/*
-** Low Level private key object
-** This is only used by the raw Crypto engines (crypto), keydb (keydb),
-** and PKCS #11. Everyone else uses the high level key structure.
-*/
-struct NSSLOWKEYPrivateKeyStr {
- PLArenaPool *arena;
- NSSLOWKEYType keyType;
- union {
- RSAPrivateKey rsa;
- DSAPrivateKey dsa;
- DHPrivateKey dh;
- ECPrivateKey ec;
- } u;
-};
-typedef struct NSSLOWKEYPrivateKeyStr NSSLOWKEYPrivateKey;
-
-
-typedef struct NSSLOWKEYPasswordEntryStr NSSLOWKEYPasswordEntry;
-struct NSSLOWKEYPasswordEntryStr {
- SECItem salt;
- SECItem value;
- unsigned char data[128];
-};
-
-
-#endif /* _LOWKEYTI_H_ */
diff --git a/security/nss/lib/softoken/legacydb/manifest.mn b/security/nss/lib/softoken/legacydb/manifest.mn
deleted file mode 100644
index 1024769de..000000000
--- a/security/nss/lib/softoken/legacydb/manifest.mn
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../../..
-
-MODULE = nss
-
-REQUIRES = dbm
-
-LIBRARY_NAME = nssdbm
-LIBRARY_VERSION = 3
-MAPFILE = $(OBJDIR)/nssdbm.def
-
-DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\"
-
-CSRCS = \
- dbmshim.c \
- keydb.c \
- lgattr.c \
- lgcreate.c \
- lgdestroy.c \
- lgfind.c \
- lginit.c \
- lgutil.c \
- lowcert.c \
- lowkey.c \
- pcertdb.c \
- pk11db.c \
- $(NULL)
-
diff --git a/security/nss/lib/softoken/legacydb/nssdbm.def b/security/nss/lib/softoken/legacydb/nssdbm.def
deleted file mode 100644
index e4dc6f281..000000000
--- a/security/nss/lib/softoken/legacydb/nssdbm.def
+++ /dev/null
@@ -1,31 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+NSSDBM_3.12 { # NSS 3.12 release
-;+ global:
-LIBRARY nssdbm3 ;-
-EXPORTS ;-
-legacy_Open;
-legacy_Shutdown;
-legacy_ReadSecmodDB;
-legacy_ReleaseSecmodDBData;
-legacy_AddSecmodDB;
-legacy_DeleteSecmodDB;
-legacy_SetCryptFunctions;
-;+ local:
-;+ *;
-;+};
diff --git a/security/nss/lib/softoken/legacydb/nssdbm.rc b/security/nss/lib/softoken/legacydb/nssdbm.rc
deleted file mode 100644
index cff86168e..000000000
--- a/security/nss/lib/softoken/legacydb/nssdbm.rc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "../softkver.h"
-#include <winver.h>
-
-#define MY_LIBNAME "nssdbm"
-#define MY_FILEDESCRIPTION "Legacy Database Driver"
-
-#define STRINGIZE(x) #x
-#define STRINGIZE2(x) STRINGIZE(x)
-#define SOFTOKEN_VMAJOR_STR STRINGIZE2(SOFTOKEN_VMAJOR)
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if SOFTOKEN_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME SOFTOKEN_VMAJOR_STR
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,SOFTOKEN_VBUILD
- PRODUCTVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,SOFTOKEN_VBUILD
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Mozilla Foundation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", SOFTOKEN_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", SOFTOKEN_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/softoken/legacydb/pcert.h b/security/nss/lib/softoken/legacydb/pcert.h
deleted file mode 100644
index 159ff7061..000000000
--- a/security/nss/lib/softoken/legacydb/pcert.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _PCERTDB_H_
-#define _PCERTDB_H_
-
-#include "plarena.h"
-#include "prlong.h"
-#include "pcertt.h"
-
-#include "lowkeyti.h" /* for struct NSSLOWKEYPublicKeyStr */
-
-SEC_BEGIN_PROTOS
-
-/*
- * initialize any global certificate locks
- */
-SECStatus nsslowcert_InitLocks(void);
-
-/*
-** Add a DER encoded certificate to the permanent database.
-** "derCert" is the DER encoded certificate.
-** "nickname" is the nickname to use for the cert
-** "trust" is the trust parameters for the cert
-*/
-SECStatus nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *handle,
- NSSLOWCERTCertificate *cert,
- char *nickname, NSSLOWCERTCertTrust *trust);
-SECStatus nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname);
-
-SECStatus nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert);
-
-typedef SECStatus (PR_CALLBACK * PermCertCallback)(NSSLOWCERTCertificate *cert,
- SECItem *k, void *pdata);
-/*
-** Traverse the entire permanent database, and pass the certs off to a
-** user supplied function.
-** "certfunc" is the user function to call for each certificate
-** "udata" is the user's data, which is passed through to "certfunc"
-*/
-SECStatus
-nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle,
- PermCertCallback certfunc,
- void *udata );
-
-PRBool
-nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle);
-
-certDBEntryRevocation *
-nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle,
- SECItem *crlKey, PRBool isKRL);
-
-SECStatus
-nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle,const SECItem *derName,
- PRBool isKRL);
-SECStatus
-nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl ,
- SECItem *derKey, char *url, PRBool isKRL);
-
-NSSLOWCERTCertDBHandle *nsslowcert_GetDefaultCertDB();
-NSSLOWKEYPublicKey *nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *);
-
-NSSLOWCERTCertificate *
-nsslowcert_NewTempCertificate(NSSLOWCERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER);
-NSSLOWCERTCertificate *
-nsslowcert_DupCertificate(NSSLOWCERTCertificate *cert);
-void nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert);
-void nsslowcert_DestroyTrust(NSSLOWCERTTrust *Trust);
-
-/*
- * Lookup a certificate in the databases without locking
- * "certKey" is the database key to look for
- *
- * XXX - this should be internal, but pkcs 11 needs to call it during a
- * traversal.
- */
-NSSLOWCERTCertificate *
-nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey);
-
-/*
- * Lookup trust for a certificate in the databases without locking
- * "certKey" is the database key to look for
- *
- * XXX - this should be internal, but pkcs 11 needs to call it during a
- * traversal.
- */
-NSSLOWCERTTrust *
-nsslowcert_FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey);
-
-/*
-** Generate a certificate key from the issuer and serialnumber, then look it
-** up in the database. Return the cert if found.
-** "issuerAndSN" is the issuer and serial number to look for
-*/
-extern NSSLOWCERTCertificate *
-nsslowcert_FindCertByIssuerAndSN (NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN);
-
-/*
-** Generate a certificate key from the issuer and serialnumber, then look it
-** up in the database. Return the cert if found.
-** "issuerAndSN" is the issuer and serial number to look for
-*/
-extern NSSLOWCERTTrust *
-nsslowcert_FindTrustByIssuerAndSN (NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN);
-
-/*
-** Find a certificate in the database by a DER encoded certificate
-** "derCert" is the DER encoded certificate
-*/
-extern NSSLOWCERTCertificate *
-nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert);
-
-/* convert an email address to lower case */
-char *nsslowcert_FixupEmailAddr(char *emailAddr);
-
-/*
-** Decode a DER encoded certificate into an NSSLOWCERTCertificate structure
-** "derSignedCert" is the DER encoded signed certificate
-** "copyDER" is true if the DER should be copied, false if the
-** existing copy should be referenced
-** "nickname" is the nickname to use in the database. If it is NULL
-** then a temporary nickname is generated.
-*/
-extern NSSLOWCERTCertificate *
-nsslowcert_DecodeDERCertificate (SECItem *derSignedCert, char *nickname);
-
-SECStatus
-nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key);
-
-certDBEntrySMime *
-nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *certHandle,
- char *emailAddr);
-void
-nsslowcert_DestroyDBEntry(certDBEntry *entry);
-
-SECStatus
-nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
- const char *domain, const char *prefix,
- NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile);
-
-void
-nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle);
-
-/*
- * is certa newer than certb? If one is expired, pick the other one.
- */
-PRBool
-nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb);
-
-
-SECStatus
-nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle,
- certDBEntryType type,
- SECStatus (* callback)(SECItem *data, SECItem *key,
- certDBEntryType type, void *pdata),
- void *udata );
-SECStatus
-nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
- SECItem *derSubject,
- NSSLOWCERTCertCallback cb, void *cbarg);
-int
-nsslowcert_NumPermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
- SECItem *derSubject);
-SECStatus
-nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
- char *nickname, NSSLOWCERTCertCallback cb, void *cbarg);
-
-int
-nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
- char *nickname);
-SECStatus
-nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert,
- NSSLOWCERTCertTrust *trust);
-
-SECStatus
-nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
- SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime);
-
-/*
- * Change the trust attributes of a certificate and make them permanent
- * in the database.
- */
-SECStatus
-nsslowcert_ChangeCertTrust(NSSLOWCERTCertDBHandle *handle,
- NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust);
-
-PRBool
-nsslowcert_needDBVerify(NSSLOWCERTCertDBHandle *handle);
-
-void
-nsslowcert_setDBVerify(NSSLOWCERTCertDBHandle *handle, PRBool value);
-
-PRBool
-nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust);
-
-void
-nsslowcert_DestroyFreeLists(void);
-
-void
-nsslowcert_DestroyGlobalLocks(void);
-
-void
-pkcs11_freeNickname(char *nickname, char *space);
-
-char *
-pkcs11_copyNickname(char *nickname, char *space, int spaceLen);
-
-void
-pkcs11_freeStaticData(unsigned char *data, unsigned char *space);
-
-unsigned char *
-pkcs11_allocStaticData(int datalen, unsigned char *space, int spaceLen);
-
-unsigned char *
-pkcs11_copyStaticData(unsigned char *data, int datalen, unsigned char *space,
- int spaceLen);
-NSSLOWCERTCertificate *
-nsslowcert_CreateCert(void);
-
-certDBEntry *
-nsslowcert_DecodeAnyDBEntry(SECItem *dbData, const SECItem *dbKey,
- certDBEntryType entryType, void *pdata);
-
-SEC_END_PROTOS
-
- #endif /* _PCERTDB_H_ */
diff --git a/security/nss/lib/softoken/legacydb/pcertdb.c b/security/nss/lib/softoken/legacydb/pcertdb.c
deleted file mode 100644
index 75f134292..000000000
--- a/security/nss/lib/softoken/legacydb/pcertdb.c
+++ /dev/null
@@ -1,5356 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Permanent Certificate database handling code
- *
- * $Id$
- */
-#include "lowkeyti.h"
-#include "pcert.h"
-#include "mcom_db.h"
-#include "pcert.h"
-#include "secitem.h"
-#include "secder.h"
-
-#include "secerr.h"
-#include "lgdb.h"
-
-/* forward declaration */
-NSSLOWCERTCertificate *
-nsslowcert_FindCertByDERCertNoLocking(NSSLOWCERTCertDBHandle *handle, SECItem *derCert);
-static SECStatus
-nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle,
- char *emailAddr, SECItem *derSubject, SECItem *emailProfile,
- SECItem *profileTime);
-static SECStatus
-nsslowcert_UpdatePermCert(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust);
-static SECStatus
-nsslowcert_UpdateCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
- SECItem *crlKey, char *url, PRBool isKRL);
-
-static NSSLOWCERTCertificate *certListHead = NULL;
-static NSSLOWCERTTrust *trustListHead = NULL;
-static certDBEntryCert *entryListHead = NULL;
-static int certListCount = 0;
-static int trustListCount = 0;
-static int entryListCount = 0;
-#define MAX_CERT_LIST_COUNT 10
-#define MAX_TRUST_LIST_COUNT 10
-#define MAX_ENTRY_LIST_COUNT 10
-
-/*
- * the following functions are wrappers for the db library that implement
- * a global lock to make the database thread safe.
- */
-static PZLock *dbLock = NULL;
-static PZLock *certRefCountLock = NULL;
-static PZLock *certTrustLock = NULL;
-static PZLock *freeListLock = NULL;
-
-void
-certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle)
-{
- if (dbLock == NULL) {
- dbLock = PZ_NewLock(nssILockCertDB);
- PORT_Assert(dbLock != NULL);
- }
-}
-
-SECStatus
-nsslowcert_InitLocks(void)
-{
- if (freeListLock == NULL) {
- freeListLock = PZ_NewLock(nssILockRefLock);
- if (freeListLock == NULL) {
- return SECFailure;
- }
- }
- if (certRefCountLock == NULL) {
- certRefCountLock = PZ_NewLock(nssILockRefLock);
- if (certRefCountLock == NULL) {
- return SECFailure;
- }
- }
- if (certTrustLock == NULL ) {
- certTrustLock = PZ_NewLock(nssILockCertDB);
- if (certTrustLock == NULL) {
- return SECFailure;
- }
- }
-
- return SECSuccess;
-}
-
-/*
- * Acquire the global lock on the cert database.
- * This lock is currently used for the following operations:
- * adding or deleting a cert to either the temp or perm databases
- * converting a temp to perm or perm to temp
- * changing (maybe just adding!?) the trust of a cert
- * chaning the DB status checking Configuration
- */
-static void
-nsslowcert_LockDB(NSSLOWCERTCertDBHandle *handle)
-{
- PZ_EnterMonitor(handle->dbMon);
- return;
-}
-
-/*
- * Free the global cert database lock.
- */
-static void
-nsslowcert_UnlockDB(NSSLOWCERTCertDBHandle *handle)
-{
- PRStatus prstat;
-
- prstat = PZ_ExitMonitor(handle->dbMon);
-
- PORT_Assert(prstat == PR_SUCCESS);
-
- return;
-}
-
-
-/*
- * Acquire the cert reference count lock
- * There is currently one global lock for all certs, but I'm putting a cert
- * arg here so that it will be easy to make it per-cert in the future if
- * that turns out to be necessary.
- */
-static void
-nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert)
-{
- PORT_Assert(certRefCountLock != NULL);
-
- PZ_Lock(certRefCountLock);
- return;
-}
-
-/*
- * Free the cert reference count lock
- */
-static void
-nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert)
-{
- PRStatus prstat;
-
- PORT_Assert(certRefCountLock != NULL);
-
- prstat = PZ_Unlock(certRefCountLock);
-
- PORT_Assert(prstat == PR_SUCCESS);
-
- return;
-}
-
-/*
- * Acquire the cert trust lock
- * There is currently one global lock for all certs, but I'm putting a cert
- * arg here so that it will be easy to make it per-cert in the future if
- * that turns out to be necessary.
- */
-static void
-nsslowcert_LockCertTrust(NSSLOWCERTCertificate *cert)
-{
- PORT_Assert(certTrustLock != NULL);
-
- PZ_Lock(certTrustLock);
- return;
-}
-
-/*
- * Free the cert trust lock
- */
-static void
-nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert)
-{
- PRStatus prstat;
-
- PORT_Assert(certTrustLock != NULL);
-
- prstat = PZ_Unlock(certTrustLock);
-
- PORT_Assert(prstat == PR_SUCCESS);
-
- return;
-}
-
-
-/*
- * Acquire the cert reference count lock
- * There is currently one global lock for all certs, but I'm putting a cert
- * arg here so that it will be easy to make it per-cert in the future if
- * that turns out to be necessary.
- */
-static void
-nsslowcert_LockFreeList(void)
-{
- PORT_Assert(freeListLock != NULL);
-
- SKIP_AFTER_FORK(PZ_Lock(freeListLock));
- return;
-}
-
-/*
- * Free the cert reference count lock
- */
-static void
-nsslowcert_UnlockFreeList(void)
-{
- PRStatus prstat = PR_SUCCESS;
-
- PORT_Assert(freeListLock != NULL);
-
- SKIP_AFTER_FORK(prstat = PZ_Unlock(freeListLock));
-
- PORT_Assert(prstat == PR_SUCCESS);
-
- return;
-}
-
-NSSLOWCERTCertificate *
-nsslowcert_DupCertificate(NSSLOWCERTCertificate *c)
-{
- if (c) {
- nsslowcert_LockCertRefCount(c);
- ++c->referenceCount;
- nsslowcert_UnlockCertRefCount(c);
- }
- return c;
-}
-
-static int
-certdb_Get(DB *db, DBT *key, DBT *data, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->get)(db, key, data, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- return(ret);
-}
-
-static int
-certdb_Put(DB *db, DBT *key, DBT *data, unsigned int flags)
-{
- PRStatus prstat;
- int ret = 0;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->put)(db, key, data, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- return(ret);
-}
-
-static int
-certdb_Sync(DB *db, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->sync)(db, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- return(ret);
-}
-
-#define DB_NOT_FOUND -30991 /* from DBM 3.2 */
-static int
-certdb_Del(DB *db, DBT *key, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->del)(db, key, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- /* don't fail if the record is already deleted */
- if (ret == DB_NOT_FOUND) {
- ret = 0;
- }
-
- return(ret);
-}
-
-static int
-certdb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags)
-{
- PRStatus prstat;
- int ret;
-
- PORT_Assert(dbLock != NULL);
- PZ_Lock(dbLock);
-
- ret = (* db->seq)(db, key, data, flags);
-
- prstat = PZ_Unlock(dbLock);
-
- return(ret);
-}
-
-static void
-certdb_Close(DB *db)
-{
- PRStatus prstat = PR_SUCCESS;
-
- PORT_Assert(dbLock != NULL);
- SKIP_AFTER_FORK(PZ_Lock(dbLock));
-
- (* db->close)(db);
-
- SKIP_AFTER_FORK(prstat = PZ_Unlock(dbLock));
-
- return;
-}
-
-void
-pkcs11_freeNickname(char *nickname, char *space)
-{
- if (nickname && nickname != space) {
- PORT_Free(nickname);
- }
-}
-
-char *
-pkcs11_copyNickname(char *nickname,char *space, int spaceLen)
-{
- int len;
- char *copy = NULL;
-
- len = PORT_Strlen(nickname)+1;
- if (len <= spaceLen) {
- copy = space;
- PORT_Memcpy(copy,nickname,len);
- } else {
- copy = PORT_Strdup(nickname);
- }
-
- return copy;
-}
-
-void
-pkcs11_freeStaticData (unsigned char *data, unsigned char *space)
-{
- if (data && data != space) {
- PORT_Free(data);
- }
-}
-
-unsigned char *
-pkcs11_allocStaticData(int len, unsigned char *space, int spaceLen)
-{
- unsigned char *data = NULL;
-
- if (len <= spaceLen) {
- data = space;
- } else {
- data = (unsigned char *) PORT_Alloc(len);
- }
-
- return data;
-}
-
-unsigned char *
-pkcs11_copyStaticData(unsigned char *data, int len,
- unsigned char *space, int spaceLen)
-{
- unsigned char *copy = pkcs11_allocStaticData(len, space, spaceLen);
- if (copy) {
- PORT_Memcpy(copy,data,len);
- }
-
- return copy;
-}
-
-/*
- * destroy a database entry
- */
-static void
-DestroyDBEntry(certDBEntry *entry)
-{
- PRArenaPool *arena = entry->common.arena;
-
- /* must be one of our certDBEntry from the free list */
- if (arena == NULL) {
- certDBEntryCert *certEntry;
- if ( entry->common.type != certDBEntryTypeCert) {
- return;
- }
- certEntry = (certDBEntryCert *)entry;
-
- pkcs11_freeStaticData(certEntry->derCert.data, certEntry->derCertSpace);
- pkcs11_freeNickname(certEntry->nickname, certEntry->nicknameSpace);
-
- nsslowcert_LockFreeList();
- if (entryListCount > MAX_ENTRY_LIST_COUNT) {
- PORT_Free(certEntry);
- } else {
- entryListCount++;
- PORT_Memset(certEntry, 0, sizeof( *certEntry));
- certEntry->next = entryListHead;
- entryListHead = certEntry;
- }
- nsslowcert_UnlockFreeList();
- return;
- }
-
-
- /* Zero out the entry struct, so that any further attempts to use it
- * will cause an exception (e.g. null pointer reference). */
- PORT_Memset(&entry->common, 0, sizeof entry->common);
- PORT_FreeArena(arena, PR_FALSE);
-
- return;
-}
-
-/* forward references */
-static void nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert);
-
-static SECStatus
-DeleteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryType type, SECItem *dbkey)
-{
- DBT key;
- int ret;
-
- /* init the database key */
- key.data = dbkey->data;
- key.size = dbkey->len;
-
- dbkey->data[0] = (unsigned char)type;
-
- /* delete entry from database */
- ret = certdb_Del(handle->permCertDB, &key, 0 );
- if ( ret != 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- ret = certdb_Sync(handle->permCertDB, 0);
- if ( ret ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-ReadDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry,
- SECItem *dbkey, SECItem *dbentry, PRArenaPool *arena)
-{
- DBT data, key;
- int ret;
- unsigned char *buf;
-
- /* init the database key */
- key.data = dbkey->data;
- key.size = dbkey->len;
-
- dbkey->data[0] = (unsigned char)entry->type;
-
- /* read entry from database */
- ret = certdb_Get(handle->permCertDB, &key, &data, 0 );
- if ( ret != 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* validate the entry */
- if ( data.size < SEC_DB_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
- buf = (unsigned char *)data.data;
- /* version 7 has the same schema, we may be using a v7 db if we openned
- * the databases readonly. */
- if (!((buf[0] == (unsigned char)CERT_DB_FILE_VERSION)
- || (buf[0] == (unsigned char) CERT_DB_V7_FILE_VERSION))) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
- if ( buf[1] != (unsigned char)entry->type ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* copy out header information */
- entry->version = (unsigned int)buf[0];
- entry->type = (certDBEntryType)buf[1];
- entry->flags = (unsigned int)buf[2];
-
- /* format body of entry for return to caller */
- dbentry->len = data.size - SEC_DB_ENTRY_HEADER_LEN;
- if ( dbentry->len ) {
- if (arena) {
- dbentry->data = (unsigned char *)
- PORT_ArenaAlloc(arena, dbentry->len);
- if ( dbentry->data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- PORT_Memcpy(dbentry->data, &buf[SEC_DB_ENTRY_HEADER_LEN],
- dbentry->len);
- } else {
- dbentry->data = &buf[SEC_DB_ENTRY_HEADER_LEN];
- }
- } else {
- dbentry->data = NULL;
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/**
- ** Implement low level database access
- **/
-static SECStatus
-WriteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry,
- SECItem *dbkey, SECItem *dbentry)
-{
- int ret;
- DBT data, key;
- unsigned char *buf;
-
- data.data = dbentry->data;
- data.size = dbentry->len;
-
- buf = (unsigned char*)data.data;
-
- buf[0] = (unsigned char)entry->version;
- buf[1] = (unsigned char)entry->type;
- buf[2] = (unsigned char)entry->flags;
-
- key.data = dbkey->data;
- key.size = dbkey->len;
-
- dbkey->data[0] = (unsigned char)entry->type;
-
- /* put the record into the database now */
- ret = certdb_Put(handle->permCertDB, &key, &data, 0);
-
- if ( ret != 0 ) {
- goto loser;
- }
-
- ret = certdb_Sync( handle->permCertDB, 0 );
-
- if ( ret ) {
- goto loser;
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * encode a database cert record
- */
-static SECStatus
-EncodeDBCertEntry(certDBEntryCert *entry, PRArenaPool *arena, SECItem *dbitem)
-{
- unsigned int nnlen;
- unsigned char *buf;
- char *nn;
- char zbuf = 0;
-
- if ( entry->nickname ) {
- nn = entry->nickname;
- } else {
- nn = &zbuf;
- }
- nnlen = PORT_Strlen(nn) + 1;
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = entry->derCert.len + nnlen + DB_CERT_ENTRY_HEADER_LEN +
- SEC_DB_ENTRY_HEADER_LEN;
-
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
-
- buf[0] = (PRUint8)( entry->trust.sslFlags >> 8 );
- buf[1] = (PRUint8)( entry->trust.sslFlags );
- buf[2] = (PRUint8)( entry->trust.emailFlags >> 8 );
- buf[3] = (PRUint8)( entry->trust.emailFlags );
- buf[4] = (PRUint8)( entry->trust.objectSigningFlags >> 8 );
- buf[5] = (PRUint8)( entry->trust.objectSigningFlags );
- buf[6] = (PRUint8)( entry->derCert.len >> 8 );
- buf[7] = (PRUint8)( entry->derCert.len );
- buf[8] = (PRUint8)( nnlen >> 8 );
- buf[9] = (PRUint8)( nnlen );
-
- PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN], entry->derCert.data,
- entry->derCert.len);
-
- PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN + entry->derCert.len],
- nn, nnlen);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * encode a database key for a cert record
- */
-static SECStatus
-EncodeDBCertKey(const SECItem *certKey, PRArenaPool *arena, SECItem *dbkey)
-{
- unsigned int len = certKey->len + SEC_DB_KEY_HEADER_LEN;
- if (len > NSS_MAX_LEGACY_DB_KEY_SIZE)
- goto loser;
- if (arena) {
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
- } else {
- if (dbkey->len < len) {
- dbkey->data = (unsigned char *)PORT_Alloc(len);
- }
- }
- dbkey->len = len;
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN],
- certKey->data, certKey->len);
- dbkey->data[0] = certDBEntryTypeCert;
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-EncodeDBGenericKey(const SECItem *certKey, PRArenaPool *arena, SECItem *dbkey,
- certDBEntryType entryType)
-{
- /*
- * we only allow _one_ KRL key!
- */
- if (entryType == certDBEntryTypeKeyRevocation) {
- dbkey->len = SEC_DB_KEY_HEADER_LEN;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- dbkey->data[0] = (unsigned char) entryType;
- return(SECSuccess);
- }
-
-
- dbkey->len = certKey->len + SEC_DB_KEY_HEADER_LEN;
- if (dbkey->len > NSS_MAX_LEGACY_DB_KEY_SIZE)
- goto loser;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN],
- certKey->data, certKey->len);
- dbkey->data[0] = (unsigned char) entryType;
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry)
-{
- unsigned int nnlen;
- unsigned int headerlen;
- int lenoff;
-
- /* allow updates of old versions of the database */
- switch ( entry->common.version ) {
- case 5:
- headerlen = DB_CERT_V5_ENTRY_HEADER_LEN;
- lenoff = 3;
- break;
- case 6:
- /* should not get here */
- PORT_Assert(0);
- headerlen = DB_CERT_V6_ENTRY_HEADER_LEN;
- lenoff = 3;
- break;
- case 7:
- case 8:
- headerlen = DB_CERT_ENTRY_HEADER_LEN;
- lenoff = 6;
- break;
- default:
- /* better not get here */
- PORT_Assert(0);
- headerlen = DB_CERT_V5_ENTRY_HEADER_LEN;
- lenoff = 3;
- break;
- }
-
- /* is record long enough for header? */
- if ( dbentry->len < headerlen ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* is database entry correct length? */
- entry->derCert.len = ( ( dbentry->data[lenoff] << 8 ) |
- dbentry->data[lenoff+1] );
- nnlen = ( ( dbentry->data[lenoff+2] << 8 ) | dbentry->data[lenoff+3] );
- lenoff = dbentry->len - ( entry->derCert.len + nnlen + headerlen );
- if ( lenoff ) {
- if ( lenoff < 0 || (lenoff & 0xffff) != 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
- /* The cert size exceeded 64KB. Reconstruct the correct length. */
- entry->derCert.len += lenoff;
- }
-
- /* copy the dercert */
- entry->derCert.data = pkcs11_copyStaticData(&dbentry->data[headerlen],
- entry->derCert.len,entry->derCertSpace,sizeof(entry->derCertSpace));
- if ( entry->derCert.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* copy the nickname */
- if ( nnlen > 1 ) {
- entry->nickname = (char *)pkcs11_copyStaticData(
- &dbentry->data[headerlen+entry->derCert.len], nnlen,
- (unsigned char *)entry->nicknameSpace,
- sizeof(entry->nicknameSpace));
- if ( entry->nickname == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- } else {
- entry->nickname = NULL;
- }
-
- if ( entry->common.version < 7 ) {
- /* allow updates of v5 db */
- entry->trust.sslFlags = dbentry->data[0];
- entry->trust.emailFlags = dbentry->data[1];
- entry->trust.objectSigningFlags = dbentry->data[2];
- } else {
- entry->trust.sslFlags = ( dbentry->data[0] << 8 ) | dbentry->data[1];
- entry->trust.emailFlags = ( dbentry->data[2] << 8 ) | dbentry->data[3];
- entry->trust.objectSigningFlags =
- ( dbentry->data[4] << 8 ) | dbentry->data[5];
- }
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-
-/*
- * Create a new certDBEntryCert from existing data
- */
-static certDBEntryCert *
-NewDBCertEntry(SECItem *derCert, char *nickname,
- NSSLOWCERTCertTrust *trust, int flags)
-{
- certDBEntryCert *entry;
- PRArenaPool *arena = NULL;
- int nnlen;
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
-
- if ( !arena ) {
- goto loser;
- }
-
- entry = PORT_ArenaZNew(arena, certDBEntryCert);
- if ( entry == NULL ) {
- goto loser;
- }
-
- /* fill in the dbCert */
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeCert;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- if ( trust ) {
- entry->trust = *trust;
- }
-
- entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, derCert->len);
- if ( !entry->derCert.data ) {
- goto loser;
- }
- entry->derCert.len = derCert->len;
- PORT_Memcpy(entry->derCert.data, derCert->data, derCert->len);
-
- nnlen = ( nickname ? strlen(nickname) + 1 : 0 );
-
- if ( nnlen ) {
- entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( !entry->nickname ) {
- goto loser;
- }
- PORT_Memcpy(entry->nickname, nickname, nnlen);
-
- } else {
- entry->nickname = 0;
- }
-
- return(entry);
-
-loser:
-
- /* allocation error, free arena and return */
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
-}
-
-/*
- * Decode a version 4 DBCert from the byte stream database format
- * and construct a current database entry struct
- */
-static certDBEntryCert *
-DecodeV4DBCertEntry(unsigned char *buf, int len)
-{
- certDBEntryCert *entry;
- int certlen;
- int nnlen;
- PRArenaPool *arena;
-
- /* make sure length is at least long enough for the header */
- if ( len < DBCERT_V4_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(0);
- }
-
- /* get other lengths */
- certlen = buf[3] << 8 | buf[4];
- nnlen = buf[5] << 8 | buf[6];
-
- /* make sure DB entry is the right size */
- if ( ( certlen + nnlen + DBCERT_V4_HEADER_LEN ) != len ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(0);
- }
-
- /* allocate arena */
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
-
- if ( !arena ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
- }
-
- /* allocate structure and members */
- entry = (certDBEntryCert *) PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
-
- if ( !entry ) {
- goto loser;
- }
-
- entry->common.arena = arena;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.type = certDBEntryTypeCert;
- entry->common.flags = 0;
- entry->trust.sslFlags = buf[0];
- entry->trust.emailFlags = buf[1];
- entry->trust.objectSigningFlags = buf[2];
-
- entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen);
- if ( !entry->derCert.data ) {
- goto loser;
- }
- entry->derCert.len = certlen;
- PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen);
-
- if ( nnlen ) {
- entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen);
- if ( !entry->nickname ) {
- goto loser;
- }
- PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen);
-
- if (PORT_Strcmp(entry->nickname, "Server-Cert") == 0) {
- entry->trust.sslFlags |= CERTDB_USER;
- }
- } else {
- entry->nickname = 0;
- }
-
- return(entry);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
-}
-
-/*
- * Encode a Certificate database entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBCertEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECItem tmpitem;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBCertEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* get the database key and format it */
- rv = nsslowcert_KeyFromDERCert(tmparena, &entry->derCert, &tmpitem);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = EncodeDBCertKey(&tmpitem, tmparena, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-
-/*
- * delete a certificate entry
- */
-static SECStatus
-DeleteDBCertEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
-{
- SECItem dbkey;
- SECStatus rv;
-
- dbkey.data= NULL;
- dbkey.len = 0;
-
- rv = EncodeDBCertKey(certKey, NULL, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, certDBEntryTypeCert, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_Free(dbkey.data);
-
- return(SECSuccess);
-
-loser:
- if (dbkey.data) {
- PORT_Free(dbkey.data);
- }
- return(SECFailure);
-}
-
-static certDBEntryCert *
-CreateCertEntry(void)
-{
- certDBEntryCert *entry;
-
- nsslowcert_LockFreeList();
- entry = entryListHead;
- if (entry) {
- entryListCount--;
- entryListHead = entry->next;
- }
- PORT_Assert(entryListCount >= 0);
- nsslowcert_UnlockFreeList();
- if (entry) {
- return entry;
- }
-
- return PORT_ZNew(certDBEntryCert);
-}
-
-static void
-DestroyCertEntryFreeList(void)
-{
- certDBEntryCert *entry;
-
- nsslowcert_LockFreeList();
- while (NULL != (entry = entryListHead)) {
- entryListCount--;
- entryListHead = entry->next;
- PORT_Free(entry);
- }
- PORT_Assert(!entryListCount);
- entryListCount = 0;
- nsslowcert_UnlockFreeList();
-}
-
-/*
- * Read a certificate entry
- */
-static certDBEntryCert *
-ReadDBCertEntry(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
-{
- certDBEntryCert *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
- unsigned char buf[512];
-
- dbkey.data = buf;
- dbkey.len = sizeof(buf);
-
- entry = CreateCertEntry();
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = NULL;
- entry->common.type = certDBEntryTypeCert;
-
- rv = EncodeDBCertKey(certKey, NULL, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, NULL);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = DecodeDBCertEntry(entry, &dbentry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- pkcs11_freeStaticData(dbkey.data,buf);
- dbkey.data = NULL;
- return(entry);
-
-loser:
- pkcs11_freeStaticData(dbkey.data,buf);
- dbkey.data = NULL;
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
- }
-
- return(NULL);
-}
-
-/*
- * encode a database cert record
- */
-static SECStatus
-EncodeDBCrlEntry(certDBEntryRevocation *entry, PRArenaPool *arena, SECItem *dbitem)
-{
- unsigned int nnlen = 0;
- unsigned char *buf;
-
- if (entry->url) {
- nnlen = PORT_Strlen(entry->url) + 1;
- }
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = entry->derCrl.len + nnlen
- + SEC_DB_ENTRY_HEADER_LEN + DB_CRL_ENTRY_HEADER_LEN;
-
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
-
- buf[0] = (PRUint8)( entry->derCrl.len >> 8 );
- buf[1] = (PRUint8)( entry->derCrl.len );
- buf[2] = (PRUint8)( nnlen >> 8 );
- buf[3] = (PRUint8)( nnlen );
-
- PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN], entry->derCrl.data,
- entry->derCrl.len);
-
- if (nnlen != 0) {
- PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
- entry->url, nnlen);
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry)
-{
- unsigned int urlLen;
- int lenDiff;
-
- /* is record long enough for header? */
- if ( dbentry->len < DB_CRL_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* is database entry correct length? */
- entry->derCrl.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
- urlLen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
- lenDiff = dbentry->len -
- (entry->derCrl.len + urlLen + DB_CRL_ENTRY_HEADER_LEN);
- if (lenDiff) {
- if (lenDiff < 0 || (lenDiff & 0xffff) != 0) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
- /* CRL entry is greater than 64 K. Hack to make this continue to work */
- entry->derCrl.len += lenDiff;
- }
-
- /* copy the der CRL */
- entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->derCrl.len);
- if ( entry->derCrl.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->derCrl.data, &dbentry->data[DB_CRL_ENTRY_HEADER_LEN],
- entry->derCrl.len);
-
- /* copy the url */
- entry->url = NULL;
- if (urlLen != 0) {
- entry->url = (char *)PORT_ArenaAlloc(entry->common.arena, urlLen);
- if ( entry->url == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->url,
- &dbentry->data[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
- urlLen);
- }
-
- return(SECSuccess);
-loser:
- return(SECFailure);
-}
-
-/*
- * Create a new certDBEntryRevocation from existing data
- */
-static certDBEntryRevocation *
-NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags)
-{
- certDBEntryRevocation *entry;
- PRArenaPool *arena = NULL;
- int nnlen;
-
- arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );
-
- if ( !arena ) {
- goto loser;
- }
-
- entry = PORT_ArenaZNew(arena, certDBEntryRevocation);
- if ( entry == NULL ) {
- goto loser;
- }
-
- /* fill in the dbRevolcation */
- entry->common.arena = arena;
- entry->common.type = crlType;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
-
- entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(arena, derCrl->len);
- if ( !entry->derCrl.data ) {
- goto loser;
- }
-
- if (url) {
- nnlen = PORT_Strlen(url) + 1;
- entry->url = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( !entry->url ) {
- goto loser;
- }
- PORT_Memcpy(entry->url, url, nnlen);
- } else {
- entry->url = NULL;
- }
-
-
- entry->derCrl.len = derCrl->len;
- PORT_Memcpy(entry->derCrl.data, derCrl->data, derCrl->len);
-
- return(entry);
-
-loser:
-
- /* allocation error, free arena and return */
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return(0);
-}
-
-
-static SECStatus
-WriteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryRevocation *entry,
- SECItem *crlKey )
-{
- SECItem dbkey;
- PRArenaPool *tmparena = NULL;
- SECItem encodedEntry;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBCrlEntry(entry, tmparena, &encodedEntry);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = EncodeDBGenericKey(crlKey, tmparena, &dbkey, entry->common.type);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &encodedEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-}
-/*
- * delete a crl entry
- */
-static SECStatus
-DeleteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, const SECItem *crlKey,
- certDBEntryType crlType)
-{
- SECItem dbkey;
- PRArenaPool *arena = NULL;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBGenericKey(crlKey, arena, &dbkey, crlType);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, crlType, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Read a certificate entry
- */
-static certDBEntryRevocation *
-ReadDBCrlEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey,
- certDBEntryType crlType)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntryRevocation *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryRevocation *)
- PORT_ArenaAlloc(arena, sizeof(certDBEntryRevocation));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = crlType;
-
- rv = EncodeDBGenericKey(certKey, tmparena, &dbkey, crlType);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, NULL);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = DecodeDBCrlEntry(entry, &dbentry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-void
-nsslowcert_DestroyDBEntry(certDBEntry *entry)
-{
- DestroyDBEntry(entry);
- return;
-}
-
-/*
- * Encode a database nickname record
- */
-static SECStatus
-EncodeDBNicknameEntry(certDBEntryNickname *entry, PRArenaPool *arena,
- SECItem *dbitem)
-{
- unsigned char *buf;
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN +
- SEC_DB_ENTRY_HEADER_LEN;
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
- buf[0] = (PRUint8)( entry->subjectName.len >> 8 );
- buf[1] = (PRUint8)( entry->subjectName.len );
- PORT_Memcpy(&buf[DB_NICKNAME_ENTRY_HEADER_LEN], entry->subjectName.data,
- entry->subjectName.len);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Encode a database key for a nickname record
- */
-static SECStatus
-EncodeDBNicknameKey(char *nickname, PRArenaPool *arena,
- SECItem *dbkey)
-{
- unsigned int nnlen;
-
- nnlen = PORT_Strlen(nickname) + 1; /* includes null */
-
- /* now get the database key and format it */
- dbkey->len = nnlen + SEC_DB_KEY_HEADER_LEN;
- if (dbkey->len > NSS_MAX_LEGACY_DB_KEY_SIZE)
- goto loser;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], nickname, nnlen);
- dbkey->data[0] = certDBEntryTypeNickname;
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-DecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry,
- char *nickname)
-{
- int lenDiff;
-
- /* is record long enough for header? */
- if ( dbentry->len < DB_NICKNAME_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* is database entry correct length? */
- entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
- lenDiff = dbentry->len -
- (entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN);
- if (lenDiff) {
- if (lenDiff < 0 || (lenDiff & 0xffff) != 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
- /* The entry size exceeded 64KB. Reconstruct the correct length. */
- entry->subjectName.len += lenDiff;
- }
-
- /* copy the certkey */
- entry->subjectName.data =
- (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->subjectName.len);
- if ( entry->subjectName.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->subjectName.data,
- &dbentry->data[DB_NICKNAME_ENTRY_HEADER_LEN],
- entry->subjectName.len);
- entry->subjectName.type = siBuffer;
-
- entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena,
- PORT_Strlen(nickname)+1);
- if ( entry->nickname ) {
- PORT_Strcpy(entry->nickname, nickname);
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * create a new nickname entry
- */
-static certDBEntryNickname *
-NewDBNicknameEntry(char *nickname, SECItem *subjectName, unsigned int flags)
-{
- PRArenaPool *arena = NULL;
- certDBEntryNickname *entry;
- int nnlen;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntryNickname));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* init common fields */
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeNickname;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- /* copy the nickname */
- nnlen = PORT_Strlen(nickname) + 1;
-
- entry->nickname = (char*)PORT_ArenaAlloc(arena, nnlen);
- if ( entry->nickname == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(entry->nickname, nickname, nnlen);
-
- rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- return(entry);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * delete a nickname entry
- */
-static SECStatus
-DeleteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv;
- SECItem dbkey;
-
- if ( nickname == NULL ) {
- return(SECSuccess);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBNicknameKey(nickname, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, certDBEntryTypeNickname, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Read a nickname entry
- */
-static certDBEntryNickname *
-ReadDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntryNickname *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntryNickname));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeNickname;
-
- rv = EncodeDBNicknameKey(nickname, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- /* is record long enough for header? */
- if ( dbentry.len < DB_NICKNAME_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- rv = DecodeDBNicknameEntry(entry, &dbentry, nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Encode a nickname entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryNickname *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBNicknameEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBNicknameKey(entry->nickname, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-
-}
-
-static SECStatus
-EncodeDBSMimeEntry(certDBEntrySMime *entry, PRArenaPool *arena,
- SECItem *dbitem)
-{
- unsigned char *buf;
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = entry->subjectName.len + entry->smimeOptions.len +
- entry->optionsDate.len +
- DB_SMIME_ENTRY_HEADER_LEN + SEC_DB_ENTRY_HEADER_LEN;
-
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
-
- buf[0] = (PRUint8)( entry->subjectName.len >> 8 );
- buf[1] = (PRUint8)( entry->subjectName.len );
- buf[2] = (PRUint8)( entry->smimeOptions.len >> 8 );
- buf[3] = (PRUint8)( entry->smimeOptions.len );
- buf[4] = (PRUint8)( entry->optionsDate.len >> 8 );
- buf[5] = (PRUint8)( entry->optionsDate.len );
-
- /* if no smime options, then there should not be an options date either */
- PORT_Assert( ! ( ( entry->smimeOptions.len == 0 ) &&
- ( entry->optionsDate.len != 0 ) ) );
-
- PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN], entry->subjectName.data,
- entry->subjectName.len);
- if ( entry->smimeOptions.len ) {
- PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN+entry->subjectName.len],
- entry->smimeOptions.data,
- entry->smimeOptions.len);
- PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len +
- entry->smimeOptions.len],
- entry->optionsDate.data,
- entry->optionsDate.len);
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Encode a database key for a SMIME record
- */
-static SECStatus
-EncodeDBSMimeKey(char *emailAddr, PRArenaPool *arena,
- SECItem *dbkey)
-{
- unsigned int addrlen;
-
- addrlen = PORT_Strlen(emailAddr) + 1; /* includes null */
-
- /* now get the database key and format it */
- dbkey->len = addrlen + SEC_DB_KEY_HEADER_LEN;
- if (dbkey->len > NSS_MAX_LEGACY_DB_KEY_SIZE)
- goto loser;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], emailAddr, addrlen);
- dbkey->data[0] = certDBEntryTypeSMimeProfile;
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Decode a database SMIME record
- */
-static SECStatus
-DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr)
-{
- int lenDiff;
-
- /* is record long enough for header? */
- if ( dbentry->len < DB_SMIME_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- /* is database entry correct length? */
- entry->subjectName.len = (( dbentry->data[0] << 8 ) | dbentry->data[1] );
- entry->smimeOptions.len = (( dbentry->data[2] << 8 ) | dbentry->data[3] );
- entry->optionsDate.len = (( dbentry->data[4] << 8 ) | dbentry->data[5] );
- lenDiff = dbentry->len - (entry->subjectName.len +
- entry->smimeOptions.len +
- entry->optionsDate.len +
- DB_SMIME_ENTRY_HEADER_LEN);
- if (lenDiff) {
- if (lenDiff < 0 || (lenDiff & 0xffff) != 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
- /* The entry size exceeded 64KB. Reconstruct the correct length. */
- entry->subjectName.len += lenDiff;
- }
-
- /* copy the subject name */
- entry->subjectName.data =
- (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->subjectName.len);
- if ( entry->subjectName.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->subjectName.data,
- &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN],
- entry->subjectName.len);
-
- /* copy the smime options */
- if ( entry->smimeOptions.len ) {
- entry->smimeOptions.data =
- (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->smimeOptions.len);
- if ( entry->smimeOptions.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->smimeOptions.data,
- &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +
- entry->subjectName.len],
- entry->smimeOptions.len);
- }
- if ( entry->optionsDate.len ) {
- entry->optionsDate.data =
- (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
- entry->optionsDate.len);
- if ( entry->optionsDate.data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->optionsDate.data,
- &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +
- entry->subjectName.len +
- entry->smimeOptions.len],
- entry->optionsDate.len);
- }
-
- /* both options and options date must either exist or not exist */
- if ( ( ( entry->optionsDate.len == 0 ) ||
- ( entry->smimeOptions.len == 0 ) ) &&
- entry->smimeOptions.len != entry->optionsDate.len ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- entry->emailAddr = (char *)PORT_ArenaAlloc(entry->common.arena,
- PORT_Strlen(emailAddr)+1);
- if ( entry->emailAddr ) {
- PORT_Strcpy(entry->emailAddr, emailAddr);
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * create a new SMIME entry
- */
-static certDBEntrySMime *
-NewDBSMimeEntry(char *emailAddr, SECItem *subjectName, SECItem *smimeOptions,
- SECItem *optionsDate, unsigned int flags)
-{
- PRArenaPool *arena = NULL;
- certDBEntrySMime *entry;
- int addrlen;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntrySMime));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* init common fields */
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeSMimeProfile;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- /* copy the email addr */
- addrlen = PORT_Strlen(emailAddr) + 1;
-
- entry->emailAddr = (char*)PORT_ArenaAlloc(arena, addrlen);
- if ( entry->emailAddr == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(entry->emailAddr, emailAddr, addrlen);
-
- /* copy the subject name */
- rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* copy the smime options */
- if ( smimeOptions ) {
- rv = SECITEM_CopyItem(arena, &entry->smimeOptions, smimeOptions);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- } else {
- PORT_Assert(optionsDate == NULL);
- entry->smimeOptions.data = NULL;
- entry->smimeOptions.len = 0;
- }
-
- /* copy the options date */
- if ( optionsDate ) {
- rv = SECITEM_CopyItem(arena, &entry->optionsDate, optionsDate);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- } else {
- PORT_Assert(smimeOptions == NULL);
- entry->optionsDate.data = NULL;
- entry->optionsDate.len = 0;
- }
-
- return(entry);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * delete a SMIME entry
- */
-static SECStatus
-DeleteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
-{
- PRArenaPool *arena = NULL;
- SECStatus rv;
- SECItem dbkey;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBSMimeKey(emailAddr, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, certDBEntryTypeSMimeProfile, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Read a SMIME entry
- */
-certDBEntrySMime *
-nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntrySMime *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntrySMime));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeSMimeProfile;
-
- rv = EncodeDBSMimeKey(emailAddr, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- /* is record long enough for header? */
- if ( dbentry.len < DB_SMIME_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- rv = DecodeDBSMimeEntry(entry, &dbentry, emailAddr);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Encode a SMIME entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySMime *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBSMimeEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBSMimeKey(entry->emailAddr, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-
-}
-
-/*
- * Encode a database subject record
- */
-static SECStatus
-EncodeDBSubjectEntry(certDBEntrySubject *entry, PRArenaPool *arena,
- SECItem *dbitem)
-{
- unsigned char *buf;
- int len;
- unsigned int ncerts;
- unsigned int i;
- unsigned char *tmpbuf;
- unsigned int nnlen = 0;
- unsigned int eaddrslen = 0;
- int keyidoff;
- SECItem *certKeys = entry->certKeys;
- SECItem *keyIDs = entry->keyIDs;;
-
- if ( entry->nickname ) {
- nnlen = PORT_Strlen(entry->nickname) + 1;
- }
- if ( entry->emailAddrs ) {
- eaddrslen = 2;
- for (i=0; i < entry->nemailAddrs; i++) {
- eaddrslen += PORT_Strlen(entry->emailAddrs[i]) + 1 + 2;
- }
- }
-
- ncerts = entry->ncerts;
-
- /* compute the length of the entry */
- keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen ;
- len = keyidoff + (4 * ncerts) + eaddrslen;
- for ( i = 0; i < ncerts; i++ ) {
- if (keyIDs[i].len > 0xffff ||
- (certKeys[i].len > 0xffff)) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- goto loser;
- }
- len += certKeys[i].len;
- len += keyIDs[i].len;
- }
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem->len = len + SEC_DB_ENTRY_HEADER_LEN;
-
- dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);
- if ( dbitem->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* fill in database record */
- buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];
-
- buf[0] = (PRUint8)( ncerts >> 8 );
- buf[1] = (PRUint8)( ncerts );
- buf[2] = (PRUint8)( nnlen >> 8 );
- buf[3] = (PRUint8)( nnlen );
- /* v7 email field is NULL in v8 */
- buf[4] = 0;
- buf[5] = 0;
-
- PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN], entry->nickname, nnlen);
- tmpbuf = &buf[keyidoff];
- for ( i = 0; i < ncerts; i++ ) {
- tmpbuf[0] = (PRUint8)( certKeys[i].len >> 8 );
- tmpbuf[1] = (PRUint8)( certKeys[i].len );
- tmpbuf += 2;
- }
- for ( i = 0; i < ncerts; i++ ) {
- tmpbuf[0] = (PRUint8)( keyIDs[i].len >> 8 );
- tmpbuf[1] = (PRUint8)( keyIDs[i].len );
- tmpbuf += 2;
- }
-
- for ( i = 0; i < ncerts; i++ ) {
- PORT_Memcpy(tmpbuf, certKeys[i].data, certKeys[i].len);
- tmpbuf += certKeys[i].len;
- }
- for ( i = 0; i < ncerts; i++ ) {
- PORT_Memcpy(tmpbuf, keyIDs[i].data, keyIDs[i].len);
- tmpbuf += keyIDs[i].len;
- }
-
- if (entry->emailAddrs) {
- tmpbuf[0] = (PRUint8)( entry->nemailAddrs >> 8 );
- tmpbuf[1] = (PRUint8)( entry->nemailAddrs );
- tmpbuf += 2;
- for (i=0; i < entry->nemailAddrs; i++) {
- int nameLen = PORT_Strlen(entry->emailAddrs[i]) + 1;
- tmpbuf[0] = (PRUint8)( nameLen >> 8 );
- tmpbuf[1] = (PRUint8)( nameLen );
- tmpbuf += 2;
- PORT_Memcpy(tmpbuf,entry->emailAddrs[i],nameLen);
- tmpbuf +=nameLen;
- }
- }
-
- PORT_Assert(tmpbuf == &buf[len]);
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * Encode a database key for a subject record
- */
-static SECStatus
-EncodeDBSubjectKey(SECItem *derSubject, PRArenaPool *arena,
- SECItem *dbkey)
-{
- dbkey->len = derSubject->len + SEC_DB_KEY_HEADER_LEN;
- if (dbkey->len > NSS_MAX_LEGACY_DB_KEY_SIZE)
- goto loser;
- dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);
- if ( dbkey->data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], derSubject->data,
- derSubject->len);
- dbkey->data[0] = certDBEntryTypeSubject;
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-static SECStatus
-DecodeDBSubjectEntry(certDBEntrySubject *entry, SECItem *dbentry,
- const SECItem *derSubject)
-{
- PRArenaPool *arena = entry->common.arena;
- unsigned char *tmpbuf;
- unsigned char *end;
- void *mark = PORT_ArenaMark(arena);
- unsigned int eaddrlen;
- unsigned int i;
- unsigned int keyidoff;
- unsigned int len;
- unsigned int ncerts = 0;
- unsigned int nnlen;
- SECStatus rv;
-
- rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* is record long enough for header? */
- if ( dbentry->len < DB_SUBJECT_ENTRY_HEADER_LEN ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- entry->ncerts = ncerts = (( dbentry->data[0] << 8 ) | dbentry->data[1] );
- nnlen = (( dbentry->data[2] << 8 ) | dbentry->data[3] );
- eaddrlen = (( dbentry->data[4] << 8 ) | dbentry->data[5] );
- keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen;
- len = keyidoff + (4 * ncerts);
- if ( dbentry->len < len) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- entry->certKeys = PORT_ArenaNewArray(arena, SECItem, ncerts);
- entry->keyIDs = PORT_ArenaNewArray(arena, SECItem, ncerts);
- if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- if ( nnlen > 1 ) { /* null terminator is stored */
- entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( entry->nickname == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->nickname,
- &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN],
- nnlen);
- } else {
- entry->nickname = NULL;
- }
-
- /* if we have an old style email entry, there is only one */
- entry->nemailAddrs = 0;
- if ( eaddrlen > 1 ) { /* null terminator is stored */
- entry->emailAddrs = PORT_ArenaNewArray(arena, char *, 2);
- if ( entry->emailAddrs == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->emailAddrs[0] = (char *)PORT_ArenaAlloc(arena, eaddrlen);
- if ( entry->emailAddrs[0] == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->emailAddrs[0],
- &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen],
- eaddrlen);
- entry->nemailAddrs = 1;
- } else {
- entry->emailAddrs = NULL;
- }
-
- /* collect the lengths of the certKeys and keyIDs, and total the
- * overall length.
- */
- tmpbuf = &dbentry->data[keyidoff];
- for ( i = 0; i < ncerts; i++ ) {
- unsigned int itemlen = ( tmpbuf[0] << 8 ) | tmpbuf[1];
- entry->certKeys[i].len = itemlen;
- len += itemlen;
- tmpbuf += 2;
- }
- for ( i = 0; i < ncerts; i++ ) {
- unsigned int itemlen = ( tmpbuf[0] << 8 ) | tmpbuf[1] ;
- entry->keyIDs[i].len = itemlen;
- len += itemlen;
- tmpbuf += 2;
- }
-
- /* is encoded entry large enough ? */
- if ( len > dbentry->len ){
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- for ( i = 0; i < ncerts; i++ ) {
- unsigned int kLen = entry->certKeys[i].len;
- entry->certKeys[i].data = (unsigned char *)PORT_ArenaAlloc(arena, kLen);
- if ( entry->certKeys[i].data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->certKeys[i].data, tmpbuf, kLen);
- tmpbuf += kLen;
- }
- for ( i = 0; i < ncerts; i++ ) {
- unsigned int iLen = entry->keyIDs[i].len;
- entry->keyIDs[i].data = (unsigned char *)PORT_ArenaAlloc(arena, iLen);
- if ( entry->keyIDs[i].data == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->keyIDs[i].data, tmpbuf, iLen);
- tmpbuf += iLen;
- }
-
- end = dbentry->data + dbentry->len;
- if ((eaddrlen == 0) && (end - tmpbuf > 1)) {
- /* read in the additional email addresses */
- entry->nemailAddrs = (((unsigned int)tmpbuf[0]) << 8) | tmpbuf[1];
- tmpbuf += 2;
- if (end - tmpbuf < 2 * (int)entry->nemailAddrs)
- goto loser;
- entry->emailAddrs = PORT_ArenaNewArray(arena, char *, entry->nemailAddrs);
- if (entry->emailAddrs == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- for (i=0; i < entry->nemailAddrs; i++) {
- int nameLen;
- if (end - tmpbuf < 2) {
- goto loser;
- }
- nameLen = (((int)tmpbuf[0]) << 8) | tmpbuf[1];
- tmpbuf += 2;
- if (end - tmpbuf < nameLen) {
- goto loser;
- }
- entry->emailAddrs[i] = PORT_ArenaAlloc(arena,nameLen);
- if (entry->emailAddrs == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- PORT_Memcpy(entry->emailAddrs[i], tmpbuf, nameLen);
- tmpbuf += nameLen;
- }
- if (tmpbuf != end)
- goto loser;
- }
- PORT_ArenaUnmark(arena, mark);
- return(SECSuccess);
-
-loser:
- PORT_ArenaRelease(arena, mark); /* discard above allocations */
- return(SECFailure);
-}
-
-/*
- * create a new subject entry with a single cert
- */
-static certDBEntrySubject *
-NewDBSubjectEntry(SECItem *derSubject, SECItem *certKey,
- SECItem *keyID, char *nickname, char *emailAddr,
- unsigned int flags)
-{
- PRArenaPool *arena = NULL;
- certDBEntrySubject *entry;
- SECStatus rv;
- unsigned int nnlen;
- unsigned int eaddrlen;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntrySubject));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* init common fields */
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeSubject;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- /* copy the subject */
- rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- entry->ncerts = 1;
- entry->nemailAddrs = 0;
- /* copy nickname */
- if ( nickname && ( *nickname != '\0' ) ) {
- nnlen = PORT_Strlen(nickname) + 1;
- entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( entry->nickname == NULL ) {
- goto loser;
- }
-
- PORT_Memcpy(entry->nickname, nickname, nnlen);
- } else {
- entry->nickname = NULL;
- }
-
- /* copy email addr */
- if ( emailAddr && ( *emailAddr != '\0' ) ) {
- emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
- if ( emailAddr == NULL ) {
- entry->emailAddrs = NULL;
- goto loser;
- }
-
- eaddrlen = PORT_Strlen(emailAddr) + 1;
- entry->emailAddrs = (char **)PORT_ArenaAlloc(arena, sizeof(char *));
- if ( entry->emailAddrs == NULL ) {
- PORT_Free(emailAddr);
- goto loser;
- }
- entry->emailAddrs[0] = PORT_ArenaStrdup(arena,emailAddr);
- if (entry->emailAddrs[0]) {
- entry->nemailAddrs = 1;
- }
-
- PORT_Free(emailAddr);
- } else {
- entry->emailAddrs = NULL;
- }
-
- /* allocate space for certKeys and keyIDs */
- entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
- entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
- if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) {
- goto loser;
- }
-
- /* copy the certKey and keyID */
- rv = SECITEM_CopyItem(arena, &entry->certKeys[0], certKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- rv = SECITEM_CopyItem(arena, &entry->keyIDs[0], keyID);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- return(entry);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * delete a subject entry
- */
-static SECStatus
-DeleteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
-{
- SECItem dbkey;
- PRArenaPool *arena = NULL;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBSubjectKey(derSubject, arena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = DeleteDBEntry(handle, certDBEntryTypeSubject, &dbkey);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(SECFailure);
-}
-
-/*
- * Read the subject entry
- */
-static certDBEntrySubject *
-ReadDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntrySubject *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntrySubject));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeSubject;
-
- rv = EncodeDBSubjectKey(derSubject, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- rv = DecodeDBSubjectEntry(entry, &dbentry, derSubject);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Encode a subject name entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySubject *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBSubjectEntry(entry, tmparena, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBSubjectKey(&entry->derSubject, tmparena, &dbkey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-
-}
-
-typedef enum { nsslowcert_remove, nsslowcert_add } nsslowcertUpdateType;
-
-static SECStatus
-nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
- SECItem *derSubject, char *emailAddr, nsslowcertUpdateType updateType)
-{
- certDBEntrySubject *entry = NULL;
- int index = -1, i;
- SECStatus rv;
-
- if (emailAddr) {
- emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
- if (emailAddr == NULL) {
- return SECFailure;
- }
- } else {
- return SECSuccess;
- }
-
- entry = ReadDBSubjectEntry(dbhandle,derSubject);
- if (entry == NULL) {
- rv = SECFailure;
- goto done;
- }
-
- for (i=0; i < (int)(entry->nemailAddrs); i++) {
- if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) {
- index = i;
- }
- }
-
- if (updateType == nsslowcert_remove) {
- if (index == -1) {
- rv = SECSuccess;
- goto done;
- }
- entry->nemailAddrs--;
- for (i=index; i < (int)(entry->nemailAddrs); i++) {
- entry->emailAddrs[i] = entry->emailAddrs[i+1];
- }
- } else {
- char **newAddrs = NULL;
-
- if (index != -1) {
- rv = SECSuccess;
- goto done;
- }
- newAddrs = (char **)PORT_ArenaAlloc(entry->common.arena,
- (entry->nemailAddrs+1)* sizeof(char *));
- if (!newAddrs) {
- rv = SECFailure;
- goto done;
- }
- for (i=0; i < (int)(entry->nemailAddrs); i++) {
- newAddrs[i] = entry->emailAddrs[i];
- }
- newAddrs[entry->nemailAddrs] =
- PORT_ArenaStrdup(entry->common.arena,emailAddr);
- if (!newAddrs[entry->nemailAddrs]) {
- rv = SECFailure;
- goto done;
- }
- entry->emailAddrs = newAddrs;
- entry->nemailAddrs++;
- }
-
- /* delete the subject entry */
- DeleteDBSubjectEntry(dbhandle, derSubject);
-
- /* write the new one */
- rv = WriteDBSubjectEntry(dbhandle, entry);
-
- done:
- if (entry) DestroyDBEntry((certDBEntry *)entry);
- if (emailAddr) PORT_Free(emailAddr);
- return rv;
-}
-
-/*
- * writes a nickname to an existing subject entry that does not currently
- * have one
- */
-static SECStatus
-AddNicknameToSubject(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname)
-{
- certDBEntrySubject *entry;
- SECStatus rv;
-
- if ( nickname == NULL ) {
- return(SECFailure);
- }
-
- entry = ReadDBSubjectEntry(dbhandle,&cert->derSubject);
- PORT_Assert(entry != NULL);
- if ( entry == NULL ) {
- goto loser;
- }
-
- PORT_Assert(entry->nickname == NULL);
- if ( entry->nickname != NULL ) {
- goto loser;
- }
-
- entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
-
- if ( entry->nickname == NULL ) {
- goto loser;
- }
-
- /* delete the subject entry */
- DeleteDBSubjectEntry(dbhandle, &cert->derSubject);
-
- /* write the new one */
- rv = WriteDBSubjectEntry(dbhandle, entry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * create a new version entry
- */
-static certDBEntryVersion *
-NewDBVersionEntry(unsigned int flags)
-{
- PRArenaPool *arena = NULL;
- certDBEntryVersion *entry;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena,
- sizeof(certDBEntryVersion));
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeVersion;
- entry->common.version = CERT_DB_FILE_VERSION;
- entry->common.flags = flags;
-
- return(entry);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-/*
- * Read the version entry
- */
-static certDBEntryVersion *
-ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle)
-{
- PRArenaPool *arena = NULL;
- PRArenaPool *tmparena = NULL;
- certDBEntryVersion *entry;
- SECItem dbkey;
- SECItem dbentry;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- entry = PORT_ArenaZNew(arena, certDBEntryVersion);
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
- entry->common.arena = arena;
- entry->common.type = certDBEntryTypeVersion;
-
- /* now get the database key and format it */
- dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
- dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
- if ( dbkey.data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,
- SEC_DB_VERSION_KEY_LEN);
-
- rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(entry);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(NULL);
-}
-
-
-/*
- * Encode a version entry into byte stream suitable for
- * the database
- */
-static SECStatus
-WriteDBVersionEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryVersion *entry)
-{
- SECItem dbitem, dbkey;
- PRArenaPool *tmparena = NULL;
- SECStatus rv;
-
- tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( tmparena == NULL ) {
- goto loser;
- }
-
- /* allocate space for encoded database record, including space
- * for low level header
- */
- dbitem.len = SEC_DB_ENTRY_HEADER_LEN;
-
- dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len);
- if ( dbitem.data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto loser;
- }
-
- /* now get the database key and format it */
- dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;
- dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);
- if ( dbkey.data == NULL ) {
- goto loser;
- }
- PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,
- SEC_DB_VERSION_KEY_LEN);
-
- /* now write it to the database */
- rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- PORT_FreeArena(tmparena, PR_FALSE);
- return(SECSuccess);
-
-loser:
- if ( tmparena ) {
- PORT_FreeArena(tmparena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-/*
- * cert is no longer a perm cert, but will remain a temp cert
- */
-static SECStatus
-RemovePermSubjectNode(NSSLOWCERTCertificate *cert)
-{
- certDBEntrySubject *entry;
- unsigned int i;
- SECStatus rv;
-
- entry = ReadDBSubjectEntry(cert->dbhandle,&cert->derSubject);
- if ( entry == NULL ) {
- return(SECFailure);
- }
-
- PORT_Assert(entry->ncerts);
- rv = SECFailure;
-
- if ( entry->ncerts > 1 ) {
- for ( i = 0; i < entry->ncerts; i++ ) {
- if ( SECITEM_CompareItem(&entry->certKeys[i], &cert->certKey) ==
- SECEqual ) {
- /* copy rest of list forward one entry */
- for ( i = i + 1; i < entry->ncerts; i++ ) {
- entry->certKeys[i-1] = entry->certKeys[i];
- entry->keyIDs[i-1] = entry->keyIDs[i];
- }
- entry->ncerts--;
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
- rv = WriteDBSubjectEntry(cert->dbhandle, entry);
- break;
- }
- }
- } else {
- /* no entries left, delete the perm entry in the DB */
- if ( entry->emailAddrs ) {
- /* if the subject had an email record, then delete it too */
- for (i=0; i < entry->nemailAddrs; i++) {
- DeleteDBSMimeEntry(cert->dbhandle, entry->emailAddrs[i]);
- }
- }
- if ( entry->nickname ) {
- DeleteDBNicknameEntry(cert->dbhandle, entry->nickname);
- }
-
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
- }
- DestroyDBEntry((certDBEntry *)entry);
-
- return(rv);
-}
-
-/*
- * add a cert to the perm subject list
- */
-static SECStatus
-AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
- char *nickname)
-{
- SECItem *newCertKeys, *newKeyIDs;
- unsigned int i, new_i;
- SECStatus rv;
- unsigned int ncerts;
-
- PORT_Assert(entry);
- ncerts = entry->ncerts;
-
- if ( nickname && entry->nickname ) {
- /* nicknames must be the same */
- PORT_Assert(PORT_Strcmp(nickname, entry->nickname) == 0);
- }
-
- if ( ( entry->nickname == NULL ) && ( nickname != NULL ) ) {
- /* copy nickname into the entry */
- entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
- if ( entry->nickname == NULL ) {
- return(SECFailure);
- }
- }
-
- /* a DB entry already exists, so add this cert */
- newCertKeys = PORT_ArenaZNewArray(entry->common.arena, SECItem, ncerts + 1);
- newKeyIDs = PORT_ArenaZNewArray(entry->common.arena, SECItem, ncerts + 1);
-
- if ( ( newCertKeys == NULL ) || ( newKeyIDs == NULL ) ) {
- return(SECFailure);
- }
-
- /* Step 1: copy certs older than "cert" into new entry. */
- for ( i = 0, new_i=0; i < ncerts; i++ ) {
- NSSLOWCERTCertificate *cmpcert;
- PRBool isNewer;
- cmpcert = nsslowcert_FindCertByKey(cert->dbhandle,
- &entry->certKeys[i]);
- /* The entry has been corrupted, remove it from the list */
- if (!cmpcert) {
- continue;
- }
-
- isNewer = nsslowcert_IsNewer(cert, cmpcert);
- nsslowcert_DestroyCertificate(cmpcert);
- if ( isNewer )
- break;
- /* copy this cert entry */
- newCertKeys[new_i] = entry->certKeys[i];
- newKeyIDs[new_i] = entry->keyIDs[i];
- new_i++;
- }
-
- /* Step 2: Add "cert" to the entry. */
- rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i],
- &cert->certKey);
- if ( rv != SECSuccess ) {
- return(SECFailure);
- }
- rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i],
- &cert->subjectKeyID);
- if ( rv != SECSuccess ) {
- return(SECFailure);
- }
- new_i++;
-
- /* Step 3: copy remaining certs (if any) from old entry to new. */
- for ( ; i < ncerts; i++ ,new_i++) {
- newCertKeys[new_i] = entry->certKeys[i];
- newKeyIDs[new_i] = entry->keyIDs[i];
- }
-
- /* update certKeys and keyIDs */
- entry->certKeys = newCertKeys;
- entry->keyIDs = newKeyIDs;
-
- /* set new count value */
- entry->ncerts = new_i;
-
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
- rv = WriteDBSubjectEntry(cert->dbhandle, entry);
- return(rv);
-}
-
-
-SECStatus
-nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
- SECItem *derSubject,
- NSSLOWCERTCertCallback cb, void *cbarg)
-{
- certDBEntrySubject *entry;
- unsigned int i;
- NSSLOWCERTCertificate *cert;
- SECStatus rv = SECSuccess;
-
- entry = ReadDBSubjectEntry(handle, derSubject);
-
- if ( entry == NULL ) {
- return(SECFailure);
- }
-
- for( i = 0; i < entry->ncerts; i++ ) {
- cert = nsslowcert_FindCertByKey(handle, &entry->certKeys[i]);
- if (!cert) {
- continue;
- }
- rv = (* cb)(cert, cbarg);
- nsslowcert_DestroyCertificate(cert);
- if ( rv == SECFailure ) {
- break;
- }
- }
-
- DestroyDBEntry((certDBEntry *)entry);
-
- return(rv);
-}
-
-int
-nsslowcert_NumPermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
- SECItem *derSubject)
-{
- certDBEntrySubject *entry;
- int ret;
-
- entry = ReadDBSubjectEntry(handle, derSubject);
-
- if ( entry == NULL ) {
- return(SECFailure);
- }
-
- ret = entry->ncerts;
-
- DestroyDBEntry((certDBEntry *)entry);
-
- return(ret);
-}
-
-SECStatus
-nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
- char *nickname, NSSLOWCERTCertCallback cb, void *cbarg)
-{
- certDBEntryNickname *nnentry = NULL;
- certDBEntrySMime *smentry = NULL;
- SECStatus rv;
- SECItem *derSubject = NULL;
-
- nnentry = ReadDBNicknameEntry(handle, nickname);
- if ( nnentry ) {
- derSubject = &nnentry->subjectName;
- } else {
- smentry = nsslowcert_ReadDBSMimeEntry(handle, nickname);
- if ( smentry ) {
- derSubject = &smentry->subjectName;
- }
- }
-
- if ( derSubject ) {
- rv = nsslowcert_TraversePermCertsForSubject(handle, derSubject,
- cb, cbarg);
- } else {
- rv = SECFailure;
- }
-
- if ( nnentry ) {
- DestroyDBEntry((certDBEntry *)nnentry);
- }
- if ( smentry ) {
- DestroyDBEntry((certDBEntry *)smentry);
- }
-
- return(rv);
-}
-
-int
-nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle,
- char *nickname)
-{
- certDBEntryNickname *entry;
- int ret;
-
- entry = ReadDBNicknameEntry(handle, nickname);
-
- if ( entry ) {
- ret = nsslowcert_NumPermCertsForSubject(handle, &entry->subjectName);
- DestroyDBEntry((certDBEntry *)entry);
- } else {
- ret = 0;
- }
- return(ret);
-}
-
-/*
- * add a nickname to a cert that doesn't have one
- */
-static SECStatus
-AddNicknameToPermCert(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname)
-{
- certDBEntryCert *entry;
- int rv;
-
- entry = cert->dbEntry;
- PORT_Assert(entry != NULL);
- if ( entry == NULL ) {
- goto loser;
- }
-
- pkcs11_freeNickname(entry->nickname,entry->nicknameSpace);
- entry->nickname = NULL;
- entry->nickname = pkcs11_copyNickname(nickname,entry->nicknameSpace,
- sizeof(entry->nicknameSpace));
-
- rv = WriteDBCertEntry(dbhandle, entry);
- if ( rv ) {
- goto loser;
- }
-
- pkcs11_freeNickname(cert->nickname,cert->nicknameSpace);
- cert->nickname = NULL;
- cert->nickname = pkcs11_copyNickname(nickname,cert->nicknameSpace,
- sizeof(cert->nicknameSpace));
-
- return(SECSuccess);
-
-loser:
- return(SECFailure);
-}
-
-/*
- * add a nickname to a cert that is already in the perm database, but doesn't
- * have one yet (it is probably an e-mail cert).
- */
-SECStatus
-nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname)
-{
- SECStatus rv = SECFailure;
- certDBEntrySubject *entry = NULL;
- certDBEntryNickname *nicknameEntry = NULL;
-
- nsslowcert_LockDB(dbhandle);
-
- entry = ReadDBSubjectEntry(dbhandle, &cert->derSubject);
- if (entry == NULL) goto loser;
-
- if ( entry->nickname == NULL ) {
-
- /* no nickname for subject */
- rv = AddNicknameToSubject(dbhandle, cert, nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- rv = AddNicknameToPermCert(dbhandle, cert, nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0);
- if ( nicknameEntry == NULL ) {
- goto loser;
- }
-
- rv = WriteDBNicknameEntry(dbhandle, nicknameEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- } else {
- /* subject already has a nickname */
- rv = AddNicknameToPermCert(dbhandle, cert, entry->nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- /* make sure nickname entry exists. If the database was corrupted,
- * we may have lost the nickname entry. Add it back now */
- nicknameEntry = ReadDBNicknameEntry(dbhandle, entry->nickname);
- if (nicknameEntry == NULL ) {
- nicknameEntry = NewDBNicknameEntry(entry->nickname,
- &cert->derSubject, 0);
- if ( nicknameEntry == NULL ) {
- goto loser;
- }
-
- rv = WriteDBNicknameEntry(dbhandle, nicknameEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
- }
- rv = SECSuccess;
-
-loser:
- if (entry) {
- DestroyDBEntry((certDBEntry *)entry);
- }
- if (nicknameEntry) {
- DestroyDBEntry((certDBEntry *)nicknameEntry);
- }
- nsslowcert_UnlockDB(dbhandle);
- return(rv);
-}
-
-static certDBEntryCert *
-AddCertToPermDB(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTCertificate *cert,
- char *nickname, NSSLOWCERTCertTrust *trust)
-{
- certDBEntryCert *certEntry = NULL;
- certDBEntryNickname *nicknameEntry = NULL;
- certDBEntrySubject *subjectEntry = NULL;
- int state = 0;
- SECStatus rv;
- PRBool donnentry = PR_FALSE;
-
- if ( nickname ) {
- donnentry = PR_TRUE;
- }
-
- subjectEntry = ReadDBSubjectEntry(handle, &cert->derSubject);
-
- if ( subjectEntry && subjectEntry->nickname ) {
- donnentry = PR_FALSE;
- nickname = subjectEntry->nickname;
- }
-
- certEntry = NewDBCertEntry(&cert->derCert, nickname, trust, 0);
- if ( certEntry == NULL ) {
- goto loser;
- }
-
- if ( donnentry ) {
- nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0);
- if ( nicknameEntry == NULL ) {
- goto loser;
- }
- }
-
- rv = WriteDBCertEntry(handle, certEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- state = 1;
-
- if ( nicknameEntry ) {
- rv = WriteDBNicknameEntry(handle, nicknameEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- state = 2;
-
- /* "Change" handles if necessary */
- cert->dbhandle = handle;
-
- /* add to or create new subject entry */
- if ( subjectEntry ) {
- /* REWRITE BASED ON SUBJECT ENTRY */
- rv = AddPermSubjectNode(subjectEntry, cert, nickname);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- } else {
- /* make a new subject entry - this case is only used when updating
- * an old version of the database. This is OK because the oldnickname
- * db format didn't allow multiple certs with the same subject.
- */
- /* where does subjectKeyID and certKey come from? */
- subjectEntry = NewDBSubjectEntry(&cert->derSubject, &cert->certKey,
- &cert->subjectKeyID, nickname,
- NULL, 0);
- if ( subjectEntry == NULL ) {
- goto loser;
- }
- rv = WriteDBSubjectEntry(handle, subjectEntry);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- state = 3;
-
- if ( nicknameEntry ) {
- DestroyDBEntry((certDBEntry *)nicknameEntry);
- }
-
- if ( subjectEntry ) {
- DestroyDBEntry((certDBEntry *)subjectEntry);
- }
-
- return(certEntry);
-
-loser:
- /* don't leave partial entry in the database */
- if ( state > 0 ) {
- rv = DeleteDBCertEntry(handle, &cert->certKey);
- }
- if ( ( state > 1 ) && donnentry ) {
- rv = DeleteDBNicknameEntry(handle, nickname);
- }
- if ( state > 2 ) {
- rv = DeleteDBSubjectEntry(handle, &cert->derSubject);
- }
- if ( certEntry ) {
- DestroyDBEntry((certDBEntry *)certEntry);
- }
- if ( nicknameEntry ) {
- DestroyDBEntry((certDBEntry *)nicknameEntry);
- }
- if ( subjectEntry ) {
- DestroyDBEntry((certDBEntry *)subjectEntry);
- }
-
- return(NULL);
-}
-
-/* forward declaration */
-static SECStatus
-UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb);
-
-/*
- * version 8 uses the same schema as version 7. The only differences are
- * 1) version 8 db uses the blob shim to store data entries > 32k.
- * 2) version 8 db sets the db block size to 32k.
- * both of these are dealt with by the handle.
- */
-
-static SECStatus
-UpdateV8DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
-{
- return UpdateV7DB(handle,updatedb);
-}
-
-
-/*
- * we could just blindly sequence through reading key data pairs and writing
- * them back out, but some cert.db's have gotten quite large and may have some
- * subtle corruption problems, so instead we cycle through the certs and
- * CRL's and S/MIME profiles and rebuild our subject lists from those records.
- */
-static SECStatus
-UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
-{
- DBT key, data;
- int ret;
- NSSLOWCERTCertificate *cert;
- PRBool isKRL = PR_FALSE;
- certDBEntryType entryType;
- SECItem dbEntry, dbKey;
- certDBEntryRevocation crlEntry;
- certDBEntryCert certEntry;
- certDBEntrySMime smimeEntry;
- SECStatus rv;
-
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
-
- if ( ret ) {
- return(SECFailure);
- }
-
- do {
- unsigned char *dataBuf = (unsigned char *)data.data;
- unsigned char *keyBuf = (unsigned char *)key.data;
- dbEntry.data = &dataBuf[SEC_DB_ENTRY_HEADER_LEN];
- dbEntry.len = data.size - SEC_DB_ENTRY_HEADER_LEN;
- entryType = (certDBEntryType) keyBuf[0];
- dbKey.data = &keyBuf[SEC_DB_KEY_HEADER_LEN];
- dbKey.len = key.size - SEC_DB_KEY_HEADER_LEN;
- if ((dbEntry.len <= 0) || (dbKey.len <= 0)) {
- continue;
- }
-
- switch (entryType) {
- /* these entries will get regenerated as we read the
- * rest of the data from the database */
- case certDBEntryTypeVersion:
- case certDBEntryTypeSubject:
- case certDBEntryTypeContentVersion:
- case certDBEntryTypeNickname:
- /* smime profiles need entries created after the certs have
- * been imported, loop over them in a second run */
- case certDBEntryTypeSMimeProfile:
- break;
-
- case certDBEntryTypeCert:
- /* decode Entry */
- certEntry.common.version = (unsigned int)dataBuf[0];
- certEntry.common.type = entryType;
- certEntry.common.flags = (unsigned int)dataBuf[2];
- rv = DecodeDBCertEntry(&certEntry,&dbEntry);
- if (rv != SECSuccess) {
- break;
- }
- /* should we check for existing duplicates? */
- cert = nsslowcert_DecodeDERCertificate(&certEntry.derCert,
- certEntry.nickname);
- if (cert) {
- nsslowcert_UpdatePermCert(handle, cert, certEntry.nickname,
- &certEntry.trust);
- nsslowcert_DestroyCertificate(cert);
- }
- /* free any data the decode may have allocated. */
- pkcs11_freeStaticData(certEntry.derCert.data,
- certEntry.derCertSpace);
- pkcs11_freeNickname(certEntry.nickname, certEntry.nicknameSpace);
- break;
-
- case certDBEntryTypeKeyRevocation:
- isKRL = PR_TRUE;
- /* fall through */
- case certDBEntryTypeRevocation:
- crlEntry.common.version = (unsigned int)dataBuf[0];
- crlEntry.common.type = entryType;
- crlEntry.common.flags = (unsigned int)dataBuf[2];
- crlEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (crlEntry.common.arena == NULL) {
- break;
- }
- rv = DecodeDBCrlEntry(&crlEntry,&dbEntry);
- if (rv != SECSuccess) {
- break;
- }
- nsslowcert_UpdateCrl(handle, &crlEntry.derCrl, &dbKey,
- crlEntry.url, isKRL);
- /* free data allocated by the decode */
- PORT_FreeArena(crlEntry.common.arena, PR_FALSE);
- crlEntry.common.arena = NULL;
- break;
-
- default:
- break;
- }
- } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
-
- /* now loop again updating just the SMimeProfile. */
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
-
- if ( ret ) {
- return(SECFailure);
- }
-
- do {
- unsigned char *dataBuf = (unsigned char *)data.data;
- unsigned char *keyBuf = (unsigned char *)key.data;
- dbEntry.data = &dataBuf[SEC_DB_ENTRY_HEADER_LEN];
- dbEntry.len = data.size - SEC_DB_ENTRY_HEADER_LEN;
- entryType = (certDBEntryType) keyBuf[0];
- if (entryType != certDBEntryTypeSMimeProfile) {
- continue;
- }
- dbKey.data = &keyBuf[SEC_DB_KEY_HEADER_LEN];
- dbKey.len = key.size - SEC_DB_KEY_HEADER_LEN;
- if ((dbEntry.len <= 0) || (dbKey.len <= 0)) {
- continue;
- }
- smimeEntry.common.version = (unsigned int)dataBuf[0];
- smimeEntry.common.type = entryType;
- smimeEntry.common.flags = (unsigned int)dataBuf[2];
- smimeEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- /* decode entry */
- rv = DecodeDBSMimeEntry(&smimeEntry,&dbEntry,(char *)dbKey.data);
- if (rv == SECSuccess) {
- nsslowcert_UpdateSMimeProfile(handle, smimeEntry.emailAddr,
- &smimeEntry.subjectName, &smimeEntry.smimeOptions,
- &smimeEntry.optionsDate);
- }
- PORT_FreeArena(smimeEntry.common.arena, PR_FALSE);
- smimeEntry.common.arena = NULL;
- } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
-
- (* updatedb->close)(updatedb);
-
- /* a database update is a good time to go back and verify the integrity of
- * the keys and certs */
- handle->dbVerify = PR_TRUE;
- return(SECSuccess);
-}
-
-/*
- * NOTE - Version 6 DB did not go out to the real world in a release,
- * so we can remove this function in a later release.
- */
-static SECStatus
-UpdateV6DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
-{
- int ret;
- DBT key, data;
- unsigned char *buf, *tmpbuf = NULL;
- certDBEntryType type;
- certDBEntryNickname *nnEntry = NULL;
- certDBEntrySubject *subjectEntry = NULL;
- certDBEntrySMime *emailEntry = NULL;
- char *nickname;
- char *emailAddr;
- SECStatus rv;
-
- /*
- * Sequence through the old database and copy all of the entries
- * to the new database. Subject name entries will have the new
- * fields inserted into them (with zero length).
- */
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
- }
-
- do {
- buf = (unsigned char *)data.data;
-
- if ( data.size >= 3 ) {
- if ( buf[0] == 6 ) { /* version number */
- type = (certDBEntryType)buf[1];
- if ( type == certDBEntryTypeSubject ) {
- /* expando subjecto entrieo */
- tmpbuf = (unsigned char *)PORT_Alloc(data.size + 4);
- if ( tmpbuf ) {
- /* copy header stuff */
- PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN + 2);
- /* insert 4 more bytes of zero'd header */
- PORT_Memset(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 2],
- 0, 4);
- /* copy rest of the data */
- PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6],
- &buf[SEC_DB_ENTRY_HEADER_LEN + 2],
- data.size - (SEC_DB_ENTRY_HEADER_LEN + 2));
-
- data.data = (void *)tmpbuf;
- data.size += 4;
- buf = tmpbuf;
- }
- } else if ( type == certDBEntryTypeCert ) {
- /* expando certo entrieo */
- tmpbuf = (unsigned char *)PORT_Alloc(data.size + 3);
- if ( tmpbuf ) {
- /* copy header stuff */
- PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN);
-
- /* copy trust flage, setting msb's to 0 */
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN] = 0;
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+1] =
- buf[SEC_DB_ENTRY_HEADER_LEN];
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+2] = 0;
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+3] =
- buf[SEC_DB_ENTRY_HEADER_LEN+1];
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+4] = 0;
- tmpbuf[SEC_DB_ENTRY_HEADER_LEN+5] =
- buf[SEC_DB_ENTRY_HEADER_LEN+2];
-
- /* copy rest of the data */
- PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6],
- &buf[SEC_DB_ENTRY_HEADER_LEN + 3],
- data.size - (SEC_DB_ENTRY_HEADER_LEN + 3));
-
- data.data = (void *)tmpbuf;
- data.size += 3;
- buf = tmpbuf;
- }
-
- }
-
- /* update the record version number */
- buf[0] = CERT_DB_FILE_VERSION;
-
- /* copy to the new database */
- ret = certdb_Put(handle->permCertDB, &key, &data, 0);
- if ( tmpbuf ) {
- PORT_Free(tmpbuf);
- tmpbuf = NULL;
- }
- }
- }
- } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
-
- ret = certdb_Sync(handle->permCertDB, 0);
-
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
- }
-
- do {
- buf = (unsigned char *)data.data;
-
- if ( data.size >= 3 ) {
- if ( buf[0] == CERT_DB_FILE_VERSION ) { /* version number */
- type = (certDBEntryType)buf[1];
- if ( type == certDBEntryTypeNickname ) {
- nickname = &((char *)key.data)[1];
-
- /* get the matching nickname entry in the new DB */
- nnEntry = ReadDBNicknameEntry(handle, nickname);
- if ( nnEntry == NULL ) {
- goto endloop;
- }
-
- /* find the subject entry pointed to by nickname */
- subjectEntry = ReadDBSubjectEntry(handle,
- &nnEntry->subjectName);
- if ( subjectEntry == NULL ) {
- goto endloop;
- }
-
- subjectEntry->nickname =
- (char *)PORT_ArenaAlloc(subjectEntry->common.arena,
- key.size - 1);
- if ( subjectEntry->nickname ) {
- PORT_Memcpy(subjectEntry->nickname, nickname,
- key.size - 1);
- rv = WriteDBSubjectEntry(handle, subjectEntry);
- }
- } else if ( type == certDBEntryTypeSMimeProfile ) {
- emailAddr = &((char *)key.data)[1];
-
- /* get the matching smime entry in the new DB */
- emailEntry = nsslowcert_ReadDBSMimeEntry(handle, emailAddr);
- if ( emailEntry == NULL ) {
- goto endloop;
- }
-
- /* find the subject entry pointed to by nickname */
- subjectEntry = ReadDBSubjectEntry(handle,
- &emailEntry->subjectName);
- if ( subjectEntry == NULL ) {
- goto endloop;
- }
-
- subjectEntry->emailAddrs = (char **)
- PORT_ArenaAlloc(subjectEntry->common.arena,
- sizeof(char *));
- if ( subjectEntry->emailAddrs ) {
- subjectEntry->emailAddrs[0] =
- (char *)PORT_ArenaAlloc(subjectEntry->common.arena,
- key.size - 1);
- if ( subjectEntry->emailAddrs[0] ) {
- PORT_Memcpy(subjectEntry->emailAddrs[0], emailAddr,
- key.size - 1);
- subjectEntry->nemailAddrs = 1;
- rv = WriteDBSubjectEntry(handle, subjectEntry);
- }
- }
- }
-
-endloop:
- if ( subjectEntry ) {
- DestroyDBEntry((certDBEntry *)subjectEntry);
- subjectEntry = NULL;
- }
- if ( nnEntry ) {
- DestroyDBEntry((certDBEntry *)nnEntry);
- nnEntry = NULL;
- }
- if ( emailEntry ) {
- DestroyDBEntry((certDBEntry *)emailEntry);
- emailEntry = NULL;
- }
- }
- }
- } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
-
- ret = certdb_Sync(handle->permCertDB, 0);
-
- (* updatedb->close)(updatedb);
- return(SECSuccess);
-}
-
-
-static SECStatus
-updateV5Callback(NSSLOWCERTCertificate *cert, SECItem *k, void *pdata)
-{
- NSSLOWCERTCertDBHandle *handle;
- certDBEntryCert *entry;
- NSSLOWCERTCertTrust *trust;
-
- handle = (NSSLOWCERTCertDBHandle *)pdata;
- trust = &cert->dbEntry->trust;
-
- /* SSL user certs can be used for email if they have an email addr */
- if ( cert->emailAddr && ( trust->sslFlags & CERTDB_USER ) &&
- ( trust->emailFlags == 0 ) ) {
- trust->emailFlags = CERTDB_USER;
- }
- /* servers didn't set the user flags on the server cert.. */
- if (PORT_Strcmp(cert->dbEntry->nickname,"Server-Cert") == 0) {
- trust->sslFlags |= CERTDB_USER;
- }
-
- entry = AddCertToPermDB(handle, cert, cert->dbEntry->nickname,
- &cert->dbEntry->trust);
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
- }
-
- return(SECSuccess);
-}
-
-static SECStatus
-UpdateV5DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
-{
- NSSLOWCERTCertDBHandle updatehandle;
- SECStatus rv;
-
- updatehandle.permCertDB = updatedb;
- updatehandle.dbMon = PZ_NewMonitor(nssILockCertDB);
- updatehandle.dbVerify = 0;
- updatehandle.ref = 1; /* prevent premature close */
-
- rv = nsslowcert_TraversePermCerts(&updatehandle, updateV5Callback,
- (void *)handle);
-
- PZ_DestroyMonitor(updatehandle.dbMon);
-
- (* updatedb->close)(updatedb);
- return(SECSuccess);
-}
-
-static PRBool
-isV4DB(DB *db) {
- DBT key,data;
- int ret;
-
- key.data = "Version";
- key.size = 7;
-
- ret = (*db->get)(db, &key, &data, 0);
- if (ret) {
- return PR_FALSE;
- }
-
- if ((data.size == 1) && (*(unsigned char *)data.data <= 4)) {
- return PR_TRUE;
- }
-
- return PR_FALSE;
-}
-
-static SECStatus
-UpdateV4DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
-{
- DBT key, data;
- certDBEntryCert *entry, *entry2;
- int ret;
- PRArenaPool *arena = NULL;
- NSSLOWCERTCertificate *cert;
-
- ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST);
-
- if ( ret ) {
- return(SECFailure);
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return(SECFailure);
- }
-
- do {
- if ( data.size != 1 ) { /* skip version number */
-
- /* decode the old DB entry */
- entry = (certDBEntryCert *)
- DecodeV4DBCertEntry((unsigned char*)data.data, data.size);
-
- if ( entry ) {
- cert = nsslowcert_DecodeDERCertificate(&entry->derCert,
- entry->nickname);
-
- if ( cert != NULL ) {
- /* add to new database */
- entry2 = AddCertToPermDB(handle, cert, entry->nickname,
- &entry->trust);
-
- nsslowcert_DestroyCertificate(cert);
- if ( entry2 ) {
- DestroyDBEntry((certDBEntry *)entry2);
- }
- }
- DestroyDBEntry((certDBEntry *)entry);
- }
- }
- } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 );
-
- PORT_FreeArena(arena, PR_FALSE);
- (* updatedb->close)(updatedb);
- return(SECSuccess);
-}
-
-
-/*
- * return true if a database key conflict exists
- */
-PRBool
-nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle)
-{
- SECStatus rv;
- DBT tmpdata;
- DBT namekey;
- int ret;
- SECItem keyitem;
- PRArenaPool *arena = NULL;
- SECItem derKey;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- /* get the db key of the cert */
- rv = nsslowcert_KeyFromDERCert(arena, derCert, &derKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBCertKey(&derKey, arena, &keyitem);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- namekey.data = keyitem.data;
- namekey.size = keyitem.len;
-
- ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0);
- if ( ret == 0 ) {
- goto loser;
- }
-
- PORT_FreeArena(arena, PR_FALSE);
-
- return(PR_FALSE);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(PR_TRUE);
-}
-
-/*
- * return true if a nickname conflict exists
- * NOTE: caller must have already made sure that this exact cert
- * doesn't exist in the DB
- */
-static PRBool
-nsslowcert_CertNicknameConflict(char *nickname, SECItem *derSubject,
- NSSLOWCERTCertDBHandle *handle)
-{
- PRBool rv;
- certDBEntryNickname *entry;
-
- if ( nickname == NULL ) {
- return(PR_FALSE);
- }
-
- entry = ReadDBNicknameEntry(handle, nickname);
-
- if ( entry == NULL ) {
- /* no entry for this nickname, so no conflict */
- return(PR_FALSE);
- }
-
- rv = PR_TRUE;
- if ( SECITEM_CompareItem(derSubject, &entry->subjectName) == SECEqual ) {
- /* if subject names are the same, then no conflict */
- rv = PR_FALSE;
- }
-
- DestroyDBEntry((certDBEntry *)entry);
- return(rv);
-}
-
-#ifdef DBM_USING_NSPR
-#define NO_RDONLY PR_RDONLY
-#define NO_RDWR PR_RDWR
-#define NO_CREATE (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE)
-#else
-#define NO_RDONLY O_RDONLY
-#define NO_RDWR O_RDWR
-#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC)
-#endif
-
-/*
- * open an old database that needs to be updated
- */
-static DB *
-nsslowcert_openolddb(NSSLOWCERTDBNameFunc namecb, void *cbarg, int version)
-{
- char * tmpname;
- DB *updatedb = NULL;
-
- tmpname = (* namecb)(cbarg, version); /* get v6 db name */
- if ( tmpname ) {
- updatedb = dbopen( tmpname, NO_RDONLY, 0600, DB_HASH, 0 );
- PORT_Free(tmpname);
- }
- return updatedb;
-}
-
-static SECStatus
-openNewCertDB(const char *appName, const char *prefix, const char *certdbname,
- NSSLOWCERTCertDBHandle *handle, NSSLOWCERTDBNameFunc namecb, void *cbarg)
-{
- SECStatus rv;
- certDBEntryVersion *versionEntry = NULL;
- DB *updatedb = NULL;
- int status = RDB_FAIL;
-
- if (appName) {
- handle->permCertDB=rdbopen( appName, prefix, "cert", NO_CREATE, &status);
- } else {
- handle->permCertDB=dbsopen(certdbname, NO_CREATE, 0600, DB_HASH, 0);
- }
-
- /* if create fails then we lose */
- if ( handle->permCertDB == 0 ) {
- return status == RDB_RETRY ? SECWouldBlock : SECFailure;
- }
-
- /* Verify version number; */
- versionEntry = NewDBVersionEntry(0);
- if ( versionEntry == NULL ) {
- rv = SECFailure;
- goto loser;
- }
-
- rv = WriteDBVersionEntry(handle, versionEntry);
-
- DestroyDBEntry((certDBEntry *)versionEntry);
-
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* rv must already be Success here because of previous if statement */
- /* try to upgrade old db here */
- if (appName &&
- (updatedb = dbsopen(certdbname, NO_RDONLY, 0600, DB_HASH, 0)) != NULL) {
- rv = UpdateV8DB(handle, updatedb);
- } else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,7)) != NULL) {
- rv = UpdateV7DB(handle, updatedb);
- } else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,6)) != NULL) {
- rv = UpdateV6DB(handle, updatedb);
- } else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,5)) != NULL) {
- rv = UpdateV5DB(handle, updatedb);
- } else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,4)) != NULL) {
- /* NES has v5 format db's with v4 db names! */
- if (isV4DB(updatedb)) {
- rv = UpdateV4DB(handle,updatedb);
- } else {
- rv = UpdateV5DB(handle,updatedb);
- }
- }
-
-
-loser:
- db_InitComplete(handle->permCertDB);
- return rv;
-}
-
-static int
-nsslowcert_GetVersionNumber( NSSLOWCERTCertDBHandle *handle)
-{
- certDBEntryVersion *versionEntry = NULL;
- int version = 0;
-
- versionEntry = ReadDBVersionEntry(handle);
- if ( versionEntry == NULL ) {
- return 0;
- }
- version = versionEntry->common.version;
- DestroyDBEntry((certDBEntry *)versionEntry);
- return version;
-}
-
-/*
- * Open the certificate database and index databases. Create them if
- * they are not there or bad.
- */
-static SECStatus
-nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
- const char *appName, const char *prefix,
- NSSLOWCERTDBNameFunc namecb, void *cbarg)
-{
- SECStatus rv;
- int openflags;
- char *certdbname;
- int version = 0;
-
- certdbname = (* namecb)(cbarg, CERT_DB_FILE_VERSION);
- if ( certdbname == NULL ) {
- return(SECFailure);
- }
-
- openflags = readOnly ? NO_RDONLY : NO_RDWR;
-
- /*
- * first open the permanent file based database.
- */
- if (appName) {
- handle->permCertDB = rdbopen( appName, prefix, "cert", openflags, NULL);
- } else {
- handle->permCertDB = dbsopen( certdbname, openflags, 0600, DB_HASH, 0 );
- }
-
- /* check for correct version number */
- if ( handle->permCertDB ) {
- version = nsslowcert_GetVersionNumber(handle);
- if ((version != CERT_DB_FILE_VERSION) &&
- !(appName && version == CERT_DB_V7_FILE_VERSION)) {
- goto loser;
- }
- } else if ( readOnly ) {
- /* don't create if readonly */
- /* Try openning a version 7 database */
- handle->permCertDB = nsslowcert_openolddb(namecb,cbarg, 7);
- if (!handle->permCertDB) {
- goto loser;
- }
- if (nsslowcert_GetVersionNumber(handle) != 7) {
- goto loser;
- }
- } else {
- /* if first open fails, try to create a new DB */
- rv = openNewCertDB(appName,prefix,certdbname,handle,namecb,cbarg);
- if (rv == SECWouldBlock) {
- /* only the rdb version can fail with wouldblock */
- handle->permCertDB =
- rdbopen( appName, prefix, "cert", openflags, NULL);
-
- /* check for correct version number */
- if ( !handle->permCertDB ) {
- goto loser;
- }
- version = nsslowcert_GetVersionNumber(handle);
- if ((version != CERT_DB_FILE_VERSION) &&
- !(appName && version == CERT_DB_V7_FILE_VERSION)) {
- goto loser;
- }
- } else if (rv != SECSuccess) {
- goto loser;
- }
- }
-
- PORT_Free(certdbname);
-
- return (SECSuccess);
-
-loser:
-
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
-
- if ( handle->permCertDB ) {
- certdb_Close(handle->permCertDB);
- handle->permCertDB = 0;
- }
-
- PORT_Free(certdbname);
-
- return(SECFailure);
-}
-
-/*
- * delete all DB records associated with a particular certificate
- */
-static SECStatus
-DeletePermCert(NSSLOWCERTCertificate *cert)
-{
- SECStatus rv;
- SECStatus ret;
-
- ret = SECSuccess;
-
- rv = DeleteDBCertEntry(cert->dbhandle, &cert->certKey);
- if ( rv != SECSuccess ) {
- ret = SECFailure;
- }
-
- rv = RemovePermSubjectNode(cert);
-
-
- return(ret);
-}
-
-/*
- * Delete a certificate from the permanent database.
- */
-SECStatus
-nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert)
-{
- SECStatus rv;
-
- nsslowcert_LockDB(cert->dbhandle);
-
- /* delete the records from the permanent database */
- rv = DeletePermCert(cert);
-
- /* get rid of dbcert and stuff pointing to it */
- DestroyDBEntry((certDBEntry *)cert->dbEntry);
- cert->dbEntry = NULL;
- cert->trust = NULL;
-
- nsslowcert_UnlockDB(cert->dbhandle);
- return(rv);
-}
-
-/*
- * Traverse all of the entries in the database of a particular type
- * call the given function for each one.
- */
-SECStatus
-nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle,
- certDBEntryType type,
- SECStatus (* callback)(SECItem *data, SECItem *key,
- certDBEntryType type, void *pdata),
- void *udata )
-{
- DBT data;
- DBT key;
- SECStatus rv = SECSuccess;
- int ret;
- SECItem dataitem;
- SECItem keyitem;
- unsigned char *buf;
- unsigned char *keybuf;
-
- ret = certdb_Seq(handle->permCertDB, &key, &data, R_FIRST);
- if ( ret ) {
- return(SECFailure);
- }
- /* here, ret is zero and rv is SECSuccess.
- * Below here, ret is a count of successful calls to the callback function.
- */
- do {
- buf = (unsigned char *)data.data;
-
- if ( buf[1] == (unsigned char)type ) {
- dataitem.len = data.size;
- dataitem.data = buf;
- dataitem.type = siBuffer;
- keyitem.len = key.size - SEC_DB_KEY_HEADER_LEN;
- keybuf = (unsigned char *)key.data;
- keyitem.data = &keybuf[SEC_DB_KEY_HEADER_LEN];
- keyitem.type = siBuffer;
- /* type should equal keybuf[0]. */
-
- rv = (* callback)(&dataitem, &keyitem, type, udata);
- if ( rv == SECSuccess ) {
- ++ret;
- }
- }
- } while ( certdb_Seq(handle->permCertDB, &key, &data, R_NEXT) == 0 );
- /* If any callbacks succeeded, or no calls to callbacks were made,
- * then report success. Otherwise, report failure.
- */
- return (ret ? SECSuccess : rv);
-}
-/*
- * Decode a certificate and enter it into the temporary certificate database.
- * Deal with nicknames correctly
- *
- * This is the private entry point.
- */
-static NSSLOWCERTCertificate *
-DecodeACert(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry)
-{
- NSSLOWCERTCertificate *cert = NULL;
-
- cert = nsslowcert_DecodeDERCertificate(&entry->derCert, entry->nickname );
-
- if ( cert == NULL ) {
- goto loser;
- }
-
- cert->dbhandle = handle;
- cert->dbEntry = entry;
- cert->trust = &entry->trust;
-
- return(cert);
-
-loser:
- return(0);
-}
-
-static NSSLOWCERTTrust *
-CreateTrust(void)
-{
- NSSLOWCERTTrust *trust = NULL;
-
- nsslowcert_LockFreeList();
- trust = trustListHead;
- if (trust) {
- trustListCount--;
- trustListHead = trust->next;
- }
- PORT_Assert(trustListCount >= 0);
- nsslowcert_UnlockFreeList();
- if (trust) {
- return trust;
- }
-
- return PORT_ZNew(NSSLOWCERTTrust);
-}
-
-static void
-DestroyTrustFreeList(void)
-{
- NSSLOWCERTTrust *trust;
-
- nsslowcert_LockFreeList();
- while (NULL != (trust = trustListHead)) {
- trustListCount--;
- trustListHead = trust->next;
- PORT_Free(trust);
- }
- PORT_Assert(!trustListCount);
- trustListCount = 0;
- nsslowcert_UnlockFreeList();
-}
-
-static NSSLOWCERTTrust *
-DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry,
- const SECItem *dbKey)
-{
- NSSLOWCERTTrust *trust = CreateTrust();
- if (trust == NULL) {
- return trust;
- }
- trust->dbhandle = handle;
- trust->dbEntry = entry;
- trust->dbKey.data = pkcs11_copyStaticData(dbKey->data,dbKey->len,
- trust->dbKeySpace, sizeof(trust->dbKeySpace));
- if (!trust->dbKey.data) {
- PORT_Free(trust);
- return NULL;
- }
- trust->dbKey.len = dbKey->len;
-
- trust->trust = &entry->trust;
- trust->derCert = &entry->derCert;
-
- return(trust);
-}
-
-typedef struct {
- PermCertCallback certfunc;
- NSSLOWCERTCertDBHandle *handle;
- void *data;
-} PermCertCallbackState;
-
-/*
- * traversal callback to decode certs and call callers callback
- */
-static SECStatus
-certcallback(SECItem *dbdata, SECItem *dbkey, certDBEntryType type, void *data)
-{
- PermCertCallbackState *mystate;
- SECStatus rv;
- certDBEntryCert *entry;
- SECItem entryitem;
- NSSLOWCERTCertificate *cert;
- PRArenaPool *arena = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));
- mystate = (PermCertCallbackState *)data;
- entry->common.version = (unsigned int)dbdata->data[0];
- entry->common.type = (certDBEntryType)dbdata->data[1];
- entry->common.flags = (unsigned int)dbdata->data[2];
- entry->common.arena = arena;
-
- entryitem.len = dbdata->len - SEC_DB_ENTRY_HEADER_LEN;
- entryitem.data = &dbdata->data[SEC_DB_ENTRY_HEADER_LEN];
-
- rv = DecodeDBCertEntry(entry, &entryitem);
- if (rv != SECSuccess ) {
- goto loser;
- }
- entry->derCert.type = siBuffer;
-
- /* note: Entry is 'inheritted'. */
- cert = DecodeACert(mystate->handle, entry);
-
- rv = (* mystate->certfunc)(cert, dbkey, mystate->data);
-
- /* arena stored in entry destroyed by nsslowcert_DestroyCertificate */
- nsslowcert_DestroyCertificateNoLocking(cert);
-
- return(rv);
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return(SECFailure);
-}
-
-/*
- * Traverse all of the certificates in the permanent database and
- * call the given function for each one; expect the caller to have lock.
- */
-static SECStatus
-TraversePermCertsNoLocking(NSSLOWCERTCertDBHandle *handle,
- SECStatus (* certfunc)(NSSLOWCERTCertificate *cert,
- SECItem *k,
- void *pdata),
- void *udata )
-{
- SECStatus rv;
- PermCertCallbackState mystate;
-
- mystate.certfunc = certfunc;
- mystate.handle = handle;
- mystate.data = udata;
- rv = nsslowcert_TraverseDBEntries(handle, certDBEntryTypeCert, certcallback,
- (void *)&mystate);
-
- return(rv);
-}
-
-/*
- * Traverse all of the certificates in the permanent database and
- * call the given function for each one.
- */
-SECStatus
-nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle,
- SECStatus (* certfunc)(NSSLOWCERTCertificate *cert, SECItem *k,
- void *pdata),
- void *udata )
-{
- SECStatus rv;
-
- nsslowcert_LockDB(handle);
- rv = TraversePermCertsNoLocking(handle, certfunc, udata);
- nsslowcert_UnlockDB(handle);
-
- return(rv);
-}
-
-
-
-/*
- * Close the database
- */
-void
-nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle)
-{
- if ( handle ) {
- if ( handle->permCertDB ) {
- certdb_Close( handle->permCertDB );
- handle->permCertDB = NULL;
- }
- if (handle->dbMon) {
- PZ_DestroyMonitor(handle->dbMon);
- handle->dbMon = NULL;
- }
- PORT_Free(handle);
- }
- return;
-}
-
-/*
- * Get the trust attributes from a certificate
- */
-SECStatus
-nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust)
-{
- SECStatus rv;
-
- nsslowcert_LockCertTrust(cert);
-
- if ( cert->trust == NULL ) {
- rv = SECFailure;
- } else {
- *trust = *cert->trust;
- rv = SECSuccess;
- }
-
- nsslowcert_UnlockCertTrust(cert);
- return(rv);
-}
-
-/*
- * Change the trust attributes of a certificate and make them permanent
- * in the database.
- */
-SECStatus
-nsslowcert_ChangeCertTrust(NSSLOWCERTCertDBHandle *handle,
- NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust)
-{
- certDBEntryCert *entry;
- int rv;
- SECStatus ret;
-
- nsslowcert_LockDB(handle);
- nsslowcert_LockCertTrust(cert);
- /* only set the trust on permanent certs */
- if ( cert->trust == NULL ) {
- ret = SECFailure;
- goto done;
- }
-
- *cert->trust = *trust;
- if ( cert->dbEntry == NULL ) {
- ret = SECSuccess; /* not in permanent database */
- goto done;
- }
-
- entry = cert->dbEntry;
- entry->trust = *trust;
-
- rv = WriteDBCertEntry(handle, entry);
- if ( rv ) {
- ret = SECFailure;
- goto done;
- }
-
- ret = SECSuccess;
-
-done:
- nsslowcert_UnlockCertTrust(cert);
- nsslowcert_UnlockDB(handle);
- return(ret);
-}
-
-
-static SECStatus
-nsslowcert_UpdatePermCert(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
-{
- char *oldnn;
- certDBEntryCert *entry;
- PRBool conflict;
- SECStatus ret;
-
- PORT_Assert(!cert->dbEntry);
-
- /* don't add a conflicting nickname */
- conflict = nsslowcert_CertNicknameConflict(nickname, &cert->derSubject,
- dbhandle);
- if ( conflict ) {
- ret = SECFailure;
- goto done;
- }
-
- /* save old nickname so that we can delete it */
- oldnn = cert->nickname;
-
- entry = AddCertToPermDB(dbhandle, cert, nickname, trust);
-
- if ( entry == NULL ) {
- ret = SECFailure;
- goto done;
- }
-
- pkcs11_freeNickname(oldnn,cert->nicknameSpace);
-
- cert->nickname = (entry->nickname) ? pkcs11_copyNickname(entry->nickname,
- cert->nicknameSpace, sizeof(cert->nicknameSpace)) : NULL;
- cert->trust = &entry->trust;
- cert->dbEntry = entry;
-
- ret = SECSuccess;
-done:
- return(ret);
-}
-
-SECStatus
-nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *dbhandle,
- NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
-{
- SECStatus ret;
-
- nsslowcert_LockDB(dbhandle);
-
- ret = nsslowcert_UpdatePermCert(dbhandle, cert, nickname, trust);
-
- nsslowcert_UnlockDB(dbhandle);
- return(ret);
-}
-
-/*
- * Open the certificate database and index databases. Create them if
- * they are not there or bad.
- */
-SECStatus
-nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
- const char *appName, const char *prefix,
- NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile)
-{
- int rv;
-
- certdb_InitDBLock(handle);
-
- handle->dbMon = PZ_NewMonitor(nssILockCertDB);
- PORT_Assert(handle->dbMon != NULL);
- handle->dbVerify = PR_FALSE;
-
- rv = nsslowcert_OpenPermCertDB(handle, readOnly, appName, prefix,
- namecb, cbarg);
- if ( rv ) {
- goto loser;
- }
-
- return (SECSuccess);
-
-loser:
-
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- return(SECFailure);
-}
-
-PRBool
-nsslowcert_needDBVerify(NSSLOWCERTCertDBHandle *handle)
-{
- if (!handle) return PR_FALSE;
- return handle->dbVerify;
-}
-
-void
-nsslowcert_setDBVerify(NSSLOWCERTCertDBHandle *handle, PRBool value)
-{
- handle->dbVerify = value;
-}
-
-
-/*
- * Lookup a certificate in the databases.
- */
-static NSSLOWCERTCertificate *
-FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey, PRBool lockdb)
-{
- NSSLOWCERTCertificate *cert = NULL;
- certDBEntryCert *entry;
- PRBool locked = PR_FALSE;
-
- if ( lockdb ) {
- locked = PR_TRUE;
- nsslowcert_LockDB(handle);
- }
-
- /* find in perm database */
- entry = ReadDBCertEntry(handle, certKey);
-
- if ( entry == NULL ) {
- goto loser;
- }
-
- /* inherit entry */
- cert = DecodeACert(handle, entry);
-
-loser:
- if (cert == NULL) {
- if (entry) {
- DestroyDBEntry((certDBEntry *)entry);
- }
- }
-
- if ( locked ) {
- nsslowcert_UnlockDB(handle);
- }
-
- return(cert);
-}
-
-/*
- * Lookup a certificate in the databases.
- */
-static NSSLOWCERTTrust *
-FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey, PRBool lockdb)
-{
- NSSLOWCERTTrust *trust = NULL;
- certDBEntryCert *entry;
- PRBool locked = PR_FALSE;
-
- if ( lockdb ) {
- locked = PR_TRUE;
- nsslowcert_LockDB(handle);
- }
-
- /* find in perm database */
- entry = ReadDBCertEntry(handle, certKey);
-
- if ( entry == NULL ) {
- goto loser;
- }
-
- if (!nsslowcert_hasTrust(&entry->trust)) {
- goto loser;
- }
-
- /* inherit entry */
- trust = DecodeTrustEntry(handle, entry, certKey);
-
-loser:
- if (trust == NULL) {
- if (entry) {
- DestroyDBEntry((certDBEntry *)entry);
- }
- }
-
- if ( locked ) {
- nsslowcert_UnlockDB(handle);
- }
-
- return(trust);
-}
-
-/*
- * Lookup a certificate in the databases without locking
- */
-NSSLOWCERTCertificate *
-nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
-{
- return(FindCertByKey(handle, certKey, PR_FALSE));
-}
-
-/*
- * Lookup a trust object in the databases without locking
- */
-NSSLOWCERTTrust *
-nsslowcert_FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey)
-{
- return(FindTrustByKey(handle, certKey, PR_FALSE));
-}
-
-/*
- * Generate a key from an issuerAndSerialNumber, and find the
- * associated cert in the database.
- */
-NSSLOWCERTCertificate *
-nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN)
-{
- SECItem certKey;
- SECItem *sn = &issuerAndSN->serialNumber;
- SECItem *issuer = &issuerAndSN->derIssuer;
- NSSLOWCERTCertificate *cert;
- int data_left = sn->len-1;
- int data_len = sn->len;
- int index = 0;
-
- /* automatically detect DER encoded serial numbers and remove the der
- * encoding since the database expects unencoded data.
- * if it's DER encoded, there must be at least 3 bytes, tag, len, data */
- if ((sn->len >= 3) && (sn->data[0] == 0x2)) {
- /* remove the der encoding of the serial number before generating the
- * key.. */
- data_left = sn->len-2;
- data_len = sn->data[1];
- index = 2;
-
- /* extended length ? (not very likely for a serial number) */
- if (data_len & 0x80) {
- int len_count = data_len & 0x7f;
-
- data_len = 0;
- data_left -= len_count;
- if (data_left > 0) {
- while (len_count --) {
- data_len = (data_len << 8) | sn->data[index++];
- }
- }
- }
- /* XXX leaving any leading zeros on the serial number for backwards
- * compatibility
- */
- /* not a valid der, must be just an unlucky serial number value */
- if (data_len != data_left) {
- data_len = sn->len;
- index = 0;
- }
- }
-
- certKey.type = 0;
- certKey.data = (unsigned char*)PORT_Alloc(sn->len + issuer->len);
- certKey.len = data_len + issuer->len;
-
- if ( certKey.data == NULL ) {
- return(0);
- }
-
- /* first try the serial number as hand-decoded above*/
- /* copy the serialNumber */
- PORT_Memcpy(certKey.data, &sn->data[index], data_len);
-
- /* copy the issuer */
- PORT_Memcpy( &certKey.data[data_len],issuer->data,issuer->len);
-
- cert = nsslowcert_FindCertByKey(handle, &certKey);
- if (cert) {
- PORT_Free(certKey.data);
- return (cert);
- }
-
- /* didn't find it, try by der encoded serial number */
- /* copy the serialNumber */
- PORT_Memcpy(certKey.data, sn->data, sn->len);
-
- /* copy the issuer */
- PORT_Memcpy( &certKey.data[sn->len], issuer->data, issuer->len);
- certKey.len = sn->len + issuer->len;
-
- cert = nsslowcert_FindCertByKey(handle, &certKey);
-
- PORT_Free(certKey.data);
-
- return(cert);
-}
-
-/*
- * Generate a key from an issuerAndSerialNumber, and find the
- * associated cert in the database.
- */
-NSSLOWCERTTrust *
-nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle,
- NSSLOWCERTIssuerAndSN *issuerAndSN)
-{
- SECItem certKey;
- SECItem *sn = &issuerAndSN->serialNumber;
- SECItem *issuer = &issuerAndSN->derIssuer;
- NSSLOWCERTTrust *trust;
- unsigned char keyBuf[512];
- int data_left = sn->len-1;
- int data_len = sn->len;
- int index = 0;
- int len;
-
- /* automatically detect DER encoded serial numbers and remove the der
- * encoding since the database expects unencoded data.
- * if it's DER encoded, there must be at least 3 bytes, tag, len, data */
- if ((sn->len >= 3) && (sn->data[0] == 0x2)) {
- /* remove the der encoding of the serial number before generating the
- * key.. */
- data_left = sn->len-2;
- data_len = sn->data[1];
- index = 2;
-
- /* extended length ? (not very likely for a serial number) */
- if (data_len & 0x80) {
- int len_count = data_len & 0x7f;
-
- data_len = 0;
- data_left -= len_count;
- if (data_left > 0) {
- while (len_count --) {
- data_len = (data_len << 8) | sn->data[index++];
- }
- }
- }
- /* XXX leaving any leading zeros on the serial number for backwards
- * compatibility
- */
- /* not a valid der, must be just an unlucky serial number value */
- if (data_len != data_left) {
- data_len = sn->len;
- index = 0;
- }
- }
-
- certKey.type = 0;
- certKey.len = data_len + issuer->len;
- len = sn->len + issuer->len;
- if (len > sizeof (keyBuf)) {
- certKey.data = (unsigned char*)PORT_Alloc(len);
- } else {
- certKey.data = keyBuf;
- }
-
- if ( certKey.data == NULL ) {
- return(0);
- }
-
- /* first try the serial number as hand-decoded above*/
- /* copy the serialNumber */
- PORT_Memcpy(certKey.data, &sn->data[index], data_len);
-
- /* copy the issuer */
- PORT_Memcpy( &certKey.data[data_len],issuer->data,issuer->len);
-
- trust = nsslowcert_FindTrustByKey(handle, &certKey);
- if (trust) {
- pkcs11_freeStaticData(certKey.data, keyBuf);
- return (trust);
- }
-
- if (index == 0) {
- pkcs11_freeStaticData(certKey.data, keyBuf);
- return NULL;
- }
-
- /* didn't find it, try by der encoded serial number */
- /* copy the serialNumber */
- PORT_Memcpy(certKey.data, sn->data, sn->len);
-
- /* copy the issuer */
- PORT_Memcpy( &certKey.data[sn->len], issuer->data, issuer->len);
- certKey.len = sn->len + issuer->len;
-
- trust = nsslowcert_FindTrustByKey(handle, &certKey);
-
- pkcs11_freeStaticData(certKey.data, keyBuf);
-
- return(trust);
-}
-
-/*
- * look for the given DER certificate in the database
- */
-NSSLOWCERTCertificate *
-nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert)
-{
- PRArenaPool *arena;
- SECItem certKey;
- SECStatus rv;
- NSSLOWCERTCertificate *cert = NULL;
-
- /* create a scratch arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
- }
-
- /* extract the database key from the cert */
- rv = nsslowcert_KeyFromDERCert(arena, derCert, &certKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* find the certificate */
- cert = nsslowcert_FindCertByKey(handle, &certKey);
-
-loser:
- PORT_FreeArena(arena, PR_FALSE);
- return(cert);
-}
-
-static void
-DestroyCertificate(NSSLOWCERTCertificate *cert, PRBool lockdb)
-{
- int refCount;
- NSSLOWCERTCertDBHandle *handle;
-
- if ( cert ) {
-
- handle = cert->dbhandle;
-
- /*
- * handle may be NULL, for example if the cert was created with
- * nsslowcert_DecodeDERCertificate.
- */
- if ( lockdb && handle ) {
- nsslowcert_LockDB(handle);
- }
-
- nsslowcert_LockCertRefCount(cert);
- PORT_Assert(cert->referenceCount > 0);
- refCount = --cert->referenceCount;
- nsslowcert_UnlockCertRefCount(cert);
-
- if ( refCount == 0 ) {
- certDBEntryCert *entry = cert->dbEntry;
-
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
- }
-
- pkcs11_freeNickname(cert->nickname,cert->nicknameSpace);
- pkcs11_freeNickname(cert->emailAddr,cert->emailAddrSpace);
- pkcs11_freeStaticData(cert->certKey.data,cert->certKeySpace);
- cert->certKey.data = NULL;
- cert->nickname = NULL;
-
- /* zero cert before freeing. Any stale references to this cert
- * after this point will probably cause an exception. */
- PORT_Memset(cert, 0, sizeof *cert);
-
- /* use reflock to protect the free list */
- nsslowcert_LockFreeList();
- if (certListCount > MAX_CERT_LIST_COUNT) {
- PORT_Free(cert);
- } else {
- certListCount++;
- cert->next = certListHead;
- certListHead = cert;
- }
- nsslowcert_UnlockFreeList();
- cert = NULL;
- }
- if ( lockdb && handle ) {
- nsslowcert_UnlockDB(handle);
- }
- }
-
- return;
-}
-
-NSSLOWCERTCertificate *
-nsslowcert_CreateCert(void)
-{
- NSSLOWCERTCertificate *cert;
- nsslowcert_LockFreeList();
- cert = certListHead;
- if (cert) {
- certListHead = cert->next;
- certListCount--;
- }
- PORT_Assert(certListCount >= 0);
- nsslowcert_UnlockFreeList();
- if (cert) {
- return cert;
- }
- return PORT_ZNew(NSSLOWCERTCertificate);
-}
-
-static void
-DestroyCertFreeList(void)
-{
- NSSLOWCERTCertificate *cert;
-
- nsslowcert_LockFreeList();
- while (NULL != (cert = certListHead)) {
- certListCount--;
- certListHead = cert->next;
- PORT_Free(cert);
- }
- PORT_Assert(!certListCount);
- certListCount = 0;
- nsslowcert_UnlockFreeList();
-}
-
-void
-nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust)
-{
- certDBEntryCert *entry = trust->dbEntry;
-
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
- }
- pkcs11_freeStaticData(trust->dbKey.data,trust->dbKeySpace);
- PORT_Memset(trust, 0, sizeof(*trust));
-
- nsslowcert_LockFreeList();
- if (trustListCount > MAX_TRUST_LIST_COUNT) {
- PORT_Free(trust);
- } else {
- trustListCount++;
- trust->next = trustListHead;
- trustListHead = trust;
- }
- nsslowcert_UnlockFreeList();
-
- return;
-}
-
-void
-nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert)
-{
- DestroyCertificate(cert, PR_TRUE);
- return;
-}
-
-static void
-nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert)
-{
- DestroyCertificate(cert, PR_FALSE);
- return;
-}
-
-/*
- * Lookup a CRL in the databases. We mirror the same fast caching data base
- * caching stuff used by certificates....?
- */
-certDBEntryRevocation *
-nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle,
- SECItem *crlKey, PRBool isKRL)
-{
- SECItem keyitem;
- DBT key;
- SECStatus rv;
- PRArenaPool *arena = NULL;
- certDBEntryRevocation *entry = NULL;
- certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
- : certDBEntryTypeRevocation;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- rv = EncodeDBGenericKey(crlKey, arena, &keyitem, crlType);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- key.data = keyitem.data;
- key.size = keyitem.len;
-
- /* find in perm database */
- entry = ReadDBCrlEntry(handle, crlKey, crlType);
-
- if ( entry == NULL ) {
- goto loser;
- }
-
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return entry;
-}
-
-/*
- * replace the existing URL in the data base with a new one
- */
-static SECStatus
-nsslowcert_UpdateCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
- SECItem *crlKey, char *url, PRBool isKRL)
-{
- SECStatus rv = SECFailure;
- certDBEntryRevocation *entry = NULL;
- certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
- : certDBEntryTypeRevocation;
- DeleteDBCrlEntry(handle, crlKey, crlType);
-
- /* Write the new entry into the data base */
- entry = NewDBCrlEntry(derCrl, url, crlType, 0);
- if (entry == NULL) goto done;
-
- rv = WriteDBCrlEntry(handle, entry, crlKey);
- if (rv != SECSuccess) goto done;
-
-done:
- if (entry) {
- DestroyDBEntry((certDBEntry *)entry);
- }
- return rv;
-}
-
-SECStatus
-nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
- SECItem *crlKey, char *url, PRBool isKRL)
-{
- SECStatus rv;
-
- rv = nsslowcert_UpdateCrl(handle, derCrl, crlKey, url, isKRL);
-
- return rv;
-}
-
-SECStatus
-nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle, const SECItem *derName,
- PRBool isKRL)
-{
- SECStatus rv;
- certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
- : certDBEntryTypeRevocation;
-
- rv = DeleteDBCrlEntry(handle, derName, crlType);
- if (rv != SECSuccess) goto done;
-
-done:
- return rv;
-}
-
-
-PRBool
-nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust)
-{
- if (trust == NULL) {
- return PR_FALSE;
- }
- return !((trust->sslFlags & CERTDB_TRUSTED_UNKNOWN) &&
- (trust->emailFlags & CERTDB_TRUSTED_UNKNOWN) &&
- (trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN));
-}
-
-/*
- * This function has the logic that decides if another person's cert and
- * email profile from an S/MIME message should be saved. It can deal with
- * the case when there is no profile.
- */
-static SECStatus
-nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle,
- char *emailAddr, SECItem *derSubject, SECItem *emailProfile,
- SECItem *profileTime)
-{
- certDBEntrySMime *entry = NULL;
- SECStatus rv = SECFailure;;
-
-
- /* find our existing entry */
- entry = nsslowcert_ReadDBSMimeEntry(dbhandle, emailAddr);
-
- if ( entry ) {
- /* keep our old db entry consistant for old applications. */
- if (!SECITEM_ItemsAreEqual(derSubject, &entry->subjectName)) {
- nsslowcert_UpdateSubjectEmailAddr(dbhandle, &entry->subjectName,
- emailAddr, nsslowcert_remove);
- }
- DestroyDBEntry((certDBEntry *)entry);
- entry = NULL;
- }
-
- /* now save the entry */
- entry = NewDBSMimeEntry(emailAddr, derSubject, emailProfile,
- profileTime, 0);
- if ( entry == NULL ) {
- rv = SECFailure;
- goto loser;
- }
-
- nsslowcert_LockDB(dbhandle);
-
- rv = DeleteDBSMimeEntry(dbhandle, emailAddr);
- /* if delete fails, try to write new entry anyway... */
-
- /* link subject entry back here */
- rv = nsslowcert_UpdateSubjectEmailAddr(dbhandle, derSubject, emailAddr,
- nsslowcert_add);
- if ( rv != SECSuccess ) {
- nsslowcert_UnlockDB(dbhandle);
- goto loser;
- }
-
- rv = WriteDBSMimeEntry(dbhandle, entry);
- if ( rv != SECSuccess ) {
- nsslowcert_UnlockDB(dbhandle);
- goto loser;
- }
-
- nsslowcert_UnlockDB(dbhandle);
-
- rv = SECSuccess;
-
-loser:
- if ( entry ) {
- DestroyDBEntry((certDBEntry *)entry);
- }
- return(rv);
-}
-
-SECStatus
-nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
- SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime)
-{
- SECStatus rv = SECFailure;;
-
-
- rv = nsslowcert_UpdateSMimeProfile(dbhandle, emailAddr,
- derSubject, emailProfile, profileTime);
-
- return(rv);
-}
-
-void
-nsslowcert_DestroyFreeLists(void)
-{
- if (freeListLock == NULL) {
- return;
- }
- DestroyCertEntryFreeList();
- DestroyTrustFreeList();
- DestroyCertFreeList();
- SKIP_AFTER_FORK(PZ_DestroyLock(freeListLock));
- freeListLock = NULL;
-}
-
-void
-nsslowcert_DestroyGlobalLocks(void)
-{
- if (dbLock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(dbLock));
- dbLock = NULL;
- }
- if (certRefCountLock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(certRefCountLock));
- certRefCountLock = NULL;
- }
- if (certTrustLock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(certTrustLock));
- certTrustLock = NULL;
- }
-}
-
-certDBEntry *
-nsslowcert_DecodeAnyDBEntry(SECItem *dbData, const SECItem *dbKey,
- certDBEntryType entryType, void *pdata)
-{
- PLArenaPool *arena = NULL;
- certDBEntry *entry;
- SECStatus rv;
- SECItem dbEntry;
-
-
- if ((dbData->len < SEC_DB_ENTRY_HEADER_LEN) || (dbKey->len == 0)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto loser;
- }
- dbEntry.data = &dbData->data[SEC_DB_ENTRY_HEADER_LEN];
- dbEntry.len = dbData->len - SEC_DB_ENTRY_HEADER_LEN;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto loser;
- }
- entry = PORT_ArenaZNew(arena, certDBEntry);
- if (!entry)
- goto loser;
-
- entry->common.version = (unsigned int)dbData->data[0];
- entry->common.flags = (unsigned int)dbData->data[2];
- entry->common.type = entryType;
- entry->common.arena = arena;
-
- switch (entryType) {
- case certDBEntryTypeContentVersion: /* This type appears to be unused */
- case certDBEntryTypeVersion: /* This type has only the common hdr */
- rv = SECSuccess;
- break;
-
- case certDBEntryTypeSubject:
- rv = DecodeDBSubjectEntry(&entry->subject, &dbEntry, dbKey);
- break;
-
- case certDBEntryTypeNickname:
- rv = DecodeDBNicknameEntry(&entry->nickname, &dbEntry,
- (char *)dbKey->data);
- break;
-
- /* smime profiles need entries created after the certs have
- * been imported, loop over them in a second run */
- case certDBEntryTypeSMimeProfile:
- rv = DecodeDBSMimeEntry(&entry->smime, &dbEntry, (char *)dbKey->data);
- break;
-
- case certDBEntryTypeCert:
- rv = DecodeDBCertEntry(&entry->cert, &dbEntry);
- break;
-
- case certDBEntryTypeKeyRevocation:
- case certDBEntryTypeRevocation:
- rv = DecodeDBCrlEntry(&entry->revocation, &dbEntry);
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
-
- if (rv == SECSuccess)
- return entry;
-
-loser:
- if (arena)
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
-}
-
diff --git a/security/nss/lib/softoken/legacydb/pcertt.h b/security/nss/lib/softoken/legacydb/pcertt.h
deleted file mode 100644
index 705c43017..000000000
--- a/security/nss/lib/softoken/legacydb/pcertt.h
+++ /dev/null
@@ -1,420 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * certt.h - public data structures for the certificate library
- *
- * $Id$
- */
-#ifndef _PCERTT_H_
-#define _PCERTT_H_
-
-#include "prclist.h"
-#include "pkcs11t.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "plarena.h"
-#include "prcvar.h"
-#include "nssilock.h"
-#include "prio.h"
-#include "prmon.h"
-
-/* Non-opaque objects */
-typedef struct NSSLOWCERTCertDBHandleStr NSSLOWCERTCertDBHandle;
-typedef struct NSSLOWCERTCertKeyStr NSSLOWCERTCertKey;
-
-typedef struct NSSLOWCERTTrustStr NSSLOWCERTTrust;
-typedef struct NSSLOWCERTCertTrustStr NSSLOWCERTCertTrust;
-typedef struct NSSLOWCERTCertificateStr NSSLOWCERTCertificate;
-typedef struct NSSLOWCERTCertificateListStr NSSLOWCERTCertificateList;
-typedef struct NSSLOWCERTIssuerAndSNStr NSSLOWCERTIssuerAndSN;
-typedef struct NSSLOWCERTSignedDataStr NSSLOWCERTSignedData;
-typedef struct NSSLOWCERTSubjectPublicKeyInfoStr NSSLOWCERTSubjectPublicKeyInfo;
-typedef struct NSSLOWCERTValidityStr NSSLOWCERTValidity;
-
-/*
-** An X.509 validity object
-*/
-struct NSSLOWCERTValidityStr {
- PRArenaPool *arena;
- SECItem notBefore;
- SECItem notAfter;
-};
-
-/*
- * A serial number and issuer name, which is used as a database key
- */
-struct NSSLOWCERTCertKeyStr {
- SECItem serialNumber;
- SECItem derIssuer;
-};
-
-/*
-** A signed data object. Used to implement the "signed" macro used
-** in the X.500 specs.
-*/
-struct NSSLOWCERTSignedDataStr {
- SECItem data;
- SECAlgorithmID signatureAlgorithm;
- SECItem signature;
-};
-
-/*
-** An X.509 subject-public-key-info object
-*/
-struct NSSLOWCERTSubjectPublicKeyInfoStr {
- PRArenaPool *arena;
- SECAlgorithmID algorithm;
- SECItem subjectPublicKey;
-};
-
-typedef struct _certDBEntryCert certDBEntryCert;
-typedef struct _certDBEntryRevocation certDBEntryRevocation;
-
-struct NSSLOWCERTCertTrustStr {
- unsigned int sslFlags;
- unsigned int emailFlags;
- unsigned int objectSigningFlags;
-};
-
-/*
-** PKCS11 Trust representation
-*/
-struct NSSLOWCERTTrustStr {
- NSSLOWCERTTrust *next;
- NSSLOWCERTCertDBHandle *dbhandle;
- SECItem dbKey; /* database key for this cert */
- certDBEntryCert *dbEntry; /* database entry struct */
- NSSLOWCERTCertTrust *trust;
- SECItem *derCert; /* original DER for the cert */
- unsigned char dbKeySpace[512];
-};
-
-/*
-** An X.509 certificate object (the unsigned form)
-*/
-struct NSSLOWCERTCertificateStr {
- /* the arena is used to allocate any data structures that have the same
- * lifetime as the cert. This is all stuff that hangs off of the cert
- * structure, and is all freed at the same time. I is used when the
- * cert is decoded, destroyed, and at some times when it changes
- * state
- */
- NSSLOWCERTCertificate *next;
- NSSLOWCERTCertDBHandle *dbhandle;
-
- SECItem derCert; /* original DER for the cert */
- SECItem derIssuer; /* DER for issuer name */
- SECItem derSN;
- SECItem serialNumber;
- SECItem derSubject; /* DER for subject name */
- SECItem derSubjKeyInfo;
- NSSLOWCERTSubjectPublicKeyInfo *subjectPublicKeyInfo;
- SECItem certKey; /* database key for this cert */
- SECItem validity;
- certDBEntryCert *dbEntry; /* database entry struct */
- SECItem subjectKeyID; /* x509v3 subject key identifier */
- SECItem extensions;
- char *nickname;
- char *emailAddr;
- NSSLOWCERTCertTrust *trust;
-
- /* the reference count is modified whenever someone looks up, dups
- * or destroys a certificate
- */
- int referenceCount;
-
- char nicknameSpace[200];
- char emailAddrSpace[200];
- unsigned char certKeySpace[512];
-};
-
-#define SEC_CERTIFICATE_VERSION_1 0 /* default created */
-#define SEC_CERTIFICATE_VERSION_2 1 /* v2 */
-#define SEC_CERTIFICATE_VERSION_3 2 /* v3 extensions */
-
-#define SEC_CRL_VERSION_1 0 /* default */
-#define SEC_CRL_VERSION_2 1 /* v2 extensions */
-
-#define NSS_MAX_LEGACY_DB_KEY_SIZE (60 * 1024)
-
-struct NSSLOWCERTIssuerAndSNStr {
- SECItem derIssuer;
- SECItem serialNumber;
-};
-
-typedef SECStatus (* NSSLOWCERTCertCallback)(NSSLOWCERTCertificate *cert, void *arg);
-
-/* This is the typedef for the callback passed to nsslowcert_OpenCertDB() */
-/* callback to return database name based on version number */
-typedef char * (*NSSLOWCERTDBNameFunc)(void *arg, int dbVersion);
-
-/* XXX Lisa thinks the template declarations belong in cert.h, not here? */
-
-#include "secasn1t.h" /* way down here because I expect template stuff to
- * move out of here anyway */
-
-/*
- * Certificate Database related definitions and data structures
- */
-
-/* version number of certificate database */
-#define CERT_DB_FILE_VERSION 8
-#define CERT_DB_V7_FILE_VERSION 7
-#define CERT_DB_CONTENT_VERSION 2
-
-#define SEC_DB_ENTRY_HEADER_LEN 3
-#define SEC_DB_KEY_HEADER_LEN 1
-
-/* All database entries have this form:
- *
- * byte offset field
- * ----------- -----
- * 0 version
- * 1 type
- * 2 flags
- */
-
-/* database entry types */
-typedef enum {
- certDBEntryTypeVersion = 0,
- certDBEntryTypeCert = 1,
- certDBEntryTypeNickname = 2,
- certDBEntryTypeSubject = 3,
- certDBEntryTypeRevocation = 4,
- certDBEntryTypeKeyRevocation = 5,
- certDBEntryTypeSMimeProfile = 6,
- certDBEntryTypeContentVersion = 7,
- certDBEntryTypeBlob = 8
-} certDBEntryType;
-
-typedef struct {
- certDBEntryType type;
- unsigned int version;
- unsigned int flags;
- PRArenaPool *arena;
-} certDBEntryCommon;
-
-/*
- * Certificate entry:
- *
- * byte offset field
- * ----------- -----
- * 0 sslFlags-msb
- * 1 sslFlags-lsb
- * 2 emailFlags-msb
- * 3 emailFlags-lsb
- * 4 objectSigningFlags-msb
- * 5 objectSigningFlags-lsb
- * 6 derCert-len-msb
- * 7 derCert-len-lsb
- * 8 nickname-len-msb
- * 9 nickname-len-lsb
- * ... derCert
- * ... nickname
- *
- * NOTE: the nickname string as stored in the database is null terminated,
- * in other words, the last byte of the db entry is always 0
- * if a nickname is present.
- * NOTE: if nickname is not present, then nickname-len-msb and
- * nickname-len-lsb will both be zero.
- */
-struct _certDBEntryCert {
- certDBEntryCommon common;
- certDBEntryCert *next;
- NSSLOWCERTCertTrust trust;
- SECItem derCert;
- char *nickname;
- char nicknameSpace[200];
- unsigned char derCertSpace[2048];
-};
-
-/*
- * Certificate Nickname entry:
- *
- * byte offset field
- * ----------- -----
- * 0 subjectname-len-msb
- * 1 subjectname-len-lsb
- * 2... subjectname
- *
- * The database key for this type of entry is a nickname string
- * The "subjectname" value is the DER encoded DN of the identity
- * that matches this nickname.
- */
-typedef struct {
- certDBEntryCommon common;
- char *nickname;
- SECItem subjectName;
-} certDBEntryNickname;
-
-#define DB_NICKNAME_ENTRY_HEADER_LEN 2
-
-/*
- * Certificate Subject entry:
- *
- * byte offset field
- * ----------- -----
- * 0 ncerts-msb
- * 1 ncerts-lsb
- * 2 nickname-msb
- * 3 nickname-lsb
- * 4 emailAddr-msb
- * 5 emailAddr-lsb
- * ... nickname
- * ... emailAddr
- * ...+2*i certkey-len-msb
- * ...+1+2*i certkey-len-lsb
- * ...+2*ncerts+2*i keyid-len-msb
- * ...+1+2*ncerts+2*i keyid-len-lsb
- * ... certkeys
- * ... keyids
- *
- * The database key for this type of entry is the DER encoded subject name
- * The "certkey" value is an array of certificate database lookup keys that
- * points to the database entries for the certificates that matche
- * this subject.
- *
- */
-typedef struct _certDBEntrySubject {
- certDBEntryCommon common;
- SECItem derSubject;
- unsigned int ncerts;
- char *nickname;
- SECItem *certKeys;
- SECItem *keyIDs;
- char **emailAddrs;
- unsigned int nemailAddrs;
-} certDBEntrySubject;
-
-#define DB_SUBJECT_ENTRY_HEADER_LEN 6
-
-/*
- * Certificate SMIME profile entry:
- *
- * byte offset field
- * ----------- -----
- * 0 subjectname-len-msb
- * 1 subjectname-len-lsb
- * 2 smimeoptions-len-msb
- * 3 smimeoptions-len-lsb
- * 4 options-date-len-msb
- * 5 options-date-len-lsb
- * 6... subjectname
- * ... smimeoptions
- * ... options-date
- *
- * The database key for this type of entry is the email address string
- * The "subjectname" value is the DER encoded DN of the identity
- * that matches this nickname.
- * The "smimeoptions" value is a string that represents the algorithm
- * capabilities on the remote user.
- * The "options-date" is the date that the smime options value was created.
- * This is generally the signing time of the signed message that contained
- * the options. It is a UTCTime value.
- */
-typedef struct {
- certDBEntryCommon common;
- char *emailAddr;
- SECItem subjectName;
- SECItem smimeOptions;
- SECItem optionsDate;
-} certDBEntrySMime;
-
-#define DB_SMIME_ENTRY_HEADER_LEN 6
-
-/*
- * Crl/krl entry:
- *
- * byte offset field
- * ----------- -----
- * 0 derCert-len-msb
- * 1 derCert-len-lsb
- * 2 url-len-msb
- * 3 url-len-lsb
- * ... derCert
- * ... url
- *
- * NOTE: the url string as stored in the database is null terminated,
- * in other words, the last byte of the db entry is always 0
- * if a nickname is present.
- * NOTE: if url is not present, then url-len-msb and
- * url-len-lsb will both be zero.
- */
-#define DB_CRL_ENTRY_HEADER_LEN 4
-struct _certDBEntryRevocation {
- certDBEntryCommon common;
- SECItem derCrl;
- char *url; /* where to load the crl from */
-};
-
-/*
- * Database Version Entry:
- *
- * byte offset field
- * ----------- -----
- * only the low level header...
- *
- * The database key for this type of entry is the string "Version"
- */
-typedef struct {
- certDBEntryCommon common;
-} certDBEntryVersion;
-
-#define SEC_DB_VERSION_KEY "Version"
-#define SEC_DB_VERSION_KEY_LEN sizeof(SEC_DB_VERSION_KEY)
-
-/*
- * Database Content Version Entry:
- *
- * byte offset field
- * ----------- -----
- * 0 contentVersion
- *
- * The database key for this type of entry is the string "ContentVersion"
- */
-typedef struct {
- certDBEntryCommon common;
- char contentVersion;
-} certDBEntryContentVersion;
-
-#define SEC_DB_CONTENT_VERSION_KEY "ContentVersion"
-#define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY)
-
-typedef union {
- certDBEntryCommon common;
- certDBEntryCert cert;
- certDBEntryContentVersion content;
- certDBEntryNickname nickname;
- certDBEntryRevocation revocation;
- certDBEntrySMime smime;
- certDBEntrySubject subject;
- certDBEntryVersion version;
-} certDBEntry;
-
-/* length of the fixed part of a database entry */
-#define DBCERT_V4_HEADER_LEN 7
-#define DB_CERT_V5_ENTRY_HEADER_LEN 7
-#define DB_CERT_V6_ENTRY_HEADER_LEN 7
-#define DB_CERT_ENTRY_HEADER_LEN 10
-
-/* common flags for all types of certificates */
-#define CERTDB_TERMINAL_RECORD (1<<0)
-#define CERTDB_TRUSTED (1<<1)
-#define CERTDB_SEND_WARN (1<<2)
-#define CERTDB_VALID_CA (1<<3)
-#define CERTDB_TRUSTED_CA (1<<4) /* trusted for issuing server certs */
-#define CERTDB_NS_TRUSTED_CA (1<<5)
-#define CERTDB_USER (1<<6)
-#define CERTDB_TRUSTED_CLIENT_CA (1<<7) /* trusted for issuing client certs */
-#define CERTDB_INVISIBLE_CA (1<<8) /* don't show in UI */
-#define CERTDB_GOVT_APPROVED_CA (1<<9) /* can do strong crypto in export ver */
-#define CERTDB_MUST_VERIFY (1<<10) /* explicitly don't trust this cert */
-#define CERTDB_TRUSTED_UNKNOWN (1<<11) /* accept trust from another source */
-
-/* bits not affected by the CKO_NETSCAPE_TRUST object */
-#define CERTDB_PRESERVE_TRUST_BITS (CERTDB_USER | \
- CERTDB_NS_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_INVISIBLE_CA | \
- CERTDB_GOVT_APPROVED_CA)
-
-#endif /* _PCERTT_H_ */
diff --git a/security/nss/lib/softoken/legacydb/pk11db.c b/security/nss/lib/softoken/legacydb/pk11db.c
deleted file mode 100644
index 7d0a03c7a..000000000
--- a/security/nss/lib/softoken/legacydb/pk11db.c
+++ /dev/null
@@ -1,717 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * The following code handles the storage of PKCS 11 modules used by the
- * NSS. This file is written to abstract away how the modules are
- * stored so we can deside that later.
- */
-
-#include "lgdb.h"
-#include "mcom_db.h"
-#include "secerr.h"
-#include "utilpars.h"
-
-#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; }
-
-/* Construct a database key for a given module */
-static SECStatus lgdb_MakeKey(DBT *key, char * module) {
- int len = 0;
- char *commonName;
-
- commonName = NSSUTIL_ArgGetParamValue("name",module);
- if (commonName == NULL) {
- commonName = NSSUTIL_ArgGetParamValue("library",module);
- }
- if (commonName == NULL) return SECFailure;
- len = PORT_Strlen(commonName);
- key->data = commonName;
- key->size = len;
- return SECSuccess;
-}
-
-/* free out constructed database key */
-static void
-lgdb_FreeKey(DBT *key)
-{
- if (key->data) {
- PORT_Free(key->data);
- }
- key->data = NULL;
- key->size = 0;
-}
-
-typedef struct lgdbDataStr lgdbData;
-typedef struct lgdbSlotDataStr lgdbSlotData;
-struct lgdbDataStr {
- unsigned char major;
- unsigned char minor;
- unsigned char nameStart[2];
- unsigned char slotOffset[2];
- unsigned char internal;
- unsigned char fips;
- unsigned char ssl[8];
- unsigned char trustOrder[4];
- unsigned char cipherOrder[4];
- unsigned char reserved1;
- unsigned char isModuleDB;
- unsigned char isModuleDBOnly;
- unsigned char isCritical;
- unsigned char reserved[4];
- unsigned char names[6]; /* enough space for the length fields */
-};
-
-struct lgdbSlotDataStr {
- unsigned char slotID[4];
- unsigned char defaultFlags[4];
- unsigned char timeout[4];
- unsigned char askpw;
- unsigned char hasRootCerts;
- unsigned char reserved[18]; /* this makes it a round 32 bytes */
-};
-
-#define LGDB_DB_VERSION_MAJOR 0
-#define LGDB_DB_VERSION_MINOR 6
-#define LGDB_DB_EXT1_VERSION_MAJOR 0
-#define LGDB_DB_EXT1_VERSION_MINOR 6
-#define LGDB_DB_NOUI_VERSION_MAJOR 0
-#define LGDB_DB_NOUI_VERSION_MINOR 4
-
-#define LGDB_PUTSHORT(dest,src) \
- (dest)[1] = (unsigned char) ((src)&0xff); \
- (dest)[0] = (unsigned char) (((src) >> 8) & 0xff);
-#define LGDB_PUTLONG(dest,src) \
- (dest)[3] = (unsigned char) ((src)&0xff); \
- (dest)[2] = (unsigned char) (((src) >> 8) & 0xff); \
- (dest)[1] = (unsigned char) (((src) >> 16) & 0xff); \
- (dest)[0] = (unsigned char) (((src) >> 24) & 0xff);
-#define LGDB_GETSHORT(src) \
- ((unsigned short) (((src)[0] << 8) | (src)[1]))
-#define LGDB_GETLONG(src) \
- ((unsigned long) (( (unsigned long) (src)[0] << 24) | \
- ( (unsigned long) (src)[1] << 16) | \
- ( (unsigned long) (src)[2] << 8) | \
- (unsigned long) (src)[3]))
-
-/*
- * build a data base entry from a module
- */
-static SECStatus
-lgdb_EncodeData(DBT *data, char * module)
-{
- lgdbData *encoded = NULL;
- lgdbSlotData *slot;
- unsigned char *dataPtr;
- unsigned short len, len2 = 0, len3 = 0;
- int count = 0;
- unsigned short offset;
- int dataLen, i;
- unsigned long order;
- unsigned long ssl[2];
- char *commonName = NULL , *dllName = NULL, *param = NULL, *nss = NULL;
- char *slotParams, *ciphers;
- struct NSSUTILPreSlotInfoStr *slotInfo = NULL;
- SECStatus rv = SECFailure;
-
- rv = NSSUTIL_ArgParseModuleSpec(module,&dllName,&commonName,&param,&nss);
- if (rv != SECSuccess) return rv;
- rv = SECFailure;
-
- if (commonName == NULL) {
- /* set error */
- goto loser;
- }
-
- len = PORT_Strlen(commonName);
- if (dllName) {
- len2 = PORT_Strlen(dllName);
- }
- if (param) {
- len3 = PORT_Strlen(param);
- }
-
- slotParams = NSSUTIL_ArgGetParamValue("slotParams",nss);
- slotInfo = NSSUTIL_ArgParseSlotInfo(NULL,slotParams,&count);
- if (slotParams) PORT_Free(slotParams);
-
- if (count && slotInfo == NULL) {
- /* set error */
- goto loser;
- }
-
- dataLen = sizeof(lgdbData) + len + len2 + len3 + sizeof(unsigned short) +
- count*sizeof(lgdbSlotData);
-
- data->data = (unsigned char *) PORT_ZAlloc(dataLen);
- encoded = (lgdbData *)data->data;
- dataPtr = (unsigned char *) data->data;
- data->size = dataLen;
-
- if (encoded == NULL) {
- /* set error */
- goto loser;
- }
-
- encoded->major = LGDB_DB_VERSION_MAJOR;
- encoded->minor = LGDB_DB_VERSION_MINOR;
- encoded->internal = (unsigned char)
- (NSSUTIL_ArgHasFlag("flags","internal",nss) ? 1 : 0);
- encoded->fips = (unsigned char)
- (NSSUTIL_ArgHasFlag("flags","FIPS",nss) ? 1 : 0);
- encoded->isModuleDB = (unsigned char)
- (NSSUTIL_ArgHasFlag("flags","isModuleDB",nss) ? 1 : 0);
- encoded->isModuleDBOnly = (unsigned char)
- (NSSUTIL_ArgHasFlag("flags","isModuleDBOnly",nss) ? 1 : 0);
- encoded->isCritical = (unsigned char)
- (NSSUTIL_ArgHasFlag("flags","critical",nss) ? 1 : 0);
-
- order = NSSUTIL_ArgReadLong("trustOrder", nss,
- NSSUTIL_DEFAULT_TRUST_ORDER, NULL);
- LGDB_PUTLONG(encoded->trustOrder,order);
- order = NSSUTIL_ArgReadLong("cipherOrder", nss,
- NSSUTIL_DEFAULT_CIPHER_ORDER, NULL);
- LGDB_PUTLONG(encoded->cipherOrder,order);
-
-
- ciphers = NSSUTIL_ArgGetParamValue("ciphers",nss);
- NSSUTIL_ArgParseCipherFlags(&ssl[0], ciphers);
- LGDB_PUTLONG(encoded->ssl,ssl[0]);
- LGDB_PUTLONG(&encoded->ssl[4],ssl[1]);
- if (ciphers) PORT_Free(ciphers);
-
- offset = (unsigned short) offsetof(lgdbData, names);
- LGDB_PUTSHORT(encoded->nameStart,offset);
- offset = offset + len + len2 + len3 + 3*sizeof(unsigned short);
- LGDB_PUTSHORT(encoded->slotOffset,offset);
-
-
- LGDB_PUTSHORT(&dataPtr[offset],((unsigned short)count));
- slot = (lgdbSlotData *)(dataPtr+offset+sizeof(unsigned short));
-
- offset = 0;
- LGDB_PUTSHORT(encoded->names,len);
- offset += sizeof(unsigned short);
- PORT_Memcpy(&encoded->names[offset],commonName,len);
- offset += len;
-
-
- LGDB_PUTSHORT(&encoded->names[offset],len2);
- offset += sizeof(unsigned short);
- if (len2) PORT_Memcpy(&encoded->names[offset],dllName,len2);
- offset += len2;
-
- LGDB_PUTSHORT(&encoded->names[offset],len3);
- offset += sizeof(unsigned short);
- if (len3) PORT_Memcpy(&encoded->names[offset],param,len3);
- offset += len3;
-
- if (count) {
- for (i=0; i < count; i++) {
- LGDB_PUTLONG(slot[i].slotID, slotInfo[i].slotID);
- LGDB_PUTLONG(slot[i].defaultFlags,
- slotInfo[i].defaultFlags);
- LGDB_PUTLONG(slot[i].timeout,slotInfo[i].timeout);
- slot[i].askpw = slotInfo[i].askpw;
- slot[i].hasRootCerts = slotInfo[i].hasRootCerts;
- PORT_Memset(slot[i].reserved, 0, sizeof(slot[i].reserved));
- }
- }
- rv = SECSuccess;
-
-loser:
- if (commonName) PORT_Free(commonName);
- if (dllName) PORT_Free(dllName);
- if (param) PORT_Free(param);
- if (slotInfo) PORT_Free(slotInfo);
- if (nss) PORT_Free(nss);
- return rv;
-
-}
-
-static void
-lgdb_FreeData(DBT *data)
-{
- if (data->data) {
- PORT_Free(data->data);
- }
-}
-
-static void
-lgdb_FreeSlotStrings(char **slotStrings, int count)
-{
- int i;
-
- for (i=0; i < count; i++) {
- if (slotStrings[i]) {
- PR_smprintf_free(slotStrings[i]);
- slotStrings[i] = NULL;
- }
- }
-}
-
-/*
- * build a module from the data base entry.
- */
-static char *
-lgdb_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
-{
- lgdbData *encoded;
- lgdbSlotData *slots;
- PLArenaPool *arena;
- char *commonName = NULL;
- char *dllName = NULL;
- char *parameters = NULL;
- char *nss;
- char *moduleSpec;
- char **slotStrings = NULL;
- unsigned char *names;
- unsigned long slotCount;
- unsigned long ssl0 =0;
- unsigned long ssl1 =0;
- unsigned long slotID;
- unsigned long defaultFlags;
- unsigned long timeout;
- unsigned long trustOrder = NSSUTIL_DEFAULT_TRUST_ORDER;
- unsigned long cipherOrder = NSSUTIL_DEFAULT_CIPHER_ORDER;
- unsigned short len;
- unsigned short namesOffset = 0; /* start of the names block */
- unsigned long namesRunningOffset; /* offset to name we are
- * currently processing */
- unsigned short slotOffset;
- PRBool isOldVersion = PR_FALSE;
- PRBool internal;
- PRBool isFIPS;
- PRBool isModuleDB =PR_FALSE;
- PRBool isModuleDBOnly =PR_FALSE;
- PRBool extended =PR_FALSE;
- int i;
-
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (arena == NULL)
- return NULL;
-
-#define CHECK_SIZE(x) \
- if ((unsigned int) data->size < (unsigned int)(x)) goto db_loser
-
- /* -------------------------------------------------------------
- ** Process the buffer header, which is the lgdbData struct.
- ** It may be an old or new version. Check the length for each.
- */
-
- CHECK_SIZE( offsetof(lgdbData, trustOrder[0]) );
-
- encoded = (lgdbData *)data->data;
-
- internal = (encoded->internal != 0) ? PR_TRUE: PR_FALSE;
- isFIPS = (encoded->fips != 0) ? PR_TRUE: PR_FALSE;
-
- if (retInternal)
- *retInternal = internal;
- if (internal) {
- parameters = PORT_ArenaStrdup(arena,defParams);
- if (parameters == NULL)
- goto loser;
- }
- if (internal && (encoded->major == LGDB_DB_NOUI_VERSION_MAJOR) &&
- (encoded->minor <= LGDB_DB_NOUI_VERSION_MINOR)) {
- isOldVersion = PR_TRUE;
- }
- if ((encoded->major == LGDB_DB_EXT1_VERSION_MAJOR) &&
- (encoded->minor >= LGDB_DB_EXT1_VERSION_MINOR)) {
- CHECK_SIZE( sizeof(lgdbData));
- trustOrder = LGDB_GETLONG(encoded->trustOrder);
- cipherOrder = LGDB_GETLONG(encoded->cipherOrder);
- isModuleDB = (encoded->isModuleDB != 0) ? PR_TRUE: PR_FALSE;
- isModuleDBOnly = (encoded->isModuleDBOnly != 0) ? PR_TRUE: PR_FALSE;
- extended = PR_TRUE;
- }
- if (internal && !extended) {
- trustOrder = 0;
- cipherOrder = 100;
- }
- /* decode SSL cipher enable flags */
- ssl0 = LGDB_GETLONG(encoded->ssl);
- ssl1 = LGDB_GETLONG(encoded->ssl + 4);
-
- slotOffset = LGDB_GETSHORT(encoded->slotOffset);
- namesOffset = LGDB_GETSHORT(encoded->nameStart);
-
-
- /*--------------------------------------------------------------
- ** Now process the variable length set of names.
- ** The names have this structure:
- ** struct {
- ** BYTE commonNameLen[ 2 ];
- ** BYTE commonName [ commonNameLen ];
- ** BTTE libNameLen [ 2 ];
- ** BYTE libName [ libNameLen ];
- ** If it is "extended" it also has these members:
- ** BYTE initStringLen[ 2 ];
- ** BYTE initString [ initStringLen ];
- ** }
- */
-
- namesRunningOffset = namesOffset;
- /* copy the module's common name */
- CHECK_SIZE( namesRunningOffset + 2);
- names = (unsigned char *)data->data;
- len = LGDB_GETSHORT(names+namesRunningOffset);
-
- CHECK_SIZE( namesRunningOffset + 2 + len);
- commonName = (char*)PORT_ArenaAlloc(arena,len+1);
- if (commonName == NULL)
- goto loser;
- PORT_Memcpy(commonName, names + namesRunningOffset + 2, len);
- commonName[len] = 0;
- namesRunningOffset += len + 2;
-
- /* copy the module's shared library file name. */
- CHECK_SIZE( namesRunningOffset + 2);
- len = LGDB_GETSHORT(names + namesRunningOffset);
- if (len) {
- CHECK_SIZE( namesRunningOffset + 2 + len);
- dllName = (char*)PORT_ArenaAlloc(arena,len + 1);
- if (dllName == NULL)
- goto loser;
- PORT_Memcpy(dllName, names + namesRunningOffset + 2, len);
- dllName[len] = 0;
- }
- namesRunningOffset += len + 2;
-
- /* copy the module's initialization string, if present. */
- if (!internal && extended) {
- CHECK_SIZE( namesRunningOffset + 2);
- len = LGDB_GETSHORT(names+namesRunningOffset);
- if (len) {
- CHECK_SIZE( namesRunningOffset + 2 + len );
- parameters = (char*)PORT_ArenaAlloc(arena,len + 1);
- if (parameters == NULL)
- goto loser;
- PORT_Memcpy(parameters,names + namesRunningOffset + 2, len);
- parameters[len] = 0;
- }
- namesRunningOffset += len + 2;
- }
-
- /*
- * Consistency check: Make sure the slot and names blocks don't
- * overlap. These blocks can occur in any order, so this check is made
- * in 2 parts. First we check the case where the slot block starts
- * after the name block. Later, when we have the slot block length,
- * we check the case where slot block starts before the name block.
- * NOTE: in most cases any overlap will likely be detected by invalid
- * data read from the blocks, but it's better to find out sooner
- * than later.
- */
- if (slotOffset >= namesOffset) { /* slot block starts after name block */
- if (slotOffset < namesRunningOffset) {
- goto db_loser;
- }
- }
-
- /* ------------------------------------------------------------------
- ** Part 3, process the slot table.
- ** This part has this structure:
- ** struct {
- ** BYTE slotCount [ 2 ];
- ** lgdbSlotData [ slotCount ];
- ** {
- */
-
- CHECK_SIZE( slotOffset + 2 );
- slotCount = LGDB_GETSHORT((unsigned char *)data->data + slotOffset);
-
- /*
- * Consistency check: Part 2. We now have the slot block length, we can
- * check the case where the slotblock procedes the name block.
- */
- if (slotOffset < namesOffset) { /* slot block starts before name block */
- if (namesOffset < slotOffset + 2 + slotCount*sizeof(lgdbSlotData)) {
- goto db_loser;
- }
- }
-
- CHECK_SIZE( (slotOffset + 2 + slotCount * sizeof(lgdbSlotData)));
- slots = (lgdbSlotData *) ((unsigned char *)data->data + slotOffset + 2);
-
- /* slotCount; */
- slotStrings = (char **)PORT_ArenaZAlloc(arena, slotCount * sizeof(char *));
- if (slotStrings == NULL)
- goto loser;
- for (i=0; i < (int) slotCount; i++, slots++) {
- PRBool hasRootCerts =PR_FALSE;
- PRBool hasRootTrust =PR_FALSE;
- slotID = LGDB_GETLONG(slots->slotID);
- defaultFlags = LGDB_GETLONG(slots->defaultFlags);
- timeout = LGDB_GETLONG(slots->timeout);
- hasRootCerts = slots->hasRootCerts;
- if (isOldVersion && internal && (slotID != 2)) {
- unsigned long internalFlags=
- NSSUTIL_ArgParseSlotFlags("slotFlags",
- NSSUTIL_DEFAULT_SFTKN_FLAGS);
- defaultFlags |= internalFlags;
- }
- if (hasRootCerts && !extended) {
- trustOrder = 100;
- }
-
- slotStrings[i] = NSSUTIL_MkSlotString(slotID, defaultFlags, timeout,
- (unsigned char)slots->askpw,
- hasRootCerts, hasRootTrust);
- if (slotStrings[i] == NULL) {
- lgdb_FreeSlotStrings(slotStrings,i);
- goto loser;
- }
- }
-
- nss = NSSUTIL_MkNSSString(slotStrings, slotCount, internal, isFIPS,
- isModuleDB, isModuleDBOnly, internal, trustOrder,
- cipherOrder, ssl0, ssl1);
- lgdb_FreeSlotStrings(slotStrings,slotCount);
- /* it's permissible (and normal) for nss to be NULL. it simply means
- * there are no NSS specific parameters in the database */
- moduleSpec = NSSUTIL_MkModuleSpec(dllName,commonName,parameters,nss);
- PR_smprintf_free(nss);
- PORT_FreeArena(arena,PR_TRUE);
- return moduleSpec;
-
-db_loser:
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
-loser:
- PORT_FreeArena(arena,PR_TRUE);
- return NULL;
-}
-
-static DB *
-lgdb_OpenDB(const char *appName, const char *filename, const char *dbName,
- PRBool readOnly, PRBool update)
-{
- DB *pkcs11db = NULL;
-
-
- if (appName) {
- char *secname = PORT_Strdup(filename);
- int len = strlen(secname);
- int status = RDB_FAIL;
-
- if (len >= 3 && PORT_Strcmp(&secname[len-3],".db") == 0) {
- secname[len-3] = 0;
- }
- pkcs11db=
- rdbopen(appName, "", secname, readOnly ? NO_RDONLY:NO_RDWR, NULL);
- if (update && !pkcs11db) {
- DB *updatedb;
-
- pkcs11db = rdbopen(appName, "", secname, NO_CREATE, &status);
- if (!pkcs11db) {
- if (status == RDB_RETRY) {
- pkcs11db= rdbopen(appName, "", secname,
- readOnly ? NO_RDONLY:NO_RDWR, NULL);
- }
- PORT_Free(secname);
- return pkcs11db;
- }
- updatedb = dbopen(dbName, NO_RDONLY, 0600, DB_HASH, 0);
- if (updatedb) {
- db_Copy(pkcs11db,updatedb);
- (*updatedb->close)(updatedb);
- } else {
- (*pkcs11db->close)(pkcs11db);
- PORT_Free(secname);
- return NULL;
- }
- }
- PORT_Free(secname);
- return pkcs11db;
- }
-
- /* I'm sure we should do more checks here sometime... */
- pkcs11db = dbopen(dbName, readOnly ? NO_RDONLY : NO_RDWR, 0600, DB_HASH, 0);
-
- /* didn't exist? create it */
- if (pkcs11db == NULL) {
- if (readOnly)
- return NULL;
-
- pkcs11db = dbopen( dbName, NO_CREATE, 0600, DB_HASH, 0 );
- if (pkcs11db)
- (* pkcs11db->sync)(pkcs11db, 0);
- }
- return pkcs11db;
-}
-
-static void
-lgdb_CloseDB(DB *pkcs11db)
-{
- (*pkcs11db->close)(pkcs11db);
-}
-
-
-SECStatus legacy_AddSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *module, PRBool rw);
-
-#define LGDB_STEP 10
-/*
- * Read all the existing modules in
- */
-char **
-legacy_ReadSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *params, PRBool rw)
-{
- DBT key,data;
- int ret;
- DB *pkcs11db = NULL;
- char **moduleList = NULL, **newModuleList = NULL;
- int moduleCount = 1;
- int useCount = LGDB_STEP;
-
- moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **));
- if (moduleList == NULL) return NULL;
-
- pkcs11db = lgdb_OpenDB(appName,filename,dbname,PR_TRUE,rw);
- if (pkcs11db == NULL) goto done;
-
- /* read and parse the file or data base */
- ret = (*pkcs11db->seq)(pkcs11db, &key, &data, R_FIRST);
- if (ret) goto done;
-
-
- do {
- char *moduleString;
- PRBool internal = PR_FALSE;
- if ((moduleCount+1) >= useCount) {
- useCount += LGDB_STEP;
- newModuleList =
- (char **)PORT_Realloc(moduleList,useCount*sizeof(char *));
- if (newModuleList == NULL) goto done;
- moduleList = newModuleList;
- PORT_Memset(&moduleList[moduleCount+1],0,
- sizeof(char *)*LGDB_STEP);
- }
- moduleString = lgdb_DecodeData(params,&data,&internal);
- if (internal) {
- moduleList[0] = moduleString;
- } else {
- moduleList[moduleCount] = moduleString;
- moduleCount++;
- }
- } while ( (*pkcs11db->seq)(pkcs11db, &key, &data, R_NEXT) == 0);
-
-done:
- if (!moduleList[0]) {
- char * newparams = NSSUTIL_Quote(params,'"');
- if (newparams) {
- moduleList[0] = PR_smprintf(
- NSSUTIL_DEFAULT_INTERNAL_INIT1 "%s"
- NSSUTIL_DEFAULT_INTERNAL_INIT2 "%s"
- NSSUTIL_DEFAULT_INTERNAL_INIT3,
- newparams, NSSUTIL_DEFAULT_SFTKN_FLAGS);
- PORT_Free(newparams);
- }
- }
- /* deal with trust cert db here */
-
- if (pkcs11db) {
- lgdb_CloseDB(pkcs11db);
- } else if (moduleList[0] && rw) {
- legacy_AddSecmodDB(appName,filename,dbname,moduleList[0], rw) ;
- }
- if (!moduleList[0]) {
- PORT_Free(moduleList);
- moduleList = NULL;
- }
- return moduleList;
-}
-
-SECStatus
-legacy_ReleaseSecmodDBData(const char *appName, const char *filename,
- const char *dbname, char **moduleSpecList, PRBool rw)
-{
- if (moduleSpecList) {
- char **index;
- for(index = moduleSpecList; *index; index++) {
- PR_smprintf_free(*index);
- }
- PORT_Free(moduleSpecList);
- }
- return SECSuccess;
-}
-
-/*
- * Delete a module from the Data Base
- */
-SECStatus
-legacy_DeleteSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *args, PRBool rw)
-{
- DBT key;
- SECStatus rv = SECFailure;
- DB *pkcs11db = NULL;
- int ret;
-
- if (!rw) return SECFailure;
-
- /* make sure we have a db handle */
- pkcs11db = lgdb_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE);
- if (pkcs11db == NULL) {
- return SECFailure;
- }
-
- rv = lgdb_MakeKey(&key,args);
- if (rv != SECSuccess) goto done;
- rv = SECFailure;
- ret = (*pkcs11db->del)(pkcs11db, &key, 0);
- lgdb_FreeKey(&key);
- if (ret != 0) goto done;
-
-
- ret = (*pkcs11db->sync)(pkcs11db, 0);
- if (ret == 0) rv = SECSuccess;
-
-done:
- lgdb_CloseDB(pkcs11db);
- return rv;
-}
-
-/*
- * Add a module to the Data base
- */
-SECStatus
-legacy_AddSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *module, PRBool rw)
-{
- DBT key,data;
- SECStatus rv = SECFailure;
- DB *pkcs11db = NULL;
- int ret;
-
-
- if (!rw) return SECFailure;
-
- /* make sure we have a db handle */
- pkcs11db = lgdb_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE);
- if (pkcs11db == NULL) {
- return SECFailure;
- }
-
- rv = lgdb_MakeKey(&key,module);
- if (rv != SECSuccess) goto done;
- rv = lgdb_EncodeData(&data,module);
- if (rv != SECSuccess) {
- lgdb_FreeKey(&key);
- goto done;
- }
- rv = SECFailure;
- ret = (*pkcs11db->put)(pkcs11db, &key, &data, 0);
- lgdb_FreeKey(&key);
- lgdb_FreeData(&data);
- if (ret != 0) goto done;
-
- ret = (*pkcs11db->sync)(pkcs11db, 0);
- if (ret == 0) rv = SECSuccess;
-
-done:
- lgdb_CloseDB(pkcs11db);
- return rv;
-}
diff --git a/security/nss/lib/softoken/lgglue.c b/security/nss/lib/softoken/lgglue.c
deleted file mode 100644
index 55933ddde..000000000
--- a/security/nss/lib/softoken/lgglue.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * The following code handles the storage of PKCS 11 modules used by the
- * NSS. This file is written to abstract away how the modules are
- * stored so we can deside that later.
- */
-#include "sftkdb.h"
-#include "sftkdbti.h"
-#include "sdb.h"
-#include "prsystem.h"
-#include "prprf.h"
-#include "prenv.h"
-#include "lgglue.h"
-#include "secerr.h"
-#include "softoken.h"
-
-static LGOpenFunc legacy_glue_open = NULL;
-static LGReadSecmodFunc legacy_glue_readSecmod = NULL;
-static LGReleaseSecmodFunc legacy_glue_releaseSecmod = NULL;
-static LGDeleteSecmodFunc legacy_glue_deleteSecmod = NULL;
-static LGAddSecmodFunc legacy_glue_addSecmod = NULL;
-static LGShutdownFunc legacy_glue_shutdown = NULL;
-
-/*
- * The following 3 functions duplicate the work done by bl_LoadLibrary.
- * We should make bl_LoadLibrary a global and replace the call to
- * sftkdb_LoadLibrary(const char *libname) with it.
- */
-#ifdef XP_UNIX
-#include <unistd.h>
-#define LG_MAX_LINKS 20
-static char *
-sftkdb_resolvePath(const char *orig)
-{
- int count = 0;
- int len =0;
- int ret = -1;
- char *resolved = NULL;
- char *source = NULL;
-
- len = 1025; /* MAX PATH +1*/
- if (strlen(orig)+1 > len) {
- /* PATH TOO LONG */
- return NULL;
- }
- resolved = PORT_Alloc(len);
- if (!resolved) {
- return NULL;
- }
- source = PORT_Alloc(len);
- if (!source) {
- goto loser;
- }
- PORT_Strcpy(source, orig);
- /* Walk down all the links */
- while ( count++ < LG_MAX_LINKS) {
- char *tmp;
- /* swap our previous sorce out with resolved */
- /* read it */
- ret = readlink(source, resolved, len-1);
- if (ret < 0) {
- break;
- }
- resolved[ret] = 0;
- tmp = source; source = resolved; resolved = tmp;
- }
- if (count > 1) {
- ret = 0;
- }
-loser:
- if (resolved) {
- PORT_Free(resolved);
- }
- if (ret < 0) {
- if (source) {
- PORT_Free(source);
- source = NULL;
- }
- }
- return source;
-}
-
-#endif
-
-static PRLibrary *
-sftkdb_LoadFromPath(const char *path, const char *libname)
-{
- char *c;
- int pathLen, nameLen, fullPathLen;
- char *fullPathName = NULL;
- PRLibSpec libSpec;
- PRLibrary *lib = NULL;
-
-
- /* strip of our parent's library name */
- c = strrchr(path, PR_GetDirectorySeparator());
- if (!c) {
- return NULL; /* invalid path */
- }
- pathLen = (c-path)+1;
- nameLen = strlen(libname);
- fullPathLen = pathLen + nameLen +1;
- fullPathName = (char *)PORT_Alloc(fullPathLen);
- if (fullPathName == NULL) {
- return NULL; /* memory allocation error */
- }
- PORT_Memcpy(fullPathName, path, pathLen);
- PORT_Memcpy(fullPathName+pathLen, libname, nameLen);
- fullPathName[fullPathLen-1] = 0;
-
- libSpec.type = PR_LibSpec_Pathname;
- libSpec.value.pathname = fullPathName;
- lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
- PORT_Free(fullPathName);
- return lib;
-}
-
-
-static PRLibrary *
-sftkdb_LoadLibrary(const char *libname)
-{
- PRLibrary *lib = NULL;
- PRFuncPtr fn_addr;
- char *parentLibPath = NULL;
-
- fn_addr = (PRFuncPtr) &sftkdb_LoadLibrary;
- parentLibPath = PR_GetLibraryFilePathname(SOFTOKEN_LIB_NAME, fn_addr);
-
- if (!parentLibPath) {
- goto done;
- }
-
- lib = sftkdb_LoadFromPath(parentLibPath, libname);
-#ifdef XP_UNIX
- /* handle symbolic link case */
- if (!lib) {
- char *trueParentLibPath = sftkdb_resolvePath(parentLibPath);
- if (!trueParentLibPath) {
- goto done;
- }
- lib = sftkdb_LoadFromPath(trueParentLibPath, libname);
- PORT_Free(trueParentLibPath);
- }
-#endif
-
-done:
- if (parentLibPath) {
- PORT_Free(parentLibPath);
- }
-
- /* still couldn't load it, try the generic path */
- if (!lib) {
- PRLibSpec libSpec;
- libSpec.type = PR_LibSpec_Pathname;
- libSpec.value.pathname = libname;
- lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
- }
-
- return lib;
-}
-
-/*
- * stub files for legacy db's to be able to encrypt and decrypt
- * various keys and attributes.
- */
-static SECStatus
-sftkdb_encrypt_stub(PRArenaPool *arena, SDB *sdb, SECItem *plainText,
- SECItem **cipherText)
-{
- SFTKDBHandle *handle = sdb->app_private;
- SECStatus rv;
-
- if (handle == NULL) {
- return SECFailure;
- }
-
- /* if we aren't the key handle, try the other handle */
- if (handle->type != SFTK_KEYDB_TYPE) {
- handle = handle->peerDB;
- }
-
- /* not a key handle */
- if (handle == NULL || handle->passwordLock == NULL) {
- return SECFailure;
- }
-
- PZ_Lock(handle->passwordLock);
- if (handle->passwordKey.data == NULL) {
- PZ_Unlock(handle->passwordLock);
- /* PORT_SetError */
- return SECFailure;
- }
-
- rv = sftkdb_EncryptAttribute(arena,
- handle->newKey?handle->newKey:&handle->passwordKey,
- plainText, cipherText);
- PZ_Unlock(handle->passwordLock);
-
- return rv;
-}
-
-/*
- * stub files for legacy db's to be able to encrypt and decrypt
- * various keys and attributes.
- */
-static SECStatus
-sftkdb_decrypt_stub(SDB *sdb, SECItem *cipherText, SECItem **plainText)
-{
- SFTKDBHandle *handle = sdb->app_private;
- SECStatus rv;
- SECItem *oldKey = NULL;
-
- if (handle == NULL) {
- return SECFailure;
- }
-
- /* if we aren't th handle, try the other handle */
- oldKey = handle->oldKey;
- if (handle->type != SFTK_KEYDB_TYPE) {
- handle = handle->peerDB;
- }
-
- /* not a key handle */
- if (handle == NULL || handle->passwordLock == NULL) {
- return SECFailure;
- }
-
- PZ_Lock(handle->passwordLock);
- if (handle->passwordKey.data == NULL) {
- PZ_Unlock(handle->passwordLock);
- /* PORT_SetError */
- return SECFailure;
- }
- rv = sftkdb_DecryptAttribute( oldKey ? oldKey : &handle->passwordKey,
- cipherText, plainText);
- PZ_Unlock(handle->passwordLock);
-
- return rv;
-}
-
-static const char *LEGACY_LIB_NAME =
- SHLIB_PREFIX"nssdbm"SHLIB_VERSION"."SHLIB_SUFFIX;
-/*
- * 2 bools to tell us if we've check the legacy library successfully or
- * not. Initialize on startup to false by the C BSS segment;
- */
-static PRBool legacy_glue_libCheckFailed; /* set if we failed the check */
-static PRBool legacy_glue_libCheckSucceeded; /* set if we passed the check */
-static PRLibrary *legacy_glue_lib = NULL;
-static SECStatus
-sftkdbLoad_Legacy(PRBool isFIPS)
-{
- PRLibrary *lib = NULL;
- LGSetCryptFunc setCryptFunction = NULL;
-
- if (legacy_glue_lib) {
- /* this check is necessary because it's possible we loaded the
- * legacydb to read secmod.db, which told us whether we were in
- * FIPS mode or not. */
- if (isFIPS && !legacy_glue_libCheckSucceeded) {
- if (legacy_glue_libCheckFailed ||
- !BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open)) {
- legacy_glue_libCheckFailed = PR_TRUE;
- /* don't clobber legacy glue to avoid race. just let it
- * get cleared in shutdown */
- return SECFailure;
- }
- legacy_glue_libCheckSucceeded = PR_TRUE;
- }
- return SECSuccess;
- }
-
- lib = sftkdb_LoadLibrary(LEGACY_LIB_NAME);
- if (lib == NULL) {
- return SECFailure;
- }
-
- legacy_glue_open = (LGOpenFunc)PR_FindFunctionSymbol(lib, "legacy_Open");
- legacy_glue_readSecmod = (LGReadSecmodFunc) PR_FindFunctionSymbol(lib,
- "legacy_ReadSecmodDB");
- legacy_glue_releaseSecmod = (LGReleaseSecmodFunc) PR_FindFunctionSymbol(lib,
- "legacy_ReleaseSecmodDBData");
- legacy_glue_deleteSecmod = (LGDeleteSecmodFunc) PR_FindFunctionSymbol(lib,
- "legacy_DeleteSecmodDB");
- legacy_glue_addSecmod = (LGAddSecmodFunc)PR_FindFunctionSymbol(lib,
- "legacy_AddSecmodDB");
- legacy_glue_shutdown = (LGShutdownFunc) PR_FindFunctionSymbol(lib,
- "legacy_Shutdown");
- setCryptFunction = (LGSetCryptFunc) PR_FindFunctionSymbol(lib,
- "legacy_SetCryptFunctions");
-
- if (!legacy_glue_open || !legacy_glue_readSecmod ||
- !legacy_glue_releaseSecmod || !legacy_glue_deleteSecmod ||
- !legacy_glue_addSecmod || !setCryptFunction) {
- PR_UnloadLibrary(lib);
- return SECFailure;
- }
-
- /* verify the loaded library if we are in FIPS mode */
- if (isFIPS) {
- if (!BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open)) {
- PR_UnloadLibrary(lib);
- return SECFailure;
- }
- legacy_glue_libCheckSucceeded = PR_TRUE;
- }
-
- setCryptFunction(sftkdb_encrypt_stub,sftkdb_decrypt_stub);
- legacy_glue_lib = lib;
- return SECSuccess;
-}
-
-CK_RV
-sftkdbCall_open(const char *dir, const char *certPrefix, const char *keyPrefix,
- int certVersion, int keyVersion, int flags, PRBool isFIPS,
- SDB **certDB, SDB **keyDB)
-{
- SECStatus rv;
-
- rv = sftkdbLoad_Legacy(isFIPS);
- if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR;
- }
- if (!legacy_glue_open) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- return (*legacy_glue_open)(dir, certPrefix, keyPrefix,
- certVersion, keyVersion,
- flags, certDB, keyDB);
-}
-
-char **
-sftkdbCall_ReadSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *params, PRBool rw)
-{
- SECStatus rv;
-
- rv = sftkdbLoad_Legacy(PR_FALSE);
- if (rv != SECSuccess) {
- return NULL;
- }
- if (!legacy_glue_readSecmod) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
- return (*legacy_glue_readSecmod)(appName, filename, dbname, params, rw);
-}
-
-SECStatus
-sftkdbCall_ReleaseSecmodDBData(const char *appName,
- const char *filename, const char *dbname,
- char **moduleSpecList, PRBool rw)
-{
- SECStatus rv;
-
- rv = sftkdbLoad_Legacy(PR_FALSE);
- if (rv != SECSuccess) {
- return rv;
- }
- if (!legacy_glue_releaseSecmod) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- return (*legacy_glue_releaseSecmod)(appName, filename, dbname,
- moduleSpecList, rw);
-}
-
-SECStatus
-sftkdbCall_DeleteSecmodDB(const char *appName,
- const char *filename, const char *dbname,
- char *args, PRBool rw)
-{
- SECStatus rv;
-
- rv = sftkdbLoad_Legacy(PR_FALSE);
- if (rv != SECSuccess) {
- return rv;
- }
- if (!legacy_glue_deleteSecmod) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- return (*legacy_glue_deleteSecmod)(appName, filename, dbname, args, rw);
-}
-
-SECStatus
-sftkdbCall_AddSecmodDB(const char *appName,
- const char *filename, const char *dbname,
- char *module, PRBool rw)
-{
- SECStatus rv;
-
- rv = sftkdbLoad_Legacy(PR_FALSE);
- if (rv != SECSuccess) {
- return rv;
- }
- if (!legacy_glue_addSecmod) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- return (*legacy_glue_addSecmod)(appName, filename, dbname, module, rw);
-}
-
-CK_RV
-sftkdbCall_Shutdown(void)
-{
- CK_RV crv = CKR_OK;
- char *disableUnload = NULL;
- if (!legacy_glue_lib) {
- return CKR_OK;
- }
- if (legacy_glue_shutdown) {
-#ifdef NO_FORK_CHECK
- PRBool parentForkedAfterC_Initialize = PR_FALSE;
-#endif
- crv = (*legacy_glue_shutdown)(parentForkedAfterC_Initialize);
- }
- disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
- if (!disableUnload) {
- PR_UnloadLibrary(legacy_glue_lib);
- }
- legacy_glue_lib = NULL;
- legacy_glue_open = NULL;
- legacy_glue_readSecmod = NULL;
- legacy_glue_releaseSecmod = NULL;
- legacy_glue_deleteSecmod = NULL;
- legacy_glue_addSecmod = NULL;
- legacy_glue_libCheckFailed = PR_FALSE;
- legacy_glue_libCheckSucceeded = PR_FALSE;
- return crv;
-}
-
-
diff --git a/security/nss/lib/softoken/lgglue.h b/security/nss/lib/softoken/lgglue.h
deleted file mode 100644
index 68d3b9320..000000000
--- a/security/nss/lib/softoken/lgglue.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This code defines the glue layer between softoken and the legacy DB library
- */
-#include "sdb.h"
-
-/*
- * function prototypes for the callbacks into softoken from the legacyDB
- */
-
-typedef SECStatus (*LGEncryptFunc)(PRArenaPool *arena, SDB *sdb,
- SECItem *plainText, SECItem **cipherText);
-typedef SECStatus (*LGDecryptFunc)(SDB *sdb, SECItem *cipherText,
- SECItem **plainText);
-
-/*
- * function prototypes for the exported functions.
- */
-typedef CK_RV (*LGOpenFunc) (const char *dir, const char *certPrefix,
- const char *keyPrefix,
- int certVersion, int keyVersion, int flags,
- SDB **certDB, SDB **keyDB);
-typedef char ** (*LGReadSecmodFunc)(const char *appName,
- const char *filename,
- const char *dbname, char *params, PRBool rw);
-typedef SECStatus (*LGReleaseSecmodFunc)(const char *appName,
- const char *filename,
- const char *dbname, char **params, PRBool rw);
-typedef SECStatus (*LGDeleteSecmodFunc)(const char *appName,
- const char *filename,
- const char *dbname, char *params, PRBool rw);
-typedef SECStatus (*LGAddSecmodFunc)(const char *appName,
- const char *filename,
- const char *dbname, char *params, PRBool rw);
-typedef SECStatus (*LGShutdownFunc)(PRBool forked);
-typedef void (*LGSetForkStateFunc)(PRBool);
-typedef void (*LGSetCryptFunc)(LGEncryptFunc, LGDecryptFunc);
-
-/*
- * Softoken Glue Functions
- */
-CK_RV sftkdbCall_open(const char *dir, const char *certPrefix,
- const char *keyPrefix,
- int certVersion, int keyVersion, int flags, PRBool isFIPS,
- SDB **certDB, SDB **keyDB);
-char ** sftkdbCall_ReadSecmodDB(const char *appName, const char *filename,
- const char *dbname, char *params, PRBool rw);
-SECStatus sftkdbCall_ReleaseSecmodDBData(const char *appName,
- const char *filename, const char *dbname,
- char **moduleSpecList, PRBool rw);
-SECStatus sftkdbCall_DeleteSecmodDB(const char *appName,
- const char *filename, const char *dbname,
- char *args, PRBool rw);
-SECStatus sftkdbCall_AddSecmodDB(const char *appName,
- const char *filename, const char *dbname,
- char *module, PRBool rw);
-CK_RV sftkdbCall_Shutdown(void);
-
diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c
deleted file mode 100644
index d7f97133f..000000000
--- a/security/nss/lib/softoken/lowkey.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "lowkeyi.h"
-#include "secoid.h"
-#include "secitem.h"
-#include "secder.h"
-#include "base64.h"
-#include "secasn1.h"
-#include "secerr.h"
-
-#ifdef NSS_ENABLE_ECC
-#include "softoken.h"
-#endif
-
-SEC_ASN1_MKSUB(SEC_AnyTemplate)
-SEC_ASN1_MKSUB(SEC_BitStringTemplate)
-SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-const SEC_ASN1Template nsslowkey_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYAttribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) },
- { SEC_ASN1_SET_OF | SEC_ASN1_XTRN ,
- offsetof(NSSLOWKEYAttribute, attrValue),
- SEC_ASN1_SUB(SEC_AnyTemplate) },
- { 0 }
-};
-
-const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate },
-};
-/* ASN1 Templates for new decoder/encoder */
-const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSLOWKEYPrivateKeyInfo,version) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
- nsslowkey_SetOfAttributeTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) },
- { SEC_ASN1_INTEGER, offsetof(PQGParams,prime) },
- { SEC_ASN1_INTEGER, offsetof(PQGParams,subPrime) },
- { SEC_ASN1_INTEGER, offsetof(PQGParams,base) },
- { 0, }
-};
-
-const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) },
- { 0 }
-};
-
-
-const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.publicValue) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
- { 0, }
-};
-
-const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = {
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) },
-};
-
-const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.publicValue) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.privateValue) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.base) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.prime) },
- { 0, }
-};
-
-#ifdef NSS_ENABLE_ECC
-
-/* XXX This is just a placeholder for later when we support
- * generic curves and need full-blown support for parsing EC
- * parameters. For now, we only support named curves in which
- * EC params are simply encoded as an object ID and we don't
- * use nsslowkey_ECParamsTemplate.
- */
-const SEC_ASN1Template nsslowkey_ECParamsTemplate[] = {
- { SEC_ASN1_CHOICE, offsetof(ECParams,type), NULL, sizeof(ECParams) },
- { SEC_ASN1_OBJECT_ID, offsetof(ECParams,curveOID), NULL, ec_params_named },
- { 0, }
-};
-
-
-/* NOTE: The SECG specification allows the private key structure
- * to contain curve parameters but recommends that they be stored
- * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo
- * instead.
- */
-const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.ec.version) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSLOWKEYPrivateKey,u.ec.privateValue) },
- /* XXX The following template works for now since we only
- * support named curves for which the parameters are
- * encoded as an object ID. When we support generic curves,
- * we'll need to define nsslowkey_ECParamsTemplate
- */
-#if 1
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 0,
- offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams.curveOID),
- SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
-#else
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams),
- nsslowkey_ECParamsTemplate },
-#endif
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
- SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
- offsetof(NSSLOWKEYPrivateKey,u.ec.publicValue),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
- { 0, }
-};
-#endif /* NSS_ENABLE_ECC */
-/*
- * See bugzilla bug 125359
- * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
- * all of the templates above that en/decode into integers must be converted
- * from ASN.1's signed integer type. This is done by marking either the
- * source or destination (encoding or decoding, respectively) type as
- * siUnsignedInteger.
- */
-
-void
-prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
-{
- key->u.rsa.modulus.type = siUnsignedInteger;
- key->u.rsa.publicExponent.type = siUnsignedInteger;
- key->u.rsa.privateExponent.type = siUnsignedInteger;
- key->u.rsa.prime1.type = siUnsignedInteger;
- key->u.rsa.prime2.type = siUnsignedInteger;
- key->u.rsa.exponent1.type = siUnsignedInteger;
- key->u.rsa.exponent2.type = siUnsignedInteger;
- key->u.rsa.coefficient.type = siUnsignedInteger;
-}
-
-void
-prepare_low_pqg_params_for_asn1(PQGParams *params)
-{
- params->prime.type = siUnsignedInteger;
- params->subPrime.type = siUnsignedInteger;
- params->base.type = siUnsignedInteger;
-}
-
-void
-prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
-{
- key->u.dsa.publicValue.type = siUnsignedInteger;
- key->u.dsa.privateValue.type = siUnsignedInteger;
- key->u.dsa.params.prime.type = siUnsignedInteger;
- key->u.dsa.params.subPrime.type = siUnsignedInteger;
- key->u.dsa.params.base.type = siUnsignedInteger;
-}
-
-void
-prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key)
-{
- key->u.dsa.privateValue.type = siUnsignedInteger;
-}
-
-void
-prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
-{
- key->u.dh.prime.type = siUnsignedInteger;
- key->u.dh.base.type = siUnsignedInteger;
- key->u.dh.publicValue.type = siUnsignedInteger;
- key->u.dh.privateValue.type = siUnsignedInteger;
-}
-
-#ifdef NSS_ENABLE_ECC
-void
-prepare_low_ecparams_for_asn1(ECParams *params)
-{
- params->DEREncoding.type = siUnsignedInteger;
- params->curveOID.type = siUnsignedInteger;
-}
-
-void
-prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
-{
- key->u.ec.version.type = siUnsignedInteger;
- key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger;
- key->u.ec.ecParams.curveOID.type = siUnsignedInteger;
- key->u.ec.privateValue.type = siUnsignedInteger;
- key->u.ec.publicValue.type = siUnsignedInteger;
-}
-#endif /* NSS_ENABLE_ECC */
-
-void
-nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk)
-{
- if (privk && privk->arena) {
- PORT_FreeArena(privk->arena, PR_TRUE);
- }
-}
-
-void
-nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk)
-{
- if (pubk && pubk->arena) {
- PORT_FreeArena(pubk->arena, PR_FALSE);
- }
-}
-unsigned
-nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk)
-{
- unsigned char b0;
-
- /* interpret modulus length as key strength... in
- * fortezza that's the public key length */
-
- switch (pubk->keyType) {
- case NSSLOWKEYRSAKey:
- b0 = pubk->u.rsa.modulus.data[0];
- return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
- default:
- break;
- }
- return 0;
-}
-
-unsigned
-nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk)
-{
-
- unsigned char b0;
-
- switch (privk->keyType) {
- case NSSLOWKEYRSAKey:
- b0 = privk->u.rsa.modulus.data[0];
- return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len - 1;
- default:
- break;
- }
- return 0;
-}
-
-NSSLOWKEYPublicKey *
-nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
-{
- NSSLOWKEYPublicKey *pubk;
- PLArenaPool *arena;
-
-
- arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- switch(privk->keyType) {
- case NSSLOWKEYRSAKey:
- case NSSLOWKEYNullKey:
- pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof (NSSLOWKEYPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- if (privk->keyType == NSSLOWKEYNullKey) return pubk;
- rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus,
- &privk->u.rsa.modulus);
- if (rv == SECSuccess) {
- rv = SECITEM_CopyItem (arena, &pubk->u.rsa.publicExponent,
- &privk->u.rsa.publicExponent);
- if (rv == SECSuccess)
- return pubk;
- }
- } else {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- }
- break;
- case NSSLOWKEYDSAKey:
- pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue,
- &privk->u.dsa.publicValue);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime,
- &privk->u.dsa.params.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime,
- &privk->u.dsa.params.subPrime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base,
- &privk->u.dsa.params.base);
- if (rv == SECSuccess) return pubk;
- }
- break;
- case NSSLOWKEYDHKey:
- pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
- &privk->u.dh.publicValue);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime,
- &privk->u.dh.prime);
- if (rv != SECSuccess) break;
- rv = SECITEM_CopyItem(arena, &pubk->u.dh.base,
- &privk->u.dh.base);
- if (rv == SECSuccess) return pubk;
- }
- break;
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPublicKey));
- if (pubk != NULL) {
- SECStatus rv;
-
- pubk->arena = arena;
- pubk->keyType = privk->keyType;
- rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue,
- &privk->u.ec.publicValue);
- if (rv != SECSuccess) break;
- pubk->u.ec.ecParams.arena = arena;
- /* Copy the rest of the params */
- rv = EC_CopyParams(arena, &(pubk->u.ec.ecParams),
- &(privk->u.ec.ecParams));
- if (rv == SECSuccess) return pubk;
- }
- break;
-#endif /* NSS_ENABLE_ECC */
- /* No Fortezza in Low Key implementations (Fortezza keys aren't
- * stored in our data base */
- default:
- break;
- }
-
- PORT_FreeArena (arena, PR_FALSE);
- return NULL;
-}
-
-NSSLOWKEYPrivateKey *
-nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey)
-{
- NSSLOWKEYPrivateKey *returnKey = NULL;
- SECStatus rv = SECFailure;
- PLArenaPool *poolp;
-
- if(!privKey) {
- return NULL;
- }
-
- poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(!poolp) {
- return NULL;
- }
-
- returnKey = (NSSLOWKEYPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(NSSLOWKEYPrivateKey));
- if(!returnKey) {
- rv = SECFailure;
- goto loser;
- }
-
- returnKey->keyType = privKey->keyType;
- returnKey->arena = poolp;
-
- switch(privKey->keyType) {
- case NSSLOWKEYRSAKey:
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.modulus),
- &(privKey->u.rsa.modulus));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.version),
- &(privKey->u.rsa.version));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.publicExponent),
- &(privKey->u.rsa.publicExponent));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.privateExponent),
- &(privKey->u.rsa.privateExponent));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime1),
- &(privKey->u.rsa.prime1));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime2),
- &(privKey->u.rsa.prime2));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent1),
- &(privKey->u.rsa.exponent1));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent2),
- &(privKey->u.rsa.exponent2));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.coefficient),
- &(privKey->u.rsa.coefficient));
- if(rv != SECSuccess) break;
- break;
- case NSSLOWKEYDSAKey:
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.publicValue),
- &(privKey->u.dsa.publicValue));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.privateValue),
- &(privKey->u.dsa.privateValue));
- if(rv != SECSuccess) break;
- returnKey->u.dsa.params.arena = poolp;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.prime),
- &(privKey->u.dsa.params.prime));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.subPrime),
- &(privKey->u.dsa.params.subPrime));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.base),
- &(privKey->u.dsa.params.base));
- if(rv != SECSuccess) break;
- break;
- case NSSLOWKEYDHKey:
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.publicValue),
- &(privKey->u.dh.publicValue));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.privateValue),
- &(privKey->u.dh.privateValue));
- if(rv != SECSuccess) break;
- returnKey->u.dsa.params.arena = poolp;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.prime),
- &(privKey->u.dh.prime));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.base),
- &(privKey->u.dh.base));
- if(rv != SECSuccess) break;
- break;
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version),
- &(privKey->u.ec.version));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.publicValue),
- &(privKey->u.ec.publicValue));
- if(rv != SECSuccess) break;
- rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.privateValue),
- &(privKey->u.ec.privateValue));
- if(rv != SECSuccess) break;
- returnKey->u.ec.ecParams.arena = poolp;
- /* Copy the rest of the params */
- rv = EC_CopyParams(poolp, &(returnKey->u.ec.ecParams),
- &(privKey->u.ec.ecParams));
- if (rv != SECSuccess) break;
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- rv = SECFailure;
- }
-
-loser:
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_TRUE);
- returnKey = NULL;
- }
-
- return returnKey;
-}
diff --git a/security/nss/lib/softoken/lowkeyi.h b/security/nss/lib/softoken/lowkeyi.h
deleted file mode 100644
index 2ae7d5d24..000000000
--- a/security/nss/lib/softoken/lowkeyi.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _LOWKEYI_H_
-#define _LOWKEYI_H_
-
-#include "prtypes.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "lowkeyti.h"
-
-SEC_BEGIN_PROTOS
-
-/*
- * See bugzilla bug 125359
- * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
- * all of the templates above that en/decode into integers must be converted
- * from ASN.1's signed integer type. This is done by marking either the
- * source or destination (encoding or decoding, respectively) type as
- * siUnsignedInteger.
- */
-extern void prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
-extern void prepare_low_pqg_params_for_asn1(PQGParams *params);
-extern void prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
-extern void prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key);
-extern void prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
-#ifdef NSS_ENABLE_ECC
-extern void prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
-extern void prepare_low_ecparams_for_asn1(ECParams *params);
-#endif /* NSS_ENABLE_ECC */
-
-/*
-** Destroy a private key object.
-** "key" the object
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *key);
-
-/*
-** Destroy a public key object.
-** "key" the object
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *key);
-
-/*
-** Return the modulus length of "pubKey".
-*/
-extern unsigned int nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubKey);
-
-
-/*
-** Return the modulus length of "privKey".
-*/
-extern unsigned int nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privKey);
-
-
-/*
-** Convert a low private key "privateKey" into a public low key
-*/
-extern NSSLOWKEYPublicKey
- *nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privateKey);
-
-/* Make a copy of a low private key in it's own arena.
- * a return of NULL indicates an error.
- */
-extern NSSLOWKEYPrivateKey *
-nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey);
-
-
-SEC_END_PROTOS
-
-#endif /* _LOWKEYI_H_ */
diff --git a/security/nss/lib/softoken/lowkeyti.h b/security/nss/lib/softoken/lowkeyti.h
deleted file mode 100644
index 76c15aa04..000000000
--- a/security/nss/lib/softoken/lowkeyti.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef _LOWKEYTI_H_
-#define _LOWKEYTI_H_ 1
-
-#include "blapit.h"
-#include "prtypes.h"
-#include "plarena.h"
-#include "secitem.h"
-#include "secasn1t.h"
-#include "secoidt.h"
-
-/*
-** Typedef for callback to get a password "key".
-*/
-extern const SEC_ASN1Template nsslowkey_PQGParamsTemplate[];
-extern const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[];
-extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[];
-extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[];
-extern const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[];
-extern const SEC_ASN1Template nsslowkey_DHPrivateKeyExportTemplate[];
-#ifdef NSS_ENABLE_ECC
-#define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */
-extern const SEC_ASN1Template nsslowkey_ECParamsTemplate[];
-extern const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[];
-#endif /* NSS_ENABLE_ECC */
-
-extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[];
-extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[];
-
-/*
- * PKCS #8 attributes
- */
-struct NSSLOWKEYAttributeStr {
- SECItem attrType;
- SECItem *attrValue;
-};
-typedef struct NSSLOWKEYAttributeStr NSSLOWKEYAttribute;
-
-/*
-** A PKCS#8 private key info object
-*/
-struct NSSLOWKEYPrivateKeyInfoStr {
- PLArenaPool *arena;
- SECItem version;
- SECAlgorithmID algorithm;
- SECItem privateKey;
- NSSLOWKEYAttribute **attributes;
-};
-typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
-#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
-
-typedef enum {
- NSSLOWKEYNullKey = 0,
- NSSLOWKEYRSAKey = 1,
- NSSLOWKEYDSAKey = 2,
- NSSLOWKEYDHKey = 4,
- NSSLOWKEYECKey = 5
-} NSSLOWKEYType;
-
-/*
-** An RSA public key object.
-*/
-struct NSSLOWKEYPublicKeyStr {
- PLArenaPool *arena;
- NSSLOWKEYType keyType ;
- union {
- RSAPublicKey rsa;
- DSAPublicKey dsa;
- DHPublicKey dh;
- ECPublicKey ec;
- } u;
-};
-typedef struct NSSLOWKEYPublicKeyStr NSSLOWKEYPublicKey;
-
-/*
-** Low Level private key object
-** This is only used by the raw Crypto engines (crypto), keydb (keydb),
-** and PKCS #11. Everyone else uses the high level key structure.
-*/
-struct NSSLOWKEYPrivateKeyStr {
- PLArenaPool *arena;
- NSSLOWKEYType keyType;
- union {
- RSAPrivateKey rsa;
- DSAPrivateKey dsa;
- DHPrivateKey dh;
- ECPrivateKey ec;
- } u;
-};
-typedef struct NSSLOWKEYPrivateKeyStr NSSLOWKEYPrivateKey;
-
-#endif /* _LOWKEYTI_H_ */
diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c
deleted file mode 100644
index ebb23c29e..000000000
--- a/security/nss/lib/softoken/lowpbe.c
+++ /dev/null
@@ -1,1378 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "plarena.h"
-
-#include "seccomon.h"
-#include "secitem.h"
-#include "secport.h"
-#include "hasht.h"
-#include "pkcs11t.h"
-#include "blapi.h"
-#include "hasht.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "lowpbe.h"
-#include "secoid.h"
-#include "alghmac.h"
-#include "softoken.h"
-#include "secerr.h"
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-/* template for PKCS 5 PBE Parameter. This template has been expanded
- * based upon the additions in PKCS 12. This should eventually be moved
- * if RSA updates PKCS 5.
- */
-static const SEC_ASN1Template NSSPKCS5PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSPKCS5PBEParameter) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSPKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER,
- offsetof(NSSPKCS5PBEParameter, iteration) },
- { 0 }
-};
-
-static const SEC_ASN1Template NSSPKCS5PKCS12V2PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSPKCS5PBEParameter) },
- { SEC_ASN1_OCTET_STRING, offsetof(NSSPKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, iteration) },
- { 0 }
-};
-
-
-/* PKCS5 v2 */
-
-struct nsspkcs5V2PBEParameterStr {
- SECAlgorithmID keyParams; /* parameters of the key generation */
- SECAlgorithmID algParams; /* parameters for the encryption or mac op */
-};
-
-typedef struct nsspkcs5V2PBEParameterStr nsspkcs5V2PBEParameter;
-#define PBKDF2
-
-#ifdef PBKDF2
-static const SEC_ASN1Template NSSPKCS5V2PBES2ParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(nsspkcs5V2PBEParameter) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(nsspkcs5V2PBEParameter, keyParams),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(nsspkcs5V2PBEParameter, algParams),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { 0 }
-};
-
-static const SEC_ASN1Template NSSPKCS5V2PBEParameterTemplate[] =
-{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSPKCS5PBEParameter) },
- /* this is really a choice, but since we don't understand any other
- *choice, just inline it. */
- { SEC_ASN1_OCTET_STRING, offsetof(NSSPKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, iteration) },
- { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, keyLength) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
- offsetof(NSSPKCS5PBEParameter, prfAlg),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { 0 }
-};
-#endif
-
-SECStatus
-nsspkcs5_HashBuf(const SECHashObject *hashObj, unsigned char *dest,
- unsigned char *src, int len)
-{
- void *ctx;
- unsigned int retLen;
-
- ctx = hashObj->create();
- if(ctx == NULL) {
- return SECFailure;
- }
- hashObj->begin(ctx);
- hashObj->update(ctx, src, len);
- hashObj->end(ctx, dest, &retLen, hashObj->length);
- hashObj->destroy(ctx, PR_TRUE);
- return SECSuccess;
-}
-
-/* generate bits using any hash
- */
-static SECItem *
-nsspkcs5_PBKDF1(const SECHashObject *hashObj, SECItem *salt, SECItem *pwd,
- int iter, PRBool faulty3DES)
-{
- SECItem *hash = NULL, *pre_hash = NULL;
- SECStatus rv = SECFailure;
-
- if((salt == NULL) || (pwd == NULL) || (iter < 0)) {
- return NULL;
- }
-
- hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
-
- if((hash != NULL) && (pre_hash != NULL)) {
- int i, ph_len;
-
- ph_len = hashObj->length;
- if((salt->len + pwd->len) > hashObj->length) {
- ph_len = salt->len + pwd->len;
- }
-
- rv = SECFailure;
-
- /* allocate buffers */
- hash->len = hashObj->length;
- hash->data = (unsigned char *)PORT_ZAlloc(hash->len);
- pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
-
- /* in pbeSHA1TripleDESCBC there was an allocation error that made
- * it into the caller. We do not want to propagate those errors
- * further, so we are doing it correctly, but reading the old method.
- */
- if (faulty3DES) {
- pre_hash->len = ph_len;
- } else {
- pre_hash->len = salt->len + pwd->len;
- }
-
- /* preform hash */
- if ((hash->data != NULL) && (pre_hash->data != NULL)) {
- rv = SECSuccess;
- /* check for 0 length password */
- if(pwd->len > 0) {
- PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
- }
- if(salt->len > 0) {
- PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
- }
- for(i = 0; ((i < iter) && (rv == SECSuccess)); i++) {
- rv = nsspkcs5_HashBuf(hashObj, hash->data,
- pre_hash->data, pre_hash->len);
- if(rv != SECFailure) {
- pre_hash->len = hashObj->length;
- PORT_Memcpy(pre_hash->data, hash->data, hashObj->length);
- }
- }
- }
- }
-
- if(pre_hash != NULL) {
- SECITEM_FreeItem(pre_hash, PR_TRUE);
- }
-
- if((rv != SECSuccess) && (hash != NULL)) {
- SECITEM_FreeItem(hash, PR_TRUE);
- hash = NULL;
- }
-
- return hash;
-}
-
-/* this bit generation routine is described in PKCS 12 and the proposed
- * extensions to PKCS 5. an initial hash is generated following the
- * instructions laid out in PKCS 5. If the number of bits generated is
- * insufficient, then the method discussed in the proposed extensions to
- * PKCS 5 in PKCS 12 are used. This extension makes use of the HMAC
- * function. And the P_Hash function from the TLS standard.
- */
-static SECItem *
-nsspkcs5_PFXPBE(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param,
- SECItem *init_hash, unsigned int bytes_needed)
-{
- SECItem *ret_bits = NULL;
- int hash_size = 0;
- unsigned int i;
- unsigned int hash_iter;
- unsigned int dig_len;
- SECStatus rv = SECFailure;
- unsigned char *state = NULL;
- unsigned int state_len;
- HMACContext *cx = NULL;
-
- hash_size = hashObj->length;
- hash_iter = (bytes_needed + (unsigned int)hash_size - 1) / hash_size;
-
- /* allocate return buffer */
- ret_bits = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(ret_bits == NULL)
- return NULL;
- ret_bits->data = (unsigned char *)PORT_ZAlloc((hash_iter * hash_size) + 1);
- ret_bits->len = (hash_iter * hash_size);
- if(ret_bits->data == NULL) {
- PORT_Free(ret_bits);
- return NULL;
- }
-
- /* allocate intermediate hash buffer. 8 is for the 8 bytes of
- * data which are added based on iteration number
- */
-
- if ((unsigned int)hash_size > pbe_param->salt.len) {
- state_len = hash_size;
- } else {
- state_len = pbe_param->salt.len;
- }
- state = (unsigned char *)PORT_ZAlloc(state_len);
- if(state == NULL) {
- rv = SECFailure;
- goto loser;
- }
- if(pbe_param->salt.len > 0) {
- PORT_Memcpy(state, pbe_param->salt.data, pbe_param->salt.len);
- }
-
- cx = HMAC_Create(hashObj, init_hash->data, init_hash->len, PR_TRUE);
- if (cx == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- for(i = 0; i < hash_iter; i++) {
-
- /* generate output bits */
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- HMAC_Update(cx, pbe_param->salt.data, pbe_param->salt.len);
- rv = HMAC_Finish(cx, ret_bits->data + (i * hash_size),
- &dig_len, hash_size);
- if (rv != SECSuccess)
- goto loser;
- PORT_Assert((unsigned int)hash_size == dig_len);
-
- /* generate new state */
- HMAC_Begin(cx);
- HMAC_Update(cx, state, state_len);
- rv = HMAC_Finish(cx, state, &state_len, state_len);
- if (rv != SECSuccess)
- goto loser;
- PORT_Assert(state_len == dig_len);
- }
-
-loser:
- if (state != NULL)
- PORT_ZFree(state, state_len);
- HMAC_Destroy(cx, PR_TRUE);
-
- if(rv != SECSuccess) {
- SECITEM_ZfreeItem(ret_bits, PR_TRUE);
- ret_bits = NULL;
- }
-
- return ret_bits;
-}
-
-/* generate bits for the key and iv determination. if enough bits
- * are not generated using PKCS 5, then we need to generate more bits
- * based on the extension proposed in PKCS 12
- */
-static SECItem *
-nsspkcs5_PBKDF1Extended(const SECHashObject *hashObj,
- NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, PRBool faulty3DES)
-{
- SECItem * hash = NULL;
- SECItem * newHash = NULL;
- int bytes_needed;
- int bytes_available;
-
- bytes_needed = pbe_param->ivLen + pbe_param->keyLen;
- bytes_available = hashObj->length;
-
- hash = nsspkcs5_PBKDF1(hashObj, &pbe_param->salt, pwitem,
- pbe_param->iter, faulty3DES);
-
- if(hash == NULL) {
- return NULL;
- }
-
- if(bytes_needed <= bytes_available) {
- return hash;
- }
-
- newHash = nsspkcs5_PFXPBE(hashObj, pbe_param, hash, bytes_needed);
- if (hash != newHash)
- SECITEM_FreeItem(hash, PR_TRUE);
- return newHash;
-}
-
-#ifdef PBKDF2
-
-/*
- * PBDKDF2 is PKCS #5 v2.0 it's currently not used by NSS
- */
-static void
-do_xor(unsigned char *dest, unsigned char *src, int len)
-{
- /* use byt xor, not all platforms are happy about inaligned
- * integer fetches */
- while (len--) {
- *dest = *dest ^ *src;
- dest++;
- src++;
- }
-}
-
-static SECStatus
-nsspkcs5_PBKFD2_F(const SECHashObject *hashobj, SECItem *pwitem, SECItem *salt,
- int iterations, unsigned int i, unsigned char *T)
-{
- int j;
- HMACContext *cx = NULL;
- unsigned int hLen = hashobj->length;
- SECStatus rv = SECFailure;
- unsigned char *last = NULL;
- unsigned int lastLength = salt->len + 4;
- unsigned int lastBufLength;
-
- cx=HMAC_Create(hashobj,pwitem->data,pwitem->len,PR_FALSE);
- if (cx == NULL) {
- goto loser;
- }
- PORT_Memset(T,0,hLen);
- lastBufLength = PR_MAX(lastLength, hLen);
- last = PORT_Alloc(lastBufLength);
- if (last == NULL) {
- goto loser;
- }
- PORT_Memcpy(last,salt->data,salt->len);
- last[salt->len ] = (i >> 24) & 0xff;
- last[salt->len+1] = (i >> 16) & 0xff;
- last[salt->len+2] = (i >> 8) & 0xff;
- last[salt->len+3] = i & 0xff;
-
- /* NOTE: we need at least one iteration to return success! */
- for (j=0; j < iterations; j++) {
- HMAC_Begin(cx);
- HMAC_Update(cx,last,lastLength);
- rv =HMAC_Finish(cx,last,&lastLength,hLen);
- if (rv !=SECSuccess) {
- break;
- }
- do_xor(T,last,hLen);
- }
-loser:
- if (cx) {
- HMAC_Destroy(cx, PR_TRUE);
- }
- if (last) {
- PORT_ZFree(last,lastBufLength);
- }
- return rv;
-}
-
-static SECItem *
-nsspkcs5_PBKDF2(const SECHashObject *hashobj, NSSPKCS5PBEParameter *pbe_param,
- SECItem *pwitem)
-{
- int iterations = pbe_param->iter;
- int bytesNeeded = pbe_param->keyLen;
- unsigned int dkLen = bytesNeeded;
- unsigned int hLen = hashobj->length;
- unsigned int nblocks = (dkLen+hLen-1) / hLen;
- unsigned int i;
- unsigned char *rp;
- unsigned char *T = NULL;
- SECItem *result = NULL;
- SECItem *salt = &pbe_param->salt;
- SECStatus rv = SECFailure;
-
- result = SECITEM_AllocItem(NULL,NULL,nblocks*hLen);
- if (result == NULL) {
- return NULL;
- }
-
- T = PORT_Alloc(hLen);
- if (T == NULL) {
- goto loser;
- }
-
- for (i=1,rp=result->data; i <= nblocks ; i++, rp +=hLen) {
- rv = nsspkcs5_PBKFD2_F(hashobj,pwitem,salt,iterations,i,T);
- if (rv != SECSuccess) {
- break;
- }
- PORT_Memcpy(rp,T,hLen);
- }
-
-loser:
- if (T) {
- PORT_ZFree(T,hLen);
- }
- if (rv != SECSuccess) {
- SECITEM_FreeItem(result,PR_TRUE);
- result = NULL;
- } else {
- result->len = dkLen;
- }
-
- return result;
-}
-#endif
-
-#define HMAC_BUFFER 64
-#define NSSPBE_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
-#define NSSPBE_MIN(x,y) ((x) < (y) ? (x) : (y))
-/*
- * This is the extended PBE function defined by the final PKCS #12 spec.
- */
-static SECItem *
-nsspkcs5_PKCS12PBE(const SECHashObject *hashObject,
- NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PBEBitGenID bitGenPurpose, unsigned int bytesNeeded)
-{
- PRArenaPool *arena = NULL;
- unsigned int SLen,PLen;
- unsigned int hashLength = hashObject->length;
- unsigned char *S, *P;
- SECItem *A = NULL, B, D, I;
- SECItem *salt = &pbe_param->salt;
- unsigned int c,i = 0;
- unsigned int hashLen;
- int iter;
- unsigned char *iterBuf;
- void *hash = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(!arena) {
- return NULL;
- }
-
- /* how many hash object lengths are needed */
- c = (bytesNeeded + (hashLength-1))/hashLength;
-
- /* initialize our buffers */
- D.len = HMAC_BUFFER;
- /* B and D are the same length, use one alloc go get both */
- D.data = (unsigned char*)PORT_ArenaZAlloc(arena, D.len*2);
- B.len = D.len;
- B.data = D.data + D.len;
-
- /* if all goes well, A will be returned, so don't use our temp arena */
- A = SECITEM_AllocItem(NULL,NULL,c*hashLength);
- if (A == NULL) {
- goto loser;
- }
-
- SLen = NSSPBE_ROUNDUP(salt->len,HMAC_BUFFER);
- PLen = NSSPBE_ROUNDUP(pwitem->len,HMAC_BUFFER);
- I.len = SLen+PLen;
- I.data = (unsigned char*)PORT_ArenaZAlloc(arena, I.len);
- if (I.data == NULL) {
- goto loser;
- }
-
- /* S & P are only used to initialize I */
- S = I.data;
- P = S + SLen;
-
- PORT_Memset(D.data, (char)bitGenPurpose, D.len);
- if (SLen) {
- for (i=0; i < SLen; i += salt->len) {
- PORT_Memcpy(S+i, salt->data, NSSPBE_MIN(SLen-i,salt->len));
- }
- }
- if (PLen) {
- for (i=0; i < PLen; i += pwitem->len) {
- PORT_Memcpy(P+i, pwitem->data, NSSPBE_MIN(PLen-i,pwitem->len));
- }
- }
-
- iterBuf = (unsigned char*)PORT_ArenaZAlloc(arena,hashLength);
- if (iterBuf == NULL) {
- goto loser;
- }
-
- hash = hashObject->create();
- if(!hash) {
- goto loser;
- }
- /* calculate the PBE now */
- for(i = 0; i < c; i++) {
- int Bidx; /* must be signed or the for loop won't terminate */
- unsigned int k, j;
- unsigned char *Ai = A->data+i*hashLength;
-
-
- for(iter = 0; iter < pbe_param->iter; iter++) {
- hashObject->begin(hash);
-
- if (iter) {
- hashObject->update(hash, iterBuf, hashLen);
- } else {
- hashObject->update(hash, D.data, D.len);
- hashObject->update(hash, I.data, I.len);
- }
-
- hashObject->end(hash, iterBuf, &hashLen, hashObject->length);
- if(hashLen != hashObject->length) {
- break;
- }
- }
-
- PORT_Memcpy(Ai, iterBuf, hashLength);
- for (Bidx = 0; Bidx < B.len; Bidx += hashLength) {
- PORT_Memcpy(B.data+Bidx,iterBuf,NSSPBE_MIN(B.len-Bidx,hashLength));
- }
-
- k = I.len/B.len;
- for(j = 0; j < k; j++) {
- unsigned int q, carryBit;
- unsigned char *Ij = I.data + j*B.len;
-
- /* (Ij = Ij+B+1) */
- for (Bidx = (B.len-1), q=1, carryBit=0; Bidx >= 0; Bidx--,q=0) {
- q += (unsigned int)Ij[Bidx];
- q += (unsigned int)B.data[Bidx];
- q += carryBit;
-
- carryBit = (q > 0xff);
- Ij[Bidx] = (unsigned char)(q & 0xff);
- }
- }
- }
-loser:
- if (hash) {
- hashObject->destroy(hash, PR_TRUE);
- }
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- if (A) {
- /* if i != c, then we didn't complete the loop above and must of failed
- * somwhere along the way */
- if (i != c) {
- SECITEM_ZfreeItem(A,PR_TRUE);
- A = NULL;
- } else {
- A->len = bytesNeeded;
- }
- }
-
- return A;
-}
-
-/*
- * generate key as per PKCS 5
- */
-SECItem *
-nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
- SECItem *iv, PRBool faulty3DES)
-{
- SECItem *hash = NULL, *key = NULL;
- const SECHashObject *hashObj;
- PRBool getIV = PR_FALSE;
-
- if((pbe_param == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- key = SECITEM_AllocItem(NULL,NULL,pbe_param->keyLen);
- if (key == NULL) {
- return NULL;
- }
-
- if (iv && (pbe_param->ivLen) && (iv->data == NULL)) {
- getIV = PR_TRUE;
- iv->data = (unsigned char *)PORT_Alloc(pbe_param->ivLen);
- if (iv->data == NULL) {
- goto loser;
- }
- iv->len = pbe_param->ivLen;
- }
-
- hashObj = HASH_GetRawHashObject(pbe_param->hashType);
- switch (pbe_param->pbeType) {
- case NSSPKCS5_PBKDF1:
- hash = nsspkcs5_PBKDF1Extended(hashObj,pbe_param,pwitem,faulty3DES);
- if (hash == NULL) {
- goto loser;
- }
- PORT_Assert(hash->len >= key->len+(getIV ? iv->len : 0));
- if (getIV) {
- PORT_Memcpy(iv->data, hash->data+(hash->len - iv->len),iv->len);
- }
-
- break;
-#ifdef PBKDF2
- case NSSPKCS5_PBKDF2:
- hash = nsspkcs5_PBKDF2(hashObj,pbe_param,pwitem);
- if (getIV) {
- PORT_Memcpy(iv->data, pbe_param->ivData, iv->len);
- }
- break;
-#endif
- case NSSPKCS5_PKCS12_V2:
- if (getIV) {
- hash = nsspkcs5_PKCS12PBE(hashObj,pbe_param,pwitem,
- pbeBitGenCipherIV,iv->len);
- if (hash == NULL) {
- goto loser;
- }
- PORT_Memcpy(iv->data,hash->data,iv->len);
- SECITEM_ZfreeItem(hash,PR_TRUE);
- hash = NULL;
- }
- hash = nsspkcs5_PKCS12PBE(hashObj,pbe_param,pwitem,
- pbe_param->keyID,key->len);
- default:
- break;
- }
-
- if (hash == NULL) {
- goto loser;
- }
-
- if (pbe_param->is2KeyDES) {
- PORT_Memcpy(key->data, hash->data, (key->len * 2) / 3);
- PORT_Memcpy(&(key->data[(key->len * 2) / 3]), key->data,
- key->len / 3);
- } else {
- PORT_Memcpy(key->data, hash->data, key->len);
- }
-
- SECITEM_ZfreeItem(hash, PR_TRUE);
- return key;
-
-loser:
- if (getIV && iv->data) {
- PORT_ZFree(iv->data,iv->len);
- iv->data = NULL;
- }
-
- SECITEM_ZfreeItem(key, PR_TRUE);
- return NULL;
-}
-
-static SECStatus
-nsspkcs5_FillInParam(SECOidTag algorithm, NSSPKCS5PBEParameter *pbe_param)
-{
- PRBool skipType = PR_FALSE;
-
- pbe_param->keyLen = 5;
- pbe_param->ivLen = 8;
- pbe_param->hashType = HASH_AlgSHA1;
- pbe_param->pbeType = NSSPKCS5_PBKDF1;
- pbe_param->encAlg = SEC_OID_RC2_CBC;
- pbe_param->is2KeyDES = PR_FALSE;
- switch(algorithm) {
- /* DES3 Algorithms */
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- pbe_param->is2KeyDES = PR_TRUE;
- /* fall through */
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
- /* fall through */
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- pbe_param->keyLen = 24;
- pbe_param->encAlg = SEC_OID_DES_EDE3_CBC;
- break;
-
- /* DES Algorithms */
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- pbe_param->hashType = HASH_AlgMD2;
- goto finish_des;
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- pbe_param->hashType = HASH_AlgMD5;
- /* fall through */
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
-finish_des:
- pbe_param->keyLen = 8;
- pbe_param->encAlg = SEC_OID_DES_CBC;
- break;
-
- /* RC2 Algorithms */
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- pbe_param->keyLen = 16;
- /* fall through */
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
- break;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- pbe_param->keyLen = 16;
- /* fall through */
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- break;
-
- /* RC4 algorithms */
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- skipType = PR_TRUE;
- /* fall through */
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- pbe_param->keyLen = 16;
- /* fall through */
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- if (!skipType) {
- pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
- }
- /* fall through */
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- pbe_param->ivLen = 0;
- pbe_param->encAlg = SEC_OID_RC4;
- break;
-
-#ifdef PBKDF2
- case SEC_OID_PKCS5_PBKDF2:
- case SEC_OID_PKCS5_PBES2:
- case SEC_OID_PKCS5_PBMAC1:
- /* everything else will be filled in by the template */
- pbe_param->ivLen = 0;
- pbe_param->pbeType = NSSPKCS5_PBKDF2;
- pbe_param->encAlg = SEC_OID_PKCS5_PBKDF2;
- pbe_param->keyLen = 0; /* needs to be set by caller after return */
- break;
-#endif
-
- default:
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-/* decode the algid and generate a PKCS 5 parameter from it
- */
-NSSPKCS5PBEParameter *
-nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator)
-{
- PRArenaPool *arena = NULL;
- NSSPKCS5PBEParameter *pbe_param = NULL;
- SECStatus rv = SECFailure;
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (arena == NULL)
- return NULL;
-
- /* allocate memory for the parameter */
- pbe_param = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena,
- sizeof(NSSPKCS5PBEParameter));
-
- if (pbe_param == NULL) {
- goto loser;
- }
-
- pbe_param->poolp = arena;
-
- rv = nsspkcs5_FillInParam(alg, pbe_param);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- pbe_param->iter = iterator;
- if (salt) {
- rv = SECITEM_CopyItem(arena,&pbe_param->salt,salt);
- }
-
- /* default key gen */
- pbe_param->keyID = pbeBitGenCipherKey;
-
-loser:
- if (rv != SECSuccess) {
- PORT_FreeArena(arena, PR_TRUE);
- pbe_param = NULL;
- }
-
- return pbe_param;
-}
-
-/*
- * find the hash type needed to implement a specific HMAC.
- * OID definitions are from pkcs 5 v2.0 and 2.1
- */
-HASH_HashType
-HASH_FromHMACOid(SECOidTag hmac)
-{
- switch (hmac) {
- case SEC_OID_HMAC_SHA1:
- return HASH_AlgSHA1;
- case SEC_OID_HMAC_SHA256:
- return HASH_AlgSHA256;
- case SEC_OID_HMAC_SHA384:
- return HASH_AlgSHA384;
- case SEC_OID_HMAC_SHA512:
- return HASH_AlgSHA512;
- case SEC_OID_HMAC_SHA224:
- default:
- break;
- }
- return HASH_AlgNULL;
-}
-
-/* decode the algid and generate a PKCS 5 parameter from it
- */
-NSSPKCS5PBEParameter *
-nsspkcs5_AlgidToParam(SECAlgorithmID *algid)
-{
- NSSPKCS5PBEParameter *pbe_param = NULL;
- nsspkcs5V2PBEParameter pbev2_param;
- SECOidTag algorithm;
- SECStatus rv = SECFailure;
-
- if (algid == NULL) {
- return NULL;
- }
-
- algorithm = SECOID_GetAlgorithmTag(algid);
- if (algorithm == SEC_OID_UNKNOWN) {
- goto loser;
- }
-
- pbe_param = nsspkcs5_NewParam(algorithm, NULL, 1);
- if (pbe_param == NULL) {
- goto loser;
- }
-
- /* decode parameter */
- rv = SECFailure;
- switch (pbe_param->pbeType) {
- case NSSPKCS5_PBKDF1:
- rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
- NSSPKCS5PBEParameterTemplate, &algid->parameters);
- break;
- case NSSPKCS5_PKCS12_V2:
- rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
- NSSPKCS5PKCS12V2PBEParameterTemplate, &algid->parameters);
- break;
-#ifdef PBKDF2
- case NSSPKCS5_PBKDF2:
- PORT_Memset(&pbev2_param,0, sizeof(pbev2_param));
- /* just the PBE */
- if (algorithm == SEC_OID_PKCS5_PBKDF2) {
- rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
- NSSPKCS5V2PBEParameterTemplate, &algid->parameters);
- } else {
- /* PBE data an others */
- rv = SEC_ASN1DecodeItem(pbe_param->poolp, &pbev2_param,
- NSSPKCS5V2PBES2ParameterTemplate, &algid->parameters);
- if (rv != SECSuccess) {
- break;
- }
- pbe_param->encAlg = SECOID_GetAlgorithmTag(&pbev2_param.algParams);
- rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
- NSSPKCS5V2PBEParameterTemplate,
- &pbev2_param.keyParams.parameters);
- if (rv != SECSuccess) {
- break;
- }
- pbe_param->keyLen = DER_GetInteger(&pbe_param->keyLength);
- }
- /* we we are encrypting, save any iv's */
- if (algorithm == SEC_OID_PKCS5_PBES2) {
- pbe_param->ivLen = pbev2_param.algParams.parameters.len;
- pbe_param->ivData = pbev2_param.algParams.parameters.data;
- }
- pbe_param->hashType =
- HASH_FromHMACOid(SECOID_GetAlgorithmTag(&pbe_param->prfAlg));
- if (pbe_param->hashType == HASH_AlgNULL) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- rv = SECFailure;
- }
- break;
-#endif
- }
-
-loser:
- if (rv == SECSuccess) {
- pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
- } else {
- nsspkcs5_DestroyPBEParameter(pbe_param);
- pbe_param = NULL;
- }
-
- return pbe_param;
-}
-
-/* destroy a pbe parameter. it assumes that the parameter was
- * generated using the appropriate create function and therefor
- * contains an arena pool.
- */
-void
-nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param)
-{
- if (pbe_param != NULL) {
- PORT_FreeArena(pbe_param->poolp, PR_FALSE);
- }
-}
-
-
-/* crypto routines */
-/* perform DES encryption and decryption. these routines are called
- * by nsspkcs5_CipherData. In the case of an error, NULL is returned.
- */
-static SECItem *
-sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
- PRBool encrypt)
-{
- SECItem *dest;
- SECItem *dup_src;
- SECStatus rv = SECFailure;
- int pad;
-
- if((src == NULL) || (key == NULL) || (iv == NULL))
- return NULL;
-
- dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
- }
-
- if(encrypt != PR_FALSE) {
- void *dummy;
-
- dummy = CBC_PadBuffer(NULL, dup_src->data,
- dup_src->len, &dup_src->len, 8 /* DES_BLOCK_SIZE */);
- if(dummy == NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- return NULL;
- }
- dup_src->data = (unsigned char*)dummy;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- /* allocate with over flow */
- dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64);
- if(dest->data != NULL) {
- DESContext *ctxt;
- ctxt = DES_CreateContext(key->data, iv->data,
- (triple_des ? NSS_DES_EDE3_CBC : NSS_DES_CBC),
- encrypt);
-
- if(ctxt != NULL) {
- rv = (encrypt ? DES_Encrypt : DES_Decrypt)(
- ctxt, dest->data, &dest->len,
- dup_src->len + 64, dup_src->data, dup_src->len);
-
- /* remove padding -- assumes 64 bit blocks */
- if((encrypt == PR_FALSE) && (rv == SECSuccess)) {
- pad = dest->data[dest->len-1];
- if((pad > 0) && (pad <= 8)) {
- if(dest->data[dest->len-pad] != pad) {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- } else {
- dest->len -= pad;
- }
- } else {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- }
- }
- DES_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
-
- if(rv == SECFailure) {
- if(dest != NULL) {
- SECITEM_FreeItem(dest, PR_TRUE);
- }
- dest = NULL;
- }
-
- if(dup_src != NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- }
-
- return dest;
-}
-
-/* perform aes encryption/decryption if an error occurs, NULL is returned
- */
-static SECItem *
-sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
- PRBool encrypt)
-{
- SECItem *dest;
- SECItem *dup_src;
- SECStatus rv = SECFailure;
- int pad;
-
- if((src == NULL) || (key == NULL) || (iv == NULL))
- return NULL;
-
- dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
- }
-
- if(encrypt != PR_FALSE) {
- void *dummy;
-
- dummy = CBC_PadBuffer(NULL, dup_src->data,
- dup_src->len, &dup_src->len,AES_BLOCK_SIZE);
- if(dummy == NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- return NULL;
- }
- dup_src->data = (unsigned char*)dummy;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- /* allocate with over flow */
- dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64);
- if(dest->data != NULL) {
- AESContext *ctxt;
- ctxt = AES_CreateContext(key->data, iv->data,
- NSS_AES_CBC, encrypt, key->len, 16);
-
- if(ctxt != NULL) {
- rv = (encrypt ? AES_Encrypt : AES_Decrypt)(
- ctxt, dest->data, &dest->len,
- dup_src->len + 64, dup_src->data, dup_src->len);
-
- /* remove padding -- assumes 64 bit blocks */
- if((encrypt == PR_FALSE) && (rv == SECSuccess)) {
- pad = dest->data[dest->len-1];
- if((pad > 0) && (pad <= 16)) {
- if(dest->data[dest->len-pad] != pad) {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- } else {
- dest->len -= pad;
- }
- } else {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- }
- }
- AES_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
-
- if(rv == SECFailure) {
- if(dest != NULL) {
- SECITEM_FreeItem(dest, PR_TRUE);
- }
- dest = NULL;
- }
-
- if(dup_src != NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- }
-
- return dest;
-}
-
-/* perform rc2 encryption/decryption if an error occurs, NULL is returned
- */
-static SECItem *
-sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
- PRBool encrypt)
-{
- SECItem *dest;
- SECItem *dup_src;
- SECStatus rv = SECFailure;
- int pad;
-
- if((src == NULL) || (key == NULL) || (iv == NULL)) {
- return NULL;
- }
-
- dup_src = SECITEM_DupItem(src);
- if(dup_src == NULL) {
- return NULL;
- }
-
- if(encrypt != PR_FALSE) {
- void *dummy;
-
- dummy = CBC_PadBuffer(NULL, dup_src->data,
- dup_src->len, &dup_src->len, 8 /* RC2_BLOCK_SIZE */);
- if(dummy == NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- return NULL;
- }
- dup_src->data = (unsigned char*)dummy;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64);
- if(dest->data != NULL) {
- RC2Context *ctxt;
-
- ctxt = RC2_CreateContext(key->data, key->len, iv->data,
- NSS_RC2_CBC, key->len);
-
- if(ctxt != NULL) {
- rv = (encrypt ? RC2_Encrypt: RC2_Decrypt)(
- ctxt, dest->data, &dest->len,
- dup_src->len + 64, dup_src->data, dup_src->len);
-
- /* assumes 8 byte blocks -- remove padding */
- if((rv == SECSuccess) && (encrypt != PR_TRUE)) {
- pad = dest->data[dest->len-1];
- if((pad > 0) && (pad <= 8)) {
- if(dest->data[dest->len-pad] != pad) {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECFailure;
- } else {
- dest->len -= pad;
- }
- } else {
- PORT_SetError(SEC_ERROR_BAD_PASSWORD);
- rv = SECFailure;
- }
- }
-
- }
- }
- }
-
- if((rv != SECSuccess) && (dest != NULL)) {
- SECITEM_FreeItem(dest, PR_TRUE);
- dest = NULL;
- }
-
- if(dup_src != NULL) {
- SECITEM_FreeItem(dup_src, PR_TRUE);
- }
-
- return dest;
-}
-
-/* perform rc4 encryption and decryption */
-static SECItem *
-sec_pkcs5_rc4(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy_op,
- PRBool encrypt)
-{
- SECItem *dest;
- SECStatus rv = SECFailure;
-
- if((src == NULL) || (key == NULL) || (iv == NULL)) {
- return NULL;
- }
-
- dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(dest != NULL) {
- dest->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- (src->len + 64));
- if(dest->data != NULL) {
- RC4Context *ctxt;
-
- ctxt = RC4_CreateContext(key->data, key->len);
- if(ctxt) {
- rv = (encrypt ? RC4_Encrypt : RC4_Decrypt)(
- ctxt, dest->data, &dest->len,
- src->len + 64, src->data, src->len);
- RC4_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
-
- if((rv != SECSuccess) && (dest)) {
- SECITEM_FreeItem(dest, PR_TRUE);
- dest = NULL;
- }
-
- return dest;
-}
-/* function pointer template for crypto functions */
-typedef SECItem *(* pkcs5_crypto_func)(SECItem *key, SECItem *iv,
- SECItem *src, PRBool op1, PRBool op2);
-
-/* performs the cipher operation on the src and returns the result.
- * if an error occurs, NULL is returned.
- *
- * a null length password is allowed. this corresponds to encrypting
- * the data with ust the salt.
- */
-/* change this to use PKCS 11? */
-SECItem *
-nsspkcs5_CipherData(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
- SECItem *src, PRBool encrypt, PRBool *update)
-{
- SECItem *key = NULL, iv;
- SECItem *dest = NULL;
- PRBool tripleDES = PR_TRUE;
- pkcs5_crypto_func cryptof;
-
- iv.data = NULL;
-
- if (update) {
- *update = PR_FALSE;
- }
-
- if ((pwitem == NULL) || (src == NULL)) {
- return NULL;
- }
-
- /* get key, and iv */
- key = nsspkcs5_ComputeKeyAndIV(pbe_param, pwitem, &iv, PR_FALSE);
- if(key == NULL) {
- return NULL;
- }
-
- switch(pbe_param->encAlg) {
- /* PKCS 5 v2 only */
- case SEC_OID_AES_128_CBC:
- case SEC_OID_AES_192_CBC:
- case SEC_OID_AES_256_CBC:
- cryptof = sec_pkcs5_aes;
- break;
- case SEC_OID_DES_EDE3_CBC:
- cryptof = sec_pkcs5_des;
- tripleDES = PR_TRUE;
- break;
- case SEC_OID_DES_CBC:
- cryptof = sec_pkcs5_des;
- tripleDES = PR_FALSE;
- break;
- case SEC_OID_RC2_CBC:
- cryptof = sec_pkcs5_rc2;
- break;
- case SEC_OID_RC4:
- cryptof = sec_pkcs5_rc4;
- break;
- default:
- cryptof = NULL;
- break;
- }
-
- if (cryptof == NULL) {
- goto loser;
- }
-
- dest = (*cryptof)(key, &iv, src, tripleDES, encrypt);
- /*
- * it's possible for some keys and keydb's to claim to
- * be triple des when they're really des. In this case
- * we simply try des. If des works we set the update flag
- * so the key db knows it needs to update all it's entries.
- * The case can only happen on decrypted of a
- * SEC_OID_DES_EDE3_CBD.
- */
- if ((dest == NULL) && (encrypt == PR_FALSE) &&
- (pbe_param->encAlg == SEC_OID_DES_EDE3_CBC)) {
- dest = (*cryptof)(key, &iv, src, PR_FALSE, encrypt);
- if (update && (dest != NULL)) *update = PR_TRUE;
- }
-
-loser:
- if (key != NULL) {
- SECITEM_ZfreeItem(key, PR_TRUE);
- }
- if (iv.data != NULL) {
- SECITEM_ZfreeItem(&iv, PR_FALSE);
- }
-
- return dest;
-}
-
-/* creates a algorithm ID containing the PBE algorithm and appropriate
- * parameters. the required parameter is the algorithm. if salt is
- * not specified, it is generated randomly. if IV is specified, it overrides
- * the PKCS 5 generation of the IV.
- *
- * the returned SECAlgorithmID should be destroyed using
- * SECOID_DestroyAlgorithmID
- */
-SECAlgorithmID *
-nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm,
- NSSPKCS5PBEParameter *pbe_param)
-{
- SECAlgorithmID *algid, *ret_algid = NULL;
- SECItem der_param;
- nsspkcs5V2PBEParameter pkcs5v2_param;
-
- SECStatus rv = SECFailure;
- void *dummy = NULL;
-
- if (arena == NULL) {
- return NULL;
- }
-
- der_param.data = NULL;
- der_param.len = 0;
-
- /* generate the algorithm id */
- algid = (SECAlgorithmID *)PORT_ArenaZAlloc(arena, sizeof(SECAlgorithmID));
- if (algid == NULL) {
- goto loser;
- }
-
- if (pbe_param->iteration.data == NULL) {
- dummy = SEC_ASN1EncodeInteger(pbe_param->poolp,&pbe_param->iteration,
- pbe_param->iter);
- if (dummy == NULL) {
- goto loser;
- }
- }
- switch (pbe_param->pbeType) {
- case NSSPKCS5_PBKDF1:
- dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param,
- NSSPKCS5PBEParameterTemplate);
- break;
- case NSSPKCS5_PKCS12_V2:
- dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param,
- NSSPKCS5PKCS12V2PBEParameterTemplate);
- break;
-#ifdef PBKDF2
- case NSSPKCS5_PBKDF2:
- if (pbe_param->keyLength.data == NULL) {
- dummy = SEC_ASN1EncodeInteger(pbe_param->poolp,
- &pbe_param->keyLength, pbe_param->keyLen);
- if (dummy == NULL) {
- goto loser;
- }
- }
- PORT_Memset(&pkcs5v2_param, 0, sizeof(pkcs5v2_param));
- dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param,
- NSSPKCS5V2PBEParameterTemplate);
- if (dummy == NULL) {
- break;
- }
- dummy = NULL;
- rv = SECOID_SetAlgorithmID(arena, &pkcs5v2_param.keyParams,
- SEC_OID_PKCS5_PBKDF2, &der_param);
- if (rv != SECSuccess) {
- break;
- }
- der_param.data = pbe_param->ivData;
- der_param.len = pbe_param->ivLen;
- rv = SECOID_SetAlgorithmID(arena, &pkcs5v2_param.algParams,
- pbe_param->encAlg, pbe_param->ivLen ? &der_param : NULL);
- if (rv != SECSuccess) {
- break;
- }
- dummy = SEC_ASN1EncodeItem(arena, &der_param, &pkcs5v2_param,
- NSSPKCS5V2PBES2ParameterTemplate);
- break;
-#endif
- default:
- break;
- }
-
- if (dummy == NULL) {
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(arena, algid, algorithm, &der_param);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
- if (ret_algid == NULL) {
- goto loser;
- }
-
- rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
- if (rv != SECSuccess) {
- SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
- ret_algid = NULL;
- }
-
-loser:
-
- return ret_algid;
-}
diff --git a/security/nss/lib/softoken/lowpbe.h b/security/nss/lib/softoken/lowpbe.h
deleted file mode 100644
index 655ec5a6c..000000000
--- a/security/nss/lib/softoken/lowpbe.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SECPKCS5_H_
-#define _SECPKCS5_H_
-
-#include "plarena.h"
-#include "secitem.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "hasht.h"
-
-typedef SECItem * (* SEC_PKCS5GetPBEPassword)(void *arg);
-
-/* used for V2 PKCS 12 Draft Spec */
-typedef enum {
- pbeBitGenIDNull = 0,
- pbeBitGenCipherKey = 0x01,
- pbeBitGenCipherIV = 0x02,
- pbeBitGenIntegrityKey = 0x03
-} PBEBitGenID;
-
-typedef enum {
- NSSPKCS5_PBKDF1 = 0,
- NSSPKCS5_PBKDF2 = 1,
- NSSPKCS5_PKCS12_V2 = 2
-} NSSPKCS5PBEType;
-
-typedef struct NSSPKCS5PBEParameterStr NSSPKCS5PBEParameter;
-
-struct NSSPKCS5PBEParameterStr {
- PRArenaPool *poolp;
- SECItem salt; /* octet string */
- SECItem iteration; /* integer */
- SECItem keyLength; /* integer */
-
- /* used locally */
- int iter;
- int keyLen;
- int ivLen;
- unsigned char *ivData;
- HASH_HashType hashType;
- NSSPKCS5PBEType pbeType;
- SECAlgorithmID prfAlg;
- PBEBitGenID keyID;
- SECOidTag encAlg;
- PRBool is2KeyDES;
-};
-
-
-SEC_BEGIN_PROTOS
-/* Create a PKCS5 Algorithm ID
- * The algorithm ID is set up using the PKCS #5 parameter structure
- * algorithm is the PBE algorithm ID for the desired algorithm
- * pbe is a pbe param block with all the info needed to create the
- * algorithm id.
- * If an error occurs or the algorithm specified is not supported
- * or is not a password based encryption algorithm, NULL is returned.
- * Otherwise, a pointer to the algorithm id is returned.
- */
-extern SECAlgorithmID *
-nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm,
- NSSPKCS5PBEParameter *pbe);
-
-/*
- * Convert an Algorithm ID to a PBE Param.
- * NOTE: this does not suppport PKCS 5 v2 because it's only used for the
- * keyDB which only support PKCS 5 v1, PFX, and PKCS 12.
- */
-NSSPKCS5PBEParameter *
-nsspkcs5_AlgidToParam(SECAlgorithmID *algid);
-
-/*
- * Convert an Algorithm ID to a PBE Param.
- * NOTE: this does not suppport PKCS 5 v2 because it's only used for the
- * keyDB which only support PKCS 5 v1, PFX, and PKCS 12.
- */
-NSSPKCS5PBEParameter *
-nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator);
-
-
-/* Encrypt/Decrypt data using password based encryption.
- * algid is the PBE algorithm identifier,
- * pwitem is the password,
- * src is the source for encryption/decryption,
- * encrypt is PR_TRUE for encryption, PR_FALSE for decryption.
- * The key and iv are generated based upon PKCS #5 then the src
- * is either encrypted or decrypted. If an error occurs, NULL
- * is returned, otherwise the ciphered contents is returned.
- */
-extern SECItem *
-nsspkcs5_CipherData(NSSPKCS5PBEParameter *, SECItem *pwitem,
- SECItem *src, PRBool encrypt, PRBool *update);
-
-extern SECItem *
-nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *, SECItem *pwitem,
- SECItem *iv, PRBool faulty3DES);
-
-/* Destroys PBE parameter */
-extern void
-nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *param);
-
-HASH_HashType HASH_FromHMACOid(SECOidTag oid);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn
deleted file mode 100644
index e36bf6075..000000000
--- a/security/nss/lib/softoken/manifest.mn
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-
-MODULE = nss
-DIRS = legacydb
-
-LIBRARY_NAME = softokn
-LIBRARY_VERSION = 3
-MAPFILE = $(OBJDIR)/softokn.def
-
-DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" -DSOFTOKEN_LIB_NAME=\"$(notdir $(SHARED_LIBRARY))\" -DSHLIB_VERSION=\"$(LIBRARY_VERSION)\"
-
-ifdef SQLITE_INCLUDE_DIR
-INCLUDES += -I$(SQLITE_INCLUDE_DIR)
-endif
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- lgglue.h \
- lowkeyi.h \
- lowkeyti.h \
- pkcs11ni.h \
- softoken.h \
- softoknt.h \
- softkver.h \
- sdb.h \
- sftkdbt.h \
- $(NULL)
-
-CSRCS = \
- ecdecode.c \
- fipsaudt.c \
- fipstest.c \
- fipstokn.c \
- lgglue.c \
- lowkey.c \
- lowpbe.c \
- padbuf.c \
- pkcs11.c \
- pkcs11c.c \
- pkcs11u.c \
- rsawrapr.c \
- sdb.c \
- sftkdb.c \
- sftkhmac.c \
- sftkpars.c \
- sftkpwd.c \
- softkver.c \
- tlsprf.c \
- jpakesftk.c \
- $(NULL)
-
-ifdef SQLITE_UNSAFE_THREADS
-DEFINES += -DSQLITE_UNSAFE_THREADS
-endif
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/softoken/padbuf.c b/security/nss/lib/softoken/padbuf.c
deleted file mode 100644
index 549fdeab7..000000000
--- a/security/nss/lib/softoken/padbuf.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "blapit.h"
-#include "secport.h"
-#include "secerr.h"
-
-/*
- * Prepare a buffer for any padded CBC encryption algorithm, growing to the
- * appropriate boundary and filling with the appropriate padding.
- * blockSize must be a power of 2.
- *
- * NOTE: If arena is non-NULL, we re-allocate from there, otherwise
- * we assume (and use) XP memory (re)allocation.
- */
-unsigned char *
-CBC_PadBuffer(PRArenaPool *arena, unsigned char *inbuf, unsigned int inlen,
- unsigned int *outlen, int blockSize)
-{
- unsigned char *outbuf;
- unsigned int des_len;
- unsigned int i;
- unsigned char des_pad_len;
-
- /*
- * We need from 1 to blockSize bytes -- we *always* grow.
- * The extra bytes contain the value of the length of the padding:
- * if we have 2 bytes of padding, then the padding is "0x02, 0x02".
- */
- des_len = (inlen + blockSize) & ~(blockSize - 1);
-
- if (arena != NULL) {
- outbuf = (unsigned char*)PORT_ArenaGrow (arena, inbuf, inlen, des_len);
- } else {
- outbuf = (unsigned char*)PORT_Realloc (inbuf, des_len);
- }
-
- if (outbuf == NULL) {
- PORT_SetError (SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- des_pad_len = des_len - inlen;
- for (i = inlen; i < des_len; i++)
- outbuf[i] = des_pad_len;
-
- *outlen = des_len;
- return outbuf;
-}
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
deleted file mode 100644
index f91d15a3d..000000000
--- a/security/nss/lib/softoken/pkcs11.c
+++ /dev/null
@@ -1,4708 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file implements PKCS 11 on top of our existing security modules
- *
- * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
- * This implementation has two slots:
- * slot 1 is our generic crypto support. It does not require login.
- * It supports Public Key ops, and all they bulk ciphers and hashes.
- * It can also support Private Key ops for imported Private keys. It does
- * not have any token storage.
- * slot 2 is our private key support. It requires a login before use. It
- * can store Private Keys and Certs as token objects. Currently only private
- * keys and their associated Certificates are saved on the token.
- *
- * In this implementation, session objects are only visible to the session
- * that created or generated them.
- */
-#include "seccomon.h"
-#include "secitem.h"
-#include "pkcs11.h"
-#include "pkcs11i.h"
-#include "softoken.h"
-#include "lowkeyi.h"
-#include "blapi.h"
-#include "secder.h"
-#include "secport.h"
-#include "secrng.h"
-#include "prtypes.h"
-#include "nspr.h"
-#include "softkver.h"
-#include "secoid.h"
-#include "sftkdb.h"
-#include "utilpars.h"
-#include "ec.h"
-#include "secasn1.h"
-#include "secerr.h"
-#include "lgglue.h"
-
-PRBool parentForkedAfterC_Initialize;
-
-#ifndef NO_FORK_CHECK
-
-PRBool sftkForkCheckDisabled;
-
-#if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED)
-PRBool forked = PR_FALSE;
-#endif
-
-#if defined(CHECK_FORK_GETPID) || defined(CHECK_FORK_MIXED)
-#include <unistd.h>
-pid_t myPid;
-#endif
-
-#ifdef CHECK_FORK_MIXED
-#include <sys/systeminfo.h>
-PRBool usePthread_atfork;
-#endif
-
-#endif
-
-/*
- * ******************** Static data *******************************
- */
-
-/* The next three strings must be exactly 32 characters long */
-static char *manufacturerID = "Mozilla Foundation ";
-static char manufacturerID_space[33];
-static char *libraryDescription = "NSS Internal Crypto Services ";
-static char libraryDescription_space[33];
-
-/*
- * In FIPS mode, we disallow login attempts for 1 second after a login
- * failure so that there are at most 60 login attempts per minute.
- */
-static PRIntervalTime loginWaitTime;
-static PRUint32 minSessionObjectHandle = 1U;
-
-#define __PASTE(x,y) x##y
-
-/*
- * we renamed all our internal functions, get the correct
- * definitions for them...
- */
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-
-#define CK_EXTERN extern
-#define CK_PKCS11_FUNCTION_INFO(func) \
- CK_RV __PASTE(NS,func)
-#define CK_NEED_ARG_LIST 1
-
-#include "pkcs11f.h"
-
-
-
-/* build the crypto module table */
-static const CK_FUNCTION_LIST sftk_funcList = {
- { 1, 10 },
-
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-
-#define CK_PKCS11_FUNCTION_INFO(func) \
- __PASTE(NS,func),
-#include "pkcs11f.h"
-
-};
-
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-
-
-#undef __PASTE
-
-/* List of DES Weak Keys */
-typedef unsigned char desKey[8];
-static const desKey sftk_desWeakTable[] = {
-#ifdef noParity
- /* weak */
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e },
- { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 },
- { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
- /* semi-weak */
- { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe },
- { 0xfe, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0xfe },
-
- { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 },
- { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e },
-
- { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x0f, 0x00, 0x0f },
- { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 },
-
- { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
- { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e },
-
- { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e },
- { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 },
-
- { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe },
- { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 },
-#else
- /* weak */
- { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
- { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e },
- { 0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1 },
- { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe },
-
- /* semi-weak */
- { 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe },
- { 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01 },
-
- { 0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1 },
- { 0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e },
-
- { 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1 },
- { 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01 },
-
- { 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
- { 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e },
-
- { 0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e },
- { 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01 },
-
- { 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe },
- { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1 }
-#endif
-};
-
-
-static const int sftk_desWeakTableSize = sizeof(sftk_desWeakTable)/
- sizeof(sftk_desWeakTable[0]);
-
-/* DES KEY Parity conversion table. Takes each byte/2 as an index, returns
- * that byte with the proper parity bit set */
-static const unsigned char parityTable[256] = {
-/* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */
-/* E */ 0x01,0x02,0x04,0x07,0x08,0x0b,0x0d,0x0e,
-/* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */
-/* O */ 0x10,0x13,0x15,0x16,0x19,0x1a,0x1c,0x1f,
-/* Odd....0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e */
-/* O */ 0x20,0x23,0x25,0x26,0x29,0x2a,0x2c,0x2f,
-/* Even...0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e */
-/* E */ 0x31,0x32,0x34,0x37,0x38,0x3b,0x3d,0x3e,
-/* Odd....0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e */
-/* O */ 0x40,0x43,0x45,0x46,0x49,0x4a,0x4c,0x4f,
-/* Even...0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e */
-/* E */ 0x51,0x52,0x54,0x57,0x58,0x5b,0x5d,0x5e,
-/* Even...0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e */
-/* E */ 0x61,0x62,0x64,0x67,0x68,0x6b,0x6d,0x6e,
-/* Odd....0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e */
-/* O */ 0x70,0x73,0x75,0x76,0x79,0x7a,0x7c,0x7f,
-/* Odd....0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e */
-/* O */ 0x80,0x83,0x85,0x86,0x89,0x8a,0x8c,0x8f,
-/* Even...0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e */
-/* E */ 0x91,0x92,0x94,0x97,0x98,0x9b,0x9d,0x9e,
-/* Even...0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae */
-/* E */ 0xa1,0xa2,0xa4,0xa7,0xa8,0xab,0xad,0xae,
-/* Odd....0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe */
-/* O */ 0xb0,0xb3,0xb5,0xb6,0xb9,0xba,0xbc,0xbf,
-/* Even...0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce */
-/* E */ 0xc1,0xc2,0xc4,0xc7,0xc8,0xcb,0xcd,0xce,
-/* Odd....0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde */
-/* O */ 0xd0,0xd3,0xd5,0xd6,0xd9,0xda,0xdc,0xdf,
-/* Odd....0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee */
-/* O */ 0xe0,0xe3,0xe5,0xe6,0xe9,0xea,0xec,0xef,
-/* Even...0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe */
-/* E */ 0xf1,0xf2,0xf4,0xf7,0xf8,0xfb,0xfd,0xfe,
-};
-
-/* Mechanisms */
-struct mechanismList {
- CK_MECHANISM_TYPE type;
- CK_MECHANISM_INFO info;
- PRBool privkey;
-};
-
-/*
- * the following table includes a complete list of mechanism defined by
- * PKCS #11 version 2.01. Those Mechanisms not supported by this PKCS #11
- * module are ifdef'ed out.
- */
-#define CKF_EN_DE CKF_ENCRYPT | CKF_DECRYPT
-#define CKF_WR_UN CKF_WRAP | CKF_UNWRAP
-#define CKF_SN_VR CKF_SIGN | CKF_VERIFY
-#define CKF_SN_RE CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER
-
-#define CKF_EN_DE_WR_UN CKF_EN_DE | CKF_WR_UN
-#define CKF_SN_VR_RE CKF_SN_VR | CKF_SN_RE
-#define CKF_DUZ_IT_ALL CKF_EN_DE_WR_UN | CKF_SN_VR_RE
-
-#define CKF_EC_PNU CKF_EC_FP | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS
-
-#define CKF_EC_BPNU CKF_EC_F_2M | CKF_EC_PNU
-
-#define CK_MAX 0xffffffff
-
-static const struct mechanismList mechanisms[] = {
-
- /*
- * PKCS #11 Mechanism List.
- *
- * The first argument is the PKCS #11 Mechanism we support.
- * The second argument is Mechanism info structure. It includes:
- * The minimum key size,
- * in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
- * in bytes for RC5, AES, Camellia, and CAST*
- * ignored for DES*, IDEA and FORTEZZA based
- * The maximum key size,
- * in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs.
- * in bytes for RC5, AES, Camellia, and CAST*
- * ignored for DES*, IDEA and FORTEZZA based
- * Flags
- * What operations are supported by this mechanism.
- * The third argument is a bool which tells if this mechanism is
- * supported in the database token.
- *
- */
-
- /* ------------------------- RSA Operations ---------------------------*/
- {CKM_RSA_PKCS_KEY_PAIR_GEN,{RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_GENERATE_KEY_PAIR},PR_TRUE},
- {CKM_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_DUZ_IT_ALL}, PR_TRUE},
- {CKM_RSA_PKCS_PSS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_SN_VR}, PR_TRUE},
-#ifdef SFTK_RSA9796_SUPPORTED
- {CKM_RSA_9796, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_DUZ_IT_ALL}, PR_TRUE},
-#endif
- {CKM_RSA_X_509, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_DUZ_IT_ALL}, PR_TRUE},
- /* -------------- RSA Multipart Signing Operations -------------------- */
- {CKM_MD2_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_SN_VR}, PR_TRUE},
- {CKM_MD5_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_SN_VR}, PR_TRUE},
- {CKM_SHA1_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_SN_VR}, PR_TRUE},
- {CKM_SHA224_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_SN_VR}, PR_TRUE},
- {CKM_SHA256_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_SN_VR}, PR_TRUE},
- {CKM_SHA384_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_SN_VR}, PR_TRUE},
- {CKM_SHA512_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX,
- CKF_SN_VR}, PR_TRUE},
- /* ------------------------- DSA Operations --------------------------- */
- {CKM_DSA_KEY_PAIR_GEN, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
- CKF_GENERATE_KEY_PAIR}, PR_TRUE},
- {CKM_DSA, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
- CKF_SN_VR}, PR_TRUE},
- {CKM_DSA_PARAMETER_GEN, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
- CKF_GENERATE}, PR_TRUE},
- {CKM_DSA_SHA1, {DSA_MIN_P_BITS, DSA_MAX_P_BITS,
- CKF_SN_VR}, PR_TRUE},
- /* -------------------- Diffie Hellman Operations --------------------- */
- /* no diffie hellman yet */
- {CKM_DH_PKCS_KEY_PAIR_GEN, {DH_MIN_P_BITS, DH_MAX_P_BITS,
- CKF_GENERATE_KEY_PAIR}, PR_TRUE},
- {CKM_DH_PKCS_DERIVE, {DH_MIN_P_BITS, DH_MAX_P_BITS,
- CKF_DERIVE}, PR_TRUE},
-#ifdef NSS_ENABLE_ECC
- /* -------------------- Elliptic Curve Operations --------------------- */
- {CKM_EC_KEY_PAIR_GEN, {112, 571, CKF_GENERATE_KEY_PAIR|CKF_EC_BPNU}, PR_TRUE},
- {CKM_ECDH1_DERIVE, {112, 571, CKF_DERIVE|CKF_EC_BPNU}, PR_TRUE},
- {CKM_ECDSA, {112, 571, CKF_SN_VR|CKF_EC_BPNU}, PR_TRUE},
- {CKM_ECDSA_SHA1, {112, 571, CKF_SN_VR|CKF_EC_BPNU}, PR_TRUE},
-#endif /* NSS_ENABLE_ECC */
- /* ------------------------- RC2 Operations --------------------------- */
- {CKM_RC2_KEY_GEN, {1, 128, CKF_GENERATE}, PR_TRUE},
- {CKM_RC2_ECB, {1, 128, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_RC2_CBC, {1, 128, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_RC2_MAC, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_RC2_MAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_RC2_CBC_PAD, {1, 128, CKF_EN_DE_WR_UN}, PR_TRUE},
- /* ------------------------- RC4 Operations --------------------------- */
- {CKM_RC4_KEY_GEN, {1, 256, CKF_GENERATE}, PR_FALSE},
- {CKM_RC4, {1, 256, CKF_EN_DE_WR_UN}, PR_FALSE},
- /* ------------------------- DES Operations --------------------------- */
- {CKM_DES_KEY_GEN, { 8, 8, CKF_GENERATE}, PR_TRUE},
- {CKM_DES_ECB, { 8, 8, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_DES_CBC, { 8, 8, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_DES_MAC, { 8, 8, CKF_SN_VR}, PR_TRUE},
- {CKM_DES_MAC_GENERAL, { 8, 8, CKF_SN_VR}, PR_TRUE},
- {CKM_DES_CBC_PAD, { 8, 8, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_DES2_KEY_GEN, {24, 24, CKF_GENERATE}, PR_TRUE},
- {CKM_DES3_KEY_GEN, {24, 24, CKF_GENERATE}, PR_TRUE },
- {CKM_DES3_ECB, {24, 24, CKF_EN_DE_WR_UN}, PR_TRUE },
- {CKM_DES3_CBC, {24, 24, CKF_EN_DE_WR_UN}, PR_TRUE },
- {CKM_DES3_MAC, {24, 24, CKF_SN_VR}, PR_TRUE },
- {CKM_DES3_MAC_GENERAL, {24, 24, CKF_SN_VR}, PR_TRUE },
- {CKM_DES3_CBC_PAD, {24, 24, CKF_EN_DE_WR_UN}, PR_TRUE },
- /* ------------------------- CDMF Operations --------------------------- */
- {CKM_CDMF_KEY_GEN, {8, 8, CKF_GENERATE}, PR_TRUE},
- {CKM_CDMF_ECB, {8, 8, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CDMF_CBC, {8, 8, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CDMF_MAC, {8, 8, CKF_SN_VR}, PR_TRUE},
- {CKM_CDMF_MAC_GENERAL, {8, 8, CKF_SN_VR}, PR_TRUE},
- {CKM_CDMF_CBC_PAD, {8, 8, CKF_EN_DE_WR_UN}, PR_TRUE},
- /* ------------------------- AES Operations --------------------------- */
- {CKM_AES_KEY_GEN, {16, 32, CKF_GENERATE}, PR_TRUE},
- {CKM_AES_ECB, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_AES_CBC, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_AES_MAC, {16, 32, CKF_SN_VR}, PR_TRUE},
- {CKM_AES_MAC_GENERAL, {16, 32, CKF_SN_VR}, PR_TRUE},
- {CKM_AES_CBC_PAD, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_AES_CTS, {16, 32, CKF_EN_DE}, PR_TRUE},
- {CKM_AES_CTR, {16, 32, CKF_EN_DE}, PR_TRUE},
- {CKM_AES_GCM, {16, 32, CKF_EN_DE}, PR_TRUE},
- /* ------------------------- Camellia Operations --------------------- */
- {CKM_CAMELLIA_KEY_GEN, {16, 32, CKF_GENERATE}, PR_TRUE},
- {CKM_CAMELLIA_ECB, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAMELLIA_CBC, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAMELLIA_MAC, {16, 32, CKF_SN_VR}, PR_TRUE},
- {CKM_CAMELLIA_MAC_GENERAL, {16, 32, CKF_SN_VR}, PR_TRUE},
- {CKM_CAMELLIA_CBC_PAD, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- /* ------------------------- SEED Operations --------------------------- */
- {CKM_SEED_KEY_GEN, {16, 16, CKF_GENERATE}, PR_TRUE},
- {CKM_SEED_ECB, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_SEED_CBC, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_SEED_MAC, {16, 16, CKF_SN_VR}, PR_TRUE},
- {CKM_SEED_MAC_GENERAL, {16, 16, CKF_SN_VR}, PR_TRUE},
- {CKM_SEED_CBC_PAD, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- /* ------------------------- Hashing Operations ----------------------- */
- {CKM_MD2, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_MD2_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_MD2_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_MD5, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_MD5_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_MD5_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA_1, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_SHA_1_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA_1_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA224, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_SHA224_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA224_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA256, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_SHA256_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA256_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA384, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_SHA384_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA384_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA512, {0, 0, CKF_DIGEST}, PR_FALSE},
- {CKM_SHA512_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA512_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE},
- {CKM_TLS_PRF_GENERAL, {0, 512, CKF_SN_VR}, PR_FALSE},
- /* ------------------------- HKDF Operations -------------------------- */
- {CKM_NSS_HKDF_SHA1, {1, 128, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_HKDF_SHA256, {1, 128, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_HKDF_SHA384, {1, 128, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_HKDF_SHA512, {1, 128, CKF_DERIVE}, PR_TRUE},
- /* ------------------------- CAST Operations --------------------------- */
-#ifdef NSS_SOFTOKEN_DOES_CAST
- /* Cast operations are not supported ( yet? ) */
- {CKM_CAST_KEY_GEN, {1, 8, CKF_GENERATE}, PR_TRUE},
- {CKM_CAST_ECB, {1, 8, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAST_CBC, {1, 8, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAST_MAC, {1, 8, CKF_SN_VR}, PR_TRUE},
- {CKM_CAST_MAC_GENERAL, {1, 8, CKF_SN_VR}, PR_TRUE},
- {CKM_CAST_CBC_PAD, {1, 8, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAST3_KEY_GEN, {1, 16, CKF_GENERATE}, PR_TRUE},
- {CKM_CAST3_ECB, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAST3_CBC, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAST3_MAC, {1, 16, CKF_SN_VR}, PR_TRUE},
- {CKM_CAST3_MAC_GENERAL, {1, 16, CKF_SN_VR}, PR_TRUE},
- {CKM_CAST3_CBC_PAD, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAST5_KEY_GEN, {1, 16, CKF_GENERATE}, PR_TRUE},
- {CKM_CAST5_ECB, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAST5_CBC, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_CAST5_MAC, {1, 16, CKF_SN_VR}, PR_TRUE},
- {CKM_CAST5_MAC_GENERAL, {1, 16, CKF_SN_VR}, PR_TRUE},
- {CKM_CAST5_CBC_PAD, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
-#endif
-#if NSS_SOFTOKEN_DOES_RC5
- /* ------------------------- RC5 Operations --------------------------- */
- {CKM_RC5_KEY_GEN, {1, 32, CKF_GENERATE}, PR_TRUE},
- {CKM_RC5_ECB, {1, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_RC5_CBC, {1, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_RC5_MAC, {1, 32, CKF_SN_VR}, PR_TRUE},
- {CKM_RC5_MAC_GENERAL, {1, 32, CKF_SN_VR}, PR_TRUE},
- {CKM_RC5_CBC_PAD, {1, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
-#endif
-#ifdef NSS_SOFTOKEN_DOES_IDEA
- /* ------------------------- IDEA Operations -------------------------- */
- {CKM_IDEA_KEY_GEN, {16, 16, CKF_GENERATE}, PR_TRUE},
- {CKM_IDEA_ECB, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_IDEA_CBC, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_IDEA_MAC, {16, 16, CKF_SN_VR}, PR_TRUE},
- {CKM_IDEA_MAC_GENERAL, {16, 16, CKF_SN_VR}, PR_TRUE},
- {CKM_IDEA_CBC_PAD, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
-#endif
- /* --------------------- Secret Key Operations ------------------------ */
- {CKM_GENERIC_SECRET_KEY_GEN, {1, 32, CKF_GENERATE}, PR_TRUE},
- {CKM_CONCATENATE_BASE_AND_KEY, {1, 32, CKF_GENERATE}, PR_FALSE},
- {CKM_CONCATENATE_BASE_AND_DATA, {1, 32, CKF_GENERATE}, PR_FALSE},
- {CKM_CONCATENATE_DATA_AND_BASE, {1, 32, CKF_GENERATE}, PR_FALSE},
- {CKM_XOR_BASE_AND_DATA, {1, 32, CKF_GENERATE}, PR_FALSE},
- {CKM_EXTRACT_KEY_FROM_KEY, {1, 32, CKF_DERIVE}, PR_FALSE},
- /* ---------------------- SSL Key Derivations ------------------------- */
- {CKM_SSL3_PRE_MASTER_KEY_GEN, {48, 48, CKF_GENERATE}, PR_FALSE},
- {CKM_SSL3_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_SSL3_MASTER_KEY_DERIVE_DH, {8, 128, CKF_DERIVE}, PR_FALSE},
- {CKM_SSL3_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_SSL3_MD5_MAC, { 0, 16, CKF_DERIVE}, PR_FALSE},
- {CKM_SSL3_SHA1_MAC, { 0, 20, CKF_DERIVE}, PR_FALSE},
- {CKM_MD5_KEY_DERIVATION, { 0, 16, CKF_DERIVE}, PR_FALSE},
- {CKM_MD2_KEY_DERIVATION, { 0, 16, CKF_DERIVE}, PR_FALSE},
- {CKM_SHA1_KEY_DERIVATION, { 0, 20, CKF_DERIVE}, PR_FALSE},
- {CKM_SHA224_KEY_DERIVATION, { 0, 28, CKF_DERIVE}, PR_FALSE},
- {CKM_SHA256_KEY_DERIVATION, { 0, 32, CKF_DERIVE}, PR_FALSE},
- {CKM_SHA384_KEY_DERIVATION, { 0, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_SHA512_KEY_DERIVATION, { 0, 64, CKF_DERIVE}, PR_FALSE},
- {CKM_TLS_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- {CKM_TLS_MASTER_KEY_DERIVE_DH, {8, 128, CKF_DERIVE}, PR_FALSE},
- {CKM_TLS_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE},
- /* ---------------------- PBE Key Derivations ------------------------ */
- {CKM_PBE_MD2_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE},
- {CKM_PBE_MD5_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE},
- /* ------------------ NETSCAPE PBE Key Derivations ------------------- */
- {CKM_NETSCAPE_PBE_SHA1_DES_CBC, { 8, 8, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_DES3_EDE_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_DES2_EDE_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_RC2_40_CBC, {40,40, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_RC2_128_CBC, {128,128, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_RC4_40, {40,40, CKF_GENERATE}, PR_TRUE},
- {CKM_PBE_SHA1_RC4_128, {128,128, CKF_GENERATE}, PR_TRUE},
- {CKM_PBA_SHA1_WITH_SHA1_HMAC, {20,20, CKF_GENERATE}, PR_TRUE},
- {CKM_PKCS5_PBKD2, {1,256, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, {20,20, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, {16,16, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, {16,16, CKF_GENERATE}, PR_TRUE},
- /* ------------------ AES Key Wrap (also encrypt) ------------------- */
- {CKM_NETSCAPE_AES_KEY_WRAP, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- {CKM_NETSCAPE_AES_KEY_WRAP_PAD, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE},
- /* --------------------------- J-PAKE -------------------------------- */
- {CKM_NSS_JPAKE_ROUND1_SHA1, {0, 0, CKF_GENERATE}, PR_TRUE},
- {CKM_NSS_JPAKE_ROUND1_SHA256, {0, 0, CKF_GENERATE}, PR_TRUE},
- {CKM_NSS_JPAKE_ROUND1_SHA384, {0, 0, CKF_GENERATE}, PR_TRUE},
- {CKM_NSS_JPAKE_ROUND1_SHA512, {0, 0, CKF_GENERATE}, PR_TRUE},
- {CKM_NSS_JPAKE_ROUND2_SHA1, {0, 0, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_JPAKE_ROUND2_SHA256, {0, 0, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_JPAKE_ROUND2_SHA384, {0, 0, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_JPAKE_ROUND2_SHA512, {0, 0, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_JPAKE_FINAL_SHA1, {0, 0, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_JPAKE_FINAL_SHA256, {0, 0, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_JPAKE_FINAL_SHA384, {0, 0, CKF_DERIVE}, PR_TRUE},
- {CKM_NSS_JPAKE_FINAL_SHA512, {0, 0, CKF_DERIVE}, PR_TRUE},
- /* -------------------- Constant Time TLS MACs ----------------------- */
- {CKM_NSS_HMAC_CONSTANT_TIME, {0, 0, CKF_DIGEST}, PR_TRUE},
- {CKM_NSS_SSL3_MAC_CONSTANT_TIME, {0, 0, CKF_DIGEST}, PR_TRUE}
-};
-static const CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
-
-/* sigh global so fipstokn can read it */
-PRBool nsc_init = PR_FALSE;
-
-#if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED)
-
-#include <pthread.h>
-
-static void ForkedChild(void)
-{
- if (nsc_init || nsf_init) {
- forked = PR_TRUE;
- }
-}
-
-#endif
-
-static char *
-sftk_setStringName(const char *inString, char *buffer, int buffer_length, PRBool nullTerminate)
-{
- int full_length, string_length;
-
- full_length = nullTerminate ? buffer_length -1 : buffer_length;
- string_length = PORT_Strlen(inString);
- /*
- * shorten the string, respecting utf8 encoding
- * to do so, we work backward from the end
- * bytes looking from the end are either:
- * - ascii [0x00,0x7f]
- * - the [2-n]th byte of a multibyte sequence
- * [0x3F,0xBF], i.e, most significant 2 bits are '10'
- * - the first byte of a multibyte sequence [0xC0,0xFD],
- * i.e, most significant 2 bits are '11'
- *
- * When the string is too long, we lop off any trailing '10' bytes,
- * if any. When these are all eliminated we lop off
- * one additional byte. Thus if we lopped any '10'
- * we'll be lopping a '11' byte (the first byte of the multibyte sequence),
- * otherwise we're lopping off an ascii character.
- *
- * To test for '10' bytes, we first AND it with
- * 11000000 (0xc0) so that we get 10000000 (0x80) if and only if
- * the byte starts with 10. We test for equality.
- */
- while ( string_length > full_length ) {
- /* need to shorten */
- while ( string_length > 0 &&
- ((inString[string_length-1]&(char)0xc0) == (char)0x80)) {
- /* lop off '10' byte */
- string_length--;
- }
- /*
- * test string_length in case bad data is received
- * and string consisted of all '10' bytes,
- * avoiding any infinite loop
- */
- if ( string_length ) {
- /* remove either '11' byte or an asci byte */
- string_length--;
- }
- }
- PORT_Memset(buffer,' ',full_length);
- if (nullTerminate) {
- buffer[full_length] = 0;
- }
- PORT_Memcpy(buffer,inString,string_length);
- return buffer;
-}
-/*
- * Configuration utils
- */
-static CK_RV
-sftk_configure(const char *man, const char *libdes)
-{
-
- /* make sure the internationalization was done correctly... */
- if (man) {
- manufacturerID = sftk_setStringName(man,manufacturerID_space,
- sizeof(manufacturerID_space), PR_TRUE);
- }
- if (libdes) {
- libraryDescription = sftk_setStringName(libdes,
- libraryDescription_space, sizeof(libraryDescription_space),
- PR_TRUE);
- }
-
- return CKR_OK;
-}
-
-/*
- * ******************** Password Utilities *******************************
- */
-
-/*
- * see if the key DB password is enabled
- */
-static PRBool
-sftk_hasNullPassword(SFTKSlot *slot, SFTKDBHandle *keydb)
-{
- PRBool pwenabled;
-
- pwenabled = PR_FALSE;
- if (sftkdb_HasPasswordSet(keydb) == SECSuccess) {
- PRBool tokenRemoved = PR_FALSE;
- SECStatus rv = sftkdb_CheckPassword(keydb, "", &tokenRemoved);
- if (tokenRemoved) {
- sftk_CloseAllSessions(slot, PR_FALSE);
- }
- return (rv == SECSuccess);
- }
-
- return pwenabled;
-}
-
-/*
- * ******************** Object Creation Utilities ***************************
- */
-
-
-/* Make sure a given attribute exists. If it doesn't, initialize it to
- * value and len
- */
-CK_RV
-sftk_defaultAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len)
-{
- if ( !sftk_hasAttribute(object, type)) {
- return sftk_AddAttributeType(object,type,value,len);
- }
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Data Object
- */
-static CK_RV
-sftk_handleDataObject(SFTKSession *session,SFTKObject *object)
-{
- CK_RV crv;
-
- /* first reject private and token data objects */
- if (sftk_isTrue(object,CKA_PRIVATE) || sftk_isTrue(object,CKA_TOKEN)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* now just verify the required date fields */
- crv = sftk_defaultAttribute(object,CKA_APPLICATION,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_VALUE,NULL,0);
- if (crv != CKR_OK) return crv;
-
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Certificate Object
- */
-static CK_RV
-sftk_handleCertObject(SFTKSession *session,SFTKObject *object)
-{
- CK_CERTIFICATE_TYPE type;
- SFTKAttribute *attribute;
- CK_RV crv;
-
- /* certificates must have a type */
- if ( !sftk_hasAttribute(object,CKA_CERTIFICATE_TYPE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* we can't store any certs private */
- if (sftk_isTrue(object,CKA_PRIVATE)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* We only support X.509 Certs for now */
- attribute = sftk_FindAttribute(object,CKA_CERTIFICATE_TYPE);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- type = *(CK_CERTIFICATE_TYPE *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
-
- if (type != CKC_X_509) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* X.509 Certificate */
-
- /* make sure we have a cert */
- if ( !sftk_hasAttribute(object,CKA_VALUE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* in PKCS #11, Subject is a required field */
- if ( !sftk_hasAttribute(object,CKA_SUBJECT) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* in PKCS #11, Issuer is a required field */
- if ( !sftk_hasAttribute(object,CKA_ISSUER) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* in PKCS #11, Serial is a required field */
- if ( !sftk_hasAttribute(object,CKA_SERIAL_NUMBER) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* add it to the object */
- object->objectInfo = NULL;
- object->infoFree = (SFTKFree) NULL;
-
- /* now just verify the required date fields */
- crv = sftk_defaultAttribute(object, CKA_ID, NULL, 0);
- if (crv != CKR_OK) { return crv; }
-
- if (sftk_isTrue(object,CKA_TOKEN)) {
- SFTKSlot *slot = session->slot;
- SFTKDBHandle *certHandle = sftk_getCertDB(slot);
-
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
- }
-
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Trust Object
- */
-static CK_RV
-sftk_handleTrustObject(SFTKSession *session,SFTKObject *object)
-{
- /* we can't store any certs private */
- if (sftk_isTrue(object,CKA_PRIVATE)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* certificates must have a type */
- if ( !sftk_hasAttribute(object,CKA_ISSUER) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !sftk_hasAttribute(object,CKA_SERIAL_NUMBER) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !sftk_hasAttribute(object,CKA_CERT_SHA1_HASH) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !sftk_hasAttribute(object,CKA_CERT_MD5_HASH) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- if (sftk_isTrue(object,CKA_TOKEN)) {
- SFTKSlot *slot = session->slot;
- SFTKDBHandle *certHandle = sftk_getCertDB(slot);
- CK_RV crv;
-
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
- }
-
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Trust Object
- */
-static CK_RV
-sftk_handleSMimeObject(SFTKSession *session,SFTKObject *object)
-{
-
- /* we can't store any certs private */
- if (sftk_isTrue(object,CKA_PRIVATE)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* certificates must have a type */
- if ( !sftk_hasAttribute(object,CKA_SUBJECT) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !sftk_hasAttribute(object,CKA_NETSCAPE_EMAIL) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- if (sftk_isTrue(object,CKA_TOKEN)) {
- SFTKSlot *slot = session->slot;
- SFTKDBHandle *certHandle;
- CK_RV crv;
-
- PORT_Assert(slot);
- if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- certHandle = sftk_getCertDB(slot);
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
- }
-
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Trust Object
- */
-static CK_RV
-sftk_handleCrlObject(SFTKSession *session,SFTKObject *object)
-{
-
- /* we can't store any certs private */
- if (sftk_isTrue(object,CKA_PRIVATE)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* certificates must have a type */
- if ( !sftk_hasAttribute(object,CKA_SUBJECT) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !sftk_hasAttribute(object,CKA_VALUE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- if (sftk_isTrue(object,CKA_TOKEN)) {
- SFTKSlot *slot = session->slot;
- SFTKDBHandle *certHandle = sftk_getCertDB(slot);
- CK_RV crv;
-
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
- }
-
- return CKR_OK;
-}
-
-/*
- * check the consistancy and initialize a Public Key Object
- */
-static CK_RV
-sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
- CK_KEY_TYPE key_type)
-{
- CK_BBOOL encrypt = CK_TRUE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL wrap = CK_TRUE;
- CK_BBOOL derive = CK_FALSE;
- CK_BBOOL verify = CK_TRUE;
- CK_RV crv;
-
- switch (key_type) {
- case CKK_RSA:
- crv = sftk_ConstrainAttribute(object, CKA_MODULUS,
- RSA_MIN_MODULUS_BITS, 0, 0);
- if (crv != CKR_OK) {
- return crv;
- }
- crv = sftk_ConstrainAttribute(object, CKA_PUBLIC_EXPONENT, 2, 0, 0);
- if (crv != CKR_OK) {
- return crv;
- }
- break;
- case CKK_DSA:
- crv = sftk_ConstrainAttribute(object, CKA_SUBPRIME,
- DSA_MIN_Q_BITS, DSA_MAX_Q_BITS, 0);
- if (crv != CKR_OK) {
- return crv;
- }
- crv = sftk_ConstrainAttribute(object, CKA_PRIME,
- DSA_MIN_P_BITS, DSA_MAX_P_BITS, 64);
- if (crv != CKR_OK) {
- return crv;
- }
- crv = sftk_ConstrainAttribute(object, CKA_BASE, 2, DSA_MAX_P_BITS, 0);
- if (crv != CKR_OK) {
- return crv;
- }
- crv = sftk_ConstrainAttribute(object, CKA_VALUE, 2, DSA_MAX_P_BITS, 0);
- if (crv != CKR_OK) {
- return crv;
- }
- encrypt = CK_FALSE;
- recover = CK_FALSE;
- wrap = CK_FALSE;
- break;
- case CKK_DH:
- crv = sftk_ConstrainAttribute(object, CKA_PRIME,
- DH_MIN_P_BITS, DH_MAX_P_BITS, 0);
- if (crv != CKR_OK) {
- return crv;
- }
- crv = sftk_ConstrainAttribute(object, CKA_BASE, 2, DH_MAX_P_BITS, 0);
- if (crv != CKR_OK) {
- return crv;
- }
- crv = sftk_ConstrainAttribute(object, CKA_VALUE, 2, DH_MAX_P_BITS, 0);
- if (crv != CKR_OK) {
- return crv;
- }
- verify = CK_FALSE;
- derive = CK_TRUE;
- encrypt = CK_FALSE;
- recover = CK_FALSE;
- wrap = CK_FALSE;
- break;
-#ifdef NSS_ENABLE_ECC
- case CKK_EC:
- if ( !sftk_hasAttribute(object, CKA_EC_PARAMS)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !sftk_hasAttribute(object, CKA_EC_POINT)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- derive = CK_TRUE; /* for ECDH */
- verify = CK_TRUE; /* for ECDSA */
- encrypt = CK_FALSE;
- recover = CK_FALSE;
- wrap = CK_FALSE;
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- /* make sure the required fields exist */
- crv = sftk_defaultAttribute(object,CKA_SUBJECT,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_ENCRYPT,&encrypt,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_VERIFY,&verify,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_VERIFY_RECOVER,
- &recover,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_WRAP,&wrap,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- object->objectInfo = sftk_GetPubKey(object,key_type, &crv);
- if (object->objectInfo == NULL) {
- return crv;
- }
- object->infoFree = (SFTKFree) nsslowkey_DestroyPublicKey;
-
- if (sftk_isTrue(object,CKA_TOKEN)) {
- SFTKSlot *slot = session->slot;
- SFTKDBHandle *certHandle = sftk_getCertDB(slot);
-
- if (certHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- crv = sftkdb_write(certHandle, object, &object->handle);
- sftk_freeDB(certHandle);
- return crv;
- }
-
- return CKR_OK;
-}
-
-static NSSLOWKEYPrivateKey *
-sftk_mkPrivKey(SFTKObject *object,CK_KEY_TYPE key, CK_RV *rvp);
-
-static SECStatus
-sftk_fillRSAPrivateKey(SFTKObject *object);
-
-/*
- * check the consistancy and initialize a Private Key Object
- */
-static CK_RV
-sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE key_type)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL encrypt = CK_TRUE;
- CK_BBOOL sign = CK_FALSE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL wrap = CK_TRUE;
- CK_BBOOL derive = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- PRBool createObjectInfo = PR_TRUE;
- int missing_rsa_mod_component = 0;
- int missing_rsa_exp_component = 0;
- int missing_rsa_crt_component = 0;
-
- SECItem mod;
- CK_RV crv;
-
- switch (key_type) {
- case CKK_RSA:
- if ( !sftk_hasAttribute(object, CKA_MODULUS)) {
- missing_rsa_mod_component++;
- }
- if ( !sftk_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {
- missing_rsa_exp_component++;
- }
- if ( !sftk_hasAttribute(object, CKA_PRIVATE_EXPONENT)) {
- missing_rsa_exp_component++;
- }
- if ( !sftk_hasAttribute(object, CKA_PRIME_1)) {
- missing_rsa_mod_component++;
- }
- if ( !sftk_hasAttribute(object, CKA_PRIME_2)) {
- missing_rsa_mod_component++;
- }
- if ( !sftk_hasAttribute(object, CKA_EXPONENT_1)) {
- missing_rsa_crt_component++;
- }
- if ( !sftk_hasAttribute(object, CKA_EXPONENT_2)) {
- missing_rsa_crt_component++;
- }
- if ( !sftk_hasAttribute(object, CKA_COEFFICIENT)) {
- missing_rsa_crt_component++;
- }
- if (missing_rsa_mod_component || missing_rsa_exp_component ||
- missing_rsa_crt_component) {
- /* we are missing a component, see if we have enough to rebuild
- * the rest */
- int have_exp = 2- missing_rsa_exp_component;
- int have_component = 5-
- (missing_rsa_exp_component+missing_rsa_mod_component);
- SECStatus rv;
-
- if ((have_exp == 0) || (have_component < 3)) {
- /* nope, not enough to reconstruct the private key */
- return CKR_TEMPLATE_INCOMPLETE;
- }
- /*fill in the missing parameters */
- rv = sftk_fillRSAPrivateKey(object);
- if (rv != SECSuccess) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- }
-
- /* make sure Netscape DB attribute is set correctly */
- crv = sftk_Attribute2SSecItem(NULL, &mod, object, CKA_MODULUS);
- if (crv != CKR_OK) return crv;
- crv = sftk_forceAttribute(object, CKA_NETSCAPE_DB,
- sftk_item_expand(&mod));
- if (mod.data) PORT_Free(mod.data);
- if (crv != CKR_OK) return crv;
-
- sign = CK_TRUE;
- derive = CK_FALSE;
- break;
- case CKK_DSA:
- if ( !sftk_hasAttribute(object, CKA_SUBPRIME)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- sign = CK_TRUE;
- derive = CK_FALSE;
- /* fall through */
- case CKK_DH:
- if ( !sftk_hasAttribute(object, CKA_PRIME)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !sftk_hasAttribute(object, CKA_BASE)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !sftk_hasAttribute(object, CKA_VALUE)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- encrypt = CK_FALSE;
- recover = CK_FALSE;
- wrap = CK_FALSE;
- break;
-#ifdef NSS_ENABLE_ECC
- case CKK_EC:
- if ( !sftk_hasAttribute(object, CKA_EC_PARAMS)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if ( !sftk_hasAttribute(object, CKA_VALUE)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- encrypt = CK_FALSE;
- sign = CK_TRUE;
- recover = CK_FALSE;
- wrap = CK_FALSE;
- break;
-#endif /* NSS_ENABLE_ECC */
- case CKK_NSS_JPAKE_ROUND1:
- if (!sftk_hasAttribute(object, CKA_PRIME ||
- !sftk_hasAttribute(object, CKA_SUBPRIME) ||
- !sftk_hasAttribute(object, CKA_BASE))) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- /* fall through */
- case CKK_NSS_JPAKE_ROUND2:
- /* CKA_NSS_JPAKE_SIGNERID and CKA_NSS_JPAKE_PEERID are checked in
- the J-PAKE code. */
- encrypt = sign = recover = wrap = CK_FALSE;
- derive = CK_TRUE;
- createObjectInfo = PR_FALSE;
- break;
- default:
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- crv = sftk_defaultAttribute(object,CKA_SUBJECT,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_DECRYPT,&encrypt,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_SIGN,&sign,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_SIGN_RECOVER,&recover,
- sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_UNWRAP,&wrap,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- /* the next two bits get modified only in the key gen and token cases */
- crv = sftk_forceAttribute(object,CKA_ALWAYS_SENSITIVE,
- &ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_forceAttribute(object,CKA_NEVER_EXTRACTABLE,
- &ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- /* should we check the non-token RSA private keys? */
-
- if (sftk_isTrue(object,CKA_TOKEN)) {
- SFTKSlot *slot = session->slot;
- SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
- CK_RV crv;
-
- if (keyHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- crv = sftkdb_write(keyHandle, object, &object->handle);
- sftk_freeDB(keyHandle);
- return crv;
- } else if (createObjectInfo) {
- object->objectInfo = sftk_mkPrivKey(object,key_type,&crv);
- if (object->objectInfo == NULL) return crv;
- object->infoFree = (SFTKFree) nsslowkey_DestroyPrivateKey;
- }
- return CKR_OK;
-}
-
-/* forward declare the DES formating function for handleSecretKey */
-void sftk_FormatDESKey(unsigned char *key, int length);
-
-/* Validate secret key data, and set defaults */
-static CK_RV
-validateSecretKey(SFTKSession *session, SFTKObject *object,
- CK_KEY_TYPE key_type, PRBool isFIPS)
-{
- CK_RV crv;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- SFTKAttribute *attribute = NULL;
- unsigned long requiredLen;
-
- crv = sftk_defaultAttribute(object,CKA_SENSITIVE,
- isFIPS?&cktrue:&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_EXTRACTABLE,
- &cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_ENCRYPT,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_DECRYPT,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_SIGN,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_VERIFY,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_WRAP,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_UNWRAP,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- if ( !sftk_hasAttribute(object, CKA_VALUE)) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- /* the next two bits get modified only in the key gen and token cases */
- crv = sftk_forceAttribute(object,CKA_ALWAYS_SENSITIVE,
- &ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_forceAttribute(object,CKA_NEVER_EXTRACTABLE,
- &ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- /* some types of keys have a value length */
- crv = CKR_OK;
- switch (key_type) {
- /* force CKA_VALUE_LEN to be set */
- case CKK_GENERIC_SECRET:
- case CKK_RC2:
- case CKK_RC4:
-#if NSS_SOFTOKEN_DOES_RC5
- case CKK_RC5:
-#endif
-#ifdef NSS_SOFTOKEN_DOES_CAST
- case CKK_CAST:
- case CKK_CAST3:
- case CKK_CAST5:
-#endif
-#if NSS_SOFTOKEN_DOES_IDEA
- case CKK_IDEA:
-#endif
- attribute = sftk_FindAttribute(object,CKA_VALUE);
- /* shouldn't happen */
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- crv = sftk_forceAttribute(object, CKA_VALUE_LEN,
- &attribute->attrib.ulValueLen, sizeof(CK_ULONG));
- sftk_FreeAttribute(attribute);
- break;
- /* force the value to have the correct parity */
- case CKK_DES:
- case CKK_DES2:
- case CKK_DES3:
- case CKK_CDMF:
- attribute = sftk_FindAttribute(object,CKA_VALUE);
- /* shouldn't happen */
- if (attribute == NULL)
- return CKR_TEMPLATE_INCOMPLETE;
- requiredLen = sftk_MapKeySize(key_type);
- if (attribute->attrib.ulValueLen != requiredLen) {
- sftk_FreeAttribute(attribute);
- return CKR_KEY_SIZE_RANGE;
- }
- sftk_FormatDESKey((unsigned char*)attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- sftk_FreeAttribute(attribute);
- break;
- case CKK_AES:
- attribute = sftk_FindAttribute(object,CKA_VALUE);
- /* shouldn't happen */
- if (attribute == NULL)
- return CKR_TEMPLATE_INCOMPLETE;
- if (attribute->attrib.ulValueLen != 16 &&
- attribute->attrib.ulValueLen != 24 &&
- attribute->attrib.ulValueLen != 32) {
- sftk_FreeAttribute(attribute);
- return CKR_KEY_SIZE_RANGE;
- }
- crv = sftk_forceAttribute(object, CKA_VALUE_LEN,
- &attribute->attrib.ulValueLen, sizeof(CK_ULONG));
- sftk_FreeAttribute(attribute);
- break;
- default:
- break;
- }
-
- return crv;
-}
-
-/*
- * check the consistancy and initialize a Secret Key Object
- */
-static CK_RV
-sftk_handleSecretKeyObject(SFTKSession *session,SFTKObject *object,
- CK_KEY_TYPE key_type, PRBool isFIPS)
-{
- CK_RV crv;
-
- /* First validate and set defaults */
- crv = validateSecretKey(session, object, key_type, isFIPS);
- if (crv != CKR_OK) goto loser;
-
- /* If the object is a TOKEN object, store in the database */
- if (sftk_isTrue(object,CKA_TOKEN)) {
- SFTKSlot *slot = session->slot;
- SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
- CK_RV crv;
-
- if (keyHandle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- crv = sftkdb_write(keyHandle, object, &object->handle);
- sftk_freeDB(keyHandle);
- return crv;
- }
-
-loser:
-
- return crv;
-}
-
-/*
- * check the consistancy and initialize a Key Object
- */
-static CK_RV
-sftk_handleKeyObject(SFTKSession *session, SFTKObject *object)
-{
- SFTKAttribute *attribute;
- CK_KEY_TYPE key_type;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_RV crv;
-
- /* verify the required fields */
- if ( !sftk_hasAttribute(object,CKA_KEY_TYPE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* now verify the common fields */
- crv = sftk_defaultAttribute(object,CKA_ID,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_START_DATE,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_END_DATE,NULL,0);
- if (crv != CKR_OK) return crv;
- /* CKA_DERIVE is common to all keys, but it's default value is
- * key dependent */
- crv = sftk_defaultAttribute(object,CKA_LOCAL,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- /* get the key type */
- attribute = sftk_FindAttribute(object,CKA_KEY_TYPE);
- if (!attribute) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
-
- switch (object->objclass) {
- case CKO_PUBLIC_KEY:
- return sftk_handlePublicKeyObject(session,object,key_type);
- case CKO_PRIVATE_KEY:
- return sftk_handlePrivateKeyObject(session,object,key_type);
- case CKO_SECRET_KEY:
- /* make sure the required fields exist */
- return sftk_handleSecretKeyObject(session,object,key_type,
- (PRBool)(session->slot->slotID == FIPS_SLOT_ID));
- default:
- break;
- }
- return CKR_ATTRIBUTE_VALUE_INVALID;
-}
-
-/*
- * check the consistancy and Verify a DSA Parameter Object
- */
-static CK_RV
-sftk_handleDSAParameterObject(SFTKSession *session, SFTKObject *object)
-{
- SFTKAttribute *primeAttr = NULL;
- SFTKAttribute *subPrimeAttr = NULL;
- SFTKAttribute *baseAttr = NULL;
- SFTKAttribute *seedAttr = NULL;
- SFTKAttribute *hAttr = NULL;
- SFTKAttribute *attribute;
- CK_RV crv = CKR_TEMPLATE_INCOMPLETE;
- PQGParams params;
- PQGVerify vfy, *verify = NULL;
- SECStatus result,rv;
- /* This bool keeps track of whether or not we need verify parameters.
- * If a P, Q and G or supplied, we dont' need verify parameters, as we
- * have PQ and G.
- * - If G is not supplied, the presumption is that we want to
- * verify P and Q only.
- * - If counter is supplied, it is presumed we want to verify PQ because
- * the counter is only used in verification.
- * - If H is supplied, is is presumed we want to verify G because H is
- * only used to verify G.
- * - Any verification step must have the SEED (counter or H could be
- * missing depending on exactly what we want to verify). If SEED is supplied,
- * the code just goes ahead and runs verify (other errors are parameter
- * errors are detected by the PQG_VerifyParams function). If SEED is not
- * supplied, but we determined that we are trying to verify (because needVfy
- * is set, go ahead and return CKR_TEMPLATE_INCOMPLETE.
- */
- PRBool needVfy = PR_FALSE;
-
- primeAttr = sftk_FindAttribute(object,CKA_PRIME);
- if (primeAttr == NULL) goto loser;
- params.prime.data = primeAttr->attrib.pValue;
- params.prime.len = primeAttr->attrib.ulValueLen;
-
- subPrimeAttr = sftk_FindAttribute(object,CKA_SUBPRIME);
- if (subPrimeAttr == NULL) goto loser;
- params.subPrime.data = subPrimeAttr->attrib.pValue;
- params.subPrime.len = subPrimeAttr->attrib.ulValueLen;
-
- baseAttr = sftk_FindAttribute(object,CKA_BASE);
- if (baseAttr != NULL) {
- params.base.data = baseAttr->attrib.pValue;
- params.base.len = baseAttr->attrib.ulValueLen;
- } else {
- params.base.data = NULL;
- params.base.len = 0;
- needVfy = PR_TRUE; /* presumably only including PQ so we can verify
- * them. */
- }
-
- attribute = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_COUNTER);
- if (attribute != NULL) {
- vfy.counter = *(CK_ULONG *) attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
- needVfy = PR_TRUE; /* included a count so we can verify PQ */
- } else {
- vfy.counter = -1;
- }
-
- hAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_H);
- if (hAttr != NULL) {
- vfy.h.data = hAttr->attrib.pValue;
- vfy.h.len = hAttr->attrib.ulValueLen;
- needVfy = PR_TRUE; /* included H so we can verify G */
- } else {
- vfy.h.data = NULL;
- vfy.h.len = 0;
- }
- seedAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_SEED);
- if (seedAttr != NULL) {
- vfy.seed.data = seedAttr->attrib.pValue;
- vfy.seed.len = seedAttr->attrib.ulValueLen;
-
- verify = &vfy;
- } else if (needVfy) {
- goto loser; /* Verify always needs seed, if we need verify and not seed
- * then fail */
- }
-
- crv = CKR_FUNCTION_FAILED;
- rv = PQG_VerifyParams(&params,verify,&result);
- if (rv == SECSuccess) {
- crv = (result== SECSuccess) ? CKR_OK : CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
-loser:
- if (hAttr) sftk_FreeAttribute(hAttr);
- if (seedAttr) sftk_FreeAttribute(seedAttr);
- if (baseAttr) sftk_FreeAttribute(baseAttr);
- if (subPrimeAttr) sftk_FreeAttribute(subPrimeAttr);
- if (primeAttr) sftk_FreeAttribute(primeAttr);
-
- return crv;
-}
-
-/*
- * check the consistancy and initialize a Key Parameter Object
- */
-static CK_RV
-sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object)
-{
- SFTKAttribute *attribute;
- CK_KEY_TYPE key_type;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_RV crv;
-
- /* verify the required fields */
- if ( !sftk_hasAttribute(object,CKA_KEY_TYPE) ) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
-
- /* now verify the common fields */
- crv = sftk_defaultAttribute(object,CKA_LOCAL,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- /* get the key type */
- attribute = sftk_FindAttribute(object,CKA_KEY_TYPE);
- if (!attribute) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
-
- switch (key_type) {
- case CKK_DSA:
- return sftk_handleDSAParameterObject(session,object);
-
- default:
- break;
- }
- return CKR_KEY_TYPE_INCONSISTENT;
-}
-
-/*
- * Handle Object does all the object consistancy checks, automatic attribute
- * generation, attribute defaulting, etc. If handleObject succeeds, the object
- * will be assigned an object handle, and the object installed in the session
- * or stored in the DB.
- */
-CK_RV
-sftk_handleObject(SFTKObject *object, SFTKSession *session)
-{
- SFTKSlot *slot = session->slot;
- SFTKAttribute *attribute;
- SFTKObject *duplicateObject = NULL;
- CK_OBJECT_HANDLE handle;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL cktrue = CK_TRUE;
- CK_RV crv;
-
- /* make sure all the base object types are defined. If not set the
- * defaults */
- crv = sftk_defaultAttribute(object,CKA_TOKEN,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_PRIVATE,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_LABEL,NULL,0);
- if (crv != CKR_OK) return crv;
- crv = sftk_defaultAttribute(object,CKA_MODIFIABLE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) return crv;
-
- /* don't create a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (sftk_isTrue(object,CKA_PRIVATE))) {
- return CKR_USER_NOT_LOGGED_IN;
- }
-
-
- if (((session->info.flags & CKF_RW_SESSION) == 0) &&
- (sftk_isTrue(object,CKA_TOKEN))) {
- return CKR_SESSION_READ_ONLY;
- }
-
- /* Assign a unique SESSION object handle to every new object,
- * whether it is a session object or a token object.
- * At this point, all new objects are structured as session objects.
- * Objects with the CKA_TOKEN attribute true will be turned into
- * token objects and will have a token object handle assigned to
- * them by a call to sftk_mkHandle in the handler for each object
- * class, invoked below.
- *
- * It may be helpful to note/remember that
- * sftk_narrowToXxxObject uses sftk_isToken,
- * sftk_isToken examines the sign bit of the object's handle, but
- * sftk_isTrue(...,CKA_TOKEN) examines the CKA_TOKEN attribute.
- */
- do {
- PRUint32 wrappedAround;
-
- duplicateObject = NULL;
- PZ_Lock(slot->objectLock);
- wrappedAround = slot->sessionObjectHandleCount & SFTK_TOKEN_MASK;
- handle = slot->sessionObjectHandleCount & ~SFTK_TOKEN_MASK;
- if (!handle) /* don't allow zero handle */
- handle = minSessionObjectHandle;
- slot->sessionObjectHandleCount = (handle + 1U) | wrappedAround;
- /* Is there already a session object with this handle? */
- if (wrappedAround) {
- sftkqueue_find(duplicateObject, handle, slot->sessObjHashTable, \
- slot->sessObjHashSize);
- }
- PZ_Unlock(slot->objectLock);
- } while (duplicateObject != NULL);
- object->handle = handle;
-
- /* get the object class */
- attribute = sftk_FindAttribute(object,CKA_CLASS);
- if (attribute == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- object->objclass = *(CK_OBJECT_CLASS *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
-
- /* Now handle the specific object class.
- * At this point, all objects are session objects, and the session
- * number must be passed to the object class handlers.
- */
- switch (object->objclass) {
- case CKO_DATA:
- crv = sftk_handleDataObject(session,object);
- break;
- case CKO_CERTIFICATE:
- crv = sftk_handleCertObject(session,object);
- break;
- case CKO_NETSCAPE_TRUST:
- crv = sftk_handleTrustObject(session,object);
- break;
- case CKO_NETSCAPE_CRL:
- crv = sftk_handleCrlObject(session,object);
- break;
- case CKO_NETSCAPE_SMIME:
- crv = sftk_handleSMimeObject(session,object);
- break;
- case CKO_PRIVATE_KEY:
- case CKO_PUBLIC_KEY:
- case CKO_SECRET_KEY:
- crv = sftk_handleKeyObject(session,object);
- break;
- case CKO_KG_PARAMETERS:
- crv = sftk_handleKeyParameterObject(session,object);
- break;
- default:
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- break;
- }
-
- /* can't fail from here on out unless the pk_handlXXX functions have
- * failed the request */
- if (crv != CKR_OK) {
- return crv;
- }
-
- /* Now link the object into the slot and session structures.
- * If the object has a true CKA_TOKEN attribute, the above object
- * class handlers will have set the sign bit in the object handle,
- * causing the following test to be true.
- */
- if (sftk_isToken(object->handle)) {
- sftk_convertSessionToToken(object);
- } else {
- object->slot = slot;
- sftk_AddObject(session,object);
- }
-
- return CKR_OK;
-}
-
-/*
- * ******************** Public Key Utilities ***************************
- */
-/* Generate a low public key structure from an object */
-NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,CK_KEY_TYPE key_type,
- CK_RV *crvp)
-{
- NSSLOWKEYPublicKey *pubKey;
- PLArenaPool *arena;
- CK_RV crv;
-
- if (object->objclass != CKO_PUBLIC_KEY) {
- *crvp = CKR_KEY_TYPE_INCONSISTENT;
- return NULL;
- }
-
- if (sftk_isToken(object->handle)) {
-/* ferret out the token object handle */
- }
-
- /* If we already have a key, use it */
- if (object->objectInfo) {
- *crvp = CKR_OK;
- return (NSSLOWKEYPublicKey *)object->objectInfo;
- }
-
- /* allocate the structure */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- *crvp = CKR_HOST_MEMORY;
- return NULL;
- }
-
- pubKey = (NSSLOWKEYPublicKey *)
- PORT_ArenaAlloc(arena,sizeof(NSSLOWKEYPublicKey));
- if (pubKey == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- *crvp = CKR_HOST_MEMORY;
- return NULL;
- }
-
- /* fill in the structure */
- pubKey->arena = arena;
- switch (key_type) {
- case CKK_RSA:
- pubKey->keyType = NSSLOWKEYRSAKey;
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.rsa.modulus,
- object,CKA_MODULUS);
- if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.rsa.publicExponent,
- object,CKA_PUBLIC_EXPONENT);
- break;
- case CKK_DSA:
- pubKey->keyType = NSSLOWKEYDSAKey;
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dsa.params.prime,
- object,CKA_PRIME);
- if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dsa.params.subPrime,
- object,CKA_SUBPRIME);
- if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dsa.params.base,
- object,CKA_BASE);
- if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dsa.publicValue,
- object,CKA_VALUE);
- break;
- case CKK_DH:
- pubKey->keyType = NSSLOWKEYDHKey;
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dh.prime,
- object,CKA_PRIME);
- if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dh.base,
- object,CKA_BASE);
- if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dh.publicValue,
- object,CKA_VALUE);
- break;
-#ifdef NSS_ENABLE_ECC
- case CKK_EC:
- pubKey->keyType = NSSLOWKEYECKey;
- crv = sftk_Attribute2SSecItem(arena,
- &pubKey->u.ec.ecParams.DEREncoding,
- object,CKA_EC_PARAMS);
- if (crv != CKR_OK) break;
-
- /* Fill out the rest of the ecParams structure
- * based on the encoded params
- */
- if (EC_FillParams(arena, &pubKey->u.ec.ecParams.DEREncoding,
- &pubKey->u.ec.ecParams) != SECSuccess) {
- crv = CKR_DOMAIN_PARAMS_INVALID;
- break;
- }
-
- crv = sftk_Attribute2SSecItem(arena,&pubKey->u.ec.publicValue,
- object,CKA_EC_POINT);
- if (crv == CKR_OK) {
- int keyLen,curveLen;
-
- curveLen = (pubKey->u.ec.ecParams.fieldID.size +7)/8;
- keyLen = (2*curveLen)+1;
-
- /* special note: We can't just use the first byte to determine
- * between these 2 cases because both EC_POINT_FORM_UNCOMPRESSED
- * and SEC_ASN1_OCTET_STRING are 0x04 */
-
- /* handle the non-DER encoded case (UNCOMPRESSED only) */
- if (pubKey->u.ec.publicValue.data[0] == EC_POINT_FORM_UNCOMPRESSED
- && pubKey->u.ec.publicValue.len == keyLen) {
- break; /* key was not DER encoded, no need to unwrap */
- }
-
- /* if we ever support compressed, handle it here */
-
- /* handle the encoded case */
- if ((pubKey->u.ec.publicValue.data[0] == SEC_ASN1_OCTET_STRING)
- && pubKey->u.ec.publicValue.len > keyLen) {
- SECItem publicValue;
- SECStatus rv;
-
- rv = SEC_QuickDERDecodeItem(arena, &publicValue,
- SEC_ASN1_GET(SEC_OctetStringTemplate),
- &pubKey->u.ec.publicValue);
- /* nope, didn't decode correctly */
- if ((rv != SECSuccess)
- || (publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED)
- || (publicValue.len != keyLen)) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- break;
- }
- /* replace our previous with the decoded key */
- pubKey->u.ec.publicValue = publicValue;
- break;
- }
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- }
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- *crvp = crv;
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
-
- object->objectInfo = pubKey;
- object->infoFree = (SFTKFree) nsslowkey_DestroyPublicKey;
- return pubKey;
-}
-
-/* make a private key from a verified object */
-static NSSLOWKEYPrivateKey *
-sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
-{
- NSSLOWKEYPrivateKey *privKey;
- SFTKItemTemplate itemTemplate[SFTK_MAX_ITEM_TEMPLATE];
- int itemTemplateCount = 0;
- PLArenaPool *arena;
- CK_RV crv = CKR_OK;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- *crvp = CKR_HOST_MEMORY;
- return NULL;
- }
-
- privKey = (NSSLOWKEYPrivateKey *)
- PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey));
- if (privKey == NULL) {
- PORT_FreeArena(arena,PR_FALSE);
- *crvp = CKR_HOST_MEMORY;
- return NULL;
- }
-
- /* in future this would be a switch on key_type */
- privKey->arena = arena;
- switch (key_type) {
- case CKK_RSA:
- privKey->keyType = NSSLOWKEYRSAKey;
-
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.rsa.modulus,CKA_MODULUS);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.rsa.publicExponent, CKA_PUBLIC_EXPONENT);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.rsa.privateExponent, CKA_PRIVATE_EXPONENT);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.rsa.prime1, CKA_PRIME_1);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.rsa.prime2, CKA_PRIME_2);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.rsa.exponent1, CKA_EXPONENT_1);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.rsa.exponent2, CKA_EXPONENT_2);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.rsa.coefficient, CKA_COEFFICIENT);
- itemTemplateCount++;
- rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version,
- NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
- if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
- break;
-
- case CKK_DSA:
- privKey->keyType = NSSLOWKEYDSAKey;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.dsa.params.prime, CKA_PRIME);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.dsa.params.subPrime, CKA_SUBPRIME);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.dsa.params.base, CKA_BASE);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.dsa.privateValue, CKA_VALUE);
- itemTemplateCount++;
- /* privKey was zero'd so public value is already set to NULL, 0
- * if we don't set it explicitly */
- break;
-
- case CKK_DH:
- privKey->keyType = NSSLOWKEYDHKey;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.dh.prime, CKA_PRIME);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.dh.base, CKA_BASE);
- itemTemplateCount++;
- SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount,
- &privKey->u.dh.privateValue, CKA_VALUE);
- itemTemplateCount++;
- /* privKey was zero'd so public value is already set to NULL, 0
- * if we don't set it explicitly */
- break;
-
-#ifdef NSS_ENABLE_ECC
- case CKK_EC:
- privKey->keyType = NSSLOWKEYECKey;
- crv = sftk_Attribute2SSecItem(arena,
- &privKey->u.ec.ecParams.DEREncoding,
- object,CKA_EC_PARAMS);
- if (crv != CKR_OK) break;
-
- /* Fill out the rest of the ecParams structure
- * based on the encoded params
- */
- if (EC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding,
- &privKey->u.ec.ecParams) != SECSuccess) {
- crv = CKR_DOMAIN_PARAMS_INVALID;
- break;
- }
- crv = sftk_Attribute2SSecItem(arena,&privKey->u.ec.privateValue,
- object,CKA_VALUE);
- if (crv != CKR_OK) break;
-
- if (sftk_hasAttribute(object, CKA_NETSCAPE_DB)) {
- crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue,
- object, CKA_NETSCAPE_DB);
- if (crv != CKR_OK) break;
- /* privKey was zero'd so public value is already set to NULL, 0
- * if we don't set it explicitly */
- }
- rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version,
- NSSLOWKEY_EC_PRIVATE_KEY_VERSION);
- if (rv != SECSuccess) crv = CKR_HOST_MEMORY;
- break;
-#endif /* NSS_ENABLE_ECC */
-
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- if (crv == CKR_OK && itemTemplateCount != 0) {
- PORT_Assert(itemTemplateCount > 0);
- PORT_Assert(itemTemplateCount <= SFTK_MAX_ITEM_TEMPLATE);
- crv = sftk_MultipleAttribute2SecItem(arena, object, itemTemplate,
- itemTemplateCount);
- }
- *crvp = crv;
- if (crv != CKR_OK) {
- PORT_FreeArena(arena,PR_FALSE);
- return NULL;
- }
- return privKey;
-}
-
-/*
- * we have a partial rsa private key, fill in the rest
- */
-static SECStatus
-sftk_fillRSAPrivateKey(SFTKObject *object)
-{
- RSAPrivateKey tmpKey = { 0 };
- SFTKAttribute *modulus = NULL;
- SFTKAttribute *prime1 = NULL;
- SFTKAttribute *prime2 = NULL;
- SFTKAttribute *privateExponent = NULL;
- SFTKAttribute *publicExponent = NULL;
- SECStatus rv;
- CK_RV crv;
-
- /* first fill in the components that we have. Populate only uses
- * the non-crt components, so only fill those in */
- tmpKey.arena = NULL;
- modulus = sftk_FindAttribute(object, CKA_MODULUS);
- if (modulus) {
- tmpKey.modulus.data = modulus->attrib.pValue;
- tmpKey.modulus.len = modulus->attrib.ulValueLen;
- }
- prime1 = sftk_FindAttribute(object, CKA_PRIME_1);
- if (prime1) {
- tmpKey.prime1.data = prime1->attrib.pValue;
- tmpKey.prime1.len = prime1->attrib.ulValueLen;
- }
- prime2 = sftk_FindAttribute(object, CKA_PRIME_2);
- if (prime2) {
- tmpKey.prime2.data = prime2->attrib.pValue;
- tmpKey.prime2.len = prime2->attrib.ulValueLen;
- }
- privateExponent = sftk_FindAttribute(object, CKA_PRIVATE_EXPONENT);
- if (privateExponent) {
- tmpKey.privateExponent.data = privateExponent->attrib.pValue;
- tmpKey.privateExponent.len = privateExponent->attrib.ulValueLen;
- }
- publicExponent = sftk_FindAttribute(object, CKA_PUBLIC_EXPONENT);
- if (publicExponent) {
- tmpKey.publicExponent.data = publicExponent->attrib.pValue;
- tmpKey.publicExponent.len = publicExponent->attrib.ulValueLen;
- }
-
- /*
- * populate requires one exponent plus 2 other components to work.
- * we expected our caller to check that first. If that didn't happen,
- * populate will simply return an error here.
- */
- rv = RSA_PopulatePrivateKey(&tmpKey);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* now that we have a fully populated key, set all our attribute values */
- rv = SECFailure;
- crv = sftk_forceAttribute(object,CKA_MODULUS,
- sftk_item_expand(&tmpKey.modulus));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(object,CKA_PUBLIC_EXPONENT,
- sftk_item_expand(&tmpKey.publicExponent));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(object,CKA_PRIVATE_EXPONENT,
- sftk_item_expand(&tmpKey.privateExponent));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(object,CKA_PRIME_1,
- sftk_item_expand(&tmpKey.prime1));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(object,CKA_PRIME_2,
- sftk_item_expand(&tmpKey.prime2));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(object,CKA_EXPONENT_1,
- sftk_item_expand(&tmpKey.exponent1));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(object,CKA_EXPONENT_2,
- sftk_item_expand(&tmpKey.exponent2));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(object,CKA_COEFFICIENT,
- sftk_item_expand(&tmpKey.coefficient));
- if (crv != CKR_OK) goto loser;
- rv = SECSuccess;
-
- /* we're done (one way or the other), clean up all our stuff */
-loser:
- if (tmpKey.arena) {
- PORT_FreeArena(tmpKey.arena,PR_TRUE);
- }
- if (modulus) {
- sftk_FreeAttribute(modulus);
- }
- if (prime1) {
- sftk_FreeAttribute(prime1);
- }
- if (prime2) {
- sftk_FreeAttribute(prime2);
- }
- if (privateExponent) {
- sftk_FreeAttribute(privateExponent);
- }
- if (publicExponent) {
- sftk_FreeAttribute(publicExponent);
- }
- return rv;
-}
-
-
-
-
-
-
-
-/* Generate a low private key structure from an object */
-NSSLOWKEYPrivateKey *
-sftk_GetPrivKey(SFTKObject *object,CK_KEY_TYPE key_type, CK_RV *crvp)
-{
- NSSLOWKEYPrivateKey *priv = NULL;
-
- if (object->objclass != CKO_PRIVATE_KEY) {
- *crvp = CKR_KEY_TYPE_INCONSISTENT;
- return NULL;
- }
- if (object->objectInfo) {
- *crvp = CKR_OK;
- return (NSSLOWKEYPrivateKey *)object->objectInfo;
- }
-
- priv = sftk_mkPrivKey(object, key_type, crvp);
- object->objectInfo = priv;
- object->infoFree = (SFTKFree) nsslowkey_DestroyPrivateKey;
- return priv;
-}
-
-/*
- **************************** Symetric Key utils ************************
- */
-/*
- * set the DES key with parity bits correctly
- */
-void
-sftk_FormatDESKey(unsigned char *key, int length)
-{
- int i;
-
- /* format the des key */
- for (i=0; i < length; i++) {
- key[i] = parityTable[key[i]>>1];
- }
-}
-
-/*
- * check a des key (des2 or des3 subkey) for weak keys.
- */
-PRBool
-sftk_CheckDESKey(unsigned char *key)
-{
- int i;
-
- /* format the des key with parity */
- sftk_FormatDESKey(key, 8);
-
- for (i=0; i < sftk_desWeakTableSize; i++) {
- if (PORT_Memcmp(key,sftk_desWeakTable[i],8) == 0) {
- return PR_TRUE;
- }
- }
- return PR_FALSE;
-}
-
-/*
- * check if a des or triple des key is weak.
- */
-PRBool
-sftk_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type)
-{
-
- switch(key_type) {
- case CKK_DES:
- return sftk_CheckDESKey(key);
- case CKM_DES2_KEY_GEN:
- if (sftk_CheckDESKey(key)) return PR_TRUE;
- return sftk_CheckDESKey(&key[8]);
- case CKM_DES3_KEY_GEN:
- if (sftk_CheckDESKey(key)) return PR_TRUE;
- if (sftk_CheckDESKey(&key[8])) return PR_TRUE;
- return sftk_CheckDESKey(&key[16]);
- default:
- break;
- }
- return PR_FALSE;
-}
-
-
-/**********************************************************************
- *
- * Start of PKCS 11 functions
- *
- **********************************************************************/
-
-
-/* return the function list */
-CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
-{
- CHECK_FORK();
-
- *pFunctionList = (CK_FUNCTION_LIST_PTR) &sftk_funcList;
- return CKR_OK;
-}
-
-/* return the function list */
-CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
-{
- CHECK_FORK();
-
- return NSC_GetFunctionList(pFunctionList);
-}
-
-static PLHashNumber
-sftk_HashNumber(const void *key)
-{
- return (PLHashNumber) key;
-}
-
-/*
- * eventually I'd like to expunge all occurances of XXX_SLOT_ID and
- * just go with the info in the slot. This is one place, however,
- * where it might be a little difficult.
- */
-const char *
-sftk_getDefTokName(CK_SLOT_ID slotID)
-{
- static char buf[33];
-
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- return "NSS Generic Crypto Services ";
- case PRIVATE_KEY_SLOT_ID:
- return "NSS Certificate DB ";
- case FIPS_SLOT_ID:
- return "NSS FIPS 140-2 Certificate DB ";
- default:
- break;
- }
- sprintf(buf,"NSS Application Token %08x ",(unsigned int) slotID);
- return buf;
-}
-
-const char *
-sftk_getDefSlotName(CK_SLOT_ID slotID)
-{
- static char buf[65];
-
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- return
- "NSS Internal Cryptographic Services ";
- case PRIVATE_KEY_SLOT_ID:
- return
- "NSS User Private Key and Certificate Services ";
- case FIPS_SLOT_ID:
- return
- "NSS FIPS 140-2 User Private Key Services ";
- default:
- break;
- }
- sprintf(buf,
- "NSS Application Slot %08x ",
- (unsigned int) slotID);
- return buf;
-}
-
-static CK_ULONG nscSlotCount[2] = {0 , 0};
-static CK_SLOT_ID_PTR nscSlotList[2] = {NULL, NULL};
-static CK_ULONG nscSlotListSize[2] = {0, 0};
-static PLHashTable *nscSlotHashTable[2] = {NULL, NULL};
-
-static int
-sftk_GetModuleIndex(CK_SLOT_ID slotID)
-{
- if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) {
- return NSC_FIPS_MODULE;
- }
- return NSC_NON_FIPS_MODULE;
-}
-
-/* look up a slot structure from the ID (used to be a macro when we only
- * had two slots) */
-/* if all is true, return the slot even if it has been 'unloaded' */
-/* if all is false, only return the slots which are present */
-SFTKSlot *
-sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all)
-{
- SFTKSlot *slot;
- int index = sftk_GetModuleIndex(slotID);
-
- if (nscSlotHashTable[index] == NULL) return NULL;
- slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index],
- (void *)slotID);
- /* cleared slots shouldn't 'show up' */
- if (slot && !all && !slot->present) slot = NULL;
- return slot;
-}
-
-SFTKSlot *
-sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
-{
- CK_ULONG slotIDIndex = (handle >> 24) & 0x7f;
- CK_ULONG moduleIndex = (handle >> 31) & 1;
-
- if (slotIDIndex >= nscSlotCount[moduleIndex]) {
- return NULL;
- }
-
- return sftk_SlotFromID(nscSlotList[moduleIndex][slotIDIndex], PR_FALSE);
-}
-
-static CK_RV
-sftk_RegisterSlot(SFTKSlot *slot, int moduleIndex)
-{
- PLHashEntry *entry;
- int index;
-
- index = sftk_GetModuleIndex(slot->slotID);
-
- /* make sure the slotID for this module is valid */
- if (moduleIndex != index) {
- return CKR_SLOT_ID_INVALID;
- }
-
- if (nscSlotList[index] == NULL) {
- nscSlotListSize[index] = NSC_SLOT_LIST_BLOCK_SIZE;
- nscSlotList[index] = (CK_SLOT_ID *)
- PORT_ZAlloc(nscSlotListSize[index]*sizeof(CK_SLOT_ID));
- if (nscSlotList[index] == NULL) {
- return CKR_HOST_MEMORY;
- }
- }
- if (nscSlotCount[index] >= nscSlotListSize[index]) {
- CK_SLOT_ID* oldNscSlotList = nscSlotList[index];
- CK_ULONG oldNscSlotListSize = nscSlotListSize[index];
- nscSlotListSize[index] += NSC_SLOT_LIST_BLOCK_SIZE;
- nscSlotList[index] = (CK_SLOT_ID *) PORT_Realloc(oldNscSlotList,
- nscSlotListSize[index]*sizeof(CK_SLOT_ID));
- if (nscSlotList[index] == NULL) {
- nscSlotList[index] = oldNscSlotList;
- nscSlotListSize[index] = oldNscSlotListSize;
- return CKR_HOST_MEMORY;
- }
- }
-
- if (nscSlotHashTable[index] == NULL) {
- nscSlotHashTable[index] = PL_NewHashTable(64,sftk_HashNumber,
- PL_CompareValues, PL_CompareValues, NULL, 0);
- if (nscSlotHashTable[index] == NULL) {
- return CKR_HOST_MEMORY;
- }
- }
-
- entry = PL_HashTableAdd(nscSlotHashTable[index],(void *)slot->slotID,slot);
- if (entry == NULL) {
- return CKR_HOST_MEMORY;
- }
- slot->index = (nscSlotCount[index] & 0x7f) | ((index << 7) & 0x80);
- nscSlotList[index][nscSlotCount[index]++] = slot->slotID;
-
- return CKR_OK;
-}
-
-
-/*
- * ths function has all the common initialization that happens whenever we
- * create a new slot or repurpose an old slot (only valid for slotID's 4
- * and greater).
- *
- * things that are not reinitialized are:
- * slotID (can't change)
- * slotDescription (can't change once defined)
- * the locks and hash tables (difficult to change in running code, and
- * unnecessary. hash tables and list are cleared on shutdown, but they
- * are cleared in a 'friendly' way).
- * session and object ID counters -- so any old sessions and objects in the
- * application will get properly notified that the world has changed.
- *
- * things that are reinitialized:
- * database (otherwise what would the point be;).
- * state variables related to databases.
- * session count stat info.
- * tokenDescription.
- *
- * NOTE: slotID's 4 and greater show up as removable devices.
- *
- */
-CK_RV
-SFTK_SlotReInit(SFTKSlot *slot, char *configdir, char *updatedir,
- char *updateID, sftk_token_parameters *params, int moduleIndex)
-{
- PRBool needLogin = !params->noKeyDB;
- CK_RV crv;
-
- slot->hasTokens = PR_FALSE;
- slot->sessionIDConflict = 0;
- slot->sessionCount = 0;
- slot->rwSessionCount = 0;
- slot->needLogin = PR_FALSE;
- slot->isLoggedIn = PR_FALSE;
- slot->ssoLoggedIn = PR_FALSE;
- slot->DB_loaded = PR_FALSE;
- slot->certDB = NULL;
- slot->keyDB = NULL;
- slot->minimumPinLen = 0;
- slot->readOnly = params->readOnly;
- sftk_setStringName(params->tokdes ? params->tokdes :
- sftk_getDefTokName(slot->slotID), slot->tokDescription,
- sizeof(slot->tokDescription),PR_TRUE);
- sftk_setStringName(params->updtokdes ? params->updtokdes : " ",
- slot->updateTokDescription,
- sizeof(slot->updateTokDescription),PR_TRUE);
-
- if ((!params->noCertDB) || (!params->noKeyDB)) {
- SFTKDBHandle * certHandle = NULL;
- SFTKDBHandle *keyHandle = NULL;
- crv = sftk_DBInit(params->configdir ? params->configdir : configdir,
- params->certPrefix, params->keyPrefix,
- params->updatedir ? params->updatedir : updatedir,
- params->updCertPrefix, params->updKeyPrefix,
- params->updateID ? params->updateID : updateID,
- params->readOnly, params->noCertDB, params->noKeyDB,
- params->forceOpen,
- moduleIndex == NSC_FIPS_MODULE,
- &certHandle, &keyHandle);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- slot->certDB = certHandle;
- slot->keyDB = keyHandle;
- }
- if (needLogin) {
- /* if the data base is initialized with a null password,remember that */
- slot->needLogin =
- (PRBool)!sftk_hasNullPassword(slot, slot->keyDB);
- if ((params->minPW >= 0) && (params->minPW <= SFTK_MAX_PIN)) {
- slot->minimumPinLen = params->minPW;
- }
- if ((slot->minimumPinLen == 0) && (params->pwRequired)) {
- slot->minimumPinLen = 1;
- }
- if ((moduleIndex == NSC_FIPS_MODULE) &&
- (slot->minimumPinLen < FIPS_MIN_PIN)) {
- slot->minimumPinLen = FIPS_MIN_PIN;
- }
- }
-
- slot->present = PR_TRUE;
- return CKR_OK;
-
-loser:
- SFTK_ShutdownSlot(slot);
- return crv;
-}
-
-/*
- * initialize one of the slot structures. figure out which by the ID
- */
-CK_RV
-SFTK_SlotInit(char *configdir, char *updatedir, char *updateID,
- sftk_token_parameters *params, int moduleIndex)
-{
- unsigned int i;
- CK_SLOT_ID slotID = params->slotID;
- SFTKSlot *slot;
- CK_RV crv = CKR_HOST_MEMORY;
-
- /*
- * first we initialize everything that is 'permanent' with this slot.
- * that is everything we aren't going to shutdown if we close this slot
- * and open it up again with different databases */
-
- slot = PORT_ZNew(SFTKSlot);
-
- if (slot == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- slot->optimizeSpace = params->optimizeSpace;
- if (slot->optimizeSpace) {
- slot->sessObjHashSize = SPACE_SESSION_OBJECT_HASH_SIZE;
- slot->sessHashSize = SPACE_SESSION_HASH_SIZE;
- slot->numSessionLocks = 1;
- } else {
- slot->sessObjHashSize = TIME_SESSION_OBJECT_HASH_SIZE;
- slot->sessHashSize = TIME_SESSION_HASH_SIZE;
- slot->numSessionLocks = slot->sessHashSize/BUCKETS_PER_SESSION_LOCK;
- }
- slot->sessionLockMask = slot->numSessionLocks-1;
-
- slot->slotLock = PZ_NewLock(nssILockSession);
- if (slot->slotLock == NULL)
- goto mem_loser;
- slot->sessionLock = PORT_ZNewArray(PZLock *, slot->numSessionLocks);
- if (slot->sessionLock == NULL)
- goto mem_loser;
- for (i=0; i < slot->numSessionLocks; i++) {
- slot->sessionLock[i] = PZ_NewLock(nssILockSession);
- if (slot->sessionLock[i] == NULL)
- goto mem_loser;
- }
- slot->objectLock = PZ_NewLock(nssILockObject);
- if (slot->objectLock == NULL)
- goto mem_loser;
- slot->pwCheckLock = PR_NewLock();
- if (slot->pwCheckLock == NULL)
- goto mem_loser;
- slot->head = PORT_ZNewArray(SFTKSession *, slot->sessHashSize);
- if (slot->head == NULL)
- goto mem_loser;
- slot->sessObjHashTable = PORT_ZNewArray(SFTKObject *, slot->sessObjHashSize);
- if (slot->sessObjHashTable == NULL)
- goto mem_loser;
- slot->tokObjHashTable = PL_NewHashTable(64,sftk_HashNumber,PL_CompareValues,
- SECITEM_HashCompare, NULL, 0);
- if (slot->tokObjHashTable == NULL)
- goto mem_loser;
-
- slot->sessionIDCount = 0;
- slot->sessionObjectHandleCount = minSessionObjectHandle;
- slot->slotID = slotID;
- sftk_setStringName(params->slotdes ? params->slotdes :
- sftk_getDefSlotName(slotID), slot->slotDescription,
- sizeof(slot->slotDescription), PR_TRUE);
-
- /* call the reinit code to set everything that changes between token
- * init calls */
- crv = SFTK_SlotReInit(slot, configdir, updatedir, updateID,
- params, moduleIndex);
- if (crv != CKR_OK) {
- goto loser;
- }
- crv = sftk_RegisterSlot(slot, moduleIndex);
- if (crv != CKR_OK) {
- goto loser;
- }
- return CKR_OK;
-
-mem_loser:
- crv = CKR_HOST_MEMORY;
-loser:
- SFTK_DestroySlotData(slot);
- return crv;
-}
-
-
-CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout)
-{
- SFTKSession *session;
- unsigned int i;
- SFTKDBHandle *handle;
-
- /* first log out the card */
- /* special case - if we are in a middle of upgrade, we want to close the
- * sessions to fake a token removal to tell the upper level code we have
- * switched from one database to another, but we don't want to
- * explicity logout in case we can continue the upgrade with the
- * existing password if possible.
- */
- if (logout) {
- handle = sftk_getKeyDB(slot);
- SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
- slot->isLoggedIn = PR_FALSE;
- if (slot->needLogin && handle) {
- sftkdb_ClearPassword(handle);
- }
- SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
- if (handle) {
- sftk_freeDB(handle);
- }
- }
-
- /* now close all the current sessions */
- /* NOTE: If you try to open new sessions before NSC_CloseAllSessions
- * completes, some of those new sessions may or may not be closed by
- * NSC_CloseAllSessions... but any session running when this code starts
- * will guarrenteed be close, and no session will be partially closed */
- for (i=0; i < slot->sessHashSize; i++) {
- PZLock *lock = SFTK_SESSION_LOCK(slot,i);
- do {
- SKIP_AFTER_FORK(PZ_Lock(lock));
- session = slot->head[i];
- /* hand deque */
- /* this duplicates function of NSC_close session functions, but
- * because we know that we are freeing all the sessions, we can
- * do more efficient processing */
- if (session) {
- slot->head[i] = session->next;
- if (session->next) session->next->prev = NULL;
- session->next = session->prev = NULL;
- SKIP_AFTER_FORK(PZ_Unlock(lock));
- SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
- --slot->sessionCount;
- SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
- if (session->info.flags & CKF_RW_SESSION) {
- PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
- }
- } else {
- SKIP_AFTER_FORK(PZ_Unlock(lock));
- }
- if (session) sftk_FreeSession(session);
- } while (session != NULL);
- }
- return CKR_OK;
-}
-
-/*
- * shut down the databases.
- * we get the slot lock (which also protects slot->certDB and slot->keyDB)
- * and clear the values so the new users will not find the databases.
- * once things are clear, we can release our references to the databases.
- * The databases will close when the last reference is released.
- *
- * We use reference counts so that we don't crash if someone shuts down
- * a token that another thread is actively using.
- */
-static void
-sftk_DBShutdown(SFTKSlot *slot)
-{
- SFTKDBHandle *certHandle;
- SFTKDBHandle *keyHandle;
- SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
- certHandle = slot->certDB;
- slot->certDB = NULL;
- keyHandle = slot->keyDB;
- slot->keyDB = NULL;
- SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
- if (certHandle) {
- sftk_freeDB(certHandle);
- }
- if (keyHandle) {
- sftk_freeDB(keyHandle);
- }
-}
-
-CK_RV
-SFTK_ShutdownSlot(SFTKSlot *slot)
-{
- /* make sure no new PK11 calls work except C_GetSlotInfo */
- slot->present = PR_FALSE;
-
- /* close all outstanding sessions
- * the sessHashSize variable guarentees we have all the session
- * mechanism set up */
- if (slot->head) {
- sftk_CloseAllSessions(slot, PR_TRUE);
- }
-
- /* clear all objects.. session objects are cleared as a result of
- * closing all the sessions. We just need to clear the token object
- * cache. slot->tokObjHashTable guarentees we have the token
- * infrastructure set up. */
- if (slot->tokObjHashTable) {
- SFTK_ClearTokenKeyHashTable(slot);
- }
-
- /* clear the slot description for the next guy */
- PORT_Memset(slot->tokDescription, 0, sizeof(slot->tokDescription));
-
- /* now shut down the databases. */
- sftk_DBShutdown(slot);
- return CKR_OK;
-}
-
-/*
- * initialize one of the slot structures. figure out which by the ID
- */
-CK_RV
-SFTK_DestroySlotData(SFTKSlot *slot)
-{
- unsigned int i;
-
- SFTK_ShutdownSlot(slot);
-
- if (slot->tokObjHashTable) {
- PL_HashTableDestroy(slot->tokObjHashTable);
- slot->tokObjHashTable = NULL;
- }
-
- if (slot->sessObjHashTable) {
- PORT_Free(slot->sessObjHashTable);
- slot->sessObjHashTable = NULL;
- }
- slot->sessObjHashSize = 0;
-
- if (slot->head) {
- PORT_Free(slot->head);
- slot->head = NULL;
- }
- slot->sessHashSize = 0;
-
- /* OK everything has been disassembled, now we can finally get rid
- * of the locks */
- SKIP_AFTER_FORK(PZ_DestroyLock(slot->slotLock));
- slot->slotLock = NULL;
- if (slot->sessionLock) {
- for (i=0; i < slot->numSessionLocks; i++) {
- if (slot->sessionLock[i]) {
- SKIP_AFTER_FORK(PZ_DestroyLock(slot->sessionLock[i]));
- slot->sessionLock[i] = NULL;
- }
- }
- PORT_Free(slot->sessionLock);
- slot->sessionLock = NULL;
- }
- if (slot->objectLock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(slot->objectLock));
- slot->objectLock = NULL;
- }
- if (slot->pwCheckLock) {
- SKIP_AFTER_FORK(PR_DestroyLock(slot->pwCheckLock));
- slot->pwCheckLock = NULL;
- }
- PORT_Free(slot);
- return CKR_OK;
-}
-
-/*
- * handle the SECMOD.db
- */
-char **
-NSC_ModuleDBFunc(unsigned long function,char *parameters, void *args)
-{
- char *secmod = NULL;
- char *appName = NULL;
- char *filename = NULL;
- NSSDBType dbType = NSS_DB_TYPE_NONE;
- PRBool rw;
- static char *success="Success";
- char **rvstr = NULL;
-
- rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
- if (rvstr != NULL) {
- return rvstr;
- }
-
- if (PORT_GetError() != SEC_ERROR_LEGACY_DATABASE) {
- return NULL;
- }
-
- /* The legacy database uses the old dbm, which is only linked with the
- * legacy DB handler, which is only callable from softoken */
-
- secmod = _NSSUTIL_GetSecmodName(parameters, &dbType, &appName,
- &filename, &rw);
-
- switch (function) {
- case SECMOD_MODULE_DB_FUNCTION_FIND:
- if (secmod == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- if (rw && (dbType != NSS_DB_TYPE_LEGACY) &&
- (dbType != NSS_DB_TYPE_MULTIACCESS)) {
- /* if we get here, we are trying to update the local database */
- /* force data from the legacy DB */
- char *oldSecmod = NULL;
- char *oldAppName = NULL;
- char *oldFilename = NULL;
- PRBool oldrw;
- char **strings = NULL;
- int i;
-
- dbType = NSS_DB_TYPE_LEGACY;
- oldSecmod = _NSSUTIL_GetSecmodName(parameters,&dbType, &oldAppName,
- &oldFilename, &oldrw);
- strings = sftkdbCall_ReadSecmodDB(appName, oldFilename, oldSecmod,
- (char *)parameters, oldrw);
- if (strings) {
- /* write out the strings */
- for (i=0; strings[i]; i++) {
- NSSUTIL_DoModuleDBFunction(SECMOD_MODULE_DB_FUNCTION_ADD,
- parameters, strings[i]);
- }
- sftkdbCall_ReleaseSecmodDBData(oldAppName,oldFilename,oldSecmod,
- (char **)strings,oldrw);
- } else {
- /* write out a dummy record */
- NSSUTIL_DoModuleDBFunction(SECMOD_MODULE_DB_FUNCTION_ADD,
- parameters, " ");
- }
- if (oldSecmod) { PR_smprintf_free(oldSecmod); }
- if (oldAppName) { PORT_Free(oldAppName); }
- if (oldFilename) { PORT_Free(oldFilename); }
- rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
- break;
- }
- rvstr = sftkdbCall_ReadSecmodDB(appName,filename,secmod,
- (char *)parameters,rw);
- break;
- case SECMOD_MODULE_DB_FUNCTION_ADD:
- if (secmod == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- rvstr = (sftkdbCall_AddSecmodDB(appName,filename,secmod,
- (char *)args,rw) == SECSuccess) ? &success: NULL;
- break;
- case SECMOD_MODULE_DB_FUNCTION_DEL:
- if (secmod == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- rvstr = (sftkdbCall_DeleteSecmodDB(appName,filename,secmod,
- (char *)args,rw) == SECSuccess) ? &success: NULL;
- break;
- case SECMOD_MODULE_DB_FUNCTION_RELEASE:
- rvstr = (sftkdbCall_ReleaseSecmodDBData(appName,filename,secmod,
- (char **)args,rw) == SECSuccess) ? &success: NULL;
- break;
- }
- if (secmod) PR_smprintf_free(secmod);
- if (appName) PORT_Free(appName);
- if (filename) PORT_Free(filename);
- return rvstr;
-}
-
-static void nscFreeAllSlots(int moduleIndex)
-{
- /* free all the slots */
- SFTKSlot *slot = NULL;
- CK_SLOT_ID slotID;
- int i;
-
- if (nscSlotList[moduleIndex]) {
- CK_ULONG tmpSlotCount = nscSlotCount[moduleIndex];
- CK_SLOT_ID_PTR tmpSlotList = nscSlotList[moduleIndex];
- PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex];
-
- /* first close all the session */
- for (i=0; i < (int) tmpSlotCount; i++) {
- slotID = tmpSlotList[i];
- (void) NSC_CloseAllSessions(slotID);
- }
-
- /* now clear out the statics */
- nscSlotList[moduleIndex] = NULL;
- nscSlotCount[moduleIndex] = 0;
- nscSlotHashTable[moduleIndex] = NULL;
- nscSlotListSize[moduleIndex] = 0;
-
- for (i=0; i < (int) tmpSlotCount; i++) {
- slotID = tmpSlotList[i];
- slot = (SFTKSlot *)
- PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
- PORT_Assert(slot);
- if (!slot) continue;
- SFTK_DestroySlotData(slot);
- PL_HashTableRemove(tmpSlotHashTable, (void *)slotID);
- }
- PORT_Free(tmpSlotList);
- PL_HashTableDestroy(tmpSlotHashTable);
- }
-}
-
-static void
-sftk_closePeer(PRBool isFIPS)
-{
- CK_SLOT_ID slotID = isFIPS ? PRIVATE_KEY_SLOT_ID: FIPS_SLOT_ID;
- SFTKSlot *slot;
- int moduleIndex = isFIPS? NSC_NON_FIPS_MODULE : NSC_FIPS_MODULE;
- PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex];
-
- slot = (SFTKSlot *) PL_HashTableLookup(tmpSlotHashTable, (void *)slotID);
- if (slot == NULL) {
- return;
- }
- sftk_DBShutdown(slot);
- return;
-}
-
-/* NSC_Initialize initializes the Cryptoki library. */
-CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
-{
- CK_RV crv = CKR_OK;
- SECStatus rv;
- CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *) pReserved;
- int i;
- int moduleIndex = isFIPS? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE;
-
- if (isFIPS) {
- loginWaitTime = PR_SecondsToInterval(1);
- }
-
- ENABLE_FORK_CHECK();
-
- rv = SECOID_Init();
- if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- return crv;
- }
-
- rv = RNG_RNGInit(); /* initialize random number generator */
- if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- return crv;
- }
- rv = BL_Init(); /* initialize freebl engine */
- if (rv != SECSuccess) {
- crv = CKR_DEVICE_ERROR;
- return crv;
- }
-
- /* NOTE:
- * we should be getting out mutexes from this list, not statically binding
- * them from NSPR. This should happen before we allow the internal to split
- * off from the rest on NSS.
- */
-
- /* initialize the key and cert db's */
- if (init_args && (!(init_args->flags & CKF_OS_LOCKING_OK))) {
- if (init_args->CreateMutex && init_args->DestroyMutex &&
- init_args->LockMutex && init_args->UnlockMutex) {
- /* softoken always uses NSPR (ie. OS locking), and doesn't know how
- * to use the lock functions provided by the application.
- */
- crv = CKR_CANT_LOCK;
- return crv;
- }
- if (init_args->CreateMutex || init_args->DestroyMutex ||
- init_args->LockMutex || init_args->UnlockMutex) {
- /* only some of the lock functions were provided by the
- * application. This is invalid per PKCS#11 spec.
- */
- crv = CKR_ARGUMENTS_BAD;
- return crv;
- }
- }
- crv = CKR_ARGUMENTS_BAD;
- if ((init_args && init_args->LibraryParameters)) {
- sftk_parameters paramStrings;
-
- crv = sftk_parseParameters
- ((char *)init_args->LibraryParameters, &paramStrings, isFIPS);
- if (crv != CKR_OK) {
- return crv;
- }
- crv = sftk_configure(paramStrings.man, paramStrings.libdes);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- /* if we have a peer already open, have him close his DB's so we
- * don't clobber each other. */
- if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) {
- sftk_closePeer(isFIPS);
- if (sftk_audit_enabled) {
- if (isFIPS && nsc_init) {
- sftk_LogAuditMessage(NSS_AUDIT_INFO, NSS_AUDIT_FIPS_STATE,
- "enabled FIPS mode");
- } else {
- sftk_LogAuditMessage(NSS_AUDIT_INFO, NSS_AUDIT_FIPS_STATE,
- "disabled FIPS mode");
- }
- }
- }
-
- for (i=0; i < paramStrings.token_count; i++) {
- crv = SFTK_SlotInit(paramStrings.configdir,
- paramStrings.updatedir, paramStrings.updateID,
- &paramStrings.tokens[i], moduleIndex);
- if (crv != CKR_OK) {
- nscFreeAllSlots(moduleIndex);
- break;
- }
- }
-loser:
- sftk_freeParams(&paramStrings);
- }
- if (CKR_OK == crv) {
- sftk_InitFreeLists();
- }
-
-#ifndef NO_FORK_CHECK
- if (CKR_OK == crv) {
-#if defined(CHECK_FORK_MIXED)
- /* Before Solaris 10, fork handlers are not unregistered at dlclose()
- * time. So, we only use pthread_atfork on Solaris 10 and later. For
- * earlier versions, we use PID checks.
- */
- char buf[200];
- int major = 0, minor = 0;
-
- long rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
- if (rv > 0 && rv < sizeof(buf)) {
- if (2 == sscanf(buf, "%d.%d", &major, &minor)) {
- /* Are we on Solaris 10 or greater ? */
- if (major >5 || (5 == major && minor >= 10)) {
- /* we are safe to use pthread_atfork */
- usePthread_atfork = PR_TRUE;
- }
- }
- }
- if (usePthread_atfork) {
- pthread_atfork(NULL, NULL, ForkedChild);
- } else {
- myPid = getpid();
- }
-
-#elif defined(CHECK_FORK_PTHREAD)
- pthread_atfork(NULL, NULL, ForkedChild);
-#elif defined(CHECK_FORK_GETPID)
- myPid = getpid();
-#else
-#error Incorrect fork check method.
-#endif
- }
-#endif
- return crv;
-}
-
-CK_RV NSC_Initialize(CK_VOID_PTR pReserved)
-{
- CK_RV crv;
-
- sftk_ForkReset(pReserved, &crv);
-
- if (nsc_init) {
- return CKR_CRYPTOKI_ALREADY_INITIALIZED;
- }
- crv = nsc_CommonInitialize(pReserved,PR_FALSE);
- nsc_init = (PRBool) (crv == CKR_OK);
- return crv;
-}
-
-
-/* NSC_Finalize indicates that an application is done with the
- * Cryptoki library.*/
-CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS)
-{
- /* propagate the fork status to freebl and util */
- BL_SetForkState(parentForkedAfterC_Initialize);
- UTIL_SetForkState(parentForkedAfterC_Initialize);
-
- nscFreeAllSlots(isFIPS ? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE);
-
- /* don't muck with the globals if our peer is still initialized */
- if (isFIPS && nsc_init) {
- return CKR_OK;
- }
- if (!isFIPS && nsf_init) {
- return CKR_OK;
- }
-
- sftk_CleanupFreeLists();
- sftkdb_Shutdown();
-
- /* This function does not discard all our previously aquired entropy. */
- RNG_RNGShutdown();
-
- /* tell freeBL to clean up after itself */
- BL_Cleanup();
-
- /* reset fork status in freebl. We must do this before BL_Unload so that
- * this call doesn't force freebl to be reloaded. */
- BL_SetForkState(PR_FALSE);
-
- /* unload freeBL shared library from memory. This may only decrement the
- * OS refcount if it's been loaded multiple times, eg. by libssl */
- BL_Unload();
-
- /* clean up the default OID table */
- SECOID_Shutdown();
-
- /* reset fork status in util */
- UTIL_SetForkState(PR_FALSE);
-
- nsc_init = PR_FALSE;
-
-#ifdef CHECK_FORK_MIXED
- if (!usePthread_atfork) {
- myPid = 0; /* allow CHECK_FORK in the next softoken initialization to
- * succeed */
- } else {
- forked = PR_FALSE; /* allow reinitialization */
- }
-#elif defined(CHECK_FORK_GETPID)
- myPid = 0; /* allow reinitialization */
-#elif defined (CHECK_FORK_PTHREAD)
- forked = PR_FALSE; /* allow reinitialization */
-#endif
- return CKR_OK;
-}
-
-/* Hard-reset the entire softoken PKCS#11 module if the parent process forked
- * while it was initialized. */
-PRBool sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV* crv)
-{
-#ifndef NO_FORK_CHECK
- if (PARENT_FORKED()) {
- parentForkedAfterC_Initialize = PR_TRUE;
- if (nsc_init) {
- /* finalize non-FIPS token */
- *crv = nsc_CommonFinalize(pReserved, PR_FALSE);
- PORT_Assert(CKR_OK == *crv);
- nsc_init = (PRBool) !(*crv == CKR_OK);
- }
- if (nsf_init) {
- /* finalize FIPS token */
- *crv = nsc_CommonFinalize(pReserved, PR_TRUE);
- PORT_Assert(CKR_OK == *crv);
- nsf_init = (PRBool) !(*crv == CKR_OK);
- }
- parentForkedAfterC_Initialize = PR_FALSE;
- return PR_TRUE;
- }
-#endif
- return PR_FALSE;
-}
-
-/* NSC_Finalize indicates that an application is done with the
- * Cryptoki library.*/
-CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
-{
- CK_RV crv;
-
- /* reset entire PKCS#11 module upon fork */
- if (sftk_ForkReset(pReserved, &crv)) {
- return crv;
- }
-
- if (!nsc_init) {
- return CKR_OK;
- }
-
- crv = nsc_CommonFinalize (pReserved, PR_FALSE);
-
- nsc_init = (PRBool) !(crv == CKR_OK);
-
- return crv;
-}
-
-extern const char __nss_softokn_rcsid[];
-extern const char __nss_softokn_sccsid[];
-
-/* NSC_GetInfo returns general information about Cryptoki. */
-CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
-{
- volatile char c; /* force a reference that won't get optimized away */
-
- CHECK_FORK();
-
- c = __nss_softokn_rcsid[0] + __nss_softokn_sccsid[0];
- pInfo->cryptokiVersion.major = 2;
- pInfo->cryptokiVersion.minor = 20;
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- pInfo->libraryVersion.major = SOFTOKEN_VMAJOR;
- pInfo->libraryVersion.minor = SOFTOKEN_VMINOR;
- PORT_Memcpy(pInfo->libraryDescription,libraryDescription,32);
- pInfo->flags = 0;
- return CKR_OK;
-}
-
-
-/* NSC_GetSlotList obtains a list of slots in the system. */
-CK_RV nsc_CommonGetSlotList(CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex)
-{
- *pulCount = nscSlotCount[moduleIndex];
- if (pSlotList != NULL) {
- PORT_Memcpy(pSlotList,nscSlotList[moduleIndex],
- nscSlotCount[moduleIndex]*sizeof(CK_SLOT_ID));
- }
- return CKR_OK;
-}
-
-/* NSC_GetSlotList obtains a list of slots in the system. */
-CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
-{
- CHECK_FORK();
- return nsc_CommonGetSlotList(tokenPresent, pSlotList, pulCount,
- NSC_NON_FIPS_MODULE);
-}
-
-/* NSC_GetSlotInfo obtains information about a particular slot in the system. */
-CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
-{
- SFTKSlot *slot = sftk_SlotFromID(slotID, PR_TRUE);
-
- CHECK_FORK();
-
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
-
- pInfo->firmwareVersion.major = 0;
- pInfo->firmwareVersion.minor = 0;
-
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,
- sizeof(pInfo->manufacturerID));
- PORT_Memcpy(pInfo->slotDescription,slot->slotDescription,
- sizeof(pInfo->slotDescription));
- pInfo->flags = (slot->present) ? CKF_TOKEN_PRESENT : 0;
-
- /* all user defined slots are defined as removable */
- if (slotID >= SFTK_MIN_USER_SLOT_ID) {
- pInfo->flags |= CKF_REMOVABLE_DEVICE;
- } else {
- /* In the case where we are doing a merge update, we need
- * the DB slot to be removable so the token name can change
- * appropriately. */
- SFTKDBHandle *handle = sftk_getKeyDB(slot);
- if (handle) {
- if (sftkdb_InUpdateMerge(handle)) {
- pInfo->flags |= CKF_REMOVABLE_DEVICE;
- }
- sftk_freeDB(handle);
- }
- }
-
- /* ok we really should read it out of the keydb file. */
- /* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
- pInfo->hardwareVersion.major = SOFTOKEN_VMAJOR;
- pInfo->hardwareVersion.minor = SOFTOKEN_VMINOR;
- return CKR_OK;
-}
-
-/*
- * check the current state of the 'needLogin' flag in case the database has
- * been changed underneath us.
- */
-static PRBool
-sftk_checkNeedLogin(SFTKSlot *slot, SFTKDBHandle *keyHandle)
-{
- if (sftkdb_PWCached(keyHandle) == SECSuccess) {
- return slot->needLogin;
- }
- slot->needLogin = (PRBool)!sftk_hasNullPassword(slot, keyHandle);
- return (slot->needLogin);
-}
-
-static PRBool
-sftk_isBlank(const char *s, int len)
-{
- int i;
- for (i=0; i < len; i++) {
- if (s[i] != ' ') {
- return PR_FALSE;
- }
- }
- return PR_TRUE;
-}
-
-/* NSC_GetTokenInfo obtains information about a particular token in
- * the system. */
-CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
-{
- SFTKSlot *slot;
- SFTKDBHandle *handle;
-
- CHECK_FORK();
-
- if (!nsc_init && !nsf_init) return CKR_CRYPTOKI_NOT_INITIALIZED;
- slot = sftk_SlotFromID(slotID, PR_FALSE);
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
-
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->model,"NSS 3 ",16);
- PORT_Memcpy(pInfo->serialNumber,"0000000000000000",16);
- PORT_Memcpy(pInfo->utcTime,"0000000000000000",16);
- pInfo->ulMaxSessionCount = 0; /* arbitrarily large */
- pInfo->ulSessionCount = slot->sessionCount;
- pInfo->ulMaxRwSessionCount = 0; /* arbitarily large */
- pInfo->ulRwSessionCount = slot->rwSessionCount;
- pInfo->firmwareVersion.major = 0;
- pInfo->firmwareVersion.minor = 0;
- PORT_Memcpy(pInfo->label,slot->tokDescription,sizeof(pInfo->label));
- handle = sftk_getKeyDB(slot);
- pInfo->flags = CKF_RNG | CKF_DUAL_CRYPTO_OPERATIONS;
- if (handle == NULL) {
- pInfo->flags |= CKF_WRITE_PROTECTED;
- pInfo->ulMaxPinLen = 0;
- pInfo->ulMinPinLen = 0;
- pInfo->ulTotalPublicMemory = 0;
- pInfo->ulFreePublicMemory = 0;
- pInfo->ulTotalPrivateMemory = 0;
- pInfo->ulFreePrivateMemory = 0;
- pInfo->hardwareVersion.major = 4;
- pInfo->hardwareVersion.minor = 0;
- } else {
- /*
- * we have three possible states which we may be in:
- * (1) No DB password has been initialized. This also means we
- * have no keys in the key db.
- * (2) Password initialized to NULL. This means we have keys, but
- * the user has chosen not use a password.
- * (3) Finally we have an initialized password whicn is not NULL, and
- * we will need to prompt for it.
- */
- if (sftkdb_HasPasswordSet(handle) == SECFailure) {
- pInfo->flags |= CKF_LOGIN_REQUIRED;
- } else if (!sftk_checkNeedLogin(slot,handle)) {
- pInfo->flags |= CKF_USER_PIN_INITIALIZED;
- } else {
- pInfo->flags |= CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
- /*
- * if we are doing a merge style update, and we need to get the password
- * of our source database (the database we are updating from), make sure we
- * return a token name that will match the database we are prompting for.
- */
- if (sftkdb_NeedUpdateDBPassword(handle)) {
- /* if we have an update tok description, use it. otherwise
- * use the updateID for this database */
- if (!sftk_isBlank(slot->updateTokDescription,
- sizeof(pInfo->label))) {
- PORT_Memcpy(pInfo->label,slot->updateTokDescription,
- sizeof(pInfo->label));
- } else {
- /* build from updateID */
- const char *updateID = sftkdb_GetUpdateID(handle);
- if (updateID) {
- sftk_setStringName(updateID, (char *)pInfo->label,
- sizeof(pInfo->label), PR_FALSE);
- }
- }
- }
- }
- pInfo->ulMaxPinLen = SFTK_MAX_PIN;
- pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
- pInfo->ulTotalPublicMemory = 1;
- pInfo->ulFreePublicMemory = 1;
- pInfo->ulTotalPrivateMemory = 1;
- pInfo->ulFreePrivateMemory = 1;
-#ifdef SHDB_FIXME
- pInfo->hardwareVersion.major = CERT_DB_FILE_VERSION;
- pInfo->hardwareVersion.minor = handle->version;
-#else
- pInfo->hardwareVersion.major = 0;
- pInfo->hardwareVersion.minor = 0;
-#endif
- sftk_freeDB(handle);
- }
- /*
- * CKF_LOGIN_REQUIRED CKF_USER_PIN_INITIALIZED how CKF_TOKEN_INITIALIZED
- * should be set
- * 0 0 1
- * 1 0 0
- * 0 1 1
- * 1 1 1
- */
- if (!(pInfo->flags & CKF_LOGIN_REQUIRED) ||
- (pInfo->flags & CKF_USER_PIN_INITIALIZED)) {
- pInfo->flags |= CKF_TOKEN_INITIALIZED;
- }
- return CKR_OK;
-}
-
-/* NSC_GetMechanismList obtains a list of mechanism types
- * supported by a token. */
-CK_RV NSC_GetMechanismList(CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount)
-{
- CK_ULONG i;
-
- CHECK_FORK();
-
- switch (slotID) {
- /* default: */
- case NETSCAPE_SLOT_ID:
- *pulCount = mechanismCount;
- if (pMechanismList != NULL) {
- for (i=0; i < mechanismCount; i++) {
- pMechanismList[i] = mechanisms[i].type;
- }
- }
- break;
- default:
- *pulCount = 0;
- for (i=0; i < mechanismCount; i++) {
- if (mechanisms[i].privkey) {
- (*pulCount)++;
- if (pMechanismList != NULL) {
- *pMechanismList++ = mechanisms[i].type;
- }
- }
- }
- break;
- }
- return CKR_OK;
-}
-
-
-/* NSC_GetMechanismInfo obtains information about a particular mechanism
- * possibly supported by a token. */
-CK_RV NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo)
-{
- PRBool isPrivateKey;
- CK_ULONG i;
-
- CHECK_FORK();
-
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- isPrivateKey = PR_FALSE;
- break;
- default:
- isPrivateKey = PR_TRUE;
- break;
- }
- for (i=0; i < mechanismCount; i++) {
- if (type == mechanisms[i].type) {
- if (isPrivateKey && !mechanisms[i].privkey) {
- return CKR_MECHANISM_INVALID;
- }
- PORT_Memcpy(pInfo,&mechanisms[i].info, sizeof(CK_MECHANISM_INFO));
- return CKR_OK;
- }
- }
- return CKR_MECHANISM_INVALID;
-}
-
-CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op)
-{
- CK_ULONG i;
- CK_FLAGS flags;
-
- switch (op) {
- case CKA_ENCRYPT: flags = CKF_ENCRYPT; break;
- case CKA_DECRYPT: flags = CKF_DECRYPT; break;
- case CKA_WRAP: flags = CKF_WRAP; break;
- case CKA_UNWRAP: flags = CKF_UNWRAP; break;
- case CKA_SIGN: flags = CKF_SIGN; break;
- case CKA_SIGN_RECOVER: flags = CKF_SIGN_RECOVER; break;
- case CKA_VERIFY: flags = CKF_VERIFY; break;
- case CKA_VERIFY_RECOVER: flags = CKF_VERIFY_RECOVER; break;
- case CKA_DERIVE: flags = CKF_DERIVE; break;
- default:
- return CKR_ARGUMENTS_BAD;
- }
- for (i=0; i < mechanismCount; i++) {
- if (type == mechanisms[i].type) {
- return (flags & mechanisms[i].info.flags) ? CKR_OK
- : CKR_MECHANISM_INVALID;
- }
- }
- return CKR_MECHANISM_INVALID;
-}
-
-/* NSC_InitToken initializes a token. */
-CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,CK_CHAR_PTR pLabel) {
- SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
- SFTKDBHandle *handle;
- SFTKDBHandle *certHandle;
- SECStatus rv;
- unsigned int i;
- SFTKObject *object;
-
- CHECK_FORK();
-
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
-
- /* don't initialize the database if we aren't talking to a token
- * that uses the key database.
- */
- if (slotID == NETSCAPE_SLOT_ID) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* first, delete all our loaded key and cert objects from our
- * internal list. */
- PZ_Lock(slot->objectLock);
- for (i=0; i < slot->sessObjHashSize; i++) {
- do {
- object = slot->sessObjHashTable[i];
- /* hand deque */
- /* this duplicates function of NSC_close session functions, but
- * because we know that we are freeing all the sessions, we can
- * do more efficient processing */
- if (object) {
- slot->sessObjHashTable[i] = object->next;
-
- if (object->next) object->next->prev = NULL;
- object->next = object->prev = NULL;
- }
- if (object) sftk_FreeObject(object);
- } while (object != NULL);
- }
- slot->DB_loaded = PR_FALSE;
- PZ_Unlock(slot->objectLock);
-
- /* then clear out the key database */
- handle = sftk_getKeyDB(slot);
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- rv = sftkdb_ResetKeyDB(handle);
- sftk_freeDB(handle);
- if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
- }
-
- /* finally mark all the user certs as non-user certs */
- certHandle = sftk_getCertDB(slot);
- if (certHandle == NULL) return CKR_OK;
-
- sftk_freeDB(certHandle);
-
- return CKR_OK; /*is this the right function for not implemented*/
-}
-
-
-/* NSC_InitPIN initializes the normal user's PIN. */
-CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
-{
- SFTKSession *sp = NULL;
- SFTKSlot *slot;
- SFTKDBHandle *handle = NULL;
- char newPinStr[SFTK_MAX_PIN+1];
- SECStatus rv;
- CK_RV crv = CKR_SESSION_HANDLE_INVALID;
- PRBool tokenRemoved = PR_FALSE;
-
- CHECK_FORK();
-
- sp = sftk_SessionFromHandle(hSession);
- if (sp == NULL) {
- goto loser;
- }
-
- slot = sftk_SlotFromSession(sp);
- if (slot == NULL) {
- goto loser;
- }
-
- handle = sftk_getKeyDB(slot);
- if (handle == NULL) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
- }
-
-
- if (sp->info.state != CKS_RW_SO_FUNCTIONS) {
- crv = CKR_USER_NOT_LOGGED_IN;
- goto loser;
- }
-
- sftk_FreeSession(sp);
- sp = NULL;
-
- /* make sure the pins aren't too long */
- if (ulPinLen > SFTK_MAX_PIN) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
- }
- if (ulPinLen < (CK_ULONG)slot->minimumPinLen) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
- }
-
- if (sftkdb_HasPasswordSet(handle) != SECFailure) {
- crv = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- /* convert to null terminated string */
- PORT_Memcpy(newPinStr, pPin, ulPinLen);
- newPinStr[ulPinLen] = 0;
-
- /* build the hashed pins which we pass around */
-
- /* change the data base */
- rv = sftkdb_ChangePassword(handle, NULL, newPinStr, &tokenRemoved);
- if (tokenRemoved) {
- sftk_CloseAllSessions(slot, PR_FALSE);
- }
- sftk_freeDB(handle);
- handle = NULL;
-
- /* Now update our local copy of the pin */
- if (rv == SECSuccess) {
- if (ulPinLen == 0) slot->needLogin = PR_FALSE;
- return CKR_OK;
- }
- crv = CKR_PIN_INCORRECT;
-
-loser:
- if (sp) {
- sftk_FreeSession(sp);
- }
- if (handle) {
- sftk_freeDB(handle);
- }
- return crv;
-}
-
-
-/* NSC_SetPIN modifies the PIN of user that is currently logged in. */
-/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
-CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen)
-{
- SFTKSession *sp = NULL;
- SFTKSlot *slot;
- SFTKDBHandle *handle = NULL;
- char newPinStr[SFTK_MAX_PIN+1],oldPinStr[SFTK_MAX_PIN+1];
- SECStatus rv;
- CK_RV crv = CKR_SESSION_HANDLE_INVALID;
- PRBool tokenRemoved = PR_FALSE;
-
- CHECK_FORK();
-
- sp = sftk_SessionFromHandle(hSession);
- if (sp == NULL) {
- goto loser;
- }
-
- slot = sftk_SlotFromSession(sp);
- if (!slot) {
- goto loser;
- }
-
- handle = sftk_getKeyDB(slot);
- if (handle == NULL) {
- sftk_FreeSession(sp);
- return CKR_PIN_LEN_RANGE; /* XXX FIXME wrong return value */
- }
-
- if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) {
- crv = CKR_USER_NOT_LOGGED_IN;
- goto loser;
- }
-
- sftk_FreeSession(sp);
- sp = NULL;
-
- /* make sure the pins aren't too long */
- if ((ulNewLen > SFTK_MAX_PIN) || (ulOldLen > SFTK_MAX_PIN)) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
- }
- if (ulNewLen < (CK_ULONG)slot->minimumPinLen) {
- crv = CKR_PIN_LEN_RANGE;
- goto loser;
- }
-
-
- /* convert to null terminated string */
- PORT_Memcpy(newPinStr,pNewPin,ulNewLen);
- newPinStr[ulNewLen] = 0;
- PORT_Memcpy(oldPinStr,pOldPin,ulOldLen);
- oldPinStr[ulOldLen] = 0;
-
- /* change the data base password */
- PR_Lock(slot->pwCheckLock);
- rv = sftkdb_ChangePassword(handle, oldPinStr, newPinStr, &tokenRemoved);
- if (tokenRemoved) {
- sftk_CloseAllSessions(slot, PR_FALSE);
- }
- if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
- PR_Sleep(loginWaitTime);
- }
- PR_Unlock(slot->pwCheckLock);
-
- /* Now update our local copy of the pin */
- if (rv == SECSuccess) {
- slot->needLogin = (PRBool)(ulNewLen != 0);
- /* Reset login flags. */
- if (ulNewLen == 0) {
- PRBool tokenRemoved = PR_FALSE;
- PZ_Lock(slot->slotLock);
- slot->isLoggedIn = PR_FALSE;
- slot->ssoLoggedIn = PR_FALSE;
- PZ_Unlock(slot->slotLock);
-
- rv = sftkdb_CheckPassword(handle, "", &tokenRemoved);
- if (tokenRemoved) {
- sftk_CloseAllSessions(slot, PR_FALSE);
- }
- }
- sftk_update_all_states(slot);
- sftk_freeDB(handle);
- return CKR_OK;
- }
- crv = CKR_PIN_INCORRECT;
-loser:
- if (sp) {
- sftk_FreeSession(sp);
- }
- if (handle) {
- sftk_freeDB(handle);
- }
- return crv;
-}
-
-/* NSC_OpenSession opens a session between an application and a token. */
-CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
- CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession)
-{
- SFTKSlot *slot;
- CK_SESSION_HANDLE sessionID;
- SFTKSession *session;
- SFTKSession *sameID;
-
- CHECK_FORK();
-
- slot = sftk_SlotFromID(slotID, PR_FALSE);
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
-
- /* new session (we only have serial sessions) */
- session = sftk_NewSession(slotID, Notify, pApplication,
- flags | CKF_SERIAL_SESSION);
- if (session == NULL) return CKR_HOST_MEMORY;
-
- if (slot->readOnly && (flags & CKF_RW_SESSION)) {
- /* NETSCAPE_SLOT_ID is Read ONLY */
- session->info.flags &= ~CKF_RW_SESSION;
- }
- PZ_Lock(slot->slotLock);
- ++slot->sessionCount;
- PZ_Unlock(slot->slotLock);
- if (session->info.flags & CKF_RW_SESSION) {
- PR_ATOMIC_INCREMENT(&slot->rwSessionCount);
- }
-
- do {
- PZLock *lock;
- do {
- sessionID = (PR_ATOMIC_INCREMENT(&slot->sessionIDCount) & 0xffffff)
- | (slot->index << 24);
- } while (sessionID == CK_INVALID_HANDLE);
- lock = SFTK_SESSION_LOCK(slot,sessionID);
- PZ_Lock(lock);
- sftkqueue_find(sameID, sessionID, slot->head, slot->sessHashSize);
- if (sameID == NULL) {
- session->handle = sessionID;
- sftk_update_state(slot, session);
- sftkqueue_add(session, sessionID, slot->head,slot->sessHashSize);
- } else {
- slot->sessionIDConflict++; /* for debugging */
- }
- PZ_Unlock(lock);
- } while (sameID != NULL);
-
- *phSession = sessionID;
- return CKR_OK;
-}
-
-
-/* NSC_CloseSession closes a session between an application and a token. */
-CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession)
-{
- SFTKSlot *slot;
- SFTKSession *session;
- PRBool sessionFound;
- PZLock *lock;
-
- CHECK_FORK();
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- slot = sftk_SlotFromSession(session);
- sessionFound = PR_FALSE;
-
- /* lock */
- lock = SFTK_SESSION_LOCK(slot,hSession);
- PZ_Lock(lock);
- if (sftkqueue_is_queued(session,hSession,slot->head,slot->sessHashSize)) {
- sessionFound = PR_TRUE;
- sftkqueue_delete(session,hSession,slot->head,slot->sessHashSize);
- session->refCount--; /* can't go to zero while we hold the reference */
- PORT_Assert(session->refCount > 0);
- }
- PZ_Unlock(lock);
-
- if (sessionFound) {
- SFTKDBHandle *handle;
- handle = sftk_getKeyDB(slot);
- PZ_Lock(slot->slotLock);
- if (--slot->sessionCount == 0) {
- slot->isLoggedIn = PR_FALSE;
- if (slot->needLogin && handle) {
- sftkdb_ClearPassword(handle);
- }
- }
- PZ_Unlock(slot->slotLock);
- if (handle) {
- sftk_freeDB(handle);
- }
- if (session->info.flags & CKF_RW_SESSION) {
- PR_ATOMIC_DECREMENT(&slot->rwSessionCount);
- }
- }
-
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-
-/* NSC_CloseAllSessions closes all sessions with a token. */
-CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID)
-{
- SFTKSlot *slot;
-
-#ifndef NO_FORK_CHECK
- /* skip fork check if we are being called from C_Initialize or C_Finalize */
- if (!parentForkedAfterC_Initialize) {
- CHECK_FORK();
- }
-#endif
-
- slot = sftk_SlotFromID(slotID, PR_FALSE);
- if (slot == NULL) return CKR_SLOT_ID_INVALID;
-
- return sftk_CloseAllSessions(slot, PR_TRUE);
-}
-
-
-
-/* NSC_GetSessionInfo obtains information about the session. */
-CK_RV NSC_GetSessionInfo(CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo)
-{
- SFTKSession *session;
-
- CHECK_FORK();
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
-
- PORT_Memcpy(pInfo,&session->info,sizeof(CK_SESSION_INFO));
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_Login logs a user into a token. */
-CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
- CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
-{
- SFTKSlot *slot;
- SFTKSession *session;
- SFTKDBHandle *handle;
- CK_FLAGS sessionFlags;
- SECStatus rv;
- CK_RV crv;
- char pinStr[SFTK_MAX_PIN+1];
- PRBool tokenRemoved = PR_FALSE;
-
- CHECK_FORK();
-
- /* get the slot */
- slot = sftk_SlotFromSessionHandle(hSession);
- if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /* make sure the session is valid */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- sessionFlags = session->info.flags;
- sftk_FreeSession(session);
- session = NULL;
-
- /* can't log into the Netscape Slot */
- if (slot->slotID == NETSCAPE_SLOT_ID) {
- return CKR_USER_TYPE_INVALID;
- }
-
- if (slot->isLoggedIn) return CKR_USER_ALREADY_LOGGED_IN;
- if (!slot->needLogin) {
- return ulPinLen ? CKR_PIN_INCORRECT : CKR_OK;
- }
- slot->ssoLoggedIn = PR_FALSE;
-
- if (ulPinLen > SFTK_MAX_PIN) return CKR_PIN_LEN_RANGE;
-
- /* convert to null terminated string */
- PORT_Memcpy(pinStr,pPin,ulPinLen);
- pinStr[ulPinLen] = 0;
-
- handle = sftk_getKeyDB(slot);
- if (handle == NULL) {
- return CKR_USER_TYPE_INVALID;
- }
-
- /*
- * Deal with bootstrap. We allow the SSO to login in with a NULL
- * password if and only if we haven't initialized the KEY DB yet.
- * We only allow this on a RW session.
- */
- rv = sftkdb_HasPasswordSet(handle);
- if (rv == SECFailure) {
- /* allow SSO's to log in only if there is not password on the
- * key database */
- if (((userType == CKU_SO) && (sessionFlags & CKF_RW_SESSION))
- /* fips always needs to authenticate, even if there isn't a db */
- || (slot->slotID == FIPS_SLOT_ID)) {
- /* should this be a fixed password? */
- if (ulPinLen == 0) {
- sftkdb_ClearPassword(handle);
- PZ_Lock(slot->slotLock);
- slot->isLoggedIn = PR_TRUE;
- slot->ssoLoggedIn = (PRBool)(userType == CKU_SO);
- PZ_Unlock(slot->slotLock);
- sftk_update_all_states(slot);
- crv = CKR_OK;
- goto done;
- }
- crv = CKR_PIN_INCORRECT;
- goto done;
- }
- crv = CKR_USER_TYPE_INVALID;
- goto done;
- }
-
- /* don't allow the SSO to log in if the user is already initialized */
- if (userType != CKU_USER) {
- crv = CKR_USER_TYPE_INVALID;
- goto done;
- }
-
-
- /* build the hashed pins which we pass around */
- PR_Lock(slot->pwCheckLock);
- rv = sftkdb_CheckPassword(handle,pinStr, &tokenRemoved);
- if (tokenRemoved) {
- sftk_CloseAllSessions(slot, PR_FALSE);
- }
- if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
- PR_Sleep(loginWaitTime);
- }
- PR_Unlock(slot->pwCheckLock);
- if (rv == SECSuccess) {
- PZ_Lock(slot->slotLock);
- /* make sure the login state matches the underlying
- * database state */
- slot->isLoggedIn = sftkdb_PWCached(handle) == SECSuccess ?
- PR_TRUE : PR_FALSE;
- PZ_Unlock(slot->slotLock);
-
- sftk_freeDB(handle);
- handle = NULL;
-
- /* update all sessions */
- sftk_update_all_states(slot);
- return CKR_OK;
- }
-
- crv = CKR_PIN_INCORRECT;
-done:
- if (handle) {
- sftk_freeDB(handle);
- }
- return crv;
-}
-
-/* NSC_Logout logs a user out from a token. */
-CK_RV NSC_Logout(CK_SESSION_HANDLE hSession)
-{
- SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- SFTKSession *session;
- SFTKDBHandle *handle;
-
- CHECK_FORK();
-
- if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- sftk_FreeSession(session);
- session = NULL;
-
- if (!slot->isLoggedIn) return CKR_USER_NOT_LOGGED_IN;
-
- handle = sftk_getKeyDB(slot);
- PZ_Lock(slot->slotLock);
- slot->isLoggedIn = PR_FALSE;
- slot->ssoLoggedIn = PR_FALSE;
- if (slot->needLogin && handle) {
- sftkdb_ClearPassword(handle);
- }
- PZ_Unlock(slot->slotLock);
- if (handle) {
- sftk_freeDB(handle);
- }
-
- sftk_update_all_states(slot);
- return CKR_OK;
-}
-
-/*
- * Create or remove a new slot on the fly.
- * When creating a slot, "slot" is the slot that the request came from. The
- * resulting slot will live in the same module as "slot".
- * When removing a slot, "slot" is the slot to be removed.
- * "object" is the creation object that specifies the module spec for the slot
- * to add or remove.
- */
-static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
- SFTKObject *object)
-{
- PRBool isValidUserSlot = PR_FALSE;
- PRBool isValidFIPSUserSlot = PR_FALSE;
- PRBool isValidSlot = PR_FALSE;
- PRBool isFIPS = PR_FALSE;
- unsigned long moduleIndex;
- SFTKAttribute *attribute;
- sftk_parameters paramStrings;
- char *paramString;
- CK_SLOT_ID slotID = 0;
- SFTKSlot *newSlot = NULL;
- CK_RV crv = CKR_OK;
-
- if (class != CKO_NETSCAPE_DELSLOT && class != CKO_NETSCAPE_NEWSLOT) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- if (class == CKO_NETSCAPE_NEWSLOT && slot->slotID == FIPS_SLOT_ID) {
- isFIPS = PR_TRUE;
- }
- attribute = sftk_FindAttribute(object, CKA_NETSCAPE_MODULE_SPEC);
- if (attribute == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- paramString = (char *)attribute->attrib.pValue;
- crv = sftk_parseParameters(paramString, &paramStrings, isFIPS);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- /* enforce only one at a time */
- if (paramStrings.token_count != 1) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
-
- slotID = paramStrings.tokens[0].slotID;
-
- /* stay within the valid ID space */
- isValidUserSlot = (slotID >= SFTK_MIN_USER_SLOT_ID &&
- slotID <= SFTK_MAX_USER_SLOT_ID);
- isValidFIPSUserSlot = (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID &&
- slotID <= SFTK_MAX_FIPS_USER_SLOT_ID);
-
- if (class == CKO_NETSCAPE_DELSLOT) {
- if (slot->slotID == slotID) {
- isValidSlot = isValidUserSlot || isValidFIPSUserSlot;
- }
- } else {
- /* only the crypto or FIPS slots can create new slot objects */
- if (slot->slotID == NETSCAPE_SLOT_ID) {
- isValidSlot = isValidUserSlot;
- moduleIndex = NSC_NON_FIPS_MODULE;
- } else if (slot->slotID == FIPS_SLOT_ID) {
- isValidSlot = isValidFIPSUserSlot;
- moduleIndex = NSC_FIPS_MODULE;
- }
- }
-
- if (!isValidSlot) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
-
- /* unload any existing slot at this id */
- newSlot = sftk_SlotFromID(slotID, PR_TRUE);
- if (newSlot && newSlot->present) {
- crv = SFTK_ShutdownSlot(newSlot);
- if (crv != CKR_OK) {
- goto loser;
- }
- }
-
- /* if we were just planning on deleting the slot, then do so now */
- if (class == CKO_NETSCAPE_DELSLOT) {
- /* sort of a unconventional use of this error code, be we are
- * overusing CKR_ATTRIBUTE_VALUE_INVALID, and it does apply */
- crv = newSlot ? CKR_OK : CKR_SLOT_ID_INVALID;
- goto loser; /* really exit */
- }
-
- if (newSlot) {
- crv = SFTK_SlotReInit(newSlot, paramStrings.configdir,
- paramStrings.updatedir, paramStrings.updateID,
- &paramStrings.tokens[0], moduleIndex);
- } else {
- crv = SFTK_SlotInit(paramStrings.configdir,
- paramStrings.updatedir, paramStrings.updateID,
- &paramStrings.tokens[0], moduleIndex);
- }
-
-loser:
- sftk_freeParams(&paramStrings);
- sftk_FreeAttribute(attribute);
-
- return crv;
-}
-
-
-/* NSC_CreateObject creates a new object. */
-CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject)
-{
- SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- SFTKSession *session;
- SFTKObject *object;
- /* make sure class isn't randomly CKO_NETSCAPE_NEWSLOT or
- * CKO_NETSCPE_DELSLOT. */
- CK_OBJECT_CLASS class = CKO_VENDOR_DEFINED;
- CK_RV crv;
- int i;
-
- CHECK_FORK();
-
- *phObject = CK_INVALID_HANDLE;
-
- if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- /*
- * now lets create an object to hang the attributes off of
- */
- object = sftk_NewObject(slot); /* fill in the handle later */
- if (object == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulCount; i++) {
- crv = sftk_AddAttributeType(object,sftk_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) {
- sftk_FreeObject(object);
- return crv;
- }
- if ((pTemplate[i].type == CKA_CLASS) && pTemplate[i].pValue) {
- class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
- }
- }
-
- /* get the session */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- sftk_FreeObject(object);
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /*
- * handle pseudo objects (CKO_NEWSLOT)
- */
- if ((class == CKO_NETSCAPE_NEWSLOT) || (class == CKO_NETSCAPE_DELSLOT)) {
- crv = sftk_CreateNewSlot(slot, class, object);
- goto done;
- }
-
- /*
- * handle the base object stuff
- */
- crv = sftk_handleObject(object,session);
- *phObject = object->handle;
-done:
- sftk_FreeSession(session);
- sftk_FreeObject(object);
-
- return crv;
-}
-
-
-
-/* NSC_CopyObject copies an object, creating a new object for the copy. */
-CK_RV NSC_CopyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject)
-{
- SFTKObject *destObject,*srcObject;
- SFTKSession *session;
- CK_RV crv = CKR_OK;
- SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- int i;
-
- CHECK_FORK();
-
- if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- /* Get srcObject so we can find the class */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- srcObject = sftk_ObjectFromHandle(hObject,session);
- if (srcObject == NULL) {
- sftk_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
- }
- /*
- * create an object to hang the attributes off of
- */
- destObject = sftk_NewObject(slot); /* fill in the handle later */
- if (destObject == NULL) {
- sftk_FreeSession(session);
- sftk_FreeObject(srcObject);
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulCount; i++) {
- if (sftk_modifyType(pTemplate[i].type,srcObject->objclass) == SFTK_NEVER) {
- crv = CKR_ATTRIBUTE_READ_ONLY;
- break;
- }
- crv = sftk_AddAttributeType(destObject,sftk_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) { break; }
- }
- if (crv != CKR_OK) {
- sftk_FreeSession(session);
- sftk_FreeObject(srcObject);
- sftk_FreeObject(destObject);
- return crv;
- }
-
- /* sensitive can only be changed to CK_TRUE */
- if (sftk_hasAttribute(destObject,CKA_SENSITIVE)) {
- if (!sftk_isTrue(destObject,CKA_SENSITIVE)) {
- sftk_FreeSession(session);
- sftk_FreeObject(srcObject);
- sftk_FreeObject(destObject);
- return CKR_ATTRIBUTE_READ_ONLY;
- }
- }
-
- /*
- * now copy the old attributes from the new attributes
- */
- /* don't create a token object if we aren't in a rw session */
- /* we need to hold the lock to copy a consistant version of
- * the object. */
- crv = sftk_CopyObject(destObject,srcObject);
-
- destObject->objclass = srcObject->objclass;
- sftk_FreeObject(srcObject);
- if (crv != CKR_OK) {
- sftk_FreeObject(destObject);
- sftk_FreeSession(session);
- return crv;
- }
-
- crv = sftk_handleObject(destObject,session);
- *phNewObject = destObject->handle;
- sftk_FreeSession(session);
- sftk_FreeObject(destObject);
-
- return crv;
-}
-
-
-/* NSC_GetObjectSize gets the size of an object in bytes. */
-CK_RV NSC_GetObjectSize(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize)
-{
- CHECK_FORK();
-
- *pulSize = 0;
- return CKR_OK;
-}
-
-
-/* NSC_GetAttributeValue obtains the value of one or more object attributes. */
-CK_RV NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
-{
- SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- SFTKSession *session;
- SFTKObject *object;
- SFTKAttribute *attribute;
- PRBool sensitive;
- CK_RV crv;
- int i;
-
- CHECK_FORK();
-
- if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- /*
- * make sure we're allowed
- */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /* short circuit everything for token objects */
- if (sftk_isToken(hObject)) {
- SFTKSlot *slot = sftk_SlotFromSession(session);
- SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, hObject);
- SFTKDBHandle *keydb = NULL;
-
- if (dbHandle == NULL) {
- sftk_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- crv = sftkdb_GetAttributeValue(dbHandle, hObject, pTemplate, ulCount);
-
- /* make sure we don't export any sensitive information */
- keydb = sftk_getKeyDB(slot);
- if (dbHandle == keydb) {
- for (i=0; i < (int) ulCount; i++) {
- if (sftk_isSensitive(pTemplate[i].type,CKO_PRIVATE_KEY)) {
- crv = CKR_ATTRIBUTE_SENSITIVE;
- if (pTemplate[i].pValue && (pTemplate[i].ulValueLen!= -1)){
- PORT_Memset(pTemplate[i].pValue, 0,
- pTemplate[i].ulValueLen);
- }
- pTemplate[i].ulValueLen = -1;
- }
- }
- }
-
- sftk_FreeSession(session);
- sftk_freeDB(dbHandle);
- if (keydb) {
- sftk_freeDB(keydb);
- }
- return crv;
- }
-
- /* handle the session object */
- object = sftk_ObjectFromHandle(hObject,session);
- sftk_FreeSession(session);
- if (object == NULL) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- /* don't read a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (sftk_isTrue(object,CKA_PRIVATE))) {
- sftk_FreeObject(object);
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- crv = CKR_OK;
- sensitive = sftk_isTrue(object,CKA_SENSITIVE);
- for (i=0; i < (int) ulCount; i++) {
- /* Make sure that this attribute is retrievable */
- if (sensitive && sftk_isSensitive(pTemplate[i].type,object->objclass)) {
- crv = CKR_ATTRIBUTE_SENSITIVE;
- pTemplate[i].ulValueLen = -1;
- continue;
- }
- attribute = sftk_FindAttribute(object,pTemplate[i].type);
- if (attribute == NULL) {
- crv = CKR_ATTRIBUTE_TYPE_INVALID;
- pTemplate[i].ulValueLen = -1;
- continue;
- }
- if (pTemplate[i].pValue != NULL) {
- PORT_Memcpy(pTemplate[i].pValue,attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- }
- pTemplate[i].ulValueLen = attribute->attrib.ulValueLen;
- sftk_FreeAttribute(attribute);
- }
-
- sftk_FreeObject(object);
- return crv;
-}
-
-/* NSC_SetAttributeValue modifies the value of one or more object attributes */
-CK_RV NSC_SetAttributeValue (CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
-{
- SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- SFTKSession *session;
- SFTKAttribute *attribute;
- SFTKObject *object;
- PRBool isToken;
- CK_RV crv = CKR_OK;
- CK_BBOOL legal;
- int i;
-
- CHECK_FORK();
-
- if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- /*
- * make sure we're allowed
- */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- object = sftk_ObjectFromHandle(hObject,session);
- if (object == NULL) {
- sftk_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- /* don't modify a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (sftk_isTrue(object,CKA_PRIVATE))) {
- sftk_FreeSession(session);
- sftk_FreeObject(object);
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- /* don't modify a token object if we aren't in a rw session */
- isToken = sftk_isTrue(object,CKA_TOKEN);
- if (((session->info.flags & CKF_RW_SESSION) == 0) && isToken) {
- sftk_FreeSession(session);
- sftk_FreeObject(object);
- return CKR_SESSION_READ_ONLY;
- }
- sftk_FreeSession(session);
-
- /* only change modifiable objects */
- if (!sftk_isTrue(object,CKA_MODIFIABLE)) {
- sftk_FreeObject(object);
- return CKR_ATTRIBUTE_READ_ONLY;
- }
-
- for (i=0; i < (int) ulCount; i++) {
- /* Make sure that this attribute is changeable */
- switch (sftk_modifyType(pTemplate[i].type,object->objclass)) {
- case SFTK_NEVER:
- case SFTK_ONCOPY:
- default:
- crv = CKR_ATTRIBUTE_READ_ONLY;
- break;
-
- case SFTK_SENSITIVE:
- legal = (pTemplate[i].type == CKA_EXTRACTABLE) ? CK_FALSE : CK_TRUE;
- if ((*(CK_BBOOL *)pTemplate[i].pValue) != legal) {
- crv = CKR_ATTRIBUTE_READ_ONLY;
- }
- break;
- case SFTK_ALWAYS:
- break;
- }
- if (crv != CKR_OK) break;
-
- /* find the old attribute */
- attribute = sftk_FindAttribute(object,pTemplate[i].type);
- if (attribute == NULL) {
- crv =CKR_ATTRIBUTE_TYPE_INVALID;
- break;
- }
- sftk_FreeAttribute(attribute);
- crv = sftk_forceAttribute(object,sftk_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) break;
-
- }
-
- sftk_FreeObject(object);
- return crv;
-}
-
-static CK_RV
-sftk_expandSearchList(SFTKSearchResults *search, int count)
-{
- search->array_size += count;
- search->handles = (CK_OBJECT_HANDLE *)PORT_Realloc(search->handles,
- sizeof(CK_OBJECT_HANDLE)*search->array_size);
- return search->handles ? CKR_OK : CKR_HOST_MEMORY;
-}
-
-
-
-static CK_RV
-sftk_searchDatabase(SFTKDBHandle *handle, SFTKSearchResults *search,
- const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
-{
- CK_RV crv;
- int objectListSize = search->array_size-search->size;
- CK_OBJECT_HANDLE *array = &search->handles[search->size];
- SDBFind *find;
- CK_ULONG count;
-
- crv = sftkdb_FindObjectsInit(handle, pTemplate, ulCount, &find);
- if (crv != CKR_OK)
- return crv;
- do {
- crv = sftkdb_FindObjects(handle, find, array, objectListSize, &count);
- if ((crv != CKR_OK) || (count == 0))
- break;
- search->size += count;
- objectListSize -= count;
- if (objectListSize > 0)
- break;
- crv = sftk_expandSearchList(search,NSC_SEARCH_BLOCK_SIZE);
- objectListSize = NSC_SEARCH_BLOCK_SIZE;
- array = &search->handles[search->size];
- } while (crv == CKR_OK);
- sftkdb_FindObjectsFinal(handle, find);
-
- return crv;
-}
-
-/* softoken used to search the SMimeEntries automatically instead of
- * doing this in pk11wrap. This code should really be up in
- * pk11wrap so that it will work with other tokens other than softoken.
- */
-CK_RV
-sftk_emailhack(SFTKSlot *slot, SFTKDBHandle *handle,
- SFTKSearchResults *search, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
-{
- PRBool isCert = PR_FALSE;
- int emailIndex = -1;
- int i;
- SFTKSearchResults smime_search;
- CK_ATTRIBUTE smime_template[2];
- CK_OBJECT_CLASS smime_class = CKO_NETSCAPE_SMIME;
- SFTKAttribute *attribute = NULL;
- SFTKObject *object = NULL;
- CK_RV crv = CKR_OK;
-
-
- smime_search.handles = NULL; /* paranoia, some one is bound to add a goto
- * loser before this gets initialized */
-
- /* see if we are looking for email certs */
- for (i=0; i < ulCount; i++) {
- if (pTemplate[i].type == CKA_CLASS) {
- if ((pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS) ||
- (*(CK_OBJECT_CLASS *)pTemplate[i].pValue) != CKO_CERTIFICATE)) {
- /* not a cert, skip out */
- break;
- }
- isCert = PR_TRUE;
- } else if (pTemplate[i].type == CKA_NETSCAPE_EMAIL) {
- emailIndex = i;
-
- }
- if (isCert && (emailIndex != -1)) break;
- }
-
- if (!isCert || (emailIndex == -1)) {
- return CKR_OK;
- }
-
- /* we are doing a cert and email search, find the SMimeEntry */
- smime_template[0].type = CKA_CLASS;
- smime_template[0].pValue = &smime_class;
- smime_template[0].ulValueLen = sizeof(smime_class);
- smime_template[1] = pTemplate[emailIndex];
-
- smime_search.handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
- if (smime_search.handles == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- smime_search.index = 0;
- smime_search.size = 0;
- smime_search.array_size = NSC_SEARCH_BLOCK_SIZE;
-
- crv = sftk_searchDatabase(handle, &smime_search, smime_template, 2);
- if (crv != CKR_OK || smime_search.size == 0) {
- goto loser;
- }
-
- /* get the SMime subject */
- object = sftk_NewTokenObject(slot, NULL, smime_search.handles[0]);
- if (object == NULL) {
- crv = CKR_HOST_MEMORY; /* is there any other reason for this failure? */
- goto loser;
- }
- attribute = sftk_FindAttribute(object,CKA_SUBJECT);
- if (attribute == NULL) {
- crv = CKR_ATTRIBUTE_TYPE_INVALID;
- goto loser;
- }
-
- /* now find the certs with that subject */
- pTemplate[emailIndex] = attribute->attrib;
- /* now add the appropriate certs to the search list */
- crv = sftk_searchDatabase(handle, search, pTemplate, ulCount);
- pTemplate[emailIndex] = smime_template[1]; /* restore the user's template*/
-
-loser:
- if (attribute) {
- sftk_FreeAttribute(attribute);
- }
- if (object) {
- sftk_FreeObject(object);
- }
- if (smime_search.handles) {
- PORT_Free(smime_search.handles);
- }
-
- return crv;
-}
-
-static void
-sftk_pruneSearch(CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount,
- PRBool *searchCertDB, PRBool *searchKeyDB) {
- CK_ULONG i;
-
- *searchCertDB = PR_TRUE;
- *searchKeyDB = PR_TRUE;
- for (i = 0; i < ulCount; i++) {
- if (pTemplate[i].type == CKA_CLASS && pTemplate[i].pValue != NULL) {
- CK_OBJECT_CLASS class = *((CK_OBJECT_CLASS*)pTemplate[i].pValue);
- if (class == CKO_PRIVATE_KEY || class == CKO_SECRET_KEY) {
- *searchCertDB = PR_FALSE;
- } else {
- *searchKeyDB = PR_FALSE;
- }
- break;
- }
- }
-}
-
-static CK_RV
-sftk_searchTokenList(SFTKSlot *slot, SFTKSearchResults *search,
- CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount,
- PRBool *tokenOnly, PRBool isLoggedIn)
-{
- CK_RV crv = CKR_OK;
- CK_RV crv2;
- PRBool searchCertDB;
- PRBool searchKeyDB;
-
- sftk_pruneSearch(pTemplate, ulCount, &searchCertDB, &searchKeyDB);
-
- if (searchCertDB) {
- SFTKDBHandle *certHandle = sftk_getCertDB(slot);
- crv = sftk_searchDatabase(certHandle, search, pTemplate, ulCount);
- crv2 = sftk_emailhack(slot, certHandle, search, pTemplate, ulCount);
- if (crv == CKR_OK) crv = crv2;
- sftk_freeDB(certHandle);
- }
-
- if (crv == CKR_OK && isLoggedIn && searchKeyDB) {
- SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
- crv = sftk_searchDatabase(keyHandle, search, pTemplate, ulCount);
- sftk_freeDB(keyHandle);
- }
- return crv;
-}
-
-/* NSC_FindObjectsInit initializes a search for token and session objects
- * that match a template. */
-CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
-{
- SFTKSearchResults *search = NULL, *freeSearch = NULL;
- SFTKSession *session = NULL;
- SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- PRBool tokenOnly = PR_FALSE;
- CK_RV crv = CKR_OK;
- PRBool isLoggedIn;
-
- CHECK_FORK();
-
- if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- crv = CKR_SESSION_HANDLE_INVALID;
- goto loser;
- }
-
- search = (SFTKSearchResults *)PORT_Alloc(sizeof(SFTKSearchResults));
- if (search == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- search->handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
- if (search->handles == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- search->index = 0;
- search->size = 0;
- search->array_size = NSC_SEARCH_BLOCK_SIZE;
- isLoggedIn = (PRBool)((!slot->needLogin) || slot->isLoggedIn);
-
- crv = sftk_searchTokenList(slot, search, pTemplate, ulCount, &tokenOnly,
- isLoggedIn);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- /* build list of found objects in the session */
- if (!tokenOnly) {
- crv = sftk_searchObjectList(search, slot->sessObjHashTable,
- slot->sessObjHashSize, slot->objectLock,
- pTemplate, ulCount, isLoggedIn);
- }
- if (crv != CKR_OK) {
- goto loser;
- }
-
- if ((freeSearch = session->search) != NULL) {
- session->search = NULL;
- sftk_FreeSearch(freeSearch);
- }
- session->search = search;
- sftk_FreeSession(session);
- return CKR_OK;
-
-loser:
- if (search) {
- sftk_FreeSearch(search);
- }
- if (session) {
- sftk_FreeSession(session);
- }
- return crv;
-}
-
-
-/* NSC_FindObjects continues a search for token and session objects
- * that match a template, obtaining additional object handles. */
-CK_RV NSC_FindObjects(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount)
-{
- SFTKSession *session;
- SFTKSearchResults *search;
- int transfer;
- int left;
-
- CHECK_FORK();
-
- *pulObjectCount = 0;
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- if (session->search == NULL) {
- sftk_FreeSession(session);
- return CKR_OK;
- }
- search = session->search;
- left = session->search->size - session->search->index;
- transfer = ((int)ulMaxObjectCount > left) ? left : ulMaxObjectCount;
- if (transfer > 0) {
- PORT_Memcpy(phObject,&search->handles[search->index],
- transfer*sizeof(CK_OBJECT_HANDLE));
- } else {
- *phObject = CK_INVALID_HANDLE;
- }
-
- search->index += transfer;
- if (search->index == search->size) {
- session->search = NULL;
- sftk_FreeSearch(search);
- }
- *pulObjectCount = transfer;
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_FindObjectsFinal finishes a search for token and session objects. */
-CK_RV NSC_FindObjectsFinal(CK_SESSION_HANDLE hSession)
-{
- SFTKSession *session;
- SFTKSearchResults *search;
-
- CHECK_FORK();
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- search = session->search;
- session->search = NULL;
- sftk_FreeSession(session);
- if (search != NULL) {
- sftk_FreeSearch(search);
- }
- return CKR_OK;
-}
-
-
-
-CK_RV NSC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pReserved)
-{
- CHECK_FORK();
-
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
deleted file mode 100644
index 4c2ccaa7e..000000000
--- a/security/nss/lib/softoken/pkcs11c.c
+++ /dev/null
@@ -1,6931 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file implements PKCS 11 on top of our existing security modules
- *
- * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
- * This implementation has two slots:
- * slot 1 is our generic crypto support. It does not require login.
- * It supports Public Key ops, and all they bulk ciphers and hashes.
- * It can also support Private Key ops for imported Private keys. It does
- * not have any token storage.
- * slot 2 is our private key support. It requires a login before use. It
- * can store Private Keys and Certs as token objects. Currently only private
- * keys and their associated Certificates are saved on the token.
- *
- * In this implementation, session objects are only visible to the session
- * that created or generated them.
- */
-#include "seccomon.h"
-#include "secitem.h"
-#include "secport.h"
-#include "blapi.h"
-#include "pkcs11.h"
-#include "pkcs11i.h"
-#include "lowkeyi.h"
-#include "secder.h"
-#include "secdig.h"
-#include "lowpbe.h" /* We do PBE below */
-#include "pkcs11t.h"
-#include "secoid.h"
-#include "alghmac.h"
-#include "softoken.h"
-#include "secasn1.h"
-#include "secerr.h"
-
-#include "prprf.h"
-
-#define __PASTE(x,y) x##y
-
-/*
- * we renamed all our internal functions, get the correct
- * definitions for them...
- */
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-
-#define CK_EXTERN extern
-#define CK_PKCS11_FUNCTION_INFO(func) \
- CK_RV __PASTE(NS,func)
-#define CK_NEED_ARG_LIST 1
-
-#include "pkcs11f.h"
-
-typedef struct {
- uint8 client_version[2];
- uint8 random[46];
-} SSL3RSAPreMasterSecret;
-
-static void sftk_Null(void *data, PRBool freeit)
-{
- return;
-}
-
-#ifdef NSS_ENABLE_ECC
-#ifdef EC_DEBUG
-#define SEC_PRINT(str1, str2, num, sitem) \
- printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \
- str1, str2, num, sitem->len); \
- for (i = 0; i < sitem->len; i++) { \
- printf("%02x:", sitem->data[i]); \
- } \
- printf("\n")
-#else
-#define SEC_PRINT(a, b, c, d)
-#endif
-#endif /* NSS_ENABLE_ECC */
-
-/*
- * free routines.... Free local type allocated data, and convert
- * other free routines to the destroy signature.
- */
-static void
-sftk_FreePrivKey(NSSLOWKEYPrivateKey *key, PRBool freeit)
-{
- nsslowkey_DestroyPrivateKey(key);
-}
-
-static void
-sftk_Space(void *data, PRBool freeit)
-{
- PORT_Free(data);
-}
-
-/*
- * map all the SEC_ERROR_xxx error codes that may be returned by freebl
- * functions to CKR_xxx. return CKR_DEVICE_ERROR by default for backward
- * compatibility.
- */
-static CK_RV
-sftk_MapCryptError(int error)
-{
- switch (error) {
- case SEC_ERROR_INVALID_ARGS:
- case SEC_ERROR_BAD_DATA: /* MP_RANGE gets mapped to this */
- return CKR_ARGUMENTS_BAD;
- case SEC_ERROR_INPUT_LEN:
- return CKR_DATA_LEN_RANGE;
- case SEC_ERROR_OUTPUT_LEN:
- return CKR_BUFFER_TOO_SMALL;
- case SEC_ERROR_LIBRARY_FAILURE:
- return CKR_GENERAL_ERROR;
- case SEC_ERROR_NO_MEMORY:
- return CKR_HOST_MEMORY;
- case SEC_ERROR_BAD_SIGNATURE:
- return CKR_SIGNATURE_INVALID;
- case SEC_ERROR_INVALID_KEY:
- return CKR_KEY_SIZE_RANGE;
- case SEC_ERROR_BAD_KEY: /* an EC public key that fails validation */
- return CKR_KEY_SIZE_RANGE; /* the closest error code */
- case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM:
- return CKR_TEMPLATE_INCONSISTENT;
- /* EC functions set this error if NSS_ENABLE_ECC is not defined */
- case SEC_ERROR_UNSUPPORTED_KEYALG:
- return CKR_MECHANISM_INVALID;
- case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE:
- return CKR_DOMAIN_PARAMS_INVALID;
- /* key pair generation failed after max number of attempts */
- case SEC_ERROR_NEED_RANDOM:
- return CKR_FUNCTION_FAILED;
- }
- return CKR_DEVICE_ERROR;
-}
-
-/* used by Decrypt and UnwrapKey (indirectly) */
-static CK_RV
-sftk_MapDecryptError(int error)
-{
- switch (error) {
- case SEC_ERROR_BAD_DATA:
- return CKR_ENCRYPTED_DATA_INVALID;
- default:
- return sftk_MapCryptError(error);
- }
-}
-
-/*
- * return CKR_SIGNATURE_INVALID instead of CKR_DEVICE_ERROR by default for
- * backward compatibilty.
- */
-static CK_RV
-sftk_MapVerifyError(int error)
-{
- CK_RV crv = sftk_MapCryptError(error);
- if (crv == CKR_DEVICE_ERROR)
- crv = CKR_SIGNATURE_INVALID;
- return crv;
-}
-
-
-/*
- * turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by
- * Deprecating a full des key to 40 bit key strenth.
- */
-static CK_RV
-sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
-{
- unsigned char key1[8] = { 0xc4, 0x08, 0xb0, 0x54, 0x0b, 0xa1, 0xe0, 0xae };
- unsigned char key2[8] = { 0xef, 0x2c, 0x04, 0x1c, 0xe6, 0x38, 0x2f, 0xe6 };
- unsigned char enc_src[8];
- unsigned char enc_dest[8];
- unsigned int leng,i;
- DESContext *descx;
- SECStatus rv;
-
-
- /* zero the parity bits */
- for (i=0; i < 8; i++) {
- enc_src[i] = cdmfkey[i] & 0xfe;
- }
-
- /* encrypt with key 1 */
- descx = DES_CreateContext(key1, NULL, NSS_DES, PR_TRUE);
- if (descx == NULL) return CKR_HOST_MEMORY;
- rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8);
- DES_DestroyContext(descx,PR_TRUE);
- if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError());
-
- /* xor source with des, zero the parity bits and deprecate the key*/
- for (i=0; i < 8; i++) {
- if (i & 1) {
- enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0xfe;
- } else {
- enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0x0e;
- }
- }
-
- /* encrypt with key 2 */
- descx = DES_CreateContext(key2, NULL, NSS_DES, PR_TRUE);
- if (descx == NULL) return CKR_HOST_MEMORY;
- rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8);
- DES_DestroyContext(descx,PR_TRUE);
- if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError());
-
- /* set the corret parity on our new des key */
- sftk_FormatDESKey(deskey, 8);
- return CKR_OK;
-}
-
-
-/* NSC_DestroyObject destroys an object. */
-CK_RV
-NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
-{
- SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- SFTKSession *session;
- SFTKObject *object;
- SFTKFreeStatus status;
-
- CHECK_FORK();
-
- if (slot == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- /*
- * This whole block just makes sure we really can destroy the
- * requested object.
- */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- object = sftk_ObjectFromHandle(hObject,session);
- if (object == NULL) {
- sftk_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- /* don't destroy a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (sftk_isTrue(object,CKA_PRIVATE))) {
- sftk_FreeSession(session);
- sftk_FreeObject(object);
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- /* don't destroy a token object if we aren't in a rw session */
-
- if (((session->info.flags & CKF_RW_SESSION) == 0) &&
- (sftk_isTrue(object,CKA_TOKEN))) {
- sftk_FreeSession(session);
- sftk_FreeObject(object);
- return CKR_SESSION_READ_ONLY;
- }
-
- sftk_DeleteObject(session,object);
-
- sftk_FreeSession(session);
-
- /*
- * get some indication if the object is destroyed. Note: this is not
- * 100%. Someone may have an object reference outstanding (though that
- * should not be the case by here. Also note that the object is "half"
- * destroyed. Our internal representation is destroyed, but it may still
- * be in the data base.
- */
- status = sftk_FreeObject(object);
-
- return (status != SFTK_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR;
-}
-
-
-/*
- ************** Crypto Functions: Utilities ************************
- */
-
-
-/*
- * return a context based on the SFTKContext type.
- */
-SFTKSessionContext *
-sftk_ReturnContextByType(SFTKSession *session, SFTKContextType type)
-{
- switch (type) {
- case SFTK_ENCRYPT:
- case SFTK_DECRYPT:
- return session->enc_context;
- case SFTK_HASH:
- return session->hash_context;
- case SFTK_SIGN:
- case SFTK_SIGN_RECOVER:
- case SFTK_VERIFY:
- case SFTK_VERIFY_RECOVER:
- return session->hash_context;
- }
- return NULL;
-}
-
-/*
- * change a context based on the SFTKContext type.
- */
-void
-sftk_SetContextByType(SFTKSession *session, SFTKContextType type,
- SFTKSessionContext *context)
-{
- switch (type) {
- case SFTK_ENCRYPT:
- case SFTK_DECRYPT:
- session->enc_context = context;
- break;
- case SFTK_HASH:
- session->hash_context = context;
- break;
- case SFTK_SIGN:
- case SFTK_SIGN_RECOVER:
- case SFTK_VERIFY:
- case SFTK_VERIFY_RECOVER:
- session->hash_context = context;
- break;
- }
- return;
-}
-
-/*
- * code to grab the context. Needed by every C_XXXUpdate, C_XXXFinal,
- * and C_XXX function. The function takes a session handle, the context type,
- * and wether or not the session needs to be multipart. It returns the context,
- * and optionally returns the session pointer (if sessionPtr != NULL) if session
- * pointer is returned, the caller is responsible for freeing it.
- */
-static CK_RV
-sftk_GetContext(CK_SESSION_HANDLE handle,SFTKSessionContext **contextPtr,
- SFTKContextType type, PRBool needMulti, SFTKSession **sessionPtr)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
-
- session = sftk_SessionFromHandle(handle);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- context = sftk_ReturnContextByType(session,type);
- /* make sure the context is valid */
- if((context==NULL)||(context->type!=type)||(needMulti&&!(context->multi))){
- sftk_FreeSession(session);
- return CKR_OPERATION_NOT_INITIALIZED;
- }
- *contextPtr = context;
- if (sessionPtr != NULL) {
- *sessionPtr = session;
- } else {
- sftk_FreeSession(session);
- }
- return CKR_OK;
-}
-
-/** Terminate operation (in the PKCS#11 spec sense).
- * Intuitive name for FreeContext/SetNullContext pair.
- */
-static void
-sftk_TerminateOp( SFTKSession *session, SFTKContextType ctype,
- SFTKSessionContext *context )
-{
- sftk_FreeContext( context );
- sftk_SetContextByType( session, ctype, NULL );
-}
-
-/*
- ************** Crypto Functions: Encrypt ************************
- */
-
-/*
- * All the NSC_InitXXX functions have a set of common checks and processing they
- * all need to do at the beginning. This is done here.
- */
-static CK_RV
-sftk_InitGeneric(SFTKSession *session,SFTKSessionContext **contextPtr,
- SFTKContextType ctype,SFTKObject **keyPtr,
- CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr,
- CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation)
-{
- SFTKObject *key = NULL;
- SFTKAttribute *att;
- SFTKSessionContext *context;
-
- /* We can only init if there is not current context active */
- if (sftk_ReturnContextByType(session,ctype) != NULL) {
- return CKR_OPERATION_ACTIVE;
- }
-
- /* find the key */
- if (keyPtr) {
- key = sftk_ObjectFromHandle(hKey,session);
- if (key == NULL) {
- return CKR_KEY_HANDLE_INVALID;
- }
-
- /* make sure it's a valid key for this operation */
- if (((key->objclass != CKO_SECRET_KEY) && (key->objclass != pubKeyType))
- || !sftk_isTrue(key,operation)) {
- sftk_FreeObject(key);
- return CKR_KEY_TYPE_INCONSISTENT;
- }
- /* get the key type */
- att = sftk_FindAttribute(key,CKA_KEY_TYPE);
- if (att == NULL) {
- sftk_FreeObject(key);
- return CKR_KEY_TYPE_INCONSISTENT;
- }
- PORT_Assert(att->attrib.ulValueLen == sizeof(CK_KEY_TYPE));
- if (att->attrib.ulValueLen != sizeof(CK_KEY_TYPE)) {
- sftk_FreeAttribute(att);
- sftk_FreeObject(key);
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- PORT_Memcpy(keyTypePtr, att->attrib.pValue, sizeof(CK_KEY_TYPE));
- sftk_FreeAttribute(att);
- *keyPtr = key;
- }
-
- /* allocate the context structure */
- context = (SFTKSessionContext *)PORT_Alloc(sizeof(SFTKSessionContext));
- if (context == NULL) {
- if (key) sftk_FreeObject(key);
- return CKR_HOST_MEMORY;
- }
- context->type = ctype;
- context->multi = PR_TRUE;
- context->rsa = PR_FALSE;
- context->cipherInfo = NULL;
- context->hashInfo = NULL;
- context->doPad = PR_FALSE;
- context->padDataLength = 0;
- context->key = key;
- context->blockSize = 0;
- context->maxLen = 0;
-
- *contextPtr = context;
- return CKR_OK;
-}
-
-static int
-sftk_aes_mode(CK_MECHANISM_TYPE mechanism)
-{
- switch (mechanism) {
- case CKM_AES_CBC_PAD:
- case CKM_AES_CBC:
- return NSS_AES_CBC;
- case CKM_AES_ECB:
- return NSS_AES;
- case CKM_AES_CTS:
- return NSS_AES_CTS;
- case CKM_AES_CTR:
- return NSS_AES_CTR;
- case CKM_AES_GCM:
- return NSS_AES_GCM;
- }
- return -1;
-}
-
-static SECStatus
-sftk_EncryptOAEP(SFTKOAEPEncryptInfo *info, unsigned char *output,
- unsigned int *outputLen, unsigned int maxLen,
- unsigned char *input, unsigned int inputLen)
-{
- return RSA_EncryptOAEP(info->params, info->key, output, outputLen,
- maxLen, input, inputLen);
-}
-
-static SECStatus
-sftk_DecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output,
- unsigned int *outputLen, unsigned int maxLen,
- unsigned char *input, unsigned int inputLen)
-{
- return RSA_DecryptOAEP(info->params, info->key, output, outputLen,
- maxLen, input, inputLen);
-}
-
-/** NSC_CryptInit initializes an encryption/Decryption operation.
- *
- * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
- * Called by NSC_SignInit, NSC_VerifyInit (via sftk_InitCBCMac) only for block
- * ciphers MAC'ing.
- */
-static CK_RV
-sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey,
- CK_ATTRIBUTE_TYPE mechUsage, CK_ATTRIBUTE_TYPE keyUsage,
- SFTKContextType contextType, PRBool isEncrypt)
-{
- SFTKSession *session;
- SFTKObject *key;
- SFTKSessionContext *context;
- SFTKAttribute *att;
- CK_RC2_CBC_PARAMS *rc2_param;
-#if NSS_SOFTOKEN_DOES_RC5
- CK_RC5_CBC_PARAMS *rc5_param;
- SECItem rc5Key;
-#endif
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- unsigned effectiveKeyLength;
- unsigned char newdeskey[24];
- PRBool useNewKey=PR_FALSE;
- int t;
-
- crv = sftk_MechAllowsOperation(pMechanism->mechanism, mechUsage );
- if (crv != CKR_OK)
- return crv;
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
-
- crv = sftk_InitGeneric(session,&context,contextType,&key,hKey,&key_type,
- isEncrypt ?CKO_PUBLIC_KEY:CKO_PRIVATE_KEY, keyUsage);
-
- if (crv != CKR_OK) {
- sftk_FreeSession(session);
- return crv;
- }
-
- context->doPad = PR_FALSE;
- switch(pMechanism->mechanism) {
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- context->rsa = PR_TRUE;
- if (isEncrypt) {
- NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
- if (pubKey == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->maxLen = nsslowkey_PublicModulusLen(pubKey);
- context->cipherInfo = (void *)pubKey;
- context->update = (SFTKCipher)
- (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_EncryptRaw : RSA_EncryptBlock);
- } else {
- NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv);
- if (privKey == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->maxLen = nsslowkey_PrivateModulusLen(privKey);
- context->cipherInfo = (void *)privKey;
- context->update = (SFTKCipher)
- (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_DecryptRaw : RSA_DecryptBlock);
- }
- context->destroy = sftk_Null;
- break;
-/* XXX: Disabled until unit tests land.
- case CKM_RSA_PKCS_OAEP:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- context->rsa = PR_TRUE;
- if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS)) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- /\* XXX: Need Parameter validation here *\/
- if (isEncrypt) {
- SFTKOAEPEncryptInfo *info = PORT_New(SFTKOAEPEncryptInfo);
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->params = pMechanism->pParameter;
- info->key = sftk_GetPubKey(key, CKK_RSA, &crv);
- if (info->key == NULL) {
- PORT_Free(info);
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->update = (SFTKCipher) sftk_EncryptOAEP;
- context->maxLen = nsslowkey_PublicModulusLen(info->key);
- context->cipherInfo = info;
- } else {
- SFTKOAEPDecryptInfo *info = PORT_New(SFTKOAEPDecryptInfo);
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->params = pMechanism->pParameter;
- info->key = sftk_GetPrivKey(key, CKK_RSA, &crv);
- if (info->key == NULL) {
- PORT_Free(info);
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->update = (SFTKCipher) sftk_DecryptOAEP;
- context->maxLen = nsslowkey_PrivateModulusLen(info->key);
- context->cipherInfo = info;
- }
- context->destroy = (SFTKDestroy) sftk_Space;
- break;
-*/
- case CKM_RC2_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- context->blockSize = 8;
- if (key_type != CKK_RC2) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = sftk_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
- effectiveKeyLength = (rc2_param->ulEffectiveBits+7)/8;
- context->cipherInfo =
- RC2_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen, rc2_param->iv,
- pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 :
- NSS_RC2_CBC,effectiveKeyLength);
- sftk_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (SFTKCipher) (isEncrypt ? RC2_Encrypt : RC2_Decrypt);
- context->destroy = (SFTKDestroy) RC2_DestroyContext;
- break;
-#if NSS_SOFTOKEN_DOES_RC5
- case CKM_RC5_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_RC5_ECB:
- case CKM_RC5_CBC:
- if (key_type != CKK_RC5) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = sftk_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
- context->blockSize = rc5_param->ulWordsize*2;
- rc5Key.data = (unsigned char*)att->attrib.pValue;
- rc5Key.len = att->attrib.ulValueLen;
- context->cipherInfo = RC5_CreateContext(&rc5Key,rc5_param->ulRounds,
- rc5_param->ulWordsize,rc5_param->pIv,
- pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC);
- sftk_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (SFTKCipher) (isEncrypt ? RC5_Encrypt : RC5_Decrypt);
- context->destroy = (SFTKDestroy) RC5_DestroyContext;
- break;
-#endif
- case CKM_RC4:
- if (key_type != CKK_RC4) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = sftk_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->cipherInfo =
- RC4_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- sftk_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY; /* WRONG !!! */
- break;
- }
- context->update = (SFTKCipher) (isEncrypt ? RC4_Encrypt : RC4_Decrypt);
- context->destroy = (SFTKDestroy) RC4_DestroyContext;
- break;
- case CKM_CDMF_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_CDMF_ECB:
- case CKM_CDMF_CBC:
- if (key_type != CKK_CDMF) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
- if (crv != CKR_OK) break;
- goto finish_des;
- case CKM_DES_ECB:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES;
- goto finish_des;
- case CKM_DES_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_DES_CBC:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_CBC;
- goto finish_des;
- case CKM_DES3_ECB:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3;
- goto finish_des;
- case CKM_DES3_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_DES3_CBC:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3_CBC;
-finish_des:
- context->blockSize = 8;
- att = sftk_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- if (key_type == CKK_DES2 &&
- (t == NSS_DES_EDE3_CBC || t == NSS_DES_EDE3)) {
- /* extend DES2 key to DES3 key. */
- memcpy(newdeskey, att->attrib.pValue, 16);
- memcpy(newdeskey + 16, newdeskey, 8);
- useNewKey=PR_TRUE;
- } else if (key_type == CKK_CDMF) {
- crv = sftk_cdmf2des((unsigned char*)att->attrib.pValue,newdeskey);
- if (crv != CKR_OK) {
- sftk_FreeAttribute(att);
- break;
- }
- useNewKey=PR_TRUE;
- }
- context->cipherInfo = DES_CreateContext(
- useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,t, isEncrypt);
- if (useNewKey)
- memset(newdeskey, 0, sizeof newdeskey);
- sftk_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (SFTKCipher) (isEncrypt ? DES_Encrypt : DES_Decrypt);
- context->destroy = (SFTKDestroy) DES_DestroyContext;
- break;
- case CKM_SEED_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_SEED_CBC:
- if (!pMechanism->pParameter ||
- pMechanism->ulParameterLen != 16) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- /* fall thru */
- case CKM_SEED_ECB:
- context->blockSize = 16;
- if (key_type != CKK_SEED) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = sftk_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->cipherInfo = SEED_CreateContext(
- (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,
- pMechanism->mechanism == CKM_SEED_ECB ? NSS_SEED : NSS_SEED_CBC,
- isEncrypt);
- sftk_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (SFTKCipher)(isEncrypt ? SEED_Encrypt : SEED_Decrypt);
- context->destroy = (SFTKDestroy) SEED_DestroyContext;
- break;
-
- case CKM_CAMELLIA_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_CAMELLIA_CBC:
- if (!pMechanism->pParameter ||
- pMechanism->ulParameterLen != 16) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- /* fall thru */
- case CKM_CAMELLIA_ECB:
- context->blockSize = 16;
- if (key_type != CKK_CAMELLIA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = sftk_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->cipherInfo = Camellia_CreateContext(
- (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,
- pMechanism->mechanism ==
- CKM_CAMELLIA_ECB ? NSS_CAMELLIA : NSS_CAMELLIA_CBC,
- isEncrypt, att->attrib.ulValueLen);
- sftk_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (SFTKCipher) (isEncrypt ?
- Camellia_Encrypt : Camellia_Decrypt);
- context->destroy = (SFTKDestroy) Camellia_DestroyContext;
- break;
-
- case CKM_AES_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_AES_ECB:
- case CKM_AES_CBC:
- context->blockSize = 16;
- case CKM_AES_CTS:
- case CKM_AES_CTR:
- case CKM_AES_GCM:
- if (pMechanism->mechanism == CKM_AES_GCM) {
- context->multi = PR_FALSE;
- }
- if (key_type != CKK_AES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = sftk_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->cipherInfo = AES_CreateContext(
- (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,
- sftk_aes_mode(pMechanism->mechanism),
- isEncrypt, att->attrib.ulValueLen, 16);
- sftk_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (SFTKCipher) (isEncrypt ? AES_Encrypt : AES_Decrypt);
- context->destroy = (SFTKDestroy) AES_DestroyContext;
- break;
-
- case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_NETSCAPE_AES_KEY_WRAP:
- context->multi = PR_FALSE;
- context->blockSize = 8;
- if (key_type != CKK_AES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = sftk_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->cipherInfo = AESKeyWrap_CreateContext(
- (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,
- isEncrypt, att->attrib.ulValueLen);
- sftk_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (SFTKCipher) (isEncrypt ? AESKeyWrap_Encrypt
- : AESKeyWrap_Decrypt);
- context->destroy = (SFTKDestroy) AESKeyWrap_DestroyContext;
- break;
-
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- if (crv != CKR_OK) {
- sftk_FreeContext(context);
- sftk_FreeSession(session);
- return crv;
- }
- sftk_SetContextByType(session, contextType, context);
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_EncryptInit initializes an encryption operation. */
-CK_RV NSC_EncryptInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
-{
- CHECK_FORK();
- return sftk_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT, CKA_ENCRYPT,
- SFTK_ENCRYPT, PR_TRUE);
-}
-
-/* NSC_EncryptUpdate continues a multiple-part encryption operation. */
-CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen)
-{
- SFTKSessionContext *context;
- unsigned int outlen,i;
- unsigned int padoutlen = 0;
- unsigned int maxout = *pulEncryptedPartLen;
- CK_RV crv;
- SECStatus rv;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,NULL);
- if (crv != CKR_OK) return crv;
-
- if (!pEncryptedPart) {
- if (context->doPad) {
- CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength;
- CK_ULONG blocksToSend = totalDataAvailable/context->blockSize;
-
- *pulEncryptedPartLen = blocksToSend * context->blockSize;
- return CKR_OK;
- }
- *pulEncryptedPartLen = ulPartLen;
- return CKR_OK;
- }
-
- /* do padding */
- if (context->doPad) {
- /* deal with previous buffered data */
- if (context->padDataLength != 0) {
- /* fill in the padded to a full block size */
- for (i=context->padDataLength;
- (ulPartLen != 0) && i < context->blockSize; i++) {
- context->padBuf[i] = *pPart++;
- ulPartLen--;
- context->padDataLength++;
- }
-
- /* not enough data to encrypt yet? then return */
- if (context->padDataLength != context->blockSize) {
- *pulEncryptedPartLen = 0;
- return CKR_OK;
- }
- /* encrypt the current padded data */
- rv = (*context->update)(context->cipherInfo, pEncryptedPart,
- &padoutlen, context->blockSize, context->padBuf,
- context->blockSize);
- if (rv != SECSuccess) {
- return sftk_MapCryptError(PORT_GetError());
- }
- pEncryptedPart += padoutlen;
- maxout -= padoutlen;
- }
- /* save the residual */
- context->padDataLength = ulPartLen % context->blockSize;
- if (context->padDataLength) {
- PORT_Memcpy(context->padBuf,
- &pPart[ulPartLen-context->padDataLength],
- context->padDataLength);
- ulPartLen -= context->padDataLength;
- }
- /* if we've exhausted our new buffer, we're done */
- if (ulPartLen == 0) {
- *pulEncryptedPartLen = padoutlen;
- return CKR_OK;
- }
- }
-
-
- /* do it: NOTE: this assumes buf size in is >= buf size out! */
- rv = (*context->update)(context->cipherInfo,pEncryptedPart,
- &outlen, maxout, pPart, ulPartLen);
- *pulEncryptedPartLen = (CK_ULONG) (outlen + padoutlen);
- return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
-}
-
-
-/* NSC_EncryptFinal finishes a multiple-part encryption operation. */
-CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- unsigned int outlen,i;
- unsigned int maxout = *pulLastEncryptedPartLen;
- CK_RV crv;
- SECStatus rv = SECSuccess;
- PRBool contextFinished = PR_TRUE;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
-
- *pulLastEncryptedPartLen = 0;
- if (!pLastEncryptedPart) {
- /* caller is checking the amount of remaining data */
- if (context->blockSize > 0 && context->doPad) {
- *pulLastEncryptedPartLen = context->blockSize;
- contextFinished = PR_FALSE; /* still have padding to go */
- }
- goto finish;
- }
-
- /* do padding */
- if (context->doPad) {
- unsigned char padbyte = (unsigned char)
- (context->blockSize - context->padDataLength);
- /* fill out rest of pad buffer with pad magic*/
- for (i=context->padDataLength; i < context->blockSize; i++) {
- context->padBuf[i] = padbyte;
- }
- rv = (*context->update)(context->cipherInfo,pLastEncryptedPart,
- &outlen, maxout, context->padBuf, context->blockSize);
- if (rv == SECSuccess) *pulLastEncryptedPartLen = (CK_ULONG) outlen;
- }
-
-finish:
- if (contextFinished)
- sftk_TerminateOp( session, SFTK_ENCRYPT, context );
- sftk_FreeSession(session);
- return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
-}
-
-/* NSC_Encrypt encrypts single-part data. */
-CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- unsigned int outlen;
- unsigned int maxoutlen = *pulEncryptedDataLen;
- CK_RV crv;
- CK_RV crv2;
- SECStatus rv = SECSuccess;
- SECItem pText;
-
- pText.type = siBuffer;
- pText.data = pData;
- pText.len = ulDataLen;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- if (!pEncryptedData) {
- *pulEncryptedDataLen = context->rsa ? context->maxLen :
- ulDataLen + 2 * context->blockSize;
- goto finish;
- }
-
- if (context->doPad) {
- if (context->multi) {
- CK_ULONG finalLen;
- /* padding is fairly complicated, have the update and final
- * code deal with it */
- sftk_FreeSession(session);
- crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData,
- pulEncryptedDataLen);
- if (crv != CKR_OK)
- *pulEncryptedDataLen = 0;
- maxoutlen -= *pulEncryptedDataLen;
- pEncryptedData += *pulEncryptedDataLen;
- finalLen = maxoutlen;
- crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen);
- if (crv2 == CKR_OK)
- *pulEncryptedDataLen += finalLen;
- return crv == CKR_OK ? crv2 : crv;
- }
- /* doPad without multi means that padding must be done on the first
- ** and only update. There will be no final.
- */
- PORT_Assert(context->blockSize > 1);
- if (context->blockSize > 1) {
- CK_ULONG remainder = ulDataLen % context->blockSize;
- CK_ULONG padding = context->blockSize - remainder;
- pText.len += padding;
- pText.data = PORT_ZAlloc(pText.len);
- if (pText.data) {
- memcpy(pText.data, pData, ulDataLen);
- memset(pText.data + ulDataLen, padding, padding);
- } else {
- crv = CKR_HOST_MEMORY;
- goto fail;
- }
- }
- }
-
- /* do it: NOTE: this assumes buf size is big enough. */
- rv = (*context->update)(context->cipherInfo, pEncryptedData,
- &outlen, maxoutlen, pText.data, pText.len);
- crv = (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
- *pulEncryptedDataLen = (CK_ULONG) outlen;
- if (pText.data != pData)
- PORT_ZFree(pText.data, pText.len);
-fail:
- sftk_TerminateOp( session, SFTK_ENCRYPT, context );
-finish:
- sftk_FreeSession(session);
-
- return crv;
-}
-
-
-/*
- ************** Crypto Functions: Decrypt ************************
- */
-
-/* NSC_DecryptInit initializes a decryption operation. */
-CK_RV NSC_DecryptInit( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
-{
- CHECK_FORK();
- return sftk_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT, CKA_DECRYPT,
- SFTK_DECRYPT, PR_FALSE);
-}
-
-/* NSC_DecryptUpdate continues a multiple-part decryption operation. */
-CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
-{
- SFTKSessionContext *context;
- unsigned int padoutlen = 0;
- unsigned int outlen;
- unsigned int maxout = *pulPartLen;
- CK_RV crv;
- SECStatus rv;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,NULL);
- if (crv != CKR_OK) return crv;
-
- /* this can only happen on an NSS programming error */
- PORT_Assert((context->padDataLength == 0)
- || context->padDataLength == context->blockSize);
-
-
- if (!pPart) {
- if (context->doPad) {
- /* we can check the data length here because if we are padding,
- * then we must be using a block cipher. In the non-padding case
- * the error will be returned by the underlying decryption
- * function when do do the actual decrypt. We need to do the
- * check here to avoid returning a negative length to the caller.
- */
- if ((ulEncryptedPartLen == 0) ||
- (ulEncryptedPartLen % context->blockSize) != 0) {
- return CKR_ENCRYPTED_DATA_LEN_RANGE;
- }
- *pulPartLen =
- ulEncryptedPartLen + context->padDataLength - context->blockSize;
- return CKR_OK;
- }
- /* for stream ciphers there is are no constraints on ulEncryptedPartLen.
- * for block ciphers, it must be a multiple of blockSize. The error is
- * detected when this function is called again do decrypt the output.
- */
- *pulPartLen = ulEncryptedPartLen;
- return CKR_OK;
- }
-
- if (context->doPad) {
- /* first decrypt our saved buffer */
- if (context->padDataLength != 0) {
- rv = (*context->update)(context->cipherInfo, pPart, &padoutlen,
- maxout, context->padBuf, context->blockSize);
- if (rv != SECSuccess) return sftk_MapDecryptError(PORT_GetError());
- pPart += padoutlen;
- maxout -= padoutlen;
- }
- /* now save the final block for the next decrypt or the final */
- PORT_Memcpy(context->padBuf,&pEncryptedPart[ulEncryptedPartLen -
- context->blockSize], context->blockSize);
- context->padDataLength = context->blockSize;
- ulEncryptedPartLen -= context->padDataLength;
- }
-
- /* do it: NOTE: this assumes buf size in is >= buf size out! */
- rv = (*context->update)(context->cipherInfo,pPart, &outlen,
- maxout, pEncryptedPart, ulEncryptedPartLen);
- *pulPartLen = (CK_ULONG) (outlen + padoutlen);
- return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
-}
-
-
-/* NSC_DecryptFinal finishes a multiple-part decryption operation. */
-CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- unsigned int outlen;
- unsigned int maxout = *pulLastPartLen;
- CK_RV crv;
- SECStatus rv = SECSuccess;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
-
- *pulLastPartLen = 0;
- if (!pLastPart) {
- /* caller is checking the amount of remaining data */
- if (context->padDataLength > 0) {
- *pulLastPartLen = context->padDataLength;
- }
- goto finish;
- }
-
- if (context->doPad) {
- /* decrypt our saved buffer */
- if (context->padDataLength != 0) {
- /* this assumes that pLastPart is big enough to hold the *whole*
- * buffer!!! */
- rv = (*context->update)(context->cipherInfo, pLastPart, &outlen,
- maxout, context->padBuf, context->blockSize);
- if (rv != SECSuccess) {
- crv = sftk_MapDecryptError(PORT_GetError());
- } else {
- unsigned int padSize =
- (unsigned int) pLastPart[context->blockSize-1];
- if ((padSize > context->blockSize) || (padSize == 0)) {
- crv = CKR_ENCRYPTED_DATA_INVALID;
- } else {
- unsigned int i;
- unsigned int badPadding = 0; /* used as a boolean */
- for (i = 0; i < padSize; i++) {
- badPadding |=
- (unsigned int) pLastPart[context->blockSize-1-i] ^
- padSize;
- }
- if (badPadding) {
- crv = CKR_ENCRYPTED_DATA_INVALID;
- } else {
- *pulLastPartLen = outlen - padSize;
- }
- }
- }
- }
- }
-
- sftk_TerminateOp( session, SFTK_DECRYPT, context );
-finish:
- sftk_FreeSession(session);
- return crv;
-}
-
-/* NSC_Decrypt decrypts encrypted data in a single part. */
-CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- unsigned int outlen;
- unsigned int maxoutlen = *pulDataLen;
- CK_RV crv;
- CK_RV crv2;
- SECStatus rv = SECSuccess;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- if (!pData) {
- *pulDataLen = ulEncryptedDataLen + context->blockSize;
- goto finish;
- }
-
- if (context->doPad && context->multi) {
- CK_ULONG finalLen;
- /* padding is fairly complicated, have the update and final
- * code deal with it */
- sftk_FreeSession(session);
- crv = NSC_DecryptUpdate(hSession,pEncryptedData,ulEncryptedDataLen,
- pData, pulDataLen);
- if (crv != CKR_OK)
- *pulDataLen = 0;
- maxoutlen -= *pulDataLen;
- pData += *pulDataLen;
- finalLen = maxoutlen;
- crv2 = NSC_DecryptFinal(hSession, pData, &finalLen);
- if (crv2 == CKR_OK)
- *pulDataLen += finalLen;
- return crv == CKR_OK ? crv2 : crv;
- }
-
- rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
- pEncryptedData, ulEncryptedDataLen);
- /* XXX need to do MUCH better error mapping than this. */
- crv = (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError());
- if (rv == SECSuccess && context->doPad) {
- unsigned int padding = pData[outlen - 1];
- if (padding > context->blockSize || !padding) {
- crv = CKR_ENCRYPTED_DATA_INVALID;
- } else {
- unsigned int i;
- unsigned int badPadding = 0; /* used as a boolean */
- for (i = 0; i < padding; i++) {
- badPadding |= (unsigned int) pData[outlen - 1 - i] ^ padding;
- }
- if (badPadding) {
- crv = CKR_ENCRYPTED_DATA_INVALID;
- } else {
- outlen -= padding;
- }
- }
- }
- *pulDataLen = (CK_ULONG) outlen;
- sftk_TerminateOp( session, SFTK_DECRYPT, context );
-finish:
- sftk_FreeSession(session);
- return crv;
-}
-
-
-
-/*
- ************** Crypto Functions: Digest (HASH) ************************
- */
-
-/* NSC_DigestInit initializes a message-digesting operation. */
-CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- CK_RV crv = CKR_OK;
-
- CHECK_FORK();
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL)
- return CKR_SESSION_HANDLE_INVALID;
- crv = sftk_InitGeneric(session,&context,SFTK_HASH,NULL,0,NULL, 0, 0);
- if (crv != CKR_OK) {
- sftk_FreeSession(session);
- return crv;
- }
-
-
-#define INIT_MECH(mech,mmm) \
- case mech: { \
- mmm ## Context * mmm ## _ctx = mmm ## _NewContext(); \
- context->cipherInfo = (void *)mmm ## _ctx; \
- context->cipherInfoLen = mmm ## _FlattenSize(mmm ## _ctx); \
- context->currentMech = mech; \
- context->hashUpdate = (SFTKHash) mmm ## _Update; \
- context->end = (SFTKEnd) mmm ## _End; \
- context->destroy = (SFTKDestroy) mmm ## _DestroyContext; \
- context->maxLen = mmm ## _LENGTH; \
- if (mmm ## _ctx) \
- mmm ## _Begin(mmm ## _ctx); \
- else \
- crv = CKR_HOST_MEMORY; \
- break; \
- }
-
- switch(pMechanism->mechanism) {
- INIT_MECH(CKM_MD2, MD2)
- INIT_MECH(CKM_MD5, MD5)
- INIT_MECH(CKM_SHA_1, SHA1)
- INIT_MECH(CKM_SHA224, SHA224)
- INIT_MECH(CKM_SHA256, SHA256)
- INIT_MECH(CKM_SHA384, SHA384)
- INIT_MECH(CKM_SHA512, SHA512)
-
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- if (crv != CKR_OK) {
- sftk_FreeContext(context);
- sftk_FreeSession(session);
- return crv;
- }
- sftk_SetContextByType(session, SFTK_HASH, context);
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-
-/* NSC_Digest digests data in a single part. */
-CK_RV NSC_Digest(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- unsigned int digestLen;
- unsigned int maxout = *pulDigestLen;
- CK_RV crv;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- if (pDigest == NULL) {
- *pulDigestLen = context->maxLen;
- goto finish;
- }
-
- /* do it: */
- (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen);
- /* NOTE: this assumes buf size is bigenough for the algorithm */
- (*context->end)(context->cipherInfo, pDigest, &digestLen,maxout);
- *pulDigestLen = digestLen;
-
- sftk_TerminateOp( session, SFTK_HASH, context );
-finish:
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-
-/* NSC_DigestUpdate continues a multiple-part message-digesting operation. */
-CK_RV NSC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen)
-{
- SFTKSessionContext *context;
- CK_RV crv;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_TRUE,NULL);
- if (crv != CKR_OK) return crv;
- /* do it: */
- (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen);
- return CKR_OK;
-}
-
-
-/* NSC_DigestFinal finishes a multiple-part message-digesting operation. */
-CK_RV NSC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- unsigned int maxout = *pulDigestLen;
- unsigned int digestLen;
- CK_RV crv;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
- if (crv != CKR_OK) return crv;
-
- if (pDigest != NULL) {
- (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout);
- *pulDigestLen = digestLen;
- sftk_TerminateOp( session, SFTK_HASH, context );
- } else {
- *pulDigestLen = context->maxLen;
- }
-
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-/*
- * these helper functions are used by Generic Macing and Signing functions
- * that use hashes as part of their operations.
- */
-#define DOSUB(mmm) \
-static CK_RV \
-sftk_doSub ## mmm(SFTKSessionContext *context) { \
- mmm ## Context * mmm ## _ctx = mmm ## _NewContext(); \
- context->hashInfo = (void *) mmm ## _ctx; \
- context->hashUpdate = (SFTKHash) mmm ## _Update; \
- context->end = (SFTKEnd) mmm ## _End; \
- context->hashdestroy = (SFTKDestroy) mmm ## _DestroyContext; \
- if (!context->hashInfo) { \
- return CKR_HOST_MEMORY; \
- } \
- mmm ## _Begin( mmm ## _ctx ); \
- return CKR_OK; \
-}
-
-DOSUB(MD2)
-DOSUB(MD5)
-DOSUB(SHA1)
-DOSUB(SHA224)
-DOSUB(SHA256)
-DOSUB(SHA384)
-DOSUB(SHA512)
-
-static SECStatus
-sftk_SignCopy(
- CK_ULONG *copyLen,
- void *out, unsigned int *outLength,
- unsigned int maxLength,
- const unsigned char *hashResult,
- unsigned int hashResultLength)
-{
- unsigned int toCopy = *copyLen;
- if (toCopy > maxLength) {
- toCopy = maxLength;
- }
- if (toCopy > hashResultLength) {
- toCopy = hashResultLength;
- }
- memcpy(out, hashResult, toCopy);
- if (outLength) {
- *outLength = toCopy;
- }
- return SECSuccess;
-}
-
-/* Verify is just a compare for HMAC */
-static SECStatus
-sftk_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen,
- unsigned char *hash, unsigned int hashLen)
-{
- return (PORT_Memcmp(sig,hash,*copyLen) == 0) ? SECSuccess : SECFailure ;
-}
-
-/*
- * common HMAC initalization routine
- */
-static CK_RV
-sftk_doHMACInit(SFTKSessionContext *context,HASH_HashType hash,
- SFTKObject *key, CK_ULONG mac_size)
-{
- SFTKAttribute *keyval;
- HMACContext *HMACcontext;
- CK_ULONG *intpointer;
- const SECHashObject *hashObj = HASH_GetRawHashObject(hash);
- PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID);
-
- /* required by FIPS 198 Section 4 */
- if (isFIPS && (mac_size < 4 || mac_size < hashObj->length/2)) {
- return CKR_BUFFER_TOO_SMALL;
- }
-
- keyval = sftk_FindAttribute(key,CKA_VALUE);
- if (keyval == NULL) return CKR_KEY_SIZE_RANGE;
-
- HMACcontext = HMAC_Create(hashObj,
- (const unsigned char*)keyval->attrib.pValue,
- keyval->attrib.ulValueLen, isFIPS);
- context->hashInfo = HMACcontext;
- context->multi = PR_TRUE;
- sftk_FreeAttribute(keyval);
- if (context->hashInfo == NULL) {
- if (PORT_GetError() == SEC_ERROR_INVALID_ARGS) {
- return CKR_KEY_SIZE_RANGE;
- }
- return CKR_HOST_MEMORY;
- }
- context->hashUpdate = (SFTKHash) HMAC_Update;
- context->end = (SFTKEnd) HMAC_Finish;
-
- context->hashdestroy = (SFTKDestroy) HMAC_Destroy;
- intpointer = PORT_New(CK_ULONG);
- if (intpointer == NULL) {
- return CKR_HOST_MEMORY;
- }
- *intpointer = mac_size;
- context->cipherInfo = intpointer;
- context->destroy = (SFTKDestroy) sftk_Space;
- context->update = (SFTKCipher) sftk_SignCopy;
- context->verify = (SFTKVerify) sftk_HMACCmp;
- context->maxLen = hashObj->length;
- HMAC_Begin(HMACcontext);
- return CKR_OK;
-}
-
-/*
- * SSL Macing support. SSL Macs are inited, then update with the base
- * hashing algorithm, then finalized in sign and verify
- */
-
-/*
- * FROM SSL:
- * 60 bytes is 3 times the maximum length MAC size that is supported.
- * We probably should have one copy of this table. We still need this table
- * in ssl to 'sign' the handshake hashes.
- */
-static unsigned char ssl_pad_1 [60] = {
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36
-};
-static unsigned char ssl_pad_2 [60] = {
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c
-};
-
-static SECStatus
-sftk_SSLMACSign(SFTKSSLMACInfo *info,unsigned char *sig,unsigned int *sigLen,
- unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
-{
- unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH];
- unsigned int out;
-
- info->begin(info->hashContext);
- info->update(info->hashContext,info->key,info->keySize);
- info->update(info->hashContext,ssl_pad_2,info->padSize);
- info->update(info->hashContext,hash,hashLen);
- info->end(info->hashContext,tmpBuf,&out,SFTK_MAX_MAC_LENGTH);
- PORT_Memcpy(sig,tmpBuf,info->macSize);
- *sigLen = info->macSize;
- return SECSuccess;
-}
-
-static SECStatus
-sftk_SSLMACVerify(SFTKSSLMACInfo *info,unsigned char *sig,unsigned int sigLen,
- unsigned char *hash, unsigned int hashLen)
-{
- unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH];
- unsigned int out;
-
- info->begin(info->hashContext);
- info->update(info->hashContext,info->key,info->keySize);
- info->update(info->hashContext,ssl_pad_2,info->padSize);
- info->update(info->hashContext,hash,hashLen);
- info->end(info->hashContext,tmpBuf,&out,SFTK_MAX_MAC_LENGTH);
- return (PORT_Memcmp(sig,tmpBuf,info->macSize) == 0) ?
- SECSuccess : SECFailure;
-}
-
-/*
- * common HMAC initalization routine
- */
-static CK_RV
-sftk_doSSLMACInit(SFTKSessionContext *context,SECOidTag oid,
- SFTKObject *key, CK_ULONG mac_size)
-{
- SFTKAttribute *keyval;
- SFTKBegin begin;
- int padSize;
- SFTKSSLMACInfo *sslmacinfo;
- CK_RV crv = CKR_MECHANISM_INVALID;
-
- if (oid == SEC_OID_SHA1) {
- crv = sftk_doSubSHA1(context);
- if (crv != CKR_OK) return crv;
- begin = (SFTKBegin) SHA1_Begin;
- padSize = 40;
- } else {
- crv = sftk_doSubMD5(context);
- if (crv != CKR_OK) return crv;
- begin = (SFTKBegin) MD5_Begin;
- padSize = 48;
- }
- context->multi = PR_TRUE;
-
- keyval = sftk_FindAttribute(key,CKA_VALUE);
- if (keyval == NULL) return CKR_KEY_SIZE_RANGE;
-
- context->hashUpdate(context->hashInfo,keyval->attrib.pValue,
- keyval->attrib.ulValueLen);
- context->hashUpdate(context->hashInfo,ssl_pad_1,padSize);
- sslmacinfo = (SFTKSSLMACInfo *) PORT_Alloc(sizeof(SFTKSSLMACInfo));
- if (sslmacinfo == NULL) {
- sftk_FreeAttribute(keyval);
- return CKR_HOST_MEMORY;
- }
- sslmacinfo->macSize = mac_size;
- sslmacinfo->hashContext = context->hashInfo;
- PORT_Memcpy(sslmacinfo->key,keyval->attrib.pValue,
- keyval->attrib.ulValueLen);
- sslmacinfo->keySize = keyval->attrib.ulValueLen;
- sslmacinfo->begin = begin;
- sslmacinfo->end = context->end;
- sslmacinfo->update = context->hashUpdate;
- sslmacinfo->padSize = padSize;
- sftk_FreeAttribute(keyval);
- context->cipherInfo = (void *) sslmacinfo;
- context->destroy = (SFTKDestroy) sftk_Space;
- context->update = (SFTKCipher) sftk_SSLMACSign;
- context->verify = (SFTKVerify) sftk_SSLMACVerify;
- context->maxLen = mac_size;
- return CKR_OK;
-}
-
-/*
- ************** Crypto Functions: Sign ************************
- */
-
-/**
- * Check if We're using CBCMacing and initialize the session context if we are.
- * @param contextType SFTK_SIGN or SFTK_VERIFY
- * @param keyUsage check whether key allows this usage
- */
-static CK_RV
-sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage,
- SFTKContextType contextType)
-
-{
- CK_MECHANISM cbc_mechanism;
- CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE;
- CK_RC2_CBC_PARAMS rc2_params;
-#if NSS_SOFTOKEN_DOES_RC5
- CK_RC5_CBC_PARAMS rc5_params;
- CK_RC5_MAC_GENERAL_PARAMS *rc5_mac;
-#endif
- unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE];
- SFTKSessionContext *context;
- CK_RV crv;
- unsigned int blockSize;
-
- switch (pMechanism->mechanism) {
- case CKM_RC2_MAC_GENERAL:
- mac_bytes =
- ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
- /* fall through */
- case CKM_RC2_MAC:
- /* this works because ulEffectiveBits is in the same place in both the
- * CK_RC2_MAC_GENERAL_PARAMS and CK_RC2_CBC_PARAMS */
- rc2_params.ulEffectiveBits = ((CK_RC2_MAC_GENERAL_PARAMS *)
- pMechanism->pParameter)->ulEffectiveBits;
- PORT_Memset(rc2_params.iv,0,sizeof(rc2_params.iv));
- cbc_mechanism.mechanism = CKM_RC2_CBC;
- cbc_mechanism.pParameter = &rc2_params;
- cbc_mechanism.ulParameterLen = sizeof(rc2_params);
- blockSize = 8;
- break;
-#if NSS_SOFTOKEN_DOES_RC5
- case CKM_RC5_MAC_GENERAL:
- mac_bytes =
- ((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength;
- /* fall through */
- case CKM_RC5_MAC:
- /* this works because ulEffectiveBits is in the same place in both the
- * CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */
- rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter;
- rc5_params.ulWordsize = rc5_mac->ulWordsize;
- rc5_params.ulRounds = rc5_mac->ulRounds;
- rc5_params.pIv = ivBlock;
- if( (blockSize = rc5_mac->ulWordsize*2) > SFTK_MAX_BLOCK_SIZE )
- return CKR_MECHANISM_PARAM_INVALID;
- rc5_params.ulIvLen = blockSize;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_RC5_CBC;
- cbc_mechanism.pParameter = &rc5_params;
- cbc_mechanism.ulParameterLen = sizeof(rc5_params);
- break;
-#endif
- /* add cast and idea later */
- case CKM_DES_MAC_GENERAL:
- mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
- /* fall through */
- case CKM_DES_MAC:
- blockSize = 8;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_DES_CBC;
- cbc_mechanism.pParameter = &ivBlock;
- cbc_mechanism.ulParameterLen = blockSize;
- break;
- case CKM_DES3_MAC_GENERAL:
- mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
- /* fall through */
- case CKM_DES3_MAC:
- blockSize = 8;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_DES3_CBC;
- cbc_mechanism.pParameter = &ivBlock;
- cbc_mechanism.ulParameterLen = blockSize;
- break;
- case CKM_CDMF_MAC_GENERAL:
- mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
- /* fall through */
- case CKM_CDMF_MAC:
- blockSize = 8;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_CDMF_CBC;
- cbc_mechanism.pParameter = &ivBlock;
- cbc_mechanism.ulParameterLen = blockSize;
- break;
- case CKM_SEED_MAC_GENERAL:
- mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
- /* fall through */
- case CKM_SEED_MAC:
- blockSize = 16;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_SEED_CBC;
- cbc_mechanism.pParameter = &ivBlock;
- cbc_mechanism.ulParameterLen = blockSize;
- break;
- case CKM_CAMELLIA_MAC_GENERAL:
- mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
- /* fall through */
- case CKM_CAMELLIA_MAC:
- blockSize = 16;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_CAMELLIA_CBC;
- cbc_mechanism.pParameter = &ivBlock;
- cbc_mechanism.ulParameterLen = blockSize;
- break;
- case CKM_AES_MAC_GENERAL:
- mac_bytes = *(CK_ULONG *)pMechanism->pParameter;
- /* fall through */
- case CKM_AES_MAC:
- blockSize = 16;
- PORT_Memset(ivBlock,0,blockSize);
- cbc_mechanism.mechanism = CKM_AES_CBC;
- cbc_mechanism.pParameter = &ivBlock;
- cbc_mechanism.ulParameterLen = blockSize;
- break;
- default:
- return CKR_FUNCTION_NOT_SUPPORTED;
- }
-
- /* if MAC size is externally supplied, it should be checked.
- */
- if (mac_bytes == SFTK_INVALID_MAC_SIZE)
- mac_bytes = blockSize >> 1;
- else {
- if( mac_bytes > blockSize )
- return CKR_MECHANISM_PARAM_INVALID;
- }
-
- crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey,
- CKA_ENCRYPT, /* CBC mech is able to ENCRYPT, not SIGN/VERIFY */
- keyUsage, contextType, PR_TRUE );
- if (crv != CKR_OK) return crv;
- crv = sftk_GetContext(hSession,&context,contextType,PR_TRUE,NULL);
-
- /* this shouldn't happen! */
- PORT_Assert(crv == CKR_OK);
- if (crv != CKR_OK) return crv;
- context->blockSize = blockSize;
- context->macSize = mac_bytes;
- return CKR_OK;
-}
-
-/*
- * encode RSA PKCS #1 Signature data before signing...
- */
-static SECStatus
-sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen,
- unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
-{
- return RSA_HashSign(info->hashOid,info->key,sig,sigLen,maxLen,
- hash,hashLen);
-}
-
-/* XXX Old template; want to expunge it eventually. */
-static DERTemplate SECAlgorithmIDTemplate[] = {
- { DER_SEQUENCE,
- 0, NULL, sizeof(SECAlgorithmID) },
- { DER_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
- { DER_OPTIONAL | DER_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
-};
-
-/*
- * XXX OLD Template. Once all uses have been switched over to new one,
- * remove this.
- */
-static DERTemplate SGNDigestInfoTemplate[] = {
- { DER_SEQUENCE,
- 0, NULL, sizeof(SGNDigestInfo) },
- { DER_INLINE,
- offsetof(SGNDigestInfo,digestAlgorithm),
- SECAlgorithmIDTemplate, },
- { DER_OCTET_STRING,
- offsetof(SGNDigestInfo,digest), },
- { 0, }
-};
-
-SECStatus
-RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
- unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
- unsigned char *hash, unsigned int hashLen)
-{
-
- SECStatus rv = SECFailure;
- SECItem digder;
- PLArenaPool *arena = NULL;
- SGNDigestInfo *di = NULL;
-
- digder.data = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) { goto loser; }
-
- /* Construct digest info */
- di = SGN_CreateDigestInfo(hashOid, hash, hashLen);
- if (!di) { goto loser; }
-
- /* Der encode the digest as a DigestInfo */
- rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /*
- ** Encrypt signature after constructing appropriate PKCS#1 signature
- ** block
- */
- rv = RSA_Sign(key,sig,sigLen,maxLen,digder.data,digder.len);
-
- loser:
- SGN_DestroyDigestInfo(di);
- if (arena != NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return rv;
-}
-
-static SECStatus
-sftk_SignPSS(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen,
- unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
-{
- return RSA_SignPSS(info->params,info->key,sig,sigLen,maxLen,
- hash,hashLen);
-}
-
-static SECStatus
-nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen,
- void *dataBuf, unsigned int dataLen)
-{
- SECItem signature, digest;
- NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
-
- signature.data = (unsigned char *)sigBuf;
- signature.len = sigLen;
- digest.data = (unsigned char *)dataBuf;
- digest.len = dataLen;
- return DSA_VerifyDigest(&(key->u.dsa), &signature, &digest);
-}
-
-static SECStatus
-nsc_DSA_Sign_Stub(void *ctx, void *sigBuf,
- unsigned int *sigLen, unsigned int maxSigLen,
- void *dataBuf, unsigned int dataLen)
-{
- SECItem signature, digest;
- SECStatus rv;
- NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
-
- signature.data = (unsigned char *)sigBuf;
- signature.len = maxSigLen;
- digest.data = (unsigned char *)dataBuf;
- digest.len = dataLen;
- rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest);
- if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- *sigLen = signature.len;
- return rv;
-}
-
-#ifdef NSS_ENABLE_ECC
-static SECStatus
-nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen,
- void *dataBuf, unsigned int dataLen)
-{
- SECItem signature, digest;
- NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx;
-
- signature.data = (unsigned char *)sigBuf;
- signature.len = sigLen;
- digest.data = (unsigned char *)dataBuf;
- digest.len = dataLen;
- return ECDSA_VerifyDigest(&(key->u.ec), &signature, &digest);
-}
-
-static SECStatus
-nsc_ECDSASignStub(void *ctx, void *sigBuf,
- unsigned int *sigLen, unsigned int maxSigLen,
- void *dataBuf, unsigned int dataLen)
-{
- SECItem signature, digest;
- SECStatus rv;
- NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx;
-
- signature.data = (unsigned char *)sigBuf;
- signature.len = maxSigLen;
- digest.data = (unsigned char *)dataBuf;
- digest.len = dataLen;
- rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest);
- if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- *sigLen = signature.len;
- return rv;
-}
-#endif /* NSS_ENABLE_ECC */
-
-/* NSC_SignInit setups up the signing operations. There are three basic
- * types of signing:
- * (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
- * to data in a single Sign operation (which often looks a lot like an
- * encrypt, with data coming in and data going out).
- * (2) Hash based signing, where we continually hash the data, then apply
- * some sort of signature to the end.
- * (3) Block Encryption CBC MAC's, where the Data is encrypted with a key,
- * and only the final block is part of the mac.
- *
- * For case number 3, we initialize a context much like the Encryption Context
- * (in fact we share code). We detect case 3 in C_SignUpdate, C_Sign, and
- * C_Final by the following method... if it's not multi-part, and it's doesn't
- * have a hash context, it must be a block Encryption CBC MAC.
- *
- * For case number 2, we initialize a hash structure, as well as make it
- * multi-part. Updates are simple calls to the hash update function. Final
- * calls the hashend, then passes the result to the 'update' function (which
- * operates as a final signature function). In some hash based MAC'ing (as
- * opposed to hash base signatures), the update function is can be simply a
- * copy (as is the case with HMAC).
- */
-CK_RV NSC_SignInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
-{
- SFTKSession *session;
- SFTKObject *key;
- SFTKSessionContext *context;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- NSSLOWKEYPrivateKey *privKey;
- SFTKHashSignInfo *info = NULL;
-
- CHECK_FORK();
-
- /* Block Cipher MACing Algorithms use a different Context init method..*/
- crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN, SFTK_SIGN);
- if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv;
-
- /* we're not using a block cipher mac */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- crv = sftk_InitGeneric(session,&context,SFTK_SIGN,&key,hKey,&key_type,
- CKO_PRIVATE_KEY,CKA_SIGN);
- if (crv != CKR_OK) {
- sftk_FreeSession(session);
- return crv;
- }
-
- context->multi = PR_FALSE;
-
-#define INIT_RSA_SIGN_MECH(mmm) \
- case CKM_ ## mmm ## _RSA_PKCS: \
- context->multi = PR_TRUE; \
- crv = sftk_doSub ## mmm (context); \
- if (crv != CKR_OK) break; \
- context->update = (SFTKCipher) sftk_HashSign; \
- info = PORT_New(SFTKHashSignInfo); \
- if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \
- info->hashOid = SEC_OID_ ## mmm ; \
- goto finish_rsa;
-
- switch(pMechanism->mechanism) {
- INIT_RSA_SIGN_MECH(MD5)
- INIT_RSA_SIGN_MECH(MD2)
- INIT_RSA_SIGN_MECH(SHA1)
- INIT_RSA_SIGN_MECH(SHA224)
- INIT_RSA_SIGN_MECH(SHA256)
- INIT_RSA_SIGN_MECH(SHA384)
- INIT_RSA_SIGN_MECH(SHA512)
-
- case CKM_RSA_PKCS:
- context->update = (SFTKCipher) RSA_Sign;
- goto finish_rsa;
- case CKM_RSA_X_509:
- context->update = (SFTKCipher) RSA_SignRaw;
-finish_rsa:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->rsa = PR_TRUE;
- privKey = sftk_GetPrivKey(key,CKK_RSA,&crv);
- if (privKey == NULL) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- /* OK, info is allocated only if we're doing hash and sign mechanism.
- * It's necessary to be able to set the correct OID in the final
- * signature.
- */
- if (info) {
- info->key = privKey;
- context->cipherInfo = info;
- context->destroy = (SFTKDestroy)sftk_Space;
- } else {
- context->cipherInfo = privKey;
- context->destroy = (SFTKDestroy)sftk_Null;
- }
- context->maxLen = nsslowkey_PrivateModulusLen(privKey);
- break;
- case CKM_RSA_PKCS_PSS:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->rsa = PR_TRUE;
- if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- info = PORT_New(SFTKHashSignInfo);
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->params = pMechanism->pParameter;
- info->key = sftk_GetPrivKey(key,CKK_RSA,&crv);
- if (info->key == NULL) {
- PORT_Free(info);
- break;
- }
- context->cipherInfo = info;
- context->destroy = (SFTKDestroy) sftk_Space;
- context->update = (SFTKCipher) sftk_SignPSS;
- context->maxLen = nsslowkey_PrivateModulusLen(info->key);
- break;
-
- case CKM_DSA_SHA1:
- context->multi = PR_TRUE;
- crv = sftk_doSubSHA1(context);
- if (crv != CKR_OK) break;
- /* fall through */
- case CKM_DSA:
- if (key_type != CKK_DSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- privKey = sftk_GetPrivKey(key,CKK_DSA,&crv);
- if (privKey == NULL) {
- break;
- }
- context->cipherInfo = privKey;
- context->update = (SFTKCipher) nsc_DSA_Sign_Stub;
- context->destroy = (privKey == key->objectInfo) ?
- (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey;
- context->maxLen = DSA_MAX_SIGNATURE_LEN;
-
- break;
-
-#ifdef NSS_ENABLE_ECC
- case CKM_ECDSA_SHA1:
- context->multi = PR_TRUE;
- crv = sftk_doSubSHA1(context);
- if (crv != CKR_OK) break;
- /* fall through */
- case CKM_ECDSA:
- if (key_type != CKK_EC) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- privKey = sftk_GetPrivKey(key,CKK_EC,&crv);
- if (privKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->cipherInfo = privKey;
- context->update = (SFTKCipher) nsc_ECDSASignStub;
- context->destroy = (privKey == key->objectInfo) ?
- (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey;
- context->maxLen = MAX_ECKEY_LEN * 2;
-
- break;
-#endif /* NSS_ENABLE_ECC */
-
-#define INIT_HMAC_MECH(mmm) \
- case CKM_ ## mmm ## _HMAC_GENERAL: \
- crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, \
- *(CK_ULONG *)pMechanism->pParameter); \
- break; \
- case CKM_ ## mmm ## _HMAC: \
- crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, mmm ## _LENGTH); \
- break;
-
- INIT_HMAC_MECH(MD2)
- INIT_HMAC_MECH(MD5)
- INIT_HMAC_MECH(SHA224)
- INIT_HMAC_MECH(SHA256)
- INIT_HMAC_MECH(SHA384)
- INIT_HMAC_MECH(SHA512)
-
- case CKM_SHA_1_HMAC_GENERAL:
- crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_SHA_1_HMAC:
- crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
- break;
-
- case CKM_SSL3_MD5_MAC:
- crv = sftk_doSSLMACInit(context,SEC_OID_MD5,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_SSL3_SHA1_MAC:
- crv = sftk_doSSLMACInit(context,SEC_OID_SHA1,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_TLS_PRF_GENERAL:
- crv = sftk_TLSPRFInit(context, key, key_type);
- break;
-
- case CKM_NSS_HMAC_CONSTANT_TIME: {
- sftk_MACConstantTimeCtx *ctx =
- sftk_HMACConstantTime_New(pMechanism,key);
- CK_ULONG *intpointer;
-
- if (ctx == NULL) {
- crv = CKR_ARGUMENTS_BAD;
- break;
- }
- intpointer = PORT_New(CK_ULONG);
- if (intpointer == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- *intpointer = ctx->hash->length;
-
- context->cipherInfo = intpointer;
- context->hashInfo = ctx;
- context->currentMech = pMechanism->mechanism;
- context->hashUpdate = sftk_HMACConstantTime_Update;
- context->hashdestroy = sftk_MACConstantTime_DestroyContext;
- context->end = sftk_MACConstantTime_EndHash;
- context->update = sftk_SignCopy;
- context->destroy = sftk_Space;
- context->maxLen = 64;
- context->multi = PR_TRUE;
- break;
- }
-
- case CKM_NSS_SSL3_MAC_CONSTANT_TIME: {
- sftk_MACConstantTimeCtx *ctx =
- sftk_SSLv3MACConstantTime_New(pMechanism,key);
- CK_ULONG *intpointer;
-
- if (ctx == NULL) {
- crv = CKR_ARGUMENTS_BAD;
- break;
- }
- intpointer = PORT_New(CK_ULONG);
- if (intpointer == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- *intpointer = ctx->hash->length;
-
- context->cipherInfo = intpointer;
- context->hashInfo = ctx;
- context->currentMech = pMechanism->mechanism;
- context->hashUpdate = sftk_SSLv3MACConstantTime_Update;
- context->hashdestroy = sftk_MACConstantTime_DestroyContext;
- context->end = sftk_MACConstantTime_EndHash;
- context->update = sftk_SignCopy;
- context->destroy = sftk_Space;
- context->maxLen = 64;
- context->multi = PR_TRUE;
- break;
- }
-
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- if (crv != CKR_OK) {
- if (info) PORT_Free(info);
- sftk_FreeContext(context);
- sftk_FreeSession(session);
- return crv;
- }
- sftk_SetContextByType(session, SFTK_SIGN, context);
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-/** MAC one block of data by block cipher
- */
-static CK_RV
-sftk_MACBlock( SFTKSessionContext *ctx, void *blk )
-{
- unsigned int outlen;
- return ( SECSuccess == (ctx->update)( ctx->cipherInfo, ctx->macBuf, &outlen,
- SFTK_MAX_BLOCK_SIZE, blk, ctx->blockSize ))
- ? CKR_OK : sftk_MapCryptError(PORT_GetError());
-}
-
-/** MAC last (incomplete) block of data by block cipher
- *
- * Call once, then terminate MACing operation.
- */
-static CK_RV
-sftk_MACFinal( SFTKSessionContext *ctx )
-{
- unsigned int padLen = ctx->padDataLength;
- /* pad and proceed the residual */
- if( padLen ) {
- /* shd clr ctx->padLen to make sftk_MACFinal idempotent */
- PORT_Memset( ctx->padBuf + padLen, 0, ctx->blockSize - padLen );
- return sftk_MACBlock( ctx, ctx->padBuf );
- } else
- return CKR_OK;
-}
-
-/** The common implementation for {Sign,Verify}Update. (S/V only vary in their
- * setup and final operations).
- *
- * A call which results in an error terminates the operation [PKCS#11,v2.11]
- */
-static CK_RV
-sftk_MACUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,SFTKContextType type)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- CK_RV crv;
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,type, PR_TRUE, &session );
- if (crv != CKR_OK) return crv;
-
- if (context->hashInfo) {
- (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen);
- } else {
- /* must be block cipher MACing */
-
- unsigned int blkSize = context->blockSize;
- unsigned char *residual = /* free room in context->padBuf */
- context->padBuf + context->padDataLength;
- unsigned int minInput = /* min input for MACing at least one block */
- blkSize - context->padDataLength;
-
- /* not enough data even for one block */
- if( ulPartLen < minInput ) {
- PORT_Memcpy( residual, pPart, ulPartLen );
- context->padDataLength += ulPartLen;
- goto cleanup;
- }
- /* MACing residual */
- if( context->padDataLength ) {
- PORT_Memcpy( residual, pPart, minInput );
- ulPartLen -= minInput;
- pPart += minInput;
- if( CKR_OK != (crv = sftk_MACBlock( context, context->padBuf )) )
- goto terminate;
- }
- /* MACing full blocks */
- while( ulPartLen >= blkSize )
- {
- if( CKR_OK != (crv = sftk_MACBlock( context, pPart )) )
- goto terminate;
- ulPartLen -= blkSize;
- pPart += blkSize;
- }
- /* save the residual */
- if( (context->padDataLength = ulPartLen) )
- PORT_Memcpy( context->padBuf, pPart, ulPartLen );
- } /* blk cipher MACing */
-
- goto cleanup;
-
-terminate:
- sftk_TerminateOp( session, type, context );
-cleanup:
- sftk_FreeSession(session);
- return crv;
-}
-
-/* NSC_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature
- *
- * A call which results in an error terminates the operation [PKCS#11,v2.11]
- */
-CK_RV NSC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen)
-{
- CHECK_FORK();
- return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_SIGN);
-}
-
-
-/* NSC_SignFinal finishes a multiple-part signature operation,
- * returning the signature. */
-CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- unsigned int outlen;
- unsigned int maxoutlen = *pulSignatureLen;
- CK_RV crv;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_TRUE,&session);
- if (crv != CKR_OK) return crv;
-
- if (context->hashInfo) {
- unsigned int digestLen;
- unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH];
-
- if( !pSignature ) {
- outlen = context->maxLen; goto finish;
- }
- (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
- if( SECSuccess != (context->update)(context->cipherInfo, pSignature,
- &outlen, maxoutlen, tmpbuf, digestLen))
- crv = sftk_MapCryptError(PORT_GetError());
- /* CKR_BUFFER_TOO_SMALL here isn't continuable, let operation terminate.
- * Keeping "too small" CK_RV intact is a standard violation, but allows
- * application read EXACT signature length */
- } else {
- /* must be block cipher MACing */
- outlen = context->macSize;
- /* null or "too small" buf doesn't terminate operation [PKCS#11,v2.11]*/
- if( !pSignature || maxoutlen < outlen ) {
- if( pSignature ) crv = CKR_BUFFER_TOO_SMALL;
- goto finish;
- }
- if( CKR_OK == (crv = sftk_MACFinal( context )) )
- PORT_Memcpy(pSignature, context->macBuf, outlen );
- }
-
- sftk_TerminateOp( session, SFTK_SIGN, context );
-finish:
- *pulSignatureLen = outlen;
- sftk_FreeSession(session);
- return crv;
-}
-
-/* NSC_Sign signs (encrypts with private key) data in a single part,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-CK_RV NSC_Sign(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- CK_RV crv;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- if (!pSignature) {
- /* see also how C_SignUpdate implements this */
- *pulSignatureLen = (!context->multi || context->hashInfo)
- ? context->maxLen
- : context->macSize; /* must be block cipher MACing */
- goto finish;
- }
-
- /* multi part Signing are completely implemented by SignUpdate and
- * sign Final */
- if (context->multi) {
- /* SignFinal can't follow failed SignUpdate */
- if( CKR_OK == (crv = NSC_SignUpdate(hSession,pData,ulDataLen) ))
- crv = NSC_SignFinal(hSession, pSignature, pulSignatureLen);
- } else {
- /* single-part PKC signature (e.g. CKM_ECDSA) */
- unsigned int outlen;
- unsigned int maxoutlen = *pulSignatureLen;
- if( SECSuccess != (*context->update)(context->cipherInfo, pSignature,
- &outlen, maxoutlen, pData, ulDataLen))
- crv = sftk_MapCryptError(PORT_GetError());
- *pulSignatureLen = (CK_ULONG) outlen;
- /* "too small" here is certainly continuable */
- if( crv != CKR_BUFFER_TOO_SMALL )
- sftk_TerminateOp(session, SFTK_SIGN, context);
- } /* single-part */
-
-finish:
- sftk_FreeSession(session);
- return crv;
-}
-
-
-/*
- ************** Crypto Functions: Sign Recover ************************
- */
-/* NSC_SignRecoverInit initializes a signature operation,
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
-CK_RV NSC_SignRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
- CHECK_FORK();
-
- switch (pMechanism->mechanism) {
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- return NSC_SignInit(hSession,pMechanism,hKey);
- default:
- break;
- }
- return CKR_MECHANISM_INVALID;
-}
-
-
-/* NSC_SignRecover signs data in a single operation
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
-CK_RV NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
-{
- CHECK_FORK();
-
- return NSC_Sign(hSession,pData,ulDataLen,pSignature,pulSignatureLen);
-}
-
-/*
- ************** Crypto Functions: verify ************************
- */
-
-/* Handle RSA Signature formatting */
-static SECStatus
-sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig,
- unsigned int sigLen, unsigned char *digest, unsigned int digestLen)
-{
- return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen,
- digest, digestLen);
-}
-
-SECStatus
-RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key,
- unsigned char *sig, unsigned int sigLen,
- unsigned char *digest, unsigned int digestLen)
-{
-
- SECItem it;
- SGNDigestInfo *di = NULL;
- SECStatus rv = SECSuccess;
-
- it.data = NULL;
-
- if (key == NULL) goto loser;
-
- it.len = nsslowkey_PublicModulusLen(key);
- if (!it.len) goto loser;
-
- it.data = (unsigned char *) PORT_Alloc(it.len);
- if (it.data == NULL) goto loser;
-
- /* decrypt the block */
- rv = RSA_CheckSignRecover(key, it.data, &it.len, it.len, sig, sigLen);
- if (rv != SECSuccess) goto loser;
-
- di = SGN_DecodeDigestInfo(&it);
- if (di == NULL) goto loser;
- if (di->digest.len != digestLen) goto loser;
-
- /* make sure the tag is OK */
- if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) {
- goto loser;
- }
- /* make sure the "parameters" are not too bogus. */
- if (di->digestAlgorithm.parameters.len > 2) {
- goto loser;
- }
- /* Now check the signature */
- if (PORT_Memcmp(digest, di->digest.data, di->digest.len) == 0) {
- goto done;
- }
-
- loser:
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- rv = SECFailure;
-
- done:
- if (it.data != NULL) PORT_Free(it.data);
- if (di != NULL) SGN_DestroyDigestInfo(di);
-
- return rv;
-}
-
-static SECStatus
-sftk_CheckSignPSS(SFTKHashVerifyInfo *info, unsigned char *sig,
- unsigned int sigLen, unsigned char *digest, unsigned int digestLen)
-{
- return RSA_CheckSignPSS(info->params, info->key, sig, sigLen,
- digest, digestLen);
-}
-
-/* NSC_VerifyInit initializes a verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature (e.g. DSA) */
-CK_RV NSC_VerifyInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
- SFTKSession *session;
- SFTKObject *key;
- SFTKSessionContext *context;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- NSSLOWKEYPublicKey *pubKey;
- SFTKHashVerifyInfo *info = NULL;
-
- CHECK_FORK();
-
- /* Block Cipher MACing Algorithms use a different Context init method..*/
- crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_VERIFY, SFTK_VERIFY);
- if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv;
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- crv = sftk_InitGeneric(session,&context,SFTK_VERIFY,&key,hKey,&key_type,
- CKO_PUBLIC_KEY,CKA_VERIFY);
- if (crv != CKR_OK) {
- sftk_FreeSession(session);
- return crv;
- }
-
- context->multi = PR_FALSE;
-
-#define INIT_RSA_VFY_MECH(mmm) \
- case CKM_ ## mmm ## _RSA_PKCS: \
- context->multi = PR_TRUE; \
- crv = sftk_doSub ## mmm (context); \
- if (crv != CKR_OK) break; \
- context->verify = (SFTKVerify) sftk_hashCheckSign; \
- info = PORT_New(SFTKHashVerifyInfo); \
- if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \
- info->hashOid = SEC_OID_ ## mmm ; \
- goto finish_rsa;
-
- switch(pMechanism->mechanism) {
- INIT_RSA_VFY_MECH(MD5)
- INIT_RSA_VFY_MECH(MD2)
- INIT_RSA_VFY_MECH(SHA1)
- INIT_RSA_VFY_MECH(SHA224)
- INIT_RSA_VFY_MECH(SHA256)
- INIT_RSA_VFY_MECH(SHA384)
- INIT_RSA_VFY_MECH(SHA512)
-
- case CKM_RSA_PKCS:
- context->verify = (SFTKVerify) RSA_CheckSign;
- goto finish_rsa;
- case CKM_RSA_X_509:
- context->verify = (SFTKVerify) RSA_CheckSignRaw;
-finish_rsa:
- if (key_type != CKK_RSA) {
- if (info) PORT_Free(info);
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->rsa = PR_TRUE;
- pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
- if (pubKey == NULL) {
- if (info) PORT_Free(info);
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- if (info) {
- info->key = pubKey;
- context->cipherInfo = info;
- context->destroy = sftk_Space;
- } else {
- context->cipherInfo = pubKey;
- context->destroy = sftk_Null;
- }
- break;
- case CKM_RSA_PKCS_PSS:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->rsa = PR_TRUE;
- if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- info = PORT_New(SFTKHashVerifyInfo);
- if (info == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- info->params = pMechanism->pParameter;
- info->key = sftk_GetPubKey(key,CKK_RSA,&crv);
- if (info->key == NULL) {
- PORT_Free(info);
- break;
- }
- context->cipherInfo = info;
- context->destroy = (SFTKDestroy) sftk_Space;
- context->verify = (SFTKVerify) sftk_CheckSignPSS;
- break;
- case CKM_DSA_SHA1:
- context->multi = PR_TRUE;
- crv = sftk_doSubSHA1(context);
- if (crv != CKR_OK) break;
- /* fall through */
- case CKM_DSA:
- if (key_type != CKK_DSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- pubKey = sftk_GetPubKey(key,CKK_DSA,&crv);
- if (pubKey == NULL) {
- break;
- }
- context->cipherInfo = pubKey;
- context->verify = (SFTKVerify) nsc_DSA_Verify_Stub;
- context->destroy = sftk_Null;
- break;
-#ifdef NSS_ENABLE_ECC
- case CKM_ECDSA_SHA1:
- context->multi = PR_TRUE;
- crv = sftk_doSubSHA1(context);
- if (crv != CKR_OK) break;
- /* fall through */
- case CKM_ECDSA:
- if (key_type != CKK_EC) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- pubKey = sftk_GetPubKey(key,CKK_EC,&crv);
- if (pubKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->cipherInfo = pubKey;
- context->verify = (SFTKVerify) nsc_ECDSAVerifyStub;
- context->destroy = sftk_Null;
- break;
-#endif /* NSS_ENABLE_ECC */
-
- INIT_HMAC_MECH(MD2)
- INIT_HMAC_MECH(MD5)
- INIT_HMAC_MECH(SHA224)
- INIT_HMAC_MECH(SHA256)
- INIT_HMAC_MECH(SHA384)
- INIT_HMAC_MECH(SHA512)
-
- case CKM_SHA_1_HMAC_GENERAL:
- crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_SHA_1_HMAC:
- crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
- break;
-
- case CKM_SSL3_MD5_MAC:
- crv = sftk_doSSLMACInit(context,SEC_OID_MD5,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_SSL3_SHA1_MAC:
- crv = sftk_doSSLMACInit(context,SEC_OID_SHA1,key,
- *(CK_ULONG *)pMechanism->pParameter);
- break;
- case CKM_TLS_PRF_GENERAL:
- crv = sftk_TLSPRFInit(context, key, key_type);
- break;
-
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- if (crv != CKR_OK) {
- if (info) PORT_Free(info);
- sftk_FreeContext(context);
- sftk_FreeSession(session);
- return crv;
- }
- sftk_SetContextByType(session, SFTK_VERIFY, context);
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-CK_RV NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
- CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- CK_RV crv;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
-
- /* multi part Verifying are completely implemented by VerifyUpdate and
- * VerifyFinal */
- if (context->multi) {
- /* VerifyFinal can't follow failed VerifyUpdate */
- if( CKR_OK == (crv = NSC_VerifyUpdate(hSession, pData, ulDataLen)))
- crv = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen);
- } else {
- if (SECSuccess != (*context->verify)(context->cipherInfo,pSignature,
- ulSignatureLen, pData, ulDataLen))
- crv = sftk_MapCryptError(PORT_GetError());
-
- sftk_TerminateOp( session, SFTK_VERIFY, context );
- }
- sftk_FreeSession(session);
- return crv;
-}
-
-
-/* NSC_VerifyUpdate continues a multiple-part verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature
- *
- * A call which results in an error terminates the operation [PKCS#11,v2.11]
- */
-CK_RV NSC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen)
-{
- CHECK_FORK();
- return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_VERIFY);
-}
-
-
-/* NSC_VerifyFinal finishes a multiple-part verification operation,
- * checking the signature. */
-CK_RV NSC_VerifyFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- CK_RV crv;
-
- CHECK_FORK();
-
- if (!pSignature)
- return CKR_ARGUMENTS_BAD;
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_TRUE,&session);
- if (crv != CKR_OK)
- return crv;
-
- if (context->hashInfo) {
- unsigned int digestLen;
- unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH];
-
- (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf));
- if( SECSuccess != (context->verify)(context->cipherInfo, pSignature,
- ulSignatureLen, tmpbuf, digestLen))
- crv = sftk_MapCryptError(PORT_GetError());
- } else if (ulSignatureLen != context->macSize) {
- /* must be block cipher MACing */
- crv = CKR_SIGNATURE_LEN_RANGE;
- } else if (CKR_OK == (crv = sftk_MACFinal(context))) {
- if (PORT_Memcmp(pSignature, context->macBuf, ulSignatureLen))
- crv = CKR_SIGNATURE_INVALID;
- }
-
- sftk_TerminateOp( session, SFTK_VERIFY, context );
- sftk_FreeSession(session);
- return crv;
-
-}
-
-/*
- ************** Crypto Functions: Verify Recover ************************
- */
-
-/* NSC_VerifyRecoverInit initializes a signature verification operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
-CK_RV NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
- SFTKSession *session;
- SFTKObject *key;
- SFTKSessionContext *context;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- NSSLOWKEYPublicKey *pubKey;
-
- CHECK_FORK();
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- crv = sftk_InitGeneric(session,&context,SFTK_VERIFY_RECOVER,
- &key,hKey,&key_type,CKO_PUBLIC_KEY,CKA_VERIFY_RECOVER);
- if (crv != CKR_OK) {
- sftk_FreeSession(session);
- return crv;
- }
-
- context->multi = PR_TRUE;
-
- switch(pMechanism->mechanism) {
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- context->rsa = PR_TRUE;
- pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
- if (pubKey == NULL) {
- break;
- }
- context->cipherInfo = pubKey;
- context->update = (SFTKCipher) (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_CheckSignRecoverRaw : RSA_CheckSignRecover);
- context->destroy = sftk_Null;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- if (crv != CKR_OK) {
- PORT_Free(context);
- sftk_FreeSession(session);
- return crv;
- }
- sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, context);
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-
-/* NSC_VerifyRecover verifies a signature in a single-part operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
-CK_RV NSC_VerifyRecover(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)
-{
- SFTKSession *session;
- SFTKSessionContext *context;
- unsigned int outlen;
- unsigned int maxoutlen = *pulDataLen;
- CK_RV crv;
- SECStatus rv;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession,&context,SFTK_VERIFY_RECOVER,
- PR_FALSE,&session);
- if (crv != CKR_OK) return crv;
- if (pData == NULL) {
- /* to return the actual size, we need to do the decrypt, just return
- * the max size, which is the size of the input signature. */
- *pulDataLen = ulSignatureLen;
- rv = SECSuccess;
- goto finish;
- }
-
- rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen,
- pSignature, ulSignatureLen);
- *pulDataLen = (CK_ULONG) outlen;
-
- sftk_TerminateOp(session, SFTK_VERIFY_RECOVER, context);
-finish:
- sftk_FreeSession(session);
- return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError());
-}
-
-/*
- **************************** Random Functions: ************************
- */
-
-/* NSC_SeedRandom mixes additional seed material into the token's random number
- * generator. */
-CK_RV NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen)
-{
- SECStatus rv;
-
- CHECK_FORK();
-
- rv = RNG_RandomUpdate(pSeed, ulSeedLen);
- return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
-}
-
-/* NSC_GenerateRandom generates random data. */
-CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
-{
- SECStatus rv;
-
- CHECK_FORK();
-
- rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen);
- /*
- * This may fail with SEC_ERROR_NEED_RANDOM, which means the RNG isn't
- * seeded with enough entropy.
- */
- return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
-}
-
-/*
- **************************** Key Functions: ************************
- */
-
-
-/*
- * generate a password based encryption key. This code uses
- * PKCS5 to do the work.
- */
-static CK_RV
-nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
- void *buf, CK_ULONG *key_length, PRBool faulty3DES)
-{
- SECItem *pbe_key = NULL, iv, pwitem;
- CK_PBE_PARAMS *pbe_params = NULL;
- CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL;
-
- *key_length = 0;
- iv.data = NULL; iv.len = 0;
-
- if (pMechanism->mechanism == CKM_PKCS5_PBKD2) {
- pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
- pwitem.data = (unsigned char *)pbkd2_params->pPassword;
- /* was this a typo in the PKCS #11 spec? */
- pwitem.len = *pbkd2_params->ulPasswordLen;
- } else {
- pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
- pwitem.data = (unsigned char *)pbe_params->pPassword;
- pwitem.len = pbe_params->ulPasswordLen;
- }
- pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES);
- if (pbe_key == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- PORT_Memcpy(buf, pbe_key->data, pbe_key->len);
- *key_length = pbe_key->len;
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
- pbe_key = NULL;
-
- if (iv.data) {
- if (pbe_params && pbe_params->pInitVector != NULL) {
- PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
- }
- PORT_Free(iv.data);
- }
-
- return CKR_OK;
-}
-
-/*
- * this is coded for "full" support. These selections will be limitted to
- * the official subset by freebl.
- */
-static unsigned int
-sftk_GetSubPrimeFromPrime(unsigned int primeBits)
-{
- if (primeBits <= 1024) {
- return 160;
- } else if (primeBits <= 2048) {
- return 224;
- } else if (primeBits <= 3072) {
- return 256;
- } else if (primeBits <= 7680) {
- return 384;
- } else {
- return 512;
- }
-}
-
-static CK_RV
-nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key)
-{
- SFTKAttribute *attribute;
- CK_ULONG counter;
- unsigned int seedBits = 0;
- unsigned int subprimeBits = 0;
- unsigned int primeBits;
- unsigned int j = 8; /* default to 1024 bits */
- CK_RV crv = CKR_OK;
- PQGParams *params = NULL;
- PQGVerify *vfy = NULL;
- SECStatus rv;
-
- attribute = sftk_FindAttribute(key, CKA_PRIME_BITS);
- if (attribute == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- primeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
- if (primeBits < 1024) {
- j = PQG_PBITS_TO_INDEX(primeBits);
- if (j == (unsigned int)-1) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- }
-
- attribute = sftk_FindAttribute(key, CKA_NETSCAPE_PQG_SEED_BITS);
- if (attribute != NULL) {
- seedBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
- }
-
- attribute = sftk_FindAttribute(key, CKA_SUBPRIME_BITS);
- if (attribute != NULL) {
- subprimeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
- }
-
- sftk_DeleteAttributeType(key,CKA_PRIME_BITS);
- sftk_DeleteAttributeType(key,CKA_SUBPRIME_BITS);
- sftk_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS);
-
- /* use the old PQG interface if we have old input data */
- if ((primeBits < 1024) || ((primeBits == 1024) && (subprimeBits == 0))) {
- if (seedBits == 0) {
- rv = PQG_ParamGen(j, &params, &vfy);
- } else {
- rv = PQG_ParamGenSeedLen(j,seedBits/8, &params, &vfy);
- }
- } else {
- if (subprimeBits == 0) {
- subprimeBits = sftk_GetSubPrimeFromPrime(primeBits);
- }
- if (seedBits == 0) {
- seedBits = primeBits;
- }
- rv = PQG_ParamGenV2(primeBits, subprimeBits, seedBits/8, &params, &vfy);
- }
-
-
-
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- return sftk_MapCryptError(PORT_GetError());
- }
- crv = sftk_AddAttributeType(key,CKA_PRIME,
- params->prime.data, params->prime.len);
- if (crv != CKR_OK) goto loser;
- crv = sftk_AddAttributeType(key,CKA_SUBPRIME,
- params->subPrime.data, params->subPrime.len);
- if (crv != CKR_OK) goto loser;
- crv = sftk_AddAttributeType(key,CKA_BASE,
- params->base.data, params->base.len);
- if (crv != CKR_OK) goto loser;
- counter = vfy->counter;
- crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_COUNTER,
- &counter, sizeof(counter));
- crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_SEED,
- vfy->seed.data, vfy->seed.len);
- if (crv != CKR_OK) goto loser;
- crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_H,
- vfy->h.data, vfy->h.len);
- if (crv != CKR_OK) goto loser;
-
-loser:
- PQG_DestroyParams(params);
-
- if (vfy) {
- PQG_DestroyVerify(vfy);
- }
- return crv;
-}
-
-
-static CK_RV
-nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type,
- CK_ULONG *key_length)
-{
- CK_RV crv = CKR_OK;
-
- switch (mechanism) {
- case CKM_RC2_KEY_GEN:
- *key_type = CKK_RC2;
- if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
-#if NSS_SOFTOKEN_DOES_RC5
- case CKM_RC5_KEY_GEN:
- *key_type = CKK_RC5;
- if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
-#endif
- case CKM_RC4_KEY_GEN:
- *key_type = CKK_RC4;
- if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- case CKM_GENERIC_SECRET_KEY_GEN:
- *key_type = CKK_GENERIC_SECRET;
- if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- case CKM_CDMF_KEY_GEN:
- *key_type = CKK_CDMF;
- *key_length = 8;
- break;
- case CKM_DES_KEY_GEN:
- *key_type = CKK_DES;
- *key_length = 8;
- break;
- case CKM_DES2_KEY_GEN:
- *key_type = CKK_DES2;
- *key_length = 16;
- break;
- case CKM_DES3_KEY_GEN:
- *key_type = CKK_DES3;
- *key_length = 24;
- break;
- case CKM_SEED_KEY_GEN:
- *key_type = CKK_SEED;
- *key_length = 16;
- break;
- case CKM_CAMELLIA_KEY_GEN:
- *key_type = CKK_CAMELLIA;
- if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- case CKM_AES_KEY_GEN:
- *key_type = CKK_AES;
- if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- default:
- PORT_Assert(0);
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- return crv;
-}
-
-CK_RV
-nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
-{
- SECItem salt;
- CK_PBE_PARAMS *pbe_params = NULL;
- NSSPKCS5PBEParameter *params;
- PRArenaPool *arena = NULL;
- SECStatus rv;
-
- *pbe = NULL;
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (arena == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- params = (NSSPKCS5PBEParameter *) PORT_ArenaZAlloc(arena,
- sizeof(NSSPKCS5PBEParameter));
- if (params == NULL) {
- PORT_FreeArena(arena,PR_TRUE);
- return CKR_HOST_MEMORY;
- }
-
- params->poolp = arena;
- params->ivLen = 0;
- params->pbeType = NSSPKCS5_PKCS12_V2;
- params->hashType = HASH_AlgSHA1;
- params->encAlg = SEC_OID_SHA1; /* any invalid value */
- params->is2KeyDES = PR_FALSE;
- params->keyID = pbeBitGenIntegrityKey;
- pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
- params->iter = pbe_params->ulIteration;
-
- salt.data = (unsigned char *)pbe_params->pSalt;
- salt.len = (unsigned int)pbe_params->ulSaltLen;
- rv = SECITEM_CopyItem(arena,&params->salt,&salt);
- if (rv != SECSuccess) {
- PORT_FreeArena(arena,PR_TRUE);
- return CKR_HOST_MEMORY;
- }
- switch (pMechanism->mechanism) {
- case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
- case CKM_PBA_SHA1_WITH_SHA1_HMAC:
- params->hashType = HASH_AlgSHA1;
- params->keyLen = 20;
- break;
- case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
- params->hashType = HASH_AlgMD5;
- params->keyLen = 16;
- break;
- case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
- params->hashType = HASH_AlgMD2;
- params->keyLen = 16;
- break;
- default:
- PORT_FreeArena(arena,PR_TRUE);
- return CKR_MECHANISM_INVALID;
- }
- *pbe = params;
- return CKR_OK;
-}
-
-/* maybe this should be table driven? */
-static CK_RV
-nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
- CK_KEY_TYPE *key_type, CK_ULONG *key_length)
-{
- CK_RV crv = CKR_OK;
- SECOidData *oid;
- CK_PBE_PARAMS *pbe_params = NULL;
- NSSPKCS5PBEParameter *params = NULL;
- CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL;
- SECItem salt;
- CK_ULONG iteration = 0;
-
- *pbe = NULL;
-
- oid = SECOID_FindOIDByMechanism(pMechanism->mechanism);
- if (oid == NULL) {
- return CKR_MECHANISM_INVALID;
- }
-
- if (pMechanism->mechanism == CKM_PKCS5_PBKD2) {
- pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter;
- if (pbkd2_params->saltSource != CKZ_SALT_SPECIFIED) {
- return CKR_MECHANISM_PARAM_INVALID;
- }
- salt.data = (unsigned char *)pbkd2_params->pSaltSourceData;
- salt.len = (unsigned int)pbkd2_params->ulSaltSourceDataLen;
- iteration = pbkd2_params->iterations;
- } else {
- pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
- salt.data = (unsigned char *)pbe_params->pSalt;
- salt.len = (unsigned int)pbe_params->ulSaltLen;
- iteration = pbe_params->ulIteration;
- }
- params=nsspkcs5_NewParam(oid->offset, &salt, iteration);
- if (params == NULL) {
- return CKR_MECHANISM_INVALID;
- }
-
- switch (params->encAlg) {
- case SEC_OID_DES_CBC:
- *key_type = CKK_DES;
- *key_length = params->keyLen;
- break;
- case SEC_OID_DES_EDE3_CBC:
- *key_type = params->is2KeyDES ? CKK_DES2 : CKK_DES3;
- *key_length = params->keyLen;
- break;
- case SEC_OID_RC2_CBC:
- *key_type = CKK_RC2;
- *key_length = params->keyLen;
- break;
- case SEC_OID_RC4:
- *key_type = CKK_RC4;
- *key_length = params->keyLen;
- break;
- case SEC_OID_PKCS5_PBKDF2:
- /* sigh, PKCS #11 currently only defines SHA1 for the KDF hash type.
- * we do the check here because this where we would handle multiple
- * hash types in the future */
- if (pbkd2_params == NULL ||
- pbkd2_params->prf != CKP_PKCS5_PBKD2_HMAC_SHA1) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- /* key type must already be set */
- if (*key_type == CKK_INVALID_KEY_TYPE) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- }
- /* PBKDF2 needs to calculate the key length from the other parameters
- */
- if (*key_length == 0) {
- *key_length = sftk_MapKeySize(*key_type);
- }
- if (*key_length == 0) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- }
- params->keyLen = *key_length;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- nsspkcs5_DestroyPBEParameter(params);
- break;
- }
- if (crv == CKR_OK) {
- *pbe = params;
- }
- return crv;
-}
-
-/* NSC_GenerateKey generates a secret key, creating a new key object. */
-CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey)
-{
- SFTKObject *key;
- SFTKSession *session;
- PRBool checkWeak = PR_FALSE;
- CK_ULONG key_length = 0;
- CK_KEY_TYPE key_type = CKK_INVALID_KEY_TYPE;
- CK_OBJECT_CLASS objclass = CKO_SECRET_KEY;
- CK_RV crv = CKR_OK;
- CK_BBOOL cktrue = CK_TRUE;
- int i;
- SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- unsigned char buf[MAX_KEY_LEN];
- enum {nsc_pbe, nsc_ssl, nsc_bulk, nsc_param, nsc_jpake} key_gen_type;
- NSSPKCS5PBEParameter *pbe_param;
- SSL3RSAPreMasterSecret *rsa_pms;
- CK_VERSION *version;
- /* in very old versions of NSS, there were implementation errors with key
- * generation methods. We want to beable to read these, but not
- * produce them any more. The affected algorithm was 3DES.
- */
- PRBool faultyPBE3DES = PR_FALSE;
- HASH_HashType hashType;
-
- CHECK_FORK();
-
- if (!slot) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- /*
- * now lets create an object to hang the attributes off of
- */
- key = sftk_NewObject(slot); /* fill in the handle later */
- if (key == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulCount; i++) {
- if (pTemplate[i].type == CKA_VALUE_LEN) {
- key_length = *(CK_ULONG *)pTemplate[i].pValue;
- continue;
- }
- /* some algorithms need keytype specified */
- if (pTemplate[i].type == CKA_KEY_TYPE) {
- key_type = *(CK_ULONG *)pTemplate[i].pValue;
- continue;
- }
-
- crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) break;
- }
- if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return crv;
- }
-
- /* make sure we don't have any class, key_type, or value fields */
- sftk_DeleteAttributeType(key,CKA_CLASS);
- sftk_DeleteAttributeType(key,CKA_KEY_TYPE);
- sftk_DeleteAttributeType(key,CKA_VALUE);
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- key_gen_type = nsc_bulk; /* bulk key by default */
- switch (pMechanism->mechanism) {
- case CKM_CDMF_KEY_GEN:
- case CKM_DES_KEY_GEN:
- case CKM_DES2_KEY_GEN:
- case CKM_DES3_KEY_GEN:
- checkWeak = PR_TRUE;
- case CKM_RC2_KEY_GEN:
- case CKM_RC4_KEY_GEN:
- case CKM_GENERIC_SECRET_KEY_GEN:
- case CKM_SEED_KEY_GEN:
- case CKM_CAMELLIA_KEY_GEN:
- case CKM_AES_KEY_GEN:
-#if NSS_SOFTOKEN_DOES_RC5
- case CKM_RC5_KEY_GEN:
-#endif
- crv = nsc_SetupBulkKeyGen(pMechanism->mechanism,&key_type,&key_length);
- break;
- case CKM_SSL3_PRE_MASTER_KEY_GEN:
- key_type = CKK_GENERIC_SECRET;
- key_length = 48;
- key_gen_type = nsc_ssl;
- break;
- case CKM_PBA_SHA1_WITH_SHA1_HMAC:
- case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
- case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
- case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
- key_gen_type = nsc_pbe;
- key_type = CKK_GENERIC_SECRET;
- crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param);
- break;
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- faultyPBE3DES = PR_TRUE;
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- case CKM_PBE_SHA1_RC2_128_CBC:
- case CKM_PBE_SHA1_RC2_40_CBC:
- case CKM_PBE_SHA1_RC4_128:
- case CKM_PBE_SHA1_RC4_40:
- case CKM_PBE_MD5_DES_CBC:
- case CKM_PBE_MD2_DES_CBC:
- case CKM_PKCS5_PBKD2:
- key_gen_type = nsc_pbe;
- crv = nsc_SetupPBEKeyGen(pMechanism,&pbe_param, &key_type, &key_length);
- break;
- case CKM_DSA_PARAMETER_GEN:
- key_gen_type = nsc_param;
- key_type = CKK_DSA;
- objclass = CKO_KG_PARAMETERS;
- crv = CKR_OK;
- break;
- case CKM_NSS_JPAKE_ROUND1_SHA1: hashType = HASH_AlgSHA1; goto jpake1;
- case CKM_NSS_JPAKE_ROUND1_SHA256: hashType = HASH_AlgSHA256; goto jpake1;
- case CKM_NSS_JPAKE_ROUND1_SHA384: hashType = HASH_AlgSHA384; goto jpake1;
- case CKM_NSS_JPAKE_ROUND1_SHA512: hashType = HASH_AlgSHA512; goto jpake1;
-jpake1:
- key_gen_type = nsc_jpake;
- key_type = CKK_NSS_JPAKE_ROUND1;
- objclass = CKO_PRIVATE_KEY;
- if (pMechanism->pParameter == NULL ||
- pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound1Params)) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- if (sftk_isTrue(key, CKA_TOKEN)) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- }
- crv = CKR_OK;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- /* make sure we aren't going to overflow the buffer */
- if (sizeof(buf) < key_length) {
- /* someone is getting pretty optimistic about how big their key can
- * be... */
- crv = CKR_TEMPLATE_INCONSISTENT;
- }
-
- if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
-
- /* if there was no error,
- * key_type *MUST* be set in the switch statement above */
- PORT_Assert( key_type != CKK_INVALID_KEY_TYPE );
-
- /*
- * now to the actual key gen.
- */
- switch (key_gen_type) {
- case nsc_pbe:
- crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length,
- faultyPBE3DES);
- nsspkcs5_DestroyPBEParameter(pbe_param);
- break;
- case nsc_ssl:
- rsa_pms = (SSL3RSAPreMasterSecret *)buf;
- version = (CK_VERSION *)pMechanism->pParameter;
- rsa_pms->client_version[0] = version->major;
- rsa_pms->client_version[1] = version->minor;
- crv =
- NSC_GenerateRandom(0,&rsa_pms->random[0], sizeof(rsa_pms->random));
- break;
- case nsc_bulk:
- /* get the key, check for weak keys and repeat if found */
- do {
- crv = NSC_GenerateRandom(0, buf, key_length);
- } while (crv == CKR_OK && checkWeak && sftk_IsWeakKey(buf,key_type));
- break;
- case nsc_param:
- /* generate parameters */
- *buf = 0;
- crv = nsc_parameter_gen(key_type,key);
- break;
- case nsc_jpake:
- crv = jpake_Round1(hashType,
- (CK_NSS_JPAKERound1Params *) pMechanism->pParameter,
- key);
- break;
- }
-
- if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
-
- /* Add the class, key_type, and value */
- crv = sftk_AddAttributeType(key,CKA_CLASS,&objclass,sizeof(CK_OBJECT_CLASS));
- if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
- crv = sftk_AddAttributeType(key,CKA_KEY_TYPE,&key_type,sizeof(CK_KEY_TYPE));
- if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
- if (key_length != 0) {
- crv = sftk_AddAttributeType(key,CKA_VALUE,buf,key_length);
- if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
- }
-
- /* get the session */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- sftk_FreeObject(key);
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /*
- * handle the base object stuff
- */
- crv = sftk_handleObject(key,session);
- sftk_FreeSession(session);
- if (sftk_isTrue(key,CKA_SENSITIVE)) {
- sftk_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
- }
- if (!sftk_isTrue(key,CKA_EXTRACTABLE)) {
- sftk_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
- }
-
- *phKey = key->handle;
- sftk_FreeObject(key);
- return crv;
-}
-
-#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
-#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
-
-/*
- * FIPS 140-2 pairwise consistency check utilized to validate key pair.
- *
- * This function returns
- * CKR_OK if pairwise consistency check passed
- * CKR_GENERAL_ERROR if pairwise consistency check failed
- * other error codes if paiswise consistency check could not be
- * performed, for example, CKR_HOST_MEMORY.
- */
-static CK_RV
-sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
- SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType)
-{
- /*
- * Key type Mechanism type
- * --------------------------------
- * For encrypt/decrypt: CKK_RSA => CKM_RSA_PKCS
- * others => CKM_INVALID_MECHANISM
- *
- * For sign/verify: CKK_RSA => CKM_RSA_PKCS
- * CKK_DSA => CKM_DSA
- * CKK_EC => CKM_ECDSA
- * others => CKM_INVALID_MECHANISM
- *
- * None of these mechanisms has a parameter.
- */
- CK_MECHANISM mech = {0, NULL, 0};
-
- CK_ULONG modulusLen;
- CK_ULONG subPrimeLen;
- PRBool isEncryptable = PR_FALSE;
- PRBool canSignVerify = PR_FALSE;
- PRBool isDerivable = PR_FALSE;
- CK_RV crv;
-
- /* Variables used for Encrypt/Decrypt functions. */
- unsigned char *known_message = (unsigned char *)"Known Crypto Message";
- unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH];
- CK_ULONG bytes_decrypted;
- unsigned char *ciphertext;
- unsigned char *text_compared;
- CK_ULONG bytes_encrypted;
- CK_ULONG bytes_compared;
- CK_ULONG pairwise_digest_length = PAIRWISE_DIGEST_LENGTH;
-
- /* Variables used for Signature/Verification functions. */
- /* Must be at least 256 bits for DSA2 digest */
- unsigned char *known_digest = (unsigned char *)
- "Mozilla Rules the World through NSS!";
- unsigned char *signature;
- CK_ULONG signature_length;
-
- if (keyType == CKK_RSA) {
- SFTKAttribute *attribute;
-
- /* Get modulus length of private key. */
- attribute = sftk_FindAttribute(privateKey, CKA_MODULUS);
- if (attribute == NULL) {
- return CKR_DEVICE_ERROR;
- }
- modulusLen = attribute->attrib.ulValueLen;
- if (*(unsigned char *)attribute->attrib.pValue == 0) {
- modulusLen--;
- }
- sftk_FreeAttribute(attribute);
- } else if (keyType == CKK_DSA) {
- SFTKAttribute *attribute;
-
- /* Get subprime length of private key. */
- attribute = sftk_FindAttribute(privateKey, CKA_SUBPRIME);
- if (attribute == NULL) {
- return CKR_DEVICE_ERROR;
- }
- subPrimeLen = attribute->attrib.ulValueLen;
- if (subPrimeLen > 1 && *(unsigned char *)attribute->attrib.pValue == 0) {
- subPrimeLen--;
- }
- sftk_FreeAttribute(attribute);
- }
-
- /**************************************************/
- /* Pairwise Consistency Check of Encrypt/Decrypt. */
- /**************************************************/
-
- isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT);
-
- /*
- * If the decryption attribute is set, attempt to encrypt
- * with the public key and decrypt with the private key.
- */
- if (isEncryptable) {
- if (keyType != CKK_RSA) {
- return CKR_DEVICE_ERROR;
- }
- bytes_encrypted = modulusLen;
- mech.mechanism = CKM_RSA_PKCS;
-
- /* Allocate space for ciphertext. */
- ciphertext = (unsigned char *) PORT_ZAlloc(bytes_encrypted);
- if (ciphertext == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /* Prepare for encryption using the public key. */
- crv = NSC_EncryptInit(hSession, &mech, publicKey->handle);
- if (crv != CKR_OK) {
- PORT_Free(ciphertext);
- return crv;
- }
-
- /* Encrypt using the public key. */
- crv = NSC_Encrypt(hSession,
- known_message,
- PAIRWISE_MESSAGE_LENGTH,
- ciphertext,
- &bytes_encrypted);
- if (crv != CKR_OK) {
- PORT_Free(ciphertext);
- return crv;
- }
-
- /* Always use the smaller of these two values . . . */
- bytes_compared = PR_MIN(bytes_encrypted, PAIRWISE_MESSAGE_LENGTH);
-
- /*
- * If there was a failure, the plaintext
- * goes at the end, therefore . . .
- */
- text_compared = ciphertext + bytes_encrypted - bytes_compared;
-
- /*
- * Check to ensure that ciphertext does
- * NOT EQUAL known input message text
- * per FIPS PUB 140-2 directive.
- */
- if (PORT_Memcmp(text_compared, known_message,
- bytes_compared) == 0) {
- /* Set error to Invalid PRIVATE Key. */
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- PORT_Free(ciphertext);
- return CKR_GENERAL_ERROR;
- }
-
- /* Prepare for decryption using the private key. */
- crv = NSC_DecryptInit(hSession, &mech, privateKey->handle);
- if (crv != CKR_OK) {
- PORT_Free(ciphertext);
- return crv;
- }
-
- memset(plaintext, 0, PAIRWISE_MESSAGE_LENGTH);
-
- /*
- * Initialize bytes decrypted to be the
- * expected PAIRWISE_MESSAGE_LENGTH.
- */
- bytes_decrypted = PAIRWISE_MESSAGE_LENGTH;
-
- /*
- * Decrypt using the private key.
- * NOTE: No need to reset the
- * value of bytes_encrypted.
- */
- crv = NSC_Decrypt(hSession,
- ciphertext,
- bytes_encrypted,
- plaintext,
- &bytes_decrypted);
-
- /* Finished with ciphertext; free it. */
- PORT_Free(ciphertext);
-
- if (crv != CKR_OK) {
- return crv;
- }
-
- /*
- * Check to ensure that the output plaintext
- * does EQUAL known input message text.
- */
- if ((bytes_decrypted != PAIRWISE_MESSAGE_LENGTH) ||
- (PORT_Memcmp(plaintext, known_message,
- PAIRWISE_MESSAGE_LENGTH) != 0)) {
- /* Set error to Bad PUBLIC Key. */
- PORT_SetError(SEC_ERROR_BAD_KEY);
- return CKR_GENERAL_ERROR;
- }
- }
-
- /**********************************************/
- /* Pairwise Consistency Check of Sign/Verify. */
- /**********************************************/
-
- canSignVerify = sftk_isTrue(privateKey, CKA_SIGN);
-
- if (canSignVerify) {
- /* Determine length of signature. */
- switch (keyType) {
- case CKK_RSA:
- signature_length = modulusLen;
- mech.mechanism = CKM_RSA_PKCS;
- break;
- case CKK_DSA:
- signature_length = DSA_MAX_SIGNATURE_LEN;
- pairwise_digest_length = subPrimeLen;
- mech.mechanism = CKM_DSA;
- break;
-#ifdef NSS_ENABLE_ECC
- case CKK_EC:
- signature_length = MAX_ECKEY_LEN * 2;
- mech.mechanism = CKM_ECDSA;
- break;
-#endif
- default:
- return CKR_DEVICE_ERROR;
- }
-
- /* Allocate space for signature data. */
- signature = (unsigned char *) PORT_ZAlloc(signature_length);
- if (signature == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /* Sign the known hash using the private key. */
- crv = NSC_SignInit(hSession, &mech, privateKey->handle);
- if (crv != CKR_OK) {
- PORT_Free(signature);
- return crv;
- }
-
- crv = NSC_Sign(hSession,
- known_digest,
- pairwise_digest_length,
- signature,
- &signature_length);
- if (crv != CKR_OK) {
- PORT_Free(signature);
- return crv;
- }
-
- /* Verify the known hash using the public key. */
- crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
- if (crv != CKR_OK) {
- PORT_Free(signature);
- return crv;
- }
-
- crv = NSC_Verify(hSession,
- known_digest,
- pairwise_digest_length,
- signature,
- signature_length);
-
- /* Free signature data. */
- PORT_Free(signature);
-
- if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
- (crv == CKR_SIGNATURE_INVALID)) {
- return CKR_GENERAL_ERROR;
- }
- if (crv != CKR_OK) {
- return crv;
- }
- }
-
- /**********************************************/
- /* Pairwise Consistency Check for Derivation */
- /**********************************************/
-
- isDerivable = sftk_isTrue(privateKey, CKA_DERIVE);
-
- if (isDerivable) {
- /*
- * We are not doing consistency check for Diffie-Hellman Key -
- * otherwise it would be here
- * This is also true for Elliptic Curve Diffie-Hellman keys
- * NOTE: EC keys are currently subjected to pairwise
- * consistency check for signing/verification.
- */
- /*
- * FIPS 140-2 had the following pairwise consistency test for
- * public and private keys used for key agreement:
- * If the keys are used to perform key agreement, then the
- * cryptographic module shall create a second, compatible
- * key pair. The cryptographic module shall perform both
- * sides of the key agreement algorithm and shall compare
- * the resulting shared values. If the shared values are
- * not equal, the test shall fail.
- * This test was removed in Change Notice 3.
- */
-
- }
-
- return CKR_OK;
-}
-
-/* NSC_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
-CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey)
-{
- SFTKObject * publicKey,*privateKey;
- SFTKSession * session;
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- CK_BBOOL cktrue = CK_TRUE;
- SECStatus rv;
- CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
- CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
- int i;
- SFTKSlot * slot = sftk_SlotFromSessionHandle(hSession);
- unsigned int bitSize;
-
- /* RSA */
- int public_modulus_bits = 0;
- SECItem pubExp;
- RSAPrivateKey * rsaPriv;
-
- /* DSA */
- PQGParams pqgParam;
- DHParams dhParam;
- DSAPrivateKey * dsaPriv;
-
- /* Diffie Hellman */
- int private_value_bits = 0;
- DHPrivateKey * dhPriv;
-
-#ifdef NSS_ENABLE_ECC
- /* Elliptic Curve Cryptography */
- SECItem ecEncodedParams; /* DER Encoded parameters */
- ECPrivateKey * ecPriv;
- ECParams * ecParams;
-#endif /* NSS_ENABLE_ECC */
-
- CHECK_FORK();
-
- if (!slot) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- /*
- * now lets create an object to hang the attributes off of
- */
- publicKey = sftk_NewObject(slot); /* fill in the handle later */
- if (publicKey == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the publicKey
- */
- for (i=0; i < (int) ulPublicKeyAttributeCount; i++) {
- if (pPublicKeyTemplate[i].type == CKA_MODULUS_BITS) {
- public_modulus_bits = *(CK_ULONG *)pPublicKeyTemplate[i].pValue;
- continue;
- }
-
- crv = sftk_AddAttributeType(publicKey,
- sftk_attr_expand(&pPublicKeyTemplate[i]));
- if (crv != CKR_OK) break;
- }
-
- if (crv != CKR_OK) {
- sftk_FreeObject(publicKey);
- return CKR_HOST_MEMORY;
- }
-
- privateKey = sftk_NewObject(slot); /* fill in the handle later */
- if (privateKey == NULL) {
- sftk_FreeObject(publicKey);
- return CKR_HOST_MEMORY;
- }
- /*
- * now load the private key template
- */
- for (i=0; i < (int) ulPrivateKeyAttributeCount; i++) {
- if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS) {
- private_value_bits = *(CK_ULONG *)pPrivateKeyTemplate[i].pValue;
- continue;
- }
-
- crv = sftk_AddAttributeType(privateKey,
- sftk_attr_expand(&pPrivateKeyTemplate[i]));
- if (crv != CKR_OK) break;
- }
-
- if (crv != CKR_OK) {
- sftk_FreeObject(publicKey);
- sftk_FreeObject(privateKey);
- return CKR_HOST_MEMORY;
- }
- sftk_DeleteAttributeType(privateKey,CKA_CLASS);
- sftk_DeleteAttributeType(privateKey,CKA_KEY_TYPE);
- sftk_DeleteAttributeType(privateKey,CKA_VALUE);
- sftk_DeleteAttributeType(publicKey,CKA_CLASS);
- sftk_DeleteAttributeType(publicKey,CKA_KEY_TYPE);
- sftk_DeleteAttributeType(publicKey,CKA_VALUE);
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- switch (pMechanism->mechanism) {
- case CKM_RSA_PKCS_KEY_PAIR_GEN:
- /* format the keys */
- sftk_DeleteAttributeType(publicKey,CKA_MODULUS);
- sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
- sftk_DeleteAttributeType(privateKey,CKA_MODULUS);
- sftk_DeleteAttributeType(privateKey,CKA_PRIVATE_EXPONENT);
- sftk_DeleteAttributeType(privateKey,CKA_PUBLIC_EXPONENT);
- sftk_DeleteAttributeType(privateKey,CKA_PRIME_1);
- sftk_DeleteAttributeType(privateKey,CKA_PRIME_2);
- sftk_DeleteAttributeType(privateKey,CKA_EXPONENT_1);
- sftk_DeleteAttributeType(privateKey,CKA_EXPONENT_2);
- sftk_DeleteAttributeType(privateKey,CKA_COEFFICIENT);
- key_type = CKK_RSA;
- if (public_modulus_bits == 0) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- }
- if (public_modulus_bits < RSA_MIN_MODULUS_BITS) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- break;
- }
- if (public_modulus_bits % 2 != 0) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- break;
- }
-
- /* extract the exponent */
- crv=sftk_Attribute2SSecItem(NULL,&pubExp,publicKey,CKA_PUBLIC_EXPONENT);
- if (crv != CKR_OK) break;
- bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len);
- if (bitSize < 2) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- break;
- }
- crv = sftk_AddAttributeType(privateKey,CKA_PUBLIC_EXPONENT,
- sftk_item_expand(&pubExp));
- if (crv != CKR_OK) {
- PORT_Free(pubExp.data);
- break;
- }
-
- rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp);
- PORT_Free(pubExp.data);
- if (rsaPriv == NULL) {
- if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- crv = sftk_MapCryptError(PORT_GetError());
- break;
- }
- /* now fill in the RSA dependent paramenters in the public key */
- crv = sftk_AddAttributeType(publicKey,CKA_MODULUS,
- sftk_item_expand(&rsaPriv->modulus));
- if (crv != CKR_OK) goto kpg_done;
- /* now fill in the RSA dependent paramenters in the private key */
- crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
- sftk_item_expand(&rsaPriv->modulus));
- if (crv != CKR_OK) goto kpg_done;
- crv = sftk_AddAttributeType(privateKey,CKA_MODULUS,
- sftk_item_expand(&rsaPriv->modulus));
- if (crv != CKR_OK) goto kpg_done;
- crv = sftk_AddAttributeType(privateKey,CKA_PRIVATE_EXPONENT,
- sftk_item_expand(&rsaPriv->privateExponent));
- if (crv != CKR_OK) goto kpg_done;
- crv = sftk_AddAttributeType(privateKey,CKA_PRIME_1,
- sftk_item_expand(&rsaPriv->prime1));
- if (crv != CKR_OK) goto kpg_done;
- crv = sftk_AddAttributeType(privateKey,CKA_PRIME_2,
- sftk_item_expand(&rsaPriv->prime2));
- if (crv != CKR_OK) goto kpg_done;
- crv = sftk_AddAttributeType(privateKey,CKA_EXPONENT_1,
- sftk_item_expand(&rsaPriv->exponent1));
- if (crv != CKR_OK) goto kpg_done;
- crv = sftk_AddAttributeType(privateKey,CKA_EXPONENT_2,
- sftk_item_expand(&rsaPriv->exponent2));
- if (crv != CKR_OK) goto kpg_done;
- crv = sftk_AddAttributeType(privateKey,CKA_COEFFICIENT,
- sftk_item_expand(&rsaPriv->coefficient));
-kpg_done:
- /* Should zeroize the contents first, since this func doesn't. */
- PORT_FreeArena(rsaPriv->arena, PR_TRUE);
- break;
- case CKM_DSA_KEY_PAIR_GEN:
- sftk_DeleteAttributeType(publicKey,CKA_VALUE);
- sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
- sftk_DeleteAttributeType(privateKey,CKA_PRIME);
- sftk_DeleteAttributeType(privateKey,CKA_SUBPRIME);
- sftk_DeleteAttributeType(privateKey,CKA_BASE);
- key_type = CKK_DSA;
-
- /* extract the necessary parameters and copy them to the private key */
- crv=sftk_Attribute2SSecItem(NULL,&pqgParam.prime,publicKey,CKA_PRIME);
- if (crv != CKR_OK) break;
- crv=sftk_Attribute2SSecItem(NULL,&pqgParam.subPrime,publicKey,
- CKA_SUBPRIME);
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- break;
- }
- crv=sftk_Attribute2SSecItem(NULL,&pqgParam.base,publicKey,CKA_BASE);
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- break;
- }
- crv = sftk_AddAttributeType(privateKey,CKA_PRIME,
- sftk_item_expand(&pqgParam.prime));
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
- break;
- }
- crv = sftk_AddAttributeType(privateKey,CKA_SUBPRIME,
- sftk_item_expand(&pqgParam.subPrime));
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
- break;
- }
- crv = sftk_AddAttributeType(privateKey,CKA_BASE,
- sftk_item_expand(&pqgParam.base));
- if (crv != CKR_OK) {
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
- break;
- }
-
- /*
- * these are checked by DSA_NewKey
- */
- bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data,
- pqgParam.subPrime.len);
- if ((bitSize < DSA_MIN_Q_BITS) || (bitSize > DSA_MAX_Q_BITS)) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
- break;
- }
- bitSize = sftk_GetLengthInBits(pqgParam.prime.data,pqgParam.prime.len);
- if ((bitSize < DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
- break;
- }
- bitSize = sftk_GetLengthInBits(pqgParam.base.data,pqgParam.base.len);
- if ((bitSize < 2) || (bitSize > DSA_MAX_P_BITS)) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
- break;
- }
-
- /* Generate the key */
- rv = DSA_NewKey(&pqgParam, &dsaPriv);
-
- PORT_Free(pqgParam.prime.data);
- PORT_Free(pqgParam.subPrime.data);
- PORT_Free(pqgParam.base.data);
-
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- crv = sftk_MapCryptError(PORT_GetError());
- break;
- }
-
- /* store the generated key into the attributes */
- crv = sftk_AddAttributeType(publicKey,CKA_VALUE,
- sftk_item_expand(&dsaPriv->publicValue));
- if (crv != CKR_OK) goto dsagn_done;
-
- /* now fill in the RSA dependent paramenters in the private key */
- crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
- sftk_item_expand(&dsaPriv->publicValue));
- if (crv != CKR_OK) goto dsagn_done;
- crv = sftk_AddAttributeType(privateKey,CKA_VALUE,
- sftk_item_expand(&dsaPriv->privateValue));
-
-dsagn_done:
- /* should zeroize, since this function doesn't. */
- PORT_FreeArena(dsaPriv->params.arena, PR_TRUE);
- break;
-
- case CKM_DH_PKCS_KEY_PAIR_GEN:
- sftk_DeleteAttributeType(privateKey,CKA_PRIME);
- sftk_DeleteAttributeType(privateKey,CKA_BASE);
- sftk_DeleteAttributeType(privateKey,CKA_VALUE);
- sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
- key_type = CKK_DH;
-
- /* extract the necessary parameters and copy them to private keys */
- crv = sftk_Attribute2SSecItem(NULL, &dhParam.prime, publicKey,
- CKA_PRIME);
- if (crv != CKR_OK) break;
- crv = sftk_Attribute2SSecItem(NULL, &dhParam.base, publicKey, CKA_BASE);
- if (crv != CKR_OK) {
- PORT_Free(dhParam.prime.data);
- break;
- }
- crv = sftk_AddAttributeType(privateKey, CKA_PRIME,
- sftk_item_expand(&dhParam.prime));
- if (crv != CKR_OK) {
- PORT_Free(dhParam.prime.data);
- PORT_Free(dhParam.base.data);
- break;
- }
- crv = sftk_AddAttributeType(privateKey, CKA_BASE,
- sftk_item_expand(&dhParam.base));
- if (crv != CKR_OK) {
- PORT_Free(dhParam.prime.data);
- PORT_Free(dhParam.base.data);
- break;
- }
- bitSize = sftk_GetLengthInBits(dhParam.prime.data,dhParam.prime.len);
- if ((bitSize < DH_MIN_P_BITS) || (bitSize > DH_MAX_P_BITS)) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- PORT_Free(dhParam.prime.data);
- PORT_Free(dhParam.base.data);
- break;
- }
- bitSize = sftk_GetLengthInBits(dhParam.base.data,dhParam.base.len);
- if ((bitSize < 1) || (bitSize > DH_MAX_P_BITS)) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- PORT_Free(dhParam.prime.data);
- PORT_Free(dhParam.base.data);
- break;
- }
-
- rv = DH_NewKey(&dhParam, &dhPriv);
- PORT_Free(dhParam.prime.data);
- PORT_Free(dhParam.base.data);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- crv = sftk_MapCryptError(PORT_GetError());
- break;
- }
-
- crv=sftk_AddAttributeType(publicKey, CKA_VALUE,
- sftk_item_expand(&dhPriv->publicValue));
- if (crv != CKR_OK) goto dhgn_done;
-
- crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
- sftk_item_expand(&dhPriv->publicValue));
- if (crv != CKR_OK) goto dhgn_done;
-
- crv=sftk_AddAttributeType(privateKey, CKA_VALUE,
- sftk_item_expand(&dhPriv->privateValue));
-
-dhgn_done:
- /* should zeroize, since this function doesn't. */
- PORT_FreeArena(dhPriv->arena, PR_TRUE);
- break;
-
-#ifdef NSS_ENABLE_ECC
- case CKM_EC_KEY_PAIR_GEN:
- sftk_DeleteAttributeType(privateKey,CKA_EC_PARAMS);
- sftk_DeleteAttributeType(privateKey,CKA_VALUE);
- sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB);
- key_type = CKK_EC;
-
- /* extract the necessary parameters and copy them to private keys */
- crv = sftk_Attribute2SSecItem(NULL, &ecEncodedParams, publicKey,
- CKA_EC_PARAMS);
- if (crv != CKR_OK) break;
-
- crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS,
- sftk_item_expand(&ecEncodedParams));
- if (crv != CKR_OK) {
- PORT_Free(ecEncodedParams.data);
- break;
- }
-
- /* Decode ec params before calling EC_NewKey */
- rv = EC_DecodeParams(&ecEncodedParams, &ecParams);
- PORT_Free(ecEncodedParams.data);
- if (rv != SECSuccess) {
- crv = sftk_MapCryptError(PORT_GetError());
- break;
- }
- rv = EC_NewKey(ecParams, &ecPriv);
- PORT_FreeArena(ecParams->arena, PR_TRUE);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- crv = sftk_MapCryptError(PORT_GetError());
- break;
- }
-
- if (getenv("NSS_USE_DECODED_CKA_EC_POINT")) {
- crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
- sftk_item_expand(&ecPriv->publicValue));
- } else {
- SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
- &ecPriv->publicValue,
- SEC_ASN1_GET(SEC_OctetStringTemplate));
- if (!pubValue) {
- crv = CKR_ARGUMENTS_BAD;
- goto ecgn_done;
- }
- crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
- sftk_item_expand(pubValue));
- SECITEM_FreeItem(pubValue, PR_TRUE);
- }
- if (crv != CKR_OK) goto ecgn_done;
-
- crv = sftk_AddAttributeType(privateKey, CKA_VALUE,
- sftk_item_expand(&ecPriv->privateValue));
- if (crv != CKR_OK) goto ecgn_done;
-
- crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB,
- sftk_item_expand(&ecPriv->publicValue));
-ecgn_done:
- /* should zeroize, since this function doesn't. */
- PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE);
- break;
-#endif /* NSS_ENABLE_ECC */
-
- default:
- crv = CKR_MECHANISM_INVALID;
- }
-
- if (crv != CKR_OK) {
- sftk_FreeObject(privateKey);
- sftk_FreeObject(publicKey);
- return crv;
- }
-
-
- /* Add the class, key_type The loop lets us check errors blow out
- * on errors and clean up at the bottom */
- session = NULL; /* make pedtantic happy... session cannot leave the*/
- /* loop below NULL unless an error is set... */
- do {
- crv = sftk_AddAttributeType(privateKey,CKA_CLASS,&privClass,
- sizeof(CK_OBJECT_CLASS));
- if (crv != CKR_OK) break;
- crv = sftk_AddAttributeType(publicKey,CKA_CLASS,&pubClass,
- sizeof(CK_OBJECT_CLASS));
- if (crv != CKR_OK) break;
- crv = sftk_AddAttributeType(privateKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE));
- if (crv != CKR_OK) break;
- crv = sftk_AddAttributeType(publicKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE));
- if (crv != CKR_OK) break;
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) crv = CKR_SESSION_HANDLE_INVALID;
- } while (0);
-
- if (crv != CKR_OK) {
- sftk_FreeObject(privateKey);
- sftk_FreeObject(publicKey);
- return crv;
- }
-
- /*
- * handle the base object cleanup for the public Key
- */
- crv = sftk_handleObject(privateKey,session);
- if (crv != CKR_OK) {
- sftk_FreeSession(session);
- sftk_FreeObject(privateKey);
- sftk_FreeObject(publicKey);
- return crv;
- }
-
- /*
- * handle the base object cleanup for the private Key
- * If we have any problems, we destroy the public Key we've
- * created and linked.
- */
- crv = sftk_handleObject(publicKey,session);
- sftk_FreeSession(session);
- if (crv != CKR_OK) {
- sftk_FreeObject(publicKey);
- NSC_DestroyObject(hSession,privateKey->handle);
- sftk_FreeObject(privateKey);
- return crv;
- }
- if (sftk_isTrue(privateKey,CKA_SENSITIVE)) {
- sftk_forceAttribute(privateKey,CKA_ALWAYS_SENSITIVE,
- &cktrue,sizeof(CK_BBOOL));
- }
- if (sftk_isTrue(publicKey,CKA_SENSITIVE)) {
- sftk_forceAttribute(publicKey,CKA_ALWAYS_SENSITIVE,
- &cktrue,sizeof(CK_BBOOL));
- }
- if (!sftk_isTrue(privateKey,CKA_EXTRACTABLE)) {
- sftk_forceAttribute(privateKey,CKA_NEVER_EXTRACTABLE,
- &cktrue,sizeof(CK_BBOOL));
- }
- if (!sftk_isTrue(publicKey,CKA_EXTRACTABLE)) {
- sftk_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE,
- &cktrue,sizeof(CK_BBOOL));
- }
-
- /* Perform FIPS 140-2 pairwise consistency check. */
- crv = sftk_PairwiseConsistencyCheck(hSession,
- publicKey, privateKey, key_type);
- if (crv != CKR_OK) {
- NSC_DestroyObject(hSession,publicKey->handle);
- sftk_FreeObject(publicKey);
- NSC_DestroyObject(hSession,privateKey->handle);
- sftk_FreeObject(privateKey);
- if (sftk_audit_enabled) {
- char msg[128];
- PR_snprintf(msg,sizeof msg,
- "C_GenerateKeyPair(hSession=0x%08lX, "
- "pMechanism->mechanism=0x%08lX)=0x%08lX "
- "self-test: pair-wise consistency test failed",
- (PRUint32)hSession,(PRUint32)pMechanism->mechanism,
- (PRUint32)crv);
- sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
- }
- return crv;
- }
-
- *phPrivateKey = privateKey->handle;
- *phPublicKey = publicKey->handle;
- sftk_FreeObject(publicKey);
- sftk_FreeObject(privateKey);
-
- return CKR_OK;
-}
-
-static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
-{
- NSSLOWKEYPrivateKey *lk = NULL;
- NSSLOWKEYPrivateKeyInfo *pki = NULL;
- SFTKAttribute *attribute = NULL;
- PLArenaPool *arena = NULL;
- SECOidTag algorithm = SEC_OID_UNKNOWN;
- void *dummy, *param = NULL;
- SECStatus rv = SECSuccess;
- SECItem *encodedKey = NULL;
-#ifdef NSS_ENABLE_ECC
- SECItem *fordebug;
- int savelen;
-#endif
-
- if(!key) {
- *crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */
- return NULL;
- }
-
- attribute = sftk_FindAttribute(key, CKA_KEY_TYPE);
- if(!attribute) {
- *crvp = CKR_KEY_TYPE_INCONSISTENT;
- return NULL;
- }
-
- lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp);
- sftk_FreeAttribute(attribute);
- if(!lk) {
- return NULL;
- }
-
- arena = PORT_NewArena(2048); /* XXX different size? */
- if(!arena) {
- *crvp = CKR_HOST_MEMORY;
- rv = SECFailure;
- goto loser;
- }
-
- pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPrivateKeyInfo));
- if(!pki) {
- *crvp = CKR_HOST_MEMORY;
- rv = SECFailure;
- goto loser;
- }
- pki->arena = arena;
-
- param = NULL;
- switch(lk->keyType) {
- case NSSLOWKEYRSAKey:
- prepare_low_rsa_priv_key_for_asn1(lk);
- dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
- nsslowkey_RSAPrivateKeyTemplate);
- algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
- break;
- case NSSLOWKEYDSAKey:
- prepare_low_dsa_priv_key_export_for_asn1(lk);
- dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
- nsslowkey_DSAPrivateKeyExportTemplate);
- prepare_low_pqg_params_for_asn1(&lk->u.dsa.params);
- param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params),
- nsslowkey_PQGParamsTemplate);
- algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE;
- break;
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- prepare_low_ec_priv_key_for_asn1(lk);
- /* Public value is encoded as a bit string so adjust length
- * to be in bits before ASN encoding and readjust
- * immediately after.
- *
- * Since the SECG specification recommends not including the
- * parameters as part of ECPrivateKey, we zero out the curveOID
- * length before encoding and restore it later.
- */
- lk->u.ec.publicValue.len <<= 3;
- savelen = lk->u.ec.ecParams.curveOID.len;
- lk->u.ec.ecParams.curveOID.len = 0;
- dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
- nsslowkey_ECPrivateKeyTemplate);
- lk->u.ec.ecParams.curveOID.len = savelen;
- lk->u.ec.publicValue.len >>= 3;
-
- fordebug = &pki->privateKey;
- SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType,
- fordebug);
-
- param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding);
-
- algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
- break;
-#endif /* NSS_ENABLE_ECC */
- case NSSLOWKEYDHKey:
- default:
- dummy = NULL;
- break;
- }
-
- if(!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) {
- *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
- rv = SECFailure;
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm,
- (SECItem*)param);
- if(rv != SECSuccess) {
- *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
- rv = SECFailure;
- goto loser;
- }
-
- dummy = SEC_ASN1EncodeInteger(arena, &pki->version,
- NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
- if(!dummy) {
- *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */
- rv = SECFailure;
- goto loser;
- }
-
- encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki,
- nsslowkey_PrivateKeyInfoTemplate);
- *crvp = encodedKey ? CKR_OK : CKR_DEVICE_ERROR;
-
-#ifdef NSS_ENABLE_ECC
- fordebug = encodedKey;
- SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType,
- fordebug);
-#endif
-loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- if(lk && (lk != key->objectInfo)) {
- nsslowkey_DestroyPrivateKey(lk);
- }
-
- if(param) {
- SECITEM_ZfreeItem((SECItem*)param, PR_TRUE);
- }
-
- if(rv != SECSuccess) {
- return NULL;
- }
-
- return encodedKey;
-}
-
-/* it doesn't matter yet, since we colapse error conditions in the
- * level above, but we really should map those few key error differences */
-static CK_RV
-sftk_mapWrap(CK_RV crv)
-{
- switch (crv) {
- case CKR_ENCRYPTED_DATA_INVALID: crv = CKR_WRAPPED_KEY_INVALID; break;
- }
- return crv;
-}
-
-/* NSC_WrapKey wraps (i.e., encrypts) a key. */
-CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen)
-{
- SFTKSession *session;
- SFTKAttribute *attribute;
- SFTKObject *key;
- CK_RV crv;
-
- CHECK_FORK();
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- key = sftk_ObjectFromHandle(hKey,session);
- sftk_FreeSession(session);
- if (key == NULL) {
- return CKR_KEY_HANDLE_INVALID;
- }
-
- switch(key->objclass) {
- case CKO_SECRET_KEY:
- {
- SFTKSessionContext *context = NULL;
- SECItem pText;
-
- attribute = sftk_FindAttribute(key,CKA_VALUE);
-
- if (attribute == NULL) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
- CKA_WRAP, CKA_WRAP, SFTK_ENCRYPT, PR_TRUE);
- if (crv != CKR_OK) {
- sftk_FreeAttribute(attribute);
- break;
- }
-
- pText.type = siBuffer;
- pText.data = (unsigned char *)attribute->attrib.pValue;
- pText.len = attribute->attrib.ulValueLen;
-
- /* Find out if this is a block cipher. */
- crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_FALSE,NULL);
- if (crv != CKR_OK || !context)
- break;
- if (context->blockSize > 1) {
- unsigned int remainder = pText.len % context->blockSize;
- if (!context->doPad && remainder) {
- /* When wrapping secret keys with unpadded block ciphers,
- ** the keys are zero padded, if necessary, to fill out
- ** a full block.
- */
- pText.len += context->blockSize - remainder;
- pText.data = PORT_ZAlloc(pText.len);
- if (pText.data)
- memcpy(pText.data, attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- else {
- crv = CKR_HOST_MEMORY;
- break;
- }
- }
- }
-
- crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data,
- pText.len, pWrappedKey, pulWrappedKeyLen);
- /* always force a finalize, both on errors and when
- * we are just getting the size */
- if (crv != CKR_OK || pWrappedKey == NULL) {
- CK_RV lcrv ;
- lcrv = sftk_GetContext(hSession,&context,
- SFTK_ENCRYPT,PR_FALSE,NULL);
- sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
- if (lcrv == CKR_OK && context) {
- sftk_FreeContext(context);
- }
- }
-
- if (pText.data != (unsigned char *)attribute->attrib.pValue)
- PORT_ZFree(pText.data, pText.len);
- sftk_FreeAttribute(attribute);
- break;
- }
-
- case CKO_PRIVATE_KEY:
- {
- SECItem *bpki = sftk_PackagePrivateKey(key, &crv);
- SFTKSessionContext *context = NULL;
-
- if(!bpki) {
- break;
- }
-
- crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey,
- CKA_WRAP, CKA_WRAP, SFTK_ENCRYPT, PR_TRUE);
- if(crv != CKR_OK) {
- SECITEM_ZfreeItem(bpki, PR_TRUE);
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
-
- crv = NSC_Encrypt(hSession, bpki->data, bpki->len,
- pWrappedKey, pulWrappedKeyLen);
- /* always force a finalize */
- if (crv != CKR_OK || pWrappedKey == NULL) {
- CK_RV lcrv ;
- lcrv = sftk_GetContext(hSession,&context,
- SFTK_ENCRYPT,PR_FALSE,NULL);
- sftk_SetContextByType(session, SFTK_ENCRYPT, NULL);
- if (lcrv == CKR_OK && context) {
- sftk_FreeContext(context);
- }
- }
- SECITEM_ZfreeItem(bpki, PR_TRUE);
- break;
- }
-
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- sftk_FreeObject(key);
-
- return sftk_mapWrap(crv);
-}
-
-/*
- * import a pprivate key info into the desired slot
- */
-static SECStatus
-sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
-{
- CK_BBOOL cktrue = CK_TRUE;
- CK_KEY_TYPE keyType = CKK_RSA;
- SECStatus rv = SECFailure;
- const SEC_ASN1Template *keyTemplate, *paramTemplate;
- void *paramDest = NULL;
- PLArenaPool *arena;
- NSSLOWKEYPrivateKey *lpk = NULL;
- NSSLOWKEYPrivateKeyInfo *pki = NULL;
- CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;
-
- arena = PORT_NewArena(2048);
- if(!arena) {
- return SECFailure;
- }
-
- pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPrivateKeyInfo));
- if(!pki) {
- PORT_FreeArena(arena, PR_FALSE);
- return SECFailure;
- }
-
- if(SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki)
- != SECSuccess) {
- PORT_FreeArena(arena, PR_TRUE);
- return SECFailure;
- }
-
- lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(arena,
- sizeof(NSSLOWKEYPrivateKey));
- if(lpk == NULL) {
- goto loser;
- }
- lpk->arena = arena;
-
- switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- keyTemplate = nsslowkey_RSAPrivateKeyTemplate;
- paramTemplate = NULL;
- paramDest = NULL;
- lpk->keyType = NSSLOWKEYRSAKey;
- prepare_low_rsa_priv_key_for_asn1(lpk);
- break;
- case SEC_OID_ANSIX9_DSA_SIGNATURE:
- keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate;
- paramTemplate = nsslowkey_PQGParamsTemplate;
- paramDest = &(lpk->u.dsa.params);
- lpk->keyType = NSSLOWKEYDSAKey;
- prepare_low_dsa_priv_key_export_for_asn1(lpk);
- prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params);
- break;
- /* case NSSLOWKEYDHKey: */
-#ifdef NSS_ENABLE_ECC
- case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
- keyTemplate = nsslowkey_ECPrivateKeyTemplate;
- paramTemplate = NULL;
- paramDest = &(lpk->u.ec.ecParams.DEREncoding);
- lpk->keyType = NSSLOWKEYECKey;
- prepare_low_ec_priv_key_for_asn1(lpk);
- prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams);
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- keyTemplate = NULL;
- paramTemplate = NULL;
- paramDest = NULL;
- break;
- }
-
- if(!keyTemplate) {
- goto loser;
- }
-
- /* decode the private key and any algorithm parameters */
- rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
-
-#ifdef NSS_ENABLE_ECC
- if (lpk->keyType == NSSLOWKEYECKey) {
- /* convert length in bits to length in bytes */
- lpk->u.ec.publicValue.len >>= 3;
- rv = SECITEM_CopyItem(arena,
- &(lpk->u.ec.ecParams.DEREncoding),
- &(pki->algorithm.parameters));
- if(rv != SECSuccess) {
- goto loser;
- }
- }
-#endif /* NSS_ENABLE_ECC */
-
- if(rv != SECSuccess) {
- goto loser;
- }
- if(paramDest && paramTemplate) {
- rv = SEC_QuickDERDecodeItem(arena, paramDest, paramTemplate,
- &(pki->algorithm.parameters));
- if(rv != SECSuccess) {
- goto loser;
- }
- }
-
- rv = SECFailure;
-
- switch (lpk->keyType) {
- case NSSLOWKEYRSAKey:
- keyType = CKK_RSA;
- if(sftk_hasAttribute(key, CKA_NETSCAPE_DB)) {
- sftk_DeleteAttributeType(key, CKA_NETSCAPE_DB);
- }
- crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
- sizeof(keyType));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_UNWRAP, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_DECRYPT, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_MODULUS,
- sftk_item_expand(&lpk->u.rsa.modulus));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_PUBLIC_EXPONENT,
- sftk_item_expand(&lpk->u.rsa.publicExponent));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_PRIVATE_EXPONENT,
- sftk_item_expand(&lpk->u.rsa.privateExponent));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_PRIME_1,
- sftk_item_expand(&lpk->u.rsa.prime1));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_PRIME_2,
- sftk_item_expand(&lpk->u.rsa.prime2));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_EXPONENT_1,
- sftk_item_expand(&lpk->u.rsa.exponent1));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_EXPONENT_2,
- sftk_item_expand(&lpk->u.rsa.exponent2));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_COEFFICIENT,
- sftk_item_expand(&lpk->u.rsa.coefficient));
- break;
- case NSSLOWKEYDSAKey:
- keyType = CKK_DSA;
- crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK :
- CKR_KEY_TYPE_INCONSISTENT;
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
- sizeof(keyType));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_PRIME,
- sftk_item_expand(&lpk->u.dsa.params.prime));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_SUBPRIME,
- sftk_item_expand(&lpk->u.dsa.params.subPrime));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_BASE,
- sftk_item_expand(&lpk->u.dsa.params.base));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_VALUE,
- sftk_item_expand(&lpk->u.dsa.privateValue));
- if(crv != CKR_OK) break;
- break;
-#ifdef notdef
- case NSSLOWKEYDHKey:
- template = dhTemplate;
- templateCount = sizeof(dhTemplate)/sizeof(CK_ATTRIBUTE);
- keyType = CKK_DH;
- break;
-#endif
- /* what about fortezza??? */
-#ifdef NSS_ENABLE_ECC
- case NSSLOWKEYECKey:
- keyType = CKK_EC;
- crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK :
- CKR_KEY_TYPE_INCONSISTENT;
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType,
- sizeof(keyType));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_DERIVE, &cktrue,
- sizeof(CK_BBOOL));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_EC_PARAMS,
- sftk_item_expand(&lpk->u.ec.ecParams.DEREncoding));
- if(crv != CKR_OK) break;
- crv = sftk_AddAttributeType(key, CKA_VALUE,
- sftk_item_expand(&lpk->u.ec.privateValue));
- if(crv != CKR_OK) break;
- /* XXX Do we need to decode the EC Params here ?? */
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
-
-loser:
- if(lpk) {
- nsslowkey_DestroyPrivateKey(lpk);
- }
-
- if(crv != CKR_OK) {
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-
-/* NSC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
-CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey)
-{
- SFTKObject *key = NULL;
- SFTKSession *session;
- CK_ULONG key_length = 0;
- unsigned char * buf = NULL;
- CK_RV crv = CKR_OK;
- int i;
- CK_ULONG bsize = ulWrappedKeyLen;
- SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession);
- SECItem bpki;
- CK_OBJECT_CLASS target_type = CKO_SECRET_KEY;
-
- CHECK_FORK();
-
- if (!slot) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- /*
- * now lets create an object to hang the attributes off of
- */
- key = sftk_NewObject(slot); /* fill in the handle later */
- if (key == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulAttributeCount; i++) {
- if (pTemplate[i].type == CKA_VALUE_LEN) {
- key_length = *(CK_ULONG *)pTemplate[i].pValue;
- continue;
- }
- if (pTemplate[i].type == CKA_CLASS) {
- target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue;
- }
- crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) break;
- }
- if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return crv;
- }
-
- crv = sftk_CryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP,
- CKA_UNWRAP, SFTK_DECRYPT, PR_FALSE);
- if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return sftk_mapWrap(crv);
- }
-
- /* allocate the buffer to decrypt into
- * this assumes the unwrapped key is never larger than the
- * wrapped key. For all the mechanisms we support this is true */
- buf = (unsigned char *)PORT_Alloc( ulWrappedKeyLen);
- bsize = ulWrappedKeyLen;
-
- crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize);
- if (crv != CKR_OK) {
- sftk_FreeObject(key);
- PORT_Free(buf);
- return sftk_mapWrap(crv);
- }
-
- switch(target_type) {
- case CKO_SECRET_KEY:
- if (!sftk_hasAttribute(key,CKA_KEY_TYPE)) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- }
-
- if (key_length == 0 || key_length > bsize) {
- key_length = bsize;
- }
- if (key_length > MAX_KEY_LEN) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
-
- /* add the value */
- crv = sftk_AddAttributeType(key,CKA_VALUE,buf,key_length);
- break;
- case CKO_PRIVATE_KEY:
- bpki.data = (unsigned char *)buf;
- bpki.len = bsize;
- crv = CKR_OK;
- if(sftk_unwrapPrivateKey(key, &bpki) != SECSuccess) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- }
- break;
- default:
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
-
- PORT_ZFree(buf, bsize);
- if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
-
- /* get the session */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- sftk_FreeObject(key);
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /*
- * handle the base object stuff
- */
- crv = sftk_handleObject(key,session);
- *phKey = key->handle;
- sftk_FreeSession(session);
- sftk_FreeObject(key);
-
- return crv;
-
-}
-
-/*
- * The SSL key gen mechanism create's lots of keys. This function handles the
- * details of each of these key creation.
- */
-static CK_RV
-sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey,
- PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize,
- CK_OBJECT_HANDLE *keyHandle)
-{
- SFTKObject *key;
- SFTKSession *session;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_RV crv = CKR_HOST_MEMORY;
-
- /*
- * now lets create an object to hang the attributes off of
- */
- *keyHandle = CK_INVALID_HANDLE;
- key = sftk_NewObject(baseKey->slot);
- if (key == NULL) return CKR_HOST_MEMORY;
- sftk_narrowToSessionObject(key)->wasDerived = PR_TRUE;
-
- crv = sftk_CopyObject(key,baseKey);
- if (crv != CKR_OK) goto loser;
- if (isMacKey) {
- crv = sftk_forceAttribute(key,CKA_KEY_TYPE,&keyType,sizeof(keyType));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(key,CKA_ENCRYPT,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(key,CKA_DECRYPT,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(key,CKA_SIGN,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(key,CKA_WRAP,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- crv = sftk_forceAttribute(key,CKA_UNWRAP,&ckfalse,sizeof(CK_BBOOL));
- if (crv != CKR_OK) goto loser;
- }
- crv = sftk_forceAttribute(key,CKA_VALUE,keyBlock,keySize);
- if (crv != CKR_OK) goto loser;
-
- /* get the session */
- crv = CKR_HOST_MEMORY;
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) { goto loser; }
-
- crv = sftk_handleObject(key,session);
- sftk_FreeSession(session);
- *keyHandle = key->handle;
-loser:
- if (key) sftk_FreeObject(key);
- return crv;
-}
-
-/*
- * if there is an error, we need to free the keys we already created in SSL
- * This is the routine that will do it..
- */
-static void
-sftk_freeSSLKeys(CK_SESSION_HANDLE session,
- CK_SSL3_KEY_MAT_OUT *returnedMaterial )
-{
- if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE) {
- NSC_DestroyObject(session,returnedMaterial->hClientMacSecret);
- }
- if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE) {
- NSC_DestroyObject(session, returnedMaterial->hServerMacSecret);
- }
- if (returnedMaterial->hClientKey != CK_INVALID_HANDLE) {
- NSC_DestroyObject(session, returnedMaterial->hClientKey);
- }
- if (returnedMaterial->hServerKey != CK_INVALID_HANDLE) {
- NSC_DestroyObject(session, returnedMaterial->hServerKey);
- }
-}
-
-/*
- * when deriving from sensitive and extractable keys, we need to preserve some
- * of the semantics in the derived key. This helper routine maintains these
- * semantics.
- */
-static CK_RV
-sftk_DeriveSensitiveCheck(SFTKObject *baseKey,SFTKObject *destKey)
-{
- PRBool hasSensitive;
- PRBool sensitive = PR_FALSE;
- PRBool hasExtractable;
- PRBool extractable = PR_TRUE;
- CK_RV crv = CKR_OK;
- SFTKAttribute *att;
-
- hasSensitive = PR_FALSE;
- att = sftk_FindAttribute(destKey,CKA_SENSITIVE);
- if (att) {
- hasSensitive = PR_TRUE;
- sensitive = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
- sftk_FreeAttribute(att);
- }
-
- hasExtractable = PR_FALSE;
- att = sftk_FindAttribute(destKey,CKA_EXTRACTABLE);
- if (att) {
- hasExtractable = PR_TRUE;
- extractable = (PRBool) *(CK_BBOOL *)att->attrib.pValue;
- sftk_FreeAttribute(att);
- }
-
-
- /* don't make a key more accessible */
- if (sftk_isTrue(baseKey,CKA_SENSITIVE) && hasSensitive &&
- (sensitive == PR_FALSE)) {
- return CKR_KEY_FUNCTION_NOT_PERMITTED;
- }
- if (!sftk_isTrue(baseKey,CKA_EXTRACTABLE) && hasExtractable &&
- (extractable == PR_TRUE)) {
- return CKR_KEY_FUNCTION_NOT_PERMITTED;
- }
-
- /* inherit parent's sensitivity */
- if (!hasSensitive) {
- att = sftk_FindAttribute(baseKey,CKA_SENSITIVE);
- if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT;
- crv = sftk_defaultAttribute(destKey,sftk_attr_expand(&att->attrib));
- sftk_FreeAttribute(att);
- if (crv != CKR_OK) return crv;
- }
- if (!hasExtractable) {
- att = sftk_FindAttribute(baseKey,CKA_EXTRACTABLE);
- if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT;
- crv = sftk_defaultAttribute(destKey,sftk_attr_expand(&att->attrib));
- sftk_FreeAttribute(att);
- if (crv != CKR_OK) return crv;
- }
-
- /* we should inherit the parent's always extractable/ never sensitive info,
- * but handleObject always forces this attributes, so we would need to do
- * something special. */
- return CKR_OK;
-}
-
-/*
- * make known fixed PKCS #11 key types to their sizes in bytes
- */
-unsigned long
-sftk_MapKeySize(CK_KEY_TYPE keyType)
-{
- switch (keyType) {
- case CKK_CDMF:
- return 8;
- case CKK_DES:
- return 8;
- case CKK_DES2:
- return 16;
- case CKK_DES3:
- return 24;
- /* IDEA and CAST need to be added */
- default:
- break;
- }
- return 0;
-}
-
-/* Inputs:
- * key_len: Length of derived key to be generated.
- * SharedSecret: a shared secret that is the output of a key agreement primitive.
- * SharedInfo: (Optional) some data shared by the entities computing the secret key.
- * SharedInfoLen: the length in octets of SharedInfo
- * Hash: The hash function to be used in the KDF
- * HashLen: the length in octets of the output of Hash
- * Output:
- * key: Pointer to a buffer containing derived key, if return value is SECSuccess.
- */
-static CK_RV sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECItem *SharedSecret,
- CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen,
- SECStatus Hash(unsigned char *, const unsigned char *, uint32),
- CK_ULONG HashLen)
-{
- unsigned char *buffer = NULL, *output_buffer = NULL;
- uint32 buffer_len, max_counter, i;
- SECStatus rv;
-
- /* Check that key_len isn't too long. The maximum key length could be
- * greatly increased if the code below did not limit the 4-byte counter
- * to a maximum value of 255. */
- if (key_len > 254 * HashLen)
- return SEC_ERROR_INVALID_ARGS;
-
- if (SharedInfo == NULL)
- SharedInfoLen = 0;
-
- buffer_len = SharedSecret->len + 4 + SharedInfoLen;
- buffer = (CK_BYTE *)PORT_Alloc(buffer_len);
- if (buffer == NULL) {
- rv = SEC_ERROR_NO_MEMORY;
- goto loser;
- }
-
- max_counter = key_len/HashLen;
- if (key_len > max_counter * HashLen)
- max_counter++;
-
- output_buffer = (CK_BYTE *)PORT_Alloc(max_counter * HashLen);
- if (output_buffer == NULL) {
- rv = SEC_ERROR_NO_MEMORY;
- goto loser;
- }
-
- /* Populate buffer with SharedSecret || Counter || [SharedInfo]
- * where Counter is 0x00000001 */
- PORT_Memcpy(buffer, SharedSecret->data, SharedSecret->len);
- buffer[SharedSecret->len] = 0;
- buffer[SharedSecret->len + 1] = 0;
- buffer[SharedSecret->len + 2] = 0;
- buffer[SharedSecret->len + 3] = 1;
- if (SharedInfo) {
- PORT_Memcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen);
- }
-
- for(i=0; i < max_counter; i++) {
- rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len);
- if (rv != SECSuccess)
- goto loser;
-
- /* Increment counter (assumes max_counter < 255) */
- buffer[SharedSecret->len + 3]++;
- }
-
- PORT_ZFree(buffer, buffer_len);
- if (key_len < max_counter * HashLen) {
- PORT_Memset(output_buffer + key_len, 0, max_counter * HashLen - key_len);
- }
- *key = output_buffer;
-
- return SECSuccess;
-
- loser:
- if (buffer) {
- PORT_ZFree(buffer, buffer_len);
- }
- if (output_buffer) {
- PORT_ZFree(output_buffer, max_counter * HashLen);
- }
- return rv;
-}
-
-static CK_RV sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len,
- SECItem *SharedSecret,
- CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen,
- CK_EC_KDF_TYPE kdf)
-{
- if (kdf == CKD_SHA1_KDF)
- return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
- SharedInfoLen, SHA1_HashBuf, SHA1_LENGTH);
- else if (kdf == CKD_SHA224_KDF)
- return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
- SharedInfoLen, SHA224_HashBuf, SHA224_LENGTH);
- else if (kdf == CKD_SHA256_KDF)
- return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
- SharedInfoLen, SHA256_HashBuf, SHA256_LENGTH);
- else if (kdf == CKD_SHA384_KDF)
- return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
- SharedInfoLen, SHA384_HashBuf, SHA384_LENGTH);
- else if (kdf == CKD_SHA512_KDF)
- return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo,
- SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH);
- else
- return SEC_ERROR_INVALID_ALGORITHM;
-}
-
-/*
- * SSL Key generation given pre master secret
- */
-#define NUM_MIXERS 9
-static const char * const mixers[NUM_MIXERS] = {
- "A",
- "BB",
- "CCC",
- "DDDD",
- "EEEEE",
- "FFFFFF",
- "GGGGGGG",
- "HHHHHHHH",
- "IIIIIIIII" };
-#define SSL3_PMS_LENGTH 48
-#define SSL3_MASTER_SECRET_LENGTH 48
-#define SSL3_RANDOM_LENGTH 32
-
-
-/* NSC_DeriveKey derives a key from a base key, creating a new key object. */
-CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey)
-{
- SFTKSession * session;
- SFTKSlot * slot = sftk_SlotFromSessionHandle(hSession);
- SFTKObject * key;
- SFTKObject * sourceKey;
- SFTKAttribute * att = NULL;
- SFTKAttribute * att2 = NULL;
- unsigned char * buf;
- SHA1Context * sha;
- MD5Context * md5;
- MD2Context * md2;
- CK_ULONG macSize;
- CK_ULONG tmpKeySize;
- CK_ULONG IVSize;
- CK_ULONG keySize = 0;
- CK_RV crv = CKR_OK;
- CK_BBOOL cktrue = CK_TRUE;
- CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
- CK_OBJECT_CLASS classType = CKO_SECRET_KEY;
- CK_KEY_DERIVATION_STRING_DATA *stringPtr;
- PRBool isTLS = PR_FALSE;
- PRBool isDH = PR_FALSE;
- SECStatus rv;
- int i;
- unsigned int outLen;
- unsigned char sha_out[SHA1_LENGTH];
- unsigned char key_block[NUM_MIXERS * MD5_LENGTH];
- unsigned char key_block2[MD5_LENGTH];
- PRBool isFIPS;
- HASH_HashType hashType;
- PRBool extractValue = PR_TRUE;
-
- CHECK_FORK();
-
- if (!slot) {
- return CKR_SESSION_HANDLE_INVALID;
- }
- /*
- * now lets create an object to hang the attributes off of
- */
- if (phKey) *phKey = CK_INVALID_HANDLE;
-
- key = sftk_NewObject(slot); /* fill in the handle later */
- if (key == NULL) {
- return CKR_HOST_MEMORY;
- }
- isFIPS = (slot->slotID == FIPS_SLOT_ID);
-
- /*
- * load the template values into the object
- */
- for (i=0; i < (int) ulAttributeCount; i++) {
- crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) break;
-
- if (pTemplate[i].type == CKA_KEY_TYPE) {
- keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue;
- }
- if (pTemplate[i].type == CKA_VALUE_LEN) {
- keySize = *(CK_ULONG *)pTemplate[i].pValue;
- }
- }
- if (crv != CKR_OK) { sftk_FreeObject(key); return crv; }
-
- if (keySize == 0) {
- keySize = sftk_MapKeySize(keyType);
- }
-
- switch (pMechanism->mechanism) {
- case CKM_NSS_JPAKE_ROUND2_SHA1: /* fall through */
- case CKM_NSS_JPAKE_ROUND2_SHA256: /* fall through */
- case CKM_NSS_JPAKE_ROUND2_SHA384: /* fall through */
- case CKM_NSS_JPAKE_ROUND2_SHA512:
- extractValue = PR_FALSE;
- classType = CKO_PRIVATE_KEY;
- break;
- case CKM_NSS_JPAKE_FINAL_SHA1: /* fall through */
- case CKM_NSS_JPAKE_FINAL_SHA256: /* fall through */
- case CKM_NSS_JPAKE_FINAL_SHA384: /* fall through */
- case CKM_NSS_JPAKE_FINAL_SHA512:
- extractValue = PR_FALSE;
- /* fall through */
- default:
- classType = CKO_SECRET_KEY;
- }
-
- crv = sftk_forceAttribute (key,CKA_CLASS,&classType,sizeof(classType));
- if (crv != CKR_OK) {
- sftk_FreeObject(key);
- return crv;
- }
-
- /* look up the base key we're deriving with */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- sftk_FreeObject(key);
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- sourceKey = sftk_ObjectFromHandle(hBaseKey,session);
- sftk_FreeSession(session);
- if (sourceKey == NULL) {
- sftk_FreeObject(key);
- return CKR_KEY_HANDLE_INVALID;
- }
-
- if (extractValue) {
- /* get the value of the base key */
- att = sftk_FindAttribute(sourceKey,CKA_VALUE);
- if (att == NULL) {
- sftk_FreeObject(key);
- sftk_FreeObject(sourceKey);
- return CKR_KEY_HANDLE_INVALID;
- }
- }
-
- switch (pMechanism->mechanism) {
- /*
- * generate the master secret
- */
- case CKM_TLS_MASTER_KEY_DERIVE:
- case CKM_TLS_MASTER_KEY_DERIVE_DH:
- isTLS = PR_TRUE;
- /* fall thru */
- case CKM_SSL3_MASTER_KEY_DERIVE:
- case CKM_SSL3_MASTER_KEY_DERIVE_DH:
- {
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master;
- SSL3RSAPreMasterSecret * rsa_pms;
- unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
-
- if ((pMechanism->mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) ||
- (pMechanism->mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH))
- isDH = PR_TRUE;
-
- /* first do the consistancy checks */
- if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE);
- if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
- CKK_GENERIC_SECRET)) {
- if (att2) sftk_FreeAttribute(att2);
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
- sftk_FreeAttribute(att2);
- if (keyType != CKK_GENERIC_SECRET) {
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
- if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) {
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
-
- /* finally do the key gen */
- ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
- pMechanism->pParameter;
-
- PORT_Memcpy(crsrdata,
- ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
- ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
-
- if (ssl3_master->pVersion) {
- SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
- rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
- /* don't leak more key material then necessary for SSL to work */
- if ((sessKey == NULL) || sessKey->wasDerived) {
- ssl3_master->pVersion->major = 0xff;
- ssl3_master->pVersion->minor = 0xff;
- } else {
- ssl3_master->pVersion->major = rsa_pms->client_version[0];
- ssl3_master->pVersion->minor = rsa_pms->client_version[1];
- }
- }
- if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
-
- if (isTLS) {
- SECStatus status;
- SECItem crsr = { siBuffer, NULL, 0 };
- SECItem master = { siBuffer, NULL, 0 };
- SECItem pms = { siBuffer, NULL, 0 };
-
- crsr.data = crsrdata;
- crsr.len = sizeof crsrdata;
- master.data = key_block;
- master.len = SSL3_MASTER_SECRET_LENGTH;
- pms.data = (unsigned char*)att->attrib.pValue;
- pms.len = att->attrib.ulValueLen;
-
- status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS);
- if (status != SECSuccess) {
- crv = CKR_FUNCTION_FAILED;
- break;
- }
- } else {
- /* now allocate the hash contexts */
- md5 = MD5_NewContext();
- if (md5 == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- sha = SHA1_NewContext();
- if (sha == NULL) {
- PORT_Free(md5);
- crv = CKR_HOST_MEMORY;
- break;
- }
- for (i = 0; i < 3; i++) {
- SHA1_Begin(sha);
- SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
- SHA1_Update(sha, (const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- SHA1_Update(sha, crsrdata, sizeof crsrdata);
- SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
- PORT_Assert(outLen == SHA1_LENGTH);
-
- MD5_Begin(md5);
- MD5_Update(md5, (const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- MD5_Update(md5, sha_out, outLen);
- MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH);
- PORT_Assert(outLen == MD5_LENGTH);
- }
- PORT_Free(md5);
- PORT_Free(sha);
- }
-
- /* store the results */
- crv = sftk_forceAttribute
- (key,CKA_VALUE,key_block,SSL3_MASTER_SECRET_LENGTH);
- if (crv != CKR_OK) break;
- keyType = CKK_GENERIC_SECRET;
- crv = sftk_forceAttribute (key,CKA_KEY_TYPE,&keyType,sizeof(keyType));
- if (isTLS) {
- /* TLS's master secret is used to "sign" finished msgs with PRF. */
- /* XXX This seems like a hack. But SFTK_Derive only accepts
- * one "operation" argument. */
- crv = sftk_forceAttribute(key,CKA_SIGN, &cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) break;
- crv = sftk_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) break;
- /* While we're here, we might as well force this, too. */
- crv = sftk_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL));
- if (crv != CKR_OK) break;
- }
- break;
- }
-
- case CKM_TLS_KEY_AND_MAC_DERIVE:
- isTLS = PR_TRUE;
- /* fall thru */
- case CKM_SSL3_KEY_AND_MAC_DERIVE:
- {
- CK_SSL3_KEY_MAT_PARAMS *ssl3_keys;
- CK_SSL3_KEY_MAT_OUT * ssl3_keys_out;
- CK_ULONG effKeySize;
- unsigned int block_needed;
- unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2];
- unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
-
- crv = sftk_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) break;
-
- if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH) {
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
- att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE);
- if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue !=
- CKK_GENERIC_SECRET)) {
- if (att2) sftk_FreeAttribute(att2);
- crv = CKR_KEY_FUNCTION_NOT_PERMITTED;
- break;
- }
- sftk_FreeAttribute(att2);
- md5 = MD5_NewContext();
- if (md5 == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- sha = SHA1_NewContext();
- if (sha == NULL) {
- PORT_Free(md5);
- crv = CKR_HOST_MEMORY;
- break;
- }
- ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter;
-
- PORT_Memcpy(srcrdata,
- ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH,
- ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
-
- PORT_Memcpy(crsrdata,
- ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH,
- ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH);
-
- /*
- * clear out our returned keys so we can recover on failure
- */
- ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial;
- ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE;
- ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE;
- ssl3_keys_out->hClientKey = CK_INVALID_HANDLE;
- ssl3_keys_out->hServerKey = CK_INVALID_HANDLE;
-
- /*
- * How much key material do we need?
- */
- macSize = ssl3_keys->ulMacSizeInBits/8;
- effKeySize = ssl3_keys->ulKeySizeInBits/8;
- IVSize = ssl3_keys->ulIVSizeInBits/8;
- if (keySize == 0) {
- effKeySize = keySize;
- }
- block_needed = 2 * (macSize + effKeySize +
- ((!ssl3_keys->bIsExport) * IVSize));
- PORT_Assert(block_needed <= sizeof key_block);
- if (block_needed > sizeof key_block)
- block_needed = sizeof key_block;
-
- /*
- * generate the key material: This looks amazingly similar to the
- * PMS code, and is clearly crying out for a function to provide it.
- */
- if (isTLS) {
- SECStatus status;
- SECItem srcr = { siBuffer, NULL, 0 };
- SECItem keyblk = { siBuffer, NULL, 0 };
- SECItem master = { siBuffer, NULL, 0 };
-
- srcr.data = srcrdata;
- srcr.len = sizeof srcrdata;
- keyblk.data = key_block;
- keyblk.len = block_needed;
- master.data = (unsigned char*)att->attrib.pValue;
- master.len = att->attrib.ulValueLen;
-
- status = TLS_PRF(&master, "key expansion", &srcr, &keyblk,
- isFIPS);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- } else {
- unsigned int block_bytes = 0;
- /* key_block =
- * MD5(master_secret + SHA('A' + master_secret +
- * ServerHello.random + ClientHello.random)) +
- * MD5(master_secret + SHA('BB' + master_secret +
- * ServerHello.random + ClientHello.random)) +
- * MD5(master_secret + SHA('CCC' + master_secret +
- * ServerHello.random + ClientHello.random)) +
- * [...];
- */
- for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) {
- SHA1_Begin(sha);
- SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i]));
- SHA1_Update(sha, (const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- SHA1_Update(sha, srcrdata, sizeof srcrdata);
- SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH);
- PORT_Assert(outLen == SHA1_LENGTH);
- MD5_Begin(md5);
- MD5_Update(md5, (const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- MD5_Update(md5, sha_out, outLen);
- MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH);
- PORT_Assert(outLen == MD5_LENGTH);
- block_bytes += outLen;
- }
- }
-
- /*
- * Put the key material where it goes.
- */
- i = 0; /* now shows how much consumed */
-
- /*
- * The key_block is partitioned as follows:
- * client_write_MAC_secret[CipherSpec.hash_size]
- */
- crv = sftk_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize,
- &ssl3_keys_out->hClientMacSecret);
- if (crv != CKR_OK)
- goto key_and_mac_derive_fail;
-
- i += macSize;
-
- /*
- * server_write_MAC_secret[CipherSpec.hash_size]
- */
- crv = sftk_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize,
- &ssl3_keys_out->hServerMacSecret);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
- i += macSize;
-
- if (keySize) {
- if (!ssl3_keys->bIsExport) {
- /*
- ** Generate Domestic write keys and IVs.
- ** client_write_key[CipherSpec.key_material]
- */
- crv = sftk_buildSSLKey(hSession,key,PR_FALSE,&key_block[i],
- keySize, &ssl3_keys_out->hClientKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
- i += keySize;
-
- /*
- ** server_write_key[CipherSpec.key_material]
- */
- crv = sftk_buildSSLKey(hSession,key,PR_FALSE,&key_block[i],
- keySize, &ssl3_keys_out->hServerKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
- i += keySize;
-
- /*
- ** client_write_IV[CipherSpec.IV_size]
- */
- if (IVSize > 0) {
- PORT_Memcpy(ssl3_keys_out->pIVClient,
- &key_block[i], IVSize);
- i += IVSize;
- }
-
- /*
- ** server_write_IV[CipherSpec.IV_size]
- */
- if (IVSize > 0) {
- PORT_Memcpy(ssl3_keys_out->pIVServer,
- &key_block[i], IVSize);
- i += IVSize;
- }
- PORT_Assert(i <= sizeof key_block);
-
- } else if (!isTLS) {
-
- /*
- ** Generate SSL3 Export write keys and IVs.
- ** client_write_key[CipherSpec.key_material]
- ** final_client_write_key = MD5(client_write_key +
- ** ClientHello.random + ServerHello.random);
- */
- MD5_Begin(md5);
- MD5_Update(md5, &key_block[i], effKeySize);
- MD5_Update(md5, crsrdata, sizeof crsrdata);
- MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
- i += effKeySize;
- crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2,
- keySize,&ssl3_keys_out->hClientKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
-
- /*
- ** server_write_key[CipherSpec.key_material]
- ** final_server_write_key = MD5(server_write_key +
- ** ServerHello.random + ClientHello.random);
- */
- MD5_Begin(md5);
- MD5_Update(md5, &key_block[i], effKeySize);
- MD5_Update(md5, srcrdata, sizeof srcrdata);
- MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
- i += effKeySize;
- crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2,
- keySize,&ssl3_keys_out->hServerKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
-
- /*
- ** client_write_IV =
- ** MD5(ClientHello.random + ServerHello.random);
- */
- MD5_Begin(md5);
- MD5_Update(md5, crsrdata, sizeof crsrdata);
- MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
- PORT_Memcpy(ssl3_keys_out->pIVClient, key_block2, IVSize);
-
- /*
- ** server_write_IV =
- ** MD5(ServerHello.random + ClientHello.random);
- */
- MD5_Begin(md5);
- MD5_Update(md5, srcrdata, sizeof srcrdata);
- MD5_End(md5, key_block2, &outLen, MD5_LENGTH);
- PORT_Memcpy(ssl3_keys_out->pIVServer, key_block2, IVSize);
-
- } else {
-
- /*
- ** Generate TLS Export write keys and IVs.
- */
- SECStatus status;
- SECItem secret = { siBuffer, NULL, 0 };
- SECItem crsr = { siBuffer, NULL, 0 };
- SECItem keyblk = { siBuffer, NULL, 0 };
-
- /*
- ** client_write_key[CipherSpec.key_material]
- ** final_client_write_key = PRF(client_write_key,
- ** "client write key",
- ** client_random + server_random);
- */
- secret.data = &key_block[i];
- secret.len = effKeySize;
- i += effKeySize;
- crsr.data = crsrdata;
- crsr.len = sizeof crsrdata;
- keyblk.data = key_block2;
- keyblk.len = sizeof key_block2;
- status = TLS_PRF(&secret, "client write key", &crsr, &keyblk,
- isFIPS);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- crv = sftk_buildSSLKey(hSession, key, PR_FALSE, key_block2,
- keySize, &ssl3_keys_out->hClientKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
-
- /*
- ** server_write_key[CipherSpec.key_material]
- ** final_server_write_key = PRF(server_write_key,
- ** "server write key",
- ** client_random + server_random);
- */
- secret.data = &key_block[i];
- secret.len = effKeySize;
- i += effKeySize;
- keyblk.data = key_block2;
- keyblk.len = sizeof key_block2;
- status = TLS_PRF(&secret, "server write key", &crsr, &keyblk,
- isFIPS);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- crv = sftk_buildSSLKey(hSession, key, PR_FALSE, key_block2,
- keySize, &ssl3_keys_out->hServerKey);
- if (crv != CKR_OK) {
- goto key_and_mac_derive_fail;
- }
-
- /*
- ** iv_block = PRF("", "IV block",
- ** client_random + server_random);
- ** client_write_IV[SecurityParameters.IV_size]
- ** server_write_IV[SecurityParameters.IV_size]
- */
- if (IVSize) {
- secret.data = NULL;
- secret.len = 0;
- keyblk.data = &key_block[i];
- keyblk.len = 2 * IVSize;
- status = TLS_PRF(&secret, "IV block", &crsr, &keyblk,
- isFIPS);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- PORT_Memcpy(ssl3_keys_out->pIVClient, keyblk.data, IVSize);
- PORT_Memcpy(ssl3_keys_out->pIVServer, keyblk.data + IVSize,
- IVSize);
- }
- }
- }
-
- crv = CKR_OK;
-
- if (0) {
-key_and_mac_derive_fail:
- if (crv == CKR_OK)
- crv = CKR_FUNCTION_FAILED;
- sftk_freeSSLKeys(hSession, ssl3_keys_out);
- }
- MD5_DestroyContext(md5, PR_TRUE);
- SHA1_DestroyContext(sha, PR_TRUE);
- sftk_FreeObject(key);
- key = NULL;
- break;
- }
-
- case CKM_CONCATENATE_BASE_AND_KEY:
- {
- SFTKObject *newKey;
-
- crv = sftk_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) break;
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- crv = CKR_SESSION_HANDLE_INVALID;
- break;
- }
-
- newKey = sftk_ObjectFromHandle(*(CK_OBJECT_HANDLE *)
- pMechanism->pParameter,session);
- sftk_FreeSession(session);
- if ( newKey == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
-
- if (sftk_isTrue(newKey,CKA_SENSITIVE)) {
- crv = sftk_forceAttribute(newKey,CKA_SENSITIVE,&cktrue,
- sizeof(CK_BBOOL));
- if (crv != CKR_OK) {
- sftk_FreeObject(newKey);
- break;
- }
- }
-
- att2 = sftk_FindAttribute(newKey,CKA_VALUE);
- if (att2 == NULL) {
- sftk_FreeObject(newKey);
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- tmpKeySize = att->attrib.ulValueLen+att2->attrib.ulValueLen;
- if (keySize == 0) keySize = tmpKeySize;
- if (keySize > tmpKeySize) {
- sftk_FreeObject(newKey);
- sftk_FreeAttribute(att2);
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(tmpKeySize);
- if (buf == NULL) {
- sftk_FreeAttribute(att2);
- sftk_FreeObject(newKey);
- crv = CKR_HOST_MEMORY;
- break;
- }
-
- PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen);
- PORT_Memcpy(buf+att->attrib.ulValueLen,
- att2->attrib.pValue,att2->attrib.ulValueLen);
-
- crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,tmpKeySize);
- sftk_FreeAttribute(att2);
- sftk_FreeObject(newKey);
- break;
- }
-
- case CKM_CONCATENATE_BASE_AND_DATA:
- crv = sftk_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) break;
-
- stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter;
- tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
- if (keySize == 0) keySize = tmpKeySize;
- if (keySize > tmpKeySize) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(tmpKeySize);
- if (buf == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
-
- PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen);
- PORT_Memcpy(buf+att->attrib.ulValueLen,stringPtr->pData,
- stringPtr->ulLen);
-
- crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,tmpKeySize);
- break;
- case CKM_CONCATENATE_DATA_AND_BASE:
- crv = sftk_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) break;
-
- stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
- tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen;
- if (keySize == 0) keySize = tmpKeySize;
- if (keySize > tmpKeySize) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(tmpKeySize);
- if (buf == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
-
- PORT_Memcpy(buf,stringPtr->pData,stringPtr->ulLen);
- PORT_Memcpy(buf+stringPtr->ulLen,att->attrib.pValue,
- att->attrib.ulValueLen);
-
- crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,tmpKeySize);
- break;
- case CKM_XOR_BASE_AND_DATA:
- crv = sftk_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) break;
-
- stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter;
- tmpKeySize = PR_MIN(att->attrib.ulValueLen,stringPtr->ulLen);
- if (keySize == 0) keySize = tmpKeySize;
- if (keySize > tmpKeySize) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(keySize);
- if (buf == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
-
-
- PORT_Memcpy(buf,att->attrib.pValue,keySize);
- for (i=0; i < (int)keySize; i++) {
- buf[i] ^= stringPtr->pData[i];
- }
-
- crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,keySize);
- break;
-
- case CKM_EXTRACT_KEY_FROM_KEY:
- {
- /* the following assumes 8 bits per byte */
- CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter;
- CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */
- CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */
-
- crv = sftk_DeriveSensitiveCheck(sourceKey,key);
- if (crv != CKR_OK) break;
-
- if (keySize == 0) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- break;
- }
- /* make sure we have enough bits in the original key */
- if (att->attrib.ulValueLen <
- (offset + keySize + ((shift != 0)? 1 :0)) ) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- buf = (unsigned char*)PORT_Alloc(keySize);
- if (buf == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
-
- /* copy the bits we need into the new key */
- for (i=0; i < (int)keySize; i++) {
- unsigned char *value =
- ((unsigned char *)att->attrib.pValue)+offset+i;
- if (shift) {
- buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift));
- } else {
- buf[i] = value[0];
- }
- }
-
- crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize);
- PORT_ZFree(buf,keySize);
- break;
- }
- case CKM_MD2_KEY_DERIVATION:
- if (keySize == 0) keySize = MD2_LENGTH;
- if (keySize > MD2_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- /* now allocate the hash contexts */
- md2 = MD2_NewContext();
- if (md2 == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- MD2_Begin(md2);
- MD2_Update(md2,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- MD2_End(md2,key_block,&outLen,MD2_LENGTH);
- MD2_DestroyContext(md2, PR_TRUE);
-
- crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize);
- break;
- case CKM_MD5_KEY_DERIVATION:
- if (keySize == 0) keySize = MD5_LENGTH;
- if (keySize > MD5_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- MD5_HashBuf(key_block,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
-
- crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize);
- break;
- case CKM_SHA1_KEY_DERIVATION:
- if (keySize == 0) keySize = SHA1_LENGTH;
- if (keySize > SHA1_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- SHA1_HashBuf(key_block,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
-
- crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize);
- break;
-
- case CKM_SHA224_KEY_DERIVATION:
- if (keySize == 0) keySize = SHA224_LENGTH;
- if (keySize > SHA224_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- SHA224_HashBuf(key_block,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
-
- crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize);
- break;
-
- case CKM_SHA256_KEY_DERIVATION:
- if (keySize == 0) keySize = SHA256_LENGTH;
- if (keySize > SHA256_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- SHA256_HashBuf(key_block,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
-
- crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize);
- break;
-
- case CKM_SHA384_KEY_DERIVATION:
- if (keySize == 0) keySize = SHA384_LENGTH;
- if (keySize > SHA384_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- SHA384_HashBuf(key_block,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
-
- crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize);
- break;
-
- case CKM_SHA512_KEY_DERIVATION:
- if (keySize == 0) keySize = SHA512_LENGTH;
- if (keySize > SHA512_LENGTH) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- SHA512_HashBuf(key_block,(const unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
-
- crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize);
- break;
-
- case CKM_DH_PKCS_DERIVE:
- {
- SECItem derived, dhPublic;
- SECItem dhPrime, dhValue;
- /* sourceKey - values for the local existing low key */
- /* get prime and value attributes */
- crv = sftk_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME);
- if (crv != SECSuccess) break;
- crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE);
- if (crv != SECSuccess) {
- PORT_Free(dhPrime.data);
- break;
- }
-
- dhPublic.data = pMechanism->pParameter;
- dhPublic.len = pMechanism->ulParameterLen;
-
- /* calculate private value - oct */
- rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
-
- PORT_Free(dhPrime.data);
- PORT_Free(dhValue.data);
-
- if (rv == SECSuccess) {
- sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
- PORT_ZFree(derived.data, derived.len);
- } else
- crv = CKR_HOST_MEMORY;
-
- break;
- }
-
-#ifdef NSS_ENABLE_ECC
- case CKM_ECDH1_DERIVE:
- case CKM_ECDH1_COFACTOR_DERIVE:
- {
- SECItem ecScalar, ecPoint;
- SECItem tmp;
- PRBool withCofactor = PR_FALSE;
- unsigned char *secret;
- unsigned char *keyData = NULL;
- int secretlen, curveLen, pubKeyLen;
- CK_ECDH1_DERIVE_PARAMS *mechParams;
- NSSLOWKEYPrivateKey *privKey;
- PLArenaPool *arena = NULL;
-
- /* Check mechanism parameters */
- mechParams = (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter;
- if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) ||
- ((mechParams->kdf == CKD_NULL) &&
- ((mechParams->ulSharedDataLen != 0) ||
- (mechParams->pSharedData != NULL)))) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
-
- privKey = sftk_GetPrivKey(sourceKey, CKK_EC, &crv);
- if (privKey == NULL) {
- break;
- }
-
- /* Now we are working with a non-NULL private key */
- SECITEM_CopyItem(NULL, &ecScalar, &privKey->u.ec.privateValue);
-
- ecPoint.data = mechParams->pPublicData;
- ecPoint.len = mechParams->ulPublicDataLen;
-
- curveLen = (privKey->u.ec.ecParams.fieldID.size +7)/8;
- pubKeyLen = (2*curveLen) + 1;
-
- /* if the len is too small, can't be a valid point */
- if (ecPoint.len < pubKeyLen) {
- goto ec_loser;
- }
- /* if the len is too large, must be an encoded point (length is
- * equal case just falls through */
- if (ecPoint.len > pubKeyLen) {
- SECItem newPoint;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto ec_loser;
- }
-
- rv = SEC_QuickDERDecodeItem(arena, &newPoint,
- SEC_ASN1_GET(SEC_OctetStringTemplate),
- &ecPoint);
- if (rv != SECSuccess) {
- goto ec_loser;
- }
- ecPoint = newPoint;
- }
-
- if (pMechanism->mechanism == CKM_ECDH1_COFACTOR_DERIVE) {
- withCofactor = PR_TRUE;
- } else {
- /* When not using cofactor derivation, one should
- * validate the public key to avoid small subgroup
- * attacks.
- */
- if (EC_ValidatePublicKey(&privKey->u.ec.ecParams, &ecPoint)
- != SECSuccess) {
- goto ec_loser;
- }
- }
-
- rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar,
- withCofactor, &tmp);
- PORT_Free(ecScalar.data);
- ecScalar.data = NULL;
- if (privKey != sourceKey->objectInfo) {
- nsslowkey_DestroyPrivateKey(privKey);
- privKey=NULL;
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- arena=NULL;
- }
-
- if (rv != SECSuccess) {
- crv = sftk_MapCryptError(PORT_GetError());
- break;
- }
-
-
- /*
- * apply the kdf function.
- */
- if (mechParams->kdf == CKD_NULL) {
- /*
- * tmp is the raw data created by ECDH_Derive,
- * secret and secretlen are the values we will
- * eventually pass as our generated key.
- */
- secret = tmp.data;
- secretlen = tmp.len;
- } else {
- secretlen = keySize;
- rv = sftk_ANSI_X9_63_kdf(&secret, keySize,
- &tmp, mechParams->pSharedData,
- mechParams->ulSharedDataLen, mechParams->kdf);
- PORT_ZFree(tmp.data, tmp.len);
- if (rv != SECSuccess) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- tmp.data = secret;
- tmp.len = secretlen;
- }
-
- /*
- * if keySize is supplied, then we are generating a key of a specific
- * length. This is done by taking the least significant 'keySize'
- * bytes from the unsigned value calculated by ECDH. Note: this may
- * mean padding temp with extra leading zeros from what ECDH_Derive
- * already returned (which itself may contain leading zeros).
- */
- if (keySize) {
- if (secretlen < keySize) {
- keyData = PORT_ZAlloc(keySize);
- if (!keyData) {
- PORT_ZFree(tmp.data, tmp.len);
- crv = CKR_HOST_MEMORY;
- break;
- }
- PORT_Memcpy(&keyData[keySize-secretlen],secret,secretlen);
- secret = keyData;
- } else {
- secret += (secretlen - keySize);
- }
- secretlen = keySize;
- }
-
- sftk_forceAttribute(key, CKA_VALUE, secret, secretlen);
- PORT_ZFree(tmp.data, tmp.len);
- if (keyData) {
- PORT_ZFree(keyData, keySize);
- }
- break;
-
-ec_loser:
- crv = CKR_ARGUMENTS_BAD;
- PORT_Free(ecScalar.data);
- if (privKey != sourceKey->objectInfo)
- nsslowkey_DestroyPrivateKey(privKey);
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- break;
-
- }
-#endif /* NSS_ENABLE_ECC */
-
- /* See RFC 5869 and CK_NSS_HKDFParams for documentation. */
- case CKM_NSS_HKDF_SHA1: hashType = HASH_AlgSHA1; goto hkdf;
- case CKM_NSS_HKDF_SHA256: hashType = HASH_AlgSHA256; goto hkdf;
- case CKM_NSS_HKDF_SHA384: hashType = HASH_AlgSHA384; goto hkdf;
- case CKM_NSS_HKDF_SHA512: hashType = HASH_AlgSHA512; goto hkdf;
-hkdf: {
- const CK_NSS_HKDFParams * params =
- (const CK_NSS_HKDFParams *) pMechanism->pParameter;
- const SECHashObject * rawHash;
- unsigned hashLen;
- CK_BYTE buf[HASH_LENGTH_MAX];
- CK_BYTE * prk; /* psuedo-random key */
- CK_ULONG prkLen;
- CK_BYTE * okm; /* output keying material */
-
- rawHash = HASH_GetRawHashObject(hashType);
- if (rawHash == NULL || rawHash->length > sizeof buf) {
- crv = CKR_FUNCTION_FAILED;
- break;
- }
- hashLen = rawHash->length;
-
- if (pMechanism->ulParameterLen != sizeof(CK_NSS_HKDFParams) ||
- !params || (!params->bExpand && !params->bExtract) ||
- (params->bExtract && params->ulSaltLen > 0 && !params->pSalt) ||
- (params->bExpand && params->ulInfoLen > 0 && !params->pInfo)) {
- crv = CKR_MECHANISM_PARAM_INVALID;
- break;
- }
- if (keySize == 0 || keySize > sizeof key_block ||
- (!params->bExpand && keySize > hashLen) ||
- (params->bExpand && keySize > 255 * hashLen)) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- break;
- }
- crv = sftk_DeriveSensitiveCheck(sourceKey, key);
- if (crv != CKR_OK)
- break;
-
- /* HKDF-Extract(salt, base key value) */
- if (params->bExtract) {
- CK_BYTE * salt;
- CK_ULONG saltLen;
- HMACContext * hmac;
- unsigned int bufLen;
-
- salt = params->pSalt;
- saltLen = params->ulSaltLen;
- if (salt == NULL) {
- saltLen = hashLen;
- salt = buf;
- memset(salt, 0, saltLen);
- }
- hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
- if (!hmac) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- HMAC_Begin(hmac);
- HMAC_Update(hmac, (const unsigned char*) att->attrib.pValue,
- att->attrib.ulValueLen);
- HMAC_Finish(hmac, buf, &bufLen, sizeof(buf));
- HMAC_Destroy(hmac, PR_TRUE);
- PORT_Assert(bufLen == rawHash->length);
- prk = buf;
- prkLen = bufLen;
- } else {
- /* PRK = base key value */
- prk = (CK_BYTE*) att->attrib.pValue;
- prkLen = att->attrib.ulValueLen;
- }
-
- /* HKDF-Expand */
- if (!params->bExpand) {
- okm = prk;
- } else {
- /* T(1) = HMAC-Hash(prk, "" | info | 0x01)
- * T(n) = HMAC-Hash(prk, T(n-1) | info | n
- * key material = T(1) | ... | T(n)
- */
- HMACContext * hmac;
- CK_BYTE i;
- unsigned iterations = PR_ROUNDUP(keySize, hashLen) / hashLen;
- hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS);
- if (hmac == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- for (i = 1; i <= iterations; ++i) {
- unsigned len;
- HMAC_Begin(hmac);
- if (i > 1) {
- HMAC_Update(hmac, key_block + ((i-2) * hashLen), hashLen);
- }
- if (params->ulInfoLen != 0) {
- HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
- }
- HMAC_Update(hmac, &i, 1);
- HMAC_Finish(hmac, key_block + ((i-1) * hashLen), &len,
- hashLen);
- PORT_Assert(len == hashLen);
- }
- HMAC_Destroy(hmac, PR_TRUE);
- okm = key_block;
- }
- /* key material = prk */
- crv = sftk_forceAttribute(key, CKA_VALUE, okm, keySize);
- break;
- } /* end of CKM_NSS_HKDF_* */
-
- case CKM_NSS_JPAKE_ROUND2_SHA1: hashType = HASH_AlgSHA1; goto jpake2;
- case CKM_NSS_JPAKE_ROUND2_SHA256: hashType = HASH_AlgSHA256; goto jpake2;
- case CKM_NSS_JPAKE_ROUND2_SHA384: hashType = HASH_AlgSHA384; goto jpake2;
- case CKM_NSS_JPAKE_ROUND2_SHA512: hashType = HASH_AlgSHA512; goto jpake2;
-jpake2:
- if (pMechanism->pParameter == NULL ||
- pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound2Params))
- crv = CKR_MECHANISM_PARAM_INVALID;
- if (crv == CKR_OK && sftk_isTrue(key, CKA_TOKEN))
- crv = CKR_TEMPLATE_INCONSISTENT;
- if (crv == CKR_OK)
- crv = sftk_DeriveSensitiveCheck(sourceKey, key);
- if (crv == CKR_OK)
- crv = jpake_Round2(hashType,
- (CK_NSS_JPAKERound2Params *) pMechanism->pParameter,
- sourceKey, key);
- break;
-
- case CKM_NSS_JPAKE_FINAL_SHA1: hashType = HASH_AlgSHA1; goto jpakeFinal;
- case CKM_NSS_JPAKE_FINAL_SHA256: hashType = HASH_AlgSHA256; goto jpakeFinal;
- case CKM_NSS_JPAKE_FINAL_SHA384: hashType = HASH_AlgSHA384; goto jpakeFinal;
- case CKM_NSS_JPAKE_FINAL_SHA512: hashType = HASH_AlgSHA512; goto jpakeFinal;
-jpakeFinal:
- if (pMechanism->pParameter == NULL ||
- pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKEFinalParams))
- crv = CKR_MECHANISM_PARAM_INVALID;
- /* We purposely do not do the derive sensitivity check; we want to be
- able to derive non-sensitive keys while allowing the ROUND1 and
- ROUND2 keys to be sensitive (which they always are, since they are
- in the CKO_PRIVATE_KEY class). The caller must include CKA_SENSITIVE
- in the template in order for the resultant keyblock key to be
- sensitive.
- */
- if (crv == CKR_OK)
- crv = jpake_Final(hashType,
- (CK_NSS_JPAKEFinalParams *) pMechanism->pParameter,
- sourceKey, key);
- break;
-
- default:
- crv = CKR_MECHANISM_INVALID;
- }
- if (att) {
- sftk_FreeAttribute(att);
- }
- sftk_FreeObject(sourceKey);
- if (crv != CKR_OK) {
- if (key) sftk_FreeObject(key);
- return crv;
- }
-
- /* link the key object into the list */
- if (key) {
- SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key);
- PORT_Assert(sessKey);
- /* get the session */
- sessKey->wasDerived = PR_TRUE;
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) {
- sftk_FreeObject(key);
- return CKR_HOST_MEMORY;
- }
-
- crv = sftk_handleObject(key,session);
- sftk_FreeSession(session);
- *phKey = key->handle;
- sftk_FreeObject(key);
- }
- return crv;
-}
-
-
-/* NSC_GetFunctionStatus obtains an updated status of a function running
- * in parallel with an application. */
-CK_RV NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession)
-{
- CHECK_FORK();
-
- return CKR_FUNCTION_NOT_PARALLEL;
-}
-
-/* NSC_CancelFunction cancels a function running in parallel */
-CK_RV NSC_CancelFunction(CK_SESSION_HANDLE hSession)
-{
- CHECK_FORK();
-
- return CKR_FUNCTION_NOT_PARALLEL;
-}
-
-/* NSC_GetOperationState saves the state of the cryptographic
- *operation in a session.
- * NOTE: This code only works for digest functions for now. eventually need
- * to add full flatten/resurect to our state stuff so that all types of state
- * can be saved */
-CK_RV NSC_GetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen)
-{
- SFTKSessionContext *context;
- SFTKSession *session;
- CK_RV crv;
- CK_ULONG pOSLen = *pulOperationStateLen;
-
- CHECK_FORK();
-
- /* make sure we're legal */
- crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session);
- if (crv != CKR_OK) return crv;
-
- *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE)
- + sizeof(SFTKContextType);
- if (pOperationState == NULL) {
- sftk_FreeSession(session);
- return CKR_OK;
- } else {
- if (pOSLen < *pulOperationStateLen) {
- return CKR_BUFFER_TOO_SMALL;
- }
- }
- PORT_Memcpy(pOperationState,&context->type,sizeof(SFTKContextType));
- pOperationState += sizeof(SFTKContextType);
- PORT_Memcpy(pOperationState,&context->currentMech,
- sizeof(CK_MECHANISM_TYPE));
- pOperationState += sizeof(CK_MECHANISM_TYPE);
- PORT_Memcpy(pOperationState,context->cipherInfo,context->cipherInfoLen);
- sftk_FreeSession(session);
- return CKR_OK;
-}
-
-
-#define sftk_Decrement(stateSize,len) \
- stateSize = ((stateSize) > (CK_ULONG)(len)) ? \
- ((stateSize) - (CK_ULONG)(len)) : 0;
-
-/* NSC_SetOperationState restores the state of the cryptographic
- * operation in a session. This is coded like it can restore lots of
- * states, but it only works for truly flat cipher structures. */
-CK_RV NSC_SetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey)
-{
- SFTKSessionContext *context;
- SFTKSession *session;
- SFTKContextType type;
- CK_MECHANISM mech;
- CK_RV crv = CKR_OK;
-
- CHECK_FORK();
-
- while (ulOperationStateLen != 0) {
- /* get what type of state we're dealing with... */
- PORT_Memcpy(&type,pOperationState, sizeof(SFTKContextType));
-
- /* fix up session contexts based on type */
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
- context = sftk_ReturnContextByType(session, type);
- sftk_SetContextByType(session, type, NULL);
- if (context) {
- sftk_FreeContext(context);
- }
- pOperationState += sizeof(SFTKContextType);
- sftk_Decrement(ulOperationStateLen,sizeof(SFTKContextType));
-
-
- /* get the mechanism structure */
- PORT_Memcpy(&mech.mechanism,pOperationState,sizeof(CK_MECHANISM_TYPE));
- pOperationState += sizeof(CK_MECHANISM_TYPE);
- sftk_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE));
- /* should be filled in... but not necessary for hash */
- mech.pParameter = NULL;
- mech.ulParameterLen = 0;
- switch (type) {
- case SFTK_HASH:
- crv = NSC_DigestInit(hSession,&mech);
- if (crv != CKR_OK) break;
- crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE,
- NULL);
- if (crv != CKR_OK) break;
- PORT_Memcpy(context->cipherInfo,pOperationState,
- context->cipherInfoLen);
- pOperationState += context->cipherInfoLen;
- sftk_Decrement(ulOperationStateLen,context->cipherInfoLen);
- break;
- default:
- /* do sign/encrypt/decrypt later */
- crv = CKR_SAVED_STATE_INVALID;
- }
- sftk_FreeSession(session);
- if (crv != CKR_OK) break;
- }
- return crv;
-}
-
-/* Dual-function cryptographic operations */
-
-/* NSC_DigestEncryptUpdate continues a multiple-part digesting and encryption
- * operation. */
-CK_RV NSC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen)
-{
- CK_RV crv;
-
- CHECK_FORK();
-
- crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart,
- pulEncryptedPartLen);
- if (crv != CKR_OK) return crv;
- crv = NSC_DigestUpdate(hSession,pPart,ulPartLen);
-
- return crv;
-}
-
-
-/* NSC_DecryptDigestUpdate continues a multiple-part decryption and
- * digesting operation. */
-CK_RV NSC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
-{
- CK_RV crv;
-
- CHECK_FORK();
-
- crv = NSC_DecryptUpdate(hSession,pEncryptedPart, ulEncryptedPartLen,
- pPart, pulPartLen);
- if (crv != CKR_OK) return crv;
- crv = NSC_DigestUpdate(hSession,pPart,*pulPartLen);
-
- return crv;
-}
-
-
-/* NSC_SignEncryptUpdate continues a multiple-part signing and
- * encryption operation. */
-CK_RV NSC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen)
-{
- CK_RV crv;
-
- CHECK_FORK();
-
- crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart,
- pulEncryptedPartLen);
- if (crv != CKR_OK) return crv;
- crv = NSC_SignUpdate(hSession,pPart,ulPartLen);
-
- return crv;
-}
-
-
-/* NSC_DecryptVerifyUpdate continues a multiple-part decryption
- * and verify operation. */
-CK_RV NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
-{
- CK_RV crv;
-
- CHECK_FORK();
-
- crv = NSC_DecryptUpdate(hSession,pEncryptedData, ulEncryptedDataLen,
- pData, pulDataLen);
- if (crv != CKR_OK) return crv;
- crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen);
-
- return crv;
-}
-
-/* NSC_DigestKey continues a multi-part message-digesting operation,
- * by digesting the value of a secret key as part of the data already digested.
- */
-CK_RV NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
-{
- SFTKSession *session = NULL;
- SFTKObject *key = NULL;
- SFTKAttribute *att;
- CK_RV crv;
-
- CHECK_FORK();
-
- session = sftk_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
-
- key = sftk_ObjectFromHandle(hKey,session);
- sftk_FreeSession(session);
- if (key == NULL) return CKR_KEY_HANDLE_INVALID;
-
- /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */
-
- /* make sure it's a valid key for this operation */
- if (key->objclass != CKO_SECRET_KEY) {
- sftk_FreeObject(key);
- return CKR_KEY_TYPE_INCONSISTENT;
- }
- /* get the key value */
- att = sftk_FindAttribute(key,CKA_VALUE);
- sftk_FreeObject(key);
- if (!att) {
- return CKR_KEY_HANDLE_INVALID;
- }
- crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue,
- att->attrib.ulValueLen);
- sftk_FreeAttribute(att);
- return crv;
-}
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
deleted file mode 100644
index 904a0621a..000000000
--- a/security/nss/lib/softoken/pkcs11i.h
+++ /dev/null
@@ -1,744 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Internal data structures and functions used by pkcs11.c
- */
-#ifndef _PKCS11I_H_
-#define _PKCS11I_H_ 1
-
-#include "nssilock.h"
-#include "seccomon.h"
-#include "secoidt.h"
-#include "lowkeyti.h"
-#include "pkcs11t.h"
-
-#include "sftkdbt.h"
-#include "hasht.h"
-
-/*
- * Configuration Defines
- *
- * The following defines affect the space verse speed trade offs of
- * the PKCS #11 module. For the most part the current settings are optimized
- * for web servers, where we want faster speed and lower lock contention at
- * the expense of space.
- */
-
-/*
- * The attribute allocation strategy is static allocation:
- * Attributes are pre-allocated as part of the session object and used from
- * the object array.
- */
-#define MAX_OBJS_ATTRS 45 /* number of attributes to preallocate in
- * the object (must me the absolute max) */
-#define ATTR_SPACE 50 /* Maximum size of attribute data before extra
- * data needs to be allocated. This is set to
- * enough space to hold an SSL MASTER secret */
-
-#define NSC_STRICT PR_FALSE /* forces the code to do strict template
- * matching when doing C_FindObject on token
- * objects. This will slow down search in
- * NSS. */
-/* default search block allocations and increments */
-#define NSC_CERT_BLOCK_SIZE 50
-#define NSC_SEARCH_BLOCK_SIZE 5
-#define NSC_SLOT_LIST_BLOCK_SIZE 10
-
-#define NSC_FIPS_MODULE 1
-#define NSC_NON_FIPS_MODULE 0
-
-/* these are data base storage hashes, not cryptographic hashes.. The define
- * the effective size of the various object hash tables */
-/* clients care more about memory usage than lookup performance on
- * cyrptographic objects. Clients also have less objects around to play with
- *
- * we eventually should make this configurable at runtime! Especially now that
- * NSS is a shared library.
- */
-#define SPACE_ATTRIBUTE_HASH_SIZE 32
-#define SPACE_SESSION_OBJECT_HASH_SIZE 32
-#define SPACE_SESSION_HASH_SIZE 32
-#define TIME_ATTRIBUTE_HASH_SIZE 32
-#define TIME_SESSION_OBJECT_HASH_SIZE 1024
-#define TIME_SESSION_HASH_SIZE 1024
-#define MAX_OBJECT_LIST_SIZE 800
- /* how many objects to keep on the free list
- * before we start freeing them */
-#define MAX_KEY_LEN 256 /* maximum symmetric key length in bytes */
-
-/*
- * LOG2_BUCKETS_PER_SESSION_LOCK must be a prime number.
- * With SESSION_HASH_SIZE=1024, LOG2 can be 9, 5, 1, or 0.
- * With SESSION_HASH_SIZE=4096, LOG2 can be 11, 9, 5, 1, or 0.
- *
- * HASH_SIZE LOG2_BUCKETS_PER BUCKETS_PER_LOCK NUMBER_OF_BUCKETS
- * 1024 9 512 2
- * 1024 5 32 32
- * 1024 1 2 512
- * 1024 0 1 1024
- * 4096 11 2048 2
- * 4096 9 512 8
- * 4096 5 32 128
- * 4096 1 2 2048
- * 4096 0 1 4096
- */
-#define LOG2_BUCKETS_PER_SESSION_LOCK 1
-#define BUCKETS_PER_SESSION_LOCK (1 << (LOG2_BUCKETS_PER_SESSION_LOCK))
-/* NOSPREAD sessionID to hash table index macro has been slower. */
-
-/* define typedefs, double as forward declarations as well */
-typedef struct SFTKAttributeStr SFTKAttribute;
-typedef struct SFTKObjectListStr SFTKObjectList;
-typedef struct SFTKObjectFreeListStr SFTKObjectFreeList;
-typedef struct SFTKObjectListElementStr SFTKObjectListElement;
-typedef struct SFTKObjectStr SFTKObject;
-typedef struct SFTKSessionObjectStr SFTKSessionObject;
-typedef struct SFTKTokenObjectStr SFTKTokenObject;
-typedef struct SFTKSessionStr SFTKSession;
-typedef struct SFTKSlotStr SFTKSlot;
-typedef struct SFTKSessionContextStr SFTKSessionContext;
-typedef struct SFTKSearchResultsStr SFTKSearchResults;
-typedef struct SFTKHashVerifyInfoStr SFTKHashVerifyInfo;
-typedef struct SFTKHashSignInfoStr SFTKHashSignInfo;
-typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
-typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
-typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
-typedef struct SFTKItemTemplateStr SFTKItemTemplate;
-
-/* define function pointer typdefs for pointer tables */
-typedef void (*SFTKDestroy)(void *, PRBool);
-typedef void (*SFTKBegin)(void *);
-typedef SECStatus (*SFTKCipher)(void *,void *,unsigned int *,unsigned int,
- void *, unsigned int);
-typedef SECStatus (*SFTKVerify)(void *,void *,unsigned int,void *,unsigned int);
-typedef void (*SFTKHash)(void *,void *,unsigned int);
-typedef void (*SFTKEnd)(void *,void *,unsigned int *,unsigned int);
-typedef void (*SFTKFree)(void *);
-
-/* Value to tell if an attribute is modifiable or not.
- * NEVER: attribute is only set on creation.
- * ONCOPY: attribute is set on creation and can only be changed on copy.
- * SENSITIVE: attribute can only be changed to TRUE.
- * ALWAYS: attribute can always be changed.
- */
-typedef enum {
- SFTK_NEVER = 0,
- SFTK_ONCOPY = 1,
- SFTK_SENSITIVE = 2,
- SFTK_ALWAYS = 3
-} SFTKModifyType;
-
-/*
- * Free Status Enum... tell us more information when we think we're
- * deleting an object.
- */
-typedef enum {
- SFTK_DestroyFailure,
- SFTK_Destroyed,
- SFTK_Busy
-} SFTKFreeStatus;
-
-/*
- * attribute values of an object.
- */
-struct SFTKAttributeStr {
- SFTKAttribute *next;
- SFTKAttribute *prev;
- PRBool freeAttr;
- PRBool freeData;
- /*must be called handle to make sftkqueue_find work */
- CK_ATTRIBUTE_TYPE handle;
- CK_ATTRIBUTE attrib;
- unsigned char space[ATTR_SPACE];
-};
-
-
-/*
- * doubly link list of objects
- */
-struct SFTKObjectListStr {
- SFTKObjectList *next;
- SFTKObjectList *prev;
- SFTKObject *parent;
-};
-
-struct SFTKObjectFreeListStr {
- SFTKObject *head;
- PZLock *lock;
- int count;
-};
-
-/*
- * PKCS 11 crypto object structure
- */
-struct SFTKObjectStr {
- SFTKObject *next;
- SFTKObject *prev;
- CK_OBJECT_CLASS objclass;
- CK_OBJECT_HANDLE handle;
- int refCount;
- PZLock *refLock;
- SFTKSlot *slot;
- void *objectInfo;
- SFTKFree infoFree;
-};
-
-struct SFTKTokenObjectStr {
- SFTKObject obj;
- SECItem dbKey;
-};
-
-struct SFTKSessionObjectStr {
- SFTKObject obj;
- SFTKObjectList sessionList;
- PZLock *attributeLock;
- SFTKSession *session;
- PRBool wasDerived;
- int nextAttr;
- SFTKAttribute attrList[MAX_OBJS_ATTRS];
- PRBool optimizeSpace;
- unsigned int hashSize;
- SFTKAttribute *head[1];
-};
-
-/*
- * struct to deal with a temparary list of objects
- */
-struct SFTKObjectListElementStr {
- SFTKObjectListElement *next;
- SFTKObject *object;
-};
-
-/*
- * Area to hold Search results
- */
-struct SFTKSearchResultsStr {
- CK_OBJECT_HANDLE *handles;
- int size;
- int index;
- int array_size;
-};
-
-
-/*
- * the universal crypto/hash/sign/verify context structure
- */
-typedef enum {
- SFTK_ENCRYPT,
- SFTK_DECRYPT,
- SFTK_HASH,
- SFTK_SIGN,
- SFTK_SIGN_RECOVER,
- SFTK_VERIFY,
- SFTK_VERIFY_RECOVER
-} SFTKContextType;
-
-/** max block size of supported block ciphers */
-#define SFTK_MAX_BLOCK_SIZE 16
-/** currently SHA512 is the biggest hash length */
-#define SFTK_MAX_MAC_LENGTH 64
-#define SFTK_INVALID_MAC_SIZE 0xffffffff
-
-/** Particular ongoing operation in session (sign/verify/digest/encrypt/...)
- *
- * Understanding sign/verify context:
- * multi=1 hashInfo=0 block (symmetric) cipher MACing
- * multi=1 hashInfo=X PKC S/V with prior hashing
- * multi=0 hashInfo=0 PKC S/V one shot (w/o hashing)
- * multi=0 hashInfo=X *** shouldn't happen ***
- */
-struct SFTKSessionContextStr {
- SFTKContextType type;
- PRBool multi; /* is multipart */
- PRBool rsa; /* is rsa */
- PRBool doPad; /* use PKCS padding for block ciphers */
- unsigned int blockSize; /* blocksize for padding */
- unsigned int padDataLength; /* length of the valid data in padbuf */
- /** latest incomplete block of data for block cipher */
- unsigned char padBuf[SFTK_MAX_BLOCK_SIZE];
- /** result of MAC'ing of latest full block of data with block cipher */
- unsigned char macBuf[SFTK_MAX_BLOCK_SIZE];
- CK_ULONG macSize; /* size of a general block cipher mac*/
- void *cipherInfo;
- void *hashInfo;
- unsigned int cipherInfoLen;
- CK_MECHANISM_TYPE currentMech;
- SFTKCipher update;
- SFTKHash hashUpdate;
- SFTKEnd end;
- SFTKDestroy destroy;
- SFTKDestroy hashdestroy;
- SFTKVerify verify;
- unsigned int maxLen;
- SFTKObject *key;
-};
-
-/*
- * Sessions (have objects)
- */
-struct SFTKSessionStr {
- SFTKSession *next;
- SFTKSession *prev;
- CK_SESSION_HANDLE handle;
- int refCount;
- PZLock *objectLock;
- int objectIDCount;
- CK_SESSION_INFO info;
- CK_NOTIFY notify;
- CK_VOID_PTR appData;
- SFTKSlot *slot;
- SFTKSearchResults *search;
- SFTKSessionContext *enc_context;
- SFTKSessionContext *hash_context;
- SFTKSessionContext *sign_context;
- SFTKObjectList *objects[1];
-};
-
-/*
- * slots (have sessions and objects)
- *
- * The array of sessionLock's protect the session hash table (head[])
- * as well as the reference count of session objects in that bucket
- * (head[]->refCount), objectLock protects all elements of the slot's
- * object hash tables (sessObjHashTable[] and tokObjHashTable), and
- * sessionObjectHandleCount.
- * slotLock protects the remaining protected elements:
- * password, isLoggedIn, ssoLoggedIn, and sessionCount,
- * and pwCheckLock serializes the key database password checks in
- * NSC_SetPIN and NSC_Login.
- *
- * Each of the fields below has the following lifetime as commented
- * next to the fields:
- * invariant - This value is set when the slot is first created and
- * never changed until it is destroyed.
- * per load - This value is set when the slot is first created, or
- * when the slot is used to open another directory. Between open and close
- * this field does not change.
- * variable - This value changes through the normal process of slot operation.
- * - reset. The value of this variable is cleared during an open/close
- * cycles.
- * - preserved. The value of this variable is preserved over open/close
- * cycles.
- */
-struct SFTKSlotStr {
- CK_SLOT_ID slotID; /* invariant */
- PZLock *slotLock; /* invariant */
- PZLock **sessionLock; /* invariant */
- unsigned int numSessionLocks; /* invariant */
- unsigned long sessionLockMask; /* invariant */
- PZLock *objectLock; /* invariant */
- PRLock *pwCheckLock; /* invariant */
- PRBool present; /* variable -set */
- PRBool hasTokens; /* per load */
- PRBool isLoggedIn; /* variable - reset */
- PRBool ssoLoggedIn; /* variable - reset */
- PRBool needLogin; /* per load */
- PRBool DB_loaded; /* per load */
- PRBool readOnly; /* per load */
- PRBool optimizeSpace; /* invariant */
- SFTKDBHandle *certDB; /* per load */
- SFTKDBHandle *keyDB; /* per load */
- int minimumPinLen; /* per load */
- PRInt32 sessionIDCount; /* atomically incremented */
- /* (preserved) */
- int sessionIDConflict; /* not protected by a lock */
- /* (preserved) */
- int sessionCount; /* variable - reset */
- PRInt32 rwSessionCount; /* set by atomic operations */
- /* (reset) */
- int sessionObjectHandleCount;/* variable - perserved */
- int index; /* invariant */
- PLHashTable *tokObjHashTable; /* invariant */
- SFTKObject **sessObjHashTable; /* variable - reset */
- unsigned int sessObjHashSize; /* invariant */
- SFTKSession **head; /* variable -reset */
- unsigned int sessHashSize; /* invariant */
- char tokDescription[33]; /* per load */
- char updateTokDescription[33]; /* per load */
- char slotDescription[65]; /* invariant */
-};
-
-/*
- * special joint operations Contexts
- */
-struct SFTKHashVerifyInfoStr {
- SECOidTag hashOid;
- void *params;
- NSSLOWKEYPublicKey *key;
-};
-
-struct SFTKHashSignInfoStr {
- SECOidTag hashOid;
- void *params;
- NSSLOWKEYPrivateKey *key;
-};
-
-/**
- * Contexts for RSA-OAEP
- */
-struct SFTKOAEPEncryptInfoStr {
- CK_RSA_PKCS_OAEP_PARAMS *params;
- NSSLOWKEYPublicKey *key;
-};
-
-struct SFTKOAEPDecryptInfoStr {
- CK_RSA_PKCS_OAEP_PARAMS *params;
- NSSLOWKEYPrivateKey *key;
-};
-
-/* context for the Final SSLMAC message */
-struct SFTKSSLMACInfoStr {
- void *hashContext;
- SFTKBegin begin;
- SFTKHash update;
- SFTKEnd end;
- CK_ULONG macSize;
- int padSize;
- unsigned char key[MAX_KEY_LEN];
- unsigned int keySize;
-};
-
-/*
- * Template based on SECItems, suitable for passing as arrays
- */
-struct SFTKItemTemplateStr {
- CK_ATTRIBUTE_TYPE type;
- SECItem *item;
-};
-
-/* macro for setting SFTKTemplates. */
-#define SFTK_SET_ITEM_TEMPLATE(templ, count, itemPtr, attr) \
- templ[count].type = attr; \
- templ[count].item = itemPtr
-
-#define SFTK_MAX_ITEM_TEMPLATE 10
-
-/*
- * session handle modifiers
- */
-#define SFTK_SESSION_SLOT_MASK 0xff000000L
-
-/*
- * object handle modifiers
- */
-#define SFTK_TOKEN_MASK 0x80000000L
-#define SFTK_TOKEN_MAGIC 0x80000000L
-#define SFTK_TOKEN_TYPE_MASK 0x70000000L
-/* keydb (high bit == 0) */
-#define SFTK_TOKEN_TYPE_PRIV 0x10000000L
-#define SFTK_TOKEN_TYPE_PUB 0x20000000L
-#define SFTK_TOKEN_TYPE_KEY 0x30000000L
-/* certdb (high bit == 1) */
-#define SFTK_TOKEN_TYPE_TRUST 0x40000000L
-#define SFTK_TOKEN_TYPE_CRL 0x50000000L
-#define SFTK_TOKEN_TYPE_SMIME 0x60000000L
-#define SFTK_TOKEN_TYPE_CERT 0x70000000L
-
-#define SFTK_TOKEN_KRL_HANDLE (SFTK_TOKEN_MAGIC|SFTK_TOKEN_TYPE_CRL|1)
-/* how big (in bytes) a password/pin we can deal with */
-#define SFTK_MAX_PIN 255
-/* minimum password/pin length (in Unicode characters) in FIPS mode */
-#define FIPS_MIN_PIN 7
-
-/* slot ID's */
-#define NETSCAPE_SLOT_ID 1
-#define PRIVATE_KEY_SLOT_ID 2
-#define FIPS_SLOT_ID 3
-
-/* slot helper macros */
-#define sftk_SlotFromSession(sp) ((sp)->slot)
-#define sftk_isToken(id) (((id) & SFTK_TOKEN_MASK) == SFTK_TOKEN_MAGIC)
-
-/* the session hash multiplier (see bug 201081) */
-#define SHMULTIPLIER 1791398085
-
-/* queueing helper macros */
-#define sftk_hash(value,size) \
- ((PRUint32)((value) * SHMULTIPLIER) & (size-1))
-#define sftkqueue_add(element,id,head,hash_size) \
- { int tmp = sftk_hash(id,hash_size); \
- (element)->next = (head)[tmp]; \
- (element)->prev = NULL; \
- if ((head)[tmp]) (head)[tmp]->prev = (element); \
- (head)[tmp] = (element); }
-#define sftkqueue_find(element,id,head,hash_size) \
- for( (element) = (head)[sftk_hash(id,hash_size)]; (element) != NULL; \
- (element) = (element)->next) { \
- if ((element)->handle == (id)) { break; } }
-#define sftkqueue_is_queued(element,id,head,hash_size) \
- ( ((element)->next) || ((element)->prev) || \
- ((head)[sftk_hash(id,hash_size)] == (element)) )
-#define sftkqueue_delete(element,id,head,hash_size) \
- if ((element)->next) (element)->next->prev = (element)->prev; \
- if ((element)->prev) (element)->prev->next = (element)->next; \
- else (head)[sftk_hash(id,hash_size)] = ((element)->next); \
- (element)->next = NULL; \
- (element)->prev = NULL; \
-
-#define sftkqueue_init_element(element) \
- (element)->prev = NULL;
-
-#define sftkqueue_add2(element, id, index, head) \
- { \
- (element)->next = (head)[index]; \
- if ((head)[index]) \
- (head)[index]->prev = (element); \
- (head)[index] = (element); \
- }
-
-#define sftkqueue_find2(element, id, index, head) \
- for ( (element) = (head)[index]; \
- (element) != NULL; \
- (element) = (element)->next) { \
- if ((element)->handle == (id)) { break; } \
- }
-
-#define sftkqueue_delete2(element, id, index, head) \
- if ((element)->next) (element)->next->prev = (element)->prev; \
- if ((element)->prev) (element)->prev->next = (element)->next; \
- else (head)[index] = ((element)->next);
-
-#define sftkqueue_clear_deleted_element(element) \
- (element)->next = NULL; \
- (element)->prev = NULL; \
-
-
-/* sessionID (handle) is used to determine session lock bucket */
-#ifdef NOSPREAD
-/* NOSPREAD: (ID>>L2LPB) & (perbucket-1) */
-#define SFTK_SESSION_LOCK(slot,handle) \
- ((slot)->sessionLock[((handle) >> LOG2_BUCKETS_PER_SESSION_LOCK) \
- & (slot)->sessionLockMask])
-#else
-/* SPREAD: ID & (perbucket-1) */
-#define SFTK_SESSION_LOCK(slot,handle) \
- ((slot)->sessionLock[(handle) & (slot)->sessionLockMask])
-#endif
-
-/* expand an attribute & secitem structures out */
-#define sftk_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen
-#define sftk_item_expand(ip) (ip)->data,(ip)->len
-
-typedef struct sftk_token_parametersStr {
- CK_SLOT_ID slotID;
- char *configdir;
- char *certPrefix;
- char *keyPrefix;
- char *updatedir;
- char *updCertPrefix;
- char *updKeyPrefix;
- char *updateID;
- char *tokdes;
- char *slotdes;
- char *updtokdes;
- int minPW;
- PRBool readOnly;
- PRBool noCertDB;
- PRBool noKeyDB;
- PRBool forceOpen;
- PRBool pwRequired;
- PRBool optimizeSpace;
-} sftk_token_parameters;
-
-typedef struct sftk_parametersStr {
- char *configdir;
- char *updatedir;
- char *updateID;
- char *secmodName;
- char *man;
- char *libdes;
- PRBool readOnly;
- PRBool noModDB;
- PRBool noCertDB;
- PRBool forceOpen;
- PRBool pwRequired;
- PRBool optimizeSpace;
- sftk_token_parameters *tokens;
- int token_count;
-} sftk_parameters;
-
-
-/* path stuff (was machine dependent) used by dbinit.c and pk11db.c */
-#define CERT_DB_FMT "%scert%s.db"
-#define KEY_DB_FMT "%skey%s.db"
-
-SEC_BEGIN_PROTOS
-
-/* shared functions between pkcs11.c and fipstokn.c */
-extern PRBool nsf_init;
-extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
-extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS);
-extern PRBool sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV* crv);
-extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent,
- CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex);
-
-/* slot initialization, reinit, shutdown and destruction */
-extern CK_RV SFTK_SlotInit(char *configdir, char *updatedir, char *updateID,
- sftk_token_parameters *params, int moduleIndex);
-extern CK_RV SFTK_SlotReInit(SFTKSlot *slot, char *configdir,
- char *updatedir, char *updateID,
- sftk_token_parameters *params, int moduleIndex);
-extern CK_RV SFTK_DestroySlotData(SFTKSlot *slot);
-extern CK_RV SFTK_ShutdownSlot(SFTKSlot *slot);
-extern CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout);
-
-
-/* internal utility functions used by pkcs11.c */
-extern SFTKAttribute *sftk_FindAttribute(SFTKObject *object,
- CK_ATTRIBUTE_TYPE type);
-extern void sftk_FreeAttribute(SFTKAttribute *attribute);
-extern CK_RV sftk_AddAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- const void *valPtr, CK_ULONG length);
-extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
- SFTKObject *object, CK_ATTRIBUTE_TYPE type);
-extern CK_RV sftk_MultipleAttribute2SecItem(PLArenaPool *arena,
- SFTKObject *object, SFTKItemTemplate *templ, int count);
-extern unsigned int sftk_GetLengthInBits(unsigned char *buf,
- unsigned int bufLen);
-extern CK_RV sftk_ConstrainAttribute(SFTKObject *object,
- CK_ATTRIBUTE_TYPE type, int minLength, int maxLength, int minMultiple);
-extern PRBool sftk_hasAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
-extern PRBool sftk_isTrue(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
-extern void sftk_DeleteAttributeType(SFTKObject *object,
- CK_ATTRIBUTE_TYPE type);
-extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item,
- SFTKObject *object, CK_ATTRIBUTE_TYPE type);
-extern CK_RV sftk_Attribute2SSecItem(PLArenaPool *arena, SECItem *item,
- SFTKObject *object,
- CK_ATTRIBUTE_TYPE type);
-extern SFTKModifyType sftk_modifyType(CK_ATTRIBUTE_TYPE type,
- CK_OBJECT_CLASS inClass);
-extern PRBool sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass);
-extern char *sftk_getString(SFTKObject *object, CK_ATTRIBUTE_TYPE type);
-extern void sftk_nullAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type);
-extern CK_RV sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- CK_ULONG *longData);
-extern CK_RV sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len);
-extern CK_RV sftk_defaultAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len);
-extern unsigned int sftk_MapTrust(CK_TRUST trust, PRBool clientAuth);
-
-extern SFTKObject *sftk_NewObject(SFTKSlot *slot);
-extern CK_RV sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject);
-extern SFTKFreeStatus sftk_FreeObject(SFTKObject *object);
-extern CK_RV sftk_DeleteObject(SFTKSession *session, SFTKObject *object);
-extern void sftk_ReferenceObject(SFTKObject *object);
-extern SFTKObject *sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle,
- SFTKSession *session);
-extern void sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object);
-extern void sftk_AddObject(SFTKSession *session, SFTKObject *object);
-/* clear out all the existing object ID to database key mappings.
- * used to reinit a token */
-extern CK_RV SFTK_ClearTokenKeyHashTable(SFTKSlot *slot);
-
-extern CK_RV sftk_searchObjectList(SFTKSearchResults *search,
- SFTKObject **head, unsigned int size,
- PZLock *lock, CK_ATTRIBUTE_PTR inTemplate,
- int count, PRBool isLoggedIn);
-extern SFTKObjectListElement *sftk_FreeObjectListElement(
- SFTKObjectListElement *objectList);
-extern void sftk_FreeObjectList(SFTKObjectListElement *objectList);
-extern void sftk_FreeSearch(SFTKSearchResults *search);
-extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session);
-
-extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all);
-extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle);
-extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle);
-extern void sftk_FreeSession(SFTKSession *session);
-extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify,
- CK_VOID_PTR pApplication, CK_FLAGS flags);
-extern void sftk_update_state(SFTKSlot *slot,SFTKSession *session);
-extern void sftk_update_all_states(SFTKSlot *slot);
-extern void sftk_FreeContext(SFTKSessionContext *context);
-extern void sftk_InitFreeLists(void);
-extern void sftk_CleanupFreeLists(void);
-
-extern NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,
- CK_KEY_TYPE key_type, CK_RV *crvp);
-extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object,
- CK_KEY_TYPE key_type, CK_RV *crvp);
-extern void sftk_FormatDESKey(unsigned char *key, int length);
-extern PRBool sftk_CheckDESKey(unsigned char *key);
-extern PRBool sftk_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type);
-
-/* mechanism allows this operation */
-extern CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op);
-
-/* helper function which calls nsslowkey_FindKeyByPublicKey after safely
- * acquiring a reference to the keydb from the slot */
-NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey);
-
-/*
- * parameter parsing functions
- */
-CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS);
-void sftk_freeParams(sftk_parameters *params);
-
-
-/*
- * narrow objects
- */
-SFTKSessionObject * sftk_narrowToSessionObject(SFTKObject *);
-SFTKTokenObject * sftk_narrowToTokenObject(SFTKObject *);
-
-/*
- * token object utilities
- */
-void sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle);
-PRBool sftk_poisonHandle(SFTKSlot *slot, SECItem *dbkey,
- CK_OBJECT_HANDLE handle);
-SFTKObject * sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey,
- CK_OBJECT_HANDLE handle);
-SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so);
-
-
-/* J-PAKE (jpakesftk.c) */
-extern
-CK_RV jpake_Round1(HASH_HashType hashType,
- CK_NSS_JPAKERound1Params * params,
- SFTKObject * key);
-extern
-CK_RV jpake_Round2(HASH_HashType hashType,
- CK_NSS_JPAKERound2Params * params,
- SFTKObject * sourceKey, SFTKObject * key);
-extern
-CK_RV jpake_Final(HASH_HashType hashType,
- const CK_NSS_JPAKEFinalParams * params,
- SFTKObject * sourceKey, SFTKObject * key);
-
-/* Constant time MAC functions (hmacct.c) */
-
-struct sftk_MACConstantTimeCtxStr {
- const SECHashObject *hash;
- unsigned char mac[64];
- unsigned char secret[64];
- unsigned int headerLength;
- unsigned int secretLength;
- unsigned int totalLength;
- unsigned char header[75];
-};
-typedef struct sftk_MACConstantTimeCtxStr sftk_MACConstantTimeCtx;
-sftk_MACConstantTimeCtx* sftk_HMACConstantTime_New(
- CK_MECHANISM_PTR mech, SFTKObject *key);
-sftk_MACConstantTimeCtx* sftk_SSLv3MACConstantTime_New(
- CK_MECHANISM_PTR mech, SFTKObject *key);
-void sftk_HMACConstantTime_Update(void *pctx, void *data, unsigned int len);
-void sftk_SSLv3MACConstantTime_Update(void *pctx, void *data, unsigned int len);
-void sftk_MACConstantTime_EndHash(
- void *pctx, void *out, unsigned int *outLength, unsigned int maxLength);
-void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool);
-
-/****************************************
- * implement TLS Pseudo Random Function (PRF)
- */
-
-extern CK_RV
-sftk_TLSPRFInit(SFTKSessionContext *context,
- SFTKObject * key,
- CK_KEY_TYPE key_type);
-
-SEC_END_PROTOS
-
-#endif /* _PKCS11I_H_ */
diff --git a/security/nss/lib/softoken/pkcs11ni.h b/security/nss/lib/softoken/pkcs11ni.h
deleted file mode 100644
index 3375102b6..000000000
--- a/security/nss/lib/softoken/pkcs11ni.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _PKCS11NI_H_
-#define _PKCS11NI_H_
-
-/*
- * pkcs11ni.h
- *
- * This file contains softoken private exports for NSS
- */
-
-/* softoken slot ID's */
-#define SFTK_MIN_USER_SLOT_ID 4
-#define SFTK_MAX_USER_SLOT_ID 100
-#define SFTK_MIN_FIPS_USER_SLOT_ID 101
-#define SFTK_MAX_FIPS_USER_SLOT_ID 127
-
-
-#endif /* _PKCS11NI_H_ */
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
deleted file mode 100644
index 770fb0e66..000000000
--- a/security/nss/lib/softoken/pkcs11u.c
+++ /dev/null
@@ -1,1979 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Internal PKCS #11 functions. Should only be called by pkcs11.c
- */
-#include "pkcs11.h"
-#include "pkcs11i.h"
-#include "lowkeyi.h"
-#include "secasn1.h"
-#include "blapi.h"
-#include "secerr.h"
-#include "prnetdb.h" /* for PR_ntohl */
-#include "sftkdb.h"
-#include "softoken.h"
-
-/*
- * ******************** Attribute Utilities *******************************
- */
-
-/*
- * create a new attribute with type, value, and length. Space is allocated
- * to hold value.
- */
-static SFTKAttribute *
-sftk_NewAttribute(SFTKObject *object,
- CK_ATTRIBUTE_TYPE type, const void *value, CK_ULONG len)
-{
- SFTKAttribute *attribute;
-
- SFTKSessionObject *so = sftk_narrowToSessionObject(object);
- int index;
-
- if (so == NULL) {
- /* allocate new attribute in a buffer */
- PORT_Assert(0);
- return NULL;
- }
- /*
- * We attempt to keep down contention on Malloc and Arena locks by
- * limiting the number of these calls on high traversed paths. This
- * is done for attributes by 'allocating' them from a pool already
- * allocated by the parent object.
- */
- PZ_Lock(so->attributeLock);
- index = so->nextAttr++;
- PZ_Unlock(so->attributeLock);
- PORT_Assert(index < MAX_OBJS_ATTRS);
- if (index >= MAX_OBJS_ATTRS) return NULL;
-
- attribute = &so->attrList[index];
- attribute->attrib.type = type;
- attribute->freeAttr = PR_FALSE;
- attribute->freeData = PR_FALSE;
- if (value) {
- if (len <= ATTR_SPACE) {
- attribute->attrib.pValue = attribute->space;
- } else {
- attribute->attrib.pValue = PORT_Alloc(len);
- attribute->freeData = PR_TRUE;
- }
- if (attribute->attrib.pValue == NULL) {
- return NULL;
- }
- PORT_Memcpy(attribute->attrib.pValue,value,len);
- attribute->attrib.ulValueLen = len;
- } else {
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
- attribute->attrib.type = type;
- attribute->handle = type;
- attribute->next = attribute->prev = NULL;
- return attribute;
-}
-
-/*
- * Free up all the memory associated with an attribute. Reference count
- * must be zero to call this.
- */
-static void
-sftk_DestroyAttribute(SFTKAttribute *attribute)
-{
- if (attribute->freeData) {
- if (attribute->attrib.pValue) {
- /* clear out the data in the attribute value... it may have been
- * sensitive data */
- PORT_Memset(attribute->attrib.pValue, 0,
- attribute->attrib.ulValueLen);
- }
- PORT_Free(attribute->attrib.pValue);
- }
- PORT_Free(attribute);
-}
-
-/*
- * release a reference to an attribute structure
- */
-void
-sftk_FreeAttribute(SFTKAttribute *attribute)
-{
- if (attribute->freeAttr) {
- sftk_DestroyAttribute(attribute);
- return;
- }
-}
-
-static SFTKAttribute *
-sftk_FindTokenAttribute(SFTKTokenObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *myattribute = NULL;
- SFTKDBHandle *dbHandle = NULL;
- CK_RV crv = CKR_HOST_MEMORY;
-
- myattribute = (SFTKAttribute*)PORT_Alloc(sizeof(SFTKAttribute));
- if (myattribute == NULL) {
- goto loser;
- }
-
- dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle);
-
- myattribute->handle = type;
- myattribute->attrib.type = type;
- myattribute->attrib.pValue = myattribute->space;
- myattribute->attrib.ulValueLen = ATTR_SPACE;
- myattribute->next = myattribute->prev = NULL;
- myattribute->freeAttr = PR_TRUE;
- myattribute->freeData = PR_FALSE;
-
- crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
- &myattribute->attrib, 1);
-
- /* attribute is bigger than our attribute space buffer, malloc it */
- if (crv == CKR_BUFFER_TOO_SMALL) {
- myattribute->attrib.pValue = NULL;
- crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
- &myattribute->attrib, 1);
- if (crv != CKR_OK) {
- goto loser;
- }
- myattribute->attrib.pValue = PORT_Alloc(myattribute->attrib.ulValueLen);
- if (myattribute->attrib.pValue == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- myattribute->freeData = PR_TRUE;
- crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
- &myattribute->attrib, 1);
- }
-loser:
- if (dbHandle) {
- sftk_freeDB(dbHandle);
- }
- if (crv != CKR_OK) {
- if (myattribute) {
- myattribute->attrib.ulValueLen = 0;
- sftk_FreeAttribute(myattribute);
- myattribute = NULL;
- }
- }
- return myattribute;
-}
-
-/*
- * look up and attribute structure from a type and Object structure.
- * The returned attribute is referenced and needs to be freed when
- * it is no longer needed.
- */
-SFTKAttribute *
-sftk_FindAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
-
- if (sessObject == NULL) {
- return sftk_FindTokenAttribute(sftk_narrowToTokenObject(object),type);
- }
-
- PZ_Lock(sessObject->attributeLock);
- sftkqueue_find(attribute,type,sessObject->head, sessObject->hashSize);
- PZ_Unlock(sessObject->attributeLock);
-
- return(attribute);
-}
-
-/*
- * Take a buffer and it's length and return it's true size in bits;
- */
-unsigned int
-sftk_GetLengthInBits(unsigned char *buf, unsigned int bufLen)
-{
- unsigned int size = bufLen * 8;
- unsigned int i;
-
- /* Get the real length in bytes */
- for (i=0; i < bufLen; i++) {
- unsigned char c = *buf++;
- if (c != 0) {
- unsigned char m;
- for (m=0x80; m > 0 ; m = m >> 1) {
- if ((c & m) != 0) {
- break;
- }
- size--;
- }
- break;
- }
- size-=8;
- }
- return size;
-}
-
-/*
- * Constrain a big num attribute. to size and padding
- * minLength means length of the object must be greater than equal to minLength
- * maxLength means length of the object must be less than equal to maxLength
- * minMultiple means that object length mod minMultiple must equal 0.
- * all input sizes are in bits.
- * if any constraint is '0' that constraint is not checked.
- */
-CK_RV
-sftk_ConstrainAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- int minLength, int maxLength, int minMultiple)
-{
- SFTKAttribute *attribute;
- int size;
- unsigned char *ptr;
-
- attribute = sftk_FindAttribute(object, type);
- if (!attribute) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- ptr = (unsigned char *) attribute->attrib.pValue;
- if (ptr == NULL) {
- sftk_FreeAttribute(attribute);
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- size = sftk_GetLengthInBits(ptr, attribute->attrib.ulValueLen);
- sftk_FreeAttribute(attribute);
-
- if ((minLength != 0) && (size < minLength)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- if ((maxLength != 0) && (size > maxLength)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- if ((minMultiple != 0) && ((size % minMultiple) != 0)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- return CKR_OK;
-}
-
-PRBool
-sftk_hasAttributeToken(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
-{
- CK_ATTRIBUTE template;
- CK_RV crv;
- SFTKDBHandle *dbHandle;
-
- dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle);
- template.type = type;
- template.pValue = NULL;
- template.ulValueLen = 0;
-
- crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle, &template, 1);
- sftk_freeDB(dbHandle);
-
- /* attribute is bigger than our attribute space buffer, malloc it */
- return (crv == CKR_OK) ? PR_TRUE : PR_FALSE;
-}
-
-/*
- * return true if object has attribute
- */
-PRBool
-sftk_hasAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
-
- if (sessObject == NULL) {
- return sftk_hasAttributeToken(sftk_narrowToTokenObject(object), type);
- }
-
- PZ_Lock(sessObject->attributeLock);
- sftkqueue_find(attribute,type,sessObject->head, sessObject->hashSize);
- PZ_Unlock(sessObject->attributeLock);
-
- return (PRBool)(attribute != NULL);
-}
-
-/*
- * add an attribute to an object
- */
-static void
-sftk_AddAttribute(SFTKObject *object,SFTKAttribute *attribute)
-{
- SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
-
- if (sessObject == NULL) return;
- PZ_Lock(sessObject->attributeLock);
- sftkqueue_add(attribute,attribute->handle,
- sessObject->head, sessObject->hashSize);
- PZ_Unlock(sessObject->attributeLock);
-}
-
-/*
- * copy an unsigned attribute into a SECItem. Secitem is allocated in
- * the specified arena.
- */
-CK_RV
-sftk_Attribute2SSecItem(PLArenaPool *arena,SECItem *item,SFTKObject *object,
- CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
-
- item->data = NULL;
-
- attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
-
- (void)SECITEM_AllocItem(arena, item, attribute->attrib.ulValueLen);
- if (item->data == NULL) {
- sftk_FreeAttribute(attribute);
- return CKR_HOST_MEMORY;
- }
- PORT_Memcpy(item->data, attribute->attrib.pValue, item->len);
- sftk_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-/*
- * fetch multiple attributes into SECItems. Secitem data is allocated in
- * the specified arena.
- */
-CK_RV
-sftk_MultipleAttribute2SecItem(PLArenaPool *arena, SFTKObject *object,
- SFTKItemTemplate *itemTemplate, int itemTemplateCount)
-{
-
- CK_RV crv = CKR_OK;
- CK_ATTRIBUTE templateSpace[SFTK_MAX_ITEM_TEMPLATE];
- CK_ATTRIBUTE *template;
- SFTKTokenObject *tokObject;
- SFTKDBHandle *dbHandle = NULL;
- int i;
-
- tokObject = sftk_narrowToTokenObject(object);
-
- /* session objects, just loop through the list */
- if (tokObject == NULL) {
- for (i=0; i < itemTemplateCount; i++) {
- crv = sftk_Attribute2SecItem(arena,itemTemplate[i].item, object,
- itemTemplate[i].type);
- if (crv != CKR_OK) {
- return crv;
- }
- }
- return CKR_OK;
- }
-
- /* don't do any work if none is required */
- if (itemTemplateCount == 0) {
- return CKR_OK;
- }
-
- /* don't allocate the template unless we need it */
- if (itemTemplateCount > SFTK_MAX_ITEM_TEMPLATE) {
- template = PORT_NewArray(CK_ATTRIBUTE, itemTemplateCount);
- } else {
- template = templateSpace;
- }
-
- if (template == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
-
- dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);
- if (dbHandle == NULL) {
- crv = CKR_OBJECT_HANDLE_INVALID;
- goto loser;
- }
-
- /* set up the PKCS #11 template */
- for (i=0; i < itemTemplateCount; i++) {
- template[i].type = itemTemplate[i].type;
- template[i].pValue = NULL;
- template[i].ulValueLen = 0;
- }
-
- /* fetch the attribute lengths */
- crv = sftkdb_GetAttributeValue(dbHandle, object->handle,
- template, itemTemplateCount);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- /* allocate space for the attributes */
- for (i=0; i < itemTemplateCount ; i++) {
- template[i].pValue = PORT_ArenaAlloc(arena, template[i].ulValueLen);
- if (template[i].pValue == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- }
-
- /* fetch the attributes */
- crv = sftkdb_GetAttributeValue(dbHandle, object->handle,
- template, itemTemplateCount);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- /* Fill in the items */
- for (i=0; i < itemTemplateCount; i++) {
- itemTemplate[i].item->data = template[i].pValue;
- itemTemplate[i].item->len = template[i].ulValueLen;
- }
-
-loser:
- if (template != templateSpace) {
- PORT_Free(template);
- }
- if (dbHandle) {
- sftk_freeDB(dbHandle);
- }
-
- return crv;
-}
-
-
-/*
- * delete an attribute from an object
- */
-static void
-sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute)
-{
- SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
-
- if (sessObject == NULL) {
- return ;
- }
- PZ_Lock(sessObject->attributeLock);
- if (sftkqueue_is_queued(attribute,attribute->handle,
- sessObject->head, sessObject->hashSize)) {
- sftkqueue_delete(attribute,attribute->handle,
- sessObject->head, sessObject->hashSize);
- }
- PZ_Unlock(sessObject->attributeLock);
-}
-
-/*
- * this is only valid for CK_BBOOL type attributes. Return the state
- * of that attribute.
- */
-PRBool
-sftk_isTrue(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- PRBool tok = PR_FALSE;
-
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) { return PR_FALSE; }
- tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue);
- sftk_FreeAttribute(attribute);
-
- return tok;
-}
-
-/*
- * force an attribute to null.
- * this is for sensitive keys which are stored in the database, we don't
- * want to keep this info around in memory in the clear.
- */
-void
-sftk_nullAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
-
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) return;
-
- if (attribute->attrib.pValue != NULL) {
- PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
- if (attribute->freeData) {
- PORT_Free(attribute->attrib.pValue);
- }
- attribute->freeData = PR_FALSE;
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
- sftk_FreeAttribute(attribute);
-}
-
-
-static CK_RV
-sftk_forceTokenAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len)
-{
- CK_ATTRIBUTE attribute;
- SFTKDBHandle *dbHandle = NULL;
- SFTKTokenObject *to = sftk_narrowToTokenObject(object);
- CK_RV crv;
-
- PORT_Assert(to);
- if (to == NULL) {
- return CKR_DEVICE_ERROR;
- }
-
- dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);
-
- attribute.type = type;
- attribute.pValue = (void *)value;
- attribute.ulValueLen = len;
-
- crv = sftkdb_SetAttributeValue(dbHandle, object, &attribute, 1);
- sftk_freeDB(dbHandle);
- return crv;
-}
-
-/*
- * force an attribute to a specifc value.
- */
-CK_RV
-sftk_forceAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
- const void *value, unsigned int len)
-{
- SFTKAttribute *attribute;
- void *att_val = NULL;
- PRBool freeData = PR_FALSE;
-
- PORT_Assert(object);
- PORT_Assert(object->refCount);
- PORT_Assert(object->slot);
- if (!object ||
- !object->refCount ||
- !object->slot) {
- return CKR_DEVICE_ERROR;
- }
- if (sftk_isToken(object->handle)) {
- return sftk_forceTokenAttribute(object,type,value,len);
- }
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) return sftk_AddAttributeType(object,type,value,len);
-
-
- if (value) {
- if (len <= ATTR_SPACE) {
- att_val = attribute->space;
- } else {
- att_val = PORT_Alloc(len);
- freeData = PR_TRUE;
- }
- if (att_val == NULL) {
- return CKR_HOST_MEMORY;
- }
- if (attribute->attrib.pValue == att_val) {
- PORT_Memset(attribute->attrib.pValue,0,
- attribute->attrib.ulValueLen);
- }
- PORT_Memcpy(att_val,value,len);
- }
- if (attribute->attrib.pValue != NULL) {
- if (attribute->attrib.pValue != att_val) {
- PORT_Memset(attribute->attrib.pValue,0,
- attribute->attrib.ulValueLen);
- }
- if (attribute->freeData) {
- PORT_Free(attribute->attrib.pValue);
- }
- attribute->freeData = PR_FALSE;
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
- if (att_val) {
- attribute->attrib.pValue = att_val;
- attribute->attrib.ulValueLen = len;
- attribute->freeData = freeData;
- }
- sftk_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-/*
- * return a null terminated string from attribute 'type'. This string
- * is allocated and needs to be freed with PORT_Free() When complete.
- */
-char *
-sftk_getString(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- char *label = NULL;
-
- attribute=sftk_FindAttribute(object,type);
- if (attribute == NULL) return NULL;
-
- if (attribute->attrib.pValue != NULL) {
- label = (char *) PORT_Alloc(attribute->attrib.ulValueLen+1);
- if (label == NULL) {
- sftk_FreeAttribute(attribute);
- return NULL;
- }
-
- PORT_Memcpy(label,attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- label[attribute->attrib.ulValueLen] = 0;
- }
- sftk_FreeAttribute(attribute);
- return label;
-}
-
-/*
- * decode when a particular attribute may be modified
- * SFTK_NEVER: This attribute must be set at object creation time and
- * can never be modified.
- * SFTK_ONCOPY: This attribute may be modified only when you copy the
- * object.
- * SFTK_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from
- * CK_FALSE to CK_TRUE.
- * SFTK_ALWAYS: This attribute can always be modified.
- * Some attributes vary their modification type based on the class of the
- * object.
- */
-SFTKModifyType
-sftk_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
-{
- /* if we don't know about it, user user defined, always allow modify */
- SFTKModifyType mtype = SFTK_ALWAYS;
-
- switch(type) {
- /* NEVER */
- case CKA_CLASS:
- case CKA_CERTIFICATE_TYPE:
- case CKA_KEY_TYPE:
- case CKA_MODULUS:
- case CKA_MODULUS_BITS:
- case CKA_PUBLIC_EXPONENT:
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME:
- case CKA_SUBPRIME:
- case CKA_BASE:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- case CKA_VALUE_LEN:
- case CKA_ALWAYS_SENSITIVE:
- case CKA_NEVER_EXTRACTABLE:
- case CKA_NETSCAPE_DB:
- mtype = SFTK_NEVER;
- break;
-
- /* ONCOPY */
- case CKA_TOKEN:
- case CKA_PRIVATE:
- case CKA_MODIFIABLE:
- mtype = SFTK_ONCOPY;
- break;
-
- /* SENSITIVE */
- case CKA_SENSITIVE:
- case CKA_EXTRACTABLE:
- mtype = SFTK_SENSITIVE;
- break;
-
- /* ALWAYS */
- case CKA_LABEL:
- case CKA_APPLICATION:
- case CKA_ID:
- case CKA_SERIAL_NUMBER:
- case CKA_START_DATE:
- case CKA_END_DATE:
- case CKA_DERIVE:
- case CKA_ENCRYPT:
- case CKA_DECRYPT:
- case CKA_SIGN:
- case CKA_VERIFY:
- case CKA_SIGN_RECOVER:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- case CKA_UNWRAP:
- mtype = SFTK_ALWAYS;
- break;
-
- /* DEPENDS ON CLASS */
- case CKA_VALUE:
- mtype = (inClass == CKO_DATA) ? SFTK_ALWAYS : SFTK_NEVER;
- break;
-
- case CKA_SUBJECT:
- mtype = (inClass == CKO_CERTIFICATE) ? SFTK_NEVER : SFTK_ALWAYS;
- break;
- default:
- break;
- }
- return mtype;
-}
-
-/* decode if a particular attribute is sensitive (cannot be read
- * back to the user of if the object is set to SENSITIVE) */
-PRBool
-sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
-{
- switch(type) {
- /* ALWAYS */
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- return PR_TRUE;
-
- /* DEPENDS ON CLASS */
- case CKA_VALUE:
- /* PRIVATE and SECRET KEYS have SENSITIVE values */
- return (PRBool)((inClass == CKO_PRIVATE_KEY) || (inClass == CKO_SECRET_KEY));
-
- default:
- break;
- }
- return PR_FALSE;
-}
-
-/*
- * copy an attribute into a SECItem. Secitem is allocated in the specified
- * arena.
- */
-CK_RV
-sftk_Attribute2SecItem(PLArenaPool *arena,SECItem *item,SFTKObject *object,
- CK_ATTRIBUTE_TYPE type)
-{
- int len;
- SFTKAttribute *attribute;
-
- attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
- len = attribute->attrib.ulValueLen;
-
- if (arena) {
- item->data = (unsigned char *) PORT_ArenaAlloc(arena,len);
- } else {
- item->data = (unsigned char *) PORT_Alloc(len);
- }
- if (item->data == NULL) {
- sftk_FreeAttribute(attribute);
- return CKR_HOST_MEMORY;
- }
- item->len = len;
- PORT_Memcpy(item->data,attribute->attrib.pValue, len);
- sftk_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-CK_RV
-sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
- CK_ULONG *longData)
-{
- SFTKAttribute *attribute;
-
- attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
-
- if (attribute->attrib.ulValueLen != sizeof(CK_ULONG)) {
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- *longData = *(CK_ULONG *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
- return CKR_OK;
-}
-
-void
-sftk_DeleteAttributeType(SFTKObject *object,CK_ATTRIBUTE_TYPE type)
-{
- SFTKAttribute *attribute;
- attribute = sftk_FindAttribute(object, type);
- if (attribute == NULL) return ;
- sftk_DeleteAttribute(object,attribute);
- sftk_FreeAttribute(attribute);
-}
-
-CK_RV
-sftk_AddAttributeType(SFTKObject *object,CK_ATTRIBUTE_TYPE type,
- const void *valPtr, CK_ULONG length)
-{
- SFTKAttribute *attribute;
- attribute = sftk_NewAttribute(object,type,valPtr,length);
- if (attribute == NULL) { return CKR_HOST_MEMORY; }
- sftk_AddAttribute(object,attribute);
- return CKR_OK;
-}
-
-/*
- * ******************** Object Utilities *******************************
- */
-
-/* must be called holding sftk_tokenKeyLock(slot) */
-static SECItem *
-sftk_lookupTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle)
-{
- return (SECItem *)PL_HashTableLookup(slot->tokObjHashTable, (void *)handle);
-}
-
-/*
- * use the refLock. This operations should be very rare, so the added
- * contention on the ref lock should be lower than the overhead of adding
- * a new lock. We use separate functions for this just in case I'm wrong.
- */
-static void
-sftk_tokenKeyLock(SFTKSlot *slot) {
- SKIP_AFTER_FORK(PZ_Lock(slot->objectLock));
-}
-
-static void
-sftk_tokenKeyUnlock(SFTKSlot *slot) {
- SKIP_AFTER_FORK(PZ_Unlock(slot->objectLock));
-}
-
-static PRIntn
-sftk_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg)
-{
- SECItem *item = (SECItem *)entry->value;
-
- SECITEM_FreeItem(item, PR_TRUE);
- return HT_ENUMERATE_NEXT;
-}
-
-CK_RV
-SFTK_ClearTokenKeyHashTable(SFTKSlot *slot)
-{
- sftk_tokenKeyLock(slot);
- PORT_Assert(!slot->present);
- PL_HashTableEnumerateEntries(slot->tokObjHashTable, sftk_freeHashItem, NULL);
- sftk_tokenKeyUnlock(slot);
- return CKR_OK;
-}
-
-
-/* allocation hooks that allow us to recycle old object structures */
-static SFTKObjectFreeList sessionObjectList = { NULL, NULL, 0 };
-static SFTKObjectFreeList tokenObjectList = { NULL, NULL, 0 };
-
-SFTKObject *
-sftk_GetObjectFromList(PRBool *hasLocks, PRBool optimizeSpace,
- SFTKObjectFreeList *list, unsigned int hashSize, PRBool isSessionObject)
-{
- SFTKObject *object;
- int size = 0;
-
- if (!optimizeSpace) {
- PZ_Lock(list->lock);
- object = list->head;
- if (object) {
- list->head = object->next;
- list->count--;
- }
- PZ_Unlock(list->lock);
- if (object) {
- object->next = object->prev = NULL;
- *hasLocks = PR_TRUE;
- return object;
- }
- }
- size = isSessionObject ? sizeof(SFTKSessionObject)
- + hashSize *sizeof(SFTKAttribute *) : sizeof(SFTKTokenObject);
-
- object = (SFTKObject*)PORT_ZAlloc(size);
- if (isSessionObject && object) {
- ((SFTKSessionObject *)object)->hashSize = hashSize;
- }
- *hasLocks = PR_FALSE;
- return object;
-}
-
-static void
-sftk_PutObjectToList(SFTKObject *object, SFTKObjectFreeList *list,
- PRBool isSessionObject) {
-
- /* the code below is equivalent to :
- * optimizeSpace = isSessionObject ? object->optimizeSpace : PR_FALSE;
- * just faster.
- */
- PRBool optimizeSpace = isSessionObject &&
- ((SFTKSessionObject *)object)->optimizeSpace;
- if (object->refLock && !optimizeSpace
- && (list->count < MAX_OBJECT_LIST_SIZE)) {
- PZ_Lock(list->lock);
- object->next = list->head;
- list->head = object;
- list->count++;
- PZ_Unlock(list->lock);
- return;
- }
- if (isSessionObject) {
- SFTKSessionObject *so = (SFTKSessionObject *)object;
- PZ_DestroyLock(so->attributeLock);
- so->attributeLock = NULL;
- }
- if (object->refLock) {
- PZ_DestroyLock(object->refLock);
- object->refLock = NULL;
- }
- PORT_Free(object);
-}
-
-static SFTKObject *
-sftk_freeObjectData(SFTKObject *object) {
- SFTKObject *next = object->next;
-
- PORT_Free(object);
- return next;
-}
-
-static void
-sftk_InitFreeList(SFTKObjectFreeList *list)
-{
- list->lock = PZ_NewLock(nssILockObject);
-}
-
-void sftk_InitFreeLists(void)
-{
- sftk_InitFreeList(&sessionObjectList);
- sftk_InitFreeList(&tokenObjectList);
-}
-
-static void
-sftk_CleanupFreeList(SFTKObjectFreeList *list, PRBool isSessionList)
-{
- SFTKObject *object;
-
- if (!list->lock) {
- return;
- }
- SKIP_AFTER_FORK(PZ_Lock(list->lock));
- for (object= list->head; object != NULL;
- object = sftk_freeObjectData(object)) {
- PZ_DestroyLock(object->refLock);
- if (isSessionList) {
- PZ_DestroyLock(((SFTKSessionObject *)object)->attributeLock);
- }
- }
- list->count = 0;
- list->head = NULL;
- SKIP_AFTER_FORK(PZ_Unlock(list->lock));
- SKIP_AFTER_FORK(PZ_DestroyLock(list->lock));
- list->lock = NULL;
-}
-
-void
-sftk_CleanupFreeLists(void)
-{
- sftk_CleanupFreeList(&sessionObjectList, PR_TRUE);
- sftk_CleanupFreeList(&tokenObjectList, PR_FALSE);
-}
-
-
-/*
- * Create a new object
- */
-SFTKObject *
-sftk_NewObject(SFTKSlot *slot)
-{
- SFTKObject *object;
- SFTKSessionObject *sessObject;
- PRBool hasLocks = PR_FALSE;
- unsigned int i;
- unsigned int hashSize = 0;
-
- hashSize = (slot->optimizeSpace) ? SPACE_ATTRIBUTE_HASH_SIZE :
- TIME_ATTRIBUTE_HASH_SIZE;
-
- object = sftk_GetObjectFromList(&hasLocks, slot->optimizeSpace,
- &sessionObjectList, hashSize, PR_TRUE);
- if (object == NULL) {
- return NULL;
- }
- sessObject = (SFTKSessionObject *)object;
- sessObject->nextAttr = 0;
-
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- sessObject->attrList[i].attrib.pValue = NULL;
- sessObject->attrList[i].freeData = PR_FALSE;
- }
- sessObject->optimizeSpace = slot->optimizeSpace;
-
- object->handle = 0;
- object->next = object->prev = NULL;
- object->slot = slot;
-
- object->refCount = 1;
- sessObject->sessionList.next = NULL;
- sessObject->sessionList.prev = NULL;
- sessObject->sessionList.parent = object;
- sessObject->session = NULL;
- sessObject->wasDerived = PR_FALSE;
- if (!hasLocks) object->refLock = PZ_NewLock(nssILockRefLock);
- if (object->refLock == NULL) {
- PORT_Free(object);
- return NULL;
- }
- if (!hasLocks) sessObject->attributeLock = PZ_NewLock(nssILockAttribute);
- if (sessObject->attributeLock == NULL) {
- PZ_DestroyLock(object->refLock);
- PORT_Free(object);
- return NULL;
- }
- for (i=0; i < sessObject->hashSize; i++) {
- sessObject->head[i] = NULL;
- }
- object->objectInfo = NULL;
- object->infoFree = NULL;
- return object;
-}
-
-static CK_RV
-sftk_DestroySessionObjectData(SFTKSessionObject *so)
-{
- int i;
-
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- unsigned char *value = so->attrList[i].attrib.pValue;
- if (value) {
- PORT_Memset(value,0,so->attrList[i].attrib.ulValueLen);
- if (so->attrList[i].freeData) {
- PORT_Free(value);
- }
- so->attrList[i].attrib.pValue = NULL;
- so->attrList[i].freeData = PR_FALSE;
- }
- }
-/* PZ_DestroyLock(so->attributeLock);*/
- return CKR_OK;
-}
-
-/*
- * free all the data associated with an object. Object reference count must
- * be 'zero'.
- */
-static CK_RV
-sftk_DestroyObject(SFTKObject *object)
-{
- CK_RV crv = CKR_OK;
- SFTKSessionObject *so = sftk_narrowToSessionObject(object);
- SFTKTokenObject *to = sftk_narrowToTokenObject(object);
-
- PORT_Assert(object->refCount == 0);
-
- /* delete the database value */
- if (to) {
- if (to->dbKey.data) {
- PORT_Free(to->dbKey.data);
- to->dbKey.data = NULL;
- }
- }
- if (so) {
- sftk_DestroySessionObjectData(so);
- }
- if (object->objectInfo) {
- (*object->infoFree)(object->objectInfo);
- object->objectInfo = NULL;
- object->infoFree = NULL;
- }
- if (so) {
- sftk_PutObjectToList(object,&sessionObjectList,PR_TRUE);
- } else {
- sftk_PutObjectToList(object,&tokenObjectList,PR_FALSE);
- }
- return crv;
-}
-
-void
-sftk_ReferenceObject(SFTKObject *object)
-{
- PZ_Lock(object->refLock);
- object->refCount++;
- PZ_Unlock(object->refLock);
-}
-
-static SFTKObject *
-sftk_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, SFTKSlot *slot)
-{
- SFTKObject *object;
- PRUint32 index = sftk_hash(handle, slot->sessObjHashSize);
-
- if (sftk_isToken(handle)) {
- return sftk_NewTokenObject(slot, NULL, handle);
- }
-
- PZ_Lock(slot->objectLock);
- sftkqueue_find2(object, handle, index, slot->sessObjHashTable);
- if (object) {
- sftk_ReferenceObject(object);
- }
- PZ_Unlock(slot->objectLock);
-
- return(object);
-}
-/*
- * look up and object structure from a handle. OBJECT_Handles only make
- * sense in terms of a given session. make a reference to that object
- * structure returned.
- */
-SFTKObject *
-sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, SFTKSession *session)
-{
- SFTKSlot *slot = sftk_SlotFromSession(session);
-
- return sftk_ObjectFromHandleOnSlot(handle,slot);
-}
-
-
-/*
- * release a reference to an object handle
- */
-SFTKFreeStatus
-sftk_FreeObject(SFTKObject *object)
-{
- PRBool destroy = PR_FALSE;
- CK_RV crv;
-
- PZ_Lock(object->refLock);
- if (object->refCount == 1) destroy = PR_TRUE;
- object->refCount--;
- PZ_Unlock(object->refLock);
-
- if (destroy) {
- crv = sftk_DestroyObject(object);
- if (crv != CKR_OK) {
- return SFTK_DestroyFailure;
- }
- return SFTK_Destroyed;
- }
- return SFTK_Busy;
-}
-
-/*
- * add an object to a slot and session queue. These two functions
- * adopt the object.
- */
-void
-sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object)
-{
- PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);
- sftkqueue_init_element(object);
- PZ_Lock(slot->objectLock);
- sftkqueue_add2(object, object->handle, index, slot->sessObjHashTable);
- PZ_Unlock(slot->objectLock);
-}
-
-void
-sftk_AddObject(SFTKSession *session, SFTKObject *object)
-{
- SFTKSlot *slot = sftk_SlotFromSession(session);
- SFTKSessionObject *so = sftk_narrowToSessionObject(object);
-
- if (so) {
- PZ_Lock(session->objectLock);
- sftkqueue_add(&so->sessionList,0,session->objects,0);
- so->session = session;
- PZ_Unlock(session->objectLock);
- }
- sftk_AddSlotObject(slot,object);
- sftk_ReferenceObject(object);
-}
-
-/*
- * delete an object from a slot and session queue
- */
-CK_RV
-sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
-{
- SFTKSlot *slot = sftk_SlotFromSession(session);
- SFTKSessionObject *so = sftk_narrowToSessionObject(object);
- SFTKTokenObject *to = sftk_narrowToTokenObject(object);
- CK_RV crv = CKR_OK;
- PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);
-
- /* Handle Token case */
- if (so && so->session) {
- SFTKSession *session = so->session;
- PZ_Lock(session->objectLock);
- sftkqueue_delete(&so->sessionList,0,session->objects,0);
- PZ_Unlock(session->objectLock);
- PZ_Lock(slot->objectLock);
- sftkqueue_delete2(object, object->handle, index, slot->sessObjHashTable);
- PZ_Unlock(slot->objectLock);
- sftkqueue_clear_deleted_element(object);
- sftk_FreeObject(object); /* free the reference owned by the queue */
- } else {
- SFTKDBHandle *handle = sftk_getDBForTokenObject(slot, object->handle);
-
- PORT_Assert(to);
- crv = sftkdb_DestroyObject(handle, object->handle);
- sftk_freeDB(handle);
- }
- return crv;
-}
-
-/*
- * Token objects don't explicitly store their attributes, so we need to know
- * what attributes make up a particular token object before we can copy it.
- * below are the tables by object type.
- */
-static const CK_ATTRIBUTE_TYPE commonAttrs[] = {
- CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_MODIFIABLE
-};
-static const CK_ULONG commonAttrsCount =
- sizeof(commonAttrs)/sizeof(commonAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE commonKeyAttrs[] = {
- CKA_ID, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE, CKA_LOCAL, CKA_KEY_TYPE
-};
-static const CK_ULONG commonKeyAttrsCount =
- sizeof(commonKeyAttrs)/sizeof(commonKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE secretKeyAttrs[] = {
- CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN,
- CKA_VERIFY, CKA_WRAP, CKA_UNWRAP, CKA_VALUE
-};
-static const CK_ULONG secretKeyAttrsCount =
- sizeof(secretKeyAttrs)/sizeof(secretKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE commonPubKeyAttrs[] = {
- CKA_ENCRYPT, CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_WRAP, CKA_SUBJECT
-};
-static const CK_ULONG commonPubKeyAttrsCount =
- sizeof(commonPubKeyAttrs)/sizeof(commonPubKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE rsaPubKeyAttrs[] = {
- CKA_MODULUS, CKA_PUBLIC_EXPONENT
-};
-static const CK_ULONG rsaPubKeyAttrsCount =
- sizeof(rsaPubKeyAttrs)/sizeof(rsaPubKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE dsaPubKeyAttrs[] = {
- CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
-};
-static const CK_ULONG dsaPubKeyAttrsCount =
- sizeof(dsaPubKeyAttrs)/sizeof(dsaPubKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE dhPubKeyAttrs[] = {
- CKA_PRIME, CKA_BASE, CKA_VALUE
-};
-static const CK_ULONG dhPubKeyAttrsCount =
- sizeof(dhPubKeyAttrs)/sizeof(dhPubKeyAttrs[0]);
-#ifdef NSS_ENABLE_ECC
-static const CK_ATTRIBUTE_TYPE ecPubKeyAttrs[] = {
- CKA_EC_PARAMS, CKA_EC_POINT
-};
-static const CK_ULONG ecPubKeyAttrsCount =
- sizeof(ecPubKeyAttrs)/sizeof(ecPubKeyAttrs[0]);
-#endif
-
-static const CK_ATTRIBUTE_TYPE commonPrivKeyAttrs[] = {
- CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_SUBJECT,
- CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NETSCAPE_DB
-};
-static const CK_ULONG commonPrivKeyAttrsCount =
- sizeof(commonPrivKeyAttrs)/sizeof(commonPrivKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE rsaPrivKeyAttrs[] = {
- CKA_MODULUS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
- CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT
-};
-static const CK_ULONG rsaPrivKeyAttrsCount =
- sizeof(rsaPrivKeyAttrs)/sizeof(rsaPrivKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE dsaPrivKeyAttrs[] = {
- CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
-};
-static const CK_ULONG dsaPrivKeyAttrsCount =
- sizeof(dsaPrivKeyAttrs)/sizeof(dsaPrivKeyAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE dhPrivKeyAttrs[] = {
- CKA_PRIME, CKA_BASE, CKA_VALUE
-};
-static const CK_ULONG dhPrivKeyAttrsCount =
- sizeof(dhPrivKeyAttrs)/sizeof(dhPrivKeyAttrs[0]);
-#ifdef NSS_ENABLE_ECC
-static const CK_ATTRIBUTE_TYPE ecPrivKeyAttrs[] = {
- CKA_EC_PARAMS, CKA_VALUE
-};
-static const CK_ULONG ecPrivKeyAttrsCount =
- sizeof(ecPrivKeyAttrs)/sizeof(ecPrivKeyAttrs[0]);
-#endif
-
-static const CK_ATTRIBUTE_TYPE certAttrs[] = {
- CKA_CERTIFICATE_TYPE, CKA_VALUE, CKA_SUBJECT, CKA_ISSUER, CKA_SERIAL_NUMBER
-};
-static const CK_ULONG certAttrsCount =
- sizeof(certAttrs)/sizeof(certAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE trustAttrs[] = {
- CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
- CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_EMAIL_PROTECTION,
- CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED
-};
-static const CK_ULONG trustAttrsCount =
- sizeof(trustAttrs)/sizeof(trustAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE smimeAttrs[] = {
- CKA_SUBJECT, CKA_NETSCAPE_EMAIL, CKA_NETSCAPE_SMIME_TIMESTAMP, CKA_VALUE
-};
-static const CK_ULONG smimeAttrsCount =
- sizeof(smimeAttrs)/sizeof(smimeAttrs[0]);
-
-static const CK_ATTRIBUTE_TYPE crlAttrs[] = {
- CKA_SUBJECT, CKA_VALUE, CKA_NETSCAPE_URL, CKA_NETSCAPE_KRL
-};
-static const CK_ULONG crlAttrsCount =
- sizeof(crlAttrs)/sizeof(crlAttrs[0]);
-
-/* copy an object based on it's table */
-CK_RV
-stfk_CopyTokenAttributes(SFTKObject *destObject,SFTKTokenObject *src_to,
- const CK_ATTRIBUTE_TYPE *attrArray, CK_ULONG attrCount)
-{
- SFTKAttribute *attribute;
- SFTKAttribute *newAttribute;
- CK_RV crv = CKR_OK;
- unsigned int i;
-
- for (i=0; i < attrCount; i++) {
- if (!sftk_hasAttribute(destObject,attrArray[i])) {
- attribute =sftk_FindAttribute(&src_to->obj, attrArray[i]);
- if (!attribute) {
- continue; /* return CKR_ATTRIBUTE_VALUE_INVALID; */
- }
- /* we need to copy the attribute since each attribute
- * only has one set of link list pointers */
- newAttribute = sftk_NewAttribute( destObject,
- sftk_attr_expand(&attribute->attrib));
- sftk_FreeAttribute(attribute); /* free the old attribute */
- if (!newAttribute) {
- return CKR_HOST_MEMORY;
- }
- sftk_AddAttribute(destObject,newAttribute);
- }
- }
- return crv;
-}
-
-CK_RV
-stfk_CopyTokenPrivateKey(SFTKObject *destObject,SFTKTokenObject *src_to)
-{
- CK_RV crv;
- CK_KEY_TYPE key_type;
- SFTKAttribute *attribute;
-
- /* copy the common attributes for all keys first */
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
- commonKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- /* copy the common attributes for all private keys next */
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs,
- commonPrivKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
- PORT_Assert(attribute); /* if it wasn't here, ww should have failed
- * copying the common attributes */
- if (!attribute) {
- /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
- * the fact is, the only reason we couldn't get the attribute would
- * be a memory error or database error (an error in the 'device').
- * if we have a database error code, we could return it here */
- crv = CKR_DEVICE_ERROR;
- goto fail;
- }
- key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
-
- /* finally copy the attributes for various private key types */
- switch (key_type) {
- case CKK_RSA:
- crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPrivKeyAttrs,
- rsaPrivKeyAttrsCount);
- break;
- case CKK_DSA:
- crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPrivKeyAttrs,
- dsaPrivKeyAttrsCount);
- break;
- case CKK_DH:
- crv = stfk_CopyTokenAttributes(destObject, src_to, dhPrivKeyAttrs,
- dhPrivKeyAttrsCount);
- break;
-#ifdef NSS_ENABLE_ECC
- case CKK_EC:
- crv = stfk_CopyTokenAttributes(destObject, src_to, ecPrivKeyAttrs,
- ecPrivKeyAttrsCount);
- break;
-#endif
- default:
- crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
- * of token keys into our database. */
- }
-fail:
- return crv;
-}
-
-CK_RV
-stfk_CopyTokenPublicKey(SFTKObject *destObject,SFTKTokenObject *src_to)
-{
- CK_RV crv;
- CK_KEY_TYPE key_type;
- SFTKAttribute *attribute;
-
- /* copy the common attributes for all keys first */
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
- commonKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
-
- /* copy the common attributes for all public keys next */
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonPubKeyAttrs,
- commonPubKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
- PORT_Assert(attribute); /* if it wasn't here, ww should have failed
- * copying the common attributes */
- if (!attribute) {
- /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
- * the fact is, the only reason we couldn't get the attribute would
- * be a memory error or database error (an error in the 'device').
- * if we have a database error code, we could return it here */
- crv = CKR_DEVICE_ERROR;
- goto fail;
- }
- key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
- sftk_FreeAttribute(attribute);
-
- /* finally copy the attributes for various public key types */
- switch (key_type) {
- case CKK_RSA:
- crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPubKeyAttrs,
- rsaPubKeyAttrsCount);
- break;
- case CKK_DSA:
- crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPubKeyAttrs,
- dsaPubKeyAttrsCount);
- break;
- case CKK_DH:
- crv = stfk_CopyTokenAttributes(destObject, src_to, dhPubKeyAttrs,
- dhPubKeyAttrsCount);
- break;
-#ifdef NSS_ENABLE_ECC
- case CKK_EC:
- crv = stfk_CopyTokenAttributes(destObject, src_to, ecPubKeyAttrs,
- ecPubKeyAttrsCount);
- break;
-#endif
- default:
- crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
- * of token keys into our database. */
- }
-fail:
- return crv;
-}
-CK_RV
-stfk_CopyTokenSecretKey(SFTKObject *destObject,SFTKTokenObject *src_to)
-{
- CK_RV crv;
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
- commonKeyAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- crv = stfk_CopyTokenAttributes(destObject, src_to, secretKeyAttrs,
- secretKeyAttrsCount);
-fail:
- return crv;
-}
-
-/*
- * Copy a token object. We need to explicitly copy the relevant
- * attributes since token objects don't store those attributes in
- * the token itself.
- */
-CK_RV
-sftk_CopyTokenObject(SFTKObject *destObject,SFTKObject *srcObject)
-{
- SFTKTokenObject *src_to = sftk_narrowToTokenObject(srcObject);
- CK_RV crv;
-
- PORT_Assert(src_to);
- if (src_to == NULL) {
- return CKR_DEVICE_ERROR; /* internal state inconsistant */
- }
-
- crv = stfk_CopyTokenAttributes(destObject, src_to, commonAttrs,
- commonAttrsCount);
- if (crv != CKR_OK) {
- goto fail;
- }
- switch (src_to->obj.objclass) {
- case CKO_CERTIFICATE:
- crv = stfk_CopyTokenAttributes(destObject, src_to, certAttrs,
- certAttrsCount);
- break;
- case CKO_NETSCAPE_TRUST:
- crv = stfk_CopyTokenAttributes(destObject, src_to, trustAttrs,
- trustAttrsCount);
- break;
- case CKO_NETSCAPE_SMIME:
- crv = stfk_CopyTokenAttributes(destObject, src_to, smimeAttrs,
- smimeAttrsCount);
- break;
- case CKO_NETSCAPE_CRL:
- crv = stfk_CopyTokenAttributes(destObject, src_to, crlAttrs,
- crlAttrsCount);
- break;
- case CKO_PRIVATE_KEY:
- crv = stfk_CopyTokenPrivateKey(destObject,src_to);
- break;
- case CKO_PUBLIC_KEY:
- crv = stfk_CopyTokenPublicKey(destObject,src_to);
- break;
- case CKO_SECRET_KEY:
- crv = stfk_CopyTokenSecretKey(destObject,src_to);
- break;
- default:
- crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
- * of token keys into our database. */
- }
-fail:
- return crv;
-}
-
-/*
- * copy the attributes from one object to another. Don't overwrite existing
- * attributes. NOTE: This is a pretty expensive operation since it
- * grabs the attribute locks for the src object for a *long* time.
- */
-CK_RV
-sftk_CopyObject(SFTKObject *destObject,SFTKObject *srcObject)
-{
- SFTKAttribute *attribute;
- SFTKSessionObject *src_so = sftk_narrowToSessionObject(srcObject);
- unsigned int i;
-
- if (src_so == NULL) {
- return sftk_CopyTokenObject(destObject,srcObject);
- }
-
- PZ_Lock(src_so->attributeLock);
- for(i=0; i < src_so->hashSize; i++) {
- attribute = src_so->head[i];
- do {
- if (attribute) {
- if (!sftk_hasAttribute(destObject,attribute->handle)) {
- /* we need to copy the attribute since each attribute
- * only has one set of link list pointers */
- SFTKAttribute *newAttribute = sftk_NewAttribute(
- destObject,sftk_attr_expand(&attribute->attrib));
- if (newAttribute == NULL) {
- PZ_Unlock(src_so->attributeLock);
- return CKR_HOST_MEMORY;
- }
- sftk_AddAttribute(destObject,newAttribute);
- }
- attribute=attribute->next;
- }
- } while (attribute != NULL);
- }
- PZ_Unlock(src_so->attributeLock);
-
- return CKR_OK;
-}
-
-/*
- * ******************** Search Utilities *******************************
- */
-
-/* add an object to a search list */
-CK_RV
-AddToList(SFTKObjectListElement **list,SFTKObject *object)
-{
- SFTKObjectListElement *newElem =
- (SFTKObjectListElement *)PORT_Alloc(sizeof(SFTKObjectListElement));
-
- if (newElem == NULL) return CKR_HOST_MEMORY;
-
- newElem->next = *list;
- newElem->object = object;
- sftk_ReferenceObject(object);
-
- *list = newElem;
- return CKR_OK;
-}
-
-
-/* return true if the object matches the template */
-PRBool
-sftk_objectMatch(SFTKObject *object,CK_ATTRIBUTE_PTR theTemplate,int count)
-{
- int i;
-
- for (i=0; i < count; i++) {
- SFTKAttribute *attribute = sftk_FindAttribute(object,theTemplate[i].type);
- if (attribute == NULL) {
- return PR_FALSE;
- }
- if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) {
- if (PORT_Memcmp(attribute->attrib.pValue,theTemplate[i].pValue,
- theTemplate[i].ulValueLen) == 0) {
- sftk_FreeAttribute(attribute);
- continue;
- }
- }
- sftk_FreeAttribute(attribute);
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-/* search through all the objects in the queue and return the template matches
- * in the object list.
- */
-CK_RV
-sftk_searchObjectList(SFTKSearchResults *search,SFTKObject **head,
- unsigned int size, PZLock *lock, CK_ATTRIBUTE_PTR theTemplate,
- int count, PRBool isLoggedIn)
-{
- unsigned int i;
- SFTKObject *object;
- CK_RV crv = CKR_OK;
-
- for(i=0; i < size; i++) {
- /* We need to hold the lock to copy a consistant version of
- * the linked list. */
- PZ_Lock(lock);
- for (object = head[i]; object != NULL; object= object->next) {
- if (sftk_objectMatch(object,theTemplate,count)) {
- /* don't return objects that aren't yet visible */
- if ((!isLoggedIn) && sftk_isTrue(object,CKA_PRIVATE)) continue;
- sftk_addHandle(search,object->handle);
- }
- }
- PZ_Unlock(lock);
- }
- return crv;
-}
-
-/*
- * free a single list element. Return the Next object in the list.
- */
-SFTKObjectListElement *
-sftk_FreeObjectListElement(SFTKObjectListElement *objectList)
-{
- SFTKObjectListElement *ol = objectList->next;
-
- sftk_FreeObject(objectList->object);
- PORT_Free(objectList);
- return ol;
-}
-
-/* free an entire object list */
-void
-sftk_FreeObjectList(SFTKObjectListElement *objectList)
-{
- SFTKObjectListElement *ol;
-
- for (ol= objectList; ol != NULL; ol = sftk_FreeObjectListElement(ol)) {}
-}
-
-/*
- * free a search structure
- */
-void
-sftk_FreeSearch(SFTKSearchResults *search)
-{
- if (search->handles) {
- PORT_Free(search->handles);
- }
- PORT_Free(search);
-}
-
-/*
- * ******************** Session Utilities *******************************
- */
-
-/* update the sessions state based in it's flags and wether or not it's
- * logged in */
-void
-sftk_update_state(SFTKSlot *slot,SFTKSession *session)
-{
- if (slot->isLoggedIn) {
- if (slot->ssoLoggedIn) {
- session->info.state = CKS_RW_SO_FUNCTIONS;
- } else if (session->info.flags & CKF_RW_SESSION) {
- session->info.state = CKS_RW_USER_FUNCTIONS;
- } else {
- session->info.state = CKS_RO_USER_FUNCTIONS;
- }
- } else {
- if (session->info.flags & CKF_RW_SESSION) {
- session->info.state = CKS_RW_PUBLIC_SESSION;
- } else {
- session->info.state = CKS_RO_PUBLIC_SESSION;
- }
- }
-}
-
-/* update the state of all the sessions on a slot */
-void
-sftk_update_all_states(SFTKSlot *slot)
-{
- unsigned int i;
- SFTKSession *session;
-
- for (i=0; i < slot->sessHashSize; i++) {
- PZLock *lock = SFTK_SESSION_LOCK(slot,i);
- PZ_Lock(lock);
- for (session = slot->head[i]; session; session = session->next) {
- sftk_update_state(slot,session);
- }
- PZ_Unlock(lock);
- }
-}
-
-/*
- * context are cipher and digest contexts that are associated with a session
- */
-void
-sftk_FreeContext(SFTKSessionContext *context)
-{
- if (context->cipherInfo) {
- (*context->destroy)(context->cipherInfo,PR_TRUE);
- }
- if (context->hashInfo) {
- (*context->hashdestroy)(context->hashInfo,PR_TRUE);
- }
- if (context->key) {
- sftk_FreeObject(context->key);
- context->key = NULL;
- }
- PORT_Free(context);
-}
-
-/*
- * create a new nession. NOTE: The session handle is not set, and the
- * session is not added to the slot's session queue.
- */
-SFTKSession *
-sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
- CK_FLAGS flags)
-{
- SFTKSession *session;
- SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);
-
- if (slot == NULL) return NULL;
-
- session = (SFTKSession*)PORT_Alloc(sizeof(SFTKSession));
- if (session == NULL) return NULL;
-
- session->next = session->prev = NULL;
- session->refCount = 1;
- session->enc_context = NULL;
- session->hash_context = NULL;
- session->sign_context = NULL;
- session->search = NULL;
- session->objectIDCount = 1;
- session->objectLock = PZ_NewLock(nssILockObject);
- if (session->objectLock == NULL) {
- PORT_Free(session);
- return NULL;
- }
- session->objects[0] = NULL;
-
- session->slot = slot;
- session->notify = notify;
- session->appData = pApplication;
- session->info.flags = flags;
- session->info.slotID = slotID;
- session->info.ulDeviceError = 0;
- sftk_update_state(slot,session);
- return session;
-}
-
-
-/* free all the data associated with a session. */
-static void
-sftk_DestroySession(SFTKSession *session)
-{
- SFTKObjectList *op,*next;
- PORT_Assert(session->refCount == 0);
-
- /* clean out the attributes */
- /* since no one is referencing us, it's safe to walk the chain
- * without a lock */
- for (op = session->objects[0]; op != NULL; op = next) {
- next = op->next;
- /* paranoia */
- op->next = op->prev = NULL;
- sftk_DeleteObject(session,op->parent);
- }
- PZ_DestroyLock(session->objectLock);
- if (session->enc_context) {
- sftk_FreeContext(session->enc_context);
- }
- if (session->hash_context) {
- sftk_FreeContext(session->hash_context);
- }
- if (session->sign_context) {
- sftk_FreeContext(session->sign_context);
- }
- if (session->search) {
- sftk_FreeSearch(session->search);
- }
- PORT_Free(session);
-}
-
-
-/*
- * look up a session structure from a session handle
- * generate a reference to it.
- */
-SFTKSession *
-sftk_SessionFromHandle(CK_SESSION_HANDLE handle)
-{
- SFTKSlot *slot = sftk_SlotFromSessionHandle(handle);
- SFTKSession *session;
- PZLock *lock;
-
- if (!slot) return NULL;
- lock = SFTK_SESSION_LOCK(slot,handle);
-
- PZ_Lock(lock);
- sftkqueue_find(session,handle,slot->head,slot->sessHashSize);
- if (session) session->refCount++;
- PZ_Unlock(lock);
-
- return (session);
-}
-
-/*
- * release a reference to a session handle
- */
-void
-sftk_FreeSession(SFTKSession *session)
-{
- PRBool destroy = PR_FALSE;
- SFTKSlot *slot = sftk_SlotFromSession(session);
- PZLock *lock = SFTK_SESSION_LOCK(slot,session->handle);
-
- PZ_Lock(lock);
- if (session->refCount == 1) destroy = PR_TRUE;
- session->refCount--;
- PZ_Unlock(lock);
-
- if (destroy) sftk_DestroySession(session);
-}
-
-void
-sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle)
-{
- if (search->handles == NULL) {
- return;
- }
- if (search->size >= search->array_size) {
- search->array_size += NSC_SEARCH_BLOCK_SIZE;
- search->handles = (CK_OBJECT_HANDLE *) PORT_Realloc(search->handles,
- sizeof(CK_OBJECT_HANDLE)* search->array_size);
- if (search->handles == NULL) {
- return;
- }
- }
- search->handles[search->size] = handle;
- search->size++;
-}
-
-static CK_RV
-handleToClass(SFTKSlot *slot, CK_OBJECT_HANDLE handle,
- CK_OBJECT_CLASS *objClass)
-{
- SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, handle);
- CK_ATTRIBUTE objClassTemplate;
- CK_RV crv;
-
- *objClass = CKO_DATA;
- objClassTemplate.type = CKA_CLASS;
- objClassTemplate.pValue = objClass;
- objClassTemplate.ulValueLen = sizeof(*objClass);
- crv = sftkdb_GetAttributeValue(dbHandle, handle, &objClassTemplate, 1);
- sftk_freeDB(dbHandle);
- return crv;
-}
-
-SFTKObject *
-sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle)
-{
- SFTKObject *object = NULL;
- SFTKTokenObject *tokObject = NULL;
- PRBool hasLocks = PR_FALSE;
- CK_RV crv;
-
- object = sftk_GetObjectFromList(&hasLocks, PR_FALSE, &tokenObjectList, 0,
- PR_FALSE);
- if (object == NULL) {
- return NULL;
- }
- tokObject = (SFTKTokenObject *) object;
-
- object->handle = handle;
- /* every object must have a class, if we can't get it, the object
- * doesn't exist */
- crv = handleToClass(slot, handle, &object->objclass);
- if (crv != CKR_OK) {
- goto loser;
- }
- object->slot = slot;
- object->objectInfo = NULL;
- object->infoFree = NULL;
- if (!hasLocks) {
- object->refLock = PZ_NewLock(nssILockRefLock);
- }
- if (object->refLock == NULL) {
- goto loser;
- }
- object->refCount = 1;
-
- return object;
-loser:
- if (object) {
- (void) sftk_DestroyObject(object);
- }
- return NULL;
-
-}
-
-SFTKTokenObject *
-sftk_convertSessionToToken(SFTKObject *obj)
-{
- SECItem *key;
- SFTKSessionObject *so = (SFTKSessionObject *)obj;
- SFTKTokenObject *to = sftk_narrowToTokenObject(obj);
- SECStatus rv;
-
- sftk_DestroySessionObjectData(so);
- PZ_DestroyLock(so->attributeLock);
- if (to == NULL) {
- return NULL;
- }
- sftk_tokenKeyLock(so->obj.slot);
- key = sftk_lookupTokenKeyByHandle(so->obj.slot,so->obj.handle);
- if (key == NULL) {
- sftk_tokenKeyUnlock(so->obj.slot);
- return NULL;
- }
- rv = SECITEM_CopyItem(NULL,&to->dbKey,key);
- sftk_tokenKeyUnlock(so->obj.slot);
- if (rv == SECFailure) {
- return NULL;
- }
-
- return to;
-}
-
-SFTKSessionObject *
-sftk_narrowToSessionObject(SFTKObject *obj)
-{
- return !sftk_isToken(obj->handle) ? (SFTKSessionObject *)obj : NULL;
-}
-
-SFTKTokenObject *
-sftk_narrowToTokenObject(SFTKObject *obj)
-{
- return sftk_isToken(obj->handle) ? (SFTKTokenObject *)obj : NULL;
-}
-
diff --git a/security/nss/lib/softoken/rsawrapr.c b/security/nss/lib/softoken/rsawrapr.c
deleted file mode 100644
index fe4c8f86c..000000000
--- a/security/nss/lib/softoken/rsawrapr.c
+++ /dev/null
@@ -1,1449 +0,0 @@
-/*
- * PKCS#1 encoding and decoding functions.
- * This file is believed to contain no code licensed from other parties.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "blapi.h"
-#include "softoken.h"
-
-#include "lowkeyi.h"
-#include "secerr.h"
-
-#define RSA_BLOCK_MIN_PAD_LEN 8
-#define RSA_BLOCK_FIRST_OCTET 0x00
-#define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00
-#define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
-#define RSA_BLOCK_AFTER_PAD_OCTET 0x00
-
-/* Needed for RSA-PSS functions */
-static const unsigned char eightZeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-/* Constant time comparison of a single byte.
- * Returns 1 iff a == b, otherwise returns 0.
- * Note: For ranges of bytes, use constantTimeCompare.
- */
-static unsigned char constantTimeEQ8(unsigned char a, unsigned char b) {
- unsigned char c = ~(a - b | b - a);
- c >>= 7;
- return c;
-}
-
-/* Constant time comparison of a range of bytes.
- * Returns 1 iff len bytes of a are identical to len bytes of b, otherwise
- * returns 0.
- */
-static unsigned char constantTimeCompare(const unsigned char *a,
- const unsigned char *b,
- unsigned int len) {
- unsigned char tmp = 0;
- unsigned int i;
- for (i = 0; i < len; ++i, ++a, ++b)
- tmp |= *a ^ *b;
- return constantTimeEQ8(0x00, tmp);
-}
-
-/* Constant time conditional.
- * Returns a if c is 1, or b if c is 0. The result is undefined if c is
- * not 0 or 1.
- */
-static unsigned int constantTimeCondition(unsigned int c,
- unsigned int a,
- unsigned int b)
-{
- return (~(c - 1) & a) | ((c - 1) & b);
-}
-
-/*
- * Format one block of data for public/private key encryption using
- * the rules defined in PKCS #1.
- */
-static unsigned char *
-rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
- SECItem *data)
-{
- unsigned char *block;
- unsigned char *bp;
- int padLen;
- int i, j;
- SECStatus rv;
-
- block = (unsigned char *) PORT_Alloc(modulusLen);
- if (block == NULL)
- return NULL;
-
- bp = block;
-
- /*
- * All RSA blocks start with two octets:
- * 0x00 || BlockType
- */
- *bp++ = RSA_BLOCK_FIRST_OCTET;
- *bp++ = (unsigned char) blockType;
-
- switch (blockType) {
-
- /*
- * Blocks intended for private-key operation.
- */
- case RSA_BlockPrivate0: /* essentially unused */
- case RSA_BlockPrivate: /* preferred method */
- /*
- * 0x00 || BT || Pad || 0x00 || ActualData
- * 1 1 padLen 1 data->len
- * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
- */
- padLen = modulusLen - data->len - 3;
- PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
- if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
- PORT_Free (block);
- return NULL;
- }
- PORT_Memset (bp,
- blockType == RSA_BlockPrivate0
- ? RSA_BLOCK_PRIVATE0_PAD_OCTET
- : RSA_BLOCK_PRIVATE_PAD_OCTET,
- padLen);
- bp += padLen;
- *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
- PORT_Memcpy (bp, data->data, data->len);
- break;
-
- /*
- * Blocks intended for public-key operation.
- */
- case RSA_BlockPublic:
-
- /*
- * 0x00 || BT || Pad || 0x00 || ActualData
- * 1 1 padLen 1 data->len
- * Pad is all non-zero random bytes.
- *
- * Build the block left to right.
- * Fill the entire block from Pad to the end with random bytes.
- * Use the bytes after Pad as a supply of extra random bytes from
- * which to find replacements for the zero bytes in Pad.
- * If we need more than that, refill the bytes after Pad with
- * new random bytes as necessary.
- */
- padLen = modulusLen - (data->len + 3);
- PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
- if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
- PORT_Free (block);
- return NULL;
- }
- j = modulusLen - 2;
- rv = RNG_GenerateGlobalRandomBytes(bp, j);
- if (rv == SECSuccess) {
- for (i = 0; i < padLen; ) {
- unsigned char repl;
- /* Pad with non-zero random data. */
- if (bp[i] != RSA_BLOCK_AFTER_PAD_OCTET) {
- ++i;
- continue;
- }
- if (j <= padLen) {
- rv = RNG_GenerateGlobalRandomBytes(bp + padLen,
- modulusLen - (2 + padLen));
- if (rv != SECSuccess)
- break;
- j = modulusLen - 2;
- }
- do {
- repl = bp[--j];
- } while (repl == RSA_BLOCK_AFTER_PAD_OCTET && j > padLen);
- if (repl != RSA_BLOCK_AFTER_PAD_OCTET) {
- bp[i++] = repl;
- }
- }
- }
- if (rv != SECSuccess) {
- sftk_fatalError = PR_TRUE;
- PORT_Free (block);
- return NULL;
- }
- bp += padLen;
- *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
- PORT_Memcpy (bp, data->data, data->len);
- break;
-
- default:
- PORT_Assert (0);
- PORT_Free (block);
- return NULL;
- }
-
- return block;
-}
-
-static SECStatus
-rsa_FormatBlock(SECItem *result, unsigned modulusLen,
- RSA_BlockType blockType, SECItem *data)
-{
- /*
- * XXX For now assume that the data length fits in a single
- * XXX encryption block; the ASSERTs below force this.
- * XXX To fix it, each case will have to loop over chunks whose
- * XXX lengths satisfy the assertions, until all data is handled.
- * XXX (Unless RSA has more to say about how to handle data
- * XXX which does not fit in a single encryption block?)
- * XXX And I do not know what the result is supposed to be,
- * XXX so the interface to this function may need to change
- * XXX to allow for returning multiple blocks, if they are
- * XXX not wanted simply concatenated one after the other.
- */
-
- switch (blockType) {
- case RSA_BlockPrivate0:
- case RSA_BlockPrivate:
- case RSA_BlockPublic:
- /*
- * 0x00 || BT || Pad || 0x00 || ActualData
- *
- * The "3" below is the first octet + the second octet + the 0x00
- * octet that always comes just before the ActualData.
- */
- PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
-
- result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
- if (result->data == NULL) {
- result->len = 0;
- return SECFailure;
- }
- result->len = modulusLen;
-
- break;
-
- case RSA_BlockRaw:
- /*
- * Pad || ActualData
- * Pad is zeros. The application is responsible for recovering
- * the actual data.
- */
- if (data->len > modulusLen ) {
- return SECFailure;
- }
- result->data = (unsigned char*)PORT_ZAlloc(modulusLen);
- result->len = modulusLen;
- PORT_Memcpy(result->data+(modulusLen-data->len),data->data,data->len);
- break;
-
- default:
- PORT_Assert (0);
- result->data = NULL;
- result->len = 0;
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_Sign(NSSLOWKEYPrivateKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int maxOutputLen,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv = SECSuccess;
- unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
- SECItem formatted;
- SECItem unformatted;
-
- if (maxOutputLen < modulus_len)
- return SECFailure;
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- return SECFailure;
-
- unformatted.len = input_len;
- unformatted.data = input;
- formatted.data = NULL;
- rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
- &unformatted);
- if (rv != SECSuccess)
- goto done;
-
- rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
- if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- *output_len = modulus_len;
-
- goto done;
-
-done:
- if (formatted.data != NULL)
- PORT_ZFree(formatted.data, modulus_len);
- return rv;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_CheckSign(NSSLOWKEYPublicKey *key,
- unsigned char * sign,
- unsigned int sign_len,
- unsigned char * hash,
- unsigned int hash_len)
-{
- SECStatus rv;
- unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
- unsigned int i;
- unsigned char * buffer;
-
- modulus_len = nsslowkey_PublicModulusLen(key);
- if (sign_len != modulus_len)
- goto failure;
- /*
- * 0x00 || BT || Pad || 0x00 || ActualData
- *
- * The "3" below is the first octet + the second octet + the 0x00
- * octet that always comes just before the ActualData.
- */
- if (hash_len > modulus_len - (3 + RSA_BLOCK_MIN_PAD_LEN))
- goto failure;
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- goto failure;
-
- buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
- if (!buffer)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- * check the padding that was used
- */
- if (buffer[0] != 0 || buffer[1] != 1)
- goto loser;
- for (i = 2; i < modulus_len - hash_len - 1; i++) {
- if (buffer[i] != 0xff)
- goto loser;
- }
- if (buffer[i] != 0)
- goto loser;
-
- /*
- * make sure we get the same results
- */
- if (PORT_Memcmp(buffer + modulus_len - hash_len, hash, hash_len) != 0)
- goto loser;
-
- PORT_Free(buffer);
- return SECSuccess;
-
-loser:
- PORT_Free(buffer);
-failure:
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_CheckSignRecover(NSSLOWKEYPublicKey *key,
- unsigned char * data,
- unsigned int * data_len,
- unsigned int max_output_len,
- unsigned char * sign,
- unsigned int sign_len)
-{
- SECStatus rv;
- unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
- unsigned int i;
- unsigned char * buffer;
-
- if (sign_len != modulus_len)
- goto failure;
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- goto failure;
-
- buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
- if (!buffer)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
- if (rv != SECSuccess)
- goto loser;
- *data_len = 0;
-
- /*
- * check the padding that was used
- */
- if (buffer[0] != 0 || buffer[1] != 1)
- goto loser;
- for (i = 2; i < modulus_len; i++) {
- if (buffer[i] == 0) {
- *data_len = modulus_len - i - 1;
- break;
- }
- if (buffer[i] != 0xff)
- goto loser;
- }
- if (*data_len == 0)
- goto loser;
- if (*data_len > max_output_len)
- goto loser;
-
- /*
- * make sure we get the same results
- */
- PORT_Memcpy(data,buffer + modulus_len - *data_len, *data_len);
-
- PORT_Free(buffer);
- return SECSuccess;
-
-loser:
- PORT_Free(buffer);
-failure:
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_EncryptBlock(NSSLOWKEYPublicKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int max_output_len,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv;
- unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
- SECItem formatted;
- SECItem unformatted;
-
- formatted.data = NULL;
- if (max_output_len < modulus_len)
- goto failure;
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- goto failure;
-
- unformatted.len = input_len;
- unformatted.data = input;
- formatted.data = NULL;
- rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPublic,
- &unformatted);
- if (rv != SECSuccess)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
- if (rv != SECSuccess)
- goto failure;
-
- PORT_ZFree(formatted.data, modulus_len);
- *output_len = modulus_len;
- return SECSuccess;
-
-failure:
- if (formatted.data != NULL)
- PORT_ZFree(formatted.data, modulus_len);
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_DecryptBlock(NSSLOWKEYPrivateKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int max_output_len,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv;
- unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
- unsigned int i;
- unsigned char * buffer;
-
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- goto failure;
- if (input_len != modulus_len)
- goto failure;
-
- buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
- if (!buffer)
- goto failure;
-
- rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- goto loser;
- }
-
- if (buffer[0] != 0 || buffer[1] != 2)
- goto loser;
- *output_len = 0;
- for (i = 2; i < modulus_len; i++) {
- if (buffer[i] == 0) {
- *output_len = modulus_len - i - 1;
- break;
- }
- }
- if (*output_len == 0)
- goto loser;
- if (*output_len > max_output_len)
- goto loser;
-
- PORT_Memcpy(output, buffer + modulus_len - *output_len, *output_len);
-
- PORT_Free(buffer);
- return SECSuccess;
-
-loser:
- PORT_Free(buffer);
-failure:
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-/*
- * added to make pkcs #11 happy
- * RAW is RSA_X_509
- */
-SECStatus
-RSA_SignRaw(NSSLOWKEYPrivateKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int maxOutputLen,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv = SECSuccess;
- unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
- SECItem formatted;
- SECItem unformatted;
-
- if (maxOutputLen < modulus_len)
- return SECFailure;
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- return SECFailure;
-
- unformatted.len = input_len;
- unformatted.data = input;
- formatted.data = NULL;
- rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
- if (rv != SECSuccess)
- goto done;
-
- rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data);
- if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- *output_len = modulus_len;
-
-done:
- if (formatted.data != NULL)
- PORT_ZFree(formatted.data, modulus_len);
- return rv;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_CheckSignRaw(NSSLOWKEYPublicKey *key,
- unsigned char * sign,
- unsigned int sign_len,
- unsigned char * hash,
- unsigned int hash_len)
-{
- SECStatus rv;
- unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
- unsigned char * buffer;
-
- if (sign_len != modulus_len)
- goto failure;
- if (hash_len > modulus_len)
- goto failure;
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- goto failure;
-
- buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
- if (!buffer)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- * make sure we get the same results
- */
- /* NOTE: should we verify the leading zeros? */
- if (PORT_Memcmp(buffer + (modulus_len-hash_len), hash, hash_len) != 0)
- goto loser;
-
- PORT_Free(buffer);
- return SECSuccess;
-
-loser:
- PORT_Free(buffer);
-failure:
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_CheckSignRecoverRaw(NSSLOWKEYPublicKey *key,
- unsigned char * data,
- unsigned int * data_len,
- unsigned int max_output_len,
- unsigned char * sign,
- unsigned int sign_len)
-{
- SECStatus rv;
- unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
-
- if (sign_len != modulus_len)
- goto failure;
- if (max_output_len < modulus_len)
- goto failure;
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, data, sign);
- if (rv != SECSuccess)
- goto failure;
-
- *data_len = modulus_len;
- return SECSuccess;
-
-failure:
- return SECFailure;
-}
-
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_EncryptRaw(NSSLOWKEYPublicKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int max_output_len,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv;
- unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
- SECItem formatted;
- SECItem unformatted;
-
- formatted.data = NULL;
- if (max_output_len < modulus_len)
- goto failure;
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- goto failure;
-
- unformatted.len = input_len;
- unformatted.data = input;
- formatted.data = NULL;
- rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
- if (rv != SECSuccess)
- goto failure;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
- if (rv != SECSuccess)
- goto failure;
-
- PORT_ZFree(formatted.data, modulus_len);
- *output_len = modulus_len;
- return SECSuccess;
-
-failure:
- if (formatted.data != NULL)
- PORT_ZFree(formatted.data, modulus_len);
- return SECFailure;
-}
-
-/* XXX Doesn't set error code */
-SECStatus
-RSA_DecryptRaw(NSSLOWKEYPrivateKey *key,
- unsigned char * output,
- unsigned int * output_len,
- unsigned int max_output_len,
- unsigned char * input,
- unsigned int input_len)
-{
- SECStatus rv;
- unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
-
- if (modulus_len <= 0)
- goto failure;
- if (modulus_len > max_output_len)
- goto failure;
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey)
- goto failure;
- if (input_len != modulus_len)
- goto failure;
-
- rv = RSA_PrivateKeyOp(&key->u.rsa, output, input);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- goto failure;
- }
-
- *output_len = modulus_len;
- return SECSuccess;
-
-failure:
- return SECFailure;
-}
-
-/*
- * Mask generation function MGF1 as defined in PKCS #1 v2.1 / RFC 3447.
- */
-static SECStatus
-MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
- const unsigned char *mgfSeed, unsigned int mgfSeedLen)
-{
- unsigned int digestLen;
- PRUint32 counter, rounds;
- unsigned char *tempHash, *temp;
- const SECHashObject *hash;
- void *hashContext;
- unsigned char C[4];
-
- hash = HASH_GetRawHashObject(hashAlg);
- if (hash == NULL)
- return SECFailure;
-
- hashContext = (*hash->create)();
- rounds = (maskLen + hash->length - 1) / hash->length;
- for (counter = 0; counter < rounds; counter++) {
- C[0] = (unsigned char)((counter >> 24) & 0xff);
- C[1] = (unsigned char)((counter >> 16) & 0xff);
- C[2] = (unsigned char)((counter >> 8) & 0xff);
- C[3] = (unsigned char)(counter & 0xff);
-
- /* This could be optimized when the clone functions in
- * rawhash.c are implemented. */
- (*hash->begin)(hashContext);
- (*hash->update)(hashContext, mgfSeed, mgfSeedLen);
- (*hash->update)(hashContext, C, sizeof C);
-
- tempHash = mask + counter * hash->length;
- if (counter != (rounds-1)) {
- (*hash->end)(hashContext, tempHash, &digestLen, hash->length);
- } else { /* we're in the last round and need to cut the hash */
- temp = PORT_Alloc(hash->length);
- (*hash->end)(hashContext, temp, &digestLen, hash->length);
- PORT_Memcpy(tempHash, temp, maskLen - counter * hash->length);
- PORT_Free(temp);
- }
- }
- (*hash->destroy)(hashContext, PR_TRUE);
-
- return SECSuccess;
-}
-
-/*
- * Decodes an EME-OAEP encoded block, validating the encoding in constant
- * time.
- * Described in RFC 3447, section 7.1.2.
- * input contains the encoded block, after decryption.
- * label is the optional value L that was associated with the message.
- * On success, the original message and message length will be stored in
- * output and outputLen.
- */
-static SECStatus
-eme_oaep_decode(unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen,
- HASH_HashType hashAlg, HASH_HashType maskHashAlg,
- const unsigned char *label, unsigned int labelLen)
-{
- const SECHashObject *hash;
- void *hashContext;
- SECStatus rv = SECFailure;
- unsigned char labelHash[HASH_LENGTH_MAX];
- unsigned int i, maskLen, paddingOffset;
- unsigned char *mask = NULL, *tmpOutput = NULL;
- unsigned char isGood, foundPaddingEnd;
-
- hash = HASH_GetRawHashObject(hashAlg);
-
- /* 1.c */
- if (inputLen < (hash->length * 2) + 2) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
-
- /* Step 3.a - Generate lHash */
- hashContext = (*hash->create)();
- if (hashContext == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- (*hash->begin)(hashContext);
- if (labelLen > 0)
- (*hash->update)(hashContext, label, labelLen);
- (*hash->end)(hashContext, labelHash, &i, sizeof(labelHash));
- (*hash->destroy)(hashContext, PR_TRUE);
-
- tmpOutput = (unsigned char*)PORT_Alloc(inputLen);
- if (tmpOutput == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto done;
- }
-
- maskLen = inputLen - hash->length - 1;
- mask = (unsigned char*)PORT_Alloc(maskLen);
- if (mask == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto done;
- }
-
- PORT_Memcpy(tmpOutput, input, inputLen);
-
- /* 3.c - Generate seedMask */
- MGF1(maskHashAlg, mask, hash->length, &tmpOutput[1 + hash->length],
- inputLen - hash->length - 1);
- /* 3.d - Unmask seed */
- for (i = 0; i < hash->length; ++i)
- tmpOutput[1 + i] ^= mask[i];
-
- /* 3.e - Generate dbMask */
- MGF1(maskHashAlg, mask, maskLen, &tmpOutput[1], hash->length);
- /* 3.f - Unmask DB */
- for (i = 0; i < maskLen; ++i)
- tmpOutput[1 + hash->length + i] ^= mask[i];
-
- /* 3.g - Compare Y, lHash, and PS in constant time
- * Warning: This code is timing dependent and must not disclose which of
- * these were invalid.
- */
- paddingOffset = 0;
- isGood = 1;
- foundPaddingEnd = 0;
-
- /* Compare Y */
- isGood &= constantTimeEQ8(0x00, tmpOutput[0]);
-
- /* Compare lHash and lHash' */
- isGood &= constantTimeCompare(&labelHash[0],
- &tmpOutput[1 + hash->length],
- hash->length);
-
- /* Compare that the padding is zero or more zero octets, followed by a
- * 0x01 octet */
- for (i = 1 + (hash->length * 2); i < inputLen; ++i) {
- unsigned char isZero = constantTimeEQ8(0x00, tmpOutput[i]);
- unsigned char isOne = constantTimeEQ8(0x01, tmpOutput[i]);
- /* non-constant time equivalent:
- * if (tmpOutput[i] == 0x01 && !foundPaddingEnd)
- * paddingOffset = i;
- */
- paddingOffset = constantTimeCondition(isOne & ~foundPaddingEnd, i,
- paddingOffset);
- /* non-constant time equivalent:
- * if (tmpOutput[i] == 0x01)
- * foundPaddingEnd = true;
- *
- * Note: This may yield false positives, as it will be set whenever
- * a 0x01 byte is encountered. If there was bad padding (eg:
- * 0x03 0x02 0x01), foundPaddingEnd will still be set to true, and
- * paddingOffset will still be set to 2.
- */
- foundPaddingEnd = constantTimeCondition(isOne, 1, foundPaddingEnd);
- /* non-constant time equivalent:
- * if (tmpOutput[i] != 0x00 && tmpOutput[i] != 0x01 &&
- * !foundPaddingEnd) {
- * isGood = false;
- * }
- *
- * Note: This may yield false positives, as a message (and padding)
- * that is entirely zeros will result in isGood still being true. Thus
- * it's necessary to check foundPaddingEnd is positive below.
- */
- isGood = constantTimeCondition(~foundPaddingEnd & ~isZero, 0, isGood);
- }
-
- /* While both isGood and foundPaddingEnd may have false positives, they
- * cannot BOTH have false positives. If both are not true, then an invalid
- * message was received. Note, this comparison must still be done in constant
- * time so as not to leak either condition.
- */
- if (!(isGood & foundPaddingEnd)) {
- PORT_SetError(SEC_ERROR_BAD_DATA);
- goto done;
- }
-
- /* End timing dependent code */
-
- ++paddingOffset; /* Skip the 0x01 following the end of PS */
-
- *outputLen = inputLen - paddingOffset;
- if (*outputLen > maxOutputLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- goto done;
- }
-
- if (*outputLen)
- PORT_Memcpy(output, &tmpOutput[paddingOffset], *outputLen);
- rv = SECSuccess;
-
-done:
- if (mask)
- PORT_ZFree(mask, maskLen);
- if (tmpOutput)
- PORT_ZFree(tmpOutput, inputLen);
- return rv;
-}
-
-/*
- * Generate an EME-OAEP encoded block for encryption
- * Described in RFC 3447, section 7.1.1
- * We use input instead of M for the message to be encrypted
- * label is the optional value L to be associated with the message.
- */
-static SECStatus
-eme_oaep_encode(unsigned char *em, unsigned int emLen,
- const unsigned char *input, unsigned int inputLen,
- HASH_HashType hashAlg, HASH_HashType maskHashAlg,
- const unsigned char *label, unsigned int labelLen)
-{
- const SECHashObject *hash;
- void *hashContext;
- SECStatus rv;
- unsigned char *mask;
- unsigned int reservedLen, dbMaskLen, i;
-
- hash = HASH_GetRawHashObject(hashAlg);
-
- /* Step 1.b */
- reservedLen = (2 * hash->length) + 2;
- if (emLen < reservedLen || inputLen > (emLen - reservedLen)) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
-
- /*
- * From RFC 3447, Section 7.1
- * +----------+---------+-------+
- * DB = | lHash | PS | M |
- * +----------+---------+-------+
- * |
- * +----------+ V
- * | seed |--> MGF ---> xor
- * +----------+ |
- * | |
- * +--+ V |
- * |00| xor <----- MGF <-----|
- * +--+ | |
- * | | |
- * V V V
- * +--+----------+----------------------------+
- * EM = |00|maskedSeed| maskedDB |
- * +--+----------+----------------------------+
- *
- * We use mask to hold the result of the MGF functions, and all other
- * values are generated in their final resting place.
- */
- *em = 0x00;
-
- /* Step 2.a - Generate lHash */
- hashContext = (*hash->create)();
- if (hashContext == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- (*hash->begin)(hashContext);
- if (labelLen > 0)
- (*hash->update)(hashContext, label, labelLen);
- (*hash->end)(hashContext, &em[1 + hash->length], &i, hash->length);
- (*hash->destroy)(hashContext, PR_TRUE);
-
- /* Step 2.b - Generate PS */
- if (emLen - reservedLen - inputLen > 0) {
- PORT_Memset(em + 1 + (hash->length * 2), 0x00,
- emLen - reservedLen - inputLen);
- }
-
- /* Step 2.c. - Generate DB
- * DB = lHash || PS || 0x01 || M
- * Note that PS and lHash have already been placed into em at their
- * appropriate offsets. This just copies M into place
- */
- em[emLen - inputLen - 1] = 0x01;
- if (inputLen)
- PORT_Memcpy(em + emLen - inputLen, input, inputLen);
-
- /* Step 2.d - Generate seed */
- rv = RNG_GenerateGlobalRandomBytes(em + 1, hash->length);
- if (rv != SECSuccess) {
- return rv;
- }
-
- /* Step 2.e - Generate dbMask*/
- dbMaskLen = emLen - hash->length - 1;
- mask = (unsigned char*)PORT_Alloc(dbMaskLen);
- if (mask == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- MGF1(maskHashAlg, mask, dbMaskLen, em + 1, hash->length);
- /* Step 2.f - Compute maskedDB*/
- for (i = 0; i < dbMaskLen; ++i)
- em[1 + hash->length + i] ^= mask[i];
-
- /* Step 2.g - Generate seedMask */
- MGF1(maskHashAlg, mask, hash->length, &em[1 + hash->length], dbMaskLen);
- /* Step 2.h - Compute maskedSeed */
- for (i = 0; i < hash->length; ++i)
- em[1 + i] ^= mask[i];
-
- PORT_ZFree(mask, dbMaskLen);
- return SECSuccess;
-}
-
-/*
- * Encode a RSA-PSS signature.
- * Described in RFC 3447, section 9.1.1.
- * We use mHash instead of M as input.
- * emBits from the RFC is just modBits - 1, see section 8.1.1.
- * We only support MGF1 as the MGF.
- *
- * NOTE: this code assumes modBits is a multiple of 8.
- */
-static SECStatus
-emsa_pss_encode(unsigned char *em, unsigned int emLen,
- const unsigned char *mHash, HASH_HashType hashAlg,
- HASH_HashType maskHashAlg, unsigned int sLen)
-{
- const SECHashObject *hash;
- void *hash_context;
- unsigned char *dbMask;
- unsigned int dbMaskLen, i;
- SECStatus rv;
-
- hash = HASH_GetRawHashObject(hashAlg);
- dbMaskLen = emLen - hash->length - 1;
-
- /* Step 3 */
- if (emLen < hash->length + sLen + 2) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
-
- /* Step 4 */
- rv = RNG_GenerateGlobalRandomBytes(&em[dbMaskLen - sLen], sLen);
- if (rv != SECSuccess) {
- return rv;
- }
-
- /* Step 5 + 6 */
- /* Compute H and store it at its final location &em[dbMaskLen]. */
- hash_context = (*hash->create)();
- if (hash_context == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- (*hash->begin)(hash_context);
- (*hash->update)(hash_context, eightZeros, 8);
- (*hash->update)(hash_context, mHash, hash->length);
- (*hash->update)(hash_context, &em[dbMaskLen - sLen], sLen);
- (*hash->end)(hash_context, &em[dbMaskLen], &i, hash->length);
- (*hash->destroy)(hash_context, PR_TRUE);
-
- /* Step 7 + 8 */
- PORT_Memset(em, 0, dbMaskLen - sLen - 1);
- em[dbMaskLen - sLen - 1] = 0x01;
-
- /* Step 9 */
- dbMask = (unsigned char *)PORT_Alloc(dbMaskLen);
- if (dbMask == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- MGF1(maskHashAlg, dbMask, dbMaskLen, &em[dbMaskLen], hash->length);
-
- /* Step 10 */
- for (i = 0; i < dbMaskLen; i++)
- em[i] ^= dbMask[i];
- PORT_Free(dbMask);
-
- /* Step 11 */
- em[0] &= 0x7f;
-
- /* Step 12 */
- em[emLen - 1] = 0xbc;
-
- return SECSuccess;
-}
-
-/*
- * Verify a RSA-PSS signature.
- * Described in RFC 3447, section 9.1.2.
- * We use mHash instead of M as input.
- * emBits from the RFC is just modBits - 1, see section 8.1.2.
- * We only support MGF1 as the MGF.
- *
- * NOTE: this code assumes modBits is a multiple of 8.
- */
-static SECStatus
-emsa_pss_verify(const unsigned char *mHash,
- const unsigned char *em, unsigned int emLen,
- HASH_HashType hashAlg, HASH_HashType maskHashAlg,
- unsigned int sLen)
-{
- const SECHashObject *hash;
- void *hash_context;
- unsigned char *db;
- unsigned char *H_; /* H' from the RFC */
- unsigned int i, dbMaskLen;
- SECStatus rv;
-
- hash = HASH_GetRawHashObject(hashAlg);
- dbMaskLen = emLen - hash->length - 1;
-
- /* Step 3 + 4 + 6 */
- if ((emLen < (hash->length + sLen + 2)) ||
- (em[emLen - 1] != 0xbc) ||
- ((em[0] & 0x80) != 0)) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
-
- /* Step 7 */
- db = (unsigned char *)PORT_Alloc(dbMaskLen);
- if (db == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- /* &em[dbMaskLen] points to H, used as mgfSeed */
- MGF1(maskHashAlg, db, dbMaskLen, &em[dbMaskLen], hash->length);
-
- /* Step 8 */
- for (i = 0; i < dbMaskLen; i++) {
- db[i] ^= em[i];
- }
-
- /* Step 9 */
- db[0] &= 0x7f;
-
- /* Step 10 */
- for (i = 0; i < (dbMaskLen - sLen - 1); i++) {
- if (db[i] != 0) {
- PORT_Free(db);
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
- }
- if (db[dbMaskLen - sLen - 1] != 0x01) {
- PORT_Free(db);
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
-
- /* Step 12 + 13 */
- H_ = (unsigned char *)PORT_Alloc(hash->length);
- if (H_ == NULL) {
- PORT_Free(db);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- hash_context = (*hash->create)();
- if (hash_context == NULL) {
- PORT_Free(db);
- PORT_Free(H_);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- (*hash->begin)(hash_context);
- (*hash->update)(hash_context, eightZeros, 8);
- (*hash->update)(hash_context, mHash, hash->length);
- (*hash->update)(hash_context, &db[dbMaskLen - sLen], sLen);
- (*hash->end)(hash_context, H_, &i, hash->length);
- (*hash->destroy)(hash_context, PR_TRUE);
-
- PORT_Free(db);
-
- /* Step 14 */
- if (PORT_Memcmp(H_, &em[dbMaskLen], hash->length) != 0) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- rv = SECFailure;
- } else {
- rv = SECSuccess;
- }
-
- PORT_Free(H_);
- return rv;
-}
-
-static HASH_HashType
-GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech)
-{
- switch (mech) {
- case CKM_SHA_1:
- case CKG_MGF1_SHA1:
- return HASH_AlgSHA1;
- case CKM_SHA224:
- case CKG_MGF1_SHA224:
- return HASH_AlgSHA224;
- case CKM_SHA256:
- case CKG_MGF1_SHA256:
- return HASH_AlgSHA256;
- case CKM_SHA384:
- case CKG_MGF1_SHA384:
- return HASH_AlgSHA384;
- case CKM_SHA512:
- case CKG_MGF1_SHA512:
- return HASH_AlgSHA512;
- default:
- return HASH_AlgNULL;
- }
-}
-
-/* MGF1 is the only supported MGF. */
-SECStatus
-RSA_CheckSignPSS(CK_RSA_PKCS_PSS_PARAMS *pss_params,
- NSSLOWKEYPublicKey *key,
- const unsigned char *sign, unsigned int sign_len,
- const unsigned char *hash, unsigned int hash_len)
-{
- HASH_HashType hashAlg;
- HASH_HashType maskHashAlg;
- SECStatus rv;
- unsigned int modulus_len = nsslowkey_PublicModulusLen(key);
- unsigned char *buffer;
-
- if (sign_len != modulus_len) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
-
- hashAlg = GetHashTypeFromMechanism(pss_params->hashAlg);
- maskHashAlg = GetHashTypeFromMechanism(pss_params->mgf);
- if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
-
- buffer = (unsigned char *)PORT_Alloc(modulus_len);
- if (!buffer) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
- if (rv != SECSuccess) {
- PORT_Free(buffer);
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- return SECFailure;
- }
-
- rv = emsa_pss_verify(hash, buffer, modulus_len, hashAlg,
- maskHashAlg, pss_params->sLen);
- PORT_Free(buffer);
-
- return rv;
-}
-
-/* MGF1 is the only supported MGF. */
-SECStatus
-RSA_SignPSS(CK_RSA_PKCS_PSS_PARAMS *pss_params, NSSLOWKEYPrivateKey *key,
- unsigned char *output, unsigned int *output_len,
- unsigned int max_output_len,
- const unsigned char *input, unsigned int input_len)
-{
- SECStatus rv = SECSuccess;
- unsigned int modulus_len = nsslowkey_PrivateModulusLen(key);
- unsigned char *pss_encoded = NULL;
- HASH_HashType hashAlg;
- HASH_HashType maskHashAlg;
-
- if (max_output_len < modulus_len) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return SECFailure;
- }
-
- hashAlg = GetHashTypeFromMechanism(pss_params->hashAlg);
- maskHashAlg = GetHashTypeFromMechanism(pss_params->mgf);
- if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
-
- pss_encoded = (unsigned char *)PORT_Alloc(modulus_len);
- if (pss_encoded == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- rv = emsa_pss_encode(pss_encoded, modulus_len, input, hashAlg,
- maskHashAlg, pss_params->sLen);
- if (rv != SECSuccess)
- goto done;
-
- rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, pss_encoded);
- if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- }
- *output_len = modulus_len;
-
-done:
- PORT_Free(pss_encoded);
- return rv;
-}
-
-/* MGF1 is the only supported MGF. */
-SECStatus
-RSA_EncryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
- NSSLOWKEYPublicKey *key,
- unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- SECStatus rv = SECFailure;
- unsigned int modulusLen = nsslowkey_PublicModulusLen(key);
- unsigned char *oaepEncoded = NULL;
- unsigned char *sourceData = NULL;
- unsigned int sourceDataLen = 0;
-
- HASH_HashType hashAlg;
- HASH_HashType maskHashAlg;
-
- if (maxOutputLen < modulusLen) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return SECFailure;
- }
-
- hashAlg = GetHashTypeFromMechanism(oaepParams->hashAlg);
- maskHashAlg = GetHashTypeFromMechanism(oaepParams->mgf);
- if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
-
- /* The PKCS#11 source parameter is the "source" of the label parameter.
- * The only defined source is explicitly specified, in which case, the
- * label is an optional byte string in pSourceData. If ulSourceDataLen is
- * zero, then pSourceData MUST be NULL - otherwise, it must be non-NULL.
- */
- if (oaepParams->source != CKZ_DATA_SPECIFIED) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
- sourceData = (unsigned char*)oaepParams->pSourceData;
- sourceDataLen = oaepParams->ulSourceDataLen;
- if ((sourceDataLen == 0 && sourceData != NULL) ||
- (sourceDataLen > 0 && sourceData == NULL)) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
-
- oaepEncoded = (unsigned char *)PORT_Alloc(modulusLen);
- if (oaepEncoded == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
- rv = eme_oaep_encode(oaepEncoded, modulusLen, input, inputLen,
- hashAlg, maskHashAlg, sourceData, sourceDataLen);
- if (rv != SECSuccess)
- goto done;
-
- rv = RSA_PublicKeyOp(&key->u.rsa, output, oaepEncoded);
- if (rv != SECSuccess)
- goto done;
- *outputLen = modulusLen;
-
-done:
- PORT_Free(oaepEncoded);
- return rv;
-}
-
-/* MGF1 is the only supported MGF. */
-SECStatus
-RSA_DecryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
- NSSLOWKEYPrivateKey *key,
- unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen)
-{
- SECStatus rv = SECFailure;
- unsigned int modulusLen = nsslowkey_PrivateModulusLen(key);
- unsigned char *oaepEncoded = NULL;
- unsigned char *sourceData = NULL;
- unsigned int sourceDataLen = 0;
-
- HASH_HashType hashAlg = GetHashTypeFromMechanism(oaepParams->hashAlg);
- HASH_HashType maskHashAlg = GetHashTypeFromMechanism(oaepParams->mgf);
-
- if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
-
- if (inputLen != modulusLen) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return SECFailure;
- }
- PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
- if (key->keyType != NSSLOWKEYRSAKey) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- return SECFailure;
- }
-
- /* The PKCS#11 source parameter is the "source" of the label parameter.
- * The only defined source is explicitly specified, in which case, the
- * label is an optional byte string in pSourceData. If ulSourceDataLen is
- * zero, then pSourceData MUST be NULL - otherwise, it must be non-NULL.
- */
- if (oaepParams->source != CKZ_DATA_SPECIFIED) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
- sourceData = (unsigned char*)oaepParams->pSourceData;
- sourceDataLen = oaepParams->ulSourceDataLen;
- if ((sourceDataLen == 0 && sourceData != NULL) ||
- (sourceDataLen > 0 && sourceData == NULL)) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
-
- oaepEncoded = (unsigned char *)PORT_Alloc(modulusLen);
- if (oaepEncoded == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, oaepEncoded, input);
- if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
- sftk_fatalError = PR_TRUE;
- goto done;
- }
-
- rv = eme_oaep_decode(output, outputLen, maxOutputLen, oaepEncoded,
- modulusLen, hashAlg, maskHashAlg, sourceData,
- sourceDataLen);
-
-done:
- if (oaepEncoded)
- PORT_ZFree(oaepEncoded, modulusLen);
- return rv;
-}
diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c
deleted file mode 100644
index e93c662be..000000000
--- a/security/nss/lib/softoken/sdb.c
+++ /dev/null
@@ -1,2079 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file implements PKCS 11 on top of our existing security modules
- *
- * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
- * This implementation has two slots:
- * slot 1 is our generic crypto support. It does not require login.
- * It supports Public Key ops, and all they bulk ciphers and hashes.
- * It can also support Private Key ops for imported Private keys. It does
- * not have any token storage.
- * slot 2 is our private key support. It requires a login before use. It
- * can store Private Keys and Certs as token objects. Currently only private
- * keys and their associated Certificates are saved on the token.
- *
- * In this implementation, session objects are only visible to the session
- * that created or generated them.
- */
-
-#include "sdb.h"
-#include "pkcs11t.h"
-#include "seccomon.h"
-#include <sqlite3.h>
-#include "prthread.h"
-#include "prio.h"
-#include <stdio.h>
-#include "secport.h"
-#include "prmon.h"
-#include "prenv.h"
-#include "prprf.h"
-#include "prsystem.h" /* for PR_GetDirectorySeparator() */
-#include <sys/stat.h>
-#if defined(_WIN32)
-#include <io.h>
-#include <windows.h>
-#elif defined(XP_UNIX)
-#include <unistd.h>
-#endif
-
-#ifdef SQLITE_UNSAFE_THREADS
-#include "prlock.h"
-/*
- * SQLite can be compiled to be thread safe or not.
- * turn on SQLITE_UNSAFE_THREADS if the OS does not support
- * a thread safe version of sqlite.
- */
-static PRLock *sqlite_lock = NULL;
-
-#define LOCK_SQLITE() PR_Lock(sqlite_lock);
-#define UNLOCK_SQLITE() PR_Unlock(sqlite_lock);
-#else
-#define LOCK_SQLITE()
-#define UNLOCK_SQLITE()
-#endif
-
-typedef enum {
- SDB_CERT = 1,
- SDB_KEY = 2
-} sdbDataType;
-
-/*
- * defines controlling how long we wait to acquire locks.
- *
- * SDB_SQLITE_BUSY_TIMEOUT specifies how long (in milliseconds)
- * sqlite will wait on lock. If that timeout expires, sqlite will
- * return SQLITE_BUSY.
- * SDB_BUSY_RETRY_TIME specifies how many seconds the sdb_ code waits
- * after receiving a busy before retrying.
- * SDB_MAX_BUSY_RETRIES specifies how many times the sdb_ will retry on
- * a busy condition.
- *
- * SDB_SQLITE_BUSY_TIMEOUT affects all opertions, both manual
- * (prepare/step/reset/finalize) and automatic (sqlite3_exec()).
- * SDB_BUSY_RETRY_TIME and SDB_MAX_BUSY_RETRIES only affect manual operations
- *
- * total wait time for automatic operations:
- * 1 second (SDB_SQLITE_BUSY_TIMEOUT/1000).
- * total wait time for manual operations:
- * (1 second + 5 seconds) * 10 = 60 seconds.
- * (SDB_SQLITE_BUSY_TIMEOUT/1000 + SDB_BUSY_RETRY_TIME)*SDB_MAX_BUSY_RETRIES
- */
-#define SDB_SQLITE_BUSY_TIMEOUT 1000 /* milliseconds */
-#define SDB_BUSY_RETRY_TIME 5 /* seconds */
-#define SDB_MAX_BUSY_RETRIES 10
-
-/*
- * Note on use of sqlReadDB: Only one thread at a time may have an actual
- * operation going on given sqlite3 * database. An operation is defined as
- * the time from a sqlite3_prepare() until the sqlite3_finalize().
- * Multiple sqlite3 * databases can be open and have simultaneous operations
- * going. We use the sqlXactDB for all write operations. This database
- * is only opened when we first create a transaction and closed when the
- * transaction is complete. sqlReadDB is open when we first opened the database
- * and is used for all read operation. It's use is protected by a monitor. This
- * is because an operation can span the use of FindObjectsInit() through the
- * call to FindObjectsFinal(). In the intermediate time it is possible to call
- * other operations like NSC_GetAttributeValue */
-
-struct SDBPrivateStr {
- char *sqlDBName; /* invariant, path to this database */
- sqlite3 *sqlXactDB; /* access protected by dbMon, use protected
- * by the transaction. Current transaction db*/
- PRThread *sqlXactThread; /* protected by dbMon,
- * current transaction thread */
- sqlite3 *sqlReadDB; /* use protected by dbMon, value invariant */
- PRIntervalTime lastUpdateTime; /* last time the cache was updated */
- PRIntervalTime updateInterval; /* how long the cache can go before it
- * must be updated again */
- sdbDataType type; /* invariant, database type */
- char *table; /* invariant, SQL table which contains the db */
- char *cacheTable; /* invariant, SQL table cache of db */
- PRMonitor *dbMon; /* invariant, monitor to protect
- * sqlXact* fields, and use of the sqlReadDB */
-};
-
-typedef struct SDBPrivateStr SDBPrivate;
-
-/*
- * known attributes
- */
-static const CK_ATTRIBUTE_TYPE known_attributes[] = {
- CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION,
- CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER,
- CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED,
- CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL,
- CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
- CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE,
- CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER,
- CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE,
- CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
- CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT,
- CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS,
- CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE,
- CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE,
- CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS,
- CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
- CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_TEMPLATE,
- CKA_UNWRAP_TEMPLATE, CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT,
- CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y, CKA_RESOLUTION, CKA_CHAR_ROWS,
- CKA_CHAR_COLUMNS, CKA_COLOR, CKA_BITS_PER_PIXEL, CKA_CHAR_SETS,
- CKA_ENCODING_METHODS, CKA_MIME_TYPES, CKA_MECHANISM_TYPE,
- CKA_REQUIRED_CMS_ATTRIBUTES, CKA_DEFAULT_CMS_ATTRIBUTES,
- CKA_SUPPORTED_CMS_ATTRIBUTES, CKA_NETSCAPE_URL, CKA_NETSCAPE_EMAIL,
- CKA_NETSCAPE_SMIME_INFO, CKA_NETSCAPE_SMIME_TIMESTAMP,
- CKA_NETSCAPE_PKCS8_SALT, CKA_NETSCAPE_PASSWORD_CHECK, CKA_NETSCAPE_EXPIRES,
- CKA_NETSCAPE_KRL, CKA_NETSCAPE_PQG_COUNTER, CKA_NETSCAPE_PQG_SEED,
- CKA_NETSCAPE_PQG_H, CKA_NETSCAPE_PQG_SEED_BITS, CKA_NETSCAPE_MODULE_SPEC,
- CKA_TRUST_DIGITAL_SIGNATURE, CKA_TRUST_NON_REPUDIATION,
- CKA_TRUST_KEY_ENCIPHERMENT, CKA_TRUST_DATA_ENCIPHERMENT,
- CKA_TRUST_KEY_AGREEMENT, CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN,
- CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING,
- CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM,
- CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING,
- CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
- CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS
-};
-
-static int known_attributes_size= sizeof(known_attributes)/
- sizeof(known_attributes[0]);
-
-/* Magic for an explicit NULL. NOTE: ideally this should be
- * out of band data. Since it's not completely out of band, pick
- * a value that has no meaning to any existing PKCS #11 attributes.
- * This value is 1) not a valid string (imbedded '\0'). 2) not a U_LONG
- * or a normal key (too short). 3) not a bool (too long). 4) not an RSA
- * public exponent (too many bits).
- */
-const unsigned char SQLITE_EXPLICIT_NULL[] = { 0xa5, 0x0, 0x5a };
-#define SQLITE_EXPLICIT_NULL_LEN 3
-
-/*
- * determine when we've completed our tasks
- */
-static int
-sdb_done(int err, int *count)
-{
- /* allow as many rows as the database wants to give */
- if (err == SQLITE_ROW) {
- *count = 0;
- return 0;
- }
- if (err != SQLITE_BUSY) {
- return 1;
- }
- /* err == SQLITE_BUSY, Dont' retry forever in this case */
- if (++(*count) >= SDB_MAX_BUSY_RETRIES) {
- return 1;
- }
- return 0;
-}
-
-/*
- * find out where sqlite stores the temp tables. We do this by replicating
- * the logic from sqlite.
- */
-#if defined(_WIN32)
-static char *
-sdb_getFallbackTempDir(void)
-{
- /* sqlite uses sqlite3_temp_directory if it is not NULL. We don't have
- * access to sqlite3_temp_directory because it is not exported from
- * sqlite3.dll. Assume sqlite3_win32_set_directory isn't called and
- * sqlite3_temp_directory is NULL.
- */
- char path[MAX_PATH];
- DWORD rv;
- size_t len;
-
- rv = GetTempPathA(MAX_PATH, path);
- if (rv > MAX_PATH || rv == 0)
- return NULL;
- len = strlen(path);
- if (len == 0)
- return NULL;
- /* The returned string ends with a backslash, for example, "C:\TEMP\". */
- if (path[len - 1] == '\\')
- path[len - 1] = '\0';
- return PORT_Strdup(path);
-}
-#elif defined(XP_UNIX)
-static char *
-sdb_getFallbackTempDir(void)
-{
- const char *azDirs[] = {
- NULL,
- NULL,
- "/var/tmp",
- "/usr/tmp",
- "/tmp",
- NULL /* List terminator */
- };
- unsigned int i;
- struct stat buf;
- const char *zDir = NULL;
-
- azDirs[0] = sqlite3_temp_directory;
- azDirs[1] = getenv("TMPDIR");
-
- for (i = 0; i < PR_ARRAY_SIZE(azDirs); i++) {
- zDir = azDirs[i];
- if (zDir == NULL) continue;
- if (stat(zDir, &buf)) continue;
- if (!S_ISDIR(buf.st_mode)) continue;
- if (access(zDir, 07)) continue;
- break;
- }
-
- if (zDir == NULL)
- return NULL;
- return PORT_Strdup(zDir);
-}
-#else
-#error "sdb_getFallbackTempDir not implemented"
-#endif
-
-#ifndef SQLITE_FCNTL_TEMPFILENAME
-/* SQLITE_FCNTL_TEMPFILENAME was added in SQLite 3.7.15 */
-#define SQLITE_FCNTL_TEMPFILENAME 16
-#endif
-
-static char *
-sdb_getTempDir(sqlite3 *sqlDB)
-{
- int sqlrv;
- char *result = NULL;
- char *tempName = NULL;
- char *foundSeparator = NULL;
-
- /* Obtain temporary filename in sqlite's directory for temporary tables */
- sqlrv = sqlite3_file_control(sqlDB, 0, SQLITE_FCNTL_TEMPFILENAME,
- (void*)&tempName);
- if (sqlrv == SQLITE_NOTFOUND) {
- /* SQLITE_FCNTL_TEMPFILENAME not implemented because we are using
- * an older SQLite. */
- return sdb_getFallbackTempDir();
- }
- if (sqlrv != SQLITE_OK) {
- return NULL;
- }
-
- /* We'll extract the temporary directory from tempName */
- foundSeparator = PORT_Strrchr(tempName, PR_GetDirectorySeparator());
- if (foundSeparator) {
- /* We shorten the temp filename string to contain only
- * the directory name (including the trailing separator).
- * We know the byte after the foundSeparator position is
- * safe to use, in the shortest scenario it contains the
- * end-of-string byte.
- * By keeping the separator at the found position, it will
- * even work if tempDir consists of the separator, only.
- * (In this case the toplevel directory will be used for
- * access speed testing). */
- ++foundSeparator;
- *foundSeparator = 0;
-
- /* Now we copy the directory name for our caller */
- result = PORT_Strdup(tempName);
- }
-
- sqlite3_free(tempName);
- return result;
-}
-
-/*
- * Map SQL_LITE errors to PKCS #11 errors as best we can.
- */
-static CK_RV
-sdb_mapSQLError(sdbDataType type, int sqlerr)
-{
- switch (sqlerr) {
- /* good matches */
- case SQLITE_OK:
- case SQLITE_DONE:
- return CKR_OK;
- case SQLITE_NOMEM:
- return CKR_HOST_MEMORY;
- case SQLITE_READONLY:
- return CKR_TOKEN_WRITE_PROTECTED;
- /* close matches */
- case SQLITE_AUTH:
- case SQLITE_PERM:
- /*return CKR_USER_NOT_LOGGED_IN; */
- case SQLITE_CANTOPEN:
- case SQLITE_NOTFOUND:
- /* NSS distiguishes between failure to open the cert and the key db */
- return type == SDB_CERT ?
- CKR_NETSCAPE_CERTDB_FAILED : CKR_NETSCAPE_KEYDB_FAILED;
- case SQLITE_IOERR:
- return CKR_DEVICE_ERROR;
- default:
- break;
- }
- return CKR_GENERAL_ERROR;
-}
-
-
-/*
- * build up database name from a directory, prefix, name, version and flags.
- */
-static char *sdb_BuildFileName(const char * directory,
- const char *prefix, const char *type,
- int version)
-{
- char *dbname = NULL;
- /* build the full dbname */
- dbname = sqlite3_mprintf("%s%c%s%s%d.db", directory,
- (int)(unsigned char)PR_GetDirectorySeparator(),
- prefix, type, version);
- return dbname;
-}
-
-
-/*
- * find out how expensive the access system call is for non-existant files
- * in the given directory. Return the number of operations done in 33 ms.
- */
-static PRUint32
-sdb_measureAccess(const char *directory)
-{
- PRUint32 i;
- PRIntervalTime time;
- PRIntervalTime delta;
- PRIntervalTime duration = PR_MillisecondsToInterval(33);
- const char *doesntExistName = "_dOeSnotExist_.db";
- char *temp, *tempStartOfFilename;
- size_t maxTempLen, maxFileNameLen, directoryLength;
-
- /* no directory, just return one */
- if (directory == NULL) {
- return 1;
- }
-
- /* our calculation assumes time is a 4 bytes == 32 bit integer */
- PORT_Assert(sizeof(time) == 4);
-
- directoryLength = strlen(directory);
-
- maxTempLen = directoryLength + strlen(doesntExistName)
- + 1 /* potential additional separator char */
- + 11 /* max chars for 32 bit int plus potential sign */
- + 1; /* zero terminator */
-
- temp = PORT_Alloc(maxTempLen);
- if (!temp) {
- return 1;
- }
-
- /* We'll copy directory into temp just once, then ensure it ends
- * with the directory separator, then remember the position after
- * the separator, and calculate the number of remaining bytes. */
-
- strcpy(temp, directory);
- if (directory[directoryLength - 1] != PR_GetDirectorySeparator()) {
- temp[directoryLength++] = PR_GetDirectorySeparator();
- }
- tempStartOfFilename = temp + directoryLength;
- maxFileNameLen = maxTempLen - directoryLength;
-
- /* measure number of Access operations that can be done in 33 milliseconds
- * (1/30'th of a second), or 10000 operations, which ever comes first.
- */
- time = PR_IntervalNow();
- for (i=0; i < 10000u; i++) {
- PRIntervalTime next;
-
- /* We'll use the variable part first in the filename string, just in
- * case it's longer than assumed, so if anything gets cut off, it
- * will be cut off from the constant part.
- * This code assumes the directory name at the beginning of
- * temp remains unchanged during our loop. */
- PR_snprintf(tempStartOfFilename, maxFileNameLen,
- ".%lu%s", (PRUint32)(time+i), doesntExistName);
- PR_Access(temp,PR_ACCESS_EXISTS);
- next = PR_IntervalNow();
- delta = next - time;
- if (delta >= duration)
- break;
- }
-
- PORT_Free(temp);
-
- /* always return 1 or greater */
- return i ? i : 1u;
-}
-
-/*
- * some file sytems are very slow to run sqlite3 on, particularly if the
- * access count is pretty high. On these filesystems is faster to create
- * a temporary database on the local filesystem and access that. This
- * code uses a temporary table to create that cache. Temp tables are
- * automatically cleared when the database handle it was created on
- * Is freed.
- */
-static const char DROP_CACHE_CMD[] = "DROP TABLE %s";
-static const char CREATE_CACHE_CMD[] =
- "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s";
-static const char CREATE_ISSUER_INDEX_CMD[] =
- "CREATE INDEX issuer ON %s (a81)";
-static const char CREATE_SUBJECT_INDEX_CMD[] =
- "CREATE INDEX subject ON %s (a101)";
-static const char CREATE_LABEL_INDEX_CMD[] = "CREATE INDEX label ON %s (a3)";
-static const char CREATE_ID_INDEX_CMD[] = "CREATE INDEX ckaid ON %s (a102)";
-
-static CK_RV
-sdb_buildCache(sqlite3 *sqlDB, sdbDataType type,
- const char *cacheTable, const char *table)
-{
- char *newStr;
- int sqlerr = SQLITE_OK;
-
- newStr = sqlite3_mprintf(CREATE_CACHE_CMD, cacheTable, table);
- if (newStr == NULL) {
- return CKR_HOST_MEMORY;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- if (sqlerr != SQLITE_OK) {
- return sdb_mapSQLError(type, sqlerr);
- }
- /* failure to create the indexes is not an issue */
- newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, cacheTable);
- if (newStr == NULL) {
- return CKR_OK;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, cacheTable);
- if (newStr == NULL) {
- return CKR_OK;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, cacheTable);
- if (newStr == NULL) {
- return CKR_OK;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, cacheTable);
- if (newStr == NULL) {
- return CKR_OK;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- return CKR_OK;
-}
-
-/*
- * update the cache and the data records describing it.
- * The cache is updated by dropping the temp database and recreating it.
- */
-static CK_RV
-sdb_updateCache(SDBPrivate *sdb_p)
-{
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- char *newStr;
-
- /* drop the old table */
- newStr = sqlite3_mprintf(DROP_CACHE_CMD, sdb_p->cacheTable);
- if (newStr == NULL) {
- return CKR_HOST_MEMORY;
- }
- sqlerr = sqlite3_exec(sdb_p->sqlReadDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- if ((sqlerr != SQLITE_OK) && (sqlerr != SQLITE_ERROR )) {
- /* something went wrong with the drop, don't try to refresh...
- * NOTE: SQLITE_ERROR is returned if the table doesn't exist. In
- * that case, we just continue on and try to reload it */
- return sdb_mapSQLError(sdb_p->type, sqlerr);
- }
-
-
- /* set up the new table */
- error = sdb_buildCache(sdb_p->sqlReadDB,sdb_p->type,
- sdb_p->cacheTable,sdb_p->table );
- if (error == CKR_OK) {
- /* we have a new cache! */
- sdb_p->lastUpdateTime = PR_IntervalNow();
- }
- return error;
-}
-
-/*
- * The sharing of sqlite3 handles across threads is tricky. Older versions
- * couldn't at all, but newer ones can under strict conditions. Basically
- * no 2 threads can use the same handle while another thread has an open
- * stmt running. Once the sqlite3_stmt is finalized, another thread can then
- * use the database handle.
- *
- * We use monitors to protect against trying to use a database before
- * it's sqlite3_stmt is finalized. This is preferable to the opening and
- * closing the database each operation because there is significant overhead
- * in the open and close. Also continually opening and closing the database
- * defeats the cache code as the cache table is lost on close (thus
- * requiring us to have to reinitialize the cache every operation).
- *
- * An execption to the shared handle is transations. All writes happen
- * through a transaction. When we are in a transaction, we must use the
- * same database pointer for that entire transation. In this case we save
- * the transaction database and use it for all accesses on the transaction
- * thread. Other threads use the common database.
- *
- * There can only be once active transaction on the database at a time.
- *
- * sdb_openDBLocal() provides us with a valid database handle for whatever
- * state we are in (reading or in a transaction), and acquires any locks
- * appropriate to that state. It also decides when it's time to refresh
- * the cache before we start an operation. Any database handle returned
- * just eventually be closed with sdb_closeDBLocal().
- *
- * The table returned either points to the database's physical table, or
- * to the cached shadow. Tranactions always return the physical table
- * and read operations return either the physical table or the cache
- * depending on whether or not the cache exists.
- */
-static CK_RV
-sdb_openDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB, const char **table)
-{
- *sqlDB = NULL;
-
- PR_EnterMonitor(sdb_p->dbMon);
-
- if (table) {
- *table = sdb_p->table;
- }
-
- /* We're in a transaction, use the transaction DB */
- if ((sdb_p->sqlXactDB) && (sdb_p->sqlXactThread == PR_GetCurrentThread())) {
- *sqlDB =sdb_p->sqlXactDB;
- /* only one thread can get here, safe to unlock */
- PR_ExitMonitor(sdb_p->dbMon);
- return CKR_OK;
- }
-
- /*
- * if we are just reading from the table, we may have the table
- * cached in a temporary table (especially if it's on a shared FS).
- * In that case we want to see updates to the table, the the granularity
- * is on order of human scale, not computer scale.
- */
- if (table && sdb_p->cacheTable) {
- PRIntervalTime now = PR_IntervalNow();
- if ((now - sdb_p->lastUpdateTime) > sdb_p->updateInterval) {
- sdb_updateCache(sdb_p);
- }
- *table = sdb_p->cacheTable;
- }
-
- *sqlDB = sdb_p->sqlReadDB;
-
- /* leave holding the lock. only one thread can actually use a given
- * database connection at once */
-
- return CKR_OK;
-}
-
-/* closing the local database currenly means unlocking the monitor */
-static CK_RV
-sdb_closeDBLocal(SDBPrivate *sdb_p, sqlite3 *sqlDB)
-{
- if (sdb_p->sqlXactDB != sqlDB) {
- /* if we weren't in a transaction, we got a lock */
- PR_ExitMonitor(sdb_p->dbMon);
- }
- return CKR_OK;
-}
-
-
-/*
- * wrapper to sqlite3_open which also sets the busy_timeout
- */
-static int
-sdb_openDB(const char *name, sqlite3 **sqlDB, int flags)
-{
- int sqlerr;
- /*
- * in sqlite3 3.5.0, there is a new open call that allows us
- * to specify read only. Most new OS's are still on 3.3.x (including
- * NSS's internal version and the version shipped with Firefox).
- */
- *sqlDB = NULL;
- sqlerr = sqlite3_open(name, sqlDB);
- if (sqlerr != SQLITE_OK) {
- return sqlerr;
- }
-
- sqlerr = sqlite3_busy_timeout(*sqlDB, SDB_SQLITE_BUSY_TIMEOUT);
- if (sqlerr != SQLITE_OK) {
- sqlite3_close(*sqlDB);
- *sqlDB = NULL;
- return sqlerr;
- }
- return SQLITE_OK;
-}
-
-/* Sigh, if we created a new table since we opened the database,
- * the database handle will not see the new table, we need to close this
- * database and reopen it. Caller must be in a transaction or holding
- * the dbMon. sqlDB is changed on success. */
-static int
-sdb_reopenDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB) {
- sqlite3 *newDB;
- int sqlerr;
-
- /* open a new database */
- sqlerr = sdb_openDB(sdb_p->sqlDBName, &newDB, SDB_RDONLY);
- if (sqlerr != SQLITE_OK) {
- return sqlerr;
- }
-
- /* if we are in a transaction, we may not be holding the monitor.
- * grab it before we update the transaction database. This is
- * safe since are using monitors. */
- PR_EnterMonitor(sdb_p->dbMon);
- /* update our view of the database */
- if (sdb_p->sqlReadDB == *sqlDB) {
- sdb_p->sqlReadDB = newDB;
- } else if (sdb_p->sqlXactDB == *sqlDB) {
- sdb_p->sqlXactDB = newDB;
- }
- PR_ExitMonitor(sdb_p->dbMon);
-
- /* close the old one */
- sqlite3_close(*sqlDB);
-
- *sqlDB = newDB;
- return SQLITE_OK;
-}
-
-struct SDBFindStr {
- sqlite3 *sqlDB;
- sqlite3_stmt *findstmt;
-};
-
-
-static const char FIND_OBJECTS_CMD[] = "SELECT ALL * FROM %s WHERE %s;";
-static const char FIND_OBJECTS_ALL_CMD[] = "SELECT ALL * FROM %s;";
-CK_RV
-sdb_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *template, CK_ULONG count,
- SDBFind **find)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
- const char *table;
- char *newStr, *findStr = NULL;
- sqlite3_stmt *findstmt = NULL;
- char *join="";
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- int i;
-
- LOCK_SQLITE()
- *find = NULL;
- error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
- if (error != CKR_OK) {
- goto loser;
- }
-
- findStr = sqlite3_mprintf("");
- for (i=0; findStr && i < count; i++) {
- newStr = sqlite3_mprintf("%s%sa%x=$DATA%d", findStr, join,
- template[i].type, i);
- join=" AND ";
- sqlite3_free(findStr);
- findStr = newStr;
- }
-
- if (findStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- if (count == 0) {
- newStr = sqlite3_mprintf(FIND_OBJECTS_ALL_CMD, table);
- } else {
- newStr = sqlite3_mprintf(FIND_OBJECTS_CMD, table, findStr);
- }
- sqlite3_free(findStr);
- if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &findstmt, NULL);
- sqlite3_free(newStr);
- for (i=0; sqlerr == SQLITE_OK && i < count; i++) {
- const void *blobData = template[i].pValue;
- unsigned int blobSize = template[i].ulValueLen;
- if (blobSize == 0) {
- blobSize = SQLITE_EXPLICIT_NULL_LEN;
- blobData = SQLITE_EXPLICIT_NULL;
- }
- sqlerr = sqlite3_bind_blob(findstmt, i+1, blobData, blobSize,
- SQLITE_TRANSIENT);
- }
- if (sqlerr == SQLITE_OK) {
- *find = PORT_New(SDBFind);
- if (*find == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- (*find)->findstmt = findstmt;
- (*find)->sqlDB = sqlDB;
- UNLOCK_SQLITE()
- return CKR_OK;
- }
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
-
-loser:
- if (findstmt) {
- sqlite3_reset(findstmt);
- sqlite3_finalize(findstmt);
- }
- if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
- }
- UNLOCK_SQLITE()
- return error;
-}
-
-
-CK_RV
-sdb_FindObjects(SDB *sdb, SDBFind *sdbFind, CK_OBJECT_HANDLE *object,
- CK_ULONG arraySize, CK_ULONG *count)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3_stmt *stmt = sdbFind->findstmt;
- int sqlerr = SQLITE_OK;
- int retry = 0;
-
- *count = 0;
-
- if (arraySize == 0) {
- return CKR_OK;
- }
- LOCK_SQLITE()
-
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- if (sqlerr == SQLITE_ROW) {
- /* only care about the id */
- *object++= sqlite3_column_int(stmt, 0);
- arraySize--;
- (*count)++;
- }
- } while (!sdb_done(sqlerr,&retry) && (arraySize > 0));
-
- /* we only have some of the objects, there is probably more,
- * set the sqlerr to an OK value so we return CKR_OK */
- if (sqlerr == SQLITE_ROW && arraySize == 0) {
- sqlerr = SQLITE_DONE;
- }
- UNLOCK_SQLITE()
-
- return sdb_mapSQLError(sdb_p->type, sqlerr);
-}
-
-CK_RV
-sdb_FindObjectsFinal(SDB *sdb, SDBFind *sdbFind)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3_stmt *stmt = sdbFind->findstmt;
- sqlite3 *sqlDB = sdbFind->sqlDB;
- int sqlerr = SQLITE_OK;
-
- LOCK_SQLITE()
- if (stmt) {
- sqlite3_reset(stmt);
- sqlerr = sqlite3_finalize(stmt);
- }
- if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
- }
- PORT_Free(sdbFind);
-
- UNLOCK_SQLITE()
- return sdb_mapSQLError(sdb_p->type, sqlerr);
-}
-
-static const char GET_ATTRIBUTE_CMD[] = "SELECT ALL %s FROM %s WHERE id=$ID;";
-CK_RV
-sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
- CK_ATTRIBUTE *template, CK_ULONG count)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
- sqlite3_stmt *stmt = NULL;
- char *getStr = NULL;
- char *newStr = NULL;
- const char *table = NULL;
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- int found = 0;
- int retry = 0;
- int i;
-
-
- /* open a new db if necessary */
- error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
- if (error != CKR_OK) {
- goto loser;
- }
-
- for (i=0; i < count; i++) {
- getStr = sqlite3_mprintf("a%x", template[i].type);
-
- if (getStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- newStr = sqlite3_mprintf(GET_ATTRIBUTE_CMD, getStr, table);
- sqlite3_free(getStr);
- getStr = NULL;
- if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
- sqlite3_free(newStr);
- newStr = NULL;
- if (sqlerr == SQLITE_ERROR) {
- template[i].ulValueLen = -1;
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- continue;
- } else if (sqlerr != SQLITE_OK) { goto loser; }
-
- sqlerr = sqlite3_bind_int(stmt, 1, object_id);
- if (sqlerr != SQLITE_OK) { goto loser; }
-
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- if (sqlerr == SQLITE_ROW) {
- int blobSize;
- const char *blobData;
-
- blobSize = sqlite3_column_bytes(stmt, 0);
- blobData = sqlite3_column_blob(stmt, 0);
- if (blobData == NULL) {
- template[i].ulValueLen = -1;
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- break;
- }
- /* If the blob equals our explicit NULL value, then the
- * attribute is a NULL. */
- if ((blobSize == SQLITE_EXPLICIT_NULL_LEN) &&
- (PORT_Memcmp(blobData, SQLITE_EXPLICIT_NULL,
- SQLITE_EXPLICIT_NULL_LEN) == 0)) {
- blobSize = 0;
- }
- if (template[i].pValue) {
- if (template[i].ulValueLen < blobSize) {
- template[i].ulValueLen = -1;
- error = CKR_BUFFER_TOO_SMALL;
- break;
- }
- PORT_Memcpy(template[i].pValue, blobData, blobSize);
- }
- template[i].ulValueLen = blobSize;
- found = 1;
- }
- } while (!sdb_done(sqlerr,&retry));
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- stmt = NULL;
- }
-
-loser:
- /* fix up the error if necessary */
- if (error == CKR_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
- if (!found && error == CKR_OK) {
- error = CKR_OBJECT_HANDLE_INVALID;
- }
- }
-
- if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- }
-
- /* if we had to open a new database, free it now */
- if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
- }
- return error;
-}
-
-CK_RV
-sdb_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
- CK_ATTRIBUTE *template, CK_ULONG count)
-{
- CK_RV crv;
-
- if (count == 0) {
- return CKR_OK;
- }
-
- LOCK_SQLITE()
- crv = sdb_GetAttributeValueNoLock(sdb, object_id, template, count);
- UNLOCK_SQLITE()
- return crv;
-}
-
-static const char SET_ATTRIBUTE_CMD[] = "UPDATE %s SET %s WHERE id=$ID;";
-CK_RV
-sdb_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id,
- const CK_ATTRIBUTE *template, CK_ULONG count)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
- sqlite3_stmt *stmt = NULL;
- char *setStr = NULL;
- char *newStr = NULL;
- int sqlerr = SQLITE_OK;
- int retry = 0;
- CK_RV error = CKR_OK;
- int i;
-
- if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- if (count == 0) {
- return CKR_OK;
- }
-
- LOCK_SQLITE()
- setStr = sqlite3_mprintf("");
- for (i=0; setStr && i < count; i++) {
- if (i==0) {
- sqlite3_free(setStr);
- setStr = sqlite3_mprintf("a%x=$VALUE%d",
- template[i].type, i);
- continue;
- }
- newStr = sqlite3_mprintf("%s,a%x=$VALUE%d", setStr,
- template[i].type, i);
- sqlite3_free(setStr);
- setStr = newStr;
- }
- newStr = NULL;
-
- if (setStr == NULL) {
- return CKR_HOST_MEMORY;
- }
- newStr = sqlite3_mprintf(SET_ATTRIBUTE_CMD, sdb_p->table, setStr);
- sqlite3_free(setStr);
- if (newStr == NULL) {
- UNLOCK_SQLITE()
- return CKR_HOST_MEMORY;
- }
- error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
- if (error != CKR_OK) {
- goto loser;
- }
- sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
- if (sqlerr != SQLITE_OK) goto loser;
- for (i=0; i < count; i++) {
- if (template[i].ulValueLen != 0) {
- sqlerr = sqlite3_bind_blob(stmt, i+1, template[i].pValue,
- template[i].ulValueLen, SQLITE_STATIC);
- } else {
- sqlerr = sqlite3_bind_blob(stmt, i+2, SQLITE_EXPLICIT_NULL,
- SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC);
- }
- if (sqlerr != SQLITE_OK) goto loser;
- }
- sqlerr = sqlite3_bind_int(stmt, i+1, object_id);
- if (sqlerr != SQLITE_OK) goto loser;
-
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- } while (!sdb_done(sqlerr,&retry));
-
-loser:
- if (newStr) {
- sqlite3_free(newStr);
- }
- if (error == CKR_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
- }
-
- if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- }
-
- if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
- }
-
- UNLOCK_SQLITE()
- return error;
-}
-
-/*
- * check to see if a candidate object handle already exists.
- */
-static PRBool
-sdb_objectExists(SDB *sdb, CK_OBJECT_HANDLE candidate)
-{
- CK_RV crv;
- CK_ATTRIBUTE template = { CKA_LABEL, NULL, 0 };
-
- crv = sdb_GetAttributeValueNoLock(sdb,candidate,&template, 1);
- if (crv == CKR_OBJECT_HANDLE_INVALID) {
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-/*
- * if we're here, we are in a transaction, so it's safe
- * to examine the current state of the database
- */
-static CK_OBJECT_HANDLE
-sdb_getObjectId(SDB *sdb)
-{
- CK_OBJECT_HANDLE candidate;
- static CK_OBJECT_HANDLE next_obj = CK_INVALID_HANDLE;
- int count;
- /*
- * get an initial object handle to use
- */
- if (next_obj == CK_INVALID_HANDLE) {
- PRTime time;
- time = PR_Now();
-
- next_obj = (CK_OBJECT_HANDLE)(time & 0x3fffffffL);
- }
- candidate = next_obj++;
- /* detect that we've looped through all the handles... */
- for (count = 0; count < 0x40000000; count++, candidate = next_obj++) {
- /* mask off excess bits */
- candidate &= 0x3fffffff;
- /* if we hit zero, go to the next entry */
- if (candidate == CK_INVALID_HANDLE) {
- continue;
- }
- /* make sure we aren't already using */
- if (!sdb_objectExists(sdb, candidate)) {
- /* this one is free */
- return candidate;
- }
- }
-
- /* no handle is free, fail */
- return CK_INVALID_HANDLE;
-}
-
-static const char CREATE_CMD[] = "INSERT INTO %s (id%s) VALUES($ID%s);";
-CK_RV
-sdb_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *object_id,
- const CK_ATTRIBUTE *template, CK_ULONG count)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
- sqlite3_stmt *stmt = NULL;
- char *columnStr = NULL;
- char *valueStr = NULL;
- char *newStr = NULL;
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- CK_OBJECT_HANDLE this_object = CK_INVALID_HANDLE;
- int retry = 0;
- int i;
-
- if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- LOCK_SQLITE()
- if ((*object_id != CK_INVALID_HANDLE) &&
- !sdb_objectExists(sdb, *object_id)) {
- this_object = *object_id;
- } else {
- this_object = sdb_getObjectId(sdb);
- }
- if (this_object == CK_INVALID_HANDLE) {
- UNLOCK_SQLITE();
- return CKR_HOST_MEMORY;
- }
- columnStr = sqlite3_mprintf("");
- valueStr = sqlite3_mprintf("");
- *object_id = this_object;
- for (i=0; columnStr && valueStr && i < count; i++) {
- newStr = sqlite3_mprintf("%s,a%x", columnStr, template[i].type);
- sqlite3_free(columnStr);
- columnStr = newStr;
- newStr = sqlite3_mprintf("%s,$VALUE%d", valueStr, i);
- sqlite3_free(valueStr);
- valueStr = newStr;
- }
- newStr = NULL;
- if ((columnStr == NULL) || (valueStr == NULL)) {
- if (columnStr) {
- sqlite3_free(columnStr);
- }
- if (valueStr) {
- sqlite3_free(valueStr);
- }
- UNLOCK_SQLITE()
- return CKR_HOST_MEMORY;
- }
- newStr = sqlite3_mprintf(CREATE_CMD, sdb_p->table, columnStr, valueStr);
- sqlite3_free(columnStr);
- sqlite3_free(valueStr);
- error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
- if (error != CKR_OK) {
- goto loser;
- }
- sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
- if (sqlerr != SQLITE_OK) goto loser;
- sqlerr = sqlite3_bind_int(stmt, 1, *object_id);
- if (sqlerr != SQLITE_OK) goto loser;
- for (i=0; i < count; i++) {
- if (template[i].ulValueLen) {
- sqlerr = sqlite3_bind_blob(stmt, i+2, template[i].pValue,
- template[i].ulValueLen, SQLITE_STATIC);
- } else {
- sqlerr = sqlite3_bind_blob(stmt, i+2, SQLITE_EXPLICIT_NULL,
- SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC);
- }
- if (sqlerr != SQLITE_OK) goto loser;
- }
-
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- } while (!sdb_done(sqlerr,&retry));
-
-loser:
- if (newStr) {
- sqlite3_free(newStr);
- }
- if (error == CKR_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
- }
-
- if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- }
-
- if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
- }
- UNLOCK_SQLITE()
-
- return error;
-}
-
-static const char DESTROY_CMD[] = "DELETE FROM %s WHERE (id=$ID);";
-CK_RV
-sdb_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
- sqlite3_stmt *stmt = NULL;
- char *newStr = NULL;
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- int retry = 0;
-
- if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- LOCK_SQLITE()
- error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
- if (error != CKR_OK) {
- goto loser;
- }
- newStr = sqlite3_mprintf(DESTROY_CMD, sdb_p->table);
- if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- sqlerr =sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
- sqlite3_free(newStr);
- if (sqlerr != SQLITE_OK) goto loser;
- sqlerr =sqlite3_bind_int(stmt, 1, object_id);
- if (sqlerr != SQLITE_OK) goto loser;
-
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- } while (!sdb_done(sqlerr,&retry));
-
-loser:
- if (error == CKR_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
- }
-
- if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- }
-
- if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
- }
-
- UNLOCK_SQLITE()
- return error;
-}
-
-static const char BEGIN_CMD[] = "BEGIN IMMEDIATE TRANSACTION;";
-/*
- * start a transaction.
- *
- * We need to open a new database, then store that new database into
- * the private data structure. We open the database first, then use locks
- * to protect storing the data to prevent deadlocks.
- */
-CK_RV
-sdb_Begin(SDB *sdb)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
- sqlite3_stmt *stmt = NULL;
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- int retry = 0;
-
-
- if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
-
- LOCK_SQLITE()
-
- /* get a new version that we will use for the entire transaction */
- sqlerr = sdb_openDB(sdb_p->sqlDBName, &sqlDB, SDB_RDWR);
- if (sqlerr != SQLITE_OK) {
- goto loser;
- }
-
- sqlerr =sqlite3_prepare_v2(sqlDB, BEGIN_CMD, -1, &stmt, NULL);
-
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- } while (!sdb_done(sqlerr,&retry));
-
- if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- }
-
-loser:
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
-
- /* we are starting a new transaction,
- * and if we succeeded, then save this database for the rest of
- * our transaction */
- if (error == CKR_OK) {
- /* we hold a 'BEGIN TRANSACTION' and a sdb_p->lock. At this point
- * sdb_p->sqlXactDB MUST be null */
- PR_EnterMonitor(sdb_p->dbMon);
- PORT_Assert(sdb_p->sqlXactDB == NULL);
- sdb_p->sqlXactDB = sqlDB;
- sdb_p->sqlXactThread = PR_GetCurrentThread();
- PR_ExitMonitor(sdb_p->dbMon);
- } else {
- /* we failed to start our transaction,
- * free any databases we opened. */
- if (sqlDB) {
- sqlite3_close(sqlDB);
- }
- }
-
- UNLOCK_SQLITE()
- return error;
-}
-
-/*
- * Complete a transaction. Basically undo everything we did in begin.
- * There are 2 flavors Abort and Commit. Basically the only differerence between
- * these 2 are what the database will show. (no change in to former, change in
- * the latter).
- */
-static CK_RV
-sdb_complete(SDB *sdb, const char *cmd)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
- sqlite3_stmt *stmt = NULL;
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- int retry = 0;
-
-
- if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* We must have a transation database, or we shouldn't have arrived here */
- PR_EnterMonitor(sdb_p->dbMon);
- PORT_Assert(sdb_p->sqlXactDB);
- if (sdb_p->sqlXactDB == NULL) {
- PR_ExitMonitor(sdb_p->dbMon);
- return CKR_GENERAL_ERROR; /* shouldn't happen */
- }
- PORT_Assert( sdb_p->sqlXactThread == PR_GetCurrentThread());
- if ( sdb_p->sqlXactThread != PR_GetCurrentThread()) {
- PR_ExitMonitor(sdb_p->dbMon);
- return CKR_GENERAL_ERROR; /* shouldn't happen */
- }
- sqlDB = sdb_p->sqlXactDB;
- sdb_p->sqlXactDB = NULL; /* no one else can get to this DB,
- * safe to unlock */
- sdb_p->sqlXactThread = NULL;
- PR_ExitMonitor(sdb_p->dbMon);
-
- sqlerr =sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);
-
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- } while (!sdb_done(sqlerr,&retry));
-
- /* Pending BEGIN TRANSACTIONS Can move forward at this point. */
-
- if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- }
-
- /* we we have a cached DB image, update it as well */
- if (sdb_p->cacheTable) {
- PR_EnterMonitor(sdb_p->dbMon);
- sdb_updateCache(sdb_p);
- PR_ExitMonitor(sdb_p->dbMon);
- }
-
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
-
- /* We just finished a transaction.
- * Free the database, and remove it from the list */
- sqlite3_close(sqlDB);
-
- return error;
-}
-
-static const char COMMIT_CMD[] = "COMMIT TRANSACTION;";
-CK_RV
-sdb_Commit(SDB *sdb)
-{
- CK_RV crv;
- LOCK_SQLITE()
- crv = sdb_complete(sdb,COMMIT_CMD);
- UNLOCK_SQLITE()
- return crv;
-}
-
-static const char ROLLBACK_CMD[] = "ROLLBACK TRANSACTION;";
-CK_RV
-sdb_Abort(SDB *sdb)
-{
- CK_RV crv;
- LOCK_SQLITE()
- crv = sdb_complete(sdb,ROLLBACK_CMD);
- UNLOCK_SQLITE()
- return crv;
-}
-
-static int tableExists(sqlite3 *sqlDB, const char *tableName);
-
-static const char GET_PW_CMD[] = "SELECT ALL * FROM metaData WHERE id=$ID;";
-CK_RV
-sdb_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = sdb_p->sqlXactDB;
- sqlite3_stmt *stmt = NULL;
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- int found = 0;
- int retry = 0;
-
- LOCK_SQLITE()
- error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
- if (error != CKR_OK) {
- goto loser;
- }
-
- /* handle 'test' versions of the sqlite db */
- sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL);
- /* Sigh, if we created a new table since we opened the database,
- * the database handle will not see the new table, we need to close this
- * database and reopen it. This is safe because we are holding the lock
- * still. */
- if (sqlerr == SQLITE_SCHEMA) {
- sqlerr = sdb_reopenDBLocal(sdb_p, &sqlDB);
- if (sqlerr != SQLITE_OK) {
- goto loser;
- }
- sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL);
- }
- if (sqlerr != SQLITE_OK) goto loser;
- sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC);
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- if (sqlerr == SQLITE_ROW) {
- const char *blobData;
- unsigned int len = item1->len;
- item1->len = sqlite3_column_bytes(stmt, 1);
- if (item1->len > len) {
- error = CKR_BUFFER_TOO_SMALL;
- continue;
- }
- blobData = sqlite3_column_blob(stmt, 1);
- PORT_Memcpy(item1->data,blobData, item1->len);
- if (item2) {
- len = item2->len;
- item2->len = sqlite3_column_bytes(stmt, 2);
- if (item2->len > len) {
- error = CKR_BUFFER_TOO_SMALL;
- continue;
- }
- blobData = sqlite3_column_blob(stmt, 2);
- PORT_Memcpy(item2->data,blobData, item2->len);
- }
- found = 1;
- }
- } while (!sdb_done(sqlerr,&retry));
-
-loser:
- /* fix up the error if necessary */
- if (error == CKR_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
- if (!found && error == CKR_OK) {
- error = CKR_OBJECT_HANDLE_INVALID;
- }
- }
-
- if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- }
-
- if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
- }
- UNLOCK_SQLITE()
-
- return error;
-}
-
-static const char PW_CREATE_TABLE_CMD[] =
- "CREATE TABLE metaData (id PRIMARY KEY UNIQUE ON CONFLICT REPLACE, item1, item2);";
-static const char PW_CREATE_CMD[] =
- "INSERT INTO metaData (id,item1,item2) VALUES($ID,$ITEM1,$ITEM2);";
-static const char MD_CREATE_CMD[] =
- "INSERT INTO metaData (id,item1) VALUES($ID,$ITEM1);";
-CK_RV
-sdb_PutMetaData(SDB *sdb, const char *id, const SECItem *item1,
- const SECItem *item2)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = sdb_p->sqlXactDB;
- sqlite3_stmt *stmt = NULL;
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- int retry = 0;
- const char *cmd = PW_CREATE_CMD;
-
- if ((sdb->sdb_flags & SDB_RDONLY) != 0) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- LOCK_SQLITE()
- error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
- if (error != CKR_OK) {
- goto loser;
- }
-
- if (!tableExists(sqlDB, "metaData")) {
- sqlerr = sqlite3_exec(sqlDB, PW_CREATE_TABLE_CMD, NULL, 0, NULL);
- if (sqlerr != SQLITE_OK) goto loser;
- }
- if (item2 == NULL) {
- cmd = MD_CREATE_CMD;
- }
- sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL);
- if (sqlerr != SQLITE_OK) goto loser;
- sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC);
- if (sqlerr != SQLITE_OK) goto loser;
- sqlerr = sqlite3_bind_blob(stmt, 2, item1->data, item1->len, SQLITE_STATIC);
- if (sqlerr != SQLITE_OK) goto loser;
- if (item2) {
- sqlerr = sqlite3_bind_blob(stmt, 3, item2->data,
- item2->len, SQLITE_STATIC);
- if (sqlerr != SQLITE_OK) goto loser;
- }
-
- do {
- sqlerr = sqlite3_step(stmt);
- if (sqlerr == SQLITE_BUSY) {
- PR_Sleep(SDB_BUSY_RETRY_TIME);
- }
- } while (!sdb_done(sqlerr,&retry));
-
-loser:
- /* fix up the error if necessary */
- if (error == CKR_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
- }
-
- if (stmt) {
- sqlite3_reset(stmt);
- sqlite3_finalize(stmt);
- }
-
- if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
- }
- UNLOCK_SQLITE()
-
- return error;
-}
-
-static const char RESET_CMD[] = "DROP TABLE IF EXISTS %s;";
-CK_RV
-sdb_Reset(SDB *sdb)
-{
- SDBPrivate *sdb_p = sdb->private;
- sqlite3 *sqlDB = NULL;
- char *newStr;
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
-
- /* only Key databases can be reset */
- if (sdb_p->type != SDB_KEY) {
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- LOCK_SQLITE()
- error = sdb_openDBLocal(sdb_p, &sqlDB, NULL);
- if (error != CKR_OK) {
- goto loser;
- }
-
- /* delete the key table */
- newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table);
- if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
-
- if (sqlerr != SQLITE_OK) goto loser;
-
- /* delete the password entry table */
- sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;",
- NULL, 0, NULL);
-
-loser:
- /* fix up the error if necessary */
- if (error == CKR_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
- }
-
- if (sqlDB) {
- sdb_closeDBLocal(sdb_p, sqlDB) ;
- }
-
- UNLOCK_SQLITE()
- return error;
-}
-
-
-CK_RV
-sdb_Close(SDB *sdb)
-{
- SDBPrivate *sdb_p = sdb->private;
- int sqlerr = SQLITE_OK;
- sdbDataType type = sdb_p->type;
-
- sqlerr = sqlite3_close(sdb_p->sqlReadDB);
- PORT_Free(sdb_p->sqlDBName);
- if (sdb_p->cacheTable) {
- sqlite3_free(sdb_p->cacheTable);
- }
- if (sdb_p->dbMon) {
- PR_DestroyMonitor(sdb_p->dbMon);
- }
- free(sdb_p);
- free(sdb);
- return sdb_mapSQLError(type, sqlerr);
-}
-
-
-/*
- * functions to support open
- */
-
-static const char CHECK_TABLE_CMD[] = "SELECT ALL * FROM %s LIMIT 0;";
-/* return 1 if sqlDB contains table 'tableName */
-static int tableExists(sqlite3 *sqlDB, const char *tableName)
-{
- char * cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName);
- int sqlerr = SQLITE_OK;
-
- if (cmd == NULL) {
- return 0;
- }
-
- sqlerr = sqlite3_exec(sqlDB, cmd, NULL, 0, 0);
- sqlite3_free(cmd);
-
- return (sqlerr == SQLITE_OK) ? 1 : 0;
-}
-
-void sdb_SetForkState(PRBool forked)
-{
- /* XXXright now this is a no-op. The global fork state in the softokn3
- * shared library is already taken care of at the PKCS#11 level.
- * If and when we add fork state to the sqlite shared library and extern
- * interface, we will need to set it and reset it from here */
-}
-
-/*
- * initialize a single database
- */
-static const char INIT_CMD[] =
- "CREATE TABLE %s (id PRIMARY KEY UNIQUE ON CONFLICT ABORT%s)";
-static const char ALTER_CMD[] =
- "ALTER TABLE %s ADD COLUMN a%x";
-
-CK_RV
-sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
- int *newInit, int flags, PRUint32 accessOps, SDB **pSdb)
-{
- int i;
- char *initStr = NULL;
- char *newStr;
- int inTransaction = 0;
- SDB *sdb = NULL;
- SDBPrivate *sdb_p = NULL;
- sqlite3 *sqlDB = NULL;
- int sqlerr = SQLITE_OK;
- CK_RV error = CKR_OK;
- char *cacheTable = NULL;
- PRIntervalTime now = 0;
- char *env;
- PRBool enableCache = PR_FALSE;
- PRBool create;
-
- *pSdb = NULL;
- *inUpdate = 0;
-
- /* sqlite3 doesn't have a flag to specify that we want to
- * open the database read only. If the db doesn't exist,
- * sqlite3 will always create it.
- */
- LOCK_SQLITE();
- create = (PR_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS);
- if ((flags == SDB_RDONLY) && create) {
- error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
- goto loser;
- }
- sqlerr = sdb_openDB(dbname, &sqlDB, flags);
- if (sqlerr != SQLITE_OK) {
- error = sdb_mapSQLError(type, sqlerr);
- goto loser;
- }
- /* sql created the file, but it doesn't set appropriate modes for
- * a database */
- if (create) {
- /* NO NSPR call for this? :( */
- chmod (dbname, 0600);
- }
-
- if (flags != SDB_RDONLY) {
- sqlerr = sqlite3_exec(sqlDB, BEGIN_CMD, NULL, 0, NULL);
- if (sqlerr != SQLITE_OK) {
- error = sdb_mapSQLError(type, sqlerr);
- goto loser;
- }
- inTransaction = 1;
- }
- if (!tableExists(sqlDB,table)) {
- *newInit = 1;
- if (flags != SDB_CREATE) {
- error = sdb_mapSQLError(type, SQLITE_CANTOPEN);
- goto loser;
- }
- initStr = sqlite3_mprintf("");
- for (i=0; initStr && i < known_attributes_size; i++) {
- newStr = sqlite3_mprintf("%s, a%x",initStr, known_attributes[i]);
- sqlite3_free(initStr);
- initStr = newStr;
- }
- if (initStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- newStr = sqlite3_mprintf(INIT_CMD, table, initStr);
- sqlite3_free(initStr);
- if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- if (sqlerr != SQLITE_OK) {
- error = sdb_mapSQLError(type, sqlerr);
- goto loser;
- }
-
- newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, table);
- if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- if (sqlerr != SQLITE_OK) {
- error = sdb_mapSQLError(type, sqlerr);
- goto loser;
- }
-
- newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, table);
- if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- if (sqlerr != SQLITE_OK) {
- error = sdb_mapSQLError(type, sqlerr);
- goto loser;
- }
-
- newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, table);
- if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- if (sqlerr != SQLITE_OK) {
- error = sdb_mapSQLError(type, sqlerr);
- goto loser;
- }
-
- newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, table);
- if (newStr == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL);
- sqlite3_free(newStr);
- if (sqlerr != SQLITE_OK) {
- error = sdb_mapSQLError(type, sqlerr);
- goto loser;
- }
- }
- /*
- * detect the case where we have created the database, but have
- * not yet updated it.
- *
- * We only check the Key database because only the key database has
- * a metaData table. The metaData table is created when a password
- * is set, or in the case of update, when a password is supplied.
- * If no key database exists, then the update would have happened immediately
- * on noticing that the cert database didn't exist (see newInit set above).
- */
- if (type == SDB_KEY && !tableExists(sqlDB, "metaData")) {
- *newInit = 1;
- }
-
- /* access to network filesystems are significantly slower than local ones
- * for database operations. In those cases we need to create a cached copy
- * of the database in a temporary location on the local disk. SQLITE
- * already provides a way to create a temporary table and initialize it,
- * so we use it for the cache (see sdb_buildCache for how it's done).*/
-
- /*
- * we decide whether or not to use the cache based on the following input.
- *
- * NSS_SDB_USE_CACHE environment variable is non-existant or set to
- * anything other than "no" or "yes" ("auto", for instance).
- * This is the normal case. NSS will measure the performance of access
- * to the temp database versus the access to the users passed in
- * database location. If the temp database location is "significantly"
- * faster we will use the cache.
- *
- * NSS_SDB_USE_CACHE environment variable is set to "no": cache will not
- * be used.
- *
- * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will
- * always be used.
- *
- * It is expected that most applications would use the "auto" selection,
- * the environment variable is primarily to simplify testing, and to
- * correct potential corner cases where */
-
- env = PR_GetEnv("NSS_SDB_USE_CACHE");
-
- if (env && PORT_Strcasecmp(env,"no") == 0) {
- enableCache = PR_FALSE;
- } else if (env && PORT_Strcasecmp(env,"yes") == 0) {
- enableCache = PR_TRUE;
- } else {
- char *tempDir = NULL;
- PRUint32 tempOps = 0;
- /*
- * Use PR_Access to determine how expensive it
- * is to check for the existance of a local file compared to the same
- * check in the temp directory. If the temp directory is faster, cache
- * the database there. */
- tempDir = sdb_getTempDir(sqlDB);
- if (tempDir) {
- tempOps = sdb_measureAccess(tempDir);
- PORT_Free(tempDir);
-
- /* There is a cost to continually copying the database.
- * Account for that cost with the arbitrary factor of 10 */
- enableCache = (PRBool)(tempOps > accessOps * 10);
- }
- }
-
- if (enableCache) {
- /* try to set the temp store to memory.*/
- sqlite3_exec(sqlDB, "PRAGMA temp_store=MEMORY", NULL, 0, NULL);
- /* Failure to set the temp store to memory is not fatal,
- * ignore the error */
-
- cacheTable = sqlite3_mprintf("%sCache",table);
- if (cacheTable == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- /* build the cache table */
- error = sdb_buildCache(sqlDB, type, cacheTable, table);
- if (error != CKR_OK) {
- goto loser;
- }
- /* initialize the last cache build time */
- now = PR_IntervalNow();
- }
-
- sdb = (SDB *) malloc(sizeof(SDB));
- sdb_p = (SDBPrivate *) malloc(sizeof(SDBPrivate));
-
- /* invariant fields */
- sdb_p->sqlDBName = PORT_Strdup(dbname);
- sdb_p->type = type;
- sdb_p->table = table;
- sdb_p->cacheTable = cacheTable;
- sdb_p->lastUpdateTime = now;
- /* set the cache delay time. This is how long we will wait before we
- * decide the existing cache is stale. Currently set to 10 sec */
- sdb_p->updateInterval = PR_SecondsToInterval(10);
- sdb_p->dbMon = PR_NewMonitor();
- /* these fields are protected by the lock */
- sdb_p->sqlXactDB = NULL;
- sdb_p->sqlXactThread = NULL;
- sdb->private = sdb_p;
- sdb->version = 0;
- sdb->sdb_flags = flags | SDB_HAS_META;
- sdb->app_private = NULL;
- sdb->sdb_FindObjectsInit = sdb_FindObjectsInit;
- sdb->sdb_FindObjects = sdb_FindObjects;
- sdb->sdb_FindObjectsFinal = sdb_FindObjectsFinal;
- sdb->sdb_GetAttributeValue = sdb_GetAttributeValue;
- sdb->sdb_SetAttributeValue = sdb_SetAttributeValue;
- sdb->sdb_CreateObject = sdb_CreateObject;
- sdb->sdb_DestroyObject = sdb_DestroyObject;
- sdb->sdb_GetMetaData = sdb_GetMetaData;
- sdb->sdb_PutMetaData = sdb_PutMetaData;
- sdb->sdb_Begin = sdb_Begin;
- sdb->sdb_Commit = sdb_Commit;
- sdb->sdb_Abort = sdb_Abort;
- sdb->sdb_Reset = sdb_Reset;
- sdb->sdb_Close = sdb_Close;
- sdb->sdb_SetForkState = sdb_SetForkState;
-
- if (inTransaction) {
- sqlerr = sqlite3_exec(sqlDB, COMMIT_CMD, NULL, 0, NULL);
- if (sqlerr != SQLITE_OK) {
- error = sdb_mapSQLError(sdb_p->type, sqlerr);
- goto loser;
- }
- inTransaction = 0;
- }
-
- sdb_p->sqlReadDB = sqlDB;
-
- *pSdb = sdb;
- UNLOCK_SQLITE();
- return CKR_OK;
-
-loser:
- /* lots of stuff to do */
- if (inTransaction) {
- sqlite3_exec(sqlDB, ROLLBACK_CMD, NULL, 0, NULL);
- }
- if (sdb) {
- free(sdb);
- }
- if (sdb_p) {
- free(sdb_p);
- }
- if (sqlDB) {
- sqlite3_close(sqlDB);
- }
- UNLOCK_SQLITE();
- return error;
-
-}
-
-
-/* sdbopen */
-CK_RV
-s_open(const char *directory, const char *certPrefix, const char *keyPrefix,
- int cert_version, int key_version, int flags,
- SDB **certdb, SDB **keydb, int *newInit)
-{
- char *cert = sdb_BuildFileName(directory, certPrefix,
- "cert", cert_version);
- char *key = sdb_BuildFileName(directory, keyPrefix,
- "key", key_version);
- CK_RV error = CKR_OK;
- int inUpdate;
- PRUint32 accessOps;
-
- if (certdb)
- *certdb = NULL;
- if (keydb)
- *keydb = NULL;
- *newInit = 0;
-
-#ifdef SQLITE_UNSAFE_THREADS
- if (sqlite_lock == NULL) {
- sqlite_lock = PR_NewLock();
- if (sqlite_lock == NULL) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- }
-#endif
-
- /* how long does it take to test for a non-existant file in our working
- * directory? Allows us to test if we may be on a network file system */
- accessOps = sdb_measureAccess(directory);
-
- /*
- * open the cert data base
- */
- if (certdb) {
- /* initialize Certificate database */
- error = sdb_init(cert, "nssPublic", SDB_CERT, &inUpdate,
- newInit, flags, accessOps, certdb);
- if (error != CKR_OK) {
- goto loser;
- }
- }
-
- /*
- * open the key data base:
- * NOTE:if we want to implement a single database, we open
- * the same database file as the certificate here.
- *
- * cert an key db's have different tables, so they will not
- * conflict.
- */
- if (keydb) {
- /* initialize the Key database */
- error = sdb_init(key, "nssPrivate", SDB_KEY, &inUpdate,
- newInit, flags, accessOps, keydb);
- if (error != CKR_OK) {
- goto loser;
- }
- }
-
-
-loser:
- if (cert) {
- sqlite3_free(cert);
- }
- if (key) {
- sqlite3_free(key);
- }
-
- if (error != CKR_OK) {
- /* currently redundant, but could be necessary if more code is added
- * just before loser */
- if (keydb && *keydb) {
- sdb_Close(*keydb);
- }
- if (certdb && *certdb) {
- sdb_Close(*certdb);
- }
- }
-
- return error;
-}
-
-CK_RV
-s_shutdown()
-{
-#ifdef SQLITE_UNSAFE_THREADS
- if (sqlite_lock) {
- PR_DestroyLock(sqlite_lock);
- sqlite_lock = NULL;
- }
-#endif
- return CKR_OK;
-}
diff --git a/security/nss/lib/softoken/sdb.h b/security/nss/lib/softoken/sdb.h
deleted file mode 100644
index 2a855fb26..000000000
--- a/security/nss/lib/softoken/sdb.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * This file implements PKCS 11 on top of our existing security modules
- *
- * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
- * This implementation has two slots:
- * slot 1 is our generic crypto support. It does not require login.
- * It supports Public Key ops, and all they bulk ciphers and hashes.
- * It can also support Private Key ops for imported Private keys. It does
- * not have any token storage.
- * slot 2 is our private key support. It requires a login before use. It
- * can store Private Keys and Certs as token objects. Currently only private
- * keys and their associated Certificates are saved on the token.
- *
- * In this implementation, session objects are only visible to the session
- * that created or generated them.
- */
-
-/*
- * the following data structures should be moved to a 'rdb.h'.
- */
-
-#ifndef _SDB_H
-#define _SDB_H 1
-#include "pkcs11t.h"
-#include "secitem.h"
-#include "sftkdbt.h"
-
-#define STATIC_CMD_SIZE 2048
-
-typedef struct SDBFindStr SDBFind;
-typedef struct SDBStr SDB;
-
-struct SDBStr {
- void *private;
- int version;
- int reserved;
- int sdb_flags;
- void *app_private;
- CK_RV (*sdb_FindObjectsInit)(SDB *sdb, const CK_ATTRIBUTE *template,
- CK_ULONG count, SDBFind **find);
- CK_RV (*sdb_FindObjects)(SDB *sdb, SDBFind *find, CK_OBJECT_HANDLE *ids,
- CK_ULONG arraySize, CK_ULONG *count);
- CK_RV (*sdb_FindObjectsFinal)(SDB *sdb, SDBFind *find);
- CK_RV (*sdb_GetAttributeValue)(SDB *sdb, CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE *template, CK_ULONG count);
- CK_RV (*sdb_SetAttributeValue)(SDB *sdb, CK_OBJECT_HANDLE object,
- const CK_ATTRIBUTE *template, CK_ULONG count);
- CK_RV (*sdb_CreateObject)(SDB *sdb, CK_OBJECT_HANDLE *object,
- const CK_ATTRIBUTE *template, CK_ULONG count);
- CK_RV (*sdb_DestroyObject)(SDB *sdb, CK_OBJECT_HANDLE object);
- CK_RV (*sdb_GetMetaData)(SDB *sdb, const char *id,
- SECItem *item1, SECItem *item2);
- CK_RV (*sdb_PutMetaData)(SDB *sdb, const char *id,
- const SECItem *item1, const SECItem *item2);
- CK_RV (*sdb_Begin)(SDB *sdb);
- CK_RV (*sdb_Commit)(SDB *sdb);
- CK_RV (*sdb_Abort)(SDB *sdb);
- CK_RV (*sdb_Reset)(SDB *sdb);
- CK_RV (*sdb_Close)(SDB *sdb);
- void (*sdb_SetForkState)(PRBool forked);
-};
-
-CK_RV s_open(const char *directory, const char *certPrefix,
- const char *keyPrefix,
- int cert_version, int key_version,
- int flags, SDB **certdb, SDB **keydb, int *newInit);
-CK_RV s_shutdown();
-
-/* flags */
-#define SDB_RDONLY 1
-#define SDB_RDWR 2
-#define SDB_CREATE 4
-#define SDB_HAS_META 8
-
-#endif
diff --git a/security/nss/lib/softoken/sftkdb.c b/security/nss/lib/softoken/sftkdb.c
deleted file mode 100644
index 5495871ad..000000000
--- a/security/nss/lib/softoken/sftkdb.c
+++ /dev/null
@@ -1,2737 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * The following code handles the storage of PKCS 11 modules used by the
- * NSS. For the rest of NSS, only one kind of database handle exists:
- *
- * SFTKDBHandle
- *
- * There is one SFTKDBHandle for the each key database and one for each cert
- * database. These databases are opened as associated pairs, one pair per
- * slot. SFTKDBHandles are reference counted objects.
- *
- * Each SFTKDBHandle points to a low level database handle (SDB). This handle
- * represents the underlying physical database. These objects are not
- * reference counted, an are 'owned' by their respective SFTKDBHandles.
- *
- *
- */
-#include "sftkdb.h"
-#include "sftkdbti.h"
-#include "pkcs11t.h"
-#include "pkcs11i.h"
-#include "sdb.h"
-#include "prprf.h"
-#include "pratom.h"
-#include "lgglue.h"
-#include "utilpars.h"
-#include "secerr.h"
-#include "softoken.h"
-
-/*
- * We want all databases to have the same binary representation independent of
- * endianness or length of the host architecture. In general PKCS #11 attributes
- * are endian/length independent except those attributes that pass CK_ULONG.
- *
- * The following functions fixes up the CK_ULONG type attributes so that the data
- * base sees a machine independent view. CK_ULONGs are stored as 4 byte network
- * byte order values (big endian).
- */
-#define BBP 8
-
-static PRBool
-sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYPE type)
-{
- switch(type) {
- case CKA_CERTIFICATE_CATEGORY:
- case CKA_CERTIFICATE_TYPE:
- case CKA_CLASS:
- case CKA_JAVA_MIDP_SECURITY_DOMAIN:
- case CKA_KEY_GEN_MECHANISM:
- case CKA_KEY_TYPE:
- case CKA_MECHANISM_TYPE:
- case CKA_MODULUS_BITS:
- case CKA_PRIME_BITS:
- case CKA_SUBPRIME_BITS:
- case CKA_VALUE_BITS:
- case CKA_VALUE_LEN:
-
- case CKA_TRUST_DIGITAL_SIGNATURE:
- case CKA_TRUST_NON_REPUDIATION:
- case CKA_TRUST_KEY_ENCIPHERMENT:
- case CKA_TRUST_DATA_ENCIPHERMENT:
- case CKA_TRUST_KEY_AGREEMENT:
- case CKA_TRUST_KEY_CERT_SIGN:
- case CKA_TRUST_CRL_SIGN:
-
- case CKA_TRUST_SERVER_AUTH:
- case CKA_TRUST_CLIENT_AUTH:
- case CKA_TRUST_CODE_SIGNING:
- case CKA_TRUST_EMAIL_PROTECTION:
- case CKA_TRUST_IPSEC_END_SYSTEM:
- case CKA_TRUST_IPSEC_TUNNEL:
- case CKA_TRUST_IPSEC_USER:
- case CKA_TRUST_TIME_STAMPING:
- case CKA_TRUST_STEP_UP_APPROVED:
- return PR_TRUE;
- default:
- break;
- }
- return PR_FALSE;
-
-}
-
-/* are the attributes private? */
-static PRBool
-sftkdb_isPrivateAttribute(CK_ATTRIBUTE_TYPE type)
-{
- switch(type) {
- case CKA_VALUE:
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- return PR_TRUE;
- default:
- break;
- }
- return PR_FALSE;
-}
-
-/* These attributes must be authenticated with an hmac. */
-static PRBool
-sftkdb_isAuthenticatedAttribute(CK_ATTRIBUTE_TYPE type)
-{
- switch(type) {
- case CKA_MODULUS:
- case CKA_PUBLIC_EXPONENT:
- case CKA_CERT_SHA1_HASH:
- case CKA_CERT_MD5_HASH:
- case CKA_TRUST_SERVER_AUTH:
- case CKA_TRUST_CLIENT_AUTH:
- case CKA_TRUST_EMAIL_PROTECTION:
- case CKA_TRUST_CODE_SIGNING:
- case CKA_TRUST_STEP_UP_APPROVED:
- case CKA_NSS_OVERRIDE_EXTENSIONS:
- return PR_TRUE;
- default:
- break;
- }
- return PR_FALSE;
-}
-
-/*
- * convert a native ULONG to a database ulong. Database ulong's
- * are all 4 byte big endian values.
- */
-void
-sftk_ULong2SDBULong(unsigned char *data, CK_ULONG value)
-{
- int i;
-
- for (i=0; i < SDB_ULONG_SIZE; i++) {
- data[i] = (value >> (SDB_ULONG_SIZE-1-i)*BBP) & 0xff;
- }
-}
-
-/*
- * convert a database ulong back to a native ULONG. (reverse of the above
- * function.
- */
-static CK_ULONG
-sftk_SDBULong2ULong(unsigned char *data)
-{
- int i;
- CK_ULONG value = 0;
-
- for (i=0; i < SDB_ULONG_SIZE; i++) {
- value |= (((CK_ULONG)data[i]) << (SDB_ULONG_SIZE-1-i)*BBP);
- }
- return value;
-}
-
-/*
- * fix up the input templates. Our fixed up ints are stored in data and must
- * be freed by the caller. The new template must also be freed. If there are no
- * CK_ULONG attributes, the orignal template is passed in as is.
- */
-static CK_ATTRIBUTE *
-sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count,
- unsigned char **dataOut)
-{
- int i;
- int ulongCount = 0;
- unsigned char *data;
- CK_ATTRIBUTE *ntemplate;
-
- *dataOut = NULL;
-
- /* first count the number of CK_ULONG attributes */
- for (i=0; i < count; i++) {
- /* Don't 'fixup' NULL values */
- if (!template[i].pValue) {
- continue;
- }
- if (template[i].ulValueLen == sizeof (CK_ULONG)) {
- if ( sftkdb_isULONGAttribute(template[i].type)) {
- ulongCount++;
- }
- }
- }
- /* no attributes to fixup, just call on through */
- if (ulongCount == 0) {
- return (CK_ATTRIBUTE *)template;
- }
-
- /* allocate space for new ULONGS */
- data = (unsigned char *)PORT_Alloc(SDB_ULONG_SIZE*ulongCount);
- if (!data) {
- return NULL;
- }
-
- /* allocate new template */
- ntemplate = PORT_NewArray(CK_ATTRIBUTE,count);
- if (!ntemplate) {
- PORT_Free(data);
- return NULL;
- }
- *dataOut = data;
- /* copy the old template, fixup the actual ulongs */
- for (i=0; i < count; i++) {
- ntemplate[i] = template[i];
- /* Don't 'fixup' NULL values */
- if (!template[i].pValue) {
- continue;
- }
- if (template[i].ulValueLen == sizeof (CK_ULONG)) {
- if ( sftkdb_isULONGAttribute(template[i].type) ) {
- CK_ULONG value = *(CK_ULONG *) template[i].pValue;
- sftk_ULong2SDBULong(data, value);
- ntemplate[i].pValue = data;
- ntemplate[i].ulValueLen = SDB_ULONG_SIZE;
- data += SDB_ULONG_SIZE;
- }
- }
- }
- return ntemplate;
-}
-
-
-static const char SFTKDB_META_SIG_TEMPLATE[] = "sig_%s_%08x_%08x";
-
-/*
- * return a string describing the database type (key or cert)
- */
-const char *
-sftkdb_TypeString(SFTKDBHandle *handle)
-{
- return (handle->type == SFTK_KEYDB_TYPE) ? "key" : "cert";
-}
-
-/*
- * Some attributes are signed with an Hmac and a pbe key generated from
- * the password. This signature is stored indexed by object handle and
- * attribute type in the meta data table in the key database.
- *
- * Signature entries are indexed by the string
- * sig_[cert/key]_{ObjectID}_{Attribute}
- *
- * This function fetches that pkcs5 signature. Caller supplies a SECItem
- * pre-allocated to the appropriate size if the SECItem is too small the
- * function will fail with CKR_BUFFER_TOO_SMALL.
- */
-static CK_RV
-sftkdb_getAttributeSignature(SFTKDBHandle *handle, SFTKDBHandle *keyHandle,
- CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE type,
- SECItem *signText)
-{
- SDB *db;
- char id[30];
- CK_RV crv;
-
- db = SFTK_GET_SDB(keyHandle);
-
- sprintf(id, SFTKDB_META_SIG_TEMPLATE,
- sftkdb_TypeString(handle),
- (unsigned int)objectID, (unsigned int)type);
-
- crv = (*db->sdb_GetMetaData)(db, id, signText, NULL);
- return crv;
-}
-
-/*
- * Some attributes are signed with an Hmac and a pbe key generated from
- * the password. This signature is stored indexed by object handle and
- * attribute type in the meta data table in the key database.
- *
- * Signature entries are indexed by the string
- * sig_[cert/key]_{ObjectID}_{Attribute}
- *
- * This function stores that pkcs5 signature.
- */
-CK_RV
-sftkdb_PutAttributeSignature(SFTKDBHandle *handle, SDB *keyTarget,
- CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE type,
- SECItem *signText)
-{
- char id[30];
- CK_RV crv;
-
- sprintf(id, SFTKDB_META_SIG_TEMPLATE,
- sftkdb_TypeString(handle),
- (unsigned int)objectID, (unsigned int)type);
-
- crv = (*keyTarget->sdb_PutMetaData)(keyTarget, id, signText, NULL);
- return crv;
-}
-
-/*
- * fix up returned data. NOTE: sftkdb_fixupTemplateIn has already allocated
- * separate data sections for the database ULONG values.
- */
-static CK_RV
-sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE *ntemplate, int count, SFTKDBHandle *handle)
-{
- int i;
- CK_RV crv = CKR_OK;
- SFTKDBHandle *keyHandle;
- PRBool checkSig = PR_TRUE;
- PRBool checkEnc = PR_TRUE;
-
- PORT_Assert(handle);
-
- /* find the key handle */
- keyHandle = handle;
- if (handle->type != SFTK_KEYDB_TYPE) {
- checkEnc = PR_FALSE;
- keyHandle = handle->peerDB;
- }
-
- if ((keyHandle == NULL) ||
- ((SFTK_GET_SDB(keyHandle)->sdb_flags & SDB_HAS_META) == 0) ||
- (keyHandle->passwordKey.data == NULL)) {
- checkSig = PR_FALSE;
- }
-
- for (i=0; i < count; i++) {
- CK_ULONG length = template[i].ulValueLen;
- template[i].ulValueLen = ntemplate[i].ulValueLen;
- /* fixup ulongs */
- if (ntemplate[i].ulValueLen == SDB_ULONG_SIZE) {
- if (sftkdb_isULONGAttribute(template[i].type)) {
- if (template[i].pValue) {
- CK_ULONG value;
- unsigned char *data;
-
- data = (unsigned char *)ntemplate[i].pValue;
- value = sftk_SDBULong2ULong(ntemplate[i].pValue);
- if (length < sizeof(CK_ULONG)) {
- template[i].ulValueLen = -1;
- crv = CKR_BUFFER_TOO_SMALL;
- continue;
- }
- PORT_Memcpy(template[i].pValue,&value,sizeof(CK_ULONG));
- }
- template[i].ulValueLen = sizeof(CK_ULONG);
- }
- }
-
- /* if no data was retrieved, no need to process encrypted or signed
- * attributes */
- if ((template[i].pValue == NULL) || (template[i].ulValueLen == -1)) {
- continue;
- }
-
- /* fixup private attributes */
- if (checkEnc && sftkdb_isPrivateAttribute(ntemplate[i].type)) {
- /* we have a private attribute */
- /* This code depends on the fact that the cipherText is bigger
- * than the plain text */
- SECItem cipherText;
- SECItem *plainText;
- SECStatus rv;
-
- cipherText.data = ntemplate[i].pValue;
- cipherText.len = ntemplate[i].ulValueLen;
- PZ_Lock(handle->passwordLock);
- if (handle->passwordKey.data == NULL) {
- PZ_Unlock(handle->passwordLock);
- template[i].ulValueLen = -1;
- crv = CKR_USER_NOT_LOGGED_IN;
- continue;
- }
- rv = sftkdb_DecryptAttribute(&handle->passwordKey,
- &cipherText, &plainText);
- PZ_Unlock(handle->passwordLock);
- if (rv != SECSuccess) {
- PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
- template[i].ulValueLen = -1;
- crv = CKR_GENERAL_ERROR;
- continue;
- }
- PORT_Assert(template[i].ulValueLen >= plainText->len);
- if (template[i].ulValueLen < plainText->len) {
- SECITEM_FreeItem(plainText,PR_TRUE);
- PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
- template[i].ulValueLen = -1;
- crv = CKR_GENERAL_ERROR;
- continue;
- }
-
- /* copy the plain text back into the template */
- PORT_Memcpy(template[i].pValue, plainText->data, plainText->len);
- template[i].ulValueLen = plainText->len;
- SECITEM_FreeItem(plainText,PR_TRUE);
- }
- /* make sure signed attributes are valid */
- if (checkSig && sftkdb_isAuthenticatedAttribute(ntemplate[i].type)) {
- SECStatus rv;
- SECItem signText;
- SECItem plainText;
- unsigned char signData[SDB_MAX_META_DATA_LEN];
-
- signText.data = signData;
- signText.len = sizeof(signData);
-
- rv = sftkdb_getAttributeSignature(handle, keyHandle,
- objectID, ntemplate[i].type, &signText);
- if (rv != SECSuccess) {
- PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
- template[i].ulValueLen = -1;
- crv = CKR_DATA_INVALID; /* better error code? */
- continue;
- }
-
- plainText.data = ntemplate[i].pValue;
- plainText.len = ntemplate[i].ulValueLen;
-
- /*
- * we do a second check holding the lock just in case the user
- * loggout while we were trying to get the signature.
- */
- PZ_Lock(keyHandle->passwordLock);
- if (keyHandle->passwordKey.data == NULL) {
- /* if we are no longer logged in, no use checking the other
- * Signatures either. */
- checkSig = PR_FALSE;
- PZ_Unlock(keyHandle->passwordLock);
- continue;
- }
-
- rv = sftkdb_VerifyAttribute(&keyHandle->passwordKey,
- objectID, ntemplate[i].type,
- &plainText, &signText);
- PZ_Unlock(keyHandle->passwordLock);
- if (rv != SECSuccess) {
- PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
- template[i].ulValueLen = -1;
- crv = CKR_SIGNATURE_INVALID; /* better error code? */
- }
- /* This Attribute is fine */
- }
- }
- return crv;
-}
-
-/*
- * Some attributes are signed with an HMAC and a pbe key generated from
- * the password. This signature is stored indexed by object handle and
- *
- * Those attributes are:
- * 1) Trust object hashes and trust values.
- * 2) public key values.
- *
- * Certs themselves are considered properly authenticated by virtue of their
- * signature, or their matching hash with the trust object.
- *
- * These signature is only checked for objects coming from shared databases.
- * Older dbm style databases have such no signature checks. HMACs are also
- * only checked when the token is logged in, as it requires a pbe generated
- * from the password.
- *
- * Tokens which have no key database (and therefore no master password) do not
- * have any stored signature values. Signature values are stored in the key
- * database, since the signature data is tightly coupled to the key database
- * password.
- *
- * This function takes a template of attributes that were either created or
- * modified. These attributes are checked to see if the need to be signed.
- * If they do, then this function signs the attributes and writes them
- * to the meta data store.
- *
- * This function can fail if there are attributes that must be signed, but
- * the token is not logged in.
- *
- * The caller is expected to abort any transaction he was in in the
- * event of a failure of this function.
- */
-static CK_RV
-sftk_signTemplate(PLArenaPool *arena, SFTKDBHandle *handle,
- PRBool mayBeUpdateDB,
- CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template,
- CK_ULONG count)
-{
- int i;
- CK_RV crv;
- SFTKDBHandle *keyHandle = handle;
- SDB *keyTarget = NULL;
- PRBool usingPeerDB = PR_FALSE;
- PRBool inPeerDBTransaction = PR_FALSE;
-
- PORT_Assert(handle);
-
- if (handle->type != SFTK_KEYDB_TYPE) {
- keyHandle = handle->peerDB;
- usingPeerDB = PR_TRUE;
- }
-
- /* no key DB defined? then no need to sign anything */
- if (keyHandle == NULL) {
- crv = CKR_OK;
- goto loser;
- }
-
- /* When we are in a middle of an update, we have an update database set,
- * but we want to write to the real database. The bool mayBeUpdateDB is
- * set to TRUE if it's possible that we want to write an update database
- * rather than a primary */
- keyTarget = (mayBeUpdateDB && keyHandle->update) ?
- keyHandle->update : keyHandle->db;
-
- /* skip the the database does not support meta data */
- if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) {
- crv = CKR_OK;
- goto loser;
- }
-
- /* If we had to switch databases, we need to initialize a transaction. */
- if (usingPeerDB) {
- crv = (*keyTarget->sdb_Begin)(keyTarget);
- if (crv != CKR_OK) {
- goto loser;
- }
- inPeerDBTransaction = PR_TRUE;
- }
-
- for (i=0; i < count; i ++) {
- if (sftkdb_isAuthenticatedAttribute(template[i].type)) {
- SECStatus rv;
- SECItem *signText;
- SECItem plainText;
-
- plainText.data = template[i].pValue;
- plainText.len = template[i].ulValueLen;
- PZ_Lock(keyHandle->passwordLock);
- if (keyHandle->passwordKey.data == NULL) {
- PZ_Unlock(keyHandle->passwordLock);
- crv = CKR_USER_NOT_LOGGED_IN;
- goto loser;
- }
- rv = sftkdb_SignAttribute(arena, &keyHandle->passwordKey,
- objectID, template[i].type,
- &plainText, &signText);
- PZ_Unlock(keyHandle->passwordLock);
- if (rv != SECSuccess) {
- crv = CKR_GENERAL_ERROR; /* better error code here? */
- goto loser;
- }
- rv = sftkdb_PutAttributeSignature(handle, keyTarget,
- objectID, template[i].type, signText);
- if (rv != SECSuccess) {
- crv = CKR_GENERAL_ERROR; /* better error code here? */
- goto loser;
- }
- }
- }
- crv = CKR_OK;
-
- /* If necessary, commit the transaction */
- if (inPeerDBTransaction) {
- crv = (*keyTarget->sdb_Commit)(keyTarget);
- if (crv != CKR_OK) {
- goto loser;
- }
- inPeerDBTransaction = PR_FALSE;
- }
-
-loser:
- if (inPeerDBTransaction) {
- /* The transaction must have failed. Abort. */
- (*keyTarget->sdb_Abort)(keyTarget);
- PORT_Assert(crv != CKR_OK);
- if (crv == CKR_OK) crv = CKR_GENERAL_ERROR;
- }
- return crv;
-}
-
-static CK_RV
-sftkdb_CreateObject(PRArenaPool *arena, SFTKDBHandle *handle,
- SDB *db, CK_OBJECT_HANDLE *objectID,
- CK_ATTRIBUTE *template, CK_ULONG count)
-{
- PRBool inTransaction = PR_FALSE;
- CK_RV crv;
-
- inTransaction = PR_TRUE;
-
- crv = (*db->sdb_CreateObject)(db, objectID, template, count);
- if (crv != CKR_OK) {
- goto loser;
- }
- crv = sftk_signTemplate(arena, handle, (db == handle->update),
- *objectID, template, count);
-loser:
-
- return crv;
-}
-
-
-CK_ATTRIBUTE *
-sftk_ExtractTemplate(PLArenaPool *arena, SFTKObject *object,
- SFTKDBHandle *handle,CK_ULONG *pcount,
- CK_RV *crv)
-{
- int count;
- CK_ATTRIBUTE *template;
- int i, templateIndex;
- SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);
- PRBool doEnc = PR_TRUE;
-
- *crv = CKR_OK;
-
- if (sessObject == NULL) {
- *crv = CKR_GENERAL_ERROR; /* internal programming error */
- return NULL;
- }
-
- PORT_Assert(handle);
- /* find the key handle */
- if (handle->type != SFTK_KEYDB_TYPE) {
- doEnc = PR_FALSE;
- }
-
- PZ_Lock(sessObject->attributeLock);
- count = 0;
- for (i=0; i < sessObject->hashSize; i++) {
- SFTKAttribute *attr;
- for (attr=sessObject->head[i]; attr; attr=attr->next) {
- count++;
- }
- }
- template = PORT_ArenaNewArray(arena, CK_ATTRIBUTE, count);
- if (template == NULL) {
- PZ_Unlock(sessObject->attributeLock);
- *crv = CKR_HOST_MEMORY;
- return NULL;
- }
- templateIndex = 0;
- for (i=0; i < sessObject->hashSize; i++) {
- SFTKAttribute *attr;
- for (attr=sessObject->head[i]; attr; attr=attr->next) {
- CK_ATTRIBUTE *tp = &template[templateIndex++];
- /* copy the attribute */
- *tp = attr->attrib;
-
- /* fixup ULONG s */
- if ((tp->ulValueLen == sizeof (CK_ULONG)) &&
- (sftkdb_isULONGAttribute(tp->type)) ) {
- CK_ULONG value = *(CK_ULONG *) tp->pValue;
- unsigned char *data;
-
- tp->pValue = PORT_ArenaAlloc(arena, SDB_ULONG_SIZE);
- data = (unsigned char *)tp->pValue;
- if (data == NULL) {
- *crv = CKR_HOST_MEMORY;
- break;
- }
- sftk_ULong2SDBULong(data, value);
- tp->ulValueLen = SDB_ULONG_SIZE;
- }
-
- /* encrypt private attributes */
- if (doEnc && sftkdb_isPrivateAttribute(tp->type)) {
- /* we have a private attribute */
- SECItem *cipherText;
- SECItem plainText;
- SECStatus rv;
-
- plainText.data = tp->pValue;
- plainText.len = tp->ulValueLen;
- PZ_Lock(handle->passwordLock);
- if (handle->passwordKey.data == NULL) {
- PZ_Unlock(handle->passwordLock);
- *crv = CKR_USER_NOT_LOGGED_IN;
- break;
- }
- rv = sftkdb_EncryptAttribute(arena, &handle->passwordKey,
- &plainText, &cipherText);
- PZ_Unlock(handle->passwordLock);
- if (rv == SECSuccess) {
- tp->pValue = cipherText->data;
- tp->ulValueLen = cipherText->len;
- } else {
- *crv = CKR_GENERAL_ERROR; /* better error code here? */
- break;
- }
- PORT_Memset(plainText.data, 0, plainText.len);
- }
- }
- }
- PORT_Assert(templateIndex <= count);
- PZ_Unlock(sessObject->attributeLock);
-
- if (*crv != CKR_OK) {
- return NULL;
- }
- if (pcount) {
- *pcount = count;
- }
- return template;
-
-}
-
-/*
- * return a pointer to the attribute in the give template.
- * The return value is not const, as the caller may modify
- * the given attribute value, but such modifications will
- * modify the actual value in the template.
- */
-static CK_ATTRIBUTE *
-sftkdb_getAttributeFromTemplate(CK_ATTRIBUTE_TYPE attribute,
- CK_ATTRIBUTE *ptemplate, CK_ULONG len)
-{
- CK_ULONG i;
-
- for (i=0; i < len; i++) {
- if (attribute == ptemplate[i].type) {
- return &ptemplate[i];
- }
- }
- return NULL;
-}
-
-static const CK_ATTRIBUTE *
-sftkdb_getAttributeFromConstTemplate(CK_ATTRIBUTE_TYPE attribute,
- const CK_ATTRIBUTE *ptemplate, CK_ULONG len)
-{
- CK_ULONG i;
-
- for (i=0; i < len; i++) {
- if (attribute == ptemplate[i].type) {
- return &ptemplate[i];
- }
- }
- return NULL;
-}
-
-
-/*
- * fetch a template which identifies 'unique' entries based on object type
- */
-static CK_RV
-sftkdb_getFindTemplate(CK_OBJECT_CLASS objectType, unsigned char *objTypeData,
- CK_ATTRIBUTE *findTemplate, CK_ULONG *findCount,
- CK_ATTRIBUTE *ptemplate, int len)
-{
- CK_ATTRIBUTE *attr;
- CK_ULONG count = 1;
-
- sftk_ULong2SDBULong(objTypeData, objectType);
- findTemplate[0].type = CKA_CLASS;
- findTemplate[0].pValue = objTypeData;
- findTemplate[0].ulValueLen = SDB_ULONG_SIZE;
-
- switch (objectType) {
- case CKO_CERTIFICATE:
- case CKO_NSS_TRUST:
- attr = sftkdb_getAttributeFromTemplate(CKA_ISSUER, ptemplate, len);
- if (attr == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- findTemplate[1] = *attr;
- attr = sftkdb_getAttributeFromTemplate(CKA_SERIAL_NUMBER,
- ptemplate, len);
- if (attr == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- findTemplate[2] = *attr;
- count = 3;
- break;
-
- case CKO_PRIVATE_KEY:
- case CKO_PUBLIC_KEY:
- case CKO_SECRET_KEY:
- attr = sftkdb_getAttributeFromTemplate(CKA_ID, ptemplate, len);
- if (attr == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- if (attr->ulValueLen == 0) {
- /* key is too generic to determine that it's unique, usually
- * happens in the key gen case */
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- findTemplate[1] = *attr;
- count = 2;
- break;
-
- case CKO_NSS_CRL:
- attr = sftkdb_getAttributeFromTemplate(CKA_SUBJECT, ptemplate, len);
- if (attr == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- findTemplate[1] = *attr;
- count = 2;
- break;
-
- case CKO_NSS_SMIME:
- attr = sftkdb_getAttributeFromTemplate(CKA_SUBJECT, ptemplate, len);
- if (attr == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- findTemplate[1] = *attr;
- attr = sftkdb_getAttributeFromTemplate(CKA_NSS_EMAIL, ptemplate, len);
- if (attr == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- findTemplate[2] = *attr;
- count = 3;
- break;
- default:
- attr = sftkdb_getAttributeFromTemplate(CKA_VALUE, ptemplate, len);
- if (attr == NULL) {
- return CKR_TEMPLATE_INCOMPLETE;
- }
- findTemplate[1] = *attr;
- count = 2;
- break;
- }
- *findCount = count;
-
- return CKR_OK;
-}
-
-/*
- * look to see if this object already exists and return its object ID if
- * it does.
- */
-static CK_RV
-sftkdb_lookupObject(SDB *db, CK_OBJECT_CLASS objectType,
- CK_OBJECT_HANDLE *id, CK_ATTRIBUTE *ptemplate, CK_ULONG len)
-{
- CK_ATTRIBUTE findTemplate[3];
- CK_ULONG count = 1;
- CK_ULONG objCount = 0;
- SDBFind *find = NULL;
- unsigned char objTypeData[SDB_ULONG_SIZE];
- CK_RV crv;
-
- *id = CK_INVALID_HANDLE;
- if (objectType == CKO_NSS_CRL) {
- return CKR_OK;
- }
- crv = sftkdb_getFindTemplate(objectType, objTypeData,
- findTemplate, &count, ptemplate, len);
-
- if (crv == CKR_OBJECT_HANDLE_INVALID) {
- /* key is too generic to determine that it's unique, usually
- * happens in the key gen case, tell the caller to go ahead
- * and just create it */
- return CKR_OK;
- }
- if (crv != CKR_OK) {
- return crv;
- }
-
- /* use the raw find, so we get the correct database */
- crv = (*db->sdb_FindObjectsInit)(db, findTemplate, count, &find);
- if (crv != CKR_OK) {
- return crv;
- }
- (*db->sdb_FindObjects)(db, find, id, 1, &objCount);
- (*db->sdb_FindObjectsFinal)(db, find);
-
- if (objCount == 0) {
- *id = CK_INVALID_HANDLE;
- }
- return CKR_OK;
-}
-
-
-/*
- * check to see if this template conflicts with others in our current database.
- */
-static CK_RV
-sftkdb_checkConflicts(SDB *db, CK_OBJECT_CLASS objectType,
- const CK_ATTRIBUTE *ptemplate, CK_ULONG len,
- CK_OBJECT_HANDLE sourceID)
-{
- CK_ATTRIBUTE findTemplate[2];
- unsigned char objTypeData[SDB_ULONG_SIZE];
- /* we may need to allocate some temporaries. Keep track of what was
- * allocated so we can free it in the end */
- unsigned char *temp1 = NULL;
- unsigned char *temp2 = NULL;
- CK_ULONG objCount = 0;
- SDBFind *find = NULL;
- CK_OBJECT_HANDLE id;
- const CK_ATTRIBUTE *attr, *attr2;
- CK_RV crv;
- CK_ATTRIBUTE subject;
-
- /* Currently the only conflict is with nicknames pointing to the same
- * subject when creating or modifying a certificate. */
- /* If the object is not a cert, no problem. */
- if (objectType != CKO_CERTIFICATE) {
- return CKR_OK;
- }
- /* if not setting a nickname then there's still no problem */
- attr = sftkdb_getAttributeFromConstTemplate(CKA_LABEL, ptemplate, len);
- if ((attr == NULL) || (attr->ulValueLen == 0)) {
- return CKR_OK;
- }
- /* fetch the subject of the source. For creation and merge, this should
- * be found in the template */
- attr2 = sftkdb_getAttributeFromConstTemplate(CKA_SUBJECT, ptemplate, len);
- if (sourceID == CK_INVALID_HANDLE) {
- if ((attr2 == NULL) || ((CK_LONG)attr2->ulValueLen < 0)) {
- crv = CKR_TEMPLATE_INCOMPLETE;
- goto done;
- }
- } else if ((attr2 == NULL) || ((CK_LONG)attr2->ulValueLen <= 0)) {
- /* sourceID is set if we are trying to modify an existing entry instead
- * of creating a new one. In this case the subject may not be (probably
- * isn't) in the template, we have to read it from the database */
- subject.type = CKA_SUBJECT;
- subject.pValue = NULL;
- subject.ulValueLen = 0;
- crv = (*db->sdb_GetAttributeValue)(db, sourceID, &subject, 1);
- if (crv != CKR_OK) {
- goto done;
- }
- if ((CK_LONG)subject.ulValueLen < 0) {
- crv = CKR_DEVICE_ERROR; /* closest pkcs11 error to corrupted DB */
- goto done;
- }
- temp1 = subject.pValue = PORT_Alloc(++subject.ulValueLen);
- if (temp1 == NULL) {
- crv = CKR_HOST_MEMORY;
- goto done;
- }
- crv = (*db->sdb_GetAttributeValue)(db, sourceID, &subject, 1);
- if (crv != CKR_OK) {
- goto done;
- }
- attr2 = &subject;
- }
-
- /* check for another cert in the database with the same nickname */
- sftk_ULong2SDBULong(objTypeData, objectType);
- findTemplate[0].type = CKA_CLASS;
- findTemplate[0].pValue = objTypeData;
- findTemplate[0].ulValueLen = SDB_ULONG_SIZE;
- findTemplate[1] = *attr;
-
- crv = (*db->sdb_FindObjectsInit)(db, findTemplate, 2, &find);
- if (crv != CKR_OK) {
- goto done;
- }
- (*db->sdb_FindObjects)(db, find, &id, 1, &objCount);
- (*db->sdb_FindObjectsFinal)(db, find);
-
- /* object count == 0 means no conflicting certs found,
- * go on with the operation */
- if (objCount == 0) {
- crv = CKR_OK;
- goto done;
- }
-
- /* There is a least one cert that shares the nickname, make sure it also
- * matches the subject. */
- findTemplate[0] = *attr2;
- /* we know how big the source subject was. Use that length to create the
- * space for the target. If it's not enough space, then it means the
- * source subject is too big, and therefore not a match. GetAttributeValue
- * will return CKR_BUFFER_TOO_SMALL. Otherwise it should be exactly enough
- * space (or enough space to be able to compare the result. */
- temp2 = findTemplate[0].pValue = PORT_Alloc(++findTemplate[0].ulValueLen);
- if (temp2 == NULL) {
- crv = CKR_HOST_MEMORY;
- goto done;
- }
- crv = (*db->sdb_GetAttributeValue)(db, id, findTemplate, 1);
- if (crv != CKR_OK) {
- if (crv == CKR_BUFFER_TOO_SMALL) {
- /* if our buffer is too small, then the Subjects clearly do
- * not match */
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- /* otherwise we couldn't get the value, just fail */
- goto done;
- }
-
- /* Ok, we have both subjects, make sure they are the same.
- * Compare the subjects */
- if ((findTemplate[0].ulValueLen != attr2->ulValueLen) ||
- (attr2->ulValueLen > 0 &&
- PORT_Memcmp(findTemplate[0].pValue, attr2->pValue, attr2->ulValueLen)
- != 0)) {
- crv = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- crv = CKR_OK;
-
-done:
- /* If we've failed for some other reason than a conflict, make sure we
- * return an error code other than CKR_ATTRIBUTE_VALUE_INVALID.
- * (NOTE: neither sdb_FindObjectsInit nor sdb_GetAttributeValue should
- * return CKR_ATTRIBUTE_VALUE_INVALID, so the following is paranoia).
- */
- if (crv == CKR_ATTRIBUTE_VALUE_INVALID) {
- crv = CKR_GENERAL_ERROR; /* clearly a programming error */
- }
-
- /* exit point if we found a conflict */
-loser:
- PORT_Free(temp1);
- PORT_Free(temp2);
- return crv;
-}
-
-/*
- * try to update the template to fix any errors. This is only done
- * during update.
- *
- * NOTE: we must update the template or return an error, or the update caller
- * will loop forever!
- *
- * Two copies of the source code for this algorithm exist in NSS.
- * Changes must be made in both copies.
- * The other copy is in pk11_IncrementNickname() in pk11wrap/pk11merge.c.
- *
- */
-static CK_RV
-sftkdb_resolveConflicts(PRArenaPool *arena, CK_OBJECT_CLASS objectType,
- CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
-{
- CK_ATTRIBUTE *attr;
- char *nickname, *newNickname;
- int end, digit;
-
- /* sanity checks. We should never get here with these errors */
- if (objectType != CKO_CERTIFICATE) {
- return CKR_GENERAL_ERROR; /* shouldn't happen */
- }
- attr = sftkdb_getAttributeFromTemplate(CKA_LABEL, ptemplate, *plen);
- if ((attr == NULL) || (attr->ulValueLen == 0)) {
- return CKR_GENERAL_ERROR; /* shouldn't happen */
- }
-
- /* update the nickname */
- /* is there a number at the end of the nickname already?
- * if so just increment that number */
- nickname = (char *)attr->pValue;
-
- /* does nickname end with " #n*" ? */
- for (end = attr->ulValueLen - 1;
- end >= 2 && (digit = nickname[end]) <= '9' && digit >= '0';
- end--) /* just scan */ ;
- if (attr->ulValueLen >= 3 &&
- end < (attr->ulValueLen - 1) /* at least one digit */ &&
- nickname[end] == '#' &&
- nickname[end - 1] == ' ') {
- /* Already has a suitable suffix string */
- } else {
- /* ... append " #2" to the name */
- static const char num2[] = " #2";
- newNickname = PORT_ArenaAlloc(arena, attr->ulValueLen + sizeof(num2));
- if (!newNickname) {
- return CKR_HOST_MEMORY;
- }
- PORT_Memcpy(newNickname, nickname, attr->ulValueLen);
- PORT_Memcpy(&newNickname[attr->ulValueLen], num2, sizeof(num2));
- attr->pValue = newNickname; /* modifies ptemplate */
- attr->ulValueLen += 3; /* 3 is strlen(num2) */
- return CKR_OK;
- }
-
- for (end = attr->ulValueLen - 1;
- end >= 0 && (digit = nickname[end]) <= '9' && digit >= '0';
- end--) {
- if (digit < '9') {
- nickname[end]++;
- return CKR_OK;
- }
- nickname[end] = '0';
- }
-
- /* we overflowed, insert a new '1' for a carry in front of the number */
- newNickname = PORT_ArenaAlloc(arena, attr->ulValueLen + 1);
- if (!newNickname) {
- return CKR_HOST_MEMORY;
- }
- /* PORT_Memcpy should handle len of '0' */
- PORT_Memcpy(newNickname, nickname, ++end);
- newNickname[end] = '1';
- PORT_Memset(&newNickname[end+1],'0',attr->ulValueLen - end);
- attr->pValue = newNickname;
- attr->ulValueLen++;
- return CKR_OK;
-}
-
-/*
- * set an attribute and sign it if necessary
- */
-static CK_RV
-sftkdb_setAttributeValue(PRArenaPool *arena, SFTKDBHandle *handle,
- SDB *db, CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template,
- CK_ULONG count)
-{
- CK_RV crv;
- crv = (*db->sdb_SetAttributeValue)(db, objectID, template, count);
- if (crv != CKR_OK) {
- return crv;
- }
- crv = sftk_signTemplate(arena, handle, db == handle->update,
- objectID, template, count);
- return crv;
-}
-
-/*
- * write a softoken object out to the database.
- */
-CK_RV
-sftkdb_write(SFTKDBHandle *handle, SFTKObject *object,
- CK_OBJECT_HANDLE *objectID)
-{
- CK_ATTRIBUTE *template;
- PLArenaPool *arena;
- CK_ULONG count;
- CK_RV crv;
- SDB *db;
- PRBool inTransaction = PR_FALSE;
- CK_OBJECT_HANDLE id;
-
- *objectID = CK_INVALID_HANDLE;
-
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
- db = SFTK_GET_SDB(handle);
-
- /*
- * we have opened a new database, but we have not yet updated it. We are
- * still running pointing to the old database (so the application can
- * still read). We don't want to write to the old database at this point,
- * however, since it leads to user confusion. So at this point we simply
- * require a user login. Let NSS know this so it can prompt the user.
- */
- if (db == handle->update) {
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- arena = PORT_NewArena(256);
- if (arena == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- template = sftk_ExtractTemplate(arena, object, handle, &count, &crv);
- if (!template) {
- goto loser;
- }
-
- crv = (*db->sdb_Begin)(db);
- if (crv != CKR_OK) {
- goto loser;
- }
- inTransaction = PR_TRUE;
-
- /*
- * We want to make the base database as free from object specific knowledge
- * as possible. To maintain compatibility, keep some of the desirable
- * object specific semantics of the old database.
- *
- * These were 2 fold:
- * 1) there were certain conflicts (like trying to set the same nickname
- * on two different subjects) that would return an error.
- * 2) Importing the 'same' object would silently update that object.
- *
- * The following 2 functions mimic the desirable effects of these two
- * semantics without pushing any object knowledge to the underlying database
- * code.
- */
-
- /* make sure we don't have attributes that conflict with the existing DB */
- crv = sftkdb_checkConflicts(db, object->objclass, template, count,
- CK_INVALID_HANDLE);
- if (crv != CKR_OK) {
- goto loser;
- }
- /* Find any copies that match this particular object */
- crv = sftkdb_lookupObject(db, object->objclass, &id, template, count);
- if (crv != CKR_OK) {
- goto loser;
- }
- if (id == CK_INVALID_HANDLE) {
- crv = sftkdb_CreateObject(arena, handle, db, objectID, template, count);
- } else {
- /* object already exists, modify it's attributes */
- *objectID = id;
- crv = sftkdb_setAttributeValue(arena, handle, db, id, template, count);
- }
- if (crv != CKR_OK) {
- goto loser;
- }
-
- crv = (*db->sdb_Commit)(db);
- inTransaction = PR_FALSE;
-
-loser:
- if (inTransaction) {
- (*db->sdb_Abort)(db);
- /* It is trivial to show the following code cannot
- * happen unless something is horribly wrong with our compilier or
- * hardware */
- PORT_Assert(crv != CKR_OK);
- if (crv == CKR_OK) crv = CKR_GENERAL_ERROR;
- }
-
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- if (crv == CKR_OK) {
- *objectID |= (handle->type | SFTK_TOKEN_TYPE);
- }
- return crv;
-}
-
-
-CK_RV
-sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template,
- CK_ULONG count, SDBFind **find)
-{
- unsigned char *data = NULL;
- CK_ATTRIBUTE *ntemplate = NULL;
- CK_RV crv;
- SDB *db;
-
- if (handle == NULL) {
- return CKR_OK;
- }
- db = SFTK_GET_SDB(handle);
-
- if (count != 0) {
- ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
- if (ntemplate == NULL) {
- return CKR_HOST_MEMORY;
- }
- }
-
- crv = (*db->sdb_FindObjectsInit)(db, ntemplate,
- count, find);
- if (data) {
- PORT_Free(ntemplate);
- PORT_Free(data);
- }
- return crv;
-}
-
-CK_RV
-sftkdb_FindObjects(SFTKDBHandle *handle, SDBFind *find,
- CK_OBJECT_HANDLE *ids, int arraySize, CK_ULONG *count)
-{
- CK_RV crv;
- SDB *db;
-
- if (handle == NULL) {
- *count = 0;
- return CKR_OK;
- }
- db = SFTK_GET_SDB(handle);
-
- crv = (*db->sdb_FindObjects)(db, find, ids,
- arraySize, count);
- if (crv == CKR_OK) {
- int i;
- for (i=0; i < *count; i++) {
- ids[i] |= (handle->type | SFTK_TOKEN_TYPE);
- }
- }
- return crv;
-}
-
-CK_RV sftkdb_FindObjectsFinal(SFTKDBHandle *handle, SDBFind *find)
-{
- SDB *db;
- if (handle == NULL) {
- return CKR_OK;
- }
- db = SFTK_GET_SDB(handle);
- return (*db->sdb_FindObjectsFinal)(db, find);
-}
-
-CK_RV
-sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE *template, CK_ULONG count)
-{
- CK_RV crv,crv2;
- CK_ATTRIBUTE *ntemplate;
- unsigned char *data = NULL;
- SDB *db;
-
- if (handle == NULL) {
- return CKR_GENERAL_ERROR;
- }
-
- /* short circuit common attributes */
- if (count == 1 &&
- (template[0].type == CKA_TOKEN ||
- template[0].type == CKA_PRIVATE ||
- template[0].type == CKA_SENSITIVE)) {
- CK_BBOOL boolVal = CK_TRUE;
-
- if (template[0].pValue == NULL) {
- template[0].ulValueLen = sizeof(CK_BBOOL);
- return CKR_OK;
- }
- if (template[0].ulValueLen < sizeof(CK_BBOOL)) {
- template[0].ulValueLen = -1;
- return CKR_BUFFER_TOO_SMALL;
- }
-
- if ((template[0].type == CKA_PRIVATE) &&
- (handle->type != SFTK_KEYDB_TYPE)) {
- boolVal = CK_FALSE;
- }
- if ((template[0].type == CKA_SENSITIVE) &&
- (handle->type != SFTK_KEYDB_TYPE)) {
- boolVal = CK_FALSE;
- }
- *(CK_BBOOL *)template[0].pValue = boolVal;
- template[0].ulValueLen = sizeof(CK_BBOOL);
- return CKR_OK;
- }
-
- db = SFTK_GET_SDB(handle);
- /* nothing to do */
- if (count == 0) {
- return CKR_OK;
- }
- ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
- if (ntemplate == NULL) {
- return CKR_HOST_MEMORY;
- }
- objectID &= SFTK_OBJ_ID_MASK;
- crv = (*db->sdb_GetAttributeValue)(db, objectID,
- ntemplate, count);
- crv2 = sftkdb_fixupTemplateOut(template, objectID, ntemplate,
- count, handle);
- if (crv == CKR_OK) crv = crv2;
- if (data) {
- PORT_Free(ntemplate);
- PORT_Free(data);
- }
- return crv;
-
-}
-
-CK_RV
-sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object,
- const CK_ATTRIBUTE *template, CK_ULONG count)
-{
- CK_ATTRIBUTE *ntemplate;
- unsigned char *data = NULL;
- PLArenaPool *arena = NULL;
- SDB *db;
- CK_RV crv = CKR_OK;
- CK_OBJECT_HANDLE objectID = (object->handle & SFTK_OBJ_ID_MASK);
- PRBool inTransaction = PR_FALSE;
-
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- db = SFTK_GET_SDB(handle);
- /* nothing to do */
- if (count == 0) {
- return CKR_OK;
- }
- /*
- * we have opened a new database, but we have not yet updated it. We are
- * still running pointing to the old database (so the application can
- * still read). We don't want to write to the old database at this point,
- * however, since it leads to user confusion. So at this point we simply
- * require a user login. Let NSS know this so it can prompt the user.
- */
- if (db == handle->update) {
- return CKR_USER_NOT_LOGGED_IN;
- }
-
- ntemplate = sftkdb_fixupTemplateIn(template, count, &data);
- if (ntemplate == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /* make sure we don't have attributes that conflict with the existing DB */
- crv = sftkdb_checkConflicts(db, object->objclass, template, count, objectID);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- arena = PORT_NewArena(256);
- if (arena == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
-
- crv = (*db->sdb_Begin)(db);
- if (crv != CKR_OK) {
- goto loser;
- }
- inTransaction = PR_TRUE;
- crv = sftkdb_setAttributeValue(arena, handle, db,
- objectID, template, count);
- if (crv != CKR_OK) {
- goto loser;
- }
- crv = (*db->sdb_Commit)(db);
-loser:
- if (crv != CKR_OK && inTransaction) {
- (*db->sdb_Abort)(db);
- }
- if (data) {
- PORT_Free(ntemplate);
- PORT_Free(data);
- }
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return crv;
-}
-
-CK_RV
-sftkdb_DestroyObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID)
-{
- CK_RV crv = CKR_OK;
- SDB *db;
-
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
- db = SFTK_GET_SDB(handle);
- objectID &= SFTK_OBJ_ID_MASK;
- crv = (*db->sdb_Begin)(db);
- if (crv != CKR_OK) {
- goto loser;
- }
- crv = (*db->sdb_DestroyObject)(db, objectID);
- if (crv != CKR_OK) {
- goto loser;
- }
- crv = (*db->sdb_Commit)(db);
-loser:
- if (crv != CKR_OK) {
- (*db->sdb_Abort)(db);
- }
- return crv;
-}
-
-CK_RV
-sftkdb_CloseDB(SFTKDBHandle *handle)
-{
-#ifdef NO_FORK_CHECK
- PRBool parentForkedAfterC_Initialize = PR_FALSE;
-#endif
- if (handle == NULL) {
- return CKR_OK;
- }
- if (handle->update) {
- if (handle->db->sdb_SetForkState) {
- (*handle->db->sdb_SetForkState)(parentForkedAfterC_Initialize);
- }
- (*handle->update->sdb_Close)(handle->update);
- }
- if (handle->db) {
- if (handle->db->sdb_SetForkState) {
- (*handle->db->sdb_SetForkState)(parentForkedAfterC_Initialize);
- }
- (*handle->db->sdb_Close)(handle->db);
- }
- if (handle->passwordKey.data) {
- PORT_ZFree(handle->passwordKey.data, handle->passwordKey.len);
- }
- if (handle->passwordLock) {
- SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock));
- }
- if (handle->updatePasswordKey) {
- SECITEM_FreeItem(handle->updatePasswordKey, PR_TRUE);
- }
- if (handle->updateID) {
- PORT_Free(handle->updateID);
- }
- PORT_Free(handle);
- return CKR_OK;
-}
-
-/*
- * reset a database to it's uninitialized state.
- */
-static CK_RV
-sftkdb_ResetDB(SFTKDBHandle *handle)
-{
- CK_RV crv = CKR_OK;
- SDB *db;
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
- db = SFTK_GET_SDB(handle);
- crv = (*db->sdb_Begin)(db);
- if (crv != CKR_OK) {
- goto loser;
- }
- crv = (*db->sdb_Reset)(db);
- if (crv != CKR_OK) {
- goto loser;
- }
- crv = (*db->sdb_Commit)(db);
-loser:
- if (crv != CKR_OK) {
- (*db->sdb_Abort)(db);
- }
- return crv;
-}
-
-
-CK_RV
-sftkdb_Begin(SFTKDBHandle *handle)
-{
- CK_RV crv = CKR_OK;
- SDB *db;
-
- if (handle == NULL) {
- return CKR_OK;
- }
- db = SFTK_GET_SDB(handle);
- if (db) {
- crv = (*db->sdb_Begin)(db);
- }
- return crv;
-}
-
-CK_RV
-sftkdb_Commit(SFTKDBHandle *handle)
-{
- CK_RV crv = CKR_OK;
- SDB *db;
-
- if (handle == NULL) {
- return CKR_OK;
- }
- db = SFTK_GET_SDB(handle);
- if (db) {
- (*db->sdb_Commit)(db);
- }
- return crv;
-}
-
-CK_RV
-sftkdb_Abort(SFTKDBHandle *handle)
-{
- CK_RV crv = CKR_OK;
- SDB *db;
-
- if (handle == NULL) {
- return CKR_OK;
- }
- db = SFTK_GET_SDB(handle);
- if (db) {
- crv = (db->sdb_Abort)(db);
- }
- return crv;
-}
-
-
-/*
- * functions to update the database from an old database
- */
-
-/*
- * known attributes
- */
-static const CK_ATTRIBUTE_TYPE known_attributes[] = {
- CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION,
- CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER,
- CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED,
- CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL,
- CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
- CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE,
- CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER,
- CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE,
- CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
- CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT,
- CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS,
- CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE,
- CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE,
- CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS,
- CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
- CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_TEMPLATE,
- CKA_UNWRAP_TEMPLATE, CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT,
- CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y, CKA_RESOLUTION, CKA_CHAR_ROWS,
- CKA_CHAR_COLUMNS, CKA_COLOR, CKA_BITS_PER_PIXEL, CKA_CHAR_SETS,
- CKA_ENCODING_METHODS, CKA_MIME_TYPES, CKA_MECHANISM_TYPE,
- CKA_REQUIRED_CMS_ATTRIBUTES, CKA_DEFAULT_CMS_ATTRIBUTES,
- CKA_SUPPORTED_CMS_ATTRIBUTES, CKA_NSS_URL, CKA_NSS_EMAIL,
- CKA_NSS_SMIME_INFO, CKA_NSS_SMIME_TIMESTAMP,
- CKA_NSS_PKCS8_SALT, CKA_NSS_PASSWORD_CHECK, CKA_NSS_EXPIRES,
- CKA_NSS_KRL, CKA_NSS_PQG_COUNTER, CKA_NSS_PQG_SEED,
- CKA_NSS_PQG_H, CKA_NSS_PQG_SEED_BITS, CKA_NSS_MODULE_SPEC,
- CKA_TRUST_DIGITAL_SIGNATURE, CKA_TRUST_NON_REPUDIATION,
- CKA_TRUST_KEY_ENCIPHERMENT, CKA_TRUST_DATA_ENCIPHERMENT,
- CKA_TRUST_KEY_AGREEMENT, CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN,
- CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING,
- CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM,
- CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING,
- CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
- CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS
-};
-
-static int known_attributes_size= sizeof(known_attributes)/
- sizeof(known_attributes[0]);
-
-static CK_RV
-sftkdb_GetObjectTemplate(SDB *source, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE *ptemplate, CK_ULONG *max)
-{
- int i,j;
- CK_RV crv;
-
- if (*max < known_attributes_size) {
- *max = known_attributes_size;
- return CKR_BUFFER_TOO_SMALL;
- }
- for (i=0; i < known_attributes_size; i++) {
- ptemplate[i].type = known_attributes[i];
- ptemplate[i].pValue = NULL;
- ptemplate[i].ulValueLen = 0;
- }
-
- crv = (*source->sdb_GetAttributeValue)(source, id,
- ptemplate, known_attributes_size);
-
- if ((crv != CKR_OK) && (crv != CKR_ATTRIBUTE_TYPE_INVALID)) {
- return crv;
- }
-
- for (i=0, j=0; i < known_attributes_size; i++, j++) {
- while (i < known_attributes_size && (ptemplate[i].ulValueLen == -1)) {
- i++;
- }
- if (i >= known_attributes_size) {
- break;
- }
- /* cheap optimization */
- if (i == j) {
- continue;
- }
- ptemplate[j] = ptemplate[i];
- }
- *max = j;
- return CKR_OK;
-}
-
-static const char SFTKDB_META_UPDATE_TEMPLATE[] = "upd_%s_%s";
-
-/*
- * check to see if we have already updated this database.
- * a NULL updateID means we are trying to do an in place
- * single database update. In that case we have already
- * determined that an update was necessary.
- */
-static PRBool
-sftkdb_hasUpdate(const char *typeString, SDB *db, const char *updateID)
-{
- char *id;
- CK_RV crv;
- SECItem dummy = { 0, NULL, 0 };
- unsigned char dummyData[SDB_MAX_META_DATA_LEN];
-
- if (!updateID) {
- return PR_FALSE;
- }
- id = PR_smprintf(SFTKDB_META_UPDATE_TEMPLATE, typeString, updateID);
- if (id == NULL) {
- return PR_FALSE;
- }
- dummy.data = dummyData;
- dummy.len = sizeof(dummyData);
-
- crv = (*db->sdb_GetMetaData)(db, id, &dummy, NULL);
- PR_smprintf_free(id);
- return crv == CKR_OK ? PR_TRUE : PR_FALSE;
-}
-
-/*
- * we just completed an update, store the update id
- * so we don't need to do it again. If non was given,
- * there is nothing to do.
- */
-static CK_RV
-sftkdb_putUpdate(const char *typeString, SDB *db, const char *updateID)
-{
- char *id;
- CK_RV crv;
- SECItem dummy = { 0, NULL, 0 };
-
- /* if no id was given, nothing to do */
- if (updateID == NULL) {
- return CKR_OK;
- }
-
- dummy.data = (unsigned char *)updateID;
- dummy.len = PORT_Strlen(updateID);
-
- id = PR_smprintf(SFTKDB_META_UPDATE_TEMPLATE, typeString, updateID);
- if (id == NULL) {
- return PR_FALSE;
- }
-
- crv = (*db->sdb_PutMetaData)(db, id, &dummy, NULL);
- PR_smprintf_free(id);
- return crv;
-}
-
-/*
- * get a ULong attribute from a template:
- * NOTE: this is a raw templated stored in database order!
- */
-static CK_ULONG
-sftkdb_getULongFromTemplate(CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *ptemplate, CK_ULONG len)
-{
- CK_ATTRIBUTE *attr = sftkdb_getAttributeFromTemplate(type,
- ptemplate, len);
-
- if (attr && attr->pValue && attr->ulValueLen == SDB_ULONG_SIZE) {
- return sftk_SDBULong2ULong(attr->pValue);
- }
- return (CK_ULONG)-1;
-}
-
-/*
- * we need to find a unique CKA_ID.
- * The basic idea is to just increment the lowest byte.
- * This code also handles the following corner cases:
- * 1) the single byte overflows. On overflow we increment the next byte up
- * and so forth until we have overflowed the entire CKA_ID.
- * 2) If we overflow the entire CKA_ID we expand it by one byte.
- * 3) the CKA_ID is non-existant, we create a new one with one byte.
- * This means no matter what CKA_ID is passed, the result of this function
- * is always a new CKA_ID, and this function will never return the same
- * CKA_ID the it has returned in the passed.
- */
-static CK_RV
-sftkdb_incrementCKAID(PRArenaPool *arena, CK_ATTRIBUTE *ptemplate)
-{
- unsigned char *buf = ptemplate->pValue;
- CK_ULONG len = ptemplate->ulValueLen;
-
- if (buf == NULL || len == (CK_ULONG)-1) {
- /* we have no valid CKAID, we'll create a basic one byte CKA_ID below */
- len = 0;
- } else {
- CK_ULONG i;
-
- /* walk from the back to front, incrementing
- * the CKA_ID until we no longer have a carry,
- * or have hit the front of the id. */
- for (i=len; i != 0; i--) {
- buf[i-1]++;
- if (buf[i-1] != 0) {
- /* no more carries, the increment is complete */
- return CKR_OK;
- }
- }
- /* we've now overflowed, fall through and expand the CKA_ID by
- * one byte */
- }
- buf = PORT_ArenaAlloc(arena, len+1);
- if (!buf) {
- return CKR_HOST_MEMORY;
- }
- if (len > 0) {
- PORT_Memcpy(buf, ptemplate->pValue, len);
- }
- buf[len] = 0;
- ptemplate->pValue = buf;
- ptemplate->ulValueLen = len+1;
- return CKR_OK;
-}
-
-/*
- * drop an attribute from a template.
- */
-void
-sftkdb_dropAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE *ptemplate,
- CK_ULONG *plen)
-{
- CK_ULONG count = *plen;
- CK_ULONG i;
-
- for (i=0; i < count; i++) {
- if (attr->type == ptemplate[i].type) {
- break;
- }
- }
-
- if (i == count) {
- /* attribute not found */
- return;
- }
-
- /* copy the remaining attributes up */
- for ( i++; i < count; i++) {
- ptemplate[i-1] = ptemplate[i];
- }
-
- /* decrement the template size */
- *plen = count -1;
-}
-
-/*
- * create some defines for the following functions to document the meaning
- * of true/false. (make's it easier to remember what means what.
- */
-typedef enum {
- SFTKDB_DO_NOTHING = 0,
- SFTKDB_ADD_OBJECT,
- SFTKDB_MODIFY_OBJECT,
- SFTKDB_DROP_ATTRIBUTE
-} sftkdbUpdateStatus;
-
-/*
- * helper function to reconcile a single trust entry.
- * Identify which trust entry we want to keep.
- * If we don't need to do anything (the records are already equal).
- * return SFTKDB_DO_NOTHING.
- * If we want to use the source version,
- * return SFTKDB_MODIFY_OBJECT
- * If we want to use the target version,
- * return SFTKDB_DROP_ATTRIBUTE
- *
- * In the end the caller will remove any attributes in the source
- * template when SFTKDB_DROP_ATTRIBUTE is specified, then use do a
- * set attributes with that template on the target if we received
- * any SFTKDB_MODIFY_OBJECT returns.
- */
-sftkdbUpdateStatus
-sftkdb_reconcileTrustEntry(PRArenaPool *arena, CK_ATTRIBUTE *target,
- CK_ATTRIBUTE *source)
-{
- CK_ULONG targetTrust = sftkdb_getULongFromTemplate(target->type,
- target, 1);
- CK_ULONG sourceTrust = sftkdb_getULongFromTemplate(target->type,
- source, 1);
-
- /*
- * try to pick the best solution between the source and the
- * target. Update the source template if we want the target value
- * to win out. Prefer cases where we don't actually update the
- * trust entry.
- */
-
- /* they are the same, everything is already kosher */
- if (targetTrust == sourceTrust) {
- return SFTKDB_DO_NOTHING;
- }
-
- /* handle the case where the source Trust attribute may be a bit
- * flakey */
- if (sourceTrust == (CK_ULONG)-1) {
- /*
- * The source Trust is invalid. We know that the target Trust
- * must be valid here, otherwise the above
- * targetTrust == sourceTrust check would have succeeded.
- */
- return SFTKDB_DROP_ATTRIBUTE;
- }
-
- /* target is invalid, use the source's idea of the trust value */
- if (targetTrust == (CK_ULONG)-1) {
- /* overwriting the target in this case is OK */
- return SFTKDB_MODIFY_OBJECT;
- }
-
- /* at this point we know that both attributes exist and have the
- * appropriate length (SDB_ULONG_SIZE). We no longer need to check
- * ulValueLen for either attribute.
- */
- if (sourceTrust == CKT_NSS_TRUST_UNKNOWN) {
- return SFTKDB_DROP_ATTRIBUTE;
- }
-
- /* target has no idea, use the source's idea of the trust value */
- if (targetTrust == CKT_NSS_TRUST_UNKNOWN) {
- /* overwriting the target in this case is OK */
- return SFTKDB_MODIFY_OBJECT;
- }
-
- /* so both the target and the source have some idea of what this
- * trust attribute should be, and neither agree exactly.
- * At this point, we prefer 'hard' attributes over 'soft' ones.
- * 'hard' ones are CKT_NSS_TRUSTED, CKT_NSS_TRUSTED_DELEGATOR, and
- * CKT_NSS_NOT_TRUTED. Soft ones are ones which don't change the
- * actual trust of the cert (CKT_MUST_VERIFY_TRUST,
- * CKT_NSS_VALID_DELEGATOR).
- */
- if ((sourceTrust == CKT_NSS_MUST_VERIFY_TRUST)
- || (sourceTrust == CKT_NSS_VALID_DELEGATOR)) {
- return SFTKDB_DROP_ATTRIBUTE;
- }
- if ((targetTrust == CKT_NSS_MUST_VERIFY_TRUST)
- || (targetTrust == CKT_NSS_VALID_DELEGATOR)) {
- /* again, overwriting the target in this case is OK */
- return SFTKDB_MODIFY_OBJECT;
- }
-
- /* both have hard attributes, we have a conflict, let the target win. */
- return SFTKDB_DROP_ATTRIBUTE;
-}
-
-const CK_ATTRIBUTE_TYPE sftkdb_trustList[] =
- { CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH,
- CKA_TRUST_CODE_SIGNING, CKA_TRUST_EMAIL_PROTECTION,
- CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER,
- CKA_TRUST_TIME_STAMPING };
-
-#define SFTK_TRUST_TEMPLATE_COUNT \
- (sizeof(sftkdb_trustList)/sizeof(sftkdb_trustList[0]))
-/*
- * Run through the list of known trust types, and reconcile each trust
- * entry one by one. Keep track of we really need to write out the source
- * trust object (overwriting the existing one).
- */
-static sftkdbUpdateStatus
-sftkdb_reconcileTrust(PRArenaPool *arena, SDB *db, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
-{
- CK_ATTRIBUTE trustTemplate[SFTK_TRUST_TEMPLATE_COUNT];
- unsigned char trustData[SFTK_TRUST_TEMPLATE_COUNT*SDB_ULONG_SIZE];
- sftkdbUpdateStatus update = SFTKDB_DO_NOTHING;
- CK_ULONG i;
- CK_RV crv;
-
-
- for (i=0; i < SFTK_TRUST_TEMPLATE_COUNT; i++) {
- trustTemplate[i].type = sftkdb_trustList[i];
- trustTemplate[i].pValue = &trustData[i*SDB_ULONG_SIZE];
- trustTemplate[i].ulValueLen = SDB_ULONG_SIZE;
- }
- crv = (*db->sdb_GetAttributeValue)(db, id,
- trustTemplate, SFTK_TRUST_TEMPLATE_COUNT);
- if ((crv != CKR_OK) && (crv != CKR_ATTRIBUTE_TYPE_INVALID)) {
- /* target trust has some problems, update it */
- update = SFTKDB_MODIFY_OBJECT;
- goto done;
- }
-
- for (i=0; i < SFTK_TRUST_TEMPLATE_COUNT; i++) {
- CK_ATTRIBUTE *attr = sftkdb_getAttributeFromTemplate(
- trustTemplate[i].type, ptemplate, *plen);
- sftkdbUpdateStatus status;
-
-
- /* if target trust value doesn't exist, nothing to merge */
- if (trustTemplate[i].ulValueLen == (CK_ULONG)-1) {
- /* if the source exists, then we want the source entry,
- * go ahead and update */
- if (attr && attr->ulValueLen != (CK_ULONG)-1) {
- update = SFTKDB_MODIFY_OBJECT;
- }
- continue;
- }
-
- /*
- * the source doesn't have the attribute, go to the next attribute
- */
- if (attr == NULL) {
- continue;
-
- }
- status = sftkdb_reconcileTrustEntry(arena, &trustTemplate[i], attr);
- if (status == SFTKDB_MODIFY_OBJECT) {
- update = SFTKDB_MODIFY_OBJECT;
- } else if (status == SFTKDB_DROP_ATTRIBUTE) {
- /* drop the source copy of the attribute, we are going with
- * the target's version */
- sftkdb_dropAttribute(attr, ptemplate, plen);
- }
- }
-
- /* finally manage stepup */
- if (update == SFTKDB_MODIFY_OBJECT) {
- CK_BBOOL stepUpBool = CK_FALSE;
- /* if we are going to write from the source, make sure we don't
- * overwrite the stepup bit if it's on*/
- trustTemplate[0].type = CKA_TRUST_STEP_UP_APPROVED;
- trustTemplate[0].pValue = &stepUpBool;
- trustTemplate[0].ulValueLen = sizeof(stepUpBool);
- crv = (*db->sdb_GetAttributeValue)(db, id, trustTemplate, 1);
- if ((crv == CKR_OK) && (stepUpBool == CK_TRUE)) {
- sftkdb_dropAttribute(trustTemplate, ptemplate, plen);
- }
- } else {
- /* we currently aren't going to update. If the source stepup bit is
- * on however, do an update so the target gets it as well */
- CK_ATTRIBUTE *attr;
-
- attr = sftkdb_getAttributeFromTemplate(CKA_TRUST_STEP_UP_APPROVED,
- ptemplate, *plen);
- if (attr && (attr->ulValueLen == sizeof(CK_BBOOL)) &&
- (*(CK_BBOOL *)(attr->pValue) == CK_TRUE)) {
- update = SFTKDB_MODIFY_OBJECT;
- }
- }
-
-done:
- return update;
-}
-
-static sftkdbUpdateStatus
-sftkdb_handleIDAndName(PRArenaPool *arena, SDB *db, CK_OBJECT_HANDLE id,
- CK_ATTRIBUTE *ptemplate, CK_ULONG *plen)
-{
- sftkdbUpdateStatus update = SFTKDB_DO_NOTHING;
- CK_ATTRIBUTE *attr1, *attr2;
- CK_ATTRIBUTE ttemplate[2] = {
- {CKA_ID, NULL, 0},
- {CKA_LABEL, NULL, 0}
- };
- CK_RV crv;
-
- attr1 = sftkdb_getAttributeFromTemplate(CKA_LABEL, ptemplate, *plen);
- attr2 = sftkdb_getAttributeFromTemplate(CKA_ID, ptemplate, *plen);
-
- /* if the source has neither an id nor label, don't bother updating */
- if ( (!attr1 || attr1->ulValueLen == 0) &&
- (! attr2 || attr2->ulValueLen == 0) ) {
- return SFTKDB_DO_NOTHING;
- }
-
- /* the source has either an id or a label, see what the target has */
- crv = (*db->sdb_GetAttributeValue)(db, id, ttemplate, 2);
-
- /* if the target has neither, update from the source */
- if ( ((ttemplate[0].ulValueLen == 0) ||
- (ttemplate[0].ulValueLen == (CK_ULONG)-1)) &&
- ((ttemplate[1].ulValueLen == 0) ||
- (ttemplate[1].ulValueLen == (CK_ULONG)-1)) ) {
- return SFTKDB_MODIFY_OBJECT;
- }
-
- /* check the CKA_ID */
- if ((ttemplate[0].ulValueLen != 0) &&
- (ttemplate[0].ulValueLen != (CK_ULONG)-1)) {
- /* we have a CKA_ID in the target, don't overwrite
- * the target with an empty CKA_ID from the source*/
- if (attr1 && attr1->ulValueLen == 0) {
- sftkdb_dropAttribute(attr1, ptemplate, plen);
- }
- } else if (attr1 && attr1->ulValueLen != 0) {
- /* source has a CKA_ID, but the target doesn't, update the target */
- update = SFTKDB_MODIFY_OBJECT;
- }
-
-
- /* check the nickname */
- if ((ttemplate[1].ulValueLen != 0) &&
- (ttemplate[1].ulValueLen != (CK_ULONG)-1)) {
-
- /* we have a nickname in the target, and we don't have to update
- * the CKA_ID. We are done. NOTE: if we add addition attributes
- * in this check, this shortcut can only go on the last of them. */
- if (update == SFTKDB_DO_NOTHING) {
- return update;
- }
- /* we have a nickname in the target, don't overwrite
- * the target with an empty nickname from the source */
- if (attr2 && attr2->ulValueLen == 0) {
- sftkdb_dropAttribute(attr2, ptemplate, plen);
- }
- } else if (attr2 && attr2->ulValueLen != 0) {
- /* source has a nickname, but the target doesn't, update the target */
- update = SFTKDB_MODIFY_OBJECT;
- }
-
- return update;
-}
-
-
-
-/*
- * This function updates the template before we write the object out.
- *
- * If we are going to skip updating this object, return PR_FALSE.
- * If it should be updated we return PR_TRUE.
- * To help readability, these have been defined
- * as SFTK_DONT_UPDATE and SFTK_UPDATE respectively.
- */
-static PRBool
-sftkdb_updateObjectTemplate(PRArenaPool *arena, SDB *db,
- CK_OBJECT_CLASS objectType,
- CK_ATTRIBUTE *ptemplate, CK_ULONG *plen,
- CK_OBJECT_HANDLE *targetID)
-{
- PRBool done; /* should we repeat the loop? */
- CK_OBJECT_HANDLE id;
- CK_RV crv = CKR_OK;
-
- do {
- crv = sftkdb_checkConflicts(db, objectType, ptemplate,
- *plen, CK_INVALID_HANDLE);
- if (crv != CKR_ATTRIBUTE_VALUE_INVALID) {
- break;
- }
- crv = sftkdb_resolveConflicts(arena, objectType, ptemplate, plen);
- } while (crv == CKR_OK);
-
- if (crv != CKR_OK) {
- return SFTKDB_DO_NOTHING;
- }
-
- do {
- done = PR_TRUE;
- crv = sftkdb_lookupObject(db, objectType, &id, ptemplate, *plen);
- if (crv != CKR_OK) {
- return SFTKDB_DO_NOTHING;
- }
-
- /* This object already exists, merge it, don't update */
- if (id != CK_INVALID_HANDLE) {
- CK_ATTRIBUTE *attr = NULL;
- /* special post processing for attributes */
- switch (objectType) {
- case CKO_CERTIFICATE:
- case CKO_PUBLIC_KEY:
- case CKO_PRIVATE_KEY:
- /* update target's CKA_ID and labels if they don't already
- * exist */
- *targetID = id;
- return sftkdb_handleIDAndName(arena, db, id, ptemplate, plen);
- case CKO_NSS_TRUST:
- /* if we have conflicting trust object types,
- * we need to reconcile them */
- *targetID = id;
- return sftkdb_reconcileTrust(arena, db, id, ptemplate, plen);
- case CKO_SECRET_KEY:
- /* secret keys in the old database are all sdr keys,
- * unfortunately they all appear to have the same CKA_ID,
- * even though they are truly different keys, so we always
- * want to update these keys, but we need to
- * give them a new CKA_ID */
- /* NOTE: this changes ptemplate */
- attr = sftkdb_getAttributeFromTemplate(CKA_ID,ptemplate,*plen);
- crv = attr ? sftkdb_incrementCKAID(arena, attr)
- : CKR_HOST_MEMORY;
- /* in the extremely rare event that we needed memory and
- * couldn't get it, just drop the key */
- if (crv != CKR_OK) {
- return SFTKDB_DO_NOTHING;
- }
- done = PR_FALSE; /* repeat this find loop */
- break;
- default:
- /* for all other objects, if we found the equivalent object,
- * don't update it */
- return SFTKDB_DO_NOTHING;
- }
- }
- } while (!done);
-
- /* this object doesn't exist, update it */
- return SFTKDB_ADD_OBJECT;
-}
-
-
-#define MAX_ATTRIBUTES 500
-static CK_RV
-sftkdb_mergeObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE id,
- SECItem *key)
-{
- CK_ATTRIBUTE template[MAX_ATTRIBUTES];
- CK_ATTRIBUTE *ptemplate;
- CK_ULONG max_attributes = MAX_ATTRIBUTES;
- CK_OBJECT_CLASS objectType;
- SDB *source = handle->update;
- SDB *target = handle->db;
- int i;
- CK_RV crv;
- PLArenaPool *arena = NULL;
-
- arena = PORT_NewArena(256);
- if (arena == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- ptemplate = &template[0];
- id &= SFTK_OBJ_ID_MASK;
- crv = sftkdb_GetObjectTemplate(source, id, ptemplate, &max_attributes);
- if (crv == CKR_BUFFER_TOO_SMALL) {
- ptemplate = PORT_ArenaNewArray(arena, CK_ATTRIBUTE, max_attributes);
- if (ptemplate == NULL) {
- crv = CKR_HOST_MEMORY;
- } else {
- crv = sftkdb_GetObjectTemplate(source, id,
- ptemplate, &max_attributes);
- }
- }
- if (crv != CKR_OK) {
- goto loser;
- }
-
- for (i=0; i < max_attributes; i++) {
- ptemplate[i].pValue = PORT_ArenaAlloc(arena,ptemplate[i].ulValueLen);
- if (ptemplate[i].pValue == NULL) {
- crv = CKR_HOST_MEMORY;
- goto loser;
- }
- }
- crv = (*source->sdb_GetAttributeValue)(source, id,
- ptemplate, max_attributes);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- objectType = sftkdb_getULongFromTemplate(CKA_CLASS, ptemplate,
- max_attributes);
-
- /*
- * Update Object updates the object template if necessary then returns
- * whether or not we need to actually write the object out to our target
- * database.
- */
- if (!handle->updateID) {
- crv = sftkdb_CreateObject(arena, handle, target, &id,
- ptemplate, max_attributes);
- } else {
- sftkdbUpdateStatus update_status;
- update_status = sftkdb_updateObjectTemplate(arena, target,
- objectType, ptemplate, &max_attributes, &id);
- switch (update_status) {
- case SFTKDB_ADD_OBJECT:
- crv = sftkdb_CreateObject(arena, handle, target, &id,
- ptemplate, max_attributes);
- break;
- case SFTKDB_MODIFY_OBJECT:
- crv = sftkdb_setAttributeValue(arena, handle, target,
- id, ptemplate, max_attributes);
- break;
- case SFTKDB_DO_NOTHING:
- case SFTKDB_DROP_ATTRIBUTE:
- break;
- }
- }
-
-loser:
- if (arena) {
- PORT_FreeArena(arena,PR_TRUE);
- }
- return crv;
-}
-
-
-#define MAX_IDS 10
-/*
- * update a new database from an old one, now that we have the key
- */
-CK_RV
-sftkdb_Update(SFTKDBHandle *handle, SECItem *key)
-{
- SDBFind *find = NULL;
- CK_ULONG idCount = MAX_IDS;
- CK_OBJECT_HANDLE ids[MAX_IDS];
- SECItem *updatePasswordKey = NULL;
- CK_RV crv, crv2;
- PRBool inTransaction = PR_FALSE;
- int i;
-
- if (handle == NULL) {
- return CKR_OK;
- }
- if (handle->update == NULL) {
- return CKR_OK;
- }
-
- /*
- * put the whole update under a transaction. This allows us to handle
- * any possible race conditions between with the updateID check.
- */
- crv = (*handle->db->sdb_Begin)(handle->db);
- if (crv != CKR_OK) {
- goto loser;
- }
- inTransaction = PR_TRUE;
-
- /* some one else has already updated this db */
- if (sftkdb_hasUpdate(sftkdb_TypeString(handle),
- handle->db, handle->updateID)) {
- crv = CKR_OK;
- goto done;
- }
-
- updatePasswordKey = sftkdb_GetUpdatePasswordKey(handle);
- if (updatePasswordKey) {
- /* pass the source DB key to the legacy code,
- * so it can decrypt things */
- handle->oldKey = updatePasswordKey;
- }
-
- /* find all the objects */
- crv = sftkdb_FindObjectsInit(handle, NULL, 0, &find);
-
- if (crv != CKR_OK) {
- goto loser;
- }
- while ((crv == CKR_OK) && (idCount == MAX_IDS)) {
- crv = sftkdb_FindObjects(handle, find, ids, MAX_IDS, &idCount);
- for (i=0; (crv == CKR_OK) && (i < idCount); i++) {
- crv = sftkdb_mergeObject(handle, ids[i], key);
- }
- }
- crv2 = sftkdb_FindObjectsFinal(handle, find);
- if (crv == CKR_OK) crv = crv2;
-
-loser:
- /* no longer need the old key value */
- handle->oldKey = NULL;
-
- /* update the password - even if we didn't update objects */
- if (handle->type == SFTK_KEYDB_TYPE) {
- SECItem item1, item2;
- unsigned char data1[SDB_MAX_META_DATA_LEN];
- unsigned char data2[SDB_MAX_META_DATA_LEN];
-
- item1.data = data1;
- item1.len = sizeof(data1);
- item2.data = data2;
- item2.len = sizeof(data2);
-
- /* if the target db already has a password, skip this. */
- crv = (*handle->db->sdb_GetMetaData)(handle->db, "password",
- &item1, &item2);
- if (crv == CKR_OK) {
- goto done;
- }
-
-
- /* nope, update it from the source */
- crv = (*handle->update->sdb_GetMetaData)(handle->update, "password",
- &item1, &item2);
- if (crv != CKR_OK) {
- goto done;
- }
- crv = (*handle->db->sdb_PutMetaData)(handle->db, "password", &item1,
- &item2);
- if (crv != CKR_OK) {
- goto done;
- }
- }
-
-done:
- /* finally mark this up to date db up to date */
- /* some one else has already updated this db */
- if (crv == CKR_OK) {
- crv = sftkdb_putUpdate(sftkdb_TypeString(handle),
- handle->db, handle->updateID);
- }
-
- if (inTransaction) {
- if (crv == CKR_OK) {
- crv = (*handle->db->sdb_Commit)(handle->db);
- } else {
- (*handle->db->sdb_Abort)(handle->db);
- }
- }
- if (handle->update) {
- (*handle->update->sdb_Close)(handle->update);
- handle->update = NULL;
- }
- if (handle->updateID) {
- PORT_Free(handle->updateID);
- handle->updateID = NULL;
- }
- sftkdb_FreeUpdatePasswordKey(handle);
- if (updatePasswordKey) {
- SECITEM_ZfreeItem(updatePasswordKey, PR_TRUE);
- }
- handle->updateDBIsInit = PR_FALSE;
- return crv;
-}
-
-/******************************************************************
- * DB handle managing functions.
- *
- * These functions are called by softoken to initialize, acquire,
- * and release database handles.
- */
-
-const char *
-sftkdb_GetUpdateID(SFTKDBHandle *handle)
-{
- return handle->updateID;
-}
-
-/* release a database handle */
-void
-sftk_freeDB(SFTKDBHandle *handle)
-{
- PRInt32 ref;
-
- if (!handle) return;
- ref = PR_ATOMIC_DECREMENT(&handle->ref);
- if (ref == 0) {
- sftkdb_CloseDB(handle);
- }
- return;
-}
-
-
-/*
- * acquire a database handle for a certificate db
- * (database for public objects)
- */
-SFTKDBHandle *
-sftk_getCertDB(SFTKSlot *slot)
-{
- SFTKDBHandle *dbHandle;
-
- PZ_Lock(slot->slotLock);
- dbHandle = slot->certDB;
- if (dbHandle) {
- PR_ATOMIC_INCREMENT(&dbHandle->ref);
- }
- PZ_Unlock(slot->slotLock);
- return dbHandle;
-}
-
-/*
- * acquire a database handle for a key database
- * (database for private objects)
- */
-SFTKDBHandle *
-sftk_getKeyDB(SFTKSlot *slot)
-{
- SFTKDBHandle *dbHandle;
-
- SKIP_AFTER_FORK(PZ_Lock(slot->slotLock));
- dbHandle = slot->keyDB;
- if (dbHandle) {
- PR_ATOMIC_INCREMENT(&dbHandle->ref);
- }
- SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock));
- return dbHandle;
-}
-
-/*
- * acquire the database for a specific object. NOTE: objectID must point
- * to a Token object!
- */
-SFTKDBHandle *
-sftk_getDBForTokenObject(SFTKSlot *slot, CK_OBJECT_HANDLE objectID)
-{
- SFTKDBHandle *dbHandle;
-
- PZ_Lock(slot->slotLock);
- dbHandle = objectID & SFTK_KEYDB_TYPE ? slot->keyDB : slot->certDB;
- if (dbHandle) {
- PR_ATOMIC_INCREMENT(&dbHandle->ref);
- }
- PZ_Unlock(slot->slotLock);
- return dbHandle;
-}
-
-/*
- * initialize a new database handle
- */
-static SFTKDBHandle *
-sftk_NewDBHandle(SDB *sdb, int type)
-{
- SFTKDBHandle *handle = PORT_New(SFTKDBHandle);
- handle->ref = 1;
- handle->db = sdb;
- handle->update = NULL;
- handle->peerDB = NULL;
- handle->newKey = NULL;
- handle->oldKey = NULL;
- handle->updatePasswordKey = NULL;
- handle->updateID = NULL;
- handle->type = type;
- handle->passwordKey.data = NULL;
- handle->passwordKey.len = 0;
- handle->passwordLock = NULL;
- if (type == SFTK_KEYDB_TYPE) {
- handle->passwordLock = PZ_NewLock(nssILockAttribute);
- }
- sdb->app_private = handle;
- return handle;
-}
-
-/*
- * reset the key database to it's uninitialized state. This call
- * will clear all the key entried.
- */
-SECStatus
-sftkdb_ResetKeyDB(SFTKDBHandle *handle)
-{
- CK_RV crv;
-
- /* only rest the key db */
- if (handle->type != SFTK_KEYDB_TYPE) {
- return SECFailure;
- }
- crv = sftkdb_ResetDB(handle);
- if (crv != CKR_OK) {
- /* set error */
- return SECFailure;
- }
- return SECSuccess;
-}
-
-static PRBool
-sftk_oldVersionExists(const char *dir, int version)
-{
- int i;
- PRStatus exists = PR_FAILURE;
- char *file = NULL;
-
- for (i=version; i > 1 ; i--) {
- file = PR_smprintf("%s%d.db",dir,i);
- if (file == NULL) {
- continue;
- }
- exists = PR_Access(file, PR_ACCESS_EXISTS);
- PR_smprintf_free(file);
- if (exists == PR_SUCCESS) {
- return PR_TRUE;
- }
- }
- return PR_FALSE;
-}
-
-static PRBool
-sftk_hasLegacyDB(const char *confdir, const char *certPrefix,
- const char *keyPrefix, int certVersion, int keyVersion)
-{
- char *dir;
- PRBool exists;
-
- if (certPrefix == NULL) {
- certPrefix = "";
- }
-
- if (keyPrefix == NULL) {
- keyPrefix = "";
- }
-
- dir= PR_smprintf("%s/%scert", confdir, certPrefix);
- if (dir == NULL) {
- return PR_FALSE;
- }
-
- exists = sftk_oldVersionExists(dir, certVersion);
- PR_smprintf_free(dir);
- if (exists) {
- return PR_TRUE;
- }
-
- dir= PR_smprintf("%s/%skey", confdir, keyPrefix);
- if (dir == NULL) {
- return PR_FALSE;
- }
-
- exists = sftk_oldVersionExists(dir, keyVersion);
- PR_smprintf_free(dir);
- return exists;
-}
-
-/*
- * initialize certificate and key database handles as a pair.
- *
- * This function figures out what type of database we are opening and
- * calls the appropriate low level function to open the database.
- * It also figures out whether or not to setup up automatic update.
- */
-CK_RV
-sftk_DBInit(const char *configdir, const char *certPrefix,
- const char *keyPrefix, const char *updatedir,
- const char *updCertPrefix, const char *updKeyPrefix,
- const char *updateID, PRBool readOnly, PRBool noCertDB,
- PRBool noKeyDB, PRBool forceOpen, PRBool isFIPS,
- SFTKDBHandle **certDB, SFTKDBHandle **keyDB)
-{
- const char *confdir;
- NSSDBType dbType = NSS_DB_TYPE_NONE;
- char *appName = NULL;
- SDB *keySDB, *certSDB;
- CK_RV crv = CKR_OK;
- int flags = SDB_RDONLY;
- PRBool newInit = PR_FALSE;
- PRBool needUpdate = PR_FALSE;
-
- if (!readOnly) {
- flags = SDB_CREATE;
- }
-
- *certDB = NULL;
- *keyDB = NULL;
-
- if (noKeyDB && noCertDB) {
- return CKR_OK;
- }
- confdir = _NSSUTIL_EvaluateConfigDir(configdir, &dbType, &appName);
-
- /*
- * now initialize the appropriate database
- */
- switch (dbType) {
- case NSS_DB_TYPE_LEGACY:
- crv = sftkdbCall_open(confdir, certPrefix, keyPrefix, 8, 3, flags,
- isFIPS, noCertDB? NULL : &certSDB, noKeyDB ? NULL: &keySDB);
- break;
- case NSS_DB_TYPE_MULTIACCESS:
- crv = sftkdbCall_open(configdir, certPrefix, keyPrefix, 8, 3, flags,
- isFIPS, noCertDB? NULL : &certSDB, noKeyDB ? NULL: &keySDB);
- break;
- case NSS_DB_TYPE_SQL:
- case NSS_DB_TYPE_EXTERN: /* SHOULD open a loadable db */
- crv = s_open(confdir, certPrefix, keyPrefix, 9, 4, flags,
- noCertDB? NULL : &certSDB, noKeyDB ? NULL : &keySDB, &newInit);
-
- /*
- * if we failed to open the DB's read only, use the old ones if
- * the exists.
- */
- if (crv != CKR_OK) {
- if ((flags == SDB_RDONLY) &&
- sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) {
- /* we have legacy databases, if we failed to open the new format
- * DB's read only, just use the legacy ones */
- crv = sftkdbCall_open(confdir, certPrefix,
- keyPrefix, 8, 3, flags, isFIPS,
- noCertDB? NULL : &certSDB, noKeyDB ? NULL : &keySDB);
- }
- /* Handle the database merge case.
- *
- * For the merge case, we need help from the application. Only
- * the application knows where the old database is, and what unique
- * identifier it has associated with it.
- *
- * If the client supplies these values, we use them to determine
- * if we need to update.
- */
- } else if (
- /* both update params have been supplied */
- updatedir && *updatedir && updateID && *updateID
- /* old dbs exist? */
- && sftk_hasLegacyDB(updatedir, updCertPrefix, updKeyPrefix, 8, 3)
- /* and they have not yet been updated? */
- && ((noKeyDB || !sftkdb_hasUpdate("key", keySDB, updateID))
- || (noCertDB || !sftkdb_hasUpdate("cert", certSDB, updateID)))) {
- /* we need to update */
- confdir = updatedir;
- certPrefix = updCertPrefix;
- keyPrefix = updKeyPrefix;
- needUpdate = PR_TRUE;
- } else if (newInit) {
- /* if the new format DB was also a newly created DB, and we
- * succeeded, then need to update that new database with data
- * from the existing legacy DB */
- if (sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) {
- needUpdate = PR_TRUE;
- }
- }
- break;
- default:
- crv = CKR_GENERAL_ERROR; /* can't happen, EvaluationConfigDir MUST
- * return one of the types we already
- * specified. */
- }
- if (crv != CKR_OK) {
- goto done;
- }
- if (!noCertDB) {
- *certDB = sftk_NewDBHandle(certSDB, SFTK_CERTDB_TYPE);
- } else {
- *certDB = NULL;
- }
- if (!noKeyDB) {
- *keyDB = sftk_NewDBHandle(keySDB, SFTK_KEYDB_TYPE);
- } else {
- *keyDB = NULL;
- }
-
- /* link them together */
- if (*certDB) {
- (*certDB)->peerDB = *keyDB;
- }
- if (*keyDB) {
- (*keyDB)->peerDB = *certDB;
- }
-
- /*
- * if we need to update, open the legacy database and
- * mark the handle as needing update.
- */
- if (needUpdate) {
- SDB *updateCert = NULL;
- SDB *updateKey = NULL;
- CK_RV crv2;
-
- crv2 = sftkdbCall_open(confdir, certPrefix, keyPrefix, 8, 3, flags,
- isFIPS, noCertDB ? NULL : &updateCert,
- noKeyDB ? NULL : &updateKey);
- if (crv2 == CKR_OK) {
- if (*certDB) {
- (*certDB)->update = updateCert;
- (*certDB)->updateID = updateID && *updateID
- ? PORT_Strdup(updateID) : NULL;
- updateCert->app_private = (*certDB);
- }
- if (*keyDB) {
- PRBool tokenRemoved = PR_FALSE;
- (*keyDB)->update = updateKey;
- (*keyDB)->updateID = updateID && *updateID ?
- PORT_Strdup(updateID) : NULL;
- updateKey->app_private = (*keyDB);
- (*keyDB)->updateDBIsInit = PR_TRUE;
- (*keyDB)->updateDBIsInit =
- (sftkdb_HasPasswordSet(*keyDB) == SECSuccess) ?
- PR_TRUE : PR_FALSE;
- /* if the password on the key db is NULL, kick off our update
- * chain of events */
- sftkdb_CheckPassword((*keyDB), "", &tokenRemoved);
- } else {
- /* we don't have a key DB, update the certificate DB now */
- sftkdb_Update(*certDB, NULL);
- }
- }
- }
-done:
- if (appName) {
- PORT_Free(appName);
- }
- return forceOpen ? CKR_OK : crv;
-}
-
-CK_RV
-sftkdb_Shutdown(void)
-{
- s_shutdown();
- sftkdbCall_Shutdown();
- return CKR_OK;
-}
-
diff --git a/security/nss/lib/softoken/sftkdb.h b/security/nss/lib/softoken/sftkdb.h
deleted file mode 100644
index beff9da6b..000000000
--- a/security/nss/lib/softoken/sftkdb.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "sftkdbt.h"
-#include "sdb.h"
-#include "pkcs11i.h"
-#include "pkcs11t.h"
-
-/* raw database stuff */
-CK_RV sftkdb_write(SFTKDBHandle *handle, SFTKObject *,CK_OBJECT_HANDLE *);
-CK_RV sftkdb_FindObjectsInit(SFTKDBHandle *sdb, const CK_ATTRIBUTE *template,
- CK_ULONG count, SDBFind **find);
-CK_RV sftkdb_FindObjects(SFTKDBHandle *sdb, SDBFind *find,
- CK_OBJECT_HANDLE *ids, int arraySize, CK_ULONG *count);
-CK_RV sftkdb_FindObjectsFinal(SFTKDBHandle *sdb, SDBFind *find);
-CK_RV sftkdb_GetAttributeValue(SFTKDBHandle *handle,
- CK_OBJECT_HANDLE object_id, CK_ATTRIBUTE *template, CK_ULONG count);
-CK_RV sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object,
- const CK_ATTRIBUTE *template, CK_ULONG count);
-CK_RV sftkdb_DestroyObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE object_id);
-CK_RV sftkdb_closeDB(SFTKDBHandle *handle);
-
-/* keydb functions */
-
-SECStatus sftkdb_PWIsInitialized(SFTKDBHandle *keydb);
-SECStatus sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw,
- PRBool *tokenRemoved);
-SECStatus sftkdb_PWCached(SFTKDBHandle *keydb);
-SECStatus sftkdb_HasPasswordSet(SFTKDBHandle *keydb);
-SECStatus sftkdb_ResetKeyDB(SFTKDBHandle *keydb);
-SECStatus sftkdb_ChangePassword(SFTKDBHandle *keydb,
- char *oldPin, char *newPin,
- PRBool *tokenRemoved);
-SECStatus sftkdb_ClearPassword(SFTKDBHandle *keydb);
-PRBool sftkdb_InUpdateMerge(SFTKDBHandle *keydb);
-PRBool sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb);
-const char *sftkdb_GetUpdateID(SFTKDBHandle *keydb);
-SECItem *sftkdb_GetUpdatePasswordKey(SFTKDBHandle *keydb);
-void sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *keydb);
-
-/* Utility functions */
-/*
- * OK there are now lots of options here, lets go through them all:
- *
- * configdir - base directory where all the cert, key, and module datbases live.
- * certPrefix - prefix added to the beginning of the cert database example: "
- * "https-server1-"
- * keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
- * secmodName - name of the security module database (usually "secmod.db").
- * readOnly - Boolean: true if the databases are to be openned read only.
- * nocertdb - Don't open the cert DB and key DB's, just initialize the
- * Volatile certdb.
- * nomoddb - Don't open the security module DB, just initialize the
- * PKCS #11 module.
- * forceOpen - Continue to force initializations even if the databases cannot
- * be opened.
- */
-CK_RV sftk_DBInit(const char *configdir, const char *certPrefix,
- const char *keyPrefix, const char *updatedir,
- const char *updCertPrefix, const char *updKeyPrefix,
- const char *updateID, PRBool readOnly, PRBool noCertDB,
- PRBool noKeyDB, PRBool forceOpen, PRBool isFIPS,
- SFTKDBHandle **certDB, SFTKDBHandle **keyDB);
-CK_RV sftkdb_Shutdown(void);
-
-SFTKDBHandle *sftk_getCertDB(SFTKSlot *slot);
-SFTKDBHandle *sftk_getKeyDB(SFTKSlot *slot);
-SFTKDBHandle *sftk_getDBForTokenObject(SFTKSlot *slot,
- CK_OBJECT_HANDLE objectID);
-void sftk_freeDB(SFTKDBHandle *certHandle);
diff --git a/security/nss/lib/softoken/sftkdbt.h b/security/nss/lib/softoken/sftkdbt.h
deleted file mode 100644
index 684393c9d..000000000
--- a/security/nss/lib/softoken/sftkdbt.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef SFTKDBT_H
-#define SFTKDBT_H 1
-typedef struct SFTKDBHandleStr SFTKDBHandle;
-
-#define SDB_MAX_META_DATA_LEN 256
-#define SDB_ULONG_SIZE 4
-
-#endif
diff --git a/security/nss/lib/softoken/sftkdbti.h b/security/nss/lib/softoken/sftkdbti.h
deleted file mode 100644
index eb777e496..000000000
--- a/security/nss/lib/softoken/sftkdbti.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef SFTKDBTI_H
-#define SFTKDBTI_H 1
-
-/*
- * private defines
- */
-struct SFTKDBHandleStr {
- SDB *db;
- PRInt32 ref;
- CK_OBJECT_HANDLE type;
- SECItem passwordKey;
- SECItem *newKey;
- SECItem *oldKey;
- SECItem *updatePasswordKey;
- PZLock *passwordLock;
- SFTKDBHandle *peerDB;
- SDB *update;
- char *updateID;
- PRBool updateDBIsInit;
-};
-
-#define SFTK_KEYDB_TYPE 0x40000000
-#define SFTK_CERTDB_TYPE 0x00000000
-#define SFTK_OBJ_TYPE_MASK 0xc0000000
-#define SFTK_OBJ_ID_MASK (~SFTK_OBJ_TYPE_MASK)
-#define SFTK_TOKEN_TYPE 0x80000000
-
-/* the following is the number of id's to handle on the stack at a time,
- * it's not an upper limit of IDS that can be stored in the database */
-#define SFTK_MAX_IDS 10
-
-#define SFTK_GET_SDB(handle) \
- ((handle)->update ? (handle)->update : (handle)->db)
-
-SECStatus sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText,
- SECItem **plainText);
-SECStatus sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey,
- SECItem *plainText, SECItem **cipherText);
-SECStatus sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey,
- CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE_TYPE attrType,
- SECItem *plainText, SECItem **sigText);
-SECStatus sftkdb_VerifyAttribute(SECItem *passKey,
- CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE_TYPE attrType,
- SECItem *plainText, SECItem *sigText);
-
-void sftk_ULong2SDBULong(unsigned char *data, CK_ULONG value);
-CK_RV sftkdb_Update(SFTKDBHandle *handle, SECItem *key);
-CK_RV sftkdb_PutAttributeSignature(SFTKDBHandle *handle,
- SDB *keyTarget, CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE_TYPE type, SECItem *signText);
-
-
-
-#endif
diff --git a/security/nss/lib/softoken/sftkhmac.c b/security/nss/lib/softoken/sftkhmac.c
deleted file mode 100644
index 3b55a0572..000000000
--- a/security/nss/lib/softoken/sftkhmac.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "seccomon.h"
-#include "secerr.h"
-#include "blapi.h"
-#include "pkcs11i.h"
-#include "softoken.h"
-#include "hmacct.h"
-
-/* MACMechanismToHash converts a PKCS#11 MAC mechanism into a freebl hash
- * type. */
-static HASH_HashType
-MACMechanismToHash(CK_MECHANISM_TYPE mech)
-{
- switch (mech) {
- case CKM_MD5_HMAC:
- case CKM_SSL3_MD5_MAC:
- return HASH_AlgMD5;
- case CKM_SHA_1_HMAC:
- case CKM_SSL3_SHA1_MAC:
- return HASH_AlgSHA1;
- case CKM_SHA224_HMAC:
- return HASH_AlgSHA224;
- case CKM_SHA256_HMAC:
- return HASH_AlgSHA256;
- case CKM_SHA384_HMAC:
- return HASH_AlgSHA384;
- case CKM_SHA512_HMAC:
- return HASH_AlgSHA512;
- }
- return HASH_AlgNULL;
-}
-
-static sftk_MACConstantTimeCtx *
-SetupMAC(CK_MECHANISM_PTR mech, SFTKObject *key)
-{
- CK_NSS_MAC_CONSTANT_TIME_PARAMS *params =
- (CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter;
- sftk_MACConstantTimeCtx *ctx;
- HASH_HashType alg;
- SFTKAttribute *keyval;
- unsigned char secret[sizeof(ctx->secret)];
- unsigned int secretLength;
-
- if (mech->ulParameterLen != sizeof(CK_NSS_MAC_CONSTANT_TIME_PARAMS)) {
- return NULL;
- }
-
- alg = MACMechanismToHash(params->macAlg);
- if (alg == HASH_AlgNULL) {
- return NULL;
- }
-
- keyval = sftk_FindAttribute(key,CKA_VALUE);
- if (keyval == NULL) {
- return NULL;
- }
- secretLength = keyval->attrib.ulValueLen;
- if (secretLength > sizeof(secret)) {
- sftk_FreeAttribute(keyval);
- return NULL;
- }
- memcpy(secret, keyval->attrib.pValue, secretLength);
- sftk_FreeAttribute(keyval);
-
- ctx = PORT_Alloc(sizeof(sftk_MACConstantTimeCtx));
- if (!ctx) {
- return NULL;
- }
-
- memcpy(ctx->secret, secret, secretLength);
- ctx->secretLength = secretLength;
- ctx->hash = HASH_GetRawHashObject(alg);
- ctx->totalLength = params->ulBodyTotalLen;
-
- return ctx;
-}
-
-sftk_MACConstantTimeCtx *
-sftk_HMACConstantTime_New(CK_MECHANISM_PTR mech, SFTKObject *key)
-{
- CK_NSS_MAC_CONSTANT_TIME_PARAMS *params =
- (CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter;
- sftk_MACConstantTimeCtx *ctx;
-
- if (params->ulHeaderLen > sizeof(ctx->header)) {
- return NULL;
- }
- ctx = SetupMAC(mech, key);
- if (!ctx) {
- return NULL;
- }
-
- ctx->headerLength = params->ulHeaderLen;
- memcpy(ctx->header, params->pHeader, params->ulHeaderLen);
- return ctx;
-}
-
-sftk_MACConstantTimeCtx *
-sftk_SSLv3MACConstantTime_New(CK_MECHANISM_PTR mech, SFTKObject *key)
-{
- CK_NSS_MAC_CONSTANT_TIME_PARAMS *params =
- (CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter;
- unsigned int padLength = 40, j;
- sftk_MACConstantTimeCtx *ctx;
-
- if (params->macAlg != CKM_SSL3_MD5_MAC &&
- params->macAlg != CKM_SSL3_SHA1_MAC) {
- return NULL;
- }
- ctx = SetupMAC(mech, key);
- if (!ctx) {
- return NULL;
- }
-
- if (params->macAlg == CKM_SSL3_MD5_MAC) {
- padLength = 48;
- }
-
- ctx->headerLength =
- ctx->secretLength +
- padLength +
- params->ulHeaderLen;
-
- if (ctx->headerLength > sizeof(ctx->header)) {
- goto loser;
- }
-
- j = 0;
- memcpy(&ctx->header[j], ctx->secret, ctx->secretLength);
- j += ctx->secretLength;
- memset(&ctx->header[j], 0x36, padLength);
- j += padLength;
- memcpy(&ctx->header[j], params->pHeader, params->ulHeaderLen);
-
- return ctx;
-
-loser:
- PORT_Free(ctx);
- return NULL;
-}
-
-void
-sftk_HMACConstantTime_Update(void *pctx, void *data, unsigned int len)
-{
- sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
- SECStatus rv = HMAC_ConstantTime(
- ctx->mac, NULL, sizeof(ctx->mac),
- ctx->hash,
- ctx->secret, ctx->secretLength,
- ctx->header, ctx->headerLength,
- data, len,
- ctx->totalLength);
- PORT_Assert(rv == SECSuccess);
-}
-
-void
-sftk_SSLv3MACConstantTime_Update(void *pctx, void *data, unsigned int len)
-{
- sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
- SECStatus rv = SSLv3_MAC_ConstantTime(
- ctx->mac, NULL, sizeof(ctx->mac),
- ctx->hash,
- ctx->secret, ctx->secretLength,
- ctx->header, ctx->headerLength,
- data, len,
- ctx->totalLength);
- PORT_Assert(rv == SECSuccess);
-}
-
-void
-sftk_MACConstantTime_EndHash(void *pctx, void *out, unsigned int *outLength,
- unsigned int maxLength)
-{
- const sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
- unsigned int toCopy = ctx->hash->length;
- if (toCopy > maxLength) {
- toCopy = maxLength;
- }
- memcpy(out, ctx->mac, toCopy);
- if (outLength) {
- *outLength = toCopy;
- }
-}
-
-void
-sftk_MACConstantTime_DestroyContext(void *pctx, PRBool free)
-{
- PORT_Free(pctx);
-}
diff --git a/security/nss/lib/softoken/sftkpars.c b/security/nss/lib/softoken/sftkpars.c
deleted file mode 100644
index 465cbcecc..000000000
--- a/security/nss/lib/softoken/sftkpars.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * The following code handles the storage of PKCS 11 modules used by the
- * NSS. This file is written to abstract away how the modules are
- * stored so we can deside that later.
- */
-#include "pkcs11i.h"
-#include "sdb.h"
-#include "prprf.h"
-#include "prenv.h"
-#include "utilpars.h"
-
-#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; }
-
-static void
-sftk_parseTokenFlags(char *tmp, sftk_token_parameters *parsed) {
- parsed->readOnly = NSSUTIL_ArgHasFlag("flags","readOnly",tmp);
- parsed->noCertDB = NSSUTIL_ArgHasFlag("flags","noCertDB",tmp);
- parsed->noKeyDB = NSSUTIL_ArgHasFlag("flags","noKeyDB",tmp);
- parsed->forceOpen = NSSUTIL_ArgHasFlag("flags","forceOpen",tmp);
- parsed->pwRequired = NSSUTIL_ArgHasFlag("flags","passwordRequired",tmp);
- parsed->optimizeSpace = NSSUTIL_ArgHasFlag("flags","optimizeSpace",tmp);
- return;
-}
-
-static void
-sftk_parseFlags(char *tmp, sftk_parameters *parsed) {
- parsed->noModDB = NSSUTIL_ArgHasFlag("flags","noModDB",tmp);
- parsed->readOnly = NSSUTIL_ArgHasFlag("flags","readOnly",tmp);
- /* keep legacy interface working */
- parsed->noCertDB = NSSUTIL_ArgHasFlag("flags","noCertDB",tmp);
- parsed->forceOpen = NSSUTIL_ArgHasFlag("flags","forceOpen",tmp);
- parsed->pwRequired = NSSUTIL_ArgHasFlag("flags","passwordRequired",tmp);
- parsed->optimizeSpace = NSSUTIL_ArgHasFlag("flags","optimizeSpace",tmp);
- return;
-}
-
-static CK_RV
-sftk_parseTokenParameters(char *param, sftk_token_parameters *parsed)
-{
- int next;
- char *tmp = NULL;
- char *index;
- index = NSSUTIL_ArgStrip(param);
-
- while (*index) {
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->updatedir,"updateDir=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->updCertPrefix,
- "updateCertPrefix=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->updKeyPrefix,
- "updateKeyPrefix=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->updateID,"updateID=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->certPrefix,"certPrefix=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyPrefix=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->tokdes,"tokenDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->updtokdes,
- "updateTokenDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->slotdes,"slotDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,tmp,"minPWLen=",
- if(tmp) { parsed->minPW=atoi(tmp); PORT_Free(tmp); tmp = NULL; })
- NSSUTIL_HANDLE_STRING_ARG(index,tmp,"flags=",
- if(tmp) { sftk_parseTokenFlags(param,parsed); PORT_Free(tmp);
- tmp = NULL; })
- NSSUTIL_HANDLE_FINAL_ARG(index)
- }
- return CKR_OK;
-}
-
-static void
-sftk_parseTokens(char *tokenParams, sftk_parameters *parsed)
-{
- char *tokenIndex;
- sftk_token_parameters *tokens = NULL;
- int i=0,count = 0,next;
-
- if ((tokenParams == NULL) || (*tokenParams == 0)) return;
-
- /* first count the number of slots */
- for (tokenIndex = NSSUTIL_ArgStrip(tokenParams); *tokenIndex;
- tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) {
- count++;
- }
-
- /* get the data structures */
- tokens = (sftk_token_parameters *)
- PORT_ZAlloc(count*sizeof(sftk_token_parameters));
- if (tokens == NULL) return;
-
- for (tokenIndex = NSSUTIL_ArgStrip(tokenParams), i = 0;
- *tokenIndex && i < count ; i++ ) {
- char *name;
- name = NSSUTIL_ArgGetLabel(tokenIndex,&next);
- tokenIndex += next;
-
- tokens[i].slotID = NSSUTIL_ArgDecodeNumber(name);
- tokens[i].readOnly = PR_FALSE;
- tokens[i].noCertDB = PR_FALSE;
- tokens[i].noKeyDB = PR_FALSE;
- if (!NSSUTIL_ArgIsBlank(*tokenIndex)) {
- char *args = NSSUTIL_ArgFetchValue(tokenIndex,&next);
- tokenIndex += next;
- if (args) {
- sftk_parseTokenParameters(args,&tokens[i]);
- PORT_Free(args);
- }
- }
- if (name) PORT_Free(name);
- tokenIndex = NSSUTIL_ArgStrip(tokenIndex);
- }
- parsed->token_count = i;
- parsed->tokens = tokens;
- return;
-}
-
-CK_RV
-sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
-{
- int next;
- char *tmp = NULL;
- char *index;
- char *certPrefix = NULL, *keyPrefix = NULL;
- char *tokdes = NULL, *ptokdes = NULL, *pupdtokdes = NULL;
- char *slotdes = NULL, *pslotdes = NULL;
- char *fslotdes = NULL, *ftokdes = NULL;
- char *minPW = NULL;
- index = NSSUTIL_ArgStrip(param);
-
- PORT_Memset(parsed, 0, sizeof(sftk_parameters));
-
- while (*index) {
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->updatedir,"updateDir=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->updateID,"updateID=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->secmodName,"secmod=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->man,"manufacturerID=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,parsed->libdes,"libraryDescription=",;)
- /* constructed values, used so legacy interfaces still work */
- NSSUTIL_HANDLE_STRING_ARG(index,certPrefix,"certPrefix=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,keyPrefix,"keyPrefix=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,tokdes,"cryptoTokenDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,ptokdes,"dbTokenDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,slotdes,"cryptoSlotDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,pslotdes,"dbSlotDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,fslotdes,"FIPSSlotDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,ftokdes,"FIPSTokenDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,pupdtokdes, "updateTokenDescription=",;)
- NSSUTIL_HANDLE_STRING_ARG(index,minPW,"minPWLen=",;)
-
- NSSUTIL_HANDLE_STRING_ARG(index,tmp,"flags=",
- if(tmp) { sftk_parseFlags(param,parsed); PORT_Free(tmp);
- tmp = NULL; })
- NSSUTIL_HANDLE_STRING_ARG(index,tmp,"tokens=",
- if(tmp) { sftk_parseTokens(tmp,parsed); PORT_Free(tmp); tmp = NULL; })
- NSSUTIL_HANDLE_FINAL_ARG(index)
- }
- if (parsed->tokens == NULL) {
- int count = isFIPS ? 1 : 2;
- int index = count-1;
- sftk_token_parameters *tokens = NULL;
-
- tokens = (sftk_token_parameters *)
- PORT_ZAlloc(count*sizeof(sftk_token_parameters));
- if (tokens == NULL) {
- goto loser;
- }
- parsed->tokens = tokens;
- parsed->token_count = count;
- tokens[index].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID;
- tokens[index].certPrefix = certPrefix;
- tokens[index].keyPrefix = keyPrefix;
- tokens[index].minPW = minPW ? atoi(minPW) : 0;
- tokens[index].readOnly = parsed->readOnly;
- tokens[index].noCertDB = parsed->noCertDB;
- tokens[index].noKeyDB = parsed->noCertDB;
- tokens[index].forceOpen = parsed->forceOpen;
- tokens[index].pwRequired = parsed->pwRequired;
- tokens[index].optimizeSpace = parsed->optimizeSpace;
- tokens[0].optimizeSpace = parsed->optimizeSpace;
- certPrefix = NULL;
- keyPrefix = NULL;
- if (isFIPS) {
- tokens[index].tokdes = ftokdes;
- tokens[index].updtokdes = pupdtokdes;
- tokens[index].slotdes = fslotdes;
- fslotdes = NULL;
- ftokdes = NULL;
- pupdtokdes = NULL;
- } else {
- tokens[index].tokdes = ptokdes;
- tokens[index].updtokdes = pupdtokdes;
- tokens[index].slotdes = pslotdes;
- tokens[0].slotID = NETSCAPE_SLOT_ID;
- tokens[0].tokdes = tokdes;
- tokens[0].slotdes = slotdes;
- tokens[0].noCertDB = PR_TRUE;
- tokens[0].noKeyDB = PR_TRUE;
- pupdtokdes = NULL;
- ptokdes = NULL;
- pslotdes = NULL;
- tokdes = NULL;
- slotdes = NULL;
- }
- }
-
-loser:
- FREE_CLEAR(certPrefix);
- FREE_CLEAR(keyPrefix);
- FREE_CLEAR(tokdes);
- FREE_CLEAR(ptokdes);
- FREE_CLEAR(pupdtokdes);
- FREE_CLEAR(slotdes);
- FREE_CLEAR(pslotdes);
- FREE_CLEAR(fslotdes);
- FREE_CLEAR(ftokdes);
- FREE_CLEAR(minPW);
- return CKR_OK;
-}
-
-void
-sftk_freeParams(sftk_parameters *params)
-{
- int i;
-
- for (i=0; i < params->token_count; i++) {
- FREE_CLEAR(params->tokens[i].configdir);
- FREE_CLEAR(params->tokens[i].certPrefix);
- FREE_CLEAR(params->tokens[i].keyPrefix);
- FREE_CLEAR(params->tokens[i].tokdes);
- FREE_CLEAR(params->tokens[i].slotdes);
- FREE_CLEAR(params->tokens[i].updatedir);
- FREE_CLEAR(params->tokens[i].updCertPrefix);
- FREE_CLEAR(params->tokens[i].updKeyPrefix);
- FREE_CLEAR(params->tokens[i].updateID);
- FREE_CLEAR(params->tokens[i].updtokdes);
- }
-
- FREE_CLEAR(params->configdir);
- FREE_CLEAR(params->secmodName);
- FREE_CLEAR(params->man);
- FREE_CLEAR(params->libdes);
- FREE_CLEAR(params->tokens);
- FREE_CLEAR(params->updatedir);
- FREE_CLEAR(params->updateID);
-}
-
diff --git a/security/nss/lib/softoken/sftkpars.h b/security/nss/lib/softoken/sftkpars.h
deleted file mode 100644
index 6178dff40..000000000
--- a/security/nss/lib/softoken/sftkpars.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "pkcs11i.h"
-#include "sftkdbt.h"
-
-/* parsing functions */
-char * sftk_argFetchValue(char *string, int *pcount);
-char * sftk_getSecmodName(char *param, SDBType *dbType, char **appName, char **filename,PRBool *rw);
-char *sftk_argStrip(char *c);
-CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS);
-void sftk_freeParams(sftk_parameters *params);
-const char *sftk_EvaluateConfigDir(const char *configdir, SDBType *dbType, char **app);
-char * sftk_argGetParamValue(char *paramName,char *parameters);
-
-
-
diff --git a/security/nss/lib/softoken/sftkpwd.c b/security/nss/lib/softoken/sftkpwd.c
deleted file mode 100644
index 4c9ac172b..000000000
--- a/security/nss/lib/softoken/sftkpwd.c
+++ /dev/null
@@ -1,1275 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * The following code handles the storage of PKCS 11 modules used by the
- * NSS. For the rest of NSS, only one kind of database handle exists:
- *
- * SFTKDBHandle
- *
- * There is one SFTKDBHandle for the each key database and one for each cert
- * database. These databases are opened as associated pairs, one pair per
- * slot. SFTKDBHandles are reference counted objects.
- *
- * Each SFTKDBHandle points to a low level database handle (SDB). This handle
- * represents the underlying physical database. These objects are not
- * reference counted, an are 'owned' by their respective SFTKDBHandles.
- *
- *
- */
-#include "sftkdb.h"
-#include "sftkdbti.h"
-#include "pkcs11t.h"
-#include "pkcs11i.h"
-#include "sdb.h"
-#include "prprf.h"
-#include "secasn1.h"
-#include "pratom.h"
-#include "blapi.h"
-#include "secoid.h"
-#include "lowpbe.h"
-#include "secdert.h"
-#include "prsystem.h"
-#include "lgglue.h"
-#include "secerr.h"
-#include "softoken.h"
-
-/******************************************************************
- *
- * Key DB password handling functions
- *
- * These functions manage the key db password (set, reset, initialize, use).
- *
- * The key is managed on 'this side' of the database. All private data is
- * encrypted before it is sent to the database itself. Besides PBE's, the
- * database management code can also mix in various fixed keys so the data
- * in the database is no longer considered 'plain text'.
- */
-
-
-/* take string password and turn it into a key. The key is dependent
- * on a global salt entry acquired from the database. This salted
- * value will be based to a pkcs5 pbe function before it is used
- * in an actual encryption */
-static SECStatus
-sftkdb_passwordToKey(SFTKDBHandle *keydb, SECItem *salt,
- const char *pw, SECItem *key)
-{
- SHA1Context *cx = NULL;
- SECStatus rv = SECFailure;
-
- key->data = PORT_Alloc(SHA1_LENGTH);
- if (key->data == NULL) {
- goto loser;
- }
- key->len = SHA1_LENGTH;
-
- cx = SHA1_NewContext();
- if ( cx == NULL) {
- goto loser;
- }
- SHA1_Begin(cx);
- if (salt && salt->data ) {
- SHA1_Update(cx, salt->data, salt->len);
- }
- SHA1_Update(cx, (unsigned char *)pw, PORT_Strlen(pw));
- SHA1_End(cx, key->data, &key->len, key->len);
- rv = SECSuccess;
-
-loser:
- if (cx) {
- SHA1_DestroyContext(cx, PR_TRUE);
- }
- if (rv != SECSuccess) {
- if (key->data != NULL) {
- PORT_ZFree(key->data,key->len);
- }
- key->data = NULL;
- }
- return rv;
-}
-
-/*
- * Cipher text stored in the database contains 3 elements:
- * 1) an identifier describing the encryption algorithm.
- * 2) an entry specific salt value.
- * 3) the encrypted value.
- *
- * The following data structure represents the encrypted data in a decoded
- * (but still encrypted) form.
- */
-typedef struct sftkCipherValueStr sftkCipherValue;
-struct sftkCipherValueStr {
- PLArenaPool *arena;
- SECOidTag alg;
- NSSPKCS5PBEParameter *param;
- SECItem salt;
- SECItem value;
-};
-
-#define SFTK_CIPHERTEXT_VERSION 3
-
-struct SFTKDBEncryptedDataInfoStr {
- SECAlgorithmID algorithm;
- SECItem encryptedData;
-};
-typedef struct SFTKDBEncryptedDataInfoStr SFTKDBEncryptedDataInfo;
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-const SEC_ASN1Template sftkdb_EncryptedDataInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SFTKDBEncryptedDataInfo) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN ,
- offsetof(SFTKDBEncryptedDataInfo,algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SFTKDBEncryptedDataInfo,encryptedData) },
- { 0 }
-};
-
-/*
- * This parses the cipherText into cipher value. NOTE: cipherValue will point
- * to data in cipherText, if cipherText is freed, cipherValue will be invalid.
- */
-static SECStatus
-sftkdb_decodeCipherText(SECItem *cipherText, sftkCipherValue *cipherValue)
-{
- PLArenaPool *arena = NULL;
- SFTKDBEncryptedDataInfo edi;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return SECFailure;
- }
- cipherValue->arena = NULL;
- cipherValue->param = NULL;
-
- rv = SEC_QuickDERDecodeItem(arena, &edi, sftkdb_EncryptedDataInfoTemplate,
- cipherText);
- if (rv != SECSuccess) {
- goto loser;
- }
- cipherValue->alg = SECOID_GetAlgorithmTag(&edi.algorithm);
- cipherValue->param = nsspkcs5_AlgidToParam(&edi.algorithm);
- if (cipherValue->param == NULL) {
- goto loser;
- }
- cipherValue->value = edi.encryptedData;
- cipherValue->arena = arena;
-
- return SECSuccess;
-loser:
- if (cipherValue->param) {
- nsspkcs5_DestroyPBEParameter(cipherValue->param);
- cipherValue->param = NULL;
- }
- if (arena) {
- PORT_FreeArena(arena,PR_FALSE);
- }
- return SECFailure;
-}
-
-
-
-/*
- * unlike decode, Encode actually allocates a SECItem the caller must free
- * The caller can pass an optional arena to to indicate where to place
- * the resultant cipherText.
- */
-static SECStatus
-sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue,
- SECItem **cipherText)
-{
- SFTKDBEncryptedDataInfo edi;
- SECAlgorithmID *algid;
- SECStatus rv;
- PLArenaPool *localArena = NULL;
-
-
- localArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (localArena == NULL) {
- return SECFailure;
- }
-
- algid = nsspkcs5_CreateAlgorithmID(localArena, cipherValue->alg,
- cipherValue->param);
- if (algid == NULL) {
- rv = SECFailure;
- goto loser;
- }
- rv = SECOID_CopyAlgorithmID(localArena, &edi.algorithm, algid);
- SECOID_DestroyAlgorithmID(algid, PR_TRUE);
- if (rv != SECSuccess) {
- goto loser;
- }
- edi.encryptedData = cipherValue->value;
-
- *cipherText = SEC_ASN1EncodeItem(arena, NULL, &edi,
- sftkdb_EncryptedDataInfoTemplate);
- if (*cipherText == NULL) {
- rv = SECFailure;
- }
-
-loser:
- if (localArena) {
- PORT_FreeArena(localArena,PR_FALSE);
- }
-
- return rv;
-}
-
-
-/*
- * Use our key to decode a cipherText block from the database.
- *
- * plain text is allocated by nsspkcs5_CipherData and must be freed
- * with SECITEM_FreeItem by the caller.
- */
-SECStatus
-sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plain)
-{
- SECStatus rv;
- sftkCipherValue cipherValue;
-
- /* First get the cipher type */
- rv = sftkdb_decodeCipherText(cipherText, &cipherValue);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- *plain = nsspkcs5_CipherData(cipherValue.param, passKey, &cipherValue.value,
- PR_FALSE, NULL);
- if (*plain == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
-loser:
- if (cipherValue.param) {
- nsspkcs5_DestroyPBEParameter(cipherValue.param);
- }
- if (cipherValue.arena) {
- PORT_FreeArena(cipherValue.arena,PR_FALSE);
- }
- return rv;
-}
-
-/*
- * encrypt a block. This function returned the encrypted ciphertext which
- * the caller must free. If the caller provides an arena, cipherText will
- * be allocated out of that arena. This also generated the per entry
- * salt automatically.
- */
-SECStatus
-sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey,
- SECItem *plainText, SECItem **cipherText)
-{
- SECStatus rv;
- sftkCipherValue cipherValue;
- SECItem *cipher = NULL;
- NSSPKCS5PBEParameter *param = NULL;
- unsigned char saltData[HASH_LENGTH_MAX];
-
- cipherValue.alg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
- cipherValue.salt.len = SHA1_LENGTH;
- cipherValue.salt.data = saltData;
- RNG_GenerateGlobalRandomBytes(saltData,cipherValue.salt.len);
-
- param = nsspkcs5_NewParam(cipherValue.alg, &cipherValue.salt, 1);
- if (param == NULL) {
- rv = SECFailure;
- goto loser;
- }
- cipher = nsspkcs5_CipherData(param, passKey, plainText, PR_TRUE, NULL);
- if (cipher == NULL) {
- rv = SECFailure;
- goto loser;
- }
- cipherValue.value = *cipher;
- cipherValue.param = param;
-
- rv = sftkdb_encodeCipherText(arena, &cipherValue, cipherText);
- if (rv != SECSuccess) {
- goto loser;
- }
-
-loser:
- if (cipher) {
- SECITEM_FreeItem(cipher, PR_TRUE);
- }
- if (param) {
- nsspkcs5_DestroyPBEParameter(param);
- }
- return rv;
-}
-
-/*
- * use the password and the pbe parameters to generate an HMAC for the
- * given plain text data. This is used by sftkdb_VerifyAttribute and
- * sftkdb_SignAttribute. Signature is returned in signData. The caller
- * must preallocate the space in the secitem.
- */
-static SECStatus
-sftkdb_pbehash(SECOidTag sigOid, SECItem *passKey,
- NSSPKCS5PBEParameter *param,
- CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType,
- SECItem *plainText, SECItem *signData)
-{
- SECStatus rv = SECFailure;
- SECItem *key = NULL;
- HMACContext *hashCx = NULL;
- HASH_HashType hashType = HASH_AlgNULL;
- const SECHashObject *hashObj;
- unsigned char addressData[SDB_ULONG_SIZE];
-
- hashType = HASH_FromHMACOid(param->encAlg);
- if (hashType == HASH_AlgNULL) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
-
- hashObj = HASH_GetRawHashObject(hashType);
- if (hashObj == NULL) {
- goto loser;
- }
-
- key = nsspkcs5_ComputeKeyAndIV(param, passKey, NULL, PR_FALSE);
- if (!key) {
- goto loser;
- }
-
- hashCx = HMAC_Create(hashObj, key->data, key->len, PR_TRUE);
- if (!hashCx) {
- goto loser;
- }
- HMAC_Begin(hashCx);
- /* Tie this value to a particular object. This is most important for
- * the trust attributes, where and attacker could copy a value for
- * 'validCA' from another cert in the database */
- sftk_ULong2SDBULong(addressData, objectID);
- HMAC_Update(hashCx, addressData, SDB_ULONG_SIZE);
- sftk_ULong2SDBULong(addressData, attrType);
- HMAC_Update(hashCx, addressData, SDB_ULONG_SIZE);
-
- HMAC_Update(hashCx, plainText->data, plainText->len);
- rv = HMAC_Finish(hashCx, signData->data, &signData->len, signData->len);
-
-loser:
- if (hashCx) {
- HMAC_Destroy(hashCx, PR_TRUE);
- }
- if (key) {
- SECITEM_FreeItem(key,PR_TRUE);
- }
- return rv;
-}
-
-/*
- * Use our key to verify a signText block from the database matches
- * the plainText from the database. The signText is a PKCS 5 v2 pbe.
- * plainText is the plainText of the attribute.
- */
-SECStatus
-sftkdb_VerifyAttribute(SECItem *passKey, CK_OBJECT_HANDLE objectID,
- CK_ATTRIBUTE_TYPE attrType,
- SECItem *plainText, SECItem *signText)
-{
- SECStatus rv;
- sftkCipherValue signValue;
- SECItem signature;
- unsigned char signData[HASH_LENGTH_MAX];
-
-
- /* First get the cipher type */
- rv = sftkdb_decodeCipherText(signText, &signValue);
- if (rv != SECSuccess) {
- goto loser;
- }
- signature.data = signData;
- signature.len = sizeof(signData);
-
- rv = sftkdb_pbehash(signValue.alg, passKey, signValue.param,
- objectID, attrType, plainText, &signature);
- if (rv != SECSuccess) {
- goto loser;
- }
- if (SECITEM_CompareItem(&signValue.value,&signature) != 0) {
- PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
- rv = SECFailure;
- }
-
-loser:
- if (signValue.param) {
- nsspkcs5_DestroyPBEParameter(signValue.param);
- }
- if (signValue.arena) {
- PORT_FreeArena(signValue.arena,PR_FALSE);
- }
- return rv;
-}
-
-/*
- * Use our key to create a signText block the plain text of an
- * attribute. The signText is a PKCS 5 v2 pbe.
- */
-SECStatus
-sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey,
- CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType,
- SECItem *plainText, SECItem **signature)
-{
- SECStatus rv;
- sftkCipherValue signValue;
- NSSPKCS5PBEParameter *param = NULL;
- unsigned char saltData[HASH_LENGTH_MAX];
- unsigned char signData[HASH_LENGTH_MAX];
- SECOidTag hmacAlg = SEC_OID_HMAC_SHA256; /* hash for authentication */
- SECOidTag prfAlg = SEC_OID_HMAC_SHA256; /* hash for pb key generation */
- HASH_HashType prfType;
- unsigned int hmacLength;
- unsigned int prfLength;
-
- /* this code allows us to fetch the lengths and hashes on the fly
- * by simply changing the OID above */
- prfType = HASH_FromHMACOid(prfAlg);
- PORT_Assert(prfType != HASH_AlgNULL);
- prfLength = HASH_GetRawHashObject(prfType)->length;
- PORT_Assert(prfLength <= HASH_LENGTH_MAX);
-
- hmacLength = HASH_GetRawHashObject(HASH_FromHMACOid(hmacAlg))->length;
- PORT_Assert(hmacLength <= HASH_LENGTH_MAX);
-
- /* initialize our CipherValue structure */
- signValue.alg = SEC_OID_PKCS5_PBMAC1;
- signValue.salt.len = prfLength;
- signValue.salt.data = saltData;
- signValue.value.data = signData;
- signValue.value.len = hmacLength;
- RNG_GenerateGlobalRandomBytes(saltData,prfLength);
-
- /* initialize our pkcs5 parameter */
- param = nsspkcs5_NewParam(signValue.alg, &signValue.salt, 1);
- if (param == NULL) {
- rv = SECFailure;
- goto loser;
- }
- param->keyID = pbeBitGenIntegrityKey;
- /* set the PKCS 5 v2 parameters, not extractable from the
- * data passed into nsspkcs5_NewParam */
- param->encAlg = hmacAlg;
- param->hashType = prfType;
- param->keyLen = hmacLength;
- rv = SECOID_SetAlgorithmID(param->poolp, &param->prfAlg, prfAlg, NULL);
- if (rv != SECSuccess) {
- goto loser;
- }
-
-
- /* calculate the mac */
- rv = sftkdb_pbehash(signValue.alg, passKey, param, objectID, attrType,
- plainText, &signValue.value);
- if (rv != SECSuccess) {
- goto loser;
- }
- signValue.param = param;
-
- /* write it out */
- rv = sftkdb_encodeCipherText(arena, &signValue, signature);
- if (rv != SECSuccess) {
- goto loser;
- }
-
-loser:
- if (param) {
- nsspkcs5_DestroyPBEParameter(param);
- }
- return rv;
-}
-
-/*
- * safely swith the passed in key for the one caches in the keydb handle
- *
- * A key attached to the handle tells us the the token is logged in.
- * We can used the key attached to the handle in sftkdb_EncryptAttribute
- * and sftkdb_DecryptAttribute calls.
- */
-static void
-sftkdb_switchKeys(SFTKDBHandle *keydb, SECItem *passKey)
-{
- unsigned char *data;
- int len;
-
- if (keydb->passwordLock == NULL) {
- PORT_Assert(keydb->type != SFTK_KEYDB_TYPE);
- return;
- }
-
- /* an atomic pointer set would be nice */
- SKIP_AFTER_FORK(PZ_Lock(keydb->passwordLock));
- data = keydb->passwordKey.data;
- len = keydb->passwordKey.len;
- keydb->passwordKey.data = passKey->data;
- keydb->passwordKey.len = passKey->len;
- passKey->data = data;
- passKey->len = len;
- SKIP_AFTER_FORK(PZ_Unlock(keydb->passwordLock));
-}
-
-/*
- * returns true if we are in a middle of a merge style update.
- */
-PRBool
-sftkdb_InUpdateMerge(SFTKDBHandle *keydb)
-{
- return keydb->updateID ? PR_TRUE : PR_FALSE;
-}
-
-/*
- * returns true if we are looking for the password for the user's old source
- * database as part of a merge style update.
- */
-PRBool
-sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb)
-{
- if (!sftkdb_InUpdateMerge(keydb)) {
- return PR_FALSE;
- }
- if (keydb->updateDBIsInit && !keydb->updatePasswordKey) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-/*
- * fetch an update password key from a handle.
- */
-SECItem *
-sftkdb_GetUpdatePasswordKey(SFTKDBHandle *handle)
-{
- SECItem *key = NULL;
-
- /* if we're a cert db, fetch it from our peer key db */
- if (handle->type == SFTK_CERTDB_TYPE) {
- handle = handle->peerDB;
- }
-
- /* don't have one */
- if (!handle) {
- return NULL;
- }
-
- PZ_Lock(handle->passwordLock);
- if (handle->updatePasswordKey) {
- key = SECITEM_DupItem(handle->updatePasswordKey);
- }
- PZ_Unlock(handle->passwordLock);
-
- return key;
-}
-
-/*
- * free the update password key from a handle.
- */
-void
-sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *handle)
-{
- SECItem *key = NULL;
-
- /* don't have one */
- if (!handle) {
- return;
- }
-
- /* if we're a cert db, we don't have one */
- if (handle->type == SFTK_CERTDB_TYPE) {
- return;
- }
-
- PZ_Lock(handle->passwordLock);
- if (handle->updatePasswordKey) {
- key = handle->updatePasswordKey;
- handle->updatePasswordKey = NULL;
- }
- PZ_Unlock(handle->passwordLock);
-
- if (key) {
- SECITEM_ZfreeItem(key, PR_TRUE);
- }
-
- return;
-}
-
-/*
- * what password db we use depends heavily on the update state machine
- *
- * 1) no update db, return the normal database.
- * 2) update db and no merge return the update db.
- * 3) update db and in merge:
- * return the update db if we need the update db's password,
- * otherwise return our normal datbase.
- */
-static SDB *
-sftk_getPWSDB(SFTKDBHandle *keydb)
-{
- if (!keydb->update) {
- return keydb->db;
- }
- if (!sftkdb_InUpdateMerge(keydb)) {
- return keydb->update;
- }
- if (sftkdb_NeedUpdateDBPassword(keydb)) {
- return keydb->update;
- }
- return keydb->db;
-}
-
-/*
- * return success if we have a valid password entry.
- * This is will show up outside of PKCS #11 as CKF_USER_PIN_INIT
- * in the token flags.
- */
-SECStatus
-sftkdb_HasPasswordSet(SFTKDBHandle *keydb)
-{
- SECItem salt, value;
- unsigned char saltData[SDB_MAX_META_DATA_LEN];
- unsigned char valueData[SDB_MAX_META_DATA_LEN];
- CK_RV crv;
- SDB *db;
-
- if (keydb == NULL) {
- return SECFailure;
- }
-
- db = sftk_getPWSDB(keydb);
- if (db == NULL) {
- return SECFailure;
- }
-
- salt.data = saltData;
- salt.len = sizeof(saltData);
- value.data = valueData;
- value.len = sizeof(valueData);
- crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);
-
- /* If no password is set, we can update right away */
- if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update
- && crv != CKR_OK) {
- /* update the peer certdb if it exists */
- if (keydb->peerDB) {
- sftkdb_Update(keydb->peerDB, NULL);
- }
- sftkdb_Update(keydb, NULL);
- }
- return (crv == CKR_OK) ? SECSuccess : SECFailure;
-}
-
-#define SFTK_PW_CHECK_STRING "password-check"
-#define SFTK_PW_CHECK_LEN 14
-
-/*
- * check if the supplied password is valid
- */
-SECStatus
-sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved)
-{
- SECStatus rv;
- SECItem salt, value;
- unsigned char saltData[SDB_MAX_META_DATA_LEN];
- unsigned char valueData[SDB_MAX_META_DATA_LEN];
- SECItem key;
- SECItem *result = NULL;
- SDB *db;
- CK_RV crv;
-
- if (keydb == NULL) {
- return SECFailure;
- }
-
- db = sftk_getPWSDB(keydb);
- if (db == NULL) {
- return SECFailure;
- }
-
- key.data = NULL;
- key.len = 0;
-
- if (pw == NULL) pw="";
-
- /* get the entry from the database */
- salt.data = saltData;
- salt.len = sizeof(saltData);
- value.data = valueData;
- value.len = sizeof(valueData);
- crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);
- if (crv != CKR_OK) {
- rv = SECFailure;
- goto done;
- }
-
- /* get our intermediate key based on the entry salt value */
- rv = sftkdb_passwordToKey(keydb, &salt, pw, &key);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* decrypt the entry value */
- rv = sftkdb_DecryptAttribute(&key, &value, &result);
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* if it's what we expect, update our key in the database handle and
- * return Success */
- if ((result->len == SFTK_PW_CHECK_LEN) &&
- PORT_Memcmp(result->data, SFTK_PW_CHECK_STRING, SFTK_PW_CHECK_LEN) == 0){
- /*
- * We have a password, now lets handle any potential update cases..
- *
- * First, the normal case: no update. In this case we only need the
- * the password for our only DB, which we now have, we switch
- * the keys and fall through.
- * Second regular (non-merge) update: The target DB does not yet have
- * a password initialized, we now have the password for the source DB,
- * so we can switch the keys and simply update the target database.
- * Merge update case: This one is trickier.
- * 1) If we need the source DB password, then we just got it here.
- * We need to save that password,
- * then we need to check to see if we need or have the target
- * database password.
- * If we have it (it's the same as the source), or don't need
- * it (it's not set or is ""), we can start the update now.
- * If we don't have it, we need the application to get it from
- * the user. Clear our sessions out to simulate a token
- * removal. C_GetTokenInfo will change the token description
- * and the token will still appear to be logged out.
- * 2) If we already have the source DB password, this password is
- * for the target database. We can now move forward with the
- * update, as we now have both required passwords.
- *
- */
- PZ_Lock(keydb->passwordLock);
- if (sftkdb_NeedUpdateDBPassword(keydb)) {
- /* Squirrel this special key away.
- * This has the side effect of turning sftkdb_NeedLegacyPW off,
- * as well as changing which database is returned from
- * SFTK_GET_PW_DB (thus effecting both sftkdb_CheckPassword()
- * and sftkdb_HasPasswordSet()) */
- keydb->updatePasswordKey = SECITEM_DupItem(&key);
- PZ_Unlock(keydb->passwordLock);
- if (keydb->updatePasswordKey == NULL) {
- /* PORT_Error set by SECITEM_DupItem */
- rv = SECFailure;
- goto done;
- }
-
- /* Simulate a token removal -- we need to do this any
- * any case at this point so the token name is correct. */
- *tokenRemoved = PR_TRUE;
-
- /*
- * OK, we got the update DB password, see if we need a password
- * for the target...
- */
- if (sftkdb_HasPasswordSet(keydb) == SECSuccess) {
- /* We have a password, do we know what the password is?
- * check 1) for the password the user supplied for the
- * update DB,
- * and 2) for the null password.
- *
- * RECURSION NOTE: we are calling ourselves here. This means
- * any updates, switchKeys, etc will have been completed
- * if these functions return successfully, in those cases
- * just exit returning Success. We don't recurse infinitely
- * because we are making this call from a NeedUpdateDBPassword
- * block and we've already set that update password at this
- * point. */
- rv = sftkdb_CheckPassword(keydb, pw, tokenRemoved);
- if (rv == SECSuccess) {
- /* source and target databases have the same password, we
- * are good to go */
- goto done;
- }
- sftkdb_CheckPassword(keydb, "", tokenRemoved);
-
- /*
- * Important 'NULL' code here. At this point either we
- * succeeded in logging in with "" or we didn't.
- *
- * If we did succeed at login, our machine state will be set
- * to logged in appropriately. The application will find that
- * it's logged in as soon as it opens a new session. We have
- * also completed the update. Life is good.
- *
- * If we did not succeed, well the user still successfully
- * logged into the update database, since we faked the token
- * removal it's just like the user logged into his smart card
- * then removed it. the actual login work, so we report that
- * success back to the user, but we won't actually be
- * logged in. The application will find this out when it
- * checks it's login state, thus triggering another password
- * prompt so we can get the real target DB password.
- *
- * summary, we exit from here with SECSuccess no matter what.
- */
- rv = SECSuccess;
- goto done;
- } else {
- /* there is no password, just fall through to update.
- * update will write the source DB's password record
- * into the target DB just like it would in a non-merge
- * update case. */
- }
- } else {
- PZ_Unlock(keydb->passwordLock);
- }
- /* load the keys, so the keydb can parse it's key set */
- sftkdb_switchKeys(keydb, &key);
-
- /* we need to update, do it now */
- if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update) {
- /* update the peer certdb if it exists */
- if (keydb->peerDB) {
- sftkdb_Update(keydb->peerDB, &key);
- }
- sftkdb_Update(keydb, &key);
- }
- } else {
- rv = SECFailure;
- /*PORT_SetError( bad password); */
- }
-
-done:
- if (key.data) {
- PORT_ZFree(key.data,key.len);
- }
- if (result) {
- SECITEM_FreeItem(result,PR_TRUE);
- }
- return rv;
-}
-
-/*
- * return Success if the there is a cached password key.
- */
-SECStatus
-sftkdb_PWCached(SFTKDBHandle *keydb)
-{
- return keydb->passwordKey.data ? SECSuccess : SECFailure;
-}
-
-
-static CK_RV
-sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle,
- CK_OBJECT_HANDLE id, SECItem *newKey)
-{
- CK_RV crv = CKR_OK;
- CK_RV crv2;
- CK_ATTRIBUTE authAttrs[] = {
- {CKA_MODULUS, NULL, 0},
- {CKA_PUBLIC_EXPONENT, NULL, 0},
- {CKA_CERT_SHA1_HASH, NULL, 0},
- {CKA_CERT_MD5_HASH, NULL, 0},
- {CKA_TRUST_SERVER_AUTH, NULL, 0},
- {CKA_TRUST_CLIENT_AUTH, NULL, 0},
- {CKA_TRUST_EMAIL_PROTECTION, NULL, 0},
- {CKA_TRUST_CODE_SIGNING, NULL, 0},
- {CKA_TRUST_STEP_UP_APPROVED, NULL, 0},
- {CKA_NSS_OVERRIDE_EXTENSIONS, NULL, 0},
- };
- CK_ULONG authAttrCount = sizeof(authAttrs)/sizeof(CK_ATTRIBUTE);
- int i, count;
- SFTKDBHandle *keyHandle = handle;
- SDB *keyTarget = NULL;
-
- id &= SFTK_OBJ_ID_MASK;
-
- if (handle->type != SFTK_KEYDB_TYPE) {
- keyHandle = handle->peerDB;
- }
-
- if (keyHandle == NULL) {
- return CKR_OK;
- }
-
- /* old DB's don't have meta data, finished with MACs */
- keyTarget = SFTK_GET_SDB(keyHandle);
- if ((keyTarget->sdb_flags &SDB_HAS_META) == 0) {
- return CKR_OK;
- }
-
- /*
- * STEP 1: find the MACed attributes of this object
- */
- crv2 = sftkdb_GetAttributeValue(handle, id, authAttrs, authAttrCount);
- count = 0;
- /* allocate space for the attributes */
- for (i=0; i < authAttrCount; i++) {
- if ((authAttrs[i].ulValueLen == -1) || (authAttrs[i].ulValueLen == 0)){
- continue;
- }
- count++;
- authAttrs[i].pValue = PORT_ArenaAlloc(arena,authAttrs[i].ulValueLen);
- if (authAttrs[i].pValue == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- }
-
- /* if count was zero, none were found, finished with MACs */
- if (count == 0) {
- return CKR_OK;
- }
-
- crv = sftkdb_GetAttributeValue(handle, id, authAttrs, authAttrCount);
- /* ignore error code, we expect some possible errors */
-
- /* GetAttributeValue just verified the old macs, safe to write
- * them out then... */
- for (i=0; i < authAttrCount; i++) {
- SECItem *signText;
- SECItem plainText;
- SECStatus rv;
-
- if ((authAttrs[i].ulValueLen == -1) || (authAttrs[i].ulValueLen == 0)){
- continue;
- }
-
- plainText.data = authAttrs[i].pValue;
- plainText.len = authAttrs[i].ulValueLen;
- rv = sftkdb_SignAttribute(arena, newKey, id,
- authAttrs[i].type, &plainText, &signText);
- if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR;
- }
- rv = sftkdb_PutAttributeSignature(handle, keyTarget, id,
- authAttrs[i].type, signText);
- if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR;
- }
- }
-
- return CKR_OK;
-}
-
-static CK_RV
-sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb,
- CK_OBJECT_HANDLE id, SECItem *newKey)
-{
- CK_RV crv = CKR_OK;
- CK_RV crv2;
- CK_ATTRIBUTE *first, *last;
- CK_ATTRIBUTE privAttrs[] = {
- {CKA_VALUE, NULL, 0},
- {CKA_PRIVATE_EXPONENT, NULL, 0},
- {CKA_PRIME_1, NULL, 0},
- {CKA_PRIME_2, NULL, 0},
- {CKA_EXPONENT_1, NULL, 0},
- {CKA_EXPONENT_2, NULL, 0},
- {CKA_COEFFICIENT, NULL, 0} };
- CK_ULONG privAttrCount = sizeof(privAttrs)/sizeof(CK_ATTRIBUTE);
- int i, count;
-
- /*
- * STEP 1. Read the old attributes in the clear.
- */
-
- /* Get the attribute sizes.
- * ignore the error code, we will have unknown attributes here */
- crv2 = sftkdb_GetAttributeValue(keydb, id, privAttrs, privAttrCount);
-
- /*
- * find the valid block of attributes and fill allocate space for
- * their data */
- first = last = NULL;
- for (i=0; i < privAttrCount; i++) {
- /* find the block of attributes that are appropriate for this
- * objects. There should only be once contiguous block, if not
- * there's an error.
- *
- * find the first and last good entry.
- */
- if ((privAttrs[i].ulValueLen == -1) || (privAttrs[i].ulValueLen == 0)){
- if (!first) continue;
- if (!last) {
- /* previous entry was last good entry */
- last= &privAttrs[i-1];
- }
- continue;
- }
- if (!first) {
- first = &privAttrs[i];
- }
- if (last) {
- /* OOPS, we've found another good entry beyond the end of the
- * last good entry, we need to fail here. */
- crv = CKR_GENERAL_ERROR;
- break;
- }
- privAttrs[i].pValue = PORT_ArenaAlloc(arena,privAttrs[i].ulValueLen);
- if (privAttrs[i].pValue == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- }
- if (first == NULL) {
- /* no valid entries found, return error based on crv2 */
- return crv2;
- }
- if (last == NULL) {
- last = &privAttrs[privAttrCount-1];
- }
- if (crv != CKR_OK) {
- return crv;
- }
- /* read the attributes */
- count = (last-first)+1;
- crv = sftkdb_GetAttributeValue(keydb, id, first, count);
- if (crv != CKR_OK) {
- return crv;
- }
-
- /*
- * STEP 2: read the encrypt the attributes with the new key.
- */
- for (i=0; i < count; i++) {
- SECItem plainText;
- SECItem *result;
- SECStatus rv;
-
- plainText.data = first[i].pValue;
- plainText.len = first[i].ulValueLen;
- rv = sftkdb_EncryptAttribute(arena, newKey, &plainText, &result);
- if (rv != SECSuccess) {
- return CKR_GENERAL_ERROR;
- }
- first[i].pValue = result->data;
- first[i].ulValueLen = result->len;
- /* clear our sensitive data out */
- PORT_Memset(plainText.data, 0, plainText.len);
- }
-
-
- /*
- * STEP 3: write the newly encrypted attributes out directly
- */
- id &= SFTK_OBJ_ID_MASK;
- keydb->newKey = newKey;
- crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, id, first, count);
- keydb->newKey = NULL;
-
- return crv;
-}
-
-static CK_RV
-sftk_convertAttributes(SFTKDBHandle *handle,
- CK_OBJECT_HANDLE id, SECItem *newKey)
-{
- CK_RV crv = CKR_OK;
- PLArenaPool *arena = NULL;
-
- /* get a new arena to simplify cleanup */
- arena = PORT_NewArena(1024);
- if (!arena) {
- return CKR_HOST_MEMORY;
- }
-
- /*
- * first handle the MACS
- */
- crv = sftk_updateMacs(arena, handle, id, newKey);
- if (crv != CKR_OK) {
- goto loser;
- }
-
- if (handle->type == SFTK_KEYDB_TYPE) {
- crv = sftk_updateEncrypted(arena, handle, id, newKey);
- if (crv != CKR_OK) {
- goto loser;
- }
- }
-
- /* free up our mess */
- /* NOTE: at this point we know we've cleared out any unencrypted data */
- PORT_FreeArena(arena, PR_FALSE);
- return CKR_OK;
-
-loser:
- /* there may be unencrypted data, clear it out down */
- PORT_FreeArena(arena, PR_TRUE);
- return crv;
-}
-
-
-/*
- * must be called with the old key active.
- */
-CK_RV
-sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template,
- CK_ULONG count, SECItem *newKey)
-{
- SDBFind *find = NULL;
- CK_ULONG idCount = SFTK_MAX_IDS;
- CK_OBJECT_HANDLE ids[SFTK_MAX_IDS];
- CK_RV crv, crv2;
- int i;
-
- crv = sftkdb_FindObjectsInit(handle, template, count, &find);
-
- if (crv != CKR_OK) {
- return crv;
- }
- while ((crv == CKR_OK) && (idCount == SFTK_MAX_IDS)) {
- crv = sftkdb_FindObjects(handle, find, ids, SFTK_MAX_IDS, &idCount);
- for (i=0; (crv == CKR_OK) && (i < idCount); i++) {
- crv = sftk_convertAttributes(handle, ids[i], newKey);
- }
- }
- crv2 = sftkdb_FindObjectsFinal(handle, find);
- if (crv == CKR_OK) crv = crv2;
-
- return crv;
-}
-
-
-/*
- * change the database password.
- */
-SECStatus
-sftkdb_ChangePassword(SFTKDBHandle *keydb,
- char *oldPin, char *newPin, PRBool *tokenRemoved)
-{
- SECStatus rv = SECSuccess;
- SECItem plainText;
- SECItem newKey;
- SECItem *result = NULL;
- SECItem salt, value;
- SFTKDBHandle *certdb;
- unsigned char saltData[SDB_MAX_META_DATA_LEN];
- unsigned char valueData[SDB_MAX_META_DATA_LEN];
- CK_RV crv;
- SDB *db;
-
- if (keydb == NULL) {
- return SECFailure;
- }
-
- db = SFTK_GET_SDB(keydb);
- if (db == NULL) {
- return SECFailure;
- }
-
- newKey.data = NULL;
-
- /* make sure we have a valid old pin */
- crv = (*keydb->db->sdb_Begin)(keydb->db);
- if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
- }
- salt.data = saltData;
- salt.len = sizeof(saltData);
- value.data = valueData;
- value.len = sizeof(valueData);
- crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);
- if (crv == CKR_OK) {
- rv = sftkdb_CheckPassword(keydb, oldPin, tokenRemoved);
- if (rv == SECFailure) {
- goto loser;
- }
- } else {
- salt.len = SHA1_LENGTH;
- RNG_GenerateGlobalRandomBytes(salt.data,salt.len);
- }
-
- rv = sftkdb_passwordToKey(keydb, &salt, newPin, &newKey);
- if (rv != SECSuccess) {
- goto loser;
- }
-
-
- /*
- * convert encrypted entries here.
- */
- crv = sftkdb_convertObjects(keydb, NULL, 0, &newKey);
- if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
- }
- /* fix up certdb macs */
- certdb = keydb->peerDB;
- if (certdb) {
- CK_ATTRIBUTE objectType = { CKA_CLASS, 0, sizeof(CK_OBJECT_CLASS) };
- CK_OBJECT_CLASS myClass = CKO_NETSCAPE_TRUST;
-
- objectType.pValue = &myClass;
- crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey);
- if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
- }
- myClass = CKO_PUBLIC_KEY;
- crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey);
- if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
- }
- }
-
-
- plainText.data = (unsigned char *)SFTK_PW_CHECK_STRING;
- plainText.len = SFTK_PW_CHECK_LEN;
-
- rv = sftkdb_EncryptAttribute(NULL, &newKey, &plainText, &result);
- if (rv != SECSuccess) {
- goto loser;
- }
- value.data = result->data;
- value.len = result->len;
- crv = (*keydb->db->sdb_PutMetaData)(keydb->db, "password", &salt, &value);
- if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
- }
- crv = (*keydb->db->sdb_Commit)(keydb->db);
- if (crv != CKR_OK) {
- rv = SECFailure;
- goto loser;
- }
-
- keydb->newKey = NULL;
-
- sftkdb_switchKeys(keydb, &newKey);
-
-loser:
- if (newKey.data) {
- PORT_ZFree(newKey.data,newKey.len);
- }
- if (result) {
- SECITEM_FreeItem(result, PR_FALSE);
- }
- if (rv != SECSuccess) {
- (*keydb->db->sdb_Abort)(keydb->db);
- }
-
- return rv;
-}
-
-/*
- * lose our cached password
- */
-SECStatus
-sftkdb_ClearPassword(SFTKDBHandle *keydb)
-{
- SECItem oldKey;
- oldKey.data = NULL;
- oldKey.len = 0;
- sftkdb_switchKeys(keydb, &oldKey);
- if (oldKey.data) {
- PORT_ZFree(oldKey.data, oldKey.len);
- }
- return SECSuccess;
-}
-
-
diff --git a/security/nss/lib/softoken/softkver.c b/security/nss/lib/softoken/softkver.c
deleted file mode 100644
index de21bfef3..000000000
--- a/security/nss/lib/softoken/softkver.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Library identity and versioning */
-
-#include "softkver.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_softokn_rcsid[] = "$Header: NSS " SOFTOKEN_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_softokn_sccsid[] = "@(#)NSS " SOFTOKEN_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h
deleted file mode 100644
index 13e8528cf..000000000
--- a/security/nss/lib/softoken/softkver.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Softoken version numbers
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SOFTKVER_H_
-#define _SOFTKVER_H_
-
-#ifdef NSS_ENABLE_ECC
-#ifdef NSS_ECC_MORE_THAN_SUITE_B
-#define SOFTOKEN_ECC_STRING " Extended ECC"
-#else
-#define SOFTOKEN_ECC_STRING " Basic ECC"
-#endif
-#else
-#define SOFTOKEN_ECC_STRING ""
-#endif
-
-/*
- * Softoken's major version, minor version, patch level, build number,
- * and whether this is a beta release.
- *
- * The format of the version string should be
- * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
- */
-#define SOFTOKEN_VERSION "3.14.4.0" SOFTOKEN_ECC_STRING "Beta"
-#define SOFTOKEN_VMAJOR 3
-#define SOFTOKEN_VMINOR 14
-#define SOFTOKEN_VPATCH 4
-#define SOFTOKEN_VBUILD 0
-#define SOFTOKEN_BETA PR_TRUE
-
-#endif /* _SOFTKVER_H_ */
diff --git a/security/nss/lib/softoken/softoken.h b/security/nss/lib/softoken/softoken.h
deleted file mode 100644
index 254fa79fb..000000000
--- a/security/nss/lib/softoken/softoken.h
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * softoken.h - private data structures and prototypes for the softoken lib
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _SOFTOKEN_H_
-#define _SOFTOKEN_H_
-
-#include "blapi.h"
-#include "lowkeyti.h"
-#include "softoknt.h"
-#include "secoidt.h"
-
-#include "pkcs11t.h"
-
-SEC_BEGIN_PROTOS
-
-/*
-** RSA encryption/decryption. When encrypting/decrypting the output
-** buffer must be at least the size of the public key modulus.
-*/
-
-/*
-** Format some data into a PKCS#1 encryption block, preparing the
-** data for RSA encryption.
-** "result" where the formatted block is stored (memory is allocated)
-** "modulusLen" the size of the formatted block
-** "blockType" what block type to use (SEC_RSABlock*)
-** "data" the data to format
-*/
-extern SECStatus RSA_FormatBlock(SECItem *result,
- unsigned int modulusLen,
- RSA_BlockType blockType,
- SECItem *data);
-/*
-** Similar, but just returns a pointer to the allocated memory, *and*
-** will *only* format one block, even if we (in the future) modify
-** RSA_FormatBlock() to loop over multiples of modulusLen.
-*/
-extern unsigned char *RSA_FormatOneBlock(unsigned int modulusLen,
- RSA_BlockType blockType,
- SECItem *data);
-
-
-
-/*
- * convenience wrappers for doing single RSA operations. They create the
- * RSA context internally and take care of the formatting
- * requirements. Blinding happens automagically within RSA_Sign and
- * RSA_DecryptBlock.
- */
-extern
-SECStatus RSA_Sign(NSSLOWKEYPrivateKey *key, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- unsigned char *input, unsigned int inputLen);
-extern
-SECStatus RSA_HashSign(SECOidTag hashOid,
- NSSLOWKEYPrivateKey *key, unsigned char *sig,
- unsigned int *sigLen, unsigned int maxLen,
- unsigned char *hash, unsigned int hashLen);
-extern
-SECStatus RSA_SignPSS(CK_RSA_PKCS_PSS_PARAMS *pss_params,
- NSSLOWKEYPrivateKey *key,
- unsigned char *output, unsigned int *output_len,
- unsigned int max_output_len, const unsigned char *input,
- unsigned int input_len);
-extern
-SECStatus RSA_CheckSign(NSSLOWKEYPublicKey *key, unsigned char *sign,
- unsigned int signLength, unsigned char *hash,
- unsigned int hashLength);
-extern
-SECStatus RSA_HashCheckSign(SECOidTag hashOid,
- NSSLOWKEYPublicKey *key, unsigned char *sig,
- unsigned int sigLen, unsigned char *digest,
- unsigned int digestLen);
-extern
-SECStatus RSA_CheckSignPSS(CK_RSA_PKCS_PSS_PARAMS *pss_params,
- NSSLOWKEYPublicKey *key,
- const unsigned char *sign, unsigned int sign_len,
- const unsigned char *hash, unsigned int hash_len);
-extern
-SECStatus RSA_CheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data,
- unsigned int *data_len,unsigned int max_output_len,
- unsigned char *sign, unsigned int sign_len);
-extern
-SECStatus RSA_EncryptBlock(NSSLOWKEYPublicKey *key, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- unsigned char *input, unsigned int inputLen);
-extern
-SECStatus RSA_DecryptBlock(NSSLOWKEYPrivateKey *key, unsigned char *output,
- unsigned int *outputLen, unsigned int maxOutputLen,
- unsigned char *input, unsigned int inputLen);
-
-extern
-SECStatus RSA_EncryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
- NSSLOWKEYPublicKey *key,
- unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-extern
-SECStatus RSA_DecryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
- NSSLOWKEYPrivateKey *key,
- unsigned char *output, unsigned int *outputLen,
- unsigned int maxOutputLen,
- const unsigned char *input, unsigned int inputLen);
-
-/*
- * added to make pkcs #11 happy
- * RAW is RSA_X_509
- */
-extern
-SECStatus RSA_SignRaw( NSSLOWKEYPrivateKey *key, unsigned char *output,
- unsigned int *output_len, unsigned int maxOutputLen,
- unsigned char *input, unsigned int input_len);
-extern
-SECStatus RSA_CheckSignRaw( NSSLOWKEYPublicKey *key, unsigned char *sign,
- unsigned int sign_len, unsigned char *hash,
- unsigned int hash_len);
-extern
-SECStatus RSA_CheckSignRecoverRaw( NSSLOWKEYPublicKey *key, unsigned char *data,
- unsigned int *data_len, unsigned int max_output_len,
- unsigned char *sign, unsigned int sign_len);
-extern
-SECStatus RSA_EncryptRaw( NSSLOWKEYPublicKey *key, unsigned char *output,
- unsigned int *output_len,
- unsigned int max_output_len,
- unsigned char *input, unsigned int input_len);
-extern
-SECStatus RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output,
- unsigned int *output_len,
- unsigned int max_output_len,
- unsigned char *input, unsigned int input_len);
-#ifdef NSS_ENABLE_ECC
-/*
-** pepare an ECParam structure from DEREncoded params
- */
-extern SECStatus EC_FillParams(PRArenaPool *arena,
- const SECItem *encodedParams, ECParams *params);
-extern SECStatus EC_DecodeParams(const SECItem *encodedParams,
- ECParams **ecparams);
-extern SECStatus EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
- const ECParams *srcParams);
-#endif
-
-
-/*
-** Prepare a buffer for padded CBC encryption, growing to the appropriate
-** boundary, filling with the appropriate padding.
-**
-** blockSize must be a power of 2.
-**
-** We add from 1 to blockSize bytes -- we *always* grow.
-** The extra bytes contain the value of the length of the padding:
-** if we have 2 bytes of padding, then the padding is "0x02, 0x02".
-**
-** NOTE: If arena is non-NULL, we re-allocate from there, otherwise
-** we assume (and use) PR memory (re)allocation.
-*/
-extern unsigned char * CBC_PadBuffer(PRArenaPool *arena, unsigned char *inbuf,
- unsigned int inlen, unsigned int *outlen,
- int blockSize);
-
-
-/****************************************/
-/*
-** Power-Up selftests required for FIPS and invoked only
-** under PKCS #11 FIPS mode.
-*/
-extern CK_RV sftk_fipsPowerUpSelfTest( void );
-
-/*
-** make known fixed PKCS #11 key types to their sizes in bytes
-*/
-unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType);
-
-/*
-** FIPS 140-2 auditing
-*/
-extern PRBool sftk_audit_enabled;
-
-extern void sftk_LogAuditMessage(NSSAuditSeverity severity,
- NSSAuditType, const char *msg);
-
-extern void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject, CK_RV rv);
-
-extern void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv);
-
-extern void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_RV rv);
-
-extern void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize,
- CK_RV rv);
-
-extern void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount, CK_RV rv);
-
-extern void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount, CK_RV rv);
-
-extern void sftk_AuditCryptInit(const char *opName,
- CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey, CK_RV rv);
-
-extern void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey, CK_RV rv);
-
-extern void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPublicKey,
- CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv);
-
-extern void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv);
-
-extern void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey, CK_RV rv);
-
-extern void sftk_AuditDeriveKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey, CK_RV rv);
-
-extern void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey, CK_RV rv);
-
-/*
-** FIPS 140-2 Error state
-*/
-extern PRBool sftk_fatalError;
-
-/*
-** macros to check for forked child process after C_Initialize
-*/
-#if defined(XP_UNIX) && !defined(NO_FORK_CHECK)
-
-#ifdef DEBUG
-
-#define FORK_ASSERT() \
- { \
- char* forkAssert = getenv("NSS_STRICT_NOFORK"); \
- if ( (!forkAssert) || (0 == strcmp(forkAssert, "1")) ) { \
- PORT_Assert(0); \
- } \
- }
-
-#else
-
-#define FORK_ASSERT()
-
-#endif
-
-/* we have 3 methods of implementing the fork checks :
- * - Solaris "mixed" method
- * - pthread_atfork method
- * - getpid method
- */
-
-#if !defined (CHECK_FORK_MIXED) && !defined(CHECK_FORK_PTHREAD) && \
- !defined (CHECK_FORK_GETPID)
-
-/* Choose fork check method automatically unless specified
- * This section should be updated as more platforms get pthread fixes
- * to unregister fork handlers in dlclose.
- */
-
-#ifdef SOLARIS
-
-/* Solaris 8, s9 use PID checks, s10 uses pthread_atfork */
-
-#define CHECK_FORK_MIXED
-
-#elif defined(LINUX)
-
-#define CHECK_FORK_PTHREAD
-
-#else
-
-/* Other Unix platforms use only PID checks. Even if pthread_atfork is
- * available, the behavior of dlclose isn't guaranteed by POSIX to
- * unregister the fork handler. */
-
-#define CHECK_FORK_GETPID
-
-#endif
-
-#endif
-
-#if defined(CHECK_FORK_MIXED)
-
-extern PRBool usePthread_atfork;
-#include <unistd.h>
-extern pid_t myPid;
-extern PRBool forked;
-
-#define PARENT_FORKED() (usePthread_atfork ? forked : (myPid && myPid != getpid()))
-
-#elif defined(CHECK_FORK_PTHREAD)
-
-extern PRBool forked;
-
-#define PARENT_FORKED() forked
-
-#elif defined(CHECK_FORK_GETPID)
-
-#include <unistd.h>
-extern pid_t myPid;
-
-#define PARENT_FORKED() (myPid && myPid != getpid())
-
-#endif
-
-extern PRBool parentForkedAfterC_Initialize;
-extern PRBool sftkForkCheckDisabled;
-
-#define CHECK_FORK() \
- do { \
- if (!sftkForkCheckDisabled && PARENT_FORKED()) { \
- FORK_ASSERT(); \
- return CKR_DEVICE_ERROR; \
- } \
- } while (0)
-
-#define SKIP_AFTER_FORK(x) if (!parentForkedAfterC_Initialize) x
-
-#define ENABLE_FORK_CHECK() \
- { \
- char* doForkCheck = getenv("NSS_STRICT_NOFORK"); \
- if ( doForkCheck && !strcmp(doForkCheck, "DISABLED") ) { \
- sftkForkCheckDisabled = PR_TRUE; \
- } \
- }
-
-
-#else
-
-/* non-Unix platforms, or fork check disabled */
-
-#define CHECK_FORK()
-#define SKIP_AFTER_FORK(x) x
-#define ENABLE_FORK_CHECK()
-
-#ifndef NO_FORK_CHECK
-#define NO_FORK_CHECK
-#endif
-
-#endif
-
-
-SEC_END_PROTOS
-
-#endif /* _SOFTOKEN_H_ */
diff --git a/security/nss/lib/softoken/softokn.def b/security/nss/lib/softoken/softokn.def
deleted file mode 100644
index 24c591573..000000000
--- a/security/nss/lib/softoken/softokn.def
+++ /dev/null
@@ -1,28 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+NSS_3.4 { # NSS 3.4 release
-;+ global:
-LIBRARY softokn3 ;-
-EXPORTS ;-
-C_GetFunctionList; Make this function like a real PKCS #11 module as well
-FC_GetFunctionList;
-NSC_GetFunctionList;
-NSC_ModuleDBFunc;
-;+ local:
-;+ *;
-;+};
diff --git a/security/nss/lib/softoken/softokn.rc b/security/nss/lib/softoken/softokn.rc
deleted file mode 100644
index f3dbb5c42..000000000
--- a/security/nss/lib/softoken/softokn.rc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "softkver.h"
-#include <winver.h>
-
-#define MY_LIBNAME "softokn"
-#define MY_FILEDESCRIPTION "NSS PKCS #11 Library"
-
-#define STRINGIZE(x) #x
-#define STRINGIZE2(x) STRINGIZE(x)
-#define SOFTOKEN_VMAJOR_STR STRINGIZE2(SOFTOKEN_VMAJOR)
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if SOFTOKEN_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME SOFTOKEN_VMAJOR_STR
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,SOFTOKEN_VBUILD
- PRODUCTVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,SOFTOKEN_VBUILD
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Mozilla Foundation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", SOFTOKEN_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", SOFTOKEN_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/softoken/softoknt.h b/security/nss/lib/softoken/softoknt.h
deleted file mode 100644
index 7ab8a24ce..000000000
--- a/security/nss/lib/softoken/softoknt.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * softoknt.h - public data structures for the software token library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _SOFTOKNT_H_
-#define _SOFTOKNT_H_
-
-/*
- * RSA block types
- *
- * The actual values are important -- they are fixed, *not* arbitrary.
- * The explicit value assignments are not needed (because C would give
- * us those same values anyway) but are included as a reminder...
- */
-typedef enum {
- RSA_BlockPrivate0 = 0, /* unused, really */
- RSA_BlockPrivate = 1, /* pad for a private-key operation */
- RSA_BlockPublic = 2, /* pad for a public-key operation */
- RSA_BlockRaw = 4, /* simply justify the block appropriately */
- RSA_BlockTotal
-} RSA_BlockType;
-
-#define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048
-
-/*
- * FIPS 140-2 auditing
- */
-typedef enum {
- NSS_AUDIT_ERROR = 3, /* errors */
- NSS_AUDIT_WARNING = 2, /* warning messages */
- NSS_AUDIT_INFO = 1 /* informational messages */
-} NSSAuditSeverity;
-
-typedef enum {
- NSS_AUDIT_ACCESS_KEY = 0,
- NSS_AUDIT_CHANGE_KEY,
- NSS_AUDIT_COPY_KEY,
- NSS_AUDIT_CRYPT,
- NSS_AUDIT_DERIVE_KEY,
- NSS_AUDIT_DESTROY_KEY,
- NSS_AUDIT_DIGEST_KEY,
- NSS_AUDIT_FIPS_STATE,
- NSS_AUDIT_GENERATE_KEY,
- NSS_AUDIT_INIT_PIN,
- NSS_AUDIT_INIT_TOKEN,
- NSS_AUDIT_LOAD_KEY,
- NSS_AUDIT_LOGIN,
- NSS_AUDIT_LOGOUT,
- NSS_AUDIT_SELF_TEST,
- NSS_AUDIT_SET_PIN,
- NSS_AUDIT_UNWRAP_KEY,
- NSS_AUDIT_WRAP_KEY
-} NSSAuditType;
-
-#endif /* _SOFTOKNT_H_ */
diff --git a/security/nss/lib/softoken/tlsprf.c b/security/nss/lib/softoken/tlsprf.c
deleted file mode 100644
index 15f4d698d..000000000
--- a/security/nss/lib/softoken/tlsprf.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* tlsprf.c - TLS Pseudo Random Function (PRF) implementation
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "pkcs11i.h"
-#include "blapi.h"
-
-#define SFTK_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb)))
-
-static void sftk_TLSPRFNull(void *data, PRBool freeit)
-{
- return;
-}
-
-typedef struct {
- PRUint32 cxSize; /* size of allocated block, in bytes. */
- PRUint32 cxBufSize; /* sizeof buffer at cxBufPtr. */
- unsigned char *cxBufPtr; /* points to real buffer, may be cxBuf. */
- PRUint32 cxKeyLen; /* bytes of cxBufPtr containing key. */
- PRUint32 cxDataLen; /* bytes of cxBufPtr containing data. */
- SECStatus cxRv; /* records failure of void functions. */
- PRBool cxIsFIPS; /* true if conforming to FIPS 198. */
- unsigned char cxBuf[512]; /* actual size may be larger than 512. */
-} TLSPRFContext;
-
-static void
-sftk_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data,
- unsigned int data_len)
-{
- PRUint32 bytesUsed = cx->cxKeyLen + cx->cxDataLen;
-
- if (cx->cxRv != SECSuccess) /* function has previously failed. */
- return;
- if (bytesUsed + data_len > cx->cxBufSize) {
- /* We don't use realloc here because
- ** (a) realloc doesn't zero out the old block, and
- ** (b) if realloc fails, we lose the old block.
- */
- PRUint32 newBufSize = bytesUsed + data_len + 512;
- unsigned char * newBuf = (unsigned char *)PORT_Alloc(newBufSize);
- if (!newBuf) {
- cx->cxRv = SECFailure;
- return;
- }
- PORT_Memcpy(newBuf, cx->cxBufPtr, bytesUsed);
- if (cx->cxBufPtr != cx->cxBuf) {
- PORT_ZFree(cx->cxBufPtr, bytesUsed);
- }
- cx->cxBufPtr = newBuf;
- cx->cxBufSize = newBufSize;
- }
- PORT_Memcpy(cx->cxBufPtr + bytesUsed, data, data_len);
- cx->cxDataLen += data_len;
-}
-
-static void
-sftk_TLSPRFEnd(TLSPRFContext *ctx, unsigned char *hashout,
- unsigned int *pDigestLen, unsigned int maxDigestLen)
-{
- *pDigestLen = 0; /* tells Verify that no data has been input yet. */
-}
-
-/* Compute the PRF values from the data previously input. */
-static SECStatus
-sftk_TLSPRFUpdate(TLSPRFContext *cx,
- unsigned char *sig, /* output goes here. */
- unsigned int * sigLen, /* how much output. */
- unsigned int maxLen, /* output buffer size */
- unsigned char *hash, /* unused. */
- unsigned int hashLen) /* unused. */
-{
- SECStatus rv;
- SECItem sigItem;
- SECItem seedItem;
- SECItem secretItem;
-
- if (cx->cxRv != SECSuccess)
- return cx->cxRv;
-
- secretItem.data = cx->cxBufPtr;
- secretItem.len = cx->cxKeyLen;
-
- seedItem.data = cx->cxBufPtr + cx->cxKeyLen;
- seedItem.len = cx->cxDataLen;
-
- sigItem.data = sig;
- sigItem.len = maxLen;
-
- rv = TLS_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS);
- if (rv == SECSuccess && sigLen != NULL)
- *sigLen = sigItem.len;
- return rv;
-
-}
-
-static SECStatus
-sftk_TLSPRFVerify(TLSPRFContext *cx,
- unsigned char *sig, /* input, for comparison. */
- unsigned int sigLen, /* length of sig. */
- unsigned char *hash, /* data to be verified. */
- unsigned int hashLen) /* size of hash data. */
-{
- unsigned char * tmp = (unsigned char *)PORT_Alloc(sigLen);
- unsigned int tmpLen = sigLen;
- SECStatus rv;
-
- if (!tmp)
- return SECFailure;
- if (hashLen) {
- /* hashLen is non-zero when the user does a one-step verify.
- ** In this case, none of the data has been input yet.
- */
- sftk_TLSPRFHashUpdate(cx, hash, hashLen);
- }
- rv = sftk_TLSPRFUpdate(cx, tmp, &tmpLen, sigLen, NULL, 0);
- if (rv == SECSuccess) {
- rv = (SECStatus)(1 - !PORT_Memcmp(tmp, sig, sigLen));
- }
- PORT_ZFree(tmp, sigLen);
- return rv;
-}
-
-static void
-sftk_TLSPRFHashDestroy(TLSPRFContext *cx, PRBool freeit)
-{
- if (freeit) {
- if (cx->cxBufPtr != cx->cxBuf)
- PORT_ZFree(cx->cxBufPtr, cx->cxBufSize);
- PORT_ZFree(cx, cx->cxSize);
- }
-}
-
-CK_RV
-sftk_TLSPRFInit(SFTKSessionContext *context,
- SFTKObject * key,
- CK_KEY_TYPE key_type)
-{
- SFTKAttribute * keyVal;
- TLSPRFContext * prf_cx;
- CK_RV crv = CKR_HOST_MEMORY;
- PRUint32 keySize;
- PRUint32 blockSize;
-
- if (key_type != CKK_GENERIC_SECRET)
- return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */
-
- context->multi = PR_TRUE;
-
- keyVal = sftk_FindAttribute(key, CKA_VALUE);
- keySize = (!keyVal) ? 0 : keyVal->attrib.ulValueLen;
- blockSize = keySize + sizeof(TLSPRFContext);
- prf_cx = (TLSPRFContext *)PORT_Alloc(blockSize);
- if (!prf_cx)
- goto done;
- prf_cx->cxSize = blockSize;
- prf_cx->cxKeyLen = keySize;
- prf_cx->cxDataLen = 0;
- prf_cx->cxBufSize = blockSize - SFTK_OFFSETOF(TLSPRFContext, cxBuf);
- prf_cx->cxRv = SECSuccess;
- prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID);
- prf_cx->cxBufPtr = prf_cx->cxBuf;
- if (keySize)
- PORT_Memcpy(prf_cx->cxBufPtr, keyVal->attrib.pValue, keySize);
-
- context->hashInfo = (void *) prf_cx;
- context->cipherInfo = (void *) prf_cx;
- context->hashUpdate = (SFTKHash) sftk_TLSPRFHashUpdate;
- context->end = (SFTKEnd) sftk_TLSPRFEnd;
- context->update = (SFTKCipher) sftk_TLSPRFUpdate;
- context->verify = (SFTKVerify) sftk_TLSPRFVerify;
- context->destroy = (SFTKDestroy) sftk_TLSPRFNull;
- context->hashdestroy = (SFTKDestroy) sftk_TLSPRFHashDestroy;
- crv = CKR_OK;
-
-done:
- if (keyVal)
- sftk_FreeAttribute(keyVal);
- return crv;
-}
-
diff --git a/security/nss/lib/sqlite/Makefile b/security/nss/lib/sqlite/Makefile
deleted file mode 100644
index a2f0cf7d5..000000000
--- a/security/nss/lib/sqlite/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
--include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
diff --git a/security/nss/lib/sqlite/README b/security/nss/lib/sqlite/README
deleted file mode 100644
index dbb9048f5..000000000
--- a/security/nss/lib/sqlite/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This is SQLite 3.7.14.1.
-
-Local changes:
diff --git a/security/nss/lib/sqlite/config.mk b/security/nss/lib/sqlite/config.mk
deleted file mode 100644
index c7b93ed39..000000000
--- a/security/nss/lib/sqlite/config.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
-
-#RES = $(OBJDIR)/$(LIBRARY_NAME).res
-#RESNAME = $(LIBRARY_NAME).rc
-endif
-
-ifeq ($(OS_TARGET),AIX)
-EXTRA_LIBS += -lpthreads
-ifdef BUILD_OPT
-OPTIMIZER=
-endif
-endif
-
-ifeq ($(OS_TARGET),SunOS)
-OS_LIBS += -lbsm
-endif
-
-ifeq ($(OS_TARGET),Darwin)
-# These version numbers come from the -version-info 8:6:8 libtool option in
-# sqlite upstream's Makefile.in. (Given -version-info current:revision:age,
-# libtool passes
-# -compatibility_version current+1 -current_version current+1.revision
-# to the linker.) Apple builds the system libsqlite3.dylib with these
-# version numbers, so we use the same to be compatible.
-DARWIN_DYLIB_VERSIONS = -compatibility_version 9 -current_version 9.6
-
-# The SQLite code that uses the Apple zone allocator calls
-# OSAtomicCompareAndSwapPtrBarrier, which is only available on Mac OS X 10.5
-# (Darwin 9.0) and later. Define SQLITE_WITHOUT_ZONEMALLOC to disable
-# that code for older versions of Mac OS X. See bug 820374.
-DARWIN_VER_MAJOR := $(shell uname -r | cut -f1 -d.)
-DARWIN_LT_9 := $(shell [ $(DARWIN_VER_MAJOR) -lt 9 ] && echo true)
-ifeq ($(DARWIN_LT_9),true)
-OS_CFLAGS += -DSQLITE_WITHOUT_ZONEMALLOC
-endif
-endif # Darwin
diff --git a/security/nss/lib/sqlite/manifest.mn b/security/nss/lib/sqlite/manifest.mn
deleted file mode 100644
index 149170b5b..000000000
--- a/security/nss/lib/sqlite/manifest.mn
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-
-MODULE = nss
-
-LIBRARY_NAME = sqlite
-LIBRARY_VERSION = 3
-MAPFILE = $(OBJDIR)/sqlite.def
-DEFINES += -DSQLITE_THREADSAFE=1
-
-EXPORTS = \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- sqlite3.h \
- $(NULL)
-
-
-CSRCS = \
- sqlite3.c \
- $(NULL)
-
-
-
-# only add module debugging in opt builds if DEBUG_PKCS11 is set
-ifdef DEBUG_PKCS11
- DEFINES += -DDEBUG_MODULE
-endif
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/sqlite/sqlite.def b/security/nss/lib/sqlite/sqlite.def
deleted file mode 100644
index 00fa623ab..000000000
--- a/security/nss/lib/sqlite/sqlite.def
+++ /dev/null
@@ -1,147 +0,0 @@
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+SQLITE_3 {
-;+ global:
-LIBRARY sqlite3 ;-
-EXPORTS ;-
-sqlite3_aggregate_context;
-sqlite3_aggregate_count;
-sqlite3_auto_extension;
-sqlite3_bind_blob;
-sqlite3_bind_double;
-sqlite3_bind_int;
-sqlite3_bind_int64;
-sqlite3_bind_null;
-sqlite3_bind_parameter_count;
-sqlite3_bind_parameter_index;
-sqlite3_bind_parameter_name;
-sqlite3_bind_text;
-sqlite3_bind_text16;
-sqlite3_bind_value;
-sqlite3_busy_handler;
-sqlite3_busy_timeout;
-sqlite3_changes;
-sqlite3_clear_bindings;
-sqlite3_close;
-sqlite3_collation_needed;
-sqlite3_collation_needed16;
-sqlite3_column_blob;
-sqlite3_column_bytes;
-sqlite3_column_bytes16;
-sqlite3_column_count;
-sqlite3_column_decltype;
-sqlite3_column_decltype16;
-sqlite3_column_double;
-sqlite3_column_int;
-sqlite3_column_int64;
-sqlite3_column_name;
-sqlite3_column_name16;
-sqlite3_column_text;
-sqlite3_column_text16;
-sqlite3_column_type;
-sqlite3_column_value;
-sqlite3_commit_hook;
-sqlite3_complete;
-sqlite3_complete16;
-sqlite3_create_collation;
-sqlite3_create_collation16;
-sqlite3_create_function;
-sqlite3_create_function16;
-sqlite3_create_module;
-sqlite3_data_count;
-sqlite3_db_handle;
-sqlite3_declare_vtab;
-sqlite3_enable_load_extension;
-sqlite3_enable_shared_cache;
-sqlite3_errcode;
-sqlite3_errmsg;
-sqlite3_errmsg16;
-sqlite3_exec;
-sqlite3_expired;
-sqlite3_extended_result_codes;
-sqlite3_file_control;
-sqlite3_finalize;
-sqlite3_free;
-sqlite3_free_table;
-sqlite3_get_autocommit;
-sqlite3_get_auxdata;
-sqlite3_get_table;
-sqlite3_global_recover;
-sqlite3_interrupt;
-sqlite3_last_insert_rowid;
-sqlite3_libversion;
-sqlite3_libversion_number;
-sqlite3_load_extension;
-sqlite3_malloc;
-sqlite3_mprintf;
-sqlite3_open;
-sqlite3_open16;
-sqlite3_open_v2;
-sqlite3_overload_function;
-sqlite3_prepare;
-sqlite3_prepare16;
-sqlite3_prepare16_v2;
-sqlite3_prepare_v2;
-sqlite3_profile;
-sqlite3_progress_handler;
-sqlite3_realloc;
-sqlite3_reset;
-sqlite3_reset_auto_extension;
-sqlite3_result_blob;
-sqlite3_result_double;
-sqlite3_result_error;
-sqlite3_result_error16;
-sqlite3_result_int;
-sqlite3_result_int64;
-sqlite3_result_null;
-sqlite3_result_text;
-sqlite3_result_text16;
-sqlite3_result_text16be;
-sqlite3_result_text16le;
-sqlite3_result_value;
-sqlite3_rollback_hook;
-sqlite3_set_authorizer;
-sqlite3_set_auxdata;
-sqlite3_sleep;
-sqlite3_snprintf;
-sqlite3_step;
-;;sqlite3_temp_directory DATA ;
-sqlite3_thread_cleanup;
-sqlite3_total_changes;
-sqlite3_trace;
-sqlite3_transfer_bindings;
-sqlite3_update_hook;
-sqlite3_user_data;
-sqlite3_value_blob;
-sqlite3_value_bytes;
-sqlite3_value_bytes16;
-sqlite3_value_double;
-sqlite3_value_int;
-sqlite3_value_int64;
-sqlite3_value_numeric_type;
-sqlite3_value_text;
-sqlite3_value_text16;
-sqlite3_value_text16be;
-sqlite3_value_text16le;
-sqlite3_value_type;
-sqlite3_version;
-sqlite3_vmprintf;
-sqlite3_wal_checkpoint;
-;+ local:
-;+ *;
-;+};
diff --git a/security/nss/lib/sqlite/sqlite3.c b/security/nss/lib/sqlite/sqlite3.c
deleted file mode 100644
index 8ec2bb950..000000000
--- a/security/nss/lib/sqlite/sqlite3.c
+++ /dev/null
@@ -1,137413 +0,0 @@
-/******************************************************************************
-** This file is an amalgamation of many separate C source files from SQLite
-** version 3.7.15. By combining all the individual C code files into this
-** single large file, the entire code can be compiled as a single translation
-** unit. This allows many compilers to do optimizations that would not be
-** possible if the files were compiled separately. Performance improvements
-** of 5% or more are commonly seen when SQLite is compiled as a single
-** translation unit.
-**
-** This file is all you need to compile SQLite. To use SQLite in other
-** programs, you need this file and the "sqlite3.h" header file that defines
-** the programming interface to the SQLite library. (If you do not have
-** the "sqlite3.h" header file at hand, you will find a copy embedded within
-** the text of this file. Search for "Begin file sqlite3.h" to find the start
-** of the embedded sqlite3.h header file.) Additional code files may be needed
-** if you want a wrapper to interface SQLite with your choice of programming
-** language. The code for the "sqlite3" command-line shell is also in a
-** separate file. This file contains only code for the core SQLite library.
-*/
-#define SQLITE_CORE 1
-#define SQLITE_AMALGAMATION 1
-#ifndef SQLITE_PRIVATE
-# define SQLITE_PRIVATE static
-#endif
-#ifndef SQLITE_API
-# define SQLITE_API
-#endif
-/************** Begin file sqliteInt.h ***************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** Internal interface definitions for SQLite.
-**
-*/
-#ifndef _SQLITEINT_H_
-#define _SQLITEINT_H_
-
-/*
-** These #defines should enable >2GB file support on POSIX if the
-** underlying operating system supports it. If the OS lacks
-** large file support, or if the OS is windows, these should be no-ops.
-**
-** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any
-** system #includes. Hence, this block of code must be the very first
-** code in all source files.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line. This is necessary if you are compiling
-** on a recent machine (ex: Red Hat 7.2) but you want your code to work
-** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2
-** without this option, LFS is enable. But LFS does not exist in the kernel
-** in Red Hat 6.0, so the code won't work. Hence, for maximum binary
-** portability you should omit LFS.
-**
-** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE 1
-# ifndef _FILE_OFFSET_BITS
-# define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-/*
-** Include the configuration header output by 'configure' if we're using the
-** autoconf-based build
-*/
-#ifdef _HAVE_SQLITE_CONFIG_H
-#include "config.h"
-#endif
-
-/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
-/************** Begin file sqliteLimit.h *************************************/
-/*
-** 2007 May 7
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file defines various limits of what SQLite can process.
-*/
-
-/*
-** The maximum length of a TEXT or BLOB in bytes. This also
-** limits the size of a row in a table or index.
-**
-** The hard limit is the ability of a 32-bit signed integer
-** to count the size: 2^31-1 or 2147483647.
-*/
-#ifndef SQLITE_MAX_LENGTH
-# define SQLITE_MAX_LENGTH 1000000000
-#endif
-
-/*
-** This is the maximum number of
-**
-** * Columns in a table
-** * Columns in an index
-** * Columns in a view
-** * Terms in the SET clause of an UPDATE statement
-** * Terms in the result set of a SELECT statement
-** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement.
-** * Terms in the VALUES clause of an INSERT statement
-**
-** The hard upper limit here is 32676. Most database people will
-** tell you that in a well-normalized database, you usually should
-** not have more than a dozen or so columns in any table. And if
-** that is the case, there is no point in having more than a few
-** dozen values in any of the other situations described above.
-*/
-#ifndef SQLITE_MAX_COLUMN
-# define SQLITE_MAX_COLUMN 2000
-#endif
-
-/*
-** The maximum length of a single SQL statement in bytes.
-**
-** It used to be the case that setting this value to zero would
-** turn the limit off. That is no longer true. It is not possible
-** to turn this limit off.
-*/
-#ifndef SQLITE_MAX_SQL_LENGTH
-# define SQLITE_MAX_SQL_LENGTH 1000000000
-#endif
-
-/*
-** The maximum depth of an expression tree. This is limited to
-** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might
-** want to place more severe limits on the complexity of an
-** expression.
-**
-** A value of 0 used to mean that the limit was not enforced.
-** But that is no longer true. The limit is now strictly enforced
-** at all times.
-*/
-#ifndef SQLITE_MAX_EXPR_DEPTH
-# define SQLITE_MAX_EXPR_DEPTH 1000
-#endif
-
-/*
-** The maximum number of terms in a compound SELECT statement.
-** The code generator for compound SELECT statements does one
-** level of recursion for each term. A stack overflow can result
-** if the number of terms is too large. In practice, most SQL
-** never has more than 3 or 4 terms. Use a value of 0 to disable
-** any limit on the number of terms in a compount SELECT.
-*/
-#ifndef SQLITE_MAX_COMPOUND_SELECT
-# define SQLITE_MAX_COMPOUND_SELECT 500
-#endif
-
-/*
-** The maximum number of opcodes in a VDBE program.
-** Not currently enforced.
-*/
-#ifndef SQLITE_MAX_VDBE_OP
-# define SQLITE_MAX_VDBE_OP 25000
-#endif
-
-/*
-** The maximum number of arguments to an SQL function.
-*/
-#ifndef SQLITE_MAX_FUNCTION_ARG
-# define SQLITE_MAX_FUNCTION_ARG 127
-#endif
-
-/*
-** The maximum number of in-memory pages to use for the main database
-** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE
-*/
-#ifndef SQLITE_DEFAULT_CACHE_SIZE
-# define SQLITE_DEFAULT_CACHE_SIZE 2000
-#endif
-#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
-# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500
-#endif
-
-/*
-** The default number of frames to accumulate in the log file before
-** checkpointing the database in WAL mode.
-*/
-#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
-# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000
-#endif
-
-/*
-** The maximum number of attached databases. This must be between 0
-** and 62. The upper bound on 62 is because a 64-bit integer bitmap
-** is used internally to track attached databases.
-*/
-#ifndef SQLITE_MAX_ATTACHED
-# define SQLITE_MAX_ATTACHED 10
-#endif
-
-
-/*
-** The maximum value of a ?nnn wildcard that the parser will accept.
-*/
-#ifndef SQLITE_MAX_VARIABLE_NUMBER
-# define SQLITE_MAX_VARIABLE_NUMBER 999
-#endif
-
-/* Maximum page size. The upper bound on this value is 65536. This a limit
-** imposed by the use of 16-bit offsets within each page.
-**
-** Earlier versions of SQLite allowed the user to change this value at
-** compile time. This is no longer permitted, on the grounds that it creates
-** a library that is technically incompatible with an SQLite library
-** compiled with a different limit. If a process operating on a database
-** with a page-size of 65536 bytes crashes, then an instance of SQLite
-** compiled with the default page-size limit will not be able to rollback
-** the aborted transaction. This could lead to database corruption.
-*/
-#ifdef SQLITE_MAX_PAGE_SIZE
-# undef SQLITE_MAX_PAGE_SIZE
-#endif
-#define SQLITE_MAX_PAGE_SIZE 65536
-
-
-/*
-** The default size of a database page.
-*/
-#ifndef SQLITE_DEFAULT_PAGE_SIZE
-# define SQLITE_DEFAULT_PAGE_SIZE 1024
-#endif
-#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
-# undef SQLITE_DEFAULT_PAGE_SIZE
-# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
-#endif
-
-/*
-** Ordinarily, if no value is explicitly provided, SQLite creates databases
-** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain
-** device characteristics (sector-size and atomic write() support),
-** SQLite may choose a larger value. This constant is the maximum value
-** SQLite will choose on its own.
-*/
-#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE
-# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192
-#endif
-#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
-# undef SQLITE_MAX_DEFAULT_PAGE_SIZE
-# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
-#endif
-
-
-/*
-** Maximum number of pages in one database file.
-**
-** This is really just the default value for the max_page_count pragma.
-** This value can be lowered (or raised) at run-time using that the
-** max_page_count macro.
-*/
-#ifndef SQLITE_MAX_PAGE_COUNT
-# define SQLITE_MAX_PAGE_COUNT 1073741823
-#endif
-
-/*
-** Maximum length (in bytes) of the pattern in a LIKE or GLOB
-** operator.
-*/
-#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
-# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
-#endif
-
-/*
-** Maximum depth of recursion for triggers.
-**
-** A value of 1 means that a trigger program will not be able to itself
-** fire any triggers. A value of 0 means that no trigger programs at all
-** may be executed.
-*/
-#ifndef SQLITE_MAX_TRIGGER_DEPTH
-# define SQLITE_MAX_TRIGGER_DEPTH 1000
-#endif
-
-/************** End of sqliteLimit.h *****************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-
-/* Disable nuisance warnings on Borland compilers */
-#if defined(__BORLANDC__)
-#pragma warn -rch /* unreachable code */
-#pragma warn -ccc /* Condition is always true or false */
-#pragma warn -aus /* Assigned value is never used */
-#pragma warn -csu /* Comparing signed and unsigned */
-#pragma warn -spa /* Suspicious pointer arithmetic */
-#endif
-
-/* Needed for various definitions... */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-/*
-** Include standard header files as necessary
-*/
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-/*
-** The following macros are used to cast pointers to integers and
-** integers to pointers. The way you do this varies from one compiler
-** to the next, so we have developed the following set of #if statements
-** to generate appropriate macros for a wide range of compilers.
-**
-** The correct "ANSI" way to do this is to use the intptr_t type.
-** Unfortunately, that typedef is not available on all compilers, or
-** if it is available, it requires an #include of specific headers
-** that vary from one machine to the next.
-**
-** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on
-** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)).
-** So we have to define the macros in different ways depending on the
-** compiler.
-*/
-#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */
-# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X))
-# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X))
-#elif !defined(__GNUC__) /* Works for compilers other than LLVM */
-# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
-# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
-#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */
-# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
-# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
-#else /* Generates a warning - but it always works */
-# define SQLITE_INT_TO_PTR(X) ((void*)(X))
-# define SQLITE_PTR_TO_INT(X) ((int)(X))
-#endif
-
-/*
-** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
-** 0 means mutexes are permanently disable and the library is never
-** threadsafe. 1 means the library is serialized which is the highest
-** level of threadsafety. 2 means the libary is multithreaded - multiple
-** threads can use SQLite as long as no two threads try to use the same
-** database connection at the same time.
-**
-** Older versions of SQLite used an optional THREADSAFE macro.
-** We support that for legacy.
-*/
-#if !defined(SQLITE_THREADSAFE)
-#if defined(THREADSAFE)
-# define SQLITE_THREADSAFE THREADSAFE
-#else
-# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
-#endif
-#endif
-
-/*
-** Powersafe overwrite is on by default. But can be turned off using
-** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option.
-*/
-#ifndef SQLITE_POWERSAFE_OVERWRITE
-# define SQLITE_POWERSAFE_OVERWRITE 1
-#endif
-
-/*
-** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
-** It determines whether or not the features related to
-** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
-** be overridden at runtime using the sqlite3_config() API.
-*/
-#if !defined(SQLITE_DEFAULT_MEMSTATUS)
-# define SQLITE_DEFAULT_MEMSTATUS 1
-#endif
-
-/*
-** Exactly one of the following macros must be defined in order to
-** specify which memory allocation subsystem to use.
-**
-** SQLITE_SYSTEM_MALLOC // Use normal system malloc()
-** SQLITE_WIN32_MALLOC // Use Win32 native heap API
-** SQLITE_ZERO_MALLOC // Use a stub allocator that always fails
-** SQLITE_MEMDEBUG // Debugging version of system malloc()
-**
-** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
-** assert() macro is enabled, each call into the Win32 native heap subsystem
-** will cause HeapValidate to be called. If heap validation should fail, an
-** assertion will be triggered.
-**
-** (Historical note: There used to be several other options, but we've
-** pared it down to just these three.)
-**
-** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
-** the default.
-*/
-#if defined(SQLITE_SYSTEM_MALLOC) \
- + defined(SQLITE_WIN32_MALLOC) \
- + defined(SQLITE_ZERO_MALLOC) \
- + defined(SQLITE_MEMDEBUG)>1
-# error "Two or more of the following compile-time configuration options\
- are defined but at most one is allowed:\
- SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\
- SQLITE_ZERO_MALLOC"
-#endif
-#if defined(SQLITE_SYSTEM_MALLOC) \
- + defined(SQLITE_WIN32_MALLOC) \
- + defined(SQLITE_ZERO_MALLOC) \
- + defined(SQLITE_MEMDEBUG)==0
-# define SQLITE_SYSTEM_MALLOC 1
-#endif
-
-/*
-** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the
-** sizes of memory allocations below this value where possible.
-*/
-#if !defined(SQLITE_MALLOC_SOFT_LIMIT)
-# define SQLITE_MALLOC_SOFT_LIMIT 1024
-#endif
-
-/*
-** We need to define _XOPEN_SOURCE as follows in order to enable
-** recursive mutexes on most Unix systems. But Mac OS X is different.
-** The _XOPEN_SOURCE define causes problems for Mac OS X we are told,
-** so it is omitted there. See ticket #2673.
-**
-** Later we learn that _XOPEN_SOURCE is poorly or incorrectly
-** implemented on some systems. So we avoid defining it at all
-** if it is already defined or if it is unneeded because we are
-** not doing a threadsafe build. Ticket #2681.
-**
-** See also ticket #2741.
-*/
-#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) && SQLITE_THREADSAFE
-# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */
-#endif
-
-/*
-** The TCL headers are only needed when compiling the TCL bindings.
-*/
-#if defined(SQLITE_TCL) || defined(TCLSH)
-# include <tcl.h>
-#endif
-
-/*
-** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that
-** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true,
-** make it true by defining or undefining NDEBUG.
-**
-** Setting NDEBUG makes the code smaller and run faster by disabling the
-** number assert() statements in the code. So we want the default action
-** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
-** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
-** feature.
-*/
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
-# define NDEBUG 1
-#endif
-#if defined(NDEBUG) && defined(SQLITE_DEBUG)
-# undef NDEBUG
-#endif
-
-/*
-** The testcase() macro is used to aid in coverage testing. When
-** doing coverage testing, the condition inside the argument to
-** testcase() must be evaluated both true and false in order to
-** get full branch coverage. The testcase() macro is inserted
-** to help ensure adequate test coverage in places where simple
-** condition/decision coverage is inadequate. For example, testcase()
-** can be used to make sure boundary values are tested. For
-** bitmask tests, testcase() can be used to make sure each bit
-** is significant and used at least once. On switch statements
-** where multiple cases go to the same block of code, testcase()
-** can insure that all cases are evaluated.
-**
-*/
-#ifdef SQLITE_COVERAGE_TEST
-SQLITE_PRIVATE void sqlite3Coverage(int);
-# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); }
-#else
-# define testcase(X)
-#endif
-
-/*
-** The TESTONLY macro is used to enclose variable declarations or
-** other bits of code that are needed to support the arguments
-** within testcase() and assert() macros.
-*/
-#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST)
-# define TESTONLY(X) X
-#else
-# define TESTONLY(X)
-#endif
-
-/*
-** Sometimes we need a small amount of code such as a variable initialization
-** to setup for a later assert() statement. We do not want this code to
-** appear when assert() is disabled. The following macro is therefore
-** used to contain that setup code. The "VVA" acronym stands for
-** "Verification, Validation, and Accreditation". In other words, the
-** code within VVA_ONLY() will only run during verification processes.
-*/
-#ifndef NDEBUG
-# define VVA_ONLY(X) X
-#else
-# define VVA_ONLY(X)
-#endif
-
-/*
-** The ALWAYS and NEVER macros surround boolean expressions which
-** are intended to always be true or false, respectively. Such
-** expressions could be omitted from the code completely. But they
-** are included in a few cases in order to enhance the resilience
-** of SQLite to unexpected behavior - to make the code "self-healing"
-** or "ductile" rather than being "brittle" and crashing at the first
-** hint of unplanned behavior.
-**
-** In other words, ALWAYS and NEVER are added for defensive code.
-**
-** When doing coverage testing ALWAYS and NEVER are hard-coded to
-** be true and false so that the unreachable code then specify will
-** not be counted as untested code.
-*/
-#if defined(SQLITE_COVERAGE_TEST)
-# define ALWAYS(X) (1)
-# define NEVER(X) (0)
-#elif !defined(NDEBUG)
-# define ALWAYS(X) ((X)?1:(assert(0),0))
-# define NEVER(X) ((X)?(assert(0),1):0)
-#else
-# define ALWAYS(X) (X)
-# define NEVER(X) (X)
-#endif
-
-/*
-** Return true (non-zero) if the input is a integer that is too large
-** to fit in 32-bits. This macro is used inside of various testcase()
-** macros to verify that we have tested SQLite for large-file support.
-*/
-#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0)
-
-/*
-** The macro unlikely() is a hint that surrounds a boolean
-** expression that is usually false. Macro likely() surrounds
-** a boolean expression that is usually true. GCC is able to
-** use these hints to generate better code, sometimes.
-*/
-#if defined(__GNUC__) && 0
-# define likely(X) __builtin_expect((X),1)
-# define unlikely(X) __builtin_expect((X),0)
-#else
-# define likely(X) !!(X)
-# define unlikely(X) !!(X)
-#endif
-
-/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
-/************** Begin file sqlite3.h *****************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This header file defines the interface that the SQLite library
-** presents to client programs. If a C-function, structure, datatype,
-** or constant definition does not appear in this file, then it is
-** not a published API of SQLite, is subject to change without
-** notice, and should not be referenced by programs that use SQLite.
-**
-** Some of the definitions that are in this file are marked as
-** "experimental". Experimental interfaces are normally new
-** features recently added to SQLite. We do not anticipate changes
-** to experimental interfaces but reserve the right to make minor changes
-** if experience from use "in the wild" suggest such changes are prudent.
-**
-** The official C-language API documentation for SQLite is derived
-** from comments in this file. This file is the authoritative source
-** on how SQLite interfaces are suppose to operate.
-**
-** The name of this file under configuration management is "sqlite.h.in".
-** The makefile makes some minor changes to this file (such as inserting
-** the version number) and changes its name to "sqlite3.h" as
-** part of the build process.
-*/
-#ifndef _SQLITE3_H_
-#define _SQLITE3_H_
-#include <stdarg.h> /* Needed for the definition of va_list */
-
-/*
-** Make sure we can call this stuff from C++.
-*/
-#if 0
-extern "C" {
-#endif
-
-
-/*
-** Add the ability to override 'extern'
-*/
-#ifndef SQLITE_EXTERN
-# define SQLITE_EXTERN extern
-#endif
-
-#ifndef SQLITE_API
-# define SQLITE_API
-#endif
-
-
-/*
-** These no-op macros are used in front of interfaces to mark those
-** interfaces as either deprecated or experimental. New applications
-** should not use deprecated interfaces - they are support for backwards
-** compatibility only. Application writers should be aware that
-** experimental interfaces are subject to change in point releases.
-**
-** These macros used to resolve to various kinds of compiler magic that
-** would generate warning messages when they were used. But that
-** compiler magic ended up generating such a flurry of bug reports
-** that we have taken it all out and gone back to using simple
-** noop macros.
-*/
-#define SQLITE_DEPRECATED
-#define SQLITE_EXPERIMENTAL
-
-/*
-** Ensure these symbols were not defined by some previous header file.
-*/
-#ifdef SQLITE_VERSION
-# undef SQLITE_VERSION
-#endif
-#ifdef SQLITE_VERSION_NUMBER
-# undef SQLITE_VERSION_NUMBER
-#endif
-
-/*
-** CAPI3REF: Compile-Time Library Version Numbers
-**
-** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header
-** evaluates to a string literal that is the SQLite version in the
-** format "X.Y.Z" where X is the major version number (always 3 for
-** SQLite3) and Y is the minor version number and Z is the release number.)^
-** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer
-** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
-** numbers used in [SQLITE_VERSION].)^
-** The SQLITE_VERSION_NUMBER for any given release of SQLite will also
-** be larger than the release from which it is derived. Either Y will
-** be held constant and Z will be incremented or else Y will be incremented
-** and Z will be reset to zero.
-**
-** Since version 3.6.18, SQLite source code has been stored in the
-** <a href="http://www.fossil-scm.org/">Fossil configuration management
-** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
-** a string which identifies a particular check-in of SQLite
-** within its configuration management system. ^The SQLITE_SOURCE_ID
-** string contains the date and time of the check-in (UTC) and an SHA1
-** hash of the entire source tree.
-**
-** See also: [sqlite3_libversion()],
-** [sqlite3_libversion_number()], [sqlite3_sourceid()],
-** [sqlite_version()] and [sqlite_source_id()].
-*/
-#define SQLITE_VERSION "3.7.15"
-#define SQLITE_VERSION_NUMBER 3007015
-#define SQLITE_SOURCE_ID "2012-12-12 13:36:53 cd0b37c52658bfdf992b1e3dc467bae1835a94ae"
-
-/*
-** CAPI3REF: Run-Time Library Version Numbers
-** KEYWORDS: sqlite3_version, sqlite3_sourceid
-**
-** These interfaces provide the same information as the [SQLITE_VERSION],
-** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
-** but are associated with the library instead of the header file. ^(Cautious
-** programmers might include assert() statements in their application to
-** verify that values returned by these interfaces match the macros in
-** the header, and thus insure that the application is
-** compiled with matching library and header files.
-**
-** <blockquote><pre>
-** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
-** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
-** </pre></blockquote>)^
-**
-** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION]
-** macro. ^The sqlite3_libversion() function returns a pointer to the
-** to the sqlite3_version[] string constant. The sqlite3_libversion()
-** function is provided for use in DLLs since DLL users usually do not have
-** direct access to string constants within the DLL. ^The
-** sqlite3_libversion_number() function returns an integer equal to
-** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns
-** a pointer to a string constant whose value is the same as the
-** [SQLITE_SOURCE_ID] C preprocessor macro.
-**
-** See also: [sqlite_version()] and [sqlite_source_id()].
-*/
-SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
-SQLITE_API const char *sqlite3_libversion(void);
-SQLITE_API const char *sqlite3_sourceid(void);
-SQLITE_API int sqlite3_libversion_number(void);
-
-/*
-** CAPI3REF: Run-Time Library Compilation Options Diagnostics
-**
-** ^The sqlite3_compileoption_used() function returns 0 or 1
-** indicating whether the specified option was defined at
-** compile time. ^The SQLITE_ prefix may be omitted from the
-** option name passed to sqlite3_compileoption_used().
-**
-** ^The sqlite3_compileoption_get() function allows iterating
-** over the list of options that were defined at compile time by
-** returning the N-th compile time option string. ^If N is out of range,
-** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_
-** prefix is omitted from any strings returned by
-** sqlite3_compileoption_get().
-**
-** ^Support for the diagnostic functions sqlite3_compileoption_used()
-** and sqlite3_compileoption_get() may be omitted by specifying the
-** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time.
-**
-** See also: SQL functions [sqlite_compileoption_used()] and
-** [sqlite_compileoption_get()] and the [compile_options pragma].
-*/
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
-SQLITE_API const char *sqlite3_compileoption_get(int N);
-#endif
-
-/*
-** CAPI3REF: Test To See If The Library Is Threadsafe
-**
-** ^The sqlite3_threadsafe() function returns zero if and only if
-** SQLite was compiled with mutexing code omitted due to the
-** [SQLITE_THREADSAFE] compile-time option being set to 0.
-**
-** SQLite can be compiled with or without mutexes. When
-** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
-** are enabled and SQLite is threadsafe. When the
-** [SQLITE_THREADSAFE] macro is 0,
-** the mutexes are omitted. Without the mutexes, it is not safe
-** to use SQLite concurrently from more than one thread.
-**
-** Enabling mutexes incurs a measurable performance penalty.
-** So if speed is of utmost importance, it makes sense to disable
-** the mutexes. But for maximum safety, mutexes should be enabled.
-** ^The default behavior is for mutexes to be enabled.
-**
-** This interface can be used by an application to make sure that the
-** version of SQLite that it is linking against was compiled with
-** the desired setting of the [SQLITE_THREADSAFE] macro.
-**
-** This interface only reports on the compile-time mutex setting
-** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
-** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
-** can be fully or partially disabled using a call to [sqlite3_config()]
-** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
-** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the
-** sqlite3_threadsafe() function shows only the compile-time setting of
-** thread safety, not any run-time changes to that setting made by
-** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
-** is unchanged by calls to sqlite3_config().)^
-**
-** See the [threading mode] documentation for additional information.
-*/
-SQLITE_API int sqlite3_threadsafe(void);
-
-/*
-** CAPI3REF: Database Connection Handle
-** KEYWORDS: {database connection} {database connections}
-**
-** Each open SQLite database is represented by a pointer to an instance of
-** the opaque structure named "sqlite3". It is useful to think of an sqlite3
-** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
-** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
-** and [sqlite3_close_v2()] are its destructors. There are many other
-** interfaces (such as
-** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
-** [sqlite3_busy_timeout()] to name but three) that are methods on an
-** sqlite3 object.
-*/
-typedef struct sqlite3 sqlite3;
-
-/*
-** CAPI3REF: 64-Bit Integer Types
-** KEYWORDS: sqlite_int64 sqlite_uint64
-**
-** Because there is no cross-platform way to specify 64-bit integer types
-** SQLite includes typedefs for 64-bit signed and unsigned integers.
-**
-** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions.
-** The sqlite_int64 and sqlite_uint64 types are supported for backwards
-** compatibility only.
-**
-** ^The sqlite3_int64 and sqlite_int64 types can store integer values
-** between -9223372036854775808 and +9223372036854775807 inclusive. ^The
-** sqlite3_uint64 and sqlite_uint64 types can store integer values
-** between 0 and +18446744073709551615 inclusive.
-*/
-#ifdef SQLITE_INT64_TYPE
- typedef SQLITE_INT64_TYPE sqlite_int64;
- typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
-#elif defined(_MSC_VER) || defined(__BORLANDC__)
- typedef __int64 sqlite_int64;
- typedef unsigned __int64 sqlite_uint64;
-#else
- typedef long long int sqlite_int64;
- typedef unsigned long long int sqlite_uint64;
-#endif
-typedef sqlite_int64 sqlite3_int64;
-typedef sqlite_uint64 sqlite3_uint64;
-
-/*
-** If compiling for a processor that lacks floating point support,
-** substitute integer for floating-point.
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# define double sqlite3_int64
-#endif
-
-/*
-** CAPI3REF: Closing A Database Connection
-**
-** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
-** for the [sqlite3] object.
-** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
-** the [sqlite3] object is successfully destroyed and all associated
-** resources are deallocated.
-**
-** ^If the database connection is associated with unfinalized prepared
-** statements or unfinished sqlite3_backup objects then sqlite3_close()
-** will leave the database connection open and return [SQLITE_BUSY].
-** ^If sqlite3_close_v2() is called with unfinalized prepared statements
-** and unfinished sqlite3_backups, then the database connection becomes
-** an unusable "zombie" which will automatically be deallocated when the
-** last prepared statement is finalized or the last sqlite3_backup is
-** finished. The sqlite3_close_v2() interface is intended for use with
-** host languages that are garbage collected, and where the order in which
-** destructors are called is arbitrary.
-**
-** Applications should [sqlite3_finalize | finalize] all [prepared statements],
-** [sqlite3_blob_close | close] all [BLOB handles], and
-** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
-** with the [sqlite3] object prior to attempting to close the object. ^If
-** sqlite3_close() is called on a [database connection] that still has
-** outstanding [prepared statements], [BLOB handles], and/or
-** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
-** of resources is deferred until all [prepared statements], [BLOB handles],
-** and [sqlite3_backup] objects are also destroyed.
-**
-** ^If an [sqlite3] object is destroyed while a transaction is open,
-** the transaction is automatically rolled back.
-**
-** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
-** must be either a NULL
-** pointer or an [sqlite3] object pointer obtained
-** from [sqlite3_open()], [sqlite3_open16()], or
-** [sqlite3_open_v2()], and not previously closed.
-** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
-** argument is a harmless no-op.
-*/
-SQLITE_API int sqlite3_close(sqlite3*);
-SQLITE_API int sqlite3_close_v2(sqlite3*);
-
-/*
-** The type for a callback function.
-** This is legacy and deprecated. It is included for historical
-** compatibility and is not documented.
-*/
-typedef int (*sqlite3_callback)(void*,int,char**, char**);
-
-/*
-** CAPI3REF: One-Step Query Execution Interface
-**
-** The sqlite3_exec() interface is a convenience wrapper around
-** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
-** that allows an application to run multiple statements of SQL
-** without having to use a lot of C code.
-**
-** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded,
-** semicolon-separate SQL statements passed into its 2nd argument,
-** in the context of the [database connection] passed in as its 1st
-** argument. ^If the callback function of the 3rd argument to
-** sqlite3_exec() is not NULL, then it is invoked for each result row
-** coming out of the evaluated SQL statements. ^The 4th argument to
-** sqlite3_exec() is relayed through to the 1st argument of each
-** callback invocation. ^If the callback pointer to sqlite3_exec()
-** is NULL, then no callback is ever invoked and result rows are
-** ignored.
-**
-** ^If an error occurs while evaluating the SQL statements passed into
-** sqlite3_exec(), then execution of the current statement stops and
-** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec()
-** is not NULL then any error message is written into memory obtained
-** from [sqlite3_malloc()] and passed back through the 5th parameter.
-** To avoid memory leaks, the application should invoke [sqlite3_free()]
-** on error message strings returned through the 5th parameter of
-** of sqlite3_exec() after the error message string is no longer needed.
-** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
-** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
-** NULL before returning.
-**
-** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec()
-** routine returns SQLITE_ABORT without invoking the callback again and
-** without running any subsequent SQL statements.
-**
-** ^The 2nd argument to the sqlite3_exec() callback function is the
-** number of columns in the result. ^The 3rd argument to the sqlite3_exec()
-** callback is an array of pointers to strings obtained as if from
-** [sqlite3_column_text()], one for each column. ^If an element of a
-** result row is NULL then the corresponding string pointer for the
-** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the
-** sqlite3_exec() callback is an array of pointers to strings where each
-** entry represents the name of corresponding result column as obtained
-** from [sqlite3_column_name()].
-**
-** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer
-** to an empty string, or a pointer that contains only whitespace and/or
-** SQL comments, then no SQL statements are evaluated and the database
-** is not changed.
-**
-** Restrictions:
-**
-** <ul>
-** <li> The application must insure that the 1st parameter to sqlite3_exec()
-** is a valid and open [database connection].
-** <li> The application must not close [database connection] specified by
-** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
-** <li> The application must not modify the SQL statement text passed into
-** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
-** </ul>
-*/
-SQLITE_API int sqlite3_exec(
- sqlite3*, /* An open database */
- const char *sql, /* SQL to be evaluated */
- int (*callback)(void*,int,char**,char**), /* Callback function */
- void *, /* 1st argument to callback */
- char **errmsg /* Error msg written here */
-);
-
-/*
-** CAPI3REF: Result Codes
-** KEYWORDS: SQLITE_OK {error code} {error codes}
-** KEYWORDS: {result code} {result codes}
-**
-** Many SQLite functions return an integer result code from the set shown
-** here in order to indicate success or failure.
-**
-** New error codes may be added in future versions of SQLite.
-**
-** See also: [SQLITE_IOERR_READ | extended result codes],
-** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes].
-*/
-#define SQLITE_OK 0 /* Successful result */
-/* beginning-of-error-codes */
-#define SQLITE_ERROR 1 /* SQL error or missing database */
-#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */
-#define SQLITE_PERM 3 /* Access permission denied */
-#define SQLITE_ABORT 4 /* Callback routine requested an abort */
-#define SQLITE_BUSY 5 /* The database file is locked */
-#define SQLITE_LOCKED 6 /* A table in the database is locked */
-#define SQLITE_NOMEM 7 /* A malloc() failed */
-#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
-#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
-#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
-#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
-#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */
-#define SQLITE_FULL 13 /* Insertion failed because database is full */
-#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
-#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
-#define SQLITE_EMPTY 16 /* Database is empty */
-#define SQLITE_SCHEMA 17 /* The database schema changed */
-#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
-#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
-#define SQLITE_MISMATCH 20 /* Data type mismatch */
-#define SQLITE_MISUSE 21 /* Library used incorrectly */
-#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
-#define SQLITE_AUTH 23 /* Authorization denied */
-#define SQLITE_FORMAT 24 /* Auxiliary database format error */
-#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
-#define SQLITE_NOTADB 26 /* File opened that is not a database file */
-#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
-#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
-/* end-of-error-codes */
-
-/*
-** CAPI3REF: Extended Result Codes
-** KEYWORDS: {extended error code} {extended error codes}
-** KEYWORDS: {extended result code} {extended result codes}
-**
-** In its default configuration, SQLite API routines return one of 26 integer
-** [SQLITE_OK | result codes]. However, experience has shown that many of
-** these result codes are too coarse-grained. They do not provide as
-** much information about problems as programmers might like. In an effort to
-** address this, newer versions of SQLite (version 3.3.8 and later) include
-** support for additional result codes that provide more detailed information
-** about errors. The extended result codes are enabled or disabled
-** on a per database connection basis using the
-** [sqlite3_extended_result_codes()] API.
-**
-** Some of the available extended result codes are listed here.
-** One may expect the number of extended result codes will be expand
-** over time. Software that uses extended result codes should expect
-** to see new result codes in future releases of SQLite.
-**
-** The SQLITE_OK result code will never be extended. It will always
-** be exactly zero.
-*/
-#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
-#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
-#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
-#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8))
-#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8))
-#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8))
-#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8))
-#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8))
-#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8))
-#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8))
-#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8))
-#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8))
-#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8))
-#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
-#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8))
-#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8))
-#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8))
-#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8))
-#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8))
-#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
-#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
-#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
-#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
-#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
-#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
-#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
-#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
-#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
-#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
-#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
-#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
-#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
-
-/*
-** CAPI3REF: Flags For File Open Operations
-**
-** These bit values are intended for use in the
-** 3rd parameter to the [sqlite3_open_v2()] interface and
-** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
-*/
-#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
-#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
-#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */
-#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
-#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
-#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
-#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
-#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
-#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
-#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
-#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
-
-/* Reserved: 0x00F00000 */
-
-/*
-** CAPI3REF: Device Characteristics
-**
-** The xDeviceCharacteristics method of the [sqlite3_io_methods]
-** object returns an integer which is a vector of these
-** bit values expressing I/O characteristics of the mass storage
-** device that holds the file that the [sqlite3_io_methods]
-** refers to.
-**
-** The SQLITE_IOCAP_ATOMIC property means that all writes of
-** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values
-** mean that writes of blocks that are nnn bytes in size and
-** are aligned to an address which is an integer multiple of
-** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means
-** that when data is appended to a file, the data is appended
-** first then the size of the file is extended, never the other
-** way around. The SQLITE_IOCAP_SEQUENTIAL property means that
-** information is written to disk in the same order as calls
-** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that
-** after reboot following a crash or power loss, the only bytes in a
-** file that were written at the application level might have changed
-** and that adjacent bytes, even bytes within the same sector are
-** guaranteed to be unchanged.
-*/
-#define SQLITE_IOCAP_ATOMIC 0x00000001
-#define SQLITE_IOCAP_ATOMIC512 0x00000002
-#define SQLITE_IOCAP_ATOMIC1K 0x00000004
-#define SQLITE_IOCAP_ATOMIC2K 0x00000008
-#define SQLITE_IOCAP_ATOMIC4K 0x00000010
-#define SQLITE_IOCAP_ATOMIC8K 0x00000020
-#define SQLITE_IOCAP_ATOMIC16K 0x00000040
-#define SQLITE_IOCAP_ATOMIC32K 0x00000080
-#define SQLITE_IOCAP_ATOMIC64K 0x00000100
-#define SQLITE_IOCAP_SAFE_APPEND 0x00000200
-#define SQLITE_IOCAP_SEQUENTIAL 0x00000400
-#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
-#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
-
-/*
-** CAPI3REF: File Locking Levels
-**
-** SQLite uses one of these integer values as the second
-** argument to calls it makes to the xLock() and xUnlock() methods
-** of an [sqlite3_io_methods] object.
-*/
-#define SQLITE_LOCK_NONE 0
-#define SQLITE_LOCK_SHARED 1
-#define SQLITE_LOCK_RESERVED 2
-#define SQLITE_LOCK_PENDING 3
-#define SQLITE_LOCK_EXCLUSIVE 4
-
-/*
-** CAPI3REF: Synchronization Type Flags
-**
-** When SQLite invokes the xSync() method of an
-** [sqlite3_io_methods] object it uses a combination of
-** these integer values as the second argument.
-**
-** When the SQLITE_SYNC_DATAONLY flag is used, it means that the
-** sync operation only needs to flush data to mass storage. Inode
-** information need not be flushed. If the lower four bits of the flag
-** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics.
-** If the lower four bits equal SQLITE_SYNC_FULL, that means
-** to use Mac OS X style fullsync instead of fsync().
-**
-** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags
-** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL
-** settings. The [synchronous pragma] determines when calls to the
-** xSync VFS method occur and applies uniformly across all platforms.
-** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how
-** energetic or rigorous or forceful the sync operations are and
-** only make a difference on Mac OSX for the default SQLite code.
-** (Third-party VFS implementations might also make the distinction
-** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the
-** operating systems natively supported by SQLite, only Mac OSX
-** cares about the difference.)
-*/
-#define SQLITE_SYNC_NORMAL 0x00002
-#define SQLITE_SYNC_FULL 0x00003
-#define SQLITE_SYNC_DATAONLY 0x00010
-
-/*
-** CAPI3REF: OS Interface Open File Handle
-**
-** An [sqlite3_file] object represents an open file in the
-** [sqlite3_vfs | OS interface layer]. Individual OS interface
-** implementations will
-** want to subclass this object by appending additional fields
-** for their own use. The pMethods entry is a pointer to an
-** [sqlite3_io_methods] object that defines methods for performing
-** I/O operations on the open file.
-*/
-typedef struct sqlite3_file sqlite3_file;
-struct sqlite3_file {
- const struct sqlite3_io_methods *pMethods; /* Methods for an open file */
-};
-
-/*
-** CAPI3REF: OS Interface File Virtual Methods Object
-**
-** Every file opened by the [sqlite3_vfs.xOpen] method populates an
-** [sqlite3_file] object (or, more commonly, a subclass of the
-** [sqlite3_file] object) with a pointer to an instance of this object.
-** This object defines the methods used to perform various operations
-** against the open file represented by the [sqlite3_file] object.
-**
-** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element
-** to a non-NULL pointer, then the sqlite3_io_methods.xClose method
-** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The
-** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen]
-** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element
-** to NULL.
-**
-** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or
-** [SQLITE_SYNC_FULL]. The first choice is the normal fsync().
-** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY]
-** flag may be ORed in to indicate that only the data of the file
-** and not its inode needs to be synced.
-**
-** The integer values to xLock() and xUnlock() are one of
-** <ul>
-** <li> [SQLITE_LOCK_NONE],
-** <li> [SQLITE_LOCK_SHARED],
-** <li> [SQLITE_LOCK_RESERVED],
-** <li> [SQLITE_LOCK_PENDING], or
-** <li> [SQLITE_LOCK_EXCLUSIVE].
-** </ul>
-** xLock() increases the lock. xUnlock() decreases the lock.
-** The xCheckReservedLock() method checks whether any database connection,
-** either in this process or in some other process, is holding a RESERVED,
-** PENDING, or EXCLUSIVE lock on the file. It returns true
-** if such a lock exists and false otherwise.
-**
-** The xFileControl() method is a generic interface that allows custom
-** VFS implementations to directly control an open file using the
-** [sqlite3_file_control()] interface. The second "op" argument is an
-** integer opcode. The third argument is a generic pointer intended to
-** point to a structure that may contain arguments or space in which to
-** write return values. Potential uses for xFileControl() might be
-** functions to enable blocking locks with timeouts, to change the
-** locking strategy (for example to use dot-file locks), to inquire
-** about the status of a lock, or to break stale locks. The SQLite
-** core reserves all opcodes less than 100 for its own use.
-** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
-** Applications that define a custom xFileControl method should use opcodes
-** greater than 100 to avoid conflicts. VFS implementations should
-** return [SQLITE_NOTFOUND] for file control opcodes that they do not
-** recognize.
-**
-** The xSectorSize() method returns the sector size of the
-** device that underlies the file. The sector size is the
-** minimum write that can be performed without disturbing
-** other bytes in the file. The xDeviceCharacteristics()
-** method returns a bit vector describing behaviors of the
-** underlying device:
-**
-** <ul>
-** <li> [SQLITE_IOCAP_ATOMIC]
-** <li> [SQLITE_IOCAP_ATOMIC512]
-** <li> [SQLITE_IOCAP_ATOMIC1K]
-** <li> [SQLITE_IOCAP_ATOMIC2K]
-** <li> [SQLITE_IOCAP_ATOMIC4K]
-** <li> [SQLITE_IOCAP_ATOMIC8K]
-** <li> [SQLITE_IOCAP_ATOMIC16K]
-** <li> [SQLITE_IOCAP_ATOMIC32K]
-** <li> [SQLITE_IOCAP_ATOMIC64K]
-** <li> [SQLITE_IOCAP_SAFE_APPEND]
-** <li> [SQLITE_IOCAP_SEQUENTIAL]
-** </ul>
-**
-** The SQLITE_IOCAP_ATOMIC property means that all writes of
-** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values
-** mean that writes of blocks that are nnn bytes in size and
-** are aligned to an address which is an integer multiple of
-** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means
-** that when data is appended to a file, the data is appended
-** first then the size of the file is extended, never the other
-** way around. The SQLITE_IOCAP_SEQUENTIAL property means that
-** information is written to disk in the same order as calls
-** to xWrite().
-**
-** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill
-** in the unread portions of the buffer with zeros. A VFS that
-** fails to zero-fill short reads might seem to work. However,
-** failure to zero-fill short reads will eventually lead to
-** database corruption.
-*/
-typedef struct sqlite3_io_methods sqlite3_io_methods;
-struct sqlite3_io_methods {
- int iVersion;
- int (*xClose)(sqlite3_file*);
- int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
- int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
- int (*xTruncate)(sqlite3_file*, sqlite3_int64 size);
- int (*xSync)(sqlite3_file*, int flags);
- int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
- int (*xLock)(sqlite3_file*, int);
- int (*xUnlock)(sqlite3_file*, int);
- int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
- int (*xFileControl)(sqlite3_file*, int op, void *pArg);
- int (*xSectorSize)(sqlite3_file*);
- int (*xDeviceCharacteristics)(sqlite3_file*);
- /* Methods above are valid for version 1 */
- int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
- int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
- void (*xShmBarrier)(sqlite3_file*);
- int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
- /* Methods above are valid for version 2 */
- /* Additional methods may be added in future releases */
-};
-
-/*
-** CAPI3REF: Standard File Control Opcodes
-**
-** These integer constants are opcodes for the xFileControl method
-** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
-** interface.
-**
-** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This
-** opcode causes the xFileControl method to write the current state of
-** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
-** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
-** into an integer that the pArg argument points to. This capability
-** is used during testing and only needs to be supported when SQLITE_TEST
-** is defined.
-** <ul>
-** <li>[[SQLITE_FCNTL_SIZE_HINT]]
-** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
-** layer a hint of how large the database file will grow to be during the
-** current transaction. This hint is not guaranteed to be accurate but it
-** is often close. The underlying VFS might choose to preallocate database
-** file space based on this hint in order to help writes to the database
-** file run faster.
-**
-** <li>[[SQLITE_FCNTL_CHUNK_SIZE]]
-** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
-** extends and truncates the database file in chunks of a size specified
-** by the user. The fourth argument to [sqlite3_file_control()] should
-** point to an integer (type int) containing the new chunk-size to use
-** for the nominated database. Allocating database file space in large
-** chunks (say 1MB at a time), may reduce file-system fragmentation and
-** improve performance on some systems.
-**
-** <li>[[SQLITE_FCNTL_FILE_POINTER]]
-** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
-** to the [sqlite3_file] object associated with a particular database
-** connection. See the [sqlite3_file_control()] documentation for
-** additional information.
-**
-** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
-** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
-** SQLite and sent to all VFSes in place of a call to the xSync method
-** when the database connection has [PRAGMA synchronous] set to OFF.)^
-** Some specialized VFSes need this signal in order to operate correctly
-** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most
-** VFSes do not need this signal and should silently ignore this opcode.
-** Applications should not call [sqlite3_file_control()] with this
-** opcode as doing so may disrupt the operation of the specialized VFSes
-** that do require it.
-**
-** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]]
-** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
-** retry counts and intervals for certain disk I/O operations for the
-** windows [VFS] in order to provide robustness in the presence of
-** anti-virus programs. By default, the windows VFS will retry file read,
-** file write, and file delete operations up to 10 times, with a delay
-** of 25 milliseconds before the first retry and with the delay increasing
-** by an additional 25 milliseconds with each subsequent retry. This
-** opcode allows these two values (10 retries and 25 milliseconds of delay)
-** to be adjusted. The values are changed for all database connections
-** within the same process. The argument is a pointer to an array of two
-** integers where the first integer i the new retry count and the second
-** integer is the delay. If either integer is negative, then the setting
-** is not changed but instead the prior value of that setting is written
-** into the array entry, allowing the current retry settings to be
-** interrogated. The zDbName parameter is ignored.
-**
-** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
-** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
-** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary
-** write ahead log and shared memory files used for transaction control
-** are automatically deleted when the latest connection to the database
-** closes. Setting persistent WAL mode causes those files to persist after
-** close. Persisting the files is useful when other processes that do not
-** have write permission on the directory containing the database file want
-** to read the database file, as the WAL and shared memory files must exist
-** in order for the database to be readable. The fourth parameter to
-** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
-** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
-** WAL mode. If the integer is -1, then it is overwritten with the current
-** WAL persistence setting.
-**
-** <li>[[SQLITE_FCNTL_POWERSAFE_OVERWRITE]]
-** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the
-** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting
-** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the
-** xDeviceCharacteristics methods. The fourth parameter to
-** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
-** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage
-** mode. If the integer is -1, then it is overwritten with the current
-** zero-damage mode setting.
-**
-** <li>[[SQLITE_FCNTL_OVERWRITE]]
-** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
-** a write transaction to indicate that, unless it is rolled back for some
-** reason, the entire database file will be overwritten by the current
-** transaction. This is used by VACUUM operations.
-**
-** <li>[[SQLITE_FCNTL_VFSNAME]]
-** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of
-** all [VFSes] in the VFS stack. The names are of all VFS shims and the
-** final bottom-level VFS are written into memory obtained from
-** [sqlite3_malloc()] and the result is stored in the char* variable
-** that the fourth parameter of [sqlite3_file_control()] points to.
-** The caller is responsible for freeing the memory when done. As with
-** all file-control actions, there is no guarantee that this will actually
-** do anything. Callers should initialize the char* variable to a NULL
-** pointer in case this file-control is not implemented. This file-control
-** is intended for diagnostic use only.
-**
-** <li>[[SQLITE_FCNTL_PRAGMA]]
-** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA]
-** file control is sent to the open [sqlite3_file] object corresponding
-** to the database file to which the pragma statement refers. ^The argument
-** to the [SQLITE_FCNTL_PRAGMA] file control is an array of
-** pointers to strings (char**) in which the second element of the array
-** is the name of the pragma and the third element is the argument to the
-** pragma or NULL if the pragma has no argument. ^The handler for an
-** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element
-** of the char** argument point to a string obtained from [sqlite3_mprintf()]
-** or the equivalent and that string will become the result of the pragma or
-** the error message if the pragma fails. ^If the
-** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal
-** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA]
-** file control returns [SQLITE_OK], then the parser assumes that the
-** VFS has handled the PRAGMA itself and the parser generates a no-op
-** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns
-** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
-** that the VFS encountered an error while handling the [PRAGMA] and the
-** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA]
-** file control occurs at the beginning of pragma statement analysis and so
-** it is able to override built-in [PRAGMA] statements.
-**
-** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
-** ^This file-control may be invoked by SQLite on the database file handle
-** shortly after it is opened in order to provide a custom VFS with access
-** to the connections busy-handler callback. The argument is of type (void **)
-** - an array of two (void *) values. The first (void *) actually points
-** to a function of type (int (*)(void *)). In order to invoke the connections
-** busy-handler, this function should be invoked with the second (void *) in
-** the array as the only argument. If it returns non-zero, then the operation
-** should be retried. If it returns zero, the custom VFS should abandon the
-** current operation.
-**
-** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
-** ^Application can invoke this file-control to have SQLite generate a
-** temporary filename using the same algorithm that is followed to generate
-** temporary filenames for TEMP tables and other internal uses. The
-** argument should be a char** which will be filled with the filename
-** written into memory obtained from [sqlite3_malloc()]. The caller should
-** invoke [sqlite3_free()] on the result to avoid a memory leak.
-**
-** </ul>
-*/
-#define SQLITE_FCNTL_LOCKSTATE 1
-#define SQLITE_GET_LOCKPROXYFILE 2
-#define SQLITE_SET_LOCKPROXYFILE 3
-#define SQLITE_LAST_ERRNO 4
-#define SQLITE_FCNTL_SIZE_HINT 5
-#define SQLITE_FCNTL_CHUNK_SIZE 6
-#define SQLITE_FCNTL_FILE_POINTER 7
-#define SQLITE_FCNTL_SYNC_OMITTED 8
-#define SQLITE_FCNTL_WIN32_AV_RETRY 9
-#define SQLITE_FCNTL_PERSIST_WAL 10
-#define SQLITE_FCNTL_OVERWRITE 11
-#define SQLITE_FCNTL_VFSNAME 12
-#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
-#define SQLITE_FCNTL_PRAGMA 14
-#define SQLITE_FCNTL_BUSYHANDLER 15
-#define SQLITE_FCNTL_TEMPFILENAME 16
-
-/*
-** CAPI3REF: Mutex Handle
-**
-** The mutex module within SQLite defines [sqlite3_mutex] to be an
-** abstract type for a mutex object. The SQLite core never looks
-** at the internal representation of an [sqlite3_mutex]. It only
-** deals with pointers to the [sqlite3_mutex] object.
-**
-** Mutexes are created using [sqlite3_mutex_alloc()].
-*/
-typedef struct sqlite3_mutex sqlite3_mutex;
-
-/*
-** CAPI3REF: OS Interface Object
-**
-** An instance of the sqlite3_vfs object defines the interface between
-** the SQLite core and the underlying operating system. The "vfs"
-** in the name of the object stands for "virtual file system". See
-** the [VFS | VFS documentation] for further information.
-**
-** The value of the iVersion field is initially 1 but may be larger in
-** future versions of SQLite. Additional fields may be appended to this
-** object when the iVersion value is increased. Note that the structure
-** of the sqlite3_vfs object changes in the transaction between
-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
-** modified.
-**
-** The szOsFile field is the size of the subclassed [sqlite3_file]
-** structure used by this VFS. mxPathname is the maximum length of
-** a pathname in this VFS.
-**
-** Registered sqlite3_vfs objects are kept on a linked list formed by
-** the pNext pointer. The [sqlite3_vfs_register()]
-** and [sqlite3_vfs_unregister()] interfaces manage this list
-** in a thread-safe way. The [sqlite3_vfs_find()] interface
-** searches the list. Neither the application code nor the VFS
-** implementation should use the pNext pointer.
-**
-** The pNext field is the only field in the sqlite3_vfs
-** structure that SQLite will ever modify. SQLite will only access
-** or modify this field while holding a particular static mutex.
-** The application should never modify anything within the sqlite3_vfs
-** object once the object has been registered.
-**
-** The zName field holds the name of the VFS module. The name must
-** be unique across all VFS modules.
-**
-** [[sqlite3_vfs.xOpen]]
-** ^SQLite guarantees that the zFilename parameter to xOpen
-** is either a NULL pointer or string obtained
-** from xFullPathname() with an optional suffix added.
-** ^If a suffix is added to the zFilename parameter, it will
-** consist of a single "-" character followed by no more than
-** 11 alphanumeric and/or "-" characters.
-** ^SQLite further guarantees that
-** the string will be valid and unchanged until xClose() is
-** called. Because of the previous sentence,
-** the [sqlite3_file] can safely store a pointer to the
-** filename if it needs to remember the filename for some reason.
-** If the zFilename parameter to xOpen is a NULL pointer then xOpen
-** must invent its own temporary name for the file. ^Whenever the
-** xFilename parameter is NULL it will also be the case that the
-** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
-**
-** The flags argument to xOpen() includes all bits set in
-** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()]
-** or [sqlite3_open16()] is used, then flags includes at least
-** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE].
-** If xOpen() opens a file read-only then it sets *pOutFlags to
-** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set.
-**
-** ^(SQLite will also add one of the following flags to the xOpen()
-** call, depending on the object being opened:
-**
-** <ul>
-** <li> [SQLITE_OPEN_MAIN_DB]
-** <li> [SQLITE_OPEN_MAIN_JOURNAL]
-** <li> [SQLITE_OPEN_TEMP_DB]
-** <li> [SQLITE_OPEN_TEMP_JOURNAL]
-** <li> [SQLITE_OPEN_TRANSIENT_DB]
-** <li> [SQLITE_OPEN_SUBJOURNAL]
-** <li> [SQLITE_OPEN_MASTER_JOURNAL]
-** <li> [SQLITE_OPEN_WAL]
-** </ul>)^
-**
-** The file I/O implementation can use the object type flags to
-** change the way it deals with files. For example, an application
-** that does not care about crash recovery or rollback might make
-** the open of a journal file a no-op. Writes to this journal would
-** also be no-ops, and any attempt to read the journal would return
-** SQLITE_IOERR. Or the implementation might recognize that a database
-** file will be doing page-aligned sector reads and writes in a random
-** order and set up its I/O subsystem accordingly.
-**
-** SQLite might also add one of the following flags to the xOpen method:
-**
-** <ul>
-** <li> [SQLITE_OPEN_DELETEONCLOSE]
-** <li> [SQLITE_OPEN_EXCLUSIVE]
-** </ul>
-**
-** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
-** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE]
-** will be set for TEMP databases and their journals, transient
-** databases, and subjournals.
-**
-** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
-** with the [SQLITE_OPEN_CREATE] flag, which are both directly
-** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
-** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the
-** SQLITE_OPEN_CREATE, is used to indicate that file should always
-** be created, and that it is an error if it already exists.
-** It is <i>not</i> used to indicate the file should be opened
-** for exclusive access.
-**
-** ^At least szOsFile bytes of memory are allocated by SQLite
-** to hold the [sqlite3_file] structure passed as the third
-** argument to xOpen. The xOpen method does not have to
-** allocate the structure; it should just fill it in. Note that
-** the xOpen method must set the sqlite3_file.pMethods to either
-** a valid [sqlite3_io_methods] object or to NULL. xOpen must do
-** this even if the open fails. SQLite expects that the sqlite3_file.pMethods
-** element will be valid after xOpen returns regardless of the success
-** or failure of the xOpen call.
-**
-** [[sqlite3_vfs.xAccess]]
-** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
-** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
-** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test whether a file is at least readable. The file can be a
-** directory.
-**
-** ^SQLite will always allocate at least mxPathname+1 bytes for the
-** output buffer xFullPathname. The exact size of the output buffer
-** is also passed as a parameter to both methods. If the output buffer
-** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
-** handled as a fatal error by SQLite, vfs implementations should endeavor
-** to prevent this by setting mxPathname to a sufficiently large value.
-**
-** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64()
-** interfaces are not strictly a part of the filesystem, but they are
-** included in the VFS structure for completeness.
-** The xRandomness() function attempts to return nBytes bytes
-** of good-quality randomness into zOut. The return value is
-** the actual number of bytes of randomness obtained.
-** The xSleep() method causes the calling thread to sleep for at
-** least the number of microseconds given. ^The xCurrentTime()
-** method returns a Julian Day Number for the current date and time as
-** a floating point value.
-** ^The xCurrentTimeInt64() method returns, as an integer, the Julian
-** Day Number multiplied by 86400000 (the number of milliseconds in
-** a 24-hour day).
-** ^SQLite will use the xCurrentTimeInt64() method to get the current
-** date and time if that method is available (if iVersion is 2 or
-** greater and the function pointer is not NULL) and will fall back
-** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
-**
-** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces
-** are not used by the SQLite core. These optional interfaces are provided
-** by some VFSes to facilitate testing of the VFS code. By overriding
-** system calls with functions under its control, a test program can
-** simulate faults and error conditions that would otherwise be difficult
-** or impossible to induce. The set of system calls that can be overridden
-** varies from one VFS to another, and from one version of the same VFS to the
-** next. Applications that use these interfaces must be prepared for any
-** or all of these interfaces to be NULL or for their behavior to change
-** from one release to the next. Applications must not attempt to access
-** any of these methods if the iVersion of the VFS is less than 3.
-*/
-typedef struct sqlite3_vfs sqlite3_vfs;
-typedef void (*sqlite3_syscall_ptr)(void);
-struct sqlite3_vfs {
- int iVersion; /* Structure version number (currently 3) */
- int szOsFile; /* Size of subclassed sqlite3_file */
- int mxPathname; /* Maximum file pathname length */
- sqlite3_vfs *pNext; /* Next registered VFS */
- const char *zName; /* Name of this virtual file system */
- void *pAppData; /* Pointer to application-specific data */
- int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
- int flags, int *pOutFlags);
- int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
- int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
- int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
- void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
- void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
- void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
- void (*xDlClose)(sqlite3_vfs*, void*);
- int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
- int (*xSleep)(sqlite3_vfs*, int microseconds);
- int (*xCurrentTime)(sqlite3_vfs*, double*);
- int (*xGetLastError)(sqlite3_vfs*, int, char *);
- /*
- ** The methods above are in version 1 of the sqlite_vfs object
- ** definition. Those that follow are added in version 2 or later
- */
- int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
- /*
- ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
- ** Those below are for version 3 and greater.
- */
- int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr);
- sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName);
- const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
- /*
- ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
- ** New fields may be appended in figure versions. The iVersion
- ** value will increment whenever this happens.
- */
-};
-
-/*
-** CAPI3REF: Flags for the xAccess VFS method
-**
-** These integer constants can be used as the third parameter to
-** the xAccess method of an [sqlite3_vfs] object. They determine
-** what kind of permissions the xAccess method is looking for.
-** With SQLITE_ACCESS_EXISTS, the xAccess method
-** simply checks whether the file exists.
-** With SQLITE_ACCESS_READWRITE, the xAccess method
-** checks whether the named directory is both readable and writable
-** (in other words, if files can be added, removed, and renamed within
-** the directory).
-** The SQLITE_ACCESS_READWRITE constant is currently used only by the
-** [temp_store_directory pragma], though this could change in a future
-** release of SQLite.
-** With SQLITE_ACCESS_READ, the xAccess method
-** checks whether the file is readable. The SQLITE_ACCESS_READ constant is
-** currently unused, though it might be used in a future release of
-** SQLite.
-*/
-#define SQLITE_ACCESS_EXISTS 0
-#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */
-#define SQLITE_ACCESS_READ 2 /* Unused */
-
-/*
-** CAPI3REF: Flags for the xShmLock VFS method
-**
-** These integer constants define the various locking operations
-** allowed by the xShmLock method of [sqlite3_io_methods]. The
-** following are the only legal combinations of flags to the
-** xShmLock method:
-**
-** <ul>
-** <li> SQLITE_SHM_LOCK | SQLITE_SHM_SHARED
-** <li> SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE
-** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED
-** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE
-** </ul>
-**
-** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
-** was given no the corresponding lock.
-**
-** The xShmLock method can transition between unlocked and SHARED or
-** between unlocked and EXCLUSIVE. It cannot transition between SHARED
-** and EXCLUSIVE.
-*/
-#define SQLITE_SHM_UNLOCK 1
-#define SQLITE_SHM_LOCK 2
-#define SQLITE_SHM_SHARED 4
-#define SQLITE_SHM_EXCLUSIVE 8
-
-/*
-** CAPI3REF: Maximum xShmLock index
-**
-** The xShmLock method on [sqlite3_io_methods] may use values
-** between 0 and this upper bound as its "offset" argument.
-** The SQLite core will never attempt to acquire or release a
-** lock outside of this range
-*/
-#define SQLITE_SHM_NLOCK 8
-
-
-/*
-** CAPI3REF: Initialize The SQLite Library
-**
-** ^The sqlite3_initialize() routine initializes the
-** SQLite library. ^The sqlite3_shutdown() routine
-** deallocates any resources that were allocated by sqlite3_initialize().
-** These routines are designed to aid in process initialization and
-** shutdown on embedded systems. Workstation applications using
-** SQLite normally do not need to invoke either of these routines.
-**
-** A call to sqlite3_initialize() is an "effective" call if it is
-** the first time sqlite3_initialize() is invoked during the lifetime of
-** the process, or if it is the first time sqlite3_initialize() is invoked
-** following a call to sqlite3_shutdown(). ^(Only an effective call
-** of sqlite3_initialize() does any initialization. All other calls
-** are harmless no-ops.)^
-**
-** A call to sqlite3_shutdown() is an "effective" call if it is the first
-** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only
-** an effective call to sqlite3_shutdown() does any deinitialization.
-** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^
-**
-** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown()
-** is not. The sqlite3_shutdown() interface must only be called from a
-** single thread. All open [database connections] must be closed and all
-** other SQLite resources must be deallocated prior to invoking
-** sqlite3_shutdown().
-**
-** Among other things, ^sqlite3_initialize() will invoke
-** sqlite3_os_init(). Similarly, ^sqlite3_shutdown()
-** will invoke sqlite3_os_end().
-**
-** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success.
-** ^If for some reason, sqlite3_initialize() is unable to initialize
-** the library (perhaps it is unable to allocate a needed resource such
-** as a mutex) it returns an [error code] other than [SQLITE_OK].
-**
-** ^The sqlite3_initialize() routine is called internally by many other
-** SQLite interfaces so that an application usually does not need to
-** invoke sqlite3_initialize() directly. For example, [sqlite3_open()]
-** calls sqlite3_initialize() so the SQLite library will be automatically
-** initialized when [sqlite3_open()] is called if it has not be initialized
-** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT]
-** compile-time option, then the automatic calls to sqlite3_initialize()
-** are omitted and the application must call sqlite3_initialize() directly
-** prior to using any other SQLite interface. For maximum portability,
-** it is recommended that applications always invoke sqlite3_initialize()
-** directly prior to using any other SQLite interface. Future releases
-** of SQLite may require this. In other words, the behavior exhibited
-** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the
-** default behavior in some future release of SQLite.
-**
-** The sqlite3_os_init() routine does operating-system specific
-** initialization of the SQLite library. The sqlite3_os_end()
-** routine undoes the effect of sqlite3_os_init(). Typical tasks
-** performed by these routines include allocation or deallocation
-** of static resources, initialization of global variables,
-** setting up a default [sqlite3_vfs] module, or setting up
-** a default configuration using [sqlite3_config()].
-**
-** The application should never invoke either sqlite3_os_init()
-** or sqlite3_os_end() directly. The application should only invoke
-** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init()
-** interface is called automatically by sqlite3_initialize() and
-** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate
-** implementations for sqlite3_os_init() and sqlite3_os_end()
-** are built into SQLite when it is compiled for Unix, Windows, or OS/2.
-** When [custom builds | built for other platforms]
-** (using the [SQLITE_OS_OTHER=1] compile-time
-** option) the application must supply a suitable implementation for
-** sqlite3_os_init() and sqlite3_os_end(). An application-supplied
-** implementation of sqlite3_os_init() or sqlite3_os_end()
-** must return [SQLITE_OK] on success and some other [error code] upon
-** failure.
-*/
-SQLITE_API int sqlite3_initialize(void);
-SQLITE_API int sqlite3_shutdown(void);
-SQLITE_API int sqlite3_os_init(void);
-SQLITE_API int sqlite3_os_end(void);
-
-/*
-** CAPI3REF: Configuring The SQLite Library
-**
-** The sqlite3_config() interface is used to make global configuration
-** changes to SQLite in order to tune SQLite to the specific needs of
-** the application. The default configuration is recommended for most
-** applications and so this routine is usually not necessary. It is
-** provided to support rare applications with unusual needs.
-**
-** The sqlite3_config() interface is not threadsafe. The application
-** must insure that no other SQLite interfaces are invoked by other
-** threads while sqlite3_config() is running. Furthermore, sqlite3_config()
-** may only be invoked prior to library initialization using
-** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
-** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
-** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
-** Note, however, that ^sqlite3_config() can be called as part of the
-** implementation of an application-defined [sqlite3_os_init()].
-**
-** The first argument to sqlite3_config() is an integer
-** [configuration option] that determines
-** what property of SQLite is to be configured. Subsequent arguments
-** vary depending on the [configuration option]
-** in the first argument.
-**
-** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
-** ^If the option is unknown or SQLite is unable to set the option
-** then this routine returns a non-zero [error code].
-*/
-SQLITE_API int sqlite3_config(int, ...);
-
-/*
-** CAPI3REF: Configure database connections
-**
-** The sqlite3_db_config() interface is used to make configuration
-** changes to a [database connection]. The interface is similar to
-** [sqlite3_config()] except that the changes apply to a single
-** [database connection] (specified in the first argument).
-**
-** The second argument to sqlite3_db_config(D,V,...) is the
-** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code
-** that indicates what aspect of the [database connection] is being configured.
-** Subsequent arguments vary depending on the configuration verb.
-**
-** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
-** the call is considered successful.
-*/
-SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
-
-/*
-** CAPI3REF: Memory Allocation Routines
-**
-** An instance of this object defines the interface between SQLite
-** and low-level memory allocation routines.
-**
-** This object is used in only one place in the SQLite interface.
-** A pointer to an instance of this object is the argument to
-** [sqlite3_config()] when the configuration option is
-** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].
-** By creating an instance of this object
-** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC])
-** during configuration, an application can specify an alternative
-** memory allocation subsystem for SQLite to use for all of its
-** dynamic memory needs.
-**
-** Note that SQLite comes with several [built-in memory allocators]
-** that are perfectly adequate for the overwhelming majority of applications
-** and that this object is only useful to a tiny minority of applications
-** with specialized memory allocation requirements. This object is
-** also used during testing of SQLite in order to specify an alternative
-** memory allocator that simulates memory out-of-memory conditions in
-** order to verify that SQLite recovers gracefully from such
-** conditions.
-**
-** The xMalloc, xRealloc, and xFree methods must work like the
-** malloc(), realloc() and free() functions from the standard C library.
-** ^SQLite guarantees that the second argument to
-** xRealloc is always a value returned by a prior call to xRoundup.
-**
-** xSize should return the allocated size of a memory allocation
-** previously obtained from xMalloc or xRealloc. The allocated size
-** is always at least as big as the requested size but may be larger.
-**
-** The xRoundup method returns what would be the allocated size of
-** a memory allocation given a particular requested size. Most memory
-** allocators round up memory allocations at least to the next multiple
-** of 8. Some allocators round up to a larger multiple or to a power of 2.
-** Every memory allocation request coming in through [sqlite3_malloc()]
-** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0,
-** that causes the corresponding memory allocation to fail.
-**
-** The xInit method initializes the memory allocator. (For example,
-** it might allocate any require mutexes or initialize internal data
-** structures. The xShutdown method is invoked (indirectly) by
-** [sqlite3_shutdown()] and should deallocate any resources acquired
-** by xInit. The pAppData pointer is used as the only parameter to
-** xInit and xShutdown.
-**
-** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
-** the xInit method, so the xInit method need not be threadsafe. The
-** xShutdown method is only called from [sqlite3_shutdown()] so it does
-** not need to be threadsafe either. For all other methods, SQLite
-** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
-** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
-** it is by default) and so the methods are automatically serialized.
-** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
-** methods must be threadsafe or else make their own arrangements for
-** serialization.
-**
-** SQLite will never invoke xInit() more than once without an intervening
-** call to xShutdown().
-*/
-typedef struct sqlite3_mem_methods sqlite3_mem_methods;
-struct sqlite3_mem_methods {
- void *(*xMalloc)(int); /* Memory allocation function */
- void (*xFree)(void*); /* Free a prior allocation */
- void *(*xRealloc)(void*,int); /* Resize an allocation */
- int (*xSize)(void*); /* Return the size of an allocation */
- int (*xRoundup)(int); /* Round up request size to allocation size */
- int (*xInit)(void*); /* Initialize the memory allocator */
- void (*xShutdown)(void*); /* Deinitialize the memory allocator */
- void *pAppData; /* Argument to xInit() and xShutdown() */
-};
-
-/*
-** CAPI3REF: Configuration Options
-** KEYWORDS: {configuration option}
-**
-** These constants are the available integer configuration options that
-** can be passed as the first argument to the [sqlite3_config()] interface.
-**
-** New configuration options may be added in future releases of SQLite.
-** Existing configuration options might be discontinued. Applications
-** should check the return code from [sqlite3_config()] to make sure that
-** the call worked. The [sqlite3_config()] interface will return a
-** non-zero [error code] if a discontinued or unsupported configuration option
-** is invoked.
-**
-** <dl>
-** [[SQLITE_CONFIG_SINGLETHREAD]] <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
-** <dd>There are no arguments to this option. ^This option sets the
-** [threading mode] to Single-thread. In other words, it disables
-** all mutexing and puts SQLite into a mode where it can only be used
-** by a single thread. ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** it is not possible to change the [threading mode] from its default
-** value of Single-thread and so [sqlite3_config()] will return
-** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD
-** configuration option.</dd>
-**
-** [[SQLITE_CONFIG_MULTITHREAD]] <dt>SQLITE_CONFIG_MULTITHREAD</dt>
-** <dd>There are no arguments to this option. ^This option sets the
-** [threading mode] to Multi-thread. In other words, it disables
-** mutexing on [database connection] and [prepared statement] objects.
-** The application is responsible for serializing access to
-** [database connections] and [prepared statements]. But other mutexes
-** are enabled so that SQLite will be safe to use in a multi-threaded
-** environment as long as no two threads attempt to use the same
-** [database connection] at the same time. ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** it is not possible to set the Multi-thread [threading mode] and
-** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
-** SQLITE_CONFIG_MULTITHREAD configuration option.</dd>
-**
-** [[SQLITE_CONFIG_SERIALIZED]] <dt>SQLITE_CONFIG_SERIALIZED</dt>
-** <dd>There are no arguments to this option. ^This option sets the
-** [threading mode] to Serialized. In other words, this option enables
-** all mutexes including the recursive
-** mutexes on [database connection] and [prepared statement] objects.
-** In this mode (which is the default when SQLite is compiled with
-** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access
-** to [database connections] and [prepared statements] so that the
-** application is free to use the same [database connection] or the
-** same [prepared statement] in different threads at the same time.
-** ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** it is not possible to set the Serialized [threading mode] and
-** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
-** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
-**
-** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure. The argument specifies
-** alternative low-level memory allocation routines to be used in place of
-** the memory allocation routines built into SQLite.)^ ^SQLite makes
-** its own private copy of the content of the [sqlite3_mem_methods] structure
-** before the [sqlite3_config()] call returns.</dd>
-**
-** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods]
-** structure is filled with the currently defined memory allocation routines.)^
-** This option can be used to overload the default memory allocation
-** routines with a wrapper that simulations memory allocation failure or
-** tracks memory usage, for example. </dd>
-**
-** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
-** <dd> ^This option takes single argument of type int, interpreted as a
-** boolean, which enables or disables the collection of memory allocation
-** statistics. ^(When memory allocation statistics are disabled, the
-** following SQLite interfaces become non-operational:
-** <ul>
-** <li> [sqlite3_memory_used()]
-** <li> [sqlite3_memory_highwater()]
-** <li> [sqlite3_soft_heap_limit64()]
-** <li> [sqlite3_status()]
-** </ul>)^
-** ^Memory allocation statistics are enabled by default unless SQLite is
-** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
-** allocation statistics are disabled by default.
-** </dd>
-**
-** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite can use for
-** scratch memory. There are three arguments: A pointer an 8-byte
-** aligned memory buffer from which the scratch allocations will be
-** drawn, the size of each scratch allocation (sz),
-** and the maximum number of scratch allocations (N). The sz
-** argument must be a multiple of 16.
-** The first argument must be a pointer to an 8-byte aligned buffer
-** of at least sz*N bytes of memory.
-** ^SQLite will use no more than two scratch buffers per thread. So
-** N should be set to twice the expected maximum number of threads.
-** ^SQLite will never require a scratch buffer that is more than 6
-** times the database page size. ^If SQLite needs needs additional
-** scratch memory beyond what is provided by this configuration option, then
-** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
-**
-** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite can use for
-** the database page cache with the default page cache implementation.
-** This configuration should not be used if an application-define page
-** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.
-** There are three arguments to this option: A pointer to 8-byte aligned
-** memory, the size of each page buffer (sz), and the number of pages (N).
-** The sz argument should be the size of the largest database page
-** (a power of two between 512 and 32768) plus a little extra for each
-** page header. ^The page header size is 20 to 40 bytes depending on
-** the host architecture. ^It is harmless, apart from the wasted memory,
-** to make sz a little too large. The first
-** argument should point to an allocation of at least sz*N bytes of memory.
-** ^SQLite will use the memory provided by the first argument to satisfy its
-** memory needs for the first N pages that it adds to cache. ^If additional
-** page cache memory is needed beyond what is provided by this option, then
-** SQLite goes to [sqlite3_malloc()] for the additional storage space.
-** The pointer in the first argument must
-** be aligned to an 8-byte boundary or subsequent behavior of SQLite
-** will be undefined.</dd>
-**
-** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite will use
-** for all of its dynamic memory allocation needs beyond those provided
-** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
-** There are three arguments: An 8-byte aligned pointer to the memory,
-** the number of bytes in the memory buffer, and the minimum allocation size.
-** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
-** to using its default memory allocator (the system malloc() implementation),
-** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the
-** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
-** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
-** allocator is engaged to handle all of SQLites memory allocation needs.
-** The first pointer (the memory pointer) must be aligned to an 8-byte
-** boundary or subsequent behavior of SQLite will be undefined.
-** The minimum allocation size is capped at 2**12. Reasonable values
-** for the minimum allocation size are 2**5 through 2**8.</dd>
-**
-** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure. The argument specifies
-** alternative low-level mutex routines to be used in place
-** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the
-** content of the [sqlite3_mutex_methods] structure before the call to
-** [sqlite3_config()] returns. ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** the entire mutexing subsystem is omitted from the build and hence calls to
-** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
-** return [SQLITE_ERROR].</dd>
-**
-** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure. The
-** [sqlite3_mutex_methods]
-** structure is filled with the currently defined mutex routines.)^
-** This option can be used to overload the default mutex allocation
-** routines with a wrapper used to track mutex usage for performance
-** profiling or testing, for example. ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** the entire mutexing subsystem is omitted from the build and hence calls to
-** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
-** return [SQLITE_ERROR].</dd>
-**
-** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
-** <dd> ^(This option takes two arguments that determine the default
-** memory allocation for the lookaside memory allocator on each
-** [database connection]. The first argument is the
-** size of each lookaside buffer slot and the second is the number of
-** slots allocated to each database connection.)^ ^(This option sets the
-** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
-** verb to [sqlite3_db_config()] can be used to change the lookaside
-** configuration on individual connections.)^ </dd>
-**
-** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
-** <dd> ^(This option takes a single argument which is a pointer to
-** an [sqlite3_pcache_methods2] object. This object specifies the interface
-** to a custom page cache implementation.)^ ^SQLite makes a copy of the
-** object and uses it for page cache memory allocations.</dd>
-**
-** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** [sqlite3_pcache_methods2] object. SQLite copies of the current
-** page cache implementation into that object.)^ </dd>
-**
-** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
-** <dd> ^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
-** function with a call signature of void(*)(void*,int,const char*),
-** and a pointer to void. ^If the function pointer is not NULL, it is
-** invoked by [sqlite3_log()] to process each logging event. ^If the
-** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op.
-** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is
-** passed through as the first parameter to the application-defined logger
-** function whenever that function is invoked. ^The second parameter to
-** the logger function is a copy of the first parameter to the corresponding
-** [sqlite3_log()] call and is intended to be a [result code] or an
-** [extended result code]. ^The third parameter passed to the logger is
-** log message after formatting via [sqlite3_snprintf()].
-** The SQLite logging interface is not reentrant; the logger function
-** supplied by the application must not invoke any SQLite interface.
-** In a multi-threaded application, the application-defined logger
-** function must be threadsafe. </dd>
-**
-** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
-** <dd> This option takes a single argument of type int. If non-zero, then
-** URI handling is globally enabled. If the parameter is zero, then URI handling
-** is globally disabled. If URI handling is globally enabled, all filenames
-** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
-** specified as part of [ATTACH] commands are interpreted as URIs, regardless
-** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
-** connection is opened. If it is globally disabled, filenames are
-** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
-** database connection is opened. By default, URI handling is globally
-** disabled. The default value may be changed by compiling with the
-** [SQLITE_USE_URI] symbol defined.
-**
-** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
-** <dd> This option takes a single integer argument which is interpreted as
-** a boolean in order to enable or disable the use of covering indices for
-** full table scans in the query optimizer. The default setting is determined
-** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
-** if that compile-time option is omitted.
-** The ability to disable the use of covering indices for full table scans
-** is because some incorrectly coded legacy applications might malfunction
-** malfunction when the optimization is enabled. Providing the ability to
-** disable the optimization allows the older, buggy application code to work
-** without change even with newer versions of SQLite.
-**
-** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
-** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
-** <dd> These options are obsolete and should not be used by new code.
-** They are retained for backwards compatibility but are now no-ops.
-** </dl>
-**
-** [[SQLITE_CONFIG_SQLLOG]]
-** <dt>SQLITE_CONFIG_SQLLOG
-** <dd>This option is only available if sqlite is compiled with the
-** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should
-** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int).
-** The second should be of type (void*). The callback is invoked by the library
-** in three separate circumstances, identified by the value passed as the
-** fourth parameter. If the fourth parameter is 0, then the database connection
-** passed as the second argument has just been opened. The third argument
-** points to a buffer containing the name of the main database file. If the
-** fourth parameter is 1, then the SQL statement that the third parameter
-** points to has just been executed. Or, if the fourth parameter is 2, then
-** the connection being passed as the second parameter is being closed. The
-** third parameter is passed NULL In this case.
-** </dl>
-*/
-#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
-#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
-#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
-#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */
-#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
-#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
-#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
-#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */
-#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */
-/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
-#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */
-#define SQLITE_CONFIG_PCACHE 14 /* no-op */
-#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */
-#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */
-#define SQLITE_CONFIG_URI 17 /* int */
-#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
-#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
-#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
-#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
-
-/*
-** CAPI3REF: Database Connection Configuration Options
-**
-** These constants are the available integer configuration options that
-** can be passed as the second argument to the [sqlite3_db_config()] interface.
-**
-** New configuration options may be added in future releases of SQLite.
-** Existing configuration options might be discontinued. Applications
-** should check the return code from [sqlite3_db_config()] to make sure that
-** the call worked. ^The [sqlite3_db_config()] interface will return a
-** non-zero [error code] if a discontinued or unsupported configuration option
-** is invoked.
-**
-** <dl>
-** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
-** <dd> ^This option takes three additional arguments that determine the
-** [lookaside memory allocator] configuration for the [database connection].
-** ^The first argument (the third parameter to [sqlite3_db_config()] is a
-** pointer to a memory buffer to use for lookaside memory.
-** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
-** may be NULL in which case SQLite will allocate the
-** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
-** size of each lookaside buffer slot. ^The third argument is the number of
-** slots. The size of the buffer in the first argument must be greater than
-** or equal to the product of the second and third arguments. The buffer
-** must be aligned to an 8-byte boundary. ^If the second argument to
-** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
-** rounded down to the next smaller multiple of 8. ^(The lookaside memory
-** configuration for a database connection can only be changed when that
-** connection is not currently using lookaside memory, or in other words
-** when the "current value" returned by
-** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
-** Any attempt to change the lookaside memory configuration when lookaside
-** memory is in use leaves the configuration unchanged and returns
-** [SQLITE_BUSY].)^</dd>
-**
-** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
-** <dd> ^This option is used to enable or disable the enforcement of
-** [foreign key constraints]. There should be two additional arguments.
-** The first argument is an integer which is 0 to disable FK enforcement,
-** positive to enable FK enforcement or negative to leave FK enforcement
-** unchanged. The second parameter is a pointer to an integer into which
-** is written 0 or 1 to indicate whether FK enforcement is off or on
-** following this call. The second parameter may be a NULL pointer, in
-** which case the FK enforcement setting is not reported back. </dd>
-**
-** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
-** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
-** There should be two additional arguments.
-** The first argument is an integer which is 0 to disable triggers,
-** positive to enable triggers or negative to leave the setting unchanged.
-** The second parameter is a pointer to an integer into which
-** is written 0 or 1 to indicate whether triggers are disabled or enabled
-** following this call. The second parameter may be a NULL pointer, in
-** which case the trigger setting is not reported back. </dd>
-**
-** </dl>
-*/
-#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
-#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
-
-
-/*
-** CAPI3REF: Enable Or Disable Extended Result Codes
-**
-** ^The sqlite3_extended_result_codes() routine enables or disables the
-** [extended result codes] feature of SQLite. ^The extended result
-** codes are disabled by default for historical compatibility.
-*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
-
-/*
-** CAPI3REF: Last Insert Rowid
-**
-** ^Each entry in an SQLite table has a unique 64-bit signed
-** integer key called the [ROWID | "rowid"]. ^The rowid is always available
-** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
-** names are not also used by explicitly declared columns. ^If
-** the table has a column of type [INTEGER PRIMARY KEY] then that column
-** is another alias for the rowid.
-**
-** ^This routine returns the [rowid] of the most recent
-** successful [INSERT] into the database from the [database connection]
-** in the first argument. ^As of SQLite version 3.7.7, this routines
-** records the last insert rowid of both ordinary tables and [virtual tables].
-** ^If no successful [INSERT]s
-** have ever occurred on that database connection, zero is returned.
-**
-** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
-** method, then this routine will return the [rowid] of the inserted
-** row as long as the trigger or virtual table method is running.
-** But once the trigger or virtual table method ends, the value returned
-** by this routine reverts to what it was before the trigger or virtual
-** table method began.)^
-**
-** ^An [INSERT] that fails due to a constraint violation is not a
-** successful [INSERT] and does not change the value returned by this
-** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
-** and INSERT OR ABORT make no changes to the return value of this
-** routine when their insertion fails. ^(When INSERT OR REPLACE
-** encounters a constraint violation, it does not fail. The
-** INSERT continues to completion after deleting rows that caused
-** the constraint problem so INSERT OR REPLACE will always change
-** the return value of this interface.)^
-**
-** ^For the purposes of this routine, an [INSERT] is considered to
-** be successful even if it is subsequently rolled back.
-**
-** This function is accessible to SQL statements via the
-** [last_insert_rowid() SQL function].
-**
-** If a separate thread performs a new [INSERT] on the same
-** database connection while the [sqlite3_last_insert_rowid()]
-** function is running and thus changes the last insert [rowid],
-** then the value returned by [sqlite3_last_insert_rowid()] is
-** unpredictable and might not equal either the old or the new
-** last insert [rowid].
-*/
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
-
-/*
-** CAPI3REF: Count The Number Of Rows Modified
-**
-** ^This function returns the number of database rows that were changed
-** or inserted or deleted by the most recently completed SQL statement
-** on the [database connection] specified by the first parameter.
-** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
-** or [DELETE] statement are counted. Auxiliary changes caused by
-** triggers or [foreign key actions] are not counted.)^ Use the
-** [sqlite3_total_changes()] function to find the total number of changes
-** including changes caused by triggers and foreign key actions.
-**
-** ^Changes to a view that are simulated by an [INSTEAD OF trigger]
-** are not counted. Only real table changes are counted.
-**
-** ^(A "row change" is a change to a single row of a single table
-** caused by an INSERT, DELETE, or UPDATE statement. Rows that
-** are changed as side effects of [REPLACE] constraint resolution,
-** rollback, ABORT processing, [DROP TABLE], or by any other
-** mechanisms do not count as direct row changes.)^
-**
-** A "trigger context" is a scope of execution that begins and
-** ends with the script of a [CREATE TRIGGER | trigger].
-** Most SQL statements are
-** evaluated outside of any trigger. This is the "top level"
-** trigger context. If a trigger fires from the top level, a
-** new trigger context is entered for the duration of that one
-** trigger. Subtriggers create subcontexts for their duration.
-**
-** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
-** not create a new trigger context.
-**
-** ^This function returns the number of direct row changes in the
-** most recent INSERT, UPDATE, or DELETE statement within the same
-** trigger context.
-**
-** ^Thus, when called from the top level, this function returns the
-** number of changes in the most recent INSERT, UPDATE, or DELETE
-** that also occurred at the top level. ^(Within the body of a trigger,
-** the sqlite3_changes() interface can be called to find the number of
-** changes in the most recently completed INSERT, UPDATE, or DELETE
-** statement within the body of the same trigger.
-** However, the number returned does not include changes
-** caused by subtriggers since those have their own context.)^
-**
-** See also the [sqlite3_total_changes()] interface, the
-** [count_changes pragma], and the [changes() SQL function].
-**
-** If a separate thread makes changes on the same database connection
-** while [sqlite3_changes()] is running then the value returned
-** is unpredictable and not meaningful.
-*/
-SQLITE_API int sqlite3_changes(sqlite3*);
-
-/*
-** CAPI3REF: Total Number Of Rows Modified
-**
-** ^This function returns the number of row changes caused by [INSERT],
-** [UPDATE] or [DELETE] statements since the [database connection] was opened.
-** ^(The count returned by sqlite3_total_changes() includes all changes
-** from all [CREATE TRIGGER | trigger] contexts and changes made by
-** [foreign key actions]. However,
-** the count does not include changes used to implement [REPLACE] constraints,
-** do rollbacks or ABORT processing, or [DROP TABLE] processing. The
-** count does not include rows of views that fire an [INSTEAD OF trigger],
-** though if the INSTEAD OF trigger makes changes of its own, those changes
-** are counted.)^
-** ^The sqlite3_total_changes() function counts the changes as soon as
-** the statement that makes them is completed (when the statement handle
-** is passed to [sqlite3_reset()] or [sqlite3_finalize()]).
-**
-** See also the [sqlite3_changes()] interface, the
-** [count_changes pragma], and the [total_changes() SQL function].
-**
-** If a separate thread makes changes on the same database connection
-** while [sqlite3_total_changes()] is running then the value
-** returned is unpredictable and not meaningful.
-*/
-SQLITE_API int sqlite3_total_changes(sqlite3*);
-
-/*
-** CAPI3REF: Interrupt A Long-Running Query
-**
-** ^This function causes any pending database operation to abort and
-** return at its earliest opportunity. This routine is typically
-** called in response to a user action such as pressing "Cancel"
-** or Ctrl-C where the user wants a long query operation to halt
-** immediately.
-**
-** ^It is safe to call this routine from a thread different from the
-** thread that is currently running the database operation. But it
-** is not safe to call this routine with a [database connection] that
-** is closed or might close before sqlite3_interrupt() returns.
-**
-** ^If an SQL operation is very nearly finished at the time when
-** sqlite3_interrupt() is called, then it might not have an opportunity
-** to be interrupted and might continue to completion.
-**
-** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT].
-** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE
-** that is inside an explicit transaction, then the entire transaction
-** will be rolled back automatically.
-**
-** ^The sqlite3_interrupt(D) call is in effect until all currently running
-** SQL statements on [database connection] D complete. ^Any new SQL statements
-** that are started after the sqlite3_interrupt() call and before the
-** running statements reaches zero are interrupted as if they had been
-** running prior to the sqlite3_interrupt() call. ^New SQL statements
-** that are started after the running statement count reaches zero are
-** not effected by the sqlite3_interrupt().
-** ^A call to sqlite3_interrupt(D) that occurs when there are no running
-** SQL statements is a no-op and has no effect on SQL statements
-** that are started after the sqlite3_interrupt() call returns.
-**
-** If the database connection closes while [sqlite3_interrupt()]
-** is running then bad things will likely happen.
-*/
-SQLITE_API void sqlite3_interrupt(sqlite3*);
-
-/*
-** CAPI3REF: Determine If An SQL Statement Is Complete
-**
-** These routines are useful during command-line input to determine if the
-** currently entered text seems to form a complete SQL statement or
-** if additional input is needed before sending the text into
-** SQLite for parsing. ^These routines return 1 if the input string
-** appears to be a complete SQL statement. ^A statement is judged to be
-** complete if it ends with a semicolon token and is not a prefix of a
-** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within
-** string literals or quoted identifier names or comments are not
-** independent tokens (they are part of the token in which they are
-** embedded) and thus do not count as a statement terminator. ^Whitespace
-** and comments that follow the final semicolon are ignored.
-**
-** ^These routines return 0 if the statement is incomplete. ^If a
-** memory allocation fails, then SQLITE_NOMEM is returned.
-**
-** ^These routines do not parse the SQL statements thus
-** will not detect syntactically incorrect SQL.
-**
-** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior
-** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
-** automatically by sqlite3_complete16(). If that initialization fails,
-** then the return value from sqlite3_complete16() will be non-zero
-** regardless of whether or not the input SQL is complete.)^
-**
-** The input to [sqlite3_complete()] must be a zero-terminated
-** UTF-8 string.
-**
-** The input to [sqlite3_complete16()] must be a zero-terminated
-** UTF-16 string in native byte order.
-*/
-SQLITE_API int sqlite3_complete(const char *sql);
-SQLITE_API int sqlite3_complete16(const void *sql);
-
-/*
-** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
-**
-** ^This routine sets a callback function that might be invoked whenever
-** an attempt is made to open a database table that another thread
-** or process has locked.
-**
-** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
-** is returned immediately upon encountering the lock. ^If the busy callback
-** is not NULL, then the callback might be invoked with two arguments.
-**
-** ^The first argument to the busy handler is a copy of the void* pointer which
-** is the third argument to sqlite3_busy_handler(). ^The second argument to
-** the busy handler callback is the number of times that the busy handler has
-** been invoked for this locking event. ^If the
-** busy callback returns 0, then no additional attempts are made to
-** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned.
-** ^If the callback returns non-zero, then another attempt
-** is made to open the database for reading and the cycle repeats.
-**
-** The presence of a busy handler does not guarantee that it will be invoked
-** when there is lock contention. ^If SQLite determines that invoking the busy
-** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
-** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler.
-** Consider a scenario where one process is holding a read lock that
-** it is trying to promote to a reserved lock and
-** a second process is holding a reserved lock that it is trying
-** to promote to an exclusive lock. The first process cannot proceed
-** because it is blocked by the second and the second process cannot
-** proceed because it is blocked by the first. If both processes
-** invoke the busy handlers, neither will make any progress. Therefore,
-** SQLite returns [SQLITE_BUSY] for the first process, hoping that this
-** will induce the first process to release its read lock and allow
-** the second process to proceed.
-**
-** ^The default busy callback is NULL.
-**
-** ^The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED]
-** when SQLite is in the middle of a large transaction where all the
-** changes will not fit into the in-memory cache. SQLite will
-** already hold a RESERVED lock on the database file, but it needs
-** to promote this lock to EXCLUSIVE so that it can spill cache
-** pages into the database file without harm to concurrent
-** readers. ^If it is unable to promote the lock, then the in-memory
-** cache will be left in an inconsistent state and so the error
-** code is promoted from the relatively benign [SQLITE_BUSY] to
-** the more severe [SQLITE_IOERR_BLOCKED]. ^This error code promotion
-** forces an automatic rollback of the changes. See the
-** <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
-** CorruptionFollowingBusyError</a> wiki page for a discussion of why
-** this is important.
-**
-** ^(There can only be a single busy handler defined for each
-** [database connection]. Setting a new busy handler clears any
-** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()]
-** will also set or clear the busy handler.
-**
-** The busy callback should not take any actions which modify the
-** database connection that invoked the busy handler. Any such actions
-** result in undefined behavior.
-**
-** A busy handler must not close the database connection
-** or [prepared statement] that invoked the busy handler.
-*/
-SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
-
-/*
-** CAPI3REF: Set A Busy Timeout
-**
-** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
-** for a specified amount of time when a table is locked. ^The handler
-** will sleep multiple times until at least "ms" milliseconds of sleeping
-** have accumulated. ^After at least "ms" milliseconds of sleeping,
-** the handler returns 0 which causes [sqlite3_step()] to return
-** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
-**
-** ^Calling this routine with an argument less than or equal to zero
-** turns off all busy handlers.
-**
-** ^(There can only be a single busy handler for a particular
-** [database connection] any any given moment. If another busy handler
-** was defined (using [sqlite3_busy_handler()]) prior to calling
-** this routine, that other busy handler is cleared.)^
-*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
-
-/*
-** CAPI3REF: Convenience Routines For Running Queries
-**
-** This is a legacy interface that is preserved for backwards compatibility.
-** Use of this interface is not recommended.
-**
-** Definition: A <b>result table</b> is memory data structure created by the
-** [sqlite3_get_table()] interface. A result table records the
-** complete query results from one or more queries.
-**
-** The table conceptually has a number of rows and columns. But
-** these numbers are not part of the result table itself. These
-** numbers are obtained separately. Let N be the number of rows
-** and M be the number of columns.
-**
-** A result table is an array of pointers to zero-terminated UTF-8 strings.
-** There are (N+1)*M elements in the array. The first M pointers point
-** to zero-terminated strings that contain the names of the columns.
-** The remaining entries all point to query results. NULL values result
-** in NULL pointers. All other values are in their UTF-8 zero-terminated
-** string representation as returned by [sqlite3_column_text()].
-**
-** A result table might consist of one or more memory allocations.
-** It is not safe to pass a result table directly to [sqlite3_free()].
-** A result table should be deallocated using [sqlite3_free_table()].
-**
-** ^(As an example of the result table format, suppose a query result
-** is as follows:
-**
-** <blockquote><pre>
-** Name | Age
-** -----------------------
-** Alice | 43
-** Bob | 28
-** Cindy | 21
-** </pre></blockquote>
-**
-** There are two column (M==2) and three rows (N==3). Thus the
-** result table has 8 entries. Suppose the result table is stored
-** in an array names azResult. Then azResult holds this content:
-**
-** <blockquote><pre>
-** azResult&#91;0] = "Name";
-** azResult&#91;1] = "Age";
-** azResult&#91;2] = "Alice";
-** azResult&#91;3] = "43";
-** azResult&#91;4] = "Bob";
-** azResult&#91;5] = "28";
-** azResult&#91;6] = "Cindy";
-** azResult&#91;7] = "21";
-** </pre></blockquote>)^
-**
-** ^The sqlite3_get_table() function evaluates one or more
-** semicolon-separated SQL statements in the zero-terminated UTF-8
-** string of its 2nd parameter and returns a result table to the
-** pointer given in its 3rd parameter.
-**
-** After the application has finished with the result from sqlite3_get_table(),
-** it must pass the result table pointer to sqlite3_free_table() in order to
-** release the memory that was malloced. Because of the way the
-** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
-** function must not try to call [sqlite3_free()] directly. Only
-** [sqlite3_free_table()] is able to release the memory properly and safely.
-**
-** The sqlite3_get_table() interface is implemented as a wrapper around
-** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access
-** to any internal data structures of SQLite. It uses only the public
-** interface defined here. As a consequence, errors that occur in the
-** wrapper layer outside of the internal [sqlite3_exec()] call are not
-** reflected in subsequent calls to [sqlite3_errcode()] or
-** [sqlite3_errmsg()].
-*/
-SQLITE_API int sqlite3_get_table(
- sqlite3 *db, /* An open database */
- const char *zSql, /* SQL to be evaluated */
- char ***pazResult, /* Results of the query */
- int *pnRow, /* Number of result rows written here */
- int *pnColumn, /* Number of result columns written here */
- char **pzErrmsg /* Error msg written here */
-);
-SQLITE_API void sqlite3_free_table(char **result);
-
-/*
-** CAPI3REF: Formatted String Printing Functions
-**
-** These routines are work-alikes of the "printf()" family of functions
-** from the standard C library.
-**
-** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
-** results into memory obtained from [sqlite3_malloc()].
-** The strings returned by these two routines should be
-** released by [sqlite3_free()]. ^Both routines return a
-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
-** memory to hold the resulting string.
-**
-** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
-** the standard C library. The result is written into the
-** buffer supplied as the second parameter whose size is given by
-** the first parameter. Note that the order of the
-** first two parameters is reversed from snprintf().)^ This is an
-** historical accident that cannot be fixed without breaking
-** backwards compatibility. ^(Note also that sqlite3_snprintf()
-** returns a pointer to its buffer instead of the number of
-** characters actually written into the buffer.)^ We admit that
-** the number of characters written would be a more useful return
-** value but we cannot change the implementation of sqlite3_snprintf()
-** now without breaking compatibility.
-**
-** ^As long as the buffer size is greater than zero, sqlite3_snprintf()
-** guarantees that the buffer is always zero-terminated. ^The first
-** parameter "n" is the total size of the buffer, including space for
-** the zero terminator. So the longest string that can be completely
-** written will be n-1 characters.
-**
-** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
-**
-** These routines all implement some additional formatting
-** options that are useful for constructing SQL statements.
-** All of the usual printf() formatting options apply. In addition, there
-** is are "%q", "%Q", and "%z" options.
-**
-** ^(The %q option works like %s in that it substitutes a nul-terminated
-** string from the argument list. But %q also doubles every '\'' character.
-** %q is designed for use inside a string literal.)^ By doubling each '\''
-** character it escapes that character and allows it to be inserted into
-** the string.
-**
-** For example, assume the string variable zText contains text as follows:
-**
-** <blockquote><pre>
-** char *zText = "It's a happy day!";
-** </pre></blockquote>
-**
-** One can use this text in an SQL statement as follows:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** Because the %q format string is used, the '\'' character in zText
-** is escaped and the SQL generated is as follows:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It''s a happy day!')
-** </pre></blockquote>
-**
-** This is correct. Had we used %s instead of %q, the generated SQL
-** would have looked like this:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It's a happy day!');
-** </pre></blockquote>
-**
-** This second example is an SQL syntax error. As a general rule you should
-** always use %q instead of %s when inserting text into a string literal.
-**
-** ^(The %Q option works like %q except it also adds single quotes around
-** the outside of the total string. Additionally, if the parameter in the
-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
-** single quotes).)^ So, for example, one could say:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** The code above will render a correct SQL statement in the zSQL
-** variable even if the zText variable is a NULL pointer.
-**
-** ^(The "%z" formatting option works like "%s" but with the
-** addition that after the string has been read and copied into
-** the result, [sqlite3_free()] is called on the input string.)^
-*/
-SQLITE_API char *sqlite3_mprintf(const char*,...);
-SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
-
-/*
-** CAPI3REF: Memory Allocation Subsystem
-**
-** The SQLite core uses these three routines for all of its own
-** internal memory allocation needs. "Core" in the previous sentence
-** does not include operating-system specific VFS implementation. The
-** Windows VFS uses native malloc() and free() for some operations.
-**
-** ^The sqlite3_malloc() routine returns a pointer to a block
-** of memory at least N bytes in length, where N is the parameter.
-** ^If sqlite3_malloc() is unable to obtain sufficient free
-** memory, it returns a NULL pointer. ^If the parameter N to
-** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
-** a NULL pointer.
-**
-** ^Calling sqlite3_free() with a pointer previously returned
-** by sqlite3_malloc() or sqlite3_realloc() releases that memory so
-** that it might be reused. ^The sqlite3_free() routine is
-** a no-op if is called with a NULL pointer. Passing a NULL pointer
-** to sqlite3_free() is harmless. After being freed, memory
-** should neither be read nor written. Even reading previously freed
-** memory might result in a segmentation fault or other severe error.
-** Memory corruption, a segmentation fault, or other severe error
-** might result if sqlite3_free() is called with a non-NULL pointer that
-** was not obtained from sqlite3_malloc() or sqlite3_realloc().
-**
-** ^(The sqlite3_realloc() interface attempts to resize a
-** prior memory allocation to be at least N bytes, where N is the
-** second parameter. The memory allocation to be resized is the first
-** parameter.)^ ^ If the first parameter to sqlite3_realloc()
-** is a NULL pointer then its behavior is identical to calling
-** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc().
-** ^If the second parameter to sqlite3_realloc() is zero or
-** negative then the behavior is exactly the same as calling
-** sqlite3_free(P) where P is the first parameter to sqlite3_realloc().
-** ^sqlite3_realloc() returns a pointer to a memory allocation
-** of at least N bytes in size or NULL if sufficient memory is unavailable.
-** ^If M is the size of the prior allocation, then min(N,M) bytes
-** of the prior allocation are copied into the beginning of buffer returned
-** by sqlite3_realloc() and the prior allocation is freed.
-** ^If sqlite3_realloc() returns NULL, then the prior allocation
-** is not freed.
-**
-** ^The memory returned by sqlite3_malloc() and sqlite3_realloc()
-** is always aligned to at least an 8 byte boundary, or to a
-** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
-** option is used.
-**
-** In SQLite version 3.5.0 and 3.5.1, it was possible to define
-** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
-** implementation of these routines to be omitted. That capability
-** is no longer provided. Only built-in memory allocators can be used.
-**
-** Prior to SQLite version 3.7.10, the Windows OS interface layer called
-** the system malloc() and free() directly when converting
-** filenames between the UTF-8 encoding used by SQLite
-** and whatever filename encoding is used by the particular Windows
-** installation. Memory allocation errors were detected, but
-** they were reported back as [SQLITE_CANTOPEN] or
-** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
-**
-** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
-** must be either NULL or else pointers obtained from a prior
-** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
-** not yet been released.
-**
-** The application must not read or write any part of
-** a block of memory after it has been released using
-** [sqlite3_free()] or [sqlite3_realloc()].
-*/
-SQLITE_API void *sqlite3_malloc(int);
-SQLITE_API void *sqlite3_realloc(void*, int);
-SQLITE_API void sqlite3_free(void*);
-
-/*
-** CAPI3REF: Memory Allocator Statistics
-**
-** SQLite provides these two interfaces for reporting on the status
-** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
-** routines, which form the built-in memory allocation subsystem.
-**
-** ^The [sqlite3_memory_used()] routine returns the number of bytes
-** of memory currently outstanding (malloced but not freed).
-** ^The [sqlite3_memory_highwater()] routine returns the maximum
-** value of [sqlite3_memory_used()] since the high-water mark
-** was last reset. ^The values returned by [sqlite3_memory_used()] and
-** [sqlite3_memory_highwater()] include any overhead
-** added by SQLite in its implementation of [sqlite3_malloc()],
-** but not overhead added by the any underlying system library
-** routines that [sqlite3_malloc()] may call.
-**
-** ^The memory high-water mark is reset to the current value of
-** [sqlite3_memory_used()] if and only if the parameter to
-** [sqlite3_memory_highwater()] is true. ^The value returned
-** by [sqlite3_memory_highwater(1)] is the high-water mark
-** prior to the reset.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
-
-/*
-** CAPI3REF: Pseudo-Random Number Generator
-**
-** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
-** select random [ROWID | ROWIDs] when inserting new records into a table that
-** already uses the largest possible [ROWID]. The PRNG is also used for
-** the build-in random() and randomblob() SQL functions. This interface allows
-** applications to access the same PRNG for other purposes.
-**
-** ^A call to this routine stores N bytes of randomness into buffer P.
-**
-** ^The first time this routine is invoked (either internally or by
-** the application) the PRNG is seeded using randomness obtained
-** from the xRandomness method of the default [sqlite3_vfs] object.
-** ^On all subsequent invocations, the pseudo-randomness is generated
-** internally and without recourse to the [sqlite3_vfs] xRandomness
-** method.
-*/
-SQLITE_API void sqlite3_randomness(int N, void *P);
-
-/*
-** CAPI3REF: Compile-Time Authorization Callbacks
-**
-** ^This routine registers an authorizer callback with a particular
-** [database connection], supplied in the first argument.
-** ^The authorizer callback is invoked as SQL statements are being compiled
-** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
-** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various
-** points during the compilation process, as logic is being created
-** to perform various actions, the authorizer callback is invoked to
-** see if those actions are allowed. ^The authorizer callback should
-** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the
-** specific action but allow the SQL statement to continue to be
-** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be
-** rejected with an error. ^If the authorizer callback returns
-** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
-** then the [sqlite3_prepare_v2()] or equivalent call that triggered
-** the authorizer will fail with an error message.
-**
-** When the callback returns [SQLITE_OK], that means the operation
-** requested is ok. ^When the callback returns [SQLITE_DENY], the
-** [sqlite3_prepare_v2()] or equivalent call that triggered the
-** authorizer will fail with an error message explaining that
-** access is denied.
-**
-** ^The first parameter to the authorizer callback is a copy of the third
-** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
-** to the callback is an integer [SQLITE_COPY | action code] that specifies
-** the particular action to be authorized. ^The third through sixth parameters
-** to the callback are zero-terminated strings that contain additional
-** details about the action to be authorized.
-**
-** ^If the action code is [SQLITE_READ]
-** and the callback returns [SQLITE_IGNORE] then the
-** [prepared statement] statement is constructed to substitute
-** a NULL value in place of the table column that would have
-** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
-** return can be used to deny an untrusted user access to individual
-** columns of a table.
-** ^If the action code is [SQLITE_DELETE] and the callback returns
-** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
-** [truncate optimization] is disabled and all rows are deleted individually.
-**
-** An authorizer is used when [sqlite3_prepare | preparing]
-** SQL statements from an untrusted source, to ensure that the SQL statements
-** do not try to access data they are not allowed to see, or that they do not
-** try to execute malicious statements that damage the database. For
-** example, an application may allow a user to enter arbitrary
-** SQL queries for evaluation by a database. But the application does
-** not want the user to be able to make arbitrary changes to the
-** database. An authorizer could then be put in place while the
-** user-entered SQL is being [sqlite3_prepare | prepared] that
-** disallows everything except [SELECT] statements.
-**
-** Applications that need to process SQL from untrusted sources
-** might also consider lowering resource limits using [sqlite3_limit()]
-** and limiting database size using the [max_page_count] [PRAGMA]
-** in addition to using an authorizer.
-**
-** ^(Only a single authorizer can be in place on a database connection
-** at a time. Each call to sqlite3_set_authorizer overrides the
-** previous call.)^ ^Disable the authorizer by installing a NULL callback.
-** The authorizer is disabled by default.
-**
-** The authorizer callback must not do anything that will modify
-** the database connection that invoked the authorizer callback.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the
-** statement might be re-prepared during [sqlite3_step()] due to a
-** schema change. Hence, the application should ensure that the
-** correct authorizer callback remains in place during the [sqlite3_step()].
-**
-** ^Note that the authorizer callback is invoked only during
-** [sqlite3_prepare()] or its variants. Authorization is not
-** performed during statement evaluation in [sqlite3_step()], unless
-** as stated in the previous paragraph, sqlite3_step() invokes
-** sqlite3_prepare_v2() to reprepare a statement after a schema change.
-*/
-SQLITE_API int sqlite3_set_authorizer(
- sqlite3*,
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
- void *pUserData
-);
-
-/*
-** CAPI3REF: Authorizer Return Codes
-**
-** The [sqlite3_set_authorizer | authorizer callback function] must
-** return either [SQLITE_OK] or one of these two constants in order
-** to signal SQLite whether or not the action is permitted. See the
-** [sqlite3_set_authorizer | authorizer documentation] for additional
-** information.
-**
-** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code]
-** from the [sqlite3_vtab_on_conflict()] interface.
-*/
-#define SQLITE_DENY 1 /* Abort the SQL statement with an error */
-#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
-
-/*
-** CAPI3REF: Authorizer Action Codes
-**
-** The [sqlite3_set_authorizer()] interface registers a callback function
-** that is invoked to authorize certain SQL statement actions. The
-** second parameter to the callback is an integer code that specifies
-** what action is being authorized. These are the integer action codes that
-** the authorizer callback may be passed.
-**
-** These action code values signify what kind of operation is to be
-** authorized. The 3rd and 4th parameters to the authorization
-** callback function will be parameters or NULL depending on which of these
-** codes is used as the second parameter. ^(The 5th parameter to the
-** authorizer callback is the name of the database ("main", "temp",
-** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback
-** is the name of the inner-most trigger or view that is responsible for
-** the access attempt or NULL if this access attempt is directly from
-** top-level SQL code.
-*/
-/******************************************* 3rd ************ 4th ***********/
-#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
-#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */
-#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
-#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */
-#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */
-#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */
-#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */
-#define SQLITE_CREATE_VIEW 8 /* View Name NULL */
-#define SQLITE_DELETE 9 /* Table Name NULL */
-#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */
-#define SQLITE_DROP_TABLE 11 /* Table Name NULL */
-#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */
-#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */
-#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */
-#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */
-#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */
-#define SQLITE_DROP_VIEW 17 /* View Name NULL */
-#define SQLITE_INSERT 18 /* Table Name NULL */
-#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
-#define SQLITE_READ 20 /* Table Name Column Name */
-#define SQLITE_SELECT 21 /* NULL NULL */
-#define SQLITE_TRANSACTION 22 /* Operation NULL */
-#define SQLITE_UPDATE 23 /* Table Name Column Name */
-#define SQLITE_ATTACH 24 /* Filename NULL */
-#define SQLITE_DETACH 25 /* Database Name NULL */
-#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */
-#define SQLITE_REINDEX 27 /* Index Name NULL */
-#define SQLITE_ANALYZE 28 /* Table Name NULL */
-#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */
-#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
-#define SQLITE_FUNCTION 31 /* NULL Function Name */
-#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
-#define SQLITE_COPY 0 /* No longer used */
-
-/*
-** CAPI3REF: Tracing And Profiling Functions
-**
-** These routines register callback functions that can be used for
-** tracing and profiling the execution of SQL statements.
-**
-** ^The callback function registered by sqlite3_trace() is invoked at
-** various times when an SQL statement is being run by [sqlite3_step()].
-** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the
-** SQL statement text as the statement first begins executing.
-** ^(Additional sqlite3_trace() callbacks might occur
-** as each triggered subprogram is entered. The callbacks for triggers
-** contain a UTF-8 SQL comment that identifies the trigger.)^
-**
-** ^The callback function registered by sqlite3_profile() is invoked
-** as each SQL statement finishes. ^The profile callback contains
-** the original statement text and an estimate of wall-clock time
-** of how long that statement took to run. ^The profile callback
-** time is in units of nanoseconds, however the current implementation
-** is only capable of millisecond resolution so the six least significant
-** digits in the time are meaningless. Future versions of SQLite
-** might provide greater resolution on the profiler callback. The
-** sqlite3_profile() function is considered experimental and is
-** subject to change in future versions of SQLite.
-*/
-SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
- void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
-
-/*
-** CAPI3REF: Query Progress Callbacks
-**
-** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
-** function X to be invoked periodically during long running calls to
-** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
-** database connection D. An example use for this
-** interface is to keep a GUI updated during a large query.
-**
-** ^The parameter P is passed through as the only parameter to the
-** callback function X. ^The parameter N is the number of
-** [virtual machine instructions] that are evaluated between successive
-** invocations of the callback X.
-**
-** ^Only a single progress handler may be defined at one time per
-** [database connection]; setting a new progress handler cancels the
-** old one. ^Setting parameter X to NULL disables the progress handler.
-** ^The progress handler is also disabled by setting N to a value less
-** than 1.
-**
-** ^If the progress callback returns non-zero, the operation is
-** interrupted. This feature can be used to implement a
-** "Cancel" button on a GUI progress dialog box.
-**
-** The progress handler callback must not do anything that will modify
-** the database connection that invoked the progress handler.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-*/
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
-
-/*
-** CAPI3REF: Opening A New Database Connection
-**
-** ^These routines open an SQLite database file as specified by the
-** filename argument. ^The filename argument is interpreted as UTF-8 for
-** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
-** order for sqlite3_open16(). ^(A [database connection] handle is usually
-** returned in *ppDb, even if an error occurs. The only exception is that
-** if SQLite is unable to allocate memory to hold the [sqlite3] object,
-** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
-** object.)^ ^(If the database is opened (and/or created) successfully, then
-** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The
-** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
-** an English language description of the error following a failure of any
-** of the sqlite3_open() routines.
-**
-** ^The default encoding for the database will be UTF-8 if
-** sqlite3_open() or sqlite3_open_v2() is called and
-** UTF-16 in the native byte order if sqlite3_open16() is used.
-**
-** Whether or not an error occurs when it is opened, resources
-** associated with the [database connection] handle should be released by
-** passing it to [sqlite3_close()] when it is no longer required.
-**
-** The sqlite3_open_v2() interface works like sqlite3_open()
-** except that it accepts two additional parameters for additional control
-** over the new database connection. ^(The flags parameter to
-** sqlite3_open_v2() can take one of
-** the following three values, optionally combined with the
-** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
-** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^
-**
-** <dl>
-** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
-** <dd>The database is opened in read-only mode. If the database does not
-** already exist, an error is returned.</dd>)^
-**
-** ^(<dt>[SQLITE_OPEN_READWRITE]</dt>
-** <dd>The database is opened for reading and writing if possible, or reading
-** only if the file is write protected by the operating system. In either
-** case the database must already exist, otherwise an error is returned.</dd>)^
-**
-** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
-** <dd>The database is opened for reading and writing, and is created if
-** it does not already exist. This is the behavior that is always used for
-** sqlite3_open() and sqlite3_open16().</dd>)^
-** </dl>
-**
-** If the 3rd parameter to sqlite3_open_v2() is not one of the
-** combinations shown above optionally combined with other
-** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
-** then the behavior is undefined.
-**
-** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
-** opens in the multi-thread [threading mode] as long as the single-thread
-** mode has not been set at compile-time or start-time. ^If the
-** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
-** in the serialized [threading mode] unless single-thread was
-** previously selected at compile-time or start-time.
-** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be
-** eligible to use [shared cache mode], regardless of whether or not shared
-** cache is enabled using [sqlite3_enable_shared_cache()]. ^The
-** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not
-** participate in [shared cache mode] even if it is enabled.
-**
-** ^The fourth parameter to sqlite3_open_v2() is the name of the
-** [sqlite3_vfs] object that defines the operating system interface that
-** the new database connection should use. ^If the fourth parameter is
-** a NULL pointer then the default [sqlite3_vfs] object is used.
-**
-** ^If the filename is ":memory:", then a private, temporary in-memory database
-** is created for the connection. ^This in-memory database will vanish when
-** the database connection is closed. Future versions of SQLite might
-** make use of additional special filenames that begin with the ":" character.
-** It is recommended that when a database filename actually does begin with
-** a ":" character you should prefix the filename with a pathname such as
-** "./" to avoid ambiguity.
-**
-** ^If the filename is an empty string, then a private, temporary
-** on-disk database will be created. ^This private database will be
-** automatically deleted as soon as the database connection is closed.
-**
-** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3>
-**
-** ^If [URI filename] interpretation is enabled, and the filename argument
-** begins with "file:", then the filename is interpreted as a URI. ^URI
-** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
-** set in the fourth argument to sqlite3_open_v2(), or if it has
-** been enabled globally using the [SQLITE_CONFIG_URI] option with the
-** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
-** As of SQLite version 3.7.7, URI filename interpretation is turned off
-** by default, but future releases of SQLite might enable URI filename
-** interpretation by default. See "[URI filenames]" for additional
-** information.
-**
-** URI filenames are parsed according to RFC 3986. ^If the URI contains an
-** authority, then it must be either an empty string or the string
-** "localhost". ^If the authority is not an empty string or "localhost", an
-** error is returned to the caller. ^The fragment component of a URI, if
-** present, is ignored.
-**
-** ^SQLite uses the path component of the URI as the name of the disk file
-** which contains the database. ^If the path begins with a '/' character,
-** then it is interpreted as an absolute path. ^If the path does not begin
-** with a '/' (meaning that the authority section is omitted from the URI)
-** then the path is interpreted as a relative path.
-** ^On windows, the first component of an absolute path
-** is a drive specification (e.g. "C:").
-**
-** [[core URI query parameters]]
-** The query component of a URI may contain parameters that are interpreted
-** either by SQLite itself, or by a [VFS | custom VFS implementation].
-** SQLite interprets the following three query parameters:
-**
-** <ul>
-** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
-** a VFS object that provides the operating system interface that should
-** be used to access the database file on disk. ^If this option is set to
-** an empty string the default VFS object is used. ^Specifying an unknown
-** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is
-** present, then the VFS specified by the option takes precedence over
-** the value passed as the fourth parameter to sqlite3_open_v2().
-**
-** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw",
-** "rwc", or "memory". Attempting to set it to any other value is
-** an error)^.
-** ^If "ro" is specified, then the database is opened for read-only
-** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the
-** third argument to sqlite3_open_v2(). ^If the mode option is set to
-** "rw", then the database is opened for read-write (but not create)
-** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had
-** been set. ^Value "rwc" is equivalent to setting both
-** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is
-** set to "memory" then a pure [in-memory database] that never reads
-** or writes from disk is used. ^It is an error to specify a value for
-** the mode parameter that is less restrictive than that specified by
-** the flags passed in the third parameter to sqlite3_open_v2().
-**
-** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or
-** "private". ^Setting it to "shared" is equivalent to setting the
-** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
-** sqlite3_open_v2(). ^Setting the cache parameter to "private" is
-** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
-** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
-** a URI filename, its value overrides any behaviour requested by setting
-** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
-** </ul>
-**
-** ^Specifying an unknown parameter in the query component of a URI is not an
-** error. Future versions of SQLite might understand additional query
-** parameters. See "[query parameters with special meaning to SQLite]" for
-** additional information.
-**
-** [[URI filename examples]] <h3>URI filename examples</h3>
-**
-** <table border="1" align=center cellpadding=5>
-** <tr><th> URI filenames <th> Results
-** <tr><td> file:data.db <td>
-** Open the file "data.db" in the current directory.
-** <tr><td> file:/home/fred/data.db<br>
-** file:///home/fred/data.db <br>
-** file://localhost/home/fred/data.db <br> <td>
-** Open the database file "/home/fred/data.db".
-** <tr><td> file://darkstar/home/fred/data.db <td>
-** An error. "darkstar" is not a recognized authority.
-** <tr><td style="white-space:nowrap">
-** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db
-** <td> Windows only: Open the file "data.db" on fred's desktop on drive
-** C:. Note that the %20 escaping in this example is not strictly
-** necessary - space characters can be used literally
-** in URI filenames.
-** <tr><td> file:data.db?mode=ro&cache=private <td>
-** Open file "data.db" in the current directory for read-only access.
-** Regardless of whether or not shared-cache mode is enabled by
-** default, use a private cache.
-** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td>
-** Open file "/home/fred/data.db". Use the special VFS "unix-nolock".
-** <tr><td> file:data.db?mode=readonly <td>
-** An error. "readonly" is not a valid option for the "mode" parameter.
-** </table>
-**
-** ^URI hexadecimal escape sequences (%HH) are supported within the path and
-** query components of a URI. A hexadecimal escape sequence consists of a
-** percent sign - "%" - followed by exactly two hexadecimal digits
-** specifying an octet value. ^Before the path or query components of a
-** URI filename are interpreted, they are encoded using UTF-8 and all
-** hexadecimal escape sequences replaced by a single byte containing the
-** corresponding octet. If this process generates an invalid UTF-8 encoding,
-** the results are undefined.
-**
-** <b>Note to Windows users:</b> The encoding used for the filename argument
-** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever
-** codepage is currently defined. Filenames containing international
-** characters must be converted to UTF-8 prior to passing them into
-** sqlite3_open() or sqlite3_open_v2().
-**
-** <b>Note to Windows Runtime users:</b> The temporary directory must be set
-** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various
-** features that require the use of temporary files may fail.
-**
-** See also: [sqlite3_temp_directory]
-*/
-SQLITE_API int sqlite3_open(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb /* OUT: SQLite db handle */
-);
-SQLITE_API int sqlite3_open16(
- const void *filename, /* Database filename (UTF-16) */
- sqlite3 **ppDb /* OUT: SQLite db handle */
-);
-SQLITE_API int sqlite3_open_v2(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb, /* OUT: SQLite db handle */
- int flags, /* Flags */
- const char *zVfs /* Name of VFS module to use */
-);
-
-/*
-** CAPI3REF: Obtain Values For URI Parameters
-**
-** These are utility routines, useful to VFS implementations, that check
-** to see if a database file was a URI that contained a specific query
-** parameter, and if so obtains the value of that query parameter.
-**
-** If F is the database filename pointer passed into the xOpen() method of
-** a VFS implementation when the flags parameter to xOpen() has one or
-** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and
-** P is the name of the query parameter, then
-** sqlite3_uri_parameter(F,P) returns the value of the P
-** parameter if it exists or a NULL pointer if P does not appear as a
-** query parameter on F. If P is a query parameter of F
-** has no explicit value, then sqlite3_uri_parameter(F,P) returns
-** a pointer to an empty string.
-**
-** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean
-** parameter and returns true (1) or false (0) according to the value
-** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the
-** value of query parameter P is one of "yes", "true", or "on" in any
-** case or if the value begins with a non-zero number. The
-** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of
-** query parameter P is one of "no", "false", or "off" in any case or
-** if the value begins with a numeric zero. If P is not a query
-** parameter on F or if the value of P is does not match any of the
-** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0).
-**
-** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
-** 64-bit signed integer and returns that integer, or D if P does not
-** exist. If the value of P is something other than an integer, then
-** zero is returned.
-**
-** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
-** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and
-** is not a database file pathname pointer that SQLite passed into the xOpen
-** VFS method, then the behavior of this routine is undefined and probably
-** undesirable.
-*/
-SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
-SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
-
-
-/*
-** CAPI3REF: Error Codes And Messages
-**
-** ^The sqlite3_errcode() interface returns the numeric [result code] or
-** [extended result code] for the most recent failed sqlite3_* API call
-** associated with a [database connection]. If a prior API call failed
-** but the most recent API call succeeded, the return value from
-** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode()
-** interface is the same except that it always returns the
-** [extended result code] even when extended result codes are
-** disabled.
-**
-** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
-** text that describes the error, as either UTF-8 or UTF-16 respectively.
-** ^(Memory to hold the error message string is managed internally.
-** The application does not need to worry about freeing the result.
-** However, the error string might be overwritten or deallocated by
-** subsequent calls to other SQLite interface functions.)^
-**
-** ^The sqlite3_errstr() interface returns the English-language text
-** that describes the [result code], as UTF-8.
-** ^(Memory to hold the error message string is managed internally
-** and must not be freed by the application)^.
-**
-** When the serialized [threading mode] is in use, it might be the
-** case that a second error occurs on a separate thread in between
-** the time of the first error and the call to these interfaces.
-** When that happens, the second error will be reported since these
-** interfaces always report the most recent result. To avoid
-** this, each thread can obtain exclusive use of the [database connection] D
-** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
-** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
-** all calls to the interfaces listed here are completed.
-**
-** If an interface fails with SQLITE_MISUSE, that means the interface
-** was invoked incorrectly by the application. In that case, the
-** error code and message may or may not be set.
-*/
-SQLITE_API int sqlite3_errcode(sqlite3 *db);
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
-SQLITE_API const char *sqlite3_errstr(int);
-
-/*
-** CAPI3REF: SQL Statement Object
-** KEYWORDS: {prepared statement} {prepared statements}
-**
-** An instance of this object represents a single SQL statement.
-** This object is variously known as a "prepared statement" or a
-** "compiled SQL statement" or simply as a "statement".
-**
-** The life of a statement object goes something like this:
-**
-** <ol>
-** <li> Create the object using [sqlite3_prepare_v2()] or a related
-** function.
-** <li> Bind values to [host parameters] using the sqlite3_bind_*()
-** interfaces.
-** <li> Run the SQL by calling [sqlite3_step()] one or more times.
-** <li> Reset the statement using [sqlite3_reset()] then go back
-** to step 2. Do this zero or more times.
-** <li> Destroy the object using [sqlite3_finalize()].
-** </ol>
-**
-** Refer to documentation on individual methods above for additional
-** information.
-*/
-typedef struct sqlite3_stmt sqlite3_stmt;
-
-/*
-** CAPI3REF: Run-time Limits
-**
-** ^(This interface allows the size of various constructs to be limited
-** on a connection by connection basis. The first parameter is the
-** [database connection] whose limit is to be set or queried. The
-** second parameter is one of the [limit categories] that define a
-** class of constructs to be size limited. The third parameter is the
-** new limit for that construct.)^
-**
-** ^If the new limit is a negative number, the limit is unchanged.
-** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a
-** [limits | hard upper bound]
-** set at compile-time by a C preprocessor macro called
-** [limits | SQLITE_MAX_<i>NAME</i>].
-** (The "_LIMIT_" in the name is changed to "_MAX_".))^
-** ^Attempts to increase a limit above its hard upper bound are
-** silently truncated to the hard upper bound.
-**
-** ^Regardless of whether or not the limit was changed, the
-** [sqlite3_limit()] interface returns the prior value of the limit.
-** ^Hence, to find the current value of a limit without changing it,
-** simply invoke this interface with the third parameter set to -1.
-**
-** Run-time limits are intended for use in applications that manage
-** both their own internal database and also databases that are controlled
-** by untrusted external sources. An example application might be a
-** web browser that has its own databases for storing history and
-** separate databases controlled by JavaScript applications downloaded
-** off the Internet. The internal databases can be given the
-** large, default limits. Databases managed by external sources can
-** be given much smaller limits designed to prevent a denial of service
-** attack. Developers might also want to use the [sqlite3_set_authorizer()]
-** interface to further control untrusted SQL. The size of the database
-** created by an untrusted script can be contained using the
-** [max_page_count] [PRAGMA].
-**
-** New run-time limit categories may be added in future releases.
-*/
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
-
-/*
-** CAPI3REF: Run-Time Limit Categories
-** KEYWORDS: {limit category} {*limit categories}
-**
-** These constants define various performance limits
-** that can be lowered at run-time using [sqlite3_limit()].
-** The synopsis of the meanings of the various limits is shown below.
-** Additional information is available at [limits | Limits in SQLite].
-**
-** <dl>
-** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt>
-** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
-**
-** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
-** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
-**
-** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt>
-** <dd>The maximum number of columns in a table definition or in the
-** result set of a [SELECT] or the maximum number of columns in an index
-** or in an ORDER BY or GROUP BY clause.</dd>)^
-**
-** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
-** <dd>The maximum depth of the parse tree on any expression.</dd>)^
-**
-** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
-** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
-**
-** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
-** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement. This limit is not currently
-** enforced, though that might be added in some future release of
-** SQLite.</dd>)^
-**
-** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
-** <dd>The maximum number of arguments on a function.</dd>)^
-**
-** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
-** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
-**
-** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]]
-** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
-** <dd>The maximum length of the pattern argument to the [LIKE] or
-** [GLOB] operators.</dd>)^
-**
-** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
-** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
-** <dd>The maximum index number of any [parameter] in an SQL statement.)^
-**
-** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
-** <dd>The maximum depth of recursion for triggers.</dd>)^
-** </dl>
-*/
-#define SQLITE_LIMIT_LENGTH 0
-#define SQLITE_LIMIT_SQL_LENGTH 1
-#define SQLITE_LIMIT_COLUMN 2
-#define SQLITE_LIMIT_EXPR_DEPTH 3
-#define SQLITE_LIMIT_COMPOUND_SELECT 4
-#define SQLITE_LIMIT_VDBE_OP 5
-#define SQLITE_LIMIT_FUNCTION_ARG 6
-#define SQLITE_LIMIT_ATTACHED 7
-#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
-#define SQLITE_LIMIT_VARIABLE_NUMBER 9
-#define SQLITE_LIMIT_TRIGGER_DEPTH 10
-
-/*
-** CAPI3REF: Compiling An SQL Statement
-** KEYWORDS: {SQL statement compiler}
-**
-** To execute an SQL query, it must first be compiled into a byte-code
-** program using one of these routines.
-**
-** The first argument, "db", is a [database connection] obtained from a
-** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
-** [sqlite3_open16()]. The database connection must not have been closed.
-**
-** The second argument, "zSql", is the statement to be compiled, encoded
-** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2()
-** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
-** use UTF-16.
-**
-** ^If the nByte argument is less than zero, then zSql is read up to the
-** first zero terminator. ^If nByte is non-negative, then it is the maximum
-** number of bytes read from zSql. ^When nByte is non-negative, the
-** zSql string ends at either the first '\000' or '\u0000' character or
-** the nByte-th byte, whichever comes first. If the caller knows
-** that the supplied string is nul-terminated, then there is a small
-** performance advantage to be gained by passing an nByte parameter that
-** is equal to the number of bytes in the input string <i>including</i>
-** the nul-terminator bytes as this saves SQLite from having to
-** make a copy of the input string.
-**
-** ^If pzTail is not NULL then *pzTail is made to point to the first byte
-** past the end of the first SQL statement in zSql. These routines only
-** compile the first statement in zSql, so *pzTail is left pointing to
-** what remains uncompiled.
-**
-** ^*ppStmt is left pointing to a compiled [prepared statement] that can be
-** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set
-** to NULL. ^If the input text contains no SQL (if the input is an empty
-** string or a comment) then *ppStmt is set to NULL.
-** The calling procedure is responsible for deleting the compiled
-** SQL statement using [sqlite3_finalize()] after it has finished with it.
-** ppStmt may not be NULL.
-**
-** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK];
-** otherwise an [error code] is returned.
-**
-** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
-** recommended for all new programs. The two older interfaces are retained
-** for backwards compatibility, but their use is discouraged.
-** ^In the "v2" interfaces, the prepared statement
-** that is returned (the [sqlite3_stmt] object) contains a copy of the
-** original SQL text. This causes the [sqlite3_step()] interface to
-** behave differently in three ways:
-**
-** <ol>
-** <li>
-** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
-** always used to do, [sqlite3_step()] will automatically recompile the SQL
-** statement and try to run it again.
-** </li>
-**
-** <li>
-** ^When an error occurs, [sqlite3_step()] will return one of the detailed
-** [error codes] or [extended error codes]. ^The legacy behavior was that
-** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
-** and the application would have to make a second call to [sqlite3_reset()]
-** in order to find the underlying cause of the problem. With the "v2" prepare
-** interfaces, the underlying reason for the error is returned immediately.
-** </li>
-**
-** <li>
-** ^If the specific value bound to [parameter | host parameter] in the
-** WHERE clause might influence the choice of query plan for a statement,
-** then the statement will be automatically recompiled, as if there had been
-** a schema change, on the first [sqlite3_step()] call following any change
-** to the [sqlite3_bind_text | bindings] of that [parameter].
-** ^The specific value of WHERE-clause [parameter] might influence the
-** choice of query plan if the parameter is the left-hand side of a [LIKE]
-** or [GLOB] operator or if the parameter is compared to an indexed column
-** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
-** the
-** </li>
-** </ol>
-*/
-SQLITE_API int sqlite3_prepare(
- sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare_v2(
- sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16_v2(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-
-/*
-** CAPI3REF: Retrieving Statement SQL
-**
-** ^This interface can be used to retrieve a saved copy of the original
-** SQL text used to create a [prepared statement] if that statement was
-** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
-*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Determine If An SQL Statement Writes The Database
-**
-** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
-** and only if the [prepared statement] X makes no direct changes to
-** the content of the database file.
-**
-** Note that [application-defined SQL functions] or
-** [virtual tables] might change the database indirectly as a side effect.
-** ^(For example, if an application defines a function "eval()" that
-** calls [sqlite3_exec()], then the following SQL statement would
-** change the database file through side-effects:
-**
-** <blockquote><pre>
-** SELECT eval('DELETE FROM t1') FROM t2;
-** </pre></blockquote>
-**
-** But because the [SELECT] statement does not change the database file
-** directly, sqlite3_stmt_readonly() would still return true.)^
-**
-** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK],
-** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true,
-** since the statements themselves do not actually modify the database but
-** rather they control the timing of when other statements modify the
-** database. ^The [ATTACH] and [DETACH] statements also cause
-** sqlite3_stmt_readonly() to return true since, while those statements
-** change the configuration of a database connection, they do not make
-** changes to the content of the database files on disk.
-*/
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Determine If A Prepared Statement Has Been Reset
-**
-** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
-** [prepared statement] S has been stepped at least once using
-** [sqlite3_step(S)] but has not run to completion and/or has not
-** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
-** interface returns false if S is a NULL pointer. If S is not a
-** NULL pointer and is not a pointer to a valid [prepared statement]
-** object, then the behavior is undefined and probably undesirable.
-**
-** This interface can be used in combination [sqlite3_next_stmt()]
-** to locate all prepared statements associated with a database
-** connection that are in need of being reset. This can be used,
-** for example, in diagnostic routines to search for prepared
-** statements that are holding a transaction open.
-*/
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Dynamically Typed Value Object
-** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
-**
-** SQLite uses the sqlite3_value object to represent all values
-** that can be stored in a database table. SQLite uses dynamic typing
-** for the values it stores. ^Values stored in sqlite3_value objects
-** can be integers, floating point values, strings, BLOBs, or NULL.
-**
-** An sqlite3_value object may be either "protected" or "unprotected".
-** Some interfaces require a protected sqlite3_value. Other interfaces
-** will accept either a protected or an unprotected sqlite3_value.
-** Every interface that accepts sqlite3_value arguments specifies
-** whether or not it requires a protected sqlite3_value.
-**
-** The terms "protected" and "unprotected" refer to whether or not
-** a mutex is held. An internal mutex is held for a protected
-** sqlite3_value object but no mutex is held for an unprotected
-** sqlite3_value object. If SQLite is compiled to be single-threaded
-** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
-** or if SQLite is run in one of reduced mutex modes
-** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
-** then there is no distinction between protected and unprotected
-** sqlite3_value objects and they can be used interchangeably. However,
-** for maximum code portability it is recommended that applications
-** still make the distinction between protected and unprotected
-** sqlite3_value objects even when not strictly required.
-**
-** ^The sqlite3_value objects that are passed as parameters into the
-** implementation of [application-defined SQL functions] are protected.
-** ^The sqlite3_value object returned by
-** [sqlite3_column_value()] is unprotected.
-** Unprotected sqlite3_value objects may only be used with
-** [sqlite3_result_value()] and [sqlite3_bind_value()].
-** The [sqlite3_value_blob | sqlite3_value_type()] family of
-** interfaces require protected sqlite3_value objects.
-*/
-typedef struct Mem sqlite3_value;
-
-/*
-** CAPI3REF: SQL Function Context Object
-**
-** The context in which an SQL function executes is stored in an
-** sqlite3_context object. ^A pointer to an sqlite3_context object
-** is always first parameter to [application-defined SQL functions].
-** The application-defined SQL function implementation will pass this
-** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
-** [sqlite3_aggregate_context()], [sqlite3_user_data()],
-** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
-** and/or [sqlite3_set_auxdata()].
-*/
-typedef struct sqlite3_context sqlite3_context;
-
-/*
-** CAPI3REF: Binding Values To Prepared Statements
-** KEYWORDS: {host parameter} {host parameters} {host parameter name}
-** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
-**
-** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
-** literals may be replaced by a [parameter] that matches one of following
-** templates:
-**
-** <ul>
-** <li> ?
-** <li> ?NNN
-** <li> :VVV
-** <li> @VVV
-** <li> $VVV
-** </ul>
-**
-** In the templates above, NNN represents an integer literal,
-** and VVV represents an alphanumeric identifier.)^ ^The values of these
-** parameters (also called "host parameter names" or "SQL parameters")
-** can be set using the sqlite3_bind_*() routines defined here.
-**
-** ^The first argument to the sqlite3_bind_*() routines is always
-** a pointer to the [sqlite3_stmt] object returned from
-** [sqlite3_prepare_v2()] or its variants.
-**
-** ^The second argument is the index of the SQL parameter to be set.
-** ^The leftmost SQL parameter has an index of 1. ^When the same named
-** SQL parameter is used more than once, second and subsequent
-** occurrences have the same index as the first occurrence.
-** ^The index for named parameters can be looked up using the
-** [sqlite3_bind_parameter_index()] API if desired. ^The index
-** for "?NNN" parameters is the value of NNN.
-** ^The NNN value must be between 1 and the [sqlite3_limit()]
-** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
-**
-** ^The third argument is the value to bind to the parameter.
-**
-** ^(In those routines that have a fourth argument, its value is the
-** number of bytes in the parameter. To be clear: the value is the
-** number of <u>bytes</u> in the value, not the number of characters.)^
-** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
-** is negative, then the length of the string is
-** the number of bytes up to the first zero terminator.
-** If the fourth parameter to sqlite3_bind_blob() is negative, then
-** the behavior is undefined.
-** If a non-negative fourth parameter is provided to sqlite3_bind_text()
-** or sqlite3_bind_text16() then that parameter must be the byte offset
-** where the NUL terminator would occur assuming the string were NUL
-** terminated. If any NUL characters occur at byte offsets less than
-** the value of the fourth parameter then the resulting string value will
-** contain embedded NULs. The result of expressions involving strings
-** with embedded NULs is undefined.
-**
-** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
-** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
-** string after SQLite has finished with it. ^The destructor is called
-** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
-** sqlite3_bind_text(), or sqlite3_bind_text16() fails.
-** ^If the fifth argument is
-** the special value [SQLITE_STATIC], then SQLite assumes that the
-** information is in static, unmanaged space and does not need to be freed.
-** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
-** SQLite makes its own private copy of the data immediately, before
-** the sqlite3_bind_*() routine returns.
-**
-** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
-** is filled with zeroes. ^A zeroblob uses a fixed amount of memory
-** (just an integer to hold its size) while it is being processed.
-** Zeroblobs are intended to serve as placeholders for BLOBs whose
-** content is later written using
-** [sqlite3_blob_open | incremental BLOB I/O] routines.
-** ^A negative value for the zeroblob results in a zero-length BLOB.
-**
-** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
-** for the [prepared statement] or with a prepared statement for which
-** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
-** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_()
-** routine is passed a [prepared statement] that has been finalized, the
-** result is undefined and probably harmful.
-**
-** ^Bindings are not cleared by the [sqlite3_reset()] routine.
-** ^Unbound parameters are interpreted as NULL.
-**
-** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an
-** [error code] if anything goes wrong.
-** ^[SQLITE_RANGE] is returned if the parameter
-** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails.
-**
-** See also: [sqlite3_bind_parameter_count()],
-** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
-*/
-SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
-
-/*
-** CAPI3REF: Number Of SQL Parameters
-**
-** ^This routine can be used to find the number of [SQL parameters]
-** in a [prepared statement]. SQL parameters are tokens of the
-** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
-** placeholders for values that are [sqlite3_bind_blob | bound]
-** to the parameters at a later time.
-**
-** ^(This routine actually returns the index of the largest (rightmost)
-** parameter. For all forms except ?NNN, this will correspond to the
-** number of unique parameters. If parameters of the ?NNN form are used,
-** there may be gaps in the list.)^
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_name()], and
-** [sqlite3_bind_parameter_index()].
-*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Name Of A Host Parameter
-**
-** ^The sqlite3_bind_parameter_name(P,N) interface returns
-** the name of the N-th [SQL parameter] in the [prepared statement] P.
-** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
-** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
-** respectively.
-** In other words, the initial ":" or "$" or "@" or "?"
-** is included as part of the name.)^
-** ^Parameters of the form "?" without a following integer have no name
-** and are referred to as "nameless" or "anonymous parameters".
-**
-** ^The first host parameter has an index of 1, not 0.
-**
-** ^If the value N is out of range or if the N-th parameter is
-** nameless, then NULL is returned. ^The returned string is
-** always in UTF-8 encoding even if the named parameter was
-** originally specified as UTF-16 in [sqlite3_prepare16()] or
-** [sqlite3_prepare16_v2()].
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
-*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
-
-/*
-** CAPI3REF: Index Of A Parameter With A Given Name
-**
-** ^Return the index of an SQL parameter given its name. ^The
-** index value returned is suitable for use as the second
-** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero
-** is returned if no matching parameter is found. ^The parameter
-** name must be given in UTF-8 even if the original statement
-** was prepared from UTF-16 text using [sqlite3_prepare16_v2()].
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
-*/
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
-
-/*
-** CAPI3REF: Reset All Bindings On A Prepared Statement
-**
-** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
-** the [sqlite3_bind_blob | bindings] on a [prepared statement].
-** ^Use this routine to reset all host parameters to NULL.
-*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Number Of Columns In A Result Set
-**
-** ^Return the number of columns in the result set returned by the
-** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
-** statement that does not return data (for example an [UPDATE]).
-**
-** See also: [sqlite3_data_count()]
-*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Column Names In A Result Set
-**
-** ^These routines return the name assigned to a particular column
-** in the result set of a [SELECT] statement. ^The sqlite3_column_name()
-** interface returns a pointer to a zero-terminated UTF-8 string
-** and sqlite3_column_name16() returns a pointer to a zero-terminated
-** UTF-16 string. ^The first parameter is the [prepared statement]
-** that implements the [SELECT] statement. ^The second parameter is the
-** column number. ^The leftmost column is number 0.
-**
-** ^The returned string pointer is valid until either the [prepared statement]
-** is destroyed by [sqlite3_finalize()] or until the statement is automatically
-** reprepared by the first call to [sqlite3_step()] for a particular run
-** or until the next call to
-** sqlite3_column_name() or sqlite3_column_name16() on the same column.
-**
-** ^If sqlite3_malloc() fails during the processing of either routine
-** (for example during a conversion from UTF-8 to UTF-16) then a
-** NULL pointer is returned.
-**
-** ^The name of a result column is the value of the "AS" clause for
-** that column, if there is an AS clause. If there is no AS clause
-** then the name of the column is unspecified and may change from
-** one release of SQLite to the next.
-*/
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
-
-/*
-** CAPI3REF: Source Of Data In A Query Result
-**
-** ^These routines provide a means to determine the database, table, and
-** table column that is the origin of a particular result column in
-** [SELECT] statement.
-** ^The name of the database or table or column can be returned as
-** either a UTF-8 or UTF-16 string. ^The _database_ routines return
-** the database name, the _table_ routines return the table name, and
-** the origin_ routines return the column name.
-** ^The returned string is valid until the [prepared statement] is destroyed
-** using [sqlite3_finalize()] or until the statement is automatically
-** reprepared by the first call to [sqlite3_step()] for a particular run
-** or until the same information is requested
-** again in a different encoding.
-**
-** ^The names returned are the original un-aliased names of the
-** database, table, and column.
-**
-** ^The first argument to these interfaces is a [prepared statement].
-** ^These functions return information about the Nth result column returned by
-** the statement, where N is the second function argument.
-** ^The left-most column is column 0 for these routines.
-**
-** ^If the Nth column returned by the statement is an expression or
-** subquery and is not a column value, then all of these functions return
-** NULL. ^These routine might also return NULL if a memory allocation error
-** occurs. ^Otherwise, they return the name of the attached database, table,
-** or column that query result column was extracted from.
-**
-** ^As with all other SQLite APIs, those whose names end with "16" return
-** UTF-16 encoded strings and the other functions return UTF-8.
-**
-** ^These APIs are only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol.
-**
-** If two or more threads call one or more of these routines against the same
-** prepared statement and column at the same time then the results are
-** undefined.
-**
-** If two or more threads call one or more
-** [sqlite3_column_database_name | column metadata interfaces]
-** for the same [prepared statement] and result column
-** at the same time then the results are undefined.
-*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
-
-/*
-** CAPI3REF: Declared Datatype Of A Query Result
-**
-** ^(The first parameter is a [prepared statement].
-** If this statement is a [SELECT] statement and the Nth column of the
-** returned result set of that [SELECT] is a table column (not an
-** expression or subquery) then the declared type of the table
-** column is returned.)^ ^If the Nth column of the result set is an
-** expression or subquery, then a NULL pointer is returned.
-** ^The returned string is always UTF-8 encoded.
-**
-** ^(For example, given the database schema:
-**
-** CREATE TABLE t1(c1 VARIANT);
-**
-** and the following statement to be compiled:
-**
-** SELECT c1 + 1, c1 FROM t1;
-**
-** this routine would return the string "VARIANT" for the second result
-** column (i==1), and a NULL pointer for the first result column (i==0).)^
-**
-** ^SQLite uses dynamic run-time typing. ^So just because a column
-** is declared to contain a particular type does not mean that the
-** data stored in that column is of the declared type. SQLite is
-** strongly typed, but the typing is dynamic not static. ^Type
-** is associated with individual values, not with the containers
-** used to hold those values.
-*/
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
-
-/*
-** CAPI3REF: Evaluate An SQL Statement
-**
-** After a [prepared statement] has been prepared using either
-** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
-** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
-** must be called one or more times to evaluate the statement.
-**
-** The details of the behavior of the sqlite3_step() interface depend
-** on whether the statement was prepared using the newer "v2" interface
-** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy
-** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the
-** new "v2" interface is recommended for new applications but the legacy
-** interface will continue to be supported.
-**
-** ^In the legacy interface, the return value will be either [SQLITE_BUSY],
-** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
-** ^With the "v2" interface, any of the other [result codes] or
-** [extended result codes] might be returned as well.
-**
-** ^[SQLITE_BUSY] means that the database engine was unable to acquire the
-** database locks it needs to do its job. ^If the statement is a [COMMIT]
-** or occurs outside of an explicit transaction, then you can retry the
-** statement. If the statement is not a [COMMIT] and occurs within an
-** explicit transaction then you should rollback the transaction before
-** continuing.
-**
-** ^[SQLITE_DONE] means that the statement has finished executing
-** successfully. sqlite3_step() should not be called again on this virtual
-** machine without first calling [sqlite3_reset()] to reset the virtual
-** machine back to its initial state.
-**
-** ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
-** is returned each time a new row of data is ready for processing by the
-** caller. The values may be accessed using the [column access functions].
-** sqlite3_step() is called again to retrieve the next row of data.
-**
-** ^[SQLITE_ERROR] means that a run-time error (such as a constraint
-** violation) has occurred. sqlite3_step() should not be called again on
-** the VM. More information may be found by calling [sqlite3_errmsg()].
-** ^With the legacy interface, a more specific error code (for example,
-** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
-** can be obtained by calling [sqlite3_reset()] on the
-** [prepared statement]. ^In the "v2" interface,
-** the more specific error code is returned directly by sqlite3_step().
-**
-** [SQLITE_MISUSE] means that the this routine was called inappropriately.
-** Perhaps it was called on a [prepared statement] that has
-** already been [sqlite3_finalize | finalized] or on one that had
-** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could
-** be the case that the same database connection is being used by two or
-** more threads at the same moment in time.
-**
-** For all versions of SQLite up to and including 3.6.23.1, a call to
-** [sqlite3_reset()] was required after sqlite3_step() returned anything
-** other than [SQLITE_ROW] before any subsequent invocation of
-** sqlite3_step(). Failure to reset the prepared statement using
-** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
-** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began
-** calling [sqlite3_reset()] automatically in this circumstance rather
-** than returning [SQLITE_MISUSE]. This is not considered a compatibility
-** break because any application that ever receives an SQLITE_MISUSE error
-** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option
-** can be used to restore the legacy behavior.
-**
-** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
-** API always returns a generic error code, [SQLITE_ERROR], following any
-** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call
-** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
-** specific [error codes] that better describes the error.
-** We admit that this is a goofy design. The problem has been fixed
-** with the "v2" interface. If you prepare all of your SQL statements
-** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
-** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
-** then the more specific [error codes] are returned directly
-** by sqlite3_step(). The use of the "v2" interface is recommended.
-*/
-SQLITE_API int sqlite3_step(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Number of columns in a result set
-**
-** ^The sqlite3_data_count(P) interface returns the number of columns in the
-** current row of the result set of [prepared statement] P.
-** ^If prepared statement P does not have results ready to return
-** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
-** interfaces) then sqlite3_data_count(P) returns 0.
-** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
-** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
-** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P)
-** will return non-zero if previous call to [sqlite3_step](P) returned
-** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
-** where it always returns zero since each step of that multi-step
-** pragma returns 0 columns of data.
-**
-** See also: [sqlite3_column_count()]
-*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Fundamental Datatypes
-** KEYWORDS: SQLITE_TEXT
-**
-** ^(Every value in SQLite has one of five fundamental datatypes:
-**
-** <ul>
-** <li> 64-bit signed integer
-** <li> 64-bit IEEE floating point number
-** <li> string
-** <li> BLOB
-** <li> NULL
-** </ul>)^
-**
-** These constants are codes for each of those types.
-**
-** Note that the SQLITE_TEXT constant was also used in SQLite version 2
-** for a completely different meaning. Software that links against both
-** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not
-** SQLITE_TEXT.
-*/
-#define SQLITE_INTEGER 1
-#define SQLITE_FLOAT 2
-#define SQLITE_BLOB 4
-#define SQLITE_NULL 5
-#ifdef SQLITE_TEXT
-# undef SQLITE_TEXT
-#else
-# define SQLITE_TEXT 3
-#endif
-#define SQLITE3_TEXT 3
-
-/*
-** CAPI3REF: Result Values From A Query
-** KEYWORDS: {column access functions}
-**
-** These routines form the "result set" interface.
-**
-** ^These routines return information about a single column of the current
-** result row of a query. ^In every case the first argument is a pointer
-** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
-** that was returned from [sqlite3_prepare_v2()] or one of its variants)
-** and the second argument is the index of the column for which information
-** should be returned. ^The leftmost column of the result set has the index 0.
-** ^The number of columns in the result can be determined using
-** [sqlite3_column_count()].
-**
-** If the SQL statement does not currently point to a valid row, or if the
-** column index is out of range, the result is undefined.
-** These routines may only be called when the most recent call to
-** [sqlite3_step()] has returned [SQLITE_ROW] and neither
-** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
-** If any of these routines are called after [sqlite3_reset()] or
-** [sqlite3_finalize()] or after [sqlite3_step()] has returned
-** something other than [SQLITE_ROW], the results are undefined.
-** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
-** are called from a different thread while any of these routines
-** are pending, then the results are undefined.
-**
-** ^The sqlite3_column_type() routine returns the
-** [SQLITE_INTEGER | datatype code] for the initial data type
-** of the result column. ^The returned value is one of [SQLITE_INTEGER],
-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value
-** returned by sqlite3_column_type() is only meaningful if no type
-** conversions have occurred as described below. After a type conversion,
-** the value returned by sqlite3_column_type() is undefined. Future
-** versions of SQLite may change the behavior of sqlite3_column_type()
-** following a type conversion.
-**
-** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
-** routine returns the number of bytes in that BLOB or string.
-** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
-** the string to UTF-8 and then returns the number of bytes.
-** ^If the result is a numeric value then sqlite3_column_bytes() uses
-** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns
-** the number of bytes in that string.
-** ^If the result is NULL, then sqlite3_column_bytes() returns zero.
-**
-** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16()
-** routine returns the number of bytes in that BLOB or string.
-** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts
-** the string to UTF-16 and then returns the number of bytes.
-** ^If the result is a numeric value then sqlite3_column_bytes16() uses
-** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns
-** the number of bytes in that string.
-** ^If the result is NULL, then sqlite3_column_bytes16() returns zero.
-**
-** ^The values returned by [sqlite3_column_bytes()] and
-** [sqlite3_column_bytes16()] do not include the zero terminators at the end
-** of the string. ^For clarity: the values returned by
-** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
-** bytes in the string, not the number of characters.
-**
-** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
-** even empty strings, are always zero-terminated. ^The return
-** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
-**
-** ^The object returned by [sqlite3_column_value()] is an
-** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
-** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
-** If the [unprotected sqlite3_value] object returned by
-** [sqlite3_column_value()] is used in any other way, including calls
-** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
-** or [sqlite3_value_bytes()], then the behavior is undefined.
-**
-** These routines attempt to convert the value where appropriate. ^For
-** example, if the internal representation is FLOAT and a text result
-** is requested, [sqlite3_snprintf()] is used internally to perform the
-** conversion automatically. ^(The following table details the conversions
-** that are applied:
-**
-** <blockquote>
-** <table border="1">
-** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion
-**
-** <tr><td> NULL <td> INTEGER <td> Result is 0
-** <tr><td> NULL <td> FLOAT <td> Result is 0.0
-** <tr><td> NULL <td> TEXT <td> Result is NULL pointer
-** <tr><td> NULL <td> BLOB <td> Result is NULL pointer
-** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float
-** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer
-** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT
-** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer
-** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float
-** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT
-** <tr><td> TEXT <td> INTEGER <td> Use atoi()
-** <tr><td> TEXT <td> FLOAT <td> Use atof()
-** <tr><td> TEXT <td> BLOB <td> No change
-** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi()
-** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof()
-** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
-** </table>
-** </blockquote>)^
-**
-** The table above makes reference to standard C library functions atoi()
-** and atof(). SQLite does not really use these functions. It has its
-** own equivalent internal routines. The atoi() and atof() names are
-** used in the table for brevity and because they are familiar to most
-** C programmers.
-**
-** Note that when type conversions occur, pointers returned by prior
-** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
-** sqlite3_column_text16() may be invalidated.
-** Type conversions and pointer invalidations might occur
-** in the following cases:
-**
-** <ul>
-** <li> The initial content is a BLOB and sqlite3_column_text() or
-** sqlite3_column_text16() is called. A zero-terminator might
-** need to be added to the string.</li>
-** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
-** sqlite3_column_text16() is called. The content must be converted
-** to UTF-16.</li>
-** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
-** sqlite3_column_text() is called. The content must be converted
-** to UTF-8.</li>
-** </ul>
-**
-** ^Conversions between UTF-16be and UTF-16le are always done in place and do
-** not invalidate a prior pointer, though of course the content of the buffer
-** that the prior pointer references will have been modified. Other kinds
-** of conversion are done in place when it is possible, but sometimes they
-** are not possible and in those cases prior pointers are invalidated.
-**
-** The safest and easiest to remember policy is to invoke these routines
-** in one of the following ways:
-**
-** <ul>
-** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
-** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
-** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
-** </ul>
-**
-** In other words, you should call sqlite3_column_text(),
-** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
-** into the desired format, then invoke sqlite3_column_bytes() or
-** sqlite3_column_bytes16() to find the size of the result. Do not mix calls
-** to sqlite3_column_text() or sqlite3_column_blob() with calls to
-** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
-** with calls to sqlite3_column_bytes().
-**
-** ^The pointers returned are valid until a type conversion occurs as
-** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
-** [sqlite3_finalize()] is called. ^The memory space used to hold strings
-** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
-** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
-** [sqlite3_free()].
-**
-** ^(If a memory allocation error occurs during the evaluation of any
-** of these routines, a default value is returned. The default value
-** is either the integer 0, the floating point number 0.0, or a NULL
-** pointer. Subsequent calls to [sqlite3_errcode()] will return
-** [SQLITE_NOMEM].)^
-*/
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
-
-/*
-** CAPI3REF: Destroy A Prepared Statement Object
-**
-** ^The sqlite3_finalize() function is called to delete a [prepared statement].
-** ^If the most recent evaluation of the statement encountered no errors
-** or if the statement is never been evaluated, then sqlite3_finalize() returns
-** SQLITE_OK. ^If the most recent evaluation of statement S failed, then
-** sqlite3_finalize(S) returns the appropriate [error code] or
-** [extended error code].
-**
-** ^The sqlite3_finalize(S) routine can be called at any point during
-** the life cycle of [prepared statement] S:
-** before statement S is ever evaluated, after
-** one or more calls to [sqlite3_reset()], or after any call
-** to [sqlite3_step()] regardless of whether or not the statement has
-** completed execution.
-**
-** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
-**
-** The application must finalize every [prepared statement] in order to avoid
-** resource leaks. It is a grievous error for the application to try to use
-** a prepared statement after it has been finalized. Any use of a prepared
-** statement after it has been finalized can result in undefined and
-** undesirable behavior such as segfaults and heap corruption.
-*/
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Reset A Prepared Statement Object
-**
-** The sqlite3_reset() function is called to reset a [prepared statement]
-** object back to its initial state, ready to be re-executed.
-** ^Any SQL statement variables that had values bound to them using
-** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
-** Use [sqlite3_clear_bindings()] to reset the bindings.
-**
-** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S
-** back to the beginning of its program.
-**
-** ^If the most recent call to [sqlite3_step(S)] for the
-** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
-** or if [sqlite3_step(S)] has never before been called on S,
-** then [sqlite3_reset(S)] returns [SQLITE_OK].
-**
-** ^If the most recent call to [sqlite3_step(S)] for the
-** [prepared statement] S indicated an error, then
-** [sqlite3_reset(S)] returns an appropriate [error code].
-**
-** ^The [sqlite3_reset(S)] interface does not change the values
-** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
-*/
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Create Or Redefine SQL Functions
-** KEYWORDS: {function creation routines}
-** KEYWORDS: {application-defined SQL function}
-** KEYWORDS: {application-defined SQL functions}
-**
-** ^These functions (collectively known as "function creation routines")
-** are used to add SQL functions or aggregates or to redefine the behavior
-** of existing SQL functions or aggregates. The only differences between
-** these routines are the text encoding expected for
-** the second parameter (the name of the function being created)
-** and the presence or absence of a destructor callback for
-** the application data pointer.
-**
-** ^The first parameter is the [database connection] to which the SQL
-** function is to be added. ^If an application uses more than one database
-** connection then application-defined SQL functions must be added
-** to each database connection separately.
-**
-** ^The second parameter is the name of the SQL function to be created or
-** redefined. ^The length of the name is limited to 255 bytes in a UTF-8
-** representation, exclusive of the zero-terminator. ^Note that the name
-** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.
-** ^Any attempt to create a function with a longer name
-** will result in [SQLITE_MISUSE] being returned.
-**
-** ^The third parameter (nArg)
-** is the number of arguments that the SQL function or
-** aggregate takes. ^If this parameter is -1, then the SQL function or
-** aggregate may take any number of arguments between 0 and the limit
-** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third
-** parameter is less than -1 or greater than 127 then the behavior is
-** undefined.
-**
-** ^The fourth parameter, eTextRep, specifies what
-** [SQLITE_UTF8 | text encoding] this SQL function prefers for
-** its parameters. Every SQL function implementation must be able to work
-** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be
-** more efficient with one encoding than another. ^An application may
-** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
-** times with the same function but with different values of eTextRep.
-** ^When multiple implementations of the same function are available, SQLite
-** will pick the one that involves the least amount of data conversion.
-** If there is only a single implementation which does not care what text
-** encoding is used, then the fourth argument should be [SQLITE_ANY].
-**
-** ^(The fifth parameter is an arbitrary pointer. The implementation of the
-** function can gain access to this pointer using [sqlite3_user_data()].)^
-**
-** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
-** pointers to C-language functions that implement the SQL function or
-** aggregate. ^A scalar SQL function requires an implementation of the xFunc
-** callback only; NULL pointers must be passed as the xStep and xFinal
-** parameters. ^An aggregate SQL function requires an implementation of xStep
-** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
-** SQL function or aggregate, pass NULL pointers for all three function
-** callbacks.
-**
-** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
-** then it is destructor for the application data pointer.
-** The destructor is invoked when the function is deleted, either by being
-** overloaded or when the database connection closes.)^
-** ^The destructor is also invoked if the call to
-** sqlite3_create_function_v2() fails.
-** ^When the destructor callback of the tenth parameter is invoked, it
-** is passed a single argument which is a copy of the application data
-** pointer which was the fifth parameter to sqlite3_create_function_v2().
-**
-** ^It is permitted to register multiple implementations of the same
-** functions with the same name but with either differing numbers of
-** arguments or differing preferred text encodings. ^SQLite will use
-** the implementation that most closely matches the way in which the
-** SQL function is used. ^A function implementation with a non-negative
-** nArg parameter is a better match than a function implementation with
-** a negative nArg. ^A function where the preferred text encoding
-** matches the database encoding is a better
-** match than a function where the encoding is different.
-** ^A function where the encoding difference is between UTF16le and UTF16be
-** is a closer match than a function where the encoding difference is
-** between UTF8 and UTF16.
-**
-** ^Built-in functions may be overloaded by new application-defined functions.
-**
-** ^An application-defined function is permitted to call other
-** SQLite interfaces. However, such calls must not
-** close the database connection nor finalize or reset the prepared
-** statement in which the function is running.
-*/
-SQLITE_API int sqlite3_create_function(
- sqlite3 *db,
- const char *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-);
-SQLITE_API int sqlite3_create_function16(
- sqlite3 *db,
- const void *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-);
-SQLITE_API int sqlite3_create_function_v2(
- sqlite3 *db,
- const char *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*),
- void(*xDestroy)(void*)
-);
-
-/*
-** CAPI3REF: Text Encodings
-**
-** These constant define integer codes that represent the various
-** text encodings supported by SQLite.
-*/
-#define SQLITE_UTF8 1
-#define SQLITE_UTF16LE 2
-#define SQLITE_UTF16BE 3
-#define SQLITE_UTF16 4 /* Use native byte order */
-#define SQLITE_ANY 5 /* sqlite3_create_function only */
-#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
-
-/*
-** CAPI3REF: Deprecated Functions
-** DEPRECATED
-**
-** These functions are [deprecated]. In order to maintain
-** backwards compatibility with older code, these functions continue
-** to be supported. However, new applications should avoid
-** the use of these functions. To help encourage people to avoid
-** using these functions, we are not going to tell you what they do.
-*/
-#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64);
-#endif
-
-/*
-** CAPI3REF: Obtaining SQL Function Parameter Values
-**
-** The C-language implementation of SQL functions and aggregates uses
-** this set of interface routines to access the parameter values on
-** the function or aggregate.
-**
-** The xFunc (for scalar functions) or xStep (for aggregates) parameters
-** to [sqlite3_create_function()] and [sqlite3_create_function16()]
-** define callbacks that implement the SQL functions and aggregates.
-** The 3rd parameter to these callbacks is an array of pointers to
-** [protected sqlite3_value] objects. There is one [sqlite3_value] object for
-** each parameter to the SQL function. These routines are used to
-** extract values from the [sqlite3_value] objects.
-**
-** These routines work only with [protected sqlite3_value] objects.
-** Any attempt to use these routines on an [unprotected sqlite3_value]
-** object results in undefined behavior.
-**
-** ^These routines work just like the corresponding [column access functions]
-** except that these routines take a single [protected sqlite3_value] object
-** pointer instead of a [sqlite3_stmt*] pointer and an integer column number.
-**
-** ^The sqlite3_value_text16() interface extracts a UTF-16 string
-** in the native byte-order of the host machine. ^The
-** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
-** extract UTF-16 strings as big-endian and little-endian respectively.
-**
-** ^(The sqlite3_value_numeric_type() interface attempts to apply
-** numeric affinity to the value. This means that an attempt is
-** made to convert the value to an integer or floating point. If
-** such a conversion is possible without loss of information (in other
-** words, if the value is a string that looks like a number)
-** then the conversion is performed. Otherwise no conversion occurs.
-** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
-**
-** Please pay particular attention to the fact that the pointer returned
-** from [sqlite3_value_blob()], [sqlite3_value_text()], or
-** [sqlite3_value_text16()] can be invalidated by a subsequent call to
-** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
-** or [sqlite3_value_text16()].
-**
-** These routines must be called from the same thread as
-** the SQL function that supplied the [sqlite3_value*] parameters.
-*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double sqlite3_value_double(sqlite3_value*);
-SQLITE_API int sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int sqlite3_value_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
-
-/*
-** CAPI3REF: Obtain Aggregate Function Context
-**
-** Implementations of aggregate SQL functions use this
-** routine to allocate memory for storing their state.
-**
-** ^The first time the sqlite3_aggregate_context(C,N) routine is called
-** for a particular aggregate function, SQLite
-** allocates N of memory, zeroes out that memory, and returns a pointer
-** to the new memory. ^On second and subsequent calls to
-** sqlite3_aggregate_context() for the same aggregate function instance,
-** the same buffer is returned. Sqlite3_aggregate_context() is normally
-** called once for each invocation of the xStep callback and then one
-** last time when the xFinal callback is invoked. ^(When no rows match
-** an aggregate query, the xStep() callback of the aggregate function
-** implementation is never called and xFinal() is called exactly once.
-** In those cases, sqlite3_aggregate_context() might be called for the
-** first time from within xFinal().)^
-**
-** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer if N is
-** less than or equal to zero or if a memory allocate error occurs.
-**
-** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
-** determined by the N parameter on first successful call. Changing the
-** value of N in subsequent call to sqlite3_aggregate_context() within
-** the same aggregate function instance will not resize the memory
-** allocation.)^
-**
-** ^SQLite automatically frees the memory allocated by
-** sqlite3_aggregate_context() when the aggregate query concludes.
-**
-** The first parameter must be a copy of the
-** [sqlite3_context | SQL function context] that is the first parameter
-** to the xStep or xFinal callback routine that implements the aggregate
-** function.
-**
-** This routine must be called from the same thread in which
-** the aggregate SQL function is running.
-*/
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
-
-/*
-** CAPI3REF: User Data For Functions
-**
-** ^The sqlite3_user_data() interface returns a copy of
-** the pointer that was the pUserData parameter (the 5th parameter)
-** of the [sqlite3_create_function()]
-** and [sqlite3_create_function16()] routines that originally
-** registered the application defined function.
-**
-** This routine must be called from the same thread in which
-** the application-defined function is running.
-*/
-SQLITE_API void *sqlite3_user_data(sqlite3_context*);
-
-/*
-** CAPI3REF: Database Connection For Functions
-**
-** ^The sqlite3_context_db_handle() interface returns a copy of
-** the pointer to the [database connection] (the 1st parameter)
-** of the [sqlite3_create_function()]
-** and [sqlite3_create_function16()] routines that originally
-** registered the application defined function.
-*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
-
-/*
-** CAPI3REF: Function Auxiliary Data
-**
-** The following two functions may be used by scalar SQL functions to
-** associate metadata with argument values. If the same value is passed to
-** multiple invocations of the same SQL function during query execution, under
-** some circumstances the associated metadata may be preserved. This may
-** be used, for example, to add a regular-expression matching scalar
-** function. The compiled version of the regular expression is stored as
-** metadata associated with the SQL value passed as the regular expression
-** pattern. The compiled regular expression can be reused on multiple
-** invocations of the same function so that the original pattern string
-** does not need to be recompiled on each invocation.
-**
-** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. ^If no metadata has been ever
-** been set for the Nth argument of the function, or if the corresponding
-** function parameter has changed since the meta-data was set,
-** then sqlite3_get_auxdata() returns a NULL pointer.
-**
-** ^The sqlite3_set_auxdata() interface saves the metadata
-** pointed to by its 3rd parameter as the metadata for the N-th
-** argument of the application-defined function. Subsequent
-** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed.
-** ^If it is not NULL, SQLite will invoke the destructor
-** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the metadata when the corresponding function parameter changes
-** or when the SQL statement completes, whichever comes first.
-**
-** SQLite is free to call the destructor and drop metadata on any
-** parameter of any function at any time. ^The only guarantee is that
-** the destructor will be called before the metadata is dropped.
-**
-** ^(In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and [parameters].)^
-**
-** These routines must be called from the same thread in which
-** the SQL function is running.
-*/
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
-
-
-/*
-** CAPI3REF: Constants Defining Special Destructor Behavior
-**
-** These are special values for the destructor that is passed in as the
-** final argument to routines like [sqlite3_result_blob()]. ^If the destructor
-** argument is SQLITE_STATIC, it means that the content pointer is constant
-** and will never change. It does not need to be destroyed. ^The
-** SQLITE_TRANSIENT value means that the content will likely change in
-** the near future and that SQLite should make its own private copy of
-** the content before returning.
-**
-** The typedef is necessary to work around problems in certain
-** C++ compilers. See ticket #2191.
-*/
-typedef void (*sqlite3_destructor_type)(void*);
-#define SQLITE_STATIC ((sqlite3_destructor_type)0)
-#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
-
-/*
-** CAPI3REF: Setting The Result Of An SQL Function
-**
-** These routines are used by the xFunc or xFinal callbacks that
-** implement SQL functions and aggregates. See
-** [sqlite3_create_function()] and [sqlite3_create_function16()]
-** for additional information.
-**
-** These functions work very much like the [parameter binding] family of
-** functions used to bind values to host parameters in prepared statements.
-** Refer to the [SQL parameter] documentation for additional information.
-**
-** ^The sqlite3_result_blob() interface sets the result from
-** an application-defined function to be the BLOB whose content is pointed
-** to by the second parameter and which is N bytes long where N is the
-** third parameter.
-**
-** ^The sqlite3_result_zeroblob() interfaces set the result of
-** the application-defined function to be a BLOB containing all zero
-** bytes and N bytes in size, where N is the value of the 2nd parameter.
-**
-** ^The sqlite3_result_double() interface sets the result from
-** an application-defined function to be a floating point value specified
-** by its 2nd argument.
-**
-** ^The sqlite3_result_error() and sqlite3_result_error16() functions
-** cause the implemented SQL function to throw an exception.
-** ^SQLite uses the string pointed to by the
-** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
-** as the text of an error message. ^SQLite interprets the error
-** message string from sqlite3_result_error() as UTF-8. ^SQLite
-** interprets the string from sqlite3_result_error16() as UTF-16 in native
-** byte order. ^If the third parameter to sqlite3_result_error()
-** or sqlite3_result_error16() is negative then SQLite takes as the error
-** message all text up through the first zero character.
-** ^If the third parameter to sqlite3_result_error() or
-** sqlite3_result_error16() is non-negative then SQLite takes that many
-** bytes (not characters) from the 2nd parameter as the error message.
-** ^The sqlite3_result_error() and sqlite3_result_error16()
-** routines make a private copy of the error message text before
-** they return. Hence, the calling function can deallocate or
-** modify the text after they return without harm.
-** ^The sqlite3_result_error_code() function changes the error code
-** returned by SQLite as a result of an error in a function. ^By default,
-** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error()
-** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
-**
-** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an
-** error indicating that a string or BLOB is too long to represent.
-**
-** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an
-** error indicating that a memory allocation failed.
-**
-** ^The sqlite3_result_int() interface sets the return value
-** of the application-defined function to be the 32-bit signed integer
-** value given in the 2nd argument.
-** ^The sqlite3_result_int64() interface sets the return value
-** of the application-defined function to be the 64-bit signed integer
-** value given in the 2nd argument.
-**
-** ^The sqlite3_result_null() interface sets the return value
-** of the application-defined function to be NULL.
-**
-** ^The sqlite3_result_text(), sqlite3_result_text16(),
-** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
-** set the return value of the application-defined function to be
-** a text string which is represented as UTF-8, UTF-16 native byte order,
-** UTF-16 little endian, or UTF-16 big endian, respectively.
-** ^SQLite takes the text result from the application from
-** the 2nd parameter of the sqlite3_result_text* interfaces.
-** ^If the 3rd parameter to the sqlite3_result_text* interfaces
-** is negative, then SQLite takes result text from the 2nd parameter
-** through the first zero character.
-** ^If the 3rd parameter to the sqlite3_result_text* interfaces
-** is non-negative, then as many bytes (not characters) of the text
-** pointed to by the 2nd parameter are taken as the application-defined
-** function result. If the 3rd parameter is non-negative, then it
-** must be the byte offset into the string where the NUL terminator would
-** appear if the string where NUL terminated. If any NUL characters occur
-** in the string at a byte offset that is less than the value of the 3rd
-** parameter, then the resulting string will contain embedded NULs and the
-** result of expressions operating on strings with embedded NULs is undefined.
-** ^If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
-** function as the destructor on the text or BLOB result when it has
-** finished using that result.
-** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
-** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
-** assumes that the text or BLOB result is in constant space and does not
-** copy the content of the parameter nor call a destructor on the content
-** when it has finished using that result.
-** ^If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
-** then SQLite makes a copy of the result into space obtained from
-** from [sqlite3_malloc()] before it returns.
-**
-** ^The sqlite3_result_value() interface sets the result of
-** the application-defined function to be a copy the
-** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
-** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
-** so that the [sqlite3_value] specified in the parameter may change or
-** be deallocated after sqlite3_result_value() returns without harm.
-** ^A [protected sqlite3_value] object may always be used where an
-** [unprotected sqlite3_value] object is required, so either
-** kind of [sqlite3_value] object can be used with this interface.
-**
-** If these routines are called from within the different thread
-** than the one containing the application-defined function that received
-** the [sqlite3_context] pointer, the results are undefined.
-*/
-SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void sqlite3_result_null(sqlite3_context*);
-SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
-
-/*
-** CAPI3REF: Define New Collating Sequences
-**
-** ^These functions add, remove, or modify a [collation] associated
-** with the [database connection] specified as the first argument.
-**
-** ^The name of the collation is a UTF-8 string
-** for sqlite3_create_collation() and sqlite3_create_collation_v2()
-** and a UTF-16 string in native byte order for sqlite3_create_collation16().
-** ^Collation names that compare equal according to [sqlite3_strnicmp()] are
-** considered to be the same name.
-**
-** ^(The third argument (eTextRep) must be one of the constants:
-** <ul>
-** <li> [SQLITE_UTF8],
-** <li> [SQLITE_UTF16LE],
-** <li> [SQLITE_UTF16BE],
-** <li> [SQLITE_UTF16], or
-** <li> [SQLITE_UTF16_ALIGNED].
-** </ul>)^
-** ^The eTextRep argument determines the encoding of strings passed
-** to the collating function callback, xCallback.
-** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
-** force strings to be UTF16 with native byte order.
-** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
-** on an even byte address.
-**
-** ^The fourth argument, pArg, is an application data pointer that is passed
-** through as the first argument to the collating function callback.
-**
-** ^The fifth argument, xCallback, is a pointer to the collating function.
-** ^Multiple collating functions can be registered using the same name but
-** with different eTextRep parameters and SQLite will use whichever
-** function requires the least amount of data transformation.
-** ^If the xCallback argument is NULL then the collating function is
-** deleted. ^When all collating functions having the same name are deleted,
-** that collation is no longer usable.
-**
-** ^The collating function callback is invoked with a copy of the pArg
-** application data pointer and with two strings in the encoding specified
-** by the eTextRep argument. The collating function must return an
-** integer that is negative, zero, or positive
-** if the first string is less than, equal to, or greater than the second,
-** respectively. A collating function must always return the same answer
-** given the same inputs. If two or more collating functions are registered
-** to the same collation name (using different eTextRep values) then all
-** must give an equivalent answer when invoked with equivalent strings.
-** The collating function must obey the following properties for all
-** strings A, B, and C:
-**
-** <ol>
-** <li> If A==B then B==A.
-** <li> If A==B and B==C then A==C.
-** <li> If A&lt;B THEN B&gt;A.
-** <li> If A&lt;B and B&lt;C then A&lt;C.
-** </ol>
-**
-** If a collating function fails any of the above constraints and that
-** collating function is registered and used, then the behavior of SQLite
-** is undefined.
-**
-** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation()
-** with the addition that the xDestroy callback is invoked on pArg when
-** the collating function is deleted.
-** ^Collating functions are deleted when they are overridden by later
-** calls to the collation creation functions or when the
-** [database connection] is closed using [sqlite3_close()].
-**
-** ^The xDestroy callback is <u>not</u> called if the
-** sqlite3_create_collation_v2() function fails. Applications that invoke
-** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should
-** check the return code and dispose of the application data pointer
-** themselves rather than expecting SQLite to deal with it for them.
-** This is different from every other SQLite interface. The inconsistency
-** is unfortunate but cannot be changed without breaking backwards
-** compatibility.
-**
-** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
-*/
-SQLITE_API int sqlite3_create_collation(
- sqlite3*,
- const char *zName,
- int eTextRep,
- void *pArg,
- int(*xCompare)(void*,int,const void*,int,const void*)
-);
-SQLITE_API int sqlite3_create_collation_v2(
- sqlite3*,
- const char *zName,
- int eTextRep,
- void *pArg,
- int(*xCompare)(void*,int,const void*,int,const void*),
- void(*xDestroy)(void*)
-);
-SQLITE_API int sqlite3_create_collation16(
- sqlite3*,
- const void *zName,
- int eTextRep,
- void *pArg,
- int(*xCompare)(void*,int,const void*,int,const void*)
-);
-
-/*
-** CAPI3REF: Collation Needed Callbacks
-**
-** ^To avoid having to register all collation sequences before a database
-** can be used, a single callback function may be registered with the
-** [database connection] to be invoked whenever an undefined collation
-** sequence is required.
-**
-** ^If the function is registered using the sqlite3_collation_needed() API,
-** then it is passed the names of undefined collation sequences as strings
-** encoded in UTF-8. ^If sqlite3_collation_needed16() is used,
-** the names are passed as UTF-16 in machine native byte order.
-** ^A call to either function replaces the existing collation-needed callback.
-**
-** ^(When the callback is invoked, the first argument passed is a copy
-** of the second argument to sqlite3_collation_needed() or
-** sqlite3_collation_needed16(). The second argument is the database
-** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE],
-** or [SQLITE_UTF16LE], indicating the most desirable form of the collation
-** sequence function required. The fourth parameter is the name of the
-** required collation sequence.)^
-**
-** The callback function should register the desired collation using
-** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
-** [sqlite3_create_collation_v2()].
-*/
-SQLITE_API int sqlite3_collation_needed(
- sqlite3*,
- void*,
- void(*)(void*,sqlite3*,int eTextRep,const char*)
-);
-SQLITE_API int sqlite3_collation_needed16(
- sqlite3*,
- void*,
- void(*)(void*,sqlite3*,int eTextRep,const void*)
-);
-
-#ifdef SQLITE_HAS_CODEC
-/*
-** Specify the key for an encrypted database. This routine should be
-** called right after sqlite3_open().
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_key(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The key */
-);
-
-/*
-** Change the key on an open database. If the current database is not
-** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
-** database is decrypted.
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_rekey(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The new key */
-);
-
-/*
-** Specify the activation key for a SEE database. Unless
-** activated, none of the SEE routines will work.
-*/
-SQLITE_API void sqlite3_activate_see(
- const char *zPassPhrase /* Activation phrase */
-);
-#endif
-
-#ifdef SQLITE_ENABLE_CEROD
-/*
-** Specify the activation key for a CEROD database. Unless
-** activated, none of the CEROD routines will work.
-*/
-SQLITE_API void sqlite3_activate_cerod(
- const char *zPassPhrase /* Activation phrase */
-);
-#endif
-
-/*
-** CAPI3REF: Suspend Execution For A Short Time
-**
-** The sqlite3_sleep() function causes the current thread to suspend execution
-** for at least a number of milliseconds specified in its parameter.
-**
-** If the operating system does not support sleep requests with
-** millisecond time resolution, then the time will be rounded up to
-** the nearest second. The number of milliseconds of sleep actually
-** requested from the operating system is returned.
-**
-** ^SQLite implements this interface by calling the xSleep()
-** method of the default [sqlite3_vfs] object. If the xSleep() method
-** of the default VFS is not implemented correctly, or not implemented at
-** all, then the behavior of sqlite3_sleep() may deviate from the description
-** in the previous paragraphs.
-*/
-SQLITE_API int sqlite3_sleep(int);
-
-/*
-** CAPI3REF: Name Of The Folder Holding Temporary Files
-**
-** ^(If this global variable is made to point to a string which is
-** the name of a folder (a.k.a. directory), then all temporary files
-** created by SQLite when using a built-in [sqlite3_vfs | VFS]
-** will be placed in that directory.)^ ^If this variable
-** is a NULL pointer, then SQLite performs a search for an appropriate
-** temporary file directory.
-**
-** It is not safe to read or modify this variable in more than one
-** thread at a time. It is not safe to read or modify this variable
-** if a [database connection] is being used at the same time in a separate
-** thread.
-** It is intended that this variable be set once
-** as part of process initialization and before any SQLite interface
-** routines have been called and that this variable remain unchanged
-** thereafter.
-**
-** ^The [temp_store_directory pragma] may modify this variable and cause
-** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore,
-** the [temp_store_directory pragma] always assumes that any string
-** that this variable points to is held in memory obtained from
-** [sqlite3_malloc] and the pragma may attempt to free that memory
-** using [sqlite3_free].
-** Hence, if this variable is modified directly, either it should be
-** made NULL or made to point to memory obtained from [sqlite3_malloc]
-** or else the use of the [temp_store_directory pragma] should be avoided.
-**
-** <b>Note to Windows Runtime users:</b> The temporary directory must be set
-** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various
-** features that require the use of temporary files may fail. Here is an
-** example of how to do this using C++ with the Windows Runtime:
-**
-** <blockquote><pre>
-** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
-** &nbsp; TemporaryFolder->Path->Data();
-** char zPathBuf&#91;MAX_PATH + 1&#93;;
-** memset(zPathBuf, 0, sizeof(zPathBuf));
-** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
-** &nbsp; NULL, NULL);
-** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
-** </pre></blockquote>
-*/
-SQLITE_API char *sqlite3_temp_directory;
-
-/*
-** CAPI3REF: Name Of The Folder Holding Database Files
-**
-** ^(If this global variable is made to point to a string which is
-** the name of a folder (a.k.a. directory), then all database files
-** specified with a relative pathname and created or accessed by
-** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed
-** to be relative to that directory.)^ ^If this variable is a NULL
-** pointer, then SQLite assumes that all database files specified
-** with a relative pathname are relative to the current directory
-** for the process. Only the windows VFS makes use of this global
-** variable; it is ignored by the unix VFS.
-**
-** Changing the value of this variable while a database connection is
-** open can result in a corrupt database.
-**
-** It is not safe to read or modify this variable in more than one
-** thread at a time. It is not safe to read or modify this variable
-** if a [database connection] is being used at the same time in a separate
-** thread.
-** It is intended that this variable be set once
-** as part of process initialization and before any SQLite interface
-** routines have been called and that this variable remain unchanged
-** thereafter.
-**
-** ^The [data_store_directory pragma] may modify this variable and cause
-** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore,
-** the [data_store_directory pragma] always assumes that any string
-** that this variable points to is held in memory obtained from
-** [sqlite3_malloc] and the pragma may attempt to free that memory
-** using [sqlite3_free].
-** Hence, if this variable is modified directly, either it should be
-** made NULL or made to point to memory obtained from [sqlite3_malloc]
-** or else the use of the [data_store_directory pragma] should be avoided.
-*/
-SQLITE_API char *sqlite3_data_directory;
-
-/*
-** CAPI3REF: Test For Auto-Commit Mode
-** KEYWORDS: {autocommit mode}
-**
-** ^The sqlite3_get_autocommit() interface returns non-zero or
-** zero if the given database connection is or is not in autocommit mode,
-** respectively. ^Autocommit mode is on by default.
-** ^Autocommit mode is disabled by a [BEGIN] statement.
-** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
-**
-** If certain kinds of errors occur on a statement within a multi-statement
-** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
-** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
-** transaction might be rolled back automatically. The only way to
-** find out whether SQLite automatically rolled back the transaction after
-** an error is to use this function.
-**
-** If another thread changes the autocommit status of the database
-** connection while this routine is running, then the return value
-** is undefined.
-*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
-
-/*
-** CAPI3REF: Find The Database Handle Of A Prepared Statement
-**
-** ^The sqlite3_db_handle interface returns the [database connection] handle
-** to which a [prepared statement] belongs. ^The [database connection]
-** returned by sqlite3_db_handle is the same [database connection]
-** that was the first argument
-** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
-** create the statement in the first place.
-*/
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Return The Filename For A Database Connection
-**
-** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
-** associated with database N of connection D. ^The main database file
-** has the name "main". If there is no attached database N on the database
-** connection D, or if database N is a temporary or in-memory database, then
-** a NULL pointer is returned.
-**
-** ^The filename returned by this function is the output of the
-** xFullPathname method of the [VFS]. ^In other words, the filename
-** will be an absolute pathname, even if the filename used
-** to open the database originally was a URI or relative pathname.
-*/
-SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
-
-/*
-** CAPI3REF: Determine if a database is read-only
-**
-** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
-** of connection D is read-only, 0 if it is read/write, or -1 if N is not
-** the name of a database on connection D.
-*/
-SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
-
-/*
-** CAPI3REF: Find the next prepared statement
-**
-** ^This interface returns a pointer to the next [prepared statement] after
-** pStmt associated with the [database connection] pDb. ^If pStmt is NULL
-** then this interface returns a pointer to the first prepared statement
-** associated with the database connection pDb. ^If no prepared statement
-** satisfies the conditions of this routine, it returns NULL.
-**
-** The [database connection] pointer D in a call to
-** [sqlite3_next_stmt(D,S)] must refer to an open database
-** connection and in particular must not be a NULL pointer.
-*/
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Commit And Rollback Notification Callbacks
-**
-** ^The sqlite3_commit_hook() interface registers a callback
-** function to be invoked whenever a transaction is [COMMIT | committed].
-** ^Any callback set by a previous call to sqlite3_commit_hook()
-** for the same database connection is overridden.
-** ^The sqlite3_rollback_hook() interface registers a callback
-** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
-** ^Any callback set by a previous call to sqlite3_rollback_hook()
-** for the same database connection is overridden.
-** ^The pArg argument is passed through to the callback.
-** ^If the callback on a commit hook function returns non-zero,
-** then the commit is converted into a rollback.
-**
-** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions
-** return the P argument from the previous call of the same function
-** on the same [database connection] D, or NULL for
-** the first call for each function on D.
-**
-** The commit and rollback hook callbacks are not reentrant.
-** The callback implementation must not do anything that will modify
-** the database connection that invoked the callback. Any actions
-** to modify the database connection must be deferred until after the
-** completion of the [sqlite3_step()] call that triggered the commit
-** or rollback hook in the first place.
-** Note that running any other SQL statements, including SELECT statements,
-** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify
-** the database connections for the meaning of "modify" in this paragraph.
-**
-** ^Registering a NULL function disables the callback.
-**
-** ^When the commit hook callback routine returns zero, the [COMMIT]
-** operation is allowed to continue normally. ^If the commit hook
-** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
-** ^The rollback hook is invoked on a rollback that results from a commit
-** hook returning non-zero, just as it would be with any other rollback.
-**
-** ^For the purposes of this API, a transaction is said to have been
-** rolled back if an explicit "ROLLBACK" statement is executed, or
-** an error or constraint causes an implicit rollback to occur.
-** ^The rollback callback is not invoked if a transaction is
-** automatically rolled back because the database connection is closed.
-**
-** See also the [sqlite3_update_hook()] interface.
-*/
-SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
-
-/*
-** CAPI3REF: Data Change Notification Callbacks
-**
-** ^The sqlite3_update_hook() interface registers a callback function
-** with the [database connection] identified by the first argument
-** to be invoked whenever a row is updated, inserted or deleted.
-** ^Any callback set by a previous call to this function
-** for the same database connection is overridden.
-**
-** ^The second argument is a pointer to the function to invoke when a
-** row is updated, inserted or deleted.
-** ^The first argument to the callback is a copy of the third argument
-** to sqlite3_update_hook().
-** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
-** or [SQLITE_UPDATE], depending on the operation that caused the callback
-** to be invoked.
-** ^The third and fourth arguments to the callback contain pointers to the
-** database and table name containing the affected row.
-** ^The final callback parameter is the [rowid] of the row.
-** ^In the case of an update, this is the [rowid] after the update takes place.
-**
-** ^(The update hook is not invoked when internal system tables are
-** modified (i.e. sqlite_master and sqlite_sequence).)^
-**
-** ^In the current implementation, the update hook
-** is not invoked when duplication rows are deleted because of an
-** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
-** invoked when rows are deleted using the [truncate optimization].
-** The exceptions defined in this paragraph might change in a future
-** release of SQLite.
-**
-** The update hook implementation must not do anything that will modify
-** the database connection that invoked the update hook. Any actions
-** to modify the database connection must be deferred until after the
-** completion of the [sqlite3_step()] call that triggered the update hook.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** ^The sqlite3_update_hook(D,C,P) function
-** returns the P argument from the previous call
-** on the same [database connection] D, or NULL for
-** the first call on D.
-**
-** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
-** interfaces.
-*/
-SQLITE_API void *sqlite3_update_hook(
- sqlite3*,
- void(*)(void *,int ,char const *,char const *,sqlite3_int64),
- void*
-);
-
-/*
-** CAPI3REF: Enable Or Disable Shared Pager Cache
-**
-** ^(This routine enables or disables the sharing of the database cache
-** and schema data structures between [database connection | connections]
-** to the same database. Sharing is enabled if the argument is true
-** and disabled if the argument is false.)^
-**
-** ^Cache sharing is enabled and disabled for an entire process.
-** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
-** sharing was enabled or disabled for each thread separately.
-**
-** ^(The cache sharing mode set by this interface effects all subsequent
-** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
-** Existing database connections continue use the sharing mode
-** that was in effect at the time they were opened.)^
-**
-** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled
-** successfully. An [error code] is returned otherwise.)^
-**
-** ^Shared cache is disabled by default. But this might change in
-** future releases of SQLite. Applications that care about shared
-** cache setting should set it explicitly.
-**
-** This interface is threadsafe on processors where writing a
-** 32-bit integer is atomic.
-**
-** See Also: [SQLite Shared-Cache Mode]
-*/
-SQLITE_API int sqlite3_enable_shared_cache(int);
-
-/*
-** CAPI3REF: Attempt To Free Heap Memory
-**
-** ^The sqlite3_release_memory() interface attempts to free N bytes
-** of heap memory by deallocating non-essential memory allocations
-** held by the database library. Memory used to cache database
-** pages to improve performance is an example of non-essential memory.
-** ^sqlite3_release_memory() returns the number of bytes actually freed,
-** which might be more or less than the amount requested.
-** ^The sqlite3_release_memory() routine is a no-op returning zero
-** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT].
-**
-** See also: [sqlite3_db_release_memory()]
-*/
-SQLITE_API int sqlite3_release_memory(int);
-
-/*
-** CAPI3REF: Free Memory Used By A Database Connection
-**
-** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
-** memory as possible from database connection D. Unlike the
-** [sqlite3_release_memory()] interface, this interface is effect even
-** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
-** omitted.
-**
-** See also: [sqlite3_release_memory()]
-*/
-SQLITE_API int sqlite3_db_release_memory(sqlite3*);
-
-/*
-** CAPI3REF: Impose A Limit On Heap Size
-**
-** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
-** soft limit on the amount of heap memory that may be allocated by SQLite.
-** ^SQLite strives to keep heap memory utilization below the soft heap
-** limit by reducing the number of pages held in the page cache
-** as heap memory usages approaches the limit.
-** ^The soft heap limit is "soft" because even though SQLite strives to stay
-** below the limit, it will exceed the limit rather than generate
-** an [SQLITE_NOMEM] error. In other words, the soft heap limit
-** is advisory only.
-**
-** ^The return value from sqlite3_soft_heap_limit64() is the size of
-** the soft heap limit prior to the call, or negative in the case of an
-** error. ^If the argument N is negative
-** then no change is made to the soft heap limit. Hence, the current
-** size of the soft heap limit can be determined by invoking
-** sqlite3_soft_heap_limit64() with a negative argument.
-**
-** ^If the argument N is zero then the soft heap limit is disabled.
-**
-** ^(The soft heap limit is not enforced in the current implementation
-** if one or more of following conditions are true:
-**
-** <ul>
-** <li> The soft heap limit is set to zero.
-** <li> Memory accounting is disabled using a combination of the
-** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
-** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
-** <li> An alternative page cache implementation is specified using
-** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...).
-** <li> The page cache allocates from its own memory pool supplied
-** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
-** from the heap.
-** </ul>)^
-**
-** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
-** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
-** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
-** the soft heap limit is enforced on every memory allocation. Without
-** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced
-** when memory is allocated by the page cache. Testing suggests that because
-** the page cache is the predominate memory user in SQLite, most
-** applications will achieve adequate soft heap limit enforcement without
-** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT].
-**
-** The circumstances under which SQLite will enforce the soft heap limit may
-** changes in future releases of SQLite.
-*/
-SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
-
-/*
-** CAPI3REF: Deprecated Soft Heap Limit Interface
-** DEPRECATED
-**
-** This is a deprecated version of the [sqlite3_soft_heap_limit64()]
-** interface. This routine is provided for historical compatibility
-** only. All new applications should use the
-** [sqlite3_soft_heap_limit64()] interface rather than this one.
-*/
-SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
-
-
-/*
-** CAPI3REF: Extract Metadata About A Column Of A Table
-**
-** ^This routine returns metadata about a specific column of a specific
-** database table accessible using the [database connection] handle
-** passed as the first function argument.
-**
-** ^The column is identified by the second, third and fourth parameters to
-** this function. ^The second parameter is either the name of the database
-** (i.e. "main", "temp", or an attached database) containing the specified
-** table or NULL. ^If it is NULL, then all attached databases are searched
-** for the table using the same algorithm used by the database engine to
-** resolve unqualified table references.
-**
-** ^The third and fourth parameters to this function are the table and column
-** name of the desired column, respectively. Neither of these parameters
-** may be NULL.
-**
-** ^Metadata is returned by writing to the memory locations passed as the 5th
-** and subsequent parameters to this function. ^Any of these arguments may be
-** NULL, in which case the corresponding element of metadata is omitted.
-**
-** ^(<blockquote>
-** <table border="1">
-** <tr><th> Parameter <th> Output<br>Type <th> Description
-**
-** <tr><td> 5th <td> const char* <td> Data type
-** <tr><td> 6th <td> const char* <td> Name of default collation sequence
-** <tr><td> 7th <td> int <td> True if column has a NOT NULL constraint
-** <tr><td> 8th <td> int <td> True if column is part of the PRIMARY KEY
-** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
-** </table>
-** </blockquote>)^
-**
-** ^The memory pointed to by the character pointers returned for the
-** declaration type and collation sequence is valid only until the next
-** call to any SQLite API function.
-**
-** ^If the specified table is actually a view, an [error code] is returned.
-**
-** ^If the specified column is "rowid", "oid" or "_rowid_" and an
-** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
-** parameters are set for the explicitly declared column. ^(If there is no
-** explicitly declared [INTEGER PRIMARY KEY] column, then the output
-** parameters are set as follows:
-**
-** <pre>
-** data type: "INTEGER"
-** collation sequence: "BINARY"
-** not null: 0
-** primary key: 1
-** auto increment: 0
-** </pre>)^
-**
-** ^(This function may load one or more schemas from database files. If an
-** error occurs during this process, or if the requested table or column
-** cannot be found, an [error code] is returned and an error message left
-** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
-**
-** ^This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
-*/
-SQLITE_API int sqlite3_table_column_metadata(
- sqlite3 *db, /* Connection handle */
- const char *zDbName, /* Database name or NULL */
- const char *zTableName, /* Table name */
- const char *zColumnName, /* Column name */
- char const **pzDataType, /* OUTPUT: Declared data type */
- char const **pzCollSeq, /* OUTPUT: Collation sequence name */
- int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
- int *pPrimaryKey, /* OUTPUT: True if column part of PK */
- int *pAutoinc /* OUTPUT: True if column is auto-increment */
-);
-
-/*
-** CAPI3REF: Load An Extension
-**
-** ^This interface loads an SQLite extension library from the named file.
-**
-** ^The sqlite3_load_extension() interface attempts to load an
-** SQLite extension library contained in the file zFile.
-**
-** ^The entry point is zProc.
-** ^zProc may be 0, in which case the name of the entry point
-** defaults to "sqlite3_extension_init".
-** ^The sqlite3_load_extension() interface returns
-** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
-** ^If an error occurs and pzErrMsg is not 0, then the
-** [sqlite3_load_extension()] interface shall attempt to
-** fill *pzErrMsg with error message text stored in memory
-** obtained from [sqlite3_malloc()]. The calling function
-** should free this memory by calling [sqlite3_free()].
-**
-** ^Extension loading must be enabled using
-** [sqlite3_enable_load_extension()] prior to calling this API,
-** otherwise an error will be returned.
-**
-** See also the [load_extension() SQL function].
-*/
-SQLITE_API int sqlite3_load_extension(
- sqlite3 *db, /* Load the extension into this database connection */
- const char *zFile, /* Name of the shared library containing extension */
- const char *zProc, /* Entry point. Derived from zFile if 0 */
- char **pzErrMsg /* Put error message here if not 0 */
-);
-
-/*
-** CAPI3REF: Enable Or Disable Extension Loading
-**
-** ^So as not to open security holes in older applications that are
-** unprepared to deal with extension loading, and as a means of disabling
-** extension loading while evaluating user-entered SQL, the following API
-** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
-**
-** ^Extension loading is off by default. See ticket #1863.
-** ^Call the sqlite3_enable_load_extension() routine with onoff==1
-** to turn extension loading on and call it with onoff==0 to turn
-** it back off again.
-*/
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
-
-/*
-** CAPI3REF: Automatically Load Statically Linked Extensions
-**
-** ^This interface causes the xEntryPoint() function to be invoked for
-** each new [database connection] that is created. The idea here is that
-** xEntryPoint() is the entry point for a statically linked SQLite extension
-** that is to be automatically loaded into all new database connections.
-**
-** ^(Even though the function prototype shows that xEntryPoint() takes
-** no arguments and returns void, SQLite invokes xEntryPoint() with three
-** arguments and expects and integer result as if the signature of the
-** entry point where as follows:
-**
-** <blockquote><pre>
-** &nbsp; int xEntryPoint(
-** &nbsp; sqlite3 *db,
-** &nbsp; const char **pzErrMsg,
-** &nbsp; const struct sqlite3_api_routines *pThunk
-** &nbsp; );
-** </pre></blockquote>)^
-**
-** If the xEntryPoint routine encounters an error, it should make *pzErrMsg
-** point to an appropriate error message (obtained from [sqlite3_mprintf()])
-** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg
-** is NULL before calling the xEntryPoint(). ^SQLite will invoke
-** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any
-** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()],
-** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail.
-**
-** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
-** on the list of automatic extensions is a harmless no-op. ^No entry point
-** will be called more than once for each database connection that is opened.
-**
-** See also: [sqlite3_reset_auto_extension()].
-*/
-SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
-
-/*
-** CAPI3REF: Reset Automatic Extension Loading
-**
-** ^This interface disables all automatic extensions previously
-** registered using [sqlite3_auto_extension()].
-*/
-SQLITE_API void sqlite3_reset_auto_extension(void);
-
-/*
-** The interface to the virtual-table mechanism is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-*/
-
-/*
-** Structures used by the virtual table interface
-*/
-typedef struct sqlite3_vtab sqlite3_vtab;
-typedef struct sqlite3_index_info sqlite3_index_info;
-typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
-typedef struct sqlite3_module sqlite3_module;
-
-/*
-** CAPI3REF: Virtual Table Object
-** KEYWORDS: sqlite3_module {virtual table module}
-**
-** This structure, sometimes called a "virtual table module",
-** defines the implementation of a [virtual tables].
-** This structure consists mostly of methods for the module.
-**
-** ^A virtual table module is created by filling in a persistent
-** instance of this structure and passing a pointer to that instance
-** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
-** ^The registration remains valid until it is replaced by a different
-** module or until the [database connection] closes. The content
-** of this structure must not change while it is registered with
-** any database connection.
-*/
-struct sqlite3_module {
- int iVersion;
- int (*xCreate)(sqlite3*, void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVTab, char**);
- int (*xConnect)(sqlite3*, void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVTab, char**);
- int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
- int (*xDisconnect)(sqlite3_vtab *pVTab);
- int (*xDestroy)(sqlite3_vtab *pVTab);
- int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
- int (*xClose)(sqlite3_vtab_cursor*);
- int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv);
- int (*xNext)(sqlite3_vtab_cursor*);
- int (*xEof)(sqlite3_vtab_cursor*);
- int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
- int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid);
- int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *);
- int (*xBegin)(sqlite3_vtab *pVTab);
- int (*xSync)(sqlite3_vtab *pVTab);
- int (*xCommit)(sqlite3_vtab *pVTab);
- int (*xRollback)(sqlite3_vtab *pVTab);
- int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
- void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
- void **ppArg);
- int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
- /* The methods above are in version 1 of the sqlite_module object. Those
- ** below are for version 2 and greater. */
- int (*xSavepoint)(sqlite3_vtab *pVTab, int);
- int (*xRelease)(sqlite3_vtab *pVTab, int);
- int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
-};
-
-/*
-** CAPI3REF: Virtual Table Indexing Information
-** KEYWORDS: sqlite3_index_info
-**
-** The sqlite3_index_info structure and its substructures is used as part
-** of the [virtual table] interface to
-** pass information into and receive the reply from the [xBestIndex]
-** method of a [virtual table module]. The fields under **Inputs** are the
-** inputs to xBestIndex and are read-only. xBestIndex inserts its
-** results into the **Outputs** fields.
-**
-** ^(The aConstraint[] array records WHERE clause constraints of the form:
-**
-** <blockquote>column OP expr</blockquote>
-**
-** where OP is =, &lt;, &lt;=, &gt;, or &gt;=.)^ ^(The particular operator is
-** stored in aConstraint[].op using one of the
-** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^
-** ^(The index of the column is stored in
-** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the
-** expr on the right-hand side can be evaluated (and thus the constraint
-** is usable) and false if it cannot.)^
-**
-** ^The optimizer automatically inverts terms of the form "expr OP column"
-** and makes other simplifications to the WHERE clause in an attempt to
-** get as many WHERE clause terms into the form shown above as possible.
-** ^The aConstraint[] array only reports WHERE clause terms that are
-** relevant to the particular virtual table being queried.
-**
-** ^Information about the ORDER BY clause is stored in aOrderBy[].
-** ^Each term of aOrderBy records a column of the ORDER BY clause.
-**
-** The [xBestIndex] method must fill aConstraintUsage[] with information
-** about what parameters to pass to xFilter. ^If argvIndex>0 then
-** the right-hand side of the corresponding aConstraint[] is evaluated
-** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit
-** is true, then the constraint is assumed to be fully handled by the
-** virtual table and is not checked again by SQLite.)^
-**
-** ^The idxNum and idxPtr values are recorded and passed into the
-** [xFilter] method.
-** ^[sqlite3_free()] is used to free idxPtr if and only if
-** needToFreeIdxPtr is true.
-**
-** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
-** the correct order to satisfy the ORDER BY clause so that no separate
-** sorting step is required.
-**
-** ^The estimatedCost value is an estimate of the cost of doing the
-** particular lookup. A full scan of a table with N entries should have
-** a cost of N. A binary search of a table of N entries should have a
-** cost of approximately log(N).
-*/
-struct sqlite3_index_info {
- /* Inputs */
- int nConstraint; /* Number of entries in aConstraint */
- struct sqlite3_index_constraint {
- int iColumn; /* Column on left-hand side of constraint */
- unsigned char op; /* Constraint operator */
- unsigned char usable; /* True if this constraint is usable */
- int iTermOffset; /* Used internally - xBestIndex should ignore */
- } *aConstraint; /* Table of WHERE clause constraints */
- int nOrderBy; /* Number of terms in the ORDER BY clause */
- struct sqlite3_index_orderby {
- int iColumn; /* Column number */
- unsigned char desc; /* True for DESC. False for ASC. */
- } *aOrderBy; /* The ORDER BY clause */
- /* Outputs */
- struct sqlite3_index_constraint_usage {
- int argvIndex; /* if >0, constraint is part of argv to xFilter */
- unsigned char omit; /* Do not code a test for this constraint */
- } *aConstraintUsage;
- int idxNum; /* Number used to identify the index */
- char *idxStr; /* String, possibly obtained from sqlite3_malloc */
- int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
- int orderByConsumed; /* True if output is already ordered */
- double estimatedCost; /* Estimated cost of using this index */
-};
-
-/*
-** CAPI3REF: Virtual Table Constraint Operator Codes
-**
-** These macros defined the allowed values for the
-** [sqlite3_index_info].aConstraint[].op field. Each value represents
-** an operator that is part of a constraint term in the wHERE clause of
-** a query that uses a [virtual table].
-*/
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
-#define SQLITE_INDEX_CONSTRAINT_GT 4
-#define SQLITE_INDEX_CONSTRAINT_LE 8
-#define SQLITE_INDEX_CONSTRAINT_LT 16
-#define SQLITE_INDEX_CONSTRAINT_GE 32
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
-
-/*
-** CAPI3REF: Register A Virtual Table Implementation
-**
-** ^These routines are used to register a new [virtual table module] name.
-** ^Module names must be registered before
-** creating a new [virtual table] using the module and before using a
-** preexisting [virtual table] for the module.
-**
-** ^The module name is registered on the [database connection] specified
-** by the first parameter. ^The name of the module is given by the
-** second parameter. ^The third parameter is a pointer to
-** the implementation of the [virtual table module]. ^The fourth
-** parameter is an arbitrary client data pointer that is passed through
-** into the [xCreate] and [xConnect] methods of the virtual table module
-** when a new virtual table is be being created or reinitialized.
-**
-** ^The sqlite3_create_module_v2() interface has a fifth parameter which
-** is a pointer to a destructor for the pClientData. ^SQLite will
-** invoke the destructor function (if it is not NULL) when SQLite
-** no longer needs the pClientData pointer. ^The destructor will also
-** be invoked if the call to sqlite3_create_module_v2() fails.
-** ^The sqlite3_create_module()
-** interface is equivalent to sqlite3_create_module_v2() with a NULL
-** destructor.
-*/
-SQLITE_API int sqlite3_create_module(
- sqlite3 *db, /* SQLite connection to register module with */
- const char *zName, /* Name of the module */
- const sqlite3_module *p, /* Methods for the module */
- void *pClientData /* Client data for xCreate/xConnect */
-);
-SQLITE_API int sqlite3_create_module_v2(
- sqlite3 *db, /* SQLite connection to register module with */
- const char *zName, /* Name of the module */
- const sqlite3_module *p, /* Methods for the module */
- void *pClientData, /* Client data for xCreate/xConnect */
- void(*xDestroy)(void*) /* Module destructor function */
-);
-
-/*
-** CAPI3REF: Virtual Table Instance Object
-** KEYWORDS: sqlite3_vtab
-**
-** Every [virtual table module] implementation uses a subclass
-** of this object to describe a particular instance
-** of the [virtual table]. Each subclass will
-** be tailored to the specific needs of the module implementation.
-** The purpose of this superclass is to define certain fields that are
-** common to all module implementations.
-**
-** ^Virtual tables methods can set an error message by assigning a
-** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should
-** take care that any prior string is freed by a call to [sqlite3_free()]
-** prior to assigning a new string to zErrMsg. ^After the error message
-** is delivered up to the client application, the string will be automatically
-** freed by sqlite3_free() and the zErrMsg field will be zeroed.
-*/
-struct sqlite3_vtab {
- const sqlite3_module *pModule; /* The module for this virtual table */
- int nRef; /* NO LONGER USED */
- char *zErrMsg; /* Error message from sqlite3_mprintf() */
- /* Virtual table implementations will typically add additional fields */
-};
-
-/*
-** CAPI3REF: Virtual Table Cursor Object
-** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
-**
-** Every [virtual table module] implementation uses a subclass of the
-** following structure to describe cursors that point into the
-** [virtual table] and are used
-** to loop through the virtual table. Cursors are created using the
-** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed
-** by the [sqlite3_module.xClose | xClose] method. Cursors are used
-** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
-** of the module. Each module implementation will define
-** the content of a cursor structure to suit its own needs.
-**
-** This superclass exists in order to define fields of the cursor that
-** are common to all implementations.
-*/
-struct sqlite3_vtab_cursor {
- sqlite3_vtab *pVtab; /* Virtual table of this cursor */
- /* Virtual table implementations will typically add additional fields */
-};
-
-/*
-** CAPI3REF: Declare The Schema Of A Virtual Table
-**
-** ^The [xCreate] and [xConnect] methods of a
-** [virtual table module] call this interface
-** to declare the format (the names and datatypes of the columns) of
-** the virtual tables they implement.
-*/
-SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
-
-/*
-** CAPI3REF: Overload A Function For A Virtual Table
-**
-** ^(Virtual tables can provide alternative implementations of functions
-** using the [xFindFunction] method of the [virtual table module].
-** But global versions of those functions
-** must exist in order to be overloaded.)^
-**
-** ^(This API makes sure a global version of a function with a particular
-** name and number of parameters exists. If no such function exists
-** before this API is called, a new function is created.)^ ^The implementation
-** of the new function always causes an exception to be thrown. So
-** the new function is not good for anything by itself. Its only
-** purpose is to be a placeholder function that can be overloaded
-** by a [virtual table].
-*/
-SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
-
-/*
-** The interface to the virtual-table mechanism defined above (back up
-** to a comment remarkably similar to this one) is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-*/
-
-/*
-** CAPI3REF: A Handle To An Open BLOB
-** KEYWORDS: {BLOB handle} {BLOB handles}
-**
-** An instance of this object represents an open BLOB on which
-** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
-** ^Objects of this type are created by [sqlite3_blob_open()]
-** and destroyed by [sqlite3_blob_close()].
-** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces
-** can be used to read or write small subsections of the BLOB.
-** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes.
-*/
-typedef struct sqlite3_blob sqlite3_blob;
-
-/*
-** CAPI3REF: Open A BLOB For Incremental I/O
-**
-** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
-** in row iRow, column zColumn, table zTable in database zDb;
-** in other words, the same BLOB that would be selected by:
-**
-** <pre>
-** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
-** </pre>)^
-**
-** ^If the flags parameter is non-zero, then the BLOB is opened for read
-** and write access. ^If it is zero, the BLOB is opened for read access.
-** ^It is not possible to open a column that is part of an index or primary
-** key for writing. ^If [foreign key constraints] are enabled, it is
-** not possible to open a column that is part of a [child key] for writing.
-**
-** ^Note that the database name is not the filename that contains
-** the database but rather the symbolic name of the database that
-** appears after the AS keyword when the database is connected using [ATTACH].
-** ^For the main database file, the database name is "main".
-** ^For TEMP tables, the database name is "temp".
-**
-** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
-** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
-** to be a null pointer.)^
-** ^This function sets the [database connection] error code and message
-** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
-** functions. ^Note that the *ppBlob variable is always initialized in a
-** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
-** regardless of the success or failure of this routine.
-**
-** ^(If the row that a BLOB handle points to is modified by an
-** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
-** then the BLOB handle is marked as "expired".
-** This is true if any column of the row is changed, even a column
-** other than the one the BLOB handle is open on.)^
-** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
-** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
-** ^(Changes written into a BLOB prior to the BLOB expiring are not
-** rolled back by the expiration of the BLOB. Such changes will eventually
-** commit if the transaction continues to completion.)^
-**
-** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
-** the opened blob. ^The size of a blob may not be changed by this
-** interface. Use the [UPDATE] SQL command to change the size of a
-** blob.
-**
-** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
-** and the built-in [zeroblob] SQL function can be used, if desired,
-** to create an empty, zero-filled blob in which to read or write using
-** this interface.
-**
-** To avoid a resource leak, every open [BLOB handle] should eventually
-** be released by a call to [sqlite3_blob_close()].
-*/
-SQLITE_API int sqlite3_blob_open(
- sqlite3*,
- const char *zDb,
- const char *zTable,
- const char *zColumn,
- sqlite3_int64 iRow,
- int flags,
- sqlite3_blob **ppBlob
-);
-
-/*
-** CAPI3REF: Move a BLOB Handle to a New Row
-**
-** ^This function is used to move an existing blob handle so that it points
-** to a different row of the same database table. ^The new row is identified
-** by the rowid value passed as the second argument. Only the row can be
-** changed. ^The database, table and column on which the blob handle is open
-** remain the same. Moving an existing blob handle to a new row can be
-** faster than closing the existing handle and opening a new one.
-**
-** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
-** it must exist and there must be either a blob or text value stored in
-** the nominated column.)^ ^If the new row is not present in the table, or if
-** it does not contain a blob or text value, or if another error occurs, an
-** SQLite error code is returned and the blob handle is considered aborted.
-** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or
-** [sqlite3_blob_reopen()] on an aborted blob handle immediately return
-** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
-** always returns zero.
-**
-** ^This function sets the database handle error code and message.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
-
-/*
-** CAPI3REF: Close A BLOB Handle
-**
-** ^Closes an open [BLOB handle].
-**
-** ^Closing a BLOB shall cause the current transaction to commit
-** if there are no other BLOBs, no pending prepared statements, and the
-** database connection is in [autocommit mode].
-** ^If any writes were made to the BLOB, they might be held in cache
-** until the close operation if they will fit.
-**
-** ^(Closing the BLOB often forces the changes
-** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed. Any errors that occur during
-** closing are reported as a non-zero return value.)^
-**
-** ^(The BLOB is closed unconditionally. Even if this routine returns
-** an error code, the BLOB is still closed.)^
-**
-** ^Calling this routine with a null pointer (such as would be returned
-** by a failed call to [sqlite3_blob_open()]) is a harmless no-op.
-*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
-
-/*
-** CAPI3REF: Return The Size Of An Open BLOB
-**
-** ^Returns the size in bytes of the BLOB accessible via the
-** successfully opened [BLOB handle] in its only argument. ^The
-** incremental blob I/O routines can only read or overwriting existing
-** blob content; they cannot change the size of a blob.
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-*/
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
-
-/*
-** CAPI3REF: Read Data From A BLOB Incrementally
-**
-** ^(This function is used to read data from an open [BLOB handle] into a
-** caller-supplied buffer. N bytes of data are copied into buffer Z
-** from the open BLOB, starting at offset iOffset.)^
-**
-** ^If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is
-** less than zero, [SQLITE_ERROR] is returned and no data is read.
-** ^The size of the blob (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
-**
-** ^An attempt to read from an expired [BLOB handle] fails with an
-** error code of [SQLITE_ABORT].
-**
-** ^(On success, sqlite3_blob_read() returns SQLITE_OK.
-** Otherwise, an [error code] or an [extended error code] is returned.)^
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** See also: [sqlite3_blob_write()].
-*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
-
-/*
-** CAPI3REF: Write Data Into A BLOB Incrementally
-**
-** ^This function is used to write data into an open [BLOB handle] from a
-** caller-supplied buffer. ^N bytes of data are copied from the buffer Z
-** into the open BLOB, starting at offset iOffset.
-**
-** ^If the [BLOB handle] passed as the first argument was not opened for
-** writing (the flags parameter to [sqlite3_blob_open()] was zero),
-** this function returns [SQLITE_READONLY].
-**
-** ^This function may only modify the contents of the BLOB; it is
-** not possible to increase the size of a BLOB using this API.
-** ^If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is written. ^If N is
-** less than zero [SQLITE_ERROR] is returned and no data is written.
-** The size of the BLOB (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
-**
-** ^An attempt to write to an expired [BLOB handle] fails with an
-** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred
-** before the [BLOB handle] expired are not rolled back by the
-** expiration of the handle, though of course those changes might
-** have been overwritten by the statement that expired the BLOB handle
-** or by other independent statements.
-**
-** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
-** Otherwise, an [error code] or an [extended error code] is returned.)^
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** See also: [sqlite3_blob_read()].
-*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
-
-/*
-** CAPI3REF: Virtual File System Objects
-**
-** A virtual filesystem (VFS) is an [sqlite3_vfs] object
-** that SQLite uses to interact
-** with the underlying operating system. Most SQLite builds come with a
-** single default VFS that is appropriate for the host computer.
-** New VFSes can be registered and existing VFSes can be unregistered.
-** The following interfaces are provided.
-**
-** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name.
-** ^Names are case sensitive.
-** ^Names are zero-terminated UTF-8 strings.
-** ^If there is no match, a NULL pointer is returned.
-** ^If zVfsName is NULL then the default VFS is returned.
-**
-** ^New VFSes are registered with sqlite3_vfs_register().
-** ^Each new VFS becomes the default VFS if the makeDflt flag is set.
-** ^The same VFS can be registered multiple times without injury.
-** ^To make an existing VFS into the default VFS, register it again
-** with the makeDflt flag set. If two different VFSes with the
-** same name are registered, the behavior is undefined. If a
-** VFS is registered with a name that is NULL or an empty string,
-** then the behavior is undefined.
-**
-** ^Unregister a VFS with the sqlite3_vfs_unregister() interface.
-** ^(If the default VFS is unregistered, another VFS is chosen as
-** the default. The choice for the new VFS is arbitrary.)^
-*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
-
-/*
-** CAPI3REF: Mutexes
-**
-** The SQLite core uses these routines for thread
-** synchronization. Though they are intended for internal
-** use by SQLite, code that links against SQLite is
-** permitted to use any of these routines.
-**
-** The SQLite source code contains multiple implementations
-** of these mutex routines. An appropriate implementation
-** is selected automatically at compile-time. ^(The following
-** implementations are available in the SQLite core:
-**
-** <ul>
-** <li> SQLITE_MUTEX_PTHREADS
-** <li> SQLITE_MUTEX_W32
-** <li> SQLITE_MUTEX_NOOP
-** </ul>)^
-**
-** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
-** that does no real locking and is appropriate for use in
-** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS and
-** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
-** and Windows.
-**
-** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
-** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
-** implementation is included with the library. In this case the
-** application must supply a custom mutex implementation using the
-** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
-** before calling sqlite3_initialize() or any other public sqlite3_
-** function that calls sqlite3_initialize().)^
-**
-** ^The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. ^If it returns NULL
-** that means that a mutex could not be allocated. ^SQLite
-** will unwind its stack and return an error. ^(The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
-**
-** <ul>
-** <li> SQLITE_MUTEX_FAST
-** <li> SQLITE_MUTEX_RECURSIVE
-** <li> SQLITE_MUTEX_STATIC_MASTER
-** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
-** <li> SQLITE_MUTEX_STATIC_PRNG
-** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_LRU2
-** </ul>)^
-**
-** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
-** cause sqlite3_mutex_alloc() to create
-** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
-** The mutex implementation does not need to make a distinction
-** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. ^SQLite will only request a recursive mutex in
-** cases where it really needs one. ^If a faster non-recursive mutex
-** implementation is available on the host platform, the mutex subsystem
-** might return such a mutex in response to SQLITE_MUTEX_FAST.
-**
-** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
-** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
-** a pointer to a static preexisting mutex. ^Six static mutexes are
-** used by the current version of SQLite. Future versions of SQLite
-** may add additional static mutexes. Static mutexes are for internal
-** use by SQLite only. Applications that use SQLite mutexes should
-** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-** SQLITE_MUTEX_RECURSIVE.
-**
-** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. ^But for the static
-** mutex types, the same mutex is returned on every call that has
-** the same type number.
-**
-** ^The sqlite3_mutex_free() routine deallocates a previously
-** allocated dynamic mutex. ^SQLite is careful to deallocate every
-** dynamic mutex that it allocates. The dynamic mutexes must not be in
-** use when they are deallocated. Attempting to deallocate a static
-** mutex results in undefined behavior. ^SQLite never deallocates
-** a static mutex.
-**
-** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. ^If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
-** upon successful entry. ^(Mutexes created using
-** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
-** In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter.)^ ^(If the same thread tries to enter any other
-** kind of mutex more than once, the behavior is undefined.
-** SQLite will never exhibit
-** such behavior in its own use of mutexes.)^
-**
-** ^(Some systems (for example, Windows 95) do not support the operation
-** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
-** will always return SQLITE_BUSY. The SQLite core only ever uses
-** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^
-**
-** ^The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. ^(The behavior
-** is undefined if the mutex is not currently entered by the
-** calling thread or is not currently allocated. SQLite will
-** never do either.)^
-**
-** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
-** sqlite3_mutex_leave() is a NULL pointer, then all three routines
-** behave as no-ops.
-**
-** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
-*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
-
-/*
-** CAPI3REF: Mutex Methods Object
-**
-** An instance of this structure defines the low-level routines
-** used to allocate and use mutexes.
-**
-** Usually, the default mutex implementations provided by SQLite are
-** sufficient, however the user has the option of substituting a custom
-** implementation for specialized deployments or systems for which SQLite
-** does not provide a suitable implementation. In this case, the user
-** creates and populates an instance of this structure to pass
-** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
-** Additionally, an instance of this structure can be used as an
-** output variable when querying the system for the current mutex
-** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
-**
-** ^The xMutexInit method defined by this structure is invoked as
-** part of system initialization by the sqlite3_initialize() function.
-** ^The xMutexInit routine is called by SQLite exactly once for each
-** effective call to [sqlite3_initialize()].
-**
-** ^The xMutexEnd method defined by this structure is invoked as
-** part of system shutdown by the sqlite3_shutdown() function. The
-** implementation of this method is expected to release all outstanding
-** resources obtained by the mutex methods implementation, especially
-** those obtained by the xMutexInit method. ^The xMutexEnd()
-** interface is invoked exactly once for each call to [sqlite3_shutdown()].
-**
-** ^(The remaining seven methods defined by this structure (xMutexAlloc,
-** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and
-** xMutexNotheld) implement the following interfaces (respectively):
-**
-** <ul>
-** <li> [sqlite3_mutex_alloc()] </li>
-** <li> [sqlite3_mutex_free()] </li>
-** <li> [sqlite3_mutex_enter()] </li>
-** <li> [sqlite3_mutex_try()] </li>
-** <li> [sqlite3_mutex_leave()] </li>
-** <li> [sqlite3_mutex_held()] </li>
-** <li> [sqlite3_mutex_notheld()] </li>
-** </ul>)^
-**
-** The only difference is that the public sqlite3_XXX functions enumerated
-** above silently ignore any invocations that pass a NULL pointer instead
-** of a valid mutex handle. The implementations of the methods defined
-** by this structure are not required to handle this case, the results
-** of passing a NULL pointer instead of a valid mutex handle are undefined
-** (i.e. it is acceptable to provide an implementation that segfaults if
-** it is passed a NULL pointer).
-**
-** The xMutexInit() method must be threadsafe. ^It must be harmless to
-** invoke xMutexInit() multiple times within the same process and without
-** intervening calls to xMutexEnd(). Second and subsequent calls to
-** xMutexInit() must be no-ops.
-**
-** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
-** and its associates). ^Similarly, xMutexAlloc() must not use SQLite memory
-** allocation for a static mutex. ^However xMutexAlloc() may use SQLite
-** memory allocation for a fast or recursive mutex.
-**
-** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
-** called, but only if the prior call to xMutexInit returned SQLITE_OK.
-** If xMutexInit fails in any way, it is expected to clean up after itself
-** prior to returning.
-*/
-typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
-struct sqlite3_mutex_methods {
- int (*xMutexInit)(void);
- int (*xMutexEnd)(void);
- sqlite3_mutex *(*xMutexAlloc)(int);
- void (*xMutexFree)(sqlite3_mutex *);
- void (*xMutexEnter)(sqlite3_mutex *);
- int (*xMutexTry)(sqlite3_mutex *);
- void (*xMutexLeave)(sqlite3_mutex *);
- int (*xMutexHeld)(sqlite3_mutex *);
- int (*xMutexNotheld)(sqlite3_mutex *);
-};
-
-/*
-** CAPI3REF: Mutex Verification Routines
-**
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements. ^The SQLite core
-** never uses these routines except inside an assert() and applications
-** are advised to follow the lead of the core. ^The SQLite core only
-** provides implementations for these routines when it is compiled
-** with the SQLITE_DEBUG flag. ^External mutex implementations
-** are only required to provide these routines if SQLITE_DEBUG is
-** defined and if NDEBUG is not defined.
-**
-** ^These routines should return true if the mutex in their argument
-** is held or not held, respectively, by the calling thread.
-**
-** ^The implementation is not required to provide versions of these
-** routines that actually work. If the implementation does not provide working
-** versions of these routines, it should at least provide stubs that always
-** return true so that one does not get spurious assertion failures.
-**
-** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
-** the routine should return 1. This seems counter-intuitive since
-** clearly the mutex cannot be held if it does not exist. But
-** the reason the mutex does not exist is because the build is not
-** using mutexes. And we do not want the assert() containing the
-** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do. ^The sqlite3_mutex_notheld()
-** interface should also return 1 when given a NULL pointer.
-*/
-#ifndef NDEBUG
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
-#endif
-
-/*
-** CAPI3REF: Mutex Types
-**
-** The [sqlite3_mutex_alloc()] interface takes a single argument
-** which is one of these integer constants.
-**
-** The set of static mutexes may change from one SQLite release to the
-** next. Applications that override the built-in mutex logic must be
-** prepared to accommodate additional static mutexes.
-*/
-#define SQLITE_MUTEX_FAST 0
-#define SQLITE_MUTEX_RECURSIVE 1
-#define SQLITE_MUTEX_STATIC_MASTER 2
-#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
-#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
-#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
-#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */
-#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
-#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
-#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
-
-/*
-** CAPI3REF: Retrieve the mutex for a database connection
-**
-** ^This interface returns a pointer the [sqlite3_mutex] object that
-** serializes access to the [database connection] given in the argument
-** when the [threading mode] is Serialized.
-** ^If the [threading mode] is Single-thread or Multi-thread then this
-** routine returns a NULL pointer.
-*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
-
-/*
-** CAPI3REF: Low-Level Control Of Database Files
-**
-** ^The [sqlite3_file_control()] interface makes a direct call to the
-** xFileControl method for the [sqlite3_io_methods] object associated
-** with a particular database identified by the second argument. ^The
-** name of the database is "main" for the main database or "temp" for the
-** TEMP database, or the name that appears after the AS keyword for
-** databases that are added using the [ATTACH] SQL command.
-** ^A NULL pointer can be used in place of "main" to refer to the
-** main database file.
-** ^The third and fourth parameters to this routine
-** are passed directly through to the second and third parameters of
-** the xFileControl method. ^The return value of the xFileControl
-** method becomes the return value of this routine.
-**
-** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
-** a pointer to the underlying [sqlite3_file] object to be written into
-** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER
-** case is a short-circuit path which does not actually invoke the
-** underlying sqlite3_io_methods.xFileControl method.
-**
-** ^If the second parameter (zDbName) does not match the name of any
-** open database file, then SQLITE_ERROR is returned. ^This error
-** code is not remembered and will not be recalled by [sqlite3_errcode()]
-** or [sqlite3_errmsg()]. The underlying xFileControl method might
-** also return SQLITE_ERROR. There is no way to distinguish between
-** an incorrect zDbName and an SQLITE_ERROR return from the underlying
-** xFileControl method.
-**
-** See also: [SQLITE_FCNTL_LOCKSTATE]
-*/
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
-
-/*
-** CAPI3REF: Testing Interface
-**
-** ^The sqlite3_test_control() interface is used to read out internal
-** state of SQLite and to inject faults into SQLite for testing
-** purposes. ^The first parameter is an operation code that determines
-** the number, meaning, and operation of all subsequent parameters.
-**
-** This interface is not for use by applications. It exists solely
-** for verifying the correct operation of the SQLite library. Depending
-** on how the SQLite library is compiled, this interface might not exist.
-**
-** The details of the operation codes, their meanings, the parameters
-** they take, and what they do are all subject to change without notice.
-** Unlike most of the SQLite API, this function is not guaranteed to
-** operate consistently from one release to the next.
-*/
-SQLITE_API int sqlite3_test_control(int op, ...);
-
-/*
-** CAPI3REF: Testing Interface Operation Codes
-**
-** These constants are the valid operation code parameters used
-** as the first argument to [sqlite3_test_control()].
-**
-** These parameters and their meanings are subject to change
-** without notice. These values are for testing purposes only.
-** Applications should not use any of these parameters or the
-** [sqlite3_test_control()] interface.
-*/
-#define SQLITE_TESTCTRL_FIRST 5
-#define SQLITE_TESTCTRL_PRNG_SAVE 5
-#define SQLITE_TESTCTRL_PRNG_RESTORE 6
-#define SQLITE_TESTCTRL_PRNG_RESET 7
-#define SQLITE_TESTCTRL_BITVEC_TEST 8
-#define SQLITE_TESTCTRL_FAULT_INSTALL 9
-#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
-#define SQLITE_TESTCTRL_PENDING_BYTE 11
-#define SQLITE_TESTCTRL_ASSERT 12
-#define SQLITE_TESTCTRL_ALWAYS 13
-#define SQLITE_TESTCTRL_RESERVE 14
-#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
-#define SQLITE_TESTCTRL_ISKEYWORD 16
-#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
-#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
-#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
-#define SQLITE_TESTCTRL_LAST 19
-
-/*
-** CAPI3REF: SQLite Runtime Status
-**
-** ^This interface is used to retrieve runtime status information
-** about the performance of SQLite, and optionally to reset various
-** highwater marks. ^The first argument is an integer code for
-** the specific parameter to measure. ^(Recognized integer codes
-** are of the form [status parameters | SQLITE_STATUS_...].)^
-** ^The current value of the parameter is returned into *pCurrent.
-** ^The highest recorded value is returned in *pHighwater. ^If the
-** resetFlag is true, then the highest record value is reset after
-** *pHighwater is written. ^(Some parameters do not record the highest
-** value. For those parameters
-** nothing is written into *pHighwater and the resetFlag is ignored.)^
-** ^(Other parameters record only the highwater mark and not the current
-** value. For these latter parameters nothing is written into *pCurrent.)^
-**
-** ^The sqlite3_status() routine returns SQLITE_OK on success and a
-** non-zero [error code] on failure.
-**
-** This routine is threadsafe but is not atomic. This routine can be
-** called while other threads are running the same or different SQLite
-** interfaces. However the values returned in *pCurrent and
-** *pHighwater reflect the status of SQLite at different points in time
-** and it is possible that another thread might change the parameter
-** in between the times when *pCurrent and *pHighwater are written.
-**
-** See also: [sqlite3_db_status()]
-*/
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
-
-
-/*
-** CAPI3REF: Status Parameters
-** KEYWORDS: {status parameters}
-**
-** These integer constants designate various run-time status parameters
-** that can be returned by [sqlite3_status()].
-**
-** <dl>
-** [[SQLITE_STATUS_MEMORY_USED]] ^(<dt>SQLITE_STATUS_MEMORY_USED</dt>
-** <dd>This parameter is the current amount of memory checked out
-** using [sqlite3_malloc()], either directly or indirectly. The
-** figure includes calls made to [sqlite3_malloc()] by the application
-** and internal memory usage by the SQLite library. Scratch memory
-** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
-** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
-** this parameter. The amount returned is the sum of the allocation
-** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
-**
-** [[SQLITE_STATUS_MALLOC_SIZE]] ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
-** internal equivalents). Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>)^
-**
-** [[SQLITE_STATUS_MALLOC_COUNT]] ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt>
-** <dd>This parameter records the number of separate memory allocations
-** currently checked out.</dd>)^
-**
-** [[SQLITE_STATUS_PAGECACHE_USED]] ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt>
-** <dd>This parameter returns the number of pages used out of the
-** [pagecache memory allocator] that was configured using
-** [SQLITE_CONFIG_PAGECACHE]. The
-** value returned is in pages, not in bytes.</dd>)^
-**
-** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]]
-** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of page cache
-** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The
-** returned value includes allocations that overflowed because they
-** where too large (they were larger than the "sz" parameter to
-** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
-** no space was left in the page cache.</dd>)^
-**
-** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [pagecache memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>)^
-**
-** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
-** <dd>This parameter returns the number of allocations used out of the
-** [scratch memory allocator] configured using
-** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
-** in bytes. Since a single thread may only have one scratch allocation
-** outstanding at time, this parameter also reports the number of threads
-** using scratch memory at the same time.</dd>)^
-**
-** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of scratch memory
-** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The values
-** returned include overflows because the requested allocation was too
-** larger (that is, because the requested allocation was larger than the
-** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
-** slots were available.
-** </dd>)^
-**
-** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [scratch memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>)^
-**
-** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
-** <dd>This parameter records the deepest parser stack. It is only
-** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
-** </dl>
-**
-** New status parameters may be added from time to time.
-*/
-#define SQLITE_STATUS_MEMORY_USED 0
-#define SQLITE_STATUS_PAGECACHE_USED 1
-#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
-#define SQLITE_STATUS_SCRATCH_USED 3
-#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
-#define SQLITE_STATUS_MALLOC_SIZE 5
-#define SQLITE_STATUS_PARSER_STACK 6
-#define SQLITE_STATUS_PAGECACHE_SIZE 7
-#define SQLITE_STATUS_SCRATCH_SIZE 8
-#define SQLITE_STATUS_MALLOC_COUNT 9
-
-/*
-** CAPI3REF: Database Connection Status
-**
-** ^This interface is used to retrieve runtime status information
-** about a single [database connection]. ^The first argument is the
-** database connection object to be interrogated. ^The second argument
-** is an integer constant, taken from the set of
-** [SQLITE_DBSTATUS options], that
-** determines the parameter to interrogate. The set of
-** [SQLITE_DBSTATUS options] is likely
-** to grow in future releases of SQLite.
-**
-** ^The current value of the requested parameter is written into *pCur
-** and the highest instantaneous value is written into *pHiwtr. ^If
-** the resetFlg is true, then the highest instantaneous value is
-** reset back down to the current value.
-**
-** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
-** non-zero [error code] on failure.
-**
-** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
-*/
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
-
-/*
-** CAPI3REF: Status Parameters for database connections
-** KEYWORDS: {SQLITE_DBSTATUS options}
-**
-** These constants are the available integer "verbs" that can be passed as
-** the second argument to the [sqlite3_db_status()] interface.
-**
-** New verbs may be added in future releases of SQLite. Existing verbs
-** might be discontinued. Applications should check the return code from
-** [sqlite3_db_status()] to make sure that the call worked.
-** The [sqlite3_db_status()] interface will return a non-zero error code
-** if a discontinued or unsupported verb is invoked.
-**
-** <dl>
-** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
-** <dd>This parameter returns the number of lookaside memory slots currently
-** checked out.</dd>)^
-**
-** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
-** <dd>This parameter returns the number malloc attempts that were
-** satisfied using lookaside memory. Only the high-water value is meaningful;
-** the current value is always zero.)^
-**
-** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]]
-** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
-** <dd>This parameter returns the number malloc attempts that might have
-** been satisfied using lookaside memory but failed due to the amount of
-** memory requested being larger than the lookaside slot size.
-** Only the high-water value is meaningful;
-** the current value is always zero.)^
-**
-** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]]
-** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt>
-** <dd>This parameter returns the number malloc attempts that might have
-** been satisfied using lookaside memory but failed due to all lookaside
-** memory already being in use.
-** Only the high-water value is meaningful;
-** the current value is always zero.)^
-**
-** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
-** memory used by all pager caches associated with the database connection.)^
-** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
-**
-** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
-** memory used to store the schema for all databases associated
-** with the connection - main, temp, and any [ATTACH]-ed databases.)^
-** ^The full amount of memory used by the schemas is reported, even if the
-** schema memory is shared with other database connections due to
-** [shared cache mode] being enabled.
-** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
-**
-** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
-** and lookaside memory used by all prepared statements associated with
-** the database connection.)^
-** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
-** </dd>
-**
-** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
-** <dd>This parameter returns the number of pager cache hits that have
-** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT
-** is always 0.
-** </dd>
-**
-** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
-** <dd>This parameter returns the number of pager cache misses that have
-** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS
-** is always 0.
-** </dd>
-**
-** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt>
-** <dd>This parameter returns the number of dirty cache entries that have
-** been written to disk. Specifically, the number of pages written to the
-** wal file in wal mode databases, or the number of pages written to the
-** database file in rollback mode databases. Any pages written as part of
-** transaction rollback or database recovery operations are not included.
-** If an IO or other error occurs while writing a page to disk, the effect
-** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
-** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
-** </dd>
-** </dl>
-*/
-#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
-#define SQLITE_DBSTATUS_CACHE_USED 1
-#define SQLITE_DBSTATUS_SCHEMA_USED 2
-#define SQLITE_DBSTATUS_STMT_USED 3
-#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
-#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
-#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
-#define SQLITE_DBSTATUS_CACHE_HIT 7
-#define SQLITE_DBSTATUS_CACHE_MISS 8
-#define SQLITE_DBSTATUS_CACHE_WRITE 9
-#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
-
-
-/*
-** CAPI3REF: Prepared Statement Status
-**
-** ^(Each prepared statement maintains various
-** [SQLITE_STMTSTATUS counters] that measure the number
-** of times it has performed specific operations.)^ These counters can
-** be used to monitor the performance characteristics of the prepared
-** statements. For example, if the number of table steps greatly exceeds
-** the number of table searches or result rows, that would tend to indicate
-** that the prepared statement is using a full table scan rather than
-** an index.
-**
-** ^(This interface is used to retrieve and reset counter values from
-** a [prepared statement]. The first argument is the prepared statement
-** object to be interrogated. The second argument
-** is an integer code for a specific [SQLITE_STMTSTATUS counter]
-** to be interrogated.)^
-** ^The current value of the requested counter is returned.
-** ^If the resetFlg is true, then the counter is reset to zero after this
-** interface call returns.
-**
-** See also: [sqlite3_status()] and [sqlite3_db_status()].
-*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
-
-/*
-** CAPI3REF: Status Parameters for prepared statements
-** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters}
-**
-** These preprocessor macros define integer codes that name counter
-** values associated with the [sqlite3_stmt_status()] interface.
-** The meanings of the various counters are as follows:
-**
-** <dl>
-** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
-** <dd>^This is the number of times that SQLite has stepped forward in
-** a table as part of a full table scan. Large numbers for this counter
-** may indicate opportunities for performance improvement through
-** careful use of indices.</dd>
-**
-** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt>
-** <dd>^This is the number of sort operations that have occurred.
-** A non-zero value in this counter may indicate an opportunity to
-** improvement performance through careful use of indices.</dd>
-**
-** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt>
-** <dd>^This is the number of rows inserted into transient indices that
-** were created automatically in order to help joins run faster.
-** A non-zero value in this counter may indicate an opportunity to
-** improvement performance by adding permanent indices that do not
-** need to be reinitialized each time the statement is run.</dd>
-** </dl>
-*/
-#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
-#define SQLITE_STMTSTATUS_SORT 2
-#define SQLITE_STMTSTATUS_AUTOINDEX 3
-
-/*
-** CAPI3REF: Custom Page Cache Object
-**
-** The sqlite3_pcache type is opaque. It is implemented by
-** the pluggable module. The SQLite core has no knowledge of
-** its size or internal structure and never deals with the
-** sqlite3_pcache object except by holding and passing pointers
-** to the object.
-**
-** See [sqlite3_pcache_methods2] for additional information.
-*/
-typedef struct sqlite3_pcache sqlite3_pcache;
-
-/*
-** CAPI3REF: Custom Page Cache Object
-**
-** The sqlite3_pcache_page object represents a single page in the
-** page cache. The page cache will allocate instances of this
-** object. Various methods of the page cache use pointers to instances
-** of this object as parameters or as their return value.
-**
-** See [sqlite3_pcache_methods2] for additional information.
-*/
-typedef struct sqlite3_pcache_page sqlite3_pcache_page;
-struct sqlite3_pcache_page {
- void *pBuf; /* The content of the page */
- void *pExtra; /* Extra information associated with the page */
-};
-
-/*
-** CAPI3REF: Application Defined Page Cache.
-** KEYWORDS: {page cache}
-**
-** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can
-** register an alternative page cache implementation by passing in an
-** instance of the sqlite3_pcache_methods2 structure.)^
-** In many applications, most of the heap memory allocated by
-** SQLite is used for the page cache.
-** By implementing a
-** custom page cache using this API, an application can better control
-** the amount of memory consumed by SQLite, the way in which
-** that memory is allocated and released, and the policies used to
-** determine exactly which parts of a database file are cached and for
-** how long.
-**
-** The alternative page cache mechanism is an
-** extreme measure that is only needed by the most demanding applications.
-** The built-in page cache is recommended for most uses.
-**
-** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an
-** internal buffer by SQLite within the call to [sqlite3_config]. Hence
-** the application may discard the parameter after the call to
-** [sqlite3_config()] returns.)^
-**
-** [[the xInit() page cache method]]
-** ^(The xInit() method is called once for each effective
-** call to [sqlite3_initialize()])^
-** (usually only once during the lifetime of the process). ^(The xInit()
-** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^
-** The intent of the xInit() method is to set up global data structures
-** required by the custom page cache implementation.
-** ^(If the xInit() method is NULL, then the
-** built-in default page cache is used instead of the application defined
-** page cache.)^
-**
-** [[the xShutdown() page cache method]]
-** ^The xShutdown() method is called by [sqlite3_shutdown()].
-** It can be used to clean up
-** any outstanding resources before process shutdown, if required.
-** ^The xShutdown() method may be NULL.
-**
-** ^SQLite automatically serializes calls to the xInit method,
-** so the xInit method need not be threadsafe. ^The
-** xShutdown method is only called from [sqlite3_shutdown()] so it does
-** not need to be threadsafe either. All other methods must be threadsafe
-** in multithreaded applications.
-**
-** ^SQLite will never invoke xInit() more than once without an intervening
-** call to xShutdown().
-**
-** [[the xCreate() page cache methods]]
-** ^SQLite invokes the xCreate() method to construct a new cache instance.
-** SQLite will typically create one cache instance for each open database file,
-** though this is not guaranteed. ^The
-** first parameter, szPage, is the size in bytes of the pages that must
-** be allocated by the cache. ^szPage will always a power of two. ^The
-** second parameter szExtra is a number of bytes of extra storage
-** associated with each page cache entry. ^The szExtra parameter will
-** a number less than 250. SQLite will use the
-** extra szExtra bytes on each page to store metadata about the underlying
-** database page on disk. The value passed into szExtra depends
-** on the SQLite version, the target platform, and how SQLite was compiled.
-** ^The third argument to xCreate(), bPurgeable, is true if the cache being
-** created will be used to cache database pages of a file stored on disk, or
-** false if it is used for an in-memory database. The cache implementation
-** does not have to do anything special based with the value of bPurgeable;
-** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will
-** never invoke xUnpin() except to deliberately delete a page.
-** ^In other words, calls to xUnpin() on a cache with bPurgeable set to
-** false will always have the "discard" flag set to true.
-** ^Hence, a cache created with bPurgeable false will
-** never contain any unpinned pages.
-**
-** [[the xCachesize() page cache method]]
-** ^(The xCachesize() method may be called at any time by SQLite to set the
-** suggested maximum cache-size (number of pages stored by) the cache
-** instance passed as the first argument. This is the value configured using
-** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable
-** parameter, the implementation is not required to do anything with this
-** value; it is advisory only.
-**
-** [[the xPagecount() page cache methods]]
-** The xPagecount() method must return the number of pages currently
-** stored in the cache, both pinned and unpinned.
-**
-** [[the xFetch() page cache methods]]
-** The xFetch() method locates a page in the cache and returns a pointer to
-** an sqlite3_pcache_page object associated with that page, or a NULL pointer.
-** The pBuf element of the returned sqlite3_pcache_page object will be a
-** pointer to a buffer of szPage bytes used to store the content of a
-** single database page. The pExtra element of sqlite3_pcache_page will be
-** a pointer to the szExtra bytes of extra storage that SQLite has requested
-** for each entry in the page cache.
-**
-** The page to be fetched is determined by the key. ^The minimum key value
-** is 1. After it has been retrieved using xFetch, the page is considered
-** to be "pinned".
-**
-** If the requested page is already in the page cache, then the page cache
-** implementation must return a pointer to the page buffer with its content
-** intact. If the requested page is not already in the cache, then the
-** cache implementation should use the value of the createFlag
-** parameter to help it determined what action to take:
-**
-** <table border=1 width=85% align=center>
-** <tr><th> createFlag <th> Behaviour when page is not already in cache
-** <tr><td> 0 <td> Do not allocate a new page. Return NULL.
-** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
-** Otherwise return NULL.
-** <tr><td> 2 <td> Make every effort to allocate a new page. Only return
-** NULL if allocating a new page is effectively impossible.
-** </table>
-**
-** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite
-** will only use a createFlag of 2 after a prior call with a createFlag of 1
-** failed.)^ In between the to xFetch() calls, SQLite may
-** attempt to unpin one or more cache pages by spilling the content of
-** pinned pages to disk and synching the operating system disk cache.
-**
-** [[the xUnpin() page cache method]]
-** ^xUnpin() is called by SQLite with a pointer to a currently pinned page
-** as its second argument. If the third parameter, discard, is non-zero,
-** then the page must be evicted from the cache.
-** ^If the discard parameter is
-** zero, then the page may be discarded or retained at the discretion of
-** page cache implementation. ^The page cache implementation
-** may choose to evict unpinned pages at any time.
-**
-** The cache must not perform any reference counting. A single
-** call to xUnpin() unpins the page regardless of the number of prior calls
-** to xFetch().
-**
-** [[the xRekey() page cache methods]]
-** The xRekey() method is used to change the key value associated with the
-** page passed as the second argument. If the cache
-** previously contains an entry associated with newKey, it must be
-** discarded. ^Any prior cache entry associated with newKey is guaranteed not
-** to be pinned.
-**
-** When SQLite calls the xTruncate() method, the cache must discard all
-** existing cache entries with page numbers (keys) greater than or equal
-** to the value of the iLimit parameter passed to xTruncate(). If any
-** of these pages are pinned, they are implicitly unpinned, meaning that
-** they can be safely discarded.
-**
-** [[the xDestroy() page cache method]]
-** ^The xDestroy() method is used to delete a cache allocated by xCreate().
-** All resources associated with the specified cache should be freed. ^After
-** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
-** handle invalid, and will not use it with any other sqlite3_pcache_methods2
-** functions.
-**
-** [[the xShrink() page cache method]]
-** ^SQLite invokes the xShrink() method when it wants the page cache to
-** free up as much of heap memory as possible. The page cache implementation
-** is not obligated to free any memory, but well-behaved implementations should
-** do their best.
-*/
-typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
-struct sqlite3_pcache_methods2 {
- int iVersion;
- void *pArg;
- int (*xInit)(void*);
- void (*xShutdown)(void*);
- sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
- void (*xCachesize)(sqlite3_pcache*, int nCachesize);
- int (*xPagecount)(sqlite3_pcache*);
- sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
- void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
- void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*,
- unsigned oldKey, unsigned newKey);
- void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
- void (*xDestroy)(sqlite3_pcache*);
- void (*xShrink)(sqlite3_pcache*);
-};
-
-/*
-** This is the obsolete pcache_methods object that has now been replaced
-** by sqlite3_pcache_methods2. This object is not used by SQLite. It is
-** retained in the header file for backwards compatibility only.
-*/
-typedef struct sqlite3_pcache_methods sqlite3_pcache_methods;
-struct sqlite3_pcache_methods {
- void *pArg;
- int (*xInit)(void*);
- void (*xShutdown)(void*);
- sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable);
- void (*xCachesize)(sqlite3_pcache*, int nCachesize);
- int (*xPagecount)(sqlite3_pcache*);
- void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
- void (*xUnpin)(sqlite3_pcache*, void*, int discard);
- void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
- void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
- void (*xDestroy)(sqlite3_pcache*);
-};
-
-
-/*
-** CAPI3REF: Online Backup Object
-**
-** The sqlite3_backup object records state information about an ongoing
-** online backup operation. ^The sqlite3_backup object is created by
-** a call to [sqlite3_backup_init()] and is destroyed by a call to
-** [sqlite3_backup_finish()].
-**
-** See Also: [Using the SQLite Online Backup API]
-*/
-typedef struct sqlite3_backup sqlite3_backup;
-
-/*
-** CAPI3REF: Online Backup API.
-**
-** The backup API copies the content of one database into another.
-** It is useful either for creating backups of databases or
-** for copying in-memory databases to or from persistent files.
-**
-** See Also: [Using the SQLite Online Backup API]
-**
-** ^SQLite holds a write transaction open on the destination database file
-** for the duration of the backup operation.
-** ^The source database is read-locked only while it is being read;
-** it is not locked continuously for the entire backup operation.
-** ^Thus, the backup may be performed on a live source database without
-** preventing other database connections from
-** reading or writing to the source database while the backup is underway.
-**
-** ^(To perform a backup operation:
-** <ol>
-** <li><b>sqlite3_backup_init()</b> is called once to initialize the
-** backup,
-** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer
-** the data between the two databases, and finally
-** <li><b>sqlite3_backup_finish()</b> is called to release all resources
-** associated with the backup operation.
-** </ol>)^
-** There should be exactly one call to sqlite3_backup_finish() for each
-** successful call to sqlite3_backup_init().
-**
-** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b>
-**
-** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the
-** [database connection] associated with the destination database
-** and the database name, respectively.
-** ^The database name is "main" for the main database, "temp" for the
-** temporary database, or the name specified after the AS keyword in
-** an [ATTACH] statement for an attached database.
-** ^The S and M arguments passed to
-** sqlite3_backup_init(D,N,S,M) identify the [database connection]
-** and database name of the source database, respectively.
-** ^The source and destination [database connections] (parameters S and D)
-** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
-** an error.
-**
-** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
-** returned and an error code and error message are stored in the
-** destination [database connection] D.
-** ^The error code and message for the failed call to sqlite3_backup_init()
-** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
-** [sqlite3_errmsg16()] functions.
-** ^A successful call to sqlite3_backup_init() returns a pointer to an
-** [sqlite3_backup] object.
-** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and
-** sqlite3_backup_finish() functions to perform the specified backup
-** operation.
-**
-** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b>
-**
-** ^Function sqlite3_backup_step(B,N) will copy up to N pages between
-** the source and destination databases specified by [sqlite3_backup] object B.
-** ^If N is negative, all remaining source pages are copied.
-** ^If sqlite3_backup_step(B,N) successfully copies N pages and there
-** are still more pages to be copied, then the function returns [SQLITE_OK].
-** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
-** from source to destination, then it returns [SQLITE_DONE].
-** ^If an error occurs while running sqlite3_backup_step(B,N),
-** then an [error code] is returned. ^As well as [SQLITE_OK] and
-** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
-** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
-**
-** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
-** <ol>
-** <li> the destination database was opened read-only, or
-** <li> the destination database is using write-ahead-log journaling
-** and the destination and source page sizes differ, or
-** <li> the destination database is an in-memory database and the
-** destination and source page sizes differ.
-** </ol>)^
-**
-** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
-** the [sqlite3_busy_handler | busy-handler function]
-** is invoked (if one is specified). ^If the
-** busy-handler returns non-zero before the lock is available, then
-** [SQLITE_BUSY] is returned to the caller. ^In this case the call to
-** sqlite3_backup_step() can be retried later. ^If the source
-** [database connection]
-** is being used to write to the source database when sqlite3_backup_step()
-** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this
-** case the call to sqlite3_backup_step() can be retried later on. ^(If
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
-** [SQLITE_READONLY] is returned, then
-** there is no point in retrying the call to sqlite3_backup_step(). These
-** errors are considered fatal.)^ The application must accept
-** that the backup operation has failed and pass the backup operation handle
-** to the sqlite3_backup_finish() to release associated resources.
-**
-** ^The first call to sqlite3_backup_step() obtains an exclusive lock
-** on the destination file. ^The exclusive lock is not released until either
-** sqlite3_backup_finish() is called or the backup operation is complete
-** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to
-** sqlite3_backup_step() obtains a [shared lock] on the source database that
-** lasts for the duration of the sqlite3_backup_step() call.
-** ^Because the source database is not locked between calls to
-** sqlite3_backup_step(), the source database may be modified mid-way
-** through the backup process. ^If the source database is modified by an
-** external process or via a database connection other than the one being
-** used by the backup operation, then the backup will be automatically
-** restarted by the next call to sqlite3_backup_step(). ^If the source
-** database is modified by the using the same database connection as is used
-** by the backup operation, then the backup database is automatically
-** updated at the same time.
-**
-** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b>
-**
-** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the
-** application wishes to abandon the backup operation, the application
-** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish().
-** ^The sqlite3_backup_finish() interfaces releases all
-** resources associated with the [sqlite3_backup] object.
-** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any
-** active write-transaction on the destination database is rolled back.
-** The [sqlite3_backup] object is invalid
-** and may not be used following a call to sqlite3_backup_finish().
-**
-** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no
-** sqlite3_backup_step() errors occurred, regardless or whether or not
-** sqlite3_backup_step() completed.
-** ^If an out-of-memory condition or IO error occurred during any prior
-** sqlite3_backup_step() call on the same [sqlite3_backup] object, then
-** sqlite3_backup_finish() returns the corresponding [error code].
-**
-** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step()
-** is not a permanent error and does not affect the return value of
-** sqlite3_backup_finish().
-**
-** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
-** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
-**
-** ^Each call to sqlite3_backup_step() sets two values inside
-** the [sqlite3_backup] object: the number of pages still to be backed
-** up and the total number of pages in the source database file.
-** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces
-** retrieve these two values, respectively.
-**
-** ^The values returned by these functions are only updated by
-** sqlite3_backup_step(). ^If the source database is modified during a backup
-** operation, then the values are not updated to account for any extra
-** pages that need to be updated or the size of the source database file
-** changing.
-**
-** <b>Concurrent Usage of Database Handles</b>
-**
-** ^The source [database connection] may be used by the application for other
-** purposes while a backup operation is underway or being initialized.
-** ^If SQLite is compiled and configured to support threadsafe database
-** connections, then the source database connection may be used concurrently
-** from within other threads.
-**
-** However, the application must guarantee that the destination
-** [database connection] is not passed to any other API (by any thread) after
-** sqlite3_backup_init() is called and before the corresponding call to
-** sqlite3_backup_finish(). SQLite does not currently check to see
-** if the application incorrectly accesses the destination [database connection]
-** and so no error code is reported, but the operations may malfunction
-** nevertheless. Use of the destination database connection while a
-** backup is in progress might also also cause a mutex deadlock.
-**
-** If running in [shared cache mode], the application must
-** guarantee that the shared cache used by the destination database
-** is not accessed while the backup is running. In practice this means
-** that the application must guarantee that the disk file being
-** backed up to is not accessed by any connection within the process,
-** not just the specific connection that was passed to sqlite3_backup_init().
-**
-** The [sqlite3_backup] object itself is partially threadsafe. Multiple
-** threads may safely make multiple concurrent calls to sqlite3_backup_step().
-** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
-** APIs are not strictly speaking threadsafe. If they are invoked at the
-** same time as another thread is invoking sqlite3_backup_step() it is
-** possible that they return invalid values.
-*/
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
- sqlite3 *pDest, /* Destination database handle */
- const char *zDestName, /* Destination database name */
- sqlite3 *pSource, /* Source database handle */
- const char *zSourceName /* Source database name */
-);
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
-
-/*
-** CAPI3REF: Unlock Notification
-**
-** ^When running in shared-cache mode, a database operation may fail with
-** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
-** individual tables within the shared-cache cannot be obtained. See
-** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
-** ^This API may be used to register a callback that SQLite will invoke
-** when the connection currently holding the required lock relinquishes it.
-** ^This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
-**
-** See Also: [Using the SQLite Unlock Notification Feature].
-**
-** ^Shared-cache locks are released when a database connection concludes
-** its current transaction, either by committing it or rolling it back.
-**
-** ^When a connection (known as the blocked connection) fails to obtain a
-** shared-cache lock and SQLITE_LOCKED is returned to the caller, the
-** identity of the database connection (the blocking connection) that
-** has locked the required resource is stored internally. ^After an
-** application receives an SQLITE_LOCKED error, it may call the
-** sqlite3_unlock_notify() method with the blocked connection handle as
-** the first argument to register for a callback that will be invoked
-** when the blocking connections current transaction is concluded. ^The
-** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
-** call that concludes the blocking connections transaction.
-**
-** ^(If sqlite3_unlock_notify() is called in a multi-threaded application,
-** there is a chance that the blocking connection will have already
-** concluded its transaction by the time sqlite3_unlock_notify() is invoked.
-** If this happens, then the specified callback is invoked immediately,
-** from within the call to sqlite3_unlock_notify().)^
-**
-** ^If the blocked connection is attempting to obtain a write-lock on a
-** shared-cache table, and more than one other connection currently holds
-** a read-lock on the same table, then SQLite arbitrarily selects one of
-** the other connections to use as the blocking connection.
-**
-** ^(There may be at most one unlock-notify callback registered by a
-** blocked connection. If sqlite3_unlock_notify() is called when the
-** blocked connection already has a registered unlock-notify callback,
-** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is
-** called with a NULL pointer as its second argument, then any existing
-** unlock-notify callback is canceled. ^The blocked connections
-** unlock-notify callback may also be canceled by closing the blocked
-** connection using [sqlite3_close()].
-**
-** The unlock-notify callback is not reentrant. If an application invokes
-** any sqlite3_xxx API functions from within an unlock-notify callback, a
-** crash or deadlock may be the result.
-**
-** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always
-** returns SQLITE_OK.
-**
-** <b>Callback Invocation Details</b>
-**
-** When an unlock-notify callback is registered, the application provides a
-** single void* pointer that is passed to the callback when it is invoked.
-** However, the signature of the callback function allows SQLite to pass
-** it an array of void* context pointers. The first argument passed to
-** an unlock-notify callback is a pointer to an array of void* pointers,
-** and the second is the number of entries in the array.
-**
-** When a blocking connections transaction is concluded, there may be
-** more than one blocked connection that has registered for an unlock-notify
-** callback. ^If two or more such blocked connections have specified the
-** same callback function, then instead of invoking the callback function
-** multiple times, it is invoked once with the set of void* context pointers
-** specified by the blocked connections bundled together into an array.
-** This gives the application an opportunity to prioritize any actions
-** related to the set of unblocked database connections.
-**
-** <b>Deadlock Detection</b>
-**
-** Assuming that after registering for an unlock-notify callback a
-** database waits for the callback to be issued before taking any further
-** action (a reasonable assumption), then using this API may cause the
-** application to deadlock. For example, if connection X is waiting for
-** connection Y's transaction to be concluded, and similarly connection
-** Y is waiting on connection X's transaction, then neither connection
-** will proceed and the system may remain deadlocked indefinitely.
-**
-** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock
-** detection. ^If a given call to sqlite3_unlock_notify() would put the
-** system in a deadlocked state, then SQLITE_LOCKED is returned and no
-** unlock-notify callback is registered. The system is said to be in
-** a deadlocked state if connection A has registered for an unlock-notify
-** callback on the conclusion of connection B's transaction, and connection
-** B has itself registered for an unlock-notify callback when connection
-** A's transaction is concluded. ^Indirect deadlock is also detected, so
-** the system is also considered to be deadlocked if connection B has
-** registered for an unlock-notify callback on the conclusion of connection
-** C's transaction, where connection C is waiting on connection A. ^Any
-** number of levels of indirection are allowed.
-**
-** <b>The "DROP TABLE" Exception</b>
-**
-** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost
-** always appropriate to call sqlite3_unlock_notify(). There is however,
-** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
-** SQLite checks if there are any currently executing SELECT statements
-** that belong to the same connection. If there are, SQLITE_LOCKED is
-** returned. In this case there is no "blocking connection", so invoking
-** sqlite3_unlock_notify() results in the unlock-notify callback being
-** invoked immediately. If the application then re-attempts the "DROP TABLE"
-** or "DROP INDEX" query, an infinite loop might be the result.
-**
-** One way around this problem is to check the extended error code returned
-** by an sqlite3_step() call. ^(If there is a blocking connection, then the
-** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
-** the special "DROP TABLE/INDEX" case, the extended error code is just
-** SQLITE_LOCKED.)^
-*/
-SQLITE_API int sqlite3_unlock_notify(
- sqlite3 *pBlocked, /* Waiting connection */
- void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
- void *pNotifyArg /* Argument to pass to xNotify */
-);
-
-
-/*
-** CAPI3REF: String Comparison
-**
-** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications
-** and extensions to compare the contents of two buffers containing UTF-8
-** strings in a case-independent fashion, using the same definition of "case
-** independence" that SQLite uses internally when comparing identifiers.
-*/
-SQLITE_API int sqlite3_stricmp(const char *, const char *);
-SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
-
-/*
-** CAPI3REF: Error Logging Interface
-**
-** ^The [sqlite3_log()] interface writes a message into the error log
-** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
-** ^If logging is enabled, the zFormat string and subsequent arguments are
-** used with [sqlite3_snprintf()] to generate the final output string.
-**
-** The sqlite3_log() interface is intended for use by extensions such as
-** virtual tables, collating functions, and SQL functions. While there is
-** nothing to prevent an application from calling sqlite3_log(), doing so
-** is considered bad form.
-**
-** The zFormat string must not be NULL.
-**
-** To avoid deadlocks and other threading problems, the sqlite3_log() routine
-** will not use dynamically allocated memory. The log message is stored in
-** a fixed-length buffer on the stack. If the log message is longer than
-** a few hundred characters, it will be truncated to the length of the
-** buffer.
-*/
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
-
-/*
-** CAPI3REF: Write-Ahead Log Commit Hook
-**
-** ^The [sqlite3_wal_hook()] function is used to register a callback that
-** will be invoked each time a database connection commits data to a
-** [write-ahead log] (i.e. whenever a transaction is committed in
-** [journal_mode | journal_mode=WAL mode]).
-**
-** ^The callback is invoked by SQLite after the commit has taken place and
-** the associated write-lock on the database released, so the implementation
-** may read, write or [checkpoint] the database as required.
-**
-** ^The first parameter passed to the callback function when it is invoked
-** is a copy of the third parameter passed to sqlite3_wal_hook() when
-** registering the callback. ^The second is a copy of the database handle.
-** ^The third parameter is the name of the database that was written to -
-** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
-** is the number of pages currently in the write-ahead log file,
-** including those that were just committed.
-**
-** The callback function should normally return [SQLITE_OK]. ^If an error
-** code is returned, that error will propagate back up through the
-** SQLite code base to cause the statement that provoked the callback
-** to report an error, though the commit will have still occurred. If the
-** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
-** that does not correspond to any valid SQLite error code, the results
-** are undefined.
-**
-** A single database handle may have at most a single write-ahead log callback
-** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
-** previously registered write-ahead log callback. ^Note that the
-** [sqlite3_wal_autocheckpoint()] interface and the
-** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
-** those overwrite any prior [sqlite3_wal_hook()] settings.
-*/
-SQLITE_API void *sqlite3_wal_hook(
- sqlite3*,
- int(*)(void *,sqlite3*,const char*,int),
- void*
-);
-
-/*
-** CAPI3REF: Configure an auto-checkpoint
-**
-** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
-** [sqlite3_wal_hook()] that causes any database on [database connection] D
-** to automatically [checkpoint]
-** after committing a transaction if there are N or
-** more frames in the [write-ahead log] file. ^Passing zero or
-** a negative value as the nFrame parameter disables automatic
-** checkpoints entirely.
-**
-** ^The callback registered by this function replaces any existing callback
-** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback
-** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
-** configured by this function.
-**
-** ^The [wal_autocheckpoint pragma] can be used to invoke this interface
-** from SQL.
-**
-** ^Every new [database connection] defaults to having the auto-checkpoint
-** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
-** pages. The use of this interface
-** is only necessary if the default setting is found to be suboptimal
-** for a particular application.
-*/
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
-
-/*
-** CAPI3REF: Checkpoint a database
-**
-** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X
-** on [database connection] D to be [checkpointed]. ^If X is NULL or an
-** empty string, then a checkpoint is run on all databases of
-** connection D. ^If the database connection D is not in
-** [WAL | write-ahead log mode] then this interface is a harmless no-op.
-**
-** ^The [wal_checkpoint pragma] can be used to invoke this interface
-** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the
-** [wal_autocheckpoint pragma] can be used to cause this interface to be
-** run whenever the WAL reaches a certain size threshold.
-**
-** See also: [sqlite3_wal_checkpoint_v2()]
-*/
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
-
-/*
-** CAPI3REF: Checkpoint a database
-**
-** Run a checkpoint operation on WAL database zDb attached to database
-** handle db. The specific operation is determined by the value of the
-** eMode parameter:
-**
-** <dl>
-** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
-** Checkpoint as many frames as possible without waiting for any database
-** readers or writers to finish. Sync the db file if all frames in the log
-** are checkpointed. This mode is the same as calling
-** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked.
-**
-** <dt>SQLITE_CHECKPOINT_FULL<dd>
-** This mode blocks (calls the busy-handler callback) until there is no
-** database writer and all readers are reading from the most recent database
-** snapshot. It then checkpoints all frames in the log file and syncs the
-** database file. This call blocks database writers while it is running,
-** but not database readers.
-**
-** <dt>SQLITE_CHECKPOINT_RESTART<dd>
-** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after
-** checkpointing the log file it blocks (calls the busy-handler callback)
-** until all readers are reading from the database file only. This ensures
-** that the next client to write to the database file restarts the log file
-** from the beginning. This call blocks database writers while it is running,
-** but not database readers.
-** </dl>
-**
-** If pnLog is not NULL, then *pnLog is set to the total number of frames in
-** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to
-** the total number of checkpointed frames (including any that were already
-** checkpointed when this function is called). *pnLog and *pnCkpt may be
-** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK.
-** If no values are available because of an error, they are both set to -1
-** before returning to communicate this to the caller.
-**
-** All calls obtain an exclusive "checkpoint" lock on the database file. If
-** any other process is running a checkpoint operation at the same time, the
-** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a
-** busy-handler configured, it will not be invoked in this case.
-**
-** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive
-** "writer" lock on the database file. If the writer lock cannot be obtained
-** immediately, and a busy-handler is configured, it is invoked and the writer
-** lock retried until either the busy-handler returns 0 or the lock is
-** successfully obtained. The busy-handler is also invoked while waiting for
-** database readers as described above. If the busy-handler returns 0 before
-** the writer lock is obtained or while waiting for database readers, the
-** checkpoint operation proceeds from that point in the same way as
-** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
-** without blocking any further. SQLITE_BUSY is returned in this case.
-**
-** If parameter zDb is NULL or points to a zero length string, then the
-** specified operation is attempted on all WAL databases. In this case the
-** values written to output parameters *pnLog and *pnCkpt are undefined. If
-** an SQLITE_BUSY error is encountered when processing one or more of the
-** attached WAL databases, the operation is still attempted on any remaining
-** attached databases and SQLITE_BUSY is returned to the caller. If any other
-** error occurs while processing an attached database, processing is abandoned
-** and the error code returned to the caller immediately. If no error
-** (SQLITE_BUSY or otherwise) is encountered while processing the attached
-** databases, SQLITE_OK is returned.
-**
-** If database zDb is the name of an attached database that is not in WAL
-** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If
-** zDb is not NULL (or a zero length string) and is not the name of any
-** attached database, SQLITE_ERROR is returned to the caller.
-*/
-SQLITE_API int sqlite3_wal_checkpoint_v2(
- sqlite3 *db, /* Database handle */
- const char *zDb, /* Name of attached database (or NULL) */
- int eMode, /* SQLITE_CHECKPOINT_* value */
- int *pnLog, /* OUT: Size of WAL log in frames */
- int *pnCkpt /* OUT: Total number of frames checkpointed */
-);
-
-/*
-** CAPI3REF: Checkpoint operation parameters
-**
-** These constants can be used as the 3rd parameter to
-** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()]
-** documentation for additional information about the meaning and use of
-** each of these values.
-*/
-#define SQLITE_CHECKPOINT_PASSIVE 0
-#define SQLITE_CHECKPOINT_FULL 1
-#define SQLITE_CHECKPOINT_RESTART 2
-
-/*
-** CAPI3REF: Virtual Table Interface Configuration
-**
-** This function may be called by either the [xConnect] or [xCreate] method
-** of a [virtual table] implementation to configure
-** various facets of the virtual table interface.
-**
-** If this interface is invoked outside the context of an xConnect or
-** xCreate virtual table method then the behavior is undefined.
-**
-** At present, there is only one option that may be configured using
-** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options
-** may be added in the future.
-*/
-SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
-
-/*
-** CAPI3REF: Virtual Table Configuration Options
-**
-** These macros define the various options to the
-** [sqlite3_vtab_config()] interface that [virtual table] implementations
-** can use to customize and optimize their behavior.
-**
-** <dl>
-** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
-** <dd>Calls of the form
-** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
-** where X is an integer. If X is zero, then the [virtual table] whose
-** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
-** support constraints. In this configuration (which is the default) if
-** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire
-** statement is rolled back as if [ON CONFLICT | OR ABORT] had been
-** specified as part of the users SQL statement, regardless of the actual
-** ON CONFLICT mode specified.
-**
-** If X is non-zero, then the virtual table implementation guarantees
-** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before
-** any modifications to internal or persistent data structures have been made.
-** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite
-** is able to roll back a statement or database transaction, and abandon
-** or continue processing the current SQL statement as appropriate.
-** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns
-** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode
-** had been ABORT.
-**
-** Virtual table implementations that are required to handle OR REPLACE
-** must do so within the [xUpdate] method. If a call to the
-** [sqlite3_vtab_on_conflict()] function indicates that the current ON
-** CONFLICT policy is REPLACE, the virtual table implementation should
-** silently replace the appropriate rows within the xUpdate callback and
-** return SQLITE_OK. Or, if this is not possible, it may return
-** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT
-** constraint handling.
-** </dl>
-*/
-#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
-
-/*
-** CAPI3REF: Determine The Virtual Table Conflict Policy
-**
-** This function may only be called from within a call to the [xUpdate] method
-** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
-** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
-** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
-** of the SQL statement that triggered the call to the [xUpdate] method of the
-** [virtual table].
-*/
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
-
-/*
-** CAPI3REF: Conflict resolution modes
-**
-** These constants are returned by [sqlite3_vtab_on_conflict()] to
-** inform a [virtual table] implementation what the [ON CONFLICT] mode
-** is for the SQL statement being evaluated.
-**
-** Note that the [SQLITE_IGNORE] constant is also used as a potential
-** return value from the [sqlite3_set_authorizer()] callback and that
-** [SQLITE_ABORT] is also a [result code].
-*/
-#define SQLITE_ROLLBACK 1
-/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
-#define SQLITE_FAIL 3
-/* #define SQLITE_ABORT 4 // Also an error code */
-#define SQLITE_REPLACE 5
-
-
-
-/*
-** Undo the hack that converts floating point types to integer for
-** builds on processors without floating point support.
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# undef double
-#endif
-
-#if 0
-} /* End of the 'extern "C"' block */
-#endif
-#endif
-
-/*
-** 2010 August 30
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-*/
-
-#ifndef _SQLITE3RTREE_H_
-#define _SQLITE3RTREE_H_
-
-
-#if 0
-extern "C" {
-#endif
-
-typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
-
-/*
-** Register a geometry callback named zGeom that can be used as part of an
-** R-Tree geometry query as follows:
-**
-** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
-*/
-SQLITE_API int sqlite3_rtree_geometry_callback(
- sqlite3 *db,
- const char *zGeom,
-#ifdef SQLITE_RTREE_INT_ONLY
- int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes),
-#else
- int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes),
-#endif
- void *pContext
-);
-
-
-/*
-** A pointer to a structure of the following type is passed as the first
-** argument to callbacks registered using rtree_geometry_callback().
-*/
-struct sqlite3_rtree_geometry {
- void *pContext; /* Copy of pContext passed to s_r_g_c() */
- int nParam; /* Size of array aParam[] */
- double *aParam; /* Parameters passed to SQL geom function */
- void *pUser; /* Callback implementation user data */
- void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */
-};
-
-
-#if 0
-} /* end of the 'extern "C"' block */
-#endif
-
-#endif /* ifndef _SQLITE3RTREE_H_ */
-
-
-/************** End of sqlite3.h *********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include hash.h in the middle of sqliteInt.h ******************/
-/************** Begin file hash.h ********************************************/
-/*
-** 2001 September 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This is the header file for the generic hash-table implemenation
-** used in SQLite.
-*/
-#ifndef _SQLITE_HASH_H_
-#define _SQLITE_HASH_H_
-
-/* Forward declarations of structures. */
-typedef struct Hash Hash;
-typedef struct HashElem HashElem;
-
-/* A complete hash table is an instance of the following structure.
-** The internals of this structure are intended to be opaque -- client
-** code should not attempt to access or modify the fields of this structure
-** directly. Change this structure only by using the routines below.
-** However, some of the "procedures" and "functions" for modifying and
-** accessing this structure are really macros, so we can't really make
-** this structure opaque.
-**
-** All elements of the hash table are on a single doubly-linked list.
-** Hash.first points to the head of this list.
-**
-** There are Hash.htsize buckets. Each bucket points to a spot in
-** the global doubly-linked list. The contents of the bucket are the
-** element pointed to plus the next _ht.count-1 elements in the list.
-**
-** Hash.htsize and Hash.ht may be zero. In that case lookup is done
-** by a linear search of the global list. For small tables, the
-** Hash.ht table is never allocated because if there are few elements
-** in the table, it is faster to do a linear search than to manage
-** the hash table.
-*/
-struct Hash {
- unsigned int htsize; /* Number of buckets in the hash table */
- unsigned int count; /* Number of entries in this table */
- HashElem *first; /* The first element of the array */
- struct _ht { /* the hash table */
- int count; /* Number of entries with this hash */
- HashElem *chain; /* Pointer to first entry with this hash */
- } *ht;
-};
-
-/* Each element in the hash table is an instance of the following
-** structure. All elements are stored on a single doubly-linked list.
-**
-** Again, this structure is intended to be opaque, but it can't really
-** be opaque because it is used by macros.
-*/
-struct HashElem {
- HashElem *next, *prev; /* Next and previous elements in the table */
- void *data; /* Data associated with this element */
- const char *pKey; int nKey; /* Key associated with this element */
-};
-
-/*
-** Access routines. To delete, insert a NULL pointer.
-*/
-SQLITE_PRIVATE void sqlite3HashInit(Hash*);
-SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, int nKey, void *pData);
-SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey, int nKey);
-SQLITE_PRIVATE void sqlite3HashClear(Hash*);
-
-/*
-** Macros for looping over all elements of a hash table. The idiom is
-** like this:
-**
-** Hash h;
-** HashElem *p;
-** ...
-** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){
-** SomeStructure *pData = sqliteHashData(p);
-** // do something with pData
-** }
-*/
-#define sqliteHashFirst(H) ((H)->first)
-#define sqliteHashNext(E) ((E)->next)
-#define sqliteHashData(E) ((E)->data)
-/* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */
-/* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */
-
-/*
-** Number of entries in a hash table
-*/
-/* #define sqliteHashCount(H) ((H)->count) // NOT USED */
-
-#endif /* _SQLITE_HASH_H_ */
-
-/************** End of hash.h ************************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include parse.h in the middle of sqliteInt.h *****************/
-/************** Begin file parse.h *******************************************/
-#define TK_SEMI 1
-#define TK_EXPLAIN 2
-#define TK_QUERY 3
-#define TK_PLAN 4
-#define TK_BEGIN 5
-#define TK_TRANSACTION 6
-#define TK_DEFERRED 7
-#define TK_IMMEDIATE 8
-#define TK_EXCLUSIVE 9
-#define TK_COMMIT 10
-#define TK_END 11
-#define TK_ROLLBACK 12
-#define TK_SAVEPOINT 13
-#define TK_RELEASE 14
-#define TK_TO 15
-#define TK_TABLE 16
-#define TK_CREATE 17
-#define TK_IF 18
-#define TK_NOT 19
-#define TK_EXISTS 20
-#define TK_TEMP 21
-#define TK_LP 22
-#define TK_RP 23
-#define TK_AS 24
-#define TK_COMMA 25
-#define TK_ID 26
-#define TK_INDEXED 27
-#define TK_ABORT 28
-#define TK_ACTION 29
-#define TK_AFTER 30
-#define TK_ANALYZE 31
-#define TK_ASC 32
-#define TK_ATTACH 33
-#define TK_BEFORE 34
-#define TK_BY 35
-#define TK_CASCADE 36
-#define TK_CAST 37
-#define TK_COLUMNKW 38
-#define TK_CONFLICT 39
-#define TK_DATABASE 40
-#define TK_DESC 41
-#define TK_DETACH 42
-#define TK_EACH 43
-#define TK_FAIL 44
-#define TK_FOR 45
-#define TK_IGNORE 46
-#define TK_INITIALLY 47
-#define TK_INSTEAD 48
-#define TK_LIKE_KW 49
-#define TK_MATCH 50
-#define TK_NO 51
-#define TK_KEY 52
-#define TK_OF 53
-#define TK_OFFSET 54
-#define TK_PRAGMA 55
-#define TK_RAISE 56
-#define TK_REPLACE 57
-#define TK_RESTRICT 58
-#define TK_ROW 59
-#define TK_TRIGGER 60
-#define TK_VACUUM 61
-#define TK_VIEW 62
-#define TK_VIRTUAL 63
-#define TK_REINDEX 64
-#define TK_RENAME 65
-#define TK_CTIME_KW 66
-#define TK_ANY 67
-#define TK_OR 68
-#define TK_AND 69
-#define TK_IS 70
-#define TK_BETWEEN 71
-#define TK_IN 72
-#define TK_ISNULL 73
-#define TK_NOTNULL 74
-#define TK_NE 75
-#define TK_EQ 76
-#define TK_GT 77
-#define TK_LE 78
-#define TK_LT 79
-#define TK_GE 80
-#define TK_ESCAPE 81
-#define TK_BITAND 82
-#define TK_BITOR 83
-#define TK_LSHIFT 84
-#define TK_RSHIFT 85
-#define TK_PLUS 86
-#define TK_MINUS 87
-#define TK_STAR 88
-#define TK_SLASH 89
-#define TK_REM 90
-#define TK_CONCAT 91
-#define TK_COLLATE 92
-#define TK_BITNOT 93
-#define TK_STRING 94
-#define TK_JOIN_KW 95
-#define TK_CONSTRAINT 96
-#define TK_DEFAULT 97
-#define TK_NULL 98
-#define TK_PRIMARY 99
-#define TK_UNIQUE 100
-#define TK_CHECK 101
-#define TK_REFERENCES 102
-#define TK_AUTOINCR 103
-#define TK_ON 104
-#define TK_INSERT 105
-#define TK_DELETE 106
-#define TK_UPDATE 107
-#define TK_SET 108
-#define TK_DEFERRABLE 109
-#define TK_FOREIGN 110
-#define TK_DROP 111
-#define TK_UNION 112
-#define TK_ALL 113
-#define TK_EXCEPT 114
-#define TK_INTERSECT 115
-#define TK_SELECT 116
-#define TK_DISTINCT 117
-#define TK_DOT 118
-#define TK_FROM 119
-#define TK_JOIN 120
-#define TK_USING 121
-#define TK_ORDER 122
-#define TK_GROUP 123
-#define TK_HAVING 124
-#define TK_LIMIT 125
-#define TK_WHERE 126
-#define TK_INTO 127
-#define TK_VALUES 128
-#define TK_INTEGER 129
-#define TK_FLOAT 130
-#define TK_BLOB 131
-#define TK_REGISTER 132
-#define TK_VARIABLE 133
-#define TK_CASE 134
-#define TK_WHEN 135
-#define TK_THEN 136
-#define TK_ELSE 137
-#define TK_INDEX 138
-#define TK_ALTER 139
-#define TK_ADD 140
-#define TK_TO_TEXT 141
-#define TK_TO_BLOB 142
-#define TK_TO_NUMERIC 143
-#define TK_TO_INT 144
-#define TK_TO_REAL 145
-#define TK_ISNOT 146
-#define TK_END_OF_FILE 147
-#define TK_ILLEGAL 148
-#define TK_SPACE 149
-#define TK_UNCLOSED_STRING 150
-#define TK_FUNCTION 151
-#define TK_COLUMN 152
-#define TK_AGG_FUNCTION 153
-#define TK_AGG_COLUMN 154
-#define TK_CONST_FUNC 155
-#define TK_UMINUS 156
-#define TK_UPLUS 157
-
-/************** End of parse.h ***********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <stddef.h>
-
-/*
-** If compiling for a processor that lacks floating point support,
-** substitute integer for floating-point
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# define double sqlite_int64
-# define float sqlite_int64
-# define LONGDOUBLE_TYPE sqlite_int64
-# ifndef SQLITE_BIG_DBL
-# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50)
-# endif
-# define SQLITE_OMIT_DATETIME_FUNCS 1
-# define SQLITE_OMIT_TRACE 1
-# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
-# undef SQLITE_HAVE_ISNAN
-#endif
-#ifndef SQLITE_BIG_DBL
-# define SQLITE_BIG_DBL (1e99)
-#endif
-
-/*
-** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0
-** afterward. Having this macro allows us to cause the C compiler
-** to omit code used by TEMP tables without messy #ifndef statements.
-*/
-#ifdef SQLITE_OMIT_TEMPDB
-#define OMIT_TEMPDB 1
-#else
-#define OMIT_TEMPDB 0
-#endif
-
-/*
-** The "file format" number is an integer that is incremented whenever
-** the VDBE-level file format changes. The following macros define the
-** the default file format for new databases and the maximum file format
-** that the library can read.
-*/
-#define SQLITE_MAX_FILE_FORMAT 4
-#ifndef SQLITE_DEFAULT_FILE_FORMAT
-# define SQLITE_DEFAULT_FILE_FORMAT 4
-#endif
-
-/*
-** Determine whether triggers are recursive by default. This can be
-** changed at run-time using a pragma.
-*/
-#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS
-# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0
-#endif
-
-/*
-** Provide a default value for SQLITE_TEMP_STORE in case it is not specified
-** on the command-line
-*/
-#ifndef SQLITE_TEMP_STORE
-# define SQLITE_TEMP_STORE 1
-#endif
-
-/*
-** GCC does not define the offsetof() macro so we'll have to do it
-** ourselves.
-*/
-#ifndef offsetof
-#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
-#endif
-
-/*
-** Check to see if this machine uses EBCDIC. (Yes, believe it or
-** not, there are still machines out there that use EBCDIC.)
-*/
-#if 'A' == '\301'
-# define SQLITE_EBCDIC 1
-#else
-# define SQLITE_ASCII 1
-#endif
-
-/*
-** Integers of known sizes. These typedefs might change for architectures
-** where the sizes very. Preprocessor macros are available so that the
-** types can be conveniently redefined at compile-type. Like this:
-**
-** cc '-DUINTPTR_TYPE=long long int' ...
-*/
-#ifndef UINT32_TYPE
-# ifdef HAVE_UINT32_T
-# define UINT32_TYPE uint32_t
-# else
-# define UINT32_TYPE unsigned int
-# endif
-#endif
-#ifndef UINT16_TYPE
-# ifdef HAVE_UINT16_T
-# define UINT16_TYPE uint16_t
-# else
-# define UINT16_TYPE unsigned short int
-# endif
-#endif
-#ifndef INT16_TYPE
-# ifdef HAVE_INT16_T
-# define INT16_TYPE int16_t
-# else
-# define INT16_TYPE short int
-# endif
-#endif
-#ifndef UINT8_TYPE
-# ifdef HAVE_UINT8_T
-# define UINT8_TYPE uint8_t
-# else
-# define UINT8_TYPE unsigned char
-# endif
-#endif
-#ifndef INT8_TYPE
-# ifdef HAVE_INT8_T
-# define INT8_TYPE int8_t
-# else
-# define INT8_TYPE signed char
-# endif
-#endif
-#ifndef LONGDOUBLE_TYPE
-# define LONGDOUBLE_TYPE long double
-#endif
-typedef sqlite_int64 i64; /* 8-byte signed integer */
-typedef sqlite_uint64 u64; /* 8-byte unsigned integer */
-typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
-typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
-typedef INT16_TYPE i16; /* 2-byte signed integer */
-typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
-typedef INT8_TYPE i8; /* 1-byte signed integer */
-
-/*
-** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value
-** that can be stored in a u32 without loss of data. The value
-** is 0x00000000ffffffff. But because of quirks of some compilers, we
-** have to specify the value in the less intuitive manner shown:
-*/
-#define SQLITE_MAX_U32 ((((u64)1)<<32)-1)
-
-/*
-** The datatype used to store estimates of the number of rows in a
-** table or index. This is an unsigned integer type. For 99.9% of
-** the world, a 32-bit integer is sufficient. But a 64-bit integer
-** can be used at compile-time if desired.
-*/
-#ifdef SQLITE_64BIT_STATS
- typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */
-#else
- typedef u32 tRowcnt; /* 32-bit is the default */
-#endif
-
-/*
-** Macros to determine whether the machine is big or little endian,
-** evaluated at runtime.
-*/
-#ifdef SQLITE_AMALGAMATION
-SQLITE_PRIVATE const int sqlite3one = 1;
-#else
-SQLITE_PRIVATE const int sqlite3one;
-#endif
-#if defined(i386) || defined(__i386__) || defined(_M_IX86)\
- || defined(__x86_64) || defined(__x86_64__)
-# define SQLITE_BIGENDIAN 0
-# define SQLITE_LITTLEENDIAN 1
-# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
-#else
-# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
-# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
-# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
-#endif
-
-/*
-** Constants for the largest and smallest possible 64-bit signed integers.
-** These macros are designed to work correctly on both 32-bit and 64-bit
-** compilers.
-*/
-#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
-#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
-
-/*
-** Round up a number to the next larger multiple of 8. This is used
-** to force 8-byte alignment on 64-bit architectures.
-*/
-#define ROUND8(x) (((x)+7)&~7)
-
-/*
-** Round down to the nearest multiple of 8
-*/
-#define ROUNDDOWN8(x) ((x)&~7)
-
-/*
-** Assert that the pointer X is aligned to an 8-byte boundary. This
-** macro is used only within assert() to verify that the code gets
-** all alignment restrictions correct.
-**
-** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the
-** underlying malloc() implemention might return us 4-byte aligned
-** pointers. In that case, only verify 4-byte alignment.
-*/
-#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
-# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&3)==0)
-#else
-# define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
-#endif
-
-
-/*
-** An instance of the following structure is used to store the busy-handler
-** callback for a given sqlite handle.
-**
-** The sqlite.busyHandler member of the sqlite struct contains the busy
-** callback for the database handle. Each pager opened via the sqlite
-** handle is passed a pointer to sqlite.busyHandler. The busy-handler
-** callback is currently invoked only from within pager.c.
-*/
-typedef struct BusyHandler BusyHandler;
-struct BusyHandler {
- int (*xFunc)(void *,int); /* The busy callback */
- void *pArg; /* First arg to busy callback */
- int nBusy; /* Incremented with each busy call */
-};
-
-/*
-** Name of the master database table. The master database table
-** is a special table that holds the names and attributes of all
-** user tables and indices.
-*/
-#define MASTER_NAME "sqlite_master"
-#define TEMP_MASTER_NAME "sqlite_temp_master"
-
-/*
-** The root-page of the master database table.
-*/
-#define MASTER_ROOT 1
-
-/*
-** The name of the schema table.
-*/
-#define SCHEMA_TABLE(x) ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME)
-
-/*
-** A convenience macro that returns the number of elements in
-** an array.
-*/
-#define ArraySize(X) ((int)(sizeof(X)/sizeof(X[0])))
-
-/*
-** The following value as a destructor means to use sqlite3DbFree().
-** The sqlite3DbFree() routine requires two parameters instead of the
-** one parameter that destructors normally want. So we have to introduce
-** this magic value that the code knows to handle differently. Any
-** pointer will work here as long as it is distinct from SQLITE_STATIC
-** and SQLITE_TRANSIENT.
-*/
-#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3MallocSize)
-
-/*
-** When SQLITE_OMIT_WSD is defined, it means that the target platform does
-** not support Writable Static Data (WSD) such as global and static variables.
-** All variables must either be on the stack or dynamically allocated from
-** the heap. When WSD is unsupported, the variable declarations scattered
-** throughout the SQLite code must become constants instead. The SQLITE_WSD
-** macro is used for this purpose. And instead of referencing the variable
-** directly, we use its constant as a key to lookup the run-time allocated
-** buffer that holds real variable. The constant is also the initializer
-** for the run-time allocated buffer.
-**
-** In the usual case where WSD is supported, the SQLITE_WSD and GLOBAL
-** macros become no-ops and have zero performance impact.
-*/
-#ifdef SQLITE_OMIT_WSD
- #define SQLITE_WSD const
- #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v)))
- #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config)
-SQLITE_API int sqlite3_wsd_init(int N, int J);
-SQLITE_API void *sqlite3_wsd_find(void *K, int L);
-#else
- #define SQLITE_WSD
- #define GLOBAL(t,v) v
- #define sqlite3GlobalConfig sqlite3Config
-#endif
-
-/*
-** The following macros are used to suppress compiler warnings and to
-** make it clear to human readers when a function parameter is deliberately
-** left unused within the body of a function. This usually happens when
-** a function is called via a function pointer. For example the
-** implementation of an SQL aggregate step callback may not use the
-** parameter indicating the number of arguments passed to the aggregate,
-** if it knows that this is enforced elsewhere.
-**
-** When a function parameter is not used at all within the body of a function,
-** it is generally named "NotUsed" or "NotUsed2" to make things even clearer.
-** However, these macros may also be used to suppress warnings related to
-** parameters that may or may not be used depending on compilation options.
-** For example those parameters only used in assert() statements. In these
-** cases the parameters are named as per the usual conventions.
-*/
-#define UNUSED_PARAMETER(x) (void)(x)
-#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y)
-
-/*
-** Forward references to structures
-*/
-typedef struct AggInfo AggInfo;
-typedef struct AuthContext AuthContext;
-typedef struct AutoincInfo AutoincInfo;
-typedef struct Bitvec Bitvec;
-typedef struct CollSeq CollSeq;
-typedef struct Column Column;
-typedef struct Db Db;
-typedef struct Schema Schema;
-typedef struct Expr Expr;
-typedef struct ExprList ExprList;
-typedef struct ExprSpan ExprSpan;
-typedef struct FKey FKey;
-typedef struct FuncDestructor FuncDestructor;
-typedef struct FuncDef FuncDef;
-typedef struct FuncDefHash FuncDefHash;
-typedef struct IdList IdList;
-typedef struct Index Index;
-typedef struct IndexSample IndexSample;
-typedef struct KeyClass KeyClass;
-typedef struct KeyInfo KeyInfo;
-typedef struct Lookaside Lookaside;
-typedef struct LookasideSlot LookasideSlot;
-typedef struct Module Module;
-typedef struct NameContext NameContext;
-typedef struct Parse Parse;
-typedef struct RowSet RowSet;
-typedef struct Savepoint Savepoint;
-typedef struct Select Select;
-typedef struct SelectDest SelectDest;
-typedef struct SrcList SrcList;
-typedef struct StrAccum StrAccum;
-typedef struct Table Table;
-typedef struct TableLock TableLock;
-typedef struct Token Token;
-typedef struct Trigger Trigger;
-typedef struct TriggerPrg TriggerPrg;
-typedef struct TriggerStep TriggerStep;
-typedef struct UnpackedRecord UnpackedRecord;
-typedef struct VTable VTable;
-typedef struct VtabCtx VtabCtx;
-typedef struct Walker Walker;
-typedef struct WherePlan WherePlan;
-typedef struct WhereInfo WhereInfo;
-typedef struct WhereLevel WhereLevel;
-
-/*
-** Defer sourcing vdbe.h and btree.h until after the "u8" and
-** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
-** pointer types (i.e. FuncDef) defined above.
-*/
-/************** Include btree.h in the middle of sqliteInt.h *****************/
-/************** Begin file btree.h *******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This header file defines the interface that the sqlite B-Tree file
-** subsystem. See comments in the source code for a detailed description
-** of what each interface routine does.
-*/
-#ifndef _BTREE_H_
-#define _BTREE_H_
-
-/* TODO: This definition is just included so other modules compile. It
-** needs to be revisited.
-*/
-#define SQLITE_N_BTREE_META 10
-
-/*
-** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
-** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
-*/
-#ifndef SQLITE_DEFAULT_AUTOVACUUM
- #define SQLITE_DEFAULT_AUTOVACUUM 0
-#endif
-
-#define BTREE_AUTOVACUUM_NONE 0 /* Do not do auto-vacuum */
-#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */
-#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */
-
-/*
-** Forward declarations of structure
-*/
-typedef struct Btree Btree;
-typedef struct BtCursor BtCursor;
-typedef struct BtShared BtShared;
-
-
-SQLITE_PRIVATE int sqlite3BtreeOpen(
- sqlite3_vfs *pVfs, /* VFS to use with this b-tree */
- const char *zFilename, /* Name of database file to open */
- sqlite3 *db, /* Associated database connection */
- Btree **ppBtree, /* Return open Btree* here */
- int flags, /* Flags */
- int vfsFlags /* Flags passed through to VFS open */
-);
-
-/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
-** following values.
-**
-** NOTE: These values must match the corresponding PAGER_ values in
-** pager.h.
-*/
-#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */
-#define BTREE_MEMORY 2 /* This is an in-memory DB */
-#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */
-#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */
-
-SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
-SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
-SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
-SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
-#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
-SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
-#endif
-SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
-SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
-SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
-SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags);
-SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
-SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
-SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);
-SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
-SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int);
-
-SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *);
-SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *);
-SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *);
-
-SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
-
-/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR
-** of the flags shown below.
-**
-** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set.
-** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data
-** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With
-** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored
-** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL
-** indices.)
-*/
-#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */
-#define BTREE_BLOBKEY 2 /* Table has keys only - no data */
-
-SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
-SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
-SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
-
-SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
-SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
-
-SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
-
-/*
-** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
-** should be one of the following values. The integer values are assigned
-** to constants so that the offset of the corresponding field in an
-** SQLite database header may be found using the following formula:
-**
-** offset = 36 + (idx * 4)
-**
-** For example, the free-page-count field is located at byte offset 36 of
-** the database file header. The incr-vacuum-flag field is located at
-** byte offset 64 (== 36+4*7).
-*/
-#define BTREE_FREE_PAGE_COUNT 0
-#define BTREE_SCHEMA_VERSION 1
-#define BTREE_FILE_FORMAT 2
-#define BTREE_DEFAULT_CACHE_SIZE 3
-#define BTREE_LARGEST_ROOT_PAGE 4
-#define BTREE_TEXT_ENCODING 5
-#define BTREE_USER_VERSION 6
-#define BTREE_INCR_VACUUM 7
-
-/*
-** Values that may be OR'd together to form the second argument of an
-** sqlite3BtreeCursorHints() call.
-*/
-#define BTREE_BULKLOAD 0x00000001
-
-SQLITE_PRIVATE int sqlite3BtreeCursor(
- Btree*, /* BTree containing table to open */
- int iTable, /* Index of root page */
- int wrFlag, /* 1 for writing. 0 for read-only */
- struct KeyInfo*, /* First argument to compare function */
- BtCursor *pCursor /* Space to write cursor structure */
-);
-SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
-SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*);
-
-SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
- BtCursor*,
- UnpackedRecord *pUnKey,
- i64 intKey,
- int bias,
- int *pRes
-);
-SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*, int*);
-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
- const void *pData, int nData,
- int nZero, int bias, int seekResult);
-SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
-SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
-SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes);
-SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes);
-SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
-SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
-SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
-SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
-SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64);
-SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*);
-
-SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
-SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
-
-SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *);
-SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
-SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
-SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
-
-#ifndef NDEBUG
-SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
-#endif
-
-#ifndef SQLITE_OMIT_BTREECOUNT
-SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);
-#endif
-
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
-SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*);
-#endif
-
-#ifndef SQLITE_OMIT_WAL
-SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);
-#endif
-
-/*
-** If we are not using shared cache, then there is no need to
-** use mutexes to access the BtShared structures. So make the
-** Enter and Leave procedures no-ops.
-*/
-#ifndef SQLITE_OMIT_SHARED_CACHE
-SQLITE_PRIVATE void sqlite3BtreeEnter(Btree*);
-SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3*);
-#else
-# define sqlite3BtreeEnter(X)
-# define sqlite3BtreeEnterAll(X)
-#endif
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
-SQLITE_PRIVATE int sqlite3BtreeSharable(Btree*);
-SQLITE_PRIVATE void sqlite3BtreeLeave(Btree*);
-SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*);
-SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor*);
-SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3*);
-#ifndef NDEBUG
- /* These routines are used inside assert() statements only. */
-SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*);
-SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
-#endif
-#else
-
-# define sqlite3BtreeSharable(X) 0
-# define sqlite3BtreeLeave(X)
-# define sqlite3BtreeEnterCursor(X)
-# define sqlite3BtreeLeaveCursor(X)
-# define sqlite3BtreeLeaveAll(X)
-
-# define sqlite3BtreeHoldsMutex(X) 1
-# define sqlite3BtreeHoldsAllMutexes(X) 1
-# define sqlite3SchemaMutexHeld(X,Y,Z) 1
-#endif
-
-
-#endif /* _BTREE_H_ */
-
-/************** End of btree.h ***********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include vdbe.h in the middle of sqliteInt.h ******************/
-/************** Begin file vdbe.h ********************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** Header file for the Virtual DataBase Engine (VDBE)
-**
-** This header defines the interface to the virtual database engine
-** or VDBE. The VDBE implements an abstract machine that runs a
-** simple program to access and modify the underlying database.
-*/
-#ifndef _SQLITE_VDBE_H_
-#define _SQLITE_VDBE_H_
-/* #include <stdio.h> */
-
-/*
-** A single VDBE is an opaque structure named "Vdbe". Only routines
-** in the source file sqliteVdbe.c are allowed to see the insides
-** of this structure.
-*/
-typedef struct Vdbe Vdbe;
-
-/*
-** The names of the following types declared in vdbeInt.h are required
-** for the VdbeOp definition.
-*/
-typedef struct VdbeFunc VdbeFunc;
-typedef struct Mem Mem;
-typedef struct SubProgram SubProgram;
-
-/*
-** A single instruction of the virtual machine has an opcode
-** and as many as three operands. The instruction is recorded
-** as an instance of the following structure:
-*/
-struct VdbeOp {
- u8 opcode; /* What operation to perform */
- signed char p4type; /* One of the P4_xxx constants for p4 */
- u8 opflags; /* Mask of the OPFLG_* flags in opcodes.h */
- u8 p5; /* Fifth parameter is an unsigned character */
- int p1; /* First operand */
- int p2; /* Second parameter (often the jump destination) */
- int p3; /* The third parameter */
- union { /* fourth parameter */
- int i; /* Integer value if p4type==P4_INT32 */
- void *p; /* Generic pointer */
- char *z; /* Pointer to data for string (char array) types */
- i64 *pI64; /* Used when p4type is P4_INT64 */
- double *pReal; /* Used when p4type is P4_REAL */
- FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
- VdbeFunc *pVdbeFunc; /* Used when p4type is P4_VDBEFUNC */
- CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */
- Mem *pMem; /* Used when p4type is P4_MEM */
- VTable *pVtab; /* Used when p4type is P4_VTAB */
- KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
- int *ai; /* Used when p4type is P4_INTARRAY */
- SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
- int (*xAdvance)(BtCursor *, int *);
- } p4;
-#ifdef SQLITE_DEBUG
- char *zComment; /* Comment to improve readability */
-#endif
-#ifdef VDBE_PROFILE
- int cnt; /* Number of times this instruction was executed */
- u64 cycles; /* Total time spent executing this instruction */
-#endif
-};
-typedef struct VdbeOp VdbeOp;
-
-
-/*
-** A sub-routine used to implement a trigger program.
-*/
-struct SubProgram {
- VdbeOp *aOp; /* Array of opcodes for sub-program */
- int nOp; /* Elements in aOp[] */
- int nMem; /* Number of memory cells required */
- int nCsr; /* Number of cursors required */
- int nOnce; /* Number of OP_Once instructions */
- void *token; /* id that may be used to recursive triggers */
- SubProgram *pNext; /* Next sub-program already visited */
-};
-
-/*
-** A smaller version of VdbeOp used for the VdbeAddOpList() function because
-** it takes up less space.
-*/
-struct VdbeOpList {
- u8 opcode; /* What operation to perform */
- signed char p1; /* First operand */
- signed char p2; /* Second parameter (often the jump destination) */
- signed char p3; /* Third parameter */
-};
-typedef struct VdbeOpList VdbeOpList;
-
-/*
-** Allowed values of VdbeOp.p4type
-*/
-#define P4_NOTUSED 0 /* The P4 parameter is not used */
-#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
-#define P4_STATIC (-2) /* Pointer to a static string */
-#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
-#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
-#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
-#define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */
-#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
-#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
-#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */
-#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */
-#define P4_REAL (-12) /* P4 is a 64-bit floating point value */
-#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
-#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */
-#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
-#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */
-#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
-
-/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
-** is made. That copy is freed when the Vdbe is finalized. But if the
-** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used. It still
-** gets freed when the Vdbe is finalized so it still should be obtained
-** from a single sqliteMalloc(). But no copy is made and the calling
-** function should *not* try to free the KeyInfo.
-*/
-#define P4_KEYINFO_HANDOFF (-16)
-#define P4_KEYINFO_STATIC (-17)
-
-/*
-** The Vdbe.aColName array contains 5n Mem structures, where n is the
-** number of columns of data returned by the statement.
-*/
-#define COLNAME_NAME 0
-#define COLNAME_DECLTYPE 1
-#define COLNAME_DATABASE 2
-#define COLNAME_TABLE 3
-#define COLNAME_COLUMN 4
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
-# define COLNAME_N 5 /* Number of COLNAME_xxx symbols */
-#else
-# ifdef SQLITE_OMIT_DECLTYPE
-# define COLNAME_N 1 /* Store only the name */
-# else
-# define COLNAME_N 2 /* Store the name and decltype */
-# endif
-#endif
-
-/*
-** The following macro converts a relative address in the p2 field
-** of a VdbeOp structure into a negative number so that
-** sqlite3VdbeAddOpList() knows that the address is relative. Calling
-** the macro again restores the address.
-*/
-#define ADDR(X) (-1-(X))
-
-/*
-** The makefile scans the vdbe.c source file and creates the "opcodes.h"
-** header file that defines a number for each opcode used by the VDBE.
-*/
-/************** Include opcodes.h in the middle of vdbe.h ********************/
-/************** Begin file opcodes.h *****************************************/
-/* Automatically generated. Do not edit */
-/* See the mkopcodeh.awk script for details */
-#define OP_Goto 1
-#define OP_Gosub 2
-#define OP_Return 3
-#define OP_Yield 4
-#define OP_HaltIfNull 5
-#define OP_Halt 6
-#define OP_Integer 7
-#define OP_Int64 8
-#define OP_Real 130 /* same as TK_FLOAT */
-#define OP_String8 94 /* same as TK_STRING */
-#define OP_String 9
-#define OP_Null 10
-#define OP_Blob 11
-#define OP_Variable 12
-#define OP_Move 13
-#define OP_Copy 14
-#define OP_SCopy 15
-#define OP_ResultRow 16
-#define OP_Concat 91 /* same as TK_CONCAT */
-#define OP_Add 86 /* same as TK_PLUS */
-#define OP_Subtract 87 /* same as TK_MINUS */
-#define OP_Multiply 88 /* same as TK_STAR */
-#define OP_Divide 89 /* same as TK_SLASH */
-#define OP_Remainder 90 /* same as TK_REM */
-#define OP_CollSeq 17
-#define OP_Function 18
-#define OP_BitAnd 82 /* same as TK_BITAND */
-#define OP_BitOr 83 /* same as TK_BITOR */
-#define OP_ShiftLeft 84 /* same as TK_LSHIFT */
-#define OP_ShiftRight 85 /* same as TK_RSHIFT */
-#define OP_AddImm 20
-#define OP_MustBeInt 21
-#define OP_RealAffinity 22
-#define OP_ToText 141 /* same as TK_TO_TEXT */
-#define OP_ToBlob 142 /* same as TK_TO_BLOB */
-#define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/
-#define OP_ToInt 144 /* same as TK_TO_INT */
-#define OP_ToReal 145 /* same as TK_TO_REAL */
-#define OP_Eq 76 /* same as TK_EQ */
-#define OP_Ne 75 /* same as TK_NE */
-#define OP_Lt 79 /* same as TK_LT */
-#define OP_Le 78 /* same as TK_LE */
-#define OP_Gt 77 /* same as TK_GT */
-#define OP_Ge 80 /* same as TK_GE */
-#define OP_Permutation 23
-#define OP_Compare 24
-#define OP_Jump 25
-#define OP_And 69 /* same as TK_AND */
-#define OP_Or 68 /* same as TK_OR */
-#define OP_Not 19 /* same as TK_NOT */
-#define OP_BitNot 93 /* same as TK_BITNOT */
-#define OP_Once 26
-#define OP_If 27
-#define OP_IfNot 28
-#define OP_IsNull 73 /* same as TK_ISNULL */
-#define OP_NotNull 74 /* same as TK_NOTNULL */
-#define OP_Column 29
-#define OP_Affinity 30
-#define OP_MakeRecord 31
-#define OP_Count 32
-#define OP_Savepoint 33
-#define OP_AutoCommit 34
-#define OP_Transaction 35
-#define OP_ReadCookie 36
-#define OP_SetCookie 37
-#define OP_VerifyCookie 38
-#define OP_OpenRead 39
-#define OP_OpenWrite 40
-#define OP_OpenAutoindex 41
-#define OP_OpenEphemeral 42
-#define OP_SorterOpen 43
-#define OP_OpenPseudo 44
-#define OP_Close 45
-#define OP_SeekLt 46
-#define OP_SeekLe 47
-#define OP_SeekGe 48
-#define OP_SeekGt 49
-#define OP_Seek 50
-#define OP_NotFound 51
-#define OP_Found 52
-#define OP_IsUnique 53
-#define OP_NotExists 54
-#define OP_Sequence 55
-#define OP_NewRowid 56
-#define OP_Insert 57
-#define OP_InsertInt 58
-#define OP_Delete 59
-#define OP_ResetCount 60
-#define OP_SorterCompare 61
-#define OP_SorterData 62
-#define OP_RowKey 63
-#define OP_RowData 64
-#define OP_Rowid 65
-#define OP_NullRow 66
-#define OP_Last 67
-#define OP_SorterSort 70
-#define OP_Sort 71
-#define OP_Rewind 72
-#define OP_SorterNext 81
-#define OP_Prev 92
-#define OP_Next 95
-#define OP_SorterInsert 96
-#define OP_IdxInsert 97
-#define OP_IdxDelete 98
-#define OP_IdxRowid 99
-#define OP_IdxLT 100
-#define OP_IdxGE 101
-#define OP_Destroy 102
-#define OP_Clear 103
-#define OP_CreateIndex 104
-#define OP_CreateTable 105
-#define OP_ParseSchema 106
-#define OP_LoadAnalysis 107
-#define OP_DropTable 108
-#define OP_DropIndex 109
-#define OP_DropTrigger 110
-#define OP_IntegrityCk 111
-#define OP_RowSetAdd 112
-#define OP_RowSetRead 113
-#define OP_RowSetTest 114
-#define OP_Program 115
-#define OP_Param 116
-#define OP_FkCounter 117
-#define OP_FkIfZero 118
-#define OP_MemMax 119
-#define OP_IfPos 120
-#define OP_IfNeg 121
-#define OP_IfZero 122
-#define OP_AggStep 123
-#define OP_AggFinal 124
-#define OP_Checkpoint 125
-#define OP_JournalMode 126
-#define OP_Vacuum 127
-#define OP_IncrVacuum 128
-#define OP_Expire 129
-#define OP_TableLock 131
-#define OP_VBegin 132
-#define OP_VCreate 133
-#define OP_VDestroy 134
-#define OP_VOpen 135
-#define OP_VFilter 136
-#define OP_VColumn 137
-#define OP_VNext 138
-#define OP_VRename 139
-#define OP_VUpdate 140
-#define OP_Pagecount 146
-#define OP_MaxPgcnt 147
-#define OP_Trace 148
-#define OP_Noop 149
-#define OP_Explain 150
-
-
-/* Properties such as "out2" or "jump" that are specified in
-** comments following the "case" for each opcode in the vdbe.c
-** are encoded into bitvectors as follows:
-*/
-#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */
-#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */
-#define OPFLG_IN1 0x0004 /* in1: P1 is an input */
-#define OPFLG_IN2 0x0008 /* in2: P2 is an input */
-#define OPFLG_IN3 0x0010 /* in3: P3 is an input */
-#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */
-#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */
-#define OPFLG_INITIALIZER {\
-/* 0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\
-/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x24,\
-/* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\
-/* 24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\
-/* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\
-/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
-/* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\
-/* 56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\
-/* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
-/* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
-/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\
-/* 96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
-/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
-/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\
-/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\
-/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}
-
-/************** End of opcodes.h *********************************************/
-/************** Continuing where we left off in vdbe.h ***********************/
-
-/*
-** Prototypes for the VDBE interface. See comments on the implementation
-** for a description of what each of these routines does.
-*/
-SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3*);
-SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
-SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
-SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
-SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
-SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
-SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
-SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
-SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
-SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
-SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
-SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int);
-SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*);
-#endif
-SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*);
-SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int);
-SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
-SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
-SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
-SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
-SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8);
-SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
-#ifndef SQLITE_OMIT_TRACE
-SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
-#endif
-
-SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
-SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
-SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
-
-#ifndef SQLITE_OMIT_TRIGGER
-SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
-#endif
-
-
-#ifndef NDEBUG
-SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...);
-# define VdbeComment(X) sqlite3VdbeComment X
-SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...);
-# define VdbeNoopComment(X) sqlite3VdbeNoopComment X
-#else
-# define VdbeComment(X)
-# define VdbeNoopComment(X)
-#endif
-
-#endif
-
-/************** End of vdbe.h ************************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include pager.h in the middle of sqliteInt.h *****************/
-/************** Begin file pager.h *******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This header file defines the interface that the sqlite page cache
-** subsystem. The page cache subsystem reads and writes a file a page
-** at a time and provides a journal for rollback.
-*/
-
-#ifndef _PAGER_H_
-#define _PAGER_H_
-
-/*
-** Default maximum size for persistent journal files. A negative
-** value means no limit. This value may be overridden using the
-** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit".
-*/
-#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
- #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1
-#endif
-
-/*
-** The type used to represent a page number. The first page in a file
-** is called page 1. 0 is used to represent "not a page".
-*/
-typedef u32 Pgno;
-
-/*
-** Each open file is managed by a separate instance of the "Pager" structure.
-*/
-typedef struct Pager Pager;
-
-/*
-** Handle type for pages.
-*/
-typedef struct PgHdr DbPage;
-
-/*
-** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
-** reserved for working around a windows/posix incompatibility). It is
-** used in the journal to signify that the remainder of the journal file
-** is devoted to storing a master journal name - there are no more pages to
-** roll back. See comments for function writeMasterJournal() in pager.c
-** for details.
-*/
-#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
-
-/*
-** Allowed values for the flags parameter to sqlite3PagerOpen().
-**
-** NOTE: These values must match the corresponding BTREE_ values in btree.h.
-*/
-#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */
-#define PAGER_MEMORY 0x0002 /* In-memory database */
-
-/*
-** Valid values for the second argument to sqlite3PagerLockingMode().
-*/
-#define PAGER_LOCKINGMODE_QUERY -1
-#define PAGER_LOCKINGMODE_NORMAL 0
-#define PAGER_LOCKINGMODE_EXCLUSIVE 1
-
-/*
-** Numeric constants that encode the journalmode.
-*/
-#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */
-#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */
-#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */
-#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */
-#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */
-#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */
-#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */
-
-/*
-** The remainder of this file contains the declarations of the functions
-** that make up the Pager sub-system API. See source code comments for
-** a detailed description of each routine.
-*/
-
-/* Open and close a Pager connection. */
-SQLITE_PRIVATE int sqlite3PagerOpen(
- sqlite3_vfs*,
- Pager **ppPager,
- const char*,
- int,
- int,
- int,
- void(*)(DbPage*)
-);
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
-
-/* Functions used to configure a Pager object. */
-SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
-SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
-SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
-SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
-SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
-SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
-SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int);
-SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*);
-SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*);
-SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
-SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
-
-/* Functions used to obtain and release page references. */
-SQLITE_PRIVATE int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
-#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0)
-SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
-SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
-SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*);
-
-/* Operations on page references. */
-SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*);
-SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*);
-SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int);
-SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*);
-SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *);
-SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *);
-
-/* Functions used to manage pager transactions and savepoints. */
-SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*);
-SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int);
-SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
-SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*);
-SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
-SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
-SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
-SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
-SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
-
-#ifndef SQLITE_OMIT_WAL
-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
-SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager);
-#endif
-
-#ifdef SQLITE_ENABLE_ZIPVFS
-SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
-#endif
-
-/* Functions used to query pager state and configuration. */
-SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
-SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
-SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
-SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int);
-SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
-SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
-SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
-SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
-SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
-SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
-SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
-SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *);
-SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
-
-/* Functions used to truncate the database file. */
-SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
-
-#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
-SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *);
-#endif
-
-/* Functions to support testing and debugging. */
-#if !defined(NDEBUG) || defined(SQLITE_TEST)
-SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*);
-SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*);
-#endif
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE int *sqlite3PagerStats(Pager*);
-SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*);
- void disable_simulated_io_errors(void);
- void enable_simulated_io_errors(void);
-#else
-# define disable_simulated_io_errors()
-# define enable_simulated_io_errors()
-#endif
-
-#endif /* _PAGER_H_ */
-
-/************** End of pager.h ***********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include pcache.h in the middle of sqliteInt.h ****************/
-/************** Begin file pcache.h ******************************************/
-/*
-** 2008 August 05
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This header file defines the interface that the sqlite page cache
-** subsystem.
-*/
-
-#ifndef _PCACHE_H_
-
-typedef struct PgHdr PgHdr;
-typedef struct PCache PCache;
-
-/*
-** Every page in the cache is controlled by an instance of the following
-** structure.
-*/
-struct PgHdr {
- sqlite3_pcache_page *pPage; /* Pcache object page handle */
- void *pData; /* Page data */
- void *pExtra; /* Extra content */
- PgHdr *pDirty; /* Transient list of dirty pages */
- Pager *pPager; /* The pager this page is part of */
- Pgno pgno; /* Page number for this page */
-#ifdef SQLITE_CHECK_PAGES
- u32 pageHash; /* Hash of page content */
-#endif
- u16 flags; /* PGHDR flags defined below */
-
- /**********************************************************************
- ** Elements above are public. All that follows is private to pcache.c
- ** and should not be accessed by other modules.
- */
- i16 nRef; /* Number of users of this page */
- PCache *pCache; /* Cache that owns this page */
-
- PgHdr *pDirtyNext; /* Next element in list of dirty pages */
- PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */
-};
-
-/* Bit values for PgHdr.flags */
-#define PGHDR_DIRTY 0x002 /* Page has changed */
-#define PGHDR_NEED_SYNC 0x004 /* Fsync the rollback journal before
- ** writing this page to the database */
-#define PGHDR_NEED_READ 0x008 /* Content is unread */
-#define PGHDR_REUSE_UNLIKELY 0x010 /* A hint that reuse is unlikely */
-#define PGHDR_DONT_WRITE 0x020 /* Do not write content to disk */
-
-/* Initialize and shutdown the page cache subsystem */
-SQLITE_PRIVATE int sqlite3PcacheInitialize(void);
-SQLITE_PRIVATE void sqlite3PcacheShutdown(void);
-
-/* Page cache buffer management:
-** These routines implement SQLITE_CONFIG_PAGECACHE.
-*/
-SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n);
-
-/* Create a new pager cache.
-** Under memory stress, invoke xStress to try to make pages clean.
-** Only clean and unpinned pages can be reclaimed.
-*/
-SQLITE_PRIVATE void sqlite3PcacheOpen(
- int szPage, /* Size of every page */
- int szExtra, /* Extra space associated with each page */
- int bPurgeable, /* True if pages are on backing store */
- int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */
- void *pStress, /* Argument to xStress */
- PCache *pToInit /* Preallocated space for the PCache */
-);
-
-/* Modify the page-size after the cache has been created. */
-SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *, int);
-
-/* Return the size in bytes of a PCache object. Used to preallocate
-** storage space.
-*/
-SQLITE_PRIVATE int sqlite3PcacheSize(void);
-
-/* One release per successful fetch. Page is pinned until released.
-** Reference counted.
-*/
-SQLITE_PRIVATE int sqlite3PcacheFetch(PCache*, Pgno, int createFlag, PgHdr**);
-SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*);
-
-SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */
-SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */
-SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */
-SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */
-
-/* Change a page number. Used by incr-vacuum. */
-SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno);
-
-/* Remove all pages with pgno>x. Reset the cache if x==0 */
-SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache*, Pgno x);
-
-/* Get a list of all dirty pages in the cache, sorted by page number */
-SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache*);
-
-/* Reset and close the cache object */
-SQLITE_PRIVATE void sqlite3PcacheClose(PCache*);
-
-/* Clear flags from pages of the page cache */
-SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *);
-
-/* Discard the contents of the cache */
-SQLITE_PRIVATE void sqlite3PcacheClear(PCache*);
-
-/* Return the total number of outstanding page references */
-SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*);
-
-/* Increment the reference count of an existing page */
-SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*);
-
-SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*);
-
-/* Return the total number of pages stored in the cache */
-SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*);
-
-#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
-/* Iterate through all dirty pages currently stored in the cache. This
-** interface is only available if SQLITE_CHECK_PAGES is defined when the
-** library is built.
-*/
-SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *));
-#endif
-
-/* Set and get the suggested cache-size for the specified pager-cache.
-**
-** If no global maximum is configured, then the system attempts to limit
-** the total number of pages cached by purgeable pager-caches to the sum
-** of the suggested cache-sizes.
-*/
-SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int);
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *);
-#endif
-
-/* Free up as much memory as possible from the page cache */
-SQLITE_PRIVATE void sqlite3PcacheShrink(PCache*);
-
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-/* Try to return memory used by the pcache module to the main memory heap */
-SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int);
-#endif
-
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*);
-#endif
-
-SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
-
-#endif /* _PCACHE_H_ */
-
-/************** End of pcache.h **********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-
-/************** Include os.h in the middle of sqliteInt.h ********************/
-/************** Begin file os.h **********************************************/
-/*
-** 2001 September 16
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This header file (together with is companion C source-code file
-** "os.c") attempt to abstract the underlying operating system so that
-** the SQLite library will work on both POSIX and windows systems.
-**
-** This header file is #include-ed by sqliteInt.h and thus ends up
-** being included by every source file.
-*/
-#ifndef _SQLITE_OS_H_
-#define _SQLITE_OS_H_
-
-/*
-** Figure out if we are dealing with Unix, Windows, or some other
-** operating system. After the following block of preprocess macros,
-** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER
-** will defined to either 1 or 0. One of the four will be 1. The other
-** three will be 0.
-*/
-#if defined(SQLITE_OS_OTHER)
-# if SQLITE_OS_OTHER==1
-# undef SQLITE_OS_UNIX
-# define SQLITE_OS_UNIX 0
-# undef SQLITE_OS_WIN
-# define SQLITE_OS_WIN 0
-# else
-# undef SQLITE_OS_OTHER
-# endif
-#endif
-#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
-# define SQLITE_OS_OTHER 0
-# ifndef SQLITE_OS_WIN
-# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
-# define SQLITE_OS_WIN 1
-# define SQLITE_OS_UNIX 0
-# else
-# define SQLITE_OS_WIN 0
-# define SQLITE_OS_UNIX 1
-# endif
-# else
-# define SQLITE_OS_UNIX 0
-# endif
-#else
-# ifndef SQLITE_OS_WIN
-# define SQLITE_OS_WIN 0
-# endif
-#endif
-
-#if SQLITE_OS_WIN
-# include <windows.h>
-#endif
-
-/*
-** Determine if we are dealing with Windows NT.
-**
-** We ought to be able to determine if we are compiling for win98 or winNT
-** using the _WIN32_WINNT macro as follows:
-**
-** #if defined(_WIN32_WINNT)
-** # define SQLITE_OS_WINNT 1
-** #else
-** # define SQLITE_OS_WINNT 0
-** #endif
-**
-** However, vs2005 does not set _WIN32_WINNT by default, as it ought to,
-** so the above test does not work. We'll just assume that everything is
-** winNT unless the programmer explicitly says otherwise by setting
-** SQLITE_OS_WINNT to 0.
-*/
-#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT)
-# define SQLITE_OS_WINNT 1
-#endif
-
-/*
-** Determine if we are dealing with WindowsCE - which has a much
-** reduced API.
-*/
-#if defined(_WIN32_WCE)
-# define SQLITE_OS_WINCE 1
-#else
-# define SQLITE_OS_WINCE 0
-#endif
-
-/*
-** Determine if we are dealing with WinRT, which provides only a subset of
-** the full Win32 API.
-*/
-#if !defined(SQLITE_OS_WINRT)
-# define SQLITE_OS_WINRT 0
-#endif
-
-/*
-** When compiled for WinCE or WinRT, there is no concept of the current
-** directory.
- */
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-# define SQLITE_CURDIR 1
-#endif
-
-/* If the SET_FULLSYNC macro is not defined above, then make it
-** a no-op
-*/
-#ifndef SET_FULLSYNC
-# define SET_FULLSYNC(x,y)
-#endif
-
-/*
-** The default size of a disk sector
-*/
-#ifndef SQLITE_DEFAULT_SECTOR_SIZE
-# define SQLITE_DEFAULT_SECTOR_SIZE 4096
-#endif
-
-/*
-** Temporary files are named starting with this prefix followed by 16 random
-** alphanumeric characters, and no file extension. They are stored in the
-** OS's standard temporary file directory, and are deleted prior to exit.
-** If sqlite is being embedded in another program, you may wish to change the
-** prefix to reflect your program's name, so that if your program exits
-** prematurely, old temporary files can be easily identified. This can be done
-** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line.
-**
-** 2006-10-31: The default prefix used to be "sqlite_". But then
-** Mcafee started using SQLite in their anti-virus product and it
-** started putting files with the "sqlite" name in the c:/temp folder.
-** This annoyed many windows users. Those users would then do a
-** Google search for "sqlite", find the telephone numbers of the
-** developers and call to wake them up at night and complain.
-** For this reason, the default name prefix is changed to be "sqlite"
-** spelled backwards. So the temp files are still identified, but
-** anybody smart enough to figure out the code is also likely smart
-** enough to know that calling the developer will not help get rid
-** of the file.
-*/
-#ifndef SQLITE_TEMP_FILE_PREFIX
-# define SQLITE_TEMP_FILE_PREFIX "etilqs_"
-#endif
-
-/*
-** The following values may be passed as the second argument to
-** sqlite3OsLock(). The various locks exhibit the following semantics:
-**
-** SHARED: Any number of processes may hold a SHARED lock simultaneously.
-** RESERVED: A single process may hold a RESERVED lock on a file at
-** any time. Other processes may hold and obtain new SHARED locks.
-** PENDING: A single process may hold a PENDING lock on a file at
-** any one time. Existing SHARED locks may persist, but no new
-** SHARED locks may be obtained by other processes.
-** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks.
-**
-** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a
-** process that requests an EXCLUSIVE lock may actually obtain a PENDING
-** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to
-** sqlite3OsLock().
-*/
-#define NO_LOCK 0
-#define SHARED_LOCK 1
-#define RESERVED_LOCK 2
-#define PENDING_LOCK 3
-#define EXCLUSIVE_LOCK 4
-
-/*
-** File Locking Notes: (Mostly about windows but also some info for Unix)
-**
-** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
-** those functions are not available. So we use only LockFile() and
-** UnlockFile().
-**
-** LockFile() prevents not just writing but also reading by other processes.
-** A SHARED_LOCK is obtained by locking a single randomly-chosen
-** byte out of a specific range of bytes. The lock byte is obtained at
-** random so two separate readers can probably access the file at the
-** same time, unless they are unlucky and choose the same lock byte.
-** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range.
-** There can only be one writer. A RESERVED_LOCK is obtained by locking
-** a single byte of the file that is designated as the reserved lock byte.
-** A PENDING_LOCK is obtained by locking a designated byte different from
-** the RESERVED_LOCK byte.
-**
-** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
-** which means we can use reader/writer locks. When reader/writer locks
-** are used, the lock is placed on the same range of bytes that is used
-** for probabilistic locking in Win95/98/ME. Hence, the locking scheme
-** will support two or more Win95 readers or two or more WinNT readers.
-** But a single Win95 reader will lock out all WinNT readers and a single
-** WinNT reader will lock out all other Win95 readers.
-**
-** The following #defines specify the range of bytes used for locking.
-** SHARED_SIZE is the number of bytes available in the pool from which
-** a random byte is selected for a shared lock. The pool of bytes for
-** shared locks begins at SHARED_FIRST.
-**
-** The same locking strategy and
-** byte ranges are used for Unix. This leaves open the possiblity of having
-** clients on win95, winNT, and unix all talking to the same shared file
-** and all locking correctly. To do so would require that samba (or whatever
-** tool is being used for file sharing) implements locks correctly between
-** windows and unix. I'm guessing that isn't likely to happen, but by
-** using the same locking range we are at least open to the possibility.
-**
-** Locking in windows is manditory. For this reason, we cannot store
-** actual data in the bytes used for locking. The pager never allocates
-** the pages involved in locking therefore. SHARED_SIZE is selected so
-** that all locks will fit on a single page even at the minimum page size.
-** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE
-** is set high so that we don't have to allocate an unused page except
-** for very large databases. But one should test the page skipping logic
-** by setting PENDING_BYTE low and running the entire regression suite.
-**
-** Changing the value of PENDING_BYTE results in a subtly incompatible
-** file format. Depending on how it is changed, you might not notice
-** the incompatibility right away, even running a full regression test.
-** The default location of PENDING_BYTE is the first byte past the
-** 1GB boundary.
-**
-*/
-#ifdef SQLITE_OMIT_WSD
-# define PENDING_BYTE (0x40000000)
-#else
-# define PENDING_BYTE sqlite3PendingByte
-#endif
-#define RESERVED_BYTE (PENDING_BYTE+1)
-#define SHARED_FIRST (PENDING_BYTE+2)
-#define SHARED_SIZE 510
-
-/*
-** Wrapper around OS specific sqlite3_os_init() function.
-*/
-SQLITE_PRIVATE int sqlite3OsInit(void);
-
-/*
-** Functions for accessing sqlite3_file methods
-*/
-SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file*);
-SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
-SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
-SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size);
-SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int);
-SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize);
-SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int);
-SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int);
-SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut);
-SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*);
-SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*);
-#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
-SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id);
-SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
-SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
-SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
-SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id);
-SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int);
-
-
-/*
-** Functions for accessing sqlite3_vfs methods
-*/
-SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
-SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int);
-SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut);
-SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *);
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *);
-SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *);
-SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void);
-SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *);
-#endif /* SQLITE_OMIT_LOAD_EXTENSION */
-SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
-SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int);
-SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*);
-
-/*
-** Convenience functions for opening and closing files using
-** sqlite3_malloc() to obtain space for the file-handle structure.
-*/
-SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
-SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
-
-#endif /* _SQLITE_OS_H_ */
-
-/************** End of os.h **************************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-/************** Include mutex.h in the middle of sqliteInt.h *****************/
-/************** Begin file mutex.h *******************************************/
-/*
-** 2007 August 28
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains the common header for all mutex implementations.
-** The sqliteInt.h header #includes this file so that it is available
-** to all source files. We break it out in an effort to keep the code
-** better organized.
-**
-** NOTE: source files should *not* #include this header file directly.
-** Source files should #include the sqliteInt.h file and let that file
-** include this one indirectly.
-*/
-
-
-/*
-** Figure out what version of the code to use. The choices are
-**
-** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The
-** mutexes implemention cannot be overridden
-** at start-time.
-**
-** SQLITE_MUTEX_NOOP For single-threaded applications. No
-** mutual exclusion is provided. But this
-** implementation can be overridden at
-** start-time.
-**
-** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix.
-**
-** SQLITE_MUTEX_W32 For multi-threaded applications on Win32.
-*/
-#if !SQLITE_THREADSAFE
-# define SQLITE_MUTEX_OMIT
-#endif
-#if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP)
-# if SQLITE_OS_UNIX
-# define SQLITE_MUTEX_PTHREADS
-# elif SQLITE_OS_WIN
-# define SQLITE_MUTEX_W32
-# else
-# define SQLITE_MUTEX_NOOP
-# endif
-#endif
-
-#ifdef SQLITE_MUTEX_OMIT
-/*
-** If this is a no-op implementation, implement everything as macros.
-*/
-#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
-#define sqlite3_mutex_free(X)
-#define sqlite3_mutex_enter(X)
-#define sqlite3_mutex_try(X) SQLITE_OK
-#define sqlite3_mutex_leave(X)
-#define sqlite3_mutex_held(X) ((void)(X),1)
-#define sqlite3_mutex_notheld(X) ((void)(X),1)
-#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8)
-#define sqlite3MutexInit() SQLITE_OK
-#define sqlite3MutexEnd()
-#define MUTEX_LOGIC(X)
-#else
-#define MUTEX_LOGIC(X) X
-#endif /* defined(SQLITE_MUTEX_OMIT) */
-
-/************** End of mutex.h ***********************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-
-
-/*
-** Each database file to be accessed by the system is an instance
-** of the following structure. There are normally two of these structures
-** in the sqlite.aDb[] array. aDb[0] is the main database file and
-** aDb[1] is the database file used to hold temporary tables. Additional
-** databases may be attached.
-*/
-struct Db {
- char *zName; /* Name of this database */
- Btree *pBt; /* The B*Tree structure for this database file */
- u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
- u8 safety_level; /* How aggressive at syncing data to disk */
- Schema *pSchema; /* Pointer to database schema (possibly shared) */
-};
-
-/*
-** An instance of the following structure stores a database schema.
-**
-** Most Schema objects are associated with a Btree. The exception is
-** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing.
-** In shared cache mode, a single Schema object can be shared by multiple
-** Btrees that refer to the same underlying BtShared object.
-**
-** Schema objects are automatically deallocated when the last Btree that
-** references them is destroyed. The TEMP Schema is manually freed by
-** sqlite3_close().
-*
-** A thread must be holding a mutex on the corresponding Btree in order
-** to access Schema content. This implies that the thread must also be
-** holding a mutex on the sqlite3 connection pointer that owns the Btree.
-** For a TEMP Schema, only the connection mutex is required.
-*/
-struct Schema {
- int schema_cookie; /* Database schema version number for this file */
- int iGeneration; /* Generation counter. Incremented with each change */
- Hash tblHash; /* All tables indexed by name */
- Hash idxHash; /* All (named) indices indexed by name */
- Hash trigHash; /* All triggers indexed by name */
- Hash fkeyHash; /* All foreign keys by referenced table name */
- Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */
- u8 file_format; /* Schema format version for this file */
- u8 enc; /* Text encoding used by this database */
- u16 flags; /* Flags associated with this schema */
- int cache_size; /* Number of pages to use in the cache */
-};
-
-/*
-** These macros can be used to test, set, or clear bits in the
-** Db.pSchema->flags field.
-*/
-#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))==(P))
-#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->flags&(P))!=0)
-#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->flags|=(P)
-#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->flags&=~(P)
-
-/*
-** Allowed values for the DB.pSchema->flags field.
-**
-** The DB_SchemaLoaded flag is set after the database schema has been
-** read into internal hash tables.
-**
-** DB_UnresetViews means that one or more views have column names that
-** have been filled out. If the schema changes, these column names might
-** changes and so the view will need to be reset.
-*/
-#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */
-#define DB_UnresetViews 0x0002 /* Some views have defined column names */
-#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */
-
-/*
-** The number of different kinds of things that can be limited
-** using the sqlite3_limit() interface.
-*/
-#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1)
-
-/*
-** Lookaside malloc is a set of fixed-size buffers that can be used
-** to satisfy small transient memory allocation requests for objects
-** associated with a particular database connection. The use of
-** lookaside malloc provides a significant performance enhancement
-** (approx 10%) by avoiding numerous malloc/free requests while parsing
-** SQL statements.
-**
-** The Lookaside structure holds configuration information about the
-** lookaside malloc subsystem. Each available memory allocation in
-** the lookaside subsystem is stored on a linked list of LookasideSlot
-** objects.
-**
-** Lookaside allocations are only allowed for objects that are associated
-** with a particular database connection. Hence, schema information cannot
-** be stored in lookaside because in shared cache mode the schema information
-** is shared by multiple database connections. Therefore, while parsing
-** schema information, the Lookaside.bEnabled flag is cleared so that
-** lookaside allocations are not used to construct the schema objects.
-*/
-struct Lookaside {
- u16 sz; /* Size of each buffer in bytes */
- u8 bEnabled; /* False to disable new lookaside allocations */
- u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */
- int nOut; /* Number of buffers currently checked out */
- int mxOut; /* Highwater mark for nOut */
- int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */
- LookasideSlot *pFree; /* List of available buffers */
- void *pStart; /* First byte of available memory space */
- void *pEnd; /* First byte past end of available space */
-};
-struct LookasideSlot {
- LookasideSlot *pNext; /* Next buffer in the list of free buffers */
-};
-
-/*
-** A hash table for function definitions.
-**
-** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
-** Collisions are on the FuncDef.pHash chain.
-*/
-struct FuncDefHash {
- FuncDef *a[23]; /* Hash table for functions */
-};
-
-/*
-** Each database connection is an instance of the following structure.
-*/
-struct sqlite3 {
- sqlite3_vfs *pVfs; /* OS Interface */
- struct Vdbe *pVdbe; /* List of active virtual machines */
- CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
- sqlite3_mutex *mutex; /* Connection mutex */
- Db *aDb; /* All backends */
- int nDb; /* Number of backends currently in use */
- int flags; /* Miscellaneous flags. See below */
- i64 lastRowid; /* ROWID of most recent insert (see above) */
- unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
- int errCode; /* Most recent error code (SQLITE_*) */
- int errMask; /* & result codes with this before returning */
- u16 dbOptFlags; /* Flags to enable/disable optimizations */
- u8 autoCommit; /* The auto-commit flag. */
- u8 temp_store; /* 1: file 2: memory 0: default */
- u8 mallocFailed; /* True if we have seen a malloc failure */
- u8 dfltLockMode; /* Default locking-mode for attached dbs */
- signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */
- u8 suppressErr; /* Do not issue error messages if true */
- u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
- u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
- int nextPagesize; /* Pagesize after VACUUM if >0 */
- u32 magic; /* Magic number for detect library misuse */
- int nChange; /* Value returned by sqlite3_changes() */
- int nTotalChange; /* Value returned by sqlite3_total_changes() */
- int aLimit[SQLITE_N_LIMIT]; /* Limits */
- struct sqlite3InitInfo { /* Information used during initialization */
- int newTnum; /* Rootpage of table being initialized */
- u8 iDb; /* Which db file is being initialized */
- u8 busy; /* TRUE if currently initializing */
- u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
- } init;
- int activeVdbeCnt; /* Number of VDBEs currently executing */
- int writeVdbeCnt; /* Number of active VDBEs that are writing */
- int vdbeExecCnt; /* Number of nested calls to VdbeExec() */
- int nExtension; /* Number of loaded extensions */
- void **aExtension; /* Array of shared library handles */
- void (*xTrace)(void*,const char*); /* Trace function */
- void *pTraceArg; /* Argument to the trace function */
- void (*xProfile)(void*,const char*,u64); /* Profiling function */
- void *pProfileArg; /* Argument to profile function */
- void *pCommitArg; /* Argument to xCommitCallback() */
- int (*xCommitCallback)(void*); /* Invoked at every commit. */
- void *pRollbackArg; /* Argument to xRollbackCallback() */
- void (*xRollbackCallback)(void*); /* Invoked at every commit. */
- void *pUpdateArg;
- void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
-#ifndef SQLITE_OMIT_WAL
- int (*xWalCallback)(void *, sqlite3 *, const char *, int);
- void *pWalArg;
-#endif
- void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*);
- void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
- void *pCollNeededArg;
- sqlite3_value *pErr; /* Most recent error message */
- char *zErrMsg; /* Most recent error message (UTF-8 encoded) */
- char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */
- union {
- volatile int isInterrupted; /* True if sqlite3_interrupt has been called */
- double notUsed1; /* Spacer */
- } u1;
- Lookaside lookaside; /* Lookaside malloc configuration */
-#ifndef SQLITE_OMIT_AUTHORIZATION
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
- /* Access authorization function */
- void *pAuthArg; /* 1st argument to the access auth function */
-#endif
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- int (*xProgress)(void *); /* The progress callback */
- void *pProgressArg; /* Argument to the progress callback */
- int nProgressOps; /* Number of opcodes for progress callback */
-#endif
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- int nVTrans; /* Allocated size of aVTrans */
- Hash aModule; /* populated by sqlite3_create_module() */
- VtabCtx *pVtabCtx; /* Context for active vtab connect/create */
- VTable **aVTrans; /* Virtual tables with open transactions */
- VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
-#endif
- FuncDefHash aFunc; /* Hash table of connection functions */
- Hash aCollSeq; /* All collating sequences */
- BusyHandler busyHandler; /* Busy callback */
- Db aDbStatic[2]; /* Static space for the 2 default backends */
- Savepoint *pSavepoint; /* List of active savepoints */
- int busyTimeout; /* Busy handler timeout, in msec */
- int nSavepoint; /* Number of non-transaction savepoints */
- int nStatement; /* Number of nested statement-transactions */
- i64 nDeferredCons; /* Net deferred constraints this transaction. */
- int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
-
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
- /* The following variables are all protected by the STATIC_MASTER
- ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
- **
- ** When X.pUnlockConnection==Y, that means that X is waiting for Y to
- ** unlock so that it can proceed.
- **
- ** When X.pBlockingConnection==Y, that means that something that X tried
- ** tried to do recently failed with an SQLITE_LOCKED error due to locks
- ** held by Y.
- */
- sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */
- sqlite3 *pUnlockConnection; /* Connection to watch for unlock */
- void *pUnlockArg; /* Argument to xUnlockNotify */
- void (*xUnlockNotify)(void **, int); /* Unlock notify callback */
- sqlite3 *pNextBlocked; /* Next in list of all blocked connections */
-#endif
-};
-
-/*
-** A macro to discover the encoding of a database.
-*/
-#define ENC(db) ((db)->aDb[0].pSchema->enc)
-
-/*
-** Possible values for the sqlite3.flags.
-*/
-#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
-#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
-#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
-#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */
-#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */
- /* DELETE, or UPDATE and return */
- /* the count using a callback. */
-#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
- /* result set is empty */
-#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
-#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
-#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
- /* 0x00000200 Unused */
-#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
-#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
-#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
-#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
-#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
-#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */
-#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */
-#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */
-#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
-#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
-#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
-#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
-#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
-
-/*
-** Bits of the sqlite3.dbOptFlags field that are used by the
-** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
-** selectively disable various optimizations.
-*/
-#define SQLITE_QueryFlattener 0x0001 /* Query flattening */
-#define SQLITE_ColumnCache 0x0002 /* Column cache */
-#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */
-#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */
-#define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */
-#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */
-#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */
-#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */
-#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */
-#define SQLITE_AllOpts 0xffff /* All optimizations */
-
-/*
-** Macros for testing whether or not optimizations are enabled or disabled.
-*/
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0)
-#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0)
-#else
-#define OptimizationDisabled(db, mask) 0
-#define OptimizationEnabled(db, mask) 1
-#endif
-
-/*
-** Possible values for the sqlite.magic field.
-** The numbers are obtained at random and have no special meaning, other
-** than being distinct from one another.
-*/
-#define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */
-#define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */
-#define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */
-#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */
-#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */
-#define SQLITE_MAGIC_ZOMBIE 0x64cffc7f /* Close with last statement close */
-
-/*
-** Each SQL function is defined by an instance of the following
-** structure. A pointer to this structure is stored in the sqlite.aFunc
-** hash table. When multiple functions have the same name, the hash table
-** points to a linked list of these structures.
-*/
-struct FuncDef {
- i16 nArg; /* Number of arguments. -1 means unlimited */
- u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */
- u8 flags; /* Some combination of SQLITE_FUNC_* */
- void *pUserData; /* User data parameter */
- FuncDef *pNext; /* Next function with same name */
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
- void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
- void (*xFinalize)(sqlite3_context*); /* Aggregate finalizer */
- char *zName; /* SQL name of the function. */
- FuncDef *pHash; /* Next with a different name but the same hash */
- FuncDestructor *pDestructor; /* Reference counted destructor function */
-};
-
-/*
-** This structure encapsulates a user-function destructor callback (as
-** configured using create_function_v2()) and a reference counter. When
-** create_function_v2() is called to create a function with a destructor,
-** a single object of this type is allocated. FuncDestructor.nRef is set to
-** the number of FuncDef objects created (either 1 or 3, depending on whether
-** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor
-** member of each of the new FuncDef objects is set to point to the allocated
-** FuncDestructor.
-**
-** Thereafter, when one of the FuncDef objects is deleted, the reference
-** count on this object is decremented. When it reaches 0, the destructor
-** is invoked and the FuncDestructor structure freed.
-*/
-struct FuncDestructor {
- int nRef;
- void (*xDestroy)(void *);
- void *pUserData;
-};
-
-/*
-** Possible values for FuncDef.flags. Note that the _LENGTH and _TYPEOF
-** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. There
-** are assert() statements in the code to verify this.
-*/
-#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */
-#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */
-#define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */
-#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */
-#define SQLITE_FUNC_COUNT 0x10 /* Built-in count(*) aggregate */
-#define SQLITE_FUNC_COALESCE 0x20 /* Built-in coalesce() or ifnull() function */
-#define SQLITE_FUNC_LENGTH 0x40 /* Built-in length() function */
-#define SQLITE_FUNC_TYPEOF 0x80 /* Built-in typeof() function */
-
-/*
-** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
-** used to create the initializers for the FuncDef structures.
-**
-** FUNCTION(zName, nArg, iArg, bNC, xFunc)
-** Used to create a scalar function definition of a function zName
-** implemented by C function xFunc that accepts nArg arguments. The
-** value passed as iArg is cast to a (void*) and made available
-** as the user-data (sqlite3_user_data()) for the function. If
-** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
-**
-** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
-** Used to create an aggregate function definition implemented by
-** the C functions xStep and xFinal. The first four parameters
-** are interpreted in the same way as the first 4 parameters to
-** FUNCTION().
-**
-** LIKEFUNC(zName, nArg, pArg, flags)
-** Used to create a scalar function definition of a function zName
-** that accepts nArg arguments and is implemented by a call to C
-** function likeFunc. Argument pArg is cast to a (void *) and made
-** available as the function user-data (sqlite3_user_data()). The
-** FuncDef.flags variable is set to the value passed as the flags
-** parameter.
-*/
-#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, (bNC*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
-#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
- {nArg, SQLITE_UTF8, (bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
-#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
- pArg, 0, xFunc, 0, 0, #zName, 0, 0}
-#define LIKEFUNC(zName, nArg, arg, flags) \
- {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0}
-#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
- {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \
- SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
-
-/*
-** All current savepoints are stored in a linked list starting at
-** sqlite3.pSavepoint. The first element in the list is the most recently
-** opened savepoint. Savepoints are added to the list by the vdbe
-** OP_Savepoint instruction.
-*/
-struct Savepoint {
- char *zName; /* Savepoint name (nul-terminated) */
- i64 nDeferredCons; /* Number of deferred fk violations */
- Savepoint *pNext; /* Parent savepoint (if any) */
-};
-
-/*
-** The following are used as the second parameter to sqlite3Savepoint(),
-** and as the P1 argument to the OP_Savepoint instruction.
-*/
-#define SAVEPOINT_BEGIN 0
-#define SAVEPOINT_RELEASE 1
-#define SAVEPOINT_ROLLBACK 2
-
-
-/*
-** Each SQLite module (virtual table definition) is defined by an
-** instance of the following structure, stored in the sqlite3.aModule
-** hash table.
-*/
-struct Module {
- const sqlite3_module *pModule; /* Callback pointers */
- const char *zName; /* Name passed to create_module() */
- void *pAux; /* pAux passed to create_module() */
- void (*xDestroy)(void *); /* Module destructor function */
-};
-
-/*
-** information about each column of an SQL table is held in an instance
-** of this structure.
-*/
-struct Column {
- char *zName; /* Name of this column */
- Expr *pDflt; /* Default value of this column */
- char *zDflt; /* Original text of the default value */
- char *zType; /* Data type for this column */
- char *zColl; /* Collating sequence. If NULL, use the default */
- u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
- char affinity; /* One of the SQLITE_AFF_... values */
- u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */
-};
-
-/* Allowed values for Column.colFlags:
-*/
-#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */
-#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */
-
-/*
-** A "Collating Sequence" is defined by an instance of the following
-** structure. Conceptually, a collating sequence consists of a name and
-** a comparison routine that defines the order of that sequence.
-**
-** If CollSeq.xCmp is NULL, it means that the
-** collating sequence is undefined. Indices built on an undefined
-** collating sequence may not be read or written.
-*/
-struct CollSeq {
- char *zName; /* Name of the collating sequence, UTF-8 encoded */
- u8 enc; /* Text encoding handled by xCmp() */
- void *pUser; /* First argument to xCmp() */
- int (*xCmp)(void*,int, const void*, int, const void*);
- void (*xDel)(void*); /* Destructor for pUser */
-};
-
-/*
-** A sort order can be either ASC or DESC.
-*/
-#define SQLITE_SO_ASC 0 /* Sort in ascending order */
-#define SQLITE_SO_DESC 1 /* Sort in ascending order */
-
-/*
-** Column affinity types.
-**
-** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
-** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve
-** the speed a little by numbering the values consecutively.
-**
-** But rather than start with 0 or 1, we begin with 'a'. That way,
-** when multiple affinity types are concatenated into a string and
-** used as the P4 operand, they will be more readable.
-**
-** Note also that the numeric types are grouped together so that testing
-** for a numeric type is a single comparison.
-*/
-#define SQLITE_AFF_TEXT 'a'
-#define SQLITE_AFF_NONE 'b'
-#define SQLITE_AFF_NUMERIC 'c'
-#define SQLITE_AFF_INTEGER 'd'
-#define SQLITE_AFF_REAL 'e'
-
-#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC)
-
-/*
-** The SQLITE_AFF_MASK values masks off the significant bits of an
-** affinity value.
-*/
-#define SQLITE_AFF_MASK 0x67
-
-/*
-** Additional bit values that can be ORed with an affinity without
-** changing the affinity.
-*/
-#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */
-#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */
-#define SQLITE_NULLEQ 0x80 /* NULL=NULL */
-
-/*
-** An object of this type is created for each virtual table present in
-** the database schema.
-**
-** If the database schema is shared, then there is one instance of this
-** structure for each database connection (sqlite3*) that uses the shared
-** schema. This is because each database connection requires its own unique
-** instance of the sqlite3_vtab* handle used to access the virtual table
-** implementation. sqlite3_vtab* handles can not be shared between
-** database connections, even when the rest of the in-memory database
-** schema is shared, as the implementation often stores the database
-** connection handle passed to it via the xConnect() or xCreate() method
-** during initialization internally. This database connection handle may
-** then be used by the virtual table implementation to access real tables
-** within the database. So that they appear as part of the callers
-** transaction, these accesses need to be made via the same database
-** connection as that used to execute SQL operations on the virtual table.
-**
-** All VTable objects that correspond to a single table in a shared
-** database schema are initially stored in a linked-list pointed to by
-** the Table.pVTable member variable of the corresponding Table object.
-** When an sqlite3_prepare() operation is required to access the virtual
-** table, it searches the list for the VTable that corresponds to the
-** database connection doing the preparing so as to use the correct
-** sqlite3_vtab* handle in the compiled query.
-**
-** When an in-memory Table object is deleted (for example when the
-** schema is being reloaded for some reason), the VTable objects are not
-** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
-** immediately. Instead, they are moved from the Table.pVTable list to
-** another linked list headed by the sqlite3.pDisconnect member of the
-** corresponding sqlite3 structure. They are then deleted/xDisconnected
-** next time a statement is prepared using said sqlite3*. This is done
-** to avoid deadlock issues involving multiple sqlite3.mutex mutexes.
-** Refer to comments above function sqlite3VtabUnlockList() for an
-** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect
-** list without holding the corresponding sqlite3.mutex mutex.
-**
-** The memory for objects of this type is always allocated by
-** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
-** the first argument.
-*/
-struct VTable {
- sqlite3 *db; /* Database connection associated with this table */
- Module *pMod; /* Pointer to module implementation */
- sqlite3_vtab *pVtab; /* Pointer to vtab instance */
- int nRef; /* Number of pointers to this structure */
- u8 bConstraint; /* True if constraints are supported */
- int iSavepoint; /* Depth of the SAVEPOINT stack */
- VTable *pNext; /* Next in linked list (see above) */
-};
-
-/*
-** Each SQL table is represented in memory by an instance of the
-** following structure.
-**
-** Table.zName is the name of the table. The case of the original
-** CREATE TABLE statement is stored, but case is not significant for
-** comparisons.
-**
-** Table.nCol is the number of columns in this table. Table.aCol is a
-** pointer to an array of Column structures, one for each column.
-**
-** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
-** the column that is that key. Otherwise Table.iPKey is negative. Note
-** that the datatype of the PRIMARY KEY must be INTEGER for this field to
-** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of
-** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid
-** is generated for each row of the table. TF_HasPrimaryKey is set if
-** the table has any PRIMARY KEY, INTEGER or otherwise.
-**
-** Table.tnum is the page number for the root BTree page of the table in the
-** database file. If Table.iDb is the index of the database table backend
-** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that
-** holds temporary tables and indices. If TF_Ephemeral is set
-** then the table is stored in a file that is automatically deleted
-** when the VDBE cursor to the table is closed. In this case Table.tnum
-** refers VDBE cursor number that holds the table open, not to the root
-** page number. Transient tables are used to hold the results of a
-** sub-query that appears instead of a real table name in the FROM clause
-** of a SELECT statement.
-*/
-struct Table {
- char *zName; /* Name of the table or view */
- Column *aCol; /* Information about each column */
- Index *pIndex; /* List of SQL indexes on this table. */
- Select *pSelect; /* NULL for tables. Points to definition if a view. */
- FKey *pFKey; /* Linked list of all foreign keys in this table */
- char *zColAff; /* String defining the affinity of each column */
-#ifndef SQLITE_OMIT_CHECK
- ExprList *pCheck; /* All CHECK constraints */
-#endif
- tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
- int tnum; /* Root BTree node for this table (see note above) */
- i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */
- i16 nCol; /* Number of columns in this table */
- u16 nRef; /* Number of pointers to this Table */
- u8 tabFlags; /* Mask of TF_* values */
- u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
-#ifndef SQLITE_OMIT_ALTERTABLE
- int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
-#endif
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- int nModuleArg; /* Number of arguments to the module */
- char **azModuleArg; /* Text of all module args. [0] is module name */
- VTable *pVTable; /* List of VTable objects. */
-#endif
- Trigger *pTrigger; /* List of triggers stored in pSchema */
- Schema *pSchema; /* Schema that contains this table */
- Table *pNextZombie; /* Next on the Parse.pZombieTab list */
-};
-
-/*
-** Allowed values for Tabe.tabFlags.
-*/
-#define TF_Readonly 0x01 /* Read-only system table */
-#define TF_Ephemeral 0x02 /* An ephemeral table */
-#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
-#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
-#define TF_Virtual 0x10 /* Is a virtual table */
-
-
-/*
-** Test to see whether or not a table is a virtual table. This is
-** done as a macro so that it will be optimized out when virtual
-** table support is omitted from the build.
-*/
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
-# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
-#else
-# define IsVirtual(X) 0
-# define IsHiddenColumn(X) 0
-#endif
-
-/*
-** Each foreign key constraint is an instance of the following structure.
-**
-** A foreign key is associated with two tables. The "from" table is
-** the table that contains the REFERENCES clause that creates the foreign
-** key. The "to" table is the table that is named in the REFERENCES clause.
-** Consider this example:
-**
-** CREATE TABLE ex1(
-** a INTEGER PRIMARY KEY,
-** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x)
-** );
-**
-** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
-**
-** Each REFERENCES clause generates an instance of the following structure
-** which is attached to the from-table. The to-table need not exist when
-** the from-table is created. The existence of the to-table is not checked.
-*/
-struct FKey {
- Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */
- FKey *pNextFrom; /* Next foreign key in pFrom */
- char *zTo; /* Name of table that the key points to (aka: Parent) */
- FKey *pNextTo; /* Next foreign key on table named zTo */
- FKey *pPrevTo; /* Previous foreign key on table named zTo */
- int nCol; /* Number of columns in this key */
- /* EV: R-30323-21917 */
- u8 isDeferred; /* True if constraint checking is deferred till COMMIT */
- u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */
- Trigger *apTrigger[2]; /* Triggers for aAction[] actions */
- struct sColMap { /* Mapping of columns in pFrom to columns in zTo */
- int iFrom; /* Index of column in pFrom */
- char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */
- } aCol[1]; /* One entry for each of nCol column s */
-};
-
-/*
-** SQLite supports many different ways to resolve a constraint
-** error. ROLLBACK processing means that a constraint violation
-** causes the operation in process to fail and for the current transaction
-** to be rolled back. ABORT processing means the operation in process
-** fails and any prior changes from that one operation are backed out,
-** but the transaction is not rolled back. FAIL processing means that
-** the operation in progress stops and returns an error code. But prior
-** changes due to the same operation are not backed out and no rollback
-** occurs. IGNORE means that the particular row that caused the constraint
-** error is not inserted or updated. Processing continues and no error
-** is returned. REPLACE means that preexisting database rows that caused
-** a UNIQUE constraint violation are removed so that the new insert or
-** update can proceed. Processing continues and no error is reported.
-**
-** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys.
-** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the
-** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign
-** key is set to NULL. CASCADE means that a DELETE or UPDATE of the
-** referenced table row is propagated into the row that holds the
-** foreign key.
-**
-** The following symbolic values are used to record which type
-** of action to take.
-*/
-#define OE_None 0 /* There is no constraint to check */
-#define OE_Rollback 1 /* Fail the operation and rollback the transaction */
-#define OE_Abort 2 /* Back out changes but do no rollback transaction */
-#define OE_Fail 3 /* Stop the operation but leave all prior changes */
-#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */
-#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */
-
-#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
-#define OE_SetNull 7 /* Set the foreign key value to NULL */
-#define OE_SetDflt 8 /* Set the foreign key value to its default */
-#define OE_Cascade 9 /* Cascade the changes */
-
-#define OE_Default 99 /* Do whatever the default action is */
-
-
-/*
-** An instance of the following structure is passed as the first
-** argument to sqlite3VdbeKeyCompare and is used to control the
-** comparison of the two index keys.
-*/
-struct KeyInfo {
- sqlite3 *db; /* The database connection */
- u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
- u16 nField; /* Number of entries in aColl[] */
- u8 *aSortOrder; /* Sort order for each column. May be NULL */
- CollSeq *aColl[1]; /* Collating sequence for each term of the key */
-};
-
-/*
-** An instance of the following structure holds information about a
-** single index record that has already been parsed out into individual
-** values.
-**
-** A record is an object that contains one or more fields of data.
-** Records are used to store the content of a table row and to store
-** the key of an index. A blob encoding of a record is created by
-** the OP_MakeRecord opcode of the VDBE and is disassembled by the
-** OP_Column opcode.
-**
-** This structure holds a record that has already been disassembled
-** into its constituent fields.
-*/
-struct UnpackedRecord {
- KeyInfo *pKeyInfo; /* Collation and sort-order information */
- u16 nField; /* Number of entries in apMem[] */
- u8 flags; /* Boolean settings. UNPACKED_... below */
- i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */
- Mem *aMem; /* Values */
-};
-
-/*
-** Allowed values of UnpackedRecord.flags
-*/
-#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */
-#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */
-#define UNPACKED_PREFIX_SEARCH 0x04 /* Ignore final (rowid) field */
-
-/*
-** Each SQL index is represented in memory by an
-** instance of the following structure.
-**
-** The columns of the table that are to be indexed are described
-** by the aiColumn[] field of this structure. For example, suppose
-** we have the following table and index:
-**
-** CREATE TABLE Ex1(c1 int, c2 int, c3 text);
-** CREATE INDEX Ex2 ON Ex1(c3,c1);
-**
-** In the Table structure describing Ex1, nCol==3 because there are
-** three columns in the table. In the Index structure describing
-** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
-** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
-** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
-** The second column to be indexed (c1) has an index of 0 in
-** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
-**
-** The Index.onError field determines whether or not the indexed columns
-** must be unique and what to do if they are not. When Index.onError=OE_None,
-** it means this is not a unique index. Otherwise it is a unique index
-** and the value of Index.onError indicate the which conflict resolution
-** algorithm to employ whenever an attempt is made to insert a non-unique
-** element.
-*/
-struct Index {
- char *zName; /* Name of this index */
- int *aiColumn; /* Which columns are used by this index. 1st is 0 */
- tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
- Table *pTable; /* The SQL table being indexed */
- char *zColAff; /* String defining the affinity of each column */
- Index *pNext; /* The next index associated with the same table */
- Schema *pSchema; /* Schema containing this index */
- u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
- char **azColl; /* Array of collation sequence names for index */
- int nColumn; /* Number of columns in the table used by this index */
- int tnum; /* Page containing root of this index in database file */
- u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
- u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
- u8 bUnordered; /* Use this index for == or IN queries only */
-#ifdef SQLITE_ENABLE_STAT3
- int nSample; /* Number of elements in aSample[] */
- tRowcnt avgEq; /* Average nEq value for key values not in aSample */
- IndexSample *aSample; /* Samples of the left-most key */
-#endif
-};
-
-/*
-** Each sample stored in the sqlite_stat3 table is represented in memory
-** using a structure of this type. See documentation at the top of the
-** analyze.c source file for additional information.
-*/
-struct IndexSample {
- union {
- char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
- double r; /* Value if eType is SQLITE_FLOAT */
- i64 i; /* Value if eType is SQLITE_INTEGER */
- } u;
- u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
- int nByte; /* Size in byte of text or blob. */
- tRowcnt nEq; /* Est. number of rows where the key equals this sample */
- tRowcnt nLt; /* Est. number of rows where key is less than this sample */
- tRowcnt nDLt; /* Est. number of distinct keys less than this sample */
-};
-
-/*
-** Each token coming out of the lexer is an instance of
-** this structure. Tokens are also used as part of an expression.
-**
-** Note if Token.z==0 then Token.dyn and Token.n are undefined and
-** may contain random values. Do not make any assumptions about Token.dyn
-** and Token.n when Token.z==0.
-*/
-struct Token {
- const char *z; /* Text of the token. Not NULL-terminated! */
- unsigned int n; /* Number of characters in this token */
-};
-
-/*
-** An instance of this structure contains information needed to generate
-** code for a SELECT that contains aggregate functions.
-**
-** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
-** pointer to this structure. The Expr.iColumn field is the index in
-** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
-** code for that node.
-**
-** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the
-** original Select structure that describes the SELECT statement. These
-** fields do not need to be freed when deallocating the AggInfo structure.
-*/
-struct AggInfo {
- u8 directMode; /* Direct rendering mode means take data directly
- ** from source tables rather than from accumulators */
- u8 useSortingIdx; /* In direct mode, reference the sorting index rather
- ** than the source table */
- int sortingIdx; /* Cursor number of the sorting index */
- int sortingIdxPTab; /* Cursor number of pseudo-table */
- int nSortingColumn; /* Number of columns in the sorting index */
- ExprList *pGroupBy; /* The group by clause */
- struct AggInfo_col { /* For each column used in source tables */
- Table *pTab; /* Source table */
- int iTable; /* Cursor number of the source table */
- int iColumn; /* Column number within the source table */
- int iSorterColumn; /* Column number in the sorting index */
- int iMem; /* Memory location that acts as accumulator */
- Expr *pExpr; /* The original expression */
- } *aCol;
- int nColumn; /* Number of used entries in aCol[] */
- int nAccumulator; /* Number of columns that show through to the output.
- ** Additional columns are used only as parameters to
- ** aggregate functions */
- struct AggInfo_func { /* For each aggregate function */
- Expr *pExpr; /* Expression encoding the function */
- FuncDef *pFunc; /* The aggregate function implementation */
- int iMem; /* Memory location that acts as accumulator */
- int iDistinct; /* Ephemeral table used to enforce DISTINCT */
- } *aFunc;
- int nFunc; /* Number of entries in aFunc[] */
-};
-
-/*
-** The datatype ynVar is a signed integer, either 16-bit or 32-bit.
-** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater
-** than 32767 we have to make it 32-bit. 16-bit is preferred because
-** it uses less memory in the Expr object, which is a big memory user
-** in systems with lots of prepared statements. And few applications
-** need more than about 10 or 20 variables. But some extreme users want
-** to have prepared statements with over 32767 variables, and for them
-** the option is available (at compile-time).
-*/
-#if SQLITE_MAX_VARIABLE_NUMBER<=32767
-typedef i16 ynVar;
-#else
-typedef int ynVar;
-#endif
-
-/*
-** Each node of an expression in the parse tree is an instance
-** of this structure.
-**
-** Expr.op is the opcode. The integer parser token codes are reused
-** as opcodes here. For example, the parser defines TK_GE to be an integer
-** code representing the ">=" operator. This same integer code is reused
-** to represent the greater-than-or-equal-to operator in the expression
-** tree.
-**
-** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
-** or TK_STRING), then Expr.token contains the text of the SQL literal. If
-** the expression is a variable (TK_VARIABLE), then Expr.token contains the
-** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
-** then Expr.token contains the name of the function.
-**
-** Expr.pRight and Expr.pLeft are the left and right subexpressions of a
-** binary operator. Either or both may be NULL.
-**
-** Expr.x.pList is a list of arguments if the expression is an SQL function,
-** a CASE expression or an IN expression of the form "<lhs> IN (<y>, <z>...)".
-** Expr.x.pSelect is used if the expression is a sub-select or an expression of
-** the form "<lhs> IN (SELECT ...)". If the EP_xIsSelect bit is set in the
-** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
-** valid.
-**
-** An expression of the form ID or ID.ID refers to a column in a table.
-** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is
-** the integer cursor number of a VDBE cursor pointing to that table and
-** Expr.iColumn is the column number for the specific column. If the
-** expression is used as a result in an aggregate SELECT, then the
-** value is also stored in the Expr.iAgg column in the aggregate so that
-** it can be accessed after all aggregates are computed.
-**
-** If the expression is an unbound variable marker (a question mark
-** character '?' in the original SQL) then the Expr.iTable holds the index
-** number for that variable.
-**
-** If the expression is a subquery then Expr.iColumn holds an integer
-** register number containing the result of the subquery. If the
-** subquery gives a constant result, then iTable is -1. If the subquery
-** gives a different answer at different times during statement processing
-** then iTable is the address of a subroutine that computes the subquery.
-**
-** If the Expr is of type OP_Column, and the table it is selecting from
-** is a disk table or the "old.*" pseudo-table, then pTab points to the
-** corresponding table definition.
-**
-** ALLOCATION NOTES:
-**
-** Expr objects can use a lot of memory space in database schema. To
-** help reduce memory requirements, sometimes an Expr object will be
-** truncated. And to reduce the number of memory allocations, sometimes
-** two or more Expr objects will be stored in a single memory allocation,
-** together with Expr.zToken strings.
-**
-** If the EP_Reduced and EP_TokenOnly flags are set when
-** an Expr object is truncated. When EP_Reduced is set, then all
-** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
-** are contained within the same memory allocation. Note, however, that
-** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately
-** allocated, regardless of whether or not EP_Reduced is set.
-*/
-struct Expr {
- u8 op; /* Operation performed by this node */
- char affinity; /* The affinity of the column or 0 if not a column */
- u16 flags; /* Various flags. EP_* See below */
- union {
- char *zToken; /* Token value. Zero terminated and dequoted */
- int iValue; /* Non-negative integer value if EP_IntValue */
- } u;
-
- /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
- ** space is allocated for the fields below this point. An attempt to
- ** access them will result in a segfault or malfunction.
- *********************************************************************/
-
- Expr *pLeft; /* Left subnode */
- Expr *pRight; /* Right subnode */
- union {
- ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
- Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
- } x;
-
- /* If the EP_Reduced flag is set in the Expr.flags mask, then no
- ** space is allocated for the fields below this point. An attempt to
- ** access them will result in a segfault or malfunction.
- *********************************************************************/
-
-#if SQLITE_MAX_EXPR_DEPTH>0
- int nHeight; /* Height of the tree headed by this node */
-#endif
- int iTable; /* TK_COLUMN: cursor number of table holding column
- ** TK_REGISTER: register number
- ** TK_TRIGGER: 1 -> new, 0 -> old */
- ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
- ** TK_VARIABLE: variable number (always >= 1). */
- i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
- i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
- u8 flags2; /* Second set of flags. EP2_... */
- u8 op2; /* TK_REGISTER: original value of Expr.op
- ** TK_COLUMN: the value of p5 for OP_Column
- ** TK_AGG_FUNCTION: nesting depth */
- AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
- Table *pTab; /* Table for TK_COLUMN expressions. */
-};
-
-/*
-** The following are the meanings of bits in the Expr.flags field.
-*/
-#define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */
-#define EP_Agg 0x0002 /* Contains one or more aggregate functions */
-#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */
-#define EP_Error 0x0008 /* Expression contains one or more errors */
-#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
-#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
-#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
-#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
-#define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */
-#define EP_FixedDest 0x0200 /* Result needed in a specific register */
-#define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
-#define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
-#define EP_Hint 0x1000 /* Not used */
-#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
-#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
-#define EP_Static 0x8000 /* Held in memory not obtained from malloc() */
-
-/*
-** The following are the meanings of bits in the Expr.flags2 field.
-*/
-#define EP2_MallocedToken 0x0001 /* Need to sqlite3DbFree() Expr.zToken */
-#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */
-
-/*
-** The pseudo-routine sqlite3ExprSetIrreducible sets the EP2_Irreducible
-** flag on an expression structure. This flag is used for VV&A only. The
-** routine is implemented as a macro that only works when in debugging mode,
-** so as not to burden production code.
-*/
-#ifdef SQLITE_DEBUG
-# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible
-#else
-# define ExprSetIrreducible(X)
-#endif
-
-/*
-** These macros can be used to test, set, or clear bits in the
-** Expr.flags field.
-*/
-#define ExprHasProperty(E,P) (((E)->flags&(P))==(P))
-#define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0)
-#define ExprSetProperty(E,P) (E)->flags|=(P)
-#define ExprClearProperty(E,P) (E)->flags&=~(P)
-
-/*
-** Macros to determine the number of bytes required by a normal Expr
-** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
-** and an Expr struct with the EP_TokenOnly flag set.
-*/
-#define EXPR_FULLSIZE sizeof(Expr) /* Full size */
-#define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */
-#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */
-
-/*
-** Flags passed to the sqlite3ExprDup() function. See the header comment
-** above sqlite3ExprDup() for details.
-*/
-#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
-
-/*
-** A list of expressions. Each expression may optionally have a
-** name. An expr/name combination can be used in several ways, such
-** as the list of "expr AS ID" fields following a "SELECT" or in the
-** list of "ID = expr" items in an UPDATE. A list of expressions can
-** also be used as the argument to a function, in which case the a.zName
-** field is not used.
-*/
-struct ExprList {
- int nExpr; /* Number of expressions on the list */
- int iECursor; /* VDBE Cursor associated with this ExprList */
- struct ExprList_item { /* For each expression in the list */
- Expr *pExpr; /* The list of expressions */
- char *zName; /* Token associated with this expression */
- char *zSpan; /* Original text of the expression */
- u8 sortOrder; /* 1 for DESC or 0 for ASC */
- u8 done; /* A flag to indicate when processing is finished */
- u16 iOrderByCol; /* For ORDER BY, column number in result set */
- u16 iAlias; /* Index into Parse.aAlias[] for zName */
- } *a; /* Alloc a power of two greater or equal to nExpr */
-};
-
-/*
-** An instance of this structure is used by the parser to record both
-** the parse tree for an expression and the span of input text for an
-** expression.
-*/
-struct ExprSpan {
- Expr *pExpr; /* The expression parse tree */
- const char *zStart; /* First character of input text */
- const char *zEnd; /* One character past the end of input text */
-};
-
-/*
-** An instance of this structure can hold a simple list of identifiers,
-** such as the list "a,b,c" in the following statements:
-**
-** INSERT INTO t(a,b,c) VALUES ...;
-** CREATE INDEX idx ON t(a,b,c);
-** CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...;
-**
-** The IdList.a.idx field is used when the IdList represents the list of
-** column names after a table name in an INSERT statement. In the statement
-**
-** INSERT INTO t(a,b,c) ...
-**
-** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
-*/
-struct IdList {
- struct IdList_item {
- char *zName; /* Name of the identifier */
- int idx; /* Index in some Table.aCol[] of a column named zName */
- } *a;
- int nId; /* Number of identifiers on the list */
-};
-
-/*
-** The bitmask datatype defined below is used for various optimizations.
-**
-** Changing this from a 64-bit to a 32-bit type limits the number of
-** tables in a join to 32 instead of 64. But it also reduces the size
-** of the library by 738 bytes on ix86.
-*/
-typedef u64 Bitmask;
-
-/*
-** The number of bits in a Bitmask. "BMS" means "BitMask Size".
-*/
-#define BMS ((int)(sizeof(Bitmask)*8))
-
-/*
-** The following structure describes the FROM clause of a SELECT statement.
-** Each table or subquery in the FROM clause is a separate element of
-** the SrcList.a[] array.
-**
-** With the addition of multiple database support, the following structure
-** can also be used to describe a particular table such as the table that
-** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL,
-** such a table must be a simple name: ID. But in SQLite, the table can
-** now be identified by a database name, a dot, then the table name: ID.ID.
-**
-** The jointype starts out showing the join type between the current table
-** and the next table on the list. The parser builds the list this way.
-** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each
-** jointype expresses the join between the table and the previous table.
-**
-** In the colUsed field, the high-order bit (bit 63) is set if the table
-** contains more than 63 columns and the 64-th or later column is used.
-*/
-struct SrcList {
- i16 nSrc; /* Number of tables or subqueries in the FROM clause */
- i16 nAlloc; /* Number of entries allocated in a[] below */
- struct SrcList_item {
- Schema *pSchema; /* Schema to which this item is fixed */
- char *zDatabase; /* Name of database holding this table */
- char *zName; /* Name of the table */
- char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
- Table *pTab; /* An SQL table corresponding to zName */
- Select *pSelect; /* A SELECT statement used in place of a table name */
- int addrFillSub; /* Address of subroutine to manifest a subquery */
- int regReturn; /* Register holding return address of addrFillSub */
- u8 jointype; /* Type of join between this able and the previous */
- unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
- unsigned isCorrelated :1; /* True if sub-query is correlated */
- unsigned viaCoroutine :1; /* Implemented as a co-routine */
-#ifndef SQLITE_OMIT_EXPLAIN
- u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */
-#endif
- int iCursor; /* The VDBE cursor number used to access this table */
- Expr *pOn; /* The ON clause of a join */
- IdList *pUsing; /* The USING clause of a join */
- Bitmask colUsed; /* Bit N (1<<N) set if column N of pTab is used */
- char *zIndex; /* Identifier from "INDEXED BY <zIndex>" clause */
- Index *pIndex; /* Index structure corresponding to zIndex, if any */
- } a[1]; /* One entry for each identifier on the list */
-};
-
-/*
-** Permitted values of the SrcList.a.jointype field
-*/
-#define JT_INNER 0x0001 /* Any kind of inner or cross join */
-#define JT_CROSS 0x0002 /* Explicit use of the CROSS keyword */
-#define JT_NATURAL 0x0004 /* True for a "natural" join */
-#define JT_LEFT 0x0008 /* Left outer join */
-#define JT_RIGHT 0x0010 /* Right outer join */
-#define JT_OUTER 0x0020 /* The "OUTER" keyword is present */
-#define JT_ERROR 0x0040 /* unknown or unsupported join type */
-
-
-/*
-** A WherePlan object holds information that describes a lookup
-** strategy.
-**
-** This object is intended to be opaque outside of the where.c module.
-** It is included here only so that that compiler will know how big it
-** is. None of the fields in this object should be used outside of
-** the where.c module.
-**
-** Within the union, pIdx is only used when wsFlags&WHERE_INDEXED is true.
-** pTerm is only used when wsFlags&WHERE_MULTI_OR is true. And pVtabIdx
-** is only used when wsFlags&WHERE_VIRTUALTABLE is true. It is never the
-** case that more than one of these conditions is true.
-*/
-struct WherePlan {
- u32 wsFlags; /* WHERE_* flags that describe the strategy */
- u16 nEq; /* Number of == constraints */
- u16 nOBSat; /* Number of ORDER BY terms satisfied */
- double nRow; /* Estimated number of rows (for EQP) */
- union {
- Index *pIdx; /* Index when WHERE_INDEXED is true */
- struct WhereTerm *pTerm; /* WHERE clause term for OR-search */
- sqlite3_index_info *pVtabIdx; /* Virtual table index to use */
- } u;
-};
-
-/*
-** For each nested loop in a WHERE clause implementation, the WhereInfo
-** structure contains a single instance of this structure. This structure
-** is intended to be private to the where.c module and should not be
-** access or modified by other modules.
-**
-** The pIdxInfo field is used to help pick the best index on a
-** virtual table. The pIdxInfo pointer contains indexing
-** information for the i-th table in the FROM clause before reordering.
-** All the pIdxInfo pointers are freed by whereInfoFree() in where.c.
-** All other information in the i-th WhereLevel object for the i-th table
-** after FROM clause ordering.
-*/
-struct WhereLevel {
- WherePlan plan; /* query plan for this element of the FROM clause */
- int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
- int iTabCur; /* The VDBE cursor used to access the table */
- int iIdxCur; /* The VDBE cursor used to access pIdx */
- int addrBrk; /* Jump here to break out of the loop */
- int addrNxt; /* Jump here to start the next IN combination */
- int addrCont; /* Jump here to continue with the next loop cycle */
- int addrFirst; /* First instruction of interior of the loop */
- u8 iFrom; /* Which entry in the FROM clause */
- u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
- int p1, p2; /* Operands of the opcode used to ends the loop */
- union { /* Information that depends on plan.wsFlags */
- struct {
- int nIn; /* Number of entries in aInLoop[] */
- struct InLoop {
- int iCur; /* The VDBE cursor used by this IN operator */
- int addrInTop; /* Top of the IN loop */
- } *aInLoop; /* Information about each nested IN operator */
- } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */
- Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
- } u;
- double rOptCost; /* "Optimal" cost for this level */
-
- /* The following field is really not part of the current level. But
- ** we need a place to cache virtual table index information for each
- ** virtual table in the FROM clause and the WhereLevel structure is
- ** a convenient place since there is one WhereLevel for each FROM clause
- ** element.
- */
- sqlite3_index_info *pIdxInfo; /* Index info for n-th source table */
-};
-
-/*
-** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
-** and the WhereInfo.wctrlFlags member.
-*/
-#define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */
-#define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */
-#define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */
-#define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */
-#define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */
-#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
-#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
-#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
-#define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */
-
-/*
-** The WHERE clause processing routine has two halves. The
-** first part does the start of the WHERE loop and the second
-** half does the tail of the WHERE loop. An instance of
-** this structure is returned by the first half and passed
-** into the second half to give some continuity.
-*/
-struct WhereInfo {
- Parse *pParse; /* Parsing and code generating context */
- SrcList *pTabList; /* List of tables in the join */
- u16 nOBSat; /* Number of ORDER BY terms satisfied by indices */
- u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
- u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */
- u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
- u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
- int iTop; /* The very beginning of the WHERE loop */
- int iContinue; /* Jump here to continue with next record */
- int iBreak; /* Jump here to break out of the loop */
- int nLevel; /* Number of nested loop */
- struct WhereClause *pWC; /* Decomposition of the WHERE clause */
- double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
- double nRowOut; /* Estimated number of output rows */
- WhereLevel a[1]; /* Information about each nest loop in WHERE */
-};
-
-/* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */
-#define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */
-#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */
-#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */
-#define WHERE_DISTINCT_UNORDERED 3 /* Duplicates are scattered */
-
-/*
-** A NameContext defines a context in which to resolve table and column
-** names. The context consists of a list of tables (the pSrcList) field and
-** a list of named expression (pEList). The named expression list may
-** be NULL. The pSrc corresponds to the FROM clause of a SELECT or
-** to the table being operated on by INSERT, UPDATE, or DELETE. The
-** pEList corresponds to the result set of a SELECT and is NULL for
-** other statements.
-**
-** NameContexts can be nested. When resolving names, the inner-most
-** context is searched first. If no match is found, the next outer
-** context is checked. If there is still no match, the next context
-** is checked. This process continues until either a match is found
-** or all contexts are check. When a match is found, the nRef member of
-** the context containing the match is incremented.
-**
-** Each subquery gets a new NameContext. The pNext field points to the
-** NameContext in the parent query. Thus the process of scanning the
-** NameContext list corresponds to searching through successively outer
-** subqueries looking for a match.
-*/
-struct NameContext {
- Parse *pParse; /* The parser */
- SrcList *pSrcList; /* One or more tables used to resolve names */
- ExprList *pEList; /* Optional list of named expressions */
- AggInfo *pAggInfo; /* Information about aggregates at this level */
- NameContext *pNext; /* Next outer name context. NULL for outermost */
- int nRef; /* Number of names resolved by this context */
- int nErr; /* Number of errors encountered while resolving names */
- u8 ncFlags; /* Zero or more NC_* flags defined below */
-};
-
-/*
-** Allowed values for the NameContext, ncFlags field.
-*/
-#define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */
-#define NC_HasAgg 0x02 /* One or more aggregate functions seen */
-#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
-#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
-
-/*
-** An instance of the following structure contains all information
-** needed to generate code for a single SELECT statement.
-**
-** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
-** If there is a LIMIT clause, the parser sets nLimit to the value of the
-** limit and nOffset to the value of the offset (or 0 if there is not
-** offset). But later on, nLimit and nOffset become the memory locations
-** in the VDBE that record the limit and offset counters.
-**
-** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
-** These addresses must be stored so that we can go back and fill in
-** the P4_KEYINFO and P2 parameters later. Neither the KeyInfo nor
-** the number of columns in P2 can be computed at the same time
-** as the OP_OpenEphm instruction is coded because not
-** enough information about the compound query is known at that point.
-** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
-** for the result set. The KeyInfo for addrOpenEphm[2] contains collating
-** sequences for the ORDER BY clause.
-*/
-struct Select {
- ExprList *pEList; /* The fields of the result */
- u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
- u16 selFlags; /* Various SF_* values */
- int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
- int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
- double nSelectRow; /* Estimated number of result rows */
- SrcList *pSrc; /* The FROM clause */
- Expr *pWhere; /* The WHERE clause */
- ExprList *pGroupBy; /* The GROUP BY clause */
- Expr *pHaving; /* The HAVING clause */
- ExprList *pOrderBy; /* The ORDER BY clause */
- Select *pPrior; /* Prior select in a compound select statement */
- Select *pNext; /* Next select to the left in a compound */
- Select *pRightmost; /* Right-most select in a compound select statement */
- Expr *pLimit; /* LIMIT expression. NULL means not used. */
- Expr *pOffset; /* OFFSET expression. NULL means not used. */
-};
-
-/*
-** Allowed values for Select.selFlags. The "SF" prefix stands for
-** "Select Flag".
-*/
-#define SF_Distinct 0x0001 /* Output should be DISTINCT */
-#define SF_Resolved 0x0002 /* Identifiers have been resolved */
-#define SF_Aggregate 0x0004 /* Contains aggregate functions */
-#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */
-#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
-#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
-#define SF_UseSorter 0x0040 /* Sort using a sorter */
-#define SF_Values 0x0080 /* Synthesized from VALUES clause */
-#define SF_Materialize 0x0100 /* Force materialization of views */
-
-
-/*
-** The results of a select can be distributed in several ways. The
-** "SRT" prefix means "SELECT Result Type".
-*/
-#define SRT_Union 1 /* Store result as keys in an index */
-#define SRT_Except 2 /* Remove result from a UNION index */
-#define SRT_Exists 3 /* Store 1 if the result is not empty */
-#define SRT_Discard 4 /* Do not save the results anywhere */
-
-/* The ORDER BY clause is ignored for all of the above */
-#define IgnorableOrderby(X) ((X->eDest)<=SRT_Discard)
-
-#define SRT_Output 5 /* Output each row of result */
-#define SRT_Mem 6 /* Store result in a memory cell */
-#define SRT_Set 7 /* Store results as keys in an index */
-#define SRT_Table 8 /* Store result as data with an automatic rowid */
-#define SRT_EphemTab 9 /* Create transient tab and store like SRT_Table */
-#define SRT_Coroutine 10 /* Generate a single row of result */
-
-/*
-** An instance of this object describes where to put of the results of
-** a SELECT statement.
-*/
-struct SelectDest {
- u8 eDest; /* How to dispose of the results. On of SRT_* above. */
- char affSdst; /* Affinity used when eDest==SRT_Set */
- int iSDParm; /* A parameter used by the eDest disposal method */
- int iSdst; /* Base register where results are written */
- int nSdst; /* Number of registers allocated */
-};
-
-/*
-** During code generation of statements that do inserts into AUTOINCREMENT
-** tables, the following information is attached to the Table.u.autoInc.p
-** pointer of each autoincrement table to record some side information that
-** the code generator needs. We have to keep per-table autoincrement
-** information in case inserts are down within triggers. Triggers do not
-** normally coordinate their activities, but we do need to coordinate the
-** loading and saving of autoincrement information.
-*/
-struct AutoincInfo {
- AutoincInfo *pNext; /* Next info block in a list of them all */
- Table *pTab; /* Table this info block refers to */
- int iDb; /* Index in sqlite3.aDb[] of database holding pTab */
- int regCtr; /* Memory register holding the rowid counter */
-};
-
-/*
-** Size of the column cache
-*/
-#ifndef SQLITE_N_COLCACHE
-# define SQLITE_N_COLCACHE 10
-#endif
-
-/*
-** At least one instance of the following structure is created for each
-** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
-** statement. All such objects are stored in the linked list headed at
-** Parse.pTriggerPrg and deleted once statement compilation has been
-** completed.
-**
-** A Vdbe sub-program that implements the body and WHEN clause of trigger
-** TriggerPrg.pTrigger, assuming a default ON CONFLICT clause of
-** TriggerPrg.orconf, is stored in the TriggerPrg.pProgram variable.
-** The Parse.pTriggerPrg list never contains two entries with the same
-** values for both pTrigger and orconf.
-**
-** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns
-** accessed (or set to 0 for triggers fired as a result of INSERT
-** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to
-** a mask of new.* columns used by the program.
-*/
-struct TriggerPrg {
- Trigger *pTrigger; /* Trigger this program was coded from */
- TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */
- SubProgram *pProgram; /* Program implementing pTrigger/orconf */
- int orconf; /* Default ON CONFLICT policy */
- u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */
-};
-
-/*
-** The yDbMask datatype for the bitmask of all attached databases.
-*/
-#if SQLITE_MAX_ATTACHED>30
- typedef sqlite3_uint64 yDbMask;
-#else
- typedef unsigned int yDbMask;
-#endif
-
-/*
-** An SQL parser context. A copy of this structure is passed through
-** the parser and down into all the parser action routine in order to
-** carry around information that is global to the entire parse.
-**
-** The structure is divided into two parts. When the parser and code
-** generate call themselves recursively, the first part of the structure
-** is constant but the second part is reset at the beginning and end of
-** each recursion.
-**
-** The nTableLock and aTableLock variables are only used if the shared-cache
-** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
-** used to store the set of table-locks required by the statement being
-** compiled. Function sqlite3TableLock() is used to add entries to the
-** list.
-*/
-struct Parse {
- sqlite3 *db; /* The main database structure */
- char *zErrMsg; /* An error message */
- Vdbe *pVdbe; /* An engine for executing database bytecode */
- int rc; /* Return code from execution */
- u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */
- u8 checkSchema; /* Causes schema cookie check after an error */
- u8 nested; /* Number of nested calls to the parser/code generator */
- u8 nTempReg; /* Number of temporary registers in aTempReg[] */
- u8 nTempInUse; /* Number of aTempReg[] currently checked out */
- u8 nColCache; /* Number of entries in aColCache[] */
- u8 iColCache; /* Next entry in aColCache[] to replace */
- u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
- u8 mayAbort; /* True if statement may throw an ABORT exception */
- int aTempReg[8]; /* Holding area for temporary registers */
- int nRangeReg; /* Size of the temporary register block */
- int iRangeReg; /* First register in temporary register block */
- int nErr; /* Number of errors seen */
- int nTab; /* Number of previously allocated VDBE cursors */
- int nMem; /* Number of memory cells used so far */
- int nSet; /* Number of sets used so far */
- int nOnce; /* Number of OP_Once instructions so far */
- int ckBase; /* Base register of data during check constraints */
- int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
- int iCacheCnt; /* Counter used to generate aColCache[].lru values */
- struct yColCache {
- int iTable; /* Table cursor number */
- int iColumn; /* Table column number */
- u8 tempReg; /* iReg is a temp register that needs to be freed */
- int iLevel; /* Nesting level */
- int iReg; /* Reg with value of this column. 0 means none. */
- int lru; /* Least recently used entry has the smallest value */
- } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
- yDbMask writeMask; /* Start a write transaction on these databases */
- yDbMask cookieMask; /* Bitmask of schema verified databases */
- int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */
- int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
- int regRowid; /* Register holding rowid of CREATE TABLE entry */
- int regRoot; /* Register holding root page number for new objects */
- int nMaxArg; /* Max args passed to user function by sub-program */
- Token constraintName;/* Name of the constraint currently being parsed */
-#ifndef SQLITE_OMIT_SHARED_CACHE
- int nTableLock; /* Number of locks in aTableLock */
- TableLock *aTableLock; /* Required table locks for shared-cache mode */
-#endif
- AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
-
- /* Information used while coding trigger programs. */
- Parse *pToplevel; /* Parse structure for main program (or NULL) */
- Table *pTriggerTab; /* Table triggers are being coded for */
- double nQueryLoop; /* Estimated number of iterations of a query */
- u32 oldmask; /* Mask of old.* columns referenced */
- u32 newmask; /* Mask of new.* columns referenced */
- u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
- u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
- u8 disableTriggers; /* True to disable triggers */
-
- /* Above is constant between recursions. Below is reset before and after
- ** each recursion */
-
- int nVar; /* Number of '?' variables seen in the SQL so far */
- int nzVar; /* Number of available slots in azVar[] */
- u8 explain; /* True if the EXPLAIN flag is found on the query */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
- int nVtabLock; /* Number of virtual tables to lock */
-#endif
- int nAlias; /* Number of aliased result set columns */
- int nHeight; /* Expression tree height of current sub-select */
-#ifndef SQLITE_OMIT_EXPLAIN
- int iSelectId; /* ID of current select for EXPLAIN output */
- int iNextSelectId; /* Next available select ID for EXPLAIN output */
-#endif
- char **azVar; /* Pointers to names of parameters */
- Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
- int *aAlias; /* Register used to hold aliased result */
- const char *zTail; /* All SQL text past the last semicolon parsed */
- Table *pNewTable; /* A table being constructed by CREATE TABLE */
- Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
- const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
- Token sNameToken; /* Token with unqualified schema object name */
- Token sLastToken; /* The last token parsed */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- Token sArg; /* Complete text of a module argument */
- Table **apVtabLock; /* Pointer to virtual tables needing locking */
-#endif
- Table *pZombieTab; /* List of Table objects to delete after code gen */
- TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
-};
-
-/*
-** Return true if currently inside an sqlite3_declare_vtab() call.
-*/
-#ifdef SQLITE_OMIT_VIRTUALTABLE
- #define IN_DECLARE_VTAB 0
-#else
- #define IN_DECLARE_VTAB (pParse->declareVtab)
-#endif
-
-/*
-** An instance of the following structure can be declared on a stack and used
-** to save the Parse.zAuthContext value so that it can be restored later.
-*/
-struct AuthContext {
- const char *zAuthContext; /* Put saved Parse.zAuthContext here */
- Parse *pParse; /* The Parse structure */
-};
-
-/*
-** Bitfield flags for P5 value in various opcodes.
-*/
-#define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */
-#define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */
-#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
-#define OPFLAG_APPEND 0x08 /* This is likely to be an append */
-#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
-#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */
-#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
-#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
-#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
-#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */
-#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
-
-/*
- * Each trigger present in the database schema is stored as an instance of
- * struct Trigger.
- *
- * Pointers to instances of struct Trigger are stored in two ways.
- * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
- * database). This allows Trigger structures to be retrieved by name.
- * 2. All triggers associated with a single table form a linked list, using the
- * pNext member of struct Trigger. A pointer to the first element of the
- * linked list is stored as the "pTrigger" member of the associated
- * struct Table.
- *
- * The "step_list" member points to the first element of a linked list
- * containing the SQL statements specified as the trigger program.
- */
-struct Trigger {
- char *zName; /* The name of the trigger */
- char *table; /* The table or view to which the trigger applies */
- u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
- u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
- Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */
- IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger,
- the <column-list> is stored here */
- Schema *pSchema; /* Schema containing the trigger */
- Schema *pTabSchema; /* Schema containing the table */
- TriggerStep *step_list; /* Link list of trigger program steps */
- Trigger *pNext; /* Next trigger associated with the table */
-};
-
-/*
-** A trigger is either a BEFORE or an AFTER trigger. The following constants
-** determine which.
-**
-** If there are multiple triggers, you might of some BEFORE and some AFTER.
-** In that cases, the constants below can be ORed together.
-*/
-#define TRIGGER_BEFORE 1
-#define TRIGGER_AFTER 2
-
-/*
- * An instance of struct TriggerStep is used to store a single SQL statement
- * that is a part of a trigger-program.
- *
- * Instances of struct TriggerStep are stored in a singly linked list (linked
- * using the "pNext" member) referenced by the "step_list" member of the
- * associated struct Trigger instance. The first element of the linked list is
- * the first step of the trigger-program.
- *
- * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
- * "SELECT" statement. The meanings of the other members is determined by the
- * value of "op" as follows:
- *
- * (op == TK_INSERT)
- * orconf -> stores the ON CONFLICT algorithm
- * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
- * this stores a pointer to the SELECT statement. Otherwise NULL.
- * target -> A token holding the quoted name of the table to insert into.
- * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
- * this stores values to be inserted. Otherwise NULL.
- * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
- * statement, then this stores the column-names to be
- * inserted into.
- *
- * (op == TK_DELETE)
- * target -> A token holding the quoted name of the table to delete from.
- * pWhere -> The WHERE clause of the DELETE statement if one is specified.
- * Otherwise NULL.
- *
- * (op == TK_UPDATE)
- * target -> A token holding the quoted name of the table to update rows of.
- * pWhere -> The WHERE clause of the UPDATE statement if one is specified.
- * Otherwise NULL.
- * pExprList -> A list of the columns to update and the expressions to update
- * them to. See sqlite3Update() documentation of "pChanges"
- * argument.
- *
- */
-struct TriggerStep {
- u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
- u8 orconf; /* OE_Rollback etc. */
- Trigger *pTrig; /* The trigger that this step is a part of */
- Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
- Token target; /* Target table for DELETE, UPDATE, INSERT */
- Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
- ExprList *pExprList; /* SET clause for UPDATE. VALUES clause for INSERT */
- IdList *pIdList; /* Column names for INSERT */
- TriggerStep *pNext; /* Next in the link-list */
- TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
-};
-
-/*
-** The following structure contains information used by the sqliteFix...
-** routines as they walk the parse tree to make database references
-** explicit.
-*/
-typedef struct DbFixer DbFixer;
-struct DbFixer {
- Parse *pParse; /* The parsing context. Error messages written here */
- Schema *pSchema; /* Fix items to this schema */
- const char *zDb; /* Make sure all objects are contained in this database */
- const char *zType; /* Type of the container - used for error messages */
- const Token *pName; /* Name of the container - used for error messages */
-};
-
-/*
-** An objected used to accumulate the text of a string where we
-** do not necessarily know how big the string will be in the end.
-*/
-struct StrAccum {
- sqlite3 *db; /* Optional database for lookaside. Can be NULL */
- char *zBase; /* A base allocation. Not from malloc. */
- char *zText; /* The string collected so far */
- int nChar; /* Length of the string so far */
- int nAlloc; /* Amount of space allocated in zText */
- int mxAlloc; /* Maximum allowed string length */
- u8 mallocFailed; /* Becomes true if any memory allocation fails */
- u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */
- u8 tooBig; /* Becomes true if string size exceeds limits */
-};
-
-/*
-** A pointer to this structure is used to communicate information
-** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
-*/
-typedef struct {
- sqlite3 *db; /* The database being initialized */
- char **pzErrMsg; /* Error message stored here */
- int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */
- int rc; /* Result code stored here */
-} InitData;
-
-/*
-** Structure containing global configuration data for the SQLite library.
-**
-** This structure also contains some state information.
-*/
-struct Sqlite3Config {
- int bMemstat; /* True to enable memory status */
- int bCoreMutex; /* True to enable core mutexing */
- int bFullMutex; /* True to enable full mutexing */
- int bOpenUri; /* True to interpret filenames as URIs */
- int bUseCis; /* Use covering indices for full-scans */
- int mxStrlen; /* Maximum string length */
- int szLookaside; /* Default lookaside buffer size */
- int nLookaside; /* Default lookaside buffer count */
- sqlite3_mem_methods m; /* Low-level memory allocation interface */
- sqlite3_mutex_methods mutex; /* Low-level mutex interface */
- sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */
- void *pHeap; /* Heap storage space */
- int nHeap; /* Size of pHeap[] */
- int mnReq, mxReq; /* Min and max heap requests sizes */
- void *pScratch; /* Scratch memory */
- int szScratch; /* Size of each scratch buffer */
- int nScratch; /* Number of scratch buffers */
- void *pPage; /* Page cache memory */
- int szPage; /* Size of each page in pPage[] */
- int nPage; /* Number of pages in pPage[] */
- int mxParserStack; /* maximum depth of the parser stack */
- int sharedCacheEnabled; /* true if shared-cache mode enabled */
- /* The above might be initialized to non-zero. The following need to always
- ** initially be zero, however. */
- int isInit; /* True after initialization has finished */
- int inProgress; /* True while initialization in progress */
- int isMutexInit; /* True after mutexes are initialized */
- int isMallocInit; /* True after malloc is initialized */
- int isPCacheInit; /* True after malloc is initialized */
- sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */
- int nRefInitMutex; /* Number of users of pInitMutex */
- void (*xLog)(void*,int,const char*); /* Function for logging */
- void *pLogArg; /* First argument to xLog() */
- int bLocaltimeFault; /* True to fail localtime() calls */
-#ifdef SQLITE_ENABLE_SQLLOG
- void(*xSqllog)(void*,sqlite3*,const char*, int);
- void *pSqllogArg;
-#endif
-};
-
-/*
-** Context pointer passed down through the tree-walk.
-*/
-struct Walker {
- int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */
- int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
- Parse *pParse; /* Parser context. */
- int walkerDepth; /* Number of subqueries */
- union { /* Extra data for callback */
- NameContext *pNC; /* Naming context */
- int i; /* Integer value */
- SrcList *pSrcList; /* FROM clause */
- struct SrcCount *pSrcCount; /* Counting column references */
- } u;
-};
-
-/* Forward declarations */
-SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*);
-SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*);
-SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*);
-SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
-SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
-
-/*
-** Return code from the parse-tree walking primitives and their
-** callbacks.
-*/
-#define WRC_Continue 0 /* Continue down into children */
-#define WRC_Prune 1 /* Omit children but continue walking siblings */
-#define WRC_Abort 2 /* Abandon the tree walk */
-
-/*
-** Assuming zIn points to the first byte of a UTF-8 character,
-** advance zIn to point to the first byte of the next UTF-8 character.
-*/
-#define SQLITE_SKIP_UTF8(zIn) { \
- if( (*(zIn++))>=0xc0 ){ \
- while( (*zIn & 0xc0)==0x80 ){ zIn++; } \
- } \
-}
-
-/*
-** The SQLITE_*_BKPT macros are substitutes for the error codes with
-** the same name but without the _BKPT suffix. These macros invoke
-** routines that report the line-number on which the error originated
-** using sqlite3_log(). The routines also provide a convenient place
-** to set a debugger breakpoint.
-*/
-SQLITE_PRIVATE int sqlite3CorruptError(int);
-SQLITE_PRIVATE int sqlite3MisuseError(int);
-SQLITE_PRIVATE int sqlite3CantopenError(int);
-#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
-#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
-#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
-
-
-/*
-** FTS4 is really an extension for FTS3. It is enabled using the
-** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all
-** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3.
-*/
-#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3)
-# define SQLITE_ENABLE_FTS3
-#endif
-
-/*
-** The ctype.h header is needed for non-ASCII systems. It is also
-** needed by FTS3 when FTS3 is included in the amalgamation.
-*/
-#if !defined(SQLITE_ASCII) || \
- (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION))
-# include <ctype.h>
-#endif
-
-/*
-** The following macros mimic the standard library functions toupper(),
-** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
-** sqlite versions only work for ASCII characters, regardless of locale.
-*/
-#ifdef SQLITE_ASCII
-# define sqlite3Toupper(x) ((x)&~(sqlite3CtypeMap[(unsigned char)(x)]&0x20))
-# define sqlite3Isspace(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x01)
-# define sqlite3Isalnum(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x06)
-# define sqlite3Isalpha(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x02)
-# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04)
-# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
-# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
-#else
-# define sqlite3Toupper(x) toupper((unsigned char)(x))
-# define sqlite3Isspace(x) isspace((unsigned char)(x))
-# define sqlite3Isalnum(x) isalnum((unsigned char)(x))
-# define sqlite3Isalpha(x) isalpha((unsigned char)(x))
-# define sqlite3Isdigit(x) isdigit((unsigned char)(x))
-# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x))
-# define sqlite3Tolower(x) tolower((unsigned char)(x))
-#endif
-
-/*
-** Internal function prototypes
-*/
-#define sqlite3StrICmp sqlite3_stricmp
-SQLITE_PRIVATE int sqlite3Strlen30(const char*);
-#define sqlite3StrNICmp sqlite3_strnicmp
-
-SQLITE_PRIVATE int sqlite3MallocInit(void);
-SQLITE_PRIVATE void sqlite3MallocEnd(void);
-SQLITE_PRIVATE void *sqlite3Malloc(int);
-SQLITE_PRIVATE void *sqlite3MallocZero(int);
-SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, int);
-SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, int);
-SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
-SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, int);
-SQLITE_PRIVATE void *sqlite3Realloc(void*, int);
-SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
-SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, int);
-SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
-SQLITE_PRIVATE int sqlite3MallocSize(void*);
-SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
-SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
-SQLITE_PRIVATE void sqlite3ScratchFree(void*);
-SQLITE_PRIVATE void *sqlite3PageMalloc(int);
-SQLITE_PRIVATE void sqlite3PageFree(void*);
-SQLITE_PRIVATE void sqlite3MemSetDefault(void);
-SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
-SQLITE_PRIVATE int sqlite3HeapNearlyFull(void);
-
-/*
-** On systems with ample stack space and that support alloca(), make
-** use of alloca() to obtain space for large automatic objects. By default,
-** obtain space from malloc().
-**
-** The alloca() routine never returns NULL. This will cause code paths
-** that deal with sqlite3StackAlloc() failures to be unreachable.
-*/
-#ifdef SQLITE_USE_ALLOCA
-# define sqlite3StackAllocRaw(D,N) alloca(N)
-# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N)
-# define sqlite3StackFree(D,P)
-#else
-# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N)
-# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N)
-# define sqlite3StackFree(D,P) sqlite3DbFree(D,P)
-#endif
-
-#ifdef SQLITE_ENABLE_MEMSYS3
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
-#endif
-#ifdef SQLITE_ENABLE_MEMSYS5
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
-#endif
-
-
-#ifndef SQLITE_MUTEX_OMIT
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void);
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void);
-SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int);
-SQLITE_PRIVATE int sqlite3MutexInit(void);
-SQLITE_PRIVATE int sqlite3MutexEnd(void);
-#endif
-
-SQLITE_PRIVATE int sqlite3StatusValue(int);
-SQLITE_PRIVATE void sqlite3StatusAdd(int, int);
-SQLITE_PRIVATE void sqlite3StatusSet(int, int);
-
-#ifndef SQLITE_OMIT_FLOATING_POINT
-SQLITE_PRIVATE int sqlite3IsNaN(double);
-#else
-# define sqlite3IsNaN(X) 0
-#endif
-
-SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, int, const char*, va_list);
-#ifndef SQLITE_OMIT_TRACE
-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...);
-#endif
-SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
-SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
-SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
-#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
-SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...);
-#endif
-#if defined(SQLITE_TEST)
-SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
-#endif
-
-/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe*);
-SQLITE_PRIVATE void sqlite3ExplainPrintf(Vdbe*, const char*, ...);
-SQLITE_PRIVATE void sqlite3ExplainNL(Vdbe*);
-SQLITE_PRIVATE void sqlite3ExplainPush(Vdbe*);
-SQLITE_PRIVATE void sqlite3ExplainPop(Vdbe*);
-SQLITE_PRIVATE void sqlite3ExplainFinish(Vdbe*);
-SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe*, Select*);
-SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe*, Expr*);
-SQLITE_PRIVATE void sqlite3ExplainExprList(Vdbe*, ExprList*);
-SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe*);
-#else
-# define sqlite3ExplainBegin(X)
-# define sqlite3ExplainSelect(A,B)
-# define sqlite3ExplainExpr(A,B)
-# define sqlite3ExplainExprList(A,B)
-# define sqlite3ExplainFinish(X)
-# define sqlite3VdbeExplanation(X) 0
-#endif
-
-
-SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
-SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
-SQLITE_PRIVATE int sqlite3Dequote(char*);
-SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
-SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
-SQLITE_PRIVATE void sqlite3FinishCoding(Parse*);
-SQLITE_PRIVATE int sqlite3GetTempReg(Parse*);
-SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int);
-SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int);
-SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int);
-SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*);
-SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
-SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
-SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
-SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
-SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
-SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
-SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
-SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
-SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
-SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
-SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
-SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*);
-SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int);
-SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*);
-SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int);
-SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*);
-SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*);
-SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int);
-SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
-SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*);
-SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
-SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
-SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
-SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
-SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
-SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*);
-SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
- sqlite3_vfs**,char**,char **);
-SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
-SQLITE_PRIVATE int sqlite3CodeOnce(Parse *);
-
-SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32);
-SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32);
-SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
-SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*);
-SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
-SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
-SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
-
-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*);
-SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64);
-SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, u8 iBatch, i64);
-SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*);
-
-SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
-
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
-SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*);
-#else
-# define sqlite3ViewGetColumnNames(A,B) 0
-#endif
-
-SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
-SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
-SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
-#ifndef SQLITE_OMIT_AUTOINCREMENT
-SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse);
-SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
-#else
-# define sqlite3AutoincrementBegin(X)
-# define sqlite3AutoincrementEnd(X)
-#endif
-SQLITE_PRIVATE int sqlite3CodeCoroutine(Parse*, Select*, SelectDest*);
-SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
-SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
-SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
-SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
- Token*, Select*, Expr*, IdList*);
-SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
-SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
-SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
-SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
-SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
-SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
-SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
- Token*, int, int);
-SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
-SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
-SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
- Expr*,ExprList*,int,Expr*,Expr*);
-SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
-SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
-SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
-SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
-#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
-SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *);
-#endif
-SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
-SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
-SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
-SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
-SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
-SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int);
-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int);
-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
-SQLITE_PRIVATE int sqlite3ExprCode(Parse*, Expr*, int);
-SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
-SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
-SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
-SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse*, Expr*);
-SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int);
-SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
-SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
-SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
-SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
-SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
-SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
-SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
-SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
-SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);
-SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
-SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
-SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
-SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
-SQLITE_PRIVATE void sqlite3PrngSaveState(void);
-SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
-SQLITE_PRIVATE void sqlite3PrngResetState(void);
-SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int);
-SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
-SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
-SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int);
-SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
-SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
-SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
-SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
-SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
-SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
-SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
-SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
-SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
-SQLITE_PRIVATE int sqlite3IsRowid(const char*);
-SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
-SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
-SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
-SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
- int*,int,int,int,int,int*);
-SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
-SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
-SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
-SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
-SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
-SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int);
-SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
-SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
-SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
-SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
-SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
-SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
-SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
-SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void);
-SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
-SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
-SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
-
-#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
-SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, int);
-#endif
-
-#ifndef SQLITE_OMIT_TRIGGER
-SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
- Expr*,int, int);
-SQLITE_PRIVATE void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
-SQLITE_PRIVATE void sqlite3DropTrigger(Parse*, SrcList*, int);
-SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse*, Trigger*);
-SQLITE_PRIVATE Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask);
-SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *, Table *);
-SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *,
- int, int, int);
-SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int);
- void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
-SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
- ExprList*,Select*,u8);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
-SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*);
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
-SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
-# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
-#else
-# define sqlite3TriggersExist(B,C,D,E,F) 0
-# define sqlite3DeleteTrigger(A,B)
-# define sqlite3DropTriggerPtr(A,B)
-# define sqlite3UnlinkAndDeleteTrigger(A,B,C)
-# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I)
-# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F)
-# define sqlite3TriggerList(X, Y) 0
-# define sqlite3ParseToplevel(p) p
-# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0
-#endif
-
-SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*);
-SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
-SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int);
-#ifndef SQLITE_OMIT_AUTHORIZATION
-SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*);
-SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*);
-SQLITE_PRIVATE void sqlite3AuthContextPush(Parse*, AuthContext*, const char*);
-SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext*);
-SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int);
-#else
-# define sqlite3AuthRead(a,b,c,d)
-# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK
-# define sqlite3AuthContextPush(a,b,c)
-# define sqlite3AuthContextPop(a) ((void)(a))
-#endif
-SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
-SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*);
-SQLITE_PRIVATE int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
-SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*);
-SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*);
-SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*);
-SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*);
-SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
-SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8);
-SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
-SQLITE_PRIVATE int sqlite3Atoi(const char*);
-SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
-SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
-SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
-
-/*
-** Routines to read and write variable-length integers. These used to
-** be defined locally, but now we use the varint routines in the util.c
-** file. Code should use the MACRO forms below, as the Varint32 versions
-** are coded to assume the single byte case is already handled (which
-** the MACRO form does).
-*/
-SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64);
-SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char*, u32);
-SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *);
-SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *);
-SQLITE_PRIVATE int sqlite3VarintLen(u64 v);
-
-/*
-** The header of a record consists of a sequence variable-length integers.
-** These integers are almost always small and are encoded as a single byte.
-** The following macros take advantage this fact to provide a fast encode
-** and decode of the integers in a record header. It is faster for the common
-** case where the integer is a single byte. It is a little slower when the
-** integer is two or more bytes. But overall it is faster.
-**
-** The following expressions are equivalent:
-**
-** x = sqlite3GetVarint32( A, &B );
-** x = sqlite3PutVarint32( A, B );
-**
-** x = getVarint32( A, B );
-** x = putVarint32( A, B );
-**
-*/
-#define getVarint32(A,B) (u8)((*(A)<(u8)0x80) ? ((B) = (u32)*(A)),1 : sqlite3GetVarint32((A), (u32 *)&(B)))
-#define putVarint32(A,B) (u8)(((u32)(B)<(u32)0x80) ? (*(A) = (unsigned char)(B)),1 : sqlite3PutVarint32((A), (B)))
-#define getVarint sqlite3GetVarint
-#define putVarint sqlite3PutVarint
-
-
-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
-SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *, Table *);
-SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2);
-SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
-SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
-SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
-SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...);
-SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
-SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
-SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
-SQLITE_PRIVATE const char *sqlite3ErrStr(int);
-SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
-SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
-SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
-SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
-SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
-SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
-SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
-SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
-SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
-SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
-SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
-SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64);
-SQLITE_PRIVATE int sqlite3AbsInt32(int);
-#ifdef SQLITE_ENABLE_8_3_NAMES
-SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*);
-#else
-# define sqlite3FileSuffix3(X,Y)
-#endif
-SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,int);
-
-SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
-SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
-SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
- void(*)(void*));
-SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
-SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
-SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
-#ifdef SQLITE_ENABLE_STAT3
-SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
-#endif
-SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
-SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
-#ifndef SQLITE_AMALGAMATION
-SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[];
-SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
-SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[];
-SQLITE_PRIVATE const Token sqlite3IntTokens[];
-SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config;
-SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
-#ifndef SQLITE_OMIT_WSD
-SQLITE_PRIVATE int sqlite3PendingByte;
-#endif
-#endif
-SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, int, int);
-SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
-SQLITE_PRIVATE void sqlite3AlterFunctions(void);
-SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
-SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
-SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
-SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
-SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
-SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
-SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
-SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
-SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
-SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
-SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
-SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
-SQLITE_PRIVATE char sqlite3AffinityType(const char*);
-SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
-SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
-SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
-SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
-SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*);
-SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*);
-SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int);
-SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
-SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
-SQLITE_PRIVATE void sqlite3SchemaClear(void *);
-SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
-SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
-SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
-SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
- void (*)(sqlite3_context*,int,sqlite3_value **),
- void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
- FuncDestructor *pDestructor
-);
-SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
-SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
-
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
-SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int);
-SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
-SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
-SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
-
-SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
-SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
-
-/*
-** The interface to the LEMON-generated parser
-*/
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t));
-SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
-SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
-#ifdef YYTRACKMAXSTACKDEPTH
-SQLITE_PRIVATE int sqlite3ParserStackPeak(void*);
-#endif
-
-SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3*);
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3*);
-#else
-# define sqlite3CloseExtensions(X)
-#endif
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-SQLITE_PRIVATE void sqlite3TableLock(Parse *, int, int, u8, const char *);
-#else
- #define sqlite3TableLock(v,w,x,y,z)
-#endif
-
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*);
-#endif
-
-#ifdef SQLITE_OMIT_VIRTUALTABLE
-# define sqlite3VtabClear(Y)
-# define sqlite3VtabSync(X,Y) SQLITE_OK
-# define sqlite3VtabRollback(X)
-# define sqlite3VtabCommit(X)
-# define sqlite3VtabInSync(db) 0
-# define sqlite3VtabLock(X)
-# define sqlite3VtabUnlock(X)
-# define sqlite3VtabUnlockList(X)
-# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
-# define sqlite3GetVTable(X,Y) ((VTable*)0)
-#else
-SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*);
-SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **);
-SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db);
-SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db);
-SQLITE_PRIVATE void sqlite3VtabLock(VTable *);
-SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *);
-SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*);
-SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int);
-SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
-# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
-#endif
-SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
-SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
-SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
-SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*);
-SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*);
-SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
-SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*);
-SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
-SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
-SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
-SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
-SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
-SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
-SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
-SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
-SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
-SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
-SQLITE_PRIVATE const char *sqlite3JournalModename(int);
-#ifndef SQLITE_OMIT_WAL
-SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
-SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
-#endif
-
-/* Declarations for functions in fkey.c. All of these are replaced by
-** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
-** key functionality is available. If OMIT_TRIGGER is defined but
-** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
-** this case foreign keys are parsed, but no other functionality is
-** provided (enforcement of FK constraints requires the triggers sub-system).
-*/
-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
-SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int);
-SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*);
-SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int);
-SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int);
-SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*);
-SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *);
-#else
- #define sqlite3FkActions(a,b,c,d)
- #define sqlite3FkCheck(a,b,c,d)
- #define sqlite3FkDropTable(a,b,c)
- #define sqlite3FkOldmask(a,b) 0
- #define sqlite3FkRequired(a,b,c,d) 0
-#endif
-#ifndef SQLITE_OMIT_FOREIGN_KEY
-SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
-#else
- #define sqlite3FkDelete(a,b)
-#endif
-
-
-/*
-** Available fault injectors. Should be numbered beginning with 0.
-*/
-#define SQLITE_FAULTINJECTOR_MALLOC 0
-#define SQLITE_FAULTINJECTOR_COUNT 1
-
-/*
-** The interface to the code in fault.c used for identifying "benign"
-** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST
-** is not defined.
-*/
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void);
-SQLITE_PRIVATE void sqlite3EndBenignMalloc(void);
-#else
- #define sqlite3BeginBenignMalloc()
- #define sqlite3EndBenignMalloc()
-#endif
-
-#define IN_INDEX_ROWID 1
-#define IN_INDEX_EPH 2
-#define IN_INDEX_INDEX 3
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, int*);
-
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
-SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
-SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *);
-SQLITE_PRIVATE int sqlite3JournalExists(sqlite3_file *p);
-#else
- #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
- #define sqlite3JournalExists(p) 1
-#endif
-
-SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
-SQLITE_PRIVATE int sqlite3MemJournalSize(void);
-SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *);
-
-#if SQLITE_MAX_EXPR_DEPTH>0
-SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
-SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *);
-SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int);
-#else
- #define sqlite3ExprSetHeight(x,y)
- #define sqlite3SelectExprHeight(x) 0
- #define sqlite3ExprCheckHeight(x,y)
-#endif
-
-SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*);
-SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32);
-
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
-SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *, sqlite3 *);
-SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db);
-SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db);
-#else
- #define sqlite3ConnectionBlocked(x,y)
- #define sqlite3ConnectionUnlocked(x)
- #define sqlite3ConnectionClosed(x)
-#endif
-
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *);
-#endif
-
-/*
-** If the SQLITE_ENABLE IOTRACE exists then the global variable
-** sqlite3IoTrace is a pointer to a printf-like routine used to
-** print I/O tracing messages.
-*/
-#ifdef SQLITE_ENABLE_IOTRACE
-# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
-SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*);
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...);
-#else
-# define IOTRACE(A)
-# define sqlite3VdbeIOTraceSql(X)
-#endif
-
-/*
-** These routines are available for the mem2.c debugging memory allocator
-** only. They are used to verify that different "types" of memory
-** allocations are properly tracked by the system.
-**
-** sqlite3MemdebugSetType() sets the "type" of an allocation to one of
-** the MEMTYPE_* macros defined below. The type must be a bitmask with
-** a single bit set.
-**
-** sqlite3MemdebugHasType() returns true if any of the bits in its second
-** argument match the type set by the previous sqlite3MemdebugSetType().
-** sqlite3MemdebugHasType() is intended for use inside assert() statements.
-**
-** sqlite3MemdebugNoType() returns true if none of the bits in its second
-** argument match the type set by the previous sqlite3MemdebugSetType().
-**
-** Perhaps the most important point is the difference between MEMTYPE_HEAP
-** and MEMTYPE_LOOKASIDE. If an allocation is MEMTYPE_LOOKASIDE, that means
-** it might have been allocated by lookaside, except the allocation was
-** too large or lookaside was already full. It is important to verify
-** that allocations that might have been satisfied by lookaside are not
-** passed back to non-lookaside free() routines. Asserts such as the
-** example above are placed on the non-lookaside free() routines to verify
-** this constraint.
-**
-** All of this is no-op for a production build. It only comes into
-** play when the SQLITE_MEMDEBUG compile-time option is used.
-*/
-#ifdef SQLITE_MEMDEBUG
-SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8);
-SQLITE_PRIVATE int sqlite3MemdebugHasType(void*,u8);
-SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8);
-#else
-# define sqlite3MemdebugSetType(X,Y) /* no-op */
-# define sqlite3MemdebugHasType(X,Y) 1
-# define sqlite3MemdebugNoType(X,Y) 1
-#endif
-#define MEMTYPE_HEAP 0x01 /* General heap allocations */
-#define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */
-#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
-#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
-#define MEMTYPE_DB 0x10 /* Uses sqlite3DbMalloc, not sqlite_malloc */
-
-#endif /* _SQLITEINT_H_ */
-
-/************** End of sqliteInt.h *******************************************/
-/************** Begin file global.c ******************************************/
-/*
-** 2008 June 13
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains definitions of global variables and contants.
-*/
-
-/* An array to map all upper-case characters into their corresponding
-** lower-case character.
-**
-** SQLite only considers US-ASCII (or EBCDIC) characters. We do not
-** handle case conversions for the UTF character set since the tables
-** involved are nearly as big or bigger than SQLite itself.
-*/
-SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
-#ifdef SQLITE_ASCII
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
- 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
- 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
- 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
- 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
- 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
- 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
- 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
- 252,253,254,255
-#endif
-#ifdef SQLITE_EBCDIC
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 0x */
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
- 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
- 96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
- 112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
- 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
- 144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
- 160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
- 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
- 192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
- 208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
- 224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
- 239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
-#endif
-};
-
-/*
-** The following 256 byte lookup table is used to support SQLites built-in
-** equivalents to the following standard library functions:
-**
-** isspace() 0x01
-** isalpha() 0x02
-** isdigit() 0x04
-** isalnum() 0x06
-** isxdigit() 0x08
-** toupper() 0x20
-** SQLite identifier character 0x40
-**
-** Bit 0x20 is set if the mapped character requires translation to upper
-** case. i.e. if the character is a lower-case ASCII character.
-** If x is a lower-case ASCII character, then its upper-case equivalent
-** is (x - 0x20). Therefore toupper() can be implemented as:
-**
-** (x & ~(map[x]&0x20))
-**
-** Standard function tolower() is implemented using the sqlite3UpperToLower[]
-** array. tolower() is used more often than toupper() by SQLite.
-**
-** Bit 0x40 is set if the character non-alphanumeric and can be used in an
-** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any
-** non-ASCII UTF character. Hence the test for whether or not a character is
-** part of an identifier is 0x46.
-**
-** SQLite's versions are identical to the standard versions assuming a
-** locale of "C". They are implemented as macros in sqliteInt.h.
-*/
-#ifdef SQLITE_ASCII
-SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
- 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */
- 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, /* 20..27 !"#$%&' */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */
- 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */
-
- 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */
- 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */
- 0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */
- 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */
-
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 80..87 ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 88..8f ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 90..97 ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 98..9f ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a0..a7 ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a8..af ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b0..b7 ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b8..bf ........ */
-
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c0..c7 ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c8..cf ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d0..d7 ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d8..df ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */
-};
-#endif
-
-#ifndef SQLITE_USE_URI
-# define SQLITE_USE_URI 0
-#endif
-
-#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
-# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
-#endif
-
-/*
-** The following singleton contains the global configuration for
-** the SQLite library.
-*/
-SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
- SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */
- 1, /* bCoreMutex */
- SQLITE_THREADSAFE==1, /* bFullMutex */
- SQLITE_USE_URI, /* bOpenUri */
- SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
- 0x7ffffffe, /* mxStrlen */
- 128, /* szLookaside */
- 500, /* nLookaside */
- {0,0,0,0,0,0,0,0}, /* m */
- {0,0,0,0,0,0,0,0,0}, /* mutex */
- {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
- (void*)0, /* pHeap */
- 0, /* nHeap */
- 0, 0, /* mnHeap, mxHeap */
- (void*)0, /* pScratch */
- 0, /* szScratch */
- 0, /* nScratch */
- (void*)0, /* pPage */
- 0, /* szPage */
- 0, /* nPage */
- 0, /* mxParserStack */
- 0, /* sharedCacheEnabled */
- /* All the rest should always be initialized to zero */
- 0, /* isInit */
- 0, /* inProgress */
- 0, /* isMutexInit */
- 0, /* isMallocInit */
- 0, /* isPCacheInit */
- 0, /* pInitMutex */
- 0, /* nRefInitMutex */
- 0, /* xLog */
- 0, /* pLogArg */
- 0, /* bLocaltimeFault */
-#ifdef SQLITE_ENABLE_SQLLOG
- 0, /* xSqllog */
- 0 /* pSqllogArg */
-#endif
-};
-
-
-/*
-** Hash table for global functions - functions common to all
-** database connections. After initialization, this table is
-** read-only.
-*/
-SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
-
-/*
-** Constant tokens for values 0 and 1.
-*/
-SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
- { "0", 1 },
- { "1", 1 }
-};
-
-
-/*
-** The value of the "pending" byte must be 0x40000000 (1 byte past the
-** 1-gibabyte boundary) in a compatible database. SQLite never uses
-** the database page that contains the pending byte. It never attempts
-** to read or write that page. The pending byte page is set assign
-** for use by the VFS layers as space for managing file locks.
-**
-** During testing, it is often desirable to move the pending byte to
-** a different position in the file. This allows code that has to
-** deal with the pending byte to run on files that are much smaller
-** than 1 GiB. The sqlite3_test_control() interface can be used to
-** move the pending byte.
-**
-** IMPORTANT: Changing the pending byte to any value other than
-** 0x40000000 results in an incompatible database file format!
-** Changing the pending byte during operating results in undefined
-** and dileterious behavior.
-*/
-#ifndef SQLITE_OMIT_WSD
-SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
-#endif
-
-/*
-** Properties of opcodes. The OPFLG_INITIALIZER macro is
-** created by mkopcodeh.awk during compilation. Data is obtained
-** from the comments following the "case OP_xxxx:" statements in
-** the vdbe.c file.
-*/
-SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
-
-/************** End of global.c **********************************************/
-/************** Begin file ctime.c *******************************************/
-/*
-** 2010 February 23
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file implements routines used to report what compile-time options
-** SQLite was built with.
-*/
-
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-
-
-/*
-** An array of names of all compile-time options. This array should
-** be sorted A-Z.
-**
-** This array looks large, but in a typical installation actually uses
-** only a handful of compile-time options, so most times this array is usually
-** rather short and uses little memory space.
-*/
-static const char * const azCompileOpt[] = {
-
-/* These macros are provided to "stringify" the value of the define
-** for those options in which the value is meaningful. */
-#define CTIMEOPT_VAL_(opt) #opt
-#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
-
-#ifdef SQLITE_32BIT_ROWID
- "32BIT_ROWID",
-#endif
-#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
- "4_BYTE_ALIGNED_MALLOC",
-#endif
-#ifdef SQLITE_CASE_SENSITIVE_LIKE
- "CASE_SENSITIVE_LIKE",
-#endif
-#ifdef SQLITE_CHECK_PAGES
- "CHECK_PAGES",
-#endif
-#ifdef SQLITE_COVERAGE_TEST
- "COVERAGE_TEST",
-#endif
-#ifdef SQLITE_CURDIR
- "CURDIR",
-#endif
-#ifdef SQLITE_DEBUG
- "DEBUG",
-#endif
-#ifdef SQLITE_DEFAULT_LOCKING_MODE
- "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
-#endif
-#ifdef SQLITE_DISABLE_DIRSYNC
- "DISABLE_DIRSYNC",
-#endif
-#ifdef SQLITE_DISABLE_LFS
- "DISABLE_LFS",
-#endif
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- "ENABLE_ATOMIC_WRITE",
-#endif
-#ifdef SQLITE_ENABLE_CEROD
- "ENABLE_CEROD",
-#endif
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
- "ENABLE_COLUMN_METADATA",
-#endif
-#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
- "ENABLE_EXPENSIVE_ASSERT",
-#endif
-#ifdef SQLITE_ENABLE_FTS1
- "ENABLE_FTS1",
-#endif
-#ifdef SQLITE_ENABLE_FTS2
- "ENABLE_FTS2",
-#endif
-#ifdef SQLITE_ENABLE_FTS3
- "ENABLE_FTS3",
-#endif
-#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS
- "ENABLE_FTS3_PARENTHESIS",
-#endif
-#ifdef SQLITE_ENABLE_FTS4
- "ENABLE_FTS4",
-#endif
-#ifdef SQLITE_ENABLE_ICU
- "ENABLE_ICU",
-#endif
-#ifdef SQLITE_ENABLE_IOTRACE
- "ENABLE_IOTRACE",
-#endif
-#ifdef SQLITE_ENABLE_LOAD_EXTENSION
- "ENABLE_LOAD_EXTENSION",
-#endif
-#ifdef SQLITE_ENABLE_LOCKING_STYLE
- "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
-#endif
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- "ENABLE_MEMORY_MANAGEMENT",
-#endif
-#ifdef SQLITE_ENABLE_MEMSYS3
- "ENABLE_MEMSYS3",
-#endif
-#ifdef SQLITE_ENABLE_MEMSYS5
- "ENABLE_MEMSYS5",
-#endif
-#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
- "ENABLE_OVERSIZE_CELL_CHECK",
-#endif
-#ifdef SQLITE_ENABLE_RTREE
- "ENABLE_RTREE",
-#endif
-#ifdef SQLITE_ENABLE_STAT3
- "ENABLE_STAT3",
-#endif
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
- "ENABLE_UNLOCK_NOTIFY",
-#endif
-#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
- "ENABLE_UPDATE_DELETE_LIMIT",
-#endif
-#ifdef SQLITE_HAS_CODEC
- "HAS_CODEC",
-#endif
-#ifdef SQLITE_HAVE_ISNAN
- "HAVE_ISNAN",
-#endif
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
- "HOMEGROWN_RECURSIVE_MUTEX",
-#endif
-#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
- "IGNORE_AFP_LOCK_ERRORS",
-#endif
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- "IGNORE_FLOCK_LOCK_ERRORS",
-#endif
-#ifdef SQLITE_INT64_TYPE
- "INT64_TYPE",
-#endif
-#ifdef SQLITE_LOCK_TRACE
- "LOCK_TRACE",
-#endif
-#ifdef SQLITE_MAX_SCHEMA_RETRY
- "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
-#endif
-#ifdef SQLITE_MEMDEBUG
- "MEMDEBUG",
-#endif
-#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
- "MIXED_ENDIAN_64BIT_FLOAT",
-#endif
-#ifdef SQLITE_NO_SYNC
- "NO_SYNC",
-#endif
-#ifdef SQLITE_OMIT_ALTERTABLE
- "OMIT_ALTERTABLE",
-#endif
-#ifdef SQLITE_OMIT_ANALYZE
- "OMIT_ANALYZE",
-#endif
-#ifdef SQLITE_OMIT_ATTACH
- "OMIT_ATTACH",
-#endif
-#ifdef SQLITE_OMIT_AUTHORIZATION
- "OMIT_AUTHORIZATION",
-#endif
-#ifdef SQLITE_OMIT_AUTOINCREMENT
- "OMIT_AUTOINCREMENT",
-#endif
-#ifdef SQLITE_OMIT_AUTOINIT
- "OMIT_AUTOINIT",
-#endif
-#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
- "OMIT_AUTOMATIC_INDEX",
-#endif
-#ifdef SQLITE_OMIT_AUTORESET
- "OMIT_AUTORESET",
-#endif
-#ifdef SQLITE_OMIT_AUTOVACUUM
- "OMIT_AUTOVACUUM",
-#endif
-#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
- "OMIT_BETWEEN_OPTIMIZATION",
-#endif
-#ifdef SQLITE_OMIT_BLOB_LITERAL
- "OMIT_BLOB_LITERAL",
-#endif
-#ifdef SQLITE_OMIT_BTREECOUNT
- "OMIT_BTREECOUNT",
-#endif
-#ifdef SQLITE_OMIT_BUILTIN_TEST
- "OMIT_BUILTIN_TEST",
-#endif
-#ifdef SQLITE_OMIT_CAST
- "OMIT_CAST",
-#endif
-#ifdef SQLITE_OMIT_CHECK
- "OMIT_CHECK",
-#endif
-/* // redundant
-** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS
-** "OMIT_COMPILEOPTION_DIAGS",
-** #endif
-*/
-#ifdef SQLITE_OMIT_COMPLETE
- "OMIT_COMPLETE",
-#endif
-#ifdef SQLITE_OMIT_COMPOUND_SELECT
- "OMIT_COMPOUND_SELECT",
-#endif
-#ifdef SQLITE_OMIT_DATETIME_FUNCS
- "OMIT_DATETIME_FUNCS",
-#endif
-#ifdef SQLITE_OMIT_DECLTYPE
- "OMIT_DECLTYPE",
-#endif
-#ifdef SQLITE_OMIT_DEPRECATED
- "OMIT_DEPRECATED",
-#endif
-#ifdef SQLITE_OMIT_DISKIO
- "OMIT_DISKIO",
-#endif
-#ifdef SQLITE_OMIT_EXPLAIN
- "OMIT_EXPLAIN",
-#endif
-#ifdef SQLITE_OMIT_FLAG_PRAGMAS
- "OMIT_FLAG_PRAGMAS",
-#endif
-#ifdef SQLITE_OMIT_FLOATING_POINT
- "OMIT_FLOATING_POINT",
-#endif
-#ifdef SQLITE_OMIT_FOREIGN_KEY
- "OMIT_FOREIGN_KEY",
-#endif
-#ifdef SQLITE_OMIT_GET_TABLE
- "OMIT_GET_TABLE",
-#endif
-#ifdef SQLITE_OMIT_INCRBLOB
- "OMIT_INCRBLOB",
-#endif
-#ifdef SQLITE_OMIT_INTEGRITY_CHECK
- "OMIT_INTEGRITY_CHECK",
-#endif
-#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
- "OMIT_LIKE_OPTIMIZATION",
-#endif
-#ifdef SQLITE_OMIT_LOAD_EXTENSION
- "OMIT_LOAD_EXTENSION",
-#endif
-#ifdef SQLITE_OMIT_LOCALTIME
- "OMIT_LOCALTIME",
-#endif
-#ifdef SQLITE_OMIT_LOOKASIDE
- "OMIT_LOOKASIDE",
-#endif
-#ifdef SQLITE_OMIT_MEMORYDB
- "OMIT_MEMORYDB",
-#endif
-#ifdef SQLITE_OMIT_MERGE_SORT
- "OMIT_MERGE_SORT",
-#endif
-#ifdef SQLITE_OMIT_OR_OPTIMIZATION
- "OMIT_OR_OPTIMIZATION",
-#endif
-#ifdef SQLITE_OMIT_PAGER_PRAGMAS
- "OMIT_PAGER_PRAGMAS",
-#endif
-#ifdef SQLITE_OMIT_PRAGMA
- "OMIT_PRAGMA",
-#endif
-#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
- "OMIT_PROGRESS_CALLBACK",
-#endif
-#ifdef SQLITE_OMIT_QUICKBALANCE
- "OMIT_QUICKBALANCE",
-#endif
-#ifdef SQLITE_OMIT_REINDEX
- "OMIT_REINDEX",
-#endif
-#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
- "OMIT_SCHEMA_PRAGMAS",
-#endif
-#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
- "OMIT_SCHEMA_VERSION_PRAGMAS",
-#endif
-#ifdef SQLITE_OMIT_SHARED_CACHE
- "OMIT_SHARED_CACHE",
-#endif
-#ifdef SQLITE_OMIT_SUBQUERY
- "OMIT_SUBQUERY",
-#endif
-#ifdef SQLITE_OMIT_TCL_VARIABLE
- "OMIT_TCL_VARIABLE",
-#endif
-#ifdef SQLITE_OMIT_TEMPDB
- "OMIT_TEMPDB",
-#endif
-#ifdef SQLITE_OMIT_TRACE
- "OMIT_TRACE",
-#endif
-#ifdef SQLITE_OMIT_TRIGGER
- "OMIT_TRIGGER",
-#endif
-#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
- "OMIT_TRUNCATE_OPTIMIZATION",
-#endif
-#ifdef SQLITE_OMIT_UTF16
- "OMIT_UTF16",
-#endif
-#ifdef SQLITE_OMIT_VACUUM
- "OMIT_VACUUM",
-#endif
-#ifdef SQLITE_OMIT_VIEW
- "OMIT_VIEW",
-#endif
-#ifdef SQLITE_OMIT_VIRTUALTABLE
- "OMIT_VIRTUALTABLE",
-#endif
-#ifdef SQLITE_OMIT_WAL
- "OMIT_WAL",
-#endif
-#ifdef SQLITE_OMIT_WSD
- "OMIT_WSD",
-#endif
-#ifdef SQLITE_OMIT_XFER_OPT
- "OMIT_XFER_OPT",
-#endif
-#ifdef SQLITE_PERFORMANCE_TRACE
- "PERFORMANCE_TRACE",
-#endif
-#ifdef SQLITE_PROXY_DEBUG
- "PROXY_DEBUG",
-#endif
-#ifdef SQLITE_RTREE_INT_ONLY
- "RTREE_INT_ONLY",
-#endif
-#ifdef SQLITE_SECURE_DELETE
- "SECURE_DELETE",
-#endif
-#ifdef SQLITE_SMALL_STACK
- "SMALL_STACK",
-#endif
-#ifdef SQLITE_SOUNDEX
- "SOUNDEX",
-#endif
-#ifdef SQLITE_TCL
- "TCL",
-#endif
-#ifdef SQLITE_TEMP_STORE
- "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
-#endif
-#ifdef SQLITE_TEST
- "TEST",
-#endif
-#ifdef SQLITE_THREADSAFE
- "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
-#endif
-#ifdef SQLITE_USE_ALLOCA
- "USE_ALLOCA",
-#endif
-#ifdef SQLITE_ZERO_MALLOC
- "ZERO_MALLOC"
-#endif
-};
-
-/*
-** Given the name of a compile-time option, return true if that option
-** was used and false if not.
-**
-** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
-** is not required for a match.
-*/
-SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
- int i, n;
- if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
- n = sqlite3Strlen30(zOptName);
-
- /* Since ArraySize(azCompileOpt) is normally in single digits, a
- ** linear search is adequate. No need for a binary search. */
- for(i=0; i<ArraySize(azCompileOpt); i++){
- if( (sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0)
- && ( (azCompileOpt[i][n]==0) || (azCompileOpt[i][n]=='=') ) ) return 1;
- }
- return 0;
-}
-
-/*
-** Return the N-th compile-time option string. If N is out of range,
-** return a NULL pointer.
-*/
-SQLITE_API const char *sqlite3_compileoption_get(int N){
- if( N>=0 && N<ArraySize(azCompileOpt) ){
- return azCompileOpt[N];
- }
- return 0;
-}
-
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
-
-/************** End of ctime.c ***********************************************/
-/************** Begin file status.c ******************************************/
-/*
-** 2008 June 18
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This module implements the sqlite3_status() interface and related
-** functionality.
-*/
-/************** Include vdbeInt.h in the middle of status.c ******************/
-/************** Begin file vdbeInt.h *****************************************/
-/*
-** 2003 September 6
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This is the header file for information that is private to the
-** VDBE. This information used to all be at the top of the single
-** source code file "vdbe.c". When that file became too big (over
-** 6000 lines long) it was split up into several smaller files and
-** this header information was factored out.
-*/
-#ifndef _VDBEINT_H_
-#define _VDBEINT_H_
-
-/*
-** SQL is translated into a sequence of instructions to be
-** executed by a virtual machine. Each instruction is an instance
-** of the following structure.
-*/
-typedef struct VdbeOp Op;
-
-/*
-** Boolean values
-*/
-typedef unsigned char Bool;
-
-/* Opaque type used by code in vdbesort.c */
-typedef struct VdbeSorter VdbeSorter;
-
-/* Opaque type used by the explainer */
-typedef struct Explain Explain;
-
-/*
-** A cursor is a pointer into a single BTree within a database file.
-** The cursor can seek to a BTree entry with a particular key, or
-** loop over all entries of the Btree. You can also insert new BTree
-** entries or retrieve the key or data from the entry that the cursor
-** is currently pointing to.
-**
-** Every cursor that the virtual machine has open is represented by an
-** instance of the following structure.
-*/
-struct VdbeCursor {
- BtCursor *pCursor; /* The cursor structure of the backend */
- Btree *pBt; /* Separate file holding temporary table */
- KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
- int iDb; /* Index of cursor database in db->aDb[] (or -1) */
- int pseudoTableReg; /* Register holding pseudotable content. */
- int nField; /* Number of fields in the header */
- Bool zeroed; /* True if zeroed out and ready for reuse */
- Bool rowidIsValid; /* True if lastRowid is valid */
- Bool atFirst; /* True if pointing to first entry */
- Bool useRandomRowid; /* Generate new record numbers semi-randomly */
- Bool nullRow; /* True if pointing to a row with no data */
- Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
- Bool isTable; /* True if a table requiring integer keys */
- Bool isIndex; /* True if an index containing keys only - no data */
- Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */
- Bool isSorter; /* True if a new-style sorter */
- Bool multiPseudo; /* Multi-register pseudo-cursor */
- sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
- const sqlite3_module *pModule; /* Module for cursor pVtabCursor */
- i64 seqCount; /* Sequence counter */
- i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
- i64 lastRowid; /* Last rowid from a Next or NextIdx operation */
- VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
-
- /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or
- ** OP_IsUnique opcode on this cursor. */
- int seekResult;
-
- /* Cached information about the header for the data record that the
- ** cursor is currently pointing to. Only valid if cacheStatus matches
- ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
- ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
- ** the cache is out of date.
- **
- ** aRow might point to (ephemeral) data for the current row, or it might
- ** be NULL.
- */
- u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
- int payloadSize; /* Total number of bytes in the record */
- u32 *aType; /* Type values for all entries in the record */
- u32 *aOffset; /* Cached offsets to the start of each columns data */
- u8 *aRow; /* Data for the current row, if all on one page */
-};
-typedef struct VdbeCursor VdbeCursor;
-
-/*
-** When a sub-program is executed (OP_Program), a structure of this type
-** is allocated to store the current value of the program counter, as
-** well as the current memory cell array and various other frame specific
-** values stored in the Vdbe struct. When the sub-program is finished,
-** these values are copied back to the Vdbe from the VdbeFrame structure,
-** restoring the state of the VM to as it was before the sub-program
-** began executing.
-**
-** The memory for a VdbeFrame object is allocated and managed by a memory
-** cell in the parent (calling) frame. When the memory cell is deleted or
-** overwritten, the VdbeFrame object is not freed immediately. Instead, it
-** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame
-** list is deleted when the VM is reset in VdbeHalt(). The reason for doing
-** this instead of deleting the VdbeFrame immediately is to avoid recursive
-** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the
-** child frame are released.
-**
-** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is
-** set to NULL if the currently executing frame is the main program.
-*/
-typedef struct VdbeFrame VdbeFrame;
-struct VdbeFrame {
- Vdbe *v; /* VM this frame belongs to */
- VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */
- Op *aOp; /* Program instructions for parent frame */
- Mem *aMem; /* Array of memory cells for parent frame */
- u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */
- VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
- void *token; /* Copy of SubProgram.token */
- i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
- u16 nCursor; /* Number of entries in apCsr */
- int pc; /* Program Counter in parent (calling) frame */
- int nOp; /* Size of aOp array */
- int nMem; /* Number of entries in aMem */
- int nOnceFlag; /* Number of entries in aOnceFlag */
- int nChildMem; /* Number of memory cells for child frame */
- int nChildCsr; /* Number of cursors for child frame */
- int nChange; /* Statement changes (Vdbe.nChanges) */
-};
-
-#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
-
-/*
-** A value for VdbeCursor.cacheValid that means the cache is always invalid.
-*/
-#define CACHE_STALE 0
-
-/*
-** Internally, the vdbe manipulates nearly all SQL values as Mem
-** structures. Each Mem struct may cache multiple representations (string,
-** integer etc.) of the same value.
-*/
-struct Mem {
- sqlite3 *db; /* The associated database connection */
- char *z; /* String or BLOB value */
- double r; /* Real value */
- union {
- i64 i; /* Integer value used when MEM_Int is set in flags */
- int nZero; /* Used when bit MEM_Zero is set in flags */
- FuncDef *pDef; /* Used only when flags==MEM_Agg */
- RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
- VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
- } u;
- int n; /* Number of characters in string value, excluding '\0' */
- u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
- u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
- u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
-#ifdef SQLITE_DEBUG
- Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
- void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
-#endif
- void (*xDel)(void *); /* If not null, call this function to delete Mem.z */
- char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */
-};
-
-/* One or more of the following flags are set to indicate the validOK
-** representations of the value stored in the Mem struct.
-**
-** If the MEM_Null flag is set, then the value is an SQL NULL value.
-** No other flags may be set in this case.
-**
-** If the MEM_Str flag is set then Mem.z points at a string representation.
-** Usually this is encoded in the same unicode encoding as the main
-** database (see below for exceptions). If the MEM_Term flag is also
-** set, then the string is nul terminated. The MEM_Int and MEM_Real
-** flags may coexist with the MEM_Str flag.
-*/
-#define MEM_Null 0x0001 /* Value is NULL */
-#define MEM_Str 0x0002 /* Value is a string */
-#define MEM_Int 0x0004 /* Value is an integer */
-#define MEM_Real 0x0008 /* Value is a real number */
-#define MEM_Blob 0x0010 /* Value is a BLOB */
-#define MEM_RowSet 0x0020 /* Value is a RowSet object */
-#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
-#define MEM_Invalid 0x0080 /* Value is undefined */
-#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
-#define MEM_TypeMask 0x01ff /* Mask of type bits */
-
-
-/* Whenever Mem contains a valid string or blob representation, one of
-** the following flags must be set to determine the memory management
-** policy for Mem.z. The MEM_Term flag tells us whether or not the
-** string is \000 or \u0000 terminated
-*/
-#define MEM_Term 0x0200 /* String rep is nul terminated */
-#define MEM_Dyn 0x0400 /* Need to call sqliteFree() on Mem.z */
-#define MEM_Static 0x0800 /* Mem.z points to a static string */
-#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
-#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
-#define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */
-#ifdef SQLITE_OMIT_INCRBLOB
- #undef MEM_Zero
- #define MEM_Zero 0x0000
-#endif
-
-/*
-** Clear any existing type flags from a Mem and replace them with f
-*/
-#define MemSetTypeFlag(p, f) \
- ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
-
-/*
-** Return true if a memory cell is not marked as invalid. This macro
-** is for use inside assert() statements only.
-*/
-#ifdef SQLITE_DEBUG
-#define memIsValid(M) ((M)->flags & MEM_Invalid)==0
-#endif
-
-
-/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
-** additional information about auxiliary information bound to arguments
-** of the function. This is used to implement the sqlite3_get_auxdata()
-** and sqlite3_set_auxdata() APIs. The "auxdata" is some auxiliary data
-** that can be associated with a constant argument to a function. This
-** allows functions such as "regexp" to compile their constant regular
-** expression argument once and reused the compiled code for multiple
-** invocations.
-*/
-struct VdbeFunc {
- FuncDef *pFunc; /* The definition of the function */
- int nAux; /* Number of entries allocated for apAux[] */
- struct AuxData {
- void *pAux; /* Aux data for the i-th argument */
- void (*xDelete)(void *); /* Destructor for the aux data */
- } apAux[1]; /* One slot for each function argument */
-};
-
-/*
-** The "context" argument for a installable function. A pointer to an
-** instance of this structure is the first argument to the routines used
-** implement the SQL functions.
-**
-** There is a typedef for this structure in sqlite.h. So all routines,
-** even the public interface to SQLite, can use a pointer to this structure.
-** But this file is the only place where the internal details of this
-** structure are known.
-**
-** This structure is defined inside of vdbeInt.h because it uses substructures
-** (Mem) which are only defined there.
-*/
-struct sqlite3_context {
- FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
- VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */
- Mem s; /* The return value is stored here */
- Mem *pMem; /* Memory cell used to store aggregate context */
- CollSeq *pColl; /* Collating sequence */
- int isError; /* Error code returned by the function. */
- int skipFlag; /* Skip skip accumulator loading if true */
-};
-
-/*
-** An Explain object accumulates indented output which is helpful
-** in describing recursive data structures.
-*/
-struct Explain {
- Vdbe *pVdbe; /* Attach the explanation to this Vdbe */
- StrAccum str; /* The string being accumulated */
- int nIndent; /* Number of elements in aIndent */
- u16 aIndent[100]; /* Levels of indentation */
- char zBase[100]; /* Initial space */
-};
-
-/* A bitfield type for use inside of structures. Always follow with :N where
-** N is the number of bits.
-*/
-typedef unsigned bft; /* Bit Field Type */
-
-/*
-** An instance of the virtual machine. This structure contains the complete
-** state of the virtual machine.
-**
-** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
-** is really a pointer to an instance of this structure.
-**
-** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
-** any virtual table method invocations made by the vdbe program. It is
-** set to 2 for xDestroy method calls and 1 for all other methods. This
-** variable is used for two purposes: to allow xDestroy methods to execute
-** "DROP TABLE" statements and to prevent some nasty side effects of
-** malloc failure when SQLite is invoked recursively by a virtual table
-** method function.
-*/
-struct Vdbe {
- sqlite3 *db; /* The database connection that owns this statement */
- Op *aOp; /* Space to hold the virtual machine's program */
- Mem *aMem; /* The memory locations */
- Mem **apArg; /* Arguments to currently executing user function */
- Mem *aColName; /* Column names to return */
- Mem *pResultSet; /* Pointer to an array of results */
- int nMem; /* Number of memory locations currently allocated */
- int nOp; /* Number of instructions in the program */
- int nOpAlloc; /* Number of slots allocated for aOp[] */
- int nLabel; /* Number of labels used */
- int *aLabel; /* Space to hold the labels */
- u16 nResColumn; /* Number of columns in one row of the result set */
- u16 nCursor; /* Number of slots in apCsr[] */
- u32 magic; /* Magic number for sanity checking */
- char *zErrMsg; /* Error message written here */
- Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
- VdbeCursor **apCsr; /* One element of this array for each open cursor */
- Mem *aVar; /* Values for the OP_Variable opcode. */
- char **azVar; /* Name of variables */
- ynVar nVar; /* Number of entries in aVar[] */
- ynVar nzVar; /* Number of entries in azVar[] */
- u32 cacheCtr; /* VdbeCursor row cache generation counter */
- int pc; /* The program counter */
- int rc; /* Value to return */
- u8 errorAction; /* Recovery action to do in case of an error */
- u8 minWriteFileFormat; /* Minimum file format for writable database files */
- bft explain:2; /* True if EXPLAIN present on SQL command */
- bft inVtabMethod:2; /* See comments above */
- bft changeCntOn:1; /* True to update the change-counter */
- bft expired:1; /* True if the VM needs to be recompiled */
- bft runOnlyOnce:1; /* Automatically expire on reset */
- bft usesStmtJournal:1; /* True if uses a statement journal */
- bft readOnly:1; /* True for read-only statements */
- bft isPrepareV2:1; /* True if prepared with prepare_v2() */
- bft doingRerun:1; /* True if rerunning after an auto-reprepare */
- int nChange; /* Number of db changes made since last reset */
- yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
- yDbMask lockMask; /* Subset of btreeMask that requires a lock */
- int iStatement; /* Statement number (or 0 if has not opened stmt) */
- int aCounter[3]; /* Counters used by sqlite3_stmt_status() */
-#ifndef SQLITE_OMIT_TRACE
- i64 startTime; /* Time when query started - used for profiling */
-#endif
- i64 nFkConstraint; /* Number of imm. FK constraints this VM */
- i64 nStmtDefCons; /* Number of def. constraints when stmt started */
- char *zSql; /* Text of the SQL statement that generated this */
- void *pFree; /* Free this when deleting the vdbe */
-#ifdef SQLITE_DEBUG
- FILE *trace; /* Write an execution trace here, if not NULL */
-#endif
-#ifdef SQLITE_ENABLE_TREE_EXPLAIN
- Explain *pExplain; /* The explainer */
- char *zExplain; /* Explanation of data structures */
-#endif
- VdbeFrame *pFrame; /* Parent frame */
- VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
- int nFrame; /* Number of frames in pFrame list */
- u32 expmask; /* Binding to these vars invalidates VM */
- SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
- int nOnceFlag; /* Size of array aOnceFlag[] */
- u8 *aOnceFlag; /* Flags for OP_Once */
-};
-
-/*
-** The following are allowed values for Vdbe.magic
-*/
-#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */
-#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */
-#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */
-#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
-
-/*
-** Function prototypes
-*/
-SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
-void sqliteVdbePopStack(Vdbe*,int);
-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
-#endif
-SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
-SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
-SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
-SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
-
-int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
-SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
-SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
-SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
-SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
-SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
-SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
-SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
-SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
-SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
-SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
-SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64
-#else
-SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
-#endif
-SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
-SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, int);
-SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
-SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
-SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
-SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
-SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p);
-#define VdbeMemRelease(X) \
- if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \
- sqlite3VdbeMemReleaseExternal(X);
-SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
-SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
-SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
-SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
-SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
-SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
-SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem);
-SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
-
-#ifdef SQLITE_OMIT_MERGE_SORT
-# define sqlite3VdbeSorterInit(Y,Z) SQLITE_OK
-# define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK
-# define sqlite3VdbeSorterClose(Y,Z)
-# define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK
-# define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK
-# define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK
-# define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK
-#else
-SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
-SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
-SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
-SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
-SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
-SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
-SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *);
-#endif
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
-SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*);
-#else
-# define sqlite3VdbeEnter(X)
-# define sqlite3VdbeLeave(X)
-#endif
-
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
-#endif
-
-#ifndef SQLITE_OMIT_FOREIGN_KEY
-SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
-#else
-# define sqlite3VdbeCheckFk(p,i) 0
-#endif
-
-SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
-#endif
-SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
-
-#ifndef SQLITE_OMIT_INCRBLOB
-SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *);
- #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)
-#else
- #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK
- #define ExpandBlob(P) SQLITE_OK
-#endif
-
-#endif /* !defined(_VDBEINT_H_) */
-
-/************** End of vdbeInt.h *********************************************/
-/************** Continuing where we left off in status.c *********************/
-
-/*
-** Variables in which to record status information.
-*/
-typedef struct sqlite3StatType sqlite3StatType;
-static SQLITE_WSD struct sqlite3StatType {
- int nowValue[10]; /* Current value */
- int mxValue[10]; /* Maximum value */
-} sqlite3Stat = { {0,}, {0,} };
-
-
-/* The "wsdStat" macro will resolve to the status information
-** state vector. If writable static data is unsupported on the target,
-** we have to locate the state vector at run-time. In the more common
-** case where writable static data is supported, wsdStat can refer directly
-** to the "sqlite3Stat" state vector declared above.
-*/
-#ifdef SQLITE_OMIT_WSD
-# define wsdStatInit sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat)
-# define wsdStat x[0]
-#else
-# define wsdStatInit
-# define wsdStat sqlite3Stat
-#endif
-
-/*
-** Return the current value of a status parameter.
-*/
-SQLITE_PRIVATE int sqlite3StatusValue(int op){
- wsdStatInit;
- assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- return wsdStat.nowValue[op];
-}
-
-/*
-** Add N to the value of a status record. It is assumed that the
-** caller holds appropriate locks.
-*/
-SQLITE_PRIVATE void sqlite3StatusAdd(int op, int N){
- wsdStatInit;
- assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- wsdStat.nowValue[op] += N;
- if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
- wsdStat.mxValue[op] = wsdStat.nowValue[op];
- }
-}
-
-/*
-** Set the value of a status to X.
-*/
-SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
- wsdStatInit;
- assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
- wsdStat.nowValue[op] = X;
- if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
- wsdStat.mxValue[op] = wsdStat.nowValue[op];
- }
-}
-
-/*
-** Query status information.
-**
-** This implementation assumes that reading or writing an aligned
-** 32-bit integer is an atomic operation. If that assumption is not true,
-** then this routine is not threadsafe.
-*/
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
- wsdStatInit;
- if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
- return SQLITE_MISUSE_BKPT;
- }
- *pCurrent = wsdStat.nowValue[op];
- *pHighwater = wsdStat.mxValue[op];
- if( resetFlag ){
- wsdStat.mxValue[op] = wsdStat.nowValue[op];
- }
- return SQLITE_OK;
-}
-
-/*
-** Query status information for a single database connection
-*/
-SQLITE_API int sqlite3_db_status(
- sqlite3 *db, /* The database connection whose status is desired */
- int op, /* Status verb */
- int *pCurrent, /* Write current value here */
- int *pHighwater, /* Write high-water mark here */
- int resetFlag /* Reset high-water mark if true */
-){
- int rc = SQLITE_OK; /* Return code */
- sqlite3_mutex_enter(db->mutex);
- switch( op ){
- case SQLITE_DBSTATUS_LOOKASIDE_USED: {
- *pCurrent = db->lookaside.nOut;
- *pHighwater = db->lookaside.mxOut;
- if( resetFlag ){
- db->lookaside.mxOut = db->lookaside.nOut;
- }
- break;
- }
-
- case SQLITE_DBSTATUS_LOOKASIDE_HIT:
- case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE:
- case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
- testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT );
- testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE );
- testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL );
- assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
- assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
- *pCurrent = 0;
- *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT];
- if( resetFlag ){
- db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0;
- }
- break;
- }
-
- /*
- ** Return an approximation for the amount of memory currently used
- ** by all pagers associated with the given database connection. The
- ** highwater mark is meaningless and is returned as zero.
- */
- case SQLITE_DBSTATUS_CACHE_USED: {
- int totalUsed = 0;
- int i;
- sqlite3BtreeEnterAll(db);
- for(i=0; i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- Pager *pPager = sqlite3BtreePager(pBt);
- totalUsed += sqlite3PagerMemUsed(pPager);
- }
- }
- sqlite3BtreeLeaveAll(db);
- *pCurrent = totalUsed;
- *pHighwater = 0;
- break;
- }
-
- /*
- ** *pCurrent gets an accurate estimate of the amount of memory used
- ** to store the schema for all databases (main, temp, and any ATTACHed
- ** databases. *pHighwater is set to zero.
- */
- case SQLITE_DBSTATUS_SCHEMA_USED: {
- int i; /* Used to iterate through schemas */
- int nByte = 0; /* Used to accumulate return value */
-
- sqlite3BtreeEnterAll(db);
- db->pnBytesFreed = &nByte;
- for(i=0; i<db->nDb; i++){
- Schema *pSchema = db->aDb[i].pSchema;
- if( ALWAYS(pSchema!=0) ){
- HashElem *p;
-
- nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * (
- pSchema->tblHash.count
- + pSchema->trigHash.count
- + pSchema->idxHash.count
- + pSchema->fkeyHash.count
- );
- nByte += sqlite3MallocSize(pSchema->tblHash.ht);
- nByte += sqlite3MallocSize(pSchema->trigHash.ht);
- nByte += sqlite3MallocSize(pSchema->idxHash.ht);
- nByte += sqlite3MallocSize(pSchema->fkeyHash.ht);
-
- for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
- sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
- }
- for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
- sqlite3DeleteTable(db, (Table *)sqliteHashData(p));
- }
- }
- }
- db->pnBytesFreed = 0;
- sqlite3BtreeLeaveAll(db);
-
- *pHighwater = 0;
- *pCurrent = nByte;
- break;
- }
-
- /*
- ** *pCurrent gets an accurate estimate of the amount of memory used
- ** to store all prepared statements.
- ** *pHighwater is set to zero.
- */
- case SQLITE_DBSTATUS_STMT_USED: {
- struct Vdbe *pVdbe; /* Used to iterate through VMs */
- int nByte = 0; /* Used to accumulate return value */
-
- db->pnBytesFreed = &nByte;
- for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
- sqlite3VdbeClearObject(db, pVdbe);
- sqlite3DbFree(db, pVdbe);
- }
- db->pnBytesFreed = 0;
-
- *pHighwater = 0;
- *pCurrent = nByte;
-
- break;
- }
-
- /*
- ** Set *pCurrent to the total cache hits or misses encountered by all
- ** pagers the database handle is connected to. *pHighwater is always set
- ** to zero.
- */
- case SQLITE_DBSTATUS_CACHE_HIT:
- case SQLITE_DBSTATUS_CACHE_MISS:
- case SQLITE_DBSTATUS_CACHE_WRITE:{
- int i;
- int nRet = 0;
- assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
- assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );
-
- for(i=0; i<db->nDb; i++){
- if( db->aDb[i].pBt ){
- Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
- sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
- }
- }
- *pHighwater = 0;
- *pCurrent = nRet;
- break;
- }
-
- default: {
- rc = SQLITE_ERROR;
- }
- }
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/************** End of status.c **********************************************/
-/************** Begin file date.c ********************************************/
-/*
-** 2003 October 31
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the C functions that implement date and time
-** functions for SQLite.
-**
-** There is only one exported symbol in this file - the function
-** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
-** All other code has file scope.
-**
-** SQLite processes all times and dates as Julian Day numbers. The
-** dates and times are stored as the number of days since noon
-** in Greenwich on November 24, 4714 B.C. according to the Gregorian
-** calendar system.
-**
-** 1970-01-01 00:00:00 is JD 2440587.5
-** 2000-01-01 00:00:00 is JD 2451544.5
-**
-** This implemention requires years to be expressed as a 4-digit number
-** which means that only dates between 0000-01-01 and 9999-12-31 can
-** be represented, even though julian day numbers allow a much wider
-** range of dates.
-**
-** The Gregorian calendar system is used for all dates and times,
-** even those that predate the Gregorian calendar. Historians usually
-** use the Julian calendar for dates prior to 1582-10-15 and for some
-** dates afterwards, depending on locale. Beware of this difference.
-**
-** The conversion algorithms are implemented based on descriptions
-** in the following text:
-**
-** Jean Meeus
-** Astronomical Algorithms, 2nd Edition, 1998
-** ISBM 0-943396-61-1
-** Willmann-Bell, Inc
-** Richmond, Virginia (USA)
-*/
-/* #include <stdlib.h> */
-/* #include <assert.h> */
-#include <time.h>
-
-#ifndef SQLITE_OMIT_DATETIME_FUNCS
-
-
-/*
-** A structure for holding a single date and time.
-*/
-typedef struct DateTime DateTime;
-struct DateTime {
- sqlite3_int64 iJD; /* The julian day number times 86400000 */
- int Y, M, D; /* Year, month, and day */
- int h, m; /* Hour and minutes */
- int tz; /* Timezone offset in minutes */
- double s; /* Seconds */
- char validYMD; /* True (1) if Y,M,D are valid */
- char validHMS; /* True (1) if h,m,s are valid */
- char validJD; /* True (1) if iJD is valid */
- char validTZ; /* True (1) if tz is valid */
-};
-
-
-/*
-** Convert zDate into one or more integers. Additional arguments
-** come in groups of 5 as follows:
-**
-** N number of digits in the integer
-** min minimum allowed value of the integer
-** max maximum allowed value of the integer
-** nextC first character after the integer
-** pVal where to write the integers value.
-**
-** Conversions continue until one with nextC==0 is encountered.
-** The function returns the number of successful conversions.
-*/
-static int getDigits(const char *zDate, ...){
- va_list ap;
- int val;
- int N;
- int min;
- int max;
- int nextC;
- int *pVal;
- int cnt = 0;
- va_start(ap, zDate);
- do{
- N = va_arg(ap, int);
- min = va_arg(ap, int);
- max = va_arg(ap, int);
- nextC = va_arg(ap, int);
- pVal = va_arg(ap, int*);
- val = 0;
- while( N-- ){
- if( !sqlite3Isdigit(*zDate) ){
- goto end_getDigits;
- }
- val = val*10 + *zDate - '0';
- zDate++;
- }
- if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
- goto end_getDigits;
- }
- *pVal = val;
- zDate++;
- cnt++;
- }while( nextC );
-end_getDigits:
- va_end(ap);
- return cnt;
-}
-
-/*
-** Parse a timezone extension on the end of a date-time.
-** The extension is of the form:
-**
-** (+/-)HH:MM
-**
-** Or the "zulu" notation:
-**
-** Z
-**
-** If the parse is successful, write the number of minutes
-** of change in p->tz and return 0. If a parser error occurs,
-** return non-zero.
-**
-** A missing specifier is not considered an error.
-*/
-static int parseTimezone(const char *zDate, DateTime *p){
- int sgn = 0;
- int nHr, nMn;
- int c;
- while( sqlite3Isspace(*zDate) ){ zDate++; }
- p->tz = 0;
- c = *zDate;
- if( c=='-' ){
- sgn = -1;
- }else if( c=='+' ){
- sgn = +1;
- }else if( c=='Z' || c=='z' ){
- zDate++;
- goto zulu_time;
- }else{
- return c!=0;
- }
- zDate++;
- if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
- return 1;
- }
- zDate += 5;
- p->tz = sgn*(nMn + nHr*60);
-zulu_time:
- while( sqlite3Isspace(*zDate) ){ zDate++; }
- return *zDate!=0;
-}
-
-/*
-** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
-** The HH, MM, and SS must each be exactly 2 digits. The
-** fractional seconds FFFF can be one or more digits.
-**
-** Return 1 if there is a parsing error and 0 on success.
-*/
-static int parseHhMmSs(const char *zDate, DateTime *p){
- int h, m, s;
- double ms = 0.0;
- if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
- return 1;
- }
- zDate += 5;
- if( *zDate==':' ){
- zDate++;
- if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
- return 1;
- }
- zDate += 2;
- if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){
- double rScale = 1.0;
- zDate++;
- while( sqlite3Isdigit(*zDate) ){
- ms = ms*10.0 + *zDate - '0';
- rScale *= 10.0;
- zDate++;
- }
- ms /= rScale;
- }
- }else{
- s = 0;
- }
- p->validJD = 0;
- p->validHMS = 1;
- p->h = h;
- p->m = m;
- p->s = s + ms;
- if( parseTimezone(zDate, p) ) return 1;
- p->validTZ = (p->tz!=0)?1:0;
- return 0;
-}
-
-/*
-** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume
-** that the YYYY-MM-DD is according to the Gregorian calendar.
-**
-** Reference: Meeus page 61
-*/
-static void computeJD(DateTime *p){
- int Y, M, D, A, B, X1, X2;
-
- if( p->validJD ) return;
- if( p->validYMD ){
- Y = p->Y;
- M = p->M;
- D = p->D;
- }else{
- Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */
- M = 1;
- D = 1;
- }
- if( M<=2 ){
- Y--;
- M += 12;
- }
- A = Y/100;
- B = 2 - A + (A/4);
- X1 = 36525*(Y+4716)/100;
- X2 = 306001*(M+1)/10000;
- p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
- p->validJD = 1;
- if( p->validHMS ){
- p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000);
- if( p->validTZ ){
- p->iJD -= p->tz*60000;
- p->validYMD = 0;
- p->validHMS = 0;
- p->validTZ = 0;
- }
- }
-}
-
-/*
-** Parse dates of the form
-**
-** YYYY-MM-DD HH:MM:SS.FFF
-** YYYY-MM-DD HH:MM:SS
-** YYYY-MM-DD HH:MM
-** YYYY-MM-DD
-**
-** Write the result into the DateTime structure and return 0
-** on success and 1 if the input string is not a well-formed
-** date.
-*/
-static int parseYyyyMmDd(const char *zDate, DateTime *p){
- int Y, M, D, neg;
-
- if( zDate[0]=='-' ){
- zDate++;
- neg = 1;
- }else{
- neg = 0;
- }
- if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
- return 1;
- }
- zDate += 10;
- while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
- if( parseHhMmSs(zDate, p)==0 ){
- /* We got the time */
- }else if( *zDate==0 ){
- p->validHMS = 0;
- }else{
- return 1;
- }
- p->validJD = 0;
- p->validYMD = 1;
- p->Y = neg ? -Y : Y;
- p->M = M;
- p->D = D;
- if( p->validTZ ){
- computeJD(p);
- }
- return 0;
-}
-
-/*
-** Set the time to the current time reported by the VFS.
-**
-** Return the number of errors.
-*/
-static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
- sqlite3 *db = sqlite3_context_db_handle(context);
- if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){
- p->validJD = 1;
- return 0;
- }else{
- return 1;
- }
-}
-
-/*
-** Attempt to parse the given string into a Julian Day Number. Return
-** the number of errors.
-**
-** The following are acceptable forms for the input string:
-**
-** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM
-** DDDD.DD
-** now
-**
-** In the first form, the +/-HH:MM is always optional. The fractional
-** seconds extension (the ".FFF") is optional. The seconds portion
-** (":SS.FFF") is option. The year and date can be omitted as long
-** as there is a time string. The time string can be omitted as long
-** as there is a year and date.
-*/
-static int parseDateOrTime(
- sqlite3_context *context,
- const char *zDate,
- DateTime *p
-){
- double r;
- if( parseYyyyMmDd(zDate,p)==0 ){
- return 0;
- }else if( parseHhMmSs(zDate, p)==0 ){
- return 0;
- }else if( sqlite3StrICmp(zDate,"now")==0){
- return setDateTimeToCurrent(context, p);
- }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
- p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
- p->validJD = 1;
- return 0;
- }
- return 1;
-}
-
-/*
-** Compute the Year, Month, and Day from the julian day number.
-*/
-static void computeYMD(DateTime *p){
- int Z, A, B, C, D, E, X1;
- if( p->validYMD ) return;
- if( !p->validJD ){
- p->Y = 2000;
- p->M = 1;
- p->D = 1;
- }else{
- Z = (int)((p->iJD + 43200000)/86400000);
- A = (int)((Z - 1867216.25)/36524.25);
- A = Z + 1 + A - (A/4);
- B = A + 1524;
- C = (int)((B - 122.1)/365.25);
- D = (36525*C)/100;
- E = (int)((B-D)/30.6001);
- X1 = (int)(30.6001*E);
- p->D = B - D - X1;
- p->M = E<14 ? E-1 : E-13;
- p->Y = p->M>2 ? C - 4716 : C - 4715;
- }
- p->validYMD = 1;
-}
-
-/*
-** Compute the Hour, Minute, and Seconds from the julian day number.
-*/
-static void computeHMS(DateTime *p){
- int s;
- if( p->validHMS ) return;
- computeJD(p);
- s = (int)((p->iJD + 43200000) % 86400000);
- p->s = s/1000.0;
- s = (int)p->s;
- p->s -= s;
- p->h = s/3600;
- s -= p->h*3600;
- p->m = s/60;
- p->s += s - p->m*60;
- p->validHMS = 1;
-}
-
-/*
-** Compute both YMD and HMS
-*/
-static void computeYMD_HMS(DateTime *p){
- computeYMD(p);
- computeHMS(p);
-}
-
-/*
-** Clear the YMD and HMS and the TZ
-*/
-static void clearYMD_HMS_TZ(DateTime *p){
- p->validYMD = 0;
- p->validHMS = 0;
- p->validTZ = 0;
-}
-
-/*
-** On recent Windows platforms, the localtime_s() function is available
-** as part of the "Secure CRT". It is essentially equivalent to
-** localtime_r() available under most POSIX platforms, except that the
-** order of the parameters is reversed.
-**
-** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
-**
-** If the user has not indicated to use localtime_r() or localtime_s()
-** already, check for an MSVC build environment that provides
-** localtime_s().
-*/
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
- defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
-#define HAVE_LOCALTIME_S 1
-#endif
-
-#ifndef SQLITE_OMIT_LOCALTIME
-/*
-** The following routine implements the rough equivalent of localtime_r()
-** using whatever operating-system specific localtime facility that
-** is available. This routine returns 0 on success and
-** non-zero on any kind of error.
-**
-** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
-** routine will always fail.
-*/
-static int osLocaltime(time_t *t, struct tm *pTm){
- int rc;
-#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \
- && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S)
- struct tm *pX;
-#if SQLITE_THREADSAFE>0
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- sqlite3_mutex_enter(mutex);
- pX = localtime(t);
-#ifndef SQLITE_OMIT_BUILTIN_TEST
- if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
-#endif
- if( pX ) *pTm = *pX;
- sqlite3_mutex_leave(mutex);
- rc = pX==0;
-#else
-#ifndef SQLITE_OMIT_BUILTIN_TEST
- if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
-#endif
-#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R
- rc = localtime_r(t, pTm)==0;
-#else
- rc = localtime_s(pTm, t);
-#endif /* HAVE_LOCALTIME_R */
-#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */
- return rc;
-}
-#endif /* SQLITE_OMIT_LOCALTIME */
-
-
-#ifndef SQLITE_OMIT_LOCALTIME
-/*
-** Compute the difference (in milliseconds) between localtime and UTC
-** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
-** return this value and set *pRc to SQLITE_OK.
-**
-** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
-** is undefined in this case.
-*/
-static sqlite3_int64 localtimeOffset(
- DateTime *p, /* Date at which to calculate offset */
- sqlite3_context *pCtx, /* Write error here if one occurs */
- int *pRc /* OUT: Error code. SQLITE_OK or ERROR */
-){
- DateTime x, y;
- time_t t;
- struct tm sLocal;
-
- /* Initialize the contents of sLocal to avoid a compiler warning. */
- memset(&sLocal, 0, sizeof(sLocal));
-
- x = *p;
- computeYMD_HMS(&x);
- if( x.Y<1971 || x.Y>=2038 ){
- x.Y = 2000;
- x.M = 1;
- x.D = 1;
- x.h = 0;
- x.m = 0;
- x.s = 0.0;
- } else {
- int s = (int)(x.s + 0.5);
- x.s = s;
- }
- x.tz = 0;
- x.validJD = 0;
- computeJD(&x);
- t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
- if( osLocaltime(&t, &sLocal) ){
- sqlite3_result_error(pCtx, "local time unavailable", -1);
- *pRc = SQLITE_ERROR;
- return 0;
- }
- y.Y = sLocal.tm_year + 1900;
- y.M = sLocal.tm_mon + 1;
- y.D = sLocal.tm_mday;
- y.h = sLocal.tm_hour;
- y.m = sLocal.tm_min;
- y.s = sLocal.tm_sec;
- y.validYMD = 1;
- y.validHMS = 1;
- y.validJD = 0;
- y.validTZ = 0;
- computeJD(&y);
- *pRc = SQLITE_OK;
- return y.iJD - x.iJD;
-}
-#endif /* SQLITE_OMIT_LOCALTIME */
-
-/*
-** Process a modifier to a date-time stamp. The modifiers are
-** as follows:
-**
-** NNN days
-** NNN hours
-** NNN minutes
-** NNN.NNNN seconds
-** NNN months
-** NNN years
-** start of month
-** start of year
-** start of week
-** start of day
-** weekday N
-** unixepoch
-** localtime
-** utc
-**
-** Return 0 on success and 1 if there is any kind of error. If the error
-** is in a system call (i.e. localtime()), then an error message is written
-** to context pCtx. If the error is an unrecognized modifier, no error is
-** written to pCtx.
-*/
-static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
- int rc = 1;
- int n;
- double r;
- char *z, zBuf[30];
- z = zBuf;
- for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
- z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
- }
- z[n] = 0;
- switch( z[0] ){
-#ifndef SQLITE_OMIT_LOCALTIME
- case 'l': {
- /* localtime
- **
- ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
- ** show local time.
- */
- if( strcmp(z, "localtime")==0 ){
- computeJD(p);
- p->iJD += localtimeOffset(p, pCtx, &rc);
- clearYMD_HMS_TZ(p);
- }
- break;
- }
-#endif
- case 'u': {
- /*
- ** unixepoch
- **
- ** Treat the current value of p->iJD as the number of
- ** seconds since 1970. Convert to a real julian day number.
- */
- if( strcmp(z, "unixepoch")==0 && p->validJD ){
- p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
- clearYMD_HMS_TZ(p);
- rc = 0;
- }
-#ifndef SQLITE_OMIT_LOCALTIME
- else if( strcmp(z, "utc")==0 ){
- sqlite3_int64 c1;
- computeJD(p);
- c1 = localtimeOffset(p, pCtx, &rc);
- if( rc==SQLITE_OK ){
- p->iJD -= c1;
- clearYMD_HMS_TZ(p);
- p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
- }
- }
-#endif
- break;
- }
- case 'w': {
- /*
- ** weekday N
- **
- ** Move the date to the same time on the next occurrence of
- ** weekday N where 0==Sunday, 1==Monday, and so forth. If the
- ** date is already on the appropriate weekday, this is a no-op.
- */
- if( strncmp(z, "weekday ", 8)==0
- && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
- && (n=(int)r)==r && n>=0 && r<7 ){
- sqlite3_int64 Z;
- computeYMD_HMS(p);
- p->validTZ = 0;
- p->validJD = 0;
- computeJD(p);
- Z = ((p->iJD + 129600000)/86400000) % 7;
- if( Z>n ) Z -= 7;
- p->iJD += (n - Z)*86400000;
- clearYMD_HMS_TZ(p);
- rc = 0;
- }
- break;
- }
- case 's': {
- /*
- ** start of TTTTT
- **
- ** Move the date backwards to the beginning of the current day,
- ** or month or year.
- */
- if( strncmp(z, "start of ", 9)!=0 ) break;
- z += 9;
- computeYMD(p);
- p->validHMS = 1;
- p->h = p->m = 0;
- p->s = 0.0;
- p->validTZ = 0;
- p->validJD = 0;
- if( strcmp(z,"month")==0 ){
- p->D = 1;
- rc = 0;
- }else if( strcmp(z,"year")==0 ){
- computeYMD(p);
- p->M = 1;
- p->D = 1;
- rc = 0;
- }else if( strcmp(z,"day")==0 ){
- rc = 0;
- }
- break;
- }
- case '+':
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- double rRounder;
- for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
- if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
- rc = 1;
- break;
- }
- if( z[n]==':' ){
- /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
- ** specified number of hours, minutes, seconds, and fractional seconds
- ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be
- ** omitted.
- */
- const char *z2 = z;
- DateTime tx;
- sqlite3_int64 day;
- if( !sqlite3Isdigit(*z2) ) z2++;
- memset(&tx, 0, sizeof(tx));
- if( parseHhMmSs(z2, &tx) ) break;
- computeJD(&tx);
- tx.iJD -= 43200000;
- day = tx.iJD/86400000;
- tx.iJD -= day*86400000;
- if( z[0]=='-' ) tx.iJD = -tx.iJD;
- computeJD(p);
- clearYMD_HMS_TZ(p);
- p->iJD += tx.iJD;
- rc = 0;
- break;
- }
- z += n;
- while( sqlite3Isspace(*z) ) z++;
- n = sqlite3Strlen30(z);
- if( n>10 || n<3 ) break;
- if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
- computeJD(p);
- rc = 0;
- rRounder = r<0 ? -0.5 : +0.5;
- if( n==3 && strcmp(z,"day")==0 ){
- p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
- }else if( n==4 && strcmp(z,"hour")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
- }else if( n==6 && strcmp(z,"minute")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
- }else if( n==6 && strcmp(z,"second")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
- }else if( n==5 && strcmp(z,"month")==0 ){
- int x, y;
- computeYMD_HMS(p);
- p->M += (int)r;
- x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
- p->Y += x;
- p->M -= x*12;
- p->validJD = 0;
- computeJD(p);
- y = (int)r;
- if( y!=r ){
- p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
- }
- }else if( n==4 && strcmp(z,"year")==0 ){
- int y = (int)r;
- computeYMD_HMS(p);
- p->Y += y;
- p->validJD = 0;
- computeJD(p);
- if( y!=r ){
- p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
- }
- }else{
- rc = 1;
- }
- clearYMD_HMS_TZ(p);
- break;
- }
- default: {
- break;
- }
- }
- return rc;
-}
-
-/*
-** Process time function arguments. argv[0] is a date-time stamp.
-** argv[1] and following are modifiers. Parse them all and write
-** the resulting time into the DateTime structure p. Return 0
-** on success and 1 if there are any errors.
-**
-** If there are zero parameters (if even argv[0] is undefined)
-** then assume a default value of "now" for argv[0].
-*/
-static int isDate(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv,
- DateTime *p
-){
- int i;
- const unsigned char *z;
- int eType;
- memset(p, 0, sizeof(*p));
- if( argc==0 ){
- return setDateTimeToCurrent(context, p);
- }
- if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
- || eType==SQLITE_INTEGER ){
- p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
- p->validJD = 1;
- }else{
- z = sqlite3_value_text(argv[0]);
- if( !z || parseDateOrTime(context, (char*)z, p) ){
- return 1;
- }
- }
- for(i=1; i<argc; i++){
- z = sqlite3_value_text(argv[i]);
- if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
- }
- return 0;
-}
-
-
-/*
-** The following routines implement the various date and time functions
-** of SQLite.
-*/
-
-/*
-** julianday( TIMESTRING, MOD, MOD, ...)
-**
-** Return the julian day number of the date specified in the arguments
-*/
-static void juliandayFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- computeJD(&x);
- sqlite3_result_double(context, x.iJD/86400000.0);
- }
-}
-
-/*
-** datetime( TIMESTRING, MOD, MOD, ...)
-**
-** Return YYYY-MM-DD HH:MM:SS
-*/
-static void datetimeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- char zBuf[100];
- computeYMD_HMS(&x);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
- x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
-}
-
-/*
-** time( TIMESTRING, MOD, MOD, ...)
-**
-** Return HH:MM:SS
-*/
-static void timeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- char zBuf[100];
- computeHMS(&x);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
-}
-
-/*
-** date( TIMESTRING, MOD, MOD, ...)
-**
-** Return YYYY-MM-DD
-*/
-static void dateFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- if( isDate(context, argc, argv, &x)==0 ){
- char zBuf[100];
- computeYMD(&x);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
-}
-
-/*
-** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
-**
-** Return a string described by FORMAT. Conversions as follows:
-**
-** %d day of month
-** %f ** fractional seconds SS.SSS
-** %H hour 00-24
-** %j day of year 000-366
-** %J ** Julian day number
-** %m month 01-12
-** %M minute 00-59
-** %s seconds since 1970-01-01
-** %S seconds 00-59
-** %w day of week 0-6 sunday==0
-** %W week of year 00-53
-** %Y year 0000-9999
-** %% %
-*/
-static void strftimeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- DateTime x;
- u64 n;
- size_t i,j;
- char *z;
- sqlite3 *db;
- const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
- char zBuf[100];
- if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
- db = sqlite3_context_db_handle(context);
- for(i=0, n=1; zFmt[i]; i++, n++){
- if( zFmt[i]=='%' ){
- switch( zFmt[i+1] ){
- case 'd':
- case 'H':
- case 'm':
- case 'M':
- case 'S':
- case 'W':
- n++;
- /* fall thru */
- case 'w':
- case '%':
- break;
- case 'f':
- n += 8;
- break;
- case 'j':
- n += 3;
- break;
- case 'Y':
- n += 8;
- break;
- case 's':
- case 'J':
- n += 50;
- break;
- default:
- return; /* ERROR. return a NULL */
- }
- i++;
- }
- }
- testcase( n==sizeof(zBuf)-1 );
- testcase( n==sizeof(zBuf) );
- testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
- testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
- if( n<sizeof(zBuf) ){
- z = zBuf;
- }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- return;
- }else{
- z = sqlite3DbMallocRaw(db, (int)n);
- if( z==0 ){
- sqlite3_result_error_nomem(context);
- return;
- }
- }
- computeJD(&x);
- computeYMD_HMS(&x);
- for(i=j=0; zFmt[i]; i++){
- if( zFmt[i]!='%' ){
- z[j++] = zFmt[i];
- }else{
- i++;
- switch( zFmt[i] ){
- case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break;
- case 'f': {
- double s = x.s;
- if( s>59.999 ) s = 59.999;
- sqlite3_snprintf(7, &z[j],"%06.3f", s);
- j += sqlite3Strlen30(&z[j]);
- break;
- }
- case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;
- case 'W': /* Fall thru */
- case 'j': {
- int nDay; /* Number of days since 1st day of year */
- DateTime y = x;
- y.validJD = 0;
- y.M = 1;
- y.D = 1;
- computeJD(&y);
- nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
- if( zFmt[i]=='W' ){
- int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */
- wd = (int)(((x.iJD+43200000)/86400000)%7);
- sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
- j += 2;
- }else{
- sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
- j += 3;
- }
- break;
- }
- case 'J': {
- sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
- j+=sqlite3Strlen30(&z[j]);
- break;
- }
- case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
- case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
- case 's': {
- sqlite3_snprintf(30,&z[j],"%lld",
- (i64)(x.iJD/1000 - 21086676*(i64)10000));
- j += sqlite3Strlen30(&z[j]);
- break;
- }
- case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
- case 'w': {
- z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
- break;
- }
- case 'Y': {
- sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
- break;
- }
- default: z[j++] = '%'; break;
- }
- }
- }
- z[j] = 0;
- sqlite3_result_text(context, z, -1,
- z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
-}
-
-/*
-** current_time()
-**
-** This function returns the same value as time('now').
-*/
-static void ctimeFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- timeFunc(context, 0, 0);
-}
-
-/*
-** current_date()
-**
-** This function returns the same value as date('now').
-*/
-static void cdateFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- dateFunc(context, 0, 0);
-}
-
-/*
-** current_timestamp()
-**
-** This function returns the same value as datetime('now').
-*/
-static void ctimestampFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- datetimeFunc(context, 0, 0);
-}
-#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
-
-#ifdef SQLITE_OMIT_DATETIME_FUNCS
-/*
-** If the library is compiled to omit the full-scale date and time
-** handling (to get a smaller binary), the following minimal version
-** of the functions current_time(), current_date() and current_timestamp()
-** are included instead. This is to support column declarations that
-** include "DEFAULT CURRENT_TIME" etc.
-**
-** This function uses the C-library functions time(), gmtime()
-** and strftime(). The format string to pass to strftime() is supplied
-** as the user-data for the function.
-*/
-static void currentTimeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- time_t t;
- char *zFormat = (char *)sqlite3_user_data(context);
- sqlite3 *db;
- sqlite3_int64 iT;
- struct tm *pTm;
- struct tm sNow;
- char zBuf[20];
-
- UNUSED_PARAMETER(argc);
- UNUSED_PARAMETER(argv);
-
- db = sqlite3_context_db_handle(context);
- if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
- t = iT/1000 - 10000*(sqlite3_int64)21086676;
-#ifdef HAVE_GMTIME_R
- pTm = gmtime_r(&t, &sNow);
-#else
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- pTm = gmtime(&t);
- if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-#endif
- if( pTm ){
- strftime(zBuf, 20, zFormat, &sNow);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- }
-}
-#endif
-
-/*
-** This function registered all of the above C functions as SQL
-** functions. This should be the only routine in this file with
-** external linkage.
-*/
-SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
- static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
-#ifndef SQLITE_OMIT_DATETIME_FUNCS
- FUNCTION(julianday, -1, 0, 0, juliandayFunc ),
- FUNCTION(date, -1, 0, 0, dateFunc ),
- FUNCTION(time, -1, 0, 0, timeFunc ),
- FUNCTION(datetime, -1, 0, 0, datetimeFunc ),
- FUNCTION(strftime, -1, 0, 0, strftimeFunc ),
- FUNCTION(current_time, 0, 0, 0, ctimeFunc ),
- FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
- FUNCTION(current_date, 0, 0, 0, cdateFunc ),
-#else
- STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc),
- STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc),
- STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
-#endif
- };
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
-
- for(i=0; i<ArraySize(aDateTimeFuncs); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
-}
-
-/************** End of date.c ************************************************/
-/************** Begin file os.c **********************************************/
-/*
-** 2005 November 29
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains OS interface code that is common to all
-** architectures.
-*/
-#define _SQLITE_OS_C_ 1
-#undef _SQLITE_OS_C_
-
-/*
-** The default SQLite sqlite3_vfs implementations do not allocate
-** memory (actually, os_unix.c allocates a small amount of memory
-** from within OsOpen()), but some third-party implementations may.
-** So we test the effects of a malloc() failing and the sqlite3OsXXX()
-** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
-**
-** The following functions are instrumented for malloc() failure
-** testing:
-**
-** sqlite3OsRead()
-** sqlite3OsWrite()
-** sqlite3OsSync()
-** sqlite3OsFileSize()
-** sqlite3OsLock()
-** sqlite3OsCheckReservedLock()
-** sqlite3OsFileControl()
-** sqlite3OsShmMap()
-** sqlite3OsOpen()
-** sqlite3OsDelete()
-** sqlite3OsAccess()
-** sqlite3OsFullPathname()
-**
-*/
-#if defined(SQLITE_TEST)
-SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
- #define DO_OS_MALLOC_TEST(x) \
- if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \
- void *pTstAlloc = sqlite3Malloc(10); \
- if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
- sqlite3_free(pTstAlloc); \
- }
-#else
- #define DO_OS_MALLOC_TEST(x)
-#endif
-
-/*
-** The following routines are convenience wrappers around methods
-** of the sqlite3_file object. This is mostly just syntactic sugar. All
-** of this would be completely automatic if SQLite were coded using
-** C++ instead of plain old C.
-*/
-SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file *pId){
- int rc = SQLITE_OK;
- if( pId->pMethods ){
- rc = pId->pMethods->xClose(pId);
- pId->pMethods = 0;
- }
- return rc;
-}
-SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xRead(id, pBuf, amt, offset);
-}
-SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xWrite(id, pBuf, amt, offset);
-}
-SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){
- return id->pMethods->xTruncate(id, size);
-}
-SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xSync(id, flags);
-}
-SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xFileSize(id, pSize);
-}
-SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xLock(id, lockType);
-}
-SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){
- return id->pMethods->xUnlock(id, lockType);
-}
-SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xCheckReservedLock(id, pResOut);
-}
-
-/*
-** Use sqlite3OsFileControl() when we are doing something that might fail
-** and we need to know about the failures. Use sqlite3OsFileControlHint()
-** when simply tossing information over the wall to the VFS and we do not
-** really care if the VFS receives and understands the information since it
-** is only a hint and can be safely ignored. The sqlite3OsFileControlHint()
-** routine has no return value since the return value would be meaningless.
-*/
-SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xFileControl(id, op, pArg);
-}
-SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
- (void)id->pMethods->xFileControl(id, op, pArg);
-}
-
-SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
- int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
- return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
-}
-SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
- return id->pMethods->xDeviceCharacteristics(id);
-}
-SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
- return id->pMethods->xShmLock(id, offset, n, flags);
-}
-SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){
- id->pMethods->xShmBarrier(id);
-}
-SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
- return id->pMethods->xShmUnmap(id, deleteFlag);
-}
-SQLITE_PRIVATE int sqlite3OsShmMap(
- sqlite3_file *id, /* Database file handle */
- int iPage,
- int pgsz,
- int bExtend, /* True to extend file if necessary */
- void volatile **pp /* OUT: Pointer to mapping */
-){
- DO_OS_MALLOC_TEST(id);
- return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
-}
-
-/*
-** The next group of routines are convenience wrappers around the
-** VFS methods.
-*/
-SQLITE_PRIVATE int sqlite3OsOpen(
- sqlite3_vfs *pVfs,
- const char *zPath,
- sqlite3_file *pFile,
- int flags,
- int *pFlagsOut
-){
- int rc;
- DO_OS_MALLOC_TEST(0);
- /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
- ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
- ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
- ** reaching the VFS. */
- rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
- assert( rc==SQLITE_OK || pFile->pMethods==0 );
- return rc;
-}
-SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
- DO_OS_MALLOC_TEST(0);
- assert( dirSync==0 || dirSync==1 );
- return pVfs->xDelete(pVfs, zPath, dirSync);
-}
-SQLITE_PRIVATE int sqlite3OsAccess(
- sqlite3_vfs *pVfs,
- const char *zPath,
- int flags,
- int *pResOut
-){
- DO_OS_MALLOC_TEST(0);
- return pVfs->xAccess(pVfs, zPath, flags, pResOut);
-}
-SQLITE_PRIVATE int sqlite3OsFullPathname(
- sqlite3_vfs *pVfs,
- const char *zPath,
- int nPathOut,
- char *zPathOut
-){
- DO_OS_MALLOC_TEST(0);
- zPathOut[0] = 0;
- return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
-}
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
- return pVfs->xDlOpen(pVfs, zPath);
-}
-SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
- pVfs->xDlError(pVfs, nByte, zBufOut);
-}
-SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
- return pVfs->xDlSym(pVfs, pHdle, zSym);
-}
-SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
- pVfs->xDlClose(pVfs, pHandle);
-}
-#endif /* SQLITE_OMIT_LOAD_EXTENSION */
-SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
- return pVfs->xRandomness(pVfs, nByte, zBufOut);
-}
-SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
- return pVfs->xSleep(pVfs, nMicro);
-}
-SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
- int rc;
- /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
- ** method to get the current date and time if that method is available
- ** (if iVersion is 2 or greater and the function pointer is not NULL) and
- ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
- ** unavailable.
- */
- if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
- rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
- }else{
- double r;
- rc = pVfs->xCurrentTime(pVfs, &r);
- *pTimeOut = (sqlite3_int64)(r*86400000.0);
- }
- return rc;
-}
-
-SQLITE_PRIVATE int sqlite3OsOpenMalloc(
- sqlite3_vfs *pVfs,
- const char *zFile,
- sqlite3_file **ppFile,
- int flags,
- int *pOutFlags
-){
- int rc = SQLITE_NOMEM;
- sqlite3_file *pFile;
- pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
- if( pFile ){
- rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
- if( rc!=SQLITE_OK ){
- sqlite3_free(pFile);
- }else{
- *ppFile = pFile;
- }
- }
- return rc;
-}
-SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){
- int rc = SQLITE_OK;
- assert( pFile );
- rc = sqlite3OsClose(pFile);
- sqlite3_free(pFile);
- return rc;
-}
-
-/*
-** This function is a wrapper around the OS specific implementation of
-** sqlite3_os_init(). The purpose of the wrapper is to provide the
-** ability to simulate a malloc failure, so that the handling of an
-** error in sqlite3_os_init() by the upper layers can be tested.
-*/
-SQLITE_PRIVATE int sqlite3OsInit(void){
- void *p = sqlite3_malloc(10);
- if( p==0 ) return SQLITE_NOMEM;
- sqlite3_free(p);
- return sqlite3_os_init();
-}
-
-/*
-** The list of all registered VFS implementations.
-*/
-static sqlite3_vfs * SQLITE_WSD vfsList = 0;
-#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
-
-/*
-** Locate a VFS by name. If no name is given, simply return the
-** first VFS on the list.
-*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
- sqlite3_vfs *pVfs = 0;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex;
-#endif
-#ifndef SQLITE_OMIT_AUTOINIT
- int rc = sqlite3_initialize();
- if( rc ) return 0;
-#endif
-#if SQLITE_THREADSAFE
- mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- sqlite3_mutex_enter(mutex);
- for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
- if( zVfs==0 ) break;
- if( strcmp(zVfs, pVfs->zName)==0 ) break;
- }
- sqlite3_mutex_leave(mutex);
- return pVfs;
-}
-
-/*
-** Unlink a VFS from the linked list
-*/
-static void vfsUnlink(sqlite3_vfs *pVfs){
- assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
- if( pVfs==0 ){
- /* No-op */
- }else if( vfsList==pVfs ){
- vfsList = pVfs->pNext;
- }else if( vfsList ){
- sqlite3_vfs *p = vfsList;
- while( p->pNext && p->pNext!=pVfs ){
- p = p->pNext;
- }
- if( p->pNext==pVfs ){
- p->pNext = pVfs->pNext;
- }
- }
-}
-
-/*
-** Register a VFS with the system. It is harmless to register the same
-** VFS multiple times. The new VFS becomes the default if makeDflt is
-** true.
-*/
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
- MUTEX_LOGIC(sqlite3_mutex *mutex;)
-#ifndef SQLITE_OMIT_AUTOINIT
- int rc = sqlite3_initialize();
- if( rc ) return rc;
-#endif
- MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
- sqlite3_mutex_enter(mutex);
- vfsUnlink(pVfs);
- if( makeDflt || vfsList==0 ){
- pVfs->pNext = vfsList;
- vfsList = pVfs;
- }else{
- pVfs->pNext = vfsList->pNext;
- vfsList->pNext = pVfs;
- }
- assert(vfsList);
- sqlite3_mutex_leave(mutex);
- return SQLITE_OK;
-}
-
-/*
-** Unregister a VFS so that it is no longer accessible.
-*/
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- sqlite3_mutex_enter(mutex);
- vfsUnlink(pVfs);
- sqlite3_mutex_leave(mutex);
- return SQLITE_OK;
-}
-
-/************** End of os.c **************************************************/
-/************** Begin file fault.c *******************************************/
-/*
-** 2008 Jan 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains code to support the concept of "benign"
-** malloc failures (when the xMalloc() or xRealloc() method of the
-** sqlite3_mem_methods structure fails to allocate a block of memory
-** and returns 0).
-**
-** Most malloc failures are non-benign. After they occur, SQLite
-** abandons the current operation and returns an error code (usually
-** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily
-** fatal. For example, if a malloc fails while resizing a hash table, this
-** is completely recoverable simply by not carrying out the resize. The
-** hash table will continue to function normally. So a malloc failure
-** during a hash table resize is a benign fault.
-*/
-
-
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-
-/*
-** Global variables.
-*/
-typedef struct BenignMallocHooks BenignMallocHooks;
-static SQLITE_WSD struct BenignMallocHooks {
- void (*xBenignBegin)(void);
- void (*xBenignEnd)(void);
-} sqlite3Hooks = { 0, 0 };
-
-/* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks
-** structure. If writable static data is unsupported on the target,
-** we have to locate the state vector at run-time. In the more common
-** case where writable static data is supported, wsdHooks can refer directly
-** to the "sqlite3Hooks" state vector declared above.
-*/
-#ifdef SQLITE_OMIT_WSD
-# define wsdHooksInit \
- BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks)
-# define wsdHooks x[0]
-#else
-# define wsdHooksInit
-# define wsdHooks sqlite3Hooks
-#endif
-
-
-/*
-** Register hooks to call when sqlite3BeginBenignMalloc() and
-** sqlite3EndBenignMalloc() are called, respectively.
-*/
-SQLITE_PRIVATE void sqlite3BenignMallocHooks(
- void (*xBenignBegin)(void),
- void (*xBenignEnd)(void)
-){
- wsdHooksInit;
- wsdHooks.xBenignBegin = xBenignBegin;
- wsdHooks.xBenignEnd = xBenignEnd;
-}
-
-/*
-** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that
-** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc()
-** indicates that subsequent malloc failures are non-benign.
-*/
-SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){
- wsdHooksInit;
- if( wsdHooks.xBenignBegin ){
- wsdHooks.xBenignBegin();
- }
-}
-SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){
- wsdHooksInit;
- if( wsdHooks.xBenignEnd ){
- wsdHooks.xBenignEnd();
- }
-}
-
-#endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */
-
-/************** End of fault.c ***********************************************/
-/************** Begin file mem0.c ********************************************/
-/*
-** 2008 October 28
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains a no-op memory allocation drivers for use when
-** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented
-** here always fail. SQLite will not operate with these drivers. These
-** are merely placeholders. Real drivers must be substituted using
-** sqlite3_config() before SQLite will operate.
-*/
-
-/*
-** This version of the memory allocator is the default. It is
-** used when no other memory allocator is specified using compile-time
-** macros.
-*/
-#ifdef SQLITE_ZERO_MALLOC
-
-/*
-** No-op versions of all memory allocation routines
-*/
-static void *sqlite3MemMalloc(int nByte){ return 0; }
-static void sqlite3MemFree(void *pPrior){ return; }
-static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; }
-static int sqlite3MemSize(void *pPrior){ return 0; }
-static int sqlite3MemRoundup(int n){ return n; }
-static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; }
-static void sqlite3MemShutdown(void *NotUsed){ return; }
-
-/*
-** This routine is the only routine in this file with external linkage.
-**
-** Populate the low-level memory allocation function pointers in
-** sqlite3GlobalConfig.m with pointers to the routines in this file.
-*/
-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
- static const sqlite3_mem_methods defaultMethods = {
- sqlite3MemMalloc,
- sqlite3MemFree,
- sqlite3MemRealloc,
- sqlite3MemSize,
- sqlite3MemRoundup,
- sqlite3MemInit,
- sqlite3MemShutdown,
- 0
- };
- sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
-}
-
-#endif /* SQLITE_ZERO_MALLOC */
-
-/************** End of mem0.c ************************************************/
-/************** Begin file mem1.c ********************************************/
-/*
-** 2007 August 14
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains low-level memory allocation drivers for when
-** SQLite will use the standard C-library malloc/realloc/free interface
-** to obtain the memory it needs.
-**
-** This file contains implementations of the low-level memory allocation
-** routines specified in the sqlite3_mem_methods object. The content of
-** this file is only used if SQLITE_SYSTEM_MALLOC is defined. The
-** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the
-** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined. The
-** default configuration is to use memory allocation routines in this
-** file.
-**
-** C-preprocessor macro summary:
-**
-** HAVE_MALLOC_USABLE_SIZE The configure script sets this symbol if
-** the malloc_usable_size() interface exists
-** on the target platform. Or, this symbol
-** can be set manually, if desired.
-** If an equivalent interface exists by
-** a different name, using a separate -D
-** option to rename it.
-**
-** SQLITE_WITHOUT_ZONEMALLOC Some older macs lack support for the zone
-** memory allocator. Set this symbol to enable
-** building on older macs.
-**
-** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of
-** _msize() on windows systems. This might
-** be necessary when compiling for Delphi,
-** for example.
-*/
-
-/*
-** This version of the memory allocator is the default. It is
-** used when no other memory allocator is specified using compile-time
-** macros.
-*/
-#ifdef SQLITE_SYSTEM_MALLOC
-
-/*
-** The MSVCRT has malloc_usable_size() but it is called _msize().
-** The use of _msize() is automatic, but can be disabled by compiling
-** with -DSQLITE_WITHOUT_MSIZE
-*/
-#if defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)
-# define SQLITE_MALLOCSIZE _msize
-#endif
-
-#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
-
-/*
-** Use the zone allocator available on apple products unless the
-** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.
-*/
-#include <sys/sysctl.h>
-#include <malloc/malloc.h>
-#include <libkern/OSAtomic.h>
-static malloc_zone_t* _sqliteZone_;
-#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
-#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
-#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
-#define SQLITE_MALLOCSIZE(x) \
- (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))
-
-#else /* if not __APPLE__ */
-
-/*
-** Use standard C library malloc and free on non-Apple systems.
-** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.
-*/
-#define SQLITE_MALLOC(x) malloc(x)
-#define SQLITE_FREE(x) free(x)
-#define SQLITE_REALLOC(x,y) realloc((x),(y))
-
-#if (defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)) \
- || (defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE))
-# include <malloc.h> /* Needed for malloc_usable_size on linux */
-#endif
-#ifdef HAVE_MALLOC_USABLE_SIZE
-# ifndef SQLITE_MALLOCSIZE
-# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
-# endif
-#else
-# undef SQLITE_MALLOCSIZE
-#endif
-
-#endif /* __APPLE__ or not __APPLE__ */
-
-/*
-** Like malloc(), but remember the size of the allocation
-** so that we can find it later using sqlite3MemSize().
-**
-** For this low-level routine, we are guaranteed that nByte>0 because
-** cases of nByte<=0 will be intercepted and dealt with by higher level
-** routines.
-*/
-static void *sqlite3MemMalloc(int nByte){
-#ifdef SQLITE_MALLOCSIZE
- void *p = SQLITE_MALLOC( nByte );
- if( p==0 ){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
- }
- return p;
-#else
- sqlite3_int64 *p;
- assert( nByte>0 );
- nByte = ROUND8(nByte);
- p = SQLITE_MALLOC( nByte+8 );
- if( p ){
- p[0] = nByte;
- p++;
- }else{
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
- }
- return (void *)p;
-#endif
-}
-
-/*
-** Like free() but works for allocations obtained from sqlite3MemMalloc()
-** or sqlite3MemRealloc().
-**
-** For this low-level routine, we already know that pPrior!=0 since
-** cases where pPrior==0 will have been intecepted and dealt with
-** by higher-level routines.
-*/
-static void sqlite3MemFree(void *pPrior){
-#ifdef SQLITE_MALLOCSIZE
- SQLITE_FREE(pPrior);
-#else
- sqlite3_int64 *p = (sqlite3_int64*)pPrior;
- assert( pPrior!=0 );
- p--;
- SQLITE_FREE(p);
-#endif
-}
-
-/*
-** Report the allocated size of a prior return from xMalloc()
-** or xRealloc().
-*/
-static int sqlite3MemSize(void *pPrior){
-#ifdef SQLITE_MALLOCSIZE
- return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
-#else
- sqlite3_int64 *p;
- if( pPrior==0 ) return 0;
- p = (sqlite3_int64*)pPrior;
- p--;
- return (int)p[0];
-#endif
-}
-
-/*
-** Like realloc(). Resize an allocation previously obtained from
-** sqlite3MemMalloc().
-**
-** For this low-level interface, we know that pPrior!=0. Cases where
-** pPrior==0 while have been intercepted by higher-level routine and
-** redirected to xMalloc. Similarly, we know that nByte>0 becauses
-** cases where nByte<=0 will have been intercepted by higher-level
-** routines and redirected to xFree.
-*/
-static void *sqlite3MemRealloc(void *pPrior, int nByte){
-#ifdef SQLITE_MALLOCSIZE
- void *p = SQLITE_REALLOC(pPrior, nByte);
- if( p==0 ){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_NOMEM,
- "failed memory resize %u to %u bytes",
- SQLITE_MALLOCSIZE(pPrior), nByte);
- }
- return p;
-#else
- sqlite3_int64 *p = (sqlite3_int64*)pPrior;
- assert( pPrior!=0 && nByte>0 );
- assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */
- p--;
- p = SQLITE_REALLOC(p, nByte+8 );
- if( p ){
- p[0] = nByte;
- p++;
- }else{
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_NOMEM,
- "failed memory resize %u to %u bytes",
- sqlite3MemSize(pPrior), nByte);
- }
- return (void*)p;
-#endif
-}
-
-/*
-** Round up a request size to the next valid allocation size.
-*/
-static int sqlite3MemRoundup(int n){
- return ROUND8(n);
-}
-
-/*
-** Initialize this module.
-*/
-static int sqlite3MemInit(void *NotUsed){
-#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
- int cpuCount;
- size_t len;
- if( _sqliteZone_ ){
- return SQLITE_OK;
- }
- len = sizeof(cpuCount);
- /* One usually wants to use hw.acctivecpu for MT decisions, but not here */
- sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
- if( cpuCount>1 ){
- /* defer MT decisions to system malloc */
- _sqliteZone_ = malloc_default_zone();
- }else{
- /* only 1 core, use our own zone to contention over global locks,
- ** e.g. we have our own dedicated locks */
- bool success;
- malloc_zone_t* newzone = malloc_create_zone(4096, 0);
- malloc_set_zone_name(newzone, "Sqlite_Heap");
- do{
- success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone,
- (void * volatile *)&_sqliteZone_);
- }while(!_sqliteZone_);
- if( !success ){
- /* somebody registered a zone first */
- malloc_destroy_zone(newzone);
- }
- }
-#endif
- UNUSED_PARAMETER(NotUsed);
- return SQLITE_OK;
-}
-
-/*
-** Deinitialize this module.
-*/
-static void sqlite3MemShutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- return;
-}
-
-/*
-** This routine is the only routine in this file with external linkage.
-**
-** Populate the low-level memory allocation function pointers in
-** sqlite3GlobalConfig.m with pointers to the routines in this file.
-*/
-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
- static const sqlite3_mem_methods defaultMethods = {
- sqlite3MemMalloc,
- sqlite3MemFree,
- sqlite3MemRealloc,
- sqlite3MemSize,
- sqlite3MemRoundup,
- sqlite3MemInit,
- sqlite3MemShutdown,
- 0
- };
- sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
-}
-
-#endif /* SQLITE_SYSTEM_MALLOC */
-
-/************** End of mem1.c ************************************************/
-/************** Begin file mem2.c ********************************************/
-/*
-** 2007 August 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains low-level memory allocation drivers for when
-** SQLite will use the standard C-library malloc/realloc/free interface
-** to obtain the memory it needs while adding lots of additional debugging
-** information to each allocation in order to help detect and fix memory
-** leaks and memory usage errors.
-**
-** This file contains implementations of the low-level memory allocation
-** routines specified in the sqlite3_mem_methods object.
-*/
-
-/*
-** This version of the memory allocator is used only if the
-** SQLITE_MEMDEBUG macro is defined
-*/
-#ifdef SQLITE_MEMDEBUG
-
-/*
-** The backtrace functionality is only available with GLIBC
-*/
-#ifdef __GLIBC__
- extern int backtrace(void**,int);
- extern void backtrace_symbols_fd(void*const*,int,int);
-#else
-# define backtrace(A,B) 1
-# define backtrace_symbols_fd(A,B,C)
-#endif
-/* #include <stdio.h> */
-
-/*
-** Each memory allocation looks like this:
-**
-** ------------------------------------------------------------------------
-** | Title | backtrace pointers | MemBlockHdr | allocation | EndGuard |
-** ------------------------------------------------------------------------
-**
-** The application code sees only a pointer to the allocation. We have
-** to back up from the allocation pointer to find the MemBlockHdr. The
-** MemBlockHdr tells us the size of the allocation and the number of
-** backtrace pointers. There is also a guard word at the end of the
-** MemBlockHdr.
-*/
-struct MemBlockHdr {
- i64 iSize; /* Size of this allocation */
- struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */
- char nBacktrace; /* Number of backtraces on this alloc */
- char nBacktraceSlots; /* Available backtrace slots */
- u8 nTitle; /* Bytes of title; includes '\0' */
- u8 eType; /* Allocation type code */
- int iForeGuard; /* Guard word for sanity */
-};
-
-/*
-** Guard words
-*/
-#define FOREGUARD 0x80F5E153
-#define REARGUARD 0xE4676B53
-
-/*
-** Number of malloc size increments to track.
-*/
-#define NCSIZE 1000
-
-/*
-** All of the static variables used by this module are collected
-** into a single structure named "mem". This is to keep the
-** static variables organized and to reduce namespace pollution
-** when this module is combined with other in the amalgamation.
-*/
-static struct {
-
- /*
- ** Mutex to control access to the memory allocation subsystem.
- */
- sqlite3_mutex *mutex;
-
- /*
- ** Head and tail of a linked list of all outstanding allocations
- */
- struct MemBlockHdr *pFirst;
- struct MemBlockHdr *pLast;
-
- /*
- ** The number of levels of backtrace to save in new allocations.
- */
- int nBacktrace;
- void (*xBacktrace)(int, int, void **);
-
- /*
- ** Title text to insert in front of each block
- */
- int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */
- char zTitle[100]; /* The title text */
-
- /*
- ** sqlite3MallocDisallow() increments the following counter.
- ** sqlite3MallocAllow() decrements it.
- */
- int disallow; /* Do not allow memory allocation */
-
- /*
- ** Gather statistics on the sizes of memory allocations.
- ** nAlloc[i] is the number of allocation attempts of i*8
- ** bytes. i==NCSIZE is the number of allocation attempts for
- ** sizes more than NCSIZE*8 bytes.
- */
- int nAlloc[NCSIZE]; /* Total number of allocations */
- int nCurrent[NCSIZE]; /* Current number of allocations */
- int mxCurrent[NCSIZE]; /* Highwater mark for nCurrent */
-
-} mem;
-
-
-/*
-** Adjust memory usage statistics
-*/
-static void adjustStats(int iSize, int increment){
- int i = ROUND8(iSize)/8;
- if( i>NCSIZE-1 ){
- i = NCSIZE - 1;
- }
- if( increment>0 ){
- mem.nAlloc[i]++;
- mem.nCurrent[i]++;
- if( mem.nCurrent[i]>mem.mxCurrent[i] ){
- mem.mxCurrent[i] = mem.nCurrent[i];
- }
- }else{
- mem.nCurrent[i]--;
- assert( mem.nCurrent[i]>=0 );
- }
-}
-
-/*
-** Given an allocation, find the MemBlockHdr for that allocation.
-**
-** This routine checks the guards at either end of the allocation and
-** if they are incorrect it asserts.
-*/
-static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){
- struct MemBlockHdr *p;
- int *pInt;
- u8 *pU8;
- int nReserve;
-
- p = (struct MemBlockHdr*)pAllocation;
- p--;
- assert( p->iForeGuard==(int)FOREGUARD );
- nReserve = ROUND8(p->iSize);
- pInt = (int*)pAllocation;
- pU8 = (u8*)pAllocation;
- assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD );
- /* This checks any of the "extra" bytes allocated due
- ** to rounding up to an 8 byte boundary to ensure
- ** they haven't been overwritten.
- */
- while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 );
- return p;
-}
-
-/*
-** Return the number of bytes currently allocated at address p.
-*/
-static int sqlite3MemSize(void *p){
- struct MemBlockHdr *pHdr;
- if( !p ){
- return 0;
- }
- pHdr = sqlite3MemsysGetHeader(p);
- return pHdr->iSize;
-}
-
-/*
-** Initialize the memory allocation subsystem.
-*/
-static int sqlite3MemInit(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- assert( (sizeof(struct MemBlockHdr)&7) == 0 );
- if( !sqlite3GlobalConfig.bMemstat ){
- /* If memory status is enabled, then the malloc.c wrapper will already
- ** hold the STATIC_MEM mutex when the routines here are invoked. */
- mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- }
- return SQLITE_OK;
-}
-
-/*
-** Deinitialize the memory allocation subsystem.
-*/
-static void sqlite3MemShutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- mem.mutex = 0;
-}
-
-/*
-** Round up a request size to the next valid allocation size.
-*/
-static int sqlite3MemRoundup(int n){
- return ROUND8(n);
-}
-
-/*
-** Fill a buffer with pseudo-random bytes. This is used to preset
-** the content of a new memory allocation to unpredictable values and
-** to clear the content of a freed allocation to unpredictable values.
-*/
-static void randomFill(char *pBuf, int nByte){
- unsigned int x, y, r;
- x = SQLITE_PTR_TO_INT(pBuf);
- y = nByte | 1;
- while( nByte >= 4 ){
- x = (x>>1) ^ (-(x&1) & 0xd0000001);
- y = y*1103515245 + 12345;
- r = x ^ y;
- *(int*)pBuf = r;
- pBuf += 4;
- nByte -= 4;
- }
- while( nByte-- > 0 ){
- x = (x>>1) ^ (-(x&1) & 0xd0000001);
- y = y*1103515245 + 12345;
- r = x ^ y;
- *(pBuf++) = r & 0xff;
- }
-}
-
-/*
-** Allocate nByte bytes of memory.
-*/
-static void *sqlite3MemMalloc(int nByte){
- struct MemBlockHdr *pHdr;
- void **pBt;
- char *z;
- int *pInt;
- void *p = 0;
- int totalSize;
- int nReserve;
- sqlite3_mutex_enter(mem.mutex);
- assert( mem.disallow==0 );
- nReserve = ROUND8(nByte);
- totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
- mem.nBacktrace*sizeof(void*) + mem.nTitle;
- p = malloc(totalSize);
- if( p ){
- z = p;
- pBt = (void**)&z[mem.nTitle];
- pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
- pHdr->pNext = 0;
- pHdr->pPrev = mem.pLast;
- if( mem.pLast ){
- mem.pLast->pNext = pHdr;
- }else{
- mem.pFirst = pHdr;
- }
- mem.pLast = pHdr;
- pHdr->iForeGuard = FOREGUARD;
- pHdr->eType = MEMTYPE_HEAP;
- pHdr->nBacktraceSlots = mem.nBacktrace;
- pHdr->nTitle = mem.nTitle;
- if( mem.nBacktrace ){
- void *aAddr[40];
- pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
- memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
- assert(pBt[0]);
- if( mem.xBacktrace ){
- mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
- }
- }else{
- pHdr->nBacktrace = 0;
- }
- if( mem.nTitle ){
- memcpy(z, mem.zTitle, mem.nTitle);
- }
- pHdr->iSize = nByte;
- adjustStats(nByte, +1);
- pInt = (int*)&pHdr[1];
- pInt[nReserve/sizeof(int)] = REARGUARD;
- randomFill((char*)pInt, nByte);
- memset(((char*)pInt)+nByte, 0x65, nReserve-nByte);
- p = (void*)pInt;
- }
- sqlite3_mutex_leave(mem.mutex);
- return p;
-}
-
-/*
-** Free memory.
-*/
-static void sqlite3MemFree(void *pPrior){
- struct MemBlockHdr *pHdr;
- void **pBt;
- char *z;
- assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0
- || mem.mutex!=0 );
- pHdr = sqlite3MemsysGetHeader(pPrior);
- pBt = (void**)pHdr;
- pBt -= pHdr->nBacktraceSlots;
- sqlite3_mutex_enter(mem.mutex);
- if( pHdr->pPrev ){
- assert( pHdr->pPrev->pNext==pHdr );
- pHdr->pPrev->pNext = pHdr->pNext;
- }else{
- assert( mem.pFirst==pHdr );
- mem.pFirst = pHdr->pNext;
- }
- if( pHdr->pNext ){
- assert( pHdr->pNext->pPrev==pHdr );
- pHdr->pNext->pPrev = pHdr->pPrev;
- }else{
- assert( mem.pLast==pHdr );
- mem.pLast = pHdr->pPrev;
- }
- z = (char*)pBt;
- z -= pHdr->nTitle;
- adjustStats(pHdr->iSize, -1);
- randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
- pHdr->iSize + sizeof(int) + pHdr->nTitle);
- free(z);
- sqlite3_mutex_leave(mem.mutex);
-}
-
-/*
-** Change the size of an existing memory allocation.
-**
-** For this debugging implementation, we *always* make a copy of the
-** allocation into a new place in memory. In this way, if the
-** higher level code is using pointer to the old allocation, it is
-** much more likely to break and we are much more liking to find
-** the error.
-*/
-static void *sqlite3MemRealloc(void *pPrior, int nByte){
- struct MemBlockHdr *pOldHdr;
- void *pNew;
- assert( mem.disallow==0 );
- assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */
- pOldHdr = sqlite3MemsysGetHeader(pPrior);
- pNew = sqlite3MemMalloc(nByte);
- if( pNew ){
- memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
- if( nByte>pOldHdr->iSize ){
- randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
- }
- sqlite3MemFree(pPrior);
- }
- return pNew;
-}
-
-/*
-** Populate the low-level memory allocation function pointers in
-** sqlite3GlobalConfig.m with pointers to the routines in this file.
-*/
-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
- static const sqlite3_mem_methods defaultMethods = {
- sqlite3MemMalloc,
- sqlite3MemFree,
- sqlite3MemRealloc,
- sqlite3MemSize,
- sqlite3MemRoundup,
- sqlite3MemInit,
- sqlite3MemShutdown,
- 0
- };
- sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
-}
-
-/*
-** Set the "type" of an allocation.
-*/
-SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){
- if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
- struct MemBlockHdr *pHdr;
- pHdr = sqlite3MemsysGetHeader(p);
- assert( pHdr->iForeGuard==FOREGUARD );
- pHdr->eType = eType;
- }
-}
-
-/*
-** Return TRUE if the mask of type in eType matches the type of the
-** allocation p. Also return true if p==NULL.
-**
-** This routine is designed for use within an assert() statement, to
-** verify the type of an allocation. For example:
-**
-** assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
-*/
-SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
- int rc = 1;
- if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
- struct MemBlockHdr *pHdr;
- pHdr = sqlite3MemsysGetHeader(p);
- assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
- if( (pHdr->eType&eType)==0 ){
- rc = 0;
- }
- }
- return rc;
-}
-
-/*
-** Return TRUE if the mask of type in eType matches no bits of the type of the
-** allocation p. Also return true if p==NULL.
-**
-** This routine is designed for use within an assert() statement, to
-** verify the type of an allocation. For example:
-**
-** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
-*/
-SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
- int rc = 1;
- if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
- struct MemBlockHdr *pHdr;
- pHdr = sqlite3MemsysGetHeader(p);
- assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
- if( (pHdr->eType&eType)!=0 ){
- rc = 0;
- }
- }
- return rc;
-}
-
-/*
-** Set the number of backtrace levels kept for each allocation.
-** A value of zero turns off backtracing. The number is always rounded
-** up to a multiple of 2.
-*/
-SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){
- if( depth<0 ){ depth = 0; }
- if( depth>20 ){ depth = 20; }
- depth = (depth+1)&0xfe;
- mem.nBacktrace = depth;
-}
-
-SQLITE_PRIVATE void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){
- mem.xBacktrace = xBacktrace;
-}
-
-/*
-** Set the title string for subsequent allocations.
-*/
-SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){
- unsigned int n = sqlite3Strlen30(zTitle) + 1;
- sqlite3_mutex_enter(mem.mutex);
- if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
- memcpy(mem.zTitle, zTitle, n);
- mem.zTitle[n] = 0;
- mem.nTitle = ROUND8(n);
- sqlite3_mutex_leave(mem.mutex);
-}
-
-SQLITE_PRIVATE void sqlite3MemdebugSync(){
- struct MemBlockHdr *pHdr;
- for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
- void **pBt = (void**)pHdr;
- pBt -= pHdr->nBacktraceSlots;
- mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
- }
-}
-
-/*
-** Open the file indicated and write a log of all unfreed memory
-** allocations into that log.
-*/
-SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){
- FILE *out;
- struct MemBlockHdr *pHdr;
- void **pBt;
- int i;
- out = fopen(zFilename, "w");
- if( out==0 ){
- fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
- zFilename);
- return;
- }
- for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
- char *z = (char*)pHdr;
- z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle;
- fprintf(out, "**** %lld bytes at %p from %s ****\n",
- pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???");
- if( pHdr->nBacktrace ){
- fflush(out);
- pBt = (void**)pHdr;
- pBt -= pHdr->nBacktraceSlots;
- backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
- fprintf(out, "\n");
- }
- }
- fprintf(out, "COUNTS:\n");
- for(i=0; i<NCSIZE-1; i++){
- if( mem.nAlloc[i] ){
- fprintf(out, " %5d: %10d %10d %10d\n",
- i*8, mem.nAlloc[i], mem.nCurrent[i], mem.mxCurrent[i]);
- }
- }
- if( mem.nAlloc[NCSIZE-1] ){
- fprintf(out, " %5d: %10d %10d %10d\n",
- NCSIZE*8-8, mem.nAlloc[NCSIZE-1],
- mem.nCurrent[NCSIZE-1], mem.mxCurrent[NCSIZE-1]);
- }
- fclose(out);
-}
-
-/*
-** Return the number of times sqlite3MemMalloc() has been called.
-*/
-SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){
- int i;
- int nTotal = 0;
- for(i=0; i<NCSIZE; i++){
- nTotal += mem.nAlloc[i];
- }
- return nTotal;
-}
-
-
-#endif /* SQLITE_MEMDEBUG */
-
-/************** End of mem2.c ************************************************/
-/************** Begin file mem3.c ********************************************/
-/*
-** 2007 October 14
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the C functions that implement a memory
-** allocation subsystem for use by SQLite.
-**
-** This version of the memory allocation subsystem omits all
-** use of malloc(). The SQLite user supplies a block of memory
-** before calling sqlite3_initialize() from which allocations
-** are made and returned by the xMalloc() and xRealloc()
-** implementations. Once sqlite3_initialize() has been called,
-** the amount of memory available to SQLite is fixed and cannot
-** be changed.
-**
-** This version of the memory allocation subsystem is included
-** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
-*/
-
-/*
-** This version of the memory allocator is only built into the library
-** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not
-** mean that the library will use a memory-pool by default, just that
-** it is available. The mempool allocator is activated by calling
-** sqlite3_config().
-*/
-#ifdef SQLITE_ENABLE_MEMSYS3
-
-/*
-** Maximum size (in Mem3Blocks) of a "small" chunk.
-*/
-#define MX_SMALL 10
-
-
-/*
-** Number of freelist hash slots
-*/
-#define N_HASH 61
-
-/*
-** A memory allocation (also called a "chunk") consists of two or
-** more blocks where each block is 8 bytes. The first 8 bytes are
-** a header that is not returned to the user.
-**
-** A chunk is two or more blocks that is either checked out or
-** free. The first block has format u.hdr. u.hdr.size4x is 4 times the
-** size of the allocation in blocks if the allocation is free.
-** The u.hdr.size4x&1 bit is true if the chunk is checked out and
-** false if the chunk is on the freelist. The u.hdr.size4x&2 bit
-** is true if the previous chunk is checked out and false if the
-** previous chunk is free. The u.hdr.prevSize field is the size of
-** the previous chunk in blocks if the previous chunk is on the
-** freelist. If the previous chunk is checked out, then
-** u.hdr.prevSize can be part of the data for that chunk and should
-** not be read or written.
-**
-** We often identify a chunk by its index in mem3.aPool[]. When
-** this is done, the chunk index refers to the second block of
-** the chunk. In this way, the first chunk has an index of 1.
-** A chunk index of 0 means "no such chunk" and is the equivalent
-** of a NULL pointer.
-**
-** The second block of free chunks is of the form u.list. The
-** two fields form a double-linked list of chunks of related sizes.
-** Pointers to the head of the list are stored in mem3.aiSmall[]
-** for smaller chunks and mem3.aiHash[] for larger chunks.
-**
-** The second block of a chunk is user data if the chunk is checked
-** out. If a chunk is checked out, the user data may extend into
-** the u.hdr.prevSize value of the following chunk.
-*/
-typedef struct Mem3Block Mem3Block;
-struct Mem3Block {
- union {
- struct {
- u32 prevSize; /* Size of previous chunk in Mem3Block elements */
- u32 size4x; /* 4x the size of current chunk in Mem3Block elements */
- } hdr;
- struct {
- u32 next; /* Index in mem3.aPool[] of next free chunk */
- u32 prev; /* Index in mem3.aPool[] of previous free chunk */
- } list;
- } u;
-};
-
-/*
-** All of the static variables used by this module are collected
-** into a single structure named "mem3". This is to keep the
-** static variables organized and to reduce namespace pollution
-** when this module is combined with other in the amalgamation.
-*/
-static SQLITE_WSD struct Mem3Global {
- /*
- ** Memory available for allocation. nPool is the size of the array
- ** (in Mem3Blocks) pointed to by aPool less 2.
- */
- u32 nPool;
- Mem3Block *aPool;
-
- /*
- ** True if we are evaluating an out-of-memory callback.
- */
- int alarmBusy;
-
- /*
- ** Mutex to control access to the memory allocation subsystem.
- */
- sqlite3_mutex *mutex;
-
- /*
- ** The minimum amount of free space that we have seen.
- */
- u32 mnMaster;
-
- /*
- ** iMaster is the index of the master chunk. Most new allocations
- ** occur off of this chunk. szMaster is the size (in Mem3Blocks)
- ** of the current master. iMaster is 0 if there is not master chunk.
- ** The master chunk is not in either the aiHash[] or aiSmall[].
- */
- u32 iMaster;
- u32 szMaster;
-
- /*
- ** Array of lists of free blocks according to the block size
- ** for smaller chunks, or a hash on the block size for larger
- ** chunks.
- */
- u32 aiSmall[MX_SMALL-1]; /* For sizes 2 through MX_SMALL, inclusive */
- u32 aiHash[N_HASH]; /* For sizes MX_SMALL+1 and larger */
-} mem3 = { 97535575 };
-
-#define mem3 GLOBAL(struct Mem3Global, mem3)
-
-/*
-** Unlink the chunk at mem3.aPool[i] from list it is currently
-** on. *pRoot is the list that i is a member of.
-*/
-static void memsys3UnlinkFromList(u32 i, u32 *pRoot){
- u32 next = mem3.aPool[i].u.list.next;
- u32 prev = mem3.aPool[i].u.list.prev;
- assert( sqlite3_mutex_held(mem3.mutex) );
- if( prev==0 ){
- *pRoot = next;
- }else{
- mem3.aPool[prev].u.list.next = next;
- }
- if( next ){
- mem3.aPool[next].u.list.prev = prev;
- }
- mem3.aPool[i].u.list.next = 0;
- mem3.aPool[i].u.list.prev = 0;
-}
-
-/*
-** Unlink the chunk at index i from
-** whatever list is currently a member of.
-*/
-static void memsys3Unlink(u32 i){
- u32 size, hash;
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
- assert( i>=1 );
- size = mem3.aPool[i-1].u.hdr.size4x/4;
- assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
- assert( size>=2 );
- if( size <= MX_SMALL ){
- memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]);
- }else{
- hash = size % N_HASH;
- memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
- }
-}
-
-/*
-** Link the chunk at mem3.aPool[i] so that is on the list rooted
-** at *pRoot.
-*/
-static void memsys3LinkIntoList(u32 i, u32 *pRoot){
- assert( sqlite3_mutex_held(mem3.mutex) );
- mem3.aPool[i].u.list.next = *pRoot;
- mem3.aPool[i].u.list.prev = 0;
- if( *pRoot ){
- mem3.aPool[*pRoot].u.list.prev = i;
- }
- *pRoot = i;
-}
-
-/*
-** Link the chunk at index i into either the appropriate
-** small chunk list, or into the large chunk hash table.
-*/
-static void memsys3Link(u32 i){
- u32 size, hash;
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( i>=1 );
- assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
- size = mem3.aPool[i-1].u.hdr.size4x/4;
- assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
- assert( size>=2 );
- if( size <= MX_SMALL ){
- memsys3LinkIntoList(i, &mem3.aiSmall[size-2]);
- }else{
- hash = size % N_HASH;
- memsys3LinkIntoList(i, &mem3.aiHash[hash]);
- }
-}
-
-/*
-** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
-** will already be held (obtained by code in malloc.c) if
-** sqlite3GlobalConfig.bMemStat is true.
-*/
-static void memsys3Enter(void){
- if( sqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){
- mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- }
- sqlite3_mutex_enter(mem3.mutex);
-}
-static void memsys3Leave(void){
- sqlite3_mutex_leave(mem3.mutex);
-}
-
-/*
-** Called when we are unable to satisfy an allocation of nBytes.
-*/
-static void memsys3OutOfMemory(int nByte){
- if( !mem3.alarmBusy ){
- mem3.alarmBusy = 1;
- assert( sqlite3_mutex_held(mem3.mutex) );
- sqlite3_mutex_leave(mem3.mutex);
- sqlite3_release_memory(nByte);
- sqlite3_mutex_enter(mem3.mutex);
- mem3.alarmBusy = 0;
- }
-}
-
-
-/*
-** Chunk i is a free chunk that has been unlinked. Adjust its
-** size parameters for check-out and return a pointer to the
-** user portion of the chunk.
-*/
-static void *memsys3Checkout(u32 i, u32 nBlock){
- u32 x;
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( i>=1 );
- assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock );
- assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
- x = mem3.aPool[i-1].u.hdr.size4x;
- mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2);
- mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock;
- mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2;
- return &mem3.aPool[i];
-}
-
-/*
-** Carve a piece off of the end of the mem3.iMaster free chunk.
-** Return a pointer to the new allocation. Or, if the master chunk
-** is not large enough, return 0.
-*/
-static void *memsys3FromMaster(u32 nBlock){
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( mem3.szMaster>=nBlock );
- if( nBlock>=mem3.szMaster-1 ){
- /* Use the entire master */
- void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster);
- mem3.iMaster = 0;
- mem3.szMaster = 0;
- mem3.mnMaster = 0;
- return p;
- }else{
- /* Split the master block. Return the tail. */
- u32 newi, x;
- newi = mem3.iMaster + mem3.szMaster - nBlock;
- assert( newi > mem3.iMaster+1 );
- mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock;
- mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2;
- mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1;
- mem3.szMaster -= nBlock;
- mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster;
- x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
- mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
- if( mem3.szMaster < mem3.mnMaster ){
- mem3.mnMaster = mem3.szMaster;
- }
- return (void*)&mem3.aPool[newi];
- }
-}
-
-/*
-** *pRoot is the head of a list of free chunks of the same size
-** or same size hash. In other words, *pRoot is an entry in either
-** mem3.aiSmall[] or mem3.aiHash[].
-**
-** This routine examines all entries on the given list and tries
-** to coalesce each entries with adjacent free chunks.
-**
-** If it sees a chunk that is larger than mem3.iMaster, it replaces
-** the current mem3.iMaster with the new larger chunk. In order for
-** this mem3.iMaster replacement to work, the master chunk must be
-** linked into the hash tables. That is not the normal state of
-** affairs, of course. The calling routine must link the master
-** chunk before invoking this routine, then must unlink the (possibly
-** changed) master chunk once this routine has finished.
-*/
-static void memsys3Merge(u32 *pRoot){
- u32 iNext, prev, size, i, x;
-
- assert( sqlite3_mutex_held(mem3.mutex) );
- for(i=*pRoot; i>0; i=iNext){
- iNext = mem3.aPool[i].u.list.next;
- size = mem3.aPool[i-1].u.hdr.size4x;
- assert( (size&1)==0 );
- if( (size&2)==0 ){
- memsys3UnlinkFromList(i, pRoot);
- assert( i > mem3.aPool[i-1].u.hdr.prevSize );
- prev = i - mem3.aPool[i-1].u.hdr.prevSize;
- if( prev==iNext ){
- iNext = mem3.aPool[prev].u.list.next;
- }
- memsys3Unlink(prev);
- size = i + size/4 - prev;
- x = mem3.aPool[prev-1].u.hdr.size4x & 2;
- mem3.aPool[prev-1].u.hdr.size4x = size*4 | x;
- mem3.aPool[prev+size-1].u.hdr.prevSize = size;
- memsys3Link(prev);
- i = prev;
- }else{
- size /= 4;
- }
- if( size>mem3.szMaster ){
- mem3.iMaster = i;
- mem3.szMaster = size;
- }
- }
-}
-
-/*
-** Return a block of memory of at least nBytes in size.
-** Return NULL if unable.
-**
-** This function assumes that the necessary mutexes, if any, are
-** already held by the caller. Hence "Unsafe".
-*/
-static void *memsys3MallocUnsafe(int nByte){
- u32 i;
- u32 nBlock;
- u32 toFree;
-
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( sizeof(Mem3Block)==8 );
- if( nByte<=12 ){
- nBlock = 2;
- }else{
- nBlock = (nByte + 11)/8;
- }
- assert( nBlock>=2 );
-
- /* STEP 1:
- ** Look for an entry of the correct size in either the small
- ** chunk table or in the large chunk hash table. This is
- ** successful most of the time (about 9 times out of 10).
- */
- if( nBlock <= MX_SMALL ){
- i = mem3.aiSmall[nBlock-2];
- if( i>0 ){
- memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]);
- return memsys3Checkout(i, nBlock);
- }
- }else{
- int hash = nBlock % N_HASH;
- for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){
- if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){
- memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
- return memsys3Checkout(i, nBlock);
- }
- }
- }
-
- /* STEP 2:
- ** Try to satisfy the allocation by carving a piece off of the end
- ** of the master chunk. This step usually works if step 1 fails.
- */
- if( mem3.szMaster>=nBlock ){
- return memsys3FromMaster(nBlock);
- }
-
-
- /* STEP 3:
- ** Loop through the entire memory pool. Coalesce adjacent free
- ** chunks. Recompute the master chunk as the largest free chunk.
- ** Then try again to satisfy the allocation by carving a piece off
- ** of the end of the master chunk. This step happens very
- ** rarely (we hope!)
- */
- for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){
- memsys3OutOfMemory(toFree);
- if( mem3.iMaster ){
- memsys3Link(mem3.iMaster);
- mem3.iMaster = 0;
- mem3.szMaster = 0;
- }
- for(i=0; i<N_HASH; i++){
- memsys3Merge(&mem3.aiHash[i]);
- }
- for(i=0; i<MX_SMALL-1; i++){
- memsys3Merge(&mem3.aiSmall[i]);
- }
- if( mem3.szMaster ){
- memsys3Unlink(mem3.iMaster);
- if( mem3.szMaster>=nBlock ){
- return memsys3FromMaster(nBlock);
- }
- }
- }
-
- /* If none of the above worked, then we fail. */
- return 0;
-}
-
-/*
-** Free an outstanding memory allocation.
-**
-** This function assumes that the necessary mutexes, if any, are
-** already held by the caller. Hence "Unsafe".
-*/
-static void memsys3FreeUnsafe(void *pOld){
- Mem3Block *p = (Mem3Block*)pOld;
- int i;
- u32 size, x;
- assert( sqlite3_mutex_held(mem3.mutex) );
- assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] );
- i = p - mem3.aPool;
- assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 );
- size = mem3.aPool[i-1].u.hdr.size4x/4;
- assert( i+size<=mem3.nPool+1 );
- mem3.aPool[i-1].u.hdr.size4x &= ~1;
- mem3.aPool[i+size-1].u.hdr.prevSize = size;
- mem3.aPool[i+size-1].u.hdr.size4x &= ~2;
- memsys3Link(i);
-
- /* Try to expand the master using the newly freed chunk */
- if( mem3.iMaster ){
- while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){
- size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize;
- mem3.iMaster -= size;
- mem3.szMaster += size;
- memsys3Unlink(mem3.iMaster);
- x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
- mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
- mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
- }
- x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
- while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){
- memsys3Unlink(mem3.iMaster+mem3.szMaster);
- mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4;
- mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
- mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
- }
- }
-}
-
-/*
-** Return the size of an outstanding allocation, in bytes. The
-** size returned omits the 8-byte header overhead. This only
-** works for chunks that are currently checked out.
-*/
-static int memsys3Size(void *p){
- Mem3Block *pBlock;
- if( p==0 ) return 0;
- pBlock = (Mem3Block*)p;
- assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
- return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
-}
-
-/*
-** Round up a request size to the next valid allocation size.
-*/
-static int memsys3Roundup(int n){
- if( n<=12 ){
- return 12;
- }else{
- return ((n+11)&~7) - 4;
- }
-}
-
-/*
-** Allocate nBytes of memory.
-*/
-static void *memsys3Malloc(int nBytes){
- sqlite3_int64 *p;
- assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */
- memsys3Enter();
- p = memsys3MallocUnsafe(nBytes);
- memsys3Leave();
- return (void*)p;
-}
-
-/*
-** Free memory.
-*/
-static void memsys3Free(void *pPrior){
- assert( pPrior );
- memsys3Enter();
- memsys3FreeUnsafe(pPrior);
- memsys3Leave();
-}
-
-/*
-** Change the size of an existing memory allocation
-*/
-static void *memsys3Realloc(void *pPrior, int nBytes){
- int nOld;
- void *p;
- if( pPrior==0 ){
- return sqlite3_malloc(nBytes);
- }
- if( nBytes<=0 ){
- sqlite3_free(pPrior);
- return 0;
- }
- nOld = memsys3Size(pPrior);
- if( nBytes<=nOld && nBytes>=nOld-128 ){
- return pPrior;
- }
- memsys3Enter();
- p = memsys3MallocUnsafe(nBytes);
- if( p ){
- if( nOld<nBytes ){
- memcpy(p, pPrior, nOld);
- }else{
- memcpy(p, pPrior, nBytes);
- }
- memsys3FreeUnsafe(pPrior);
- }
- memsys3Leave();
- return p;
-}
-
-/*
-** Initialize this module.
-*/
-static int memsys3Init(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- if( !sqlite3GlobalConfig.pHeap ){
- return SQLITE_ERROR;
- }
-
- /* Store a pointer to the memory block in global structure mem3. */
- assert( sizeof(Mem3Block)==8 );
- mem3.aPool = (Mem3Block *)sqlite3GlobalConfig.pHeap;
- mem3.nPool = (sqlite3GlobalConfig.nHeap / sizeof(Mem3Block)) - 2;
-
- /* Initialize the master block. */
- mem3.szMaster = mem3.nPool;
- mem3.mnMaster = mem3.szMaster;
- mem3.iMaster = 1;
- mem3.aPool[0].u.hdr.size4x = (mem3.szMaster<<2) + 2;
- mem3.aPool[mem3.nPool].u.hdr.prevSize = mem3.nPool;
- mem3.aPool[mem3.nPool].u.hdr.size4x = 1;
-
- return SQLITE_OK;
-}
-
-/*
-** Deinitialize this module.
-*/
-static void memsys3Shutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- mem3.mutex = 0;
- return;
-}
-
-
-
-/*
-** Open the file indicated and write a log of all unfreed memory
-** allocations into that log.
-*/
-SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){
-#ifdef SQLITE_DEBUG
- FILE *out;
- u32 i, j;
- u32 size;
- if( zFilename==0 || zFilename[0]==0 ){
- out = stdout;
- }else{
- out = fopen(zFilename, "w");
- if( out==0 ){
- fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
- zFilename);
- return;
- }
- }
- memsys3Enter();
- fprintf(out, "CHUNKS:\n");
- for(i=1; i<=mem3.nPool; i+=size/4){
- size = mem3.aPool[i-1].u.hdr.size4x;
- if( size/4<=1 ){
- fprintf(out, "%p size error\n", &mem3.aPool[i]);
- assert( 0 );
- break;
- }
- if( (size&1)==0 && mem3.aPool[i+size/4-1].u.hdr.prevSize!=size/4 ){
- fprintf(out, "%p tail size does not match\n", &mem3.aPool[i]);
- assert( 0 );
- break;
- }
- if( ((mem3.aPool[i+size/4-1].u.hdr.size4x&2)>>1)!=(size&1) ){
- fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]);
- assert( 0 );
- break;
- }
- if( size&1 ){
- fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8);
- }else{
- fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8,
- i==mem3.iMaster ? " **master**" : "");
- }
- }
- for(i=0; i<MX_SMALL-1; i++){
- if( mem3.aiSmall[i]==0 ) continue;
- fprintf(out, "small(%2d):", i);
- for(j = mem3.aiSmall[i]; j>0; j=mem3.aPool[j].u.list.next){
- fprintf(out, " %p(%d)", &mem3.aPool[j],
- (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
- }
- fprintf(out, "\n");
- }
- for(i=0; i<N_HASH; i++){
- if( mem3.aiHash[i]==0 ) continue;
- fprintf(out, "hash(%2d):", i);
- for(j = mem3.aiHash[i]; j>0; j=mem3.aPool[j].u.list.next){
- fprintf(out, " %p(%d)", &mem3.aPool[j],
- (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
- }
- fprintf(out, "\n");
- }
- fprintf(out, "master=%d\n", mem3.iMaster);
- fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8);
- fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8);
- sqlite3_mutex_leave(mem3.mutex);
- if( out==stdout ){
- fflush(stdout);
- }else{
- fclose(out);
- }
-#else
- UNUSED_PARAMETER(zFilename);
-#endif
-}
-
-/*
-** This routine is the only routine in this file with external
-** linkage.
-**
-** Populate the low-level memory allocation function pointers in
-** sqlite3GlobalConfig.m with pointers to the routines in this file. The
-** arguments specify the block of memory to manage.
-**
-** This routine is only called by sqlite3_config(), and therefore
-** is not required to be threadsafe (it is not).
-*/
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){
- static const sqlite3_mem_methods mempoolMethods = {
- memsys3Malloc,
- memsys3Free,
- memsys3Realloc,
- memsys3Size,
- memsys3Roundup,
- memsys3Init,
- memsys3Shutdown,
- 0
- };
- return &mempoolMethods;
-}
-
-#endif /* SQLITE_ENABLE_MEMSYS3 */
-
-/************** End of mem3.c ************************************************/
-/************** Begin file mem5.c ********************************************/
-/*
-** 2007 October 14
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the C functions that implement a memory
-** allocation subsystem for use by SQLite.
-**
-** This version of the memory allocation subsystem omits all
-** use of malloc(). The application gives SQLite a block of memory
-** before calling sqlite3_initialize() from which allocations
-** are made and returned by the xMalloc() and xRealloc()
-** implementations. Once sqlite3_initialize() has been called,
-** the amount of memory available to SQLite is fixed and cannot
-** be changed.
-**
-** This version of the memory allocation subsystem is included
-** in the build only if SQLITE_ENABLE_MEMSYS5 is defined.
-**
-** This memory allocator uses the following algorithm:
-**
-** 1. All memory allocations sizes are rounded up to a power of 2.
-**
-** 2. If two adjacent free blocks are the halves of a larger block,
-** then the two blocks are coalesed into the single larger block.
-**
-** 3. New memory is allocated from the first available free block.
-**
-** This algorithm is described in: J. M. Robson. "Bounds for Some Functions
-** Concerning Dynamic Storage Allocation". Journal of the Association for
-** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499.
-**
-** Let n be the size of the largest allocation divided by the minimum
-** allocation size (after rounding all sizes up to a power of 2.) Let M
-** be the maximum amount of memory ever outstanding at one time. Let
-** N be the total amount of memory available for allocation. Robson
-** proved that this memory allocator will never breakdown due to
-** fragmentation as long as the following constraint holds:
-**
-** N >= M*(1 + log2(n)/2) - n + 1
-**
-** The sqlite3_status() logic tracks the maximum values of n and M so
-** that an application can, at any time, verify this constraint.
-*/
-
-/*
-** This version of the memory allocator is used only when
-** SQLITE_ENABLE_MEMSYS5 is defined.
-*/
-#ifdef SQLITE_ENABLE_MEMSYS5
-
-/*
-** A minimum allocation is an instance of the following structure.
-** Larger allocations are an array of these structures where the
-** size of the array is a power of 2.
-**
-** The size of this object must be a power of two. That fact is
-** verified in memsys5Init().
-*/
-typedef struct Mem5Link Mem5Link;
-struct Mem5Link {
- int next; /* Index of next free chunk */
- int prev; /* Index of previous free chunk */
-};
-
-/*
-** Maximum size of any allocation is ((1<<LOGMAX)*mem5.szAtom). Since
-** mem5.szAtom is always at least 8 and 32-bit integers are used,
-** it is not actually possible to reach this limit.
-*/
-#define LOGMAX 30
-
-/*
-** Masks used for mem5.aCtrl[] elements.
-*/
-#define CTRL_LOGSIZE 0x1f /* Log2 Size of this block */
-#define CTRL_FREE 0x20 /* True if not checked out */
-
-/*
-** All of the static variables used by this module are collected
-** into a single structure named "mem5". This is to keep the
-** static variables organized and to reduce namespace pollution
-** when this module is combined with other in the amalgamation.
-*/
-static SQLITE_WSD struct Mem5Global {
- /*
- ** Memory available for allocation
- */
- int szAtom; /* Smallest possible allocation in bytes */
- int nBlock; /* Number of szAtom sized blocks in zPool */
- u8 *zPool; /* Memory available to be allocated */
-
- /*
- ** Mutex to control access to the memory allocation subsystem.
- */
- sqlite3_mutex *mutex;
-
- /*
- ** Performance statistics
- */
- u64 nAlloc; /* Total number of calls to malloc */
- u64 totalAlloc; /* Total of all malloc calls - includes internal frag */
- u64 totalExcess; /* Total internal fragmentation */
- u32 currentOut; /* Current checkout, including internal fragmentation */
- u32 currentCount; /* Current number of distinct checkouts */
- u32 maxOut; /* Maximum instantaneous currentOut */
- u32 maxCount; /* Maximum instantaneous currentCount */
- u32 maxRequest; /* Largest allocation (exclusive of internal frag) */
-
- /*
- ** Lists of free blocks. aiFreelist[0] is a list of free blocks of
- ** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2.
- ** and so forth.
- */
- int aiFreelist[LOGMAX+1];
-
- /*
- ** Space for tracking which blocks are checked out and the size
- ** of each block. One byte per block.
- */
- u8 *aCtrl;
-
-} mem5;
-
-/*
-** Access the static variable through a macro for SQLITE_OMIT_WSD
-*/
-#define mem5 GLOBAL(struct Mem5Global, mem5)
-
-/*
-** Assuming mem5.zPool is divided up into an array of Mem5Link
-** structures, return a pointer to the idx-th such lik.
-*/
-#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))
-
-/*
-** Unlink the chunk at mem5.aPool[i] from list it is currently
-** on. It should be found on mem5.aiFreelist[iLogsize].
-*/
-static void memsys5Unlink(int i, int iLogsize){
- int next, prev;
- assert( i>=0 && i<mem5.nBlock );
- assert( iLogsize>=0 && iLogsize<=LOGMAX );
- assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
-
- next = MEM5LINK(i)->next;
- prev = MEM5LINK(i)->prev;
- if( prev<0 ){
- mem5.aiFreelist[iLogsize] = next;
- }else{
- MEM5LINK(prev)->next = next;
- }
- if( next>=0 ){
- MEM5LINK(next)->prev = prev;
- }
-}
-
-/*
-** Link the chunk at mem5.aPool[i] so that is on the iLogsize
-** free list.
-*/
-static void memsys5Link(int i, int iLogsize){
- int x;
- assert( sqlite3_mutex_held(mem5.mutex) );
- assert( i>=0 && i<mem5.nBlock );
- assert( iLogsize>=0 && iLogsize<=LOGMAX );
- assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
-
- x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize];
- MEM5LINK(i)->prev = -1;
- if( x>=0 ){
- assert( x<mem5.nBlock );
- MEM5LINK(x)->prev = i;
- }
- mem5.aiFreelist[iLogsize] = i;
-}
-
-/*
-** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
-** will already be held (obtained by code in malloc.c) if
-** sqlite3GlobalConfig.bMemStat is true.
-*/
-static void memsys5Enter(void){
- sqlite3_mutex_enter(mem5.mutex);
-}
-static void memsys5Leave(void){
- sqlite3_mutex_leave(mem5.mutex);
-}
-
-/*
-** Return the size of an outstanding allocation, in bytes. The
-** size returned omits the 8-byte header overhead. This only
-** works for chunks that are currently checked out.
-*/
-static int memsys5Size(void *p){
- int iSize = 0;
- if( p ){
- int i = ((u8 *)p-mem5.zPool)/mem5.szAtom;
- assert( i>=0 && i<mem5.nBlock );
- iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
- }
- return iSize;
-}
-
-/*
-** Find the first entry on the freelist iLogsize. Unlink that
-** entry and return its index.
-*/
-static int memsys5UnlinkFirst(int iLogsize){
- int i;
- int iFirst;
-
- assert( iLogsize>=0 && iLogsize<=LOGMAX );
- i = iFirst = mem5.aiFreelist[iLogsize];
- assert( iFirst>=0 );
- while( i>0 ){
- if( i<iFirst ) iFirst = i;
- i = MEM5LINK(i)->next;
- }
- memsys5Unlink(iFirst, iLogsize);
- return iFirst;
-}
-
-/*
-** Return a block of memory of at least nBytes in size.
-** Return NULL if unable. Return NULL if nBytes==0.
-**
-** The caller guarantees that nByte positive.
-**
-** The caller has obtained a mutex prior to invoking this
-** routine so there is never any chance that two or more
-** threads can be in this routine at the same time.
-*/
-static void *memsys5MallocUnsafe(int nByte){
- int i; /* Index of a mem5.aPool[] slot */
- int iBin; /* Index into mem5.aiFreelist[] */
- int iFullSz; /* Size of allocation rounded up to power of 2 */
- int iLogsize; /* Log2 of iFullSz/POW2_MIN */
-
- /* nByte must be a positive */
- assert( nByte>0 );
-
- /* Keep track of the maximum allocation request. Even unfulfilled
- ** requests are counted */
- if( (u32)nByte>mem5.maxRequest ){
- mem5.maxRequest = nByte;
- }
-
- /* Abort if the requested allocation size is larger than the largest
- ** power of two that we can represent using 32-bit signed integers.
- */
- if( nByte > 0x40000000 ){
- return 0;
- }
-
- /* Round nByte up to the next valid power of two */
- for(iFullSz=mem5.szAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
-
- /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
- ** block. If not, then split a block of the next larger power of
- ** two in order to create a new free block of size iLogsize.
- */
- for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
- if( iBin>LOGMAX ){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
- return 0;
- }
- i = memsys5UnlinkFirst(iBin);
- while( iBin>iLogsize ){
- int newSize;
-
- iBin--;
- newSize = 1 << iBin;
- mem5.aCtrl[i+newSize] = CTRL_FREE | iBin;
- memsys5Link(i+newSize, iBin);
- }
- mem5.aCtrl[i] = iLogsize;
-
- /* Update allocator performance statistics. */
- mem5.nAlloc++;
- mem5.totalAlloc += iFullSz;
- mem5.totalExcess += iFullSz - nByte;
- mem5.currentCount++;
- mem5.currentOut += iFullSz;
- if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
- if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
-
- /* Return a pointer to the allocated memory. */
- return (void*)&mem5.zPool[i*mem5.szAtom];
-}
-
-/*
-** Free an outstanding memory allocation.
-*/
-static void memsys5FreeUnsafe(void *pOld){
- u32 size, iLogsize;
- int iBlock;
-
- /* Set iBlock to the index of the block pointed to by pOld in
- ** the array of mem5.szAtom byte blocks pointed to by mem5.zPool.
- */
- iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom;
-
- /* Check that the pointer pOld points to a valid, non-free block. */
- assert( iBlock>=0 && iBlock<mem5.nBlock );
- assert( ((u8 *)pOld-mem5.zPool)%mem5.szAtom==0 );
- assert( (mem5.aCtrl[iBlock] & CTRL_FREE)==0 );
-
- iLogsize = mem5.aCtrl[iBlock] & CTRL_LOGSIZE;
- size = 1<<iLogsize;
- assert( iBlock+size-1<(u32)mem5.nBlock );
-
- mem5.aCtrl[iBlock] |= CTRL_FREE;
- mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
- assert( mem5.currentCount>0 );
- assert( mem5.currentOut>=(size*mem5.szAtom) );
- mem5.currentCount--;
- mem5.currentOut -= size*mem5.szAtom;
- assert( mem5.currentOut>0 || mem5.currentCount==0 );
- assert( mem5.currentCount>0 || mem5.currentOut==0 );
-
- mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
- while( ALWAYS(iLogsize<LOGMAX) ){
- int iBuddy;
- if( (iBlock>>iLogsize) & 1 ){
- iBuddy = iBlock - size;
- }else{
- iBuddy = iBlock + size;
- }
- assert( iBuddy>=0 );
- if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
- if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
- memsys5Unlink(iBuddy, iLogsize);
- iLogsize++;
- if( iBuddy<iBlock ){
- mem5.aCtrl[iBuddy] = CTRL_FREE | iLogsize;
- mem5.aCtrl[iBlock] = 0;
- iBlock = iBuddy;
- }else{
- mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
- mem5.aCtrl[iBuddy] = 0;
- }
- size *= 2;
- }
- memsys5Link(iBlock, iLogsize);
-}
-
-/*
-** Allocate nBytes of memory
-*/
-static void *memsys5Malloc(int nBytes){
- sqlite3_int64 *p = 0;
- if( nBytes>0 ){
- memsys5Enter();
- p = memsys5MallocUnsafe(nBytes);
- memsys5Leave();
- }
- return (void*)p;
-}
-
-/*
-** Free memory.
-**
-** The outer layer memory allocator prevents this routine from
-** being called with pPrior==0.
-*/
-static void memsys5Free(void *pPrior){
- assert( pPrior!=0 );
- memsys5Enter();
- memsys5FreeUnsafe(pPrior);
- memsys5Leave();
-}
-
-/*
-** Change the size of an existing memory allocation.
-**
-** The outer layer memory allocator prevents this routine from
-** being called with pPrior==0.
-**
-** nBytes is always a value obtained from a prior call to
-** memsys5Round(). Hence nBytes is always a non-negative power
-** of two. If nBytes==0 that means that an oversize allocation
-** (an allocation larger than 0x40000000) was requested and this
-** routine should return 0 without freeing pPrior.
-*/
-static void *memsys5Realloc(void *pPrior, int nBytes){
- int nOld;
- void *p;
- assert( pPrior!=0 );
- assert( (nBytes&(nBytes-1))==0 ); /* EV: R-46199-30249 */
- assert( nBytes>=0 );
- if( nBytes==0 ){
- return 0;
- }
- nOld = memsys5Size(pPrior);
- if( nBytes<=nOld ){
- return pPrior;
- }
- memsys5Enter();
- p = memsys5MallocUnsafe(nBytes);
- if( p ){
- memcpy(p, pPrior, nOld);
- memsys5FreeUnsafe(pPrior);
- }
- memsys5Leave();
- return p;
-}
-
-/*
-** Round up a request size to the next valid allocation size. If
-** the allocation is too large to be handled by this allocation system,
-** return 0.
-**
-** All allocations must be a power of two and must be expressed by a
-** 32-bit signed integer. Hence the largest allocation is 0x40000000
-** or 1073741824 bytes.
-*/
-static int memsys5Roundup(int n){
- int iFullSz;
- if( n > 0x40000000 ) return 0;
- for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
- return iFullSz;
-}
-
-/*
-** Return the ceiling of the logarithm base 2 of iValue.
-**
-** Examples: memsys5Log(1) -> 0
-** memsys5Log(2) -> 1
-** memsys5Log(4) -> 2
-** memsys5Log(5) -> 3
-** memsys5Log(8) -> 3
-** memsys5Log(9) -> 4
-*/
-static int memsys5Log(int iValue){
- int iLog;
- for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<<iLog)<iValue; iLog++);
- return iLog;
-}
-
-/*
-** Initialize the memory allocator.
-**
-** This routine is not threadsafe. The caller must be holding a mutex
-** to prevent multiple threads from entering at the same time.
-*/
-static int memsys5Init(void *NotUsed){
- int ii; /* Loop counter */
- int nByte; /* Number of bytes of memory available to this allocator */
- u8 *zByte; /* Memory usable by this allocator */
- int nMinLog; /* Log base 2 of minimum allocation size in bytes */
- int iOffset; /* An offset into mem5.aCtrl[] */
-
- UNUSED_PARAMETER(NotUsed);
-
- /* For the purposes of this routine, disable the mutex */
- mem5.mutex = 0;
-
- /* The size of a Mem5Link object must be a power of two. Verify that
- ** this is case.
- */
- assert( (sizeof(Mem5Link)&(sizeof(Mem5Link)-1))==0 );
-
- nByte = sqlite3GlobalConfig.nHeap;
- zByte = (u8*)sqlite3GlobalConfig.pHeap;
- assert( zByte!=0 ); /* sqlite3_config() does not allow otherwise */
-
- /* boundaries on sqlite3GlobalConfig.mnReq are enforced in sqlite3_config() */
- nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq);
- mem5.szAtom = (1<<nMinLog);
- while( (int)sizeof(Mem5Link)>mem5.szAtom ){
- mem5.szAtom = mem5.szAtom << 1;
- }
-
- mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8)));
- mem5.zPool = zByte;
- mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom];
-
- for(ii=0; ii<=LOGMAX; ii++){
- mem5.aiFreelist[ii] = -1;
- }
-
- iOffset = 0;
- for(ii=LOGMAX; ii>=0; ii--){
- int nAlloc = (1<<ii);
- if( (iOffset+nAlloc)<=mem5.nBlock ){
- mem5.aCtrl[iOffset] = ii | CTRL_FREE;
- memsys5Link(iOffset, ii);
- iOffset += nAlloc;
- }
- assert((iOffset+nAlloc)>mem5.nBlock);
- }
-
- /* If a mutex is required for normal operation, allocate one */
- if( sqlite3GlobalConfig.bMemstat==0 ){
- mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Deinitialize this module.
-*/
-static void memsys5Shutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- mem5.mutex = 0;
- return;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Open the file indicated and write a log of all unfreed memory
-** allocations into that log.
-*/
-SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){
- FILE *out;
- int i, j, n;
- int nMinLog;
-
- if( zFilename==0 || zFilename[0]==0 ){
- out = stdout;
- }else{
- out = fopen(zFilename, "w");
- if( out==0 ){
- fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
- zFilename);
- return;
- }
- }
- memsys5Enter();
- nMinLog = memsys5Log(mem5.szAtom);
- for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
- for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
- fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n);
- }
- fprintf(out, "mem5.nAlloc = %llu\n", mem5.nAlloc);
- fprintf(out, "mem5.totalAlloc = %llu\n", mem5.totalAlloc);
- fprintf(out, "mem5.totalExcess = %llu\n", mem5.totalExcess);
- fprintf(out, "mem5.currentOut = %u\n", mem5.currentOut);
- fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount);
- fprintf(out, "mem5.maxOut = %u\n", mem5.maxOut);
- fprintf(out, "mem5.maxCount = %u\n", mem5.maxCount);
- fprintf(out, "mem5.maxRequest = %u\n", mem5.maxRequest);
- memsys5Leave();
- if( out==stdout ){
- fflush(stdout);
- }else{
- fclose(out);
- }
-}
-#endif
-
-/*
-** This routine is the only routine in this file with external
-** linkage. It returns a pointer to a static sqlite3_mem_methods
-** struct populated with the memsys5 methods.
-*/
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
- static const sqlite3_mem_methods memsys5Methods = {
- memsys5Malloc,
- memsys5Free,
- memsys5Realloc,
- memsys5Size,
- memsys5Roundup,
- memsys5Init,
- memsys5Shutdown,
- 0
- };
- return &memsys5Methods;
-}
-
-#endif /* SQLITE_ENABLE_MEMSYS5 */
-
-/************** End of mem5.c ************************************************/
-/************** Begin file mutex.c *******************************************/
-/*
-** 2007 August 14
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the C functions that implement mutexes.
-**
-** This file contains code that is common across all mutex implementations.
-*/
-
-#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
-/*
-** For debugging purposes, record when the mutex subsystem is initialized
-** and uninitialized so that we can assert() if there is an attempt to
-** allocate a mutex while the system is uninitialized.
-*/
-static SQLITE_WSD int mutexIsInit = 0;
-#endif /* SQLITE_DEBUG */
-
-
-#ifndef SQLITE_MUTEX_OMIT
-/*
-** Initialize the mutex system.
-*/
-SQLITE_PRIVATE int sqlite3MutexInit(void){
- int rc = SQLITE_OK;
- if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
- /* If the xMutexAlloc method has not been set, then the user did not
- ** install a mutex implementation via sqlite3_config() prior to
- ** sqlite3_initialize() being called. This block copies pointers to
- ** the default implementation into the sqlite3GlobalConfig structure.
- */
- sqlite3_mutex_methods const *pFrom;
- sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
-
- if( sqlite3GlobalConfig.bCoreMutex ){
- pFrom = sqlite3DefaultMutex();
- }else{
- pFrom = sqlite3NoopMutex();
- }
- memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
- memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
- sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
- pTo->xMutexAlloc = pFrom->xMutexAlloc;
- }
- rc = sqlite3GlobalConfig.mutex.xMutexInit();
-
-#ifdef SQLITE_DEBUG
- GLOBAL(int, mutexIsInit) = 1;
-#endif
-
- return rc;
-}
-
-/*
-** Shutdown the mutex system. This call frees resources allocated by
-** sqlite3MutexInit().
-*/
-SQLITE_PRIVATE int sqlite3MutexEnd(void){
- int rc = SQLITE_OK;
- if( sqlite3GlobalConfig.mutex.xMutexEnd ){
- rc = sqlite3GlobalConfig.mutex.xMutexEnd();
- }
-
-#ifdef SQLITE_DEBUG
- GLOBAL(int, mutexIsInit) = 0;
-#endif
-
- return rc;
-}
-
-/*
-** Retrieve a pointer to a static mutex or allocate a new dynamic one.
-*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
-}
-
-SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
- if( !sqlite3GlobalConfig.bCoreMutex ){
- return 0;
- }
- assert( GLOBAL(int, mutexIsInit) );
- return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
-}
-
-/*
-** Free a dynamic mutex.
-*/
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
- if( p ){
- sqlite3GlobalConfig.mutex.xMutexFree(p);
- }
-}
-
-/*
-** Obtain the mutex p. If some other thread already has the mutex, block
-** until it can be obtained.
-*/
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
- if( p ){
- sqlite3GlobalConfig.mutex.xMutexEnter(p);
- }
-}
-
-/*
-** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
-** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
-*/
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
- int rc = SQLITE_OK;
- if( p ){
- return sqlite3GlobalConfig.mutex.xMutexTry(p);
- }
- return rc;
-}
-
-/*
-** The sqlite3_mutex_leave() routine exits a mutex that was previously
-** entered by the same thread. The behavior is undefined if the mutex
-** is not currently entered. If a NULL pointer is passed as an argument
-** this function is a no-op.
-*/
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
- if( p ){
- sqlite3GlobalConfig.mutex.xMutexLeave(p);
- }
-}
-
-#ifndef NDEBUG
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use inside assert() statements.
-*/
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
- return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
-}
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
- return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
-}
-#endif
-
-#endif /* !defined(SQLITE_MUTEX_OMIT) */
-
-/************** End of mutex.c ***********************************************/
-/************** Begin file mutex_noop.c **************************************/
-/*
-** 2008 October 07
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the C functions that implement mutexes.
-**
-** This implementation in this file does not provide any mutual
-** exclusion and is thus suitable for use only in applications
-** that use SQLite in a single thread. The routines defined
-** here are place-holders. Applications can substitute working
-** mutex routines at start-time using the
-**
-** sqlite3_config(SQLITE_CONFIG_MUTEX,...)
-**
-** interface.
-**
-** If compiled with SQLITE_DEBUG, then additional logic is inserted
-** that does error checking on mutexes to make sure they are being
-** called correctly.
-*/
-
-#ifndef SQLITE_MUTEX_OMIT
-
-#ifndef SQLITE_DEBUG
-/*
-** Stub routines for all mutex methods.
-**
-** This routines provide no mutual exclusion or error checking.
-*/
-static int noopMutexInit(void){ return SQLITE_OK; }
-static int noopMutexEnd(void){ return SQLITE_OK; }
-static sqlite3_mutex *noopMutexAlloc(int id){
- UNUSED_PARAMETER(id);
- return (sqlite3_mutex*)8;
-}
-static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
-static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
-static int noopMutexTry(sqlite3_mutex *p){
- UNUSED_PARAMETER(p);
- return SQLITE_OK;
-}
-static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
-
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){
- static const sqlite3_mutex_methods sMutex = {
- noopMutexInit,
- noopMutexEnd,
- noopMutexAlloc,
- noopMutexFree,
- noopMutexEnter,
- noopMutexTry,
- noopMutexLeave,
-
- 0,
- 0,
- };
-
- return &sMutex;
-}
-#endif /* !SQLITE_DEBUG */
-
-#ifdef SQLITE_DEBUG
-/*
-** In this implementation, error checking is provided for testing
-** and debugging purposes. The mutexes still do not provide any
-** mutual exclusion.
-*/
-
-/*
-** The mutex object
-*/
-typedef struct sqlite3_debug_mutex {
- int id; /* The mutex type */
- int cnt; /* Number of entries without a matching leave */
-} sqlite3_debug_mutex;
-
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use inside assert() statements.
-*/
-static int debugMutexHeld(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- return p==0 || p->cnt>0;
-}
-static int debugMutexNotheld(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- return p==0 || p->cnt==0;
-}
-
-/*
-** Initialize and deinitialize the mutex subsystem.
-*/
-static int debugMutexInit(void){ return SQLITE_OK; }
-static int debugMutexEnd(void){ return SQLITE_OK; }
-
-/*
-** The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. If it returns NULL
-** that means that a mutex could not be allocated.
-*/
-static sqlite3_mutex *debugMutexAlloc(int id){
- static sqlite3_debug_mutex aStatic[6];
- sqlite3_debug_mutex *pNew = 0;
- switch( id ){
- case SQLITE_MUTEX_FAST:
- case SQLITE_MUTEX_RECURSIVE: {
- pNew = sqlite3Malloc(sizeof(*pNew));
- if( pNew ){
- pNew->id = id;
- pNew->cnt = 0;
- }
- break;
- }
- default: {
- assert( id-2 >= 0 );
- assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
- pNew = &aStatic[id-2];
- pNew->id = id;
- break;
- }
- }
- return (sqlite3_mutex*)pNew;
-}
-
-/*
-** This routine deallocates a previously allocated mutex.
-*/
-static void debugMutexFree(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- assert( p->cnt==0 );
- assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
- sqlite3_free(p);
-}
-
-/*
-** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
-** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
-** be entered multiple times by the same thread. In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter. If the same thread tries to enter any other kind of mutex
-** more than once, the behavior is undefined.
-*/
-static void debugMutexEnter(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
- p->cnt++;
-}
-static int debugMutexTry(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
- p->cnt++;
- return SQLITE_OK;
-}
-
-/*
-** The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. The behavior
-** is undefined if the mutex is not currently entered or
-** is not currently allocated. SQLite will never do either.
-*/
-static void debugMutexLeave(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- assert( debugMutexHeld(pX) );
- p->cnt--;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
-}
-
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){
- static const sqlite3_mutex_methods sMutex = {
- debugMutexInit,
- debugMutexEnd,
- debugMutexAlloc,
- debugMutexFree,
- debugMutexEnter,
- debugMutexTry,
- debugMutexLeave,
-
- debugMutexHeld,
- debugMutexNotheld
- };
-
- return &sMutex;
-}
-#endif /* SQLITE_DEBUG */
-
-/*
-** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation
-** is used regardless of the run-time threadsafety setting.
-*/
-#ifdef SQLITE_MUTEX_NOOP
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
- return sqlite3NoopMutex();
-}
-#endif /* defined(SQLITE_MUTEX_NOOP) */
-#endif /* !defined(SQLITE_MUTEX_OMIT) */
-
-/************** End of mutex_noop.c ******************************************/
-/************** Begin file mutex_unix.c **************************************/
-/*
-** 2007 August 28
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the C functions that implement mutexes for pthreads
-*/
-
-/*
-** The code in this file is only used if we are compiling threadsafe
-** under unix with pthreads.
-**
-** Note that this implementation requires a version of pthreads that
-** supports recursive mutexes.
-*/
-#ifdef SQLITE_MUTEX_PTHREADS
-
-#include <pthread.h>
-
-/*
-** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields
-** are necessary under two condidtions: (1) Debug builds and (2) using
-** home-grown mutexes. Encapsulate these conditions into a single #define.
-*/
-#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX)
-# define SQLITE_MUTEX_NREF 1
-#else
-# define SQLITE_MUTEX_NREF 0
-#endif
-
-/*
-** Each recursive mutex is an instance of the following structure.
-*/
-struct sqlite3_mutex {
- pthread_mutex_t mutex; /* Mutex controlling the lock */
-#if SQLITE_MUTEX_NREF
- int id; /* Mutex type */
- volatile int nRef; /* Number of entrances */
- volatile pthread_t owner; /* Thread that is within this mutex */
- int trace; /* True to trace changes */
-#endif
-};
-#if SQLITE_MUTEX_NREF
-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
-#else
-#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
-#endif
-
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use only inside assert() statements. On some platforms,
-** there might be race conditions that can cause these routines to
-** deliver incorrect results. In particular, if pthread_equal() is
-** not an atomic operation, then these routines might delivery
-** incorrect results. On most platforms, pthread_equal() is a
-** comparison of two integers and is therefore atomic. But we are
-** told that HPUX is not such a platform. If so, then these routines
-** will not always work correctly on HPUX.
-**
-** On those platforms where pthread_equal() is not atomic, SQLite
-** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
-** make sure no assert() statements are evaluated and hence these
-** routines are never called.
-*/
-#if !defined(NDEBUG) || defined(SQLITE_DEBUG)
-static int pthreadMutexHeld(sqlite3_mutex *p){
- return (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
-}
-static int pthreadMutexNotheld(sqlite3_mutex *p){
- return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
-}
-#endif
-
-/*
-** Initialize and deinitialize the mutex subsystem.
-*/
-static int pthreadMutexInit(void){ return SQLITE_OK; }
-static int pthreadMutexEnd(void){ return SQLITE_OK; }
-
-/*
-** The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. If it returns NULL
-** that means that a mutex could not be allocated. SQLite
-** will unwind its stack and return an error. The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
-**
-** <ul>
-** <li> SQLITE_MUTEX_FAST
-** <li> SQLITE_MUTEX_RECURSIVE
-** <li> SQLITE_MUTEX_STATIC_MASTER
-** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
-** <li> SQLITE_MUTEX_STATIC_PRNG
-** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_PMEM
-** </ul>
-**
-** The first two constants cause sqlite3_mutex_alloc() to create
-** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
-** The mutex implementation does not need to make a distinction
-** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. But SQLite will only request a recursive mutex in
-** cases where it really needs one. If a faster non-recursive mutex
-** implementation is available on the host platform, the mutex subsystem
-** might return such a mutex in response to SQLITE_MUTEX_FAST.
-**
-** The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex. Six static mutexes are
-** used by the current version of SQLite. Future versions of SQLite
-** may add additional static mutexes. Static mutexes are for internal
-** use by SQLite only. Applications that use SQLite mutexes should
-** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-** SQLITE_MUTEX_RECURSIVE.
-**
-** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. But for the static
-** mutex types, the same mutex is returned on every call that has
-** the same type number.
-*/
-static sqlite3_mutex *pthreadMutexAlloc(int iType){
- static sqlite3_mutex staticMutexes[] = {
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER
- };
- sqlite3_mutex *p;
- switch( iType ){
- case SQLITE_MUTEX_RECURSIVE: {
- p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
- /* If recursive mutexes are not available, we will have to
- ** build our own. See below. */
- pthread_mutex_init(&p->mutex, 0);
-#else
- /* Use a recursive mutex if it is available */
- pthread_mutexattr_t recursiveAttr;
- pthread_mutexattr_init(&recursiveAttr);
- pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&p->mutex, &recursiveAttr);
- pthread_mutexattr_destroy(&recursiveAttr);
-#endif
-#if SQLITE_MUTEX_NREF
- p->id = iType;
-#endif
- }
- break;
- }
- case SQLITE_MUTEX_FAST: {
- p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
-#if SQLITE_MUTEX_NREF
- p->id = iType;
-#endif
- pthread_mutex_init(&p->mutex, 0);
- }
- break;
- }
- default: {
- assert( iType-2 >= 0 );
- assert( iType-2 < ArraySize(staticMutexes) );
- p = &staticMutexes[iType-2];
-#if SQLITE_MUTEX_NREF
- p->id = iType;
-#endif
- break;
- }
- }
- return p;
-}
-
-
-/*
-** This routine deallocates a previously
-** allocated mutex. SQLite is careful to deallocate every
-** mutex that it allocates.
-*/
-static void pthreadMutexFree(sqlite3_mutex *p){
- assert( p->nRef==0 );
- assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
- pthread_mutex_destroy(&p->mutex);
- sqlite3_free(p);
-}
-
-/*
-** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
-** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
-** be entered multiple times by the same thread. In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter. If the same thread tries to enter any other kind of mutex
-** more than once, the behavior is undefined.
-*/
-static void pthreadMutexEnter(sqlite3_mutex *p){
- assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
-
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
- /* If recursive mutexes are not available, then we have to grow
- ** our own. This implementation assumes that pthread_equal()
- ** is atomic - that it cannot be deceived into thinking self
- ** and p->owner are equal if p->owner changes between two values
- ** that are not equal to self while the comparison is taking place.
- ** This implementation also assumes a coherent cache - that
- ** separate processes cannot read different values from the same
- ** address at the same time. If either of these two conditions
- ** are not met, then the mutexes will fail and problems will result.
- */
- {
- pthread_t self = pthread_self();
- if( p->nRef>0 && pthread_equal(p->owner, self) ){
- p->nRef++;
- }else{
- pthread_mutex_lock(&p->mutex);
- assert( p->nRef==0 );
- p->owner = self;
- p->nRef = 1;
- }
- }
-#else
- /* Use the built-in recursive mutexes if they are available.
- */
- pthread_mutex_lock(&p->mutex);
-#if SQLITE_MUTEX_NREF
- assert( p->nRef>0 || p->owner==0 );
- p->owner = pthread_self();
- p->nRef++;
-#endif
-#endif
-
-#ifdef SQLITE_DEBUG
- if( p->trace ){
- printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
- }
-#endif
-}
-static int pthreadMutexTry(sqlite3_mutex *p){
- int rc;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
-
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
- /* If recursive mutexes are not available, then we have to grow
- ** our own. This implementation assumes that pthread_equal()
- ** is atomic - that it cannot be deceived into thinking self
- ** and p->owner are equal if p->owner changes between two values
- ** that are not equal to self while the comparison is taking place.
- ** This implementation also assumes a coherent cache - that
- ** separate processes cannot read different values from the same
- ** address at the same time. If either of these two conditions
- ** are not met, then the mutexes will fail and problems will result.
- */
- {
- pthread_t self = pthread_self();
- if( p->nRef>0 && pthread_equal(p->owner, self) ){
- p->nRef++;
- rc = SQLITE_OK;
- }else if( pthread_mutex_trylock(&p->mutex)==0 ){
- assert( p->nRef==0 );
- p->owner = self;
- p->nRef = 1;
- rc = SQLITE_OK;
- }else{
- rc = SQLITE_BUSY;
- }
- }
-#else
- /* Use the built-in recursive mutexes if they are available.
- */
- if( pthread_mutex_trylock(&p->mutex)==0 ){
-#if SQLITE_MUTEX_NREF
- p->owner = pthread_self();
- p->nRef++;
-#endif
- rc = SQLITE_OK;
- }else{
- rc = SQLITE_BUSY;
- }
-#endif
-
-#ifdef SQLITE_DEBUG
- if( rc==SQLITE_OK && p->trace ){
- printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
- }
-#endif
- return rc;
-}
-
-/*
-** The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. The behavior
-** is undefined if the mutex is not currently entered or
-** is not currently allocated. SQLite will never do either.
-*/
-static void pthreadMutexLeave(sqlite3_mutex *p){
- assert( pthreadMutexHeld(p) );
-#if SQLITE_MUTEX_NREF
- p->nRef--;
- if( p->nRef==0 ) p->owner = 0;
-#endif
- assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
-
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
- if( p->nRef==0 ){
- pthread_mutex_unlock(&p->mutex);
- }
-#else
- pthread_mutex_unlock(&p->mutex);
-#endif
-
-#ifdef SQLITE_DEBUG
- if( p->trace ){
- printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
- }
-#endif
-}
-
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
- static const sqlite3_mutex_methods sMutex = {
- pthreadMutexInit,
- pthreadMutexEnd,
- pthreadMutexAlloc,
- pthreadMutexFree,
- pthreadMutexEnter,
- pthreadMutexTry,
- pthreadMutexLeave,
-#ifdef SQLITE_DEBUG
- pthreadMutexHeld,
- pthreadMutexNotheld
-#else
- 0,
- 0
-#endif
- };
-
- return &sMutex;
-}
-
-#endif /* SQLITE_MUTEX_PTHREADS */
-
-/************** End of mutex_unix.c ******************************************/
-/************** Begin file mutex_w32.c ***************************************/
-/*
-** 2007 August 14
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the C functions that implement mutexes for win32
-*/
-
-/*
-** The code in this file is only used if we are compiling multithreaded
-** on a win32 system.
-*/
-#ifdef SQLITE_MUTEX_W32
-
-/*
-** Each recursive mutex is an instance of the following structure.
-*/
-struct sqlite3_mutex {
- CRITICAL_SECTION mutex; /* Mutex controlling the lock */
- int id; /* Mutex type */
-#ifdef SQLITE_DEBUG
- volatile int nRef; /* Number of enterances */
- volatile DWORD owner; /* Thread holding this mutex */
- int trace; /* True to trace changes */
-#endif
-};
-#define SQLITE_W32_MUTEX_INITIALIZER { 0 }
-#ifdef SQLITE_DEBUG
-#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 }
-#else
-#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
-#endif
-
-/*
-** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
-** or WinCE. Return false (zero) for Win95, Win98, or WinME.
-**
-** Here is an interesting observation: Win95, Win98, and WinME lack
-** the LockFileEx() API. But we can still statically link against that
-** API as long as we don't call it win running Win95/98/ME. A call to
-** this routine is used to determine if the host is Win95/98/ME or
-** WinNT/2K/XP so that we will know whether or not we can safely call
-** the LockFileEx() API.
-**
-** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
-** which is only available if your application was compiled with
-** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only
-** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef
-** this out as well.
-*/
-#if 0
-#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
-# define mutexIsNT() (1)
-#else
- static int mutexIsNT(void){
- static int osType = 0;
- if( osType==0 ){
- OSVERSIONINFO sInfo;
- sInfo.dwOSVersionInfoSize = sizeof(sInfo);
- GetVersionEx(&sInfo);
- osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
- }
- return osType==2;
- }
-#endif /* SQLITE_OS_WINCE */
-#endif
-
-#ifdef SQLITE_DEBUG
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use only inside assert() statements.
-*/
-static int winMutexHeld(sqlite3_mutex *p){
- return p->nRef!=0 && p->owner==GetCurrentThreadId();
-}
-static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){
- return p->nRef==0 || p->owner!=tid;
-}
-static int winMutexNotheld(sqlite3_mutex *p){
- DWORD tid = GetCurrentThreadId();
- return winMutexNotheld2(p, tid);
-}
-#endif
-
-
-/*
-** Initialize and deinitialize the mutex subsystem.
-*/
-static sqlite3_mutex winMutex_staticMutexes[6] = {
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER,
- SQLITE3_MUTEX_INITIALIZER
-};
-static int winMutex_isInit = 0;
-/* As winMutexInit() and winMutexEnd() are called as part
-** of the sqlite3_initialize and sqlite3_shutdown()
-** processing, the "interlocked" magic is probably not
-** strictly necessary.
-*/
-static long winMutex_lock = 0;
-
-SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
-
-static int winMutexInit(void){
- /* The first to increment to 1 does actual initialization */
- if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
- int i;
- for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
-#if SQLITE_OS_WINRT
- InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0);
-#else
- InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
-#endif
- }
- winMutex_isInit = 1;
- }else{
- /* Someone else is in the process of initing the static mutexes */
- while( !winMutex_isInit ){
- sqlite3_win32_sleep(1);
- }
- }
- return SQLITE_OK;
-}
-
-static int winMutexEnd(void){
- /* The first to decrement to 0 does actual shutdown
- ** (which should be the last to shutdown.) */
- if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
- if( winMutex_isInit==1 ){
- int i;
- for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
- DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
- }
- winMutex_isInit = 0;
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. If it returns NULL
-** that means that a mutex could not be allocated. SQLite
-** will unwind its stack and return an error. The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
-**
-** <ul>
-** <li> SQLITE_MUTEX_FAST
-** <li> SQLITE_MUTEX_RECURSIVE
-** <li> SQLITE_MUTEX_STATIC_MASTER
-** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
-** <li> SQLITE_MUTEX_STATIC_PRNG
-** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_PMEM
-** </ul>
-**
-** The first two constants cause sqlite3_mutex_alloc() to create
-** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
-** The mutex implementation does not need to make a distinction
-** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. But SQLite will only request a recursive mutex in
-** cases where it really needs one. If a faster non-recursive mutex
-** implementation is available on the host platform, the mutex subsystem
-** might return such a mutex in response to SQLITE_MUTEX_FAST.
-**
-** The other allowed parameters to sqlite3_mutex_alloc() each return
-** a pointer to a static preexisting mutex. Six static mutexes are
-** used by the current version of SQLite. Future versions of SQLite
-** may add additional static mutexes. Static mutexes are for internal
-** use by SQLite only. Applications that use SQLite mutexes should
-** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-** SQLITE_MUTEX_RECURSIVE.
-**
-** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. But for the static
-** mutex types, the same mutex is returned on every call that has
-** the same type number.
-*/
-static sqlite3_mutex *winMutexAlloc(int iType){
- sqlite3_mutex *p;
-
- switch( iType ){
- case SQLITE_MUTEX_FAST:
- case SQLITE_MUTEX_RECURSIVE: {
- p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
-#ifdef SQLITE_DEBUG
- p->id = iType;
-#endif
-#if SQLITE_OS_WINRT
- InitializeCriticalSectionEx(&p->mutex, 0, 0);
-#else
- InitializeCriticalSection(&p->mutex);
-#endif
- }
- break;
- }
- default: {
- assert( winMutex_isInit==1 );
- assert( iType-2 >= 0 );
- assert( iType-2 < ArraySize(winMutex_staticMutexes) );
- p = &winMutex_staticMutexes[iType-2];
-#ifdef SQLITE_DEBUG
- p->id = iType;
-#endif
- break;
- }
- }
- return p;
-}
-
-
-/*
-** This routine deallocates a previously
-** allocated mutex. SQLite is careful to deallocate every
-** mutex that it allocates.
-*/
-static void winMutexFree(sqlite3_mutex *p){
- assert( p );
- assert( p->nRef==0 && p->owner==0 );
- assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
- DeleteCriticalSection(&p->mutex);
- sqlite3_free(p);
-}
-
-/*
-** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
-** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
-** be entered multiple times by the same thread. In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter. If the same thread tries to enter any other kind of mutex
-** more than once, the behavior is undefined.
-*/
-static void winMutexEnter(sqlite3_mutex *p){
-#ifdef SQLITE_DEBUG
- DWORD tid = GetCurrentThreadId();
- assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
-#endif
- EnterCriticalSection(&p->mutex);
-#ifdef SQLITE_DEBUG
- assert( p->nRef>0 || p->owner==0 );
- p->owner = tid;
- p->nRef++;
- if( p->trace ){
- printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
- }
-#endif
-}
-static int winMutexTry(sqlite3_mutex *p){
-#ifndef NDEBUG
- DWORD tid = GetCurrentThreadId();
-#endif
- int rc = SQLITE_BUSY;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
- /*
- ** The sqlite3_mutex_try() routine is very rarely used, and when it
- ** is used it is merely an optimization. So it is OK for it to always
- ** fail.
- **
- ** The TryEnterCriticalSection() interface is only available on WinNT.
- ** And some windows compilers complain if you try to use it without
- ** first doing some #defines that prevent SQLite from building on Win98.
- ** For that reason, we will omit this optimization for now. See
- ** ticket #2685.
- */
-#if 0
- if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
- p->owner = tid;
- p->nRef++;
- rc = SQLITE_OK;
- }
-#else
- UNUSED_PARAMETER(p);
-#endif
-#ifdef SQLITE_DEBUG
- if( rc==SQLITE_OK && p->trace ){
- printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
- }
-#endif
- return rc;
-}
-
-/*
-** The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. The behavior
-** is undefined if the mutex is not currently entered or
-** is not currently allocated. SQLite will never do either.
-*/
-static void winMutexLeave(sqlite3_mutex *p){
-#ifndef NDEBUG
- DWORD tid = GetCurrentThreadId();
- assert( p->nRef>0 );
- assert( p->owner==tid );
- p->nRef--;
- if( p->nRef==0 ) p->owner = 0;
- assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
-#endif
- LeaveCriticalSection(&p->mutex);
-#ifdef SQLITE_DEBUG
- if( p->trace ){
- printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
- }
-#endif
-}
-
-SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
- static const sqlite3_mutex_methods sMutex = {
- winMutexInit,
- winMutexEnd,
- winMutexAlloc,
- winMutexFree,
- winMutexEnter,
- winMutexTry,
- winMutexLeave,
-#ifdef SQLITE_DEBUG
- winMutexHeld,
- winMutexNotheld
-#else
- 0,
- 0
-#endif
- };
-
- return &sMutex;
-}
-#endif /* SQLITE_MUTEX_W32 */
-
-/************** End of mutex_w32.c *******************************************/
-/************** Begin file malloc.c ******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** Memory allocation functions used throughout sqlite.
-*/
-/* #include <stdarg.h> */
-
-/*
-** Attempt to release up to n bytes of non-essential memory currently
-** held by SQLite. An example of non-essential memory is memory used to
-** cache database pages that are not currently in use.
-*/
-SQLITE_API int sqlite3_release_memory(int n){
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- return sqlite3PcacheReleaseMemory(n);
-#else
- /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine
- ** is a no-op returning zero if SQLite is not compiled with
- ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */
- UNUSED_PARAMETER(n);
- return 0;
-#endif
-}
-
-/*
-** An instance of the following object records the location of
-** each unused scratch buffer.
-*/
-typedef struct ScratchFreeslot {
- struct ScratchFreeslot *pNext; /* Next unused scratch buffer */
-} ScratchFreeslot;
-
-/*
-** State information local to the memory allocation subsystem.
-*/
-static SQLITE_WSD struct Mem0Global {
- sqlite3_mutex *mutex; /* Mutex to serialize access */
-
- /*
- ** The alarm callback and its arguments. The mem0.mutex lock will
- ** be held while the callback is running. Recursive calls into
- ** the memory subsystem are allowed, but no new callbacks will be
- ** issued.
- */
- sqlite3_int64 alarmThreshold;
- void (*alarmCallback)(void*, sqlite3_int64,int);
- void *alarmArg;
-
- /*
- ** Pointers to the end of sqlite3GlobalConfig.pScratch memory
- ** (so that a range test can be used to determine if an allocation
- ** being freed came from pScratch) and a pointer to the list of
- ** unused scratch allocations.
- */
- void *pScratchEnd;
- ScratchFreeslot *pScratchFree;
- u32 nScratchFree;
-
- /*
- ** True if heap is nearly "full" where "full" is defined by the
- ** sqlite3_soft_heap_limit() setting.
- */
- int nearlyFull;
-} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-#define mem0 GLOBAL(struct Mem0Global, mem0)
-
-/*
-** This routine runs when the memory allocator sees that the
-** total memory allocation is about to exceed the soft heap
-** limit.
-*/
-static void softHeapLimitEnforcer(
- void *NotUsed,
- sqlite3_int64 NotUsed2,
- int allocSize
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_release_memory(allocSize);
-}
-
-/*
-** Change the alarm callback
-*/
-static int sqlite3MemoryAlarm(
- void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
- void *pArg,
- sqlite3_int64 iThreshold
-){
- int nUsed;
- sqlite3_mutex_enter(mem0.mutex);
- mem0.alarmCallback = xCallback;
- mem0.alarmArg = pArg;
- mem0.alarmThreshold = iThreshold;
- nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed);
- sqlite3_mutex_leave(mem0.mutex);
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** Deprecated external interface. Internal/core SQLite code
-** should call sqlite3MemoryAlarm.
-*/
-SQLITE_API int sqlite3_memory_alarm(
- void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
- void *pArg,
- sqlite3_int64 iThreshold
-){
- return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
-}
-#endif
-
-/*
-** Set the soft heap-size limit for the library. Passing a zero or
-** negative value indicates no limit.
-*/
-SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
- sqlite3_int64 priorLimit;
- sqlite3_int64 excess;
-#ifndef SQLITE_OMIT_AUTOINIT
- int rc = sqlite3_initialize();
- if( rc ) return -1;
-#endif
- sqlite3_mutex_enter(mem0.mutex);
- priorLimit = mem0.alarmThreshold;
- sqlite3_mutex_leave(mem0.mutex);
- if( n<0 ) return priorLimit;
- if( n>0 ){
- sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
- }else{
- sqlite3MemoryAlarm(0, 0, 0);
- }
- excess = sqlite3_memory_used() - n;
- if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
- return priorLimit;
-}
-SQLITE_API void sqlite3_soft_heap_limit(int n){
- if( n<0 ) n = 0;
- sqlite3_soft_heap_limit64(n);
-}
-
-/*
-** Initialize the memory allocation subsystem.
-*/
-SQLITE_PRIVATE int sqlite3MallocInit(void){
- if( sqlite3GlobalConfig.m.xMalloc==0 ){
- sqlite3MemSetDefault();
- }
- memset(&mem0, 0, sizeof(mem0));
- if( sqlite3GlobalConfig.bCoreMutex ){
- mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- }
- if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
- && sqlite3GlobalConfig.nScratch>0 ){
- int i, n, sz;
- ScratchFreeslot *pSlot;
- sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch);
- sqlite3GlobalConfig.szScratch = sz;
- pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch;
- n = sqlite3GlobalConfig.nScratch;
- mem0.pScratchFree = pSlot;
- mem0.nScratchFree = n;
- for(i=0; i<n-1; i++){
- pSlot->pNext = (ScratchFreeslot*)(sz+(char*)pSlot);
- pSlot = pSlot->pNext;
- }
- pSlot->pNext = 0;
- mem0.pScratchEnd = (void*)&pSlot[1];
- }else{
- mem0.pScratchEnd = 0;
- sqlite3GlobalConfig.pScratch = 0;
- sqlite3GlobalConfig.szScratch = 0;
- sqlite3GlobalConfig.nScratch = 0;
- }
- if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
- || sqlite3GlobalConfig.nPage<1 ){
- sqlite3GlobalConfig.pPage = 0;
- sqlite3GlobalConfig.szPage = 0;
- sqlite3GlobalConfig.nPage = 0;
- }
- return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
-}
-
-/*
-** Return true if the heap is currently under memory pressure - in other
-** words if the amount of heap used is close to the limit set by
-** sqlite3_soft_heap_limit().
-*/
-SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
- return mem0.nearlyFull;
-}
-
-/*
-** Deinitialize the memory allocation subsystem.
-*/
-SQLITE_PRIVATE void sqlite3MallocEnd(void){
- if( sqlite3GlobalConfig.m.xShutdown ){
- sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData);
- }
- memset(&mem0, 0, sizeof(mem0));
-}
-
-/*
-** Return the amount of memory currently checked out.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
- int n, mx;
- sqlite3_int64 res;
- sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
- res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */
- return res;
-}
-
-/*
-** Return the maximum amount of memory that has ever been
-** checked out since either the beginning of this process
-** or since the most recent reset.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
- int n, mx;
- sqlite3_int64 res;
- sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
- res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */
- return res;
-}
-
-/*
-** Trigger the alarm
-*/
-static void sqlite3MallocAlarm(int nByte){
- void (*xCallback)(void*,sqlite3_int64,int);
- sqlite3_int64 nowUsed;
- void *pArg;
- if( mem0.alarmCallback==0 ) return;
- xCallback = mem0.alarmCallback;
- nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- pArg = mem0.alarmArg;
- mem0.alarmCallback = 0;
- sqlite3_mutex_leave(mem0.mutex);
- xCallback(pArg, nowUsed, nByte);
- sqlite3_mutex_enter(mem0.mutex);
- mem0.alarmCallback = xCallback;
- mem0.alarmArg = pArg;
-}
-
-/*
-** Do a memory allocation with statistics and alarms. Assume the
-** lock is already held.
-*/
-static int mallocWithAlarm(int n, void **pp){
- int nFull;
- void *p;
- assert( sqlite3_mutex_held(mem0.mutex) );
- nFull = sqlite3GlobalConfig.m.xRoundup(n);
- sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
- if( mem0.alarmCallback!=0 ){
- int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- if( nUsed >= mem0.alarmThreshold - nFull ){
- mem0.nearlyFull = 1;
- sqlite3MallocAlarm(nFull);
- }else{
- mem0.nearlyFull = 0;
- }
- }
- p = sqlite3GlobalConfig.m.xMalloc(nFull);
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- if( p==0 && mem0.alarmCallback ){
- sqlite3MallocAlarm(nFull);
- p = sqlite3GlobalConfig.m.xMalloc(nFull);
- }
-#endif
- if( p ){
- nFull = sqlite3MallocSize(p);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
- sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
- }
- *pp = p;
- return nFull;
-}
-
-/*
-** Allocate memory. This routine is like sqlite3_malloc() except that it
-** assumes the memory subsystem has already been initialized.
-*/
-SQLITE_PRIVATE void *sqlite3Malloc(int n){
- void *p;
- if( n<=0 /* IMP: R-65312-04917 */
- || n>=0x7fffff00
- ){
- /* A memory allocation of a number of bytes which is near the maximum
- ** signed integer value might cause an integer overflow inside of the
- ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving
- ** 255 bytes of overhead. SQLite itself will never use anything near
- ** this amount. The only way to reach the limit is with sqlite3_malloc() */
- p = 0;
- }else if( sqlite3GlobalConfig.bMemstat ){
- sqlite3_mutex_enter(mem0.mutex);
- mallocWithAlarm(n, &p);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- p = sqlite3GlobalConfig.m.xMalloc(n);
- }
- assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */
- return p;
-}
-
-/*
-** This version of the memory allocation is for use by the application.
-** First make sure the memory subsystem is initialized, then do the
-** allocation.
-*/
-SQLITE_API void *sqlite3_malloc(int n){
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return sqlite3Malloc(n);
-}
-
-/*
-** Each thread may only have a single outstanding allocation from
-** xScratchMalloc(). We verify this constraint in the single-threaded
-** case by setting scratchAllocOut to 1 when an allocation
-** is outstanding clearing it when the allocation is freed.
-*/
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
-static int scratchAllocOut = 0;
-#endif
-
-
-/*
-** Allocate memory that is to be used and released right away.
-** This routine is similar to alloca() in that it is not intended
-** for situations where the memory might be held long-term. This
-** routine is intended to get memory to old large transient data
-** structures that would not normally fit on the stack of an
-** embedded processor.
-*/
-SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
- void *p;
- assert( n>0 );
-
- sqlite3_mutex_enter(mem0.mutex);
- if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
- p = mem0.pScratchFree;
- mem0.pScratchFree = mem0.pScratchFree->pNext;
- mem0.nScratchFree--;
- sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
- sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- if( sqlite3GlobalConfig.bMemstat ){
- sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
- n = mallocWithAlarm(n, &p);
- if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- sqlite3_mutex_leave(mem0.mutex);
- p = sqlite3GlobalConfig.m.xMalloc(n);
- }
- sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
- }
- assert( sqlite3_mutex_notheld(mem0.mutex) );
-
-
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
- /* Verify that no more than two scratch allocations per thread
- ** are outstanding at one time. (This is only checked in the
- ** single-threaded case since checking in the multi-threaded case
- ** would be much more complicated.) */
- assert( scratchAllocOut<=1 );
- if( p ) scratchAllocOut++;
-#endif
-
- return p;
-}
-SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
- if( p ){
-
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
- /* Verify that no more than two scratch allocation per thread
- ** is outstanding at one time. (This is only checked in the
- ** single-threaded case since checking in the multi-threaded case
- ** would be much more complicated.) */
- assert( scratchAllocOut>=1 && scratchAllocOut<=2 );
- scratchAllocOut--;
-#endif
-
- if( p>=sqlite3GlobalConfig.pScratch && p<mem0.pScratchEnd ){
- /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
- ScratchFreeslot *pSlot;
- pSlot = (ScratchFreeslot*)p;
- sqlite3_mutex_enter(mem0.mutex);
- pSlot->pNext = mem0.pScratchFree;
- mem0.pScratchFree = pSlot;
- mem0.nScratchFree++;
- assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
- sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- /* Release memory back to the heap */
- assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
- assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) );
- sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- if( sqlite3GlobalConfig.bMemstat ){
- int iSize = sqlite3MallocSize(p);
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
- sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
- sqlite3GlobalConfig.m.xFree(p);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- sqlite3GlobalConfig.m.xFree(p);
- }
- }
- }
-}
-
-/*
-** TRUE if p is a lookaside memory allocation from db
-*/
-#ifndef SQLITE_OMIT_LOOKASIDE
-static int isLookaside(sqlite3 *db, void *p){
- return p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;
-}
-#else
-#define isLookaside(A,B) 0
-#endif
-
-/*
-** Return the size of a memory allocation previously obtained from
-** sqlite3Malloc() or sqlite3_malloc().
-*/
-SQLITE_PRIVATE int sqlite3MallocSize(void *p){
- assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
- assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
- return sqlite3GlobalConfig.m.xSize(p);
-}
-SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
- if( db && isLookaside(db, p) ){
- return db->lookaside.sz;
- }else{
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
- assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
- return sqlite3GlobalConfig.m.xSize(p);
- }
-}
-
-/*
-** Free memory previously obtained from sqlite3Malloc().
-*/
-SQLITE_API void sqlite3_free(void *p){
- if( p==0 ) return; /* IMP: R-49053-54554 */
- assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
- assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
- if( sqlite3GlobalConfig.bMemstat ){
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
- sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
- sqlite3GlobalConfig.m.xFree(p);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- sqlite3GlobalConfig.m.xFree(p);
- }
-}
-
-/*
-** Free memory that might be associated with a particular database
-** connection.
-*/
-SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
- if( db ){
- if( db->pnBytesFreed ){
- *db->pnBytesFreed += sqlite3DbMallocSize(db, p);
- return;
- }
- if( isLookaside(db, p) ){
- LookasideSlot *pBuf = (LookasideSlot*)p;
-#if SQLITE_DEBUG
- /* Trash all content in the buffer being freed */
- memset(p, 0xaa, db->lookaside.sz);
-#endif
- pBuf->pNext = db->lookaside.pFree;
- db->lookaside.pFree = pBuf;
- db->lookaside.nOut--;
- return;
- }
- }
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
- assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
- sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- sqlite3_free(p);
-}
-
-/*
-** Change the size of an existing memory allocation
-*/
-SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
- int nOld, nNew, nDiff;
- void *pNew;
- if( pOld==0 ){
- return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
- }
- if( nBytes<=0 ){
- sqlite3_free(pOld); /* IMP: R-31593-10574 */
- return 0;
- }
- if( nBytes>=0x7fffff00 ){
- /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
- return 0;
- }
- nOld = sqlite3MallocSize(pOld);
- /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second
- ** argument to xRealloc is always a value returned by a prior call to
- ** xRoundup. */
- nNew = sqlite3GlobalConfig.m.xRoundup(nBytes);
- if( nOld==nNew ){
- pNew = pOld;
- }else if( sqlite3GlobalConfig.bMemstat ){
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
- nDiff = nNew - nOld;
- if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
- mem0.alarmThreshold-nDiff ){
- sqlite3MallocAlarm(nDiff);
- }
- assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
- assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
- pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
- if( pNew==0 && mem0.alarmCallback ){
- sqlite3MallocAlarm(nBytes);
- pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
- }
- if( pNew ){
- nNew = sqlite3MallocSize(pNew);
- sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
- }
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
- }
- assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */
- return pNew;
-}
-
-/*
-** The public interface to sqlite3Realloc. Make sure that the memory
-** subsystem is initialized prior to invoking sqliteRealloc.
-*/
-SQLITE_API void *sqlite3_realloc(void *pOld, int n){
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- return sqlite3Realloc(pOld, n);
-}
-
-
-/*
-** Allocate and zero memory.
-*/
-SQLITE_PRIVATE void *sqlite3MallocZero(int n){
- void *p = sqlite3Malloc(n);
- if( p ){
- memset(p, 0, n);
- }
- return p;
-}
-
-/*
-** Allocate and zero memory. If the allocation fails, make
-** the mallocFailed flag in the connection pointer.
-*/
-SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){
- void *p = sqlite3DbMallocRaw(db, n);
- if( p ){
- memset(p, 0, n);
- }
- return p;
-}
-
-/*
-** Allocate and zero memory. If the allocation fails, make
-** the mallocFailed flag in the connection pointer.
-**
-** If db!=0 and db->mallocFailed is true (indicating a prior malloc
-** failure on the same database connection) then always return 0.
-** Hence for a particular database connection, once malloc starts
-** failing, it fails consistently until mallocFailed is reset.
-** This is an important assumption. There are many places in the
-** code that do things like this:
-**
-** int *a = (int*)sqlite3DbMallocRaw(db, 100);
-** int *b = (int*)sqlite3DbMallocRaw(db, 200);
-** if( b ) a[10] = 9;
-**
-** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
-** that all prior mallocs (ex: "a") worked too.
-*/
-SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
- void *p;
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
- assert( db==0 || db->pnBytesFreed==0 );
-#ifndef SQLITE_OMIT_LOOKASIDE
- if( db ){
- LookasideSlot *pBuf;
- if( db->mallocFailed ){
- return 0;
- }
- if( db->lookaside.bEnabled ){
- if( n>db->lookaside.sz ){
- db->lookaside.anStat[1]++;
- }else if( (pBuf = db->lookaside.pFree)==0 ){
- db->lookaside.anStat[2]++;
- }else{
- db->lookaside.pFree = pBuf->pNext;
- db->lookaside.nOut++;
- db->lookaside.anStat[0]++;
- if( db->lookaside.nOut>db->lookaside.mxOut ){
- db->lookaside.mxOut = db->lookaside.nOut;
- }
- return (void*)pBuf;
- }
- }
- }
-#else
- if( db && db->mallocFailed ){
- return 0;
- }
-#endif
- p = sqlite3Malloc(n);
- if( !p && db ){
- db->mallocFailed = 1;
- }
- sqlite3MemdebugSetType(p, MEMTYPE_DB |
- ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
- return p;
-}
-
-/*
-** Resize the block of memory pointed to by p to n bytes. If the
-** resize fails, set the mallocFailed flag in the connection object.
-*/
-SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
- void *pNew = 0;
- assert( db!=0 );
- assert( sqlite3_mutex_held(db->mutex) );
- if( db->mallocFailed==0 ){
- if( p==0 ){
- return sqlite3DbMallocRaw(db, n);
- }
- if( isLookaside(db, p) ){
- if( n<=db->lookaside.sz ){
- return p;
- }
- pNew = sqlite3DbMallocRaw(db, n);
- if( pNew ){
- memcpy(pNew, p, db->lookaside.sz);
- sqlite3DbFree(db, p);
- }
- }else{
- assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
- assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
- sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- pNew = sqlite3_realloc(p, n);
- if( !pNew ){
- sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
- db->mallocFailed = 1;
- }
- sqlite3MemdebugSetType(pNew, MEMTYPE_DB |
- (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
- }
- }
- return pNew;
-}
-
-/*
-** Attempt to reallocate p. If the reallocation fails, then free p
-** and set the mallocFailed flag in the database connection.
-*/
-SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){
- void *pNew;
- pNew = sqlite3DbRealloc(db, p, n);
- if( !pNew ){
- sqlite3DbFree(db, p);
- }
- return pNew;
-}
-
-/*
-** Make a copy of a string in memory obtained from sqliteMalloc(). These
-** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This
-** is because when memory debugging is turned on, these two functions are
-** called via macros that record the current file and line number in the
-** ThreadData structure.
-*/
-SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
- char *zNew;
- size_t n;
- if( z==0 ){
- return 0;
- }
- n = sqlite3Strlen30(z) + 1;
- assert( (n&0x7fffffff)==n );
- zNew = sqlite3DbMallocRaw(db, (int)n);
- if( zNew ){
- memcpy(zNew, z, n);
- }
- return zNew;
-}
-SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
- char *zNew;
- if( z==0 ){
- return 0;
- }
- assert( (n&0x7fffffff)==n );
- zNew = sqlite3DbMallocRaw(db, n+1);
- if( zNew ){
- memcpy(zNew, z, n);
- zNew[n] = 0;
- }
- return zNew;
-}
-
-/*
-** Create a string from the zFromat argument and the va_list that follows.
-** Store the string in memory obtained from sqliteMalloc() and make *pz
-** point to that string.
-*/
-SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
- va_list ap;
- char *z;
-
- va_start(ap, zFormat);
- z = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- sqlite3DbFree(db, *pz);
- *pz = z;
-}
-
-
-/*
-** This function must be called before exiting any API function (i.e.
-** returning control to the user) that has called sqlite3_malloc or
-** sqlite3_realloc.
-**
-** The returned value is normally a copy of the second argument to this
-** function. However, if a malloc() failure has occurred since the previous
-** invocation SQLITE_NOMEM is returned instead.
-**
-** If the first argument, db, is not NULL and a malloc() error has occurred,
-** then the connection error-code (the value returned by sqlite3_errcode())
-** is set to SQLITE_NOMEM.
-*/
-SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
- /* If the db handle is not NULL, then we must hold the connection handle
- ** mutex here. Otherwise the read (and possible write) of db->mallocFailed
- ** is unsafe, as is the call to sqlite3Error().
- */
- assert( !db || sqlite3_mutex_held(db->mutex) );
- if( db && (db->mallocFailed || rc==SQLITE_IOERR_NOMEM) ){
- sqlite3Error(db, SQLITE_NOMEM, 0);
- db->mallocFailed = 0;
- rc = SQLITE_NOMEM;
- }
- return rc & (db ? db->errMask : 0xff);
-}
-
-/************** End of malloc.c **********************************************/
-/************** Begin file printf.c ******************************************/
-/*
-** The "printf" code that follows dates from the 1980's. It is in
-** the public domain. The original comments are included here for
-** completeness. They are very out-of-date but might be useful as
-** an historical reference. Most of the "enhancements" have been backed
-** out so that the functionality is now the same as standard printf().
-**
-**************************************************************************
-**
-** This file contains code for a set of "printf"-like routines. These
-** routines format strings much like the printf() from the standard C
-** library, though the implementation here has enhancements to support
-** SQLlite.
-*/
-
-/*
-** Conversion types fall into various categories as defined by the
-** following enumeration.
-*/
-#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */
-#define etFLOAT 2 /* Floating point. %f */
-#define etEXP 3 /* Exponentional notation. %e and %E */
-#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */
-#define etSIZE 5 /* Return number of characters processed so far. %n */
-#define etSTRING 6 /* Strings. %s */
-#define etDYNSTRING 7 /* Dynamically allocated strings. %z */
-#define etPERCENT 8 /* Percent symbol. %% */
-#define etCHARX 9 /* Characters. %c */
-/* The rest are extensions, not normally found in printf() */
-#define etSQLESCAPE 10 /* Strings with '\'' doubled. %q */
-#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
- NULL pointers replaced by SQL NULL. %Q */
-#define etTOKEN 12 /* a pointer to a Token structure */
-#define etSRCLIST 13 /* a pointer to a SrcList */
-#define etPOINTER 14 /* The %p conversion */
-#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
-#define etORDINAL 16 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
-
-#define etINVALID 0 /* Any unrecognized conversion type */
-
-
-/*
-** An "etByte" is an 8-bit unsigned value.
-*/
-typedef unsigned char etByte;
-
-/*
-** Each builtin conversion character (ex: the 'd' in "%d") is described
-** by an instance of the following structure
-*/
-typedef struct et_info { /* Information about each format field */
- char fmttype; /* The format field code letter */
- etByte base; /* The base for radix conversion */
- etByte flags; /* One or more of FLAG_ constants below */
- etByte type; /* Conversion paradigm */
- etByte charset; /* Offset into aDigits[] of the digits string */
- etByte prefix; /* Offset into aPrefix[] of the prefix string */
-} et_info;
-
-/*
-** Allowed values for et_info.flags
-*/
-#define FLAG_SIGNED 1 /* True if the value to convert is signed */
-#define FLAG_INTERN 2 /* True if for internal use only */
-#define FLAG_STRING 4 /* Allow infinity precision */
-
-
-/*
-** The following table is searched linearly, so it is good to put the
-** most frequently used conversion types first.
-*/
-static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
-static const char aPrefix[] = "-x0\000X0";
-static const et_info fmtinfo[] = {
- { 'd', 10, 1, etRADIX, 0, 0 },
- { 's', 0, 4, etSTRING, 0, 0 },
- { 'g', 0, 1, etGENERIC, 30, 0 },
- { 'z', 0, 4, etDYNSTRING, 0, 0 },
- { 'q', 0, 4, etSQLESCAPE, 0, 0 },
- { 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
- { 'w', 0, 4, etSQLESCAPE3, 0, 0 },
- { 'c', 0, 0, etCHARX, 0, 0 },
- { 'o', 8, 0, etRADIX, 0, 2 },
- { 'u', 10, 0, etRADIX, 0, 0 },
- { 'x', 16, 0, etRADIX, 16, 1 },
- { 'X', 16, 0, etRADIX, 0, 4 },
-#ifndef SQLITE_OMIT_FLOATING_POINT
- { 'f', 0, 1, etFLOAT, 0, 0 },
- { 'e', 0, 1, etEXP, 30, 0 },
- { 'E', 0, 1, etEXP, 14, 0 },
- { 'G', 0, 1, etGENERIC, 14, 0 },
-#endif
- { 'i', 10, 1, etRADIX, 0, 0 },
- { 'n', 0, 0, etSIZE, 0, 0 },
- { '%', 0, 0, etPERCENT, 0, 0 },
- { 'p', 16, 0, etPOINTER, 0, 1 },
-
-/* All the rest have the FLAG_INTERN bit set and are thus for internal
-** use only */
- { 'T', 0, 2, etTOKEN, 0, 0 },
- { 'S', 0, 2, etSRCLIST, 0, 0 },
- { 'r', 10, 3, etORDINAL, 0, 0 },
-};
-
-/*
-** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
-** conversions will work.
-*/
-#ifndef SQLITE_OMIT_FLOATING_POINT
-/*
-** "*val" is a double such that 0.1 <= *val < 10.0
-** Return the ascii code for the leading digit of *val, then
-** multiply "*val" by 10.0 to renormalize.
-**
-** Example:
-** input: *val = 3.14159
-** output: *val = 1.4159 function return = '3'
-**
-** The counter *cnt is incremented each time. After counter exceeds
-** 16 (the number of significant digits in a 64-bit float) '0' is
-** always returned.
-*/
-static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
- int digit;
- LONGDOUBLE_TYPE d;
- if( (*cnt)<=0 ) return '0';
- (*cnt)--;
- digit = (int)*val;
- d = digit;
- digit += '0';
- *val = (*val - d)*10.0;
- return (char)digit;
-}
-#endif /* SQLITE_OMIT_FLOATING_POINT */
-
-/*
-** Append N space characters to the given string buffer.
-*/
-SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *pAccum, int N){
- static const char zSpaces[] = " ";
- while( N>=(int)sizeof(zSpaces)-1 ){
- sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1);
- N -= sizeof(zSpaces)-1;
- }
- if( N>0 ){
- sqlite3StrAccumAppend(pAccum, zSpaces, N);
- }
-}
-
-/*
-** On machines with a small stack size, you can redefine the
-** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
-*/
-#ifndef SQLITE_PRINT_BUF_SIZE
-# define SQLITE_PRINT_BUF_SIZE 70
-#endif
-#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
-
-/*
-** Render a string given by "fmt" into the StrAccum object.
-*/
-SQLITE_PRIVATE void sqlite3VXPrintf(
- StrAccum *pAccum, /* Accumulate results here */
- int useExtended, /* Allow extended %-conversions */
- const char *fmt, /* Format string */
- va_list ap /* arguments */
-){
- int c; /* Next character in the format string */
- char *bufpt; /* Pointer to the conversion buffer */
- int precision; /* Precision of the current field */
- int length; /* Length of the field */
- int idx; /* A general purpose loop counter */
- int width; /* Width of the current field */
- etByte flag_leftjustify; /* True if "-" flag is present */
- etByte flag_plussign; /* True if "+" flag is present */
- etByte flag_blanksign; /* True if " " flag is present */
- etByte flag_alternateform; /* True if "#" flag is present */
- etByte flag_altform2; /* True if "!" flag is present */
- etByte flag_zeropad; /* True if field width constant starts with zero */
- etByte flag_long; /* True if "l" flag is present */
- etByte flag_longlong; /* True if the "ll" flag is present */
- etByte done; /* Loop termination flag */
- etByte xtype = 0; /* Conversion paradigm */
- char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
- sqlite_uint64 longvalue; /* Value for integer types */
- LONGDOUBLE_TYPE realvalue; /* Value for real types */
- const et_info *infop; /* Pointer to the appropriate info structure */
- char *zOut; /* Rendering buffer */
- int nOut; /* Size of the rendering buffer */
- char *zExtra; /* Malloced memory used by some conversion */
-#ifndef SQLITE_OMIT_FLOATING_POINT
- int exp, e2; /* exponent of real numbers */
- int nsd; /* Number of significant digits returned */
- double rounder; /* Used for rounding floating point values */
- etByte flag_dp; /* True if decimal point should be shown */
- etByte flag_rtz; /* True if trailing zeros should be removed */
-#endif
- char buf[etBUFSIZE]; /* Conversion buffer */
-
- bufpt = 0;
- for(; (c=(*fmt))!=0; ++fmt){
- if( c!='%' ){
- int amt;
- bufpt = (char *)fmt;
- amt = 1;
- while( (c=(*++fmt))!='%' && c!=0 ) amt++;
- sqlite3StrAccumAppend(pAccum, bufpt, amt);
- if( c==0 ) break;
- }
- if( (c=(*++fmt))==0 ){
- sqlite3StrAccumAppend(pAccum, "%", 1);
- break;
- }
- /* Find out what flags are present */
- flag_leftjustify = flag_plussign = flag_blanksign =
- flag_alternateform = flag_altform2 = flag_zeropad = 0;
- done = 0;
- do{
- switch( c ){
- case '-': flag_leftjustify = 1; break;
- case '+': flag_plussign = 1; break;
- case ' ': flag_blanksign = 1; break;
- case '#': flag_alternateform = 1; break;
- case '!': flag_altform2 = 1; break;
- case '0': flag_zeropad = 1; break;
- default: done = 1; break;
- }
- }while( !done && (c=(*++fmt))!=0 );
- /* Get the field width */
- width = 0;
- if( c=='*' ){
- width = va_arg(ap,int);
- if( width<0 ){
- flag_leftjustify = 1;
- width = -width;
- }
- c = *++fmt;
- }else{
- while( c>='0' && c<='9' ){
- width = width*10 + c - '0';
- c = *++fmt;
- }
- }
- /* Get the precision */
- if( c=='.' ){
- precision = 0;
- c = *++fmt;
- if( c=='*' ){
- precision = va_arg(ap,int);
- if( precision<0 ) precision = -precision;
- c = *++fmt;
- }else{
- while( c>='0' && c<='9' ){
- precision = precision*10 + c - '0';
- c = *++fmt;
- }
- }
- }else{
- precision = -1;
- }
- /* Get the conversion type modifier */
- if( c=='l' ){
- flag_long = 1;
- c = *++fmt;
- if( c=='l' ){
- flag_longlong = 1;
- c = *++fmt;
- }else{
- flag_longlong = 0;
- }
- }else{
- flag_long = flag_longlong = 0;
- }
- /* Fetch the info entry for the field */
- infop = &fmtinfo[0];
- xtype = etINVALID;
- for(idx=0; idx<ArraySize(fmtinfo); idx++){
- if( c==fmtinfo[idx].fmttype ){
- infop = &fmtinfo[idx];
- if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
- xtype = infop->type;
- }else{
- return;
- }
- break;
- }
- }
- zExtra = 0;
-
- /*
- ** At this point, variables are initialized as follows:
- **
- ** flag_alternateform TRUE if a '#' is present.
- ** flag_altform2 TRUE if a '!' is present.
- ** flag_plussign TRUE if a '+' is present.
- ** flag_leftjustify TRUE if a '-' is present or if the
- ** field width was negative.
- ** flag_zeropad TRUE if the width began with 0.
- ** flag_long TRUE if the letter 'l' (ell) prefixed
- ** the conversion character.
- ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed
- ** the conversion character.
- ** flag_blanksign TRUE if a ' ' is present.
- ** width The specified field width. This is
- ** always non-negative. Zero is the default.
- ** precision The specified precision. The default
- ** is -1.
- ** xtype The class of the conversion.
- ** infop Pointer to the appropriate info struct.
- */
- switch( xtype ){
- case etPOINTER:
- flag_longlong = sizeof(char*)==sizeof(i64);
- flag_long = sizeof(char*)==sizeof(long int);
- /* Fall through into the next case */
- case etORDINAL:
- case etRADIX:
- if( infop->flags & FLAG_SIGNED ){
- i64 v;
- if( flag_longlong ){
- v = va_arg(ap,i64);
- }else if( flag_long ){
- v = va_arg(ap,long int);
- }else{
- v = va_arg(ap,int);
- }
- if( v<0 ){
- if( v==SMALLEST_INT64 ){
- longvalue = ((u64)1)<<63;
- }else{
- longvalue = -v;
- }
- prefix = '-';
- }else{
- longvalue = v;
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
- }
- }else{
- if( flag_longlong ){
- longvalue = va_arg(ap,u64);
- }else if( flag_long ){
- longvalue = va_arg(ap,unsigned long int);
- }else{
- longvalue = va_arg(ap,unsigned int);
- }
- prefix = 0;
- }
- if( longvalue==0 ) flag_alternateform = 0;
- if( flag_zeropad && precision<width-(prefix!=0) ){
- precision = width-(prefix!=0);
- }
- if( precision<etBUFSIZE-10 ){
- nOut = etBUFSIZE;
- zOut = buf;
- }else{
- nOut = precision + 10;
- zOut = zExtra = sqlite3Malloc( nOut );
- if( zOut==0 ){
- pAccum->mallocFailed = 1;
- return;
- }
- }
- bufpt = &zOut[nOut-1];
- if( xtype==etORDINAL ){
- static const char zOrd[] = "thstndrd";
- int x = (int)(longvalue % 10);
- if( x>=4 || (longvalue/10)%10==1 ){
- x = 0;
- }
- *(--bufpt) = zOrd[x*2+1];
- *(--bufpt) = zOrd[x*2];
- }
- {
- register const char *cset; /* Use registers for speed */
- register int base;
- cset = &aDigits[infop->charset];
- base = infop->base;
- do{ /* Convert to ascii */
- *(--bufpt) = cset[longvalue%base];
- longvalue = longvalue/base;
- }while( longvalue>0 );
- }
- length = (int)(&zOut[nOut-1]-bufpt);
- for(idx=precision-length; idx>0; idx--){
- *(--bufpt) = '0'; /* Zero pad */
- }
- if( prefix ) *(--bufpt) = prefix; /* Add sign */
- if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
- const char *pre;
- char x;
- pre = &aPrefix[infop->prefix];
- for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
- }
- length = (int)(&zOut[nOut-1]-bufpt);
- break;
- case etFLOAT:
- case etEXP:
- case etGENERIC:
- realvalue = va_arg(ap,double);
-#ifdef SQLITE_OMIT_FLOATING_POINT
- length = 0;
-#else
- if( precision<0 ) precision = 6; /* Set default precision */
- if( realvalue<0.0 ){
- realvalue = -realvalue;
- prefix = '-';
- }else{
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
- }
- if( xtype==etGENERIC && precision>0 ) precision--;
-#if 0
- /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */
- for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
-#else
- /* It makes more sense to use 0.5 */
- for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
-#endif
- if( xtype==etFLOAT ) realvalue += rounder;
- /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
- exp = 0;
- if( sqlite3IsNaN((double)realvalue) ){
- bufpt = "NaN";
- length = 3;
- break;
- }
- if( realvalue>0.0 ){
- LONGDOUBLE_TYPE scale = 1.0;
- while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
- while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
- while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
- while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
- realvalue /= scale;
- while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
- while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
- if( exp>350 ){
- if( prefix=='-' ){
- bufpt = "-Inf";
- }else if( prefix=='+' ){
- bufpt = "+Inf";
- }else{
- bufpt = "Inf";
- }
- length = sqlite3Strlen30(bufpt);
- break;
- }
- }
- bufpt = buf;
- /*
- ** If the field type is etGENERIC, then convert to either etEXP
- ** or etFLOAT, as appropriate.
- */
- if( xtype!=etFLOAT ){
- realvalue += rounder;
- if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
- }
- if( xtype==etGENERIC ){
- flag_rtz = !flag_alternateform;
- if( exp<-4 || exp>precision ){
- xtype = etEXP;
- }else{
- precision = precision - exp;
- xtype = etFLOAT;
- }
- }else{
- flag_rtz = flag_altform2;
- }
- if( xtype==etEXP ){
- e2 = 0;
- }else{
- e2 = exp;
- }
- if( e2+precision+width > etBUFSIZE - 15 ){
- bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
- if( bufpt==0 ){
- pAccum->mallocFailed = 1;
- return;
- }
- }
- zOut = bufpt;
- nsd = 16 + flag_altform2*10;
- flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
- /* The sign in front of the number */
- if( prefix ){
- *(bufpt++) = prefix;
- }
- /* Digits prior to the decimal point */
- if( e2<0 ){
- *(bufpt++) = '0';
- }else{
- for(; e2>=0; e2--){
- *(bufpt++) = et_getdigit(&realvalue,&nsd);
- }
- }
- /* The decimal point */
- if( flag_dp ){
- *(bufpt++) = '.';
- }
- /* "0" digits after the decimal point but before the first
- ** significant digit of the number */
- for(e2++; e2<0; precision--, e2++){
- assert( precision>0 );
- *(bufpt++) = '0';
- }
- /* Significant digits after the decimal point */
- while( (precision--)>0 ){
- *(bufpt++) = et_getdigit(&realvalue,&nsd);
- }
- /* Remove trailing zeros and the "." if no digits follow the "." */
- if( flag_rtz && flag_dp ){
- while( bufpt[-1]=='0' ) *(--bufpt) = 0;
- assert( bufpt>zOut );
- if( bufpt[-1]=='.' ){
- if( flag_altform2 ){
- *(bufpt++) = '0';
- }else{
- *(--bufpt) = 0;
- }
- }
- }
- /* Add the "eNNN" suffix */
- if( xtype==etEXP ){
- *(bufpt++) = aDigits[infop->charset];
- if( exp<0 ){
- *(bufpt++) = '-'; exp = -exp;
- }else{
- *(bufpt++) = '+';
- }
- if( exp>=100 ){
- *(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */
- exp %= 100;
- }
- *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */
- *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */
- }
- *bufpt = 0;
-
- /* The converted number is in buf[] and zero terminated. Output it.
- ** Note that the number is in the usual order, not reversed as with
- ** integer conversions. */
- length = (int)(bufpt-zOut);
- bufpt = zOut;
-
- /* Special case: Add leading zeros if the flag_zeropad flag is
- ** set and we are not left justified */
- if( flag_zeropad && !flag_leftjustify && length < width){
- int i;
- int nPad = width - length;
- for(i=width; i>=nPad; i--){
- bufpt[i] = bufpt[i-nPad];
- }
- i = prefix!=0;
- while( nPad-- ) bufpt[i++] = '0';
- length = width;
- }
-#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */
- break;
- case etSIZE:
- *(va_arg(ap,int*)) = pAccum->nChar;
- length = width = 0;
- break;
- case etPERCENT:
- buf[0] = '%';
- bufpt = buf;
- length = 1;
- break;
- case etCHARX:
- c = va_arg(ap,int);
- buf[0] = (char)c;
- if( precision>=0 ){
- for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
- length = precision;
- }else{
- length =1;
- }
- bufpt = buf;
- break;
- case etSTRING:
- case etDYNSTRING:
- bufpt = va_arg(ap,char*);
- if( bufpt==0 ){
- bufpt = "";
- }else if( xtype==etDYNSTRING ){
- zExtra = bufpt;
- }
- if( precision>=0 ){
- for(length=0; length<precision && bufpt[length]; length++){}
- }else{
- length = sqlite3Strlen30(bufpt);
- }
- break;
- case etSQLESCAPE:
- case etSQLESCAPE2:
- case etSQLESCAPE3: {
- int i, j, k, n, isnull;
- int needQuote;
- char ch;
- char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */
- char *escarg = va_arg(ap,char*);
- isnull = escarg==0;
- if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
- k = precision;
- for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
- if( ch==q ) n++;
- }
- needQuote = !isnull && xtype==etSQLESCAPE2;
- n += i + 1 + needQuote*2;
- if( n>etBUFSIZE ){
- bufpt = zExtra = sqlite3Malloc( n );
- if( bufpt==0 ){
- pAccum->mallocFailed = 1;
- return;
- }
- }else{
- bufpt = buf;
- }
- j = 0;
- if( needQuote ) bufpt[j++] = q;
- k = i;
- for(i=0; i<k; i++){
- bufpt[j++] = ch = escarg[i];
- if( ch==q ) bufpt[j++] = ch;
- }
- if( needQuote ) bufpt[j++] = q;
- bufpt[j] = 0;
- length = j;
- /* The precision in %q and %Q means how many input characters to
- ** consume, not the length of the output...
- ** if( precision>=0 && precision<length ) length = precision; */
- break;
- }
- case etTOKEN: {
- Token *pToken = va_arg(ap, Token*);
- if( pToken ){
- sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
- }
- length = width = 0;
- break;
- }
- case etSRCLIST: {
- SrcList *pSrc = va_arg(ap, SrcList*);
- int k = va_arg(ap, int);
- struct SrcList_item *pItem = &pSrc->a[k];
- assert( k>=0 && k<pSrc->nSrc );
- if( pItem->zDatabase ){
- sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1);
- sqlite3StrAccumAppend(pAccum, ".", 1);
- }
- sqlite3StrAccumAppend(pAccum, pItem->zName, -1);
- length = width = 0;
- break;
- }
- default: {
- assert( xtype==etINVALID );
- return;
- }
- }/* End switch over the format type */
- /*
- ** The text of the conversion is pointed to by "bufpt" and is
- ** "length" characters long. The field width is "width". Do
- ** the output.
- */
- if( !flag_leftjustify ){
- register int nspace;
- nspace = width-length;
- if( nspace>0 ){
- sqlite3AppendSpace(pAccum, nspace);
- }
- }
- if( length>0 ){
- sqlite3StrAccumAppend(pAccum, bufpt, length);
- }
- if( flag_leftjustify ){
- register int nspace;
- nspace = width-length;
- if( nspace>0 ){
- sqlite3AppendSpace(pAccum, nspace);
- }
- }
- sqlite3_free(zExtra);
- }/* End for loop over the format string */
-} /* End of function */
-
-/*
-** Append N bytes of text from z to the StrAccum object.
-*/
-SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
- assert( z!=0 || N==0 );
- if( p->tooBig | p->mallocFailed ){
- testcase(p->tooBig);
- testcase(p->mallocFailed);
- return;
- }
- assert( p->zText!=0 || p->nChar==0 );
- if( N<0 ){
- N = sqlite3Strlen30(z);
- }
- if( N==0 || NEVER(z==0) ){
- return;
- }
- if( p->nChar+N >= p->nAlloc ){
- char *zNew;
- if( !p->useMalloc ){
- p->tooBig = 1;
- N = p->nAlloc - p->nChar - 1;
- if( N<=0 ){
- return;
- }
- }else{
- char *zOld = (p->zText==p->zBase ? 0 : p->zText);
- i64 szNew = p->nChar;
- szNew += N + 1;
- if( szNew > p->mxAlloc ){
- sqlite3StrAccumReset(p);
- p->tooBig = 1;
- return;
- }else{
- p->nAlloc = (int)szNew;
- }
- if( p->useMalloc==1 ){
- zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
- }else{
- zNew = sqlite3_realloc(zOld, p->nAlloc);
- }
- if( zNew ){
- if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
- p->zText = zNew;
- }else{
- p->mallocFailed = 1;
- sqlite3StrAccumReset(p);
- return;
- }
- }
- }
- assert( p->zText );
- memcpy(&p->zText[p->nChar], z, N);
- p->nChar += N;
-}
-
-/*
-** Finish off a string by making sure it is zero-terminated.
-** Return a pointer to the resulting string. Return a NULL
-** pointer if any kind of error was encountered.
-*/
-SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
- if( p->zText ){
- p->zText[p->nChar] = 0;
- if( p->useMalloc && p->zText==p->zBase ){
- if( p->useMalloc==1 ){
- p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
- }else{
- p->zText = sqlite3_malloc(p->nChar+1);
- }
- if( p->zText ){
- memcpy(p->zText, p->zBase, p->nChar+1);
- }else{
- p->mallocFailed = 1;
- }
- }
- }
- return p->zText;
-}
-
-/*
-** Reset an StrAccum string. Reclaim all malloced memory.
-*/
-SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
- if( p->zText!=p->zBase ){
- if( p->useMalloc==1 ){
- sqlite3DbFree(p->db, p->zText);
- }else{
- sqlite3_free(p->zText);
- }
- }
- p->zText = 0;
-}
-
-/*
-** Initialize a string accumulator
-*/
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
- p->zText = p->zBase = zBase;
- p->db = 0;
- p->nChar = 0;
- p->nAlloc = n;
- p->mxAlloc = mx;
- p->useMalloc = 1;
- p->tooBig = 0;
- p->mallocFailed = 0;
-}
-
-/*
-** Print into memory obtained from sqliteMalloc(). Use the internal
-** %-conversion extensions.
-*/
-SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
- char *z;
- char zBase[SQLITE_PRINT_BUF_SIZE];
- StrAccum acc;
- assert( db!=0 );
- sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
- db->aLimit[SQLITE_LIMIT_LENGTH]);
- acc.db = db;
- sqlite3VXPrintf(&acc, 1, zFormat, ap);
- z = sqlite3StrAccumFinish(&acc);
- if( acc.mallocFailed ){
- db->mallocFailed = 1;
- }
- return z;
-}
-
-/*
-** Print into memory obtained from sqliteMalloc(). Use the internal
-** %-conversion extensions.
-*/
-SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
- va_list ap;
- char *z;
- va_start(ap, zFormat);
- z = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- return z;
-}
-
-/*
-** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
-** the string and before returnning. This routine is intended to be used
-** to modify an existing string. For example:
-**
-** x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
-**
-*/
-SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
- va_list ap;
- char *z;
- va_start(ap, zFormat);
- z = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- sqlite3DbFree(db, zStr);
- return z;
-}
-
-/*
-** Print into memory obtained from sqlite3_malloc(). Omit the internal
-** %-conversion extensions.
-*/
-SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
- char *z;
- char zBase[SQLITE_PRINT_BUF_SIZE];
- StrAccum acc;
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
- acc.useMalloc = 2;
- sqlite3VXPrintf(&acc, 0, zFormat, ap);
- z = sqlite3StrAccumFinish(&acc);
- return z;
-}
-
-/*
-** Print into memory obtained from sqlite3_malloc()(). Omit the internal
-** %-conversion extensions.
-*/
-SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
- va_list ap;
- char *z;
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize() ) return 0;
-#endif
- va_start(ap, zFormat);
- z = sqlite3_vmprintf(zFormat, ap);
- va_end(ap);
- return z;
-}
-
-/*
-** sqlite3_snprintf() works like snprintf() except that it ignores the
-** current locale settings. This is important for SQLite because we
-** are not able to use a "," as the decimal point in place of "." as
-** specified by some locales.
-**
-** Oops: The first two arguments of sqlite3_snprintf() are backwards
-** from the snprintf() standard. Unfortunately, it is too late to change
-** this without breaking compatibility, so we just have to live with the
-** mistake.
-**
-** sqlite3_vsnprintf() is the varargs version.
-*/
-SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
- StrAccum acc;
- if( n<=0 ) return zBuf;
- sqlite3StrAccumInit(&acc, zBuf, n, 0);
- acc.useMalloc = 0;
- sqlite3VXPrintf(&acc, 0, zFormat, ap);
- return sqlite3StrAccumFinish(&acc);
-}
-SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
- char *z;
- va_list ap;
- va_start(ap,zFormat);
- z = sqlite3_vsnprintf(n, zBuf, zFormat, ap);
- va_end(ap);
- return z;
-}
-
-/*
-** This is the routine that actually formats the sqlite3_log() message.
-** We house it in a separate routine from sqlite3_log() to avoid using
-** stack space on small-stack systems when logging is disabled.
-**
-** sqlite3_log() must render into a static buffer. It cannot dynamically
-** allocate memory because it might be called while the memory allocator
-** mutex is held.
-*/
-static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
- StrAccum acc; /* String accumulator */
- char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
-
- sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
- acc.useMalloc = 0;
- sqlite3VXPrintf(&acc, 0, zFormat, ap);
- sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
- sqlite3StrAccumFinish(&acc));
-}
-
-/*
-** Format and write a message to the log if logging is enabled.
-*/
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
- va_list ap; /* Vararg list */
- if( sqlite3GlobalConfig.xLog ){
- va_start(ap, zFormat);
- renderLogMsg(iErrCode, zFormat, ap);
- va_end(ap);
- }
-}
-
-#if defined(SQLITE_DEBUG)
-/*
-** A version of printf() that understands %lld. Used for debugging.
-** The printf() built into some versions of windows does not understand %lld
-** and segfaults if you give it a long long int.
-*/
-SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
- va_list ap;
- StrAccum acc;
- char zBuf[500];
- sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
- acc.useMalloc = 0;
- va_start(ap,zFormat);
- sqlite3VXPrintf(&acc, 0, zFormat, ap);
- va_end(ap);
- sqlite3StrAccumFinish(&acc);
- fprintf(stdout,"%s", zBuf);
- fflush(stdout);
-}
-#endif
-
-#ifndef SQLITE_OMIT_TRACE
-/*
-** variable-argument wrapper around sqlite3VXPrintf().
-*/
-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
- va_list ap;
- va_start(ap,zFormat);
- sqlite3VXPrintf(p, 1, zFormat, ap);
- va_end(ap);
-}
-#endif
-
-/************** End of printf.c **********************************************/
-/************** Begin file random.c ******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code to implement a pseudo-random number
-** generator (PRNG) for SQLite.
-**
-** Random numbers are used by some of the database backends in order
-** to generate random integer keys for tables or random filenames.
-*/
-
-
-/* All threads share a single random number generator.
-** This structure is the current state of the generator.
-*/
-static SQLITE_WSD struct sqlite3PrngType {
- unsigned char isInit; /* True if initialized */
- unsigned char i, j; /* State variables */
- unsigned char s[256]; /* State variables */
-} sqlite3Prng;
-
-/*
-** Get a single 8-bit random value from the RC4 PRNG. The Mutex
-** must be held while executing this routine.
-**
-** Why not just use a library random generator like lrand48() for this?
-** Because the OP_NewRowid opcode in the VDBE depends on having a very
-** good source of random numbers. The lrand48() library function may
-** well be good enough. But maybe not. Or maybe lrand48() has some
-** subtle problems on some systems that could cause problems. It is hard
-** to know. To minimize the risk of problems due to bad lrand48()
-** implementations, SQLite uses this random number generator based
-** on RC4, which we know works very well.
-**
-** (Later): Actually, OP_NewRowid does not depend on a good source of
-** randomness any more. But we will leave this code in all the same.
-*/
-static u8 randomByte(void){
- unsigned char t;
-
-
- /* The "wsdPrng" macro will resolve to the pseudo-random number generator
- ** state vector. If writable static data is unsupported on the target,
- ** we have to locate the state vector at run-time. In the more common
- ** case where writable static data is supported, wsdPrng can refer directly
- ** to the "sqlite3Prng" state vector declared above.
- */
-#ifdef SQLITE_OMIT_WSD
- struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
-# define wsdPrng p[0]
-#else
-# define wsdPrng sqlite3Prng
-#endif
-
-
- /* Initialize the state of the random number generator once,
- ** the first time this routine is called. The seed value does
- ** not need to contain a lot of randomness since we are not
- ** trying to do secure encryption or anything like that...
- **
- ** Nothing in this file or anywhere else in SQLite does any kind of
- ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
- ** number generator) not as an encryption device.
- */
- if( !wsdPrng.isInit ){
- int i;
- char k[256];
- wsdPrng.j = 0;
- wsdPrng.i = 0;
- sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
- for(i=0; i<256; i++){
- wsdPrng.s[i] = (u8)i;
- }
- for(i=0; i<256; i++){
- wsdPrng.j += wsdPrng.s[i] + k[i];
- t = wsdPrng.s[wsdPrng.j];
- wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
- wsdPrng.s[i] = t;
- }
- wsdPrng.isInit = 1;
- }
-
- /* Generate and return single random byte
- */
- wsdPrng.i++;
- t = wsdPrng.s[wsdPrng.i];
- wsdPrng.j += t;
- wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
- wsdPrng.s[wsdPrng.j] = t;
- t += wsdPrng.s[wsdPrng.i];
- return wsdPrng.s[t];
-}
-
-/*
-** Return N random bytes.
-*/
-SQLITE_API void sqlite3_randomness(int N, void *pBuf){
- unsigned char *zBuf = pBuf;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
-#endif
- sqlite3_mutex_enter(mutex);
- while( N-- ){
- *(zBuf++) = randomByte();
- }
- sqlite3_mutex_leave(mutex);
-}
-
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-/*
-** For testing purposes, we sometimes want to preserve the state of
-** PRNG and restore the PRNG to its saved state at a later time, or
-** to reset the PRNG to its initial state. These routines accomplish
-** those tasks.
-**
-** The sqlite3_test_control() interface calls these routines to
-** control the PRNG.
-*/
-static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng;
-SQLITE_PRIVATE void sqlite3PrngSaveState(void){
- memcpy(
- &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
- &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
- sizeof(sqlite3Prng)
- );
-}
-SQLITE_PRIVATE void sqlite3PrngRestoreState(void){
- memcpy(
- &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
- &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
- sizeof(sqlite3Prng)
- );
-}
-SQLITE_PRIVATE void sqlite3PrngResetState(void){
- GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0;
-}
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
-
-/************** End of random.c **********************************************/
-/************** Begin file utf.c *********************************************/
-/*
-** 2004 April 13
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains routines used to translate between UTF-8,
-** UTF-16, UTF-16BE, and UTF-16LE.
-**
-** Notes on UTF-8:
-**
-** Byte-0 Byte-1 Byte-2 Byte-3 Value
-** 0xxxxxxx 00000000 00000000 0xxxxxxx
-** 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx
-** 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx
-** 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 000uuuuu zzzzyyyy yyxxxxxx
-**
-**
-** Notes on UTF-16: (with wwww+1==uuuuu)
-**
-** Word-0 Word-1 Value
-** 110110ww wwzzzzyy 110111yy yyxxxxxx 000uuuuu zzzzyyyy yyxxxxxx
-** zzzzyyyy yyxxxxxx 00000000 zzzzyyyy yyxxxxxx
-**
-**
-** BOM or Byte Order Mark:
-** 0xff 0xfe little-endian utf-16 follows
-** 0xfe 0xff big-endian utf-16 follows
-**
-*/
-/* #include <assert.h> */
-
-#ifndef SQLITE_AMALGAMATION
-/*
-** The following constant value is used by the SQLITE_BIGENDIAN and
-** SQLITE_LITTLEENDIAN macros.
-*/
-SQLITE_PRIVATE const int sqlite3one = 1;
-#endif /* SQLITE_AMALGAMATION */
-
-/*
-** This lookup table is used to help decode the first byte of
-** a multi-byte UTF8 character.
-*/
-static const unsigned char sqlite3Utf8Trans1[] = {
- 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,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
-};
-
-
-#define WRITE_UTF8(zOut, c) { \
- if( c<0x00080 ){ \
- *zOut++ = (u8)(c&0xFF); \
- } \
- else if( c<0x00800 ){ \
- *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \
- *zOut++ = 0x80 + (u8)(c & 0x3F); \
- } \
- else if( c<0x10000 ){ \
- *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \
- *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
- *zOut++ = 0x80 + (u8)(c & 0x3F); \
- }else{ \
- *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \
- *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \
- *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
- *zOut++ = 0x80 + (u8)(c & 0x3F); \
- } \
-}
-
-#define WRITE_UTF16LE(zOut, c) { \
- if( c<=0xFFFF ){ \
- *zOut++ = (u8)(c&0x00FF); \
- *zOut++ = (u8)((c>>8)&0x00FF); \
- }else{ \
- *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \
- *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \
- *zOut++ = (u8)(c&0x00FF); \
- *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \
- } \
-}
-
-#define WRITE_UTF16BE(zOut, c) { \
- if( c<=0xFFFF ){ \
- *zOut++ = (u8)((c>>8)&0x00FF); \
- *zOut++ = (u8)(c&0x00FF); \
- }else{ \
- *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \
- *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \
- *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \
- *zOut++ = (u8)(c&0x00FF); \
- } \
-}
-
-#define READ_UTF16LE(zIn, TERM, c){ \
- c = (*zIn++); \
- c += ((*zIn++)<<8); \
- if( c>=0xD800 && c<0xE000 && TERM ){ \
- int c2 = (*zIn++); \
- c2 += ((*zIn++)<<8); \
- c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
- } \
-}
-
-#define READ_UTF16BE(zIn, TERM, c){ \
- c = ((*zIn++)<<8); \
- c += (*zIn++); \
- if( c>=0xD800 && c<0xE000 && TERM ){ \
- int c2 = ((*zIn++)<<8); \
- c2 += (*zIn++); \
- c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
- } \
-}
-
-/*
-** Translate a single UTF-8 character. Return the unicode value.
-**
-** During translation, assume that the byte that zTerm points
-** is a 0x00.
-**
-** Write a pointer to the next unread byte back into *pzNext.
-**
-** Notes On Invalid UTF-8:
-**
-** * This routine never allows a 7-bit character (0x00 through 0x7f) to
-** be encoded as a multi-byte character. Any multi-byte character that
-** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd.
-**
-** * This routine never allows a UTF16 surrogate value to be encoded.
-** If a multi-byte character attempts to encode a value between
-** 0xd800 and 0xe000 then it is rendered as 0xfffd.
-**
-** * Bytes in the range of 0x80 through 0xbf which occur as the first
-** byte of a character are interpreted as single-byte characters
-** and rendered as themselves even though they are technically
-** invalid characters.
-**
-** * This routine accepts an infinite number of different UTF8 encodings
-** for unicode values 0x80 and greater. It do not change over-length
-** encodings to 0xfffd as some systems recommend.
-*/
-#define READ_UTF8(zIn, zTerm, c) \
- c = *(zIn++); \
- if( c>=0xc0 ){ \
- c = sqlite3Utf8Trans1[c-0xc0]; \
- while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
- c = (c<<6) + (0x3f & *(zIn++)); \
- } \
- if( c<0x80 \
- || (c&0xFFFFF800)==0xD800 \
- || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
- }
-SQLITE_PRIVATE u32 sqlite3Utf8Read(
- const unsigned char **pz /* Pointer to string from which to read char */
-){
- unsigned int c;
-
- /* Same as READ_UTF8() above but without the zTerm parameter.
- ** For this routine, we assume the UTF8 string is always zero-terminated.
- */
- c = *((*pz)++);
- if( c>=0xc0 ){
- c = sqlite3Utf8Trans1[c-0xc0];
- while( (*(*pz) & 0xc0)==0x80 ){
- c = (c<<6) + (0x3f & *((*pz)++));
- }
- if( c<0x80
- || (c&0xFFFFF800)==0xD800
- || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; }
- }
- return c;
-}
-
-
-
-
-/*
-** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
-** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
-*/
-/* #define TRANSLATE_TRACE 1 */
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** This routine transforms the internal text encoding used by pMem to
-** desiredEnc. It is an error if the string is already of the desired
-** encoding, or if *pMem does not contain a string value.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
- int len; /* Maximum length of output string in bytes */
- unsigned char *zOut; /* Output buffer */
- unsigned char *zIn; /* Input iterator */
- unsigned char *zTerm; /* End of input */
- unsigned char *z; /* Output iterator */
- unsigned int c;
-
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( pMem->flags&MEM_Str );
- assert( pMem->enc!=desiredEnc );
- assert( pMem->enc!=0 );
- assert( pMem->n>=0 );
-
-#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
- {
- char zBuf[100];
- sqlite3VdbeMemPrettyPrint(pMem, zBuf);
- fprintf(stderr, "INPUT: %s\n", zBuf);
- }
-#endif
-
- /* If the translation is between UTF-16 little and big endian, then
- ** all that is required is to swap the byte order. This case is handled
- ** differently from the others.
- */
- if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){
- u8 temp;
- int rc;
- rc = sqlite3VdbeMemMakeWriteable(pMem);
- if( rc!=SQLITE_OK ){
- assert( rc==SQLITE_NOMEM );
- return SQLITE_NOMEM;
- }
- zIn = (u8*)pMem->z;
- zTerm = &zIn[pMem->n&~1];
- while( zIn<zTerm ){
- temp = *zIn;
- *zIn = *(zIn+1);
- zIn++;
- *zIn++ = temp;
- }
- pMem->enc = desiredEnc;
- goto translate_out;
- }
-
- /* Set len to the maximum number of bytes required in the output buffer. */
- if( desiredEnc==SQLITE_UTF8 ){
- /* When converting from UTF-16, the maximum growth results from
- ** translating a 2-byte character to a 4-byte UTF-8 character.
- ** A single byte is required for the output string
- ** nul-terminator.
- */
- pMem->n &= ~1;
- len = pMem->n * 2 + 1;
- }else{
- /* When converting from UTF-8 to UTF-16 the maximum growth is caused
- ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
- ** character. Two bytes are required in the output buffer for the
- ** nul-terminator.
- */
- len = pMem->n * 2 + 2;
- }
-
- /* Set zIn to point at the start of the input buffer and zTerm to point 1
- ** byte past the end.
- **
- ** Variable zOut is set to point at the output buffer, space obtained
- ** from sqlite3_malloc().
- */
- zIn = (u8*)pMem->z;
- zTerm = &zIn[pMem->n];
- zOut = sqlite3DbMallocRaw(pMem->db, len);
- if( !zOut ){
- return SQLITE_NOMEM;
- }
- z = zOut;
-
- if( pMem->enc==SQLITE_UTF8 ){
- if( desiredEnc==SQLITE_UTF16LE ){
- /* UTF-8 -> UTF-16 Little-endian */
- while( zIn<zTerm ){
- READ_UTF8(zIn, zTerm, c);
- WRITE_UTF16LE(z, c);
- }
- }else{
- assert( desiredEnc==SQLITE_UTF16BE );
- /* UTF-8 -> UTF-16 Big-endian */
- while( zIn<zTerm ){
- READ_UTF8(zIn, zTerm, c);
- WRITE_UTF16BE(z, c);
- }
- }
- pMem->n = (int)(z - zOut);
- *z++ = 0;
- }else{
- assert( desiredEnc==SQLITE_UTF8 );
- if( pMem->enc==SQLITE_UTF16LE ){
- /* UTF-16 Little-endian -> UTF-8 */
- while( zIn<zTerm ){
- READ_UTF16LE(zIn, zIn<zTerm, c);
- WRITE_UTF8(z, c);
- }
- }else{
- /* UTF-16 Big-endian -> UTF-8 */
- while( zIn<zTerm ){
- READ_UTF16BE(zIn, zIn<zTerm, c);
- WRITE_UTF8(z, c);
- }
- }
- pMem->n = (int)(z - zOut);
- }
- *z = 0;
- assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
-
- sqlite3VdbeMemRelease(pMem);
- pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
- pMem->enc = desiredEnc;
- pMem->flags |= (MEM_Term|MEM_Dyn);
- pMem->z = (char*)zOut;
- pMem->zMalloc = pMem->z;
-
-translate_out:
-#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
- {
- char zBuf[100];
- sqlite3VdbeMemPrettyPrint(pMem, zBuf);
- fprintf(stderr, "OUTPUT: %s\n", zBuf);
- }
-#endif
- return SQLITE_OK;
-}
-
-/*
-** This routine checks for a byte-order mark at the beginning of the
-** UTF-16 string stored in *pMem. If one is present, it is removed and
-** the encoding of the Mem adjusted. This routine does not do any
-** byte-swapping, it just sets Mem.enc appropriately.
-**
-** The allocation (static, dynamic etc.) and encoding of the Mem may be
-** changed by this function.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){
- int rc = SQLITE_OK;
- u8 bom = 0;
-
- assert( pMem->n>=0 );
- if( pMem->n>1 ){
- u8 b1 = *(u8 *)pMem->z;
- u8 b2 = *(((u8 *)pMem->z) + 1);
- if( b1==0xFE && b2==0xFF ){
- bom = SQLITE_UTF16BE;
- }
- if( b1==0xFF && b2==0xFE ){
- bom = SQLITE_UTF16LE;
- }
- }
-
- if( bom ){
- rc = sqlite3VdbeMemMakeWriteable(pMem);
- if( rc==SQLITE_OK ){
- pMem->n -= 2;
- memmove(pMem->z, &pMem->z[2], pMem->n);
- pMem->z[pMem->n] = '\0';
- pMem->z[pMem->n+1] = '\0';
- pMem->flags |= MEM_Term;
- pMem->enc = bom;
- }
- }
- return rc;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** pZ is a UTF-8 encoded unicode string. If nByte is less than zero,
-** return the number of unicode characters in pZ up to (but not including)
-** the first 0x00 byte. If nByte is not less than zero, return the
-** number of unicode characters in the first nByte of pZ (or up to
-** the first 0x00, whichever comes first).
-*/
-SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){
- int r = 0;
- const u8 *z = (const u8*)zIn;
- const u8 *zTerm;
- if( nByte>=0 ){
- zTerm = &z[nByte];
- }else{
- zTerm = (const u8*)(-1);
- }
- assert( z<=zTerm );
- while( *z!=0 && z<zTerm ){
- SQLITE_SKIP_UTF8(z);
- r++;
- }
- return r;
-}
-
-/* This test function is not currently used by the automated test-suite.
-** Hence it is only available in debug builds.
-*/
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-/*
-** Translate UTF-8 to UTF-8.
-**
-** This has the effect of making sure that the string is well-formed
-** UTF-8. Miscoded characters are removed.
-**
-** The translation is done in-place and aborted if the output
-** overruns the input.
-*/
-SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char *zIn){
- unsigned char *zOut = zIn;
- unsigned char *zStart = zIn;
- u32 c;
-
- while( zIn[0] && zOut<=zIn ){
- c = sqlite3Utf8Read((const u8**)&zIn);
- if( c!=0xfffd ){
- WRITE_UTF8(zOut, c);
- }
- }
- *zOut = 0;
- return (int)(zOut - zStart);
-}
-#endif
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Convert a UTF-16 string in the native encoding into a UTF-8 string.
-** Memory to hold the UTF-8 string is obtained from sqlite3_malloc and must
-** be freed by the calling function.
-**
-** NULL is returned if there is an allocation error.
-*/
-SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 enc){
- Mem m;
- memset(&m, 0, sizeof(m));
- m.db = db;
- sqlite3VdbeMemSetStr(&m, z, nByte, enc, SQLITE_STATIC);
- sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
- if( db->mallocFailed ){
- sqlite3VdbeMemRelease(&m);
- m.z = 0;
- }
- assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
- assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
- assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
- assert( m.z || db->mallocFailed );
- return m.z;
-}
-
-/*
-** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
-** enc. A pointer to the new string is returned, and the value of *pnOut
-** is set to the length of the returned string in bytes. The call should
-** arrange to call sqlite3DbFree() on the returned pointer when it is
-** no longer required.
-**
-** If a malloc failure occurs, NULL is returned and the db.mallocFailed
-** flag set.
-*/
-#ifdef SQLITE_ENABLE_STAT3
-SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
- Mem m;
- memset(&m, 0, sizeof(m));
- m.db = db;
- sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
- if( sqlite3VdbeMemTranslate(&m, enc) ){
- assert( db->mallocFailed );
- return 0;
- }
- assert( m.z==m.zMalloc );
- *pnOut = m.n;
- return m.z;
-}
-#endif
-
-/*
-** zIn is a UTF-16 encoded unicode string at least nChar characters long.
-** Return the number of bytes in the first nChar unicode characters
-** in pZ. nChar must be non-negative.
-*/
-SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){
- int c;
- unsigned char const *z = zIn;
- int n = 0;
-
- if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
- while( n<nChar ){
- READ_UTF16BE(z, 1, c);
- n++;
- }
- }else{
- while( n<nChar ){
- READ_UTF16LE(z, 1, c);
- n++;
- }
- }
- return (int)(z-(unsigned char const *)zIn);
-}
-
-#if defined(SQLITE_TEST)
-/*
-** This routine is called from the TCL test function "translate_selftest".
-** It checks that the primitives for serializing and deserializing
-** characters in each encoding are inverses of each other.
-*/
-SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
- unsigned int i, t;
- unsigned char zBuf[20];
- unsigned char *z;
- int n;
- unsigned int c;
-
- for(i=0; i<0x00110000; i++){
- z = zBuf;
- WRITE_UTF8(z, i);
- n = (int)(z-zBuf);
- assert( n>0 && n<=4 );
- z[0] = 0;
- z = zBuf;
- c = sqlite3Utf8Read((const u8**)&z);
- t = i;
- if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
- if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
- assert( c==t );
- assert( (z-zBuf)==n );
- }
- for(i=0; i<0x00110000; i++){
- if( i>=0xD800 && i<0xE000 ) continue;
- z = zBuf;
- WRITE_UTF16LE(z, i);
- n = (int)(z-zBuf);
- assert( n>0 && n<=4 );
- z[0] = 0;
- z = zBuf;
- READ_UTF16LE(z, 1, c);
- assert( c==i );
- assert( (z-zBuf)==n );
- }
- for(i=0; i<0x00110000; i++){
- if( i>=0xD800 && i<0xE000 ) continue;
- z = zBuf;
- WRITE_UTF16BE(z, i);
- n = (int)(z-zBuf);
- assert( n>0 && n<=4 );
- z[0] = 0;
- z = zBuf;
- READ_UTF16BE(z, 1, c);
- assert( c==i );
- assert( (z-zBuf)==n );
- }
-}
-#endif /* SQLITE_TEST */
-#endif /* SQLITE_OMIT_UTF16 */
-
-/************** End of utf.c *************************************************/
-/************** Begin file util.c ********************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** Utility functions used throughout sqlite.
-**
-** This file contains functions for allocating memory, comparing
-** strings, and stuff like that.
-**
-*/
-/* #include <stdarg.h> */
-#ifdef SQLITE_HAVE_ISNAN
-# include <math.h>
-#endif
-
-/*
-** Routine needed to support the testcase() macro.
-*/
-#ifdef SQLITE_COVERAGE_TEST
-SQLITE_PRIVATE void sqlite3Coverage(int x){
- static unsigned dummy = 0;
- dummy += (unsigned)x;
-}
-#endif
-
-#ifndef SQLITE_OMIT_FLOATING_POINT
-/*
-** Return true if the floating point value is Not a Number (NaN).
-**
-** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
-** Otherwise, we have our own implementation that works on most systems.
-*/
-SQLITE_PRIVATE int sqlite3IsNaN(double x){
- int rc; /* The value return */
-#if !defined(SQLITE_HAVE_ISNAN)
- /*
- ** Systems that support the isnan() library function should probably
- ** make use of it by compiling with -DSQLITE_HAVE_ISNAN. But we have
- ** found that many systems do not have a working isnan() function so
- ** this implementation is provided as an alternative.
- **
- ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
- ** On the other hand, the use of -ffast-math comes with the following
- ** warning:
- **
- ** This option [-ffast-math] should never be turned on by any
- ** -O option since it can result in incorrect output for programs
- ** which depend on an exact implementation of IEEE or ISO
- ** rules/specifications for math functions.
- **
- ** Under MSVC, this NaN test may fail if compiled with a floating-
- ** point precision mode other than /fp:precise. From the MSDN
- ** documentation:
- **
- ** The compiler [with /fp:precise] will properly handle comparisons
- ** involving NaN. For example, x != x evaluates to true if x is NaN
- ** ...
- */
-#ifdef __FAST_MATH__
-# error SQLite will not work correctly with the -ffast-math option of GCC.
-#endif
- volatile double y = x;
- volatile double z = y;
- rc = (y!=z);
-#else /* if defined(SQLITE_HAVE_ISNAN) */
- rc = isnan(x);
-#endif /* SQLITE_HAVE_ISNAN */
- testcase( rc );
- return rc;
-}
-#endif /* SQLITE_OMIT_FLOATING_POINT */
-
-/*
-** Compute a string length that is limited to what can be stored in
-** lower 30 bits of a 32-bit signed integer.
-**
-** The value returned will never be negative. Nor will it ever be greater
-** than the actual length of the string. For very long strings (greater
-** than 1GiB) the value returned might be less than the true string length.
-*/
-SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
- const char *z2 = z;
- if( z==0 ) return 0;
- while( *z2 ){ z2++; }
- return 0x3fffffff & (int)(z2 - z);
-}
-
-/*
-** Set the most recent error code and error string for the sqlite
-** handle "db". The error code is set to "err_code".
-**
-** If it is not NULL, string zFormat specifies the format of the
-** error string in the style of the printf functions: The following
-** format characters are allowed:
-**
-** %s Insert a string
-** %z A string that should be freed after use
-** %d Insert an integer
-** %T Insert a token
-** %S Insert the first element of a SrcList
-**
-** zFormat and any string tokens that follow it are assumed to be
-** encoded in UTF-8.
-**
-** To clear the most recent error for sqlite handle "db", sqlite3Error
-** should be called with err_code set to SQLITE_OK and zFormat set
-** to NULL.
-*/
-SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
- if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){
- db->errCode = err_code;
- if( zFormat ){
- char *z;
- va_list ap;
- va_start(ap, zFormat);
- z = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
- }else{
- sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
- }
- }
-}
-
-/*
-** Add an error message to pParse->zErrMsg and increment pParse->nErr.
-** The following formatting characters are allowed:
-**
-** %s Insert a string
-** %z A string that should be freed after use
-** %d Insert an integer
-** %T Insert a token
-** %S Insert the first element of a SrcList
-**
-** This function should be used to report any error that occurs whilst
-** compiling an SQL statement (i.e. within sqlite3_prepare()). The
-** last thing the sqlite3_prepare() function does is copy the error
-** stored by this function into the database handle using sqlite3Error().
-** Function sqlite3Error() should be used during statement execution
-** (sqlite3_step() etc.).
-*/
-SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
- char *zMsg;
- va_list ap;
- sqlite3 *db = pParse->db;
- va_start(ap, zFormat);
- zMsg = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- if( db->suppressErr ){
- sqlite3DbFree(db, zMsg);
- }else{
- pParse->nErr++;
- sqlite3DbFree(db, pParse->zErrMsg);
- pParse->zErrMsg = zMsg;
- pParse->rc = SQLITE_ERROR;
- }
-}
-
-/*
-** Convert an SQL-style quoted string into a normal string by removing
-** the quote characters. The conversion is done in-place. If the
-** input does not begin with a quote character, then this routine
-** is a no-op.
-**
-** The input string must be zero-terminated. A new zero-terminator
-** is added to the dequoted string.
-**
-** The return value is -1 if no dequoting occurs or the length of the
-** dequoted string, exclusive of the zero terminator, if dequoting does
-** occur.
-**
-** 2002-Feb-14: This routine is extended to remove MS-Access style
-** brackets from around identifers. For example: "[a-b-c]" becomes
-** "a-b-c".
-*/
-SQLITE_PRIVATE int sqlite3Dequote(char *z){
- char quote;
- int i, j;
- if( z==0 ) return -1;
- quote = z[0];
- switch( quote ){
- case '\'': break;
- case '"': break;
- case '`': break; /* For MySQL compatibility */
- case '[': quote = ']'; break; /* For MS SqlServer compatibility */
- default: return -1;
- }
- for(i=1, j=0; ALWAYS(z[i]); i++){
- if( z[i]==quote ){
- if( z[i+1]==quote ){
- z[j++] = quote;
- i++;
- }else{
- break;
- }
- }else{
- z[j++] = z[i];
- }
- }
- z[j] = 0;
- return j;
-}
-
-/* Convenient short-hand */
-#define UpperToLower sqlite3UpperToLower
-
-/*
-** Some systems have stricmp(). Others have strcasecmp(). Because
-** there is no consistency, we will define our own.
-**
-** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and
-** sqlite3_strnicmp() APIs allow applications and extensions to compare
-** the contents of two buffers containing UTF-8 strings in a
-** case-independent fashion, using the same definition of "case
-** independence" that SQLite uses internally when comparing identifiers.
-*/
-SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
- register unsigned char *a, *b;
- a = (unsigned char *)zLeft;
- b = (unsigned char *)zRight;
- while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
- return UpperToLower[*a] - UpperToLower[*b];
-}
-SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
- register unsigned char *a, *b;
- a = (unsigned char *)zLeft;
- b = (unsigned char *)zRight;
- while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
- return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
-}
-
-/*
-** The string z[] is an text representation of a real number.
-** Convert this string to a double and write it into *pResult.
-**
-** The string z[] is length bytes in length (bytes, not characters) and
-** uses the encoding enc. The string is not necessarily zero-terminated.
-**
-** Return TRUE if the result is a valid real number (or integer) and FALSE
-** if the string is empty or contains extraneous text. Valid numbers
-** are in one of these formats:
-**
-** [+-]digits[E[+-]digits]
-** [+-]digits.[digits][E[+-]digits]
-** [+-].digits[E[+-]digits]
-**
-** Leading and trailing whitespace is ignored for the purpose of determining
-** validity.
-**
-** If some prefix of the input string is a valid number, this routine
-** returns FALSE but it still converts the prefix and writes the result
-** into *pResult.
-*/
-SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
-#ifndef SQLITE_OMIT_FLOATING_POINT
- int incr = (enc==SQLITE_UTF8?1:2);
- const char *zEnd = z + length;
- /* sign * significand * (10 ^ (esign * exponent)) */
- int sign = 1; /* sign of significand */
- i64 s = 0; /* significand */
- int d = 0; /* adjust exponent for shifting decimal point */
- int esign = 1; /* sign of exponent */
- int e = 0; /* exponent */
- int eValid = 1; /* True exponent is either not used or is well-formed */
- double result;
- int nDigits = 0;
-
- *pResult = 0.0; /* Default return value, in case of an error */
-
- if( enc==SQLITE_UTF16BE ) z++;
-
- /* skip leading spaces */
- while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
- if( z>=zEnd ) return 0;
-
- /* get sign of significand */
- if( *z=='-' ){
- sign = -1;
- z+=incr;
- }else if( *z=='+' ){
- z+=incr;
- }
-
- /* skip leading zeroes */
- while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
-
- /* copy max significant digits to significand */
- while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
- s = s*10 + (*z - '0');
- z+=incr, nDigits++;
- }
-
- /* skip non-significant significand digits
- ** (increase exponent by d to shift decimal left) */
- while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++;
- if( z>=zEnd ) goto do_atof_calc;
-
- /* if decimal point is present */
- if( *z=='.' ){
- z+=incr;
- /* copy digits from after decimal to significand
- ** (decrease exponent by d to shift decimal right) */
- while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
- s = s*10 + (*z - '0');
- z+=incr, nDigits++, d--;
- }
- /* skip non-significant digits */
- while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
- }
- if( z>=zEnd ) goto do_atof_calc;
-
- /* if exponent is present */
- if( *z=='e' || *z=='E' ){
- z+=incr;
- eValid = 0;
- if( z>=zEnd ) goto do_atof_calc;
- /* get sign of exponent */
- if( *z=='-' ){
- esign = -1;
- z+=incr;
- }else if( *z=='+' ){
- z+=incr;
- }
- /* copy digits to exponent */
- while( z<zEnd && sqlite3Isdigit(*z) ){
- e = e<10000 ? (e*10 + (*z - '0')) : 10000;
- z+=incr;
- eValid = 1;
- }
- }
-
- /* skip trailing spaces */
- if( nDigits && eValid ){
- while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
- }
-
-do_atof_calc:
- /* adjust exponent by d, and update sign */
- e = (e*esign) + d;
- if( e<0 ) {
- esign = -1;
- e *= -1;
- } else {
- esign = 1;
- }
-
- /* if 0 significand */
- if( !s ) {
- /* In the IEEE 754 standard, zero is signed.
- ** Add the sign if we've seen at least one digit */
- result = (sign<0 && nDigits) ? -(double)0 : (double)0;
- } else {
- /* attempt to reduce exponent */
- if( esign>0 ){
- while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
- }else{
- while( !(s%10) && e>0 ) e--,s/=10;
- }
-
- /* adjust the sign of significand */
- s = sign<0 ? -s : s;
-
- /* if exponent, scale significand as appropriate
- ** and store in result. */
- if( e ){
- LONGDOUBLE_TYPE scale = 1.0;
- /* attempt to handle extremely small/large numbers better */
- if( e>307 && e<342 ){
- while( e%308 ) { scale *= 1.0e+1; e -= 1; }
- if( esign<0 ){
- result = s / scale;
- result /= 1.0e+308;
- }else{
- result = s * scale;
- result *= 1.0e+308;
- }
- }else if( e>=342 ){
- if( esign<0 ){
- result = 0.0*s;
- }else{
- result = 1e308*1e308*s; /* Infinity */
- }
- }else{
- /* 1.0e+22 is the largest power of 10 than can be
- ** represented exactly. */
- while( e%22 ) { scale *= 1.0e+1; e -= 1; }
- while( e>0 ) { scale *= 1.0e+22; e -= 22; }
- if( esign<0 ){
- result = s / scale;
- }else{
- result = s * scale;
- }
- }
- } else {
- result = (double)s;
- }
- }
-
- /* store the result */
- *pResult = result;
-
- /* return true if number and no extra non-whitespace chracters after */
- return z>=zEnd && nDigits>0 && eValid;
-#else
- return !sqlite3Atoi64(z, pResult, length, enc);
-#endif /* SQLITE_OMIT_FLOATING_POINT */
-}
-
-/*
-** Compare the 19-character string zNum against the text representation
-** value 2^63: 9223372036854775808. Return negative, zero, or positive
-** if zNum is less than, equal to, or greater than the string.
-** Note that zNum must contain exactly 19 characters.
-**
-** Unlike memcmp() this routine is guaranteed to return the difference
-** in the values of the last digit if the only difference is in the
-** last digit. So, for example,
-**
-** compare2pow63("9223372036854775800", 1)
-**
-** will return -8.
-*/
-static int compare2pow63(const char *zNum, int incr){
- int c = 0;
- int i;
- /* 012345678901234567 */
- const char *pow63 = "922337203685477580";
- for(i=0; c==0 && i<18; i++){
- c = (zNum[i*incr]-pow63[i])*10;
- }
- if( c==0 ){
- c = zNum[18*incr] - '8';
- testcase( c==(-1) );
- testcase( c==0 );
- testcase( c==(+1) );
- }
- return c;
-}
-
-
-/*
-** Convert zNum to a 64-bit signed integer.
-**
-** If the zNum value is representable as a 64-bit twos-complement
-** integer, then write that value into *pNum and return 0.
-**
-** If zNum is exactly 9223372036854665808, return 2. This special
-** case is broken out because while 9223372036854665808 cannot be a
-** signed 64-bit integer, its negative -9223372036854665808 can be.
-**
-** If zNum is too big for a 64-bit integer and is not
-** 9223372036854665808 then return 1.
-**
-** length is the number of bytes in the string (bytes, not characters).
-** The string is not necessarily zero-terminated. The encoding is
-** given by enc.
-*/
-SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
- int incr = (enc==SQLITE_UTF8?1:2);
- u64 u = 0;
- int neg = 0; /* assume positive */
- int i;
- int c = 0;
- const char *zStart;
- const char *zEnd = zNum + length;
- if( enc==SQLITE_UTF16BE ) zNum++;
- while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
- if( zNum<zEnd ){
- if( *zNum=='-' ){
- neg = 1;
- zNum+=incr;
- }else if( *zNum=='+' ){
- zNum+=incr;
- }
- }
- zStart = zNum;
- while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
- for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
- u = u*10 + c - '0';
- }
- if( u>LARGEST_INT64 ){
- *pNum = SMALLEST_INT64;
- }else if( neg ){
- *pNum = -(i64)u;
- }else{
- *pNum = (i64)u;
- }
- testcase( i==18 );
- testcase( i==19 );
- testcase( i==20 );
- if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
- /* zNum is empty or contains non-numeric text or is longer
- ** than 19 digits (thus guaranteeing that it is too large) */
- return 1;
- }else if( i<19*incr ){
- /* Less than 19 digits, so we know that it fits in 64 bits */
- assert( u<=LARGEST_INT64 );
- return 0;
- }else{
- /* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */
- c = compare2pow63(zNum, incr);
- if( c<0 ){
- /* zNum is less than 9223372036854775808 so it fits */
- assert( u<=LARGEST_INT64 );
- return 0;
- }else if( c>0 ){
- /* zNum is greater than 9223372036854775808 so it overflows */
- return 1;
- }else{
- /* zNum is exactly 9223372036854775808. Fits if negative. The
- ** special case 2 overflow if positive */
- assert( u-1==LARGEST_INT64 );
- assert( (*pNum)==SMALLEST_INT64 );
- return neg ? 0 : 2;
- }
- }
-}
-
-/*
-** If zNum represents an integer that will fit in 32-bits, then set
-** *pValue to that integer and return true. Otherwise return false.
-**
-** Any non-numeric characters that following zNum are ignored.
-** This is different from sqlite3Atoi64() which requires the
-** input number to be zero-terminated.
-*/
-SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
- sqlite_int64 v = 0;
- int i, c;
- int neg = 0;
- if( zNum[0]=='-' ){
- neg = 1;
- zNum++;
- }else if( zNum[0]=='+' ){
- zNum++;
- }
- while( zNum[0]=='0' ) zNum++;
- for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
- v = v*10 + c;
- }
-
- /* The longest decimal representation of a 32 bit integer is 10 digits:
- **
- ** 1234567890
- ** 2^31 -> 2147483648
- */
- testcase( i==10 );
- if( i>10 ){
- return 0;
- }
- testcase( v-neg==2147483647 );
- if( v-neg>2147483647 ){
- return 0;
- }
- if( neg ){
- v = -v;
- }
- *pValue = (int)v;
- return 1;
-}
-
-/*
-** Return a 32-bit integer value extracted from a string. If the
-** string is not an integer, just return 0.
-*/
-SQLITE_PRIVATE int sqlite3Atoi(const char *z){
- int x = 0;
- if( z ) sqlite3GetInt32(z, &x);
- return x;
-}
-
-/*
-** The variable-length integer encoding is as follows:
-**
-** KEY:
-** A = 0xxxxxxx 7 bits of data and one flag bit
-** B = 1xxxxxxx 7 bits of data and one flag bit
-** C = xxxxxxxx 8 bits of data
-**
-** 7 bits - A
-** 14 bits - BA
-** 21 bits - BBA
-** 28 bits - BBBA
-** 35 bits - BBBBA
-** 42 bits - BBBBBA
-** 49 bits - BBBBBBA
-** 56 bits - BBBBBBBA
-** 64 bits - BBBBBBBBC
-*/
-
-/*
-** Write a 64-bit variable-length integer to memory starting at p[0].
-** The length of data write will be between 1 and 9 bytes. The number
-** of bytes written is returned.
-**
-** A variable-length integer consists of the lower 7 bits of each byte
-** for all bytes that have the 8th bit set and one byte with the 8th
-** bit clear. Except, if we get to the 9th byte, it stores the full
-** 8 bits and is the last byte.
-*/
-SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
- int i, j, n;
- u8 buf[10];
- if( v & (((u64)0xff000000)<<32) ){
- p[8] = (u8)v;
- v >>= 8;
- for(i=7; i>=0; i--){
- p[i] = (u8)((v & 0x7f) | 0x80);
- v >>= 7;
- }
- return 9;
- }
- n = 0;
- do{
- buf[n++] = (u8)((v & 0x7f) | 0x80);
- v >>= 7;
- }while( v!=0 );
- buf[0] &= 0x7f;
- assert( n<=9 );
- for(i=0, j=n-1; j>=0; j--, i++){
- p[i] = buf[j];
- }
- return n;
-}
-
-/*
-** This routine is a faster version of sqlite3PutVarint() that only
-** works for 32-bit positive integers and which is optimized for
-** the common case of small integers. A MACRO version, putVarint32,
-** is provided which inlines the single-byte case. All code should use
-** the MACRO version as this function assumes the single-byte case has
-** already been handled.
-*/
-SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char *p, u32 v){
-#ifndef putVarint32
- if( (v & ~0x7f)==0 ){
- p[0] = v;
- return 1;
- }
-#endif
- if( (v & ~0x3fff)==0 ){
- p[0] = (u8)((v>>7) | 0x80);
- p[1] = (u8)(v & 0x7f);
- return 2;
- }
- return sqlite3PutVarint(p, v);
-}
-
-/*
-** Bitmasks used by sqlite3GetVarint(). These precomputed constants
-** are defined here rather than simply putting the constant expressions
-** inline in order to work around bugs in the RVT compiler.
-**
-** SLOT_2_0 A mask for (0x7f<<14) | 0x7f
-**
-** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0
-*/
-#define SLOT_2_0 0x001fc07f
-#define SLOT_4_2_0 0xf01fc07f
-
-
-/*
-** Read a 64-bit variable-length integer from memory starting at p[0].
-** Return the number of bytes read. The value is stored in *v.
-*/
-SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
- u32 a,b,s;
-
- a = *p;
- /* a: p0 (unmasked) */
- if (!(a&0x80))
- {
- *v = a;
- return 1;
- }
-
- p++;
- b = *p;
- /* b: p1 (unmasked) */
- if (!(b&0x80))
- {
- a &= 0x7f;
- a = a<<7;
- a |= b;
- *v = a;
- return 2;
- }
-
- /* Verify that constants are precomputed correctly */
- assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
- assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<14 | p2 (unmasked) */
- if (!(a&0x80))
- {
- a &= SLOT_2_0;
- b &= 0x7f;
- b = b<<7;
- a |= b;
- *v = a;
- return 3;
- }
-
- /* CSE1 from below */
- a &= SLOT_2_0;
- p++;
- b = b<<14;
- b |= *p;
- /* b: p1<<14 | p3 (unmasked) */
- if (!(b&0x80))
- {
- b &= SLOT_2_0;
- /* moved CSE1 up */
- /* a &= (0x7f<<14)|(0x7f); */
- a = a<<7;
- a |= b;
- *v = a;
- return 4;
- }
-
- /* a: p0<<14 | p2 (masked) */
- /* b: p1<<14 | p3 (unmasked) */
- /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
- /* moved CSE1 up */
- /* a &= (0x7f<<14)|(0x7f); */
- b &= SLOT_2_0;
- s = a;
- /* s: p0<<14 | p2 (masked) */
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<28 | p2<<14 | p4 (unmasked) */
- if (!(a&0x80))
- {
- /* we can skip these cause they were (effectively) done above in calc'ing s */
- /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
- /* b &= (0x7f<<14)|(0x7f); */
- b = b<<7;
- a |= b;
- s = s>>18;
- *v = ((u64)s)<<32 | a;
- return 5;
- }
-
- /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
- s = s<<7;
- s |= b;
- /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
-
- p++;
- b = b<<14;
- b |= *p;
- /* b: p1<<28 | p3<<14 | p5 (unmasked) */
- if (!(b&0x80))
- {
- /* we can skip this cause it was (effectively) done above in calc'ing s */
- /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
- a &= SLOT_2_0;
- a = a<<7;
- a |= b;
- s = s>>18;
- *v = ((u64)s)<<32 | a;
- return 6;
- }
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p2<<28 | p4<<14 | p6 (unmasked) */
- if (!(a&0x80))
- {
- a &= SLOT_4_2_0;
- b &= SLOT_2_0;
- b = b<<7;
- a |= b;
- s = s>>11;
- *v = ((u64)s)<<32 | a;
- return 7;
- }
-
- /* CSE2 from below */
- a &= SLOT_2_0;
- p++;
- b = b<<14;
- b |= *p;
- /* b: p3<<28 | p5<<14 | p7 (unmasked) */
- if (!(b&0x80))
- {
- b &= SLOT_4_2_0;
- /* moved CSE2 up */
- /* a &= (0x7f<<14)|(0x7f); */
- a = a<<7;
- a |= b;
- s = s>>4;
- *v = ((u64)s)<<32 | a;
- return 8;
- }
-
- p++;
- a = a<<15;
- a |= *p;
- /* a: p4<<29 | p6<<15 | p8 (unmasked) */
-
- /* moved CSE2 up */
- /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
- b &= SLOT_2_0;
- b = b<<8;
- a |= b;
-
- s = s<<4;
- b = p[-4];
- b &= 0x7f;
- b = b>>3;
- s |= b;
-
- *v = ((u64)s)<<32 | a;
-
- return 9;
-}
-
-/*
-** Read a 32-bit variable-length integer from memory starting at p[0].
-** Return the number of bytes read. The value is stored in *v.
-**
-** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
-** integer, then set *v to 0xffffffff.
-**
-** A MACRO version, getVarint32, is provided which inlines the
-** single-byte case. All code should use the MACRO version as
-** this function assumes the single-byte case has already been handled.
-*/
-SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
- u32 a,b;
-
- /* The 1-byte case. Overwhelmingly the most common. Handled inline
- ** by the getVarin32() macro */
- a = *p;
- /* a: p0 (unmasked) */
-#ifndef getVarint32
- if (!(a&0x80))
- {
- /* Values between 0 and 127 */
- *v = a;
- return 1;
- }
-#endif
-
- /* The 2-byte case */
- p++;
- b = *p;
- /* b: p1 (unmasked) */
- if (!(b&0x80))
- {
- /* Values between 128 and 16383 */
- a &= 0x7f;
- a = a<<7;
- *v = a | b;
- return 2;
- }
-
- /* The 3-byte case */
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<14 | p2 (unmasked) */
- if (!(a&0x80))
- {
- /* Values between 16384 and 2097151 */
- a &= (0x7f<<14)|(0x7f);
- b &= 0x7f;
- b = b<<7;
- *v = a | b;
- return 3;
- }
-
- /* A 32-bit varint is used to store size information in btrees.
- ** Objects are rarely larger than 2MiB limit of a 3-byte varint.
- ** A 3-byte varint is sufficient, for example, to record the size
- ** of a 1048569-byte BLOB or string.
- **
- ** We only unroll the first 1-, 2-, and 3- byte cases. The very
- ** rare larger cases can be handled by the slower 64-bit varint
- ** routine.
- */
-#if 1
- {
- u64 v64;
- u8 n;
-
- p -= 2;
- n = sqlite3GetVarint(p, &v64);
- assert( n>3 && n<=9 );
- if( (v64 & SQLITE_MAX_U32)!=v64 ){
- *v = 0xffffffff;
- }else{
- *v = (u32)v64;
- }
- return n;
- }
-
-#else
- /* For following code (kept for historical record only) shows an
- ** unrolling for the 3- and 4-byte varint cases. This code is
- ** slightly faster, but it is also larger and much harder to test.
- */
- p++;
- b = b<<14;
- b |= *p;
- /* b: p1<<14 | p3 (unmasked) */
- if (!(b&0x80))
- {
- /* Values between 2097152 and 268435455 */
- b &= (0x7f<<14)|(0x7f);
- a &= (0x7f<<14)|(0x7f);
- a = a<<7;
- *v = a | b;
- return 4;
- }
-
- p++;
- a = a<<14;
- a |= *p;
- /* a: p0<<28 | p2<<14 | p4 (unmasked) */
- if (!(a&0x80))
- {
- /* Values between 268435456 and 34359738367 */
- a &= SLOT_4_2_0;
- b &= SLOT_4_2_0;
- b = b<<7;
- *v = a | b;
- return 5;
- }
-
- /* We can only reach this point when reading a corrupt database
- ** file. In that case we are not in any hurry. Use the (relatively
- ** slow) general-purpose sqlite3GetVarint() routine to extract the
- ** value. */
- {
- u64 v64;
- u8 n;
-
- p -= 4;
- n = sqlite3GetVarint(p, &v64);
- assert( n>5 && n<=9 );
- *v = (u32)v64;
- return n;
- }
-#endif
-}
-
-/*
-** Return the number of bytes that will be needed to store the given
-** 64-bit integer.
-*/
-SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
- int i = 0;
- do{
- i++;
- v >>= 7;
- }while( v!=0 && ALWAYS(i<9) );
- return i;
-}
-
-
-/*
-** Read or write a four-byte big-endian integer value.
-*/
-SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
- return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
-}
-SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
- p[0] = (u8)(v>>24);
- p[1] = (u8)(v>>16);
- p[2] = (u8)(v>>8);
- p[3] = (u8)v;
-}
-
-
-
-/*
-** Translate a single byte of Hex into an integer.
-** This routine only works if h really is a valid hexadecimal
-** character: 0..9a..fA..F
-*/
-SQLITE_PRIVATE u8 sqlite3HexToInt(int h){
- assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') );
-#ifdef SQLITE_ASCII
- h += 9*(1&(h>>6));
-#endif
-#ifdef SQLITE_EBCDIC
- h += 9*(1&~(h>>4));
-#endif
- return (u8)(h & 0xf);
-}
-
-#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
-/*
-** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
-** value. Return a pointer to its binary value. Space to hold the
-** binary value has been obtained from malloc and must be freed by
-** the calling routine.
-*/
-SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
- char *zBlob;
- int i;
-
- zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1);
- n--;
- if( zBlob ){
- for(i=0; i<n; i+=2){
- zBlob[i/2] = (sqlite3HexToInt(z[i])<<4) | sqlite3HexToInt(z[i+1]);
- }
- zBlob[i/2] = 0;
- }
- return zBlob;
-}
-#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
-
-/*
-** Log an error that is an API call on a connection pointer that should
-** not have been used. The "type" of connection pointer is given as the
-** argument. The zType is a word like "NULL" or "closed" or "invalid".
-*/
-static void logBadConnection(const char *zType){
- sqlite3_log(SQLITE_MISUSE,
- "API call with %s database connection pointer",
- zType
- );
-}
-
-/*
-** Check to make sure we have a valid db pointer. This test is not
-** foolproof but it does provide some measure of protection against
-** misuse of the interface such as passing in db pointers that are
-** NULL or which have been previously closed. If this routine returns
-** 1 it means that the db pointer is valid and 0 if it should not be
-** dereferenced for any reason. The calling function should invoke
-** SQLITE_MISUSE immediately.
-**
-** sqlite3SafetyCheckOk() requires that the db pointer be valid for
-** use. sqlite3SafetyCheckSickOrOk() allows a db pointer that failed to
-** open properly and is not fit for general use but which can be
-** used as an argument to sqlite3_errmsg() or sqlite3_close().
-*/
-SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3 *db){
- u32 magic;
- if( db==0 ){
- logBadConnection("NULL");
- return 0;
- }
- magic = db->magic;
- if( magic!=SQLITE_MAGIC_OPEN ){
- if( sqlite3SafetyCheckSickOrOk(db) ){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- logBadConnection("unopened");
- }
- return 0;
- }else{
- return 1;
- }
-}
-SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
- u32 magic;
- magic = db->magic;
- if( magic!=SQLITE_MAGIC_SICK &&
- magic!=SQLITE_MAGIC_OPEN &&
- magic!=SQLITE_MAGIC_BUSY ){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- logBadConnection("invalid");
- return 0;
- }else{
- return 1;
- }
-}
-
-/*
-** Attempt to add, substract, or multiply the 64-bit signed value iB against
-** the other 64-bit signed integer at *pA and store the result in *pA.
-** Return 0 on success. Or if the operation would have resulted in an
-** overflow, leave *pA unchanged and return 1.
-*/
-SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
- i64 iA = *pA;
- testcase( iA==0 ); testcase( iA==1 );
- testcase( iB==-1 ); testcase( iB==0 );
- if( iB>=0 ){
- testcase( iA>0 && LARGEST_INT64 - iA == iB );
- testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 );
- if( iA>0 && LARGEST_INT64 - iA < iB ) return 1;
- *pA += iB;
- }else{
- testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 );
- testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 );
- if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1;
- *pA += iB;
- }
- return 0;
-}
-SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
- testcase( iB==SMALLEST_INT64+1 );
- if( iB==SMALLEST_INT64 ){
- testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
- if( (*pA)>=0 ) return 1;
- *pA -= iB;
- return 0;
- }else{
- return sqlite3AddInt64(pA, -iB);
- }
-}
-#define TWOPOWER32 (((i64)1)<<32)
-#define TWOPOWER31 (((i64)1)<<31)
-SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
- i64 iA = *pA;
- i64 iA1, iA0, iB1, iB0, r;
-
- iA1 = iA/TWOPOWER32;
- iA0 = iA % TWOPOWER32;
- iB1 = iB/TWOPOWER32;
- iB0 = iB % TWOPOWER32;
- if( iA1*iB1 != 0 ) return 1;
- assert( iA1*iB0==0 || iA0*iB1==0 );
- r = iA1*iB0 + iA0*iB1;
- testcase( r==(-TWOPOWER31)-1 );
- testcase( r==(-TWOPOWER31) );
- testcase( r==TWOPOWER31 );
- testcase( r==TWOPOWER31-1 );
- if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
- r *= TWOPOWER32;
- if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;
- *pA = r;
- return 0;
-}
-
-/*
-** Compute the absolute value of a 32-bit signed integer, of possible. Or
-** if the integer has a value of -2147483648, return +2147483647
-*/
-SQLITE_PRIVATE int sqlite3AbsInt32(int x){
- if( x>=0 ) return x;
- if( x==(int)0x80000000 ) return 0x7fffffff;
- return -x;
-}
-
-#ifdef SQLITE_ENABLE_8_3_NAMES
-/*
-** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database
-** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
-** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
-** three characters, then shorten the suffix on z[] to be the last three
-** characters of the original suffix.
-**
-** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
-** do the suffix shortening regardless of URI parameter.
-**
-** Examples:
-**
-** test.db-journal => test.nal
-** test.db-wal => test.wal
-** test.db-shm => test.shm
-** test.db-mj7f3319fa => test.9fa
-*/
-SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
-#if SQLITE_ENABLE_8_3_NAMES<2
- if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) )
-#endif
- {
- int i, sz;
- sz = sqlite3Strlen30(z);
- for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
- if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
- }
-}
-#endif
-
-/************** End of util.c ************************************************/
-/************** Begin file hash.c ********************************************/
-/*
-** 2001 September 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This is the implementation of generic hash-tables
-** used in SQLite.
-*/
-/* #include <assert.h> */
-
-/* Turn bulk memory into a hash table object by initializing the
-** fields of the Hash structure.
-**
-** "pNew" is a pointer to the hash table that is to be initialized.
-*/
-SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){
- assert( pNew!=0 );
- pNew->first = 0;
- pNew->count = 0;
- pNew->htsize = 0;
- pNew->ht = 0;
-}
-
-/* Remove all entries from a hash table. Reclaim all memory.
-** Call this routine to delete a hash table or to reset a hash table
-** to the empty state.
-*/
-SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){
- HashElem *elem; /* For looping over all elements of the table */
-
- assert( pH!=0 );
- elem = pH->first;
- pH->first = 0;
- sqlite3_free(pH->ht);
- pH->ht = 0;
- pH->htsize = 0;
- while( elem ){
- HashElem *next_elem = elem->next;
- sqlite3_free(elem);
- elem = next_elem;
- }
- pH->count = 0;
-}
-
-/*
-** The hashing function.
-*/
-static unsigned int strHash(const char *z, int nKey){
- int h = 0;
- assert( nKey>=0 );
- while( nKey > 0 ){
- h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
- nKey--;
- }
- return h;
-}
-
-
-/* Link pNew element into the hash table pH. If pEntry!=0 then also
-** insert pNew into the pEntry hash bucket.
-*/
-static void insertElement(
- Hash *pH, /* The complete hash table */
- struct _ht *pEntry, /* The entry into which pNew is inserted */
- HashElem *pNew /* The element to be inserted */
-){
- HashElem *pHead; /* First element already in pEntry */
- if( pEntry ){
- pHead = pEntry->count ? pEntry->chain : 0;
- pEntry->count++;
- pEntry->chain = pNew;
- }else{
- pHead = 0;
- }
- if( pHead ){
- pNew->next = pHead;
- pNew->prev = pHead->prev;
- if( pHead->prev ){ pHead->prev->next = pNew; }
- else { pH->first = pNew; }
- pHead->prev = pNew;
- }else{
- pNew->next = pH->first;
- if( pH->first ){ pH->first->prev = pNew; }
- pNew->prev = 0;
- pH->first = pNew;
- }
-}
-
-
-/* Resize the hash table so that it cantains "new_size" buckets.
-**
-** The hash table might fail to resize if sqlite3_malloc() fails or
-** if the new size is the same as the prior size.
-** Return TRUE if the resize occurs and false if not.
-*/
-static int rehash(Hash *pH, unsigned int new_size){
- struct _ht *new_ht; /* The new hash table */
- HashElem *elem, *next_elem; /* For looping over existing elements */
-
-#if SQLITE_MALLOC_SOFT_LIMIT>0
- if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){
- new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht);
- }
- if( new_size==pH->htsize ) return 0;
-#endif
-
- /* The inability to allocates space for a larger hash table is
- ** a performance hit but it is not a fatal error. So mark the
- ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of
- ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero()
- ** only zeroes the requested number of bytes whereas this module will
- ** use the actual amount of space allocated for the hash table (which
- ** may be larger than the requested amount).
- */
- sqlite3BeginBenignMalloc();
- new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );
- sqlite3EndBenignMalloc();
-
- if( new_ht==0 ) return 0;
- sqlite3_free(pH->ht);
- pH->ht = new_ht;
- pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
- memset(new_ht, 0, new_size*sizeof(struct _ht));
- for(elem=pH->first, pH->first=0; elem; elem = next_elem){
- unsigned int h = strHash(elem->pKey, elem->nKey) % new_size;
- next_elem = elem->next;
- insertElement(pH, &new_ht[h], elem);
- }
- return 1;
-}
-
-/* This function (for internal use only) locates an element in an
-** hash table that matches the given key. The hash for this key has
-** already been computed and is passed as the 4th parameter.
-*/
-static HashElem *findElementGivenHash(
- const Hash *pH, /* The pH to be searched */
- const char *pKey, /* The key we are searching for */
- int nKey, /* Bytes in key (not counting zero terminator) */
- unsigned int h /* The hash for this key. */
-){
- HashElem *elem; /* Used to loop thru the element list */
- int count; /* Number of elements left to test */
-
- if( pH->ht ){
- struct _ht *pEntry = &pH->ht[h];
- elem = pEntry->chain;
- count = pEntry->count;
- }else{
- elem = pH->first;
- count = pH->count;
- }
- while( count-- && ALWAYS(elem) ){
- if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
- return elem;
- }
- elem = elem->next;
- }
- return 0;
-}
-
-/* Remove a single entry from the hash table given a pointer to that
-** element and a hash on the element's key.
-*/
-static void removeElementGivenHash(
- Hash *pH, /* The pH containing "elem" */
- HashElem* elem, /* The element to be removed from the pH */
- unsigned int h /* Hash value for the element */
-){
- struct _ht *pEntry;
- if( elem->prev ){
- elem->prev->next = elem->next;
- }else{
- pH->first = elem->next;
- }
- if( elem->next ){
- elem->next->prev = elem->prev;
- }
- if( pH->ht ){
- pEntry = &pH->ht[h];
- if( pEntry->chain==elem ){
- pEntry->chain = elem->next;
- }
- pEntry->count--;
- assert( pEntry->count>=0 );
- }
- sqlite3_free( elem );
- pH->count--;
- if( pH->count==0 ){
- assert( pH->first==0 );
- assert( pH->count==0 );
- sqlite3HashClear(pH);
- }
-}
-
-/* Attempt to locate an element of the hash table pH with a key
-** that matches pKey,nKey. Return the data for this element if it is
-** found, or NULL if there is no match.
-*/
-SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){
- HashElem *elem; /* The element that matches key */
- unsigned int h; /* A hash on key */
-
- assert( pH!=0 );
- assert( pKey!=0 );
- assert( nKey>=0 );
- if( pH->ht ){
- h = strHash(pKey, nKey) % pH->htsize;
- }else{
- h = 0;
- }
- elem = findElementGivenHash(pH, pKey, nKey, h);
- return elem ? elem->data : 0;
-}
-
-/* Insert an element into the hash table pH. The key is pKey,nKey
-** and the data is "data".
-**
-** If no element exists with a matching key, then a new
-** element is created and NULL is returned.
-**
-** If another element already exists with the same key, then the
-** new data replaces the old data and the old data is returned.
-** The key is not copied in this instance. If a malloc fails, then
-** the new data is returned and the hash table is unchanged.
-**
-** If the "data" parameter to this function is NULL, then the
-** element corresponding to "key" is removed from the hash table.
-*/
-SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, void *data){
- unsigned int h; /* the hash of the key modulo hash table size */
- HashElem *elem; /* Used to loop thru the element list */
- HashElem *new_elem; /* New element added to the pH */
-
- assert( pH!=0 );
- assert( pKey!=0 );
- assert( nKey>=0 );
- if( pH->htsize ){
- h = strHash(pKey, nKey) % pH->htsize;
- }else{
- h = 0;
- }
- elem = findElementGivenHash(pH,pKey,nKey,h);
- if( elem ){
- void *old_data = elem->data;
- if( data==0 ){
- removeElementGivenHash(pH,elem,h);
- }else{
- elem->data = data;
- elem->pKey = pKey;
- assert(nKey==elem->nKey);
- }
- return old_data;
- }
- if( data==0 ) return 0;
- new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) );
- if( new_elem==0 ) return data;
- new_elem->pKey = pKey;
- new_elem->nKey = nKey;
- new_elem->data = data;
- pH->count++;
- if( pH->count>=10 && pH->count > 2*pH->htsize ){
- if( rehash(pH, pH->count*2) ){
- assert( pH->htsize>0 );
- h = strHash(pKey, nKey) % pH->htsize;
- }
- }
- if( pH->ht ){
- insertElement(pH, &pH->ht[h], new_elem);
- }else{
- insertElement(pH, 0, new_elem);
- }
- return 0;
-}
-
-/************** End of hash.c ************************************************/
-/************** Begin file opcodes.c *****************************************/
-/* Automatically generated. Do not edit */
-/* See the mkopcodec.awk script for details. */
-#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
-SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
- static const char *const azName[] = { "?",
- /* 1 */ "Goto",
- /* 2 */ "Gosub",
- /* 3 */ "Return",
- /* 4 */ "Yield",
- /* 5 */ "HaltIfNull",
- /* 6 */ "Halt",
- /* 7 */ "Integer",
- /* 8 */ "Int64",
- /* 9 */ "String",
- /* 10 */ "Null",
- /* 11 */ "Blob",
- /* 12 */ "Variable",
- /* 13 */ "Move",
- /* 14 */ "Copy",
- /* 15 */ "SCopy",
- /* 16 */ "ResultRow",
- /* 17 */ "CollSeq",
- /* 18 */ "Function",
- /* 19 */ "Not",
- /* 20 */ "AddImm",
- /* 21 */ "MustBeInt",
- /* 22 */ "RealAffinity",
- /* 23 */ "Permutation",
- /* 24 */ "Compare",
- /* 25 */ "Jump",
- /* 26 */ "Once",
- /* 27 */ "If",
- /* 28 */ "IfNot",
- /* 29 */ "Column",
- /* 30 */ "Affinity",
- /* 31 */ "MakeRecord",
- /* 32 */ "Count",
- /* 33 */ "Savepoint",
- /* 34 */ "AutoCommit",
- /* 35 */ "Transaction",
- /* 36 */ "ReadCookie",
- /* 37 */ "SetCookie",
- /* 38 */ "VerifyCookie",
- /* 39 */ "OpenRead",
- /* 40 */ "OpenWrite",
- /* 41 */ "OpenAutoindex",
- /* 42 */ "OpenEphemeral",
- /* 43 */ "SorterOpen",
- /* 44 */ "OpenPseudo",
- /* 45 */ "Close",
- /* 46 */ "SeekLt",
- /* 47 */ "SeekLe",
- /* 48 */ "SeekGe",
- /* 49 */ "SeekGt",
- /* 50 */ "Seek",
- /* 51 */ "NotFound",
- /* 52 */ "Found",
- /* 53 */ "IsUnique",
- /* 54 */ "NotExists",
- /* 55 */ "Sequence",
- /* 56 */ "NewRowid",
- /* 57 */ "Insert",
- /* 58 */ "InsertInt",
- /* 59 */ "Delete",
- /* 60 */ "ResetCount",
- /* 61 */ "SorterCompare",
- /* 62 */ "SorterData",
- /* 63 */ "RowKey",
- /* 64 */ "RowData",
- /* 65 */ "Rowid",
- /* 66 */ "NullRow",
- /* 67 */ "Last",
- /* 68 */ "Or",
- /* 69 */ "And",
- /* 70 */ "SorterSort",
- /* 71 */ "Sort",
- /* 72 */ "Rewind",
- /* 73 */ "IsNull",
- /* 74 */ "NotNull",
- /* 75 */ "Ne",
- /* 76 */ "Eq",
- /* 77 */ "Gt",
- /* 78 */ "Le",
- /* 79 */ "Lt",
- /* 80 */ "Ge",
- /* 81 */ "SorterNext",
- /* 82 */ "BitAnd",
- /* 83 */ "BitOr",
- /* 84 */ "ShiftLeft",
- /* 85 */ "ShiftRight",
- /* 86 */ "Add",
- /* 87 */ "Subtract",
- /* 88 */ "Multiply",
- /* 89 */ "Divide",
- /* 90 */ "Remainder",
- /* 91 */ "Concat",
- /* 92 */ "Prev",
- /* 93 */ "BitNot",
- /* 94 */ "String8",
- /* 95 */ "Next",
- /* 96 */ "SorterInsert",
- /* 97 */ "IdxInsert",
- /* 98 */ "IdxDelete",
- /* 99 */ "IdxRowid",
- /* 100 */ "IdxLT",
- /* 101 */ "IdxGE",
- /* 102 */ "Destroy",
- /* 103 */ "Clear",
- /* 104 */ "CreateIndex",
- /* 105 */ "CreateTable",
- /* 106 */ "ParseSchema",
- /* 107 */ "LoadAnalysis",
- /* 108 */ "DropTable",
- /* 109 */ "DropIndex",
- /* 110 */ "DropTrigger",
- /* 111 */ "IntegrityCk",
- /* 112 */ "RowSetAdd",
- /* 113 */ "RowSetRead",
- /* 114 */ "RowSetTest",
- /* 115 */ "Program",
- /* 116 */ "Param",
- /* 117 */ "FkCounter",
- /* 118 */ "FkIfZero",
- /* 119 */ "MemMax",
- /* 120 */ "IfPos",
- /* 121 */ "IfNeg",
- /* 122 */ "IfZero",
- /* 123 */ "AggStep",
- /* 124 */ "AggFinal",
- /* 125 */ "Checkpoint",
- /* 126 */ "JournalMode",
- /* 127 */ "Vacuum",
- /* 128 */ "IncrVacuum",
- /* 129 */ "Expire",
- /* 130 */ "Real",
- /* 131 */ "TableLock",
- /* 132 */ "VBegin",
- /* 133 */ "VCreate",
- /* 134 */ "VDestroy",
- /* 135 */ "VOpen",
- /* 136 */ "VFilter",
- /* 137 */ "VColumn",
- /* 138 */ "VNext",
- /* 139 */ "VRename",
- /* 140 */ "VUpdate",
- /* 141 */ "ToText",
- /* 142 */ "ToBlob",
- /* 143 */ "ToNumeric",
- /* 144 */ "ToInt",
- /* 145 */ "ToReal",
- /* 146 */ "Pagecount",
- /* 147 */ "MaxPgcnt",
- /* 148 */ "Trace",
- /* 149 */ "Noop",
- /* 150 */ "Explain",
- };
- return azName[i];
-}
-#endif
-
-/************** End of opcodes.c *********************************************/
-/************** Begin file os_unix.c *****************************************/
-/*
-** 2004 May 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains the VFS implementation for unix-like operating systems
-** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others.
-**
-** There are actually several different VFS implementations in this file.
-** The differences are in the way that file locking is done. The default
-** implementation uses Posix Advisory Locks. Alternative implementations
-** use flock(), dot-files, various proprietary locking schemas, or simply
-** skip locking all together.
-**
-** This source file is organized into divisions where the logic for various
-** subfunctions is contained within the appropriate division. PLEASE
-** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed
-** in the correct division and should be clearly labeled.
-**
-** The layout of divisions is as follows:
-**
-** * General-purpose declarations and utility functions.
-** * Unique file ID logic used by VxWorks.
-** * Various locking primitive implementations (all except proxy locking):
-** + for Posix Advisory Locks
-** + for no-op locks
-** + for dot-file locks
-** + for flock() locking
-** + for named semaphore locks (VxWorks only)
-** + for AFP filesystem locks (MacOSX only)
-** * sqlite3_file methods not associated with locking.
-** * Definitions of sqlite3_io_methods objects for all locking
-** methods plus "finder" functions for each locking method.
-** * sqlite3_vfs method implementations.
-** * Locking primitives for the proxy uber-locking-method. (MacOSX only)
-** * Definitions of sqlite3_vfs objects for all locking methods
-** plus implementations of sqlite3_os_init() and sqlite3_os_end().
-*/
-#if SQLITE_OS_UNIX /* This file is used on unix only */
-
-/* Use posix_fallocate() if it is available
-*/
-#if !defined(HAVE_POSIX_FALLOCATE) \
- && (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L)
-# define HAVE_POSIX_FALLOCATE 1
-#endif
-
-/*
-** There are various methods for file locking used for concurrency
-** control:
-**
-** 1. POSIX locking (the default),
-** 2. No locking,
-** 3. Dot-file locking,
-** 4. flock() locking,
-** 5. AFP locking (OSX only),
-** 6. Named POSIX semaphores (VXWorks only),
-** 7. proxy locking. (OSX only)
-**
-** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE
-** is defined to 1. The SQLITE_ENABLE_LOCKING_STYLE also enables automatic
-** selection of the appropriate locking style based on the filesystem
-** where the database is located.
-*/
-#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
-# if defined(__APPLE__)
-# define SQLITE_ENABLE_LOCKING_STYLE 1
-# else
-# define SQLITE_ENABLE_LOCKING_STYLE 0
-# endif
-#endif
-
-/*
-** Define the OS_VXWORKS pre-processor macro to 1 if building on
-** vxworks, or 0 otherwise.
-*/
-#ifndef OS_VXWORKS
-# if defined(__RTP__) || defined(_WRS_KERNEL)
-# define OS_VXWORKS 1
-# else
-# define OS_VXWORKS 0
-# endif
-#endif
-
-/*
-** These #defines should enable >2GB file support on Posix if the
-** underlying operating system supports it. If the OS lacks
-** large file support, these should be no-ops.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line. This is necessary if you are compiling
-** on a recent machine (ex: RedHat 7.2) but you want your code to work
-** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2
-** without this option, LFS is enable. But LFS does not exist in the kernel
-** in RedHat 6.0, so the code won't work. Hence, for maximum binary
-** portability you should omit LFS.
-**
-** The previous paragraph was written in 2005. (This paragraph is written
-** on 2008-11-28.) These days, all Linux kernels support large files, so
-** you should probably leave LFS enabled. But some embedded platforms might
-** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE 1
-# ifndef _FILE_OFFSET_BITS
-# define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-/*
-** standard include files.
-*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-/* #include <time.h> */
-#include <sys/time.h>
-#include <errno.h>
-#ifndef SQLITE_OMIT_WAL
-#include <sys/mman.h>
-#endif
-
-
-#if SQLITE_ENABLE_LOCKING_STYLE
-# include <sys/ioctl.h>
-# if OS_VXWORKS
-# include <semaphore.h>
-# include <limits.h>
-# else
-# include <sys/file.h>
-# include <sys/param.h>
-# endif
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-
-#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
-# include <sys/mount.h>
-#endif
-
-#ifdef HAVE_UTIME
-# include <utime.h>
-#endif
-
-/*
-** Allowed values of unixFile.fsFlags
-*/
-#define SQLITE_FSFLAGS_IS_MSDOS 0x1
-
-/*
-** If we are to be thread-safe, include the pthreads header and define
-** the SQLITE_UNIX_THREADS macro.
-*/
-#if SQLITE_THREADSAFE
-/* # include <pthread.h> */
-# define SQLITE_UNIX_THREADS 1
-#endif
-
-/*
-** Default permissions when creating a new file
-*/
-#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
-# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
-#endif
-
-/*
-** Default permissions when creating auto proxy dir
-*/
-#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
-# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755
-#endif
-
-/*
-** Maximum supported path-length.
-*/
-#define MAX_PATHNAME 512
-
-/*
-** Only set the lastErrno if the error code is a real error and not
-** a normal expected return code of SQLITE_BUSY or SQLITE_OK
-*/
-#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY))
-
-/* Forward references */
-typedef struct unixShm unixShm; /* Connection shared memory */
-typedef struct unixShmNode unixShmNode; /* Shared memory instance */
-typedef struct unixInodeInfo unixInodeInfo; /* An i-node */
-typedef struct UnixUnusedFd UnixUnusedFd; /* An unused file descriptor */
-
-/*
-** Sometimes, after a file handle is closed by SQLite, the file descriptor
-** cannot be closed immediately. In these cases, instances of the following
-** structure are used to store the file descriptor while waiting for an
-** opportunity to either close or reuse it.
-*/
-struct UnixUnusedFd {
- int fd; /* File descriptor to close */
- int flags; /* Flags this file descriptor was opened with */
- UnixUnusedFd *pNext; /* Next unused file descriptor on same file */
-};
-
-/*
-** The unixFile structure is subclass of sqlite3_file specific to the unix
-** VFS implementations.
-*/
-typedef struct unixFile unixFile;
-struct unixFile {
- sqlite3_io_methods const *pMethod; /* Always the first entry */
- sqlite3_vfs *pVfs; /* The VFS that created this unixFile */
- unixInodeInfo *pInode; /* Info about locks on this inode */
- int h; /* The file descriptor */
- unsigned char eFileLock; /* The type of lock held on this fd */
- unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */
- int lastErrno; /* The unix errno from last I/O error */
- void *lockingContext; /* Locking style specific state */
- UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */
- const char *zPath; /* Name of the file */
- unixShm *pShm; /* Shared memory segment information */
- int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
-#ifdef __QNXNTO__
- int sectorSize; /* Device sector size */
- int deviceCharacteristics; /* Precomputed device characteristics */
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE
- int openFlags; /* The flags specified at open() */
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
- unsigned fsFlags; /* cached details from statfs() */
-#endif
-#if OS_VXWORKS
- struct vxworksFileId *pId; /* Unique file ID */
-#endif
-#ifdef SQLITE_DEBUG
- /* The next group of variables are used to track whether or not the
- ** transaction counter in bytes 24-27 of database files are updated
- ** whenever any part of the database changes. An assertion fault will
- ** occur if a file is updated without also updating the transaction
- ** counter. This test is made to avoid new problems similar to the
- ** one described by ticket #3584.
- */
- unsigned char transCntrChng; /* True if the transaction counter changed */
- unsigned char dbUpdate; /* True if any part of database file changed */
- unsigned char inNormalWrite; /* True if in a normal write operation */
-#endif
-#ifdef SQLITE_TEST
- /* In test mode, increase the size of this structure a bit so that
- ** it is larger than the struct CrashFile defined in test6.c.
- */
- char aPadding[32];
-#endif
-};
-
-/*
-** Allowed values for the unixFile.ctrlFlags bitmask:
-*/
-#define UNIXFILE_EXCL 0x01 /* Connections from one process only */
-#define UNIXFILE_RDONLY 0x02 /* Connection is read only */
-#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
-#ifndef SQLITE_DISABLE_DIRSYNC
-# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */
-#else
-# define UNIXFILE_DIRSYNC 0x00
-#endif
-#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
-#define UNIXFILE_DELETE 0x20 /* Delete on close */
-#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
-#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
-
-/*
-** Include code that is common to all os_*.c files
-*/
-/************** Include os_common.h in the middle of os_unix.c ***************/
-/************** Begin file os_common.h ***************************************/
-/*
-** 2004 May 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains macros and a little bit of code that is common to
-** all of the platform-specific files (os_*.c) and is #included into those
-** files.
-**
-** This file should be #included by the os_*.c files only. It is not a
-** general purpose header file.
-*/
-#ifndef _OS_COMMON_H_
-#define _OS_COMMON_H_
-
-/*
-** At least two bugs have slipped in because we changed the MEMORY_DEBUG
-** macro to SQLITE_DEBUG and some older makefiles have not yet made the
-** switch. The following code should catch this problem at compile-time.
-*/
-#ifdef MEMORY_DEBUG
-# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
-#endif
-
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-# ifndef SQLITE_DEBUG_OS_TRACE
-# define SQLITE_DEBUG_OS_TRACE 0
-# endif
- int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
-# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
-#else
-# define OSTRACE(X)
-#endif
-
-/*
-** Macros for performance tracing. Normally turned off. Only works
-** on i486 hardware.
-*/
-#ifdef SQLITE_PERFORMANCE_TRACE
-
-/*
-** hwtime.h contains inline assembler code for implementing
-** high-performance timing routines.
-*/
-/************** Include hwtime.h in the middle of os_common.h ****************/
-/************** Begin file hwtime.h ******************************************/
-/*
-** 2008 May 27
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
-*/
-#ifndef _HWTIME_H_
-#define _HWTIME_H_
-
-/*
-** The following routine only works on pentium-class (or newer) processors.
-** It uses the RDTSC opcode to read the cycle count value out of the
-** processor and returns that value. This can be used for high-res
-** profiling.
-*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
-
- #if defined(__GNUC__)
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
- #elif defined(_MSC_VER)
-
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
- __asm {
- rdtsc
- ret ; return value at EDX:EAX
- }
- }
-
- #endif
-
-#elif (defined(__GNUC__) && defined(__x86_64__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long val;
- __asm__ __volatile__ ("rdtsc" : "=A" (val));
- return val;
- }
-
-#elif (defined(__GNUC__) && defined(__ppc__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long long retval;
- unsigned long junk;
- __asm__ __volatile__ ("\n\
- 1: mftbu %1\n\
- mftb %L0\n\
- mftbu %0\n\
- cmpw %0,%1\n\
- bne 1b"
- : "=r" (retval), "=r" (junk));
- return retval;
- }
-
-#else
-
- #error Need implementation of sqlite3Hwtime() for your platform.
-
- /*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
- */
-SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-
-#endif
-
-#endif /* !defined(_HWTIME_H_) */
-
-/************** End of hwtime.h **********************************************/
-/************** Continuing where we left off in os_common.h ******************/
-
-static sqlite_uint64 g_start;
-static sqlite_uint64 g_elapsed;
-#define TIMER_START g_start=sqlite3Hwtime()
-#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start
-#define TIMER_ELAPSED g_elapsed
-#else
-#define TIMER_START
-#define TIMER_END
-#define TIMER_ELAPSED ((sqlite_uint64)0)
-#endif
-
-/*
-** If we compile with the SQLITE_TEST macro set, then the following block
-** of code will give us the ability to simulate a disk I/O error. This
-** is used for testing the I/O recovery logic.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */
-SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */
-SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */
-SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */
-SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */
-SQLITE_API int sqlite3_diskfull_pending = 0;
-SQLITE_API int sqlite3_diskfull = 0;
-#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
-#define SimulateIOError(CODE) \
- if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
- || sqlite3_io_error_pending-- == 1 ) \
- { local_ioerr(); CODE; }
-static void local_ioerr(){
- IOTRACE(("IOERR\n"));
- sqlite3_io_error_hit++;
- if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
-}
-#define SimulateDiskfullError(CODE) \
- if( sqlite3_diskfull_pending ){ \
- if( sqlite3_diskfull_pending == 1 ){ \
- local_ioerr(); \
- sqlite3_diskfull = 1; \
- sqlite3_io_error_hit = 1; \
- CODE; \
- }else{ \
- sqlite3_diskfull_pending--; \
- } \
- }
-#else
-#define SimulateIOErrorBenign(X)
-#define SimulateIOError(A)
-#define SimulateDiskfullError(A)
-#endif
-
-/*
-** When testing, keep a count of the number of open files.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_open_file_count = 0;
-#define OpenCounter(X) sqlite3_open_file_count+=(X)
-#else
-#define OpenCounter(X)
-#endif
-
-#endif /* !defined(_OS_COMMON_H_) */
-
-/************** End of os_common.h *******************************************/
-/************** Continuing where we left off in os_unix.c ********************/
-
-/*
-** Define various macros that are missing from some systems.
-*/
-#ifndef O_LARGEFILE
-# define O_LARGEFILE 0
-#endif
-#ifdef SQLITE_DISABLE_LFS
-# undef O_LARGEFILE
-# define O_LARGEFILE 0
-#endif
-#ifndef O_NOFOLLOW
-# define O_NOFOLLOW 0
-#endif
-#ifndef O_BINARY
-# define O_BINARY 0
-#endif
-
-/*
-** The threadid macro resolves to the thread-id or to 0. Used for
-** testing and debugging only.
-*/
-#if SQLITE_THREADSAFE
-#define threadid pthread_self()
-#else
-#define threadid 0
-#endif
-
-/*
-** Different Unix systems declare open() in different ways. Same use
-** open(const char*,int,mode_t). Others use open(const char*,int,...).
-** The difference is important when using a pointer to the function.
-**
-** The safest way to deal with the problem is to always use this wrapper
-** which always has the same well-defined interface.
-*/
-static int posixOpen(const char *zFile, int flags, int mode){
- return open(zFile, flags, mode);
-}
-
-/*
-** On some systems, calls to fchown() will trigger a message in a security
-** log if they come from non-root processes. So avoid calling fchown() if
-** we are not running as root.
-*/
-static int posixFchown(int fd, uid_t uid, gid_t gid){
- return geteuid() ? 0 : fchown(fd,uid,gid);
-}
-
-/* Forward reference */
-static int openDirectory(const char*, int*);
-
-/*
-** Many system calls are accessed through pointer-to-functions so that
-** they may be overridden at runtime to facilitate fault injection during
-** testing and sandboxing. The following array holds the names and pointers
-** to all overrideable system calls.
-*/
-static struct unix_syscall {
- const char *zName; /* Name of the sytem call */
- sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
- sqlite3_syscall_ptr pDefault; /* Default value */
-} aSyscall[] = {
- { "open", (sqlite3_syscall_ptr)posixOpen, 0 },
-#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent)
-
- { "close", (sqlite3_syscall_ptr)close, 0 },
-#define osClose ((int(*)(int))aSyscall[1].pCurrent)
-
- { "access", (sqlite3_syscall_ptr)access, 0 },
-#define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent)
-
- { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 },
-#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent)
-
- { "stat", (sqlite3_syscall_ptr)stat, 0 },
-#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent)
-
-/*
-** The DJGPP compiler environment looks mostly like Unix, but it
-** lacks the fcntl() system call. So redefine fcntl() to be something
-** that always succeeds. This means that locking does not occur under
-** DJGPP. But it is DOS - what did you expect?
-*/
-#ifdef __DJGPP__
- { "fstat", 0, 0 },
-#define osFstat(a,b,c) 0
-#else
- { "fstat", (sqlite3_syscall_ptr)fstat, 0 },
-#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
-#endif
-
- { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 },
-#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent)
-
- { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 },
-#define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent)
-
- { "read", (sqlite3_syscall_ptr)read, 0 },
-#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
-
-#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
- { "pread", (sqlite3_syscall_ptr)pread, 0 },
-#else
- { "pread", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent)
-
-#if defined(USE_PREAD64)
- { "pread64", (sqlite3_syscall_ptr)pread64, 0 },
-#else
- { "pread64", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osPread64 ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)
-
- { "write", (sqlite3_syscall_ptr)write, 0 },
-#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
-
-#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
- { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 },
-#else
- { "pwrite", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\
- aSyscall[12].pCurrent)
-
-#if defined(USE_PREAD64)
- { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 },
-#else
- { "pwrite64", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
- aSyscall[13].pCurrent)
-
-#if SQLITE_ENABLE_LOCKING_STYLE
- { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
-#else
- { "fchmod", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
-
-#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
- { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
-#else
- { "fallocate", (sqlite3_syscall_ptr)0, 0 },
-#endif
-#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent)
-
- { "unlink", (sqlite3_syscall_ptr)unlink, 0 },
-#define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent)
-
- { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 },
-#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent)
-
- { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 },
-#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)
-
- { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
-#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
-
- { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
-#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
-
- { "umask", (sqlite3_syscall_ptr)umask, 0 },
-#define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
-
-}; /* End of the overrideable system calls */
-
-/*
-** This is the xSetSystemCall() method of sqlite3_vfs for all of the
-** "unix" VFSes. Return SQLITE_OK opon successfully updating the
-** system call pointer, or SQLITE_NOTFOUND if there is no configurable
-** system call named zName.
-*/
-static int unixSetSystemCall(
- sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */
- const char *zName, /* Name of system call to override */
- sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */
-){
- unsigned int i;
- int rc = SQLITE_NOTFOUND;
-
- UNUSED_PARAMETER(pNotUsed);
- if( zName==0 ){
- /* If no zName is given, restore all system calls to their default
- ** settings and return NULL
- */
- rc = SQLITE_OK;
- for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
- if( aSyscall[i].pDefault ){
- aSyscall[i].pCurrent = aSyscall[i].pDefault;
- }
- }
- }else{
- /* If zName is specified, operate on only the one system call
- ** specified.
- */
- for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
- if( strcmp(zName, aSyscall[i].zName)==0 ){
- if( aSyscall[i].pDefault==0 ){
- aSyscall[i].pDefault = aSyscall[i].pCurrent;
- }
- rc = SQLITE_OK;
- if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
- aSyscall[i].pCurrent = pNewFunc;
- break;
- }
- }
- }
- return rc;
-}
-
-/*
-** Return the value of a system call. Return NULL if zName is not a
-** recognized system call name. NULL is also returned if the system call
-** is currently undefined.
-*/
-static sqlite3_syscall_ptr unixGetSystemCall(
- sqlite3_vfs *pNotUsed,
- const char *zName
-){
- unsigned int i;
-
- UNUSED_PARAMETER(pNotUsed);
- for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
- if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
- }
- return 0;
-}
-
-/*
-** Return the name of the first system call after zName. If zName==NULL
-** then return the name of the first system call. Return NULL if zName
-** is the last system call or if zName is not the name of a valid
-** system call.
-*/
-static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
- int i = -1;
-
- UNUSED_PARAMETER(p);
- if( zName ){
- for(i=0; i<ArraySize(aSyscall)-1; i++){
- if( strcmp(zName, aSyscall[i].zName)==0 ) break;
- }
- }
- for(i++; i<ArraySize(aSyscall); i++){
- if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
- }
- return 0;
-}
-
-/*
-** Invoke open(). Do so multiple times, until it either succeeds or
-** fails for some reason other than EINTR.
-**
-** If the file creation mode "m" is 0 then set it to the default for
-** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
-** 0644) as modified by the system umask. If m is not 0, then
-** make the file creation mode be exactly m ignoring the umask.
-**
-** The m parameter will be non-zero only when creating -wal, -journal,
-** and -shm files. We want those files to have *exactly* the same
-** permissions as their original database, unadulterated by the umask.
-** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
-** transaction crashes and leaves behind hot journals, then any
-** process that is able to write to the database will also be able to
-** recover the hot journals.
-*/
-static int robust_open(const char *z, int f, mode_t m){
- int fd;
- mode_t m2;
- mode_t origM = 0;
- if( m==0 ){
- m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
- }else{
- m2 = m;
- origM = osUmask(0);
- }
- do{
-#if defined(O_CLOEXEC)
- fd = osOpen(z,f|O_CLOEXEC,m2);
-#else
- fd = osOpen(z,f,m2);
-#endif
- }while( fd<0 && errno==EINTR );
- if( m ){
- osUmask(origM);
- }
-#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
- if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
-#endif
- return fd;
-}
-
-/*
-** Helper functions to obtain and relinquish the global mutex. The
-** global mutex is used to protect the unixInodeInfo and
-** vxworksFileId objects used by this file, all of which may be
-** shared by multiple threads.
-**
-** Function unixMutexHeld() is used to assert() that the global mutex
-** is held when required. This function is only used as part of assert()
-** statements. e.g.
-**
-** unixEnterMutex()
-** assert( unixMutexHeld() );
-** unixEnterLeave()
-*/
-static void unixEnterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-static void unixLeaveMutex(void){
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#ifdef SQLITE_DEBUG
-static int unixMutexHeld(void) {
- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#endif
-
-
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-/*
-** Helper function for printing out trace information from debugging
-** binaries. This returns the string represetation of the supplied
-** integer lock-type.
-*/
-static const char *azFileLock(int eFileLock){
- switch( eFileLock ){
- case NO_LOCK: return "NONE";
- case SHARED_LOCK: return "SHARED";
- case RESERVED_LOCK: return "RESERVED";
- case PENDING_LOCK: return "PENDING";
- case EXCLUSIVE_LOCK: return "EXCLUSIVE";
- }
- return "ERROR";
-}
-#endif
-
-#ifdef SQLITE_LOCK_TRACE
-/*
-** Print out information about all locking operations.
-**
-** This routine is used for troubleshooting locks on multithreaded
-** platforms. Enable by compiling with the -DSQLITE_LOCK_TRACE
-** command-line option on the compiler. This code is normally
-** turned off.
-*/
-static int lockTrace(int fd, int op, struct flock *p){
- char *zOpName, *zType;
- int s;
- int savedErrno;
- if( op==F_GETLK ){
- zOpName = "GETLK";
- }else if( op==F_SETLK ){
- zOpName = "SETLK";
- }else{
- s = osFcntl(fd, op, p);
- sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s);
- return s;
- }
- if( p->l_type==F_RDLCK ){
- zType = "RDLCK";
- }else if( p->l_type==F_WRLCK ){
- zType = "WRLCK";
- }else if( p->l_type==F_UNLCK ){
- zType = "UNLCK";
- }else{
- assert( 0 );
- }
- assert( p->l_whence==SEEK_SET );
- s = osFcntl(fd, op, p);
- savedErrno = errno;
- sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",
- threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,
- (int)p->l_pid, s);
- if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){
- struct flock l2;
- l2 = *p;
- osFcntl(fd, F_GETLK, &l2);
- if( l2.l_type==F_RDLCK ){
- zType = "RDLCK";
- }else if( l2.l_type==F_WRLCK ){
- zType = "WRLCK";
- }else if( l2.l_type==F_UNLCK ){
- zType = "UNLCK";
- }else{
- assert( 0 );
- }
- sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n",
- zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid);
- }
- errno = savedErrno;
- return s;
-}
-#undef osFcntl
-#define osFcntl lockTrace
-#endif /* SQLITE_LOCK_TRACE */
-
-/*
-** Retry ftruncate() calls that fail due to EINTR
-*/
-static int robust_ftruncate(int h, sqlite3_int64 sz){
- int rc;
- do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR );
- return rc;
-}
-
-/*
-** This routine translates a standard POSIX errno code into something
-** useful to the clients of the sqlite3 functions. Specifically, it is
-** intended to translate a variety of "try again" errors into SQLITE_BUSY
-** and a variety of "please close the file descriptor NOW" errors into
-** SQLITE_IOERR
-**
-** Errors during initialization of locks, or file system support for locks,
-** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
-*/
-static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
- switch (posixError) {
-#if 0
- /* At one point this code was not commented out. In theory, this branch
- ** should never be hit, as this function should only be called after
- ** a locking-related function (i.e. fcntl()) has returned non-zero with
- ** the value of errno as the first argument. Since a system call has failed,
- ** errno should be non-zero.
- **
- ** Despite this, if errno really is zero, we still don't want to return
- ** SQLITE_OK. The system call failed, and *some* SQLite error should be
- ** propagated back to the caller. Commenting this branch out means errno==0
- ** will be handled by the "default:" case below.
- */
- case 0:
- return SQLITE_OK;
-#endif
-
- case EAGAIN:
- case ETIMEDOUT:
- case EBUSY:
- case EINTR:
- case ENOLCK:
- /* random NFS retry error, unless during file system support
- * introspection, in which it actually means what it says */
- return SQLITE_BUSY;
-
- case EACCES:
- /* EACCES is like EAGAIN during locking operations, but not any other time*/
- if( (sqliteIOErr == SQLITE_IOERR_LOCK) ||
- (sqliteIOErr == SQLITE_IOERR_UNLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
- (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
- return SQLITE_BUSY;
- }
- /* else fall through */
- case EPERM:
- return SQLITE_PERM;
-
- /* EDEADLK is only possible if a call to fcntl(F_SETLKW) is made. And
- ** this module never makes such a call. And the code in SQLite itself
- ** asserts that SQLITE_IOERR_BLOCKED is never returned. For these reasons
- ** this case is also commented out. If the system does set errno to EDEADLK,
- ** the default SQLITE_IOERR_XXX code will be returned. */
-#if 0
- case EDEADLK:
- return SQLITE_IOERR_BLOCKED;
-#endif
-
-#if EOPNOTSUPP!=ENOTSUP
- case EOPNOTSUPP:
- /* something went terribly awry, unless during file system support
- * introspection, in which it actually means what it says */
-#endif
-#ifdef ENOTSUP
- case ENOTSUP:
- /* invalid fd, unless during file system support introspection, in which
- * it actually means what it says */
-#endif
- case EIO:
- case EBADF:
- case EINVAL:
- case ENOTCONN:
- case ENODEV:
- case ENXIO:
- case ENOENT:
-#ifdef ESTALE /* ESTALE is not defined on Interix systems */
- case ESTALE:
-#endif
- case ENOSYS:
- /* these should force the client to close the file and reconnect */
-
- default:
- return sqliteIOErr;
- }
-}
-
-
-
-/******************************************************************************
-****************** Begin Unique File ID Utility Used By VxWorks ***************
-**
-** On most versions of unix, we can get a unique ID for a file by concatenating
-** the device number and the inode number. But this does not work on VxWorks.
-** On VxWorks, a unique file id must be based on the canonical filename.
-**
-** A pointer to an instance of the following structure can be used as a
-** unique file ID in VxWorks. Each instance of this structure contains
-** a copy of the canonical filename. There is also a reference count.
-** The structure is reclaimed when the number of pointers to it drops to
-** zero.
-**
-** There are never very many files open at one time and lookups are not
-** a performance-critical path, so it is sufficient to put these
-** structures on a linked list.
-*/
-struct vxworksFileId {
- struct vxworksFileId *pNext; /* Next in a list of them all */
- int nRef; /* Number of references to this one */
- int nName; /* Length of the zCanonicalName[] string */
- char *zCanonicalName; /* Canonical filename */
-};
-
-#if OS_VXWORKS
-/*
-** All unique filenames are held on a linked list headed by this
-** variable:
-*/
-static struct vxworksFileId *vxworksFileList = 0;
-
-/*
-** Simplify a filename into its canonical form
-** by making the following changes:
-**
-** * removing any trailing and duplicate /
-** * convert /./ into just /
-** * convert /A/../ where A is any simple name into just /
-**
-** Changes are made in-place. Return the new name length.
-**
-** The original filename is in z[0..n-1]. Return the number of
-** characters in the simplified name.
-*/
-static int vxworksSimplifyName(char *z, int n){
- int i, j;
- while( n>1 && z[n-1]=='/' ){ n--; }
- for(i=j=0; i<n; i++){
- if( z[i]=='/' ){
- if( z[i+1]=='/' ) continue;
- if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){
- i += 1;
- continue;
- }
- if( z[i+1]=='.' && i+3<n && z[i+2]=='.' && z[i+3]=='/' ){
- while( j>0 && z[j-1]!='/' ){ j--; }
- if( j>0 ){ j--; }
- i += 2;
- continue;
- }
- }
- z[j++] = z[i];
- }
- z[j] = 0;
- return j;
-}
-
-/*
-** Find a unique file ID for the given absolute pathname. Return
-** a pointer to the vxworksFileId object. This pointer is the unique
-** file ID.
-**
-** The nRef field of the vxworksFileId object is incremented before
-** the object is returned. A new vxworksFileId object is created
-** and added to the global list if necessary.
-**
-** If a memory allocation error occurs, return NULL.
-*/
-static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
- struct vxworksFileId *pNew; /* search key and new file ID */
- struct vxworksFileId *pCandidate; /* For looping over existing file IDs */
- int n; /* Length of zAbsoluteName string */
-
- assert( zAbsoluteName[0]=='/' );
- n = (int)strlen(zAbsoluteName);
- pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
- if( pNew==0 ) return 0;
- pNew->zCanonicalName = (char*)&pNew[1];
- memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
- n = vxworksSimplifyName(pNew->zCanonicalName, n);
-
- /* Search for an existing entry that matching the canonical name.
- ** If found, increment the reference count and return a pointer to
- ** the existing file ID.
- */
- unixEnterMutex();
- for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){
- if( pCandidate->nName==n
- && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0
- ){
- sqlite3_free(pNew);
- pCandidate->nRef++;
- unixLeaveMutex();
- return pCandidate;
- }
- }
-
- /* No match was found. We will make a new file ID */
- pNew->nRef = 1;
- pNew->nName = n;
- pNew->pNext = vxworksFileList;
- vxworksFileList = pNew;
- unixLeaveMutex();
- return pNew;
-}
-
-/*
-** Decrement the reference count on a vxworksFileId object. Free
-** the object when the reference count reaches zero.
-*/
-static void vxworksReleaseFileId(struct vxworksFileId *pId){
- unixEnterMutex();
- assert( pId->nRef>0 );
- pId->nRef--;
- if( pId->nRef==0 ){
- struct vxworksFileId **pp;
- for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){}
- assert( *pp==pId );
- *pp = pId->pNext;
- sqlite3_free(pId);
- }
- unixLeaveMutex();
-}
-#endif /* OS_VXWORKS */
-/*************** End of Unique File ID Utility Used By VxWorks ****************
-******************************************************************************/
-
-
-/******************************************************************************
-*************************** Posix Advisory Locking ****************************
-**
-** POSIX advisory locks are broken by design. ANSI STD 1003.1 (1996)
-** section 6.5.2.2 lines 483 through 490 specify that when a process
-** sets or clears a lock, that operation overrides any prior locks set
-** by the same process. It does not explicitly say so, but this implies
-** that it overrides locks set by the same process using a different
-** file descriptor. Consider this test case:
-**
-** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
-** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
-**
-** Suppose ./file1 and ./file2 are really the same file (because
-** one is a hard or symbolic link to the other) then if you set
-** an exclusive lock on fd1, then try to get an exclusive lock
-** on fd2, it works. I would have expected the second lock to
-** fail since there was already a lock on the file due to fd1.
-** But not so. Since both locks came from the same process, the
-** second overrides the first, even though they were on different
-** file descriptors opened on different file names.
-**
-** This means that we cannot use POSIX locks to synchronize file access
-** among competing threads of the same process. POSIX locks will work fine
-** to synchronize access for threads in separate processes, but not
-** threads within the same process.
-**
-** To work around the problem, SQLite has to manage file locks internally
-** on its own. Whenever a new database is opened, we have to find the
-** specific inode of the database file (the inode is determined by the
-** st_dev and st_ino fields of the stat structure that fstat() fills in)
-** and check for locks already existing on that inode. When locks are
-** created or removed, we have to look at our own internal record of the
-** locks to see if another thread has previously set a lock on that same
-** inode.
-**
-** (Aside: The use of inode numbers as unique IDs does not work on VxWorks.
-** For VxWorks, we have to use the alternative unique ID system based on
-** canonical filename and implemented in the previous division.)
-**
-** The sqlite3_file structure for POSIX is no longer just an integer file
-** descriptor. It is now a structure that holds the integer file
-** descriptor and a pointer to a structure that describes the internal
-** locks on the corresponding inode. There is one locking structure
-** per inode, so if the same inode is opened twice, both unixFile structures
-** point to the same locking structure. The locking structure keeps
-** a reference count (so we will know when to delete it) and a "cnt"
-** field that tells us its internal lock status. cnt==0 means the
-** file is unlocked. cnt==-1 means the file has an exclusive lock.
-** cnt>0 means there are cnt shared locks on the file.
-**
-** Any attempt to lock or unlock a file first checks the locking
-** structure. The fcntl() system call is only invoked to set a
-** POSIX lock if the internal lock structure transitions between
-** a locked and an unlocked state.
-**
-** But wait: there are yet more problems with POSIX advisory locks.
-**
-** If you close a file descriptor that points to a file that has locks,
-** all locks on that file that are owned by the current process are
-** released. To work around this problem, each unixInodeInfo object
-** maintains a count of the number of pending locks on tha inode.
-** When an attempt is made to close an unixFile, if there are
-** other unixFile open on the same inode that are holding locks, the call
-** to close() the file descriptor is deferred until all of the locks clear.
-** The unixInodeInfo structure keeps a list of file descriptors that need to
-** be closed and that list is walked (and cleared) when the last lock
-** clears.
-**
-** Yet another problem: LinuxThreads do not play well with posix locks.
-**
-** Many older versions of linux use the LinuxThreads library which is
-** not posix compliant. Under LinuxThreads, a lock created by thread
-** A cannot be modified or overridden by a different thread B.
-** Only thread A can modify the lock. Locking behavior is correct
-** if the appliation uses the newer Native Posix Thread Library (NPTL)
-** on linux - with NPTL a lock created by thread A can override locks
-** in thread B. But there is no way to know at compile-time which
-** threading library is being used. So there is no way to know at
-** compile-time whether or not thread A can override locks on thread B.
-** One has to do a run-time check to discover the behavior of the
-** current process.
-**
-** SQLite used to support LinuxThreads. But support for LinuxThreads
-** was dropped beginning with version 3.7.0. SQLite will still work with
-** LinuxThreads provided that (1) there is no more than one connection
-** per database file in the same process and (2) database connections
-** do not move across threads.
-*/
-
-/*
-** An instance of the following structure serves as the key used
-** to locate a particular unixInodeInfo object.
-*/
-struct unixFileId {
- dev_t dev; /* Device number */
-#if OS_VXWORKS
- struct vxworksFileId *pId; /* Unique file ID for vxworks. */
-#else
- ino_t ino; /* Inode number */
-#endif
-};
-
-/*
-** An instance of the following structure is allocated for each open
-** inode. Or, on LinuxThreads, there is one of these structures for
-** each inode opened by each thread.
-**
-** A single inode can have multiple file descriptors, so each unixFile
-** structure contains a pointer to an instance of this object and this
-** object keeps a count of the number of unixFile pointing to it.
-*/
-struct unixInodeInfo {
- struct unixFileId fileId; /* The lookup key */
- int nShared; /* Number of SHARED locks held */
- unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */
- unsigned char bProcessLock; /* An exclusive process lock is held */
- int nRef; /* Number of pointers to this structure */
- unixShmNode *pShmNode; /* Shared memory associated with this inode */
- int nLock; /* Number of outstanding file locks */
- UnixUnusedFd *pUnused; /* Unused file descriptors to close */
- unixInodeInfo *pNext; /* List of all unixInodeInfo objects */
- unixInodeInfo *pPrev; /* .... doubly linked */
-#if SQLITE_ENABLE_LOCKING_STYLE
- unsigned long long sharedByte; /* for AFP simulated shared lock */
-#endif
-#if OS_VXWORKS
- sem_t *pSem; /* Named POSIX semaphore */
- char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */
-#endif
-};
-
-/*
-** A lists of all unixInodeInfo objects.
-*/
-static unixInodeInfo *inodeList = 0;
-
-/*
-**
-** This function - unixLogError_x(), is only ever called via the macro
-** unixLogError().
-**
-** It is invoked after an error occurs in an OS function and errno has been
-** set. It logs a message using sqlite3_log() containing the current value of
-** errno and, if possible, the human-readable equivalent from strerror() or
-** strerror_r().
-**
-** The first argument passed to the macro should be the error code that
-** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN).
-** The two subsequent arguments should be the name of the OS function that
-** failed (e.g. "unlink", "open") and the associated file-system path,
-** if any.
-*/
-#define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__)
-static int unixLogErrorAtLine(
- int errcode, /* SQLite error code */
- const char *zFunc, /* Name of OS function that failed */
- const char *zPath, /* File path associated with error */
- int iLine /* Source line number where error occurred */
-){
- char *zErr; /* Message from strerror() or equivalent */
- int iErrno = errno; /* Saved syscall error number */
-
- /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use
- ** the strerror() function to obtain the human-readable error message
- ** equivalent to errno. Otherwise, use strerror_r().
- */
-#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R)
- char aErr[80];
- memset(aErr, 0, sizeof(aErr));
- zErr = aErr;
-
- /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined,
- ** assume that the system provides the GNU version of strerror_r() that
- ** returns a pointer to a buffer containing the error message. That pointer
- ** may point to aErr[], or it may point to some static storage somewhere.
- ** Otherwise, assume that the system provides the POSIX version of
- ** strerror_r(), which always writes an error message into aErr[].
- **
- ** If the code incorrectly assumes that it is the POSIX version that is
- ** available, the error message will often be an empty string. Not a
- ** huge problem. Incorrectly concluding that the GNU version is available
- ** could lead to a segfault though.
- */
-#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
- zErr =
-# endif
- strerror_r(iErrno, aErr, sizeof(aErr)-1);
-
-#elif SQLITE_THREADSAFE
- /* This is a threadsafe build, but strerror_r() is not available. */
- zErr = "";
-#else
- /* Non-threadsafe build, use strerror(). */
- zErr = strerror(iErrno);
-#endif
-
- assert( errcode!=SQLITE_OK );
- if( zPath==0 ) zPath = "";
- sqlite3_log(errcode,
- "os_unix.c:%d: (%d) %s(%s) - %s",
- iLine, iErrno, zFunc, zPath, zErr
- );
-
- return errcode;
-}
-
-/*
-** Close a file descriptor.
-**
-** We assume that close() almost always works, since it is only in a
-** very sick application or on a very sick platform that it might fail.
-** If it does fail, simply leak the file descriptor, but do log the
-** error.
-**
-** Note that it is not safe to retry close() after EINTR since the
-** file descriptor might have already been reused by another thread.
-** So we don't even try to recover from an EINTR. Just log the error
-** and move on.
-*/
-static void robust_close(unixFile *pFile, int h, int lineno){
- if( osClose(h) ){
- unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close",
- pFile ? pFile->zPath : 0, lineno);
- }
-}
-
-/*
-** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
-*/
-static void closePendingFds(unixFile *pFile){
- unixInodeInfo *pInode = pFile->pInode;
- UnixUnusedFd *p;
- UnixUnusedFd *pNext;
- for(p=pInode->pUnused; p; p=pNext){
- pNext = p->pNext;
- robust_close(pFile, p->fd, __LINE__);
- sqlite3_free(p);
- }
- pInode->pUnused = 0;
-}
-
-/*
-** Release a unixInodeInfo structure previously allocated by findInodeInfo().
-**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
-*/
-static void releaseInodeInfo(unixFile *pFile){
- unixInodeInfo *pInode = pFile->pInode;
- assert( unixMutexHeld() );
- if( ALWAYS(pInode) ){
- pInode->nRef--;
- if( pInode->nRef==0 ){
- assert( pInode->pShmNode==0 );
- closePendingFds(pFile);
- if( pInode->pPrev ){
- assert( pInode->pPrev->pNext==pInode );
- pInode->pPrev->pNext = pInode->pNext;
- }else{
- assert( inodeList==pInode );
- inodeList = pInode->pNext;
- }
- if( pInode->pNext ){
- assert( pInode->pNext->pPrev==pInode );
- pInode->pNext->pPrev = pInode->pPrev;
- }
- sqlite3_free(pInode);
- }
- }
-}
-
-/*
-** Given a file descriptor, locate the unixInodeInfo object that
-** describes that file descriptor. Create a new one if necessary. The
-** return value might be uninitialized if an error occurs.
-**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
-**
-** Return an appropriate error code.
-*/
-static int findInodeInfo(
- unixFile *pFile, /* Unix file with file desc used in the key */
- unixInodeInfo **ppInode /* Return the unixInodeInfo object here */
-){
- int rc; /* System call return code */
- int fd; /* The file descriptor for pFile */
- struct unixFileId fileId; /* Lookup key for the unixInodeInfo */
- struct stat statbuf; /* Low-level file information */
- unixInodeInfo *pInode = 0; /* Candidate unixInodeInfo object */
-
- assert( unixMutexHeld() );
-
- /* Get low-level information about the file that we can used to
- ** create a unique name for the file.
- */
- fd = pFile->h;
- rc = osFstat(fd, &statbuf);
- if( rc!=0 ){
- pFile->lastErrno = errno;
-#ifdef EOVERFLOW
- if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
-#endif
- return SQLITE_IOERR;
- }
-
-#ifdef __APPLE__
- /* On OS X on an msdos filesystem, the inode number is reported
- ** incorrectly for zero-size files. See ticket #3260. To work
- ** around this problem (we consider it a bug in OS X, not SQLite)
- ** we always increase the file size to 1 by writing a single byte
- ** prior to accessing the inode number. The one byte written is
- ** an ASCII 'S' character which also happens to be the first byte
- ** in the header of every SQLite database. In this way, if there
- ** is a race condition such that another thread has already populated
- ** the first page of the database, no damage is done.
- */
- if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){
- do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
- if( rc!=1 ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR;
- }
- rc = osFstat(fd, &statbuf);
- if( rc!=0 ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR;
- }
- }
-#endif
-
- memset(&fileId, 0, sizeof(fileId));
- fileId.dev = statbuf.st_dev;
-#if OS_VXWORKS
- fileId.pId = pFile->pId;
-#else
- fileId.ino = statbuf.st_ino;
-#endif
- pInode = inodeList;
- while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
- pInode = pInode->pNext;
- }
- if( pInode==0 ){
- pInode = sqlite3_malloc( sizeof(*pInode) );
- if( pInode==0 ){
- return SQLITE_NOMEM;
- }
- memset(pInode, 0, sizeof(*pInode));
- memcpy(&pInode->fileId, &fileId, sizeof(fileId));
- pInode->nRef = 1;
- pInode->pNext = inodeList;
- pInode->pPrev = 0;
- if( inodeList ) inodeList->pPrev = pInode;
- inodeList = pInode;
- }else{
- pInode->nRef++;
- }
- *ppInode = pInode;
- return SQLITE_OK;
-}
-
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
- unixEnterMutex(); /* Because pFile->pInode is shared across threads */
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->pInode->eFileLock>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it.
- */
-#ifndef __DJGPP__
- if( !reserved && !pFile->pInode->bProcessLock ){
- struct flock lock;
- lock.l_whence = SEEK_SET;
- lock.l_start = RESERVED_BYTE;
- lock.l_len = 1;
- lock.l_type = F_WRLCK;
- if( osFcntl(pFile->h, F_GETLK, &lock) ){
- rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
- pFile->lastErrno = errno;
- } else if( lock.l_type!=F_UNLCK ){
- reserved = 1;
- }
- }
-#endif
-
- unixLeaveMutex();
- OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));
-
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Attempt to set a system-lock on the file pFile. The lock is
-** described by pLock.
-**
-** If the pFile was opened read/write from unix-excl, then the only lock
-** ever obtained is an exclusive lock, and it is obtained exactly once
-** the first time any lock is attempted. All subsequent system locking
-** operations become no-ops. Locking operations still happen internally,
-** in order to coordinate access between separate database connections
-** within this process, but all of that is handled in memory and the
-** operating system does not participate.
-**
-** This function is a pass-through to fcntl(F_SETLK) if pFile is using
-** any VFS other than "unix-excl" or if pFile is opened on "unix-excl"
-** and is read-only.
-**
-** Zero is returned if the call completes successfully, or -1 if a call
-** to fcntl() fails. In this case, errno is set appropriately (by fcntl()).
-*/
-static int unixFileLock(unixFile *pFile, struct flock *pLock){
- int rc;
- unixInodeInfo *pInode = pFile->pInode;
- assert( unixMutexHeld() );
- assert( pInode!=0 );
- if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock)
- && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0)
- ){
- if( pInode->bProcessLock==0 ){
- struct flock lock;
- assert( pInode->nLock==0 );
- lock.l_whence = SEEK_SET;
- lock.l_start = SHARED_FIRST;
- lock.l_len = SHARED_SIZE;
- lock.l_type = F_WRLCK;
- rc = osFcntl(pFile->h, F_SETLK, &lock);
- if( rc<0 ) return rc;
- pInode->bProcessLock = 1;
- pInode->nLock++;
- }else{
- rc = 0;
- }
- }else{
- rc = osFcntl(pFile->h, F_SETLK, pLock);
- }
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter eFileLock - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int unixLock(sqlite3_file *id, int eFileLock){
- /* The following describes the implementation of the various locks and
- ** lock transitions in terms of the POSIX advisory shared and exclusive
- ** lock primitives (called read-locks and write-locks below, to avoid
- ** confusion with SQLite lock names). The algorithms are complicated
- ** slightly in order to be compatible with windows systems simultaneously
- ** accessing the same database file, in case that is ever required.
- **
- ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
- ** byte', each single bytes at well known offsets, and the 'shared byte
- ** range', a range of 510 bytes at a well known offset.
- **
- ** To obtain a SHARED lock, a read-lock is obtained on the 'pending
- ** byte'. If this is successful, a random byte from the 'shared byte
- ** range' is read-locked and the lock on the 'pending byte' released.
- **
- ** A process may only obtain a RESERVED lock after it has a SHARED lock.
- ** A RESERVED lock is implemented by grabbing a write-lock on the
- ** 'reserved byte'.
- **
- ** A process may only obtain a PENDING lock after it has obtained a
- ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock
- ** on the 'pending byte'. This ensures that no new SHARED locks can be
- ** obtained, but existing SHARED locks are allowed to persist. A process
- ** does not have to obtain a RESERVED lock on the way to a PENDING lock.
- ** This property is used by the algorithm for rolling back a journal file
- ** after a crash.
- **
- ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is
- ** implemented by obtaining a write-lock on the entire 'shared byte
- ** range'. Since all other locks require a read-lock on one of the bytes
- ** within this range, this ensures that no other locks are held on the
- ** database.
- **
- ** The reason a single byte cannot be used instead of the 'shared byte
- ** range' is that some versions of windows do not support read-locks. By
- ** locking a random byte from a range, concurrent SHARED locks may exist
- ** even if the locking primitive used is always a write-lock.
- */
- int rc = SQLITE_OK;
- unixFile *pFile = (unixFile*)id;
- unixInodeInfo *pInode;
- struct flock lock;
- int tErrno = 0;
-
- assert( pFile );
- OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
- azFileLock(eFileLock), azFileLock(pFile->eFileLock),
- azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid()));
-
- /* If there is already a lock of this type or more restrictive on the
- ** unixFile, do nothing. Don't use the end_lock: exit path, as
- ** unixEnterMutex() hasn't been called yet.
- */
- if( pFile->eFileLock>=eFileLock ){
- OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h,
- azFileLock(eFileLock)));
- return SQLITE_OK;
- }
-
- /* Make sure the locking sequence is correct.
- ** (1) We never move from unlocked to anything higher than shared lock.
- ** (2) SQLite never explicitly requests a pendig lock.
- ** (3) A shared lock is always held when a reserve lock is requested.
- */
- assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
- assert( eFileLock!=PENDING_LOCK );
- assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );
-
- /* This mutex is needed because pFile->pInode is shared across threads
- */
- unixEnterMutex();
- pInode = pFile->pInode;
-
- /* If some thread using this PID has a lock via a different unixFile*
- ** handle that precludes the requested lock, return BUSY.
- */
- if( (pFile->eFileLock!=pInode->eFileLock &&
- (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK))
- ){
- rc = SQLITE_BUSY;
- goto end_lock;
- }
-
- /* If a SHARED lock is requested, and some thread using this PID already
- ** has a SHARED or RESERVED lock, then increment reference counts and
- ** return SQLITE_OK.
- */
- if( eFileLock==SHARED_LOCK &&
- (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){
- assert( eFileLock==SHARED_LOCK );
- assert( pFile->eFileLock==0 );
- assert( pInode->nShared>0 );
- pFile->eFileLock = SHARED_LOCK;
- pInode->nShared++;
- pInode->nLock++;
- goto end_lock;
- }
-
-
- /* A PENDING lock is needed before acquiring a SHARED lock and before
- ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will
- ** be released.
- */
- lock.l_len = 1L;
- lock.l_whence = SEEK_SET;
- if( eFileLock==SHARED_LOCK
- || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
- ){
- lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK);
- lock.l_start = PENDING_BYTE;
- if( unixFileLock(pFile, &lock) ){
- tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( rc!=SQLITE_BUSY ){
- pFile->lastErrno = tErrno;
- }
- goto end_lock;
- }
- }
-
-
- /* If control gets to this point, then actually go ahead and make
- ** operating system calls for the specified lock.
- */
- if( eFileLock==SHARED_LOCK ){
- assert( pInode->nShared==0 );
- assert( pInode->eFileLock==0 );
- assert( rc==SQLITE_OK );
-
- /* Now get the read-lock */
- lock.l_start = SHARED_FIRST;
- lock.l_len = SHARED_SIZE;
- if( unixFileLock(pFile, &lock) ){
- tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- }
-
- /* Drop the temporary PENDING lock */
- lock.l_start = PENDING_BYTE;
- lock.l_len = 1L;
- lock.l_type = F_UNLCK;
- if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){
- /* This could happen with a network mount */
- tErrno = errno;
- rc = SQLITE_IOERR_UNLOCK;
- }
-
- if( rc ){
- if( rc!=SQLITE_BUSY ){
- pFile->lastErrno = tErrno;
- }
- goto end_lock;
- }else{
- pFile->eFileLock = SHARED_LOCK;
- pInode->nLock++;
- pInode->nShared = 1;
- }
- }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
- /* We are trying for an exclusive lock but another thread in this
- ** same process is still holding a shared lock. */
- rc = SQLITE_BUSY;
- }else{
- /* The request was for a RESERVED or EXCLUSIVE lock. It is
- ** assumed that there is a SHARED or greater lock on the file
- ** already.
- */
- assert( 0!=pFile->eFileLock );
- lock.l_type = F_WRLCK;
-
- assert( eFileLock==RESERVED_LOCK || eFileLock==EXCLUSIVE_LOCK );
- if( eFileLock==RESERVED_LOCK ){
- lock.l_start = RESERVED_BYTE;
- lock.l_len = 1L;
- }else{
- lock.l_start = SHARED_FIRST;
- lock.l_len = SHARED_SIZE;
- }
-
- if( unixFileLock(pFile, &lock) ){
- tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( rc!=SQLITE_BUSY ){
- pFile->lastErrno = tErrno;
- }
- }
- }
-
-
-#ifdef SQLITE_DEBUG
- /* Set up the transaction-counter change checking flags when
- ** transitioning from a SHARED to a RESERVED lock. The change
- ** from SHARED to RESERVED marks the beginning of a normal
- ** write operation (not a hot journal rollback).
- */
- if( rc==SQLITE_OK
- && pFile->eFileLock<=SHARED_LOCK
- && eFileLock==RESERVED_LOCK
- ){
- pFile->transCntrChng = 0;
- pFile->dbUpdate = 0;
- pFile->inNormalWrite = 1;
- }
-#endif
-
-
- if( rc==SQLITE_OK ){
- pFile->eFileLock = eFileLock;
- pInode->eFileLock = eFileLock;
- }else if( eFileLock==EXCLUSIVE_LOCK ){
- pFile->eFileLock = PENDING_LOCK;
- pInode->eFileLock = PENDING_LOCK;
- }
-
-end_lock:
- unixLeaveMutex();
- OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock),
- rc==SQLITE_OK ? "ok" : "failed"));
- return rc;
-}
-
-/*
-** Add the file descriptor used by file handle pFile to the corresponding
-** pUnused list.
-*/
-static void setPendingFd(unixFile *pFile){
- unixInodeInfo *pInode = pFile->pInode;
- UnixUnusedFd *p = pFile->pUnused;
- p->pNext = pInode->pUnused;
- pInode->pUnused = p;
- pFile->h = -1;
- pFile->pUnused = 0;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-**
-** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED
-** the byte range is divided into 2 parts and the first part is unlocked then
-** set to a read lock, then the other part is simply unlocked. This works
-** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to
-** remove the write lock on a region when a read lock is set.
-*/
-static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
- unixFile *pFile = (unixFile*)id;
- unixInodeInfo *pInode;
- struct flock lock;
- int rc = SQLITE_OK;
-
- assert( pFile );
- OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
- pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
- getpid()));
-
- assert( eFileLock<=SHARED_LOCK );
- if( pFile->eFileLock<=eFileLock ){
- return SQLITE_OK;
- }
- unixEnterMutex();
- pInode = pFile->pInode;
- assert( pInode->nShared!=0 );
- if( pFile->eFileLock>SHARED_LOCK ){
- assert( pInode->eFileLock==pFile->eFileLock );
-
-#ifdef SQLITE_DEBUG
- /* When reducing a lock such that other processes can start
- ** reading the database file again, make sure that the
- ** transaction counter was updated if any part of the database
- ** file changed. If the transaction counter is not updated,
- ** other connections to the same file might not realize that
- ** the file has changed and hence might not know to flush their
- ** cache. The use of a stale cache can lead to database corruption.
- */
- pFile->inNormalWrite = 0;
-#endif
-
- /* downgrading to a shared lock on NFS involves clearing the write lock
- ** before establishing the readlock - to avoid a race condition we downgrade
- ** the lock in 2 blocks, so that part of the range will be covered by a
- ** write lock until the rest is covered by a read lock:
- ** 1: [WWWWW]
- ** 2: [....W]
- ** 3: [RRRRW]
- ** 4: [RRRR.]
- */
- if( eFileLock==SHARED_LOCK ){
-
-#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE
- (void)handleNFSUnlock;
- assert( handleNFSUnlock==0 );
-#endif
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
- if( handleNFSUnlock ){
- int tErrno; /* Error code from system call errors */
- off_t divSize = SHARED_SIZE - 1;
-
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = SHARED_FIRST;
- lock.l_len = divSize;
- if( unixFileLock(pFile, &lock)==(-1) ){
- tErrno = errno;
- rc = SQLITE_IOERR_UNLOCK;
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- goto end_unlock;
- }
- lock.l_type = F_RDLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = SHARED_FIRST;
- lock.l_len = divSize;
- if( unixFileLock(pFile, &lock)==(-1) ){
- tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- goto end_unlock;
- }
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = SHARED_FIRST+divSize;
- lock.l_len = SHARED_SIZE-divSize;
- if( unixFileLock(pFile, &lock)==(-1) ){
- tErrno = errno;
- rc = SQLITE_IOERR_UNLOCK;
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- goto end_unlock;
- }
- }else
-#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
- {
- lock.l_type = F_RDLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = SHARED_FIRST;
- lock.l_len = SHARED_SIZE;
- if( unixFileLock(pFile, &lock) ){
- /* In theory, the call to unixFileLock() cannot fail because another
- ** process is holding an incompatible lock. If it does, this
- ** indicates that the other process is not following the locking
- ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning
- ** SQLITE_BUSY would confuse the upper layer (in practice it causes
- ** an assert to fail). */
- rc = SQLITE_IOERR_RDLOCK;
- pFile->lastErrno = errno;
- goto end_unlock;
- }
- }
- }
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = PENDING_BYTE;
- lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE );
- if( unixFileLock(pFile, &lock)==0 ){
- pInode->eFileLock = SHARED_LOCK;
- }else{
- rc = SQLITE_IOERR_UNLOCK;
- pFile->lastErrno = errno;
- goto end_unlock;
- }
- }
- if( eFileLock==NO_LOCK ){
- /* Decrement the shared lock counter. Release the lock using an
- ** OS call only when all threads in this same process have released
- ** the lock.
- */
- pInode->nShared--;
- if( pInode->nShared==0 ){
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = lock.l_len = 0L;
- if( unixFileLock(pFile, &lock)==0 ){
- pInode->eFileLock = NO_LOCK;
- }else{
- rc = SQLITE_IOERR_UNLOCK;
- pFile->lastErrno = errno;
- pInode->eFileLock = NO_LOCK;
- pFile->eFileLock = NO_LOCK;
- }
- }
-
- /* Decrement the count of locks against this same file. When the
- ** count reaches zero, close any other file descriptors whose close
- ** was deferred because of outstanding locks.
- */
- pInode->nLock--;
- assert( pInode->nLock>=0 );
- if( pInode->nLock==0 ){
- closePendingFds(pFile);
- }
- }
-
-end_unlock:
- unixLeaveMutex();
- if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
- return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int unixUnlock(sqlite3_file *id, int eFileLock){
- return posixUnlock(id, eFileLock, 0);
-}
-
-/*
-** This function performs the parts of the "close file" operation
-** common to all locking schemes. It closes the directory and file
-** handles, if they are valid, and sets all fields of the unixFile
-** structure to 0.
-**
-** It is *not* necessary to hold the mutex when this routine is called,
-** even on VxWorks. A mutex will be acquired on VxWorks by the
-** vxworksReleaseFileId() routine.
-*/
-static int closeUnixFile(sqlite3_file *id){
- unixFile *pFile = (unixFile*)id;
- if( pFile->h>=0 ){
- robust_close(pFile, pFile->h, __LINE__);
- pFile->h = -1;
- }
-#if OS_VXWORKS
- if( pFile->pId ){
- if( pFile->ctrlFlags & UNIXFILE_DELETE ){
- osUnlink(pFile->pId->zCanonicalName);
- }
- vxworksReleaseFileId(pFile->pId);
- pFile->pId = 0;
- }
-#endif
- OSTRACE(("CLOSE %-3d\n", pFile->h));
- OpenCounter(-1);
- sqlite3_free(pFile->pUnused);
- memset(pFile, 0, sizeof(unixFile));
- return SQLITE_OK;
-}
-
-/*
-** Close a file.
-*/
-static int unixClose(sqlite3_file *id){
- int rc = SQLITE_OK;
- unixFile *pFile = (unixFile *)id;
- unixUnlock(id, NO_LOCK);
- unixEnterMutex();
-
- /* unixFile.pInode is always valid here. Otherwise, a different close
- ** routine (e.g. nolockClose()) would be called instead.
- */
- assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );
- if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){
- /* If there are outstanding locks, do not actually close the file just
- ** yet because that would clear those locks. Instead, add the file
- ** descriptor to pInode->pUnused list. It will be automatically closed
- ** when the last lock is cleared.
- */
- setPendingFd(pFile);
- }
- releaseInodeInfo(pFile);
- rc = closeUnixFile(id);
- unixLeaveMutex();
- return rc;
-}
-
-/************** End of the posix advisory lock implementation *****************
-******************************************************************************/
-
-/******************************************************************************
-****************************** No-op Locking **********************************
-**
-** Of the various locking implementations available, this is by far the
-** simplest: locking is ignored. No attempt is made to lock the database
-** file for reading or writing.
-**
-** This locking mode is appropriate for use on read-only databases
-** (ex: databases that are burned into CD-ROM, for example.) It can
-** also be used if the application employs some external mechanism to
-** prevent simultaneous access of the same database by two or more
-** database connections. But there is a serious risk of database
-** corruption if this locking mode is used in situations where multiple
-** database connections are accessing the same database file at the same
-** time and one or more of those connections are writing.
-*/
-
-static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){
- UNUSED_PARAMETER(NotUsed);
- *pResOut = 0;
- return SQLITE_OK;
-}
-static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return SQLITE_OK;
-}
-static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return SQLITE_OK;
-}
-
-/*
-** Close the file.
-*/
-static int nolockClose(sqlite3_file *id) {
- return closeUnixFile(id);
-}
-
-/******************* End of the no-op lock implementation *********************
-******************************************************************************/
-
-/******************************************************************************
-************************* Begin dot-file Locking ******************************
-**
-** The dotfile locking implementation uses the existance of separate lock
-** files (really a directory) to control access to the database. This works
-** on just about every filesystem imaginable. But there are serious downsides:
-**
-** (1) There is zero concurrency. A single reader blocks all other
-** connections from reading or writing the database.
-**
-** (2) An application crash or power loss can leave stale lock files
-** sitting around that need to be cleared manually.
-**
-** Nevertheless, a dotlock is an appropriate locking mode for use if no
-** other locking strategy is available.
-**
-** Dotfile locking works by creating a subdirectory in the same directory as
-** the database and with the same name but with a ".lock" extension added.
-** The existance of a lock directory implies an EXCLUSIVE lock. All other
-** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
-*/
-
-/*
-** The file suffix added to the data base filename in order to create the
-** lock directory.
-*/
-#define DOTLOCK_SUFFIX ".lock"
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-**
-** In dotfile locking, either a lock exists or it does not. So in this
-** variation of CheckReservedLock(), *pResOut is set to true if any lock
-** is held on the file and false if the file is unlocked.
-*/
-static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->eFileLock>SHARED_LOCK ){
- /* Either this connection or some other connection in the same process
- ** holds a lock on the file. No need to check further. */
- reserved = 1;
- }else{
- /* The lock is held if and only if the lockfile exists */
- const char *zLockFile = (const char*)pFile->lockingContext;
- reserved = osAccess(zLockFile, 0)==0;
- }
- OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter eFileLock - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-**
-** With dotfile locking, we really only support state (4): EXCLUSIVE.
-** But we track the other locking levels internally.
-*/
-static int dotlockLock(sqlite3_file *id, int eFileLock) {
- unixFile *pFile = (unixFile*)id;
- char *zLockFile = (char *)pFile->lockingContext;
- int rc = SQLITE_OK;
-
-
- /* If we have any lock, then the lock file already exists. All we have
- ** to do is adjust our internal record of the lock level.
- */
- if( pFile->eFileLock > NO_LOCK ){
- pFile->eFileLock = eFileLock;
- /* Always update the timestamp on the old file */
-#ifdef HAVE_UTIME
- utime(zLockFile, NULL);
-#else
- utimes(zLockFile, NULL);
-#endif
- return SQLITE_OK;
- }
-
- /* grab an exclusive lock */
- rc = osMkdir(zLockFile, 0777);
- if( rc<0 ){
- /* failed to open/create the lock directory */
- int tErrno = errno;
- if( EEXIST == tErrno ){
- rc = SQLITE_BUSY;
- } else {
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- }
- return rc;
- }
-
- /* got it, set the type and return ok */
- pFile->eFileLock = eFileLock;
- return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-**
-** When the locking level reaches NO_LOCK, delete the lock file.
-*/
-static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
- unixFile *pFile = (unixFile*)id;
- char *zLockFile = (char *)pFile->lockingContext;
- int rc;
-
- assert( pFile );
- OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
- pFile->eFileLock, getpid()));
- assert( eFileLock<=SHARED_LOCK );
-
- /* no-op if possible */
- if( pFile->eFileLock==eFileLock ){
- return SQLITE_OK;
- }
-
- /* To downgrade to shared, simply update our internal notion of the
- ** lock state. No need to mess with the file on disk.
- */
- if( eFileLock==SHARED_LOCK ){
- pFile->eFileLock = SHARED_LOCK;
- return SQLITE_OK;
- }
-
- /* To fully unlock the database, delete the lock file */
- assert( eFileLock==NO_LOCK );
- rc = osRmdir(zLockFile);
- if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
- if( rc<0 ){
- int tErrno = errno;
- rc = 0;
- if( ENOENT != tErrno ){
- rc = SQLITE_IOERR_UNLOCK;
- }
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- return rc;
- }
- pFile->eFileLock = NO_LOCK;
- return SQLITE_OK;
-}
-
-/*
-** Close a file. Make sure the lock has been released before closing.
-*/
-static int dotlockClose(sqlite3_file *id) {
- int rc = SQLITE_OK;
- if( id ){
- unixFile *pFile = (unixFile*)id;
- dotlockUnlock(id, NO_LOCK);
- sqlite3_free(pFile->lockingContext);
- rc = closeUnixFile(id);
- }
- return rc;
-}
-/****************** End of the dot-file lock implementation *******************
-******************************************************************************/
-
-/******************************************************************************
-************************** Begin flock Locking ********************************
-**
-** Use the flock() system call to do file locking.
-**
-** flock() locking is like dot-file locking in that the various
-** fine-grain locking levels supported by SQLite are collapsed into
-** a single exclusive lock. In other words, SHARED, RESERVED, and
-** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite
-** still works when you do this, but concurrency is reduced since
-** only a single process can be reading the database at a time.
-**
-** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if
-** compiling for VXWORKS.
-*/
-#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
-
-/*
-** Retry flock() calls that fail with EINTR
-*/
-#ifdef EINTR
-static int robust_flock(int fd, int op){
- int rc;
- do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR );
- return rc;
-}
-#else
-# define robust_flock(a,b) flock(a,b)
-#endif
-
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->eFileLock>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it. */
- if( !reserved ){
- /* attempt to get the lock */
- int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB);
- if( !lrc ){
- /* got the lock, unlock it */
- lrc = robust_flock(pFile->h, LOCK_UN);
- if ( lrc ) {
- int tErrno = errno;
- /* unlock failed with an error */
- lrc = SQLITE_IOERR_UNLOCK;
- if( IS_LOCK_ERROR(lrc) ){
- pFile->lastErrno = tErrno;
- rc = lrc;
- }
- }
- } else {
- int tErrno = errno;
- reserved = 1;
- /* someone else might have it reserved */
- lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(lrc) ){
- pFile->lastErrno = tErrno;
- rc = lrc;
- }
- }
- }
- OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
-
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
- rc = SQLITE_OK;
- reserved=1;
- }
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter eFileLock - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** flock() only really support EXCLUSIVE locks. We track intermediate
-** lock states in the sqlite3_file structure, but all locks SHARED or
-** above are really EXCLUSIVE locks and exclude all other processes from
-** access the file.
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int flockLock(sqlite3_file *id, int eFileLock) {
- int rc = SQLITE_OK;
- unixFile *pFile = (unixFile*)id;
-
- assert( pFile );
-
- /* if we already have a lock, it is exclusive.
- ** Just adjust level and punt on outta here. */
- if (pFile->eFileLock > NO_LOCK) {
- pFile->eFileLock = eFileLock;
- return SQLITE_OK;
- }
-
- /* grab an exclusive lock */
-
- if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) {
- int tErrno = errno;
- /* didn't get, must be busy */
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- } else {
- /* got it, set the type and return ok */
- pFile->eFileLock = eFileLock;
- }
- OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock),
- rc==SQLITE_OK ? "ok" : "failed"));
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
- rc = SQLITE_BUSY;
- }
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- return rc;
-}
-
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int flockUnlock(sqlite3_file *id, int eFileLock) {
- unixFile *pFile = (unixFile*)id;
-
- assert( pFile );
- OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock,
- pFile->eFileLock, getpid()));
- assert( eFileLock<=SHARED_LOCK );
-
- /* no-op if possible */
- if( pFile->eFileLock==eFileLock ){
- return SQLITE_OK;
- }
-
- /* shared can just be set because we always have an exclusive */
- if (eFileLock==SHARED_LOCK) {
- pFile->eFileLock = eFileLock;
- return SQLITE_OK;
- }
-
- /* no, really, unlock. */
- if( robust_flock(pFile->h, LOCK_UN) ){
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- return SQLITE_OK;
-#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
- return SQLITE_IOERR_UNLOCK;
- }else{
- pFile->eFileLock = NO_LOCK;
- return SQLITE_OK;
- }
-}
-
-/*
-** Close a file.
-*/
-static int flockClose(sqlite3_file *id) {
- int rc = SQLITE_OK;
- if( id ){
- flockUnlock(id, NO_LOCK);
- rc = closeUnixFile(id);
- }
- return rc;
-}
-
-#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
-
-/******************* End of the flock lock implementation *********************
-******************************************************************************/
-
-/******************************************************************************
-************************ Begin Named Semaphore Locking ************************
-**
-** Named semaphore locking is only supported on VxWorks.
-**
-** Semaphore locking is like dot-lock and flock in that it really only
-** supports EXCLUSIVE locking. Only a single process can read or write
-** the database file at a time. This reduces potential concurrency, but
-** makes the lock implementation much easier.
-*/
-#if OS_VXWORKS
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->eFileLock>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it. */
- if( !reserved ){
- sem_t *pSem = pFile->pInode->pSem;
- struct stat statBuf;
-
- if( sem_trywait(pSem)==-1 ){
- int tErrno = errno;
- if( EAGAIN != tErrno ){
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
- pFile->lastErrno = tErrno;
- } else {
- /* someone else has the lock when we are in NO_LOCK */
- reserved = (pFile->eFileLock < SHARED_LOCK);
- }
- }else{
- /* we could have it if we want it */
- sem_post(pSem);
- }
- }
- OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved));
-
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter eFileLock - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** Semaphore locks only really support EXCLUSIVE locks. We track intermediate
-** lock states in the sqlite3_file structure, but all locks SHARED or
-** above are really EXCLUSIVE locks and exclude all other processes from
-** access the file.
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int semLock(sqlite3_file *id, int eFileLock) {
- unixFile *pFile = (unixFile*)id;
- int fd;
- sem_t *pSem = pFile->pInode->pSem;
- int rc = SQLITE_OK;
-
- /* if we already have a lock, it is exclusive.
- ** Just adjust level and punt on outta here. */
- if (pFile->eFileLock > NO_LOCK) {
- pFile->eFileLock = eFileLock;
- rc = SQLITE_OK;
- goto sem_end_lock;
- }
-
- /* lock semaphore now but bail out when already locked. */
- if( sem_trywait(pSem)==-1 ){
- rc = SQLITE_BUSY;
- goto sem_end_lock;
- }
-
- /* got it, set the type and return ok */
- pFile->eFileLock = eFileLock;
-
- sem_end_lock:
- return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int semUnlock(sqlite3_file *id, int eFileLock) {
- unixFile *pFile = (unixFile*)id;
- sem_t *pSem = pFile->pInode->pSem;
-
- assert( pFile );
- assert( pSem );
- OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
- pFile->eFileLock, getpid()));
- assert( eFileLock<=SHARED_LOCK );
-
- /* no-op if possible */
- if( pFile->eFileLock==eFileLock ){
- return SQLITE_OK;
- }
-
- /* shared can just be set because we always have an exclusive */
- if (eFileLock==SHARED_LOCK) {
- pFile->eFileLock = eFileLock;
- return SQLITE_OK;
- }
-
- /* no, really unlock. */
- if ( sem_post(pSem)==-1 ) {
- int rc, tErrno = errno;
- rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- return rc;
- }
- pFile->eFileLock = NO_LOCK;
- return SQLITE_OK;
-}
-
-/*
- ** Close a file.
- */
-static int semClose(sqlite3_file *id) {
- if( id ){
- unixFile *pFile = (unixFile*)id;
- semUnlock(id, NO_LOCK);
- assert( pFile );
- unixEnterMutex();
- releaseInodeInfo(pFile);
- unixLeaveMutex();
- closeUnixFile(id);
- }
- return SQLITE_OK;
-}
-
-#endif /* OS_VXWORKS */
-/*
-** Named semaphore locking is only available on VxWorks.
-**
-*************** End of the named semaphore lock implementation ****************
-******************************************************************************/
-
-
-/******************************************************************************
-*************************** Begin AFP Locking *********************************
-**
-** AFP is the Apple Filing Protocol. AFP is a network filesystem found
-** on Apple Macintosh computers - both OS9 and OSX.
-**
-** Third-party implementations of AFP are available. But this code here
-** only works on OSX.
-*/
-
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-/*
-** The afpLockingContext structure contains all afp lock specific state
-*/
-typedef struct afpLockingContext afpLockingContext;
-struct afpLockingContext {
- int reserved;
- const char *dbPath; /* Name of the open file */
-};
-
-struct ByteRangeLockPB2
-{
- unsigned long long offset; /* offset to first byte to lock */
- unsigned long long length; /* nbr of bytes to lock */
- unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */
- unsigned char unLockFlag; /* 1 = unlock, 0 = lock */
- unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */
- int fd; /* file desc to assoc this lock with */
-};
-
-#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2)
-
-/*
-** This is a utility for setting or clearing a bit-range lock on an
-** AFP filesystem.
-**
-** Return SQLITE_OK on success, SQLITE_BUSY on failure.
-*/
-static int afpSetLock(
- const char *path, /* Name of the file to be locked or unlocked */
- unixFile *pFile, /* Open file descriptor on path */
- unsigned long long offset, /* First byte to be locked */
- unsigned long long length, /* Number of bytes to lock */
- int setLockFlag /* True to set lock. False to clear lock */
-){
- struct ByteRangeLockPB2 pb;
- int err;
-
- pb.unLockFlag = setLockFlag ? 0 : 1;
- pb.startEndFlag = 0;
- pb.offset = offset;
- pb.length = length;
- pb.fd = pFile->h;
-
- OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n",
- (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""),
- offset, length));
- err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0);
- if ( err==-1 ) {
- int rc;
- int tErrno = errno;
- OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n",
- path, tErrno, strerror(tErrno)));
-#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
- rc = SQLITE_BUSY;
-#else
- rc = sqliteErrorFromPosixError(tErrno,
- setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
-#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
- if( IS_LOCK_ERROR(rc) ){
- pFile->lastErrno = tErrno;
- }
- return rc;
- } else {
- return SQLITE_OK;
- }
-}
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc = SQLITE_OK;
- int reserved = 0;
- unixFile *pFile = (unixFile*)id;
- afpLockingContext *context;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( pFile );
- context = (afpLockingContext *) pFile->lockingContext;
- if( context->reserved ){
- *pResOut = 1;
- return SQLITE_OK;
- }
- unixEnterMutex(); /* Because pFile->pInode is shared across threads */
-
- /* Check if a thread in this process holds such a lock */
- if( pFile->pInode->eFileLock>SHARED_LOCK ){
- reserved = 1;
- }
-
- /* Otherwise see if some other process holds it.
- */
- if( !reserved ){
- /* lock the RESERVED byte */
- int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);
- if( SQLITE_OK==lrc ){
- /* if we succeeded in taking the reserved lock, unlock it to restore
- ** the original state */
- lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0);
- } else {
- /* if we failed to get the lock then someone else must have it */
- reserved = 1;
- }
- if( IS_LOCK_ERROR(lrc) ){
- rc=lrc;
- }
- }
-
- unixLeaveMutex();
- OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved));
-
- *pResOut = reserved;
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter eFileLock - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int afpLock(sqlite3_file *id, int eFileLock){
- int rc = SQLITE_OK;
- unixFile *pFile = (unixFile*)id;
- unixInodeInfo *pInode = pFile->pInode;
- afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
-
- assert( pFile );
- OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h,
- azFileLock(eFileLock), azFileLock(pFile->eFileLock),
- azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
-
- /* If there is already a lock of this type or more restrictive on the
- ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
- ** unixEnterMutex() hasn't been called yet.
- */
- if( pFile->eFileLock>=eFileLock ){
- OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h,
- azFileLock(eFileLock)));
- return SQLITE_OK;
- }
-
- /* Make sure the locking sequence is correct
- ** (1) We never move from unlocked to anything higher than shared lock.
- ** (2) SQLite never explicitly requests a pendig lock.
- ** (3) A shared lock is always held when a reserve lock is requested.
- */
- assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
- assert( eFileLock!=PENDING_LOCK );
- assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );
-
- /* This mutex is needed because pFile->pInode is shared across threads
- */
- unixEnterMutex();
- pInode = pFile->pInode;
-
- /* If some thread using this PID has a lock via a different unixFile*
- ** handle that precludes the requested lock, return BUSY.
- */
- if( (pFile->eFileLock!=pInode->eFileLock &&
- (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK))
- ){
- rc = SQLITE_BUSY;
- goto afp_end_lock;
- }
-
- /* If a SHARED lock is requested, and some thread using this PID already
- ** has a SHARED or RESERVED lock, then increment reference counts and
- ** return SQLITE_OK.
- */
- if( eFileLock==SHARED_LOCK &&
- (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){
- assert( eFileLock==SHARED_LOCK );
- assert( pFile->eFileLock==0 );
- assert( pInode->nShared>0 );
- pFile->eFileLock = SHARED_LOCK;
- pInode->nShared++;
- pInode->nLock++;
- goto afp_end_lock;
- }
-
- /* A PENDING lock is needed before acquiring a SHARED lock and before
- ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will
- ** be released.
- */
- if( eFileLock==SHARED_LOCK
- || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
- ){
- int failed;
- failed = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 1);
- if (failed) {
- rc = failed;
- goto afp_end_lock;
- }
- }
-
- /* If control gets to this point, then actually go ahead and make
- ** operating system calls for the specified lock.
- */
- if( eFileLock==SHARED_LOCK ){
- int lrc1, lrc2, lrc1Errno = 0;
- long lk, mask;
-
- assert( pInode->nShared==0 );
- assert( pInode->eFileLock==0 );
-
- mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff;
- /* Now get the read-lock SHARED_LOCK */
- /* note that the quality of the randomness doesn't matter that much */
- lk = random();
- pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1);
- lrc1 = afpSetLock(context->dbPath, pFile,
- SHARED_FIRST+pInode->sharedByte, 1, 1);
- if( IS_LOCK_ERROR(lrc1) ){
- lrc1Errno = pFile->lastErrno;
- }
- /* Drop the temporary PENDING lock */
- lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
-
- if( IS_LOCK_ERROR(lrc1) ) {
- pFile->lastErrno = lrc1Errno;
- rc = lrc1;
- goto afp_end_lock;
- } else if( IS_LOCK_ERROR(lrc2) ){
- rc = lrc2;
- goto afp_end_lock;
- } else if( lrc1 != SQLITE_OK ) {
- rc = lrc1;
- } else {
- pFile->eFileLock = SHARED_LOCK;
- pInode->nLock++;
- pInode->nShared = 1;
- }
- }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
- /* We are trying for an exclusive lock but another thread in this
- ** same process is still holding a shared lock. */
- rc = SQLITE_BUSY;
- }else{
- /* The request was for a RESERVED or EXCLUSIVE lock. It is
- ** assumed that there is a SHARED or greater lock on the file
- ** already.
- */
- int failed = 0;
- assert( 0!=pFile->eFileLock );
- if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) {
- /* Acquire a RESERVED lock */
- failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);
- if( !failed ){
- context->reserved = 1;
- }
- }
- if (!failed && eFileLock == EXCLUSIVE_LOCK) {
- /* Acquire an EXCLUSIVE lock */
-
- /* Remove the shared lock before trying the range. we'll need to
- ** reestablish the shared lock if we can't get the afpUnlock
- */
- if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST +
- pInode->sharedByte, 1, 0)) ){
- int failed2 = SQLITE_OK;
- /* now attemmpt to get the exclusive lock range */
- failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST,
- SHARED_SIZE, 1);
- if( failed && (failed2 = afpSetLock(context->dbPath, pFile,
- SHARED_FIRST + pInode->sharedByte, 1, 1)) ){
- /* Can't reestablish the shared lock. Sqlite can't deal, this is
- ** a critical I/O error
- */
- rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 :
- SQLITE_IOERR_LOCK;
- goto afp_end_lock;
- }
- }else{
- rc = failed;
- }
- }
- if( failed ){
- rc = failed;
- }
- }
-
- if( rc==SQLITE_OK ){
- pFile->eFileLock = eFileLock;
- pInode->eFileLock = eFileLock;
- }else if( eFileLock==EXCLUSIVE_LOCK ){
- pFile->eFileLock = PENDING_LOCK;
- pInode->eFileLock = PENDING_LOCK;
- }
-
-afp_end_lock:
- unixLeaveMutex();
- OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock),
- rc==SQLITE_OK ? "ok" : "failed"));
- return rc;
-}
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int afpUnlock(sqlite3_file *id, int eFileLock) {
- int rc = SQLITE_OK;
- unixFile *pFile = (unixFile*)id;
- unixInodeInfo *pInode;
- afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
- int skipShared = 0;
-#ifdef SQLITE_TEST
- int h = pFile->h;
-#endif
-
- assert( pFile );
- OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock,
- pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
- getpid()));
-
- assert( eFileLock<=SHARED_LOCK );
- if( pFile->eFileLock<=eFileLock ){
- return SQLITE_OK;
- }
- unixEnterMutex();
- pInode = pFile->pInode;
- assert( pInode->nShared!=0 );
- if( pFile->eFileLock>SHARED_LOCK ){
- assert( pInode->eFileLock==pFile->eFileLock );
- SimulateIOErrorBenign(1);
- SimulateIOError( h=(-1) )
- SimulateIOErrorBenign(0);
-
-#ifdef SQLITE_DEBUG
- /* When reducing a lock such that other processes can start
- ** reading the database file again, make sure that the
- ** transaction counter was updated if any part of the database
- ** file changed. If the transaction counter is not updated,
- ** other connections to the same file might not realize that
- ** the file has changed and hence might not know to flush their
- ** cache. The use of a stale cache can lead to database corruption.
- */
- assert( pFile->inNormalWrite==0
- || pFile->dbUpdate==0
- || pFile->transCntrChng==1 );
- pFile->inNormalWrite = 0;
-#endif
-
- if( pFile->eFileLock==EXCLUSIVE_LOCK ){
- rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0);
- if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){
- /* only re-establish the shared lock if necessary */
- int sharedLockByte = SHARED_FIRST+pInode->sharedByte;
- rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1);
- } else {
- skipShared = 1;
- }
- }
- if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){
- rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
- }
- if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){
- rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0);
- if( !rc ){
- context->reserved = 0;
- }
- }
- if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){
- pInode->eFileLock = SHARED_LOCK;
- }
- }
- if( rc==SQLITE_OK && eFileLock==NO_LOCK ){
-
- /* Decrement the shared lock counter. Release the lock using an
- ** OS call only when all threads in this same process have released
- ** the lock.
- */
- unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte;
- pInode->nShared--;
- if( pInode->nShared==0 ){
- SimulateIOErrorBenign(1);
- SimulateIOError( h=(-1) )
- SimulateIOErrorBenign(0);
- if( !skipShared ){
- rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0);
- }
- if( !rc ){
- pInode->eFileLock = NO_LOCK;
- pFile->eFileLock = NO_LOCK;
- }
- }
- if( rc==SQLITE_OK ){
- pInode->nLock--;
- assert( pInode->nLock>=0 );
- if( pInode->nLock==0 ){
- closePendingFds(pFile);
- }
- }
- }
-
- unixLeaveMutex();
- if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
- return rc;
-}
-
-/*
-** Close a file & cleanup AFP specific locking context
-*/
-static int afpClose(sqlite3_file *id) {
- int rc = SQLITE_OK;
- if( id ){
- unixFile *pFile = (unixFile*)id;
- afpUnlock(id, NO_LOCK);
- unixEnterMutex();
- if( pFile->pInode && pFile->pInode->nLock ){
- /* If there are outstanding locks, do not actually close the file just
- ** yet because that would clear those locks. Instead, add the file
- ** descriptor to pInode->aPending. It will be automatically closed when
- ** the last lock is cleared.
- */
- setPendingFd(pFile);
- }
- releaseInodeInfo(pFile);
- sqlite3_free(pFile->lockingContext);
- rc = closeUnixFile(id);
- unixLeaveMutex();
- }
- return rc;
-}
-
-#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-/*
-** The code above is the AFP lock implementation. The code is specific
-** to MacOSX and does not work on other unix platforms. No alternative
-** is available. If you don't compile for a mac, then the "unix-afp"
-** VFS is not available.
-**
-********************* End of the AFP lock implementation **********************
-******************************************************************************/
-
-/******************************************************************************
-*************************** Begin NFS Locking ********************************/
-
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-/*
- ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
- ** must be either NO_LOCK or SHARED_LOCK.
- **
- ** If the locking level of the file descriptor is already at or below
- ** the requested locking level, this routine is a no-op.
- */
-static int nfsUnlock(sqlite3_file *id, int eFileLock){
- return posixUnlock(id, eFileLock, 1);
-}
-
-#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-/*
-** The code above is the NFS lock implementation. The code is specific
-** to MacOSX and does not work on other unix platforms. No alternative
-** is available.
-**
-********************* End of the NFS lock implementation **********************
-******************************************************************************/
-
-/******************************************************************************
-**************** Non-locking sqlite3_file methods *****************************
-**
-** The next division contains implementations for all methods of the
-** sqlite3_file object other than the locking methods. The locking
-** methods were defined in divisions above (one locking method per
-** division). Those methods that are common to all locking modes
-** are gather together into this division.
-*/
-
-/*
-** Seek to the offset passed as the second argument, then read cnt
-** bytes into pBuf. Return the number of bytes actually read.
-**
-** NB: If you define USE_PREAD or USE_PREAD64, then it might also
-** be necessary to define _XOPEN_SOURCE to be 500. This varies from
-** one system to another. Since SQLite does not define USE_PREAD
-** any any form by default, we will not attempt to define _XOPEN_SOURCE.
-** See tickets #2741 and #2681.
-**
-** To avoid stomping the errno value on a failed read the lastErrno value
-** is set before returning.
-*/
-static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
- int got;
- int prior = 0;
-#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
- i64 newOffset;
-#endif
- TIMER_START;
- assert( cnt==(cnt&0x1ffff) );
- cnt &= 0x1ffff;
- do{
-#if defined(USE_PREAD)
- got = osPread(id->h, pBuf, cnt, offset);
- SimulateIOError( got = -1 );
-#elif defined(USE_PREAD64)
- got = osPread64(id->h, pBuf, cnt, offset);
- SimulateIOError( got = -1 );
-#else
- newOffset = lseek(id->h, offset, SEEK_SET);
- SimulateIOError( newOffset-- );
- if( newOffset!=offset ){
- if( newOffset == -1 ){
- ((unixFile*)id)->lastErrno = errno;
- }else{
- ((unixFile*)id)->lastErrno = 0;
- }
- return -1;
- }
- got = osRead(id->h, pBuf, cnt);
-#endif
- if( got==cnt ) break;
- if( got<0 ){
- if( errno==EINTR ){ got = 1; continue; }
- prior = 0;
- ((unixFile*)id)->lastErrno = errno;
- break;
- }else if( got>0 ){
- cnt -= got;
- offset += got;
- prior += got;
- pBuf = (void*)(got + (char*)pBuf);
- }
- }while( got>0 );
- TIMER_END;
- OSTRACE(("READ %-3d %5d %7lld %llu\n",
- id->h, got+prior, offset-prior, TIMER_ELAPSED));
- return got+prior;
-}
-
-/*
-** Read data from a file into a buffer. Return SQLITE_OK if all
-** bytes were read successfully and SQLITE_IOERR if anything goes
-** wrong.
-*/
-static int unixRead(
- sqlite3_file *id,
- void *pBuf,
- int amt,
- sqlite3_int64 offset
-){
- unixFile *pFile = (unixFile *)id;
- int got;
- assert( id );
-
- /* If this is a database file (not a journal, master-journal or temp
- ** file), the bytes in the locking range should never be read or written. */
-#if 0
- assert( pFile->pUnused==0
- || offset>=PENDING_BYTE+512
- || offset+amt<=PENDING_BYTE
- );
-#endif
-
- got = seekAndRead(pFile, offset, pBuf, amt);
- if( got==amt ){
- return SQLITE_OK;
- }else if( got<0 ){
- /* lastErrno set by seekAndRead */
- return SQLITE_IOERR_READ;
- }else{
- pFile->lastErrno = 0; /* not a system error */
- /* Unread parts of the buffer must be zero-filled */
- memset(&((char*)pBuf)[got], 0, amt-got);
- return SQLITE_IOERR_SHORT_READ;
- }
-}
-
-/*
-** Seek to the offset in id->offset then read cnt bytes into pBuf.
-** Return the number of bytes actually read. Update the offset.
-**
-** To avoid stomping the errno value on a failed write the lastErrno value
-** is set before returning.
-*/
-static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
- int got;
-#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
- i64 newOffset;
-#endif
- assert( cnt==(cnt&0x1ffff) );
- cnt &= 0x1ffff;
- TIMER_START;
-#if defined(USE_PREAD)
- do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
-#elif defined(USE_PREAD64)
- do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR);
-#else
- do{
- newOffset = lseek(id->h, offset, SEEK_SET);
- SimulateIOError( newOffset-- );
- if( newOffset!=offset ){
- if( newOffset == -1 ){
- ((unixFile*)id)->lastErrno = errno;
- }else{
- ((unixFile*)id)->lastErrno = 0;
- }
- return -1;
- }
- got = osWrite(id->h, pBuf, cnt);
- }while( got<0 && errno==EINTR );
-#endif
- TIMER_END;
- if( got<0 ){
- ((unixFile*)id)->lastErrno = errno;
- }
-
- OSTRACE(("WRITE %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
- return got;
-}
-
-
-/*
-** Write data from a buffer into a file. Return SQLITE_OK on success
-** or some other error code on failure.
-*/
-static int unixWrite(
- sqlite3_file *id,
- const void *pBuf,
- int amt,
- sqlite3_int64 offset
-){
- unixFile *pFile = (unixFile*)id;
- int wrote = 0;
- assert( id );
- assert( amt>0 );
-
- /* If this is a database file (not a journal, master-journal or temp
- ** file), the bytes in the locking range should never be read or written. */
-#if 0
- assert( pFile->pUnused==0
- || offset>=PENDING_BYTE+512
- || offset+amt<=PENDING_BYTE
- );
-#endif
-
-#ifdef SQLITE_DEBUG
- /* If we are doing a normal write to a database file (as opposed to
- ** doing a hot-journal rollback or a write to some file other than a
- ** normal database file) then record the fact that the database
- ** has changed. If the transaction counter is modified, record that
- ** fact too.
- */
- if( pFile->inNormalWrite ){
- pFile->dbUpdate = 1; /* The database has been modified */
- if( offset<=24 && offset+amt>=27 ){
- int rc;
- char oldCntr[4];
- SimulateIOErrorBenign(1);
- rc = seekAndRead(pFile, 24, oldCntr, 4);
- SimulateIOErrorBenign(0);
- if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){
- pFile->transCntrChng = 1; /* The transaction counter has changed */
- }
- }
- }
-#endif
-
- while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
- amt -= wrote;
- offset += wrote;
- pBuf = &((char*)pBuf)[wrote];
- }
- SimulateIOError(( wrote=(-1), amt=1 ));
- SimulateDiskfullError(( wrote=0, amt=1 ));
-
- if( amt>0 ){
- if( wrote<0 && pFile->lastErrno!=ENOSPC ){
- /* lastErrno set by seekAndWrite */
- return SQLITE_IOERR_WRITE;
- }else{
- pFile->lastErrno = 0; /* not a system error */
- return SQLITE_FULL;
- }
- }
-
- return SQLITE_OK;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Count the number of fullsyncs and normal syncs. This is used to test
-** that syncs and fullsyncs are occurring at the right times.
-*/
-SQLITE_API int sqlite3_sync_count = 0;
-SQLITE_API int sqlite3_fullsync_count = 0;
-#endif
-
-/*
-** We do not trust systems to provide a working fdatasync(). Some do.
-** Others do no. To be safe, we will stick with the (slightly slower)
-** fsync(). If you know that your system does support fdatasync() correctly,
-** then simply compile with -Dfdatasync=fdatasync
-*/
-#if !defined(fdatasync)
-# define fdatasync fsync
-#endif
-
-/*
-** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
-** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently
-** only available on Mac OS X. But that could change.
-*/
-#ifdef F_FULLFSYNC
-# define HAVE_FULLFSYNC 1
-#else
-# define HAVE_FULLFSYNC 0
-#endif
-
-
-/*
-** The fsync() system call does not work as advertised on many
-** unix systems. The following procedure is an attempt to make
-** it work better.
-**
-** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful
-** for testing when we want to run through the test suite quickly.
-** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
-** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
-** or power failure will likely corrupt the database file.
-**
-** SQLite sets the dataOnly flag if the size of the file is unchanged.
-** The idea behind dataOnly is that it should only write the file content
-** to disk, not the inode. We only set dataOnly if the file size is
-** unchanged since the file size is part of the inode. However,
-** Ted Ts'o tells us that fdatasync() will also write the inode if the
-** file size has changed. The only real difference between fdatasync()
-** and fsync(), Ted tells us, is that fdatasync() will not flush the
-** inode if the mtime or owner or other inode attributes have changed.
-** We only care about the file size, not the other file attributes, so
-** as far as SQLite is concerned, an fdatasync() is always adequate.
-** So, we always use fdatasync() if it is available, regardless of
-** the value of the dataOnly flag.
-*/
-static int full_fsync(int fd, int fullSync, int dataOnly){
- int rc;
-
- /* The following "ifdef/elif/else/" block has the same structure as
- ** the one below. It is replicated here solely to avoid cluttering
- ** up the real code with the UNUSED_PARAMETER() macros.
- */
-#ifdef SQLITE_NO_SYNC
- UNUSED_PARAMETER(fd);
- UNUSED_PARAMETER(fullSync);
- UNUSED_PARAMETER(dataOnly);
-#elif HAVE_FULLFSYNC
- UNUSED_PARAMETER(dataOnly);
-#else
- UNUSED_PARAMETER(fullSync);
- UNUSED_PARAMETER(dataOnly);
-#endif
-
- /* Record the number of times that we do a normal fsync() and
- ** FULLSYNC. This is used during testing to verify that this procedure
- ** gets called with the correct arguments.
- */
-#ifdef SQLITE_TEST
- if( fullSync ) sqlite3_fullsync_count++;
- sqlite3_sync_count++;
-#endif
-
- /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
- ** no-op
- */
-#ifdef SQLITE_NO_SYNC
- rc = SQLITE_OK;
-#elif HAVE_FULLFSYNC
- if( fullSync ){
- rc = osFcntl(fd, F_FULLFSYNC, 0);
- }else{
- rc = 1;
- }
- /* If the FULLFSYNC failed, fall back to attempting an fsync().
- ** It shouldn't be possible for fullfsync to fail on the local
- ** file system (on OSX), so failure indicates that FULLFSYNC
- ** isn't supported for this file system. So, attempt an fsync
- ** and (for now) ignore the overhead of a superfluous fcntl call.
- ** It'd be better to detect fullfsync support once and avoid
- ** the fcntl call every time sync is called.
- */
- if( rc ) rc = fsync(fd);
-
-#elif defined(__APPLE__)
- /* fdatasync() on HFS+ doesn't yet flush the file size if it changed correctly
- ** so currently we default to the macro that redefines fdatasync to fsync
- */
- rc = fsync(fd);
-#else
- rc = fdatasync(fd);
-#if OS_VXWORKS
- if( rc==-1 && errno==ENOTSUP ){
- rc = fsync(fd);
- }
-#endif /* OS_VXWORKS */
-#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */
-
- if( OS_VXWORKS && rc!= -1 ){
- rc = 0;
- }
- return rc;
-}
-
-/*
-** Open a file descriptor to the directory containing file zFilename.
-** If successful, *pFd is set to the opened file descriptor and
-** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
-** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
-** value.
-**
-** The directory file descriptor is used for only one thing - to
-** fsync() a directory to make sure file creation and deletion events
-** are flushed to disk. Such fsyncs are not needed on newer
-** journaling filesystems, but are required on older filesystems.
-**
-** This routine can be overridden using the xSetSysCall interface.
-** The ability to override this routine was added in support of the
-** chromium sandbox. Opening a directory is a security risk (we are
-** told) so making it overrideable allows the chromium sandbox to
-** replace this routine with a harmless no-op. To make this routine
-** a no-op, replace it with a stub that returns SQLITE_OK but leaves
-** *pFd set to a negative number.
-**
-** If SQLITE_OK is returned, the caller is responsible for closing
-** the file descriptor *pFd using close().
-*/
-static int openDirectory(const char *zFilename, int *pFd){
- int ii;
- int fd = -1;
- char zDirname[MAX_PATHNAME+1];
-
- sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
- for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
- if( ii>0 ){
- zDirname[ii] = '\0';
- fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
- if( fd>=0 ){
- OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
- }
- }
- *pFd = fd;
- return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
-}
-
-/*
-** Make sure all writes to a particular file are committed to disk.
-**
-** If dataOnly==0 then both the file itself and its metadata (file
-** size, access time, etc) are synced. If dataOnly!=0 then only the
-** file data is synced.
-**
-** Under Unix, also make sure that the directory entry for the file
-** has been created by fsync-ing the directory that contains the file.
-** If we do not do this and we encounter a power failure, the directory
-** entry for the journal might not exist after we reboot. The next
-** SQLite to access the file will not know that the journal exists (because
-** the directory entry for the journal was never created) and the transaction
-** will not roll back - possibly leading to database corruption.
-*/
-static int unixSync(sqlite3_file *id, int flags){
- int rc;
- unixFile *pFile = (unixFile*)id;
-
- int isDataOnly = (flags&SQLITE_SYNC_DATAONLY);
- int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL;
-
- /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
- assert((flags&0x0F)==SQLITE_SYNC_NORMAL
- || (flags&0x0F)==SQLITE_SYNC_FULL
- );
-
- /* Unix cannot, but some systems may return SQLITE_FULL from here. This
- ** line is to test that doing so does not cause any problems.
- */
- SimulateDiskfullError( return SQLITE_FULL );
-
- assert( pFile );
- OSTRACE(("SYNC %-3d\n", pFile->h));
- rc = full_fsync(pFile->h, isFullsync, isDataOnly);
- SimulateIOError( rc=1 );
- if( rc ){
- pFile->lastErrno = errno;
- return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
- }
-
- /* Also fsync the directory containing the file if the DIRSYNC flag
- ** is set. This is a one-time occurrance. Many systems (examples: AIX)
- ** are unable to fsync a directory, so ignore errors on the fsync.
- */
- if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){
- int dirfd;
- OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
- HAVE_FULLFSYNC, isFullsync));
- rc = osOpenDirectory(pFile->zPath, &dirfd);
- if( rc==SQLITE_OK && dirfd>=0 ){
- full_fsync(dirfd, 0, 0);
- robust_close(pFile, dirfd, __LINE__);
- }else if( rc==SQLITE_CANTOPEN ){
- rc = SQLITE_OK;
- }
- pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
- }
- return rc;
-}
-
-/*
-** Truncate an open file to a specified size
-*/
-static int unixTruncate(sqlite3_file *id, i64 nByte){
- unixFile *pFile = (unixFile *)id;
- int rc;
- assert( pFile );
- SimulateIOError( return SQLITE_IOERR_TRUNCATE );
-
- /* If the user has configured a chunk-size for this file, truncate the
- ** file so that it consists of an integer number of chunks (i.e. the
- ** actual file size after the operation may be larger than the requested
- ** size).
- */
- if( pFile->szChunk>0 ){
- nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
- }
-
- rc = robust_ftruncate(pFile->h, (off_t)nByte);
- if( rc ){
- pFile->lastErrno = errno;
- return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
- }else{
-#ifdef SQLITE_DEBUG
- /* If we are doing a normal write to a database file (as opposed to
- ** doing a hot-journal rollback or a write to some file other than a
- ** normal database file) and we truncate the file to zero length,
- ** that effectively updates the change counter. This might happen
- ** when restoring a database using the backup API from a zero-length
- ** source.
- */
- if( pFile->inNormalWrite && nByte==0 ){
- pFile->transCntrChng = 1;
- }
-#endif
-
- return SQLITE_OK;
- }
-}
-
-/*
-** Determine the current size of a file in bytes
-*/
-static int unixFileSize(sqlite3_file *id, i64 *pSize){
- int rc;
- struct stat buf;
- assert( id );
- rc = osFstat(((unixFile*)id)->h, &buf);
- SimulateIOError( rc=1 );
- if( rc!=0 ){
- ((unixFile*)id)->lastErrno = errno;
- return SQLITE_IOERR_FSTAT;
- }
- *pSize = buf.st_size;
-
- /* When opening a zero-size database, the findInodeInfo() procedure
- ** writes a single byte into that file in order to work around a bug
- ** in the OS-X msdos filesystem. In order to avoid problems with upper
- ** layers, we need to report this file size as zero even though it is
- ** really 1. Ticket #3260.
- */
- if( *pSize==1 ) *pSize = 0;
-
-
- return SQLITE_OK;
-}
-
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-/*
-** Handler for proxy-locking file-control verbs. Defined below in the
-** proxying locking division.
-*/
-static int proxyFileControl(sqlite3_file*,int,void*);
-#endif
-
-/*
-** This function is called to handle the SQLITE_FCNTL_SIZE_HINT
-** file-control operation. Enlarge the database to nBytes in size
-** (rounded up to the next chunk-size). If the database is already
-** nBytes or larger, this routine is a no-op.
-*/
-static int fcntlSizeHint(unixFile *pFile, i64 nByte){
- if( pFile->szChunk>0 ){
- i64 nSize; /* Required file size */
- struct stat buf; /* Used to hold return values of fstat() */
-
- if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
-
- nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
- if( nSize>(i64)buf.st_size ){
-
-#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
- /* The code below is handling the return value of osFallocate()
- ** correctly. posix_fallocate() is defined to "returns zero on success,
- ** or an error number on failure". See the manpage for details. */
- int err;
- do{
- err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size);
- }while( err==EINTR );
- if( err ) return SQLITE_IOERR_WRITE;
-#else
- /* If the OS does not have posix_fallocate(), fake it. First use
- ** ftruncate() to set the file size, then write a single byte to
- ** the last byte in each block within the extended region. This
- ** is the same technique used by glibc to implement posix_fallocate()
- ** on systems that do not have a real fallocate() system call.
- */
- int nBlk = buf.st_blksize; /* File-system block size */
- i64 iWrite; /* Next offset to write to */
-
- if( robust_ftruncate(pFile->h, nSize) ){
- pFile->lastErrno = errno;
- return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
- }
- iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
- while( iWrite<nSize ){
- int nWrite = seekAndWrite(pFile, iWrite, "", 1);
- if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
- iWrite += nBlk;
- }
-#endif
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** If *pArg is inititially negative then this is a query. Set *pArg to
-** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
-**
-** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
-*/
-static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){
- if( *pArg<0 ){
- *pArg = (pFile->ctrlFlags & mask)!=0;
- }else if( (*pArg)==0 ){
- pFile->ctrlFlags &= ~mask;
- }else{
- pFile->ctrlFlags |= mask;
- }
-}
-
-/* Forward declaration */
-static int unixGetTempname(int nBuf, char *zBuf);
-
-/*
-** Information and control of an open file handle.
-*/
-static int unixFileControl(sqlite3_file *id, int op, void *pArg){
- unixFile *pFile = (unixFile*)id;
- switch( op ){
- case SQLITE_FCNTL_LOCKSTATE: {
- *(int*)pArg = pFile->eFileLock;
- return SQLITE_OK;
- }
- case SQLITE_LAST_ERRNO: {
- *(int*)pArg = pFile->lastErrno;
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_CHUNK_SIZE: {
- pFile->szChunk = *(int *)pArg;
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_SIZE_HINT: {
- int rc;
- SimulateIOErrorBenign(1);
- rc = fcntlSizeHint(pFile, *(i64 *)pArg);
- SimulateIOErrorBenign(0);
- return rc;
- }
- case SQLITE_FCNTL_PERSIST_WAL: {
- unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg);
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
- unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_VFSNAME: {
- *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_TEMPFILENAME: {
- char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
- if( zTFile ){
- unixGetTempname(pFile->pVfs->mxPathname, zTFile);
- *(char**)pArg = zTFile;
- }
- return SQLITE_OK;
- }
-#ifdef SQLITE_DEBUG
- /* The pager calls this method to signal that it has done
- ** a rollback and that the database is therefore unchanged and
- ** it hence it is OK for the transaction change counter to be
- ** unchanged.
- */
- case SQLITE_FCNTL_DB_UNCHANGED: {
- ((unixFile*)id)->dbUpdate = 0;
- return SQLITE_OK;
- }
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- case SQLITE_SET_LOCKPROXYFILE:
- case SQLITE_GET_LOCKPROXYFILE: {
- return proxyFileControl(id,op,pArg);
- }
-#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
- }
- return SQLITE_NOTFOUND;
-}
-
-/*
-** Return the sector size in bytes of the underlying block device for
-** the specified file. This is almost always 512 bytes, but may be
-** larger for some devices.
-**
-** SQLite code assumes this function cannot fail. It also assumes that
-** if two files are created in the same file-system directory (i.e.
-** a database and its journal file) that the sector size will be the
-** same for both.
-*/
-#ifndef __QNXNTO__
-static int unixSectorSize(sqlite3_file *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- return SQLITE_DEFAULT_SECTOR_SIZE;
-}
-#endif
-
-/*
-** The following version of unixSectorSize() is optimized for QNX.
-*/
-#ifdef __QNXNTO__
-#include <sys/dcmd_blk.h>
-#include <sys/statvfs.h>
-static int unixSectorSize(sqlite3_file *id){
- unixFile *pFile = (unixFile*)id;
- if( pFile->sectorSize == 0 ){
- struct statvfs fsInfo;
-
- /* Set defaults for non-supported filesystems */
- pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
- pFile->deviceCharacteristics = 0;
- if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
- return pFile->sectorSize;
- }
-
- if( !strcmp(fsInfo.f_basetype, "tmp") ) {
- pFile->sectorSize = fsInfo.f_bsize;
- pFile->deviceCharacteristics =
- SQLITE_IOCAP_ATOMIC4K | /* All ram filesystem writes are atomic */
- SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until
- ** the write succeeds */
- SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
- ** so it is ordered */
- 0;
- }else if( strstr(fsInfo.f_basetype, "etfs") ){
- pFile->sectorSize = fsInfo.f_bsize;
- pFile->deviceCharacteristics =
- /* etfs cluster size writes are atomic */
- (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) |
- SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until
- ** the write succeeds */
- SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
- ** so it is ordered */
- 0;
- }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){
- pFile->sectorSize = fsInfo.f_bsize;
- pFile->deviceCharacteristics =
- SQLITE_IOCAP_ATOMIC | /* All filesystem writes are atomic */
- SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until
- ** the write succeeds */
- SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
- ** so it is ordered */
- 0;
- }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){
- pFile->sectorSize = fsInfo.f_bsize;
- pFile->deviceCharacteristics =
- /* full bitset of atomics from max sector size and smaller */
- ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
- SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
- ** so it is ordered */
- 0;
- }else if( strstr(fsInfo.f_basetype, "dos") ){
- pFile->sectorSize = fsInfo.f_bsize;
- pFile->deviceCharacteristics =
- /* full bitset of atomics from max sector size and smaller */
- ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
- SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind
- ** so it is ordered */
- 0;
- }else{
- pFile->deviceCharacteristics =
- SQLITE_IOCAP_ATOMIC512 | /* blocks are atomic */
- SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until
- ** the write succeeds */
- 0;
- }
- }
- /* Last chance verification. If the sector size isn't a multiple of 512
- ** then it isn't valid.*/
- if( pFile->sectorSize % 512 != 0 ){
- pFile->deviceCharacteristics = 0;
- pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
- }
- return pFile->sectorSize;
-}
-#endif /* __QNXNTO__ */
-
-/*
-** Return the device characteristics for the file.
-**
-** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
-** However, that choice is contraversial since technically the underlying
-** file system does not always provide powersafe overwrites. (In other
-** words, after a power-loss event, parts of the file that were never
-** written might end up being altered.) However, non-PSOW behavior is very,
-** very rare. And asserting PSOW makes a large reduction in the amount
-** of required I/O for journaling, since a lot of padding is eliminated.
-** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
-** available to turn it off and URI query parameter available to turn it off.
-*/
-static int unixDeviceCharacteristics(sqlite3_file *id){
- unixFile *p = (unixFile*)id;
- int rc = 0;
-#ifdef __QNXNTO__
- if( p->sectorSize==0 ) unixSectorSize(id);
- rc = p->deviceCharacteristics;
-#endif
- if( p->ctrlFlags & UNIXFILE_PSOW ){
- rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
- }
- return rc;
-}
-
-#ifndef SQLITE_OMIT_WAL
-
-
-/*
-** Object used to represent an shared memory buffer.
-**
-** When multiple threads all reference the same wal-index, each thread
-** has its own unixShm object, but they all point to a single instance
-** of this unixShmNode object. In other words, each wal-index is opened
-** only once per process.
-**
-** Each unixShmNode object is connected to a single unixInodeInfo object.
-** We could coalesce this object into unixInodeInfo, but that would mean
-** every open file that does not use shared memory (in other words, most
-** open files) would have to carry around this extra information. So
-** the unixInodeInfo object contains a pointer to this unixShmNode object
-** and the unixShmNode object is created only when needed.
-**
-** unixMutexHeld() must be true when creating or destroying
-** this object or while reading or writing the following fields:
-**
-** nRef
-**
-** The following fields are read-only after the object is created:
-**
-** fid
-** zFilename
-**
-** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
-** unixMutexHeld() is true when reading or writing any other field
-** in this structure.
-*/
-struct unixShmNode {
- unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
- sqlite3_mutex *mutex; /* Mutex to access this object */
- char *zFilename; /* Name of the mmapped file */
- int h; /* Open file descriptor */
- int szRegion; /* Size of shared-memory regions */
- u16 nRegion; /* Size of array apRegion */
- u8 isReadonly; /* True if read-only */
- char **apRegion; /* Array of mapped shared-memory regions */
- int nRef; /* Number of unixShm objects pointing to this */
- unixShm *pFirst; /* All unixShm objects pointing to this */
-#ifdef SQLITE_DEBUG
- u8 exclMask; /* Mask of exclusive locks held */
- u8 sharedMask; /* Mask of shared locks held */
- u8 nextShmId; /* Next available unixShm.id value */
-#endif
-};
-
-/*
-** Structure used internally by this VFS to record the state of an
-** open shared memory connection.
-**
-** The following fields are initialized when this object is created and
-** are read-only thereafter:
-**
-** unixShm.pFile
-** unixShm.id
-**
-** All other fields are read/write. The unixShm.pFile->mutex must be held
-** while accessing any read/write fields.
-*/
-struct unixShm {
- unixShmNode *pShmNode; /* The underlying unixShmNode object */
- unixShm *pNext; /* Next unixShm with the same unixShmNode */
- u8 hasMutex; /* True if holding the unixShmNode mutex */
- u8 id; /* Id of this connection within its unixShmNode */
- u16 sharedMask; /* Mask of shared locks held */
- u16 exclMask; /* Mask of exclusive locks held */
-};
-
-/*
-** Constants used for locking
-*/
-#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
-#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
-
-/*
-** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
-**
-** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
-** otherwise.
-*/
-static int unixShmSystemLock(
- unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */
- int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */
- int ofst, /* First byte of the locking range */
- int n /* Number of bytes to lock */
-){
- struct flock f; /* The posix advisory locking structure */
- int rc = SQLITE_OK; /* Result code form fcntl() */
-
- /* Access to the unixShmNode object is serialized by the caller */
- assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
-
- /* Shared locks never span more than one byte */
- assert( n==1 || lockType!=F_RDLCK );
-
- /* Locks are within range */
- assert( n>=1 && n<SQLITE_SHM_NLOCK );
-
- if( pShmNode->h>=0 ){
- /* Initialize the locking parameters */
- memset(&f, 0, sizeof(f));
- f.l_type = lockType;
- f.l_whence = SEEK_SET;
- f.l_start = ofst;
- f.l_len = n;
-
- rc = osFcntl(pShmNode->h, F_SETLK, &f);
- rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
- }
-
- /* Update the global lock state and do debug tracing */
-#ifdef SQLITE_DEBUG
- { u16 mask;
- OSTRACE(("SHM-LOCK "));
- mask = (1<<(ofst+n)) - (1<<ofst);
- if( rc==SQLITE_OK ){
- if( lockType==F_UNLCK ){
- OSTRACE(("unlock %d ok", ofst));
- pShmNode->exclMask &= ~mask;
- pShmNode->sharedMask &= ~mask;
- }else if( lockType==F_RDLCK ){
- OSTRACE(("read-lock %d ok", ofst));
- pShmNode->exclMask &= ~mask;
- pShmNode->sharedMask |= mask;
- }else{
- assert( lockType==F_WRLCK );
- OSTRACE(("write-lock %d ok", ofst));
- pShmNode->exclMask |= mask;
- pShmNode->sharedMask &= ~mask;
- }
- }else{
- if( lockType==F_UNLCK ){
- OSTRACE(("unlock %d failed", ofst));
- }else if( lockType==F_RDLCK ){
- OSTRACE(("read-lock failed"));
- }else{
- assert( lockType==F_WRLCK );
- OSTRACE(("write-lock %d failed", ofst));
- }
- }
- OSTRACE((" - afterwards %03x,%03x\n",
- pShmNode->sharedMask, pShmNode->exclMask));
- }
-#endif
-
- return rc;
-}
-
-
-/*
-** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
-**
-** This is not a VFS shared-memory method; it is a utility function called
-** by VFS shared-memory methods.
-*/
-static void unixShmPurge(unixFile *pFd){
- unixShmNode *p = pFd->pInode->pShmNode;
- assert( unixMutexHeld() );
- if( p && p->nRef==0 ){
- int i;
- assert( p->pInode==pFd->pInode );
- sqlite3_mutex_free(p->mutex);
- for(i=0; i<p->nRegion; i++){
- if( p->h>=0 ){
- munmap(p->apRegion[i], p->szRegion);
- }else{
- sqlite3_free(p->apRegion[i]);
- }
- }
- sqlite3_free(p->apRegion);
- if( p->h>=0 ){
- robust_close(pFd, p->h, __LINE__);
- p->h = -1;
- }
- p->pInode->pShmNode = 0;
- sqlite3_free(p);
- }
-}
-
-/*
-** Open a shared-memory area associated with open database file pDbFd.
-** This particular implementation uses mmapped files.
-**
-** The file used to implement shared-memory is in the same directory
-** as the open database file and has the same name as the open database
-** file with the "-shm" suffix added. For example, if the database file
-** is "/home/user1/config.db" then the file that is created and mmapped
-** for shared memory will be called "/home/user1/config.db-shm".
-**
-** Another approach to is to use files in /dev/shm or /dev/tmp or an
-** some other tmpfs mount. But if a file in a different directory
-** from the database file is used, then differing access permissions
-** or a chroot() might cause two different processes on the same
-** database to end up using different files for shared memory -
-** meaning that their memory would not really be shared - resulting
-** in database corruption. Nevertheless, this tmpfs file usage
-** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm"
-** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time
-** option results in an incompatible build of SQLite; builds of SQLite
-** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the
-** same database file at the same time, database corruption will likely
-** result. The SQLITE_SHM_DIRECTORY compile-time option is considered
-** "unsupported" and may go away in a future SQLite release.
-**
-** When opening a new shared-memory file, if no other instances of that
-** file are currently open, in this process or in other processes, then
-** the file must be truncated to zero length or have its header cleared.
-**
-** If the original database file (pDbFd) is using the "unix-excl" VFS
-** that means that an exclusive lock is held on the database file and
-** that no other processes are able to read or write the database. In
-** that case, we do not really need shared memory. No shared memory
-** file is created. The shared memory will be simulated with heap memory.
-*/
-static int unixOpenSharedMemory(unixFile *pDbFd){
- struct unixShm *p = 0; /* The connection to be opened */
- struct unixShmNode *pShmNode; /* The underlying mmapped file */
- int rc; /* Result code */
- unixInodeInfo *pInode; /* The inode of fd */
- char *zShmFilename; /* Name of the file used for SHM */
- int nShmFilename; /* Size of the SHM filename in bytes */
-
- /* Allocate space for the new unixShm object. */
- p = sqlite3_malloc( sizeof(*p) );
- if( p==0 ) return SQLITE_NOMEM;
- memset(p, 0, sizeof(*p));
- assert( pDbFd->pShm==0 );
-
- /* Check to see if a unixShmNode object already exists. Reuse an existing
- ** one if present. Create a new one if necessary.
- */
- unixEnterMutex();
- pInode = pDbFd->pInode;
- pShmNode = pInode->pShmNode;
- if( pShmNode==0 ){
- struct stat sStat; /* fstat() info for database file */
-
- /* Call fstat() to figure out the permissions on the database file. If
- ** a new *-shm file is created, an attempt will be made to create it
- ** with the same permissions.
- */
- if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
- rc = SQLITE_IOERR_FSTAT;
- goto shm_open_err;
- }
-
-#ifdef SQLITE_SHM_DIRECTORY
- nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
-#else
- nShmFilename = 6 + (int)strlen(pDbFd->zPath);
-#endif
- pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
- if( pShmNode==0 ){
- rc = SQLITE_NOMEM;
- goto shm_open_err;
- }
- memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
- zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1];
-#ifdef SQLITE_SHM_DIRECTORY
- sqlite3_snprintf(nShmFilename, zShmFilename,
- SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
- (u32)sStat.st_ino, (u32)sStat.st_dev);
-#else
- sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
- sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
-#endif
- pShmNode->h = -1;
- pDbFd->pInode->pShmNode = pShmNode;
- pShmNode->pInode = pDbFd->pInode;
- pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
- if( pShmNode->mutex==0 ){
- rc = SQLITE_NOMEM;
- goto shm_open_err;
- }
-
- if( pInode->bProcessLock==0 ){
- int openFlags = O_RDWR | O_CREAT;
- if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- openFlags = O_RDONLY;
- pShmNode->isReadonly = 1;
- }
- pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
- if( pShmNode->h<0 ){
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
- goto shm_open_err;
- }
-
- /* If this process is running as root, make sure that the SHM file
- ** is owned by the same user that owns the original database. Otherwise,
- ** the original owner will not be able to connect.
- */
- osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
-
- /* Check to see if another process is holding the dead-man switch.
- ** If not, truncate the file to zero length.
- */
- rc = SQLITE_OK;
- if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
- if( robust_ftruncate(pShmNode->h, 0) ){
- rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
- }
- }
- if( rc==SQLITE_OK ){
- rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
- }
- if( rc ) goto shm_open_err;
- }
- }
-
- /* Make the new connection a child of the unixShmNode */
- p->pShmNode = pShmNode;
-#ifdef SQLITE_DEBUG
- p->id = pShmNode->nextShmId++;
-#endif
- pShmNode->nRef++;
- pDbFd->pShm = p;
- unixLeaveMutex();
-
- /* The reference count on pShmNode has already been incremented under
- ** the cover of the unixEnterMutex() mutex and the pointer from the
- ** new (struct unixShm) object to the pShmNode has been set. All that is
- ** left to do is to link the new object into the linked list starting
- ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
- ** mutex.
- */
- sqlite3_mutex_enter(pShmNode->mutex);
- p->pNext = pShmNode->pFirst;
- pShmNode->pFirst = p;
- sqlite3_mutex_leave(pShmNode->mutex);
- return SQLITE_OK;
-
- /* Jump here on any error */
-shm_open_err:
- unixShmPurge(pDbFd); /* This call frees pShmNode if required */
- sqlite3_free(p);
- unixLeaveMutex();
- return rc;
-}
-
-/*
-** This function is called to obtain a pointer to region iRegion of the
-** shared-memory associated with the database file fd. Shared-memory regions
-** are numbered starting from zero. Each shared-memory region is szRegion
-** bytes in size.
-**
-** If an error occurs, an error code is returned and *pp is set to NULL.
-**
-** Otherwise, if the bExtend parameter is 0 and the requested shared-memory
-** region has not been allocated (by any client, including one running in a
-** separate process), then *pp is set to NULL and SQLITE_OK returned. If
-** bExtend is non-zero and the requested shared-memory region has not yet
-** been allocated, it is allocated by this function.
-**
-** If the shared-memory region has already been allocated or is allocated by
-** this call as described above, then it is mapped into this processes
-** address space (if it is not already), *pp is set to point to the mapped
-** memory and SQLITE_OK returned.
-*/
-static int unixShmMap(
- sqlite3_file *fd, /* Handle open on database file */
- int iRegion, /* Region to retrieve */
- int szRegion, /* Size of regions */
- int bExtend, /* True to extend file if necessary */
- void volatile **pp /* OUT: Mapped memory */
-){
- unixFile *pDbFd = (unixFile*)fd;
- unixShm *p;
- unixShmNode *pShmNode;
- int rc = SQLITE_OK;
-
- /* If the shared-memory file has not yet been opened, open it now. */
- if( pDbFd->pShm==0 ){
- rc = unixOpenSharedMemory(pDbFd);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- p = pDbFd->pShm;
- pShmNode = p->pShmNode;
- sqlite3_mutex_enter(pShmNode->mutex);
- assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
- assert( pShmNode->pInode==pDbFd->pInode );
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
-
- if( pShmNode->nRegion<=iRegion ){
- char **apNew; /* New apRegion[] array */
- int nByte = (iRegion+1)*szRegion; /* Minimum required file size */
- struct stat sStat; /* Used by fstat() */
-
- pShmNode->szRegion = szRegion;
-
- if( pShmNode->h>=0 ){
- /* The requested region is not mapped into this processes address space.
- ** Check to see if it has been allocated (i.e. if the wal-index file is
- ** large enough to contain the requested region).
- */
- if( osFstat(pShmNode->h, &sStat) ){
- rc = SQLITE_IOERR_SHMSIZE;
- goto shmpage_out;
- }
-
- if( sStat.st_size<nByte ){
- /* The requested memory region does not exist. If bExtend is set to
- ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
- **
- ** Alternatively, if bExtend is true, use ftruncate() to allocate
- ** the requested memory region.
- */
- if( !bExtend ) goto shmpage_out;
-#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
- if( osFallocate(pShmNode->h, sStat.st_size, nByte)!=0 ){
- rc = unixLogError(SQLITE_IOERR_SHMSIZE, "fallocate",
- pShmNode->zFilename);
- goto shmpage_out;
- }
-#else
- if( robust_ftruncate(pShmNode->h, nByte) ){
- rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate",
- pShmNode->zFilename);
- goto shmpage_out;
- }
-#endif
- }
- }
-
- /* Map the requested memory region into this processes address space. */
- apNew = (char **)sqlite3_realloc(
- pShmNode->apRegion, (iRegion+1)*sizeof(char *)
- );
- if( !apNew ){
- rc = SQLITE_IOERR_NOMEM;
- goto shmpage_out;
- }
- pShmNode->apRegion = apNew;
- while(pShmNode->nRegion<=iRegion){
- void *pMem;
- if( pShmNode->h>=0 ){
- pMem = mmap(0, szRegion,
- pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
- MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
- );
- if( pMem==MAP_FAILED ){
- rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
- goto shmpage_out;
- }
- }else{
- pMem = sqlite3_malloc(szRegion);
- if( pMem==0 ){
- rc = SQLITE_NOMEM;
- goto shmpage_out;
- }
- memset(pMem, 0, szRegion);
- }
- pShmNode->apRegion[pShmNode->nRegion] = pMem;
- pShmNode->nRegion++;
- }
- }
-
-shmpage_out:
- if( pShmNode->nRegion>iRegion ){
- *pp = pShmNode->apRegion[iRegion];
- }else{
- *pp = 0;
- }
- if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
- sqlite3_mutex_leave(pShmNode->mutex);
- return rc;
-}
-
-/*
-** Change the lock state for a shared-memory segment.
-**
-** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
-** different here than in posix. In xShmLock(), one can go from unlocked
-** to shared and back or from unlocked to exclusive and back. But one may
-** not go from shared to exclusive or from exclusive to shared.
-*/
-static int unixShmLock(
- sqlite3_file *fd, /* Database file holding the shared memory */
- int ofst, /* First lock to acquire or release */
- int n, /* Number of locks to acquire or release */
- int flags /* What to do with the lock */
-){
- unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */
- unixShm *p = pDbFd->pShm; /* The shared memory being locked */
- unixShm *pX; /* For looping over all siblings */
- unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */
- int rc = SQLITE_OK; /* Result code */
- u16 mask; /* Mask of locks to take or release */
-
- assert( pShmNode==pDbFd->pInode->pShmNode );
- assert( pShmNode->pInode==pDbFd->pInode );
- assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
- assert( n>=1 );
- assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
- || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
- || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
- || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
- assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
-
- mask = (1<<(ofst+n)) - (1<<ofst);
- assert( n>1 || mask==(1<<ofst) );
- sqlite3_mutex_enter(pShmNode->mutex);
- if( flags & SQLITE_SHM_UNLOCK ){
- u16 allMask = 0; /* Mask of locks held by siblings */
-
- /* See if any siblings hold this same lock */
- for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
- if( pX==p ) continue;
- assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
- allMask |= pX->sharedMask;
- }
-
- /* Unlock the system-level locks */
- if( (mask & allMask)==0 ){
- rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
- }else{
- rc = SQLITE_OK;
- }
-
- /* Undo the local locks */
- if( rc==SQLITE_OK ){
- p->exclMask &= ~mask;
- p->sharedMask &= ~mask;
- }
- }else if( flags & SQLITE_SHM_SHARED ){
- u16 allShared = 0; /* Union of locks held by connections other than "p" */
-
- /* Find out which shared locks are already held by sibling connections.
- ** If any sibling already holds an exclusive lock, go ahead and return
- ** SQLITE_BUSY.
- */
- for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
- if( (pX->exclMask & mask)!=0 ){
- rc = SQLITE_BUSY;
- break;
- }
- allShared |= pX->sharedMask;
- }
-
- /* Get shared locks at the system level, if necessary */
- if( rc==SQLITE_OK ){
- if( (allShared & mask)==0 ){
- rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n);
- }else{
- rc = SQLITE_OK;
- }
- }
-
- /* Get the local shared locks */
- if( rc==SQLITE_OK ){
- p->sharedMask |= mask;
- }
- }else{
- /* Make sure no sibling connections hold locks that will block this
- ** lock. If any do, return SQLITE_BUSY right away.
- */
- for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
- if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
- rc = SQLITE_BUSY;
- break;
- }
- }
-
- /* Get the exclusive locks at the system level. Then if successful
- ** also mark the local connection as being locked.
- */
- if( rc==SQLITE_OK ){
- rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
- if( rc==SQLITE_OK ){
- assert( (p->sharedMask & mask)==0 );
- p->exclMask |= mask;
- }
- }
- }
- sqlite3_mutex_leave(pShmNode->mutex);
- OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
- p->id, getpid(), p->sharedMask, p->exclMask));
- return rc;
-}
-
-/*
-** Implement a memory barrier or memory fence on shared memory.
-**
-** All loads and stores begun before the barrier must complete before
-** any load or store begun after the barrier.
-*/
-static void unixShmBarrier(
- sqlite3_file *fd /* Database file holding the shared memory */
-){
- UNUSED_PARAMETER(fd);
- unixEnterMutex();
- unixLeaveMutex();
-}
-
-/*
-** Close a connection to shared-memory. Delete the underlying
-** storage if deleteFlag is true.
-**
-** If there is no shared memory associated with the connection then this
-** routine is a harmless no-op.
-*/
-static int unixShmUnmap(
- sqlite3_file *fd, /* The underlying database file */
- int deleteFlag /* Delete shared-memory if true */
-){
- unixShm *p; /* The connection to be closed */
- unixShmNode *pShmNode; /* The underlying shared-memory file */
- unixShm **pp; /* For looping over sibling connections */
- unixFile *pDbFd; /* The underlying database file */
-
- pDbFd = (unixFile*)fd;
- p = pDbFd->pShm;
- if( p==0 ) return SQLITE_OK;
- pShmNode = p->pShmNode;
-
- assert( pShmNode==pDbFd->pInode->pShmNode );
- assert( pShmNode->pInode==pDbFd->pInode );
-
- /* Remove connection p from the set of connections associated
- ** with pShmNode */
- sqlite3_mutex_enter(pShmNode->mutex);
- for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
- *pp = p->pNext;
-
- /* Free the connection p */
- sqlite3_free(p);
- pDbFd->pShm = 0;
- sqlite3_mutex_leave(pShmNode->mutex);
-
- /* If pShmNode->nRef has reached 0, then close the underlying
- ** shared-memory file, too */
- unixEnterMutex();
- assert( pShmNode->nRef>0 );
- pShmNode->nRef--;
- if( pShmNode->nRef==0 ){
- if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
- unixShmPurge(pDbFd);
- }
- unixLeaveMutex();
-
- return SQLITE_OK;
-}
-
-
-#else
-# define unixShmMap 0
-# define unixShmLock 0
-# define unixShmBarrier 0
-# define unixShmUnmap 0
-#endif /* #ifndef SQLITE_OMIT_WAL */
-
-/*
-** Here ends the implementation of all sqlite3_file methods.
-**
-********************** End sqlite3_file Methods *******************************
-******************************************************************************/
-
-/*
-** This division contains definitions of sqlite3_io_methods objects that
-** implement various file locking strategies. It also contains definitions
-** of "finder" functions. A finder-function is used to locate the appropriate
-** sqlite3_io_methods object for a particular database file. The pAppData
-** field of the sqlite3_vfs VFS objects are initialized to be pointers to
-** the correct finder-function for that VFS.
-**
-** Most finder functions return a pointer to a fixed sqlite3_io_methods
-** object. The only interesting finder-function is autolockIoFinder, which
-** looks at the filesystem type and tries to guess the best locking
-** strategy from that.
-**
-** For finder-funtion F, two objects are created:
-**
-** (1) The real finder-function named "FImpt()".
-**
-** (2) A constant pointer to this function named just "F".
-**
-**
-** A pointer to the F pointer is used as the pAppData value for VFS
-** objects. We have to do this instead of letting pAppData point
-** directly at the finder-function since C90 rules prevent a void*
-** from be cast into a function pointer.
-**
-**
-** Each instance of this macro generates two objects:
-**
-** * A constant sqlite3_io_methods object call METHOD that has locking
-** methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
-**
-** * An I/O method finder function called FINDER that returns a pointer
-** to the METHOD object in the previous bullet.
-*/
-#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK) \
-static const sqlite3_io_methods METHOD = { \
- VERSION, /* iVersion */ \
- CLOSE, /* xClose */ \
- unixRead, /* xRead */ \
- unixWrite, /* xWrite */ \
- unixTruncate, /* xTruncate */ \
- unixSync, /* xSync */ \
- unixFileSize, /* xFileSize */ \
- LOCK, /* xLock */ \
- UNLOCK, /* xUnlock */ \
- CKLOCK, /* xCheckReservedLock */ \
- unixFileControl, /* xFileControl */ \
- unixSectorSize, /* xSectorSize */ \
- unixDeviceCharacteristics, /* xDeviceCapabilities */ \
- unixShmMap, /* xShmMap */ \
- unixShmLock, /* xShmLock */ \
- unixShmBarrier, /* xShmBarrier */ \
- unixShmUnmap /* xShmUnmap */ \
-}; \
-static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \
- UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \
- return &METHOD; \
-} \
-static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \
- = FINDER##Impl;
-
-/*
-** Here are all of the sqlite3_io_methods objects for each of the
-** locking strategies. Functions that return pointers to these methods
-** are also created.
-*/
-IOMETHODS(
- posixIoFinder, /* Finder function name */
- posixIoMethods, /* sqlite3_io_methods object name */
- 2, /* shared memory is enabled */
- unixClose, /* xClose method */
- unixLock, /* xLock method */
- unixUnlock, /* xUnlock method */
- unixCheckReservedLock /* xCheckReservedLock method */
-)
-IOMETHODS(
- nolockIoFinder, /* Finder function name */
- nolockIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- nolockClose, /* xClose method */
- nolockLock, /* xLock method */
- nolockUnlock, /* xUnlock method */
- nolockCheckReservedLock /* xCheckReservedLock method */
-)
-IOMETHODS(
- dotlockIoFinder, /* Finder function name */
- dotlockIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- dotlockClose, /* xClose method */
- dotlockLock, /* xLock method */
- dotlockUnlock, /* xUnlock method */
- dotlockCheckReservedLock /* xCheckReservedLock method */
-)
-
-#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
-IOMETHODS(
- flockIoFinder, /* Finder function name */
- flockIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- flockClose, /* xClose method */
- flockLock, /* xLock method */
- flockUnlock, /* xUnlock method */
- flockCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-#if OS_VXWORKS
-IOMETHODS(
- semIoFinder, /* Finder function name */
- semIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- semClose, /* xClose method */
- semLock, /* xLock method */
- semUnlock, /* xUnlock method */
- semCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-IOMETHODS(
- afpIoFinder, /* Finder function name */
- afpIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- afpClose, /* xClose method */
- afpLock, /* xLock method */
- afpUnlock, /* xUnlock method */
- afpCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-/*
-** The proxy locking method is a "super-method" in the sense that it
-** opens secondary file descriptors for the conch and lock files and
-** it uses proxy, dot-file, AFP, and flock() locking methods on those
-** secondary files. For this reason, the division that implements
-** proxy locking is located much further down in the file. But we need
-** to go ahead and define the sqlite3_io_methods and finder function
-** for proxy locking here. So we forward declare the I/O methods.
-*/
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-static int proxyClose(sqlite3_file*);
-static int proxyLock(sqlite3_file*, int);
-static int proxyUnlock(sqlite3_file*, int);
-static int proxyCheckReservedLock(sqlite3_file*, int*);
-IOMETHODS(
- proxyIoFinder, /* Finder function name */
- proxyIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- proxyClose, /* xClose method */
- proxyLock, /* xLock method */
- proxyUnlock, /* xUnlock method */
- proxyCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-IOMETHODS(
- nfsIoFinder, /* Finder function name */
- nfsIoMethods, /* sqlite3_io_methods object name */
- 1, /* shared memory is disabled */
- unixClose, /* xClose method */
- unixLock, /* xLock method */
- nfsUnlock, /* xUnlock method */
- unixCheckReservedLock /* xCheckReservedLock method */
-)
-#endif
-
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-/*
-** This "finder" function attempts to determine the best locking strategy
-** for the database file "filePath". It then returns the sqlite3_io_methods
-** object that implements that strategy.
-**
-** This is for MacOSX only.
-*/
-static const sqlite3_io_methods *autolockIoFinderImpl(
- const char *filePath, /* name of the database file */
- unixFile *pNew /* open file object for the database file */
-){
- static const struct Mapping {
- const char *zFilesystem; /* Filesystem type name */
- const sqlite3_io_methods *pMethods; /* Appropriate locking method */
- } aMap[] = {
- { "hfs", &posixIoMethods },
- { "ufs", &posixIoMethods },
- { "afpfs", &afpIoMethods },
- { "smbfs", &afpIoMethods },
- { "webdav", &nolockIoMethods },
- { 0, 0 }
- };
- int i;
- struct statfs fsInfo;
- struct flock lockInfo;
-
- if( !filePath ){
- /* If filePath==NULL that means we are dealing with a transient file
- ** that does not need to be locked. */
- return &nolockIoMethods;
- }
- if( statfs(filePath, &fsInfo) != -1 ){
- if( fsInfo.f_flags & MNT_RDONLY ){
- return &nolockIoMethods;
- }
- for(i=0; aMap[i].zFilesystem; i++){
- if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
- return aMap[i].pMethods;
- }
- }
- }
-
- /* Default case. Handles, amongst others, "nfs".
- ** Test byte-range lock using fcntl(). If the call succeeds,
- ** assume that the file-system supports POSIX style locks.
- */
- lockInfo.l_len = 1;
- lockInfo.l_start = 0;
- lockInfo.l_whence = SEEK_SET;
- lockInfo.l_type = F_RDLCK;
- if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
- if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){
- return &nfsIoMethods;
- } else {
- return &posixIoMethods;
- }
- }else{
- return &dotlockIoMethods;
- }
-}
-static const sqlite3_io_methods
- *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
-
-#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-
-#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE
-/*
-** This "finder" function attempts to determine the best locking strategy
-** for the database file "filePath". It then returns the sqlite3_io_methods
-** object that implements that strategy.
-**
-** This is for VXWorks only.
-*/
-static const sqlite3_io_methods *autolockIoFinderImpl(
- const char *filePath, /* name of the database file */
- unixFile *pNew /* the open file object */
-){
- struct flock lockInfo;
-
- if( !filePath ){
- /* If filePath==NULL that means we are dealing with a transient file
- ** that does not need to be locked. */
- return &nolockIoMethods;
- }
-
- /* Test if fcntl() is supported and use POSIX style locks.
- ** Otherwise fall back to the named semaphore method.
- */
- lockInfo.l_len = 1;
- lockInfo.l_start = 0;
- lockInfo.l_whence = SEEK_SET;
- lockInfo.l_type = F_RDLCK;
- if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
- return &posixIoMethods;
- }else{
- return &semIoMethods;
- }
-}
-static const sqlite3_io_methods
- *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
-
-#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */
-
-/*
-** An abstract type for a pointer to a IO method finder function:
-*/
-typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*);
-
-
-/****************************************************************************
-**************************** sqlite3_vfs methods ****************************
-**
-** This division contains the implementation of methods on the
-** sqlite3_vfs object.
-*/
-
-/*
-** Initialize the contents of the unixFile structure pointed to by pId.
-*/
-static int fillInUnixFile(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- int h, /* Open file descriptor of file being opened */
- sqlite3_file *pId, /* Write to the unixFile structure here */
- const char *zFilename, /* Name of the file being opened */
- int ctrlFlags /* Zero or more UNIXFILE_* values */
-){
- const sqlite3_io_methods *pLockingStyle;
- unixFile *pNew = (unixFile *)pId;
- int rc = SQLITE_OK;
-
- assert( pNew->pInode==NULL );
-
- /* Usually the path zFilename should not be a relative pathname. The
- ** exception is when opening the proxy "conch" file in builds that
- ** include the special Apple locking styles.
- */
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
- assert( zFilename==0 || zFilename[0]=='/'
- || pVfs->pAppData==(void*)&autolockIoFinder );
-#else
- assert( zFilename==0 || zFilename[0]=='/' );
-#endif
-
- /* No locking occurs in temporary files */
- assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );
-
- OSTRACE(("OPEN %-3d %s\n", h, zFilename));
- pNew->h = h;
- pNew->pVfs = pVfs;
- pNew->zPath = zFilename;
- pNew->ctrlFlags = (u8)ctrlFlags;
- if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
- "psow", SQLITE_POWERSAFE_OVERWRITE) ){
- pNew->ctrlFlags |= UNIXFILE_PSOW;
- }
- if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
- pNew->ctrlFlags |= UNIXFILE_EXCL;
- }
-
-#if OS_VXWORKS
- pNew->pId = vxworksFindFileId(zFilename);
- if( pNew->pId==0 ){
- ctrlFlags |= UNIXFILE_NOLOCK;
- rc = SQLITE_NOMEM;
- }
-#endif
-
- if( ctrlFlags & UNIXFILE_NOLOCK ){
- pLockingStyle = &nolockIoMethods;
- }else{
- pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew);
-#if SQLITE_ENABLE_LOCKING_STYLE
- /* Cache zFilename in the locking context (AFP and dotlock override) for
- ** proxyLock activation is possible (remote proxy is based on db name)
- ** zFilename remains valid until file is closed, to support */
- pNew->lockingContext = (void*)zFilename;
-#endif
- }
-
- if( pLockingStyle == &posixIoMethods
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
- || pLockingStyle == &nfsIoMethods
-#endif
- ){
- unixEnterMutex();
- rc = findInodeInfo(pNew, &pNew->pInode);
- if( rc!=SQLITE_OK ){
- /* If an error occured in findInodeInfo(), close the file descriptor
- ** immediately, before releasing the mutex. findInodeInfo() may fail
- ** in two scenarios:
- **
- ** (a) A call to fstat() failed.
- ** (b) A malloc failed.
- **
- ** Scenario (b) may only occur if the process is holding no other
- ** file descriptors open on the same file. If there were other file
- ** descriptors on this file, then no malloc would be required by
- ** findInodeInfo(). If this is the case, it is quite safe to close
- ** handle h - as it is guaranteed that no posix locks will be released
- ** by doing so.
- **
- ** If scenario (a) caused the error then things are not so safe. The
- ** implicit assumption here is that if fstat() fails, things are in
- ** such bad shape that dropping a lock or two doesn't matter much.
- */
- robust_close(pNew, h, __LINE__);
- h = -1;
- }
- unixLeaveMutex();
- }
-
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- else if( pLockingStyle == &afpIoMethods ){
- /* AFP locking uses the file path so it needs to be included in
- ** the afpLockingContext.
- */
- afpLockingContext *pCtx;
- pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
- if( pCtx==0 ){
- rc = SQLITE_NOMEM;
- }else{
- /* NB: zFilename exists and remains valid until the file is closed
- ** according to requirement F11141. So we do not need to make a
- ** copy of the filename. */
- pCtx->dbPath = zFilename;
- pCtx->reserved = 0;
- srandomdev();
- unixEnterMutex();
- rc = findInodeInfo(pNew, &pNew->pInode);
- if( rc!=SQLITE_OK ){
- sqlite3_free(pNew->lockingContext);
- robust_close(pNew, h, __LINE__);
- h = -1;
- }
- unixLeaveMutex();
- }
- }
-#endif
-
- else if( pLockingStyle == &dotlockIoMethods ){
- /* Dotfile locking uses the file path so it needs to be included in
- ** the dotlockLockingContext
- */
- char *zLockFile;
- int nFilename;
- assert( zFilename!=0 );
- nFilename = (int)strlen(zFilename) + 6;
- zLockFile = (char *)sqlite3_malloc(nFilename);
- if( zLockFile==0 ){
- rc = SQLITE_NOMEM;
- }else{
- sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
- }
- pNew->lockingContext = zLockFile;
- }
-
-#if OS_VXWORKS
- else if( pLockingStyle == &semIoMethods ){
- /* Named semaphore locking uses the file path so it needs to be
- ** included in the semLockingContext
- */
- unixEnterMutex();
- rc = findInodeInfo(pNew, &pNew->pInode);
- if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){
- char *zSemName = pNew->pInode->aSemName;
- int n;
- sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem",
- pNew->pId->zCanonicalName);
- for( n=1; zSemName[n]; n++ )
- if( zSemName[n]=='/' ) zSemName[n] = '_';
- pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
- if( pNew->pInode->pSem == SEM_FAILED ){
- rc = SQLITE_NOMEM;
- pNew->pInode->aSemName[0] = '\0';
- }
- }
- unixLeaveMutex();
- }
-#endif
-
- pNew->lastErrno = 0;
-#if OS_VXWORKS
- if( rc!=SQLITE_OK ){
- if( h>=0 ) robust_close(pNew, h, __LINE__);
- h = -1;
- osUnlink(zFilename);
- isDelete = 0;
- }
- if( isDelete ) pNew->ctrlFlags |= UNIXFILE_DELETE;
-#endif
- if( rc!=SQLITE_OK ){
- if( h>=0 ) robust_close(pNew, h, __LINE__);
- }else{
- pNew->pMethod = pLockingStyle;
- OpenCounter(+1);
- }
- return rc;
-}
-
-/*
-** Return the name of a directory in which to put temporary files.
-** If no suitable temporary file directory can be found, return NULL.
-*/
-static const char *unixTempFileDir(void){
- static const char *azDirs[] = {
- 0,
- 0,
- "/var/tmp",
- "/usr/tmp",
- "/tmp",
- 0 /* List terminator */
- };
- unsigned int i;
- struct stat buf;
- const char *zDir = 0;
-
- azDirs[0] = sqlite3_temp_directory;
- if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
- for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
- if( zDir==0 ) continue;
- if( osStat(zDir, &buf) ) continue;
- if( !S_ISDIR(buf.st_mode) ) continue;
- if( osAccess(zDir, 07) ) continue;
- break;
- }
- return zDir;
-}
-
-/*
-** Create a temporary file name in zBuf. zBuf must be allocated
-** by the calling process and must be big enough to hold at least
-** pVfs->mxPathname bytes.
-*/
-static int unixGetTempname(int nBuf, char *zBuf){
- static const unsigned char zChars[] =
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789";
- unsigned int i, j;
- const char *zDir;
-
- /* It's odd to simulate an io-error here, but really this is just
- ** using the io-error infrastructure to test that SQLite handles this
- ** function failing.
- */
- SimulateIOError( return SQLITE_IOERR );
-
- zDir = unixTempFileDir();
- if( zDir==0 ) zDir = ".";
-
- /* Check that the output buffer is large enough for the temporary file
- ** name. If it is not, return SQLITE_ERROR.
- */
- if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){
- return SQLITE_ERROR;
- }
-
- do{
- sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
- j = (int)strlen(zBuf);
- sqlite3_randomness(15, &zBuf[j]);
- for(i=0; i<15; i++, j++){
- zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
- }
- zBuf[j] = 0;
- zBuf[j+1] = 0;
- }while( osAccess(zBuf,0)==0 );
- return SQLITE_OK;
-}
-
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-/*
-** Routine to transform a unixFile into a proxy-locking unixFile.
-** Implementation in the proxy-lock division, but used by unixOpen()
-** if SQLITE_PREFER_PROXY_LOCKING is defined.
-*/
-static int proxyTransformUnixFile(unixFile*, const char*);
-#endif
-
-/*
-** Search for an unused file descriptor that was opened on the database
-** file (not a journal or master-journal file) identified by pathname
-** zPath with SQLITE_OPEN_XXX flags matching those passed as the second
-** argument to this function.
-**
-** Such a file descriptor may exist if a database connection was closed
-** but the associated file descriptor could not be closed because some
-** other file descriptor open on the same file is holding a file-lock.
-** Refer to comments in the unixClose() function and the lengthy comment
-** describing "Posix Advisory Locking" at the start of this file for
-** further details. Also, ticket #4018.
-**
-** If a suitable file descriptor is found, then it is returned. If no
-** such file descriptor is located, -1 is returned.
-*/
-static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
- UnixUnusedFd *pUnused = 0;
-
- /* Do not search for an unused file descriptor on vxworks. Not because
- ** vxworks would not benefit from the change (it might, we're not sure),
- ** but because no way to test it is currently available. It is better
- ** not to risk breaking vxworks support for the sake of such an obscure
- ** feature. */
-#if !OS_VXWORKS
- struct stat sStat; /* Results of stat() call */
-
- /* A stat() call may fail for various reasons. If this happens, it is
- ** almost certain that an open() call on the same path will also fail.
- ** For this reason, if an error occurs in the stat() call here, it is
- ** ignored and -1 is returned. The caller will try to open a new file
- ** descriptor on the same path, fail, and return an error to SQLite.
- **
- ** Even if a subsequent open() call does succeed, the consequences of
- ** not searching for a resusable file descriptor are not dire. */
- if( 0==osStat(zPath, &sStat) ){
- unixInodeInfo *pInode;
-
- unixEnterMutex();
- pInode = inodeList;
- while( pInode && (pInode->fileId.dev!=sStat.st_dev
- || pInode->fileId.ino!=sStat.st_ino) ){
- pInode = pInode->pNext;
- }
- if( pInode ){
- UnixUnusedFd **pp;
- for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
- pUnused = *pp;
- if( pUnused ){
- *pp = pUnused->pNext;
- }
- }
- unixLeaveMutex();
- }
-#endif /* if !OS_VXWORKS */
- return pUnused;
-}
-
-/*
-** This function is called by unixOpen() to determine the unix permissions
-** to create new files with. If no error occurs, then SQLITE_OK is returned
-** and a value suitable for passing as the third argument to open(2) is
-** written to *pMode. If an IO error occurs, an SQLite error code is
-** returned and the value of *pMode is not modified.
-**
-** In most cases cases, this routine sets *pMode to 0, which will become
-** an indication to robust_open() to create the file using
-** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask.
-** But if the file being opened is a WAL or regular journal file, then
-** this function queries the file-system for the permissions on the
-** corresponding database file and sets *pMode to this value. Whenever
-** possible, WAL and journal files are created using the same permissions
-** as the associated database file.
-**
-** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
-** original filename is unavailable. But 8_3_NAMES is only used for
-** FAT filesystems and permissions do not matter there, so just use
-** the default permissions.
-*/
-static int findCreateFileMode(
- const char *zPath, /* Path of file (possibly) being created */
- int flags, /* Flags passed as 4th argument to xOpen() */
- mode_t *pMode, /* OUT: Permissions to open file with */
- uid_t *pUid, /* OUT: uid to set on the file */
- gid_t *pGid /* OUT: gid to set on the file */
-){
- int rc = SQLITE_OK; /* Return Code */
- *pMode = 0;
- *pUid = 0;
- *pGid = 0;
- if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
- char zDb[MAX_PATHNAME+1]; /* Database file path */
- int nDb; /* Number of valid bytes in zDb */
- struct stat sStat; /* Output of stat() on database file */
-
- /* zPath is a path to a WAL or journal file. The following block derives
- ** the path to the associated database file from zPath. This block handles
- ** the following naming conventions:
- **
- ** "<path to db>-journal"
- ** "<path to db>-wal"
- ** "<path to db>-journalNN"
- ** "<path to db>-walNN"
- **
- ** where NN is a decimal number. The NN naming schemes are
- ** used by the test_multiplex.c module.
- */
- nDb = sqlite3Strlen30(zPath) - 1;
-#ifdef SQLITE_ENABLE_8_3_NAMES
- while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--;
- if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK;
-#else
- while( zPath[nDb]!='-' ){
- assert( nDb>0 );
- assert( zPath[nDb]!='\n' );
- nDb--;
- }
-#endif
- memcpy(zDb, zPath, nDb);
- zDb[nDb] = '\0';
-
- if( 0==osStat(zDb, &sStat) ){
- *pMode = sStat.st_mode & 0777;
- *pUid = sStat.st_uid;
- *pGid = sStat.st_gid;
- }else{
- rc = SQLITE_IOERR_FSTAT;
- }
- }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
- *pMode = 0600;
- }
- return rc;
-}
-
-/*
-** Open the file zPath.
-**
-** Previously, the SQLite OS layer used three functions in place of this
-** one:
-**
-** sqlite3OsOpenReadWrite();
-** sqlite3OsOpenReadOnly();
-** sqlite3OsOpenExclusive();
-**
-** These calls correspond to the following combinations of flags:
-**
-** ReadWrite() -> (READWRITE | CREATE)
-** ReadOnly() -> (READONLY)
-** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE)
-**
-** The old OpenExclusive() accepted a boolean argument - "delFlag". If
-** true, the file was configured to be automatically deleted when the
-** file handle closed. To achieve the same effect using this new
-** interface, add the DELETEONCLOSE flag to those specified above for
-** OpenExclusive().
-*/
-static int unixOpen(
- sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */
- const char *zPath, /* Pathname of file to be opened */
- sqlite3_file *pFile, /* The file descriptor to be filled in */
- int flags, /* Input flags to control the opening */
- int *pOutFlags /* Output flags returned to SQLite core */
-){
- unixFile *p = (unixFile *)pFile;
- int fd = -1; /* File descriptor returned by open() */
- int openFlags = 0; /* Flags to pass to open() */
- int eType = flags&0xFFFFFF00; /* Type of file to open */
- int noLock; /* True to omit locking primitives */
- int rc = SQLITE_OK; /* Function Return Code */
- int ctrlFlags = 0; /* UNIXFILE_* flags */
-
- int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
- int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
- int isCreate = (flags & SQLITE_OPEN_CREATE);
- int isReadonly = (flags & SQLITE_OPEN_READONLY);
- int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
-#if SQLITE_ENABLE_LOCKING_STYLE
- int isAutoProxy = (flags & SQLITE_OPEN_AUTOPROXY);
-#endif
-#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
- struct statfs fsInfo;
-#endif
-
- /* If creating a master or main-file journal, this function will open
- ** a file-descriptor on the directory too. The first time unixSync()
- ** is called the directory file descriptor will be fsync()ed and close()d.
- */
- int syncDir = (isCreate && (
- eType==SQLITE_OPEN_MASTER_JOURNAL
- || eType==SQLITE_OPEN_MAIN_JOURNAL
- || eType==SQLITE_OPEN_WAL
- ));
-
- /* If argument zPath is a NULL pointer, this function is required to open
- ** a temporary file. Use this buffer to store the file name in.
- */
- char zTmpname[MAX_PATHNAME+2];
- const char *zName = zPath;
-
- /* Check the following statements are true:
- **
- ** (a) Exactly one of the READWRITE and READONLY flags must be set, and
- ** (b) if CREATE is set, then READWRITE must also be set, and
- ** (c) if EXCLUSIVE is set, then CREATE must also be set.
- ** (d) if DELETEONCLOSE is set, then CREATE must also be set.
- */
- assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
- assert(isCreate==0 || isReadWrite);
- assert(isExclusive==0 || isCreate);
- assert(isDelete==0 || isCreate);
-
- /* The main DB, main journal, WAL file and master journal are never
- ** automatically deleted. Nor are they ever temporary files. */
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
-
- /* Assert that the upper layer has set one of the "file-type" flags. */
- assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB
- || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
- || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
- || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
- );
-
- memset(p, 0, sizeof(unixFile));
-
- if( eType==SQLITE_OPEN_MAIN_DB ){
- UnixUnusedFd *pUnused;
- pUnused = findReusableFd(zName, flags);
- if( pUnused ){
- fd = pUnused->fd;
- }else{
- pUnused = sqlite3_malloc(sizeof(*pUnused));
- if( !pUnused ){
- return SQLITE_NOMEM;
- }
- }
- p->pUnused = pUnused;
-
- /* Database filenames are double-zero terminated if they are not
- ** URIs with parameters. Hence, they can always be passed into
- ** sqlite3_uri_parameter(). */
- assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 );
-
- }else if( !zName ){
- /* If zName is NULL, the upper layer is requesting a temp file. */
- assert(isDelete && !syncDir);
- rc = unixGetTempname(MAX_PATHNAME+2, zTmpname);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- zName = zTmpname;
-
- /* Generated temporary filenames are always double-zero terminated
- ** for use by sqlite3_uri_parameter(). */
- assert( zName[strlen(zName)+1]==0 );
- }
-
- /* Determine the value of the flags parameter passed to POSIX function
- ** open(). These must be calculated even if open() is not called, as
- ** they may be stored as part of the file handle and used by the
- ** 'conch file' locking functions later on. */
- if( isReadonly ) openFlags |= O_RDONLY;
- if( isReadWrite ) openFlags |= O_RDWR;
- if( isCreate ) openFlags |= O_CREAT;
- if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
- openFlags |= (O_LARGEFILE|O_BINARY);
-
- if( fd<0 ){
- mode_t openMode; /* Permissions to create file with */
- uid_t uid; /* Userid for the file */
- gid_t gid; /* Groupid for the file */
- rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
- if( rc!=SQLITE_OK ){
- assert( !p->pUnused );
- assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
- return rc;
- }
- fd = robust_open(zName, openFlags, openMode);
- OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
- if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
- /* Failed to open the file for read/write access. Try read-only. */
- flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
- openFlags &= ~(O_RDWR|O_CREAT);
- flags |= SQLITE_OPEN_READONLY;
- openFlags |= O_RDONLY;
- isReadonly = 1;
- fd = robust_open(zName, openFlags, openMode);
- }
- if( fd<0 ){
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
- goto open_finished;
- }
-
- /* If this process is running as root and if creating a new rollback
- ** journal or WAL file, set the ownership of the journal or WAL to be
- ** the same as the original database.
- */
- if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
- osFchown(fd, uid, gid);
- }
- }
- assert( fd>=0 );
- if( pOutFlags ){
- *pOutFlags = flags;
- }
-
- if( p->pUnused ){
- p->pUnused->fd = fd;
- p->pUnused->flags = flags;
- }
-
- if( isDelete ){
-#if OS_VXWORKS
- zPath = zName;
-#else
- osUnlink(zName);
-#endif
- }
-#if SQLITE_ENABLE_LOCKING_STYLE
- else{
- p->openFlags = openFlags;
- }
-#endif
-
- noLock = eType!=SQLITE_OPEN_MAIN_DB;
-
-
-#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
- if( fstatfs(fd, &fsInfo) == -1 ){
- ((unixFile*)pFile)->lastErrno = errno;
- robust_close(p, fd, __LINE__);
- return SQLITE_IOERR_ACCESS;
- }
- if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
- ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
- }
-#endif
-
- /* Set up appropriate ctrlFlags */
- if( isDelete ) ctrlFlags |= UNIXFILE_DELETE;
- if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY;
- if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK;
- if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC;
- if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
-
-#if SQLITE_ENABLE_LOCKING_STYLE
-#if SQLITE_PREFER_PROXY_LOCKING
- isAutoProxy = 1;
-#endif
- if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){
- char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
- int useProxy = 0;
-
- /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means
- ** never use proxy, NULL means use proxy for non-local files only. */
- if( envforce!=NULL ){
- useProxy = atoi(envforce)>0;
- }else{
- if( statfs(zPath, &fsInfo) == -1 ){
- /* In theory, the close(fd) call is sub-optimal. If the file opened
- ** with fd is a database file, and there are other connections open
- ** on that file that are currently holding advisory locks on it,
- ** then the call to close() will cancel those locks. In practice,
- ** we're assuming that statfs() doesn't fail very often. At least
- ** not while other file descriptors opened by the same process on
- ** the same file are working. */
- p->lastErrno = errno;
- robust_close(p, fd, __LINE__);
- rc = SQLITE_IOERR_ACCESS;
- goto open_finished;
- }
- useProxy = !(fsInfo.f_flags&MNT_LOCAL);
- }
- if( useProxy ){
- rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
- if( rc==SQLITE_OK ){
- rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
- if( rc!=SQLITE_OK ){
- /* Use unixClose to clean up the resources added in fillInUnixFile
- ** and clear all the structure's references. Specifically,
- ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op
- */
- unixClose(pFile);
- return rc;
- }
- }
- goto open_finished;
- }
- }
-#endif
-
- rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
-
-open_finished:
- if( rc!=SQLITE_OK ){
- sqlite3_free(p->pUnused);
- }
- return rc;
-}
-
-
-/*
-** Delete the file at zPath. If the dirSync argument is true, fsync()
-** the directory after deleting the file.
-*/
-static int unixDelete(
- sqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */
- const char *zPath, /* Name of file to be deleted */
- int dirSync /* If true, fsync() directory after deleting file */
-){
- int rc = SQLITE_OK;
- UNUSED_PARAMETER(NotUsed);
- SimulateIOError(return SQLITE_IOERR_DELETE);
- if( osUnlink(zPath)==(-1) ){
- if( errno==ENOENT ){
- rc = SQLITE_IOERR_DELETE_NOENT;
- }else{
- rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
- }
- return rc;
- }
-#ifndef SQLITE_DISABLE_DIRSYNC
- if( (dirSync & 1)!=0 ){
- int fd;
- rc = osOpenDirectory(zPath, &fd);
- if( rc==SQLITE_OK ){
-#if OS_VXWORKS
- if( fsync(fd)==-1 )
-#else
- if( fsync(fd) )
-#endif
- {
- rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
- }
- robust_close(0, fd, __LINE__);
- }else if( rc==SQLITE_CANTOPEN ){
- rc = SQLITE_OK;
- }
- }
-#endif
- return rc;
-}
-
-/*
-** Test the existance of or access permissions of file zPath. The
-** test performed depends on the value of flags:
-**
-** SQLITE_ACCESS_EXISTS: Return 1 if the file exists
-** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable.
-** SQLITE_ACCESS_READONLY: Return 1 if the file is readable.
-**
-** Otherwise return 0.
-*/
-static int unixAccess(
- sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */
- const char *zPath, /* Path of the file to examine */
- int flags, /* What do we want to learn about the zPath file? */
- int *pResOut /* Write result boolean here */
-){
- int amode = 0;
- UNUSED_PARAMETER(NotUsed);
- SimulateIOError( return SQLITE_IOERR_ACCESS; );
- switch( flags ){
- case SQLITE_ACCESS_EXISTS:
- amode = F_OK;
- break;
- case SQLITE_ACCESS_READWRITE:
- amode = W_OK|R_OK;
- break;
- case SQLITE_ACCESS_READ:
- amode = R_OK;
- break;
-
- default:
- assert(!"Invalid flags argument");
- }
- *pResOut = (osAccess(zPath, amode)==0);
- if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
- struct stat buf;
- if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
- *pResOut = 0;
- }
- }
- return SQLITE_OK;
-}
-
-
-/*
-** Turn a relative pathname into a full pathname. The relative path
-** is stored as a nul-terminated string in the buffer pointed to by
-** zPath.
-**
-** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes
-** (in this case, MAX_PATHNAME bytes). The full-path is written to
-** this buffer before returning.
-*/
-static int unixFullPathname(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- const char *zPath, /* Possibly relative input path */
- int nOut, /* Size of output buffer in bytes */
- char *zOut /* Output buffer */
-){
-
- /* It's odd to simulate an io-error here, but really this is just
- ** using the io-error infrastructure to test that SQLite handles this
- ** function failing. This function could fail if, for example, the
- ** current working directory has been unlinked.
- */
- SimulateIOError( return SQLITE_ERROR );
-
- assert( pVfs->mxPathname==MAX_PATHNAME );
- UNUSED_PARAMETER(pVfs);
-
- zOut[nOut-1] = '\0';
- if( zPath[0]=='/' ){
- sqlite3_snprintf(nOut, zOut, "%s", zPath);
- }else{
- int nCwd;
- if( osGetcwd(zOut, nOut-1)==0 ){
- return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
- }
- nCwd = (int)strlen(zOut);
- sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
- }
- return SQLITE_OK;
-}
-
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-/*
-** Interfaces for opening a shared library, finding entry points
-** within the shared library, and closing the shared library.
-*/
-#include <dlfcn.h>
-static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){
- UNUSED_PARAMETER(NotUsed);
- return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
-}
-
-/*
-** SQLite calls this function immediately after a call to unixDlSym() or
-** unixDlOpen() fails (returns a null pointer). If a more detailed error
-** message is available, it is written to zBufOut. If no error message
-** is available, zBufOut is left unmodified and SQLite uses a default
-** error message.
-*/
-static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){
- const char *zErr;
- UNUSED_PARAMETER(NotUsed);
- unixEnterMutex();
- zErr = dlerror();
- if( zErr ){
- sqlite3_snprintf(nBuf, zBufOut, "%s", zErr);
- }
- unixLeaveMutex();
-}
-static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){
- /*
- ** GCC with -pedantic-errors says that C90 does not allow a void* to be
- ** cast into a pointer to a function. And yet the library dlsym() routine
- ** returns a void* which is really a pointer to a function. So how do we
- ** use dlsym() with -pedantic-errors?
- **
- ** Variable x below is defined to be a pointer to a function taking
- ** parameters void* and const char* and returning a pointer to a function.
- ** We initialize x by assigning it a pointer to the dlsym() function.
- ** (That assignment requires a cast.) Then we call the function that
- ** x points to.
- **
- ** This work-around is unlikely to work correctly on any system where
- ** you really cannot cast a function pointer into void*. But then, on the
- ** other hand, dlsym() will not work on such a system either, so we have
- ** not really lost anything.
- */
- void (*(*x)(void*,const char*))(void);
- UNUSED_PARAMETER(NotUsed);
- x = (void(*(*)(void*,const char*))(void))dlsym;
- return (*x)(p, zSym);
-}
-static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){
- UNUSED_PARAMETER(NotUsed);
- dlclose(pHandle);
-}
-#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
- #define unixDlOpen 0
- #define unixDlError 0
- #define unixDlSym 0
- #define unixDlClose 0
-#endif
-
-/*
-** Write nBuf bytes of random data to the supplied buffer zBuf.
-*/
-static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
- UNUSED_PARAMETER(NotUsed);
- assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int)));
-
- /* We have to initialize zBuf to prevent valgrind from reporting
- ** errors. The reports issued by valgrind are incorrect - we would
- ** prefer that the randomness be increased by making use of the
- ** uninitialized space in zBuf - but valgrind errors tend to worry
- ** some users. Rather than argue, it seems easier just to initialize
- ** the whole array and silence valgrind, even if that means less randomness
- ** in the random seed.
- **
- ** When testing, initializing zBuf[] to zero is all we do. That means
- ** that we always use the same random number sequence. This makes the
- ** tests repeatable.
- */
- memset(zBuf, 0, nBuf);
-#if !defined(SQLITE_TEST)
- {
- int pid, fd, got;
- fd = robust_open("/dev/urandom", O_RDONLY, 0);
- if( fd<0 ){
- time_t t;
- time(&t);
- memcpy(zBuf, &t, sizeof(t));
- pid = getpid();
- memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid));
- assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf );
- nBuf = sizeof(t) + sizeof(pid);
- }else{
- do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR );
- robust_close(0, fd, __LINE__);
- }
- }
-#endif
- return nBuf;
-}
-
-
-/*
-** Sleep for a little while. Return the amount of time slept.
-** The argument is the number of microseconds we want to sleep.
-** The return value is the number of microseconds of sleep actually
-** requested from the underlying operating system, a number which
-** might be greater than or equal to the argument, but not less
-** than the argument.
-*/
-static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){
-#if OS_VXWORKS
- struct timespec sp;
-
- sp.tv_sec = microseconds / 1000000;
- sp.tv_nsec = (microseconds % 1000000) * 1000;
- nanosleep(&sp, NULL);
- UNUSED_PARAMETER(NotUsed);
- return microseconds;
-#elif defined(HAVE_USLEEP) && HAVE_USLEEP
- usleep(microseconds);
- UNUSED_PARAMETER(NotUsed);
- return microseconds;
-#else
- int seconds = (microseconds+999999)/1000000;
- sleep(seconds);
- UNUSED_PARAMETER(NotUsed);
- return seconds*1000000;
-#endif
-}
-
-/*
-** The following variable, if set to a non-zero value, is interpreted as
-** the number of seconds since 1970 and is used to set the result of
-** sqlite3OsCurrentTime() during testing.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */
-#endif
-
-/*
-** Find the current time (in Universal Coordinated Time). Write into *piNow
-** the current time and date as a Julian Day number times 86_400_000. In
-** other words, write into *piNow the number of milliseconds since the Julian
-** epoch of noon in Greenwich on November 24, 4714 B.C according to the
-** proleptic Gregorian calendar.
-**
-** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
-** cannot be found.
-*/
-static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
- static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
- int rc = SQLITE_OK;
-#if defined(NO_GETTOD)
- time_t t;
- time(&t);
- *piNow = ((sqlite3_int64)t)*1000 + unixEpoch;
-#elif OS_VXWORKS
- struct timespec sNow;
- clock_gettime(CLOCK_REALTIME, &sNow);
- *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
-#else
- struct timeval sNow;
- if( gettimeofday(&sNow, 0)==0 ){
- *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
- }else{
- rc = SQLITE_ERROR;
- }
-#endif
-
-#ifdef SQLITE_TEST
- if( sqlite3_current_time ){
- *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
- }
-#endif
- UNUSED_PARAMETER(NotUsed);
- return rc;
-}
-
-/*
-** Find the current time (in Universal Coordinated Time). Write the
-** current time and date as a Julian Day number into *prNow and
-** return 0. Return 1 if the time and date cannot be found.
-*/
-static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
- sqlite3_int64 i = 0;
- int rc;
- UNUSED_PARAMETER(NotUsed);
- rc = unixCurrentTimeInt64(0, &i);
- *prNow = i/86400000.0;
- return rc;
-}
-
-/*
-** We added the xGetLastError() method with the intention of providing
-** better low-level error messages when operating-system problems come up
-** during SQLite operation. But so far, none of that has been implemented
-** in the core. So this routine is never called. For now, it is merely
-** a place-holder.
-*/
-static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
- UNUSED_PARAMETER(NotUsed);
- UNUSED_PARAMETER(NotUsed2);
- UNUSED_PARAMETER(NotUsed3);
- return 0;
-}
-
-
-/*
-************************ End of sqlite3_vfs methods ***************************
-******************************************************************************/
-
-/******************************************************************************
-************************** Begin Proxy Locking ********************************
-**
-** Proxy locking is a "uber-locking-method" in this sense: It uses the
-** other locking methods on secondary lock files. Proxy locking is a
-** meta-layer over top of the primitive locking implemented above. For
-** this reason, the division that implements of proxy locking is deferred
-** until late in the file (here) after all of the other I/O methods have
-** been defined - so that the primitive locking methods are available
-** as services to help with the implementation of proxy locking.
-**
-****
-**
-** The default locking schemes in SQLite use byte-range locks on the
-** database file to coordinate safe, concurrent access by multiple readers
-** and writers [http://sqlite.org/lockingv3.html]. The five file locking
-** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented
-** as POSIX read & write locks over fixed set of locations (via fsctl),
-** on AFP and SMB only exclusive byte-range locks are available via fsctl
-** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states.
-** To simulate a F_RDLCK on the shared range, on AFP a randomly selected
-** address in the shared range is taken for a SHARED lock, the entire
-** shared range is taken for an EXCLUSIVE lock):
-**
-** PENDING_BYTE 0x40000000
-** RESERVED_BYTE 0x40000001
-** SHARED_RANGE 0x40000002 -> 0x40000200
-**
-** This works well on the local file system, but shows a nearly 100x
-** slowdown in read performance on AFP because the AFP client disables
-** the read cache when byte-range locks are present. Enabling the read
-** cache exposes a cache coherency problem that is present on all OS X
-** supported network file systems. NFS and AFP both observe the
-** close-to-open semantics for ensuring cache coherency
-** [http://nfs.sourceforge.net/#faq_a8], which does not effectively
-** address the requirements for concurrent database access by multiple
-** readers and writers
-** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html].
-**
-** To address the performance and cache coherency issues, proxy file locking
-** changes the way database access is controlled by limiting access to a
-** single host at a time and moving file locks off of the database file
-** and onto a proxy file on the local file system.
-**
-**
-** Using proxy locks
-** -----------------
-**
-** C APIs
-**
-** sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
-** <proxy_path> | ":auto:");
-** sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
-**
-**
-** SQL pragmas
-**
-** PRAGMA [database.]lock_proxy_file=<proxy_path> | :auto:
-** PRAGMA [database.]lock_proxy_file
-**
-** Specifying ":auto:" means that if there is a conch file with a matching
-** host ID in it, the proxy path in the conch file will be used, otherwise
-** a proxy path based on the user's temp dir
-** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the
-** actual proxy file name is generated from the name and path of the
-** database file. For example:
-**
-** For database path "/Users/me/foo.db"
-** The lock path will be "<tmpdir>/sqliteplocks/_Users_me_foo.db:auto:")
-**
-** Once a lock proxy is configured for a database connection, it can not
-** be removed, however it may be switched to a different proxy path via
-** the above APIs (assuming the conch file is not being held by another
-** connection or process).
-**
-**
-** How proxy locking works
-** -----------------------
-**
-** Proxy file locking relies primarily on two new supporting files:
-**
-** * conch file to limit access to the database file to a single host
-** at a time
-**
-** * proxy file to act as a proxy for the advisory locks normally
-** taken on the database
-**
-** The conch file - to use a proxy file, sqlite must first "hold the conch"
-** by taking an sqlite-style shared lock on the conch file, reading the
-** contents and comparing the host's unique host ID (see below) and lock
-** proxy path against the values stored in the conch. The conch file is
-** stored in the same directory as the database file and the file name
-** is patterned after the database file name as ".<databasename>-conch".
-** If the conch file does not exist, or it's contents do not match the
-** host ID and/or proxy path, then the lock is escalated to an exclusive
-** lock and the conch file contents is updated with the host ID and proxy
-** path and the lock is downgraded to a shared lock again. If the conch
-** is held by another process (with a shared lock), the exclusive lock
-** will fail and SQLITE_BUSY is returned.
-**
-** The proxy file - a single-byte file used for all advisory file locks
-** normally taken on the database file. This allows for safe sharing
-** of the database file for multiple readers and writers on the same
-** host (the conch ensures that they all use the same local lock file).
-**
-** Requesting the lock proxy does not immediately take the conch, it is
-** only taken when the first request to lock database file is made.
-** This matches the semantics of the traditional locking behavior, where
-** opening a connection to a database file does not take a lock on it.
-** The shared lock and an open file descriptor are maintained until
-** the connection to the database is closed.
-**
-** The proxy file and the lock file are never deleted so they only need
-** to be created the first time they are used.
-**
-** Configuration options
-** ---------------------
-**
-** SQLITE_PREFER_PROXY_LOCKING
-**
-** Database files accessed on non-local file systems are
-** automatically configured for proxy locking, lock files are
-** named automatically using the same logic as
-** PRAGMA lock_proxy_file=":auto:"
-**
-** SQLITE_PROXY_DEBUG
-**
-** Enables the logging of error messages during host id file
-** retrieval and creation
-**
-** LOCKPROXYDIR
-**
-** Overrides the default directory used for lock proxy files that
-** are named automatically via the ":auto:" setting
-**
-** SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
-**
-** Permissions to use when creating a directory for storing the
-** lock proxy files, only used when LOCKPROXYDIR is not set.
-**
-**
-** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING,
-** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will
-** force proxy locking to be used for every database file opened, and 0
-** will force automatic proxy locking to be disabled for all database
-** files (explicity calling the SQLITE_SET_LOCKPROXYFILE pragma or
-** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
-*/
-
-/*
-** Proxy locking is only available on MacOSX
-*/
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-
-/*
-** The proxyLockingContext has the path and file structures for the remote
-** and local proxy files in it
-*/
-typedef struct proxyLockingContext proxyLockingContext;
-struct proxyLockingContext {
- unixFile *conchFile; /* Open conch file */
- char *conchFilePath; /* Name of the conch file */
- unixFile *lockProxy; /* Open proxy lock file */
- char *lockProxyPath; /* Name of the proxy lock file */
- char *dbPath; /* Name of the open file */
- int conchHeld; /* 1 if the conch is held, -1 if lockless */
- void *oldLockingContext; /* Original lockingcontext to restore on close */
- sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */
-};
-
-/*
-** The proxy lock file path for the database at dbPath is written into lPath,
-** which must point to valid, writable memory large enough for a maxLen length
-** file path.
-*/
-static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
- int len;
- int dbLen;
- int i;
-
-#ifdef LOCKPROXYDIR
- len = strlcpy(lPath, LOCKPROXYDIR, maxLen);
-#else
-# ifdef _CS_DARWIN_USER_TEMP_DIR
- {
- if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){
- OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n",
- lPath, errno, getpid()));
- return SQLITE_IOERR_LOCK;
- }
- len = strlcat(lPath, "sqliteplocks", maxLen);
- }
-# else
- len = strlcpy(lPath, "/tmp/", maxLen);
-# endif
-#endif
-
- if( lPath[len-1]!='/' ){
- len = strlcat(lPath, "/", maxLen);
- }
-
- /* transform the db path to a unique cache name */
- dbLen = (int)strlen(dbPath);
- for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){
- char c = dbPath[i];
- lPath[i+len] = (c=='/')?'_':c;
- }
- lPath[i+len]='\0';
- strlcat(lPath, ":auto:", maxLen);
- OSTRACE(("GETLOCKPATH proxy lock path=%s pid=%d\n", lPath, getpid()));
- return SQLITE_OK;
-}
-
-/*
- ** Creates the lock file and any missing directories in lockPath
- */
-static int proxyCreateLockPath(const char *lockPath){
- int i, len;
- char buf[MAXPATHLEN];
- int start = 0;
-
- assert(lockPath!=NULL);
- /* try to create all the intermediate directories */
- len = (int)strlen(lockPath);
- buf[0] = lockPath[0];
- for( i=1; i<len; i++ ){
- if( lockPath[i] == '/' && (i - start > 0) ){
- /* only mkdir if leaf dir != "." or "/" or ".." */
- if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/')
- || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){
- buf[i]='\0';
- if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){
- int err=errno;
- if( err!=EEXIST ) {
- OSTRACE(("CREATELOCKPATH FAILED creating %s, "
- "'%s' proxy lock path=%s pid=%d\n",
- buf, strerror(err), lockPath, getpid()));
- return err;
- }
- }
- }
- start=i+1;
- }
- buf[i] = lockPath[i];
- }
- OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n", lockPath, getpid()));
- return 0;
-}
-
-/*
-** Create a new VFS file descriptor (stored in memory obtained from
-** sqlite3_malloc) and open the file named "path" in the file descriptor.
-**
-** The caller is responsible not only for closing the file descriptor
-** but also for freeing the memory associated with the file descriptor.
-*/
-static int proxyCreateUnixFile(
- const char *path, /* path for the new unixFile */
- unixFile **ppFile, /* unixFile created and returned by ref */
- int islockfile /* if non zero missing dirs will be created */
-) {
- int fd = -1;
- unixFile *pNew;
- int rc = SQLITE_OK;
- int openFlags = O_RDWR | O_CREAT;
- sqlite3_vfs dummyVfs;
- int terrno = 0;
- UnixUnusedFd *pUnused = NULL;
-
- /* 1. first try to open/create the file
- ** 2. if that fails, and this is a lock file (not-conch), try creating
- ** the parent directories and then try again.
- ** 3. if that fails, try to open the file read-only
- ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file
- */
- pUnused = findReusableFd(path, openFlags);
- if( pUnused ){
- fd = pUnused->fd;
- }else{
- pUnused = sqlite3_malloc(sizeof(*pUnused));
- if( !pUnused ){
- return SQLITE_NOMEM;
- }
- }
- if( fd<0 ){
- fd = robust_open(path, openFlags, 0);
- terrno = errno;
- if( fd<0 && errno==ENOENT && islockfile ){
- if( proxyCreateLockPath(path) == SQLITE_OK ){
- fd = robust_open(path, openFlags, 0);
- }
- }
- }
- if( fd<0 ){
- openFlags = O_RDONLY;
- fd = robust_open(path, openFlags, 0);
- terrno = errno;
- }
- if( fd<0 ){
- if( islockfile ){
- return SQLITE_BUSY;
- }
- switch (terrno) {
- case EACCES:
- return SQLITE_PERM;
- case EIO:
- return SQLITE_IOERR_LOCK; /* even though it is the conch */
- default:
- return SQLITE_CANTOPEN_BKPT;
- }
- }
-
- pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
- if( pNew==NULL ){
- rc = SQLITE_NOMEM;
- goto end_create_proxy;
- }
- memset(pNew, 0, sizeof(unixFile));
- pNew->openFlags = openFlags;
- memset(&dummyVfs, 0, sizeof(dummyVfs));
- dummyVfs.pAppData = (void*)&autolockIoFinder;
- dummyVfs.zName = "dummy";
- pUnused->fd = fd;
- pUnused->flags = openFlags;
- pNew->pUnused = pUnused;
-
- rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0);
- if( rc==SQLITE_OK ){
- *ppFile = pNew;
- return SQLITE_OK;
- }
-end_create_proxy:
- robust_close(pNew, fd, __LINE__);
- sqlite3_free(pNew);
- sqlite3_free(pUnused);
- return rc;
-}
-
-#ifdef SQLITE_TEST
-/* simulate multiple hosts by creating unique hostid file paths */
-SQLITE_API int sqlite3_hostid_num = 0;
-#endif
-
-#define PROXY_HOSTIDLEN 16 /* conch file host id length */
-
-/* Not always defined in the headers as it ought to be */
-extern int gethostuuid(uuid_t id, const struct timespec *wait);
-
-/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN
-** bytes of writable memory.
-*/
-static int proxyGetHostID(unsigned char *pHostID, int *pError){
- assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
- memset(pHostID, 0, PROXY_HOSTIDLEN);
-#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\
- && __MAC_OS_X_VERSION_MIN_REQUIRED<1050
- {
- static const struct timespec timeout = {1, 0}; /* 1 sec timeout */
- if( gethostuuid(pHostID, &timeout) ){
- int err = errno;
- if( pError ){
- *pError = err;
- }
- return SQLITE_IOERR;
- }
- }
-#else
- UNUSED_PARAMETER(pError);
-#endif
-#ifdef SQLITE_TEST
- /* simulate multiple hosts by creating unique hostid file paths */
- if( sqlite3_hostid_num != 0){
- pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF));
- }
-#endif
-
- return SQLITE_OK;
-}
-
-/* The conch file contains the header, host id and lock file path
- */
-#define PROXY_CONCHVERSION 2 /* 1-byte header, 16-byte host id, path */
-#define PROXY_HEADERLEN 1 /* conch file header length */
-#define PROXY_PATHINDEX (PROXY_HEADERLEN+PROXY_HOSTIDLEN)
-#define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN)
-
-/*
-** Takes an open conch file, copies the contents to a new path and then moves
-** it back. The newly created file's file descriptor is assigned to the
-** conch file structure and finally the original conch file descriptor is
-** closed. Returns zero if successful.
-*/
-static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- unixFile *conchFile = pCtx->conchFile;
- char tPath[MAXPATHLEN];
- char buf[PROXY_MAXCONCHLEN];
- char *cPath = pCtx->conchFilePath;
- size_t readLen = 0;
- size_t pathLen = 0;
- char errmsg[64] = "";
- int fd = -1;
- int rc = -1;
- UNUSED_PARAMETER(myHostID);
-
- /* create a new path by replace the trailing '-conch' with '-break' */
- pathLen = strlcpy(tPath, cPath, MAXPATHLEN);
- if( pathLen>MAXPATHLEN || pathLen<6 ||
- (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){
- sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen);
- goto end_breaklock;
- }
- /* read the conch content */
- readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0);
- if( readLen<PROXY_PATHINDEX ){
- sqlite3_snprintf(sizeof(errmsg),errmsg,"read error (len %d)",(int)readLen);
- goto end_breaklock;
- }
- /* write it out to the temporary break file */
- fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), 0);
- if( fd<0 ){
- sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno);
- goto end_breaklock;
- }
- if( osPwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){
- sqlite3_snprintf(sizeof(errmsg), errmsg, "write failed (%d)", errno);
- goto end_breaklock;
- }
- if( rename(tPath, cPath) ){
- sqlite3_snprintf(sizeof(errmsg), errmsg, "rename failed (%d)", errno);
- goto end_breaklock;
- }
- rc = 0;
- fprintf(stderr, "broke stale lock on %s\n", cPath);
- robust_close(pFile, conchFile->h, __LINE__);
- conchFile->h = fd;
- conchFile->openFlags = O_RDWR | O_CREAT;
-
-end_breaklock:
- if( rc ){
- if( fd>=0 ){
- osUnlink(tPath);
- robust_close(pFile, fd, __LINE__);
- }
- fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg);
- }
- return rc;
-}
-
-/* Take the requested lock on the conch file and break a stale lock if the
-** host id matches.
-*/
-static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- unixFile *conchFile = pCtx->conchFile;
- int rc = SQLITE_OK;
- int nTries = 0;
- struct timespec conchModTime;
-
- memset(&conchModTime, 0, sizeof(conchModTime));
- do {
- rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
- nTries ++;
- if( rc==SQLITE_BUSY ){
- /* If the lock failed (busy):
- * 1st try: get the mod time of the conch, wait 0.5s and try again.
- * 2nd try: fail if the mod time changed or host id is different, wait
- * 10 sec and try again
- * 3rd try: break the lock unless the mod time has changed.
- */
- struct stat buf;
- if( osFstat(conchFile->h, &buf) ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR_LOCK;
- }
-
- if( nTries==1 ){
- conchModTime = buf.st_mtimespec;
- usleep(500000); /* wait 0.5 sec and try the lock again*/
- continue;
- }
-
- assert( nTries>1 );
- if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec ||
- conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){
- return SQLITE_BUSY;
- }
-
- if( nTries==2 ){
- char tBuf[PROXY_MAXCONCHLEN];
- int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
- if( len<0 ){
- pFile->lastErrno = errno;
- return SQLITE_IOERR_LOCK;
- }
- if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
- /* don't break the lock if the host id doesn't match */
- if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){
- return SQLITE_BUSY;
- }
- }else{
- /* don't break the lock on short read or a version mismatch */
- return SQLITE_BUSY;
- }
- usleep(10000000); /* wait 10 sec and try the lock again */
- continue;
- }
-
- assert( nTries==3 );
- if( 0==proxyBreakConchLock(pFile, myHostID) ){
- rc = SQLITE_OK;
- if( lockType==EXCLUSIVE_LOCK ){
- rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
- }
- if( !rc ){
- rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
- }
- }
- }
- } while( rc==SQLITE_BUSY && nTries<3 );
-
- return rc;
-}
-
-/* Takes the conch by taking a shared lock and read the contents conch, if
-** lockPath is non-NULL, the host ID and lock file path must match. A NULL
-** lockPath means that the lockPath in the conch file will be used if the
-** host IDs match, or a new lock path will be generated automatically
-** and written to the conch file.
-*/
-static int proxyTakeConch(unixFile *pFile){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
-
- if( pCtx->conchHeld!=0 ){
- return SQLITE_OK;
- }else{
- unixFile *conchFile = pCtx->conchFile;
- uuid_t myHostID;
- int pError = 0;
- char readBuf[PROXY_MAXCONCHLEN];
- char lockPath[MAXPATHLEN];
- char *tempLockPath = NULL;
- int rc = SQLITE_OK;
- int createConch = 0;
- int hostIdMatch = 0;
- int readLen = 0;
- int tryOldLockPath = 0;
- int forceNewLockPath = 0;
-
- OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h,
- (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()));
-
- rc = proxyGetHostID(myHostID, &pError);
- if( (rc&0xff)==SQLITE_IOERR ){
- pFile->lastErrno = pError;
- goto end_takeconch;
- }
- rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
- if( rc!=SQLITE_OK ){
- goto end_takeconch;
- }
- /* read the existing conch file */
- readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN);
- if( readLen<0 ){
- /* I/O error: lastErrno set by seekAndRead */
- pFile->lastErrno = conchFile->lastErrno;
- rc = SQLITE_IOERR_READ;
- goto end_takeconch;
- }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) ||
- readBuf[0]!=(char)PROXY_CONCHVERSION ){
- /* a short read or version format mismatch means we need to create a new
- ** conch file.
- */
- createConch = 1;
- }
- /* if the host id matches and the lock path already exists in the conch
- ** we'll try to use the path there, if we can't open that path, we'll
- ** retry with a new auto-generated path
- */
- do { /* in case we need to try again for an :auto: named lock file */
-
- if( !createConch && !forceNewLockPath ){
- hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID,
- PROXY_HOSTIDLEN);
- /* if the conch has data compare the contents */
- if( !pCtx->lockProxyPath ){
- /* for auto-named local lock file, just check the host ID and we'll
- ** use the local lock file path that's already in there
- */
- if( hostIdMatch ){
- size_t pathLen = (readLen - PROXY_PATHINDEX);
-
- if( pathLen>=MAXPATHLEN ){
- pathLen=MAXPATHLEN-1;
- }
- memcpy(lockPath, &readBuf[PROXY_PATHINDEX], pathLen);
- lockPath[pathLen] = 0;
- tempLockPath = lockPath;
- tryOldLockPath = 1;
- /* create a copy of the lock path if the conch is taken */
- goto end_takeconch;
- }
- }else if( hostIdMatch
- && !strncmp(pCtx->lockProxyPath, &readBuf[PROXY_PATHINDEX],
- readLen-PROXY_PATHINDEX)
- ){
- /* conch host and lock path match */
- goto end_takeconch;
- }
- }
-
- /* if the conch isn't writable and doesn't match, we can't take it */
- if( (conchFile->openFlags&O_RDWR) == 0 ){
- rc = SQLITE_BUSY;
- goto end_takeconch;
- }
-
- /* either the conch didn't match or we need to create a new one */
- if( !pCtx->lockProxyPath ){
- proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN);
- tempLockPath = lockPath;
- /* create a copy of the lock path _only_ if the conch is taken */
- }
-
- /* update conch with host and path (this will fail if other process
- ** has a shared lock already), if the host id matches, use the big
- ** stick.
- */
- futimes(conchFile->h, NULL);
- if( hostIdMatch && !createConch ){
- if( conchFile->pInode && conchFile->pInode->nShared>1 ){
- /* We are trying for an exclusive lock but another thread in this
- ** same process is still holding a shared lock. */
- rc = SQLITE_BUSY;
- } else {
- rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
- }
- }else{
- rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
- }
- if( rc==SQLITE_OK ){
- char writeBuffer[PROXY_MAXCONCHLEN];
- int writeSize = 0;
-
- writeBuffer[0] = (char)PROXY_CONCHVERSION;
- memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN);
- if( pCtx->lockProxyPath!=NULL ){
- strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN);
- }else{
- strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN);
- }
- writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]);
- robust_ftruncate(conchFile->h, writeSize);
- rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0);
- fsync(conchFile->h);
- /* If we created a new conch file (not just updated the contents of a
- ** valid conch file), try to match the permissions of the database
- */
- if( rc==SQLITE_OK && createConch ){
- struct stat buf;
- int err = osFstat(pFile->h, &buf);
- if( err==0 ){
- mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP |
- S_IROTH|S_IWOTH);
- /* try to match the database file R/W permissions, ignore failure */
-#ifndef SQLITE_PROXY_DEBUG
- osFchmod(conchFile->h, cmode);
-#else
- do{
- rc = osFchmod(conchFile->h, cmode);
- }while( rc==(-1) && errno==EINTR );
- if( rc!=0 ){
- int code = errno;
- fprintf(stderr, "fchmod %o FAILED with %d %s\n",
- cmode, code, strerror(code));
- } else {
- fprintf(stderr, "fchmod %o SUCCEDED\n",cmode);
- }
- }else{
- int code = errno;
- fprintf(stderr, "STAT FAILED[%d] with %d %s\n",
- err, code, strerror(code));
-#endif
- }
- }
- }
- conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK);
-
- end_takeconch:
- OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h));
- if( rc==SQLITE_OK && pFile->openFlags ){
- int fd;
- if( pFile->h>=0 ){
- robust_close(pFile, pFile->h, __LINE__);
- }
- pFile->h = -1;
- fd = robust_open(pCtx->dbPath, pFile->openFlags, 0);
- OSTRACE(("TRANSPROXY: OPEN %d\n", fd));
- if( fd>=0 ){
- pFile->h = fd;
- }else{
- rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called
- during locking */
- }
- }
- if( rc==SQLITE_OK && !pCtx->lockProxy ){
- char *path = tempLockPath ? tempLockPath : pCtx->lockProxyPath;
- rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1);
- if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){
- /* we couldn't create the proxy lock file with the old lock file path
- ** so try again via auto-naming
- */
- forceNewLockPath = 1;
- tryOldLockPath = 0;
- continue; /* go back to the do {} while start point, try again */
- }
- }
- if( rc==SQLITE_OK ){
- /* Need to make a copy of path if we extracted the value
- ** from the conch file or the path was allocated on the stack
- */
- if( tempLockPath ){
- pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath);
- if( !pCtx->lockProxyPath ){
- rc = SQLITE_NOMEM;
- }
- }
- }
- if( rc==SQLITE_OK ){
- pCtx->conchHeld = 1;
-
- if( pCtx->lockProxy->pMethod == &afpIoMethods ){
- afpLockingContext *afpCtx;
- afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext;
- afpCtx->dbPath = pCtx->lockProxyPath;
- }
- } else {
- conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
- }
- OSTRACE(("TAKECONCH %d %s\n", conchFile->h,
- rc==SQLITE_OK?"ok":"failed"));
- return rc;
- } while (1); /* in case we need to retry the :auto: lock file -
- ** we should never get here except via the 'continue' call. */
- }
-}
-
-/*
-** If pFile holds a lock on a conch file, then release that lock.
-*/
-static int proxyReleaseConch(unixFile *pFile){
- int rc = SQLITE_OK; /* Subroutine return code */
- proxyLockingContext *pCtx; /* The locking context for the proxy lock */
- unixFile *conchFile; /* Name of the conch file */
-
- pCtx = (proxyLockingContext *)pFile->lockingContext;
- conchFile = pCtx->conchFile;
- OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h,
- (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
- getpid()));
- if( pCtx->conchHeld>0 ){
- rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
- }
- pCtx->conchHeld = 0;
- OSTRACE(("RELEASECONCH %d %s\n", conchFile->h,
- (rc==SQLITE_OK ? "ok" : "failed")));
- return rc;
-}
-
-/*
-** Given the name of a database file, compute the name of its conch file.
-** Store the conch filename in memory obtained from sqlite3_malloc().
-** Make *pConchPath point to the new name. Return SQLITE_OK on success
-** or SQLITE_NOMEM if unable to obtain memory.
-**
-** The caller is responsible for ensuring that the allocated memory
-** space is eventually freed.
-**
-** *pConchPath is set to NULL if a memory allocation error occurs.
-*/
-static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
- int i; /* Loop counter */
- int len = (int)strlen(dbPath); /* Length of database filename - dbPath */
- char *conchPath; /* buffer in which to construct conch name */
-
- /* Allocate space for the conch filename and initialize the name to
- ** the name of the original database file. */
- *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8);
- if( conchPath==0 ){
- return SQLITE_NOMEM;
- }
- memcpy(conchPath, dbPath, len+1);
-
- /* now insert a "." before the last / character */
- for( i=(len-1); i>=0; i-- ){
- if( conchPath[i]=='/' ){
- i++;
- break;
- }
- }
- conchPath[i]='.';
- while ( i<len ){
- conchPath[i+1]=dbPath[i];
- i++;
- }
-
- /* append the "-conch" suffix to the file */
- memcpy(&conchPath[i+1], "-conch", 7);
- assert( (int)strlen(conchPath) == len+7 );
-
- return SQLITE_OK;
-}
-
-
-/* Takes a fully configured proxy locking-style unix file and switches
-** the local lock file path
-*/
-static int switchLockProxyPath(unixFile *pFile, const char *path) {
- proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
- char *oldPath = pCtx->lockProxyPath;
- int rc = SQLITE_OK;
-
- if( pFile->eFileLock!=NO_LOCK ){
- return SQLITE_BUSY;
- }
-
- /* nothing to do if the path is NULL, :auto: or matches the existing path */
- if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ||
- (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){
- return SQLITE_OK;
- }else{
- unixFile *lockProxy = pCtx->lockProxy;
- pCtx->lockProxy=NULL;
- pCtx->conchHeld = 0;
- if( lockProxy!=NULL ){
- rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy);
- if( rc ) return rc;
- sqlite3_free(lockProxy);
- }
- sqlite3_free(oldPath);
- pCtx->lockProxyPath = sqlite3DbStrDup(0, path);
- }
-
- return rc;
-}
-
-/*
-** pFile is a file that has been opened by a prior xOpen call. dbPath
-** is a string buffer at least MAXPATHLEN+1 characters in size.
-**
-** This routine find the filename associated with pFile and writes it
-** int dbPath.
-*/
-static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
-#if defined(__APPLE__)
- if( pFile->pMethod == &afpIoMethods ){
- /* afp style keeps a reference to the db path in the filePath field
- ** of the struct */
- assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
- strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPATHLEN);
- } else
-#endif
- if( pFile->pMethod == &dotlockIoMethods ){
- /* dot lock style uses the locking context to store the dot lock
- ** file path */
- int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX);
- memcpy(dbPath, (char *)pFile->lockingContext, len + 1);
- }else{
- /* all other styles use the locking context to store the db file path */
- assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
- strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN);
- }
- return SQLITE_OK;
-}
-
-/*
-** Takes an already filled in unix file and alters it so all file locking
-** will be performed on the local proxy lock file. The following fields
-** are preserved in the locking context so that they can be restored and
-** the unix structure properly cleaned up at close time:
-** ->lockingContext
-** ->pMethod
-*/
-static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
- proxyLockingContext *pCtx;
- char dbPath[MAXPATHLEN+1]; /* Name of the database file */
- char *lockPath=NULL;
- int rc = SQLITE_OK;
-
- if( pFile->eFileLock!=NO_LOCK ){
- return SQLITE_BUSY;
- }
- proxyGetDbPathForUnixFile(pFile, dbPath);
- if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){
- lockPath=NULL;
- }else{
- lockPath=(char *)path;
- }
-
- OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h,
- (lockPath ? lockPath : ":auto:"), getpid()));
-
- pCtx = sqlite3_malloc( sizeof(*pCtx) );
- if( pCtx==0 ){
- return SQLITE_NOMEM;
- }
- memset(pCtx, 0, sizeof(*pCtx));
-
- rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath);
- if( rc==SQLITE_OK ){
- rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0);
- if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){
- /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and
- ** (c) the file system is read-only, then enable no-locking access.
- ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts
- ** that openFlags will have only one of O_RDONLY or O_RDWR.
- */
- struct statfs fsInfo;
- struct stat conchInfo;
- int goLockless = 0;
-
- if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) {
- int err = errno;
- if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){
- goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY;
- }
- }
- if( goLockless ){
- pCtx->conchHeld = -1; /* read only FS/ lockless */
- rc = SQLITE_OK;
- }
- }
- }
- if( rc==SQLITE_OK && lockPath ){
- pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath);
- }
-
- if( rc==SQLITE_OK ){
- pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
- if( pCtx->dbPath==NULL ){
- rc = SQLITE_NOMEM;
- }
- }
- if( rc==SQLITE_OK ){
- /* all memory is allocated, proxys are created and assigned,
- ** switch the locking context and pMethod then return.
- */
- pCtx->oldLockingContext = pFile->lockingContext;
- pFile->lockingContext = pCtx;
- pCtx->pOldMethod = pFile->pMethod;
- pFile->pMethod = &proxyIoMethods;
- }else{
- if( pCtx->conchFile ){
- pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
- sqlite3_free(pCtx->conchFile);
- }
- sqlite3DbFree(0, pCtx->lockProxyPath);
- sqlite3_free(pCtx->conchFilePath);
- sqlite3_free(pCtx);
- }
- OSTRACE(("TRANSPROXY %d %s\n", pFile->h,
- (rc==SQLITE_OK ? "ok" : "failed")));
- return rc;
-}
-
-
-/*
-** This routine handles sqlite3_file_control() calls that are specific
-** to proxy locking.
-*/
-static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
- switch( op ){
- case SQLITE_GET_LOCKPROXYFILE: {
- unixFile *pFile = (unixFile*)id;
- if( pFile->pMethod == &proxyIoMethods ){
- proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
- proxyTakeConch(pFile);
- if( pCtx->lockProxyPath ){
- *(const char **)pArg = pCtx->lockProxyPath;
- }else{
- *(const char **)pArg = ":auto: (not held)";
- }
- } else {
- *(const char **)pArg = NULL;
- }
- return SQLITE_OK;
- }
- case SQLITE_SET_LOCKPROXYFILE: {
- unixFile *pFile = (unixFile*)id;
- int rc = SQLITE_OK;
- int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
- if( pArg==NULL || (const char *)pArg==0 ){
- if( isProxyStyle ){
- /* turn off proxy locking - not supported */
- rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
- }else{
- /* turn off proxy locking - already off - NOOP */
- rc = SQLITE_OK;
- }
- }else{
- const char *proxyPath = (const char *)pArg;
- if( isProxyStyle ){
- proxyLockingContext *pCtx =
- (proxyLockingContext*)pFile->lockingContext;
- if( !strcmp(pArg, ":auto:")
- || (pCtx->lockProxyPath &&
- !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN))
- ){
- rc = SQLITE_OK;
- }else{
- rc = switchLockProxyPath(pFile, proxyPath);
- }
- }else{
- /* turn on proxy file locking */
- rc = proxyTransformUnixFile(pFile, proxyPath);
- }
- }
- return rc;
- }
- default: {
- assert( 0 ); /* The call assures that only valid opcodes are sent */
- }
- }
- /*NOTREACHED*/
- return SQLITE_ERROR;
-}
-
-/*
-** Within this division (the proxying locking implementation) the procedures
-** above this point are all utilities. The lock-related methods of the
-** proxy-locking sqlite3_io_method object follow.
-*/
-
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, set *pResOut
-** to a non-zero value otherwise *pResOut is set to zero. The return value
-** is set to SQLITE_OK unless an I/O error occurs during lock checking.
-*/
-static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) {
- unixFile *pFile = (unixFile*)id;
- int rc = proxyTakeConch(pFile);
- if( rc==SQLITE_OK ){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- if( pCtx->conchHeld>0 ){
- unixFile *proxy = pCtx->lockProxy;
- return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut);
- }else{ /* conchHeld < 0 is lockless */
- pResOut=0;
- }
- }
- return rc;
-}
-
-/*
-** Lock the file with the lock specified by parameter eFileLock - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. Use the sqlite3OsUnlock()
-** routine to lower a locking level.
-*/
-static int proxyLock(sqlite3_file *id, int eFileLock) {
- unixFile *pFile = (unixFile*)id;
- int rc = proxyTakeConch(pFile);
- if( rc==SQLITE_OK ){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- if( pCtx->conchHeld>0 ){
- unixFile *proxy = pCtx->lockProxy;
- rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock);
- pFile->eFileLock = proxy->eFileLock;
- }else{
- /* conchHeld < 0 is lockless */
- }
- }
- return rc;
-}
-
-
-/*
-** Lower the locking level on file descriptor pFile to eFileLock. eFileLock
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-*/
-static int proxyUnlock(sqlite3_file *id, int eFileLock) {
- unixFile *pFile = (unixFile*)id;
- int rc = proxyTakeConch(pFile);
- if( rc==SQLITE_OK ){
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- if( pCtx->conchHeld>0 ){
- unixFile *proxy = pCtx->lockProxy;
- rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock);
- pFile->eFileLock = proxy->eFileLock;
- }else{
- /* conchHeld < 0 is lockless */
- }
- }
- return rc;
-}
-
-/*
-** Close a file that uses proxy locks.
-*/
-static int proxyClose(sqlite3_file *id) {
- if( id ){
- unixFile *pFile = (unixFile*)id;
- proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
- unixFile *lockProxy = pCtx->lockProxy;
- unixFile *conchFile = pCtx->conchFile;
- int rc = SQLITE_OK;
-
- if( lockProxy ){
- rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK);
- if( rc ) return rc;
- rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy);
- if( rc ) return rc;
- sqlite3_free(lockProxy);
- pCtx->lockProxy = 0;
- }
- if( conchFile ){
- if( pCtx->conchHeld ){
- rc = proxyReleaseConch(pFile);
- if( rc ) return rc;
- }
- rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile);
- if( rc ) return rc;
- sqlite3_free(conchFile);
- }
- sqlite3DbFree(0, pCtx->lockProxyPath);
- sqlite3_free(pCtx->conchFilePath);
- sqlite3DbFree(0, pCtx->dbPath);
- /* restore the original locking context and pMethod then close it */
- pFile->lockingContext = pCtx->oldLockingContext;
- pFile->pMethod = pCtx->pOldMethod;
- sqlite3_free(pCtx);
- return pFile->pMethod->xClose(id);
- }
- return SQLITE_OK;
-}
-
-
-
-#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-/*
-** The proxy locking style is intended for use with AFP filesystems.
-** And since AFP is only supported on MacOSX, the proxy locking is also
-** restricted to MacOSX.
-**
-**
-******************* End of the proxy lock implementation **********************
-******************************************************************************/
-
-/*
-** Initialize the operating system interface.
-**
-** This routine registers all VFS implementations for unix-like operating
-** systems. This routine, and the sqlite3_os_end() routine that follows,
-** should be the only routines in this file that are visible from other
-** files.
-**
-** This routine is called once during SQLite initialization and by a
-** single thread. The memory allocation and mutex subsystems have not
-** necessarily been initialized when this routine is called, and so they
-** should not be used.
-*/
-SQLITE_API int sqlite3_os_init(void){
- /*
- ** The following macro defines an initializer for an sqlite3_vfs object.
- ** The name of the VFS is NAME. The pAppData is a pointer to a pointer
- ** to the "finder" function. (pAppData is a pointer to a pointer because
- ** silly C90 rules prohibit a void* from being cast to a function pointer
- ** and so we have to go through the intermediate pointer to avoid problems
- ** when compiling with -pedantic-errors on GCC.)
- **
- ** The FINDER parameter to this macro is the name of the pointer to the
- ** finder-function. The finder-function returns a pointer to the
- ** sqlite_io_methods object that implements the desired locking
- ** behaviors. See the division above that contains the IOMETHODS
- ** macro for addition information on finder-functions.
- **
- ** Most finders simply return a pointer to a fixed sqlite3_io_methods
- ** object. But the "autolockIoFinder" available on MacOSX does a little
- ** more than that; it looks at the filesystem type that hosts the
- ** database file and tries to choose an locking method appropriate for
- ** that filesystem time.
- */
- #define UNIXVFS(VFSNAME, FINDER) { \
- 3, /* iVersion */ \
- sizeof(unixFile), /* szOsFile */ \
- MAX_PATHNAME, /* mxPathname */ \
- 0, /* pNext */ \
- VFSNAME, /* zName */ \
- (void*)&FINDER, /* pAppData */ \
- unixOpen, /* xOpen */ \
- unixDelete, /* xDelete */ \
- unixAccess, /* xAccess */ \
- unixFullPathname, /* xFullPathname */ \
- unixDlOpen, /* xDlOpen */ \
- unixDlError, /* xDlError */ \
- unixDlSym, /* xDlSym */ \
- unixDlClose, /* xDlClose */ \
- unixRandomness, /* xRandomness */ \
- unixSleep, /* xSleep */ \
- unixCurrentTime, /* xCurrentTime */ \
- unixGetLastError, /* xGetLastError */ \
- unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \
- unixSetSystemCall, /* xSetSystemCall */ \
- unixGetSystemCall, /* xGetSystemCall */ \
- unixNextSystemCall, /* xNextSystemCall */ \
- }
-
- /*
- ** All default VFSes for unix are contained in the following array.
- **
- ** Note that the sqlite3_vfs.pNext field of the VFS object is modified
- ** by the SQLite core when the VFS is registered. So the following
- ** array cannot be const.
- */
- static sqlite3_vfs aVfs[] = {
-#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
- UNIXVFS("unix", autolockIoFinder ),
-#else
- UNIXVFS("unix", posixIoFinder ),
-#endif
- UNIXVFS("unix-none", nolockIoFinder ),
- UNIXVFS("unix-dotfile", dotlockIoFinder ),
- UNIXVFS("unix-excl", posixIoFinder ),
-#if OS_VXWORKS
- UNIXVFS("unix-namedsem", semIoFinder ),
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE
- UNIXVFS("unix-posix", posixIoFinder ),
-#if !OS_VXWORKS
- UNIXVFS("unix-flock", flockIoFinder ),
-#endif
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- UNIXVFS("unix-afp", afpIoFinder ),
- UNIXVFS("unix-nfs", nfsIoFinder ),
- UNIXVFS("unix-proxy", proxyIoFinder ),
-#endif
- };
- unsigned int i; /* Loop counter */
-
- /* Double-check that the aSyscall[] array has been constructed
- ** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==22 );
-
- /* Register all VFSes defined in the aVfs[] array */
- for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
- sqlite3_vfs_register(&aVfs[i], i==0);
- }
- return SQLITE_OK;
-}
-
-/*
-** Shutdown the operating system interface.
-**
-** Some operating systems might need to do some cleanup in this routine,
-** to release dynamically allocated objects. But not on unix.
-** This routine is a no-op for unix.
-*/
-SQLITE_API int sqlite3_os_end(void){
- return SQLITE_OK;
-}
-
-#endif /* SQLITE_OS_UNIX */
-
-/************** End of os_unix.c *********************************************/
-/************** Begin file os_win.c ******************************************/
-/*
-** 2004 May 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains code that is specific to Windows.
-*/
-#if SQLITE_OS_WIN /* This file is used for Windows only */
-
-#ifdef __CYGWIN__
-# include <sys/cygwin.h>
-#endif
-
-/*
-** Include code that is common to all os_*.c files
-*/
-/************** Include os_common.h in the middle of os_win.c ****************/
-/************** Begin file os_common.h ***************************************/
-/*
-** 2004 May 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains macros and a little bit of code that is common to
-** all of the platform-specific files (os_*.c) and is #included into those
-** files.
-**
-** This file should be #included by the os_*.c files only. It is not a
-** general purpose header file.
-*/
-#ifndef _OS_COMMON_H_
-#define _OS_COMMON_H_
-
-/*
-** At least two bugs have slipped in because we changed the MEMORY_DEBUG
-** macro to SQLITE_DEBUG and some older makefiles have not yet made the
-** switch. The following code should catch this problem at compile-time.
-*/
-#ifdef MEMORY_DEBUG
-# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
-#endif
-
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-# ifndef SQLITE_DEBUG_OS_TRACE
-# define SQLITE_DEBUG_OS_TRACE 0
-# endif
- int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
-# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X
-#else
-# define OSTRACE(X)
-#endif
-
-/*
-** Macros for performance tracing. Normally turned off. Only works
-** on i486 hardware.
-*/
-#ifdef SQLITE_PERFORMANCE_TRACE
-
-/*
-** hwtime.h contains inline assembler code for implementing
-** high-performance timing routines.
-*/
-/************** Include hwtime.h in the middle of os_common.h ****************/
-/************** Begin file hwtime.h ******************************************/
-/*
-** 2008 May 27
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
-*/
-#ifndef _HWTIME_H_
-#define _HWTIME_H_
-
-/*
-** The following routine only works on pentium-class (or newer) processors.
-** It uses the RDTSC opcode to read the cycle count value out of the
-** processor and returns that value. This can be used for high-res
-** profiling.
-*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
-
- #if defined(__GNUC__)
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
- #elif defined(_MSC_VER)
-
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
- __asm {
- rdtsc
- ret ; return value at EDX:EAX
- }
- }
-
- #endif
-
-#elif (defined(__GNUC__) && defined(__x86_64__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long val;
- __asm__ __volatile__ ("rdtsc" : "=A" (val));
- return val;
- }
-
-#elif (defined(__GNUC__) && defined(__ppc__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long long retval;
- unsigned long junk;
- __asm__ __volatile__ ("\n\
- 1: mftbu %1\n\
- mftb %L0\n\
- mftbu %0\n\
- cmpw %0,%1\n\
- bne 1b"
- : "=r" (retval), "=r" (junk));
- return retval;
- }
-
-#else
-
- #error Need implementation of sqlite3Hwtime() for your platform.
-
- /*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
- */
-SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-
-#endif
-
-#endif /* !defined(_HWTIME_H_) */
-
-/************** End of hwtime.h **********************************************/
-/************** Continuing where we left off in os_common.h ******************/
-
-static sqlite_uint64 g_start;
-static sqlite_uint64 g_elapsed;
-#define TIMER_START g_start=sqlite3Hwtime()
-#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start
-#define TIMER_ELAPSED g_elapsed
-#else
-#define TIMER_START
-#define TIMER_END
-#define TIMER_ELAPSED ((sqlite_uint64)0)
-#endif
-
-/*
-** If we compile with the SQLITE_TEST macro set, then the following block
-** of code will give us the ability to simulate a disk I/O error. This
-** is used for testing the I/O recovery logic.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */
-SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */
-SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */
-SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */
-SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */
-SQLITE_API int sqlite3_diskfull_pending = 0;
-SQLITE_API int sqlite3_diskfull = 0;
-#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
-#define SimulateIOError(CODE) \
- if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
- || sqlite3_io_error_pending-- == 1 ) \
- { local_ioerr(); CODE; }
-static void local_ioerr(){
- IOTRACE(("IOERR\n"));
- sqlite3_io_error_hit++;
- if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
-}
-#define SimulateDiskfullError(CODE) \
- if( sqlite3_diskfull_pending ){ \
- if( sqlite3_diskfull_pending == 1 ){ \
- local_ioerr(); \
- sqlite3_diskfull = 1; \
- sqlite3_io_error_hit = 1; \
- CODE; \
- }else{ \
- sqlite3_diskfull_pending--; \
- } \
- }
-#else
-#define SimulateIOErrorBenign(X)
-#define SimulateIOError(A)
-#define SimulateDiskfullError(A)
-#endif
-
-/*
-** When testing, keep a count of the number of open files.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_open_file_count = 0;
-#define OpenCounter(X) sqlite3_open_file_count+=(X)
-#else
-#define OpenCounter(X)
-#endif
-
-#endif /* !defined(_OS_COMMON_H_) */
-
-/************** End of os_common.h *******************************************/
-/************** Continuing where we left off in os_win.c *********************/
-
-/*
-** Compiling and using WAL mode requires several APIs that are only
-** available in Windows platforms based on the NT kernel.
-*/
-#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
-# error "WAL mode requires support from the Windows NT kernel, compile\
- with SQLITE_OMIT_WAL."
-#endif
-
-/*
-** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
-** based on the sub-platform)?
-*/
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-# define SQLITE_WIN32_HAS_ANSI
-#endif
-
-/*
-** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
-** based on the sub-platform)?
-*/
-#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
-# define SQLITE_WIN32_HAS_WIDE
-#endif
-
-/*
-** Do we need to manually define the Win32 file mapping APIs for use with WAL
-** mode (e.g. these APIs are available in the Windows CE SDK; however, they
-** are not present in the header file)?
-*/
-#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
-/*
-** Two of the file mapping APIs are different under WinRT. Figure out which
-** set we need.
-*/
-#if SQLITE_OS_WINRT
-WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
- LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);
-
-WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T);
-#else
-#if defined(SQLITE_WIN32_HAS_ANSI)
-WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \
- DWORD, DWORD, DWORD, LPCSTR);
-#endif /* defined(SQLITE_WIN32_HAS_ANSI) */
-
-#if defined(SQLITE_WIN32_HAS_WIDE)
-WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \
- DWORD, DWORD, DWORD, LPCWSTR);
-#endif /* defined(SQLITE_WIN32_HAS_WIDE) */
-
-WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
-#endif /* SQLITE_OS_WINRT */
-
-/*
-** This file mapping API is common to both Win32 and WinRT.
-*/
-WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
-#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
-
-/*
-** Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
-/*
-** Some Microsoft compilers lack this definition.
-*/
-#ifndef INVALID_FILE_ATTRIBUTES
-# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
-#endif
-
-#ifndef FILE_FLAG_MASK
-# define FILE_FLAG_MASK (0xFF3C0000)
-#endif
-
-#ifndef FILE_ATTRIBUTE_MASK
-# define FILE_ATTRIBUTE_MASK (0x0003FFF7)
-#endif
-
-#ifndef SQLITE_OMIT_WAL
-/* Forward references */
-typedef struct winShm winShm; /* A connection to shared-memory */
-typedef struct winShmNode winShmNode; /* A region of shared-memory */
-#endif
-
-/*
-** WinCE lacks native support for file locking so we have to fake it
-** with some code of our own.
-*/
-#if SQLITE_OS_WINCE
-typedef struct winceLock {
- int nReaders; /* Number of reader locks obtained */
- BOOL bPending; /* Indicates a pending lock has been obtained */
- BOOL bReserved; /* Indicates a reserved lock has been obtained */
- BOOL bExclusive; /* Indicates an exclusive lock has been obtained */
-} winceLock;
-#endif
-
-/*
-** The winFile structure is a subclass of sqlite3_file* specific to the win32
-** portability layer.
-*/
-typedef struct winFile winFile;
-struct winFile {
- const sqlite3_io_methods *pMethod; /*** Must be first ***/
- sqlite3_vfs *pVfs; /* The VFS used to open this file */
- HANDLE h; /* Handle for accessing the file */
- u8 locktype; /* Type of lock currently held on this file */
- short sharedLockByte; /* Randomly chosen byte used as a shared lock */
- u8 ctrlFlags; /* Flags. See WINFILE_* below */
- DWORD lastErrno; /* The Windows errno from the last I/O error */
-#ifndef SQLITE_OMIT_WAL
- winShm *pShm; /* Instance of shared memory on this file */
-#endif
- const char *zPath; /* Full pathname of this file */
- int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */
-#if SQLITE_OS_WINCE
- LPWSTR zDeleteOnClose; /* Name of file to delete when closing */
- HANDLE hMutex; /* Mutex used to control access to shared lock */
- HANDLE hShared; /* Shared memory segment used for locking */
- winceLock local; /* Locks obtained by this instance of winFile */
- winceLock *shared; /* Global shared lock memory for the file */
-#endif
-};
-
-/*
-** Allowed values for winFile.ctrlFlags
-*/
-#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
-#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
-
-/*
- * The size of the buffer used by sqlite3_win32_write_debug().
- */
-#ifndef SQLITE_WIN32_DBG_BUF_SIZE
-# define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD)))
-#endif
-
-/*
- * The value used with sqlite3_win32_set_directory() to specify that
- * the data directory should be changed.
- */
-#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE
-# define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1)
-#endif
-
-/*
- * The value used with sqlite3_win32_set_directory() to specify that
- * the temporary directory should be changed.
- */
-#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE
-# define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2)
-#endif
-
-/*
- * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
- * various Win32 API heap functions instead of our own.
- */
-#ifdef SQLITE_WIN32_MALLOC
-
-/*
- * If this is non-zero, an isolated heap will be created by the native Win32
- * allocator subsystem; otherwise, the default process heap will be used. This
- * setting has no effect when compiling for WinRT. By default, this is enabled
- * and an isolated heap will be created to store all allocated data.
- *
- ******************************************************************************
- * WARNING: It is important to note that when this setting is non-zero and the
- * winMemShutdown function is called (e.g. by the sqlite3_shutdown
- * function), all data that was allocated using the isolated heap will
- * be freed immediately and any attempt to access any of that freed
- * data will almost certainly result in an immediate access violation.
- ******************************************************************************
- */
-#ifndef SQLITE_WIN32_HEAP_CREATE
-# define SQLITE_WIN32_HEAP_CREATE (TRUE)
-#endif
-
-/*
- * The initial size of the Win32-specific heap. This value may be zero.
- */
-#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
-# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
- (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
-#endif
-
-/*
- * The maximum size of the Win32-specific heap. This value may be zero.
- */
-#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
-# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
-#endif
-
-/*
- * The extra flags to use in calls to the Win32 heap APIs. This value may be
- * zero for the default behavior.
- */
-#ifndef SQLITE_WIN32_HEAP_FLAGS
-# define SQLITE_WIN32_HEAP_FLAGS (0)
-#endif
-
-/*
-** The winMemData structure stores information required by the Win32-specific
-** sqlite3_mem_methods implementation.
-*/
-typedef struct winMemData winMemData;
-struct winMemData {
-#ifndef NDEBUG
- u32 magic; /* Magic number to detect structure corruption. */
-#endif
- HANDLE hHeap; /* The handle to our heap. */
- BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */
-};
-
-#ifndef NDEBUG
-#define WINMEM_MAGIC 0x42b2830b
-#endif
-
-static struct winMemData win_mem_data = {
-#ifndef NDEBUG
- WINMEM_MAGIC,
-#endif
- NULL, FALSE
-};
-
-#ifndef NDEBUG
-#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
-#else
-#define winMemAssertMagic()
-#endif
-
-#define winMemGetHeap() win_mem_data.hHeap
-
-static void *winMemMalloc(int nBytes);
-static void winMemFree(void *pPrior);
-static void *winMemRealloc(void *pPrior, int nBytes);
-static int winMemSize(void *p);
-static int winMemRoundup(int n);
-static int winMemInit(void *pAppData);
-static void winMemShutdown(void *pAppData);
-
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void);
-#endif /* SQLITE_WIN32_MALLOC */
-
-/*
-** The following variable is (normally) set once and never changes
-** thereafter. It records whether the operating system is Win9x
-** or WinNT.
-**
-** 0: Operating system unknown.
-** 1: Operating system is Win9x.
-** 2: Operating system is WinNT.
-**
-** In order to facilitate testing on a WinNT system, the test fixture
-** can manually set this value to 1 to emulate Win98 behavior.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_os_type = 0;
-#else
-static int sqlite3_os_type = 0;
-#endif
-
-#ifndef SYSCALL
-# define SYSCALL sqlite3_syscall_ptr
-#endif
-
-/*
-** This function is not available on Windows CE or WinRT.
- */
-
-#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
-# define osAreFileApisANSI() 1
-#endif
-
-/*
-** Many system calls are accessed through pointer-to-functions so that
-** they may be overridden at runtime to facilitate fault injection during
-** testing and sandboxing. The following array holds the names and pointers
-** to all overrideable system calls.
-*/
-static struct win_syscall {
- const char *zName; /* Name of the sytem call */
- sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
- sqlite3_syscall_ptr pDefault; /* Default value */
-} aSyscall[] = {
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
- { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 },
-#else
- { "AreFileApisANSI", (SYSCALL)0, 0 },
-#endif
-
-#ifndef osAreFileApisANSI
-#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
-#endif
-
-#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
- { "CharLowerW", (SYSCALL)CharLowerW, 0 },
-#else
- { "CharLowerW", (SYSCALL)0, 0 },
-#endif
-
-#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
-
-#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
- { "CharUpperW", (SYSCALL)CharUpperW, 0 },
-#else
- { "CharUpperW", (SYSCALL)0, 0 },
-#endif
-
-#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
-
- { "CloseHandle", (SYSCALL)CloseHandle, 0 },
-
-#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_ANSI)
- { "CreateFileA", (SYSCALL)CreateFileA, 0 },
-#else
- { "CreateFileA", (SYSCALL)0, 0 },
-#endif
-
-#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
- LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
-
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
- { "CreateFileW", (SYSCALL)CreateFileW, 0 },
-#else
- { "CreateFileW", (SYSCALL)0, 0 },
-#endif
-
-#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
- LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
-
-#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
- !defined(SQLITE_OMIT_WAL))
- { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 },
-#else
- { "CreateFileMappingA", (SYSCALL)0, 0 },
-#endif
-
-#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
- DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
-
-#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
- !defined(SQLITE_OMIT_WAL))
- { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 },
-#else
- { "CreateFileMappingW", (SYSCALL)0, 0 },
-#endif
-
-#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
- DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
-
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
- { "CreateMutexW", (SYSCALL)CreateMutexW, 0 },
-#else
- { "CreateMutexW", (SYSCALL)0, 0 },
-#endif
-
-#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
- LPCWSTR))aSyscall[8].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_ANSI)
- { "DeleteFileA", (SYSCALL)DeleteFileA, 0 },
-#else
- { "DeleteFileA", (SYSCALL)0, 0 },
-#endif
-
-#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_WIDE)
- { "DeleteFileW", (SYSCALL)DeleteFileW, 0 },
-#else
- { "DeleteFileW", (SYSCALL)0, 0 },
-#endif
-
-#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
-
-#if SQLITE_OS_WINCE
- { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
-#else
- { "FileTimeToLocalFileTime", (SYSCALL)0, 0 },
-#endif
-
-#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
- LPFILETIME))aSyscall[11].pCurrent)
-
-#if SQLITE_OS_WINCE
- { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 },
-#else
- { "FileTimeToSystemTime", (SYSCALL)0, 0 },
-#endif
-
-#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
- LPSYSTEMTIME))aSyscall[12].pCurrent)
-
- { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 },
-
-#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_ANSI)
- { "FormatMessageA", (SYSCALL)FormatMessageA, 0 },
-#else
- { "FormatMessageA", (SYSCALL)0, 0 },
-#endif
-
-#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
- DWORD,va_list*))aSyscall[14].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_WIDE)
- { "FormatMessageW", (SYSCALL)FormatMessageW, 0 },
-#else
- { "FormatMessageW", (SYSCALL)0, 0 },
-#endif
-
-#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
- DWORD,va_list*))aSyscall[15].pCurrent)
-
-#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
- { "FreeLibrary", (SYSCALL)FreeLibrary, 0 },
-#else
- { "FreeLibrary", (SYSCALL)0, 0 },
-#endif
-
-#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
-
- { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 },
-
-#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
-
-#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
- { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 },
-#else
- { "GetDiskFreeSpaceA", (SYSCALL)0, 0 },
-#endif
-
-#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
- LPDWORD))aSyscall[18].pCurrent)
-
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
- { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 },
-#else
- { "GetDiskFreeSpaceW", (SYSCALL)0, 0 },
-#endif
-
-#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
- LPDWORD))aSyscall[19].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_ANSI)
- { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 },
-#else
- { "GetFileAttributesA", (SYSCALL)0, 0 },
-#endif
-
-#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
-
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
- { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 },
-#else
- { "GetFileAttributesW", (SYSCALL)0, 0 },
-#endif
-
-#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_WIDE)
- { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 },
-#else
- { "GetFileAttributesExW", (SYSCALL)0, 0 },
-#endif
-
-#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
- LPVOID))aSyscall[22].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "GetFileSize", (SYSCALL)GetFileSize, 0 },
-#else
- { "GetFileSize", (SYSCALL)0, 0 },
-#endif
-
-#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
-
-#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
- { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 },
-#else
- { "GetFullPathNameA", (SYSCALL)0, 0 },
-#endif
-
-#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
- LPSTR*))aSyscall[24].pCurrent)
-
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
- { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 },
-#else
- { "GetFullPathNameW", (SYSCALL)0, 0 },
-#endif
-
-#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
- LPWSTR*))aSyscall[25].pCurrent)
-
- { "GetLastError", (SYSCALL)GetLastError, 0 },
-
-#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
-
-#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
-#if SQLITE_OS_WINCE
- /* The GetProcAddressA() routine is only available on Windows CE. */
- { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 },
-#else
- /* All other Windows platforms expect GetProcAddress() to take
- ** an ANSI string regardless of the _UNICODE setting */
- { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 },
-#endif
-#else
- { "GetProcAddressA", (SYSCALL)0, 0 },
-#endif
-
-#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
- LPCSTR))aSyscall[27].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 },
-#else
- { "GetSystemInfo", (SYSCALL)0, 0 },
-#endif
-
-#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
-
- { "GetSystemTime", (SYSCALL)GetSystemTime, 0 },
-
-#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
-
-#if !SQLITE_OS_WINCE
- { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
-#else
- { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 },
-#endif
-
-#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
- LPFILETIME))aSyscall[30].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_ANSI)
- { "GetTempPathA", (SYSCALL)GetTempPathA, 0 },
-#else
- { "GetTempPathA", (SYSCALL)0, 0 },
-#endif
-
-#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
-
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
- { "GetTempPathW", (SYSCALL)GetTempPathW, 0 },
-#else
- { "GetTempPathW", (SYSCALL)0, 0 },
-#endif
-
-#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "GetTickCount", (SYSCALL)GetTickCount, 0 },
-#else
- { "GetTickCount", (SYSCALL)0, 0 },
-#endif
-
-#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_ANSI)
- { "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
-#else
- { "GetVersionExA", (SYSCALL)0, 0 },
-#endif
-
-#define osGetVersionExA ((BOOL(WINAPI*)( \
- LPOSVERSIONINFOA))aSyscall[34].pCurrent)
-
- { "HeapAlloc", (SYSCALL)HeapAlloc, 0 },
-
-#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
- SIZE_T))aSyscall[35].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "HeapCreate", (SYSCALL)HeapCreate, 0 },
-#else
- { "HeapCreate", (SYSCALL)0, 0 },
-#endif
-
-#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
- SIZE_T))aSyscall[36].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "HeapDestroy", (SYSCALL)HeapDestroy, 0 },
-#else
- { "HeapDestroy", (SYSCALL)0, 0 },
-#endif
-
-#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
-
- { "HeapFree", (SYSCALL)HeapFree, 0 },
-
-#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
-
- { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 },
-
-#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
- SIZE_T))aSyscall[39].pCurrent)
-
- { "HeapSize", (SYSCALL)HeapSize, 0 },
-
-#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
- LPCVOID))aSyscall[40].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "HeapValidate", (SYSCALL)HeapValidate, 0 },
-#else
- { "HeapValidate", (SYSCALL)0, 0 },
-#endif
-
-#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
- LPCVOID))aSyscall[41].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
- { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
-#else
- { "LoadLibraryA", (SYSCALL)0, 0 },
-#endif
-
-#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
-
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
- !defined(SQLITE_OMIT_LOAD_EXTENSION)
- { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 },
-#else
- { "LoadLibraryW", (SYSCALL)0, 0 },
-#endif
-
-#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "LocalFree", (SYSCALL)LocalFree, 0 },
-#else
- { "LocalFree", (SYSCALL)0, 0 },
-#endif
-
-#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
-
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
- { "LockFile", (SYSCALL)LockFile, 0 },
-#else
- { "LockFile", (SYSCALL)0, 0 },
-#endif
-
-#ifndef osLockFile
-#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[45].pCurrent)
-#endif
-
-#if !SQLITE_OS_WINCE
- { "LockFileEx", (SYSCALL)LockFileEx, 0 },
-#else
- { "LockFileEx", (SYSCALL)0, 0 },
-#endif
-
-#ifndef osLockFileEx
-#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[46].pCurrent)
-#endif
-
-#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
- { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 },
-#else
- { "MapViewOfFile", (SYSCALL)0, 0 },
-#endif
-
-#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- SIZE_T))aSyscall[47].pCurrent)
-
- { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 },
-
-#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
- int))aSyscall[48].pCurrent)
-
- { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
-
-#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
- LARGE_INTEGER*))aSyscall[49].pCurrent)
-
- { "ReadFile", (SYSCALL)ReadFile, 0 },
-
-#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[50].pCurrent)
-
- { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 },
-
-#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "SetFilePointer", (SYSCALL)SetFilePointer, 0 },
-#else
- { "SetFilePointer", (SYSCALL)0, 0 },
-#endif
-
-#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
- DWORD))aSyscall[52].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "Sleep", (SYSCALL)Sleep, 0 },
-#else
- { "Sleep", (SYSCALL)0, 0 },
-#endif
-
-#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
-
- { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 },
-
-#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
- LPFILETIME))aSyscall[54].pCurrent)
-
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
- { "UnlockFile", (SYSCALL)UnlockFile, 0 },
-#else
- { "UnlockFile", (SYSCALL)0, 0 },
-#endif
-
-#ifndef osUnlockFile
-#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[55].pCurrent)
-#endif
-
-#if !SQLITE_OS_WINCE
- { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 },
-#else
- { "UnlockFileEx", (SYSCALL)0, 0 },
-#endif
-
-#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[56].pCurrent)
-
-#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
- { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
-#else
- { "UnmapViewOfFile", (SYSCALL)0, 0 },
-#endif
-
-#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
-
- { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 },
-
-#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
- LPCSTR,LPBOOL))aSyscall[58].pCurrent)
-
- { "WriteFile", (SYSCALL)WriteFile, 0 },
-
-#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[59].pCurrent)
-
-#if SQLITE_OS_WINRT
- { "CreateEventExW", (SYSCALL)CreateEventExW, 0 },
-#else
- { "CreateEventExW", (SYSCALL)0, 0 },
-#endif
-
-#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
- DWORD,DWORD))aSyscall[60].pCurrent)
-
-#if !SQLITE_OS_WINRT
- { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 },
-#else
- { "WaitForSingleObject", (SYSCALL)0, 0 },
-#endif
-
-#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
- DWORD))aSyscall[61].pCurrent)
-
-#if SQLITE_OS_WINRT
- { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
-#else
- { "WaitForSingleObjectEx", (SYSCALL)0, 0 },
-#endif
-
-#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
- BOOL))aSyscall[62].pCurrent)
-
-#if SQLITE_OS_WINRT
- { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
-#else
- { "SetFilePointerEx", (SYSCALL)0, 0 },
-#endif
-
-#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
- PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent)
-
-#if SQLITE_OS_WINRT
- { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
-#else
- { "GetFileInformationByHandleEx", (SYSCALL)0, 0 },
-#endif
-
-#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
- FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent)
-
-#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
- { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
-#else
- { "MapViewOfFileFromApp", (SYSCALL)0, 0 },
-#endif
-
-#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
- SIZE_T))aSyscall[65].pCurrent)
-
-#if SQLITE_OS_WINRT
- { "CreateFile2", (SYSCALL)CreateFile2, 0 },
-#else
- { "CreateFile2", (SYSCALL)0, 0 },
-#endif
-
-#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
- LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
-
-#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
- { "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
-#else
- { "LoadPackagedLibrary", (SYSCALL)0, 0 },
-#endif
-
-#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
- DWORD))aSyscall[67].pCurrent)
-
-#if SQLITE_OS_WINRT
- { "GetTickCount64", (SYSCALL)GetTickCount64, 0 },
-#else
- { "GetTickCount64", (SYSCALL)0, 0 },
-#endif
-
-#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent)
-
-#if SQLITE_OS_WINRT
- { "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 },
-#else
- { "GetNativeSystemInfo", (SYSCALL)0, 0 },
-#endif
-
-#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
- LPSYSTEM_INFO))aSyscall[69].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_ANSI)
- { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 },
-#else
- { "OutputDebugStringA", (SYSCALL)0, 0 },
-#endif
-
-#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent)
-
-#if defined(SQLITE_WIN32_HAS_WIDE)
- { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 },
-#else
- { "OutputDebugStringW", (SYSCALL)0, 0 },
-#endif
-
-#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent)
-
- { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 },
-
-#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent)
-
-#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
- { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
-#else
- { "CreateFileMappingFromApp", (SYSCALL)0, 0 },
-#endif
-
-#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
- LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent)
-
-}; /* End of the overrideable system calls */
-
-/*
-** This is the xSetSystemCall() method of sqlite3_vfs for all of the
-** "win32" VFSes. Return SQLITE_OK opon successfully updating the
-** system call pointer, or SQLITE_NOTFOUND if there is no configurable
-** system call named zName.
-*/
-static int winSetSystemCall(
- sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */
- const char *zName, /* Name of system call to override */
- sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */
-){
- unsigned int i;
- int rc = SQLITE_NOTFOUND;
-
- UNUSED_PARAMETER(pNotUsed);
- if( zName==0 ){
- /* If no zName is given, restore all system calls to their default
- ** settings and return NULL
- */
- rc = SQLITE_OK;
- for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
- if( aSyscall[i].pDefault ){
- aSyscall[i].pCurrent = aSyscall[i].pDefault;
- }
- }
- }else{
- /* If zName is specified, operate on only the one system call
- ** specified.
- */
- for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
- if( strcmp(zName, aSyscall[i].zName)==0 ){
- if( aSyscall[i].pDefault==0 ){
- aSyscall[i].pDefault = aSyscall[i].pCurrent;
- }
- rc = SQLITE_OK;
- if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
- aSyscall[i].pCurrent = pNewFunc;
- break;
- }
- }
- }
- return rc;
-}
-
-/*
-** Return the value of a system call. Return NULL if zName is not a
-** recognized system call name. NULL is also returned if the system call
-** is currently undefined.
-*/
-static sqlite3_syscall_ptr winGetSystemCall(
- sqlite3_vfs *pNotUsed,
- const char *zName
-){
- unsigned int i;
-
- UNUSED_PARAMETER(pNotUsed);
- for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
- if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
- }
- return 0;
-}
-
-/*
-** Return the name of the first system call after zName. If zName==NULL
-** then return the name of the first system call. Return NULL if zName
-** is the last system call or if zName is not the name of a valid
-** system call.
-*/
-static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
- int i = -1;
-
- UNUSED_PARAMETER(p);
- if( zName ){
- for(i=0; i<ArraySize(aSyscall)-1; i++){
- if( strcmp(zName, aSyscall[i].zName)==0 ) break;
- }
- }
- for(i++; i<ArraySize(aSyscall); i++){
- if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
- }
- return 0;
-}
-
-/*
-** This function outputs the specified (ANSI) string to the Win32 debugger
-** (if available).
-*/
-
-SQLITE_API void sqlite3_win32_write_debug(char *zBuf, int nBuf){
- char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
- int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
- if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
- assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
-#if defined(SQLITE_WIN32_HAS_ANSI)
- if( nMin>0 ){
- memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
- memcpy(zDbgBuf, zBuf, nMin);
- osOutputDebugStringA(zDbgBuf);
- }else{
- osOutputDebugStringA(zBuf);
- }
-#elif defined(SQLITE_WIN32_HAS_WIDE)
- memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
- if ( osMultiByteToWideChar(
- osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf,
- nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){
- return;
- }
- osOutputDebugStringW((LPCWSTR)zDbgBuf);
-#else
- if( nMin>0 ){
- memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
- memcpy(zDbgBuf, zBuf, nMin);
- fprintf(stderr, "%s", zDbgBuf);
- }else{
- fprintf(stderr, "%s", zBuf);
- }
-#endif
-}
-
-/*
-** The following routine suspends the current thread for at least ms
-** milliseconds. This is equivalent to the Win32 Sleep() interface.
-*/
-#if SQLITE_OS_WINRT
-static HANDLE sleepObj = NULL;
-#endif
-
-SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
-#if SQLITE_OS_WINRT
- if ( sleepObj==NULL ){
- sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
- SYNCHRONIZE);
- }
- assert( sleepObj!=NULL );
- osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
-#else
- osSleep(milliseconds);
-#endif
-}
-
-/*
-** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
-** or WinCE. Return false (zero) for Win95, Win98, or WinME.
-**
-** Here is an interesting observation: Win95, Win98, and WinME lack
-** the LockFileEx() API. But we can still statically link against that
-** API as long as we don't call it when running Win95/98/ME. A call to
-** this routine is used to determine if the host is Win95/98/ME or
-** WinNT/2K/XP so that we will know whether or not we can safely call
-** the LockFileEx() API.
-*/
-#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
-# define isNT() (1)
-#elif !defined(SQLITE_WIN32_HAS_WIDE)
-# define isNT() (0)
-#else
- static int isNT(void){
- if( sqlite3_os_type==0 ){
- OSVERSIONINFOA sInfo;
- sInfo.dwOSVersionInfoSize = sizeof(sInfo);
- osGetVersionExA(&sInfo);
- sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
- }
- return sqlite3_os_type==2;
- }
-#endif
-
-#ifdef SQLITE_WIN32_MALLOC
-/*
-** Allocate nBytes of memory.
-*/
-static void *winMemMalloc(int nBytes){
- HANDLE hHeap;
- void *p;
-
- winMemAssertMagic();
- hHeap = winMemGetHeap();
- assert( hHeap!=0 );
- assert( hHeap!=INVALID_HANDLE_VALUE );
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
-#endif
- assert( nBytes>=0 );
- p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
- if( !p ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p",
- nBytes, osGetLastError(), (void*)hHeap);
- }
- return p;
-}
-
-/*
-** Free memory.
-*/
-static void winMemFree(void *pPrior){
- HANDLE hHeap;
-
- winMemAssertMagic();
- hHeap = winMemGetHeap();
- assert( hHeap!=0 );
- assert( hHeap!=INVALID_HANDLE_VALUE );
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
-#endif
- if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
- if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p",
- pPrior, osGetLastError(), (void*)hHeap);
- }
-}
-
-/*
-** Change the size of an existing memory allocation
-*/
-static void *winMemRealloc(void *pPrior, int nBytes){
- HANDLE hHeap;
- void *p;
-
- winMemAssertMagic();
- hHeap = winMemGetHeap();
- assert( hHeap!=0 );
- assert( hHeap!=INVALID_HANDLE_VALUE );
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
-#endif
- assert( nBytes>=0 );
- if( !pPrior ){
- p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
- }else{
- p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
- }
- if( !p ){
- sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p",
- pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
- (void*)hHeap);
- }
- return p;
-}
-
-/*
-** Return the size of an outstanding allocation, in bytes.
-*/
-static int winMemSize(void *p){
- HANDLE hHeap;
- SIZE_T n;
-
- winMemAssertMagic();
- hHeap = winMemGetHeap();
- assert( hHeap!=0 );
- assert( hHeap!=INVALID_HANDLE_VALUE );
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
-#endif
- if( !p ) return 0;
- n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
- if( n==(SIZE_T)-1 ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p",
- p, osGetLastError(), (void*)hHeap);
- return 0;
- }
- return (int)n;
-}
-
-/*
-** Round up a request size to the next valid allocation size.
-*/
-static int winMemRoundup(int n){
- return n;
-}
-
-/*
-** Initialize this module.
-*/
-static int winMemInit(void *pAppData){
- winMemData *pWinMemData = (winMemData *)pAppData;
-
- if( !pWinMemData ) return SQLITE_ERROR;
- assert( pWinMemData->magic==WINMEM_MAGIC );
-
-#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
- if( !pWinMemData->hHeap ){
- pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
- SQLITE_WIN32_HEAP_INIT_SIZE,
- SQLITE_WIN32_HEAP_MAX_SIZE);
- if( !pWinMemData->hHeap ){
- sqlite3_log(SQLITE_NOMEM,
- "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
- osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
- SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
- return SQLITE_NOMEM;
- }
- pWinMemData->bOwned = TRUE;
- assert( pWinMemData->bOwned );
- }
-#else
- pWinMemData->hHeap = osGetProcessHeap();
- if( !pWinMemData->hHeap ){
- sqlite3_log(SQLITE_NOMEM,
- "failed to GetProcessHeap (%d)", osGetLastError());
- return SQLITE_NOMEM;
- }
- pWinMemData->bOwned = FALSE;
- assert( !pWinMemData->bOwned );
-#endif
- assert( pWinMemData->hHeap!=0 );
- assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
-#endif
- return SQLITE_OK;
-}
-
-/*
-** Deinitialize this module.
-*/
-static void winMemShutdown(void *pAppData){
- winMemData *pWinMemData = (winMemData *)pAppData;
-
- if( !pWinMemData ) return;
- if( pWinMemData->hHeap ){
- assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
-#endif
- if( pWinMemData->bOwned ){
- if( !osHeapDestroy(pWinMemData->hHeap) ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
- osGetLastError(), (void*)pWinMemData->hHeap);
- }
- pWinMemData->bOwned = FALSE;
- }
- pWinMemData->hHeap = NULL;
- }
-}
-
-/*
-** Populate the low-level memory allocation function pointers in
-** sqlite3GlobalConfig.m with pointers to the routines in this file. The
-** arguments specify the block of memory to manage.
-**
-** This routine is only called by sqlite3_config(), and therefore
-** is not required to be threadsafe (it is not).
-*/
-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){
- static const sqlite3_mem_methods winMemMethods = {
- winMemMalloc,
- winMemFree,
- winMemRealloc,
- winMemSize,
- winMemRoundup,
- winMemInit,
- winMemShutdown,
- &win_mem_data
- };
- return &winMemMethods;
-}
-
-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
- sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
-}
-#endif /* SQLITE_WIN32_MALLOC */
-
-/*
-** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
-**
-** Space to hold the returned string is obtained from malloc.
-*/
-static LPWSTR utf8ToUnicode(const char *zFilename){
- int nChar;
- LPWSTR zWideFilename;
-
- nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
- if( nChar==0 ){
- return 0;
- }
- zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
- if( zWideFilename==0 ){
- return 0;
- }
- nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
- nChar);
- if( nChar==0 ){
- sqlite3_free(zWideFilename);
- zWideFilename = 0;
- }
- return zWideFilename;
-}
-
-/*
-** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is
-** obtained from sqlite3_malloc().
-*/
-static char *unicodeToUtf8(LPCWSTR zWideFilename){
- int nByte;
- char *zFilename;
-
- nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
- if( nByte == 0 ){
- return 0;
- }
- zFilename = sqlite3MallocZero( nByte );
- if( zFilename==0 ){
- return 0;
- }
- nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
- 0, 0);
- if( nByte == 0 ){
- sqlite3_free(zFilename);
- zFilename = 0;
- }
- return zFilename;
-}
-
-/*
-** Convert an ANSI string to Microsoft Unicode, based on the
-** current codepage settings for file apis.
-**
-** Space to hold the returned string is obtained
-** from sqlite3_malloc.
-*/
-static LPWSTR mbcsToUnicode(const char *zFilename){
- int nByte;
- LPWSTR zMbcsFilename;
- int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
-
- nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
- 0)*sizeof(WCHAR);
- if( nByte==0 ){
- return 0;
- }
- zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
- if( zMbcsFilename==0 ){
- return 0;
- }
- nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
- nByte);
- if( nByte==0 ){
- sqlite3_free(zMbcsFilename);
- zMbcsFilename = 0;
- }
- return zMbcsFilename;
-}
-
-/*
-** Convert Microsoft Unicode to multi-byte character string, based on the
-** user's ANSI codepage.
-**
-** Space to hold the returned string is obtained from
-** sqlite3_malloc().
-*/
-static char *unicodeToMbcs(LPCWSTR zWideFilename){
- int nByte;
- char *zFilename;
- int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
-
- nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
- if( nByte == 0 ){
- return 0;
- }
- zFilename = sqlite3MallocZero( nByte );
- if( zFilename==0 ){
- return 0;
- }
- nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
- nByte, 0, 0);
- if( nByte == 0 ){
- sqlite3_free(zFilename);
- zFilename = 0;
- }
- return zFilename;
-}
-
-/*
-** Convert multibyte character string to UTF-8. Space to hold the
-** returned string is obtained from sqlite3_malloc().
-*/
-SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
- char *zFilenameUtf8;
- LPWSTR zTmpWide;
-
- zTmpWide = mbcsToUnicode(zFilename);
- if( zTmpWide==0 ){
- return 0;
- }
- zFilenameUtf8 = unicodeToUtf8(zTmpWide);
- sqlite3_free(zTmpWide);
- return zFilenameUtf8;
-}
-
-/*
-** Convert UTF-8 to multibyte character string. Space to hold the
-** returned string is obtained from sqlite3_malloc().
-*/
-SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
- char *zFilenameMbcs;
- LPWSTR zTmpWide;
-
- zTmpWide = utf8ToUnicode(zFilename);
- if( zTmpWide==0 ){
- return 0;
- }
- zFilenameMbcs = unicodeToMbcs(zTmpWide);
- sqlite3_free(zTmpWide);
- return zFilenameMbcs;
-}
-
-/*
-** This function sets the data directory or the temporary directory based on
-** the provided arguments. The type argument must be 1 in order to set the
-** data directory or 2 in order to set the temporary directory. The zValue
-** argument is the name of the directory to use. The return value will be
-** SQLITE_OK if successful.
-*/
-SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
- char **ppDirectory = 0;
-#ifndef SQLITE_OMIT_AUTOINIT
- int rc = sqlite3_initialize();
- if( rc ) return rc;
-#endif
- if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
- ppDirectory = &sqlite3_data_directory;
- }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){
- ppDirectory = &sqlite3_temp_directory;
- }
- assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
- || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
- );
- assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
- if( ppDirectory ){
- char *zValueUtf8 = 0;
- if( zValue && zValue[0] ){
- zValueUtf8 = unicodeToUtf8(zValue);
- if ( zValueUtf8==0 ){
- return SQLITE_NOMEM;
- }
- }
- sqlite3_free(*ppDirectory);
- *ppDirectory = zValueUtf8;
- return SQLITE_OK;
- }
- return SQLITE_ERROR;
-}
-
-/*
-** The return value of getLastErrorMsg
-** is zero if the error message fits in the buffer, or non-zero
-** otherwise (if the message was truncated).
-*/
-static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
- /* FormatMessage returns 0 on failure. Otherwise it
- ** returns the number of TCHARs written to the output
- ** buffer, excluding the terminating null char.
- */
- DWORD dwLen = 0;
- char *zOut = 0;
-
- if( isNT() ){
-#if SQLITE_OS_WINRT
- WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */
- dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- lastErrno,
- 0,
- zTempWide,
- MAX_PATH,
- 0);
-#else
- LPWSTR zTempWide = NULL;
- dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- lastErrno,
- 0,
- (LPWSTR) &zTempWide,
- 0,
- 0);
-#endif
- if( dwLen > 0 ){
- /* allocate a buffer and convert to UTF8 */
- sqlite3BeginBenignMalloc();
- zOut = unicodeToUtf8(zTempWide);
- sqlite3EndBenignMalloc();
-#if !SQLITE_OS_WINRT
- /* free the system buffer allocated by FormatMessage */
- osLocalFree(zTempWide);
-#endif
- }
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- char *zTemp = NULL;
- dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- lastErrno,
- 0,
- (LPSTR) &zTemp,
- 0,
- 0);
- if( dwLen > 0 ){
- /* allocate a buffer and convert to UTF8 */
- sqlite3BeginBenignMalloc();
- zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
- sqlite3EndBenignMalloc();
- /* free the system buffer allocated by FormatMessage */
- osLocalFree(zTemp);
- }
- }
-#endif
- if( 0 == dwLen ){
- sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno);
- }else{
- /* copy a maximum of nBuf chars to output buffer */
- sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
- /* free the UTF8 buffer */
- sqlite3_free(zOut);
- }
- return 0;
-}
-
-/*
-**
-** This function - winLogErrorAtLine() - is only ever called via the macro
-** winLogError().
-**
-** This routine is invoked after an error occurs in an OS function.
-** It logs a message using sqlite3_log() containing the current value of
-** error code and, if possible, the human-readable equivalent from
-** FormatMessage.
-**
-** The first argument passed to the macro should be the error code that
-** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN).
-** The two subsequent arguments should be the name of the OS function that
-** failed and the associated file-system path, if any.
-*/
-#define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__)
-static int winLogErrorAtLine(
- int errcode, /* SQLite error code */
- DWORD lastErrno, /* Win32 last error */
- const char *zFunc, /* Name of OS function that failed */
- const char *zPath, /* File path associated with error */
- int iLine /* Source line number where error occurred */
-){
- char zMsg[500]; /* Human readable error text */
- int i; /* Loop counter */
-
- zMsg[0] = 0;
- getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
- assert( errcode!=SQLITE_OK );
- if( zPath==0 ) zPath = "";
- for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
- zMsg[i] = 0;
- sqlite3_log(errcode,
- "os_win.c:%d: (%d) %s(%s) - %s",
- iLine, lastErrno, zFunc, zPath, zMsg
- );
-
- return errcode;
-}
-
-/*
-** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
-** will be retried following a locking error - probably caused by
-** antivirus software. Also the initial delay before the first retry.
-** The delay increases linearly with each retry.
-*/
-#ifndef SQLITE_WIN32_IOERR_RETRY
-# define SQLITE_WIN32_IOERR_RETRY 10
-#endif
-#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
-# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
-#endif
-static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY;
-static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
-
-/*
-** If a ReadFile() or WriteFile() error occurs, invoke this routine
-** to see if it should be retried. Return TRUE to retry. Return FALSE
-** to give up with an error.
-*/
-static int retryIoerr(int *pnRetry, DWORD *pError){
- DWORD e = osGetLastError();
- if( *pnRetry>=win32IoerrRetry ){
- if( pError ){
- *pError = e;
- }
- return 0;
- }
- if( e==ERROR_ACCESS_DENIED ||
- e==ERROR_LOCK_VIOLATION ||
- e==ERROR_SHARING_VIOLATION ){
- sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry));
- ++*pnRetry;
- return 1;
- }
- if( pError ){
- *pError = e;
- }
- return 0;
-}
-
-/*
-** Log a I/O error retry episode.
-*/
-static void logIoerr(int nRetry){
- if( nRetry ){
- sqlite3_log(SQLITE_IOERR,
- "delayed %dms for lock/sharing conflict",
- win32IoerrRetryDelay*nRetry*(nRetry+1)/2
- );
- }
-}
-
-#if SQLITE_OS_WINCE
-/*************************************************************************
-** This section contains code for WinCE only.
-*/
-/*
-** Windows CE does not have a localtime() function. So create a
-** substitute.
-*/
-/* #include <time.h> */
-struct tm *__cdecl localtime(const time_t *t)
-{
- static struct tm y;
- FILETIME uTm, lTm;
- SYSTEMTIME pTm;
- sqlite3_int64 t64;
- t64 = *t;
- t64 = (t64 + 11644473600)*10000000;
- uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
- uTm.dwHighDateTime= (DWORD)(t64 >> 32);
- osFileTimeToLocalFileTime(&uTm,&lTm);
- osFileTimeToSystemTime(&lTm,&pTm);
- y.tm_year = pTm.wYear - 1900;
- y.tm_mon = pTm.wMonth - 1;
- y.tm_wday = pTm.wDayOfWeek;
- y.tm_mday = pTm.wDay;
- y.tm_hour = pTm.wHour;
- y.tm_min = pTm.wMinute;
- y.tm_sec = pTm.wSecond;
- return &y;
-}
-
-#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
-
-/*
-** Acquire a lock on the handle h
-*/
-static void winceMutexAcquire(HANDLE h){
- DWORD dwErr;
- do {
- dwErr = osWaitForSingleObject(h, INFINITE);
- } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
-}
-/*
-** Release a lock acquired by winceMutexAcquire()
-*/
-#define winceMutexRelease(h) ReleaseMutex(h)
-
-/*
-** Create the mutex and shared memory used for locking in the file
-** descriptor pFile
-*/
-static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
- LPWSTR zTok;
- LPWSTR zName;
- BOOL bInit = TRUE;
-
- zName = utf8ToUnicode(zFilename);
- if( zName==0 ){
- /* out of memory */
- return FALSE;
- }
-
- /* Initialize the local lockdata */
- memset(&pFile->local, 0, sizeof(pFile->local));
-
- /* Replace the backslashes from the filename and lowercase it
- ** to derive a mutex name. */
- zTok = osCharLowerW(zName);
- for (;*zTok;zTok++){
- if (*zTok == '\\') *zTok = '_';
- }
-
- /* Create/open the named mutex */
- pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
- if (!pFile->hMutex){
- pFile->lastErrno = osGetLastError();
- winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename);
- sqlite3_free(zName);
- return FALSE;
- }
-
- /* Acquire the mutex before continuing */
- winceMutexAcquire(pFile->hMutex);
-
- /* Since the names of named mutexes, semaphores, file mappings etc are
- ** case-sensitive, take advantage of that by uppercasing the mutex name
- ** and using that as the shared filemapping name.
- */
- osCharUpperW(zName);
- pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
- PAGE_READWRITE, 0, sizeof(winceLock),
- zName);
-
- /* Set a flag that indicates we're the first to create the memory so it
- ** must be zero-initialized */
- if (osGetLastError() == ERROR_ALREADY_EXISTS){
- bInit = FALSE;
- }
-
- sqlite3_free(zName);
-
- /* If we succeeded in making the shared memory handle, map it. */
- if (pFile->hShared){
- pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,
- FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
- /* If mapping failed, close the shared memory handle and erase it */
- if (!pFile->shared){
- pFile->lastErrno = osGetLastError();
- winLogError(SQLITE_ERROR, pFile->lastErrno,
- "winceCreateLock2", zFilename);
- osCloseHandle(pFile->hShared);
- pFile->hShared = NULL;
- }
- }
-
- /* If shared memory could not be created, then close the mutex and fail */
- if (pFile->hShared == NULL){
- winceMutexRelease(pFile->hMutex);
- osCloseHandle(pFile->hMutex);
- pFile->hMutex = NULL;
- return FALSE;
- }
-
- /* Initialize the shared memory if we're supposed to */
- if (bInit) {
- memset(pFile->shared, 0, sizeof(winceLock));
- }
-
- winceMutexRelease(pFile->hMutex);
- return TRUE;
-}
-
-/*
-** Destroy the part of winFile that deals with wince locks
-*/
-static void winceDestroyLock(winFile *pFile){
- if (pFile->hMutex){
- /* Acquire the mutex */
- winceMutexAcquire(pFile->hMutex);
-
- /* The following blocks should probably assert in debug mode, but they
- are to cleanup in case any locks remained open */
- if (pFile->local.nReaders){
- pFile->shared->nReaders --;
- }
- if (pFile->local.bReserved){
- pFile->shared->bReserved = FALSE;
- }
- if (pFile->local.bPending){
- pFile->shared->bPending = FALSE;
- }
- if (pFile->local.bExclusive){
- pFile->shared->bExclusive = FALSE;
- }
-
- /* De-reference and close our copy of the shared memory handle */
- osUnmapViewOfFile(pFile->shared);
- osCloseHandle(pFile->hShared);
-
- /* Done with the mutex */
- winceMutexRelease(pFile->hMutex);
- osCloseHandle(pFile->hMutex);
- pFile->hMutex = NULL;
- }
-}
-
-/*
-** An implementation of the LockFile() API of Windows for CE
-*/
-static BOOL winceLockFile(
- LPHANDLE phFile,
- DWORD dwFileOffsetLow,
- DWORD dwFileOffsetHigh,
- DWORD nNumberOfBytesToLockLow,
- DWORD nNumberOfBytesToLockHigh
-){
- winFile *pFile = HANDLE_TO_WINFILE(phFile);
- BOOL bReturn = FALSE;
-
- UNUSED_PARAMETER(dwFileOffsetHigh);
- UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
-
- if (!pFile->hMutex) return TRUE;
- winceMutexAcquire(pFile->hMutex);
-
- /* Wanting an exclusive lock? */
- if (dwFileOffsetLow == (DWORD)SHARED_FIRST
- && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
- if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
- pFile->shared->bExclusive = TRUE;
- pFile->local.bExclusive = TRUE;
- bReturn = TRUE;
- }
- }
-
- /* Want a read-only lock? */
- else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
- nNumberOfBytesToLockLow == 1){
- if (pFile->shared->bExclusive == 0){
- pFile->local.nReaders ++;
- if (pFile->local.nReaders == 1){
- pFile->shared->nReaders ++;
- }
- bReturn = TRUE;
- }
- }
-
- /* Want a pending lock? */
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
- /* If no pending lock has been acquired, then acquire it */
- if (pFile->shared->bPending == 0) {
- pFile->shared->bPending = TRUE;
- pFile->local.bPending = TRUE;
- bReturn = TRUE;
- }
- }
-
- /* Want a reserved lock? */
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
- if (pFile->shared->bReserved == 0) {
- pFile->shared->bReserved = TRUE;
- pFile->local.bReserved = TRUE;
- bReturn = TRUE;
- }
- }
-
- winceMutexRelease(pFile->hMutex);
- return bReturn;
-}
-
-/*
-** An implementation of the UnlockFile API of Windows for CE
-*/
-static BOOL winceUnlockFile(
- LPHANDLE phFile,
- DWORD dwFileOffsetLow,
- DWORD dwFileOffsetHigh,
- DWORD nNumberOfBytesToUnlockLow,
- DWORD nNumberOfBytesToUnlockHigh
-){
- winFile *pFile = HANDLE_TO_WINFILE(phFile);
- BOOL bReturn = FALSE;
-
- UNUSED_PARAMETER(dwFileOffsetHigh);
- UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
-
- if (!pFile->hMutex) return TRUE;
- winceMutexAcquire(pFile->hMutex);
-
- /* Releasing a reader lock or an exclusive lock */
- if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
- /* Did we have an exclusive lock? */
- if (pFile->local.bExclusive){
- assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
- pFile->local.bExclusive = FALSE;
- pFile->shared->bExclusive = FALSE;
- bReturn = TRUE;
- }
-
- /* Did we just have a reader lock? */
- else if (pFile->local.nReaders){
- assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
- pFile->local.nReaders --;
- if (pFile->local.nReaders == 0)
- {
- pFile->shared->nReaders --;
- }
- bReturn = TRUE;
- }
- }
-
- /* Releasing a pending lock */
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
- if (pFile->local.bPending){
- pFile->local.bPending = FALSE;
- pFile->shared->bPending = FALSE;
- bReturn = TRUE;
- }
- }
- /* Releasing a reserved lock */
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
- if (pFile->local.bReserved) {
- pFile->local.bReserved = FALSE;
- pFile->shared->bReserved = FALSE;
- bReturn = TRUE;
- }
- }
-
- winceMutexRelease(pFile->hMutex);
- return bReturn;
-}
-/*
-** End of the special code for wince
-*****************************************************************************/
-#endif /* SQLITE_OS_WINCE */
-
-/*
-** Lock a file region.
-*/
-static BOOL winLockFile(
- LPHANDLE phFile,
- DWORD flags,
- DWORD offsetLow,
- DWORD offsetHigh,
- DWORD numBytesLow,
- DWORD numBytesHigh
-){
-#if SQLITE_OS_WINCE
- /*
- ** NOTE: Windows CE is handled differently here due its lack of the Win32
- ** API LockFile.
- */
- return winceLockFile(phFile, offsetLow, offsetHigh,
- numBytesLow, numBytesHigh);
-#else
- if( isNT() ){
- OVERLAPPED ovlp;
- memset(&ovlp, 0, sizeof(OVERLAPPED));
- ovlp.Offset = offsetLow;
- ovlp.OffsetHigh = offsetHigh;
- return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
- }else{
- return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
- numBytesHigh);
- }
-#endif
-}
-
-/*
-** Unlock a file region.
- */
-static BOOL winUnlockFile(
- LPHANDLE phFile,
- DWORD offsetLow,
- DWORD offsetHigh,
- DWORD numBytesLow,
- DWORD numBytesHigh
-){
-#if SQLITE_OS_WINCE
- /*
- ** NOTE: Windows CE is handled differently here due its lack of the Win32
- ** API UnlockFile.
- */
- return winceUnlockFile(phFile, offsetLow, offsetHigh,
- numBytesLow, numBytesHigh);
-#else
- if( isNT() ){
- OVERLAPPED ovlp;
- memset(&ovlp, 0, sizeof(OVERLAPPED));
- ovlp.Offset = offsetLow;
- ovlp.OffsetHigh = offsetHigh;
- return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
- }else{
- return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
- numBytesHigh);
- }
-#endif
-}
-
-/*****************************************************************************
-** The next group of routines implement the I/O methods specified
-** by the sqlite3_io_methods object.
-******************************************************************************/
-
-/*
-** Some Microsoft compilers lack this definition.
-*/
-#ifndef INVALID_SET_FILE_POINTER
-# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
-/*
-** Move the current position of the file handle passed as the first
-** argument to offset iOffset within the file. If successful, return 0.
-** Otherwise, set pFile->lastErrno and return non-zero.
-*/
-static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
-#if !SQLITE_OS_WINRT
- LONG upperBits; /* Most sig. 32 bits of new offset */
- LONG lowerBits; /* Least sig. 32 bits of new offset */
- DWORD dwRet; /* Value returned by SetFilePointer() */
- DWORD lastErrno; /* Value returned by GetLastError() */
-
- upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
- lowerBits = (LONG)(iOffset & 0xffffffff);
-
- /* API oddity: If successful, SetFilePointer() returns a dword
- ** containing the lower 32-bits of the new file-offset. Or, if it fails,
- ** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
- ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
- ** whether an error has actually occured, it is also necessary to call
- ** GetLastError().
- */
- dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
-
- if( (dwRet==INVALID_SET_FILE_POINTER
- && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
- pFile->lastErrno = lastErrno;
- winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
- "seekWinFile", pFile->zPath);
- return 1;
- }
-
- return 0;
-#else
- /*
- ** Same as above, except that this implementation works for WinRT.
- */
-
- LARGE_INTEGER x; /* The new offset */
- BOOL bRet; /* Value returned by SetFilePointerEx() */
-
- x.QuadPart = iOffset;
- bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
-
- if(!bRet){
- pFile->lastErrno = osGetLastError();
- winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
- "seekWinFile", pFile->zPath);
- return 1;
- }
-
- return 0;
-#endif
-}
-
-/*
-** Close a file.
-**
-** It is reported that an attempt to close a handle might sometimes
-** fail. This is a very unreasonable result, but Windows is notorious
-** for being unreasonable so I do not doubt that it might happen. If
-** the close fails, we pause for 100 milliseconds and try again. As
-** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
-** giving up and returning an error.
-*/
-#define MX_CLOSE_ATTEMPT 3
-static int winClose(sqlite3_file *id){
- int rc, cnt = 0;
- winFile *pFile = (winFile*)id;
-
- assert( id!=0 );
-#ifndef SQLITE_OMIT_WAL
- assert( pFile->pShm==0 );
-#endif
- OSTRACE(("CLOSE %d\n", pFile->h));
- do{
- rc = osCloseHandle(pFile->h);
- /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
- }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
-#if SQLITE_OS_WINCE
-#define WINCE_DELETION_ATTEMPTS 3
- winceDestroyLock(pFile);
- if( pFile->zDeleteOnClose ){
- int cnt = 0;
- while(
- osDeleteFileW(pFile->zDeleteOnClose)==0
- && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
- && cnt++ < WINCE_DELETION_ATTEMPTS
- ){
- sqlite3_win32_sleep(100); /* Wait a little before trying again */
- }
- sqlite3_free(pFile->zDeleteOnClose);
- }
-#endif
- OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
- if( rc ){
- pFile->h = NULL;
- }
- OpenCounter(-1);
- return rc ? SQLITE_OK
- : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
- "winClose", pFile->zPath);
-}
-
-/*
-** Read data from a file into a buffer. Return SQLITE_OK if all
-** bytes were read successfully and SQLITE_IOERR if anything goes
-** wrong.
-*/
-static int winRead(
- sqlite3_file *id, /* File to read from */
- void *pBuf, /* Write content into this buffer */
- int amt, /* Number of bytes to read */
- sqlite3_int64 offset /* Begin reading at this offset */
-){
-#if !SQLITE_OS_WINCE
- OVERLAPPED overlapped; /* The offset for ReadFile. */
-#endif
- winFile *pFile = (winFile*)id; /* file handle */
- DWORD nRead; /* Number of bytes actually read from file */
- int nRetry = 0; /* Number of retrys */
-
- assert( id!=0 );
- SimulateIOError(return SQLITE_IOERR_READ);
- OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
-
-#if SQLITE_OS_WINCE
- if( seekWinFile(pFile, offset) ){
- return SQLITE_FULL;
- }
- while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
-#else
- memset(&overlapped, 0, sizeof(OVERLAPPED));
- overlapped.Offset = (LONG)(offset & 0xffffffff);
- overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
- while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
- osGetLastError()!=ERROR_HANDLE_EOF ){
-#endif
- DWORD lastErrno;
- if( retryIoerr(&nRetry, &lastErrno) ) continue;
- pFile->lastErrno = lastErrno;
- return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
- "winRead", pFile->zPath);
- }
- logIoerr(nRetry);
- if( nRead<(DWORD)amt ){
- /* Unread parts of the buffer must be zero-filled */
- memset(&((char*)pBuf)[nRead], 0, amt-nRead);
- return SQLITE_IOERR_SHORT_READ;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Write data from a buffer into a file. Return SQLITE_OK on success
-** or some other error code on failure.
-*/
-static int winWrite(
- sqlite3_file *id, /* File to write into */
- const void *pBuf, /* The bytes to be written */
- int amt, /* Number of bytes to write */
- sqlite3_int64 offset /* Offset into the file to begin writing at */
-){
- int rc = 0; /* True if error has occured, else false */
- winFile *pFile = (winFile*)id; /* File handle */
- int nRetry = 0; /* Number of retries */
-
- assert( amt>0 );
- assert( pFile );
- SimulateIOError(return SQLITE_IOERR_WRITE);
- SimulateDiskfullError(return SQLITE_FULL);
-
- OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
-
-#if SQLITE_OS_WINCE
- rc = seekWinFile(pFile, offset);
- if( rc==0 ){
-#else
- {
-#endif
-#if !SQLITE_OS_WINCE
- OVERLAPPED overlapped; /* The offset for WriteFile. */
-#endif
- u8 *aRem = (u8 *)pBuf; /* Data yet to be written */
- int nRem = amt; /* Number of bytes yet to be written */
- DWORD nWrite; /* Bytes written by each WriteFile() call */
- DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */
-
-#if !SQLITE_OS_WINCE
- memset(&overlapped, 0, sizeof(OVERLAPPED));
- overlapped.Offset = (LONG)(offset & 0xffffffff);
- overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
-#endif
-
- while( nRem>0 ){
-#if SQLITE_OS_WINCE
- if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
-#else
- if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
-#endif
- if( retryIoerr(&nRetry, &lastErrno) ) continue;
- break;
- }
- assert( nWrite==0 || nWrite<=(DWORD)nRem );
- if( nWrite==0 || nWrite>(DWORD)nRem ){
- lastErrno = osGetLastError();
- break;
- }
-#if !SQLITE_OS_WINCE
- offset += nWrite;
- overlapped.Offset = (LONG)(offset & 0xffffffff);
- overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
-#endif
- aRem += nWrite;
- nRem -= nWrite;
- }
- if( nRem>0 ){
- pFile->lastErrno = lastErrno;
- rc = 1;
- }
- }
-
- if( rc ){
- if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
- || ( pFile->lastErrno==ERROR_DISK_FULL )){
- return SQLITE_FULL;
- }
- return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
- "winWrite", pFile->zPath);
- }else{
- logIoerr(nRetry);
- }
- return SQLITE_OK;
-}
-
-/*
-** Truncate an open file to a specified size
-*/
-static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
- winFile *pFile = (winFile*)id; /* File handle object */
- int rc = SQLITE_OK; /* Return code for this function */
-
- assert( pFile );
-
- OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
- SimulateIOError(return SQLITE_IOERR_TRUNCATE);
-
- /* If the user has configured a chunk-size for this file, truncate the
- ** file so that it consists of an integer number of chunks (i.e. the
- ** actual file size after the operation may be larger than the requested
- ** size).
- */
- if( pFile->szChunk>0 ){
- nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
- }
-
- /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
- if( seekWinFile(pFile, nByte) ){
- rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
- "winTruncate1", pFile->zPath);
- }else if( 0==osSetEndOfFile(pFile->h) ){
- pFile->lastErrno = osGetLastError();
- rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
- "winTruncate2", pFile->zPath);
- }
-
- OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok"));
- return rc;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Count the number of fullsyncs and normal syncs. This is used to test
-** that syncs and fullsyncs are occuring at the right times.
-*/
-SQLITE_API int sqlite3_sync_count = 0;
-SQLITE_API int sqlite3_fullsync_count = 0;
-#endif
-
-/*
-** Make sure all writes to a particular file are committed to disk.
-*/
-static int winSync(sqlite3_file *id, int flags){
-#ifndef SQLITE_NO_SYNC
- /*
- ** Used only when SQLITE_NO_SYNC is not defined.
- */
- BOOL rc;
-#endif
-#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
- (defined(SQLITE_TEST) && defined(SQLITE_DEBUG))
- /*
- ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
- ** OSTRACE() macros.
- */
- winFile *pFile = (winFile*)id;
-#else
- UNUSED_PARAMETER(id);
-#endif
-
- assert( pFile );
- /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
- assert((flags&0x0F)==SQLITE_SYNC_NORMAL
- || (flags&0x0F)==SQLITE_SYNC_FULL
- );
-
- OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype));
-
- /* Unix cannot, but some systems may return SQLITE_FULL from here. This
- ** line is to test that doing so does not cause any problems.
- */
- SimulateDiskfullError( return SQLITE_FULL );
-
-#ifndef SQLITE_TEST
- UNUSED_PARAMETER(flags);
-#else
- if( (flags&0x0F)==SQLITE_SYNC_FULL ){
- sqlite3_fullsync_count++;
- }
- sqlite3_sync_count++;
-#endif
-
- /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
- ** no-op
- */
-#ifdef SQLITE_NO_SYNC
- return SQLITE_OK;
-#else
- rc = osFlushFileBuffers(pFile->h);
- SimulateIOError( rc=FALSE );
- if( rc ){
- return SQLITE_OK;
- }else{
- pFile->lastErrno = osGetLastError();
- return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
- "winSync", pFile->zPath);
- }
-#endif
-}
-
-/*
-** Determine the current size of a file in bytes
-*/
-static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
- winFile *pFile = (winFile*)id;
- int rc = SQLITE_OK;
-
- assert( id!=0 );
- SimulateIOError(return SQLITE_IOERR_FSTAT);
-#if SQLITE_OS_WINRT
- {
- FILE_STANDARD_INFO info;
- if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo,
- &info, sizeof(info)) ){
- *pSize = info.EndOfFile.QuadPart;
- }else{
- pFile->lastErrno = osGetLastError();
- rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
- "winFileSize", pFile->zPath);
- }
- }
-#else
- {
- DWORD upperBits;
- DWORD lowerBits;
- DWORD lastErrno;
-
- lowerBits = osGetFileSize(pFile->h, &upperBits);
- *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
- if( (lowerBits == INVALID_FILE_SIZE)
- && ((lastErrno = osGetLastError())!=NO_ERROR) ){
- pFile->lastErrno = lastErrno;
- rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
- "winFileSize", pFile->zPath);
- }
- }
-#endif
- return rc;
-}
-
-/*
-** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
-*/
-#ifndef LOCKFILE_FAIL_IMMEDIATELY
-# define LOCKFILE_FAIL_IMMEDIATELY 1
-#endif
-
-#ifndef LOCKFILE_EXCLUSIVE_LOCK
-# define LOCKFILE_EXCLUSIVE_LOCK 2
-#endif
-
-/*
-** Historically, SQLite has used both the LockFile and LockFileEx functions.
-** When the LockFile function was used, it was always expected to fail
-** immediately if the lock could not be obtained. Also, it always expected to
-** obtain an exclusive lock. These flags are used with the LockFileEx function
-** and reflect those expectations; therefore, they should not be changed.
-*/
-#ifndef SQLITE_LOCKFILE_FLAGS
-# define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \
- LOCKFILE_EXCLUSIVE_LOCK)
-#endif
-
-/*
-** Currently, SQLite never calls the LockFileEx function without wanting the
-** call to fail immediately if the lock cannot be obtained.
-*/
-#ifndef SQLITE_LOCKFILEEX_FLAGS
-# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY)
-#endif
-
-/*
-** Acquire a reader lock.
-** Different API routines are called depending on whether or not this
-** is Win9x or WinNT.
-*/
-static int getReadLock(winFile *pFile){
- int res;
- if( isNT() ){
-#if SQLITE_OS_WINCE
- /*
- ** NOTE: Windows CE is handled differently here due its lack of the Win32
- ** API LockFileEx.
- */
- res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
-#else
- res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
- SHARED_SIZE, 0);
-#endif
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- int lk;
- sqlite3_randomness(sizeof(lk), &lk);
- pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
- res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
- SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
- }
-#endif
- if( res == 0 ){
- pFile->lastErrno = osGetLastError();
- /* No need to log a failure to lock */
- }
- return res;
-}
-
-/*
-** Undo a readlock
-*/
-static int unlockReadLock(winFile *pFile){
- int res;
- DWORD lastErrno;
- if( isNT() ){
- res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
- }
-#endif
- if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
- pFile->lastErrno = lastErrno;
- winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
- "unlockReadLock", pFile->zPath);
- }
- return res;
-}
-
-/*
-** Lock the file with the lock specified by parameter locktype - one
-** of the following:
-**
-** (1) SHARED_LOCK
-** (2) RESERVED_LOCK
-** (3) PENDING_LOCK
-** (4) EXCLUSIVE_LOCK
-**
-** Sometimes when requesting one lock state, additional lock states
-** are inserted in between. The locking might fail on one of the later
-** transitions leaving the lock state different from what it started but
-** still short of its goal. The following chart shows the allowed
-** transitions and the inserted intermediate states:
-**
-** UNLOCKED -> SHARED
-** SHARED -> RESERVED
-** SHARED -> (PENDING) -> EXCLUSIVE
-** RESERVED -> (PENDING) -> EXCLUSIVE
-** PENDING -> EXCLUSIVE
-**
-** This routine will only increase a lock. The winUnlock() routine
-** erases all locks at once and returns us immediately to locking level 0.
-** It is not possible to lower the locking level one step at a time. You
-** must go straight to locking level 0.
-*/
-static int winLock(sqlite3_file *id, int locktype){
- int rc = SQLITE_OK; /* Return code from subroutines */
- int res = 1; /* Result of a Windows lock call */
- int newLocktype; /* Set pFile->locktype to this value before exiting */
- int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
- winFile *pFile = (winFile*)id;
- DWORD lastErrno = NO_ERROR;
-
- assert( id!=0 );
- OSTRACE(("LOCK %d %d was %d(%d)\n",
- pFile->h, locktype, pFile->locktype, pFile->sharedLockByte));
-
- /* If there is already a lock of this type or more restrictive on the
- ** OsFile, do nothing. Don't use the end_lock: exit path, as
- ** sqlite3OsEnterMutex() hasn't been called yet.
- */
- if( pFile->locktype>=locktype ){
- return SQLITE_OK;
- }
-
- /* Make sure the locking sequence is correct
- */
- assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
- assert( locktype!=PENDING_LOCK );
- assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
-
- /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
- ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
- ** the PENDING_LOCK byte is temporary.
- */
- newLocktype = pFile->locktype;
- if( (pFile->locktype==NO_LOCK)
- || ( (locktype==EXCLUSIVE_LOCK)
- && (pFile->locktype==RESERVED_LOCK))
- ){
- int cnt = 3;
- while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
- PENDING_BYTE, 0, 1, 0))==0 ){
- /* Try 3 times to get the pending lock. This is needed to work
- ** around problems caused by indexing and/or anti-virus software on
- ** Windows systems.
- ** If you are using this code as a model for alternative VFSes, do not
- ** copy this retry logic. It is a hack intended for Windows only.
- */
- OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt));
- if( cnt ) sqlite3_win32_sleep(1);
- }
- gotPendingLock = res;
- if( !res ){
- lastErrno = osGetLastError();
- }
- }
-
- /* Acquire a shared lock
- */
- if( locktype==SHARED_LOCK && res ){
- assert( pFile->locktype==NO_LOCK );
- res = getReadLock(pFile);
- if( res ){
- newLocktype = SHARED_LOCK;
- }else{
- lastErrno = osGetLastError();
- }
- }
-
- /* Acquire a RESERVED lock
- */
- if( locktype==RESERVED_LOCK && res ){
- assert( pFile->locktype==SHARED_LOCK );
- res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
- if( res ){
- newLocktype = RESERVED_LOCK;
- }else{
- lastErrno = osGetLastError();
- }
- }
-
- /* Acquire a PENDING lock
- */
- if( locktype==EXCLUSIVE_LOCK && res ){
- newLocktype = PENDING_LOCK;
- gotPendingLock = 0;
- }
-
- /* Acquire an EXCLUSIVE lock
- */
- if( locktype==EXCLUSIVE_LOCK && res ){
- assert( pFile->locktype>=SHARED_LOCK );
- res = unlockReadLock(pFile);
- OSTRACE(("unreadlock = %d\n", res));
- res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
- SHARED_SIZE, 0);
- if( res ){
- newLocktype = EXCLUSIVE_LOCK;
- }else{
- lastErrno = osGetLastError();
- OSTRACE(("error-code = %d\n", lastErrno));
- getReadLock(pFile);
- }
- }
-
- /* If we are holding a PENDING lock that ought to be released, then
- ** release it now.
- */
- if( gotPendingLock && locktype==SHARED_LOCK ){
- winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
- }
-
- /* Update the state of the lock has held in the file descriptor then
- ** return the appropriate result code.
- */
- if( res ){
- rc = SQLITE_OK;
- }else{
- OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
- locktype, newLocktype));
- pFile->lastErrno = lastErrno;
- rc = SQLITE_BUSY;
- }
- pFile->locktype = (u8)newLocktype;
- return rc;
-}
-
-/*
-** This routine checks if there is a RESERVED lock held on the specified
-** file by this or any other process. If such a lock is held, return
-** non-zero, otherwise zero.
-*/
-static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
- int rc;
- winFile *pFile = (winFile*)id;
-
- SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-
- assert( id!=0 );
- if( pFile->locktype>=RESERVED_LOCK ){
- rc = 1;
- OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
- }else{
- rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
- if( rc ){
- winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
- }
- rc = !rc;
- OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
- }
- *pResOut = rc;
- return SQLITE_OK;
-}
-
-/*
-** Lower the locking level on file descriptor id to locktype. locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-**
-** It is not possible for this routine to fail if the second argument
-** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
-** might return SQLITE_IOERR;
-*/
-static int winUnlock(sqlite3_file *id, int locktype){
- int type;
- winFile *pFile = (winFile*)id;
- int rc = SQLITE_OK;
- assert( pFile!=0 );
- assert( locktype<=SHARED_LOCK );
- OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
- pFile->locktype, pFile->sharedLockByte));
- type = pFile->locktype;
- if( type>=EXCLUSIVE_LOCK ){
- winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
- if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
- /* This should never happen. We should always be able to
- ** reacquire the read lock */
- rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
- "winUnlock", pFile->zPath);
- }
- }
- if( type>=RESERVED_LOCK ){
- winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
- }
- if( locktype==NO_LOCK && type>=SHARED_LOCK ){
- unlockReadLock(pFile);
- }
- if( type>=PENDING_LOCK ){
- winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
- }
- pFile->locktype = (u8)locktype;
- return rc;
-}
-
-/*
-** If *pArg is inititially negative then this is a query. Set *pArg to
-** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
-**
-** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
-*/
-static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
- if( *pArg<0 ){
- *pArg = (pFile->ctrlFlags & mask)!=0;
- }else if( (*pArg)==0 ){
- pFile->ctrlFlags &= ~mask;
- }else{
- pFile->ctrlFlags |= mask;
- }
-}
-
-/* Forward declaration */
-static int getTempname(int nBuf, char *zBuf);
-
-/*
-** Control and query of the open file handle.
-*/
-static int winFileControl(sqlite3_file *id, int op, void *pArg){
- winFile *pFile = (winFile*)id;
- switch( op ){
- case SQLITE_FCNTL_LOCKSTATE: {
- *(int*)pArg = pFile->locktype;
- return SQLITE_OK;
- }
- case SQLITE_LAST_ERRNO: {
- *(int*)pArg = (int)pFile->lastErrno;
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_CHUNK_SIZE: {
- pFile->szChunk = *(int *)pArg;
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_SIZE_HINT: {
- if( pFile->szChunk>0 ){
- sqlite3_int64 oldSz;
- int rc = winFileSize(id, &oldSz);
- if( rc==SQLITE_OK ){
- sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
- if( newSz>oldSz ){
- SimulateIOErrorBenign(1);
- rc = winTruncate(id, newSz);
- SimulateIOErrorBenign(0);
- }
- }
- return rc;
- }
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_PERSIST_WAL: {
- winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
- winModeBit(pFile, WINFILE_PSOW, (int*)pArg);
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_VFSNAME: {
- *(char**)pArg = sqlite3_mprintf("win32");
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_WIN32_AV_RETRY: {
- int *a = (int*)pArg;
- if( a[0]>0 ){
- win32IoerrRetry = a[0];
- }else{
- a[0] = win32IoerrRetry;
- }
- if( a[1]>0 ){
- win32IoerrRetryDelay = a[1];
- }else{
- a[1] = win32IoerrRetryDelay;
- }
- return SQLITE_OK;
- }
- case SQLITE_FCNTL_TEMPFILENAME: {
- char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
- if( zTFile ){
- getTempname(pFile->pVfs->mxPathname, zTFile);
- *(char**)pArg = zTFile;
- }
- return SQLITE_OK;
- }
- }
- return SQLITE_NOTFOUND;
-}
-
-/*
-** Return the sector size in bytes of the underlying block device for
-** the specified file. This is almost always 512 bytes, but may be
-** larger for some devices.
-**
-** SQLite code assumes this function cannot fail. It also assumes that
-** if two files are created in the same file-system directory (i.e.
-** a database and its journal file) that the sector size will be the
-** same for both.
-*/
-static int winSectorSize(sqlite3_file *id){
- (void)id;
- return SQLITE_DEFAULT_SECTOR_SIZE;
-}
-
-/*
-** Return a vector of device characteristics.
-*/
-static int winDeviceCharacteristics(sqlite3_file *id){
- winFile *p = (winFile*)id;
- return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
- ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
-}
-
-#ifndef SQLITE_OMIT_WAL
-
-/*
-** Windows will only let you create file view mappings
-** on allocation size granularity boundaries.
-** During sqlite3_os_init() we do a GetSystemInfo()
-** to get the granularity size.
-*/
-SYSTEM_INFO winSysInfo;
-
-/*
-** Helper functions to obtain and relinquish the global mutex. The
-** global mutex is used to protect the winLockInfo objects used by
-** this file, all of which may be shared by multiple threads.
-**
-** Function winShmMutexHeld() is used to assert() that the global mutex
-** is held when required. This function is only used as part of assert()
-** statements. e.g.
-**
-** winShmEnterMutex()
-** assert( winShmMutexHeld() );
-** winShmLeaveMutex()
-*/
-static void winShmEnterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-static void winShmLeaveMutex(void){
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#ifdef SQLITE_DEBUG
-static int winShmMutexHeld(void) {
- return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#endif
-
-/*
-** Object used to represent a single file opened and mmapped to provide
-** shared memory. When multiple threads all reference the same
-** log-summary, each thread has its own winFile object, but they all
-** point to a single instance of this object. In other words, each
-** log-summary is opened only once per process.
-**
-** winShmMutexHeld() must be true when creating or destroying
-** this object or while reading or writing the following fields:
-**
-** nRef
-** pNext
-**
-** The following fields are read-only after the object is created:
-**
-** fid
-** zFilename
-**
-** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
-** winShmMutexHeld() is true when reading or writing any other field
-** in this structure.
-**
-*/
-struct winShmNode {
- sqlite3_mutex *mutex; /* Mutex to access this object */
- char *zFilename; /* Name of the file */
- winFile hFile; /* File handle from winOpen */
-
- int szRegion; /* Size of shared-memory regions */
- int nRegion; /* Size of array apRegion */
- struct ShmRegion {
- HANDLE hMap; /* File handle from CreateFileMapping */
- void *pMap;
- } *aRegion;
- DWORD lastErrno; /* The Windows errno from the last I/O error */
-
- int nRef; /* Number of winShm objects pointing to this */
- winShm *pFirst; /* All winShm objects pointing to this */
- winShmNode *pNext; /* Next in list of all winShmNode objects */
-#ifdef SQLITE_DEBUG
- u8 nextShmId; /* Next available winShm.id value */
-#endif
-};
-
-/*
-** A global array of all winShmNode objects.
-**
-** The winShmMutexHeld() must be true while reading or writing this list.
-*/
-static winShmNode *winShmNodeList = 0;
-
-/*
-** Structure used internally by this VFS to record the state of an
-** open shared memory connection.
-**
-** The following fields are initialized when this object is created and
-** are read-only thereafter:
-**
-** winShm.pShmNode
-** winShm.id
-**
-** All other fields are read/write. The winShm.pShmNode->mutex must be held
-** while accessing any read/write fields.
-*/
-struct winShm {
- winShmNode *pShmNode; /* The underlying winShmNode object */
- winShm *pNext; /* Next winShm with the same winShmNode */
- u8 hasMutex; /* True if holding the winShmNode mutex */
- u16 sharedMask; /* Mask of shared locks held */
- u16 exclMask; /* Mask of exclusive locks held */
-#ifdef SQLITE_DEBUG
- u8 id; /* Id of this connection with its winShmNode */
-#endif
-};
-
-/*
-** Constants used for locking
-*/
-#define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
-#define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
-
-/*
-** Apply advisory locks for all n bytes beginning at ofst.
-*/
-#define _SHM_UNLCK 1
-#define _SHM_RDLCK 2
-#define _SHM_WRLCK 3
-static int winShmSystemLock(
- winShmNode *pFile, /* Apply locks to this open shared-memory segment */
- int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
- int ofst, /* Offset to first byte to be locked/unlocked */
- int nByte /* Number of bytes to lock or unlock */
-){
- int rc = 0; /* Result code form Lock/UnlockFileEx() */
-
- /* Access to the winShmNode object is serialized by the caller */
- assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
-
- /* Release/Acquire the system-level lock */
- if( lockType==_SHM_UNLCK ){
- rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
- }else{
- /* Initialize the locking parameters */
- DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
- if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
- rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
- }
-
- if( rc!= 0 ){
- rc = SQLITE_OK;
- }else{
- pFile->lastErrno = osGetLastError();
- rc = SQLITE_BUSY;
- }
-
- OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n",
- pFile->hFile.h,
- rc==SQLITE_OK ? "ok" : "failed",
- lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx",
- pFile->lastErrno));
-
- return rc;
-}
-
-/* Forward references to VFS methods */
-static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
-static int winDelete(sqlite3_vfs *,const char*,int);
-
-/*
-** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
-**
-** This is not a VFS shared-memory method; it is a utility function called
-** by VFS shared-memory methods.
-*/
-static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
- winShmNode **pp;
- winShmNode *p;
- BOOL bRc;
- assert( winShmMutexHeld() );
- pp = &winShmNodeList;
- while( (p = *pp)!=0 ){
- if( p->nRef==0 ){
- int i;
- if( p->mutex ) sqlite3_mutex_free(p->mutex);
- for(i=0; i<p->nRegion; i++){
- bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
- OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
- (int)osGetCurrentProcessId(), i,
- bRc ? "ok" : "failed"));
- bRc = osCloseHandle(p->aRegion[i].hMap);
- OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n",
- (int)osGetCurrentProcessId(), i,
- bRc ? "ok" : "failed"));
- }
- if( p->hFile.h != INVALID_HANDLE_VALUE ){
- SimulateIOErrorBenign(1);
- winClose((sqlite3_file *)&p->hFile);
- SimulateIOErrorBenign(0);
- }
- if( deleteFlag ){
- SimulateIOErrorBenign(1);
- sqlite3BeginBenignMalloc();
- winDelete(pVfs, p->zFilename, 0);
- sqlite3EndBenignMalloc();
- SimulateIOErrorBenign(0);
- }
- *pp = p->pNext;
- sqlite3_free(p->aRegion);
- sqlite3_free(p);
- }else{
- pp = &p->pNext;
- }
- }
-}
-
-/*
-** Open the shared-memory area associated with database file pDbFd.
-**
-** When opening a new shared-memory file, if no other instances of that
-** file are currently open, in this process or in other processes, then
-** the file must be truncated to zero length or have its header cleared.
-*/
-static int winOpenSharedMemory(winFile *pDbFd){
- struct winShm *p; /* The connection to be opened */
- struct winShmNode *pShmNode = 0; /* The underlying mmapped file */
- int rc; /* Result code */
- struct winShmNode *pNew; /* Newly allocated winShmNode */
- int nName; /* Size of zName in bytes */
-
- assert( pDbFd->pShm==0 ); /* Not previously opened */
-
- /* Allocate space for the new sqlite3_shm object. Also speculatively
- ** allocate space for a new winShmNode and filename.
- */
- p = sqlite3MallocZero( sizeof(*p) );
- if( p==0 ) return SQLITE_IOERR_NOMEM;
- nName = sqlite3Strlen30(pDbFd->zPath);
- pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
- if( pNew==0 ){
- sqlite3_free(p);
- return SQLITE_IOERR_NOMEM;
- }
- pNew->zFilename = (char*)&pNew[1];
- sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
- sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
-
- /* Look to see if there is an existing winShmNode that can be used.
- ** If no matching winShmNode currently exists, create a new one.
- */
- winShmEnterMutex();
- for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
- /* TBD need to come up with better match here. Perhaps
- ** use FILE_ID_BOTH_DIR_INFO Structure.
- */
- if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
- }
- if( pShmNode ){
- sqlite3_free(pNew);
- }else{
- pShmNode = pNew;
- pNew = 0;
- ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
- pShmNode->pNext = winShmNodeList;
- winShmNodeList = pShmNode;
-
- pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
- if( pShmNode->mutex==0 ){
- rc = SQLITE_IOERR_NOMEM;
- goto shm_open_err;
- }
-
- rc = winOpen(pDbFd->pVfs,
- pShmNode->zFilename, /* Name of the file (UTF-8) */
- (sqlite3_file*)&pShmNode->hFile, /* File handle here */
- SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
- 0);
- if( SQLITE_OK!=rc ){
- goto shm_open_err;
- }
-
- /* Check to see if another process is holding the dead-man switch.
- ** If not, truncate the file to zero length.
- */
- if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
- rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
- if( rc!=SQLITE_OK ){
- rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
- "winOpenShm", pDbFd->zPath);
- }
- }
- if( rc==SQLITE_OK ){
- winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
- rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
- }
- if( rc ) goto shm_open_err;
- }
-
- /* Make the new connection a child of the winShmNode */
- p->pShmNode = pShmNode;
-#ifdef SQLITE_DEBUG
- p->id = pShmNode->nextShmId++;
-#endif
- pShmNode->nRef++;
- pDbFd->pShm = p;
- winShmLeaveMutex();
-
- /* The reference count on pShmNode has already been incremented under
- ** the cover of the winShmEnterMutex() mutex and the pointer from the
- ** new (struct winShm) object to the pShmNode has been set. All that is
- ** left to do is to link the new object into the linked list starting
- ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
- ** mutex.
- */
- sqlite3_mutex_enter(pShmNode->mutex);
- p->pNext = pShmNode->pFirst;
- pShmNode->pFirst = p;
- sqlite3_mutex_leave(pShmNode->mutex);
- return SQLITE_OK;
-
- /* Jump here on any error */
-shm_open_err:
- winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
- winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */
- sqlite3_free(p);
- sqlite3_free(pNew);
- winShmLeaveMutex();
- return rc;
-}
-
-/*
-** Close a connection to shared-memory. Delete the underlying
-** storage if deleteFlag is true.
-*/
-static int winShmUnmap(
- sqlite3_file *fd, /* Database holding shared memory */
- int deleteFlag /* Delete after closing if true */
-){
- winFile *pDbFd; /* Database holding shared-memory */
- winShm *p; /* The connection to be closed */
- winShmNode *pShmNode; /* The underlying shared-memory file */
- winShm **pp; /* For looping over sibling connections */
-
- pDbFd = (winFile*)fd;
- p = pDbFd->pShm;
- if( p==0 ) return SQLITE_OK;
- pShmNode = p->pShmNode;
-
- /* Remove connection p from the set of connections associated
- ** with pShmNode */
- sqlite3_mutex_enter(pShmNode->mutex);
- for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
- *pp = p->pNext;
-
- /* Free the connection p */
- sqlite3_free(p);
- pDbFd->pShm = 0;
- sqlite3_mutex_leave(pShmNode->mutex);
-
- /* If pShmNode->nRef has reached 0, then close the underlying
- ** shared-memory file, too */
- winShmEnterMutex();
- assert( pShmNode->nRef>0 );
- pShmNode->nRef--;
- if( pShmNode->nRef==0 ){
- winShmPurge(pDbFd->pVfs, deleteFlag);
- }
- winShmLeaveMutex();
-
- return SQLITE_OK;
-}
-
-/*
-** Change the lock state for a shared-memory segment.
-*/
-static int winShmLock(
- sqlite3_file *fd, /* Database file holding the shared memory */
- int ofst, /* First lock to acquire or release */
- int n, /* Number of locks to acquire or release */
- int flags /* What to do with the lock */
-){
- winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */
- winShm *p = pDbFd->pShm; /* The shared memory being locked */
- winShm *pX; /* For looping over all siblings */
- winShmNode *pShmNode = p->pShmNode;
- int rc = SQLITE_OK; /* Result code */
- u16 mask; /* Mask of locks to take or release */
-
- assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
- assert( n>=1 );
- assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
- || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
- || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
- || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
- assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
-
- mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
- assert( n>1 || mask==(1<<ofst) );
- sqlite3_mutex_enter(pShmNode->mutex);
- if( flags & SQLITE_SHM_UNLOCK ){
- u16 allMask = 0; /* Mask of locks held by siblings */
-
- /* See if any siblings hold this same lock */
- for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
- if( pX==p ) continue;
- assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
- allMask |= pX->sharedMask;
- }
-
- /* Unlock the system-level locks */
- if( (mask & allMask)==0 ){
- rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
- }else{
- rc = SQLITE_OK;
- }
-
- /* Undo the local locks */
- if( rc==SQLITE_OK ){
- p->exclMask &= ~mask;
- p->sharedMask &= ~mask;
- }
- }else if( flags & SQLITE_SHM_SHARED ){
- u16 allShared = 0; /* Union of locks held by connections other than "p" */
-
- /* Find out which shared locks are already held by sibling connections.
- ** If any sibling already holds an exclusive lock, go ahead and return
- ** SQLITE_BUSY.
- */
- for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
- if( (pX->exclMask & mask)!=0 ){
- rc = SQLITE_BUSY;
- break;
- }
- allShared |= pX->sharedMask;
- }
-
- /* Get shared locks at the system level, if necessary */
- if( rc==SQLITE_OK ){
- if( (allShared & mask)==0 ){
- rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
- }else{
- rc = SQLITE_OK;
- }
- }
-
- /* Get the local shared locks */
- if( rc==SQLITE_OK ){
- p->sharedMask |= mask;
- }
- }else{
- /* Make sure no sibling connections hold locks that will block this
- ** lock. If any do, return SQLITE_BUSY right away.
- */
- for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
- if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
- rc = SQLITE_BUSY;
- break;
- }
- }
-
- /* Get the exclusive locks at the system level. Then if successful
- ** also mark the local connection as being locked.
- */
- if( rc==SQLITE_OK ){
- rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
- if( rc==SQLITE_OK ){
- assert( (p->sharedMask & mask)==0 );
- p->exclMask |= mask;
- }
- }
- }
- sqlite3_mutex_leave(pShmNode->mutex);
- OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
- p->id, (int)osGetCurrentProcessId(), p->sharedMask, p->exclMask,
- rc ? "failed" : "ok"));
- return rc;
-}
-
-/*
-** Implement a memory barrier or memory fence on shared memory.
-**
-** All loads and stores begun before the barrier must complete before
-** any load or store begun after the barrier.
-*/
-static void winShmBarrier(
- sqlite3_file *fd /* Database holding the shared memory */
-){
- UNUSED_PARAMETER(fd);
- /* MemoryBarrier(); // does not work -- do not know why not */
- winShmEnterMutex();
- winShmLeaveMutex();
-}
-
-/*
-** This function is called to obtain a pointer to region iRegion of the
-** shared-memory associated with the database file fd. Shared-memory regions
-** are numbered starting from zero. Each shared-memory region is szRegion
-** bytes in size.
-**
-** If an error occurs, an error code is returned and *pp is set to NULL.
-**
-** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
-** region has not been allocated (by any client, including one running in a
-** separate process), then *pp is set to NULL and SQLITE_OK returned. If
-** isWrite is non-zero and the requested shared-memory region has not yet
-** been allocated, it is allocated by this function.
-**
-** If the shared-memory region has already been allocated or is allocated by
-** this call as described above, then it is mapped into this processes
-** address space (if it is not already), *pp is set to point to the mapped
-** memory and SQLITE_OK returned.
-*/
-static int winShmMap(
- sqlite3_file *fd, /* Handle open on database file */
- int iRegion, /* Region to retrieve */
- int szRegion, /* Size of regions */
- int isWrite, /* True to extend file if necessary */
- void volatile **pp /* OUT: Mapped memory */
-){
- winFile *pDbFd = (winFile*)fd;
- winShm *p = pDbFd->pShm;
- winShmNode *pShmNode;
- int rc = SQLITE_OK;
-
- if( !p ){
- rc = winOpenSharedMemory(pDbFd);
- if( rc!=SQLITE_OK ) return rc;
- p = pDbFd->pShm;
- }
- pShmNode = p->pShmNode;
-
- sqlite3_mutex_enter(pShmNode->mutex);
- assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
-
- if( pShmNode->nRegion<=iRegion ){
- struct ShmRegion *apNew; /* New aRegion[] array */
- int nByte = (iRegion+1)*szRegion; /* Minimum required file size */
- sqlite3_int64 sz; /* Current size of wal-index file */
-
- pShmNode->szRegion = szRegion;
-
- /* The requested region is not mapped into this processes address space.
- ** Check to see if it has been allocated (i.e. if the wal-index file is
- ** large enough to contain the requested region).
- */
- rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
- if( rc!=SQLITE_OK ){
- rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
- "winShmMap1", pDbFd->zPath);
- goto shmpage_out;
- }
-
- if( sz<nByte ){
- /* The requested memory region does not exist. If isWrite is set to
- ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
- **
- ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
- ** the requested memory region.
- */
- if( !isWrite ) goto shmpage_out;
- rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
- if( rc!=SQLITE_OK ){
- rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
- "winShmMap2", pDbFd->zPath);
- goto shmpage_out;
- }
- }
-
- /* Map the requested memory region into this processes address space. */
- apNew = (struct ShmRegion *)sqlite3_realloc(
- pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
- );
- if( !apNew ){
- rc = SQLITE_IOERR_NOMEM;
- goto shmpage_out;
- }
- pShmNode->aRegion = apNew;
-
- while( pShmNode->nRegion<=iRegion ){
- HANDLE hMap = NULL; /* file-mapping handle */
- void *pMap = 0; /* Mapped memory region */
-
-#if SQLITE_OS_WINRT
- hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
- NULL, PAGE_READWRITE, nByte, NULL
- );
-#elif defined(SQLITE_WIN32_HAS_WIDE)
- hMap = osCreateFileMappingW(pShmNode->hFile.h,
- NULL, PAGE_READWRITE, 0, nByte, NULL
- );
-#elif defined(SQLITE_WIN32_HAS_ANSI)
- hMap = osCreateFileMappingA(pShmNode->hFile.h,
- NULL, PAGE_READWRITE, 0, nByte, NULL
- );
-#endif
- OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n",
- (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte,
- hMap ? "ok" : "failed"));
- if( hMap ){
- int iOffset = pShmNode->nRegion*szRegion;
- int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
-#if SQLITE_OS_WINRT
- pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
- iOffset - iOffsetShift, szRegion + iOffsetShift
- );
-#else
- pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
- 0, iOffset - iOffsetShift, szRegion + iOffsetShift
- );
-#endif
- OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
- (int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
- szRegion, pMap ? "ok" : "failed"));
- }
- if( !pMap ){
- pShmNode->lastErrno = osGetLastError();
- rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
- "winShmMap3", pDbFd->zPath);
- if( hMap ) osCloseHandle(hMap);
- goto shmpage_out;
- }
-
- pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
- pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
- pShmNode->nRegion++;
- }
- }
-
-shmpage_out:
- if( pShmNode->nRegion>iRegion ){
- int iOffset = iRegion*szRegion;
- int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
- char *p = (char *)pShmNode->aRegion[iRegion].pMap;
- *pp = (void *)&p[iOffsetShift];
- }else{
- *pp = 0;
- }
- sqlite3_mutex_leave(pShmNode->mutex);
- return rc;
-}
-
-#else
-# define winShmMap 0
-# define winShmLock 0
-# define winShmBarrier 0
-# define winShmUnmap 0
-#endif /* #ifndef SQLITE_OMIT_WAL */
-
-/*
-** Here ends the implementation of all sqlite3_file methods.
-**
-********************** End sqlite3_file Methods *******************************
-******************************************************************************/
-
-/*
-** This vector defines all the methods that can operate on an
-** sqlite3_file for win32.
-*/
-static const sqlite3_io_methods winIoMethod = {
- 2, /* iVersion */
- winClose, /* xClose */
- winRead, /* xRead */
- winWrite, /* xWrite */
- winTruncate, /* xTruncate */
- winSync, /* xSync */
- winFileSize, /* xFileSize */
- winLock, /* xLock */
- winUnlock, /* xUnlock */
- winCheckReservedLock, /* xCheckReservedLock */
- winFileControl, /* xFileControl */
- winSectorSize, /* xSectorSize */
- winDeviceCharacteristics, /* xDeviceCharacteristics */
- winShmMap, /* xShmMap */
- winShmLock, /* xShmLock */
- winShmBarrier, /* xShmBarrier */
- winShmUnmap /* xShmUnmap */
-};
-
-/****************************************************************************
-**************************** sqlite3_vfs methods ****************************
-**
-** This division contains the implementation of methods on the
-** sqlite3_vfs object.
-*/
-
-/*
-** Convert a UTF-8 filename into whatever form the underlying
-** operating system wants filenames in. Space to hold the result
-** is obtained from malloc and must be freed by the calling
-** function.
-*/
-static void *convertUtf8Filename(const char *zFilename){
- void *zConverted = 0;
- if( isNT() ){
- zConverted = utf8ToUnicode(zFilename);
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
- }
-#endif
- /* caller will handle out of memory */
- return zConverted;
-}
-
-/*
-** Create a temporary file name in zBuf. zBuf must be big enough to
-** hold at pVfs->mxPathname characters.
-*/
-static int getTempname(int nBuf, char *zBuf){
- static char zChars[] =
- "abcdefghijklmnopqrstuvwxyz"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "0123456789";
- size_t i, j;
- int nTempPath;
- char zTempPath[MAX_PATH+2];
-
- /* It's odd to simulate an io-error here, but really this is just
- ** using the io-error infrastructure to test that SQLite handles this
- ** function failing.
- */
- SimulateIOError( return SQLITE_IOERR );
-
- memset(zTempPath, 0, MAX_PATH+2);
-
- if( sqlite3_temp_directory ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
- }
-#if !SQLITE_OS_WINRT
- else if( isNT() ){
- char *zMulti;
- WCHAR zWidePath[MAX_PATH];
- osGetTempPathW(MAX_PATH-30, zWidePath);
- zMulti = unicodeToUtf8(zWidePath);
- if( zMulti ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
- sqlite3_free(zMulti);
- }else{
- return SQLITE_IOERR_NOMEM;
- }
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- char *zUtf8;
- char zMbcsPath[MAX_PATH];
- osGetTempPathA(MAX_PATH-30, zMbcsPath);
- zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
- if( zUtf8 ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
- sqlite3_free(zUtf8);
- }else{
- return SQLITE_IOERR_NOMEM;
- }
- }
-#endif
-#endif
-
- /* Check that the output buffer is large enough for the temporary file
- ** name. If it is not, return SQLITE_ERROR.
- */
- nTempPath = sqlite3Strlen30(zTempPath);
-
- if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
- return SQLITE_ERROR;
- }
-
- for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){}
- zTempPath[i] = 0;
-
- sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ?
- "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX,
- zTempPath);
- j = sqlite3Strlen30(zBuf);
- sqlite3_randomness(15, &zBuf[j]);
- for(i=0; i<15; i++, j++){
- zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
- }
- zBuf[j] = 0;
- zBuf[j+1] = 0;
-
- OSTRACE(("TEMP FILENAME: %s\n", zBuf));
- return SQLITE_OK;
-}
-
-/*
-** Return TRUE if the named file is really a directory. Return false if
-** it is something other than a directory, or if there is any kind of memory
-** allocation failure.
-*/
-static int winIsDir(const void *zConverted){
- DWORD attr;
- int rc = 0;
- DWORD lastErrno;
-
- if( isNT() ){
- int cnt = 0;
- WIN32_FILE_ATTRIBUTE_DATA sAttrData;
- memset(&sAttrData, 0, sizeof(sAttrData));
- while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
- GetFileExInfoStandard,
- &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
- if( !rc ){
- return 0; /* Invalid name? */
- }
- attr = sAttrData.dwFileAttributes;
-#if SQLITE_OS_WINCE==0
- }else{
- attr = osGetFileAttributesA((char*)zConverted);
-#endif
- }
- return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
-}
-
-/*
-** Open a file.
-*/
-static int winOpen(
- sqlite3_vfs *pVfs, /* Not used */
- const char *zName, /* Name of the file (UTF-8) */
- sqlite3_file *id, /* Write the SQLite file handle here */
- int flags, /* Open mode flags */
- int *pOutFlags /* Status return flags */
-){
- HANDLE h;
- DWORD lastErrno;
- DWORD dwDesiredAccess;
- DWORD dwShareMode;
- DWORD dwCreationDisposition;
- DWORD dwFlagsAndAttributes = 0;
-#if SQLITE_OS_WINCE
- int isTemp = 0;
-#endif
- winFile *pFile = (winFile*)id;
- void *zConverted; /* Filename in OS encoding */
- const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
- int cnt = 0;
-
- /* If argument zPath is a NULL pointer, this function is required to open
- ** a temporary file. Use this buffer to store the file name in.
- */
- char zTmpname[MAX_PATH+2]; /* Buffer used to create temp filename */
-
- int rc = SQLITE_OK; /* Function Return Code */
-#if !defined(NDEBUG) || SQLITE_OS_WINCE
- int eType = flags&0xFFFFFF00; /* Type of file to open */
-#endif
-
- int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
- int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
- int isCreate = (flags & SQLITE_OPEN_CREATE);
-#ifndef NDEBUG
- int isReadonly = (flags & SQLITE_OPEN_READONLY);
-#endif
- int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
-
-#ifndef NDEBUG
- int isOpenJournal = (isCreate && (
- eType==SQLITE_OPEN_MASTER_JOURNAL
- || eType==SQLITE_OPEN_MAIN_JOURNAL
- || eType==SQLITE_OPEN_WAL
- ));
-#endif
-
- /* Check the following statements are true:
- **
- ** (a) Exactly one of the READWRITE and READONLY flags must be set, and
- ** (b) if CREATE is set, then READWRITE must also be set, and
- ** (c) if EXCLUSIVE is set, then CREATE must also be set.
- ** (d) if DELETEONCLOSE is set, then CREATE must also be set.
- */
- assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
- assert(isCreate==0 || isReadWrite);
- assert(isExclusive==0 || isCreate);
- assert(isDelete==0 || isCreate);
-
- /* The main DB, main journal, WAL file and master journal are never
- ** automatically deleted. Nor are they ever temporary files. */
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
- assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
-
- /* Assert that the upper layer has set one of the "file-type" flags. */
- assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB
- || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
- || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
- || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
- );
-
- assert( id!=0 );
- UNUSED_PARAMETER(pVfs);
-
-#if SQLITE_OS_WINRT
- if( !sqlite3_temp_directory ){
- sqlite3_log(SQLITE_ERROR,
- "sqlite3_temp_directory variable should be set for WinRT");
- }
-#endif
-
- pFile->h = INVALID_HANDLE_VALUE;
-
- /* If the second argument to this function is NULL, generate a
- ** temporary file name to use
- */
- if( !zUtf8Name ){
- assert(isDelete && !isOpenJournal);
- rc = getTempname(MAX_PATH+2, zTmpname);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- zUtf8Name = zTmpname;
- }
-
- /* Database filenames are double-zero terminated if they are not
- ** URIs with parameters. Hence, they can always be passed into
- ** sqlite3_uri_parameter().
- */
- assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
- zUtf8Name[strlen(zUtf8Name)+1]==0 );
-
- /* Convert the filename to the system encoding. */
- zConverted = convertUtf8Filename(zUtf8Name);
- if( zConverted==0 ){
- return SQLITE_IOERR_NOMEM;
- }
-
- if( winIsDir(zConverted) ){
- sqlite3_free(zConverted);
- return SQLITE_CANTOPEN_ISDIR;
- }
-
- if( isReadWrite ){
- dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
- }else{
- dwDesiredAccess = GENERIC_READ;
- }
-
- /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
- ** created. SQLite doesn't use it to indicate "exclusive access"
- ** as it is usually understood.
- */
- if( isExclusive ){
- /* Creates a new file, only if it does not already exist. */
- /* If the file exists, it fails. */
- dwCreationDisposition = CREATE_NEW;
- }else if( isCreate ){
- /* Open existing file, or create if it doesn't exist */
- dwCreationDisposition = OPEN_ALWAYS;
- }else{
- /* Opens a file, only if it exists. */
- dwCreationDisposition = OPEN_EXISTING;
- }
-
- dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-
- if( isDelete ){
-#if SQLITE_OS_WINCE
- dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
- isTemp = 1;
-#else
- dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
- | FILE_ATTRIBUTE_HIDDEN
- | FILE_FLAG_DELETE_ON_CLOSE;
-#endif
- }else{
- dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
- }
- /* Reports from the internet are that performance is always
- ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
-#if SQLITE_OS_WINCE
- dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
-#endif
-
- if( isNT() ){
-#if SQLITE_OS_WINRT
- CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
- extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
- extendedParameters.dwFileAttributes =
- dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
- extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
- extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
- extendedParameters.lpSecurityAttributes = NULL;
- extendedParameters.hTemplateFile = NULL;
- while( (h = osCreateFile2((LPCWSTR)zConverted,
- dwDesiredAccess,
- dwShareMode,
- dwCreationDisposition,
- &extendedParameters))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
- /* Noop */
- }
-#else
- while( (h = osCreateFileW((LPCWSTR)zConverted,
- dwDesiredAccess,
- dwShareMode, NULL,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- NULL))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
- /* Noop */
- }
-#endif
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- while( (h = osCreateFileA((LPCSTR)zConverted,
- dwDesiredAccess,
- dwShareMode, NULL,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- NULL))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
- /* Noop */
- }
- }
-#endif
- logIoerr(cnt);
-
- OSTRACE(("OPEN %d %s 0x%lx %s\n",
- h, zName, dwDesiredAccess,
- h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
-
- if( h==INVALID_HANDLE_VALUE ){
- pFile->lastErrno = lastErrno;
- winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
- sqlite3_free(zConverted);
- if( isReadWrite && !isExclusive ){
- return winOpen(pVfs, zName, id,
- ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
- }else{
- return SQLITE_CANTOPEN_BKPT;
- }
- }
-
- if( pOutFlags ){
- if( isReadWrite ){
- *pOutFlags = SQLITE_OPEN_READWRITE;
- }else{
- *pOutFlags = SQLITE_OPEN_READONLY;
- }
- }
-
- memset(pFile, 0, sizeof(*pFile));
- pFile->pMethod = &winIoMethod;
- pFile->h = h;
- pFile->lastErrno = NO_ERROR;
- pFile->pVfs = pVfs;
-#ifndef SQLITE_OMIT_WAL
- pFile->pShm = 0;
-#endif
- pFile->zPath = zName;
- if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
- pFile->ctrlFlags |= WINFILE_PSOW;
- }
-
-#if SQLITE_OS_WINCE
- if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
- && !winceCreateLock(zName, pFile)
- ){
- osCloseHandle(h);
- sqlite3_free(zConverted);
- return SQLITE_CANTOPEN_BKPT;
- }
- if( isTemp ){
- pFile->zDeleteOnClose = zConverted;
- }else
-#endif
- {
- sqlite3_free(zConverted);
- }
-
- OpenCounter(+1);
- return rc;
-}
-
-/*
-** Delete the named file.
-**
-** Note that Windows does not allow a file to be deleted if some other
-** process has it open. Sometimes a virus scanner or indexing program
-** will open a journal file shortly after it is created in order to do
-** whatever it does. While this other process is holding the
-** file open, we will be unable to delete it. To work around this
-** problem, we delay 100 milliseconds and try to delete again. Up
-** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
-** up and returning an error.
-*/
-static int winDelete(
- sqlite3_vfs *pVfs, /* Not used on win32 */
- const char *zFilename, /* Name of file to delete */
- int syncDir /* Not used on win32 */
-){
- int cnt = 0;
- int rc;
- DWORD attr;
- DWORD lastErrno;
- void *zConverted;
- UNUSED_PARAMETER(pVfs);
- UNUSED_PARAMETER(syncDir);
-
- SimulateIOError(return SQLITE_IOERR_DELETE);
- zConverted = convertUtf8Filename(zFilename);
- if( zConverted==0 ){
- return SQLITE_IOERR_NOMEM;
- }
- if( isNT() ){
- do {
-#if SQLITE_OS_WINRT
- WIN32_FILE_ATTRIBUTE_DATA sAttrData;
- memset(&sAttrData, 0, sizeof(sAttrData));
- if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
- &sAttrData) ){
- attr = sAttrData.dwFileAttributes;
- }else{
- lastErrno = osGetLastError();
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
- rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
- }else{
- rc = SQLITE_ERROR;
- }
- break;
- }
-#else
- attr = osGetFileAttributesW(zConverted);
-#endif
- if ( attr==INVALID_FILE_ATTRIBUTES ){
- lastErrno = osGetLastError();
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
- rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
- }else{
- rc = SQLITE_ERROR;
- }
- break;
- }
- if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
- rc = SQLITE_ERROR; /* Files only. */
- break;
- }
- if ( osDeleteFileW(zConverted) ){
- rc = SQLITE_OK; /* Deleted OK. */
- break;
- }
- if ( !retryIoerr(&cnt, &lastErrno) ){
- rc = SQLITE_ERROR; /* No more retries. */
- break;
- }
- } while(1);
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- do {
- attr = osGetFileAttributesA(zConverted);
- if ( attr==INVALID_FILE_ATTRIBUTES ){
- lastErrno = osGetLastError();
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
- rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
- }else{
- rc = SQLITE_ERROR;
- }
- break;
- }
- if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
- rc = SQLITE_ERROR; /* Files only. */
- break;
- }
- if ( osDeleteFileA(zConverted) ){
- rc = SQLITE_OK; /* Deleted OK. */
- break;
- }
- if ( !retryIoerr(&cnt, &lastErrno) ){
- rc = SQLITE_ERROR; /* No more retries. */
- break;
- }
- } while(1);
- }
-#endif
- if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
- rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
- "winDelete", zFilename);
- }else{
- logIoerr(cnt);
- }
- sqlite3_free(zConverted);
- OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" )));
- return rc;
-}
-
-/*
-** Check the existance and status of a file.
-*/
-static int winAccess(
- sqlite3_vfs *pVfs, /* Not used on win32 */
- const char *zFilename, /* Name of file to check */
- int flags, /* Type of test to make on this file */
- int *pResOut /* OUT: Result */
-){
- DWORD attr;
- int rc = 0;
- DWORD lastErrno;
- void *zConverted;
- UNUSED_PARAMETER(pVfs);
-
- SimulateIOError( return SQLITE_IOERR_ACCESS; );
- zConverted = convertUtf8Filename(zFilename);
- if( zConverted==0 ){
- return SQLITE_IOERR_NOMEM;
- }
- if( isNT() ){
- int cnt = 0;
- WIN32_FILE_ATTRIBUTE_DATA sAttrData;
- memset(&sAttrData, 0, sizeof(sAttrData));
- while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
- GetFileExInfoStandard,
- &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
- if( rc ){
- /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
- ** as if it does not exist.
- */
- if( flags==SQLITE_ACCESS_EXISTS
- && sAttrData.nFileSizeHigh==0
- && sAttrData.nFileSizeLow==0 ){
- attr = INVALID_FILE_ATTRIBUTES;
- }else{
- attr = sAttrData.dwFileAttributes;
- }
- }else{
- logIoerr(cnt);
- if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
- winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
- sqlite3_free(zConverted);
- return SQLITE_IOERR_ACCESS;
- }else{
- attr = INVALID_FILE_ATTRIBUTES;
- }
- }
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- attr = osGetFileAttributesA((char*)zConverted);
- }
-#endif
- sqlite3_free(zConverted);
- switch( flags ){
- case SQLITE_ACCESS_READ:
- case SQLITE_ACCESS_EXISTS:
- rc = attr!=INVALID_FILE_ATTRIBUTES;
- break;
- case SQLITE_ACCESS_READWRITE:
- rc = attr!=INVALID_FILE_ATTRIBUTES &&
- (attr & FILE_ATTRIBUTE_READONLY)==0;
- break;
- default:
- assert(!"Invalid flags argument");
- }
- *pResOut = rc;
- return SQLITE_OK;
-}
-
-
-/*
-** Returns non-zero if the specified path name should be used verbatim. If
-** non-zero is returned from this function, the calling function must simply
-** use the provided path name verbatim -OR- resolve it into a full path name
-** using the GetFullPathName Win32 API function (if available).
-*/
-static BOOL winIsVerbatimPathname(
- const char *zPathname
-){
- /*
- ** If the path name starts with a forward slash or a backslash, it is either
- ** a legal UNC name, a volume relative path, or an absolute path name in the
- ** "Unix" format on Windows. There is no easy way to differentiate between
- ** the final two cases; therefore, we return the safer return value of TRUE
- ** so that callers of this function will simply use it verbatim.
- */
- if ( zPathname[0]=='/' || zPathname[0]=='\\' ){
- return TRUE;
- }
-
- /*
- ** If the path name starts with a letter and a colon it is either a volume
- ** relative path or an absolute path. Callers of this function must not
- ** attempt to treat it as a relative path name (i.e. they should simply use
- ** it verbatim).
- */
- if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
- return TRUE;
- }
-
- /*
- ** If we get to this point, the path name should almost certainly be a purely
- ** relative one (i.e. not a UNC name, not absolute, and not volume relative).
- */
- return FALSE;
-}
-
-/*
-** Turn a relative pathname into a full pathname. Write the full
-** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
-** bytes in size.
-*/
-static int winFullPathname(
- sqlite3_vfs *pVfs, /* Pointer to vfs object */
- const char *zRelative, /* Possibly relative input path */
- int nFull, /* Size of output buffer in bytes */
- char *zFull /* Output buffer */
-){
-
-#if defined(__CYGWIN__)
- SimulateIOError( return SQLITE_ERROR );
- UNUSED_PARAMETER(nFull);
- assert( pVfs->mxPathname>=MAX_PATH );
- assert( nFull>=pVfs->mxPathname );
- if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
- /*
- ** NOTE: We are dealing with a relative path name and the data
- ** directory has been set. Therefore, use it as the basis
- ** for converting the relative path name to an absolute
- ** one by prepending the data directory and a slash.
- */
- char zOut[MAX_PATH+1];
- memset(zOut, 0, MAX_PATH+1);
- cygwin_conv_to_win32_path(zRelative, zOut); /* POSIX to Win32 */
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
- sqlite3_data_directory, zOut);
- }else{
- /*
- ** NOTE: The Cygwin docs state that the maximum length needed
- ** for the buffer passed to cygwin_conv_to_full_win32_path
- ** is MAX_PATH.
- */
- cygwin_conv_to_full_win32_path(zRelative, zFull);
- }
- return SQLITE_OK;
-#endif
-
-#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
- SimulateIOError( return SQLITE_ERROR );
- /* WinCE has no concept of a relative pathname, or so I am told. */
- /* WinRT has no way to convert a relative path to an absolute one. */
- if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
- /*
- ** NOTE: We are dealing with a relative path name and the data
- ** directory has been set. Therefore, use it as the basis
- ** for converting the relative path name to an absolute
- ** one by prepending the data directory and a backslash.
- */
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
- sqlite3_data_directory, zRelative);
- }else{
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
- }
- return SQLITE_OK;
-#endif
-
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
- DWORD nByte;
- void *zConverted;
- char *zOut;
-
- /* If this path name begins with "/X:", where "X" is any alphabetic
- ** character, discard the initial "/" from the pathname.
- */
- if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
- zRelative++;
- }
-
- /* It's odd to simulate an io-error here, but really this is just
- ** using the io-error infrastructure to test that SQLite handles this
- ** function failing. This function could fail if, for example, the
- ** current working directory has been unlinked.
- */
- SimulateIOError( return SQLITE_ERROR );
- if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
- /*
- ** NOTE: We are dealing with a relative path name and the data
- ** directory has been set. Therefore, use it as the basis
- ** for converting the relative path name to an absolute
- ** one by prepending the data directory and a backslash.
- */
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
- sqlite3_data_directory, zRelative);
- return SQLITE_OK;
- }
- zConverted = convertUtf8Filename(zRelative);
- if( zConverted==0 ){
- return SQLITE_IOERR_NOMEM;
- }
- if( isNT() ){
- LPWSTR zTemp;
- nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
- if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameW1", zConverted);
- sqlite3_free(zConverted);
- return SQLITE_CANTOPEN_FULLPATH;
- }
- nByte += 3;
- zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
- if( zTemp==0 ){
- sqlite3_free(zConverted);
- return SQLITE_IOERR_NOMEM;
- }
- nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
- if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameW2", zConverted);
- sqlite3_free(zConverted);
- sqlite3_free(zTemp);
- return SQLITE_CANTOPEN_FULLPATH;
- }
- sqlite3_free(zConverted);
- zOut = unicodeToUtf8(zTemp);
- sqlite3_free(zTemp);
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- char *zTemp;
- nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
- if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameA1", zConverted);
- sqlite3_free(zConverted);
- return SQLITE_CANTOPEN_FULLPATH;
- }
- nByte += 3;
- zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
- if( zTemp==0 ){
- sqlite3_free(zConverted);
- return SQLITE_IOERR_NOMEM;
- }
- nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
- if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameA2", zConverted);
- sqlite3_free(zConverted);
- sqlite3_free(zTemp);
- return SQLITE_CANTOPEN_FULLPATH;
- }
- sqlite3_free(zConverted);
- zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
- sqlite3_free(zTemp);
- }
-#endif
- if( zOut ){
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut);
- sqlite3_free(zOut);
- return SQLITE_OK;
- }else{
- return SQLITE_IOERR_NOMEM;
- }
-#endif
-}
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-/*
-** Interfaces for opening a shared library, finding entry points
-** within the shared library, and closing the shared library.
-*/
-/*
-** Interfaces for opening a shared library, finding entry points
-** within the shared library, and closing the shared library.
-*/
-static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
- HANDLE h;
- void *zConverted = convertUtf8Filename(zFilename);
- UNUSED_PARAMETER(pVfs);
- if( zConverted==0 ){
- return 0;
- }
- if( isNT() ){
-#if SQLITE_OS_WINRT
- h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
-#else
- h = osLoadLibraryW((LPCWSTR)zConverted);
-#endif
- }
-#ifdef SQLITE_WIN32_HAS_ANSI
- else{
- h = osLoadLibraryA((char*)zConverted);
- }
-#endif
- sqlite3_free(zConverted);
- return (void*)h;
-}
-static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
- UNUSED_PARAMETER(pVfs);
- getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
-}
-static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
- UNUSED_PARAMETER(pVfs);
- return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol);
-}
-static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
- UNUSED_PARAMETER(pVfs);
- osFreeLibrary((HANDLE)pHandle);
-}
-#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
- #define winDlOpen 0
- #define winDlError 0
- #define winDlSym 0
- #define winDlClose 0
-#endif
-
-
-/*
-** Write up to nBuf bytes of randomness into zBuf.
-*/
-static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
- int n = 0;
- UNUSED_PARAMETER(pVfs);
-#if defined(SQLITE_TEST)
- n = nBuf;
- memset(zBuf, 0, nBuf);
-#else
- if( sizeof(SYSTEMTIME)<=nBuf-n ){
- SYSTEMTIME x;
- osGetSystemTime(&x);
- memcpy(&zBuf[n], &x, sizeof(x));
- n += sizeof(x);
- }
- if( sizeof(DWORD)<=nBuf-n ){
- DWORD pid = osGetCurrentProcessId();
- memcpy(&zBuf[n], &pid, sizeof(pid));
- n += sizeof(pid);
- }
-#if SQLITE_OS_WINRT
- if( sizeof(ULONGLONG)<=nBuf-n ){
- ULONGLONG cnt = osGetTickCount64();
- memcpy(&zBuf[n], &cnt, sizeof(cnt));
- n += sizeof(cnt);
- }
-#else
- if( sizeof(DWORD)<=nBuf-n ){
- DWORD cnt = osGetTickCount();
- memcpy(&zBuf[n], &cnt, sizeof(cnt));
- n += sizeof(cnt);
- }
-#endif
- if( sizeof(LARGE_INTEGER)<=nBuf-n ){
- LARGE_INTEGER i;
- osQueryPerformanceCounter(&i);
- memcpy(&zBuf[n], &i, sizeof(i));
- n += sizeof(i);
- }
-#endif
- return n;
-}
-
-
-/*
-** Sleep for a little while. Return the amount of time slept.
-*/
-static int winSleep(sqlite3_vfs *pVfs, int microsec){
- sqlite3_win32_sleep((microsec+999)/1000);
- UNUSED_PARAMETER(pVfs);
- return ((microsec+999)/1000)*1000;
-}
-
-/*
-** The following variable, if set to a non-zero value, is interpreted as
-** the number of seconds since 1970 and is used to set the result of
-** sqlite3OsCurrentTime() during testing.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */
-#endif
-
-/*
-** Find the current time (in Universal Coordinated Time). Write into *piNow
-** the current time and date as a Julian Day number times 86_400_000. In
-** other words, write into *piNow the number of milliseconds since the Julian
-** epoch of noon in Greenwich on November 24, 4714 B.C according to the
-** proleptic Gregorian calendar.
-**
-** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
-** cannot be found.
-*/
-static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
- /* FILETIME structure is a 64-bit value representing the number of
- 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
- */
- FILETIME ft;
- static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
-#ifdef SQLITE_TEST
- static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
-#endif
- /* 2^32 - to avoid use of LL and warnings in gcc */
- static const sqlite3_int64 max32BitValue =
- (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
-
-#if SQLITE_OS_WINCE
- SYSTEMTIME time;
- osGetSystemTime(&time);
- /* if SystemTimeToFileTime() fails, it returns zero. */
- if (!osSystemTimeToFileTime(&time,&ft)){
- return SQLITE_ERROR;
- }
-#else
- osGetSystemTimeAsFileTime( &ft );
-#endif
-
- *piNow = winFiletimeEpoch +
- ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
- (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
-
-#ifdef SQLITE_TEST
- if( sqlite3_current_time ){
- *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
- }
-#endif
- UNUSED_PARAMETER(pVfs);
- return SQLITE_OK;
-}
-
-/*
-** Find the current time (in Universal Coordinated Time). Write the
-** current time and date as a Julian Day number into *prNow and
-** return 0. Return 1 if the time and date cannot be found.
-*/
-static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
- int rc;
- sqlite3_int64 i;
- rc = winCurrentTimeInt64(pVfs, &i);
- if( !rc ){
- *prNow = i/86400000.0;
- }
- return rc;
-}
-
-/*
-** The idea is that this function works like a combination of
-** GetLastError() and FormatMessage() on Windows (or errno and
-** strerror_r() on Unix). After an error is returned by an OS
-** function, SQLite calls this function with zBuf pointing to
-** a buffer of nBuf bytes. The OS layer should populate the
-** buffer with a nul-terminated UTF-8 encoded error message
-** describing the last IO error to have occurred within the calling
-** thread.
-**
-** If the error message is too large for the supplied buffer,
-** it should be truncated. The return value of xGetLastError
-** is zero if the error message fits in the buffer, or non-zero
-** otherwise (if the message was truncated). If non-zero is returned,
-** then it is not necessary to include the nul-terminator character
-** in the output buffer.
-**
-** Not supplying an error message will have no adverse effect
-** on SQLite. It is fine to have an implementation that never
-** returns an error message:
-**
-** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-** assert(zBuf[0]=='\0');
-** return 0;
-** }
-**
-** However if an error message is supplied, it will be incorporated
-** by sqlite into the error message available to the user using
-** sqlite3_errmsg(), possibly making IO errors easier to debug.
-*/
-static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
- UNUSED_PARAMETER(pVfs);
- return getLastErrorMsg(osGetLastError(), nBuf, zBuf);
-}
-
-/*
-** Initialize and deinitialize the operating system interface.
-*/
-SQLITE_API int sqlite3_os_init(void){
- static sqlite3_vfs winVfs = {
- 3, /* iVersion */
- sizeof(winFile), /* szOsFile */
- MAX_PATH, /* mxPathname */
- 0, /* pNext */
- "win32", /* zName */
- 0, /* pAppData */
- winOpen, /* xOpen */
- winDelete, /* xDelete */
- winAccess, /* xAccess */
- winFullPathname, /* xFullPathname */
- winDlOpen, /* xDlOpen */
- winDlError, /* xDlError */
- winDlSym, /* xDlSym */
- winDlClose, /* xDlClose */
- winRandomness, /* xRandomness */
- winSleep, /* xSleep */
- winCurrentTime, /* xCurrentTime */
- winGetLastError, /* xGetLastError */
- winCurrentTimeInt64, /* xCurrentTimeInt64 */
- winSetSystemCall, /* xSetSystemCall */
- winGetSystemCall, /* xGetSystemCall */
- winNextSystemCall, /* xNextSystemCall */
- };
-
- /* Double-check that the aSyscall[] array has been constructed
- ** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==74 );
-
-#ifndef SQLITE_OMIT_WAL
- /* get memory map allocation granularity */
- memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
-#if SQLITE_OS_WINRT
- osGetNativeSystemInfo(&winSysInfo);
-#else
- osGetSystemInfo(&winSysInfo);
-#endif
- assert(winSysInfo.dwAllocationGranularity > 0);
-#endif
-
- sqlite3_vfs_register(&winVfs, 1);
- return SQLITE_OK;
-}
-
-SQLITE_API int sqlite3_os_end(void){
-#if SQLITE_OS_WINRT
- if( sleepObj!=NULL ){
- osCloseHandle(sleepObj);
- sleepObj = NULL;
- }
-#endif
- return SQLITE_OK;
-}
-
-#endif /* SQLITE_OS_WIN */
-
-/************** End of os_win.c **********************************************/
-/************** Begin file bitvec.c ******************************************/
-/*
-** 2008 February 16
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file implements an object that represents a fixed-length
-** bitmap. Bits are numbered starting with 1.
-**
-** A bitmap is used to record which pages of a database file have been
-** journalled during a transaction, or which pages have the "dont-write"
-** property. Usually only a few pages are meet either condition.
-** So the bitmap is usually sparse and has low cardinality.
-** But sometimes (for example when during a DROP of a large table) most
-** or all of the pages in a database can get journalled. In those cases,
-** the bitmap becomes dense with high cardinality. The algorithm needs
-** to handle both cases well.
-**
-** The size of the bitmap is fixed when the object is created.
-**
-** All bits are clear when the bitmap is created. Individual bits
-** may be set or cleared one at a time.
-**
-** Test operations are about 100 times more common that set operations.
-** Clear operations are exceedingly rare. There are usually between
-** 5 and 500 set operations per Bitvec object, though the number of sets can
-** sometimes grow into tens of thousands or larger. The size of the
-** Bitvec object is the number of pages in the database file at the
-** start of a transaction, and is thus usually less than a few thousand,
-** but can be as large as 2 billion for a really big database.
-*/
-
-/* Size of the Bitvec structure in bytes. */
-#define BITVEC_SZ 512
-
-/* Round the union size down to the nearest pointer boundary, since that's how
-** it will be aligned within the Bitvec struct. */
-#define BITVEC_USIZE (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
-
-/* Type of the array "element" for the bitmap representation.
-** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE.
-** Setting this to the "natural word" size of your CPU may improve
-** performance. */
-#define BITVEC_TELEM u8
-/* Size, in bits, of the bitmap element. */
-#define BITVEC_SZELEM 8
-/* Number of elements in a bitmap array. */
-#define BITVEC_NELEM (BITVEC_USIZE/sizeof(BITVEC_TELEM))
-/* Number of bits in the bitmap array. */
-#define BITVEC_NBIT (BITVEC_NELEM*BITVEC_SZELEM)
-
-/* Number of u32 values in hash table. */
-#define BITVEC_NINT (BITVEC_USIZE/sizeof(u32))
-/* Maximum number of entries in hash table before
-** sub-dividing and re-hashing. */
-#define BITVEC_MXHASH (BITVEC_NINT/2)
-/* Hashing function for the aHash representation.
-** Empirical testing showed that the *37 multiplier
-** (an arbitrary prime)in the hash function provided
-** no fewer collisions than the no-op *1. */
-#define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT)
-
-#define BITVEC_NPTR (BITVEC_USIZE/sizeof(Bitvec *))
-
-
-/*
-** A bitmap is an instance of the following structure.
-**
-** This bitmap records the existance of zero or more bits
-** with values between 1 and iSize, inclusive.
-**
-** There are three possible representations of the bitmap.
-** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight
-** bitmap. The least significant bit is bit 1.
-**
-** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is
-** a hash table that will hold up to BITVEC_MXHASH distinct values.
-**
-** Otherwise, the value i is redirected into one of BITVEC_NPTR
-** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap
-** handles up to iDivisor separate values of i. apSub[0] holds
-** values between 1 and iDivisor. apSub[1] holds values between
-** iDivisor+1 and 2*iDivisor. apSub[N] holds values between
-** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized
-** to hold deal with values between 1 and iDivisor.
-*/
-struct Bitvec {
- u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */
- u32 nSet; /* Number of bits that are set - only valid for aHash
- ** element. Max is BITVEC_NINT. For BITVEC_SZ of 512,
- ** this would be 125. */
- u32 iDivisor; /* Number of bits handled by each apSub[] entry. */
- /* Should >=0 for apSub element. */
- /* Max iDivisor is max(u32) / BITVEC_NPTR + 1. */
- /* For a BITVEC_SZ of 512, this would be 34,359,739. */
- union {
- BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */
- u32 aHash[BITVEC_NINT]; /* Hash table representation */
- Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */
- } u;
-};
-
-/*
-** Create a new bitmap object able to handle bits between 0 and iSize,
-** inclusive. Return a pointer to the new object. Return NULL if
-** malloc fails.
-*/
-SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){
- Bitvec *p;
- assert( sizeof(*p)==BITVEC_SZ );
- p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
- p->iSize = iSize;
- }
- return p;
-}
-
-/*
-** Check to see if the i-th bit is set. Return true or false.
-** If p is NULL (if the bitmap has not been created) or if
-** i is out of range, then return false.
-*/
-SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
- if( p==0 ) return 0;
- if( i>p->iSize || i==0 ) return 0;
- i--;
- while( p->iDivisor ){
- u32 bin = i/p->iDivisor;
- i = i%p->iDivisor;
- p = p->u.apSub[bin];
- if (!p) {
- return 0;
- }
- }
- if( p->iSize<=BITVEC_NBIT ){
- return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0;
- } else{
- u32 h = BITVEC_HASH(i++);
- while( p->u.aHash[h] ){
- if( p->u.aHash[h]==i ) return 1;
- h = (h+1) % BITVEC_NINT;
- }
- return 0;
- }
-}
-
-/*
-** Set the i-th bit. Return 0 on success and an error code if
-** anything goes wrong.
-**
-** This routine might cause sub-bitmaps to be allocated. Failing
-** to get the memory needed to hold the sub-bitmap is the only
-** that can go wrong with an insert, assuming p and i are valid.
-**
-** The calling function must ensure that p is a valid Bitvec object
-** and that the value for "i" is within range of the Bitvec object.
-** Otherwise the behavior is undefined.
-*/
-SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){
- u32 h;
- if( p==0 ) return SQLITE_OK;
- assert( i>0 );
- assert( i<=p->iSize );
- i--;
- while((p->iSize > BITVEC_NBIT) && p->iDivisor) {
- u32 bin = i/p->iDivisor;
- i = i%p->iDivisor;
- if( p->u.apSub[bin]==0 ){
- p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
- if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
- }
- p = p->u.apSub[bin];
- }
- if( p->iSize<=BITVEC_NBIT ){
- p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1));
- return SQLITE_OK;
- }
- h = BITVEC_HASH(i++);
- /* if there wasn't a hash collision, and this doesn't */
- /* completely fill the hash, then just add it without */
- /* worring about sub-dividing and re-hashing. */
- if( !p->u.aHash[h] ){
- if (p->nSet<(BITVEC_NINT-1)) {
- goto bitvec_set_end;
- } else {
- goto bitvec_set_rehash;
- }
- }
- /* there was a collision, check to see if it's already */
- /* in hash, if not, try to find a spot for it */
- do {
- if( p->u.aHash[h]==i ) return SQLITE_OK;
- h++;
- if( h>=BITVEC_NINT ) h = 0;
- } while( p->u.aHash[h] );
- /* we didn't find it in the hash. h points to the first */
- /* available free spot. check to see if this is going to */
- /* make our hash too "full". */
-bitvec_set_rehash:
- if( p->nSet>=BITVEC_MXHASH ){
- unsigned int j;
- int rc;
- u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
- if( aiValues==0 ){
- return SQLITE_NOMEM;
- }else{
- memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
- memset(p->u.apSub, 0, sizeof(p->u.apSub));
- p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
- rc = sqlite3BitvecSet(p, i);
- for(j=0; j<BITVEC_NINT; j++){
- if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
- }
- sqlite3StackFree(0, aiValues);
- return rc;
- }
- }
-bitvec_set_end:
- p->nSet++;
- p->u.aHash[h] = i;
- return SQLITE_OK;
-}
-
-/*
-** Clear the i-th bit.
-**
-** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
-** that BitvecClear can use to rebuilt its hash table.
-*/
-SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
- if( p==0 ) return;
- assert( i>0 );
- i--;
- while( p->iDivisor ){
- u32 bin = i/p->iDivisor;
- i = i%p->iDivisor;
- p = p->u.apSub[bin];
- if (!p) {
- return;
- }
- }
- if( p->iSize<=BITVEC_NBIT ){
- p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
- }else{
- unsigned int j;
- u32 *aiValues = pBuf;
- memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
- memset(p->u.aHash, 0, sizeof(p->u.aHash));
- p->nSet = 0;
- for(j=0; j<BITVEC_NINT; j++){
- if( aiValues[j] && aiValues[j]!=(i+1) ){
- u32 h = BITVEC_HASH(aiValues[j]-1);
- p->nSet++;
- while( p->u.aHash[h] ){
- h++;
- if( h>=BITVEC_NINT ) h = 0;
- }
- p->u.aHash[h] = aiValues[j];
- }
- }
- }
-}
-
-/*
-** Destroy a bitmap object. Reclaim all memory used.
-*/
-SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){
- if( p==0 ) return;
- if( p->iDivisor ){
- unsigned int i;
- for(i=0; i<BITVEC_NPTR; i++){
- sqlite3BitvecDestroy(p->u.apSub[i]);
- }
- }
- sqlite3_free(p);
-}
-
-/*
-** Return the value of the iSize parameter specified when Bitvec *p
-** was created.
-*/
-SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
- return p->iSize;
-}
-
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-/*
-** Let V[] be an array of unsigned characters sufficient to hold
-** up to N bits. Let I be an integer between 0 and N. 0<=I<N.
-** Then the following macros can be used to set, clear, or test
-** individual bits within V.
-*/
-#define SETBIT(V,I) V[I>>3] |= (1<<(I&7))
-#define CLEARBIT(V,I) V[I>>3] &= ~(1<<(I&7))
-#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0
-
-/*
-** This routine runs an extensive test of the Bitvec code.
-**
-** The input is an array of integers that acts as a program
-** to test the Bitvec. The integers are opcodes followed
-** by 0, 1, or 3 operands, depending on the opcode. Another
-** opcode follows immediately after the last operand.
-**
-** There are 6 opcodes numbered from 0 through 5. 0 is the
-** "halt" opcode and causes the test to end.
-**
-** 0 Halt and return the number of errors
-** 1 N S X Set N bits beginning with S and incrementing by X
-** 2 N S X Clear N bits beginning with S and incrementing by X
-** 3 N Set N randomly chosen bits
-** 4 N Clear N randomly chosen bits
-** 5 N S X Set N bits from S increment X in array only, not in bitvec
-**
-** The opcodes 1 through 4 perform set and clear operations are performed
-** on both a Bitvec object and on a linear array of bits obtained from malloc.
-** Opcode 5 works on the linear array only, not on the Bitvec.
-** Opcode 5 is used to deliberately induce a fault in order to
-** confirm that error detection works.
-**
-** At the conclusion of the test the linear array is compared
-** against the Bitvec object. If there are any differences,
-** an error is returned. If they are the same, zero is returned.
-**
-** If a memory allocation error occurs, return -1.
-*/
-SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
- Bitvec *pBitvec = 0;
- unsigned char *pV = 0;
- int rc = -1;
- int i, nx, pc, op;
- void *pTmpSpace;
-
- /* Allocate the Bitvec to be tested and a linear array of
- ** bits to act as the reference */
- pBitvec = sqlite3BitvecCreate( sz );
- pV = sqlite3MallocZero( (sz+7)/8 + 1 );
- pTmpSpace = sqlite3_malloc(BITVEC_SZ);
- if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
-
- /* NULL pBitvec tests */
- sqlite3BitvecSet(0, 1);
- sqlite3BitvecClear(0, 1, pTmpSpace);
-
- /* Run the program */
- pc = 0;
- while( (op = aOp[pc])!=0 ){
- switch( op ){
- case 1:
- case 2:
- case 5: {
- nx = 4;
- i = aOp[pc+2] - 1;
- aOp[pc+2] += aOp[pc+3];
- break;
- }
- case 3:
- case 4:
- default: {
- nx = 2;
- sqlite3_randomness(sizeof(i), &i);
- break;
- }
- }
- if( (--aOp[pc+1]) > 0 ) nx = 0;
- pc += nx;
- i = (i & 0x7fffffff)%sz;
- if( (op & 1)!=0 ){
- SETBIT(pV, (i+1));
- if( op!=5 ){
- if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
- }
- }else{
- CLEARBIT(pV, (i+1));
- sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
- }
- }
-
- /* Test to make sure the linear array exactly matches the
- ** Bitvec object. Start with the assumption that they do
- ** match (rc==0). Change rc to non-zero if a discrepancy
- ** is found.
- */
- rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
- + sqlite3BitvecTest(pBitvec, 0)
- + (sqlite3BitvecSize(pBitvec) - sz);
- for(i=1; i<=sz; i++){
- if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
- rc = i;
- break;
- }
- }
-
- /* Free allocated structure */
-bitvec_end:
- sqlite3_free(pTmpSpace);
- sqlite3_free(pV);
- sqlite3BitvecDestroy(pBitvec);
- return rc;
-}
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
-
-/************** End of bitvec.c **********************************************/
-/************** Begin file pcache.c ******************************************/
-/*
-** 2008 August 05
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file implements that page cache.
-*/
-
-/*
-** A complete page cache is an instance of this structure.
-*/
-struct PCache {
- PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */
- PgHdr *pSynced; /* Last synced page in dirty page list */
- int nRef; /* Number of referenced pages */
- int szCache; /* Configured cache size */
- int szPage; /* Size of every page in this cache */
- int szExtra; /* Size of extra space for each page */
- int bPurgeable; /* True if pages are on backing store */
- int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */
- void *pStress; /* Argument to xStress */
- sqlite3_pcache *pCache; /* Pluggable cache module */
- PgHdr *pPage1; /* Reference to page 1 */
-};
-
-/*
-** Some of the assert() macros in this code are too expensive to run
-** even during normal debugging. Use them only rarely on long-running
-** tests. Enable the expensive asserts using the
-** -DSQLITE_ENABLE_EXPENSIVE_ASSERT=1 compile-time option.
-*/
-#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
-# define expensive_assert(X) assert(X)
-#else
-# define expensive_assert(X)
-#endif
-
-/********************************** Linked List Management ********************/
-
-#if !defined(NDEBUG) && defined(SQLITE_ENABLE_EXPENSIVE_ASSERT)
-/*
-** Check that the pCache->pSynced variable is set correctly. If it
-** is not, either fail an assert or return zero. Otherwise, return
-** non-zero. This is only used in debugging builds, as follows:
-**
-** expensive_assert( pcacheCheckSynced(pCache) );
-*/
-static int pcacheCheckSynced(PCache *pCache){
- PgHdr *p;
- for(p=pCache->pDirtyTail; p!=pCache->pSynced; p=p->pDirtyPrev){
- assert( p->nRef || (p->flags&PGHDR_NEED_SYNC) );
- }
- return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0);
-}
-#endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */
-
-/*
-** Remove page pPage from the list of dirty pages.
-*/
-static void pcacheRemoveFromDirtyList(PgHdr *pPage){
- PCache *p = pPage->pCache;
-
- assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
- assert( pPage->pDirtyPrev || pPage==p->pDirty );
-
- /* Update the PCache1.pSynced variable if necessary. */
- if( p->pSynced==pPage ){
- PgHdr *pSynced = pPage->pDirtyPrev;
- while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
- pSynced = pSynced->pDirtyPrev;
- }
- p->pSynced = pSynced;
- }
-
- if( pPage->pDirtyNext ){
- pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
- }else{
- assert( pPage==p->pDirtyTail );
- p->pDirtyTail = pPage->pDirtyPrev;
- }
- if( pPage->pDirtyPrev ){
- pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
- }else{
- assert( pPage==p->pDirty );
- p->pDirty = pPage->pDirtyNext;
- }
- pPage->pDirtyNext = 0;
- pPage->pDirtyPrev = 0;
-
- expensive_assert( pcacheCheckSynced(p) );
-}
-
-/*
-** Add page pPage to the head of the dirty list (PCache1.pDirty is set to
-** pPage).
-*/
-static void pcacheAddToDirtyList(PgHdr *pPage){
- PCache *p = pPage->pCache;
-
- assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
-
- pPage->pDirtyNext = p->pDirty;
- if( pPage->pDirtyNext ){
- assert( pPage->pDirtyNext->pDirtyPrev==0 );
- pPage->pDirtyNext->pDirtyPrev = pPage;
- }
- p->pDirty = pPage;
- if( !p->pDirtyTail ){
- p->pDirtyTail = pPage;
- }
- if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
- p->pSynced = pPage;
- }
- expensive_assert( pcacheCheckSynced(p) );
-}
-
-/*
-** Wrapper around the pluggable caches xUnpin method. If the cache is
-** being used for an in-memory database, this function is a no-op.
-*/
-static void pcacheUnpin(PgHdr *p){
- PCache *pCache = p->pCache;
- if( pCache->bPurgeable ){
- if( p->pgno==1 ){
- pCache->pPage1 = 0;
- }
- sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0);
- }
-}
-
-/*************************************************** General Interfaces ******
-**
-** Initialize and shutdown the page cache subsystem. Neither of these
-** functions are threadsafe.
-*/
-SQLITE_PRIVATE int sqlite3PcacheInitialize(void){
- if( sqlite3GlobalConfig.pcache2.xInit==0 ){
- /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
- ** built-in default page cache is used instead of the application defined
- ** page cache. */
- sqlite3PCacheSetDefault();
- }
- return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
-}
-SQLITE_PRIVATE void sqlite3PcacheShutdown(void){
- if( sqlite3GlobalConfig.pcache2.xShutdown ){
- /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
- sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg);
- }
-}
-
-/*
-** Return the size in bytes of a PCache object.
-*/
-SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
-
-/*
-** Create a new PCache object. Storage space to hold the object
-** has already been allocated and is passed in as the p pointer.
-** The caller discovers how much space needs to be allocated by
-** calling sqlite3PcacheSize().
-*/
-SQLITE_PRIVATE void sqlite3PcacheOpen(
- int szPage, /* Size of every page */
- int szExtra, /* Extra space associated with each page */
- int bPurgeable, /* True if pages are on backing store */
- int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */
- void *pStress, /* Argument to xStress */
- PCache *p /* Preallocated space for the PCache */
-){
- memset(p, 0, sizeof(PCache));
- p->szPage = szPage;
- p->szExtra = szExtra;
- p->bPurgeable = bPurgeable;
- p->xStress = xStress;
- p->pStress = pStress;
- p->szCache = 100;
-}
-
-/*
-** Change the page size for PCache object. The caller must ensure that there
-** are no outstanding page references when this function is called.
-*/
-SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
- assert( pCache->nRef==0 && pCache->pDirty==0 );
- if( pCache->pCache ){
- sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
- pCache->pCache = 0;
- pCache->pPage1 = 0;
- }
- pCache->szPage = szPage;
-}
-
-/*
-** Compute the number of pages of cache requested.
-*/
-static int numberOfCachePages(PCache *p){
- if( p->szCache>=0 ){
- return p->szCache;
- }else{
- return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
- }
-}
-
-/*
-** Try to obtain a page from the cache.
-*/
-SQLITE_PRIVATE int sqlite3PcacheFetch(
- PCache *pCache, /* Obtain the page from this cache */
- Pgno pgno, /* Page number to obtain */
- int createFlag, /* If true, create page if it does not exist already */
- PgHdr **ppPage /* Write the page here */
-){
- sqlite3_pcache_page *pPage = 0;
- PgHdr *pPgHdr = 0;
- int eCreate;
-
- assert( pCache!=0 );
- assert( createFlag==1 || createFlag==0 );
- assert( pgno>0 );
-
- /* If the pluggable cache (sqlite3_pcache*) has not been allocated,
- ** allocate it now.
- */
- if( !pCache->pCache && createFlag ){
- sqlite3_pcache *p;
- p = sqlite3GlobalConfig.pcache2.xCreate(
- pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
- );
- if( !p ){
- return SQLITE_NOMEM;
- }
- sqlite3GlobalConfig.pcache2.xCachesize(p, numberOfCachePages(pCache));
- pCache->pCache = p;
- }
-
- eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty));
- if( pCache->pCache ){
- pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
- }
-
- if( !pPage && eCreate==1 ){
- PgHdr *pPg;
-
- /* Find a dirty page to write-out and recycle. First try to find a
- ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
- ** cleared), but if that is not possible settle for any other
- ** unreferenced dirty page.
- */
- expensive_assert( pcacheCheckSynced(pCache) );
- for(pPg=pCache->pSynced;
- pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC));
- pPg=pPg->pDirtyPrev
- );
- pCache->pSynced = pPg;
- if( !pPg ){
- for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
- }
- if( pPg ){
- int rc;
-#ifdef SQLITE_LOG_CACHE_SPILL
- sqlite3_log(SQLITE_FULL,
- "spill page %d making room for %d - cache used: %d/%d",
- pPg->pgno, pgno,
- sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
- numberOfCachePages(pCache));
-#endif
- rc = pCache->xStress(pCache->pStress, pPg);
- if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
- return rc;
- }
- }
-
- pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
- }
-
- if( pPage ){
- pPgHdr = (PgHdr *)pPage->pExtra;
-
- if( !pPgHdr->pPage ){
- memset(pPgHdr, 0, sizeof(PgHdr));
- pPgHdr->pPage = pPage;
- pPgHdr->pData = pPage->pBuf;
- pPgHdr->pExtra = (void *)&pPgHdr[1];
- memset(pPgHdr->pExtra, 0, pCache->szExtra);
- pPgHdr->pCache = pCache;
- pPgHdr->pgno = pgno;
- }
- assert( pPgHdr->pCache==pCache );
- assert( pPgHdr->pgno==pgno );
- assert( pPgHdr->pData==pPage->pBuf );
- assert( pPgHdr->pExtra==(void *)&pPgHdr[1] );
-
- if( 0==pPgHdr->nRef ){
- pCache->nRef++;
- }
- pPgHdr->nRef++;
- if( pgno==1 ){
- pCache->pPage1 = pPgHdr;
- }
- }
- *ppPage = pPgHdr;
- return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
-}
-
-/*
-** Decrement the reference count on a page. If the page is clean and the
-** reference count drops to 0, then it is made elible for recycling.
-*/
-SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr *p){
- assert( p->nRef>0 );
- p->nRef--;
- if( p->nRef==0 ){
- PCache *pCache = p->pCache;
- pCache->nRef--;
- if( (p->flags&PGHDR_DIRTY)==0 ){
- pcacheUnpin(p);
- }else{
- /* Move the page to the head of the dirty list. */
- pcacheRemoveFromDirtyList(p);
- pcacheAddToDirtyList(p);
- }
- }
-}
-
-/*
-** Increase the reference count of a supplied page by 1.
-*/
-SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
- assert(p->nRef>0);
- p->nRef++;
-}
-
-/*
-** Drop a page from the cache. There must be exactly one reference to the
-** page. This function deletes that reference, so after it returns the
-** page pointed to by p is invalid.
-*/
-SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
- PCache *pCache;
- assert( p->nRef==1 );
- if( p->flags&PGHDR_DIRTY ){
- pcacheRemoveFromDirtyList(p);
- }
- pCache = p->pCache;
- pCache->nRef--;
- if( p->pgno==1 ){
- pCache->pPage1 = 0;
- }
- sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1);
-}
-
-/*
-** Make sure the page is marked as dirty. If it isn't dirty already,
-** make it so.
-*/
-SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
- p->flags &= ~PGHDR_DONT_WRITE;
- assert( p->nRef>0 );
- if( 0==(p->flags & PGHDR_DIRTY) ){
- p->flags |= PGHDR_DIRTY;
- pcacheAddToDirtyList( p);
- }
-}
-
-/*
-** Make sure the page is marked as clean. If it isn't clean already,
-** make it so.
-*/
-SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
- if( (p->flags & PGHDR_DIRTY) ){
- pcacheRemoveFromDirtyList(p);
- p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
- if( p->nRef==0 ){
- pcacheUnpin(p);
- }
- }
-}
-
-/*
-** Make every page in the cache clean.
-*/
-SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
- PgHdr *p;
- while( (p = pCache->pDirty)!=0 ){
- sqlite3PcacheMakeClean(p);
- }
-}
-
-/*
-** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
-*/
-SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){
- PgHdr *p;
- for(p=pCache->pDirty; p; p=p->pDirtyNext){
- p->flags &= ~PGHDR_NEED_SYNC;
- }
- pCache->pSynced = pCache->pDirtyTail;
-}
-
-/*
-** Change the page number of page p to newPgno.
-*/
-SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
- PCache *pCache = p->pCache;
- assert( p->nRef>0 );
- assert( newPgno>0 );
- sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
- p->pgno = newPgno;
- if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
- pcacheRemoveFromDirtyList(p);
- pcacheAddToDirtyList(p);
- }
-}
-
-/*
-** Drop every cache entry whose page number is greater than "pgno". The
-** caller must ensure that there are no outstanding references to any pages
-** other than page 1 with a page number greater than pgno.
-**
-** If there is a reference to page 1 and the pgno parameter passed to this
-** function is 0, then the data area associated with page 1 is zeroed, but
-** the page object is not dropped.
-*/
-SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
- if( pCache->pCache ){
- PgHdr *p;
- PgHdr *pNext;
- for(p=pCache->pDirty; p; p=pNext){
- pNext = p->pDirtyNext;
- /* This routine never gets call with a positive pgno except right
- ** after sqlite3PcacheCleanAll(). So if there are dirty pages,
- ** it must be that pgno==0.
- */
- assert( p->pgno>0 );
- if( ALWAYS(p->pgno>pgno) ){
- assert( p->flags&PGHDR_DIRTY );
- sqlite3PcacheMakeClean(p);
- }
- }
- if( pgno==0 && pCache->pPage1 ){
- memset(pCache->pPage1->pData, 0, pCache->szPage);
- pgno = 1;
- }
- sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
- }
-}
-
-/*
-** Close a cache.
-*/
-SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
- if( pCache->pCache ){
- sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
- }
-}
-
-/*
-** Discard the contents of the cache.
-*/
-SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
- sqlite3PcacheTruncate(pCache, 0);
-}
-
-/*
-** Merge two lists of pages connected by pDirty and in pgno order.
-** Do not both fixing the pDirtyPrev pointers.
-*/
-static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
- PgHdr result, *pTail;
- pTail = &result;
- while( pA && pB ){
- if( pA->pgno<pB->pgno ){
- pTail->pDirty = pA;
- pTail = pA;
- pA = pA->pDirty;
- }else{
- pTail->pDirty = pB;
- pTail = pB;
- pB = pB->pDirty;
- }
- }
- if( pA ){
- pTail->pDirty = pA;
- }else if( pB ){
- pTail->pDirty = pB;
- }else{
- pTail->pDirty = 0;
- }
- return result.pDirty;
-}
-
-/*
-** Sort the list of pages in accending order by pgno. Pages are
-** connected by pDirty pointers. The pDirtyPrev pointers are
-** corrupted by this sort.
-**
-** Since there cannot be more than 2^31 distinct pages in a database,
-** there cannot be more than 31 buckets required by the merge sorter.
-** One extra bucket is added to catch overflow in case something
-** ever changes to make the previous sentence incorrect.
-*/
-#define N_SORT_BUCKET 32
-static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
- PgHdr *a[N_SORT_BUCKET], *p;
- int i;
- memset(a, 0, sizeof(a));
- while( pIn ){
- p = pIn;
- pIn = p->pDirty;
- p->pDirty = 0;
- for(i=0; ALWAYS(i<N_SORT_BUCKET-1); i++){
- if( a[i]==0 ){
- a[i] = p;
- break;
- }else{
- p = pcacheMergeDirtyList(a[i], p);
- a[i] = 0;
- }
- }
- if( NEVER(i==N_SORT_BUCKET-1) ){
- /* To get here, there need to be 2^(N_SORT_BUCKET) elements in
- ** the input list. But that is impossible.
- */
- a[i] = pcacheMergeDirtyList(a[i], p);
- }
- }
- p = a[0];
- for(i=1; i<N_SORT_BUCKET; i++){
- p = pcacheMergeDirtyList(p, a[i]);
- }
- return p;
-}
-
-/*
-** Return a list of all dirty pages in the cache, sorted by page number.
-*/
-SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
- PgHdr *p;
- for(p=pCache->pDirty; p; p=p->pDirtyNext){
- p->pDirty = p->pDirtyNext;
- }
- return pcacheSortDirtyList(pCache->pDirty);
-}
-
-/*
-** Return the total number of referenced pages held by the cache.
-*/
-SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
- return pCache->nRef;
-}
-
-/*
-** Return the number of references to the page supplied as an argument.
-*/
-SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
- return p->nRef;
-}
-
-/*
-** Return the total number of pages in the cache.
-*/
-SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){
- int nPage = 0;
- if( pCache->pCache ){
- nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
- }
- return nPage;
-}
-
-#ifdef SQLITE_TEST
-/*
-** Get the suggested cache-size value.
-*/
-SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
- return numberOfCachePages(pCache);
-}
-#endif
-
-/*
-** Set the suggested cache-size value.
-*/
-SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
- pCache->szCache = mxPage;
- if( pCache->pCache ){
- sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
- numberOfCachePages(pCache));
- }
-}
-
-/*
-** Free up as much memory as possible from the page cache.
-*/
-SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
- if( pCache->pCache ){
- sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
- }
-}
-
-#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
-/*
-** For all dirty pages currently in the cache, invoke the specified
-** callback. This is only used if the SQLITE_CHECK_PAGES macro is
-** defined.
-*/
-SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){
- PgHdr *pDirty;
- for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){
- xIter(pDirty);
- }
-}
-#endif
-
-/************** End of pcache.c **********************************************/
-/************** Begin file pcache1.c *****************************************/
-/*
-** 2008 November 05
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file implements the default page cache implementation (the
-** sqlite3_pcache interface). It also contains part of the implementation
-** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
-** If the default page cache implementation is overriden, then neither of
-** these two features are available.
-*/
-
-
-typedef struct PCache1 PCache1;
-typedef struct PgHdr1 PgHdr1;
-typedef struct PgFreeslot PgFreeslot;
-typedef struct PGroup PGroup;
-
-/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
-** of one or more PCaches that are able to recycle each others unpinned
-** pages when they are under memory pressure. A PGroup is an instance of
-** the following object.
-**
-** This page cache implementation works in one of two modes:
-**
-** (1) Every PCache is the sole member of its own PGroup. There is
-** one PGroup per PCache.
-**
-** (2) There is a single global PGroup that all PCaches are a member
-** of.
-**
-** Mode 1 uses more memory (since PCache instances are not able to rob
-** unused pages from other PCaches) but it also operates without a mutex,
-** and is therefore often faster. Mode 2 requires a mutex in order to be
-** threadsafe, but recycles pages more efficiently.
-**
-** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single
-** PGroup which is the pcache1.grp global variable and its mutex is
-** SQLITE_MUTEX_STATIC_LRU.
-*/
-struct PGroup {
- sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */
- unsigned int nMaxPage; /* Sum of nMax for purgeable caches */
- unsigned int nMinPage; /* Sum of nMin for purgeable caches */
- unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */
- unsigned int nCurrentPage; /* Number of purgeable pages allocated */
- PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */
-};
-
-/* Each page cache is an instance of the following object. Every
-** open database file (including each in-memory database and each
-** temporary or transient database) has a single page cache which
-** is an instance of this object.
-**
-** Pointers to structures of this type are cast and returned as
-** opaque sqlite3_pcache* handles.
-*/
-struct PCache1 {
- /* Cache configuration parameters. Page size (szPage) and the purgeable
- ** flag (bPurgeable) are set when the cache is created. nMax may be
- ** modified at any time by a call to the pcache1Cachesize() method.
- ** The PGroup mutex must be held when accessing nMax.
- */
- PGroup *pGroup; /* PGroup this cache belongs to */
- int szPage; /* Size of allocated pages in bytes */
- int szExtra; /* Size of extra space in bytes */
- int bPurgeable; /* True if cache is purgeable */
- unsigned int nMin; /* Minimum number of pages reserved */
- unsigned int nMax; /* Configured "cache_size" value */
- unsigned int n90pct; /* nMax*9/10 */
- unsigned int iMaxKey; /* Largest key seen since xTruncate() */
-
- /* Hash table of all pages. The following variables may only be accessed
- ** when the accessor is holding the PGroup mutex.
- */
- unsigned int nRecyclable; /* Number of pages in the LRU list */
- unsigned int nPage; /* Total number of pages in apHash */
- unsigned int nHash; /* Number of slots in apHash[] */
- PgHdr1 **apHash; /* Hash table for fast lookup by key */
-};
-
-/*
-** Each cache entry is represented by an instance of the following
-** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
-** PgHdr1.pCache->szPage bytes is allocated directly before this structure
-** in memory.
-*/
-struct PgHdr1 {
- sqlite3_pcache_page page;
- unsigned int iKey; /* Key value (page number) */
- PgHdr1 *pNext; /* Next in hash table chain */
- PCache1 *pCache; /* Cache that currently owns this page */
- PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
- PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
-};
-
-/*
-** Free slots in the allocator used to divide up the buffer provided using
-** the SQLITE_CONFIG_PAGECACHE mechanism.
-*/
-struct PgFreeslot {
- PgFreeslot *pNext; /* Next free slot */
-};
-
-/*
-** Global data used by this cache.
-*/
-static SQLITE_WSD struct PCacheGlobal {
- PGroup grp; /* The global PGroup for mode (2) */
-
- /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The
- ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all
- ** fixed at sqlite3_initialize() time and do not require mutex protection.
- ** The nFreeSlot and pFree values do require mutex protection.
- */
- int isInit; /* True if initialized */
- int szSlot; /* Size of each free slot */
- int nSlot; /* The number of pcache slots */
- int nReserve; /* Try to keep nFreeSlot above this */
- void *pStart, *pEnd; /* Bounds of pagecache malloc range */
- /* Above requires no mutex. Use mutex below for variable that follow. */
- sqlite3_mutex *mutex; /* Mutex for accessing the following: */
- PgFreeslot *pFree; /* Free page blocks */
- int nFreeSlot; /* Number of unused pcache slots */
- /* The following value requires a mutex to change. We skip the mutex on
- ** reading because (1) most platforms read a 32-bit integer atomically and
- ** (2) even if an incorrect value is read, no great harm is done since this
- ** is really just an optimization. */
- int bUnderPressure; /* True if low on PAGECACHE memory */
-} pcache1_g;
-
-/*
-** All code in this file should access the global structure above via the
-** alias "pcache1". This ensures that the WSD emulation is used when
-** compiling for systems that do not support real WSD.
-*/
-#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
-
-/*
-** Macros to enter and leave the PCache LRU mutex.
-*/
-#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
-#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
-
-/******************************************************************************/
-/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
-
-/*
-** This function is called during initialization if a static buffer is
-** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
-** verb to sqlite3_config(). Parameter pBuf points to an allocation large
-** enough to contain 'n' buffers of 'sz' bytes each.
-**
-** This routine is called from sqlite3_initialize() and so it is guaranteed
-** to be serialized already. There is no need for further mutexing.
-*/
-SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
- if( pcache1.isInit ){
- PgFreeslot *p;
- sz = ROUNDDOWN8(sz);
- pcache1.szSlot = sz;
- pcache1.nSlot = pcache1.nFreeSlot = n;
- pcache1.nReserve = n>90 ? 10 : (n/10 + 1);
- pcache1.pStart = pBuf;
- pcache1.pFree = 0;
- pcache1.bUnderPressure = 0;
- while( n-- ){
- p = (PgFreeslot*)pBuf;
- p->pNext = pcache1.pFree;
- pcache1.pFree = p;
- pBuf = (void*)&((char*)pBuf)[sz];
- }
- pcache1.pEnd = pBuf;
- }
-}
-
-/*
-** Malloc function used within this file to allocate space from the buffer
-** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no
-** such buffer exists or there is no space left in it, this function falls
-** back to sqlite3Malloc().
-**
-** Multiple threads can run this routine at the same time. Global variables
-** in pcache1 need to be protected via mutex.
-*/
-static void *pcache1Alloc(int nByte){
- void *p = 0;
- assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
- sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
- if( nByte<=pcache1.szSlot ){
- sqlite3_mutex_enter(pcache1.mutex);
- p = (PgHdr1 *)pcache1.pFree;
- if( p ){
- pcache1.pFree = pcache1.pFree->pNext;
- pcache1.nFreeSlot--;
- pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
- assert( pcache1.nFreeSlot>=0 );
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
- }
- sqlite3_mutex_leave(pcache1.mutex);
- }
- if( p==0 ){
- /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get
- ** it from sqlite3Malloc instead.
- */
- p = sqlite3Malloc(nByte);
-#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
- if( p ){
- int sz = sqlite3MallocSize(p);
- sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
- sqlite3_mutex_leave(pcache1.mutex);
- }
-#endif
- sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
- }
- return p;
-}
-
-/*
-** Free an allocated buffer obtained from pcache1Alloc().
-*/
-static int pcache1Free(void *p){
- int nFreed = 0;
- if( p==0 ) return 0;
- if( p>=pcache1.pStart && p<pcache1.pEnd ){
- PgFreeslot *pSlot;
- sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
- pSlot = (PgFreeslot*)p;
- pSlot->pNext = pcache1.pFree;
- pcache1.pFree = pSlot;
- pcache1.nFreeSlot++;
- pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
- assert( pcache1.nFreeSlot<=pcache1.nSlot );
- sqlite3_mutex_leave(pcache1.mutex);
- }else{
- assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
- sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- nFreed = sqlite3MallocSize(p);
-#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
- sqlite3_mutex_enter(pcache1.mutex);
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
- sqlite3_mutex_leave(pcache1.mutex);
-#endif
- sqlite3_free(p);
- }
- return nFreed;
-}
-
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-/*
-** Return the size of a pcache allocation
-*/
-static int pcache1MemSize(void *p){
- if( p>=pcache1.pStart && p<pcache1.pEnd ){
- return pcache1.szSlot;
- }else{
- int iSize;
- assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
- sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- iSize = sqlite3MallocSize(p);
- sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
- return iSize;
- }
-}
-#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
-
-/*
-** Allocate a new page object initially associated with cache pCache.
-*/
-static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
- PgHdr1 *p = 0;
- void *pPg;
-
- /* The group mutex must be released before pcache1Alloc() is called. This
- ** is because it may call sqlite3_release_memory(), which assumes that
- ** this mutex is not held. */
- assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
- pcache1LeaveMutex(pCache->pGroup);
-#ifdef SQLITE_PCACHE_SEPARATE_HEADER
- pPg = pcache1Alloc(pCache->szPage);
- p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
- if( !pPg || !p ){
- pcache1Free(pPg);
- sqlite3_free(p);
- pPg = 0;
- }
-#else
- pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra);
- p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
-#endif
- pcache1EnterMutex(pCache->pGroup);
-
- if( pPg ){
- p->page.pBuf = pPg;
- p->page.pExtra = &p[1];
- if( pCache->bPurgeable ){
- pCache->pGroup->nCurrentPage++;
- }
- return p;
- }
- return 0;
-}
-
-/*
-** Free a page object allocated by pcache1AllocPage().
-**
-** The pointer is allowed to be NULL, which is prudent. But it turns out
-** that the current implementation happens to never call this routine
-** with a NULL pointer, so we mark the NULL test with ALWAYS().
-*/
-static void pcache1FreePage(PgHdr1 *p){
- if( ALWAYS(p) ){
- PCache1 *pCache = p->pCache;
- assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
- pcache1Free(p->page.pBuf);
-#ifdef SQLITE_PCACHE_SEPARATE_HEADER
- sqlite3_free(p);
-#endif
- if( pCache->bPurgeable ){
- pCache->pGroup->nCurrentPage--;
- }
- }
-}
-
-/*
-** Malloc function used by SQLite to obtain space from the buffer configured
-** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
-** exists, this function falls back to sqlite3Malloc().
-*/
-SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
- return pcache1Alloc(sz);
-}
-
-/*
-** Free an allocated buffer obtained from sqlite3PageMalloc().
-*/
-SQLITE_PRIVATE void sqlite3PageFree(void *p){
- pcache1Free(p);
-}
-
-
-/*
-** Return true if it desirable to avoid allocating a new page cache
-** entry.
-**
-** If memory was allocated specifically to the page cache using
-** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then
-** it is desirable to avoid allocating a new page cache entry because
-** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient
-** for all page cache needs and we should not need to spill the
-** allocation onto the heap.
-**
-** Or, the heap is used for all page cache memory but the heap is
-** under memory pressure, then again it is desirable to avoid
-** allocating a new page cache entry in order to avoid stressing
-** the heap even further.
-*/
-static int pcache1UnderMemoryPressure(PCache1 *pCache){
- if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
- return pcache1.bUnderPressure;
- }else{
- return sqlite3HeapNearlyFull();
- }
-}
-
-/******************************************************************************/
-/******** General Implementation Functions ************************************/
-
-/*
-** This function is used to resize the hash table used by the cache passed
-** as the first argument.
-**
-** The PCache mutex must be held when this function is called.
-*/
-static int pcache1ResizeHash(PCache1 *p){
- PgHdr1 **apNew;
- unsigned int nNew;
- unsigned int i;
-
- assert( sqlite3_mutex_held(p->pGroup->mutex) );
-
- nNew = p->nHash*2;
- if( nNew<256 ){
- nNew = 256;
- }
-
- pcache1LeaveMutex(p->pGroup);
- if( p->nHash ){ sqlite3BeginBenignMalloc(); }
- apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
- if( p->nHash ){ sqlite3EndBenignMalloc(); }
- pcache1EnterMutex(p->pGroup);
- if( apNew ){
- for(i=0; i<p->nHash; i++){
- PgHdr1 *pPage;
- PgHdr1 *pNext = p->apHash[i];
- while( (pPage = pNext)!=0 ){
- unsigned int h = pPage->iKey % nNew;
- pNext = pPage->pNext;
- pPage->pNext = apNew[h];
- apNew[h] = pPage;
- }
- }
- sqlite3_free(p->apHash);
- p->apHash = apNew;
- p->nHash = nNew;
- }
-
- return (p->apHash ? SQLITE_OK : SQLITE_NOMEM);
-}
-
-/*
-** This function is used internally to remove the page pPage from the
-** PGroup LRU list, if is part of it. If pPage is not part of the PGroup
-** LRU list, then this function is a no-op.
-**
-** The PGroup mutex must be held when this function is called.
-**
-** If pPage is NULL then this routine is a no-op.
-*/
-static void pcache1PinPage(PgHdr1 *pPage){
- PCache1 *pCache;
- PGroup *pGroup;
-
- if( pPage==0 ) return;
- pCache = pPage->pCache;
- pGroup = pCache->pGroup;
- assert( sqlite3_mutex_held(pGroup->mutex) );
- if( pPage->pLruNext || pPage==pGroup->pLruTail ){
- if( pPage->pLruPrev ){
- pPage->pLruPrev->pLruNext = pPage->pLruNext;
- }
- if( pPage->pLruNext ){
- pPage->pLruNext->pLruPrev = pPage->pLruPrev;
- }
- if( pGroup->pLruHead==pPage ){
- pGroup->pLruHead = pPage->pLruNext;
- }
- if( pGroup->pLruTail==pPage ){
- pGroup->pLruTail = pPage->pLruPrev;
- }
- pPage->pLruNext = 0;
- pPage->pLruPrev = 0;
- pPage->pCache->nRecyclable--;
- }
-}
-
-
-/*
-** Remove the page supplied as an argument from the hash table
-** (PCache1.apHash structure) that it is currently stored in.
-**
-** The PGroup mutex must be held when this function is called.
-*/
-static void pcache1RemoveFromHash(PgHdr1 *pPage){
- unsigned int h;
- PCache1 *pCache = pPage->pCache;
- PgHdr1 **pp;
-
- assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
- h = pPage->iKey % pCache->nHash;
- for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext);
- *pp = (*pp)->pNext;
-
- pCache->nPage--;
-}
-
-/*
-** If there are currently more than nMaxPage pages allocated, try
-** to recycle pages to reduce the number allocated to nMaxPage.
-*/
-static void pcache1EnforceMaxPage(PGroup *pGroup){
- assert( sqlite3_mutex_held(pGroup->mutex) );
- while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
- PgHdr1 *p = pGroup->pLruTail;
- assert( p->pCache->pGroup==pGroup );
- pcache1PinPage(p);
- pcache1RemoveFromHash(p);
- pcache1FreePage(p);
- }
-}
-
-/*
-** Discard all pages from cache pCache with a page number (key value)
-** greater than or equal to iLimit. Any pinned pages that meet this
-** criteria are unpinned before they are discarded.
-**
-** The PCache mutex must be held when this function is called.
-*/
-static void pcache1TruncateUnsafe(
- PCache1 *pCache, /* The cache to truncate */
- unsigned int iLimit /* Drop pages with this pgno or larger */
-){
- TESTONLY( unsigned int nPage = 0; ) /* To assert pCache->nPage is correct */
- unsigned int h;
- assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
- for(h=0; h<pCache->nHash; h++){
- PgHdr1 **pp = &pCache->apHash[h];
- PgHdr1 *pPage;
- while( (pPage = *pp)!=0 ){
- if( pPage->iKey>=iLimit ){
- pCache->nPage--;
- *pp = pPage->pNext;
- pcache1PinPage(pPage);
- pcache1FreePage(pPage);
- }else{
- pp = &pPage->pNext;
- TESTONLY( nPage++; )
- }
- }
- }
- assert( pCache->nPage==nPage );
-}
-
-/******************************************************************************/
-/******** sqlite3_pcache Methods **********************************************/
-
-/*
-** Implementation of the sqlite3_pcache.xInit method.
-*/
-static int pcache1Init(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- assert( pcache1.isInit==0 );
- memset(&pcache1, 0, sizeof(pcache1));
- if( sqlite3GlobalConfig.bCoreMutex ){
- pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
- pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
- }
- pcache1.grp.mxPinned = 10;
- pcache1.isInit = 1;
- return SQLITE_OK;
-}
-
-/*
-** Implementation of the sqlite3_pcache.xShutdown method.
-** Note that the static mutex allocated in xInit does
-** not need to be freed.
-*/
-static void pcache1Shutdown(void *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- assert( pcache1.isInit!=0 );
- memset(&pcache1, 0, sizeof(pcache1));
-}
-
-/*
-** Implementation of the sqlite3_pcache.xCreate method.
-**
-** Allocate a new cache.
-*/
-static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
- PCache1 *pCache; /* The newly created page cache */
- PGroup *pGroup; /* The group the new page cache will belong to */
- int sz; /* Bytes of memory required to allocate the new cache */
-
- /*
- ** The seperateCache variable is true if each PCache has its own private
- ** PGroup. In other words, separateCache is true for mode (1) where no
- ** mutexing is required.
- **
- ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
- **
- ** * Always use a unified cache in single-threaded applications
- **
- ** * Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
- ** use separate caches (mode-1)
- */
-#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
- const int separateCache = 0;
-#else
- int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
-#endif
-
- assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
- assert( szExtra < 300 );
-
- sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
- pCache = (PCache1 *)sqlite3MallocZero(sz);
- if( pCache ){
- if( separateCache ){
- pGroup = (PGroup*)&pCache[1];
- pGroup->mxPinned = 10;
- }else{
- pGroup = &pcache1.grp;
- }
- pCache->pGroup = pGroup;
- pCache->szPage = szPage;
- pCache->szExtra = szExtra;
- pCache->bPurgeable = (bPurgeable ? 1 : 0);
- if( bPurgeable ){
- pCache->nMin = 10;
- pcache1EnterMutex(pGroup);
- pGroup->nMinPage += pCache->nMin;
- pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
- pcache1LeaveMutex(pGroup);
- }
- }
- return (sqlite3_pcache *)pCache;
-}
-
-/*
-** Implementation of the sqlite3_pcache.xCachesize method.
-**
-** Configure the cache_size limit for a cache.
-*/
-static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
- PCache1 *pCache = (PCache1 *)p;
- if( pCache->bPurgeable ){
- PGroup *pGroup = pCache->pGroup;
- pcache1EnterMutex(pGroup);
- pGroup->nMaxPage += (nMax - pCache->nMax);
- pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
- pCache->nMax = nMax;
- pCache->n90pct = pCache->nMax*9/10;
- pcache1EnforceMaxPage(pGroup);
- pcache1LeaveMutex(pGroup);
- }
-}
-
-/*
-** Implementation of the sqlite3_pcache.xShrink method.
-**
-** Free up as much memory as possible.
-*/
-static void pcache1Shrink(sqlite3_pcache *p){
- PCache1 *pCache = (PCache1*)p;
- if( pCache->bPurgeable ){
- PGroup *pGroup = pCache->pGroup;
- int savedMaxPage;
- pcache1EnterMutex(pGroup);
- savedMaxPage = pGroup->nMaxPage;
- pGroup->nMaxPage = 0;
- pcache1EnforceMaxPage(pGroup);
- pGroup->nMaxPage = savedMaxPage;
- pcache1LeaveMutex(pGroup);
- }
-}
-
-/*
-** Implementation of the sqlite3_pcache.xPagecount method.
-*/
-static int pcache1Pagecount(sqlite3_pcache *p){
- int n;
- PCache1 *pCache = (PCache1*)p;
- pcache1EnterMutex(pCache->pGroup);
- n = pCache->nPage;
- pcache1LeaveMutex(pCache->pGroup);
- return n;
-}
-
-/*
-** Implementation of the sqlite3_pcache.xFetch method.
-**
-** Fetch a page by key value.
-**
-** Whether or not a new page may be allocated by this function depends on
-** the value of the createFlag argument. 0 means do not allocate a new
-** page. 1 means allocate a new page if space is easily available. 2
-** means to try really hard to allocate a new page.
-**
-** For a non-purgeable cache (a cache used as the storage for an in-memory
-** database) there is really no difference between createFlag 1 and 2. So
-** the calling function (pcache.c) will never have a createFlag of 1 on
-** a non-purgeable cache.
-**
-** There are three different approaches to obtaining space for a page,
-** depending on the value of parameter createFlag (which may be 0, 1 or 2).
-**
-** 1. Regardless of the value of createFlag, the cache is searched for a
-** copy of the requested page. If one is found, it is returned.
-**
-** 2. If createFlag==0 and the page is not already in the cache, NULL is
-** returned.
-**
-** 3. If createFlag is 1, and the page is not already in the cache, then
-** return NULL (do not allocate a new page) if any of the following
-** conditions are true:
-**
-** (a) the number of pages pinned by the cache is greater than
-** PCache1.nMax, or
-**
-** (b) the number of pages pinned by the cache is greater than
-** the sum of nMax for all purgeable caches, less the sum of
-** nMin for all other purgeable caches, or
-**
-** 4. If none of the first three conditions apply and the cache is marked
-** as purgeable, and if one of the following is true:
-**
-** (a) The number of pages allocated for the cache is already
-** PCache1.nMax, or
-**
-** (b) The number of pages allocated for all purgeable caches is
-** already equal to or greater than the sum of nMax for all
-** purgeable caches,
-**
-** (c) The system is under memory pressure and wants to avoid
-** unnecessary pages cache entry allocations
-**
-** then attempt to recycle a page from the LRU list. If it is the right
-** size, return the recycled buffer. Otherwise, free the buffer and
-** proceed to step 5.
-**
-** 5. Otherwise, allocate and return a new page buffer.
-*/
-static sqlite3_pcache_page *pcache1Fetch(
- sqlite3_pcache *p,
- unsigned int iKey,
- int createFlag
-){
- unsigned int nPinned;
- PCache1 *pCache = (PCache1 *)p;
- PGroup *pGroup;
- PgHdr1 *pPage = 0;
-
- assert( pCache->bPurgeable || createFlag!=1 );
- assert( pCache->bPurgeable || pCache->nMin==0 );
- assert( pCache->bPurgeable==0 || pCache->nMin==10 );
- assert( pCache->nMin==0 || pCache->bPurgeable );
- pcache1EnterMutex(pGroup = pCache->pGroup);
-
- /* Step 1: Search the hash table for an existing entry. */
- if( pCache->nHash>0 ){
- unsigned int h = iKey % pCache->nHash;
- for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext);
- }
-
- /* Step 2: Abort if no existing page is found and createFlag is 0 */
- if( pPage || createFlag==0 ){
- pcache1PinPage(pPage);
- goto fetch_out;
- }
-
- /* The pGroup local variable will normally be initialized by the
- ** pcache1EnterMutex() macro above. But if SQLITE_MUTEX_OMIT is defined,
- ** then pcache1EnterMutex() is a no-op, so we have to initialize the
- ** local variable here. Delaying the initialization of pGroup is an
- ** optimization: The common case is to exit the module before reaching
- ** this point.
- */
-#ifdef SQLITE_MUTEX_OMIT
- pGroup = pCache->pGroup;
-#endif
-
- /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
- assert( pCache->nPage >= pCache->nRecyclable );
- nPinned = pCache->nPage - pCache->nRecyclable;
- assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
- assert( pCache->n90pct == pCache->nMax*9/10 );
- if( createFlag==1 && (
- nPinned>=pGroup->mxPinned
- || nPinned>=pCache->n90pct
- || pcache1UnderMemoryPressure(pCache)
- )){
- goto fetch_out;
- }
-
- if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
- goto fetch_out;
- }
-
- /* Step 4. Try to recycle a page. */
- if( pCache->bPurgeable && pGroup->pLruTail && (
- (pCache->nPage+1>=pCache->nMax)
- || pGroup->nCurrentPage>=pGroup->nMaxPage
- || pcache1UnderMemoryPressure(pCache)
- )){
- PCache1 *pOther;
- pPage = pGroup->pLruTail;
- pcache1RemoveFromHash(pPage);
- pcache1PinPage(pPage);
- pOther = pPage->pCache;
-
- /* We want to verify that szPage and szExtra are the same for pOther
- ** and pCache. Assert that we can verify this by comparing sums. */
- assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
- assert( pCache->szExtra<512 );
- assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
- assert( pOther->szExtra<512 );
-
- if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
- pcache1FreePage(pPage);
- pPage = 0;
- }else{
- pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
- }
- }
-
- /* Step 5. If a usable page buffer has still not been found,
- ** attempt to allocate a new one.
- */
- if( !pPage ){
- if( createFlag==1 ) sqlite3BeginBenignMalloc();
- pPage = pcache1AllocPage(pCache);
- if( createFlag==1 ) sqlite3EndBenignMalloc();
- }
-
- if( pPage ){
- unsigned int h = iKey % pCache->nHash;
- pCache->nPage++;
- pPage->iKey = iKey;
- pPage->pNext = pCache->apHash[h];
- pPage->pCache = pCache;
- pPage->pLruPrev = 0;
- pPage->pLruNext = 0;
- *(void **)pPage->page.pExtra = 0;
- pCache->apHash[h] = pPage;
- }
-
-fetch_out:
- if( pPage && iKey>pCache->iMaxKey ){
- pCache->iMaxKey = iKey;
- }
- pcache1LeaveMutex(pGroup);
- return &pPage->page;
-}
-
-
-/*
-** Implementation of the sqlite3_pcache.xUnpin method.
-**
-** Mark a page as unpinned (eligible for asynchronous recycling).
-*/
-static void pcache1Unpin(
- sqlite3_pcache *p,
- sqlite3_pcache_page *pPg,
- int reuseUnlikely
-){
- PCache1 *pCache = (PCache1 *)p;
- PgHdr1 *pPage = (PgHdr1 *)pPg;
- PGroup *pGroup = pCache->pGroup;
-
- assert( pPage->pCache==pCache );
- pcache1EnterMutex(pGroup);
-
- /* It is an error to call this function if the page is already
- ** part of the PGroup LRU list.
- */
- assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
- assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
-
- if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
- pcache1RemoveFromHash(pPage);
- pcache1FreePage(pPage);
- }else{
- /* Add the page to the PGroup LRU list. */
- if( pGroup->pLruHead ){
- pGroup->pLruHead->pLruPrev = pPage;
- pPage->pLruNext = pGroup->pLruHead;
- pGroup->pLruHead = pPage;
- }else{
- pGroup->pLruTail = pPage;
- pGroup->pLruHead = pPage;
- }
- pCache->nRecyclable++;
- }
-
- pcache1LeaveMutex(pCache->pGroup);
-}
-
-/*
-** Implementation of the sqlite3_pcache.xRekey method.
-*/
-static void pcache1Rekey(
- sqlite3_pcache *p,
- sqlite3_pcache_page *pPg,
- unsigned int iOld,
- unsigned int iNew
-){
- PCache1 *pCache = (PCache1 *)p;
- PgHdr1 *pPage = (PgHdr1 *)pPg;
- PgHdr1 **pp;
- unsigned int h;
- assert( pPage->iKey==iOld );
- assert( pPage->pCache==pCache );
-
- pcache1EnterMutex(pCache->pGroup);
-
- h = iOld%pCache->nHash;
- pp = &pCache->apHash[h];
- while( (*pp)!=pPage ){
- pp = &(*pp)->pNext;
- }
- *pp = pPage->pNext;
-
- h = iNew%pCache->nHash;
- pPage->iKey = iNew;
- pPage->pNext = pCache->apHash[h];
- pCache->apHash[h] = pPage;
- if( iNew>pCache->iMaxKey ){
- pCache->iMaxKey = iNew;
- }
-
- pcache1LeaveMutex(pCache->pGroup);
-}
-
-/*
-** Implementation of the sqlite3_pcache.xTruncate method.
-**
-** Discard all unpinned pages in the cache with a page number equal to
-** or greater than parameter iLimit. Any pinned pages with a page number
-** equal to or greater than iLimit are implicitly unpinned.
-*/
-static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){
- PCache1 *pCache = (PCache1 *)p;
- pcache1EnterMutex(pCache->pGroup);
- if( iLimit<=pCache->iMaxKey ){
- pcache1TruncateUnsafe(pCache, iLimit);
- pCache->iMaxKey = iLimit-1;
- }
- pcache1LeaveMutex(pCache->pGroup);
-}
-
-/*
-** Implementation of the sqlite3_pcache.xDestroy method.
-**
-** Destroy a cache allocated using pcache1Create().
-*/
-static void pcache1Destroy(sqlite3_pcache *p){
- PCache1 *pCache = (PCache1 *)p;
- PGroup *pGroup = pCache->pGroup;
- assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
- pcache1EnterMutex(pGroup);
- pcache1TruncateUnsafe(pCache, 0);
- assert( pGroup->nMaxPage >= pCache->nMax );
- pGroup->nMaxPage -= pCache->nMax;
- assert( pGroup->nMinPage >= pCache->nMin );
- pGroup->nMinPage -= pCache->nMin;
- pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
- pcache1EnforceMaxPage(pGroup);
- pcache1LeaveMutex(pGroup);
- sqlite3_free(pCache->apHash);
- sqlite3_free(pCache);
-}
-
-/*
-** This function is called during initialization (sqlite3_initialize()) to
-** install the default pluggable cache module, assuming the user has not
-** already provided an alternative.
-*/
-SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
- static const sqlite3_pcache_methods2 defaultMethods = {
- 1, /* iVersion */
- 0, /* pArg */
- pcache1Init, /* xInit */
- pcache1Shutdown, /* xShutdown */
- pcache1Create, /* xCreate */
- pcache1Cachesize, /* xCachesize */
- pcache1Pagecount, /* xPagecount */
- pcache1Fetch, /* xFetch */
- pcache1Unpin, /* xUnpin */
- pcache1Rekey, /* xRekey */
- pcache1Truncate, /* xTruncate */
- pcache1Destroy, /* xDestroy */
- pcache1Shrink /* xShrink */
- };
- sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
-}
-
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-/*
-** This function is called to free superfluous dynamically allocated memory
-** held by the pager system. Memory in use by any SQLite pager allocated
-** by the current thread may be sqlite3_free()ed.
-**
-** nReq is the number of bytes of memory required. Once this much has
-** been released, the function returns. The return value is the total number
-** of bytes of memory released.
-*/
-SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
- int nFree = 0;
- assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
- assert( sqlite3_mutex_notheld(pcache1.mutex) );
- if( pcache1.pStart==0 ){
- PgHdr1 *p;
- pcache1EnterMutex(&pcache1.grp);
- while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
- nFree += pcache1MemSize(p->page.pBuf);
-#ifdef SQLITE_PCACHE_SEPARATE_HEADER
- nFree += sqlite3MemSize(p);
-#endif
- pcache1PinPage(p);
- pcache1RemoveFromHash(p);
- pcache1FreePage(p);
- }
- pcache1LeaveMutex(&pcache1.grp);
- }
- return nFree;
-}
-#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
-
-#ifdef SQLITE_TEST
-/*
-** This function is used by test procedures to inspect the internal state
-** of the global cache.
-*/
-SQLITE_PRIVATE void sqlite3PcacheStats(
- int *pnCurrent, /* OUT: Total number of pages cached */
- int *pnMax, /* OUT: Global maximum cache size */
- int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */
- int *pnRecyclable /* OUT: Total number of pages available for recycling */
-){
- PgHdr1 *p;
- int nRecyclable = 0;
- for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
- nRecyclable++;
- }
- *pnCurrent = pcache1.grp.nCurrentPage;
- *pnMax = (int)pcache1.grp.nMaxPage;
- *pnMin = (int)pcache1.grp.nMinPage;
- *pnRecyclable = nRecyclable;
-}
-#endif
-
-/************** End of pcache1.c *********************************************/
-/************** Begin file rowset.c ******************************************/
-/*
-** 2008 December 3
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This module implements an object we call a "RowSet".
-**
-** The RowSet object is a collection of rowids. Rowids
-** are inserted into the RowSet in an arbitrary order. Inserts
-** can be intermixed with tests to see if a given rowid has been
-** previously inserted into the RowSet.
-**
-** After all inserts are finished, it is possible to extract the
-** elements of the RowSet in sorted order. Once this extraction
-** process has started, no new elements may be inserted.
-**
-** Hence, the primitive operations for a RowSet are:
-**
-** CREATE
-** INSERT
-** TEST
-** SMALLEST
-** DESTROY
-**
-** The CREATE and DESTROY primitives are the constructor and destructor,
-** obviously. The INSERT primitive adds a new element to the RowSet.
-** TEST checks to see if an element is already in the RowSet. SMALLEST
-** extracts the least value from the RowSet.
-**
-** The INSERT primitive might allocate additional memory. Memory is
-** allocated in chunks so most INSERTs do no allocation. There is an
-** upper bound on the size of allocated memory. No memory is freed
-** until DESTROY.
-**
-** The TEST primitive includes a "batch" number. The TEST primitive
-** will only see elements that were inserted before the last change
-** in the batch number. In other words, if an INSERT occurs between
-** two TESTs where the TESTs have the same batch nubmer, then the
-** value added by the INSERT will not be visible to the second TEST.
-** The initial batch number is zero, so if the very first TEST contains
-** a non-zero batch number, it will see all prior INSERTs.
-**
-** No INSERTs may occurs after a SMALLEST. An assertion will fail if
-** that is attempted.
-**
-** The cost of an INSERT is roughly constant. (Sometime new memory
-** has to be allocated on an INSERT.) The cost of a TEST with a new
-** batch number is O(NlogN) where N is the number of elements in the RowSet.
-** The cost of a TEST using the same batch number is O(logN). The cost
-** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST
-** primitives are constant time. The cost of DESTROY is O(N).
-**
-** There is an added cost of O(N) when switching between TEST and
-** SMALLEST primitives.
-*/
-
-
-/*
-** Target size for allocation chunks.
-*/
-#define ROWSET_ALLOCATION_SIZE 1024
-
-/*
-** The number of rowset entries per allocation chunk.
-*/
-#define ROWSET_ENTRY_PER_CHUNK \
- ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
-
-/*
-** Each entry in a RowSet is an instance of the following object.
-**
-** This same object is reused to store a linked list of trees of RowSetEntry
-** objects. In that alternative use, pRight points to the next entry
-** in the list, pLeft points to the tree, and v is unused. The
-** RowSet.pForest value points to the head of this forest list.
-*/
-struct RowSetEntry {
- i64 v; /* ROWID value for this entry */
- struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */
- struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */
-};
-
-/*
-** RowSetEntry objects are allocated in large chunks (instances of the
-** following structure) to reduce memory allocation overhead. The
-** chunks are kept on a linked list so that they can be deallocated
-** when the RowSet is destroyed.
-*/
-struct RowSetChunk {
- struct RowSetChunk *pNextChunk; /* Next chunk on list of them all */
- struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */
-};
-
-/*
-** A RowSet in an instance of the following structure.
-**
-** A typedef of this structure if found in sqliteInt.h.
-*/
-struct RowSet {
- struct RowSetChunk *pChunk; /* List of all chunk allocations */
- sqlite3 *db; /* The database connection */
- struct RowSetEntry *pEntry; /* List of entries using pRight */
- struct RowSetEntry *pLast; /* Last entry on the pEntry list */
- struct RowSetEntry *pFresh; /* Source of new entry objects */
- struct RowSetEntry *pForest; /* List of binary trees of entries */
- u16 nFresh; /* Number of objects on pFresh */
- u8 rsFlags; /* Various flags */
- u8 iBatch; /* Current insert batch */
-};
-
-/*
-** Allowed values for RowSet.rsFlags
-*/
-#define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */
-#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */
-
-/*
-** Turn bulk memory into a RowSet object. N bytes of memory
-** are available at pSpace. The db pointer is used as a memory context
-** for any subsequent allocations that need to occur.
-** Return a pointer to the new RowSet object.
-**
-** It must be the case that N is sufficient to make a Rowset. If not
-** an assertion fault occurs.
-**
-** If N is larger than the minimum, use the surplus as an initial
-** allocation of entries available to be filled.
-*/
-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
- RowSet *p;
- assert( N >= ROUND8(sizeof(*p)) );
- p = pSpace;
- p->pChunk = 0;
- p->db = db;
- p->pEntry = 0;
- p->pLast = 0;
- p->pForest = 0;
- p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
- p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
- p->rsFlags = ROWSET_SORTED;
- p->iBatch = 0;
- return p;
-}
-
-/*
-** Deallocate all chunks from a RowSet. This frees all memory that
-** the RowSet has allocated over its lifetime. This routine is
-** the destructor for the RowSet.
-*/
-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
- struct RowSetChunk *pChunk, *pNextChunk;
- for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
- pNextChunk = pChunk->pNextChunk;
- sqlite3DbFree(p->db, pChunk);
- }
- p->pChunk = 0;
- p->nFresh = 0;
- p->pEntry = 0;
- p->pLast = 0;
- p->pForest = 0;
- p->rsFlags = ROWSET_SORTED;
-}
-
-/*
-** Allocate a new RowSetEntry object that is associated with the
-** given RowSet. Return a pointer to the new and completely uninitialized
-** objected.
-**
-** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
-** routine returns NULL.
-*/
-static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
- assert( p!=0 );
- if( p->nFresh==0 ){
- struct RowSetChunk *pNew;
- pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
- if( pNew==0 ){
- return 0;
- }
- pNew->pNextChunk = p->pChunk;
- p->pChunk = pNew;
- p->pFresh = pNew->aEntry;
- p->nFresh = ROWSET_ENTRY_PER_CHUNK;
- }
- p->nFresh--;
- return p->pFresh++;
-}
-
-/*
-** Insert a new value into a RowSet.
-**
-** The mallocFailed flag of the database connection is set if a
-** memory allocation fails.
-*/
-SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
- struct RowSetEntry *pEntry; /* The new entry */
- struct RowSetEntry *pLast; /* The last prior entry */
-
- /* This routine is never called after sqlite3RowSetNext() */
- assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
-
- pEntry = rowSetEntryAlloc(p);
- if( pEntry==0 ) return;
- pEntry->v = rowid;
- pEntry->pRight = 0;
- pLast = p->pLast;
- if( pLast ){
- if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
- p->rsFlags &= ~ROWSET_SORTED;
- }
- pLast->pRight = pEntry;
- }else{
- p->pEntry = pEntry;
- }
- p->pLast = pEntry;
-}
-
-/*
-** Merge two lists of RowSetEntry objects. Remove duplicates.
-**
-** The input lists are connected via pRight pointers and are
-** assumed to each already be in sorted order.
-*/
-static struct RowSetEntry *rowSetEntryMerge(
- struct RowSetEntry *pA, /* First sorted list to be merged */
- struct RowSetEntry *pB /* Second sorted list to be merged */
-){
- struct RowSetEntry head;
- struct RowSetEntry *pTail;
-
- pTail = &head;
- while( pA && pB ){
- assert( pA->pRight==0 || pA->v<=pA->pRight->v );
- assert( pB->pRight==0 || pB->v<=pB->pRight->v );
- if( pA->v<pB->v ){
- pTail->pRight = pA;
- pA = pA->pRight;
- pTail = pTail->pRight;
- }else if( pB->v<pA->v ){
- pTail->pRight = pB;
- pB = pB->pRight;
- pTail = pTail->pRight;
- }else{
- pA = pA->pRight;
- }
- }
- if( pA ){
- assert( pA->pRight==0 || pA->v<=pA->pRight->v );
- pTail->pRight = pA;
- }else{
- assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
- pTail->pRight = pB;
- }
- return head.pRight;
-}
-
-/*
-** Sort all elements on the list of RowSetEntry objects into order of
-** increasing v.
-*/
-static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
- unsigned int i;
- struct RowSetEntry *pNext, *aBucket[40];
-
- memset(aBucket, 0, sizeof(aBucket));
- while( pIn ){
- pNext = pIn->pRight;
- pIn->pRight = 0;
- for(i=0; aBucket[i]; i++){
- pIn = rowSetEntryMerge(aBucket[i], pIn);
- aBucket[i] = 0;
- }
- aBucket[i] = pIn;
- pIn = pNext;
- }
- pIn = 0;
- for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
- pIn = rowSetEntryMerge(pIn, aBucket[i]);
- }
- return pIn;
-}
-
-
-/*
-** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects.
-** Convert this tree into a linked list connected by the pRight pointers
-** and return pointers to the first and last elements of the new list.
-*/
-static void rowSetTreeToList(
- struct RowSetEntry *pIn, /* Root of the input tree */
- struct RowSetEntry **ppFirst, /* Write head of the output list here */
- struct RowSetEntry **ppLast /* Write tail of the output list here */
-){
- assert( pIn!=0 );
- if( pIn->pLeft ){
- struct RowSetEntry *p;
- rowSetTreeToList(pIn->pLeft, ppFirst, &p);
- p->pRight = pIn;
- }else{
- *ppFirst = pIn;
- }
- if( pIn->pRight ){
- rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast);
- }else{
- *ppLast = pIn;
- }
- assert( (*ppLast)->pRight==0 );
-}
-
-
-/*
-** Convert a sorted list of elements (connected by pRight) into a binary
-** tree with depth of iDepth. A depth of 1 means the tree contains a single
-** node taken from the head of *ppList. A depth of 2 means a tree with
-** three nodes. And so forth.
-**
-** Use as many entries from the input list as required and update the
-** *ppList to point to the unused elements of the list. If the input
-** list contains too few elements, then construct an incomplete tree
-** and leave *ppList set to NULL.
-**
-** Return a pointer to the root of the constructed binary tree.
-*/
-static struct RowSetEntry *rowSetNDeepTree(
- struct RowSetEntry **ppList,
- int iDepth
-){
- struct RowSetEntry *p; /* Root of the new tree */
- struct RowSetEntry *pLeft; /* Left subtree */
- if( *ppList==0 ){
- return 0;
- }
- if( iDepth==1 ){
- p = *ppList;
- *ppList = p->pRight;
- p->pLeft = p->pRight = 0;
- return p;
- }
- pLeft = rowSetNDeepTree(ppList, iDepth-1);
- p = *ppList;
- if( p==0 ){
- return pLeft;
- }
- p->pLeft = pLeft;
- *ppList = p->pRight;
- p->pRight = rowSetNDeepTree(ppList, iDepth-1);
- return p;
-}
-
-/*
-** Convert a sorted list of elements into a binary tree. Make the tree
-** as deep as it needs to be in order to contain the entire list.
-*/
-static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
- int iDepth; /* Depth of the tree so far */
- struct RowSetEntry *p; /* Current tree root */
- struct RowSetEntry *pLeft; /* Left subtree */
-
- assert( pList!=0 );
- p = pList;
- pList = p->pRight;
- p->pLeft = p->pRight = 0;
- for(iDepth=1; pList; iDepth++){
- pLeft = p;
- p = pList;
- pList = p->pRight;
- p->pLeft = pLeft;
- p->pRight = rowSetNDeepTree(&pList, iDepth);
- }
- return p;
-}
-
-/*
-** Take all the entries on p->pEntry and on the trees in p->pForest and
-** sort them all together into one big ordered list on p->pEntry.
-**
-** This routine should only be called once in the life of a RowSet.
-*/
-static void rowSetToList(RowSet *p){
-
- /* This routine is called only once */
- assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
-
- if( (p->rsFlags & ROWSET_SORTED)==0 ){
- p->pEntry = rowSetEntrySort(p->pEntry);
- }
-
- /* While this module could theoretically support it, sqlite3RowSetNext()
- ** is never called after sqlite3RowSetText() for the same RowSet. So
- ** there is never a forest to deal with. Should this change, simply
- ** remove the assert() and the #if 0. */
- assert( p->pForest==0 );
-#if 0
- while( p->pForest ){
- struct RowSetEntry *pTree = p->pForest->pLeft;
- if( pTree ){
- struct RowSetEntry *pHead, *pTail;
- rowSetTreeToList(pTree, &pHead, &pTail);
- p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
- }
- p->pForest = p->pForest->pRight;
- }
-#endif
- p->rsFlags |= ROWSET_NEXT; /* Verify this routine is never called again */
-}
-
-/*
-** Extract the smallest element from the RowSet.
-** Write the element into *pRowid. Return 1 on success. Return
-** 0 if the RowSet is already empty.
-**
-** After this routine has been called, the sqlite3RowSetInsert()
-** routine may not be called again.
-*/
-SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
- assert( p!=0 );
-
- /* Merge the forest into a single sorted list on first call */
- if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
-
- /* Return the next entry on the list */
- if( p->pEntry ){
- *pRowid = p->pEntry->v;
- p->pEntry = p->pEntry->pRight;
- if( p->pEntry==0 ){
- sqlite3RowSetClear(p);
- }
- return 1;
- }else{
- return 0;
- }
-}
-
-/*
-** Check to see if element iRowid was inserted into the rowset as
-** part of any insert batch prior to iBatch. Return 1 or 0.
-**
-** If this is the first test of a new batch and if there exist entires
-** on pRowSet->pEntry, then sort those entires into the forest at
-** pRowSet->pForest so that they can be tested.
-*/
-SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){
- struct RowSetEntry *p, *pTree;
-
- /* This routine is never called after sqlite3RowSetNext() */
- assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
-
- /* Sort entries into the forest on the first test of a new batch
- */
- if( iBatch!=pRowSet->iBatch ){
- p = pRowSet->pEntry;
- if( p ){
- struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
- if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
- p = rowSetEntrySort(p);
- }
- for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
- ppPrevTree = &pTree->pRight;
- if( pTree->pLeft==0 ){
- pTree->pLeft = rowSetListToTree(p);
- break;
- }else{
- struct RowSetEntry *pAux, *pTail;
- rowSetTreeToList(pTree->pLeft, &pAux, &pTail);
- pTree->pLeft = 0;
- p = rowSetEntryMerge(pAux, p);
- }
- }
- if( pTree==0 ){
- *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet);
- if( pTree ){
- pTree->v = 0;
- pTree->pRight = 0;
- pTree->pLeft = rowSetListToTree(p);
- }
- }
- pRowSet->pEntry = 0;
- pRowSet->pLast = 0;
- pRowSet->rsFlags |= ROWSET_SORTED;
- }
- pRowSet->iBatch = iBatch;
- }
-
- /* Test to see if the iRowid value appears anywhere in the forest.
- ** Return 1 if it does and 0 if not.
- */
- for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
- p = pTree->pLeft;
- while( p ){
- if( p->v<iRowid ){
- p = p->pRight;
- }else if( p->v>iRowid ){
- p = p->pLeft;
- }else{
- return 1;
- }
- }
- }
- return 0;
-}
-
-/************** End of rowset.c **********************************************/
-/************** Begin file pager.c *******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This is the implementation of the page cache subsystem or "pager".
-**
-** The pager is used to access a database disk file. It implements
-** atomic commit and rollback through the use of a journal file that
-** is separate from the database file. The pager also implements file
-** locking to prevent two processes from writing the same database
-** file simultaneously, or one process from reading the database while
-** another is writing.
-*/
-#ifndef SQLITE_OMIT_DISKIO
-/************** Include wal.h in the middle of pager.c ***********************/
-/************** Begin file wal.h *********************************************/
-/*
-** 2010 February 1
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This header file defines the interface to the write-ahead logging
-** system. Refer to the comments below and the header comment attached to
-** the implementation of each function in log.c for further details.
-*/
-
-#ifndef _WAL_H_
-#define _WAL_H_
-
-
-/* Additional values that can be added to the sync_flags argument of
-** sqlite3WalFrames():
-*/
-#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */
-#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */
-
-#ifdef SQLITE_OMIT_WAL
-# define sqlite3WalOpen(x,y,z) 0
-# define sqlite3WalLimit(x,y)
-# define sqlite3WalClose(w,x,y,z) 0
-# define sqlite3WalBeginReadTransaction(y,z) 0
-# define sqlite3WalEndReadTransaction(z)
-# define sqlite3WalRead(v,w,x,y,z) 0
-# define sqlite3WalDbsize(y) 0
-# define sqlite3WalBeginWriteTransaction(y) 0
-# define sqlite3WalEndWriteTransaction(x) 0
-# define sqlite3WalUndo(x,y,z) 0
-# define sqlite3WalSavepoint(y,z)
-# define sqlite3WalSavepointUndo(y,z) 0
-# define sqlite3WalFrames(u,v,w,x,y,z) 0
-# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
-# define sqlite3WalCallback(z) 0
-# define sqlite3WalExclusiveMode(y,z) 0
-# define sqlite3WalHeapMemory(z) 0
-# define sqlite3WalFramesize(z) 0
-#else
-
-#define WAL_SAVEPOINT_NDATA 4
-
-/* Connection to a write-ahead log (WAL) file.
-** There is one object of this type for each pager.
-*/
-typedef struct Wal Wal;
-
-/* Open and close a connection to a write-ahead log. */
-SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
-SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
-
-/* Set the limiting size of a WAL file. */
-SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
-
-/* Used by readers to open (lock) and close (unlock) a snapshot. A
-** snapshot is like a read-transaction. It is the state of the database
-** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and
-** preserves the current state even if the other threads or processes
-** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the
-** transaction and releases the lock.
-*/
-SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
-SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal);
-
-/* Read a page from the write-ahead log, if it is present. */
-SQLITE_PRIVATE int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut);
-
-/* If the WAL is not empty, return the size of the database. */
-SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal);
-
-/* Obtain or release the WRITER lock. */
-SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal);
-SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal);
-
-/* Undo any frames written (but not committed) to the log */
-SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx);
-
-/* Return an integer that records the current (uncommitted) write
-** position in the WAL */
-SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData);
-
-/* Move the write position of the WAL back to iFrame. Called in
-** response to a ROLLBACK TO command. */
-SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData);
-
-/* Write a frame or frames to the log. */
-SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
-
-/* Copy pages from the log to the database file */
-SQLITE_PRIVATE int sqlite3WalCheckpoint(
- Wal *pWal, /* Write-ahead log connection */
- int eMode, /* One of PASSIVE, FULL and RESTART */
- int (*xBusy)(void*), /* Function to call when busy */
- void *pBusyArg, /* Context argument for xBusyHandler */
- int sync_flags, /* Flags to sync db file with (or 0) */
- int nBuf, /* Size of buffer nBuf */
- u8 *zBuf, /* Temporary buffer to use */
- int *pnLog, /* OUT: Number of frames in WAL */
- int *pnCkpt /* OUT: Number of backfilled frames in WAL */
-);
-
-/* Return the value to pass to a sqlite3_wal_hook callback, the
-** number of frames in the WAL at the point of the last commit since
-** sqlite3WalCallback() was called. If no commits have occurred since
-** the last call, then return 0.
-*/
-SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal);
-
-/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released)
-** by the pager layer on the database file.
-*/
-SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
-
-/* Return true if the argument is non-NULL and the WAL module is using
-** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
-** WAL module is using shared-memory, return false.
-*/
-SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
-
-#ifdef SQLITE_ENABLE_ZIPVFS
-/* If the WAL file is not empty, return the number of bytes of content
-** stored in each frame (i.e. the db page-size when the WAL was created).
-*/
-SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
-#endif
-
-#endif /* ifndef SQLITE_OMIT_WAL */
-#endif /* _WAL_H_ */
-
-/************** End of wal.h *************************************************/
-/************** Continuing where we left off in pager.c **********************/
-
-
-/******************* NOTES ON THE DESIGN OF THE PAGER ************************
-**
-** This comment block describes invariants that hold when using a rollback
-** journal. These invariants do not apply for journal_mode=WAL,
-** journal_mode=MEMORY, or journal_mode=OFF.
-**
-** Within this comment block, a page is deemed to have been synced
-** automatically as soon as it is written when PRAGMA synchronous=OFF.
-** Otherwise, the page is not synced until the xSync method of the VFS
-** is called successfully on the file containing the page.
-**
-** Definition: A page of the database file is said to be "overwriteable" if
-** one or more of the following are true about the page:
-**
-** (a) The original content of the page as it was at the beginning of
-** the transaction has been written into the rollback journal and
-** synced.
-**
-** (b) The page was a freelist leaf page at the start of the transaction.
-**
-** (c) The page number is greater than the largest page that existed in
-** the database file at the start of the transaction.
-**
-** (1) A page of the database file is never overwritten unless one of the
-** following are true:
-**
-** (a) The page and all other pages on the same sector are overwriteable.
-**
-** (b) The atomic page write optimization is enabled, and the entire
-** transaction other than the update of the transaction sequence
-** number consists of a single page change.
-**
-** (2) The content of a page written into the rollback journal exactly matches
-** both the content in the database when the rollback journal was written
-** and the content in the database at the beginning of the current
-** transaction.
-**
-** (3) Writes to the database file are an integer multiple of the page size
-** in length and are aligned on a page boundary.
-**
-** (4) Reads from the database file are either aligned on a page boundary and
-** an integer multiple of the page size in length or are taken from the
-** first 100 bytes of the database file.
-**
-** (5) All writes to the database file are synced prior to the rollback journal
-** being deleted, truncated, or zeroed.
-**
-** (6) If a master journal file is used, then all writes to the database file
-** are synced prior to the master journal being deleted.
-**
-** Definition: Two databases (or the same database at two points it time)
-** are said to be "logically equivalent" if they give the same answer to
-** all queries. Note in particular the content of freelist leaf
-** pages can be changed arbitarily without effecting the logical equivalence
-** of the database.
-**
-** (7) At any time, if any subset, including the empty set and the total set,
-** of the unsynced changes to a rollback journal are removed and the
-** journal is rolled back, the resulting database file will be logical
-** equivalent to the database file at the beginning of the transaction.
-**
-** (8) When a transaction is rolled back, the xTruncate method of the VFS
-** is called to restore the database file to the same size it was at
-** the beginning of the transaction. (In some VFSes, the xTruncate
-** method is a no-op, but that does not change the fact the SQLite will
-** invoke it.)
-**
-** (9) Whenever the database file is modified, at least one bit in the range
-** of bytes from 24 through 39 inclusive will be changed prior to releasing
-** the EXCLUSIVE lock, thus signaling other connections on the same
-** database to flush their caches.
-**
-** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less
-** than one billion transactions.
-**
-** (11) A database file is well-formed at the beginning and at the conclusion
-** of every transaction.
-**
-** (12) An EXCLUSIVE lock is held on the database file when writing to
-** the database file.
-**
-** (13) A SHARED lock is held on the database file while reading any
-** content out of the database file.
-**
-******************************************************************************/
-
-/*
-** Macros for troubleshooting. Normally turned off
-*/
-#if 0
-int sqlite3PagerTrace=1; /* True to enable tracing */
-#define sqlite3DebugPrintf printf
-#define PAGERTRACE(X) if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; }
-#else
-#define PAGERTRACE(X)
-#endif
-
-/*
-** The following two macros are used within the PAGERTRACE() macros above
-** to print out file-descriptors.
-**
-** PAGERID() takes a pointer to a Pager struct as its argument. The
-** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
-** struct as its argument.
-*/
-#define PAGERID(p) ((int)(p->fd))
-#define FILEHANDLEID(fd) ((int)fd)
-
-/*
-** The Pager.eState variable stores the current 'state' of a pager. A
-** pager may be in any one of the seven states shown in the following
-** state diagram.
-**
-** OPEN <------+------+
-** | | |
-** V | |
-** +---------> READER-------+ |
-** | | |
-** | V |
-** |<-------WRITER_LOCKED------> ERROR
-** | | ^
-** | V |
-** |<------WRITER_CACHEMOD-------->|
-** | | |
-** | V |
-** |<-------WRITER_DBMOD---------->|
-** | | |
-** | V |
-** +<------WRITER_FINISHED-------->+
-**
-**
-** List of state transitions and the C [function] that performs each:
-**
-** OPEN -> READER [sqlite3PagerSharedLock]
-** READER -> OPEN [pager_unlock]
-**
-** READER -> WRITER_LOCKED [sqlite3PagerBegin]
-** WRITER_LOCKED -> WRITER_CACHEMOD [pager_open_journal]
-** WRITER_CACHEMOD -> WRITER_DBMOD [syncJournal]
-** WRITER_DBMOD -> WRITER_FINISHED [sqlite3PagerCommitPhaseOne]
-** WRITER_*** -> READER [pager_end_transaction]
-**
-** WRITER_*** -> ERROR [pager_error]
-** ERROR -> OPEN [pager_unlock]
-**
-**
-** OPEN:
-**
-** The pager starts up in this state. Nothing is guaranteed in this
-** state - the file may or may not be locked and the database size is
-** unknown. The database may not be read or written.
-**
-** * No read or write transaction is active.
-** * Any lock, or no lock at all, may be held on the database file.
-** * The dbSize, dbOrigSize and dbFileSize variables may not be trusted.
-**
-** READER:
-**
-** In this state all the requirements for reading the database in
-** rollback (non-WAL) mode are met. Unless the pager is (or recently
-** was) in exclusive-locking mode, a user-level read transaction is
-** open. The database size is known in this state.
-**
-** A connection running with locking_mode=normal enters this state when
-** it opens a read-transaction on the database and returns to state
-** OPEN after the read-transaction is completed. However a connection
-** running in locking_mode=exclusive (including temp databases) remains in
-** this state even after the read-transaction is closed. The only way
-** a locking_mode=exclusive connection can transition from READER to OPEN
-** is via the ERROR state (see below).
-**
-** * A read transaction may be active (but a write-transaction cannot).
-** * A SHARED or greater lock is held on the database file.
-** * The dbSize variable may be trusted (even if a user-level read
-** transaction is not active). The dbOrigSize and dbFileSize variables
-** may not be trusted at this point.
-** * If the database is a WAL database, then the WAL connection is open.
-** * Even if a read-transaction is not open, it is guaranteed that
-** there is no hot-journal in the file-system.
-**
-** WRITER_LOCKED:
-**
-** The pager moves to this state from READER when a write-transaction
-** is first opened on the database. In WRITER_LOCKED state, all locks
-** required to start a write-transaction are held, but no actual
-** modifications to the cache or database have taken place.
-**
-** In rollback mode, a RESERVED or (if the transaction was opened with
-** BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when
-** moving to this state, but the journal file is not written to or opened
-** to in this state. If the transaction is committed or rolled back while
-** in WRITER_LOCKED state, all that is required is to unlock the database
-** file.
-**
-** IN WAL mode, WalBeginWriteTransaction() is called to lock the log file.
-** If the connection is running with locking_mode=exclusive, an attempt
-** is made to obtain an EXCLUSIVE lock on the database file.
-**
-** * A write transaction is active.
-** * If the connection is open in rollback-mode, a RESERVED or greater
-** lock is held on the database file.
-** * If the connection is open in WAL-mode, a WAL write transaction
-** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully
-** called).
-** * The dbSize, dbOrigSize and dbFileSize variables are all valid.
-** * The contents of the pager cache have not been modified.
-** * The journal file may or may not be open.
-** * Nothing (not even the first header) has been written to the journal.
-**
-** WRITER_CACHEMOD:
-**
-** A pager moves from WRITER_LOCKED state to this state when a page is
-** first modified by the upper layer. In rollback mode the journal file
-** is opened (if it is not already open) and a header written to the
-** start of it. The database file on disk has not been modified.
-**
-** * A write transaction is active.
-** * A RESERVED or greater lock is held on the database file.
-** * The journal file is open and the first header has been written
-** to it, but the header has not been synced to disk.
-** * The contents of the page cache have been modified.
-**
-** WRITER_DBMOD:
-**
-** The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state
-** when it modifies the contents of the database file. WAL connections
-** never enter this state (since they do not modify the database file,
-** just the log file).
-**
-** * A write transaction is active.
-** * An EXCLUSIVE or greater lock is held on the database file.
-** * The journal file is open and the first header has been written
-** and synced to disk.
-** * The contents of the page cache have been modified (and possibly
-** written to disk).
-**
-** WRITER_FINISHED:
-**
-** It is not possible for a WAL connection to enter this state.
-**
-** A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD
-** state after the entire transaction has been successfully written into the
-** database file. In this state the transaction may be committed simply
-** by finalizing the journal file. Once in WRITER_FINISHED state, it is
-** not possible to modify the database further. At this point, the upper
-** layer must either commit or rollback the transaction.
-**
-** * A write transaction is active.
-** * An EXCLUSIVE or greater lock is held on the database file.
-** * All writing and syncing of journal and database data has finished.
-** If no error occured, all that remains is to finalize the journal to
-** commit the transaction. If an error did occur, the caller will need
-** to rollback the transaction.
-**
-** ERROR:
-**
-** The ERROR state is entered when an IO or disk-full error (including
-** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it
-** difficult to be sure that the in-memory pager state (cache contents,
-** db size etc.) are consistent with the contents of the file-system.
-**
-** Temporary pager files may enter the ERROR state, but in-memory pagers
-** cannot.
-**
-** For example, if an IO error occurs while performing a rollback,
-** the contents of the page-cache may be left in an inconsistent state.
-** At this point it would be dangerous to change back to READER state
-** (as usually happens after a rollback). Any subsequent readers might
-** report database corruption (due to the inconsistent cache), and if
-** they upgrade to writers, they may inadvertently corrupt the database
-** file. To avoid this hazard, the pager switches into the ERROR state
-** instead of READER following such an error.
-**
-** Once it has entered the ERROR state, any attempt to use the pager
-** to read or write data returns an error. Eventually, once all
-** outstanding transactions have been abandoned, the pager is able to
-** transition back to OPEN state, discarding the contents of the
-** page-cache and any other in-memory state at the same time. Everything
-** is reloaded from disk (and, if necessary, hot-journal rollback peformed)
-** when a read-transaction is next opened on the pager (transitioning
-** the pager into READER state). At that point the system has recovered
-** from the error.
-**
-** Specifically, the pager jumps into the ERROR state if:
-**
-** 1. An error occurs while attempting a rollback. This happens in
-** function sqlite3PagerRollback().
-**
-** 2. An error occurs while attempting to finalize a journal file
-** following a commit in function sqlite3PagerCommitPhaseTwo().
-**
-** 3. An error occurs while attempting to write to the journal or
-** database file in function pagerStress() in order to free up
-** memory.
-**
-** In other cases, the error is returned to the b-tree layer. The b-tree
-** layer then attempts a rollback operation. If the error condition
-** persists, the pager enters the ERROR state via condition (1) above.
-**
-** Condition (3) is necessary because it can be triggered by a read-only
-** statement executed within a transaction. In this case, if the error
-** code were simply returned to the user, the b-tree layer would not
-** automatically attempt a rollback, as it assumes that an error in a
-** read-only statement cannot leave the pager in an internally inconsistent
-** state.
-**
-** * The Pager.errCode variable is set to something other than SQLITE_OK.
-** * There are one or more outstanding references to pages (after the
-** last reference is dropped the pager should move back to OPEN state).
-** * The pager is not an in-memory pager.
-**
-**
-** Notes:
-**
-** * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the
-** connection is open in WAL mode. A WAL connection is always in one
-** of the first four states.
-**
-** * Normally, a connection open in exclusive mode is never in PAGER_OPEN
-** state. There are two exceptions: immediately after exclusive-mode has
-** been turned on (and before any read or write transactions are
-** executed), and when the pager is leaving the "error state".
-**
-** * See also: assert_pager_state().
-*/
-#define PAGER_OPEN 0
-#define PAGER_READER 1
-#define PAGER_WRITER_LOCKED 2
-#define PAGER_WRITER_CACHEMOD 3
-#define PAGER_WRITER_DBMOD 4
-#define PAGER_WRITER_FINISHED 5
-#define PAGER_ERROR 6
-
-/*
-** The Pager.eLock variable is almost always set to one of the
-** following locking-states, according to the lock currently held on
-** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
-** This variable is kept up to date as locks are taken and released by
-** the pagerLockDb() and pagerUnlockDb() wrappers.
-**
-** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY
-** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not
-** the operation was successful. In these circumstances pagerLockDb() and
-** pagerUnlockDb() take a conservative approach - eLock is always updated
-** when unlocking the file, and only updated when locking the file if the
-** VFS call is successful. This way, the Pager.eLock variable may be set
-** to a less exclusive (lower) value than the lock that is actually held
-** at the system level, but it is never set to a more exclusive value.
-**
-** This is usually safe. If an xUnlock fails or appears to fail, there may
-** be a few redundant xLock() calls or a lock may be held for longer than
-** required, but nothing really goes wrong.
-**
-** The exception is when the database file is unlocked as the pager moves
-** from ERROR to OPEN state. At this point there may be a hot-journal file
-** in the file-system that needs to be rolled back (as part of a OPEN->SHARED
-** transition, by the same pager or any other). If the call to xUnlock()
-** fails at this point and the pager is left holding an EXCLUSIVE lock, this
-** can confuse the call to xCheckReservedLock() call made later as part
-** of hot-journal detection.
-**
-** xCheckReservedLock() is defined as returning true "if there is a RESERVED
-** lock held by this process or any others". So xCheckReservedLock may
-** return true because the caller itself is holding an EXCLUSIVE lock (but
-** doesn't know it because of a previous error in xUnlock). If this happens
-** a hot-journal may be mistaken for a journal being created by an active
-** transaction in another process, causing SQLite to read from the database
-** without rolling it back.
-**
-** To work around this, if a call to xUnlock() fails when unlocking the
-** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It
-** is only changed back to a real locking state after a successful call
-** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition
-** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK
-** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE
-** lock on the database file before attempting to roll it back. See function
-** PagerSharedLock() for more detail.
-**
-** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in
-** PAGER_OPEN state.
-*/
-#define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1)
-
-/*
-** A macro used for invoking the codec if there is one
-*/
-#ifdef SQLITE_HAS_CODEC
-# define CODEC1(P,D,N,X,E) \
- if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
-# define CODEC2(P,D,N,X,E,O) \
- if( P->xCodec==0 ){ O=(char*)D; }else \
- if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
-#else
-# define CODEC1(P,D,N,X,E) /* NO-OP */
-# define CODEC2(P,D,N,X,E,O) O=(char*)D
-#endif
-
-/*
-** The maximum allowed sector size. 64KiB. If the xSectorsize() method
-** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
-** This could conceivably cause corruption following a power failure on
-** such a system. This is currently an undocumented limit.
-*/
-#define MAX_SECTOR_SIZE 0x10000
-
-/*
-** An instance of the following structure is allocated for each active
-** savepoint and statement transaction in the system. All such structures
-** are stored in the Pager.aSavepoint[] array, which is allocated and
-** resized using sqlite3Realloc().
-**
-** When a savepoint is created, the PagerSavepoint.iHdrOffset field is
-** set to 0. If a journal-header is written into the main journal while
-** the savepoint is active, then iHdrOffset is set to the byte offset
-** immediately following the last journal record written into the main
-** journal before the journal-header. This is required during savepoint
-** rollback (see pagerPlaybackSavepoint()).
-*/
-typedef struct PagerSavepoint PagerSavepoint;
-struct PagerSavepoint {
- i64 iOffset; /* Starting offset in main journal */
- i64 iHdrOffset; /* See above */
- Bitvec *pInSavepoint; /* Set of pages in this savepoint */
- Pgno nOrig; /* Original number of pages in file */
- Pgno iSubRec; /* Index of first record in sub-journal */
-#ifndef SQLITE_OMIT_WAL
- u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */
-#endif
-};
-
-/*
-** A open page cache is an instance of struct Pager. A description of
-** some of the more important member variables follows:
-**
-** eState
-**
-** The current 'state' of the pager object. See the comment and state
-** diagram above for a description of the pager state.
-**
-** eLock
-**
-** For a real on-disk database, the current lock held on the database file -
-** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
-**
-** For a temporary or in-memory database (neither of which require any
-** locks), this variable is always set to EXCLUSIVE_LOCK. Since such
-** databases always have Pager.exclusiveMode==1, this tricks the pager
-** logic into thinking that it already has all the locks it will ever
-** need (and no reason to release them).
-**
-** In some (obscure) circumstances, this variable may also be set to
-** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for
-** details.
-**
-** changeCountDone
-**
-** This boolean variable is used to make sure that the change-counter
-** (the 4-byte header field at byte offset 24 of the database file) is
-** not updated more often than necessary.
-**
-** It is set to true when the change-counter field is updated, which
-** can only happen if an exclusive lock is held on the database file.
-** It is cleared (set to false) whenever an exclusive lock is
-** relinquished on the database file. Each time a transaction is committed,
-** The changeCountDone flag is inspected. If it is true, the work of
-** updating the change-counter is omitted for the current transaction.
-**
-** This mechanism means that when running in exclusive mode, a connection
-** need only update the change-counter once, for the first transaction
-** committed.
-**
-** setMaster
-**
-** When PagerCommitPhaseOne() is called to commit a transaction, it may
-** (or may not) specify a master-journal name to be written into the
-** journal file before it is synced to disk.
-**
-** Whether or not a journal file contains a master-journal pointer affects
-** the way in which the journal file is finalized after the transaction is
-** committed or rolled back when running in "journal_mode=PERSIST" mode.
-** If a journal file does not contain a master-journal pointer, it is
-** finalized by overwriting the first journal header with zeroes. If
-** it does contain a master-journal pointer the journal file is finalized
-** by truncating it to zero bytes, just as if the connection were
-** running in "journal_mode=truncate" mode.
-**
-** Journal files that contain master journal pointers cannot be finalized
-** simply by overwriting the first journal-header with zeroes, as the
-** master journal pointer could interfere with hot-journal rollback of any
-** subsequently interrupted transaction that reuses the journal file.
-**
-** The flag is cleared as soon as the journal file is finalized (either
-** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
-** journal file from being successfully finalized, the setMaster flag
-** is cleared anyway (and the pager will move to ERROR state).
-**
-** doNotSpill, doNotSyncSpill
-**
-** These two boolean variables control the behaviour of cache-spills
-** (calls made by the pcache module to the pagerStress() routine to
-** write cached data to the file-system in order to free up memory).
-**
-** When doNotSpill is non-zero, writing to the database from pagerStress()
-** is disabled altogether. This is done in a very obscure case that
-** comes up during savepoint rollback that requires the pcache module
-** to allocate a new page to prevent the journal file from being written
-** while it is being traversed by code in pager_playback().
-**
-** If doNotSyncSpill is non-zero, writing to the database from pagerStress()
-** is permitted, but syncing the journal file is not. This flag is set
-** by sqlite3PagerWrite() when the file-system sector-size is larger than
-** the database page-size in order to prevent a journal sync from happening
-** in between the journalling of two pages on the same sector.
-**
-** subjInMemory
-**
-** This is a boolean variable. If true, then any required sub-journal
-** is opened as an in-memory journal file. If false, then in-memory
-** sub-journals are only used for in-memory pager files.
-**
-** This variable is updated by the upper layer each time a new
-** write-transaction is opened.
-**
-** dbSize, dbOrigSize, dbFileSize
-**
-** Variable dbSize is set to the number of pages in the database file.
-** It is valid in PAGER_READER and higher states (all states except for
-** OPEN and ERROR).
-**
-** dbSize is set based on the size of the database file, which may be
-** larger than the size of the database (the value stored at offset
-** 28 of the database header by the btree). If the size of the file
-** is not an integer multiple of the page-size, the value stored in
-** dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2).
-** Except, any file that is greater than 0 bytes in size is considered
-** to have at least one page. (i.e. a 1KB file with 2K page-size leads
-** to dbSize==1).
-**
-** During a write-transaction, if pages with page-numbers greater than
-** dbSize are modified in the cache, dbSize is updated accordingly.
-** Similarly, if the database is truncated using PagerTruncateImage(),
-** dbSize is updated.
-**
-** Variables dbOrigSize and dbFileSize are valid in states
-** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize
-** variable at the start of the transaction. It is used during rollback,
-** and to determine whether or not pages need to be journalled before
-** being modified.
-**
-** Throughout a write-transaction, dbFileSize contains the size of
-** the file on disk in pages. It is set to a copy of dbSize when the
-** write-transaction is first opened, and updated when VFS calls are made
-** to write or truncate the database file on disk.
-**
-** The only reason the dbFileSize variable is required is to suppress
-** unnecessary calls to xTruncate() after committing a transaction. If,
-** when a transaction is committed, the dbFileSize variable indicates
-** that the database file is larger than the database image (Pager.dbSize),
-** pager_truncate() is called. The pager_truncate() call uses xFilesize()
-** to measure the database file on disk, and then truncates it if required.
-** dbFileSize is not used when rolling back a transaction. In this case
-** pager_truncate() is called unconditionally (which means there may be
-** a call to xFilesize() that is not strictly required). In either case,
-** pager_truncate() may cause the file to become smaller or larger.
-**
-** dbHintSize
-**
-** The dbHintSize variable is used to limit the number of calls made to
-** the VFS xFileControl(FCNTL_SIZE_HINT) method.
-**
-** dbHintSize is set to a copy of the dbSize variable when a
-** write-transaction is opened (at the same time as dbFileSize and
-** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called,
-** dbHintSize is increased to the number of pages that correspond to the
-** size-hint passed to the method call. See pager_write_pagelist() for
-** details.
-**
-** errCode
-**
-** The Pager.errCode variable is only ever used in PAGER_ERROR state. It
-** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode
-** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX
-** sub-codes.
-*/
-struct Pager {
- sqlite3_vfs *pVfs; /* OS functions to use for IO */
- u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */
- u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */
- u8 useJournal; /* Use a rollback journal on this file */
- u8 noSync; /* Do not sync the journal if true */
- u8 fullSync; /* Do extra syncs of the journal for robustness */
- u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */
- u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */
- u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */
- u8 tempFile; /* zFilename is a temporary file */
- u8 readOnly; /* True for a read-only database */
- u8 memDb; /* True to inhibit all file I/O */
-
- /**************************************************************************
- ** The following block contains those class members that change during
- ** routine opertion. Class members not in this block are either fixed
- ** when the pager is first created or else only change when there is a
- ** significant mode change (such as changing the page_size, locking_mode,
- ** or the journal_mode). From another view, these class members describe
- ** the "state" of the pager, while other class members describe the
- ** "configuration" of the pager.
- */
- u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */
- u8 eLock; /* Current lock held on database file */
- u8 changeCountDone; /* Set after incrementing the change-counter */
- u8 setMaster; /* True if a m-j name has been written to jrnl */
- u8 doNotSpill; /* Do not spill the cache when non-zero */
- u8 doNotSyncSpill; /* Do not do a spill that requires jrnl sync */
- u8 subjInMemory; /* True to use in-memory sub-journals */
- Pgno dbSize; /* Number of pages in the database */
- Pgno dbOrigSize; /* dbSize before the current transaction */
- Pgno dbFileSize; /* Number of pages in the database file */
- Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */
- int errCode; /* One of several kinds of errors */
- int nRec; /* Pages journalled since last j-header written */
- u32 cksumInit; /* Quasi-random value added to every checksum */
- u32 nSubRec; /* Number of records written to sub-journal */
- Bitvec *pInJournal; /* One bit for each page in the database file */
- sqlite3_file *fd; /* File descriptor for database */
- sqlite3_file *jfd; /* File descriptor for main journal */
- sqlite3_file *sjfd; /* File descriptor for sub-journal */
- i64 journalOff; /* Current write offset in the journal file */
- i64 journalHdr; /* Byte offset to previous journal header */
- sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
- PagerSavepoint *aSavepoint; /* Array of active savepoints */
- int nSavepoint; /* Number of elements in aSavepoint[] */
- char dbFileVers[16]; /* Changes whenever database file changes */
- /*
- ** End of the routinely-changing class members
- ***************************************************************************/
-
- u16 nExtra; /* Add this many bytes to each in-memory page */
- i16 nReserve; /* Number of unused bytes at end of each page */
- u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */
- u32 sectorSize; /* Assumed sector size during rollback */
- int pageSize; /* Number of bytes in a page */
- Pgno mxPgno; /* Maximum allowed size of the database */
- i64 journalSizeLimit; /* Size limit for persistent journal files */
- char *zFilename; /* Name of the database file */
- char *zJournal; /* Name of the journal file */
- int (*xBusyHandler)(void*); /* Function to call when busy */
- void *pBusyHandlerArg; /* Context argument for xBusyHandler */
- int aStat[3]; /* Total cache hits, misses and writes */
-#ifdef SQLITE_TEST
- int nRead; /* Database pages read */
-#endif
- void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
-#ifdef SQLITE_HAS_CODEC
- void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
- void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
- void (*xCodecFree)(void*); /* Destructor for the codec */
- void *pCodec; /* First argument to xCodec... methods */
-#endif
- char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */
- PCache *pPCache; /* Pointer to page cache object */
-#ifndef SQLITE_OMIT_WAL
- Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */
- char *zWal; /* File name for write-ahead log */
-#endif
-};
-
-/*
-** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains
-** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS
-** or CACHE_WRITE to sqlite3_db_status().
-*/
-#define PAGER_STAT_HIT 0
-#define PAGER_STAT_MISS 1
-#define PAGER_STAT_WRITE 2
-
-/*
-** The following global variables hold counters used for
-** testing purposes only. These variables do not exist in
-** a non-testing build. These variables are not thread-safe.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */
-SQLITE_API int sqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */
-SQLITE_API int sqlite3_pager_writej_count = 0; /* Number of pages written to journal */
-# define PAGER_INCR(v) v++
-#else
-# define PAGER_INCR(v)
-#endif
-
-
-
-/*
-** Journal files begin with the following magic string. The data
-** was obtained from /dev/random. It is used only as a sanity check.
-**
-** Since version 2.8.0, the journal format contains additional sanity
-** checking information. If the power fails while the journal is being
-** written, semi-random garbage data might appear in the journal
-** file after power is restored. If an attempt is then made
-** to roll the journal back, the database could be corrupted. The additional
-** sanity checking data is an attempt to discover the garbage in the
-** journal and ignore it.
-**
-** The sanity checking information for the new journal format consists
-** of a 32-bit checksum on each page of data. The checksum covers both
-** the page number and the pPager->pageSize bytes of data for the page.
-** This cksum is initialized to a 32-bit random value that appears in the
-** journal file right after the header. The random initializer is important,
-** because garbage data that appears at the end of a journal is likely
-** data that was once in other files that have now been deleted. If the
-** garbage data came from an obsolete journal file, the checksums might
-** be correct. But by initializing the checksum to random value which
-** is different for every journal, we minimize that risk.
-*/
-static const unsigned char aJournalMagic[] = {
- 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
-};
-
-/*
-** The size of the of each page record in the journal is given by
-** the following macro.
-*/
-#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8)
-
-/*
-** The journal header size for this pager. This is usually the same
-** size as a single disk sector. See also setSectorSize().
-*/
-#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
-
-/*
-** The macro MEMDB is true if we are dealing with an in-memory database.
-** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,
-** the value of MEMDB will be a constant and the compiler will optimize
-** out code that would never execute.
-*/
-#ifdef SQLITE_OMIT_MEMORYDB
-# define MEMDB 0
-#else
-# define MEMDB pPager->memDb
-#endif
-
-/*
-** The maximum legal page number is (2^31 - 1).
-*/
-#define PAGER_MAX_PGNO 2147483647
-
-/*
-** The argument to this macro is a file descriptor (type sqlite3_file*).
-** Return 0 if it is not open, or non-zero (but not 1) if it is.
-**
-** This is so that expressions can be written as:
-**
-** if( isOpen(pPager->jfd) ){ ...
-**
-** instead of
-**
-** if( pPager->jfd->pMethods ){ ...
-*/
-#define isOpen(pFd) ((pFd)->pMethods)
-
-/*
-** Return true if this pager uses a write-ahead log instead of the usual
-** rollback journal. Otherwise false.
-*/
-#ifndef SQLITE_OMIT_WAL
-static int pagerUseWal(Pager *pPager){
- return (pPager->pWal!=0);
-}
-#else
-# define pagerUseWal(x) 0
-# define pagerRollbackWal(x) 0
-# define pagerWalFrames(v,w,x,y) 0
-# define pagerOpenWalIfPresent(z) SQLITE_OK
-# define pagerBeginReadTransaction(z) SQLITE_OK
-#endif
-
-#ifndef NDEBUG
-/*
-** Usage:
-**
-** assert( assert_pager_state(pPager) );
-**
-** This function runs many asserts to try to find inconsistencies in
-** the internal state of the Pager object.
-*/
-static int assert_pager_state(Pager *p){
- Pager *pPager = p;
-
- /* State must be valid. */
- assert( p->eState==PAGER_OPEN
- || p->eState==PAGER_READER
- || p->eState==PAGER_WRITER_LOCKED
- || p->eState==PAGER_WRITER_CACHEMOD
- || p->eState==PAGER_WRITER_DBMOD
- || p->eState==PAGER_WRITER_FINISHED
- || p->eState==PAGER_ERROR
- );
-
- /* Regardless of the current state, a temp-file connection always behaves
- ** as if it has an exclusive lock on the database file. It never updates
- ** the change-counter field, so the changeCountDone flag is always set.
- */
- assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK );
- assert( p->tempFile==0 || pPager->changeCountDone );
-
- /* If the useJournal flag is clear, the journal-mode must be "OFF".
- ** And if the journal-mode is "OFF", the journal file must not be open.
- */
- assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal );
- assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) );
-
- /* Check that MEMDB implies noSync. And an in-memory journal. Since
- ** this means an in-memory pager performs no IO at all, it cannot encounter
- ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing
- ** a journal file. (although the in-memory journal implementation may
- ** return SQLITE_IOERR_NOMEM while the journal file is being written). It
- ** is therefore not possible for an in-memory pager to enter the ERROR
- ** state.
- */
- if( MEMDB ){
- assert( p->noSync );
- assert( p->journalMode==PAGER_JOURNALMODE_OFF
- || p->journalMode==PAGER_JOURNALMODE_MEMORY
- );
- assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN );
- assert( pagerUseWal(p)==0 );
- }
-
- /* If changeCountDone is set, a RESERVED lock or greater must be held
- ** on the file.
- */
- assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
- assert( p->eLock!=PENDING_LOCK );
-
- switch( p->eState ){
- case PAGER_OPEN:
- assert( !MEMDB );
- assert( pPager->errCode==SQLITE_OK );
- assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile );
- break;
-
- case PAGER_READER:
- assert( pPager->errCode==SQLITE_OK );
- assert( p->eLock!=UNKNOWN_LOCK );
- assert( p->eLock>=SHARED_LOCK );
- break;
-
- case PAGER_WRITER_LOCKED:
- assert( p->eLock!=UNKNOWN_LOCK );
- assert( pPager->errCode==SQLITE_OK );
- if( !pagerUseWal(pPager) ){
- assert( p->eLock>=RESERVED_LOCK );
- }
- assert( pPager->dbSize==pPager->dbOrigSize );
- assert( pPager->dbOrigSize==pPager->dbFileSize );
- assert( pPager->dbOrigSize==pPager->dbHintSize );
- assert( pPager->setMaster==0 );
- break;
-
- case PAGER_WRITER_CACHEMOD:
- assert( p->eLock!=UNKNOWN_LOCK );
- assert( pPager->errCode==SQLITE_OK );
- if( !pagerUseWal(pPager) ){
- /* It is possible that if journal_mode=wal here that neither the
- ** journal file nor the WAL file are open. This happens during
- ** a rollback transaction that switches from journal_mode=off
- ** to journal_mode=wal.
- */
- assert( p->eLock>=RESERVED_LOCK );
- assert( isOpen(p->jfd)
- || p->journalMode==PAGER_JOURNALMODE_OFF
- || p->journalMode==PAGER_JOURNALMODE_WAL
- );
- }
- assert( pPager->dbOrigSize==pPager->dbFileSize );
- assert( pPager->dbOrigSize==pPager->dbHintSize );
- break;
-
- case PAGER_WRITER_DBMOD:
- assert( p->eLock==EXCLUSIVE_LOCK );
- assert( pPager->errCode==SQLITE_OK );
- assert( !pagerUseWal(pPager) );
- assert( p->eLock>=EXCLUSIVE_LOCK );
- assert( isOpen(p->jfd)
- || p->journalMode==PAGER_JOURNALMODE_OFF
- || p->journalMode==PAGER_JOURNALMODE_WAL
- );
- assert( pPager->dbOrigSize<=pPager->dbHintSize );
- break;
-
- case PAGER_WRITER_FINISHED:
- assert( p->eLock==EXCLUSIVE_LOCK );
- assert( pPager->errCode==SQLITE_OK );
- assert( !pagerUseWal(pPager) );
- assert( isOpen(p->jfd)
- || p->journalMode==PAGER_JOURNALMODE_OFF
- || p->journalMode==PAGER_JOURNALMODE_WAL
- );
- break;
-
- case PAGER_ERROR:
- /* There must be at least one outstanding reference to the pager if
- ** in ERROR state. Otherwise the pager should have already dropped
- ** back to OPEN state.
- */
- assert( pPager->errCode!=SQLITE_OK );
- assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
- break;
- }
-
- return 1;
-}
-#endif /* ifndef NDEBUG */
-
-#ifdef SQLITE_DEBUG
-/*
-** Return a pointer to a human readable string in a static buffer
-** containing the state of the Pager object passed as an argument. This
-** is intended to be used within debuggers. For example, as an alternative
-** to "print *pPager" in gdb:
-**
-** (gdb) printf "%s", print_pager_state(pPager)
-*/
-static char *print_pager_state(Pager *p){
- static char zRet[1024];
-
- sqlite3_snprintf(1024, zRet,
- "Filename: %s\n"
- "State: %s errCode=%d\n"
- "Lock: %s\n"
- "Locking mode: locking_mode=%s\n"
- "Journal mode: journal_mode=%s\n"
- "Backing store: tempFile=%d memDb=%d useJournal=%d\n"
- "Journal: journalOff=%lld journalHdr=%lld\n"
- "Size: dbsize=%d dbOrigSize=%d dbFileSize=%d\n"
- , p->zFilename
- , p->eState==PAGER_OPEN ? "OPEN" :
- p->eState==PAGER_READER ? "READER" :
- p->eState==PAGER_WRITER_LOCKED ? "WRITER_LOCKED" :
- p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" :
- p->eState==PAGER_WRITER_DBMOD ? "WRITER_DBMOD" :
- p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" :
- p->eState==PAGER_ERROR ? "ERROR" : "?error?"
- , (int)p->errCode
- , p->eLock==NO_LOCK ? "NO_LOCK" :
- p->eLock==RESERVED_LOCK ? "RESERVED" :
- p->eLock==EXCLUSIVE_LOCK ? "EXCLUSIVE" :
- p->eLock==SHARED_LOCK ? "SHARED" :
- p->eLock==UNKNOWN_LOCK ? "UNKNOWN" : "?error?"
- , p->exclusiveMode ? "exclusive" : "normal"
- , p->journalMode==PAGER_JOURNALMODE_MEMORY ? "memory" :
- p->journalMode==PAGER_JOURNALMODE_OFF ? "off" :
- p->journalMode==PAGER_JOURNALMODE_DELETE ? "delete" :
- p->journalMode==PAGER_JOURNALMODE_PERSIST ? "persist" :
- p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" :
- p->journalMode==PAGER_JOURNALMODE_WAL ? "wal" : "?error?"
- , (int)p->tempFile, (int)p->memDb, (int)p->useJournal
- , p->journalOff, p->journalHdr
- , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize
- );
-
- return zRet;
-}
-#endif
-
-/*
-** Return true if it is necessary to write page *pPg into the sub-journal.
-** A page needs to be written into the sub-journal if there exists one
-** or more open savepoints for which:
-**
-** * The page-number is less than or equal to PagerSavepoint.nOrig, and
-** * The bit corresponding to the page-number is not set in
-** PagerSavepoint.pInSavepoint.
-*/
-static int subjRequiresPage(PgHdr *pPg){
- Pgno pgno = pPg->pgno;
- Pager *pPager = pPg->pPager;
- int i;
- for(i=0; i<pPager->nSavepoint; i++){
- PagerSavepoint *p = &pPager->aSavepoint[i];
- if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** Return true if the page is already in the journal file.
-*/
-static int pageInJournal(PgHdr *pPg){
- return sqlite3BitvecTest(pPg->pPager->pInJournal, pPg->pgno);
-}
-
-/*
-** Read a 32-bit integer from the given file descriptor. Store the integer
-** that is read in *pRes. Return SQLITE_OK if everything worked, or an
-** error code is something goes wrong.
-**
-** All values are stored on disk as big-endian.
-*/
-static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){
- unsigned char ac[4];
- int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);
- if( rc==SQLITE_OK ){
- *pRes = sqlite3Get4byte(ac);
- }
- return rc;
-}
-
-/*
-** Write a 32-bit integer into a string buffer in big-endian byte order.
-*/
-#define put32bits(A,B) sqlite3Put4byte((u8*)A,B)
-
-
-/*
-** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK
-** on success or an error code is something goes wrong.
-*/
-static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
- char ac[4];
- put32bits(ac, val);
- return sqlite3OsWrite(fd, ac, 4, offset);
-}
-
-/*
-** Unlock the database file to level eLock, which must be either NO_LOCK
-** or SHARED_LOCK. Regardless of whether or not the call to xUnlock()
-** succeeds, set the Pager.eLock variable to match the (attempted) new lock.
-**
-** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is
-** called, do not modify it. See the comment above the #define of
-** UNKNOWN_LOCK for an explanation of this.
-*/
-static int pagerUnlockDb(Pager *pPager, int eLock){
- int rc = SQLITE_OK;
-
- assert( !pPager->exclusiveMode || pPager->eLock==eLock );
- assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
- assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
- if( isOpen(pPager->fd) ){
- assert( pPager->eLock>=eLock );
- rc = sqlite3OsUnlock(pPager->fd, eLock);
- if( pPager->eLock!=UNKNOWN_LOCK ){
- pPager->eLock = (u8)eLock;
- }
- IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
- }
- return rc;
-}
-
-/*
-** Lock the database file to level eLock, which must be either SHARED_LOCK,
-** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the
-** Pager.eLock variable to the new locking state.
-**
-** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is
-** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK.
-** See the comment above the #define of UNKNOWN_LOCK for an explanation
-** of this.
-*/
-static int pagerLockDb(Pager *pPager, int eLock){
- int rc = SQLITE_OK;
-
- assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
- if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
- rc = sqlite3OsLock(pPager->fd, eLock);
- if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){
- pPager->eLock = (u8)eLock;
- IOTRACE(("LOCK %p %d\n", pPager, eLock))
- }
- }
- return rc;
-}
-
-/*
-** This function determines whether or not the atomic-write optimization
-** can be used with this pager. The optimization can be used if:
-**
-** (a) the value returned by OsDeviceCharacteristics() indicates that
-** a database page may be written atomically, and
-** (b) the value returned by OsSectorSize() is less than or equal
-** to the page size.
-**
-** The optimization is also always enabled for temporary files. It is
-** an error to call this function if pPager is opened on an in-memory
-** database.
-**
-** If the optimization cannot be used, 0 is returned. If it can be used,
-** then the value returned is the size of the journal file when it
-** contains rollback data for exactly one page.
-*/
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-static int jrnlBufferSize(Pager *pPager){
- assert( !MEMDB );
- if( !pPager->tempFile ){
- int dc; /* Device characteristics */
- int nSector; /* Sector size */
- int szPage; /* Page size */
-
- assert( isOpen(pPager->fd) );
- dc = sqlite3OsDeviceCharacteristics(pPager->fd);
- nSector = pPager->sectorSize;
- szPage = pPager->pageSize;
-
- assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
- assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
- if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){
- return 0;
- }
- }
-
- return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
-}
-#endif
-
-/*
-** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
-** on the cache using a hash function. This is used for testing
-** and debugging only.
-*/
-#ifdef SQLITE_CHECK_PAGES
-/*
-** Return a 32-bit hash of the page data for pPage.
-*/
-static u32 pager_datahash(int nByte, unsigned char *pData){
- u32 hash = 0;
- int i;
- for(i=0; i<nByte; i++){
- hash = (hash*1039) + pData[i];
- }
- return hash;
-}
-static u32 pager_pagehash(PgHdr *pPage){
- return pager_datahash(pPage->pPager->pageSize, (unsigned char *)pPage->pData);
-}
-static void pager_set_pagehash(PgHdr *pPage){
- pPage->pageHash = pager_pagehash(pPage);
-}
-
-/*
-** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
-** is defined, and NDEBUG is not defined, an assert() statement checks
-** that the page is either dirty or still matches the calculated page-hash.
-*/
-#define CHECK_PAGE(x) checkPage(x)
-static void checkPage(PgHdr *pPg){
- Pager *pPager = pPg->pPager;
- assert( pPager->eState!=PAGER_ERROR );
- assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
-}
-
-#else
-#define pager_datahash(X,Y) 0
-#define pager_pagehash(X) 0
-#define pager_set_pagehash(X)
-#define CHECK_PAGE(x)
-#endif /* SQLITE_CHECK_PAGES */
-
-/*
-** When this is called the journal file for pager pPager must be open.
-** This function attempts to read a master journal file name from the
-** end of the file and, if successful, copies it into memory supplied
-** by the caller. See comments above writeMasterJournal() for the format
-** used to store a master journal file name at the end of a journal file.
-**
-** zMaster must point to a buffer of at least nMaster bytes allocated by
-** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
-** enough space to write the master journal name). If the master journal
-** name in the journal is longer than nMaster bytes (including a
-** nul-terminator), then this is handled as if no master journal name
-** were present in the journal.
-**
-** If a master journal file name is present at the end of the journal
-** file, then it is copied into the buffer pointed to by zMaster. A
-** nul-terminator byte is appended to the buffer following the master
-** journal file name.
-**
-** If it is determined that no master journal file name is present
-** zMaster[0] is set to 0 and SQLITE_OK returned.
-**
-** If an error occurs while reading from the journal file, an SQLite
-** error code is returned.
-*/
-static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
- int rc; /* Return code */
- u32 len; /* Length in bytes of master journal name */
- i64 szJ; /* Total size in bytes of journal file pJrnl */
- u32 cksum; /* MJ checksum value read from journal */
- u32 u; /* Unsigned loop counter */
- unsigned char aMagic[8]; /* A buffer to hold the magic header */
- zMaster[0] = '\0';
-
- if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
- || szJ<16
- || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
- || len>=nMaster
- || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
- || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
- || memcmp(aMagic, aJournalMagic, 8)
- || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len))
- ){
- return rc;
- }
-
- /* See if the checksum matches the master journal name */
- for(u=0; u<len; u++){
- cksum -= zMaster[u];
- }
- if( cksum ){
- /* If the checksum doesn't add up, then one or more of the disk sectors
- ** containing the master journal filename is corrupted. This means
- ** definitely roll back, so just return SQLITE_OK and report a (nul)
- ** master-journal filename.
- */
- len = 0;
- }
- zMaster[len] = '\0';
-
- return SQLITE_OK;
-}
-
-/*
-** Return the offset of the sector boundary at or immediately
-** following the value in pPager->journalOff, assuming a sector
-** size of pPager->sectorSize bytes.
-**
-** i.e for a sector size of 512:
-**
-** Pager.journalOff Return value
-** ---------------------------------------
-** 0 0
-** 512 512
-** 100 512
-** 2000 2048
-**
-*/
-static i64 journalHdrOffset(Pager *pPager){
- i64 offset = 0;
- i64 c = pPager->journalOff;
- if( c ){
- offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
- }
- assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
- assert( offset>=c );
- assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
- return offset;
-}
-
-/*
-** The journal file must be open when this function is called.
-**
-** This function is a no-op if the journal file has not been written to
-** within the current transaction (i.e. if Pager.journalOff==0).
-**
-** If doTruncate is non-zero or the Pager.journalSizeLimit variable is
-** set to 0, then truncate the journal file to zero bytes in size. Otherwise,
-** zero the 28-byte header at the start of the journal file. In either case,
-** if the pager is not in no-sync mode, sync the journal file immediately
-** after writing or truncating it.
-**
-** If Pager.journalSizeLimit is set to a positive, non-zero value, and
-** following the truncation or zeroing described above the size of the
-** journal file in bytes is larger than this value, then truncate the
-** journal file to Pager.journalSizeLimit bytes. The journal file does
-** not need to be synced following this operation.
-**
-** If an IO error occurs, abandon processing and return the IO error code.
-** Otherwise, return SQLITE_OK.
-*/
-static int zeroJournalHdr(Pager *pPager, int doTruncate){
- int rc = SQLITE_OK; /* Return code */
- assert( isOpen(pPager->jfd) );
- if( pPager->journalOff ){
- const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */
-
- IOTRACE(("JZEROHDR %p\n", pPager))
- if( doTruncate || iLimit==0 ){
- rc = sqlite3OsTruncate(pPager->jfd, 0);
- }else{
- static const char zeroHdr[28] = {0};
- rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
- }
- if( rc==SQLITE_OK && !pPager->noSync ){
- rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags);
- }
-
- /* At this point the transaction is committed but the write lock
- ** is still held on the file. If there is a size limit configured for
- ** the persistent journal and the journal file currently consumes more
- ** space than that limit allows for, truncate it now. There is no need
- ** to sync the file following this operation.
- */
- if( rc==SQLITE_OK && iLimit>0 ){
- i64 sz;
- rc = sqlite3OsFileSize(pPager->jfd, &sz);
- if( rc==SQLITE_OK && sz>iLimit ){
- rc = sqlite3OsTruncate(pPager->jfd, iLimit);
- }
- }
- }
- return rc;
-}
-
-/*
-** The journal file must be open when this routine is called. A journal
-** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
-** current location.
-**
-** The format for the journal header is as follows:
-** - 8 bytes: Magic identifying journal format.
-** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
-** - 4 bytes: Random number used for page hash.
-** - 4 bytes: Initial database page count.
-** - 4 bytes: Sector size used by the process that wrote this journal.
-** - 4 bytes: Database page size.
-**
-** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
-*/
-static int writeJournalHdr(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
- char *zHeader = pPager->pTmpSpace; /* Temporary space used to build header */
- u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */
- u32 nWrite; /* Bytes of header sector written */
- int ii; /* Loop counter */
-
- assert( isOpen(pPager->jfd) ); /* Journal file must be open. */
-
- if( nHeader>JOURNAL_HDR_SZ(pPager) ){
- nHeader = JOURNAL_HDR_SZ(pPager);
- }
-
- /* If there are active savepoints and any of them were created
- ** since the most recent journal header was written, update the
- ** PagerSavepoint.iHdrOffset fields now.
- */
- for(ii=0; ii<pPager->nSavepoint; ii++){
- if( pPager->aSavepoint[ii].iHdrOffset==0 ){
- pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff;
- }
- }
-
- pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager);
-
- /*
- ** Write the nRec Field - the number of page records that follow this
- ** journal header. Normally, zero is written to this value at this time.
- ** After the records are added to the journal (and the journal synced,
- ** if in full-sync mode), the zero is overwritten with the true number
- ** of records (see syncJournal()).
- **
- ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
- ** reading the journal this value tells SQLite to assume that the
- ** rest of the journal file contains valid page records. This assumption
- ** is dangerous, as if a failure occurred whilst writing to the journal
- ** file it may contain some garbage data. There are two scenarios
- ** where this risk can be ignored:
- **
- ** * When the pager is in no-sync mode. Corruption can follow a
- ** power failure in this case anyway.
- **
- ** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
- ** that garbage data is never appended to the journal file.
- */
- assert( isOpen(pPager->fd) || pPager->noSync );
- if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
- || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
- ){
- memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
- put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
- }else{
- memset(zHeader, 0, sizeof(aJournalMagic)+4);
- }
-
- /* The random check-hash initialiser */
- sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
- put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
- /* The initial database size */
- put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize);
- /* The assumed sector size for this process */
- put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
-
- /* The page size */
- put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
-
- /* Initializing the tail of the buffer is not necessary. Everything
- ** works find if the following memset() is omitted. But initializing
- ** the memory prevents valgrind from complaining, so we are willing to
- ** take the performance hit.
- */
- memset(&zHeader[sizeof(aJournalMagic)+20], 0,
- nHeader-(sizeof(aJournalMagic)+20));
-
- /* In theory, it is only necessary to write the 28 bytes that the
- ** journal header consumes to the journal file here. Then increment the
- ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next
- ** record is written to the following sector (leaving a gap in the file
- ** that will be implicitly filled in by the OS).
- **
- ** However it has been discovered that on some systems this pattern can
- ** be significantly slower than contiguously writing data to the file,
- ** even if that means explicitly writing data to the block of
- ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what
- ** is done.
- **
- ** The loop is required here in case the sector-size is larger than the
- ** database page size. Since the zHeader buffer is only Pager.pageSize
- ** bytes in size, more than one call to sqlite3OsWrite() may be required
- ** to populate the entire journal header sector.
- */
- for(nWrite=0; rc==SQLITE_OK&&nWrite<JOURNAL_HDR_SZ(pPager); nWrite+=nHeader){
- IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, nHeader))
- rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff);
- assert( pPager->journalHdr <= pPager->journalOff );
- pPager->journalOff += nHeader;
- }
-
- return rc;
-}
-
-/*
-** The journal file must be open when this is called. A journal header file
-** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
-** file. The current location in the journal file is given by
-** pPager->journalOff. See comments above function writeJournalHdr() for
-** a description of the journal header format.
-**
-** If the header is read successfully, *pNRec is set to the number of
-** page records following this header and *pDbSize is set to the size of the
-** database before the transaction began, in pages. Also, pPager->cksumInit
-** is set to the value read from the journal header. SQLITE_OK is returned
-** in this case.
-**
-** If the journal header file appears to be corrupted, SQLITE_DONE is
-** returned and *pNRec and *PDbSize are undefined. If JOURNAL_HDR_SZ bytes
-** cannot be read from the journal file an error code is returned.
-*/
-static int readJournalHdr(
- Pager *pPager, /* Pager object */
- int isHot,
- i64 journalSize, /* Size of the open journal file in bytes */
- u32 *pNRec, /* OUT: Value read from the nRec field */
- u32 *pDbSize /* OUT: Value of original database size field */
-){
- int rc; /* Return code */
- unsigned char aMagic[8]; /* A buffer to hold the magic header */
- i64 iHdrOff; /* Offset of journal header being read */
-
- assert( isOpen(pPager->jfd) ); /* Journal file must be open. */
-
- /* Advance Pager.journalOff to the start of the next sector. If the
- ** journal file is too small for there to be a header stored at this
- ** point, return SQLITE_DONE.
- */
- pPager->journalOff = journalHdrOffset(pPager);
- if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
- return SQLITE_DONE;
- }
- iHdrOff = pPager->journalOff;
-
- /* Read in the first 8 bytes of the journal header. If they do not match
- ** the magic string found at the start of each journal header, return
- ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise,
- ** proceed.
- */
- if( isHot || iHdrOff!=pPager->journalHdr ){
- rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff);
- if( rc ){
- return rc;
- }
- if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
- return SQLITE_DONE;
- }
- }
-
- /* Read the first three 32-bit fields of the journal header: The nRec
- ** field, the checksum-initializer and the database size at the start
- ** of the transaction. Return an error code if anything goes wrong.
- */
- if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec))
- || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit))
- || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize))
- ){
- return rc;
- }
-
- if( pPager->journalOff==0 ){
- u32 iPageSize; /* Page-size field of journal header */
- u32 iSectorSize; /* Sector-size field of journal header */
-
- /* Read the page-size and sector-size journal header fields. */
- if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
- || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
- ){
- return rc;
- }
-
- /* Versions of SQLite prior to 3.5.8 set the page-size field of the
- ** journal header to zero. In this case, assume that the Pager.pageSize
- ** variable is already set to the correct page size.
- */
- if( iPageSize==0 ){
- iPageSize = pPager->pageSize;
- }
-
- /* Check that the values read from the page-size and sector-size fields
- ** are within range. To be 'in range', both values need to be a power
- ** of two greater than or equal to 512 or 32, and not greater than their
- ** respective compile time maximum limits.
- */
- if( iPageSize<512 || iSectorSize<32
- || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE
- || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0
- ){
- /* If the either the page-size or sector-size in the journal-header is
- ** invalid, then the process that wrote the journal-header must have
- ** crashed before the header was synced. In this case stop reading
- ** the journal file here.
- */
- return SQLITE_DONE;
- }
-
- /* Update the page-size to match the value read from the journal.
- ** Use a testcase() macro to make sure that malloc failure within
- ** PagerSetPagesize() is tested.
- */
- rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1);
- testcase( rc!=SQLITE_OK );
-
- /* Update the assumed sector-size to match the value used by
- ** the process that created this journal. If this journal was
- ** created by a process other than this one, then this routine
- ** is being called from within pager_playback(). The local value
- ** of Pager.sectorSize is restored at the end of that routine.
- */
- pPager->sectorSize = iSectorSize;
- }
-
- pPager->journalOff += JOURNAL_HDR_SZ(pPager);
- return rc;
-}
-
-
-/*
-** Write the supplied master journal name into the journal file for pager
-** pPager at the current location. The master journal name must be the last
-** thing written to a journal file. If the pager is in full-sync mode, the
-** journal file descriptor is advanced to the next sector boundary before
-** anything is written. The format is:
-**
-** + 4 bytes: PAGER_MJ_PGNO.
-** + N bytes: Master journal filename in utf-8.
-** + 4 bytes: N (length of master journal name in bytes, no nul-terminator).
-** + 4 bytes: Master journal name checksum.
-** + 8 bytes: aJournalMagic[].
-**
-** The master journal page checksum is the sum of the bytes in the master
-** journal name, where each byte is interpreted as a signed 8-bit integer.
-**
-** If zMaster is a NULL pointer (occurs for a single database transaction),
-** this call is a no-op.
-*/
-static int writeMasterJournal(Pager *pPager, const char *zMaster){
- int rc; /* Return code */
- int nMaster; /* Length of string zMaster */
- i64 iHdrOff; /* Offset of header in journal file */
- i64 jrnlSize; /* Size of journal file on disk */
- u32 cksum = 0; /* Checksum of string zMaster */
-
- assert( pPager->setMaster==0 );
- assert( !pagerUseWal(pPager) );
-
- if( !zMaster
- || pPager->journalMode==PAGER_JOURNALMODE_MEMORY
- || pPager->journalMode==PAGER_JOURNALMODE_OFF
- ){
- return SQLITE_OK;
- }
- pPager->setMaster = 1;
- assert( isOpen(pPager->jfd) );
- assert( pPager->journalHdr <= pPager->journalOff );
-
- /* Calculate the length in bytes and the checksum of zMaster */
- for(nMaster=0; zMaster[nMaster]; nMaster++){
- cksum += zMaster[nMaster];
- }
-
- /* If in full-sync mode, advance to the next disk sector before writing
- ** the master journal name. This is in case the previous page written to
- ** the journal has already been synced.
- */
- if( pPager->fullSync ){
- pPager->journalOff = journalHdrOffset(pPager);
- }
- iHdrOff = pPager->journalOff;
-
- /* Write the master journal data to the end of the journal file. If
- ** an error occurs, return the error code to the caller.
- */
- if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
- || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4)))
- || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
- || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
- || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
- ){
- return rc;
- }
- pPager->journalOff += (nMaster+20);
-
- /* If the pager is in peristent-journal mode, then the physical
- ** journal-file may extend past the end of the master-journal name
- ** and 8 bytes of magic data just written to the file. This is
- ** dangerous because the code to rollback a hot-journal file
- ** will not be able to find the master-journal name to determine
- ** whether or not the journal is hot.
- **
- ** Easiest thing to do in this scenario is to truncate the journal
- ** file to the required size.
- */
- if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))
- && jrnlSize>pPager->journalOff
- ){
- rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff);
- }
- return rc;
-}
-
-/*
-** Find a page in the hash table given its page number. Return
-** a pointer to the page or NULL if the requested page is not
-** already in memory.
-*/
-static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
- PgHdr *p; /* Return value */
-
- /* It is not possible for a call to PcacheFetch() with createFlag==0 to
- ** fail, since no attempt to allocate dynamic memory will be made.
- */
- (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &p);
- return p;
-}
-
-/*
-** Discard the entire contents of the in-memory page-cache.
-*/
-static void pager_reset(Pager *pPager){
- sqlite3BackupRestart(pPager->pBackup);
- sqlite3PcacheClear(pPager->pPCache);
-}
-
-/*
-** Free all structures in the Pager.aSavepoint[] array and set both
-** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
-** if it is open and the pager is not in exclusive mode.
-*/
-static void releaseAllSavepoints(Pager *pPager){
- int ii; /* Iterator for looping through Pager.aSavepoint */
- for(ii=0; ii<pPager->nSavepoint; ii++){
- sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
- }
- if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
- sqlite3OsClose(pPager->sjfd);
- }
- sqlite3_free(pPager->aSavepoint);
- pPager->aSavepoint = 0;
- pPager->nSavepoint = 0;
- pPager->nSubRec = 0;
-}
-
-/*
-** Set the bit number pgno in the PagerSavepoint.pInSavepoint
-** bitvecs of all open savepoints. Return SQLITE_OK if successful
-** or SQLITE_NOMEM if a malloc failure occurs.
-*/
-static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
- int ii; /* Loop counter */
- int rc = SQLITE_OK; /* Result code */
-
- for(ii=0; ii<pPager->nSavepoint; ii++){
- PagerSavepoint *p = &pPager->aSavepoint[ii];
- if( pgno<=p->nOrig ){
- rc |= sqlite3BitvecSet(p->pInSavepoint, pgno);
- testcase( rc==SQLITE_NOMEM );
- assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
- }
- }
- return rc;
-}
-
-/*
-** This function is a no-op if the pager is in exclusive mode and not
-** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN
-** state.
-**
-** If the pager is not in exclusive-access mode, the database file is
-** completely unlocked. If the file is unlocked and the file-system does
-** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is
-** closed (if it is open).
-**
-** If the pager is in ERROR state when this function is called, the
-** contents of the pager cache are discarded before switching back to
-** the OPEN state. Regardless of whether the pager is in exclusive-mode
-** or not, any journal file left in the file-system will be treated
-** as a hot-journal and rolled back the next time a read-transaction
-** is opened (by this or by any other connection).
-*/
-static void pager_unlock(Pager *pPager){
-
- assert( pPager->eState==PAGER_READER
- || pPager->eState==PAGER_OPEN
- || pPager->eState==PAGER_ERROR
- );
-
- sqlite3BitvecDestroy(pPager->pInJournal);
- pPager->pInJournal = 0;
- releaseAllSavepoints(pPager);
-
- if( pagerUseWal(pPager) ){
- assert( !isOpen(pPager->jfd) );
- sqlite3WalEndReadTransaction(pPager->pWal);
- pPager->eState = PAGER_OPEN;
- }else if( !pPager->exclusiveMode ){
- int rc; /* Error code returned by pagerUnlockDb() */
- int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
-
- /* If the operating system support deletion of open files, then
- ** close the journal file when dropping the database lock. Otherwise
- ** another connection with journal_mode=delete might delete the file
- ** out from under us.
- */
- assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 );
- assert( (PAGER_JOURNALMODE_OFF & 5)!=1 );
- assert( (PAGER_JOURNALMODE_WAL & 5)!=1 );
- assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 );
- assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
- assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
- if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
- || 1!=(pPager->journalMode & 5)
- ){
- sqlite3OsClose(pPager->jfd);
- }
-
- /* If the pager is in the ERROR state and the call to unlock the database
- ** file fails, set the current lock to UNKNOWN_LOCK. See the comment
- ** above the #define for UNKNOWN_LOCK for an explanation of why this
- ** is necessary.
- */
- rc = pagerUnlockDb(pPager, NO_LOCK);
- if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){
- pPager->eLock = UNKNOWN_LOCK;
- }
-
- /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here
- ** without clearing the error code. This is intentional - the error
- ** code is cleared and the cache reset in the block below.
- */
- assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
- pPager->changeCountDone = 0;
- pPager->eState = PAGER_OPEN;
- }
-
- /* If Pager.errCode is set, the contents of the pager cache cannot be
- ** trusted. Now that there are no outstanding references to the pager,
- ** it can safely move back to PAGER_OPEN state. This happens in both
- ** normal and exclusive-locking mode.
- */
- if( pPager->errCode ){
- assert( !MEMDB );
- pager_reset(pPager);
- pPager->changeCountDone = pPager->tempFile;
- pPager->eState = PAGER_OPEN;
- pPager->errCode = SQLITE_OK;
- }
-
- pPager->journalOff = 0;
- pPager->journalHdr = 0;
- pPager->setMaster = 0;
-}
-
-/*
-** This function is called whenever an IOERR or FULL error that requires
-** the pager to transition into the ERROR state may ahve occurred.
-** The first argument is a pointer to the pager structure, the second
-** the error-code about to be returned by a pager API function. The
-** value returned is a copy of the second argument to this function.
-**
-** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the
-** IOERR sub-codes, the pager enters the ERROR state and the error code
-** is stored in Pager.errCode. While the pager remains in the ERROR state,
-** all major API calls on the Pager will immediately return Pager.errCode.
-**
-** The ERROR state indicates that the contents of the pager-cache
-** cannot be trusted. This state can be cleared by completely discarding
-** the contents of the pager-cache. If a transaction was active when
-** the persistent error occurred, then the rollback journal may need
-** to be replayed to restore the contents of the database file (as if
-** it were a hot-journal).
-*/
-static int pager_error(Pager *pPager, int rc){
- int rc2 = rc & 0xff;
- assert( rc==SQLITE_OK || !MEMDB );
- assert(
- pPager->errCode==SQLITE_FULL ||
- pPager->errCode==SQLITE_OK ||
- (pPager->errCode & 0xff)==SQLITE_IOERR
- );
- if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
- pPager->errCode = rc;
- pPager->eState = PAGER_ERROR;
- }
- return rc;
-}
-
-/*
-** This routine ends a transaction. A transaction is usually ended by
-** either a COMMIT or a ROLLBACK operation. This routine may be called
-** after rollback of a hot-journal, or if an error occurs while opening
-** the journal file or writing the very first journal-header of a
-** database transaction.
-**
-** This routine is never called in PAGER_ERROR state. If it is called
-** in PAGER_NONE or PAGER_SHARED state and the lock held is less
-** exclusive than a RESERVED lock, it is a no-op.
-**
-** Otherwise, any active savepoints are released.
-**
-** If the journal file is open, then it is "finalized". Once a journal
-** file has been finalized it is not possible to use it to roll back a
-** transaction. Nor will it be considered to be a hot-journal by this
-** or any other database connection. Exactly how a journal is finalized
-** depends on whether or not the pager is running in exclusive mode and
-** the current journal-mode (Pager.journalMode value), as follows:
-**
-** journalMode==MEMORY
-** Journal file descriptor is simply closed. This destroys an
-** in-memory journal.
-**
-** journalMode==TRUNCATE
-** Journal file is truncated to zero bytes in size.
-**
-** journalMode==PERSIST
-** The first 28 bytes of the journal file are zeroed. This invalidates
-** the first journal header in the file, and hence the entire journal
-** file. An invalid journal file cannot be rolled back.
-**
-** journalMode==DELETE
-** The journal file is closed and deleted using sqlite3OsDelete().
-**
-** If the pager is running in exclusive mode, this method of finalizing
-** the journal file is never used. Instead, if the journalMode is
-** DELETE and the pager is in exclusive mode, the method described under
-** journalMode==PERSIST is used instead.
-**
-** After the journal is finalized, the pager moves to PAGER_READER state.
-** If running in non-exclusive rollback mode, the lock on the file is
-** downgraded to a SHARED_LOCK.
-**
-** SQLITE_OK is returned if no error occurs. If an error occurs during
-** any of the IO operations to finalize the journal file or unlock the
-** database then the IO error code is returned to the user. If the
-** operation to finalize the journal file fails, then the code still
-** tries to unlock the database file if not in exclusive mode. If the
-** unlock operation fails as well, then the first error code related
-** to the first error encountered (the journal finalization one) is
-** returned.
-*/
-static int pager_end_transaction(Pager *pPager, int hasMaster){
- int rc = SQLITE_OK; /* Error code from journal finalization operation */
- int rc2 = SQLITE_OK; /* Error code from db file unlock operation */
-
- /* Do nothing if the pager does not have an open write transaction
- ** or at least a RESERVED lock. This function may be called when there
- ** is no write-transaction active but a RESERVED or greater lock is
- ** held under two circumstances:
- **
- ** 1. After a successful hot-journal rollback, it is called with
- ** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK.
- **
- ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE
- ** lock switches back to locking_mode=normal and then executes a
- ** read-transaction, this function is called with eState==PAGER_READER
- ** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed.
- */
- assert( assert_pager_state(pPager) );
- assert( pPager->eState!=PAGER_ERROR );
- if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){
- return SQLITE_OK;
- }
-
- releaseAllSavepoints(pPager);
- assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
- if( isOpen(pPager->jfd) ){
- assert( !pagerUseWal(pPager) );
-
- /* Finalize the journal file. */
- if( sqlite3IsMemJournal(pPager->jfd) ){
- assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
- sqlite3OsClose(pPager->jfd);
- }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
- if( pPager->journalOff==0 ){
- rc = SQLITE_OK;
- }else{
- rc = sqlite3OsTruncate(pPager->jfd, 0);
- }
- pPager->journalOff = 0;
- }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
- || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
- ){
- rc = zeroJournalHdr(pPager, hasMaster);
- pPager->journalOff = 0;
- }else{
- /* This branch may be executed with Pager.journalMode==MEMORY if
- ** a hot-journal was just rolled back. In this case the journal
- ** file should be closed and deleted. If this connection writes to
- ** the database file, it will do so using an in-memory journal.
- */
- int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
- assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE
- || pPager->journalMode==PAGER_JOURNALMODE_MEMORY
- || pPager->journalMode==PAGER_JOURNALMODE_WAL
- );
- sqlite3OsClose(pPager->jfd);
- if( bDelete ){
- rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
- }
- }
- }
-
-#ifdef SQLITE_CHECK_PAGES
- sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
- if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
- PgHdr *p = pager_lookup(pPager, 1);
- if( p ){
- p->pageHash = 0;
- sqlite3PagerUnref(p);
- }
- }
-#endif
-
- sqlite3BitvecDestroy(pPager->pInJournal);
- pPager->pInJournal = 0;
- pPager->nRec = 0;
- sqlite3PcacheCleanAll(pPager->pPCache);
- sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
-
- if( pagerUseWal(pPager) ){
- /* Drop the WAL write-lock, if any. Also, if the connection was in
- ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE
- ** lock held on the database file.
- */
- rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
- assert( rc2==SQLITE_OK );
- }
- if( !pPager->exclusiveMode
- && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
- ){
- rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
- pPager->changeCountDone = 0;
- }
- pPager->eState = PAGER_READER;
- pPager->setMaster = 0;
-
- return (rc==SQLITE_OK?rc2:rc);
-}
-
-/*
-** Execute a rollback if a transaction is active and unlock the
-** database file.
-**
-** If the pager has already entered the ERROR state, do not attempt
-** the rollback at this time. Instead, pager_unlock() is called. The
-** call to pager_unlock() will discard all in-memory pages, unlock
-** the database file and move the pager back to OPEN state. If this
-** means that there is a hot-journal left in the file-system, the next
-** connection to obtain a shared lock on the pager (which may be this one)
-** will roll it back.
-**
-** If the pager has not already entered the ERROR state, but an IO or
-** malloc error occurs during a rollback, then this will itself cause
-** the pager to enter the ERROR state. Which will be cleared by the
-** call to pager_unlock(), as described above.
-*/
-static void pagerUnlockAndRollback(Pager *pPager){
- if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){
- assert( assert_pager_state(pPager) );
- if( pPager->eState>=PAGER_WRITER_LOCKED ){
- sqlite3BeginBenignMalloc();
- sqlite3PagerRollback(pPager);
- sqlite3EndBenignMalloc();
- }else if( !pPager->exclusiveMode ){
- assert( pPager->eState==PAGER_READER );
- pager_end_transaction(pPager, 0);
- }
- }
- pager_unlock(pPager);
-}
-
-/*
-** Parameter aData must point to a buffer of pPager->pageSize bytes
-** of data. Compute and return a checksum based ont the contents of the
-** page of data and the current value of pPager->cksumInit.
-**
-** This is not a real checksum. It is really just the sum of the
-** random initial value (pPager->cksumInit) and every 200th byte
-** of the page data, starting with byte offset (pPager->pageSize%200).
-** Each byte is interpreted as an 8-bit unsigned integer.
-**
-** Changing the formula used to compute this checksum results in an
-** incompatible journal file format.
-**
-** If journal corruption occurs due to a power failure, the most likely
-** scenario is that one end or the other of the record will be changed.
-** It is much less likely that the two ends of the journal record will be
-** correct and the middle be corrupt. Thus, this "checksum" scheme,
-** though fast and simple, catches the mostly likely kind of corruption.
-*/
-static u32 pager_cksum(Pager *pPager, const u8 *aData){
- u32 cksum = pPager->cksumInit; /* Checksum value to return */
- int i = pPager->pageSize-200; /* Loop counter */
- while( i>0 ){
- cksum += aData[i];
- i -= 200;
- }
- return cksum;
-}
-
-/*
-** Report the current page size and number of reserved bytes back
-** to the codec.
-*/
-#ifdef SQLITE_HAS_CODEC
-static void pagerReportSize(Pager *pPager){
- if( pPager->xCodecSizeChng ){
- pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
- (int)pPager->nReserve);
- }
-}
-#else
-# define pagerReportSize(X) /* No-op if we do not support a codec */
-#endif
-
-/*
-** Read a single page from either the journal file (if isMainJrnl==1) or
-** from the sub-journal (if isMainJrnl==0) and playback that page.
-** The page begins at offset *pOffset into the file. The *pOffset
-** value is increased to the start of the next page in the journal.
-**
-** The main rollback journal uses checksums - the statement journal does
-** not.
-**
-** If the page number of the page record read from the (sub-)journal file
-** is greater than the current value of Pager.dbSize, then playback is
-** skipped and SQLITE_OK is returned.
-**
-** If pDone is not NULL, then it is a record of pages that have already
-** been played back. If the page at *pOffset has already been played back
-** (if the corresponding pDone bit is set) then skip the playback.
-** Make sure the pDone bit corresponding to the *pOffset page is set
-** prior to returning.
-**
-** If the page record is successfully read from the (sub-)journal file
-** and played back, then SQLITE_OK is returned. If an IO error occurs
-** while reading the record from the (sub-)journal file or while writing
-** to the database file, then the IO error code is returned. If data
-** is successfully read from the (sub-)journal file but appears to be
-** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
-** two circumstances:
-**
-** * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
-** * If the record is being rolled back from the main journal file
-** and the checksum field does not match the record content.
-**
-** Neither of these two scenarios are possible during a savepoint rollback.
-**
-** If this is a savepoint rollback, then memory may have to be dynamically
-** allocated by this function. If this is the case and an allocation fails,
-** SQLITE_NOMEM is returned.
-*/
-static int pager_playback_one_page(
- Pager *pPager, /* The pager being played back */
- i64 *pOffset, /* Offset of record to playback */
- Bitvec *pDone, /* Bitvec of pages already played back */
- int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */
- int isSavepnt /* True for a savepoint rollback */
-){
- int rc;
- PgHdr *pPg; /* An existing page in the cache */
- Pgno pgno; /* The page number of a page in journal */
- u32 cksum; /* Checksum used for sanity checking */
- char *aData; /* Temporary storage for the page */
- sqlite3_file *jfd; /* The file descriptor for the journal file */
- int isSynced; /* True if journal page is synced */
-
- assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */
- assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */
- assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */
- assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */
-
- aData = pPager->pTmpSpace;
- assert( aData ); /* Temp storage must have already been allocated */
- assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) );
-
- /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction
- ** or savepoint rollback done at the request of the caller) or this is
- ** a hot-journal rollback. If it is a hot-journal rollback, the pager
- ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback
- ** only reads from the main journal, not the sub-journal.
- */
- assert( pPager->eState>=PAGER_WRITER_CACHEMOD
- || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK)
- );
- assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl );
-
- /* Read the page number and page data from the journal or sub-journal
- ** file. Return an error code to the caller if an IO error occurs.
- */
- jfd = isMainJrnl ? pPager->jfd : pPager->sjfd;
- rc = read32bits(jfd, *pOffset, &pgno);
- if( rc!=SQLITE_OK ) return rc;
- rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4);
- if( rc!=SQLITE_OK ) return rc;
- *pOffset += pPager->pageSize + 4 + isMainJrnl*4;
-
- /* Sanity checking on the page. This is more important that I originally
- ** thought. If a power failure occurs while the journal is being written,
- ** it could cause invalid data to be written into the journal. We need to
- ** detect this invalid data (with high probability) and ignore it.
- */
- if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
- assert( !isSavepnt );
- return SQLITE_DONE;
- }
- if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
- return SQLITE_OK;
- }
- if( isMainJrnl ){
- rc = read32bits(jfd, (*pOffset)-4, &cksum);
- if( rc ) return rc;
- if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){
- return SQLITE_DONE;
- }
- }
-
- /* If this page has already been played by before during the current
- ** rollback, then don't bother to play it back again.
- */
- if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
- return rc;
- }
-
- /* When playing back page 1, restore the nReserve setting
- */
- if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
- pPager->nReserve = ((u8*)aData)[20];
- pagerReportSize(pPager);
- }
-
- /* If the pager is in CACHEMOD state, then there must be a copy of this
- ** page in the pager cache. In this case just update the pager cache,
- ** not the database file. The page is left marked dirty in this case.
- **
- ** An exception to the above rule: If the database is in no-sync mode
- ** and a page is moved during an incremental vacuum then the page may
- ** not be in the pager cache. Later: if a malloc() or IO error occurs
- ** during a Movepage() call, then the page may not be in the cache
- ** either. So the condition described in the above paragraph is not
- ** assert()able.
- **
- ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the
- ** pager cache if it exists and the main file. The page is then marked
- ** not dirty. Since this code is only executed in PAGER_OPEN state for
- ** a hot-journal rollback, it is guaranteed that the page-cache is empty
- ** if the pager is in OPEN state.
- **
- ** Ticket #1171: The statement journal might contain page content that is
- ** different from the page content at the start of the transaction.
- ** This occurs when a page is changed prior to the start of a statement
- ** then changed again within the statement. When rolling back such a
- ** statement we must not write to the original database unless we know
- ** for certain that original page contents are synced into the main rollback
- ** journal. Otherwise, a power loss might leave modified data in the
- ** database file without an entry in the rollback journal that can
- ** restore the database to its original form. Two conditions must be
- ** met before writing to the database files. (1) the database must be
- ** locked. (2) we know that the original page content is fully synced
- ** in the main journal either because the page is not in cache or else
- ** the page is marked as needSync==0.
- **
- ** 2008-04-14: When attempting to vacuum a corrupt database file, it
- ** is possible to fail a statement on a database that does not yet exist.
- ** Do not attempt to write if database file has never been opened.
- */
- if( pagerUseWal(pPager) ){
- pPg = 0;
- }else{
- pPg = pager_lookup(pPager, pgno);
- }
- assert( pPg || !MEMDB );
- assert( pPager->eState!=PAGER_OPEN || pPg==0 );
- PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
- PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
- (isMainJrnl?"main-journal":"sub-journal")
- ));
- if( isMainJrnl ){
- isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr);
- }else{
- isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC));
- }
- if( isOpen(pPager->fd)
- && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
- && isSynced
- ){
- i64 ofst = (pgno-1)*(i64)pPager->pageSize;
- testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
- assert( !pagerUseWal(pPager) );
- rc = sqlite3OsWrite(pPager->fd, (u8*)aData, pPager->pageSize, ofst);
- if( pgno>pPager->dbFileSize ){
- pPager->dbFileSize = pgno;
- }
- if( pPager->pBackup ){
- CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
- sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
- CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
- }
- }else if( !isMainJrnl && pPg==0 ){
- /* If this is a rollback of a savepoint and data was not written to
- ** the database and the page is not in-memory, there is a potential
- ** problem. When the page is next fetched by the b-tree layer, it
- ** will be read from the database file, which may or may not be
- ** current.
- **
- ** There are a couple of different ways this can happen. All are quite
- ** obscure. When running in synchronous mode, this can only happen
- ** if the page is on the free-list at the start of the transaction, then
- ** populated, then moved using sqlite3PagerMovepage().
- **
- ** The solution is to add an in-memory page to the cache containing
- ** the data just read from the sub-journal. Mark the page as dirty
- ** and if the pager requires a journal-sync, then mark the page as
- ** requiring a journal-sync before it is written.
- */
- assert( isSavepnt );
- assert( pPager->doNotSpill==0 );
- pPager->doNotSpill++;
- rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
- assert( pPager->doNotSpill==1 );
- pPager->doNotSpill--;
- if( rc!=SQLITE_OK ) return rc;
- pPg->flags &= ~PGHDR_NEED_READ;
- sqlite3PcacheMakeDirty(pPg);
- }
- if( pPg ){
- /* No page should ever be explicitly rolled back that is in use, except
- ** for page 1 which is held in use in order to keep the lock on the
- ** database active. However such a page may be rolled back as a result
- ** of an internal error resulting in an automatic call to
- ** sqlite3PagerRollback().
- */
- void *pData;
- pData = pPg->pData;
- memcpy(pData, (u8*)aData, pPager->pageSize);
- pPager->xReiniter(pPg);
- if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
- /* If the contents of this page were just restored from the main
- ** journal file, then its content must be as they were when the
- ** transaction was first opened. In this case we can mark the page
- ** as clean, since there will be no need to write it out to the
- ** database.
- **
- ** There is one exception to this rule. If the page is being rolled
- ** back as part of a savepoint (or statement) rollback from an
- ** unsynced portion of the main journal file, then it is not safe
- ** to mark the page as clean. This is because marking the page as
- ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is
- ** already in the journal file (recorded in Pager.pInJournal) and
- ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to
- ** again within this transaction, it will be marked as dirty but
- ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially
- ** be written out into the database file before its journal file
- ** segment is synced. If a crash occurs during or following this,
- ** database corruption may ensue.
- */
- assert( !pagerUseWal(pPager) );
- sqlite3PcacheMakeClean(pPg);
- }
- pager_set_pagehash(pPg);
-
- /* If this was page 1, then restore the value of Pager.dbFileVers.
- ** Do this before any decoding. */
- if( pgno==1 ){
- memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
- }
-
- /* Decode the page just read from disk */
- CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
- sqlite3PcacheRelease(pPg);
- }
- return rc;
-}
-
-/*
-** Parameter zMaster is the name of a master journal file. A single journal
-** file that referred to the master journal file has just been rolled back.
-** This routine checks if it is possible to delete the master journal file,
-** and does so if it is.
-**
-** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not
-** available for use within this function.
-**
-** When a master journal file is created, it is populated with the names
-** of all of its child journals, one after another, formatted as utf-8
-** encoded text. The end of each child journal file is marked with a
-** nul-terminator byte (0x00). i.e. the entire contents of a master journal
-** file for a transaction involving two databases might be:
-**
-** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00"
-**
-** A master journal file may only be deleted once all of its child
-** journals have been rolled back.
-**
-** This function reads the contents of the master-journal file into
-** memory and loops through each of the child journal names. For
-** each child journal, it checks if:
-**
-** * if the child journal exists, and if so
-** * if the child journal contains a reference to master journal
-** file zMaster
-**
-** If a child journal can be found that matches both of the criteria
-** above, this function returns without doing anything. Otherwise, if
-** no such child journal can be found, file zMaster is deleted from
-** the file-system using sqlite3OsDelete().
-**
-** If an IO error within this function, an error code is returned. This
-** function allocates memory by calling sqlite3Malloc(). If an allocation
-** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors
-** occur, SQLITE_OK is returned.
-**
-** TODO: This function allocates a single block of memory to load
-** the entire contents of the master journal file. This could be
-** a couple of kilobytes or so - potentially larger than the page
-** size.
-*/
-static int pager_delmaster(Pager *pPager, const char *zMaster){
- sqlite3_vfs *pVfs = pPager->pVfs;
- int rc; /* Return code */
- sqlite3_file *pMaster; /* Malloc'd master-journal file descriptor */
- sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */
- char *zMasterJournal = 0; /* Contents of master journal file */
- i64 nMasterJournal; /* Size of master journal file */
- char *zJournal; /* Pointer to one journal within MJ file */
- char *zMasterPtr; /* Space to hold MJ filename from a journal file */
- int nMasterPtr; /* Amount of space allocated to zMasterPtr[] */
-
- /* Allocate space for both the pJournal and pMaster file descriptors.
- ** If successful, open the master journal file for reading.
- */
- pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
- pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
- if( !pMaster ){
- rc = SQLITE_NOMEM;
- }else{
- const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
- rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
- }
- if( rc!=SQLITE_OK ) goto delmaster_out;
-
- /* Load the entire master journal file into space obtained from
- ** sqlite3_malloc() and pointed to by zMasterJournal. Also obtain
- ** sufficient space (in zMasterPtr) to hold the names of master
- ** journal files extracted from regular rollback-journals.
- */
- rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
- if( rc!=SQLITE_OK ) goto delmaster_out;
- nMasterPtr = pVfs->mxPathname+1;
- zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1);
- if( !zMasterJournal ){
- rc = SQLITE_NOMEM;
- goto delmaster_out;
- }
- zMasterPtr = &zMasterJournal[nMasterJournal+1];
- rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
- if( rc!=SQLITE_OK ) goto delmaster_out;
- zMasterJournal[nMasterJournal] = 0;
-
- zJournal = zMasterJournal;
- while( (zJournal-zMasterJournal)<nMasterJournal ){
- int exists;
- rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
- if( rc!=SQLITE_OK ){
- goto delmaster_out;
- }
- if( exists ){
- /* One of the journals pointed to by the master journal exists.
- ** Open it and check if it points at the master journal. If
- ** so, return without deleting the master journal file.
- */
- int c;
- int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
- rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
- if( rc!=SQLITE_OK ){
- goto delmaster_out;
- }
-
- rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
- sqlite3OsClose(pJournal);
- if( rc!=SQLITE_OK ){
- goto delmaster_out;
- }
-
- c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
- if( c ){
- /* We have a match. Do not delete the master journal file. */
- goto delmaster_out;
- }
- }
- zJournal += (sqlite3Strlen30(zJournal)+1);
- }
-
- sqlite3OsClose(pMaster);
- rc = sqlite3OsDelete(pVfs, zMaster, 0);
-
-delmaster_out:
- sqlite3_free(zMasterJournal);
- if( pMaster ){
- sqlite3OsClose(pMaster);
- assert( !isOpen(pJournal) );
- sqlite3_free(pMaster);
- }
- return rc;
-}
-
-
-/*
-** This function is used to change the actual size of the database
-** file in the file-system. This only happens when committing a transaction,
-** or rolling back a transaction (including rolling back a hot-journal).
-**
-** If the main database file is not open, or the pager is not in either
-** DBMOD or OPEN state, this function is a no-op. Otherwise, the size
-** of the file is changed to nPage pages (nPage*pPager->pageSize bytes).
-** If the file on disk is currently larger than nPage pages, then use the VFS
-** xTruncate() method to truncate it.
-**
-** Or, it might might be the case that the file on disk is smaller than
-** nPage pages. Some operating system implementations can get confused if
-** you try to truncate a file to some size that is larger than it
-** currently is, so detect this case and write a single zero byte to
-** the end of the new file instead.
-**
-** If successful, return SQLITE_OK. If an IO error occurs while modifying
-** the database file, return the error code to the caller.
-*/
-static int pager_truncate(Pager *pPager, Pgno nPage){
- int rc = SQLITE_OK;
- assert( pPager->eState!=PAGER_ERROR );
- assert( pPager->eState!=PAGER_READER );
-
- if( isOpen(pPager->fd)
- && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
- ){
- i64 currentSize, newSize;
- int szPage = pPager->pageSize;
- assert( pPager->eLock==EXCLUSIVE_LOCK );
- /* TODO: Is it safe to use Pager.dbFileSize here? */
- rc = sqlite3OsFileSize(pPager->fd, &currentSize);
- newSize = szPage*(i64)nPage;
- if( rc==SQLITE_OK && currentSize!=newSize ){
- if( currentSize>newSize ){
- rc = sqlite3OsTruncate(pPager->fd, newSize);
- }else if( (currentSize+szPage)<=newSize ){
- char *pTmp = pPager->pTmpSpace;
- memset(pTmp, 0, szPage);
- testcase( (newSize-szPage) == currentSize );
- testcase( (newSize-szPage) > currentSize );
- rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
- }
- if( rc==SQLITE_OK ){
- pPager->dbFileSize = nPage;
- }
- }
- }
- return rc;
-}
-
-/*
-** Return a sanitized version of the sector-size of OS file pFile. The
-** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE.
-*/
-SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){
- int iRet = sqlite3OsSectorSize(pFile);
- if( iRet<32 ){
- iRet = 512;
- }else if( iRet>MAX_SECTOR_SIZE ){
- assert( MAX_SECTOR_SIZE>=512 );
- iRet = MAX_SECTOR_SIZE;
- }
- return iRet;
-}
-
-/*
-** Set the value of the Pager.sectorSize variable for the given
-** pager based on the value returned by the xSectorSize method
-** of the open database file. The sector size will be used used
-** to determine the size and alignment of journal header and
-** master journal pointers within created journal files.
-**
-** For temporary files the effective sector size is always 512 bytes.
-**
-** Otherwise, for non-temporary files, the effective sector size is
-** the value returned by the xSectorSize() method rounded up to 32 if
-** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it
-** is greater than MAX_SECTOR_SIZE.
-**
-** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set
-** the effective sector size to its minimum value (512). The purpose of
-** pPager->sectorSize is to define the "blast radius" of bytes that
-** might change if a crash occurs while writing to a single byte in
-** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero
-** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector
-** size. For backwards compatibility of the rollback journal file format,
-** we cannot reduce the effective sector size below 512.
-*/
-static void setSectorSize(Pager *pPager){
- assert( isOpen(pPager->fd) || pPager->tempFile );
-
- if( pPager->tempFile
- || (sqlite3OsDeviceCharacteristics(pPager->fd) &
- SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0
- ){
- /* Sector size doesn't matter for temporary files. Also, the file
- ** may not have been opened yet, in which case the OsSectorSize()
- ** call will segfault. */
- pPager->sectorSize = 512;
- }else{
- pPager->sectorSize = sqlite3SectorSize(pPager->fd);
- }
-}
-
-/*
-** Playback the journal and thus restore the database file to
-** the state it was in before we started making changes.
-**
-** The journal file format is as follows:
-**
-** (1) 8 byte prefix. A copy of aJournalMagic[].
-** (2) 4 byte big-endian integer which is the number of valid page records
-** in the journal. If this value is 0xffffffff, then compute the
-** number of page records from the journal size.
-** (3) 4 byte big-endian integer which is the initial value for the
-** sanity checksum.
-** (4) 4 byte integer which is the number of pages to truncate the
-** database to during a rollback.
-** (5) 4 byte big-endian integer which is the sector size. The header
-** is this many bytes in size.
-** (6) 4 byte big-endian integer which is the page size.
-** (7) zero padding out to the next sector size.
-** (8) Zero or more pages instances, each as follows:
-** + 4 byte page number.
-** + pPager->pageSize bytes of data.
-** + 4 byte checksum
-**
-** When we speak of the journal header, we mean the first 7 items above.
-** Each entry in the journal is an instance of the 8th item.
-**
-** Call the value from the second bullet "nRec". nRec is the number of
-** valid page entries in the journal. In most cases, you can compute the
-** value of nRec from the size of the journal file. But if a power
-** failure occurred while the journal was being written, it could be the
-** case that the size of the journal file had already been increased but
-** the extra entries had not yet made it safely to disk. In such a case,
-** the value of nRec computed from the file size would be too large. For
-** that reason, we always use the nRec value in the header.
-**
-** If the nRec value is 0xffffffff it means that nRec should be computed
-** from the file size. This value is used when the user selects the
-** no-sync option for the journal. A power failure could lead to corruption
-** in this case. But for things like temporary table (which will be
-** deleted when the power is restored) we don't care.
-**
-** If the file opened as the journal file is not a well-formed
-** journal file then all pages up to the first corrupted page are rolled
-** back (or no pages if the journal header is corrupted). The journal file
-** is then deleted and SQLITE_OK returned, just as if no corruption had
-** been encountered.
-**
-** If an I/O or malloc() error occurs, the journal-file is not deleted
-** and an error code is returned.
-**
-** The isHot parameter indicates that we are trying to rollback a journal
-** that might be a hot journal. Or, it could be that the journal is
-** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE.
-** If the journal really is hot, reset the pager cache prior rolling
-** back any content. If the journal is merely persistent, no reset is
-** needed.
-*/
-static int pager_playback(Pager *pPager, int isHot){
- sqlite3_vfs *pVfs = pPager->pVfs;
- i64 szJ; /* Size of the journal file in bytes */
- u32 nRec; /* Number of Records in the journal */
- u32 u; /* Unsigned loop counter */
- Pgno mxPg = 0; /* Size of the original file in pages */
- int rc; /* Result code of a subroutine */
- int res = 1; /* Value returned by sqlite3OsAccess() */
- char *zMaster = 0; /* Name of master journal file if any */
- int needPagerReset; /* True to reset page prior to first page rollback */
-
- /* Figure out how many records are in the journal. Abort early if
- ** the journal is empty.
- */
- assert( isOpen(pPager->jfd) );
- rc = sqlite3OsFileSize(pPager->jfd, &szJ);
- if( rc!=SQLITE_OK ){
- goto end_playback;
- }
-
- /* Read the master journal name from the journal, if it is present.
- ** If a master journal file name is specified, but the file is not
- ** present on disk, then the journal is not hot and does not need to be
- ** played back.
- **
- ** TODO: Technically the following is an error because it assumes that
- ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
- ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
- ** mxPathname is 512, which is the same as the minimum allowable value
- ** for pageSize.
- */
- zMaster = pPager->pTmpSpace;
- rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
- if( rc==SQLITE_OK && zMaster[0] ){
- rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
- }
- zMaster = 0;
- if( rc!=SQLITE_OK || !res ){
- goto end_playback;
- }
- pPager->journalOff = 0;
- needPagerReset = isHot;
-
- /* This loop terminates either when a readJournalHdr() or
- ** pager_playback_one_page() call returns SQLITE_DONE or an IO error
- ** occurs.
- */
- while( 1 ){
- /* Read the next journal header from the journal file. If there are
- ** not enough bytes left in the journal file for a complete header, or
- ** it is corrupted, then a process must have failed while writing it.
- ** This indicates nothing more needs to be rolled back.
- */
- rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- }
- goto end_playback;
- }
-
- /* If nRec is 0xffffffff, then this journal was created by a process
- ** working in no-sync mode. This means that the rest of the journal
- ** file consists of pages, there are no more journal headers. Compute
- ** the value of nRec based on this assumption.
- */
- if( nRec==0xffffffff ){
- assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
- nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager));
- }
-
- /* If nRec is 0 and this rollback is of a transaction created by this
- ** process and if this is the final header in the journal, then it means
- ** that this part of the journal was being filled but has not yet been
- ** synced to disk. Compute the number of pages based on the remaining
- ** size of the file.
- **
- ** The third term of the test was added to fix ticket #2565.
- ** When rolling back a hot journal, nRec==0 always means that the next
- ** chunk of the journal contains zero pages to be rolled back. But
- ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in
- ** the journal, it means that the journal might contain additional
- ** pages that need to be rolled back and that the number of pages
- ** should be computed based on the journal file size.
- */
- if( nRec==0 && !isHot &&
- pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
- nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
- }
-
- /* If this is the first header read from the journal, truncate the
- ** database file back to its original size.
- */
- if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
- rc = pager_truncate(pPager, mxPg);
- if( rc!=SQLITE_OK ){
- goto end_playback;
- }
- pPager->dbSize = mxPg;
- }
-
- /* Copy original pages out of the journal and back into the
- ** database file and/or page cache.
- */
- for(u=0; u<nRec; u++){
- if( needPagerReset ){
- pager_reset(pPager);
- needPagerReset = 0;
- }
- rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_DONE ){
- pPager->journalOff = szJ;
- break;
- }else if( rc==SQLITE_IOERR_SHORT_READ ){
- /* If the journal has been truncated, simply stop reading and
- ** processing the journal. This might happen if the journal was
- ** not completely written and synced prior to a crash. In that
- ** case, the database should have never been written in the
- ** first place so it is OK to simply abandon the rollback. */
- rc = SQLITE_OK;
- goto end_playback;
- }else{
- /* If we are unable to rollback, quit and return the error
- ** code. This will cause the pager to enter the error state
- ** so that no further harm will be done. Perhaps the next
- ** process to come along will be able to rollback the database.
- */
- goto end_playback;
- }
- }
- }
- }
- /*NOTREACHED*/
- assert( 0 );
-
-end_playback:
- /* Following a rollback, the database file should be back in its original
- ** state prior to the start of the transaction, so invoke the
- ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
- ** assertion that the transaction counter was modified.
- */
-#ifdef SQLITE_DEBUG
- if( pPager->fd->pMethods ){
- sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
- }
-#endif
-
- /* If this playback is happening automatically as a result of an IO or
- ** malloc error that occurred after the change-counter was updated but
- ** before the transaction was committed, then the change-counter
- ** modification may just have been reverted. If this happens in exclusive
- ** mode, then subsequent transactions performed by the connection will not
- ** update the change-counter at all. This may lead to cache inconsistency
- ** problems for other processes at some point in the future. So, just
- ** in case this has happened, clear the changeCountDone flag now.
- */
- pPager->changeCountDone = pPager->tempFile;
-
- if( rc==SQLITE_OK ){
- zMaster = pPager->pTmpSpace;
- rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
- testcase( rc!=SQLITE_OK );
- }
- if( rc==SQLITE_OK
- && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
- ){
- rc = sqlite3PagerSync(pPager);
- }
- if( rc==SQLITE_OK ){
- rc = pager_end_transaction(pPager, zMaster[0]!='\0');
- testcase( rc!=SQLITE_OK );
- }
- if( rc==SQLITE_OK && zMaster[0] && res ){
- /* If there was a master journal and this routine will return success,
- ** see if it is possible to delete the master journal.
- */
- rc = pager_delmaster(pPager, zMaster);
- testcase( rc!=SQLITE_OK );
- }
-
- /* The Pager.sectorSize variable may have been updated while rolling
- ** back a journal created by a process with a different sector size
- ** value. Reset it to the correct value for this process.
- */
- setSectorSize(pPager);
- return rc;
-}
-
-
-/*
-** Read the content for page pPg out of the database file and into
-** pPg->pData. A shared lock or greater must be held on the database
-** file before this function is called.
-**
-** If page 1 is read, then the value of Pager.dbFileVers[] is set to
-** the value read from the database file.
-**
-** If an IO error occurs, then the IO error is returned to the caller.
-** Otherwise, SQLITE_OK is returned.
-*/
-static int readDbPage(PgHdr *pPg){
- Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
- Pgno pgno = pPg->pgno; /* Page number to read */
- int rc = SQLITE_OK; /* Return code */
- int isInWal = 0; /* True if page is in log file */
- int pgsz = pPager->pageSize; /* Number of bytes to read */
-
- assert( pPager->eState>=PAGER_READER && !MEMDB );
- assert( isOpen(pPager->fd) );
-
- if( NEVER(!isOpen(pPager->fd)) ){
- assert( pPager->tempFile );
- memset(pPg->pData, 0, pPager->pageSize);
- return SQLITE_OK;
- }
-
- if( pagerUseWal(pPager) ){
- /* Try to pull the page from the write-ahead log. */
- rc = sqlite3WalRead(pPager->pWal, pgno, &isInWal, pgsz, pPg->pData);
- }
- if( rc==SQLITE_OK && !isInWal ){
- i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
- rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
- if( rc==SQLITE_IOERR_SHORT_READ ){
- rc = SQLITE_OK;
- }
- }
-
- if( pgno==1 ){
- if( rc ){
- /* If the read is unsuccessful, set the dbFileVers[] to something
- ** that will never be a valid file version. dbFileVers[] is a copy
- ** of bytes 24..39 of the database. Bytes 28..31 should always be
- ** zero or the size of the database in page. Bytes 32..35 and 35..39
- ** should be page numbers which are never 0xffffffff. So filling
- ** pPager->dbFileVers[] with all 0xff bytes should suffice.
- **
- ** For an encrypted database, the situation is more complex: bytes
- ** 24..39 of the database are white noise. But the probability of
- ** white noising equaling 16 bytes of 0xff is vanishingly small so
- ** we should still be ok.
- */
- memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
- }else{
- u8 *dbFileVers = &((u8*)pPg->pData)[24];
- memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
- }
- }
- CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
-
- PAGER_INCR(sqlite3_pager_readdb_count);
- PAGER_INCR(pPager->nRead);
- IOTRACE(("PGIN %p %d\n", pPager, pgno));
- PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
- PAGERID(pPager), pgno, pager_pagehash(pPg)));
-
- return rc;
-}
-
-/*
-** Update the value of the change-counter at offsets 24 and 92 in
-** the header and the sqlite version number at offset 96.
-**
-** This is an unconditional update. See also the pager_incr_changecounter()
-** routine which only updates the change-counter if the update is actually
-** needed, as determined by the pPager->changeCountDone state variable.
-*/
-static void pager_write_changecounter(PgHdr *pPg){
- u32 change_counter;
-
- /* Increment the value just read and write it back to byte 24. */
- change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
- put32bits(((char*)pPg->pData)+24, change_counter);
-
- /* Also store the SQLite version number in bytes 96..99 and in
- ** bytes 92..95 store the change counter for which the version number
- ** is valid. */
- put32bits(((char*)pPg->pData)+92, change_counter);
- put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER);
-}
-
-#ifndef SQLITE_OMIT_WAL
-/*
-** This function is invoked once for each page that has already been
-** written into the log file when a WAL transaction is rolled back.
-** Parameter iPg is the page number of said page. The pCtx argument
-** is actually a pointer to the Pager structure.
-**
-** If page iPg is present in the cache, and has no outstanding references,
-** it is discarded. Otherwise, if there are one or more outstanding
-** references, the page content is reloaded from the database. If the
-** attempt to reload content from the database is required and fails,
-** return an SQLite error code. Otherwise, SQLITE_OK.
-*/
-static int pagerUndoCallback(void *pCtx, Pgno iPg){
- int rc = SQLITE_OK;
- Pager *pPager = (Pager *)pCtx;
- PgHdr *pPg;
-
- pPg = sqlite3PagerLookup(pPager, iPg);
- if( pPg ){
- if( sqlite3PcachePageRefcount(pPg)==1 ){
- sqlite3PcacheDrop(pPg);
- }else{
- rc = readDbPage(pPg);
- if( rc==SQLITE_OK ){
- pPager->xReiniter(pPg);
- }
- sqlite3PagerUnref(pPg);
- }
- }
-
- /* Normally, if a transaction is rolled back, any backup processes are
- ** updated as data is copied out of the rollback journal and into the
- ** database. This is not generally possible with a WAL database, as
- ** rollback involves simply truncating the log file. Therefore, if one
- ** or more frames have already been written to the log (and therefore
- ** also copied into the backup databases) as part of this transaction,
- ** the backups must be restarted.
- */
- sqlite3BackupRestart(pPager->pBackup);
-
- return rc;
-}
-
-/*
-** This function is called to rollback a transaction on a WAL database.
-*/
-static int pagerRollbackWal(Pager *pPager){
- int rc; /* Return Code */
- PgHdr *pList; /* List of dirty pages to revert */
-
- /* For all pages in the cache that are currently dirty or have already
- ** been written (but not committed) to the log file, do one of the
- ** following:
- **
- ** + Discard the cached page (if refcount==0), or
- ** + Reload page content from the database (if refcount>0).
- */
- pPager->dbSize = pPager->dbOrigSize;
- rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager);
- pList = sqlite3PcacheDirtyList(pPager->pPCache);
- while( pList && rc==SQLITE_OK ){
- PgHdr *pNext = pList->pDirty;
- rc = pagerUndoCallback((void *)pPager, pList->pgno);
- pList = pNext;
- }
-
- return rc;
-}
-
-/*
-** This function is a wrapper around sqlite3WalFrames(). As well as logging
-** the contents of the list of pages headed by pList (connected by pDirty),
-** this function notifies any active backup processes that the pages have
-** changed.
-**
-** The list of pages passed into this routine is always sorted by page number.
-** Hence, if page 1 appears anywhere on the list, it will be the first page.
-*/
-static int pagerWalFrames(
- Pager *pPager, /* Pager object */
- PgHdr *pList, /* List of frames to log */
- Pgno nTruncate, /* Database size after this commit */
- int isCommit /* True if this is a commit */
-){
- int rc; /* Return code */
- int nList; /* Number of pages in pList */
-#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
- PgHdr *p; /* For looping over pages */
-#endif
-
- assert( pPager->pWal );
- assert( pList );
-#ifdef SQLITE_DEBUG
- /* Verify that the page list is in accending order */
- for(p=pList; p && p->pDirty; p=p->pDirty){
- assert( p->pgno < p->pDirty->pgno );
- }
-#endif
-
- assert( pList->pDirty==0 || isCommit );
- if( isCommit ){
- /* If a WAL transaction is being committed, there is no point in writing
- ** any pages with page numbers greater than nTruncate into the WAL file.
- ** They will never be read by any client. So remove them from the pDirty
- ** list here. */
- PgHdr *p;
- PgHdr **ppNext = &pList;
- nList = 0;
- for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
- if( p->pgno<=nTruncate ){
- ppNext = &p->pDirty;
- nList++;
- }
- }
- assert( pList );
- }else{
- nList = 1;
- }
- pPager->aStat[PAGER_STAT_WRITE] += nList;
-
- if( pList->pgno==1 ) pager_write_changecounter(pList);
- rc = sqlite3WalFrames(pPager->pWal,
- pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
- );
- if( rc==SQLITE_OK && pPager->pBackup ){
- PgHdr *p;
- for(p=pList; p; p=p->pDirty){
- sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
- }
- }
-
-#ifdef SQLITE_CHECK_PAGES
- pList = sqlite3PcacheDirtyList(pPager->pPCache);
- for(p=pList; p; p=p->pDirty){
- pager_set_pagehash(p);
- }
-#endif
-
- return rc;
-}
-
-/*
-** Begin a read transaction on the WAL.
-**
-** This routine used to be called "pagerOpenSnapshot()" because it essentially
-** makes a snapshot of the database at the current point in time and preserves
-** that snapshot for use by the reader in spite of concurrently changes by
-** other writers or checkpointers.
-*/
-static int pagerBeginReadTransaction(Pager *pPager){
- int rc; /* Return code */
- int changed = 0; /* True if cache must be reset */
-
- assert( pagerUseWal(pPager) );
- assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
-
- /* sqlite3WalEndReadTransaction() was not called for the previous
- ** transaction in locking_mode=EXCLUSIVE. So call it now. If we
- ** are in locking_mode=NORMAL and EndRead() was previously called,
- ** the duplicate call is harmless.
- */
- sqlite3WalEndReadTransaction(pPager->pWal);
-
- rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
- if( rc!=SQLITE_OK || changed ){
- pager_reset(pPager);
- }
-
- return rc;
-}
-#endif
-
-/*
-** This function is called as part of the transition from PAGER_OPEN
-** to PAGER_READER state to determine the size of the database file
-** in pages (assuming the page size currently stored in Pager.pageSize).
-**
-** If no error occurs, SQLITE_OK is returned and the size of the database
-** in pages is stored in *pnPage. Otherwise, an error code (perhaps
-** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified.
-*/
-static int pagerPagecount(Pager *pPager, Pgno *pnPage){
- Pgno nPage; /* Value to return via *pnPage */
-
- /* Query the WAL sub-system for the database size. The WalDbsize()
- ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
- ** if the database size is not available. The database size is not
- ** available from the WAL sub-system if the log file is empty or
- ** contains no valid committed transactions.
- */
- assert( pPager->eState==PAGER_OPEN );
- assert( pPager->eLock>=SHARED_LOCK );
- nPage = sqlite3WalDbsize(pPager->pWal);
-
- /* If the database size was not available from the WAL sub-system,
- ** determine it based on the size of the database file. If the size
- ** of the database file is not an integer multiple of the page-size,
- ** round down to the nearest page. Except, any file larger than 0
- ** bytes in size is considered to contain at least one page.
- */
- if( nPage==0 ){
- i64 n = 0; /* Size of db file in bytes */
- assert( isOpen(pPager->fd) || pPager->tempFile );
- if( isOpen(pPager->fd) ){
- int rc = sqlite3OsFileSize(pPager->fd, &n);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
- nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
- }
-
- /* If the current number of pages in the file is greater than the
- ** configured maximum pager number, increase the allowed limit so
- ** that the file can be read.
- */
- if( nPage>pPager->mxPgno ){
- pPager->mxPgno = (Pgno)nPage;
- }
-
- *pnPage = nPage;
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_WAL
-/*
-** Check if the *-wal file that corresponds to the database opened by pPager
-** exists if the database is not empy, or verify that the *-wal file does
-** not exist (by deleting it) if the database file is empty.
-**
-** If the database is not empty and the *-wal file exists, open the pager
-** in WAL mode. If the database is empty or if no *-wal file exists and
-** if no error occurs, make sure Pager.journalMode is not set to
-** PAGER_JOURNALMODE_WAL.
-**
-** Return SQLITE_OK or an error code.
-**
-** The caller must hold a SHARED lock on the database file to call this
-** function. Because an EXCLUSIVE lock on the db file is required to delete
-** a WAL on a none-empty database, this ensures there is no race condition
-** between the xAccess() below and an xDelete() being executed by some
-** other connection.
-*/
-static int pagerOpenWalIfPresent(Pager *pPager){
- int rc = SQLITE_OK;
- assert( pPager->eState==PAGER_OPEN );
- assert( pPager->eLock>=SHARED_LOCK );
-
- if( !pPager->tempFile ){
- int isWal; /* True if WAL file exists */
- Pgno nPage; /* Size of the database file */
-
- rc = pagerPagecount(pPager, &nPage);
- if( rc ) return rc;
- if( nPage==0 ){
- rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
- if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
- isWal = 0;
- }else{
- rc = sqlite3OsAccess(
- pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
- );
- }
- if( rc==SQLITE_OK ){
- if( isWal ){
- testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
- rc = sqlite3PagerOpenWal(pPager, 0);
- }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
- pPager->journalMode = PAGER_JOURNALMODE_DELETE;
- }
- }
- }
- return rc;
-}
-#endif
-
-/*
-** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
-** the entire master journal file. The case pSavepoint==NULL occurs when
-** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction
-** savepoint.
-**
-** When pSavepoint is not NULL (meaning a non-transaction savepoint is
-** being rolled back), then the rollback consists of up to three stages,
-** performed in the order specified:
-**
-** * Pages are played back from the main journal starting at byte
-** offset PagerSavepoint.iOffset and continuing to
-** PagerSavepoint.iHdrOffset, or to the end of the main journal
-** file if PagerSavepoint.iHdrOffset is zero.
-**
-** * If PagerSavepoint.iHdrOffset is not zero, then pages are played
-** back starting from the journal header immediately following
-** PagerSavepoint.iHdrOffset to the end of the main journal file.
-**
-** * Pages are then played back from the sub-journal file, starting
-** with the PagerSavepoint.iSubRec and continuing to the end of
-** the journal file.
-**
-** Throughout the rollback process, each time a page is rolled back, the
-** corresponding bit is set in a bitvec structure (variable pDone in the
-** implementation below). This is used to ensure that a page is only
-** rolled back the first time it is encountered in either journal.
-**
-** If pSavepoint is NULL, then pages are only played back from the main
-** journal file. There is no need for a bitvec in this case.
-**
-** In either case, before playback commences the Pager.dbSize variable
-** is reset to the value that it held at the start of the savepoint
-** (or transaction). No page with a page-number greater than this value
-** is played back. If one is encountered it is simply skipped.
-*/
-static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
- i64 szJ; /* Effective size of the main journal */
- i64 iHdrOff; /* End of first segment of main-journal records */
- int rc = SQLITE_OK; /* Return code */
- Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */
-
- assert( pPager->eState!=PAGER_ERROR );
- assert( pPager->eState>=PAGER_WRITER_LOCKED );
-
- /* Allocate a bitvec to use to store the set of pages rolled back */
- if( pSavepoint ){
- pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
- if( !pDone ){
- return SQLITE_NOMEM;
- }
- }
-
- /* Set the database size back to the value it was before the savepoint
- ** being reverted was opened.
- */
- pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
- pPager->changeCountDone = pPager->tempFile;
-
- if( !pSavepoint && pagerUseWal(pPager) ){
- return pagerRollbackWal(pPager);
- }
-
- /* Use pPager->journalOff as the effective size of the main rollback
- ** journal. The actual file might be larger than this in
- ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST. But anything
- ** past pPager->journalOff is off-limits to us.
- */
- szJ = pPager->journalOff;
- assert( pagerUseWal(pPager)==0 || szJ==0 );
-
- /* Begin by rolling back records from the main journal starting at
- ** PagerSavepoint.iOffset and continuing to the next journal header.
- ** There might be records in the main journal that have a page number
- ** greater than the current database size (pPager->dbSize) but those
- ** will be skipped automatically. Pages are added to pDone as they
- ** are played back.
- */
- if( pSavepoint && !pagerUseWal(pPager) ){
- iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ;
- pPager->journalOff = pSavepoint->iOffset;
- while( rc==SQLITE_OK && pPager->journalOff<iHdrOff ){
- rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
- }
- assert( rc!=SQLITE_DONE );
- }else{
- pPager->journalOff = 0;
- }
-
- /* Continue rolling back records out of the main journal starting at
- ** the first journal header seen and continuing until the effective end
- ** of the main journal file. Continue to skip out-of-range pages and
- ** continue adding pages rolled back to pDone.
- */
- while( rc==SQLITE_OK && pPager->journalOff<szJ ){
- u32 ii; /* Loop counter */
- u32 nJRec = 0; /* Number of Journal Records */
- u32 dummy;
- rc = readJournalHdr(pPager, 0, szJ, &nJRec, &dummy);
- assert( rc!=SQLITE_DONE );
-
- /*
- ** The "pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff"
- ** test is related to ticket #2565. See the discussion in the
- ** pager_playback() function for additional information.
- */
- if( nJRec==0
- && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
- ){
- nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager));
- }
- for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){
- rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
- }
- assert( rc!=SQLITE_DONE );
- }
- assert( rc!=SQLITE_OK || pPager->journalOff>=szJ );
-
- /* Finally, rollback pages from the sub-journal. Page that were
- ** previously rolled back out of the main journal (and are hence in pDone)
- ** will be skipped. Out-of-range pages are also skipped.
- */
- if( pSavepoint ){
- u32 ii; /* Loop counter */
- i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize);
-
- if( pagerUseWal(pPager) ){
- rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData);
- }
- for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && ii<pPager->nSubRec; ii++){
- assert( offset==(i64)ii*(4+pPager->pageSize) );
- rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1);
- }
- assert( rc!=SQLITE_DONE );
- }
-
- sqlite3BitvecDestroy(pDone);
- if( rc==SQLITE_OK ){
- pPager->journalOff = szJ;
- }
-
- return rc;
-}
-
-/*
-** Change the maximum number of in-memory pages that are allowed.
-*/
-SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
- sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
-}
-
-/*
-** Free as much memory as possible from the pager.
-*/
-SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
- sqlite3PcacheShrink(pPager->pPCache);
-}
-
-/*
-** Adjust the robustness of the database to damage due to OS crashes
-** or power failures by changing the number of syncs()s when writing
-** the rollback journal. There are three levels:
-**
-** OFF sqlite3OsSync() is never called. This is the default
-** for temporary and transient files.
-**
-** NORMAL The journal is synced once before writes begin on the
-** database. This is normally adequate protection, but
-** it is theoretically possible, though very unlikely,
-** that an inopertune power failure could leave the journal
-** in a state which would cause damage to the database
-** when it is rolled back.
-**
-** FULL The journal is synced twice before writes begin on the
-** database (with some additional information - the nRec field
-** of the journal header - being written in between the two
-** syncs). If we assume that writing a
-** single disk sector is atomic, then this mode provides
-** assurance that the journal will not be corrupted to the
-** point of causing damage to the database during rollback.
-**
-** The above is for a rollback-journal mode. For WAL mode, OFF continues
-** to mean that no syncs ever occur. NORMAL means that the WAL is synced
-** prior to the start of checkpoint and that the database file is synced
-** at the conclusion of the checkpoint if the entire content of the WAL
-** was written back into the database. But no sync operations occur for
-** an ordinary commit in NORMAL mode with WAL. FULL means that the WAL
-** file is synced following each commit operation, in addition to the
-** syncs associated with NORMAL.
-**
-** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL. The
-** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync
-** using fcntl(F_FULLFSYNC). SQLITE_SYNC_NORMAL means to do an
-** ordinary fsync() call. There is no difference between SQLITE_SYNC_FULL
-** and SQLITE_SYNC_NORMAL on platforms other than MacOSX. But the
-** synchronous=FULL versus synchronous=NORMAL setting determines when
-** the xSync primitive is called and is relevant to all platforms.
-**
-** Numeric values associated with these states are OFF==1, NORMAL=2,
-** and FULL=3.
-*/
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(
- Pager *pPager, /* The pager to set safety level for */
- int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
- int bFullFsync, /* PRAGMA fullfsync */
- int bCkptFullFsync /* PRAGMA checkpoint_fullfsync */
-){
- assert( level>=1 && level<=3 );
- pPager->noSync = (level==1 || pPager->tempFile) ?1:0;
- pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
- if( pPager->noSync ){
- pPager->syncFlags = 0;
- pPager->ckptSyncFlags = 0;
- }else if( bFullFsync ){
- pPager->syncFlags = SQLITE_SYNC_FULL;
- pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
- }else if( bCkptFullFsync ){
- pPager->syncFlags = SQLITE_SYNC_NORMAL;
- pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
- }else{
- pPager->syncFlags = SQLITE_SYNC_NORMAL;
- pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
- }
- pPager->walSyncFlags = pPager->syncFlags;
- if( pPager->fullSync ){
- pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
- }
-}
-#endif
-
-/*
-** The following global variable is incremented whenever the library
-** attempts to open a temporary file. This information is used for
-** testing and analysis only.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_opentemp_count = 0;
-#endif
-
-/*
-** Open a temporary file.
-**
-** Write the file descriptor into *pFile. Return SQLITE_OK on success
-** or some other error code if we fail. The OS will automatically
-** delete the temporary file when it is closed.
-**
-** The flags passed to the VFS layer xOpen() call are those specified
-** by parameter vfsFlags ORed with the following:
-**
-** SQLITE_OPEN_READWRITE
-** SQLITE_OPEN_CREATE
-** SQLITE_OPEN_EXCLUSIVE
-** SQLITE_OPEN_DELETEONCLOSE
-*/
-static int pagerOpentemp(
- Pager *pPager, /* The pager object */
- sqlite3_file *pFile, /* Write the file descriptor here */
- int vfsFlags /* Flags passed through to the VFS */
-){
- int rc; /* Return code */
-
-#ifdef SQLITE_TEST
- sqlite3_opentemp_count++; /* Used for testing and analysis only */
-#endif
-
- vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
- rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
- assert( rc!=SQLITE_OK || isOpen(pFile) );
- return rc;
-}
-
-/*
-** Set the busy handler function.
-**
-** The pager invokes the busy-handler if sqlite3OsLock() returns
-** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
-** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE
-** lock. It does *not* invoke the busy handler when upgrading from
-** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
-** (which occurs during hot-journal rollback). Summary:
-**
-** Transition | Invokes xBusyHandler
-** --------------------------------------------------------
-** NO_LOCK -> SHARED_LOCK | Yes
-** SHARED_LOCK -> RESERVED_LOCK | No
-** SHARED_LOCK -> EXCLUSIVE_LOCK | No
-** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes
-**
-** If the busy-handler callback returns non-zero, the lock is
-** retried. If it returns zero, then the SQLITE_BUSY error is
-** returned to the caller of the pager API function.
-*/
-SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
- Pager *pPager, /* Pager object */
- int (*xBusyHandler)(void *), /* Pointer to busy-handler function */
- void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
-){
- pPager->xBusyHandler = xBusyHandler;
- pPager->pBusyHandlerArg = pBusyHandlerArg;
-
- if( isOpen(pPager->fd) ){
- void **ap = (void **)&pPager->xBusyHandler;
- assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
- assert( ap[1]==pBusyHandlerArg );
- sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
- }
-}
-
-/*
-** Change the page size used by the Pager object. The new page size
-** is passed in *pPageSize.
-**
-** If the pager is in the error state when this function is called, it
-** is a no-op. The value returned is the error state error code (i.e.
-** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL).
-**
-** Otherwise, if all of the following are true:
-**
-** * the new page size (value of *pPageSize) is valid (a power
-** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
-**
-** * there are no outstanding page references, and
-**
-** * the database is either not an in-memory database or it is
-** an in-memory database that currently consists of zero pages.
-**
-** then the pager object page size is set to *pPageSize.
-**
-** If the page size is changed, then this function uses sqlite3PagerMalloc()
-** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt
-** fails, SQLITE_NOMEM is returned and the page size remains unchanged.
-** In all other cases, SQLITE_OK is returned.
-**
-** If the page size is not changed, either because one of the enumerated
-** conditions above is not true, the pager was in error state when this
-** function was called, or because the memory allocation attempt failed,
-** then *pPageSize is set to the old, retained page size before returning.
-*/
-SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
- int rc = SQLITE_OK;
-
- /* It is not possible to do a full assert_pager_state() here, as this
- ** function may be called from within PagerOpen(), before the state
- ** of the Pager object is internally consistent.
- **
- ** At one point this function returned an error if the pager was in
- ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that
- ** there is at least one outstanding page reference, this function
- ** is a no-op for that case anyhow.
- */
-
- u32 pageSize = *pPageSize;
- assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
- if( (pPager->memDb==0 || pPager->dbSize==0)
- && sqlite3PcacheRefCount(pPager->pPCache)==0
- && pageSize && pageSize!=(u32)pPager->pageSize
- ){
- char *pNew = NULL; /* New temp space */
- i64 nByte = 0;
-
- if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){
- rc = sqlite3OsFileSize(pPager->fd, &nByte);
- }
- if( rc==SQLITE_OK ){
- pNew = (char *)sqlite3PageMalloc(pageSize);
- if( !pNew ) rc = SQLITE_NOMEM;
- }
-
- if( rc==SQLITE_OK ){
- pager_reset(pPager);
- pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
- pPager->pageSize = pageSize;
- sqlite3PageFree(pPager->pTmpSpace);
- pPager->pTmpSpace = pNew;
- sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
- }
- }
-
- *pPageSize = pPager->pageSize;
- if( rc==SQLITE_OK ){
- if( nReserve<0 ) nReserve = pPager->nReserve;
- assert( nReserve>=0 && nReserve<1000 );
- pPager->nReserve = (i16)nReserve;
- pagerReportSize(pPager);
- }
- return rc;
-}
-
-/*
-** Return a pointer to the "temporary page" buffer held internally
-** by the pager. This is a buffer that is big enough to hold the
-** entire content of a database page. This buffer is used internally
-** during rollback and will be overwritten whenever a rollback
-** occurs. But other modules are free to use it too, as long as
-** no rollbacks are happening.
-*/
-SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){
- return pPager->pTmpSpace;
-}
-
-/*
-** Attempt to set the maximum database page count if mxPage is positive.
-** Make no changes if mxPage is zero or negative. And never reduce the
-** maximum page count below the current size of the database.
-**
-** Regardless of mxPage, return the current maximum page count.
-*/
-SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
- if( mxPage>0 ){
- pPager->mxPgno = mxPage;
- }
- assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */
- assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */
- return pPager->mxPgno;
-}
-
-/*
-** The following set of routines are used to disable the simulated
-** I/O error mechanism. These routines are used to avoid simulated
-** errors in places where we do not care about errors.
-**
-** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops
-** and generate no code.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API extern int sqlite3_io_error_pending;
-SQLITE_API extern int sqlite3_io_error_hit;
-static int saved_cnt;
-void disable_simulated_io_errors(void){
- saved_cnt = sqlite3_io_error_pending;
- sqlite3_io_error_pending = -1;
-}
-void enable_simulated_io_errors(void){
- sqlite3_io_error_pending = saved_cnt;
-}
-#else
-# define disable_simulated_io_errors()
-# define enable_simulated_io_errors()
-#endif
-
-/*
-** Read the first N bytes from the beginning of the file into memory
-** that pDest points to.
-**
-** If the pager was opened on a transient file (zFilename==""), or
-** opened on a file less than N bytes in size, the output buffer is
-** zeroed and SQLITE_OK returned. The rationale for this is that this
-** function is used to read database headers, and a new transient or
-** zero sized database has a header than consists entirely of zeroes.
-**
-** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered,
-** the error code is returned to the caller and the contents of the
-** output buffer undefined.
-*/
-SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
- int rc = SQLITE_OK;
- memset(pDest, 0, N);
- assert( isOpen(pPager->fd) || pPager->tempFile );
-
- /* This routine is only called by btree immediately after creating
- ** the Pager object. There has not been an opportunity to transition
- ** to WAL mode yet.
- */
- assert( !pagerUseWal(pPager) );
-
- if( isOpen(pPager->fd) ){
- IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
- rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
- if( rc==SQLITE_IOERR_SHORT_READ ){
- rc = SQLITE_OK;
- }
- }
- return rc;
-}
-
-/*
-** This function may only be called when a read-transaction is open on
-** the pager. It returns the total number of pages in the database.
-**
-** However, if the file is between 1 and <page-size> bytes in size, then
-** this is considered a 1 page file.
-*/
-SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){
- assert( pPager->eState>=PAGER_READER );
- assert( pPager->eState!=PAGER_WRITER_FINISHED );
- *pnPage = (int)pPager->dbSize;
-}
-
-
-/*
-** Try to obtain a lock of type locktype on the database file. If
-** a similar or greater lock is already held, this function is a no-op
-** (returning SQLITE_OK immediately).
-**
-** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke
-** the busy callback if the lock is currently not available. Repeat
-** until the busy callback returns false or until the attempt to
-** obtain the lock succeeds.
-**
-** Return SQLITE_OK on success and an error code if we cannot obtain
-** the lock. If the lock is obtained successfully, set the Pager.state
-** variable to locktype before returning.
-*/
-static int pager_wait_on_lock(Pager *pPager, int locktype){
- int rc; /* Return code */
-
- /* Check that this is either a no-op (because the requested lock is
- ** already held, or one of the transistions that the busy-handler
- ** may be invoked during, according to the comment above
- ** sqlite3PagerSetBusyhandler().
- */
- assert( (pPager->eLock>=locktype)
- || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK)
- || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK)
- );
-
- do {
- rc = pagerLockDb(pPager, locktype);
- }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
- return rc;
-}
-
-/*
-** Function assertTruncateConstraint(pPager) checks that one of the
-** following is true for all dirty pages currently in the page-cache:
-**
-** a) The page number is less than or equal to the size of the
-** current database image, in pages, OR
-**
-** b) if the page content were written at this time, it would not
-** be necessary to write the current content out to the sub-journal
-** (as determined by function subjRequiresPage()).
-**
-** If the condition asserted by this function were not true, and the
-** dirty page were to be discarded from the cache via the pagerStress()
-** routine, pagerStress() would not write the current page content to
-** the database file. If a savepoint transaction were rolled back after
-** this happened, the correct behaviour would be to restore the current
-** content of the page. However, since this content is not present in either
-** the database file or the portion of the rollback journal and
-** sub-journal rolled back the content could not be restored and the
-** database image would become corrupt. It is therefore fortunate that
-** this circumstance cannot arise.
-*/
-#if defined(SQLITE_DEBUG)
-static void assertTruncateConstraintCb(PgHdr *pPg){
- assert( pPg->flags&PGHDR_DIRTY );
- assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize );
-}
-static void assertTruncateConstraint(Pager *pPager){
- sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb);
-}
-#else
-# define assertTruncateConstraint(pPager)
-#endif
-
-/*
-** Truncate the in-memory database file image to nPage pages. This
-** function does not actually modify the database file on disk. It
-** just sets the internal state of the pager object so that the
-** truncation will be done when the current transaction is committed.
-*/
-SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
- assert( pPager->dbSize>=nPage );
- assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
- pPager->dbSize = nPage;
- assertTruncateConstraint(pPager);
-}
-
-
-/*
-** This function is called before attempting a hot-journal rollback. It
-** syncs the journal file to disk, then sets pPager->journalHdr to the
-** size of the journal file so that the pager_playback() routine knows
-** that the entire journal file has been synced.
-**
-** Syncing a hot-journal to disk before attempting to roll it back ensures
-** that if a power-failure occurs during the rollback, the process that
-** attempts rollback following system recovery sees the same journal
-** content as this process.
-**
-** If everything goes as planned, SQLITE_OK is returned. Otherwise,
-** an SQLite error code.
-*/
-static int pagerSyncHotJournal(Pager *pPager){
- int rc = SQLITE_OK;
- if( !pPager->noSync ){
- rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr);
- }
- return rc;
-}
-
-/*
-** Shutdown the page cache. Free all memory and close all files.
-**
-** If a transaction was in progress when this routine is called, that
-** transaction is rolled back. All outstanding pages are invalidated
-** and their memory is freed. Any attempt to use a page associated
-** with this page cache after this function returns will likely
-** result in a coredump.
-**
-** This function always succeeds. If a transaction is active an attempt
-** is made to roll it back. If an error occurs during the rollback
-** a hot journal may be left in the filesystem but no error is returned
-** to the caller.
-*/
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
- u8 *pTmp = (u8 *)pPager->pTmpSpace;
-
- assert( assert_pager_state(pPager) );
- disable_simulated_io_errors();
- sqlite3BeginBenignMalloc();
- /* pPager->errCode = 0; */
- pPager->exclusiveMode = 0;
-#ifndef SQLITE_OMIT_WAL
- sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
- pPager->pWal = 0;
-#endif
- pager_reset(pPager);
- if( MEMDB ){
- pager_unlock(pPager);
- }else{
- /* If it is open, sync the journal file before calling UnlockAndRollback.
- ** If this is not done, then an unsynced portion of the open journal
- ** file may be played back into the database. If a power failure occurs
- ** while this is happening, the database could become corrupt.
- **
- ** If an error occurs while trying to sync the journal, shift the pager
- ** into the ERROR state. This causes UnlockAndRollback to unlock the
- ** database and close the journal file without attempting to roll it
- ** back or finalize it. The next database user will have to do hot-journal
- ** rollback before accessing the database file.
- */
- if( isOpen(pPager->jfd) ){
- pager_error(pPager, pagerSyncHotJournal(pPager));
- }
- pagerUnlockAndRollback(pPager);
- }
- sqlite3EndBenignMalloc();
- enable_simulated_io_errors();
- PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
- IOTRACE(("CLOSE %p\n", pPager))
- sqlite3OsClose(pPager->jfd);
- sqlite3OsClose(pPager->fd);
- sqlite3PageFree(pTmp);
- sqlite3PcacheClose(pPager->pPCache);
-
-#ifdef SQLITE_HAS_CODEC
- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
-#endif
-
- assert( !pPager->aSavepoint && !pPager->pInJournal );
- assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
-
- sqlite3_free(pPager);
- return SQLITE_OK;
-}
-
-#if !defined(NDEBUG) || defined(SQLITE_TEST)
-/*
-** Return the page number for page pPg.
-*/
-SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){
- return pPg->pgno;
-}
-#endif
-
-/*
-** Increment the reference count for page pPg.
-*/
-SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
- sqlite3PcacheRef(pPg);
-}
-
-/*
-** Sync the journal. In other words, make sure all the pages that have
-** been written to the journal have actually reached the surface of the
-** disk and can be restored in the event of a hot-journal rollback.
-**
-** If the Pager.noSync flag is set, then this function is a no-op.
-** Otherwise, the actions required depend on the journal-mode and the
-** device characteristics of the file-system, as follows:
-**
-** * If the journal file is an in-memory journal file, no action need
-** be taken.
-**
-** * Otherwise, if the device does not support the SAFE_APPEND property,
-** then the nRec field of the most recently written journal header
-** is updated to contain the number of journal records that have
-** been written following it. If the pager is operating in full-sync
-** mode, then the journal file is synced before this field is updated.
-**
-** * If the device does not support the SEQUENTIAL property, then
-** journal file is synced.
-**
-** Or, in pseudo-code:
-**
-** if( NOT <in-memory journal> ){
-** if( NOT SAFE_APPEND ){
-** if( <full-sync mode> ) xSync(<journal file>);
-** <update nRec field>
-** }
-** if( NOT SEQUENTIAL ) xSync(<journal file>);
-** }
-**
-** If successful, this routine clears the PGHDR_NEED_SYNC flag of every
-** page currently held in memory before returning SQLITE_OK. If an IO
-** error is encountered, then the IO error code is returned to the caller.
-*/
-static int syncJournal(Pager *pPager, int newHdr){
- int rc; /* Return code */
-
- assert( pPager->eState==PAGER_WRITER_CACHEMOD
- || pPager->eState==PAGER_WRITER_DBMOD
- );
- assert( assert_pager_state(pPager) );
- assert( !pagerUseWal(pPager) );
-
- rc = sqlite3PagerExclusiveLock(pPager);
- if( rc!=SQLITE_OK ) return rc;
-
- if( !pPager->noSync ){
- assert( !pPager->tempFile );
- if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
- const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
- assert( isOpen(pPager->jfd) );
-
- if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
- /* This block deals with an obscure problem. If the last connection
- ** that wrote to this database was operating in persistent-journal
- ** mode, then the journal file may at this point actually be larger
- ** than Pager.journalOff bytes. If the next thing in the journal
- ** file happens to be a journal-header (written as part of the
- ** previous connection's transaction), and a crash or power-failure
- ** occurs after nRec is updated but before this connection writes
- ** anything else to the journal file (or commits/rolls back its
- ** transaction), then SQLite may become confused when doing the
- ** hot-journal rollback following recovery. It may roll back all
- ** of this connections data, then proceed to rolling back the old,
- ** out-of-date data that follows it. Database corruption.
- **
- ** To work around this, if the journal file does appear to contain
- ** a valid header following Pager.journalOff, then write a 0x00
- ** byte to the start of it to prevent it from being recognized.
- **
- ** Variable iNextHdrOffset is set to the offset at which this
- ** problematic header will occur, if it exists. aMagic is used
- ** as a temporary buffer to inspect the first couple of bytes of
- ** the potential journal header.
- */
- i64 iNextHdrOffset;
- u8 aMagic[8];
- u8 zHeader[sizeof(aJournalMagic)+4];
-
- memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
- put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec);
-
- iNextHdrOffset = journalHdrOffset(pPager);
- rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset);
- if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){
- static const u8 zerobyte = 0;
- rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset);
- }
- if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
- return rc;
- }
-
- /* Write the nRec value into the journal file header. If in
- ** full-synchronous mode, sync the journal first. This ensures that
- ** all data has really hit the disk before nRec is updated to mark
- ** it as a candidate for rollback.
- **
- ** This is not required if the persistent media supports the
- ** SAFE_APPEND property. Because in this case it is not possible
- ** for garbage data to be appended to the file, the nRec field
- ** is populated with 0xFFFFFFFF when the journal header is written
- ** and never needs to be updated.
- */
- if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
- PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
- IOTRACE(("JSYNC %p\n", pPager))
- rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
- if( rc!=SQLITE_OK ) return rc;
- }
- IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr));
- rc = sqlite3OsWrite(
- pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr
- );
- if( rc!=SQLITE_OK ) return rc;
- }
- if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
- PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
- IOTRACE(("JSYNC %p\n", pPager))
- rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags|
- (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
- );
- if( rc!=SQLITE_OK ) return rc;
- }
-
- pPager->journalHdr = pPager->journalOff;
- if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
- pPager->nRec = 0;
- rc = writeJournalHdr(pPager);
- if( rc!=SQLITE_OK ) return rc;
- }
- }else{
- pPager->journalHdr = pPager->journalOff;
- }
- }
-
- /* Unless the pager is in noSync mode, the journal file was just
- ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on
- ** all pages.
- */
- sqlite3PcacheClearSyncFlags(pPager->pPCache);
- pPager->eState = PAGER_WRITER_DBMOD;
- assert( assert_pager_state(pPager) );
- return SQLITE_OK;
-}
-
-/*
-** The argument is the first in a linked list of dirty pages connected
-** by the PgHdr.pDirty pointer. This function writes each one of the
-** in-memory pages in the list to the database file. The argument may
-** be NULL, representing an empty list. In this case this function is
-** a no-op.
-**
-** The pager must hold at least a RESERVED lock when this function
-** is called. Before writing anything to the database file, this lock
-** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained,
-** SQLITE_BUSY is returned and no data is written to the database file.
-**
-** If the pager is a temp-file pager and the actual file-system file
-** is not yet open, it is created and opened before any data is
-** written out.
-**
-** Once the lock has been upgraded and, if necessary, the file opened,
-** the pages are written out to the database file in list order. Writing
-** a page is skipped if it meets either of the following criteria:
-**
-** * The page number is greater than Pager.dbSize, or
-** * The PGHDR_DONT_WRITE flag is set on the page.
-**
-** If writing out a page causes the database file to grow, Pager.dbFileSize
-** is updated accordingly. If page 1 is written out, then the value cached
-** in Pager.dbFileVers[] is updated to match the new value stored in
-** the database file.
-**
-** If everything is successful, SQLITE_OK is returned. If an IO error
-** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
-** be obtained, SQLITE_BUSY is returned.
-*/
-static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
- int rc = SQLITE_OK; /* Return code */
-
- /* This function is only called for rollback pagers in WRITER_DBMOD state. */
- assert( !pagerUseWal(pPager) );
- assert( pPager->eState==PAGER_WRITER_DBMOD );
- assert( pPager->eLock==EXCLUSIVE_LOCK );
-
- /* If the file is a temp-file has not yet been opened, open it now. It
- ** is not possible for rc to be other than SQLITE_OK if this branch
- ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
- */
- if( !isOpen(pPager->fd) ){
- assert( pPager->tempFile && rc==SQLITE_OK );
- rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
- }
-
- /* Before the first write, give the VFS a hint of what the final
- ** file size will be.
- */
- assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
- if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){
- sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
- sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
- pPager->dbHintSize = pPager->dbSize;
- }
-
- while( rc==SQLITE_OK && pList ){
- Pgno pgno = pList->pgno;
-
- /* If there are dirty pages in the page cache with page numbers greater
- ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
- ** make the file smaller (presumably by auto-vacuum code). Do not write
- ** any such pages to the file.
- **
- ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
- ** set (set by sqlite3PagerDontWrite()).
- */
- if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
- i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */
- char *pData; /* Data to write */
-
- assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
- if( pList->pgno==1 ) pager_write_changecounter(pList);
-
- /* Encode the database */
- CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
-
- /* Write out the page data. */
- rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
-
- /* If page 1 was just written, update Pager.dbFileVers to match
- ** the value now stored in the database file. If writing this
- ** page caused the database file to grow, update dbFileSize.
- */
- if( pgno==1 ){
- memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
- }
- if( pgno>pPager->dbFileSize ){
- pPager->dbFileSize = pgno;
- }
- pPager->aStat[PAGER_STAT_WRITE]++;
-
- /* Update any backup objects copying the contents of this pager. */
- sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData);
-
- PAGERTRACE(("STORE %d page %d hash(%08x)\n",
- PAGERID(pPager), pgno, pager_pagehash(pList)));
- IOTRACE(("PGOUT %p %d\n", pPager, pgno));
- PAGER_INCR(sqlite3_pager_writedb_count);
- }else{
- PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
- }
- pager_set_pagehash(pList);
- pList = pList->pDirty;
- }
-
- return rc;
-}
-
-/*
-** Ensure that the sub-journal file is open. If it is already open, this
-** function is a no-op.
-**
-** SQLITE_OK is returned if everything goes according to plan. An
-** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen()
-** fails.
-*/
-static int openSubJournal(Pager *pPager){
- int rc = SQLITE_OK;
- if( !isOpen(pPager->sjfd) ){
- if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
- sqlite3MemJournalOpen(pPager->sjfd);
- }else{
- rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
- }
- }
- return rc;
-}
-
-/*
-** Append a record of the current state of page pPg to the sub-journal.
-** It is the callers responsibility to use subjRequiresPage() to check
-** that it is really required before calling this function.
-**
-** If successful, set the bit corresponding to pPg->pgno in the bitvecs
-** for all open savepoints before returning.
-**
-** This function returns SQLITE_OK if everything is successful, an IO
-** error code if the attempt to write to the sub-journal fails, or
-** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint
-** bitvec.
-*/
-static int subjournalPage(PgHdr *pPg){
- int rc = SQLITE_OK;
- Pager *pPager = pPg->pPager;
- if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
-
- /* Open the sub-journal, if it has not already been opened */
- assert( pPager->useJournal );
- assert( isOpen(pPager->jfd) || pagerUseWal(pPager) );
- assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 );
- assert( pagerUseWal(pPager)
- || pageInJournal(pPg)
- || pPg->pgno>pPager->dbOrigSize
- );
- rc = openSubJournal(pPager);
-
- /* If the sub-journal was opened successfully (or was already open),
- ** write the journal record into the file. */
- if( rc==SQLITE_OK ){
- void *pData = pPg->pData;
- i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
- char *pData2;
-
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
- PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
- rc = write32bits(pPager->sjfd, offset, pPg->pgno);
- if( rc==SQLITE_OK ){
- rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
- }
- }
- }
- if( rc==SQLITE_OK ){
- pPager->nSubRec++;
- assert( pPager->nSavepoint>0 );
- rc = addToSavepointBitvecs(pPager, pPg->pgno);
- }
- return rc;
-}
-
-/*
-** This function is called by the pcache layer when it has reached some
-** soft memory limit. The first argument is a pointer to a Pager object
-** (cast as a void*). The pager is always 'purgeable' (not an in-memory
-** database). The second argument is a reference to a page that is
-** currently dirty but has no outstanding references. The page
-** is always associated with the Pager object passed as the first
-** argument.
-**
-** The job of this function is to make pPg clean by writing its contents
-** out to the database file, if possible. This may involve syncing the
-** journal file.
-**
-** If successful, sqlite3PcacheMakeClean() is called on the page and
-** SQLITE_OK returned. If an IO error occurs while trying to make the
-** page clean, the IO error code is returned. If the page cannot be
-** made clean for some other reason, but no error occurs, then SQLITE_OK
-** is returned by sqlite3PcacheMakeClean() is not called.
-*/
-static int pagerStress(void *p, PgHdr *pPg){
- Pager *pPager = (Pager *)p;
- int rc = SQLITE_OK;
-
- assert( pPg->pPager==pPager );
- assert( pPg->flags&PGHDR_DIRTY );
-
- /* The doNotSyncSpill flag is set during times when doing a sync of
- ** journal (and adding a new header) is not allowed. This occurs
- ** during calls to sqlite3PagerWrite() while trying to journal multiple
- ** pages belonging to the same sector.
- **
- ** The doNotSpill flag inhibits all cache spilling regardless of whether
- ** or not a sync is required. This is set during a rollback.
- **
- ** Spilling is also prohibited when in an error state since that could
- ** lead to database corruption. In the current implementaton it
- ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1
- ** while in the error state, hence it is impossible for this routine to
- ** be called in the error state. Nevertheless, we include a NEVER()
- ** test for the error state as a safeguard against future changes.
- */
- if( NEVER(pPager->errCode) ) return SQLITE_OK;
- if( pPager->doNotSpill ) return SQLITE_OK;
- if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
- return SQLITE_OK;
- }
-
- pPg->pDirty = 0;
- if( pagerUseWal(pPager) ){
- /* Write a single frame for this page to the log. */
- if( subjRequiresPage(pPg) ){
- rc = subjournalPage(pPg);
- }
- if( rc==SQLITE_OK ){
- rc = pagerWalFrames(pPager, pPg, 0, 0);
- }
- }else{
-
- /* Sync the journal file if required. */
- if( pPg->flags&PGHDR_NEED_SYNC
- || pPager->eState==PAGER_WRITER_CACHEMOD
- ){
- rc = syncJournal(pPager, 1);
- }
-
- /* If the page number of this page is larger than the current size of
- ** the database image, it may need to be written to the sub-journal.
- ** This is because the call to pager_write_pagelist() below will not
- ** actually write data to the file in this case.
- **
- ** Consider the following sequence of events:
- **
- ** BEGIN;
- ** <journal page X>
- ** <modify page X>
- ** SAVEPOINT sp;
- ** <shrink database file to Y pages>
- ** pagerStress(page X)
- ** ROLLBACK TO sp;
- **
- ** If (X>Y), then when pagerStress is called page X will not be written
- ** out to the database file, but will be dropped from the cache. Then,
- ** following the "ROLLBACK TO sp" statement, reading page X will read
- ** data from the database file. This will be the copy of page X as it
- ** was when the transaction started, not as it was when "SAVEPOINT sp"
- ** was executed.
- **
- ** The solution is to write the current data for page X into the
- ** sub-journal file now (if it is not already there), so that it will
- ** be restored to its current value when the "ROLLBACK TO sp" is
- ** executed.
- */
- if( NEVER(
- rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
- ) ){
- rc = subjournalPage(pPg);
- }
-
- /* Write the contents of the page out to the database file. */
- if( rc==SQLITE_OK ){
- assert( (pPg->flags&PGHDR_NEED_SYNC)==0 );
- rc = pager_write_pagelist(pPager, pPg);
- }
- }
-
- /* Mark the page as clean. */
- if( rc==SQLITE_OK ){
- PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
- sqlite3PcacheMakeClean(pPg);
- }
-
- return pager_error(pPager, rc);
-}
-
-
-/*
-** Allocate and initialize a new Pager object and put a pointer to it
-** in *ppPager. The pager should eventually be freed by passing it
-** to sqlite3PagerClose().
-**
-** The zFilename argument is the path to the database file to open.
-** If zFilename is NULL then a randomly-named temporary file is created
-** and used as the file to be cached. Temporary files are be deleted
-** automatically when they are closed. If zFilename is ":memory:" then
-** all information is held in cache. It is never written to disk.
-** This can be used to implement an in-memory database.
-**
-** The nExtra parameter specifies the number of bytes of space allocated
-** along with each page reference. This space is available to the user
-** via the sqlite3PagerGetExtra() API.
-**
-** The flags argument is used to specify properties that affect the
-** operation of the pager. It should be passed some bitwise combination
-** of the PAGER_* flags.
-**
-** The vfsFlags parameter is a bitmask to pass to the flags parameter
-** of the xOpen() method of the supplied VFS when opening files.
-**
-** If the pager object is allocated and the specified file opened
-** successfully, SQLITE_OK is returned and *ppPager set to point to
-** the new pager object. If an error occurs, *ppPager is set to NULL
-** and error code returned. This function may return SQLITE_NOMEM
-** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or
-** various SQLITE_IO_XXX errors.
-*/
-SQLITE_PRIVATE int sqlite3PagerOpen(
- sqlite3_vfs *pVfs, /* The virtual file system to use */
- Pager **ppPager, /* OUT: Return the Pager structure here */
- const char *zFilename, /* Name of the database file to open */
- int nExtra, /* Extra bytes append to each in-memory page */
- int flags, /* flags controlling this file */
- int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */
- void (*xReinit)(DbPage*) /* Function to reinitialize pages */
-){
- u8 *pPtr;
- Pager *pPager = 0; /* Pager object to allocate and return */
- int rc = SQLITE_OK; /* Return code */
- int tempFile = 0; /* True for temp files (incl. in-memory files) */
- int memDb = 0; /* True if this is an in-memory file */
- int readOnly = 0; /* True if this is a read-only file */
- int journalFileSize; /* Bytes to allocate for each journal fd */
- char *zPathname = 0; /* Full path to database file */
- int nPathname = 0; /* Number of bytes in zPathname */
- int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
- int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */
- u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */
- const char *zUri = 0; /* URI args to copy */
- int nUri = 0; /* Number of bytes of URI args at *zUri */
-
- /* Figure out how much space is required for each journal file-handle
- ** (there are two of them, the main journal and the sub-journal). This
- ** is the maximum space required for an in-memory journal file handle
- ** and a regular journal file-handle. Note that a "regular journal-handle"
- ** may be a wrapper capable of caching the first portion of the journal
- ** file in memory to implement the atomic-write optimization (see
- ** source file journal.c).
- */
- if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
- journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
- }else{
- journalFileSize = ROUND8(sqlite3MemJournalSize());
- }
-
- /* Set the output variable to NULL in case an error occurs. */
- *ppPager = 0;
-
-#ifndef SQLITE_OMIT_MEMORYDB
- if( flags & PAGER_MEMORY ){
- memDb = 1;
- if( zFilename && zFilename[0] ){
- zPathname = sqlite3DbStrDup(0, zFilename);
- if( zPathname==0 ) return SQLITE_NOMEM;
- nPathname = sqlite3Strlen30(zPathname);
- zFilename = 0;
- }
- }
-#endif
-
- /* Compute and store the full pathname in an allocated buffer pointed
- ** to by zPathname, length nPathname. Or, if this is a temporary file,
- ** leave both nPathname and zPathname set to 0.
- */
- if( zFilename && zFilename[0] ){
- const char *z;
- nPathname = pVfs->mxPathname+1;
- zPathname = sqlite3DbMallocRaw(0, nPathname*2);
- if( zPathname==0 ){
- return SQLITE_NOMEM;
- }
- zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
- rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
- nPathname = sqlite3Strlen30(zPathname);
- z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
- while( *z ){
- z += sqlite3Strlen30(z)+1;
- z += sqlite3Strlen30(z)+1;
- }
- nUri = (int)(&z[1] - zUri);
- assert( nUri>=0 );
- if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
- /* This branch is taken when the journal path required by
- ** the database being opened will be more than pVfs->mxPathname
- ** bytes in length. This means the database cannot be opened,
- ** as it will not be possible to open the journal file or even
- ** check for a hot-journal before reading.
- */
- rc = SQLITE_CANTOPEN_BKPT;
- }
- if( rc!=SQLITE_OK ){
- sqlite3DbFree(0, zPathname);
- return rc;
- }
- }
-
- /* Allocate memory for the Pager structure, PCache object, the
- ** three file descriptors, the database file name and the journal
- ** file name. The layout in memory is as follows:
- **
- ** Pager object (sizeof(Pager) bytes)
- ** PCache object (sqlite3PcacheSize() bytes)
- ** Database file handle (pVfs->szOsFile bytes)
- ** Sub-journal file handle (journalFileSize bytes)
- ** Main journal file handle (journalFileSize bytes)
- ** Database file name (nPathname+1 bytes)
- ** Journal file name (nPathname+8+1 bytes)
- */
- pPtr = (u8 *)sqlite3MallocZero(
- ROUND8(sizeof(*pPager)) + /* Pager structure */
- ROUND8(pcacheSize) + /* PCache object */
- ROUND8(pVfs->szOsFile) + /* The main db file */
- journalFileSize * 2 + /* The two journal files */
- nPathname + 1 + nUri + /* zFilename */
- nPathname + 8 + 2 /* zJournal */
-#ifndef SQLITE_OMIT_WAL
- + nPathname + 4 + 2 /* zWal */
-#endif
- );
- assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
- if( !pPtr ){
- sqlite3DbFree(0, zPathname);
- return SQLITE_NOMEM;
- }
- pPager = (Pager*)(pPtr);
- pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
- pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
- pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
- pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize);
- pPager->zFilename = (char*)(pPtr += journalFileSize);
- assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
-
- /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
- if( zPathname ){
- assert( nPathname>0 );
- pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri);
- memcpy(pPager->zFilename, zPathname, nPathname);
- if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
- memcpy(pPager->zJournal, zPathname, nPathname);
- memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
- sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
-#ifndef SQLITE_OMIT_WAL
- pPager->zWal = &pPager->zJournal[nPathname+8+1];
- memcpy(pPager->zWal, zPathname, nPathname);
- memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
- sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
-#endif
- sqlite3DbFree(0, zPathname);
- }
- pPager->pVfs = pVfs;
- pPager->vfsFlags = vfsFlags;
-
- /* Open the pager file.
- */
- if( zFilename && zFilename[0] ){
- int fout = 0; /* VFS flags returned by xOpen() */
- rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
- assert( !memDb );
- readOnly = (fout&SQLITE_OPEN_READONLY);
-
- /* If the file was successfully opened for read/write access,
- ** choose a default page size in case we have to create the
- ** database file. The default page size is the maximum of:
- **
- ** + SQLITE_DEFAULT_PAGE_SIZE,
- ** + The value returned by sqlite3OsSectorSize()
- ** + The largest page size that can be written atomically.
- */
- if( rc==SQLITE_OK && !readOnly ){
- setSectorSize(pPager);
- assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
- if( szPageDflt<pPager->sectorSize ){
- if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
- szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
- }else{
- szPageDflt = (u32)pPager->sectorSize;
- }
- }
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
- {
- int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
- int ii;
- assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
- assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
- assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
- for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
- if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
- szPageDflt = ii;
- }
- }
- }
-#endif
- }
- }else{
- /* If a temporary file is requested, it is not opened immediately.
- ** In this case we accept the default page size and delay actually
- ** opening the file until the first call to OsWrite().
- **
- ** This branch is also run for an in-memory database. An in-memory
- ** database is the same as a temp-file that is never written out to
- ** disk and uses an in-memory rollback journal.
- */
- tempFile = 1;
- pPager->eState = PAGER_READER;
- pPager->eLock = EXCLUSIVE_LOCK;
- readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
- }
-
- /* The following call to PagerSetPagesize() serves to set the value of
- ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
- */
- if( rc==SQLITE_OK ){
- assert( pPager->memDb==0 );
- rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
- testcase( rc!=SQLITE_OK );
- }
-
- /* If an error occurred in either of the blocks above, free the
- ** Pager structure and close the file.
- */
- if( rc!=SQLITE_OK ){
- assert( !pPager->pTmpSpace );
- sqlite3OsClose(pPager->fd);
- sqlite3_free(pPager);
- return rc;
- }
-
- /* Initialize the PCache object. */
- assert( nExtra<1000 );
- nExtra = ROUND8(nExtra);
- sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
- !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
-
- PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
- IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
-
- pPager->useJournal = (u8)useJournal;
- /* pPager->stmtOpen = 0; */
- /* pPager->stmtInUse = 0; */
- /* pPager->nRef = 0; */
- /* pPager->stmtSize = 0; */
- /* pPager->stmtJSize = 0; */
- /* pPager->nPage = 0; */
- pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
- /* pPager->state = PAGER_UNLOCK; */
-#if 0
- assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
-#endif
- /* pPager->errMask = 0; */
- pPager->tempFile = (u8)tempFile;
- assert( tempFile==PAGER_LOCKINGMODE_NORMAL
- || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
- assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
- pPager->exclusiveMode = (u8)tempFile;
- pPager->changeCountDone = pPager->tempFile;
- pPager->memDb = (u8)memDb;
- pPager->readOnly = (u8)readOnly;
- assert( useJournal || pPager->tempFile );
- pPager->noSync = pPager->tempFile;
- if( pPager->noSync ){
- assert( pPager->fullSync==0 );
- assert( pPager->syncFlags==0 );
- assert( pPager->walSyncFlags==0 );
- assert( pPager->ckptSyncFlags==0 );
- }else{
- pPager->fullSync = 1;
- pPager->syncFlags = SQLITE_SYNC_NORMAL;
- pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
- pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
- }
- /* pPager->pFirst = 0; */
- /* pPager->pFirstSynced = 0; */
- /* pPager->pLast = 0; */
- pPager->nExtra = (u16)nExtra;
- pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
- assert( isOpen(pPager->fd) || tempFile );
- setSectorSize(pPager);
- if( !useJournal ){
- pPager->journalMode = PAGER_JOURNALMODE_OFF;
- }else if( memDb ){
- pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
- }
- /* pPager->xBusyHandler = 0; */
- /* pPager->pBusyHandlerArg = 0; */
- pPager->xReiniter = xReinit;
- /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
-
- *ppPager = pPager;
- return SQLITE_OK;
-}
-
-
-
-/*
-** This function is called after transitioning from PAGER_UNLOCK to
-** PAGER_SHARED state. It tests if there is a hot journal present in
-** the file-system for the given pager. A hot journal is one that
-** needs to be played back. According to this function, a hot-journal
-** file exists if the following criteria are met:
-**
-** * The journal file exists in the file system, and
-** * No process holds a RESERVED or greater lock on the database file, and
-** * The database file itself is greater than 0 bytes in size, and
-** * The first byte of the journal file exists and is not 0x00.
-**
-** If the current size of the database file is 0 but a journal file
-** exists, that is probably an old journal left over from a prior
-** database with the same name. In this case the journal file is
-** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK
-** is returned.
-**
-** This routine does not check if there is a master journal filename
-** at the end of the file. If there is, and that master journal file
-** does not exist, then the journal file is not really hot. In this
-** case this routine will return a false-positive. The pager_playback()
-** routine will discover that the journal file is not really hot and
-** will not roll it back.
-**
-** If a hot-journal file is found to exist, *pExists is set to 1 and
-** SQLITE_OK returned. If no hot-journal file is present, *pExists is
-** set to 0 and SQLITE_OK returned. If an IO error occurs while trying
-** to determine whether or not a hot-journal file exists, the IO error
-** code is returned and the value of *pExists is undefined.
-*/
-static int hasHotJournal(Pager *pPager, int *pExists){
- sqlite3_vfs * const pVfs = pPager->pVfs;
- int rc = SQLITE_OK; /* Return code */
- int exists = 1; /* True if a journal file is present */
- int jrnlOpen = !!isOpen(pPager->jfd);
-
- assert( pPager->useJournal );
- assert( isOpen(pPager->fd) );
- assert( pPager->eState==PAGER_OPEN );
-
- assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) &
- SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
- ));
-
- *pExists = 0;
- if( !jrnlOpen ){
- rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
- }
- if( rc==SQLITE_OK && exists ){
- int locked = 0; /* True if some process holds a RESERVED lock */
-
- /* Race condition here: Another process might have been holding the
- ** the RESERVED lock and have a journal open at the sqlite3OsAccess()
- ** call above, but then delete the journal and drop the lock before
- ** we get to the following sqlite3OsCheckReservedLock() call. If that
- ** is the case, this routine might think there is a hot journal when
- ** in fact there is none. This results in a false-positive which will
- ** be dealt with by the playback routine. Ticket #3883.
- */
- rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
- if( rc==SQLITE_OK && !locked ){
- Pgno nPage; /* Number of pages in database file */
-
- /* Check the size of the database file. If it consists of 0 pages,
- ** then delete the journal file. See the header comment above for
- ** the reasoning here. Delete the obsolete journal file under
- ** a RESERVED lock to avoid race conditions and to avoid violating
- ** [H33020].
- */
- rc = pagerPagecount(pPager, &nPage);
- if( rc==SQLITE_OK ){
- if( nPage==0 ){
- sqlite3BeginBenignMalloc();
- if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
- sqlite3OsDelete(pVfs, pPager->zJournal, 0);
- if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
- }
- sqlite3EndBenignMalloc();
- }else{
- /* The journal file exists and no other connection has a reserved
- ** or greater lock on the database file. Now check that there is
- ** at least one non-zero bytes at the start of the journal file.
- ** If there is, then we consider this journal to be hot. If not,
- ** it can be ignored.
- */
- if( !jrnlOpen ){
- int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
- rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f);
- }
- if( rc==SQLITE_OK ){
- u8 first = 0;
- rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0);
- if( rc==SQLITE_IOERR_SHORT_READ ){
- rc = SQLITE_OK;
- }
- if( !jrnlOpen ){
- sqlite3OsClose(pPager->jfd);
- }
- *pExists = (first!=0);
- }else if( rc==SQLITE_CANTOPEN ){
- /* If we cannot open the rollback journal file in order to see if
- ** its has a zero header, that might be due to an I/O error, or
- ** it might be due to the race condition described above and in
- ** ticket #3883. Either way, assume that the journal is hot.
- ** This might be a false positive. But if it is, then the
- ** automatic journal playback and recovery mechanism will deal
- ** with it under an EXCLUSIVE lock where we do not need to
- ** worry so much with race conditions.
- */
- *pExists = 1;
- rc = SQLITE_OK;
- }
- }
- }
- }
- }
-
- return rc;
-}
-
-/*
-** This function is called to obtain a shared lock on the database file.
-** It is illegal to call sqlite3PagerAcquire() until after this function
-** has been successfully called. If a shared-lock is already held when
-** this function is called, it is a no-op.
-**
-** The following operations are also performed by this function.
-**
-** 1) If the pager is currently in PAGER_OPEN state (no lock held
-** on the database file), then an attempt is made to obtain a
-** SHARED lock on the database file. Immediately after obtaining
-** the SHARED lock, the file-system is checked for a hot-journal,
-** which is played back if present. Following any hot-journal
-** rollback, the contents of the cache are validated by checking
-** the 'change-counter' field of the database file header and
-** discarded if they are found to be invalid.
-**
-** 2) If the pager is running in exclusive-mode, and there are currently
-** no outstanding references to any pages, and is in the error state,
-** then an attempt is made to clear the error state by discarding
-** the contents of the page cache and rolling back any open journal
-** file.
-**
-** If everything is successful, SQLITE_OK is returned. If an IO error
-** occurs while locking the database, checking for a hot-journal file or
-** rolling back a journal file, the IO error code is returned.
-*/
-SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
-
- /* This routine is only called from b-tree and only when there are no
- ** outstanding pages. This implies that the pager state should either
- ** be OPEN or READER. READER is only possible if the pager is or was in
- ** exclusive access mode.
- */
- assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
- assert( assert_pager_state(pPager) );
- assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
- if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
-
- if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
- int bHotJournal = 1; /* True if there exists a hot journal-file */
-
- assert( !MEMDB );
-
- rc = pager_wait_on_lock(pPager, SHARED_LOCK);
- if( rc!=SQLITE_OK ){
- assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
- goto failed;
- }
-
- /* If a journal file exists, and there is no RESERVED lock on the
- ** database file, then it either needs to be played back or deleted.
- */
- if( pPager->eLock<=SHARED_LOCK ){
- rc = hasHotJournal(pPager, &bHotJournal);
- }
- if( rc!=SQLITE_OK ){
- goto failed;
- }
- if( bHotJournal ){
- /* Get an EXCLUSIVE lock on the database file. At this point it is
- ** important that a RESERVED lock is not obtained on the way to the
- ** EXCLUSIVE lock. If it were, another process might open the
- ** database file, detect the RESERVED lock, and conclude that the
- ** database is safe to read while this process is still rolling the
- ** hot-journal back.
- **
- ** Because the intermediate RESERVED lock is not requested, any
- ** other process attempting to access the database file will get to
- ** this point in the code and fail to obtain its own EXCLUSIVE lock
- ** on the database file.
- **
- ** Unless the pager is in locking_mode=exclusive mode, the lock is
- ** downgraded to SHARED_LOCK before this function returns.
- */
- rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
- if( rc!=SQLITE_OK ){
- goto failed;
- }
-
- /* If it is not already open and the file exists on disk, open the
- ** journal for read/write access. Write access is required because
- ** in exclusive-access mode the file descriptor will be kept open
- ** and possibly used for a transaction later on. Also, write-access
- ** is usually required to finalize the journal in journal_mode=persist
- ** mode (and also for journal_mode=truncate on some systems).
- **
- ** If the journal does not exist, it usually means that some
- ** other connection managed to get in and roll it back before
- ** this connection obtained the exclusive lock above. Or, it
- ** may mean that the pager was in the error-state when this
- ** function was called and the journal file does not exist.
- */
- if( !isOpen(pPager->jfd) ){
- sqlite3_vfs * const pVfs = pPager->pVfs;
- int bExists; /* True if journal file exists */
- rc = sqlite3OsAccess(
- pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists);
- if( rc==SQLITE_OK && bExists ){
- int fout = 0;
- int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
- assert( !pPager->tempFile );
- rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
- assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
- if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
- rc = SQLITE_CANTOPEN_BKPT;
- sqlite3OsClose(pPager->jfd);
- }
- }
- }
-
- /* Playback and delete the journal. Drop the database write
- ** lock and reacquire the read lock. Purge the cache before
- ** playing back the hot-journal so that we don't end up with
- ** an inconsistent cache. Sync the hot journal before playing
- ** it back since the process that crashed and left the hot journal
- ** probably did not sync it and we are required to always sync
- ** the journal before playing it back.
- */
- if( isOpen(pPager->jfd) ){
- assert( rc==SQLITE_OK );
- rc = pagerSyncHotJournal(pPager);
- if( rc==SQLITE_OK ){
- rc = pager_playback(pPager, 1);
- pPager->eState = PAGER_OPEN;
- }
- }else if( !pPager->exclusiveMode ){
- pagerUnlockDb(pPager, SHARED_LOCK);
- }
-
- if( rc!=SQLITE_OK ){
- /* This branch is taken if an error occurs while trying to open
- ** or roll back a hot-journal while holding an EXCLUSIVE lock. The
- ** pager_unlock() routine will be called before returning to unlock
- ** the file. If the unlock attempt fails, then Pager.eLock must be
- ** set to UNKNOWN_LOCK (see the comment above the #define for
- ** UNKNOWN_LOCK above for an explanation).
- **
- ** In order to get pager_unlock() to do this, set Pager.eState to
- ** PAGER_ERROR now. This is not actually counted as a transition
- ** to ERROR state in the state diagram at the top of this file,
- ** since we know that the same call to pager_unlock() will very
- ** shortly transition the pager object to the OPEN state. Calling
- ** assert_pager_state() would fail now, as it should not be possible
- ** to be in ERROR state when there are zero outstanding page
- ** references.
- */
- pager_error(pPager, rc);
- goto failed;
- }
-
- assert( pPager->eState==PAGER_OPEN );
- assert( (pPager->eLock==SHARED_LOCK)
- || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
- );
- }
-
- if( !pPager->tempFile
- && (pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0)
- ){
- /* The shared-lock has just been acquired on the database file
- ** and there are already pages in the cache (from a previous
- ** read or write transaction). Check to see if the database
- ** has been modified. If the database has changed, flush the
- ** cache.
- **
- ** Database changes is detected by looking at 15 bytes beginning
- ** at offset 24 into the file. The first 4 of these 16 bytes are
- ** a 32-bit counter that is incremented with each change. The
- ** other bytes change randomly with each file change when
- ** a codec is in use.
- **
- ** There is a vanishingly small chance that a change will not be
- ** detected. The chance of an undetected change is so small that
- ** it can be neglected.
- */
- Pgno nPage = 0;
- char dbFileVers[sizeof(pPager->dbFileVers)];
-
- rc = pagerPagecount(pPager, &nPage);
- if( rc ) goto failed;
-
- if( nPage>0 ){
- IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
- rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
- if( rc!=SQLITE_OK ){
- goto failed;
- }
- }else{
- memset(dbFileVers, 0, sizeof(dbFileVers));
- }
-
- if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
- pager_reset(pPager);
- }
- }
-
- /* If there is a WAL file in the file-system, open this database in WAL
- ** mode. Otherwise, the following function call is a no-op.
- */
- rc = pagerOpenWalIfPresent(pPager);
-#ifndef SQLITE_OMIT_WAL
- assert( pPager->pWal==0 || rc==SQLITE_OK );
-#endif
- }
-
- if( pagerUseWal(pPager) ){
- assert( rc==SQLITE_OK );
- rc = pagerBeginReadTransaction(pPager);
- }
-
- if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
- rc = pagerPagecount(pPager, &pPager->dbSize);
- }
-
- failed:
- if( rc!=SQLITE_OK ){
- assert( !MEMDB );
- pager_unlock(pPager);
- assert( pPager->eState==PAGER_OPEN );
- }else{
- pPager->eState = PAGER_READER;
- }
- return rc;
-}
-
-/*
-** If the reference count has reached zero, rollback any active
-** transaction and unlock the pager.
-**
-** Except, in locking_mode=EXCLUSIVE when there is nothing to in
-** the rollback journal, the unlock is not performed and there is
-** nothing to rollback, so this routine is a no-op.
-*/
-static void pagerUnlockIfUnused(Pager *pPager){
- if( (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
- pagerUnlockAndRollback(pPager);
- }
-}
-
-/*
-** Acquire a reference to page number pgno in pager pPager (a page
-** reference has type DbPage*). If the requested reference is
-** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
-**
-** If the requested page is already in the cache, it is returned.
-** Otherwise, a new page object is allocated and populated with data
-** read from the database file. In some cases, the pcache module may
-** choose not to allocate a new page object and may reuse an existing
-** object with no outstanding references.
-**
-** The extra data appended to a page is always initialized to zeros the
-** first time a page is loaded into memory. If the page requested is
-** already in the cache when this function is called, then the extra
-** data is left as it was when the page object was last used.
-**
-** If the database image is smaller than the requested page or if a
-** non-zero value is passed as the noContent parameter and the
-** requested page is not already stored in the cache, then no
-** actual disk read occurs. In this case the memory image of the
-** page is initialized to all zeros.
-**
-** If noContent is true, it means that we do not care about the contents
-** of the page. This occurs in two seperate scenarios:
-**
-** a) When reading a free-list leaf page from the database, and
-**
-** b) When a savepoint is being rolled back and we need to load
-** a new page into the cache to be filled with the data read
-** from the savepoint journal.
-**
-** If noContent is true, then the data returned is zeroed instead of
-** being read from the database. Additionally, the bits corresponding
-** to pgno in Pager.pInJournal (bitvec of pages already written to the
-** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
-** savepoints are set. This means if the page is made writable at any
-** point in the future, using a call to sqlite3PagerWrite(), its contents
-** will not be journaled. This saves IO.
-**
-** The acquisition might fail for several reasons. In all cases,
-** an appropriate error code is returned and *ppPage is set to NULL.
-**
-** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt
-** to find a page in the in-memory cache first. If the page is not already
-** in memory, this routine goes to disk to read it in whereas Lookup()
-** just returns 0. This routine acquires a read-lock the first time it
-** has to go to disk, and could also playback an old journal if necessary.
-** Since Lookup() never goes to disk, it never has to deal with locks
-** or journal files.
-*/
-SQLITE_PRIVATE int sqlite3PagerAcquire(
- Pager *pPager, /* The pager open on the database file */
- Pgno pgno, /* Page number to fetch */
- DbPage **ppPage, /* Write a pointer to the page here */
- int noContent /* Do not bother reading content from disk if true */
-){
- int rc;
- PgHdr *pPg;
-
- assert( pPager->eState>=PAGER_READER );
- assert( assert_pager_state(pPager) );
-
- if( pgno==0 ){
- return SQLITE_CORRUPT_BKPT;
- }
-
- /* If the pager is in the error state, return an error immediately.
- ** Otherwise, request the page from the PCache layer. */
- if( pPager->errCode!=SQLITE_OK ){
- rc = pPager->errCode;
- }else{
- rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage);
- }
-
- if( rc!=SQLITE_OK ){
- /* Either the call to sqlite3PcacheFetch() returned an error or the
- ** pager was already in the error-state when this function was called.
- ** Set pPg to 0 and jump to the exception handler. */
- pPg = 0;
- goto pager_acquire_err;
- }
- assert( (*ppPage)->pgno==pgno );
- assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 );
-
- if( (*ppPage)->pPager && !noContent ){
- /* In this case the pcache already contains an initialized copy of
- ** the page. Return without further ado. */
- assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
- pPager->aStat[PAGER_STAT_HIT]++;
- return SQLITE_OK;
-
- }else{
- /* The pager cache has created a new page. Its content needs to
- ** be initialized. */
-
- pPg = *ppPage;
- pPg->pPager = pPager;
-
- /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
- ** number greater than this, or the unused locking-page, is requested. */
- if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
- rc = SQLITE_CORRUPT_BKPT;
- goto pager_acquire_err;
- }
-
- if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
- if( pgno>pPager->mxPgno ){
- rc = SQLITE_FULL;
- goto pager_acquire_err;
- }
- if( noContent ){
- /* Failure to set the bits in the InJournal bit-vectors is benign.
- ** It merely means that we might do some extra work to journal a
- ** page that does not need to be journaled. Nevertheless, be sure
- ** to test the case where a malloc error occurs while trying to set
- ** a bit in a bit vector.
- */
- sqlite3BeginBenignMalloc();
- if( pgno<=pPager->dbOrigSize ){
- TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno);
- testcase( rc==SQLITE_NOMEM );
- }
- TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno);
- testcase( rc==SQLITE_NOMEM );
- sqlite3EndBenignMalloc();
- }
- memset(pPg->pData, 0, pPager->pageSize);
- IOTRACE(("ZERO %p %d\n", pPager, pgno));
- }else{
- assert( pPg->pPager==pPager );
- pPager->aStat[PAGER_STAT_MISS]++;
- rc = readDbPage(pPg);
- if( rc!=SQLITE_OK ){
- goto pager_acquire_err;
- }
- }
- pager_set_pagehash(pPg);
- }
-
- return SQLITE_OK;
-
-pager_acquire_err:
- assert( rc!=SQLITE_OK );
- if( pPg ){
- sqlite3PcacheDrop(pPg);
- }
- pagerUnlockIfUnused(pPager);
-
- *ppPage = 0;
- return rc;
-}
-
-/*
-** Acquire a page if it is already in the in-memory cache. Do
-** not read the page from disk. Return a pointer to the page,
-** or 0 if the page is not in cache.
-**
-** See also sqlite3PagerGet(). The difference between this routine
-** and sqlite3PagerGet() is that _get() will go to the disk and read
-** in the page if the page is not already in cache. This routine
-** returns NULL if the page is not in cache or if a disk I/O error
-** has ever happened.
-*/
-SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
- PgHdr *pPg = 0;
- assert( pPager!=0 );
- assert( pgno!=0 );
- assert( pPager->pPCache!=0 );
- assert( pPager->eState>=PAGER_READER && pPager->eState!=PAGER_ERROR );
- sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
- return pPg;
-}
-
-/*
-** Release a page reference.
-**
-** If the number of references to the page drop to zero, then the
-** page is added to the LRU list. When all references to all pages
-** are released, a rollback occurs and the lock on the database is
-** removed.
-*/
-SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
- if( pPg ){
- Pager *pPager = pPg->pPager;
- sqlite3PcacheRelease(pPg);
- pagerUnlockIfUnused(pPager);
- }
-}
-
-/*
-** This function is called at the start of every write transaction.
-** There must already be a RESERVED or EXCLUSIVE lock on the database
-** file when this routine is called.
-**
-** Open the journal file for pager pPager and write a journal header
-** to the start of it. If there are active savepoints, open the sub-journal
-** as well. This function is only used when the journal file is being
-** opened to write a rollback log for a transaction. It is not used
-** when opening a hot journal file to roll it back.
-**
-** If the journal file is already open (as it may be in exclusive mode),
-** then this function just writes a journal header to the start of the
-** already open file.
-**
-** Whether or not the journal file is opened by this function, the
-** Pager.pInJournal bitvec structure is allocated.
-**
-** Return SQLITE_OK if everything is successful. Otherwise, return
-** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or
-** an IO error code if opening or writing the journal file fails.
-*/
-static int pager_open_journal(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
- sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */
-
- assert( pPager->eState==PAGER_WRITER_LOCKED );
- assert( assert_pager_state(pPager) );
- assert( pPager->pInJournal==0 );
-
- /* If already in the error state, this function is a no-op. But on
- ** the other hand, this routine is never called if we are already in
- ** an error state. */
- if( NEVER(pPager->errCode) ) return pPager->errCode;
-
- if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
- pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
- if( pPager->pInJournal==0 ){
- return SQLITE_NOMEM;
- }
-
- /* Open the journal file if it is not already open. */
- if( !isOpen(pPager->jfd) ){
- if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
- sqlite3MemJournalOpen(pPager->jfd);
- }else{
- const int flags = /* VFS flags to open journal file */
- SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
- (pPager->tempFile ?
- (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
- (SQLITE_OPEN_MAIN_JOURNAL)
- );
- #ifdef SQLITE_ENABLE_ATOMIC_WRITE
- rc = sqlite3JournalOpen(
- pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
- );
- #else
- rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
- #endif
- }
- assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
- }
-
-
- /* Write the first journal header to the journal file and open
- ** the sub-journal if necessary.
- */
- if( rc==SQLITE_OK ){
- /* TODO: Check if all of these are really required. */
- pPager->nRec = 0;
- pPager->journalOff = 0;
- pPager->setMaster = 0;
- pPager->journalHdr = 0;
- rc = writeJournalHdr(pPager);
- }
- }
-
- if( rc!=SQLITE_OK ){
- sqlite3BitvecDestroy(pPager->pInJournal);
- pPager->pInJournal = 0;
- }else{
- assert( pPager->eState==PAGER_WRITER_LOCKED );
- pPager->eState = PAGER_WRITER_CACHEMOD;
- }
-
- return rc;
-}
-
-/*
-** Begin a write-transaction on the specified pager object. If a
-** write-transaction has already been opened, this function is a no-op.
-**
-** If the exFlag argument is false, then acquire at least a RESERVED
-** lock on the database file. If exFlag is true, then acquire at least
-** an EXCLUSIVE lock. If such a lock is already held, no locking
-** functions need be called.
-**
-** If the subjInMemory argument is non-zero, then any sub-journal opened
-** within this transaction will be opened as an in-memory file. This
-** has no effect if the sub-journal is already opened (as it may be when
-** running in exclusive mode) or if the transaction does not require a
-** sub-journal. If the subjInMemory argument is zero, then any required
-** sub-journal is implemented in-memory if pPager is an in-memory database,
-** or using a temporary file otherwise.
-*/
-SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
- int rc = SQLITE_OK;
-
- if( pPager->errCode ) return pPager->errCode;
- assert( pPager->eState>=PAGER_READER && pPager->eState<PAGER_ERROR );
- pPager->subjInMemory = (u8)subjInMemory;
-
- if( ALWAYS(pPager->eState==PAGER_READER) ){
- assert( pPager->pInJournal==0 );
-
- if( pagerUseWal(pPager) ){
- /* If the pager is configured to use locking_mode=exclusive, and an
- ** exclusive lock on the database is not already held, obtain it now.
- */
- if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){
- rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- sqlite3WalExclusiveMode(pPager->pWal, 1);
- }
-
- /* Grab the write lock on the log file. If successful, upgrade to
- ** PAGER_RESERVED state. Otherwise, return an error code to the caller.
- ** The busy-handler is not invoked if another connection already
- ** holds the write-lock. If possible, the upper layer will call it.
- */
- rc = sqlite3WalBeginWriteTransaction(pPager->pWal);
- }else{
- /* Obtain a RESERVED lock on the database file. If the exFlag parameter
- ** is true, then immediately upgrade this to an EXCLUSIVE lock. The
- ** busy-handler callback can be used when upgrading to the EXCLUSIVE
- ** lock, but not when obtaining the RESERVED lock.
- */
- rc = pagerLockDb(pPager, RESERVED_LOCK);
- if( rc==SQLITE_OK && exFlag ){
- rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
- }
- }
-
- if( rc==SQLITE_OK ){
- /* Change to WRITER_LOCKED state.
- **
- ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD
- ** when it has an open transaction, but never to DBMOD or FINISHED.
- ** This is because in those states the code to roll back savepoint
- ** transactions may copy data from the sub-journal into the database
- ** file as well as into the page cache. Which would be incorrect in
- ** WAL mode.
- */
- pPager->eState = PAGER_WRITER_LOCKED;
- pPager->dbHintSize = pPager->dbSize;
- pPager->dbFileSize = pPager->dbSize;
- pPager->dbOrigSize = pPager->dbSize;
- pPager->journalOff = 0;
- }
-
- assert( rc==SQLITE_OK || pPager->eState==PAGER_READER );
- assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED );
- assert( assert_pager_state(pPager) );
- }
-
- PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
- return rc;
-}
-
-/*
-** Mark a single data page as writeable. The page is written into the
-** main journal or sub-journal as required. If the page is written into
-** one of the journals, the corresponding bit is set in the
-** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs
-** of any open savepoints as appropriate.
-*/
-static int pager_write(PgHdr *pPg){
- void *pData = pPg->pData;
- Pager *pPager = pPg->pPager;
- int rc = SQLITE_OK;
-
- /* This routine is not called unless a write-transaction has already
- ** been started. The journal file may or may not be open at this point.
- ** It is never called in the ERROR state.
- */
- assert( pPager->eState==PAGER_WRITER_LOCKED
- || pPager->eState==PAGER_WRITER_CACHEMOD
- || pPager->eState==PAGER_WRITER_DBMOD
- );
- assert( assert_pager_state(pPager) );
-
- /* If an error has been previously detected, report the same error
- ** again. This should not happen, but the check provides robustness. */
- if( NEVER(pPager->errCode) ) return pPager->errCode;
-
- /* Higher-level routines never call this function if database is not
- ** writable. But check anyway, just for robustness. */
- if( NEVER(pPager->readOnly) ) return SQLITE_PERM;
-
- CHECK_PAGE(pPg);
-
- /* The journal file needs to be opened. Higher level routines have already
- ** obtained the necessary locks to begin the write-transaction, but the
- ** rollback journal might not yet be open. Open it now if this is the case.
- **
- ** This is done before calling sqlite3PcacheMakeDirty() on the page.
- ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then
- ** an error might occur and the pager would end up in WRITER_LOCKED state
- ** with pages marked as dirty in the cache.
- */
- if( pPager->eState==PAGER_WRITER_LOCKED ){
- rc = pager_open_journal(pPager);
- if( rc!=SQLITE_OK ) return rc;
- }
- assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
- assert( assert_pager_state(pPager) );
-
- /* Mark the page as dirty. If the page has already been written
- ** to the journal then we can return right away.
- */
- sqlite3PcacheMakeDirty(pPg);
- if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){
- assert( !pagerUseWal(pPager) );
- }else{
-
- /* The transaction journal now exists and we have a RESERVED or an
- ** EXCLUSIVE lock on the main database file. Write the current page to
- ** the transaction journal if it is not there already.
- */
- if( !pageInJournal(pPg) && !pagerUseWal(pPager) ){
- assert( pagerUseWal(pPager)==0 );
- if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){
- u32 cksum;
- char *pData2;
- i64 iOff = pPager->journalOff;
-
- /* We should never write to the journal file the page that
- ** contains the database locks. The following assert verifies
- ** that we do not. */
- assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
-
- assert( pPager->journalHdr<=pPager->journalOff );
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
- cksum = pager_cksum(pPager, (u8*)pData2);
-
- /* Even if an IO or diskfull error occurs while journalling the
- ** page in the block above, set the need-sync flag for the page.
- ** Otherwise, when the transaction is rolled back, the logic in
- ** playback_one_page() will think that the page needs to be restored
- ** in the database file. And if an IO error occurs while doing so,
- ** then corruption may follow.
- */
- pPg->flags |= PGHDR_NEED_SYNC;
-
- rc = write32bits(pPager->jfd, iOff, pPg->pgno);
- if( rc!=SQLITE_OK ) return rc;
- rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4);
- if( rc!=SQLITE_OK ) return rc;
- rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum);
- if( rc!=SQLITE_OK ) return rc;
-
- IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno,
- pPager->journalOff, pPager->pageSize));
- PAGER_INCR(sqlite3_pager_writej_count);
- PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n",
- PAGERID(pPager), pPg->pgno,
- ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg)));
-
- pPager->journalOff += 8 + pPager->pageSize;
- pPager->nRec++;
- assert( pPager->pInJournal!=0 );
- rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
- testcase( rc==SQLITE_NOMEM );
- assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
- rc |= addToSavepointBitvecs(pPager, pPg->pgno);
- if( rc!=SQLITE_OK ){
- assert( rc==SQLITE_NOMEM );
- return rc;
- }
- }else{
- if( pPager->eState!=PAGER_WRITER_DBMOD ){
- pPg->flags |= PGHDR_NEED_SYNC;
- }
- PAGERTRACE(("APPEND %d page %d needSync=%d\n",
- PAGERID(pPager), pPg->pgno,
- ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
- }
- }
-
- /* If the statement journal is open and the page is not in it,
- ** then write the current page to the statement journal. Note that
- ** the statement journal format differs from the standard journal format
- ** in that it omits the checksums and the header.
- */
- if( subjRequiresPage(pPg) ){
- rc = subjournalPage(pPg);
- }
- }
-
- /* Update the database size and return.
- */
- if( pPager->dbSize<pPg->pgno ){
- pPager->dbSize = pPg->pgno;
- }
- return rc;
-}
-
-/*
-** Mark a data page as writeable. This routine must be called before
-** making changes to a page. The caller must check the return value
-** of this function and be careful not to change any page data unless
-** this routine returns SQLITE_OK.
-**
-** The difference between this function and pager_write() is that this
-** function also deals with the special case where 2 or more pages
-** fit on a single disk sector. In this case all co-resident pages
-** must have been written to the journal file before returning.
-**
-** If an error occurs, SQLITE_NOMEM or an IO error code is returned
-** as appropriate. Otherwise, SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
- int rc = SQLITE_OK;
-
- PgHdr *pPg = pDbPage;
- Pager *pPager = pPg->pPager;
- Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
-
- assert( pPager->eState>=PAGER_WRITER_LOCKED );
- assert( pPager->eState!=PAGER_ERROR );
- assert( assert_pager_state(pPager) );
-
- if( nPagePerSector>1 ){
- Pgno nPageCount; /* Total number of pages in database file */
- Pgno pg1; /* First page of the sector pPg is located on. */
- int nPage = 0; /* Number of pages starting at pg1 to journal */
- int ii; /* Loop counter */
- int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */
-
- /* Set the doNotSyncSpill flag to 1. This is because we cannot allow
- ** a journal header to be written between the pages journaled by
- ** this function.
- */
- assert( !MEMDB );
- assert( pPager->doNotSyncSpill==0 );
- pPager->doNotSyncSpill++;
-
- /* This trick assumes that both the page-size and sector-size are
- ** an integer power of 2. It sets variable pg1 to the identifier
- ** of the first page of the sector pPg is located on.
- */
- pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
-
- nPageCount = pPager->dbSize;
- if( pPg->pgno>nPageCount ){
- nPage = (pPg->pgno - pg1)+1;
- }else if( (pg1+nPagePerSector-1)>nPageCount ){
- nPage = nPageCount+1-pg1;
- }else{
- nPage = nPagePerSector;
- }
- assert(nPage>0);
- assert(pg1<=pPg->pgno);
- assert((pg1+nPage)>pPg->pgno);
-
- for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
- Pgno pg = pg1+ii;
- PgHdr *pPage;
- if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
- if( pg!=PAGER_MJ_PGNO(pPager) ){
- rc = sqlite3PagerGet(pPager, pg, &pPage);
- if( rc==SQLITE_OK ){
- rc = pager_write(pPage);
- if( pPage->flags&PGHDR_NEED_SYNC ){
- needSync = 1;
- }
- sqlite3PagerUnref(pPage);
- }
- }
- }else if( (pPage = pager_lookup(pPager, pg))!=0 ){
- if( pPage->flags&PGHDR_NEED_SYNC ){
- needSync = 1;
- }
- sqlite3PagerUnref(pPage);
- }
- }
-
- /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages
- ** starting at pg1, then it needs to be set for all of them. Because
- ** writing to any of these nPage pages may damage the others, the
- ** journal file must contain sync()ed copies of all of them
- ** before any of them can be written out to the database file.
- */
- if( rc==SQLITE_OK && needSync ){
- assert( !MEMDB );
- for(ii=0; ii<nPage; ii++){
- PgHdr *pPage = pager_lookup(pPager, pg1+ii);
- if( pPage ){
- pPage->flags |= PGHDR_NEED_SYNC;
- sqlite3PagerUnref(pPage);
- }
- }
- }
-
- assert( pPager->doNotSyncSpill==1 );
- pPager->doNotSyncSpill--;
- }else{
- rc = pager_write(pDbPage);
- }
- return rc;
-}
-
-/*
-** Return TRUE if the page given in the argument was previously passed
-** to sqlite3PagerWrite(). In other words, return TRUE if it is ok
-** to change the content of the page.
-*/
-#ifndef NDEBUG
-SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
- return pPg->flags&PGHDR_DIRTY;
-}
-#endif
-
-/*
-** A call to this routine tells the pager that it is not necessary to
-** write the information on page pPg back to the disk, even though
-** that page might be marked as dirty. This happens, for example, when
-** the page has been added as a leaf of the freelist and so its
-** content no longer matters.
-**
-** The overlying software layer calls this routine when all of the data
-** on the given page is unused. The pager marks the page as clean so
-** that it does not get written to disk.
-**
-** Tests show that this optimization can quadruple the speed of large
-** DELETE operations.
-*/
-SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
- Pager *pPager = pPg->pPager;
- if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
- PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
- IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
- pPg->flags |= PGHDR_DONT_WRITE;
- pager_set_pagehash(pPg);
- }
-}
-
-/*
-** This routine is called to increment the value of the database file
-** change-counter, stored as a 4-byte big-endian integer starting at
-** byte offset 24 of the pager file. The secondary change counter at
-** 92 is also updated, as is the SQLite version number at offset 96.
-**
-** But this only happens if the pPager->changeCountDone flag is false.
-** To avoid excess churning of page 1, the update only happens once.
-** See also the pager_write_changecounter() routine that does an
-** unconditional update of the change counters.
-**
-** If the isDirectMode flag is zero, then this is done by calling
-** sqlite3PagerWrite() on page 1, then modifying the contents of the
-** page data. In this case the file will be updated when the current
-** transaction is committed.
-**
-** The isDirectMode flag may only be non-zero if the library was compiled
-** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
-** if isDirect is non-zero, then the database file is updated directly
-** by writing an updated version of page 1 using a call to the
-** sqlite3OsWrite() function.
-*/
-static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
- int rc = SQLITE_OK;
-
- assert( pPager->eState==PAGER_WRITER_CACHEMOD
- || pPager->eState==PAGER_WRITER_DBMOD
- );
- assert( assert_pager_state(pPager) );
-
- /* Declare and initialize constant integer 'isDirect'. If the
- ** atomic-write optimization is enabled in this build, then isDirect
- ** is initialized to the value passed as the isDirectMode parameter
- ** to this function. Otherwise, it is always set to zero.
- **
- ** The idea is that if the atomic-write optimization is not
- ** enabled at compile time, the compiler can omit the tests of
- ** 'isDirect' below, as well as the block enclosed in the
- ** "if( isDirect )" condition.
- */
-#ifndef SQLITE_ENABLE_ATOMIC_WRITE
-# define DIRECT_MODE 0
- assert( isDirectMode==0 );
- UNUSED_PARAMETER(isDirectMode);
-#else
-# define DIRECT_MODE isDirectMode
-#endif
-
- if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
- PgHdr *pPgHdr; /* Reference to page 1 */
-
- assert( !pPager->tempFile && isOpen(pPager->fd) );
-
- /* Open page 1 of the file for writing. */
- rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
- assert( pPgHdr==0 || rc==SQLITE_OK );
-
- /* If page one was fetched successfully, and this function is not
- ** operating in direct-mode, make page 1 writable. When not in
- ** direct mode, page 1 is always held in cache and hence the PagerGet()
- ** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
- */
- if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
- rc = sqlite3PagerWrite(pPgHdr);
- }
-
- if( rc==SQLITE_OK ){
- /* Actually do the update of the change counter */
- pager_write_changecounter(pPgHdr);
-
- /* If running in direct mode, write the contents of page 1 to the file. */
- if( DIRECT_MODE ){
- const void *zBuf;
- assert( pPager->dbFileSize>0 );
- CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
- if( rc==SQLITE_OK ){
- rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
- pPager->aStat[PAGER_STAT_WRITE]++;
- }
- if( rc==SQLITE_OK ){
- pPager->changeCountDone = 1;
- }
- }else{
- pPager->changeCountDone = 1;
- }
- }
-
- /* Release the page reference. */
- sqlite3PagerUnref(pPgHdr);
- }
- return rc;
-}
-
-/*
-** Sync the database file to disk. This is a no-op for in-memory databases
-** or pages with the Pager.noSync flag set.
-**
-** If successful, or if called on a pager for which it is a no-op, this
-** function returns SQLITE_OK. Otherwise, an IO error code is returned.
-*/
-SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){
- int rc = SQLITE_OK;
- if( !pPager->noSync ){
- assert( !MEMDB );
- rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
- }else if( isOpen(pPager->fd) ){
- assert( !MEMDB );
- rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, 0);
- if( rc==SQLITE_NOTFOUND ){
- rc = SQLITE_OK;
- }
- }
- return rc;
-}
-
-/*
-** This function may only be called while a write-transaction is active in
-** rollback. If the connection is in WAL mode, this call is a no-op.
-** Otherwise, if the connection does not already have an EXCLUSIVE lock on
-** the database file, an attempt is made to obtain one.
-**
-** If the EXCLUSIVE lock is already held or the attempt to obtain it is
-** successful, or the connection is in WAL mode, SQLITE_OK is returned.
-** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is
-** returned.
-*/
-SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){
- int rc = SQLITE_OK;
- assert( pPager->eState==PAGER_WRITER_CACHEMOD
- || pPager->eState==PAGER_WRITER_DBMOD
- || pPager->eState==PAGER_WRITER_LOCKED
- );
- assert( assert_pager_state(pPager) );
- if( 0==pagerUseWal(pPager) ){
- rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
- }
- return rc;
-}
-
-/*
-** Sync the database file for the pager pPager. zMaster points to the name
-** of a master journal file that should be written into the individual
-** journal file. zMaster may be NULL, which is interpreted as no master
-** journal (a single database transaction).
-**
-** This routine ensures that:
-**
-** * The database file change-counter is updated,
-** * the journal is synced (unless the atomic-write optimization is used),
-** * all dirty pages are written to the database file,
-** * the database file is truncated (if required), and
-** * the database file synced.
-**
-** The only thing that remains to commit the transaction is to finalize
-** (delete, truncate or zero the first part of) the journal file (or
-** delete the master journal file if specified).
-**
-** Note that if zMaster==NULL, this does not overwrite a previous value
-** passed to an sqlite3PagerCommitPhaseOne() call.
-**
-** If the final parameter - noSync - is true, then the database file itself
-** is not synced. The caller must call sqlite3PagerSync() directly to
-** sync the database file before calling CommitPhaseTwo() to delete the
-** journal file in this case.
-*/
-SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
- Pager *pPager, /* Pager object */
- const char *zMaster, /* If not NULL, the master journal name */
- int noSync /* True to omit the xSync on the db file */
-){
- int rc = SQLITE_OK; /* Return code */
-
- assert( pPager->eState==PAGER_WRITER_LOCKED
- || pPager->eState==PAGER_WRITER_CACHEMOD
- || pPager->eState==PAGER_WRITER_DBMOD
- || pPager->eState==PAGER_ERROR
- );
- assert( assert_pager_state(pPager) );
-
- /* If a prior error occurred, report that error again. */
- if( NEVER(pPager->errCode) ) return pPager->errCode;
-
- PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n",
- pPager->zFilename, zMaster, pPager->dbSize));
-
- /* If no database changes have been made, return early. */
- if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
-
- if( MEMDB ){
- /* If this is an in-memory db, or no pages have been written to, or this
- ** function has already been called, it is mostly a no-op. However, any
- ** backup in progress needs to be restarted.
- */
- sqlite3BackupRestart(pPager->pBackup);
- }else{
- if( pagerUseWal(pPager) ){
- PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
- PgHdr *pPageOne = 0;
- if( pList==0 ){
- /* Must have at least one page for the WAL commit flag.
- ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
- rc = sqlite3PagerGet(pPager, 1, &pPageOne);
- pList = pPageOne;
- pList->pDirty = 0;
- }
- assert( rc==SQLITE_OK );
- if( ALWAYS(pList) ){
- rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1);
- }
- sqlite3PagerUnref(pPageOne);
- if( rc==SQLITE_OK ){
- sqlite3PcacheCleanAll(pPager->pPCache);
- }
- }else{
- /* The following block updates the change-counter. Exactly how it
- ** does this depends on whether or not the atomic-update optimization
- ** was enabled at compile time, and if this transaction meets the
- ** runtime criteria to use the operation:
- **
- ** * The file-system supports the atomic-write property for
- ** blocks of size page-size, and
- ** * This commit is not part of a multi-file transaction, and
- ** * Exactly one page has been modified and store in the journal file.
- **
- ** If the optimization was not enabled at compile time, then the
- ** pager_incr_changecounter() function is called to update the change
- ** counter in 'indirect-mode'. If the optimization is compiled in but
- ** is not applicable to this transaction, call sqlite3JournalCreate()
- ** to make sure the journal file has actually been created, then call
- ** pager_incr_changecounter() to update the change-counter in indirect
- ** mode.
- **
- ** Otherwise, if the optimization is both enabled and applicable,
- ** then call pager_incr_changecounter() to update the change-counter
- ** in 'direct' mode. In this case the journal file will never be
- ** created for this transaction.
- */
- #ifdef SQLITE_ENABLE_ATOMIC_WRITE
- PgHdr *pPg;
- assert( isOpen(pPager->jfd)
- || pPager->journalMode==PAGER_JOURNALMODE_OFF
- || pPager->journalMode==PAGER_JOURNALMODE_WAL
- );
- if( !zMaster && isOpen(pPager->jfd)
- && pPager->journalOff==jrnlBufferSize(pPager)
- && pPager->dbSize>=pPager->dbOrigSize
- && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
- ){
- /* Update the db file change counter via the direct-write method. The
- ** following call will modify the in-memory representation of page 1
- ** to include the updated change counter and then write page 1
- ** directly to the database file. Because of the atomic-write
- ** property of the host file-system, this is safe.
- */
- rc = pager_incr_changecounter(pPager, 1);
- }else{
- rc = sqlite3JournalCreate(pPager->jfd);
- if( rc==SQLITE_OK ){
- rc = pager_incr_changecounter(pPager, 0);
- }
- }
- #else
- rc = pager_incr_changecounter(pPager, 0);
- #endif
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-
- /* If this transaction has made the database smaller, then all pages
- ** being discarded by the truncation must be written to the journal
- ** file.
- **
- ** Before reading the pages with page numbers larger than the
- ** current value of Pager.dbSize, set dbSize back to the value
- ** that it took at the start of the transaction. Otherwise, the
- ** calls to sqlite3PagerGet() return zeroed pages instead of
- ** reading data from the database file.
- */
- if( pPager->dbSize<pPager->dbOrigSize
- && pPager->journalMode!=PAGER_JOURNALMODE_OFF
- ){
- Pgno i; /* Iterator variable */
- const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
- const Pgno dbSize = pPager->dbSize; /* Database image size */
- pPager->dbSize = pPager->dbOrigSize;
- for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
- if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
- PgHdr *pPage; /* Page to journal */
- rc = sqlite3PagerGet(pPager, i, &pPage);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
- rc = sqlite3PagerWrite(pPage);
- sqlite3PagerUnref(pPage);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
- }
- }
- pPager->dbSize = dbSize;
- }
-
- /* Write the master journal name into the journal file. If a master
- ** journal file name has already been written to the journal file,
- ** or if zMaster is NULL (no master journal), then this call is a no-op.
- */
- rc = writeMasterJournal(pPager, zMaster);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-
- /* Sync the journal file and write all dirty pages to the database.
- ** If the atomic-update optimization is being used, this sync will not
- ** create the journal file or perform any real IO.
- **
- ** Because the change-counter page was just modified, unless the
- ** atomic-update optimization is used it is almost certain that the
- ** journal requires a sync here. However, in locking_mode=exclusive
- ** on a system under memory pressure it is just possible that this is
- ** not the case. In this case it is likely enough that the redundant
- ** xSync() call will be changed to a no-op by the OS anyhow.
- */
- rc = syncJournal(pPager, 0);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-
- rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
- if( rc!=SQLITE_OK ){
- assert( rc!=SQLITE_IOERR_BLOCKED );
- goto commit_phase_one_exit;
- }
- sqlite3PcacheCleanAll(pPager->pPCache);
-
- /* If the file on disk is not the same size as the database image,
- ** then use pager_truncate to grow or shrink the file here.
- */
- if( pPager->dbSize!=pPager->dbFileSize ){
- Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
- assert( pPager->eState==PAGER_WRITER_DBMOD );
- rc = pager_truncate(pPager, nNew);
- if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
- }
-
- /* Finally, sync the database file. */
- if( !noSync ){
- rc = sqlite3PagerSync(pPager);
- }
- IOTRACE(("DBSYNC %p\n", pPager))
- }
- }
-
-commit_phase_one_exit:
- if( rc==SQLITE_OK && !pagerUseWal(pPager) ){
- pPager->eState = PAGER_WRITER_FINISHED;
- }
- return rc;
-}
-
-
-/*
-** When this function is called, the database file has been completely
-** updated to reflect the changes made by the current transaction and
-** synced to disk. The journal file still exists in the file-system
-** though, and if a failure occurs at this point it will eventually
-** be used as a hot-journal and the current transaction rolled back.
-**
-** This function finalizes the journal file, either by deleting,
-** truncating or partially zeroing it, so that it cannot be used
-** for hot-journal rollback. Once this is done the transaction is
-** irrevocably committed.
-**
-** If an error occurs, an IO error code is returned and the pager
-** moves into the error state. Otherwise, SQLITE_OK is returned.
-*/
-SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
-
- /* This routine should not be called if a prior error has occurred.
- ** But if (due to a coding error elsewhere in the system) it does get
- ** called, just return the same error code without doing anything. */
- if( NEVER(pPager->errCode) ) return pPager->errCode;
-
- assert( pPager->eState==PAGER_WRITER_LOCKED
- || pPager->eState==PAGER_WRITER_FINISHED
- || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
- );
- assert( assert_pager_state(pPager) );
-
- /* An optimization. If the database was not actually modified during
- ** this transaction, the pager is running in exclusive-mode and is
- ** using persistent journals, then this function is a no-op.
- **
- ** The start of the journal file currently contains a single journal
- ** header with the nRec field set to 0. If such a journal is used as
- ** a hot-journal during hot-journal rollback, 0 changes will be made
- ** to the database file. So there is no need to zero the journal
- ** header. Since the pager is in exclusive mode, there is no need
- ** to drop any locks either.
- */
- if( pPager->eState==PAGER_WRITER_LOCKED
- && pPager->exclusiveMode
- && pPager->journalMode==PAGER_JOURNALMODE_PERSIST
- ){
- assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff );
- pPager->eState = PAGER_READER;
- return SQLITE_OK;
- }
-
- PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
- rc = pager_end_transaction(pPager, pPager->setMaster);
- return pager_error(pPager, rc);
-}
-
-/*
-** If a write transaction is open, then all changes made within the
-** transaction are reverted and the current write-transaction is closed.
-** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR
-** state if an error occurs.
-**
-** If the pager is already in PAGER_ERROR state when this function is called,
-** it returns Pager.errCode immediately. No work is performed in this case.
-**
-** Otherwise, in rollback mode, this function performs two functions:
-**
-** 1) It rolls back the journal file, restoring all database file and
-** in-memory cache pages to the state they were in when the transaction
-** was opened, and
-**
-** 2) It finalizes the journal file, so that it is not used for hot
-** rollback at any point in the future.
-**
-** Finalization of the journal file (task 2) is only performed if the
-** rollback is successful.
-**
-** In WAL mode, all cache-entries containing data modified within the
-** current transaction are either expelled from the cache or reverted to
-** their pre-transaction state by re-reading data from the database or
-** WAL files. The WAL transaction is then closed.
-*/
-SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
- int rc = SQLITE_OK; /* Return code */
- PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
-
- /* PagerRollback() is a no-op if called in READER or OPEN state. If
- ** the pager is already in the ERROR state, the rollback is not
- ** attempted here. Instead, the error code is returned to the caller.
- */
- assert( assert_pager_state(pPager) );
- if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
- if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
-
- if( pagerUseWal(pPager) ){
- int rc2;
- rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
- rc2 = pager_end_transaction(pPager, pPager->setMaster);
- if( rc==SQLITE_OK ) rc = rc2;
- }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
- int eState = pPager->eState;
- rc = pager_end_transaction(pPager, 0);
- if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
- /* This can happen using journal_mode=off. Move the pager to the error
- ** state to indicate that the contents of the cache may not be trusted.
- ** Any active readers will get SQLITE_ABORT.
- */
- pPager->errCode = SQLITE_ABORT;
- pPager->eState = PAGER_ERROR;
- return rc;
- }
- }else{
- rc = pager_playback(pPager, 0);
- }
-
- assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
- assert( rc==SQLITE_OK || rc==SQLITE_FULL
- || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR );
-
- /* If an error occurs during a ROLLBACK, we can no longer trust the pager
- ** cache. So call pager_error() on the way out to make any error persistent.
- */
- return pager_error(pPager, rc);
-}
-
-/*
-** Return TRUE if the database file is opened read-only. Return FALSE
-** if the database is (in theory) writable.
-*/
-SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
- return pPager->readOnly;
-}
-
-/*
-** Return the number of references to the pager.
-*/
-SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
- return sqlite3PcacheRefCount(pPager->pPCache);
-}
-
-/*
-** Return the approximate number of bytes of memory currently
-** used by the pager and its associated cache.
-*/
-SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){
- int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr)
- + 5*sizeof(void*);
- return perPageSize*sqlite3PcachePagecount(pPager->pPCache)
- + sqlite3MallocSize(pPager)
- + pPager->pageSize;
-}
-
-/*
-** Return the number of references to the specified page.
-*/
-SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){
- return sqlite3PcachePageRefcount(pPage);
-}
-
-#ifdef SQLITE_TEST
-/*
-** This routine is used for testing and analysis only.
-*/
-SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){
- static int a[11];
- a[0] = sqlite3PcacheRefCount(pPager->pPCache);
- a[1] = sqlite3PcachePagecount(pPager->pPCache);
- a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
- a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize;
- a[4] = pPager->eState;
- a[5] = pPager->errCode;
- a[6] = pPager->aStat[PAGER_STAT_HIT];
- a[7] = pPager->aStat[PAGER_STAT_MISS];
- a[8] = 0; /* Used to be pPager->nOvfl */
- a[9] = pPager->nRead;
- a[10] = pPager->aStat[PAGER_STAT_WRITE];
- return a;
-}
-#endif
-
-/*
-** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
-** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
-** current cache hit or miss count, according to the value of eStat. If the
-** reset parameter is non-zero, the cache hit or miss count is zeroed before
-** returning.
-*/
-SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
-
- assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
- || eStat==SQLITE_DBSTATUS_CACHE_MISS
- || eStat==SQLITE_DBSTATUS_CACHE_WRITE
- );
-
- assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS );
- assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE );
- assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 );
-
- *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
- if( reset ){
- pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
- }
-}
-
-/*
-** Return true if this is an in-memory pager.
-*/
-SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
- return MEMDB;
-}
-
-/*
-** Check that there are at least nSavepoint savepoints open. If there are
-** currently less than nSavepoints open, then open one or more savepoints
-** to make up the difference. If the number of savepoints is already
-** equal to nSavepoint, then this function is a no-op.
-**
-** If a memory allocation fails, SQLITE_NOMEM is returned. If an error
-** occurs while opening the sub-journal file, then an IO error code is
-** returned. Otherwise, SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
- int rc = SQLITE_OK; /* Return code */
- int nCurrent = pPager->nSavepoint; /* Current number of savepoints */
-
- assert( pPager->eState>=PAGER_WRITER_LOCKED );
- assert( assert_pager_state(pPager) );
-
- if( nSavepoint>nCurrent && pPager->useJournal ){
- int ii; /* Iterator variable */
- PagerSavepoint *aNew; /* New Pager.aSavepoint array */
-
- /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
- ** if the allocation fails. Otherwise, zero the new portion in case a
- ** malloc failure occurs while populating it in the for(...) loop below.
- */
- aNew = (PagerSavepoint *)sqlite3Realloc(
- pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
- );
- if( !aNew ){
- return SQLITE_NOMEM;
- }
- memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
- pPager->aSavepoint = aNew;
-
- /* Populate the PagerSavepoint structures just allocated. */
- for(ii=nCurrent; ii<nSavepoint; ii++){
- aNew[ii].nOrig = pPager->dbSize;
- if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
- aNew[ii].iOffset = pPager->journalOff;
- }else{
- aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
- }
- aNew[ii].iSubRec = pPager->nSubRec;
- aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
- if( !aNew[ii].pInSavepoint ){
- return SQLITE_NOMEM;
- }
- if( pagerUseWal(pPager) ){
- sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
- }
- pPager->nSavepoint = ii+1;
- }
- assert( pPager->nSavepoint==nSavepoint );
- assertTruncateConstraint(pPager);
- }
-
- return rc;
-}
-
-/*
-** This function is called to rollback or release (commit) a savepoint.
-** The savepoint to release or rollback need not be the most recently
-** created savepoint.
-**
-** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE.
-** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with
-** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes
-** that have occurred since the specified savepoint was created.
-**
-** The savepoint to rollback or release is identified by parameter
-** iSavepoint. A value of 0 means to operate on the outermost savepoint
-** (the first created). A value of (Pager.nSavepoint-1) means operate
-** on the most recently created savepoint. If iSavepoint is greater than
-** (Pager.nSavepoint-1), then this function is a no-op.
-**
-** If a negative value is passed to this function, then the current
-** transaction is rolled back. This is different to calling
-** sqlite3PagerRollback() because this function does not terminate
-** the transaction or unlock the database, it just restores the
-** contents of the database to its original state.
-**
-** In any case, all savepoints with an index greater than iSavepoint
-** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE),
-** then savepoint iSavepoint is also destroyed.
-**
-** This function may return SQLITE_NOMEM if a memory allocation fails,
-** or an IO error code if an IO error occurs while rolling back a
-** savepoint. If no errors occur, SQLITE_OK is returned.
-*/
-SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
- int rc = pPager->errCode; /* Return code */
-
- assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
- assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
-
- if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){
- int ii; /* Iterator variable */
- int nNew; /* Number of remaining savepoints after this op. */
-
- /* Figure out how many savepoints will still be active after this
- ** operation. Store this value in nNew. Then free resources associated
- ** with any savepoints that are destroyed by this operation.
- */
- nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1);
- for(ii=nNew; ii<pPager->nSavepoint; ii++){
- sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
- }
- pPager->nSavepoint = nNew;
-
- /* If this is a release of the outermost savepoint, truncate
- ** the sub-journal to zero bytes in size. */
- if( op==SAVEPOINT_RELEASE ){
- if( nNew==0 && isOpen(pPager->sjfd) ){
- /* Only truncate if it is an in-memory sub-journal. */
- if( sqlite3IsMemJournal(pPager->sjfd) ){
- rc = sqlite3OsTruncate(pPager->sjfd, 0);
- assert( rc==SQLITE_OK );
- }
- pPager->nSubRec = 0;
- }
- }
- /* Else this is a rollback operation, playback the specified savepoint.
- ** If this is a temp-file, it is possible that the journal file has
- ** not yet been opened. In this case there have been no changes to
- ** the database file, so the playback operation can be skipped.
- */
- else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){
- PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
- rc = pagerPlaybackSavepoint(pPager, pSavepoint);
- assert(rc!=SQLITE_DONE);
- }
- }
-
- return rc;
-}
-
-/*
-** Return the full pathname of the database file.
-**
-** Except, if the pager is in-memory only, then return an empty string if
-** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when
-** used to report the filename to the user, for compatibility with legacy
-** behavior. But when the Btree needs to know the filename for matching to
-** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
-** participate in shared-cache.
-*/
-SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
- return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
-}
-
-/*
-** Return the VFS structure for the pager.
-*/
-SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
- return pPager->pVfs;
-}
-
-/*
-** Return the file handle for the database file associated
-** with the pager. This might return NULL if the file has
-** not yet been opened.
-*/
-SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
- return pPager->fd;
-}
-
-/*
-** Return the full pathname of the journal file.
-*/
-SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
- return pPager->zJournal;
-}
-
-/*
-** Return true if fsync() calls are disabled for this pager. Return FALSE
-** if fsync()s are executed normally.
-*/
-SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){
- return pPager->noSync;
-}
-
-#ifdef SQLITE_HAS_CODEC
-/*
-** Set or retrieve the codec for this pager
-*/
-SQLITE_PRIVATE void sqlite3PagerSetCodec(
- Pager *pPager,
- void *(*xCodec)(void*,void*,Pgno,int),
- void (*xCodecSizeChng)(void*,int,int),
- void (*xCodecFree)(void*),
- void *pCodec
-){
- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
- pPager->xCodec = pPager->memDb ? 0 : xCodec;
- pPager->xCodecSizeChng = xCodecSizeChng;
- pPager->xCodecFree = xCodecFree;
- pPager->pCodec = pCodec;
- pagerReportSize(pPager);
-}
-SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
- return pPager->pCodec;
-}
-#endif
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** Move the page pPg to location pgno in the file.
-**
-** There must be no references to the page previously located at
-** pgno (which we call pPgOld) though that page is allowed to be
-** in cache. If the page previously located at pgno is not already
-** in the rollback journal, it is not put there by by this routine.
-**
-** References to the page pPg remain valid. Updating any
-** meta-data associated with pPg (i.e. data stored in the nExtra bytes
-** allocated along with the page) is the responsibility of the caller.
-**
-** A transaction must be active when this routine is called. It used to be
-** required that a statement transaction was not active, but this restriction
-** has been removed (CREATE INDEX needs to move a page when a statement
-** transaction is active).
-**
-** If the fourth argument, isCommit, is non-zero, then this page is being
-** moved as part of a database reorganization just before the transaction
-** is being committed. In this case, it is guaranteed that the database page
-** pPg refers to will not be written to again within this transaction.
-**
-** This function may return SQLITE_NOMEM or an IO error code if an error
-** occurs. Otherwise, it returns SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
- PgHdr *pPgOld; /* The page being overwritten. */
- Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */
- int rc; /* Return code */
- Pgno origPgno; /* The original page number */
-
- assert( pPg->nRef>0 );
- assert( pPager->eState==PAGER_WRITER_CACHEMOD
- || pPager->eState==PAGER_WRITER_DBMOD
- );
- assert( assert_pager_state(pPager) );
-
- /* In order to be able to rollback, an in-memory database must journal
- ** the page we are moving from.
- */
- if( MEMDB ){
- rc = sqlite3PagerWrite(pPg);
- if( rc ) return rc;
- }
-
- /* If the page being moved is dirty and has not been saved by the latest
- ** savepoint, then save the current contents of the page into the
- ** sub-journal now. This is required to handle the following scenario:
- **
- ** BEGIN;
- ** <journal page X, then modify it in memory>
- ** SAVEPOINT one;
- ** <Move page X to location Y>
- ** ROLLBACK TO one;
- **
- ** If page X were not written to the sub-journal here, it would not
- ** be possible to restore its contents when the "ROLLBACK TO one"
- ** statement were is processed.
- **
- ** subjournalPage() may need to allocate space to store pPg->pgno into
- ** one or more savepoint bitvecs. This is the reason this function
- ** may return SQLITE_NOMEM.
- */
- if( pPg->flags&PGHDR_DIRTY
- && subjRequiresPage(pPg)
- && SQLITE_OK!=(rc = subjournalPage(pPg))
- ){
- return rc;
- }
-
- PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n",
- PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno));
- IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
-
- /* If the journal needs to be sync()ed before page pPg->pgno can
- ** be written to, store pPg->pgno in local variable needSyncPgno.
- **
- ** If the isCommit flag is set, there is no need to remember that
- ** the journal needs to be sync()ed before database page pPg->pgno
- ** can be written to. The caller has already promised not to write to it.
- */
- if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
- needSyncPgno = pPg->pgno;
- assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
- assert( pPg->flags&PGHDR_DIRTY );
- }
-
- /* If the cache contains a page with page-number pgno, remove it
- ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for
- ** page pgno before the 'move' operation, it needs to be retained
- ** for the page moved there.
- */
- pPg->flags &= ~PGHDR_NEED_SYNC;
- pPgOld = pager_lookup(pPager, pgno);
- assert( !pPgOld || pPgOld->nRef==1 );
- if( pPgOld ){
- pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
- if( MEMDB ){
- /* Do not discard pages from an in-memory database since we might
- ** need to rollback later. Just move the page out of the way. */
- sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
- }else{
- sqlite3PcacheDrop(pPgOld);
- }
- }
-
- origPgno = pPg->pgno;
- sqlite3PcacheMove(pPg, pgno);
- sqlite3PcacheMakeDirty(pPg);
-
- /* For an in-memory database, make sure the original page continues
- ** to exist, in case the transaction needs to roll back. Use pPgOld
- ** as the original page since it has already been allocated.
- */
- if( MEMDB ){
- assert( pPgOld );
- sqlite3PcacheMove(pPgOld, origPgno);
- sqlite3PagerUnref(pPgOld);
- }
-
- if( needSyncPgno ){
- /* If needSyncPgno is non-zero, then the journal file needs to be
- ** sync()ed before any data is written to database file page needSyncPgno.
- ** Currently, no such page exists in the page-cache and the
- ** "is journaled" bitvec flag has been set. This needs to be remedied by
- ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC
- ** flag.
- **
- ** If the attempt to load the page into the page-cache fails, (due
- ** to a malloc() or IO failure), clear the bit in the pInJournal[]
- ** array. Otherwise, if the page is loaded and written again in
- ** this transaction, it may be written to the database file before
- ** it is synced into the journal file. This way, it may end up in
- ** the journal file twice, but that is not a problem.
- */
- PgHdr *pPgHdr;
- rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
- if( rc!=SQLITE_OK ){
- if( needSyncPgno<=pPager->dbOrigSize ){
- assert( pPager->pTmpSpace!=0 );
- sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
- }
- return rc;
- }
- pPgHdr->flags |= PGHDR_NEED_SYNC;
- sqlite3PcacheMakeDirty(pPgHdr);
- sqlite3PagerUnref(pPgHdr);
- }
-
- return SQLITE_OK;
-}
-#endif
-
-/*
-** Return a pointer to the data for the specified page.
-*/
-SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
- assert( pPg->nRef>0 || pPg->pPager->memDb );
- return pPg->pData;
-}
-
-/*
-** Return a pointer to the Pager.nExtra bytes of "extra" space
-** allocated along with the specified page.
-*/
-SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){
- return pPg->pExtra;
-}
-
-/*
-** Get/set the locking-mode for this pager. Parameter eMode must be one
-** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or
-** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
-** the locking-mode is set to the value specified.
-**
-** The returned value is either PAGER_LOCKINGMODE_NORMAL or
-** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
-** locking-mode.
-*/
-SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){
- assert( eMode==PAGER_LOCKINGMODE_QUERY
- || eMode==PAGER_LOCKINGMODE_NORMAL
- || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
- assert( PAGER_LOCKINGMODE_QUERY<0 );
- assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
- assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) );
- if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){
- pPager->exclusiveMode = (u8)eMode;
- }
- return (int)pPager->exclusiveMode;
-}
-
-/*
-** Set the journal-mode for this pager. Parameter eMode must be one of:
-**
-** PAGER_JOURNALMODE_DELETE
-** PAGER_JOURNALMODE_TRUNCATE
-** PAGER_JOURNALMODE_PERSIST
-** PAGER_JOURNALMODE_OFF
-** PAGER_JOURNALMODE_MEMORY
-** PAGER_JOURNALMODE_WAL
-**
-** The journalmode is set to the value specified if the change is allowed.
-** The change may be disallowed for the following reasons:
-**
-** * An in-memory database can only have its journal_mode set to _OFF
-** or _MEMORY.
-**
-** * Temporary databases cannot have _WAL journalmode.
-**
-** The returned indicate the current (possibly updated) journal-mode.
-*/
-SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
- u8 eOld = pPager->journalMode; /* Prior journalmode */
-
-#ifdef SQLITE_DEBUG
- /* The print_pager_state() routine is intended to be used by the debugger
- ** only. We invoke it once here to suppress a compiler warning. */
- print_pager_state(pPager);
-#endif
-
-
- /* The eMode parameter is always valid */
- assert( eMode==PAGER_JOURNALMODE_DELETE
- || eMode==PAGER_JOURNALMODE_TRUNCATE
- || eMode==PAGER_JOURNALMODE_PERSIST
- || eMode==PAGER_JOURNALMODE_OFF
- || eMode==PAGER_JOURNALMODE_WAL
- || eMode==PAGER_JOURNALMODE_MEMORY );
-
- /* This routine is only called from the OP_JournalMode opcode, and
- ** the logic there will never allow a temporary file to be changed
- ** to WAL mode.
- */
- assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL );
-
- /* Do allow the journalmode of an in-memory database to be set to
- ** anything other than MEMORY or OFF
- */
- if( MEMDB ){
- assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
- if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
- eMode = eOld;
- }
- }
-
- if( eMode!=eOld ){
-
- /* Change the journal mode. */
- assert( pPager->eState!=PAGER_ERROR );
- pPager->journalMode = (u8)eMode;
-
- /* When transistioning from TRUNCATE or PERSIST to any other journal
- ** mode except WAL, unless the pager is in locking_mode=exclusive mode,
- ** delete the journal file.
- */
- assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
- assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
- assert( (PAGER_JOURNALMODE_DELETE & 5)==0 );
- assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 );
- assert( (PAGER_JOURNALMODE_OFF & 5)==0 );
- assert( (PAGER_JOURNALMODE_WAL & 5)==5 );
-
- assert( isOpen(pPager->fd) || pPager->exclusiveMode );
- if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){
-
- /* In this case we would like to delete the journal file. If it is
- ** not possible, then that is not a problem. Deleting the journal file
- ** here is an optimization only.
- **
- ** Before deleting the journal file, obtain a RESERVED lock on the
- ** database file. This ensures that the journal file is not deleted
- ** while it is in use by some other client.
- */
- sqlite3OsClose(pPager->jfd);
- if( pPager->eLock>=RESERVED_LOCK ){
- sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
- }else{
- int rc = SQLITE_OK;
- int state = pPager->eState;
- assert( state==PAGER_OPEN || state==PAGER_READER );
- if( state==PAGER_OPEN ){
- rc = sqlite3PagerSharedLock(pPager);
- }
- if( pPager->eState==PAGER_READER ){
- assert( rc==SQLITE_OK );
- rc = pagerLockDb(pPager, RESERVED_LOCK);
- }
- if( rc==SQLITE_OK ){
- sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
- }
- if( rc==SQLITE_OK && state==PAGER_READER ){
- pagerUnlockDb(pPager, SHARED_LOCK);
- }else if( state==PAGER_OPEN ){
- pager_unlock(pPager);
- }
- assert( state==pPager->eState );
- }
- }
- }
-
- /* Return the new journal mode */
- return (int)pPager->journalMode;
-}
-
-/*
-** Return the current journal mode.
-*/
-SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){
- return (int)pPager->journalMode;
-}
-
-/*
-** Return TRUE if the pager is in a state where it is OK to change the
-** journalmode. Journalmode changes can only happen when the database
-** is unmodified.
-*/
-SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
- assert( assert_pager_state(pPager) );
- if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0;
- if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0;
- return 1;
-}
-
-/*
-** Get/set the size-limit used for persistent journal files.
-**
-** Setting the size limit to -1 means no limit is enforced.
-** An attempt to set a limit smaller than -1 is a no-op.
-*/
-SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
- if( iLimit>=-1 ){
- pPager->journalSizeLimit = iLimit;
- sqlite3WalLimit(pPager->pWal, iLimit);
- }
- return pPager->journalSizeLimit;
-}
-
-/*
-** Return a pointer to the pPager->pBackup variable. The backup module
-** in backup.c maintains the content of this variable. This module
-** uses it opaquely as an argument to sqlite3BackupRestart() and
-** sqlite3BackupUpdate() only.
-*/
-SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
- return &pPager->pBackup;
-}
-
-#ifndef SQLITE_OMIT_VACUUM
-/*
-** Unless this is an in-memory or temporary database, clear the pager cache.
-*/
-SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
- if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
-}
-#endif
-
-#ifndef SQLITE_OMIT_WAL
-/*
-** This function is called when the user invokes "PRAGMA wal_checkpoint",
-** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
-** or wal_blocking_checkpoint() API functions.
-**
-** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
-*/
-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
- int rc = SQLITE_OK;
- if( pPager->pWal ){
- rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
- pPager->xBusyHandler, pPager->pBusyHandlerArg,
- pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
- pnLog, pnCkpt
- );
- }
- return rc;
-}
-
-SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
- return sqlite3WalCallback(pPager->pWal);
-}
-
-/*
-** Return true if the underlying VFS for the given pager supports the
-** primitives necessary for write-ahead logging.
-*/
-SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
- const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
- return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
-}
-
-/*
-** Attempt to take an exclusive lock on the database file. If a PENDING lock
-** is obtained instead, immediately release it.
-*/
-static int pagerExclusiveLock(Pager *pPager){
- int rc; /* Return code */
-
- assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
- rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
- if( rc!=SQLITE_OK ){
- /* If the attempt to grab the exclusive lock failed, release the
- ** pending lock that may have been obtained instead. */
- pagerUnlockDb(pPager, SHARED_LOCK);
- }
-
- return rc;
-}
-
-/*
-** Call sqlite3WalOpen() to open the WAL handle. If the pager is in
-** exclusive-locking mode when this function is called, take an EXCLUSIVE
-** lock on the database file and use heap-memory to store the wal-index
-** in. Otherwise, use the normal shared-memory.
-*/
-static int pagerOpenWal(Pager *pPager){
- int rc = SQLITE_OK;
-
- assert( pPager->pWal==0 && pPager->tempFile==0 );
- assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
-
- /* If the pager is already in exclusive-mode, the WAL module will use
- ** heap-memory for the wal-index instead of the VFS shared-memory
- ** implementation. Take the exclusive lock now, before opening the WAL
- ** file, to make sure this is safe.
- */
- if( pPager->exclusiveMode ){
- rc = pagerExclusiveLock(pPager);
- }
-
- /* Open the connection to the log file. If this operation fails,
- ** (e.g. due to malloc() failure), return an error code.
- */
- if( rc==SQLITE_OK ){
- rc = sqlite3WalOpen(pPager->pVfs,
- pPager->fd, pPager->zWal, pPager->exclusiveMode,
- pPager->journalSizeLimit, &pPager->pWal
- );
- }
-
- return rc;
-}
-
-
-/*
-** The caller must be holding a SHARED lock on the database file to call
-** this function.
-**
-** If the pager passed as the first argument is open on a real database
-** file (not a temp file or an in-memory database), and the WAL file
-** is not already open, make an attempt to open it now. If successful,
-** return SQLITE_OK. If an error occurs or the VFS used by the pager does
-** not support the xShmXXX() methods, return an error code. *pbOpen is
-** not modified in either case.
-**
-** If the pager is open on a temp-file (or in-memory database), or if
-** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK
-** without doing anything.
-*/
-SQLITE_PRIVATE int sqlite3PagerOpenWal(
- Pager *pPager, /* Pager object */
- int *pbOpen /* OUT: Set to true if call is a no-op */
-){
- int rc = SQLITE_OK; /* Return code */
-
- assert( assert_pager_state(pPager) );
- assert( pPager->eState==PAGER_OPEN || pbOpen );
- assert( pPager->eState==PAGER_READER || !pbOpen );
- assert( pbOpen==0 || *pbOpen==0 );
- assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) );
-
- if( !pPager->tempFile && !pPager->pWal ){
- if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
-
- /* Close any rollback journal previously open */
- sqlite3OsClose(pPager->jfd);
-
- rc = pagerOpenWal(pPager);
- if( rc==SQLITE_OK ){
- pPager->journalMode = PAGER_JOURNALMODE_WAL;
- pPager->eState = PAGER_OPEN;
- }
- }else{
- *pbOpen = 1;
- }
-
- return rc;
-}
-
-/*
-** This function is called to close the connection to the log file prior
-** to switching from WAL to rollback mode.
-**
-** Before closing the log file, this function attempts to take an
-** EXCLUSIVE lock on the database file. If this cannot be obtained, an
-** error (SQLITE_BUSY) is returned and the log connection is not closed.
-** If successful, the EXCLUSIVE lock is not released before returning.
-*/
-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
- int rc = SQLITE_OK;
-
- assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
-
- /* If the log file is not already open, but does exist in the file-system,
- ** it may need to be checkpointed before the connection can switch to
- ** rollback mode. Open it now so this can happen.
- */
- if( !pPager->pWal ){
- int logexists = 0;
- rc = pagerLockDb(pPager, SHARED_LOCK);
- if( rc==SQLITE_OK ){
- rc = sqlite3OsAccess(
- pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists
- );
- }
- if( rc==SQLITE_OK && logexists ){
- rc = pagerOpenWal(pPager);
- }
- }
-
- /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
- ** the database file, the log and log-summary files will be deleted.
- */
- if( rc==SQLITE_OK && pPager->pWal ){
- rc = pagerExclusiveLock(pPager);
- if( rc==SQLITE_OK ){
- rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
- pPager->pageSize, (u8*)pPager->pTmpSpace);
- pPager->pWal = 0;
- }
- }
- return rc;
-}
-
-#endif /* !SQLITE_OMIT_WAL */
-
-#ifdef SQLITE_ENABLE_ZIPVFS
-/*
-** A read-lock must be held on the pager when this function is called. If
-** the pager is in WAL mode and the WAL file currently contains one or more
-** frames, return the size in bytes of the page images stored within the
-** WAL frames. Otherwise, if this is not a WAL database or the WAL file
-** is empty, return 0.
-*/
-SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
- assert( pPager->eState==PAGER_READER );
- return sqlite3WalFramesize(pPager->pWal);
-}
-#endif
-
-#ifdef SQLITE_HAS_CODEC
-/*
-** This function is called by the wal module when writing page content
-** into the log file.
-**
-** This function returns a pointer to a buffer containing the encrypted
-** page content. If a malloc fails, this function may return NULL.
-*/
-SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
- void *aData = 0;
- CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
- return aData;
-}
-#endif /* SQLITE_HAS_CODEC */
-
-#endif /* SQLITE_OMIT_DISKIO */
-
-/************** End of pager.c ***********************************************/
-/************** Begin file wal.c *********************************************/
-/*
-** 2010 February 1
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains the implementation of a write-ahead log (WAL) used in
-** "journal_mode=WAL" mode.
-**
-** WRITE-AHEAD LOG (WAL) FILE FORMAT
-**
-** A WAL file consists of a header followed by zero or more "frames".
-** Each frame records the revised content of a single page from the
-** database file. All changes to the database are recorded by writing
-** frames into the WAL. Transactions commit when a frame is written that
-** contains a commit marker. A single WAL can and usually does record
-** multiple transactions. Periodically, the content of the WAL is
-** transferred back into the database file in an operation called a
-** "checkpoint".
-**
-** A single WAL file can be used multiple times. In other words, the
-** WAL can fill up with frames and then be checkpointed and then new
-** frames can overwrite the old ones. A WAL always grows from beginning
-** toward the end. Checksums and counters attached to each frame are
-** used to determine which frames within the WAL are valid and which
-** are leftovers from prior checkpoints.
-**
-** The WAL header is 32 bytes in size and consists of the following eight
-** big-endian 32-bit unsigned integer values:
-**
-** 0: Magic number. 0x377f0682 or 0x377f0683
-** 4: File format version. Currently 3007000
-** 8: Database page size. Example: 1024
-** 12: Checkpoint sequence number
-** 16: Salt-1, random integer incremented with each checkpoint
-** 20: Salt-2, a different random integer changing with each ckpt
-** 24: Checksum-1 (first part of checksum for first 24 bytes of header).
-** 28: Checksum-2 (second part of checksum for first 24 bytes of header).
-**
-** Immediately following the wal-header are zero or more frames. Each
-** frame consists of a 24-byte frame-header followed by a <page-size> bytes
-** of page data. The frame-header is six big-endian 32-bit unsigned
-** integer values, as follows:
-**
-** 0: Page number.
-** 4: For commit records, the size of the database image in pages
-** after the commit. For all other records, zero.
-** 8: Salt-1 (copied from the header)
-** 12: Salt-2 (copied from the header)
-** 16: Checksum-1.
-** 20: Checksum-2.
-**
-** A frame is considered valid if and only if the following conditions are
-** true:
-**
-** (1) The salt-1 and salt-2 values in the frame-header match
-** salt values in the wal-header
-**
-** (2) The checksum values in the final 8 bytes of the frame-header
-** exactly match the checksum computed consecutively on the
-** WAL header and the first 8 bytes and the content of all frames
-** up to and including the current frame.
-**
-** The checksum is computed using 32-bit big-endian integers if the
-** magic number in the first 4 bytes of the WAL is 0x377f0683 and it
-** is computed using little-endian if the magic number is 0x377f0682.
-** The checksum values are always stored in the frame header in a
-** big-endian format regardless of which byte order is used to compute
-** the checksum. The checksum is computed by interpreting the input as
-** an even number of unsigned 32-bit integers: x[0] through x[N]. The
-** algorithm used for the checksum is as follows:
-**
-** for i from 0 to n-1 step 2:
-** s0 += x[i] + s1;
-** s1 += x[i+1] + s0;
-** endfor
-**
-** Note that s0 and s1 are both weighted checksums using fibonacci weights
-** in reverse order (the largest fibonacci weight occurs on the first element
-** of the sequence being summed.) The s1 value spans all 32-bit
-** terms of the sequence whereas s0 omits the final term.
-**
-** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the
-** WAL is transferred into the database, then the database is VFS.xSync-ed.
-** The VFS.xSync operations serve as write barriers - all writes launched
-** before the xSync must complete before any write that launches after the
-** xSync begins.
-**
-** After each checkpoint, the salt-1 value is incremented and the salt-2
-** value is randomized. This prevents old and new frames in the WAL from
-** being considered valid at the same time and being checkpointing together
-** following a crash.
-**
-** READER ALGORITHM
-**
-** To read a page from the database (call it page number P), a reader
-** first checks the WAL to see if it contains page P. If so, then the
-** last valid instance of page P that is a followed by a commit frame
-** or is a commit frame itself becomes the value read. If the WAL
-** contains no copies of page P that are valid and which are a commit
-** frame or are followed by a commit frame, then page P is read from
-** the database file.
-**
-** To start a read transaction, the reader records the index of the last
-** valid frame in the WAL. The reader uses this recorded "mxFrame" value
-** for all subsequent read operations. New transactions can be appended
-** to the WAL, but as long as the reader uses its original mxFrame value
-** and ignores the newly appended content, it will see a consistent snapshot
-** of the database from a single point in time. This technique allows
-** multiple concurrent readers to view different versions of the database
-** content simultaneously.
-**
-** The reader algorithm in the previous paragraphs works correctly, but
-** because frames for page P can appear anywhere within the WAL, the
-** reader has to scan the entire WAL looking for page P frames. If the
-** WAL is large (multiple megabytes is typical) that scan can be slow,
-** and read performance suffers. To overcome this problem, a separate
-** data structure called the wal-index is maintained to expedite the
-** search for frames of a particular page.
-**
-** WAL-INDEX FORMAT
-**
-** Conceptually, the wal-index is shared memory, though VFS implementations
-** might choose to implement the wal-index using a mmapped file. Because
-** the wal-index is shared memory, SQLite does not support journal_mode=WAL
-** on a network filesystem. All users of the database must be able to
-** share memory.
-**
-** The wal-index is transient. After a crash, the wal-index can (and should
-** be) reconstructed from the original WAL file. In fact, the VFS is required
-** to either truncate or zero the header of the wal-index when the last
-** connection to it closes. Because the wal-index is transient, it can
-** use an architecture-specific format; it does not have to be cross-platform.
-** Hence, unlike the database and WAL file formats which store all values
-** as big endian, the wal-index can store multi-byte values in the native
-** byte order of the host computer.
-**
-** The purpose of the wal-index is to answer this question quickly: Given
-** a page number P and a maximum frame index M, return the index of the
-** last frame in the wal before frame M for page P in the WAL, or return
-** NULL if there are no frames for page P in the WAL prior to M.
-**
-** The wal-index consists of a header region, followed by an one or
-** more index blocks.
-**
-** The wal-index header contains the total number of frames within the WAL
-** in the mxFrame field.
-**
-** Each index block except for the first contains information on
-** HASHTABLE_NPAGE frames. The first index block contains information on
-** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and
-** HASHTABLE_NPAGE are selected so that together the wal-index header and
-** first index block are the same size as all other index blocks in the
-** wal-index.
-**
-** Each index block contains two sections, a page-mapping that contains the
-** database page number associated with each wal frame, and a hash-table
-** that allows readers to query an index block for a specific page number.
-** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE
-** for the first index block) 32-bit page numbers. The first entry in the
-** first index-block contains the database page number corresponding to the
-** first frame in the WAL file. The first entry in the second index block
-** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in
-** the log, and so on.
-**
-** The last index block in a wal-index usually contains less than the full
-** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers,
-** depending on the contents of the WAL file. This does not change the
-** allocated size of the page-mapping array - the page-mapping array merely
-** contains unused entries.
-**
-** Even without using the hash table, the last frame for page P
-** can be found by scanning the page-mapping sections of each index block
-** starting with the last index block and moving toward the first, and
-** within each index block, starting at the end and moving toward the
-** beginning. The first entry that equals P corresponds to the frame
-** holding the content for that page.
-**
-** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers.
-** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the
-** hash table for each page number in the mapping section, so the hash
-** table is never more than half full. The expected number of collisions
-** prior to finding a match is 1. Each entry of the hash table is an
-** 1-based index of an entry in the mapping section of the same
-** index block. Let K be the 1-based index of the largest entry in
-** the mapping section. (For index blocks other than the last, K will
-** always be exactly HASHTABLE_NPAGE (4096) and for the last index block
-** K will be (mxFrame%HASHTABLE_NPAGE).) Unused slots of the hash table
-** contain a value of 0.
-**
-** To look for page P in the hash table, first compute a hash iKey on
-** P as follows:
-**
-** iKey = (P * 383) % HASHTABLE_NSLOT
-**
-** Then start scanning entries of the hash table, starting with iKey
-** (wrapping around to the beginning when the end of the hash table is
-** reached) until an unused hash slot is found. Let the first unused slot
-** be at index iUnused. (iUnused might be less than iKey if there was
-** wrap-around.) Because the hash table is never more than half full,
-** the search is guaranteed to eventually hit an unused entry. Let
-** iMax be the value between iKey and iUnused, closest to iUnused,
-** where aHash[iMax]==P. If there is no iMax entry (if there exists
-** no hash slot such that aHash[i]==p) then page P is not in the
-** current index block. Otherwise the iMax-th mapping entry of the
-** current index block corresponds to the last entry that references
-** page P.
-**
-** A hash search begins with the last index block and moves toward the
-** first index block, looking for entries corresponding to page P. On
-** average, only two or three slots in each index block need to be
-** examined in order to either find the last entry for page P, or to
-** establish that no such entry exists in the block. Each index block
-** holds over 4000 entries. So two or three index blocks are sufficient
-** to cover a typical 10 megabyte WAL file, assuming 1K pages. 8 or 10
-** comparisons (on average) suffice to either locate a frame in the
-** WAL or to establish that the frame does not exist in the WAL. This
-** is much faster than scanning the entire 10MB WAL.
-**
-** Note that entries are added in order of increasing K. Hence, one
-** reader might be using some value K0 and a second reader that started
-** at a later time (after additional transactions were added to the WAL
-** and to the wal-index) might be using a different value K1, where K1>K0.
-** Both readers can use the same hash table and mapping section to get
-** the correct result. There may be entries in the hash table with
-** K>K0 but to the first reader, those entries will appear to be unused
-** slots in the hash table and so the first reader will get an answer as
-** if no values greater than K0 had ever been inserted into the hash table
-** in the first place - which is what reader one wants. Meanwhile, the
-** second reader using K1 will see additional values that were inserted
-** later, which is exactly what reader two wants.
-**
-** When a rollback occurs, the value of K is decreased. Hash table entries
-** that correspond to frames greater than the new K value are removed
-** from the hash table at this point.
-*/
-#ifndef SQLITE_OMIT_WAL
-
-
-/*
-** Trace output macros
-*/
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-SQLITE_PRIVATE int sqlite3WalTrace = 0;
-# define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X
-#else
-# define WALTRACE(X)
-#endif
-
-/*
-** The maximum (and only) versions of the wal and wal-index formats
-** that may be interpreted by this version of SQLite.
-**
-** If a client begins recovering a WAL file and finds that (a) the checksum
-** values in the wal-header are correct and (b) the version field is not
-** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN.
-**
-** Similarly, if a client successfully reads a wal-index header (i.e. the
-** checksum test is successful) and finds that the version field is not
-** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite
-** returns SQLITE_CANTOPEN.
-*/
-#define WAL_MAX_VERSION 3007000
-#define WALINDEX_MAX_VERSION 3007000
-
-/*
-** Indices of various locking bytes. WAL_NREADER is the number
-** of available reader locks and should be at least 3.
-*/
-#define WAL_WRITE_LOCK 0
-#define WAL_ALL_BUT_WRITE 1
-#define WAL_CKPT_LOCK 1
-#define WAL_RECOVER_LOCK 2
-#define WAL_READ_LOCK(I) (3+(I))
-#define WAL_NREADER (SQLITE_SHM_NLOCK-3)
-
-
-/* Object declarations */
-typedef struct WalIndexHdr WalIndexHdr;
-typedef struct WalIterator WalIterator;
-typedef struct WalCkptInfo WalCkptInfo;
-
-
-/*
-** The following object holds a copy of the wal-index header content.
-**
-** The actual header in the wal-index consists of two copies of this
-** object.
-**
-** The szPage value can be any power of 2 between 512 and 32768, inclusive.
-** Or it can be 1 to represent a 65536-byte page. The latter case was
-** added in 3.7.1 when support for 64K pages was added.
-*/
-struct WalIndexHdr {
- u32 iVersion; /* Wal-index version */
- u32 unused; /* Unused (padding) field */
- u32 iChange; /* Counter incremented each transaction */
- u8 isInit; /* 1 when initialized */
- u8 bigEndCksum; /* True if checksums in WAL are big-endian */
- u16 szPage; /* Database page size in bytes. 1==64K */
- u32 mxFrame; /* Index of last valid frame in the WAL */
- u32 nPage; /* Size of database in pages */
- u32 aFrameCksum[2]; /* Checksum of last frame in log */
- u32 aSalt[2]; /* Two salt values copied from WAL header */
- u32 aCksum[2]; /* Checksum over all prior fields */
-};
-
-/*
-** A copy of the following object occurs in the wal-index immediately
-** following the second copy of the WalIndexHdr. This object stores
-** information used by checkpoint.
-**
-** nBackfill is the number of frames in the WAL that have been written
-** back into the database. (We call the act of moving content from WAL to
-** database "backfilling".) The nBackfill number is never greater than
-** WalIndexHdr.mxFrame. nBackfill can only be increased by threads
-** holding the WAL_CKPT_LOCK lock (which includes a recovery thread).
-** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
-** mxFrame back to zero when the WAL is reset.
-**
-** There is one entry in aReadMark[] for each reader lock. If a reader
-** holds read-lock K, then the value in aReadMark[K] is no greater than
-** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff)
-** for any aReadMark[] means that entry is unused. aReadMark[0] is
-** a special case; its value is never used and it exists as a place-holder
-** to avoid having to offset aReadMark[] indexs by one. Readers holding
-** WAL_READ_LOCK(0) always ignore the entire WAL and read all content
-** directly from the database.
-**
-** The value of aReadMark[K] may only be changed by a thread that
-** is holding an exclusive lock on WAL_READ_LOCK(K). Thus, the value of
-** aReadMark[K] cannot changed while there is a reader is using that mark
-** since the reader will be holding a shared lock on WAL_READ_LOCK(K).
-**
-** The checkpointer may only transfer frames from WAL to database where
-** the frame numbers are less than or equal to every aReadMark[] that is
-** in use (that is, every aReadMark[j] for which there is a corresponding
-** WAL_READ_LOCK(j)). New readers (usually) pick the aReadMark[] with the
-** largest value and will increase an unused aReadMark[] to mxFrame if there
-** is not already an aReadMark[] equal to mxFrame. The exception to the
-** previous sentence is when nBackfill equals mxFrame (meaning that everything
-** in the WAL has been backfilled into the database) then new readers
-** will choose aReadMark[0] which has value 0 and hence such reader will
-** get all their all content directly from the database file and ignore
-** the WAL.
-**
-** Writers normally append new frames to the end of the WAL. However,
-** if nBackfill equals mxFrame (meaning that all WAL content has been
-** written back into the database) and if no readers are using the WAL
-** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then
-** the writer will first "reset" the WAL back to the beginning and start
-** writing new content beginning at frame 1.
-**
-** We assume that 32-bit loads are atomic and so no locks are needed in
-** order to read from any aReadMark[] entries.
-*/
-struct WalCkptInfo {
- u32 nBackfill; /* Number of WAL frames backfilled into DB */
- u32 aReadMark[WAL_NREADER]; /* Reader marks */
-};
-#define READMARK_NOT_USED 0xffffffff
-
-
-/* A block of WALINDEX_LOCK_RESERVED bytes beginning at
-** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems
-** only support mandatory file-locks, we do not read or write data
-** from the region of the file on which locks are applied.
-*/
-#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo))
-#define WALINDEX_LOCK_RESERVED 16
-#define WALINDEX_HDR_SIZE (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED)
-
-/* Size of header before each frame in wal */
-#define WAL_FRAME_HDRSIZE 24
-
-/* Size of write ahead log header, including checksum. */
-/* #define WAL_HDRSIZE 24 */
-#define WAL_HDRSIZE 32
-
-/* WAL magic value. Either this value, or the same value with the least
-** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit
-** big-endian format in the first 4 bytes of a WAL file.
-**
-** If the LSB is set, then the checksums for each frame within the WAL
-** file are calculated by treating all data as an array of 32-bit
-** big-endian words. Otherwise, they are calculated by interpreting
-** all data as 32-bit little-endian words.
-*/
-#define WAL_MAGIC 0x377f0682
-
-/*
-** Return the offset of frame iFrame in the write-ahead log file,
-** assuming a database page size of szPage bytes. The offset returned
-** is to the start of the write-ahead log frame-header.
-*/
-#define walFrameOffset(iFrame, szPage) ( \
- WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \
-)
-
-/*
-** An open write-ahead log file is represented by an instance of the
-** following object.
-*/
-struct Wal {
- sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */
- sqlite3_file *pDbFd; /* File handle for the database file */
- sqlite3_file *pWalFd; /* File handle for WAL file */
- u32 iCallback; /* Value to pass to log callback (or 0) */
- i64 mxWalSize; /* Truncate WAL to this size upon reset */
- int nWiData; /* Size of array apWiData */
- int szFirstBlock; /* Size of first block written to WAL file */
- volatile u32 **apWiData; /* Pointer to wal-index content in memory */
- u32 szPage; /* Database page size */
- i16 readLock; /* Which read lock is being held. -1 for none */
- u8 syncFlags; /* Flags to use to sync header writes */
- u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */
- u8 writeLock; /* True if in a write transaction */
- u8 ckptLock; /* True if holding a checkpoint lock */
- u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
- u8 truncateOnCommit; /* True to truncate WAL file on commit */
- u8 syncHeader; /* Fsync the WAL header if true */
- u8 padToSectorBoundary; /* Pad transactions out to the next sector */
- WalIndexHdr hdr; /* Wal-index header for current transaction */
- const char *zWalName; /* Name of WAL file */
- u32 nCkpt; /* Checkpoint sequence counter in the wal-header */
-#ifdef SQLITE_DEBUG
- u8 lockError; /* True if a locking error has occurred */
-#endif
-};
-
-/*
-** Candidate values for Wal.exclusiveMode.
-*/
-#define WAL_NORMAL_MODE 0
-#define WAL_EXCLUSIVE_MODE 1
-#define WAL_HEAPMEMORY_MODE 2
-
-/*
-** Possible values for WAL.readOnly
-*/
-#define WAL_RDWR 0 /* Normal read/write connection */
-#define WAL_RDONLY 1 /* The WAL file is readonly */
-#define WAL_SHM_RDONLY 2 /* The SHM file is readonly */
-
-/*
-** Each page of the wal-index mapping contains a hash-table made up of
-** an array of HASHTABLE_NSLOT elements of the following type.
-*/
-typedef u16 ht_slot;
-
-/*
-** This structure is used to implement an iterator that loops through
-** all frames in the WAL in database page order. Where two or more frames
-** correspond to the same database page, the iterator visits only the
-** frame most recently written to the WAL (in other words, the frame with
-** the largest index).
-**
-** The internals of this structure are only accessed by:
-**
-** walIteratorInit() - Create a new iterator,
-** walIteratorNext() - Step an iterator,
-** walIteratorFree() - Free an iterator.
-**
-** This functionality is used by the checkpoint code (see walCheckpoint()).
-*/
-struct WalIterator {
- int iPrior; /* Last result returned from the iterator */
- int nSegment; /* Number of entries in aSegment[] */
- struct WalSegment {
- int iNext; /* Next slot in aIndex[] not yet returned */
- ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */
- u32 *aPgno; /* Array of page numbers. */
- int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */
- int iZero; /* Frame number associated with aPgno[0] */
- } aSegment[1]; /* One for every 32KB page in the wal-index */
-};
-
-/*
-** Define the parameters of the hash tables in the wal-index file. There
-** is a hash-table following every HASHTABLE_NPAGE page numbers in the
-** wal-index.
-**
-** Changing any of these constants will alter the wal-index format and
-** create incompatibilities.
-*/
-#define HASHTABLE_NPAGE 4096 /* Must be power of 2 */
-#define HASHTABLE_HASH_1 383 /* Should be prime */
-#define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */
-
-/*
-** The block of page numbers associated with the first hash-table in a
-** wal-index is smaller than usual. This is so that there is a complete
-** hash-table on each aligned 32KB page of the wal-index.
-*/
-#define HASHTABLE_NPAGE_ONE (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32)))
-
-/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */
-#define WALINDEX_PGSZ ( \
- sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \
-)
-
-/*
-** Obtain a pointer to the iPage'th page of the wal-index. The wal-index
-** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
-** numbered from zero.
-**
-** If this call is successful, *ppPage is set to point to the wal-index
-** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
-** then an SQLite error code is returned and *ppPage is set to 0.
-*/
-static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
- int rc = SQLITE_OK;
-
- /* Enlarge the pWal->apWiData[] array if required */
- if( pWal->nWiData<=iPage ){
- int nByte = sizeof(u32*)*(iPage+1);
- volatile u32 **apNew;
- apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
- if( !apNew ){
- *ppPage = 0;
- return SQLITE_NOMEM;
- }
- memset((void*)&apNew[pWal->nWiData], 0,
- sizeof(u32*)*(iPage+1-pWal->nWiData));
- pWal->apWiData = apNew;
- pWal->nWiData = iPage+1;
- }
-
- /* Request a pointer to the required page from the VFS */
- if( pWal->apWiData[iPage]==0 ){
- if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
- pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
- if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
- pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
- );
- if( rc==SQLITE_READONLY ){
- pWal->readOnly |= WAL_SHM_RDONLY;
- rc = SQLITE_OK;
- }
- }
- }
-
- *ppPage = pWal->apWiData[iPage];
- assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
- return rc;
-}
-
-/*
-** Return a pointer to the WalCkptInfo structure in the wal-index.
-*/
-static volatile WalCkptInfo *walCkptInfo(Wal *pWal){
- assert( pWal->nWiData>0 && pWal->apWiData[0] );
- return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]);
-}
-
-/*
-** Return a pointer to the WalIndexHdr structure in the wal-index.
-*/
-static volatile WalIndexHdr *walIndexHdr(Wal *pWal){
- assert( pWal->nWiData>0 && pWal->apWiData[0] );
- return (volatile WalIndexHdr*)pWal->apWiData[0];
-}
-
-/*
-** The argument to this macro must be of type u32. On a little-endian
-** architecture, it returns the u32 value that results from interpreting
-** the 4 bytes as a big-endian value. On a big-endian architecture, it
-** returns the value that would be produced by intepreting the 4 bytes
-** of the input value as a little-endian integer.
-*/
-#define BYTESWAP32(x) ( \
- (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) \
- + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24) \
-)
-
-/*
-** Generate or extend an 8 byte checksum based on the data in
-** array aByte[] and the initial values of aIn[0] and aIn[1] (or
-** initial values of 0 and 0 if aIn==NULL).
-**
-** The checksum is written back into aOut[] before returning.
-**
-** nByte must be a positive multiple of 8.
-*/
-static void walChecksumBytes(
- int nativeCksum, /* True for native byte-order, false for non-native */
- u8 *a, /* Content to be checksummed */
- int nByte, /* Bytes of content in a[]. Must be a multiple of 8. */
- const u32 *aIn, /* Initial checksum value input */
- u32 *aOut /* OUT: Final checksum value output */
-){
- u32 s1, s2;
- u32 *aData = (u32 *)a;
- u32 *aEnd = (u32 *)&a[nByte];
-
- if( aIn ){
- s1 = aIn[0];
- s2 = aIn[1];
- }else{
- s1 = s2 = 0;
- }
-
- assert( nByte>=8 );
- assert( (nByte&0x00000007)==0 );
-
- if( nativeCksum ){
- do {
- s1 += *aData++ + s2;
- s2 += *aData++ + s1;
- }while( aData<aEnd );
- }else{
- do {
- s1 += BYTESWAP32(aData[0]) + s2;
- s2 += BYTESWAP32(aData[1]) + s1;
- aData += 2;
- }while( aData<aEnd );
- }
-
- aOut[0] = s1;
- aOut[1] = s2;
-}
-
-static void walShmBarrier(Wal *pWal){
- if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
- sqlite3OsShmBarrier(pWal->pDbFd);
- }
-}
-
-/*
-** Write the header information in pWal->hdr into the wal-index.
-**
-** The checksum on pWal->hdr is updated before it is written.
-*/
-static void walIndexWriteHdr(Wal *pWal){
- volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
- const int nCksum = offsetof(WalIndexHdr, aCksum);
-
- assert( pWal->writeLock );
- pWal->hdr.isInit = 1;
- pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
- walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
- memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr));
- walShmBarrier(pWal);
- memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
-}
-
-/*
-** This function encodes a single frame header and writes it to a buffer
-** supplied by the caller. A frame-header is made up of a series of
-** 4-byte big-endian integers, as follows:
-**
-** 0: Page number.
-** 4: For commit records, the size of the database image in pages
-** after the commit. For all other records, zero.
-** 8: Salt-1 (copied from the wal-header)
-** 12: Salt-2 (copied from the wal-header)
-** 16: Checksum-1.
-** 20: Checksum-2.
-*/
-static void walEncodeFrame(
- Wal *pWal, /* The write-ahead log */
- u32 iPage, /* Database page number for frame */
- u32 nTruncate, /* New db size (or 0 for non-commit frames) */
- u8 *aData, /* Pointer to page data */
- u8 *aFrame /* OUT: Write encoded frame here */
-){
- int nativeCksum; /* True for native byte-order checksums */
- u32 *aCksum = pWal->hdr.aFrameCksum;
- assert( WAL_FRAME_HDRSIZE==24 );
- sqlite3Put4byte(&aFrame[0], iPage);
- sqlite3Put4byte(&aFrame[4], nTruncate);
- memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
-
- nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
- walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
- walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
-
- sqlite3Put4byte(&aFrame[16], aCksum[0]);
- sqlite3Put4byte(&aFrame[20], aCksum[1]);
-}
-
-/*
-** Check to see if the frame with header in aFrame[] and content
-** in aData[] is valid. If it is a valid frame, fill *piPage and
-** *pnTruncate and return true. Return if the frame is not valid.
-*/
-static int walDecodeFrame(
- Wal *pWal, /* The write-ahead log */
- u32 *piPage, /* OUT: Database page number for frame */
- u32 *pnTruncate, /* OUT: New db size (or 0 if not commit) */
- u8 *aData, /* Pointer to page data (for checksum) */
- u8 *aFrame /* Frame data */
-){
- int nativeCksum; /* True for native byte-order checksums */
- u32 *aCksum = pWal->hdr.aFrameCksum;
- u32 pgno; /* Page number of the frame */
- assert( WAL_FRAME_HDRSIZE==24 );
-
- /* A frame is only valid if the salt values in the frame-header
- ** match the salt values in the wal-header.
- */
- if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){
- return 0;
- }
-
- /* A frame is only valid if the page number is creater than zero.
- */
- pgno = sqlite3Get4byte(&aFrame[0]);
- if( pgno==0 ){
- return 0;
- }
-
- /* A frame is only valid if a checksum of the WAL header,
- ** all prior frams, the first 16 bytes of this frame-header,
- ** and the frame-data matches the checksum in the last 8
- ** bytes of this frame-header.
- */
- nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
- walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
- walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
- if( aCksum[0]!=sqlite3Get4byte(&aFrame[16])
- || aCksum[1]!=sqlite3Get4byte(&aFrame[20])
- ){
- /* Checksum failed. */
- return 0;
- }
-
- /* If we reach this point, the frame is valid. Return the page number
- ** and the new database size.
- */
- *piPage = pgno;
- *pnTruncate = sqlite3Get4byte(&aFrame[4]);
- return 1;
-}
-
-
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-/*
-** Names of locks. This routine is used to provide debugging output and is not
-** a part of an ordinary build.
-*/
-static const char *walLockName(int lockIdx){
- if( lockIdx==WAL_WRITE_LOCK ){
- return "WRITE-LOCK";
- }else if( lockIdx==WAL_CKPT_LOCK ){
- return "CKPT-LOCK";
- }else if( lockIdx==WAL_RECOVER_LOCK ){
- return "RECOVER-LOCK";
- }else{
- static char zName[15];
- sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]",
- lockIdx-WAL_READ_LOCK(0));
- return zName;
- }
-}
-#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
-
-
-/*
-** Set or release locks on the WAL. Locks are either shared or exclusive.
-** A lock cannot be moved directly between shared and exclusive - it must go
-** through the unlocked state first.
-**
-** In locking_mode=EXCLUSIVE, all of these routines become no-ops.
-*/
-static int walLockShared(Wal *pWal, int lockIdx){
- int rc;
- if( pWal->exclusiveMode ) return SQLITE_OK;
- rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
- SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
- WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
- walLockName(lockIdx), rc ? "failed" : "ok"));
- VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
- return rc;
-}
-static void walUnlockShared(Wal *pWal, int lockIdx){
- if( pWal->exclusiveMode ) return;
- (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
- SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
- WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
-}
-static int walLockExclusive(Wal *pWal, int lockIdx, int n){
- int rc;
- if( pWal->exclusiveMode ) return SQLITE_OK;
- rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
- SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
- WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
- walLockName(lockIdx), n, rc ? "failed" : "ok"));
- VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
- return rc;
-}
-static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
- if( pWal->exclusiveMode ) return;
- (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
- SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE);
- WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal,
- walLockName(lockIdx), n));
-}
-
-/*
-** Compute a hash on a page number. The resulting hash value must land
-** between 0 and (HASHTABLE_NSLOT-1). The walHashNext() function advances
-** the hash to the next value in the event of a collision.
-*/
-static int walHash(u32 iPage){
- assert( iPage>0 );
- assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 );
- return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1);
-}
-static int walNextHash(int iPriorHash){
- return (iPriorHash+1)&(HASHTABLE_NSLOT-1);
-}
-
-/*
-** Return pointers to the hash table and page number array stored on
-** page iHash of the wal-index. The wal-index is broken into 32KB pages
-** numbered starting from 0.
-**
-** Set output variable *paHash to point to the start of the hash table
-** in the wal-index file. Set *piZero to one less than the frame
-** number of the first frame indexed by this hash table. If a
-** slot in the hash table is set to N, it refers to frame number
-** (*piZero+N) in the log.
-**
-** Finally, set *paPgno so that *paPgno[1] is the page number of the
-** first frame indexed by the hash table, frame (*piZero+1).
-*/
-static int walHashGet(
- Wal *pWal, /* WAL handle */
- int iHash, /* Find the iHash'th table */
- volatile ht_slot **paHash, /* OUT: Pointer to hash index */
- volatile u32 **paPgno, /* OUT: Pointer to page number array */
- u32 *piZero /* OUT: Frame associated with *paPgno[0] */
-){
- int rc; /* Return code */
- volatile u32 *aPgno;
-
- rc = walIndexPage(pWal, iHash, &aPgno);
- assert( rc==SQLITE_OK || iHash>0 );
-
- if( rc==SQLITE_OK ){
- u32 iZero;
- volatile ht_slot *aHash;
-
- aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE];
- if( iHash==0 ){
- aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
- iZero = 0;
- }else{
- iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
- }
-
- *paPgno = &aPgno[-1];
- *paHash = aHash;
- *piZero = iZero;
- }
- return rc;
-}
-
-/*
-** Return the number of the wal-index page that contains the hash-table
-** and page-number array that contain entries corresponding to WAL frame
-** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages
-** are numbered starting from 0.
-*/
-static int walFramePage(u32 iFrame){
- int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE;
- assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE)
- && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE)
- && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE))
- && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)
- && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE))
- );
- return iHash;
-}
-
-/*
-** Return the page number associated with frame iFrame in this WAL.
-*/
-static u32 walFramePgno(Wal *pWal, u32 iFrame){
- int iHash = walFramePage(iFrame);
- if( iHash==0 ){
- return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1];
- }
- return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE];
-}
-
-/*
-** Remove entries from the hash table that point to WAL slots greater
-** than pWal->hdr.mxFrame.
-**
-** This function is called whenever pWal->hdr.mxFrame is decreased due
-** to a rollback or savepoint.
-**
-** At most only the hash table containing pWal->hdr.mxFrame needs to be
-** updated. Any later hash tables will be automatically cleared when
-** pWal->hdr.mxFrame advances to the point where those hash tables are
-** actually needed.
-*/
-static void walCleanupHash(Wal *pWal){
- volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */
- volatile u32 *aPgno = 0; /* Page number array for hash table */
- u32 iZero = 0; /* frame == (aHash[x]+iZero) */
- int iLimit = 0; /* Zero values greater than this */
- int nByte; /* Number of bytes to zero in aPgno[] */
- int i; /* Used to iterate through aHash[] */
-
- assert( pWal->writeLock );
- testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
- testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE );
- testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 );
-
- if( pWal->hdr.mxFrame==0 ) return;
-
- /* Obtain pointers to the hash-table and page-number array containing
- ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
- ** that the page said hash-table and array reside on is already mapped.
- */
- assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
- assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
- walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
-
- /* Zero all hash-table entries that correspond to frame numbers greater
- ** than pWal->hdr.mxFrame.
- */
- iLimit = pWal->hdr.mxFrame - iZero;
- assert( iLimit>0 );
- for(i=0; i<HASHTABLE_NSLOT; i++){
- if( aHash[i]>iLimit ){
- aHash[i] = 0;
- }
- }
-
- /* Zero the entries in the aPgno array that correspond to frames with
- ** frame numbers greater than pWal->hdr.mxFrame.
- */
- nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
- memset((void *)&aPgno[iLimit+1], 0, nByte);
-
-#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
- /* Verify that the every entry in the mapping region is still reachable
- ** via the hash table even after the cleanup.
- */
- if( iLimit ){
- int i; /* Loop counter */
- int iKey; /* Hash key */
- for(i=1; i<=iLimit; i++){
- for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
- if( aHash[iKey]==i ) break;
- }
- assert( aHash[iKey]==i );
- }
- }
-#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
-}
-
-
-/*
-** Set an entry in the wal-index that will map database page number
-** pPage into WAL frame iFrame.
-*/
-static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
- int rc; /* Return code */
- u32 iZero = 0; /* One less than frame number of aPgno[1] */
- volatile u32 *aPgno = 0; /* Page number array */
- volatile ht_slot *aHash = 0; /* Hash table */
-
- rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero);
-
- /* Assuming the wal-index file was successfully mapped, populate the
- ** page number array and hash table entry.
- */
- if( rc==SQLITE_OK ){
- int iKey; /* Hash table key */
- int idx; /* Value to write to hash-table slot */
- int nCollide; /* Number of hash collisions */
-
- idx = iFrame - iZero;
- assert( idx <= HASHTABLE_NSLOT/2 + 1 );
-
- /* If this is the first entry to be added to this hash-table, zero the
- ** entire hash table and aPgno[] array before proceding.
- */
- if( idx==1 ){
- int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
- memset((void*)&aPgno[1], 0, nByte);
- }
-
- /* If the entry in aPgno[] is already set, then the previous writer
- ** must have exited unexpectedly in the middle of a transaction (after
- ** writing one or more dirty pages to the WAL to free up memory).
- ** Remove the remnants of that writers uncommitted transaction from
- ** the hash-table before writing any new entries.
- */
- if( aPgno[idx] ){
- walCleanupHash(pWal);
- assert( !aPgno[idx] );
- }
-
- /* Write the aPgno[] array entry and the hash-table slot. */
- nCollide = idx;
- for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
- if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
- }
- aPgno[idx] = iPage;
- aHash[iKey] = (ht_slot)idx;
-
-#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
- /* Verify that the number of entries in the hash table exactly equals
- ** the number of entries in the mapping region.
- */
- {
- int i; /* Loop counter */
- int nEntry = 0; /* Number of entries in the hash table */
- for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
- assert( nEntry==idx );
- }
-
- /* Verify that the every entry in the mapping region is reachable
- ** via the hash table. This turns out to be a really, really expensive
- ** thing to check, so only do this occasionally - not on every
- ** iteration.
- */
- if( (idx&0x3ff)==0 ){
- int i; /* Loop counter */
- for(i=1; i<=idx; i++){
- for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
- if( aHash[iKey]==i ) break;
- }
- assert( aHash[iKey]==i );
- }
- }
-#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
- }
-
-
- return rc;
-}
-
-
-/*
-** Recover the wal-index by reading the write-ahead log file.
-**
-** This routine first tries to establish an exclusive lock on the
-** wal-index to prevent other threads/processes from doing anything
-** with the WAL or wal-index while recovery is running. The
-** WAL_RECOVER_LOCK is also held so that other threads will know
-** that this thread is running recovery. If unable to establish
-** the necessary locks, this routine returns SQLITE_BUSY.
-*/
-static int walIndexRecover(Wal *pWal){
- int rc; /* Return Code */
- i64 nSize; /* Size of log file */
- u32 aFrameCksum[2] = {0, 0};
- int iLock; /* Lock offset to lock for checkpoint */
- int nLock; /* Number of locks to hold */
-
- /* Obtain an exclusive lock on all byte in the locking range not already
- ** locked by the caller. The caller is guaranteed to have locked the
- ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
- ** If successful, the same bytes that are locked here are unlocked before
- ** this function returns.
- */
- assert( pWal->ckptLock==1 || pWal->ckptLock==0 );
- assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 );
- assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
- assert( pWal->writeLock );
- iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
- nLock = SQLITE_SHM_NLOCK - iLock;
- rc = walLockExclusive(pWal, iLock, nLock);
- if( rc ){
- return rc;
- }
- WALTRACE(("WAL%p: recovery begin...\n", pWal));
-
- memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
-
- rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
- if( rc!=SQLITE_OK ){
- goto recovery_error;
- }
-
- if( nSize>WAL_HDRSIZE ){
- u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */
- u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */
- int szFrame; /* Number of bytes in buffer aFrame[] */
- u8 *aData; /* Pointer to data part of aFrame buffer */
- int iFrame; /* Index of last frame read */
- i64 iOffset; /* Next offset to read from log file */
- int szPage; /* Page size according to the log */
- u32 magic; /* Magic value read from WAL header */
- u32 version; /* Magic value read from WAL header */
- int isValid; /* True if this frame is valid */
-
- /* Read in the WAL header. */
- rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
- if( rc!=SQLITE_OK ){
- goto recovery_error;
- }
-
- /* If the database page size is not a power of two, or is greater than
- ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid
- ** data. Similarly, if the 'magic' value is invalid, ignore the whole
- ** WAL file.
- */
- magic = sqlite3Get4byte(&aBuf[0]);
- szPage = sqlite3Get4byte(&aBuf[8]);
- if( (magic&0xFFFFFFFE)!=WAL_MAGIC
- || szPage&(szPage-1)
- || szPage>SQLITE_MAX_PAGE_SIZE
- || szPage<512
- ){
- goto finished;
- }
- pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
- pWal->szPage = szPage;
- pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
- memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
-
- /* Verify that the WAL header checksum is correct */
- walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN,
- aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
- );
- if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24])
- || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28])
- ){
- goto finished;
- }
-
- /* Verify that the version number on the WAL format is one that
- ** are able to understand */
- version = sqlite3Get4byte(&aBuf[4]);
- if( version!=WAL_MAX_VERSION ){
- rc = SQLITE_CANTOPEN_BKPT;
- goto finished;
- }
-
- /* Malloc a buffer to read frames into. */
- szFrame = szPage + WAL_FRAME_HDRSIZE;
- aFrame = (u8 *)sqlite3_malloc(szFrame);
- if( !aFrame ){
- rc = SQLITE_NOMEM;
- goto recovery_error;
- }
- aData = &aFrame[WAL_FRAME_HDRSIZE];
-
- /* Read all frames from the log file. */
- iFrame = 0;
- for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){
- u32 pgno; /* Database page number for frame */
- u32 nTruncate; /* dbsize field from frame header */
-
- /* Read and decode the next log frame. */
- iFrame++;
- rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
- if( rc!=SQLITE_OK ) break;
- isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame);
- if( !isValid ) break;
- rc = walIndexAppend(pWal, iFrame, pgno);
- if( rc!=SQLITE_OK ) break;
-
- /* If nTruncate is non-zero, this is a commit record. */
- if( nTruncate ){
- pWal->hdr.mxFrame = iFrame;
- pWal->hdr.nPage = nTruncate;
- pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
- testcase( szPage<=32768 );
- testcase( szPage>=65536 );
- aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
- aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
- }
- }
-
- sqlite3_free(aFrame);
- }
-
-finished:
- if( rc==SQLITE_OK ){
- volatile WalCkptInfo *pInfo;
- int i;
- pWal->hdr.aFrameCksum[0] = aFrameCksum[0];
- pWal->hdr.aFrameCksum[1] = aFrameCksum[1];
- walIndexWriteHdr(pWal);
-
- /* Reset the checkpoint-header. This is safe because this thread is
- ** currently holding locks that exclude all other readers, writers and
- ** checkpointers.
- */
- pInfo = walCkptInfo(pWal);
- pInfo->nBackfill = 0;
- pInfo->aReadMark[0] = 0;
- for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
- if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;
-
- /* If more than one frame was recovered from the log file, report an
- ** event via sqlite3_log(). This is to help with identifying performance
- ** problems caused by applications routinely shutting down without
- ** checkpointing the log file.
- */
- if( pWal->hdr.nPage ){
- sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s",
- pWal->hdr.nPage, pWal->zWalName
- );
- }
- }
-
-recovery_error:
- WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
- walUnlockExclusive(pWal, iLock, nLock);
- return rc;
-}
-
-/*
-** Close an open wal-index.
-*/
-static void walIndexClose(Wal *pWal, int isDelete){
- if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
- int i;
- for(i=0; i<pWal->nWiData; i++){
- sqlite3_free((void *)pWal->apWiData[i]);
- pWal->apWiData[i] = 0;
- }
- }else{
- sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
- }
-}
-
-/*
-** Open a connection to the WAL file zWalName. The database file must
-** already be opened on connection pDbFd. The buffer that zWalName points
-** to must remain valid for the lifetime of the returned Wal* handle.
-**
-** A SHARED lock should be held on the database file when this function
-** is called. The purpose of this SHARED lock is to prevent any other
-** client from unlinking the WAL or wal-index file. If another process
-** were to do this just after this client opened one of these files, the
-** system would be badly broken.
-**
-** If the log file is successfully opened, SQLITE_OK is returned and
-** *ppWal is set to point to a new WAL handle. If an error occurs,
-** an SQLite error code is returned and *ppWal is left unmodified.
-*/
-SQLITE_PRIVATE int sqlite3WalOpen(
- sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */
- sqlite3_file *pDbFd, /* The open database file */
- const char *zWalName, /* Name of the WAL file */
- int bNoShm, /* True to run in heap-memory mode */
- i64 mxWalSize, /* Truncate WAL to this size on reset */
- Wal **ppWal /* OUT: Allocated Wal handle */
-){
- int rc; /* Return Code */
- Wal *pRet; /* Object to allocate and return */
- int flags; /* Flags passed to OsOpen() */
-
- assert( zWalName && zWalName[0] );
- assert( pDbFd );
-
- /* In the amalgamation, the os_unix.c and os_win.c source files come before
- ** this source file. Verify that the #defines of the locking byte offsets
- ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
- */
-#ifdef WIN_SHM_BASE
- assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
-#endif
-#ifdef UNIX_SHM_BASE
- assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET );
-#endif
-
-
- /* Allocate an instance of struct Wal to return. */
- *ppWal = 0;
- pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
- if( !pRet ){
- return SQLITE_NOMEM;
- }
-
- pRet->pVfs = pVfs;
- pRet->pWalFd = (sqlite3_file *)&pRet[1];
- pRet->pDbFd = pDbFd;
- pRet->readLock = -1;
- pRet->mxWalSize = mxWalSize;
- pRet->zWalName = zWalName;
- pRet->syncHeader = 1;
- pRet->padToSectorBoundary = 1;
- pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
-
- /* Open file handle on the write-ahead log file. */
- flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
- rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
- if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
- pRet->readOnly = WAL_RDONLY;
- }
-
- if( rc!=SQLITE_OK ){
- walIndexClose(pRet, 0);
- sqlite3OsClose(pRet->pWalFd);
- sqlite3_free(pRet);
- }else{
- int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd);
- if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; }
- if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){
- pRet->padToSectorBoundary = 0;
- }
- *ppWal = pRet;
- WALTRACE(("WAL%d: opened\n", pRet));
- }
- return rc;
-}
-
-/*
-** Change the size to which the WAL file is trucated on each reset.
-*/
-SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){
- if( pWal ) pWal->mxWalSize = iLimit;
-}
-
-/*
-** Find the smallest page number out of all pages held in the WAL that
-** has not been returned by any prior invocation of this method on the
-** same WalIterator object. Write into *piFrame the frame index where
-** that page was last written into the WAL. Write into *piPage the page
-** number.
-**
-** Return 0 on success. If there are no pages in the WAL with a page
-** number larger than *piPage, then return 1.
-*/
-static int walIteratorNext(
- WalIterator *p, /* Iterator */
- u32 *piPage, /* OUT: The page number of the next page */
- u32 *piFrame /* OUT: Wal frame index of next page */
-){
- u32 iMin; /* Result pgno must be greater than iMin */
- u32 iRet = 0xFFFFFFFF; /* 0xffffffff is never a valid page number */
- int i; /* For looping through segments */
-
- iMin = p->iPrior;
- assert( iMin<0xffffffff );
- for(i=p->nSegment-1; i>=0; i--){
- struct WalSegment *pSegment = &p->aSegment[i];
- while( pSegment->iNext<pSegment->nEntry ){
- u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]];
- if( iPg>iMin ){
- if( iPg<iRet ){
- iRet = iPg;
- *piFrame = pSegment->iZero + pSegment->aIndex[pSegment->iNext];
- }
- break;
- }
- pSegment->iNext++;
- }
- }
-
- *piPage = p->iPrior = iRet;
- return (iRet==0xFFFFFFFF);
-}
-
-/*
-** This function merges two sorted lists into a single sorted list.
-**
-** aLeft[] and aRight[] are arrays of indices. The sort key is
-** aContent[aLeft[]] and aContent[aRight[]]. Upon entry, the following
-** is guaranteed for all J<K:
-**
-** aContent[aLeft[J]] < aContent[aLeft[K]]
-** aContent[aRight[J]] < aContent[aRight[K]]
-**
-** This routine overwrites aRight[] with a new (probably longer) sequence
-** of indices such that the aRight[] contains every index that appears in
-** either aLeft[] or the old aRight[] and such that the second condition
-** above is still met.
-**
-** The aContent[aLeft[X]] values will be unique for all X. And the
-** aContent[aRight[X]] values will be unique too. But there might be
-** one or more combinations of X and Y such that
-**
-** aLeft[X]!=aRight[Y] && aContent[aLeft[X]] == aContent[aRight[Y]]
-**
-** When that happens, omit the aLeft[X] and use the aRight[Y] index.
-*/
-static void walMerge(
- const u32 *aContent, /* Pages in wal - keys for the sort */
- ht_slot *aLeft, /* IN: Left hand input list */
- int nLeft, /* IN: Elements in array *paLeft */
- ht_slot **paRight, /* IN/OUT: Right hand input list */
- int *pnRight, /* IN/OUT: Elements in *paRight */
- ht_slot *aTmp /* Temporary buffer */
-){
- int iLeft = 0; /* Current index in aLeft */
- int iRight = 0; /* Current index in aRight */
- int iOut = 0; /* Current index in output buffer */
- int nRight = *pnRight;
- ht_slot *aRight = *paRight;
-
- assert( nLeft>0 && nRight>0 );
- while( iRight<nRight || iLeft<nLeft ){
- ht_slot logpage;
- Pgno dbpage;
-
- if( (iLeft<nLeft)
- && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]])
- ){
- logpage = aLeft[iLeft++];
- }else{
- logpage = aRight[iRight++];
- }
- dbpage = aContent[logpage];
-
- aTmp[iOut++] = logpage;
- if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++;
-
- assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage );
- assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage );
- }
-
- *paRight = aLeft;
- *pnRight = iOut;
- memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut);
-}
-
-/*
-** Sort the elements in list aList using aContent[] as the sort key.
-** Remove elements with duplicate keys, preferring to keep the
-** larger aList[] values.
-**
-** The aList[] entries are indices into aContent[]. The values in
-** aList[] are to be sorted so that for all J<K:
-**
-** aContent[aList[J]] < aContent[aList[K]]
-**
-** For any X and Y such that
-**
-** aContent[aList[X]] == aContent[aList[Y]]
-**
-** Keep the larger of the two values aList[X] and aList[Y] and discard
-** the smaller.
-*/
-static void walMergesort(
- const u32 *aContent, /* Pages in wal */
- ht_slot *aBuffer, /* Buffer of at least *pnList items to use */
- ht_slot *aList, /* IN/OUT: List to sort */
- int *pnList /* IN/OUT: Number of elements in aList[] */
-){
- struct Sublist {
- int nList; /* Number of elements in aList */
- ht_slot *aList; /* Pointer to sub-list content */
- };
-
- const int nList = *pnList; /* Size of input list */
- int nMerge = 0; /* Number of elements in list aMerge */
- ht_slot *aMerge = 0; /* List to be merged */
- int iList; /* Index into input list */
- int iSub = 0; /* Index into aSub array */
- struct Sublist aSub[13]; /* Array of sub-lists */
-
- memset(aSub, 0, sizeof(aSub));
- assert( nList<=HASHTABLE_NPAGE && nList>0 );
- assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) );
-
- for(iList=0; iList<nList; iList++){
- nMerge = 1;
- aMerge = &aList[iList];
- for(iSub=0; iList & (1<<iSub); iSub++){
- struct Sublist *p = &aSub[iSub];
- assert( p->aList && p->nList<=(1<<iSub) );
- assert( p->aList==&aList[iList&~((2<<iSub)-1)] );
- walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
- }
- aSub[iSub].aList = aMerge;
- aSub[iSub].nList = nMerge;
- }
-
- for(iSub++; iSub<ArraySize(aSub); iSub++){
- if( nList & (1<<iSub) ){
- struct Sublist *p = &aSub[iSub];
- assert( p->nList<=(1<<iSub) );
- assert( p->aList==&aList[nList&~((2<<iSub)-1)] );
- walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
- }
- }
- assert( aMerge==aList );
- *pnList = nMerge;
-
-#ifdef SQLITE_DEBUG
- {
- int i;
- for(i=1; i<*pnList; i++){
- assert( aContent[aList[i]] > aContent[aList[i-1]] );
- }
- }
-#endif
-}
-
-/*
-** Free an iterator allocated by walIteratorInit().
-*/
-static void walIteratorFree(WalIterator *p){
- sqlite3ScratchFree(p);
-}
-
-/*
-** Construct a WalInterator object that can be used to loop over all
-** pages in the WAL in ascending order. The caller must hold the checkpoint
-** lock.
-**
-** On success, make *pp point to the newly allocated WalInterator object
-** return SQLITE_OK. Otherwise, return an error code. If this routine
-** returns an error, the value of *pp is undefined.
-**
-** The calling routine should invoke walIteratorFree() to destroy the
-** WalIterator object when it has finished with it.
-*/
-static int walIteratorInit(Wal *pWal, WalIterator **pp){
- WalIterator *p; /* Return value */
- int nSegment; /* Number of segments to merge */
- u32 iLast; /* Last frame in log */
- int nByte; /* Number of bytes to allocate */
- int i; /* Iterator variable */
- ht_slot *aTmp; /* Temp space used by merge-sort */
- int rc = SQLITE_OK; /* Return Code */
-
- /* This routine only runs while holding the checkpoint lock. And
- ** it only runs if there is actually content in the log (mxFrame>0).
- */
- assert( pWal->ckptLock && pWal->hdr.mxFrame>0 );
- iLast = pWal->hdr.mxFrame;
-
- /* Allocate space for the WalIterator object. */
- nSegment = walFramePage(iLast) + 1;
- nByte = sizeof(WalIterator)
- + (nSegment-1)*sizeof(struct WalSegment)
- + iLast*sizeof(ht_slot);
- p = (WalIterator *)sqlite3ScratchMalloc(nByte);
- if( !p ){
- return SQLITE_NOMEM;
- }
- memset(p, 0, nByte);
- p->nSegment = nSegment;
-
- /* Allocate temporary space used by the merge-sort routine. This block
- ** of memory will be freed before this function returns.
- */
- aTmp = (ht_slot *)sqlite3ScratchMalloc(
- sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
- );
- if( !aTmp ){
- rc = SQLITE_NOMEM;
- }
-
- for(i=0; rc==SQLITE_OK && i<nSegment; i++){
- volatile ht_slot *aHash;
- u32 iZero;
- volatile u32 *aPgno;
-
- rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
- if( rc==SQLITE_OK ){
- int j; /* Counter variable */
- int nEntry; /* Number of entries in this segment */
- ht_slot *aIndex; /* Sorted index for this segment */
-
- aPgno++;
- if( (i+1)==nSegment ){
- nEntry = (int)(iLast - iZero);
- }else{
- nEntry = (int)((u32*)aHash - (u32*)aPgno);
- }
- aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
- iZero++;
-
- for(j=0; j<nEntry; j++){
- aIndex[j] = (ht_slot)j;
- }
- walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
- p->aSegment[i].iZero = iZero;
- p->aSegment[i].nEntry = nEntry;
- p->aSegment[i].aIndex = aIndex;
- p->aSegment[i].aPgno = (u32 *)aPgno;
- }
- }
- sqlite3ScratchFree(aTmp);
-
- if( rc!=SQLITE_OK ){
- walIteratorFree(p);
- }
- *pp = p;
- return rc;
-}
-
-/*
-** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
-** n. If the attempt fails and parameter xBusy is not NULL, then it is a
-** busy-handler function. Invoke it and retry the lock until either the
-** lock is successfully obtained or the busy-handler returns 0.
-*/
-static int walBusyLock(
- Wal *pWal, /* WAL connection */
- int (*xBusy)(void*), /* Function to call when busy */
- void *pBusyArg, /* Context argument for xBusyHandler */
- int lockIdx, /* Offset of first byte to lock */
- int n /* Number of bytes to lock */
-){
- int rc;
- do {
- rc = walLockExclusive(pWal, lockIdx, n);
- }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
- return rc;
-}
-
-/*
-** The cache of the wal-index header must be valid to call this function.
-** Return the page-size in bytes used by the database.
-*/
-static int walPagesize(Wal *pWal){
- return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
-}
-
-/*
-** Copy as much content as we can from the WAL back into the database file
-** in response to an sqlite3_wal_checkpoint() request or the equivalent.
-**
-** The amount of information copies from WAL to database might be limited
-** by active readers. This routine will never overwrite a database page
-** that a concurrent reader might be using.
-**
-** All I/O barrier operations (a.k.a fsyncs) occur in this routine when
-** SQLite is in WAL-mode in synchronous=NORMAL. That means that if
-** checkpoints are always run by a background thread or background
-** process, foreground threads will never block on a lengthy fsync call.
-**
-** Fsync is called on the WAL before writing content out of the WAL and
-** into the database. This ensures that if the new content is persistent
-** in the WAL and can be recovered following a power-loss or hard reset.
-**
-** Fsync is also called on the database file if (and only if) the entire
-** WAL content is copied into the database file. This second fsync makes
-** it safe to delete the WAL since the new content will persist in the
-** database file.
-**
-** This routine uses and updates the nBackfill field of the wal-index header.
-** This is the only routine tha will increase the value of nBackfill.
-** (A WAL reset or recovery will revert nBackfill to zero, but not increase
-** its value.)
-**
-** The caller must be holding sufficient locks to ensure that no other
-** checkpoint is running (in any other thread or process) at the same
-** time.
-*/
-static int walCheckpoint(
- Wal *pWal, /* Wal connection */
- int eMode, /* One of PASSIVE, FULL or RESTART */
- int (*xBusyCall)(void*), /* Function to call when busy */
- void *pBusyArg, /* Context argument for xBusyHandler */
- int sync_flags, /* Flags for OsSync() (or 0) */
- u8 *zBuf /* Temporary buffer to use */
-){
- int rc; /* Return code */
- int szPage; /* Database page-size */
- WalIterator *pIter = 0; /* Wal iterator context */
- u32 iDbpage = 0; /* Next database page to write */
- u32 iFrame = 0; /* Wal frame containing data for iDbpage */
- u32 mxSafeFrame; /* Max frame that can be backfilled */
- u32 mxPage; /* Max database page to write */
- int i; /* Loop counter */
- volatile WalCkptInfo *pInfo; /* The checkpoint status information */
- int (*xBusy)(void*) = 0; /* Function to call when waiting for locks */
-
- szPage = walPagesize(pWal);
- testcase( szPage<=32768 );
- testcase( szPage>=65536 );
- pInfo = walCkptInfo(pWal);
- if( pInfo->nBackfill>=pWal->hdr.mxFrame ) return SQLITE_OK;
-
- /* Allocate the iterator */
- rc = walIteratorInit(pWal, &pIter);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- assert( pIter );
-
- if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall;
-
- /* Compute in mxSafeFrame the index of the last frame of the WAL that is
- ** safe to write into the database. Frames beyond mxSafeFrame might
- ** overwrite database pages that are in use by active readers and thus
- ** cannot be backfilled from the WAL.
- */
- mxSafeFrame = pWal->hdr.mxFrame;
- mxPage = pWal->hdr.nPage;
- for(i=1; i<WAL_NREADER; i++){
- u32 y = pInfo->aReadMark[i];
- if( mxSafeFrame>y ){
- assert( y<=pWal->hdr.mxFrame );
- rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
- if( rc==SQLITE_OK ){
- pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
- walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
- }else if( rc==SQLITE_BUSY ){
- mxSafeFrame = y;
- xBusy = 0;
- }else{
- goto walcheckpoint_out;
- }
- }
- }
-
- if( pInfo->nBackfill<mxSafeFrame
- && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0), 1))==SQLITE_OK
- ){
- i64 nSize; /* Current size of database file */
- u32 nBackfill = pInfo->nBackfill;
-
- /* Sync the WAL to disk */
- if( sync_flags ){
- rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
- }
-
- /* If the database file may grow as a result of this checkpoint, hint
- ** about the eventual size of the db file to the VFS layer.
- */
- if( rc==SQLITE_OK ){
- i64 nReq = ((i64)mxPage * szPage);
- rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
- if( rc==SQLITE_OK && nSize<nReq ){
- sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
- }
- }
-
- /* Iterate through the contents of the WAL, copying data to the db file. */
- while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
- i64 iOffset;
- assert( walFramePgno(pWal, iFrame)==iDbpage );
- if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
- iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
- /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
- rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
- if( rc!=SQLITE_OK ) break;
- iOffset = (iDbpage-1)*(i64)szPage;
- testcase( IS_BIG_INT(iOffset) );
- rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
- if( rc!=SQLITE_OK ) break;
- }
-
- /* If work was actually accomplished... */
- if( rc==SQLITE_OK ){
- if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
- i64 szDb = pWal->hdr.nPage*(i64)szPage;
- testcase( IS_BIG_INT(szDb) );
- rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
- if( rc==SQLITE_OK && sync_flags ){
- rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
- }
- }
- if( rc==SQLITE_OK ){
- pInfo->nBackfill = mxSafeFrame;
- }
- }
-
- /* Release the reader lock held while backfilling */
- walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
- }
-
- if( rc==SQLITE_BUSY ){
- /* Reset the return code so as not to report a checkpoint failure
- ** just because there are active readers. */
- rc = SQLITE_OK;
- }
-
- /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal
- ** file has been copied into the database file, then block until all
- ** readers have finished using the wal file. This ensures that the next
- ** process to write to the database restarts the wal file.
- */
- if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
- assert( pWal->writeLock );
- if( pInfo->nBackfill<pWal->hdr.mxFrame ){
- rc = SQLITE_BUSY;
- }else if( eMode==SQLITE_CHECKPOINT_RESTART ){
- assert( mxSafeFrame==pWal->hdr.mxFrame );
- rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
- if( rc==SQLITE_OK ){
- walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
- }
- }
- }
-
- walcheckpoint_out:
- walIteratorFree(pIter);
- return rc;
-}
-
-/*
-** If the WAL file is currently larger than nMax bytes in size, truncate
-** it to exactly nMax bytes. If an error occurs while doing so, ignore it.
-*/
-static void walLimitSize(Wal *pWal, i64 nMax){
- i64 sz;
- int rx;
- sqlite3BeginBenignMalloc();
- rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
- if( rx==SQLITE_OK && (sz > nMax ) ){
- rx = sqlite3OsTruncate(pWal->pWalFd, nMax);
- }
- sqlite3EndBenignMalloc();
- if( rx ){
- sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
- }
-}
-
-/*
-** Close a connection to a log file.
-*/
-SQLITE_PRIVATE int sqlite3WalClose(
- Wal *pWal, /* Wal to close */
- int sync_flags, /* Flags to pass to OsSync() (or 0) */
- int nBuf,
- u8 *zBuf /* Buffer of at least nBuf bytes */
-){
- int rc = SQLITE_OK;
- if( pWal ){
- int isDelete = 0; /* True to unlink wal and wal-index files */
-
- /* If an EXCLUSIVE lock can be obtained on the database file (using the
- ** ordinary, rollback-mode locking methods, this guarantees that the
- ** connection associated with this log file is the only connection to
- ** the database. In this case checkpoint the database and unlink both
- ** the wal and wal-index files.
- **
- ** The EXCLUSIVE lock is not released before returning.
- */
- rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
- if( rc==SQLITE_OK ){
- if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
- pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
- }
- rc = sqlite3WalCheckpoint(
- pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
- );
- if( rc==SQLITE_OK ){
- int bPersist = -1;
- sqlite3OsFileControlHint(
- pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist
- );
- if( bPersist!=1 ){
- /* Try to delete the WAL file if the checkpoint completed and
- ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal
- ** mode (!bPersist) */
- isDelete = 1;
- }else if( pWal->mxWalSize>=0 ){
- /* Try to truncate the WAL file to zero bytes if the checkpoint
- ** completed and fsynced (rc==SQLITE_OK) and we are in persistent
- ** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a
- ** non-negative value (pWal->mxWalSize>=0). Note that we truncate
- ** to zero bytes as truncating to the journal_size_limit might
- ** leave a corrupt WAL file on disk. */
- walLimitSize(pWal, 0);
- }
- }
- }
-
- walIndexClose(pWal, isDelete);
- sqlite3OsClose(pWal->pWalFd);
- if( isDelete ){
- sqlite3BeginBenignMalloc();
- sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0);
- sqlite3EndBenignMalloc();
- }
- WALTRACE(("WAL%p: closed\n", pWal));
- sqlite3_free((void *)pWal->apWiData);
- sqlite3_free(pWal);
- }
- return rc;
-}
-
-/*
-** Try to read the wal-index header. Return 0 on success and 1 if
-** there is a problem.
-**
-** The wal-index is in shared memory. Another thread or process might
-** be writing the header at the same time this procedure is trying to
-** read it, which might result in inconsistency. A dirty read is detected
-** by verifying that both copies of the header are the same and also by
-** a checksum on the header.
-**
-** If and only if the read is consistent and the header is different from
-** pWal->hdr, then pWal->hdr is updated to the content of the new header
-** and *pChanged is set to 1.
-**
-** If the checksum cannot be verified return non-zero. If the header
-** is read successfully and the checksum verified, return zero.
-*/
-static int walIndexTryHdr(Wal *pWal, int *pChanged){
- u32 aCksum[2]; /* Checksum on the header content */
- WalIndexHdr h1, h2; /* Two copies of the header content */
- WalIndexHdr volatile *aHdr; /* Header in shared memory */
-
- /* The first page of the wal-index must be mapped at this point. */
- assert( pWal->nWiData>0 && pWal->apWiData[0] );
-
- /* Read the header. This might happen concurrently with a write to the
- ** same area of shared memory on a different CPU in a SMP,
- ** meaning it is possible that an inconsistent snapshot is read
- ** from the file. If this happens, return non-zero.
- **
- ** There are two copies of the header at the beginning of the wal-index.
- ** When reading, read [0] first then [1]. Writes are in the reverse order.
- ** Memory barriers are used to prevent the compiler or the hardware from
- ** reordering the reads and writes.
- */
- aHdr = walIndexHdr(pWal);
- memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
- walShmBarrier(pWal);
- memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
-
- if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
- return 1; /* Dirty read */
- }
- if( h1.isInit==0 ){
- return 1; /* Malformed header - probably all zeros */
- }
- walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum);
- if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){
- return 1; /* Checksum does not match */
- }
-
- if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){
- *pChanged = 1;
- memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr));
- pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
- testcase( pWal->szPage<=32768 );
- testcase( pWal->szPage>=65536 );
- }
-
- /* The header was successfully read. Return zero. */
- return 0;
-}
-
-/*
-** Read the wal-index header from the wal-index and into pWal->hdr.
-** If the wal-header appears to be corrupt, try to reconstruct the
-** wal-index from the WAL before returning.
-**
-** Set *pChanged to 1 if the wal-index header value in pWal->hdr is
-** changed by this opertion. If pWal->hdr is unchanged, set *pChanged
-** to 0.
-**
-** If the wal-index header is successfully read, return SQLITE_OK.
-** Otherwise an SQLite error code.
-*/
-static int walIndexReadHdr(Wal *pWal, int *pChanged){
- int rc; /* Return code */
- int badHdr; /* True if a header read failed */
- volatile u32 *page0; /* Chunk of wal-index containing header */
-
- /* Ensure that page 0 of the wal-index (the page that contains the
- ** wal-index header) is mapped. Return early if an error occurs here.
- */
- assert( pChanged );
- rc = walIndexPage(pWal, 0, &page0);
- if( rc!=SQLITE_OK ){
- return rc;
- };
- assert( page0 || pWal->writeLock==0 );
-
- /* If the first page of the wal-index has been mapped, try to read the
- ** wal-index header immediately, without holding any lock. This usually
- ** works, but may fail if the wal-index header is corrupt or currently
- ** being modified by another thread or process.
- */
- badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
-
- /* If the first attempt failed, it might have been due to a race
- ** with a writer. So get a WRITE lock and try again.
- */
- assert( badHdr==0 || pWal->writeLock==0 );
- if( badHdr ){
- if( pWal->readOnly & WAL_SHM_RDONLY ){
- if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
- walUnlockShared(pWal, WAL_WRITE_LOCK);
- rc = SQLITE_READONLY_RECOVERY;
- }
- }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
- pWal->writeLock = 1;
- if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
- badHdr = walIndexTryHdr(pWal, pChanged);
- if( badHdr ){
- /* If the wal-index header is still malformed even while holding
- ** a WRITE lock, it can only mean that the header is corrupted and
- ** needs to be reconstructed. So run recovery to do exactly that.
- */
- rc = walIndexRecover(pWal);
- *pChanged = 1;
- }
- }
- pWal->writeLock = 0;
- walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
- }
- }
-
- /* If the header is read successfully, check the version number to make
- ** sure the wal-index was not constructed with some future format that
- ** this version of SQLite cannot understand.
- */
- if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
- rc = SQLITE_CANTOPEN_BKPT;
- }
-
- return rc;
-}
-
-/*
-** This is the value that walTryBeginRead returns when it needs to
-** be retried.
-*/
-#define WAL_RETRY (-1)
-
-/*
-** Attempt to start a read transaction. This might fail due to a race or
-** other transient condition. When that happens, it returns WAL_RETRY to
-** indicate to the caller that it is safe to retry immediately.
-**
-** On success return SQLITE_OK. On a permanent failure (such an
-** I/O error or an SQLITE_BUSY because another process is running
-** recovery) return a positive error code.
-**
-** The useWal parameter is true to force the use of the WAL and disable
-** the case where the WAL is bypassed because it has been completely
-** checkpointed. If useWal==0 then this routine calls walIndexReadHdr()
-** to make a copy of the wal-index header into pWal->hdr. If the
-** wal-index header has changed, *pChanged is set to 1 (as an indication
-** to the caller that the local paget cache is obsolete and needs to be
-** flushed.) When useWal==1, the wal-index header is assumed to already
-** be loaded and the pChanged parameter is unused.
-**
-** The caller must set the cnt parameter to the number of prior calls to
-** this routine during the current read attempt that returned WAL_RETRY.
-** This routine will start taking more aggressive measures to clear the
-** race conditions after multiple WAL_RETRY returns, and after an excessive
-** number of errors will ultimately return SQLITE_PROTOCOL. The
-** SQLITE_PROTOCOL return indicates that some other process has gone rogue
-** and is not honoring the locking protocol. There is a vanishingly small
-** chance that SQLITE_PROTOCOL could be returned because of a run of really
-** bad luck when there is lots of contention for the wal-index, but that
-** possibility is so small that it can be safely neglected, we believe.
-**
-** On success, this routine obtains a read lock on
-** WAL_READ_LOCK(pWal->readLock). The pWal->readLock integer is
-** in the range 0 <= pWal->readLock < WAL_NREADER. If pWal->readLock==(-1)
-** that means the Wal does not hold any read lock. The reader must not
-** access any database page that is modified by a WAL frame up to and
-** including frame number aReadMark[pWal->readLock]. The reader will
-** use WAL frames up to and including pWal->hdr.mxFrame if pWal->readLock>0
-** Or if pWal->readLock==0, then the reader will ignore the WAL
-** completely and get all content directly from the database file.
-** If the useWal parameter is 1 then the WAL will never be ignored and
-** this routine will always set pWal->readLock>0 on success.
-** When the read transaction is completed, the caller must release the
-** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1.
-**
-** This routine uses the nBackfill and aReadMark[] fields of the header
-** to select a particular WAL_READ_LOCK() that strives to let the
-** checkpoint process do as much work as possible. This routine might
-** update values of the aReadMark[] array in the header, but if it does
-** so it takes care to hold an exclusive lock on the corresponding
-** WAL_READ_LOCK() while changing values.
-*/
-static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
- volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */
- u32 mxReadMark; /* Largest aReadMark[] value */
- int mxI; /* Index of largest aReadMark[] value */
- int i; /* Loop counter */
- int rc = SQLITE_OK; /* Return code */
-
- assert( pWal->readLock<0 ); /* Not currently locked */
-
- /* Take steps to avoid spinning forever if there is a protocol error.
- **
- ** Circumstances that cause a RETRY should only last for the briefest
- ** instances of time. No I/O or other system calls are done while the
- ** locks are held, so the locks should not be held for very long. But
- ** if we are unlucky, another process that is holding a lock might get
- ** paged out or take a page-fault that is time-consuming to resolve,
- ** during the few nanoseconds that it is holding the lock. In that case,
- ** it might take longer than normal for the lock to free.
- **
- ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few
- ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this
- ** is more of a scheduler yield than an actual delay. But on the 10th
- ** an subsequent retries, the delays start becoming longer and longer,
- ** so that on the 100th (and last) RETRY we delay for 21 milliseconds.
- ** The total delay time before giving up is less than 1 second.
- */
- if( cnt>5 ){
- int nDelay = 1; /* Pause time in microseconds */
- if( cnt>100 ){
- VVA_ONLY( pWal->lockError = 1; )
- return SQLITE_PROTOCOL;
- }
- if( cnt>=10 ) nDelay = (cnt-9)*238; /* Max delay 21ms. Total delay 996ms */
- sqlite3OsSleep(pWal->pVfs, nDelay);
- }
-
- if( !useWal ){
- rc = walIndexReadHdr(pWal, pChanged);
- if( rc==SQLITE_BUSY ){
- /* If there is not a recovery running in another thread or process
- ** then convert BUSY errors to WAL_RETRY. If recovery is known to
- ** be running, convert BUSY to BUSY_RECOVERY. There is a race here
- ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY
- ** would be technically correct. But the race is benign since with
- ** WAL_RETRY this routine will be called again and will probably be
- ** right on the second iteration.
- */
- if( pWal->apWiData[0]==0 ){
- /* This branch is taken when the xShmMap() method returns SQLITE_BUSY.
- ** We assume this is a transient condition, so return WAL_RETRY. The
- ** xShmMap() implementation used by the default unix and win32 VFS
- ** modules may return SQLITE_BUSY due to a race condition in the
- ** code that determines whether or not the shared-memory region
- ** must be zeroed before the requested page is returned.
- */
- rc = WAL_RETRY;
- }else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){
- walUnlockShared(pWal, WAL_RECOVER_LOCK);
- rc = WAL_RETRY;
- }else if( rc==SQLITE_BUSY ){
- rc = SQLITE_BUSY_RECOVERY;
- }
- }
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
-
- pInfo = walCkptInfo(pWal);
- if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){
- /* The WAL has been completely backfilled (or it is empty).
- ** and can be safely ignored.
- */
- rc = walLockShared(pWal, WAL_READ_LOCK(0));
- walShmBarrier(pWal);
- if( rc==SQLITE_OK ){
- if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){
- /* It is not safe to allow the reader to continue here if frames
- ** may have been appended to the log before READ_LOCK(0) was obtained.
- ** When holding READ_LOCK(0), the reader ignores the entire log file,
- ** which implies that the database file contains a trustworthy
- ** snapshoT. Since holding READ_LOCK(0) prevents a checkpoint from
- ** happening, this is usually correct.
- **
- ** However, if frames have been appended to the log (or if the log
- ** is wrapped and written for that matter) before the READ_LOCK(0)
- ** is obtained, that is not necessarily true. A checkpointer may
- ** have started to backfill the appended frames but crashed before
- ** it finished. Leaving a corrupt image in the database file.
- */
- walUnlockShared(pWal, WAL_READ_LOCK(0));
- return WAL_RETRY;
- }
- pWal->readLock = 0;
- return SQLITE_OK;
- }else if( rc!=SQLITE_BUSY ){
- return rc;
- }
- }
-
- /* If we get this far, it means that the reader will want to use
- ** the WAL to get at content from recent commits. The job now is
- ** to select one of the aReadMark[] entries that is closest to
- ** but not exceeding pWal->hdr.mxFrame and lock that entry.
- */
- mxReadMark = 0;
- mxI = 0;
- for(i=1; i<WAL_NREADER; i++){
- u32 thisMark = pInfo->aReadMark[i];
- if( mxReadMark<=thisMark && thisMark<=pWal->hdr.mxFrame ){
- assert( thisMark!=READMARK_NOT_USED );
- mxReadMark = thisMark;
- mxI = i;
- }
- }
- /* There was once an "if" here. The extra "{" is to preserve indentation. */
- {
- if( (pWal->readOnly & WAL_SHM_RDONLY)==0
- && (mxReadMark<pWal->hdr.mxFrame || mxI==0)
- ){
- for(i=1; i<WAL_NREADER; i++){
- rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
- if( rc==SQLITE_OK ){
- mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
- mxI = i;
- walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
- break;
- }else if( rc!=SQLITE_BUSY ){
- return rc;
- }
- }
- }
- if( mxI==0 ){
- assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
- return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
- }
-
- rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
- if( rc ){
- return rc==SQLITE_BUSY ? WAL_RETRY : rc;
- }
- /* Now that the read-lock has been obtained, check that neither the
- ** value in the aReadMark[] array or the contents of the wal-index
- ** header have changed.
- **
- ** It is necessary to check that the wal-index header did not change
- ** between the time it was read and when the shared-lock was obtained
- ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
- ** that the log file may have been wrapped by a writer, or that frames
- ** that occur later in the log than pWal->hdr.mxFrame may have been
- ** copied into the database by a checkpointer. If either of these things
- ** happened, then reading the database with the current value of
- ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
- ** instead.
- **
- ** This does not guarantee that the copy of the wal-index header is up to
- ** date before proceeding. That would not be possible without somehow
- ** blocking writers. It only guarantees that a dangerous checkpoint or
- ** log-wrap (either of which would require an exclusive lock on
- ** WAL_READ_LOCK(mxI)) has not occurred since the snapshot was valid.
- */
- walShmBarrier(pWal);
- if( pInfo->aReadMark[mxI]!=mxReadMark
- || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
- ){
- walUnlockShared(pWal, WAL_READ_LOCK(mxI));
- return WAL_RETRY;
- }else{
- assert( mxReadMark<=pWal->hdr.mxFrame );
- pWal->readLock = (i16)mxI;
- }
- }
- return rc;
-}
-
-/*
-** Begin a read transaction on the database.
-**
-** This routine used to be called sqlite3OpenSnapshot() and with good reason:
-** it takes a snapshot of the state of the WAL and wal-index for the current
-** instant in time. The current thread will continue to use this snapshot.
-** Other threads might append new content to the WAL and wal-index but
-** that extra content is ignored by the current thread.
-**
-** If the database contents have changes since the previous read
-** transaction, then *pChanged is set to 1 before returning. The
-** Pager layer will use this to know that is cache is stale and
-** needs to be flushed.
-*/
-SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
- int rc; /* Return code */
- int cnt = 0; /* Number of TryBeginRead attempts */
-
- do{
- rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
- }while( rc==WAL_RETRY );
- testcase( (rc&0xff)==SQLITE_BUSY );
- testcase( (rc&0xff)==SQLITE_IOERR );
- testcase( rc==SQLITE_PROTOCOL );
- testcase( rc==SQLITE_OK );
- return rc;
-}
-
-/*
-** Finish with a read transaction. All this does is release the
-** read-lock.
-*/
-SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
- sqlite3WalEndWriteTransaction(pWal);
- if( pWal->readLock>=0 ){
- walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
- pWal->readLock = -1;
- }
-}
-
-/*
-** Read a page from the WAL, if it is present in the WAL and if the
-** current read transaction is configured to use the WAL.
-**
-** The *pInWal is set to 1 if the requested page is in the WAL and
-** has been loaded. Or *pInWal is set to 0 if the page was not in
-** the WAL and needs to be read out of the database.
-*/
-SQLITE_PRIVATE int sqlite3WalRead(
- Wal *pWal, /* WAL handle */
- Pgno pgno, /* Database page number to read data for */
- int *pInWal, /* OUT: True if data is read from WAL */
- int nOut, /* Size of buffer pOut in bytes */
- u8 *pOut /* Buffer to write page data to */
-){
- u32 iRead = 0; /* If !=0, WAL frame to return data from */
- u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */
- int iHash; /* Used to loop through N hash tables */
-
- /* This routine is only be called from within a read transaction. */
- assert( pWal->readLock>=0 || pWal->lockError );
-
- /* If the "last page" field of the wal-index header snapshot is 0, then
- ** no data will be read from the wal under any circumstances. Return early
- ** in this case as an optimization. Likewise, if pWal->readLock==0,
- ** then the WAL is ignored by the reader so return early, as if the
- ** WAL were empty.
- */
- if( iLast==0 || pWal->readLock==0 ){
- *pInWal = 0;
- return SQLITE_OK;
- }
-
- /* Search the hash table or tables for an entry matching page number
- ** pgno. Each iteration of the following for() loop searches one
- ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames).
- **
- ** This code might run concurrently to the code in walIndexAppend()
- ** that adds entries to the wal-index (and possibly to this hash
- ** table). This means the value just read from the hash
- ** slot (aHash[iKey]) may have been added before or after the
- ** current read transaction was opened. Values added after the
- ** read transaction was opened may have been written incorrectly -
- ** i.e. these slots may contain garbage data. However, we assume
- ** that any slots written before the current read transaction was
- ** opened remain unmodified.
- **
- ** For the reasons above, the if(...) condition featured in the inner
- ** loop of the following block is more stringent that would be required
- ** if we had exclusive access to the hash-table:
- **
- ** (aPgno[iFrame]==pgno):
- ** This condition filters out normal hash-table collisions.
- **
- ** (iFrame<=iLast):
- ** This condition filters out entries that were added to the hash
- ** table after the current read-transaction had started.
- */
- for(iHash=walFramePage(iLast); iHash>=0 && iRead==0; iHash--){
- volatile ht_slot *aHash; /* Pointer to hash table */
- volatile u32 *aPgno; /* Pointer to array of page numbers */
- u32 iZero; /* Frame number corresponding to aPgno[0] */
- int iKey; /* Hash slot index */
- int nCollide; /* Number of hash collisions remaining */
- int rc; /* Error code */
-
- rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- nCollide = HASHTABLE_NSLOT;
- for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
- u32 iFrame = aHash[iKey] + iZero;
- if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
- /* assert( iFrame>iRead ); -- not true if there is corruption */
- iRead = iFrame;
- }
- if( (nCollide--)==0 ){
- return SQLITE_CORRUPT_BKPT;
- }
- }
- }
-
-#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
- /* If expensive assert() statements are available, do a linear search
- ** of the wal-index file content. Make sure the results agree with the
- ** result obtained using the hash indexes above. */
- {
- u32 iRead2 = 0;
- u32 iTest;
- for(iTest=iLast; iTest>0; iTest--){
- if( walFramePgno(pWal, iTest)==pgno ){
- iRead2 = iTest;
- break;
- }
- }
- assert( iRead==iRead2 );
- }
-#endif
-
- /* If iRead is non-zero, then it is the log frame number that contains the
- ** required page. Read and return data from the log file.
- */
- if( iRead ){
- int sz;
- i64 iOffset;
- sz = pWal->hdr.szPage;
- sz = (sz&0xfe00) + ((sz&0x0001)<<16);
- testcase( sz<=32768 );
- testcase( sz>=65536 );
- iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
- *pInWal = 1;
- /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
- return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
- }
-
- *pInWal = 0;
- return SQLITE_OK;
-}
-
-
-/*
-** Return the size of the database in pages (or zero, if unknown).
-*/
-SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){
- if( pWal && ALWAYS(pWal->readLock>=0) ){
- return pWal->hdr.nPage;
- }
- return 0;
-}
-
-
-/*
-** This function starts a write transaction on the WAL.
-**
-** A read transaction must have already been started by a prior call
-** to sqlite3WalBeginReadTransaction().
-**
-** If another thread or process has written into the database since
-** the read transaction was started, then it is not possible for this
-** thread to write as doing so would cause a fork. So this routine
-** returns SQLITE_BUSY in that case and no write transaction is started.
-**
-** There can only be a single writer active at a time.
-*/
-SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
- int rc;
-
- /* Cannot start a write transaction without first holding a read
- ** transaction. */
- assert( pWal->readLock>=0 );
-
- if( pWal->readOnly ){
- return SQLITE_READONLY;
- }
-
- /* Only one writer allowed at a time. Get the write lock. Return
- ** SQLITE_BUSY if unable.
- */
- rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
- if( rc ){
- return rc;
- }
- pWal->writeLock = 1;
-
- /* If another connection has written to the database file since the
- ** time the read transaction on this connection was started, then
- ** the write is disallowed.
- */
- if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
- walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
- pWal->writeLock = 0;
- rc = SQLITE_BUSY;
- }
-
- return rc;
-}
-
-/*
-** End a write transaction. The commit has already been done. This
-** routine merely releases the lock.
-*/
-SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){
- if( pWal->writeLock ){
- walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
- pWal->writeLock = 0;
- pWal->truncateOnCommit = 0;
- }
- return SQLITE_OK;
-}
-
-/*
-** If any data has been written (but not committed) to the log file, this
-** function moves the write-pointer back to the start of the transaction.
-**
-** Additionally, the callback function is invoked for each frame written
-** to the WAL since the start of the transaction. If the callback returns
-** other than SQLITE_OK, it is not invoked again and the error code is
-** returned to the caller.
-**
-** Otherwise, if the callback function does not return an error, this
-** function returns SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
- int rc = SQLITE_OK;
- if( ALWAYS(pWal->writeLock) ){
- Pgno iMax = pWal->hdr.mxFrame;
- Pgno iFrame;
-
- /* Restore the clients cache of the wal-index header to the state it
- ** was in before the client began writing to the database.
- */
- memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr));
-
- for(iFrame=pWal->hdr.mxFrame+1;
- ALWAYS(rc==SQLITE_OK) && iFrame<=iMax;
- iFrame++
- ){
- /* This call cannot fail. Unless the page for which the page number
- ** is passed as the second argument is (a) in the cache and
- ** (b) has an outstanding reference, then xUndo is either a no-op
- ** (if (a) is false) or simply expels the page from the cache (if (b)
- ** is false).
- **
- ** If the upper layer is doing a rollback, it is guaranteed that there
- ** are no outstanding references to any page other than page 1. And
- ** page 1 is never written to the log until the transaction is
- ** committed. As a result, the call to xUndo may not fail.
- */
- assert( walFramePgno(pWal, iFrame)!=1 );
- rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
- }
- if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
- }
- assert( rc==SQLITE_OK );
- return rc;
-}
-
-/*
-** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32
-** values. This function populates the array with values required to
-** "rollback" the write position of the WAL handle back to the current
-** point in the event of a savepoint rollback (via WalSavepointUndo()).
-*/
-SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){
- assert( pWal->writeLock );
- aWalData[0] = pWal->hdr.mxFrame;
- aWalData[1] = pWal->hdr.aFrameCksum[0];
- aWalData[2] = pWal->hdr.aFrameCksum[1];
- aWalData[3] = pWal->nCkpt;
-}
-
-/*
-** Move the write position of the WAL back to the point identified by
-** the values in the aWalData[] array. aWalData must point to an array
-** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated
-** by a call to WalSavepoint().
-*/
-SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
- int rc = SQLITE_OK;
-
- assert( pWal->writeLock );
- assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame );
-
- if( aWalData[3]!=pWal->nCkpt ){
- /* This savepoint was opened immediately after the write-transaction
- ** was started. Right after that, the writer decided to wrap around
- ** to the start of the log. Update the savepoint values to match.
- */
- aWalData[0] = 0;
- aWalData[3] = pWal->nCkpt;
- }
-
- if( aWalData[0]<pWal->hdr.mxFrame ){
- pWal->hdr.mxFrame = aWalData[0];
- pWal->hdr.aFrameCksum[0] = aWalData[1];
- pWal->hdr.aFrameCksum[1] = aWalData[2];
- walCleanupHash(pWal);
- }
-
- return rc;
-}
-
-
-/*
-** This function is called just before writing a set of frames to the log
-** file (see sqlite3WalFrames()). It checks to see if, instead of appending
-** to the current log file, it is possible to overwrite the start of the
-** existing log file with the new frames (i.e. "reset" the log). If so,
-** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left
-** unchanged.
-**
-** SQLITE_OK is returned if no error is encountered (regardless of whether
-** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned
-** if an error occurs.
-*/
-static int walRestartLog(Wal *pWal){
- int rc = SQLITE_OK;
- int cnt;
-
- if( pWal->readLock==0 ){
- volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
- assert( pInfo->nBackfill==pWal->hdr.mxFrame );
- if( pInfo->nBackfill>0 ){
- u32 salt1;
- sqlite3_randomness(4, &salt1);
- rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
- if( rc==SQLITE_OK ){
- /* If all readers are using WAL_READ_LOCK(0) (in other words if no
- ** readers are currently using the WAL), then the transactions
- ** frames will overwrite the start of the existing log. Update the
- ** wal-index header to reflect this.
- **
- ** In theory it would be Ok to update the cache of the header only
- ** at this point. But updating the actual wal-index header is also
- ** safe and means there is no special case for sqlite3WalUndo()
- ** to handle if this transaction is rolled back.
- */
- int i; /* Loop counter */
- u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */
-
- pWal->nCkpt++;
- pWal->hdr.mxFrame = 0;
- sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
- aSalt[1] = salt1;
- walIndexWriteHdr(pWal);
- pInfo->nBackfill = 0;
- pInfo->aReadMark[1] = 0;
- for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
- assert( pInfo->aReadMark[0]==0 );
- walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
- }else if( rc!=SQLITE_BUSY ){
- return rc;
- }
- }
- walUnlockShared(pWal, WAL_READ_LOCK(0));
- pWal->readLock = -1;
- cnt = 0;
- do{
- int notUsed;
- rc = walTryBeginRead(pWal, &notUsed, 1, ++cnt);
- }while( rc==WAL_RETRY );
- assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */
- testcase( (rc&0xff)==SQLITE_IOERR );
- testcase( rc==SQLITE_PROTOCOL );
- testcase( rc==SQLITE_OK );
- }
- return rc;
-}
-
-/*
-** Information about the current state of the WAL file and where
-** the next fsync should occur - passed from sqlite3WalFrames() into
-** walWriteToLog().
-*/
-typedef struct WalWriter {
- Wal *pWal; /* The complete WAL information */
- sqlite3_file *pFd; /* The WAL file to which we write */
- sqlite3_int64 iSyncPoint; /* Fsync at this offset */
- int syncFlags; /* Flags for the fsync */
- int szPage; /* Size of one page */
-} WalWriter;
-
-/*
-** Write iAmt bytes of content into the WAL file beginning at iOffset.
-** Do a sync when crossing the p->iSyncPoint boundary.
-**
-** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt,
-** first write the part before iSyncPoint, then sync, then write the
-** rest.
-*/
-static int walWriteToLog(
- WalWriter *p, /* WAL to write to */
- void *pContent, /* Content to be written */
- int iAmt, /* Number of bytes to write */
- sqlite3_int64 iOffset /* Start writing at this offset */
-){
- int rc;
- if( iOffset<p->iSyncPoint && iOffset+iAmt>=p->iSyncPoint ){
- int iFirstAmt = (int)(p->iSyncPoint - iOffset);
- rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset);
- if( rc ) return rc;
- iOffset += iFirstAmt;
- iAmt -= iFirstAmt;
- pContent = (void*)(iFirstAmt + (char*)pContent);
- assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
- rc = sqlite3OsSync(p->pFd, p->syncFlags);
- if( iAmt==0 || rc ) return rc;
- }
- rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
- return rc;
-}
-
-/*
-** Write out a single frame of the WAL
-*/
-static int walWriteOneFrame(
- WalWriter *p, /* Where to write the frame */
- PgHdr *pPage, /* The page of the frame to be written */
- int nTruncate, /* The commit flag. Usually 0. >0 for commit */
- sqlite3_int64 iOffset /* Byte offset at which to write */
-){
- int rc; /* Result code from subfunctions */
- void *pData; /* Data actually written */
- u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */
-#if defined(SQLITE_HAS_CODEC)
- if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
-#else
- pData = pPage->pData;
-#endif
- walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
- rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
- if( rc ) return rc;
- /* Write the page data */
- rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
- return rc;
-}
-
-/*
-** Write a set of frames to the log. The caller must hold the write-lock
-** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
-*/
-SQLITE_PRIVATE int sqlite3WalFrames(
- Wal *pWal, /* Wal handle to write to */
- int szPage, /* Database page-size in bytes */
- PgHdr *pList, /* List of dirty pages to write */
- Pgno nTruncate, /* Database size after this commit */
- int isCommit, /* True if this is a commit */
- int sync_flags /* Flags to pass to OsSync() (or 0) */
-){
- int rc; /* Used to catch return codes */
- u32 iFrame; /* Next frame address */
- PgHdr *p; /* Iterator to run through pList with. */
- PgHdr *pLast = 0; /* Last frame in list */
- int nExtra = 0; /* Number of extra copies of last page */
- int szFrame; /* The size of a single frame */
- i64 iOffset; /* Next byte to write in WAL file */
- WalWriter w; /* The writer */
-
- assert( pList );
- assert( pWal->writeLock );
-
- /* If this frame set completes a transaction, then nTruncate>0. If
- ** nTruncate==0 then this frame set does not complete the transaction. */
- assert( (isCommit!=0)==(nTruncate!=0) );
-
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
- { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){}
- WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n",
- pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill"));
- }
-#endif
-
- /* See if it is possible to write these frames into the start of the
- ** log file, instead of appending to it at pWal->hdr.mxFrame.
- */
- if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){
- return rc;
- }
-
- /* If this is the first frame written into the log, write the WAL
- ** header to the start of the WAL file. See comments at the top of
- ** this source file for a description of the WAL header format.
- */
- iFrame = pWal->hdr.mxFrame;
- if( iFrame==0 ){
- u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */
- u32 aCksum[2]; /* Checksum for wal-header */
-
- sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN));
- sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
- sqlite3Put4byte(&aWalHdr[8], szPage);
- sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
- if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt);
- memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
- walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
- sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
- sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
-
- pWal->szPage = szPage;
- pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
- pWal->hdr.aFrameCksum[0] = aCksum[0];
- pWal->hdr.aFrameCksum[1] = aCksum[1];
- pWal->truncateOnCommit = 1;
-
- rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0);
- WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok"));
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless
- ** all syncing is turned off by PRAGMA synchronous=OFF). Otherwise
- ** an out-of-order write following a WAL restart could result in
- ** database corruption. See the ticket:
- **
- ** http://localhost:591/sqlite/info/ff5be73dee
- */
- if( pWal->syncHeader && sync_flags ){
- rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK);
- if( rc ) return rc;
- }
- }
- assert( (int)pWal->szPage==szPage );
-
- /* Setup information needed to write frames into the WAL */
- w.pWal = pWal;
- w.pFd = pWal->pWalFd;
- w.iSyncPoint = 0;
- w.syncFlags = sync_flags;
- w.szPage = szPage;
- iOffset = walFrameOffset(iFrame+1, szPage);
- szFrame = szPage + WAL_FRAME_HDRSIZE;
-
- /* Write all frames into the log file exactly once */
- for(p=pList; p; p=p->pDirty){
- int nDbSize; /* 0 normally. Positive == commit flag */
- iFrame++;
- assert( iOffset==walFrameOffset(iFrame, szPage) );
- nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
- rc = walWriteOneFrame(&w, p, nDbSize, iOffset);
- if( rc ) return rc;
- pLast = p;
- iOffset += szFrame;
- }
-
- /* If this is the end of a transaction, then we might need to pad
- ** the transaction and/or sync the WAL file.
- **
- ** Padding and syncing only occur if this set of frames complete a
- ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL
- ** or synchonous==OFF, then no padding or syncing are needed.
- **
- ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not
- ** needed and only the sync is done. If padding is needed, then the
- ** final frame is repeated (with its commit mark) until the next sector
- ** boundary is crossed. Only the part of the WAL prior to the last
- ** sector boundary is synced; the part of the last frame that extends
- ** past the sector boundary is written after the sync.
- */
- if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
- if( pWal->padToSectorBoundary ){
- int sectorSize = sqlite3SectorSize(pWal->pWalFd);
- w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
- while( iOffset<w.iSyncPoint ){
- rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
- if( rc ) return rc;
- iOffset += szFrame;
- nExtra++;
- }
- }else{
- rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
- }
- }
-
- /* If this frame set completes the first transaction in the WAL and
- ** if PRAGMA journal_size_limit is set, then truncate the WAL to the
- ** journal size limit, if possible.
- */
- if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){
- i64 sz = pWal->mxWalSize;
- if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){
- sz = walFrameOffset(iFrame+nExtra+1, szPage);
- }
- walLimitSize(pWal, sz);
- pWal->truncateOnCommit = 0;
- }
-
- /* Append data to the wal-index. It is not necessary to lock the
- ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index
- ** guarantees that there are no other writers, and no data that may
- ** be in use by existing readers is being overwritten.
- */
- iFrame = pWal->hdr.mxFrame;
- for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
- iFrame++;
- rc = walIndexAppend(pWal, iFrame, p->pgno);
- }
- while( rc==SQLITE_OK && nExtra>0 ){
- iFrame++;
- nExtra--;
- rc = walIndexAppend(pWal, iFrame, pLast->pgno);
- }
-
- if( rc==SQLITE_OK ){
- /* Update the private copy of the header. */
- pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
- testcase( szPage<=32768 );
- testcase( szPage>=65536 );
- pWal->hdr.mxFrame = iFrame;
- if( isCommit ){
- pWal->hdr.iChange++;
- pWal->hdr.nPage = nTruncate;
- }
- /* If this is a commit, update the wal-index header too. */
- if( isCommit ){
- walIndexWriteHdr(pWal);
- pWal->iCallback = iFrame;
- }
- }
-
- WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok"));
- return rc;
-}
-
-/*
-** This routine is called to implement sqlite3_wal_checkpoint() and
-** related interfaces.
-**
-** Obtain a CHECKPOINT lock and then backfill as much information as
-** we can from WAL into the database.
-**
-** If parameter xBusy is not NULL, it is a pointer to a busy-handler
-** callback. In this case this function runs a blocking checkpoint.
-*/
-SQLITE_PRIVATE int sqlite3WalCheckpoint(
- Wal *pWal, /* Wal connection */
- int eMode, /* PASSIVE, FULL or RESTART */
- int (*xBusy)(void*), /* Function to call when busy */
- void *pBusyArg, /* Context argument for xBusyHandler */
- int sync_flags, /* Flags to sync db file with (or 0) */
- int nBuf, /* Size of temporary buffer */
- u8 *zBuf, /* Temporary buffer to use */
- int *pnLog, /* OUT: Number of frames in WAL */
- int *pnCkpt /* OUT: Number of backfilled frames in WAL */
-){
- int rc; /* Return code */
- int isChanged = 0; /* True if a new wal-index header is loaded */
- int eMode2 = eMode; /* Mode to pass to walCheckpoint() */
-
- assert( pWal->ckptLock==0 );
- assert( pWal->writeLock==0 );
-
- if( pWal->readOnly ) return SQLITE_READONLY;
- WALTRACE(("WAL%p: checkpoint begins\n", pWal));
- rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
- if( rc ){
- /* Usually this is SQLITE_BUSY meaning that another thread or process
- ** is already running a checkpoint, or maybe a recovery. But it might
- ** also be SQLITE_IOERR. */
- return rc;
- }
- pWal->ckptLock = 1;
-
- /* If this is a blocking-checkpoint, then obtain the write-lock as well
- ** to prevent any writers from running while the checkpoint is underway.
- ** This has to be done before the call to walIndexReadHdr() below.
- **
- ** If the writer lock cannot be obtained, then a passive checkpoint is
- ** run instead. Since the checkpointer is not holding the writer lock,
- ** there is no point in blocking waiting for any readers. Assuming no
- ** other error occurs, this function will return SQLITE_BUSY to the caller.
- */
- if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
- rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
- if( rc==SQLITE_OK ){
- pWal->writeLock = 1;
- }else if( rc==SQLITE_BUSY ){
- eMode2 = SQLITE_CHECKPOINT_PASSIVE;
- rc = SQLITE_OK;
- }
- }
-
- /* Read the wal-index header. */
- if( rc==SQLITE_OK ){
- rc = walIndexReadHdr(pWal, &isChanged);
- }
-
- /* Copy data from the log to the database file. */
- if( rc==SQLITE_OK ){
- if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
- rc = SQLITE_CORRUPT_BKPT;
- }else{
- rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf);
- }
-
- /* If no error occurred, set the output variables. */
- if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
- if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
- if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill);
- }
- }
-
- if( isChanged ){
- /* If a new wal-index header was loaded before the checkpoint was
- ** performed, then the pager-cache associated with pWal is now
- ** out of date. So zero the cached wal-index header to ensure that
- ** next time the pager opens a snapshot on this database it knows that
- ** the cache needs to be reset.
- */
- memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
- }
-
- /* Release the locks. */
- sqlite3WalEndWriteTransaction(pWal);
- walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
- pWal->ckptLock = 0;
- WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
- return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
-}
-
-/* Return the value to pass to a sqlite3_wal_hook callback, the
-** number of frames in the WAL at the point of the last commit since
-** sqlite3WalCallback() was called. If no commits have occurred since
-** the last call, then return 0.
-*/
-SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){
- u32 ret = 0;
- if( pWal ){
- ret = pWal->iCallback;
- pWal->iCallback = 0;
- }
- return (int)ret;
-}
-
-/*
-** This function is called to change the WAL subsystem into or out
-** of locking_mode=EXCLUSIVE.
-**
-** If op is zero, then attempt to change from locking_mode=EXCLUSIVE
-** into locking_mode=NORMAL. This means that we must acquire a lock
-** on the pWal->readLock byte. If the WAL is already in locking_mode=NORMAL
-** or if the acquisition of the lock fails, then return 0. If the
-** transition out of exclusive-mode is successful, return 1. This
-** operation must occur while the pager is still holding the exclusive
-** lock on the main database file.
-**
-** If op is one, then change from locking_mode=NORMAL into
-** locking_mode=EXCLUSIVE. This means that the pWal->readLock must
-** be released. Return 1 if the transition is made and 0 if the
-** WAL is already in exclusive-locking mode - meaning that this
-** routine is a no-op. The pager must already hold the exclusive lock
-** on the main database file before invoking this operation.
-**
-** If op is negative, then do a dry-run of the op==1 case but do
-** not actually change anything. The pager uses this to see if it
-** should acquire the database exclusive lock prior to invoking
-** the op==1 case.
-*/
-SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){
- int rc;
- assert( pWal->writeLock==0 );
- assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 );
-
- /* pWal->readLock is usually set, but might be -1 if there was a
- ** prior error while attempting to acquire are read-lock. This cannot
- ** happen if the connection is actually in exclusive mode (as no xShmLock
- ** locks are taken in this case). Nor should the pager attempt to
- ** upgrade to exclusive-mode following such an error.
- */
- assert( pWal->readLock>=0 || pWal->lockError );
- assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) );
-
- if( op==0 ){
- if( pWal->exclusiveMode ){
- pWal->exclusiveMode = 0;
- if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
- pWal->exclusiveMode = 1;
- }
- rc = pWal->exclusiveMode==0;
- }else{
- /* Already in locking_mode=NORMAL */
- rc = 0;
- }
- }else if( op>0 ){
- assert( pWal->exclusiveMode==0 );
- assert( pWal->readLock>=0 );
- walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
- pWal->exclusiveMode = 1;
- rc = 1;
- }else{
- rc = pWal->exclusiveMode==0;
- }
- return rc;
-}
-
-/*
-** Return true if the argument is non-NULL and the WAL module is using
-** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
-** WAL module is using shared-memory, return false.
-*/
-SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){
- return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
-}
-
-#ifdef SQLITE_ENABLE_ZIPVFS
-/*
-** If the argument is not NULL, it points to a Wal object that holds a
-** read-lock. This function returns the database page-size if it is known,
-** or zero if it is not (or if pWal is NULL).
-*/
-SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
- assert( pWal==0 || pWal->readLock>=0 );
- return (pWal ? pWal->szPage : 0);
-}
-#endif
-
-#endif /* #ifndef SQLITE_OMIT_WAL */
-
-/************** End of wal.c *************************************************/
-/************** Begin file btmutex.c *****************************************/
-/*
-** 2007 August 27
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains code used to implement mutexes on Btree objects.
-** This code really belongs in btree.c. But btree.c is getting too
-** big and we want to break it down some. This packaged seemed like
-** a good breakout.
-*/
-/************** Include btreeInt.h in the middle of btmutex.c ****************/
-/************** Begin file btreeInt.h ****************************************/
-/*
-** 2004 April 6
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file implements a external (disk-based) database using BTrees.
-** For a detailed discussion of BTrees, refer to
-**
-** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
-** "Sorting And Searching", pages 473-480. Addison-Wesley
-** Publishing Company, Reading, Massachusetts.
-**
-** The basic idea is that each page of the file contains N database
-** entries and N+1 pointers to subpages.
-**
-** ----------------------------------------------------------------
-** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) |
-** ----------------------------------------------------------------
-**
-** All of the keys on the page that Ptr(0) points to have values less
-** than Key(0). All of the keys on page Ptr(1) and its subpages have
-** values greater than Key(0) and less than Key(1). All of the keys
-** on Ptr(N) and its subpages have values greater than Key(N-1). And
-** so forth.
-**
-** Finding a particular key requires reading O(log(M)) pages from the
-** disk where M is the number of entries in the tree.
-**
-** In this implementation, a single file can hold one or more separate
-** BTrees. Each BTree is identified by the index of its root page. The
-** key and data for any entry are combined to form the "payload". A
-** fixed amount of payload can be carried directly on the database
-** page. If the payload is larger than the preset amount then surplus
-** bytes are stored on overflow pages. The payload for an entry
-** and the preceding pointer are combined to form a "Cell". Each
-** page has a small header which contains the Ptr(N) pointer and other
-** information such as the size of key and data.
-**
-** FORMAT DETAILS
-**
-** The file is divided into pages. The first page is called page 1,
-** the second is page 2, and so forth. A page number of zero indicates
-** "no such page". The page size can be any power of 2 between 512 and 65536.
-** Each page can be either a btree page, a freelist page, an overflow
-** page, or a pointer-map page.
-**
-** The first page is always a btree page. The first 100 bytes of the first
-** page contain a special header (the "file header") that describes the file.
-** The format of the file header is as follows:
-**
-** OFFSET SIZE DESCRIPTION
-** 0 16 Header string: "SQLite format 3\000"
-** 16 2 Page size in bytes.
-** 18 1 File format write version
-** 19 1 File format read version
-** 20 1 Bytes of unused space at the end of each page
-** 21 1 Max embedded payload fraction
-** 22 1 Min embedded payload fraction
-** 23 1 Min leaf payload fraction
-** 24 4 File change counter
-** 28 4 Reserved for future use
-** 32 4 First freelist page
-** 36 4 Number of freelist pages in the file
-** 40 60 15 4-byte meta values passed to higher layers
-**
-** 40 4 Schema cookie
-** 44 4 File format of schema layer
-** 48 4 Size of page cache
-** 52 4 Largest root-page (auto/incr_vacuum)
-** 56 4 1=UTF-8 2=UTF16le 3=UTF16be
-** 60 4 User version
-** 64 4 Incremental vacuum mode
-** 68 4 unused
-** 72 4 unused
-** 76 4 unused
-**
-** All of the integer values are big-endian (most significant byte first).
-**
-** The file change counter is incremented when the database is changed
-** This counter allows other processes to know when the file has changed
-** and thus when they need to flush their cache.
-**
-** The max embedded payload fraction is the amount of the total usable
-** space in a page that can be consumed by a single cell for standard
-** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default
-** is to limit the maximum cell size so that at least 4 cells will fit
-** on one page. Thus the default max embedded payload fraction is 64.
-**
-** If the payload for a cell is larger than the max payload, then extra
-** payload is spilled to overflow pages. Once an overflow page is allocated,
-** as many bytes as possible are moved into the overflow pages without letting
-** the cell size drop below the min embedded payload fraction.
-**
-** The min leaf payload fraction is like the min embedded payload fraction
-** except that it applies to leaf nodes in a LEAFDATA tree. The maximum
-** payload fraction for a LEAFDATA tree is always 100% (or 255) and it
-** not specified in the header.
-**
-** Each btree pages is divided into three sections: The header, the
-** cell pointer array, and the cell content area. Page 1 also has a 100-byte
-** file header that occurs before the page header.
-**
-** |----------------|
-** | file header | 100 bytes. Page 1 only.
-** |----------------|
-** | page header | 8 bytes for leaves. 12 bytes for interior nodes
-** |----------------|
-** | cell pointer | | 2 bytes per cell. Sorted order.
-** | array | | Grows downward
-** | | v
-** |----------------|
-** | unallocated |
-** | space |
-** |----------------| ^ Grows upwards
-** | cell content | | Arbitrary order interspersed with freeblocks.
-** | area | | and free space fragments.
-** |----------------|
-**
-** The page headers looks like this:
-**
-** OFFSET SIZE DESCRIPTION
-** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
-** 1 2 byte offset to the first freeblock
-** 3 2 number of cells on this page
-** 5 2 first byte of the cell content area
-** 7 1 number of fragmented free bytes
-** 8 4 Right child (the Ptr(N) value). Omitted on leaves.
-**
-** The flags define the format of this btree page. The leaf flag means that
-** this page has no children. The zerodata flag means that this page carries
-** only keys and no data. The intkey flag means that the key is a integer
-** which is stored in the key size entry of the cell header rather than in
-** the payload area.
-**
-** The cell pointer array begins on the first byte after the page header.
-** The cell pointer array contains zero or more 2-byte numbers which are
-** offsets from the beginning of the page to the cell content in the cell
-** content area. The cell pointers occur in sorted order. The system strives
-** to keep free space after the last cell pointer so that new cells can
-** be easily added without having to defragment the page.
-**
-** Cell content is stored at the very end of the page and grows toward the
-** beginning of the page.
-**
-** Unused space within the cell content area is collected into a linked list of
-** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset
-** to the first freeblock is given in the header. Freeblocks occur in
-** increasing order. Because a freeblock must be at least 4 bytes in size,
-** any group of 3 or fewer unused bytes in the cell content area cannot
-** exist on the freeblock chain. A group of 3 or fewer free bytes is called
-** a fragment. The total number of bytes in all fragments is recorded.
-** in the page header at offset 7.
-**
-** SIZE DESCRIPTION
-** 2 Byte offset of the next freeblock
-** 2 Bytes in this freeblock
-**
-** Cells are of variable length. Cells are stored in the cell content area at
-** the end of the page. Pointers to the cells are in the cell pointer array
-** that immediately follows the page header. Cells is not necessarily
-** contiguous or in order, but cell pointers are contiguous and in order.
-**
-** Cell content makes use of variable length integers. A variable
-** length integer is 1 to 9 bytes where the lower 7 bits of each
-** byte are used. The integer consists of all bytes that have bit 8 set and
-** the first byte with bit 8 clear. The most significant byte of the integer
-** appears first. A variable-length integer may not be more than 9 bytes long.
-** As a special case, all 8 bytes of the 9th byte are used as data. This
-** allows a 64-bit integer to be encoded in 9 bytes.
-**
-** 0x00 becomes 0x00000000
-** 0x7f becomes 0x0000007f
-** 0x81 0x00 becomes 0x00000080
-** 0x82 0x00 becomes 0x00000100
-** 0x80 0x7f becomes 0x0000007f
-** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678
-** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081
-**
-** Variable length integers are used for rowids and to hold the number of
-** bytes of key and data in a btree cell.
-**
-** The content of a cell looks like this:
-**
-** SIZE DESCRIPTION
-** 4 Page number of the left child. Omitted if leaf flag is set.
-** var Number of bytes of data. Omitted if the zerodata flag is set.
-** var Number of bytes of key. Or the key itself if intkey flag is set.
-** * Payload
-** 4 First page of the overflow chain. Omitted if no overflow
-**
-** Overflow pages form a linked list. Each page except the last is completely
-** filled with data (pagesize - 4 bytes). The last page can have as little
-** as 1 byte of data.
-**
-** SIZE DESCRIPTION
-** 4 Page number of next overflow page
-** * Data
-**
-** Freelist pages come in two subtypes: trunk pages and leaf pages. The
-** file header points to the first in a linked list of trunk page. Each trunk
-** page points to multiple leaf pages. The content of a leaf page is
-** unspecified. A trunk page looks like this:
-**
-** SIZE DESCRIPTION
-** 4 Page number of next trunk page
-** 4 Number of leaf pointers on this page
-** * zero or more pages numbers of leaves
-*/
-
-
-/* The following value is the maximum cell size assuming a maximum page
-** size give above.
-*/
-#define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8))
-
-/* The maximum number of cells on a single page of the database. This
-** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself
-** plus 2 bytes for the index to the cell in the page header). Such
-** small cells will be rare, but they are possible.
-*/
-#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
-
-/* Forward declarations */
-typedef struct MemPage MemPage;
-typedef struct BtLock BtLock;
-
-/*
-** This is a magic string that appears at the beginning of every
-** SQLite database in order to identify the file as a real database.
-**
-** You can change this value at compile-time by specifying a
-** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The
-** header must be exactly 16 bytes including the zero-terminator so
-** the string itself should be 15 characters long. If you change
-** the header, then your custom library will not be able to read
-** databases generated by the standard tools and the standard tools
-** will not be able to read databases created by your custom library.
-*/
-#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */
-# define SQLITE_FILE_HEADER "SQLite format 3"
-#endif
-
-/*
-** Page type flags. An ORed combination of these flags appear as the
-** first byte of on-disk image of every BTree page.
-*/
-#define PTF_INTKEY 0x01
-#define PTF_ZERODATA 0x02
-#define PTF_LEAFDATA 0x04
-#define PTF_LEAF 0x08
-
-/*
-** As each page of the file is loaded into memory, an instance of the following
-** structure is appended and initialized to zero. This structure stores
-** information about the page that is decoded from the raw file page.
-**
-** The pParent field points back to the parent page. This allows us to
-** walk up the BTree from any leaf to the root. Care must be taken to
-** unref() the parent page pointer when this page is no longer referenced.
-** The pageDestructor() routine handles that chore.
-**
-** Access to all fields of this structure is controlled by the mutex
-** stored in MemPage.pBt->mutex.
-*/
-struct MemPage {
- u8 isInit; /* True if previously initialized. MUST BE FIRST! */
- u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
- u8 intKey; /* True if intkey flag is set */
- u8 leaf; /* True if leaf flag is set */
- u8 hasData; /* True if this page stores data */
- u8 hdrOffset; /* 100 for page 1. 0 otherwise */
- u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
- u8 max1bytePayload; /* min(maxLocal,127) */
- u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
- u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
- u16 cellOffset; /* Index in aData of first cell pointer */
- u16 nFree; /* Number of free bytes on the page */
- u16 nCell; /* Number of cells on this page, local and ovfl */
- u16 maskPage; /* Mask for page offset */
- u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th
- ** non-overflow cell */
- u8 *apOvfl[5]; /* Pointers to the body of overflow cells */
- BtShared *pBt; /* Pointer to BtShared that this page is part of */
- u8 *aData; /* Pointer to disk image of the page data */
- u8 *aDataEnd; /* One byte past the end of usable data */
- u8 *aCellIdx; /* The cell index area */
- DbPage *pDbPage; /* Pager page handle */
- Pgno pgno; /* Page number for this page */
-};
-
-/*
-** The in-memory image of a disk page has the auxiliary information appended
-** to the end. EXTRA_SIZE is the number of bytes of space needed to hold
-** that extra information.
-*/
-#define EXTRA_SIZE sizeof(MemPage)
-
-/*
-** A linked list of the following structures is stored at BtShared.pLock.
-** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor
-** is opened on the table with root page BtShared.iTable. Locks are removed
-** from this list when a transaction is committed or rolled back, or when
-** a btree handle is closed.
-*/
-struct BtLock {
- Btree *pBtree; /* Btree handle holding this lock */
- Pgno iTable; /* Root page of table */
- u8 eLock; /* READ_LOCK or WRITE_LOCK */
- BtLock *pNext; /* Next in BtShared.pLock list */
-};
-
-/* Candidate values for BtLock.eLock */
-#define READ_LOCK 1
-#define WRITE_LOCK 2
-
-/* A Btree handle
-**
-** A database connection contains a pointer to an instance of
-** this object for every database file that it has open. This structure
-** is opaque to the database connection. The database connection cannot
-** see the internals of this structure and only deals with pointers to
-** this structure.
-**
-** For some database files, the same underlying database cache might be
-** shared between multiple connections. In that case, each connection
-** has it own instance of this object. But each instance of this object
-** points to the same BtShared object. The database cache and the
-** schema associated with the database file are all contained within
-** the BtShared object.
-**
-** All fields in this structure are accessed under sqlite3.mutex.
-** The pBt pointer itself may not be changed while there exists cursors
-** in the referenced BtShared that point back to this Btree since those
-** cursors have to go through this Btree to find their BtShared and
-** they often do so without holding sqlite3.mutex.
-*/
-struct Btree {
- sqlite3 *db; /* The database connection holding this btree */
- BtShared *pBt; /* Sharable content of this btree */
- u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
- u8 sharable; /* True if we can share pBt with another db */
- u8 locked; /* True if db currently has pBt locked */
- int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
- int nBackup; /* Number of backup operations reading this btree */
- Btree *pNext; /* List of other sharable Btrees from the same db */
- Btree *pPrev; /* Back pointer of the same list */
-#ifndef SQLITE_OMIT_SHARED_CACHE
- BtLock lock; /* Object used to lock page 1 */
-#endif
-};
-
-/*
-** Btree.inTrans may take one of the following values.
-**
-** If the shared-data extension is enabled, there may be multiple users
-** of the Btree structure. At most one of these may open a write transaction,
-** but any number may have active read transactions.
-*/
-#define TRANS_NONE 0
-#define TRANS_READ 1
-#define TRANS_WRITE 2
-
-/*
-** An instance of this object represents a single database file.
-**
-** A single database file can be in use at the same time by two
-** or more database connections. When two or more connections are
-** sharing the same database file, each connection has it own
-** private Btree object for the file and each of those Btrees points
-** to this one BtShared object. BtShared.nRef is the number of
-** connections currently sharing this database file.
-**
-** Fields in this structure are accessed under the BtShared.mutex
-** mutex, except for nRef and pNext which are accessed under the
-** global SQLITE_MUTEX_STATIC_MASTER mutex. The pPager field
-** may not be modified once it is initially set as long as nRef>0.
-** The pSchema field may be set once under BtShared.mutex and
-** thereafter is unchanged as long as nRef>0.
-**
-** isPending:
-**
-** If a BtShared client fails to obtain a write-lock on a database
-** table (because there exists one or more read-locks on the table),
-** the shared-cache enters 'pending-lock' state and isPending is
-** set to true.
-**
-** The shared-cache leaves the 'pending lock' state when either of
-** the following occur:
-**
-** 1) The current writer (BtShared.pWriter) concludes its transaction, OR
-** 2) The number of locks held by other connections drops to zero.
-**
-** while in the 'pending-lock' state, no connection may start a new
-** transaction.
-**
-** This feature is included to help prevent writer-starvation.
-*/
-struct BtShared {
- Pager *pPager; /* The page cache */
- sqlite3 *db; /* Database connection currently using this Btree */
- BtCursor *pCursor; /* A list of all open cursors */
- MemPage *pPage1; /* First page of the database */
- u8 openFlags; /* Flags to sqlite3BtreeOpen() */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- u8 autoVacuum; /* True if auto-vacuum is enabled */
- u8 incrVacuum; /* True if incr-vacuum is enabled */
-#endif
- u8 inTransaction; /* Transaction state */
- u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
- u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
- u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
- u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
- u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */
- u16 minLeaf; /* Minimum local payload in a LEAFDATA table */
- u32 pageSize; /* Total number of bytes on a page */
- u32 usableSize; /* Number of usable bytes on each page */
- int nTransaction; /* Number of open transactions (read + write) */
- u32 nPage; /* Number of pages in the database */
- void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */
- void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */
- sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */
- Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */
-#ifndef SQLITE_OMIT_SHARED_CACHE
- int nRef; /* Number of references to this structure */
- BtShared *pNext; /* Next on a list of sharable BtShared structs */
- BtLock *pLock; /* List of locks held on this shared-btree struct */
- Btree *pWriter; /* Btree with currently open write transaction */
-#endif
- u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */
-};
-
-/*
-** Allowed values for BtShared.btsFlags
-*/
-#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */
-#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */
-#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */
-#define BTS_INITIALLY_EMPTY 0x0008 /* Database was empty at trans start */
-#define BTS_NO_WAL 0x0010 /* Do not open write-ahead-log files */
-#define BTS_EXCLUSIVE 0x0020 /* pWriter has an exclusive lock */
-#define BTS_PENDING 0x0040 /* Waiting for read-locks to clear */
-
-/*
-** An instance of the following structure is used to hold information
-** about a cell. The parseCellPtr() function fills in this structure
-** based on information extract from the raw disk page.
-*/
-typedef struct CellInfo CellInfo;
-struct CellInfo {
- i64 nKey; /* The key for INTKEY tables, or number of bytes in key */
- u8 *pCell; /* Pointer to the start of cell content */
- u32 nData; /* Number of bytes of data */
- u32 nPayload; /* Total amount of payload */
- u16 nHeader; /* Size of the cell content header in bytes */
- u16 nLocal; /* Amount of payload held locally */
- u16 iOverflow; /* Offset to overflow page number. Zero if no overflow */
- u16 nSize; /* Size of the cell content on the main b-tree page */
-};
-
-/*
-** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
-** this will be declared corrupt. This value is calculated based on a
-** maximum database size of 2^31 pages a minimum fanout of 2 for a
-** root-node and 3 for all other internal nodes.
-**
-** If a tree that appears to be taller than this is encountered, it is
-** assumed that the database is corrupt.
-*/
-#define BTCURSOR_MAX_DEPTH 20
-
-/*
-** A cursor is a pointer to a particular entry within a particular
-** b-tree within a database file.
-**
-** The entry is identified by its MemPage and the index in
-** MemPage.aCell[] of the entry.
-**
-** A single database file can be shared by two more database connections,
-** but cursors cannot be shared. Each cursor is associated with a
-** particular database connection identified BtCursor.pBtree.db.
-**
-** Fields in this structure are accessed under the BtShared.mutex
-** found at self->pBt->mutex.
-*/
-struct BtCursor {
- Btree *pBtree; /* The Btree to which this cursor belongs */
- BtShared *pBt; /* The BtShared this cursor points to */
- BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
- struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
-#ifndef SQLITE_OMIT_INCRBLOB
- Pgno *aOverflow; /* Cache of overflow page locations */
-#endif
- Pgno pgnoRoot; /* The root page of this tree */
- sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */
- CellInfo info; /* A parse of the cell we are pointing at */
- i64 nKey; /* Size of pKey, or last integer key */
- void *pKey; /* Saved key that was cursor's last known position */
- int skipNext; /* Prev() is noop if negative. Next() is noop if positive */
- u8 wrFlag; /* True if writable */
- u8 atLast; /* Cursor pointing to the last entry */
- u8 validNKey; /* True if info.nKey is valid */
- u8 eState; /* One of the CURSOR_XXX constants (see below) */
-#ifndef SQLITE_OMIT_INCRBLOB
- u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */
-#endif
- u8 hints; /* As configured by CursorSetHints() */
- i16 iPage; /* Index of current page in apPage */
- u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
- MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
-};
-
-/*
-** Potential values for BtCursor.eState.
-**
-** CURSOR_VALID:
-** Cursor points to a valid entry. getPayload() etc. may be called.
-**
-** CURSOR_INVALID:
-** Cursor does not point to a valid entry. This can happen (for example)
-** because the table is empty or because BtreeCursorFirst() has not been
-** called.
-**
-** CURSOR_REQUIRESEEK:
-** The table that this cursor was opened on still exists, but has been
-** modified since the cursor was last used. The cursor position is saved
-** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in
-** this state, restoreCursorPosition() can be called to attempt to
-** seek the cursor to the saved position.
-**
-** CURSOR_FAULT:
-** A unrecoverable error (an I/O error or a malloc failure) has occurred
-** on a different connection that shares the BtShared cache with this
-** cursor. The error has left the cache in an inconsistent state.
-** Do nothing else with this cursor. Any attempt to use the cursor
-** should return the error code stored in BtCursor.skip
-*/
-#define CURSOR_INVALID 0
-#define CURSOR_VALID 1
-#define CURSOR_REQUIRESEEK 2
-#define CURSOR_FAULT 3
-
-/*
-** The database page the PENDING_BYTE occupies. This page is never used.
-*/
-# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
-
-/*
-** These macros define the location of the pointer-map entry for a
-** database page. The first argument to each is the number of usable
-** bytes on each page of the database (often 1024). The second is the
-** page number to look up in the pointer map.
-**
-** PTRMAP_PAGENO returns the database page number of the pointer-map
-** page that stores the required pointer. PTRMAP_PTROFFSET returns
-** the offset of the requested map entry.
-**
-** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page,
-** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
-** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
-** this test.
-*/
-#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno)
-#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1))
-#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
-
-/*
-** The pointer map is a lookup table that identifies the parent page for
-** each child page in the database file. The parent page is the page that
-** contains a pointer to the child. Every page in the database contains
-** 0 or 1 parent pages. (In this context 'database page' refers
-** to any page that is not part of the pointer map itself.) Each pointer map
-** entry consists of a single byte 'type' and a 4 byte parent page number.
-** The PTRMAP_XXX identifiers below are the valid types.
-**
-** The purpose of the pointer map is to facility moving pages from one
-** position in the file to another as part of autovacuum. When a page
-** is moved, the pointer in its parent must be updated to point to the
-** new location. The pointer map is used to locate the parent page quickly.
-**
-** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
-** used in this case.
-**
-** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number
-** is not used in this case.
-**
-** PTRMAP_OVERFLOW1: The database page is the first page in a list of
-** overflow pages. The page number identifies the page that
-** contains the cell with a pointer to this overflow page.
-**
-** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of
-** overflow pages. The page-number identifies the previous
-** page in the overflow page list.
-**
-** PTRMAP_BTREE: The database page is a non-root btree page. The page number
-** identifies the parent page in the btree.
-*/
-#define PTRMAP_ROOTPAGE 1
-#define PTRMAP_FREEPAGE 2
-#define PTRMAP_OVERFLOW1 3
-#define PTRMAP_OVERFLOW2 4
-#define PTRMAP_BTREE 5
-
-/* A bunch of assert() statements to check the transaction state variables
-** of handle p (type Btree*) are internally consistent.
-*/
-#define btreeIntegrity(p) \
- assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \
- assert( p->pBt->inTransaction>=p->inTrans );
-
-
-/*
-** The ISAUTOVACUUM macro is used within balance_nonroot() to determine
-** if the database supports auto-vacuum or not. Because it is used
-** within an expression that is an argument to another macro
-** (sqliteMallocRaw), it is not possible to use conditional compilation.
-** So, this macro is defined instead.
-*/
-#ifndef SQLITE_OMIT_AUTOVACUUM
-#define ISAUTOVACUUM (pBt->autoVacuum)
-#else
-#define ISAUTOVACUUM 0
-#endif
-
-
-/*
-** This structure is passed around through all the sanity checking routines
-** in order to keep track of some global state information.
-**
-** The aRef[] array is allocated so that there is 1 bit for each page in
-** the database. As the integrity-check proceeds, for each page used in
-** the database the corresponding bit is set. This allows integrity-check to
-** detect pages that are used twice and orphaned pages (both of which
-** indicate corruption).
-*/
-typedef struct IntegrityCk IntegrityCk;
-struct IntegrityCk {
- BtShared *pBt; /* The tree being checked out */
- Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
- u8 *aPgRef; /* 1 bit per page in the db (see above) */
- Pgno nPage; /* Number of pages in the database */
- int mxErr; /* Stop accumulating errors when this reaches zero */
- int nErr; /* Number of messages written to zErrMsg so far */
- int mallocFailed; /* A memory allocation error has occurred */
- StrAccum errMsg; /* Accumulate the error message text here */
-};
-
-/*
-** Routines to read or write a two- and four-byte big-endian integer values.
-*/
-#define get2byte(x) ((x)[0]<<8 | (x)[1])
-#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
-#define get4byte sqlite3Get4byte
-#define put4byte sqlite3Put4byte
-
-/************** End of btreeInt.h ********************************************/
-/************** Continuing where we left off in btmutex.c ********************/
-#ifndef SQLITE_OMIT_SHARED_CACHE
-#if SQLITE_THREADSAFE
-
-/*
-** Obtain the BtShared mutex associated with B-Tree handle p. Also,
-** set BtShared.db to the database handle associated with p and the
-** p->locked boolean to true.
-*/
-static void lockBtreeMutex(Btree *p){
- assert( p->locked==0 );
- assert( sqlite3_mutex_notheld(p->pBt->mutex) );
- assert( sqlite3_mutex_held(p->db->mutex) );
-
- sqlite3_mutex_enter(p->pBt->mutex);
- p->pBt->db = p->db;
- p->locked = 1;
-}
-
-/*
-** Release the BtShared mutex associated with B-Tree handle p and
-** clear the p->locked boolean.
-*/
-static void unlockBtreeMutex(Btree *p){
- BtShared *pBt = p->pBt;
- assert( p->locked==1 );
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( sqlite3_mutex_held(p->db->mutex) );
- assert( p->db==pBt->db );
-
- sqlite3_mutex_leave(pBt->mutex);
- p->locked = 0;
-}
-
-/*
-** Enter a mutex on the given BTree object.
-**
-** If the object is not sharable, then no mutex is ever required
-** and this routine is a no-op. The underlying mutex is non-recursive.
-** But we keep a reference count in Btree.wantToLock so the behavior
-** of this interface is recursive.
-**
-** To avoid deadlocks, multiple Btrees are locked in the same order
-** by all database connections. The p->pNext is a list of other
-** Btrees belonging to the same database connection as the p Btree
-** which need to be locked after p. If we cannot get a lock on
-** p, then first unlock all of the others on p->pNext, then wait
-** for the lock to become available on p, then relock all of the
-** subsequent Btrees that desire a lock.
-*/
-SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
- Btree *pLater;
-
- /* Some basic sanity checking on the Btree. The list of Btrees
- ** connected by pNext and pPrev should be in sorted order by
- ** Btree.pBt value. All elements of the list should belong to
- ** the same connection. Only shared Btrees are on the list. */
- assert( p->pNext==0 || p->pNext->pBt>p->pBt );
- assert( p->pPrev==0 || p->pPrev->pBt<p->pBt );
- assert( p->pNext==0 || p->pNext->db==p->db );
- assert( p->pPrev==0 || p->pPrev->db==p->db );
- assert( p->sharable || (p->pNext==0 && p->pPrev==0) );
-
- /* Check for locking consistency */
- assert( !p->locked || p->wantToLock>0 );
- assert( p->sharable || p->wantToLock==0 );
-
- /* We should already hold a lock on the database connection */
- assert( sqlite3_mutex_held(p->db->mutex) );
-
- /* Unless the database is sharable and unlocked, then BtShared.db
- ** should already be set correctly. */
- assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db );
-
- if( !p->sharable ) return;
- p->wantToLock++;
- if( p->locked ) return;
-
- /* In most cases, we should be able to acquire the lock we
- ** want without having to go throught the ascending lock
- ** procedure that follows. Just be sure not to block.
- */
- if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){
- p->pBt->db = p->db;
- p->locked = 1;
- return;
- }
-
- /* To avoid deadlock, first release all locks with a larger
- ** BtShared address. Then acquire our lock. Then reacquire
- ** the other BtShared locks that we used to hold in ascending
- ** order.
- */
- for(pLater=p->pNext; pLater; pLater=pLater->pNext){
- assert( pLater->sharable );
- assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt );
- assert( !pLater->locked || pLater->wantToLock>0 );
- if( pLater->locked ){
- unlockBtreeMutex(pLater);
- }
- }
- lockBtreeMutex(p);
- for(pLater=p->pNext; pLater; pLater=pLater->pNext){
- if( pLater->wantToLock ){
- lockBtreeMutex(pLater);
- }
- }
-}
-
-/*
-** Exit the recursive mutex on a Btree.
-*/
-SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){
- if( p->sharable ){
- assert( p->wantToLock>0 );
- p->wantToLock--;
- if( p->wantToLock==0 ){
- unlockBtreeMutex(p);
- }
- }
-}
-
-#ifndef NDEBUG
-/*
-** Return true if the BtShared mutex is held on the btree, or if the
-** B-Tree is not marked as sharable.
-**
-** This routine is used only from within assert() statements.
-*/
-SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){
- assert( p->sharable==0 || p->locked==0 || p->wantToLock>0 );
- assert( p->sharable==0 || p->locked==0 || p->db==p->pBt->db );
- assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) );
- assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) );
-
- return (p->sharable==0 || p->locked);
-}
-#endif
-
-
-#ifndef SQLITE_OMIT_INCRBLOB
-/*
-** Enter and leave a mutex on a Btree given a cursor owned by that
-** Btree. These entry points are used by incremental I/O and can be
-** omitted if that module is not used.
-*/
-SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){
- sqlite3BtreeEnter(pCur->pBtree);
-}
-SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){
- sqlite3BtreeLeave(pCur->pBtree);
-}
-#endif /* SQLITE_OMIT_INCRBLOB */
-
-
-/*
-** Enter the mutex on every Btree associated with a database
-** connection. This is needed (for example) prior to parsing
-** a statement since we will be comparing table and column names
-** against all schemas and we do not want those schemas being
-** reset out from under us.
-**
-** There is a corresponding leave-all procedures.
-**
-** Enter the mutexes in accending order by BtShared pointer address
-** to avoid the possibility of deadlock when two threads with
-** two or more btrees in common both try to lock all their btrees
-** at the same instant.
-*/
-SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
- int i;
- Btree *p;
- assert( sqlite3_mutex_held(db->mutex) );
- for(i=0; i<db->nDb; i++){
- p = db->aDb[i].pBt;
- if( p ) sqlite3BtreeEnter(p);
- }
-}
-SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
- int i;
- Btree *p;
- assert( sqlite3_mutex_held(db->mutex) );
- for(i=0; i<db->nDb; i++){
- p = db->aDb[i].pBt;
- if( p ) sqlite3BtreeLeave(p);
- }
-}
-
-/*
-** Return true if a particular Btree requires a lock. Return FALSE if
-** no lock is ever required since it is not sharable.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){
- return p->sharable;
-}
-
-#ifndef NDEBUG
-/*
-** Return true if the current thread holds the database connection
-** mutex and all required BtShared mutexes.
-**
-** This routine is used inside assert() statements only.
-*/
-SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){
- int i;
- if( !sqlite3_mutex_held(db->mutex) ){
- return 0;
- }
- for(i=0; i<db->nDb; i++){
- Btree *p;
- p = db->aDb[i].pBt;
- if( p && p->sharable &&
- (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){
- return 0;
- }
- }
- return 1;
-}
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/*
-** Return true if the correct mutexes are held for accessing the
-** db->aDb[iDb].pSchema structure. The mutexes required for schema
-** access are:
-**
-** (1) The mutex on db
-** (2) if iDb!=1, then the mutex on db->aDb[iDb].pBt.
-**
-** If pSchema is not NULL, then iDb is computed from pSchema and
-** db using sqlite3SchemaToIndex().
-*/
-SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){
- Btree *p;
- assert( db!=0 );
- if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema);
- assert( iDb>=0 && iDb<db->nDb );
- if( !sqlite3_mutex_held(db->mutex) ) return 0;
- if( iDb==1 ) return 1;
- p = db->aDb[iDb].pBt;
- assert( p!=0 );
- return p->sharable==0 || p->locked==1;
-}
-#endif /* NDEBUG */
-
-#else /* SQLITE_THREADSAFE>0 above. SQLITE_THREADSAFE==0 below */
-/*
-** The following are special cases for mutex enter routines for use
-** in single threaded applications that use shared cache. Except for
-** these two routines, all mutex operations are no-ops in that case and
-** are null #defines in btree.h.
-**
-** If shared cache is disabled, then all btree mutex routines, including
-** the ones below, are no-ops and are null #defines in btree.h.
-*/
-
-SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
- p->pBt->db = p->db;
-}
-SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
- int i;
- for(i=0; i<db->nDb; i++){
- Btree *p = db->aDb[i].pBt;
- if( p ){
- p->pBt->db = p->db;
- }
- }
-}
-#endif /* if SQLITE_THREADSAFE */
-#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
-
-/************** End of btmutex.c *********************************************/
-/************** Begin file btree.c *******************************************/
-/*
-** 2004 April 6
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file implements a external (disk-based) database using BTrees.
-** See the header comment on "btreeInt.h" for additional information.
-** Including a description of file format and an overview of operation.
-*/
-
-/*
-** The header string that appears at the beginning of every
-** SQLite database.
-*/
-static const char zMagicHeader[] = SQLITE_FILE_HEADER;
-
-/*
-** Set this global variable to 1 to enable tracing using the TRACE
-** macro.
-*/
-#if 0
-int sqlite3BtreeTrace=1; /* True to enable tracing */
-# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);}
-#else
-# define TRACE(X)
-#endif
-
-/*
-** Extract a 2-byte big-endian integer from an array of unsigned bytes.
-** But if the value is zero, make it 65536.
-**
-** This routine is used to extract the "offset to cell content area" value
-** from the header of a btree page. If the page size is 65536 and the page
-** is empty, the offset should be 65536, but the 2-byte value stores zero.
-** This routine makes the necessary adjustment to 65536.
-*/
-#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1)
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** A list of BtShared objects that are eligible for participation
-** in shared cache. This variable has file scope during normal builds,
-** but the test harness needs to access it so we make it global for
-** test builds.
-**
-** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER.
-*/
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
-#else
-static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
-#endif
-#endif /* SQLITE_OMIT_SHARED_CACHE */
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** Enable or disable the shared pager and schema features.
-**
-** This routine has no effect on existing database connections.
-** The shared cache setting effects only future calls to
-** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
-*/
-SQLITE_API int sqlite3_enable_shared_cache(int enable){
- sqlite3GlobalConfig.sharedCacheEnabled = enable;
- return SQLITE_OK;
-}
-#endif
-
-
-
-#ifdef SQLITE_OMIT_SHARED_CACHE
- /*
- ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(),
- ** and clearAllSharedCacheTableLocks()
- ** manipulate entries in the BtShared.pLock linked list used to store
- ** shared-cache table level locks. If the library is compiled with the
- ** shared-cache feature disabled, then there is only ever one user
- ** of each BtShared structure and so this locking is not necessary.
- ** So define the lock related functions as no-ops.
- */
- #define querySharedCacheTableLock(a,b,c) SQLITE_OK
- #define setSharedCacheTableLock(a,b,c) SQLITE_OK
- #define clearAllSharedCacheTableLocks(a)
- #define downgradeAllSharedCacheTableLocks(a)
- #define hasSharedCacheTableLock(a,b,c,d) 1
- #define hasReadConflicts(a, b) 0
-#endif
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-
-#ifdef SQLITE_DEBUG
-/*
-**** This function is only used as part of an assert() statement. ***
-**
-** Check to see if pBtree holds the required locks to read or write to the
-** table with root page iRoot. Return 1 if it does and 0 if not.
-**
-** For example, when writing to a table with root-page iRoot via
-** Btree connection pBtree:
-**
-** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) );
-**
-** When writing to an index that resides in a sharable database, the
-** caller should have first obtained a lock specifying the root page of
-** the corresponding table. This makes things a bit more complicated,
-** as this module treats each table as a separate structure. To determine
-** the table corresponding to the index being written, this
-** function has to search through the database schema.
-**
-** Instead of a lock on the table/index rooted at page iRoot, the caller may
-** hold a write-lock on the schema table (root page 1). This is also
-** acceptable.
-*/
-static int hasSharedCacheTableLock(
- Btree *pBtree, /* Handle that must hold lock */
- Pgno iRoot, /* Root page of b-tree */
- int isIndex, /* True if iRoot is the root of an index b-tree */
- int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */
-){
- Schema *pSchema = (Schema *)pBtree->pBt->pSchema;
- Pgno iTab = 0;
- BtLock *pLock;
-
- /* If this database is not shareable, or if the client is reading
- ** and has the read-uncommitted flag set, then no lock is required.
- ** Return true immediately.
- */
- if( (pBtree->sharable==0)
- || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted))
- ){
- return 1;
- }
-
- /* If the client is reading or writing an index and the schema is
- ** not loaded, then it is too difficult to actually check to see if
- ** the correct locks are held. So do not bother - just return true.
- ** This case does not come up very often anyhow.
- */
- if( isIndex && (!pSchema || (pSchema->flags&DB_SchemaLoaded)==0) ){
- return 1;
- }
-
- /* Figure out the root-page that the lock should be held on. For table
- ** b-trees, this is just the root page of the b-tree being read or
- ** written. For index b-trees, it is the root page of the associated
- ** table. */
- if( isIndex ){
- HashElem *p;
- for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
- Index *pIdx = (Index *)sqliteHashData(p);
- if( pIdx->tnum==(int)iRoot ){
- iTab = pIdx->pTable->tnum;
- }
- }
- }else{
- iTab = iRoot;
- }
-
- /* Search for the required lock. Either a write-lock on root-page iTab, a
- ** write-lock on the schema table, or (if the client is reading) a
- ** read-lock on iTab will suffice. Return 1 if any of these are found. */
- for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){
- if( pLock->pBtree==pBtree
- && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1))
- && pLock->eLock>=eLockType
- ){
- return 1;
- }
- }
-
- /* Failed to find the required lock. */
- return 0;
-}
-#endif /* SQLITE_DEBUG */
-
-#ifdef SQLITE_DEBUG
-/*
-**** This function may be used as part of assert() statements only. ****
-**
-** Return true if it would be illegal for pBtree to write into the
-** table or index rooted at iRoot because other shared connections are
-** simultaneously reading that same table or index.
-**
-** It is illegal for pBtree to write if some other Btree object that
-** shares the same BtShared object is currently reading or writing
-** the iRoot table. Except, if the other Btree object has the
-** read-uncommitted flag set, then it is OK for the other object to
-** have a read cursor.
-**
-** For example, before writing to any part of the table or index
-** rooted at page iRoot, one should call:
-**
-** assert( !hasReadConflicts(pBtree, iRoot) );
-*/
-static int hasReadConflicts(Btree *pBtree, Pgno iRoot){
- BtCursor *p;
- for(p=pBtree->pBt->pCursor; p; p=p->pNext){
- if( p->pgnoRoot==iRoot
- && p->pBtree!=pBtree
- && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted)
- ){
- return 1;
- }
- }
- return 0;
-}
-#endif /* #ifdef SQLITE_DEBUG */
-
-/*
-** Query to see if Btree handle p may obtain a lock of type eLock
-** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
-** SQLITE_OK if the lock may be obtained (by calling
-** setSharedCacheTableLock()), or SQLITE_LOCKED if not.
-*/
-static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
- BtShared *pBt = p->pBt;
- BtLock *pIter;
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
- assert( p->db!=0 );
- assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 );
-
- /* If requesting a write-lock, then the Btree must have an open write
- ** transaction on this file. And, obviously, for this to be so there
- ** must be an open write transaction on the file itself.
- */
- assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) );
- assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE );
-
- /* This routine is a no-op if the shared-cache is not enabled */
- if( !p->sharable ){
- return SQLITE_OK;
- }
-
- /* If some other connection is holding an exclusive lock, the
- ** requested lock may not be obtained.
- */
- if( pBt->pWriter!=p && (pBt->btsFlags & BTS_EXCLUSIVE)!=0 ){
- sqlite3ConnectionBlocked(p->db, pBt->pWriter->db);
- return SQLITE_LOCKED_SHAREDCACHE;
- }
-
- for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
- /* The condition (pIter->eLock!=eLock) in the following if(...)
- ** statement is a simplification of:
- **
- ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK)
- **
- ** since we know that if eLock==WRITE_LOCK, then no other connection
- ** may hold a WRITE_LOCK on any table in this file (since there can
- ** only be a single writer).
- */
- assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK );
- assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK);
- if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){
- sqlite3ConnectionBlocked(p->db, pIter->pBtree->db);
- if( eLock==WRITE_LOCK ){
- assert( p==pBt->pWriter );
- pBt->btsFlags |= BTS_PENDING;
- }
- return SQLITE_LOCKED_SHAREDCACHE;
- }
- }
- return SQLITE_OK;
-}
-#endif /* !SQLITE_OMIT_SHARED_CACHE */
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** Add a lock on the table with root-page iTable to the shared-btree used
-** by Btree handle p. Parameter eLock must be either READ_LOCK or
-** WRITE_LOCK.
-**
-** This function assumes the following:
-**
-** (a) The specified Btree object p is connected to a sharable
-** database (one with the BtShared.sharable flag set), and
-**
-** (b) No other Btree objects hold a lock that conflicts
-** with the requested lock (i.e. querySharedCacheTableLock() has
-** already been called and returned SQLITE_OK).
-**
-** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM
-** is returned if a malloc attempt fails.
-*/
-static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
- BtShared *pBt = p->pBt;
- BtLock *pLock = 0;
- BtLock *pIter;
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
- assert( p->db!=0 );
-
- /* A connection with the read-uncommitted flag set will never try to
- ** obtain a read-lock using this function. The only read-lock obtained
- ** by a connection in read-uncommitted mode is on the sqlite_master
- ** table, and that lock is obtained in BtreeBeginTrans(). */
- assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK );
-
- /* This function should only be called on a sharable b-tree after it
- ** has been determined that no other b-tree holds a conflicting lock. */
- assert( p->sharable );
- assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) );
-
- /* First search the list for an existing lock on this table. */
- for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
- if( pIter->iTable==iTable && pIter->pBtree==p ){
- pLock = pIter;
- break;
- }
- }
-
- /* If the above search did not find a BtLock struct associating Btree p
- ** with table iTable, allocate one and link it into the list.
- */
- if( !pLock ){
- pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
- if( !pLock ){
- return SQLITE_NOMEM;
- }
- pLock->iTable = iTable;
- pLock->pBtree = p;
- pLock->pNext = pBt->pLock;
- pBt->pLock = pLock;
- }
-
- /* Set the BtLock.eLock variable to the maximum of the current lock
- ** and the requested lock. This means if a write-lock was already held
- ** and a read-lock requested, we don't incorrectly downgrade the lock.
- */
- assert( WRITE_LOCK>READ_LOCK );
- if( eLock>pLock->eLock ){
- pLock->eLock = eLock;
- }
-
- return SQLITE_OK;
-}
-#endif /* !SQLITE_OMIT_SHARED_CACHE */
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** Release all the table locks (locks obtained via calls to
-** the setSharedCacheTableLock() procedure) held by Btree object p.
-**
-** This function assumes that Btree p has an open read or write
-** transaction. If it does not, then the BTS_PENDING flag
-** may be incorrectly cleared.
-*/
-static void clearAllSharedCacheTableLocks(Btree *p){
- BtShared *pBt = p->pBt;
- BtLock **ppIter = &pBt->pLock;
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( p->sharable || 0==*ppIter );
- assert( p->inTrans>0 );
-
- while( *ppIter ){
- BtLock *pLock = *ppIter;
- assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree );
- assert( pLock->pBtree->inTrans>=pLock->eLock );
- if( pLock->pBtree==p ){
- *ppIter = pLock->pNext;
- assert( pLock->iTable!=1 || pLock==&p->lock );
- if( pLock->iTable!=1 ){
- sqlite3_free(pLock);
- }
- }else{
- ppIter = &pLock->pNext;
- }
- }
-
- assert( (pBt->btsFlags & BTS_PENDING)==0 || pBt->pWriter );
- if( pBt->pWriter==p ){
- pBt->pWriter = 0;
- pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING);
- }else if( pBt->nTransaction==2 ){
- /* This function is called when Btree p is concluding its
- ** transaction. If there currently exists a writer, and p is not
- ** that writer, then the number of locks held by connections other
- ** than the writer must be about to drop to zero. In this case
- ** set the BTS_PENDING flag to 0.
- **
- ** If there is not currently a writer, then BTS_PENDING must
- ** be zero already. So this next line is harmless in that case.
- */
- pBt->btsFlags &= ~BTS_PENDING;
- }
-}
-
-/*
-** This function changes all write-locks held by Btree p into read-locks.
-*/
-static void downgradeAllSharedCacheTableLocks(Btree *p){
- BtShared *pBt = p->pBt;
- if( pBt->pWriter==p ){
- BtLock *pLock;
- pBt->pWriter = 0;
- pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING);
- for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){
- assert( pLock->eLock==READ_LOCK || pLock->pBtree==p );
- pLock->eLock = READ_LOCK;
- }
- }
-}
-
-#endif /* SQLITE_OMIT_SHARED_CACHE */
-
-static void releasePage(MemPage *pPage); /* Forward reference */
-
-/*
-***** This routine is used inside of assert() only ****
-**
-** Verify that the cursor holds the mutex on its BtShared
-*/
-#ifdef SQLITE_DEBUG
-static int cursorHoldsMutex(BtCursor *p){
- return sqlite3_mutex_held(p->pBt->mutex);
-}
-#endif
-
-
-#ifndef SQLITE_OMIT_INCRBLOB
-/*
-** Invalidate the overflow page-list cache for cursor pCur, if any.
-*/
-static void invalidateOverflowCache(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- sqlite3_free(pCur->aOverflow);
- pCur->aOverflow = 0;
-}
-
-/*
-** Invalidate the overflow page-list cache for all cursors opened
-** on the shared btree structure pBt.
-*/
-static void invalidateAllOverflowCache(BtShared *pBt){
- BtCursor *p;
- assert( sqlite3_mutex_held(pBt->mutex) );
- for(p=pBt->pCursor; p; p=p->pNext){
- invalidateOverflowCache(p);
- }
-}
-
-/*
-** This function is called before modifying the contents of a table
-** to invalidate any incrblob cursors that are open on the
-** row or one of the rows being modified.
-**
-** If argument isClearTable is true, then the entire contents of the
-** table is about to be deleted. In this case invalidate all incrblob
-** cursors open on any row within the table with root-page pgnoRoot.
-**
-** Otherwise, if argument isClearTable is false, then the row with
-** rowid iRow is being replaced or deleted. In this case invalidate
-** only those incrblob cursors open on that specific row.
-*/
-static void invalidateIncrblobCursors(
- Btree *pBtree, /* The database file to check */
- i64 iRow, /* The rowid that might be changing */
- int isClearTable /* True if all rows are being deleted */
-){
- BtCursor *p;
- BtShared *pBt = pBtree->pBt;
- assert( sqlite3BtreeHoldsMutex(pBtree) );
- for(p=pBt->pCursor; p; p=p->pNext){
- if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){
- p->eState = CURSOR_INVALID;
- }
- }
-}
-
-#else
- /* Stub functions when INCRBLOB is omitted */
- #define invalidateOverflowCache(x)
- #define invalidateAllOverflowCache(x)
- #define invalidateIncrblobCursors(x,y,z)
-#endif /* SQLITE_OMIT_INCRBLOB */
-
-/*
-** Set bit pgno of the BtShared.pHasContent bitvec. This is called
-** when a page that previously contained data becomes a free-list leaf
-** page.
-**
-** The BtShared.pHasContent bitvec exists to work around an obscure
-** bug caused by the interaction of two useful IO optimizations surrounding
-** free-list leaf pages:
-**
-** 1) When all data is deleted from a page and the page becomes
-** a free-list leaf page, the page is not written to the database
-** (as free-list leaf pages contain no meaningful data). Sometimes
-** such a page is not even journalled (as it will not be modified,
-** why bother journalling it?).
-**
-** 2) When a free-list leaf page is reused, its content is not read
-** from the database or written to the journal file (why should it
-** be, if it is not at all meaningful?).
-**
-** By themselves, these optimizations work fine and provide a handy
-** performance boost to bulk delete or insert operations. However, if
-** a page is moved to the free-list and then reused within the same
-** transaction, a problem comes up. If the page is not journalled when
-** it is moved to the free-list and it is also not journalled when it
-** is extracted from the free-list and reused, then the original data
-** may be lost. In the event of a rollback, it may not be possible
-** to restore the database to its original configuration.
-**
-** The solution is the BtShared.pHasContent bitvec. Whenever a page is
-** moved to become a free-list leaf page, the corresponding bit is
-** set in the bitvec. Whenever a leaf page is extracted from the free-list,
-** optimization 2 above is omitted if the corresponding bit is already
-** set in BtShared.pHasContent. The contents of the bitvec are cleared
-** at the end of every transaction.
-*/
-static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
- int rc = SQLITE_OK;
- if( !pBt->pHasContent ){
- assert( pgno<=pBt->nPage );
- pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage);
- if( !pBt->pHasContent ){
- rc = SQLITE_NOMEM;
- }
- }
- if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
- rc = sqlite3BitvecSet(pBt->pHasContent, pgno);
- }
- return rc;
-}
-
-/*
-** Query the BtShared.pHasContent vector.
-**
-** This function is called when a free-list leaf page is removed from the
-** free-list for reuse. It returns false if it is safe to retrieve the
-** page from the pager layer with the 'no-content' flag set. True otherwise.
-*/
-static int btreeGetHasContent(BtShared *pBt, Pgno pgno){
- Bitvec *p = pBt->pHasContent;
- return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno)));
-}
-
-/*
-** Clear (destroy) the BtShared.pHasContent bitvec. This should be
-** invoked at the conclusion of each write-transaction.
-*/
-static void btreeClearHasContent(BtShared *pBt){
- sqlite3BitvecDestroy(pBt->pHasContent);
- pBt->pHasContent = 0;
-}
-
-/*
-** Save the current cursor position in the variables BtCursor.nKey
-** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
-**
-** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID)
-** prior to calling this routine.
-*/
-static int saveCursorPosition(BtCursor *pCur){
- int rc;
-
- assert( CURSOR_VALID==pCur->eState );
- assert( 0==pCur->pKey );
- assert( cursorHoldsMutex(pCur) );
-
- rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
- assert( rc==SQLITE_OK ); /* KeySize() cannot fail */
-
- /* If this is an intKey table, then the above call to BtreeKeySize()
- ** stores the integer key in pCur->nKey. In this case this value is
- ** all that is required. Otherwise, if pCur is not open on an intKey
- ** table, then malloc space for and store the pCur->nKey bytes of key
- ** data.
- */
- if( 0==pCur->apPage[0]->intKey ){
- void *pKey = sqlite3Malloc( (int)pCur->nKey );
- if( pKey ){
- rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
- if( rc==SQLITE_OK ){
- pCur->pKey = pKey;
- }else{
- sqlite3_free(pKey);
- }
- }else{
- rc = SQLITE_NOMEM;
- }
- }
- assert( !pCur->apPage[0]->intKey || !pCur->pKey );
-
- if( rc==SQLITE_OK ){
- int i;
- for(i=0; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- pCur->apPage[i] = 0;
- }
- pCur->iPage = -1;
- pCur->eState = CURSOR_REQUIRESEEK;
- }
-
- invalidateOverflowCache(pCur);
- return rc;
-}
-
-/*
-** Save the positions of all cursors (except pExcept) that are open on
-** the table with root-page iRoot. Usually, this is called just before cursor
-** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
-*/
-static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
- BtCursor *p;
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pExcept==0 || pExcept->pBt==pBt );
- for(p=pBt->pCursor; p; p=p->pNext){
- if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) &&
- p->eState==CURSOR_VALID ){
- int rc = saveCursorPosition(p);
- if( SQLITE_OK!=rc ){
- return rc;
- }
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** Clear the current cursor position.
-*/
-SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- sqlite3_free(pCur->pKey);
- pCur->pKey = 0;
- pCur->eState = CURSOR_INVALID;
-}
-
-/*
-** In this version of BtreeMoveto, pKey is a packed index record
-** such as is generated by the OP_MakeRecord opcode. Unpack the
-** record and then call BtreeMovetoUnpacked() to do the work.
-*/
-static int btreeMoveto(
- BtCursor *pCur, /* Cursor open on the btree to be searched */
- const void *pKey, /* Packed key if the btree is an index */
- i64 nKey, /* Integer key for tables. Size of pKey for indices */
- int bias, /* Bias search to the high end */
- int *pRes /* Write search results here */
-){
- int rc; /* Status code */
- UnpackedRecord *pIdxKey; /* Unpacked index key */
- char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */
- char *pFree = 0;
-
- if( pKey ){
- assert( nKey==(i64)(int)nKey );
- pIdxKey = sqlite3VdbeAllocUnpackedRecord(
- pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree
- );
- if( pIdxKey==0 ) return SQLITE_NOMEM;
- sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
- }else{
- pIdxKey = 0;
- }
- rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes);
- if( pFree ){
- sqlite3DbFree(pCur->pKeyInfo->db, pFree);
- }
- return rc;
-}
-
-/*
-** Restore the cursor to the position it was in (or as close to as possible)
-** when saveCursorPosition() was called. Note that this call deletes the
-** saved position info stored by saveCursorPosition(), so there can be
-** at most one effective restoreCursorPosition() call after each
-** saveCursorPosition().
-*/
-static int btreeRestoreCursorPosition(BtCursor *pCur){
- int rc;
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState>=CURSOR_REQUIRESEEK );
- if( pCur->eState==CURSOR_FAULT ){
- return pCur->skipNext;
- }
- pCur->eState = CURSOR_INVALID;
- rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext);
- if( rc==SQLITE_OK ){
- sqlite3_free(pCur->pKey);
- pCur->pKey = 0;
- assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
- }
- return rc;
-}
-
-#define restoreCursorPosition(p) \
- (p->eState>=CURSOR_REQUIRESEEK ? \
- btreeRestoreCursorPosition(p) : \
- SQLITE_OK)
-
-/*
-** Determine whether or not a cursor has moved from the position it
-** was last placed at. Cursors can move when the row they are pointing
-** at is deleted out from under them.
-**
-** This routine returns an error code if something goes wrong. The
-** integer *pHasMoved is set to one if the cursor has moved and 0 if not.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
- int rc;
-
- rc = restoreCursorPosition(pCur);
- if( rc ){
- *pHasMoved = 1;
- return rc;
- }
- if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){
- *pHasMoved = 1;
- }else{
- *pHasMoved = 0;
- }
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** Given a page number of a regular database page, return the page
-** number for the pointer-map page that contains the entry for the
-** input page number.
-**
-** Return 0 (not a valid page) for pgno==1 since there is
-** no pointer map associated with page 1. The integrity_check logic
-** requires that ptrmapPageno(*,1)!=1.
-*/
-static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
- int nPagesPerMapPage;
- Pgno iPtrMap, ret;
- assert( sqlite3_mutex_held(pBt->mutex) );
- if( pgno<2 ) return 0;
- nPagesPerMapPage = (pBt->usableSize/5)+1;
- iPtrMap = (pgno-2)/nPagesPerMapPage;
- ret = (iPtrMap*nPagesPerMapPage) + 2;
- if( ret==PENDING_BYTE_PAGE(pBt) ){
- ret++;
- }
- return ret;
-}
-
-/*
-** Write an entry into the pointer map.
-**
-** This routine updates the pointer map entry for page number 'key'
-** so that it maps to type 'eType' and parent page number 'pgno'.
-**
-** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is
-** a no-op. If an error occurs, the appropriate error code is written
-** into *pRC.
-*/
-static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
- DbPage *pDbPage; /* The pointer map page */
- u8 *pPtrmap; /* The pointer map data */
- Pgno iPtrmap; /* The pointer map page number */
- int offset; /* Offset in pointer map page */
- int rc; /* Return code from subfunctions */
-
- if( *pRC ) return;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- /* The master-journal page number must never be used as a pointer map page */
- assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) );
-
- assert( pBt->autoVacuum );
- if( key==0 ){
- *pRC = SQLITE_CORRUPT_BKPT;
- return;
- }
- iPtrmap = PTRMAP_PAGENO(pBt, key);
- rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
- if( rc!=SQLITE_OK ){
- *pRC = rc;
- return;
- }
- offset = PTRMAP_PTROFFSET(iPtrmap, key);
- if( offset<0 ){
- *pRC = SQLITE_CORRUPT_BKPT;
- goto ptrmap_exit;
- }
- assert( offset <= (int)pBt->usableSize-5 );
- pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
-
- if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
- TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
- *pRC= rc = sqlite3PagerWrite(pDbPage);
- if( rc==SQLITE_OK ){
- pPtrmap[offset] = eType;
- put4byte(&pPtrmap[offset+1], parent);
- }
- }
-
-ptrmap_exit:
- sqlite3PagerUnref(pDbPage);
-}
-
-/*
-** Read an entry from the pointer map.
-**
-** This routine retrieves the pointer map entry for page 'key', writing
-** the type and parent page number to *pEType and *pPgno respectively.
-** An error code is returned if something goes wrong, otherwise SQLITE_OK.
-*/
-static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
- DbPage *pDbPage; /* The pointer map page */
- int iPtrmap; /* Pointer map page index */
- u8 *pPtrmap; /* Pointer map page data */
- int offset; /* Offset of entry in pointer map */
- int rc;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
-
- iPtrmap = PTRMAP_PAGENO(pBt, key);
- rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage);
- if( rc!=0 ){
- return rc;
- }
- pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
-
- offset = PTRMAP_PTROFFSET(iPtrmap, key);
- if( offset<0 ){
- sqlite3PagerUnref(pDbPage);
- return SQLITE_CORRUPT_BKPT;
- }
- assert( offset <= (int)pBt->usableSize-5 );
- assert( pEType!=0 );
- *pEType = pPtrmap[offset];
- if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]);
-
- sqlite3PagerUnref(pDbPage);
- if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_BKPT;
- return SQLITE_OK;
-}
-
-#else /* if defined SQLITE_OMIT_AUTOVACUUM */
- #define ptrmapPut(w,x,y,z,rc)
- #define ptrmapGet(w,x,y,z) SQLITE_OK
- #define ptrmapPutOvflPtr(x, y, rc)
-#endif
-
-/*
-** Given a btree page and a cell index (0 means the first cell on
-** the page, 1 means the second cell, and so forth) return a pointer
-** to the cell content.
-**
-** This routine works only for pages that do not contain overflow cells.
-*/
-#define findCell(P,I) \
- ((P)->aData + ((P)->maskPage & get2byte(&(P)->aCellIdx[2*(I)])))
-#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I)))))
-
-
-/*
-** This a more complex version of findCell() that works for
-** pages that do contain overflow cells.
-*/
-static u8 *findOverflowCell(MemPage *pPage, int iCell){
- int i;
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- for(i=pPage->nOverflow-1; i>=0; i--){
- int k;
- k = pPage->aiOvfl[i];
- if( k<=iCell ){
- if( k==iCell ){
- return pPage->apOvfl[i];
- }
- iCell--;
- }
- }
- return findCell(pPage, iCell);
-}
-
-/*
-** Parse a cell content block and fill in the CellInfo structure. There
-** are two versions of this function. btreeParseCell() takes a
-** cell index as the second argument and btreeParseCellPtr()
-** takes a pointer to the body of the cell as its second argument.
-**
-** Within this file, the parseCell() macro can be called instead of
-** btreeParseCellPtr(). Using some compilers, this will be faster.
-*/
-static void btreeParseCellPtr(
- MemPage *pPage, /* Page containing the cell */
- u8 *pCell, /* Pointer to the cell text. */
- CellInfo *pInfo /* Fill in this structure */
-){
- u16 n; /* Number bytes in cell content header */
- u32 nPayload; /* Number of bytes of cell payload */
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-
- pInfo->pCell = pCell;
- assert( pPage->leaf==0 || pPage->leaf==1 );
- n = pPage->childPtrSize;
- assert( n==4-4*pPage->leaf );
- if( pPage->intKey ){
- if( pPage->hasData ){
- n += getVarint32(&pCell[n], nPayload);
- }else{
- nPayload = 0;
- }
- n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
- pInfo->nData = nPayload;
- }else{
- pInfo->nData = 0;
- n += getVarint32(&pCell[n], nPayload);
- pInfo->nKey = nPayload;
- }
- pInfo->nPayload = nPayload;
- pInfo->nHeader = n;
- testcase( nPayload==pPage->maxLocal );
- testcase( nPayload==pPage->maxLocal+1 );
- if( likely(nPayload<=pPage->maxLocal) ){
- /* This is the (easy) common case where the entire payload fits
- ** on the local page. No overflow is required.
- */
- if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4;
- pInfo->nLocal = (u16)nPayload;
- pInfo->iOverflow = 0;
- }else{
- /* If the payload will not fit completely on the local page, we have
- ** to decide how much to store locally and how much to spill onto
- ** overflow pages. The strategy is to minimize the amount of unused
- ** space on overflow pages while keeping the amount of local storage
- ** in between minLocal and maxLocal.
- **
- ** Warning: changing the way overflow payload is distributed in any
- ** way will result in an incompatible file format.
- */
- int minLocal; /* Minimum amount of payload held locally */
- int maxLocal; /* Maximum amount of payload held locally */
- int surplus; /* Overflow payload available for local storage */
-
- minLocal = pPage->minLocal;
- maxLocal = pPage->maxLocal;
- surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4);
- testcase( surplus==maxLocal );
- testcase( surplus==maxLocal+1 );
- if( surplus <= maxLocal ){
- pInfo->nLocal = (u16)surplus;
- }else{
- pInfo->nLocal = (u16)minLocal;
- }
- pInfo->iOverflow = (u16)(pInfo->nLocal + n);
- pInfo->nSize = pInfo->iOverflow + 4;
- }
-}
-#define parseCell(pPage, iCell, pInfo) \
- btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
-static void btreeParseCell(
- MemPage *pPage, /* Page containing the cell */
- int iCell, /* The cell index. First cell is 0 */
- CellInfo *pInfo /* Fill in this structure */
-){
- parseCell(pPage, iCell, pInfo);
-}
-
-/*
-** Compute the total number of bytes that a Cell needs in the cell
-** data area of the btree-page. The return number includes the cell
-** data header and the local payload, but not any overflow page or
-** the space used by the cell pointer.
-*/
-static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
- u8 *pIter = &pCell[pPage->childPtrSize];
- u32 nSize;
-
-#ifdef SQLITE_DEBUG
- /* The value returned by this function should always be the same as
- ** the (CellInfo.nSize) value found by doing a full parse of the
- ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
- ** this function verifies that this invariant is not violated. */
- CellInfo debuginfo;
- btreeParseCellPtr(pPage, pCell, &debuginfo);
-#endif
-
- if( pPage->intKey ){
- u8 *pEnd;
- if( pPage->hasData ){
- pIter += getVarint32(pIter, nSize);
- }else{
- nSize = 0;
- }
-
- /* pIter now points at the 64-bit integer key value, a variable length
- ** integer. The following block moves pIter to point at the first byte
- ** past the end of the key value. */
- pEnd = &pIter[9];
- while( (*pIter++)&0x80 && pIter<pEnd );
- }else{
- pIter += getVarint32(pIter, nSize);
- }
-
- testcase( nSize==pPage->maxLocal );
- testcase( nSize==pPage->maxLocal+1 );
- if( nSize>pPage->maxLocal ){
- int minLocal = pPage->minLocal;
- nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
- testcase( nSize==pPage->maxLocal );
- testcase( nSize==pPage->maxLocal+1 );
- if( nSize>pPage->maxLocal ){
- nSize = minLocal;
- }
- nSize += 4;
- }
- nSize += (u32)(pIter - pCell);
-
- /* The minimum size of any cell is 4 bytes. */
- if( nSize<4 ){
- nSize = 4;
- }
-
- assert( nSize==debuginfo.nSize );
- return (u16)nSize;
-}
-
-#ifdef SQLITE_DEBUG
-/* This variation on cellSizePtr() is used inside of assert() statements
-** only. */
-static u16 cellSize(MemPage *pPage, int iCell){
- return cellSizePtr(pPage, findCell(pPage, iCell));
-}
-#endif
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** If the cell pCell, part of page pPage contains a pointer
-** to an overflow page, insert an entry into the pointer-map
-** for the overflow page.
-*/
-static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
- CellInfo info;
- if( *pRC ) return;
- assert( pCell!=0 );
- btreeParseCellPtr(pPage, pCell, &info);
- assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
- if( info.iOverflow ){
- Pgno ovfl = get4byte(&pCell[info.iOverflow]);
- ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
- }
-}
-#endif
-
-
-/*
-** Defragment the page given. All Cells are moved to the
-** end of the page and all free space is collected into one
-** big FreeBlk that occurs in between the header and cell
-** pointer array and the cell content area.
-*/
-static int defragmentPage(MemPage *pPage){
- int i; /* Loop counter */
- int pc; /* Address of a i-th cell */
- int hdr; /* Offset to the page header */
- int size; /* Size of a cell */
- int usableSize; /* Number of usable bytes on a page */
- int cellOffset; /* Offset to the cell pointer array */
- int cbrk; /* Offset to the cell content area */
- int nCell; /* Number of cells on the page */
- unsigned char *data; /* The page data */
- unsigned char *temp; /* Temp area for cell content */
- int iCellFirst; /* First allowable cell index */
- int iCellLast; /* Last possible cell index */
-
-
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( pPage->pBt!=0 );
- assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
- assert( pPage->nOverflow==0 );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
- data = pPage->aData;
- hdr = pPage->hdrOffset;
- cellOffset = pPage->cellOffset;
- nCell = pPage->nCell;
- assert( nCell==get2byte(&data[hdr+3]) );
- usableSize = pPage->pBt->usableSize;
- cbrk = get2byte(&data[hdr+5]);
- memcpy(&temp[cbrk], &data[cbrk], usableSize - cbrk);
- cbrk = usableSize;
- iCellFirst = cellOffset + 2*nCell;
- iCellLast = usableSize - 4;
- for(i=0; i<nCell; i++){
- u8 *pAddr; /* The i-th cell pointer */
- pAddr = &data[cellOffset + i*2];
- pc = get2byte(pAddr);
- testcase( pc==iCellFirst );
- testcase( pc==iCellLast );
-#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
- /* These conditions have already been verified in btreeInitPage()
- ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined
- */
- if( pc<iCellFirst || pc>iCellLast ){
- return SQLITE_CORRUPT_BKPT;
- }
-#endif
- assert( pc>=iCellFirst && pc<=iCellLast );
- size = cellSizePtr(pPage, &temp[pc]);
- cbrk -= size;
-#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
- if( cbrk<iCellFirst ){
- return SQLITE_CORRUPT_BKPT;
- }
-#else
- if( cbrk<iCellFirst || pc+size>usableSize ){
- return SQLITE_CORRUPT_BKPT;
- }
-#endif
- assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
- testcase( cbrk+size==usableSize );
- testcase( pc+size==usableSize );
- memcpy(&data[cbrk], &temp[pc], size);
- put2byte(pAddr, cbrk);
- }
- assert( cbrk>=iCellFirst );
- put2byte(&data[hdr+5], cbrk);
- data[hdr+1] = 0;
- data[hdr+2] = 0;
- data[hdr+7] = 0;
- memset(&data[iCellFirst], 0, cbrk-iCellFirst);
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- if( cbrk-iCellFirst!=pPage->nFree ){
- return SQLITE_CORRUPT_BKPT;
- }
- return SQLITE_OK;
-}
-
-/*
-** Allocate nByte bytes of space from within the B-Tree page passed
-** as the first argument. Write into *pIdx the index into pPage->aData[]
-** of the first byte of allocated space. Return either SQLITE_OK or
-** an error code (usually SQLITE_CORRUPT).
-**
-** The caller guarantees that there is sufficient space to make the
-** allocation. This routine might need to defragment in order to bring
-** all the space together, however. This routine will avoid using
-** the first two bytes past the cell pointer area since presumably this
-** allocation is being made in order to insert a new cell, so we will
-** also end up needing a new cell pointer.
-*/
-static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
- const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
- u8 * const data = pPage->aData; /* Local cache of pPage->aData */
- int nFrag; /* Number of fragmented bytes on pPage */
- int top; /* First byte of cell content area */
- int gap; /* First byte of gap between cell pointers and cell content */
- int rc; /* Integer return code */
- int usableSize; /* Usable size of the page */
-
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( pPage->pBt );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( nByte>=0 ); /* Minimum cell size is 4 */
- assert( pPage->nFree>=nByte );
- assert( pPage->nOverflow==0 );
- usableSize = pPage->pBt->usableSize;
- assert( nByte < usableSize-8 );
-
- nFrag = data[hdr+7];
- assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
- gap = pPage->cellOffset + 2*pPage->nCell;
- top = get2byteNotZero(&data[hdr+5]);
- if( gap>top ) return SQLITE_CORRUPT_BKPT;
- testcase( gap+2==top );
- testcase( gap+1==top );
- testcase( gap==top );
-
- if( nFrag>=60 ){
- /* Always defragment highly fragmented pages */
- rc = defragmentPage(pPage);
- if( rc ) return rc;
- top = get2byteNotZero(&data[hdr+5]);
- }else if( gap+2<=top ){
- /* Search the freelist looking for a free slot big enough to satisfy
- ** the request. The allocation is made from the first free slot in
- ** the list that is large enough to accomadate it.
- */
- int pc, addr;
- for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
- int size; /* Size of the free slot */
- if( pc>usableSize-4 || pc<addr+4 ){
- return SQLITE_CORRUPT_BKPT;
- }
- size = get2byte(&data[pc+2]);
- if( size>=nByte ){
- int x = size - nByte;
- testcase( x==4 );
- testcase( x==3 );
- if( x<4 ){
- /* Remove the slot from the free-list. Update the number of
- ** fragmented bytes within the page. */
- memcpy(&data[addr], &data[pc], 2);
- data[hdr+7] = (u8)(nFrag + x);
- }else if( size+pc > usableSize ){
- return SQLITE_CORRUPT_BKPT;
- }else{
- /* The slot remains on the free-list. Reduce its size to account
- ** for the portion used by the new allocation. */
- put2byte(&data[pc+2], x);
- }
- *pIdx = pc + x;
- return SQLITE_OK;
- }
- }
- }
-
- /* Check to make sure there is enough space in the gap to satisfy
- ** the allocation. If not, defragment.
- */
- testcase( gap+2+nByte==top );
- if( gap+2+nByte>top ){
- rc = defragmentPage(pPage);
- if( rc ) return rc;
- top = get2byteNotZero(&data[hdr+5]);
- assert( gap+nByte<=top );
- }
-
-
- /* Allocate memory from the gap in between the cell pointer array
- ** and the cell content area. The btreeInitPage() call has already
- ** validated the freelist. Given that the freelist is valid, there
- ** is no way that the allocation can extend off the end of the page.
- ** The assert() below verifies the previous sentence.
- */
- top -= nByte;
- put2byte(&data[hdr+5], top);
- assert( top+nByte <= (int)pPage->pBt->usableSize );
- *pIdx = top;
- return SQLITE_OK;
-}
-
-/*
-** Return a section of the pPage->aData to the freelist.
-** The first byte of the new free block is pPage->aDisk[start]
-** and the size of the block is "size" bytes.
-**
-** Most of the effort here is involved in coalesing adjacent
-** free blocks into a single big free block.
-*/
-static int freeSpace(MemPage *pPage, int start, int size){
- int addr, pbegin, hdr;
- int iLast; /* Largest possible freeblock offset */
- unsigned char *data = pPage->aData;
-
- assert( pPage->pBt!=0 );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( start>=pPage->hdrOffset+6+pPage->childPtrSize );
- assert( (start + size) <= (int)pPage->pBt->usableSize );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( size>=0 ); /* Minimum cell size is 4 */
-
- if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
- /* Overwrite deleted information with zeros when the secure_delete
- ** option is enabled */
- memset(&data[start], 0, size);
- }
-
- /* Add the space back into the linked list of freeblocks. Note that
- ** even though the freeblock list was checked by btreeInitPage(),
- ** btreeInitPage() did not detect overlapping cells or
- ** freeblocks that overlapped cells. Nor does it detect when the
- ** cell content area exceeds the value in the page header. If these
- ** situations arise, then subsequent insert operations might corrupt
- ** the freelist. So we do need to check for corruption while scanning
- ** the freelist.
- */
- hdr = pPage->hdrOffset;
- addr = hdr + 1;
- iLast = pPage->pBt->usableSize - 4;
- assert( start<=iLast );
- while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
- if( pbegin<addr+4 ){
- return SQLITE_CORRUPT_BKPT;
- }
- addr = pbegin;
- }
- if( pbegin>iLast ){
- return SQLITE_CORRUPT_BKPT;
- }
- assert( pbegin>addr || pbegin==0 );
- put2byte(&data[addr], start);
- put2byte(&data[start], pbegin);
- put2byte(&data[start+2], size);
- pPage->nFree = pPage->nFree + (u16)size;
-
- /* Coalesce adjacent free blocks */
- addr = hdr + 1;
- while( (pbegin = get2byte(&data[addr]))>0 ){
- int pnext, psize, x;
- assert( pbegin>addr );
- assert( pbegin <= (int)pPage->pBt->usableSize-4 );
- pnext = get2byte(&data[pbegin]);
- psize = get2byte(&data[pbegin+2]);
- if( pbegin + psize + 3 >= pnext && pnext>0 ){
- int frag = pnext - (pbegin+psize);
- if( (frag<0) || (frag>(int)data[hdr+7]) ){
- return SQLITE_CORRUPT_BKPT;
- }
- data[hdr+7] -= (u8)frag;
- x = get2byte(&data[pnext]);
- put2byte(&data[pbegin], x);
- x = pnext + get2byte(&data[pnext+2]) - pbegin;
- put2byte(&data[pbegin+2], x);
- }else{
- addr = pbegin;
- }
- }
-
- /* If the cell content area begins with a freeblock, remove it. */
- if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){
- int top;
- pbegin = get2byte(&data[hdr+1]);
- memcpy(&data[hdr+1], &data[pbegin], 2);
- top = get2byte(&data[hdr+5]) + get2byte(&data[pbegin+2]);
- put2byte(&data[hdr+5], top);
- }
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- return SQLITE_OK;
-}
-
-/*
-** Decode the flags byte (the first byte of the header) for a page
-** and initialize fields of the MemPage structure accordingly.
-**
-** Only the following combinations are supported. Anything different
-** indicates a corrupt database files:
-**
-** PTF_ZERODATA
-** PTF_ZERODATA | PTF_LEAF
-** PTF_LEAFDATA | PTF_INTKEY
-** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF
-*/
-static int decodeFlags(MemPage *pPage, int flagByte){
- BtShared *pBt; /* A copy of pPage->pBt */
-
- assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 );
- flagByte &= ~PTF_LEAF;
- pPage->childPtrSize = 4-4*pPage->leaf;
- pBt = pPage->pBt;
- if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
- pPage->intKey = 1;
- pPage->hasData = pPage->leaf;
- pPage->maxLocal = pBt->maxLeaf;
- pPage->minLocal = pBt->minLeaf;
- }else if( flagByte==PTF_ZERODATA ){
- pPage->intKey = 0;
- pPage->hasData = 0;
- pPage->maxLocal = pBt->maxLocal;
- pPage->minLocal = pBt->minLocal;
- }else{
- return SQLITE_CORRUPT_BKPT;
- }
- pPage->max1bytePayload = pBt->max1bytePayload;
- return SQLITE_OK;
-}
-
-/*
-** Initialize the auxiliary information for a disk block.
-**
-** Return SQLITE_OK on success. If we see that the page does
-** not contain a well-formed database page, then return
-** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
-** guarantee that the page is well-formed. It only shows that
-** we failed to detect any corruption.
-*/
-static int btreeInitPage(MemPage *pPage){
-
- assert( pPage->pBt!=0 );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
- assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
- assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
-
- if( !pPage->isInit ){
- u16 pc; /* Address of a freeblock within pPage->aData[] */
- u8 hdr; /* Offset to beginning of page header */
- u8 *data; /* Equal to pPage->aData */
- BtShared *pBt; /* The main btree structure */
- int usableSize; /* Amount of usable space on each page */
- u16 cellOffset; /* Offset from start of page to first cell pointer */
- int nFree; /* Number of unused bytes on the page */
- int top; /* First byte of the cell content area */
- int iCellFirst; /* First allowable cell or freeblock offset */
- int iCellLast; /* Last possible cell or freeblock offset */
-
- pBt = pPage->pBt;
-
- hdr = pPage->hdrOffset;
- data = pPage->aData;
- if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
- assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
- pPage->maskPage = (u16)(pBt->pageSize - 1);
- pPage->nOverflow = 0;
- usableSize = pBt->usableSize;
- pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
- pPage->aDataEnd = &data[usableSize];
- pPage->aCellIdx = &data[cellOffset];
- top = get2byteNotZero(&data[hdr+5]);
- pPage->nCell = get2byte(&data[hdr+3]);
- if( pPage->nCell>MX_CELL(pBt) ){
- /* To many cells for a single page. The page must be corrupt */
- return SQLITE_CORRUPT_BKPT;
- }
- testcase( pPage->nCell==MX_CELL(pBt) );
-
- /* A malformed database page might cause us to read past the end
- ** of page when parsing a cell.
- **
- ** The following block of code checks early to see if a cell extends
- ** past the end of a page boundary and causes SQLITE_CORRUPT to be
- ** returned if it does.
- */
- iCellFirst = cellOffset + 2*pPage->nCell;
- iCellLast = usableSize - 4;
-#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
- {
- int i; /* Index into the cell pointer array */
- int sz; /* Size of a cell */
-
- if( !pPage->leaf ) iCellLast--;
- for(i=0; i<pPage->nCell; i++){
- pc = get2byte(&data[cellOffset+i*2]);
- testcase( pc==iCellFirst );
- testcase( pc==iCellLast );
- if( pc<iCellFirst || pc>iCellLast ){
- return SQLITE_CORRUPT_BKPT;
- }
- sz = cellSizePtr(pPage, &data[pc]);
- testcase( pc+sz==usableSize );
- if( pc+sz>usableSize ){
- return SQLITE_CORRUPT_BKPT;
- }
- }
- if( !pPage->leaf ) iCellLast++;
- }
-#endif
-
- /* Compute the total free space on the page */
- pc = get2byte(&data[hdr+1]);
- nFree = data[hdr+7] + top;
- while( pc>0 ){
- u16 next, size;
- if( pc<iCellFirst || pc>iCellLast ){
- /* Start of free block is off the page */
- return SQLITE_CORRUPT_BKPT;
- }
- next = get2byte(&data[pc]);
- size = get2byte(&data[pc+2]);
- if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
- /* Free blocks must be in ascending order. And the last byte of
- ** the free-block must lie on the database page. */
- return SQLITE_CORRUPT_BKPT;
- }
- nFree = nFree + size;
- pc = next;
- }
-
- /* At this point, nFree contains the sum of the offset to the start
- ** of the cell-content area plus the number of free bytes within
- ** the cell-content area. If this is greater than the usable-size
- ** of the page, then the page must be corrupted. This check also
- ** serves to verify that the offset to the start of the cell-content
- ** area, according to the page header, lies within the page.
- */
- if( nFree>usableSize ){
- return SQLITE_CORRUPT_BKPT;
- }
- pPage->nFree = (u16)(nFree - iCellFirst);
- pPage->isInit = 1;
- }
- return SQLITE_OK;
-}
-
-/*
-** Set up a raw page so that it looks like a database page holding
-** no entries.
-*/
-static void zeroPage(MemPage *pPage, int flags){
- unsigned char *data = pPage->aData;
- BtShared *pBt = pPage->pBt;
- u8 hdr = pPage->hdrOffset;
- u16 first;
-
- assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
- assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
- assert( sqlite3PagerGetData(pPage->pDbPage) == data );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( sqlite3_mutex_held(pBt->mutex) );
- if( pBt->btsFlags & BTS_SECURE_DELETE ){
- memset(&data[hdr], 0, pBt->usableSize - hdr);
- }
- data[hdr] = (char)flags;
- first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0);
- memset(&data[hdr+1], 0, 4);
- data[hdr+7] = 0;
- put2byte(&data[hdr+5], pBt->usableSize);
- pPage->nFree = (u16)(pBt->usableSize - first);
- decodeFlags(pPage, flags);
- pPage->hdrOffset = hdr;
- pPage->cellOffset = first;
- pPage->aDataEnd = &data[pBt->usableSize];
- pPage->aCellIdx = &data[first];
- pPage->nOverflow = 0;
- assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
- pPage->maskPage = (u16)(pBt->pageSize - 1);
- pPage->nCell = 0;
- pPage->isInit = 1;
-}
-
-
-/*
-** Convert a DbPage obtained from the pager into a MemPage used by
-** the btree layer.
-*/
-static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){
- MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage);
- pPage->aData = sqlite3PagerGetData(pDbPage);
- pPage->pDbPage = pDbPage;
- pPage->pBt = pBt;
- pPage->pgno = pgno;
- pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
- return pPage;
-}
-
-/*
-** Get a page from the pager. Initialize the MemPage.pBt and
-** MemPage.aData elements if needed.
-**
-** If the noContent flag is set, it means that we do not care about
-** the content of the page at this time. So do not go to the disk
-** to fetch the content. Just fill in the content with zeros for now.
-** If in the future we call sqlite3PagerWrite() on this page, that
-** means we have started to be concerned about content and the disk
-** read should occur at that point.
-*/
-static int btreeGetPage(
- BtShared *pBt, /* The btree */
- Pgno pgno, /* Number of the page to fetch */
- MemPage **ppPage, /* Return the page in this parameter */
- int noContent /* Do not load page content if true */
-){
- int rc;
- DbPage *pDbPage;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent);
- if( rc ) return rc;
- *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt);
- return SQLITE_OK;
-}
-
-/*
-** Retrieve a page from the pager cache. If the requested page is not
-** already in the pager cache return NULL. Initialize the MemPage.pBt and
-** MemPage.aData elements if needed.
-*/
-static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){
- DbPage *pDbPage;
- assert( sqlite3_mutex_held(pBt->mutex) );
- pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
- if( pDbPage ){
- return btreePageFromDbPage(pDbPage, pgno, pBt);
- }
- return 0;
-}
-
-/*
-** Return the size of the database file in pages. If there is any kind of
-** error, return ((unsigned int)-1).
-*/
-static Pgno btreePagecount(BtShared *pBt){
- return pBt->nPage;
-}
-SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( ((p->pBt->nPage)&0x8000000)==0 );
- return (int)btreePagecount(p->pBt);
-}
-
-/*
-** Get a page from the pager and initialize it. This routine is just a
-** convenience wrapper around separate calls to btreeGetPage() and
-** btreeInitPage().
-**
-** If an error occurs, then the value *ppPage is set to is undefined. It
-** may remain unchanged, or it may be set to an invalid value.
-*/
-static int getAndInitPage(
- BtShared *pBt, /* The database file */
- Pgno pgno, /* Number of the page to get */
- MemPage **ppPage /* Write the page pointer here */
-){
- int rc;
- assert( sqlite3_mutex_held(pBt->mutex) );
-
- if( pgno>btreePagecount(pBt) ){
- rc = SQLITE_CORRUPT_BKPT;
- }else{
- rc = btreeGetPage(pBt, pgno, ppPage, 0);
- if( rc==SQLITE_OK ){
- rc = btreeInitPage(*ppPage);
- if( rc!=SQLITE_OK ){
- releasePage(*ppPage);
- }
- }
- }
-
- testcase( pgno==0 );
- assert( pgno!=0 || rc==SQLITE_CORRUPT );
- return rc;
-}
-
-/*
-** Release a MemPage. This should be called once for each prior
-** call to btreeGetPage.
-*/
-static void releasePage(MemPage *pPage){
- if( pPage ){
- assert( pPage->aData );
- assert( pPage->pBt );
- assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
- assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- sqlite3PagerUnref(pPage->pDbPage);
- }
-}
-
-/*
-** During a rollback, when the pager reloads information into the cache
-** so that the cache is restored to its original state at the start of
-** the transaction, for each page restored this routine is called.
-**
-** This routine needs to reset the extra data section at the end of the
-** page to agree with the restored data.
-*/
-static void pageReinit(DbPage *pData){
- MemPage *pPage;
- pPage = (MemPage *)sqlite3PagerGetExtra(pData);
- assert( sqlite3PagerPageRefcount(pData)>0 );
- if( pPage->isInit ){
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- pPage->isInit = 0;
- if( sqlite3PagerPageRefcount(pData)>1 ){
- /* pPage might not be a btree page; it might be an overflow page
- ** or ptrmap page or a free page. In those cases, the following
- ** call to btreeInitPage() will likely return SQLITE_CORRUPT.
- ** But no harm is done by this. And it is very important that
- ** btreeInitPage() be called on every btree page so we make
- ** the call for every page that comes in for re-initing. */
- btreeInitPage(pPage);
- }
- }
-}
-
-/*
-** Invoke the busy handler for a btree.
-*/
-static int btreeInvokeBusyHandler(void *pArg){
- BtShared *pBt = (BtShared*)pArg;
- assert( pBt->db );
- assert( sqlite3_mutex_held(pBt->db->mutex) );
- return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
-}
-
-/*
-** Open a database file.
-**
-** zFilename is the name of the database file. If zFilename is NULL
-** then an ephemeral database is created. The ephemeral database might
-** be exclusively in memory, or it might use a disk-based memory cache.
-** Either way, the ephemeral database will be automatically deleted
-** when sqlite3BtreeClose() is called.
-**
-** If zFilename is ":memory:" then an in-memory database is created
-** that is automatically destroyed when it is closed.
-**
-** The "flags" parameter is a bitmask that might contain bits like
-** BTREE_OMIT_JOURNAL and/or BTREE_MEMORY.
-**
-** If the database is already opened in the same database connection
-** and we are in shared cache mode, then the open will fail with an
-** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared
-** objects in the same database connection since doing so will lead
-** to problems with locking.
-*/
-SQLITE_PRIVATE int sqlite3BtreeOpen(
- sqlite3_vfs *pVfs, /* VFS to use for this b-tree */
- const char *zFilename, /* Name of the file containing the BTree database */
- sqlite3 *db, /* Associated database handle */
- Btree **ppBtree, /* Pointer to new Btree object written here */
- int flags, /* Options */
- int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */
-){
- BtShared *pBt = 0; /* Shared part of btree structure */
- Btree *p; /* Handle to return */
- sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */
- int rc = SQLITE_OK; /* Result code from this function */
- u8 nReserve; /* Byte of unused space on each page */
- unsigned char zDbHeader[100]; /* Database header content */
-
- /* True if opening an ephemeral, temporary database */
- const int isTempDb = zFilename==0 || zFilename[0]==0;
-
- /* Set the variable isMemdb to true for an in-memory database, or
- ** false for a file-based database.
- */
-#ifdef SQLITE_OMIT_MEMORYDB
- const int isMemdb = 0;
-#else
- const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0)
- || (isTempDb && sqlite3TempInMemory(db))
- || (vfsFlags & SQLITE_OPEN_MEMORY)!=0;
-#endif
-
- assert( db!=0 );
- assert( pVfs!=0 );
- assert( sqlite3_mutex_held(db->mutex) );
- assert( (flags&0xff)==flags ); /* flags fit in 8 bits */
-
- /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */
- assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 );
-
- /* A BTREE_SINGLE database is always a temporary and/or ephemeral */
- assert( (flags & BTREE_SINGLE)==0 || isTempDb );
-
- if( isMemdb ){
- flags |= BTREE_MEMORY;
- }
- if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){
- vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB;
- }
- p = sqlite3MallocZero(sizeof(Btree));
- if( !p ){
- return SQLITE_NOMEM;
- }
- p->inTrans = TRANS_NONE;
- p->db = db;
-#ifndef SQLITE_OMIT_SHARED_CACHE
- p->lock.pBtree = p;
- p->lock.iTable = 1;
-#endif
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
- /*
- ** If this Btree is a candidate for shared cache, try to find an
- ** existing BtShared object that we can share with
- */
- if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
- if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
- int nFullPathname = pVfs->mxPathname+1;
- char *zFullPathname = sqlite3Malloc(nFullPathname);
- MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
- p->sharable = 1;
- if( !zFullPathname ){
- sqlite3_free(p);
- return SQLITE_NOMEM;
- }
- if( isMemdb ){
- memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1);
- }else{
- rc = sqlite3OsFullPathname(pVfs, zFilename,
- nFullPathname, zFullPathname);
- if( rc ){
- sqlite3_free(zFullPathname);
- sqlite3_free(p);
- return rc;
- }
- }
-#if SQLITE_THREADSAFE
- mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
- sqlite3_mutex_enter(mutexOpen);
- mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
- sqlite3_mutex_enter(mutexShared);
-#endif
- for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
- assert( pBt->nRef>0 );
- if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0))
- && sqlite3PagerVfs(pBt->pPager)==pVfs ){
- int iDb;
- for(iDb=db->nDb-1; iDb>=0; iDb--){
- Btree *pExisting = db->aDb[iDb].pBt;
- if( pExisting && pExisting->pBt==pBt ){
- sqlite3_mutex_leave(mutexShared);
- sqlite3_mutex_leave(mutexOpen);
- sqlite3_free(zFullPathname);
- sqlite3_free(p);
- return SQLITE_CONSTRAINT;
- }
- }
- p->pBt = pBt;
- pBt->nRef++;
- break;
- }
- }
- sqlite3_mutex_leave(mutexShared);
- sqlite3_free(zFullPathname);
- }
-#ifdef SQLITE_DEBUG
- else{
- /* In debug mode, we mark all persistent databases as sharable
- ** even when they are not. This exercises the locking code and
- ** gives more opportunity for asserts(sqlite3_mutex_held())
- ** statements to find locking problems.
- */
- p->sharable = 1;
- }
-#endif
- }
-#endif
- if( pBt==0 ){
- /*
- ** The following asserts make sure that structures used by the btree are
- ** the right size. This is to guard against size changes that result
- ** when compiling on a different architecture.
- */
- assert( sizeof(i64)==8 || sizeof(i64)==4 );
- assert( sizeof(u64)==8 || sizeof(u64)==4 );
- assert( sizeof(u32)==4 );
- assert( sizeof(u16)==2 );
- assert( sizeof(Pgno)==4 );
-
- pBt = sqlite3MallocZero( sizeof(*pBt) );
- if( pBt==0 ){
- rc = SQLITE_NOMEM;
- goto btree_open_out;
- }
- rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
- EXTRA_SIZE, flags, vfsFlags, pageReinit);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
- }
- if( rc!=SQLITE_OK ){
- goto btree_open_out;
- }
- pBt->openFlags = (u8)flags;
- pBt->db = db;
- sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
- p->pBt = pBt;
-
- pBt->pCursor = 0;
- pBt->pPage1 = 0;
- if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY;
-#ifdef SQLITE_SECURE_DELETE
- pBt->btsFlags |= BTS_SECURE_DELETE;
-#endif
- pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16);
- if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
- || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
- pBt->pageSize = 0;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- /* If the magic name ":memory:" will create an in-memory database, then
- ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
- ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
- ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a
- ** regular file-name. In this case the auto-vacuum applies as per normal.
- */
- if( zFilename && !isMemdb ){
- pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0);
- pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0);
- }
-#endif
- nReserve = 0;
- }else{
- nReserve = zDbHeader[20];
- pBt->btsFlags |= BTS_PAGESIZE_FIXED;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
- pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0);
-#endif
- }
- rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
- if( rc ) goto btree_open_out;
- pBt->usableSize = pBt->pageSize - nReserve;
- assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
- /* Add the new BtShared object to the linked list sharable BtShareds.
- */
- if( p->sharable ){
- MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
- pBt->nRef = 1;
- MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);)
- if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
- pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
- if( pBt->mutex==0 ){
- rc = SQLITE_NOMEM;
- db->mallocFailed = 0;
- goto btree_open_out;
- }
- }
- sqlite3_mutex_enter(mutexShared);
- pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList);
- GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt;
- sqlite3_mutex_leave(mutexShared);
- }
-#endif
- }
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
- /* If the new Btree uses a sharable pBtShared, then link the new
- ** Btree into the list of all sharable Btrees for the same connection.
- ** The list is kept in ascending order by pBt address.
- */
- if( p->sharable ){
- int i;
- Btree *pSib;
- for(i=0; i<db->nDb; i++){
- if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
- while( pSib->pPrev ){ pSib = pSib->pPrev; }
- if( p->pBt<pSib->pBt ){
- p->pNext = pSib;
- p->pPrev = 0;
- pSib->pPrev = p;
- }else{
- while( pSib->pNext && pSib->pNext->pBt<p->pBt ){
- pSib = pSib->pNext;
- }
- p->pNext = pSib->pNext;
- p->pPrev = pSib;
- if( p->pNext ){
- p->pNext->pPrev = p;
- }
- pSib->pNext = p;
- }
- break;
- }
- }
- }
-#endif
- *ppBtree = p;
-
-btree_open_out:
- if( rc!=SQLITE_OK ){
- if( pBt && pBt->pPager ){
- sqlite3PagerClose(pBt->pPager);
- }
- sqlite3_free(pBt);
- sqlite3_free(p);
- *ppBtree = 0;
- }else{
- /* If the B-Tree was successfully opened, set the pager-cache size to the
- ** default value. Except, when opening on an existing shared pager-cache,
- ** do not change the pager-cache size.
- */
- if( sqlite3BtreeSchema(p, 0, 0)==0 ){
- sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
- }
- }
- if( mutexOpen ){
- assert( sqlite3_mutex_held(mutexOpen) );
- sqlite3_mutex_leave(mutexOpen);
- }
- return rc;
-}
-
-/*
-** Decrement the BtShared.nRef counter. When it reaches zero,
-** remove the BtShared structure from the sharing list. Return
-** true if the BtShared.nRef counter reaches zero and return
-** false if it is still positive.
-*/
-static int removeFromSharingList(BtShared *pBt){
-#ifndef SQLITE_OMIT_SHARED_CACHE
- MUTEX_LOGIC( sqlite3_mutex *pMaster; )
- BtShared *pList;
- int removed = 0;
-
- assert( sqlite3_mutex_notheld(pBt->mutex) );
- MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
- sqlite3_mutex_enter(pMaster);
- pBt->nRef--;
- if( pBt->nRef<=0 ){
- if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
- GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext;
- }else{
- pList = GLOBAL(BtShared*,sqlite3SharedCacheList);
- while( ALWAYS(pList) && pList->pNext!=pBt ){
- pList=pList->pNext;
- }
- if( ALWAYS(pList) ){
- pList->pNext = pBt->pNext;
- }
- }
- if( SQLITE_THREADSAFE ){
- sqlite3_mutex_free(pBt->mutex);
- }
- removed = 1;
- }
- sqlite3_mutex_leave(pMaster);
- return removed;
-#else
- return 1;
-#endif
-}
-
-/*
-** Make sure pBt->pTmpSpace points to an allocation of
-** MX_CELL_SIZE(pBt) bytes.
-*/
-static void allocateTempSpace(BtShared *pBt){
- if( !pBt->pTmpSpace ){
- pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
- }
-}
-
-/*
-** Free the pBt->pTmpSpace allocation
-*/
-static void freeTempSpace(BtShared *pBt){
- sqlite3PageFree( pBt->pTmpSpace);
- pBt->pTmpSpace = 0;
-}
-
-/*
-** Close an open database and invalidate all cursors.
-*/
-SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
- BtShared *pBt = p->pBt;
- BtCursor *pCur;
-
- /* Close all cursors opened via this handle. */
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- pCur = pBt->pCursor;
- while( pCur ){
- BtCursor *pTmp = pCur;
- pCur = pCur->pNext;
- if( pTmp->pBtree==p ){
- sqlite3BtreeCloseCursor(pTmp);
- }
- }
-
- /* Rollback any active transaction and free the handle structure.
- ** The call to sqlite3BtreeRollback() drops any table-locks held by
- ** this handle.
- */
- sqlite3BtreeRollback(p, SQLITE_OK);
- sqlite3BtreeLeave(p);
-
- /* If there are still other outstanding references to the shared-btree
- ** structure, return now. The remainder of this procedure cleans
- ** up the shared-btree.
- */
- assert( p->wantToLock==0 && p->locked==0 );
- if( !p->sharable || removeFromSharingList(pBt) ){
- /* The pBt is no longer on the sharing list, so we can access
- ** it without having to hold the mutex.
- **
- ** Clean out and delete the BtShared object.
- */
- assert( !pBt->pCursor );
- sqlite3PagerClose(pBt->pPager);
- if( pBt->xFreeSchema && pBt->pSchema ){
- pBt->xFreeSchema(pBt->pSchema);
- }
- sqlite3DbFree(0, pBt->pSchema);
- freeTempSpace(pBt);
- sqlite3_free(pBt);
- }
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
- assert( p->wantToLock==0 );
- assert( p->locked==0 );
- if( p->pPrev ) p->pPrev->pNext = p->pNext;
- if( p->pNext ) p->pNext->pPrev = p->pPrev;
-#endif
-
- sqlite3_free(p);
- return SQLITE_OK;
-}
-
-/*
-** Change the limit on the number of pages allowed in the cache.
-**
-** The maximum number of cache pages is set to the absolute
-** value of mxPage. If mxPage is negative, the pager will
-** operate asynchronously - it will not stop to do fsync()s
-** to insure data is written to the disk surface before
-** continuing. Transactions still work if synchronous is off,
-** and the database cannot be corrupted if this program
-** crashes. But if the operating system crashes or there is
-** an abrupt power failure when synchronous is off, the database
-** could be left in an inconsistent and unrecoverable state.
-** Synchronous is on by default so database corruption is not
-** normally a worry.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
- BtShared *pBt = p->pBt;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- sqlite3PagerSetCachesize(pBt->pPager, mxPage);
- sqlite3BtreeLeave(p);
- return SQLITE_OK;
-}
-
-/*
-** Change the way data is synced to disk in order to increase or decrease
-** how well the database resists damage due to OS crashes and power
-** failures. Level 1 is the same as asynchronous (no syncs() occur and
-** there is a high probability of damage) Level 2 is the default. There
-** is a very low but non-zero probability of damage. Level 3 reduces the
-** probability of damage to near zero but with a write performance reduction.
-*/
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(
- Btree *p, /* The btree to set the safety level on */
- int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
- int fullSync, /* PRAGMA fullfsync. */
- int ckptFullSync /* PRAGMA checkpoint_fullfync */
-){
- BtShared *pBt = p->pBt;
- assert( sqlite3_mutex_held(p->db->mutex) );
- assert( level>=1 && level<=3 );
- sqlite3BtreeEnter(p);
- sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync);
- sqlite3BtreeLeave(p);
- return SQLITE_OK;
-}
-#endif
-
-/*
-** Return TRUE if the given btree is set to safety level 1. In other
-** words, return TRUE if no sync() occurs on the disk files.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree *p){
- BtShared *pBt = p->pBt;
- int rc;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- assert( pBt && pBt->pPager );
- rc = sqlite3PagerNosync(pBt->pPager);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Change the default pages size and the number of reserved bytes per page.
-** Or, if the page size has already been fixed, return SQLITE_READONLY
-** without changing anything.
-**
-** The page size must be a power of 2 between 512 and 65536. If the page
-** size supplied does not meet this constraint then the page size is not
-** changed.
-**
-** Page sizes are constrained to be a power of two so that the region
-** of the database file used for locking (beginning at PENDING_BYTE,
-** the first byte past the 1GB boundary, 0x40000000) needs to occur
-** at the beginning of a page.
-**
-** If parameter nReserve is less than zero, then the number of reserved
-** bytes per page is left unchanged.
-**
-** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size
-** and autovacuum mode can no longer be changed.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
- int rc = SQLITE_OK;
- BtShared *pBt = p->pBt;
- assert( nReserve>=-1 && nReserve<=255 );
- sqlite3BtreeEnter(p);
- if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
- sqlite3BtreeLeave(p);
- return SQLITE_READONLY;
- }
- if( nReserve<0 ){
- nReserve = pBt->pageSize - pBt->usableSize;
- }
- assert( nReserve>=0 && nReserve<=255 );
- if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
- ((pageSize-1)&pageSize)==0 ){
- assert( (pageSize & 7)==0 );
- assert( !pBt->pPage1 && !pBt->pCursor );
- pBt->pageSize = (u32)pageSize;
- freeTempSpace(pBt);
- }
- rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
- pBt->usableSize = pBt->pageSize - (u16)nReserve;
- if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED;
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Return the currently defined page size
-*/
-SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
- return p->pBt->pageSize;
-}
-
-#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
-/*
-** This function is similar to sqlite3BtreeGetReserve(), except that it
-** may only be called if it is guaranteed that the b-tree mutex is already
-** held.
-**
-** This is useful in one special case in the backup API code where it is
-** known that the shared b-tree mutex is held, but the mutex on the
-** database handle that owns *p is not. In this case if sqlite3BtreeEnter()
-** were to be called, it might collide with some other operation on the
-** database handle that owns *p, causing undefined behaviour.
-*/
-SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){
- assert( sqlite3_mutex_held(p->pBt->mutex) );
- return p->pBt->pageSize - p->pBt->usableSize;
-}
-#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */
-
-#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
-/*
-** Return the number of bytes of space at the end of every page that
-** are intentually left unused. This is the "reserved" space that is
-** sometimes used by extensions.
-*/
-SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree *p){
- int n;
- sqlite3BtreeEnter(p);
- n = p->pBt->pageSize - p->pBt->usableSize;
- sqlite3BtreeLeave(p);
- return n;
-}
-
-/*
-** Set the maximum page count for a database if mxPage is positive.
-** No changes are made if mxPage is 0 or negative.
-** Regardless of the value of mxPage, return the maximum page count.
-*/
-SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){
- int n;
- sqlite3BtreeEnter(p);
- n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage);
- sqlite3BtreeLeave(p);
- return n;
-}
-
-/*
-** Set the BTS_SECURE_DELETE flag if newFlag is 0 or 1. If newFlag is -1,
-** then make no changes. Always return the value of the BTS_SECURE_DELETE
-** setting after the change.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
- int b;
- if( p==0 ) return 0;
- sqlite3BtreeEnter(p);
- if( newFlag>=0 ){
- p->pBt->btsFlags &= ~BTS_SECURE_DELETE;
- if( newFlag ) p->pBt->btsFlags |= BTS_SECURE_DELETE;
- }
- b = (p->pBt->btsFlags & BTS_SECURE_DELETE)!=0;
- sqlite3BtreeLeave(p);
- return b;
-}
-#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
-
-/*
-** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
-** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
-** is disabled. The default value for the auto-vacuum property is
-** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- return SQLITE_READONLY;
-#else
- BtShared *pBt = p->pBt;
- int rc = SQLITE_OK;
- u8 av = (u8)autoVacuum;
-
- sqlite3BtreeEnter(p);
- if( (pBt->btsFlags & BTS_PAGESIZE_FIXED)!=0 && (av ?1:0)!=pBt->autoVacuum ){
- rc = SQLITE_READONLY;
- }else{
- pBt->autoVacuum = av ?1:0;
- pBt->incrVacuum = av==2 ?1:0;
- }
- sqlite3BtreeLeave(p);
- return rc;
-#endif
-}
-
-/*
-** Return the value of the 'auto-vacuum' property. If auto-vacuum is
-** enabled 1 is returned. Otherwise 0.
-*/
-SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- return BTREE_AUTOVACUUM_NONE;
-#else
- int rc;
- sqlite3BtreeEnter(p);
- rc = (
- (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE:
- (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL:
- BTREE_AUTOVACUUM_INCR
- );
- sqlite3BtreeLeave(p);
- return rc;
-#endif
-}
-
-
-/*
-** Get a reference to pPage1 of the database file. This will
-** also acquire a readlock on that file.
-**
-** SQLITE_OK is returned on success. If the file is not a
-** well-formed database file, then SQLITE_CORRUPT is returned.
-** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM
-** is returned if we run out of memory.
-*/
-static int lockBtree(BtShared *pBt){
- int rc; /* Result code from subfunctions */
- MemPage *pPage1; /* Page 1 of the database file */
- int nPage; /* Number of pages in the database */
- int nPageFile = 0; /* Number of pages in the database file */
- int nPageHeader; /* Number of pages in the database according to hdr */
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pBt->pPage1==0 );
- rc = sqlite3PagerSharedLock(pBt->pPager);
- if( rc!=SQLITE_OK ) return rc;
- rc = btreeGetPage(pBt, 1, &pPage1, 0);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Do some checking to help insure the file we opened really is
- ** a valid database file.
- */
- nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
- sqlite3PagerPagecount(pBt->pPager, &nPageFile);
- if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
- nPage = nPageFile;
- }
- if( nPage>0 ){
- u32 pageSize;
- u32 usableSize;
- u8 *page1 = pPage1->aData;
- rc = SQLITE_NOTADB;
- if( memcmp(page1, zMagicHeader, 16)!=0 ){
- goto page1_init_failed;
- }
-
-#ifdef SQLITE_OMIT_WAL
- if( page1[18]>1 ){
- pBt->btsFlags |= BTS_READ_ONLY;
- }
- if( page1[19]>1 ){
- goto page1_init_failed;
- }
-#else
- if( page1[18]>2 ){
- pBt->btsFlags |= BTS_READ_ONLY;
- }
- if( page1[19]>2 ){
- goto page1_init_failed;
- }
-
- /* If the write version is set to 2, this database should be accessed
- ** in WAL mode. If the log is not already open, open it now. Then
- ** return SQLITE_OK and return without populating BtShared.pPage1.
- ** The caller detects this and calls this function again. This is
- ** required as the version of page 1 currently in the page1 buffer
- ** may not be the latest version - there may be a newer one in the log
- ** file.
- */
- if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){
- int isOpen = 0;
- rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen);
- if( rc!=SQLITE_OK ){
- goto page1_init_failed;
- }else if( isOpen==0 ){
- releasePage(pPage1);
- return SQLITE_OK;
- }
- rc = SQLITE_NOTADB;
- }
-#endif
-
- /* The maximum embedded fraction must be exactly 25%. And the minimum
- ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
- ** The original design allowed these amounts to vary, but as of
- ** version 3.6.0, we require them to be fixed.
- */
- if( memcmp(&page1[21], "\100\040\040",3)!=0 ){
- goto page1_init_failed;
- }
- pageSize = (page1[16]<<8) | (page1[17]<<16);
- if( ((pageSize-1)&pageSize)!=0
- || pageSize>SQLITE_MAX_PAGE_SIZE
- || pageSize<=256
- ){
- goto page1_init_failed;
- }
- assert( (pageSize & 7)==0 );
- usableSize = pageSize - page1[20];
- if( (u32)pageSize!=pBt->pageSize ){
- /* After reading the first page of the database assuming a page size
- ** of BtShared.pageSize, we have discovered that the page-size is
- ** actually pageSize. Unlock the database, leave pBt->pPage1 at
- ** zero and return SQLITE_OK. The caller will call this function
- ** again with the correct page-size.
- */
- releasePage(pPage1);
- pBt->usableSize = usableSize;
- pBt->pageSize = pageSize;
- freeTempSpace(pBt);
- rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
- pageSize-usableSize);
- return rc;
- }
- if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPage>nPageFile ){
- rc = SQLITE_CORRUPT_BKPT;
- goto page1_init_failed;
- }
- if( usableSize<480 ){
- goto page1_init_failed;
- }
- pBt->pageSize = pageSize;
- pBt->usableSize = usableSize;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
- pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0);
-#endif
- }
-
- /* maxLocal is the maximum amount of payload to store locally for
- ** a cell. Make sure it is small enough so that at least minFanout
- ** cells can will fit on one page. We assume a 10-byte page header.
- ** Besides the payload, the cell must store:
- ** 2-byte pointer to the cell
- ** 4-byte child pointer
- ** 9-byte nKey value
- ** 4-byte nData value
- ** 4-byte overflow page pointer
- ** So a cell consists of a 2-byte pointer, a header which is as much as
- ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
- ** page pointer.
- */
- pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23);
- pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23);
- pBt->maxLeaf = (u16)(pBt->usableSize - 35);
- pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23);
- if( pBt->maxLocal>127 ){
- pBt->max1bytePayload = 127;
- }else{
- pBt->max1bytePayload = (u8)pBt->maxLocal;
- }
- assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
- pBt->pPage1 = pPage1;
- pBt->nPage = nPage;
- return SQLITE_OK;
-
-page1_init_failed:
- releasePage(pPage1);
- pBt->pPage1 = 0;
- return rc;
-}
-
-/*
-** If there are no outstanding cursors and we are not in the middle
-** of a transaction but there is a read lock on the database, then
-** this routine unrefs the first page of the database file which
-** has the effect of releasing the read lock.
-**
-** If there is a transaction in progress, this routine is a no-op.
-*/
-static void unlockBtreeIfUnused(BtShared *pBt){
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE );
- if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){
- assert( pBt->pPage1->aData );
- assert( sqlite3PagerRefcount(pBt->pPager)==1 );
- assert( pBt->pPage1->aData );
- releasePage(pBt->pPage1);
- pBt->pPage1 = 0;
- }
-}
-
-/*
-** If pBt points to an empty file then convert that empty file
-** into a new empty database by initializing the first page of
-** the database.
-*/
-static int newDatabase(BtShared *pBt){
- MemPage *pP1;
- unsigned char *data;
- int rc;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- if( pBt->nPage>0 ){
- return SQLITE_OK;
- }
- pP1 = pBt->pPage1;
- assert( pP1!=0 );
- data = pP1->aData;
- rc = sqlite3PagerWrite(pP1->pDbPage);
- if( rc ) return rc;
- memcpy(data, zMagicHeader, sizeof(zMagicHeader));
- assert( sizeof(zMagicHeader)==16 );
- data[16] = (u8)((pBt->pageSize>>8)&0xff);
- data[17] = (u8)((pBt->pageSize>>16)&0xff);
- data[18] = 1;
- data[19] = 1;
- assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize);
- data[20] = (u8)(pBt->pageSize - pBt->usableSize);
- data[21] = 64;
- data[22] = 32;
- data[23] = 32;
- memset(&data[24], 0, 100-24);
- zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
- pBt->btsFlags |= BTS_PAGESIZE_FIXED;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 );
- assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 );
- put4byte(&data[36 + 4*4], pBt->autoVacuum);
- put4byte(&data[36 + 7*4], pBt->incrVacuum);
-#endif
- pBt->nPage = 1;
- data[31] = 1;
- return SQLITE_OK;
-}
-
-/*
-** Initialize the first page of the database file (creating a database
-** consisting of a single page and no schema objects). Return SQLITE_OK
-** if successful, or an SQLite error code otherwise.
-*/
-SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){
- int rc;
- sqlite3BtreeEnter(p);
- p->pBt->nPage = 0;
- rc = newDatabase(p->pBt);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Attempt to start a new transaction. A write-transaction
-** is started if the second argument is nonzero, otherwise a read-
-** transaction. If the second argument is 2 or more and exclusive
-** transaction is started, meaning that no other process is allowed
-** to access the database. A preexisting transaction may not be
-** upgraded to exclusive by calling this routine a second time - the
-** exclusivity flag only works for a new transaction.
-**
-** A write-transaction must be started before attempting any
-** changes to the database. None of the following routines
-** will work unless a transaction is started first:
-**
-** sqlite3BtreeCreateTable()
-** sqlite3BtreeCreateIndex()
-** sqlite3BtreeClearTable()
-** sqlite3BtreeDropTable()
-** sqlite3BtreeInsert()
-** sqlite3BtreeDelete()
-** sqlite3BtreeUpdateMeta()
-**
-** If an initial attempt to acquire the lock fails because of lock contention
-** and the database was previously unlocked, then invoke the busy handler
-** if there is one. But if there was previously a read-lock, do not
-** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is
-** returned when there is already a read-lock in order to avoid a deadlock.
-**
-** Suppose there are two processes A and B. A has a read lock and B has
-** a reserved lock. B tries to promote to exclusive but is blocked because
-** of A's read lock. A tries to promote to reserved but is blocked by B.
-** One or the other of the two processes must give way or there can be
-** no progress. By returning SQLITE_BUSY and not invoking the busy callback
-** when A already has a read lock, we encourage A to give up and let B
-** proceed.
-*/
-SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
- sqlite3 *pBlock = 0;
- BtShared *pBt = p->pBt;
- int rc = SQLITE_OK;
-
- sqlite3BtreeEnter(p);
- btreeIntegrity(p);
-
- /* If the btree is already in a write-transaction, or it
- ** is already in a read-transaction and a read-transaction
- ** is requested, this is a no-op.
- */
- if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
- goto trans_begun;
- }
-
- /* Write transactions are not possible on a read-only database */
- if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
- rc = SQLITE_READONLY;
- goto trans_begun;
- }
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
- /* If another database handle has already opened a write transaction
- ** on this shared-btree structure and a second write transaction is
- ** requested, return SQLITE_LOCKED.
- */
- if( (wrflag && pBt->inTransaction==TRANS_WRITE)
- || (pBt->btsFlags & BTS_PENDING)!=0
- ){
- pBlock = pBt->pWriter->db;
- }else if( wrflag>1 ){
- BtLock *pIter;
- for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
- if( pIter->pBtree!=p ){
- pBlock = pIter->pBtree->db;
- break;
- }
- }
- }
- if( pBlock ){
- sqlite3ConnectionBlocked(p->db, pBlock);
- rc = SQLITE_LOCKED_SHAREDCACHE;
- goto trans_begun;
- }
-#endif
-
- /* Any read-only or read-write transaction implies a read-lock on
- ** page 1. So if some other shared-cache client already has a write-lock
- ** on page 1, the transaction cannot be opened. */
- rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
- if( SQLITE_OK!=rc ) goto trans_begun;
-
- pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
- if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
- do {
- /* Call lockBtree() until either pBt->pPage1 is populated or
- ** lockBtree() returns something other than SQLITE_OK. lockBtree()
- ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
- ** reading page 1 it discovers that the page-size of the database
- ** file is not pBt->pageSize. In this case lockBtree() will update
- ** pBt->pageSize to the page-size of the file on disk.
- */
- while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) );
-
- if( rc==SQLITE_OK && wrflag ){
- if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
- rc = SQLITE_READONLY;
- }else{
- rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
- if( rc==SQLITE_OK ){
- rc = newDatabase(pBt);
- }
- }
- }
-
- if( rc!=SQLITE_OK ){
- unlockBtreeIfUnused(pBt);
- }
- }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
- btreeInvokeBusyHandler(pBt) );
-
- if( rc==SQLITE_OK ){
- if( p->inTrans==TRANS_NONE ){
- pBt->nTransaction++;
-#ifndef SQLITE_OMIT_SHARED_CACHE
- if( p->sharable ){
- assert( p->lock.pBtree==p && p->lock.iTable==1 );
- p->lock.eLock = READ_LOCK;
- p->lock.pNext = pBt->pLock;
- pBt->pLock = &p->lock;
- }
-#endif
- }
- p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
- if( p->inTrans>pBt->inTransaction ){
- pBt->inTransaction = p->inTrans;
- }
- if( wrflag ){
- MemPage *pPage1 = pBt->pPage1;
-#ifndef SQLITE_OMIT_SHARED_CACHE
- assert( !pBt->pWriter );
- pBt->pWriter = p;
- pBt->btsFlags &= ~BTS_EXCLUSIVE;
- if( wrflag>1 ) pBt->btsFlags |= BTS_EXCLUSIVE;
-#endif
-
- /* If the db-size header field is incorrect (as it may be if an old
- ** client has been writing the database file), update it now. Doing
- ** this sooner rather than later means the database size can safely
- ** re-read the database size from page 1 if a savepoint or transaction
- ** rollback occurs within the transaction.
- */
- if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){
- rc = sqlite3PagerWrite(pPage1->pDbPage);
- if( rc==SQLITE_OK ){
- put4byte(&pPage1->aData[28], pBt->nPage);
- }
- }
- }
- }
-
-
-trans_begun:
- if( rc==SQLITE_OK && wrflag ){
- /* This call makes sure that the pager has the correct number of
- ** open savepoints. If the second parameter is greater than 0 and
- ** the sub-journal is not already open, then it will be opened here.
- */
- rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
- }
-
- btreeIntegrity(p);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-
-/*
-** Set the pointer-map entries for all children of page pPage. Also, if
-** pPage contains cells that point to overflow pages, set the pointer
-** map entries for the overflow pages as well.
-*/
-static int setChildPtrmaps(MemPage *pPage){
- int i; /* Counter variable */
- int nCell; /* Number of cells in page pPage */
- int rc; /* Return code */
- BtShared *pBt = pPage->pBt;
- u8 isInitOrig = pPage->isInit;
- Pgno pgno = pPage->pgno;
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- rc = btreeInitPage(pPage);
- if( rc!=SQLITE_OK ){
- goto set_child_ptrmaps_out;
- }
- nCell = pPage->nCell;
-
- for(i=0; i<nCell; i++){
- u8 *pCell = findCell(pPage, i);
-
- ptrmapPutOvflPtr(pPage, pCell, &rc);
-
- if( !pPage->leaf ){
- Pgno childPgno = get4byte(pCell);
- ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
- }
- }
-
- if( !pPage->leaf ){
- Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
- }
-
-set_child_ptrmaps_out:
- pPage->isInit = isInitOrig;
- return rc;
-}
-
-/*
-** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so
-** that it points to iTo. Parameter eType describes the type of pointer to
-** be modified, as follows:
-**
-** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child
-** page of pPage.
-**
-** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow
-** page pointed to by one of the cells on pPage.
-**
-** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
-** overflow page in the list.
-*/
-static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- if( eType==PTRMAP_OVERFLOW2 ){
- /* The pointer is always the first 4 bytes of the page in this case. */
- if( get4byte(pPage->aData)!=iFrom ){
- return SQLITE_CORRUPT_BKPT;
- }
- put4byte(pPage->aData, iTo);
- }else{
- u8 isInitOrig = pPage->isInit;
- int i;
- int nCell;
-
- btreeInitPage(pPage);
- nCell = pPage->nCell;
-
- for(i=0; i<nCell; i++){
- u8 *pCell = findCell(pPage, i);
- if( eType==PTRMAP_OVERFLOW1 ){
- CellInfo info;
- btreeParseCellPtr(pPage, pCell, &info);
- if( info.iOverflow
- && pCell+info.iOverflow+3<=pPage->aData+pPage->maskPage
- && iFrom==get4byte(&pCell[info.iOverflow])
- ){
- put4byte(&pCell[info.iOverflow], iTo);
- break;
- }
- }else{
- if( get4byte(pCell)==iFrom ){
- put4byte(pCell, iTo);
- break;
- }
- }
- }
-
- if( i==nCell ){
- if( eType!=PTRMAP_BTREE ||
- get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
- return SQLITE_CORRUPT_BKPT;
- }
- put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
- }
-
- pPage->isInit = isInitOrig;
- }
- return SQLITE_OK;
-}
-
-
-/*
-** Move the open database page pDbPage to location iFreePage in the
-** database. The pDbPage reference remains valid.
-**
-** The isCommit flag indicates that there is no need to remember that
-** the journal needs to be sync()ed before database page pDbPage->pgno
-** can be written to. The caller has already promised not to write to that
-** page.
-*/
-static int relocatePage(
- BtShared *pBt, /* Btree */
- MemPage *pDbPage, /* Open page to move */
- u8 eType, /* Pointer map 'type' entry for pDbPage */
- Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */
- Pgno iFreePage, /* The location to move pDbPage to */
- int isCommit /* isCommit flag passed to sqlite3PagerMovepage */
-){
- MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */
- Pgno iDbPage = pDbPage->pgno;
- Pager *pPager = pBt->pPager;
- int rc;
-
- assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 ||
- eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pDbPage->pBt==pBt );
-
- /* Move page iDbPage from its current location to page number iFreePage */
- TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
- iDbPage, iFreePage, iPtrPage, eType));
- rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pDbPage->pgno = iFreePage;
-
- /* If pDbPage was a btree-page, then it may have child pages and/or cells
- ** that point to overflow pages. The pointer map entries for all these
- ** pages need to be changed.
- **
- ** If pDbPage is an overflow page, then the first 4 bytes may store a
- ** pointer to a subsequent overflow page. If this is the case, then
- ** the pointer map needs to be updated for the subsequent overflow page.
- */
- if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){
- rc = setChildPtrmaps(pDbPage);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }else{
- Pgno nextOvfl = get4byte(pDbPage->aData);
- if( nextOvfl!=0 ){
- ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
- }
-
- /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
- ** that it points at iFreePage. Also fix the pointer map entry for
- ** iPtrPage.
- */
- if( eType!=PTRMAP_ROOTPAGE ){
- rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = sqlite3PagerWrite(pPtrPage->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(pPtrPage);
- return rc;
- }
- rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType);
- releasePage(pPtrPage);
- if( rc==SQLITE_OK ){
- ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc);
- }
- }
- return rc;
-}
-
-/* Forward declaration required by incrVacuumStep(). */
-static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
-
-/*
-** Perform a single step of an incremental-vacuum. If successful,
-** return SQLITE_OK. If there is no work to do (and therefore no
-** point in calling this function again), return SQLITE_DONE.
-**
-** More specificly, this function attempts to re-organize the
-** database so that the last page of the file currently in use
-** is no longer in use.
-**
-** If the nFin parameter is non-zero, this function assumes
-** that the caller will keep calling incrVacuumStep() until
-** it returns SQLITE_DONE or an error, and that nFin is the
-** number of pages the database file will contain after this
-** process is complete. If nFin is zero, it is assumed that
-** incrVacuumStep() will be called a finite amount of times
-** which may or may not empty the freelist. A full autovacuum
-** has nFin>0. A "PRAGMA incremental_vacuum" has nFin==0.
-*/
-static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
- Pgno nFreeList; /* Number of pages still on the free-list */
- int rc;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( iLastPg>nFin );
-
- if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){
- u8 eType;
- Pgno iPtrPage;
-
- nFreeList = get4byte(&pBt->pPage1->aData[36]);
- if( nFreeList==0 ){
- return SQLITE_DONE;
- }
-
- rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- if( eType==PTRMAP_ROOTPAGE ){
- return SQLITE_CORRUPT_BKPT;
- }
-
- if( eType==PTRMAP_FREEPAGE ){
- if( nFin==0 ){
- /* Remove the page from the files free-list. This is not required
- ** if nFin is non-zero. In that case, the free-list will be
- ** truncated to zero after this function returns, so it doesn't
- ** matter if it still contains some garbage entries.
- */
- Pgno iFreePg;
- MemPage *pFreePg;
- rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- assert( iFreePg==iLastPg );
- releasePage(pFreePg);
- }
- } else {
- Pgno iFreePg; /* Index of free page to move pLastPg to */
- MemPage *pLastPg;
-
- rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* If nFin is zero, this loop runs exactly once and page pLastPg
- ** is swapped with the first free page pulled off the free list.
- **
- ** On the other hand, if nFin is greater than zero, then keep
- ** looping until a free-page located within the first nFin pages
- ** of the file is found.
- */
- do {
- MemPage *pFreePg;
- rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, 0, 0);
- if( rc!=SQLITE_OK ){
- releasePage(pLastPg);
- return rc;
- }
- releasePage(pFreePg);
- }while( nFin!=0 && iFreePg>nFin );
- assert( iFreePg<iLastPg );
-
- rc = sqlite3PagerWrite(pLastPg->pDbPage);
- if( rc==SQLITE_OK ){
- rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
- }
- releasePage(pLastPg);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
- }
-
- if( nFin==0 ){
- iLastPg--;
- while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){
- if( PTRMAP_ISPAGE(pBt, iLastPg) ){
- MemPage *pPg;
- rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = sqlite3PagerWrite(pPg->pDbPage);
- releasePage(pPg);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
- iLastPg--;
- }
- sqlite3PagerTruncateImage(pBt->pPager, iLastPg);
- pBt->nPage = iLastPg;
- }
- return SQLITE_OK;
-}
-
-/*
-** A write-transaction must be opened before calling this function.
-** It performs a single unit of work towards an incremental vacuum.
-**
-** If the incremental vacuum is finished after this function has run,
-** SQLITE_DONE is returned. If it is not finished, but no error occurred,
-** SQLITE_OK is returned. Otherwise an SQLite error code.
-*/
-SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){
- int rc;
- BtShared *pBt = p->pBt;
-
- sqlite3BtreeEnter(p);
- assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
- if( !pBt->autoVacuum ){
- rc = SQLITE_DONE;
- }else{
- invalidateAllOverflowCache(pBt);
- rc = incrVacuumStep(pBt, 0, btreePagecount(pBt));
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
- put4byte(&pBt->pPage1->aData[28], pBt->nPage);
- }
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** This routine is called prior to sqlite3PagerCommit when a transaction
-** is commited for an auto-vacuum database.
-**
-** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
-** the database file should be truncated to during the commit process.
-** i.e. the database has been reorganized so that only the first *pnTrunc
-** pages are in use.
-*/
-static int autoVacuumCommit(BtShared *pBt){
- int rc = SQLITE_OK;
- Pager *pPager = pBt->pPager;
- VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager) );
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- invalidateAllOverflowCache(pBt);
- assert(pBt->autoVacuum);
- if( !pBt->incrVacuum ){
- Pgno nFin; /* Number of pages in database after autovacuuming */
- Pgno nFree; /* Number of pages on the freelist initially */
- Pgno nPtrmap; /* Number of PtrMap pages to be freed */
- Pgno iFree; /* The next page to be freed */
- int nEntry; /* Number of entries on one ptrmap page */
- Pgno nOrig; /* Database size before freeing */
-
- nOrig = btreePagecount(pBt);
- if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
- /* It is not possible to create a database for which the final page
- ** is either a pointer-map page or the pending-byte page. If one
- ** is encountered, this indicates corruption.
- */
- return SQLITE_CORRUPT_BKPT;
- }
-
- nFree = get4byte(&pBt->pPage1->aData[36]);
- nEntry = pBt->usableSize/5;
- nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry;
- nFin = nOrig - nFree - nPtrmap;
- if( nOrig>PENDING_BYTE_PAGE(pBt) && nFin<PENDING_BYTE_PAGE(pBt) ){
- nFin--;
- }
- while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
- nFin--;
- }
- if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
-
- for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
- rc = incrVacuumStep(pBt, nFin, iFree);
- }
- if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
- rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
- put4byte(&pBt->pPage1->aData[32], 0);
- put4byte(&pBt->pPage1->aData[36], 0);
- put4byte(&pBt->pPage1->aData[28], nFin);
- sqlite3PagerTruncateImage(pBt->pPager, nFin);
- pBt->nPage = nFin;
- }
- if( rc!=SQLITE_OK ){
- sqlite3PagerRollback(pPager);
- }
- }
-
- assert( nRef==sqlite3PagerRefcount(pPager) );
- return rc;
-}
-
-#else /* ifndef SQLITE_OMIT_AUTOVACUUM */
-# define setChildPtrmaps(x) SQLITE_OK
-#endif
-
-/*
-** This routine does the first phase of a two-phase commit. This routine
-** causes a rollback journal to be created (if it does not already exist)
-** and populated with enough information so that if a power loss occurs
-** the database can be restored to its original state by playing back
-** the journal. Then the contents of the journal are flushed out to
-** the disk. After the journal is safely on oxide, the changes to the
-** database are written into the database file and flushed to oxide.
-** At the end of this call, the rollback journal still exists on the
-** disk and we are still holding all locks, so the transaction has not
-** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the
-** commit process.
-**
-** This call is a no-op if no write-transaction is currently active on pBt.
-**
-** Otherwise, sync the database file for the btree pBt. zMaster points to
-** the name of a master journal file that should be written into the
-** individual journal file, or is NULL, indicating no master journal file
-** (single database transaction).
-**
-** When this is called, the master journal should already have been
-** created, populated with this journal pointer and synced to disk.
-**
-** Once this is routine has returned, the only thing required to commit
-** the write-transaction for this database file is to delete the journal.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
- int rc = SQLITE_OK;
- if( p->inTrans==TRANS_WRITE ){
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
- rc = autoVacuumCommit(pBt);
- if( rc!=SQLITE_OK ){
- sqlite3BtreeLeave(p);
- return rc;
- }
- }
-#endif
- rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0);
- sqlite3BtreeLeave(p);
- }
- return rc;
-}
-
-/*
-** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback()
-** at the conclusion of a transaction.
-*/
-static void btreeEndTransaction(Btree *p){
- BtShared *pBt = p->pBt;
- assert( sqlite3BtreeHoldsMutex(p) );
-
- btreeClearHasContent(pBt);
- if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){
- /* If there are other active statements that belong to this database
- ** handle, downgrade to a read-only transaction. The other statements
- ** may still be reading from the database. */
- downgradeAllSharedCacheTableLocks(p);
- p->inTrans = TRANS_READ;
- }else{
- /* If the handle had any kind of transaction open, decrement the
- ** transaction count of the shared btree. If the transaction count
- ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused()
- ** call below will unlock the pager. */
- if( p->inTrans!=TRANS_NONE ){
- clearAllSharedCacheTableLocks(p);
- pBt->nTransaction--;
- if( 0==pBt->nTransaction ){
- pBt->inTransaction = TRANS_NONE;
- }
- }
-
- /* Set the current transaction state to TRANS_NONE and unlock the
- ** pager if this call closed the only read or write transaction. */
- p->inTrans = TRANS_NONE;
- unlockBtreeIfUnused(pBt);
- }
-
- btreeIntegrity(p);
-}
-
-/*
-** Commit the transaction currently in progress.
-**
-** This routine implements the second phase of a 2-phase commit. The
-** sqlite3BtreeCommitPhaseOne() routine does the first phase and should
-** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne()
-** routine did all the work of writing information out to disk and flushing the
-** contents so that they are written onto the disk platter. All this
-** routine has to do is delete or truncate or zero the header in the
-** the rollback journal (which causes the transaction to commit) and
-** drop locks.
-**
-** Normally, if an error occurs while the pager layer is attempting to
-** finalize the underlying journal file, this function returns an error and
-** the upper layer will attempt a rollback. However, if the second argument
-** is non-zero then this b-tree transaction is part of a multi-file
-** transaction. In this case, the transaction has already been committed
-** (by deleting a master journal file) and the caller will ignore this
-** functions return code. So, even if an error occurs in the pager layer,
-** reset the b-tree objects internal state to indicate that the write
-** transaction has been closed. This is quite safe, as the pager will have
-** transitioned to the error state.
-**
-** This will release the write lock on the database file. If there
-** are no active cursors, it also releases the read lock.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){
-
- if( p->inTrans==TRANS_NONE ) return SQLITE_OK;
- sqlite3BtreeEnter(p);
- btreeIntegrity(p);
-
- /* If the handle has a write-transaction open, commit the shared-btrees
- ** transaction and set the shared state to TRANS_READ.
- */
- if( p->inTrans==TRANS_WRITE ){
- int rc;
- BtShared *pBt = p->pBt;
- assert( pBt->inTransaction==TRANS_WRITE );
- assert( pBt->nTransaction>0 );
- rc = sqlite3PagerCommitPhaseTwo(pBt->pPager);
- if( rc!=SQLITE_OK && bCleanup==0 ){
- sqlite3BtreeLeave(p);
- return rc;
- }
- pBt->inTransaction = TRANS_READ;
- }
-
- btreeEndTransaction(p);
- sqlite3BtreeLeave(p);
- return SQLITE_OK;
-}
-
-/*
-** Do both phases of a commit.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){
- int rc;
- sqlite3BtreeEnter(p);
- rc = sqlite3BtreeCommitPhaseOne(p, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeCommitPhaseTwo(p, 0);
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-#ifndef NDEBUG
-/*
-** Return the number of write-cursors open on this handle. This is for use
-** in assert() expressions, so it is only compiled if NDEBUG is not
-** defined.
-**
-** For the purposes of this routine, a write-cursor is any cursor that
-** is capable of writing to the databse. That means the cursor was
-** originally opened for writing and the cursor has not be disabled
-** by having its state changed to CURSOR_FAULT.
-*/
-static int countWriteCursors(BtShared *pBt){
- BtCursor *pCur;
- int r = 0;
- for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
- if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++;
- }
- return r;
-}
-#endif
-
-/*
-** This routine sets the state to CURSOR_FAULT and the error
-** code to errCode for every cursor on BtShared that pBtree
-** references.
-**
-** Every cursor is tripped, including cursors that belong
-** to other database connections that happen to be sharing
-** the cache with pBtree.
-**
-** This routine gets called when a rollback occurs.
-** All cursors using the same cache must be tripped
-** to prevent them from trying to use the btree after
-** the rollback. The rollback may have deleted tables
-** or moved root pages, so it is not sufficient to
-** save the state of the cursor. The cursor must be
-** invalidated.
-*/
-SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
- BtCursor *p;
- if( pBtree==0 ) return;
- sqlite3BtreeEnter(pBtree);
- for(p=pBtree->pBt->pCursor; p; p=p->pNext){
- int i;
- sqlite3BtreeClearCursor(p);
- p->eState = CURSOR_FAULT;
- p->skipNext = errCode;
- for(i=0; i<=p->iPage; i++){
- releasePage(p->apPage[i]);
- p->apPage[i] = 0;
- }
- }
- sqlite3BtreeLeave(pBtree);
-}
-
-/*
-** Rollback the transaction in progress. All cursors will be
-** invalided by this operation. Any attempt to use a cursor
-** that was open at the beginning of this operation will result
-** in an error.
-**
-** This will release the write lock on the database file. If there
-** are no active cursors, it also releases the read lock.
-*/
-SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
- int rc;
- BtShared *pBt = p->pBt;
- MemPage *pPage1;
-
- sqlite3BtreeEnter(p);
- if( tripCode==SQLITE_OK ){
- rc = tripCode = saveAllCursors(pBt, 0, 0);
- }else{
- rc = SQLITE_OK;
- }
- if( tripCode ){
- sqlite3BtreeTripAllCursors(p, tripCode);
- }
- btreeIntegrity(p);
-
- if( p->inTrans==TRANS_WRITE ){
- int rc2;
-
- assert( TRANS_WRITE==pBt->inTransaction );
- rc2 = sqlite3PagerRollback(pBt->pPager);
- if( rc2!=SQLITE_OK ){
- rc = rc2;
- }
-
- /* The rollback may have destroyed the pPage1->aData value. So
- ** call btreeGetPage() on page 1 again to make
- ** sure pPage1->aData is set correctly. */
- if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
- int nPage = get4byte(28+(u8*)pPage1->aData);
- testcase( nPage==0 );
- if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
- testcase( pBt->nPage!=nPage );
- pBt->nPage = nPage;
- releasePage(pPage1);
- }
- assert( countWriteCursors(pBt)==0 );
- pBt->inTransaction = TRANS_READ;
- }
-
- btreeEndTransaction(p);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Start a statement subtransaction. The subtransaction can can be rolled
-** back independently of the main transaction. You must start a transaction
-** before starting a subtransaction. The subtransaction is ended automatically
-** if the main transaction commits or rolls back.
-**
-** Statement subtransactions are used around individual SQL statements
-** that are contained within a BEGIN...COMMIT block. If a constraint
-** error occurs within the statement, the effect of that one statement
-** can be rolled back without having to rollback the entire transaction.
-**
-** A statement sub-transaction is implemented as an anonymous savepoint. The
-** value passed as the second parameter is the total number of savepoints,
-** including the new anonymous savepoint, open on the B-Tree. i.e. if there
-** are no active savepoints and no other statement-transactions open,
-** iStatement is 1. This anonymous savepoint can be released or rolled back
-** using the sqlite3BtreeSavepoint() function.
-*/
-SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){
- int rc;
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
- assert( p->inTrans==TRANS_WRITE );
- assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
- assert( iStatement>0 );
- assert( iStatement>p->db->nSavepoint );
- assert( pBt->inTransaction==TRANS_WRITE );
- /* At the pager level, a statement transaction is a savepoint with
- ** an index greater than all savepoints created explicitly using
- ** SQL statements. It is illegal to open, release or rollback any
- ** such savepoints while the statement transaction savepoint is active.
- */
- rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** The second argument to this function, op, is always SAVEPOINT_ROLLBACK
-** or SAVEPOINT_RELEASE. This function either releases or rolls back the
-** savepoint identified by parameter iSavepoint, depending on the value
-** of op.
-**
-** Normally, iSavepoint is greater than or equal to zero. However, if op is
-** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the
-** contents of the entire transaction are rolled back. This is different
-** from a normal transaction rollback, as no locks are released and the
-** transaction remains open.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
- int rc = SQLITE_OK;
- if( p && p->inTrans==TRANS_WRITE ){
- BtShared *pBt = p->pBt;
- assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
- assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) );
- sqlite3BtreeEnter(p);
- rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
- if( rc==SQLITE_OK ){
- if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){
- pBt->nPage = 0;
- }
- rc = newDatabase(pBt);
- pBt->nPage = get4byte(28 + pBt->pPage1->aData);
-
- /* The database size was written into the offset 28 of the header
- ** when the transaction started, so we know that the value at offset
- ** 28 is nonzero. */
- assert( pBt->nPage>0 );
- }
- sqlite3BtreeLeave(p);
- }
- return rc;
-}
-
-/*
-** Create a new cursor for the BTree whose root is on the page
-** iTable. If a read-only cursor is requested, it is assumed that
-** the caller already has at least a read-only transaction open
-** on the database already. If a write-cursor is requested, then
-** the caller is assumed to have an open write transaction.
-**
-** If wrFlag==0, then the cursor can only be used for reading.
-** If wrFlag==1, then the cursor can be used for reading or for
-** writing if other conditions for writing are also met. These
-** are the conditions that must be met in order for writing to
-** be allowed:
-**
-** 1: The cursor must have been opened with wrFlag==1
-**
-** 2: Other database connections that share the same pager cache
-** but which are not in the READ_UNCOMMITTED state may not have
-** cursors open with wrFlag==0 on the same table. Otherwise
-** the changes made by this write cursor would be visible to
-** the read cursors in the other database connection.
-**
-** 3: The database must be writable (not on read-only media)
-**
-** 4: There must be an active transaction.
-**
-** No checking is done to make sure that page iTable really is the
-** root page of a b-tree. If it is not, then the cursor acquired
-** will not work correctly.
-**
-** It is assumed that the sqlite3BtreeCursorZero() has been called
-** on pCur to initialize the memory space prior to invoking this routine.
-*/
-static int btreeCursor(
- Btree *p, /* The btree */
- int iTable, /* Root page of table to open */
- int wrFlag, /* 1 to write. 0 read-only */
- struct KeyInfo *pKeyInfo, /* First arg to comparison function */
- BtCursor *pCur /* Space for new cursor */
-){
- BtShared *pBt = p->pBt; /* Shared b-tree handle */
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( wrFlag==0 || wrFlag==1 );
-
- /* The following assert statements verify that if this is a sharable
- ** b-tree database, the connection is holding the required table locks,
- ** and that no other connection has any open cursor that conflicts with
- ** this lock. */
- assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) );
- assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
-
- /* Assert that the caller has opened the required transaction. */
- assert( p->inTrans>TRANS_NONE );
- assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
- assert( pBt->pPage1 && pBt->pPage1->aData );
-
- if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){
- return SQLITE_READONLY;
- }
- if( iTable==1 && btreePagecount(pBt)==0 ){
- assert( wrFlag==0 );
- iTable = 0;
- }
-
- /* Now that no other errors can occur, finish filling in the BtCursor
- ** variables and link the cursor into the BtShared list. */
- pCur->pgnoRoot = (Pgno)iTable;
- pCur->iPage = -1;
- pCur->pKeyInfo = pKeyInfo;
- pCur->pBtree = p;
- pCur->pBt = pBt;
- pCur->wrFlag = (u8)wrFlag;
- pCur->pNext = pBt->pCursor;
- if( pCur->pNext ){
- pCur->pNext->pPrev = pCur;
- }
- pBt->pCursor = pCur;
- pCur->eState = CURSOR_INVALID;
- pCur->cachedRowid = 0;
- return SQLITE_OK;
-}
-SQLITE_PRIVATE int sqlite3BtreeCursor(
- Btree *p, /* The btree */
- int iTable, /* Root page of table to open */
- int wrFlag, /* 1 to write. 0 read-only */
- struct KeyInfo *pKeyInfo, /* First arg to xCompare() */
- BtCursor *pCur /* Write new cursor here */
-){
- int rc;
- sqlite3BtreeEnter(p);
- rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Return the size of a BtCursor object in bytes.
-**
-** This interfaces is needed so that users of cursors can preallocate
-** sufficient storage to hold a cursor. The BtCursor object is opaque
-** to users so they cannot do the sizeof() themselves - they must call
-** this routine.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){
- return ROUND8(sizeof(BtCursor));
-}
-
-/*
-** Initialize memory that will be converted into a BtCursor object.
-**
-** The simple approach here would be to memset() the entire object
-** to zero. But it turns out that the apPage[] and aiIdx[] arrays
-** do not need to be zeroed and they are large, so we can save a lot
-** of run-time by skipping the initialization of those elements.
-*/
-SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){
- memset(p, 0, offsetof(BtCursor, iPage));
-}
-
-/*
-** Set the cached rowid value of every cursor in the same database file
-** as pCur and having the same root page number as pCur. The value is
-** set to iRowid.
-**
-** Only positive rowid values are considered valid for this cache.
-** The cache is initialized to zero, indicating an invalid cache.
-** A btree will work fine with zero or negative rowids. We just cannot
-** cache zero or negative rowids, which means tables that use zero or
-** negative rowids might run a little slower. But in practice, zero
-** or negative rowids are very uncommon so this should not be a problem.
-*/
-SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor *pCur, sqlite3_int64 iRowid){
- BtCursor *p;
- for(p=pCur->pBt->pCursor; p; p=p->pNext){
- if( p->pgnoRoot==pCur->pgnoRoot ) p->cachedRowid = iRowid;
- }
- assert( pCur->cachedRowid==iRowid );
-}
-
-/*
-** Return the cached rowid for the given cursor. A negative or zero
-** return value indicates that the rowid cache is invalid and should be
-** ignored. If the rowid cache has never before been set, then a
-** zero is returned.
-*/
-SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor *pCur){
- return pCur->cachedRowid;
-}
-
-/*
-** Close a cursor. The read lock on the database file is released
-** when the last cursor is closed.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
- Btree *pBtree = pCur->pBtree;
- if( pBtree ){
- int i;
- BtShared *pBt = pCur->pBt;
- sqlite3BtreeEnter(pBtree);
- sqlite3BtreeClearCursor(pCur);
- if( pCur->pPrev ){
- pCur->pPrev->pNext = pCur->pNext;
- }else{
- pBt->pCursor = pCur->pNext;
- }
- if( pCur->pNext ){
- pCur->pNext->pPrev = pCur->pPrev;
- }
- for(i=0; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- }
- unlockBtreeIfUnused(pBt);
- invalidateOverflowCache(pCur);
- /* sqlite3_free(pCur); */
- sqlite3BtreeLeave(pBtree);
- }
- return SQLITE_OK;
-}
-
-/*
-** Make sure the BtCursor* given in the argument has a valid
-** BtCursor.info structure. If it is not already valid, call
-** btreeParseCell() to fill it in.
-**
-** BtCursor.info is a cache of the information in the current cell.
-** Using this cache reduces the number of calls to btreeParseCell().
-**
-** 2007-06-25: There is a bug in some versions of MSVC that cause the
-** compiler to crash when getCellInfo() is implemented as a macro.
-** But there is a measureable speed advantage to using the macro on gcc
-** (when less compiler optimizations like -Os or -O0 are used and the
-** compiler is not doing agressive inlining.) So we use a real function
-** for MSVC and a macro for everything else. Ticket #2457.
-*/
-#ifndef NDEBUG
- static void assertCellInfo(BtCursor *pCur){
- CellInfo info;
- int iPage = pCur->iPage;
- memset(&info, 0, sizeof(info));
- btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
- assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
- }
-#else
- #define assertCellInfo(x)
-#endif
-#ifdef _MSC_VER
- /* Use a real function in MSVC to work around bugs in that compiler. */
- static void getCellInfo(BtCursor *pCur){
- if( pCur->info.nSize==0 ){
- int iPage = pCur->iPage;
- btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info);
- pCur->validNKey = 1;
- }else{
- assertCellInfo(pCur);
- }
- }
-#else /* if not _MSC_VER */
- /* Use a macro in all other compilers so that the function is inlined */
-#define getCellInfo(pCur) \
- if( pCur->info.nSize==0 ){ \
- int iPage = pCur->iPage; \
- btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \
- pCur->validNKey = 1; \
- }else{ \
- assertCellInfo(pCur); \
- }
-#endif /* _MSC_VER */
-
-#ifndef NDEBUG /* The next routine used only within assert() statements */
-/*
-** Return true if the given BtCursor is valid. A valid cursor is one
-** that is currently pointing to a row in a (non-empty) table.
-** This is a verification routine is used only within assert() statements.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){
- return pCur && pCur->eState==CURSOR_VALID;
-}
-#endif /* NDEBUG */
-
-/*
-** Set *pSize to the size of the buffer needed to hold the value of
-** the key for the current entry. If the cursor is not pointing
-** to a valid entry, *pSize is set to 0.
-**
-** For a table with the INTKEY flag set, this routine returns the key
-** itself, not the number of bytes in the key.
-**
-** The caller must position the cursor prior to invoking this routine.
-**
-** This routine cannot fail. It always returns SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
- if( pCur->eState!=CURSOR_VALID ){
- *pSize = 0;
- }else{
- getCellInfo(pCur);
- *pSize = pCur->info.nKey;
- }
- return SQLITE_OK;
-}
-
-/*
-** Set *pSize to the number of bytes of data in the entry the
-** cursor currently points to.
-**
-** The caller must guarantee that the cursor is pointing to a non-NULL
-** valid entry. In other words, the calling procedure must guarantee
-** that the cursor has Cursor.eState==CURSOR_VALID.
-**
-** Failure is not possible. This function always returns SQLITE_OK.
-** It might just as well be a procedure (returning void) but we continue
-** to return an integer result code for historical reasons.
-*/
-SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- getCellInfo(pCur);
- *pSize = pCur->info.nData;
- return SQLITE_OK;
-}
-
-/*
-** Given the page number of an overflow page in the database (parameter
-** ovfl), this function finds the page number of the next page in the
-** linked list of overflow pages. If possible, it uses the auto-vacuum
-** pointer-map data instead of reading the content of page ovfl to do so.
-**
-** If an error occurs an SQLite error code is returned. Otherwise:
-**
-** The page number of the next overflow page in the linked list is
-** written to *pPgnoNext. If page ovfl is the last page in its linked
-** list, *pPgnoNext is set to zero.
-**
-** If ppPage is not NULL, and a reference to the MemPage object corresponding
-** to page number pOvfl was obtained, then *ppPage is set to point to that
-** reference. It is the responsibility of the caller to call releasePage()
-** on *ppPage to free the reference. In no reference was obtained (because
-** the pointer-map was used to obtain the value for *pPgnoNext), then
-** *ppPage is set to zero.
-*/
-static int getOverflowPage(
- BtShared *pBt, /* The database file */
- Pgno ovfl, /* Current overflow page number */
- MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */
- Pgno *pPgnoNext /* OUT: Next overflow page number */
-){
- Pgno next = 0;
- MemPage *pPage = 0;
- int rc = SQLITE_OK;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert(pPgnoNext);
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
- /* Try to find the next page in the overflow list using the
- ** autovacuum pointer-map pages. Guess that the next page in
- ** the overflow list is page number (ovfl+1). If that guess turns
- ** out to be wrong, fall back to loading the data of page
- ** number ovfl to determine the next page number.
- */
- if( pBt->autoVacuum ){
- Pgno pgno;
- Pgno iGuess = ovfl+1;
- u8 eType;
-
- while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){
- iGuess++;
- }
-
- if( iGuess<=btreePagecount(pBt) ){
- rc = ptrmapGet(pBt, iGuess, &eType, &pgno);
- if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){
- next = iGuess;
- rc = SQLITE_DONE;
- }
- }
- }
-#endif
-
- assert( next==0 || rc==SQLITE_DONE );
- if( rc==SQLITE_OK ){
- rc = btreeGetPage(pBt, ovfl, &pPage, 0);
- assert( rc==SQLITE_OK || pPage==0 );
- if( rc==SQLITE_OK ){
- next = get4byte(pPage->aData);
- }
- }
-
- *pPgnoNext = next;
- if( ppPage ){
- *ppPage = pPage;
- }else{
- releasePage(pPage);
- }
- return (rc==SQLITE_DONE ? SQLITE_OK : rc);
-}
-
-/*
-** Copy data from a buffer to a page, or from a page to a buffer.
-**
-** pPayload is a pointer to data stored on database page pDbPage.
-** If argument eOp is false, then nByte bytes of data are copied
-** from pPayload to the buffer pointed at by pBuf. If eOp is true,
-** then sqlite3PagerWrite() is called on pDbPage and nByte bytes
-** of data are copied from the buffer pBuf to pPayload.
-**
-** SQLITE_OK is returned on success, otherwise an error code.
-*/
-static int copyPayload(
- void *pPayload, /* Pointer to page data */
- void *pBuf, /* Pointer to buffer */
- int nByte, /* Number of bytes to copy */
- int eOp, /* 0 -> copy from page, 1 -> copy to page */
- DbPage *pDbPage /* Page containing pPayload */
-){
- if( eOp ){
- /* Copy data from buffer to page (a write operation) */
- int rc = sqlite3PagerWrite(pDbPage);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- memcpy(pPayload, pBuf, nByte);
- }else{
- /* Copy data from page to buffer (a read operation) */
- memcpy(pBuf, pPayload, nByte);
- }
- return SQLITE_OK;
-}
-
-/*
-** This function is used to read or overwrite payload information
-** for the entry that the pCur cursor is pointing to. If the eOp
-** parameter is 0, this is a read operation (data copied into
-** buffer pBuf). If it is non-zero, a write (data copied from
-** buffer pBuf).
-**
-** A total of "amt" bytes are read or written beginning at "offset".
-** Data is read to or from the buffer pBuf.
-**
-** The content being read or written might appear on the main page
-** or be scattered out on multiple overflow pages.
-**
-** If the BtCursor.isIncrblobHandle flag is set, and the current
-** cursor entry uses one or more overflow pages, this function
-** allocates space for and lazily popluates the overflow page-list
-** cache array (BtCursor.aOverflow). Subsequent calls use this
-** cache to make seeking to the supplied offset more efficient.
-**
-** Once an overflow page-list cache has been allocated, it may be
-** invalidated if some other cursor writes to the same table, or if
-** the cursor is moved to a different row. Additionally, in auto-vacuum
-** mode, the following events may invalidate an overflow page-list cache.
-**
-** * An incremental vacuum,
-** * A commit in auto_vacuum="full" mode,
-** * Creating a table (may require moving an overflow page).
-*/
-static int accessPayload(
- BtCursor *pCur, /* Cursor pointing to entry to read from */
- u32 offset, /* Begin reading this far into payload */
- u32 amt, /* Read this many bytes */
- unsigned char *pBuf, /* Write the bytes into this buffer */
- int eOp /* zero to read. non-zero to write. */
-){
- unsigned char *aPayload;
- int rc = SQLITE_OK;
- u32 nKey;
- int iIdx = 0;
- MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
- BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
-
- assert( pPage );
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
- assert( cursorHoldsMutex(pCur) );
-
- getCellInfo(pCur);
- aPayload = pCur->info.pCell + pCur->info.nHeader;
- nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
-
- if( NEVER(offset+amt > nKey+pCur->info.nData)
- || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
- ){
- /* Trying to read or write past the end of the data is an error */
- return SQLITE_CORRUPT_BKPT;
- }
-
- /* Check if data must be read/written to/from the btree page itself. */
- if( offset<pCur->info.nLocal ){
- int a = amt;
- if( a+offset>pCur->info.nLocal ){
- a = pCur->info.nLocal - offset;
- }
- rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
- offset = 0;
- pBuf += a;
- amt -= a;
- }else{
- offset -= pCur->info.nLocal;
- }
-
- if( rc==SQLITE_OK && amt>0 ){
- const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */
- Pgno nextPage;
-
- nextPage = get4byte(&aPayload[pCur->info.nLocal]);
-
-#ifndef SQLITE_OMIT_INCRBLOB
- /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[]
- ** has not been allocated, allocate it now. The array is sized at
- ** one entry for each overflow page in the overflow chain. The
- ** page number of the first overflow page is stored in aOverflow[0],
- ** etc. A value of 0 in the aOverflow[] array means "not yet known"
- ** (the cache is lazily populated).
- */
- if( pCur->isIncrblobHandle && !pCur->aOverflow ){
- int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
- pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl);
- /* nOvfl is always positive. If it were zero, fetchPayload would have
- ** been used instead of this routine. */
- if( ALWAYS(nOvfl) && !pCur->aOverflow ){
- rc = SQLITE_NOMEM;
- }
- }
-
- /* If the overflow page-list cache has been allocated and the
- ** entry for the first required overflow page is valid, skip
- ** directly to it.
- */
- if( pCur->aOverflow && pCur->aOverflow[offset/ovflSize] ){
- iIdx = (offset/ovflSize);
- nextPage = pCur->aOverflow[iIdx];
- offset = (offset%ovflSize);
- }
-#endif
-
- for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){
-
-#ifndef SQLITE_OMIT_INCRBLOB
- /* If required, populate the overflow page-list cache. */
- if( pCur->aOverflow ){
- assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage);
- pCur->aOverflow[iIdx] = nextPage;
- }
-#endif
-
- if( offset>=ovflSize ){
- /* The only reason to read this page is to obtain the page
- ** number for the next page in the overflow chain. The page
- ** data is not required. So first try to lookup the overflow
- ** page-list cache, if any, then fall back to the getOverflowPage()
- ** function.
- */
-#ifndef SQLITE_OMIT_INCRBLOB
- if( pCur->aOverflow && pCur->aOverflow[iIdx+1] ){
- nextPage = pCur->aOverflow[iIdx+1];
- } else
-#endif
- rc = getOverflowPage(pBt, nextPage, 0, &nextPage);
- offset -= ovflSize;
- }else{
- /* Need to read this page properly. It contains some of the
- ** range of data that is being read (eOp==0) or written (eOp!=0).
- */
-#ifdef SQLITE_DIRECT_OVERFLOW_READ
- sqlite3_file *fd;
-#endif
- int a = amt;
- if( a + offset > ovflSize ){
- a = ovflSize - offset;
- }
-
-#ifdef SQLITE_DIRECT_OVERFLOW_READ
- /* If all the following are true:
- **
- ** 1) this is a read operation, and
- ** 2) data is required from the start of this overflow page, and
- ** 3) the database is file-backed, and
- ** 4) there is no open write-transaction, and
- ** 5) the database is not a WAL database,
- **
- ** then data can be read directly from the database file into the
- ** output buffer, bypassing the page-cache altogether. This speeds
- ** up loading large records that span many overflow pages.
- */
- if( eOp==0 /* (1) */
- && offset==0 /* (2) */
- && pBt->inTransaction==TRANS_READ /* (4) */
- && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
- && pBt->pPage1->aData[19]==0x01 /* (5) */
- ){
- u8 aSave[4];
- u8 *aWrite = &pBuf[-4];
- memcpy(aSave, aWrite, 4);
- rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
- nextPage = get4byte(aWrite);
- memcpy(aWrite, aSave, 4);
- }else
-#endif
-
- {
- DbPage *pDbPage;
- rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
- if( rc==SQLITE_OK ){
- aPayload = sqlite3PagerGetData(pDbPage);
- nextPage = get4byte(aPayload);
- rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
- sqlite3PagerUnref(pDbPage);
- offset = 0;
- }
- }
- amt -= a;
- pBuf += a;
- }
- }
- }
-
- if( rc==SQLITE_OK && amt>0 ){
- return SQLITE_CORRUPT_BKPT;
- }
- return rc;
-}
-
-/*
-** Read part of the key associated with cursor pCur. Exactly
-** "amt" bytes will be transfered into pBuf[]. The transfer
-** begins at "offset".
-**
-** The caller must ensure that pCur is pointing to a valid row
-** in the table.
-**
-** Return SQLITE_OK on success or an error code if anything goes
-** wrong. An error is returned if "offset+amt" is larger than
-** the available payload.
-*/
-SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
- return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
-}
-
-/*
-** Read part of the data associated with cursor pCur. Exactly
-** "amt" bytes will be transfered into pBuf[]. The transfer
-** begins at "offset".
-**
-** Return SQLITE_OK on success or an error code if anything goes
-** wrong. An error is returned if "offset+amt" is larger than
-** the available payload.
-*/
-SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
- int rc;
-
-#ifndef SQLITE_OMIT_INCRBLOB
- if ( pCur->eState==CURSOR_INVALID ){
- return SQLITE_ABORT;
- }
-#endif
-
- assert( cursorHoldsMutex(pCur) );
- rc = restoreCursorPosition(pCur);
- if( rc==SQLITE_OK ){
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
- rc = accessPayload(pCur, offset, amt, pBuf, 0);
- }
- return rc;
-}
-
-/*
-** Return a pointer to payload information from the entry that the
-** pCur cursor is pointing to. The pointer is to the beginning of
-** the key if skipKey==0 and it points to the beginning of data if
-** skipKey==1. The number of bytes of available key/data is written
-** into *pAmt. If *pAmt==0, then the value returned will not be
-** a valid pointer.
-**
-** This routine is an optimization. It is common for the entire key
-** and data to fit on the local page and for there to be no overflow
-** pages. When that is so, this routine can be used to access the
-** key and data without making a copy. If the key and/or data spills
-** onto overflow pages, then accessPayload() must be used to reassemble
-** the key/data and copy it into a preallocated buffer.
-**
-** The pointer returned by this routine looks directly into the cached
-** page of the database. The data might change or move the next time
-** any btree routine is called.
-*/
-static const unsigned char *fetchPayload(
- BtCursor *pCur, /* Cursor pointing to entry to read from */
- int *pAmt, /* Write the number of available bytes here */
- int skipKey /* read beginning at data if this is true */
-){
- unsigned char *aPayload;
- MemPage *pPage;
- u32 nKey;
- u32 nLocal;
-
- assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
- assert( pCur->eState==CURSOR_VALID );
- assert( cursorHoldsMutex(pCur) );
- pPage = pCur->apPage[pCur->iPage];
- assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
- if( NEVER(pCur->info.nSize==0) ){
- btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
- &pCur->info);
- }
- aPayload = pCur->info.pCell;
- aPayload += pCur->info.nHeader;
- if( pPage->intKey ){
- nKey = 0;
- }else{
- nKey = (int)pCur->info.nKey;
- }
- if( skipKey ){
- aPayload += nKey;
- nLocal = pCur->info.nLocal - nKey;
- }else{
- nLocal = pCur->info.nLocal;
- assert( nLocal<=nKey );
- }
- *pAmt = nLocal;
- return aPayload;
-}
-
-
-/*
-** For the entry that cursor pCur is point to, return as
-** many bytes of the key or data as are available on the local
-** b-tree page. Write the number of available bytes into *pAmt.
-**
-** The pointer returned is ephemeral. The key/data may move
-** or be destroyed on the next call to any Btree routine,
-** including calls from other threads against the same cache.
-** Hence, a mutex on the BtShared should be held prior to calling
-** this routine.
-**
-** These routines is used to get quick access to key and data
-** in the common case where no overflow pages are used.
-*/
-SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
- const void *p = 0;
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert( cursorHoldsMutex(pCur) );
- if( ALWAYS(pCur->eState==CURSOR_VALID) ){
- p = (const void*)fetchPayload(pCur, pAmt, 0);
- }
- return p;
-}
-SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
- const void *p = 0;
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert( cursorHoldsMutex(pCur) );
- if( ALWAYS(pCur->eState==CURSOR_VALID) ){
- p = (const void*)fetchPayload(pCur, pAmt, 1);
- }
- return p;
-}
-
-
-/*
-** Move the cursor down to a new child page. The newPgno argument is the
-** page number of the child page to move to.
-**
-** This function returns SQLITE_CORRUPT if the page-header flags field of
-** the new child page does not match the flags field of the parent (i.e.
-** if an intkey page appears to be the parent of a non-intkey page, or
-** vice-versa).
-*/
-static int moveToChild(BtCursor *pCur, u32 newPgno){
- int rc;
- int i = pCur->iPage;
- MemPage *pNewPage;
- BtShared *pBt = pCur->pBt;
-
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
- if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
- return SQLITE_CORRUPT_BKPT;
- }
- rc = getAndInitPage(pBt, newPgno, &pNewPage);
- if( rc ) return rc;
- pCur->apPage[i+1] = pNewPage;
- pCur->aiIdx[i+1] = 0;
- pCur->iPage++;
-
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){
- return SQLITE_CORRUPT_BKPT;
- }
- return SQLITE_OK;
-}
-
-#if 0
-/*
-** Page pParent is an internal (non-leaf) tree page. This function
-** asserts that page number iChild is the left-child if the iIdx'th
-** cell in page pParent. Or, if iIdx is equal to the total number of
-** cells in pParent, that page number iChild is the right-child of
-** the page.
-*/
-static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
- assert( iIdx<=pParent->nCell );
- if( iIdx==pParent->nCell ){
- assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild );
- }else{
- assert( get4byte(findCell(pParent, iIdx))==iChild );
- }
-}
-#else
-# define assertParentIndex(x,y,z)
-#endif
-
-/*
-** Move the cursor up to the parent page.
-**
-** pCur->idx is set to the cell index that contains the pointer
-** to the page we are coming from. If we are coming from the
-** right-most child page then pCur->idx is set to one more than
-** the largest cell index.
-*/
-static void moveToParent(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>0 );
- assert( pCur->apPage[pCur->iPage] );
-
- /* UPDATE: It is actually possible for the condition tested by the assert
- ** below to be untrue if the database file is corrupt. This can occur if
- ** one cursor has modified page pParent while a reference to it is held
- ** by a second cursor. Which can only happen if a single page is linked
- ** into more than one b-tree structure in a corrupt database. */
-#if 0
- assertParentIndex(
- pCur->apPage[pCur->iPage-1],
- pCur->aiIdx[pCur->iPage-1],
- pCur->apPage[pCur->iPage]->pgno
- );
-#endif
- testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
-
- releasePage(pCur->apPage[pCur->iPage]);
- pCur->iPage--;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
-}
-
-/*
-** Move the cursor to point to the root page of its b-tree structure.
-**
-** If the table has a virtual root page, then the cursor is moved to point
-** to the virtual root page instead of the actual root page. A table has a
-** virtual root page when the actual root page contains no cells and a
-** single child page. This can only happen with the table rooted at page 1.
-**
-** If the b-tree structure is empty, the cursor state is set to
-** CURSOR_INVALID. Otherwise, the cursor is set to point to the first
-** cell located on the root (or virtual root) page and the cursor state
-** is set to CURSOR_VALID.
-**
-** If this function returns successfully, it may be assumed that the
-** page-header flags indicate that the [virtual] root-page is the expected
-** kind of b-tree page (i.e. if when opening the cursor the caller did not
-** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D,
-** indicating a table b-tree, or if the caller did specify a KeyInfo
-** structure the flags byte is set to 0x02 or 0x0A, indicating an index
-** b-tree).
-*/
-static int moveToRoot(BtCursor *pCur){
- MemPage *pRoot;
- int rc = SQLITE_OK;
- Btree *p = pCur->pBtree;
- BtShared *pBt = p->pBt;
-
- assert( cursorHoldsMutex(pCur) );
- assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
- assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
- assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
- if( pCur->eState>=CURSOR_REQUIRESEEK ){
- if( pCur->eState==CURSOR_FAULT ){
- assert( pCur->skipNext!=SQLITE_OK );
- return pCur->skipNext;
- }
- sqlite3BtreeClearCursor(pCur);
- }
-
- if( pCur->iPage>=0 ){
- int i;
- for(i=1; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- }
- pCur->iPage = 0;
- }else if( pCur->pgnoRoot==0 ){
- pCur->eState = CURSOR_INVALID;
- return SQLITE_OK;
- }else{
- rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]);
- if( rc!=SQLITE_OK ){
- pCur->eState = CURSOR_INVALID;
- return rc;
- }
- pCur->iPage = 0;
-
- /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
- ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
- ** NULL, the caller expects a table b-tree. If this is not the case,
- ** return an SQLITE_CORRUPT error. */
- assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 );
- if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){
- return SQLITE_CORRUPT_BKPT;
- }
- }
-
- /* Assert that the root page is of the correct type. This must be the
- ** case as the call to this function that loaded the root-page (either
- ** this call or a previous invocation) would have detected corruption
- ** if the assumption were not true, and it is not possible for the flags
- ** byte to have been modified while this cursor is holding a reference
- ** to the page. */
- pRoot = pCur->apPage[0];
- assert( pRoot->pgno==pCur->pgnoRoot );
- assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey );
-
- pCur->aiIdx[0] = 0;
- pCur->info.nSize = 0;
- pCur->atLast = 0;
- pCur->validNKey = 0;
-
- if( pRoot->nCell==0 && !pRoot->leaf ){
- Pgno subpage;
- if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
- subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
- pCur->eState = CURSOR_VALID;
- rc = moveToChild(pCur, subpage);
- }else{
- pCur->eState = ((pRoot->nCell>0)?CURSOR_VALID:CURSOR_INVALID);
- }
- return rc;
-}
-
-/*
-** Move the cursor down to the left-most leaf entry beneath the
-** entry to which it is currently pointing.
-**
-** The left-most leaf is the one with the smallest key - the first
-** in ascending order.
-*/
-static int moveToLeftmost(BtCursor *pCur){
- Pgno pgno;
- int rc = SQLITE_OK;
- MemPage *pPage;
-
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
- assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
- pgno = get4byte(findCell(pPage, pCur->aiIdx[pCur->iPage]));
- rc = moveToChild(pCur, pgno);
- }
- return rc;
-}
-
-/*
-** Move the cursor down to the right-most leaf entry beneath the
-** page to which it is currently pointing. Notice the difference
-** between moveToLeftmost() and moveToRightmost(). moveToLeftmost()
-** finds the left-most entry beneath the *entry* whereas moveToRightmost()
-** finds the right-most entry beneath the *page*.
-**
-** The right-most entry is the one with the largest key - the last
-** key in ascending order.
-*/
-static int moveToRightmost(BtCursor *pCur){
- Pgno pgno;
- int rc = SQLITE_OK;
- MemPage *pPage = 0;
-
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->eState==CURSOR_VALID );
- while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
- pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- pCur->aiIdx[pCur->iPage] = pPage->nCell;
- rc = moveToChild(pCur, pgno);
- }
- if( rc==SQLITE_OK ){
- pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- }
- return rc;
-}
-
-/* Move the cursor to the first entry in the table. Return SQLITE_OK
-** on success. Set *pRes to 0 if the cursor actually points to something
-** or set *pRes to 1 if the table is empty.
-*/
-SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
- int rc;
-
- assert( cursorHoldsMutex(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- rc = moveToRoot(pCur);
- if( rc==SQLITE_OK ){
- if( pCur->eState==CURSOR_INVALID ){
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
- *pRes = 1;
- }else{
- assert( pCur->apPage[pCur->iPage]->nCell>0 );
- *pRes = 0;
- rc = moveToLeftmost(pCur);
- }
- }
- return rc;
-}
-
-/* Move the cursor to the last entry in the table. Return SQLITE_OK
-** on success. Set *pRes to 0 if the cursor actually points to something
-** or set *pRes to 1 if the table is empty.
-*/
-SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
- int rc;
-
- assert( cursorHoldsMutex(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
-
- /* If the cursor already points to the last entry, this is a no-op. */
- if( CURSOR_VALID==pCur->eState && pCur->atLast ){
-#ifdef SQLITE_DEBUG
- /* This block serves to assert() that the cursor really does point
- ** to the last entry in the b-tree. */
- int ii;
- for(ii=0; ii<pCur->iPage; ii++){
- assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
- }
- assert( pCur->aiIdx[pCur->iPage]==pCur->apPage[pCur->iPage]->nCell-1 );
- assert( pCur->apPage[pCur->iPage]->leaf );
-#endif
- return SQLITE_OK;
- }
-
- rc = moveToRoot(pCur);
- if( rc==SQLITE_OK ){
- if( CURSOR_INVALID==pCur->eState ){
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
- *pRes = 1;
- }else{
- assert( pCur->eState==CURSOR_VALID );
- *pRes = 0;
- rc = moveToRightmost(pCur);
- pCur->atLast = rc==SQLITE_OK ?1:0;
- }
- }
- return rc;
-}
-
-/* Move the cursor so that it points to an entry near the key
-** specified by pIdxKey or intKey. Return a success code.
-**
-** For INTKEY tables, the intKey parameter is used. pIdxKey
-** must be NULL. For index tables, pIdxKey is used and intKey
-** is ignored.
-**
-** If an exact match is not found, then the cursor is always
-** left pointing at a leaf page which would hold the entry if it
-** were present. The cursor might point to an entry that comes
-** before or after the key.
-**
-** An integer is written into *pRes which is the result of
-** comparing the key with the entry to which the cursor is
-** pointing. The meaning of the integer written into
-** *pRes is as follows:
-**
-** *pRes<0 The cursor is left pointing at an entry that
-** is smaller than intKey/pIdxKey or if the table is empty
-** and the cursor is therefore left point to nothing.
-**
-** *pRes==0 The cursor is left pointing at an entry that
-** exactly matches intKey/pIdxKey.
-**
-** *pRes>0 The cursor is left pointing at an entry that
-** is larger than intKey/pIdxKey.
-**
-*/
-SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
- BtCursor *pCur, /* The cursor to be moved */
- UnpackedRecord *pIdxKey, /* Unpacked index key */
- i64 intKey, /* The table key */
- int biasRight, /* If true, bias the search to the high end */
- int *pRes /* Write search results here */
-){
- int rc;
-
- assert( cursorHoldsMutex(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert( pRes );
- assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
-
- /* If the cursor is already positioned at the point we are trying
- ** to move to, then just return without doing any work */
- if( pCur->eState==CURSOR_VALID && pCur->validNKey
- && pCur->apPage[0]->intKey
- ){
- if( pCur->info.nKey==intKey ){
- *pRes = 0;
- return SQLITE_OK;
- }
- if( pCur->atLast && pCur->info.nKey<intKey ){
- *pRes = -1;
- return SQLITE_OK;
- }
- }
-
- rc = moveToRoot(pCur);
- if( rc ){
- return rc;
- }
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] );
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit );
- assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 );
- if( pCur->eState==CURSOR_INVALID ){
- *pRes = -1;
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
- return SQLITE_OK;
- }
- assert( pCur->apPage[0]->intKey || pIdxKey );
- for(;;){
- int lwr, upr, idx;
- Pgno chldPg;
- MemPage *pPage = pCur->apPage[pCur->iPage];
- int c;
-
- /* pPage->nCell must be greater than zero. If this is the root-page
- ** the cursor would have been INVALID above and this for(;;) loop
- ** not run. If this is not the root-page, then the moveToChild() routine
- ** would have already detected db corruption. Similarly, pPage must
- ** be the right kind (index or table) of b-tree page. Otherwise
- ** a moveToChild() or moveToRoot() call would have detected corruption. */
- assert( pPage->nCell>0 );
- assert( pPage->intKey==(pIdxKey==0) );
- lwr = 0;
- upr = pPage->nCell-1;
- if( biasRight ){
- pCur->aiIdx[pCur->iPage] = (u16)(idx = upr);
- }else{
- pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2);
- }
- for(;;){
- u8 *pCell; /* Pointer to current cell in pPage */
-
- assert( idx==pCur->aiIdx[pCur->iPage] );
- pCur->info.nSize = 0;
- pCell = findCell(pPage, idx) + pPage->childPtrSize;
- if( pPage->intKey ){
- i64 nCellKey;
- if( pPage->hasData ){
- u32 dummy;
- pCell += getVarint32(pCell, dummy);
- }
- getVarint(pCell, (u64*)&nCellKey);
- if( nCellKey==intKey ){
- c = 0;
- }else if( nCellKey<intKey ){
- c = -1;
- }else{
- assert( nCellKey>intKey );
- c = +1;
- }
- pCur->validNKey = 1;
- pCur->info.nKey = nCellKey;
- }else{
- /* The maximum supported page-size is 65536 bytes. This means that
- ** the maximum number of record bytes stored on an index B-Tree
- ** page is less than 16384 bytes and may be stored as a 2-byte
- ** varint. This information is used to attempt to avoid parsing
- ** the entire cell by checking for the cases where the record is
- ** stored entirely within the b-tree page by inspecting the first
- ** 2 bytes of the cell.
- */
- int nCell = pCell[0];
- if( nCell<=pPage->max1bytePayload
- /* && (pCell+nCell)<pPage->aDataEnd */
- ){
- /* This branch runs if the record-size field of the cell is a
- ** single byte varint and the record fits entirely on the main
- ** b-tree page. */
- testcase( pCell+nCell+1==pPage->aDataEnd );
- c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
- }else if( !(pCell[1] & 0x80)
- && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
- /* && (pCell+nCell+2)<=pPage->aDataEnd */
- ){
- /* The record-size field is a 2 byte varint and the record
- ** fits entirely on the main b-tree page. */
- testcase( pCell+nCell+2==pPage->aDataEnd );
- c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
- }else{
- /* The record flows over onto one or more overflow pages. In
- ** this case the whole cell needs to be parsed, a buffer allocated
- ** and accessPayload() used to retrieve the record into the
- ** buffer before VdbeRecordCompare() can be called. */
- void *pCellKey;
- u8 * const pCellBody = pCell - pPage->childPtrSize;
- btreeParseCellPtr(pPage, pCellBody, &pCur->info);
- nCell = (int)pCur->info.nKey;
- pCellKey = sqlite3Malloc( nCell );
- if( pCellKey==0 ){
- rc = SQLITE_NOMEM;
- goto moveto_finish;
- }
- rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
- if( rc ){
- sqlite3_free(pCellKey);
- goto moveto_finish;
- }
- c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
- sqlite3_free(pCellKey);
- }
- }
- if( c==0 ){
- if( pPage->intKey && !pPage->leaf ){
- lwr = idx;
- break;
- }else{
- *pRes = 0;
- rc = SQLITE_OK;
- goto moveto_finish;
- }
- }
- if( c<0 ){
- lwr = idx+1;
- }else{
- upr = idx-1;
- }
- if( lwr>upr ){
- break;
- }
- pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2);
- }
- assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
- assert( pPage->isInit );
- if( pPage->leaf ){
- chldPg = 0;
- }else if( lwr>=pPage->nCell ){
- chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- }else{
- chldPg = get4byte(findCell(pPage, lwr));
- }
- if( chldPg==0 ){
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
- *pRes = c;
- rc = SQLITE_OK;
- goto moveto_finish;
- }
- pCur->aiIdx[pCur->iPage] = (u16)lwr;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- rc = moveToChild(pCur, chldPg);
- if( rc ) goto moveto_finish;
- }
-moveto_finish:
- return rc;
-}
-
-
-/*
-** Return TRUE if the cursor is not pointing at an entry of the table.
-**
-** TRUE will be returned after a call to sqlite3BtreeNext() moves
-** past the last entry in the table or sqlite3BtreePrev() moves past
-** the first entry. TRUE is also returned if the table is empty.
-*/
-SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
- /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
- ** have been deleted? This API will need to change to return an error code
- ** as well as the boolean result value.
- */
- return (CURSOR_VALID!=pCur->eState);
-}
-
-/*
-** Advance the cursor to the next entry in the database. If
-** successful then set *pRes=0. If the cursor
-** was already pointing to the last entry in the database before
-** this routine was called, then set *pRes=1.
-*/
-SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
- int rc;
- int idx;
- MemPage *pPage;
-
- assert( cursorHoldsMutex(pCur) );
- rc = restoreCursorPosition(pCur);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- assert( pRes!=0 );
- if( CURSOR_INVALID==pCur->eState ){
- *pRes = 1;
- return SQLITE_OK;
- }
- if( pCur->skipNext>0 ){
- pCur->skipNext = 0;
- *pRes = 0;
- return SQLITE_OK;
- }
- pCur->skipNext = 0;
-
- pPage = pCur->apPage[pCur->iPage];
- idx = ++pCur->aiIdx[pCur->iPage];
- assert( pPage->isInit );
-
- /* If the database file is corrupt, it is possible for the value of idx
- ** to be invalid here. This can only occur if a second cursor modifies
- ** the page while cursor pCur is holding a reference to it. Which can
- ** only happen if the database is corrupt in such a way as to link the
- ** page into more than one b-tree structure. */
- testcase( idx>pPage->nCell );
-
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- if( idx>=pPage->nCell ){
- if( !pPage->leaf ){
- rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
- if( rc ) return rc;
- rc = moveToLeftmost(pCur);
- *pRes = 0;
- return rc;
- }
- do{
- if( pCur->iPage==0 ){
- *pRes = 1;
- pCur->eState = CURSOR_INVALID;
- return SQLITE_OK;
- }
- moveToParent(pCur);
- pPage = pCur->apPage[pCur->iPage];
- }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
- *pRes = 0;
- if( pPage->intKey ){
- rc = sqlite3BtreeNext(pCur, pRes);
- }else{
- rc = SQLITE_OK;
- }
- return rc;
- }
- *pRes = 0;
- if( pPage->leaf ){
- return SQLITE_OK;
- }
- rc = moveToLeftmost(pCur);
- return rc;
-}
-
-
-/*
-** Step the cursor to the back to the previous entry in the database. If
-** successful then set *pRes=0. If the cursor
-** was already pointing to the first entry in the database before
-** this routine was called, then set *pRes=1.
-*/
-SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
- int rc;
- MemPage *pPage;
-
- assert( cursorHoldsMutex(pCur) );
- rc = restoreCursorPosition(pCur);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pCur->atLast = 0;
- if( CURSOR_INVALID==pCur->eState ){
- *pRes = 1;
- return SQLITE_OK;
- }
- if( pCur->skipNext<0 ){
- pCur->skipNext = 0;
- *pRes = 0;
- return SQLITE_OK;
- }
- pCur->skipNext = 0;
-
- pPage = pCur->apPage[pCur->iPage];
- assert( pPage->isInit );
- if( !pPage->leaf ){
- int idx = pCur->aiIdx[pCur->iPage];
- rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
- if( rc ){
- return rc;
- }
- rc = moveToRightmost(pCur);
- }else{
- while( pCur->aiIdx[pCur->iPage]==0 ){
- if( pCur->iPage==0 ){
- pCur->eState = CURSOR_INVALID;
- *pRes = 1;
- return SQLITE_OK;
- }
- moveToParent(pCur);
- }
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
-
- pCur->aiIdx[pCur->iPage]--;
- pPage = pCur->apPage[pCur->iPage];
- if( pPage->intKey && !pPage->leaf ){
- rc = sqlite3BtreePrevious(pCur, pRes);
- }else{
- rc = SQLITE_OK;
- }
- }
- *pRes = 0;
- return rc;
-}
-
-/*
-** Allocate a new page from the database file.
-**
-** The new page is marked as dirty. (In other words, sqlite3PagerWrite()
-** has already been called on the new page.) The new page has also
-** been referenced and the calling routine is responsible for calling
-** sqlite3PagerUnref() on the new page when it is done.
-**
-** SQLITE_OK is returned on success. Any other return value indicates
-** an error. *ppPage and *pPgno are undefined in the event of an error.
-** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned.
-**
-** If the "nearby" parameter is not 0, then a (feeble) effort is made to
-** locate a page close to the page number "nearby". This can be used in an
-** attempt to keep related pages close to each other in the database file,
-** which in turn can make database access faster.
-**
-** If the "exact" parameter is not 0, and the page-number nearby exists
-** anywhere on the free-list, then it is guarenteed to be returned. This
-** is only used by auto-vacuum databases when allocating a new table.
-*/
-static int allocateBtreePage(
- BtShared *pBt,
- MemPage **ppPage,
- Pgno *pPgno,
- Pgno nearby,
- u8 exact
-){
- MemPage *pPage1;
- int rc;
- u32 n; /* Number of pages on the freelist */
- u32 k; /* Number of leaves on the trunk of the freelist */
- MemPage *pTrunk = 0;
- MemPage *pPrevTrunk = 0;
- Pgno mxPage; /* Total size of the database file */
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- pPage1 = pBt->pPage1;
- mxPage = btreePagecount(pBt);
- n = get4byte(&pPage1->aData[36]);
- testcase( n==mxPage-1 );
- if( n>=mxPage ){
- return SQLITE_CORRUPT_BKPT;
- }
- if( n>0 ){
- /* There are pages on the freelist. Reuse one of those pages. */
- Pgno iTrunk;
- u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
-
- /* If the 'exact' parameter was true and a query of the pointer-map
- ** shows that the page 'nearby' is somewhere on the free-list, then
- ** the entire-list will be searched for that page.
- */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( exact && nearby<=mxPage ){
- u8 eType;
- assert( nearby>0 );
- assert( pBt->autoVacuum );
- rc = ptrmapGet(pBt, nearby, &eType, 0);
- if( rc ) return rc;
- if( eType==PTRMAP_FREEPAGE ){
- searchList = 1;
- }
- *pPgno = nearby;
- }
-#endif
-
- /* Decrement the free-list count by 1. Set iTrunk to the index of the
- ** first free-list trunk page. iPrevTrunk is initially 1.
- */
- rc = sqlite3PagerWrite(pPage1->pDbPage);
- if( rc ) return rc;
- put4byte(&pPage1->aData[36], n-1);
-
- /* The code within this loop is run only once if the 'searchList' variable
- ** is not true. Otherwise, it runs once for each trunk-page on the
- ** free-list until the page 'nearby' is located.
- */
- do {
- pPrevTrunk = pTrunk;
- if( pPrevTrunk ){
- iTrunk = get4byte(&pPrevTrunk->aData[0]);
- }else{
- iTrunk = get4byte(&pPage1->aData[32]);
- }
- testcase( iTrunk==mxPage );
- if( iTrunk>mxPage ){
- rc = SQLITE_CORRUPT_BKPT;
- }else{
- rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
- }
- if( rc ){
- pTrunk = 0;
- goto end_allocate_page;
- }
- assert( pTrunk!=0 );
- assert( pTrunk->aData!=0 );
-
- k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
- if( k==0 && !searchList ){
- /* The trunk has no leaves and the list is not being searched.
- ** So extract the trunk page itself and use it as the newly
- ** allocated page */
- assert( pPrevTrunk==0 );
- rc = sqlite3PagerWrite(pTrunk->pDbPage);
- if( rc ){
- goto end_allocate_page;
- }
- *pPgno = iTrunk;
- memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
- *ppPage = pTrunk;
- pTrunk = 0;
- TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
- }else if( k>(u32)(pBt->usableSize/4 - 2) ){
- /* Value of k is out of range. Database corruption */
- rc = SQLITE_CORRUPT_BKPT;
- goto end_allocate_page;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- }else if( searchList && nearby==iTrunk ){
- /* The list is being searched and this trunk page is the page
- ** to allocate, regardless of whether it has leaves.
- */
- assert( *pPgno==iTrunk );
- *ppPage = pTrunk;
- searchList = 0;
- rc = sqlite3PagerWrite(pTrunk->pDbPage);
- if( rc ){
- goto end_allocate_page;
- }
- if( k==0 ){
- if( !pPrevTrunk ){
- memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
- }else{
- rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
- if( rc!=SQLITE_OK ){
- goto end_allocate_page;
- }
- memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4);
- }
- }else{
- /* The trunk page is required by the caller but it contains
- ** pointers to free-list leaves. The first leaf becomes a trunk
- ** page in this case.
- */
- MemPage *pNewTrunk;
- Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
- if( iNewTrunk>mxPage ){
- rc = SQLITE_CORRUPT_BKPT;
- goto end_allocate_page;
- }
- testcase( iNewTrunk==mxPage );
- rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
- if( rc!=SQLITE_OK ){
- goto end_allocate_page;
- }
- rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(pNewTrunk);
- goto end_allocate_page;
- }
- memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4);
- put4byte(&pNewTrunk->aData[4], k-1);
- memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
- releasePage(pNewTrunk);
- if( !pPrevTrunk ){
- assert( sqlite3PagerIswriteable(pPage1->pDbPage) );
- put4byte(&pPage1->aData[32], iNewTrunk);
- }else{
- rc = sqlite3PagerWrite(pPrevTrunk->pDbPage);
- if( rc ){
- goto end_allocate_page;
- }
- put4byte(&pPrevTrunk->aData[0], iNewTrunk);
- }
- }
- pTrunk = 0;
- TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
-#endif
- }else if( k>0 ){
- /* Extract a leaf from the trunk */
- u32 closest;
- Pgno iPage;
- unsigned char *aData = pTrunk->aData;
- if( nearby>0 ){
- u32 i;
- int dist;
- closest = 0;
- dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby);
- for(i=1; i<k; i++){
- int d2 = sqlite3AbsInt32(get4byte(&aData[8+i*4]) - nearby);
- if( d2<dist ){
- closest = i;
- dist = d2;
- }
- }
- }else{
- closest = 0;
- }
-
- iPage = get4byte(&aData[8+closest*4]);
- testcase( iPage==mxPage );
- if( iPage>mxPage ){
- rc = SQLITE_CORRUPT_BKPT;
- goto end_allocate_page;
- }
- testcase( iPage==mxPage );
- if( !searchList || iPage==nearby ){
- int noContent;
- *pPgno = iPage;
- TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
- ": %d more free pages\n",
- *pPgno, closest+1, k, pTrunk->pgno, n-1));
- rc = sqlite3PagerWrite(pTrunk->pDbPage);
- if( rc ) goto end_allocate_page;
- if( closest<k-1 ){
- memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
- }
- put4byte(&aData[4], k-1);
- noContent = !btreeGetHasContent(pBt, *pPgno);
- rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerWrite((*ppPage)->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(*ppPage);
- }
- }
- searchList = 0;
- }
- }
- releasePage(pPrevTrunk);
- pPrevTrunk = 0;
- }while( searchList );
- }else{
- /* There are no pages on the freelist, so create a new page at the
- ** end of the file */
- rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
- if( rc ) return rc;
- pBt->nPage++;
- if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){
- /* If *pPgno refers to a pointer-map page, allocate two new pages
- ** at the end of the file instead of one. The first allocated page
- ** becomes a new pointer-map page, the second is used by the caller.
- */
- MemPage *pPg = 0;
- TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
- assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
- rc = btreeGetPage(pBt, pBt->nPage, &pPg, 1);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerWrite(pPg->pDbPage);
- releasePage(pPg);
- }
- if( rc ) return rc;
- pBt->nPage++;
- if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; }
- }
-#endif
- put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
- *pPgno = pBt->nPage;
-
- assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
- rc = btreeGetPage(pBt, *pPgno, ppPage, 1);
- if( rc ) return rc;
- rc = sqlite3PagerWrite((*ppPage)->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(*ppPage);
- }
- TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
- }
-
- assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
-
-end_allocate_page:
- releasePage(pTrunk);
- releasePage(pPrevTrunk);
- if( rc==SQLITE_OK ){
- if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
- releasePage(*ppPage);
- return SQLITE_CORRUPT_BKPT;
- }
- (*ppPage)->isInit = 0;
- }else{
- *ppPage = 0;
- }
- assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) );
- return rc;
-}
-
-/*
-** This function is used to add page iPage to the database file free-list.
-** It is assumed that the page is not already a part of the free-list.
-**
-** The value passed as the second argument to this function is optional.
-** If the caller happens to have a pointer to the MemPage object
-** corresponding to page iPage handy, it may pass it as the second value.
-** Otherwise, it may pass NULL.
-**
-** If a pointer to a MemPage object is passed as the second argument,
-** its reference count is not altered by this function.
-*/
-static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
- MemPage *pTrunk = 0; /* Free-list trunk page */
- Pgno iTrunk = 0; /* Page number of free-list trunk page */
- MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */
- MemPage *pPage; /* Page being freed. May be NULL. */
- int rc; /* Return Code */
- int nFree; /* Initial number of pages on free-list */
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( iPage>1 );
- assert( !pMemPage || pMemPage->pgno==iPage );
-
- if( pMemPage ){
- pPage = pMemPage;
- sqlite3PagerRef(pPage->pDbPage);
- }else{
- pPage = btreePageLookup(pBt, iPage);
- }
-
- /* Increment the free page count on pPage1 */
- rc = sqlite3PagerWrite(pPage1->pDbPage);
- if( rc ) goto freepage_out;
- nFree = get4byte(&pPage1->aData[36]);
- put4byte(&pPage1->aData[36], nFree+1);
-
- if( pBt->btsFlags & BTS_SECURE_DELETE ){
- /* If the secure_delete option is enabled, then
- ** always fully overwrite deleted information with zeros.
- */
- if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) )
- || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
- ){
- goto freepage_out;
- }
- memset(pPage->aData, 0, pPage->pBt->pageSize);
- }
-
- /* If the database supports auto-vacuum, write an entry in the pointer-map
- ** to indicate that the page is free.
- */
- if( ISAUTOVACUUM ){
- ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc);
- if( rc ) goto freepage_out;
- }
-
- /* Now manipulate the actual database free-list structure. There are two
- ** possibilities. If the free-list is currently empty, or if the first
- ** trunk page in the free-list is full, then this page will become a
- ** new free-list trunk page. Otherwise, it will become a leaf of the
- ** first trunk page in the current free-list. This block tests if it
- ** is possible to add the page as a new free-list leaf.
- */
- if( nFree!=0 ){
- u32 nLeaf; /* Initial number of leaf cells on trunk page */
-
- iTrunk = get4byte(&pPage1->aData[32]);
- rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
- if( rc!=SQLITE_OK ){
- goto freepage_out;
- }
-
- nLeaf = get4byte(&pTrunk->aData[4]);
- assert( pBt->usableSize>32 );
- if( nLeaf > (u32)pBt->usableSize/4 - 2 ){
- rc = SQLITE_CORRUPT_BKPT;
- goto freepage_out;
- }
- if( nLeaf < (u32)pBt->usableSize/4 - 8 ){
- /* In this case there is room on the trunk page to insert the page
- ** being freed as a new leaf.
- **
- ** Note that the trunk page is not really full until it contains
- ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have
- ** coded. But due to a coding error in versions of SQLite prior to
- ** 3.6.0, databases with freelist trunk pages holding more than
- ** usableSize/4 - 8 entries will be reported as corrupt. In order
- ** to maintain backwards compatibility with older versions of SQLite,
- ** we will continue to restrict the number of entries to usableSize/4 - 8
- ** for now. At some point in the future (once everyone has upgraded
- ** to 3.6.0 or later) we should consider fixing the conditional above
- ** to read "usableSize/4-2" instead of "usableSize/4-8".
- */
- rc = sqlite3PagerWrite(pTrunk->pDbPage);
- if( rc==SQLITE_OK ){
- put4byte(&pTrunk->aData[4], nLeaf+1);
- put4byte(&pTrunk->aData[8+nLeaf*4], iPage);
- if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){
- sqlite3PagerDontWrite(pPage->pDbPage);
- }
- rc = btreeSetHasContent(pBt, iPage);
- }
- TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
- goto freepage_out;
- }
- }
-
- /* If control flows to this point, then it was not possible to add the
- ** the page being freed as a leaf page of the first trunk in the free-list.
- ** Possibly because the free-list is empty, or possibly because the
- ** first trunk in the free-list is full. Either way, the page being freed
- ** will become the new first trunk page in the free-list.
- */
- if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
- goto freepage_out;
- }
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc!=SQLITE_OK ){
- goto freepage_out;
- }
- put4byte(pPage->aData, iTrunk);
- put4byte(&pPage->aData[4], 0);
- put4byte(&pPage1->aData[32], iPage);
- TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk));
-
-freepage_out:
- if( pPage ){
- pPage->isInit = 0;
- }
- releasePage(pPage);
- releasePage(pTrunk);
- return rc;
-}
-static void freePage(MemPage *pPage, int *pRC){
- if( (*pRC)==SQLITE_OK ){
- *pRC = freePage2(pPage->pBt, pPage, pPage->pgno);
- }
-}
-
-/*
-** Free any overflow pages associated with the given Cell.
-*/
-static int clearCell(MemPage *pPage, unsigned char *pCell){
- BtShared *pBt = pPage->pBt;
- CellInfo info;
- Pgno ovflPgno;
- int rc;
- int nOvfl;
- u32 ovflPageSize;
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- btreeParseCellPtr(pPage, pCell, &info);
- if( info.iOverflow==0 ){
- return SQLITE_OK; /* No overflow pages. Return without doing anything */
- }
- if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
- return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
- }
- ovflPgno = get4byte(&pCell[info.iOverflow]);
- assert( pBt->usableSize > 4 );
- ovflPageSize = pBt->usableSize - 4;
- nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
- assert( ovflPgno==0 || nOvfl>0 );
- while( nOvfl-- ){
- Pgno iNext = 0;
- MemPage *pOvfl = 0;
- if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){
- /* 0 is not a legal page number and page 1 cannot be an
- ** overflow page. Therefore if ovflPgno<2 or past the end of the
- ** file the database must be corrupt. */
- return SQLITE_CORRUPT_BKPT;
- }
- if( nOvfl ){
- rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext);
- if( rc ) return rc;
- }
-
- if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) )
- && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1
- ){
- /* There is no reason any cursor should have an outstanding reference
- ** to an overflow page belonging to a cell that is being deleted/updated.
- ** So if there exists more than one reference to this page, then it
- ** must not really be an overflow page and the database must be corrupt.
- ** It is helpful to detect this before calling freePage2(), as
- ** freePage2() may zero the page contents if secure-delete mode is
- ** enabled. If this 'overflow' page happens to be a page that the
- ** caller is iterating through or using in some other way, this
- ** can be problematic.
- */
- rc = SQLITE_CORRUPT_BKPT;
- }else{
- rc = freePage2(pBt, pOvfl, ovflPgno);
- }
-
- if( pOvfl ){
- sqlite3PagerUnref(pOvfl->pDbPage);
- }
- if( rc ) return rc;
- ovflPgno = iNext;
- }
- return SQLITE_OK;
-}
-
-/*
-** Create the byte sequence used to represent a cell on page pPage
-** and write that byte sequence into pCell[]. Overflow pages are
-** allocated and filled in as necessary. The calling procedure
-** is responsible for making sure sufficient space has been allocated
-** for pCell[].
-**
-** Note that pCell does not necessary need to point to the pPage->aData
-** area. pCell might point to some temporary storage. The cell will
-** be constructed in this temporary area then copied into pPage->aData
-** later.
-*/
-static int fillInCell(
- MemPage *pPage, /* The page that contains the cell */
- unsigned char *pCell, /* Complete text of the cell */
- const void *pKey, i64 nKey, /* The key */
- const void *pData,int nData, /* The data */
- int nZero, /* Extra zero bytes to append to pData */
- int *pnSize /* Write cell size here */
-){
- int nPayload;
- const u8 *pSrc;
- int nSrc, n, rc;
- int spaceLeft;
- MemPage *pOvfl = 0;
- MemPage *pToRelease = 0;
- unsigned char *pPrior;
- unsigned char *pPayload;
- BtShared *pBt = pPage->pBt;
- Pgno pgnoOvfl = 0;
- int nHeader;
- CellInfo info;
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-
- /* pPage is not necessarily writeable since pCell might be auxiliary
- ** buffer space that is separate from the pPage buffer area */
- assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
- || sqlite3PagerIswriteable(pPage->pDbPage) );
-
- /* Fill in the header. */
- nHeader = 0;
- if( !pPage->leaf ){
- nHeader += 4;
- }
- if( pPage->hasData ){
- nHeader += putVarint(&pCell[nHeader], nData+nZero);
- }else{
- nData = nZero = 0;
- }
- nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
- btreeParseCellPtr(pPage, pCell, &info);
- assert( info.nHeader==nHeader );
- assert( info.nKey==nKey );
- assert( info.nData==(u32)(nData+nZero) );
-
- /* Fill in the payload */
- nPayload = nData + nZero;
- if( pPage->intKey ){
- pSrc = pData;
- nSrc = nData;
- nData = 0;
- }else{
- if( NEVER(nKey>0x7fffffff || pKey==0) ){
- return SQLITE_CORRUPT_BKPT;
- }
- nPayload += (int)nKey;
- pSrc = pKey;
- nSrc = (int)nKey;
- }
- *pnSize = info.nSize;
- spaceLeft = info.nLocal;
- pPayload = &pCell[nHeader];
- pPrior = &pCell[info.iOverflow];
-
- while( nPayload>0 ){
- if( spaceLeft==0 ){
-#ifndef SQLITE_OMIT_AUTOVACUUM
- Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
- if( pBt->autoVacuum ){
- do{
- pgnoOvfl++;
- } while(
- PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt)
- );
- }
-#endif
- rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- /* If the database supports auto-vacuum, and the second or subsequent
- ** overflow page is being allocated, add an entry to the pointer-map
- ** for that page now.
- **
- ** If this is the first overflow page, then write a partial entry
- ** to the pointer-map. If we write nothing to this pointer-map slot,
- ** then the optimistic overflow chain processing in clearCell()
- ** may misinterpret the uninitialised values and delete the
- ** wrong pages from the database.
- */
- if( pBt->autoVacuum && rc==SQLITE_OK ){
- u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1);
- ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc);
- if( rc ){
- releasePage(pOvfl);
- }
- }
-#endif
- if( rc ){
- releasePage(pToRelease);
- return rc;
- }
-
- /* If pToRelease is not zero than pPrior points into the data area
- ** of pToRelease. Make sure pToRelease is still writeable. */
- assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
-
- /* If pPrior is part of the data area of pPage, then make sure pPage
- ** is still writeable */
- assert( pPrior<pPage->aData || pPrior>=&pPage->aData[pBt->pageSize]
- || sqlite3PagerIswriteable(pPage->pDbPage) );
-
- put4byte(pPrior, pgnoOvfl);
- releasePage(pToRelease);
- pToRelease = pOvfl;
- pPrior = pOvfl->aData;
- put4byte(pPrior, 0);
- pPayload = &pOvfl->aData[4];
- spaceLeft = pBt->usableSize - 4;
- }
- n = nPayload;
- if( n>spaceLeft ) n = spaceLeft;
-
- /* If pToRelease is not zero than pPayload points into the data area
- ** of pToRelease. Make sure pToRelease is still writeable. */
- assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
-
- /* If pPayload is part of the data area of pPage, then make sure pPage
- ** is still writeable */
- assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
- || sqlite3PagerIswriteable(pPage->pDbPage) );
-
- if( nSrc>0 ){
- if( n>nSrc ) n = nSrc;
- assert( pSrc );
- memcpy(pPayload, pSrc, n);
- }else{
- memset(pPayload, 0, n);
- }
- nPayload -= n;
- pPayload += n;
- pSrc += n;
- nSrc -= n;
- spaceLeft -= n;
- if( nSrc==0 ){
- nSrc = nData;
- pSrc = pData;
- }
- }
- releasePage(pToRelease);
- return SQLITE_OK;
-}
-
-/*
-** Remove the i-th cell from pPage. This routine effects pPage only.
-** The cell content is not freed or deallocated. It is assumed that
-** the cell content has been copied someplace else. This routine just
-** removes the reference to the cell from pPage.
-**
-** "sz" must be the number of bytes in the cell.
-*/
-static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
- u32 pc; /* Offset to cell content of cell being deleted */
- u8 *data; /* pPage->aData */
- u8 *ptr; /* Used to move bytes around within data[] */
- u8 *endPtr; /* End of loop */
- int rc; /* The return code */
- int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
-
- if( *pRC ) return;
-
- assert( idx>=0 && idx<pPage->nCell );
- assert( sz==cellSize(pPage, idx) );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- data = pPage->aData;
- ptr = &pPage->aCellIdx[2*idx];
- pc = get2byte(ptr);
- hdr = pPage->hdrOffset;
- testcase( pc==get2byte(&data[hdr+5]) );
- testcase( pc+sz==pPage->pBt->usableSize );
- if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){
- *pRC = SQLITE_CORRUPT_BKPT;
- return;
- }
- rc = freeSpace(pPage, pc, sz);
- if( rc ){
- *pRC = rc;
- return;
- }
- endPtr = &pPage->aCellIdx[2*pPage->nCell - 2];
- assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */
- while( ptr<endPtr ){
- *(u16*)ptr = *(u16*)&ptr[2];
- ptr += 2;
- }
- pPage->nCell--;
- put2byte(&data[hdr+3], pPage->nCell);
- pPage->nFree += 2;
-}
-
-/*
-** Insert a new cell on pPage at cell index "i". pCell points to the
-** content of the cell.
-**
-** If the cell content will fit on the page, then put it there. If it
-** will not fit, then make a copy of the cell content into pTemp if
-** pTemp is not null. Regardless of pTemp, allocate a new entry
-** in pPage->apOvfl[] and make it point to the cell content (either
-** in pTemp or the original pCell) and also record its index.
-** Allocating a new entry in pPage->aCell[] implies that
-** pPage->nOverflow is incremented.
-**
-** If nSkip is non-zero, then do not copy the first nSkip bytes of the
-** cell. The caller will overwrite them after this function returns. If
-** nSkip is non-zero, then pCell may not point to an invalid memory location
-** (but pCell+nSkip is always valid).
-*/
-static void insertCell(
- MemPage *pPage, /* Page into which we are copying */
- int i, /* New cell becomes the i-th cell of the page */
- u8 *pCell, /* Content of the new cell */
- int sz, /* Bytes of content in pCell */
- u8 *pTemp, /* Temp storage space for pCell, if needed */
- Pgno iChild, /* If non-zero, replace first 4 bytes with this value */
- int *pRC /* Read and write return code from here */
-){
- int idx = 0; /* Where to write new cell content in data[] */
- int j; /* Loop counter */
- int end; /* First byte past the last cell pointer in data[] */
- int ins; /* Index in data[] where new cell pointer is inserted */
- int cellOffset; /* Address of first cell pointer in data[] */
- u8 *data; /* The content of the whole page */
- u8 *ptr; /* Used for moving information around in data[] */
- u8 *endPtr; /* End of the loop */
-
- int nSkip = (iChild ? 4 : 0);
-
- if( *pRC ) return;
-
- assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
- assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 );
- assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
- assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- /* The cell should normally be sized correctly. However, when moving a
- ** malformed cell from a leaf page to an interior page, if the cell size
- ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
- ** might be less than 8 (leaf-size + pointer) on the interior node. Hence
- ** the term after the || in the following assert(). */
- assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
- if( pPage->nOverflow || sz+2>pPage->nFree ){
- if( pTemp ){
- memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
- pCell = pTemp;
- }
- if( iChild ){
- put4byte(pCell, iChild);
- }
- j = pPage->nOverflow++;
- assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );
- pPage->apOvfl[j] = pCell;
- pPage->aiOvfl[j] = (u16)i;
- }else{
- int rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc!=SQLITE_OK ){
- *pRC = rc;
- return;
- }
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- data = pPage->aData;
- cellOffset = pPage->cellOffset;
- end = cellOffset + 2*pPage->nCell;
- ins = cellOffset + 2*i;
- rc = allocateSpace(pPage, sz, &idx);
- if( rc ){ *pRC = rc; return; }
- /* The allocateSpace() routine guarantees the following two properties
- ** if it returns success */
- assert( idx >= end+2 );
- assert( idx+sz <= (int)pPage->pBt->usableSize );
- pPage->nCell++;
- pPage->nFree -= (u16)(2 + sz);
- memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
- if( iChild ){
- put4byte(&data[idx], iChild);
- }
- ptr = &data[end];
- endPtr = &data[ins];
- assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */
- while( ptr>endPtr ){
- *(u16*)ptr = *(u16*)&ptr[-2];
- ptr -= 2;
- }
- put2byte(&data[ins], idx);
- put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pPage->pBt->autoVacuum ){
- /* The cell may contain a pointer to an overflow page. If so, write
- ** the entry for the overflow page into the pointer map.
- */
- ptrmapPutOvflPtr(pPage, pCell, pRC);
- }
-#endif
- }
-}
-
-/*
-** Add a list of cells to a page. The page should be initially empty.
-** The cells are guaranteed to fit on the page.
-*/
-static void assemblePage(
- MemPage *pPage, /* The page to be assemblied */
- int nCell, /* The number of cells to add to this page */
- u8 **apCell, /* Pointers to cell bodies */
- u16 *aSize /* Sizes of the cells */
-){
- int i; /* Loop counter */
- u8 *pCellptr; /* Address of next cell pointer */
- int cellbody; /* Address of next cell body */
- u8 * const data = pPage->aData; /* Pointer to data for pPage */
- const int hdr = pPage->hdrOffset; /* Offset of header on pPage */
- const int nUsable = pPage->pBt->usableSize; /* Usable size of page */
-
- assert( pPage->nOverflow==0 );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( nCell>=0 && nCell<=(int)MX_CELL(pPage->pBt)
- && (int)MX_CELL(pPage->pBt)<=10921);
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
-
- /* Check that the page has just been zeroed by zeroPage() */
- assert( pPage->nCell==0 );
- assert( get2byteNotZero(&data[hdr+5])==nUsable );
-
- pCellptr = &pPage->aCellIdx[nCell*2];
- cellbody = nUsable;
- for(i=nCell-1; i>=0; i--){
- u16 sz = aSize[i];
- pCellptr -= 2;
- cellbody -= sz;
- put2byte(pCellptr, cellbody);
- memcpy(&data[cellbody], apCell[i], sz);
- }
- put2byte(&data[hdr+3], nCell);
- put2byte(&data[hdr+5], cellbody);
- pPage->nFree -= (nCell*2 + nUsable - cellbody);
- pPage->nCell = (u16)nCell;
-}
-
-/*
-** The following parameters determine how many adjacent pages get involved
-** in a balancing operation. NN is the number of neighbors on either side
-** of the page that participate in the balancing operation. NB is the
-** total number of pages that participate, including the target page and
-** NN neighbors on either side.
-**
-** The minimum value of NN is 1 (of course). Increasing NN above 1
-** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
-** in exchange for a larger degradation in INSERT and UPDATE performance.
-** The value of NN appears to give the best results overall.
-*/
-#define NN 1 /* Number of neighbors on either side of pPage */
-#define NB (NN*2+1) /* Total pages involved in the balance */
-
-
-#ifndef SQLITE_OMIT_QUICKBALANCE
-/*
-** This version of balance() handles the common special case where
-** a new entry is being inserted on the extreme right-end of the
-** tree, in other words, when the new entry will become the largest
-** entry in the tree.
-**
-** Instead of trying to balance the 3 right-most leaf pages, just add
-** a new page to the right-hand side and put the one new entry in
-** that page. This leaves the right side of the tree somewhat
-** unbalanced. But odds are that we will be inserting new entries
-** at the end soon afterwards so the nearly empty page will quickly
-** fill up. On average.
-**
-** pPage is the leaf page which is the right-most page in the tree.
-** pParent is its parent. pPage must have a single overflow entry
-** which is also the right-most entry on the page.
-**
-** The pSpace buffer is used to store a temporary copy of the divider
-** cell that will be inserted into pParent. Such a cell consists of a 4
-** byte page number followed by a variable length integer. In other
-** words, at most 13 bytes. Hence the pSpace buffer must be at
-** least 13 bytes in size.
-*/
-static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
- BtShared *const pBt = pPage->pBt; /* B-Tree Database */
- MemPage *pNew; /* Newly allocated page */
- int rc; /* Return Code */
- Pgno pgnoNew; /* Page number of pNew */
-
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
- assert( pPage->nOverflow==1 );
-
- /* This error condition is now caught prior to reaching this function */
- if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;
-
- /* Allocate a new page. This page will become the right-sibling of
- ** pPage. Make the parent page writable, so that the new divider cell
- ** may be inserted. If both these operations are successful, proceed.
- */
- rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
-
- if( rc==SQLITE_OK ){
-
- u8 *pOut = &pSpace[4];
- u8 *pCell = pPage->apOvfl[0];
- u16 szCell = cellSizePtr(pPage, pCell);
- u8 *pStop;
-
- assert( sqlite3PagerIswriteable(pNew->pDbPage) );
- assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
- zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
- assemblePage(pNew, 1, &pCell, &szCell);
-
- /* If this is an auto-vacuum database, update the pointer map
- ** with entries for the new page, and any pointer from the
- ** cell on the page to an overflow page. If either of these
- ** operations fails, the return code is set, but the contents
- ** of the parent page are still manipulated by thh code below.
- ** That is Ok, at this point the parent page is guaranteed to
- ** be marked as dirty. Returning an error code will cause a
- ** rollback, undoing any changes made to the parent page.
- */
- if( ISAUTOVACUUM ){
- ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc);
- if( szCell>pNew->minLocal ){
- ptrmapPutOvflPtr(pNew, pCell, &rc);
- }
- }
-
- /* Create a divider cell to insert into pParent. The divider cell
- ** consists of a 4-byte page number (the page number of pPage) and
- ** a variable length key value (which must be the same value as the
- ** largest key on pPage).
- **
- ** To find the largest key value on pPage, first find the right-most
- ** cell on pPage. The first two fields of this cell are the
- ** record-length (a variable length integer at most 32-bits in size)
- ** and the key value (a variable length integer, may have any value).
- ** The first of the while(...) loops below skips over the record-length
- ** field. The second while(...) loop copies the key value from the
- ** cell on pPage into the pSpace buffer.
- */
- pCell = findCell(pPage, pPage->nCell-1);
- pStop = &pCell[9];
- while( (*(pCell++)&0x80) && pCell<pStop );
- pStop = &pCell[9];
- while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop );
-
- /* Insert the new divider cell into pParent. */
- insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
- 0, pPage->pgno, &rc);
-
- /* Set the right-child pointer of pParent to point to the new page. */
- put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
-
- /* Release the reference to the new page. */
- releasePage(pNew);
- }
-
- return rc;
-}
-#endif /* SQLITE_OMIT_QUICKBALANCE */
-
-#if 0
-/*
-** This function does not contribute anything to the operation of SQLite.
-** it is sometimes activated temporarily while debugging code responsible
-** for setting pointer-map entries.
-*/
-static int ptrmapCheckPages(MemPage **apPage, int nPage){
- int i, j;
- for(i=0; i<nPage; i++){
- Pgno n;
- u8 e;
- MemPage *pPage = apPage[i];
- BtShared *pBt = pPage->pBt;
- assert( pPage->isInit );
-
- for(j=0; j<pPage->nCell; j++){
- CellInfo info;
- u8 *z;
-
- z = findCell(pPage, j);
- btreeParseCellPtr(pPage, z, &info);
- if( info.iOverflow ){
- Pgno ovfl = get4byte(&z[info.iOverflow]);
- ptrmapGet(pBt, ovfl, &e, &n);
- assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 );
- }
- if( !pPage->leaf ){
- Pgno child = get4byte(z);
- ptrmapGet(pBt, child, &e, &n);
- assert( n==pPage->pgno && e==PTRMAP_BTREE );
- }
- }
- if( !pPage->leaf ){
- Pgno child = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- ptrmapGet(pBt, child, &e, &n);
- assert( n==pPage->pgno && e==PTRMAP_BTREE );
- }
- }
- return 1;
-}
-#endif
-
-/*
-** This function is used to copy the contents of the b-tree node stored
-** on page pFrom to page pTo. If page pFrom was not a leaf page, then
-** the pointer-map entries for each child page are updated so that the
-** parent page stored in the pointer map is page pTo. If pFrom contained
-** any cells with overflow page pointers, then the corresponding pointer
-** map entries are also updated so that the parent page is page pTo.
-**
-** If pFrom is currently carrying any overflow cells (entries in the
-** MemPage.apOvfl[] array), they are not copied to pTo.
-**
-** Before returning, page pTo is reinitialized using btreeInitPage().
-**
-** The performance of this function is not critical. It is only used by
-** the balance_shallower() and balance_deeper() procedures, neither of
-** which are called often under normal circumstances.
-*/
-static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
- if( (*pRC)==SQLITE_OK ){
- BtShared * const pBt = pFrom->pBt;
- u8 * const aFrom = pFrom->aData;
- u8 * const aTo = pTo->aData;
- int const iFromHdr = pFrom->hdrOffset;
- int const iToHdr = ((pTo->pgno==1) ? 100 : 0);
- int rc;
- int iData;
-
-
- assert( pFrom->isInit );
- assert( pFrom->nFree>=iToHdr );
- assert( get2byte(&aFrom[iFromHdr+5]) <= (int)pBt->usableSize );
-
- /* Copy the b-tree node content from page pFrom to page pTo. */
- iData = get2byte(&aFrom[iFromHdr+5]);
- memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData);
- memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell);
-
- /* Reinitialize page pTo so that the contents of the MemPage structure
- ** match the new data. The initialization of pTo can actually fail under
- ** fairly obscure circumstances, even though it is a copy of initialized
- ** page pFrom.
- */
- pTo->isInit = 0;
- rc = btreeInitPage(pTo);
- if( rc!=SQLITE_OK ){
- *pRC = rc;
- return;
- }
-
- /* If this is an auto-vacuum database, update the pointer-map entries
- ** for any b-tree or overflow pages that pTo now contains the pointers to.
- */
- if( ISAUTOVACUUM ){
- *pRC = setChildPtrmaps(pTo);
- }
- }
-}
-
-/*
-** This routine redistributes cells on the iParentIdx'th child of pParent
-** (hereafter "the page") and up to 2 siblings so that all pages have about the
-** same amount of free space. Usually a single sibling on either side of the
-** page are used in the balancing, though both siblings might come from one
-** side if the page is the first or last child of its parent. If the page
-** has fewer than 2 siblings (something which can only happen if the page
-** is a root page or a child of a root page) then all available siblings
-** participate in the balancing.
-**
-** The number of siblings of the page might be increased or decreased by
-** one or two in an effort to keep pages nearly full but not over full.
-**
-** Note that when this routine is called, some of the cells on the page
-** might not actually be stored in MemPage.aData[]. This can happen
-** if the page is overfull. This routine ensures that all cells allocated
-** to the page and its siblings fit into MemPage.aData[] before returning.
-**
-** In the course of balancing the page and its siblings, cells may be
-** inserted into or removed from the parent page (pParent). Doing so
-** may cause the parent page to become overfull or underfull. If this
-** happens, it is the responsibility of the caller to invoke the correct
-** balancing routine to fix this problem (see the balance() routine).
-**
-** If this routine fails for any reason, it might leave the database
-** in a corrupted state. So if this routine fails, the database should
-** be rolled back.
-**
-** The third argument to this function, aOvflSpace, is a pointer to a
-** buffer big enough to hold one page. If while inserting cells into the parent
-** page (pParent) the parent page becomes overfull, this buffer is
-** used to store the parent's overflow cells. Because this function inserts
-** a maximum of four divider cells into the parent page, and the maximum
-** size of a cell stored within an internal node is always less than 1/4
-** of the page-size, the aOvflSpace[] buffer is guaranteed to be large
-** enough for all overflow cells.
-**
-** If aOvflSpace is set to a null pointer, this function returns
-** SQLITE_NOMEM.
-*/
-#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
-#pragma optimize("", off)
-#endif
-static int balance_nonroot(
- MemPage *pParent, /* Parent page of siblings being balanced */
- int iParentIdx, /* Index of "the page" in pParent */
- u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */
- int isRoot, /* True if pParent is a root-page */
- int bBulk /* True if this call is part of a bulk load */
-){
- BtShared *pBt; /* The whole database */
- int nCell = 0; /* Number of cells in apCell[] */
- int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */
- int nNew = 0; /* Number of pages in apNew[] */
- int nOld; /* Number of pages in apOld[] */
- int i, j, k; /* Loop counters */
- int nxDiv; /* Next divider slot in pParent->aCell[] */
- int rc = SQLITE_OK; /* The return code */
- u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */
- int leafData; /* True if pPage is a leaf of a LEAFDATA tree */
- int usableSpace; /* Bytes in pPage beyond the header */
- int pageFlags; /* Value of pPage->aData[0] */
- int subtotal; /* Subtotal of bytes in cells on one page */
- int iSpace1 = 0; /* First unused byte of aSpace1[] */
- int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */
- int szScratch; /* Size of scratch memory requested */
- MemPage *apOld[NB]; /* pPage and up to two siblings */
- MemPage *apCopy[NB]; /* Private copies of apOld[] pages */
- MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */
- u8 *pRight; /* Location in parent of right-sibling pointer */
- u8 *apDiv[NB-1]; /* Divider cells in pParent */
- int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */
- int szNew[NB+2]; /* Combined size of cells place on i-th page */
- u8 **apCell = 0; /* All cells begin balanced */
- u16 *szCell; /* Local size of all cells in apCell[] */
- u8 *aSpace1; /* Space for copies of dividers cells */
- Pgno pgno; /* Temp var to store a page number in */
-
- pBt = pParent->pBt;
- assert( sqlite3_mutex_held(pBt->mutex) );
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
-
-#if 0
- TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
-#endif
-
- /* At this point pParent may have at most one overflow cell. And if
- ** this overflow cell is present, it must be the cell with
- ** index iParentIdx. This scenario comes about when this function
- ** is called (indirectly) from sqlite3BtreeDelete().
- */
- assert( pParent->nOverflow==0 || pParent->nOverflow==1 );
- assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx );
-
- if( !aOvflSpace ){
- return SQLITE_NOMEM;
- }
-
- /* Find the sibling pages to balance. Also locate the cells in pParent
- ** that divide the siblings. An attempt is made to find NN siblings on
- ** either side of pPage. More siblings are taken from one side, however,
- ** if there are fewer than NN siblings on the other side. If pParent
- ** has NB or fewer children then all children of pParent are taken.
- **
- ** This loop also drops the divider cells from the parent page. This
- ** way, the remainder of the function does not have to deal with any
- ** overflow cells in the parent page, since if any existed they will
- ** have already been removed.
- */
- i = pParent->nOverflow + pParent->nCell;
- if( i<2 ){
- nxDiv = 0;
- }else{
- assert( bBulk==0 || bBulk==1 );
- if( iParentIdx==0 ){
- nxDiv = 0;
- }else if( iParentIdx==i ){
- nxDiv = i-2+bBulk;
- }else{
- assert( bBulk==0 );
- nxDiv = iParentIdx-1;
- }
- i = 2-bBulk;
- }
- nOld = i+1;
- if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){
- pRight = &pParent->aData[pParent->hdrOffset+8];
- }else{
- pRight = findCell(pParent, i+nxDiv-pParent->nOverflow);
- }
- pgno = get4byte(pRight);
- while( 1 ){
- rc = getAndInitPage(pBt, pgno, &apOld[i]);
- if( rc ){
- memset(apOld, 0, (i+1)*sizeof(MemPage*));
- goto balance_cleanup;
- }
- nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
- if( (i--)==0 ) break;
-
- if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){
- apDiv[i] = pParent->apOvfl[0];
- pgno = get4byte(apDiv[i]);
- szNew[i] = cellSizePtr(pParent, apDiv[i]);
- pParent->nOverflow = 0;
- }else{
- apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow);
- pgno = get4byte(apDiv[i]);
- szNew[i] = cellSizePtr(pParent, apDiv[i]);
-
- /* Drop the cell from the parent page. apDiv[i] still points to
- ** the cell within the parent, even though it has been dropped.
- ** This is safe because dropping a cell only overwrites the first
- ** four bytes of it, and this function does not need the first
- ** four bytes of the divider cell. So the pointer is safe to use
- ** later on.
- **
- ** But not if we are in secure-delete mode. In secure-delete mode,
- ** the dropCell() routine will overwrite the entire cell with zeroes.
- ** In this case, temporarily copy the cell into the aOvflSpace[]
- ** buffer. It will be copied out again as soon as the aSpace[] buffer
- ** is allocated. */
- if( pBt->btsFlags & BTS_SECURE_DELETE ){
- int iOff;
-
- iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
- if( (iOff+szNew[i])>(int)pBt->usableSize ){
- rc = SQLITE_CORRUPT_BKPT;
- memset(apOld, 0, (i+1)*sizeof(MemPage*));
- goto balance_cleanup;
- }else{
- memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]);
- apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
- }
- }
- dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc);
- }
- }
-
- /* Make nMaxCells a multiple of 4 in order to preserve 8-byte
- ** alignment */
- nMaxCells = (nMaxCells + 3)&~3;
-
- /*
- ** Allocate space for memory structures
- */
- k = pBt->pageSize + ROUND8(sizeof(MemPage));
- szScratch =
- nMaxCells*sizeof(u8*) /* apCell */
- + nMaxCells*sizeof(u16) /* szCell */
- + pBt->pageSize /* aSpace1 */
- + k*nOld; /* Page copies (apCopy) */
- apCell = sqlite3ScratchMalloc( szScratch );
- if( apCell==0 ){
- rc = SQLITE_NOMEM;
- goto balance_cleanup;
- }
- szCell = (u16*)&apCell[nMaxCells];
- aSpace1 = (u8*)&szCell[nMaxCells];
- assert( EIGHT_BYTE_ALIGNMENT(aSpace1) );
-
- /*
- ** Load pointers to all cells on sibling pages and the divider cells
- ** into the local apCell[] array. Make copies of the divider cells
- ** into space obtained from aSpace1[] and remove the divider cells
- ** from pParent.
- **
- ** If the siblings are on leaf pages, then the child pointers of the
- ** divider cells are stripped from the cells before they are copied
- ** into aSpace1[]. In this way, all cells in apCell[] are without
- ** child pointers. If siblings are not leaves, then all cell in
- ** apCell[] include child pointers. Either way, all cells in apCell[]
- ** are alike.
- **
- ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf.
- ** leafData: 1 if pPage holds key+data and pParent holds only keys.
- */
- leafCorrection = apOld[0]->leaf*4;
- leafData = apOld[0]->hasData;
- for(i=0; i<nOld; i++){
- int limit;
-
- /* Before doing anything else, take a copy of the i'th original sibling
- ** The rest of this function will use data from the copies rather
- ** that the original pages since the original pages will be in the
- ** process of being overwritten. */
- MemPage *pOld = apCopy[i] = (MemPage*)&aSpace1[pBt->pageSize + k*i];
- memcpy(pOld, apOld[i], sizeof(MemPage));
- pOld->aData = (void*)&pOld[1];
- memcpy(pOld->aData, apOld[i]->aData, pBt->pageSize);
-
- limit = pOld->nCell+pOld->nOverflow;
- if( pOld->nOverflow>0 ){
- for(j=0; j<limit; j++){
- assert( nCell<nMaxCells );
- apCell[nCell] = findOverflowCell(pOld, j);
- szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
- nCell++;
- }
- }else{
- u8 *aData = pOld->aData;
- u16 maskPage = pOld->maskPage;
- u16 cellOffset = pOld->cellOffset;
- for(j=0; j<limit; j++){
- assert( nCell<nMaxCells );
- apCell[nCell] = findCellv2(aData, maskPage, cellOffset, j);
- szCell[nCell] = cellSizePtr(pOld, apCell[nCell]);
- nCell++;
- }
- }
- if( i<nOld-1 && !leafData){
- u16 sz = (u16)szNew[i];
- u8 *pTemp;
- assert( nCell<nMaxCells );
- szCell[nCell] = sz;
- pTemp = &aSpace1[iSpace1];
- iSpace1 += sz;
- assert( sz<=pBt->maxLocal+23 );
- assert( iSpace1 <= (int)pBt->pageSize );
- memcpy(pTemp, apDiv[i], sz);
- apCell[nCell] = pTemp+leafCorrection;
- assert( leafCorrection==0 || leafCorrection==4 );
- szCell[nCell] = szCell[nCell] - leafCorrection;
- if( !pOld->leaf ){
- assert( leafCorrection==0 );
- assert( pOld->hdrOffset==0 );
- /* The right pointer of the child page pOld becomes the left
- ** pointer of the divider cell */
- memcpy(apCell[nCell], &pOld->aData[8], 4);
- }else{
- assert( leafCorrection==4 );
- if( szCell[nCell]<4 ){
- /* Do not allow any cells smaller than 4 bytes. */
- szCell[nCell] = 4;
- }
- }
- nCell++;
- }
- }
-
- /*
- ** Figure out the number of pages needed to hold all nCell cells.
- ** Store this number in "k". Also compute szNew[] which is the total
- ** size of all cells on the i-th page and cntNew[] which is the index
- ** in apCell[] of the cell that divides page i from page i+1.
- ** cntNew[k] should equal nCell.
- **
- ** Values computed by this block:
- **
- ** k: The total number of sibling pages
- ** szNew[i]: Spaced used on the i-th sibling page.
- ** cntNew[i]: Index in apCell[] and szCell[] for the first cell to
- ** the right of the i-th sibling page.
- ** usableSpace: Number of bytes of space available on each sibling.
- **
- */
- usableSpace = pBt->usableSize - 12 + leafCorrection;
- for(subtotal=k=i=0; i<nCell; i++){
- assert( i<nMaxCells );
- subtotal += szCell[i] + 2;
- if( subtotal > usableSpace ){
- szNew[k] = subtotal - szCell[i];
- cntNew[k] = i;
- if( leafData ){ i--; }
- subtotal = 0;
- k++;
- if( k>NB+1 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
- }
- }
- szNew[k] = subtotal;
- cntNew[k] = nCell;
- k++;
-
- /*
- ** The packing computed by the previous block is biased toward the siblings
- ** on the left side. The left siblings are always nearly full, while the
- ** right-most sibling might be nearly empty. This block of code attempts
- ** to adjust the packing of siblings to get a better balance.
- **
- ** This adjustment is more than an optimization. The packing above might
- ** be so out of balance as to be illegal. For example, the right-most
- ** sibling might be completely empty. This adjustment is not optional.
- */
- for(i=k-1; i>0; i--){
- int szRight = szNew[i]; /* Size of sibling on the right */
- int szLeft = szNew[i-1]; /* Size of sibling on the left */
- int r; /* Index of right-most cell in left sibling */
- int d; /* Index of first cell to the left of right sibling */
-
- r = cntNew[i-1] - 1;
- d = r + 1 - leafData;
- assert( d<nMaxCells );
- assert( r<nMaxCells );
- while( szRight==0
- || (!bBulk && szRight+szCell[d]+2<=szLeft-(szCell[r]+2))
- ){
- szRight += szCell[d] + 2;
- szLeft -= szCell[r] + 2;
- cntNew[i-1]--;
- r = cntNew[i-1] - 1;
- d = r + 1 - leafData;
- }
- szNew[i] = szRight;
- szNew[i-1] = szLeft;
- }
-
- /* Either we found one or more cells (cntnew[0])>0) or pPage is
- ** a virtual root page. A virtual root page is when the real root
- ** page is page 1 and we are the only child of that page.
- **
- ** UPDATE: The assert() below is not necessarily true if the database
- ** file is corrupt. The corruption will be detected and reported later
- ** in this procedure so there is no need to act upon it now.
- */
-#if 0
- assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) );
-#endif
-
- TRACE(("BALANCE: old: %d %d %d ",
- apOld[0]->pgno,
- nOld>=2 ? apOld[1]->pgno : 0,
- nOld>=3 ? apOld[2]->pgno : 0
- ));
-
- /*
- ** Allocate k new pages. Reuse old pages where possible.
- */
- if( apOld[0]->pgno<=1 ){
- rc = SQLITE_CORRUPT_BKPT;
- goto balance_cleanup;
- }
- pageFlags = apOld[0]->aData[0];
- for(i=0; i<k; i++){
- MemPage *pNew;
- if( i<nOld ){
- pNew = apNew[i] = apOld[i];
- apOld[i] = 0;
- rc = sqlite3PagerWrite(pNew->pDbPage);
- nNew++;
- if( rc ) goto balance_cleanup;
- }else{
- assert( i>0 );
- rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
- if( rc ) goto balance_cleanup;
- apNew[i] = pNew;
- nNew++;
-
- /* Set the pointer-map entry for the new sibling page. */
- if( ISAUTOVACUUM ){
- ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc);
- if( rc!=SQLITE_OK ){
- goto balance_cleanup;
- }
- }
- }
- }
-
- /* Free any old pages that were not reused as new pages.
- */
- while( i<nOld ){
- freePage(apOld[i], &rc);
- if( rc ) goto balance_cleanup;
- releasePage(apOld[i]);
- apOld[i] = 0;
- i++;
- }
-
- /*
- ** Put the new pages in accending order. This helps to
- ** keep entries in the disk file in order so that a scan
- ** of the table is a linear scan through the file. That
- ** in turn helps the operating system to deliver pages
- ** from the disk more rapidly.
- **
- ** An O(n^2) insertion sort algorithm is used, but since
- ** n is never more than NB (a small constant), that should
- ** not be a problem.
- **
- ** When NB==3, this one optimization makes the database
- ** about 25% faster for large insertions and deletions.
- */
- for(i=0; i<k-1; i++){
- int minV = apNew[i]->pgno;
- int minI = i;
- for(j=i+1; j<k; j++){
- if( apNew[j]->pgno<(unsigned)minV ){
- minI = j;
- minV = apNew[j]->pgno;
- }
- }
- if( minI>i ){
- MemPage *pT;
- pT = apNew[i];
- apNew[i] = apNew[minI];
- apNew[minI] = pT;
- }
- }
- TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
- apNew[0]->pgno, szNew[0],
- nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0,
- nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0,
- nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0,
- nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0));
-
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
- put4byte(pRight, apNew[nNew-1]->pgno);
-
- /*
- ** Evenly distribute the data in apCell[] across the new pages.
- ** Insert divider cells into pParent as necessary.
- */
- j = 0;
- for(i=0; i<nNew; i++){
- /* Assemble the new sibling page. */
- MemPage *pNew = apNew[i];
- assert( j<nMaxCells );
- zeroPage(pNew, pageFlags);
- assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
- assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
- assert( pNew->nOverflow==0 );
-
- j = cntNew[i];
-
- /* If the sibling page assembled above was not the right-most sibling,
- ** insert a divider cell into the parent page.
- */
- assert( i<nNew-1 || j==nCell );
- if( j<nCell ){
- u8 *pCell;
- u8 *pTemp;
- int sz;
-
- assert( j<nMaxCells );
- pCell = apCell[j];
- sz = szCell[j] + leafCorrection;
- pTemp = &aOvflSpace[iOvflSpace];
- if( !pNew->leaf ){
- memcpy(&pNew->aData[8], pCell, 4);
- }else if( leafData ){
- /* If the tree is a leaf-data tree, and the siblings are leaves,
- ** then there is no divider cell in apCell[]. Instead, the divider
- ** cell consists of the integer key for the right-most cell of
- ** the sibling-page assembled above only.
- */
- CellInfo info;
- j--;
- btreeParseCellPtr(pNew, apCell[j], &info);
- pCell = pTemp;
- sz = 4 + putVarint(&pCell[4], info.nKey);
- pTemp = 0;
- }else{
- pCell -= 4;
- /* Obscure case for non-leaf-data trees: If the cell at pCell was
- ** previously stored on a leaf node, and its reported size was 4
- ** bytes, then it may actually be smaller than this
- ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
- ** any cell). But it is important to pass the correct size to
- ** insertCell(), so reparse the cell now.
- **
- ** Note that this can never happen in an SQLite data file, as all
- ** cells are at least 4 bytes. It only happens in b-trees used
- ** to evaluate "IN (SELECT ...)" and similar clauses.
- */
- if( szCell[j]==4 ){
- assert(leafCorrection==4);
- sz = cellSizePtr(pParent, pCell);
- }
- }
- iOvflSpace += sz;
- assert( sz<=pBt->maxLocal+23 );
- assert( iOvflSpace <= (int)pBt->pageSize );
- insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc);
- if( rc!=SQLITE_OK ) goto balance_cleanup;
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
-
- j++;
- nxDiv++;
- }
- }
- assert( j==nCell );
- assert( nOld>0 );
- assert( nNew>0 );
- if( (pageFlags & PTF_LEAF)==0 ){
- u8 *zChild = &apCopy[nOld-1]->aData[8];
- memcpy(&apNew[nNew-1]->aData[8], zChild, 4);
- }
-
- if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){
- /* The root page of the b-tree now contains no cells. The only sibling
- ** page is the right-child of the parent. Copy the contents of the
- ** child page into the parent, decreasing the overall height of the
- ** b-tree structure by one. This is described as the "balance-shallower"
- ** sub-algorithm in some documentation.
- **
- ** If this is an auto-vacuum database, the call to copyNodeContent()
- ** sets all pointer-map entries corresponding to database image pages
- ** for which the pointer is stored within the content being copied.
- **
- ** The second assert below verifies that the child page is defragmented
- ** (it must be, as it was just reconstructed using assemblePage()). This
- ** is important if the parent page happens to be page 1 of the database
- ** image. */
- assert( nNew==1 );
- assert( apNew[0]->nFree ==
- (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
- );
- copyNodeContent(apNew[0], pParent, &rc);
- freePage(apNew[0], &rc);
- }else if( ISAUTOVACUUM ){
- /* Fix the pointer-map entries for all the cells that were shifted around.
- ** There are several different types of pointer-map entries that need to
- ** be dealt with by this routine. Some of these have been set already, but
- ** many have not. The following is a summary:
- **
- ** 1) The entries associated with new sibling pages that were not
- ** siblings when this function was called. These have already
- ** been set. We don't need to worry about old siblings that were
- ** moved to the free-list - the freePage() code has taken care
- ** of those.
- **
- ** 2) The pointer-map entries associated with the first overflow
- ** page in any overflow chains used by new divider cells. These
- ** have also already been taken care of by the insertCell() code.
- **
- ** 3) If the sibling pages are not leaves, then the child pages of
- ** cells stored on the sibling pages may need to be updated.
- **
- ** 4) If the sibling pages are not internal intkey nodes, then any
- ** overflow pages used by these cells may need to be updated
- ** (internal intkey nodes never contain pointers to overflow pages).
- **
- ** 5) If the sibling pages are not leaves, then the pointer-map
- ** entries for the right-child pages of each sibling may need
- ** to be updated.
- **
- ** Cases 1 and 2 are dealt with above by other code. The next
- ** block deals with cases 3 and 4 and the one after that, case 5. Since
- ** setting a pointer map entry is a relatively expensive operation, this
- ** code only sets pointer map entries for child or overflow pages that have
- ** actually moved between pages. */
- MemPage *pNew = apNew[0];
- MemPage *pOld = apCopy[0];
- int nOverflow = pOld->nOverflow;
- int iNextOld = pOld->nCell + nOverflow;
- int iOverflow = (nOverflow ? pOld->aiOvfl[0] : -1);
- j = 0; /* Current 'old' sibling page */
- k = 0; /* Current 'new' sibling page */
- for(i=0; i<nCell; i++){
- int isDivider = 0;
- while( i==iNextOld ){
- /* Cell i is the cell immediately following the last cell on old
- ** sibling page j. If the siblings are not leaf pages of an
- ** intkey b-tree, then cell i was a divider cell. */
- assert( j+1 < ArraySize(apCopy) );
- assert( j+1 < nOld );
- pOld = apCopy[++j];
- iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
- if( pOld->nOverflow ){
- nOverflow = pOld->nOverflow;
- iOverflow = i + !leafData + pOld->aiOvfl[0];
- }
- isDivider = !leafData;
- }
-
- assert(nOverflow>0 || iOverflow<i );
- assert(nOverflow<2 || pOld->aiOvfl[0]==pOld->aiOvfl[1]-1);
- assert(nOverflow<3 || pOld->aiOvfl[1]==pOld->aiOvfl[2]-1);
- if( i==iOverflow ){
- isDivider = 1;
- if( (--nOverflow)>0 ){
- iOverflow++;
- }
- }
-
- if( i==cntNew[k] ){
- /* Cell i is the cell immediately following the last cell on new
- ** sibling page k. If the siblings are not leaf pages of an
- ** intkey b-tree, then cell i is a divider cell. */
- pNew = apNew[++k];
- if( !leafData ) continue;
- }
- assert( j<nOld );
- assert( k<nNew );
-
- /* If the cell was originally divider cell (and is not now) or
- ** an overflow cell, or if the cell was located on a different sibling
- ** page before the balancing, then the pointer map entries associated
- ** with any child or overflow pages need to be updated. */
- if( isDivider || pOld->pgno!=pNew->pgno ){
- if( !leafCorrection ){
- ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno, &rc);
- }
- if( szCell[i]>pNew->minLocal ){
- ptrmapPutOvflPtr(pNew, apCell[i], &rc);
- }
- }
- }
-
- if( !leafCorrection ){
- for(i=0; i<nNew; i++){
- u32 key = get4byte(&apNew[i]->aData[8]);
- ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);
- }
- }
-
-#if 0
- /* The ptrmapCheckPages() contains assert() statements that verify that
- ** all pointer map pages are set correctly. This is helpful while
- ** debugging. This is usually disabled because a corrupt database may
- ** cause an assert() statement to fail. */
- ptrmapCheckPages(apNew, nNew);
- ptrmapCheckPages(&pParent, 1);
-#endif
- }
-
- assert( pParent->isInit );
- TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
- nOld, nNew, nCell));
-
- /*
- ** Cleanup before returning.
- */
-balance_cleanup:
- sqlite3ScratchFree(apCell);
- for(i=0; i<nOld; i++){
- releasePage(apOld[i]);
- }
- for(i=0; i<nNew; i++){
- releasePage(apNew[i]);
- }
-
- return rc;
-}
-#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
-#pragma optimize("", on)
-#endif
-
-
-/*
-** This function is called when the root page of a b-tree structure is
-** overfull (has one or more overflow pages).
-**
-** A new child page is allocated and the contents of the current root
-** page, including overflow cells, are copied into the child. The root
-** page is then overwritten to make it an empty page with the right-child
-** pointer pointing to the new page.
-**
-** Before returning, all pointer-map entries corresponding to pages
-** that the new child-page now contains pointers to are updated. The
-** entry corresponding to the new right-child pointer of the root
-** page is also updated.
-**
-** If successful, *ppChild is set to contain a reference to the child
-** page and SQLITE_OK is returned. In this case the caller is required
-** to call releasePage() on *ppChild exactly once. If an error occurs,
-** an error code is returned and *ppChild is set to 0.
-*/
-static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
- int rc; /* Return value from subprocedures */
- MemPage *pChild = 0; /* Pointer to a new child page */
- Pgno pgnoChild = 0; /* Page number of the new child page */
- BtShared *pBt = pRoot->pBt; /* The BTree */
-
- assert( pRoot->nOverflow>0 );
- assert( sqlite3_mutex_held(pBt->mutex) );
-
- /* Make pRoot, the root page of the b-tree, writable. Allocate a new
- ** page that will become the new right-child of pPage. Copy the contents
- ** of the node stored on pRoot into the new child page.
- */
- rc = sqlite3PagerWrite(pRoot->pDbPage);
- if( rc==SQLITE_OK ){
- rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0);
- copyNodeContent(pRoot, pChild, &rc);
- if( ISAUTOVACUUM ){
- ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc);
- }
- }
- if( rc ){
- *ppChild = 0;
- releasePage(pChild);
- return rc;
- }
- assert( sqlite3PagerIswriteable(pChild->pDbPage) );
- assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
- assert( pChild->nCell==pRoot->nCell );
-
- TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno));
-
- /* Copy the overflow cells from pRoot to pChild */
- memcpy(pChild->aiOvfl, pRoot->aiOvfl,
- pRoot->nOverflow*sizeof(pRoot->aiOvfl[0]));
- memcpy(pChild->apOvfl, pRoot->apOvfl,
- pRoot->nOverflow*sizeof(pRoot->apOvfl[0]));
- pChild->nOverflow = pRoot->nOverflow;
-
- /* Zero the contents of pRoot. Then install pChild as the right-child. */
- zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF);
- put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild);
-
- *ppChild = pChild;
- return SQLITE_OK;
-}
-
-/*
-** The page that pCur currently points to has just been modified in
-** some way. This function figures out if this modification means the
-** tree needs to be balanced, and if so calls the appropriate balancing
-** routine. Balancing routines are:
-**
-** balance_quick()
-** balance_deeper()
-** balance_nonroot()
-*/
-static int balance(BtCursor *pCur){
- int rc = SQLITE_OK;
- const int nMin = pCur->pBt->usableSize * 2 / 3;
- u8 aBalanceQuickSpace[13];
- u8 *pFree = 0;
-
- TESTONLY( int balance_quick_called = 0 );
- TESTONLY( int balance_deeper_called = 0 );
-
- do {
- int iPage = pCur->iPage;
- MemPage *pPage = pCur->apPage[iPage];
-
- if( iPage==0 ){
- if( pPage->nOverflow ){
- /* The root page of the b-tree is overfull. In this case call the
- ** balance_deeper() function to create a new child for the root-page
- ** and copy the current contents of the root-page to it. The
- ** next iteration of the do-loop will balance the child page.
- */
- assert( (balance_deeper_called++)==0 );
- rc = balance_deeper(pPage, &pCur->apPage[1]);
- if( rc==SQLITE_OK ){
- pCur->iPage = 1;
- pCur->aiIdx[0] = 0;
- pCur->aiIdx[1] = 0;
- assert( pCur->apPage[1]->nOverflow );
- }
- }else{
- break;
- }
- }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
- break;
- }else{
- MemPage * const pParent = pCur->apPage[iPage-1];
- int const iIdx = pCur->aiIdx[iPage-1];
-
- rc = sqlite3PagerWrite(pParent->pDbPage);
- if( rc==SQLITE_OK ){
-#ifndef SQLITE_OMIT_QUICKBALANCE
- if( pPage->hasData
- && pPage->nOverflow==1
- && pPage->aiOvfl[0]==pPage->nCell
- && pParent->pgno!=1
- && pParent->nCell==iIdx
- ){
- /* Call balance_quick() to create a new sibling of pPage on which
- ** to store the overflow cell. balance_quick() inserts a new cell
- ** into pParent, which may cause pParent overflow. If this
- ** happens, the next interation of the do-loop will balance pParent
- ** use either balance_nonroot() or balance_deeper(). Until this
- ** happens, the overflow cell is stored in the aBalanceQuickSpace[]
- ** buffer.
- **
- ** The purpose of the following assert() is to check that only a
- ** single call to balance_quick() is made for each call to this
- ** function. If this were not verified, a subtle bug involving reuse
- ** of the aBalanceQuickSpace[] might sneak in.
- */
- assert( (balance_quick_called++)==0 );
- rc = balance_quick(pParent, pPage, aBalanceQuickSpace);
- }else
-#endif
- {
- /* In this case, call balance_nonroot() to redistribute cells
- ** between pPage and up to 2 of its sibling pages. This involves
- ** modifying the contents of pParent, which may cause pParent to
- ** become overfull or underfull. The next iteration of the do-loop
- ** will balance the parent page to correct this.
- **
- ** If the parent page becomes overfull, the overflow cell or cells
- ** are stored in the pSpace buffer allocated immediately below.
- ** A subsequent iteration of the do-loop will deal with this by
- ** calling balance_nonroot() (balance_deeper() may be called first,
- ** but it doesn't deal with overflow cells - just moves them to a
- ** different page). Once this subsequent call to balance_nonroot()
- ** has completed, it is safe to release the pSpace buffer used by
- ** the previous call, as the overflow cell data will have been
- ** copied either into the body of a database page or into the new
- ** pSpace buffer passed to the latter call to balance_nonroot().
- */
- u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize);
- rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints);
- if( pFree ){
- /* If pFree is not NULL, it points to the pSpace buffer used
- ** by a previous call to balance_nonroot(). Its contents are
- ** now stored either on real database pages or within the
- ** new pSpace buffer, so it may be safely freed here. */
- sqlite3PageFree(pFree);
- }
-
- /* The pSpace buffer will be freed after the next call to
- ** balance_nonroot(), or just before this function returns, whichever
- ** comes first. */
- pFree = pSpace;
- }
- }
-
- pPage->nOverflow = 0;
-
- /* The next iteration of the do-loop balances the parent page. */
- releasePage(pPage);
- pCur->iPage--;
- }
- }while( rc==SQLITE_OK );
-
- if( pFree ){
- sqlite3PageFree(pFree);
- }
- return rc;
-}
-
-
-/*
-** Insert a new record into the BTree. The key is given by (pKey,nKey)
-** and the data is given by (pData,nData). The cursor is used only to
-** define what table the record should be inserted into. The cursor
-** is left pointing at a random location.
-**
-** For an INTKEY table, only the nKey value of the key is used. pKey is
-** ignored. For a ZERODATA table, the pData and nData are both ignored.
-**
-** If the seekResult parameter is non-zero, then a successful call to
-** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already
-** been performed. seekResult is the search result returned (a negative
-** number if pCur points at an entry that is smaller than (pKey, nKey), or
-** a positive value if pCur points at an etry that is larger than
-** (pKey, nKey)).
-**
-** If the seekResult parameter is non-zero, then the caller guarantees that
-** cursor pCur is pointing at the existing copy of a row that is to be
-** overwritten. If the seekResult parameter is 0, then cursor pCur may
-** point to any entry or to no entry at all and so this function has to seek
-** the cursor before the new key can be inserted.
-*/
-SQLITE_PRIVATE int sqlite3BtreeInsert(
- BtCursor *pCur, /* Insert data into the table of this cursor */
- const void *pKey, i64 nKey, /* The key of the new record */
- const void *pData, int nData, /* The data of the new record */
- int nZero, /* Number of extra 0 bytes to append to data */
- int appendBias, /* True if this is likely an append */
- int seekResult /* Result of prior MovetoUnpacked() call */
-){
- int rc;
- int loc = seekResult; /* -1: before desired location +1: after */
- int szNew = 0;
- int idx;
- MemPage *pPage;
- Btree *p = pCur->pBtree;
- BtShared *pBt = p->pBt;
- unsigned char *oldCell;
- unsigned char *newCell = 0;
-
- if( pCur->eState==CURSOR_FAULT ){
- assert( pCur->skipNext!=SQLITE_OK );
- return pCur->skipNext;
- }
-
- assert( cursorHoldsMutex(pCur) );
- assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE
- && (pBt->btsFlags & BTS_READ_ONLY)==0 );
- assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
-
- /* Assert that the caller has been consistent. If this cursor was opened
- ** expecting an index b-tree, then the caller should be inserting blob
- ** keys with no associated data. If the cursor was opened expecting an
- ** intkey table, the caller should be inserting integer keys with a
- ** blob of associated data. */
- assert( (pKey==0)==(pCur->pKeyInfo==0) );
-
- /* Save the positions of any other cursors open on this table.
- **
- ** In some cases, the call to btreeMoveto() below is a no-op. For
- ** example, when inserting data into a table with auto-generated integer
- ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
- ** integer key to use. It then calls this function to actually insert the
- ** data into the intkey B-Tree. In this case btreeMoveto() recognizes
- ** that the cursor is already where it needs to be and returns without
- ** doing any work. To avoid thwarting these optimizations, it is important
- ** not to clear the cursor here.
- */
- rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
- if( rc ) return rc;
-
- /* If this is an insert into a table b-tree, invalidate any incrblob
- ** cursors open on the row being replaced (assuming this is a replace
- ** operation - if it is not, the following is a no-op). */
- if( pCur->pKeyInfo==0 ){
- invalidateIncrblobCursors(p, nKey, 0);
- }
-
- if( !loc ){
- rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc);
- if( rc ) return rc;
- }
- assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
-
- pPage = pCur->apPage[pCur->iPage];
- assert( pPage->intKey || nKey>=0 );
- assert( pPage->leaf || !pPage->intKey );
-
- TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
- pCur->pgnoRoot, nKey, nData, pPage->pgno,
- loc==0 ? "overwrite" : "new entry"));
- assert( pPage->isInit );
- allocateTempSpace(pBt);
- newCell = pBt->pTmpSpace;
- if( newCell==0 ) return SQLITE_NOMEM;
- rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
- if( rc ) goto end_insert;
- assert( szNew==cellSizePtr(pPage, newCell) );
- assert( szNew <= MX_CELL_SIZE(pBt) );
- idx = pCur->aiIdx[pCur->iPage];
- if( loc==0 ){
- u16 szOld;
- assert( idx<pPage->nCell );
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc ){
- goto end_insert;
- }
- oldCell = findCell(pPage, idx);
- if( !pPage->leaf ){
- memcpy(newCell, oldCell, 4);
- }
- szOld = cellSizePtr(pPage, oldCell);
- rc = clearCell(pPage, oldCell);
- dropCell(pPage, idx, szOld, &rc);
- if( rc ) goto end_insert;
- }else if( loc<0 && pPage->nCell>0 ){
- assert( pPage->leaf );
- idx = ++pCur->aiIdx[pCur->iPage];
- }else{
- assert( pPage->leaf );
- }
- insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
- assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
-
- /* If no error has occured and pPage has an overflow cell, call balance()
- ** to redistribute the cells within the tree. Since balance() may move
- ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey
- ** variables.
- **
- ** Previous versions of SQLite called moveToRoot() to move the cursor
- ** back to the root page as balance() used to invalidate the contents
- ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that,
- ** set the cursor state to "invalid". This makes common insert operations
- ** slightly faster.
- **
- ** There is a subtle but important optimization here too. When inserting
- ** multiple records into an intkey b-tree using a single cursor (as can
- ** happen while processing an "INSERT INTO ... SELECT" statement), it
- ** is advantageous to leave the cursor pointing to the last entry in
- ** the b-tree if possible. If the cursor is left pointing to the last
- ** entry in the table, and the next row inserted has an integer key
- ** larger than the largest existing key, it is possible to insert the
- ** row without seeking the cursor. This can be a big performance boost.
- */
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
- if( rc==SQLITE_OK && pPage->nOverflow ){
- rc = balance(pCur);
-
- /* Must make sure nOverflow is reset to zero even if the balance()
- ** fails. Internal data structure corruption will result otherwise.
- ** Also, set the cursor state to invalid. This stops saveCursorPosition()
- ** from trying to save the current position of the cursor. */
- pCur->apPage[pCur->iPage]->nOverflow = 0;
- pCur->eState = CURSOR_INVALID;
- }
- assert( pCur->apPage[pCur->iPage]->nOverflow==0 );
-
-end_insert:
- return rc;
-}
-
-/*
-** Delete the entry that the cursor is pointing to. The cursor
-** is left pointing at a arbitrary location.
-*/
-SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
- Btree *p = pCur->pBtree;
- BtShared *pBt = p->pBt;
- int rc; /* Return code */
- MemPage *pPage; /* Page to delete cell from */
- unsigned char *pCell; /* Pointer to cell to delete */
- int iCellIdx; /* Index of cell to delete */
- int iCellDepth; /* Depth of node containing pCell */
-
- assert( cursorHoldsMutex(pCur) );
- assert( pBt->inTransaction==TRANS_WRITE );
- assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
- assert( pCur->wrFlag );
- assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
- assert( !hasReadConflicts(p, pCur->pgnoRoot) );
-
- if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell)
- || NEVER(pCur->eState!=CURSOR_VALID)
- ){
- return SQLITE_ERROR; /* Something has gone awry. */
- }
-
- iCellDepth = pCur->iPage;
- iCellIdx = pCur->aiIdx[iCellDepth];
- pPage = pCur->apPage[iCellDepth];
- pCell = findCell(pPage, iCellIdx);
-
- /* If the page containing the entry to delete is not a leaf page, move
- ** the cursor to the largest entry in the tree that is smaller than
- ** the entry being deleted. This cell will replace the cell being deleted
- ** from the internal node. The 'previous' entry is used for this instead
- ** of the 'next' entry, as the previous entry is always a part of the
- ** sub-tree headed by the child page of the cell being deleted. This makes
- ** balancing the tree following the delete operation easier. */
- if( !pPage->leaf ){
- int notUsed;
- rc = sqlite3BtreePrevious(pCur, &notUsed);
- if( rc ) return rc;
- }
-
- /* Save the positions of any other cursors open on this table before
- ** making any modifications. Make the page containing the entry to be
- ** deleted writable. Then free any overflow pages associated with the
- ** entry and finally remove the cell itself from within the page.
- */
- rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
- if( rc ) return rc;
-
- /* If this is a delete operation to remove a row from a table b-tree,
- ** invalidate any incrblob cursors open on the row being deleted. */
- if( pCur->pKeyInfo==0 ){
- invalidateIncrblobCursors(p, pCur->info.nKey, 0);
- }
-
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc ) return rc;
- rc = clearCell(pPage, pCell);
- dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
- if( rc ) return rc;
-
- /* If the cell deleted was not located on a leaf page, then the cursor
- ** is currently pointing to the largest entry in the sub-tree headed
- ** by the child-page of the cell that was just deleted from an internal
- ** node. The cell from the leaf node needs to be moved to the internal
- ** node to replace the deleted cell. */
- if( !pPage->leaf ){
- MemPage *pLeaf = pCur->apPage[pCur->iPage];
- int nCell;
- Pgno n = pCur->apPage[iCellDepth+1]->pgno;
- unsigned char *pTmp;
-
- pCell = findCell(pLeaf, pLeaf->nCell-1);
- nCell = cellSizePtr(pLeaf, pCell);
- assert( MX_CELL_SIZE(pBt) >= nCell );
-
- allocateTempSpace(pBt);
- pTmp = pBt->pTmpSpace;
-
- rc = sqlite3PagerWrite(pLeaf->pDbPage);
- insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
- dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
- if( rc ) return rc;
- }
-
- /* Balance the tree. If the entry deleted was located on a leaf page,
- ** then the cursor still points to that page. In this case the first
- ** call to balance() repairs the tree, and the if(...) condition is
- ** never true.
- **
- ** Otherwise, if the entry deleted was on an internal node page, then
- ** pCur is pointing to the leaf page from which a cell was removed to
- ** replace the cell deleted from the internal node. This is slightly
- ** tricky as the leaf node may be underfull, and the internal node may
- ** be either under or overfull. In this case run the balancing algorithm
- ** on the leaf node first. If the balance proceeds far enough up the
- ** tree that we can be sure that any problem in the internal node has
- ** been corrected, so be it. Otherwise, after balancing the leaf node,
- ** walk the cursor up the tree to the internal node and balance it as
- ** well. */
- rc = balance(pCur);
- if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
- while( pCur->iPage>iCellDepth ){
- releasePage(pCur->apPage[pCur->iPage--]);
- }
- rc = balance(pCur);
- }
-
- if( rc==SQLITE_OK ){
- moveToRoot(pCur);
- }
- return rc;
-}
-
-/*
-** Create a new BTree table. Write into *piTable the page
-** number for the root page of the new table.
-**
-** The type of type is determined by the flags parameter. Only the
-** following values of flags are currently in use. Other values for
-** flags might not work:
-**
-** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys
-** BTREE_ZERODATA Used for SQL indices
-*/
-static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
- BtShared *pBt = p->pBt;
- MemPage *pRoot;
- Pgno pgnoRoot;
- int rc;
- int ptfFlags; /* Page-type flage for the root page of new table */
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( pBt->inTransaction==TRANS_WRITE );
- assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
-
-#ifdef SQLITE_OMIT_AUTOVACUUM
- rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
- if( rc ){
- return rc;
- }
-#else
- if( pBt->autoVacuum ){
- Pgno pgnoMove; /* Move a page here to make room for the root-page */
- MemPage *pPageMove; /* The page to move to. */
-
- /* Creating a new table may probably require moving an existing database
- ** to make room for the new tables root page. In case this page turns
- ** out to be an overflow page, delete all overflow page-map caches
- ** held by open cursors.
- */
- invalidateAllOverflowCache(pBt);
-
- /* Read the value of meta[3] from the database to determine where the
- ** root page of the new table should go. meta[3] is the largest root-page
- ** created so far, so the new root-page is (meta[3]+1).
- */
- sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
- pgnoRoot++;
-
- /* The new root-page may not be allocated on a pointer-map page, or the
- ** PENDING_BYTE page.
- */
- while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
- pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
- pgnoRoot++;
- }
- assert( pgnoRoot>=3 );
-
- /* Allocate a page. The page that currently resides at pgnoRoot will
- ** be moved to the allocated page (unless the allocated page happens
- ** to reside at pgnoRoot).
- */
- rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- if( pgnoMove!=pgnoRoot ){
- /* pgnoRoot is the page that will be used for the root-page of
- ** the new table (assuming an error did not occur). But we were
- ** allocated pgnoMove. If required (i.e. if it was not allocated
- ** by extending the file), the current page at position pgnoMove
- ** is already journaled.
- */
- u8 eType = 0;
- Pgno iPtrPage = 0;
-
- releasePage(pPageMove);
-
- /* Move the page currently at pgnoRoot to pgnoMove. */
- rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage);
- if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){
- rc = SQLITE_CORRUPT_BKPT;
- }
- if( rc!=SQLITE_OK ){
- releasePage(pRoot);
- return rc;
- }
- assert( eType!=PTRMAP_ROOTPAGE );
- assert( eType!=PTRMAP_FREEPAGE );
- rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0);
- releasePage(pRoot);
-
- /* Obtain the page at pgnoRoot */
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = sqlite3PagerWrite(pRoot->pDbPage);
- if( rc!=SQLITE_OK ){
- releasePage(pRoot);
- return rc;
- }
- }else{
- pRoot = pPageMove;
- }
-
- /* Update the pointer-map and meta-data with the new root-page number. */
- ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc);
- if( rc ){
- releasePage(pRoot);
- return rc;
- }
-
- /* When the new root page was allocated, page 1 was made writable in
- ** order either to increase the database filesize, or to decrement the
- ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail.
- */
- assert( sqlite3PagerIswriteable(pBt->pPage1->pDbPage) );
- rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot);
- if( NEVER(rc) ){
- releasePage(pRoot);
- return rc;
- }
-
- }else{
- rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);
- if( rc ) return rc;
- }
-#endif
- assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
- if( createTabFlags & BTREE_INTKEY ){
- ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF;
- }else{
- ptfFlags = PTF_ZERODATA | PTF_LEAF;
- }
- zeroPage(pRoot, ptfFlags);
- sqlite3PagerUnref(pRoot->pDbPage);
- assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 );
- *piTable = (int)pgnoRoot;
- return SQLITE_OK;
-}
-SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
- int rc;
- sqlite3BtreeEnter(p);
- rc = btreeCreateTable(p, piTable, flags);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Erase the given database page and all its children. Return
-** the page to the freelist.
-*/
-static int clearDatabasePage(
- BtShared *pBt, /* The BTree that contains the table */
- Pgno pgno, /* Page number to clear */
- int freePageFlag, /* Deallocate page if true */
- int *pnChange /* Add number of Cells freed to this counter */
-){
- MemPage *pPage;
- int rc;
- unsigned char *pCell;
- int i;
-
- assert( sqlite3_mutex_held(pBt->mutex) );
- if( pgno>btreePagecount(pBt) ){
- return SQLITE_CORRUPT_BKPT;
- }
-
- rc = getAndInitPage(pBt, pgno, &pPage);
- if( rc ) return rc;
- for(i=0; i<pPage->nCell; i++){
- pCell = findCell(pPage, i);
- if( !pPage->leaf ){
- rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
- if( rc ) goto cleardatabasepage_out;
- }
- rc = clearCell(pPage, pCell);
- if( rc ) goto cleardatabasepage_out;
- }
- if( !pPage->leaf ){
- rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), 1, pnChange);
- if( rc ) goto cleardatabasepage_out;
- }else if( pnChange ){
- assert( pPage->intKey );
- *pnChange += pPage->nCell;
- }
- if( freePageFlag ){
- freePage(pPage, &rc);
- }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
- zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
- }
-
-cleardatabasepage_out:
- releasePage(pPage);
- return rc;
-}
-
-/*
-** Delete all information from a single table in the database. iTable is
-** the page number of the root of the table. After this routine returns,
-** the root page is empty, but still exists.
-**
-** This routine will fail with SQLITE_LOCKED if there are any open
-** read cursors on the table. Open write cursors are moved to the
-** root of the table.
-**
-** If pnChange is not NULL, then table iTable must be an intkey table. The
-** integer value pointed to by pnChange is incremented by the number of
-** entries in the table.
-*/
-SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){
- int rc;
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
- assert( p->inTrans==TRANS_WRITE );
-
- rc = saveAllCursors(pBt, (Pgno)iTable, 0);
-
- if( SQLITE_OK==rc ){
- /* Invalidate all incrblob cursors open on table iTable (assuming iTable
- ** is the root of a table b-tree - if it is not, the following call is
- ** a no-op). */
- invalidateIncrblobCursors(p, 0, 1);
- rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange);
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-/*
-** Erase all information in a table and add the root of the table to
-** the freelist. Except, the root of the principle table (the one on
-** page 1) is never added to the freelist.
-**
-** This routine will fail with SQLITE_LOCKED if there are any open
-** cursors on the table.
-**
-** If AUTOVACUUM is enabled and the page at iTable is not the last
-** root page in the database file, then the last root page
-** in the database file is moved into the slot formerly occupied by
-** iTable and that last slot formerly occupied by the last root page
-** is added to the freelist instead of iTable. In this say, all
-** root pages are kept at the beginning of the database file, which
-** is necessary for AUTOVACUUM to work right. *piMoved is set to the
-** page number that used to be the last root page in the file before
-** the move. If no page gets moved, *piMoved is set to 0.
-** The last root page is recorded in meta[3] and the value of
-** meta[3] is updated by this procedure.
-*/
-static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
- int rc;
- MemPage *pPage = 0;
- BtShared *pBt = p->pBt;
-
- assert( sqlite3BtreeHoldsMutex(p) );
- assert( p->inTrans==TRANS_WRITE );
-
- /* It is illegal to drop a table if any cursors are open on the
- ** database. This is because in auto-vacuum mode the backend may
- ** need to move another root-page to fill a gap left by the deleted
- ** root page. If an open cursor was using this page a problem would
- ** occur.
- **
- ** This error is caught long before control reaches this point.
- */
- if( NEVER(pBt->pCursor) ){
- sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db);
- return SQLITE_LOCKED_SHAREDCACHE;
- }
-
- rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
- if( rc ) return rc;
- rc = sqlite3BtreeClearTable(p, iTable, 0);
- if( rc ){
- releasePage(pPage);
- return rc;
- }
-
- *piMoved = 0;
-
- if( iTable>1 ){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- freePage(pPage, &rc);
- releasePage(pPage);
-#else
- if( pBt->autoVacuum ){
- Pgno maxRootPgno;
- sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
-
- if( iTable==maxRootPgno ){
- /* If the table being dropped is the table with the largest root-page
- ** number in the database, put the root page on the free list.
- */
- freePage(pPage, &rc);
- releasePage(pPage);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }else{
- /* The table being dropped does not have the largest root-page
- ** number in the database. So move the page that does into the
- ** gap left by the deleted root-page.
- */
- MemPage *pMove;
- releasePage(pPage);
- rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0);
- releasePage(pMove);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pMove = 0;
- rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
- freePage(pMove, &rc);
- releasePage(pMove);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- *piMoved = maxRootPgno;
- }
-
- /* Set the new 'max-root-page' value in the database header. This
- ** is the old value less one, less one more if that happens to
- ** be a root-page number, less one again if that is the
- ** PENDING_BYTE_PAGE.
- */
- maxRootPgno--;
- while( maxRootPgno==PENDING_BYTE_PAGE(pBt)
- || PTRMAP_ISPAGE(pBt, maxRootPgno) ){
- maxRootPgno--;
- }
- assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) );
-
- rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno);
- }else{
- freePage(pPage, &rc);
- releasePage(pPage);
- }
-#endif
- }else{
- /* If sqlite3BtreeDropTable was called on page 1.
- ** This really never should happen except in a corrupt
- ** database.
- */
- zeroPage(pPage, PTF_INTKEY|PTF_LEAF );
- releasePage(pPage);
- }
- return rc;
-}
-SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
- int rc;
- sqlite3BtreeEnter(p);
- rc = btreeDropTable(p, iTable, piMoved);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-
-/*
-** This function may only be called if the b-tree connection already
-** has a read or write transaction open on the database.
-**
-** Read the meta-information out of a database file. Meta[0]
-** is the number of free pages currently in the database. Meta[1]
-** through meta[15] are available for use by higher layers. Meta[0]
-** is read-only, the others are read/write.
-**
-** The schema layer numbers meta values differently. At the schema
-** layer (and the SetCookie and ReadCookie opcodes) the number of
-** free pages is not visible. So Cookie[0] is the same as Meta[1].
-*/
-SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
- BtShared *pBt = p->pBt;
-
- sqlite3BtreeEnter(p);
- assert( p->inTrans>TRANS_NONE );
- assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) );
- assert( pBt->pPage1 );
- assert( idx>=0 && idx<=15 );
-
- *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
-
- /* If auto-vacuum is disabled in this build and this is an auto-vacuum
- ** database, mark the database as read-only. */
-#ifdef SQLITE_OMIT_AUTOVACUUM
- if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){
- pBt->btsFlags |= BTS_READ_ONLY;
- }
-#endif
-
- sqlite3BtreeLeave(p);
-}
-
-/*
-** Write meta-information back into the database. Meta[0] is
-** read-only and may not be written.
-*/
-SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
- BtShared *pBt = p->pBt;
- unsigned char *pP1;
- int rc;
- assert( idx>=1 && idx<=15 );
- sqlite3BtreeEnter(p);
- assert( p->inTrans==TRANS_WRITE );
- assert( pBt->pPage1!=0 );
- pP1 = pBt->pPage1->aData;
- rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
- if( rc==SQLITE_OK ){
- put4byte(&pP1[36 + idx*4], iMeta);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( idx==BTREE_INCR_VACUUM ){
- assert( pBt->autoVacuum || iMeta==0 );
- assert( iMeta==0 || iMeta==1 );
- pBt->incrVacuum = (u8)iMeta;
- }
-#endif
- }
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_BTREECOUNT
-/*
-** The first argument, pCur, is a cursor opened on some b-tree. Count the
-** number of entries in the b-tree and write the result to *pnEntry.
-**
-** SQLITE_OK is returned if the operation is successfully executed.
-** Otherwise, if an error is encountered (i.e. an IO error or database
-** corruption) an SQLite error code is returned.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
- i64 nEntry = 0; /* Value to return in *pnEntry */
- int rc; /* Return code */
-
- if( pCur->pgnoRoot==0 ){
- *pnEntry = 0;
- return SQLITE_OK;
- }
- rc = moveToRoot(pCur);
-
- /* Unless an error occurs, the following loop runs one iteration for each
- ** page in the B-Tree structure (not including overflow pages).
- */
- while( rc==SQLITE_OK ){
- int iIdx; /* Index of child node in parent */
- MemPage *pPage; /* Current page of the b-tree */
-
- /* If this is a leaf page or the tree is not an int-key tree, then
- ** this page contains countable entries. Increment the entry counter
- ** accordingly.
- */
- pPage = pCur->apPage[pCur->iPage];
- if( pPage->leaf || !pPage->intKey ){
- nEntry += pPage->nCell;
- }
-
- /* pPage is a leaf node. This loop navigates the cursor so that it
- ** points to the first interior cell that it points to the parent of
- ** the next page in the tree that has not yet been visited. The
- ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell
- ** of the page, or to the number of cells in the page if the next page
- ** to visit is the right-child of its parent.
- **
- ** If all pages in the tree have been visited, return SQLITE_OK to the
- ** caller.
- */
- if( pPage->leaf ){
- do {
- if( pCur->iPage==0 ){
- /* All pages of the b-tree have been visited. Return successfully. */
- *pnEntry = nEntry;
- return SQLITE_OK;
- }
- moveToParent(pCur);
- }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
-
- pCur->aiIdx[pCur->iPage]++;
- pPage = pCur->apPage[pCur->iPage];
- }
-
- /* Descend to the child node of the cell that the cursor currently
- ** points at. This is the right-child if (iIdx==pPage->nCell).
- */
- iIdx = pCur->aiIdx[pCur->iPage];
- if( iIdx==pPage->nCell ){
- rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
- }else{
- rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx)));
- }
- }
-
- /* An error has occurred. Return an error code. */
- return rc;
-}
-#endif
-
-/*
-** Return the pager associated with a BTree. This routine is used for
-** testing and debugging only.
-*/
-SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){
- return p->pBt->pPager;
-}
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/*
-** Append a message to the error message string.
-*/
-static void checkAppendMsg(
- IntegrityCk *pCheck,
- char *zMsg1,
- const char *zFormat,
- ...
-){
- va_list ap;
- if( !pCheck->mxErr ) return;
- pCheck->mxErr--;
- pCheck->nErr++;
- va_start(ap, zFormat);
- if( pCheck->errMsg.nChar ){
- sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
- }
- if( zMsg1 ){
- sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1);
- }
- sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
- va_end(ap);
- if( pCheck->errMsg.mallocFailed ){
- pCheck->mallocFailed = 1;
- }
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-
-/*
-** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that
-** corresponds to page iPg is already set.
-*/
-static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){
- assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 );
- return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07)));
-}
-
-/*
-** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg.
-*/
-static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){
- assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 );
- pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07));
-}
-
-
-/*
-** Add 1 to the reference count for page iPage. If this is the second
-** reference to the page, add an error message to pCheck->zErrMsg.
-** Return 1 if there are 2 ore more references to the page and 0 if
-** if this is the first reference to the page.
-**
-** Also check that the page number is in bounds.
-*/
-static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){
- if( iPage==0 ) return 1;
- if( iPage>pCheck->nPage ){
- checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
- return 1;
- }
- if( getPageReferenced(pCheck, iPage) ){
- checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
- return 1;
- }
- setPageReferenced(pCheck, iPage);
- return 0;
-}
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** Check that the entry in the pointer-map for page iChild maps to
-** page iParent, pointer type ptrType. If not, append an error message
-** to pCheck.
-*/
-static void checkPtrmap(
- IntegrityCk *pCheck, /* Integrity check context */
- Pgno iChild, /* Child page number */
- u8 eType, /* Expected pointer map type */
- Pgno iParent, /* Expected pointer map parent page number */
- char *zContext /* Context description (used for error msg) */
-){
- int rc;
- u8 ePtrmapType;
- Pgno iPtrmapParent;
-
- rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
- checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
- return;
- }
-
- if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
- checkAppendMsg(pCheck, zContext,
- "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
- iChild, eType, iParent, ePtrmapType, iPtrmapParent);
- }
-}
-#endif
-
-/*
-** Check the integrity of the freelist or of an overflow page list.
-** Verify that the number of pages on the list is N.
-*/
-static void checkList(
- IntegrityCk *pCheck, /* Integrity checking context */
- int isFreeList, /* True for a freelist. False for overflow page list */
- int iPage, /* Page number for first page in the list */
- int N, /* Expected number of pages in the list */
- char *zContext /* Context for error messages */
-){
- int i;
- int expected = N;
- int iFirst = iPage;
- while( N-- > 0 && pCheck->mxErr ){
- DbPage *pOvflPage;
- unsigned char *pOvflData;
- if( iPage<1 ){
- checkAppendMsg(pCheck, zContext,
- "%d of %d pages missing from overflow list starting at %d",
- N+1, expected, iFirst);
- break;
- }
- if( checkRef(pCheck, iPage, zContext) ) break;
- if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
- checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
- break;
- }
- pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
- if( isFreeList ){
- int n = get4byte(&pOvflData[4]);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pCheck->pBt->autoVacuum ){
- checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
- }
-#endif
- if( n>(int)pCheck->pBt->usableSize/4-2 ){
- checkAppendMsg(pCheck, zContext,
- "freelist leaf count too big on page %d", iPage);
- N--;
- }else{
- for(i=0; i<n; i++){
- Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pCheck->pBt->autoVacuum ){
- checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
- }
-#endif
- checkRef(pCheck, iFreePage, zContext);
- }
- N -= n;
- }
- }
-#ifndef SQLITE_OMIT_AUTOVACUUM
- else{
- /* If this database supports auto-vacuum and iPage is not the last
- ** page in this overflow list, check that the pointer-map entry for
- ** the following page matches iPage.
- */
- if( pCheck->pBt->autoVacuum && N>0 ){
- i = get4byte(pOvflData);
- checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
- }
- }
-#endif
- iPage = get4byte(pOvflData);
- sqlite3PagerUnref(pOvflPage);
- }
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/*
-** Do various sanity checks on a single page of a tree. Return
-** the tree depth. Root pages return 0. Parents of root pages
-** return 1, and so forth.
-**
-** These checks are done:
-**
-** 1. Make sure that cells and freeblocks do not overlap
-** but combine to completely cover the page.
-** NO 2. Make sure cell keys are in order.
-** NO 3. Make sure no key is less than or equal to zLowerBound.
-** NO 4. Make sure no key is greater than or equal to zUpperBound.
-** 5. Check the integrity of overflow pages.
-** 6. Recursively call checkTreePage on all children.
-** 7. Verify that the depth of all children is the same.
-** 8. Make sure this page is at least 33% full or else it is
-** the root of the tree.
-*/
-static int checkTreePage(
- IntegrityCk *pCheck, /* Context for the sanity check */
- int iPage, /* Page number of the page to check */
- char *zParentContext, /* Parent context */
- i64 *pnParentMinKey,
- i64 *pnParentMaxKey
-){
- MemPage *pPage;
- int i, rc, depth, d2, pgno, cnt;
- int hdr, cellStart;
- int nCell;
- u8 *data;
- BtShared *pBt;
- int usableSize;
- char zContext[100];
- char *hit = 0;
- i64 nMinKey = 0;
- i64 nMaxKey = 0;
-
- sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage);
-
- /* Check that the page exists
- */
- pBt = pCheck->pBt;
- usableSize = pBt->usableSize;
- if( iPage==0 ) return 0;
- if( checkRef(pCheck, iPage, zParentContext) ) return 0;
- if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
- checkAppendMsg(pCheck, zContext,
- "unable to get the page. error code=%d", rc);
- return 0;
- }
-
- /* Clear MemPage.isInit to make sure the corruption detection code in
- ** btreeInitPage() is executed. */
- pPage->isInit = 0;
- if( (rc = btreeInitPage(pPage))!=0 ){
- assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */
- checkAppendMsg(pCheck, zContext,
- "btreeInitPage() returns error code %d", rc);
- releasePage(pPage);
- return 0;
- }
-
- /* Check out all the cells.
- */
- depth = 0;
- for(i=0; i<pPage->nCell && pCheck->mxErr; i++){
- u8 *pCell;
- u32 sz;
- CellInfo info;
-
- /* Check payload overflow pages
- */
- sqlite3_snprintf(sizeof(zContext), zContext,
- "On tree page %d cell %d: ", iPage, i);
- pCell = findCell(pPage,i);
- btreeParseCellPtr(pPage, pCell, &info);
- sz = info.nData;
- if( !pPage->intKey ) sz += (int)info.nKey;
- /* For intKey pages, check that the keys are in order.
- */
- else if( i==0 ) nMinKey = nMaxKey = info.nKey;
- else{
- if( info.nKey <= nMaxKey ){
- checkAppendMsg(pCheck, zContext,
- "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
- }
- nMaxKey = info.nKey;
- }
- assert( sz==info.nPayload );
- if( (sz>info.nLocal)
- && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
- ){
- int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4);
- Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
- checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
- }
-#endif
- checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
- }
-
- /* Check sanity of left child page.
- */
- if( !pPage->leaf ){
- pgno = get4byte(pCell);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
- checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
- }
-#endif
- d2 = checkTreePage(pCheck, pgno, zContext, &nMinKey, i==0 ? NULL : &nMaxKey);
- if( i>0 && d2!=depth ){
- checkAppendMsg(pCheck, zContext, "Child page depth differs");
- }
- depth = d2;
- }
- }
-
- if( !pPage->leaf ){
- pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- sqlite3_snprintf(sizeof(zContext), zContext,
- "On page %d at right child: ", iPage);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum ){
- checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
- }
-#endif
- checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey);
- }
-
- /* For intKey leaf pages, check that the min/max keys are in order
- ** with any left/parent/right pages.
- */
- if( pPage->leaf && pPage->intKey ){
- /* if we are a left child page */
- if( pnParentMinKey ){
- /* if we are the left most child page */
- if( !pnParentMaxKey ){
- if( nMaxKey > *pnParentMinKey ){
- checkAppendMsg(pCheck, zContext,
- "Rowid %lld out of order (max larger than parent min of %lld)",
- nMaxKey, *pnParentMinKey);
- }
- }else{
- if( nMinKey <= *pnParentMinKey ){
- checkAppendMsg(pCheck, zContext,
- "Rowid %lld out of order (min less than parent min of %lld)",
- nMinKey, *pnParentMinKey);
- }
- if( nMaxKey > *pnParentMaxKey ){
- checkAppendMsg(pCheck, zContext,
- "Rowid %lld out of order (max larger than parent max of %lld)",
- nMaxKey, *pnParentMaxKey);
- }
- *pnParentMinKey = nMaxKey;
- }
- /* else if we're a right child page */
- } else if( pnParentMaxKey ){
- if( nMinKey <= *pnParentMaxKey ){
- checkAppendMsg(pCheck, zContext,
- "Rowid %lld out of order (min less than parent max of %lld)",
- nMinKey, *pnParentMaxKey);
- }
- }
- }
-
- /* Check for complete coverage of the page
- */
- data = pPage->aData;
- hdr = pPage->hdrOffset;
- hit = sqlite3PageMalloc( pBt->pageSize );
- if( hit==0 ){
- pCheck->mallocFailed = 1;
- }else{
- int contentOffset = get2byteNotZero(&data[hdr+5]);
- assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */
- memset(hit+contentOffset, 0, usableSize-contentOffset);
- memset(hit, 1, contentOffset);
- nCell = get2byte(&data[hdr+3]);
- cellStart = hdr + 12 - 4*pPage->leaf;
- for(i=0; i<nCell; i++){
- int pc = get2byte(&data[cellStart+i*2]);
- u32 size = 65536;
- int j;
- if( pc<=usableSize-4 ){
- size = cellSizePtr(pPage, &data[pc]);
- }
- if( (int)(pc+size-1)>=usableSize ){
- checkAppendMsg(pCheck, 0,
- "Corruption detected in cell %d on page %d",i,iPage);
- }else{
- for(j=pc+size-1; j>=pc; j--) hit[j]++;
- }
- }
- i = get2byte(&data[hdr+1]);
- while( i>0 ){
- int size, j;
- assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */
- size = get2byte(&data[i+2]);
- assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */
- for(j=i+size-1; j>=i; j--) hit[j]++;
- j = get2byte(&data[i]);
- assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */
- assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */
- i = j;
- }
- for(i=cnt=0; i<usableSize; i++){
- if( hit[i]==0 ){
- cnt++;
- }else if( hit[i]>1 ){
- checkAppendMsg(pCheck, 0,
- "Multiple uses for byte %d of page %d", i, iPage);
- break;
- }
- }
- if( cnt!=data[hdr+7] ){
- checkAppendMsg(pCheck, 0,
- "Fragmentation of %d bytes reported as %d on page %d",
- cnt, data[hdr+7], iPage);
- }
- }
- sqlite3PageFree(hit);
- releasePage(pPage);
- return depth+1;
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/*
-** This routine does a complete check of the given BTree file. aRoot[] is
-** an array of pages numbers were each page number is the root page of
-** a table. nRoot is the number of entries in aRoot.
-**
-** A read-only or read-write transaction must be opened before calling
-** this function.
-**
-** Write the number of error seen in *pnErr. Except for some memory
-** allocation errors, an error message held in memory obtained from
-** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is
-** returned. If a memory allocation error occurs, NULL is returned.
-*/
-SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
- Btree *p, /* The btree to be checked */
- int *aRoot, /* An array of root pages numbers for individual trees */
- int nRoot, /* Number of entries in aRoot[] */
- int mxErr, /* Stop reporting errors after this many */
- int *pnErr /* Write number of errors seen to this variable */
-){
- Pgno i;
- int nRef;
- IntegrityCk sCheck;
- BtShared *pBt = p->pBt;
- char zErr[100];
-
- sqlite3BtreeEnter(p);
- assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
- nRef = sqlite3PagerRefcount(pBt->pPager);
- sCheck.pBt = pBt;
- sCheck.pPager = pBt->pPager;
- sCheck.nPage = btreePagecount(sCheck.pBt);
- sCheck.mxErr = mxErr;
- sCheck.nErr = 0;
- sCheck.mallocFailed = 0;
- *pnErr = 0;
- if( sCheck.nPage==0 ){
- sqlite3BtreeLeave(p);
- return 0;
- }
-
- sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
- if( !sCheck.aPgRef ){
- *pnErr = 1;
- sqlite3BtreeLeave(p);
- return 0;
- }
- i = PENDING_BYTE_PAGE(pBt);
- if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
- sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000);
- sCheck.errMsg.useMalloc = 2;
-
- /* Check the integrity of the freelist
- */
- checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
- get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
-
- /* Check all the tables.
- */
- for(i=0; (int)i<nRoot && sCheck.mxErr; i++){
- if( aRoot[i]==0 ) continue;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( pBt->autoVacuum && aRoot[i]>1 ){
- checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
- }
-#endif
- checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);
- }
-
- /* Make sure every page in the file is referenced
- */
- for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- if( getPageReferenced(&sCheck, i)==0 ){
- checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
- }
-#else
- /* If the database supports auto-vacuum, make sure no tables contain
- ** references to pointer-map pages.
- */
- if( getPageReferenced(&sCheck, i)==0 &&
- (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
- checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
- }
- if( getPageReferenced(&sCheck, i)!=0 &&
- (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
- checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
- }
-#endif
- }
-
- /* Make sure this analysis did not leave any unref() pages.
- ** This is an internal consistency check; an integrity check
- ** of the integrity check.
- */
- if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
- checkAppendMsg(&sCheck, 0,
- "Outstanding page count goes from %d to %d during this analysis",
- nRef, sqlite3PagerRefcount(pBt->pPager)
- );
- }
-
- /* Clean up and report errors.
- */
- sqlite3BtreeLeave(p);
- sqlite3_free(sCheck.aPgRef);
- if( sCheck.mallocFailed ){
- sqlite3StrAccumReset(&sCheck.errMsg);
- *pnErr = sCheck.nErr+1;
- return 0;
- }
- *pnErr = sCheck.nErr;
- if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
- return sqlite3StrAccumFinish(&sCheck.errMsg);
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-/*
-** Return the full pathname of the underlying database file. Return
-** an empty string if the database is in-memory or a TEMP database.
-**
-** The pager filename is invariant as long as the pager is
-** open so it is safe to access without the BtShared mutex.
-*/
-SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){
- assert( p->pBt->pPager!=0 );
- return sqlite3PagerFilename(p->pBt->pPager, 1);
-}
-
-/*
-** Return the pathname of the journal file for this database. The return
-** value of this routine is the same regardless of whether the journal file
-** has been created or not.
-**
-** The pager journal filename is invariant as long as the pager is
-** open so it is safe to access without the BtShared mutex.
-*/
-SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){
- assert( p->pBt->pPager!=0 );
- return sqlite3PagerJournalname(p->pBt->pPager);
-}
-
-/*
-** Return non-zero if a transaction is active.
-*/
-SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree *p){
- assert( p==0 || sqlite3_mutex_held(p->db->mutex) );
- return (p && (p->inTrans==TRANS_WRITE));
-}
-
-#ifndef SQLITE_OMIT_WAL
-/*
-** Run a checkpoint on the Btree passed as the first argument.
-**
-** Return SQLITE_LOCKED if this or any other connection has an open
-** transaction on the shared-cache the argument Btree is connected to.
-**
-** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){
- int rc = SQLITE_OK;
- if( p ){
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
- if( pBt->inTransaction!=TRANS_NONE ){
- rc = SQLITE_LOCKED;
- }else{
- rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt);
- }
- sqlite3BtreeLeave(p);
- }
- return rc;
-}
-#endif
-
-/*
-** Return non-zero if a read (or write) transaction is active.
-*/
-SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree *p){
- assert( p );
- assert( sqlite3_mutex_held(p->db->mutex) );
- return p->inTrans!=TRANS_NONE;
-}
-
-SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){
- assert( p );
- assert( sqlite3_mutex_held(p->db->mutex) );
- return p->nBackup!=0;
-}
-
-/*
-** This function returns a pointer to a blob of memory associated with
-** a single shared-btree. The memory is used by client code for its own
-** purposes (for example, to store a high-level schema associated with
-** the shared-btree). The btree layer manages reference counting issues.
-**
-** The first time this is called on a shared-btree, nBytes bytes of memory
-** are allocated, zeroed, and returned to the caller. For each subsequent
-** call the nBytes parameter is ignored and a pointer to the same blob
-** of memory returned.
-**
-** If the nBytes parameter is 0 and the blob of memory has not yet been
-** allocated, a null pointer is returned. If the blob has already been
-** allocated, it is returned as normal.
-**
-** Just before the shared-btree is closed, the function passed as the
-** xFree argument when the memory allocation was made is invoked on the
-** blob of allocated memory. The xFree function should not call sqlite3_free()
-** on the memory, the btree layer does that.
-*/
-SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
- BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
- if( !pBt->pSchema && nBytes ){
- pBt->pSchema = sqlite3DbMallocZero(0, nBytes);
- pBt->xFreeSchema = xFree;
- }
- sqlite3BtreeLeave(p);
- return pBt->pSchema;
-}
-
-/*
-** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared
-** btree as the argument handle holds an exclusive lock on the
-** sqlite_master table. Otherwise SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){
- int rc;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
- assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE );
- sqlite3BtreeLeave(p);
- return rc;
-}
-
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** Obtain a lock on the table whose root page is iTab. The
-** lock is a write lock if isWritelock is true or a read lock
-** if it is false.
-*/
-SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
- int rc = SQLITE_OK;
- assert( p->inTrans!=TRANS_NONE );
- if( p->sharable ){
- u8 lockType = READ_LOCK + isWriteLock;
- assert( READ_LOCK+1==WRITE_LOCK );
- assert( isWriteLock==0 || isWriteLock==1 );
-
- sqlite3BtreeEnter(p);
- rc = querySharedCacheTableLock(p, iTab, lockType);
- if( rc==SQLITE_OK ){
- rc = setSharedCacheTableLock(p, iTab, lockType);
- }
- sqlite3BtreeLeave(p);
- }
- return rc;
-}
-#endif
-
-#ifndef SQLITE_OMIT_INCRBLOB
-/*
-** Argument pCsr must be a cursor opened for writing on an
-** INTKEY table currently pointing at a valid table entry.
-** This function modifies the data stored as part of that entry.
-**
-** Only the data content may only be modified, it is not possible to
-** change the length of the data stored. If this function is called with
-** parameters that attempt to write past the end of the existing data,
-** no modifications are made and SQLITE_CORRUPT is returned.
-*/
-SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
- int rc;
- assert( cursorHoldsMutex(pCsr) );
- assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
- assert( pCsr->isIncrblobHandle );
-
- rc = restoreCursorPosition(pCsr);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- assert( pCsr->eState!=CURSOR_REQUIRESEEK );
- if( pCsr->eState!=CURSOR_VALID ){
- return SQLITE_ABORT;
- }
-
- /* Check some assumptions:
- ** (a) the cursor is open for writing,
- ** (b) there is a read/write transaction open,
- ** (c) the connection holds a write-lock on the table (if required),
- ** (d) there are no conflicting read-locks, and
- ** (e) the cursor points at a valid row of an intKey table.
- */
- if( !pCsr->wrFlag ){
- return SQLITE_READONLY;
- }
- assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0
- && pCsr->pBt->inTransaction==TRANS_WRITE );
- assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) );
- assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) );
- assert( pCsr->apPage[pCsr->iPage]->intKey );
-
- return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1);
-}
-
-/*
-** Set a flag on this cursor to cache the locations of pages from the
-** overflow list for the current row. This is used by cursors opened
-** for incremental blob IO only.
-**
-** This function sets a flag only. The actual page location cache
-** (stored in BtCursor.aOverflow[]) is allocated and used by function
-** accessPayload() (the worker function for sqlite3BtreeData() and
-** sqlite3BtreePutData()).
-*/
-SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *pCur){
- assert( cursorHoldsMutex(pCur) );
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- invalidateOverflowCache(pCur);
- pCur->isIncrblobHandle = 1;
-}
-#endif
-
-/*
-** Set both the "read version" (single byte at byte offset 18) and
-** "write version" (single byte at byte offset 19) fields in the database
-** header to iVersion.
-*/
-SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
- BtShared *pBt = pBtree->pBt;
- int rc; /* Return code */
-
- assert( iVersion==1 || iVersion==2 );
-
- /* If setting the version fields to 1, do not automatically open the
- ** WAL connection, even if the version fields are currently set to 2.
- */
- pBt->btsFlags &= ~BTS_NO_WAL;
- if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL;
-
- rc = sqlite3BtreeBeginTrans(pBtree, 0);
- if( rc==SQLITE_OK ){
- u8 *aData = pBt->pPage1->aData;
- if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){
- rc = sqlite3BtreeBeginTrans(pBtree, 2);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
- if( rc==SQLITE_OK ){
- aData[18] = (u8)iVersion;
- aData[19] = (u8)iVersion;
- }
- }
- }
- }
-
- pBt->btsFlags &= ~BTS_NO_WAL;
- return rc;
-}
-
-/*
-** set the mask of hint flags for cursor pCsr. Currently the only valid
-** values are 0 and BTREE_BULKLOAD.
-*/
-SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
- assert( mask==BTREE_BULKLOAD || mask==0 );
- pCsr->hints = mask;
-}
-
-/************** End of btree.c ***********************************************/
-/************** Begin file backup.c ******************************************/
-/*
-** 2009 January 28
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the implementation of the sqlite3_backup_XXX()
-** API functions and the related features.
-*/
-
-/* Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
-/*
-** Structure allocated for each backup operation.
-*/
-struct sqlite3_backup {
- sqlite3* pDestDb; /* Destination database handle */
- Btree *pDest; /* Destination b-tree file */
- u32 iDestSchema; /* Original schema cookie in destination */
- int bDestLocked; /* True once a write-transaction is open on pDest */
-
- Pgno iNext; /* Page number of the next source page to copy */
- sqlite3* pSrcDb; /* Source database handle */
- Btree *pSrc; /* Source b-tree file */
-
- int rc; /* Backup process error code */
-
- /* These two variables are set by every call to backup_step(). They are
- ** read by calls to backup_remaining() and backup_pagecount().
- */
- Pgno nRemaining; /* Number of pages left to copy */
- Pgno nPagecount; /* Total number of pages to copy */
-
- int isAttached; /* True once backup has been registered with pager */
- sqlite3_backup *pNext; /* Next backup associated with source pager */
-};
-
-/*
-** THREAD SAFETY NOTES:
-**
-** Once it has been created using backup_init(), a single sqlite3_backup
-** structure may be accessed via two groups of thread-safe entry points:
-**
-** * Via the sqlite3_backup_XXX() API function backup_step() and
-** backup_finish(). Both these functions obtain the source database
-** handle mutex and the mutex associated with the source BtShared
-** structure, in that order.
-**
-** * Via the BackupUpdate() and BackupRestart() functions, which are
-** invoked by the pager layer to report various state changes in
-** the page cache associated with the source database. The mutex
-** associated with the source database BtShared structure will always
-** be held when either of these functions are invoked.
-**
-** The other sqlite3_backup_XXX() API functions, backup_remaining() and
-** backup_pagecount() are not thread-safe functions. If they are called
-** while some other thread is calling backup_step() or backup_finish(),
-** the values returned may be invalid. There is no way for a call to
-** BackupUpdate() or BackupRestart() to interfere with backup_remaining()
-** or backup_pagecount().
-**
-** Depending on the SQLite configuration, the database handles and/or
-** the Btree objects may have their own mutexes that require locking.
-** Non-sharable Btrees (in-memory databases for example), do not have
-** associated mutexes.
-*/
-
-/*
-** Return a pointer corresponding to database zDb (i.e. "main", "temp")
-** in connection handle pDb. If such a database cannot be found, return
-** a NULL pointer and write an error message to pErrorDb.
-**
-** If the "temp" database is requested, it may need to be opened by this
-** function. If an error occurs while doing so, return 0 and write an
-** error message to pErrorDb.
-*/
-static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
- int i = sqlite3FindDbName(pDb, zDb);
-
- if( i==1 ){
- Parse *pParse;
- int rc = 0;
- pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
- if( pParse==0 ){
- sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory");
- rc = SQLITE_NOMEM;
- }else{
- pParse->db = pDb;
- if( sqlite3OpenTempDatabase(pParse) ){
- sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
- rc = SQLITE_ERROR;
- }
- sqlite3DbFree(pErrorDb, pParse->zErrMsg);
- sqlite3StackFree(pErrorDb, pParse);
- }
- if( rc ){
- return 0;
- }
- }
-
- if( i<0 ){
- sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
- return 0;
- }
-
- return pDb->aDb[i].pBt;
-}
-
-/*
-** Attempt to set the page size of the destination to match the page size
-** of the source.
-*/
-static int setDestPgsz(sqlite3_backup *p){
- int rc;
- rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
- return rc;
-}
-
-/*
-** Create an sqlite3_backup process to copy the contents of zSrcDb from
-** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
-** a pointer to the new sqlite3_backup object.
-**
-** If an error occurs, NULL is returned and an error code and error message
-** stored in database handle pDestDb.
-*/
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
- sqlite3* pDestDb, /* Database to write to */
- const char *zDestDb, /* Name of database within pDestDb */
- sqlite3* pSrcDb, /* Database connection to read from */
- const char *zSrcDb /* Name of database within pSrcDb */
-){
- sqlite3_backup *p; /* Value to return */
-
- /* Lock the source database handle. The destination database
- ** handle is not locked in this routine, but it is locked in
- ** sqlite3_backup_step(). The user is required to ensure that no
- ** other thread accesses the destination handle for the duration
- ** of the backup operation. Any attempt to use the destination
- ** database connection while a backup is in progress may cause
- ** a malfunction or a deadlock.
- */
- sqlite3_mutex_enter(pSrcDb->mutex);
- sqlite3_mutex_enter(pDestDb->mutex);
-
- if( pSrcDb==pDestDb ){
- sqlite3Error(
- pDestDb, SQLITE_ERROR, "source and destination must be distinct"
- );
- p = 0;
- }else {
- /* Allocate space for a new sqlite3_backup object...
- ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
- ** call to sqlite3_backup_init() and is destroyed by a call to
- ** sqlite3_backup_finish(). */
- p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
- if( !p ){
- sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
- }
- }
-
- /* If the allocation succeeded, populate the new object. */
- if( p ){
- p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
- p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
- p->pDestDb = pDestDb;
- p->pSrcDb = pSrcDb;
- p->iNext = 1;
- p->isAttached = 0;
-
- if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){
- /* One (or both) of the named databases did not exist or an OOM
- ** error was hit. The error has already been written into the
- ** pDestDb handle. All that is left to do here is free the
- ** sqlite3_backup structure.
- */
- sqlite3_free(p);
- p = 0;
- }
- }
- if( p ){
- p->pSrc->nBackup++;
- }
-
- sqlite3_mutex_leave(pDestDb->mutex);
- sqlite3_mutex_leave(pSrcDb->mutex);
- return p;
-}
-
-/*
-** Argument rc is an SQLite error code. Return true if this error is
-** considered fatal if encountered during a backup operation. All errors
-** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED.
-*/
-static int isFatalError(int rc){
- return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED));
-}
-
-/*
-** Parameter zSrcData points to a buffer containing the data for
-** page iSrcPg from the source database. Copy this data into the
-** destination database.
-*/
-static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
- Pager * const pDestPager = sqlite3BtreePager(p->pDest);
- const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
- int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
- const int nCopy = MIN(nSrcPgsz, nDestPgsz);
- const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
-#ifdef SQLITE_HAS_CODEC
- /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
- ** guaranteed that the shared-mutex is held by this thread, handle
- ** p->pSrc may not actually be the owner. */
- int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
- int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
-#endif
- int rc = SQLITE_OK;
- i64 iOff;
-
- assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
- assert( p->bDestLocked );
- assert( !isFatalError(p->rc) );
- assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
- assert( zSrcData );
-
- /* Catch the case where the destination is an in-memory database and the
- ** page sizes of the source and destination differ.
- */
- if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
- rc = SQLITE_READONLY;
- }
-
-#ifdef SQLITE_HAS_CODEC
- /* Backup is not possible if the page size of the destination is changing
- ** and a codec is in use.
- */
- if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
- rc = SQLITE_READONLY;
- }
-
- /* Backup is not possible if the number of bytes of reserve space differ
- ** between source and destination. If there is a difference, try to
- ** fix the destination to agree with the source. If that is not possible,
- ** then the backup cannot proceed.
- */
- if( nSrcReserve!=nDestReserve ){
- u32 newPgsz = nSrcPgsz;
- rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
- if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
- }
-#endif
-
- /* This loop runs once for each destination page spanned by the source
- ** page. For each iteration, variable iOff is set to the byte offset
- ** of the destination page.
- */
- for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOff<iEnd; iOff+=nDestPgsz){
- DbPage *pDestPg = 0;
- Pgno iDest = (Pgno)(iOff/nDestPgsz)+1;
- if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue;
- if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg))
- && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg))
- ){
- const u8 *zIn = &zSrcData[iOff%nSrcPgsz];
- u8 *zDestData = sqlite3PagerGetData(pDestPg);
- u8 *zOut = &zDestData[iOff%nDestPgsz];
-
- /* Copy the data from the source page into the destination page.
- ** Then clear the Btree layer MemPage.isInit flag. Both this module
- ** and the pager code use this trick (clearing the first byte
- ** of the page 'extra' space to invalidate the Btree layers
- ** cached parse of the page). MemPage.isInit is marked
- ** "MUST BE FIRST" for this purpose.
- */
- memcpy(zOut, zIn, nCopy);
- ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0;
- }
- sqlite3PagerUnref(pDestPg);
- }
-
- return rc;
-}
-
-/*
-** If pFile is currently larger than iSize bytes, then truncate it to
-** exactly iSize bytes. If pFile is not larger than iSize bytes, then
-** this function is a no-op.
-**
-** Return SQLITE_OK if everything is successful, or an SQLite error
-** code if an error occurs.
-*/
-static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
- i64 iCurrent;
- int rc = sqlite3OsFileSize(pFile, &iCurrent);
- if( rc==SQLITE_OK && iCurrent>iSize ){
- rc = sqlite3OsTruncate(pFile, iSize);
- }
- return rc;
-}
-
-/*
-** Register this backup object with the associated source pager for
-** callbacks when pages are changed or the cache invalidated.
-*/
-static void attachBackupObject(sqlite3_backup *p){
- sqlite3_backup **pp;
- assert( sqlite3BtreeHoldsMutex(p->pSrc) );
- pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
- p->pNext = *pp;
- *pp = p;
- p->isAttached = 1;
-}
-
-/*
-** Copy nPage pages from the source b-tree to the destination.
-*/
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
- int rc;
- int destMode; /* Destination journal mode */
- int pgszSrc = 0; /* Source page size */
- int pgszDest = 0; /* Destination page size */
-
- sqlite3_mutex_enter(p->pSrcDb->mutex);
- sqlite3BtreeEnter(p->pSrc);
- if( p->pDestDb ){
- sqlite3_mutex_enter(p->pDestDb->mutex);
- }
-
- rc = p->rc;
- if( !isFatalError(rc) ){
- Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */
- Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */
- int ii; /* Iterator variable */
- int nSrcPage = -1; /* Size of source db in pages */
- int bCloseTrans = 0; /* True if src db requires unlocking */
-
- /* If the source pager is currently in a write-transaction, return
- ** SQLITE_BUSY immediately.
- */
- if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){
- rc = SQLITE_BUSY;
- }else{
- rc = SQLITE_OK;
- }
-
- /* Lock the destination database, if it is not locked already. */
- if( SQLITE_OK==rc && p->bDestLocked==0
- && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
- ){
- p->bDestLocked = 1;
- sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
- }
-
- /* If there is no open read-transaction on the source database, open
- ** one now. If a transaction is opened here, then it will be closed
- ** before this function exits.
- */
- if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){
- rc = sqlite3BtreeBeginTrans(p->pSrc, 0);
- bCloseTrans = 1;
- }
-
- /* Do not allow backup if the destination database is in WAL mode
- ** and the page sizes are different between source and destination */
- pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
- pgszDest = sqlite3BtreeGetPageSize(p->pDest);
- destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest));
- if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){
- rc = SQLITE_READONLY;
- }
-
- /* Now that there is a read-lock on the source database, query the
- ** source pager for the number of pages in the database.
- */
- nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc);
- assert( nSrcPage>=0 );
- for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
- const Pgno iSrcPg = p->iNext; /* Source page number */
- if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
- DbPage *pSrcPg; /* Source page object */
- rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
- if( rc==SQLITE_OK ){
- rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg));
- sqlite3PagerUnref(pSrcPg);
- }
- }
- p->iNext++;
- }
- if( rc==SQLITE_OK ){
- p->nPagecount = nSrcPage;
- p->nRemaining = nSrcPage+1-p->iNext;
- if( p->iNext>(Pgno)nSrcPage ){
- rc = SQLITE_DONE;
- }else if( !p->isAttached ){
- attachBackupObject(p);
- }
- }
-
- /* Update the schema version field in the destination database. This
- ** is to make sure that the schema-version really does change in
- ** the case where the source and destination databases have the
- ** same schema version.
- */
- if( rc==SQLITE_DONE ){
- if( nSrcPage==0 ){
- rc = sqlite3BtreeNewDb(p->pDest);
- nSrcPage = 1;
- }
- if( rc==SQLITE_OK || rc==SQLITE_DONE ){
- rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
- }
- if( rc==SQLITE_OK ){
- if( p->pDestDb ){
- sqlite3ResetAllSchemasOfConnection(p->pDestDb);
- }
- if( destMode==PAGER_JOURNALMODE_WAL ){
- rc = sqlite3BtreeSetVersion(p->pDest, 2);
- }
- }
- if( rc==SQLITE_OK ){
- int nDestTruncate;
- /* Set nDestTruncate to the final number of pages in the destination
- ** database. The complication here is that the destination page
- ** size may be different to the source page size.
- **
- ** If the source page size is smaller than the destination page size,
- ** round up. In this case the call to sqlite3OsTruncate() below will
- ** fix the size of the file. However it is important to call
- ** sqlite3PagerTruncateImage() here so that any pages in the
- ** destination file that lie beyond the nDestTruncate page mark are
- ** journalled by PagerCommitPhaseOne() before they are destroyed
- ** by the file truncation.
- */
- assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) );
- assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) );
- if( pgszSrc<pgszDest ){
- int ratio = pgszDest/pgszSrc;
- nDestTruncate = (nSrcPage+ratio-1)/ratio;
- if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
- nDestTruncate--;
- }
- }else{
- nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
- }
- assert( nDestTruncate>0 );
- sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
-
- if( pgszSrc<pgszDest ){
- /* If the source page-size is smaller than the destination page-size,
- ** two extra things may need to happen:
- **
- ** * The destination may need to be truncated, and
- **
- ** * Data stored on the pages immediately following the
- ** pending-byte page in the source database may need to be
- ** copied into the destination database.
- */
- const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
- sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
- i64 iOff;
- i64 iEnd;
-
- assert( pFile );
- assert( nDestTruncate==0
- || (i64)nDestTruncate*(i64)pgszDest >= iSize || (
- nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
- && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
- ));
-
- /* This call ensures that all data required to recreate the original
- ** database has been stored in the journal for pDestPager and the
- ** journal synced to disk. So at this point we may safely modify
- ** the database file in any way, knowing that if a power failure
- ** occurs, the original database will be reconstructed from the
- ** journal file. */
- rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
-
- /* Write the extra pages and truncate the database file as required */
- iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
- for(
- iOff=PENDING_BYTE+pgszSrc;
- rc==SQLITE_OK && iOff<iEnd;
- iOff+=pgszSrc
- ){
- PgHdr *pSrcPg = 0;
- const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
- rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
- if( rc==SQLITE_OK ){
- u8 *zData = sqlite3PagerGetData(pSrcPg);
- rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
- }
- sqlite3PagerUnref(pSrcPg);
- }
- if( rc==SQLITE_OK ){
- rc = backupTruncateFile(pFile, iSize);
- }
-
- /* Sync the database file to disk. */
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerSync(pDestPager);
- }
- }else{
- rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
- }
-
- /* Finish committing the transaction to the destination database. */
- if( SQLITE_OK==rc
- && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0))
- ){
- rc = SQLITE_DONE;
- }
- }
- }
-
- /* If bCloseTrans is true, then this function opened a read transaction
- ** on the source database. Close the read transaction here. There is
- ** no need to check the return values of the btree methods here, as
- ** "committing" a read-only transaction cannot fail.
- */
- if( bCloseTrans ){
- TESTONLY( int rc2 );
- TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0);
- TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0);
- assert( rc2==SQLITE_OK );
- }
-
- if( rc==SQLITE_IOERR_NOMEM ){
- rc = SQLITE_NOMEM;
- }
- p->rc = rc;
- }
- if( p->pDestDb ){
- sqlite3_mutex_leave(p->pDestDb->mutex);
- }
- sqlite3BtreeLeave(p->pSrc);
- sqlite3_mutex_leave(p->pSrcDb->mutex);
- return rc;
-}
-
-/*
-** Release all resources associated with an sqlite3_backup* handle.
-*/
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
- sqlite3_backup **pp; /* Ptr to head of pagers backup list */
- sqlite3 *pSrcDb; /* Source database connection */
- int rc; /* Value to return */
-
- /* Enter the mutexes */
- if( p==0 ) return SQLITE_OK;
- pSrcDb = p->pSrcDb;
- sqlite3_mutex_enter(pSrcDb->mutex);
- sqlite3BtreeEnter(p->pSrc);
- if( p->pDestDb ){
- sqlite3_mutex_enter(p->pDestDb->mutex);
- }
-
- /* Detach this backup from the source pager. */
- if( p->pDestDb ){
- p->pSrc->nBackup--;
- }
- if( p->isAttached ){
- pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
- while( *pp!=p ){
- pp = &(*pp)->pNext;
- }
- *pp = p->pNext;
- }
-
- /* If a transaction is still open on the Btree, roll it back. */
- sqlite3BtreeRollback(p->pDest, SQLITE_OK);
-
- /* Set the error code of the destination database handle. */
- rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
- sqlite3Error(p->pDestDb, rc, 0);
-
- /* Exit the mutexes and free the backup context structure. */
- if( p->pDestDb ){
- sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
- }
- sqlite3BtreeLeave(p->pSrc);
- if( p->pDestDb ){
- /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
- ** call to sqlite3_backup_init() and is destroyed by a call to
- ** sqlite3_backup_finish(). */
- sqlite3_free(p);
- }
- sqlite3LeaveMutexAndCloseZombie(pSrcDb);
- return rc;
-}
-
-/*
-** Return the number of pages still to be backed up as of the most recent
-** call to sqlite3_backup_step().
-*/
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
- return p->nRemaining;
-}
-
-/*
-** Return the total number of pages in the source database as of the most
-** recent call to sqlite3_backup_step().
-*/
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
- return p->nPagecount;
-}
-
-/*
-** This function is called after the contents of page iPage of the
-** source database have been modified. If page iPage has already been
-** copied into the destination database, then the data written to the
-** destination is now invalidated. The destination copy of iPage needs
-** to be updated with the new data before the backup operation is
-** complete.
-**
-** It is assumed that the mutex associated with the BtShared object
-** corresponding to the source database is held when this function is
-** called.
-*/
-SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
- sqlite3_backup *p; /* Iterator variable */
- for(p=pBackup; p; p=p->pNext){
- assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
- if( !isFatalError(p->rc) && iPage<p->iNext ){
- /* The backup process p has already copied page iPage. But now it
- ** has been modified by a transaction on the source pager. Copy
- ** the new data into the backup.
- */
- int rc;
- assert( p->pDestDb );
- sqlite3_mutex_enter(p->pDestDb->mutex);
- rc = backupOnePage(p, iPage, aData);
- sqlite3_mutex_leave(p->pDestDb->mutex);
- assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
- if( rc!=SQLITE_OK ){
- p->rc = rc;
- }
- }
- }
-}
-
-/*
-** Restart the backup process. This is called when the pager layer
-** detects that the database has been modified by an external database
-** connection. In this case there is no way of knowing which of the
-** pages that have been copied into the destination database are still
-** valid and which are not, so the entire process needs to be restarted.
-**
-** It is assumed that the mutex associated with the BtShared object
-** corresponding to the source database is held when this function is
-** called.
-*/
-SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){
- sqlite3_backup *p; /* Iterator variable */
- for(p=pBackup; p; p=p->pNext){
- assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
- p->iNext = 1;
- }
-}
-
-#ifndef SQLITE_OMIT_VACUUM
-/*
-** Copy the complete content of pBtFrom into pBtTo. A transaction
-** must be active for both files.
-**
-** The size of file pTo may be reduced by this operation. If anything
-** goes wrong, the transaction on pTo is rolled back. If successful, the
-** transaction is committed before returning.
-*/
-SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
- int rc;
- sqlite3_file *pFd; /* File descriptor for database pTo */
- sqlite3_backup b;
- sqlite3BtreeEnter(pTo);
- sqlite3BtreeEnter(pFrom);
-
- assert( sqlite3BtreeIsInTrans(pTo) );
- pFd = sqlite3PagerFile(sqlite3BtreePager(pTo));
- if( pFd->pMethods ){
- i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom);
- rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte);
- if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
- if( rc ) goto copy_finished;
- }
-
- /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
- ** to 0. This is used by the implementations of sqlite3_backup_step()
- ** and sqlite3_backup_finish() to detect that they are being called
- ** from this function, not directly by the user.
- */
- memset(&b, 0, sizeof(b));
- b.pSrcDb = pFrom->db;
- b.pSrc = pFrom;
- b.pDest = pTo;
- b.iNext = 1;
-
- /* 0x7FFFFFFF is the hard limit for the number of pages in a database
- ** file. By passing this as the number of pages to copy to
- ** sqlite3_backup_step(), we can guarantee that the copy finishes
- ** within a single call (unless an error occurs). The assert() statement
- ** checks this assumption - (p->rc) should be set to either SQLITE_DONE
- ** or an error code.
- */
- sqlite3_backup_step(&b, 0x7FFFFFFF);
- assert( b.rc!=SQLITE_OK );
- rc = sqlite3_backup_finish(&b);
- if( rc==SQLITE_OK ){
- pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
- }else{
- sqlite3PagerClearCache(sqlite3BtreePager(b.pDest));
- }
-
- assert( sqlite3BtreeIsInTrans(pTo)==0 );
-copy_finished:
- sqlite3BtreeLeave(pFrom);
- sqlite3BtreeLeave(pTo);
- return rc;
-}
-#endif /* SQLITE_OMIT_VACUUM */
-
-/************** End of backup.c **********************************************/
-/************** Begin file vdbemem.c *****************************************/
-/*
-** 2004 May 26
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains code use to manipulate "Mem" structure. A "Mem"
-** stores a single value in the VDBE. Mem is an opaque structure visible
-** only within the VDBE. Interface routines refer to a Mem using the
-** name sqlite_value
-*/
-
-/*
-** If pMem is an object with a valid string representation, this routine
-** ensures the internal encoding for the string representation is
-** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE.
-**
-** If pMem is not a string object, or the encoding of the string
-** representation is already stored using the requested encoding, then this
-** routine is a no-op.
-**
-** SQLITE_OK is returned if the conversion is successful (or not required).
-** SQLITE_NOMEM may be returned if a malloc() fails during conversion
-** between formats.
-*/
-SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
- int rc;
- assert( (pMem->flags&MEM_RowSet)==0 );
- assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
- || desiredEnc==SQLITE_UTF16BE );
- if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
- return SQLITE_OK;
- }
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
-#ifdef SQLITE_OMIT_UTF16
- return SQLITE_ERROR;
-#else
-
- /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned,
- ** then the encoding of the value may not have changed.
- */
- rc = sqlite3VdbeMemTranslate(pMem, (u8)desiredEnc);
- assert(rc==SQLITE_OK || rc==SQLITE_NOMEM);
- assert(rc==SQLITE_OK || pMem->enc!=desiredEnc);
- assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
- return rc;
-#endif
-}
-
-/*
-** Make sure pMem->z points to a writable allocation of at least
-** n bytes.
-**
-** If the third argument passed to this function is true, then memory
-** cell pMem must contain a string or blob. In this case the content is
-** preserved. Otherwise, if the third parameter to this function is false,
-** any current string or blob value may be discarded.
-**
-** This function sets the MEM_Dyn flag and clears any xDel callback.
-** It also clears MEM_Ephem and MEM_Static. If the preserve flag is
-** not set, Mem.n is zeroed.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
- assert( 1 >=
- ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
- (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) +
- ((pMem->flags&MEM_Ephem) ? 1 : 0) +
- ((pMem->flags&MEM_Static) ? 1 : 0)
- );
- assert( (pMem->flags&MEM_RowSet)==0 );
-
- /* If the preserve flag is set to true, then the memory cell must already
- ** contain a valid string or blob value. */
- assert( preserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
-
- if( n<32 ) n = 32;
- if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
- if( preserve && pMem->z==pMem->zMalloc ){
- pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
- preserve = 0;
- }else{
- sqlite3DbFree(pMem->db, pMem->zMalloc);
- pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
- }
- }
-
- if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){
- memcpy(pMem->zMalloc, pMem->z, pMem->n);
- }
- if( pMem->flags&MEM_Dyn && pMem->xDel ){
- assert( pMem->xDel!=SQLITE_DYNAMIC );
- pMem->xDel((void *)(pMem->z));
- }
-
- pMem->z = pMem->zMalloc;
- if( pMem->z==0 ){
- pMem->flags = MEM_Null;
- }else{
- pMem->flags &= ~(MEM_Ephem|MEM_Static);
- }
- pMem->xDel = 0;
- return (pMem->z ? SQLITE_OK : SQLITE_NOMEM);
-}
-
-/*
-** Make the given Mem object MEM_Dyn. In other words, make it so
-** that any TEXT or BLOB content is stored in memory obtained from
-** malloc(). In this way, we know that the memory is safe to be
-** overwritten or altered.
-**
-** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
- int f;
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( (pMem->flags&MEM_RowSet)==0 );
- ExpandBlob(pMem);
- f = pMem->flags;
- if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
- if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
- return SQLITE_NOMEM;
- }
- pMem->z[pMem->n] = 0;
- pMem->z[pMem->n+1] = 0;
- pMem->flags |= MEM_Term;
-#ifdef SQLITE_DEBUG
- pMem->pScopyFrom = 0;
-#endif
- }
-
- return SQLITE_OK;
-}
-
-/*
-** If the given Mem* has a zero-filled tail, turn it into an ordinary
-** blob stored in dynamically allocated space.
-*/
-#ifndef SQLITE_OMIT_INCRBLOB
-SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
- if( pMem->flags & MEM_Zero ){
- int nByte;
- assert( pMem->flags&MEM_Blob );
- assert( (pMem->flags&MEM_RowSet)==0 );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
-
- /* Set nByte to the number of bytes required to store the expanded blob. */
- nByte = pMem->n + pMem->u.nZero;
- if( nByte<=0 ){
- nByte = 1;
- }
- if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
- return SQLITE_NOMEM;
- }
-
- memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
- pMem->n += pMem->u.nZero;
- pMem->flags &= ~(MEM_Zero|MEM_Term);
- }
- return SQLITE_OK;
-}
-#endif
-
-
-/*
-** Make sure the given Mem is \u0000 terminated.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
- return SQLITE_OK; /* Nothing to do */
- }
- if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
- return SQLITE_NOMEM;
- }
- pMem->z[pMem->n] = 0;
- pMem->z[pMem->n+1] = 0;
- pMem->flags |= MEM_Term;
- return SQLITE_OK;
-}
-
-/*
-** Add MEM_Str to the set of representations for the given Mem. Numbers
-** are converted using sqlite3_snprintf(). Converting a BLOB to a string
-** is a no-op.
-**
-** Existing representations MEM_Int and MEM_Real are *not* invalidated.
-**
-** A MEM_Null value will never be passed to this function. This function is
-** used for converting values to text for returning to the user (i.e. via
-** sqlite3_value_text()), or for ensuring that values to be used as btree
-** keys are strings. In the former case a NULL pointer is returned the
-** user and the later is an internal programming error.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){
- int rc = SQLITE_OK;
- int fg = pMem->flags;
- const int nByte = 32;
-
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( !(fg&MEM_Zero) );
- assert( !(fg&(MEM_Str|MEM_Blob)) );
- assert( fg&(MEM_Int|MEM_Real) );
- assert( (pMem->flags&MEM_RowSet)==0 );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
-
-
- if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
- return SQLITE_NOMEM;
- }
-
- /* For a Real or Integer, use sqlite3_mprintf() to produce the UTF-8
- ** string representation of the value. Then, if the required encoding
- ** is UTF-16le or UTF-16be do a translation.
- **
- ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
- */
- if( fg & MEM_Int ){
- sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
- }else{
- assert( fg & MEM_Real );
- sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
- }
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- pMem->flags |= MEM_Str|MEM_Term;
- sqlite3VdbeChangeEncoding(pMem, enc);
- return rc;
-}
-
-/*
-** Memory cell pMem contains the context of an aggregate function.
-** This routine calls the finalize method for that function. The
-** result of the aggregate is stored back into pMem.
-**
-** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK
-** otherwise.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
- int rc = SQLITE_OK;
- if( ALWAYS(pFunc && pFunc->xFinalize) ){
- sqlite3_context ctx;
- assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- memset(&ctx, 0, sizeof(ctx));
- ctx.s.flags = MEM_Null;
- ctx.s.db = pMem->db;
- ctx.pMem = pMem;
- ctx.pFunc = pFunc;
- pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
- assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
- sqlite3DbFree(pMem->db, pMem->zMalloc);
- memcpy(pMem, &ctx.s, sizeof(ctx.s));
- rc = ctx.isError;
- }
- return rc;
-}
-
-/*
-** If the memory cell contains a string value that must be freed by
-** invoking an external callback, free it now. Calling this function
-** does not free any Mem.zMalloc buffer.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){
- assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
- if( p->flags&MEM_Agg ){
- sqlite3VdbeMemFinalize(p, p->u.pDef);
- assert( (p->flags & MEM_Agg)==0 );
- sqlite3VdbeMemRelease(p);
- }else if( p->flags&MEM_Dyn && p->xDel ){
- assert( (p->flags&MEM_RowSet)==0 );
- assert( p->xDel!=SQLITE_DYNAMIC );
- p->xDel((void *)p->z);
- p->xDel = 0;
- }else if( p->flags&MEM_RowSet ){
- sqlite3RowSetClear(p->u.pRowSet);
- }else if( p->flags&MEM_Frame ){
- sqlite3VdbeMemSetNull(p);
- }
-}
-
-/*
-** Release any memory held by the Mem. This may leave the Mem in an
-** inconsistent state, for example with (Mem.z==0) and
-** (Mem.type==SQLITE_TEXT).
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
- VdbeMemRelease(p);
- sqlite3DbFree(p->db, p->zMalloc);
- p->z = 0;
- p->zMalloc = 0;
- p->xDel = 0;
-}
-
-/*
-** Convert a 64-bit IEEE double into a 64-bit signed integer.
-** If the double is too large, return 0x8000000000000000.
-**
-** Most systems appear to do this simply by assigning
-** variables and without the extra range tests. But
-** there are reports that windows throws an expection
-** if the floating point value is out of range. (See ticket #2880.)
-** Because we do not completely understand the problem, we will
-** take the conservative approach and always do range tests
-** before attempting the conversion.
-*/
-static i64 doubleToInt64(double r){
-#ifdef SQLITE_OMIT_FLOATING_POINT
- /* When floating-point is omitted, double and int64 are the same thing */
- return r;
-#else
- /*
- ** Many compilers we encounter do not define constants for the
- ** minimum and maximum 64-bit integers, or they define them
- ** inconsistently. And many do not understand the "LL" notation.
- ** So we define our own static constants here using nothing
- ** larger than a 32-bit integer constant.
- */
- static const i64 maxInt = LARGEST_INT64;
- static const i64 minInt = SMALLEST_INT64;
-
- if( r<(double)minInt ){
- return minInt;
- }else if( r>(double)maxInt ){
- /* minInt is correct here - not maxInt. It turns out that assigning
- ** a very large positive number to an integer results in a very large
- ** negative integer. This makes no sense, but it is what x86 hardware
- ** does so for compatibility we will do the same in software. */
- return minInt;
- }else{
- return (i64)r;
- }
-#endif
-}
-
-/*
-** Return some kind of integer value which is the best we can do
-** at representing the value that *pMem describes as an integer.
-** If pMem is an integer, then the value is exact. If pMem is
-** a floating-point then the value returned is the integer part.
-** If pMem is a string or blob, then we make an attempt to convert
-** it into a integer and return that. If pMem represents an
-** an SQL-NULL value, return 0.
-**
-** If pMem represents a string value, its encoding might be changed.
-*/
-SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
- int flags;
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
- flags = pMem->flags;
- if( flags & MEM_Int ){
- return pMem->u.i;
- }else if( flags & MEM_Real ){
- return doubleToInt64(pMem->r);
- }else if( flags & (MEM_Str|MEM_Blob) ){
- i64 value = 0;
- assert( pMem->z || pMem->n==0 );
- testcase( pMem->z==0 );
- sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
- return value;
- }else{
- return 0;
- }
-}
-
-/*
-** Return the best representation of pMem that we can get into a
-** double. If pMem is already a double or an integer, return its
-** value. If it is a string or blob, try to convert it to a double.
-** If it is a NULL, return 0.0.
-*/
-SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
- if( pMem->flags & MEM_Real ){
- return pMem->r;
- }else if( pMem->flags & MEM_Int ){
- return (double)pMem->u.i;
- }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- double val = (double)0;
- sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
- return val;
- }else{
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- return (double)0;
- }
-}
-
-/*
-** The MEM structure is already a MEM_Real. Try to also make it a
-** MEM_Int if we can.
-*/
-SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
- assert( pMem->flags & MEM_Real );
- assert( (pMem->flags & MEM_RowSet)==0 );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
-
- pMem->u.i = doubleToInt64(pMem->r);
-
- /* Only mark the value as an integer if
- **
- ** (1) the round-trip conversion real->int->real is a no-op, and
- ** (2) The integer is neither the largest nor the smallest
- ** possible integer (ticket #3922)
- **
- ** The second and third terms in the following conditional enforces
- ** the second condition under the assumption that addition overflow causes
- ** values to wrap around. On x86 hardware, the third term is always
- ** true and could be omitted. But we leave it in because other
- ** architectures might behave differently.
- */
- if( pMem->r==(double)pMem->u.i
- && pMem->u.i>SMALLEST_INT64
-#if defined(__i486__) || defined(__x86_64__)
- && ALWAYS(pMem->u.i<LARGEST_INT64)
-#else
- && pMem->u.i<LARGEST_INT64
-#endif
- ){
- pMem->flags |= MEM_Int;
- }
-}
-
-/*
-** Convert pMem to type integer. Invalidate any prior representations.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( (pMem->flags & MEM_RowSet)==0 );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
-
- pMem->u.i = sqlite3VdbeIntValue(pMem);
- MemSetTypeFlag(pMem, MEM_Int);
- return SQLITE_OK;
-}
-
-/*
-** Convert pMem so that it is of type MEM_Real.
-** Invalidate any prior representations.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
-
- pMem->r = sqlite3VdbeRealValue(pMem);
- MemSetTypeFlag(pMem, MEM_Real);
- return SQLITE_OK;
-}
-
-/*
-** Convert pMem so that it has types MEM_Real or MEM_Int or both.
-** Invalidate any prior representations.
-**
-** Every effort is made to force the conversion, even if the input
-** is a string that does not look completely like a number. Convert
-** as much of the string as we can and ignore the rest.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
- if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
- assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
- MemSetTypeFlag(pMem, MEM_Int);
- }else{
- pMem->r = sqlite3VdbeRealValue(pMem);
- MemSetTypeFlag(pMem, MEM_Real);
- sqlite3VdbeIntegerAffinity(pMem);
- }
- }
- assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
- pMem->flags &= ~(MEM_Str|MEM_Blob);
- return SQLITE_OK;
-}
-
-/*
-** Delete any previous value and set the value stored in *pMem to NULL.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
- if( pMem->flags & MEM_Frame ){
- VdbeFrame *pFrame = pMem->u.pFrame;
- pFrame->pParent = pFrame->v->pDelFrame;
- pFrame->v->pDelFrame = pFrame;
- }
- if( pMem->flags & MEM_RowSet ){
- sqlite3RowSetClear(pMem->u.pRowSet);
- }
- MemSetTypeFlag(pMem, MEM_Null);
- pMem->type = SQLITE_NULL;
-}
-
-/*
-** Delete any previous value and set the value to be a BLOB of length
-** n containing all zeros.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
- sqlite3VdbeMemRelease(pMem);
- pMem->flags = MEM_Blob|MEM_Zero;
- pMem->type = SQLITE_BLOB;
- pMem->n = 0;
- if( n<0 ) n = 0;
- pMem->u.nZero = n;
- pMem->enc = SQLITE_UTF8;
-
-#ifdef SQLITE_OMIT_INCRBLOB
- sqlite3VdbeMemGrow(pMem, n, 0);
- if( pMem->z ){
- pMem->n = n;
- memset(pMem->z, 0, n);
- }
-#endif
-}
-
-/*
-** Delete any previous value and set the value stored in *pMem to val,
-** manifest type INTEGER.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
- sqlite3VdbeMemRelease(pMem);
- pMem->u.i = val;
- pMem->flags = MEM_Int;
- pMem->type = SQLITE_INTEGER;
-}
-
-#ifndef SQLITE_OMIT_FLOATING_POINT
-/*
-** Delete any previous value and set the value stored in *pMem to val,
-** manifest type REAL.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
- if( sqlite3IsNaN(val) ){
- sqlite3VdbeMemSetNull(pMem);
- }else{
- sqlite3VdbeMemRelease(pMem);
- pMem->r = val;
- pMem->flags = MEM_Real;
- pMem->type = SQLITE_FLOAT;
- }
-}
-#endif
-
-/*
-** Delete any previous value and set the value of pMem to be an
-** empty boolean index.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){
- sqlite3 *db = pMem->db;
- assert( db!=0 );
- assert( (pMem->flags & MEM_RowSet)==0 );
- sqlite3VdbeMemRelease(pMem);
- pMem->zMalloc = sqlite3DbMallocRaw(db, 64);
- if( db->mallocFailed ){
- pMem->flags = MEM_Null;
- }else{
- assert( pMem->zMalloc );
- pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc,
- sqlite3DbMallocSize(db, pMem->zMalloc));
- assert( pMem->u.pRowSet!=0 );
- pMem->flags = MEM_RowSet;
- }
-}
-
-/*
-** Return true if the Mem object contains a TEXT or BLOB that is
-** too large - whose size exceeds SQLITE_MAX_LENGTH.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){
- assert( p->db!=0 );
- if( p->flags & (MEM_Str|MEM_Blob) ){
- int n = p->n;
- if( p->flags & MEM_Zero ){
- n += p->u.nZero;
- }
- return n>p->db->aLimit[SQLITE_LIMIT_LENGTH];
- }
- return 0;
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** This routine prepares a memory cell for modication by breaking
-** its link to a shallow copy and by marking any current shallow
-** copies of this cell as invalid.
-**
-** This is used for testing and debugging only - to make sure shallow
-** copies are not misused.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
- int i;
- Mem *pX;
- for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){
- if( pX->pScopyFrom==pMem ){
- pX->flags |= MEM_Invalid;
- pX->pScopyFrom = 0;
- }
- }
- pMem->pScopyFrom = 0;
-}
-#endif /* SQLITE_DEBUG */
-
-/*
-** Size of struct Mem not including the Mem.zMalloc member.
-*/
-#define MEMCELLSIZE (size_t)(&(((Mem *)0)->zMalloc))
-
-/*
-** Make an shallow copy of pFrom into pTo. Prior contents of
-** pTo are freed. The pFrom->z field is not duplicated. If
-** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
-** and flags gets srcType (either MEM_Ephem or MEM_Static).
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
- assert( (pFrom->flags & MEM_RowSet)==0 );
- VdbeMemRelease(pTo);
- memcpy(pTo, pFrom, MEMCELLSIZE);
- pTo->xDel = 0;
- if( (pFrom->flags&MEM_Static)==0 ){
- pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
- assert( srcType==MEM_Ephem || srcType==MEM_Static );
- pTo->flags |= srcType;
- }
-}
-
-/*
-** Make a full copy of pFrom into pTo. Prior contents of pTo are
-** freed before the copy is made.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
- int rc = SQLITE_OK;
-
- assert( (pFrom->flags & MEM_RowSet)==0 );
- VdbeMemRelease(pTo);
- memcpy(pTo, pFrom, MEMCELLSIZE);
- pTo->flags &= ~MEM_Dyn;
-
- if( pTo->flags&(MEM_Str|MEM_Blob) ){
- if( 0==(pFrom->flags&MEM_Static) ){
- pTo->flags |= MEM_Ephem;
- rc = sqlite3VdbeMemMakeWriteable(pTo);
- }
- }
-
- return rc;
-}
-
-/*
-** Transfer the contents of pFrom to pTo. Any existing value in pTo is
-** freed. If pFrom contains ephemeral data, a copy is made.
-**
-** pFrom contains an SQL NULL when this routine returns.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
- assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) );
- assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) );
- assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db );
-
- sqlite3VdbeMemRelease(pTo);
- memcpy(pTo, pFrom, sizeof(Mem));
- pFrom->flags = MEM_Null;
- pFrom->xDel = 0;
- pFrom->zMalloc = 0;
-}
-
-/*
-** Change the value of a Mem to be a string or a BLOB.
-**
-** The memory management strategy depends on the value of the xDel
-** parameter. If the value passed is SQLITE_TRANSIENT, then the
-** string is copied into a (possibly existing) buffer managed by the
-** Mem structure. Otherwise, any existing buffer is freed and the
-** pointer copied.
-**
-** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH
-** size limit) then no memory allocation occurs. If the string can be
-** stored without allocating memory, then it is. If a memory allocation
-** is required to store the string, then value of pMem is unchanged. In
-** either case, SQLITE_TOOBIG is returned.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
- Mem *pMem, /* Memory cell to set to string value */
- const char *z, /* String pointer */
- int n, /* Bytes in string, or negative */
- u8 enc, /* Encoding of z. 0 for BLOBs */
- void (*xDel)(void*) /* Destructor function */
-){
- int nByte = n; /* New value for pMem->n */
- int iLimit; /* Maximum allowed string or blob size */
- u16 flags = 0; /* New value for pMem->flags */
-
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- assert( (pMem->flags & MEM_RowSet)==0 );
-
- /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
- if( !z ){
- sqlite3VdbeMemSetNull(pMem);
- return SQLITE_OK;
- }
-
- if( pMem->db ){
- iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH];
- }else{
- iLimit = SQLITE_MAX_LENGTH;
- }
- flags = (enc==0?MEM_Blob:MEM_Str);
- if( nByte<0 ){
- assert( enc!=0 );
- if( enc==SQLITE_UTF8 ){
- for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){}
- }else{
- for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
- }
- flags |= MEM_Term;
- }
-
- /* The following block sets the new values of Mem.z and Mem.xDel. It
- ** also sets a flag in local variable "flags" to indicate the memory
- ** management (one of MEM_Dyn or MEM_Static).
- */
- if( xDel==SQLITE_TRANSIENT ){
- int nAlloc = nByte;
- if( flags&MEM_Term ){
- nAlloc += (enc==SQLITE_UTF8?1:2);
- }
- if( nByte>iLimit ){
- return SQLITE_TOOBIG;
- }
- if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){
- return SQLITE_NOMEM;
- }
- memcpy(pMem->z, z, nAlloc);
- }else if( xDel==SQLITE_DYNAMIC ){
- sqlite3VdbeMemRelease(pMem);
- pMem->zMalloc = pMem->z = (char *)z;
- pMem->xDel = 0;
- }else{
- sqlite3VdbeMemRelease(pMem);
- pMem->z = (char *)z;
- pMem->xDel = xDel;
- flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
- }
-
- pMem->n = nByte;
- pMem->flags = flags;
- pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
- pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT);
-
-#ifndef SQLITE_OMIT_UTF16
- if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
- return SQLITE_NOMEM;
- }
-#endif
-
- if( nByte>iLimit ){
- return SQLITE_TOOBIG;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Compare the values contained by the two memory cells, returning
-** negative, zero or positive if pMem1 is less than, equal to, or greater
-** than pMem2. Sorting order is NULL's first, followed by numbers (integers
-** and reals) sorted numerically, followed by text ordered by the collating
-** sequence pColl and finally blob's ordered by memcmp().
-**
-** Two NULL values are considered equal by this function.
-*/
-SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
- int rc;
- int f1, f2;
- int combined_flags;
-
- f1 = pMem1->flags;
- f2 = pMem2->flags;
- combined_flags = f1|f2;
- assert( (combined_flags & MEM_RowSet)==0 );
-
- /* If one value is NULL, it is less than the other. If both values
- ** are NULL, return 0.
- */
- if( combined_flags&MEM_Null ){
- return (f2&MEM_Null) - (f1&MEM_Null);
- }
-
- /* If one value is a number and the other is not, the number is less.
- ** If both are numbers, compare as reals if one is a real, or as integers
- ** if both values are integers.
- */
- if( combined_flags&(MEM_Int|MEM_Real) ){
- if( !(f1&(MEM_Int|MEM_Real)) ){
- return 1;
- }
- if( !(f2&(MEM_Int|MEM_Real)) ){
- return -1;
- }
- if( (f1 & f2 & MEM_Int)==0 ){
- double r1, r2;
- if( (f1&MEM_Real)==0 ){
- r1 = (double)pMem1->u.i;
- }else{
- r1 = pMem1->r;
- }
- if( (f2&MEM_Real)==0 ){
- r2 = (double)pMem2->u.i;
- }else{
- r2 = pMem2->r;
- }
- if( r1<r2 ) return -1;
- if( r1>r2 ) return 1;
- return 0;
- }else{
- assert( f1&MEM_Int );
- assert( f2&MEM_Int );
- if( pMem1->u.i < pMem2->u.i ) return -1;
- if( pMem1->u.i > pMem2->u.i ) return 1;
- return 0;
- }
- }
-
- /* If one value is a string and the other is a blob, the string is less.
- ** If both are strings, compare using the collating functions.
- */
- if( combined_flags&MEM_Str ){
- if( (f1 & MEM_Str)==0 ){
- return 1;
- }
- if( (f2 & MEM_Str)==0 ){
- return -1;
- }
-
- assert( pMem1->enc==pMem2->enc );
- assert( pMem1->enc==SQLITE_UTF8 ||
- pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
-
- /* The collation sequence must be defined at this point, even if
- ** the user deletes the collation sequence after the vdbe program is
- ** compiled (this was not always the case).
- */
- assert( !pColl || pColl->xCmp );
-
- if( pColl ){
- if( pMem1->enc==pColl->enc ){
- /* The strings are already in the correct encoding. Call the
- ** comparison function directly */
- return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
- }else{
- const void *v1, *v2;
- int n1, n2;
- Mem c1;
- Mem c2;
- memset(&c1, 0, sizeof(c1));
- memset(&c2, 0, sizeof(c2));
- sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
- sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
- v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
- n1 = v1==0 ? 0 : c1.n;
- v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
- n2 = v2==0 ? 0 : c2.n;
- rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
- sqlite3VdbeMemRelease(&c1);
- sqlite3VdbeMemRelease(&c2);
- return rc;
- }
- }
- /* If a NULL pointer was passed as the collate function, fall through
- ** to the blob case and use memcmp(). */
- }
-
- /* Both values must be blobs. Compare using memcmp(). */
- rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
- if( rc==0 ){
- rc = pMem1->n - pMem2->n;
- }
- return rc;
-}
-
-/*
-** Move data out of a btree key or data field and into a Mem structure.
-** The data or key is taken from the entry that pCur is currently pointing
-** to. offset and amt determine what portion of the data or key to retrieve.
-** key is true to get the key or false to get data. The result is written
-** into the pMem element.
-**
-** The pMem structure is assumed to be uninitialized. Any prior content
-** is overwritten without being freed.
-**
-** If this routine fails for any reason (malloc returns NULL or unable
-** to read from the disk) then the pMem is left in an inconsistent state.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
- BtCursor *pCur, /* Cursor pointing at record to retrieve. */
- int offset, /* Offset from the start of data to return bytes from. */
- int amt, /* Number of bytes to return. */
- int key, /* If true, retrieve from the btree key, not data. */
- Mem *pMem /* OUT: Return data in this Mem structure. */
-){
- char *zData; /* Data from the btree layer */
- int available = 0; /* Number of bytes available on the local btree page */
- int rc = SQLITE_OK; /* Return code */
-
- assert( sqlite3BtreeCursorIsValid(pCur) );
-
- /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
- ** that both the BtShared and database handle mutexes are held. */
- assert( (pMem->flags & MEM_RowSet)==0 );
- if( key ){
- zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
- }else{
- zData = (char *)sqlite3BtreeDataFetch(pCur, &available);
- }
- assert( zData!=0 );
-
- if( offset+amt<=available && (pMem->flags&MEM_Dyn)==0 ){
- sqlite3VdbeMemRelease(pMem);
- pMem->z = &zData[offset];
- pMem->flags = MEM_Blob|MEM_Ephem;
- }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
- pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
- pMem->enc = 0;
- pMem->type = SQLITE_BLOB;
- if( key ){
- rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
- }else{
- rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
- }
- pMem->z[amt] = 0;
- pMem->z[amt+1] = 0;
- if( rc!=SQLITE_OK ){
- sqlite3VdbeMemRelease(pMem);
- }
- }
- pMem->n = amt;
-
- return rc;
-}
-
-/* This function is only available internally, it is not part of the
-** external API. It works in a similar way to sqlite3_value_text(),
-** except the data returned is in the encoding specified by the second
-** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
-** SQLITE_UTF8.
-**
-** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
-** If that is the case, then the result must be aligned on an even byte
-** boundary.
-*/
-SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
- if( !pVal ) return 0;
-
- assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
- assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
- assert( (pVal->flags & MEM_RowSet)==0 );
-
- if( pVal->flags&MEM_Null ){
- return 0;
- }
- assert( (MEM_Blob>>3) == MEM_Str );
- pVal->flags |= (pVal->flags & MEM_Blob)>>3;
- ExpandBlob(pVal);
- if( pVal->flags&MEM_Str ){
- sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
- if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){
- assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
- if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
- return 0;
- }
- }
- sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */
- }else{
- assert( (pVal->flags&MEM_Blob)==0 );
- sqlite3VdbeMemStringify(pVal, enc);
- assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
- }
- assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
- || pVal->db->mallocFailed );
- if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){
- return pVal->z;
- }else{
- return 0;
- }
-}
-
-/*
-** Create a new sqlite3_value object.
-*/
-SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){
- Mem *p = sqlite3DbMallocZero(db, sizeof(*p));
- if( p ){
- p->flags = MEM_Null;
- p->type = SQLITE_NULL;
- p->db = db;
- }
- return p;
-}
-
-/*
-** Create a new sqlite3_value object, containing the value of pExpr.
-**
-** This only works for very simple expressions that consist of one constant
-** token (i.e. "5", "5.1", "'a string'"). If the expression can
-** be converted directly into a value, then the value is allocated and
-** a pointer written to *ppVal. The caller is responsible for deallocating
-** the value by passing it to sqlite3ValueFree() later on. If the expression
-** cannot be converted to a value, then *ppVal is set to NULL.
-*/
-SQLITE_PRIVATE int sqlite3ValueFromExpr(
- sqlite3 *db, /* The database connection */
- Expr *pExpr, /* The expression to evaluate */
- u8 enc, /* Encoding to use */
- u8 affinity, /* Affinity to use */
- sqlite3_value **ppVal /* Write the new value here */
-){
- int op;
- char *zVal = 0;
- sqlite3_value *pVal = 0;
- int negInt = 1;
- const char *zNeg = "";
-
- if( !pExpr ){
- *ppVal = 0;
- return SQLITE_OK;
- }
- op = pExpr->op;
-
- /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3.
- ** The ifdef here is to enable us to achieve 100% branch test coverage even
- ** when SQLITE_ENABLE_STAT3 is omitted.
- */
-#ifdef SQLITE_ENABLE_STAT3
- if( op==TK_REGISTER ) op = pExpr->op2;
-#else
- if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
-#endif
-
- /* Handle negative integers in a single step. This is needed in the
- ** case when the value is -9223372036854775808.
- */
- if( op==TK_UMINUS
- && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){
- pExpr = pExpr->pLeft;
- op = pExpr->op;
- negInt = -1;
- zNeg = "-";
- }
-
- if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
- pVal = sqlite3ValueNew(db);
- if( pVal==0 ) goto no_mem;
- if( ExprHasProperty(pExpr, EP_IntValue) ){
- sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
- }else{
- zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
- if( zVal==0 ) goto no_mem;
- sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
- if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
- }
- if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
- sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
- }else{
- sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
- }
- if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
- if( enc!=SQLITE_UTF8 ){
- sqlite3VdbeChangeEncoding(pVal, enc);
- }
- }else if( op==TK_UMINUS ) {
- /* This branch happens for multiple negative signs. Ex: -(-5) */
- if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){
- sqlite3VdbeMemNumerify(pVal);
- if( pVal->u.i==SMALLEST_INT64 ){
- pVal->flags &= MEM_Int;
- pVal->flags |= MEM_Real;
- pVal->r = (double)LARGEST_INT64;
- }else{
- pVal->u.i = -pVal->u.i;
- }
- pVal->r = -pVal->r;
- sqlite3ValueApplyAffinity(pVal, affinity, enc);
- }
- }else if( op==TK_NULL ){
- pVal = sqlite3ValueNew(db);
- if( pVal==0 ) goto no_mem;
- }
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- else if( op==TK_BLOB ){
- int nVal;
- assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
- assert( pExpr->u.zToken[1]=='\'' );
- pVal = sqlite3ValueNew(db);
- if( !pVal ) goto no_mem;
- zVal = &pExpr->u.zToken[2];
- nVal = sqlite3Strlen30(zVal)-1;
- assert( zVal[nVal]=='\'' );
- sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
- 0, SQLITE_DYNAMIC);
- }
-#endif
-
- if( pVal ){
- sqlite3VdbeMemStoreType(pVal);
- }
- *ppVal = pVal;
- return SQLITE_OK;
-
-no_mem:
- db->mallocFailed = 1;
- sqlite3DbFree(db, zVal);
- sqlite3ValueFree(pVal);
- *ppVal = 0;
- return SQLITE_NOMEM;
-}
-
-/*
-** Change the string value of an sqlite3_value object
-*/
-SQLITE_PRIVATE void sqlite3ValueSetStr(
- sqlite3_value *v, /* Value to be set */
- int n, /* Length of string z */
- const void *z, /* Text of the new string */
- u8 enc, /* Encoding to use */
- void (*xDel)(void*) /* Destructor for the string */
-){
- if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel);
-}
-
-/*
-** Free an sqlite3_value object
-*/
-SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){
- if( !v ) return;
- sqlite3VdbeMemRelease((Mem *)v);
- sqlite3DbFree(((Mem*)v)->db, v);
-}
-
-/*
-** Return the number of bytes in the sqlite3_value object assuming
-** that it uses the encoding "enc"
-*/
-SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
- Mem *p = (Mem*)pVal;
- if( (p->flags & MEM_Blob)!=0 || sqlite3ValueText(pVal, enc) ){
- if( p->flags & MEM_Zero ){
- return p->n + p->u.nZero;
- }else{
- return p->n;
- }
- }
- return 0;
-}
-
-/************** End of vdbemem.c *********************************************/
-/************** Begin file vdbeaux.c *****************************************/
-/*
-** 2003 September 6
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code used for creating, destroying, and populating
-** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior
-** to version 2.8.7, all this code was combined into the vdbe.c source file.
-** But that file was getting too big so this subroutines were split out.
-*/
-
-
-
-/*
-** When debugging the code generator in a symbolic debugger, one can
-** set the sqlite3VdbeAddopTrace to 1 and all opcodes will be printed
-** as they are added to the instruction stream.
-*/
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3VdbeAddopTrace = 0;
-#endif
-
-
-/*
-** Create a new virtual database engine.
-*/
-SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
- Vdbe *p;
- p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
- if( p==0 ) return 0;
- p->db = db;
- if( db->pVdbe ){
- db->pVdbe->pPrev = p;
- }
- p->pNext = db->pVdbe;
- p->pPrev = 0;
- db->pVdbe = p;
- p->magic = VDBE_MAGIC_INIT;
- return p;
-}
-
-/*
-** Remember the SQL string for a prepared statement.
-*/
-SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
- assert( isPrepareV2==1 || isPrepareV2==0 );
- if( p==0 ) return;
-#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
- if( !isPrepareV2 ) return;
-#endif
- assert( p->zSql==0 );
- p->zSql = sqlite3DbStrNDup(p->db, z, n);
- p->isPrepareV2 = (u8)isPrepareV2;
-}
-
-/*
-** Return the SQL associated with a prepared statement
-*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
- Vdbe *p = (Vdbe *)pStmt;
- return (p && p->isPrepareV2) ? p->zSql : 0;
-}
-
-/*
-** Swap all content between two VDBE structures.
-*/
-SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
- Vdbe tmp, *pTmp;
- char *zTmp;
- tmp = *pA;
- *pA = *pB;
- *pB = tmp;
- pTmp = pA->pNext;
- pA->pNext = pB->pNext;
- pB->pNext = pTmp;
- pTmp = pA->pPrev;
- pA->pPrev = pB->pPrev;
- pB->pPrev = pTmp;
- zTmp = pA->zSql;
- pA->zSql = pB->zSql;
- pB->zSql = zTmp;
- pB->isPrepareV2 = pA->isPrepareV2;
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** Turn tracing on or off
-*/
-SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
- p->trace = trace;
-}
-#endif
-
-/*
-** Resize the Vdbe.aOp array so that it is at least one op larger than
-** it was.
-**
-** If an out-of-memory error occurs while resizing the array, return
-** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain
-** unchanged (this is so that any opcodes already allocated can be
-** correctly deallocated along with the rest of the Vdbe).
-*/
-static int growOpArray(Vdbe *p){
- VdbeOp *pNew;
- int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
- pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
- if( pNew ){
- p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op);
- p->aOp = pNew;
- }
- return (pNew ? SQLITE_OK : SQLITE_NOMEM);
-}
-
-/*
-** Add a new instruction to the list of instructions current in the
-** VDBE. Return the address of the new instruction.
-**
-** Parameters:
-**
-** p Pointer to the VDBE
-**
-** op The opcode for this instruction
-**
-** p1, p2, p3 Operands
-**
-** Use the sqlite3VdbeResolveLabel() function to fix an address and
-** the sqlite3VdbeChangeP4() function to change the value of the P4
-** operand.
-*/
-SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
- int i;
- VdbeOp *pOp;
-
- i = p->nOp;
- assert( p->magic==VDBE_MAGIC_INIT );
- assert( op>0 && op<0xff );
- if( p->nOpAlloc<=i ){
- if( growOpArray(p) ){
- return 1;
- }
- }
- p->nOp++;
- pOp = &p->aOp[i];
- pOp->opcode = (u8)op;
- pOp->p5 = 0;
- pOp->p1 = p1;
- pOp->p2 = p2;
- pOp->p3 = p3;
- pOp->p4.p = 0;
- pOp->p4type = P4_NOTUSED;
-#ifdef SQLITE_DEBUG
- pOp->zComment = 0;
- if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
-#endif
-#ifdef VDBE_PROFILE
- pOp->cycles = 0;
- pOp->cnt = 0;
-#endif
- return i;
-}
-SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){
- return sqlite3VdbeAddOp3(p, op, 0, 0, 0);
-}
-SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){
- return sqlite3VdbeAddOp3(p, op, p1, 0, 0);
-}
-SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){
- return sqlite3VdbeAddOp3(p, op, p1, p2, 0);
-}
-
-
-/*
-** Add an opcode that includes the p4 value as a pointer.
-*/
-SQLITE_PRIVATE int sqlite3VdbeAddOp4(
- Vdbe *p, /* Add the opcode to this VM */
- int op, /* The new opcode */
- int p1, /* The P1 operand */
- int p2, /* The P2 operand */
- int p3, /* The P3 operand */
- const char *zP4, /* The P4 operand */
- int p4type /* P4 operand type */
-){
- int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
- sqlite3VdbeChangeP4(p, addr, zP4, p4type);
- return addr;
-}
-
-/*
-** Add an OP_ParseSchema opcode. This routine is broken out from
-** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
-** as having been used.
-**
-** The zWhere string must have been obtained from sqlite3_malloc().
-** This routine will take ownership of the allocated memory.
-*/
-SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){
- int j;
- int addr = sqlite3VdbeAddOp3(p, OP_ParseSchema, iDb, 0, 0);
- sqlite3VdbeChangeP4(p, addr, zWhere, P4_DYNAMIC);
- for(j=0; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j);
-}
-
-/*
-** Add an opcode that includes the p4 value as an integer.
-*/
-SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(
- Vdbe *p, /* Add the opcode to this VM */
- int op, /* The new opcode */
- int p1, /* The P1 operand */
- int p2, /* The P2 operand */
- int p3, /* The P3 operand */
- int p4 /* The P4 operand as an integer */
-){
- int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
- sqlite3VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32);
- return addr;
-}
-
-/*
-** Create a new symbolic label for an instruction that has yet to be
-** coded. The symbolic label is really just a negative number. The
-** label can be used as the P2 value of an operation. Later, when
-** the label is resolved to a specific address, the VDBE will scan
-** through its operation list and change all values of P2 which match
-** the label into the resolved address.
-**
-** The VDBE knows that a P2 value is a label because labels are
-** always negative and P2 values are suppose to be non-negative.
-** Hence, a negative P2 value is a label that has yet to be resolved.
-**
-** Zero is returned if a malloc() fails.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
- int i = p->nLabel++;
- assert( p->magic==VDBE_MAGIC_INIT );
- if( (i & (i-1))==0 ){
- p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
- (i*2+1)*sizeof(p->aLabel[0]));
- }
- if( p->aLabel ){
- p->aLabel[i] = -1;
- }
- return -1-i;
-}
-
-/*
-** Resolve label "x" to be the address of the next instruction to
-** be inserted. The parameter "x" must have been obtained from
-** a prior call to sqlite3VdbeMakeLabel().
-*/
-SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
- int j = -1-x;
- assert( p->magic==VDBE_MAGIC_INIT );
- assert( j>=0 && j<p->nLabel );
- if( p->aLabel ){
- p->aLabel[j] = p->nOp;
- }
-}
-
-/*
-** Mark the VDBE as one that can only be run one time.
-*/
-SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){
- p->runOnlyOnce = 1;
-}
-
-#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
-
-/*
-** The following type and function are used to iterate through all opcodes
-** in a Vdbe main program and each of the sub-programs (triggers) it may
-** invoke directly or indirectly. It should be used as follows:
-**
-** Op *pOp;
-** VdbeOpIter sIter;
-**
-** memset(&sIter, 0, sizeof(sIter));
-** sIter.v = v; // v is of type Vdbe*
-** while( (pOp = opIterNext(&sIter)) ){
-** // Do something with pOp
-** }
-** sqlite3DbFree(v->db, sIter.apSub);
-**
-*/
-typedef struct VdbeOpIter VdbeOpIter;
-struct VdbeOpIter {
- Vdbe *v; /* Vdbe to iterate through the opcodes of */
- SubProgram **apSub; /* Array of subprograms */
- int nSub; /* Number of entries in apSub */
- int iAddr; /* Address of next instruction to return */
- int iSub; /* 0 = main program, 1 = first sub-program etc. */
-};
-static Op *opIterNext(VdbeOpIter *p){
- Vdbe *v = p->v;
- Op *pRet = 0;
- Op *aOp;
- int nOp;
-
- if( p->iSub<=p->nSub ){
-
- if( p->iSub==0 ){
- aOp = v->aOp;
- nOp = v->nOp;
- }else{
- aOp = p->apSub[p->iSub-1]->aOp;
- nOp = p->apSub[p->iSub-1]->nOp;
- }
- assert( p->iAddr<nOp );
-
- pRet = &aOp[p->iAddr];
- p->iAddr++;
- if( p->iAddr==nOp ){
- p->iSub++;
- p->iAddr = 0;
- }
-
- if( pRet->p4type==P4_SUBPROGRAM ){
- int nByte = (p->nSub+1)*sizeof(SubProgram*);
- int j;
- for(j=0; j<p->nSub; j++){
- if( p->apSub[j]==pRet->p4.pProgram ) break;
- }
- if( j==p->nSub ){
- p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte);
- if( !p->apSub ){
- pRet = 0;
- }else{
- p->apSub[p->nSub++] = pRet->p4.pProgram;
- }
- }
- }
- }
-
- return pRet;
-}
-
-/*
-** Check if the program stored in the VM associated with pParse may
-** throw an ABORT exception (causing the statement, but not entire transaction
-** to be rolled back). This condition is true if the main program or any
-** sub-programs contains any of the following:
-**
-** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
-** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
-** * OP_Destroy
-** * OP_VUpdate
-** * OP_VRename
-** * OP_FkCounter with P2==0 (immediate foreign key constraint)
-**
-** Then check that the value of Parse.mayAbort is true if an
-** ABORT may be thrown, or false otherwise. Return true if it does
-** match, or false otherwise. This function is intended to be used as
-** part of an assert statement in the compiler. Similar to:
-**
-** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
-*/
-SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
- int hasAbort = 0;
- Op *pOp;
- VdbeOpIter sIter;
- memset(&sIter, 0, sizeof(sIter));
- sIter.v = v;
-
- while( (pOp = opIterNext(&sIter))!=0 ){
- int opcode = pOp->opcode;
- if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1)
-#endif
- || ((opcode==OP_Halt || opcode==OP_HaltIfNull)
- && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
- ){
- hasAbort = 1;
- break;
- }
- }
- sqlite3DbFree(v->db, sIter.apSub);
-
- /* Return true if hasAbort==mayAbort. Or if a malloc failure occured.
- ** If malloc failed, then the while() loop above may not have iterated
- ** through all opcodes and hasAbort may be set incorrectly. Return
- ** true for this case to prevent the assert() in the callers frame
- ** from failing. */
- return ( v->db->mallocFailed || hasAbort==mayAbort );
-}
-#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
-
-/*
-** Loop through the program looking for P2 values that are negative
-** on jump instructions. Each such value is a label. Resolve the
-** label by setting the P2 value to its correct non-zero value.
-**
-** This routine is called once after all opcodes have been inserted.
-**
-** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument
-** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by
-** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
-**
-** The Op.opflags field is set on all opcodes.
-*/
-static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
- int i;
- int nMaxArgs = *pMaxFuncArgs;
- Op *pOp;
- int *aLabel = p->aLabel;
- p->readOnly = 1;
- for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
- u8 opcode = pOp->opcode;
-
- pOp->opflags = sqlite3OpcodeProperty[opcode];
- if( opcode==OP_Function || opcode==OP_AggStep ){
- if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
- }else if( (opcode==OP_Transaction && pOp->p2!=0) || opcode==OP_Vacuum ){
- p->readOnly = 0;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( opcode==OP_VUpdate ){
- if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
- }else if( opcode==OP_VFilter ){
- int n;
- assert( p->nOp - i >= 3 );
- assert( pOp[-1].opcode==OP_Integer );
- n = pOp[-1].p1;
- if( n>nMaxArgs ) nMaxArgs = n;
-#endif
- }else if( opcode==OP_Next || opcode==OP_SorterNext ){
- pOp->p4.xAdvance = sqlite3BtreeNext;
- pOp->p4type = P4_ADVANCE;
- }else if( opcode==OP_Prev ){
- pOp->p4.xAdvance = sqlite3BtreePrevious;
- pOp->p4type = P4_ADVANCE;
- }
-
- if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
- assert( -1-pOp->p2<p->nLabel );
- pOp->p2 = aLabel[-1-pOp->p2];
- }
- }
- sqlite3DbFree(p->db, p->aLabel);
- p->aLabel = 0;
-
- *pMaxFuncArgs = nMaxArgs;
-}
-
-/*
-** Return the address of the next instruction to be inserted.
-*/
-SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
- assert( p->magic==VDBE_MAGIC_INIT );
- return p->nOp;
-}
-
-/*
-** This function returns a pointer to the array of opcodes associated with
-** the Vdbe passed as the first argument. It is the callers responsibility
-** to arrange for the returned array to be eventually freed using the
-** vdbeFreeOpArray() function.
-**
-** Before returning, *pnOp is set to the number of entries in the returned
-** array. Also, *pnMaxArg is set to the larger of its current value and
-** the number of entries in the Vdbe.apArg[] array required to execute the
-** returned program.
-*/
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
- VdbeOp *aOp = p->aOp;
- assert( aOp && !p->db->mallocFailed );
-
- /* Check that sqlite3VdbeUsesBtree() was not called on this VM */
- assert( p->btreeMask==0 );
-
- resolveP2Values(p, pnMaxArg);
- *pnOp = p->nOp;
- p->aOp = 0;
- return aOp;
-}
-
-/*
-** Add a whole list of operations to the operation stack. Return the
-** address of the first operation added.
-*/
-SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
- int addr;
- assert( p->magic==VDBE_MAGIC_INIT );
- if( p->nOp + nOp > p->nOpAlloc && growOpArray(p) ){
- return 0;
- }
- addr = p->nOp;
- if( ALWAYS(nOp>0) ){
- int i;
- VdbeOpList const *pIn = aOp;
- for(i=0; i<nOp; i++, pIn++){
- int p2 = pIn->p2;
- VdbeOp *pOut = &p->aOp[i+addr];
- pOut->opcode = pIn->opcode;
- pOut->p1 = pIn->p1;
- if( p2<0 && (sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP)!=0 ){
- pOut->p2 = addr + ADDR(p2);
- }else{
- pOut->p2 = p2;
- }
- pOut->p3 = pIn->p3;
- pOut->p4type = P4_NOTUSED;
- pOut->p4.p = 0;
- pOut->p5 = 0;
-#ifdef SQLITE_DEBUG
- pOut->zComment = 0;
- if( sqlite3VdbeAddopTrace ){
- sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
- }
-#endif
- }
- p->nOp += nOp;
- }
- return addr;
-}
-
-/*
-** Change the value of the P1 operand for a specific instruction.
-** This routine is useful when a large program is loaded from a
-** static array using sqlite3VdbeAddOpList but we want to make a
-** few minor changes to the program.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
- assert( p!=0 );
- if( ((u32)p->nOp)>addr ){
- p->aOp[addr].p1 = val;
- }
-}
-
-/*
-** Change the value of the P2 operand for a specific instruction.
-** This routine is useful for setting a jump destination.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
- assert( p!=0 );
- if( ((u32)p->nOp)>addr ){
- p->aOp[addr].p2 = val;
- }
-}
-
-/*
-** Change the value of the P3 operand for a specific instruction.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
- assert( p!=0 );
- if( ((u32)p->nOp)>addr ){
- p->aOp[addr].p3 = val;
- }
-}
-
-/*
-** Change the value of the P5 operand for the most recently
-** added operation.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
- assert( p!=0 );
- if( p->aOp ){
- assert( p->nOp>0 );
- p->aOp[p->nOp-1].p5 = val;
- }
-}
-
-/*
-** Change the P2 operand of instruction addr so that it points to
-** the address of the next instruction to be coded.
-*/
-SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
- assert( addr>=0 || p->db->mallocFailed );
- if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp);
-}
-
-
-/*
-** If the input FuncDef structure is ephemeral, then free it. If
-** the FuncDef is not ephermal, then do nothing.
-*/
-static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
- if( ALWAYS(pDef) && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){
- sqlite3DbFree(db, pDef);
- }
-}
-
-static void vdbeFreeOpArray(sqlite3 *, Op *, int);
-
-/*
-** Delete a P4 value if necessary.
-*/
-static void freeP4(sqlite3 *db, int p4type, void *p4){
- if( p4 ){
- assert( db );
- switch( p4type ){
- case P4_REAL:
- case P4_INT64:
- case P4_DYNAMIC:
- case P4_KEYINFO:
- case P4_INTARRAY:
- case P4_KEYINFO_HANDOFF: {
- sqlite3DbFree(db, p4);
- break;
- }
- case P4_MPRINTF: {
- if( db->pnBytesFreed==0 ) sqlite3_free(p4);
- break;
- }
- case P4_VDBEFUNC: {
- VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
- freeEphemeralFunction(db, pVdbeFunc->pFunc);
- if( db->pnBytesFreed==0 ) sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
- sqlite3DbFree(db, pVdbeFunc);
- break;
- }
- case P4_FUNCDEF: {
- freeEphemeralFunction(db, (FuncDef*)p4);
- break;
- }
- case P4_MEM: {
- if( db->pnBytesFreed==0 ){
- sqlite3ValueFree((sqlite3_value*)p4);
- }else{
- Mem *p = (Mem*)p4;
- sqlite3DbFree(db, p->zMalloc);
- sqlite3DbFree(db, p);
- }
- break;
- }
- case P4_VTAB : {
- if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4);
- break;
- }
- }
- }
-}
-
-/*
-** Free the space allocated for aOp and any p4 values allocated for the
-** opcodes contained within. If aOp is not NULL it is assumed to contain
-** nOp entries.
-*/
-static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
- if( aOp ){
- Op *pOp;
- for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
- freeP4(db, pOp->p4type, pOp->p4.p);
-#ifdef SQLITE_DEBUG
- sqlite3DbFree(db, pOp->zComment);
-#endif
- }
- }
- sqlite3DbFree(db, aOp);
-}
-
-/*
-** Link the SubProgram object passed as the second argument into the linked
-** list at Vdbe.pSubProgram. This list is used to delete all sub-program
-** objects when the VM is no longer required.
-*/
-SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
- p->pNext = pVdbe->pProgram;
- pVdbe->pProgram = p;
-}
-
-/*
-** Change the opcode at addr into OP_Noop
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
- if( p->aOp ){
- VdbeOp *pOp = &p->aOp[addr];
- sqlite3 *db = p->db;
- freeP4(db, pOp->p4type, pOp->p4.p);
- memset(pOp, 0, sizeof(pOp[0]));
- pOp->opcode = OP_Noop;
- }
-}
-
-/*
-** Change the value of the P4 operand for a specific instruction.
-** This routine is useful when a large program is loaded from a
-** static array using sqlite3VdbeAddOpList but we want to make a
-** few minor changes to the program.
-**
-** If n>=0 then the P4 operand is dynamic, meaning that a copy of
-** the string is made into memory obtained from sqlite3_malloc().
-** A value of n==0 means copy bytes of zP4 up to and including the
-** first null byte. If n>0 then copy n+1 bytes of zP4.
-**
-** If n==P4_KEYINFO it means that zP4 is a pointer to a KeyInfo structure.
-** A copy is made of the KeyInfo structure into memory obtained from
-** sqlite3_malloc, to be freed when the Vdbe is finalized.
-** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure
-** stored in memory that the caller has obtained from sqlite3_malloc. The
-** caller should not free the allocation, it will be freed when the Vdbe is
-** finalized.
-**
-** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points
-** to a string or structure that is guaranteed to exist for the lifetime of
-** the Vdbe. In these cases we can just copy the pointer.
-**
-** If addr<0 then change P4 on the most recently inserted instruction.
-*/
-SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
- Op *pOp;
- sqlite3 *db;
- assert( p!=0 );
- db = p->db;
- assert( p->magic==VDBE_MAGIC_INIT );
- if( p->aOp==0 || db->mallocFailed ){
- if ( n!=P4_KEYINFO && n!=P4_VTAB ) {
- freeP4(db, n, (void*)*(char**)&zP4);
- }
- return;
- }
- assert( p->nOp>0 );
- assert( addr<p->nOp );
- if( addr<0 ){
- addr = p->nOp - 1;
- }
- pOp = &p->aOp[addr];
- assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_INT32 );
- freeP4(db, pOp->p4type, pOp->p4.p);
- pOp->p4.p = 0;
- if( n==P4_INT32 ){
- /* Note: this cast is safe, because the origin data point was an int
- ** that was cast to a (const char *). */
- pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
- pOp->p4type = P4_INT32;
- }else if( zP4==0 ){
- pOp->p4.p = 0;
- pOp->p4type = P4_NOTUSED;
- }else if( n==P4_KEYINFO ){
- KeyInfo *pKeyInfo;
- int nField, nByte;
-
- nField = ((KeyInfo*)zP4)->nField;
- nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
- pKeyInfo = sqlite3DbMallocRaw(0, nByte);
- pOp->p4.pKeyInfo = pKeyInfo;
- if( pKeyInfo ){
- u8 *aSortOrder;
- memcpy((char*)pKeyInfo, zP4, nByte - nField);
- aSortOrder = pKeyInfo->aSortOrder;
- assert( aSortOrder!=0 );
- pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
- memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
- pOp->p4type = P4_KEYINFO;
- }else{
- p->db->mallocFailed = 1;
- pOp->p4type = P4_NOTUSED;
- }
- }else if( n==P4_KEYINFO_HANDOFF ){
- pOp->p4.p = (void*)zP4;
- pOp->p4type = P4_KEYINFO;
- }else if( n==P4_VTAB ){
- pOp->p4.p = (void*)zP4;
- pOp->p4type = P4_VTAB;
- sqlite3VtabLock((VTable *)zP4);
- assert( ((VTable *)zP4)->db==p->db );
- }else if( n<0 ){
- pOp->p4.p = (void*)zP4;
- pOp->p4type = (signed char)n;
- }else{
- if( n==0 ) n = sqlite3Strlen30(zP4);
- pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
- pOp->p4type = P4_DYNAMIC;
- }
-}
-
-#ifndef NDEBUG
-/*
-** Change the comment on the most recently coded instruction. Or
-** insert a No-op and add the comment to that new instruction. This
-** makes the code easier to read during debugging. None of this happens
-** in a production build.
-*/
-static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
- assert( p->nOp>0 || p->aOp==0 );
- assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
- if( p->nOp ){
- assert( p->aOp );
- sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
- p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
- }
-}
-SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
- va_list ap;
- if( p ){
- va_start(ap, zFormat);
- vdbeVComment(p, zFormat, ap);
- va_end(ap);
- }
-}
-SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
- va_list ap;
- if( p ){
- sqlite3VdbeAddOp0(p, OP_Noop);
- va_start(ap, zFormat);
- vdbeVComment(p, zFormat, ap);
- va_end(ap);
- }
-}
-#endif /* NDEBUG */
-
-/*
-** Return the opcode for a given address. If the address is -1, then
-** return the most recently inserted opcode.
-**
-** If a memory allocation error has occurred prior to the calling of this
-** routine, then a pointer to a dummy VdbeOp will be returned. That opcode
-** is readable but not writable, though it is cast to a writable value.
-** The return of a dummy opcode allows the call to continue functioning
-** after a OOM fault without having to check to see if the return from
-** this routine is a valid pointer. But because the dummy.opcode is 0,
-** dummy will never be written to. This is verified by code inspection and
-** by running with Valgrind.
-**
-** About the #ifdef SQLITE_OMIT_TRACE: Normally, this routine is never called
-** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE,
-** an OP_Trace instruction is always inserted by sqlite3VdbeGet() as soon as
-** a new VDBE is created. So we are free to set addr to p->nOp-1 without
-** having to double-check to make sure that the result is non-negative. But
-** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to
-** check the value of p->nOp-1 before continuing.
-*/
-SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
- /* C89 specifies that the constant "dummy" will be initialized to all
- ** zeros, which is correct. MSVC generates a warning, nevertheless. */
- static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */
- assert( p->magic==VDBE_MAGIC_INIT );
- if( addr<0 ){
-#ifdef SQLITE_OMIT_TRACE
- if( p->nOp==0 ) return (VdbeOp*)&dummy;
-#endif
- addr = p->nOp - 1;
- }
- assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
- if( p->db->mallocFailed ){
- return (VdbeOp*)&dummy;
- }else{
- return &p->aOp[addr];
- }
-}
-
-#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
- || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
-/*
-** Compute a string that describes the P4 parameter for an opcode.
-** Use zTemp for any required temporary buffer space.
-*/
-static char *displayP4(Op *pOp, char *zTemp, int nTemp){
- char *zP4 = zTemp;
- assert( nTemp>=20 );
- switch( pOp->p4type ){
- case P4_KEYINFO_STATIC:
- case P4_KEYINFO: {
- int i, j;
- KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
- assert( pKeyInfo->aSortOrder!=0 );
- sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
- i = sqlite3Strlen30(zTemp);
- for(j=0; j<pKeyInfo->nField; j++){
- CollSeq *pColl = pKeyInfo->aColl[j];
- const char *zColl = pColl ? pColl->zName : "nil";
- int n = sqlite3Strlen30(zColl);
- if( i+n>nTemp-6 ){
- memcpy(&zTemp[i],",...",4);
- break;
- }
- zTemp[i++] = ',';
- if( pKeyInfo->aSortOrder[j] ){
- zTemp[i++] = '-';
- }
- memcpy(&zTemp[i], zColl, n+1);
- i += n;
- }
- zTemp[i++] = ')';
- zTemp[i] = 0;
- assert( i<nTemp );
- break;
- }
- case P4_COLLSEQ: {
- CollSeq *pColl = pOp->p4.pColl;
- sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName);
- break;
- }
- case P4_FUNCDEF: {
- FuncDef *pDef = pOp->p4.pFunc;
- sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
- break;
- }
- case P4_INT64: {
- sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64);
- break;
- }
- case P4_INT32: {
- sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i);
- break;
- }
- case P4_REAL: {
- sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal);
- break;
- }
- case P4_MEM: {
- Mem *pMem = pOp->p4.pMem;
- if( pMem->flags & MEM_Str ){
- zP4 = pMem->z;
- }else if( pMem->flags & MEM_Int ){
- sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
- }else if( pMem->flags & MEM_Real ){
- sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r);
- }else if( pMem->flags & MEM_Null ){
- sqlite3_snprintf(nTemp, zTemp, "NULL");
- }else{
- assert( pMem->flags & MEM_Blob );
- zP4 = "(blob)";
- }
- break;
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- case P4_VTAB: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
- sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
- break;
- }
-#endif
- case P4_INTARRAY: {
- sqlite3_snprintf(nTemp, zTemp, "intarray");
- break;
- }
- case P4_SUBPROGRAM: {
- sqlite3_snprintf(nTemp, zTemp, "program");
- break;
- }
- case P4_ADVANCE: {
- zTemp[0] = 0;
- break;
- }
- default: {
- zP4 = pOp->p4.z;
- if( zP4==0 ){
- zP4 = zTemp;
- zTemp[0] = 0;
- }
- }
- }
- assert( zP4!=0 );
- return zP4;
-}
-#endif
-
-/*
-** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
-**
-** The prepared statements need to know in advance the complete set of
-** attached databases that will be use. A mask of these databases
-** is maintained in p->btreeMask. The p->lockMask value is the subset of
-** p->btreeMask of databases that will require a lock.
-*/
-SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){
- assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 );
- assert( i<(int)sizeof(p->btreeMask)*8 );
- p->btreeMask |= ((yDbMask)1)<<i;
- if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){
- p->lockMask |= ((yDbMask)1)<<i;
- }
-}
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
-/*
-** If SQLite is compiled to support shared-cache mode and to be threadsafe,
-** this routine obtains the mutex associated with each BtShared structure
-** that may be accessed by the VM passed as an argument. In doing so it also
-** sets the BtShared.db member of each of the BtShared structures, ensuring
-** that the correct busy-handler callback is invoked if required.
-**
-** If SQLite is not threadsafe but does support shared-cache mode, then
-** sqlite3BtreeEnter() is invoked to set the BtShared.db variables
-** of all of BtShared structures accessible via the database handle
-** associated with the VM.
-**
-** If SQLite is not threadsafe and does not support shared-cache mode, this
-** function is a no-op.
-**
-** The p->btreeMask field is a bitmask of all btrees that the prepared
-** statement p will ever use. Let N be the number of bits in p->btreeMask
-** corresponding to btrees that use shared cache. Then the runtime of
-** this routine is N*N. But as N is rarely more than 1, this should not
-** be a problem.
-*/
-SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){
- int i;
- yDbMask mask;
- sqlite3 *db;
- Db *aDb;
- int nDb;
- if( p->lockMask==0 ) return; /* The common case */
- db = p->db;
- aDb = db->aDb;
- nDb = db->nDb;
- for(i=0, mask=1; i<nDb; i++, mask += mask){
- if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){
- sqlite3BtreeEnter(aDb[i].pBt);
- }
- }
-}
-#endif
-
-#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
-/*
-** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter().
-*/
-SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){
- int i;
- yDbMask mask;
- sqlite3 *db;
- Db *aDb;
- int nDb;
- if( p->lockMask==0 ) return; /* The common case */
- db = p->db;
- aDb = db->aDb;
- nDb = db->nDb;
- for(i=0, mask=1; i<nDb; i++, mask += mask){
- if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){
- sqlite3BtreeLeave(aDb[i].pBt);
- }
- }
-}
-#endif
-
-#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
-/*
-** Print a single opcode. This routine is used for debugging only.
-*/
-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
- char *zP4;
- char zPtr[50];
- static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-4s %.2X %s\n";
- if( pOut==0 ) pOut = stdout;
- zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
- fprintf(pOut, zFormat1, pc,
- sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
-#ifdef SQLITE_DEBUG
- pOp->zComment ? pOp->zComment : ""
-#else
- ""
-#endif
- );
- fflush(pOut);
-}
-#endif
-
-/*
-** Release an array of N Mem elements
-*/
-static void releaseMemArray(Mem *p, int N){
- if( p && N ){
- Mem *pEnd;
- sqlite3 *db = p->db;
- u8 malloc_failed = db->mallocFailed;
- if( db->pnBytesFreed ){
- for(pEnd=&p[N]; p<pEnd; p++){
- sqlite3DbFree(db, p->zMalloc);
- }
- return;
- }
- for(pEnd=&p[N]; p<pEnd; p++){
- assert( (&p[1])==pEnd || p[0].db==p[1].db );
-
- /* This block is really an inlined version of sqlite3VdbeMemRelease()
- ** that takes advantage of the fact that the memory cell value is
- ** being set to NULL after releasing any dynamic resources.
- **
- ** The justification for duplicating code is that according to
- ** callgrind, this causes a certain test case to hit the CPU 4.7
- ** percent less (x86 linux, gcc version 4.1.2, -O6) than if
- ** sqlite3MemRelease() were called from here. With -O2, this jumps
- ** to 6.6 percent. The test case is inserting 1000 rows into a table
- ** with no indexes using a single prepared INSERT statement, bind()
- ** and reset(). Inserts are grouped into a transaction.
- */
- if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
- sqlite3VdbeMemRelease(p);
- }else if( p->zMalloc ){
- sqlite3DbFree(db, p->zMalloc);
- p->zMalloc = 0;
- }
-
- p->flags = MEM_Invalid;
- }
- db->mallocFailed = malloc_failed;
- }
-}
-
-/*
-** Delete a VdbeFrame object and its contents. VdbeFrame objects are
-** allocated by the OP_Program opcode in sqlite3VdbeExec().
-*/
-SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
- int i;
- Mem *aMem = VdbeFrameMem(p);
- VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
- for(i=0; i<p->nChildCsr; i++){
- sqlite3VdbeFreeCursor(p->v, apCsr[i]);
- }
- releaseMemArray(aMem, p->nChildMem);
- sqlite3DbFree(p->v->db, p);
-}
-
-#ifndef SQLITE_OMIT_EXPLAIN
-/*
-** Give a listing of the program in the virtual machine.
-**
-** The interface is the same as sqlite3VdbeExec(). But instead of
-** running the code, it invokes the callback once for each instruction.
-** This feature is used to implement "EXPLAIN".
-**
-** When p->explain==1, each instruction is listed. When
-** p->explain==2, only OP_Explain instructions are listed and these
-** are shown in a different format. p->explain==2 is used to implement
-** EXPLAIN QUERY PLAN.
-**
-** When p->explain==1, first the main program is listed, then each of
-** the trigger subprograms are listed one by one.
-*/
-SQLITE_PRIVATE int sqlite3VdbeList(
- Vdbe *p /* The VDBE */
-){
- int nRow; /* Stop when row count reaches this */
- int nSub = 0; /* Number of sub-vdbes seen so far */
- SubProgram **apSub = 0; /* Array of sub-vdbes */
- Mem *pSub = 0; /* Memory cell hold array of subprogs */
- sqlite3 *db = p->db; /* The database connection */
- int i; /* Loop counter */
- int rc = SQLITE_OK; /* Return code */
- Mem *pMem = &p->aMem[1]; /* First Mem of result set */
-
- assert( p->explain );
- assert( p->magic==VDBE_MAGIC_RUN );
- assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
-
- /* Even though this opcode does not use dynamic strings for
- ** the result, result columns may become dynamic if the user calls
- ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
- */
- releaseMemArray(pMem, 8);
- p->pResultSet = 0;
-
- if( p->rc==SQLITE_NOMEM ){
- /* This happens if a malloc() inside a call to sqlite3_column_text() or
- ** sqlite3_column_text16() failed. */
- db->mallocFailed = 1;
- return SQLITE_ERROR;
- }
-
- /* When the number of output rows reaches nRow, that means the
- ** listing has finished and sqlite3_step() should return SQLITE_DONE.
- ** nRow is the sum of the number of rows in the main program, plus
- ** the sum of the number of rows in all trigger subprograms encountered
- ** so far. The nRow value will increase as new trigger subprograms are
- ** encountered, but p->pc will eventually catch up to nRow.
- */
- nRow = p->nOp;
- if( p->explain==1 ){
- /* The first 8 memory cells are used for the result set. So we will
- ** commandeer the 9th cell to use as storage for an array of pointers
- ** to trigger subprograms. The VDBE is guaranteed to have at least 9
- ** cells. */
- assert( p->nMem>9 );
- pSub = &p->aMem[9];
- if( pSub->flags&MEM_Blob ){
- /* On the first call to sqlite3_step(), pSub will hold a NULL. It is
- ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
- nSub = pSub->n/sizeof(Vdbe*);
- apSub = (SubProgram **)pSub->z;
- }
- for(i=0; i<nSub; i++){
- nRow += apSub[i]->nOp;
- }
- }
-
- do{
- i = p->pc++;
- }while( i<nRow && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
- if( i>=nRow ){
- p->rc = SQLITE_OK;
- rc = SQLITE_DONE;
- }else if( db->u1.isInterrupted ){
- p->rc = SQLITE_INTERRUPT;
- rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
- }else{
- char *z;
- Op *pOp;
- if( i<p->nOp ){
- /* The output line number is small enough that we are still in the
- ** main program. */
- pOp = &p->aOp[i];
- }else{
- /* We are currently listing subprograms. Figure out which one and
- ** pick up the appropriate opcode. */
- int j;
- i -= p->nOp;
- for(j=0; i>=apSub[j]->nOp; j++){
- i -= apSub[j]->nOp;
- }
- pOp = &apSub[j]->aOp[i];
- }
- if( p->explain==1 ){
- pMem->flags = MEM_Int;
- pMem->type = SQLITE_INTEGER;
- pMem->u.i = i; /* Program counter */
- pMem++;
-
- pMem->flags = MEM_Static|MEM_Str|MEM_Term;
- pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->type = SQLITE_TEXT;
- pMem->enc = SQLITE_UTF8;
- pMem++;
-
- /* When an OP_Program opcode is encounter (the only opcode that has
- ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
- ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
- ** has not already been seen.
- */
- if( pOp->p4type==P4_SUBPROGRAM ){
- int nByte = (nSub+1)*sizeof(SubProgram*);
- int j;
- for(j=0; j<nSub; j++){
- if( apSub[j]==pOp->p4.pProgram ) break;
- }
- if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){
- apSub = (SubProgram **)pSub->z;
- apSub[nSub++] = pOp->p4.pProgram;
- pSub->flags |= MEM_Blob;
- pSub->n = nSub*sizeof(SubProgram*);
- }
- }
- }
-
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p1; /* P1 */
- pMem->type = SQLITE_INTEGER;
- pMem++;
-
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p2; /* P2 */
- pMem->type = SQLITE_INTEGER;
- pMem++;
-
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p3; /* P3 */
- pMem->type = SQLITE_INTEGER;
- pMem++;
-
- if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
- z = displayP4(pOp, pMem->z, 32);
- if( z!=pMem->z ){
- sqlite3VdbeMemSetStr(pMem, z, -1, SQLITE_UTF8, 0);
- }else{
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- }
- pMem->type = SQLITE_TEXT;
- pMem++;
-
- if( p->explain==1 ){
- if( sqlite3VdbeMemGrow(pMem, 4, 0) ){
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
- pMem->n = 2;
- sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
- pMem->type = SQLITE_TEXT;
- pMem->enc = SQLITE_UTF8;
- pMem++;
-
-#ifdef SQLITE_DEBUG
- if( pOp->zComment ){
- pMem->flags = MEM_Str|MEM_Term;
- pMem->z = pOp->zComment;
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- pMem->type = SQLITE_TEXT;
- }else
-#endif
- {
- pMem->flags = MEM_Null; /* Comment */
- pMem->type = SQLITE_NULL;
- }
- }
-
- p->nResColumn = 8 - 4*(p->explain-1);
- p->pResultSet = &p->aMem[1];
- p->rc = SQLITE_OK;
- rc = SQLITE_ROW;
- }
- return rc;
-}
-#endif /* SQLITE_OMIT_EXPLAIN */
-
-#ifdef SQLITE_DEBUG
-/*
-** Print the SQL that was used to generate a VDBE program.
-*/
-SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){
- int nOp = p->nOp;
- VdbeOp *pOp;
- if( nOp<1 ) return;
- pOp = &p->aOp[0];
- if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
- const char *z = pOp->p4.z;
- while( sqlite3Isspace(*z) ) z++;
- printf("SQL: [%s]\n", z);
- }
-}
-#endif
-
-#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
-/*
-** Print an IOTRACE message showing SQL content.
-*/
-SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){
- int nOp = p->nOp;
- VdbeOp *pOp;
- if( sqlite3IoTrace==0 ) return;
- if( nOp<1 ) return;
- pOp = &p->aOp[0];
- if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
- int i, j;
- char z[1000];
- sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z);
- for(i=0; sqlite3Isspace(z[i]); i++){}
- for(j=0; z[i]; i++){
- if( sqlite3Isspace(z[i]) ){
- if( z[i-1]!=' ' ){
- z[j++] = ' ';
- }
- }else{
- z[j++] = z[i];
- }
- }
- z[j] = 0;
- sqlite3IoTrace("SQL %s\n", z);
- }
-}
-#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
-
-/*
-** Allocate space from a fixed size buffer and return a pointer to
-** that space. If insufficient space is available, return NULL.
-**
-** The pBuf parameter is the initial value of a pointer which will
-** receive the new memory. pBuf is normally NULL. If pBuf is not
-** NULL, it means that memory space has already been allocated and that
-** this routine should not allocate any new memory. When pBuf is not
-** NULL simply return pBuf. Only allocate new memory space when pBuf
-** is NULL.
-**
-** nByte is the number of bytes of space needed.
-**
-** *ppFrom points to available space and pEnd points to the end of the
-** available space. When space is allocated, *ppFrom is advanced past
-** the end of the allocated space.
-**
-** *pnByte is a counter of the number of bytes of space that have failed
-** to allocate. If there is insufficient space in *ppFrom to satisfy the
-** request, then increment *pnByte by the amount of the request.
-*/
-static void *allocSpace(
- void *pBuf, /* Where return pointer will be stored */
- int nByte, /* Number of bytes to allocate */
- u8 **ppFrom, /* IN/OUT: Allocate from *ppFrom */
- u8 *pEnd, /* Pointer to 1 byte past the end of *ppFrom buffer */
- int *pnByte /* If allocation cannot be made, increment *pnByte */
-){
- assert( EIGHT_BYTE_ALIGNMENT(*ppFrom) );
- if( pBuf ) return pBuf;
- nByte = ROUND8(nByte);
- if( &(*ppFrom)[nByte] <= pEnd ){
- pBuf = (void*)*ppFrom;
- *ppFrom += nByte;
- }else{
- *pnByte += nByte;
- }
- return pBuf;
-}
-
-/*
-** Rewind the VDBE back to the beginning in preparation for
-** running it.
-*/
-SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
- int i;
-#endif
- assert( p!=0 );
- assert( p->magic==VDBE_MAGIC_INIT );
-
- /* There should be at least one opcode.
- */
- assert( p->nOp>0 );
-
- /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
- p->magic = VDBE_MAGIC_RUN;
-
-#ifdef SQLITE_DEBUG
- for(i=1; i<p->nMem; i++){
- assert( p->aMem[i].db==p->db );
- }
-#endif
- p->pc = -1;
- p->rc = SQLITE_OK;
- p->errorAction = OE_Abort;
- p->magic = VDBE_MAGIC_RUN;
- p->nChange = 0;
- p->cacheCtr = 1;
- p->minWriteFileFormat = 255;
- p->iStatement = 0;
- p->nFkConstraint = 0;
-#ifdef VDBE_PROFILE
- for(i=0; i<p->nOp; i++){
- p->aOp[i].cnt = 0;
- p->aOp[i].cycles = 0;
- }
-#endif
-}
-
-/*
-** Prepare a virtual machine for execution for the first time after
-** creating the virtual machine. This involves things such
-** as allocating stack space and initializing the program counter.
-** After the VDBE has be prepped, it can be executed by one or more
-** calls to sqlite3VdbeExec().
-**
-** This function may be called exact once on a each virtual machine.
-** After this routine is called the VM has been "packaged" and is ready
-** to run. After this routine is called, futher calls to
-** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects
-** the Vdbe from the Parse object that helped generate it so that the
-** the Vdbe becomes an independent entity and the Parse object can be
-** destroyed.
-**
-** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back
-** to its initial state after it has been run.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMakeReady(
- Vdbe *p, /* The VDBE */
- Parse *pParse /* Parsing context */
-){
- sqlite3 *db; /* The database connection */
- int nVar; /* Number of parameters */
- int nMem; /* Number of VM memory registers */
- int nCursor; /* Number of cursors required */
- int nArg; /* Number of arguments in subprograms */
- int nOnce; /* Number of OP_Once instructions */
- int n; /* Loop counter */
- u8 *zCsr; /* Memory available for allocation */
- u8 *zEnd; /* First byte past allocated memory */
- int nByte; /* How much extra memory is needed */
-
- assert( p!=0 );
- assert( p->nOp>0 );
- assert( pParse!=0 );
- assert( p->magic==VDBE_MAGIC_INIT );
- db = p->db;
- assert( db->mallocFailed==0 );
- nVar = pParse->nVar;
- nMem = pParse->nMem;
- nCursor = pParse->nTab;
- nArg = pParse->nMaxArg;
- nOnce = pParse->nOnce;
- if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */
-
- /* For each cursor required, also allocate a memory cell. Memory
- ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
- ** the vdbe program. Instead they are used to allocate space for
- ** VdbeCursor/BtCursor structures. The blob of memory associated with
- ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
- ** stores the blob of memory associated with cursor 1, etc.
- **
- ** See also: allocateCursor().
- */
- nMem += nCursor;
-
- /* Allocate space for memory registers, SQL variables, VDBE cursors and
- ** an array to marshal SQL function arguments in.
- */
- zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
- zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */
-
- resolveP2Values(p, &nArg);
- p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
- if( pParse->explain && nMem<10 ){
- nMem = 10;
- }
- memset(zCsr, 0, zEnd-zCsr);
- zCsr += (zCsr - (u8*)0)&7;
- assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
- p->expired = 0;
-
- /* Memory for registers, parameters, cursor, etc, is allocated in two
- ** passes. On the first pass, we try to reuse unused space at the
- ** end of the opcode array. If we are unable to satisfy all memory
- ** requirements by reusing the opcode array tail, then the second
- ** pass will fill in the rest using a fresh allocation.
- **
- ** This two-pass approach that reuses as much memory as possible from
- ** the leftover space at the end of the opcode array can significantly
- ** reduce the amount of memory held by a prepared statement.
- */
- do {
- nByte = 0;
- p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
- p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
- p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
- p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
- p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
- &zCsr, zEnd, &nByte);
- p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
- if( nByte ){
- p->pFree = sqlite3DbMallocZero(db, nByte);
- }
- zCsr = p->pFree;
- zEnd = &zCsr[nByte];
- }while( nByte && !db->mallocFailed );
-
- p->nCursor = (u16)nCursor;
- p->nOnceFlag = nOnce;
- if( p->aVar ){
- p->nVar = (ynVar)nVar;
- for(n=0; n<nVar; n++){
- p->aVar[n].flags = MEM_Null;
- p->aVar[n].db = db;
- }
- }
- if( p->azVar ){
- p->nzVar = pParse->nzVar;
- memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
- memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
- }
- if( p->aMem ){
- p->aMem--; /* aMem[] goes from 1..nMem */
- p->nMem = nMem; /* not from 0..nMem-1 */
- for(n=1; n<=nMem; n++){
- p->aMem[n].flags = MEM_Invalid;
- p->aMem[n].db = db;
- }
- }
- p->explain = pParse->explain;
- sqlite3VdbeRewind(p);
-}
-
-/*
-** Close a VDBE cursor and release all the resources that cursor
-** happens to hold.
-*/
-SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
- if( pCx==0 ){
- return;
- }
- sqlite3VdbeSorterClose(p->db, pCx);
- if( pCx->pBt ){
- sqlite3BtreeClose(pCx->pBt);
- /* The pCx->pCursor will be close automatically, if it exists, by
- ** the call above. */
- }else if( pCx->pCursor ){
- sqlite3BtreeCloseCursor(pCx->pCursor);
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pCx->pVtabCursor ){
- sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
- const sqlite3_module *pModule = pCx->pModule;
- p->inVtabMethod = 1;
- pModule->xClose(pVtabCursor);
- p->inVtabMethod = 0;
- }
-#endif
-}
-
-/*
-** Copy the values stored in the VdbeFrame structure to its Vdbe. This
-** is used, for example, when a trigger sub-program is halted to restore
-** control to the main program.
-*/
-SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
- Vdbe *v = pFrame->v;
- v->aOnceFlag = pFrame->aOnceFlag;
- v->nOnceFlag = pFrame->nOnceFlag;
- v->aOp = pFrame->aOp;
- v->nOp = pFrame->nOp;
- v->aMem = pFrame->aMem;
- v->nMem = pFrame->nMem;
- v->apCsr = pFrame->apCsr;
- v->nCursor = pFrame->nCursor;
- v->db->lastRowid = pFrame->lastRowid;
- v->nChange = pFrame->nChange;
- return pFrame->pc;
-}
-
-/*
-** Close all cursors.
-**
-** Also release any dynamic memory held by the VM in the Vdbe.aMem memory
-** cell array. This is necessary as the memory cell array may contain
-** pointers to VdbeFrame objects, which may in turn contain pointers to
-** open cursors.
-*/
-static void closeAllCursors(Vdbe *p){
- if( p->pFrame ){
- VdbeFrame *pFrame;
- for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
- sqlite3VdbeFrameRestore(pFrame);
- }
- p->pFrame = 0;
- p->nFrame = 0;
-
- if( p->apCsr ){
- int i;
- for(i=0; i<p->nCursor; i++){
- VdbeCursor *pC = p->apCsr[i];
- if( pC ){
- sqlite3VdbeFreeCursor(p, pC);
- p->apCsr[i] = 0;
- }
- }
- }
- if( p->aMem ){
- releaseMemArray(&p->aMem[1], p->nMem);
- }
- while( p->pDelFrame ){
- VdbeFrame *pDel = p->pDelFrame;
- p->pDelFrame = pDel->pParent;
- sqlite3VdbeFrameDelete(pDel);
- }
-}
-
-/*
-** Clean up the VM after execution.
-**
-** This routine will automatically close any cursors, lists, and/or
-** sorters that were left open. It also deletes the values of
-** variables in the aVar[] array.
-*/
-static void Cleanup(Vdbe *p){
- sqlite3 *db = p->db;
-
-#ifdef SQLITE_DEBUG
- /* Execute assert() statements to ensure that the Vdbe.apCsr[] and
- ** Vdbe.aMem[] arrays have already been cleaned up. */
- int i;
- if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
- if( p->aMem ){
- for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Invalid );
- }
-#endif
-
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- p->pResultSet = 0;
-}
-
-/*
-** Set the number of result columns that will be returned by this SQL
-** statement. This is now set at compile time, rather than during
-** execution of the vdbe program so that sqlite3_column_count() can
-** be called on an SQL statement before sqlite3_step().
-*/
-SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
- Mem *pColName;
- int n;
- sqlite3 *db = p->db;
-
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
- sqlite3DbFree(db, p->aColName);
- n = nResColumn*COLNAME_N;
- p->nResColumn = (u16)nResColumn;
- p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
- if( p->aColName==0 ) return;
- while( n-- > 0 ){
- pColName->flags = MEM_Null;
- pColName->db = p->db;
- pColName++;
- }
-}
-
-/*
-** Set the name of the idx'th column to be returned by the SQL statement.
-** zName must be a pointer to a nul terminated string.
-**
-** This call must be made after a call to sqlite3VdbeSetNumCols().
-**
-** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC
-** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed
-** to by zName will be freed by sqlite3DbFree() when the vdbe is destroyed.
-*/
-SQLITE_PRIVATE int sqlite3VdbeSetColName(
- Vdbe *p, /* Vdbe being configured */
- int idx, /* Index of column zName applies to */
- int var, /* One of the COLNAME_* constants */
- const char *zName, /* Pointer to buffer containing name */
- void (*xDel)(void*) /* Memory management strategy for zName */
-){
- int rc;
- Mem *pColName;
- assert( idx<p->nResColumn );
- assert( var<COLNAME_N );
- if( p->db->mallocFailed ){
- assert( !zName || xDel!=SQLITE_DYNAMIC );
- return SQLITE_NOMEM;
- }
- assert( p->aColName!=0 );
- pColName = &(p->aColName[idx+var*p->nResColumn]);
- rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel);
- assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 );
- return rc;
-}
-
-/*
-** A read or write transaction may or may not be active on database handle
-** db. If a transaction is active, commit it. If there is a
-** write-transaction spanning more than one database file, this routine
-** takes care of the master journal trickery.
-*/
-static int vdbeCommit(sqlite3 *db, Vdbe *p){
- int i;
- int nTrans = 0; /* Number of databases with an active write-transaction */
- int rc = SQLITE_OK;
- int needXcommit = 0;
-
-#ifdef SQLITE_OMIT_VIRTUALTABLE
- /* With this option, sqlite3VtabSync() is defined to be simply
- ** SQLITE_OK so p is not used.
- */
- UNUSED_PARAMETER(p);
-#endif
-
- /* Before doing anything else, call the xSync() callback for any
- ** virtual module tables written in this transaction. This has to
- ** be done before determining whether a master journal file is
- ** required, as an xSync() callback may add an attached database
- ** to the transaction.
- */
- rc = sqlite3VtabSync(db, &p->zErrMsg);
-
- /* This loop determines (a) if the commit hook should be invoked and
- ** (b) how many database files have open write transactions, not
- ** including the temp database. (b) is important because if more than
- ** one database file has an open write transaction, a master journal
- ** file is required for an atomic commit.
- */
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( sqlite3BtreeIsInTrans(pBt) ){
- needXcommit = 1;
- if( i!=1 ) nTrans++;
- sqlite3BtreeEnter(pBt);
- rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
- sqlite3BtreeLeave(pBt);
- }
- }
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* If there are any write-transactions at all, invoke the commit hook */
- if( needXcommit && db->xCommitCallback ){
- rc = db->xCommitCallback(db->pCommitArg);
- if( rc ){
- return SQLITE_CONSTRAINT;
- }
- }
-
- /* The simple case - no more than one database file (not counting the
- ** TEMP database) has a transaction active. There is no need for the
- ** master-journal.
- **
- ** If the return value of sqlite3BtreeGetFilename() is a zero length
- ** string, it means the main database is :memory: or a temp file. In
- ** that case we do not support atomic multi-file commits, so use the
- ** simple case then too.
- */
- if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt))
- || nTrans<=1
- ){
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- rc = sqlite3BtreeCommitPhaseOne(pBt, 0);
- }
- }
-
- /* Do the commit only if all databases successfully complete phase 1.
- ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an
- ** IO error while deleting or truncating a journal file. It is unlikely,
- ** but could happen. In this case abandon processing and return the error.
- */
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- rc = sqlite3BtreeCommitPhaseTwo(pBt, 0);
- }
- }
- if( rc==SQLITE_OK ){
- sqlite3VtabCommit(db);
- }
- }
-
- /* The complex case - There is a multi-file write-transaction active.
- ** This requires a master journal file to ensure the transaction is
- ** committed atomicly.
- */
-#ifndef SQLITE_OMIT_DISKIO
- else{
- sqlite3_vfs *pVfs = db->pVfs;
- int needSync = 0;
- char *zMaster = 0; /* File-name for the master journal */
- char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
- sqlite3_file *pMaster = 0;
- i64 offset = 0;
- int res;
- int retryCount = 0;
- int nMainFile;
-
- /* Select a master journal file name */
- nMainFile = sqlite3Strlen30(zMainFile);
- zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile);
- if( zMaster==0 ) return SQLITE_NOMEM;
- do {
- u32 iRandom;
- if( retryCount ){
- if( retryCount>100 ){
- sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster);
- sqlite3OsDelete(pVfs, zMaster, 0);
- break;
- }else if( retryCount==1 ){
- sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster);
- }
- }
- retryCount++;
- sqlite3_randomness(sizeof(iRandom), &iRandom);
- sqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X",
- (iRandom>>8)&0xffffff, iRandom&0xff);
- /* The antipenultimate character of the master journal name must
- ** be "9" to avoid name collisions when using 8+3 filenames. */
- assert( zMaster[sqlite3Strlen30(zMaster)-3]=='9' );
- sqlite3FileSuffix3(zMainFile, zMaster);
- rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
- }while( rc==SQLITE_OK && res );
- if( rc==SQLITE_OK ){
- /* Open the master journal. */
- rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster,
- SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
- SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
- );
- }
- if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, zMaster);
- return rc;
- }
-
- /* Write the name of each database file in the transaction into the new
- ** master journal file. If an error occurs at this point close
- ** and delete the master journal file. All the individual journal files
- ** still have 'null' as the master journal pointer, so they will roll
- ** back independently if a failure occurs.
- */
- for(i=0; i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( sqlite3BtreeIsInTrans(pBt) ){
- char const *zFile = sqlite3BtreeGetJournalname(pBt);
- if( zFile==0 ){
- continue; /* Ignore TEMP and :memory: databases */
- }
- assert( zFile[0]!=0 );
- if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
- needSync = 1;
- }
- rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
- offset += sqlite3Strlen30(zFile)+1;
- if( rc!=SQLITE_OK ){
- sqlite3OsCloseFree(pMaster);
- sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3DbFree(db, zMaster);
- return rc;
- }
- }
- }
-
- /* Sync the master journal file. If the IOCAP_SEQUENTIAL device
- ** flag is set this is not required.
- */
- if( needSync
- && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
- && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
- ){
- sqlite3OsCloseFree(pMaster);
- sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3DbFree(db, zMaster);
- return rc;
- }
-
- /* Sync all the db files involved in the transaction. The same call
- ** sets the master journal pointer in each individual journal. If
- ** an error occurs here, do not delete the master journal file.
- **
- ** If the error occurs during the first call to
- ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the
- ** master journal file will be orphaned. But we cannot delete it,
- ** in case the master journal file name was written into the journal
- ** file before the failure occurred.
- */
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
- }
- }
- sqlite3OsCloseFree(pMaster);
- assert( rc!=SQLITE_BUSY );
- if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, zMaster);
- return rc;
- }
-
- /* Delete the master journal file. This commits the transaction. After
- ** doing this the directory is synced again before any individual
- ** transaction files are deleted.
- */
- rc = sqlite3OsDelete(pVfs, zMaster, 1);
- sqlite3DbFree(db, zMaster);
- zMaster = 0;
- if( rc ){
- return rc;
- }
-
- /* All files and directories have already been synced, so the following
- ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
- ** deleting or truncating journals. If something goes wrong while
- ** this is happening we don't really care. The integrity of the
- ** transaction is already guaranteed, but some stray 'cold' journals
- ** may be lying around. Returning an error code won't help matters.
- */
- disable_simulated_io_errors();
- sqlite3BeginBenignMalloc();
- for(i=0; i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- sqlite3BtreeCommitPhaseTwo(pBt, 1);
- }
- }
- sqlite3EndBenignMalloc();
- enable_simulated_io_errors();
-
- sqlite3VtabCommit(db);
- }
-#endif
-
- return rc;
-}
-
-/*
-** This routine checks that the sqlite3.activeVdbeCnt count variable
-** matches the number of vdbe's in the list sqlite3.pVdbe that are
-** currently active. An assertion fails if the two counts do not match.
-** This is an internal self-check only - it is not an essential processing
-** step.
-**
-** This is a no-op if NDEBUG is defined.
-*/
-#ifndef NDEBUG
-static void checkActiveVdbeCnt(sqlite3 *db){
- Vdbe *p;
- int cnt = 0;
- int nWrite = 0;
- p = db->pVdbe;
- while( p ){
- if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
- cnt++;
- if( p->readOnly==0 ) nWrite++;
- }
- p = p->pNext;
- }
- assert( cnt==db->activeVdbeCnt );
- assert( nWrite==db->writeVdbeCnt );
-}
-#else
-#define checkActiveVdbeCnt(x)
-#endif
-
-/*
-** If the Vdbe passed as the first argument opened a statement-transaction,
-** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
-** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement
-** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the
-** statement transaction is commtted.
-**
-** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned.
-** Otherwise SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
- sqlite3 *const db = p->db;
- int rc = SQLITE_OK;
-
- /* If p->iStatement is greater than zero, then this Vdbe opened a
- ** statement transaction that should be closed here. The only exception
- ** is that an IO error may have occured, causing an emergency rollback.
- ** In this case (db->nStatement==0), and there is nothing to do.
- */
- if( db->nStatement && p->iStatement ){
- int i;
- const int iSavepoint = p->iStatement-1;
-
- assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
- assert( db->nStatement>0 );
- assert( p->iStatement==(db->nStatement+db->nSavepoint) );
-
- for(i=0; i<db->nDb; i++){
- int rc2 = SQLITE_OK;
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- if( eOp==SAVEPOINT_ROLLBACK ){
- rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
- }
- if( rc2==SQLITE_OK ){
- rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
- }
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
- db->nStatement--;
- p->iStatement = 0;
-
- if( rc==SQLITE_OK ){
- if( eOp==SAVEPOINT_ROLLBACK ){
- rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint);
- }
- }
-
- /* If the statement transaction is being rolled back, also restore the
- ** database handles deferred constraint counter to the value it had when
- ** the statement transaction was opened. */
- if( eOp==SAVEPOINT_ROLLBACK ){
- db->nDeferredCons = p->nStmtDefCons;
- }
- }
- return rc;
-}
-
-/*
-** This function is called when a transaction opened by the database
-** handle associated with the VM passed as an argument is about to be
-** committed. If there are outstanding deferred foreign key constraint
-** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK.
-**
-** If there are outstanding FK violations and this function returns
-** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write
-** an error message to it. Then return SQLITE_ERROR.
-*/
-#ifndef SQLITE_OMIT_FOREIGN_KEY
-SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
- sqlite3 *db = p->db;
- if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
- p->rc = SQLITE_CONSTRAINT;
- p->errorAction = OE_Abort;
- sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
- return SQLITE_ERROR;
- }
- return SQLITE_OK;
-}
-#endif
-
-/*
-** This routine is called the when a VDBE tries to halt. If the VDBE
-** has made changes and is in autocommit mode, then commit those
-** changes. If a rollback is needed, then do the rollback.
-**
-** This routine is the only way to move the state of a VM from
-** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT. It is harmless to
-** call this on a VM that is in the SQLITE_MAGIC_HALT state.
-**
-** Return an error code. If the commit could not complete because of
-** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it
-** means the close did not happen and needs to be repeated.
-*/
-SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
- int rc; /* Used to store transient return codes */
- sqlite3 *db = p->db;
-
- /* This function contains the logic that determines if a statement or
- ** transaction will be committed or rolled back as a result of the
- ** execution of this virtual machine.
- **
- ** If any of the following errors occur:
- **
- ** SQLITE_NOMEM
- ** SQLITE_IOERR
- ** SQLITE_FULL
- ** SQLITE_INTERRUPT
- **
- ** Then the internal cache might have been left in an inconsistent
- ** state. We need to rollback the statement transaction, if there is
- ** one, or the complete transaction if there is no statement transaction.
- */
-
- if( p->db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
- }
- if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
- closeAllCursors(p);
- if( p->magic!=VDBE_MAGIC_RUN ){
- return SQLITE_OK;
- }
- checkActiveVdbeCnt(db);
-
- /* No commit or rollback needed if the program never started */
- if( p->pc>=0 ){
- int mrc; /* Primary error code from p->rc */
- int eStatementOp = 0;
- int isSpecialError; /* Set to true if a 'special' error */
-
- /* Lock all btrees used by the statement */
- sqlite3VdbeEnter(p);
-
- /* Check for one of the special errors */
- mrc = p->rc & 0xff;
- assert( p->rc!=SQLITE_IOERR_BLOCKED ); /* This error no longer exists */
- isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
- || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
- if( isSpecialError ){
- /* If the query was read-only and the error code is SQLITE_INTERRUPT,
- ** no rollback is necessary. Otherwise, at least a savepoint
- ** transaction must be rolled back to restore the database to a
- ** consistent state.
- **
- ** Even if the statement is read-only, it is important to perform
- ** a statement or transaction rollback operation. If the error
- ** occured while writing to the journal, sub-journal or database
- ** file as part of an effort to free up cache space (see function
- ** pagerStress() in pager.c), the rollback is required to restore
- ** the pager to a consistent state.
- */
- if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){
- if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){
- eStatementOp = SAVEPOINT_ROLLBACK;
- }else{
- /* We are forced to roll back the active transaction. Before doing
- ** so, abort any other statements this handle currently has active.
- */
- sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
- sqlite3CloseSavepoints(db);
- db->autoCommit = 1;
- }
- }
- }
-
- /* Check for immediate foreign key violations. */
- if( p->rc==SQLITE_OK ){
- sqlite3VdbeCheckFk(p, 0);
- }
-
- /* If the auto-commit flag is set and this is the only active writer
- ** VM, then we do either a commit or rollback of the current transaction.
- **
- ** Note: This block also runs if one of the special errors handled
- ** above has occurred.
- */
- if( !sqlite3VtabInSync(db)
- && db->autoCommit
- && db->writeVdbeCnt==(p->readOnly==0)
- ){
- if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
- rc = sqlite3VdbeCheckFk(p, 1);
- if( rc!=SQLITE_OK ){
- if( NEVER(p->readOnly) ){
- sqlite3VdbeLeave(p);
- return SQLITE_ERROR;
- }
- rc = SQLITE_CONSTRAINT;
- }else{
- /* The auto-commit flag is true, the vdbe program was successful
- ** or hit an 'OR FAIL' constraint and there are no deferred foreign
- ** key constraints to hold up the transaction. This means a commit
- ** is required. */
- rc = vdbeCommit(db, p);
- }
- if( rc==SQLITE_BUSY && p->readOnly ){
- sqlite3VdbeLeave(p);
- return SQLITE_BUSY;
- }else if( rc!=SQLITE_OK ){
- p->rc = rc;
- sqlite3RollbackAll(db, SQLITE_OK);
- }else{
- db->nDeferredCons = 0;
- sqlite3CommitInternalChanges(db);
- }
- }else{
- sqlite3RollbackAll(db, SQLITE_OK);
- }
- db->nStatement = 0;
- }else if( eStatementOp==0 ){
- if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
- eStatementOp = SAVEPOINT_RELEASE;
- }else if( p->errorAction==OE_Abort ){
- eStatementOp = SAVEPOINT_ROLLBACK;
- }else{
- sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
- sqlite3CloseSavepoints(db);
- db->autoCommit = 1;
- }
- }
-
- /* If eStatementOp is non-zero, then a statement transaction needs to
- ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to
- ** do so. If this operation returns an error, and the current statement
- ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the
- ** current statement error code.
- */
- if( eStatementOp ){
- rc = sqlite3VdbeCloseStatement(p, eStatementOp);
- if( rc ){
- if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){
- p->rc = rc;
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- }
- sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
- sqlite3CloseSavepoints(db);
- db->autoCommit = 1;
- }
- }
-
- /* If this was an INSERT, UPDATE or DELETE and no statement transaction
- ** has been rolled back, update the database connection change-counter.
- */
- if( p->changeCntOn ){
- if( eStatementOp!=SAVEPOINT_ROLLBACK ){
- sqlite3VdbeSetChanges(db, p->nChange);
- }else{
- sqlite3VdbeSetChanges(db, 0);
- }
- p->nChange = 0;
- }
-
- /* Release the locks */
- sqlite3VdbeLeave(p);
- }
-
- /* We have successfully halted and closed the VM. Record this fact. */
- if( p->pc>=0 ){
- db->activeVdbeCnt--;
- if( !p->readOnly ){
- db->writeVdbeCnt--;
- }
- assert( db->activeVdbeCnt>=db->writeVdbeCnt );
- }
- p->magic = VDBE_MAGIC_HALT;
- checkActiveVdbeCnt(db);
- if( p->db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
- }
-
- /* If the auto-commit flag is set to true, then any locks that were held
- ** by connection db have now been released. Call sqlite3ConnectionUnlocked()
- ** to invoke any required unlock-notify callbacks.
- */
- if( db->autoCommit ){
- sqlite3ConnectionUnlocked(db);
- }
-
- assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 );
- return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
-}
-
-
-/*
-** Each VDBE holds the result of the most recent sqlite3_step() call
-** in p->rc. This routine sets that result back to SQLITE_OK.
-*/
-SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe *p){
- p->rc = SQLITE_OK;
-}
-
-/*
-** Copy the error code and error message belonging to the VDBE passed
-** as the first argument to its database handle (so that they will be
-** returned by calls to sqlite3_errcode() and sqlite3_errmsg()).
-**
-** This function does not clear the VDBE error code or message, just
-** copies them to the database handle.
-*/
-SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){
- sqlite3 *db = p->db;
- int rc = p->rc;
- if( p->zErrMsg ){
- u8 mallocFailed = db->mallocFailed;
- sqlite3BeginBenignMalloc();
- sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
- sqlite3EndBenignMalloc();
- db->mallocFailed = mallocFailed;
- db->errCode = rc;
- }else{
- sqlite3Error(db, rc, 0);
- }
- return rc;
-}
-
-#ifdef SQLITE_ENABLE_SQLLOG
-/*
-** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run,
-** invoke it.
-*/
-static void vdbeInvokeSqllog(Vdbe *v){
- if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){
- char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql);
- assert( v->db->init.busy==0 );
- if( zExpanded ){
- sqlite3GlobalConfig.xSqllog(
- sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1
- );
- sqlite3DbFree(v->db, zExpanded);
- }
- }
-}
-#else
-# define vdbeInvokeSqllog(x)
-#endif
-
-/*
-** Clean up a VDBE after execution but do not delete the VDBE just yet.
-** Write any error messages into *pzErrMsg. Return the result code.
-**
-** After this routine is run, the VDBE should be ready to be executed
-** again.
-**
-** To look at it another way, this routine resets the state of the
-** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
-** VDBE_MAGIC_INIT.
-*/
-SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
- sqlite3 *db;
- db = p->db;
-
- /* If the VM did not run to completion or if it encountered an
- ** error, then it might not have been halted properly. So halt
- ** it now.
- */
- sqlite3VdbeHalt(p);
-
- /* If the VDBE has be run even partially, then transfer the error code
- ** and error message from the VDBE into the main database structure. But
- ** if the VDBE has just been set to run but has not actually executed any
- ** instructions yet, leave the main database error information unchanged.
- */
- if( p->pc>=0 ){
- vdbeInvokeSqllog(p);
- sqlite3VdbeTransferError(p);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- if( p->runOnlyOnce ) p->expired = 1;
- }else if( p->rc && p->expired ){
- /* The expired flag was set on the VDBE before the first call
- ** to sqlite3_step(). For consistency (since sqlite3_step() was
- ** called), set the database error in this case as well.
- */
- sqlite3Error(db, p->rc, 0);
- sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- }
-
- /* Reclaim all memory used by the VDBE
- */
- Cleanup(p);
-
- /* Save profiling information from this VDBE run.
- */
-#ifdef VDBE_PROFILE
- {
- FILE *out = fopen("vdbe_profile.out", "a");
- if( out ){
- int i;
- fprintf(out, "---- ");
- for(i=0; i<p->nOp; i++){
- fprintf(out, "%02x", p->aOp[i].opcode);
- }
- fprintf(out, "\n");
- for(i=0; i<p->nOp; i++){
- fprintf(out, "%6d %10lld %8lld ",
- p->aOp[i].cnt,
- p->aOp[i].cycles,
- p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
- );
- sqlite3VdbePrintOp(out, i, &p->aOp[i]);
- }
- fclose(out);
- }
- }
-#endif
- p->magic = VDBE_MAGIC_INIT;
- return p->rc & db->errMask;
-}
-
-/*
-** Clean up and delete a VDBE after execution. Return an integer which is
-** the result code. Write any error message text into *pzErrMsg.
-*/
-SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
- int rc = SQLITE_OK;
- if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
- rc = sqlite3VdbeReset(p);
- assert( (rc & p->db->errMask)==rc );
- }
- sqlite3VdbeDelete(p);
- return rc;
-}
-
-/*
-** Call the destructor for each auxdata entry in pVdbeFunc for which
-** the corresponding bit in mask is clear. Auxdata entries beyond 31
-** are always destroyed. To destroy all auxdata entries, call this
-** routine with mask==0.
-*/
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
- int i;
- for(i=0; i<pVdbeFunc->nAux; i++){
- struct AuxData *pAux = &pVdbeFunc->apAux[i];
- if( (i>31 || !(mask&(((u32)1)<<i))) && pAux->pAux ){
- if( pAux->xDelete ){
- pAux->xDelete(pAux->pAux);
- }
- pAux->pAux = 0;
- }
- }
-}
-
-/*
-** Free all memory associated with the Vdbe passed as the second argument,
-** except for object itself, which is preserved.
-**
-** The difference between this function and sqlite3VdbeDelete() is that
-** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
-** the database connection and frees the object itself.
-*/
-SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
- SubProgram *pSub, *pNext;
- int i;
- assert( p->db==0 || p->db==db );
- releaseMemArray(p->aVar, p->nVar);
- releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
- for(pSub=p->pProgram; pSub; pSub=pNext){
- pNext = pSub->pNext;
- vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
- sqlite3DbFree(db, pSub);
- }
- for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
- vdbeFreeOpArray(db, p->aOp, p->nOp);
- sqlite3DbFree(db, p->aLabel);
- sqlite3DbFree(db, p->aColName);
- sqlite3DbFree(db, p->zSql);
- sqlite3DbFree(db, p->pFree);
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
- sqlite3_free(p->zExplain);
- sqlite3DbFree(db, p->pExplain);
-#endif
-}
-
-/*
-** Delete an entire VDBE.
-*/
-SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
- sqlite3 *db;
-
- if( NEVER(p==0) ) return;
- db = p->db;
- assert( sqlite3_mutex_held(db->mutex) );
- sqlite3VdbeClearObject(db, p);
- if( p->pPrev ){
- p->pPrev->pNext = p->pNext;
- }else{
- assert( db->pVdbe==p );
- db->pVdbe = p->pNext;
- }
- if( p->pNext ){
- p->pNext->pPrev = p->pPrev;
- }
- p->magic = VDBE_MAGIC_DEAD;
- p->db = 0;
- sqlite3DbFree(db, p);
-}
-
-/*
-** Make sure the cursor p is ready to read or write the row to which it
-** was last positioned. Return an error code if an OOM fault or I/O error
-** prevents us from positioning the cursor to its correct position.
-**
-** If a MoveTo operation is pending on the given cursor, then do that
-** MoveTo now. If no move is pending, check to see if the row has been
-** deleted out from under the cursor and if it has, mark the row as
-** a NULL row.
-**
-** If the cursor is already pointing to the correct row and that row has
-** not been deleted out from under the cursor, then this routine is a no-op.
-*/
-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
- if( p->deferredMoveto ){
- int res, rc;
-#ifdef SQLITE_TEST
- extern int sqlite3_search_count;
-#endif
- assert( p->isTable );
- rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
- if( rc ) return rc;
- p->lastRowid = p->movetoTarget;
- if( res!=0 ) return SQLITE_CORRUPT_BKPT;
- p->rowidIsValid = 1;
-#ifdef SQLITE_TEST
- sqlite3_search_count++;
-#endif
- p->deferredMoveto = 0;
- p->cacheStatus = CACHE_STALE;
- }else if( ALWAYS(p->pCursor) ){
- int hasMoved;
- int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
- if( rc ) return rc;
- if( hasMoved ){
- p->cacheStatus = CACHE_STALE;
- p->nullRow = 1;
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** The following functions:
-**
-** sqlite3VdbeSerialType()
-** sqlite3VdbeSerialTypeLen()
-** sqlite3VdbeSerialLen()
-** sqlite3VdbeSerialPut()
-** sqlite3VdbeSerialGet()
-**
-** encapsulate the code that serializes values for storage in SQLite
-** data and index records. Each serialized value consists of a
-** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
-** integer, stored as a varint.
-**
-** In an SQLite index record, the serial type is stored directly before
-** the blob of data that it corresponds to. In a table record, all serial
-** types are stored at the start of the record, and the blobs of data at
-** the end. Hence these functions allow the caller to handle the
-** serial-type and data blob seperately.
-**
-** The following table describes the various storage classes for data:
-**
-** serial type bytes of data type
-** -------------- --------------- ---------------
-** 0 0 NULL
-** 1 1 signed integer
-** 2 2 signed integer
-** 3 3 signed integer
-** 4 4 signed integer
-** 5 6 signed integer
-** 6 8 signed integer
-** 7 8 IEEE float
-** 8 0 Integer constant 0
-** 9 0 Integer constant 1
-** 10,11 reserved for expansion
-** N>=12 and even (N-12)/2 BLOB
-** N>=13 and odd (N-13)/2 text
-**
-** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions
-** of SQLite will not understand those serial types.
-*/
-
-/*
-** Return the serial-type for the value stored in pMem.
-*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
- int flags = pMem->flags;
- int n;
-
- if( flags&MEM_Null ){
- return 0;
- }
- if( flags&MEM_Int ){
- /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
-# define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
- i64 i = pMem->u.i;
- u64 u;
- if( i<0 ){
- if( i<(-MAX_6BYTE) ) return 6;
- /* Previous test prevents: u = -(-9223372036854775808) */
- u = -i;
- }else{
- u = i;
- }
- if( u<=127 ){
- return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
- }
- if( u<=32767 ) return 2;
- if( u<=8388607 ) return 3;
- if( u<=2147483647 ) return 4;
- if( u<=MAX_6BYTE ) return 5;
- return 6;
- }
- if( flags&MEM_Real ){
- return 7;
- }
- assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) );
- n = pMem->n;
- if( flags & MEM_Zero ){
- n += pMem->u.nZero;
- }
- assert( n>=0 );
- return ((n*2) + 12 + ((flags&MEM_Str)!=0));
-}
-
-/*
-** Return the length of the data corresponding to the supplied serial-type.
-*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
- if( serial_type>=12 ){
- return (serial_type-12)/2;
- }else{
- static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
- return aSize[serial_type];
- }
-}
-
-/*
-** If we are on an architecture with mixed-endian floating
-** points (ex: ARM7) then swap the lower 4 bytes with the
-** upper 4 bytes. Return the result.
-**
-** For most architectures, this is a no-op.
-**
-** (later): It is reported to me that the mixed-endian problem
-** on ARM7 is an issue with GCC, not with the ARM7 chip. It seems
-** that early versions of GCC stored the two words of a 64-bit
-** float in the wrong order. And that error has been propagated
-** ever since. The blame is not necessarily with GCC, though.
-** GCC might have just copying the problem from a prior compiler.
-** I am also told that newer versions of GCC that follow a different
-** ABI get the byte order right.
-**
-** Developers using SQLite on an ARM7 should compile and run their
-** application using -DSQLITE_DEBUG=1 at least once. With DEBUG
-** enabled, some asserts below will ensure that the byte order of
-** floating point values is correct.
-**
-** (2007-08-30) Frank van Vugt has studied this problem closely
-** and has send his findings to the SQLite developers. Frank
-** writes that some Linux kernels offer floating point hardware
-** emulation that uses only 32-bit mantissas instead of a full
-** 48-bits as required by the IEEE standard. (This is the
-** CONFIG_FPE_FASTFPE option.) On such systems, floating point
-** byte swapping becomes very complicated. To avoid problems,
-** the necessary byte swapping is carried out using a 64-bit integer
-** rather than a 64-bit float. Frank assures us that the code here
-** works for him. We, the developers, have no way to independently
-** verify this, but Frank seems to know what he is talking about
-** so we trust him.
-*/
-#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
-static u64 floatSwap(u64 in){
- union {
- u64 r;
- u32 i[2];
- } u;
- u32 t;
-
- u.r = in;
- t = u.i[0];
- u.i[0] = u.i[1];
- u.i[1] = t;
- return u.r;
-}
-# define swapMixedEndianFloat(X) X = floatSwap(X)
-#else
-# define swapMixedEndianFloat(X)
-#endif
-
-/*
-** Write the serialized data blob for the value stored in pMem into
-** buf. It is assumed that the caller has allocated sufficient space.
-** Return the number of bytes written.
-**
-** nBuf is the amount of space left in buf[]. nBuf must always be
-** large enough to hold the entire field. Except, if the field is
-** a blob with a zero-filled tail, then buf[] might be just the right
-** size to hold everything except for the zero-filled tail. If buf[]
-** is only big enough to hold the non-zero prefix, then only write that
-** prefix into buf[]. But if buf[] is large enough to hold both the
-** prefix and the tail then write the prefix and set the tail to all
-** zeros.
-**
-** Return the number of bytes actually written into buf[]. The number
-** of bytes in the zero-filled tail is included in the return value only
-** if those bytes were zeroed in buf[].
-*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
- u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
- u32 len;
-
- /* Integer and Real */
- if( serial_type<=7 && serial_type>0 ){
- u64 v;
- u32 i;
- if( serial_type==7 ){
- assert( sizeof(v)==sizeof(pMem->r) );
- memcpy(&v, &pMem->r, sizeof(v));
- swapMixedEndianFloat(v);
- }else{
- v = pMem->u.i;
- }
- len = i = sqlite3VdbeSerialTypeLen(serial_type);
- assert( len<=(u32)nBuf );
- while( i-- ){
- buf[i] = (u8)(v&0xFF);
- v >>= 8;
- }
- return len;
- }
-
- /* String or blob */
- if( serial_type>=12 ){
- assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
- == (int)sqlite3VdbeSerialTypeLen(serial_type) );
- assert( pMem->n<=nBuf );
- len = pMem->n;
- memcpy(buf, pMem->z, len);
- if( pMem->flags & MEM_Zero ){
- len += pMem->u.nZero;
- assert( nBuf>=0 );
- if( len > (u32)nBuf ){
- len = (u32)nBuf;
- }
- memset(&buf[pMem->n], 0, len-pMem->n);
- }
- return len;
- }
-
- /* NULL or constants 0 or 1 */
- return 0;
-}
-
-/*
-** Deserialize the data blob pointed to by buf as serial type serial_type
-** and store the result in pMem. Return the number of bytes read.
-*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
- const unsigned char *buf, /* Buffer to deserialize from */
- u32 serial_type, /* Serial type to deserialize */
- Mem *pMem /* Memory cell to write value into */
-){
- switch( serial_type ){
- case 10: /* Reserved for future use */
- case 11: /* Reserved for future use */
- case 0: { /* NULL */
- pMem->flags = MEM_Null;
- break;
- }
- case 1: { /* 1-byte signed integer */
- pMem->u.i = (signed char)buf[0];
- pMem->flags = MEM_Int;
- return 1;
- }
- case 2: { /* 2-byte signed integer */
- pMem->u.i = (((signed char)buf[0])<<8) | buf[1];
- pMem->flags = MEM_Int;
- return 2;
- }
- case 3: { /* 3-byte signed integer */
- pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
- pMem->flags = MEM_Int;
- return 3;
- }
- case 4: { /* 4-byte signed integer */
- pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
- pMem->flags = MEM_Int;
- return 4;
- }
- case 5: { /* 6-byte signed integer */
- u64 x = (((signed char)buf[0])<<8) | buf[1];
- u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
- x = (x<<32) | y;
- pMem->u.i = *(i64*)&x;
- pMem->flags = MEM_Int;
- return 6;
- }
- case 6: /* 8-byte signed integer */
- case 7: { /* IEEE floating point */
- u64 x;
- u32 y;
-#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
- /* Verify that integers and floating point values use the same
- ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
- ** defined that 64-bit floating point values really are mixed
- ** endian.
- */
- static const u64 t1 = ((u64)0x3ff00000)<<32;
- static const double r1 = 1.0;
- u64 t2 = t1;
- swapMixedEndianFloat(t2);
- assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
-#endif
-
- x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
- y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
- x = (x<<32) | y;
- if( serial_type==6 ){
- pMem->u.i = *(i64*)&x;
- pMem->flags = MEM_Int;
- }else{
- assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
- swapMixedEndianFloat(x);
- memcpy(&pMem->r, &x, sizeof(x));
- pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
- }
- return 8;
- }
- case 8: /* Integer 0 */
- case 9: { /* Integer 1 */
- pMem->u.i = serial_type-8;
- pMem->flags = MEM_Int;
- return 0;
- }
- default: {
- u32 len = (serial_type-12)/2;
- pMem->z = (char *)buf;
- pMem->n = len;
- pMem->xDel = 0;
- if( serial_type&0x01 ){
- pMem->flags = MEM_Str | MEM_Ephem;
- }else{
- pMem->flags = MEM_Blob | MEM_Ephem;
- }
- return len;
- }
- }
- return 0;
-}
-
-/*
-** This routine is used to allocate sufficient space for an UnpackedRecord
-** structure large enough to be used with sqlite3VdbeRecordUnpack() if
-** the first argument is a pointer to KeyInfo structure pKeyInfo.
-**
-** The space is either allocated using sqlite3DbMallocRaw() or from within
-** the unaligned buffer passed via the second and third arguments (presumably
-** stack space). If the former, then *ppFree is set to a pointer that should
-** be eventually freed by the caller using sqlite3DbFree(). Or, if the
-** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL
-** before returning.
-**
-** If an OOM error occurs, NULL is returned.
-*/
-SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
- KeyInfo *pKeyInfo, /* Description of the record */
- char *pSpace, /* Unaligned space available */
- int szSpace, /* Size of pSpace[] in bytes */
- char **ppFree /* OUT: Caller should free this pointer */
-){
- UnpackedRecord *p; /* Unpacked record to return */
- int nOff; /* Increment pSpace by nOff to align it */
- int nByte; /* Number of bytes required for *p */
-
- /* We want to shift the pointer pSpace up such that it is 8-byte aligned.
- ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift
- ** it by. If pSpace is already 8-byte aligned, nOff should be zero.
- */
- nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7;
- nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
- if( nByte>szSpace+nOff ){
- p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
- *ppFree = (char *)p;
- if( !p ) return 0;
- }else{
- p = (UnpackedRecord*)&pSpace[nOff];
- *ppFree = 0;
- }
-
- p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
- assert( pKeyInfo->aSortOrder!=0 );
- p->pKeyInfo = pKeyInfo;
- p->nField = pKeyInfo->nField + 1;
- return p;
-}
-
-/*
-** Given the nKey-byte encoding of a record in pKey[], populate the
-** UnpackedRecord structure indicated by the fourth argument with the
-** contents of the decoded record.
-*/
-SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
- KeyInfo *pKeyInfo, /* Information about the record format */
- int nKey, /* Size of the binary record */
- const void *pKey, /* The binary record */
- UnpackedRecord *p /* Populate this structure before returning. */
-){
- const unsigned char *aKey = (const unsigned char *)pKey;
- int d;
- u32 idx; /* Offset in aKey[] to read from */
- u16 u; /* Unsigned loop counter */
- u32 szHdr;
- Mem *pMem = p->aMem;
-
- p->flags = 0;
- assert( EIGHT_BYTE_ALIGNMENT(pMem) );
- idx = getVarint32(aKey, szHdr);
- d = szHdr;
- u = 0;
- while( idx<szHdr && u<p->nField && d<=nKey ){
- u32 serial_type;
-
- idx += getVarint32(&aKey[idx], serial_type);
- pMem->enc = pKeyInfo->enc;
- pMem->db = pKeyInfo->db;
- /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
- pMem->zMalloc = 0;
- d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
- pMem++;
- u++;
- }
- assert( u<=pKeyInfo->nField + 1 );
- p->nField = u;
-}
-
-/*
-** This function compares the two table rows or index records
-** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero
-** or positive integer if key1 is less than, equal to or
-** greater than key2. The {nKey1, pKey1} key must be a blob
-** created by th OP_MakeRecord opcode of the VDBE. The pPKey2
-** key must be a parsed key such as obtained from
-** sqlite3VdbeParseRecord.
-**
-** Key1 and Key2 do not have to contain the same number of fields.
-** The key with fewer fields is usually compares less than the
-** longer key. However if the UNPACKED_INCRKEY flags in pPKey2 is set
-** and the common prefixes are equal, then key1 is less than key2.
-** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are
-** equal, then the keys are considered to be equal and
-** the parts beyond the common prefix are ignored.
-*/
-SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
- int nKey1, const void *pKey1, /* Left key */
- UnpackedRecord *pPKey2 /* Right key */
-){
- int d1; /* Offset into aKey[] of next data element */
- u32 idx1; /* Offset into aKey[] of next header element */
- u32 szHdr1; /* Number of bytes in header */
- int i = 0;
- int nField;
- int rc = 0;
- const unsigned char *aKey1 = (const unsigned char *)pKey1;
- KeyInfo *pKeyInfo;
- Mem mem1;
-
- pKeyInfo = pPKey2->pKeyInfo;
- mem1.enc = pKeyInfo->enc;
- mem1.db = pKeyInfo->db;
- /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */
- VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
-
- /* Compilers may complain that mem1.u.i is potentially uninitialized.
- ** We could initialize it, as shown here, to silence those complaints.
- ** But in fact, mem1.u.i will never actually be used uninitialized, and doing
- ** the unnecessary initialization has a measurable negative performance
- ** impact, since this routine is a very high runner. And so, we choose
- ** to ignore the compiler warnings and leave this variable uninitialized.
- */
- /* mem1.u.i = 0; // not needed, here to silence compiler warning */
-
- idx1 = getVarint32(aKey1, szHdr1);
- d1 = szHdr1;
- nField = pKeyInfo->nField;
- assert( pKeyInfo->aSortOrder!=0 );
- while( idx1<szHdr1 && i<pPKey2->nField ){
- u32 serial_type1;
-
- /* Read the serial types for the next element in each key. */
- idx1 += getVarint32( aKey1+idx1, serial_type1 );
- if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
-
- /* Extract the values to be compared.
- */
- d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
-
- /* Do the comparison
- */
- rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
- i<nField ? pKeyInfo->aColl[i] : 0);
- if( rc!=0 ){
- assert( mem1.zMalloc==0 ); /* See comment below */
-
- /* Invert the result if we are using DESC sort order. */
- if( i<nField && pKeyInfo->aSortOrder[i] ){
- rc = -rc;
- }
-
- /* If the PREFIX_SEARCH flag is set and all fields except the final
- ** rowid field were equal, then clear the PREFIX_SEARCH flag and set
- ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
- ** This is used by the OP_IsUnique opcode.
- */
- if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){
- assert( idx1==szHdr1 && rc );
- assert( mem1.flags & MEM_Int );
- pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH;
- pPKey2->rowid = mem1.u.i;
- }
-
- return rc;
- }
- i++;
- }
-
- /* No memory allocation is ever used on mem1. Prove this using
- ** the following assert(). If the assert() fails, it indicates a
- ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).
- */
- assert( mem1.zMalloc==0 );
-
- /* rc==0 here means that one of the keys ran out of fields and
- ** all the fields up to that point were equal. If the UNPACKED_INCRKEY
- ** flag is set, then break the tie by treating key2 as larger.
- ** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes
- ** are considered to be equal. Otherwise, the longer key is the
- ** larger. As it happens, the pPKey2 will always be the longer
- ** if there is a difference.
- */
- assert( rc==0 );
- if( pPKey2->flags & UNPACKED_INCRKEY ){
- rc = -1;
- }else if( pPKey2->flags & UNPACKED_PREFIX_MATCH ){
- /* Leave rc==0 */
- }else if( idx1<szHdr1 ){
- rc = 1;
- }
- return rc;
-}
-
-
-/*
-** pCur points at an index entry created using the OP_MakeRecord opcode.
-** Read the rowid (the last field in the record) and store it in *rowid.
-** Return SQLITE_OK if everything works, or an error code otherwise.
-**
-** pCur might be pointing to text obtained from a corrupt database file.
-** So the content cannot be trusted. Do appropriate checks on the content.
-*/
-SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
- i64 nCellKey = 0;
- int rc;
- u32 szHdr; /* Size of the header */
- u32 typeRowid; /* Serial type of the rowid */
- u32 lenRowid; /* Size of the rowid */
- Mem m, v;
-
- UNUSED_PARAMETER(db);
-
- /* Get the size of the index entry. Only indices entries of less
- ** than 2GiB are support - anything large must be database corruption.
- ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
- ** this code can safely assume that nCellKey is 32-bits
- */
- assert( sqlite3BtreeCursorIsValid(pCur) );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
- assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
- assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
-
- /* Read in the complete content of the index entry */
- memset(&m, 0, sizeof(m));
- rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m);
- if( rc ){
- return rc;
- }
-
- /* The index entry must begin with a header size */
- (void)getVarint32((u8*)m.z, szHdr);
- testcase( szHdr==3 );
- testcase( szHdr==m.n );
- if( unlikely(szHdr<3 || (int)szHdr>m.n) ){
- goto idx_rowid_corruption;
- }
-
- /* The last field of the index should be an integer - the ROWID.
- ** Verify that the last entry really is an integer. */
- (void)getVarint32((u8*)&m.z[szHdr-1], typeRowid);
- testcase( typeRowid==1 );
- testcase( typeRowid==2 );
- testcase( typeRowid==3 );
- testcase( typeRowid==4 );
- testcase( typeRowid==5 );
- testcase( typeRowid==6 );
- testcase( typeRowid==8 );
- testcase( typeRowid==9 );
- if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){
- goto idx_rowid_corruption;
- }
- lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
- testcase( (u32)m.n==szHdr+lenRowid );
- if( unlikely((u32)m.n<szHdr+lenRowid) ){
- goto idx_rowid_corruption;
- }
-
- /* Fetch the integer off the end of the index record */
- sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
- *rowid = v.u.i;
- sqlite3VdbeMemRelease(&m);
- return SQLITE_OK;
-
- /* Jump here if database corruption is detected after m has been
- ** allocated. Free the m object and return SQLITE_CORRUPT. */
-idx_rowid_corruption:
- testcase( m.zMalloc!=0 );
- sqlite3VdbeMemRelease(&m);
- return SQLITE_CORRUPT_BKPT;
-}
-
-/*
-** Compare the key of the index entry that cursor pC is pointing to against
-** the key string in pUnpacked. Write into *pRes a number
-** that is negative, zero, or positive if pC is less than, equal to,
-** or greater than pUnpacked. Return SQLITE_OK on success.
-**
-** pUnpacked is either created without a rowid or is truncated so that it
-** omits the rowid at the end. The rowid at the end of the index entry
-** is ignored as well. Hence, this routine only compares the prefixes
-** of the keys prior to the final rowid, not the entire key.
-*/
-SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
- VdbeCursor *pC, /* The cursor to compare against */
- UnpackedRecord *pUnpacked, /* Unpacked version of key to compare against */
- int *res /* Write the comparison result here */
-){
- i64 nCellKey = 0;
- int rc;
- BtCursor *pCur = pC->pCursor;
- Mem m;
-
- assert( sqlite3BtreeCursorIsValid(pCur) );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
- assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
- /* nCellKey will always be between 0 and 0xffffffff because of the say
- ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
- if( nCellKey<=0 || nCellKey>0x7fffffff ){
- *res = 0;
- return SQLITE_CORRUPT_BKPT;
- }
- memset(&m, 0, sizeof(m));
- rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
- if( rc ){
- return rc;
- }
- assert( pUnpacked->flags & UNPACKED_PREFIX_MATCH );
- *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
- sqlite3VdbeMemRelease(&m);
- return SQLITE_OK;
-}
-
-/*
-** This routine sets the value to be returned by subsequent calls to
-** sqlite3_changes() on the database handle 'db'.
-*/
-SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){
- assert( sqlite3_mutex_held(db->mutex) );
- db->nChange = nChange;
- db->nTotalChange += nChange;
-}
-
-/*
-** Set a flag in the vdbe to update the change counter when it is finalised
-** or reset.
-*/
-SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){
- v->changeCntOn = 1;
-}
-
-/*
-** Mark every prepared statement associated with a database connection
-** as expired.
-**
-** An expired statement means that recompilation of the statement is
-** recommend. Statements expire when things happen that make their
-** programs obsolete. Removing user-defined functions or collating
-** sequences, or changing an authorization function are the types of
-** things that make prepared statements obsolete.
-*/
-SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db){
- Vdbe *p;
- for(p = db->pVdbe; p; p=p->pNext){
- p->expired = 1;
- }
-}
-
-/*
-** Return the database associated with the Vdbe.
-*/
-SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){
- return v->db;
-}
-
-/*
-** Return a pointer to an sqlite3_value structure containing the value bound
-** parameter iVar of VM v. Except, if the value is an SQL NULL, return
-** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
-** constants) to the value before returning it.
-**
-** The returned value must be freed by the caller using sqlite3ValueFree().
-*/
-SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){
- assert( iVar>0 );
- if( v ){
- Mem *pMem = &v->aVar[iVar-1];
- if( 0==(pMem->flags & MEM_Null) ){
- sqlite3_value *pRet = sqlite3ValueNew(v->db);
- if( pRet ){
- sqlite3VdbeMemCopy((Mem *)pRet, pMem);
- sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8);
- sqlite3VdbeMemStoreType((Mem *)pRet);
- }
- return pRet;
- }
- }
- return 0;
-}
-
-/*
-** Configure SQL variable iVar so that binding a new value to it signals
-** to sqlite3_reoptimize() that re-preparing the statement may result
-** in a better query plan.
-*/
-SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
- assert( iVar>0 );
- if( iVar>32 ){
- v->expmask = 0xffffffff;
- }else{
- v->expmask |= ((u32)1 << (iVar-1));
- }
-}
-
-/************** End of vdbeaux.c *********************************************/
-/************** Begin file vdbeapi.c *****************************************/
-/*
-** 2004 May 26
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains code use to implement APIs that are part of the
-** VDBE.
-*/
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** Return TRUE (non-zero) of the statement supplied as an argument needs
-** to be recompiled. A statement needs to be recompiled whenever the
-** execution environment changes in a way that would alter the program
-** that sqlite3_prepare() generates. For example, if new functions or
-** collating sequences are registered or if an authorizer function is
-** added or changed.
-*/
-SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){
- Vdbe *p = (Vdbe*)pStmt;
- return p==0 || p->expired;
-}
-#endif
-
-/*
-** Check on a Vdbe to make sure it has not been finalized. Log
-** an error and return true if it has been finalized (or is otherwise
-** invalid). Return false if it is ok.
-*/
-static int vdbeSafety(Vdbe *p){
- if( p->db==0 ){
- sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement");
- return 1;
- }else{
- return 0;
- }
-}
-static int vdbeSafetyNotNull(Vdbe *p){
- if( p==0 ){
- sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement");
- return 1;
- }else{
- return vdbeSafety(p);
- }
-}
-
-/*
-** The following routine destroys a virtual machine that is created by
-** the sqlite3_compile() routine. The integer returned is an SQLITE_
-** success/failure code that describes the result of executing the virtual
-** machine.
-**
-** This routine sets the error code and string returned by
-** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
-*/
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
- int rc;
- if( pStmt==0 ){
- /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
- ** pointer is a harmless no-op. */
- rc = SQLITE_OK;
- }else{
- Vdbe *v = (Vdbe*)pStmt;
- sqlite3 *db = v->db;
- if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
- sqlite3_mutex_enter(db->mutex);
- rc = sqlite3VdbeFinalize(v);
- rc = sqlite3ApiExit(db, rc);
- sqlite3LeaveMutexAndCloseZombie(db);
- }
- return rc;
-}
-
-/*
-** Terminate the current execution of an SQL statement and reset it
-** back to its starting state so that it can be reused. A success code from
-** the prior execution is returned.
-**
-** This routine sets the error code and string returned by
-** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
-*/
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
- int rc;
- if( pStmt==0 ){
- rc = SQLITE_OK;
- }else{
- Vdbe *v = (Vdbe*)pStmt;
- sqlite3_mutex_enter(v->db->mutex);
- rc = sqlite3VdbeReset(v);
- sqlite3VdbeRewind(v);
- assert( (rc & (v->db->errMask))==rc );
- rc = sqlite3ApiExit(v->db, rc);
- sqlite3_mutex_leave(v->db->mutex);
- }
- return rc;
-}
-
-/*
-** Set all the parameters in the compiled SQL statement to NULL.
-*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
- int i;
- int rc = SQLITE_OK;
- Vdbe *p = (Vdbe*)pStmt;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex;
-#endif
- sqlite3_mutex_enter(mutex);
- for(i=0; i<p->nVar; i++){
- sqlite3VdbeMemRelease(&p->aVar[i]);
- p->aVar[i].flags = MEM_Null;
- }
- if( p->isPrepareV2 && p->expmask ){
- p->expired = 1;
- }
- sqlite3_mutex_leave(mutex);
- return rc;
-}
-
-
-/**************************** sqlite3_value_ *******************************
-** The following routines extract information from a Mem or sqlite3_value
-** structure.
-*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
- Mem *p = (Mem*)pVal;
- if( p->flags & (MEM_Blob|MEM_Str) ){
- sqlite3VdbeMemExpandBlob(p);
- p->flags &= ~MEM_Str;
- p->flags |= MEM_Blob;
- return p->n ? p->z : 0;
- }else{
- return sqlite3_value_text(pVal);
- }
-}
-SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){
- return sqlite3ValueBytes(pVal, SQLITE_UTF8);
-}
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){
- return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
-}
-SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
- return sqlite3VdbeRealValue((Mem*)pVal);
-}
-SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
- return (int)sqlite3VdbeIntValue((Mem*)pVal);
-}
-SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
- return sqlite3VdbeIntValue((Mem*)pVal);
-}
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
- return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){
- return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
-}
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){
- return sqlite3ValueText(pVal, SQLITE_UTF16BE);
-}
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
- return sqlite3ValueText(pVal, SQLITE_UTF16LE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
- return pVal->type;
-}
-
-/**************************** sqlite3_result_ *******************************
-** The following routines are used by user-defined functions to specify
-** the function result.
-**
-** The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the
-** result as a string or blob but if the string or blob is too large, it
-** then sets the error code to SQLITE_TOOBIG
-*/
-static void setResultStrOrError(
- sqlite3_context *pCtx, /* Function context */
- const char *z, /* String pointer */
- int n, /* Bytes in string, or negative */
- u8 enc, /* Encoding of z. 0 for BLOBs */
- void (*xDel)(void*) /* Destructor function */
-){
- if( sqlite3VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){
- sqlite3_result_error_toobig(pCtx);
- }
-}
-SQLITE_API void sqlite3_result_blob(
- sqlite3_context *pCtx,
- const void *z,
- int n,
- void (*xDel)(void *)
-){
- assert( n>=0 );
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, 0, xDel);
-}
-SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
-}
-SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pCtx->isError = SQLITE_ERROR;
- sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pCtx->isError = SQLITE_ERROR;
- sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
-}
-#endif
-SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
-}
-SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
-}
-SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetNull(&pCtx->s);
-}
-SQLITE_API void sqlite3_result_text(
- sqlite3_context *pCtx,
- const char *z,
- int n,
- void (*xDel)(void *)
-){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void sqlite3_result_text16(
- sqlite3_context *pCtx,
- const void *z,
- int n,
- void (*xDel)(void *)
-){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
-}
-SQLITE_API void sqlite3_result_text16be(
- sqlite3_context *pCtx,
- const void *z,
- int n,
- void (*xDel)(void *)
-){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
-}
-SQLITE_API void sqlite3_result_text16le(
- sqlite3_context *pCtx,
- const void *z,
- int n,
- void (*xDel)(void *)
-){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemCopy(&pCtx->s, pValue);
-}
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
-}
-SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
- pCtx->isError = errCode;
- if( pCtx->s.flags & MEM_Null ){
- sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1,
- SQLITE_UTF8, SQLITE_STATIC);
- }
-}
-
-/* Force an SQLITE_TOOBIG error. */
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pCtx->isError = SQLITE_TOOBIG;
- sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1,
- SQLITE_UTF8, SQLITE_STATIC);
-}
-
-/* An SQLITE_NOMEM error. */
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- sqlite3VdbeMemSetNull(&pCtx->s);
- pCtx->isError = SQLITE_NOMEM;
- pCtx->s.db->mallocFailed = 1;
-}
-
-/*
-** This function is called after a transaction has been committed. It
-** invokes callbacks registered with sqlite3_wal_hook() as required.
-*/
-static int doWalCallbacks(sqlite3 *db){
- int rc = SQLITE_OK;
-#ifndef SQLITE_OMIT_WAL
- int i;
- for(i=0; i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- int nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
- if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
- rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
- }
- }
- }
-#endif
- return rc;
-}
-
-/*
-** Execute the statement pStmt, either until a row of data is ready, the
-** statement is completely executed or an error occurs.
-**
-** This routine implements the bulk of the logic behind the sqlite_step()
-** API. The only thing omitted is the automatic recompile if a
-** schema change has occurred. That detail is handled by the
-** outer sqlite3_step() wrapper procedure.
-*/
-static int sqlite3Step(Vdbe *p){
- sqlite3 *db;
- int rc;
-
- assert(p);
- if( p->magic!=VDBE_MAGIC_RUN ){
- /* We used to require that sqlite3_reset() be called before retrying
- ** sqlite3_step() after any error or after SQLITE_DONE. But beginning
- ** with version 3.7.0, we changed this so that sqlite3_reset() would
- ** be called automatically instead of throwing the SQLITE_MISUSE error.
- ** This "automatic-reset" change is not technically an incompatibility,
- ** since any application that receives an SQLITE_MISUSE is broken by
- ** definition.
- **
- ** Nevertheless, some published applications that were originally written
- ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
- ** returns, and those were broken by the automatic-reset change. As a
- ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
- ** legacy behavior of returning SQLITE_MISUSE for cases where the
- ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
- ** or SQLITE_BUSY error.
- */
-#ifdef SQLITE_OMIT_AUTORESET
- if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
- sqlite3_reset((sqlite3_stmt*)p);
- }else{
- return SQLITE_MISUSE_BKPT;
- }
-#else
- sqlite3_reset((sqlite3_stmt*)p);
-#endif
- }
-
- /* Check that malloc() has not failed. If it has, return early. */
- db = p->db;
- if( db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
- return SQLITE_NOMEM;
- }
-
- if( p->pc<=0 && p->expired ){
- p->rc = SQLITE_SCHEMA;
- rc = SQLITE_ERROR;
- goto end_of_step;
- }
- if( p->pc<0 ){
- /* If there are no other statements currently running, then
- ** reset the interrupt flag. This prevents a call to sqlite3_interrupt
- ** from interrupting a statement that has not yet started.
- */
- if( db->activeVdbeCnt==0 ){
- db->u1.isInterrupted = 0;
- }
-
- assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 );
-
-#ifndef SQLITE_OMIT_TRACE
- if( db->xProfile && !db->init.busy ){
- sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
- }
-#endif
-
- db->activeVdbeCnt++;
- if( p->readOnly==0 ) db->writeVdbeCnt++;
- p->pc = 0;
- }
-#ifndef SQLITE_OMIT_EXPLAIN
- if( p->explain ){
- rc = sqlite3VdbeList(p);
- }else
-#endif /* SQLITE_OMIT_EXPLAIN */
- {
- db->vdbeExecCnt++;
- rc = sqlite3VdbeExec(p);
- db->vdbeExecCnt--;
- }
-
-#ifndef SQLITE_OMIT_TRACE
- /* Invoke the profile callback if there is one
- */
- if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy && p->zSql ){
- sqlite3_int64 iNow;
- sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
- db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000);
- }
-#endif
-
- if( rc==SQLITE_DONE ){
- assert( p->rc==SQLITE_OK );
- p->rc = doWalCallbacks(db);
- if( p->rc!=SQLITE_OK ){
- rc = SQLITE_ERROR;
- }
- }
-
- db->errCode = rc;
- if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
- p->rc = SQLITE_NOMEM;
- }
-end_of_step:
- /* At this point local variable rc holds the value that should be
- ** returned if this statement was compiled using the legacy
- ** sqlite3_prepare() interface. According to the docs, this can only
- ** be one of the values in the first assert() below. Variable p->rc
- ** contains the value that would be returned if sqlite3_finalize()
- ** were called on statement p.
- */
- assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR
- || rc==SQLITE_BUSY || rc==SQLITE_MISUSE
- );
- assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
- if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
- /* If this statement was prepared using sqlite3_prepare_v2(), and an
- ** error has occured, then return the error code in p->rc to the
- ** caller. Set the error code in the database handle to the same value.
- */
- rc = sqlite3VdbeTransferError(p);
- }
- return (rc&db->errMask);
-}
-
-/*
-** The maximum number of times that a statement will try to reparse
-** itself before giving up and returning SQLITE_SCHEMA.
-*/
-#ifndef SQLITE_MAX_SCHEMA_RETRY
-# define SQLITE_MAX_SCHEMA_RETRY 5
-#endif
-
-/*
-** This is the top-level implementation of sqlite3_step(). Call
-** sqlite3Step() to do most of the work. If a schema error occurs,
-** call sqlite3Reprepare() and try again.
-*/
-SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
- int rc = SQLITE_OK; /* Result from sqlite3Step() */
- int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */
- Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */
- int cnt = 0; /* Counter to prevent infinite loop of reprepares */
- sqlite3 *db; /* The database connection */
-
- if( vdbeSafetyNotNull(v) ){
- return SQLITE_MISUSE_BKPT;
- }
- db = v->db;
- sqlite3_mutex_enter(db->mutex);
- v->doingRerun = 0;
- while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
- && cnt++ < SQLITE_MAX_SCHEMA_RETRY
- && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){
- sqlite3_reset(pStmt);
- v->doingRerun = 1;
- assert( v->expired==0 );
- }
- if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
- /* This case occurs after failing to recompile an sql statement.
- ** The error message from the SQL compiler has already been loaded
- ** into the database handle. This block copies the error message
- ** from the database handle into the statement and sets the statement
- ** program counter to 0 to ensure that when the statement is
- ** finalized or reset the parser error message is available via
- ** sqlite3_errmsg() and sqlite3_errcode().
- */
- const char *zErr = (const char *)sqlite3_value_text(db->pErr);
- sqlite3DbFree(db, v->zErrMsg);
- if( !db->mallocFailed ){
- v->zErrMsg = sqlite3DbStrDup(db, zErr);
- v->rc = rc2;
- } else {
- v->zErrMsg = 0;
- v->rc = rc = SQLITE_NOMEM;
- }
- }
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Extract the user data from a sqlite3_context structure and return a
-** pointer to it.
-*/
-SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
- assert( p && p->pFunc );
- return p->pFunc->pUserData;
-}
-
-/*
-** Extract the user data from a sqlite3_context structure and return a
-** pointer to it.
-**
-** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface
-** returns a copy of the pointer to the database connection (the 1st
-** parameter) of the sqlite3_create_function() and
-** sqlite3_create_function16() routines that originally registered the
-** application defined function.
-*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
- assert( p && p->pFunc );
- return p->s.db;
-}
-
-/*
-** The following is the implementation of an SQL function that always
-** fails with an error message stating that the function is used in the
-** wrong context. The sqlite3_overload_function() API might construct
-** SQL function that use this routine so that the functions will exist
-** for name resolution but are actually overloaded by the xFindFunction
-** method of virtual tables.
-*/
-SQLITE_PRIVATE void sqlite3InvalidFunction(
- sqlite3_context *context, /* The function calling context */
- int NotUsed, /* Number of arguments to the function */
- sqlite3_value **NotUsed2 /* Value of each argument */
-){
- const char *zName = context->pFunc->zName;
- char *zErr;
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- zErr = sqlite3_mprintf(
- "unable to use function %s in the requested context", zName);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
-}
-
-/*
-** Allocate or return the aggregate context for a user function. A new
-** context is allocated on the first call. Subsequent calls return the
-** same context that was returned on prior calls.
-*/
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
- Mem *pMem;
- assert( p && p->pFunc && p->pFunc->xStep );
- assert( sqlite3_mutex_held(p->s.db->mutex) );
- pMem = p->pMem;
- testcase( nByte<0 );
- if( (pMem->flags & MEM_Agg)==0 ){
- if( nByte<=0 ){
- sqlite3VdbeMemReleaseExternal(pMem);
- pMem->flags = MEM_Null;
- pMem->z = 0;
- }else{
- sqlite3VdbeMemGrow(pMem, nByte, 0);
- pMem->flags = MEM_Agg;
- pMem->u.pDef = p->pFunc;
- if( pMem->z ){
- memset(pMem->z, 0, nByte);
- }
- }
- }
- return (void*)pMem->z;
-}
-
-/*
-** Return the auxilary data pointer, if any, for the iArg'th argument to
-** the user-function defined by pCtx.
-*/
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
- VdbeFunc *pVdbeFunc;
-
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pVdbeFunc = pCtx->pVdbeFunc;
- if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
- return 0;
- }
- return pVdbeFunc->apAux[iArg].pAux;
-}
-
-/*
-** Set the auxilary data pointer and delete function, for the iArg'th
-** argument to the user-function defined by pCtx. Any previous value is
-** deleted by calling the delete function specified when it was set.
-*/
-SQLITE_API void sqlite3_set_auxdata(
- sqlite3_context *pCtx,
- int iArg,
- void *pAux,
- void (*xDelete)(void*)
-){
- struct AuxData *pAuxData;
- VdbeFunc *pVdbeFunc;
- if( iArg<0 ) goto failed;
-
- assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pVdbeFunc = pCtx->pVdbeFunc;
- if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
- int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
- int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
- pVdbeFunc = sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc);
- if( !pVdbeFunc ){
- goto failed;
- }
- pCtx->pVdbeFunc = pVdbeFunc;
- memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux));
- pVdbeFunc->nAux = iArg+1;
- pVdbeFunc->pFunc = pCtx->pFunc;
- }
-
- pAuxData = &pVdbeFunc->apAux[iArg];
- if( pAuxData->pAux && pAuxData->xDelete ){
- pAuxData->xDelete(pAuxData->pAux);
- }
- pAuxData->pAux = pAux;
- pAuxData->xDelete = xDelete;
- return;
-
-failed:
- if( xDelete ){
- xDelete(pAux);
- }
-}
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** Return the number of times the Step function of a aggregate has been
-** called.
-**
-** This function is deprecated. Do not use it for new code. It is
-** provide only to avoid breaking legacy code. New aggregate function
-** implementations should keep their own counts within their aggregate
-** context.
-*/
-SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
- assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
- return p->pMem->n;
-}
-#endif
-
-/*
-** Return the number of columns in the result set for the statement pStmt.
-*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
- Vdbe *pVm = (Vdbe *)pStmt;
- return pVm ? pVm->nResColumn : 0;
-}
-
-/*
-** Return the number of values available from the current row of the
-** currently executing statement pStmt.
-*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
- Vdbe *pVm = (Vdbe *)pStmt;
- if( pVm==0 || pVm->pResultSet==0 ) return 0;
- return pVm->nResColumn;
-}
-
-
-/*
-** Check to see if column iCol of the given statement is valid. If
-** it is, return a pointer to the Mem for the value of that column.
-** If iCol is not valid, return a pointer to a Mem which has a value
-** of NULL.
-*/
-static Mem *columnMem(sqlite3_stmt *pStmt, int i){
- Vdbe *pVm;
- Mem *pOut;
-
- pVm = (Vdbe *)pStmt;
- if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
- sqlite3_mutex_enter(pVm->db->mutex);
- pOut = &pVm->pResultSet[i];
- }else{
- /* If the value passed as the second argument is out of range, return
- ** a pointer to the following static Mem object which contains the
- ** value SQL NULL. Even though the Mem structure contains an element
- ** of type i64, on certain architectures (x86) with certain compiler
- ** switches (-Os), gcc may align this Mem object on a 4-byte boundary
- ** instead of an 8-byte one. This all works fine, except that when
- ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
- ** that a Mem structure is located on an 8-byte boundary. To prevent
- ** these assert()s from failing, when building with SQLITE_DEBUG defined
- ** using gcc, we force nullMem to be 8-byte aligned using the magical
- ** __attribute__((aligned(8))) macro. */
- static const Mem nullMem
-#if defined(SQLITE_DEBUG) && defined(__GNUC__)
- __attribute__((aligned(8)))
-#endif
- = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0,
-#ifdef SQLITE_DEBUG
- 0, 0, /* pScopyFrom, pFiller */
-#endif
- 0, 0 };
-
- if( pVm && ALWAYS(pVm->db) ){
- sqlite3_mutex_enter(pVm->db->mutex);
- sqlite3Error(pVm->db, SQLITE_RANGE, 0);
- }
- pOut = (Mem*)&nullMem;
- }
- return pOut;
-}
-
-/*
-** This function is called after invoking an sqlite3_value_XXX function on a
-** column value (i.e. a value returned by evaluating an SQL expression in the
-** select list of a SELECT statement) that may cause a malloc() failure. If
-** malloc() has failed, the threads mallocFailed flag is cleared and the result
-** code of statement pStmt set to SQLITE_NOMEM.
-**
-** Specifically, this is called from within:
-**
-** sqlite3_column_int()
-** sqlite3_column_int64()
-** sqlite3_column_text()
-** sqlite3_column_text16()
-** sqlite3_column_real()
-** sqlite3_column_bytes()
-** sqlite3_column_bytes16()
-** sqiite3_column_blob()
-*/
-static void columnMallocFailure(sqlite3_stmt *pStmt)
-{
- /* If malloc() failed during an encoding conversion within an
- ** sqlite3_column_XXX API, then set the return code of the statement to
- ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
- ** and _finalize() will return NOMEM.
- */
- Vdbe *p = (Vdbe *)pStmt;
- if( p ){
- p->rc = sqlite3ApiExit(p->db, p->rc);
- sqlite3_mutex_leave(p->db->mutex);
- }
-}
-
-/**************************** sqlite3_column_ *******************************
-** The following routines are used to access elements of the current row
-** in the result set.
-*/
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
- const void *val;
- val = sqlite3_value_blob( columnMem(pStmt,i) );
- /* Even though there is no encoding conversion, value_blob() might
- ** need to call malloc() to expand the result of a zeroblob()
- ** expression.
- */
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
- int val = sqlite3_value_bytes( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
- int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
- double val = sqlite3_value_double( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
- int val = sqlite3_value_int( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
- sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
- const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
- Mem *pOut = columnMem(pStmt, i);
- if( pOut->flags&MEM_Static ){
- pOut->flags &= ~MEM_Static;
- pOut->flags |= MEM_Ephem;
- }
- columnMallocFailure(pStmt);
- return (sqlite3_value *)pOut;
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
- const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return val;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
- int iType = sqlite3_value_type( columnMem(pStmt,i) );
- columnMallocFailure(pStmt);
- return iType;
-}
-
-/* The following function is experimental and subject to change or
-** removal */
-/*int sqlite3_column_numeric_type(sqlite3_stmt *pStmt, int i){
-** return sqlite3_value_numeric_type( columnMem(pStmt,i) );
-**}
-*/
-
-/*
-** Convert the N-th element of pStmt->pColName[] into a string using
-** xFunc() then return that string. If N is out of range, return 0.
-**
-** There are up to 5 names for each column. useType determines which
-** name is returned. Here are the names:
-**
-** 0 The column name as it should be displayed for output
-** 1 The datatype name for the column
-** 2 The name of the database that the column derives from
-** 3 The name of the table that the column derives from
-** 4 The name of the table column that the result column derives from
-**
-** If the result is not a simple column reference (if it is an expression
-** or a constant) then useTypes 2, 3, and 4 return NULL.
-*/
-static const void *columnName(
- sqlite3_stmt *pStmt,
- int N,
- const void *(*xFunc)(Mem*),
- int useType
-){
- const void *ret = 0;
- Vdbe *p = (Vdbe *)pStmt;
- int n;
- sqlite3 *db = p->db;
-
- assert( db!=0 );
- n = sqlite3_column_count(pStmt);
- if( N<n && N>=0 ){
- N += useType*n;
- sqlite3_mutex_enter(db->mutex);
- assert( db->mallocFailed==0 );
- ret = xFunc(&p->aColName[N]);
- /* A malloc may have failed inside of the xFunc() call. If this
- ** is the case, clear the mallocFailed flag and return NULL.
- */
- if( db->mallocFailed ){
- db->mallocFailed = 0;
- ret = 0;
- }
- sqlite3_mutex_leave(db->mutex);
- }
- return ret;
-}
-
-/*
-** Return the name of the Nth column of the result set returned by SQL
-** statement pStmt.
-*/
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
-}
-#endif
-
-/*
-** Constraint: If you have ENABLE_COLUMN_METADATA then you must
-** not define OMIT_DECLTYPE.
-*/
-#if defined(SQLITE_OMIT_DECLTYPE) && defined(SQLITE_ENABLE_COLUMN_METADATA)
-# error "Must not define both SQLITE_OMIT_DECLTYPE \
- and SQLITE_ENABLE_COLUMN_METADATA"
-#endif
-
-#ifndef SQLITE_OMIT_DECLTYPE
-/*
-** Return the column declaration type (if applicable) of the 'i'th column
-** of the result set of SQL statement pStmt.
-*/
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-#endif /* SQLITE_OMIT_DECLTYPE */
-
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
-/*
-** Return the name of the database from which a result column derives.
-** NULL is returned if the result column is an expression or constant or
-** anything else which is not an unabiguous reference to a database column.
-*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Return the name of the table from which a result column derives.
-** NULL is returned if the result column is an expression or constant or
-** anything else which is not an unabiguous reference to a database column.
-*/
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Return the name of the table column from which a result column derives.
-** NULL is returned if the result column is an expression or constant or
-** anything else which is not an unabiguous reference to a database column.
-*/
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
- return columnName(
- pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-#endif /* SQLITE_ENABLE_COLUMN_METADATA */
-
-
-/******************************* sqlite3_bind_ ***************************
-**
-** Routines used to attach values to wildcards in a compiled SQL statement.
-*/
-/*
-** Unbind the value bound to variable i in virtual machine p. This is the
-** the same as binding a NULL value to the column. If the "i" parameter is
-** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
-**
-** A successful evaluation of this routine acquires the mutex on p.
-** the mutex is released if any kind of error occurs.
-**
-** The error code stored in database p->db is overwritten with the return
-** value in any case.
-*/
-static int vdbeUnbind(Vdbe *p, int i){
- Mem *pVar;
- if( vdbeSafetyNotNull(p) ){
- return SQLITE_MISUSE_BKPT;
- }
- sqlite3_mutex_enter(p->db->mutex);
- if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
- sqlite3Error(p->db, SQLITE_MISUSE, 0);
- sqlite3_mutex_leave(p->db->mutex);
- sqlite3_log(SQLITE_MISUSE,
- "bind on a busy prepared statement: [%s]", p->zSql);
- return SQLITE_MISUSE_BKPT;
- }
- if( i<1 || i>p->nVar ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
- sqlite3_mutex_leave(p->db->mutex);
- return SQLITE_RANGE;
- }
- i--;
- pVar = &p->aVar[i];
- sqlite3VdbeMemRelease(pVar);
- pVar->flags = MEM_Null;
- sqlite3Error(p->db, SQLITE_OK, 0);
-
- /* If the bit corresponding to this variable in Vdbe.expmask is set, then
- ** binding a new value to this variable invalidates the current query plan.
- **
- ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host
- ** parameter in the WHERE clause might influence the choice of query plan
- ** for a statement, then the statement will be automatically recompiled,
- ** as if there had been a schema change, on the first sqlite3_step() call
- ** following any change to the bindings of that parameter.
- */
- if( p->isPrepareV2 &&
- ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
- ){
- p->expired = 1;
- }
- return SQLITE_OK;
-}
-
-/*
-** Bind a text or BLOB value.
-*/
-static int bindText(
- sqlite3_stmt *pStmt, /* The statement to bind against */
- int i, /* Index of the parameter to bind */
- const void *zData, /* Pointer to the data to be bound */
- int nData, /* Number of bytes of data to be bound */
- void (*xDel)(void*), /* Destructor for the data */
- u8 encoding /* Encoding for the data */
-){
- Vdbe *p = (Vdbe *)pStmt;
- Mem *pVar;
- int rc;
-
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- if( zData!=0 ){
- pVar = &p->aVar[i-1];
- rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
- if( rc==SQLITE_OK && encoding!=0 ){
- rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
- }
- sqlite3Error(p->db, rc, 0);
- rc = sqlite3ApiExit(p->db, rc);
- }
- sqlite3_mutex_leave(p->db->mutex);
- }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){
- xDel((void*)zData);
- }
- return rc;
-}
-
-
-/*
-** Bind a blob value to an SQL statement variable.
-*/
-SQLITE_API int sqlite3_bind_blob(
- sqlite3_stmt *pStmt,
- int i,
- const void *zData,
- int nData,
- void (*xDel)(void*)
-){
- return bindText(pStmt, i, zData, nData, xDel, 0);
-}
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
- int rc;
- Vdbe *p = (Vdbe *)pStmt;
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
- sqlite3_mutex_leave(p->db->mutex);
- }
- return rc;
-}
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
- return sqlite3_bind_int64(p, i, (i64)iValue);
-}
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
- int rc;
- Vdbe *p = (Vdbe *)pStmt;
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
- sqlite3_mutex_leave(p->db->mutex);
- }
- return rc;
-}
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
- int rc;
- Vdbe *p = (Vdbe*)pStmt;
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- sqlite3_mutex_leave(p->db->mutex);
- }
- return rc;
-}
-SQLITE_API int sqlite3_bind_text(
- sqlite3_stmt *pStmt,
- int i,
- const char *zData,
- int nData,
- void (*xDel)(void*)
-){
- return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
-}
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_bind_text16(
- sqlite3_stmt *pStmt,
- int i,
- const void *zData,
- int nData,
- void (*xDel)(void*)
-){
- return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
- int rc;
- switch( pValue->type ){
- case SQLITE_INTEGER: {
- rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
- break;
- }
- case SQLITE_FLOAT: {
- rc = sqlite3_bind_double(pStmt, i, pValue->r);
- break;
- }
- case SQLITE_BLOB: {
- if( pValue->flags & MEM_Zero ){
- rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero);
- }else{
- rc = sqlite3_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT);
- }
- break;
- }
- case SQLITE_TEXT: {
- rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT,
- pValue->enc);
- break;
- }
- default: {
- rc = sqlite3_bind_null(pStmt, i);
- break;
- }
- }
- return rc;
-}
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
- int rc;
- Vdbe *p = (Vdbe *)pStmt;
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
- sqlite3_mutex_leave(p->db->mutex);
- }
- return rc;
-}
-
-/*
-** Return the number of wildcards that can be potentially bound to.
-** This routine is added to support DBD::SQLite.
-*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
- Vdbe *p = (Vdbe*)pStmt;
- return p ? p->nVar : 0;
-}
-
-/*
-** Return the name of a wildcard parameter. Return NULL if the index
-** is out of range or if the wildcard is unnamed.
-**
-** The result is always UTF-8.
-*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
- Vdbe *p = (Vdbe*)pStmt;
- if( p==0 || i<1 || i>p->nzVar ){
- return 0;
- }
- return p->azVar[i-1];
-}
-
-/*
-** Given a wildcard parameter name, return the index of the variable
-** with that name. If there is no variable with the given name,
-** return 0.
-*/
-SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
- int i;
- if( p==0 ){
- return 0;
- }
- if( zName ){
- for(i=0; i<p->nzVar; i++){
- const char *z = p->azVar[i];
- if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){
- return i+1;
- }
- }
- }
- return 0;
-}
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
- return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
-}
-
-/*
-** Transfer all bindings from the first statement over to the second.
-*/
-SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
- Vdbe *pFrom = (Vdbe*)pFromStmt;
- Vdbe *pTo = (Vdbe*)pToStmt;
- int i;
- assert( pTo->db==pFrom->db );
- assert( pTo->nVar==pFrom->nVar );
- sqlite3_mutex_enter(pTo->db->mutex);
- for(i=0; i<pFrom->nVar; i++){
- sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
- }
- sqlite3_mutex_leave(pTo->db->mutex);
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** Deprecated external interface. Internal/core SQLite code
-** should call sqlite3TransferBindings.
-**
-** Is is misuse to call this routine with statements from different
-** database connections. But as this is a deprecated interface, we
-** will not bother to check for that condition.
-**
-** If the two statements contain a different number of bindings, then
-** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise
-** SQLITE_OK is returned.
-*/
-SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
- Vdbe *pFrom = (Vdbe*)pFromStmt;
- Vdbe *pTo = (Vdbe*)pToStmt;
- if( pFrom->nVar!=pTo->nVar ){
- return SQLITE_ERROR;
- }
- if( pTo->isPrepareV2 && pTo->expmask ){
- pTo->expired = 1;
- }
- if( pFrom->isPrepareV2 && pFrom->expmask ){
- pFrom->expired = 1;
- }
- return sqlite3TransferBindings(pFromStmt, pToStmt);
-}
-#endif
-
-/*
-** Return the sqlite3* database handle to which the prepared statement given
-** in the argument belongs. This is the same database handle that was
-** the first argument to the sqlite3_prepare() that was used to create
-** the statement in the first place.
-*/
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
- return pStmt ? ((Vdbe*)pStmt)->db : 0;
-}
-
-/*
-** Return true if the prepared statement is guaranteed to not modify the
-** database.
-*/
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
- return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
-}
-
-/*
-** Return true if the prepared statement is in need of being reset.
-*/
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
- Vdbe *v = (Vdbe*)pStmt;
- return v!=0 && v->pc>0 && v->magic==VDBE_MAGIC_RUN;
-}
-
-/*
-** Return a pointer to the next prepared statement after pStmt associated
-** with database connection pDb. If pStmt is NULL, return the first
-** prepared statement for the database connection. Return NULL if there
-** are no more.
-*/
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
- sqlite3_stmt *pNext;
- sqlite3_mutex_enter(pDb->mutex);
- if( pStmt==0 ){
- pNext = (sqlite3_stmt*)pDb->pVdbe;
- }else{
- pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext;
- }
- sqlite3_mutex_leave(pDb->mutex);
- return pNext;
-}
-
-/*
-** Return the value of a status counter for a prepared statement
-*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
- Vdbe *pVdbe = (Vdbe*)pStmt;
- int v = pVdbe->aCounter[op-1];
- if( resetFlag ) pVdbe->aCounter[op-1] = 0;
- return v;
-}
-
-/************** End of vdbeapi.c *********************************************/
-/************** Begin file vdbetrace.c ***************************************/
-/*
-** 2009 November 25
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains code used to insert the values of host parameters
-** (aka "wildcards") into the SQL text output by sqlite3_trace().
-**
-** The Vdbe parse-tree explainer is also found here.
-*/
-
-#ifndef SQLITE_OMIT_TRACE
-
-/*
-** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of
-** bytes in this text up to but excluding the first character in
-** a host parameter. If the text contains no host parameters, return
-** the total number of bytes in the text.
-*/
-static int findNextHostParameter(const char *zSql, int *pnToken){
- int tokenType;
- int nTotal = 0;
- int n;
-
- *pnToken = 0;
- while( zSql[0] ){
- n = sqlite3GetToken((u8*)zSql, &tokenType);
- assert( n>0 && tokenType!=TK_ILLEGAL );
- if( tokenType==TK_VARIABLE ){
- *pnToken = n;
- break;
- }
- nTotal += n;
- zSql += n;
- }
- return nTotal;
-}
-
-/*
-** This function returns a pointer to a nul-terminated string in memory
-** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the
-** string contains a copy of zRawSql but with host parameters expanded to
-** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1,
-** then the returned string holds a copy of zRawSql with "-- " prepended
-** to each line of text.
-**
-** The calling function is responsible for making sure the memory returned
-** is eventually freed.
-**
-** ALGORITHM: Scan the input string looking for host parameters in any of
-** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within
-** string literals, quoted identifier names, and comments. For text forms,
-** the host parameter index is found by scanning the perpared
-** statement for the corresponding OP_Variable opcode. Once the host
-** parameter index is known, locate the value in p->aVar[]. Then render
-** the value as a literal in place of the host parameter name.
-*/
-SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
- Vdbe *p, /* The prepared statement being evaluated */
- const char *zRawSql /* Raw text of the SQL statement */
-){
- sqlite3 *db; /* The database connection */
- int idx = 0; /* Index of a host parameter */
- int nextIndex = 1; /* Index of next ? host parameter */
- int n; /* Length of a token prefix */
- int nToken; /* Length of the parameter token */
- int i; /* Loop counter */
- Mem *pVar; /* Value of a host parameter */
- StrAccum out; /* Accumulate the output here */
- char zBase[100]; /* Initial working space */
-
- db = p->db;
- sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
- db->aLimit[SQLITE_LIMIT_LENGTH]);
- out.db = db;
- if( db->vdbeExecCnt>1 ){
- while( *zRawSql ){
- const char *zStart = zRawSql;
- while( *(zRawSql++)!='\n' && *zRawSql );
- sqlite3StrAccumAppend(&out, "-- ", 3);
- sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
- }
- }else{
- while( zRawSql[0] ){
- n = findNextHostParameter(zRawSql, &nToken);
- assert( n>0 );
- sqlite3StrAccumAppend(&out, zRawSql, n);
- zRawSql += n;
- assert( zRawSql[0] || nToken==0 );
- if( nToken==0 ) break;
- if( zRawSql[0]=='?' ){
- if( nToken>1 ){
- assert( sqlite3Isdigit(zRawSql[1]) );
- sqlite3GetInt32(&zRawSql[1], &idx);
- }else{
- idx = nextIndex;
- }
- }else{
- assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
- testcase( zRawSql[0]==':' );
- testcase( zRawSql[0]=='$' );
- testcase( zRawSql[0]=='@' );
- idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
- assert( idx>0 );
- }
- zRawSql += nToken;
- nextIndex = idx + 1;
- assert( idx>0 && idx<=p->nVar );
- pVar = &p->aVar[idx-1];
- if( pVar->flags & MEM_Null ){
- sqlite3StrAccumAppend(&out, "NULL", 4);
- }else if( pVar->flags & MEM_Int ){
- sqlite3XPrintf(&out, "%lld", pVar->u.i);
- }else if( pVar->flags & MEM_Real ){
- sqlite3XPrintf(&out, "%!.15g", pVar->r);
- }else if( pVar->flags & MEM_Str ){
-#ifndef SQLITE_OMIT_UTF16
- u8 enc = ENC(db);
- if( enc!=SQLITE_UTF8 ){
- Mem utf8;
- memset(&utf8, 0, sizeof(utf8));
- utf8.db = db;
- sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
- sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
- sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
- sqlite3VdbeMemRelease(&utf8);
- }else
-#endif
- {
- sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
- }
- }else if( pVar->flags & MEM_Zero ){
- sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
- }else{
- assert( pVar->flags & MEM_Blob );
- sqlite3StrAccumAppend(&out, "x'", 2);
- for(i=0; i<pVar->n; i++){
- sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
- }
- sqlite3StrAccumAppend(&out, "'", 1);
- }
- }
- }
- return sqlite3StrAccumFinish(&out);
-}
-
-#endif /* #ifndef SQLITE_OMIT_TRACE */
-
-/*****************************************************************************
-** The following code implements the data-structure explaining logic
-** for the Vdbe.
-*/
-
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-
-/*
-** Allocate a new Explain object
-*/
-SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
- if( pVdbe ){
- Explain *p;
- sqlite3BeginBenignMalloc();
- p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
- if( p ){
- p->pVdbe = pVdbe;
- sqlite3_free(pVdbe->pExplain);
- pVdbe->pExplain = p;
- sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
- SQLITE_MAX_LENGTH);
- p->str.useMalloc = 2;
- }else{
- sqlite3EndBenignMalloc();
- }
- }
-}
-
-/*
-** Return true if the Explain ends with a new-line.
-*/
-static int endsWithNL(Explain *p){
- return p && p->str.zText && p->str.nChar
- && p->str.zText[p->str.nChar-1]=='\n';
-}
-
-/*
-** Append text to the indentation
-*/
-SQLITE_PRIVATE void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
- Explain *p;
- if( pVdbe && (p = pVdbe->pExplain)!=0 ){
- va_list ap;
- if( p->nIndent && endsWithNL(p) ){
- int n = p->nIndent;
- if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent);
- sqlite3AppendSpace(&p->str, p->aIndent[n-1]);
- }
- va_start(ap, zFormat);
- sqlite3VXPrintf(&p->str, 1, zFormat, ap);
- va_end(ap);
- }
-}
-
-/*
-** Append a '\n' if there is not already one.
-*/
-SQLITE_PRIVATE void sqlite3ExplainNL(Vdbe *pVdbe){
- Explain *p;
- if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){
- sqlite3StrAccumAppend(&p->str, "\n", 1);
- }
-}
-
-/*
-** Push a new indentation level. Subsequent lines will be indented
-** so that they begin at the current cursor position.
-*/
-SQLITE_PRIVATE void sqlite3ExplainPush(Vdbe *pVdbe){
- Explain *p;
- if( pVdbe && (p = pVdbe->pExplain)!=0 ){
- if( p->str.zText && p->nIndent<ArraySize(p->aIndent) ){
- const char *z = p->str.zText;
- int i = p->str.nChar-1;
- int x;
- while( i>=0 && z[i]!='\n' ){ i--; }
- x = (p->str.nChar - 1) - i;
- if( p->nIndent && x<p->aIndent[p->nIndent-1] ){
- x = p->aIndent[p->nIndent-1];
- }
- p->aIndent[p->nIndent] = x;
- }
- p->nIndent++;
- }
-}
-
-/*
-** Pop the indentation stack by one level.
-*/
-SQLITE_PRIVATE void sqlite3ExplainPop(Vdbe *p){
- if( p && p->pExplain ) p->pExplain->nIndent--;
-}
-
-/*
-** Free the indentation structure
-*/
-SQLITE_PRIVATE void sqlite3ExplainFinish(Vdbe *pVdbe){
- if( pVdbe && pVdbe->pExplain ){
- sqlite3_free(pVdbe->zExplain);
- sqlite3ExplainNL(pVdbe);
- pVdbe->zExplain = sqlite3StrAccumFinish(&pVdbe->pExplain->str);
- sqlite3_free(pVdbe->pExplain);
- pVdbe->pExplain = 0;
- sqlite3EndBenignMalloc();
- }
-}
-
-/*
-** Return the explanation of a virtual machine.
-*/
-SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
- return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0;
-}
-#endif /* defined(SQLITE_DEBUG) */
-
-/************** End of vdbetrace.c *******************************************/
-/************** Begin file vdbe.c ********************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** The code in this file implements execution method of the
-** Virtual Database Engine (VDBE). A separate file ("vdbeaux.c")
-** handles housekeeping details such as creating and deleting
-** VDBE instances. This file is solely interested in executing
-** the VDBE program.
-**
-** In the external interface, an "sqlite3_stmt*" is an opaque pointer
-** to a VDBE.
-**
-** The SQL parser generates a program which is then executed by
-** the VDBE to do the work of the SQL statement. VDBE programs are
-** similar in form to assembly language. The program consists of
-** a linear sequence of operations. Each operation has an opcode
-** and 5 operands. Operands P1, P2, and P3 are integers. Operand P4
-** is a null-terminated string. Operand P5 is an unsigned character.
-** Few opcodes use all 5 operands.
-**
-** Computation results are stored on a set of registers numbered beginning
-** with 1 and going up to Vdbe.nMem. Each register can store
-** either an integer, a null-terminated string, a floating point
-** number, or the SQL "NULL" value. An implicit conversion from one
-** type to the other occurs as necessary.
-**
-** Most of the code in this file is taken up by the sqlite3VdbeExec()
-** function which does the work of interpreting a VDBE program.
-** But other routines are also provided to help in building up
-** a program instruction by instruction.
-**
-** Various scripts scan this source file in order to generate HTML
-** documentation, headers files, or other derived files. The formatting
-** of the code in this file is, therefore, important. See other comments
-** in this file for details. If in doubt, do not deviate from existing
-** commenting and indentation practices when changing or adding code.
-*/
-
-/*
-** Invoke this macro on memory cells just prior to changing the
-** value of the cell. This macro verifies that shallow copies are
-** not misused.
-*/
-#ifdef SQLITE_DEBUG
-# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M)
-#else
-# define memAboutToChange(P,M)
-#endif
-
-/*
-** The following global variable is incremented every time a cursor
-** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test
-** procedures use this information to make sure that indices are
-** working correctly. This variable has no function other than to
-** help verify the correct operation of the library.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_search_count = 0;
-#endif
-
-/*
-** When this global variable is positive, it gets decremented once before
-** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted
-** field of the sqlite3 structure is set in order to simulate an interrupt.
-**
-** This facility is used for testing purposes only. It does not function
-** in an ordinary build.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_interrupt_count = 0;
-#endif
-
-/*
-** The next global variable is incremented each type the OP_Sort opcode
-** is executed. The test procedures use this information to make sure that
-** sorting is occurring or not occurring at appropriate times. This variable
-** has no function other than to help verify the correct operation of the
-** library.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_sort_count = 0;
-#endif
-
-/*
-** The next global variable records the size of the largest MEM_Blob
-** or MEM_Str that has been used by a VDBE opcode. The test procedures
-** use this information to make sure that the zero-blob functionality
-** is working correctly. This variable has no function other than to
-** help verify the correct operation of the library.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_max_blobsize = 0;
-static void updateMaxBlobsize(Mem *p){
- if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){
- sqlite3_max_blobsize = p->n;
- }
-}
-#endif
-
-/*
-** The next global variable is incremented each type the OP_Found opcode
-** is executed. This is used to test whether or not the foreign key
-** operation implemented using OP_FkIsZero is working. This variable
-** has no function other than to help verify the correct operation of the
-** library.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_found_count = 0;
-#endif
-
-/*
-** Test a register to see if it exceeds the current maximum blob size.
-** If it does, record the new maximum blob size.
-*/
-#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST)
-# define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P)
-#else
-# define UPDATE_MAX_BLOBSIZE(P)
-#endif
-
-/*
-** Convert the given register into a string if it isn't one
-** already. Return non-zero if a malloc() fails.
-*/
-#define Stringify(P, enc) \
- if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \
- { goto no_mem; }
-
-/*
-** An ephemeral string value (signified by the MEM_Ephem flag) contains
-** a pointer to a dynamically allocated string where some other entity
-** is responsible for deallocating that string. Because the register
-** does not control the string, it might be deleted without the register
-** knowing it.
-**
-** This routine converts an ephemeral string into a dynamically allocated
-** string that the register itself controls. In other words, it
-** converts an MEM_Ephem string into an MEM_Dyn string.
-*/
-#define Deephemeralize(P) \
- if( ((P)->flags&MEM_Ephem)!=0 \
- && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
-
-/* Return true if the cursor was opened using the OP_OpenSorter opcode. */
-#ifdef SQLITE_OMIT_MERGE_SORT
-# define isSorter(x) 0
-#else
-# define isSorter(x) ((x)->pSorter!=0)
-#endif
-
-/*
-** Argument pMem points at a register that will be passed to a
-** user-defined function or returned to the user as the result of a query.
-** This routine sets the pMem->type variable used by the sqlite3_value_*()
-** routines.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem){
- int flags = pMem->flags;
- if( flags & MEM_Null ){
- pMem->type = SQLITE_NULL;
- }
- else if( flags & MEM_Int ){
- pMem->type = SQLITE_INTEGER;
- }
- else if( flags & MEM_Real ){
- pMem->type = SQLITE_FLOAT;
- }
- else if( flags & MEM_Str ){
- pMem->type = SQLITE_TEXT;
- }else{
- pMem->type = SQLITE_BLOB;
- }
-}
-
-/*
-** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL
-** if we run out of memory.
-*/
-static VdbeCursor *allocateCursor(
- Vdbe *p, /* The virtual machine */
- int iCur, /* Index of the new VdbeCursor */
- int nField, /* Number of fields in the table or index */
- int iDb, /* Database the cursor belongs to, or -1 */
- int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */
-){
- /* Find the memory cell that will be used to store the blob of memory
- ** required for this VdbeCursor structure. It is convenient to use a
- ** vdbe memory cell to manage the memory allocation required for a
- ** VdbeCursor structure for the following reasons:
- **
- ** * Sometimes cursor numbers are used for a couple of different
- ** purposes in a vdbe program. The different uses might require
- ** different sized allocations. Memory cells provide growable
- ** allocations.
- **
- ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can
- ** be freed lazily via the sqlite3_release_memory() API. This
- ** minimizes the number of malloc calls made by the system.
- **
- ** Memory cells for cursors are allocated at the top of the address
- ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for
- ** cursor 1 is managed by memory cell (p->nMem-1), etc.
- */
- Mem *pMem = &p->aMem[p->nMem-iCur];
-
- int nByte;
- VdbeCursor *pCx = 0;
- nByte =
- ROUND8(sizeof(VdbeCursor)) +
- (isBtreeCursor?sqlite3BtreeCursorSize():0) +
- 2*nField*sizeof(u32);
-
- assert( iCur<p->nCursor );
- if( p->apCsr[iCur] ){
- sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
- p->apCsr[iCur] = 0;
- }
- if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){
- p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
- memset(pCx, 0, sizeof(VdbeCursor));
- pCx->iDb = iDb;
- pCx->nField = nField;
- if( nField ){
- pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))];
- }
- if( isBtreeCursor ){
- pCx->pCursor = (BtCursor*)
- &pMem->z[ROUND8(sizeof(VdbeCursor))+2*nField*sizeof(u32)];
- sqlite3BtreeCursorZero(pCx->pCursor);
- }
- }
- return pCx;
-}
-
-/*
-** Try to convert a value into a numeric representation if we can
-** do so without loss of information. In other words, if the string
-** looks like a number, convert it into a number. If it does not
-** look like a number, leave it alone.
-*/
-static void applyNumericAffinity(Mem *pRec){
- if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
- double rValue;
- i64 iValue;
- u8 enc = pRec->enc;
- if( (pRec->flags&MEM_Str)==0 ) return;
- if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
- if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
- pRec->u.i = iValue;
- pRec->flags |= MEM_Int;
- }else{
- pRec->r = rValue;
- pRec->flags |= MEM_Real;
- }
- }
-}
-
-/*
-** Processing is determine by the affinity parameter:
-**
-** SQLITE_AFF_INTEGER:
-** SQLITE_AFF_REAL:
-** SQLITE_AFF_NUMERIC:
-** Try to convert pRec to an integer representation or a
-** floating-point representation if an integer representation
-** is not possible. Note that the integer representation is
-** always preferred, even if the affinity is REAL, because
-** an integer representation is more space efficient on disk.
-**
-** SQLITE_AFF_TEXT:
-** Convert pRec to a text representation.
-**
-** SQLITE_AFF_NONE:
-** No-op. pRec is unchanged.
-*/
-static void applyAffinity(
- Mem *pRec, /* The value to apply affinity to */
- char affinity, /* The affinity to be applied */
- u8 enc /* Use this text encoding */
-){
- if( affinity==SQLITE_AFF_TEXT ){
- /* Only attempt the conversion to TEXT if there is an integer or real
- ** representation (blob and NULL do not get converted) but no string
- ** representation.
- */
- if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
- sqlite3VdbeMemStringify(pRec, enc);
- }
- pRec->flags &= ~(MEM_Real|MEM_Int);
- }else if( affinity!=SQLITE_AFF_NONE ){
- assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
- || affinity==SQLITE_AFF_NUMERIC );
- applyNumericAffinity(pRec);
- if( pRec->flags & MEM_Real ){
- sqlite3VdbeIntegerAffinity(pRec);
- }
- }
-}
-
-/*
-** Try to convert the type of a function argument or a result column
-** into a numeric representation. Use either INTEGER or REAL whichever
-** is appropriate. But only do the conversion if it is possible without
-** loss of information and return the revised type of the argument.
-*/
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
- Mem *pMem = (Mem*)pVal;
- if( pMem->type==SQLITE_TEXT ){
- applyNumericAffinity(pMem);
- sqlite3VdbeMemStoreType(pMem);
- }
- return pMem->type;
-}
-
-/*
-** Exported version of applyAffinity(). This one works on sqlite3_value*,
-** not the internal Mem* type.
-*/
-SQLITE_PRIVATE void sqlite3ValueApplyAffinity(
- sqlite3_value *pVal,
- u8 affinity,
- u8 enc
-){
- applyAffinity((Mem *)pVal, affinity, enc);
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** Write a nice string representation of the contents of cell pMem
-** into buffer zBuf, length nBuf.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
- char *zCsr = zBuf;
- int f = pMem->flags;
-
- static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};
-
- if( f&MEM_Blob ){
- int i;
- char c;
- if( f & MEM_Dyn ){
- c = 'z';
- assert( (f & (MEM_Static|MEM_Ephem))==0 );
- }else if( f & MEM_Static ){
- c = 't';
- assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
- }else if( f & MEM_Ephem ){
- c = 'e';
- assert( (f & (MEM_Static|MEM_Dyn))==0 );
- }else{
- c = 's';
- }
-
- sqlite3_snprintf(100, zCsr, "%c", c);
- zCsr += sqlite3Strlen30(zCsr);
- sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
- zCsr += sqlite3Strlen30(zCsr);
- for(i=0; i<16 && i<pMem->n; i++){
- sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF));
- zCsr += sqlite3Strlen30(zCsr);
- }
- for(i=0; i<16 && i<pMem->n; i++){
- char z = pMem->z[i];
- if( z<32 || z>126 ) *zCsr++ = '.';
- else *zCsr++ = z;
- }
-
- sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]);
- zCsr += sqlite3Strlen30(zCsr);
- if( f & MEM_Zero ){
- sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
- zCsr += sqlite3Strlen30(zCsr);
- }
- *zCsr = '\0';
- }else if( f & MEM_Str ){
- int j, k;
- zBuf[0] = ' ';
- if( f & MEM_Dyn ){
- zBuf[1] = 'z';
- assert( (f & (MEM_Static|MEM_Ephem))==0 );
- }else if( f & MEM_Static ){
- zBuf[1] = 't';
- assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
- }else if( f & MEM_Ephem ){
- zBuf[1] = 'e';
- assert( (f & (MEM_Static|MEM_Dyn))==0 );
- }else{
- zBuf[1] = 's';
- }
- k = 2;
- sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n);
- k += sqlite3Strlen30(&zBuf[k]);
- zBuf[k++] = '[';
- for(j=0; j<15 && j<pMem->n; j++){
- u8 c = pMem->z[j];
- if( c>=0x20 && c<0x7f ){
- zBuf[k++] = c;
- }else{
- zBuf[k++] = '.';
- }
- }
- zBuf[k++] = ']';
- sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]);
- k += sqlite3Strlen30(&zBuf[k]);
- zBuf[k++] = 0;
- }
-}
-#endif
-
-#ifdef SQLITE_DEBUG
-/*
-** Print the value of a register for tracing purposes:
-*/
-static void memTracePrint(FILE *out, Mem *p){
- if( p->flags & MEM_Invalid ){
- fprintf(out, " undefined");
- }else if( p->flags & MEM_Null ){
- fprintf(out, " NULL");
- }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
- fprintf(out, " si:%lld", p->u.i);
- }else if( p->flags & MEM_Int ){
- fprintf(out, " i:%lld", p->u.i);
-#ifndef SQLITE_OMIT_FLOATING_POINT
- }else if( p->flags & MEM_Real ){
- fprintf(out, " r:%g", p->r);
-#endif
- }else if( p->flags & MEM_RowSet ){
- fprintf(out, " (rowset)");
- }else{
- char zBuf[200];
- sqlite3VdbeMemPrettyPrint(p, zBuf);
- fprintf(out, " ");
- fprintf(out, "%s", zBuf);
- }
-}
-static void registerTrace(FILE *out, int iReg, Mem *p){
- fprintf(out, "REG[%d] = ", iReg);
- memTracePrint(out, p);
- fprintf(out, "\n");
-}
-#endif
-
-#ifdef SQLITE_DEBUG
-# define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M)
-#else
-# define REGISTER_TRACE(R,M)
-#endif
-
-
-#ifdef VDBE_PROFILE
-
-/*
-** hwtime.h contains inline assembler code for implementing
-** high-performance timing routines.
-*/
-/************** Include hwtime.h in the middle of vdbe.c *********************/
-/************** Begin file hwtime.h ******************************************/
-/*
-** 2008 May 27
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
-*/
-#ifndef _HWTIME_H_
-#define _HWTIME_H_
-
-/*
-** The following routine only works on pentium-class (or newer) processors.
-** It uses the RDTSC opcode to read the cycle count value out of the
-** processor and returns that value. This can be used for high-res
-** profiling.
-*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
-
- #if defined(__GNUC__)
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned int lo, hi;
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (sqlite_uint64)hi << 32 | lo;
- }
-
- #elif defined(_MSC_VER)
-
- __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
- __asm {
- rdtsc
- ret ; return value at EDX:EAX
- }
- }
-
- #endif
-
-#elif (defined(__GNUC__) && defined(__x86_64__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long val;
- __asm__ __volatile__ ("rdtsc" : "=A" (val));
- return val;
- }
-
-#elif (defined(__GNUC__) && defined(__ppc__))
-
- __inline__ sqlite_uint64 sqlite3Hwtime(void){
- unsigned long long retval;
- unsigned long junk;
- __asm__ __volatile__ ("\n\
- 1: mftbu %1\n\
- mftb %L0\n\
- mftbu %0\n\
- cmpw %0,%1\n\
- bne 1b"
- : "=r" (retval), "=r" (junk));
- return retval;
- }
-
-#else
-
- #error Need implementation of sqlite3Hwtime() for your platform.
-
- /*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
- */
-SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-
-#endif
-
-#endif /* !defined(_HWTIME_H_) */
-
-/************** End of hwtime.h **********************************************/
-/************** Continuing where we left off in vdbe.c ***********************/
-
-#endif
-
-/*
-** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
-** sqlite3_interrupt() routine has been called. If it has been, then
-** processing of the VDBE program is interrupted.
-**
-** This macro added to every instruction that does a jump in order to
-** implement a loop. This test used to be on every single instruction,
-** but that meant we more testing than we needed. By only testing the
-** flag on jump instructions, we get a (small) speed improvement.
-*/
-#define CHECK_FOR_INTERRUPT \
- if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
-
-
-#ifndef NDEBUG
-/*
-** This function is only called from within an assert() expression. It
-** checks that the sqlite3.nTransaction variable is correctly set to
-** the number of non-transaction savepoints currently in the
-** linked list starting at sqlite3.pSavepoint.
-**
-** Usage:
-**
-** assert( checkSavepointCount(db) );
-*/
-static int checkSavepointCount(sqlite3 *db){
- int n = 0;
- Savepoint *p;
- for(p=db->pSavepoint; p; p=p->pNext) n++;
- assert( n==(db->nSavepoint + db->isTransactionSavepoint) );
- return 1;
-}
-#endif
-
-/*
-** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
-** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
-** in memory obtained from sqlite3DbMalloc).
-*/
-static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){
- sqlite3 *db = p->db;
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
- sqlite3_free(pVtab->zErrMsg);
- pVtab->zErrMsg = 0;
-}
-
-
-/*
-** Execute as much of a VDBE program as we can then return.
-**
-** sqlite3VdbeMakeReady() must be called before this routine in order to
-** close the program with a final OP_Halt and to set up the callbacks
-** and the error message pointer.
-**
-** Whenever a row or result data is available, this routine will either
-** invoke the result callback (if there is one) or return with
-** SQLITE_ROW.
-**
-** If an attempt is made to open a locked database, then this routine
-** will either invoke the busy callback (if there is one) or it will
-** return SQLITE_BUSY.
-**
-** If an error occurs, an error message is written to memory obtained
-** from sqlite3_malloc() and p->zErrMsg is made to point to that memory.
-** The error code is stored in p->rc and this routine returns SQLITE_ERROR.
-**
-** If the callback ever returns non-zero, then the program exits
-** immediately. There will be no error message but the p->rc field is
-** set to SQLITE_ABORT and this routine will return SQLITE_ERROR.
-**
-** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this
-** routine to return SQLITE_ERROR.
-**
-** Other fatal errors return SQLITE_ERROR.
-**
-** After this routine has finished, sqlite3VdbeFinalize() should be
-** used to clean up the mess that was left behind.
-*/
-SQLITE_PRIVATE int sqlite3VdbeExec(
- Vdbe *p /* The VDBE */
-){
- int pc=0; /* The program counter */
- Op *aOp = p->aOp; /* Copy of p->aOp */
- Op *pOp; /* Current operation */
- int rc = SQLITE_OK; /* Value to return */
- sqlite3 *db = p->db; /* The database */
- u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
- u8 encoding = ENC(db); /* The database encoding */
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- int checkProgress; /* True if progress callbacks are enabled */
- int nProgressOps = 0; /* Opcodes executed since progress callback. */
-#endif
- Mem *aMem = p->aMem; /* Copy of p->aMem */
- Mem *pIn1 = 0; /* 1st input operand */
- Mem *pIn2 = 0; /* 2nd input operand */
- Mem *pIn3 = 0; /* 3rd input operand */
- Mem *pOut = 0; /* Output operand */
- int iCompare = 0; /* Result of last OP_Compare operation */
- int *aPermute = 0; /* Permutation of columns for OP_Compare */
- i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */
-#ifdef VDBE_PROFILE
- u64 start; /* CPU clock count at start of opcode */
- int origPc; /* Program counter at start of opcode */
-#endif
- /********************************************************************
- ** Automatically generated code
- **
- ** The following union is automatically generated by the
- ** vdbe-compress.tcl script. The purpose of this union is to
- ** reduce the amount of stack space required by this function.
- ** See comments in the vdbe-compress.tcl script for details.
- */
- union vdbeExecUnion {
- struct OP_Yield_stack_vars {
- int pcDest;
- } aa;
- struct OP_Null_stack_vars {
- int cnt;
- u16 nullFlag;
- } ab;
- struct OP_Variable_stack_vars {
- Mem *pVar; /* Value being transferred */
- } ac;
- struct OP_Move_stack_vars {
- char *zMalloc; /* Holding variable for allocated memory */
- int n; /* Number of registers left to copy */
- int p1; /* Register to copy from */
- int p2; /* Register to copy to */
- } ad;
- struct OP_Copy_stack_vars {
- int n;
- } ae;
- struct OP_ResultRow_stack_vars {
- Mem *pMem;
- int i;
- } af;
- struct OP_Concat_stack_vars {
- i64 nByte;
- } ag;
- struct OP_Remainder_stack_vars {
- char bIntint; /* Started out as two integer operands */
- int flags; /* Combined MEM_* flags from both inputs */
- i64 iA; /* Integer value of left operand */
- i64 iB; /* Integer value of right operand */
- double rA; /* Real value of left operand */
- double rB; /* Real value of right operand */
- } ah;
- struct OP_Function_stack_vars {
- int i;
- Mem *pArg;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- int n;
- } ai;
- struct OP_ShiftRight_stack_vars {
- i64 iA;
- u64 uA;
- i64 iB;
- u8 op;
- } aj;
- struct OP_Ge_stack_vars {
- int res; /* Result of the comparison of pIn1 against pIn3 */
- char affinity; /* Affinity to use for comparison */
- u16 flags1; /* Copy of initial value of pIn1->flags */
- u16 flags3; /* Copy of initial value of pIn3->flags */
- } ak;
- struct OP_Compare_stack_vars {
- int n;
- int i;
- int p1;
- int p2;
- const KeyInfo *pKeyInfo;
- int idx;
- CollSeq *pColl; /* Collating sequence to use on this term */
- int bRev; /* True for DESCENDING sort order */
- } al;
- struct OP_Or_stack_vars {
- int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- } am;
- struct OP_IfNot_stack_vars {
- int c;
- } an;
- struct OP_Column_stack_vars {
- u32 payloadSize; /* Number of bytes in the record */
- i64 payloadSize64; /* Number of bytes in the record */
- int p1; /* P1 value of the opcode */
- int p2; /* column number to retrieve */
- VdbeCursor *pC; /* The VDBE cursor */
- char *zRec; /* Pointer to complete record-data */
- BtCursor *pCrsr; /* The BTree cursor */
- u32 *aType; /* aType[i] holds the numeric type of the i-th column */
- u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
- int nField; /* number of fields in the record */
- int len; /* The length of the serialized data for the column */
- int i; /* Loop counter */
- char *zData; /* Part of the record being decoded */
- Mem *pDest; /* Where to write the extracted value */
- Mem sMem; /* For storing the record being decoded */
- u8 *zIdx; /* Index into header */
- u8 *zEndHdr; /* Pointer to first byte after the header */
- u32 offset; /* Offset into the data */
- u32 szField; /* Number of bytes in the content of a field */
- int szHdr; /* Size of the header size field at start of record */
- int avail; /* Number of bytes of available data */
- u32 t; /* A type code from the record header */
- Mem *pReg; /* PseudoTable input register */
- } ao;
- struct OP_Affinity_stack_vars {
- const char *zAffinity; /* The affinity to be applied */
- char cAff; /* A single character of affinity */
- } ap;
- struct OP_MakeRecord_stack_vars {
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
- Mem *pRec; /* The new record */
- u64 nData; /* Number of bytes of data space */
- int nHdr; /* Number of bytes of header space */
- i64 nByte; /* Data space required for this record */
- int nZero; /* Number of zero bytes at the end of the record */
- int nVarint; /* Number of bytes in a varint */
- u32 serial_type; /* Type field */
- Mem *pData0; /* First field to be combined into the record */
- Mem *pLast; /* Last field of the record */
- int nField; /* Number of fields in the record */
- char *zAffinity; /* The affinity string for the record */
- int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] */
- int len; /* Length of a field */
- } aq;
- struct OP_Count_stack_vars {
- i64 nEntry;
- BtCursor *pCrsr;
- } ar;
- struct OP_Savepoint_stack_vars {
- int p1; /* Value of P1 operand */
- char *zName; /* Name of savepoint */
- int nName;
- Savepoint *pNew;
- Savepoint *pSavepoint;
- Savepoint *pTmp;
- int iSavepoint;
- int ii;
- } as;
- struct OP_AutoCommit_stack_vars {
- int desiredAutoCommit;
- int iRollback;
- int turnOnAC;
- } at;
- struct OP_Transaction_stack_vars {
- Btree *pBt;
- } au;
- struct OP_ReadCookie_stack_vars {
- int iMeta;
- int iDb;
- int iCookie;
- } av;
- struct OP_SetCookie_stack_vars {
- Db *pDb;
- } aw;
- struct OP_VerifyCookie_stack_vars {
- int iMeta;
- int iGen;
- Btree *pBt;
- } ax;
- struct OP_OpenWrite_stack_vars {
- int nField;
- KeyInfo *pKeyInfo;
- int p2;
- int iDb;
- int wrFlag;
- Btree *pX;
- VdbeCursor *pCur;
- Db *pDb;
- } ay;
- struct OP_OpenEphemeral_stack_vars {
- VdbeCursor *pCx;
- } az;
- struct OP_SorterOpen_stack_vars {
- VdbeCursor *pCx;
- } ba;
- struct OP_OpenPseudo_stack_vars {
- VdbeCursor *pCx;
- } bb;
- struct OP_SeekGt_stack_vars {
- int res;
- int oc;
- VdbeCursor *pC;
- UnpackedRecord r;
- int nField;
- i64 iKey; /* The rowid we are to seek to */
- } bc;
- struct OP_Seek_stack_vars {
- VdbeCursor *pC;
- } bd;
- struct OP_Found_stack_vars {
- int alreadyExists;
- VdbeCursor *pC;
- int res;
- char *pFree;
- UnpackedRecord *pIdxKey;
- UnpackedRecord r;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
- } be;
- struct OP_IsUnique_stack_vars {
- u16 ii;
- VdbeCursor *pCx;
- BtCursor *pCrsr;
- u16 nField;
- Mem *aMx;
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
- } bf;
- struct OP_NotExists_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- u64 iKey;
- } bg;
- struct OP_NewRowid_stack_vars {
- i64 v; /* The new rowid */
- VdbeCursor *pC; /* Cursor of table to get the new rowid */
- int res; /* Result of an sqlite3BtreeLast() */
- int cnt; /* Counter to limit the number of searches */
- Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */
- VdbeFrame *pFrame; /* Root frame of VDBE */
- } bh;
- struct OP_InsertInt_stack_vars {
- Mem *pData; /* MEM cell holding data for the record to be inserted */
- Mem *pKey; /* MEM cell holding key for the record */
- i64 iKey; /* The integer ROWID or key for the record to be inserted */
- VdbeCursor *pC; /* Cursor to table into which insert is written */
- int nZero; /* Number of zero-bytes to append */
- int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
- const char *zDb; /* database name - used by the update hook */
- const char *zTbl; /* Table name - used by the opdate hook */
- int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
- } bi;
- struct OP_Delete_stack_vars {
- i64 iKey;
- VdbeCursor *pC;
- } bj;
- struct OP_SorterCompare_stack_vars {
- VdbeCursor *pC;
- int res;
- } bk;
- struct OP_SorterData_stack_vars {
- VdbeCursor *pC;
- } bl;
- struct OP_RowData_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- u32 n;
- i64 n64;
- } bm;
- struct OP_Rowid_stack_vars {
- VdbeCursor *pC;
- i64 v;
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- } bn;
- struct OP_NullRow_stack_vars {
- VdbeCursor *pC;
- } bo;
- struct OP_Last_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- } bp;
- struct OP_Rewind_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- } bq;
- struct OP_Next_stack_vars {
- VdbeCursor *pC;
- int res;
- } br;
- struct OP_IdxInsert_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int nKey;
- const char *zKey;
- } bs;
- struct OP_IdxDelete_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- UnpackedRecord r;
- } bt;
- struct OP_IdxRowid_stack_vars {
- BtCursor *pCrsr;
- VdbeCursor *pC;
- i64 rowid;
- } bu;
- struct OP_IdxGE_stack_vars {
- VdbeCursor *pC;
- int res;
- UnpackedRecord r;
- } bv;
- struct OP_Destroy_stack_vars {
- int iMoved;
- int iCnt;
- Vdbe *pVdbe;
- int iDb;
- } bw;
- struct OP_Clear_stack_vars {
- int nChange;
- } bx;
- struct OP_CreateTable_stack_vars {
- int pgno;
- int flags;
- Db *pDb;
- } by;
- struct OP_ParseSchema_stack_vars {
- int iDb;
- const char *zMaster;
- char *zSql;
- InitData initData;
- } bz;
- struct OP_IntegrityCk_stack_vars {
- int nRoot; /* Number of tables to check. (Number of root pages.) */
- int *aRoot; /* Array of rootpage numbers for tables to be checked */
- int j; /* Loop counter */
- int nErr; /* Number of errors reported */
- char *z; /* Text of the error report */
- Mem *pnErr; /* Register keeping track of errors remaining */
- } ca;
- struct OP_RowSetRead_stack_vars {
- i64 val;
- } cb;
- struct OP_RowSetTest_stack_vars {
- int iSet;
- int exists;
- } cc;
- struct OP_Program_stack_vars {
- int nMem; /* Number of memory registers for sub-program */
- int nByte; /* Bytes of runtime space required for sub-program */
- Mem *pRt; /* Register to allocate runtime space */
- Mem *pMem; /* Used to iterate through memory cells */
- Mem *pEnd; /* Last memory cell in new array */
- VdbeFrame *pFrame; /* New vdbe frame to execute in */
- SubProgram *pProgram; /* Sub-program to execute */
- void *t; /* Token identifying trigger */
- } cd;
- struct OP_Param_stack_vars {
- VdbeFrame *pFrame;
- Mem *pIn;
- } ce;
- struct OP_MemMax_stack_vars {
- Mem *pIn1;
- VdbeFrame *pFrame;
- } cf;
- struct OP_AggStep_stack_vars {
- int n;
- int i;
- Mem *pMem;
- Mem *pRec;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- } cg;
- struct OP_AggFinal_stack_vars {
- Mem *pMem;
- } ch;
- struct OP_Checkpoint_stack_vars {
- int i; /* Loop counter */
- int aRes[3]; /* Results */
- Mem *pMem; /* Write results here */
- } ci;
- struct OP_JournalMode_stack_vars {
- Btree *pBt; /* Btree to change journal mode of */
- Pager *pPager; /* Pager associated with pBt */
- int eNew; /* New journal mode */
- int eOld; /* The old journal mode */
-#ifndef SQLITE_OMIT_WAL
- const char *zFilename; /* Name of database file for pPager */
-#endif
- } cj;
- struct OP_IncrVacuum_stack_vars {
- Btree *pBt;
- } ck;
- struct OP_VBegin_stack_vars {
- VTable *pVTab;
- } cl;
- struct OP_VOpen_stack_vars {
- VdbeCursor *pCur;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
- } cm;
- struct OP_VFilter_stack_vars {
- int nArg;
- int iQuery;
- const sqlite3_module *pModule;
- Mem *pQuery;
- Mem *pArgc;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- VdbeCursor *pCur;
- int res;
- int i;
- Mem **apArg;
- } cn;
- struct OP_VColumn_stack_vars {
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- Mem *pDest;
- sqlite3_context sContext;
- } co;
- struct OP_VNext_stack_vars {
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- int res;
- VdbeCursor *pCur;
- } cp;
- struct OP_VRename_stack_vars {
- sqlite3_vtab *pVtab;
- Mem *pName;
- } cq;
- struct OP_VUpdate_stack_vars {
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
- int nArg;
- int i;
- sqlite_int64 rowid;
- Mem **apArg;
- Mem *pX;
- } cr;
- struct OP_Trace_stack_vars {
- char *zTrace;
- char *z;
- } cs;
- } u;
- /* End automatically generated code
- ********************************************************************/
-
- assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
- sqlite3VdbeEnter(p);
- if( p->rc==SQLITE_NOMEM ){
- /* This happens if a malloc() inside a call to sqlite3_column_text() or
- ** sqlite3_column_text16() failed. */
- goto no_mem;
- }
- assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
- p->rc = SQLITE_OK;
- assert( p->explain==0 );
- p->pResultSet = 0;
- db->busyHandler.nBusy = 0;
- CHECK_FOR_INTERRUPT;
- sqlite3VdbeIOTraceSql(p);
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- checkProgress = db->xProgress!=0;
-#endif
-#ifdef SQLITE_DEBUG
- sqlite3BeginBenignMalloc();
- if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){
- int i;
- printf("VDBE Program Listing:\n");
- sqlite3VdbePrintSql(p);
- for(i=0; i<p->nOp; i++){
- sqlite3VdbePrintOp(stdout, i, &aOp[i]);
- }
- }
- sqlite3EndBenignMalloc();
-#endif
- for(pc=p->pc; rc==SQLITE_OK; pc++){
- assert( pc>=0 && pc<p->nOp );
- if( db->mallocFailed ) goto no_mem;
-#ifdef VDBE_PROFILE
- origPc = pc;
- start = sqlite3Hwtime();
-#endif
- pOp = &aOp[pc];
-
- /* Only allow tracing if SQLITE_DEBUG is defined.
- */
-#ifdef SQLITE_DEBUG
- if( p->trace ){
- if( pc==0 ){
- printf("VDBE Execution Trace:\n");
- sqlite3VdbePrintSql(p);
- }
- sqlite3VdbePrintOp(p->trace, pc, pOp);
- }
-#endif
-
-
- /* Check to see if we need to simulate an interrupt. This only happens
- ** if we have a special test build.
- */
-#ifdef SQLITE_TEST
- if( sqlite3_interrupt_count>0 ){
- sqlite3_interrupt_count--;
- if( sqlite3_interrupt_count==0 ){
- sqlite3_interrupt(db);
- }
- }
-#endif
-
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- /* Call the progress callback if it is configured and the required number
- ** of VDBE ops have been executed (either since this invocation of
- ** sqlite3VdbeExec() or since last time the progress callback was called).
- ** If the progress callback returns non-zero, exit the virtual machine with
- ** a return code SQLITE_ABORT.
- */
- if( checkProgress ){
- if( db->nProgressOps==nProgressOps ){
- int prc;
- prc = db->xProgress(db->pProgressArg);
- if( prc!=0 ){
- rc = SQLITE_INTERRUPT;
- goto vdbe_error_halt;
- }
- nProgressOps = 0;
- }
- nProgressOps++;
- }
-#endif
-
- /* On any opcode with the "out2-prerelease" tag, free any
- ** external allocations out of mem[p2] and set mem[p2] to be
- ** an undefined integer. Opcodes will either fill in the integer
- ** value or convert mem[p2] to a different type.
- */
- assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
- if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
- assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
- pOut = &aMem[pOp->p2];
- memAboutToChange(p, pOut);
- VdbeMemRelease(pOut);
- pOut->flags = MEM_Int;
- }
-
- /* Sanity checking on other operands */
-#ifdef SQLITE_DEBUG
- if( (pOp->opflags & OPFLG_IN1)!=0 ){
- assert( pOp->p1>0 );
- assert( pOp->p1<=p->nMem );
- assert( memIsValid(&aMem[pOp->p1]) );
- REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
- }
- if( (pOp->opflags & OPFLG_IN2)!=0 ){
- assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
- assert( memIsValid(&aMem[pOp->p2]) );
- REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
- }
- if( (pOp->opflags & OPFLG_IN3)!=0 ){
- assert( pOp->p3>0 );
- assert( pOp->p3<=p->nMem );
- assert( memIsValid(&aMem[pOp->p3]) );
- REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
- }
- if( (pOp->opflags & OPFLG_OUT2)!=0 ){
- assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
- memAboutToChange(p, &aMem[pOp->p2]);
- }
- if( (pOp->opflags & OPFLG_OUT3)!=0 ){
- assert( pOp->p3>0 );
- assert( pOp->p3<=p->nMem );
- memAboutToChange(p, &aMem[pOp->p3]);
- }
-#endif
-
- switch( pOp->opcode ){
-
-/*****************************************************************************
-** What follows is a massive switch statement where each case implements a
-** separate instruction in the virtual machine. If we follow the usual
-** indentation conventions, each case should be indented by 6 spaces. But
-** that is a lot of wasted space on the left margin. So the code within
-** the switch statement will break with convention and be flush-left. Another
-** big comment (similar to this one) will mark the point in the code where
-** we transition back to normal indentation.
-**
-** The formatting of each case is important. The makefile for SQLite
-** generates two C files "opcodes.h" and "opcodes.c" by scanning this
-** file looking for lines that begin with "case OP_". The opcodes.h files
-** will be filled with #defines that give unique integer values to each
-** opcode and the opcodes.c file is filled with an array of strings where
-** each string is the symbolic name for the corresponding opcode. If the
-** case statement is followed by a comment of the form "/# same as ... #/"
-** that comment is used to determine the particular value of the opcode.
-**
-** Other keywords in the comment that follows each case are used to
-** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[].
-** Keywords include: in1, in2, in3, out2_prerelease, out2, out3. See
-** the mkopcodeh.awk script for additional information.
-**
-** Documentation about VDBE opcodes is generated by scanning this file
-** for lines of that contain "Opcode:". That line and all subsequent
-** comment lines are used in the generation of the opcode.html documentation
-** file.
-**
-** SUMMARY:
-**
-** Formatting is important to scripts that scan this file.
-** Do not deviate from the formatting style currently in use.
-**
-*****************************************************************************/
-
-/* Opcode: Goto * P2 * * *
-**
-** An unconditional jump to address P2.
-** The next instruction executed will be
-** the one at index P2 from the beginning of
-** the program.
-*/
-case OP_Goto: { /* jump */
- CHECK_FOR_INTERRUPT;
- pc = pOp->p2 - 1;
- break;
-}
-
-/* Opcode: Gosub P1 P2 * * *
-**
-** Write the current address onto register P1
-** and then jump to address P2.
-*/
-case OP_Gosub: { /* jump */
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
- pIn1 = &aMem[pOp->p1];
- assert( (pIn1->flags & MEM_Dyn)==0 );
- memAboutToChange(p, pIn1);
- pIn1->flags = MEM_Int;
- pIn1->u.i = pc;
- REGISTER_TRACE(pOp->p1, pIn1);
- pc = pOp->p2 - 1;
- break;
-}
-
-/* Opcode: Return P1 * * * *
-**
-** Jump to the next instruction after the address in register P1.
-*/
-case OP_Return: { /* in1 */
- pIn1 = &aMem[pOp->p1];
- assert( pIn1->flags & MEM_Int );
- pc = (int)pIn1->u.i;
- break;
-}
-
-/* Opcode: Yield P1 * * * *
-**
-** Swap the program counter with the value in register P1.
-*/
-case OP_Yield: { /* in1 */
-#if 0 /* local variables moved into u.aa */
- int pcDest;
-#endif /* local variables moved into u.aa */
- pIn1 = &aMem[pOp->p1];
- assert( (pIn1->flags & MEM_Dyn)==0 );
- pIn1->flags = MEM_Int;
- u.aa.pcDest = (int)pIn1->u.i;
- pIn1->u.i = pc;
- REGISTER_TRACE(pOp->p1, pIn1);
- pc = u.aa.pcDest;
- break;
-}
-
-/* Opcode: HaltIfNull P1 P2 P3 P4 *
-**
-** Check the value in register P3. If it is NULL then Halt using
-** parameter P1, P2, and P4 as if this were a Halt instruction. If the
-** value in register P3 is not NULL, then this routine is a no-op.
-*/
-case OP_HaltIfNull: { /* in3 */
- pIn3 = &aMem[pOp->p3];
- if( (pIn3->flags & MEM_Null)==0 ) break;
- /* Fall through into OP_Halt */
-}
-
-/* Opcode: Halt P1 P2 * P4 *
-**
-** Exit immediately. All open cursors, etc are closed
-** automatically.
-**
-** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(),
-** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0).
-** For errors, it can be some other value. If P1!=0 then P2 will determine
-** whether or not to rollback the current transaction. Do not rollback
-** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort,
-** then back out all changes that have occurred during this execution of the
-** VDBE, but do not rollback the transaction.
-**
-** If P4 is not null then it is an error message string.
-**
-** There is an implied "Halt 0 0 0" instruction inserted at the very end of
-** every program. So a jump past the last instruction of the program
-** is the same as executing Halt.
-*/
-case OP_Halt: {
- if( pOp->p1==SQLITE_OK && p->pFrame ){
- /* Halt the sub-program. Return control to the parent frame. */
- VdbeFrame *pFrame = p->pFrame;
- p->pFrame = pFrame->pParent;
- p->nFrame--;
- sqlite3VdbeSetChanges(db, p->nChange);
- pc = sqlite3VdbeFrameRestore(pFrame);
- lastRowid = db->lastRowid;
- if( pOp->p2==OE_Ignore ){
- /* Instruction pc is the OP_Program that invoked the sub-program
- ** currently being halted. If the p2 instruction of this OP_Halt
- ** instruction is set to OE_Ignore, then the sub-program is throwing
- ** an IGNORE exception. In this case jump to the address specified
- ** as the p2 of the calling OP_Program. */
- pc = p->aOp[pc].p2-1;
- }
- aOp = p->aOp;
- aMem = p->aMem;
- break;
- }
-
- p->rc = pOp->p1;
- p->errorAction = (u8)pOp->p2;
- p->pc = pc;
- if( pOp->p4.z ){
- assert( p->rc!=SQLITE_OK );
- sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pc, p->zSql, pOp->p4.z);
- }else if( p->rc ){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(pOp->p1, "constraint failed at %d in [%s]", pc, p->zSql);
- }
- rc = sqlite3VdbeHalt(p);
- assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
- if( rc==SQLITE_BUSY ){
- p->rc = rc = SQLITE_BUSY;
- }else{
- assert( rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT );
- assert( rc==SQLITE_OK || db->nDeferredCons>0 );
- rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
- }
- goto vdbe_return;
-}
-
-/* Opcode: Integer P1 P2 * * *
-**
-** The 32-bit integer value P1 is written into register P2.
-*/
-case OP_Integer: { /* out2-prerelease */
- pOut->u.i = pOp->p1;
- break;
-}
-
-/* Opcode: Int64 * P2 * P4 *
-**
-** P4 is a pointer to a 64-bit integer value.
-** Write that value into register P2.
-*/
-case OP_Int64: { /* out2-prerelease */
- assert( pOp->p4.pI64!=0 );
- pOut->u.i = *pOp->p4.pI64;
- break;
-}
-
-#ifndef SQLITE_OMIT_FLOATING_POINT
-/* Opcode: Real * P2 * P4 *
-**
-** P4 is a pointer to a 64-bit floating point value.
-** Write that value into register P2.
-*/
-case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
- pOut->flags = MEM_Real;
- assert( !sqlite3IsNaN(*pOp->p4.pReal) );
- pOut->r = *pOp->p4.pReal;
- break;
-}
-#endif
-
-/* Opcode: String8 * P2 * P4 *
-**
-** P4 points to a nul terminated UTF-8 string. This opcode is transformed
-** into an OP_String before it is executed for the first time.
-*/
-case OP_String8: { /* same as TK_STRING, out2-prerelease */
- assert( pOp->p4.z!=0 );
- pOp->opcode = OP_String;
- pOp->p1 = sqlite3Strlen30(pOp->p4.z);
-
-#ifndef SQLITE_OMIT_UTF16
- if( encoding!=SQLITE_UTF8 ){
- rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
- if( rc==SQLITE_TOOBIG ) goto too_big;
- if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
- assert( pOut->zMalloc==pOut->z );
- assert( pOut->flags & MEM_Dyn );
- pOut->zMalloc = 0;
- pOut->flags |= MEM_Static;
- pOut->flags &= ~MEM_Dyn;
- if( pOp->p4type==P4_DYNAMIC ){
- sqlite3DbFree(db, pOp->p4.z);
- }
- pOp->p4type = P4_DYNAMIC;
- pOp->p4.z = pOut->z;
- pOp->p1 = pOut->n;
- }
-#endif
- if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- /* Fall through to the next case, OP_String */
-}
-
-/* Opcode: String P1 P2 * P4 *
-**
-** The string value P4 of length P1 (bytes) is stored in register P2.
-*/
-case OP_String: { /* out2-prerelease */
- assert( pOp->p4.z!=0 );
- pOut->flags = MEM_Str|MEM_Static|MEM_Term;
- pOut->z = pOp->p4.z;
- pOut->n = pOp->p1;
- pOut->enc = encoding;
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Null P1 P2 P3 * *
-**
-** Write a NULL into registers P2. If P3 greater than P2, then also write
-** NULL into register P3 and every register in between P2 and P3. If P3
-** is less than P2 (typically P3 is zero) then only register P2 is
-** set to NULL.
-**
-** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
-** NULL values will not compare equal even if SQLITE_NULLEQ is set on
-** OP_Ne or OP_Eq.
-*/
-case OP_Null: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ab */
- int cnt;
- u16 nullFlag;
-#endif /* local variables moved into u.ab */
- u.ab.cnt = pOp->p3-pOp->p2;
- assert( pOp->p3<=p->nMem );
- pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
- while( u.ab.cnt>0 ){
- pOut++;
- memAboutToChange(p, pOut);
- VdbeMemRelease(pOut);
- pOut->flags = u.ab.nullFlag;
- u.ab.cnt--;
- }
- break;
-}
-
-
-/* Opcode: Blob P1 P2 * P4
-**
-** P4 points to a blob of data P1 bytes long. Store this
-** blob in register P2.
-*/
-case OP_Blob: { /* out2-prerelease */
- assert( pOp->p1 <= SQLITE_MAX_LENGTH );
- sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
- pOut->enc = encoding;
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Variable P1 P2 * P4 *
-**
-** Transfer the values of bound parameter P1 into register P2
-**
-** If the parameter is named, then its name appears in P4 and P3==1.
-** The P4 value is used by sqlite3_bind_parameter_name().
-*/
-case OP_Variable: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ac */
- Mem *pVar; /* Value being transferred */
-#endif /* local variables moved into u.ac */
-
- assert( pOp->p1>0 && pOp->p1<=p->nVar );
- assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
- u.ac.pVar = &p->aVar[pOp->p1 - 1];
- if( sqlite3VdbeMemTooBig(u.ac.pVar) ){
- goto too_big;
- }
- sqlite3VdbeMemShallowCopy(pOut, u.ac.pVar, MEM_Static);
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Move P1 P2 P3 * *
-**
-** Move the values in register P1..P1+P3 over into
-** registers P2..P2+P3. Registers P1..P1+P3 are
-** left holding a NULL. It is an error for register ranges
-** P1..P1+P3 and P2..P2+P3 to overlap.
-*/
-case OP_Move: {
-#if 0 /* local variables moved into u.ad */
- char *zMalloc; /* Holding variable for allocated memory */
- int n; /* Number of registers left to copy */
- int p1; /* Register to copy from */
- int p2; /* Register to copy to */
-#endif /* local variables moved into u.ad */
-
- u.ad.n = pOp->p3 + 1;
- u.ad.p1 = pOp->p1;
- u.ad.p2 = pOp->p2;
- assert( u.ad.n>0 && u.ad.p1>0 && u.ad.p2>0 );
- assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 );
-
- pIn1 = &aMem[u.ad.p1];
- pOut = &aMem[u.ad.p2];
- while( u.ad.n-- ){
- assert( pOut<=&aMem[p->nMem] );
- assert( pIn1<=&aMem[p->nMem] );
- assert( memIsValid(pIn1) );
- memAboutToChange(p, pOut);
- u.ad.zMalloc = pOut->zMalloc;
- pOut->zMalloc = 0;
- sqlite3VdbeMemMove(pOut, pIn1);
-#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom>=&aMem[u.ad.p1] && pOut->pScopyFrom<&aMem[u.ad.p1+pOp->p3] ){
- pOut->pScopyFrom += u.ad.p1 - pOp->p2;
- }
-#endif
- pIn1->zMalloc = u.ad.zMalloc;
- REGISTER_TRACE(u.ad.p2++, pOut);
- pIn1++;
- pOut++;
- }
- break;
-}
-
-/* Opcode: Copy P1 P2 P3 * *
-**
-** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
-**
-** This instruction makes a deep copy of the value. A duplicate
-** is made of any string or blob constant. See also OP_SCopy.
-*/
-case OP_Copy: {
-#if 0 /* local variables moved into u.ae */
- int n;
-#endif /* local variables moved into u.ae */
-
- u.ae.n = pOp->p3;
- pIn1 = &aMem[pOp->p1];
- pOut = &aMem[pOp->p2];
- assert( pOut!=pIn1 );
- while( 1 ){
- sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
- Deephemeralize(pOut);
-#ifdef SQLITE_DEBUG
- pOut->pScopyFrom = 0;
-#endif
- REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
- if( (u.ae.n--)==0 ) break;
- pOut++;
- pIn1++;
- }
- break;
-}
-
-/* Opcode: SCopy P1 P2 * * *
-**
-** Make a shallow copy of register P1 into register P2.
-**
-** This instruction makes a shallow copy of the value. If the value
-** is a string or blob, then the copy is only a pointer to the
-** original and hence if the original changes so will the copy.
-** Worse, if the original is deallocated, the copy becomes invalid.
-** Thus the program must guarantee that the original will not change
-** during the lifetime of the copy. Use OP_Copy to make a complete
-** copy.
-*/
-case OP_SCopy: { /* in1, out2 */
- pIn1 = &aMem[pOp->p1];
- pOut = &aMem[pOp->p2];
- assert( pOut!=pIn1 );
- sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
-#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1;
-#endif
- REGISTER_TRACE(pOp->p2, pOut);
- break;
-}
-
-/* Opcode: ResultRow P1 P2 * * *
-**
-** The registers P1 through P1+P2-1 contain a single row of
-** results. This opcode causes the sqlite3_step() call to terminate
-** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
-** structure to provide access to the top P1 values as the result
-** row.
-*/
-case OP_ResultRow: {
-#if 0 /* local variables moved into u.af */
- Mem *pMem;
- int i;
-#endif /* local variables moved into u.af */
- assert( p->nResColumn==pOp->p2 );
- assert( pOp->p1>0 );
- assert( pOp->p1+pOp->p2<=p->nMem+1 );
-
- /* If this statement has violated immediate foreign key constraints, do
- ** not return the number of rows modified. And do not RELEASE the statement
- ** transaction. It needs to be rolled back. */
- if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){
- assert( db->flags&SQLITE_CountRows );
- assert( p->usesStmtJournal );
- break;
- }
-
- /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
- ** DML statements invoke this opcode to return the number of rows
- ** modified to the user. This is the only way that a VM that
- ** opens a statement transaction may invoke this opcode.
- **
- ** In case this is such a statement, close any statement transaction
- ** opened by this VM before returning control to the user. This is to
- ** ensure that statement-transactions are always nested, not overlapping.
- ** If the open statement-transaction is not closed here, then the user
- ** may step another VM that opens its own statement transaction. This
- ** may lead to overlapping statement transactions.
- **
- ** The statement transaction is never a top-level transaction. Hence
- ** the RELEASE call below can never fail.
- */
- assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
- rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE);
- if( NEVER(rc!=SQLITE_OK) ){
- break;
- }
-
- /* Invalidate all ephemeral cursor row caches */
- p->cacheCtr = (p->cacheCtr + 2)|1;
-
- /* Make sure the results of the current row are \000 terminated
- ** and have an assigned type. The results are de-ephemeralized as
- ** a side effect.
- */
- u.af.pMem = p->pResultSet = &aMem[pOp->p1];
- for(u.af.i=0; u.af.i<pOp->p2; u.af.i++){
- assert( memIsValid(&u.af.pMem[u.af.i]) );
- Deephemeralize(&u.af.pMem[u.af.i]);
- assert( (u.af.pMem[u.af.i].flags & MEM_Ephem)==0
- || (u.af.pMem[u.af.i].flags & (MEM_Str|MEM_Blob))==0 );
- sqlite3VdbeMemNulTerminate(&u.af.pMem[u.af.i]);
- sqlite3VdbeMemStoreType(&u.af.pMem[u.af.i]);
- REGISTER_TRACE(pOp->p1+u.af.i, &u.af.pMem[u.af.i]);
- }
- if( db->mallocFailed ) goto no_mem;
-
- /* Return SQLITE_ROW
- */
- p->pc = pc + 1;
- rc = SQLITE_ROW;
- goto vdbe_return;
-}
-
-/* Opcode: Concat P1 P2 P3 * *
-**
-** Add the text in register P1 onto the end of the text in
-** register P2 and store the result in register P3.
-** If either the P1 or P2 text are NULL then store NULL in P3.
-**
-** P3 = P2 || P1
-**
-** It is illegal for P1 and P3 to be the same register. Sometimes,
-** if P3 is the same register as P2, the implementation is able
-** to avoid a memcpy().
-*/
-case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
-#if 0 /* local variables moved into u.ag */
- i64 nByte;
-#endif /* local variables moved into u.ag */
-
- pIn1 = &aMem[pOp->p1];
- pIn2 = &aMem[pOp->p2];
- pOut = &aMem[pOp->p3];
- assert( pIn1!=pOut );
- if( (pIn1->flags | pIn2->flags) & MEM_Null ){
- sqlite3VdbeMemSetNull(pOut);
- break;
- }
- if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
- Stringify(pIn1, encoding);
- Stringify(pIn2, encoding);
- u.ag.nByte = pIn1->n + pIn2->n;
- if( u.ag.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- MemSetTypeFlag(pOut, MEM_Str);
- if( sqlite3VdbeMemGrow(pOut, (int)u.ag.nByte+2, pOut==pIn2) ){
- goto no_mem;
- }
- if( pOut!=pIn2 ){
- memcpy(pOut->z, pIn2->z, pIn2->n);
- }
- memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
- pOut->z[u.ag.nByte] = 0;
- pOut->z[u.ag.nByte+1] = 0;
- pOut->flags |= MEM_Term;
- pOut->n = (int)u.ag.nByte;
- pOut->enc = encoding;
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Add P1 P2 P3 * *
-**
-** Add the value in register P1 to the value in register P2
-** and store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: Multiply P1 P2 P3 * *
-**
-**
-** Multiply the value in register P1 by the value in register P2
-** and store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: Subtract P1 P2 P3 * *
-**
-** Subtract the value in register P1 from the value in register P2
-** and store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: Divide P1 P2 P3 * *
-**
-** Divide the value in register P1 by the value in register P2
-** and store the result in register P3 (P3=P2/P1). If the value in
-** register P1 is zero, then the result is NULL. If either input is
-** NULL, the result is NULL.
-*/
-/* Opcode: Remainder P1 P2 P3 * *
-**
-** Compute the remainder after integer division of the value in
-** register P1 by the value in register P2 and store the result in P3.
-** If the value in register P2 is zero the result is NULL.
-** If either operand is NULL, the result is NULL.
-*/
-case OP_Add: /* same as TK_PLUS, in1, in2, out3 */
-case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
-case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
-case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
-case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
-#if 0 /* local variables moved into u.ah */
- char bIntint; /* Started out as two integer operands */
- int flags; /* Combined MEM_* flags from both inputs */
- i64 iA; /* Integer value of left operand */
- i64 iB; /* Integer value of right operand */
- double rA; /* Real value of left operand */
- double rB; /* Real value of right operand */
-#endif /* local variables moved into u.ah */
-
- pIn1 = &aMem[pOp->p1];
- applyNumericAffinity(pIn1);
- pIn2 = &aMem[pOp->p2];
- applyNumericAffinity(pIn2);
- pOut = &aMem[pOp->p3];
- u.ah.flags = pIn1->flags | pIn2->flags;
- if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
- if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
- u.ah.iA = pIn1->u.i;
- u.ah.iB = pIn2->u.i;
- u.ah.bIntint = 1;
- switch( pOp->opcode ){
- case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
- case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
- case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
- case OP_Divide: {
- if( u.ah.iA==0 ) goto arithmetic_result_is_null;
- if( u.ah.iA==-1 && u.ah.iB==SMALLEST_INT64 ) goto fp_math;
- u.ah.iB /= u.ah.iA;
- break;
- }
- default: {
- if( u.ah.iA==0 ) goto arithmetic_result_is_null;
- if( u.ah.iA==-1 ) u.ah.iA = 1;
- u.ah.iB %= u.ah.iA;
- break;
- }
- }
- pOut->u.i = u.ah.iB;
- MemSetTypeFlag(pOut, MEM_Int);
- }else{
- u.ah.bIntint = 0;
-fp_math:
- u.ah.rA = sqlite3VdbeRealValue(pIn1);
- u.ah.rB = sqlite3VdbeRealValue(pIn2);
- switch( pOp->opcode ){
- case OP_Add: u.ah.rB += u.ah.rA; break;
- case OP_Subtract: u.ah.rB -= u.ah.rA; break;
- case OP_Multiply: u.ah.rB *= u.ah.rA; break;
- case OP_Divide: {
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- if( u.ah.rA==(double)0 ) goto arithmetic_result_is_null;
- u.ah.rB /= u.ah.rA;
- break;
- }
- default: {
- u.ah.iA = (i64)u.ah.rA;
- u.ah.iB = (i64)u.ah.rB;
- if( u.ah.iA==0 ) goto arithmetic_result_is_null;
- if( u.ah.iA==-1 ) u.ah.iA = 1;
- u.ah.rB = (double)(u.ah.iB % u.ah.iA);
- break;
- }
- }
-#ifdef SQLITE_OMIT_FLOATING_POINT
- pOut->u.i = u.ah.rB;
- MemSetTypeFlag(pOut, MEM_Int);
-#else
- if( sqlite3IsNaN(u.ah.rB) ){
- goto arithmetic_result_is_null;
- }
- pOut->r = u.ah.rB;
- MemSetTypeFlag(pOut, MEM_Real);
- if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
- sqlite3VdbeIntegerAffinity(pOut);
- }
-#endif
- }
- break;
-
-arithmetic_result_is_null:
- sqlite3VdbeMemSetNull(pOut);
- break;
-}
-
-/* Opcode: CollSeq P1 * * P4
-**
-** P4 is a pointer to a CollSeq struct. If the next call to a user function
-** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
-** be returned. This is used by the built-in min(), max() and nullif()
-** functions.
-**
-** If P1 is not zero, then it is a register that a subsequent min() or
-** max() aggregate will set to 1 if the current row is not the minimum or
-** maximum. The P1 register is initialized to 0 by this instruction.
-**
-** The interface used by the implementation of the aforementioned functions
-** to retrieve the collation sequence set by this opcode is not available
-** publicly, only to user functions defined in func.c.
-*/
-case OP_CollSeq: {
- assert( pOp->p4type==P4_COLLSEQ );
- if( pOp->p1 ){
- sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0);
- }
- break;
-}
-
-/* Opcode: Function P1 P2 P3 P4 P5
-**
-** Invoke a user function (P4 is a pointer to a Function structure that
-** defines the function) with P5 arguments taken from register P2 and
-** successors. The result of the function is stored in register P3.
-** Register P3 must not be one of the function inputs.
-**
-** P1 is a 32-bit bitmask indicating whether or not each argument to the
-** function was determined to be constant at compile time. If the first
-** argument was constant then bit 0 of P1 is set. This is used to determine
-** whether meta data associated with a user function argument using the
-** sqlite3_set_auxdata() API may be safely retained until the next
-** invocation of this opcode.
-**
-** See also: AggStep and AggFinal
-*/
-case OP_Function: {
-#if 0 /* local variables moved into u.ai */
- int i;
- Mem *pArg;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- int n;
-#endif /* local variables moved into u.ai */
-
- u.ai.n = pOp->p5;
- u.ai.apVal = p->apArg;
- assert( u.ai.apVal || u.ai.n==0 );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pOut = &aMem[pOp->p3];
- memAboutToChange(p, pOut);
-
- assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) );
- assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n );
- u.ai.pArg = &aMem[pOp->p2];
- for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){
- assert( memIsValid(u.ai.pArg) );
- u.ai.apVal[u.ai.i] = u.ai.pArg;
- Deephemeralize(u.ai.pArg);
- sqlite3VdbeMemStoreType(u.ai.pArg);
- REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
- }
-
- assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
- if( pOp->p4type==P4_FUNCDEF ){
- u.ai.ctx.pFunc = pOp->p4.pFunc;
- u.ai.ctx.pVdbeFunc = 0;
- }else{
- u.ai.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
- u.ai.ctx.pFunc = u.ai.ctx.pVdbeFunc->pFunc;
- }
-
- u.ai.ctx.s.flags = MEM_Null;
- u.ai.ctx.s.db = db;
- u.ai.ctx.s.xDel = 0;
- u.ai.ctx.s.zMalloc = 0;
-
- /* The output cell may already have a buffer allocated. Move
- ** the pointer to u.ai.ctx.s so in case the user-function can use
- ** the already allocated buffer instead of allocating a new one.
- */
- sqlite3VdbeMemMove(&u.ai.ctx.s, pOut);
- MemSetTypeFlag(&u.ai.ctx.s, MEM_Null);
-
- u.ai.ctx.isError = 0;
- if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
- assert( pOp>aOp );
- assert( pOp[-1].p4type==P4_COLLSEQ );
- assert( pOp[-1].opcode==OP_CollSeq );
- u.ai.ctx.pColl = pOp[-1].p4.pColl;
- }
- db->lastRowid = lastRowid;
- (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */
- lastRowid = db->lastRowid;
-
- /* If any auxiliary data functions have been called by this user function,
- ** immediately call the destructor for any non-static values.
- */
- if( u.ai.ctx.pVdbeFunc ){
- sqlite3VdbeDeleteAuxData(u.ai.ctx.pVdbeFunc, pOp->p1);
- pOp->p4.pVdbeFunc = u.ai.ctx.pVdbeFunc;
- pOp->p4type = P4_VDBEFUNC;
- }
-
- if( db->mallocFailed ){
- /* Even though a malloc() has failed, the implementation of the
- ** user function may have called an sqlite3_result_XXX() function
- ** to return a value. The following call releases any resources
- ** associated with such a value.
- */
- sqlite3VdbeMemRelease(&u.ai.ctx.s);
- goto no_mem;
- }
-
- /* If the function returned an error, throw an exception */
- if( u.ai.ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s));
- rc = u.ai.ctx.isError;
- }
-
- /* Copy the result of the function into register P3 */
- sqlite3VdbeChangeEncoding(&u.ai.ctx.s, encoding);
- sqlite3VdbeMemMove(pOut, &u.ai.ctx.s);
- if( sqlite3VdbeMemTooBig(pOut) ){
- goto too_big;
- }
-
-#if 0
- /* The app-defined function has done something that as caused this
- ** statement to expire. (Perhaps the function called sqlite3_exec()
- ** with a CREATE TABLE statement.)
- */
- if( p->expired ) rc = SQLITE_ABORT;
-#endif
-
- REGISTER_TRACE(pOp->p3, pOut);
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: BitAnd P1 P2 P3 * *
-**
-** Take the bit-wise AND of the values in register P1 and P2 and
-** store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: BitOr P1 P2 P3 * *
-**
-** Take the bit-wise OR of the values in register P1 and P2 and
-** store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: ShiftLeft P1 P2 P3 * *
-**
-** Shift the integer value in register P2 to the left by the
-** number of bits specified by the integer in register P1.
-** Store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-/* Opcode: ShiftRight P1 P2 P3 * *
-**
-** Shift the integer value in register P2 to the right by the
-** number of bits specified by the integer in register P1.
-** Store the result in register P3.
-** If either input is NULL, the result is NULL.
-*/
-case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */
-case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */
-case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
-case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
-#if 0 /* local variables moved into u.aj */
- i64 iA;
- u64 uA;
- i64 iB;
- u8 op;
-#endif /* local variables moved into u.aj */
-
- pIn1 = &aMem[pOp->p1];
- pIn2 = &aMem[pOp->p2];
- pOut = &aMem[pOp->p3];
- if( (pIn1->flags | pIn2->flags) & MEM_Null ){
- sqlite3VdbeMemSetNull(pOut);
- break;
- }
- u.aj.iA = sqlite3VdbeIntValue(pIn2);
- u.aj.iB = sqlite3VdbeIntValue(pIn1);
- u.aj.op = pOp->opcode;
- if( u.aj.op==OP_BitAnd ){
- u.aj.iA &= u.aj.iB;
- }else if( u.aj.op==OP_BitOr ){
- u.aj.iA |= u.aj.iB;
- }else if( u.aj.iB!=0 ){
- assert( u.aj.op==OP_ShiftRight || u.aj.op==OP_ShiftLeft );
-
- /* If shifting by a negative amount, shift in the other direction */
- if( u.aj.iB<0 ){
- assert( OP_ShiftRight==OP_ShiftLeft+1 );
- u.aj.op = 2*OP_ShiftLeft + 1 - u.aj.op;
- u.aj.iB = u.aj.iB>(-64) ? -u.aj.iB : 64;
- }
-
- if( u.aj.iB>=64 ){
- u.aj.iA = (u.aj.iA>=0 || u.aj.op==OP_ShiftLeft) ? 0 : -1;
- }else{
- memcpy(&u.aj.uA, &u.aj.iA, sizeof(u.aj.uA));
- if( u.aj.op==OP_ShiftLeft ){
- u.aj.uA <<= u.aj.iB;
- }else{
- u.aj.uA >>= u.aj.iB;
- /* Sign-extend on a right shift of a negative number */
- if( u.aj.iA<0 ) u.aj.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.aj.iB);
- }
- memcpy(&u.aj.iA, &u.aj.uA, sizeof(u.aj.iA));
- }
- }
- pOut->u.i = u.aj.iA;
- MemSetTypeFlag(pOut, MEM_Int);
- break;
-}
-
-/* Opcode: AddImm P1 P2 * * *
-**
-** Add the constant P2 to the value in register P1.
-** The result is always an integer.
-**
-** To force any register to be an integer, just add 0.
-*/
-case OP_AddImm: { /* in1 */
- pIn1 = &aMem[pOp->p1];
- memAboutToChange(p, pIn1);
- sqlite3VdbeMemIntegerify(pIn1);
- pIn1->u.i += pOp->p2;
- break;
-}
-
-/* Opcode: MustBeInt P1 P2 * * *
-**
-** Force the value in register P1 to be an integer. If the value
-** in P1 is not an integer and cannot be converted into an integer
-** without data loss, then jump immediately to P2, or if P2==0
-** raise an SQLITE_MISMATCH exception.
-*/
-case OP_MustBeInt: { /* jump, in1 */
- pIn1 = &aMem[pOp->p1];
- applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
- if( (pIn1->flags & MEM_Int)==0 ){
- if( pOp->p2==0 ){
- rc = SQLITE_MISMATCH;
- goto abort_due_to_error;
- }else{
- pc = pOp->p2 - 1;
- }
- }else{
- MemSetTypeFlag(pIn1, MEM_Int);
- }
- break;
-}
-
-#ifndef SQLITE_OMIT_FLOATING_POINT
-/* Opcode: RealAffinity P1 * * * *
-**
-** If register P1 holds an integer convert it to a real value.
-**
-** This opcode is used when extracting information from a column that
-** has REAL affinity. Such column values may still be stored as
-** integers, for space efficiency, but after extraction we want them
-** to have only a real value.
-*/
-case OP_RealAffinity: { /* in1 */
- pIn1 = &aMem[pOp->p1];
- if( pIn1->flags & MEM_Int ){
- sqlite3VdbeMemRealify(pIn1);
- }
- break;
-}
-#endif
-
-#ifndef SQLITE_OMIT_CAST
-/* Opcode: ToText P1 * * * *
-**
-** Force the value in register P1 to be text.
-** If the value is numeric, convert it to a string using the
-** equivalent of printf(). Blob values are unchanged and
-** are afterwards simply interpreted as text.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToText: { /* same as TK_TO_TEXT, in1 */
- pIn1 = &aMem[pOp->p1];
- memAboutToChange(p, pIn1);
- if( pIn1->flags & MEM_Null ) break;
- assert( MEM_Str==(MEM_Blob>>3) );
- pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
- applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
- rc = ExpandBlob(pIn1);
- assert( pIn1->flags & MEM_Str || db->mallocFailed );
- pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
- UPDATE_MAX_BLOBSIZE(pIn1);
- break;
-}
-
-/* Opcode: ToBlob P1 * * * *
-**
-** Force the value in register P1 to be a BLOB.
-** If the value is numeric, convert it to a string first.
-** Strings are simply reinterpreted as blobs with no change
-** to the underlying data.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */
- pIn1 = &aMem[pOp->p1];
- if( pIn1->flags & MEM_Null ) break;
- if( (pIn1->flags & MEM_Blob)==0 ){
- applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
- assert( pIn1->flags & MEM_Str || db->mallocFailed );
- MemSetTypeFlag(pIn1, MEM_Blob);
- }else{
- pIn1->flags &= ~(MEM_TypeMask&~MEM_Blob);
- }
- UPDATE_MAX_BLOBSIZE(pIn1);
- break;
-}
-
-/* Opcode: ToNumeric P1 * * * *
-**
-** Force the value in register P1 to be numeric (either an
-** integer or a floating-point number.)
-** If the value is text or blob, try to convert it to an using the
-** equivalent of atoi() or atof() and store 0 if no such conversion
-** is possible.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */
- pIn1 = &aMem[pOp->p1];
- sqlite3VdbeMemNumerify(pIn1);
- break;
-}
-#endif /* SQLITE_OMIT_CAST */
-
-/* Opcode: ToInt P1 * * * *
-**
-** Force the value in register P1 to be an integer. If
-** The value is currently a real number, drop its fractional part.
-** If the value is text or blob, try to convert it to an integer using the
-** equivalent of atoi() and store 0 if no such conversion is possible.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToInt: { /* same as TK_TO_INT, in1 */
- pIn1 = &aMem[pOp->p1];
- if( (pIn1->flags & MEM_Null)==0 ){
- sqlite3VdbeMemIntegerify(pIn1);
- }
- break;
-}
-
-#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT)
-/* Opcode: ToReal P1 * * * *
-**
-** Force the value in register P1 to be a floating point number.
-** If The value is currently an integer, convert it.
-** If the value is text or blob, try to convert it to an integer using the
-** equivalent of atoi() and store 0.0 if no such conversion is possible.
-**
-** A NULL value is not changed by this routine. It remains NULL.
-*/
-case OP_ToReal: { /* same as TK_TO_REAL, in1 */
- pIn1 = &aMem[pOp->p1];
- memAboutToChange(p, pIn1);
- if( (pIn1->flags & MEM_Null)==0 ){
- sqlite3VdbeMemRealify(pIn1);
- }
- break;
-}
-#endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */
-
-/* Opcode: Lt P1 P2 P3 P4 P5
-**
-** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
-** jump to address P2.
-**
-** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
-** reg(P3) is NULL then take the jump. If the SQLITE_JUMPIFNULL
-** bit is clear then fall through if either operand is NULL.
-**
-** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
-** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made
-** to coerce both inputs according to this affinity before the
-** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
-** affinity is used. Note that the affinity conversions are stored
-** back into the input registers P1 and P3. So this opcode can cause
-** persistent changes to registers P1 and P3.
-**
-** Once any conversions have taken place, and neither value is NULL,
-** the values are compared. If both values are blobs then memcmp() is
-** used to determine the results of the comparison. If both values
-** are text, then the appropriate collating function specified in
-** P4 is used to do the comparison. If P4 is not specified then
-** memcmp() is used to compare text string. If both values are
-** numeric, then a numeric comparison is used. If the two values
-** are of different types, then numbers are considered less than
-** strings and strings are considered less than blobs.
-**
-** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead,
-** store a boolean result (either 0, or 1, or NULL) in register P2.
-**
-** If the SQLITE_NULLEQ bit is set in P5, then NULL values are considered
-** equal to one another, provided that they do not have their MEM_Cleared
-** bit set.
-*/
-/* Opcode: Ne P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the operands in registers P1 and P3 are not equal. See the Lt opcode for
-** additional information.
-**
-** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
-** true or false and is never NULL. If both operands are NULL then the result
-** of comparison is false. If either operand is NULL then the result is true.
-** If neither operand is NULL the result is the same as it would be if
-** the SQLITE_NULLEQ flag were omitted from P5.
-*/
-/* Opcode: Eq P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the operands in registers P1 and P3 are equal.
-** See the Lt opcode for additional information.
-**
-** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
-** true or false and is never NULL. If both operands are NULL then the result
-** of comparison is true. If either operand is NULL then the result is false.
-** If neither operand is NULL the result is the same as it would be if
-** the SQLITE_NULLEQ flag were omitted from P5.
-*/
-/* Opcode: Le P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the content of register P3 is less than or equal to the content of
-** register P1. See the Lt opcode for additional information.
-*/
-/* Opcode: Gt P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the content of register P3 is greater than the content of
-** register P1. See the Lt opcode for additional information.
-*/
-/* Opcode: Ge P1 P2 P3 P4 P5
-**
-** This works just like the Lt opcode except that the jump is taken if
-** the content of register P3 is greater than or equal to the content of
-** register P1. See the Lt opcode for additional information.
-*/
-case OP_Eq: /* same as TK_EQ, jump, in1, in3 */
-case OP_Ne: /* same as TK_NE, jump, in1, in3 */
-case OP_Lt: /* same as TK_LT, jump, in1, in3 */
-case OP_Le: /* same as TK_LE, jump, in1, in3 */
-case OP_Gt: /* same as TK_GT, jump, in1, in3 */
-case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
-#if 0 /* local variables moved into u.ak */
- int res; /* Result of the comparison of pIn1 against pIn3 */
- char affinity; /* Affinity to use for comparison */
- u16 flags1; /* Copy of initial value of pIn1->flags */
- u16 flags3; /* Copy of initial value of pIn3->flags */
-#endif /* local variables moved into u.ak */
-
- pIn1 = &aMem[pOp->p1];
- pIn3 = &aMem[pOp->p3];
- u.ak.flags1 = pIn1->flags;
- u.ak.flags3 = pIn3->flags;
- if( (u.ak.flags1 | u.ak.flags3)&MEM_Null ){
- /* One or both operands are NULL */
- if( pOp->p5 & SQLITE_NULLEQ ){
- /* If SQLITE_NULLEQ is set (which will only happen if the operator is
- ** OP_Eq or OP_Ne) then take the jump or not depending on whether
- ** or not both operands are null.
- */
- assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
- assert( (u.ak.flags1 & MEM_Cleared)==0 );
- if( (u.ak.flags1&MEM_Null)!=0
- && (u.ak.flags3&MEM_Null)!=0
- && (u.ak.flags3&MEM_Cleared)==0
- ){
- u.ak.res = 0; /* Results are equal */
- }else{
- u.ak.res = 1; /* Results are not equal */
- }
- }else{
- /* SQLITE_NULLEQ is clear and at least one operand is NULL,
- ** then the result is always NULL.
- ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
- */
- if( pOp->p5 & SQLITE_STOREP2 ){
- pOut = &aMem[pOp->p2];
- MemSetTypeFlag(pOut, MEM_Null);
- REGISTER_TRACE(pOp->p2, pOut);
- }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
- pc = pOp->p2-1;
- }
- break;
- }
- }else{
- /* Neither operand is NULL. Do a comparison. */
- u.ak.affinity = pOp->p5 & SQLITE_AFF_MASK;
- if( u.ak.affinity ){
- applyAffinity(pIn1, u.ak.affinity, encoding);
- applyAffinity(pIn3, u.ak.affinity, encoding);
- if( db->mallocFailed ) goto no_mem;
- }
-
- assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
- ExpandBlob(pIn1);
- ExpandBlob(pIn3);
- u.ak.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
- }
- switch( pOp->opcode ){
- case OP_Eq: u.ak.res = u.ak.res==0; break;
- case OP_Ne: u.ak.res = u.ak.res!=0; break;
- case OP_Lt: u.ak.res = u.ak.res<0; break;
- case OP_Le: u.ak.res = u.ak.res<=0; break;
- case OP_Gt: u.ak.res = u.ak.res>0; break;
- default: u.ak.res = u.ak.res>=0; break;
- }
-
- if( pOp->p5 & SQLITE_STOREP2 ){
- pOut = &aMem[pOp->p2];
- memAboutToChange(p, pOut);
- MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = u.ak.res;
- REGISTER_TRACE(pOp->p2, pOut);
- }else if( u.ak.res ){
- pc = pOp->p2-1;
- }
-
- /* Undo any changes made by applyAffinity() to the input registers. */
- pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.ak.flags1&MEM_TypeMask);
- pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.ak.flags3&MEM_TypeMask);
- break;
-}
-
-/* Opcode: Permutation * * * P4 *
-**
-** Set the permutation used by the OP_Compare operator to be the array
-** of integers in P4.
-**
-** The permutation is only valid until the next OP_Compare that has
-** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
-** occur immediately prior to the OP_Compare.
-*/
-case OP_Permutation: {
- assert( pOp->p4type==P4_INTARRAY );
- assert( pOp->p4.ai );
- aPermute = pOp->p4.ai;
- break;
-}
-
-/* Opcode: Compare P1 P2 P3 P4 P5
-**
-** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
-** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of
-** the comparison for use by the next OP_Jump instruct.
-**
-** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is
-** determined by the most recent OP_Permutation operator. If the
-** OPFLAG_PERMUTE bit is clear, then register are compared in sequential
-** order.
-**
-** P4 is a KeyInfo structure that defines collating sequences and sort
-** orders for the comparison. The permutation applies to registers
-** only. The KeyInfo elements are used sequentially.
-**
-** The comparison is a sort comparison, so NULLs compare equal,
-** NULLs are less than numbers, numbers are less than strings,
-** and strings are less than blobs.
-*/
-case OP_Compare: {
-#if 0 /* local variables moved into u.al */
- int n;
- int i;
- int p1;
- int p2;
- const KeyInfo *pKeyInfo;
- int idx;
- CollSeq *pColl; /* Collating sequence to use on this term */
- int bRev; /* True for DESCENDING sort order */
-#endif /* local variables moved into u.al */
-
- if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
- u.al.n = pOp->p3;
- u.al.pKeyInfo = pOp->p4.pKeyInfo;
- assert( u.al.n>0 );
- assert( u.al.pKeyInfo!=0 );
- u.al.p1 = pOp->p1;
- u.al.p2 = pOp->p2;
-#if SQLITE_DEBUG
- if( aPermute ){
- int k, mx = 0;
- for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
- assert( u.al.p1>0 && u.al.p1+mx<=p->nMem+1 );
- assert( u.al.p2>0 && u.al.p2+mx<=p->nMem+1 );
- }else{
- assert( u.al.p1>0 && u.al.p1+u.al.n<=p->nMem+1 );
- assert( u.al.p2>0 && u.al.p2+u.al.n<=p->nMem+1 );
- }
-#endif /* SQLITE_DEBUG */
- for(u.al.i=0; u.al.i<u.al.n; u.al.i++){
- u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i;
- assert( memIsValid(&aMem[u.al.p1+u.al.idx]) );
- assert( memIsValid(&aMem[u.al.p2+u.al.idx]) );
- REGISTER_TRACE(u.al.p1+u.al.idx, &aMem[u.al.p1+u.al.idx]);
- REGISTER_TRACE(u.al.p2+u.al.idx, &aMem[u.al.p2+u.al.idx]);
- assert( u.al.i<u.al.pKeyInfo->nField );
- u.al.pColl = u.al.pKeyInfo->aColl[u.al.i];
- u.al.bRev = u.al.pKeyInfo->aSortOrder[u.al.i];
- iCompare = sqlite3MemCompare(&aMem[u.al.p1+u.al.idx], &aMem[u.al.p2+u.al.idx], u.al.pColl);
- if( iCompare ){
- if( u.al.bRev ) iCompare = -iCompare;
- break;
- }
- }
- aPermute = 0;
- break;
-}
-
-/* Opcode: Jump P1 P2 P3 * *
-**
-** Jump to the instruction at address P1, P2, or P3 depending on whether
-** in the most recent OP_Compare instruction the P1 vector was less than
-** equal to, or greater than the P2 vector, respectively.
-*/
-case OP_Jump: { /* jump */
- if( iCompare<0 ){
- pc = pOp->p1 - 1;
- }else if( iCompare==0 ){
- pc = pOp->p2 - 1;
- }else{
- pc = pOp->p3 - 1;
- }
- break;
-}
-
-/* Opcode: And P1 P2 P3 * *
-**
-** Take the logical AND of the values in registers P1 and P2 and
-** write the result into register P3.
-**
-** If either P1 or P2 is 0 (false) then the result is 0 even if
-** the other input is NULL. A NULL and true or two NULLs give
-** a NULL output.
-*/
-/* Opcode: Or P1 P2 P3 * *
-**
-** Take the logical OR of the values in register P1 and P2 and
-** store the answer in register P3.
-**
-** If either P1 or P2 is nonzero (true) then the result is 1 (true)
-** even if the other input is NULL. A NULL and false or two NULLs
-** give a NULL output.
-*/
-case OP_And: /* same as TK_AND, in1, in2, out3 */
-case OP_Or: { /* same as TK_OR, in1, in2, out3 */
-#if 0 /* local variables moved into u.am */
- int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
-#endif /* local variables moved into u.am */
-
- pIn1 = &aMem[pOp->p1];
- if( pIn1->flags & MEM_Null ){
- u.am.v1 = 2;
- }else{
- u.am.v1 = sqlite3VdbeIntValue(pIn1)!=0;
- }
- pIn2 = &aMem[pOp->p2];
- if( pIn2->flags & MEM_Null ){
- u.am.v2 = 2;
- }else{
- u.am.v2 = sqlite3VdbeIntValue(pIn2)!=0;
- }
- if( pOp->opcode==OP_And ){
- static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
- u.am.v1 = and_logic[u.am.v1*3+u.am.v2];
- }else{
- static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
- u.am.v1 = or_logic[u.am.v1*3+u.am.v2];
- }
- pOut = &aMem[pOp->p3];
- if( u.am.v1==2 ){
- MemSetTypeFlag(pOut, MEM_Null);
- }else{
- pOut->u.i = u.am.v1;
- MemSetTypeFlag(pOut, MEM_Int);
- }
- break;
-}
-
-/* Opcode: Not P1 P2 * * *
-**
-** Interpret the value in register P1 as a boolean value. Store the
-** boolean complement in register P2. If the value in register P1 is
-** NULL, then a NULL is stored in P2.
-*/
-case OP_Not: { /* same as TK_NOT, in1, out2 */
- pIn1 = &aMem[pOp->p1];
- pOut = &aMem[pOp->p2];
- if( pIn1->flags & MEM_Null ){
- sqlite3VdbeMemSetNull(pOut);
- }else{
- sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeIntValue(pIn1));
- }
- break;
-}
-
-/* Opcode: BitNot P1 P2 * * *
-**
-** Interpret the content of register P1 as an integer. Store the
-** ones-complement of the P1 value into register P2. If P1 holds
-** a NULL then store a NULL in P2.
-*/
-case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
- pIn1 = &aMem[pOp->p1];
- pOut = &aMem[pOp->p2];
- if( pIn1->flags & MEM_Null ){
- sqlite3VdbeMemSetNull(pOut);
- }else{
- sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1));
- }
- break;
-}
-
-/* Opcode: Once P1 P2 * * *
-**
-** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
-** set the flag and fall through to the next instruction.
-*/
-case OP_Once: { /* jump */
- assert( pOp->p1<p->nOnceFlag );
- if( p->aOnceFlag[pOp->p1] ){
- pc = pOp->p2-1;
- }else{
- p->aOnceFlag[pOp->p1] = 1;
- }
- break;
-}
-
-/* Opcode: If P1 P2 P3 * *
-**
-** Jump to P2 if the value in register P1 is true. The value
-** is considered true if it is numeric and non-zero. If the value
-** in P1 is NULL then take the jump if P3 is non-zero.
-*/
-/* Opcode: IfNot P1 P2 P3 * *
-**
-** Jump to P2 if the value in register P1 is False. The value
-** is considered false if it has a numeric value of zero. If the value
-** in P1 is NULL then take the jump if P3 is zero.
-*/
-case OP_If: /* jump, in1 */
-case OP_IfNot: { /* jump, in1 */
-#if 0 /* local variables moved into u.an */
- int c;
-#endif /* local variables moved into u.an */
- pIn1 = &aMem[pOp->p1];
- if( pIn1->flags & MEM_Null ){
- u.an.c = pOp->p3;
- }else{
-#ifdef SQLITE_OMIT_FLOATING_POINT
- u.an.c = sqlite3VdbeIntValue(pIn1)!=0;
-#else
- u.an.c = sqlite3VdbeRealValue(pIn1)!=0.0;
-#endif
- if( pOp->opcode==OP_IfNot ) u.an.c = !u.an.c;
- }
- if( u.an.c ){
- pc = pOp->p2-1;
- }
- break;
-}
-
-/* Opcode: IsNull P1 P2 * * *
-**
-** Jump to P2 if the value in register P1 is NULL.
-*/
-case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
- pIn1 = &aMem[pOp->p1];
- if( (pIn1->flags & MEM_Null)!=0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: NotNull P1 P2 * * *
-**
-** Jump to P2 if the value in register P1 is not NULL.
-*/
-case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
- pIn1 = &aMem[pOp->p1];
- if( (pIn1->flags & MEM_Null)==0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: Column P1 P2 P3 P4 P5
-**
-** Interpret the data that cursor P1 points to as a structure built using
-** the MakeRecord instruction. (See the MakeRecord opcode for additional
-** information about the format of the data.) Extract the P2-th column
-** from this record. If there are less that (P2+1)
-** values in the record, extract a NULL.
-**
-** The value extracted is stored in register P3.
-**
-** If the column contains fewer than P2 fields, then extract a NULL. Or,
-** if the P4 argument is a P4_MEM use the value of the P4 argument as
-** the result.
-**
-** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor,
-** then the cache of the cursor is reset prior to extracting the column.
-** The first OP_Column against a pseudo-table after the value of the content
-** register has changed should have this bit set.
-**
-** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when
-** the result is guaranteed to only be used as the argument of a length()
-** or typeof() function, respectively. The loading of large blobs can be
-** skipped for length() and all content loading can be skipped for typeof().
-*/
-case OP_Column: {
-#if 0 /* local variables moved into u.ao */
- u32 payloadSize; /* Number of bytes in the record */
- i64 payloadSize64; /* Number of bytes in the record */
- int p1; /* P1 value of the opcode */
- int p2; /* column number to retrieve */
- VdbeCursor *pC; /* The VDBE cursor */
- char *zRec; /* Pointer to complete record-data */
- BtCursor *pCrsr; /* The BTree cursor */
- u32 *aType; /* aType[i] holds the numeric type of the i-th column */
- u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
- int nField; /* number of fields in the record */
- int len; /* The length of the serialized data for the column */
- int i; /* Loop counter */
- char *zData; /* Part of the record being decoded */
- Mem *pDest; /* Where to write the extracted value */
- Mem sMem; /* For storing the record being decoded */
- u8 *zIdx; /* Index into header */
- u8 *zEndHdr; /* Pointer to first byte after the header */
- u32 offset; /* Offset into the data */
- u32 szField; /* Number of bytes in the content of a field */
- int szHdr; /* Size of the header size field at start of record */
- int avail; /* Number of bytes of available data */
- u32 t; /* A type code from the record header */
- Mem *pReg; /* PseudoTable input register */
-#endif /* local variables moved into u.ao */
-
-
- u.ao.p1 = pOp->p1;
- u.ao.p2 = pOp->p2;
- u.ao.pC = 0;
- memset(&u.ao.sMem, 0, sizeof(u.ao.sMem));
- assert( u.ao.p1<p->nCursor );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- u.ao.pDest = &aMem[pOp->p3];
- memAboutToChange(p, u.ao.pDest);
- u.ao.zRec = 0;
-
- /* This block sets the variable u.ao.payloadSize to be the total number of
- ** bytes in the record.
- **
- ** u.ao.zRec is set to be the complete text of the record if it is available.
- ** The complete record text is always available for pseudo-tables
- ** If the record is stored in a cursor, the complete record text
- ** might be available in the u.ao.pC->aRow cache. Or it might not be.
- ** If the data is unavailable, u.ao.zRec is set to NULL.
- **
- ** We also compute the number of columns in the record. For cursors,
- ** the number of columns is stored in the VdbeCursor.nField element.
- */
- u.ao.pC = p->apCsr[u.ao.p1];
- assert( u.ao.pC!=0 );
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- assert( u.ao.pC->pVtabCursor==0 );
-#endif
- u.ao.pCrsr = u.ao.pC->pCursor;
- if( u.ao.pCrsr!=0 ){
- /* The record is stored in a B-Tree */
- rc = sqlite3VdbeCursorMoveto(u.ao.pC);
- if( rc ) goto abort_due_to_error;
- if( u.ao.pC->nullRow ){
- u.ao.payloadSize = 0;
- }else if( u.ao.pC->cacheStatus==p->cacheCtr ){
- u.ao.payloadSize = u.ao.pC->payloadSize;
- u.ao.zRec = (char*)u.ao.pC->aRow;
- }else if( u.ao.pC->isIndex ){
- assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ao.pCrsr, &u.ao.payloadSize64);
- assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
- /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
- ** payload size, so it is impossible for u.ao.payloadSize64 to be
- ** larger than 32 bits. */
- assert( (u.ao.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ao.payloadSize64 );
- u.ao.payloadSize = (u32)u.ao.payloadSize64;
- }else{
- assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ao.pCrsr, &u.ao.payloadSize);
- assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- }
- }else if( ALWAYS(u.ao.pC->pseudoTableReg>0) ){
- u.ao.pReg = &aMem[u.ao.pC->pseudoTableReg];
- if( u.ao.pC->multiPseudo ){
- sqlite3VdbeMemShallowCopy(u.ao.pDest, u.ao.pReg+u.ao.p2, MEM_Ephem);
- Deephemeralize(u.ao.pDest);
- goto op_column_out;
- }
- assert( u.ao.pReg->flags & MEM_Blob );
- assert( memIsValid(u.ao.pReg) );
- u.ao.payloadSize = u.ao.pReg->n;
- u.ao.zRec = u.ao.pReg->z;
- u.ao.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
- assert( u.ao.payloadSize==0 || u.ao.zRec!=0 );
- }else{
- /* Consider the row to be NULL */
- u.ao.payloadSize = 0;
- }
-
- /* If u.ao.payloadSize is 0, then just store a NULL. This can happen because of
- ** nullRow or because of a corrupt database. */
- if( u.ao.payloadSize==0 ){
- MemSetTypeFlag(u.ao.pDest, MEM_Null);
- goto op_column_out;
- }
- assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
- if( u.ao.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
-
- u.ao.nField = u.ao.pC->nField;
- assert( u.ao.p2<u.ao.nField );
-
- /* Read and parse the table header. Store the results of the parse
- ** into the record header cache fields of the cursor.
- */
- u.ao.aType = u.ao.pC->aType;
- if( u.ao.pC->cacheStatus==p->cacheCtr ){
- u.ao.aOffset = u.ao.pC->aOffset;
- }else{
- assert(u.ao.aType);
- u.ao.avail = 0;
- u.ao.pC->aOffset = u.ao.aOffset = &u.ao.aType[u.ao.nField];
- u.ao.pC->payloadSize = u.ao.payloadSize;
- u.ao.pC->cacheStatus = p->cacheCtr;
-
- /* Figure out how many bytes are in the header */
- if( u.ao.zRec ){
- u.ao.zData = u.ao.zRec;
- }else{
- if( u.ao.pC->isIndex ){
- u.ao.zData = (char*)sqlite3BtreeKeyFetch(u.ao.pCrsr, &u.ao.avail);
- }else{
- u.ao.zData = (char*)sqlite3BtreeDataFetch(u.ao.pCrsr, &u.ao.avail);
- }
- /* If KeyFetch()/DataFetch() managed to get the entire payload,
- ** save the payload in the u.ao.pC->aRow cache. That will save us from
- ** having to make additional calls to fetch the content portion of
- ** the record.
- */
- assert( u.ao.avail>=0 );
- if( u.ao.payloadSize <= (u32)u.ao.avail ){
- u.ao.zRec = u.ao.zData;
- u.ao.pC->aRow = (u8*)u.ao.zData;
- }else{
- u.ao.pC->aRow = 0;
- }
- }
- /* The following assert is true in all cases except when
- ** the database file has been corrupted externally.
- ** assert( u.ao.zRec!=0 || u.ao.avail>=u.ao.payloadSize || u.ao.avail>=9 ); */
- u.ao.szHdr = getVarint32((u8*)u.ao.zData, u.ao.offset);
-
- /* Make sure a corrupt database has not given us an oversize header.
- ** Do this now to avoid an oversize memory allocation.
- **
- ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
- ** types use so much data space that there can only be 4096 and 32 of
- ** them, respectively. So the maximum header length results from a
- ** 3-byte type for each of the maximum of 32768 columns plus three
- ** extra bytes for the header length itself. 32768*3 + 3 = 98307.
- */
- if( u.ao.offset > 98307 ){
- rc = SQLITE_CORRUPT_BKPT;
- goto op_column_out;
- }
-
- /* Compute in u.ao.len the number of bytes of data we need to read in order
- ** to get u.ao.nField type values. u.ao.offset is an upper bound on this. But
- ** u.ao.nField might be significantly less than the true number of columns
- ** in the table, and in that case, 5*u.ao.nField+3 might be smaller than u.ao.offset.
- ** We want to minimize u.ao.len in order to limit the size of the memory
- ** allocation, especially if a corrupt database file has caused u.ao.offset
- ** to be oversized. Offset is limited to 98307 above. But 98307 might
- ** still exceed Robson memory allocation limits on some configurations.
- ** On systems that cannot tolerate large memory allocations, u.ao.nField*5+3
- ** will likely be much smaller since u.ao.nField will likely be less than
- ** 20 or so. This insures that Robson memory allocation limits are
- ** not exceeded even for corrupt database files.
- */
- u.ao.len = u.ao.nField*5 + 3;
- if( u.ao.len > (int)u.ao.offset ) u.ao.len = (int)u.ao.offset;
-
- /* The KeyFetch() or DataFetch() above are fast and will get the entire
- ** record header in most cases. But they will fail to get the complete
- ** record header if the record header does not fit on a single page
- ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to
- ** acquire the complete header text.
- */
- if( !u.ao.zRec && u.ao.avail<u.ao.len ){
- u.ao.sMem.flags = 0;
- u.ao.sMem.db = 0;
- rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, 0, u.ao.len, u.ao.pC->isIndex, &u.ao.sMem);
- if( rc!=SQLITE_OK ){
- goto op_column_out;
- }
- u.ao.zData = u.ao.sMem.z;
- }
- u.ao.zEndHdr = (u8 *)&u.ao.zData[u.ao.len];
- u.ao.zIdx = (u8 *)&u.ao.zData[u.ao.szHdr];
-
- /* Scan the header and use it to fill in the u.ao.aType[] and u.ao.aOffset[]
- ** arrays. u.ao.aType[u.ao.i] will contain the type integer for the u.ao.i-th
- ** column and u.ao.aOffset[u.ao.i] will contain the u.ao.offset from the beginning
- ** of the record to the start of the data for the u.ao.i-th column
- */
- for(u.ao.i=0; u.ao.i<u.ao.nField; u.ao.i++){
- if( u.ao.zIdx<u.ao.zEndHdr ){
- u.ao.aOffset[u.ao.i] = u.ao.offset;
- if( u.ao.zIdx[0]<0x80 ){
- u.ao.t = u.ao.zIdx[0];
- u.ao.zIdx++;
- }else{
- u.ao.zIdx += sqlite3GetVarint32(u.ao.zIdx, &u.ao.t);
- }
- u.ao.aType[u.ao.i] = u.ao.t;
- u.ao.szField = sqlite3VdbeSerialTypeLen(u.ao.t);
- u.ao.offset += u.ao.szField;
- if( u.ao.offset<u.ao.szField ){ /* True if u.ao.offset overflows */
- u.ao.zIdx = &u.ao.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */
- break;
- }
- }else{
- /* If u.ao.i is less that u.ao.nField, then there are fewer fields in this
- ** record than SetNumColumns indicated there are columns in the
- ** table. Set the u.ao.offset for any extra columns not present in
- ** the record to 0. This tells code below to store the default value
- ** for the column instead of deserializing a value from the record.
- */
- u.ao.aOffset[u.ao.i] = 0;
- }
- }
- sqlite3VdbeMemRelease(&u.ao.sMem);
- u.ao.sMem.flags = MEM_Null;
-
- /* If we have read more header data than was contained in the header,
- ** or if the end of the last field appears to be past the end of the
- ** record, or if the end of the last field appears to be before the end
- ** of the record (when all fields present), then we must be dealing
- ** with a corrupt database.
- */
- if( (u.ao.zIdx > u.ao.zEndHdr) || (u.ao.offset > u.ao.payloadSize)
- || (u.ao.zIdx==u.ao.zEndHdr && u.ao.offset!=u.ao.payloadSize) ){
- rc = SQLITE_CORRUPT_BKPT;
- goto op_column_out;
- }
- }
-
- /* Get the column information. If u.ao.aOffset[u.ao.p2] is non-zero, then
- ** deserialize the value from the record. If u.ao.aOffset[u.ao.p2] is zero,
- ** then there are not enough fields in the record to satisfy the
- ** request. In this case, set the value NULL or to P4 if P4 is
- ** a pointer to a Mem object.
- */
- if( u.ao.aOffset[u.ao.p2] ){
- assert( rc==SQLITE_OK );
- if( u.ao.zRec ){
- /* This is the common case where the whole row fits on a single page */
- VdbeMemRelease(u.ao.pDest);
- sqlite3VdbeSerialGet((u8 *)&u.ao.zRec[u.ao.aOffset[u.ao.p2]], u.ao.aType[u.ao.p2], u.ao.pDest);
- }else{
- /* This branch happens only when the row overflows onto multiple pages */
- u.ao.t = u.ao.aType[u.ao.p2];
- if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
- && ((u.ao.t>=12 && (u.ao.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)
- ){
- /* Content is irrelevant for the typeof() function and for
- ** the length(X) function if X is a blob. So we might as well use
- ** bogus content rather than reading content from disk. NULL works
- ** for text and blob and whatever is in the u.ao.payloadSize64 variable
- ** will work for everything else. */
- u.ao.zData = u.ao.t<12 ? (char*)&u.ao.payloadSize64 : 0;
- }else{
- u.ao.len = sqlite3VdbeSerialTypeLen(u.ao.t);
- sqlite3VdbeMemMove(&u.ao.sMem, u.ao.pDest);
- rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, u.ao.aOffset[u.ao.p2], u.ao.len, u.ao.pC->isIndex,
- &u.ao.sMem);
- if( rc!=SQLITE_OK ){
- goto op_column_out;
- }
- u.ao.zData = u.ao.sMem.z;
- }
- sqlite3VdbeSerialGet((u8*)u.ao.zData, u.ao.t, u.ao.pDest);
- }
- u.ao.pDest->enc = encoding;
- }else{
- if( pOp->p4type==P4_MEM ){
- sqlite3VdbeMemShallowCopy(u.ao.pDest, pOp->p4.pMem, MEM_Static);
- }else{
- MemSetTypeFlag(u.ao.pDest, MEM_Null);
- }
- }
-
- /* If we dynamically allocated space to hold the data (in the
- ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
- ** dynamically allocated space over to the u.ao.pDest structure.
- ** This prevents a memory copy.
- */
- if( u.ao.sMem.zMalloc ){
- assert( u.ao.sMem.z==u.ao.sMem.zMalloc );
- assert( !(u.ao.pDest->flags & MEM_Dyn) );
- assert( !(u.ao.pDest->flags & (MEM_Blob|MEM_Str)) || u.ao.pDest->z==u.ao.sMem.z );
- u.ao.pDest->flags &= ~(MEM_Ephem|MEM_Static);
- u.ao.pDest->flags |= MEM_Term;
- u.ao.pDest->z = u.ao.sMem.z;
- u.ao.pDest->zMalloc = u.ao.sMem.zMalloc;
- }
-
- rc = sqlite3VdbeMemMakeWriteable(u.ao.pDest);
-
-op_column_out:
- UPDATE_MAX_BLOBSIZE(u.ao.pDest);
- REGISTER_TRACE(pOp->p3, u.ao.pDest);
- break;
-}
-
-/* Opcode: Affinity P1 P2 * P4 *
-**
-** Apply affinities to a range of P2 registers starting with P1.
-**
-** P4 is a string that is P2 characters long. The nth character of the
-** string indicates the column affinity that should be used for the nth
-** memory cell in the range.
-*/
-case OP_Affinity: {
-#if 0 /* local variables moved into u.ap */
- const char *zAffinity; /* The affinity to be applied */
- char cAff; /* A single character of affinity */
-#endif /* local variables moved into u.ap */
-
- u.ap.zAffinity = pOp->p4.z;
- assert( u.ap.zAffinity!=0 );
- assert( u.ap.zAffinity[pOp->p2]==0 );
- pIn1 = &aMem[pOp->p1];
- while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){
- assert( pIn1 <= &p->aMem[p->nMem] );
- assert( memIsValid(pIn1) );
- ExpandBlob(pIn1);
- applyAffinity(pIn1, u.ap.cAff, encoding);
- pIn1++;
- }
- break;
-}
-
-/* Opcode: MakeRecord P1 P2 P3 P4 *
-**
-** Convert P2 registers beginning with P1 into the [record format]
-** use as a data record in a database table or as a key
-** in an index. The OP_Column opcode can decode the record later.
-**
-** P4 may be a string that is P2 characters long. The nth character of the
-** string indicates the column affinity that should be used for the nth
-** field of the index key.
-**
-** The mapping from character to affinity is given by the SQLITE_AFF_
-** macros defined in sqliteInt.h.
-**
-** If P4 is NULL then all index fields have the affinity NONE.
-*/
-case OP_MakeRecord: {
-#if 0 /* local variables moved into u.aq */
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
- Mem *pRec; /* The new record */
- u64 nData; /* Number of bytes of data space */
- int nHdr; /* Number of bytes of header space */
- i64 nByte; /* Data space required for this record */
- int nZero; /* Number of zero bytes at the end of the record */
- int nVarint; /* Number of bytes in a varint */
- u32 serial_type; /* Type field */
- Mem *pData0; /* First field to be combined into the record */
- Mem *pLast; /* Last field of the record */
- int nField; /* Number of fields in the record */
- char *zAffinity; /* The affinity string for the record */
- int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] */
- int len; /* Length of a field */
-#endif /* local variables moved into u.aq */
-
- /* Assuming the record contains N fields, the record format looks
- ** like this:
- **
- ** ------------------------------------------------------------------------
- ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
- ** ------------------------------------------------------------------------
- **
- ** Data(0) is taken from register P1. Data(1) comes from register P1+1
- ** and so froth.
- **
- ** Each type field is a varint representing the serial type of the
- ** corresponding data element (see sqlite3VdbeSerialType()). The
- ** hdr-size field is also a varint which is the offset from the beginning
- ** of the record to data0.
- */
- u.aq.nData = 0; /* Number of bytes of data space */
- u.aq.nHdr = 0; /* Number of bytes of header space */
- u.aq.nZero = 0; /* Number of zero bytes at the end of the record */
- u.aq.nField = pOp->p1;
- u.aq.zAffinity = pOp->p4.z;
- assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 );
- u.aq.pData0 = &aMem[u.aq.nField];
- u.aq.nField = pOp->p2;
- u.aq.pLast = &u.aq.pData0[u.aq.nField-1];
- u.aq.file_format = p->minWriteFileFormat;
-
- /* Identify the output register */
- assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
- pOut = &aMem[pOp->p3];
- memAboutToChange(p, pOut);
-
- /* Loop through the elements that will make up the record to figure
- ** out how much space is required for the new record.
- */
- for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
- assert( memIsValid(u.aq.pRec) );
- if( u.aq.zAffinity ){
- applyAffinity(u.aq.pRec, u.aq.zAffinity[u.aq.pRec-u.aq.pData0], encoding);
- }
- if( u.aq.pRec->flags&MEM_Zero && u.aq.pRec->n>0 ){
- sqlite3VdbeMemExpandBlob(u.aq.pRec);
- }
- u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
- u.aq.len = sqlite3VdbeSerialTypeLen(u.aq.serial_type);
- u.aq.nData += u.aq.len;
- u.aq.nHdr += sqlite3VarintLen(u.aq.serial_type);
- if( u.aq.pRec->flags & MEM_Zero ){
- /* Only pure zero-filled BLOBs can be input to this Opcode.
- ** We do not allow blobs with a prefix and a zero-filled tail. */
- u.aq.nZero += u.aq.pRec->u.nZero;
- }else if( u.aq.len ){
- u.aq.nZero = 0;
- }
- }
-
- /* Add the initial header varint and total the size */
- u.aq.nHdr += u.aq.nVarint = sqlite3VarintLen(u.aq.nHdr);
- if( u.aq.nVarint<sqlite3VarintLen(u.aq.nHdr) ){
- u.aq.nHdr++;
- }
- u.aq.nByte = u.aq.nHdr+u.aq.nData-u.aq.nZero;
- if( u.aq.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
-
- /* Make sure the output register has a buffer large enough to store
- ** the new record. The output register (pOp->p3) is not allowed to
- ** be one of the input registers (because the following call to
- ** sqlite3VdbeMemGrow() could clobber the value before it is used).
- */
- if( sqlite3VdbeMemGrow(pOut, (int)u.aq.nByte, 0) ){
- goto no_mem;
- }
- u.aq.zNewRecord = (u8 *)pOut->z;
-
- /* Write the record */
- u.aq.i = putVarint32(u.aq.zNewRecord, u.aq.nHdr);
- for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
- u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
- u.aq.i += putVarint32(&u.aq.zNewRecord[u.aq.i], u.aq.serial_type); /* serial type */
- }
- for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ /* serial data */
- u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format);
- }
- assert( u.aq.i==u.aq.nByte );
-
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pOut->n = (int)u.aq.nByte;
- pOut->flags = MEM_Blob | MEM_Dyn;
- pOut->xDel = 0;
- if( u.aq.nZero ){
- pOut->u.nZero = u.aq.nZero;
- pOut->flags |= MEM_Zero;
- }
- pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
- REGISTER_TRACE(pOp->p3, pOut);
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Count P1 P2 * * *
-**
-** Store the number of entries (an integer value) in the table or index
-** opened by cursor P1 in register P2
-*/
-#ifndef SQLITE_OMIT_BTREECOUNT
-case OP_Count: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ar */
- i64 nEntry;
- BtCursor *pCrsr;
-#endif /* local variables moved into u.ar */
-
- u.ar.pCrsr = p->apCsr[pOp->p1]->pCursor;
- if( ALWAYS(u.ar.pCrsr) ){
- rc = sqlite3BtreeCount(u.ar.pCrsr, &u.ar.nEntry);
- }else{
- u.ar.nEntry = 0;
- }
- pOut->u.i = u.ar.nEntry;
- break;
-}
-#endif
-
-/* Opcode: Savepoint P1 * * P4 *
-**
-** Open, release or rollback the savepoint named by parameter P4, depending
-** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
-** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
-*/
-case OP_Savepoint: {
-#if 0 /* local variables moved into u.as */
- int p1; /* Value of P1 operand */
- char *zName; /* Name of savepoint */
- int nName;
- Savepoint *pNew;
- Savepoint *pSavepoint;
- Savepoint *pTmp;
- int iSavepoint;
- int ii;
-#endif /* local variables moved into u.as */
-
- u.as.p1 = pOp->p1;
- u.as.zName = pOp->p4.z;
-
- /* Assert that the u.as.p1 parameter is valid. Also that if there is no open
- ** transaction, then there cannot be any savepoints.
- */
- assert( db->pSavepoint==0 || db->autoCommit==0 );
- assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK );
- assert( db->pSavepoint || db->isTransactionSavepoint==0 );
- assert( checkSavepointCount(db) );
-
- if( u.as.p1==SAVEPOINT_BEGIN ){
- if( db->writeVdbeCnt>0 ){
- /* A new savepoint cannot be created if there are active write
- ** statements (i.e. open read/write incremental blob handles).
- */
- sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
- "SQL statements in progress");
- rc = SQLITE_BUSY;
- }else{
- u.as.nName = sqlite3Strlen30(u.as.zName);
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- /* This call is Ok even if this savepoint is actually a transaction
- ** savepoint (and therefore should not prompt xSavepoint()) callbacks.
- ** If this is a transaction savepoint being opened, it is guaranteed
- ** that the db->aVTrans[] array is empty. */
- assert( db->autoCommit==0 || db->nVTrans==0 );
- rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN,
- db->nStatement+db->nSavepoint);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
-#endif
-
- /* Create a new savepoint structure. */
- u.as.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.as.nName+1);
- if( u.as.pNew ){
- u.as.pNew->zName = (char *)&u.as.pNew[1];
- memcpy(u.as.pNew->zName, u.as.zName, u.as.nName+1);
-
- /* If there is no open transaction, then mark this as a special
- ** "transaction savepoint". */
- if( db->autoCommit ){
- db->autoCommit = 0;
- db->isTransactionSavepoint = 1;
- }else{
- db->nSavepoint++;
- }
-
- /* Link the new savepoint into the database handle's list. */
- u.as.pNew->pNext = db->pSavepoint;
- db->pSavepoint = u.as.pNew;
- u.as.pNew->nDeferredCons = db->nDeferredCons;
- }
- }
- }else{
- u.as.iSavepoint = 0;
-
- /* Find the named savepoint. If there is no such savepoint, then an
- ** an error is returned to the user. */
- for(
- u.as.pSavepoint = db->pSavepoint;
- u.as.pSavepoint && sqlite3StrICmp(u.as.pSavepoint->zName, u.as.zName);
- u.as.pSavepoint = u.as.pSavepoint->pNext
- ){
- u.as.iSavepoint++;
- }
- if( !u.as.pSavepoint ){
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName);
- rc = SQLITE_ERROR;
- }else if( db->writeVdbeCnt>0 && u.as.p1==SAVEPOINT_RELEASE ){
- /* It is not possible to release (commit) a savepoint if there are
- ** active write statements.
- */
- sqlite3SetString(&p->zErrMsg, db,
- "cannot release savepoint - SQL statements in progress"
- );
- rc = SQLITE_BUSY;
- }else{
-
- /* Determine whether or not this is a transaction savepoint. If so,
- ** and this is a RELEASE command, then the current transaction
- ** is committed.
- */
- int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint;
- if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){
- if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
- goto vdbe_return;
- }
- db->autoCommit = 1;
- if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = pc;
- db->autoCommit = 0;
- p->rc = rc = SQLITE_BUSY;
- goto vdbe_return;
- }
- db->isTransactionSavepoint = 0;
- rc = p->rc;
- }else{
- u.as.iSavepoint = db->nSavepoint - u.as.iSavepoint - 1;
- if( u.as.p1==SAVEPOINT_ROLLBACK ){
- for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){
- sqlite3BtreeTripAllCursors(db->aDb[u.as.ii].pBt, SQLITE_ABORT);
- }
- }
- for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){
- rc = sqlite3BtreeSavepoint(db->aDb[u.as.ii].pBt, u.as.p1, u.as.iSavepoint);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- }
- if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
- sqlite3ExpirePreparedStatements(db);
- sqlite3ResetAllSchemasOfConnection(db);
- db->flags = (db->flags | SQLITE_InternChanges);
- }
- }
-
- /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
- ** savepoints nested inside of the savepoint being operated on. */
- while( db->pSavepoint!=u.as.pSavepoint ){
- u.as.pTmp = db->pSavepoint;
- db->pSavepoint = u.as.pTmp->pNext;
- sqlite3DbFree(db, u.as.pTmp);
- db->nSavepoint--;
- }
-
- /* If it is a RELEASE, then destroy the savepoint being operated on
- ** too. If it is a ROLLBACK TO, then set the number of deferred
- ** constraint violations present in the database to the value stored
- ** when the savepoint was created. */
- if( u.as.p1==SAVEPOINT_RELEASE ){
- assert( u.as.pSavepoint==db->pSavepoint );
- db->pSavepoint = u.as.pSavepoint->pNext;
- sqlite3DbFree(db, u.as.pSavepoint);
- if( !isTransaction ){
- db->nSavepoint--;
- }
- }else{
- db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
- }
-
- if( !isTransaction ){
- rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }
- }
-
- break;
-}
-
-/* Opcode: AutoCommit P1 P2 * * *
-**
-** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
-** back any currently active btree transactions. If there are any active
-** VMs (apart from this one), then a ROLLBACK fails. A COMMIT fails if
-** there are active writing VMs or active VMs that use shared cache.
-**
-** This instruction causes the VM to halt.
-*/
-case OP_AutoCommit: {
-#if 0 /* local variables moved into u.at */
- int desiredAutoCommit;
- int iRollback;
- int turnOnAC;
-#endif /* local variables moved into u.at */
-
- u.at.desiredAutoCommit = pOp->p1;
- u.at.iRollback = pOp->p2;
- u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit;
- assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 );
- assert( u.at.desiredAutoCommit==1 || u.at.iRollback==0 );
- assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */
-
-#if 0
- if( u.at.turnOnAC && u.at.iRollback && db->activeVdbeCnt>1 ){
- /* If this instruction implements a ROLLBACK and other VMs are
- ** still running, and a transaction is active, return an error indicating
- ** that the other VMs must complete first.
- */
- sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
- "SQL statements in progress");
- rc = SQLITE_BUSY;
- }else
-#endif
- if( u.at.turnOnAC && !u.at.iRollback && db->writeVdbeCnt>0 ){
- /* If this instruction implements a COMMIT and other VMs are writing
- ** return an error indicating that the other VMs must complete first.
- */
- sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
- "SQL statements in progress");
- rc = SQLITE_BUSY;
- }else if( u.at.desiredAutoCommit!=db->autoCommit ){
- if( u.at.iRollback ){
- assert( u.at.desiredAutoCommit==1 );
- sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
- db->autoCommit = 1;
- }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
- goto vdbe_return;
- }else{
- db->autoCommit = (u8)u.at.desiredAutoCommit;
- if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
- p->pc = pc;
- db->autoCommit = (u8)(1-u.at.desiredAutoCommit);
- p->rc = rc = SQLITE_BUSY;
- goto vdbe_return;
- }
- }
- assert( db->nStatement==0 );
- sqlite3CloseSavepoints(db);
- if( p->rc==SQLITE_OK ){
- rc = SQLITE_DONE;
- }else{
- rc = SQLITE_ERROR;
- }
- goto vdbe_return;
- }else{
- sqlite3SetString(&p->zErrMsg, db,
- (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":(
- (u.at.iRollback)?"cannot rollback - no transaction is active":
- "cannot commit - no transaction is active"));
-
- rc = SQLITE_ERROR;
- }
- break;
-}
-
-/* Opcode: Transaction P1 P2 * * *
-**
-** Begin a transaction. The transaction ends when a Commit or Rollback
-** opcode is encountered. Depending on the ON CONFLICT setting, the
-** transaction might also be rolled back if an error is encountered.
-**
-** P1 is the index of the database file on which the transaction is
-** started. Index 0 is the main database file and index 1 is the
-** file used for temporary tables. Indices of 2 or more are used for
-** attached databases.
-**
-** If P2 is non-zero, then a write-transaction is started. A RESERVED lock is
-** obtained on the database file when a write-transaction is started. No
-** other process can start another write transaction while this transaction is
-** underway. Starting a write transaction also creates a rollback journal. A
-** write transaction must be started before any changes can be made to the
-** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
-** on the file.
-**
-** If a write-transaction is started and the Vdbe.usesStmtJournal flag is
-** true (this flag is set if the Vdbe may modify more than one row and may
-** throw an ABORT exception), a statement transaction may also be opened.
-** More specifically, a statement transaction is opened iff the database
-** connection is currently not in autocommit mode, or if there are other
-** active statements. A statement transaction allows the changes made by this
-** VDBE to be rolled back after an error without having to roll back the
-** entire transaction. If no error is encountered, the statement transaction
-** will automatically commit when the VDBE halts.
-**
-** If P2 is zero, then a read-lock is obtained on the database file.
-*/
-case OP_Transaction: {
-#if 0 /* local variables moved into u.au */
- Btree *pBt;
-#endif /* local variables moved into u.au */
-
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
- u.au.pBt = db->aDb[pOp->p1].pBt;
-
- if( u.au.pBt ){
- rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2);
- if( rc==SQLITE_BUSY ){
- p->pc = pc;
- p->rc = rc = SQLITE_BUSY;
- goto vdbe_return;
- }
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
-
- if( pOp->p2 && p->usesStmtJournal
- && (db->autoCommit==0 || db->activeVdbeCnt>1)
- ){
- assert( sqlite3BtreeIsInTrans(u.au.pBt) );
- if( p->iStatement==0 ){
- assert( db->nStatement>=0 && db->nSavepoint>=0 );
- db->nStatement++;
- p->iStatement = db->nSavepoint + db->nStatement;
- }
-
- rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1);
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginStmt(u.au.pBt, p->iStatement);
- }
-
- /* Store the current value of the database handles deferred constraint
- ** counter. If the statement transaction needs to be rolled back,
- ** the value of this counter needs to be restored too. */
- p->nStmtDefCons = db->nDeferredCons;
- }
- }
- break;
-}
-
-/* Opcode: ReadCookie P1 P2 P3 * *
-**
-** Read cookie number P3 from database P1 and write it into register P2.
-** P3==1 is the schema version. P3==2 is the database format.
-** P3==3 is the recommended pager cache size, and so forth. P1==0 is
-** the main database file and P1==1 is the database file used to store
-** temporary tables.
-**
-** There must be a read-lock on the database (either a transaction
-** must be started or there must be an open cursor) before
-** executing this instruction.
-*/
-case OP_ReadCookie: { /* out2-prerelease */
-#if 0 /* local variables moved into u.av */
- int iMeta;
- int iDb;
- int iCookie;
-#endif /* local variables moved into u.av */
-
- u.av.iDb = pOp->p1;
- u.av.iCookie = pOp->p3;
- assert( pOp->p3<SQLITE_N_BTREE_META );
- assert( u.av.iDb>=0 && u.av.iDb<db->nDb );
- assert( db->aDb[u.av.iDb].pBt!=0 );
- assert( (p->btreeMask & (((yDbMask)1)<<u.av.iDb))!=0 );
-
- sqlite3BtreeGetMeta(db->aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta);
- pOut->u.i = u.av.iMeta;
- break;
-}
-
-/* Opcode: SetCookie P1 P2 P3 * *
-**
-** Write the content of register P3 (interpreted as an integer)
-** into cookie number P2 of database P1. P2==1 is the schema version.
-** P2==2 is the database format. P2==3 is the recommended pager cache
-** size, and so forth. P1==0 is the main database file and P1==1 is the
-** database file used to store temporary tables.
-**
-** A transaction must be started before executing this opcode.
-*/
-case OP_SetCookie: { /* in3 */
-#if 0 /* local variables moved into u.aw */
- Db *pDb;
-#endif /* local variables moved into u.aw */
- assert( pOp->p2<SQLITE_N_BTREE_META );
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
- u.aw.pDb = &db->aDb[pOp->p1];
- assert( u.aw.pDb->pBt!=0 );
- assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
- pIn3 = &aMem[pOp->p3];
- sqlite3VdbeMemIntegerify(pIn3);
- /* See note about index shifting on OP_ReadCookie */
- rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i);
- if( pOp->p2==BTREE_SCHEMA_VERSION ){
- /* When the schema cookie changes, record the new cookie internally */
- u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
- db->flags |= SQLITE_InternChanges;
- }else if( pOp->p2==BTREE_FILE_FORMAT ){
- /* Record changes in the file format */
- u.aw.pDb->pSchema->file_format = (u8)pIn3->u.i;
- }
- if( pOp->p1==1 ){
- /* Invalidate all prepared statements whenever the TEMP database
- ** schema is changed. Ticket #1644 */
- sqlite3ExpirePreparedStatements(db);
- p->expired = 0;
- }
- break;
-}
-
-/* Opcode: VerifyCookie P1 P2 P3 * *
-**
-** Check the value of global database parameter number 0 (the
-** schema version) and make sure it is equal to P2 and that the
-** generation counter on the local schema parse equals P3.
-**
-** P1 is the database number which is 0 for the main database file
-** and 1 for the file holding temporary tables and some higher number
-** for auxiliary databases.
-**
-** The cookie changes its value whenever the database schema changes.
-** This operation is used to detect when that the cookie has changed
-** and that the current process needs to reread the schema.
-**
-** Either a transaction needs to have been started or an OP_Open needs
-** to be executed (to establish a read lock) before this opcode is
-** invoked.
-*/
-case OP_VerifyCookie: {
-#if 0 /* local variables moved into u.ax */
- int iMeta;
- int iGen;
- Btree *pBt;
-#endif /* local variables moved into u.ax */
-
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
- assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
- u.ax.pBt = db->aDb[pOp->p1].pBt;
- if( u.ax.pBt ){
- sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta);
- u.ax.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
- }else{
- u.ax.iGen = u.ax.iMeta = 0;
- }
- if( u.ax.iMeta!=pOp->p2 || u.ax.iGen!=pOp->p3 ){
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
- /* If the schema-cookie from the database file matches the cookie
- ** stored with the in-memory representation of the schema, do
- ** not reload the schema from the database file.
- **
- ** If virtual-tables are in use, this is not just an optimization.
- ** Often, v-tables store their data in other SQLite tables, which
- ** are queried from within xNext() and other v-table methods using
- ** prepared queries. If such a query is out-of-date, we do not want to
- ** discard the database schema, as the user code implementing the
- ** v-table would have to be ready for the sqlite3_vtab structure itself
- ** to be invalidated whenever sqlite3_step() is called from within
- ** a v-table method.
- */
- if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){
- sqlite3ResetOneSchema(db, pOp->p1);
- }
-
- p->expired = 1;
- rc = SQLITE_SCHEMA;
- }
- break;
-}
-
-/* Opcode: OpenRead P1 P2 P3 P4 P5
-**
-** Open a read-only cursor for the database table whose root page is
-** P2 in a database file. The database file is determined by P3.
-** P3==0 means the main database, P3==1 means the database used for
-** temporary tables, and P3>1 means used the corresponding attached
-** database. Give the new cursor an identifier of P1. The P1
-** values need not be contiguous but all P1 values should be small integers.
-** It is an error for P1 to be negative.
-**
-** If P5!=0 then use the content of register P2 as the root page, not
-** the value of P2 itself.
-**
-** There will be a read lock on the database whenever there is an
-** open cursor. If the database was unlocked prior to this instruction
-** then a read lock is acquired as part of this instruction. A read
-** lock allows other processes to read the database but prohibits
-** any other process from modifying the database. The read lock is
-** released when all cursors are closed. If this instruction attempts
-** to get a read lock but fails, the script terminates with an
-** SQLITE_BUSY error code.
-**
-** The P4 value may be either an integer (P4_INT32) or a pointer to
-** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
-** structure, then said structure defines the content and collating
-** sequence of the index being opened. Otherwise, if P4 is an integer
-** value, it is set to the number of columns in the table.
-**
-** See also OpenWrite.
-*/
-/* Opcode: OpenWrite P1 P2 P3 P4 P5
-**
-** Open a read/write cursor named P1 on the table or index whose root
-** page is P2. Or if P5!=0 use the content of register P2 to find the
-** root page.
-**
-** The P4 value may be either an integer (P4_INT32) or a pointer to
-** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
-** structure, then said structure defines the content and collating
-** sequence of the index being opened. Otherwise, if P4 is an integer
-** value, it is set to the number of columns in the table, or to the
-** largest index of any column of the table that is actually used.
-**
-** This instruction works just like OpenRead except that it opens the cursor
-** in read/write mode. For a given table, there can be one or more read-only
-** cursors or a single read/write cursor but not both.
-**
-** See also OpenRead.
-*/
-case OP_OpenRead:
-case OP_OpenWrite: {
-#if 0 /* local variables moved into u.ay */
- int nField;
- KeyInfo *pKeyInfo;
- int p2;
- int iDb;
- int wrFlag;
- Btree *pX;
- VdbeCursor *pCur;
- Db *pDb;
-#endif /* local variables moved into u.ay */
-
- assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
- assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
-
- if( p->expired ){
- rc = SQLITE_ABORT;
- break;
- }
-
- u.ay.nField = 0;
- u.ay.pKeyInfo = 0;
- u.ay.p2 = pOp->p2;
- u.ay.iDb = pOp->p3;
- assert( u.ay.iDb>=0 && u.ay.iDb<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<u.ay.iDb))!=0 );
- u.ay.pDb = &db->aDb[u.ay.iDb];
- u.ay.pX = u.ay.pDb->pBt;
- assert( u.ay.pX!=0 );
- if( pOp->opcode==OP_OpenWrite ){
- u.ay.wrFlag = 1;
- assert( sqlite3SchemaMutexHeld(db, u.ay.iDb, 0) );
- if( u.ay.pDb->pSchema->file_format < p->minWriteFileFormat ){
- p->minWriteFileFormat = u.ay.pDb->pSchema->file_format;
- }
- }else{
- u.ay.wrFlag = 0;
- }
- if( pOp->p5 & OPFLAG_P2ISREG ){
- assert( u.ay.p2>0 );
- assert( u.ay.p2<=p->nMem );
- pIn2 = &aMem[u.ay.p2];
- assert( memIsValid(pIn2) );
- assert( (pIn2->flags & MEM_Int)!=0 );
- sqlite3VdbeMemIntegerify(pIn2);
- u.ay.p2 = (int)pIn2->u.i;
- /* The u.ay.p2 value always comes from a prior OP_CreateTable opcode and
- ** that opcode will always set the u.ay.p2 value to 2 or more or else fail.
- ** If there were a failure, the prepared statement would have halted
- ** before reaching this instruction. */
- if( NEVER(u.ay.p2<2) ) {
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
- }
- }
- if( pOp->p4type==P4_KEYINFO ){
- u.ay.pKeyInfo = pOp->p4.pKeyInfo;
- u.ay.pKeyInfo->enc = ENC(p->db);
- u.ay.nField = u.ay.pKeyInfo->nField+1;
- }else if( pOp->p4type==P4_INT32 ){
- u.ay.nField = pOp->p4.i;
- }
- assert( pOp->p1>=0 );
- u.ay.pCur = allocateCursor(p, pOp->p1, u.ay.nField, u.ay.iDb, 1);
- if( u.ay.pCur==0 ) goto no_mem;
- u.ay.pCur->nullRow = 1;
- u.ay.pCur->isOrdered = 1;
- rc = sqlite3BtreeCursor(u.ay.pX, u.ay.p2, u.ay.wrFlag, u.ay.pKeyInfo, u.ay.pCur->pCursor);
- u.ay.pCur->pKeyInfo = u.ay.pKeyInfo;
- assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
- sqlite3BtreeCursorHints(u.ay.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
-
- /* Since it performs no memory allocation or IO, the only value that
- ** sqlite3BtreeCursor() may return is SQLITE_OK. */
- assert( rc==SQLITE_OK );
-
- /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of
- ** SQLite used to check if the root-page flags were sane at this point
- ** and report database corruption if they were not, but this check has
- ** since moved into the btree layer. */
- u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO;
- u.ay.pCur->isIndex = !u.ay.pCur->isTable;
- break;
-}
-
-/* Opcode: OpenEphemeral P1 P2 * P4 P5
-**
-** Open a new cursor P1 to a transient table.
-** The cursor is always opened read/write even if
-** the main database is read-only. The ephemeral
-** table is deleted automatically when the cursor is closed.
-**
-** P2 is the number of columns in the ephemeral table.
-** The cursor points to a BTree table if P4==0 and to a BTree index
-** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure
-** that defines the format of keys in the index.
-**
-** This opcode was once called OpenTemp. But that created
-** confusion because the term "temp table", might refer either
-** to a TEMP table at the SQL level, or to a table opened by
-** this opcode. Then this opcode was call OpenVirtual. But
-** that created confusion with the whole virtual-table idea.
-**
-** The P5 parameter can be a mask of the BTREE_* flags defined
-** in btree.h. These flags control aspects of the operation of
-** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are
-** added automatically.
-*/
-/* Opcode: OpenAutoindex P1 P2 * P4 *
-**
-** This opcode works the same as OP_OpenEphemeral. It has a
-** different name to distinguish its use. Tables created using
-** by this opcode will be used for automatically created transient
-** indices in joins.
-*/
-case OP_OpenAutoindex:
-case OP_OpenEphemeral: {
-#if 0 /* local variables moved into u.az */
- VdbeCursor *pCx;
-#endif /* local variables moved into u.az */
- static const int vfsFlags =
- SQLITE_OPEN_READWRITE |
- SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE |
- SQLITE_OPEN_DELETEONCLOSE |
- SQLITE_OPEN_TRANSIENT_DB;
-
- assert( pOp->p1>=0 );
- u.az.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
- if( u.az.pCx==0 ) goto no_mem;
- u.az.pCx->nullRow = 1;
- rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.az.pCx->pBt,
- BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1);
- }
- if( rc==SQLITE_OK ){
- /* If a transient index is required, create it by calling
- ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
- ** opening it. If a transient table is required, just use the
- ** automatically created table with root-page 1 (an BLOB_INTKEY table).
- */
- if( pOp->p4.pKeyInfo ){
- int pgno;
- assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
- if( rc==SQLITE_OK ){
- assert( pgno==MASTER_ROOT+1 );
- rc = sqlite3BtreeCursor(u.az.pCx->pBt, pgno, 1,
- (KeyInfo*)pOp->p4.z, u.az.pCx->pCursor);
- u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo;
- u.az.pCx->pKeyInfo->enc = ENC(p->db);
- }
- u.az.pCx->isTable = 0;
- }else{
- rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor);
- u.az.pCx->isTable = 1;
- }
- }
- u.az.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
- u.az.pCx->isIndex = !u.az.pCx->isTable;
- break;
-}
-
-/* Opcode: SorterOpen P1 P2 * P4 *
-**
-** This opcode works like OP_OpenEphemeral except that it opens
-** a transient index that is specifically designed to sort large
-** tables using an external merge-sort algorithm.
-*/
-case OP_SorterOpen: {
-#if 0 /* local variables moved into u.ba */
- VdbeCursor *pCx;
-#endif /* local variables moved into u.ba */
-
-#ifndef SQLITE_OMIT_MERGE_SORT
- u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
- if( u.ba.pCx==0 ) goto no_mem;
- u.ba.pCx->pKeyInfo = pOp->p4.pKeyInfo;
- u.ba.pCx->pKeyInfo->enc = ENC(p->db);
- u.ba.pCx->isSorter = 1;
- rc = sqlite3VdbeSorterInit(db, u.ba.pCx);
-#else
- pOp->opcode = OP_OpenEphemeral;
- pc--;
-#endif
- break;
-}
-
-/* Opcode: OpenPseudo P1 P2 P3 * P5
-**
-** Open a new cursor that points to a fake table that contains a single
-** row of data. The content of that one row in the content of memory
-** register P2 when P5==0. In other words, cursor P1 becomes an alias for the
-** MEM_Blob content contained in register P2. When P5==1, then the
-** row is represented by P3 consecutive registers beginning with P2.
-**
-** A pseudo-table created by this opcode is used to hold a single
-** row output from the sorter so that the row can be decomposed into
-** individual columns using the OP_Column opcode. The OP_Column opcode
-** is the only cursor opcode that works with a pseudo-table.
-**
-** P3 is the number of fields in the records that will be stored by
-** the pseudo-table.
-*/
-case OP_OpenPseudo: {
-#if 0 /* local variables moved into u.bb */
- VdbeCursor *pCx;
-#endif /* local variables moved into u.bb */
-
- assert( pOp->p1>=0 );
- u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
- if( u.bb.pCx==0 ) goto no_mem;
- u.bb.pCx->nullRow = 1;
- u.bb.pCx->pseudoTableReg = pOp->p2;
- u.bb.pCx->isTable = 1;
- u.bb.pCx->isIndex = 0;
- u.bb.pCx->multiPseudo = pOp->p5;
- break;
-}
-
-/* Opcode: Close P1 * * * *
-**
-** Close a cursor previously opened as P1. If P1 is not
-** currently open, this instruction is a no-op.
-*/
-case OP_Close: {
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]);
- p->apCsr[pOp->p1] = 0;
- break;
-}
-
-/* Opcode: SeekGe P1 P2 P3 P4 *
-**
-** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the value in register P3 as the key. If cursor P1 refers
-** to an SQL index, then P3 is the first in an array of P4 registers
-** that are used as an unpacked index key.
-**
-** Reposition cursor P1 so that it points to the smallest entry that
-** is greater than or equal to the key value. If there are no records
-** greater than or equal to the key and P2 is not zero, then jump to P2.
-**
-** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe
-*/
-/* Opcode: SeekGt P1 P2 P3 P4 *
-**
-** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the value in register P3 as a key. If cursor P1 refers
-** to an SQL index, then P3 is the first in an array of P4 registers
-** that are used as an unpacked index key.
-**
-** Reposition cursor P1 so that it points to the smallest entry that
-** is greater than the key value. If there are no records greater than
-** the key and P2 is not zero, then jump to P2.
-**
-** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe
-*/
-/* Opcode: SeekLt P1 P2 P3 P4 *
-**
-** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the value in register P3 as a key. If cursor P1 refers
-** to an SQL index, then P3 is the first in an array of P4 registers
-** that are used as an unpacked index key.
-**
-** Reposition cursor P1 so that it points to the largest entry that
-** is less than the key value. If there are no records less than
-** the key and P2 is not zero, then jump to P2.
-**
-** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe
-*/
-/* Opcode: SeekLe P1 P2 P3 P4 *
-**
-** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
-** use the value in register P3 as a key. If cursor P1 refers
-** to an SQL index, then P3 is the first in an array of P4 registers
-** that are used as an unpacked index key.
-**
-** Reposition cursor P1 so that it points to the largest entry that
-** is less than or equal to the key value. If there are no records
-** less than or equal to the key and P2 is not zero, then jump to P2.
-**
-** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
-*/
-case OP_SeekLt: /* jump, in3 */
-case OP_SeekLe: /* jump, in3 */
-case OP_SeekGe: /* jump, in3 */
-case OP_SeekGt: { /* jump, in3 */
-#if 0 /* local variables moved into u.bc */
- int res;
- int oc;
- VdbeCursor *pC;
- UnpackedRecord r;
- int nField;
- i64 iKey; /* The rowid we are to seek to */
-#endif /* local variables moved into u.bc */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( pOp->p2!=0 );
- u.bc.pC = p->apCsr[pOp->p1];
- assert( u.bc.pC!=0 );
- assert( u.bc.pC->pseudoTableReg==0 );
- assert( OP_SeekLe == OP_SeekLt+1 );
- assert( OP_SeekGe == OP_SeekLt+2 );
- assert( OP_SeekGt == OP_SeekLt+3 );
- assert( u.bc.pC->isOrdered );
- if( ALWAYS(u.bc.pC->pCursor!=0) ){
- u.bc.oc = pOp->opcode;
- u.bc.pC->nullRow = 0;
- if( u.bc.pC->isTable ){
- /* The input value in P3 might be of any type: integer, real, string,
- ** blob, or NULL. But it needs to be an integer before we can do
- ** the seek, so covert it. */
- pIn3 = &aMem[pOp->p3];
- applyNumericAffinity(pIn3);
- u.bc.iKey = sqlite3VdbeIntValue(pIn3);
- u.bc.pC->rowidIsValid = 0;
-
- /* If the P3 value could not be converted into an integer without
- ** loss of information, then special processing is required... */
- if( (pIn3->flags & MEM_Int)==0 ){
- if( (pIn3->flags & MEM_Real)==0 ){
- /* If the P3 value cannot be converted into any kind of a number,
- ** then the seek is not possible, so jump to P2 */
- pc = pOp->p2 - 1;
- break;
- }
- /* If we reach this point, then the P3 value must be a floating
- ** point number. */
- assert( (pIn3->flags & MEM_Real)!=0 );
-
- if( u.bc.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bc.iKey || pIn3->r>0) ){
- /* The P3 value is too large in magnitude to be expressed as an
- ** integer. */
- u.bc.res = 1;
- if( pIn3->r<0 ){
- if( u.bc.oc>=OP_SeekGe ){ assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
- rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }else{
- if( u.bc.oc<=OP_SeekLe ){ assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
- rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }
- if( u.bc.res ){
- pc = pOp->p2 - 1;
- }
- break;
- }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){
- /* Use the ceiling() function to convert real->int */
- if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++;
- }else{
- /* Use the floor() function to convert real->int */
- assert( u.bc.oc==OP_SeekLe || u.bc.oc==OP_SeekGt );
- if( pIn3->r < (double)u.bc.iKey ) u.bc.iKey--;
- }
- }
- rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, 0, (u64)u.bc.iKey, 0, &u.bc.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- if( u.bc.res==0 ){
- u.bc.pC->rowidIsValid = 1;
- u.bc.pC->lastRowid = u.bc.iKey;
- }
- }else{
- u.bc.nField = pOp->p4.i;
- assert( pOp->p4type==P4_INT32 );
- assert( u.bc.nField>0 );
- u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo;
- u.bc.r.nField = (u16)u.bc.nField;
-
- /* The next line of code computes as follows, only faster:
- ** if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekLe ){
- ** u.bc.r.flags = UNPACKED_INCRKEY;
- ** }else{
- ** u.bc.r.flags = 0;
- ** }
- */
- u.bc.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.bc.oc - OP_SeekLt)));
- assert( u.bc.oc!=OP_SeekGt || u.bc.r.flags==UNPACKED_INCRKEY );
- assert( u.bc.oc!=OP_SeekLe || u.bc.r.flags==UNPACKED_INCRKEY );
- assert( u.bc.oc!=OP_SeekGe || u.bc.r.flags==0 );
- assert( u.bc.oc!=OP_SeekLt || u.bc.r.flags==0 );
-
- u.bc.r.aMem = &aMem[pOp->p3];
-#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); }
-#endif
- ExpandBlob(u.bc.r.aMem);
- rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, &u.bc.r, 0, 0, &u.bc.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- u.bc.pC->rowidIsValid = 0;
- }
- u.bc.pC->deferredMoveto = 0;
- u.bc.pC->cacheStatus = CACHE_STALE;
-#ifdef SQLITE_TEST
- sqlite3_search_count++;
-#endif
- if( u.bc.oc>=OP_SeekGe ){ assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
- if( u.bc.res<0 || (u.bc.res==0 && u.bc.oc==OP_SeekGt) ){
- rc = sqlite3BtreeNext(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.bc.pC->rowidIsValid = 0;
- }else{
- u.bc.res = 0;
- }
- }else{
- assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
- if( u.bc.res>0 || (u.bc.res==0 && u.bc.oc==OP_SeekLt) ){
- rc = sqlite3BtreePrevious(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.bc.pC->rowidIsValid = 0;
- }else{
- /* u.bc.res might be negative because the table is empty. Check to
- ** see if this is the case.
- */
- u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor);
- }
- }
- assert( pOp->p2>0 );
- if( u.bc.res ){
- pc = pOp->p2 - 1;
- }
- }else{
- /* This happens when attempting to open the sqlite3_master table
- ** for read access returns SQLITE_EMPTY. In this case always
- ** take the jump (since there are no records in the table).
- */
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: Seek P1 P2 * * *
-**
-** P1 is an open table cursor and P2 is a rowid integer. Arrange
-** for P1 to move so that it points to the rowid given by P2.
-**
-** This is actually a deferred seek. Nothing actually happens until
-** the cursor is used to read a record. That way, if no reads
-** occur, no unnecessary I/O happens.
-*/
-case OP_Seek: { /* in2 */
-#if 0 /* local variables moved into u.bd */
- VdbeCursor *pC;
-#endif /* local variables moved into u.bd */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bd.pC = p->apCsr[pOp->p1];
- assert( u.bd.pC!=0 );
- if( ALWAYS(u.bd.pC->pCursor!=0) ){
- assert( u.bd.pC->isTable );
- u.bd.pC->nullRow = 0;
- pIn2 = &aMem[pOp->p2];
- u.bd.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
- u.bd.pC->rowidIsValid = 0;
- u.bd.pC->deferredMoveto = 1;
- }
- break;
-}
-
-
-/* Opcode: Found P1 P2 P3 P4 *
-**
-** If P4==0 then register P3 holds a blob constructed by MakeRecord. If
-** P4>0 then register P3 is the first of P4 registers that form an unpacked
-** record.
-**
-** Cursor P1 is on an index btree. If the record identified by P3 and P4
-** is a prefix of any entry in P1 then a jump is made to P2 and
-** P1 is left pointing at the matching entry.
-*/
-/* Opcode: NotFound P1 P2 P3 P4 *
-**
-** If P4==0 then register P3 holds a blob constructed by MakeRecord. If
-** P4>0 then register P3 is the first of P4 registers that form an unpacked
-** record.
-**
-** Cursor P1 is on an index btree. If the record identified by P3 and P4
-** is not the prefix of any entry in P1 then a jump is made to P2. If P1
-** does contain an entry whose prefix matches the P3/P4 record then control
-** falls through to the next instruction and P1 is left pointing at the
-** matching entry.
-**
-** See also: Found, NotExists, IsUnique
-*/
-case OP_NotFound: /* jump, in3 */
-case OP_Found: { /* jump, in3 */
-#if 0 /* local variables moved into u.be */
- int alreadyExists;
- VdbeCursor *pC;
- int res;
- char *pFree;
- UnpackedRecord *pIdxKey;
- UnpackedRecord r;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
-#endif /* local variables moved into u.be */
-
-#ifdef SQLITE_TEST
- sqlite3_found_count++;
-#endif
-
- u.be.alreadyExists = 0;
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( pOp->p4type==P4_INT32 );
- u.be.pC = p->apCsr[pOp->p1];
- assert( u.be.pC!=0 );
- pIn3 = &aMem[pOp->p3];
- if( ALWAYS(u.be.pC->pCursor!=0) ){
-
- assert( u.be.pC->isTable==0 );
- if( pOp->p4.i>0 ){
- u.be.r.pKeyInfo = u.be.pC->pKeyInfo;
- u.be.r.nField = (u16)pOp->p4.i;
- u.be.r.aMem = pIn3;
-#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.be.r.nField; i++) assert( memIsValid(&u.be.r.aMem[i]) ); }
-#endif
- u.be.r.flags = UNPACKED_PREFIX_MATCH;
- u.be.pIdxKey = &u.be.r;
- }else{
- u.be.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
- u.be.pC->pKeyInfo, u.be.aTempRec, sizeof(u.be.aTempRec), &u.be.pFree
- );
- if( u.be.pIdxKey==0 ) goto no_mem;
- assert( pIn3->flags & MEM_Blob );
- assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
- sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z, u.be.pIdxKey);
- u.be.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
- }
- rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, u.be.pIdxKey, 0, 0, &u.be.res);
- if( pOp->p4.i==0 ){
- sqlite3DbFree(db, u.be.pFree);
- }
- if( rc!=SQLITE_OK ){
- break;
- }
- u.be.alreadyExists = (u.be.res==0);
- u.be.pC->deferredMoveto = 0;
- u.be.pC->cacheStatus = CACHE_STALE;
- }
- if( pOp->opcode==OP_Found ){
- if( u.be.alreadyExists ) pc = pOp->p2 - 1;
- }else{
- if( !u.be.alreadyExists ) pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: IsUnique P1 P2 P3 P4 *
-**
-** Cursor P1 is open on an index b-tree - that is to say, a btree which
-** no data and where the key are records generated by OP_MakeRecord with
-** the list field being the integer ROWID of the entry that the index
-** entry refers to.
-**
-** The P3 register contains an integer record number. Call this record
-** number R. Register P4 is the first in a set of N contiguous registers
-** that make up an unpacked index key that can be used with cursor P1.
-** The value of N can be inferred from the cursor. N includes the rowid
-** value appended to the end of the index record. This rowid value may
-** or may not be the same as R.
-**
-** If any of the N registers beginning with register P4 contains a NULL
-** value, jump immediately to P2.
-**
-** Otherwise, this instruction checks if cursor P1 contains an entry
-** where the first (N-1) fields match but the rowid value at the end
-** of the index entry is not R. If there is no such entry, control jumps
-** to instruction P2. Otherwise, the rowid of the conflicting index
-** entry is copied to register P3 and control falls through to the next
-** instruction.
-**
-** See also: NotFound, NotExists, Found
-*/
-case OP_IsUnique: { /* jump, in3 */
-#if 0 /* local variables moved into u.bf */
- u16 ii;
- VdbeCursor *pCx;
- BtCursor *pCrsr;
- u16 nField;
- Mem *aMx;
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
-#endif /* local variables moved into u.bf */
-
- pIn3 = &aMem[pOp->p3];
- u.bf.aMx = &aMem[pOp->p4.i];
- /* Assert that the values of parameters P1 and P4 are in range. */
- assert( pOp->p4type==P4_INT32 );
- assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem );
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-
- /* Find the index cursor. */
- u.bf.pCx = p->apCsr[pOp->p1];
- assert( u.bf.pCx->deferredMoveto==0 );
- u.bf.pCx->seekResult = 0;
- u.bf.pCx->cacheStatus = CACHE_STALE;
- u.bf.pCrsr = u.bf.pCx->pCursor;
-
- /* If any of the values are NULL, take the jump. */
- u.bf.nField = u.bf.pCx->pKeyInfo->nField;
- for(u.bf.ii=0; u.bf.ii<u.bf.nField; u.bf.ii++){
- if( u.bf.aMx[u.bf.ii].flags & MEM_Null ){
- pc = pOp->p2 - 1;
- u.bf.pCrsr = 0;
- break;
- }
- }
- assert( (u.bf.aMx[u.bf.nField].flags & MEM_Null)==0 );
-
- if( u.bf.pCrsr!=0 ){
- /* Populate the index search key. */
- u.bf.r.pKeyInfo = u.bf.pCx->pKeyInfo;
- u.bf.r.nField = u.bf.nField + 1;
- u.bf.r.flags = UNPACKED_PREFIX_SEARCH;
- u.bf.r.aMem = u.bf.aMx;
-#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bf.r.nField; i++) assert( memIsValid(&u.bf.r.aMem[i]) ); }
-#endif
-
- /* Extract the value of u.bf.R from register P3. */
- sqlite3VdbeMemIntegerify(pIn3);
- u.bf.R = pIn3->u.i;
-
- /* Search the B-Tree index. If no conflicting record is found, jump
- ** to P2. Otherwise, copy the rowid of the conflicting record to
- ** register P3 and fall through to the next instruction. */
- rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, &u.bf.r, 0, 0, &u.bf.pCx->seekResult);
- if( (u.bf.r.flags & UNPACKED_PREFIX_SEARCH) || u.bf.r.rowid==u.bf.R ){
- pc = pOp->p2 - 1;
- }else{
- pIn3->u.i = u.bf.r.rowid;
- }
- }
- break;
-}
-
-/* Opcode: NotExists P1 P2 P3 * *
-**
-** Use the content of register P3 as an integer key. If a record
-** with that key does not exist in table of P1, then jump to P2.
-** If the record does exist, then fall through. The cursor is left
-** pointing to the record if it exists.
-**
-** The difference between this operation and NotFound is that this
-** operation assumes the key is an integer and that P1 is a table whereas
-** NotFound assumes key is a blob constructed from MakeRecord and
-** P1 is an index.
-**
-** See also: Found, NotFound, IsUnique
-*/
-case OP_NotExists: { /* jump, in3 */
-#if 0 /* local variables moved into u.bg */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- u64 iKey;
-#endif /* local variables moved into u.bg */
-
- pIn3 = &aMem[pOp->p3];
- assert( pIn3->flags & MEM_Int );
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bg.pC = p->apCsr[pOp->p1];
- assert( u.bg.pC!=0 );
- assert( u.bg.pC->isTable );
- assert( u.bg.pC->pseudoTableReg==0 );
- u.bg.pCrsr = u.bg.pC->pCursor;
- if( ALWAYS(u.bg.pCrsr!=0) ){
- u.bg.res = 0;
- u.bg.iKey = pIn3->u.i;
- rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
- u.bg.pC->lastRowid = pIn3->u.i;
- u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
- u.bg.pC->nullRow = 0;
- u.bg.pC->cacheStatus = CACHE_STALE;
- u.bg.pC->deferredMoveto = 0;
- if( u.bg.res!=0 ){
- pc = pOp->p2 - 1;
- assert( u.bg.pC->rowidIsValid==0 );
- }
- u.bg.pC->seekResult = u.bg.res;
- }else{
- /* This happens when an attempt to open a read cursor on the
- ** sqlite_master table returns SQLITE_EMPTY.
- */
- pc = pOp->p2 - 1;
- assert( u.bg.pC->rowidIsValid==0 );
- u.bg.pC->seekResult = 0;
- }
- break;
-}
-
-/* Opcode: Sequence P1 P2 * * *
-**
-** Find the next available sequence number for cursor P1.
-** Write the sequence number into register P2.
-** The sequence number on the cursor is incremented after this
-** instruction.
-*/
-case OP_Sequence: { /* out2-prerelease */
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( p->apCsr[pOp->p1]!=0 );
- pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
- break;
-}
-
-
-/* Opcode: NewRowid P1 P2 P3 * *
-**
-** Get a new integer record number (a.k.a "rowid") used as the key to a table.
-** The record number is not previously used as a key in the database
-** table that cursor P1 points to. The new record number is written
-** written to register P2.
-**
-** If P3>0 then P3 is a register in the root frame of this VDBE that holds
-** the largest previously generated record number. No new record numbers are
-** allowed to be less than this value. When this value reaches its maximum,
-** an SQLITE_FULL error is generated. The P3 register is updated with the '
-** generated record number. This P3 mechanism is used to help implement the
-** AUTOINCREMENT feature.
-*/
-case OP_NewRowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bh */
- i64 v; /* The new rowid */
- VdbeCursor *pC; /* Cursor of table to get the new rowid */
- int res; /* Result of an sqlite3BtreeLast() */
- int cnt; /* Counter to limit the number of searches */
- Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */
- VdbeFrame *pFrame; /* Root frame of VDBE */
-#endif /* local variables moved into u.bh */
-
- u.bh.v = 0;
- u.bh.res = 0;
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bh.pC = p->apCsr[pOp->p1];
- assert( u.bh.pC!=0 );
- if( NEVER(u.bh.pC->pCursor==0) ){
- /* The zero initialization above is all that is needed */
- }else{
- /* The next rowid or record number (different terms for the same
- ** thing) is obtained in a two-step algorithm.
- **
- ** First we attempt to find the largest existing rowid and add one
- ** to that. But if the largest existing rowid is already the maximum
- ** positive integer, we have to fall through to the second
- ** probabilistic algorithm
- **
- ** The second algorithm is to select a rowid at random and see if
- ** it already exists in the table. If it does not exist, we have
- ** succeeded. If the random rowid does exist, we select a new one
- ** and try again, up to 100 times.
- */
- assert( u.bh.pC->isTable );
-
-#ifdef SQLITE_32BIT_ROWID
-# define MAX_ROWID 0x7fffffff
-#else
- /* Some compilers complain about constants of the form 0x7fffffffffffffff.
- ** Others complain about 0x7ffffffffffffffffLL. The following macro seems
- ** to provide the constant while making all compilers happy.
- */
-# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
-#endif
-
- if( !u.bh.pC->useRandomRowid ){
- u.bh.v = sqlite3BtreeGetCachedRowid(u.bh.pC->pCursor);
- if( u.bh.v==0 ){
- rc = sqlite3BtreeLast(u.bh.pC->pCursor, &u.bh.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- if( u.bh.res ){
- u.bh.v = 1; /* IMP: R-61914-48074 */
- }else{
- assert( sqlite3BtreeCursorIsValid(u.bh.pC->pCursor) );
- rc = sqlite3BtreeKeySize(u.bh.pC->pCursor, &u.bh.v);
- assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */
- if( u.bh.v>=MAX_ROWID ){
- u.bh.pC->useRandomRowid = 1;
- }else{
- u.bh.v++; /* IMP: R-29538-34987 */
- }
- }
- }
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- if( pOp->p3 ){
- /* Assert that P3 is a valid memory cell. */
- assert( pOp->p3>0 );
- if( p->pFrame ){
- for(u.bh.pFrame=p->pFrame; u.bh.pFrame->pParent; u.bh.pFrame=u.bh.pFrame->pParent);
- /* Assert that P3 is a valid memory cell. */
- assert( pOp->p3<=u.bh.pFrame->nMem );
- u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3];
- }else{
- /* Assert that P3 is a valid memory cell. */
- assert( pOp->p3<=p->nMem );
- u.bh.pMem = &aMem[pOp->p3];
- memAboutToChange(p, u.bh.pMem);
- }
- assert( memIsValid(u.bh.pMem) );
-
- REGISTER_TRACE(pOp->p3, u.bh.pMem);
- sqlite3VdbeMemIntegerify(u.bh.pMem);
- assert( (u.bh.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
- if( u.bh.pMem->u.i==MAX_ROWID || u.bh.pC->useRandomRowid ){
- rc = SQLITE_FULL; /* IMP: R-12275-61338 */
- goto abort_due_to_error;
- }
- if( u.bh.v<u.bh.pMem->u.i+1 ){
- u.bh.v = u.bh.pMem->u.i + 1;
- }
- u.bh.pMem->u.i = u.bh.v;
- }
-#endif
-
- sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.v<MAX_ROWID ? u.bh.v+1 : 0);
- }
- if( u.bh.pC->useRandomRowid ){
- /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the
- ** largest possible integer (9223372036854775807) then the database
- ** engine starts picking positive candidate ROWIDs at random until
- ** it finds one that is not previously used. */
- assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is
- ** an AUTOINCREMENT table. */
- /* on the first attempt, simply do one more than previous */
- u.bh.v = lastRowid;
- u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
- u.bh.v++; /* ensure non-zero */
- u.bh.cnt = 0;
- while( ((rc = sqlite3BtreeMovetoUnpacked(u.bh.pC->pCursor, 0, (u64)u.bh.v,
- 0, &u.bh.res))==SQLITE_OK)
- && (u.bh.res==0)
- && (++u.bh.cnt<100)){
- /* collision - try another random rowid */
- sqlite3_randomness(sizeof(u.bh.v), &u.bh.v);
- if( u.bh.cnt<5 ){
- /* try "small" random rowids for the initial attempts */
- u.bh.v &= 0xffffff;
- }else{
- u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
- }
- u.bh.v++; /* ensure non-zero */
- }
- if( rc==SQLITE_OK && u.bh.res==0 ){
- rc = SQLITE_FULL; /* IMP: R-38219-53002 */
- goto abort_due_to_error;
- }
- assert( u.bh.v>0 ); /* EV: R-40812-03570 */
- }
- u.bh.pC->rowidIsValid = 0;
- u.bh.pC->deferredMoveto = 0;
- u.bh.pC->cacheStatus = CACHE_STALE;
- }
- pOut->u.i = u.bh.v;
- break;
-}
-
-/* Opcode: Insert P1 P2 P3 P4 P5
-**
-** Write an entry into the table of cursor P1. A new entry is
-** created if it doesn't already exist or the data for an existing
-** entry is overwritten. The data is the value MEM_Blob stored in register
-** number P2. The key is stored in register P3. The key must
-** be a MEM_Int.
-**
-** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
-** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set,
-** then rowid is stored for subsequent return by the
-** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
-**
-** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of
-** the last seek operation (OP_NotExists) was a success, then this
-** operation will not attempt to find the appropriate row before doing
-** the insert but will instead overwrite the row that the cursor is
-** currently pointing to. Presumably, the prior OP_NotExists opcode
-** has already positioned the cursor correctly. This is an optimization
-** that boosts performance by avoiding redundant seeks.
-**
-** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an
-** UPDATE operation. Otherwise (if the flag is clear) then this opcode
-** is part of an INSERT operation. The difference is only important to
-** the update hook.
-**
-** Parameter P4 may point to a string containing the table-name, or
-** may be NULL. If it is not NULL, then the update-hook
-** (sqlite3.xUpdateCallback) is invoked following a successful insert.
-**
-** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically
-** allocated, then ownership of P2 is transferred to the pseudo-cursor
-** and register P2 becomes ephemeral. If the cursor is changed, the
-** value of register P2 will then change. Make sure this does not
-** cause any problems.)
-**
-** This instruction only works on tables. The equivalent instruction
-** for indices is OP_IdxInsert.
-*/
-/* Opcode: InsertInt P1 P2 P3 P4 P5
-**
-** This works exactly like OP_Insert except that the key is the
-** integer value P3, not the value of the integer stored in register P3.
-*/
-case OP_Insert:
-case OP_InsertInt: {
-#if 0 /* local variables moved into u.bi */
- Mem *pData; /* MEM cell holding data for the record to be inserted */
- Mem *pKey; /* MEM cell holding key for the record */
- i64 iKey; /* The integer ROWID or key for the record to be inserted */
- VdbeCursor *pC; /* Cursor to table into which insert is written */
- int nZero; /* Number of zero-bytes to append */
- int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
- const char *zDb; /* database name - used by the update hook */
- const char *zTbl; /* Table name - used by the opdate hook */
- int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
-#endif /* local variables moved into u.bi */
-
- u.bi.pData = &aMem[pOp->p2];
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( memIsValid(u.bi.pData) );
- u.bi.pC = p->apCsr[pOp->p1];
- assert( u.bi.pC!=0 );
- assert( u.bi.pC->pCursor!=0 );
- assert( u.bi.pC->pseudoTableReg==0 );
- assert( u.bi.pC->isTable );
- REGISTER_TRACE(pOp->p2, u.bi.pData);
-
- if( pOp->opcode==OP_Insert ){
- u.bi.pKey = &aMem[pOp->p3];
- assert( u.bi.pKey->flags & MEM_Int );
- assert( memIsValid(u.bi.pKey) );
- REGISTER_TRACE(pOp->p3, u.bi.pKey);
- u.bi.iKey = u.bi.pKey->u.i;
- }else{
- assert( pOp->opcode==OP_InsertInt );
- u.bi.iKey = pOp->p3;
- }
-
- if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bi.iKey;
- if( u.bi.pData->flags & MEM_Null ){
- u.bi.pData->z = 0;
- u.bi.pData->n = 0;
- }else{
- assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) );
- }
- u.bi.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bi.pC->seekResult : 0);
- if( u.bi.pData->flags & MEM_Zero ){
- u.bi.nZero = u.bi.pData->u.nZero;
- }else{
- u.bi.nZero = 0;
- }
- sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0);
- rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey,
- u.bi.pData->z, u.bi.pData->n, u.bi.nZero,
- pOp->p5 & OPFLAG_APPEND, u.bi.seekResult
- );
- u.bi.pC->rowidIsValid = 0;
- u.bi.pC->deferredMoveto = 0;
- u.bi.pC->cacheStatus = CACHE_STALE;
-
- /* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- u.bi.zDb = db->aDb[u.bi.pC->iDb].zName;
- u.bi.zTbl = pOp->p4.z;
- u.bi.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
- assert( u.bi.pC->isTable );
- db->xUpdateCallback(db->pUpdateArg, u.bi.op, u.bi.zDb, u.bi.zTbl, u.bi.iKey);
- assert( u.bi.pC->iDb>=0 );
- }
- break;
-}
-
-/* Opcode: Delete P1 P2 * P4 *
-**
-** Delete the record at which the P1 cursor is currently pointing.
-**
-** The cursor will be left pointing at either the next or the previous
-** record in the table. If it is left pointing at the next record, then
-** the next Next instruction will be a no-op. Hence it is OK to delete
-** a record from within an Next loop.
-**
-** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
-** incremented (otherwise not).
-**
-** P1 must not be pseudo-table. It has to be a real table with
-** multiple rows.
-**
-** If P4 is not NULL, then it is the name of the table that P1 is
-** pointing to. The update hook will be invoked, if it exists.
-** If P4 is not NULL then the P1 cursor must have been positioned
-** using OP_NotFound prior to invoking this opcode.
-*/
-case OP_Delete: {
-#if 0 /* local variables moved into u.bj */
- i64 iKey;
- VdbeCursor *pC;
-#endif /* local variables moved into u.bj */
-
- u.bj.iKey = 0;
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bj.pC = p->apCsr[pOp->p1];
- assert( u.bj.pC!=0 );
- assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
-
- /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the
- ** row being deleted.
- */
- if( db->xUpdateCallback && pOp->p4.z ){
- assert( u.bj.pC->isTable );
- assert( u.bj.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */
- u.bj.iKey = u.bj.pC->lastRowid;
- }
-
- /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
- ** OP_Column on the same table without any intervening operations that
- ** might move or invalidate the cursor. Hence cursor u.bj.pC is always pointing
- ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
- ** below is always a no-op and cannot fail. We will run it anyhow, though,
- ** to guard against future changes to the code generator.
- **/
- assert( u.bj.pC->deferredMoveto==0 );
- rc = sqlite3VdbeCursorMoveto(u.bj.pC);
- if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
-
- sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0);
- rc = sqlite3BtreeDelete(u.bj.pC->pCursor);
- u.bj.pC->cacheStatus = CACHE_STALE;
-
- /* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- const char *zDb = db->aDb[u.bj.pC->iDb].zName;
- const char *zTbl = pOp->p4.z;
- db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey);
- assert( u.bj.pC->iDb>=0 );
- }
- if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
- break;
-}
-/* Opcode: ResetCount * * * * *
-**
-** The value of the change counter is copied to the database handle
-** change counter (returned by subsequent calls to sqlite3_changes()).
-** Then the VMs internal change counter resets to 0.
-** This is used by trigger programs.
-*/
-case OP_ResetCount: {
- sqlite3VdbeSetChanges(db, p->nChange);
- p->nChange = 0;
- break;
-}
-
-/* Opcode: SorterCompare P1 P2 P3
-**
-** P1 is a sorter cursor. This instruction compares the record blob in
-** register P3 with the entry that the sorter cursor currently points to.
-** If, excluding the rowid fields at the end, the two records are a match,
-** fall through to the next instruction. Otherwise, jump to instruction P2.
-*/
-case OP_SorterCompare: {
-#if 0 /* local variables moved into u.bk */
- VdbeCursor *pC;
- int res;
-#endif /* local variables moved into u.bk */
-
- u.bk.pC = p->apCsr[pOp->p1];
- assert( isSorter(u.bk.pC) );
- pIn3 = &aMem[pOp->p3];
- rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, &u.bk.res);
- if( u.bk.res ){
- pc = pOp->p2-1;
- }
- break;
-};
-
-/* Opcode: SorterData P1 P2 * * *
-**
-** Write into register P2 the current sorter data for sorter cursor P1.
-*/
-case OP_SorterData: {
-#if 0 /* local variables moved into u.bl */
- VdbeCursor *pC;
-#endif /* local variables moved into u.bl */
-
-#ifndef SQLITE_OMIT_MERGE_SORT
- pOut = &aMem[pOp->p2];
- u.bl.pC = p->apCsr[pOp->p1];
- assert( u.bl.pC->isSorter );
- rc = sqlite3VdbeSorterRowkey(u.bl.pC, pOut);
-#else
- pOp->opcode = OP_RowKey;
- pc--;
-#endif
- break;
-}
-
-/* Opcode: RowData P1 P2 * * *
-**
-** Write into register P2 the complete row data for cursor P1.
-** There is no interpretation of the data.
-** It is just copied onto the P2 register exactly as
-** it is found in the database file.
-**
-** If the P1 cursor must be pointing to a valid row (not a NULL row)
-** of a real table, not a pseudo-table.
-*/
-/* Opcode: RowKey P1 P2 * * *
-**
-** Write into register P2 the complete row key for cursor P1.
-** There is no interpretation of the data.
-** The key is copied onto the P3 register exactly as
-** it is found in the database file.
-**
-** If the P1 cursor must be pointing to a valid row (not a NULL row)
-** of a real table, not a pseudo-table.
-*/
-case OP_RowKey:
-case OP_RowData: {
-#if 0 /* local variables moved into u.bm */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- u32 n;
- i64 n64;
-#endif /* local variables moved into u.bm */
-
- pOut = &aMem[pOp->p2];
- memAboutToChange(p, pOut);
-
- /* Note that RowKey and RowData are really exactly the same instruction */
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bm.pC = p->apCsr[pOp->p1];
- assert( u.bm.pC->isSorter==0 );
- assert( u.bm.pC->isTable || pOp->opcode!=OP_RowData );
- assert( u.bm.pC->isIndex || pOp->opcode==OP_RowData );
- assert( u.bm.pC!=0 );
- assert( u.bm.pC->nullRow==0 );
- assert( u.bm.pC->pseudoTableReg==0 );
- assert( u.bm.pC->pCursor!=0 );
- u.bm.pCrsr = u.bm.pC->pCursor;
- assert( sqlite3BtreeCursorIsValid(u.bm.pCrsr) );
-
- /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
- ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
- ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always
- ** a no-op and can never fail. But we leave it in place as a safety.
- */
- assert( u.bm.pC->deferredMoveto==0 );
- rc = sqlite3VdbeCursorMoveto(u.bm.pC);
- if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
-
- if( u.bm.pC->isIndex ){
- assert( !u.bm.pC->isTable );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bm.pCrsr, &u.bm.n64);
- assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
- if( u.bm.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- u.bm.n = (u32)u.bm.n64;
- }else{
- VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bm.pCrsr, &u.bm.n);
- assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- if( u.bm.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
- }
- if( sqlite3VdbeMemGrow(pOut, u.bm.n, 0) ){
- goto no_mem;
- }
- pOut->n = u.bm.n;
- MemSetTypeFlag(pOut, MEM_Blob);
- if( u.bm.pC->isIndex ){
- rc = sqlite3BtreeKey(u.bm.pCrsr, 0, u.bm.n, pOut->z);
- }else{
- rc = sqlite3BtreeData(u.bm.pCrsr, 0, u.bm.n, pOut->z);
- }
- pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
- UPDATE_MAX_BLOBSIZE(pOut);
- break;
-}
-
-/* Opcode: Rowid P1 P2 * * *
-**
-** Store in register P2 an integer which is the key of the table entry that
-** P1 is currently point to.
-**
-** P1 can be either an ordinary table or a virtual table. There used to
-** be a separate OP_VRowid opcode for use with virtual tables, but this
-** one opcode now works for both table types.
-*/
-case OP_Rowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bn */
- VdbeCursor *pC;
- i64 v;
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
-#endif /* local variables moved into u.bn */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bn.pC = p->apCsr[pOp->p1];
- assert( u.bn.pC!=0 );
- assert( u.bn.pC->pseudoTableReg==0 || u.bn.pC->nullRow );
- if( u.bn.pC->nullRow ){
- pOut->flags = MEM_Null;
- break;
- }else if( u.bn.pC->deferredMoveto ){
- u.bn.v = u.bn.pC->movetoTarget;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( u.bn.pC->pVtabCursor ){
- u.bn.pVtab = u.bn.pC->pVtabCursor->pVtab;
- u.bn.pModule = u.bn.pVtab->pModule;
- assert( u.bn.pModule->xRowid );
- rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v);
- importVtabErrMsg(p, u.bn.pVtab);
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
- }else{
- assert( u.bn.pC->pCursor!=0 );
- rc = sqlite3VdbeCursorMoveto(u.bn.pC);
- if( rc ) goto abort_due_to_error;
- if( u.bn.pC->rowidIsValid ){
- u.bn.v = u.bn.pC->lastRowid;
- }else{
- rc = sqlite3BtreeKeySize(u.bn.pC->pCursor, &u.bn.v);
- assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */
- }
- }
- pOut->u.i = u.bn.v;
- break;
-}
-
-/* Opcode: NullRow P1 * * * *
-**
-** Move the cursor P1 to a null row. Any OP_Column operations
-** that occur while the cursor is on the null row will always
-** write a NULL.
-*/
-case OP_NullRow: {
-#if 0 /* local variables moved into u.bo */
- VdbeCursor *pC;
-#endif /* local variables moved into u.bo */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bo.pC = p->apCsr[pOp->p1];
- assert( u.bo.pC!=0 );
- u.bo.pC->nullRow = 1;
- u.bo.pC->rowidIsValid = 0;
- assert( u.bo.pC->pCursor || u.bo.pC->pVtabCursor );
- if( u.bo.pC->pCursor ){
- sqlite3BtreeClearCursor(u.bo.pC->pCursor);
- }
- break;
-}
-
-/* Opcode: Last P1 P2 * * *
-**
-** The next use of the Rowid or Column or Next instruction for P1
-** will refer to the last entry in the database table or index.
-** If the table or index is empty and P2>0, then jump immediately to P2.
-** If P2 is 0 or if the table or index is not empty, fall through
-** to the following instruction.
-*/
-case OP_Last: { /* jump */
-#if 0 /* local variables moved into u.bp */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
-#endif /* local variables moved into u.bp */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bp.pC = p->apCsr[pOp->p1];
- assert( u.bp.pC!=0 );
- u.bp.pCrsr = u.bp.pC->pCursor;
- u.bp.res = 0;
- if( ALWAYS(u.bp.pCrsr!=0) ){
- rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);
- }
- u.bp.pC->nullRow = (u8)u.bp.res;
- u.bp.pC->deferredMoveto = 0;
- u.bp.pC->rowidIsValid = 0;
- u.bp.pC->cacheStatus = CACHE_STALE;
- if( pOp->p2>0 && u.bp.res ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-
-/* Opcode: Sort P1 P2 * * *
-**
-** This opcode does exactly the same thing as OP_Rewind except that
-** it increments an undocumented global variable used for testing.
-**
-** Sorting is accomplished by writing records into a sorting index,
-** then rewinding that index and playing it back from beginning to
-** end. We use the OP_Sort opcode instead of OP_Rewind to do the
-** rewinding so that the global variable will be incremented and
-** regression tests can determine whether or not the optimizer is
-** correctly optimizing out sorts.
-*/
-case OP_SorterSort: /* jump */
-#ifdef SQLITE_OMIT_MERGE_SORT
- pOp->opcode = OP_Sort;
-#endif
-case OP_Sort: { /* jump */
-#ifdef SQLITE_TEST
- sqlite3_sort_count++;
- sqlite3_search_count--;
-#endif
- p->aCounter[SQLITE_STMTSTATUS_SORT-1]++;
- /* Fall through into OP_Rewind */
-}
-/* Opcode: Rewind P1 P2 * * *
-**
-** The next use of the Rowid or Column or Next instruction for P1
-** will refer to the first entry in the database table or index.
-** If the table or index is empty and P2>0, then jump immediately to P2.
-** If P2 is 0 or if the table or index is not empty, fall through
-** to the following instruction.
-*/
-case OP_Rewind: { /* jump */
-#if 0 /* local variables moved into u.bq */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
-#endif /* local variables moved into u.bq */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bq.pC = p->apCsr[pOp->p1];
- assert( u.bq.pC!=0 );
- assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterSort) );
- u.bq.res = 1;
- if( isSorter(u.bq.pC) ){
- rc = sqlite3VdbeSorterRewind(db, u.bq.pC, &u.bq.res);
- }else{
- u.bq.pCrsr = u.bq.pC->pCursor;
- assert( u.bq.pCrsr );
- rc = sqlite3BtreeFirst(u.bq.pCrsr, &u.bq.res);
- u.bq.pC->atFirst = u.bq.res==0 ?1:0;
- u.bq.pC->deferredMoveto = 0;
- u.bq.pC->cacheStatus = CACHE_STALE;
- u.bq.pC->rowidIsValid = 0;
- }
- u.bq.pC->nullRow = (u8)u.bq.res;
- assert( pOp->p2>0 && pOp->p2<p->nOp );
- if( u.bq.res ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: Next P1 P2 * P4 P5
-**
-** Advance cursor P1 so that it points to the next key/data pair in its
-** table or index. If there are no more key/value pairs then fall through
-** to the following instruction. But if the cursor advance was successful,
-** jump immediately to P2.
-**
-** The P1 cursor must be for a real table, not a pseudo-table.
-**
-** P4 is always of type P4_ADVANCE. The function pointer points to
-** sqlite3BtreeNext().
-**
-** If P5 is positive and the jump is taken, then event counter
-** number P5-1 in the prepared statement is incremented.
-**
-** See also: Prev
-*/
-/* Opcode: Prev P1 P2 * * P5
-**
-** Back up cursor P1 so that it points to the previous key/data pair in its
-** table or index. If there is no previous key/value pairs then fall through
-** to the following instruction. But if the cursor backup was successful,
-** jump immediately to P2.
-**
-** The P1 cursor must be for a real table, not a pseudo-table.
-**
-** P4 is always of type P4_ADVANCE. The function pointer points to
-** sqlite3BtreePrevious().
-**
-** If P5 is positive and the jump is taken, then event counter
-** number P5-1 in the prepared statement is incremented.
-*/
-case OP_SorterNext: /* jump */
-#ifdef SQLITE_OMIT_MERGE_SORT
- pOp->opcode = OP_Next;
-#endif
-case OP_Prev: /* jump */
-case OP_Next: { /* jump */
-#if 0 /* local variables moved into u.br */
- VdbeCursor *pC;
- int res;
-#endif /* local variables moved into u.br */
-
- CHECK_FOR_INTERRUPT;
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( pOp->p5<=ArraySize(p->aCounter) );
- u.br.pC = p->apCsr[pOp->p1];
- if( u.br.pC==0 ){
- break; /* See ticket #2273 */
- }
- assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterNext) );
- if( isSorter(u.br.pC) ){
- assert( pOp->opcode==OP_SorterNext );
- rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res);
- }else{
- u.br.res = 1;
- assert( u.br.pC->deferredMoveto==0 );
- assert( u.br.pC->pCursor );
- assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
- assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
- rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res);
- }
- u.br.pC->nullRow = (u8)u.br.res;
- u.br.pC->cacheStatus = CACHE_STALE;
- if( u.br.res==0 ){
- pc = pOp->p2 - 1;
- if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
-#ifdef SQLITE_TEST
- sqlite3_search_count++;
-#endif
- }
- u.br.pC->rowidIsValid = 0;
- break;
-}
-
-/* Opcode: IdxInsert P1 P2 P3 * P5
-**
-** Register P2 holds an SQL index key made using the
-** MakeRecord instructions. This opcode writes that key
-** into the index P1. Data for the entry is nil.
-**
-** P3 is a flag that provides a hint to the b-tree layer that this
-** insert is likely to be an append.
-**
-** This instruction only works for indices. The equivalent instruction
-** for tables is OP_Insert.
-*/
-case OP_SorterInsert: /* in2 */
-#ifdef SQLITE_OMIT_MERGE_SORT
- pOp->opcode = OP_IdxInsert;
-#endif
-case OP_IdxInsert: { /* in2 */
-#if 0 /* local variables moved into u.bs */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int nKey;
- const char *zKey;
-#endif /* local variables moved into u.bs */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bs.pC = p->apCsr[pOp->p1];
- assert( u.bs.pC!=0 );
- assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) );
- pIn2 = &aMem[pOp->p2];
- assert( pIn2->flags & MEM_Blob );
- u.bs.pCrsr = u.bs.pC->pCursor;
- if( ALWAYS(u.bs.pCrsr!=0) ){
- assert( u.bs.pC->isTable==0 );
- rc = ExpandBlob(pIn2);
- if( rc==SQLITE_OK ){
- if( isSorter(u.bs.pC) ){
- rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
- }else{
- u.bs.nKey = pIn2->n;
- u.bs.zKey = pIn2->z;
- rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
- );
- assert( u.bs.pC->deferredMoveto==0 );
- u.bs.pC->cacheStatus = CACHE_STALE;
- }
- }
- }
- break;
-}
-
-/* Opcode: IdxDelete P1 P2 P3 * *
-**
-** The content of P3 registers starting at register P2 form
-** an unpacked index key. This opcode removes that entry from the
-** index opened by cursor P1.
-*/
-case OP_IdxDelete: {
-#if 0 /* local variables moved into u.bt */
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- UnpackedRecord r;
-#endif /* local variables moved into u.bt */
-
- assert( pOp->p3>0 );
- assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 );
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bt.pC = p->apCsr[pOp->p1];
- assert( u.bt.pC!=0 );
- u.bt.pCrsr = u.bt.pC->pCursor;
- if( ALWAYS(u.bt.pCrsr!=0) ){
- u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
- u.bt.r.nField = (u16)pOp->p3;
- u.bt.r.flags = 0;
- u.bt.r.aMem = &aMem[pOp->p2];
-#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); }
-#endif
- rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res);
- if( rc==SQLITE_OK && u.bt.res==0 ){
- rc = sqlite3BtreeDelete(u.bt.pCrsr);
- }
- assert( u.bt.pC->deferredMoveto==0 );
- u.bt.pC->cacheStatus = CACHE_STALE;
- }
- break;
-}
-
-/* Opcode: IdxRowid P1 P2 * * *
-**
-** Write into register P2 an integer which is the last entry in the record at
-** the end of the index key pointed to by cursor P1. This integer should be
-** the rowid of the table entry to which this index entry points.
-**
-** See also: Rowid, MakeRecord.
-*/
-case OP_IdxRowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bu */
- BtCursor *pCrsr;
- VdbeCursor *pC;
- i64 rowid;
-#endif /* local variables moved into u.bu */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bu.pC = p->apCsr[pOp->p1];
- assert( u.bu.pC!=0 );
- u.bu.pCrsr = u.bu.pC->pCursor;
- pOut->flags = MEM_Null;
- if( ALWAYS(u.bu.pCrsr!=0) ){
- rc = sqlite3VdbeCursorMoveto(u.bu.pC);
- if( NEVER(rc) ) goto abort_due_to_error;
- assert( u.bu.pC->deferredMoveto==0 );
- assert( u.bu.pC->isTable==0 );
- if( !u.bu.pC->nullRow ){
- rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- pOut->u.i = u.bu.rowid;
- pOut->flags = MEM_Int;
- }
- }
- break;
-}
-
-/* Opcode: IdxGE P1 P2 P3 P4 P5
-**
-** The P4 register values beginning with P3 form an unpacked index
-** key that omits the ROWID. Compare this key value against the index
-** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
-**
-** If the P1 index entry is greater than or equal to the key value
-** then jump to P2. Otherwise fall through to the next instruction.
-**
-** If P5 is non-zero then the key value is increased by an epsilon
-** prior to the comparison. This make the opcode work like IdxGT except
-** that if the key from register P3 is a prefix of the key in the cursor,
-** the result is false whereas it would be true with IdxGT.
-*/
-/* Opcode: IdxLT P1 P2 P3 P4 P5
-**
-** The P4 register values beginning with P3 form an unpacked index
-** key that omits the ROWID. Compare this key value against the index
-** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
-**
-** If the P1 index entry is less than the key value then jump to P2.
-** Otherwise fall through to the next instruction.
-**
-** If P5 is non-zero then the key value is increased by an epsilon prior
-** to the comparison. This makes the opcode work like IdxLE.
-*/
-case OP_IdxLT: /* jump */
-case OP_IdxGE: { /* jump */
-#if 0 /* local variables moved into u.bv */
- VdbeCursor *pC;
- int res;
- UnpackedRecord r;
-#endif /* local variables moved into u.bv */
-
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bv.pC = p->apCsr[pOp->p1];
- assert( u.bv.pC!=0 );
- assert( u.bv.pC->isOrdered );
- if( ALWAYS(u.bv.pC->pCursor!=0) ){
- assert( u.bv.pC->deferredMoveto==0 );
- assert( pOp->p5==0 || pOp->p5==1 );
- assert( pOp->p4type==P4_INT32 );
- u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
- u.bv.r.nField = (u16)pOp->p4.i;
- if( pOp->p5 ){
- u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
- }else{
- u.bv.r.flags = UNPACKED_PREFIX_MATCH;
- }
- u.bv.r.aMem = &aMem[pOp->p3];
-#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); }
-#endif
- rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res);
- if( pOp->opcode==OP_IdxLT ){
- u.bv.res = -u.bv.res;
- }else{
- assert( pOp->opcode==OP_IdxGE );
- u.bv.res++;
- }
- if( u.bv.res>0 ){
- pc = pOp->p2 - 1 ;
- }
- }
- break;
-}
-
-/* Opcode: Destroy P1 P2 P3 * *
-**
-** Delete an entire database table or index whose root page in the database
-** file is given by P1.
-**
-** The table being destroyed is in the main database file if P3==0. If
-** P3==1 then the table to be clear is in the auxiliary database file
-** that is used to store tables create using CREATE TEMPORARY TABLE.
-**
-** If AUTOVACUUM is enabled then it is possible that another root page
-** might be moved into the newly deleted root page in order to keep all
-** root pages contiguous at the beginning of the database. The former
-** value of the root page that moved - its value before the move occurred -
-** is stored in register P2. If no page
-** movement was required (because the table being dropped was already
-** the last one in the database) then a zero is stored in register P2.
-** If AUTOVACUUM is disabled then a zero is stored in register P2.
-**
-** See also: Clear
-*/
-case OP_Destroy: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bw */
- int iMoved;
- int iCnt;
- Vdbe *pVdbe;
- int iDb;
-#endif /* local variables moved into u.bw */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- u.bw.iCnt = 0;
- for(u.bw.pVdbe=db->pVdbe; u.bw.pVdbe; u.bw.pVdbe = u.bw.pVdbe->pNext){
- if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0 ){
- u.bw.iCnt++;
- }
- }
-#else
- u.bw.iCnt = db->activeVdbeCnt;
-#endif
- pOut->flags = MEM_Null;
- if( u.bw.iCnt>1 ){
- rc = SQLITE_LOCKED;
- p->errorAction = OE_Abort;
- }else{
- u.bw.iDb = pOp->p3;
- assert( u.bw.iCnt==1 );
- assert( (p->btreeMask & (((yDbMask)1)<<u.bw.iDb))!=0 );
- rc = sqlite3BtreeDropTable(db->aDb[u.bw.iDb].pBt, pOp->p1, &u.bw.iMoved);
- pOut->flags = MEM_Int;
- pOut->u.i = u.bw.iMoved;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK && u.bw.iMoved!=0 ){
- sqlite3RootPageMoved(db, u.bw.iDb, u.bw.iMoved, pOp->p1);
- /* All OP_Destroy operations occur on the same btree */
- assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bw.iDb+1 );
- resetSchemaOnFault = u.bw.iDb+1;
- }
-#endif
- }
- break;
-}
-
-/* Opcode: Clear P1 P2 P3
-**
-** Delete all contents of the database table or index whose root page
-** in the database file is given by P1. But, unlike Destroy, do not
-** remove the table or index from the database file.
-**
-** The table being clear is in the main database file if P2==0. If
-** P2==1 then the table to be clear is in the auxiliary database file
-** that is used to store tables create using CREATE TEMPORARY TABLE.
-**
-** If the P3 value is non-zero, then the table referred to must be an
-** intkey table (an SQL table, not an index). In this case the row change
-** count is incremented by the number of rows in the table being cleared.
-** If P3 is greater than zero, then the value stored in register P3 is
-** also incremented by the number of rows in the table being cleared.
-**
-** See also: Destroy
-*/
-case OP_Clear: {
-#if 0 /* local variables moved into u.bx */
- int nChange;
-#endif /* local variables moved into u.bx */
-
- u.bx.nChange = 0;
- assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
- rc = sqlite3BtreeClearTable(
- db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0)
- );
- if( pOp->p3 ){
- p->nChange += u.bx.nChange;
- if( pOp->p3>0 ){
- assert( memIsValid(&aMem[pOp->p3]) );
- memAboutToChange(p, &aMem[pOp->p3]);
- aMem[pOp->p3].u.i += u.bx.nChange;
- }
- }
- break;
-}
-
-/* Opcode: CreateTable P1 P2 * * *
-**
-** Allocate a new table in the main database file if P1==0 or in the
-** auxiliary database file if P1==1 or in an attached database if
-** P1>1. Write the root page number of the new table into
-** register P2
-**
-** The difference between a table and an index is this: A table must
-** have a 4-byte integer key and can have arbitrary data. An index
-** has an arbitrary key but no data.
-**
-** See also: CreateIndex
-*/
-/* Opcode: CreateIndex P1 P2 * * *
-**
-** Allocate a new index in the main database file if P1==0 or in the
-** auxiliary database file if P1==1 or in an attached database if
-** P1>1. Write the root page number of the new table into
-** register P2.
-**
-** See documentation on OP_CreateTable for additional information.
-*/
-case OP_CreateIndex: /* out2-prerelease */
-case OP_CreateTable: { /* out2-prerelease */
-#if 0 /* local variables moved into u.by */
- int pgno;
- int flags;
- Db *pDb;
-#endif /* local variables moved into u.by */
-
- u.by.pgno = 0;
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
- u.by.pDb = &db->aDb[pOp->p1];
- assert( u.by.pDb->pBt!=0 );
- if( pOp->opcode==OP_CreateTable ){
- /* u.by.flags = BTREE_INTKEY; */
- u.by.flags = BTREE_INTKEY;
- }else{
- u.by.flags = BTREE_BLOBKEY;
- }
- rc = sqlite3BtreeCreateTable(u.by.pDb->pBt, &u.by.pgno, u.by.flags);
- pOut->u.i = u.by.pgno;
- break;
-}
-
-/* Opcode: ParseSchema P1 * * P4 *
-**
-** Read and parse all entries from the SQLITE_MASTER table of database P1
-** that match the WHERE clause P4.
-**
-** This opcode invokes the parser to create a new virtual machine,
-** then runs the new virtual machine. It is thus a re-entrant opcode.
-*/
-case OP_ParseSchema: {
-#if 0 /* local variables moved into u.bz */
- int iDb;
- const char *zMaster;
- char *zSql;
- InitData initData;
-#endif /* local variables moved into u.bz */
-
- /* Any prepared statement that invokes this opcode will hold mutexes
- ** on every btree. This is a prerequisite for invoking
- ** sqlite3InitCallback().
- */
-#ifdef SQLITE_DEBUG
- for(u.bz.iDb=0; u.bz.iDb<db->nDb; u.bz.iDb++){
- assert( u.bz.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bz.iDb].pBt) );
- }
-#endif
-
- u.bz.iDb = pOp->p1;
- assert( u.bz.iDb>=0 && u.bz.iDb<db->nDb );
- assert( DbHasProperty(db, u.bz.iDb, DB_SchemaLoaded) );
- /* Used to be a conditional */ {
- u.bz.zMaster = SCHEMA_TABLE(u.bz.iDb);
- u.bz.initData.db = db;
- u.bz.initData.iDb = pOp->p1;
- u.bz.initData.pzErrMsg = &p->zErrMsg;
- u.bz.zSql = sqlite3MPrintf(db,
- "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
- db->aDb[u.bz.iDb].zName, u.bz.zMaster, pOp->p4.z);
- if( u.bz.zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
- assert( db->init.busy==0 );
- db->init.busy = 1;
- u.bz.initData.rc = SQLITE_OK;
- assert( !db->mallocFailed );
- rc = sqlite3_exec(db, u.bz.zSql, sqlite3InitCallback, &u.bz.initData, 0);
- if( rc==SQLITE_OK ) rc = u.bz.initData.rc;
- sqlite3DbFree(db, u.bz.zSql);
- db->init.busy = 0;
- }
- }
- if( rc ) sqlite3ResetAllSchemasOfConnection(db);
- if( rc==SQLITE_NOMEM ){
- goto no_mem;
- }
- break;
-}
-
-#if !defined(SQLITE_OMIT_ANALYZE)
-/* Opcode: LoadAnalysis P1 * * * *
-**
-** Read the sqlite_stat1 table for database P1 and load the content
-** of that table into the internal index hash table. This will cause
-** the analysis to be used when preparing all subsequent queries.
-*/
-case OP_LoadAnalysis: {
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- rc = sqlite3AnalysisLoad(db, pOp->p1);
- break;
-}
-#endif /* !defined(SQLITE_OMIT_ANALYZE) */
-
-/* Opcode: DropTable P1 * * P4 *
-**
-** Remove the internal (in-memory) data structures that describe
-** the table named P4 in database P1. This is called after a table
-** is dropped in order to keep the internal representation of the
-** schema consistent with what is on disk.
-*/
-case OP_DropTable: {
- sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z);
- break;
-}
-
-/* Opcode: DropIndex P1 * * P4 *
-**
-** Remove the internal (in-memory) data structures that describe
-** the index named P4 in database P1. This is called after an index
-** is dropped in order to keep the internal representation of the
-** schema consistent with what is on disk.
-*/
-case OP_DropIndex: {
- sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z);
- break;
-}
-
-/* Opcode: DropTrigger P1 * * P4 *
-**
-** Remove the internal (in-memory) data structures that describe
-** the trigger named P4 in database P1. This is called after a trigger
-** is dropped in order to keep the internal representation of the
-** schema consistent with what is on disk.
-*/
-case OP_DropTrigger: {
- sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z);
- break;
-}
-
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
-/* Opcode: IntegrityCk P1 P2 P3 * P5
-**
-** Do an analysis of the currently open database. Store in
-** register P1 the text of an error message describing any problems.
-** If no problems are found, store a NULL in register P1.
-**
-** The register P3 contains the maximum number of allowed errors.
-** At most reg(P3) errors will be reported.
-** In other words, the analysis stops as soon as reg(P1) errors are
-** seen. Reg(P1) is updated with the number of errors remaining.
-**
-** The root page numbers of all tables in the database are integer
-** stored in reg(P1), reg(P1+1), reg(P1+2), .... There are P2 tables
-** total.
-**
-** If P5 is not zero, the check is done on the auxiliary database
-** file, not the main database file.
-**
-** This opcode is used to implement the integrity_check pragma.
-*/
-case OP_IntegrityCk: {
-#if 0 /* local variables moved into u.ca */
- int nRoot; /* Number of tables to check. (Number of root pages.) */
- int *aRoot; /* Array of rootpage numbers for tables to be checked */
- int j; /* Loop counter */
- int nErr; /* Number of errors reported */
- char *z; /* Text of the error report */
- Mem *pnErr; /* Register keeping track of errors remaining */
-#endif /* local variables moved into u.ca */
-
- u.ca.nRoot = pOp->p2;
- assert( u.ca.nRoot>0 );
- u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) );
- if( u.ca.aRoot==0 ) goto no_mem;
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- u.ca.pnErr = &aMem[pOp->p3];
- assert( (u.ca.pnErr->flags & MEM_Int)!=0 );
- assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
- pIn1 = &aMem[pOp->p1];
- for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){
- u.ca.aRoot[u.ca.j] = (int)sqlite3VdbeIntValue(&pIn1[u.ca.j]);
- }
- u.ca.aRoot[u.ca.j] = 0;
- assert( pOp->p5<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 );
- u.ca.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.ca.aRoot, u.ca.nRoot,
- (int)u.ca.pnErr->u.i, &u.ca.nErr);
- sqlite3DbFree(db, u.ca.aRoot);
- u.ca.pnErr->u.i -= u.ca.nErr;
- sqlite3VdbeMemSetNull(pIn1);
- if( u.ca.nErr==0 ){
- assert( u.ca.z==0 );
- }else if( u.ca.z==0 ){
- goto no_mem;
- }else{
- sqlite3VdbeMemSetStr(pIn1, u.ca.z, -1, SQLITE_UTF8, sqlite3_free);
- }
- UPDATE_MAX_BLOBSIZE(pIn1);
- sqlite3VdbeChangeEncoding(pIn1, encoding);
- break;
-}
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-/* Opcode: RowSetAdd P1 P2 * * *
-**
-** Insert the integer value held by register P2 into a boolean index
-** held in register P1.
-**
-** An assertion fails if P2 is not an integer.
-*/
-case OP_RowSetAdd: { /* in1, in2 */
- pIn1 = &aMem[pOp->p1];
- pIn2 = &aMem[pOp->p2];
- assert( (pIn2->flags & MEM_Int)!=0 );
- if( (pIn1->flags & MEM_RowSet)==0 ){
- sqlite3VdbeMemSetRowSet(pIn1);
- if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
- }
- sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
- break;
-}
-
-/* Opcode: RowSetRead P1 P2 P3 * *
-**
-** Extract the smallest value from boolean index P1 and put that value into
-** register P3. Or, if boolean index P1 is initially empty, leave P3
-** unchanged and jump to instruction P2.
-*/
-case OP_RowSetRead: { /* jump, in1, out3 */
-#if 0 /* local variables moved into u.cb */
- i64 val;
-#endif /* local variables moved into u.cb */
- CHECK_FOR_INTERRUPT;
- pIn1 = &aMem[pOp->p1];
- if( (pIn1->flags & MEM_RowSet)==0
- || sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0
- ){
- /* The boolean index is empty */
- sqlite3VdbeMemSetNull(pIn1);
- pc = pOp->p2 - 1;
- }else{
- /* A value was pulled from the index */
- sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
- }
- break;
-}
-
-/* Opcode: RowSetTest P1 P2 P3 P4
-**
-** Register P3 is assumed to hold a 64-bit integer value. If register P1
-** contains a RowSet object and that RowSet object contains
-** the value held in P3, jump to register P2. Otherwise, insert the
-** integer in P3 into the RowSet and continue on to the
-** next opcode.
-**
-** The RowSet object is optimized for the case where successive sets
-** of integers, where each set contains no duplicates. Each set
-** of values is identified by a unique P4 value. The first set
-** must have P4==0, the final set P4=-1. P4 must be either -1 or
-** non-negative. For non-negative values of P4 only the lower 4
-** bits are significant.
-**
-** This allows optimizations: (a) when P4==0 there is no need to test
-** the rowset object for P3, as it is guaranteed not to contain it,
-** (b) when P4==-1 there is no need to insert the value, as it will
-** never be tested for, and (c) when a value that is part of set X is
-** inserted, there is no need to search to see if the same value was
-** previously inserted as part of set X (only if it was previously
-** inserted as part of some other set).
-*/
-case OP_RowSetTest: { /* jump, in1, in3 */
-#if 0 /* local variables moved into u.cc */
- int iSet;
- int exists;
-#endif /* local variables moved into u.cc */
-
- pIn1 = &aMem[pOp->p1];
- pIn3 = &aMem[pOp->p3];
- u.cc.iSet = pOp->p4.i;
- assert( pIn3->flags&MEM_Int );
-
- /* If there is anything other than a rowset object in memory cell P1,
- ** delete it now and initialize P1 with an empty rowset
- */
- if( (pIn1->flags & MEM_RowSet)==0 ){
- sqlite3VdbeMemSetRowSet(pIn1);
- if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
- }
-
- assert( pOp->p4type==P4_INT32 );
- assert( u.cc.iSet==-1 || u.cc.iSet>=0 );
- if( u.cc.iSet ){
- u.cc.exists = sqlite3RowSetTest(pIn1->u.pRowSet,
- (u8)(u.cc.iSet>=0 ? u.cc.iSet & 0xf : 0xff),
- pIn3->u.i);
- if( u.cc.exists ){
- pc = pOp->p2 - 1;
- break;
- }
- }
- if( u.cc.iSet>=0 ){
- sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
- }
- break;
-}
-
-
-#ifndef SQLITE_OMIT_TRIGGER
-
-/* Opcode: Program P1 P2 P3 P4 *
-**
-** Execute the trigger program passed as P4 (type P4_SUBPROGRAM).
-**
-** P1 contains the address of the memory cell that contains the first memory
-** cell in an array of values used as arguments to the sub-program. P2
-** contains the address to jump to if the sub-program throws an IGNORE
-** exception using the RAISE() function. Register P3 contains the address
-** of a memory cell in this (the parent) VM that is used to allocate the
-** memory required by the sub-vdbe at runtime.
-**
-** P4 is a pointer to the VM containing the trigger program.
-*/
-case OP_Program: { /* jump */
-#if 0 /* local variables moved into u.cd */
- int nMem; /* Number of memory registers for sub-program */
- int nByte; /* Bytes of runtime space required for sub-program */
- Mem *pRt; /* Register to allocate runtime space */
- Mem *pMem; /* Used to iterate through memory cells */
- Mem *pEnd; /* Last memory cell in new array */
- VdbeFrame *pFrame; /* New vdbe frame to execute in */
- SubProgram *pProgram; /* Sub-program to execute */
- void *t; /* Token identifying trigger */
-#endif /* local variables moved into u.cd */
-
- u.cd.pProgram = pOp->p4.pProgram;
- u.cd.pRt = &aMem[pOp->p3];
- assert( u.cd.pProgram->nOp>0 );
-
- /* If the p5 flag is clear, then recursive invocation of triggers is
- ** disabled for backwards compatibility (p5 is set if this sub-program
- ** is really a trigger, not a foreign key action, and the flag set
- ** and cleared by the "PRAGMA recursive_triggers" command is clear).
- **
- ** It is recursive invocation of triggers, at the SQL level, that is
- ** disabled. In some cases a single trigger may generate more than one
- ** SubProgram (if the trigger may be executed with more than one different
- ** ON CONFLICT algorithm). SubProgram structures associated with a
- ** single trigger all have the same value for the SubProgram.token
- ** variable. */
- if( pOp->p5 ){
- u.cd.t = u.cd.pProgram->token;
- for(u.cd.pFrame=p->pFrame; u.cd.pFrame && u.cd.pFrame->token!=u.cd.t; u.cd.pFrame=u.cd.pFrame->pParent);
- if( u.cd.pFrame ) break;
- }
-
- if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
- rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
- break;
- }
-
- /* Register u.cd.pRt is used to store the memory required to save the state
- ** of the current program, and the memory required at runtime to execute
- ** the trigger program. If this trigger has been fired before, then u.cd.pRt
- ** is already allocated. Otherwise, it must be initialized. */
- if( (u.cd.pRt->flags&MEM_Frame)==0 ){
- /* SubProgram.nMem is set to the number of memory cells used by the
- ** program stored in SubProgram.aOp. As well as these, one memory
- ** cell is required for each cursor used by the program. Set local
- ** variable u.cd.nMem (and later, VdbeFrame.nChildMem) to this value.
- */
- u.cd.nMem = u.cd.pProgram->nMem + u.cd.pProgram->nCsr;
- u.cd.nByte = ROUND8(sizeof(VdbeFrame))
- + u.cd.nMem * sizeof(Mem)
- + u.cd.pProgram->nCsr * sizeof(VdbeCursor *)
- + u.cd.pProgram->nOnce * sizeof(u8);
- u.cd.pFrame = sqlite3DbMallocZero(db, u.cd.nByte);
- if( !u.cd.pFrame ){
- goto no_mem;
- }
- sqlite3VdbeMemRelease(u.cd.pRt);
- u.cd.pRt->flags = MEM_Frame;
- u.cd.pRt->u.pFrame = u.cd.pFrame;
-
- u.cd.pFrame->v = p;
- u.cd.pFrame->nChildMem = u.cd.nMem;
- u.cd.pFrame->nChildCsr = u.cd.pProgram->nCsr;
- u.cd.pFrame->pc = pc;
- u.cd.pFrame->aMem = p->aMem;
- u.cd.pFrame->nMem = p->nMem;
- u.cd.pFrame->apCsr = p->apCsr;
- u.cd.pFrame->nCursor = p->nCursor;
- u.cd.pFrame->aOp = p->aOp;
- u.cd.pFrame->nOp = p->nOp;
- u.cd.pFrame->token = u.cd.pProgram->token;
- u.cd.pFrame->aOnceFlag = p->aOnceFlag;
- u.cd.pFrame->nOnceFlag = p->nOnceFlag;
-
- u.cd.pEnd = &VdbeFrameMem(u.cd.pFrame)[u.cd.pFrame->nChildMem];
- for(u.cd.pMem=VdbeFrameMem(u.cd.pFrame); u.cd.pMem!=u.cd.pEnd; u.cd.pMem++){
- u.cd.pMem->flags = MEM_Invalid;
- u.cd.pMem->db = db;
- }
- }else{
- u.cd.pFrame = u.cd.pRt->u.pFrame;
- assert( u.cd.pProgram->nMem+u.cd.pProgram->nCsr==u.cd.pFrame->nChildMem );
- assert( u.cd.pProgram->nCsr==u.cd.pFrame->nChildCsr );
- assert( pc==u.cd.pFrame->pc );
- }
-
- p->nFrame++;
- u.cd.pFrame->pParent = p->pFrame;
- u.cd.pFrame->lastRowid = lastRowid;
- u.cd.pFrame->nChange = p->nChange;
- p->nChange = 0;
- p->pFrame = u.cd.pFrame;
- p->aMem = aMem = &VdbeFrameMem(u.cd.pFrame)[-1];
- p->nMem = u.cd.pFrame->nChildMem;
- p->nCursor = (u16)u.cd.pFrame->nChildCsr;
- p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
- p->aOp = aOp = u.cd.pProgram->aOp;
- p->nOp = u.cd.pProgram->nOp;
- p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
- p->nOnceFlag = u.cd.pProgram->nOnce;
- pc = -1;
- memset(p->aOnceFlag, 0, p->nOnceFlag);
-
- break;
-}
-
-/* Opcode: Param P1 P2 * * *
-**
-** This opcode is only ever present in sub-programs called via the
-** OP_Program instruction. Copy a value currently stored in a memory
-** cell of the calling (parent) frame to cell P2 in the current frames
-** address space. This is used by trigger programs to access the new.*
-** and old.* values.
-**
-** The address of the cell in the parent frame is determined by adding
-** the value of the P1 argument to the value of the P1 argument to the
-** calling OP_Program instruction.
-*/
-case OP_Param: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ce */
- VdbeFrame *pFrame;
- Mem *pIn;
-#endif /* local variables moved into u.ce */
- u.ce.pFrame = p->pFrame;
- u.ce.pIn = &u.ce.pFrame->aMem[pOp->p1 + u.ce.pFrame->aOp[u.ce.pFrame->pc].p1];
- sqlite3VdbeMemShallowCopy(pOut, u.ce.pIn, MEM_Ephem);
- break;
-}
-
-#endif /* #ifndef SQLITE_OMIT_TRIGGER */
-
-#ifndef SQLITE_OMIT_FOREIGN_KEY
-/* Opcode: FkCounter P1 P2 * * *
-**
-** Increment a "constraint counter" by P2 (P2 may be negative or positive).
-** If P1 is non-zero, the database constraint counter is incremented
-** (deferred foreign key constraints). Otherwise, if P1 is zero, the
-** statement counter is incremented (immediate foreign key constraints).
-*/
-case OP_FkCounter: {
- if( pOp->p1 ){
- db->nDeferredCons += pOp->p2;
- }else{
- p->nFkConstraint += pOp->p2;
- }
- break;
-}
-
-/* Opcode: FkIfZero P1 P2 * * *
-**
-** This opcode tests if a foreign key constraint-counter is currently zero.
-** If so, jump to instruction P2. Otherwise, fall through to the next
-** instruction.
-**
-** If P1 is non-zero, then the jump is taken if the database constraint-counter
-** is zero (the one that counts deferred constraint violations). If P1 is
-** zero, the jump is taken if the statement constraint-counter is zero
-** (immediate foreign key constraint violations).
-*/
-case OP_FkIfZero: { /* jump */
- if( pOp->p1 ){
- if( db->nDeferredCons==0 ) pc = pOp->p2-1;
- }else{
- if( p->nFkConstraint==0 ) pc = pOp->p2-1;
- }
- break;
-}
-#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
-/* Opcode: MemMax P1 P2 * * *
-**
-** P1 is a register in the root frame of this VM (the root frame is
-** different from the current frame if this instruction is being executed
-** within a sub-program). Set the value of register P1 to the maximum of
-** its current value and the value in register P2.
-**
-** This instruction throws an error if the memory cell is not initially
-** an integer.
-*/
-case OP_MemMax: { /* in2 */
-#if 0 /* local variables moved into u.cf */
- Mem *pIn1;
- VdbeFrame *pFrame;
-#endif /* local variables moved into u.cf */
- if( p->pFrame ){
- for(u.cf.pFrame=p->pFrame; u.cf.pFrame->pParent; u.cf.pFrame=u.cf.pFrame->pParent);
- u.cf.pIn1 = &u.cf.pFrame->aMem[pOp->p1];
- }else{
- u.cf.pIn1 = &aMem[pOp->p1];
- }
- assert( memIsValid(u.cf.pIn1) );
- sqlite3VdbeMemIntegerify(u.cf.pIn1);
- pIn2 = &aMem[pOp->p2];
- sqlite3VdbeMemIntegerify(pIn2);
- if( u.cf.pIn1->u.i<pIn2->u.i){
- u.cf.pIn1->u.i = pIn2->u.i;
- }
- break;
-}
-#endif /* SQLITE_OMIT_AUTOINCREMENT */
-
-/* Opcode: IfPos P1 P2 * * *
-**
-** If the value of register P1 is 1 or greater, jump to P2.
-**
-** It is illegal to use this instruction on a register that does
-** not contain an integer. An assertion fault will result if you try.
-*/
-case OP_IfPos: { /* jump, in1 */
- pIn1 = &aMem[pOp->p1];
- assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i>0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: IfNeg P1 P2 * * *
-**
-** If the value of register P1 is less than zero, jump to P2.
-**
-** It is illegal to use this instruction on a register that does
-** not contain an integer. An assertion fault will result if you try.
-*/
-case OP_IfNeg: { /* jump, in1 */
- pIn1 = &aMem[pOp->p1];
- assert( pIn1->flags&MEM_Int );
- if( pIn1->u.i<0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: IfZero P1 P2 P3 * *
-**
-** The register P1 must contain an integer. Add literal P3 to the
-** value in register P1. If the result is exactly 0, jump to P2.
-**
-** It is illegal to use this instruction on a register that does
-** not contain an integer. An assertion fault will result if you try.
-*/
-case OP_IfZero: { /* jump, in1 */
- pIn1 = &aMem[pOp->p1];
- assert( pIn1->flags&MEM_Int );
- pIn1->u.i += pOp->p3;
- if( pIn1->u.i==0 ){
- pc = pOp->p2 - 1;
- }
- break;
-}
-
-/* Opcode: AggStep * P2 P3 P4 P5
-**
-** Execute the step function for an aggregate. The
-** function has P5 arguments. P4 is a pointer to the FuncDef
-** structure that specifies the function. Use register
-** P3 as the accumulator.
-**
-** The P5 arguments are taken from register P2 and its
-** successors.
-*/
-case OP_AggStep: {
-#if 0 /* local variables moved into u.cg */
- int n;
- int i;
- Mem *pMem;
- Mem *pRec;
- sqlite3_context ctx;
- sqlite3_value **apVal;
-#endif /* local variables moved into u.cg */
-
- u.cg.n = pOp->p5;
- assert( u.cg.n>=0 );
- u.cg.pRec = &aMem[pOp->p2];
- u.cg.apVal = p->apArg;
- assert( u.cg.apVal || u.cg.n==0 );
- for(u.cg.i=0; u.cg.i<u.cg.n; u.cg.i++, u.cg.pRec++){
- assert( memIsValid(u.cg.pRec) );
- u.cg.apVal[u.cg.i] = u.cg.pRec;
- memAboutToChange(p, u.cg.pRec);
- sqlite3VdbeMemStoreType(u.cg.pRec);
- }
- u.cg.ctx.pFunc = pOp->p4.pFunc;
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3];
- u.cg.pMem->n++;
- u.cg.ctx.s.flags = MEM_Null;
- u.cg.ctx.s.z = 0;
- u.cg.ctx.s.zMalloc = 0;
- u.cg.ctx.s.xDel = 0;
- u.cg.ctx.s.db = db;
- u.cg.ctx.isError = 0;
- u.cg.ctx.pColl = 0;
- u.cg.ctx.skipFlag = 0;
- if( u.cg.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
- assert( pOp>p->aOp );
- assert( pOp[-1].p4type==P4_COLLSEQ );
- assert( pOp[-1].opcode==OP_CollSeq );
- u.cg.ctx.pColl = pOp[-1].p4.pColl;
- }
- (u.cg.ctx.pFunc->xStep)(&u.cg.ctx, u.cg.n, u.cg.apVal); /* IMP: R-24505-23230 */
- if( u.cg.ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cg.ctx.s));
- rc = u.cg.ctx.isError;
- }
- if( u.cg.ctx.skipFlag ){
- assert( pOp[-1].opcode==OP_CollSeq );
- u.cg.i = pOp[-1].p1;
- if( u.cg.i ) sqlite3VdbeMemSetInt64(&aMem[u.cg.i], 1);
- }
-
- sqlite3VdbeMemRelease(&u.cg.ctx.s);
-
- break;
-}
-
-/* Opcode: AggFinal P1 P2 * P4 *
-**
-** Execute the finalizer function for an aggregate. P1 is
-** the memory location that is the accumulator for the aggregate.
-**
-** P2 is the number of arguments that the step function takes and
-** P4 is a pointer to the FuncDef for this function. The P2
-** argument is not used by this opcode. It is only there to disambiguate
-** functions that can take varying numbers of arguments. The
-** P4 argument is only needed for the degenerate case where
-** the step function was not previously called.
-*/
-case OP_AggFinal: {
-#if 0 /* local variables moved into u.ch */
- Mem *pMem;
-#endif /* local variables moved into u.ch */
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
- u.ch.pMem = &aMem[pOp->p1];
- assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
- rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc);
- if( rc ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem));
- }
- sqlite3VdbeChangeEncoding(u.ch.pMem, encoding);
- UPDATE_MAX_BLOBSIZE(u.ch.pMem);
- if( sqlite3VdbeMemTooBig(u.ch.pMem) ){
- goto too_big;
- }
- break;
-}
-
-#ifndef SQLITE_OMIT_WAL
-/* Opcode: Checkpoint P1 P2 P3 * *
-**
-** Checkpoint database P1. This is a no-op if P1 is not currently in
-** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL
-** or RESTART. Write 1 or 0 into mem[P3] if the checkpoint returns
-** SQLITE_BUSY or not, respectively. Write the number of pages in the
-** WAL after the checkpoint into mem[P3+1] and the number of pages
-** in the WAL that have been checkpointed after the checkpoint
-** completes into mem[P3+2]. However on an error, mem[P3+1] and
-** mem[P3+2] are initialized to -1.
-*/
-case OP_Checkpoint: {
-#if 0 /* local variables moved into u.ci */
- int i; /* Loop counter */
- int aRes[3]; /* Results */
- Mem *pMem; /* Write results here */
-#endif /* local variables moved into u.ci */
-
- u.ci.aRes[0] = 0;
- u.ci.aRes[1] = u.ci.aRes[2] = -1;
- assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
- || pOp->p2==SQLITE_CHECKPOINT_FULL
- || pOp->p2==SQLITE_CHECKPOINT_RESTART
- );
- rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ci.aRes[1], &u.ci.aRes[2]);
- if( rc==SQLITE_BUSY ){
- rc = SQLITE_OK;
- u.ci.aRes[0] = 1;
- }
- for(u.ci.i=0, u.ci.pMem = &aMem[pOp->p3]; u.ci.i<3; u.ci.i++, u.ci.pMem++){
- sqlite3VdbeMemSetInt64(u.ci.pMem, (i64)u.ci.aRes[u.ci.i]);
- }
- break;
-};
-#endif
-
-#ifndef SQLITE_OMIT_PRAGMA
-/* Opcode: JournalMode P1 P2 P3 * P5
-**
-** Change the journal mode of database P1 to P3. P3 must be one of the
-** PAGER_JOURNALMODE_XXX values. If changing between the various rollback
-** modes (delete, truncate, persist, off and memory), this is a simple
-** operation. No IO is required.
-**
-** If changing into or out of WAL mode the procedure is more complicated.
-**
-** Write a string containing the final journal-mode to register P2.
-*/
-case OP_JournalMode: { /* out2-prerelease */
-#if 0 /* local variables moved into u.cj */
- Btree *pBt; /* Btree to change journal mode of */
- Pager *pPager; /* Pager associated with pBt */
- int eNew; /* New journal mode */
- int eOld; /* The old journal mode */
-#ifndef SQLITE_OMIT_WAL
- const char *zFilename; /* Name of database file for pPager */
-#endif
-#endif /* local variables moved into u.cj */
-
- u.cj.eNew = pOp->p3;
- assert( u.cj.eNew==PAGER_JOURNALMODE_DELETE
- || u.cj.eNew==PAGER_JOURNALMODE_TRUNCATE
- || u.cj.eNew==PAGER_JOURNALMODE_PERSIST
- || u.cj.eNew==PAGER_JOURNALMODE_OFF
- || u.cj.eNew==PAGER_JOURNALMODE_MEMORY
- || u.cj.eNew==PAGER_JOURNALMODE_WAL
- || u.cj.eNew==PAGER_JOURNALMODE_QUERY
- );
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
-
- u.cj.pBt = db->aDb[pOp->p1].pBt;
- u.cj.pPager = sqlite3BtreePager(u.cj.pBt);
- u.cj.eOld = sqlite3PagerGetJournalMode(u.cj.pPager);
- if( u.cj.eNew==PAGER_JOURNALMODE_QUERY ) u.cj.eNew = u.cj.eOld;
- if( !sqlite3PagerOkToChangeJournalMode(u.cj.pPager) ) u.cj.eNew = u.cj.eOld;
-
-#ifndef SQLITE_OMIT_WAL
- u.cj.zFilename = sqlite3PagerFilename(u.cj.pPager, 1);
-
- /* Do not allow a transition to journal_mode=WAL for a database
- ** in temporary storage or if the VFS does not support shared memory
- */
- if( u.cj.eNew==PAGER_JOURNALMODE_WAL
- && (sqlite3Strlen30(u.cj.zFilename)==0 /* Temp file */
- || !sqlite3PagerWalSupported(u.cj.pPager)) /* No shared-memory support */
- ){
- u.cj.eNew = u.cj.eOld;
- }
-
- if( (u.cj.eNew!=u.cj.eOld)
- && (u.cj.eOld==PAGER_JOURNALMODE_WAL || u.cj.eNew==PAGER_JOURNALMODE_WAL)
- ){
- if( !db->autoCommit || db->activeVdbeCnt>1 ){
- rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db,
- "cannot change %s wal mode from within a transaction",
- (u.cj.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
- );
- break;
- }else{
-
- if( u.cj.eOld==PAGER_JOURNALMODE_WAL ){
- /* If leaving WAL mode, close the log file. If successful, the call
- ** to PagerCloseWal() checkpoints and deletes the write-ahead-log
- ** file. An EXCLUSIVE lock may still be held on the database file
- ** after a successful return.
- */
- rc = sqlite3PagerCloseWal(u.cj.pPager);
- if( rc==SQLITE_OK ){
- sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);
- }
- }else if( u.cj.eOld==PAGER_JOURNALMODE_MEMORY ){
- /* Cannot transition directly from MEMORY to WAL. Use mode OFF
- ** as an intermediate */
- sqlite3PagerSetJournalMode(u.cj.pPager, PAGER_JOURNALMODE_OFF);
- }
-
- /* Open a transaction on the database file. Regardless of the journal
- ** mode, this transaction always uses a rollback journal.
- */
- assert( sqlite3BtreeIsInTrans(u.cj.pBt)==0 );
- if( rc==SQLITE_OK ){
- rc = sqlite3BtreeSetVersion(u.cj.pBt, (u.cj.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
- }
- }
- }
-#endif /* ifndef SQLITE_OMIT_WAL */
-
- if( rc ){
- u.cj.eNew = u.cj.eOld;
- }
- u.cj.eNew = sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);
-
- pOut = &aMem[pOp->p2];
- pOut->flags = MEM_Str|MEM_Static|MEM_Term;
- pOut->z = (char *)sqlite3JournalModename(u.cj.eNew);
- pOut->n = sqlite3Strlen30(pOut->z);
- pOut->enc = SQLITE_UTF8;
- sqlite3VdbeChangeEncoding(pOut, encoding);
- break;
-};
-#endif /* SQLITE_OMIT_PRAGMA */
-
-#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
-/* Opcode: Vacuum * * * * *
-**
-** Vacuum the entire database. This opcode will cause other virtual
-** machines to be created and run. It may not be called from within
-** a transaction.
-*/
-case OP_Vacuum: {
- rc = sqlite3RunVacuum(&p->zErrMsg, db);
- break;
-}
-#endif
-
-#if !defined(SQLITE_OMIT_AUTOVACUUM)
-/* Opcode: IncrVacuum P1 P2 * * *
-**
-** Perform a single step of the incremental vacuum procedure on
-** the P1 database. If the vacuum has finished, jump to instruction
-** P2. Otherwise, fall through to the next instruction.
-*/
-case OP_IncrVacuum: { /* jump */
-#if 0 /* local variables moved into u.ck */
- Btree *pBt;
-#endif /* local variables moved into u.ck */
-
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
- u.ck.pBt = db->aDb[pOp->p1].pBt;
- rc = sqlite3BtreeIncrVacuum(u.ck.pBt);
- if( rc==SQLITE_DONE ){
- pc = pOp->p2 - 1;
- rc = SQLITE_OK;
- }
- break;
-}
-#endif
-
-/* Opcode: Expire P1 * * * *
-**
-** Cause precompiled statements to become expired. An expired statement
-** fails with an error code of SQLITE_SCHEMA if it is ever executed
-** (via sqlite3_step()).
-**
-** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
-** then only the currently executing statement is affected.
-*/
-case OP_Expire: {
- if( !pOp->p1 ){
- sqlite3ExpirePreparedStatements(db);
- }else{
- p->expired = 1;
- }
- break;
-}
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/* Opcode: TableLock P1 P2 P3 P4 *
-**
-** Obtain a lock on a particular table. This instruction is only used when
-** the shared-cache feature is enabled.
-**
-** P1 is the index of the database in sqlite3.aDb[] of the database
-** on which the lock is acquired. A readlock is obtained if P3==0 or
-** a write lock if P3==1.
-**
-** P2 contains the root-page of the table to lock.
-**
-** P4 contains a pointer to the name of the table being locked. This is only
-** used to generate an error message if the lock cannot be obtained.
-*/
-case OP_TableLock: {
- u8 isWriteLock = (u8)pOp->p3;
- if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
- int p1 = pOp->p1;
- assert( p1>=0 && p1<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<p1))!=0 );
- assert( isWriteLock==0 || isWriteLock==1 );
- rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
- if( (rc&0xFF)==SQLITE_LOCKED ){
- const char *z = pOp->p4.z;
- sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
- }
- }
- break;
-}
-#endif /* SQLITE_OMIT_SHARED_CACHE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VBegin * * * P4 *
-**
-** P4 may be a pointer to an sqlite3_vtab structure. If so, call the
-** xBegin method for that table.
-**
-** Also, whether or not P4 is set, check that this is not being called from
-** within a callback to a virtual table xSync() method. If it is, the error
-** code will be set to SQLITE_LOCKED.
-*/
-case OP_VBegin: {
-#if 0 /* local variables moved into u.cl */
- VTable *pVTab;
-#endif /* local variables moved into u.cl */
- u.cl.pVTab = pOp->p4.pVtab;
- rc = sqlite3VtabBegin(db, u.cl.pVTab);
- if( u.cl.pVTab ) importVtabErrMsg(p, u.cl.pVTab->pVtab);
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VCreate P1 * * P4 *
-**
-** P4 is the name of a virtual table in database P1. Call the xCreate method
-** for that table.
-*/
-case OP_VCreate: {
- rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.z, &p->zErrMsg);
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VDestroy P1 * * P4 *
-**
-** P4 is the name of a virtual table in database P1. Call the xDestroy method
-** of that table.
-*/
-case OP_VDestroy: {
- p->inVtabMethod = 2;
- rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
- p->inVtabMethod = 0;
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VOpen P1 * * P4 *
-**
-** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
-** P1 is a cursor number. This opcode opens a cursor to the virtual
-** table and stores that cursor in P1.
-*/
-case OP_VOpen: {
-#if 0 /* local variables moved into u.cm */
- VdbeCursor *pCur;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
-#endif /* local variables moved into u.cm */
-
- u.cm.pCur = 0;
- u.cm.pVtabCursor = 0;
- u.cm.pVtab = pOp->p4.pVtab->pVtab;
- u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule;
- assert(u.cm.pVtab && u.cm.pModule);
- rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor);
- importVtabErrMsg(p, u.cm.pVtab);
- if( SQLITE_OK==rc ){
- /* Initialize sqlite3_vtab_cursor base class */
- u.cm.pVtabCursor->pVtab = u.cm.pVtab;
-
- /* Initialise vdbe cursor object */
- u.cm.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
- if( u.cm.pCur ){
- u.cm.pCur->pVtabCursor = u.cm.pVtabCursor;
- u.cm.pCur->pModule = u.cm.pVtabCursor->pVtab->pModule;
- }else{
- db->mallocFailed = 1;
- u.cm.pModule->xClose(u.cm.pVtabCursor);
- }
- }
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VFilter P1 P2 P3 P4 *
-**
-** P1 is a cursor opened using VOpen. P2 is an address to jump to if
-** the filtered result set is empty.
-**
-** P4 is either NULL or a string that was generated by the xBestIndex
-** method of the module. The interpretation of the P4 string is left
-** to the module implementation.
-**
-** This opcode invokes the xFilter method on the virtual table specified
-** by P1. The integer query plan parameter to xFilter is stored in register
-** P3. Register P3+1 stores the argc parameter to be passed to the
-** xFilter method. Registers P3+2..P3+1+argc are the argc
-** additional parameters which are passed to
-** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter.
-**
-** A jump is made to P2 if the result set after filtering would be empty.
-*/
-case OP_VFilter: { /* jump */
-#if 0 /* local variables moved into u.cn */
- int nArg;
- int iQuery;
- const sqlite3_module *pModule;
- Mem *pQuery;
- Mem *pArgc;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- VdbeCursor *pCur;
- int res;
- int i;
- Mem **apArg;
-#endif /* local variables moved into u.cn */
-
- u.cn.pQuery = &aMem[pOp->p3];
- u.cn.pArgc = &u.cn.pQuery[1];
- u.cn.pCur = p->apCsr[pOp->p1];
- assert( memIsValid(u.cn.pQuery) );
- REGISTER_TRACE(pOp->p3, u.cn.pQuery);
- assert( u.cn.pCur->pVtabCursor );
- u.cn.pVtabCursor = u.cn.pCur->pVtabCursor;
- u.cn.pVtab = u.cn.pVtabCursor->pVtab;
- u.cn.pModule = u.cn.pVtab->pModule;
-
- /* Grab the index number and argc parameters */
- assert( (u.cn.pQuery->flags&MEM_Int)!=0 && u.cn.pArgc->flags==MEM_Int );
- u.cn.nArg = (int)u.cn.pArgc->u.i;
- u.cn.iQuery = (int)u.cn.pQuery->u.i;
-
- /* Invoke the xFilter method */
- {
- u.cn.res = 0;
- u.cn.apArg = p->apArg;
- for(u.cn.i = 0; u.cn.i<u.cn.nArg; u.cn.i++){
- u.cn.apArg[u.cn.i] = &u.cn.pArgc[u.cn.i+1];
- sqlite3VdbeMemStoreType(u.cn.apArg[u.cn.i]);
- }
-
- p->inVtabMethod = 1;
- rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg);
- p->inVtabMethod = 0;
- importVtabErrMsg(p, u.cn.pVtab);
- if( rc==SQLITE_OK ){
- u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor);
- }
-
- if( u.cn.res ){
- pc = pOp->p2 - 1;
- }
- }
- u.cn.pCur->nullRow = 0;
-
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VColumn P1 P2 P3 * *
-**
-** Store the value of the P2-th column of
-** the row of the virtual-table that the
-** P1 cursor is pointing to into register P3.
-*/
-case OP_VColumn: {
-#if 0 /* local variables moved into u.co */
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- Mem *pDest;
- sqlite3_context sContext;
-#endif /* local variables moved into u.co */
-
- VdbeCursor *pCur = p->apCsr[pOp->p1];
- assert( pCur->pVtabCursor );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- u.co.pDest = &aMem[pOp->p3];
- memAboutToChange(p, u.co.pDest);
- if( pCur->nullRow ){
- sqlite3VdbeMemSetNull(u.co.pDest);
- break;
- }
- u.co.pVtab = pCur->pVtabCursor->pVtab;
- u.co.pModule = u.co.pVtab->pModule;
- assert( u.co.pModule->xColumn );
- memset(&u.co.sContext, 0, sizeof(u.co.sContext));
-
- /* The output cell may already have a buffer allocated. Move
- ** the current contents to u.co.sContext.s so in case the user-function
- ** can use the already allocated buffer instead of allocating a
- ** new one.
- */
- sqlite3VdbeMemMove(&u.co.sContext.s, u.co.pDest);
- MemSetTypeFlag(&u.co.sContext.s, MEM_Null);
-
- rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2);
- importVtabErrMsg(p, u.co.pVtab);
- if( u.co.sContext.isError ){
- rc = u.co.sContext.isError;
- }
-
- /* Copy the result of the function to the P3 register. We
- ** do this regardless of whether or not an error occurred to ensure any
- ** dynamic allocation in u.co.sContext.s (a Mem struct) is released.
- */
- sqlite3VdbeChangeEncoding(&u.co.sContext.s, encoding);
- sqlite3VdbeMemMove(u.co.pDest, &u.co.sContext.s);
- REGISTER_TRACE(pOp->p3, u.co.pDest);
- UPDATE_MAX_BLOBSIZE(u.co.pDest);
-
- if( sqlite3VdbeMemTooBig(u.co.pDest) ){
- goto too_big;
- }
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VNext P1 P2 * * *
-**
-** Advance virtual table P1 to the next row in its result set and
-** jump to instruction P2. Or, if the virtual table has reached
-** the end of its result set, then fall through to the next instruction.
-*/
-case OP_VNext: { /* jump */
-#if 0 /* local variables moved into u.cp */
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- int res;
- VdbeCursor *pCur;
-#endif /* local variables moved into u.cp */
-
- u.cp.res = 0;
- u.cp.pCur = p->apCsr[pOp->p1];
- assert( u.cp.pCur->pVtabCursor );
- if( u.cp.pCur->nullRow ){
- break;
- }
- u.cp.pVtab = u.cp.pCur->pVtabCursor->pVtab;
- u.cp.pModule = u.cp.pVtab->pModule;
- assert( u.cp.pModule->xNext );
-
- /* Invoke the xNext() method of the module. There is no way for the
- ** underlying implementation to return an error if one occurs during
- ** xNext(). Instead, if an error occurs, true is returned (indicating that
- ** data is available) and the error code returned when xColumn or
- ** some other method is next invoked on the save virtual table cursor.
- */
- p->inVtabMethod = 1;
- rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor);
- p->inVtabMethod = 0;
- importVtabErrMsg(p, u.cp.pVtab);
- if( rc==SQLITE_OK ){
- u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor);
- }
-
- if( !u.cp.res ){
- /* If there is data, jump to P2 */
- pc = pOp->p2 - 1;
- }
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VRename P1 * * P4 *
-**
-** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
-** This opcode invokes the corresponding xRename method. The value
-** in register P1 is passed as the zName argument to the xRename method.
-*/
-case OP_VRename: {
-#if 0 /* local variables moved into u.cq */
- sqlite3_vtab *pVtab;
- Mem *pName;
-#endif /* local variables moved into u.cq */
-
- u.cq.pVtab = pOp->p4.pVtab->pVtab;
- u.cq.pName = &aMem[pOp->p1];
- assert( u.cq.pVtab->pModule->xRename );
- assert( memIsValid(u.cq.pName) );
- REGISTER_TRACE(pOp->p1, u.cq.pName);
- assert( u.cq.pName->flags & MEM_Str );
- testcase( u.cq.pName->enc==SQLITE_UTF8 );
- testcase( u.cq.pName->enc==SQLITE_UTF16BE );
- testcase( u.cq.pName->enc==SQLITE_UTF16LE );
- rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8);
- if( rc==SQLITE_OK ){
- rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z);
- importVtabErrMsg(p, u.cq.pVtab);
- p->expired = 0;
- }
- break;
-}
-#endif
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VUpdate P1 P2 P3 P4 *
-**
-** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
-** This opcode invokes the corresponding xUpdate method. P2 values
-** are contiguous memory cells starting at P3 to pass to the xUpdate
-** invocation. The value in register (P3+P2-1) corresponds to the
-** p2th element of the argv array passed to xUpdate.
-**
-** The xUpdate method will do a DELETE or an INSERT or both.
-** The argv[0] element (which corresponds to memory cell P3)
-** is the rowid of a row to delete. If argv[0] is NULL then no
-** deletion occurs. The argv[1] element is the rowid of the new
-** row. This can be NULL to have the virtual table select the new
-** rowid for itself. The subsequent elements in the array are
-** the values of columns in the new row.
-**
-** If P2==1 then no insert is performed. argv[0] is the rowid of
-** a row to delete.
-**
-** P1 is a boolean flag. If it is set to true and the xUpdate call
-** is successful, then the value returned by sqlite3_last_insert_rowid()
-** is set to the value of the rowid for the row just inserted.
-*/
-case OP_VUpdate: {
-#if 0 /* local variables moved into u.cr */
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
- int nArg;
- int i;
- sqlite_int64 rowid;
- Mem **apArg;
- Mem *pX;
-#endif /* local variables moved into u.cr */
-
- assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
- || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
- );
- u.cr.pVtab = pOp->p4.pVtab->pVtab;
- u.cr.pModule = (sqlite3_module *)u.cr.pVtab->pModule;
- u.cr.nArg = pOp->p2;
- assert( pOp->p4type==P4_VTAB );
- if( ALWAYS(u.cr.pModule->xUpdate) ){
- u8 vtabOnConflict = db->vtabOnConflict;
- u.cr.apArg = p->apArg;
- u.cr.pX = &aMem[pOp->p3];
- for(u.cr.i=0; u.cr.i<u.cr.nArg; u.cr.i++){
- assert( memIsValid(u.cr.pX) );
- memAboutToChange(p, u.cr.pX);
- sqlite3VdbeMemStoreType(u.cr.pX);
- u.cr.apArg[u.cr.i] = u.cr.pX;
- u.cr.pX++;
- }
- db->vtabOnConflict = pOp->p5;
- rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid);
- db->vtabOnConflict = vtabOnConflict;
- importVtabErrMsg(p, u.cr.pVtab);
- if( rc==SQLITE_OK && pOp->p1 ){
- assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
- db->lastRowid = lastRowid = u.cr.rowid;
- }
- if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
- if( pOp->p5==OE_Ignore ){
- rc = SQLITE_OK;
- }else{
- p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5);
- }
- }else{
- p->nChange++;
- }
- }
- break;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/* Opcode: Pagecount P1 P2 * * *
-**
-** Write the current number of pages in database P1 to memory cell P2.
-*/
-case OP_Pagecount: { /* out2-prerelease */
- pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
- break;
-}
-#endif
-
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/* Opcode: MaxPgcnt P1 P2 P3 * *
-**
-** Try to set the maximum page count for database P1 to the value in P3.
-** Do not let the maximum page count fall below the current page count and
-** do not change the maximum page count value if P3==0.
-**
-** Store the maximum page count after the change in register P2.
-*/
-case OP_MaxPgcnt: { /* out2-prerelease */
- unsigned int newMax;
- Btree *pBt;
-
- pBt = db->aDb[pOp->p1].pBt;
- newMax = 0;
- if( pOp->p3 ){
- newMax = sqlite3BtreeLastPage(pBt);
- if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3;
- }
- pOut->u.i = sqlite3BtreeMaxPageCount(pBt, newMax);
- break;
-}
-#endif
-
-
-#ifndef SQLITE_OMIT_TRACE
-/* Opcode: Trace * * * P4 *
-**
-** If tracing is enabled (by the sqlite3_trace()) interface, then
-** the UTF-8 string contained in P4 is emitted on the trace callback.
-*/
-case OP_Trace: {
-#if 0 /* local variables moved into u.cs */
- char *zTrace;
- char *z;
-#endif /* local variables moved into u.cs */
-
- if( db->xTrace
- && !p->doingRerun
- && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
- ){
- u.cs.z = sqlite3VdbeExpandSql(p, u.cs.zTrace);
- db->xTrace(db->pTraceArg, u.cs.z);
- sqlite3DbFree(db, u.cs.z);
- }
-#ifdef SQLITE_DEBUG
- if( (db->flags & SQLITE_SqlTrace)!=0
- && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
- ){
- sqlite3DebugPrintf("SQL-trace: %s\n", u.cs.zTrace);
- }
-#endif /* SQLITE_DEBUG */
- break;
-}
-#endif
-
-
-/* Opcode: Noop * * * * *
-**
-** Do nothing. This instruction is often useful as a jump
-** destination.
-*/
-/*
-** The magic Explain opcode are only inserted when explain==2 (which
-** is to say when the EXPLAIN QUERY PLAN syntax is used.)
-** This opcode records information from the optimizer. It is the
-** the same as a no-op. This opcodesnever appears in a real VM program.
-*/
-default: { /* This is really OP_Noop and OP_Explain */
- assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain );
- break;
-}
-
-/*****************************************************************************
-** The cases of the switch statement above this line should all be indented
-** by 6 spaces. But the left-most 6 spaces have been removed to improve the
-** readability. From this point on down, the normal indentation rules are
-** restored.
-*****************************************************************************/
- }
-
-#ifdef VDBE_PROFILE
- {
- u64 elapsed = sqlite3Hwtime() - start;
- pOp->cycles += elapsed;
- pOp->cnt++;
-#if 0
- fprintf(stdout, "%10llu ", elapsed);
- sqlite3VdbePrintOp(stdout, origPc, &aOp[origPc]);
-#endif
- }
-#endif
-
- /* The following code adds nothing to the actual functionality
- ** of the program. It is only here for testing and debugging.
- ** On the other hand, it does burn CPU cycles every time through
- ** the evaluator loop. So we can leave it out when NDEBUG is defined.
- */
-#ifndef NDEBUG
- assert( pc>=-1 && pc<p->nOp );
-
-#ifdef SQLITE_DEBUG
- if( p->trace ){
- if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc);
- if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
- registerTrace(p->trace, pOp->p2, &aMem[pOp->p2]);
- }
- if( pOp->opflags & OPFLG_OUT3 ){
- registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]);
- }
- }
-#endif /* SQLITE_DEBUG */
-#endif /* NDEBUG */
- } /* The end of the for(;;) loop the loops through opcodes */
-
- /* If we reach this point, it means that execution is finished with
- ** an error of some kind.
- */
-vdbe_error_halt:
- assert( rc );
- p->rc = rc;
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(rc, "statement aborts at %d: [%s] %s",
- pc, p->zSql, p->zErrMsg);
- sqlite3VdbeHalt(p);
- if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
- rc = SQLITE_ERROR;
- if( resetSchemaOnFault>0 ){
- sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
- }
-
- /* This is the only way out of this procedure. We have to
- ** release the mutexes on btrees that were acquired at the
- ** top. */
-vdbe_return:
- db->lastRowid = lastRowid;
- sqlite3VdbeLeave(p);
- return rc;
-
- /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
- ** is encountered.
- */
-too_big:
- sqlite3SetString(&p->zErrMsg, db, "string or blob too big");
- rc = SQLITE_TOOBIG;
- goto vdbe_error_halt;
-
- /* Jump to here if a malloc() fails.
- */
-no_mem:
- db->mallocFailed = 1;
- sqlite3SetString(&p->zErrMsg, db, "out of memory");
- rc = SQLITE_NOMEM;
- goto vdbe_error_halt;
-
- /* Jump to here for any other kind of fatal error. The "rc" variable
- ** should hold the error number.
- */
-abort_due_to_error:
- assert( p->zErrMsg==0 );
- if( db->mallocFailed ) rc = SQLITE_NOMEM;
- if( rc!=SQLITE_IOERR_NOMEM ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
- }
- goto vdbe_error_halt;
-
- /* Jump to here if the sqlite3_interrupt() API sets the interrupt
- ** flag.
- */
-abort_due_to_interrupt:
- assert( db->u1.isInterrupted );
- rc = SQLITE_INTERRUPT;
- p->rc = rc;
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto vdbe_error_halt;
-}
-
-/************** End of vdbe.c ************************************************/
-/************** Begin file vdbeblob.c ****************************************/
-/*
-** 2007 May 1
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains code used to implement incremental BLOB I/O.
-*/
-
-
-#ifndef SQLITE_OMIT_INCRBLOB
-
-/*
-** Valid sqlite3_blob* handles point to Incrblob structures.
-*/
-typedef struct Incrblob Incrblob;
-struct Incrblob {
- int flags; /* Copy of "flags" passed to sqlite3_blob_open() */
- int nByte; /* Size of open blob, in bytes */
- int iOffset; /* Byte offset of blob in cursor data */
- int iCol; /* Table column this handle is open on */
- BtCursor *pCsr; /* Cursor pointing at blob row */
- sqlite3_stmt *pStmt; /* Statement holding cursor open */
- sqlite3 *db; /* The associated database */
-};
-
-
-/*
-** This function is used by both blob_open() and blob_reopen(). It seeks
-** the b-tree cursor associated with blob handle p to point to row iRow.
-** If successful, SQLITE_OK is returned and subsequent calls to
-** sqlite3_blob_read() or sqlite3_blob_write() access the specified row.
-**
-** If an error occurs, or if the specified row does not exist or does not
-** contain a value of type TEXT or BLOB in the column nominated when the
-** blob handle was opened, then an error code is returned and *pzErr may
-** be set to point to a buffer containing an error message. It is the
-** responsibility of the caller to free the error message buffer using
-** sqlite3DbFree().
-**
-** If an error does occur, then the b-tree cursor is closed. All subsequent
-** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will
-** immediately return SQLITE_ABORT.
-*/
-static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
- int rc; /* Error code */
- char *zErr = 0; /* Error message */
- Vdbe *v = (Vdbe *)p->pStmt;
-
- /* Set the value of the SQL statements only variable to integer iRow.
- ** This is done directly instead of using sqlite3_bind_int64() to avoid
- ** triggering asserts related to mutexes.
- */
- assert( v->aVar[0].flags&MEM_Int );
- v->aVar[0].u.i = iRow;
-
- rc = sqlite3_step(p->pStmt);
- if( rc==SQLITE_ROW ){
- u32 type = v->apCsr[0]->aType[p->iCol];
- if( type<12 ){
- zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
- type==0?"null": type==7?"real": "integer"
- );
- rc = SQLITE_ERROR;
- sqlite3_finalize(p->pStmt);
- p->pStmt = 0;
- }else{
- p->iOffset = v->apCsr[0]->aOffset[p->iCol];
- p->nByte = sqlite3VdbeSerialTypeLen(type);
- p->pCsr = v->apCsr[0]->pCursor;
- sqlite3BtreeEnterCursor(p->pCsr);
- sqlite3BtreeCacheOverflow(p->pCsr);
- sqlite3BtreeLeaveCursor(p->pCsr);
- }
- }
-
- if( rc==SQLITE_ROW ){
- rc = SQLITE_OK;
- }else if( p->pStmt ){
- rc = sqlite3_finalize(p->pStmt);
- p->pStmt = 0;
- if( rc==SQLITE_OK ){
- zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow);
- rc = SQLITE_ERROR;
- }else{
- zErr = sqlite3MPrintf(p->db, "%s", sqlite3_errmsg(p->db));
- }
- }
-
- assert( rc!=SQLITE_OK || zErr==0 );
- assert( rc!=SQLITE_ROW && rc!=SQLITE_DONE );
-
- *pzErr = zErr;
- return rc;
-}
-
-/*
-** Open a blob handle.
-*/
-SQLITE_API int sqlite3_blob_open(
- sqlite3* db, /* The database connection */
- const char *zDb, /* The attached database containing the blob */
- const char *zTable, /* The table containing the blob */
- const char *zColumn, /* The column containing the blob */
- sqlite_int64 iRow, /* The row containing the glob */
- int flags, /* True -> read/write access, false -> read-only */
- sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */
-){
- int nAttempt = 0;
- int iCol; /* Index of zColumn in row-record */
-
- /* This VDBE program seeks a btree cursor to the identified
- ** db/table/row entry. The reason for using a vdbe program instead
- ** of writing code to use the b-tree layer directly is that the
- ** vdbe program will take advantage of the various transaction,
- ** locking and error handling infrastructure built into the vdbe.
- **
- ** After seeking the cursor, the vdbe executes an OP_ResultRow.
- ** Code external to the Vdbe then "borrows" the b-tree cursor and
- ** uses it to implement the blob_read(), blob_write() and
- ** blob_bytes() functions.
- **
- ** The sqlite3_blob_close() function finalizes the vdbe program,
- ** which closes the b-tree cursor and (possibly) commits the
- ** transaction.
- */
- static const VdbeOpList openBlob[] = {
- {OP_Transaction, 0, 0, 0}, /* 0: Start a transaction */
- {OP_VerifyCookie, 0, 0, 0}, /* 1: Check the schema cookie */
- {OP_TableLock, 0, 0, 0}, /* 2: Acquire a read or write lock */
-
- /* One of the following two instructions is replaced by an OP_Noop. */
- {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */
- {OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */
-
- {OP_Variable, 1, 1, 1}, /* 5: Push the rowid to the stack */
- {OP_NotExists, 0, 10, 1}, /* 6: Seek the cursor */
- {OP_Column, 0, 0, 1}, /* 7 */
- {OP_ResultRow, 1, 0, 0}, /* 8 */
- {OP_Goto, 0, 5, 0}, /* 9 */
- {OP_Close, 0, 0, 0}, /* 10 */
- {OP_Halt, 0, 0, 0}, /* 11 */
- };
-
- int rc = SQLITE_OK;
- char *zErr = 0;
- Table *pTab;
- Parse *pParse = 0;
- Incrblob *pBlob = 0;
-
- flags = !!flags; /* flags = (flags ? 1 : 0); */
- *ppBlob = 0;
-
- sqlite3_mutex_enter(db->mutex);
-
- pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
- if( !pBlob ) goto blob_open_out;
- pParse = sqlite3StackAllocRaw(db, sizeof(*pParse));
- if( !pParse ) goto blob_open_out;
-
- do {
- memset(pParse, 0, sizeof(Parse));
- pParse->db = db;
- sqlite3DbFree(db, zErr);
- zErr = 0;
-
- sqlite3BtreeEnterAll(db);
- pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
- if( pTab && IsVirtual(pTab) ){
- pTab = 0;
- sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
- }
-#ifndef SQLITE_OMIT_VIEW
- if( pTab && pTab->pSelect ){
- pTab = 0;
- sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable);
- }
-#endif
- if( !pTab ){
- if( pParse->zErrMsg ){
- sqlite3DbFree(db, zErr);
- zErr = pParse->zErrMsg;
- pParse->zErrMsg = 0;
- }
- rc = SQLITE_ERROR;
- sqlite3BtreeLeaveAll(db);
- goto blob_open_out;
- }
-
- /* Now search pTab for the exact column. */
- for(iCol=0; iCol<pTab->nCol; iCol++) {
- if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){
- break;
- }
- }
- if( iCol==pTab->nCol ){
- sqlite3DbFree(db, zErr);
- zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
- rc = SQLITE_ERROR;
- sqlite3BtreeLeaveAll(db);
- goto blob_open_out;
- }
-
- /* If the value is being opened for writing, check that the
- ** column is not indexed, and that it is not part of a foreign key.
- ** It is against the rules to open a column to which either of these
- ** descriptions applies for writing. */
- if( flags ){
- const char *zFault = 0;
- Index *pIdx;
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- if( db->flags&SQLITE_ForeignKeys ){
- /* Check that the column is not part of an FK child key definition. It
- ** is not necessary to check if it is part of a parent key, as parent
- ** key columns must be indexed. The check below will pick up this
- ** case. */
- FKey *pFKey;
- for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
- int j;
- for(j=0; j<pFKey->nCol; j++){
- if( pFKey->aCol[j].iFrom==iCol ){
- zFault = "foreign key";
- }
- }
- }
- }
-#endif
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- int j;
- for(j=0; j<pIdx->nColumn; j++){
- if( pIdx->aiColumn[j]==iCol ){
- zFault = "indexed";
- }
- }
- }
- if( zFault ){
- sqlite3DbFree(db, zErr);
- zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault);
- rc = SQLITE_ERROR;
- sqlite3BtreeLeaveAll(db);
- goto blob_open_out;
- }
- }
-
- pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db);
- assert( pBlob->pStmt || db->mallocFailed );
- if( pBlob->pStmt ){
- Vdbe *v = (Vdbe *)pBlob->pStmt;
- int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
-
- sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
-
-
- /* Configure the OP_Transaction */
- sqlite3VdbeChangeP1(v, 0, iDb);
- sqlite3VdbeChangeP2(v, 0, flags);
-
- /* Configure the OP_VerifyCookie */
- sqlite3VdbeChangeP1(v, 1, iDb);
- sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);
- sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration);
-
- /* Make sure a mutex is held on the table to be accessed */
- sqlite3VdbeUsesBtree(v, iDb);
-
- /* Configure the OP_TableLock instruction */
-#ifdef SQLITE_OMIT_SHARED_CACHE
- sqlite3VdbeChangeToNoop(v, 2);
-#else
- sqlite3VdbeChangeP1(v, 2, iDb);
- sqlite3VdbeChangeP2(v, 2, pTab->tnum);
- sqlite3VdbeChangeP3(v, 2, flags);
- sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
-#endif
-
- /* Remove either the OP_OpenWrite or OpenRead. Set the P2
- ** parameter of the other to pTab->tnum. */
- sqlite3VdbeChangeToNoop(v, 4 - flags);
- sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum);
- sqlite3VdbeChangeP3(v, 3 + flags, iDb);
-
- /* Configure the number of columns. Configure the cursor to
- ** think that the table has one more column than it really
- ** does. An OP_Column to retrieve this imaginary column will
- ** always return an SQL NULL. This is useful because it means
- ** we can invoke OP_Column to fill in the vdbe cursors type
- ** and offset cache without causing any IO.
- */
- sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
- sqlite3VdbeChangeP2(v, 7, pTab->nCol);
- if( !db->mallocFailed ){
- pParse->nVar = 1;
- pParse->nMem = 1;
- pParse->nTab = 1;
- sqlite3VdbeMakeReady(v, pParse);
- }
- }
-
- pBlob->flags = flags;
- pBlob->iCol = iCol;
- pBlob->db = db;
- sqlite3BtreeLeaveAll(db);
- if( db->mallocFailed ){
- goto blob_open_out;
- }
- sqlite3_bind_int64(pBlob->pStmt, 1, iRow);
- rc = blobSeekToRow(pBlob, iRow, &zErr);
- } while( (++nAttempt)<5 && rc==SQLITE_SCHEMA );
-
-blob_open_out:
- if( rc==SQLITE_OK && db->mallocFailed==0 ){
- *ppBlob = (sqlite3_blob *)pBlob;
- }else{
- if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
- sqlite3DbFree(db, pBlob);
- }
- sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr);
- sqlite3DbFree(db, zErr);
- sqlite3StackFree(db, pParse);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Close a blob handle that was previously created using
-** sqlite3_blob_open().
-*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
- Incrblob *p = (Incrblob *)pBlob;
- int rc;
- sqlite3 *db;
-
- if( p ){
- db = p->db;
- sqlite3_mutex_enter(db->mutex);
- rc = sqlite3_finalize(p->pStmt);
- sqlite3DbFree(db, p);
- sqlite3_mutex_leave(db->mutex);
- }else{
- rc = SQLITE_OK;
- }
- return rc;
-}
-
-/*
-** Perform a read or write operation on a blob
-*/
-static int blobReadWrite(
- sqlite3_blob *pBlob,
- void *z,
- int n,
- int iOffset,
- int (*xCall)(BtCursor*, u32, u32, void*)
-){
- int rc;
- Incrblob *p = (Incrblob *)pBlob;
- Vdbe *v;
- sqlite3 *db;
-
- if( p==0 ) return SQLITE_MISUSE_BKPT;
- db = p->db;
- sqlite3_mutex_enter(db->mutex);
- v = (Vdbe*)p->pStmt;
-
- if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
- /* Request is out of range. Return a transient error. */
- rc = SQLITE_ERROR;
- sqlite3Error(db, SQLITE_ERROR, 0);
- }else if( v==0 ){
- /* If there is no statement handle, then the blob-handle has
- ** already been invalidated. Return SQLITE_ABORT in this case.
- */
- rc = SQLITE_ABORT;
- }else{
- /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
- ** returned, clean-up the statement handle.
- */
- assert( db == v->db );
- sqlite3BtreeEnterCursor(p->pCsr);
- rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
- sqlite3BtreeLeaveCursor(p->pCsr);
- if( rc==SQLITE_ABORT ){
- sqlite3VdbeFinalize(v);
- p->pStmt = 0;
- }else{
- db->errCode = rc;
- v->rc = rc;
- }
- }
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Read data from a blob handle.
-*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
- return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
-}
-
-/*
-** Write data to a blob handle.
-*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
- return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
-}
-
-/*
-** Query a blob handle for the size of the data.
-**
-** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
-** so no mutex is required for access.
-*/
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
- Incrblob *p = (Incrblob *)pBlob;
- return (p && p->pStmt) ? p->nByte : 0;
-}
-
-/*
-** Move an existing blob handle to point to a different row of the same
-** database table.
-**
-** If an error occurs, or if the specified row does not exist or does not
-** contain a blob or text value, then an error code is returned and the
-** database handle error code and message set. If this happens, then all
-** subsequent calls to sqlite3_blob_xxx() functions (except blob_close())
-** immediately return SQLITE_ABORT.
-*/
-SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
- int rc;
- Incrblob *p = (Incrblob *)pBlob;
- sqlite3 *db;
-
- if( p==0 ) return SQLITE_MISUSE_BKPT;
- db = p->db;
- sqlite3_mutex_enter(db->mutex);
-
- if( p->pStmt==0 ){
- /* If there is no statement handle, then the blob-handle has
- ** already been invalidated. Return SQLITE_ABORT in this case.
- */
- rc = SQLITE_ABORT;
- }else{
- char *zErr;
- rc = blobSeekToRow(p, iRow, &zErr);
- if( rc!=SQLITE_OK ){
- sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr);
- sqlite3DbFree(db, zErr);
- }
- assert( rc!=SQLITE_SCHEMA );
- }
-
- rc = sqlite3ApiExit(db, rc);
- assert( rc==SQLITE_OK || p->pStmt==0 );
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-#endif /* #ifndef SQLITE_OMIT_INCRBLOB */
-
-/************** End of vdbeblob.c ********************************************/
-/************** Begin file vdbesort.c ****************************************/
-/*
-** 2011 July 9
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code for the VdbeSorter object, used in concert with
-** a VdbeCursor to sort large numbers of keys (as may be required, for
-** example, by CREATE INDEX statements on tables too large to fit in main
-** memory).
-*/
-
-
-#ifndef SQLITE_OMIT_MERGE_SORT
-
-typedef struct VdbeSorterIter VdbeSorterIter;
-typedef struct SorterRecord SorterRecord;
-typedef struct FileWriter FileWriter;
-
-/*
-** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES:
-**
-** As keys are added to the sorter, they are written to disk in a series
-** of sorted packed-memory-arrays (PMAs). The size of each PMA is roughly
-** the same as the cache-size allowed for temporary databases. In order
-** to allow the caller to extract keys from the sorter in sorted order,
-** all PMAs currently stored on disk must be merged together. This comment
-** describes the data structure used to do so. The structure supports
-** merging any number of arrays in a single pass with no redundant comparison
-** operations.
-**
-** The aIter[] array contains an iterator for each of the PMAs being merged.
-** An aIter[] iterator either points to a valid key or else is at EOF. For
-** the purposes of the paragraphs below, we assume that the array is actually
-** N elements in size, where N is the smallest power of 2 greater to or equal
-** to the number of iterators being merged. The extra aIter[] elements are
-** treated as if they are empty (always at EOF).
-**
-** The aTree[] array is also N elements in size. The value of N is stored in
-** the VdbeSorter.nTree variable.
-**
-** The final (N/2) elements of aTree[] contain the results of comparing
-** pairs of iterator keys together. Element i contains the result of
-** comparing aIter[2*i-N] and aIter[2*i-N+1]. Whichever key is smaller, the
-** aTree element is set to the index of it.
-**
-** For the purposes of this comparison, EOF is considered greater than any
-** other key value. If the keys are equal (only possible with two EOF
-** values), it doesn't matter which index is stored.
-**
-** The (N/4) elements of aTree[] that preceed the final (N/2) described
-** above contains the index of the smallest of each block of 4 iterators.
-** And so on. So that aTree[1] contains the index of the iterator that
-** currently points to the smallest key value. aTree[0] is unused.
-**
-** Example:
-**
-** aIter[0] -> Banana
-** aIter[1] -> Feijoa
-** aIter[2] -> Elderberry
-** aIter[3] -> Currant
-** aIter[4] -> Grapefruit
-** aIter[5] -> Apple
-** aIter[6] -> Durian
-** aIter[7] -> EOF
-**
-** aTree[] = { X, 5 0, 5 0, 3, 5, 6 }
-**
-** The current element is "Apple" (the value of the key indicated by
-** iterator 5). When the Next() operation is invoked, iterator 5 will
-** be advanced to the next key in its segment. Say the next key is
-** "Eggplant":
-**
-** aIter[5] -> Eggplant
-**
-** The contents of aTree[] are updated first by comparing the new iterator
-** 5 key to the current key of iterator 4 (still "Grapefruit"). The iterator
-** 5 value is still smaller, so aTree[6] is set to 5. And so on up the tree.
-** The value of iterator 6 - "Durian" - is now smaller than that of iterator
-** 5, so aTree[3] is set to 6. Key 0 is smaller than key 6 (Banana<Durian),
-** so the value written into element 1 of the array is 0. As follows:
-**
-** aTree[] = { X, 0 0, 6 0, 3, 5, 6 }
-**
-** In other words, each time we advance to the next sorter element, log2(N)
-** key comparison operations are required, where N is the number of segments
-** being merged (rounded up to the next power of 2).
-*/
-struct VdbeSorter {
- i64 iWriteOff; /* Current write offset within file pTemp1 */
- i64 iReadOff; /* Current read offset within file pTemp1 */
- int nInMemory; /* Current size of pRecord list as PMA */
- int nTree; /* Used size of aTree/aIter (power of 2) */
- int nPMA; /* Number of PMAs stored in pTemp1 */
- int mnPmaSize; /* Minimum PMA size, in bytes */
- int mxPmaSize; /* Maximum PMA size, in bytes. 0==no limit */
- VdbeSorterIter *aIter; /* Array of iterators to merge */
- int *aTree; /* Current state of incremental merge */
- sqlite3_file *pTemp1; /* PMA file 1 */
- SorterRecord *pRecord; /* Head of in-memory record list */
- UnpackedRecord *pUnpacked; /* Used to unpack keys */
-};
-
-/*
-** The following type is an iterator for a PMA. It caches the current key in
-** variables nKey/aKey. If the iterator is at EOF, pFile==0.
-*/
-struct VdbeSorterIter {
- i64 iReadOff; /* Current read offset */
- i64 iEof; /* 1 byte past EOF for this iterator */
- int nAlloc; /* Bytes of space at aAlloc */
- int nKey; /* Number of bytes in key */
- sqlite3_file *pFile; /* File iterator is reading from */
- u8 *aAlloc; /* Allocated space */
- u8 *aKey; /* Pointer to current key */
- u8 *aBuffer; /* Current read buffer */
- int nBuffer; /* Size of read buffer in bytes */
-};
-
-/*
-** An instance of this structure is used to organize the stream of records
-** being written to files by the merge-sort code into aligned, page-sized
-** blocks. Doing all I/O in aligned page-sized blocks helps I/O to go
-** faster on many operating systems.
-*/
-struct FileWriter {
- int eFWErr; /* Non-zero if in an error state */
- u8 *aBuffer; /* Pointer to write buffer */
- int nBuffer; /* Size of write buffer in bytes */
- int iBufStart; /* First byte of buffer to write */
- int iBufEnd; /* Last byte of buffer to write */
- i64 iWriteOff; /* Offset of start of buffer in file */
- sqlite3_file *pFile; /* File to write to */
-};
-
-/*
-** A structure to store a single record. All in-memory records are connected
-** together into a linked list headed at VdbeSorter.pRecord using the
-** SorterRecord.pNext pointer.
-*/
-struct SorterRecord {
- void *pVal;
- int nVal;
- SorterRecord *pNext;
-};
-
-/* Minimum allowable value for the VdbeSorter.nWorking variable */
-#define SORTER_MIN_WORKING 10
-
-/* Maximum number of segments to merge in a single pass. */
-#define SORTER_MAX_MERGE_COUNT 16
-
-/*
-** Free all memory belonging to the VdbeSorterIter object passed as the second
-** argument. All structure fields are set to zero before returning.
-*/
-static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){
- sqlite3DbFree(db, pIter->aAlloc);
- sqlite3DbFree(db, pIter->aBuffer);
- memset(pIter, 0, sizeof(VdbeSorterIter));
-}
-
-/*
-** Read nByte bytes of data from the stream of data iterated by object p.
-** If successful, set *ppOut to point to a buffer containing the data
-** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite
-** error code.
-**
-** The buffer indicated by *ppOut may only be considered valid until the
-** next call to this function.
-*/
-static int vdbeSorterIterRead(
- sqlite3 *db, /* Database handle (for malloc) */
- VdbeSorterIter *p, /* Iterator */
- int nByte, /* Bytes of data to read */
- u8 **ppOut /* OUT: Pointer to buffer containing data */
-){
- int iBuf; /* Offset within buffer to read from */
- int nAvail; /* Bytes of data available in buffer */
- assert( p->aBuffer );
-
- /* If there is no more data to be read from the buffer, read the next
- ** p->nBuffer bytes of data from the file into it. Or, if there are less
- ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */
- iBuf = p->iReadOff % p->nBuffer;
- if( iBuf==0 ){
- int nRead; /* Bytes to read from disk */
- int rc; /* sqlite3OsRead() return code */
-
- /* Determine how many bytes of data to read. */
- if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){
- nRead = p->nBuffer;
- }else{
- nRead = (int)(p->iEof - p->iReadOff);
- }
- assert( nRead>0 );
-
- /* Read data from the file. Return early if an error occurs. */
- rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff);
- assert( rc!=SQLITE_IOERR_SHORT_READ );
- if( rc!=SQLITE_OK ) return rc;
- }
- nAvail = p->nBuffer - iBuf;
-
- if( nByte<=nAvail ){
- /* The requested data is available in the in-memory buffer. In this
- ** case there is no need to make a copy of the data, just return a
- ** pointer into the buffer to the caller. */
- *ppOut = &p->aBuffer[iBuf];
- p->iReadOff += nByte;
- }else{
- /* The requested data is not all available in the in-memory buffer.
- ** In this case, allocate space at p->aAlloc[] to copy the requested
- ** range into. Then return a copy of pointer p->aAlloc to the caller. */
- int nRem; /* Bytes remaining to copy */
-
- /* Extend the p->aAlloc[] allocation if required. */
- if( p->nAlloc<nByte ){
- int nNew = p->nAlloc*2;
- while( nByte>nNew ) nNew = nNew*2;
- p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew);
- if( !p->aAlloc ) return SQLITE_NOMEM;
- p->nAlloc = nNew;
- }
-
- /* Copy as much data as is available in the buffer into the start of
- ** p->aAlloc[]. */
- memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail);
- p->iReadOff += nAvail;
- nRem = nByte - nAvail;
-
- /* The following loop copies up to p->nBuffer bytes per iteration into
- ** the p->aAlloc[] buffer. */
- while( nRem>0 ){
- int rc; /* vdbeSorterIterRead() return code */
- int nCopy; /* Number of bytes to copy */
- u8 *aNext; /* Pointer to buffer to copy data from */
-
- nCopy = nRem;
- if( nRem>p->nBuffer ) nCopy = p->nBuffer;
- rc = vdbeSorterIterRead(db, p, nCopy, &aNext);
- if( rc!=SQLITE_OK ) return rc;
- assert( aNext!=p->aAlloc );
- memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy);
- nRem -= nCopy;
- }
-
- *ppOut = p->aAlloc;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Read a varint from the stream of data accessed by p. Set *pnOut to
-** the value read.
-*/
-static int vdbeSorterIterVarint(sqlite3 *db, VdbeSorterIter *p, u64 *pnOut){
- int iBuf;
-
- iBuf = p->iReadOff % p->nBuffer;
- if( iBuf && (p->nBuffer-iBuf)>=9 ){
- p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut);
- }else{
- u8 aVarint[16], *a;
- int i = 0, rc;
- do{
- rc = vdbeSorterIterRead(db, p, 1, &a);
- if( rc ) return rc;
- aVarint[(i++)&0xf] = a[0];
- }while( (a[0]&0x80)!=0 );
- sqlite3GetVarint(aVarint, pnOut);
- }
-
- return SQLITE_OK;
-}
-
-
-/*
-** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if
-** no error occurs, or an SQLite error code if one does.
-*/
-static int vdbeSorterIterNext(
- sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */
- VdbeSorterIter *pIter /* Iterator to advance */
-){
- int rc; /* Return Code */
- u64 nRec = 0; /* Size of record in bytes */
-
- if( pIter->iReadOff>=pIter->iEof ){
- /* This is an EOF condition */
- vdbeSorterIterZero(db, pIter);
- return SQLITE_OK;
- }
-
- rc = vdbeSorterIterVarint(db, pIter, &nRec);
- if( rc==SQLITE_OK ){
- pIter->nKey = (int)nRec;
- rc = vdbeSorterIterRead(db, pIter, (int)nRec, &pIter->aKey);
- }
-
- return rc;
-}
-
-/*
-** Initialize iterator pIter to scan through the PMA stored in file pFile
-** starting at offset iStart and ending at offset iEof-1. This function
-** leaves the iterator pointing to the first key in the PMA (or EOF if the
-** PMA is empty).
-*/
-static int vdbeSorterIterInit(
- sqlite3 *db, /* Database handle */
- const VdbeSorter *pSorter, /* Sorter object */
- i64 iStart, /* Start offset in pFile */
- VdbeSorterIter *pIter, /* Iterator to populate */
- i64 *pnByte /* IN/OUT: Increment this value by PMA size */
-){
- int rc = SQLITE_OK;
- int nBuf;
-
- nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
-
- assert( pSorter->iWriteOff>iStart );
- assert( pIter->aAlloc==0 );
- assert( pIter->aBuffer==0 );
- pIter->pFile = pSorter->pTemp1;
- pIter->iReadOff = iStart;
- pIter->nAlloc = 128;
- pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc);
- pIter->nBuffer = nBuf;
- pIter->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
-
- if( !pIter->aBuffer ){
- rc = SQLITE_NOMEM;
- }else{
- int iBuf;
-
- iBuf = iStart % nBuf;
- if( iBuf ){
- int nRead = nBuf - iBuf;
- if( (iStart + nRead) > pSorter->iWriteOff ){
- nRead = (int)(pSorter->iWriteOff - iStart);
- }
- rc = sqlite3OsRead(
- pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart
- );
- assert( rc!=SQLITE_IOERR_SHORT_READ );
- }
-
- if( rc==SQLITE_OK ){
- u64 nByte; /* Size of PMA in bytes */
- pIter->iEof = pSorter->iWriteOff;
- rc = vdbeSorterIterVarint(db, pIter, &nByte);
- pIter->iEof = pIter->iReadOff + nByte;
- *pnByte += nByte;
- }
- }
-
- if( rc==SQLITE_OK ){
- rc = vdbeSorterIterNext(db, pIter);
- }
- return rc;
-}
-
-
-/*
-** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2,
-** size nKey2 bytes). Argument pKeyInfo supplies the collation functions
-** used by the comparison. If an error occurs, return an SQLite error code.
-** Otherwise, return SQLITE_OK and set *pRes to a negative, zero or positive
-** value, depending on whether key1 is smaller, equal to or larger than key2.
-**
-** If the bOmitRowid argument is non-zero, assume both keys end in a rowid
-** field. For the purposes of the comparison, ignore it. Also, if bOmitRowid
-** is true and key1 contains even a single NULL value, it is considered to
-** be less than key2. Even if key2 also contains NULL values.
-**
-** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace
-** has been allocated and contains an unpacked record that is used as key2.
-*/
-static void vdbeSorterCompare(
- const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */
- int bOmitRowid, /* Ignore rowid field at end of keys */
- const void *pKey1, int nKey1, /* Left side of comparison */
- const void *pKey2, int nKey2, /* Right side of comparison */
- int *pRes /* OUT: Result of comparison */
-){
- KeyInfo *pKeyInfo = pCsr->pKeyInfo;
- VdbeSorter *pSorter = pCsr->pSorter;
- UnpackedRecord *r2 = pSorter->pUnpacked;
- int i;
-
- if( pKey2 ){
- sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2);
- }
-
- if( bOmitRowid ){
- r2->nField = pKeyInfo->nField;
- assert( r2->nField>0 );
- for(i=0; i<r2->nField; i++){
- if( r2->aMem[i].flags & MEM_Null ){
- *pRes = -1;
- return;
- }
- }
- r2->flags |= UNPACKED_PREFIX_MATCH;
- }
-
- *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
-}
-
-/*
-** This function is called to compare two iterator keys when merging
-** multiple b-tree segments. Parameter iOut is the index of the aTree[]
-** value to recalculate.
-*/
-static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){
- VdbeSorter *pSorter = pCsr->pSorter;
- int i1;
- int i2;
- int iRes;
- VdbeSorterIter *p1;
- VdbeSorterIter *p2;
-
- assert( iOut<pSorter->nTree && iOut>0 );
-
- if( iOut>=(pSorter->nTree/2) ){
- i1 = (iOut - pSorter->nTree/2) * 2;
- i2 = i1 + 1;
- }else{
- i1 = pSorter->aTree[iOut*2];
- i2 = pSorter->aTree[iOut*2+1];
- }
-
- p1 = &pSorter->aIter[i1];
- p2 = &pSorter->aIter[i2];
-
- if( p1->pFile==0 ){
- iRes = i2;
- }else if( p2->pFile==0 ){
- iRes = i1;
- }else{
- int res;
- assert( pCsr->pSorter->pUnpacked!=0 ); /* allocated in vdbeSorterMerge() */
- vdbeSorterCompare(
- pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res
- );
- if( res<=0 ){
- iRes = i1;
- }else{
- iRes = i2;
- }
- }
-
- pSorter->aTree[iOut] = iRes;
- return SQLITE_OK;
-}
-
-/*
-** Initialize the temporary index cursor just opened as a sorter cursor.
-*/
-SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){
- int pgsz; /* Page size of main database */
- int mxCache; /* Cache size */
- VdbeSorter *pSorter; /* The new sorter */
- char *d; /* Dummy */
-
- assert( pCsr->pKeyInfo && pCsr->pBt==0 );
- pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter));
- if( pSorter==0 ){
- return SQLITE_NOMEM;
- }
-
- pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pCsr->pKeyInfo, 0, 0, &d);
- if( pSorter->pUnpacked==0 ) return SQLITE_NOMEM;
- assert( pSorter->pUnpacked==(UnpackedRecord *)d );
-
- if( !sqlite3TempInMemory(db) ){
- pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
- pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
- mxCache = db->aDb[0].pSchema->cache_size;
- if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
- pSorter->mxPmaSize = mxCache * pgsz;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Free the list of sorted records starting at pRecord.
-*/
-static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
- SorterRecord *p;
- SorterRecord *pNext;
- for(p=pRecord; p; p=pNext){
- pNext = p->pNext;
- sqlite3DbFree(db, p);
- }
-}
-
-/*
-** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
-*/
-SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
- VdbeSorter *pSorter = pCsr->pSorter;
- if( pSorter ){
- if( pSorter->aIter ){
- int i;
- for(i=0; i<pSorter->nTree; i++){
- vdbeSorterIterZero(db, &pSorter->aIter[i]);
- }
- sqlite3DbFree(db, pSorter->aIter);
- }
- if( pSorter->pTemp1 ){
- sqlite3OsCloseFree(pSorter->pTemp1);
- }
- vdbeSorterRecordFree(db, pSorter->pRecord);
- sqlite3DbFree(db, pSorter->pUnpacked);
- sqlite3DbFree(db, pSorter);
- pCsr->pSorter = 0;
- }
-}
-
-/*
-** Allocate space for a file-handle and open a temporary file. If successful,
-** set *ppFile to point to the malloc'd file-handle and return SQLITE_OK.
-** Otherwise, set *ppFile to 0 and return an SQLite error code.
-*/
-static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){
- int dummy;
- return sqlite3OsOpenMalloc(db->pVfs, 0, ppFile,
- SQLITE_OPEN_TEMP_JOURNAL |
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &dummy
- );
-}
-
-/*
-** Merge the two sorted lists p1 and p2 into a single list.
-** Set *ppOut to the head of the new list.
-*/
-static void vdbeSorterMerge(
- const VdbeCursor *pCsr, /* For pKeyInfo */
- SorterRecord *p1, /* First list to merge */
- SorterRecord *p2, /* Second list to merge */
- SorterRecord **ppOut /* OUT: Head of merged list */
-){
- SorterRecord *pFinal = 0;
- SorterRecord **pp = &pFinal;
- void *pVal2 = p2 ? p2->pVal : 0;
-
- while( p1 && p2 ){
- int res;
- vdbeSorterCompare(pCsr, 0, p1->pVal, p1->nVal, pVal2, p2->nVal, &res);
- if( res<=0 ){
- *pp = p1;
- pp = &p1->pNext;
- p1 = p1->pNext;
- pVal2 = 0;
- }else{
- *pp = p2;
- pp = &p2->pNext;
- p2 = p2->pNext;
- if( p2==0 ) break;
- pVal2 = p2->pVal;
- }
- }
- *pp = p1 ? p1 : p2;
- *ppOut = pFinal;
-}
-
-/*
-** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK
-** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error
-** occurs.
-*/
-static int vdbeSorterSort(const VdbeCursor *pCsr){
- int i;
- SorterRecord **aSlot;
- SorterRecord *p;
- VdbeSorter *pSorter = pCsr->pSorter;
-
- aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
- if( !aSlot ){
- return SQLITE_NOMEM;
- }
-
- p = pSorter->pRecord;
- while( p ){
- SorterRecord *pNext = p->pNext;
- p->pNext = 0;
- for(i=0; aSlot[i]; i++){
- vdbeSorterMerge(pCsr, p, aSlot[i], &p);
- aSlot[i] = 0;
- }
- aSlot[i] = p;
- p = pNext;
- }
-
- p = 0;
- for(i=0; i<64; i++){
- vdbeSorterMerge(pCsr, p, aSlot[i], &p);
- }
- pSorter->pRecord = p;
-
- sqlite3_free(aSlot);
- return SQLITE_OK;
-}
-
-/*
-** Initialize a file-writer object.
-*/
-static void fileWriterInit(
- sqlite3 *db, /* Database (for malloc) */
- sqlite3_file *pFile, /* File to write to */
- FileWriter *p, /* Object to populate */
- i64 iStart /* Offset of pFile to begin writing at */
-){
- int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
-
- memset(p, 0, sizeof(FileWriter));
- p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
- if( !p->aBuffer ){
- p->eFWErr = SQLITE_NOMEM;
- }else{
- p->iBufEnd = p->iBufStart = (iStart % nBuf);
- p->iWriteOff = iStart - p->iBufStart;
- p->nBuffer = nBuf;
- p->pFile = pFile;
- }
-}
-
-/*
-** Write nData bytes of data to the file-write object. Return SQLITE_OK
-** if successful, or an SQLite error code if an error occurs.
-*/
-static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
- int nRem = nData;
- while( nRem>0 && p->eFWErr==0 ){
- int nCopy = nRem;
- if( nCopy>(p->nBuffer - p->iBufEnd) ){
- nCopy = p->nBuffer - p->iBufEnd;
- }
-
- memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy);
- p->iBufEnd += nCopy;
- if( p->iBufEnd==p->nBuffer ){
- p->eFWErr = sqlite3OsWrite(p->pFile,
- &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
- p->iWriteOff + p->iBufStart
- );
- p->iBufStart = p->iBufEnd = 0;
- p->iWriteOff += p->nBuffer;
- }
- assert( p->iBufEnd<p->nBuffer );
-
- nRem -= nCopy;
- }
-}
-
-/*
-** Flush any buffered data to disk and clean up the file-writer object.
-** The results of using the file-writer after this call are undefined.
-** Return SQLITE_OK if flushing the buffered data succeeds or is not
-** required. Otherwise, return an SQLite error code.
-**
-** Before returning, set *piEof to the offset immediately following the
-** last byte written to the file.
-*/
-static int fileWriterFinish(sqlite3 *db, FileWriter *p, i64 *piEof){
- int rc;
- if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){
- p->eFWErr = sqlite3OsWrite(p->pFile,
- &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
- p->iWriteOff + p->iBufStart
- );
- }
- *piEof = (p->iWriteOff + p->iBufEnd);
- sqlite3DbFree(db, p->aBuffer);
- rc = p->eFWErr;
- memset(p, 0, sizeof(FileWriter));
- return rc;
-}
-
-/*
-** Write value iVal encoded as a varint to the file-write object. Return
-** SQLITE_OK if successful, or an SQLite error code if an error occurs.
-*/
-static void fileWriterWriteVarint(FileWriter *p, u64 iVal){
- int nByte;
- u8 aByte[10];
- nByte = sqlite3PutVarint(aByte, iVal);
- fileWriterWrite(p, aByte, nByte);
-}
-
-/*
-** Write the current contents of the in-memory linked-list to a PMA. Return
-** SQLITE_OK if successful, or an SQLite error code otherwise.
-**
-** The format of a PMA is:
-**
-** * A varint. This varint contains the total number of bytes of content
-** in the PMA (not including the varint itself).
-**
-** * One or more records packed end-to-end in order of ascending keys.
-** Each record consists of a varint followed by a blob of data (the
-** key). The varint is the number of bytes in the blob of data.
-*/
-static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){
- int rc = SQLITE_OK; /* Return code */
- VdbeSorter *pSorter = pCsr->pSorter;
- FileWriter writer;
-
- memset(&writer, 0, sizeof(FileWriter));
-
- if( pSorter->nInMemory==0 ){
- assert( pSorter->pRecord==0 );
- return rc;
- }
-
- rc = vdbeSorterSort(pCsr);
-
- /* If the first temporary PMA file has not been opened, open it now. */
- if( rc==SQLITE_OK && pSorter->pTemp1==0 ){
- rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1);
- assert( rc!=SQLITE_OK || pSorter->pTemp1 );
- assert( pSorter->iWriteOff==0 );
- assert( pSorter->nPMA==0 );
- }
-
- if( rc==SQLITE_OK ){
- SorterRecord *p;
- SorterRecord *pNext = 0;
-
- fileWriterInit(db, pSorter->pTemp1, &writer, pSorter->iWriteOff);
- pSorter->nPMA++;
- fileWriterWriteVarint(&writer, pSorter->nInMemory);
- for(p=pSorter->pRecord; p; p=pNext){
- pNext = p->pNext;
- fileWriterWriteVarint(&writer, p->nVal);
- fileWriterWrite(&writer, p->pVal, p->nVal);
- sqlite3DbFree(db, p);
- }
- pSorter->pRecord = p;
- rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff);
- }
-
- return rc;
-}
-
-/*
-** Add a record to the sorter.
-*/
-SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
- sqlite3 *db, /* Database handle */
- const VdbeCursor *pCsr, /* Sorter cursor */
- Mem *pVal /* Memory cell containing record */
-){
- VdbeSorter *pSorter = pCsr->pSorter;
- int rc = SQLITE_OK; /* Return Code */
- SorterRecord *pNew; /* New list element */
-
- assert( pSorter );
- pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n;
-
- pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord));
- if( pNew==0 ){
- rc = SQLITE_NOMEM;
- }else{
- pNew->pVal = (void *)&pNew[1];
- memcpy(pNew->pVal, pVal->z, pVal->n);
- pNew->nVal = pVal->n;
- pNew->pNext = pSorter->pRecord;
- pSorter->pRecord = pNew;
- }
-
- /* See if the contents of the sorter should now be written out. They
- ** are written out when either of the following are true:
- **
- ** * The total memory allocated for the in-memory list is greater
- ** than (page-size * cache-size), or
- **
- ** * The total memory allocated for the in-memory list is greater
- ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true.
- */
- if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && (
- (pSorter->nInMemory>pSorter->mxPmaSize)
- || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull())
- )){
-#ifdef SQLITE_DEBUG
- i64 nExpect = pSorter->iWriteOff
- + sqlite3VarintLen(pSorter->nInMemory)
- + pSorter->nInMemory;
-#endif
- rc = vdbeSorterListToPMA(db, pCsr);
- pSorter->nInMemory = 0;
- assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) );
- }
-
- return rc;
-}
-
-/*
-** Helper function for sqlite3VdbeSorterRewind().
-*/
-static int vdbeSorterInitMerge(
- sqlite3 *db, /* Database handle */
- const VdbeCursor *pCsr, /* Cursor handle for this sorter */
- i64 *pnByte /* Sum of bytes in all opened PMAs */
-){
- VdbeSorter *pSorter = pCsr->pSorter;
- int rc = SQLITE_OK; /* Return code */
- int i; /* Used to iterator through aIter[] */
- i64 nByte = 0; /* Total bytes in all opened PMAs */
-
- /* Initialize the iterators. */
- for(i=0; i<SORTER_MAX_MERGE_COUNT; i++){
- VdbeSorterIter *pIter = &pSorter->aIter[i];
- rc = vdbeSorterIterInit(db, pSorter, pSorter->iReadOff, pIter, &nByte);
- pSorter->iReadOff = pIter->iEof;
- assert( rc!=SQLITE_OK || pSorter->iReadOff<=pSorter->iWriteOff );
- if( rc!=SQLITE_OK || pSorter->iReadOff>=pSorter->iWriteOff ) break;
- }
-
- /* Initialize the aTree[] array. */
- for(i=pSorter->nTree-1; rc==SQLITE_OK && i>0; i--){
- rc = vdbeSorterDoCompare(pCsr, i);
- }
-
- *pnByte = nByte;
- return rc;
-}
-
-/*
-** Once the sorter has been populated, this function is called to prepare
-** for iterating through its contents in sorted order.
-*/
-SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
- VdbeSorter *pSorter = pCsr->pSorter;
- int rc; /* Return code */
- sqlite3_file *pTemp2 = 0; /* Second temp file to use */
- i64 iWrite2 = 0; /* Write offset for pTemp2 */
- int nIter; /* Number of iterators used */
- int nByte; /* Bytes of space required for aIter/aTree */
- int N = 2; /* Power of 2 >= nIter */
-
- assert( pSorter );
-
- /* If no data has been written to disk, then do not do so now. Instead,
- ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly
- ** from the in-memory list. */
- if( pSorter->nPMA==0 ){
- *pbEof = !pSorter->pRecord;
- assert( pSorter->aTree==0 );
- return vdbeSorterSort(pCsr);
- }
-
- /* Write the current in-memory list to a PMA. */
- rc = vdbeSorterListToPMA(db, pCsr);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Allocate space for aIter[] and aTree[]. */
- nIter = pSorter->nPMA;
- if( nIter>SORTER_MAX_MERGE_COUNT ) nIter = SORTER_MAX_MERGE_COUNT;
- assert( nIter>0 );
- while( N<nIter ) N += N;
- nByte = N * (sizeof(int) + sizeof(VdbeSorterIter));
- pSorter->aIter = (VdbeSorterIter *)sqlite3DbMallocZero(db, nByte);
- if( !pSorter->aIter ) return SQLITE_NOMEM;
- pSorter->aTree = (int *)&pSorter->aIter[N];
- pSorter->nTree = N;
-
- do {
- int iNew; /* Index of new, merged, PMA */
-
- for(iNew=0;
- rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA;
- iNew++
- ){
- int rc2; /* Return code from fileWriterFinish() */
- FileWriter writer; /* Object used to write to disk */
- i64 nWrite; /* Number of bytes in new PMA */
-
- memset(&writer, 0, sizeof(FileWriter));
-
- /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1,
- ** initialize an iterator for each of them and break out of the loop.
- ** These iterators will be incrementally merged as the VDBE layer calls
- ** sqlite3VdbeSorterNext().
- **
- ** Otherwise, if pTemp1 contains more than SORTER_MAX_MERGE_COUNT PMAs,
- ** initialize interators for SORTER_MAX_MERGE_COUNT of them. These PMAs
- ** are merged into a single PMA that is written to file pTemp2.
- */
- rc = vdbeSorterInitMerge(db, pCsr, &nWrite);
- assert( rc!=SQLITE_OK || pSorter->aIter[ pSorter->aTree[1] ].pFile );
- if( rc!=SQLITE_OK || pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){
- break;
- }
-
- /* Open the second temp file, if it is not already open. */
- if( pTemp2==0 ){
- assert( iWrite2==0 );
- rc = vdbeSorterOpenTempFile(db, &pTemp2);
- }
-
- if( rc==SQLITE_OK ){
- int bEof = 0;
- fileWriterInit(db, pTemp2, &writer, iWrite2);
- fileWriterWriteVarint(&writer, nWrite);
- while( rc==SQLITE_OK && bEof==0 ){
- VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ];
- assert( pIter->pFile );
-
- fileWriterWriteVarint(&writer, pIter->nKey);
- fileWriterWrite(&writer, pIter->aKey, pIter->nKey);
- rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
- }
- rc2 = fileWriterFinish(db, &writer, &iWrite2);
- if( rc==SQLITE_OK ) rc = rc2;
- }
- }
-
- if( pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){
- break;
- }else{
- sqlite3_file *pTmp = pSorter->pTemp1;
- pSorter->nPMA = iNew;
- pSorter->pTemp1 = pTemp2;
- pTemp2 = pTmp;
- pSorter->iWriteOff = iWrite2;
- pSorter->iReadOff = 0;
- iWrite2 = 0;
- }
- }while( rc==SQLITE_OK );
-
- if( pTemp2 ){
- sqlite3OsCloseFree(pTemp2);
- }
- *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
- return rc;
-}
-
-/*
-** Advance to the next element in the sorter.
-*/
-SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
- VdbeSorter *pSorter = pCsr->pSorter;
- int rc; /* Return code */
-
- if( pSorter->aTree ){
- int iPrev = pSorter->aTree[1];/* Index of iterator to advance */
- int i; /* Index of aTree[] to recalculate */
-
- rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]);
- for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){
- rc = vdbeSorterDoCompare(pCsr, i);
- }
-
- *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
- }else{
- SorterRecord *pFree = pSorter->pRecord;
- pSorter->pRecord = pFree->pNext;
- pFree->pNext = 0;
- vdbeSorterRecordFree(db, pFree);
- *pbEof = !pSorter->pRecord;
- rc = SQLITE_OK;
- }
- return rc;
-}
-
-/*
-** Return a pointer to a buffer owned by the sorter that contains the
-** current key.
-*/
-static void *vdbeSorterRowkey(
- const VdbeSorter *pSorter, /* Sorter object */
- int *pnKey /* OUT: Size of current key in bytes */
-){
- void *pKey;
- if( pSorter->aTree ){
- VdbeSorterIter *pIter;
- pIter = &pSorter->aIter[ pSorter->aTree[1] ];
- *pnKey = pIter->nKey;
- pKey = pIter->aKey;
- }else{
- *pnKey = pSorter->pRecord->nVal;
- pKey = pSorter->pRecord->pVal;
- }
- return pKey;
-}
-
-/*
-** Copy the current sorter key into the memory cell pOut.
-*/
-SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
- VdbeSorter *pSorter = pCsr->pSorter;
- void *pKey; int nKey; /* Sorter key to copy into pOut */
-
- pKey = vdbeSorterRowkey(pSorter, &nKey);
- if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){
- return SQLITE_NOMEM;
- }
- pOut->n = nKey;
- MemSetTypeFlag(pOut, MEM_Blob);
- memcpy(pOut->z, pKey, nKey);
-
- return SQLITE_OK;
-}
-
-/*
-** Compare the key in memory cell pVal with the key that the sorter cursor
-** passed as the first argument currently points to. For the purposes of
-** the comparison, ignore the rowid field at the end of each record.
-**
-** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM).
-** Otherwise, set *pRes to a negative, zero or positive value if the
-** key in pVal is smaller than, equal to or larger than the current sorter
-** key.
-*/
-SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
- const VdbeCursor *pCsr, /* Sorter cursor */
- Mem *pVal, /* Value to compare to current sorter key */
- int *pRes /* OUT: Result of comparison */
-){
- VdbeSorter *pSorter = pCsr->pSorter;
- void *pKey; int nKey; /* Sorter key to compare pVal with */
-
- pKey = vdbeSorterRowkey(pSorter, &nKey);
- vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes);
- return SQLITE_OK;
-}
-
-#endif /* #ifndef SQLITE_OMIT_MERGE_SORT */
-
-/************** End of vdbesort.c ********************************************/
-/************** Begin file journal.c *****************************************/
-/*
-** 2007 August 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file implements a special kind of sqlite3_file object used
-** by SQLite to create journal files if the atomic-write optimization
-** is enabled.
-**
-** The distinctive characteristic of this sqlite3_file is that the
-** actual on disk file is created lazily. When the file is created,
-** the caller specifies a buffer size for an in-memory buffer to
-** be used to service read() and write() requests. The actual file
-** on disk is not created or populated until either:
-**
-** 1) The in-memory representation grows too large for the allocated
-** buffer, or
-** 2) The sqlite3JournalCreate() function is called.
-*/
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-
-
-/*
-** A JournalFile object is a subclass of sqlite3_file used by
-** as an open file handle for journal files.
-*/
-struct JournalFile {
- sqlite3_io_methods *pMethod; /* I/O methods on journal files */
- int nBuf; /* Size of zBuf[] in bytes */
- char *zBuf; /* Space to buffer journal writes */
- int iSize; /* Amount of zBuf[] currently used */
- int flags; /* xOpen flags */
- sqlite3_vfs *pVfs; /* The "real" underlying VFS */
- sqlite3_file *pReal; /* The "real" underlying file descriptor */
- const char *zJournal; /* Name of the journal file */
-};
-typedef struct JournalFile JournalFile;
-
-/*
-** If it does not already exists, create and populate the on-disk file
-** for JournalFile p.
-*/
-static int createFile(JournalFile *p){
- int rc = SQLITE_OK;
- if( !p->pReal ){
- sqlite3_file *pReal = (sqlite3_file *)&p[1];
- rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
- if( rc==SQLITE_OK ){
- p->pReal = pReal;
- if( p->iSize>0 ){
- assert(p->iSize<=p->nBuf);
- rc = sqlite3OsWrite(p->pReal, p->zBuf, p->iSize, 0);
- }
- }
- }
- return rc;
-}
-
-/*
-** Close the file.
-*/
-static int jrnlClose(sqlite3_file *pJfd){
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- sqlite3OsClose(p->pReal);
- }
- sqlite3_free(p->zBuf);
- return SQLITE_OK;
-}
-
-/*
-** Read data from the file.
-*/
-static int jrnlRead(
- sqlite3_file *pJfd, /* The journal file from which to read */
- void *zBuf, /* Put the results here */
- int iAmt, /* Number of bytes to read */
- sqlite_int64 iOfst /* Begin reading at this offset */
-){
- int rc = SQLITE_OK;
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- rc = sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
- }else if( (iAmt+iOfst)>p->iSize ){
- rc = SQLITE_IOERR_SHORT_READ;
- }else{
- memcpy(zBuf, &p->zBuf[iOfst], iAmt);
- }
- return rc;
-}
-
-/*
-** Write data to the file.
-*/
-static int jrnlWrite(
- sqlite3_file *pJfd, /* The journal file into which to write */
- const void *zBuf, /* Take data to be written from here */
- int iAmt, /* Number of bytes to write */
- sqlite_int64 iOfst /* Begin writing at this offset into the file */
-){
- int rc = SQLITE_OK;
- JournalFile *p = (JournalFile *)pJfd;
- if( !p->pReal && (iOfst+iAmt)>p->nBuf ){
- rc = createFile(p);
- }
- if( rc==SQLITE_OK ){
- if( p->pReal ){
- rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
- }else{
- memcpy(&p->zBuf[iOfst], zBuf, iAmt);
- if( p->iSize<(iOfst+iAmt) ){
- p->iSize = (iOfst+iAmt);
- }
- }
- }
- return rc;
-}
-
-/*
-** Truncate the file.
-*/
-static int jrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
- int rc = SQLITE_OK;
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- rc = sqlite3OsTruncate(p->pReal, size);
- }else if( size<p->iSize ){
- p->iSize = size;
- }
- return rc;
-}
-
-/*
-** Sync the file.
-*/
-static int jrnlSync(sqlite3_file *pJfd, int flags){
- int rc;
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- rc = sqlite3OsSync(p->pReal, flags);
- }else{
- rc = SQLITE_OK;
- }
- return rc;
-}
-
-/*
-** Query the size of the file in bytes.
-*/
-static int jrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
- int rc = SQLITE_OK;
- JournalFile *p = (JournalFile *)pJfd;
- if( p->pReal ){
- rc = sqlite3OsFileSize(p->pReal, pSize);
- }else{
- *pSize = (sqlite_int64) p->iSize;
- }
- return rc;
-}
-
-/*
-** Table of methods for JournalFile sqlite3_file object.
-*/
-static struct sqlite3_io_methods JournalFileMethods = {
- 1, /* iVersion */
- jrnlClose, /* xClose */
- jrnlRead, /* xRead */
- jrnlWrite, /* xWrite */
- jrnlTruncate, /* xTruncate */
- jrnlSync, /* xSync */
- jrnlFileSize, /* xFileSize */
- 0, /* xLock */
- 0, /* xUnlock */
- 0, /* xCheckReservedLock */
- 0, /* xFileControl */
- 0, /* xSectorSize */
- 0, /* xDeviceCharacteristics */
- 0, /* xShmMap */
- 0, /* xShmLock */
- 0, /* xShmBarrier */
- 0 /* xShmUnmap */
-};
-
-/*
-** Open a journal file.
-*/
-SQLITE_PRIVATE int sqlite3JournalOpen(
- sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */
- const char *zName, /* Name of the journal file */
- sqlite3_file *pJfd, /* Preallocated, blank file handle */
- int flags, /* Opening flags */
- int nBuf /* Bytes buffered before opening the file */
-){
- JournalFile *p = (JournalFile *)pJfd;
- memset(p, 0, sqlite3JournalSize(pVfs));
- if( nBuf>0 ){
- p->zBuf = sqlite3MallocZero(nBuf);
- if( !p->zBuf ){
- return SQLITE_NOMEM;
- }
- }else{
- return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
- }
- p->pMethod = &JournalFileMethods;
- p->nBuf = nBuf;
- p->flags = flags;
- p->zJournal = zName;
- p->pVfs = pVfs;
- return SQLITE_OK;
-}
-
-/*
-** If the argument p points to a JournalFile structure, and the underlying
-** file has not yet been created, create it now.
-*/
-SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
- if( p->pMethods!=&JournalFileMethods ){
- return SQLITE_OK;
- }
- return createFile((JournalFile *)p);
-}
-
-/*
-** The file-handle passed as the only argument is guaranteed to be an open
-** file. It may or may not be of class JournalFile. If the file is a
-** JournalFile, and the underlying file on disk has not yet been opened,
-** return 0. Otherwise, return 1.
-*/
-SQLITE_PRIVATE int sqlite3JournalExists(sqlite3_file *p){
- return (p->pMethods!=&JournalFileMethods || ((JournalFile *)p)->pReal!=0);
-}
-
-/*
-** Return the number of bytes required to store a JournalFile that uses vfs
-** pVfs to create the underlying on-disk files.
-*/
-SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
- return (pVfs->szOsFile+sizeof(JournalFile));
-}
-#endif
-
-/************** End of journal.c *********************************************/
-/************** Begin file memjournal.c **************************************/
-/*
-** 2008 October 7
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains code use to implement an in-memory rollback journal.
-** The in-memory rollback journal is used to journal transactions for
-** ":memory:" databases and when the journal_mode=MEMORY pragma is used.
-*/
-
-/* Forward references to internal structures */
-typedef struct MemJournal MemJournal;
-typedef struct FilePoint FilePoint;
-typedef struct FileChunk FileChunk;
-
-/* Space to hold the rollback journal is allocated in increments of
-** this many bytes.
-**
-** The size chosen is a little less than a power of two. That way,
-** the FileChunk object will have a size that almost exactly fills
-** a power-of-two allocation. This mimimizes wasted space in power-of-two
-** memory allocators.
-*/
-#define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*)))
-
-/* Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
-/*
-** The rollback journal is composed of a linked list of these structures.
-*/
-struct FileChunk {
- FileChunk *pNext; /* Next chunk in the journal */
- u8 zChunk[JOURNAL_CHUNKSIZE]; /* Content of this chunk */
-};
-
-/*
-** An instance of this object serves as a cursor into the rollback journal.
-** The cursor can be either for reading or writing.
-*/
-struct FilePoint {
- sqlite3_int64 iOffset; /* Offset from the beginning of the file */
- FileChunk *pChunk; /* Specific chunk into which cursor points */
-};
-
-/*
-** This subclass is a subclass of sqlite3_file. Each open memory-journal
-** is an instance of this class.
-*/
-struct MemJournal {
- sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */
- FileChunk *pFirst; /* Head of in-memory chunk-list */
- FilePoint endpoint; /* Pointer to the end of the file */
- FilePoint readpoint; /* Pointer to the end of the last xRead() */
-};
-
-/*
-** Read data from the in-memory journal file. This is the implementation
-** of the sqlite3_vfs.xRead method.
-*/
-static int memjrnlRead(
- sqlite3_file *pJfd, /* The journal file from which to read */
- void *zBuf, /* Put the results here */
- int iAmt, /* Number of bytes to read */
- sqlite_int64 iOfst /* Begin reading at this offset */
-){
- MemJournal *p = (MemJournal *)pJfd;
- u8 *zOut = zBuf;
- int nRead = iAmt;
- int iChunkOffset;
- FileChunk *pChunk;
-
- /* SQLite never tries to read past the end of a rollback journal file */
- assert( iOfst+iAmt<=p->endpoint.iOffset );
-
- if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
- sqlite3_int64 iOff = 0;
- for(pChunk=p->pFirst;
- ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst;
- pChunk=pChunk->pNext
- ){
- iOff += JOURNAL_CHUNKSIZE;
- }
- }else{
- pChunk = p->readpoint.pChunk;
- }
-
- iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE);
- do {
- int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset;
- int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset));
- memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy);
- zOut += nCopy;
- nRead -= iSpace;
- iChunkOffset = 0;
- } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
- p->readpoint.iOffset = iOfst+iAmt;
- p->readpoint.pChunk = pChunk;
-
- return SQLITE_OK;
-}
-
-/*
-** Write data to the file.
-*/
-static int memjrnlWrite(
- sqlite3_file *pJfd, /* The journal file into which to write */
- const void *zBuf, /* Take data to be written from here */
- int iAmt, /* Number of bytes to write */
- sqlite_int64 iOfst /* Begin writing at this offset into the file */
-){
- MemJournal *p = (MemJournal *)pJfd;
- int nWrite = iAmt;
- u8 *zWrite = (u8 *)zBuf;
-
- /* An in-memory journal file should only ever be appended to. Random
- ** access writes are not required by sqlite.
- */
- assert( iOfst==p->endpoint.iOffset );
- UNUSED_PARAMETER(iOfst);
-
- while( nWrite>0 ){
- FileChunk *pChunk = p->endpoint.pChunk;
- int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE);
- int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset);
-
- if( iChunkOffset==0 ){
- /* New chunk is required to extend the file. */
- FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk));
- if( !pNew ){
- return SQLITE_IOERR_NOMEM;
- }
- pNew->pNext = 0;
- if( pChunk ){
- assert( p->pFirst );
- pChunk->pNext = pNew;
- }else{
- assert( !p->pFirst );
- p->pFirst = pNew;
- }
- p->endpoint.pChunk = pNew;
- }
-
- memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace);
- zWrite += iSpace;
- nWrite -= iSpace;
- p->endpoint.iOffset += iSpace;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Truncate the file.
-*/
-static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
- MemJournal *p = (MemJournal *)pJfd;
- FileChunk *pChunk;
- assert(size==0);
- UNUSED_PARAMETER(size);
- pChunk = p->pFirst;
- while( pChunk ){
- FileChunk *pTmp = pChunk;
- pChunk = pChunk->pNext;
- sqlite3_free(pTmp);
- }
- sqlite3MemJournalOpen(pJfd);
- return SQLITE_OK;
-}
-
-/*
-** Close the file.
-*/
-static int memjrnlClose(sqlite3_file *pJfd){
- memjrnlTruncate(pJfd, 0);
- return SQLITE_OK;
-}
-
-
-/*
-** Sync the file.
-**
-** Syncing an in-memory journal is a no-op. And, in fact, this routine
-** is never called in a working implementation. This implementation
-** exists purely as a contingency, in case some malfunction in some other
-** part of SQLite causes Sync to be called by mistake.
-*/
-static int memjrnlSync(sqlite3_file *NotUsed, int NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return SQLITE_OK;
-}
-
-/*
-** Query the size of the file in bytes.
-*/
-static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
- MemJournal *p = (MemJournal *)pJfd;
- *pSize = (sqlite_int64) p->endpoint.iOffset;
- return SQLITE_OK;
-}
-
-/*
-** Table of methods for MemJournal sqlite3_file object.
-*/
-static const struct sqlite3_io_methods MemJournalMethods = {
- 1, /* iVersion */
- memjrnlClose, /* xClose */
- memjrnlRead, /* xRead */
- memjrnlWrite, /* xWrite */
- memjrnlTruncate, /* xTruncate */
- memjrnlSync, /* xSync */
- memjrnlFileSize, /* xFileSize */
- 0, /* xLock */
- 0, /* xUnlock */
- 0, /* xCheckReservedLock */
- 0, /* xFileControl */
- 0, /* xSectorSize */
- 0, /* xDeviceCharacteristics */
- 0, /* xShmMap */
- 0, /* xShmLock */
- 0, /* xShmBarrier */
- 0 /* xShmUnlock */
-};
-
-/*
-** Open a journal file.
-*/
-SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){
- MemJournal *p = (MemJournal *)pJfd;
- assert( EIGHT_BYTE_ALIGNMENT(p) );
- memset(p, 0, sqlite3MemJournalSize());
- p->pMethod = (sqlite3_io_methods*)&MemJournalMethods;
-}
-
-/*
-** Return true if the file-handle passed as an argument is
-** an in-memory journal
-*/
-SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *pJfd){
- return pJfd->pMethods==&MemJournalMethods;
-}
-
-/*
-** Return the number of bytes required to store a MemJournal file descriptor.
-*/
-SQLITE_PRIVATE int sqlite3MemJournalSize(void){
- return sizeof(MemJournal);
-}
-
-/************** End of memjournal.c ******************************************/
-/************** Begin file walker.c ******************************************/
-/*
-** 2008 August 16
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains routines used for walking the parser tree for
-** an SQL statement.
-*/
-/* #include <stdlib.h> */
-/* #include <string.h> */
-
-
-/*
-** Walk an expression tree. Invoke the callback once for each node
-** of the expression, while decending. (In other words, the callback
-** is invoked before visiting children.)
-**
-** The return value from the callback should be one of the WRC_*
-** constants to specify how to proceed with the walk.
-**
-** WRC_Continue Continue descending down the tree.
-**
-** WRC_Prune Do not descend into child nodes. But allow
-** the walk to continue with sibling nodes.
-**
-** WRC_Abort Do no more callbacks. Unwind the stack and
-** return the top-level walk call.
-**
-** The return value from this routine is WRC_Abort to abandon the tree walk
-** and WRC_Continue to continue.
-*/
-SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
- int rc;
- if( pExpr==0 ) return WRC_Continue;
- testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
- testcase( ExprHasProperty(pExpr, EP_Reduced) );
- rc = pWalker->xExprCallback(pWalker, pExpr);
- if( rc==WRC_Continue
- && !ExprHasAnyProperty(pExpr,EP_TokenOnly) ){
- if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
- }else{
- if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
- }
- }
- return rc & WRC_Abort;
-}
-
-/*
-** Call sqlite3WalkExpr() for every expression in list p or until
-** an abort request is seen.
-*/
-SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){
- int i;
- struct ExprList_item *pItem;
- if( p ){
- for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){
- if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort;
- }
- }
- return WRC_Continue;
-}
-
-/*
-** Walk all expressions associated with SELECT statement p. Do
-** not invoke the SELECT callback on p, but do (of course) invoke
-** any expr callbacks and SELECT callbacks that come from subqueries.
-** Return WRC_Abort or WRC_Continue.
-*/
-SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
- if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort;
- if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
- if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort;
- return WRC_Continue;
-}
-
-/*
-** Walk the parse trees associated with all subqueries in the
-** FROM clause of SELECT statement p. Do not invoke the select
-** callback on p, but do invoke it on each FROM clause subquery
-** and on any subqueries further down in the tree. Return
-** WRC_Abort or WRC_Continue;
-*/
-SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
- SrcList *pSrc;
- int i;
- struct SrcList_item *pItem;
-
- pSrc = p->pSrc;
- if( ALWAYS(pSrc) ){
- for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){
- return WRC_Abort;
- }
- }
- }
- return WRC_Continue;
-}
-
-/*
-** Call sqlite3WalkExpr() for every expression in Select statement p.
-** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and
-** on the compound select chain, p->pPrior.
-**
-** Return WRC_Continue under normal conditions. Return WRC_Abort if
-** there is an abort request.
-**
-** If the Walker does not have an xSelectCallback() then this routine
-** is a no-op returning WRC_Continue.
-*/
-SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
- int rc;
- if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue;
- rc = WRC_Continue;
- pWalker->walkerDepth++;
- while( p ){
- rc = pWalker->xSelectCallback(pWalker, p);
- if( rc ) break;
- if( sqlite3WalkSelectExpr(pWalker, p)
- || sqlite3WalkSelectFrom(pWalker, p)
- ){
- pWalker->walkerDepth--;
- return WRC_Abort;
- }
- p = p->pPrior;
- }
- pWalker->walkerDepth--;
- return rc & WRC_Abort;
-}
-
-/************** End of walker.c **********************************************/
-/************** Begin file resolve.c *****************************************/
-/*
-** 2008 August 18
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains routines used for walking the parser tree and
-** resolve all identifiers by associating them with a particular
-** table and column.
-*/
-/* #include <stdlib.h> */
-/* #include <string.h> */
-
-/*
-** Walk the expression tree pExpr and increase the aggregate function
-** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node.
-** This needs to occur when copying a TK_AGG_FUNCTION node from an
-** outer query into an inner subquery.
-**
-** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..)
-** is a helper function - a callback for the tree walker.
-*/
-static int incrAggDepth(Walker *pWalker, Expr *pExpr){
- if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i;
- return WRC_Continue;
-}
-static void incrAggFunctionDepth(Expr *pExpr, int N){
- if( N>0 ){
- Walker w;
- memset(&w, 0, sizeof(w));
- w.xExprCallback = incrAggDepth;
- w.u.i = N;
- sqlite3WalkExpr(&w, pExpr);
- }
-}
-
-/*
-** Turn the pExpr expression into an alias for the iCol-th column of the
-** result set in pEList.
-**
-** If the result set column is a simple column reference, then this routine
-** makes an exact copy. But for any other kind of expression, this
-** routine make a copy of the result set column as the argument to the
-** TK_AS operator. The TK_AS operator causes the expression to be
-** evaluated just once and then reused for each alias.
-**
-** The reason for suppressing the TK_AS term when the expression is a simple
-** column reference is so that the column reference will be recognized as
-** usable by indices within the WHERE clause processing logic.
-**
-** Hack: The TK_AS operator is inhibited if zType[0]=='G'. This means
-** that in a GROUP BY clause, the expression is evaluated twice. Hence:
-**
-** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
-**
-** Is equivalent to:
-**
-** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
-**
-** The result of random()%5 in the GROUP BY clause is probably different
-** from the result in the result-set. We might fix this someday. Or
-** then again, we might not...
-**
-** If the reference is followed by a COLLATE operator, then make sure
-** the COLLATE operator is preserved. For example:
-**
-** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
-**
-** Should be transformed into:
-**
-** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
-**
-** The nSubquery parameter specifies how many levels of subquery the
-** alias is removed from the original expression. The usually value is
-** zero but it might be more if the alias is contained within a subquery
-** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION
-** structures must be increased by the nSubquery amount.
-*/
-static void resolveAlias(
- Parse *pParse, /* Parsing context */
- ExprList *pEList, /* A result set */
- int iCol, /* A column in the result set. 0..pEList->nExpr-1 */
- Expr *pExpr, /* Transform this into an alias to the result set */
- const char *zType, /* "GROUP" or "ORDER" or "" */
- int nSubquery /* Number of subqueries that the label is moving */
-){
- Expr *pOrig; /* The iCol-th column of the result set */
- Expr *pDup; /* Copy of pOrig */
- sqlite3 *db; /* The database connection */
-
- assert( iCol>=0 && iCol<pEList->nExpr );
- pOrig = pEList->a[iCol].pExpr;
- assert( pOrig!=0 );
- assert( pOrig->flags & EP_Resolved );
- db = pParse->db;
- pDup = sqlite3ExprDup(db, pOrig, 0);
- if( pDup==0 ) return;
- if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
- incrAggFunctionDepth(pDup, nSubquery);
- pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
- if( pDup==0 ) return;
- if( pEList->a[iCol].iAlias==0 ){
- pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
- }
- pDup->iTable = pEList->a[iCol].iAlias;
- }
- if( pExpr->op==TK_COLLATE ){
- pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
- }
-
- /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
- ** prevents ExprDelete() from deleting the Expr structure itself,
- ** allowing it to be repopulated by the memcpy() on the following line.
- ** The pExpr->u.zToken might point into memory that will be freed by the
- ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
- ** make a copy of the token before doing the sqlite3DbFree().
- */
- ExprSetProperty(pExpr, EP_Static);
- sqlite3ExprDelete(db, pExpr);
- memcpy(pExpr, pDup, sizeof(*pExpr));
- if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
- assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
- pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
- pExpr->flags2 |= EP2_MallocedToken;
- }
- sqlite3DbFree(db, pDup);
-}
-
-
-/*
-** Return TRUE if the name zCol occurs anywhere in the USING clause.
-**
-** Return FALSE if the USING clause is NULL or if it does not contain
-** zCol.
-*/
-static int nameInUsingClause(IdList *pUsing, const char *zCol){
- if( pUsing ){
- int k;
- for(k=0; k<pUsing->nId; k++){
- if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1;
- }
- }
- return 0;
-}
-
-
-/*
-** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
-** that name in the set of source tables in pSrcList and make the pExpr
-** expression node refer back to that source column. The following changes
-** are made to pExpr:
-**
-** pExpr->iDb Set the index in db->aDb[] of the database X
-** (even if X is implied).
-** pExpr->iTable Set to the cursor number for the table obtained
-** from pSrcList.
-** pExpr->pTab Points to the Table structure of X.Y (even if
-** X and/or Y are implied.)
-** pExpr->iColumn Set to the column number within the table.
-** pExpr->op Set to TK_COLUMN.
-** pExpr->pLeft Any expression this points to is deleted
-** pExpr->pRight Any expression this points to is deleted.
-**
-** The zDb variable is the name of the database (the "X"). This value may be
-** NULL meaning that name is of the form Y.Z or Z. Any available database
-** can be used. The zTable variable is the name of the table (the "Y"). This
-** value can be NULL if zDb is also NULL. If zTable is NULL it
-** means that the form of the name is Z and that columns from any table
-** can be used.
-**
-** If the name cannot be resolved unambiguously, leave an error message
-** in pParse and return WRC_Abort. Return WRC_Prune on success.
-*/
-static int lookupName(
- Parse *pParse, /* The parsing context */
- const char *zDb, /* Name of the database containing table, or NULL */
- const char *zTab, /* Name of table containing column, or NULL */
- const char *zCol, /* Name of the column. */
- NameContext *pNC, /* The name context used to resolve the name */
- Expr *pExpr /* Make this EXPR node point to the selected column */
-){
- int i, j; /* Loop counters */
- int cnt = 0; /* Number of matching column names */
- int cntTab = 0; /* Number of matching table names */
- int nSubquery = 0; /* How many levels of subquery */
- sqlite3 *db = pParse->db; /* The database connection */
- struct SrcList_item *pItem; /* Use for looping over pSrcList items */
- struct SrcList_item *pMatch = 0; /* The matching pSrcList item */
- NameContext *pTopNC = pNC; /* First namecontext in the list */
- Schema *pSchema = 0; /* Schema of the expression */
- int isTrigger = 0;
-
- assert( pNC ); /* the name context cannot be NULL. */
- assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
-
- /* Initialize the node to no-match */
- pExpr->iTable = -1;
- pExpr->pTab = 0;
- ExprSetIrreducible(pExpr);
-
- /* Start at the inner-most context and move outward until a match is found */
- while( pNC && cnt==0 ){
- ExprList *pEList;
- SrcList *pSrcList = pNC->pSrcList;
-
- if( pSrcList ){
- for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
- Table *pTab;
- int iDb;
- Column *pCol;
-
- pTab = pItem->pTab;
- assert( pTab!=0 && pTab->zName!=0 );
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( pTab->nCol>0 );
- if( zTab ){
- if( pItem->zAlias ){
- char *zTabName = pItem->zAlias;
- if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue;
- }else{
- char *zTabName = pTab->zName;
- if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){
- continue;
- }
- if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){
- continue;
- }
- }
- }
- if( 0==(cntTab++) ){
- pExpr->iTable = pItem->iCursor;
- pExpr->pTab = pTab;
- pSchema = pTab->pSchema;
- pMatch = pItem;
- }
- for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
- if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
- /* If there has been exactly one prior match and this match
- ** is for the right-hand table of a NATURAL JOIN or is in a
- ** USING clause, then skip this match.
- */
- if( cnt==1 ){
- if( pItem->jointype & JT_NATURAL ) continue;
- if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
- }
- cnt++;
- pExpr->iTable = pItem->iCursor;
- pExpr->pTab = pTab;
- pMatch = pItem;
- pSchema = pTab->pSchema;
- /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
- pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
- break;
- }
- }
- }
- }
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* If we have not already resolved the name, then maybe
- ** it is a new.* or old.* trigger argument reference
- */
- if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){
- int op = pParse->eTriggerOp;
- Table *pTab = 0;
- assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
- if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
- pExpr->iTable = 1;
- pTab = pParse->pTriggerTab;
- }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
- pExpr->iTable = 0;
- pTab = pParse->pTriggerTab;
- }
-
- if( pTab ){
- int iCol;
- pSchema = pTab->pSchema;
- cntTab++;
- for(iCol=0; iCol<pTab->nCol; iCol++){
- Column *pCol = &pTab->aCol[iCol];
- if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
- if( iCol==pTab->iPKey ){
- iCol = -1;
- }
- break;
- }
- }
- if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) ){
- iCol = -1; /* IMP: R-44911-55124 */
- }
- if( iCol<pTab->nCol ){
- cnt++;
- if( iCol<0 ){
- pExpr->affinity = SQLITE_AFF_INTEGER;
- }else if( pExpr->iTable==0 ){
- testcase( iCol==31 );
- testcase( iCol==32 );
- pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
- }else{
- testcase( iCol==31 );
- testcase( iCol==32 );
- pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol));
- }
- pExpr->iColumn = (i16)iCol;
- pExpr->pTab = pTab;
- isTrigger = 1;
- }
- }
- }
-#endif /* !defined(SQLITE_OMIT_TRIGGER) */
-
- /*
- ** Perhaps the name is a reference to the ROWID
- */
- if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
- cnt = 1;
- pExpr->iColumn = -1; /* IMP: R-44911-55124 */
- pExpr->affinity = SQLITE_AFF_INTEGER;
- }
-
- /*
- ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
- ** might refer to an result-set alias. This happens, for example, when
- ** we are resolving names in the WHERE clause of the following command:
- **
- ** SELECT a+b AS x FROM table WHERE x<10;
- **
- ** In cases like this, replace pExpr with a copy of the expression that
- ** forms the result set entry ("a+b" in the example) and return immediately.
- ** Note that the expression in the result set should have already been
- ** resolved by the time the WHERE clause is resolved.
- */
- if( cnt==0 && (pEList = pNC->pEList)!=0 && zTab==0 ){
- for(j=0; j<pEList->nExpr; j++){
- char *zAs = pEList->a[j].zName;
- if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
- Expr *pOrig;
- assert( pExpr->pLeft==0 && pExpr->pRight==0 );
- assert( pExpr->x.pList==0 );
- assert( pExpr->x.pSelect==0 );
- pOrig = pEList->a[j].pExpr;
- if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
- sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
- return WRC_Abort;
- }
- resolveAlias(pParse, pEList, j, pExpr, "", nSubquery);
- cnt = 1;
- pMatch = 0;
- assert( zTab==0 && zDb==0 );
- goto lookupname_end;
- }
- }
- }
-
- /* Advance to the next name context. The loop will exit when either
- ** we have a match (cnt>0) or when we run out of name contexts.
- */
- if( cnt==0 ){
- pNC = pNC->pNext;
- nSubquery++;
- }
- }
-
- /*
- ** If X and Y are NULL (in other words if only the column name Z is
- ** supplied) and the value of Z is enclosed in double-quotes, then
- ** Z is a string literal if it doesn't match any column names. In that
- ** case, we need to return right away and not make any changes to
- ** pExpr.
- **
- ** Because no reference was made to outer contexts, the pNC->nRef
- ** fields are not changed in any context.
- */
- if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
- pExpr->op = TK_STRING;
- pExpr->pTab = 0;
- return WRC_Prune;
- }
-
- /*
- ** cnt==0 means there was not match. cnt>1 means there were two or
- ** more matches. Either way, we have an error.
- */
- if( cnt!=1 ){
- const char *zErr;
- zErr = cnt==0 ? "no such column" : "ambiguous column name";
- if( zDb ){
- sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol);
- }else if( zTab ){
- sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol);
- }else{
- sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol);
- }
- pParse->checkSchema = 1;
- pTopNC->nErr++;
- }
-
- /* If a column from a table in pSrcList is referenced, then record
- ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
- ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the
- ** column number is greater than the number of bits in the bitmask
- ** then set the high-order bit of the bitmask.
- */
- if( pExpr->iColumn>=0 && pMatch!=0 ){
- int n = pExpr->iColumn;
- testcase( n==BMS-1 );
- if( n>=BMS ){
- n = BMS-1;
- }
- assert( pMatch->iCursor==pExpr->iTable );
- pMatch->colUsed |= ((Bitmask)1)<<n;
- }
-
- /* Clean up and return
- */
- sqlite3ExprDelete(db, pExpr->pLeft);
- pExpr->pLeft = 0;
- sqlite3ExprDelete(db, pExpr->pRight);
- pExpr->pRight = 0;
- pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
-lookupname_end:
- if( cnt==1 ){
- assert( pNC!=0 );
- sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
- /* Increment the nRef value on all name contexts from TopNC up to
- ** the point where the name matched. */
- for(;;){
- assert( pTopNC!=0 );
- pTopNC->nRef++;
- if( pTopNC==pNC ) break;
- pTopNC = pTopNC->pNext;
- }
- return WRC_Prune;
- } else {
- return WRC_Abort;
- }
-}
-
-/*
-** Allocate and return a pointer to an expression to load the column iCol
-** from datasource iSrc in SrcList pSrc.
-*/
-SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
- Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
- if( p ){
- struct SrcList_item *pItem = &pSrc->a[iSrc];
- p->pTab = pItem->pTab;
- p->iTable = pItem->iCursor;
- if( p->pTab->iPKey==iCol ){
- p->iColumn = -1;
- }else{
- p->iColumn = (ynVar)iCol;
- testcase( iCol==BMS );
- testcase( iCol==BMS-1 );
- pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
- }
- ExprSetProperty(p, EP_Resolved);
- }
- return p;
-}
-
-/*
-** This routine is callback for sqlite3WalkExpr().
-**
-** Resolve symbolic names into TK_COLUMN operators for the current
-** node in the expression tree. Return 0 to continue the search down
-** the tree or 2 to abort the tree walk.
-**
-** This routine also does error checking and name resolution for
-** function names. The operator for aggregate functions is changed
-** to TK_AGG_FUNCTION.
-*/
-static int resolveExprStep(Walker *pWalker, Expr *pExpr){
- NameContext *pNC;
- Parse *pParse;
-
- pNC = pWalker->u.pNC;
- assert( pNC!=0 );
- pParse = pNC->pParse;
- assert( pParse==pWalker->pParse );
-
- if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune;
- ExprSetProperty(pExpr, EP_Resolved);
-#ifndef NDEBUG
- if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
- SrcList *pSrcList = pNC->pSrcList;
- int i;
- for(i=0; i<pNC->pSrcList->nSrc; i++){
- assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab);
- }
- }
-#endif
- switch( pExpr->op ){
-
-#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
- /* The special operator TK_ROW means use the rowid for the first
- ** column in the FROM clause. This is used by the LIMIT and ORDER BY
- ** clause processing on UPDATE and DELETE statements.
- */
- case TK_ROW: {
- SrcList *pSrcList = pNC->pSrcList;
- struct SrcList_item *pItem;
- assert( pSrcList && pSrcList->nSrc==1 );
- pItem = pSrcList->a;
- pExpr->op = TK_COLUMN;
- pExpr->pTab = pItem->pTab;
- pExpr->iTable = pItem->iCursor;
- pExpr->iColumn = -1;
- pExpr->affinity = SQLITE_AFF_INTEGER;
- break;
- }
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
-
- /* A lone identifier is the name of a column.
- */
- case TK_ID: {
- return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
- }
-
- /* A table name and column name: ID.ID
- ** Or a database, table and column: ID.ID.ID
- */
- case TK_DOT: {
- const char *zColumn;
- const char *zTable;
- const char *zDb;
- Expr *pRight;
-
- /* if( pSrcList==0 ) break; */
- pRight = pExpr->pRight;
- if( pRight->op==TK_ID ){
- zDb = 0;
- zTable = pExpr->pLeft->u.zToken;
- zColumn = pRight->u.zToken;
- }else{
- assert( pRight->op==TK_DOT );
- zDb = pExpr->pLeft->u.zToken;
- zTable = pRight->pLeft->u.zToken;
- zColumn = pRight->pRight->u.zToken;
- }
- return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
- }
-
- /* Resolve function names
- */
- case TK_CONST_FUNC:
- case TK_FUNCTION: {
- ExprList *pList = pExpr->x.pList; /* The argument list */
- int n = pList ? pList->nExpr : 0; /* Number of arguments */
- int no_such_func = 0; /* True if no such function exists */
- int wrong_num_args = 0; /* True if wrong number of arguments */
- int is_agg = 0; /* True if is an aggregate function */
- int auth; /* Authorization to use the function */
- int nId; /* Number of characters in function name */
- const char *zId; /* The function name. */
- FuncDef *pDef; /* Information about the function */
- u8 enc = ENC(pParse->db); /* The database encoding */
-
- testcase( pExpr->op==TK_CONST_FUNC );
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- zId = pExpr->u.zToken;
- nId = sqlite3Strlen30(zId);
- pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
- if( pDef==0 ){
- pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
- if( pDef==0 ){
- no_such_func = 1;
- }else{
- wrong_num_args = 1;
- }
- }else{
- is_agg = pDef->xFunc==0;
- }
-#ifndef SQLITE_OMIT_AUTHORIZATION
- if( pDef ){
- auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
- if( auth!=SQLITE_OK ){
- if( auth==SQLITE_DENY ){
- sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
- pDef->zName);
- pNC->nErr++;
- }
- pExpr->op = TK_NULL;
- return WRC_Prune;
- }
- }
-#endif
- if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
- sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
- pNC->nErr++;
- is_agg = 0;
- }else if( no_such_func ){
- sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
- pNC->nErr++;
- }else if( wrong_num_args ){
- sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
- nId, zId);
- pNC->nErr++;
- }
- if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
- sqlite3WalkExprList(pWalker, pList);
- if( is_agg ){
- NameContext *pNC2 = pNC;
- pExpr->op = TK_AGG_FUNCTION;
- pExpr->op2 = 0;
- while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
- pExpr->op2++;
- pNC2 = pNC2->pNext;
- }
- if( pNC2 ) pNC2->ncFlags |= NC_HasAgg;
- pNC->ncFlags |= NC_AllowAgg;
- }
- /* FIX ME: Compute pExpr->affinity based on the expected return
- ** type of the function
- */
- return WRC_Prune;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_SELECT:
- case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
-#endif
- case TK_IN: {
- testcase( pExpr->op==TK_IN );
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- int nRef = pNC->nRef;
-#ifndef SQLITE_OMIT_CHECK
- if( (pNC->ncFlags & NC_IsCheck)!=0 ){
- sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
- }
-#endif
- sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
- assert( pNC->nRef>=nRef );
- if( nRef!=pNC->nRef ){
- ExprSetProperty(pExpr, EP_VarSelect);
- }
- }
- break;
- }
-#ifndef SQLITE_OMIT_CHECK
- case TK_VARIABLE: {
- if( (pNC->ncFlags & NC_IsCheck)!=0 ){
- sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
- }
- break;
- }
-#endif
- }
- return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
-}
-
-/*
-** pEList is a list of expressions which are really the result set of the
-** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause.
-** This routine checks to see if pE is a simple identifier which corresponds
-** to the AS-name of one of the terms of the expression list. If it is,
-** this routine return an integer between 1 and N where N is the number of
-** elements in pEList, corresponding to the matching entry. If there is
-** no match, or if pE is not a simple identifier, then this routine
-** return 0.
-**
-** pEList has been resolved. pE has not.
-*/
-static int resolveAsName(
- Parse *pParse, /* Parsing context for error messages */
- ExprList *pEList, /* List of expressions to scan */
- Expr *pE /* Expression we are trying to match */
-){
- int i; /* Loop counter */
-
- UNUSED_PARAMETER(pParse);
-
- if( pE->op==TK_ID ){
- char *zCol = pE->u.zToken;
- for(i=0; i<pEList->nExpr; i++){
- char *zAs = pEList->a[i].zName;
- if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
- return i+1;
- }
- }
- }
- return 0;
-}
-
-/*
-** pE is a pointer to an expression which is a single term in the
-** ORDER BY of a compound SELECT. The expression has not been
-** name resolved.
-**
-** At the point this routine is called, we already know that the
-** ORDER BY term is not an integer index into the result set. That
-** case is handled by the calling routine.
-**
-** Attempt to match pE against result set columns in the left-most
-** SELECT statement. Return the index i of the matching column,
-** as an indication to the caller that it should sort by the i-th column.
-** The left-most column is 1. In other words, the value returned is the
-** same integer value that would be used in the SQL statement to indicate
-** the column.
-**
-** If there is no match, return 0. Return -1 if an error occurs.
-*/
-static int resolveOrderByTermToExprList(
- Parse *pParse, /* Parsing context for error messages */
- Select *pSelect, /* The SELECT statement with the ORDER BY clause */
- Expr *pE /* The specific ORDER BY term */
-){
- int i; /* Loop counter */
- ExprList *pEList; /* The columns of the result set */
- NameContext nc; /* Name context for resolving pE */
- sqlite3 *db; /* Database connection */
- int rc; /* Return code from subprocedures */
- u8 savedSuppErr; /* Saved value of db->suppressErr */
-
- assert( sqlite3ExprIsInteger(pE, &i)==0 );
- pEList = pSelect->pEList;
-
- /* Resolve all names in the ORDER BY term expression
- */
- memset(&nc, 0, sizeof(nc));
- nc.pParse = pParse;
- nc.pSrcList = pSelect->pSrc;
- nc.pEList = pEList;
- nc.ncFlags = NC_AllowAgg;
- nc.nErr = 0;
- db = pParse->db;
- savedSuppErr = db->suppressErr;
- db->suppressErr = 1;
- rc = sqlite3ResolveExprNames(&nc, pE);
- db->suppressErr = savedSuppErr;
- if( rc ) return 0;
-
- /* Try to match the ORDER BY expression against an expression
- ** in the result set. Return an 1-based index of the matching
- ** result-set entry.
- */
- for(i=0; i<pEList->nExpr; i++){
- if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){
- return i+1;
- }
- }
-
- /* If no match, return 0. */
- return 0;
-}
-
-/*
-** Generate an ORDER BY or GROUP BY term out-of-range error.
-*/
-static void resolveOutOfRangeError(
- Parse *pParse, /* The error context into which to write the error */
- const char *zType, /* "ORDER" or "GROUP" */
- int i, /* The index (1-based) of the term out of range */
- int mx /* Largest permissible value of i */
-){
- sqlite3ErrorMsg(pParse,
- "%r %s BY term out of range - should be "
- "between 1 and %d", i, zType, mx);
-}
-
-/*
-** Analyze the ORDER BY clause in a compound SELECT statement. Modify
-** each term of the ORDER BY clause is a constant integer between 1
-** and N where N is the number of columns in the compound SELECT.
-**
-** ORDER BY terms that are already an integer between 1 and N are
-** unmodified. ORDER BY terms that are integers outside the range of
-** 1 through N generate an error. ORDER BY terms that are expressions
-** are matched against result set expressions of compound SELECT
-** beginning with the left-most SELECT and working toward the right.
-** At the first match, the ORDER BY expression is transformed into
-** the integer column number.
-**
-** Return the number of errors seen.
-*/
-static int resolveCompoundOrderBy(
- Parse *pParse, /* Parsing context. Leave error messages here */
- Select *pSelect /* The SELECT statement containing the ORDER BY */
-){
- int i;
- ExprList *pOrderBy;
- ExprList *pEList;
- sqlite3 *db;
- int moreToDo = 1;
-
- pOrderBy = pSelect->pOrderBy;
- if( pOrderBy==0 ) return 0;
- db = pParse->db;
-#if SQLITE_MAX_COLUMN
- if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
- return 1;
- }
-#endif
- for(i=0; i<pOrderBy->nExpr; i++){
- pOrderBy->a[i].done = 0;
- }
- pSelect->pNext = 0;
- while( pSelect->pPrior ){
- pSelect->pPrior->pNext = pSelect;
- pSelect = pSelect->pPrior;
- }
- while( pSelect && moreToDo ){
- struct ExprList_item *pItem;
- moreToDo = 0;
- pEList = pSelect->pEList;
- assert( pEList!=0 );
- for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
- int iCol = -1;
- Expr *pE, *pDup;
- if( pItem->done ) continue;
- pE = sqlite3ExprSkipCollate(pItem->pExpr);
- if( sqlite3ExprIsInteger(pE, &iCol) ){
- if( iCol<=0 || iCol>pEList->nExpr ){
- resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
- return 1;
- }
- }else{
- iCol = resolveAsName(pParse, pEList, pE);
- if( iCol==0 ){
- pDup = sqlite3ExprDup(db, pE, 0);
- if( !db->mallocFailed ){
- assert(pDup);
- iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup);
- }
- sqlite3ExprDelete(db, pDup);
- }
- }
- if( iCol>0 ){
- /* Convert the ORDER BY term into an integer column number iCol,
- ** taking care to preserve the COLLATE clause if it exists */
- Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
- if( pNew==0 ) return 1;
- pNew->flags |= EP_IntValue;
- pNew->u.iValue = iCol;
- if( pItem->pExpr==pE ){
- pItem->pExpr = pNew;
- }else{
- assert( pItem->pExpr->op==TK_COLLATE );
- assert( pItem->pExpr->pLeft==pE );
- pItem->pExpr->pLeft = pNew;
- }
- sqlite3ExprDelete(db, pE);
- pItem->iOrderByCol = (u16)iCol;
- pItem->done = 1;
- }else{
- moreToDo = 1;
- }
- }
- pSelect = pSelect->pNext;
- }
- for(i=0; i<pOrderBy->nExpr; i++){
- if( pOrderBy->a[i].done==0 ){
- sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any "
- "column in the result set", i+1);
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** Check every term in the ORDER BY or GROUP BY clause pOrderBy of
-** the SELECT statement pSelect. If any term is reference to a
-** result set expression (as determined by the ExprList.a.iCol field)
-** then convert that term into a copy of the corresponding result set
-** column.
-**
-** If any errors are detected, add an error message to pParse and
-** return non-zero. Return zero if no errors are seen.
-*/
-SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
- Parse *pParse, /* Parsing context. Leave error messages here */
- Select *pSelect, /* The SELECT statement containing the clause */
- ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */
- const char *zType /* "ORDER" or "GROUP" */
-){
- int i;
- sqlite3 *db = pParse->db;
- ExprList *pEList;
- struct ExprList_item *pItem;
-
- if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
-#if SQLITE_MAX_COLUMN
- if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
- return 1;
- }
-#endif
- pEList = pSelect->pEList;
- assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
- for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
- if( pItem->iOrderByCol ){
- if( pItem->iOrderByCol>pEList->nExpr ){
- resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
- return 1;
- }
- resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType,0);
- }
- }
- return 0;
-}
-
-/*
-** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
-** The Name context of the SELECT statement is pNC. zType is either
-** "ORDER" or "GROUP" depending on which type of clause pOrderBy is.
-**
-** This routine resolves each term of the clause into an expression.
-** If the order-by term is an integer I between 1 and N (where N is the
-** number of columns in the result set of the SELECT) then the expression
-** in the resolution is a copy of the I-th result-set expression. If
-** the order-by term is an identify that corresponds to the AS-name of
-** a result-set expression, then the term resolves to a copy of the
-** result-set expression. Otherwise, the expression is resolved in
-** the usual way - using sqlite3ResolveExprNames().
-**
-** This routine returns the number of errors. If errors occur, then
-** an appropriate error message might be left in pParse. (OOM errors
-** excepted.)
-*/
-static int resolveOrderGroupBy(
- NameContext *pNC, /* The name context of the SELECT statement */
- Select *pSelect, /* The SELECT statement holding pOrderBy */
- ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */
- const char *zType /* Either "ORDER" or "GROUP", as appropriate */
-){
- int i, j; /* Loop counters */
- int iCol; /* Column number */
- struct ExprList_item *pItem; /* A term of the ORDER BY clause */
- Parse *pParse; /* Parsing context */
- int nResult; /* Number of terms in the result set */
-
- if( pOrderBy==0 ) return 0;
- nResult = pSelect->pEList->nExpr;
- pParse = pNC->pParse;
- for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
- Expr *pE = pItem->pExpr;
- iCol = resolveAsName(pParse, pSelect->pEList, pE);
- if( iCol>0 ){
- /* If an AS-name match is found, mark this ORDER BY column as being
- ** a copy of the iCol-th result-set column. The subsequent call to
- ** sqlite3ResolveOrderGroupBy() will convert the expression to a
- ** copy of the iCol-th result-set expression. */
- pItem->iOrderByCol = (u16)iCol;
- continue;
- }
- if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
- /* The ORDER BY term is an integer constant. Again, set the column
- ** number so that sqlite3ResolveOrderGroupBy() will convert the
- ** order-by term to a copy of the result-set expression */
- if( iCol<1 || iCol>0xffff ){
- resolveOutOfRangeError(pParse, zType, i+1, nResult);
- return 1;
- }
- pItem->iOrderByCol = (u16)iCol;
- continue;
- }
-
- /* Otherwise, treat the ORDER BY term as an ordinary expression */
- pItem->iOrderByCol = 0;
- if( sqlite3ResolveExprNames(pNC, pE) ){
- return 1;
- }
- for(j=0; j<pSelect->pEList->nExpr; j++){
- if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){
- pItem->iOrderByCol = j+1;
- }
- }
- }
- return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
-}
-
-/*
-** Resolve names in the SELECT statement p and all of its descendents.
-*/
-static int resolveSelectStep(Walker *pWalker, Select *p){
- NameContext *pOuterNC; /* Context that contains this SELECT */
- NameContext sNC; /* Name context of this SELECT */
- int isCompound; /* True if p is a compound select */
- int nCompound; /* Number of compound terms processed so far */
- Parse *pParse; /* Parsing context */
- ExprList *pEList; /* Result set expression list */
- int i; /* Loop counter */
- ExprList *pGroupBy; /* The GROUP BY clause */
- Select *pLeftmost; /* Left-most of SELECT of a compound */
- sqlite3 *db; /* Database connection */
-
-
- assert( p!=0 );
- if( p->selFlags & SF_Resolved ){
- return WRC_Prune;
- }
- pOuterNC = pWalker->u.pNC;
- pParse = pWalker->pParse;
- db = pParse->db;
-
- /* Normally sqlite3SelectExpand() will be called first and will have
- ** already expanded this SELECT. However, if this is a subquery within
- ** an expression, sqlite3ResolveExprNames() will be called without a
- ** prior call to sqlite3SelectExpand(). When that happens, let
- ** sqlite3SelectPrep() do all of the processing for this SELECT.
- ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and
- ** this routine in the correct order.
- */
- if( (p->selFlags & SF_Expanded)==0 ){
- sqlite3SelectPrep(pParse, p, pOuterNC);
- return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune;
- }
-
- isCompound = p->pPrior!=0;
- nCompound = 0;
- pLeftmost = p;
- while( p ){
- assert( (p->selFlags & SF_Expanded)!=0 );
- assert( (p->selFlags & SF_Resolved)==0 );
- p->selFlags |= SF_Resolved;
-
- /* Resolve the expressions in the LIMIT and OFFSET clauses. These
- ** are not allowed to refer to any names, so pass an empty NameContext.
- */
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
- sqlite3ResolveExprNames(&sNC, p->pOffset) ){
- return WRC_Abort;
- }
-
- /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
- ** resolve the result-set expression list.
- */
- sNC.ncFlags = NC_AllowAgg;
- sNC.pSrcList = p->pSrc;
- sNC.pNext = pOuterNC;
-
- /* Resolve names in the result set. */
- pEList = p->pEList;
- assert( pEList!=0 );
- for(i=0; i<pEList->nExpr; i++){
- Expr *pX = pEList->a[i].pExpr;
- if( sqlite3ResolveExprNames(&sNC, pX) ){
- return WRC_Abort;
- }
- }
-
- /* Recursively resolve names in all subqueries
- */
- for(i=0; i<p->pSrc->nSrc; i++){
- struct SrcList_item *pItem = &p->pSrc->a[i];
- if( pItem->pSelect ){
- NameContext *pNC; /* Used to iterate name contexts */
- int nRef = 0; /* Refcount for pOuterNC and outer contexts */
- const char *zSavedContext = pParse->zAuthContext;
-
- /* Count the total number of references to pOuterNC and all of its
- ** parent contexts. After resolving references to expressions in
- ** pItem->pSelect, check if this value has changed. If so, then
- ** SELECT statement pItem->pSelect must be correlated. Set the
- ** pItem->isCorrelated flag if this is the case. */
- for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef;
-
- if( pItem->zName ) pParse->zAuthContext = pItem->zName;
- sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC);
- pParse->zAuthContext = zSavedContext;
- if( pParse->nErr || db->mallocFailed ) return WRC_Abort;
-
- for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef;
- assert( pItem->isCorrelated==0 && nRef<=0 );
- pItem->isCorrelated = (nRef!=0);
- }
- }
-
- /* If there are no aggregate functions in the result-set, and no GROUP BY
- ** expression, do not allow aggregates in any of the other expressions.
- */
- assert( (p->selFlags & SF_Aggregate)==0 );
- pGroupBy = p->pGroupBy;
- if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
- p->selFlags |= SF_Aggregate;
- }else{
- sNC.ncFlags &= ~NC_AllowAgg;
- }
-
- /* If a HAVING clause is present, then there must be a GROUP BY clause.
- */
- if( p->pHaving && !pGroupBy ){
- sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
- return WRC_Abort;
- }
-
- /* Add the expression list to the name-context before parsing the
- ** other expressions in the SELECT statement. This is so that
- ** expressions in the WHERE clause (etc.) can refer to expressions by
- ** aliases in the result set.
- **
- ** Minor point: If this is the case, then the expression will be
- ** re-evaluated for each reference to it.
- */
- sNC.pEList = p->pEList;
- if( sqlite3ResolveExprNames(&sNC, p->pWhere) ||
- sqlite3ResolveExprNames(&sNC, p->pHaving)
- ){
- return WRC_Abort;
- }
-
- /* The ORDER BY and GROUP BY clauses may not refer to terms in
- ** outer queries
- */
- sNC.pNext = 0;
- sNC.ncFlags |= NC_AllowAgg;
-
- /* Process the ORDER BY clause for singleton SELECT statements.
- ** The ORDER BY clause for compounds SELECT statements is handled
- ** below, after all of the result-sets for all of the elements of
- ** the compound have been resolved.
- */
- if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
- return WRC_Abort;
- }
- if( db->mallocFailed ){
- return WRC_Abort;
- }
-
- /* Resolve the GROUP BY clause. At the same time, make sure
- ** the GROUP BY clause does not contain aggregate functions.
- */
- if( pGroupBy ){
- struct ExprList_item *pItem;
-
- if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){
- return WRC_Abort;
- }
- for(i=0, pItem=pGroupBy->a; i<pGroupBy->nExpr; i++, pItem++){
- if( ExprHasProperty(pItem->pExpr, EP_Agg) ){
- sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in "
- "the GROUP BY clause");
- return WRC_Abort;
- }
- }
- }
-
- /* Advance to the next term of the compound
- */
- p = p->pPrior;
- nCompound++;
- }
-
- /* Resolve the ORDER BY on a compound SELECT after all terms of
- ** the compound have been resolved.
- */
- if( isCompound && resolveCompoundOrderBy(pParse, pLeftmost) ){
- return WRC_Abort;
- }
-
- return WRC_Prune;
-}
-
-/*
-** This routine walks an expression tree and resolves references to
-** table columns and result-set columns. At the same time, do error
-** checking on function usage and set a flag if any aggregate functions
-** are seen.
-**
-** To resolve table columns references we look for nodes (or subtrees) of the
-** form X.Y.Z or Y.Z or just Z where
-**
-** X: The name of a database. Ex: "main" or "temp" or
-** the symbolic name assigned to an ATTACH-ed database.
-**
-** Y: The name of a table in a FROM clause. Or in a trigger
-** one of the special names "old" or "new".
-**
-** Z: The name of a column in table Y.
-**
-** The node at the root of the subtree is modified as follows:
-**
-** Expr.op Changed to TK_COLUMN
-** Expr.pTab Points to the Table object for X.Y
-** Expr.iColumn The column index in X.Y. -1 for the rowid.
-** Expr.iTable The VDBE cursor number for X.Y
-**
-**
-** To resolve result-set references, look for expression nodes of the
-** form Z (with no X and Y prefix) where the Z matches the right-hand
-** size of an AS clause in the result-set of a SELECT. The Z expression
-** is replaced by a copy of the left-hand side of the result-set expression.
-** Table-name and function resolution occurs on the substituted expression
-** tree. For example, in:
-**
-** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x;
-**
-** The "x" term of the order by is replaced by "a+b" to render:
-**
-** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b;
-**
-** Function calls are checked to make sure that the function is
-** defined and that the correct number of arguments are specified.
-** If the function is an aggregate function, then the NC_HasAgg flag is
-** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION.
-** If an expression contains aggregate functions then the EP_Agg
-** property on the expression is set.
-**
-** An error message is left in pParse if anything is amiss. The number
-** if errors is returned.
-*/
-SQLITE_PRIVATE int sqlite3ResolveExprNames(
- NameContext *pNC, /* Namespace to resolve expressions in. */
- Expr *pExpr /* The expression to be analyzed. */
-){
- u8 savedHasAgg;
- Walker w;
-
- if( pExpr==0 ) return 0;
-#if SQLITE_MAX_EXPR_DEPTH>0
- {
- Parse *pParse = pNC->pParse;
- if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){
- return 1;
- }
- pParse->nHeight += pExpr->nHeight;
- }
-#endif
- savedHasAgg = pNC->ncFlags & NC_HasAgg;
- pNC->ncFlags &= ~NC_HasAgg;
- w.xExprCallback = resolveExprStep;
- w.xSelectCallback = resolveSelectStep;
- w.pParse = pNC->pParse;
- w.u.pNC = pNC;
- sqlite3WalkExpr(&w, pExpr);
-#if SQLITE_MAX_EXPR_DEPTH>0
- pNC->pParse->nHeight -= pExpr->nHeight;
-#endif
- if( pNC->nErr>0 || w.pParse->nErr>0 ){
- ExprSetProperty(pExpr, EP_Error);
- }
- if( pNC->ncFlags & NC_HasAgg ){
- ExprSetProperty(pExpr, EP_Agg);
- }else if( savedHasAgg ){
- pNC->ncFlags |= NC_HasAgg;
- }
- return ExprHasProperty(pExpr, EP_Error);
-}
-
-
-/*
-** Resolve all names in all expressions of a SELECT and in all
-** decendents of the SELECT, including compounds off of p->pPrior,
-** subqueries in expressions, and subqueries used as FROM clause
-** terms.
-**
-** See sqlite3ResolveExprNames() for a description of the kinds of
-** transformations that occur.
-**
-** All SELECT statements should have been expanded using
-** sqlite3SelectExpand() prior to invoking this routine.
-*/
-SQLITE_PRIVATE void sqlite3ResolveSelectNames(
- Parse *pParse, /* The parser context */
- Select *p, /* The SELECT statement being coded. */
- NameContext *pOuterNC /* Name context for parent SELECT statement */
-){
- Walker w;
-
- assert( p!=0 );
- w.xExprCallback = resolveExprStep;
- w.xSelectCallback = resolveSelectStep;
- w.pParse = pParse;
- w.u.pNC = pOuterNC;
- sqlite3WalkSelect(&w, p);
-}
-
-/************** End of resolve.c *********************************************/
-/************** Begin file expr.c ********************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains routines used for analyzing expressions and
-** for generating VDBE code that evaluates expressions in SQLite.
-*/
-
-/*
-** Return the 'affinity' of the expression pExpr if any.
-**
-** If pExpr is a column, a reference to a column via an 'AS' alias,
-** or a sub-select with a column as the return value, then the
-** affinity of that column is returned. Otherwise, 0x00 is returned,
-** indicating no affinity for the expression.
-**
-** i.e. the WHERE clause expresssions in the following statements all
-** have an affinity:
-**
-** CREATE TABLE t1(a);
-** SELECT * FROM t1 WHERE a;
-** SELECT a AS b FROM t1 WHERE b;
-** SELECT * FROM t1 WHERE (select a from t1);
-*/
-SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
- int op;
- pExpr = sqlite3ExprSkipCollate(pExpr);
- op = pExpr->op;
- if( op==TK_SELECT ){
- assert( pExpr->flags&EP_xIsSelect );
- return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
- }
-#ifndef SQLITE_OMIT_CAST
- if( op==TK_CAST ){
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- return sqlite3AffinityType(pExpr->u.zToken);
- }
-#endif
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
- && pExpr->pTab!=0
- ){
- /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally
- ** a TK_COLUMN but was previously evaluated and cached in a register */
- int j = pExpr->iColumn;
- if( j<0 ) return SQLITE_AFF_INTEGER;
- assert( pExpr->pTab && j<pExpr->pTab->nCol );
- return pExpr->pTab->aCol[j].affinity;
- }
- return pExpr->affinity;
-}
-
-/*
-** Set the collating sequence for expression pExpr to be the collating
-** sequence named by pToken. Return a pointer to a new Expr node that
-** implements the COLLATE operator.
-**
-** If a memory allocation error occurs, that fact is recorded in pParse->db
-** and the pExpr parameter is returned unchanged.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
- if( pCollName->n>0 ){
- Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
- if( pNew ){
- pNew->pLeft = pExpr;
- pNew->flags |= EP_Collate;
- pExpr = pNew;
- }
- }
- return pExpr;
-}
-SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
- Token s;
- assert( zC!=0 );
- s.z = zC;
- s.n = sqlite3Strlen30(s.z);
- return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
-}
-
-/*
-** Skip over any TK_COLLATE and/or TK_AS operators at the root of
-** an expression.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
- while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
- pExpr = pExpr->pLeft;
- }
- return pExpr;
-}
-
-/*
-** Return the collation sequence for the expression pExpr. If
-** there is no defined collating sequence, return NULL.
-**
-** The collating sequence might be determined by a COLLATE operator
-** or by the presence of a column with a defined collating sequence.
-** COLLATE operators take first precedence. Left operands take
-** precedence over right operands.
-*/
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
- sqlite3 *db = pParse->db;
- CollSeq *pColl = 0;
- Expr *p = pExpr;
- while( p ){
- int op = p->op;
- if( op==TK_CAST || op==TK_UPLUS ){
- p = p->pLeft;
- continue;
- }
- assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
- if( op==TK_COLLATE ){
- if( db->init.busy ){
- /* Do not report errors when parsing while the schema */
- pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
- }else{
- pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
- }
- break;
- }
- if( p->pTab!=0
- && (op==TK_AGG_COLUMN || op==TK_COLUMN
- || op==TK_REGISTER || op==TK_TRIGGER)
- ){
- /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
- ** a TK_COLUMN but was previously evaluated and cached in a register */
- int j = p->iColumn;
- if( j>=0 ){
- const char *zColl = p->pTab->aCol[j].zColl;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
- }
- break;
- }
- if( p->flags & EP_Collate ){
- if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
- p = p->pLeft;
- }else{
- p = p->pRight;
- }
- }else{
- break;
- }
- }
- if( sqlite3CheckCollSeq(pParse, pColl) ){
- pColl = 0;
- }
- return pColl;
-}
-
-/*
-** pExpr is an operand of a comparison operator. aff2 is the
-** type affinity of the other operand. This routine returns the
-** type affinity that should be used for the comparison operator.
-*/
-SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2){
- char aff1 = sqlite3ExprAffinity(pExpr);
- if( aff1 && aff2 ){
- /* Both sides of the comparison are columns. If one has numeric
- ** affinity, use that. Otherwise use no affinity.
- */
- if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){
- return SQLITE_AFF_NUMERIC;
- }else{
- return SQLITE_AFF_NONE;
- }
- }else if( !aff1 && !aff2 ){
- /* Neither side of the comparison is a column. Compare the
- ** results directly.
- */
- return SQLITE_AFF_NONE;
- }else{
- /* One side is a column, the other is not. Use the columns affinity. */
- assert( aff1==0 || aff2==0 );
- return (aff1 + aff2);
- }
-}
-
-/*
-** pExpr is a comparison operator. Return the type affinity that should
-** be applied to both operands prior to doing the comparison.
-*/
-static char comparisonAffinity(Expr *pExpr){
- char aff;
- assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
- pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
- pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
- assert( pExpr->pLeft );
- aff = sqlite3ExprAffinity(pExpr->pLeft);
- if( pExpr->pRight ){
- aff = sqlite3CompareAffinity(pExpr->pRight, aff);
- }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
- }else if( !aff ){
- aff = SQLITE_AFF_NONE;
- }
- return aff;
-}
-
-/*
-** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.
-** idx_affinity is the affinity of an indexed column. Return true
-** if the index with affinity idx_affinity may be used to implement
-** the comparison in pExpr.
-*/
-SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
- char aff = comparisonAffinity(pExpr);
- switch( aff ){
- case SQLITE_AFF_NONE:
- return 1;
- case SQLITE_AFF_TEXT:
- return idx_affinity==SQLITE_AFF_TEXT;
- default:
- return sqlite3IsNumericAffinity(idx_affinity);
- }
-}
-
-/*
-** Return the P5 value that should be used for a binary comparison
-** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
-*/
-static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
- u8 aff = (char)sqlite3ExprAffinity(pExpr2);
- aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull;
- return aff;
-}
-
-/*
-** Return a pointer to the collation sequence that should be used by
-** a binary comparison operator comparing pLeft and pRight.
-**
-** If the left hand expression has a collating sequence type, then it is
-** used. Otherwise the collation sequence for the right hand expression
-** is used, or the default (BINARY) if neither expression has a collating
-** type.
-**
-** Argument pRight (but not pLeft) may be a null pointer. In this case,
-** it is not considered.
-*/
-SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(
- Parse *pParse,
- Expr *pLeft,
- Expr *pRight
-){
- CollSeq *pColl;
- assert( pLeft );
- if( pLeft->flags & EP_Collate ){
- pColl = sqlite3ExprCollSeq(pParse, pLeft);
- }else if( pRight && (pRight->flags & EP_Collate)!=0 ){
- pColl = sqlite3ExprCollSeq(pParse, pRight);
- }else{
- pColl = sqlite3ExprCollSeq(pParse, pLeft);
- if( !pColl ){
- pColl = sqlite3ExprCollSeq(pParse, pRight);
- }
- }
- return pColl;
-}
-
-/*
-** Generate code for a comparison operator.
-*/
-static int codeCompare(
- Parse *pParse, /* The parsing (and code generating) context */
- Expr *pLeft, /* The left operand */
- Expr *pRight, /* The right operand */
- int opcode, /* The comparison opcode */
- int in1, int in2, /* Register holding operands */
- int dest, /* Jump here if true. */
- int jumpIfNull /* If true, jump if either operand is NULL */
-){
- int p5;
- int addr;
- CollSeq *p4;
-
- p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
- p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
- addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
- (void*)p4, P4_COLLSEQ);
- sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5);
- return addr;
-}
-
-#if SQLITE_MAX_EXPR_DEPTH>0
-/*
-** Check that argument nHeight is less than or equal to the maximum
-** expression depth allowed. If it is not, leave an error message in
-** pParse.
-*/
-SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){
- int rc = SQLITE_OK;
- int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH];
- if( nHeight>mxHeight ){
- sqlite3ErrorMsg(pParse,
- "Expression tree is too large (maximum depth %d)", mxHeight
- );
- rc = SQLITE_ERROR;
- }
- return rc;
-}
-
-/* The following three functions, heightOfExpr(), heightOfExprList()
-** and heightOfSelect(), are used to determine the maximum height
-** of any expression tree referenced by the structure passed as the
-** first argument.
-**
-** If this maximum height is greater than the current value pointed
-** to by pnHeight, the second parameter, then set *pnHeight to that
-** value.
-*/
-static void heightOfExpr(Expr *p, int *pnHeight){
- if( p ){
- if( p->nHeight>*pnHeight ){
- *pnHeight = p->nHeight;
- }
- }
-}
-static void heightOfExprList(ExprList *p, int *pnHeight){
- if( p ){
- int i;
- for(i=0; i<p->nExpr; i++){
- heightOfExpr(p->a[i].pExpr, pnHeight);
- }
- }
-}
-static void heightOfSelect(Select *p, int *pnHeight){
- if( p ){
- heightOfExpr(p->pWhere, pnHeight);
- heightOfExpr(p->pHaving, pnHeight);
- heightOfExpr(p->pLimit, pnHeight);
- heightOfExpr(p->pOffset, pnHeight);
- heightOfExprList(p->pEList, pnHeight);
- heightOfExprList(p->pGroupBy, pnHeight);
- heightOfExprList(p->pOrderBy, pnHeight);
- heightOfSelect(p->pPrior, pnHeight);
- }
-}
-
-/*
-** Set the Expr.nHeight variable in the structure passed as an
-** argument. An expression with no children, Expr.pList or
-** Expr.pSelect member has a height of 1. Any other expression
-** has a height equal to the maximum height of any other
-** referenced Expr plus one.
-*/
-static void exprSetHeight(Expr *p){
- int nHeight = 0;
- heightOfExpr(p->pLeft, &nHeight);
- heightOfExpr(p->pRight, &nHeight);
- if( ExprHasProperty(p, EP_xIsSelect) ){
- heightOfSelect(p->x.pSelect, &nHeight);
- }else{
- heightOfExprList(p->x.pList, &nHeight);
- }
- p->nHeight = nHeight + 1;
-}
-
-/*
-** Set the Expr.nHeight variable using the exprSetHeight() function. If
-** the height is greater than the maximum allowed expression depth,
-** leave an error in pParse.
-*/
-SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
- exprSetHeight(p);
- sqlite3ExprCheckHeight(pParse, p->nHeight);
-}
-
-/*
-** Return the maximum height of any expression tree referenced
-** by the select statement passed as an argument.
-*/
-SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){
- int nHeight = 0;
- heightOfSelect(p, &nHeight);
- return nHeight;
-}
-#else
- #define exprSetHeight(y)
-#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
-
-/*
-** This routine is the core allocator for Expr nodes.
-**
-** Construct a new expression node and return a pointer to it. Memory
-** for this node and for the pToken argument is a single allocation
-** obtained from sqlite3DbMalloc(). The calling function
-** is responsible for making sure the node eventually gets freed.
-**
-** If dequote is true, then the token (if it exists) is dequoted.
-** If dequote is false, no dequoting is performance. The deQuote
-** parameter is ignored if pToken is NULL or if the token does not
-** appear to be quoted. If the quotes were of the form "..." (double-quotes)
-** then the EP_DblQuoted flag is set on the expression node.
-**
-** Special case: If op==TK_INTEGER and pToken points to a string that
-** can be translated into a 32-bit integer, then the token is not
-** stored in u.zToken. Instead, the integer values is written
-** into u.iValue and the EP_IntValue flag is set. No extra storage
-** is allocated to hold the integer text and the dequote flag is ignored.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
- sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
- int op, /* Expression opcode */
- const Token *pToken, /* Token argument. Might be NULL */
- int dequote /* True to dequote */
-){
- Expr *pNew;
- int nExtra = 0;
- int iValue = 0;
-
- if( pToken ){
- if( op!=TK_INTEGER || pToken->z==0
- || sqlite3GetInt32(pToken->z, &iValue)==0 ){
- nExtra = pToken->n+1;
- assert( iValue>=0 );
- }
- }
- pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra);
- if( pNew ){
- pNew->op = (u8)op;
- pNew->iAgg = -1;
- if( pToken ){
- if( nExtra==0 ){
- pNew->flags |= EP_IntValue;
- pNew->u.iValue = iValue;
- }else{
- int c;
- pNew->u.zToken = (char*)&pNew[1];
- assert( pToken->z!=0 || pToken->n==0 );
- if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
- pNew->u.zToken[pToken->n] = 0;
- if( dequote && nExtra>=3
- && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
- sqlite3Dequote(pNew->u.zToken);
- if( c=='"' ) pNew->flags |= EP_DblQuoted;
- }
- }
- }
-#if SQLITE_MAX_EXPR_DEPTH>0
- pNew->nHeight = 1;
-#endif
- }
- return pNew;
-}
-
-/*
-** Allocate a new expression node from a zero-terminated token that has
-** already been dequoted.
-*/
-SQLITE_PRIVATE Expr *sqlite3Expr(
- sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
- int op, /* Expression opcode */
- const char *zToken /* Token argument. Might be NULL */
-){
- Token x;
- x.z = zToken;
- x.n = zToken ? sqlite3Strlen30(zToken) : 0;
- return sqlite3ExprAlloc(db, op, &x, 0);
-}
-
-/*
-** Attach subtrees pLeft and pRight to the Expr node pRoot.
-**
-** If pRoot==NULL that means that a memory allocation error has occurred.
-** In that case, delete the subtrees pLeft and pRight.
-*/
-SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(
- sqlite3 *db,
- Expr *pRoot,
- Expr *pLeft,
- Expr *pRight
-){
- if( pRoot==0 ){
- assert( db->mallocFailed );
- sqlite3ExprDelete(db, pLeft);
- sqlite3ExprDelete(db, pRight);
- }else{
- if( pRight ){
- pRoot->pRight = pRight;
- pRoot->flags |= EP_Collate & pRight->flags;
- }
- if( pLeft ){
- pRoot->pLeft = pLeft;
- pRoot->flags |= EP_Collate & pLeft->flags;
- }
- exprSetHeight(pRoot);
- }
-}
-
-/*
-** Allocate a Expr node which joins as many as two subtrees.
-**
-** One or both of the subtrees can be NULL. Return a pointer to the new
-** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed,
-** free the subtrees and return NULL.
-*/
-SQLITE_PRIVATE Expr *sqlite3PExpr(
- Parse *pParse, /* Parsing context */
- int op, /* Expression opcode */
- Expr *pLeft, /* Left operand */
- Expr *pRight, /* Right operand */
- const Token *pToken /* Argument token */
-){
- Expr *p;
- if( op==TK_AND && pLeft && pRight ){
- /* Take advantage of short-circuit false optimization for AND */
- p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
- }else{
- p = sqlite3ExprAlloc(pParse->db, op, pToken, 1);
- sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
- }
- if( p ) {
- sqlite3ExprCheckHeight(pParse, p->nHeight);
- }
- return p;
-}
-
-/*
-** Return 1 if an expression must be FALSE in all cases and 0 if the
-** expression might be true. This is an optimization. If is OK to
-** return 0 here even if the expression really is always false (a
-** false negative). But it is a bug to return 1 if the expression
-** might be true in some rare circumstances (a false positive.)
-**
-** Note that if the expression is part of conditional for a
-** LEFT JOIN, then we cannot determine at compile-time whether or not
-** is it true or false, so always return 0.
-*/
-static int exprAlwaysFalse(Expr *p){
- int v = 0;
- if( ExprHasProperty(p, EP_FromJoin) ) return 0;
- if( !sqlite3ExprIsInteger(p, &v) ) return 0;
- return v==0;
-}
-
-/*
-** Join two expressions using an AND operator. If either expression is
-** NULL, then just return the other expression.
-**
-** If one side or the other of the AND is known to be false, then instead
-** of returning an AND expression, just return a constant expression with
-** a value of false.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
- if( pLeft==0 ){
- return pRight;
- }else if( pRight==0 ){
- return pLeft;
- }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){
- sqlite3ExprDelete(db, pLeft);
- sqlite3ExprDelete(db, pRight);
- return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0);
- }else{
- Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
- sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
- return pNew;
- }
-}
-
-/*
-** Construct a new expression node for a function with multiple
-** arguments.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
- Expr *pNew;
- sqlite3 *db = pParse->db;
- assert( pToken );
- pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
- if( pNew==0 ){
- sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
- return 0;
- }
- pNew->x.pList = pList;
- assert( !ExprHasProperty(pNew, EP_xIsSelect) );
- sqlite3ExprSetHeight(pParse, pNew);
- return pNew;
-}
-
-/*
-** Assign a variable number to an expression that encodes a wildcard
-** in the original SQL statement.
-**
-** Wildcards consisting of a single "?" are assigned the next sequential
-** variable number.
-**
-** Wildcards of the form "?nnn" are assigned the number "nnn". We make
-** sure "nnn" is not too be to avoid a denial of service attack when
-** the SQL statement comes from an external source.
-**
-** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
-** as the previous instance of the same wildcard. Or if this is the first
-** instance of the wildcard, the next sequenial variable number is
-** assigned.
-*/
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
- sqlite3 *db = pParse->db;
- const char *z;
-
- if( pExpr==0 ) return;
- assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
- z = pExpr->u.zToken;
- assert( z!=0 );
- assert( z[0]!=0 );
- if( z[1]==0 ){
- /* Wildcard of the form "?". Assign the next variable number */
- assert( z[0]=='?' );
- pExpr->iColumn = (ynVar)(++pParse->nVar);
- }else{
- ynVar x = 0;
- u32 n = sqlite3Strlen30(z);
- if( z[0]=='?' ){
- /* Wildcard of the form "?nnn". Convert "nnn" to an integer and
- ** use it as the variable number */
- i64 i;
- int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
- pExpr->iColumn = x = (ynVar)i;
- testcase( i==0 );
- testcase( i==1 );
- testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
- testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
- if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
- sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
- db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
- x = 0;
- }
- if( i>pParse->nVar ){
- pParse->nVar = (int)i;
- }
- }else{
- /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
- ** number as the prior appearance of the same name, or if the name
- ** has never appeared before, reuse the same variable number
- */
- ynVar i;
- for(i=0; i<pParse->nzVar; i++){
- if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){
- pExpr->iColumn = x = (ynVar)i+1;
- break;
- }
- }
- if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
- }
- if( x>0 ){
- if( x>pParse->nzVar ){
- char **a;
- a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
- if( a==0 ) return; /* Error reported through db->mallocFailed */
- pParse->azVar = a;
- memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
- pParse->nzVar = x;
- }
- if( z[0]!='?' || pParse->azVar[x-1]==0 ){
- sqlite3DbFree(db, pParse->azVar[x-1]);
- pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
- }
- }
- }
- if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
- sqlite3ErrorMsg(pParse, "too many SQL variables");
- }
-}
-
-/*
-** Recursively delete an expression tree.
-*/
-SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
- if( p==0 ) return;
- /* Sanity check: Assert that the IntValue is non-negative if it exists */
- assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
- if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
- sqlite3ExprDelete(db, p->pLeft);
- sqlite3ExprDelete(db, p->pRight);
- if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){
- sqlite3DbFree(db, p->u.zToken);
- }
- if( ExprHasProperty(p, EP_xIsSelect) ){
- sqlite3SelectDelete(db, p->x.pSelect);
- }else{
- sqlite3ExprListDelete(db, p->x.pList);
- }
- }
- if( !ExprHasProperty(p, EP_Static) ){
- sqlite3DbFree(db, p);
- }
-}
-
-/*
-** Return the number of bytes allocated for the expression structure
-** passed as the first argument. This is always one of EXPR_FULLSIZE,
-** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
-*/
-static int exprStructSize(Expr *p){
- if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
- if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
- return EXPR_FULLSIZE;
-}
-
-/*
-** The dupedExpr*Size() routines each return the number of bytes required
-** to store a copy of an expression or expression tree. They differ in
-** how much of the tree is measured.
-**
-** dupedExprStructSize() Size of only the Expr structure
-** dupedExprNodeSize() Size of Expr + space for token
-** dupedExprSize() Expr + token + subtree components
-**
-***************************************************************************
-**
-** The dupedExprStructSize() function returns two values OR-ed together:
-** (1) the space required for a copy of the Expr structure only and
-** (2) the EP_xxx flags that indicate what the structure size should be.
-** The return values is always one of:
-**
-** EXPR_FULLSIZE
-** EXPR_REDUCEDSIZE | EP_Reduced
-** EXPR_TOKENONLYSIZE | EP_TokenOnly
-**
-** The size of the structure can be found by masking the return value
-** of this routine with 0xfff. The flags can be found by masking the
-** return value with EP_Reduced|EP_TokenOnly.
-**
-** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
-** (unreduced) Expr objects as they or originally constructed by the parser.
-** During expression analysis, extra information is computed and moved into
-** later parts of teh Expr object and that extra information might get chopped
-** off if the expression is reduced. Note also that it does not work to
-** make a EXPRDUP_REDUCE copy of a reduced expression. It is only legal
-** to reduce a pristine expression tree from the parser. The implementation
-** of dupedExprStructSize() contain multiple assert() statements that attempt
-** to enforce this constraint.
-*/
-static int dupedExprStructSize(Expr *p, int flags){
- int nSize;
- assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
- if( 0==(flags&EXPRDUP_REDUCE) ){
- nSize = EXPR_FULLSIZE;
- }else{
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
- assert( !ExprHasProperty(p, EP_FromJoin) );
- assert( (p->flags2 & EP2_MallocedToken)==0 );
- assert( (p->flags2 & EP2_Irreducible)==0 );
- if( p->pLeft || p->pRight || p->x.pList ){
- nSize = EXPR_REDUCEDSIZE | EP_Reduced;
- }else{
- nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
- }
- }
- return nSize;
-}
-
-/*
-** This function returns the space in bytes required to store the copy
-** of the Expr structure and a copy of the Expr.u.zToken string (if that
-** string is defined.)
-*/
-static int dupedExprNodeSize(Expr *p, int flags){
- int nByte = dupedExprStructSize(p, flags) & 0xfff;
- if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
- nByte += sqlite3Strlen30(p->u.zToken)+1;
- }
- return ROUND8(nByte);
-}
-
-/*
-** Return the number of bytes required to create a duplicate of the
-** expression passed as the first argument. The second argument is a
-** mask containing EXPRDUP_XXX flags.
-**
-** The value returned includes space to create a copy of the Expr struct
-** itself and the buffer referred to by Expr.u.zToken, if any.
-**
-** If the EXPRDUP_REDUCE flag is set, then the return value includes
-** space to duplicate all Expr nodes in the tree formed by Expr.pLeft
-** and Expr.pRight variables (but not for any structures pointed to or
-** descended from the Expr.x.pList or Expr.x.pSelect variables).
-*/
-static int dupedExprSize(Expr *p, int flags){
- int nByte = 0;
- if( p ){
- nByte = dupedExprNodeSize(p, flags);
- if( flags&EXPRDUP_REDUCE ){
- nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
- }
- }
- return nByte;
-}
-
-/*
-** This function is similar to sqlite3ExprDup(), except that if pzBuffer
-** is not NULL then *pzBuffer is assumed to point to a buffer large enough
-** to store the copy of expression p, the copies of p->u.zToken
-** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
-** if any. Before returning, *pzBuffer is set to the first byte passed the
-** portion of the buffer copied into by this function.
-*/
-static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
- Expr *pNew = 0; /* Value to return */
- if( p ){
- const int isReduced = (flags&EXPRDUP_REDUCE);
- u8 *zAlloc;
- u32 staticFlag = 0;
-
- assert( pzBuffer==0 || isReduced );
-
- /* Figure out where to write the new Expr structure. */
- if( pzBuffer ){
- zAlloc = *pzBuffer;
- staticFlag = EP_Static;
- }else{
- zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags));
- }
- pNew = (Expr *)zAlloc;
-
- if( pNew ){
- /* Set nNewSize to the size allocated for the structure pointed to
- ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
- ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
- ** by the copy of the p->u.zToken string (if any).
- */
- const unsigned nStructSize = dupedExprStructSize(p, flags);
- const int nNewSize = nStructSize & 0xfff;
- int nToken;
- if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
- nToken = sqlite3Strlen30(p->u.zToken) + 1;
- }else{
- nToken = 0;
- }
- if( isReduced ){
- assert( ExprHasProperty(p, EP_Reduced)==0 );
- memcpy(zAlloc, p, nNewSize);
- }else{
- int nSize = exprStructSize(p);
- memcpy(zAlloc, p, nSize);
- memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
- }
-
- /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
- pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
- pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
- pNew->flags |= staticFlag;
-
- /* Copy the p->u.zToken string, if any. */
- if( nToken ){
- char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
- memcpy(zToken, p->u.zToken, nToken);
- }
-
- if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
- /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
- if( ExprHasProperty(p, EP_xIsSelect) ){
- pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
- }else{
- pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced);
- }
- }
-
- /* Fill in pNew->pLeft and pNew->pRight. */
- if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){
- zAlloc += dupedExprNodeSize(p, flags);
- if( ExprHasProperty(pNew, EP_Reduced) ){
- pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
- pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
- }
- if( pzBuffer ){
- *pzBuffer = zAlloc;
- }
- }else{
- pNew->flags2 = 0;
- if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
- pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
- pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
- }
- }
-
- }
- }
- return pNew;
-}
-
-/*
-** The following group of routines make deep copies of expressions,
-** expression lists, ID lists, and select statements. The copies can
-** be deleted (by being passed to their respective ...Delete() routines)
-** without effecting the originals.
-**
-** The expression list, ID, and source lists return by sqlite3ExprListDup(),
-** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded
-** by subsequent calls to sqlite*ListAppend() routines.
-**
-** Any tables that the SrcList might point to are not duplicated.
-**
-** The flags parameter contains a combination of the EXPRDUP_XXX flags.
-** If the EXPRDUP_REDUCE flag is set, then the structure returned is a
-** truncated version of the usual Expr structure that will be stored as
-** part of the in-memory representation of the database schema.
-*/
-SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
- return exprDup(db, p, flags, 0);
-}
-SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
- ExprList *pNew;
- struct ExprList_item *pItem, *pOldItem;
- int i;
- if( p==0 ) return 0;
- pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
- if( pNew==0 ) return 0;
- pNew->iECursor = 0;
- pNew->nExpr = i = p->nExpr;
- if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; i<p->nExpr; i+=i){}
- pNew->a = pItem = sqlite3DbMallocRaw(db, i*sizeof(p->a[0]) );
- if( pItem==0 ){
- sqlite3DbFree(db, pNew);
- return 0;
- }
- pOldItem = p->a;
- for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
- Expr *pOldExpr = pOldItem->pExpr;
- pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
- pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
- pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
- pItem->sortOrder = pOldItem->sortOrder;
- pItem->done = 0;
- pItem->iOrderByCol = pOldItem->iOrderByCol;
- pItem->iAlias = pOldItem->iAlias;
- }
- return pNew;
-}
-
-/*
-** If cursors, triggers, views and subqueries are all omitted from
-** the build, then none of the following routines, except for
-** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes
-** called with a NULL argument.
-*/
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
- || !defined(SQLITE_OMIT_SUBQUERY)
-SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
- SrcList *pNew;
- int i;
- int nByte;
- if( p==0 ) return 0;
- nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
- pNew = sqlite3DbMallocRaw(db, nByte );
- if( pNew==0 ) return 0;
- pNew->nSrc = pNew->nAlloc = p->nSrc;
- for(i=0; i<p->nSrc; i++){
- struct SrcList_item *pNewItem = &pNew->a[i];
- struct SrcList_item *pOldItem = &p->a[i];
- Table *pTab;
- pNewItem->pSchema = pOldItem->pSchema;
- pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
- pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
- pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
- pNewItem->jointype = pOldItem->jointype;
- pNewItem->iCursor = pOldItem->iCursor;
- pNewItem->addrFillSub = pOldItem->addrFillSub;
- pNewItem->regReturn = pOldItem->regReturn;
- pNewItem->isCorrelated = pOldItem->isCorrelated;
- pNewItem->viaCoroutine = pOldItem->viaCoroutine;
- pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex);
- pNewItem->notIndexed = pOldItem->notIndexed;
- pNewItem->pIndex = pOldItem->pIndex;
- pTab = pNewItem->pTab = pOldItem->pTab;
- if( pTab ){
- pTab->nRef++;
- }
- pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
- pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
- pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);
- pNewItem->colUsed = pOldItem->colUsed;
- }
- return pNew;
-}
-SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
- IdList *pNew;
- int i;
- if( p==0 ) return 0;
- pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) );
- if( pNew==0 ) return 0;
- pNew->nId = p->nId;
- pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) );
- if( pNew->a==0 ){
- sqlite3DbFree(db, pNew);
- return 0;
- }
- /* Note that because the size of the allocation for p->a[] is not
- ** necessarily a power of two, sqlite3IdListAppend() may not be called
- ** on the duplicate created by this function. */
- for(i=0; i<p->nId; i++){
- struct IdList_item *pNewItem = &pNew->a[i];
- struct IdList_item *pOldItem = &p->a[i];
- pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
- pNewItem->idx = pOldItem->idx;
- }
- return pNew;
-}
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
- Select *pNew, *pPrior;
- if( p==0 ) return 0;
- pNew = sqlite3DbMallocRaw(db, sizeof(*p) );
- if( pNew==0 ) return 0;
- pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
- pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
- pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
- pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
- pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
- pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
- pNew->op = p->op;
- pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags);
- if( pPrior ) pPrior->pNext = pNew;
- pNew->pNext = 0;
- pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
- pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
- pNew->iLimit = 0;
- pNew->iOffset = 0;
- pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
- pNew->pRightmost = 0;
- pNew->addrOpenEphm[0] = -1;
- pNew->addrOpenEphm[1] = -1;
- pNew->addrOpenEphm[2] = -1;
- return pNew;
-}
-#else
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
- assert( p==0 );
- return 0;
-}
-#endif
-
-
-/*
-** Add a new element to the end of an expression list. If pList is
-** initially NULL, then create a new expression list.
-**
-** If a memory allocation error occurs, the entire list is freed and
-** NULL is returned. If non-NULL is returned, then it is guaranteed
-** that the new entry was successfully appended.
-*/
-SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* List to which to append. Might be NULL */
- Expr *pExpr /* Expression to be appended. Might be NULL */
-){
- sqlite3 *db = pParse->db;
- if( pList==0 ){
- pList = sqlite3DbMallocZero(db, sizeof(ExprList) );
- if( pList==0 ){
- goto no_mem;
- }
- pList->a = sqlite3DbMallocRaw(db, sizeof(pList->a[0]));
- if( pList->a==0 ) goto no_mem;
- }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
- struct ExprList_item *a;
- assert( pList->nExpr>0 );
- a = sqlite3DbRealloc(db, pList->a, pList->nExpr*2*sizeof(pList->a[0]));
- if( a==0 ){
- goto no_mem;
- }
- pList->a = a;
- }
- assert( pList->a!=0 );
- if( 1 ){
- struct ExprList_item *pItem = &pList->a[pList->nExpr++];
- memset(pItem, 0, sizeof(*pItem));
- pItem->pExpr = pExpr;
- }
- return pList;
-
-no_mem:
- /* Avoid leaking memory if malloc has failed. */
- sqlite3ExprDelete(db, pExpr);
- sqlite3ExprListDelete(db, pList);
- return 0;
-}
-
-/*
-** Set the ExprList.a[].zName element of the most recently added item
-** on the expression list.
-**
-** pList might be NULL following an OOM error. But pName should never be
-** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
-** is set.
-*/
-SQLITE_PRIVATE void sqlite3ExprListSetName(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* List to which to add the span. */
- Token *pName, /* Name to be added */
- int dequote /* True to cause the name to be dequoted */
-){
- assert( pList!=0 || pParse->db->mallocFailed!=0 );
- if( pList ){
- struct ExprList_item *pItem;
- assert( pList->nExpr>0 );
- pItem = &pList->a[pList->nExpr-1];
- assert( pItem->zName==0 );
- pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
- if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName);
- }
-}
-
-/*
-** Set the ExprList.a[].zSpan element of the most recently added item
-** on the expression list.
-**
-** pList might be NULL following an OOM error. But pSpan should never be
-** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
-** is set.
-*/
-SQLITE_PRIVATE void sqlite3ExprListSetSpan(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* List to which to add the span. */
- ExprSpan *pSpan /* The span to be added */
-){
- sqlite3 *db = pParse->db;
- assert( pList!=0 || db->mallocFailed!=0 );
- if( pList ){
- struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
- assert( pList->nExpr>0 );
- assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr );
- sqlite3DbFree(db, pItem->zSpan);
- pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
- }
-}
-
-/*
-** If the expression list pEList contains more than iLimit elements,
-** leave an error message in pParse.
-*/
-SQLITE_PRIVATE void sqlite3ExprListCheckLength(
- Parse *pParse,
- ExprList *pEList,
- const char *zObject
-){
- int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN];
- testcase( pEList && pEList->nExpr==mx );
- testcase( pEList && pEList->nExpr==mx+1 );
- if( pEList && pEList->nExpr>mx ){
- sqlite3ErrorMsg(pParse, "too many columns in %s", zObject);
- }
-}
-
-/*
-** Delete an entire expression list.
-*/
-SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
- int i;
- struct ExprList_item *pItem;
- if( pList==0 ) return;
- assert( pList->a!=0 || pList->nExpr==0 );
- for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
- sqlite3ExprDelete(db, pItem->pExpr);
- sqlite3DbFree(db, pItem->zName);
- sqlite3DbFree(db, pItem->zSpan);
- }
- sqlite3DbFree(db, pList->a);
- sqlite3DbFree(db, pList);
-}
-
-/*
-** These routines are Walker callbacks. Walker.u.pi is a pointer
-** to an integer. These routines are checking an expression to see
-** if it is a constant. Set *Walker.u.pi to 0 if the expression is
-** not constant.
-**
-** These callback routines are used to implement the following:
-**
-** sqlite3ExprIsConstant()
-** sqlite3ExprIsConstantNotJoin()
-** sqlite3ExprIsConstantOrFunction()
-**
-*/
-static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
-
- /* If pWalker->u.i is 3 then any term of the expression that comes from
- ** the ON or USING clauses of a join disqualifies the expression
- ** from being considered constant. */
- if( pWalker->u.i==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){
- pWalker->u.i = 0;
- return WRC_Abort;
- }
-
- switch( pExpr->op ){
- /* Consider functions to be constant if all their arguments are constant
- ** and pWalker->u.i==2 */
- case TK_FUNCTION:
- if( pWalker->u.i==2 ) return 0;
- /* Fall through */
- case TK_ID:
- case TK_COLUMN:
- case TK_AGG_FUNCTION:
- case TK_AGG_COLUMN:
- testcase( pExpr->op==TK_ID );
- testcase( pExpr->op==TK_COLUMN );
- testcase( pExpr->op==TK_AGG_FUNCTION );
- testcase( pExpr->op==TK_AGG_COLUMN );
- pWalker->u.i = 0;
- return WRC_Abort;
- default:
- testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
- testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
- return WRC_Continue;
- }
-}
-static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- pWalker->u.i = 0;
- return WRC_Abort;
-}
-static int exprIsConst(Expr *p, int initFlag){
- Walker w;
- w.u.i = initFlag;
- w.xExprCallback = exprNodeIsConstant;
- w.xSelectCallback = selectNodeIsConstant;
- sqlite3WalkExpr(&w, p);
- return w.u.i;
-}
-
-/*
-** Walk an expression tree. Return 1 if the expression is constant
-** and 0 if it involves variables or function calls.
-**
-** For the purposes of this function, a double-quoted string (ex: "abc")
-** is considered a variable but a single-quoted string (ex: 'abc') is
-** a constant.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
- return exprIsConst(p, 1);
-}
-
-/*
-** Walk an expression tree. Return 1 if the expression is constant
-** that does no originate from the ON or USING clauses of a join.
-** Return 0 if it involves variables or function calls or terms from
-** an ON or USING clause.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
- return exprIsConst(p, 3);
-}
-
-/*
-** Walk an expression tree. Return 1 if the expression is constant
-** or a function call with constant arguments. Return and 0 if there
-** are any variables.
-**
-** For the purposes of this function, a double-quoted string (ex: "abc")
-** is considered a variable but a single-quoted string (ex: 'abc') is
-** a constant.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p){
- return exprIsConst(p, 2);
-}
-
-/*
-** If the expression p codes a constant integer that is small enough
-** to fit in a 32-bit integer, return 1 and put the value of the integer
-** in *pValue. If the expression is not an integer or if it is too big
-** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
-*/
-SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
- int rc = 0;
-
- /* If an expression is an integer literal that fits in a signed 32-bit
- ** integer, then the EP_IntValue flag will have already been set */
- assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
- || sqlite3GetInt32(p->u.zToken, &rc)==0 );
-
- if( p->flags & EP_IntValue ){
- *pValue = p->u.iValue;
- return 1;
- }
- switch( p->op ){
- case TK_UPLUS: {
- rc = sqlite3ExprIsInteger(p->pLeft, pValue);
- break;
- }
- case TK_UMINUS: {
- int v;
- if( sqlite3ExprIsInteger(p->pLeft, &v) ){
- *pValue = -v;
- rc = 1;
- }
- break;
- }
- default: break;
- }
- return rc;
-}
-
-/*
-** Return FALSE if there is no chance that the expression can be NULL.
-**
-** If the expression might be NULL or if the expression is too complex
-** to tell return TRUE.
-**
-** This routine is used as an optimization, to skip OP_IsNull opcodes
-** when we know that a value cannot be NULL. Hence, a false positive
-** (returning TRUE when in fact the expression can never be NULL) might
-** be a small performance hit but is otherwise harmless. On the other
-** hand, a false negative (returning FALSE when the result could be NULL)
-** will likely result in an incorrect answer. So when in doubt, return
-** TRUE.
-*/
-SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
- u8 op;
- while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
- op = p->op;
- if( op==TK_REGISTER ) op = p->op2;
- switch( op ){
- case TK_INTEGER:
- case TK_STRING:
- case TK_FLOAT:
- case TK_BLOB:
- return 0;
- default:
- return 1;
- }
-}
-
-/*
-** Generate an OP_IsNull instruction that tests register iReg and jumps
-** to location iDest if the value in iReg is NULL. The value in iReg
-** was computed by pExpr. If we can look at pExpr at compile-time and
-** determine that it can never generate a NULL, then the OP_IsNull operation
-** can be omitted.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(
- Vdbe *v, /* The VDBE under construction */
- const Expr *pExpr, /* Only generate OP_IsNull if this expr can be NULL */
- int iReg, /* Test the value in this register for NULL */
- int iDest /* Jump here if the value is null */
-){
- if( sqlite3ExprCanBeNull(pExpr) ){
- sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iDest);
- }
-}
-
-/*
-** Return TRUE if the given expression is a constant which would be
-** unchanged by OP_Affinity with the affinity given in the second
-** argument.
-**
-** This routine is used to determine if the OP_Affinity operation
-** can be omitted. When in doubt return FALSE. A false negative
-** is harmless. A false positive, however, can result in the wrong
-** answer.
-*/
-SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
- u8 op;
- if( aff==SQLITE_AFF_NONE ) return 1;
- while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
- op = p->op;
- if( op==TK_REGISTER ) op = p->op2;
- switch( op ){
- case TK_INTEGER: {
- return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC;
- }
- case TK_FLOAT: {
- return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC;
- }
- case TK_STRING: {
- return aff==SQLITE_AFF_TEXT;
- }
- case TK_BLOB: {
- return 1;
- }
- case TK_COLUMN: {
- assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */
- return p->iColumn<0
- && (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC);
- }
- default: {
- return 0;
- }
- }
-}
-
-/*
-** Return TRUE if the given string is a row-id column name.
-*/
-SQLITE_PRIVATE int sqlite3IsRowid(const char *z){
- if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
- if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
- if( sqlite3StrICmp(z, "OID")==0 ) return 1;
- return 0;
-}
-
-/*
-** Return true if we are able to the IN operator optimization on a
-** query of the form
-**
-** x IN (SELECT ...)
-**
-** Where the SELECT... clause is as specified by the parameter to this
-** routine.
-**
-** The Select object passed in has already been preprocessed and no
-** errors have been found.
-*/
-#ifndef SQLITE_OMIT_SUBQUERY
-static int isCandidateForInOpt(Select *p){
- SrcList *pSrc;
- ExprList *pEList;
- Table *pTab;
- if( p==0 ) return 0; /* right-hand side of IN is SELECT */
- if( p->pPrior ) return 0; /* Not a compound SELECT */
- if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
- testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
- testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
- return 0; /* No DISTINCT keyword and no aggregate functions */
- }
- assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
- if( p->pLimit ) return 0; /* Has no LIMIT clause */
- assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */
- if( p->pWhere ) return 0; /* Has no WHERE clause */
- pSrc = p->pSrc;
- assert( pSrc!=0 );
- if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
- if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */
- pTab = pSrc->a[0].pTab;
- if( NEVER(pTab==0) ) return 0;
- assert( pTab->pSelect==0 ); /* FROM clause is not a view */
- if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
- pEList = p->pEList;
- if( pEList->nExpr!=1 ) return 0; /* One column in the result set */
- if( pEList->a[0].pExpr->op!=TK_COLUMN ) return 0; /* Result is a column */
- return 1;
-}
-#endif /* SQLITE_OMIT_SUBQUERY */
-
-/*
-** Code an OP_Once instruction and allocate space for its flag. Return the
-** address of the new instruction.
-*/
-SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){
- Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
- return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++);
-}
-
-/*
-** This function is used by the implementation of the IN (...) operator.
-** The pX parameter is the expression on the RHS of the IN operator, which
-** might be either a list of expressions or a subquery.
-**
-** The job of this routine is to find or create a b-tree object that can
-** be used either to test for membership in the RHS set or to iterate through
-** all members of the RHS set, skipping duplicates.
-**
-** A cursor is opened on the b-tree object that the RHS of the IN operator
-** and pX->iTable is set to the index of that cursor.
-**
-** The returned value of this function indicates the b-tree type, as follows:
-**
-** IN_INDEX_ROWID - The cursor was opened on a database table.
-** IN_INDEX_INDEX - The cursor was opened on a database index.
-** IN_INDEX_EPH - The cursor was opened on a specially created and
-** populated epheremal table.
-**
-** An existing b-tree might be used if the RHS expression pX is a simple
-** subquery such as:
-**
-** SELECT <column> FROM <table>
-**
-** If the RHS of the IN operator is a list or a more complex subquery, then
-** an ephemeral table might need to be generated from the RHS and then
-** pX->iTable made to point to the ephermeral table instead of an
-** existing table.
-**
-** If the prNotFound parameter is 0, then the b-tree will be used to iterate
-** through the set members, skipping any duplicates. In this case an
-** epheremal table must be used unless the selected <column> is guaranteed
-** to be unique - either because it is an INTEGER PRIMARY KEY or it
-** has a UNIQUE constraint or UNIQUE index.
-**
-** If the prNotFound parameter is not 0, then the b-tree will be used
-** for fast set membership tests. In this case an epheremal table must
-** be used unless <column> is an INTEGER PRIMARY KEY or an index can
-** be found with <column> as its left-most column.
-**
-** When the b-tree is being used for membership tests, the calling function
-** needs to know whether or not the structure contains an SQL NULL
-** value in order to correctly evaluate expressions like "X IN (Y, Z)".
-** If there is any chance that the (...) might contain a NULL value at
-** runtime, then a register is allocated and the register number written
-** to *prNotFound. If there is no chance that the (...) contains a
-** NULL value, then *prNotFound is left unchanged.
-**
-** If a register is allocated and its location stored in *prNotFound, then
-** its initial value is NULL. If the (...) does not remain constant
-** for the duration of the query (i.e. the SELECT within the (...)
-** is a correlated subquery) then the value of the allocated register is
-** reset to NULL each time the subquery is rerun. This allows the
-** caller to use vdbe code equivalent to the following:
-**
-** if( register==NULL ){
-** has_null = <test if data structure contains null>
-** register = 1
-** }
-**
-** in order to avoid running the <test if data structure contains null>
-** test more often than is necessary.
-*/
-#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
- Select *p; /* SELECT to the right of IN operator */
- int eType = 0; /* Type of RHS table. IN_INDEX_* */
- int iTab = pParse->nTab++; /* Cursor of the RHS table */
- int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */
- Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
-
- assert( pX->op==TK_IN );
-
- /* Check to see if an existing table or index can be used to
- ** satisfy the query. This is preferable to generating a new
- ** ephemeral table.
- */
- p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
- if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
- sqlite3 *db = pParse->db; /* Database connection */
- Table *pTab; /* Table <table>. */
- Expr *pExpr; /* Expression <column> */
- int iCol; /* Index of column <column> */
- int iDb; /* Database idx for pTab */
-
- assert( p ); /* Because of isCandidateForInOpt(p) */
- assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
- assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
- assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
- pTab = p->pSrc->a[0].pTab;
- pExpr = p->pEList->a[0].pExpr;
- iCol = pExpr->iColumn;
-
- /* Code an OP_VerifyCookie and OP_TableLock for <table>. */
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
-
- /* This function is only called from two places. In both cases the vdbe
- ** has already been allocated. So assume sqlite3GetVdbe() is always
- ** successful here.
- */
- assert(v);
- if( iCol<0 ){
- int iAddr;
-
- iAddr = sqlite3CodeOnce(pParse);
-
- sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
- eType = IN_INDEX_ROWID;
-
- sqlite3VdbeJumpHere(v, iAddr);
- }else{
- Index *pIdx; /* Iterator variable */
-
- /* The collation sequence used by the comparison. If an index is to
- ** be used in place of a temp-table, it must be ordered according
- ** to this collation sequence. */
- CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr);
-
- /* Check that the affinity that will be used to perform the
- ** comparison is the same as the affinity of the column. If
- ** it is not, it is not possible to use any index.
- */
- int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity);
-
- for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
- if( (pIdx->aiColumn[0]==iCol)
- && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
- && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
- ){
- int iAddr;
- char *pKey;
-
- pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
- iAddr = sqlite3CodeOnce(pParse);
-
- sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
- pKey,P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIdx->zName));
- eType = IN_INDEX_INDEX;
-
- sqlite3VdbeJumpHere(v, iAddr);
- if( prNotFound && !pTab->aCol[iCol].notNull ){
- *prNotFound = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
- }
- }
- }
- }
- }
-
- if( eType==0 ){
- /* Could not found an existing table or index to use as the RHS b-tree.
- ** We will have to generate an ephemeral table to do the job.
- */
- double savedNQueryLoop = pParse->nQueryLoop;
- int rMayHaveNull = 0;
- eType = IN_INDEX_EPH;
- if( prNotFound ){
- *prNotFound = rMayHaveNull = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
- }else{
- testcase( pParse->nQueryLoop>(double)1 );
- pParse->nQueryLoop = (double)1;
- if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
- eType = IN_INDEX_ROWID;
- }
- }
- sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
- pParse->nQueryLoop = savedNQueryLoop;
- }else{
- pX->iTable = iTab;
- }
- return eType;
-}
-#endif
-
-/*
-** Generate code for scalar subqueries used as a subquery expression, EXISTS,
-** or IN operators. Examples:
-**
-** (SELECT a FROM b) -- subquery
-** EXISTS (SELECT a FROM b) -- EXISTS subquery
-** x IN (4,5,11) -- IN operator with list on right-hand side
-** x IN (SELECT a FROM b) -- IN operator with subquery on the right
-**
-** The pExpr parameter describes the expression that contains the IN
-** operator or subquery.
-**
-** If parameter isRowid is non-zero, then expression pExpr is guaranteed
-** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference
-** to some integer key column of a table B-Tree. In this case, use an
-** intkey B-Tree to store the set of IN(...) values instead of the usual
-** (slower) variable length keys B-Tree.
-**
-** If rMayHaveNull is non-zero, that means that the operation is an IN
-** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
-** Furthermore, the IN is in a WHERE clause and that we really want
-** to iterate over the RHS of the IN operator in order to quickly locate
-** all corresponding LHS elements. All this routine does is initialize
-** the register given by rMayHaveNull to NULL. Calling routines will take
-** care of changing this register value to non-NULL if the RHS is NULL-free.
-**
-** If rMayHaveNull is zero, that means that the subquery is being used
-** for membership testing only. There is no need to initialize any
-** registers to indicate the presense or absence of NULLs on the RHS.
-**
-** For a SELECT or EXISTS operator, return the register that holds the
-** result. For IN operators or if an error occurs, the return value is 0.
-*/
-#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3CodeSubselect(
- Parse *pParse, /* Parsing context */
- Expr *pExpr, /* The IN, SELECT, or EXISTS operator */
- int rMayHaveNull, /* Register that records whether NULLs exist in RHS */
- int isRowid /* If true, LHS of IN operator is a rowid */
-){
- int testAddr = -1; /* One-time test address */
- int rReg = 0; /* Register storing resulting */
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return 0;
- sqlite3ExprCachePush(pParse);
-
- /* This code must be run in its entirety every time it is encountered
- ** if any of the following is true:
- **
- ** * The right-hand side is a correlated subquery
- ** * The right-hand side is an expression list containing variables
- ** * We are inside a trigger
- **
- ** If all of the above are false, then we can run this code just once
- ** save the results, and reuse the same result on subsequent invocations.
- */
- if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){
- testAddr = sqlite3CodeOnce(pParse);
- }
-
-#ifndef SQLITE_OMIT_EXPLAIN
- if( pParse->explain==2 ){
- char *zMsg = sqlite3MPrintf(
- pParse->db, "EXECUTE %s%s SUBQUERY %d", testAddr>=0?"":"CORRELATED ",
- pExpr->op==TK_IN?"LIST":"SCALAR", pParse->iNextSelectId
- );
- sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
- }
-#endif
-
- switch( pExpr->op ){
- case TK_IN: {
- char affinity; /* Affinity of the LHS of the IN */
- KeyInfo keyInfo; /* Keyinfo for the generated table */
- static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */
- int addr; /* Address of OP_OpenEphemeral instruction */
- Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
-
- if( rMayHaveNull ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
- }
-
- affinity = sqlite3ExprAffinity(pLeft);
-
- /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
- ** expression it is handled the same way. An ephemeral table is
- ** filled with single-field index keys representing the results
- ** from the SELECT or the <exprlist>.
- **
- ** If the 'x' expression is a column value, or the SELECT...
- ** statement returns a column value, then the affinity of that
- ** column is used to build the index keys. If both 'x' and the
- ** SELECT... statement are columns, then numeric affinity is used
- ** if either column has NUMERIC or INTEGER affinity. If neither
- ** 'x' nor the SELECT... statement are columns, then numeric affinity
- ** is used.
- */
- pExpr->iTable = pParse->nTab++;
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
- if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
- memset(&keyInfo, 0, sizeof(keyInfo));
- keyInfo.nField = 1;
- keyInfo.aSortOrder = &sortOrder;
-
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- /* Case 1: expr IN (SELECT ...)
- **
- ** Generate code to write the results of the select into the temporary
- ** table allocated and opened above.
- */
- SelectDest dest;
- ExprList *pEList;
-
- assert( !isRowid );
- sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
- dest.affSdst = (u8)affinity;
- assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
- pExpr->x.pSelect->iLimit = 0;
- if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
- return 0;
- }
- pEList = pExpr->x.pSelect->pEList;
- if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
- keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
- pEList->a[0].pExpr);
- }
- }else if( ALWAYS(pExpr->x.pList!=0) ){
- /* Case 2: expr IN (exprlist)
- **
- ** For each expression, build an index key from the evaluation and
- ** store it in the temporary table. If <expr> is a column, then use
- ** that columns affinity when building index keys. If <expr> is not
- ** a column, use numeric affinity.
- */
- int i;
- ExprList *pList = pExpr->x.pList;
- struct ExprList_item *pItem;
- int r1, r2, r3;
-
- if( !affinity ){
- affinity = SQLITE_AFF_NONE;
- }
- keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
- keyInfo.aSortOrder = &sortOrder;
-
- /* Loop through each expression in <exprlist>. */
- r1 = sqlite3GetTempReg(pParse);
- r2 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
- for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
- Expr *pE2 = pItem->pExpr;
- int iValToIns;
-
- /* If the expression is not constant then we will need to
- ** disable the test that was generated above that makes sure
- ** this code only executes once. Because for a non-constant
- ** expression we need to rerun this code each time.
- */
- if( testAddr>=0 && !sqlite3ExprIsConstant(pE2) ){
- sqlite3VdbeChangeToNoop(v, testAddr);
- testAddr = -1;
- }
-
- /* Evaluate the expression and insert it into the temp table */
- if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
- sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
- }else{
- r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
- if( isRowid ){
- sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
- sqlite3VdbeCurrentAddr(v)+2);
- sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
- }else{
- sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
- sqlite3ExprCacheAffinityChange(pParse, r3, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
- }
- }
- }
- sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ReleaseTempReg(pParse, r2);
- }
- if( !isRowid ){
- sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
- }
- break;
- }
-
- case TK_EXISTS:
- case TK_SELECT:
- default: {
- /* If this has to be a scalar SELECT. Generate code to put the
- ** value of this select in a memory cell and record the number
- ** of the memory cell in iColumn. If this is an EXISTS, write
- ** an integer 0 (not exists) or 1 (exists) into a memory cell
- ** and record that memory cell in iColumn.
- */
- Select *pSel; /* SELECT statement to encode */
- SelectDest dest; /* How to deal with SELECt result */
-
- testcase( pExpr->op==TK_EXISTS );
- testcase( pExpr->op==TK_SELECT );
- assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
-
- assert( ExprHasProperty(pExpr, EP_xIsSelect) );
- pSel = pExpr->x.pSelect;
- sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
- if( pExpr->op==TK_SELECT ){
- dest.eDest = SRT_Mem;
- sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
- VdbeComment((v, "Init subquery result"));
- }else{
- dest.eDest = SRT_Exists;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
- VdbeComment((v, "Init EXISTS result"));
- }
- sqlite3ExprDelete(pParse->db, pSel->pLimit);
- pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
- &sqlite3IntTokens[1]);
- pSel->iLimit = 0;
- if( sqlite3Select(pParse, pSel, &dest) ){
- return 0;
- }
- rReg = dest.iSDParm;
- ExprSetIrreducible(pExpr);
- break;
- }
- }
-
- if( testAddr>=0 ){
- sqlite3VdbeJumpHere(v, testAddr);
- }
- sqlite3ExprCachePop(pParse, 1);
-
- return rReg;
-}
-#endif /* SQLITE_OMIT_SUBQUERY */
-
-#ifndef SQLITE_OMIT_SUBQUERY
-/*
-** Generate code for an IN expression.
-**
-** x IN (SELECT ...)
-** x IN (value, value, ...)
-**
-** The left-hand side (LHS) is a scalar expression. The right-hand side (RHS)
-** is an array of zero or more values. The expression is true if the LHS is
-** contained within the RHS. The value of the expression is unknown (NULL)
-** if the LHS is NULL or if the LHS is not contained within the RHS and the
-** RHS contains one or more NULL values.
-**
-** This routine generates code will jump to destIfFalse if the LHS is not
-** contained within the RHS. If due to NULLs we cannot determine if the LHS
-** is contained in the RHS then jump to destIfNull. If the LHS is contained
-** within the RHS then fall through.
-*/
-static void sqlite3ExprCodeIN(
- Parse *pParse, /* Parsing and code generating context */
- Expr *pExpr, /* The IN expression */
- int destIfFalse, /* Jump here if LHS is not contained in the RHS */
- int destIfNull /* Jump here if the results are unknown due to NULLs */
-){
- int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */
- char affinity; /* Comparison affinity to use */
- int eType; /* Type of the RHS */
- int r1; /* Temporary use register */
- Vdbe *v; /* Statement under construction */
-
- /* Compute the RHS. After this step, the table with cursor
- ** pExpr->iTable will contains the values that make up the RHS.
- */
- v = pParse->pVdbe;
- assert( v!=0 ); /* OOM detected prior to this routine */
- VdbeNoopComment((v, "begin IN expr"));
- eType = sqlite3FindInIndex(pParse, pExpr, &rRhsHasNull);
-
- /* Figure out the affinity to use to create a key from the results
- ** of the expression. affinityStr stores a static string suitable for
- ** P4 of OP_MakeRecord.
- */
- affinity = comparisonAffinity(pExpr);
-
- /* Code the LHS, the <expr> from "<expr> IN (...)".
- */
- sqlite3ExprCachePush(pParse);
- r1 = sqlite3GetTempReg(pParse);
- sqlite3ExprCode(pParse, pExpr->pLeft, r1);
-
- /* If the LHS is NULL, then the result is either false or NULL depending
- ** on whether the RHS is empty or not, respectively.
- */
- if( destIfNull==destIfFalse ){
- /* Shortcut for the common case where the false and NULL outcomes are
- ** the same. */
- sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull);
- }else{
- int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1);
- sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
- sqlite3VdbeJumpHere(v, addr1);
- }
-
- if( eType==IN_INDEX_ROWID ){
- /* In this case, the RHS is the ROWID of table b-tree
- */
- sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse);
- sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
- }else{
- /* In this case, the RHS is an index b-tree.
- */
- sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1);
-
- /* If the set membership test fails, then the result of the
- ** "x IN (...)" expression must be either 0 or NULL. If the set
- ** contains no NULL values, then the result is 0. If the set
- ** contains one or more NULL values, then the result of the
- ** expression is also NULL.
- */
- if( rRhsHasNull==0 || destIfFalse==destIfNull ){
- /* This branch runs if it is known at compile time that the RHS
- ** cannot contain NULL values. This happens as the result
- ** of a "NOT NULL" constraint in the database schema.
- **
- ** Also run this branch if NULL is equivalent to FALSE
- ** for this particular IN operator.
- */
- sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
-
- }else{
- /* In this branch, the RHS of the IN might contain a NULL and
- ** the presence of a NULL on the RHS makes a difference in the
- ** outcome.
- */
- int j1, j2, j3;
-
- /* First check to see if the LHS is contained in the RHS. If so,
- ** then the presence of NULLs in the RHS does not matter, so jump
- ** over all of the code that follows.
- */
- j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
-
- /* Here we begin generating code that runs if the LHS is not
- ** contained within the RHS. Generate additional code that
- ** tests the RHS for NULLs. If the RHS contains a NULL then
- ** jump to destIfNull. If there are no NULLs in the RHS then
- ** jump to destIfFalse.
- */
- j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull);
- j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull);
- sqlite3VdbeJumpHere(v, j3);
- sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1);
- sqlite3VdbeJumpHere(v, j2);
-
- /* Jump to the appropriate target depending on whether or not
- ** the RHS contains a NULL
- */
- sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
-
- /* The OP_Found at the top of this branch jumps here when true,
- ** causing the overall IN expression evaluation to fall through.
- */
- sqlite3VdbeJumpHere(v, j1);
- }
- }
- sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ExprCachePop(pParse, 1);
- VdbeComment((v, "end IN expr"));
-}
-#endif /* SQLITE_OMIT_SUBQUERY */
-
-/*
-** Duplicate an 8-byte value
-*/
-static char *dup8bytes(Vdbe *v, const char *in){
- char *out = sqlite3DbMallocRaw(sqlite3VdbeDb(v), 8);
- if( out ){
- memcpy(out, in, 8);
- }
- return out;
-}
-
-#ifndef SQLITE_OMIT_FLOATING_POINT
-/*
-** Generate an instruction that will put the floating point
-** value described by z[0..n-1] into register iMem.
-**
-** The z[] string will probably not be zero-terminated. But the
-** z[n] character is guaranteed to be something that does not look
-** like the continuation of the number.
-*/
-static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
- if( ALWAYS(z!=0) ){
- double value;
- char *zV;
- sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
- assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */
- if( negateFlag ) value = -value;
- zV = dup8bytes(v, (char*)&value);
- sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
- }
-}
-#endif
-
-
-/*
-** Generate an instruction that will put the integer describe by
-** text z[0..n-1] into register iMem.
-**
-** Expr.u.zToken is always UTF8 and zero-terminated.
-*/
-static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
- Vdbe *v = pParse->pVdbe;
- if( pExpr->flags & EP_IntValue ){
- int i = pExpr->u.iValue;
- assert( i>=0 );
- if( negFlag ) i = -i;
- sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
- }else{
- int c;
- i64 value;
- const char *z = pExpr->u.zToken;
- assert( z!=0 );
- c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
- if( c==0 || (c==2 && negFlag) ){
- char *zV;
- if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
- zV = dup8bytes(v, (char*)&value);
- sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
- }else{
-#ifdef SQLITE_OMIT_FLOATING_POINT
- sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
-#else
- codeReal(v, z, negFlag, iMem);
-#endif
- }
- }
-}
-
-/*
-** Clear a cache entry.
-*/
-static void cacheEntryClear(Parse *pParse, struct yColCache *p){
- if( p->tempReg ){
- if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
- pParse->aTempReg[pParse->nTempReg++] = p->iReg;
- }
- p->tempReg = 0;
- }
-}
-
-
-/*
-** Record in the column cache that a particular column from a
-** particular table is stored in a particular register.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
- int i;
- int minLru;
- int idxLru;
- struct yColCache *p;
-
- assert( iReg>0 ); /* Register numbers are always positive */
- assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */
-
- /* The SQLITE_ColumnCache flag disables the column cache. This is used
- ** for testing only - to verify that SQLite always gets the same answer
- ** with and without the column cache.
- */
- if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return;
-
- /* First replace any existing entry.
- **
- ** Actually, the way the column cache is currently used, we are guaranteed
- ** that the object will never already be in cache. Verify this guarantee.
- */
-#ifndef NDEBUG
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol );
- }
-#endif
-
- /* Find an empty slot and replace it */
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg==0 ){
- p->iLevel = pParse->iCacheLevel;
- p->iTable = iTab;
- p->iColumn = iCol;
- p->iReg = iReg;
- p->tempReg = 0;
- p->lru = pParse->iCacheCnt++;
- return;
- }
- }
-
- /* Replace the last recently used */
- minLru = 0x7fffffff;
- idxLru = -1;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->lru<minLru ){
- idxLru = i;
- minLru = p->lru;
- }
- }
- if( ALWAYS(idxLru>=0) ){
- p = &pParse->aColCache[idxLru];
- p->iLevel = pParse->iCacheLevel;
- p->iTable = iTab;
- p->iColumn = iCol;
- p->iReg = iReg;
- p->tempReg = 0;
- p->lru = pParse->iCacheCnt++;
- return;
- }
-}
-
-/*
-** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
-** Purge the range of registers from the column cache.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
- int i;
- int iLast = iReg + nReg - 1;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- int r = p->iReg;
- if( r>=iReg && r<=iLast ){
- cacheEntryClear(pParse, p);
- p->iReg = 0;
- }
- }
-}
-
-/*
-** Remember the current column cache context. Any new entries added
-** added to the column cache after this call are removed when the
-** corresponding pop occurs.
-*/
-SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){
- pParse->iCacheLevel++;
-}
-
-/*
-** Remove from the column cache any entries that were added since the
-** the previous N Push operations. In other words, restore the cache
-** to the state it was in N Pushes ago.
-*/
-SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse, int N){
- int i;
- struct yColCache *p;
- assert( N>0 );
- assert( pParse->iCacheLevel>=N );
- pParse->iCacheLevel -= N;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg && p->iLevel>pParse->iCacheLevel ){
- cacheEntryClear(pParse, p);
- p->iReg = 0;
- }
- }
-}
-
-/*
-** When a cached column is reused, make sure that its register is
-** no longer available as a temp register. ticket #3879: that same
-** register might be in the cache in multiple places, so be sure to
-** get them all.
-*/
-static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg==iReg ){
- p->tempReg = 0;
- }
- }
-}
-
-/*
-** Generate code to extract the value of the iCol-th column of a table.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
- Vdbe *v, /* The VDBE under construction */
- Table *pTab, /* The table containing the value */
- int iTabCur, /* The cursor for this table */
- int iCol, /* Index of the column to extract */
- int regOut /* Extract the valud into this register */
-){
- if( iCol<0 || iCol==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
- }else{
- int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
- sqlite3VdbeAddOp3(v, op, iTabCur, iCol, regOut);
- }
- if( iCol>=0 ){
- sqlite3ColumnDefault(v, pTab, iCol, regOut);
- }
-}
-
-/*
-** Generate code that will extract the iColumn-th column from
-** table pTab and store the column value in a register. An effort
-** is made to store the column value in register iReg, but this is
-** not guaranteed. The location of the column value is returned.
-**
-** There must be an open cursor to pTab in iTable when this routine
-** is called. If iColumn<0 then code is generated that extracts the rowid.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
- Parse *pParse, /* Parsing and code generating context */
- Table *pTab, /* Description of the table we are reading from */
- int iColumn, /* Index of the table column */
- int iTable, /* The cursor pointing to the table */
- int iReg, /* Store results here */
- u8 p5 /* P5 value for OP_Column */
-){
- Vdbe *v = pParse->pVdbe;
- int i;
- struct yColCache *p;
-
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){
- p->lru = pParse->iCacheCnt++;
- sqlite3ExprCachePinRegister(pParse, p->iReg);
- return p->iReg;
- }
- }
- assert( v!=0 );
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
- if( p5 ){
- sqlite3VdbeChangeP5(v, p5);
- }else{
- sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg);
- }
- return iReg;
-}
-
-/*
-** Clear all column cache entries.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
- int i;
- struct yColCache *p;
-
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg ){
- cacheEntryClear(pParse, p);
- p->iReg = 0;
- }
- }
-}
-
-/*
-** Record the fact that an affinity change has occurred on iCount
-** registers starting with iStart.
-*/
-SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
- sqlite3ExprCacheRemove(pParse, iStart, iCount);
-}
-
-/*
-** Generate code to move content from registers iFrom...iFrom+nReg-1
-** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
- int i;
- struct yColCache *p;
- assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
- sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg-1);
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- int x = p->iReg;
- if( x>=iFrom && x<iFrom+nReg ){
- p->iReg += iTo-iFrom;
- }
- }
-}
-
-#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
-/*
-** Return true if any register in the range iFrom..iTo (inclusive)
-** is used as part of the column cache.
-**
-** This routine is used within assert() and testcase() macros only
-** and does not appear in a normal build.
-*/
-static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- int r = p->iReg;
- if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/
- }
- return 0;
-}
-#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
-
-/*
-** Generate code into the current Vdbe to evaluate the given
-** expression. Attempt to store the results in register "target".
-** Return the register where results are stored.
-**
-** With this routine, there is no guarantee that results will
-** be stored in target. The result might be stored in some other
-** register if it is convenient to do so. The calling function
-** must check the return code and move the results to the desired
-** register.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
- Vdbe *v = pParse->pVdbe; /* The VM under construction */
- int op; /* The opcode being coded */
- int inReg = target; /* Results stored in register inReg */
- int regFree1 = 0; /* If non-zero free this temporary register */
- int regFree2 = 0; /* If non-zero free this temporary register */
- int r1, r2, r3, r4; /* Various register numbers */
- sqlite3 *db = pParse->db; /* The database connection */
-
- assert( target>0 && target<=pParse->nMem );
- if( v==0 ){
- assert( pParse->db->mallocFailed );
- return 0;
- }
-
- if( pExpr==0 ){
- op = TK_NULL;
- }else{
- op = pExpr->op;
- }
- switch( op ){
- case TK_AGG_COLUMN: {
- AggInfo *pAggInfo = pExpr->pAggInfo;
- struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
- if( !pAggInfo->directMode ){
- assert( pCol->iMem>0 );
- inReg = pCol->iMem;
- break;
- }else if( pAggInfo->useSortingIdx ){
- sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
- pCol->iSorterColumn, target);
- break;
- }
- /* Otherwise, fall thru into the TK_COLUMN case */
- }
- case TK_COLUMN: {
- if( pExpr->iTable<0 ){
- /* This only happens when coding check constraints */
- assert( pParse->ckBase>0 );
- inReg = pExpr->iColumn + pParse->ckBase;
- }else{
- inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
- pExpr->iColumn, pExpr->iTable, target,
- pExpr->op2);
- }
- break;
- }
- case TK_INTEGER: {
- codeInteger(pParse, pExpr, 0, target);
- break;
- }
-#ifndef SQLITE_OMIT_FLOATING_POINT
- case TK_FLOAT: {
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- codeReal(v, pExpr->u.zToken, 0, target);
- break;
- }
-#endif
- case TK_STRING: {
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
- break;
- }
- case TK_NULL: {
- sqlite3VdbeAddOp2(v, OP_Null, 0, target);
- break;
- }
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- case TK_BLOB: {
- int n;
- const char *z;
- char *zBlob;
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
- assert( pExpr->u.zToken[1]=='\'' );
- z = &pExpr->u.zToken[2];
- n = sqlite3Strlen30(z) - 1;
- assert( z[n]=='\'' );
- zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
- sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
- break;
- }
-#endif
- case TK_VARIABLE: {
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- assert( pExpr->u.zToken!=0 );
- assert( pExpr->u.zToken[0]!=0 );
- sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
- if( pExpr->u.zToken[1]!=0 ){
- assert( pExpr->u.zToken[0]=='?'
- || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 );
- sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC);
- }
- break;
- }
- case TK_REGISTER: {
- inReg = pExpr->iTable;
- break;
- }
- case TK_AS: {
- inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- break;
- }
-#ifndef SQLITE_OMIT_CAST
- case TK_CAST: {
- /* Expressions of the form: CAST(pLeft AS token) */
- int aff, to_op;
- inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- aff = sqlite3AffinityType(pExpr->u.zToken);
- to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
- assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT );
- assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE );
- assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
- assert( to_op==OP_ToInt || aff!=SQLITE_AFF_INTEGER );
- assert( to_op==OP_ToReal || aff!=SQLITE_AFF_REAL );
- testcase( to_op==OP_ToText );
- testcase( to_op==OP_ToBlob );
- testcase( to_op==OP_ToNumeric );
- testcase( to_op==OP_ToInt );
- testcase( to_op==OP_ToReal );
- if( inReg!=target ){
- sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
- inReg = target;
- }
- sqlite3VdbeAddOp1(v, to_op, inReg);
- testcase( usedAsColumnCache(pParse, inReg, inReg) );
- sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
- break;
- }
-#endif /* SQLITE_OMIT_CAST */
- case TK_LT:
- case TK_LE:
- case TK_GT:
- case TK_GE:
- case TK_NE:
- case TK_EQ: {
- assert( TK_LT==OP_Lt );
- assert( TK_LE==OP_Le );
- assert( TK_GT==OP_Gt );
- assert( TK_GE==OP_Ge );
- assert( TK_EQ==OP_Eq );
- assert( TK_NE==OP_Ne );
- testcase( op==TK_LT );
- testcase( op==TK_LE );
- testcase( op==TK_GT );
- testcase( op==TK_GE );
- testcase( op==TK_EQ );
- testcase( op==TK_NE );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, inReg, SQLITE_STOREP2);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_IS:
- case TK_ISNOT: {
- testcase( op==TK_IS );
- testcase( op==TK_ISNOT );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- op = (op==TK_IS) ? TK_EQ : TK_NE;
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_AND:
- case TK_OR:
- case TK_PLUS:
- case TK_STAR:
- case TK_MINUS:
- case TK_REM:
- case TK_BITAND:
- case TK_BITOR:
- case TK_SLASH:
- case TK_LSHIFT:
- case TK_RSHIFT:
- case TK_CONCAT: {
- assert( TK_AND==OP_And );
- assert( TK_OR==OP_Or );
- assert( TK_PLUS==OP_Add );
- assert( TK_MINUS==OP_Subtract );
- assert( TK_REM==OP_Remainder );
- assert( TK_BITAND==OP_BitAnd );
- assert( TK_BITOR==OP_BitOr );
- assert( TK_SLASH==OP_Divide );
- assert( TK_LSHIFT==OP_ShiftLeft );
- assert( TK_RSHIFT==OP_ShiftRight );
- assert( TK_CONCAT==OP_Concat );
- testcase( op==TK_AND );
- testcase( op==TK_OR );
- testcase( op==TK_PLUS );
- testcase( op==TK_MINUS );
- testcase( op==TK_REM );
- testcase( op==TK_BITAND );
- testcase( op==TK_BITOR );
- testcase( op==TK_SLASH );
- testcase( op==TK_LSHIFT );
- testcase( op==TK_RSHIFT );
- testcase( op==TK_CONCAT );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- sqlite3VdbeAddOp3(v, op, r2, r1, target);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_UMINUS: {
- Expr *pLeft = pExpr->pLeft;
- assert( pLeft );
- if( pLeft->op==TK_INTEGER ){
- codeInteger(pParse, pLeft, 1, target);
-#ifndef SQLITE_OMIT_FLOATING_POINT
- }else if( pLeft->op==TK_FLOAT ){
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- codeReal(v, pLeft->u.zToken, 1, target);
-#endif
- }else{
- regFree1 = r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, r1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree2);
- sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
- testcase( regFree2==0 );
- }
- inReg = target;
- break;
- }
- case TK_BITNOT:
- case TK_NOT: {
- assert( TK_BITNOT==OP_BitNot );
- assert( TK_NOT==OP_Not );
- testcase( op==TK_BITNOT );
- testcase( op==TK_NOT );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- testcase( regFree1==0 );
- inReg = target;
- sqlite3VdbeAddOp2(v, op, r1, inReg);
- break;
- }
- case TK_ISNULL:
- case TK_NOTNULL: {
- int addr;
- assert( TK_ISNULL==OP_IsNull );
- assert( TK_NOTNULL==OP_NotNull );
- testcase( op==TK_ISNULL );
- testcase( op==TK_NOTNULL );
- sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- testcase( regFree1==0 );
- addr = sqlite3VdbeAddOp1(v, op, r1);
- sqlite3VdbeAddOp2(v, OP_AddImm, target, -1);
- sqlite3VdbeJumpHere(v, addr);
- break;
- }
- case TK_AGG_FUNCTION: {
- AggInfo *pInfo = pExpr->pAggInfo;
- if( pInfo==0 ){
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
- }else{
- inReg = pInfo->aFunc[pExpr->iAgg].iMem;
- }
- break;
- }
- case TK_CONST_FUNC:
- case TK_FUNCTION: {
- ExprList *pFarg; /* List of function arguments */
- int nFarg; /* Number of function arguments */
- FuncDef *pDef; /* The function definition object */
- int nId; /* Length of the function name in bytes */
- const char *zId; /* The function name */
- int constMask = 0; /* Mask of function arguments that are constant */
- int i; /* Loop counter */
- u8 enc = ENC(db); /* The text encoding used by this database */
- CollSeq *pColl = 0; /* A collating sequence */
-
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- testcase( op==TK_CONST_FUNC );
- testcase( op==TK_FUNCTION );
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
- pFarg = 0;
- }else{
- pFarg = pExpr->x.pList;
- }
- nFarg = pFarg ? pFarg->nExpr : 0;
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- zId = pExpr->u.zToken;
- nId = sqlite3Strlen30(zId);
- pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
- if( pDef==0 ){
- sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
- break;
- }
-
- /* Attempt a direct implementation of the built-in COALESCE() and
- ** IFNULL() functions. This avoids unnecessary evalation of
- ** arguments past the first non-NULL argument.
- */
- if( pDef->flags & SQLITE_FUNC_COALESCE ){
- int endCoalesce = sqlite3VdbeMakeLabel(v);
- assert( nFarg>=2 );
- sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
- for(i=1; i<nFarg; i++){
- sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
- sqlite3ExprCacheRemove(pParse, target, 1);
- sqlite3ExprCachePush(pParse);
- sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
- sqlite3ExprCachePop(pParse, 1);
- }
- sqlite3VdbeResolveLabel(v, endCoalesce);
- break;
- }
-
-
- if( pFarg ){
- r1 = sqlite3GetTempRange(pParse, nFarg);
-
- /* For length() and typeof() functions with a column argument,
- ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG
- ** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data
- ** loading.
- */
- if( (pDef->flags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){
- u8 exprOp;
- assert( nFarg==1 );
- assert( pFarg->a[0].pExpr!=0 );
- exprOp = pFarg->a[0].pExpr->op;
- if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){
- assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG );
- assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG );
- testcase( pDef->flags==SQLITE_FUNC_LENGTH );
- pFarg->a[0].pExpr->op2 = pDef->flags;
- }
- }
-
- sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */
- sqlite3ExprCodeExprList(pParse, pFarg, r1, 1);
- sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */
- }else{
- r1 = 0;
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Possibly overload the function if the first argument is
- ** a virtual table column.
- **
- ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the
- ** second argument, not the first, as the argument to test to
- ** see if it is a column in a virtual table. This is done because
- ** the left operand of infix functions (the operand we want to
- ** control overloading) ends up as the second argument to the
- ** function. The expression "A glob B" is equivalent to
- ** "glob(B,A). We want to use the A in "A glob B" to test
- ** for function overloading. But we use the B term in "glob(B,A)".
- */
- if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){
- pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr);
- }else if( nFarg>0 ){
- pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
- }
-#endif
- for(i=0; i<nFarg; i++){
- if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
- constMask |= (1<<i);
- }
- if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
- pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
- }
- }
- if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){
- if( !pColl ) pColl = db->pDfltColl;
- sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
- }
- sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target,
- (char*)pDef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, (u8)nFarg);
- if( nFarg ){
- sqlite3ReleaseTempRange(pParse, r1, nFarg);
- }
- break;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_EXISTS:
- case TK_SELECT: {
- testcase( op==TK_EXISTS );
- testcase( op==TK_SELECT );
- inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
- break;
- }
- case TK_IN: {
- int destIfFalse = sqlite3VdbeMakeLabel(v);
- int destIfNull = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_Null, 0, target);
- sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
- sqlite3VdbeResolveLabel(v, destIfFalse);
- sqlite3VdbeAddOp2(v, OP_AddImm, target, 0);
- sqlite3VdbeResolveLabel(v, destIfNull);
- break;
- }
-#endif /* SQLITE_OMIT_SUBQUERY */
-
-
- /*
- ** x BETWEEN y AND z
- **
- ** This is equivalent to
- **
- ** x>=y AND x<=z
- **
- ** X is stored in pExpr->pLeft.
- ** Y is stored in pExpr->pList->a[0].pExpr.
- ** Z is stored in pExpr->pList->a[1].pExpr.
- */
- case TK_BETWEEN: {
- Expr *pLeft = pExpr->pLeft;
- struct ExprList_item *pLItem = pExpr->x.pList->a;
- Expr *pRight = pLItem->pExpr;
-
- r1 = sqlite3ExprCodeTemp(pParse, pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pRight, &regFree2);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- r3 = sqlite3GetTempReg(pParse);
- r4 = sqlite3GetTempReg(pParse);
- codeCompare(pParse, pLeft, pRight, OP_Ge,
- r1, r2, r3, SQLITE_STOREP2);
- pLItem++;
- pRight = pLItem->pExpr;
- sqlite3ReleaseTempReg(pParse, regFree2);
- r2 = sqlite3ExprCodeTemp(pParse, pRight, &regFree2);
- testcase( regFree2==0 );
- codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
- sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
- sqlite3ReleaseTempReg(pParse, r3);
- sqlite3ReleaseTempReg(pParse, r4);
- break;
- }
- case TK_COLLATE:
- case TK_UPLUS: {
- inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- break;
- }
-
- case TK_TRIGGER: {
- /* If the opcode is TK_TRIGGER, then the expression is a reference
- ** to a column in the new.* or old.* pseudo-tables available to
- ** trigger programs. In this case Expr.iTable is set to 1 for the
- ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
- ** is set to the column of the pseudo-table to read, or to -1 to
- ** read the rowid field.
- **
- ** The expression is implemented using an OP_Param opcode. The p1
- ** parameter is set to 0 for an old.rowid reference, or to (i+1)
- ** to reference another column of the old.* pseudo-table, where
- ** i is the index of the column. For a new.rowid reference, p1 is
- ** set to (n+1), where n is the number of columns in each pseudo-table.
- ** For a reference to any other column in the new.* pseudo-table, p1
- ** is set to (n+2+i), where n and i are as defined previously. For
- ** example, if the table on which triggers are being fired is
- ** declared as:
- **
- ** CREATE TABLE t1(a, b);
- **
- ** Then p1 is interpreted as follows:
- **
- ** p1==0 -> old.rowid p1==3 -> new.rowid
- ** p1==1 -> old.a p1==4 -> new.a
- ** p1==2 -> old.b p1==5 -> new.b
- */
- Table *pTab = pExpr->pTab;
- int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
-
- assert( pExpr->iTable==0 || pExpr->iTable==1 );
- assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
- assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
- assert( p1>=0 && p1<(pTab->nCol*2+2) );
-
- sqlite3VdbeAddOp2(v, OP_Param, p1, target);
- VdbeComment((v, "%s.%s -> $%d",
- (pExpr->iTable ? "new" : "old"),
- (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName),
- target
- ));
-
-#ifndef SQLITE_OMIT_FLOATING_POINT
- /* If the column has REAL affinity, it may currently be stored as an
- ** integer. Use OP_RealAffinity to make sure it is really real. */
- if( pExpr->iColumn>=0
- && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
- ){
- sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
- }
-#endif
- break;
- }
-
-
- /*
- ** Form A:
- ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
- **
- ** Form B:
- ** CASE WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END
- **
- ** Form A is can be transformed into the equivalent form B as follows:
- ** CASE WHEN x=e1 THEN r1 WHEN x=e2 THEN r2 ...
- ** WHEN x=eN THEN rN ELSE y END
- **
- ** X (if it exists) is in pExpr->pLeft.
- ** Y is in pExpr->pRight. The Y is also optional. If there is no
- ** ELSE clause and no other term matches, then the result of the
- ** exprssion is NULL.
- ** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1].
- **
- ** The result of the expression is the Ri for the first matching Ei,
- ** or if there is no matching Ei, the ELSE term Y, or if there is
- ** no ELSE term, NULL.
- */
- default: assert( op==TK_CASE ); {
- int endLabel; /* GOTO label for end of CASE stmt */
- int nextCase; /* GOTO label for next WHEN clause */
- int nExpr; /* 2x number of WHEN terms */
- int i; /* Loop counter */
- ExprList *pEList; /* List of WHEN terms */
- struct ExprList_item *aListelem; /* Array of WHEN terms */
- Expr opCompare; /* The X==Ei expression */
- Expr cacheX; /* Cached expression X */
- Expr *pX; /* The X expression */
- Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
- VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
-
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
- assert((pExpr->x.pList->nExpr % 2) == 0);
- assert(pExpr->x.pList->nExpr > 0);
- pEList = pExpr->x.pList;
- aListelem = pEList->a;
- nExpr = pEList->nExpr;
- endLabel = sqlite3VdbeMakeLabel(v);
- if( (pX = pExpr->pLeft)!=0 ){
- cacheX = *pX;
- testcase( pX->op==TK_COLUMN );
- testcase( pX->op==TK_REGISTER );
- cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, &regFree1);
- testcase( regFree1==0 );
- cacheX.op = TK_REGISTER;
- opCompare.op = TK_EQ;
- opCompare.pLeft = &cacheX;
- pTest = &opCompare;
- /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
- ** The value in regFree1 might get SCopy-ed into the file result.
- ** So make sure that the regFree1 register is not reused for other
- ** purposes and possibly overwritten. */
- regFree1 = 0;
- }
- for(i=0; i<nExpr; i=i+2){
- sqlite3ExprCachePush(pParse);
- if( pX ){
- assert( pTest!=0 );
- opCompare.pRight = aListelem[i].pExpr;
- }else{
- pTest = aListelem[i].pExpr;
- }
- nextCase = sqlite3VdbeMakeLabel(v);
- testcase( pTest->op==TK_COLUMN );
- sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
- testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
- testcase( aListelem[i+1].pExpr->op==TK_REGISTER );
- sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel);
- sqlite3ExprCachePop(pParse, 1);
- sqlite3VdbeResolveLabel(v, nextCase);
- }
- if( pExpr->pRight ){
- sqlite3ExprCachePush(pParse);
- sqlite3ExprCode(pParse, pExpr->pRight, target);
- sqlite3ExprCachePop(pParse, 1);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, target);
- }
- assert( db->mallocFailed || pParse->nErr>0
- || pParse->iCacheLevel==iCacheLevel );
- sqlite3VdbeResolveLabel(v, endLabel);
- break;
- }
-#ifndef SQLITE_OMIT_TRIGGER
- case TK_RAISE: {
- assert( pExpr->affinity==OE_Rollback
- || pExpr->affinity==OE_Abort
- || pExpr->affinity==OE_Fail
- || pExpr->affinity==OE_Ignore
- );
- if( !pParse->pTriggerTab ){
- sqlite3ErrorMsg(pParse,
- "RAISE() may only be used within a trigger-program");
- return 0;
- }
- if( pExpr->affinity==OE_Abort ){
- sqlite3MayAbort(pParse);
- }
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- if( pExpr->affinity==OE_Ignore ){
- sqlite3VdbeAddOp4(
- v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
- }else{
- sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0);
- }
-
- break;
- }
-#endif
- }
- sqlite3ReleaseTempReg(pParse, regFree1);
- sqlite3ReleaseTempReg(pParse, regFree2);
- return inReg;
-}
-
-/*
-** Generate code to evaluate an expression and store the results
-** into a register. Return the register number where the results
-** are stored.
-**
-** If the register is a temporary register that can be deallocated,
-** then write its number into *pReg. If the result register is not
-** a temporary, then set *pReg to zero.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
- int r1 = sqlite3GetTempReg(pParse);
- int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
- if( r2==r1 ){
- *pReg = r1;
- }else{
- sqlite3ReleaseTempReg(pParse, r1);
- *pReg = 0;
- }
- return r2;
-}
-
-/*
-** Generate code that will evaluate expression pExpr and store the
-** results in register target. The results are guaranteed to appear
-** in register target.
-*/
-SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
- int inReg;
-
- assert( target>0 && target<=pParse->nMem );
- if( pExpr && pExpr->op==TK_REGISTER ){
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
- }else{
- inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
- assert( pParse->pVdbe || pParse->db->mallocFailed );
- if( inReg!=target && pParse->pVdbe ){
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
- }
- }
- return target;
-}
-
-/*
-** Generate code that evalutes the given expression and puts the result
-** in register target.
-**
-** Also make a copy of the expression results into another "cache" register
-** and modify the expression so that the next time it is evaluated,
-** the result is a copy of the cache register.
-**
-** This routine is used for expressions that are used multiple
-** times. They are evaluated once and the results of the expression
-** are reused.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
- Vdbe *v = pParse->pVdbe;
- int inReg;
- inReg = sqlite3ExprCode(pParse, pExpr, target);
- assert( target>0 );
- /* This routine is called for terms to INSERT or UPDATE. And the only
- ** other place where expressions can be converted into TK_REGISTER is
- ** in WHERE clause processing. So as currently implemented, there is
- ** no way for a TK_REGISTER to exist here. But it seems prudent to
- ** keep the ALWAYS() in case the conditions above change with future
- ** modifications or enhancements. */
- if( ALWAYS(pExpr->op!=TK_REGISTER) ){
- int iMem;
- iMem = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);
- pExpr->iTable = iMem;
- pExpr->op2 = pExpr->op;
- pExpr->op = TK_REGISTER;
- }
- return inReg;
-}
-
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-/*
-** Generate a human-readable explanation of an expression tree.
-*/
-SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
- int op; /* The opcode being coded */
- const char *zBinOp = 0; /* Binary operator */
- const char *zUniOp = 0; /* Unary operator */
- if( pExpr==0 ){
- op = TK_NULL;
- }else{
- op = pExpr->op;
- }
- switch( op ){
- case TK_AGG_COLUMN: {
- sqlite3ExplainPrintf(pOut, "AGG{%d:%d}",
- pExpr->iTable, pExpr->iColumn);
- break;
- }
- case TK_COLUMN: {
- if( pExpr->iTable<0 ){
- /* This only happens when coding check constraints */
- sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn);
- }else{
- sqlite3ExplainPrintf(pOut, "{%d:%d}",
- pExpr->iTable, pExpr->iColumn);
- }
- break;
- }
- case TK_INTEGER: {
- if( pExpr->flags & EP_IntValue ){
- sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue);
- }else{
- sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken);
- }
- break;
- }
-#ifndef SQLITE_OMIT_FLOATING_POINT
- case TK_FLOAT: {
- sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
- break;
- }
-#endif
- case TK_STRING: {
- sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken);
- break;
- }
- case TK_NULL: {
- sqlite3ExplainPrintf(pOut,"NULL");
- break;
- }
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- case TK_BLOB: {
- sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
- break;
- }
-#endif
- case TK_VARIABLE: {
- sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)",
- pExpr->u.zToken, pExpr->iColumn);
- break;
- }
- case TK_REGISTER: {
- sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable);
- break;
- }
- case TK_AS: {
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
- break;
- }
-#ifndef SQLITE_OMIT_CAST
- case TK_CAST: {
- /* Expressions of the form: CAST(pLeft AS token) */
- const char *zAff = "unk";
- switch( sqlite3AffinityType(pExpr->u.zToken) ){
- case SQLITE_AFF_TEXT: zAff = "TEXT"; break;
- case SQLITE_AFF_NONE: zAff = "NONE"; break;
- case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break;
- case SQLITE_AFF_INTEGER: zAff = "INTEGER"; break;
- case SQLITE_AFF_REAL: zAff = "REAL"; break;
- }
- sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff);
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
- sqlite3ExplainPrintf(pOut, ")");
- break;
- }
-#endif /* SQLITE_OMIT_CAST */
- case TK_LT: zBinOp = "LT"; break;
- case TK_LE: zBinOp = "LE"; break;
- case TK_GT: zBinOp = "GT"; break;
- case TK_GE: zBinOp = "GE"; break;
- case TK_NE: zBinOp = "NE"; break;
- case TK_EQ: zBinOp = "EQ"; break;
- case TK_IS: zBinOp = "IS"; break;
- case TK_ISNOT: zBinOp = "ISNOT"; break;
- case TK_AND: zBinOp = "AND"; break;
- case TK_OR: zBinOp = "OR"; break;
- case TK_PLUS: zBinOp = "ADD"; break;
- case TK_STAR: zBinOp = "MUL"; break;
- case TK_MINUS: zBinOp = "SUB"; break;
- case TK_REM: zBinOp = "REM"; break;
- case TK_BITAND: zBinOp = "BITAND"; break;
- case TK_BITOR: zBinOp = "BITOR"; break;
- case TK_SLASH: zBinOp = "DIV"; break;
- case TK_LSHIFT: zBinOp = "LSHIFT"; break;
- case TK_RSHIFT: zBinOp = "RSHIFT"; break;
- case TK_CONCAT: zBinOp = "CONCAT"; break;
-
- case TK_UMINUS: zUniOp = "UMINUS"; break;
- case TK_UPLUS: zUniOp = "UPLUS"; break;
- case TK_BITNOT: zUniOp = "BITNOT"; break;
- case TK_NOT: zUniOp = "NOT"; break;
- case TK_ISNULL: zUniOp = "ISNULL"; break;
- case TK_NOTNULL: zUniOp = "NOTNULL"; break;
-
- case TK_COLLATE: {
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
- sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
- break;
- }
-
- case TK_AGG_FUNCTION:
- case TK_CONST_FUNC:
- case TK_FUNCTION: {
- ExprList *pFarg; /* List of function arguments */
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
- pFarg = 0;
- }else{
- pFarg = pExpr->x.pList;
- }
- if( op==TK_AGG_FUNCTION ){
- sqlite3ExplainPrintf(pOut, "AGG_FUNCTION%d:%s(",
- pExpr->op2, pExpr->u.zToken);
- }else{
- sqlite3ExplainPrintf(pOut, "FUNCTION:%s(", pExpr->u.zToken);
- }
- if( pFarg ){
- sqlite3ExplainExprList(pOut, pFarg);
- }
- sqlite3ExplainPrintf(pOut, ")");
- break;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_EXISTS: {
- sqlite3ExplainPrintf(pOut, "EXISTS(");
- sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
- sqlite3ExplainPrintf(pOut,")");
- break;
- }
- case TK_SELECT: {
- sqlite3ExplainPrintf(pOut, "(");
- sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
- sqlite3ExplainPrintf(pOut, ")");
- break;
- }
- case TK_IN: {
- sqlite3ExplainPrintf(pOut, "IN(");
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
- sqlite3ExplainPrintf(pOut, ",");
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
- }else{
- sqlite3ExplainExprList(pOut, pExpr->x.pList);
- }
- sqlite3ExplainPrintf(pOut, ")");
- break;
- }
-#endif /* SQLITE_OMIT_SUBQUERY */
-
- /*
- ** x BETWEEN y AND z
- **
- ** This is equivalent to
- **
- ** x>=y AND x<=z
- **
- ** X is stored in pExpr->pLeft.
- ** Y is stored in pExpr->pList->a[0].pExpr.
- ** Z is stored in pExpr->pList->a[1].pExpr.
- */
- case TK_BETWEEN: {
- Expr *pX = pExpr->pLeft;
- Expr *pY = pExpr->x.pList->a[0].pExpr;
- Expr *pZ = pExpr->x.pList->a[1].pExpr;
- sqlite3ExplainPrintf(pOut, "BETWEEN(");
- sqlite3ExplainExpr(pOut, pX);
- sqlite3ExplainPrintf(pOut, ",");
- sqlite3ExplainExpr(pOut, pY);
- sqlite3ExplainPrintf(pOut, ",");
- sqlite3ExplainExpr(pOut, pZ);
- sqlite3ExplainPrintf(pOut, ")");
- break;
- }
- case TK_TRIGGER: {
- /* If the opcode is TK_TRIGGER, then the expression is a reference
- ** to a column in the new.* or old.* pseudo-tables available to
- ** trigger programs. In this case Expr.iTable is set to 1 for the
- ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
- ** is set to the column of the pseudo-table to read, or to -1 to
- ** read the rowid field.
- */
- sqlite3ExplainPrintf(pOut, "%s(%d)",
- pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
- break;
- }
- case TK_CASE: {
- sqlite3ExplainPrintf(pOut, "CASE(");
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
- sqlite3ExplainPrintf(pOut, ",");
- sqlite3ExplainExprList(pOut, pExpr->x.pList);
- break;
- }
-#ifndef SQLITE_OMIT_TRIGGER
- case TK_RAISE: {
- const char *zType = "unk";
- switch( pExpr->affinity ){
- case OE_Rollback: zType = "rollback"; break;
- case OE_Abort: zType = "abort"; break;
- case OE_Fail: zType = "fail"; break;
- case OE_Ignore: zType = "ignore"; break;
- }
- sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken);
- break;
- }
-#endif
- }
- if( zBinOp ){
- sqlite3ExplainPrintf(pOut,"%s(", zBinOp);
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
- sqlite3ExplainPrintf(pOut,",");
- sqlite3ExplainExpr(pOut, pExpr->pRight);
- sqlite3ExplainPrintf(pOut,")");
- }else if( zUniOp ){
- sqlite3ExplainPrintf(pOut,"%s(", zUniOp);
- sqlite3ExplainExpr(pOut, pExpr->pLeft);
- sqlite3ExplainPrintf(pOut,")");
- }
-}
-#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
-
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-/*
-** Generate a human-readable explanation of an expression list.
-*/
-SQLITE_PRIVATE void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){
- int i;
- if( pList==0 || pList->nExpr==0 ){
- sqlite3ExplainPrintf(pOut, "(empty-list)");
- return;
- }else if( pList->nExpr==1 ){
- sqlite3ExplainExpr(pOut, pList->a[0].pExpr);
- }else{
- sqlite3ExplainPush(pOut);
- for(i=0; i<pList->nExpr; i++){
- sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
- sqlite3ExplainPush(pOut);
- sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
- sqlite3ExplainPop(pOut);
- if( i<pList->nExpr-1 ){
- sqlite3ExplainNL(pOut);
- }
- }
- sqlite3ExplainPop(pOut);
- }
-}
-#endif /* SQLITE_DEBUG */
-
-/*
-** Return TRUE if pExpr is an constant expression that is appropriate
-** for factoring out of a loop. Appropriate expressions are:
-**
-** * Any expression that evaluates to two or more opcodes.
-**
-** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null,
-** or OP_Variable that does not need to be placed in a
-** specific register.
-**
-** There is no point in factoring out single-instruction constant
-** expressions that need to be placed in a particular register.
-** We could factor them out, but then we would end up adding an
-** OP_SCopy instruction to move the value into the correct register
-** later. We might as well just use the original instruction and
-** avoid the OP_SCopy.
-*/
-static int isAppropriateForFactoring(Expr *p){
- if( !sqlite3ExprIsConstantNotJoin(p) ){
- return 0; /* Only constant expressions are appropriate for factoring */
- }
- if( (p->flags & EP_FixedDest)==0 ){
- return 1; /* Any constant without a fixed destination is appropriate */
- }
- while( p->op==TK_UPLUS ) p = p->pLeft;
- switch( p->op ){
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- case TK_BLOB:
-#endif
- case TK_VARIABLE:
- case TK_INTEGER:
- case TK_FLOAT:
- case TK_NULL:
- case TK_STRING: {
- testcase( p->op==TK_BLOB );
- testcase( p->op==TK_VARIABLE );
- testcase( p->op==TK_INTEGER );
- testcase( p->op==TK_FLOAT );
- testcase( p->op==TK_NULL );
- testcase( p->op==TK_STRING );
- /* Single-instruction constants with a fixed destination are
- ** better done in-line. If we factor them, they will just end
- ** up generating an OP_SCopy to move the value to the destination
- ** register. */
- return 0;
- }
- case TK_UMINUS: {
- if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){
- return 0;
- }
- break;
- }
- default: {
- break;
- }
- }
- return 1;
-}
-
-/*
-** If pExpr is a constant expression that is appropriate for
-** factoring out of a loop, then evaluate the expression
-** into a register and convert the expression into a TK_REGISTER
-** expression.
-*/
-static int evalConstExpr(Walker *pWalker, Expr *pExpr){
- Parse *pParse = pWalker->pParse;
- switch( pExpr->op ){
- case TK_IN:
- case TK_REGISTER: {
- return WRC_Prune;
- }
- case TK_COLLATE: {
- return WRC_Continue;
- }
- case TK_FUNCTION:
- case TK_AGG_FUNCTION:
- case TK_CONST_FUNC: {
- /* The arguments to a function have a fixed destination.
- ** Mark them this way to avoid generated unneeded OP_SCopy
- ** instructions.
- */
- ExprList *pList = pExpr->x.pList;
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- if( pList ){
- int i = pList->nExpr;
- struct ExprList_item *pItem = pList->a;
- for(; i>0; i--, pItem++){
- if( ALWAYS(pItem->pExpr) ) pItem->pExpr->flags |= EP_FixedDest;
- }
- }
- break;
- }
- }
- if( isAppropriateForFactoring(pExpr) ){
- int r1 = ++pParse->nMem;
- int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
- /* If r2!=r1, it means that register r1 is never used. That is harmless
- ** but suboptimal, so we want to know about the situation to fix it.
- ** Hence the following assert: */
- assert( r2==r1 );
- pExpr->op2 = pExpr->op;
- pExpr->op = TK_REGISTER;
- pExpr->iTable = r2;
- return WRC_Prune;
- }
- return WRC_Continue;
-}
-
-/*
-** Preevaluate constant subexpressions within pExpr and store the
-** results in registers. Modify pExpr so that the constant subexpresions
-** are TK_REGISTER opcodes that refer to the precomputed values.
-**
-** This routine is a no-op if the jump to the cookie-check code has
-** already occur. Since the cookie-check jump is generated prior to
-** any other serious processing, this check ensures that there is no
-** way to accidently bypass the constant initializations.
-**
-** This routine is also a no-op if the SQLITE_FactorOutConst optimization
-** is disabled via the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS)
-** interface. This allows test logic to verify that the same answer is
-** obtained for queries regardless of whether or not constants are
-** precomputed into registers or if they are inserted in-line.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
- Walker w;
- if( pParse->cookieGoto ) return;
- if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return;
- w.xExprCallback = evalConstExpr;
- w.xSelectCallback = 0;
- w.pParse = pParse;
- sqlite3WalkExpr(&w, pExpr);
-}
-
-
-/*
-** Generate code that pushes the value of every element of the given
-** expression list into a sequence of registers beginning at target.
-**
-** Return the number of elements evaluated.
-*/
-SQLITE_PRIVATE int sqlite3ExprCodeExprList(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* The expression list to be coded */
- int target, /* Where to write results */
- int doHardCopy /* Make a hard copy of every element */
-){
- struct ExprList_item *pItem;
- int i, n;
- assert( pList!=0 );
- assert( target>0 );
- assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */
- n = pList->nExpr;
- for(pItem=pList->a, i=0; i<n; i++, pItem++){
- Expr *pExpr = pItem->pExpr;
- int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
- if( inReg!=target+i ){
- sqlite3VdbeAddOp2(pParse->pVdbe, doHardCopy ? OP_Copy : OP_SCopy,
- inReg, target+i);
- }
- }
- return n;
-}
-
-/*
-** Generate code for a BETWEEN operator.
-**
-** x BETWEEN y AND z
-**
-** The above is equivalent to
-**
-** x>=y AND x<=z
-**
-** Code it as such, taking care to do the common subexpression
-** elementation of x.
-*/
-static void exprCodeBetween(
- Parse *pParse, /* Parsing and code generating context */
- Expr *pExpr, /* The BETWEEN expression */
- int dest, /* Jump here if the jump is taken */
- int jumpIfTrue, /* Take the jump if the BETWEEN is true */
- int jumpIfNull /* Take the jump if the BETWEEN is NULL */
-){
- Expr exprAnd; /* The AND operator in x>=y AND x<=z */
- Expr compLeft; /* The x>=y term */
- Expr compRight; /* The x<=z term */
- Expr exprX; /* The x subexpression */
- int regFree1 = 0; /* Temporary use register */
-
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- exprX = *pExpr->pLeft;
- exprAnd.op = TK_AND;
- exprAnd.pLeft = &compLeft;
- exprAnd.pRight = &compRight;
- compLeft.op = TK_GE;
- compLeft.pLeft = &exprX;
- compLeft.pRight = pExpr->x.pList->a[0].pExpr;
- compRight.op = TK_LE;
- compRight.pLeft = &exprX;
- compRight.pRight = pExpr->x.pList->a[1].pExpr;
- exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, &regFree1);
- exprX.op = TK_REGISTER;
- if( jumpIfTrue ){
- sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
- }else{
- sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull);
- }
- sqlite3ReleaseTempReg(pParse, regFree1);
-
- /* Ensure adequate test coverage */
- testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 );
- testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 );
- testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 );
- testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 );
- testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 );
- testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 );
- testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 );
- testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 );
-}
-
-/*
-** Generate code for a boolean expression such that a jump is made
-** to the label "dest" if the expression is true but execution
-** continues straight thru if the expression is false.
-**
-** If the expression evaluates to NULL (neither true nor false), then
-** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL.
-**
-** This code depends on the fact that certain token values (ex: TK_EQ)
-** are the same as opcode values (ex: OP_Eq) that implement the corresponding
-** operation. Special comments in vdbe.c and the mkopcodeh.awk script in
-** the make process cause these values to align. Assert()s in the code
-** below verify that the numbers are aligned correctly.
-*/
-SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
- Vdbe *v = pParse->pVdbe;
- int op = 0;
- int regFree1 = 0;
- int regFree2 = 0;
- int r1, r2;
-
- assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
- if( NEVER(pExpr==0) ) return; /* No way this can happen */
- op = pExpr->op;
- switch( op ){
- case TK_AND: {
- int d2 = sqlite3VdbeMakeLabel(v);
- testcase( jumpIfNull==0 );
- sqlite3ExprCachePush(pParse);
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
- sqlite3ExprCachePop(pParse, 1);
- break;
- }
- case TK_OR: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
- break;
- }
- case TK_NOT: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
- break;
- }
- case TK_LT:
- case TK_LE:
- case TK_GT:
- case TK_GE:
- case TK_NE:
- case TK_EQ: {
- assert( TK_LT==OP_Lt );
- assert( TK_LE==OP_Le );
- assert( TK_GT==OP_Gt );
- assert( TK_GE==OP_Ge );
- assert( TK_EQ==OP_Eq );
- assert( TK_NE==OP_Ne );
- testcase( op==TK_LT );
- testcase( op==TK_LE );
- testcase( op==TK_GT );
- testcase( op==TK_GE );
- testcase( op==TK_EQ );
- testcase( op==TK_NE );
- testcase( jumpIfNull==0 );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, jumpIfNull);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_IS:
- case TK_ISNOT: {
- testcase( op==TK_IS );
- testcase( op==TK_ISNOT );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- op = (op==TK_IS) ? TK_EQ : TK_NE;
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, SQLITE_NULLEQ);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_ISNULL:
- case TK_NOTNULL: {
- assert( TK_ISNULL==OP_IsNull );
- assert( TK_NOTNULL==OP_NotNull );
- testcase( op==TK_ISNULL );
- testcase( op==TK_NOTNULL );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- sqlite3VdbeAddOp2(v, op, r1, dest);
- testcase( regFree1==0 );
- break;
- }
- case TK_BETWEEN: {
- testcase( jumpIfNull==0 );
- exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull);
- break;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_IN: {
- int destIfFalse = sqlite3VdbeMakeLabel(v);
- int destIfNull = jumpIfNull ? dest : destIfFalse;
- sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
- sqlite3VdbeResolveLabel(v, destIfFalse);
- break;
- }
-#endif
- default: {
- r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
- sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
- testcase( regFree1==0 );
- testcase( jumpIfNull==0 );
- break;
- }
- }
- sqlite3ReleaseTempReg(pParse, regFree1);
- sqlite3ReleaseTempReg(pParse, regFree2);
-}
-
-/*
-** Generate code for a boolean expression such that a jump is made
-** to the label "dest" if the expression is false but execution
-** continues straight thru if the expression is true.
-**
-** If the expression evaluates to NULL (neither true nor false) then
-** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull
-** is 0.
-*/
-SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
- Vdbe *v = pParse->pVdbe;
- int op = 0;
- int regFree1 = 0;
- int regFree2 = 0;
- int r1, r2;
-
- assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
- if( pExpr==0 ) return;
-
- /* The value of pExpr->op and op are related as follows:
- **
- ** pExpr->op op
- ** --------- ----------
- ** TK_ISNULL OP_NotNull
- ** TK_NOTNULL OP_IsNull
- ** TK_NE OP_Eq
- ** TK_EQ OP_Ne
- ** TK_GT OP_Le
- ** TK_LE OP_Gt
- ** TK_GE OP_Lt
- ** TK_LT OP_Ge
- **
- ** For other values of pExpr->op, op is undefined and unused.
- ** The value of TK_ and OP_ constants are arranged such that we
- ** can compute the mapping above using the following expression.
- ** Assert()s verify that the computation is correct.
- */
- op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1);
-
- /* Verify correct alignment of TK_ and OP_ constants
- */
- assert( pExpr->op!=TK_ISNULL || op==OP_NotNull );
- assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull );
- assert( pExpr->op!=TK_NE || op==OP_Eq );
- assert( pExpr->op!=TK_EQ || op==OP_Ne );
- assert( pExpr->op!=TK_LT || op==OP_Ge );
- assert( pExpr->op!=TK_LE || op==OP_Gt );
- assert( pExpr->op!=TK_GT || op==OP_Le );
- assert( pExpr->op!=TK_GE || op==OP_Lt );
-
- switch( pExpr->op ){
- case TK_AND: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- break;
- }
- case TK_OR: {
- int d2 = sqlite3VdbeMakeLabel(v);
- testcase( jumpIfNull==0 );
- sqlite3ExprCachePush(pParse);
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
- sqlite3VdbeResolveLabel(v, d2);
- sqlite3ExprCachePop(pParse, 1);
- break;
- }
- case TK_NOT: {
- testcase( jumpIfNull==0 );
- sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
- break;
- }
- case TK_LT:
- case TK_LE:
- case TK_GT:
- case TK_GE:
- case TK_NE:
- case TK_EQ: {
- testcase( op==TK_LT );
- testcase( op==TK_LE );
- testcase( op==TK_GT );
- testcase( op==TK_GE );
- testcase( op==TK_EQ );
- testcase( op==TK_NE );
- testcase( jumpIfNull==0 );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, jumpIfNull);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_IS:
- case TK_ISNOT: {
- testcase( pExpr->op==TK_IS );
- testcase( pExpr->op==TK_ISNOT );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, SQLITE_NULLEQ);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_ISNULL:
- case TK_NOTNULL: {
- testcase( op==TK_ISNULL );
- testcase( op==TK_NOTNULL );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- sqlite3VdbeAddOp2(v, op, r1, dest);
- testcase( regFree1==0 );
- break;
- }
- case TK_BETWEEN: {
- testcase( jumpIfNull==0 );
- exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull);
- break;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_IN: {
- if( jumpIfNull ){
- sqlite3ExprCodeIN(pParse, pExpr, dest, dest);
- }else{
- int destIfNull = sqlite3VdbeMakeLabel(v);
- sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull);
- sqlite3VdbeResolveLabel(v, destIfNull);
- }
- break;
- }
-#endif
- default: {
- r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
- sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
- testcase( regFree1==0 );
- testcase( jumpIfNull==0 );
- break;
- }
- }
- sqlite3ReleaseTempReg(pParse, regFree1);
- sqlite3ReleaseTempReg(pParse, regFree2);
-}
-
-/*
-** Do a deep comparison of two expression trees. Return 0 if the two
-** expressions are completely identical. Return 1 if they differ only
-** by a COLLATE operator at the top level. Return 2 if there are differences
-** other than the top-level COLLATE operator.
-**
-** Sometimes this routine will return 2 even if the two expressions
-** really are equivalent. If we cannot prove that the expressions are
-** identical, we return 2 just to be safe. So if this routine
-** returns 2, then you do not really know for certain if the two
-** expressions are the same. But if you get a 0 or 1 return, then you
-** can be sure the expressions are the same. In the places where
-** this routine is used, it does not hurt to get an extra 2 - that
-** just might result in some slightly slower code. But returning
-** an incorrect 0 or 1 could lead to a malfunction.
-*/
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
- if( pA==0||pB==0 ){
- return pB==pA ? 0 : 2;
- }
- assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
- assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
- if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
- return 2;
- }
- if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
- if( pA->op!=pB->op ){
- if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
- return 1;
- }
- if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
- return 1;
- }
- return 2;
- }
- if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
- if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
- if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
- if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
- if( ExprHasProperty(pA, EP_IntValue) ){
- if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
- return 2;
- }
- }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
- if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
- if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
- return pA->op==TK_COLLATE ? 1 : 2;
- }
- }
- return 0;
-}
-
-/*
-** Compare two ExprList objects. Return 0 if they are identical and
-** non-zero if they differ in any way.
-**
-** This routine might return non-zero for equivalent ExprLists. The
-** only consequence will be disabled optimizations. But this routine
-** must never return 0 if the two ExprList objects are different, or
-** a malfunction will result.
-**
-** Two NULL pointers are considered to be the same. But a NULL pointer
-** always differs from a non-NULL pointer.
-*/
-SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
- int i;
- if( pA==0 && pB==0 ) return 0;
- if( pA==0 || pB==0 ) return 1;
- if( pA->nExpr!=pB->nExpr ) return 1;
- for(i=0; i<pA->nExpr; i++){
- Expr *pExprA = pA->a[i].pExpr;
- Expr *pExprB = pB->a[i].pExpr;
- if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
- if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;
- }
- return 0;
-}
-
-/*
-** An instance of the following structure is used by the tree walker
-** to count references to table columns in the arguments of an
-** aggregate function, in order to implement the
-** sqlite3FunctionThisSrc() routine.
-*/
-struct SrcCount {
- SrcList *pSrc; /* One particular FROM clause in a nested query */
- int nThis; /* Number of references to columns in pSrcList */
- int nOther; /* Number of references to columns in other FROM clauses */
-};
-
-/*
-** Count the number of references to columns.
-*/
-static int exprSrcCount(Walker *pWalker, Expr *pExpr){
- /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc()
- ** is always called before sqlite3ExprAnalyzeAggregates() and so the
- ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN. If
- ** sqlite3FunctionUsesThisSrc() is used differently in the future, the
- ** NEVER() will need to be removed. */
- if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){
- int i;
- struct SrcCount *p = pWalker->u.pSrcCount;
- SrcList *pSrc = p->pSrc;
- for(i=0; i<pSrc->nSrc; i++){
- if( pExpr->iTable==pSrc->a[i].iCursor ) break;
- }
- if( i<pSrc->nSrc ){
- p->nThis++;
- }else{
- p->nOther++;
- }
- }
- return WRC_Continue;
-}
-
-/*
-** Determine if any of the arguments to the pExpr Function reference
-** pSrcList. Return true if they do. Also return true if the function
-** has no arguments or has only constant arguments. Return false if pExpr
-** references columns but not columns of tables found in pSrcList.
-*/
-SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
- Walker w;
- struct SrcCount cnt;
- assert( pExpr->op==TK_AGG_FUNCTION );
- memset(&w, 0, sizeof(w));
- w.xExprCallback = exprSrcCount;
- w.u.pSrcCount = &cnt;
- cnt.pSrc = pSrcList;
- cnt.nThis = 0;
- cnt.nOther = 0;
- sqlite3WalkExprList(&w, pExpr->x.pList);
- return cnt.nThis>0 || cnt.nOther==0;
-}
-
-/*
-** Add a new element to the pAggInfo->aCol[] array. Return the index of
-** the new element. Return a negative number if malloc fails.
-*/
-static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
- int i;
- pInfo->aCol = sqlite3ArrayAllocate(
- db,
- pInfo->aCol,
- sizeof(pInfo->aCol[0]),
- &pInfo->nColumn,
- &i
- );
- return i;
-}
-
-/*
-** Add a new element to the pAggInfo->aFunc[] array. Return the index of
-** the new element. Return a negative number if malloc fails.
-*/
-static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){
- int i;
- pInfo->aFunc = sqlite3ArrayAllocate(
- db,
- pInfo->aFunc,
- sizeof(pInfo->aFunc[0]),
- &pInfo->nFunc,
- &i
- );
- return i;
-}
-
-/*
-** This is the xExprCallback for a tree walker. It is used to
-** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates
-** for additional information.
-*/
-static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
- int i;
- NameContext *pNC = pWalker->u.pNC;
- Parse *pParse = pNC->pParse;
- SrcList *pSrcList = pNC->pSrcList;
- AggInfo *pAggInfo = pNC->pAggInfo;
-
- switch( pExpr->op ){
- case TK_AGG_COLUMN:
- case TK_COLUMN: {
- testcase( pExpr->op==TK_AGG_COLUMN );
- testcase( pExpr->op==TK_COLUMN );
- /* Check to see if the column is in one of the tables in the FROM
- ** clause of the aggregate query */
- if( ALWAYS(pSrcList!=0) ){
- struct SrcList_item *pItem = pSrcList->a;
- for(i=0; i<pSrcList->nSrc; i++, pItem++){
- struct AggInfo_col *pCol;
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
- if( pExpr->iTable==pItem->iCursor ){
- /* If we reach this point, it means that pExpr refers to a table
- ** that is in the FROM clause of the aggregate query.
- **
- ** Make an entry for the column in pAggInfo->aCol[] if there
- ** is not an entry there already.
- */
- int k;
- pCol = pAggInfo->aCol;
- for(k=0; k<pAggInfo->nColumn; k++, pCol++){
- if( pCol->iTable==pExpr->iTable &&
- pCol->iColumn==pExpr->iColumn ){
- break;
- }
- }
- if( (k>=pAggInfo->nColumn)
- && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
- ){
- pCol = &pAggInfo->aCol[k];
- pCol->pTab = pExpr->pTab;
- pCol->iTable = pExpr->iTable;
- pCol->iColumn = pExpr->iColumn;
- pCol->iMem = ++pParse->nMem;
- pCol->iSorterColumn = -1;
- pCol->pExpr = pExpr;
- if( pAggInfo->pGroupBy ){
- int j, n;
- ExprList *pGB = pAggInfo->pGroupBy;
- struct ExprList_item *pTerm = pGB->a;
- n = pGB->nExpr;
- for(j=0; j<n; j++, pTerm++){
- Expr *pE = pTerm->pExpr;
- if( pE->op==TK_COLUMN && pE->iTable==pExpr->iTable &&
- pE->iColumn==pExpr->iColumn ){
- pCol->iSorterColumn = j;
- break;
- }
- }
- }
- if( pCol->iSorterColumn<0 ){
- pCol->iSorterColumn = pAggInfo->nSortingColumn++;
- }
- }
- /* There is now an entry for pExpr in pAggInfo->aCol[] (either
- ** because it was there before or because we just created it).
- ** Convert the pExpr to be a TK_AGG_COLUMN referring to that
- ** pAggInfo->aCol[] entry.
- */
- ExprSetIrreducible(pExpr);
- pExpr->pAggInfo = pAggInfo;
- pExpr->op = TK_AGG_COLUMN;
- pExpr->iAgg = (i16)k;
- break;
- } /* endif pExpr->iTable==pItem->iCursor */
- } /* end loop over pSrcList */
- }
- return WRC_Prune;
- }
- case TK_AGG_FUNCTION: {
- if( (pNC->ncFlags & NC_InAggFunc)==0
- && pWalker->walkerDepth==pExpr->op2
- ){
- /* Check to see if pExpr is a duplicate of another aggregate
- ** function that is already in the pAggInfo structure
- */
- struct AggInfo_func *pItem = pAggInfo->aFunc;
- for(i=0; i<pAggInfo->nFunc; i++, pItem++){
- if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
- break;
- }
- }
- if( i>=pAggInfo->nFunc ){
- /* pExpr is original. Make a new entry in pAggInfo->aFunc[]
- */
- u8 enc = ENC(pParse->db);
- i = addAggInfoFunc(pParse->db, pAggInfo);
- if( i>=0 ){
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pItem = &pAggInfo->aFunc[i];
- pItem->pExpr = pExpr;
- pItem->iMem = ++pParse->nMem;
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- pItem->pFunc = sqlite3FindFunction(pParse->db,
- pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
- pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
- if( pExpr->flags & EP_Distinct ){
- pItem->iDistinct = pParse->nTab++;
- }else{
- pItem->iDistinct = -1;
- }
- }
- }
- /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
- */
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(pExpr);
- pExpr->iAgg = (i16)i;
- pExpr->pAggInfo = pAggInfo;
- return WRC_Prune;
- }else{
- return WRC_Continue;
- }
- }
- }
- return WRC_Continue;
-}
-static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
- UNUSED_PARAMETER(pWalker);
- UNUSED_PARAMETER(pSelect);
- return WRC_Continue;
-}
-
-/*
-** Analyze the pExpr expression looking for aggregate functions and
-** for variables that need to be added to AggInfo object that pNC->pAggInfo
-** points to. Additional entries are made on the AggInfo object as
-** necessary.
-**
-** This routine should only be called after the expression has been
-** analyzed by sqlite3ResolveExprNames().
-*/
-SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
- Walker w;
- memset(&w, 0, sizeof(w));
- w.xExprCallback = analyzeAggregate;
- w.xSelectCallback = analyzeAggregatesInSelect;
- w.u.pNC = pNC;
- assert( pNC->pSrcList!=0 );
- sqlite3WalkExpr(&w, pExpr);
-}
-
-/*
-** Call sqlite3ExprAnalyzeAggregates() for every expression in an
-** expression list. Return the number of errors.
-**
-** If an error is found, the analysis is cut short.
-*/
-SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){
- struct ExprList_item *pItem;
- int i;
- if( pList ){
- for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
- sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr);
- }
- }
-}
-
-/*
-** Allocate a single new register for use to hold some intermediate result.
-*/
-SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){
- if( pParse->nTempReg==0 ){
- return ++pParse->nMem;
- }
- return pParse->aTempReg[--pParse->nTempReg];
-}
-
-/*
-** Deallocate a register, making available for reuse for some other
-** purpose.
-**
-** If a register is currently being used by the column cache, then
-** the dallocation is deferred until the column cache line that uses
-** the register becomes stale.
-*/
-SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
- if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg==iReg ){
- p->tempReg = 1;
- return;
- }
- }
- pParse->aTempReg[pParse->nTempReg++] = iReg;
- }
-}
-
-/*
-** Allocate or deallocate a block of nReg consecutive registers
-*/
-SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){
- int i, n;
- i = pParse->iRangeReg;
- n = pParse->nRangeReg;
- if( nReg<=n ){
- assert( !usedAsColumnCache(pParse, i, i+n-1) );
- pParse->iRangeReg += nReg;
- pParse->nRangeReg -= nReg;
- }else{
- i = pParse->nMem+1;
- pParse->nMem += nReg;
- }
- return i;
-}
-SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
- sqlite3ExprCacheRemove(pParse, iReg, nReg);
- if( nReg>pParse->nRangeReg ){
- pParse->nRangeReg = nReg;
- pParse->iRangeReg = iReg;
- }
-}
-
-/*
-** Mark all temporary registers as being unavailable for reuse.
-*/
-SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){
- pParse->nTempReg = 0;
- pParse->nRangeReg = 0;
-}
-
-/************** End of expr.c ************************************************/
-/************** Begin file alter.c *******************************************/
-/*
-** 2005 February 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains C code routines that used to generate VDBE code
-** that implements the ALTER TABLE command.
-*/
-
-/*
-** The code in this file only exists if we are not omitting the
-** ALTER TABLE logic from the build.
-*/
-#ifndef SQLITE_OMIT_ALTERTABLE
-
-
-/*
-** This function is used by SQL generated to implement the
-** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
-** CREATE INDEX command. The second is a table name. The table name in
-** the CREATE TABLE or CREATE INDEX statement is replaced with the third
-** argument and the result returned. Examples:
-**
-** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
-** -> 'CREATE TABLE def(a, b, c)'
-**
-** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
-** -> 'CREATE INDEX i ON def(a, b, c)'
-*/
-static void renameTableFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- unsigned char const *zSql = sqlite3_value_text(argv[0]);
- unsigned char const *zTableName = sqlite3_value_text(argv[1]);
-
- int token;
- Token tname;
- unsigned char const *zCsr = zSql;
- int len = 0;
- char *zRet;
-
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- UNUSED_PARAMETER(NotUsed);
-
- /* The principle used to locate the table name in the CREATE TABLE
- ** statement is that the table name is the first non-space token that
- ** is immediately followed by a TK_LP or TK_USING token.
- */
- if( zSql ){
- do {
- if( !*zCsr ){
- /* Ran out of input before finding an opening bracket. Return NULL. */
- return;
- }
-
- /* Store the token that zCsr points to in tname. */
- tname.z = (char*)zCsr;
- tname.n = len;
-
- /* Advance zCsr to the next token. Store that token type in 'token',
- ** and its length in 'len' (to be used next iteration of this loop).
- */
- do {
- zCsr += len;
- len = sqlite3GetToken(zCsr, &token);
- } while( token==TK_SPACE );
- assert( len>0 );
- } while( token!=TK_LP && token!=TK_USING );
-
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
- zTableName, tname.z+tname.n);
- sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
- }
-}
-
-/*
-** This C function implements an SQL user function that is used by SQL code
-** generated by the ALTER TABLE ... RENAME command to modify the definition
-** of any foreign key constraints that use the table being renamed as the
-** parent table. It is passed three arguments:
-**
-** 1) The complete text of the CREATE TABLE statement being modified,
-** 2) The old name of the table being renamed, and
-** 3) The new name of the table being renamed.
-**
-** It returns the new CREATE TABLE statement. For example:
-**
-** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3')
-** -> 'CREATE TABLE t1(a REFERENCES t3)'
-*/
-#ifndef SQLITE_OMIT_FOREIGN_KEY
-static void renameParentFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- sqlite3 *db = sqlite3_context_db_handle(context);
- char *zOutput = 0;
- char *zResult;
- unsigned char const *zInput = sqlite3_value_text(argv[0]);
- unsigned char const *zOld = sqlite3_value_text(argv[1]);
- unsigned char const *zNew = sqlite3_value_text(argv[2]);
-
- unsigned const char *z; /* Pointer to token */
- int n; /* Length of token z */
- int token; /* Type of token */
-
- UNUSED_PARAMETER(NotUsed);
- for(z=zInput; *z; z=z+n){
- n = sqlite3GetToken(z, &token);
- if( token==TK_REFERENCES ){
- char *zParent;
- do {
- z += n;
- n = sqlite3GetToken(z, &token);
- }while( token==TK_SPACE );
-
- zParent = sqlite3DbStrNDup(db, (const char *)z, n);
- if( zParent==0 ) break;
- sqlite3Dequote(zParent);
- if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
- char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
- (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew
- );
- sqlite3DbFree(db, zOutput);
- zOutput = zOut;
- zInput = &z[n];
- }
- sqlite3DbFree(db, zParent);
- }
- }
-
- zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput),
- sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC);
- sqlite3DbFree(db, zOutput);
-}
-#endif
-
-#ifndef SQLITE_OMIT_TRIGGER
-/* This function is used by SQL generated to implement the
-** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER
-** statement. The second is a table name. The table name in the CREATE
-** TRIGGER statement is replaced with the third argument and the result
-** returned. This is analagous to renameTableFunc() above, except for CREATE
-** TRIGGER, not CREATE INDEX and CREATE TABLE.
-*/
-static void renameTriggerFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- unsigned char const *zSql = sqlite3_value_text(argv[0]);
- unsigned char const *zTableName = sqlite3_value_text(argv[1]);
-
- int token;
- Token tname;
- int dist = 3;
- unsigned char const *zCsr = zSql;
- int len = 0;
- char *zRet;
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- UNUSED_PARAMETER(NotUsed);
-
- /* The principle used to locate the table name in the CREATE TRIGGER
- ** statement is that the table name is the first token that is immediatedly
- ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
- ** of TK_WHEN, TK_BEGIN or TK_FOR.
- */
- if( zSql ){
- do {
-
- if( !*zCsr ){
- /* Ran out of input before finding the table name. Return NULL. */
- return;
- }
-
- /* Store the token that zCsr points to in tname. */
- tname.z = (char*)zCsr;
- tname.n = len;
-
- /* Advance zCsr to the next token. Store that token type in 'token',
- ** and its length in 'len' (to be used next iteration of this loop).
- */
- do {
- zCsr += len;
- len = sqlite3GetToken(zCsr, &token);
- }while( token==TK_SPACE );
- assert( len>0 );
-
- /* Variable 'dist' stores the number of tokens read since the most
- ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN
- ** token is read and 'dist' equals 2, the condition stated above
- ** to be met.
- **
- ** Note that ON cannot be a database, table or column name, so
- ** there is no need to worry about syntax like
- ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
- */
- dist++;
- if( token==TK_DOT || token==TK_ON ){
- dist = 0;
- }
- } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
-
- /* Variable tname now contains the token that is the old table-name
- ** in the CREATE TRIGGER statement.
- */
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
- zTableName, tname.z+tname.n);
- sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
- }
-}
-#endif /* !SQLITE_OMIT_TRIGGER */
-
-/*
-** Register built-in functions used to help implement ALTER TABLE
-*/
-SQLITE_PRIVATE void sqlite3AlterFunctions(void){
- static SQLITE_WSD FuncDef aAlterTableFuncs[] = {
- FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc),
-#ifndef SQLITE_OMIT_TRIGGER
- FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
-#endif
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc),
-#endif
- };
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs);
-
- for(i=0; i<ArraySize(aAlterTableFuncs); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
-}
-
-/*
-** This function is used to create the text of expressions of the form:
-**
-** name=<constant1> OR name=<constant2> OR ...
-**
-** If argument zWhere is NULL, then a pointer string containing the text
-** "name=<constant>" is returned, where <constant> is the quoted version
-** of the string passed as argument zConstant. The returned buffer is
-** allocated using sqlite3DbMalloc(). It is the responsibility of the
-** caller to ensure that it is eventually freed.
-**
-** If argument zWhere is not NULL, then the string returned is
-** "<where> OR name=<constant>", where <where> is the contents of zWhere.
-** In this case zWhere is passed to sqlite3DbFree() before returning.
-**
-*/
-static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){
- char *zNew;
- if( !zWhere ){
- zNew = sqlite3MPrintf(db, "name=%Q", zConstant);
- }else{
- zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant);
- sqlite3DbFree(db, zWhere);
- }
- return zNew;
-}
-
-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
-/*
-** Generate the text of a WHERE expression which can be used to select all
-** tables that have foreign key constraints that refer to table pTab (i.e.
-** constraints for which pTab is the parent table) from the sqlite_master
-** table.
-*/
-static char *whereForeignKeys(Parse *pParse, Table *pTab){
- FKey *p;
- char *zWhere = 0;
- for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName);
- }
- return zWhere;
-}
-#endif
-
-/*
-** Generate the text of a WHERE expression which can be used to select all
-** temporary triggers on table pTab from the sqlite_temp_master table. If
-** table pTab has no temporary triggers, or is itself stored in the
-** temporary database, NULL is returned.
-*/
-static char *whereTempTriggers(Parse *pParse, Table *pTab){
- Trigger *pTrig;
- char *zWhere = 0;
- const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
-
- /* If the table is not located in the temp-db (in which case NULL is
- ** returned, loop through the tables list of triggers. For each trigger
- ** that is not part of the temp-db schema, add a clause to the WHERE
- ** expression being built up in zWhere.
- */
- if( pTab->pSchema!=pTempSchema ){
- sqlite3 *db = pParse->db;
- for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
- if( pTrig->pSchema==pTempSchema ){
- zWhere = whereOrName(db, zWhere, pTrig->zName);
- }
- }
- }
- if( zWhere ){
- char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere);
- sqlite3DbFree(pParse->db, zWhere);
- zWhere = zNew;
- }
- return zWhere;
-}
-
-/*
-** Generate code to drop and reload the internal representation of table
-** pTab from the database, including triggers and temporary triggers.
-** Argument zName is the name of the table in the database schema at
-** the time the generated code is executed. This can be different from
-** pTab->zName if this function is being called to code part of an
-** "ALTER TABLE RENAME TO" statement.
-*/
-static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
- Vdbe *v;
- char *zWhere;
- int iDb; /* Index of database containing pTab */
-#ifndef SQLITE_OMIT_TRIGGER
- Trigger *pTrig;
-#endif
-
- v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return;
- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- assert( iDb>=0 );
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* Drop any table triggers from the internal schema. */
- for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){
- int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
- assert( iTrigDb==iDb || iTrigDb==1 );
- sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0);
- }
-#endif
-
- /* Drop the table and index from the internal schema. */
- sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
-
- /* Reload the table, index and permanent trigger schemas. */
- zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
- if( !zWhere ) return;
- sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* Now, if the table is not stored in the temp database, reload any temp
- ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined.
- */
- if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
- sqlite3VdbeAddParseSchemaOp(v, 1, zWhere);
- }
-#endif
-}
-
-/*
-** Parameter zName is the name of a table that is about to be altered
-** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
-** If the table is a system table, this function leaves an error message
-** in pParse->zErr (system tables may not be altered) and returns non-zero.
-**
-** Or, if zName is not a system table, zero is returned.
-*/
-static int isSystemTable(Parse *pParse, const char *zName){
- if( sqlite3Strlen30(zName)>6 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
- sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
- return 1;
- }
- return 0;
-}
-
-/*
-** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy"
-** command.
-*/
-SQLITE_PRIVATE void sqlite3AlterRenameTable(
- Parse *pParse, /* Parser context. */
- SrcList *pSrc, /* The table to rename. */
- Token *pName /* The new table name. */
-){
- int iDb; /* Database that contains the table */
- char *zDb; /* Name of database iDb */
- Table *pTab; /* Table being renamed */
- char *zName = 0; /* NULL-terminated version of pName */
- sqlite3 *db = pParse->db; /* Database connection */
- int nTabName; /* Number of UTF-8 characters in zTabName */
- const char *zTabName; /* Original name of the table */
- Vdbe *v;
-#ifndef SQLITE_OMIT_TRIGGER
- char *zWhere = 0; /* Where clause to locate temp triggers */
-#endif
- VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */
- int savedDbFlags; /* Saved value of db->flags */
-
- savedDbFlags = db->flags;
- if( NEVER(db->mallocFailed) ) goto exit_rename_table;
- assert( pSrc->nSrc==1 );
- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
-
- pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
- if( !pTab ) goto exit_rename_table;
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- zDb = db->aDb[iDb].zName;
- db->flags |= SQLITE_PreferBuiltin;
-
- /* Get a NULL terminated version of the new table name. */
- zName = sqlite3NameFromToken(db, pName);
- if( !zName ) goto exit_rename_table;
-
- /* Check that a table or index named 'zName' does not already exist
- ** in database iDb. If so, this is an error.
- */
- if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
- sqlite3ErrorMsg(pParse,
- "there is already another table or index with this name: %s", zName);
- goto exit_rename_table;
- }
-
- /* Make sure it is not a system table being altered, or a reserved name
- ** that the table is being renamed to.
- */
- if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
- goto exit_rename_table;
- }
- if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
- exit_rename_table;
- }
-
-#ifndef SQLITE_OMIT_VIEW
- if( pTab->pSelect ){
- sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName);
- goto exit_rename_table;
- }
-#endif
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- /* Invoke the authorization callback. */
- if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
- goto exit_rename_table;
- }
-#endif
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto exit_rename_table;
- }
- if( IsVirtual(pTab) ){
- pVTab = sqlite3GetVTable(db, pTab);
- if( pVTab->pVtab->pModule->xRename==0 ){
- pVTab = 0;
- }
- }
-#endif
-
- /* Begin a transaction and code the VerifyCookie for database iDb.
- ** Then modify the schema cookie (since the ALTER TABLE modifies the
- ** schema). Open a statement transaction if the table is a virtual
- ** table.
- */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ){
- goto exit_rename_table;
- }
- sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb);
- sqlite3ChangeCookie(pParse, iDb);
-
- /* If this is a virtual table, invoke the xRename() function if
- ** one is defined. The xRename() callback will modify the names
- ** of any resources used by the v-table implementation (including other
- ** SQLite tables) that are identified by the name of the virtual table.
- */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pVTab ){
- int i = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0);
- sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB);
- sqlite3MayAbort(pParse);
- }
-#endif
-
- /* figure out how many UTF-8 characters are in zName */
- zTabName = pTab->zName;
- nTabName = sqlite3Utf8CharLen(zTabName, -1);
-
-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- if( db->flags&SQLITE_ForeignKeys ){
- /* If foreign-key support is enabled, rewrite the CREATE TABLE
- ** statements corresponding to all child tables of foreign key constraints
- ** for which the renamed table is the parent table. */
- if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){
- sqlite3NestedParse(pParse,
- "UPDATE \"%w\".%s SET "
- "sql = sqlite_rename_parent(sql, %Q, %Q) "
- "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere);
- sqlite3DbFree(db, zWhere);
- }
- }
-#endif
-
- /* Modify the sqlite_master table to use the new table name. */
- sqlite3NestedParse(pParse,
- "UPDATE %Q.%s SET "
-#ifdef SQLITE_OMIT_TRIGGER
- "sql = sqlite_rename_table(sql, %Q), "
-#else
- "sql = CASE "
- "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
- "ELSE sqlite_rename_table(sql, %Q) END, "
-#endif
- "tbl_name = %Q, "
- "name = CASE "
- "WHEN type='table' THEN %Q "
- "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
- "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
- "ELSE name END "
- "WHERE tbl_name=%Q COLLATE nocase AND "
- "(type='table' OR type='index' OR type='trigger');",
- zDb, SCHEMA_TABLE(iDb), zName, zName, zName,
-#ifndef SQLITE_OMIT_TRIGGER
- zName,
-#endif
- zName, nTabName, zTabName
- );
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- /* If the sqlite_sequence table exists in this database, then update
- ** it with the new table name.
- */
- if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
- sqlite3NestedParse(pParse,
- "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q",
- zDb, zName, pTab->zName);
- }
-#endif
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* If there are TEMP triggers on this table, modify the sqlite_temp_master
- ** table. Don't do this if the table being ALTERed is itself located in
- ** the temp database.
- */
- if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
- sqlite3NestedParse(pParse,
- "UPDATE sqlite_temp_master SET "
- "sql = sqlite_rename_trigger(sql, %Q), "
- "tbl_name = %Q "
- "WHERE %s;", zName, zName, zWhere);
- sqlite3DbFree(db, zWhere);
- }
-#endif
-
-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- if( db->flags&SQLITE_ForeignKeys ){
- FKey *p;
- for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- Table *pFrom = p->pFrom;
- if( pFrom!=pTab ){
- reloadTableSchema(pParse, p->pFrom, pFrom->zName);
- }
- }
- }
-#endif
-
- /* Drop and reload the internal table schema. */
- reloadTableSchema(pParse, pTab, zName);
-
-exit_rename_table:
- sqlite3SrcListDelete(db, pSrc);
- sqlite3DbFree(db, zName);
- db->flags = savedDbFlags;
-}
-
-
-/*
-** Generate code to make sure the file format number is at least minFormat.
-** The generated code will increase the file format number if necessary.
-*/
-SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
- Vdbe *v;
- v = sqlite3GetVdbe(pParse);
- /* The VDBE should have been allocated before this routine is called.
- ** If that allocation failed, we would have quit before reaching this
- ** point */
- if( ALWAYS(v) ){
- int r1 = sqlite3GetTempReg(pParse);
- int r2 = sqlite3GetTempReg(pParse);
- int j1;
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
- sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
- j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ReleaseTempReg(pParse, r2);
- }
-}
-
-/*
-** This function is called after an "ALTER TABLE ... ADD" statement
-** has been parsed. Argument pColDef contains the text of the new
-** column definition.
-**
-** The Table structure pParse->pNewTable was extended to include
-** the new column during parsing.
-*/
-SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
- Table *pNew; /* Copy of pParse->pNewTable */
- Table *pTab; /* Table being altered */
- int iDb; /* Database number */
- const char *zDb; /* Database name */
- const char *zTab; /* Table name */
- char *zCol; /* Null-terminated column definition */
- Column *pCol; /* The new column */
- Expr *pDflt; /* Default value for the new column */
- sqlite3 *db; /* The database connection; */
-
- db = pParse->db;
- if( pParse->nErr || db->mallocFailed ) return;
- pNew = pParse->pNewTable;
- assert( pNew );
-
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
- zDb = db->aDb[iDb].zName;
- zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */
- pCol = &pNew->aCol[pNew->nCol-1];
- pDflt = pCol->pDflt;
- pTab = sqlite3FindTable(db, zTab, zDb);
- assert( pTab );
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- /* Invoke the authorization callback. */
- if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
- return;
- }
-#endif
-
- /* If the default value for the new column was specified with a
- ** literal NULL, then set pDflt to 0. This simplifies checking
- ** for an SQL NULL default below.
- */
- if( pDflt && pDflt->op==TK_NULL ){
- pDflt = 0;
- }
-
- /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
- ** If there is a NOT NULL constraint, then the default value for the
- ** column must not be NULL.
- */
- if( pCol->colFlags & COLFLAG_PRIMKEY ){
- sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
- return;
- }
- if( pNew->pIndex ){
- sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
- return;
- }
- if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
- sqlite3ErrorMsg(pParse,
- "Cannot add a REFERENCES column with non-NULL default value");
- return;
- }
- if( pCol->notNull && !pDflt ){
- sqlite3ErrorMsg(pParse,
- "Cannot add a NOT NULL column with default value NULL");
- return;
- }
-
- /* Ensure the default expression is something that sqlite3ValueFromExpr()
- ** can handle (i.e. not CURRENT_TIME etc.)
- */
- if( pDflt ){
- sqlite3_value *pVal;
- if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
- db->mallocFailed = 1;
- return;
- }
- if( !pVal ){
- sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
- return;
- }
- sqlite3ValueFree(pVal);
- }
-
- /* Modify the CREATE TABLE statement. */
- zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
- if( zCol ){
- char *zEnd = &zCol[pColDef->n-1];
- int savedDbFlags = db->flags;
- while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
- *zEnd-- = '\0';
- }
- db->flags |= SQLITE_PreferBuiltin;
- sqlite3NestedParse(pParse,
- "UPDATE \"%w\".%s SET "
- "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
- "WHERE type = 'table' AND name = %Q",
- zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
- zTab
- );
- sqlite3DbFree(db, zCol);
- db->flags = savedDbFlags;
- }
-
- /* If the default value of the new column is NULL, then set the file
- ** format to 2. If the default value of the new column is not NULL,
- ** the file format becomes 3.
- */
- sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
-
- /* Reload the schema of the modified table. */
- reloadTableSchema(pParse, pTab, pTab->zName);
-}
-
-/*
-** This function is called by the parser after the table-name in
-** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument
-** pSrc is the full-name of the table being altered.
-**
-** This routine makes a (partial) copy of the Table structure
-** for the table being altered and sets Parse.pNewTable to point
-** to it. Routines called by the parser as the column definition
-** is parsed (i.e. sqlite3AddColumn()) add the new Column data to
-** the copy. The copy of the Table structure is deleted by tokenize.c
-** after parsing is finished.
-**
-** Routine sqlite3AlterFinishAddColumn() will be called to complete
-** coding the "ALTER TABLE ... ADD" statement.
-*/
-SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
- Table *pNew;
- Table *pTab;
- Vdbe *v;
- int iDb;
- int i;
- int nAlloc;
- sqlite3 *db = pParse->db;
-
- /* Look up the table being altered. */
- assert( pParse->pNewTable==0 );
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- if( db->mallocFailed ) goto exit_begin_add_column;
- pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
- if( !pTab ) goto exit_begin_add_column;
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- sqlite3ErrorMsg(pParse, "virtual tables may not be altered");
- goto exit_begin_add_column;
- }
-#endif
-
- /* Make sure this is not an attempt to ALTER a view. */
- if( pTab->pSelect ){
- sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
- goto exit_begin_add_column;
- }
- if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
- goto exit_begin_add_column;
- }
-
- assert( pTab->addColOffset>0 );
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
-
- /* Put a copy of the Table struct in Parse.pNewTable for the
- ** sqlite3AddColumn() function and friends to modify. But modify
- ** the name by adding an "sqlite_altertab_" prefix. By adding this
- ** prefix, we insure that the name will not collide with an existing
- ** table because user table are not allowed to have the "sqlite_"
- ** prefix on their name.
- */
- pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
- if( !pNew ) goto exit_begin_add_column;
- pParse->pNewTable = pNew;
- pNew->nRef = 1;
- pNew->nCol = pTab->nCol;
- assert( pNew->nCol>0 );
- nAlloc = (((pNew->nCol-1)/8)*8)+8;
- assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
- pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc);
- pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);
- if( !pNew->aCol || !pNew->zName ){
- db->mallocFailed = 1;
- goto exit_begin_add_column;
- }
- memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
- for(i=0; i<pNew->nCol; i++){
- Column *pCol = &pNew->aCol[i];
- pCol->zName = sqlite3DbStrDup(db, pCol->zName);
- pCol->zColl = 0;
- pCol->zType = 0;
- pCol->pDflt = 0;
- pCol->zDflt = 0;
- }
- pNew->pSchema = db->aDb[iDb].pSchema;
- pNew->addColOffset = pTab->addColOffset;
- pNew->nRef = 1;
-
- /* Begin a transaction and increment the schema cookie. */
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- v = sqlite3GetVdbe(pParse);
- if( !v ) goto exit_begin_add_column;
- sqlite3ChangeCookie(pParse, iDb);
-
-exit_begin_add_column:
- sqlite3SrcListDelete(db, pSrc);
- return;
-}
-#endif /* SQLITE_ALTER_TABLE */
-
-/************** End of alter.c ***********************************************/
-/************** Begin file analyze.c *****************************************/
-/*
-** 2005 July 8
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code associated with the ANALYZE command.
-**
-** The ANALYZE command gather statistics about the content of tables
-** and indices. These statistics are made available to the query planner
-** to help it make better decisions about how to perform queries.
-**
-** The following system tables are or have been supported:
-**
-** CREATE TABLE sqlite_stat1(tbl, idx, stat);
-** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample);
-** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample);
-**
-** Additional tables might be added in future releases of SQLite.
-** The sqlite_stat2 table is not created or used unless the SQLite version
-** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
-** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated.
-** The sqlite_stat2 table is superceded by sqlite_stat3, which is only
-** created and used by SQLite versions 3.7.9 and later and with
-** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3
-** is a superset of sqlite_stat2.
-**
-** Format of sqlite_stat1:
-**
-** There is normally one row per index, with the index identified by the
-** name in the idx column. The tbl column is the name of the table to
-** which the index belongs. In each such row, the stat column will be
-** a string consisting of a list of integers. The first integer in this
-** list is the number of rows in the index and in the table. The second
-** integer is the average number of rows in the index that have the same
-** value in the first column of the index. The third integer is the average
-** number of rows in the index that have the same value for the first two
-** columns. The N-th integer (for N>1) is the average number of rows in
-** the index which have the same value for the first N-1 columns. For
-** a K-column index, there will be K+1 integers in the stat column. If
-** the index is unique, then the last integer will be 1.
-**
-** The list of integers in the stat column can optionally be followed
-** by the keyword "unordered". The "unordered" keyword, if it is present,
-** must be separated from the last integer by a single space. If the
-** "unordered" keyword is present, then the query planner assumes that
-** the index is unordered and will not use the index for a range query.
-**
-** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat
-** column contains a single integer which is the (estimated) number of
-** rows in the table identified by sqlite_stat1.tbl.
-**
-** Format of sqlite_stat2:
-**
-** The sqlite_stat2 is only created and is only used if SQLite is compiled
-** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between
-** 3.6.18 and 3.7.8. The "stat2" table contains additional information
-** about the distribution of keys within an index. The index is identified by
-** the "idx" column and the "tbl" column is the name of the table to which
-** the index belongs. There are usually 10 rows in the sqlite_stat2
-** table for each index.
-**
-** The sqlite_stat2 entries for an index that have sampleno between 0 and 9
-** inclusive are samples of the left-most key value in the index taken at
-** evenly spaced points along the index. Let the number of samples be S
-** (10 in the standard build) and let C be the number of rows in the index.
-** Then the sampled rows are given by:
-**
-** rownumber = (i*C*2 + C)/(S*2)
-**
-** For i between 0 and S-1. Conceptually, the index space is divided into
-** S uniform buckets and the samples are the middle row from each bucket.
-**
-** The format for sqlite_stat2 is recorded here for legacy reference. This
-** version of SQLite does not support sqlite_stat2. It neither reads nor
-** writes the sqlite_stat2 table. This version of SQLite only supports
-** sqlite_stat3.
-**
-** Format for sqlite_stat3:
-**
-** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is
-** used to avoid compatibility problems.
-**
-** The format of the sqlite_stat3 table is similar to the format of
-** the sqlite_stat2 table. There are multiple entries for each index.
-** The idx column names the index and the tbl column is the table of the
-** index. If the idx and tbl columns are the same, then the sample is
-** of the INTEGER PRIMARY KEY. The sample column is a value taken from
-** the left-most column of the index. The nEq column is the approximate
-** number of entires in the index whose left-most column exactly matches
-** the sample. nLt is the approximate number of entires whose left-most
-** column is less than the sample. The nDLt column is the approximate
-** number of distinct left-most entries in the index that are less than
-** the sample.
-**
-** Future versions of SQLite might change to store a string containing
-** multiple integers values in the nDLt column of sqlite_stat3. The first
-** integer will be the number of prior index entires that are distinct in
-** the left-most column. The second integer will be the number of prior index
-** entries that are distinct in the first two columns. The third integer
-** will be the number of prior index entries that are distinct in the first
-** three columns. And so forth. With that extension, the nDLt field is
-** similar in function to the sqlite_stat1.stat field.
-**
-** There can be an arbitrary number of sqlite_stat3 entries per index.
-** The ANALYZE command will typically generate sqlite_stat3 tables
-** that contain between 10 and 40 samples which are distributed across
-** the key space, though not uniformly, and which include samples with
-** largest possible nEq values.
-*/
-#ifndef SQLITE_OMIT_ANALYZE
-
-/*
-** This routine generates code that opens the sqlite_stat1 table for
-** writing with cursor iStatCur. If the library was built with the
-** SQLITE_ENABLE_STAT3 macro defined, then the sqlite_stat3 table is
-** opened for writing using cursor (iStatCur+1)
-**
-** If the sqlite_stat1 tables does not previously exist, it is created.
-** Similarly, if the sqlite_stat3 table does not exist and the library
-** is compiled with SQLITE_ENABLE_STAT3 defined, it is created.
-**
-** Argument zWhere may be a pointer to a buffer containing a table name,
-** or it may be a NULL pointer. If it is not NULL, then all entries in
-** the sqlite_stat1 and (if applicable) sqlite_stat3 tables associated
-** with the named table are deleted. If zWhere==0, then code is generated
-** to delete all stat table entries.
-*/
-static void openStatTable(
- Parse *pParse, /* Parsing context */
- int iDb, /* The database we are looking in */
- int iStatCur, /* Open the sqlite_stat1 table on this cursor */
- const char *zWhere, /* Delete entries for this table or index */
- const char *zWhereType /* Either "tbl" or "idx" */
-){
- static const struct {
- const char *zName;
- const char *zCols;
- } aTable[] = {
- { "sqlite_stat1", "tbl,idx,stat" },
-#ifdef SQLITE_ENABLE_STAT3
- { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
-#endif
- };
-
- int aRoot[] = {0, 0};
- u8 aCreateTbl[] = {0, 0};
-
- int i;
- sqlite3 *db = pParse->db;
- Db *pDb;
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- assert( sqlite3VdbeDb(v)==db );
- pDb = &db->aDb[iDb];
-
- /* Create new statistic tables if they do not exist, or clear them
- ** if they do already exist.
- */
- for(i=0; i<ArraySize(aTable); i++){
- const char *zTab = aTable[i].zName;
- Table *pStat;
- if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
- /* The sqlite_stat[12] table does not exist. Create it. Note that a
- ** side-effect of the CREATE TABLE statement is to leave the rootpage
- ** of the new table in register pParse->regRoot. This is important
- ** because the OpenWrite opcode below will be needing it. */
- sqlite3NestedParse(pParse,
- "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
- );
- aRoot[i] = pParse->regRoot;
- aCreateTbl[i] = OPFLAG_P2ISREG;
- }else{
- /* The table already exists. If zWhere is not NULL, delete all entries
- ** associated with the table zWhere. If zWhere is NULL, delete the
- ** entire contents of the table. */
- aRoot[i] = pStat->tnum;
- sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
- if( zWhere ){
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere
- );
- }else{
- /* The sqlite_stat[12] table already exists. Delete all rows. */
- sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
- }
- }
- }
-
- /* Open the sqlite_stat[13] tables for writing. */
- for(i=0; i<ArraySize(aTable); i++){
- sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
- sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
- sqlite3VdbeChangeP5(v, aCreateTbl[i]);
- }
-}
-
-/*
-** Recommended number of samples for sqlite_stat3
-*/
-#ifndef SQLITE_STAT3_SAMPLES
-# define SQLITE_STAT3_SAMPLES 24
-#endif
-
-/*
-** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() -
-** share an instance of the following structure to hold their state
-** information.
-*/
-typedef struct Stat3Accum Stat3Accum;
-struct Stat3Accum {
- tRowcnt nRow; /* Number of rows in the entire table */
- tRowcnt nPSample; /* How often to do a periodic sample */
- int iMin; /* Index of entry with minimum nEq and hash */
- int mxSample; /* Maximum number of samples to accumulate */
- int nSample; /* Current number of samples */
- u32 iPrn; /* Pseudo-random number used for sampling */
- struct Stat3Sample {
- i64 iRowid; /* Rowid in main table of the key */
- tRowcnt nEq; /* sqlite_stat3.nEq */
- tRowcnt nLt; /* sqlite_stat3.nLt */
- tRowcnt nDLt; /* sqlite_stat3.nDLt */
- u8 isPSample; /* True if a periodic sample */
- u32 iHash; /* Tiebreaker hash */
- } *a; /* An array of samples */
-};
-
-#ifdef SQLITE_ENABLE_STAT3
-/*
-** Implementation of the stat3_init(C,S) SQL function. The two parameters
-** are the number of rows in the table or index (C) and the number of samples
-** to accumulate (S).
-**
-** This routine allocates the Stat3Accum object.
-**
-** The return value is the Stat3Accum object (P).
-*/
-static void stat3Init(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- Stat3Accum *p;
- tRowcnt nRow;
- int mxSample;
- int n;
-
- UNUSED_PARAMETER(argc);
- nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
- mxSample = sqlite3_value_int(argv[1]);
- n = sizeof(*p) + sizeof(p->a[0])*mxSample;
- p = sqlite3MallocZero( n );
- if( p==0 ){
- sqlite3_result_error_nomem(context);
- return;
- }
- p->a = (struct Stat3Sample*)&p[1];
- p->nRow = nRow;
- p->mxSample = mxSample;
- p->nPSample = p->nRow/(mxSample/3+1) + 1;
- sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
- sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
-}
-static const FuncDef stat3InitFuncdef = {
- 2, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- stat3Init, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "stat3_init", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
-};
-
-
-/*
-** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function. The
-** arguments describe a single key instance. This routine makes the
-** decision about whether or not to retain this key for the sqlite_stat3
-** table.
-**
-** The return value is NULL.
-*/
-static void stat3Push(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[4]);
- tRowcnt nEq = sqlite3_value_int64(argv[0]);
- tRowcnt nLt = sqlite3_value_int64(argv[1]);
- tRowcnt nDLt = sqlite3_value_int64(argv[2]);
- i64 rowid = sqlite3_value_int64(argv[3]);
- u8 isPSample = 0;
- u8 doInsert = 0;
- int iMin = p->iMin;
- struct Stat3Sample *pSample;
- int i;
- u32 h;
-
- UNUSED_PARAMETER(context);
- UNUSED_PARAMETER(argc);
- if( nEq==0 ) return;
- h = p->iPrn = p->iPrn*1103515245 + 12345;
- if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){
- doInsert = isPSample = 1;
- }else if( p->nSample<p->mxSample ){
- doInsert = 1;
- }else{
- if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){
- doInsert = 1;
- }
- }
- if( !doInsert ) return;
- if( p->nSample==p->mxSample ){
- assert( p->nSample - iMin - 1 >= 0 );
- memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1));
- pSample = &p->a[p->nSample-1];
- }else{
- pSample = &p->a[p->nSample++];
- }
- pSample->iRowid = rowid;
- pSample->nEq = nEq;
- pSample->nLt = nLt;
- pSample->nDLt = nDLt;
- pSample->iHash = h;
- pSample->isPSample = isPSample;
-
- /* Find the new minimum */
- if( p->nSample==p->mxSample ){
- pSample = p->a;
- i = 0;
- while( pSample->isPSample ){
- i++;
- pSample++;
- assert( i<p->nSample );
- }
- nEq = pSample->nEq;
- h = pSample->iHash;
- iMin = i;
- for(i++, pSample++; i<p->nSample; i++, pSample++){
- if( pSample->isPSample ) continue;
- if( pSample->nEq<nEq
- || (pSample->nEq==nEq && pSample->iHash<h)
- ){
- iMin = i;
- nEq = pSample->nEq;
- h = pSample->iHash;
- }
- }
- p->iMin = iMin;
- }
-}
-static const FuncDef stat3PushFuncdef = {
- 5, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- stat3Push, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "stat3_push", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
-};
-
-/*
-** Implementation of the stat3_get(P,N,...) SQL function. This routine is
-** used to query the results. Content is returned for the Nth sqlite_stat3
-** row where N is between 0 and S-1 and S is the number of samples. The
-** value returned depends on the number of arguments.
-**
-** argc==2 result: rowid
-** argc==3 result: nEq
-** argc==4 result: nLt
-** argc==5 result: nDLt
-*/
-static void stat3Get(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int n = sqlite3_value_int(argv[1]);
- Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]);
-
- assert( p!=0 );
- if( p->nSample<=n ) return;
- switch( argc ){
- case 2: sqlite3_result_int64(context, p->a[n].iRowid); break;
- case 3: sqlite3_result_int64(context, p->a[n].nEq); break;
- case 4: sqlite3_result_int64(context, p->a[n].nLt); break;
- default: sqlite3_result_int64(context, p->a[n].nDLt); break;
- }
-}
-static const FuncDef stat3GetFuncdef = {
- -1, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- stat3Get, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "stat3_get", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
-};
-#endif /* SQLITE_ENABLE_STAT3 */
-
-
-
-
-/*
-** Generate code to do an analysis of all indices associated with
-** a single table.
-*/
-static void analyzeOneTable(
- Parse *pParse, /* Parser context */
- Table *pTab, /* Table whose indices are to be analyzed */
- Index *pOnlyIdx, /* If not NULL, only analyze this one index */
- int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */
- int iMem /* Available memory locations begin here */
-){
- sqlite3 *db = pParse->db; /* Database handle */
- Index *pIdx; /* An index to being analyzed */
- int iIdxCur; /* Cursor open on index being analyzed */
- Vdbe *v; /* The virtual machine being built up */
- int i; /* Loop counter */
- int topOfLoop; /* The top of the loop */
- int endOfLoop; /* The end of the loop */
- int jZeroRows = -1; /* Jump from here if number of rows is zero */
- int iDb; /* Index of database containing pTab */
- int regTabname = iMem++; /* Register containing table name */
- int regIdxname = iMem++; /* Register containing index name */
- int regStat1 = iMem++; /* The stat column of sqlite_stat1 */
-#ifdef SQLITE_ENABLE_STAT3
- int regNumEq = regStat1; /* Number of instances. Same as regStat1 */
- int regNumLt = iMem++; /* Number of keys less than regSample */
- int regNumDLt = iMem++; /* Number of distinct keys less than regSample */
- int regSample = iMem++; /* The next sample value */
- int regRowid = regSample; /* Rowid of a sample */
- int regAccum = iMem++; /* Register to hold Stat3Accum object */
- int regLoop = iMem++; /* Loop counter */
- int regCount = iMem++; /* Number of rows in the table or index */
- int regTemp1 = iMem++; /* Intermediate register */
- int regTemp2 = iMem++; /* Intermediate register */
- int once = 1; /* One-time initialization */
- int shortJump = 0; /* Instruction address */
- int iTabCur = pParse->nTab++; /* Table cursor */
-#endif
- int regCol = iMem++; /* Content of a column in analyzed table */
- int regRec = iMem++; /* Register holding completed record */
- int regTemp = iMem++; /* Temporary use register */
- int regNewRowid = iMem++; /* Rowid for the inserted record */
-
-
- v = sqlite3GetVdbe(pParse);
- if( v==0 || NEVER(pTab==0) ){
- return;
- }
- if( pTab->tnum==0 ){
- /* Do not gather statistics on views or virtual tables */
- return;
- }
- if( memcmp(pTab->zName, "sqlite_", 7)==0 ){
- /* Do not gather statistics on system tables */
- return;
- }
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( iDb>=0 );
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
-#ifndef SQLITE_OMIT_AUTHORIZATION
- if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
- db->aDb[iDb].zName ) ){
- return;
- }
-#endif
-
- /* Establish a read-lock on the table at the shared-cache level. */
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
-
- iIdxCur = pParse->nTab++;
- sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- int nCol;
- KeyInfo *pKey;
- int addrIfNot = 0; /* address of OP_IfNot */
- int *aChngAddr; /* Array of jump instruction addresses */
-
- if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
- VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
- nCol = pIdx->nColumn;
- aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
- if( aChngAddr==0 ) continue;
- pKey = sqlite3IndexKeyinfo(pParse, pIdx);
- if( iMem+1+(nCol*2)>pParse->nMem ){
- pParse->nMem = iMem+1+(nCol*2);
- }
-
- /* Open a cursor to the index to be analyzed. */
- assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
- sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
- (char *)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIdx->zName));
-
- /* Populate the register containing the index name. */
- sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
-
-#ifdef SQLITE_ENABLE_STAT3
- if( once ){
- once = 0;
- sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
- }
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount);
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt);
- sqlite3VdbeAddOp3(v, OP_Null, 0, regSample, regAccum);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum,
- (char*)&stat3InitFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 2);
-#endif /* SQLITE_ENABLE_STAT3 */
-
- /* The block of memory cells initialized here is used as follows.
- **
- ** iMem:
- ** The total number of rows in the table.
- **
- ** iMem+1 .. iMem+nCol:
- ** Number of distinct entries in index considering the
- ** left-most N columns only, where N is between 1 and nCol,
- ** inclusive.
- **
- ** iMem+nCol+1 .. Mem+2*nCol:
- ** Previous value of indexed columns, from left to right.
- **
- ** Cells iMem through iMem+nCol are initialized to 0. The others are
- ** initialized to contain an SQL NULL.
- */
- for(i=0; i<=nCol; i++){
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i);
- }
- for(i=0; i<nCol; i++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1);
- }
-
- /* Start the analysis loop. This loop runs through all the entries in
- ** the index b-tree. */
- endOfLoop = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
- topOfLoop = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); /* Increment row counter */
-
- for(i=0; i<nCol; i++){
- CollSeq *pColl;
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
- if( i==0 ){
- /* Always record the very first row */
- addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
- }
- assert( pIdx->azColl!=0 );
- assert( pIdx->azColl[i]!=0 );
- pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
- aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
- (char*)pColl, P4_COLLSEQ);
- sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
- VdbeComment((v, "jump if column %d changed", i));
-#ifdef SQLITE_ENABLE_STAT3
- if( i==0 ){
- sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1);
- VdbeComment((v, "incr repeat count"));
- }
-#endif
- }
- sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
- for(i=0; i<nCol; i++){
- sqlite3VdbeJumpHere(v, aChngAddr[i]); /* Set jump dest for the OP_Ne */
- if( i==0 ){
- sqlite3VdbeJumpHere(v, addrIfNot); /* Jump dest for OP_IfNot */
-#ifdef SQLITE_ENABLE_STAT3
- sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
- (char*)&stat3PushFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 5);
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid);
- sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt);
- sqlite3VdbeAddOp2(v, OP_AddImm, regNumDLt, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq);
-#endif
- }
- sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
- }
- sqlite3DbFree(db, aChngAddr);
-
- /* Always jump here after updating the iMem+1...iMem+1+nCol counters */
- sqlite3VdbeResolveLabel(v, endOfLoop);
-
- sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
- sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
-#ifdef SQLITE_ENABLE_STAT3
- sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
- (char*)&stat3PushFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 5);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop);
- shortJump =
- sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1,
- (char*)&stat3GetFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 2);
- sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1);
- sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1);
- sqlite3VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample);
- sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq,
- (char*)&stat3GetFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 3);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt,
- (char*)&stat3GetFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 4);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt,
- (char*)&stat3GetFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 5);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0);
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump);
- sqlite3VdbeJumpHere(v, shortJump+2);
-#endif
-
- /* Store the results in sqlite_stat1.
- **
- ** The result is a single row of the sqlite_stat1 table. The first
- ** two columns are the names of the table and index. The third column
- ** is a string composed of a list of integer statistics about the
- ** index. The first integer in the list is the total number of entries
- ** in the index. There is one additional integer in the list for each
- ** column of the table. This additional integer is a guess of how many
- ** rows of the table the index will select. If D is the count of distinct
- ** values and K is the total number of rows, then the integer is computed
- ** as:
- **
- ** I = (K+D-1)/D
- **
- ** If K==0 then no entry is made into the sqlite_stat1 table.
- ** If K>0 then it is always the case the D>0 so division by zero
- ** is never possible.
- */
- sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
- if( jZeroRows<0 ){
- jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
- }
- for(i=0; i<nCol; i++){
- sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
- sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
- sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
- sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
- sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
- sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
- sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
- }
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- }
-
- /* If the table has no indices, create a single sqlite_stat1 entry
- ** containing NULL as the index name and the row count as the content.
- */
- if( pTab->pIndex==0 ){
- sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
- VdbeComment((v, "%s", pTab->zName));
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
- sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
- jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
- }else{
- sqlite3VdbeJumpHere(v, jZeroRows);
- jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
- }
- sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- if( pParse->nMem<regRec ) pParse->nMem = regRec;
- sqlite3VdbeJumpHere(v, jZeroRows);
-}
-
-
-/*
-** Generate code that will cause the most recent index analysis to
-** be loaded into internal hash tables where is can be used.
-*/
-static void loadAnalysis(Parse *pParse, int iDb){
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb);
- }
-}
-
-/*
-** Generate code that will do an analysis of an entire database
-*/
-static void analyzeDatabase(Parse *pParse, int iDb){
- sqlite3 *db = pParse->db;
- Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */
- HashElem *k;
- int iStatCur;
- int iMem;
-
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- iStatCur = pParse->nTab;
- pParse->nTab += 3;
- openStatTable(pParse, iDb, iStatCur, 0, 0);
- iMem = pParse->nMem+1;
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
- Table *pTab = (Table*)sqliteHashData(k);
- analyzeOneTable(pParse, pTab, 0, iStatCur, iMem);
- }
- loadAnalysis(pParse, iDb);
-}
-
-/*
-** Generate code that will do an analysis of a single table in
-** a database. If pOnlyIdx is not NULL then it is a single index
-** in pTab that should be analyzed.
-*/
-static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){
- int iDb;
- int iStatCur;
-
- assert( pTab!=0 );
- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- iStatCur = pParse->nTab;
- pParse->nTab += 3;
- if( pOnlyIdx ){
- openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx");
- }else{
- openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
- }
- analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1);
- loadAnalysis(pParse, iDb);
-}
-
-/*
-** Generate code for the ANALYZE command. The parser calls this routine
-** when it recognizes an ANALYZE command.
-**
-** ANALYZE -- 1
-** ANALYZE <database> -- 2
-** ANALYZE ?<database>.?<tablename> -- 3
-**
-** Form 1 causes all indices in all attached databases to be analyzed.
-** Form 2 analyzes all indices the single database named.
-** Form 3 analyzes all indices associated with the named table.
-*/
-SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
- sqlite3 *db = pParse->db;
- int iDb;
- int i;
- char *z, *zDb;
- Table *pTab;
- Index *pIdx;
- Token *pTableName;
-
- /* Read the database schema. If an error occurs, leave an error message
- ** and code in pParse and return NULL. */
- assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- return;
- }
-
- assert( pName2!=0 || pName1==0 );
- if( pName1==0 ){
- /* Form 1: Analyze everything */
- for(i=0; i<db->nDb; i++){
- if( i==1 ) continue; /* Do not analyze the TEMP database */
- analyzeDatabase(pParse, i);
- }
- }else if( pName2->n==0 ){
- /* Form 2: Analyze the database or table named */
- iDb = sqlite3FindDb(db, pName1);
- if( iDb>=0 ){
- analyzeDatabase(pParse, iDb);
- }else{
- z = sqlite3NameFromToken(db, pName1);
- if( z ){
- if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){
- analyzeTable(pParse, pIdx->pTable, pIdx);
- }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){
- analyzeTable(pParse, pTab, 0);
- }
- sqlite3DbFree(db, z);
- }
- }
- }else{
- /* Form 3: Analyze the fully qualified table name */
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
- if( iDb>=0 ){
- zDb = db->aDb[iDb].zName;
- z = sqlite3NameFromToken(db, pTableName);
- if( z ){
- if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
- analyzeTable(pParse, pIdx->pTable, pIdx);
- }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){
- analyzeTable(pParse, pTab, 0);
- }
- sqlite3DbFree(db, z);
- }
- }
- }
-}
-
-/*
-** Used to pass information from the analyzer reader through to the
-** callback routine.
-*/
-typedef struct analysisInfo analysisInfo;
-struct analysisInfo {
- sqlite3 *db;
- const char *zDatabase;
-};
-
-/*
-** This callback is invoked once for each index when reading the
-** sqlite_stat1 table.
-**
-** argv[0] = name of the table
-** argv[1] = name of the index (might be NULL)
-** argv[2] = results of analysis - on integer for each column
-**
-** Entries for which argv[1]==NULL simply record the number of rows in
-** the table.
-*/
-static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
- analysisInfo *pInfo = (analysisInfo*)pData;
- Index *pIndex;
- Table *pTable;
- int i, c, n;
- tRowcnt v;
- const char *z;
-
- assert( argc==3 );
- UNUSED_PARAMETER2(NotUsed, argc);
-
- if( argv==0 || argv[0]==0 || argv[2]==0 ){
- return 0;
- }
- pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase);
- if( pTable==0 ){
- return 0;
- }
- if( argv[1] ){
- pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
- }else{
- pIndex = 0;
- }
- n = pIndex ? pIndex->nColumn : 0;
- z = argv[2];
- for(i=0; *z && i<=n; i++){
- v = 0;
- while( (c=z[0])>='0' && c<='9' ){
- v = v*10 + c - '0';
- z++;
- }
- if( i==0 ) pTable->nRowEst = v;
- if( pIndex==0 ) break;
- pIndex->aiRowEst[i] = v;
- if( *z==' ' ) z++;
- if( memcmp(z, "unordered", 10)==0 ){
- pIndex->bUnordered = 1;
- break;
- }
- }
- return 0;
-}
-
-/*
-** If the Index.aSample variable is not NULL, delete the aSample[] array
-** and its contents.
-*/
-SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
-#ifdef SQLITE_ENABLE_STAT3
- if( pIdx->aSample ){
- int j;
- for(j=0; j<pIdx->nSample; j++){
- IndexSample *p = &pIdx->aSample[j];
- if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
- sqlite3DbFree(db, p->u.z);
- }
- }
- sqlite3DbFree(db, pIdx->aSample);
- }
- if( db && db->pnBytesFreed==0 ){
- pIdx->nSample = 0;
- pIdx->aSample = 0;
- }
-#else
- UNUSED_PARAMETER(db);
- UNUSED_PARAMETER(pIdx);
-#endif
-}
-
-#ifdef SQLITE_ENABLE_STAT3
-/*
-** Load content from the sqlite_stat3 table into the Index.aSample[]
-** arrays of all indices.
-*/
-static int loadStat3(sqlite3 *db, const char *zDb){
- int rc; /* Result codes from subroutines */
- sqlite3_stmt *pStmt = 0; /* An SQL statement being run */
- char *zSql; /* Text of the SQL statement */
- Index *pPrevIdx = 0; /* Previous index in the loop */
- int idx = 0; /* slot in pIdx->aSample[] for next sample */
- int eType; /* Datatype of a sample */
- IndexSample *pSample; /* A slot in pIdx->aSample[] */
-
- assert( db->lookaside.bEnabled==0 );
- if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){
- return SQLITE_OK;
- }
-
- zSql = sqlite3MPrintf(db,
- "SELECT idx,count(*) FROM %Q.sqlite_stat3"
- " GROUP BY idx", zDb);
- if( !zSql ){
- return SQLITE_NOMEM;
- }
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
- sqlite3DbFree(db, zSql);
- if( rc ) return rc;
-
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
- char *zIndex; /* Index name */
- Index *pIdx; /* Pointer to the index object */
- int nSample; /* Number of samples */
-
- zIndex = (char *)sqlite3_column_text(pStmt, 0);
- if( zIndex==0 ) continue;
- nSample = sqlite3_column_int(pStmt, 1);
- pIdx = sqlite3FindIndex(db, zIndex, zDb);
- if( pIdx==0 ) continue;
- assert( pIdx->nSample==0 );
- pIdx->nSample = nSample;
- pIdx->aSample = sqlite3DbMallocZero(db, nSample*sizeof(IndexSample));
- pIdx->avgEq = pIdx->aiRowEst[1];
- if( pIdx->aSample==0 ){
- db->mallocFailed = 1;
- sqlite3_finalize(pStmt);
- return SQLITE_NOMEM;
- }
- }
- rc = sqlite3_finalize(pStmt);
- if( rc ) return rc;
-
- zSql = sqlite3MPrintf(db,
- "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb);
- if( !zSql ){
- return SQLITE_NOMEM;
- }
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
- sqlite3DbFree(db, zSql);
- if( rc ) return rc;
-
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
- char *zIndex; /* Index name */
- Index *pIdx; /* Pointer to the index object */
- int i; /* Loop counter */
- tRowcnt sumEq; /* Sum of the nEq values */
-
- zIndex = (char *)sqlite3_column_text(pStmt, 0);
- if( zIndex==0 ) continue;
- pIdx = sqlite3FindIndex(db, zIndex, zDb);
- if( pIdx==0 ) continue;
- if( pIdx==pPrevIdx ){
- idx++;
- }else{
- pPrevIdx = pIdx;
- idx = 0;
- }
- assert( idx<pIdx->nSample );
- pSample = &pIdx->aSample[idx];
- pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 1);
- pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 2);
- pSample->nDLt = (tRowcnt)sqlite3_column_int64(pStmt, 3);
- if( idx==pIdx->nSample-1 ){
- if( pSample->nDLt>0 ){
- for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq;
- pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt;
- }
- if( pIdx->avgEq<=0 ) pIdx->avgEq = 1;
- }
- eType = sqlite3_column_type(pStmt, 4);
- pSample->eType = (u8)eType;
- switch( eType ){
- case SQLITE_INTEGER: {
- pSample->u.i = sqlite3_column_int64(pStmt, 4);
- break;
- }
- case SQLITE_FLOAT: {
- pSample->u.r = sqlite3_column_double(pStmt, 4);
- break;
- }
- case SQLITE_NULL: {
- break;
- }
- default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); {
- const char *z = (const char *)(
- (eType==SQLITE_BLOB) ?
- sqlite3_column_blob(pStmt, 4):
- sqlite3_column_text(pStmt, 4)
- );
- int n = z ? sqlite3_column_bytes(pStmt, 4) : 0;
- pSample->nByte = n;
- if( n < 1){
- pSample->u.z = 0;
- }else{
- pSample->u.z = sqlite3DbMallocRaw(db, n);
- if( pSample->u.z==0 ){
- db->mallocFailed = 1;
- sqlite3_finalize(pStmt);
- return SQLITE_NOMEM;
- }
- memcpy(pSample->u.z, z, n);
- }
- }
- }
- }
- return sqlite3_finalize(pStmt);
-}
-#endif /* SQLITE_ENABLE_STAT3 */
-
-/*
-** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The
-** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
-** arrays. The contents of sqlite_stat3 are used to populate the
-** Index.aSample[] arrays.
-**
-** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
-** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined
-** during compilation and the sqlite_stat3 table is present, no data is
-** read from it.
-**
-** If SQLITE_ENABLE_STAT3 was defined during compilation and the
-** sqlite_stat3 table is not present in the database, SQLITE_ERROR is
-** returned. However, in this case, data is read from the sqlite_stat1
-** table (if it is present) before returning.
-**
-** If an OOM error occurs, this function always sets db->mallocFailed.
-** This means if the caller does not care about other errors, the return
-** code may be ignored.
-*/
-SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
- analysisInfo sInfo;
- HashElem *i;
- char *zSql;
- int rc;
-
- assert( iDb>=0 && iDb<db->nDb );
- assert( db->aDb[iDb].pBt!=0 );
-
- /* Clear any prior statistics */
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
- Index *pIdx = sqliteHashData(i);
- sqlite3DefaultRowEst(pIdx);
-#ifdef SQLITE_ENABLE_STAT3
- sqlite3DeleteIndexSamples(db, pIdx);
- pIdx->aSample = 0;
-#endif
- }
-
- /* Check to make sure the sqlite_stat1 table exists */
- sInfo.db = db;
- sInfo.zDatabase = db->aDb[iDb].zName;
- if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
- return SQLITE_ERROR;
- }
-
- /* Load new statistics out of the sqlite_stat1 table */
- zSql = sqlite3MPrintf(db,
- "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
- if( zSql==0 ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
- sqlite3DbFree(db, zSql);
- }
-
-
- /* Load the statistics from the sqlite_stat3 table. */
-#ifdef SQLITE_ENABLE_STAT3
- if( rc==SQLITE_OK ){
- int lookasideEnabled = db->lookaside.bEnabled;
- db->lookaside.bEnabled = 0;
- rc = loadStat3(db, sInfo.zDatabase);
- db->lookaside.bEnabled = lookasideEnabled;
- }
-#endif
-
- if( rc==SQLITE_NOMEM ){
- db->mallocFailed = 1;
- }
- return rc;
-}
-
-
-#endif /* SQLITE_OMIT_ANALYZE */
-
-/************** End of analyze.c *********************************************/
-/************** Begin file attach.c ******************************************/
-/*
-** 2003 April 6
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code used to implement the ATTACH and DETACH commands.
-*/
-
-#ifndef SQLITE_OMIT_ATTACH
-/*
-** Resolve an expression that was part of an ATTACH or DETACH statement. This
-** is slightly different from resolving a normal SQL expression, because simple
-** identifiers are treated as strings, not possible column names or aliases.
-**
-** i.e. if the parser sees:
-**
-** ATTACH DATABASE abc AS def
-**
-** it treats the two expressions as literal strings 'abc' and 'def' instead of
-** looking for columns of the same name.
-**
-** This only applies to the root node of pExpr, so the statement:
-**
-** ATTACH DATABASE abc||def AS 'db2'
-**
-** will fail because neither abc or def can be resolved.
-*/
-static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
-{
- int rc = SQLITE_OK;
- if( pExpr ){
- if( pExpr->op!=TK_ID ){
- rc = sqlite3ResolveExprNames(pName, pExpr);
- if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
- sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
- return SQLITE_ERROR;
- }
- }else{
- pExpr->op = TK_STRING;
- }
- }
- return rc;
-}
-
-/*
-** An SQL user-function registered to do the work of an ATTACH statement. The
-** three arguments to the function come directly from an attach statement:
-**
-** ATTACH DATABASE x AS y KEY z
-**
-** SELECT sqlite_attach(x, y, z)
-**
-** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
-** third argument.
-*/
-static void attachFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- int i;
- int rc = 0;
- sqlite3 *db = sqlite3_context_db_handle(context);
- const char *zName;
- const char *zFile;
- char *zPath = 0;
- char *zErr = 0;
- unsigned int flags;
- Db *aNew;
- char *zErrDyn = 0;
- sqlite3_vfs *pVfs;
-
- UNUSED_PARAMETER(NotUsed);
-
- zFile = (const char *)sqlite3_value_text(argv[0]);
- zName = (const char *)sqlite3_value_text(argv[1]);
- if( zFile==0 ) zFile = "";
- if( zName==0 ) zName = "";
-
- /* Check for the following errors:
- **
- ** * Too many attached databases,
- ** * Transaction currently open
- ** * Specified database name already being used.
- */
- if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
- zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
- db->aLimit[SQLITE_LIMIT_ATTACHED]
- );
- goto attach_error;
- }
- if( !db->autoCommit ){
- zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction");
- goto attach_error;
- }
- for(i=0; i<db->nDb; i++){
- char *z = db->aDb[i].zName;
- assert( z && zName );
- if( sqlite3StrICmp(z, zName)==0 ){
- zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
- goto attach_error;
- }
- }
-
- /* Allocate the new entry in the db->aDb[] array and initialise the schema
- ** hash tables.
- */
- if( db->aDb==db->aDbStatic ){
- aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 );
- if( aNew==0 ) return;
- memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
- }else{
- aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
- if( aNew==0 ) return;
- }
- db->aDb = aNew;
- aNew = &db->aDb[db->nDb];
- memset(aNew, 0, sizeof(*aNew));
-
- /* Open the database file. If the btree is successfully opened, use
- ** it to obtain the database schema. At this point the schema may
- ** or may not be initialised.
- */
- flags = db->openFlags;
- rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
- return;
- }
- assert( pVfs );
- flags |= SQLITE_OPEN_MAIN_DB;
- rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags);
- sqlite3_free( zPath );
- db->nDb++;
- if( rc==SQLITE_CONSTRAINT ){
- rc = SQLITE_ERROR;
- zErrDyn = sqlite3MPrintf(db, "database is already attached");
- }else if( rc==SQLITE_OK ){
- Pager *pPager;
- aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
- if( !aNew->pSchema ){
- rc = SQLITE_NOMEM;
- }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
- zErrDyn = sqlite3MPrintf(db,
- "attached databases must use the same text encoding as main database");
- rc = SQLITE_ERROR;
- }
- pPager = sqlite3BtreePager(aNew->pBt);
- sqlite3PagerLockingMode(pPager, db->dfltLockMode);
- sqlite3BtreeSecureDelete(aNew->pBt,
- sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
- }
- aNew->safety_level = 3;
- aNew->zName = sqlite3DbStrDup(db, zName);
- if( rc==SQLITE_OK && aNew->zName==0 ){
- rc = SQLITE_NOMEM;
- }
-
-
-#ifdef SQLITE_HAS_CODEC
- if( rc==SQLITE_OK ){
- extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
- extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
- int nKey;
- char *zKey;
- int t = sqlite3_value_type(argv[2]);
- switch( t ){
- case SQLITE_INTEGER:
- case SQLITE_FLOAT:
- zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
- rc = SQLITE_ERROR;
- break;
-
- case SQLITE_TEXT:
- case SQLITE_BLOB:
- nKey = sqlite3_value_bytes(argv[2]);
- zKey = (char *)sqlite3_value_blob(argv[2]);
- rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
- break;
-
- case SQLITE_NULL:
- /* No key specified. Use the key from the main database */
- sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
- if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
- rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
- }
- break;
- }
- }
-#endif
-
- /* If the file was opened successfully, read the schema for the new database.
- ** If this fails, or if opening the file failed, then close the file and
- ** remove the entry from the db->aDb[] array. i.e. put everything back the way
- ** we found it.
- */
- if( rc==SQLITE_OK ){
- sqlite3BtreeEnterAll(db);
- rc = sqlite3Init(db, &zErrDyn);
- sqlite3BtreeLeaveAll(db);
- }
- if( rc ){
- int iDb = db->nDb - 1;
- assert( iDb>=2 );
- if( db->aDb[iDb].pBt ){
- sqlite3BtreeClose(db->aDb[iDb].pBt);
- db->aDb[iDb].pBt = 0;
- db->aDb[iDb].pSchema = 0;
- }
- sqlite3ResetAllSchemasOfConnection(db);
- db->nDb = iDb;
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- db->mallocFailed = 1;
- sqlite3DbFree(db, zErrDyn);
- zErrDyn = sqlite3MPrintf(db, "out of memory");
- }else if( zErrDyn==0 ){
- zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
- }
- goto attach_error;
- }
-
- return;
-
-attach_error:
- /* Return an error if we get here */
- if( zErrDyn ){
- sqlite3_result_error(context, zErrDyn, -1);
- sqlite3DbFree(db, zErrDyn);
- }
- if( rc ) sqlite3_result_error_code(context, rc);
-}
-
-/*
-** An SQL user-function registered to do the work of an DETACH statement. The
-** three arguments to the function come directly from a detach statement:
-**
-** DETACH DATABASE x
-**
-** SELECT sqlite_detach(x)
-*/
-static void detachFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- const char *zName = (const char *)sqlite3_value_text(argv[0]);
- sqlite3 *db = sqlite3_context_db_handle(context);
- int i;
- Db *pDb = 0;
- char zErr[128];
-
- UNUSED_PARAMETER(NotUsed);
-
- if( zName==0 ) zName = "";
- for(i=0; i<db->nDb; i++){
- pDb = &db->aDb[i];
- if( pDb->pBt==0 ) continue;
- if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
- }
-
- if( i>=db->nDb ){
- sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
- goto detach_error;
- }
- if( i<2 ){
- sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
- goto detach_error;
- }
- if( !db->autoCommit ){
- sqlite3_snprintf(sizeof(zErr), zErr,
- "cannot DETACH database within transaction");
- goto detach_error;
- }
- if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
- sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
- goto detach_error;
- }
-
- sqlite3BtreeClose(pDb->pBt);
- pDb->pBt = 0;
- pDb->pSchema = 0;
- sqlite3ResetAllSchemasOfConnection(db);
- return;
-
-detach_error:
- sqlite3_result_error(context, zErr, -1);
-}
-
-/*
-** This procedure generates VDBE code for a single invocation of either the
-** sqlite_detach() or sqlite_attach() SQL user functions.
-*/
-static void codeAttach(
- Parse *pParse, /* The parser context */
- int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */
- FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */
- Expr *pAuthArg, /* Expression to pass to authorization callback */
- Expr *pFilename, /* Name of database file */
- Expr *pDbname, /* Name of the database to use internally */
- Expr *pKey /* Database key for encryption extension */
-){
- int rc;
- NameContext sName;
- Vdbe *v;
- sqlite3* db = pParse->db;
- int regArgs;
-
- memset(&sName, 0, sizeof(NameContext));
- sName.pParse = pParse;
-
- if(
- SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
- SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
- SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
- ){
- pParse->nErr++;
- goto attach_end;
- }
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- if( pAuthArg ){
- char *zAuthArg;
- if( pAuthArg->op==TK_STRING ){
- zAuthArg = pAuthArg->u.zToken;
- }else{
- zAuthArg = 0;
- }
- rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
- if(rc!=SQLITE_OK ){
- goto attach_end;
- }
- }
-#endif /* SQLITE_OMIT_AUTHORIZATION */
-
-
- v = sqlite3GetVdbe(pParse);
- regArgs = sqlite3GetTempRange(pParse, 4);
- sqlite3ExprCode(pParse, pFilename, regArgs);
- sqlite3ExprCode(pParse, pDbname, regArgs+1);
- sqlite3ExprCode(pParse, pKey, regArgs+2);
-
- assert( v || db->mallocFailed );
- if( v ){
- sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3);
- assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
- sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
- sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
-
- /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
- ** statement only). For DETACH, set it to false (expire all existing
- ** statements).
- */
- sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
- }
-
-attach_end:
- sqlite3ExprDelete(db, pFilename);
- sqlite3ExprDelete(db, pDbname);
- sqlite3ExprDelete(db, pKey);
-}
-
-/*
-** Called by the parser to compile a DETACH statement.
-**
-** DETACH pDbname
-*/
-SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){
- static const FuncDef detach_func = {
- 1, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- detachFunc, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "sqlite_detach", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
- };
- codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
-}
-
-/*
-** Called by the parser to compile an ATTACH statement.
-**
-** ATTACH p AS pDbname KEY pKey
-*/
-SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
- static const FuncDef attach_func = {
- 3, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- attachFunc, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "sqlite_attach", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
- };
- codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
-}
-#endif /* SQLITE_OMIT_ATTACH */
-
-/*
-** Initialize a DbFixer structure. This routine must be called prior
-** to passing the structure to one of the sqliteFixAAAA() routines below.
-**
-** The return value indicates whether or not fixation is required. TRUE
-** means we do need to fix the database references, FALSE means we do not.
-*/
-SQLITE_PRIVATE int sqlite3FixInit(
- DbFixer *pFix, /* The fixer to be initialized */
- Parse *pParse, /* Error messages will be written here */
- int iDb, /* This is the database that must be used */
- const char *zType, /* "view", "trigger", or "index" */
- const Token *pName /* Name of the view, trigger, or index */
-){
- sqlite3 *db;
-
- if( NEVER(iDb<0) || iDb==1 ) return 0;
- db = pParse->db;
- assert( db->nDb>iDb );
- pFix->pParse = pParse;
- pFix->zDb = db->aDb[iDb].zName;
- pFix->pSchema = db->aDb[iDb].pSchema;
- pFix->zType = zType;
- pFix->pName = pName;
- return 1;
-}
-
-/*
-** The following set of routines walk through the parse tree and assign
-** a specific database to all table references where the database name
-** was left unspecified in the original SQL statement. The pFix structure
-** must have been initialized by a prior call to sqlite3FixInit().
-**
-** These routines are used to make sure that an index, trigger, or
-** view in one database does not refer to objects in a different database.
-** (Exception: indices, triggers, and views in the TEMP database are
-** allowed to refer to anything.) If a reference is explicitly made
-** to an object in a different database, an error message is added to
-** pParse->zErrMsg and these routines return non-zero. If everything
-** checks out, these routines return 0.
-*/
-SQLITE_PRIVATE int sqlite3FixSrcList(
- DbFixer *pFix, /* Context of the fixation */
- SrcList *pList /* The Source list to check and modify */
-){
- int i;
- const char *zDb;
- struct SrcList_item *pItem;
-
- if( NEVER(pList==0) ) return 0;
- zDb = pFix->zDb;
- for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
- if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
- sqlite3ErrorMsg(pFix->pParse,
- "%s %T cannot reference objects in database %s",
- pFix->zType, pFix->pName, pItem->zDatabase);
- return 1;
- }
- sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
- pItem->zDatabase = 0;
- pItem->pSchema = pFix->pSchema;
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
- if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
- if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
-#endif
- }
- return 0;
-}
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
-SQLITE_PRIVATE int sqlite3FixSelect(
- DbFixer *pFix, /* Context of the fixation */
- Select *pSelect /* The SELECT statement to be fixed to one database */
-){
- while( pSelect ){
- if( sqlite3FixExprList(pFix, pSelect->pEList) ){
- return 1;
- }
- if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
- return 1;
- }
- if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
- return 1;
- }
- if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
- return 1;
- }
- pSelect = pSelect->pPrior;
- }
- return 0;
-}
-SQLITE_PRIVATE int sqlite3FixExpr(
- DbFixer *pFix, /* Context of the fixation */
- Expr *pExpr /* The expression to be fixed to one database */
-){
- while( pExpr ){
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
- }else{
- if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
- }
- if( sqlite3FixExpr(pFix, pExpr->pRight) ){
- return 1;
- }
- pExpr = pExpr->pLeft;
- }
- return 0;
-}
-SQLITE_PRIVATE int sqlite3FixExprList(
- DbFixer *pFix, /* Context of the fixation */
- ExprList *pList /* The expression to be fixed to one database */
-){
- int i;
- struct ExprList_item *pItem;
- if( pList==0 ) return 0;
- for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
- if( sqlite3FixExpr(pFix, pItem->pExpr) ){
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-#ifndef SQLITE_OMIT_TRIGGER
-SQLITE_PRIVATE int sqlite3FixTriggerStep(
- DbFixer *pFix, /* Context of the fixation */
- TriggerStep *pStep /* The trigger step be fixed to one database */
-){
- while( pStep ){
- if( sqlite3FixSelect(pFix, pStep->pSelect) ){
- return 1;
- }
- if( sqlite3FixExpr(pFix, pStep->pWhere) ){
- return 1;
- }
- if( sqlite3FixExprList(pFix, pStep->pExprList) ){
- return 1;
- }
- pStep = pStep->pNext;
- }
- return 0;
-}
-#endif
-
-/************** End of attach.c **********************************************/
-/************** Begin file auth.c ********************************************/
-/*
-** 2003 January 11
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code used to implement the sqlite3_set_authorizer()
-** API. This facility is an optional feature of the library. Embedded
-** systems that do not need this facility may omit it by recompiling
-** the library with -DSQLITE_OMIT_AUTHORIZATION=1
-*/
-
-/*
-** All of the code in this file may be omitted by defining a single
-** macro.
-*/
-#ifndef SQLITE_OMIT_AUTHORIZATION
-
-/*
-** Set or clear the access authorization function.
-**
-** The access authorization function is be called during the compilation
-** phase to verify that the user has read and/or write access permission on
-** various fields of the database. The first argument to the auth function
-** is a copy of the 3rd argument to this routine. The second argument
-** to the auth function is one of these constants:
-**
-** SQLITE_CREATE_INDEX
-** SQLITE_CREATE_TABLE
-** SQLITE_CREATE_TEMP_INDEX
-** SQLITE_CREATE_TEMP_TABLE
-** SQLITE_CREATE_TEMP_TRIGGER
-** SQLITE_CREATE_TEMP_VIEW
-** SQLITE_CREATE_TRIGGER
-** SQLITE_CREATE_VIEW
-** SQLITE_DELETE
-** SQLITE_DROP_INDEX
-** SQLITE_DROP_TABLE
-** SQLITE_DROP_TEMP_INDEX
-** SQLITE_DROP_TEMP_TABLE
-** SQLITE_DROP_TEMP_TRIGGER
-** SQLITE_DROP_TEMP_VIEW
-** SQLITE_DROP_TRIGGER
-** SQLITE_DROP_VIEW
-** SQLITE_INSERT
-** SQLITE_PRAGMA
-** SQLITE_READ
-** SQLITE_SELECT
-** SQLITE_TRANSACTION
-** SQLITE_UPDATE
-**
-** The third and fourth arguments to the auth function are the name of
-** the table and the column that are being accessed. The auth function
-** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If
-** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY
-** means that the SQL statement will never-run - the sqlite3_exec() call
-** will return with an error. SQLITE_IGNORE means that the SQL statement
-** should run but attempts to read the specified column will return NULL
-** and attempts to write the column will be ignored.
-**
-** Setting the auth function to NULL disables this hook. The default
-** setting of the auth function is NULL.
-*/
-SQLITE_API int sqlite3_set_authorizer(
- sqlite3 *db,
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
- void *pArg
-){
- sqlite3_mutex_enter(db->mutex);
- db->xAuth = xAuth;
- db->pAuthArg = pArg;
- sqlite3ExpirePreparedStatements(db);
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-/*
-** Write an error message into pParse->zErrMsg that explains that the
-** user-supplied authorization function returned an illegal value.
-*/
-static void sqliteAuthBadReturnCode(Parse *pParse){
- sqlite3ErrorMsg(pParse, "authorizer malfunction");
- pParse->rc = SQLITE_ERROR;
-}
-
-/*
-** Invoke the authorization callback for permission to read column zCol from
-** table zTab in database zDb. This function assumes that an authorization
-** callback has been registered (i.e. that sqlite3.xAuth is not NULL).
-**
-** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed
-** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE
-** is treated as SQLITE_DENY. In this case an error is left in pParse.
-*/
-SQLITE_PRIVATE int sqlite3AuthReadCol(
- Parse *pParse, /* The parser context */
- const char *zTab, /* Table name */
- const char *zCol, /* Column name */
- int iDb /* Index of containing database. */
-){
- sqlite3 *db = pParse->db; /* Database handle */
- char *zDb = db->aDb[iDb].zName; /* Name of attached database */
- int rc; /* Auth callback return code */
-
- rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext);
- if( rc==SQLITE_DENY ){
- if( db->nDb>2 || iDb!=0 ){
- sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
- }else{
- sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol);
- }
- pParse->rc = SQLITE_AUTH;
- }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){
- sqliteAuthBadReturnCode(pParse);
- }
- return rc;
-}
-
-/*
-** The pExpr should be a TK_COLUMN expression. The table referred to
-** is in pTabList or else it is the NEW or OLD table of a trigger.
-** Check to see if it is OK to read this particular column.
-**
-** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN
-** instruction into a TK_NULL. If the auth function returns SQLITE_DENY,
-** then generate an error.
-*/
-SQLITE_PRIVATE void sqlite3AuthRead(
- Parse *pParse, /* The parser context */
- Expr *pExpr, /* The expression to check authorization on */
- Schema *pSchema, /* The schema of the expression */
- SrcList *pTabList /* All table that pExpr might refer to */
-){
- sqlite3 *db = pParse->db;
- Table *pTab = 0; /* The table being read */
- const char *zCol; /* Name of the column of the table */
- int iSrc; /* Index in pTabList->a[] of table being read */
- int iDb; /* The index of the database the expression refers to */
- int iCol; /* Index of column in table */
-
- if( db->xAuth==0 ) return;
- iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
- if( iDb<0 ){
- /* An attempt to read a column out of a subquery or other
- ** temporary table. */
- return;
- }
-
- assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
- if( pExpr->op==TK_TRIGGER ){
- pTab = pParse->pTriggerTab;
- }else{
- assert( pTabList );
- for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){
- if( pExpr->iTable==pTabList->a[iSrc].iCursor ){
- pTab = pTabList->a[iSrc].pTab;
- break;
- }
- }
- }
- iCol = pExpr->iColumn;
- if( NEVER(pTab==0) ) return;
-
- if( iCol>=0 ){
- assert( iCol<pTab->nCol );
- zCol = pTab->aCol[iCol].zName;
- }else if( pTab->iPKey>=0 ){
- assert( pTab->iPKey<pTab->nCol );
- zCol = pTab->aCol[pTab->iPKey].zName;
- }else{
- zCol = "ROWID";
- }
- assert( iDb>=0 && iDb<db->nDb );
- if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){
- pExpr->op = TK_NULL;
- }
-}
-
-/*
-** Do an authorization check using the code and arguments given. Return
-** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY
-** is returned, then the error count and error message in pParse are
-** modified appropriately.
-*/
-SQLITE_PRIVATE int sqlite3AuthCheck(
- Parse *pParse,
- int code,
- const char *zArg1,
- const char *zArg2,
- const char *zArg3
-){
- sqlite3 *db = pParse->db;
- int rc;
-
- /* Don't do any authorization checks if the database is initialising
- ** or if the parser is being invoked from within sqlite3_declare_vtab.
- */
- if( db->init.busy || IN_DECLARE_VTAB ){
- return SQLITE_OK;
- }
-
- if( db->xAuth==0 ){
- return SQLITE_OK;
- }
- rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
- if( rc==SQLITE_DENY ){
- sqlite3ErrorMsg(pParse, "not authorized");
- pParse->rc = SQLITE_AUTH;
- }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
- rc = SQLITE_DENY;
- sqliteAuthBadReturnCode(pParse);
- }
- return rc;
-}
-
-/*
-** Push an authorization context. After this routine is called, the
-** zArg3 argument to authorization callbacks will be zContext until
-** popped. Or if pParse==0, this routine is a no-op.
-*/
-SQLITE_PRIVATE void sqlite3AuthContextPush(
- Parse *pParse,
- AuthContext *pContext,
- const char *zContext
-){
- assert( pParse );
- pContext->pParse = pParse;
- pContext->zAuthContext = pParse->zAuthContext;
- pParse->zAuthContext = zContext;
-}
-
-/*
-** Pop an authorization context that was previously pushed
-** by sqlite3AuthContextPush
-*/
-SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){
- if( pContext->pParse ){
- pContext->pParse->zAuthContext = pContext->zAuthContext;
- pContext->pParse = 0;
- }
-}
-
-#endif /* SQLITE_OMIT_AUTHORIZATION */
-
-/************** End of auth.c ************************************************/
-/************** Begin file build.c *******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains C code routines that are called by the SQLite parser
-** when syntax rules are reduced. The routines in this file handle the
-** following kinds of SQL syntax:
-**
-** CREATE TABLE
-** DROP TABLE
-** CREATE INDEX
-** DROP INDEX
-** creating ID lists
-** BEGIN TRANSACTION
-** COMMIT
-** ROLLBACK
-*/
-
-/*
-** This routine is called when a new SQL statement is beginning to
-** be parsed. Initialize the pParse structure as needed.
-*/
-SQLITE_PRIVATE void sqlite3BeginParse(Parse *pParse, int explainFlag){
- pParse->explain = (u8)explainFlag;
- pParse->nVar = 0;
-}
-
-#ifndef SQLITE_OMIT_SHARED_CACHE
-/*
-** The TableLock structure is only used by the sqlite3TableLock() and
-** codeTableLocks() functions.
-*/
-struct TableLock {
- int iDb; /* The database containing the table to be locked */
- int iTab; /* The root page of the table to be locked */
- u8 isWriteLock; /* True for write lock. False for a read lock */
- const char *zName; /* Name of the table */
-};
-
-/*
-** Record the fact that we want to lock a table at run-time.
-**
-** The table to be locked has root page iTab and is found in database iDb.
-** A read or a write lock can be taken depending on isWritelock.
-**
-** This routine just records the fact that the lock is desired. The
-** code to make the lock occur is generated by a later call to
-** codeTableLocks() which occurs during sqlite3FinishCoding().
-*/
-SQLITE_PRIVATE void sqlite3TableLock(
- Parse *pParse, /* Parsing context */
- int iDb, /* Index of the database containing the table to lock */
- int iTab, /* Root page number of the table to be locked */
- u8 isWriteLock, /* True for a write lock */
- const char *zName /* Name of the table to be locked */
-){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- int i;
- int nBytes;
- TableLock *p;
- assert( iDb>=0 );
-
- for(i=0; i<pToplevel->nTableLock; i++){
- p = &pToplevel->aTableLock[i];
- if( p->iDb==iDb && p->iTab==iTab ){
- p->isWriteLock = (p->isWriteLock || isWriteLock);
- return;
- }
- }
-
- nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1);
- pToplevel->aTableLock =
- sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes);
- if( pToplevel->aTableLock ){
- p = &pToplevel->aTableLock[pToplevel->nTableLock++];
- p->iDb = iDb;
- p->iTab = iTab;
- p->isWriteLock = isWriteLock;
- p->zName = zName;
- }else{
- pToplevel->nTableLock = 0;
- pToplevel->db->mallocFailed = 1;
- }
-}
-
-/*
-** Code an OP_TableLock instruction for each table locked by the
-** statement (configured by calls to sqlite3TableLock()).
-*/
-static void codeTableLocks(Parse *pParse){
- int i;
- Vdbe *pVdbe;
-
- pVdbe = sqlite3GetVdbe(pParse);
- assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */
-
- for(i=0; i<pParse->nTableLock; i++){
- TableLock *p = &pParse->aTableLock[i];
- int p1 = p->iDb;
- sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock,
- p->zName, P4_STATIC);
- }
-}
-#else
- #define codeTableLocks(x)
-#endif
-
-/*
-** This routine is called after a single SQL statement has been
-** parsed and a VDBE program to execute that statement has been
-** prepared. This routine puts the finishing touches on the
-** VDBE program and resets the pParse structure for the next
-** parse.
-**
-** Note that if an error occurred, it might be the case that
-** no VDBE code was generated.
-*/
-SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
- sqlite3 *db;
- Vdbe *v;
-
- assert( pParse->pToplevel==0 );
- db = pParse->db;
- if( db->mallocFailed ) return;
- if( pParse->nested ) return;
- if( pParse->nErr ) return;
-
- /* Begin by generating some termination code at the end of the
- ** vdbe program
- */
- v = sqlite3GetVdbe(pParse);
- assert( !pParse->isMultiWrite
- || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
- if( v ){
- sqlite3VdbeAddOp0(v, OP_Halt);
-
- /* The cookie mask contains one bit for each database file open.
- ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are
- ** set for each database that is used. Generate code to start a
- ** transaction on each used database and to verify the schema cookie
- ** on each used database.
- */
- if( pParse->cookieGoto>0 ){
- yDbMask mask;
- int iDb;
- sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
- for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
- if( (mask & pParse->cookieMask)==0 ) continue;
- sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
- if( db->init.busy==0 ){
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- sqlite3VdbeAddOp3(v, OP_VerifyCookie,
- iDb, pParse->cookieValue[iDb],
- db->aDb[iDb].pSchema->iGeneration);
- }
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- {
- int i;
- for(i=0; i<pParse->nVtabLock; i++){
- char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
- sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
- }
- pParse->nVtabLock = 0;
- }
-#endif
-
- /* Once all the cookies have been verified and transactions opened,
- ** obtain the required table-locks. This is a no-op unless the
- ** shared-cache feature is enabled.
- */
- codeTableLocks(pParse);
-
- /* Initialize any AUTOINCREMENT data structures required.
- */
- sqlite3AutoincrementBegin(pParse);
-
- /* Finally, jump back to the beginning of the executable code. */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto);
- }
- }
-
-
- /* Get the VDBE program ready for execution
- */
- if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
-#ifdef SQLITE_DEBUG
- FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
- sqlite3VdbeTrace(v, trace);
-#endif
- assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
- /* A minimum of one cursor is required if autoincrement is used
- * See ticket [a696379c1f08866] */
- if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1;
- sqlite3VdbeMakeReady(v, pParse);
- pParse->rc = SQLITE_DONE;
- pParse->colNamesSet = 0;
- }else{
- pParse->rc = SQLITE_ERROR;
- }
- pParse->nTab = 0;
- pParse->nMem = 0;
- pParse->nSet = 0;
- pParse->nVar = 0;
- pParse->cookieMask = 0;
- pParse->cookieGoto = 0;
-}
-
-/*
-** Run the parser and code generator recursively in order to generate
-** code for the SQL statement given onto the end of the pParse context
-** currently under construction. When the parser is run recursively
-** this way, the final OP_Halt is not appended and other initialization
-** and finalization steps are omitted because those are handling by the
-** outermost parser.
-**
-** Not everything is nestable. This facility is designed to permit
-** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use
-** care if you decide to try to use this routine for some other purposes.
-*/
-SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
- va_list ap;
- char *zSql;
- char *zErrMsg = 0;
- sqlite3 *db = pParse->db;
-# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
- char saveBuf[SAVE_SZ];
-
- if( pParse->nErr ) return;
- assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
- va_start(ap, zFormat);
- zSql = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- if( zSql==0 ){
- return; /* A malloc must have failed */
- }
- pParse->nested++;
- memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
- memset(&pParse->nVar, 0, SAVE_SZ);
- sqlite3RunParser(pParse, zSql, &zErrMsg);
- sqlite3DbFree(db, zErrMsg);
- sqlite3DbFree(db, zSql);
- memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
- pParse->nested--;
-}
-
-/*
-** Locate the in-memory structure that describes a particular database
-** table given the name of that table and (optionally) the name of the
-** database containing the table. Return NULL if not found.
-**
-** If zDatabase is 0, all databases are searched for the table and the
-** first matching table is returned. (No checking for duplicate table
-** names is done.) The search order is TEMP first, then MAIN, then any
-** auxiliary databases added using the ATTACH command.
-**
-** See also sqlite3LocateTable().
-*/
-SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
- Table *p = 0;
- int i;
- int nName;
- assert( zName!=0 );
- nName = sqlite3Strlen30(zName);
- /* All mutexes are required for schema access. Make sure we hold them. */
- assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
- for(i=OMIT_TEMPDB; i<db->nDb; i++){
- int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
- if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
- assert( sqlite3SchemaMutexHeld(db, j, 0) );
- p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, nName);
- if( p ) break;
- }
- return p;
-}
-
-/*
-** Locate the in-memory structure that describes a particular database
-** table given the name of that table and (optionally) the name of the
-** database containing the table. Return NULL if not found. Also leave an
-** error message in pParse->zErrMsg.
-**
-** The difference between this routine and sqlite3FindTable() is that this
-** routine leaves an error message in pParse->zErrMsg where
-** sqlite3FindTable() does not.
-*/
-SQLITE_PRIVATE Table *sqlite3LocateTable(
- Parse *pParse, /* context in which to report errors */
- int isView, /* True if looking for a VIEW rather than a TABLE */
- const char *zName, /* Name of the table we are looking for */
- const char *zDbase /* Name of the database. Might be NULL */
-){
- Table *p;
-
- /* Read the database schema. If an error occurs, leave an error message
- ** and code in pParse and return NULL. */
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- return 0;
- }
-
- p = sqlite3FindTable(pParse->db, zName, zDbase);
- if( p==0 ){
- const char *zMsg = isView ? "no such view" : "no such table";
- if( zDbase ){
- sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
- }else{
- sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
- }
- pParse->checkSchema = 1;
- }
- return p;
-}
-
-/*
-** Locate the table identified by *p.
-**
-** This is a wrapper around sqlite3LocateTable(). The difference between
-** sqlite3LocateTable() and this function is that this function restricts
-** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
-** non-NULL if it is part of a view or trigger program definition. See
-** sqlite3FixSrcList() for details.
-*/
-SQLITE_PRIVATE Table *sqlite3LocateTableItem(
- Parse *pParse,
- int isView,
- struct SrcList_item *p
-){
- const char *zDb;
- assert( p->pSchema==0 || p->zDatabase==0 );
- if( p->pSchema ){
- int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
- zDb = pParse->db->aDb[iDb].zName;
- }else{
- zDb = p->zDatabase;
- }
- return sqlite3LocateTable(pParse, isView, p->zName, zDb);
-}
-
-/*
-** Locate the in-memory structure that describes
-** a particular index given the name of that index
-** and the name of the database that contains the index.
-** Return NULL if not found.
-**
-** If zDatabase is 0, all databases are searched for the
-** table and the first matching index is returned. (No checking
-** for duplicate index names is done.) The search order is
-** TEMP first, then MAIN, then any auxiliary databases added
-** using the ATTACH command.
-*/
-SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
- Index *p = 0;
- int i;
- int nName = sqlite3Strlen30(zName);
- /* All mutexes are required for schema access. Make sure we hold them. */
- assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
- for(i=OMIT_TEMPDB; i<db->nDb; i++){
- int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
- Schema *pSchema = db->aDb[j].pSchema;
- assert( pSchema );
- if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
- assert( sqlite3SchemaMutexHeld(db, j, 0) );
- p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
- if( p ) break;
- }
- return p;
-}
-
-/*
-** Reclaim the memory used by an index
-*/
-static void freeIndex(sqlite3 *db, Index *p){
-#ifndef SQLITE_OMIT_ANALYZE
- sqlite3DeleteIndexSamples(db, p);
-#endif
- sqlite3DbFree(db, p->zColAff);
- sqlite3DbFree(db, p);
-}
-
-/*
-** For the index called zIdxName which is found in the database iDb,
-** unlike that index from its Table then remove the index from
-** the index hash table and free all memory structures associated
-** with the index.
-*/
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
- Index *pIndex;
- int len;
- Hash *pHash;
-
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- pHash = &db->aDb[iDb].pSchema->idxHash;
- len = sqlite3Strlen30(zIdxName);
- pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0);
- if( ALWAYS(pIndex) ){
- if( pIndex->pTable->pIndex==pIndex ){
- pIndex->pTable->pIndex = pIndex->pNext;
- }else{
- Index *p;
- /* Justification of ALWAYS(); The index must be on the list of
- ** indices. */
- p = pIndex->pTable->pIndex;
- while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; }
- if( ALWAYS(p && p->pNext==pIndex) ){
- p->pNext = pIndex->pNext;
- }
- }
- freeIndex(db, pIndex);
- }
- db->flags |= SQLITE_InternChanges;
-}
-
-/*
-** Look through the list of open database files in db->aDb[] and if
-** any have been closed, remove them from the list. Reallocate the
-** db->aDb[] structure to a smaller size, if possible.
-**
-** Entry 0 (the "main" database) and entry 1 (the "temp" database)
-** are never candidates for being collapsed.
-*/
-SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){
- int i, j;
- for(i=j=2; i<db->nDb; i++){
- struct Db *pDb = &db->aDb[i];
- if( pDb->pBt==0 ){
- sqlite3DbFree(db, pDb->zName);
- pDb->zName = 0;
- continue;
- }
- if( j<i ){
- db->aDb[j] = db->aDb[i];
- }
- j++;
- }
- memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
- db->nDb = j;
- if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
- memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
- sqlite3DbFree(db, db->aDb);
- db->aDb = db->aDbStatic;
- }
-}
-
-/*
-** Reset the schema for the database at index iDb. Also reset the
-** TEMP schema.
-*/
-SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
- Db *pDb;
- assert( iDb<db->nDb );
-
- /* Case 1: Reset the single schema identified by iDb */
- pDb = &db->aDb[iDb];
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- assert( pDb->pSchema!=0 );
- sqlite3SchemaClear(pDb->pSchema);
-
- /* If any database other than TEMP is reset, then also reset TEMP
- ** since TEMP might be holding triggers that reference tables in the
- ** other database.
- */
- if( iDb!=1 ){
- pDb = &db->aDb[1];
- assert( pDb->pSchema!=0 );
- sqlite3SchemaClear(pDb->pSchema);
- }
- return;
-}
-
-/*
-** Erase all schema information from all attached databases (including
-** "main" and "temp") for a single database connection.
-*/
-SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
- int i;
- sqlite3BtreeEnterAll(db);
- for(i=0; i<db->nDb; i++){
- Db *pDb = &db->aDb[i];
- if( pDb->pSchema ){
- sqlite3SchemaClear(pDb->pSchema);
- }
- }
- db->flags &= ~SQLITE_InternChanges;
- sqlite3VtabUnlockList(db);
- sqlite3BtreeLeaveAll(db);
- sqlite3CollapseDatabaseArray(db);
-}
-
-/*
-** This routine is called when a commit occurs.
-*/
-SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){
- db->flags &= ~SQLITE_InternChanges;
-}
-
-/*
-** Delete memory allocated for the column names of a table or view (the
-** Table.aCol[] array).
-*/
-static void sqliteDeleteColumnNames(sqlite3 *db, Table *pTable){
- int i;
- Column *pCol;
- assert( pTable!=0 );
- if( (pCol = pTable->aCol)!=0 ){
- for(i=0; i<pTable->nCol; i++, pCol++){
- sqlite3DbFree(db, pCol->zName);
- sqlite3ExprDelete(db, pCol->pDflt);
- sqlite3DbFree(db, pCol->zDflt);
- sqlite3DbFree(db, pCol->zType);
- sqlite3DbFree(db, pCol->zColl);
- }
- sqlite3DbFree(db, pTable->aCol);
- }
-}
-
-/*
-** Remove the memory data structures associated with the given
-** Table. No changes are made to disk by this routine.
-**
-** This routine just deletes the data structure. It does not unlink
-** the table data structure from the hash table. But it does destroy
-** memory structures of the indices and foreign keys associated with
-** the table.
-**
-** The db parameter is optional. It is needed if the Table object
-** contains lookaside memory. (Table objects in the schema do not use
-** lookaside memory, but some ephemeral Table objects do.) Or the
-** db parameter can be used with db->pnBytesFreed to measure the memory
-** used by the Table object.
-*/
-SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
- Index *pIndex, *pNext;
- TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */
-
- assert( !pTable || pTable->nRef>0 );
-
- /* Do not delete the table until the reference count reaches zero. */
- if( !pTable ) return;
- if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
-
- /* Record the number of outstanding lookaside allocations in schema Tables
- ** prior to doing any free() operations. Since schema Tables do not use
- ** lookaside, this number should not change. */
- TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ?
- db->lookaside.nOut : 0 );
-
- /* Delete all indices associated with this table. */
- for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
- pNext = pIndex->pNext;
- assert( pIndex->pSchema==pTable->pSchema );
- if( !db || db->pnBytesFreed==0 ){
- char *zName = pIndex->zName;
- TESTONLY ( Index *pOld = ) sqlite3HashInsert(
- &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
- );
- assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
- assert( pOld==pIndex || pOld==0 );
- }
- freeIndex(db, pIndex);
- }
-
- /* Delete any foreign keys attached to this table. */
- sqlite3FkDelete(db, pTable);
-
- /* Delete the Table structure itself.
- */
- sqliteDeleteColumnNames(db, pTable);
- sqlite3DbFree(db, pTable->zName);
- sqlite3DbFree(db, pTable->zColAff);
- sqlite3SelectDelete(db, pTable->pSelect);
-#ifndef SQLITE_OMIT_CHECK
- sqlite3ExprListDelete(db, pTable->pCheck);
-#endif
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- sqlite3VtabClear(db, pTable);
-#endif
- sqlite3DbFree(db, pTable);
-
- /* Verify that no lookaside memory was used by schema tables */
- assert( nLookaside==0 || nLookaside==db->lookaside.nOut );
-}
-
-/*
-** Unlink the given table from the hash tables and the delete the
-** table structure with all its indices and foreign keys.
-*/
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
- Table *p;
- Db *pDb;
-
- assert( db!=0 );
- assert( iDb>=0 && iDb<db->nDb );
- assert( zTabName );
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */
- pDb = &db->aDb[iDb];
- p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName,
- sqlite3Strlen30(zTabName),0);
- sqlite3DeleteTable(db, p);
- db->flags |= SQLITE_InternChanges;
-}
-
-/*
-** Given a token, return a string that consists of the text of that
-** token. Space to hold the returned string
-** is obtained from sqliteMalloc() and must be freed by the calling
-** function.
-**
-** Any quotation marks (ex: "name", 'name', [name], or `name`) that
-** surround the body of the token are removed.
-**
-** Tokens are often just pointers into the original SQL text and so
-** are not \000 terminated and are not persistent. The returned string
-** is \000 terminated and is persistent.
-*/
-SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
- char *zName;
- if( pName ){
- zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n);
- sqlite3Dequote(zName);
- }else{
- zName = 0;
- }
- return zName;
-}
-
-/*
-** Open the sqlite_master table stored in database number iDb for
-** writing. The table is opened using cursor 0.
-*/
-SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){
- Vdbe *v = sqlite3GetVdbe(p);
- sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
- sqlite3VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb);
- sqlite3VdbeChangeP4(v, -1, (char *)5, P4_INT32); /* 5 column table */
- if( p->nTab==0 ){
- p->nTab = 1;
- }
-}
-
-/*
-** Parameter zName points to a nul-terminated buffer containing the name
-** of a database ("main", "temp" or the name of an attached db). This
-** function returns the index of the named database in db->aDb[], or
-** -1 if the named db cannot be found.
-*/
-SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){
- int i = -1; /* Database number */
- if( zName ){
- Db *pDb;
- int n = sqlite3Strlen30(zName);
- for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
- if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) &&
- 0==sqlite3StrICmp(pDb->zName, zName) ){
- break;
- }
- }
- }
- return i;
-}
-
-/*
-** The token *pName contains the name of a database (either "main" or
-** "temp" or the name of an attached db). This routine returns the
-** index of the named database in db->aDb[], or -1 if the named db
-** does not exist.
-*/
-SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){
- int i; /* Database number */
- char *zName; /* Name we are searching for */
- zName = sqlite3NameFromToken(db, pName);
- i = sqlite3FindDbName(db, zName);
- sqlite3DbFree(db, zName);
- return i;
-}
-
-/* The table or view or trigger name is passed to this routine via tokens
-** pName1 and pName2. If the table name was fully qualified, for example:
-**
-** CREATE TABLE xxx.yyy (...);
-**
-** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
-** the table name is not fully qualified, i.e.:
-**
-** CREATE TABLE yyy(...);
-**
-** Then pName1 is set to "yyy" and pName2 is "".
-**
-** This routine sets the *ppUnqual pointer to point at the token (pName1 or
-** pName2) that stores the unqualified table name. The index of the
-** database "xxx" is returned.
-*/
-SQLITE_PRIVATE int sqlite3TwoPartName(
- Parse *pParse, /* Parsing and code generating context */
- Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */
- Token *pName2, /* The "yyy" in the name "xxx.yyy" */
- Token **pUnqual /* Write the unqualified object name here */
-){
- int iDb; /* Database holding the object */
- sqlite3 *db = pParse->db;
-
- if( ALWAYS(pName2!=0) && pName2->n>0 ){
- if( db->init.busy ) {
- sqlite3ErrorMsg(pParse, "corrupt database");
- pParse->nErr++;
- return -1;
- }
- *pUnqual = pName2;
- iDb = sqlite3FindDb(db, pName1);
- if( iDb<0 ){
- sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
- pParse->nErr++;
- return -1;
- }
- }else{
- assert( db->init.iDb==0 || db->init.busy );
- iDb = db->init.iDb;
- *pUnqual = pName1;
- }
- return iDb;
-}
-
-/*
-** This routine is used to check if the UTF-8 string zName is a legal
-** unqualified name for a new schema object (table, index, view or
-** trigger). All names are legal except those that begin with the string
-** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
-** is reserved for internal use.
-*/
-SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
- if( !pParse->db->init.busy && pParse->nested==0
- && (pParse->db->flags & SQLITE_WriteSchema)==0
- && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
- sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
- return SQLITE_ERROR;
- }
- return SQLITE_OK;
-}
-
-/*
-** Begin constructing a new table representation in memory. This is
-** the first of several action routines that get called in response
-** to a CREATE TABLE statement. In particular, this routine is called
-** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp
-** flag is true if the table should be stored in the auxiliary database
-** file instead of in the main database file. This is normally the case
-** when the "TEMP" or "TEMPORARY" keyword occurs in between
-** CREATE and TABLE.
-**
-** The new table record is initialized and put in pParse->pNewTable.
-** As more of the CREATE TABLE statement is parsed, additional action
-** routines will be called to add more information to this record.
-** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine
-** is called to complete the construction of the new table record.
-*/
-SQLITE_PRIVATE void sqlite3StartTable(
- Parse *pParse, /* Parser context */
- Token *pName1, /* First part of the name of the table or view */
- Token *pName2, /* Second part of the name of the table or view */
- int isTemp, /* True if this is a TEMP table */
- int isView, /* True if this is a VIEW */
- int isVirtual, /* True if this is a VIRTUAL table */
- int noErr /* Do nothing if table already exists */
-){
- Table *pTable;
- char *zName = 0; /* The name of the new table */
- sqlite3 *db = pParse->db;
- Vdbe *v;
- int iDb; /* Database number to create the table in */
- Token *pName; /* Unqualified name of the table to create */
-
- /* The table or view name to create is passed to this routine via tokens
- ** pName1 and pName2. If the table name was fully qualified, for example:
- **
- ** CREATE TABLE xxx.yyy (...);
- **
- ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if
- ** the table name is not fully qualified, i.e.:
- **
- ** CREATE TABLE yyy(...);
- **
- ** Then pName1 is set to "yyy" and pName2 is "".
- **
- ** The call below sets the pName pointer to point at the token (pName1 or
- ** pName2) that stores the unqualified table name. The variable iDb is
- ** set to the index of the database that the table or view is to be
- ** created in.
- */
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
- if( iDb<0 ) return;
- if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){
- /* If creating a temp table, the name may not be qualified. Unless
- ** the database name is "temp" anyway. */
- sqlite3ErrorMsg(pParse, "temporary table name must be unqualified");
- return;
- }
- if( !OMIT_TEMPDB && isTemp ) iDb = 1;
-
- pParse->sNameToken = *pName;
- zName = sqlite3NameFromToken(db, pName);
- if( zName==0 ) return;
- if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
- goto begin_table_error;
- }
- if( db->init.iDb==1 ) isTemp = 1;
-#ifndef SQLITE_OMIT_AUTHORIZATION
- assert( (isTemp & 1)==isTemp );
- {
- int code;
- char *zDb = db->aDb[iDb].zName;
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
- goto begin_table_error;
- }
- if( isView ){
- if( !OMIT_TEMPDB && isTemp ){
- code = SQLITE_CREATE_TEMP_VIEW;
- }else{
- code = SQLITE_CREATE_VIEW;
- }
- }else{
- if( !OMIT_TEMPDB && isTemp ){
- code = SQLITE_CREATE_TEMP_TABLE;
- }else{
- code = SQLITE_CREATE_TABLE;
- }
- }
- if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){
- goto begin_table_error;
- }
- }
-#endif
-
- /* Make sure the new table name does not collide with an existing
- ** index or table name in the same database. Issue an error message if
- ** it does. The exception is if the statement being parsed was passed
- ** to an sqlite3_declare_vtab() call. In that case only the column names
- ** and types will be used, so there is no need to test for namespace
- ** collisions.
- */
- if( !IN_DECLARE_VTAB ){
- char *zDb = db->aDb[iDb].zName;
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- goto begin_table_error;
- }
- pTable = sqlite3FindTable(db, zName, zDb);
- if( pTable ){
- if( !noErr ){
- sqlite3ErrorMsg(pParse, "table %T already exists", pName);
- }else{
- assert( !db->init.busy );
- sqlite3CodeVerifySchema(pParse, iDb);
- }
- goto begin_table_error;
- }
- if( sqlite3FindIndex(db, zName, zDb)!=0 ){
- sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
- goto begin_table_error;
- }
- }
-
- pTable = sqlite3DbMallocZero(db, sizeof(Table));
- if( pTable==0 ){
- db->mallocFailed = 1;
- pParse->rc = SQLITE_NOMEM;
- pParse->nErr++;
- goto begin_table_error;
- }
- pTable->zName = zName;
- pTable->iPKey = -1;
- pTable->pSchema = db->aDb[iDb].pSchema;
- pTable->nRef = 1;
- pTable->nRowEst = 1000000;
- assert( pParse->pNewTable==0 );
- pParse->pNewTable = pTable;
-
- /* If this is the magic sqlite_sequence table used by autoincrement,
- ** then record a pointer to this table in the main database structure
- ** so that INSERT can find the table easily.
- */
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- pTable->pSchema->pSeqTab = pTable;
- }
-#endif
-
- /* Begin generating the code that will insert the table record into
- ** the SQLITE_MASTER table. Note in particular that we must go ahead
- ** and allocate the record number for the table entry now. Before any
- ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause
- ** indices to be created and the table record must come before the
- ** indices. Hence, the record number for the table must be allocated
- ** now.
- */
- if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
- int j1;
- int fileFormat;
- int reg1, reg2, reg3;
- sqlite3BeginWriteOperation(pParse, 0, iDb);
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( isVirtual ){
- sqlite3VdbeAddOp0(v, OP_VBegin);
- }
-#endif
-
- /* If the file format and encoding in the database have not been set,
- ** set them now.
- */
- reg1 = pParse->regRowid = ++pParse->nMem;
- reg2 = pParse->regRoot = ++pParse->nMem;
- reg3 = ++pParse->nMem;
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
- sqlite3VdbeUsesBtree(v, iDb);
- j1 = sqlite3VdbeAddOp1(v, OP_If, reg3);
- fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
- 1 : SQLITE_MAX_FILE_FORMAT;
- sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3);
- sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3);
- sqlite3VdbeJumpHere(v, j1);
-
- /* This just creates a place-holder record in the sqlite_master table.
- ** The record created does not contain anything yet. It will be replaced
- ** by the real entry in code generated at sqlite3EndTable().
- **
- ** The rowid for the new entry is left in register pParse->regRowid.
- ** The root page number of the new table is left in reg pParse->regRoot.
- ** The rowid and root page number values are needed by the code that
- ** sqlite3EndTable will generate.
- */
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
- if( isView || isVirtual ){
- sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2);
- }else
-#endif
- {
- sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
- }
- sqlite3OpenMasterTable(pParse, iDb);
- sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
- sqlite3VdbeAddOp2(v, OP_Null, 0, reg3);
- sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- sqlite3VdbeAddOp0(v, OP_Close);
- }
-
- /* Normal (non-error) return. */
- return;
-
- /* If an error occurs, we jump here */
-begin_table_error:
- sqlite3DbFree(db, zName);
- return;
-}
-
-/*
-** This macro is used to compare two strings in a case-insensitive manner.
-** It is slightly faster than calling sqlite3StrICmp() directly, but
-** produces larger code.
-**
-** WARNING: This macro is not compatible with the strcmp() family. It
-** returns true if the two strings are equal, otherwise false.
-*/
-#define STRICMP(x, y) (\
-sqlite3UpperToLower[*(unsigned char *)(x)]== \
-sqlite3UpperToLower[*(unsigned char *)(y)] \
-&& sqlite3StrICmp((x)+1,(y)+1)==0 )
-
-/*
-** Add a new column to the table currently being constructed.
-**
-** The parser calls this routine once for each column declaration
-** in a CREATE TABLE statement. sqlite3StartTable() gets called
-** first to get things going. Then this routine is called for each
-** column.
-*/
-SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
- Table *p;
- int i;
- char *z;
- Column *pCol;
- sqlite3 *db = pParse->db;
- if( (p = pParse->pNewTable)==0 ) return;
-#if SQLITE_MAX_COLUMN
- if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
- return;
- }
-#endif
- z = sqlite3NameFromToken(db, pName);
- if( z==0 ) return;
- for(i=0; i<p->nCol; i++){
- if( STRICMP(z, p->aCol[i].zName) ){
- sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
- sqlite3DbFree(db, z);
- return;
- }
- }
- if( (p->nCol & 0x7)==0 ){
- Column *aNew;
- aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0]));
- if( aNew==0 ){
- sqlite3DbFree(db, z);
- return;
- }
- p->aCol = aNew;
- }
- pCol = &p->aCol[p->nCol];
- memset(pCol, 0, sizeof(p->aCol[0]));
- pCol->zName = z;
-
- /* If there is no type specified, columns have the default affinity
- ** 'NONE'. If there is a type specified, then sqlite3AddColumnType() will
- ** be called next to set pCol->affinity correctly.
- */
- pCol->affinity = SQLITE_AFF_NONE;
- p->nCol++;
-}
-
-/*
-** This routine is called by the parser while in the middle of
-** parsing a CREATE TABLE statement. A "NOT NULL" constraint has
-** been seen on a column. This routine sets the notNull flag on
-** the column currently under construction.
-*/
-SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
- Table *p;
- p = pParse->pNewTable;
- if( p==0 || NEVER(p->nCol<1) ) return;
- p->aCol[p->nCol-1].notNull = (u8)onError;
-}
-
-/*
-** Scan the column type name zType (length nType) and return the
-** associated affinity type.
-**
-** This routine does a case-independent search of zType for the
-** substrings in the following table. If one of the substrings is
-** found, the corresponding affinity is returned. If zType contains
-** more than one of the substrings, entries toward the top of
-** the table take priority. For example, if zType is 'BLOBINT',
-** SQLITE_AFF_INTEGER is returned.
-**
-** Substring | Affinity
-** --------------------------------
-** 'INT' | SQLITE_AFF_INTEGER
-** 'CHAR' | SQLITE_AFF_TEXT
-** 'CLOB' | SQLITE_AFF_TEXT
-** 'TEXT' | SQLITE_AFF_TEXT
-** 'BLOB' | SQLITE_AFF_NONE
-** 'REAL' | SQLITE_AFF_REAL
-** 'FLOA' | SQLITE_AFF_REAL
-** 'DOUB' | SQLITE_AFF_REAL
-**
-** If none of the substrings in the above table are found,
-** SQLITE_AFF_NUMERIC is returned.
-*/
-SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){
- u32 h = 0;
- char aff = SQLITE_AFF_NUMERIC;
-
- if( zIn ) while( zIn[0] ){
- h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
- zIn++;
- if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */
- aff = SQLITE_AFF_TEXT;
- }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */
- aff = SQLITE_AFF_TEXT;
- }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */
- aff = SQLITE_AFF_TEXT;
- }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */
- && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){
- aff = SQLITE_AFF_NONE;
-#ifndef SQLITE_OMIT_FLOATING_POINT
- }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */
- && aff==SQLITE_AFF_NUMERIC ){
- aff = SQLITE_AFF_REAL;
- }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */
- && aff==SQLITE_AFF_NUMERIC ){
- aff = SQLITE_AFF_REAL;
- }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b') /* DOUB */
- && aff==SQLITE_AFF_NUMERIC ){
- aff = SQLITE_AFF_REAL;
-#endif
- }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */
- aff = SQLITE_AFF_INTEGER;
- break;
- }
- }
-
- return aff;
-}
-
-/*
-** This routine is called by the parser while in the middle of
-** parsing a CREATE TABLE statement. The pFirst token is the first
-** token in the sequence of tokens that describe the type of the
-** column currently under construction. pLast is the last token
-** in the sequence. Use this information to construct a string
-** that contains the typename of the column and store that string
-** in zType.
-*/
-SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
- Table *p;
- Column *pCol;
-
- p = pParse->pNewTable;
- if( p==0 || NEVER(p->nCol<1) ) return;
- pCol = &p->aCol[p->nCol-1];
- assert( pCol->zType==0 );
- pCol->zType = sqlite3NameFromToken(pParse->db, pType);
- pCol->affinity = sqlite3AffinityType(pCol->zType);
-}
-
-/*
-** The expression is the default value for the most recently added column
-** of the table currently under construction.
-**
-** Default value expressions must be constant. Raise an exception if this
-** is not the case.
-**
-** This routine is called by the parser while in the middle of
-** parsing a CREATE TABLE statement.
-*/
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
- Table *p;
- Column *pCol;
- sqlite3 *db = pParse->db;
- p = pParse->pNewTable;
- if( p!=0 ){
- pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
- sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
- pCol->zName);
- }else{
- /* A copy of pExpr is used instead of the original, as pExpr contains
- ** tokens that point to volatile memory. The 'span' of the expression
- ** is required by pragma table_info.
- */
- sqlite3ExprDelete(db, pCol->pDflt);
- pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
- sqlite3DbFree(db, pCol->zDflt);
- pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
- }
- }
- sqlite3ExprDelete(db, pSpan->pExpr);
-}
-
-/*
-** Designate the PRIMARY KEY for the table. pList is a list of names
-** of columns that form the primary key. If pList is NULL, then the
-** most recently added column of the table is the primary key.
-**
-** A table can have at most one primary key. If the table already has
-** a primary key (and this is the second primary key) then create an
-** error.
-**
-** If the PRIMARY KEY is on a single column whose datatype is INTEGER,
-** then we will try to use that column as the rowid. Set the Table.iPKey
-** field of the table under construction to be the index of the
-** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is
-** no INTEGER PRIMARY KEY.
-**
-** If the key is not an INTEGER PRIMARY KEY, then create a unique
-** index for the key. No index is created for INTEGER PRIMARY KEYs.
-*/
-SQLITE_PRIVATE void sqlite3AddPrimaryKey(
- Parse *pParse, /* Parsing context */
- ExprList *pList, /* List of field names to be indexed */
- int onError, /* What to do with a uniqueness conflict */
- int autoInc, /* True if the AUTOINCREMENT keyword is present */
- int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */
-){
- Table *pTab = pParse->pNewTable;
- char *zType = 0;
- int iCol = -1, i;
- if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
- if( pTab->tabFlags & TF_HasPrimaryKey ){
- sqlite3ErrorMsg(pParse,
- "table \"%s\" has more than one primary key", pTab->zName);
- goto primary_key_exit;
- }
- pTab->tabFlags |= TF_HasPrimaryKey;
- if( pList==0 ){
- iCol = pTab->nCol - 1;
- pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
- }else{
- for(i=0; i<pList->nExpr; i++){
- for(iCol=0; iCol<pTab->nCol; iCol++){
- if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
- break;
- }
- }
- if( iCol<pTab->nCol ){
- pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
- }
- }
- if( pList->nExpr>1 ) iCol = -1;
- }
- if( iCol>=0 && iCol<pTab->nCol ){
- zType = pTab->aCol[iCol].zType;
- }
- if( zType && sqlite3StrICmp(zType, "INTEGER")==0
- && sortOrder==SQLITE_SO_ASC ){
- pTab->iPKey = iCol;
- pTab->keyConf = (u8)onError;
- assert( autoInc==0 || autoInc==1 );
- pTab->tabFlags |= autoInc*TF_Autoincrement;
- }else if( autoInc ){
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
- "INTEGER PRIMARY KEY");
-#endif
- }else{
- Index *p;
- p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
- if( p ){
- p->autoIndex = 2;
- }
- pList = 0;
- }
-
-primary_key_exit:
- sqlite3ExprListDelete(pParse->db, pList);
- return;
-}
-
-/*
-** Add a new CHECK constraint to the table currently under construction.
-*/
-SQLITE_PRIVATE void sqlite3AddCheckConstraint(
- Parse *pParse, /* Parsing context */
- Expr *pCheckExpr /* The check expression */
-){
-#ifndef SQLITE_OMIT_CHECK
- Table *pTab = pParse->pNewTable;
- if( pTab && !IN_DECLARE_VTAB ){
- pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr);
- if( pParse->constraintName.n ){
- sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1);
- }
- }else
-#endif
- {
- sqlite3ExprDelete(pParse->db, pCheckExpr);
- }
-}
-
-/*
-** Set the collation function of the most recently parsed table column
-** to the CollSeq given.
-*/
-SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
- Table *p;
- int i;
- char *zColl; /* Dequoted name of collation sequence */
- sqlite3 *db;
-
- if( (p = pParse->pNewTable)==0 ) return;
- i = p->nCol-1;
- db = pParse->db;
- zColl = sqlite3NameFromToken(db, pToken);
- if( !zColl ) return;
-
- if( sqlite3LocateCollSeq(pParse, zColl) ){
- Index *pIdx;
- p->aCol[i].zColl = zColl;
-
- /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
- ** then an index may have been created on this column before the
- ** collation type was added. Correct this if it is the case.
- */
- for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
- assert( pIdx->nColumn==1 );
- if( pIdx->aiColumn[0]==i ){
- pIdx->azColl[0] = p->aCol[i].zColl;
- }
- }
- }else{
- sqlite3DbFree(db, zColl);
- }
-}
-
-/*
-** This function returns the collation sequence for database native text
-** encoding identified by the string zName, length nName.
-**
-** If the requested collation sequence is not available, or not available
-** in the database native encoding, the collation factory is invoked to
-** request it. If the collation factory does not supply such a sequence,
-** and the sequence is available in another text encoding, then that is
-** returned instead.
-**
-** If no versions of the requested collations sequence are available, or
-** another error occurs, NULL is returned and an error message written into
-** pParse.
-**
-** This routine is a wrapper around sqlite3FindCollSeq(). This routine
-** invokes the collation factory if the named collation cannot be found
-** and generates an error message.
-**
-** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
-*/
-SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
- sqlite3 *db = pParse->db;
- u8 enc = ENC(db);
- u8 initbusy = db->init.busy;
- CollSeq *pColl;
-
- pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
- if( !initbusy && (!pColl || !pColl->xCmp) ){
- pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
- }
-
- return pColl;
-}
-
-
-/*
-** Generate code that will increment the schema cookie.
-**
-** The schema cookie is used to determine when the schema for the
-** database changes. After each schema change, the cookie value
-** changes. When a process first reads the schema it records the
-** cookie. Thereafter, whenever it goes to access the database,
-** it checks the cookie to make sure the schema has not changed
-** since it was last read.
-**
-** This plan is not completely bullet-proof. It is possible for
-** the schema to change multiple times and for the cookie to be
-** set back to prior value. But schema changes are infrequent
-** and the probability of hitting the same cookie value is only
-** 1 chance in 2^32. So we're safe enough.
-*/
-SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3 *db = pParse->db;
- Vdbe *v = pParse->pVdbe;
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1);
- sqlite3ReleaseTempReg(pParse, r1);
-}
-
-/*
-** Measure the number of characters needed to output the given
-** identifier. The number returned includes any quotes used
-** but does not include the null terminator.
-**
-** The estimate is conservative. It might be larger that what is
-** really needed.
-*/
-static int identLength(const char *z){
- int n;
- for(n=0; *z; n++, z++){
- if( *z=='"' ){ n++; }
- }
- return n + 2;
-}
-
-/*
-** The first parameter is a pointer to an output buffer. The second
-** parameter is a pointer to an integer that contains the offset at
-** which to write into the output buffer. This function copies the
-** nul-terminated string pointed to by the third parameter, zSignedIdent,
-** to the specified offset in the buffer and updates *pIdx to refer
-** to the first byte after the last byte written before returning.
-**
-** If the string zSignedIdent consists entirely of alpha-numeric
-** characters, does not begin with a digit and is not an SQL keyword,
-** then it is copied to the output buffer exactly as it is. Otherwise,
-** it is quoted using double-quotes.
-*/
-static void identPut(char *z, int *pIdx, char *zSignedIdent){
- unsigned char *zIdent = (unsigned char*)zSignedIdent;
- int i, j, needQuote;
- i = *pIdx;
-
- for(j=0; zIdent[j]; j++){
- if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
- }
- needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID;
- if( !needQuote ){
- needQuote = zIdent[j];
- }
-
- if( needQuote ) z[i++] = '"';
- for(j=0; zIdent[j]; j++){
- z[i++] = zIdent[j];
- if( zIdent[j]=='"' ) z[i++] = '"';
- }
- if( needQuote ) z[i++] = '"';
- z[i] = 0;
- *pIdx = i;
-}
-
-/*
-** Generate a CREATE TABLE statement appropriate for the given
-** table. Memory to hold the text of the statement is obtained
-** from sqliteMalloc() and must be freed by the calling function.
-*/
-static char *createTableStmt(sqlite3 *db, Table *p){
- int i, k, n;
- char *zStmt;
- char *zSep, *zSep2, *zEnd;
- Column *pCol;
- n = 0;
- for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
- n += identLength(pCol->zName) + 5;
- }
- n += identLength(p->zName);
- if( n<50 ){
- zSep = "";
- zSep2 = ",";
- zEnd = ")";
- }else{
- zSep = "\n ";
- zSep2 = ",\n ";
- zEnd = "\n)";
- }
- n += 35 + 6*p->nCol;
- zStmt = sqlite3DbMallocRaw(0, n);
- if( zStmt==0 ){
- db->mallocFailed = 1;
- return 0;
- }
- sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
- k = sqlite3Strlen30(zStmt);
- identPut(zStmt, &k, p->zName);
- zStmt[k++] = '(';
- for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
- static const char * const azType[] = {
- /* SQLITE_AFF_TEXT */ " TEXT",
- /* SQLITE_AFF_NONE */ "",
- /* SQLITE_AFF_NUMERIC */ " NUM",
- /* SQLITE_AFF_INTEGER */ " INT",
- /* SQLITE_AFF_REAL */ " REAL"
- };
- int len;
- const char *zType;
-
- sqlite3_snprintf(n-k, &zStmt[k], zSep);
- k += sqlite3Strlen30(&zStmt[k]);
- zSep = zSep2;
- identPut(zStmt, &k, pCol->zName);
- assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 );
- assert( pCol->affinity-SQLITE_AFF_TEXT < ArraySize(azType) );
- testcase( pCol->affinity==SQLITE_AFF_TEXT );
- testcase( pCol->affinity==SQLITE_AFF_NONE );
- testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
- testcase( pCol->affinity==SQLITE_AFF_INTEGER );
- testcase( pCol->affinity==SQLITE_AFF_REAL );
-
- zType = azType[pCol->affinity - SQLITE_AFF_TEXT];
- len = sqlite3Strlen30(zType);
- assert( pCol->affinity==SQLITE_AFF_NONE
- || pCol->affinity==sqlite3AffinityType(zType) );
- memcpy(&zStmt[k], zType, len);
- k += len;
- assert( k<=n );
- }
- sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd);
- return zStmt;
-}
-
-/*
-** This routine is called to report the final ")" that terminates
-** a CREATE TABLE statement.
-**
-** The table structure that other action routines have been building
-** is added to the internal hash tables, assuming no errors have
-** occurred.
-**
-** An entry for the table is made in the master table on disk, unless
-** this is a temporary table or db->init.busy==1. When db->init.busy==1
-** it means we are reading the sqlite_master table because we just
-** connected to the database or because the sqlite_master table has
-** recently changed, so the entry for this table already exists in
-** the sqlite_master table. We do not want to create it again.
-**
-** If the pSelect argument is not NULL, it means that this routine
-** was called to create a table generated from a
-** "CREATE TABLE ... AS SELECT ..." statement. The column names of
-** the new table will match the result set of the SELECT.
-*/
-SQLITE_PRIVATE void sqlite3EndTable(
- Parse *pParse, /* Parse context */
- Token *pCons, /* The ',' token after the last column defn. */
- Token *pEnd, /* The final ')' token in the CREATE TABLE */
- Select *pSelect /* Select from a "CREATE ... AS SELECT" */
-){
- Table *p;
- sqlite3 *db = pParse->db;
- int iDb;
-
- if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
- return;
- }
- p = pParse->pNewTable;
- if( p==0 ) return;
-
- assert( !db->init.busy || !pSelect );
-
- iDb = sqlite3SchemaToIndex(db, p->pSchema);
-
-#ifndef SQLITE_OMIT_CHECK
- /* Resolve names in all CHECK constraint expressions.
- */
- if( p->pCheck ){
- SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
- NameContext sNC; /* Name context for pParse->pNewTable */
- ExprList *pList; /* List of all CHECK constraints */
- int i; /* Loop counter */
-
- memset(&sNC, 0, sizeof(sNC));
- memset(&sSrc, 0, sizeof(sSrc));
- sSrc.nSrc = 1;
- sSrc.a[0].zName = p->zName;
- sSrc.a[0].pTab = p;
- sSrc.a[0].iCursor = -1;
- sNC.pParse = pParse;
- sNC.pSrcList = &sSrc;
- sNC.ncFlags = NC_IsCheck;
- pList = p->pCheck;
- for(i=0; i<pList->nExpr; i++){
- if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
- return;
- }
- }
- }
-#endif /* !defined(SQLITE_OMIT_CHECK) */
-
- /* If the db->init.busy is 1 it means we are reading the SQL off the
- ** "sqlite_master" or "sqlite_temp_master" table on the disk.
- ** So do not write to the disk again. Extract the root page number
- ** for the table from the db->init.newTnum field. (The page number
- ** should have been put there by the sqliteOpenCb routine.)
- */
- if( db->init.busy ){
- p->tnum = db->init.newTnum;
- }
-
- /* If not initializing, then create a record for the new table
- ** in the SQLITE_MASTER table of the database.
- **
- ** If this is a TEMPORARY table, write the entry into the auxiliary
- ** file instead of into the main database file.
- */
- if( !db->init.busy ){
- int n;
- Vdbe *v;
- char *zType; /* "view" or "table" */
- char *zType2; /* "VIEW" or "TABLE" */
- char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */
-
- v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return;
-
- sqlite3VdbeAddOp1(v, OP_Close, 0);
-
- /*
- ** Initialize zType for the new view or table.
- */
- if( p->pSelect==0 ){
- /* A regular table */
- zType = "table";
- zType2 = "TABLE";
-#ifndef SQLITE_OMIT_VIEW
- }else{
- /* A view */
- zType = "view";
- zType2 = "VIEW";
-#endif
- }
-
- /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
- ** statement to populate the new table. The root-page number for the
- ** new table is in register pParse->regRoot.
- **
- ** Once the SELECT has been coded by sqlite3Select(), it is in a
- ** suitable state to query for the column names and types to be used
- ** by the new table.
- **
- ** A shared-cache write-lock is not required to write to the new table,
- ** as a schema-lock must have already been obtained to create it. Since
- ** a schema-lock excludes all other database users, the write-lock would
- ** be redundant.
- */
- if( pSelect ){
- SelectDest dest;
- Table *pSelTab;
-
- assert(pParse->nTab==1);
- sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
- sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
- pParse->nTab = 2;
- sqlite3SelectDestInit(&dest, SRT_Table, 1);
- sqlite3Select(pParse, pSelect, &dest);
- sqlite3VdbeAddOp1(v, OP_Close, 1);
- if( pParse->nErr==0 ){
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
- if( pSelTab==0 ) return;
- assert( p->aCol==0 );
- p->nCol = pSelTab->nCol;
- p->aCol = pSelTab->aCol;
- pSelTab->nCol = 0;
- pSelTab->aCol = 0;
- sqlite3DeleteTable(db, pSelTab);
- }
- }
-
- /* Compute the complete text of the CREATE statement */
- if( pSelect ){
- zStmt = createTableStmt(db, p);
- }else{
- n = (int)(pEnd->z - pParse->sNameToken.z) + 1;
- zStmt = sqlite3MPrintf(db,
- "CREATE %s %.*s", zType2, n, pParse->sNameToken.z
- );
- }
-
- /* A slot for the record has already been allocated in the
- ** SQLITE_MASTER table. We just need to update that slot with all
- ** the information we've collected.
- */
- sqlite3NestedParse(pParse,
- "UPDATE %Q.%s "
- "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
- "WHERE rowid=#%d",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
- zType,
- p->zName,
- p->zName,
- pParse->regRoot,
- zStmt,
- pParse->regRowid
- );
- sqlite3DbFree(db, zStmt);
- sqlite3ChangeCookie(pParse, iDb);
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- /* Check to see if we need to create an sqlite_sequence table for
- ** keeping track of autoincrement keys.
- */
- if( p->tabFlags & TF_Autoincrement ){
- Db *pDb = &db->aDb[iDb];
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- if( pDb->pSchema->pSeqTab==0 ){
- sqlite3NestedParse(pParse,
- "CREATE TABLE %Q.sqlite_sequence(name,seq)",
- pDb->zName
- );
- }
- }
-#endif
-
- /* Reparse everything to update our internal data structures */
- sqlite3VdbeAddParseSchemaOp(v, iDb,
- sqlite3MPrintf(db, "tbl_name='%q'", p->zName));
- }
-
-
- /* Add the table to the in-memory representation of the database.
- */
- if( db->init.busy ){
- Table *pOld;
- Schema *pSchema = p->pSchema;
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName,
- sqlite3Strlen30(p->zName),p);
- if( pOld ){
- assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
- db->mallocFailed = 1;
- return;
- }
- pParse->pNewTable = 0;
- db->flags |= SQLITE_InternChanges;
-
-#ifndef SQLITE_OMIT_ALTERTABLE
- if( !p->pSelect ){
- const char *zName = (const char *)pParse->sNameToken.z;
- int nName;
- assert( !pSelect && pCons && pEnd );
- if( pCons->z==0 ){
- pCons = pEnd;
- }
- nName = (int)((const char *)pCons->z - zName);
- p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName);
- }
-#endif
- }
-}
-
-#ifndef SQLITE_OMIT_VIEW
-/*
-** The parser calls this routine in order to create a new VIEW
-*/
-SQLITE_PRIVATE void sqlite3CreateView(
- Parse *pParse, /* The parsing context */
- Token *pBegin, /* The CREATE token that begins the statement */
- Token *pName1, /* The token that holds the name of the view */
- Token *pName2, /* The token that holds the name of the view */
- Select *pSelect, /* A SELECT statement that will become the new view */
- int isTemp, /* TRUE for a TEMPORARY view */
- int noErr /* Suppress error messages if VIEW already exists */
-){
- Table *p;
- int n;
- const char *z;
- Token sEnd;
- DbFixer sFix;
- Token *pName = 0;
- int iDb;
- sqlite3 *db = pParse->db;
-
- if( pParse->nVar>0 ){
- sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
- sqlite3SelectDelete(db, pSelect);
- return;
- }
- sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
- p = pParse->pNewTable;
- if( p==0 || pParse->nErr ){
- sqlite3SelectDelete(db, pSelect);
- return;
- }
- sqlite3TwoPartName(pParse, pName1, pName2, &pName);
- iDb = sqlite3SchemaToIndex(db, p->pSchema);
- if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
- && sqlite3FixSelect(&sFix, pSelect)
- ){
- sqlite3SelectDelete(db, pSelect);
- return;
- }
-
- /* Make a copy of the entire SELECT statement that defines the view.
- ** This will force all the Expr.token.z values to be dynamically
- ** allocated rather than point to the input string - which means that
- ** they will persist after the current sqlite3_exec() call returns.
- */
- p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
- sqlite3SelectDelete(db, pSelect);
- if( db->mallocFailed ){
- return;
- }
- if( !db->init.busy ){
- sqlite3ViewGetColumnNames(pParse, p);
- }
-
- /* Locate the end of the CREATE VIEW statement. Make sEnd point to
- ** the end.
- */
- sEnd = pParse->sLastToken;
- if( ALWAYS(sEnd.z[0]!=0) && sEnd.z[0]!=';' ){
- sEnd.z += sEnd.n;
- }
- sEnd.n = 0;
- n = (int)(sEnd.z - pBegin->z);
- z = pBegin->z;
- while( ALWAYS(n>0) && sqlite3Isspace(z[n-1]) ){ n--; }
- sEnd.z = &z[n-1];
- sEnd.n = 1;
-
- /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
- sqlite3EndTable(pParse, 0, &sEnd, 0);
- return;
-}
-#endif /* SQLITE_OMIT_VIEW */
-
-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
-/*
-** The Table structure pTable is really a VIEW. Fill in the names of
-** the columns of the view in the pTable structure. Return the number
-** of errors. If an error is seen leave an error message in pParse->zErrMsg.
-*/
-SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
- Table *pSelTab; /* A fake table from which we get the result set */
- Select *pSel; /* Copy of the SELECT that implements the view */
- int nErr = 0; /* Number of errors encountered */
- int n; /* Temporarily holds the number of cursors assigned */
- sqlite3 *db = pParse->db; /* Database connection for malloc errors */
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
-
- assert( pTable );
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( sqlite3VtabCallConnect(pParse, pTable) ){
- return SQLITE_ERROR;
- }
- if( IsVirtual(pTable) ) return 0;
-#endif
-
-#ifndef SQLITE_OMIT_VIEW
- /* A positive nCol means the columns names for this view are
- ** already known.
- */
- if( pTable->nCol>0 ) return 0;
-
- /* A negative nCol is a special marker meaning that we are currently
- ** trying to compute the column names. If we enter this routine with
- ** a negative nCol, it means two or more views form a loop, like this:
- **
- ** CREATE VIEW one AS SELECT * FROM two;
- ** CREATE VIEW two AS SELECT * FROM one;
- **
- ** Actually, the error above is now caught prior to reaching this point.
- ** But the following test is still important as it does come up
- ** in the following:
- **
- ** CREATE TABLE main.ex1(a);
- ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1;
- ** SELECT * FROM temp.ex1;
- */
- if( pTable->nCol<0 ){
- sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
- return 1;
- }
- assert( pTable->nCol>=0 );
-
- /* If we get this far, it means we need to compute the table names.
- ** Note that the call to sqlite3ResultSetOfSelect() will expand any
- ** "*" elements in the results set of the view and will assign cursors
- ** to the elements of the FROM clause. But we do not want these changes
- ** to be permanent. So the computation is done on a copy of the SELECT
- ** statement that defines the view.
- */
- assert( pTable->pSelect );
- pSel = sqlite3SelectDup(db, pTable->pSelect, 0);
- if( pSel ){
- u8 enableLookaside = db->lookaside.bEnabled;
- n = pParse->nTab;
- sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
- pTable->nCol = -1;
- db->lookaside.bEnabled = 0;
-#ifndef SQLITE_OMIT_AUTHORIZATION
- xAuth = db->xAuth;
- db->xAuth = 0;
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
- db->xAuth = xAuth;
-#else
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);
-#endif
- db->lookaside.bEnabled = enableLookaside;
- pParse->nTab = n;
- if( pSelTab ){
- assert( pTable->aCol==0 );
- pTable->nCol = pSelTab->nCol;
- pTable->aCol = pSelTab->aCol;
- pSelTab->nCol = 0;
- pSelTab->aCol = 0;
- sqlite3DeleteTable(db, pSelTab);
- assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
- pTable->pSchema->flags |= DB_UnresetViews;
- }else{
- pTable->nCol = 0;
- nErr++;
- }
- sqlite3SelectDelete(db, pSel);
- } else {
- nErr++;
- }
-#endif /* SQLITE_OMIT_VIEW */
- return nErr;
-}
-#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
-
-#ifndef SQLITE_OMIT_VIEW
-/*
-** Clear the column names from every VIEW in database idx.
-*/
-static void sqliteViewResetAll(sqlite3 *db, int idx){
- HashElem *i;
- assert( sqlite3SchemaMutexHeld(db, idx, 0) );
- if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
- for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
- Table *pTab = sqliteHashData(i);
- if( pTab->pSelect ){
- sqliteDeleteColumnNames(db, pTab);
- pTab->aCol = 0;
- pTab->nCol = 0;
- }
- }
- DbClearProperty(db, idx, DB_UnresetViews);
-}
-#else
-# define sqliteViewResetAll(A,B)
-#endif /* SQLITE_OMIT_VIEW */
-
-/*
-** This function is called by the VDBE to adjust the internal schema
-** used by SQLite when the btree layer moves a table root page. The
-** root-page of a table or index in database iDb has changed from iFrom
-** to iTo.
-**
-** Ticket #1728: The symbol table might still contain information
-** on tables and/or indices that are the process of being deleted.
-** If you are unlucky, one of those deleted indices or tables might
-** have the same rootpage number as the real table or index that is
-** being moved. So we cannot stop searching after the first match
-** because the first match might be for one of the deleted indices
-** or tables and not the table/index that is actually being moved.
-** We must continue looping until all tables and indices with
-** rootpage==iFrom have been converted to have a rootpage of iTo
-** in order to be certain that we got the right one.
-*/
-#ifndef SQLITE_OMIT_AUTOVACUUM
-SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){
- HashElem *pElem;
- Hash *pHash;
- Db *pDb;
-
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- pDb = &db->aDb[iDb];
- pHash = &pDb->pSchema->tblHash;
- for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){
- Table *pTab = sqliteHashData(pElem);
- if( pTab->tnum==iFrom ){
- pTab->tnum = iTo;
- }
- }
- pHash = &pDb->pSchema->idxHash;
- for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){
- Index *pIdx = sqliteHashData(pElem);
- if( pIdx->tnum==iFrom ){
- pIdx->tnum = iTo;
- }
- }
-}
-#endif
-
-/*
-** Write code to erase the table with root-page iTable from database iDb.
-** Also write code to modify the sqlite_master table and internal schema
-** if a root-page of another table is moved by the btree-layer whilst
-** erasing iTable (this can happen with an auto-vacuum database).
-*/
-static void destroyRootPage(Parse *pParse, int iTable, int iDb){
- Vdbe *v = sqlite3GetVdbe(pParse);
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
- sqlite3MayAbort(pParse);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- /* OP_Destroy stores an in integer r1. If this integer
- ** is non-zero, then it is the root page number of a table moved to
- ** location iTable. The following code modifies the sqlite_master table to
- ** reflect this.
- **
- ** The "#NNN" in the SQL is a special constant that means whatever value
- ** is in register NNN. See grammar rules associated with the TK_REGISTER
- ** token for additional information.
- */
- sqlite3NestedParse(pParse,
- "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
- pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);
-#endif
- sqlite3ReleaseTempReg(pParse, r1);
-}
-
-/*
-** Write VDBE code to erase table pTab and all associated indices on disk.
-** Code to update the sqlite_master tables and internal schema definitions
-** in case a root-page belonging to another table is moved by the btree layer
-** is also added (this can happen with an auto-vacuum database).
-*/
-static void destroyTable(Parse *pParse, Table *pTab){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- Index *pIdx;
- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- destroyRootPage(pParse, pTab->tnum, iDb);
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- destroyRootPage(pParse, pIdx->tnum, iDb);
- }
-#else
- /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
- ** is not defined), then it is important to call OP_Destroy on the
- ** table and index root-pages in order, starting with the numerically
- ** largest root-page number. This guarantees that none of the root-pages
- ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the
- ** following were coded:
- **
- ** OP_Destroy 4 0
- ** ...
- ** OP_Destroy 5 0
- **
- ** and root page 5 happened to be the largest root-page number in the
- ** database, then root page 5 would be moved to page 4 by the
- ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit
- ** a free-list page.
- */
- int iTab = pTab->tnum;
- int iDestroyed = 0;
-
- while( 1 ){
- Index *pIdx;
- int iLargest = 0;
-
- if( iDestroyed==0 || iTab<iDestroyed ){
- iLargest = iTab;
- }
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- int iIdx = pIdx->tnum;
- assert( pIdx->pSchema==pTab->pSchema );
- if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){
- iLargest = iIdx;
- }
- }
- if( iLargest==0 ){
- return;
- }else{
- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- assert( iDb>=0 && iDb<pParse->db->nDb );
- destroyRootPage(pParse, iLargest, iDb);
- iDestroyed = iLargest;
- }
- }
-#endif
-}
-
-/*
-** Remove entries from the sqlite_statN tables (for N in (1,2,3))
-** after a DROP INDEX or DROP TABLE command.
-*/
-static void sqlite3ClearStatTables(
- Parse *pParse, /* The parsing context */
- int iDb, /* The database number */
- const char *zType, /* "idx" or "tbl" */
- const char *zName /* Name of index or table */
-){
- int i;
- const char *zDbName = pParse->db->aDb[iDb].zName;
- for(i=1; i<=3; i++){
- char zTab[24];
- sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
- if( sqlite3FindTable(pParse->db, zTab, zDbName) ){
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.%s WHERE %s=%Q",
- zDbName, zTab, zType, zName
- );
- }
- }
-}
-
-/*
-** Generate code to drop a table.
-*/
-SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
- Vdbe *v;
- sqlite3 *db = pParse->db;
- Trigger *pTrigger;
- Db *pDb = &db->aDb[iDb];
-
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 );
- sqlite3BeginWriteOperation(pParse, 1, iDb);
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- sqlite3VdbeAddOp0(v, OP_VBegin);
- }
-#endif
-
- /* Drop all triggers associated with the table being dropped. Code
- ** is generated to remove entries from sqlite_master and/or
- ** sqlite_temp_master if required.
- */
- pTrigger = sqlite3TriggerList(pParse, pTab);
- while( pTrigger ){
- assert( pTrigger->pSchema==pTab->pSchema ||
- pTrigger->pSchema==db->aDb[1].pSchema );
- sqlite3DropTriggerPtr(pParse, pTrigger);
- pTrigger = pTrigger->pNext;
- }
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
- /* Remove any entries of the sqlite_sequence table associated with
- ** the table being dropped. This is done before the table is dropped
- ** at the btree level, in case the sqlite_sequence table needs to
- ** move as a result of the drop (can happen in auto-vacuum mode).
- */
- if( pTab->tabFlags & TF_Autoincrement ){
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
- pDb->zName, pTab->zName
- );
- }
-#endif
-
- /* Drop all SQLITE_MASTER table and index entries that refer to the
- ** table. The program name loops through the master table and deletes
- ** every row that refers to a table of the same name as the one being
- ** dropped. Triggers are handled seperately because a trigger can be
- ** created in the temp database that refers to a table in another
- ** database.
- */
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
- pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
- if( !isView && !IsVirtual(pTab) ){
- destroyTable(pParse, pTab);
- }
-
- /* Remove the table entry from SQLite's internal schema and modify
- ** the schema cookie.
- */
- if( IsVirtual(pTab) ){
- sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
- }
- sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
- sqlite3ChangeCookie(pParse, iDb);
- sqliteViewResetAll(db, iDb);
-}
-
-/*
-** This routine is called to do the work of a DROP TABLE statement.
-** pName is the name of the table to be dropped.
-*/
-SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
- Table *pTab;
- Vdbe *v;
- sqlite3 *db = pParse->db;
- int iDb;
-
- if( db->mallocFailed ){
- goto exit_drop_table;
- }
- assert( pParse->nErr==0 );
- assert( pName->nSrc==1 );
- if( noErr ) db->suppressErr++;
- pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
- if( noErr ) db->suppressErr--;
-
- if( pTab==0 ){
- if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
- goto exit_drop_table;
- }
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( iDb>=0 && iDb<db->nDb );
-
- /* If pTab is a virtual table, call ViewGetColumnNames() to ensure
- ** it is initialized.
- */
- if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto exit_drop_table;
- }
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int code;
- const char *zTab = SCHEMA_TABLE(iDb);
- const char *zDb = db->aDb[iDb].zName;
- const char *zArg2 = 0;
- if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
- goto exit_drop_table;
- }
- if( isView ){
- if( !OMIT_TEMPDB && iDb==1 ){
- code = SQLITE_DROP_TEMP_VIEW;
- }else{
- code = SQLITE_DROP_VIEW;
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( IsVirtual(pTab) ){
- code = SQLITE_DROP_VTABLE;
- zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName;
-#endif
- }else{
- if( !OMIT_TEMPDB && iDb==1 ){
- code = SQLITE_DROP_TEMP_TABLE;
- }else{
- code = SQLITE_DROP_TABLE;
- }
- }
- if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){
- goto exit_drop_table;
- }
- if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
- goto exit_drop_table;
- }
- }
-#endif
- if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
- && sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){
- sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
- goto exit_drop_table;
- }
-
-#ifndef SQLITE_OMIT_VIEW
- /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used
- ** on a table.
- */
- if( isView && pTab->pSelect==0 ){
- sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);
- goto exit_drop_table;
- }
- if( !isView && pTab->pSelect ){
- sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);
- goto exit_drop_table;
- }
-#endif
-
- /* Generate code to remove the table from the master table
- ** on disk.
- */
- v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3BeginWriteOperation(pParse, 1, iDb);
- sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
- sqlite3FkDropTable(pParse, pName, pTab);
- sqlite3CodeDropTable(pParse, pTab, iDb, isView);
- }
-
-exit_drop_table:
- sqlite3SrcListDelete(db, pName);
-}
-
-/*
-** This routine is called to create a new foreign key on the table
-** currently under construction. pFromCol determines which columns
-** in the current table point to the foreign key. If pFromCol==0 then
-** connect the key to the last column inserted. pTo is the name of
-** the table referred to. pToCol is a list of tables in the other
-** pTo table that the foreign key points to. flags contains all
-** information about the conflict resolution algorithms specified
-** in the ON DELETE, ON UPDATE and ON INSERT clauses.
-**
-** An FKey structure is created and added to the table currently
-** under construction in the pParse->pNewTable field.
-**
-** The foreign key is set for IMMEDIATE processing. A subsequent call
-** to sqlite3DeferForeignKey() might change this to DEFERRED.
-*/
-SQLITE_PRIVATE void sqlite3CreateForeignKey(
- Parse *pParse, /* Parsing context */
- ExprList *pFromCol, /* Columns in this table that point to other table */
- Token *pTo, /* Name of the other table */
- ExprList *pToCol, /* Columns in the other table */
- int flags /* Conflict resolution algorithms. */
-){
- sqlite3 *db = pParse->db;
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- FKey *pFKey = 0;
- FKey *pNextTo;
- Table *p = pParse->pNewTable;
- int nByte;
- int i;
- int nCol;
- char *z;
-
- assert( pTo!=0 );
- if( p==0 || IN_DECLARE_VTAB ) goto fk_end;
- if( pFromCol==0 ){
- int iCol = p->nCol-1;
- if( NEVER(iCol<0) ) goto fk_end;
- if( pToCol && pToCol->nExpr!=1 ){
- sqlite3ErrorMsg(pParse, "foreign key on %s"
- " should reference only one column of table %T",
- p->aCol[iCol].zName, pTo);
- goto fk_end;
- }
- nCol = 1;
- }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){
- sqlite3ErrorMsg(pParse,
- "number of columns in foreign key does not match the number of "
- "columns in the referenced table");
- goto fk_end;
- }else{
- nCol = pFromCol->nExpr;
- }
- nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1;
- if( pToCol ){
- for(i=0; i<pToCol->nExpr; i++){
- nByte += sqlite3Strlen30(pToCol->a[i].zName) + 1;
- }
- }
- pFKey = sqlite3DbMallocZero(db, nByte );
- if( pFKey==0 ){
- goto fk_end;
- }
- pFKey->pFrom = p;
- pFKey->pNextFrom = p->pFKey;
- z = (char*)&pFKey->aCol[nCol];
- pFKey->zTo = z;
- memcpy(z, pTo->z, pTo->n);
- z[pTo->n] = 0;
- sqlite3Dequote(z);
- z += pTo->n+1;
- pFKey->nCol = nCol;
- if( pFromCol==0 ){
- pFKey->aCol[0].iFrom = p->nCol-1;
- }else{
- for(i=0; i<nCol; i++){
- int j;
- for(j=0; j<p->nCol; j++){
- if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
- pFKey->aCol[i].iFrom = j;
- break;
- }
- }
- if( j>=p->nCol ){
- sqlite3ErrorMsg(pParse,
- "unknown column \"%s\" in foreign key definition",
- pFromCol->a[i].zName);
- goto fk_end;
- }
- }
- }
- if( pToCol ){
- for(i=0; i<nCol; i++){
- int n = sqlite3Strlen30(pToCol->a[i].zName);
- pFKey->aCol[i].zCol = z;
- memcpy(z, pToCol->a[i].zName, n);
- z[n] = 0;
- z += n+1;
- }
- }
- pFKey->isDeferred = 0;
- pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */
- pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */
-
- assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
- pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash,
- pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey
- );
- if( pNextTo==pFKey ){
- db->mallocFailed = 1;
- goto fk_end;
- }
- if( pNextTo ){
- assert( pNextTo->pPrevTo==0 );
- pFKey->pNextTo = pNextTo;
- pNextTo->pPrevTo = pFKey;
- }
-
- /* Link the foreign key to the table as the last step.
- */
- p->pFKey = pFKey;
- pFKey = 0;
-
-fk_end:
- sqlite3DbFree(db, pFKey);
-#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
- sqlite3ExprListDelete(db, pFromCol);
- sqlite3ExprListDelete(db, pToCol);
-}
-
-/*
-** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED
-** clause is seen as part of a foreign key definition. The isDeferred
-** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE.
-** The behavior of the most recently created foreign key is adjusted
-** accordingly.
-*/
-SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- Table *pTab;
- FKey *pFKey;
- if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
- assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */
- pFKey->isDeferred = (u8)isDeferred;
-#endif
-}
-
-/*
-** Generate code that will erase and refill index *pIdx. This is
-** used to initialize a newly created index or to recompute the
-** content of an index in response to a REINDEX command.
-**
-** if memRootPage is not negative, it means that the index is newly
-** created. The register specified by memRootPage contains the
-** root page number of the index. If memRootPage is negative, then
-** the index already exists and must be cleared before being refilled and
-** the root page number of the index is taken from pIndex->tnum.
-*/
-static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
- Table *pTab = pIndex->pTable; /* The table that is indexed */
- int iTab = pParse->nTab++; /* Btree cursor used for pTab */
- int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */
- int iSorter; /* Cursor opened by OpenSorter (if in use) */
- int addr1; /* Address of top of loop */
- int addr2; /* Address to jump to for next iteration */
- int tnum; /* Root page of index */
- Vdbe *v; /* Generate code into this virtual machine */
- KeyInfo *pKey; /* KeyInfo for index */
-#ifdef SQLITE_OMIT_MERGE_SORT
- int regIdxKey; /* Registers containing the index key */
-#endif
- int regRecord; /* Register holding assemblied index record */
- sqlite3 *db = pParse->db; /* The database connection */
- int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
- db->aDb[iDb].zName ) ){
- return;
- }
-#endif
-
- /* Require a write-lock on the table to perform this operation */
- sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
-
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
- if( memRootPage>=0 ){
- tnum = memRootPage;
- }else{
- tnum = pIndex->tnum;
- sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
- }
- pKey = sqlite3IndexKeyinfo(pParse, pIndex);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
- (char *)pKey, P4_KEYINFO_HANDOFF);
- sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
-
-#ifndef SQLITE_OMIT_MERGE_SORT
- /* Open the sorter cursor if we are to use one. */
- iSorter = pParse->nTab++;
- sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
-#else
- iSorter = iTab;
-#endif
-
- /* Open the table. Loop through all rows of the table, inserting index
- ** records into the sorter. */
- sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
- regRecord = sqlite3GetTempReg(pParse);
-
-#ifndef SQLITE_OMIT_MERGE_SORT
- sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
- sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
- sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
- sqlite3VdbeJumpHere(v, addr1);
- addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
- if( pIndex->onError!=OE_None ){
- int j2 = sqlite3VdbeCurrentAddr(v) + 3;
- sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
- addr2 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
- sqlite3HaltConstraint(
- pParse, OE_Abort, "indexed columns are not unique", P4_STATIC
- );
- }else{
- addr2 = sqlite3VdbeCurrentAddr(v);
- }
- sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
- sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
-#else
- regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
- addr2 = addr1 + 1;
- if( pIndex->onError!=OE_None ){
- const int regRowid = regIdxKey + pIndex->nColumn;
- const int j2 = sqlite3VdbeCurrentAddr(v) + 2;
- void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);
-
- /* The registers accessed by the OP_IsUnique opcode were allocated
- ** using sqlite3GetTempRange() inside of the sqlite3GenerateIndexKey()
- ** call above. Just before that function was freed they were released
- ** (made available to the compiler for reuse) using
- ** sqlite3ReleaseTempRange(). So in some ways having the OP_IsUnique
- ** opcode use the values stored within seems dangerous. However, since
- ** we can be sure that no other temp registers have been allocated
- ** since sqlite3ReleaseTempRange() was called, it is safe to do so.
- */
- sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);
- sqlite3HaltConstraint(
- pParse, OE_Abort, "indexed columns are not unique", P4_STATIC);
- }
- sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
-#endif
- sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2);
- sqlite3VdbeJumpHere(v, addr1);
-
- sqlite3VdbeAddOp1(v, OP_Close, iTab);
- sqlite3VdbeAddOp1(v, OP_Close, iIdx);
- sqlite3VdbeAddOp1(v, OP_Close, iSorter);
-}
-
-/*
-** Create a new index for an SQL table. pName1.pName2 is the name of the index
-** and pTblList is the name of the table that is to be indexed. Both will
-** be NULL for a primary key or an index that is created to satisfy a
-** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable
-** as the table to be indexed. pParse->pNewTable is a table that is
-** currently being constructed by a CREATE TABLE statement.
-**
-** pList is a list of columns to be indexed. pList will be NULL if this
-** is a primary key or unique-constraint on the most recent column added
-** to the table currently under construction.
-**
-** If the index is created successfully, return a pointer to the new Index
-** structure. This is used by sqlite3AddPrimaryKey() to mark the index
-** as the tables primary key (Index.autoIndex==2).
-*/
-SQLITE_PRIVATE Index *sqlite3CreateIndex(
- Parse *pParse, /* All information about this parse */
- Token *pName1, /* First part of index name. May be NULL */
- Token *pName2, /* Second part of index name. May be NULL */
- SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
- ExprList *pList, /* A list of columns to be indexed */
- int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
- Token *pStart, /* The CREATE token that begins this statement */
- Token *pEnd, /* The ")" that closes the CREATE INDEX statement */
- int sortOrder, /* Sort order of primary key when pList==NULL */
- int ifNotExist /* Omit error if index already exists */
-){
- Index *pRet = 0; /* Pointer to return */
- Table *pTab = 0; /* Table to be indexed */
- Index *pIndex = 0; /* The index to be created */
- char *zName = 0; /* Name of the index */
- int nName; /* Number of characters in zName */
- int i, j;
- Token nullId; /* Fake token for an empty ID list */
- DbFixer sFix; /* For assigning database names to pTable */
- int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */
- sqlite3 *db = pParse->db;
- Db *pDb; /* The specific table containing the indexed database */
- int iDb; /* Index of the database that is being written */
- Token *pName = 0; /* Unqualified name of the index to create */
- struct ExprList_item *pListItem; /* For looping over pList */
- int nCol;
- int nExtra = 0;
- char *zExtra;
-
- assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
- assert( pParse->nErr==0 ); /* Never called with prior errors */
- if( db->mallocFailed || IN_DECLARE_VTAB ){
- goto exit_create_index;
- }
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- goto exit_create_index;
- }
-
- /*
- ** Find the table that is to be indexed. Return early if not found.
- */
- if( pTblName!=0 ){
-
- /* Use the two-part index name to determine the database
- ** to search for the table. 'Fix' the table name to this db
- ** before looking up the table.
- */
- assert( pName1 && pName2 );
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
- if( iDb<0 ) goto exit_create_index;
- assert( pName && pName->z );
-
-#ifndef SQLITE_OMIT_TEMPDB
- /* If the index name was unqualified, check if the table
- ** is a temp table. If so, set the database to 1. Do not do this
- ** if initialising a database schema.
- */
- if( !db->init.busy ){
- pTab = sqlite3SrcListLookup(pParse, pTblName);
- if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
- iDb = 1;
- }
- }
-#endif
-
- if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
- sqlite3FixSrcList(&sFix, pTblName)
- ){
- /* Because the parser constructs pTblName from a single identifier,
- ** sqlite3FixSrcList can never fail. */
- assert(0);
- }
- pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
- assert( db->mallocFailed==0 || pTab==0 );
- if( pTab==0 ) goto exit_create_index;
- assert( db->aDb[iDb].pSchema==pTab->pSchema );
- }else{
- assert( pName==0 );
- assert( pStart==0 );
- pTab = pParse->pNewTable;
- if( !pTab ) goto exit_create_index;
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- }
- pDb = &db->aDb[iDb];
-
- assert( pTab!=0 );
- assert( pParse->nErr==0 );
- if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
- && memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
- sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
- goto exit_create_index;
- }
-#ifndef SQLITE_OMIT_VIEW
- if( pTab->pSelect ){
- sqlite3ErrorMsg(pParse, "views may not be indexed");
- goto exit_create_index;
- }
-#endif
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- sqlite3ErrorMsg(pParse, "virtual tables may not be indexed");
- goto exit_create_index;
- }
-#endif
-
- /*
- ** Find the name of the index. Make sure there is not already another
- ** index or table with the same name.
- **
- ** Exception: If we are reading the names of permanent indices from the
- ** sqlite_master table (because some other process changed the schema) and
- ** one of the index names collides with the name of a temporary table or
- ** index, then we will continue to process this index.
- **
- ** If pName==0 it means that we are
- ** dealing with a primary key or UNIQUE constraint. We have to invent our
- ** own name.
- */
- if( pName ){
- zName = sqlite3NameFromToken(db, pName);
- if( zName==0 ) goto exit_create_index;
- assert( pName->z!=0 );
- if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
- goto exit_create_index;
- }
- if( !db->init.busy ){
- if( sqlite3FindTable(db, zName, 0)!=0 ){
- sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
- goto exit_create_index;
- }
- }
- if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
- if( !ifNotExist ){
- sqlite3ErrorMsg(pParse, "index %s already exists", zName);
- }else{
- assert( !db->init.busy );
- sqlite3CodeVerifySchema(pParse, iDb);
- }
- goto exit_create_index;
- }
- }else{
- int n;
- Index *pLoop;
- for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
- zName = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n);
- if( zName==0 ){
- goto exit_create_index;
- }
- }
-
- /* Check for authorization to create an index.
- */
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- const char *zDb = pDb->zName;
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
- goto exit_create_index;
- }
- i = SQLITE_CREATE_INDEX;
- if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX;
- if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
- goto exit_create_index;
- }
- }
-#endif
-
- /* If pList==0, it means this routine was called to make a primary
- ** key out of the last column added to the table under construction.
- ** So create a fake list to simulate this.
- */
- if( pList==0 ){
- nullId.z = pTab->aCol[pTab->nCol-1].zName;
- nullId.n = sqlite3Strlen30((char*)nullId.z);
- pList = sqlite3ExprListAppend(pParse, 0, 0);
- if( pList==0 ) goto exit_create_index;
- sqlite3ExprListSetName(pParse, pList, &nullId, 0);
- pList->a[0].sortOrder = (u8)sortOrder;
- }
-
- /* Figure out how many bytes of space are required to store explicitly
- ** specified collation sequence names.
- */
- for(i=0; i<pList->nExpr; i++){
- Expr *pExpr = pList->a[i].pExpr;
- if( pExpr ){
- CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
- if( pColl ){
- nExtra += (1 + sqlite3Strlen30(pColl->zName));
- }
- }
- }
-
- /*
- ** Allocate the index structure.
- */
- nName = sqlite3Strlen30(zName);
- nCol = pList->nExpr;
- pIndex = sqlite3DbMallocZero(db,
- ROUND8(sizeof(Index)) + /* Index structure */
- ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */
- sizeof(char *)*nCol + /* Index.azColl */
- sizeof(int)*nCol + /* Index.aiColumn */
- sizeof(u8)*nCol + /* Index.aSortOrder */
- nName + 1 + /* Index.zName */
- nExtra /* Collation sequence names */
- );
- if( db->mallocFailed ){
- goto exit_create_index;
- }
- zExtra = (char*)pIndex;
- pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))];
- pIndex->azColl = (char**)
- ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
- assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
- assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
- pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
- pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
- pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
- zExtra = (char *)(&pIndex->zName[nName+1]);
- memcpy(pIndex->zName, zName, nName+1);
- pIndex->pTable = pTab;
- pIndex->nColumn = pList->nExpr;
- pIndex->onError = (u8)onError;
- pIndex->autoIndex = (u8)(pName==0);
- pIndex->pSchema = db->aDb[iDb].pSchema;
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
-
- /* Check to see if we should honor DESC requests on index columns
- */
- if( pDb->pSchema->file_format>=4 ){
- sortOrderMask = -1; /* Honor DESC */
- }else{
- sortOrderMask = 0; /* Ignore DESC */
- }
-
- /* Scan the names of the columns of the table to be indexed and
- ** load the column indices into the Index structure. Report an error
- ** if any column is not found.
- **
- ** TODO: Add a test to make sure that the same column is not named
- ** more than once within the same index. Only the first instance of
- ** the column will ever be used by the optimizer. Note that using the
- ** same column more than once cannot be an error because that would
- ** break backwards compatibility - it needs to be a warning.
- */
- for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
- const char *zColName = pListItem->zName;
- Column *pTabCol;
- int requestedSortOrder;
- CollSeq *pColl; /* Collating sequence */
- char *zColl; /* Collation sequence name */
-
- for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
- if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
- }
- if( j>=pTab->nCol ){
- sqlite3ErrorMsg(pParse, "table %s has no column named %s",
- pTab->zName, zColName);
- pParse->checkSchema = 1;
- goto exit_create_index;
- }
- pIndex->aiColumn[i] = j;
- if( pListItem->pExpr
- && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
- ){
- int nColl;
- zColl = pColl->zName;
- nColl = sqlite3Strlen30(zColl) + 1;
- assert( nExtra>=nColl );
- memcpy(zExtra, zColl, nColl);
- zColl = zExtra;
- zExtra += nColl;
- nExtra -= nColl;
- }else{
- zColl = pTab->aCol[j].zColl;
- if( !zColl ){
- zColl = "BINARY";
- }
- }
- if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
- goto exit_create_index;
- }
- pIndex->azColl[i] = zColl;
- requestedSortOrder = pListItem->sortOrder & sortOrderMask;
- pIndex->aSortOrder[i] = (u8)requestedSortOrder;
- }
- sqlite3DefaultRowEst(pIndex);
-
- if( pTab==pParse->pNewTable ){
- /* This routine has been called to create an automatic index as a
- ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
- ** a PRIMARY KEY or UNIQUE clause following the column definitions.
- ** i.e. one of:
- **
- ** CREATE TABLE t(x PRIMARY KEY, y);
- ** CREATE TABLE t(x, y, UNIQUE(x, y));
- **
- ** Either way, check to see if the table already has such an index. If
- ** so, don't bother creating this one. This only applies to
- ** automatically created indices. Users can do as they wish with
- ** explicit indices.
- **
- ** Two UNIQUE or PRIMARY KEY constraints are considered equivalent
- ** (and thus suppressing the second one) even if they have different
- ** sort orders.
- **
- ** If there are different collating sequences or if the columns of
- ** the constraint occur in different orders, then the constraints are
- ** considered distinct and both result in separate indices.
- */
- Index *pIdx;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- int k;
- assert( pIdx->onError!=OE_None );
- assert( pIdx->autoIndex );
- assert( pIndex->onError!=OE_None );
-
- if( pIdx->nColumn!=pIndex->nColumn ) continue;
- for(k=0; k<pIdx->nColumn; k++){
- const char *z1;
- const char *z2;
- if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
- z1 = pIdx->azColl[k];
- z2 = pIndex->azColl[k];
- if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
- }
- if( k==pIdx->nColumn ){
- if( pIdx->onError!=pIndex->onError ){
- /* This constraint creates the same index as a previous
- ** constraint specified somewhere in the CREATE TABLE statement.
- ** However the ON CONFLICT clauses are different. If both this
- ** constraint and the previous equivalent constraint have explicit
- ** ON CONFLICT clauses this is an error. Otherwise, use the
- ** explicitly specified behaviour for the index.
- */
- if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){
- sqlite3ErrorMsg(pParse,
- "conflicting ON CONFLICT clauses specified", 0);
- }
- if( pIdx->onError==OE_Default ){
- pIdx->onError = pIndex->onError;
- }
- }
- goto exit_create_index;
- }
- }
- }
-
- /* Link the new Index structure to its table and to the other
- ** in-memory database structures.
- */
- if( db->init.busy ){
- Index *p;
- assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
- p = sqlite3HashInsert(&pIndex->pSchema->idxHash,
- pIndex->zName, sqlite3Strlen30(pIndex->zName),
- pIndex);
- if( p ){
- assert( p==pIndex ); /* Malloc must have failed */
- db->mallocFailed = 1;
- goto exit_create_index;
- }
- db->flags |= SQLITE_InternChanges;
- if( pTblName!=0 ){
- pIndex->tnum = db->init.newTnum;
- }
- }
-
- /* If the db->init.busy is 0 then create the index on disk. This
- ** involves writing the index into the master table and filling in the
- ** index with the current table contents.
- **
- ** The db->init.busy is 0 when the user first enters a CREATE INDEX
- ** command. db->init.busy is 1 when a database is opened and
- ** CREATE INDEX statements are read out of the master table. In
- ** the latter case the index already exists on disk, which is why
- ** we don't want to recreate it.
- **
- ** If pTblName==0 it means this index is generated as a primary key
- ** or UNIQUE constraint of a CREATE TABLE statement. Since the table
- ** has just been created, it contains no data and the index initialization
- ** step can be skipped.
- */
- else{ /* if( db->init.busy==0 ) */
- Vdbe *v;
- char *zStmt;
- int iMem = ++pParse->nMem;
-
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto exit_create_index;
-
-
- /* Create the rootpage for the index
- */
- sqlite3BeginWriteOperation(pParse, 1, iDb);
- sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
-
- /* Gather the complete text of the CREATE INDEX statement into
- ** the zStmt variable
- */
- if( pStart ){
- assert( pEnd!=0 );
- /* A named index with an explicit CREATE INDEX statement */
- zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
- onError==OE_None ? "" : " UNIQUE",
- (int)(pEnd->z - pName->z) + 1,
- pName->z);
- }else{
- /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
- /* zStmt = sqlite3MPrintf(""); */
- zStmt = 0;
- }
-
- /* Add an entry in sqlite_master for this index
- */
- sqlite3NestedParse(pParse,
- "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
- pIndex->zName,
- pTab->zName,
- iMem,
- zStmt
- );
- sqlite3DbFree(db, zStmt);
-
- /* Fill the index with data and reparse the schema. Code an OP_Expire
- ** to invalidate all pre-compiled statements.
- */
- if( pTblName ){
- sqlite3RefillIndex(pParse, pIndex, iMem);
- sqlite3ChangeCookie(pParse, iDb);
- sqlite3VdbeAddParseSchemaOp(v, iDb,
- sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
- sqlite3VdbeAddOp1(v, OP_Expire, 0);
- }
- }
-
- /* When adding an index to the list of indices for a table, make
- ** sure all indices labeled OE_Replace come after all those labeled
- ** OE_Ignore. This is necessary for the correct constraint check
- ** processing (in sqlite3GenerateConstraintChecks()) as part of
- ** UPDATE and INSERT statements.
- */
- if( db->init.busy || pTblName==0 ){
- if( onError!=OE_Replace || pTab->pIndex==0
- || pTab->pIndex->onError==OE_Replace){
- pIndex->pNext = pTab->pIndex;
- pTab->pIndex = pIndex;
- }else{
- Index *pOther = pTab->pIndex;
- while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
- pOther = pOther->pNext;
- }
- pIndex->pNext = pOther->pNext;
- pOther->pNext = pIndex;
- }
- pRet = pIndex;
- pIndex = 0;
- }
-
- /* Clean up before exiting */
-exit_create_index:
- if( pIndex ){
- sqlite3DbFree(db, pIndex->zColAff);
- sqlite3DbFree(db, pIndex);
- }
- sqlite3ExprListDelete(db, pList);
- sqlite3SrcListDelete(db, pTblName);
- sqlite3DbFree(db, zName);
- return pRet;
-}
-
-/*
-** Fill the Index.aiRowEst[] array with default information - information
-** to be used when we have not run the ANALYZE command.
-**
-** aiRowEst[0] is suppose to contain the number of elements in the index.
-** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the
-** number of rows in the table that match any particular value of the
-** first column of the index. aiRowEst[2] is an estimate of the number
-** of rows that match any particular combiniation of the first 2 columns
-** of the index. And so forth. It must always be the case that
-*
-** aiRowEst[N]<=aiRowEst[N-1]
-** aiRowEst[N]>=1
-**
-** Apart from that, we have little to go on besides intuition as to
-** how aiRowEst[] should be initialized. The numbers generated here
-** are based on typical values found in actual indices.
-*/
-SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
- tRowcnt *a = pIdx->aiRowEst;
- int i;
- tRowcnt n;
- assert( a!=0 );
- a[0] = pIdx->pTable->nRowEst;
- if( a[0]<10 ) a[0] = 10;
- n = 10;
- for(i=1; i<=pIdx->nColumn; i++){
- a[i] = n;
- if( n>5 ) n--;
- }
- if( pIdx->onError!=OE_None ){
- a[pIdx->nColumn] = 1;
- }
-}
-
-/*
-** This routine will drop an existing named index. This routine
-** implements the DROP INDEX statement.
-*/
-SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
- Index *pIndex;
- Vdbe *v;
- sqlite3 *db = pParse->db;
- int iDb;
-
- assert( pParse->nErr==0 ); /* Never called with prior errors */
- if( db->mallocFailed ){
- goto exit_drop_index;
- }
- assert( pName->nSrc==1 );
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- goto exit_drop_index;
- }
- pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
- if( pIndex==0 ){
- if( !ifExists ){
- sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
- }else{
- sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
- }
- pParse->checkSchema = 1;
- goto exit_drop_index;
- }
- if( pIndex->autoIndex ){
- sqlite3ErrorMsg(pParse, "index associated with UNIQUE "
- "or PRIMARY KEY constraint cannot be dropped", 0);
- goto exit_drop_index;
- }
- iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int code = SQLITE_DROP_INDEX;
- Table *pTab = pIndex->pTable;
- const char *zDb = db->aDb[iDb].zName;
- const char *zTab = SCHEMA_TABLE(iDb);
- if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
- goto exit_drop_index;
- }
- if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX;
- if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
- goto exit_drop_index;
- }
- }
-#endif
-
- /* Generate code to remove the index and from the master table */
- v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3BeginWriteOperation(pParse, 1, iDb);
- sqlite3NestedParse(pParse,
- "DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName
- );
- sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
- sqlite3ChangeCookie(pParse, iDb);
- destroyRootPage(pParse, pIndex->tnum, iDb);
- sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0);
- }
-
-exit_drop_index:
- sqlite3SrcListDelete(db, pName);
-}
-
-/*
-** pArray is a pointer to an array of objects. Each object in the
-** array is szEntry bytes in size. This routine uses sqlite3DbRealloc()
-** to extend the array so that there is space for a new object at the end.
-**
-** When this function is called, *pnEntry contains the current size of
-** the array (in entries - so the allocation is ((*pnEntry) * szEntry) bytes
-** in total).
-**
-** If the realloc() is successful (i.e. if no OOM condition occurs), the
-** space allocated for the new object is zeroed, *pnEntry updated to
-** reflect the new size of the array and a pointer to the new allocation
-** returned. *pIdx is set to the index of the new array entry in this case.
-**
-** Otherwise, if the realloc() fails, *pIdx is set to -1, *pnEntry remains
-** unchanged and a copy of pArray returned.
-*/
-SQLITE_PRIVATE void *sqlite3ArrayAllocate(
- sqlite3 *db, /* Connection to notify of malloc failures */
- void *pArray, /* Array of objects. Might be reallocated */
- int szEntry, /* Size of each object in the array */
- int *pnEntry, /* Number of objects currently in use */
- int *pIdx /* Write the index of a new slot here */
-){
- char *z;
- int n = *pnEntry;
- if( (n & (n-1))==0 ){
- int sz = (n==0) ? 1 : 2*n;
- void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry);
- if( pNew==0 ){
- *pIdx = -1;
- return pArray;
- }
- pArray = pNew;
- }
- z = (char*)pArray;
- memset(&z[n * szEntry], 0, szEntry);
- *pIdx = n;
- ++*pnEntry;
- return pArray;
-}
-
-/*
-** Append a new element to the given IdList. Create a new IdList if
-** need be.
-**
-** A new IdList is returned, or NULL if malloc() fails.
-*/
-SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
- int i;
- if( pList==0 ){
- pList = sqlite3DbMallocZero(db, sizeof(IdList) );
- if( pList==0 ) return 0;
- }
- pList->a = sqlite3ArrayAllocate(
- db,
- pList->a,
- sizeof(pList->a[0]),
- &pList->nId,
- &i
- );
- if( i<0 ){
- sqlite3IdListDelete(db, pList);
- return 0;
- }
- pList->a[i].zName = sqlite3NameFromToken(db, pToken);
- return pList;
-}
-
-/*
-** Delete an IdList.
-*/
-SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
- int i;
- if( pList==0 ) return;
- for(i=0; i<pList->nId; i++){
- sqlite3DbFree(db, pList->a[i].zName);
- }
- sqlite3DbFree(db, pList->a);
- sqlite3DbFree(db, pList);
-}
-
-/*
-** Return the index in pList of the identifier named zId. Return -1
-** if not found.
-*/
-SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
- int i;
- if( pList==0 ) return -1;
- for(i=0; i<pList->nId; i++){
- if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
- }
- return -1;
-}
-
-/*
-** Expand the space allocated for the given SrcList object by
-** creating nExtra new slots beginning at iStart. iStart is zero based.
-** New slots are zeroed.
-**
-** For example, suppose a SrcList initially contains two entries: A,B.
-** To append 3 new entries onto the end, do this:
-**
-** sqlite3SrcListEnlarge(db, pSrclist, 3, 2);
-**
-** After the call above it would contain: A, B, nil, nil, nil.
-** If the iStart argument had been 1 instead of 2, then the result
-** would have been: A, nil, nil, nil, B. To prepend the new slots,
-** the iStart value would be 0. The result then would
-** be: nil, nil, nil, A, B.
-**
-** If a memory allocation fails the SrcList is unchanged. The
-** db->mallocFailed flag will be set to true.
-*/
-SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
- sqlite3 *db, /* Database connection to notify of OOM errors */
- SrcList *pSrc, /* The SrcList to be enlarged */
- int nExtra, /* Number of new slots to add to pSrc->a[] */
- int iStart /* Index in pSrc->a[] of first new slot */
-){
- int i;
-
- /* Sanity checking on calling parameters */
- assert( iStart>=0 );
- assert( nExtra>=1 );
- assert( pSrc!=0 );
- assert( iStart<=pSrc->nSrc );
-
- /* Allocate additional space if needed */
- if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
- SrcList *pNew;
- int nAlloc = pSrc->nSrc+nExtra;
- int nGot;
- pNew = sqlite3DbRealloc(db, pSrc,
- sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
- if( pNew==0 ){
- assert( db->mallocFailed );
- return pSrc;
- }
- pSrc = pNew;
- nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
- pSrc->nAlloc = (u16)nGot;
- }
-
- /* Move existing slots that come after the newly inserted slots
- ** out of the way */
- for(i=pSrc->nSrc-1; i>=iStart; i--){
- pSrc->a[i+nExtra] = pSrc->a[i];
- }
- pSrc->nSrc += (i16)nExtra;
-
- /* Zero the newly allocated slots */
- memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
- for(i=iStart; i<iStart+nExtra; i++){
- pSrc->a[i].iCursor = -1;
- }
-
- /* Return a pointer to the enlarged SrcList */
- return pSrc;
-}
-
-
-/*
-** Append a new table name to the given SrcList. Create a new SrcList if
-** need be. A new entry is created in the SrcList even if pTable is NULL.
-**
-** A SrcList is returned, or NULL if there is an OOM error. The returned
-** SrcList might be the same as the SrcList that was input or it might be
-** a new one. If an OOM error does occurs, then the prior value of pList
-** that is input to this routine is automatically freed.
-**
-** If pDatabase is not null, it means that the table has an optional
-** database name prefix. Like this: "database.table". The pDatabase
-** points to the table name and the pTable points to the database name.
-** The SrcList.a[].zName field is filled with the table name which might
-** come from pTable (if pDatabase is NULL) or from pDatabase.
-** SrcList.a[].zDatabase is filled with the database name from pTable,
-** or with NULL if no database is specified.
-**
-** In other words, if call like this:
-**
-** sqlite3SrcListAppend(D,A,B,0);
-**
-** Then B is a table name and the database name is unspecified. If called
-** like this:
-**
-** sqlite3SrcListAppend(D,A,B,C);
-**
-** Then C is the table name and B is the database name. If C is defined
-** then so is B. In other words, we never have a case where:
-**
-** sqlite3SrcListAppend(D,A,0,C);
-**
-** Both pTable and pDatabase are assumed to be quoted. They are dequoted
-** before being added to the SrcList.
-*/
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
- sqlite3 *db, /* Connection to notify of malloc failures */
- SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */
- Token *pTable, /* Table to append */
- Token *pDatabase /* Database of the table */
-){
- struct SrcList_item *pItem;
- assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */
- if( pList==0 ){
- pList = sqlite3DbMallocZero(db, sizeof(SrcList) );
- if( pList==0 ) return 0;
- pList->nAlloc = 1;
- }
- pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
- if( db->mallocFailed ){
- sqlite3SrcListDelete(db, pList);
- return 0;
- }
- pItem = &pList->a[pList->nSrc-1];
- if( pDatabase && pDatabase->z==0 ){
- pDatabase = 0;
- }
- if( pDatabase ){
- Token *pTemp = pDatabase;
- pDatabase = pTable;
- pTable = pTemp;
- }
- pItem->zName = sqlite3NameFromToken(db, pTable);
- pItem->zDatabase = sqlite3NameFromToken(db, pDatabase);
- return pList;
-}
-
-/*
-** Assign VdbeCursor index numbers to all tables in a SrcList
-*/
-SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
- int i;
- struct SrcList_item *pItem;
- assert(pList || pParse->db->mallocFailed );
- if( pList ){
- for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
- if( pItem->iCursor>=0 ) break;
- pItem->iCursor = pParse->nTab++;
- if( pItem->pSelect ){
- sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
- }
- }
- }
-}
-
-/*
-** Delete an entire SrcList including all its substructure.
-*/
-SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
- int i;
- struct SrcList_item *pItem;
- if( pList==0 ) return;
- for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
- sqlite3DbFree(db, pItem->zDatabase);
- sqlite3DbFree(db, pItem->zName);
- sqlite3DbFree(db, pItem->zAlias);
- sqlite3DbFree(db, pItem->zIndex);
- sqlite3DeleteTable(db, pItem->pTab);
- sqlite3SelectDelete(db, pItem->pSelect);
- sqlite3ExprDelete(db, pItem->pOn);
- sqlite3IdListDelete(db, pItem->pUsing);
- }
- sqlite3DbFree(db, pList);
-}
-
-/*
-** This routine is called by the parser to add a new term to the
-** end of a growing FROM clause. The "p" parameter is the part of
-** the FROM clause that has already been constructed. "p" is NULL
-** if this is the first term of the FROM clause. pTable and pDatabase
-** are the name of the table and database named in the FROM clause term.
-** pDatabase is NULL if the database name qualifier is missing - the
-** usual case. If the term has a alias, then pAlias points to the
-** alias token. If the term is a subquery, then pSubquery is the
-** SELECT statement that the subquery encodes. The pTable and
-** pDatabase parameters are NULL for subqueries. The pOn and pUsing
-** parameters are the content of the ON and USING clauses.
-**
-** Return a new SrcList which encodes is the FROM with the new
-** term added.
-*/
-SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
- Parse *pParse, /* Parsing context */
- SrcList *p, /* The left part of the FROM clause already seen */
- Token *pTable, /* Name of the table to add to the FROM clause */
- Token *pDatabase, /* Name of the database containing pTable */
- Token *pAlias, /* The right-hand side of the AS subexpression */
- Select *pSubquery, /* A subquery used in place of a table name */
- Expr *pOn, /* The ON clause of a join */
- IdList *pUsing /* The USING clause of a join */
-){
- struct SrcList_item *pItem;
- sqlite3 *db = pParse->db;
- if( !p && (pOn || pUsing) ){
- sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s",
- (pOn ? "ON" : "USING")
- );
- goto append_from_error;
- }
- p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
- if( p==0 || NEVER(p->nSrc==0) ){
- goto append_from_error;
- }
- pItem = &p->a[p->nSrc-1];
- assert( pAlias!=0 );
- if( pAlias->n ){
- pItem->zAlias = sqlite3NameFromToken(db, pAlias);
- }
- pItem->pSelect = pSubquery;
- pItem->pOn = pOn;
- pItem->pUsing = pUsing;
- return p;
-
- append_from_error:
- assert( p==0 );
- sqlite3ExprDelete(db, pOn);
- sqlite3IdListDelete(db, pUsing);
- sqlite3SelectDelete(db, pSubquery);
- return 0;
-}
-
-/*
-** Add an INDEXED BY or NOT INDEXED clause to the most recently added
-** element of the source-list passed as the second argument.
-*/
-SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
- assert( pIndexedBy!=0 );
- if( p && ALWAYS(p->nSrc>0) ){
- struct SrcList_item *pItem = &p->a[p->nSrc-1];
- assert( pItem->notIndexed==0 && pItem->zIndex==0 );
- if( pIndexedBy->n==1 && !pIndexedBy->z ){
- /* A "NOT INDEXED" clause was supplied. See parse.y
- ** construct "indexed_opt" for details. */
- pItem->notIndexed = 1;
- }else{
- pItem->zIndex = sqlite3NameFromToken(pParse->db, pIndexedBy);
- }
- }
-}
-
-/*
-** When building up a FROM clause in the parser, the join operator
-** is initially attached to the left operand. But the code generator
-** expects the join operator to be on the right operand. This routine
-** Shifts all join operators from left to right for an entire FROM
-** clause.
-**
-** Example: Suppose the join is like this:
-**
-** A natural cross join B
-**
-** The operator is "natural cross join". The A and B operands are stored
-** in p->a[0] and p->a[1], respectively. The parser initially stores the
-** operator with A. This routine shifts that operator over to B.
-*/
-SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
- if( p ){
- int i;
- assert( p->a || p->nSrc==0 );
- for(i=p->nSrc-1; i>0; i--){
- p->a[i].jointype = p->a[i-1].jointype;
- }
- p->a[0].jointype = 0;
- }
-}
-
-/*
-** Begin a transaction
-*/
-SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){
- sqlite3 *db;
- Vdbe *v;
- int i;
-
- assert( pParse!=0 );
- db = pParse->db;
- assert( db!=0 );
-/* if( db->aDb[0].pBt==0 ) return; */
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
- return;
- }
- v = sqlite3GetVdbe(pParse);
- if( !v ) return;
- if( type!=TK_DEFERRED ){
- for(i=0; i<db->nDb; i++){
- sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
- sqlite3VdbeUsesBtree(v, i);
- }
- }
- sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0);
-}
-
-/*
-** Commit a transaction
-*/
-SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
- Vdbe *v;
-
- assert( pParse!=0 );
- assert( pParse->db!=0 );
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
- return;
- }
- v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
- }
-}
-
-/*
-** Rollback a transaction
-*/
-SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){
- Vdbe *v;
-
- assert( pParse!=0 );
- assert( pParse->db!=0 );
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
- return;
- }
- v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
- }
-}
-
-/*
-** This function is called by the parser when it parses a command to create,
-** release or rollback an SQL savepoint.
-*/
-SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){
- char *zName = sqlite3NameFromToken(pParse->db, pName);
- if( zName ){
- Vdbe *v = sqlite3GetVdbe(pParse);
-#ifndef SQLITE_OMIT_AUTHORIZATION
- static const char * const az[] = { "BEGIN", "RELEASE", "ROLLBACK" };
- assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 );
-#endif
- if( !v || sqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){
- sqlite3DbFree(pParse->db, zName);
- return;
- }
- sqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC);
- }
-}
-
-/*
-** Make sure the TEMP database is open and available for use. Return
-** the number of errors. Leave any error messages in the pParse structure.
-*/
-SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){
- sqlite3 *db = pParse->db;
- if( db->aDb[1].pBt==0 && !pParse->explain ){
- int rc;
- Btree *pBt;
- static const int flags =
- SQLITE_OPEN_READWRITE |
- SQLITE_OPEN_CREATE |
- SQLITE_OPEN_EXCLUSIVE |
- SQLITE_OPEN_DELETEONCLOSE |
- SQLITE_OPEN_TEMP_DB;
-
- rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags);
- if( rc!=SQLITE_OK ){
- sqlite3ErrorMsg(pParse, "unable to open a temporary database "
- "file for storing temporary tables");
- pParse->rc = rc;
- return 1;
- }
- db->aDb[1].pBt = pBt;
- assert( db->aDb[1].pSchema );
- if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
- db->mallocFailed = 1;
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** Generate VDBE code that will verify the schema cookie and start
-** a read-transaction for all named database files.
-**
-** It is important that all schema cookies be verified and all
-** read transactions be started before anything else happens in
-** the VDBE program. But this routine can be called after much other
-** code has been generated. So here is what we do:
-**
-** The first time this routine is called, we code an OP_Goto that
-** will jump to a subroutine at the end of the program. Then we
-** record every database that needs its schema verified in the
-** pParse->cookieMask field. Later, after all other code has been
-** generated, the subroutine that does the cookie verifications and
-** starts the transactions will be coded and the OP_Goto P2 value
-** will be made to point to that subroutine. The generation of the
-** cookie verification subroutine code happens in sqlite3FinishCoding().
-**
-** If iDb<0 then code the OP_Goto only - don't set flag to verify the
-** schema on any databases. This can be used to position the OP_Goto
-** early in the code, before we know if any database tables will be used.
-*/
-SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
-
-#ifndef SQLITE_OMIT_TRIGGER
- if( pToplevel!=pParse ){
- /* This branch is taken if a trigger is currently being coded. In this
- ** case, set cookieGoto to a non-zero value to show that this function
- ** has been called. This is used by the sqlite3ExprCodeConstants()
- ** function. */
- pParse->cookieGoto = -1;
- }
-#endif
- if( pToplevel->cookieGoto==0 ){
- Vdbe *v = sqlite3GetVdbe(pToplevel);
- if( v==0 ) return; /* This only happens if there was a prior error */
- pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
- }
- if( iDb>=0 ){
- sqlite3 *db = pToplevel->db;
- yDbMask mask;
-
- assert( iDb<db->nDb );
- assert( db->aDb[iDb].pBt!=0 || iDb==1 );
- assert( iDb<SQLITE_MAX_ATTACHED+2 );
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- mask = ((yDbMask)1)<<iDb;
- if( (pToplevel->cookieMask & mask)==0 ){
- pToplevel->cookieMask |= mask;
- pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
- if( !OMIT_TEMPDB && iDb==1 ){
- sqlite3OpenTempDatabase(pToplevel);
- }
- }
- }
-}
-
-/*
-** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each
-** attached database. Otherwise, invoke it for the database named zDb only.
-*/
-SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
- sqlite3 *db = pParse->db;
- int i;
- for(i=0; i<db->nDb; i++){
- Db *pDb = &db->aDb[i];
- if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){
- sqlite3CodeVerifySchema(pParse, i);
- }
- }
-}
-
-/*
-** Generate VDBE code that prepares for doing an operation that
-** might change the database.
-**
-** This routine starts a new transaction if we are not already within
-** a transaction. If we are already within a transaction, then a checkpoint
-** is set if the setStatement parameter is true. A checkpoint should
-** be set for operations that might fail (due to a constraint) part of
-** the way through and which will need to undo some writes without having to
-** rollback the whole transaction. For operations where all constraints
-** can be checked before any changes are made to the database, it is never
-** necessary to undo a write and the checkpoint should not be set.
-*/
-SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- sqlite3CodeVerifySchema(pParse, iDb);
- pToplevel->writeMask |= ((yDbMask)1)<<iDb;
- pToplevel->isMultiWrite |= setStatement;
-}
-
-/*
-** Indicate that the statement currently under construction might write
-** more than one entry (example: deleting one row then inserting another,
-** inserting multiple rows in a table, or inserting a row and index entries.)
-** If an abort occurs after some of these writes have completed, then it will
-** be necessary to undo the completed writes.
-*/
-SQLITE_PRIVATE void sqlite3MultiWrite(Parse *pParse){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- pToplevel->isMultiWrite = 1;
-}
-
-/*
-** The code generator calls this routine if is discovers that it is
-** possible to abort a statement prior to completion. In order to
-** perform this abort without corrupting the database, we need to make
-** sure that the statement is protected by a statement transaction.
-**
-** Technically, we only need to set the mayAbort flag if the
-** isMultiWrite flag was previously set. There is a time dependency
-** such that the abort must occur after the multiwrite. This makes
-** some statements involving the REPLACE conflict resolution algorithm
-** go a little faster. But taking advantage of this time dependency
-** makes it more difficult to prove that the code is correct (in
-** particular, it prevents us from writing an effective
-** implementation of sqlite3AssertMayAbort()) and so we have chosen
-** to take the safe route and skip the optimization.
-*/
-SQLITE_PRIVATE void sqlite3MayAbort(Parse *pParse){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- pToplevel->mayAbort = 1;
-}
-
-/*
-** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT
-** error. The onError parameter determines which (if any) of the statement
-** and/or current transaction is rolled back.
-*/
-SQLITE_PRIVATE void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( onError==OE_Abort ){
- sqlite3MayAbort(pParse);
- }
- sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type);
-}
-
-/*
-** Check to see if pIndex uses the collating sequence pColl. Return
-** true if it does and false if it does not.
-*/
-#ifndef SQLITE_OMIT_REINDEX
-static int collationMatch(const char *zColl, Index *pIndex){
- int i;
- assert( zColl!=0 );
- for(i=0; i<pIndex->nColumn; i++){
- const char *z = pIndex->azColl[i];
- assert( z!=0 );
- if( 0==sqlite3StrICmp(z, zColl) ){
- return 1;
- }
- }
- return 0;
-}
-#endif
-
-/*
-** Recompute all indices of pTab that use the collating sequence pColl.
-** If pColl==0 then recompute all indices of pTab.
-*/
-#ifndef SQLITE_OMIT_REINDEX
-static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){
- Index *pIndex; /* An index associated with pTab */
-
- for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
- if( zColl==0 || collationMatch(zColl, pIndex) ){
- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3RefillIndex(pParse, pIndex, -1);
- }
- }
-}
-#endif
-
-/*
-** Recompute all indices of all tables in all databases where the
-** indices use the collating sequence pColl. If pColl==0 then recompute
-** all indices everywhere.
-*/
-#ifndef SQLITE_OMIT_REINDEX
-static void reindexDatabases(Parse *pParse, char const *zColl){
- Db *pDb; /* A single database */
- int iDb; /* The database index number */
- sqlite3 *db = pParse->db; /* The database connection */
- HashElem *k; /* For looping over tables in pDb */
- Table *pTab; /* A table in the database */
-
- assert( sqlite3BtreeHoldsAllMutexes(db) ); /* Needed for schema access */
- for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
- assert( pDb!=0 );
- for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
- pTab = (Table*)sqliteHashData(k);
- reindexTable(pParse, pTab, zColl);
- }
- }
-}
-#endif
-
-/*
-** Generate code for the REINDEX command.
-**
-** REINDEX -- 1
-** REINDEX <collation> -- 2
-** REINDEX ?<database>.?<tablename> -- 3
-** REINDEX ?<database>.?<indexname> -- 4
-**
-** Form 1 causes all indices in all attached databases to be rebuilt.
-** Form 2 rebuilds all indices in all databases that use the named
-** collating function. Forms 3 and 4 rebuild the named index or all
-** indices associated with the named table.
-*/
-#ifndef SQLITE_OMIT_REINDEX
-SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
- CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */
- char *z; /* Name of a table or index */
- const char *zDb; /* Name of the database */
- Table *pTab; /* A table in the database */
- Index *pIndex; /* An index associated with pTab */
- int iDb; /* The database index number */
- sqlite3 *db = pParse->db; /* The database connection */
- Token *pObjName; /* Name of the table or index to be reindexed */
-
- /* Read the database schema. If an error occurs, leave an error message
- ** and code in pParse and return NULL. */
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- return;
- }
-
- if( pName1==0 ){
- reindexDatabases(pParse, 0);
- return;
- }else if( NEVER(pName2==0) || pName2->z==0 ){
- char *zColl;
- assert( pName1->z );
- zColl = sqlite3NameFromToken(pParse->db, pName1);
- if( !zColl ) return;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
- if( pColl ){
- reindexDatabases(pParse, zColl);
- sqlite3DbFree(db, zColl);
- return;
- }
- sqlite3DbFree(db, zColl);
- }
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
- if( iDb<0 ) return;
- z = sqlite3NameFromToken(db, pObjName);
- if( z==0 ) return;
- zDb = db->aDb[iDb].zName;
- pTab = sqlite3FindTable(db, z, zDb);
- if( pTab ){
- reindexTable(pParse, pTab, 0);
- sqlite3DbFree(db, z);
- return;
- }
- pIndex = sqlite3FindIndex(db, z, zDb);
- sqlite3DbFree(db, z);
- if( pIndex ){
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3RefillIndex(pParse, pIndex, -1);
- return;
- }
- sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
-}
-#endif
-
-/*
-** Return a dynamicly allocated KeyInfo structure that can be used
-** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
-**
-** If successful, a pointer to the new structure is returned. In this case
-** the caller is responsible for calling sqlite3DbFree(db, ) on the returned
-** pointer. If an error occurs (out of memory or missing collation
-** sequence), NULL is returned and the state of pParse updated to reflect
-** the error.
-*/
-SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
- int i;
- int nCol = pIdx->nColumn;
- int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
- sqlite3 *db = pParse->db;
- KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
-
- if( pKey ){
- pKey->db = pParse->db;
- pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
- assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
- for(i=0; i<nCol; i++){
- char *zColl = pIdx->azColl[i];
- assert( zColl );
- pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
- pKey->aSortOrder[i] = pIdx->aSortOrder[i];
- }
- pKey->nField = (u16)nCol;
- }
-
- if( pParse->nErr ){
- sqlite3DbFree(db, pKey);
- pKey = 0;
- }
- return pKey;
-}
-
-/************** End of build.c ***********************************************/
-/************** Begin file callback.c ****************************************/
-/*
-** 2005 May 23
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains functions used to access the internal hash tables
-** of user defined functions and collation sequences.
-*/
-
-
-/*
-** Invoke the 'collation needed' callback to request a collation sequence
-** in the encoding enc of name zName, length nName.
-*/
-static void callCollNeeded(sqlite3 *db, int enc, const char *zName){
- assert( !db->xCollNeeded || !db->xCollNeeded16 );
- if( db->xCollNeeded ){
- char *zExternal = sqlite3DbStrDup(db, zName);
- if( !zExternal ) return;
- db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal);
- sqlite3DbFree(db, zExternal);
- }
-#ifndef SQLITE_OMIT_UTF16
- if( db->xCollNeeded16 ){
- char const *zExternal;
- sqlite3_value *pTmp = sqlite3ValueNew(db);
- sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
- zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
- if( zExternal ){
- db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
- }
- sqlite3ValueFree(pTmp);
- }
-#endif
-}
-
-/*
-** This routine is called if the collation factory fails to deliver a
-** collation function in the best encoding but there may be other versions
-** of this collation function (for other text encodings) available. Use one
-** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if
-** possible.
-*/
-static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
- CollSeq *pColl2;
- char *z = pColl->zName;
- int i;
- static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
- for(i=0; i<3; i++){
- pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0);
- if( pColl2->xCmp!=0 ){
- memcpy(pColl, pColl2, sizeof(CollSeq));
- pColl->xDel = 0; /* Do not copy the destructor */
- return SQLITE_OK;
- }
- }
- return SQLITE_ERROR;
-}
-
-/*
-** This function is responsible for invoking the collation factory callback
-** or substituting a collation sequence of a different encoding when the
-** requested collation sequence is not available in the desired encoding.
-**
-** If it is not NULL, then pColl must point to the database native encoding
-** collation sequence with name zName, length nName.
-**
-** The return value is either the collation sequence to be used in database
-** db for collation type name zName, length nName, or NULL, if no collation
-** sequence can be found. If no collation is found, leave an error message.
-**
-** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
-*/
-SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
- Parse *pParse, /* Parsing context */
- u8 enc, /* The desired encoding for the collating sequence */
- CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
- const char *zName /* Collating sequence name */
-){
- CollSeq *p;
- sqlite3 *db = pParse->db;
-
- p = pColl;
- if( !p ){
- p = sqlite3FindCollSeq(db, enc, zName, 0);
- }
- if( !p || !p->xCmp ){
- /* No collation sequence of this type for this encoding is registered.
- ** Call the collation factory to see if it can supply us with one.
- */
- callCollNeeded(db, enc, zName);
- p = sqlite3FindCollSeq(db, enc, zName, 0);
- }
- if( p && !p->xCmp && synthCollSeq(db, p) ){
- p = 0;
- }
- assert( !p || p->xCmp );
- if( p==0 ){
- sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
- }
- return p;
-}
-
-/*
-** This routine is called on a collation sequence before it is used to
-** check that it is defined. An undefined collation sequence exists when
-** a database is loaded that contains references to collation sequences
-** that have not been defined by sqlite3_create_collation() etc.
-**
-** If required, this routine calls the 'collation needed' callback to
-** request a definition of the collating sequence. If this doesn't work,
-** an equivalent collating sequence that uses a text encoding different
-** from the main database is substituted, if one is available.
-*/
-SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
- if( pColl ){
- const char *zName = pColl->zName;
- sqlite3 *db = pParse->db;
- CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
- if( !p ){
- return SQLITE_ERROR;
- }
- assert( p==pColl );
- }
- return SQLITE_OK;
-}
-
-
-
-/*
-** Locate and return an entry from the db.aCollSeq hash table. If the entry
-** specified by zName and nName is not found and parameter 'create' is
-** true, then create a new entry. Otherwise return NULL.
-**
-** Each pointer stored in the sqlite3.aCollSeq hash table contains an
-** array of three CollSeq structures. The first is the collation sequence
-** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
-**
-** Stored immediately after the three collation sequences is a copy of
-** the collation sequence name. A pointer to this string is stored in
-** each collation sequence structure.
-*/
-static CollSeq *findCollSeqEntry(
- sqlite3 *db, /* Database connection */
- const char *zName, /* Name of the collating sequence */
- int create /* Create a new entry if true */
-){
- CollSeq *pColl;
- int nName = sqlite3Strlen30(zName);
- pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
-
- if( 0==pColl && create ){
- pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 );
- if( pColl ){
- CollSeq *pDel = 0;
- pColl[0].zName = (char*)&pColl[3];
- pColl[0].enc = SQLITE_UTF8;
- pColl[1].zName = (char*)&pColl[3];
- pColl[1].enc = SQLITE_UTF16LE;
- pColl[2].zName = (char*)&pColl[3];
- pColl[2].enc = SQLITE_UTF16BE;
- memcpy(pColl[0].zName, zName, nName);
- pColl[0].zName[nName] = 0;
- pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
-
- /* If a malloc() failure occurred in sqlite3HashInsert(), it will
- ** return the pColl pointer to be deleted (because it wasn't added
- ** to the hash table).
- */
- assert( pDel==0 || pDel==pColl );
- if( pDel!=0 ){
- db->mallocFailed = 1;
- sqlite3DbFree(db, pDel);
- pColl = 0;
- }
- }
- }
- return pColl;
-}
-
-/*
-** Parameter zName points to a UTF-8 encoded string nName bytes long.
-** Return the CollSeq* pointer for the collation sequence named zName
-** for the encoding 'enc' from the database 'db'.
-**
-** If the entry specified is not found and 'create' is true, then create a
-** new entry. Otherwise return NULL.
-**
-** A separate function sqlite3LocateCollSeq() is a wrapper around
-** this routine. sqlite3LocateCollSeq() invokes the collation factory
-** if necessary and generates an error message if the collating sequence
-** cannot be found.
-**
-** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq()
-*/
-SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(
- sqlite3 *db,
- u8 enc,
- const char *zName,
- int create
-){
- CollSeq *pColl;
- if( zName ){
- pColl = findCollSeqEntry(db, zName, create);
- }else{
- pColl = db->pDfltColl;
- }
- assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
- assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE );
- if( pColl ) pColl += enc-1;
- return pColl;
-}
-
-/* During the search for the best function definition, this procedure
-** is called to test how well the function passed as the first argument
-** matches the request for a function with nArg arguments in a system
-** that uses encoding enc. The value returned indicates how well the
-** request is matched. A higher value indicates a better match.
-**
-** If nArg is -1 that means to only return a match (non-zero) if p->nArg
-** is also -1. In other words, we are searching for a function that
-** takes a variable number of arguments.
-**
-** If nArg is -2 that means that we are searching for any function
-** regardless of the number of arguments it uses, so return a positive
-** match score for any
-**
-** The returned value is always between 0 and 6, as follows:
-**
-** 0: Not a match.
-** 1: UTF8/16 conversion required and function takes any number of arguments.
-** 2: UTF16 byte order change required and function takes any number of args.
-** 3: encoding matches and function takes any number of arguments
-** 4: UTF8/16 conversion required - argument count matches exactly
-** 5: UTF16 byte order conversion required - argument count matches exactly
-** 6: Perfect match: encoding and argument count match exactly.
-**
-** If nArg==(-2) then any function with a non-null xStep or xFunc is
-** a perfect match and any function with both xStep and xFunc NULL is
-** a non-match.
-*/
-#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */
-static int matchQuality(
- FuncDef *p, /* The function we are evaluating for match quality */
- int nArg, /* Desired number of arguments. (-1)==any */
- u8 enc /* Desired text encoding */
-){
- int match;
-
- /* nArg of -2 is a special case */
- if( nArg==(-2) ) return (p->xFunc==0 && p->xStep==0) ? 0 : FUNC_PERFECT_MATCH;
-
- /* Wrong number of arguments means "no match" */
- if( p->nArg!=nArg && p->nArg>=0 ) return 0;
-
- /* Give a better score to a function with a specific number of arguments
- ** than to function that accepts any number of arguments. */
- if( p->nArg==nArg ){
- match = 4;
- }else{
- match = 1;
- }
-
- /* Bonus points if the text encoding matches */
- if( enc==p->iPrefEnc ){
- match += 2; /* Exact encoding match */
- }else if( (enc & p->iPrefEnc & 2)!=0 ){
- match += 1; /* Both are UTF16, but with different byte orders */
- }
-
- return match;
-}
-
-/*
-** Search a FuncDefHash for a function with the given name. Return
-** a pointer to the matching FuncDef if found, or 0 if there is no match.
-*/
-static FuncDef *functionSearch(
- FuncDefHash *pHash, /* Hash table to search */
- int h, /* Hash of the name */
- const char *zFunc, /* Name of function */
- int nFunc /* Number of bytes in zFunc */
-){
- FuncDef *p;
- for(p=pHash->a[h]; p; p=p->pHash){
- if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
- return p;
- }
- }
- return 0;
-}
-
-/*
-** Insert a new FuncDef into a FuncDefHash hash table.
-*/
-SQLITE_PRIVATE void sqlite3FuncDefInsert(
- FuncDefHash *pHash, /* The hash table into which to insert */
- FuncDef *pDef /* The function definition to insert */
-){
- FuncDef *pOther;
- int nName = sqlite3Strlen30(pDef->zName);
- u8 c1 = (u8)pDef->zName[0];
- int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
- pOther = functionSearch(pHash, h, pDef->zName, nName);
- if( pOther ){
- assert( pOther!=pDef && pOther->pNext!=pDef );
- pDef->pNext = pOther->pNext;
- pOther->pNext = pDef;
- }else{
- pDef->pNext = 0;
- pDef->pHash = pHash->a[h];
- pHash->a[h] = pDef;
- }
-}
-
-
-
-/*
-** Locate a user function given a name, a number of arguments and a flag
-** indicating whether the function prefers UTF-16 over UTF-8. Return a
-** pointer to the FuncDef structure that defines that function, or return
-** NULL if the function does not exist.
-**
-** If the createFlag argument is true, then a new (blank) FuncDef
-** structure is created and liked into the "db" structure if a
-** no matching function previously existed.
-**
-** If nArg is -2, then the first valid function found is returned. A
-** function is valid if either xFunc or xStep is non-zero. The nArg==(-2)
-** case is used to see if zName is a valid function name for some number
-** of arguments. If nArg is -2, then createFlag must be 0.
-**
-** If createFlag is false, then a function with the required name and
-** number of arguments may be returned even if the eTextRep flag does not
-** match that requested.
-*/
-SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
- sqlite3 *db, /* An open database */
- const char *zName, /* Name of the function. Not null-terminated */
- int nName, /* Number of characters in the name */
- int nArg, /* Number of arguments. -1 means any number */
- u8 enc, /* Preferred text encoding */
- u8 createFlag /* Create new entry if true and does not otherwise exist */
-){
- FuncDef *p; /* Iterator variable */
- FuncDef *pBest = 0; /* Best match found so far */
- int bestScore = 0; /* Score of best match */
- int h; /* Hash value */
-
- assert( nArg>=(-2) );
- assert( nArg>=(-1) || createFlag==0 );
- assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
- h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
-
- /* First search for a match amongst the application-defined functions.
- */
- p = functionSearch(&db->aFunc, h, zName, nName);
- while( p ){
- int score = matchQuality(p, nArg, enc);
- if( score>bestScore ){
- pBest = p;
- bestScore = score;
- }
- p = p->pNext;
- }
-
- /* If no match is found, search the built-in functions.
- **
- ** If the SQLITE_PreferBuiltin flag is set, then search the built-in
- ** functions even if a prior app-defined function was found. And give
- ** priority to built-in functions.
- **
- ** Except, if createFlag is true, that means that we are trying to
- ** install a new function. Whatever FuncDef structure is returned it will
- ** have fields overwritten with new information appropriate for the
- ** new function. But the FuncDefs for built-in functions are read-only.
- ** So we must not search for built-ins when creating a new function.
- */
- if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- bestScore = 0;
- p = functionSearch(pHash, h, zName, nName);
- while( p ){
- int score = matchQuality(p, nArg, enc);
- if( score>bestScore ){
- pBest = p;
- bestScore = score;
- }
- p = p->pNext;
- }
- }
-
- /* If the createFlag parameter is true and the search did not reveal an
- ** exact match for the name, number of arguments and encoding, then add a
- ** new entry to the hash table and return it.
- */
- if( createFlag && bestScore<FUNC_PERFECT_MATCH &&
- (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
- pBest->zName = (char *)&pBest[1];
- pBest->nArg = (u16)nArg;
- pBest->iPrefEnc = enc;
- memcpy(pBest->zName, zName, nName);
- pBest->zName[nName] = 0;
- sqlite3FuncDefInsert(&db->aFunc, pBest);
- }
-
- if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
- return pBest;
- }
- return 0;
-}
-
-/*
-** Free all resources held by the schema structure. The void* argument points
-** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the
-** pointer itself, it just cleans up subsidiary resources (i.e. the contents
-** of the schema hash tables).
-**
-** The Schema.cache_size variable is not cleared.
-*/
-SQLITE_PRIVATE void sqlite3SchemaClear(void *p){
- Hash temp1;
- Hash temp2;
- HashElem *pElem;
- Schema *pSchema = (Schema *)p;
-
- temp1 = pSchema->tblHash;
- temp2 = pSchema->trigHash;
- sqlite3HashInit(&pSchema->trigHash);
- sqlite3HashClear(&pSchema->idxHash);
- for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
- sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem));
- }
- sqlite3HashClear(&temp2);
- sqlite3HashInit(&pSchema->tblHash);
- for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
- Table *pTab = sqliteHashData(pElem);
- sqlite3DeleteTable(0, pTab);
- }
- sqlite3HashClear(&temp1);
- sqlite3HashClear(&pSchema->fkeyHash);
- pSchema->pSeqTab = 0;
- if( pSchema->flags & DB_SchemaLoaded ){
- pSchema->iGeneration++;
- pSchema->flags &= ~DB_SchemaLoaded;
- }
-}
-
-/*
-** Find and return the schema associated with a BTree. Create
-** a new one if necessary.
-*/
-SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
- Schema * p;
- if( pBt ){
- p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear);
- }else{
- p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema));
- }
- if( !p ){
- db->mallocFailed = 1;
- }else if ( 0==p->file_format ){
- sqlite3HashInit(&p->tblHash);
- sqlite3HashInit(&p->idxHash);
- sqlite3HashInit(&p->trigHash);
- sqlite3HashInit(&p->fkeyHash);
- p->enc = SQLITE_UTF8;
- }
- return p;
-}
-
-/************** End of callback.c ********************************************/
-/************** Begin file delete.c ******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains C code routines that are called by the parser
-** in order to generate code for DELETE FROM statements.
-*/
-
-/*
-** While a SrcList can in general represent multiple tables and subqueries
-** (as in the FROM clause of a SELECT statement) in this case it contains
-** the name of a single table, as one might find in an INSERT, DELETE,
-** or UPDATE statement. Look up that table in the symbol table and
-** return a pointer. Set an error message and return NULL if the table
-** name is not found or if any other error occurs.
-**
-** The following fields are initialized appropriate in pSrc:
-**
-** pSrc->a[0].pTab Pointer to the Table object
-** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one
-**
-*/
-SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
- struct SrcList_item *pItem = pSrc->a;
- Table *pTab;
- assert( pItem && pSrc->nSrc==1 );
- pTab = sqlite3LocateTableItem(pParse, 0, pItem);
- sqlite3DeleteTable(pParse->db, pItem->pTab);
- pItem->pTab = pTab;
- if( pTab ){
- pTab->nRef++;
- }
- if( sqlite3IndexedByLookup(pParse, pItem) ){
- pTab = 0;
- }
- return pTab;
-}
-
-/*
-** Check to make sure the given table is writable. If it is not
-** writable, generate an error message and return 1. If it is
-** writable return 0;
-*/
-SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
- /* A table is not writable under the following circumstances:
- **
- ** 1) It is a virtual table and no implementation of the xUpdate method
- ** has been provided, or
- ** 2) It is a system table (i.e. sqlite_master), this call is not
- ** part of a nested parse and writable_schema pragma has not
- ** been specified.
- **
- ** In either case leave an error message in pParse and return non-zero.
- */
- if( ( IsVirtual(pTab)
- && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
- || ( (pTab->tabFlags & TF_Readonly)!=0
- && (pParse->db->flags & SQLITE_WriteSchema)==0
- && pParse->nested==0 )
- ){
- sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
- return 1;
- }
-
-#ifndef SQLITE_OMIT_VIEW
- if( !viewOk && pTab->pSelect ){
- sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
- return 1;
- }
-#endif
- return 0;
-}
-
-
-#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
-/*
-** Evaluate a view and store its result in an ephemeral table. The
-** pWhere argument is an optional WHERE clause that restricts the
-** set of rows in the view that are to be added to the ephemeral table.
-*/
-SQLITE_PRIVATE void sqlite3MaterializeView(
- Parse *pParse, /* Parsing context */
- Table *pView, /* View definition */
- Expr *pWhere, /* Optional WHERE clause to be added */
- int iCur /* Cursor number for ephemerial table */
-){
- SelectDest dest;
- Select *pDup;
- sqlite3 *db = pParse->db;
-
- pDup = sqlite3SelectDup(db, pView->pSelect, 0);
- if( pWhere ){
- SrcList *pFrom;
-
- pWhere = sqlite3ExprDup(db, pWhere, 0);
- pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
- if( pFrom ){
- assert( pFrom->nSrc==1 );
- pFrom->a[0].zAlias = sqlite3DbStrDup(db, pView->zName);
- pFrom->a[0].pSelect = pDup;
- assert( pFrom->a[0].pOn==0 );
- assert( pFrom->a[0].pUsing==0 );
- }else{
- sqlite3SelectDelete(db, pDup);
- }
- pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
- if( pDup ) pDup->selFlags |= SF_Materialize;
- }
- sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
- sqlite3Select(pParse, pDup, &dest);
- sqlite3SelectDelete(db, pDup);
-}
-#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
-
-#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
-/*
-** Generate an expression tree to implement the WHERE, ORDER BY,
-** and LIMIT/OFFSET portion of DELETE and UPDATE statements.
-**
-** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1;
-** \__________________________/
-** pLimitWhere (pInClause)
-*/
-SQLITE_PRIVATE Expr *sqlite3LimitWhere(
- Parse *pParse, /* The parser context */
- SrcList *pSrc, /* the FROM clause -- which tables to scan */
- Expr *pWhere, /* The WHERE clause. May be null */
- ExprList *pOrderBy, /* The ORDER BY clause. May be null */
- Expr *pLimit, /* The LIMIT clause. May be null */
- Expr *pOffset, /* The OFFSET clause. May be null */
- char *zStmtType /* Either DELETE or UPDATE. For error messages. */
-){
- Expr *pWhereRowid = NULL; /* WHERE rowid .. */
- Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
- Expr *pSelectRowid = NULL; /* SELECT rowid ... */
- ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */
- SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */
- Select *pSelect = NULL; /* Complete SELECT tree */
-
- /* Check that there isn't an ORDER BY without a LIMIT clause.
- */
- if( pOrderBy && (pLimit == 0) ) {
- sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
- goto limit_where_cleanup_2;
- }
-
- /* We only need to generate a select expression if there
- ** is a limit/offset term to enforce.
- */
- if( pLimit == 0 ) {
- /* if pLimit is null, pOffset will always be null as well. */
- assert( pOffset == 0 );
- return pWhere;
- }
-
- /* Generate a select expression tree to enforce the limit/offset
- ** term for the DELETE or UPDATE statement. For example:
- ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
- ** becomes:
- ** DELETE FROM table_a WHERE rowid IN (
- ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1
- ** );
- */
-
- pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
- if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
- pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
- if( pEList == 0 ) goto limit_where_cleanup_2;
-
- /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
- ** and the SELECT subtree. */
- pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
- if( pSelectSrc == 0 ) {
- sqlite3ExprListDelete(pParse->db, pEList);
- goto limit_where_cleanup_2;
- }
-
- /* generate the SELECT expression tree. */
- pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
- pOrderBy,0,pLimit,pOffset);
- if( pSelect == 0 ) return 0;
-
- /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
- pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
- if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
- pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
- if( pInClause == 0 ) goto limit_where_cleanup_1;
-
- pInClause->x.pSelect = pSelect;
- pInClause->flags |= EP_xIsSelect;
- sqlite3ExprSetHeight(pParse, pInClause);
- return pInClause;
-
- /* something went wrong. clean up anything allocated. */
-limit_where_cleanup_1:
- sqlite3SelectDelete(pParse->db, pSelect);
- return 0;
-
-limit_where_cleanup_2:
- sqlite3ExprDelete(pParse->db, pWhere);
- sqlite3ExprListDelete(pParse->db, pOrderBy);
- sqlite3ExprDelete(pParse->db, pLimit);
- sqlite3ExprDelete(pParse->db, pOffset);
- return 0;
-}
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
-
-/*
-** Generate code for a DELETE FROM statement.
-**
-** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL;
-** \________/ \________________/
-** pTabList pWhere
-*/
-SQLITE_PRIVATE void sqlite3DeleteFrom(
- Parse *pParse, /* The parser context */
- SrcList *pTabList, /* The table from which we should delete things */
- Expr *pWhere /* The WHERE clause. May be null */
-){
- Vdbe *v; /* The virtual database engine */
- Table *pTab; /* The table from which records will be deleted */
- const char *zDb; /* Name of database holding pTab */
- int end, addr = 0; /* A couple addresses of generated code */
- int i; /* Loop counter */
- WhereInfo *pWInfo; /* Information about the WHERE clause */
- Index *pIdx; /* For looping over indices of the table */
- int iCur; /* VDBE Cursor number for pTab */
- sqlite3 *db; /* Main database structure */
- AuthContext sContext; /* Authorization context */
- NameContext sNC; /* Name context to resolve expressions in */
- int iDb; /* Database number */
- int memCnt = -1; /* Memory cell used for change counting */
- int rcauth; /* Value returned by authorization callback */
-
-#ifndef SQLITE_OMIT_TRIGGER
- int isView; /* True if attempting to delete from a view */
- Trigger *pTrigger; /* List of table triggers, if required */
-#endif
-
- memset(&sContext, 0, sizeof(sContext));
- db = pParse->db;
- if( pParse->nErr || db->mallocFailed ){
- goto delete_from_cleanup;
- }
- assert( pTabList->nSrc==1 );
-
- /* Locate the table which we want to delete. This table has to be
- ** put in an SrcList structure because some of the subroutines we
- ** will be calling are designed to work with multiple tables and expect
- ** an SrcList* parameter instead of just a Table* parameter.
- */
- pTab = sqlite3SrcListLookup(pParse, pTabList);
- if( pTab==0 ) goto delete_from_cleanup;
-
- /* Figure out if we have any triggers and if the table being
- ** deleted from is a view
- */
-#ifndef SQLITE_OMIT_TRIGGER
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
- isView = pTab->pSelect!=0;
-#else
-# define pTrigger 0
-# define isView 0
-#endif
-#ifdef SQLITE_OMIT_VIEW
-# undef isView
-# define isView 0
-#endif
-
- /* If pTab is really a view, make sure it has been initialized.
- */
- if( sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto delete_from_cleanup;
- }
-
- if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
- goto delete_from_cleanup;
- }
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( iDb<db->nDb );
- zDb = db->aDb[iDb].zName;
- rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
- assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
- if( rcauth==SQLITE_DENY ){
- goto delete_from_cleanup;
- }
- assert(!isView || pTrigger);
-
- /* Assign cursor number to the table and all its indices.
- */
- assert( pTabList->nSrc==1 );
- iCur = pTabList->a[0].iCursor = pParse->nTab++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- pParse->nTab++;
- }
-
- /* Start the view context
- */
- if( isView ){
- sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
- }
-
- /* Begin generating code.
- */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ){
- goto delete_from_cleanup;
- }
- if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, 1, iDb);
-
- /* If we are trying to delete from a view, realize that view into
- ** a ephemeral table.
- */
-#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
- if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
- }
-#endif
-
- /* Resolve the column names in the WHERE clause.
- */
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- sNC.pSrcList = pTabList;
- if( sqlite3ResolveExprNames(&sNC, pWhere) ){
- goto delete_from_cleanup;
- }
-
- /* Initialize the counter of the number of rows deleted, if
- ** we are counting rows.
- */
- if( db->flags & SQLITE_CountRows ){
- memCnt = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt);
- }
-
-#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
- /* Special case: A DELETE without a WHERE clause deletes everything.
- ** It is easier just to erase the whole table. Prior to version 3.6.5,
- ** this optimization caused the row change count (the value returned by
- ** API function sqlite3_count_changes) to be set incorrectly. */
- if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab)
- && 0==sqlite3FkRequired(pParse, pTab, 0, 0)
- ){
- assert( !isView );
- sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
- pTab->zName, P4_STATIC);
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- assert( pIdx->pSchema==pTab->pSchema );
- sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
- }
- }else
-#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
- /* The usual case: There is a WHERE clause so we have to scan through
- ** the table and pick which records to delete.
- */
- {
- int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */
- int iRowid = ++pParse->nMem; /* Used for storing rowid values. */
- int regRowid; /* Actual register containing rowids */
-
- /* Collect rowids of every row to be deleted.
- */
- sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
- pWInfo = sqlite3WhereBegin(
- pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0
- );
- if( pWInfo==0 ) goto delete_from_cleanup;
- regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0);
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid);
- if( db->flags & SQLITE_CountRows ){
- sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
- }
- sqlite3WhereEnd(pWInfo);
-
- /* Delete every item whose key was written to the list during the
- ** database scan. We have to delete items after the scan is complete
- ** because deleting an item can change the scan order. */
- end = sqlite3VdbeMakeLabel(v);
-
- /* Unless this is a view, open cursors for the table we are
- ** deleting from and all its indices. If this is a view, then the
- ** only effect this statement has is to fire the INSTEAD OF
- ** triggers. */
- if( !isView ){
- sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
- }
-
- addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);
-
- /* Delete the row */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
- sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
- sqlite3VdbeChangeP5(v, OE_Abort);
- sqlite3MayAbort(pParse);
- }else
-#endif
- {
- int count = (pParse->nested==0); /* True to count changes */
- sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);
- }
-
- /* End of the delete loop */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
- sqlite3VdbeResolveLabel(v, end);
-
- /* Close the cursors open on the table and its indexes. */
- if( !isView && !IsVirtual(pTab) ){
- for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
- sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum);
- }
- sqlite3VdbeAddOp1(v, OP_Close, iCur);
- }
- }
-
- /* Update the sqlite_sequence table by storing the content of the
- ** maximum rowid counter values recorded while inserting into
- ** autoincrement tables.
- */
- if( pParse->nested==0 && pParse->pTriggerTab==0 ){
- sqlite3AutoincrementEnd(pParse);
- }
-
- /* Return the number of rows that were deleted. If this routine is
- ** generating code because of a call to sqlite3NestedParse(), do not
- ** invoke the callback function.
- */
- if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
- sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
- }
-
-delete_from_cleanup:
- sqlite3AuthContextPop(&sContext);
- sqlite3SrcListDelete(db, pTabList);
- sqlite3ExprDelete(db, pWhere);
- return;
-}
-/* Make sure "isView" and other macros defined above are undefined. Otherwise
-** thely may interfere with compilation of other functions in this file
-** (or in another file, if this file becomes part of the amalgamation). */
-#ifdef isView
- #undef isView
-#endif
-#ifdef pTrigger
- #undef pTrigger
-#endif
-
-/*
-** This routine generates VDBE code that causes a single row of a
-** single table to be deleted.
-**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
-**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number $iCur.
-**
-** 2. Read/write cursors for all indices of pTab must be open as
-** cursor number base+i for the i-th index.
-**
-** 3. The record number of the row to be deleted must be stored in
-** memory cell iRowid.
-**
-** This routine generates code to remove both the table record and all
-** index entries that point to that record.
-*/
-SQLITE_PRIVATE void sqlite3GenerateRowDelete(
- Parse *pParse, /* Parsing context */
- Table *pTab, /* Table containing the row to be deleted */
- int iCur, /* Cursor number for the table */
- int iRowid, /* Memory cell that contains the rowid to delete */
- int count, /* If non-zero, increment the row change counter */
- Trigger *pTrigger, /* List of triggers to (potentially) fire */
- int onconf /* Default ON CONFLICT policy for triggers */
-){
- Vdbe *v = pParse->pVdbe; /* Vdbe */
- int iOld = 0; /* First register in OLD.* array */
- int iLabel; /* Label resolved to end of generated code */
-
- /* Vdbe is guaranteed to have been allocated by this stage. */
- assert( v );
-
- /* Seek cursor iCur to the row to delete. If this row no longer exists
- ** (this can happen if a trigger program has already deleted it), do
- ** not attempt to delete it or fire any DELETE triggers. */
- iLabel = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
-
- /* If there are any triggers to fire, allocate a range of registers to
- ** use for the old.* references in the triggers. */
- if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){
- u32 mask; /* Mask of OLD.* columns in use */
- int iCol; /* Iterator used while populating OLD.* */
-
- /* TODO: Could use temporary registers here. Also could attempt to
- ** avoid copying the contents of the rowid register. */
- mask = sqlite3TriggerColmask(
- pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf
- );
- mask |= sqlite3FkOldmask(pParse, pTab);
- iOld = pParse->nMem+1;
- pParse->nMem += (1 + pTab->nCol);
-
- /* Populate the OLD.* pseudo-table register array. These values will be
- ** used by any BEFORE and AFTER triggers that exist. */
- sqlite3VdbeAddOp2(v, OP_Copy, iRowid, iOld);
- for(iCol=0; iCol<pTab->nCol; iCol++){
- if( mask==0xffffffff || mask&(1<<iCol) ){
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, iOld+iCol+1);
- }
- }
-
- /* Invoke BEFORE DELETE trigger programs. */
- sqlite3CodeRowTrigger(pParse, pTrigger,
- TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel
- );
-
- /* Seek the cursor to the row to be deleted again. It may be that
- ** the BEFORE triggers coded above have already removed the row
- ** being deleted. Do not attempt to delete the row a second time, and
- ** do not fire AFTER triggers. */
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
-
- /* Do FK processing. This call checks that any FK constraints that
- ** refer to this table (i.e. constraints attached to other tables)
- ** are not violated by deleting this row. */
- sqlite3FkCheck(pParse, pTab, iOld, 0);
- }
-
- /* Delete the index and table entries. Skip this step if pTab is really
- ** a view (in which case the only effect of the DELETE statement is to
- ** fire the INSTEAD OF triggers). */
- if( pTab->pSelect==0 ){
- sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
- sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
- if( count ){
- sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
- }
- }
-
- /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
- ** handle rows (possibly in other tables) that refer via a foreign key
- ** to the row just deleted. */
- sqlite3FkActions(pParse, pTab, 0, iOld);
-
- /* Invoke AFTER DELETE trigger programs. */
- sqlite3CodeRowTrigger(pParse, pTrigger,
- TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel
- );
-
- /* Jump here if the row had already been deleted before any BEFORE
- ** trigger programs were invoked. Or if a trigger program throws a
- ** RAISE(IGNORE) exception. */
- sqlite3VdbeResolveLabel(v, iLabel);
-}
-
-/*
-** This routine generates VDBE code that causes the deletion of all
-** index entries associated with a single row of a single table.
-**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
-**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number "iCur".
-**
-** 2. Read/write cursors for all indices of pTab must be open as
-** cursor number iCur+i for the i-th index.
-**
-** 3. The "iCur" cursor must be pointing to the row that is to be
-** deleted.
-*/
-SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
- Parse *pParse, /* Parsing and code generating context */
- Table *pTab, /* Table containing the row to be deleted */
- int iCur, /* Cursor number for the table */
- int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
-){
- int i;
- Index *pIdx;
- int r1;
-
- for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
- if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
- sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
- }
-}
-
-/*
-** Generate code that will assemble an index key and put it in register
-** regOut. The key with be for index pIdx which is an index on pTab.
-** iCur is the index of a cursor open on the pTab table and pointing to
-** the entry that needs indexing.
-**
-** Return a register number which is the first in a block of
-** registers that holds the elements of the index key. The
-** block of registers has already been deallocated by the time
-** this routine returns.
-*/
-SQLITE_PRIVATE int sqlite3GenerateIndexKey(
- Parse *pParse, /* Parsing context */
- Index *pIdx, /* The index for which to generate a key */
- int iCur, /* Cursor number for the pIdx->pTable table */
- int regOut, /* Write the new index key to this register */
- int doMakeRec /* Run the OP_MakeRecord instruction if true */
-){
- Vdbe *v = pParse->pVdbe;
- int j;
- Table *pTab = pIdx->pTable;
- int regBase;
- int nCol;
-
- nCol = pIdx->nColumn;
- regBase = sqlite3GetTempRange(pParse, nCol+1);
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
- for(j=0; j<nCol; j++){
- int idx = pIdx->aiColumn[j];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
- }else{
- sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
- sqlite3ColumnDefault(v, pTab, idx, -1);
- }
- }
- if( doMakeRec ){
- const char *zAff;
- if( pTab->pSelect
- || OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
- ){
- zAff = 0;
- }else{
- zAff = sqlite3IndexAffinityStr(v, pIdx);
- }
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
- sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
- }
- sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
- return regBase;
-}
-
-/************** End of delete.c **********************************************/
-/************** Begin file func.c ********************************************/
-/*
-** 2002 February 23
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the C functions that implement various SQL
-** functions of SQLite.
-**
-** There is only one exported symbol in this file - the function
-** sqliteRegisterBuildinFunctions() found at the bottom of the file.
-** All other code has file scope.
-*/
-/* #include <stdlib.h> */
-/* #include <assert.h> */
-
-/*
-** Return the collating function associated with a function.
-*/
-static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
- return context->pColl;
-}
-
-/*
-** Indicate that the accumulator load should be skipped on this
-** iteration of the aggregate loop.
-*/
-static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
- context->skipFlag = 1;
-}
-
-/*
-** Implementation of the non-aggregate min() and max() functions
-*/
-static void minmaxFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int i;
- int mask; /* 0 for min() or 0xffffffff for max() */
- int iBest;
- CollSeq *pColl;
-
- assert( argc>1 );
- mask = sqlite3_user_data(context)==0 ? 0 : -1;
- pColl = sqlite3GetFuncCollSeq(context);
- assert( pColl );
- assert( mask==-1 || mask==0 );
- iBest = 0;
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
- for(i=1; i<argc; i++){
- if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
- if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
- testcase( mask==0 );
- iBest = i;
- }
- }
- sqlite3_result_value(context, argv[iBest]);
-}
-
-/*
-** Return the type of the argument.
-*/
-static void typeofFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- const char *z = 0;
- UNUSED_PARAMETER(NotUsed);
- switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_INTEGER: z = "integer"; break;
- case SQLITE_TEXT: z = "text"; break;
- case SQLITE_FLOAT: z = "real"; break;
- case SQLITE_BLOB: z = "blob"; break;
- default: z = "null"; break;
- }
- sqlite3_result_text(context, z, -1, SQLITE_STATIC);
-}
-
-
-/*
-** Implementation of the length() function
-*/
-static void lengthFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int len;
-
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_BLOB:
- case SQLITE_INTEGER:
- case SQLITE_FLOAT: {
- sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
- break;
- }
- case SQLITE_TEXT: {
- const unsigned char *z = sqlite3_value_text(argv[0]);
- if( z==0 ) return;
- len = 0;
- while( *z ){
- len++;
- SQLITE_SKIP_UTF8(z);
- }
- sqlite3_result_int(context, len);
- break;
- }
- default: {
- sqlite3_result_null(context);
- break;
- }
- }
-}
-
-/*
-** Implementation of the abs() function.
-**
-** IMP: R-23979-26855 The abs(X) function returns the absolute value of
-** the numeric argument X.
-*/
-static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_INTEGER: {
- i64 iVal = sqlite3_value_int64(argv[0]);
- if( iVal<0 ){
- if( (iVal<<1)==0 ){
- /* IMP: R-35460-15084 If X is the integer -9223372036854775807 then
- ** abs(X) throws an integer overflow error since there is no
- ** equivalent positive 64-bit two complement value. */
- sqlite3_result_error(context, "integer overflow", -1);
- return;
- }
- iVal = -iVal;
- }
- sqlite3_result_int64(context, iVal);
- break;
- }
- case SQLITE_NULL: {
- /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */
- sqlite3_result_null(context);
- break;
- }
- default: {
- /* Because sqlite3_value_double() returns 0.0 if the argument is not
- ** something that can be converted into a number, we have:
- ** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that
- ** cannot be converted to a numeric value.
- */
- double rVal = sqlite3_value_double(argv[0]);
- if( rVal<0 ) rVal = -rVal;
- sqlite3_result_double(context, rVal);
- break;
- }
- }
-}
-
-/*
-** Implementation of the instr() function.
-**
-** instr(haystack,needle) finds the first occurrence of needle
-** in haystack and returns the number of previous characters plus 1,
-** or 0 if needle does not occur within haystack.
-**
-** If both haystack and needle are BLOBs, then the result is one more than
-** the number of bytes in haystack prior to the first occurrence of needle,
-** or 0 if needle never occurs in haystack.
-*/
-static void instrFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *zHaystack;
- const unsigned char *zNeedle;
- int nHaystack;
- int nNeedle;
- int typeHaystack, typeNeedle;
- int N = 1;
- int isText;
-
- UNUSED_PARAMETER(argc);
- typeHaystack = sqlite3_value_type(argv[0]);
- typeNeedle = sqlite3_value_type(argv[1]);
- if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
- nHaystack = sqlite3_value_bytes(argv[0]);
- nNeedle = sqlite3_value_bytes(argv[1]);
- if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
- zHaystack = sqlite3_value_blob(argv[0]);
- zNeedle = sqlite3_value_blob(argv[1]);
- isText = 0;
- }else{
- zHaystack = sqlite3_value_text(argv[0]);
- zNeedle = sqlite3_value_text(argv[1]);
- isText = 1;
- }
- while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
- N++;
- do{
- nHaystack--;
- zHaystack++;
- }while( isText && (zHaystack[0]&0xc0)==0x80 );
- }
- if( nNeedle>nHaystack ) N = 0;
- sqlite3_result_int(context, N);
-}
-
-/*
-** Implementation of the substr() function.
-**
-** substr(x,p1,p2) returns p2 characters of x[] beginning with p1.
-** p1 is 1-indexed. So substr(x,1,1) returns the first character
-** of x. If x is text, then we actually count UTF-8 characters.
-** If x is a blob, then we count bytes.
-**
-** If p1 is negative, then we begin abs(p1) from the end of x[].
-**
-** If p2 is negative, return the p2 characters preceeding p1.
-*/
-static void substrFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *z;
- const unsigned char *z2;
- int len;
- int p0type;
- i64 p1, p2;
- int negP2 = 0;
-
- assert( argc==3 || argc==2 );
- if( sqlite3_value_type(argv[1])==SQLITE_NULL
- || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL)
- ){
- return;
- }
- p0type = sqlite3_value_type(argv[0]);
- p1 = sqlite3_value_int(argv[1]);
- if( p0type==SQLITE_BLOB ){
- len = sqlite3_value_bytes(argv[0]);
- z = sqlite3_value_blob(argv[0]);
- if( z==0 ) return;
- assert( len==sqlite3_value_bytes(argv[0]) );
- }else{
- z = sqlite3_value_text(argv[0]);
- if( z==0 ) return;
- len = 0;
- if( p1<0 ){
- for(z2=z; *z2; len++){
- SQLITE_SKIP_UTF8(z2);
- }
- }
- }
- if( argc==3 ){
- p2 = sqlite3_value_int(argv[2]);
- if( p2<0 ){
- p2 = -p2;
- negP2 = 1;
- }
- }else{
- p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
- }
- if( p1<0 ){
- p1 += len;
- if( p1<0 ){
- p2 += p1;
- if( p2<0 ) p2 = 0;
- p1 = 0;
- }
- }else if( p1>0 ){
- p1--;
- }else if( p2>0 ){
- p2--;
- }
- if( negP2 ){
- p1 -= p2;
- if( p1<0 ){
- p2 += p1;
- p1 = 0;
- }
- }
- assert( p1>=0 && p2>=0 );
- if( p0type!=SQLITE_BLOB ){
- while( *z && p1 ){
- SQLITE_SKIP_UTF8(z);
- p1--;
- }
- for(z2=z; *z2 && p2; p2--){
- SQLITE_SKIP_UTF8(z2);
- }
- sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
- }else{
- if( p1+p2>len ){
- p2 = len-p1;
- if( p2<0 ) p2 = 0;
- }
- sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
- }
-}
-
-/*
-** Implementation of the round() function
-*/
-#ifndef SQLITE_OMIT_FLOATING_POINT
-static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- int n = 0;
- double r;
- char *zBuf;
- assert( argc==1 || argc==2 );
- if( argc==2 ){
- if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
- n = sqlite3_value_int(argv[1]);
- if( n>30 ) n = 30;
- if( n<0 ) n = 0;
- }
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
- r = sqlite3_value_double(argv[0]);
- /* If Y==0 and X will fit in a 64-bit int,
- ** handle the rounding directly,
- ** otherwise use printf.
- */
- if( n==0 && r>=0 && r<LARGEST_INT64-1 ){
- r = (double)((sqlite_int64)(r+0.5));
- }else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){
- r = -(double)((sqlite_int64)((-r)+0.5));
- }else{
- zBuf = sqlite3_mprintf("%.*f",n,r);
- if( zBuf==0 ){
- sqlite3_result_error_nomem(context);
- return;
- }
- sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
- sqlite3_free(zBuf);
- }
- sqlite3_result_double(context, r);
-}
-#endif
-
-/*
-** Allocate nByte bytes of space using sqlite3_malloc(). If the
-** allocation fails, call sqlite3_result_error_nomem() to notify
-** the database handle that malloc() has failed and return NULL.
-** If nByte is larger than the maximum string or blob length, then
-** raise an SQLITE_TOOBIG exception and return NULL.
-*/
-static void *contextMalloc(sqlite3_context *context, i64 nByte){
- char *z;
- sqlite3 *db = sqlite3_context_db_handle(context);
- assert( nByte>0 );
- testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
- testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
- if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- z = 0;
- }else{
- z = sqlite3Malloc((int)nByte);
- if( !z ){
- sqlite3_result_error_nomem(context);
- }
- }
- return z;
-}
-
-/*
-** Implementation of the upper() and lower() SQL functions.
-*/
-static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- char *z1;
- const char *z2;
- int i, n;
- UNUSED_PARAMETER(argc);
- z2 = (char*)sqlite3_value_text(argv[0]);
- n = sqlite3_value_bytes(argv[0]);
- /* Verify that the call to _bytes() does not invalidate the _text() pointer */
- assert( z2==(char*)sqlite3_value_text(argv[0]) );
- if( z2 ){
- z1 = contextMalloc(context, ((i64)n)+1);
- if( z1 ){
- for(i=0; i<n; i++){
- z1[i] = (char)sqlite3Toupper(z2[i]);
- }
- sqlite3_result_text(context, z1, n, sqlite3_free);
- }
- }
-}
-static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- char *z1;
- const char *z2;
- int i, n;
- UNUSED_PARAMETER(argc);
- z2 = (char*)sqlite3_value_text(argv[0]);
- n = sqlite3_value_bytes(argv[0]);
- /* Verify that the call to _bytes() does not invalidate the _text() pointer */
- assert( z2==(char*)sqlite3_value_text(argv[0]) );
- if( z2 ){
- z1 = contextMalloc(context, ((i64)n)+1);
- if( z1 ){
- for(i=0; i<n; i++){
- z1[i] = sqlite3Tolower(z2[i]);
- }
- sqlite3_result_text(context, z1, n, sqlite3_free);
- }
- }
-}
-
-/*
-** The COALESCE() and IFNULL() functions are implemented as VDBE code so
-** that unused argument values do not have to be computed. However, we
-** still need some kind of function implementation for this routines in
-** the function table. That function implementation will never be called
-** so it doesn't matter what the implementation is. We might as well use
-** the "version()" function as a substitute.
-*/
-#define ifnullFunc versionFunc /* Substitute function - never called */
-
-/*
-** Implementation of random(). Return a random integer.
-*/
-static void randomFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- sqlite_int64 r;
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_randomness(sizeof(r), &r);
- if( r<0 ){
- /* We need to prevent a random number of 0x8000000000000000
- ** (or -9223372036854775808) since when you do abs() of that
- ** number of you get the same value back again. To do this
- ** in a way that is testable, mask the sign bit off of negative
- ** values, resulting in a positive value. Then take the
- ** 2s complement of that positive value. The end result can
- ** therefore be no less than -9223372036854775807.
- */
- r = -(r & LARGEST_INT64);
- }
- sqlite3_result_int64(context, r);
-}
-
-/*
-** Implementation of randomblob(N). Return a random blob
-** that is N bytes long.
-*/
-static void randomBlob(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int n;
- unsigned char *p;
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- n = sqlite3_value_int(argv[0]);
- if( n<1 ){
- n = 1;
- }
- p = contextMalloc(context, n);
- if( p ){
- sqlite3_randomness(n, p);
- sqlite3_result_blob(context, (char*)p, n, sqlite3_free);
- }
-}
-
-/*
-** Implementation of the last_insert_rowid() SQL function. The return
-** value is the same as the sqlite3_last_insert_rowid() API function.
-*/
-static void last_insert_rowid(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- sqlite3 *db = sqlite3_context_db_handle(context);
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- /* IMP: R-51513-12026 The last_insert_rowid() SQL function is a
- ** wrapper around the sqlite3_last_insert_rowid() C/C++ interface
- ** function. */
- sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
-}
-
-/*
-** Implementation of the changes() SQL function.
-**
-** IMP: R-62073-11209 The changes() SQL function is a wrapper
-** around the sqlite3_changes() C/C++ function and hence follows the same
-** rules for counting changes.
-*/
-static void changes(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- sqlite3 *db = sqlite3_context_db_handle(context);
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- sqlite3_result_int(context, sqlite3_changes(db));
-}
-
-/*
-** Implementation of the total_changes() SQL function. The return value is
-** the same as the sqlite3_total_changes() API function.
-*/
-static void total_changes(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- sqlite3 *db = sqlite3_context_db_handle(context);
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- /* IMP: R-52756-41993 This function is a wrapper around the
- ** sqlite3_total_changes() C/C++ interface. */
- sqlite3_result_int(context, sqlite3_total_changes(db));
-}
-
-/*
-** A structure defining how to do GLOB-style comparisons.
-*/
-struct compareInfo {
- u8 matchAll;
- u8 matchOne;
- u8 matchSet;
- u8 noCase;
-};
-
-/*
-** For LIKE and GLOB matching on EBCDIC machines, assume that every
-** character is exactly one byte in size. Also, all characters are
-** able to participate in upper-case-to-lower-case mappings in EBCDIC
-** whereas only characters less than 0x80 do in ASCII.
-*/
-#if defined(SQLITE_EBCDIC)
-# define sqlite3Utf8Read(A) (*((*A)++))
-# define GlogUpperToLower(A) A = sqlite3UpperToLower[A]
-#else
-# define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
-#endif
-
-static const struct compareInfo globInfo = { '*', '?', '[', 0 };
-/* The correct SQL-92 behavior is for the LIKE operator to ignore
-** case. Thus 'a' LIKE 'A' would be true. */
-static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 };
-/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
-** is case sensitive causing 'a' LIKE 'A' to be false */
-static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
-
-/*
-** Compare two UTF-8 strings for equality where the first string can
-** potentially be a "glob" expression. Return true (1) if they
-** are the same and false (0) if they are different.
-**
-** Globbing rules:
-**
-** '*' Matches any sequence of zero or more characters.
-**
-** '?' Matches exactly one character.
-**
-** [...] Matches one character from the enclosed list of
-** characters.
-**
-** [^...] Matches one character not in the enclosed list.
-**
-** With the [...] and [^...] matching, a ']' character can be included
-** in the list by making it the first character after '[' or '^'. A
-** range of characters can be specified using '-'. Example:
-** "[a-z]" matches any single lower-case letter. To match a '-', make
-** it the last character in the list.
-**
-** This routine is usually quick, but can be N**2 in the worst case.
-**
-** Hints: to match '*' or '?', put them in "[]". Like this:
-**
-** abc[*]xyz Matches "abc*xyz" only
-*/
-static int patternCompare(
- const u8 *zPattern, /* The glob pattern */
- const u8 *zString, /* The string to compare against the glob */
- const struct compareInfo *pInfo, /* Information about how to do the compare */
- u32 esc /* The escape character */
-){
- u32 c, c2;
- int invert;
- int seen;
- u8 matchOne = pInfo->matchOne;
- u8 matchAll = pInfo->matchAll;
- u8 matchSet = pInfo->matchSet;
- u8 noCase = pInfo->noCase;
- int prevEscape = 0; /* True if the previous character was 'escape' */
-
- while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
- if( c==matchAll && !prevEscape ){
- while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
- || c == matchOne ){
- if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
- return 0;
- }
- }
- if( c==0 ){
- return 1;
- }else if( c==esc ){
- c = sqlite3Utf8Read(&zPattern);
- if( c==0 ){
- return 0;
- }
- }else if( c==matchSet ){
- assert( esc==0 ); /* This is GLOB, not LIKE */
- assert( matchSet<0x80 ); /* '[' is a single-byte character */
- while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
- SQLITE_SKIP_UTF8(zString);
- }
- return *zString!=0;
- }
- while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
- if( noCase ){
- GlogUpperToLower(c2);
- GlogUpperToLower(c);
- while( c2 != 0 && c2 != c ){
- c2 = sqlite3Utf8Read(&zString);
- GlogUpperToLower(c2);
- }
- }else{
- while( c2 != 0 && c2 != c ){
- c2 = sqlite3Utf8Read(&zString);
- }
- }
- if( c2==0 ) return 0;
- if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
- }
- return 0;
- }else if( c==matchOne && !prevEscape ){
- if( sqlite3Utf8Read(&zString)==0 ){
- return 0;
- }
- }else if( c==matchSet ){
- u32 prior_c = 0;
- assert( esc==0 ); /* This only occurs for GLOB, not LIKE */
- seen = 0;
- invert = 0;
- c = sqlite3Utf8Read(&zString);
- if( c==0 ) return 0;
- c2 = sqlite3Utf8Read(&zPattern);
- if( c2=='^' ){
- invert = 1;
- c2 = sqlite3Utf8Read(&zPattern);
- }
- if( c2==']' ){
- if( c==']' ) seen = 1;
- c2 = sqlite3Utf8Read(&zPattern);
- }
- while( c2 && c2!=']' ){
- if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
- c2 = sqlite3Utf8Read(&zPattern);
- if( c>=prior_c && c<=c2 ) seen = 1;
- prior_c = 0;
- }else{
- if( c==c2 ){
- seen = 1;
- }
- prior_c = c2;
- }
- c2 = sqlite3Utf8Read(&zPattern);
- }
- if( c2==0 || (seen ^ invert)==0 ){
- return 0;
- }
- }else if( esc==c && !prevEscape ){
- prevEscape = 1;
- }else{
- c2 = sqlite3Utf8Read(&zString);
- if( noCase ){
- GlogUpperToLower(c);
- GlogUpperToLower(c2);
- }
- if( c!=c2 ){
- return 0;
- }
- prevEscape = 0;
- }
- }
- return *zString==0;
-}
-
-/*
-** Count the number of times that the LIKE operator (or GLOB which is
-** just a variation of LIKE) gets called. This is used for testing
-** only.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_like_count = 0;
-#endif
-
-
-/*
-** Implementation of the like() SQL function. This function implements
-** the build-in LIKE operator. The first argument to the function is the
-** pattern and the second argument is the string. So, the SQL statements:
-**
-** A LIKE B
-**
-** is implemented as like(B,A).
-**
-** This same function (with a different compareInfo structure) computes
-** the GLOB operator.
-*/
-static void likeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *zA, *zB;
- u32 escape = 0;
- int nPat;
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- zB = sqlite3_value_text(argv[0]);
- zA = sqlite3_value_text(argv[1]);
-
- /* Limit the length of the LIKE or GLOB pattern to avoid problems
- ** of deep recursion and N*N behavior in patternCompare().
- */
- nPat = sqlite3_value_bytes(argv[0]);
- testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] );
- testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 );
- if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){
- sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
- return;
- }
- assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */
-
- if( argc==3 ){
- /* The escape character string must consist of a single UTF-8 character.
- ** Otherwise, return an error.
- */
- const unsigned char *zEsc = sqlite3_value_text(argv[2]);
- if( zEsc==0 ) return;
- if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
- sqlite3_result_error(context,
- "ESCAPE expression must be a single character", -1);
- return;
- }
- escape = sqlite3Utf8Read(&zEsc);
- }
- if( zA && zB ){
- struct compareInfo *pInfo = sqlite3_user_data(context);
-#ifdef SQLITE_TEST
- sqlite3_like_count++;
-#endif
-
- sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
- }
-}
-
-/*
-** Implementation of the NULLIF(x,y) function. The result is the first
-** argument if the arguments are different. The result is NULL if the
-** arguments are equal to each other.
-*/
-static void nullifFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- CollSeq *pColl = sqlite3GetFuncCollSeq(context);
- UNUSED_PARAMETER(NotUsed);
- if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){
- sqlite3_result_value(context, argv[0]);
- }
-}
-
-/*
-** Implementation of the sqlite_version() function. The result is the version
-** of the SQLite library that is running.
-*/
-static void versionFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- /* IMP: R-48699-48617 This function is an SQL wrapper around the
- ** sqlite3_libversion() C-interface. */
- sqlite3_result_text(context, sqlite3_libversion(), -1, SQLITE_STATIC);
-}
-
-/*
-** Implementation of the sqlite_source_id() function. The result is a string
-** that identifies the particular version of the source code used to build
-** SQLite.
-*/
-static void sourceidFunc(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **NotUsed2
-){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- /* IMP: R-24470-31136 This function is an SQL wrapper around the
- ** sqlite3_sourceid() C interface. */
- sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC);
-}
-
-/*
-** Implementation of the sqlite_log() function. This is a wrapper around
-** sqlite3_log(). The return value is NULL. The function exists purely for
-** its side-effects.
-*/
-static void errlogFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- UNUSED_PARAMETER(argc);
- UNUSED_PARAMETER(context);
- sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1]));
-}
-
-/*
-** Implementation of the sqlite_compileoption_used() function.
-** The result is an integer that identifies if the compiler option
-** was used to build SQLite.
-*/
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-static void compileoptionusedFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zOptName;
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL
- ** function is a wrapper around the sqlite3_compileoption_used() C/C++
- ** function.
- */
- if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){
- sqlite3_result_int(context, sqlite3_compileoption_used(zOptName));
- }
-}
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
-
-/*
-** Implementation of the sqlite_compileoption_get() function.
-** The result is a string that identifies the compiler options
-** used to build SQLite.
-*/
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-static void compileoptiongetFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int n;
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function
- ** is a wrapper around the sqlite3_compileoption_get() C/C++ function.
- */
- n = sqlite3_value_int(argv[0]);
- sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC);
-}
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
-
-/* Array for converting from half-bytes (nybbles) into ASCII hex
-** digits. */
-static const char hexdigits[] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-};
-
-/*
-** EXPERIMENTAL - This is not an official function. The interface may
-** change. This function may disappear. Do not write code that depends
-** on this function.
-**
-** Implementation of the QUOTE() function. This function takes a single
-** argument. If the argument is numeric, the return value is the same as
-** the argument. If the argument is NULL, the return value is the string
-** "NULL". Otherwise, the argument is enclosed in single quotes with
-** single-quote escapes.
-*/
-static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- switch( sqlite3_value_type(argv[0]) ){
- case SQLITE_FLOAT: {
- double r1, r2;
- char zBuf[50];
- r1 = sqlite3_value_double(argv[0]);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
- sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8);
- if( r1!=r2 ){
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1);
- }
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- break;
- }
- case SQLITE_INTEGER: {
- sqlite3_result_value(context, argv[0]);
- break;
- }
- case SQLITE_BLOB: {
- char *zText = 0;
- char const *zBlob = sqlite3_value_blob(argv[0]);
- int nBlob = sqlite3_value_bytes(argv[0]);
- assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
- zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4);
- if( zText ){
- int i;
- for(i=0; i<nBlob; i++){
- zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
- zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
- }
- zText[(nBlob*2)+2] = '\'';
- zText[(nBlob*2)+3] = '\0';
- zText[0] = 'X';
- zText[1] = '\'';
- sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
- sqlite3_free(zText);
- }
- break;
- }
- case SQLITE_TEXT: {
- int i,j;
- u64 n;
- const unsigned char *zArg = sqlite3_value_text(argv[0]);
- char *z;
-
- if( zArg==0 ) return;
- for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
- z = contextMalloc(context, ((i64)i)+((i64)n)+3);
- if( z ){
- z[0] = '\'';
- for(i=0, j=1; zArg[i]; i++){
- z[j++] = zArg[i];
- if( zArg[i]=='\'' ){
- z[j++] = '\'';
- }
- }
- z[j++] = '\'';
- z[j] = 0;
- sqlite3_result_text(context, z, j, sqlite3_free);
- }
- break;
- }
- default: {
- assert( sqlite3_value_type(argv[0])==SQLITE_NULL );
- sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
- break;
- }
- }
-}
-
-/*
-** The hex() function. Interpret the argument as a blob. Return
-** a hexadecimal rendering as text.
-*/
-static void hexFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int i, n;
- const unsigned char *pBlob;
- char *zHex, *z;
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- pBlob = sqlite3_value_blob(argv[0]);
- n = sqlite3_value_bytes(argv[0]);
- assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
- z = zHex = contextMalloc(context, ((i64)n)*2 + 1);
- if( zHex ){
- for(i=0; i<n; i++, pBlob++){
- unsigned char c = *pBlob;
- *(z++) = hexdigits[(c>>4)&0xf];
- *(z++) = hexdigits[c&0xf];
- }
- *z = 0;
- sqlite3_result_text(context, zHex, n*2, sqlite3_free);
- }
-}
-
-/*
-** The zeroblob(N) function returns a zero-filled blob of size N bytes.
-*/
-static void zeroblobFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- i64 n;
- sqlite3 *db = sqlite3_context_db_handle(context);
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- n = sqlite3_value_int64(argv[0]);
- testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] );
- testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
- if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- }else{
- sqlite3_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */
- }
-}
-
-/*
-** The replace() function. Three arguments are all strings: call
-** them A, B, and C. The result is also a string which is derived
-** from A by replacing every occurance of B with C. The match
-** must be exact. Collating sequences are not used.
-*/
-static void replaceFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *zStr; /* The input string A */
- const unsigned char *zPattern; /* The pattern string B */
- const unsigned char *zRep; /* The replacement string C */
- unsigned char *zOut; /* The output */
- int nStr; /* Size of zStr */
- int nPattern; /* Size of zPattern */
- int nRep; /* Size of zRep */
- i64 nOut; /* Maximum size of zOut */
- int loopLimit; /* Last zStr[] that might match zPattern[] */
- int i, j; /* Loop counters */
-
- assert( argc==3 );
- UNUSED_PARAMETER(argc);
- zStr = sqlite3_value_text(argv[0]);
- if( zStr==0 ) return;
- nStr = sqlite3_value_bytes(argv[0]);
- assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */
- zPattern = sqlite3_value_text(argv[1]);
- if( zPattern==0 ){
- assert( sqlite3_value_type(argv[1])==SQLITE_NULL
- || sqlite3_context_db_handle(context)->mallocFailed );
- return;
- }
- if( zPattern[0]==0 ){
- assert( sqlite3_value_type(argv[1])!=SQLITE_NULL );
- sqlite3_result_value(context, argv[0]);
- return;
- }
- nPattern = sqlite3_value_bytes(argv[1]);
- assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */
- zRep = sqlite3_value_text(argv[2]);
- if( zRep==0 ) return;
- nRep = sqlite3_value_bytes(argv[2]);
- assert( zRep==sqlite3_value_text(argv[2]) );
- nOut = nStr + 1;
- assert( nOut<SQLITE_MAX_LENGTH );
- zOut = contextMalloc(context, (i64)nOut);
- if( zOut==0 ){
- return;
- }
- loopLimit = nStr - nPattern;
- for(i=j=0; i<=loopLimit; i++){
- if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
- zOut[j++] = zStr[i];
- }else{
- u8 *zOld;
- sqlite3 *db = sqlite3_context_db_handle(context);
- nOut += nRep - nPattern;
- testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
- testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
- if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- sqlite3_free(zOut);
- return;
- }
- zOld = zOut;
- zOut = sqlite3_realloc(zOut, (int)nOut);
- if( zOut==0 ){
- sqlite3_result_error_nomem(context);
- sqlite3_free(zOld);
- return;
- }
- memcpy(&zOut[j], zRep, nRep);
- j += nRep;
- i += nPattern-1;
- }
- }
- assert( j+nStr-i+1==nOut );
- memcpy(&zOut[j], &zStr[i], nStr-i);
- j += nStr - i;
- assert( j<=nOut );
- zOut[j] = 0;
- sqlite3_result_text(context, (char*)zOut, j, sqlite3_free);
-}
-
-/*
-** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
-** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
-*/
-static void trimFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *zIn; /* Input string */
- const unsigned char *zCharSet; /* Set of characters to trim */
- int nIn; /* Number of bytes in input */
- int flags; /* 1: trimleft 2: trimright 3: trim */
- int i; /* Loop counter */
- unsigned char *aLen = 0; /* Length of each character in zCharSet */
- unsigned char **azChar = 0; /* Individual characters in zCharSet */
- int nChar; /* Number of characters in zCharSet */
-
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
- return;
- }
- zIn = sqlite3_value_text(argv[0]);
- if( zIn==0 ) return;
- nIn = sqlite3_value_bytes(argv[0]);
- assert( zIn==sqlite3_value_text(argv[0]) );
- if( argc==1 ){
- static const unsigned char lenOne[] = { 1 };
- static unsigned char * const azOne[] = { (u8*)" " };
- nChar = 1;
- aLen = (u8*)lenOne;
- azChar = (unsigned char **)azOne;
- zCharSet = 0;
- }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){
- return;
- }else{
- const unsigned char *z;
- for(z=zCharSet, nChar=0; *z; nChar++){
- SQLITE_SKIP_UTF8(z);
- }
- if( nChar>0 ){
- azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1));
- if( azChar==0 ){
- return;
- }
- aLen = (unsigned char*)&azChar[nChar];
- for(z=zCharSet, nChar=0; *z; nChar++){
- azChar[nChar] = (unsigned char *)z;
- SQLITE_SKIP_UTF8(z);
- aLen[nChar] = (u8)(z - azChar[nChar]);
- }
- }
- }
- if( nChar>0 ){
- flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context));
- if( flags & 1 ){
- while( nIn>0 ){
- int len = 0;
- for(i=0; i<nChar; i++){
- len = aLen[i];
- if( len<=nIn && memcmp(zIn, azChar[i], len)==0 ) break;
- }
- if( i>=nChar ) break;
- zIn += len;
- nIn -= len;
- }
- }
- if( flags & 2 ){
- while( nIn>0 ){
- int len = 0;
- for(i=0; i<nChar; i++){
- len = aLen[i];
- if( len<=nIn && memcmp(&zIn[nIn-len],azChar[i],len)==0 ) break;
- }
- if( i>=nChar ) break;
- nIn -= len;
- }
- }
- if( zCharSet ){
- sqlite3_free(azChar);
- }
- }
- sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
-}
-
-
-/* IMP: R-25361-16150 This function is omitted from SQLite by default. It
-** is only available if the SQLITE_SOUNDEX compile-time option is used
-** when SQLite is built.
-*/
-#ifdef SQLITE_SOUNDEX
-/*
-** Compute the soundex encoding of a word.
-**
-** IMP: R-59782-00072 The soundex(X) function returns a string that is the
-** soundex encoding of the string X.
-*/
-static void soundexFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- char zResult[8];
- const u8 *zIn;
- int i, j;
- static const unsigned char iCode[] = {
- 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, 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, 0, 0,
- 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
- 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
- 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
- 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
- };
- assert( argc==1 );
- zIn = (u8*)sqlite3_value_text(argv[0]);
- if( zIn==0 ) zIn = (u8*)"";
- for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){}
- if( zIn[i] ){
- u8 prevcode = iCode[zIn[i]&0x7f];
- zResult[0] = sqlite3Toupper(zIn[i]);
- for(j=1; j<4 && zIn[i]; i++){
- int code = iCode[zIn[i]&0x7f];
- if( code>0 ){
- if( code!=prevcode ){
- prevcode = code;
- zResult[j++] = code + '0';
- }
- }else{
- prevcode = 0;
- }
- }
- while( j<4 ){
- zResult[j++] = '0';
- }
- zResult[j] = 0;
- sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);
- }else{
- /* IMP: R-64894-50321 The string "?000" is returned if the argument
- ** is NULL or contains no ASCII alphabetic characters. */
- sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);
- }
-}
-#endif /* SQLITE_SOUNDEX */
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-/*
-** A function that loads a shared-library extension then returns NULL.
-*/
-static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
- const char *zFile = (const char *)sqlite3_value_text(argv[0]);
- const char *zProc;
- sqlite3 *db = sqlite3_context_db_handle(context);
- char *zErrMsg = 0;
-
- if( argc==2 ){
- zProc = (const char *)sqlite3_value_text(argv[1]);
- }else{
- zProc = 0;
- }
- if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){
- sqlite3_result_error(context, zErrMsg, -1);
- sqlite3_free(zErrMsg);
- }
-}
-#endif
-
-
-/*
-** An instance of the following structure holds the context of a
-** sum() or avg() aggregate computation.
-*/
-typedef struct SumCtx SumCtx;
-struct SumCtx {
- double rSum; /* Floating point sum */
- i64 iSum; /* Integer sum */
- i64 cnt; /* Number of elements summed */
- u8 overflow; /* True if integer overflow seen */
- u8 approx; /* True if non-integer value was input to the sum */
-};
-
-/*
-** Routines used to compute the sum, average, and total.
-**
-** The SUM() function follows the (broken) SQL standard which means
-** that it returns NULL if it sums over no inputs. TOTAL returns
-** 0.0 in that case. In addition, TOTAL always returns a float where
-** SUM might return an integer if it never encounters a floating point
-** value. TOTAL never fails, but SUM might through an exception if
-** it overflows an integer.
-*/
-static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
- SumCtx *p;
- int type;
- assert( argc==1 );
- UNUSED_PARAMETER(argc);
- p = sqlite3_aggregate_context(context, sizeof(*p));
- type = sqlite3_value_numeric_type(argv[0]);
- if( p && type!=SQLITE_NULL ){
- p->cnt++;
- if( type==SQLITE_INTEGER ){
- i64 v = sqlite3_value_int64(argv[0]);
- p->rSum += v;
- if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
- p->overflow = 1;
- }
- }else{
- p->rSum += sqlite3_value_double(argv[0]);
- p->approx = 1;
- }
- }
-}
-static void sumFinalize(sqlite3_context *context){
- SumCtx *p;
- p = sqlite3_aggregate_context(context, 0);
- if( p && p->cnt>0 ){
- if( p->overflow ){
- sqlite3_result_error(context,"integer overflow",-1);
- }else if( p->approx ){
- sqlite3_result_double(context, p->rSum);
- }else{
- sqlite3_result_int64(context, p->iSum);
- }
- }
-}
-static void avgFinalize(sqlite3_context *context){
- SumCtx *p;
- p = sqlite3_aggregate_context(context, 0);
- if( p && p->cnt>0 ){
- sqlite3_result_double(context, p->rSum/(double)p->cnt);
- }
-}
-static void totalFinalize(sqlite3_context *context){
- SumCtx *p;
- p = sqlite3_aggregate_context(context, 0);
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- sqlite3_result_double(context, p ? p->rSum : (double)0);
-}
-
-/*
-** The following structure keeps track of state information for the
-** count() aggregate function.
-*/
-typedef struct CountCtx CountCtx;
-struct CountCtx {
- i64 n;
-};
-
-/*
-** Routines to implement the count() aggregate function.
-*/
-static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
- CountCtx *p;
- p = sqlite3_aggregate_context(context, sizeof(*p));
- if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
- p->n++;
- }
-
-#ifndef SQLITE_OMIT_DEPRECATED
- /* The sqlite3_aggregate_count() function is deprecated. But just to make
- ** sure it still operates correctly, verify that its count agrees with our
- ** internal count when using count(*) and when the total count can be
- ** expressed as a 32-bit integer. */
- assert( argc==1 || p==0 || p->n>0x7fffffff
- || p->n==sqlite3_aggregate_count(context) );
-#endif
-}
-static void countFinalize(sqlite3_context *context){
- CountCtx *p;
- p = sqlite3_aggregate_context(context, 0);
- sqlite3_result_int64(context, p ? p->n : 0);
-}
-
-/*
-** Routines to implement min() and max() aggregate functions.
-*/
-static void minmaxStep(
- sqlite3_context *context,
- int NotUsed,
- sqlite3_value **argv
-){
- Mem *pArg = (Mem *)argv[0];
- Mem *pBest;
- UNUSED_PARAMETER(NotUsed);
-
- pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
- if( !pBest ) return;
-
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
- if( pBest->flags ) sqlite3SkipAccumulatorLoad(context);
- }else if( pBest->flags ){
- int max;
- int cmp;
- CollSeq *pColl = sqlite3GetFuncCollSeq(context);
- /* This step function is used for both the min() and max() aggregates,
- ** the only difference between the two being that the sense of the
- ** comparison is inverted. For the max() aggregate, the
- ** sqlite3_user_data() function returns (void *)-1. For min() it
- ** returns (void *)db, where db is the sqlite3* database pointer.
- ** Therefore the next statement sets variable 'max' to 1 for the max()
- ** aggregate, or 0 for min().
- */
- max = sqlite3_user_data(context)!=0;
- cmp = sqlite3MemCompare(pBest, pArg, pColl);
- if( (max && cmp<0) || (!max && cmp>0) ){
- sqlite3VdbeMemCopy(pBest, pArg);
- }else{
- sqlite3SkipAccumulatorLoad(context);
- }
- }else{
- sqlite3VdbeMemCopy(pBest, pArg);
- }
-}
-static void minMaxFinalize(sqlite3_context *context){
- sqlite3_value *pRes;
- pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
- if( pRes ){
- if( pRes->flags ){
- sqlite3_result_value(context, pRes);
- }
- sqlite3VdbeMemRelease(pRes);
- }
-}
-
-/*
-** group_concat(EXPR, ?SEPARATOR?)
-*/
-static void groupConcatStep(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const char *zVal;
- StrAccum *pAccum;
- const char *zSep;
- int nVal, nSep;
- assert( argc==1 || argc==2 );
- if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
- pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
-
- if( pAccum ){
- sqlite3 *db = sqlite3_context_db_handle(context);
- int firstTerm = pAccum->useMalloc==0;
- pAccum->useMalloc = 2;
- pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
- if( !firstTerm ){
- if( argc==2 ){
- zSep = (char*)sqlite3_value_text(argv[1]);
- nSep = sqlite3_value_bytes(argv[1]);
- }else{
- zSep = ",";
- nSep = 1;
- }
- sqlite3StrAccumAppend(pAccum, zSep, nSep);
- }
- zVal = (char*)sqlite3_value_text(argv[0]);
- nVal = sqlite3_value_bytes(argv[0]);
- sqlite3StrAccumAppend(pAccum, zVal, nVal);
- }
-}
-static void groupConcatFinalize(sqlite3_context *context){
- StrAccum *pAccum;
- pAccum = sqlite3_aggregate_context(context, 0);
- if( pAccum ){
- if( pAccum->tooBig ){
- sqlite3_result_error_toobig(context);
- }else if( pAccum->mallocFailed ){
- sqlite3_result_error_nomem(context);
- }else{
- sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
- sqlite3_free);
- }
- }
-}
-
-/*
-** This routine does per-connection function registration. Most
-** of the built-in functions above are part of the global function set.
-** This routine only deals with those that are not global.
-*/
-SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
- int rc = sqlite3_overload_function(db, "MATCH", 2);
- assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
- if( rc==SQLITE_NOMEM ){
- db->mallocFailed = 1;
- }
-}
-
-/*
-** Set the LIKEOPT flag on the 2-argument function with the given name.
-*/
-static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
- FuncDef *pDef;
- pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
- 2, SQLITE_UTF8, 0);
- if( ALWAYS(pDef) ){
- pDef->flags = flagVal;
- }
-}
-
-/*
-** Register the built-in LIKE and GLOB functions. The caseSensitive
-** parameter determines whether or not the LIKE operator is case
-** sensitive. GLOB is always case sensitive.
-*/
-SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
- struct compareInfo *pInfo;
- if( caseSensitive ){
- pInfo = (struct compareInfo*)&likeInfoAlt;
- }else{
- pInfo = (struct compareInfo*)&likeInfoNorm;
- }
- sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
- sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
- sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
- (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
- setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
- setLikeOptFlag(db, "like",
- caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
-}
-
-/*
-** pExpr points to an expression which implements a function. If
-** it is appropriate to apply the LIKE optimization to that function
-** then set aWc[0] through aWc[2] to the wildcard characters and
-** return TRUE. If the function is not a LIKE-style function then
-** return FALSE.
-*/
-SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
- FuncDef *pDef;
- if( pExpr->op!=TK_FUNCTION
- || !pExpr->x.pList
- || pExpr->x.pList->nExpr!=2
- ){
- return 0;
- }
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDef = sqlite3FindFunction(db, pExpr->u.zToken,
- sqlite3Strlen30(pExpr->u.zToken),
- 2, SQLITE_UTF8, 0);
- if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
- return 0;
- }
-
- /* The memcpy() statement assumes that the wildcard characters are
- ** the first three statements in the compareInfo structure. The
- ** asserts() that follow verify that assumption
- */
- memcpy(aWc, pDef->pUserData, 3);
- assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
- assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
- assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
- *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
- return 1;
-}
-
-/*
-** All all of the FuncDef structures in the aBuiltinFunc[] array above
-** to the global function hash table. This occurs at start-time (as
-** a consequence of calling sqlite3_initialize()).
-**
-** After this routine runs
-*/
-SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
- /*
- ** The following array holds FuncDef structures for all of the functions
- ** defined in this file.
- **
- ** The array cannot be constant since changes are made to the
- ** FuncDef.pHash elements at start-time. The elements of this array
- ** are read-only after initialization is complete.
- */
- static SQLITE_WSD FuncDef aBuiltinFunc[] = {
- FUNCTION(ltrim, 1, 1, 0, trimFunc ),
- FUNCTION(ltrim, 2, 1, 0, trimFunc ),
- FUNCTION(rtrim, 1, 2, 0, trimFunc ),
- FUNCTION(rtrim, 2, 2, 0, trimFunc ),
- FUNCTION(trim, 1, 3, 0, trimFunc ),
- FUNCTION(trim, 2, 3, 0, trimFunc ),
- FUNCTION(min, -1, 0, 1, minmaxFunc ),
- FUNCTION(min, 0, 0, 1, 0 ),
- AGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize ),
- FUNCTION(max, -1, 1, 1, minmaxFunc ),
- FUNCTION(max, 0, 1, 1, 0 ),
- AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ),
- FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
- FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
- FUNCTION(instr, 2, 0, 0, instrFunc ),
- FUNCTION(substr, 2, 0, 0, substrFunc ),
- FUNCTION(substr, 3, 0, 0, substrFunc ),
- FUNCTION(abs, 1, 0, 0, absFunc ),
-#ifndef SQLITE_OMIT_FLOATING_POINT
- FUNCTION(round, 1, 0, 0, roundFunc ),
- FUNCTION(round, 2, 0, 0, roundFunc ),
-#endif
- FUNCTION(upper, 1, 0, 0, upperFunc ),
- FUNCTION(lower, 1, 0, 0, lowerFunc ),
- FUNCTION(coalesce, 1, 0, 0, 0 ),
- FUNCTION(coalesce, 0, 0, 0, 0 ),
- FUNCTION2(coalesce, -1, 0, 0, ifnullFunc, SQLITE_FUNC_COALESCE),
- FUNCTION(hex, 1, 0, 0, hexFunc ),
- FUNCTION2(ifnull, 2, 0, 0, ifnullFunc, SQLITE_FUNC_COALESCE),
- FUNCTION(random, 0, 0, 0, randomFunc ),
- FUNCTION(randomblob, 1, 0, 0, randomBlob ),
- FUNCTION(nullif, 2, 0, 1, nullifFunc ),
- FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
- FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
- FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
- FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
- FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
- FUNCTION(quote, 1, 0, 0, quoteFunc ),
- FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
- FUNCTION(changes, 0, 0, 0, changes ),
- FUNCTION(total_changes, 0, 0, 0, total_changes ),
- FUNCTION(replace, 3, 0, 0, replaceFunc ),
- FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
- #ifdef SQLITE_SOUNDEX
- FUNCTION(soundex, 1, 0, 0, soundexFunc ),
- #endif
- #ifndef SQLITE_OMIT_LOAD_EXTENSION
- FUNCTION(load_extension, 1, 0, 0, loadExt ),
- FUNCTION(load_extension, 2, 0, 0, loadExt ),
- #endif
- AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
- AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
- AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
- /* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */
- {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0},
- AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
- AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
- AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
-
- LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
- #ifdef SQLITE_CASE_SENSITIVE_LIKE
- LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
- LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
- #else
- LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
- LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
- #endif
- };
-
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);
-
- for(i=0; i<ArraySize(aBuiltinFunc); i++){
- sqlite3FuncDefInsert(pHash, &aFunc[i]);
- }
- sqlite3RegisterDateTimeFunctions();
-#ifndef SQLITE_OMIT_ALTERTABLE
- sqlite3AlterFunctions();
-#endif
-}
-
-/************** End of func.c ************************************************/
-/************** Begin file fkey.c ********************************************/
-/*
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code used by the compiler to add foreign key
-** support to compiled SQL statements.
-*/
-
-#ifndef SQLITE_OMIT_FOREIGN_KEY
-#ifndef SQLITE_OMIT_TRIGGER
-
-/*
-** Deferred and Immediate FKs
-** --------------------------
-**
-** Foreign keys in SQLite come in two flavours: deferred and immediate.
-** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT
-** is returned and the current statement transaction rolled back. If a
-** deferred foreign key constraint is violated, no action is taken
-** immediately. However if the application attempts to commit the
-** transaction before fixing the constraint violation, the attempt fails.
-**
-** Deferred constraints are implemented using a simple counter associated
-** with the database handle. The counter is set to zero each time a
-** database transaction is opened. Each time a statement is executed
-** that causes a foreign key violation, the counter is incremented. Each
-** time a statement is executed that removes an existing violation from
-** the database, the counter is decremented. When the transaction is
-** committed, the commit fails if the current value of the counter is
-** greater than zero. This scheme has two big drawbacks:
-**
-** * When a commit fails due to a deferred foreign key constraint,
-** there is no way to tell which foreign constraint is not satisfied,
-** or which row it is not satisfied for.
-**
-** * If the database contains foreign key violations when the
-** transaction is opened, this may cause the mechanism to malfunction.
-**
-** Despite these problems, this approach is adopted as it seems simpler
-** than the alternatives.
-**
-** INSERT operations:
-**
-** I.1) For each FK for which the table is the child table, search
-** the parent table for a match. If none is found increment the
-** constraint counter.
-**
-** I.2) For each FK for which the table is the parent table,
-** search the child table for rows that correspond to the new
-** row in the parent table. Decrement the counter for each row
-** found (as the constraint is now satisfied).
-**
-** DELETE operations:
-**
-** D.1) For each FK for which the table is the child table,
-** search the parent table for a row that corresponds to the
-** deleted row in the child table. If such a row is not found,
-** decrement the counter.
-**
-** D.2) For each FK for which the table is the parent table, search
-** the child table for rows that correspond to the deleted row
-** in the parent table. For each found increment the counter.
-**
-** UPDATE operations:
-**
-** An UPDATE command requires that all 4 steps above are taken, but only
-** for FK constraints for which the affected columns are actually
-** modified (values must be compared at runtime).
-**
-** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2.
-** This simplifies the implementation a bit.
-**
-** For the purposes of immediate FK constraints, the OR REPLACE conflict
-** resolution is considered to delete rows before the new row is inserted.
-** If a delete caused by OR REPLACE violates an FK constraint, an exception
-** is thrown, even if the FK constraint would be satisfied after the new
-** row is inserted.
-**
-** Immediate constraints are usually handled similarly. The only difference
-** is that the counter used is stored as part of each individual statement
-** object (struct Vdbe). If, after the statement has run, its immediate
-** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT
-** and the statement transaction is rolled back. An exception is an INSERT
-** statement that inserts a single row only (no triggers). In this case,
-** instead of using a counter, an exception is thrown immediately if the
-** INSERT violates a foreign key constraint. This is necessary as such
-** an INSERT does not open a statement transaction.
-**
-** TODO: How should dropping a table be handled? How should renaming a
-** table be handled?
-**
-**
-** Query API Notes
-** ---------------
-**
-** Before coding an UPDATE or DELETE row operation, the code-generator
-** for those two operations needs to know whether or not the operation
-** requires any FK processing and, if so, which columns of the original
-** row are required by the FK processing VDBE code (i.e. if FKs were
-** implemented using triggers, which of the old.* columns would be
-** accessed). No information is required by the code-generator before
-** coding an INSERT operation. The functions used by the UPDATE/DELETE
-** generation code to query for this information are:
-**
-** sqlite3FkRequired() - Test to see if FK processing is required.
-** sqlite3FkOldmask() - Query for the set of required old.* columns.
-**
-**
-** Externally accessible module functions
-** --------------------------------------
-**
-** sqlite3FkCheck() - Check for foreign key violations.
-** sqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions.
-** sqlite3FkDelete() - Delete an FKey structure.
-*/
-
-/*
-** VDBE Calling Convention
-** -----------------------
-**
-** Example:
-**
-** For the following INSERT statement:
-**
-** CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c);
-** INSERT INTO t1 VALUES(1, 2, 3.1);
-**
-** Register (x): 2 (type integer)
-** Register (x+1): 1 (type integer)
-** Register (x+2): NULL (type NULL)
-** Register (x+3): 3.1 (type real)
-*/
-
-/*
-** A foreign key constraint requires that the key columns in the parent
-** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
-** Given that pParent is the parent table for foreign key constraint pFKey,
-** search the schema a unique index on the parent key columns.
-**
-** If successful, zero is returned. If the parent key is an INTEGER PRIMARY
-** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
-** is set to point to the unique index.
-**
-** If the parent key consists of a single column (the foreign key constraint
-** is not a composite foreign key), output variable *paiCol is set to NULL.
-** Otherwise, it is set to point to an allocated array of size N, where
-** N is the number of columns in the parent key. The first element of the
-** array is the index of the child table column that is mapped by the FK
-** constraint to the parent table column stored in the left-most column
-** of index *ppIdx. The second element of the array is the index of the
-** child table column that corresponds to the second left-most column of
-** *ppIdx, and so on.
-**
-** If the required index cannot be found, either because:
-**
-** 1) The named parent key columns do not exist, or
-**
-** 2) The named parent key columns do exist, but are not subject to a
-** UNIQUE or PRIMARY KEY constraint, or
-**
-** 3) No parent key columns were provided explicitly as part of the
-** foreign key definition, and the parent table does not have a
-** PRIMARY KEY, or
-**
-** 4) No parent key columns were provided explicitly as part of the
-** foreign key definition, and the PRIMARY KEY of the parent table
-** consists of a a different number of columns to the child key in
-** the child table.
-**
-** then non-zero is returned, and a "foreign key mismatch" error loaded
-** into pParse. If an OOM error occurs, non-zero is returned and the
-** pParse->db->mallocFailed flag is set.
-*/
-static int locateFkeyIndex(
- Parse *pParse, /* Parse context to store any error in */
- Table *pParent, /* Parent table of FK constraint pFKey */
- FKey *pFKey, /* Foreign key to find index for */
- Index **ppIdx, /* OUT: Unique index on parent table */
- int **paiCol /* OUT: Map of index columns in pFKey */
-){
- Index *pIdx = 0; /* Value to return via *ppIdx */
- int *aiCol = 0; /* Value to return via *paiCol */
- int nCol = pFKey->nCol; /* Number of columns in parent key */
- char *zKey = pFKey->aCol[0].zCol; /* Name of left-most parent key column */
-
- /* The caller is responsible for zeroing output parameters. */
- assert( ppIdx && *ppIdx==0 );
- assert( !paiCol || *paiCol==0 );
- assert( pParse );
-
- /* If this is a non-composite (single column) foreign key, check if it
- ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx
- ** and *paiCol set to zero and return early.
- **
- ** Otherwise, for a composite foreign key (more than one column), allocate
- ** space for the aiCol array (returned via output parameter *paiCol).
- ** Non-composite foreign keys do not require the aiCol array.
- */
- if( nCol==1 ){
- /* The FK maps to the IPK if any of the following are true:
- **
- ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly
- ** mapped to the primary key of table pParent, or
- ** 2) The FK is explicitly mapped to a column declared as INTEGER
- ** PRIMARY KEY.
- */
- if( pParent->iPKey>=0 ){
- if( !zKey ) return 0;
- if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0;
- }
- }else if( paiCol ){
- assert( nCol>1 );
- aiCol = (int *)sqlite3DbMallocRaw(pParse->db, nCol*sizeof(int));
- if( !aiCol ) return 1;
- *paiCol = aiCol;
- }
-
- for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){
- /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
- ** of columns. If each indexed column corresponds to a foreign key
- ** column of pFKey, then this index is a winner. */
-
- if( zKey==0 ){
- /* If zKey is NULL, then this foreign key is implicitly mapped to
- ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be
- ** identified by the test (Index.autoIndex==2). */
- if( pIdx->autoIndex==2 ){
- if( aiCol ){
- int i;
- for(i=0; i<nCol; i++) aiCol[i] = pFKey->aCol[i].iFrom;
- }
- break;
- }
- }else{
- /* If zKey is non-NULL, then this foreign key was declared to
- ** map to an explicit list of columns in table pParent. Check if this
- ** index matches those columns. Also, check that the index uses
- ** the default collation sequences for each column. */
- int i, j;
- for(i=0; i<nCol; i++){
- int iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
- char *zDfltColl; /* Def. collation for column */
- char *zIdxCol; /* Name of indexed column */
-
- /* If the index uses a collation sequence that is different from
- ** the default collation sequence for the column, this index is
- ** unusable. Bail out early in this case. */
- zDfltColl = pParent->aCol[iCol].zColl;
- if( !zDfltColl ){
- zDfltColl = "BINARY";
- }
- if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break;
-
- zIdxCol = pParent->aCol[iCol].zName;
- for(j=0; j<nCol; j++){
- if( sqlite3StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){
- if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom;
- break;
- }
- }
- if( j==nCol ) break;
- }
- if( i==nCol ) break; /* pIdx is usable */
- }
- }
- }
-
- if( !pIdx ){
- if( !pParse->disableTriggers ){
- sqlite3ErrorMsg(pParse, "foreign key mismatch");
- }
- sqlite3DbFree(pParse->db, aiCol);
- return 1;
- }
-
- *ppIdx = pIdx;
- return 0;
-}
-
-/*
-** This function is called when a row is inserted into or deleted from the
-** child table of foreign key constraint pFKey. If an SQL UPDATE is executed
-** on the child table of pFKey, this function is invoked twice for each row
-** affected - once to "delete" the old row, and then again to "insert" the
-** new row.
-**
-** Each time it is called, this function generates VDBE code to locate the
-** row in the parent table that corresponds to the row being inserted into
-** or deleted from the child table. If the parent row can be found, no
-** special action is taken. Otherwise, if the parent row can *not* be
-** found in the parent table:
-**
-** Operation | FK type | Action taken
-** --------------------------------------------------------------------------
-** INSERT immediate Increment the "immediate constraint counter".
-**
-** DELETE immediate Decrement the "immediate constraint counter".
-**
-** INSERT deferred Increment the "deferred constraint counter".
-**
-** DELETE deferred Decrement the "deferred constraint counter".
-**
-** These operations are identified in the comment at the top of this file
-** (fkey.c) as "I.1" and "D.1".
-*/
-static void fkLookupParent(
- Parse *pParse, /* Parse context */
- int iDb, /* Index of database housing pTab */
- Table *pTab, /* Parent table of FK pFKey */
- Index *pIdx, /* Unique index on parent key columns in pTab */
- FKey *pFKey, /* Foreign key constraint */
- int *aiCol, /* Map from parent key columns to child table columns */
- int regData, /* Address of array containing child table row */
- int nIncr, /* Increment constraint counter by this */
- int isIgnore /* If true, pretend pTab contains all NULL values */
-){
- int i; /* Iterator variable */
- Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */
- int iCur = pParse->nTab - 1; /* Cursor number to use */
- int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */
-
- /* If nIncr is less than zero, then check at runtime if there are any
- ** outstanding constraints to resolve. If there are not, there is no need
- ** to check if deleting this row resolves any outstanding violations.
- **
- ** Check if any of the key columns in the child table row are NULL. If
- ** any are, then the constraint is considered satisfied. No need to
- ** search for a matching row in the parent table. */
- if( nIncr<0 ){
- sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
- }
- for(i=0; i<pFKey->nCol; i++){
- int iReg = aiCol[i] + regData + 1;
- sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
- }
-
- if( isIgnore==0 ){
- if( pIdx==0 ){
- /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
- ** column of the parent table (table pTab). */
- int iMustBeInt; /* Address of MustBeInt instruction */
- int regTemp = sqlite3GetTempReg(pParse);
-
- /* Invoke MustBeInt to coerce the child key value to an integer (i.e.
- ** apply the affinity of the parent key). If this fails, then there
- ** is no matching parent key. Before using MustBeInt, make a copy of
- ** the value. Otherwise, the value inserted into the child key column
- ** will have INTEGER affinity applied to it, which may not be correct. */
- sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
- iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
-
- /* If the parent table is the same as the child table, and we are about
- ** to increment the constraint-counter (i.e. this is an INSERT operation),
- ** then check if the row being inserted matches itself. If so, do not
- ** increment the constraint-counter. */
- if( pTab==pFKey->pFrom && nIncr==1 ){
- sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp);
- }
-
- sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
- sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
- sqlite3VdbeJumpHere(v, iMustBeInt);
- sqlite3ReleaseTempReg(pParse, regTemp);
- }else{
- int nCol = pFKey->nCol;
- int regTemp = sqlite3GetTempRange(pParse, nCol);
- int regRec = sqlite3GetTempReg(pParse);
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
-
- sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
- for(i=0; i<nCol; i++){
- sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
- }
-
- /* If the parent table is the same as the child table, and we are about
- ** to increment the constraint-counter (i.e. this is an INSERT operation),
- ** then check if the row being inserted matches itself. If so, do not
- ** increment the constraint-counter.
- **
- ** If any of the parent-key values are NULL, then the row cannot match
- ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any
- ** of the parent-key values are NULL (at this point it is known that
- ** none of the child key values are).
- */
- if( pTab==pFKey->pFrom && nIncr==1 ){
- int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
- for(i=0; i<nCol; i++){
- int iChild = aiCol[i]+1+regData;
- int iParent = pIdx->aiColumn[i]+1+regData;
- assert( aiCol[i]!=pTab->iPKey );
- if( pIdx->aiColumn[i]==pTab->iPKey ){
- /* The parent key is a composite key that includes the IPK column */
- iParent = regData;
- }
- sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
- sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
- }
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
- }
-
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
- sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
- sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
-
- sqlite3ReleaseTempReg(pParse, regRec);
- sqlite3ReleaseTempRange(pParse, regTemp, nCol);
- }
- }
-
- if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
- /* Special case: If this is an INSERT statement that will insert exactly
- ** one row into the table, raise a constraint immediately instead of
- ** incrementing a counter. This is necessary as the VM code is being
- ** generated for will not open a statement transaction. */
- assert( nIncr==1 );
- sqlite3HaltConstraint(
- pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
- );
- }else{
- if( nIncr>0 && pFKey->isDeferred==0 ){
- sqlite3ParseToplevel(pParse)->mayAbort = 1;
- }
- sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
- }
-
- sqlite3VdbeResolveLabel(v, iOk);
- sqlite3VdbeAddOp1(v, OP_Close, iCur);
-}
-
-/*
-** This function is called to generate code executed when a row is deleted
-** from the parent table of foreign key constraint pFKey and, if pFKey is
-** deferred, when a row is inserted into the same table. When generating
-** code for an SQL UPDATE operation, this function may be called twice -
-** once to "delete" the old row and once to "insert" the new row.
-**
-** The code generated by this function scans through the rows in the child
-** table that correspond to the parent table row being deleted or inserted.
-** For each child row found, one of the following actions is taken:
-**
-** Operation | FK type | Action taken
-** --------------------------------------------------------------------------
-** DELETE immediate Increment the "immediate constraint counter".
-** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
-** throw a "foreign key constraint failed" exception.
-**
-** INSERT immediate Decrement the "immediate constraint counter".
-**
-** DELETE deferred Increment the "deferred constraint counter".
-** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
-** throw a "foreign key constraint failed" exception.
-**
-** INSERT deferred Decrement the "deferred constraint counter".
-**
-** These operations are identified in the comment at the top of this file
-** (fkey.c) as "I.2" and "D.2".
-*/
-static void fkScanChildren(
- Parse *pParse, /* Parse context */
- SrcList *pSrc, /* SrcList containing the table to scan */
- Table *pTab,
- Index *pIdx, /* Foreign key index */
- FKey *pFKey, /* Foreign key relationship */
- int *aiCol, /* Map from pIdx cols to child table cols */
- int regData, /* Referenced table data starts here */
- int nIncr /* Amount to increment deferred counter by */
-){
- sqlite3 *db = pParse->db; /* Database handle */
- int i; /* Iterator variable */
- Expr *pWhere = 0; /* WHERE clause to scan with */
- NameContext sNameContext; /* Context used to resolve WHERE clause */
- WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */
- int iFkIfZero = 0; /* Address of OP_FkIfZero */
- Vdbe *v = sqlite3GetVdbe(pParse);
-
- assert( !pIdx || pIdx->pTable==pTab );
-
- if( nIncr<0 ){
- iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
- }
-
- /* Create an Expr object representing an SQL expression like:
- **
- ** <parent-key1> = <child-key1> AND <parent-key2> = <child-key2> ...
- **
- ** The collation sequence used for the comparison should be that of
- ** the parent key columns. The affinity of the parent key column should
- ** be applied to each child key value before the comparison takes place.
- */
- for(i=0; i<pFKey->nCol; i++){
- Expr *pLeft; /* Value from parent table row */
- Expr *pRight; /* Column ref to child table */
- Expr *pEq; /* Expression (pLeft = pRight) */
- int iCol; /* Index of column in child table */
- const char *zCol; /* Name of column in child table */
-
- pLeft = sqlite3Expr(db, TK_REGISTER, 0);
- if( pLeft ){
- /* Set the collation sequence and affinity of the LHS of each TK_EQ
- ** expression to the parent key column defaults. */
- if( pIdx ){
- Column *pCol;
- const char *zColl;
- iCol = pIdx->aiColumn[i];
- pCol = &pTab->aCol[iCol];
- if( pTab->iPKey==iCol ) iCol = -1;
- pLeft->iTable = regData+iCol+1;
- pLeft->affinity = pCol->affinity;
- zColl = pCol->zColl;
- if( zColl==0 ) zColl = db->pDfltColl->zName;
- pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
- }else{
- pLeft->iTable = regData;
- pLeft->affinity = SQLITE_AFF_INTEGER;
- }
- }
- iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
- assert( iCol>=0 );
- zCol = pFKey->pFrom->aCol[iCol].zName;
- pRight = sqlite3Expr(db, TK_ID, zCol);
- pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
- }
-
- /* If the child table is the same as the parent table, and this scan
- ** is taking place as part of a DELETE operation (operation D.2), omit the
- ** row being deleted from the scan by adding ($rowid != rowid) to the WHERE
- ** clause, where $rowid is the rowid of the row being deleted. */
- if( pTab==pFKey->pFrom && nIncr>0 ){
- Expr *pEq; /* Expression (pLeft = pRight) */
- Expr *pLeft; /* Value from parent table row */
- Expr *pRight; /* Column ref to child table */
- pLeft = sqlite3Expr(db, TK_REGISTER, 0);
- pRight = sqlite3Expr(db, TK_COLUMN, 0);
- if( pLeft && pRight ){
- pLeft->iTable = regData;
- pLeft->affinity = SQLITE_AFF_INTEGER;
- pRight->iTable = pSrc->a[0].iCursor;
- pRight->iColumn = -1;
- }
- pEq = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
- }
-
- /* Resolve the references in the WHERE clause. */
- memset(&sNameContext, 0, sizeof(NameContext));
- sNameContext.pSrcList = pSrc;
- sNameContext.pParse = pParse;
- sqlite3ResolveExprNames(&sNameContext, pWhere);
-
- /* Create VDBE to loop through the entries in pSrc that match the WHERE
- ** clause. If the constraint is not deferred, throw an exception for
- ** each row found. Otherwise, for deferred constraints, increment the
- ** deferred constraint counter by nIncr for each row selected. */
- pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
- if( nIncr>0 && pFKey->isDeferred==0 ){
- sqlite3ParseToplevel(pParse)->mayAbort = 1;
- }
- sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
- if( pWInfo ){
- sqlite3WhereEnd(pWInfo);
- }
-
- /* Clean up the WHERE clause constructed above. */
- sqlite3ExprDelete(db, pWhere);
- if( iFkIfZero ){
- sqlite3VdbeJumpHere(v, iFkIfZero);
- }
-}
-
-/*
-** This function returns a pointer to the head of a linked list of FK
-** constraints for which table pTab is the parent table. For example,
-** given the following schema:
-**
-** CREATE TABLE t1(a PRIMARY KEY);
-** CREATE TABLE t2(b REFERENCES t1(a);
-**
-** Calling this function with table "t1" as an argument returns a pointer
-** to the FKey structure representing the foreign key constraint on table
-** "t2". Calling this function with "t2" as the argument would return a
-** NULL pointer (as there are no FK constraints for which t2 is the parent
-** table).
-*/
-SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){
- int nName = sqlite3Strlen30(pTab->zName);
- return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName, nName);
-}
-
-/*
-** The second argument is a Trigger structure allocated by the
-** fkActionTrigger() routine. This function deletes the Trigger structure
-** and all of its sub-components.
-**
-** The Trigger structure or any of its sub-components may be allocated from
-** the lookaside buffer belonging to database handle dbMem.
-*/
-static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){
- if( p ){
- TriggerStep *pStep = p->step_list;
- sqlite3ExprDelete(dbMem, pStep->pWhere);
- sqlite3ExprListDelete(dbMem, pStep->pExprList);
- sqlite3SelectDelete(dbMem, pStep->pSelect);
- sqlite3ExprDelete(dbMem, p->pWhen);
- sqlite3DbFree(dbMem, p);
- }
-}
-
-/*
-** This function is called to generate code that runs when table pTab is
-** being dropped from the database. The SrcList passed as the second argument
-** to this function contains a single entry guaranteed to resolve to
-** table pTab.
-**
-** Normally, no code is required. However, if either
-**
-** (a) The table is the parent table of a FK constraint, or
-** (b) The table is the child table of a deferred FK constraint and it is
-** determined at runtime that there are outstanding deferred FK
-** constraint violations in the database,
-**
-** then the equivalent of "DELETE FROM <tbl>" is executed before dropping
-** the table from the database. Triggers are disabled while running this
-** DELETE, but foreign key actions are not.
-*/
-SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
- sqlite3 *db = pParse->db;
- if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){
- int iSkip = 0;
- Vdbe *v = sqlite3GetVdbe(pParse);
-
- assert( v ); /* VDBE has already been allocated */
- if( sqlite3FkReferences(pTab)==0 ){
- /* Search for a deferred foreign key constraint for which this table
- ** is the child table. If one cannot be found, return without
- ** generating any VDBE code. If one can be found, then jump over
- ** the entire DELETE if there are no outstanding deferred constraints
- ** when this statement is run. */
- FKey *p;
- for(p=pTab->pFKey; p; p=p->pNextFrom){
- if( p->isDeferred ) break;
- }
- if( !p ) return;
- iSkip = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip);
- }
-
- pParse->disableTriggers = 1;
- sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0);
- pParse->disableTriggers = 0;
-
- /* If the DELETE has generated immediate foreign key constraint
- ** violations, halt the VDBE and return an error at this point, before
- ** any modifications to the schema are made. This is because statement
- ** transactions are not able to rollback schema changes. */
- sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
- sqlite3HaltConstraint(
- pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
- );
-
- if( iSkip ){
- sqlite3VdbeResolveLabel(v, iSkip);
- }
- }
-}
-
-/*
-** This function is called when inserting, deleting or updating a row of
-** table pTab to generate VDBE code to perform foreign key constraint
-** processing for the operation.
-**
-** For a DELETE operation, parameter regOld is passed the index of the
-** first register in an array of (pTab->nCol+1) registers containing the
-** rowid of the row being deleted, followed by each of the column values
-** of the row being deleted, from left to right. Parameter regNew is passed
-** zero in this case.
-**
-** For an INSERT operation, regOld is passed zero and regNew is passed the
-** first register of an array of (pTab->nCol+1) registers containing the new
-** row data.
-**
-** For an UPDATE operation, this function is called twice. Once before
-** the original record is deleted from the table using the calling convention
-** described for DELETE. Then again after the original record is deleted
-** but before the new record is inserted using the INSERT convention.
-*/
-SQLITE_PRIVATE void sqlite3FkCheck(
- Parse *pParse, /* Parse context */
- Table *pTab, /* Row is being deleted from this table */
- int regOld, /* Previous row data is stored here */
- int regNew /* New row data is stored here */
-){
- sqlite3 *db = pParse->db; /* Database handle */
- FKey *pFKey; /* Used to iterate through FKs */
- int iDb; /* Index of database containing pTab */
- const char *zDb; /* Name of database containing pTab */
- int isIgnoreErrors = pParse->disableTriggers;
-
- /* Exactly one of regOld and regNew should be non-zero. */
- assert( (regOld==0)!=(regNew==0) );
-
- /* If foreign-keys are disabled, this function is a no-op. */
- if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
-
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- zDb = db->aDb[iDb].zName;
-
- /* Loop through all the foreign key constraints for which pTab is the
- ** child table (the table that the foreign key definition is part of). */
- for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
- Table *pTo; /* Parent table of foreign key pFKey */
- Index *pIdx = 0; /* Index on key columns in pTo */
- int *aiFree = 0;
- int *aiCol;
- int iCol;
- int i;
- int isIgnore = 0;
-
- /* Find the parent table of this foreign key. Also find a unique index
- ** on the parent key columns in the parent table. If either of these
- ** schema items cannot be located, set an error in pParse and return
- ** early. */
- if( pParse->disableTriggers ){
- pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
- }else{
- pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
- }
- if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
- assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
- if( !isIgnoreErrors || db->mallocFailed ) return;
- if( pTo==0 ){
- /* If isIgnoreErrors is true, then a table is being dropped. In this
- ** case SQLite runs a "DELETE FROM xxx" on the table being dropped
- ** before actually dropping it in order to check FK constraints.
- ** If the parent table of an FK constraint on the current table is
- ** missing, behave as if it is empty. i.e. decrement the relevant
- ** FK counter for each row of the current table with non-NULL keys.
- */
- Vdbe *v = sqlite3GetVdbe(pParse);
- int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
- for(i=0; i<pFKey->nCol; i++){
- int iReg = pFKey->aCol[i].iFrom + regOld + 1;
- sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump);
- }
- sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
- }
- continue;
- }
- assert( pFKey->nCol==1 || (aiFree && pIdx) );
-
- if( aiFree ){
- aiCol = aiFree;
- }else{
- iCol = pFKey->aCol[0].iFrom;
- aiCol = &iCol;
- }
- for(i=0; i<pFKey->nCol; i++){
- if( aiCol[i]==pTab->iPKey ){
- aiCol[i] = -1;
- }
-#ifndef SQLITE_OMIT_AUTHORIZATION
- /* Request permission to read the parent key columns. If the
- ** authorization callback returns SQLITE_IGNORE, behave as if any
- ** values read from the parent table are NULL. */
- if( db->xAuth ){
- int rcauth;
- char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
- rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
- isIgnore = (rcauth==SQLITE_IGNORE);
- }
-#endif
- }
-
- /* Take a shared-cache advisory read-lock on the parent table. Allocate
- ** a cursor to use to search the unique index on the parent key columns
- ** in the parent table. */
- sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName);
- pParse->nTab++;
-
- if( regOld!=0 ){
- /* A row is being removed from the child table. Search for the parent.
- ** If the parent does not exist, removing the child row resolves an
- ** outstanding foreign key constraint violation. */
- fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore);
- }
- if( regNew!=0 ){
- /* A row is being added to the child table. If a parent row cannot
- ** be found, adding the child row has violated the FK constraint. */
- fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore);
- }
-
- sqlite3DbFree(db, aiFree);
- }
-
- /* Loop through all the foreign key constraints that refer to this table */
- for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
- Index *pIdx = 0; /* Foreign key index for pFKey */
- SrcList *pSrc;
- int *aiCol = 0;
-
- if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
- assert( regOld==0 && regNew!=0 );
- /* Inserting a single row into a parent table cannot cause an immediate
- ** foreign key violation. So do nothing in this case. */
- continue;
- }
-
- if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){
- if( !isIgnoreErrors || db->mallocFailed ) return;
- continue;
- }
- assert( aiCol || pFKey->nCol==1 );
-
- /* Create a SrcList structure containing a single table (the table
- ** the foreign key that refers to this table is attached to). This
- ** is required for the sqlite3WhereXXX() interface. */
- pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
- if( pSrc ){
- struct SrcList_item *pItem = pSrc->a;
- pItem->pTab = pFKey->pFrom;
- pItem->zName = pFKey->pFrom->zName;
- pItem->pTab->nRef++;
- pItem->iCursor = pParse->nTab++;
-
- if( regNew!=0 ){
- fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
- }
- if( regOld!=0 ){
- /* If there is a RESTRICT action configured for the current operation
- ** on the parent table of this FK, then throw an exception
- ** immediately if the FK constraint is violated, even if this is a
- ** deferred trigger. That's what RESTRICT means. To defer checking
- ** the constraint, the FK should specify NO ACTION (represented
- ** using OE_None). NO ACTION is the default. */
- fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
- }
- pItem->zName = 0;
- sqlite3SrcListDelete(db, pSrc);
- }
- sqlite3DbFree(db, aiCol);
- }
-}
-
-#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x)))
-
-/*
-** This function is called before generating code to update or delete a
-** row contained in table pTab.
-*/
-SQLITE_PRIVATE u32 sqlite3FkOldmask(
- Parse *pParse, /* Parse context */
- Table *pTab /* Table being modified */
-){
- u32 mask = 0;
- if( pParse->db->flags&SQLITE_ForeignKeys ){
- FKey *p;
- int i;
- for(p=pTab->pFKey; p; p=p->pNextFrom){
- for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
- }
- for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- Index *pIdx = 0;
- locateFkeyIndex(pParse, pTab, p, &pIdx, 0);
- if( pIdx ){
- for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
- }
- }
- }
- return mask;
-}
-
-/*
-** This function is called before generating code to update or delete a
-** row contained in table pTab. If the operation is a DELETE, then
-** parameter aChange is passed a NULL value. For an UPDATE, aChange points
-** to an array of size N, where N is the number of columns in table pTab.
-** If the i'th column is not modified by the UPDATE, then the corresponding
-** entry in the aChange[] array is set to -1. If the column is modified,
-** the value is 0 or greater. Parameter chngRowid is set to true if the
-** UPDATE statement modifies the rowid fields of the table.
-**
-** If any foreign key processing will be required, this function returns
-** true. If there is no foreign key related processing, this function
-** returns false.
-*/
-SQLITE_PRIVATE int sqlite3FkRequired(
- Parse *pParse, /* Parse context */
- Table *pTab, /* Table being modified */
- int *aChange, /* Non-NULL for UPDATE operations */
- int chngRowid /* True for UPDATE that affects rowid */
-){
- if( pParse->db->flags&SQLITE_ForeignKeys ){
- if( !aChange ){
- /* A DELETE operation. Foreign key processing is required if the
- ** table in question is either the child or parent table for any
- ** foreign key constraint. */
- return (sqlite3FkReferences(pTab) || pTab->pFKey);
- }else{
- /* This is an UPDATE. Foreign key processing is only required if the
- ** operation modifies one or more child or parent key columns. */
- int i;
- FKey *p;
-
- /* Check if any child key columns are being modified. */
- for(p=pTab->pFKey; p; p=p->pNextFrom){
- for(i=0; i<p->nCol; i++){
- int iChildKey = p->aCol[i].iFrom;
- if( aChange[iChildKey]>=0 ) return 1;
- if( iChildKey==pTab->iPKey && chngRowid ) return 1;
- }
- }
-
- /* Check if any parent key columns are being modified. */
- for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- for(i=0; i<p->nCol; i++){
- char *zKey = p->aCol[i].zCol;
- int iKey;
- for(iKey=0; iKey<pTab->nCol; iKey++){
- Column *pCol = &pTab->aCol[iKey];
- if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey)
- : (pCol->colFlags & COLFLAG_PRIMKEY)!=0) ){
- if( aChange[iKey]>=0 ) return 1;
- if( iKey==pTab->iPKey && chngRowid ) return 1;
- }
- }
- }
- }
- }
- }
- return 0;
-}
-
-/*
-** This function is called when an UPDATE or DELETE operation is being
-** compiled on table pTab, which is the parent table of foreign-key pFKey.
-** If the current operation is an UPDATE, then the pChanges parameter is
-** passed a pointer to the list of columns being modified. If it is a
-** DELETE, pChanges is passed a NULL pointer.
-**
-** It returns a pointer to a Trigger structure containing a trigger
-** equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
-** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is
-** returned (these actions require no special handling by the triggers
-** sub-system, code for them is created by fkScanChildren()).
-**
-** For example, if pFKey is the foreign key and pTab is table "p" in
-** the following schema:
-**
-** CREATE TABLE p(pk PRIMARY KEY);
-** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE);
-**
-** then the returned trigger structure is equivalent to:
-**
-** CREATE TRIGGER ... DELETE ON p BEGIN
-** DELETE FROM c WHERE ck = old.pk;
-** END;
-**
-** The returned pointer is cached as part of the foreign key object. It
-** is eventually freed along with the rest of the foreign key object by
-** sqlite3FkDelete().
-*/
-static Trigger *fkActionTrigger(
- Parse *pParse, /* Parse context */
- Table *pTab, /* Table being updated or deleted from */
- FKey *pFKey, /* Foreign key to get action for */
- ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */
-){
- sqlite3 *db = pParse->db; /* Database handle */
- int action; /* One of OE_None, OE_Cascade etc. */
- Trigger *pTrigger; /* Trigger definition to return */
- int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */
-
- action = pFKey->aAction[iAction];
- pTrigger = pFKey->apTrigger[iAction];
-
- if( action!=OE_None && !pTrigger ){
- u8 enableLookaside; /* Copy of db->lookaside.bEnabled */
- char const *zFrom; /* Name of child table */
- int nFrom; /* Length in bytes of zFrom */
- Index *pIdx = 0; /* Parent key index for this FK */
- int *aiCol = 0; /* child table cols -> parent key cols */
- TriggerStep *pStep = 0; /* First (only) step of trigger program */
- Expr *pWhere = 0; /* WHERE clause of trigger step */
- ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */
- Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */
- int i; /* Iterator variable */
- Expr *pWhen = 0; /* WHEN clause for the trigger */
-
- if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0;
- assert( aiCol || pFKey->nCol==1 );
-
- for(i=0; i<pFKey->nCol; i++){
- Token tOld = { "old", 3 }; /* Literal "old" token */
- Token tNew = { "new", 3 }; /* Literal "new" token */
- Token tFromCol; /* Name of column in child table */
- Token tToCol; /* Name of column in parent table */
- int iFromCol; /* Idx of column in child table */
- Expr *pEq; /* tFromCol = OLD.tToCol */
-
- iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
- assert( iFromCol>=0 );
- tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid";
- tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
-
- tToCol.n = sqlite3Strlen30(tToCol.z);
- tFromCol.n = sqlite3Strlen30(tFromCol.z);
-
- /* Create the expression "OLD.zToCol = zFromCol". It is important
- ** that the "OLD.zToCol" term is on the LHS of the = operator, so
- ** that the affinity and collation sequence associated with the
- ** parent table are used for the comparison. */
- pEq = sqlite3PExpr(pParse, TK_EQ,
- sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
- , 0),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
- , 0);
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
-
- /* For ON UPDATE, construct the next term of the WHEN clause.
- ** The final WHEN clause will be like this:
- **
- ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
- */
- if( pChanges ){
- pEq = sqlite3PExpr(pParse, TK_IS,
- sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
- 0),
- sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
- 0),
- 0);
- pWhen = sqlite3ExprAnd(db, pWhen, pEq);
- }
-
- if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){
- Expr *pNew;
- if( action==OE_Cascade ){
- pNew = sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
- , 0);
- }else if( action==OE_SetDflt ){
- Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
- if( pDflt ){
- pNew = sqlite3ExprDup(db, pDflt, 0);
- }else{
- pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
- }
- }else{
- pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
- }
- pList = sqlite3ExprListAppend(pParse, pList, pNew);
- sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
- }
- }
- sqlite3DbFree(db, aiCol);
-
- zFrom = pFKey->pFrom->zName;
- nFrom = sqlite3Strlen30(zFrom);
-
- if( action==OE_Restrict ){
- Token tFrom;
- Expr *pRaise;
-
- tFrom.z = zFrom;
- tFrom.n = nFrom;
- pRaise = sqlite3Expr(db, TK_RAISE, "foreign key constraint failed");
- if( pRaise ){
- pRaise->affinity = OE_Abort;
- }
- pSelect = sqlite3SelectNew(pParse,
- sqlite3ExprListAppend(pParse, 0, pRaise),
- sqlite3SrcListAppend(db, 0, &tFrom, 0),
- pWhere,
- 0, 0, 0, 0, 0, 0
- );
- pWhere = 0;
- }
-
- /* Disable lookaside memory allocation */
- enableLookaside = db->lookaside.bEnabled;
- db->lookaside.bEnabled = 0;
-
- pTrigger = (Trigger *)sqlite3DbMallocZero(db,
- sizeof(Trigger) + /* struct Trigger */
- sizeof(TriggerStep) + /* Single step in trigger program */
- nFrom + 1 /* Space for pStep->target.z */
- );
- if( pTrigger ){
- pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
- pStep->target.z = (char *)&pStep[1];
- pStep->target.n = nFrom;
- memcpy((char *)pStep->target.z, zFrom, nFrom);
-
- pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
- pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
- pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
- if( pWhen ){
- pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0);
- pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
- }
- }
-
- /* Re-enable the lookaside buffer, if it was disabled earlier. */
- db->lookaside.bEnabled = enableLookaside;
-
- sqlite3ExprDelete(db, pWhere);
- sqlite3ExprDelete(db, pWhen);
- sqlite3ExprListDelete(db, pList);
- sqlite3SelectDelete(db, pSelect);
- if( db->mallocFailed==1 ){
- fkTriggerDelete(db, pTrigger);
- return 0;
- }
- assert( pStep!=0 );
-
- switch( action ){
- case OE_Restrict:
- pStep->op = TK_SELECT;
- break;
- case OE_Cascade:
- if( !pChanges ){
- pStep->op = TK_DELETE;
- break;
- }
- default:
- pStep->op = TK_UPDATE;
- }
- pStep->pTrig = pTrigger;
- pTrigger->pSchema = pTab->pSchema;
- pTrigger->pTabSchema = pTab->pSchema;
- pFKey->apTrigger[iAction] = pTrigger;
- pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE);
- }
-
- return pTrigger;
-}
-
-/*
-** This function is called when deleting or updating a row to implement
-** any required CASCADE, SET NULL or SET DEFAULT actions.
-*/
-SQLITE_PRIVATE void sqlite3FkActions(
- Parse *pParse, /* Parse context */
- Table *pTab, /* Table being updated or deleted from */
- ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */
- int regOld /* Address of array containing old row */
-){
- /* If foreign-key support is enabled, iterate through all FKs that
- ** refer to table pTab. If there is an action associated with the FK
- ** for this operation (either update or delete), invoke the associated
- ** trigger sub-program. */
- if( pParse->db->flags&SQLITE_ForeignKeys ){
- FKey *pFKey; /* Iterator variable */
- for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
- Trigger *pAction = fkActionTrigger(pParse, pTab, pFKey, pChanges);
- if( pAction ){
- sqlite3CodeRowTriggerDirect(pParse, pAction, pTab, regOld, OE_Abort, 0);
- }
- }
- }
-}
-
-#endif /* ifndef SQLITE_OMIT_TRIGGER */
-
-/*
-** Free all memory associated with foreign key definitions attached to
-** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash
-** hash table.
-*/
-SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){
- FKey *pFKey; /* Iterator variable */
- FKey *pNext; /* Copy of pFKey->pNextFrom */
-
- assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
- for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){
-
- /* Remove the FK from the fkeyHash hash table. */
- if( !db || db->pnBytesFreed==0 ){
- if( pFKey->pPrevTo ){
- pFKey->pPrevTo->pNextTo = pFKey->pNextTo;
- }else{
- void *p = (void *)pFKey->pNextTo;
- const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo);
- sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, sqlite3Strlen30(z), p);
- }
- if( pFKey->pNextTo ){
- pFKey->pNextTo->pPrevTo = pFKey->pPrevTo;
- }
- }
-
- /* EV: R-30323-21917 Each foreign key constraint in SQLite is
- ** classified as either immediate or deferred.
- */
- assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 );
-
- /* Delete any triggers created to implement actions for this FK. */
-#ifndef SQLITE_OMIT_TRIGGER
- fkTriggerDelete(db, pFKey->apTrigger[0]);
- fkTriggerDelete(db, pFKey->apTrigger[1]);
-#endif
-
- pNext = pFKey->pNextFrom;
- sqlite3DbFree(db, pFKey);
- }
-}
-#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */
-
-/************** End of fkey.c ************************************************/
-/************** Begin file insert.c ******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains C code routines that are called by the parser
-** to handle INSERT statements in SQLite.
-*/
-
-/*
-** Generate code that will open a table for reading.
-*/
-SQLITE_PRIVATE void sqlite3OpenTable(
- Parse *p, /* Generate code into this VDBE */
- int iCur, /* The cursor number of the table */
- int iDb, /* The database index in sqlite3.aDb[] */
- Table *pTab, /* The table to be opened */
- int opcode /* OP_OpenRead or OP_OpenWrite */
-){
- Vdbe *v;
- assert( !IsVirtual(pTab) );
- v = sqlite3GetVdbe(p);
- assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
- sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
- sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
- VdbeComment((v, "%s", pTab->zName));
-}
-
-/*
-** Return a pointer to the column affinity string associated with index
-** pIdx. A column affinity string has one character for each column in
-** the table, according to the affinity of the column:
-**
-** Character Column affinity
-** ------------------------------
-** 'a' TEXT
-** 'b' NONE
-** 'c' NUMERIC
-** 'd' INTEGER
-** 'e' REAL
-**
-** An extra 'd' is appended to the end of the string to cover the
-** rowid that appears as the last column in every index.
-**
-** Memory for the buffer containing the column index affinity string
-** is managed along with the rest of the Index structure. It will be
-** released when sqlite3DeleteIndex() is called.
-*/
-SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
- if( !pIdx->zColAff ){
- /* The first time a column affinity string for a particular index is
- ** required, it is allocated and populated here. It is then stored as
- ** a member of the Index structure for subsequent use.
- **
- ** The column affinity string will eventually be deleted by
- ** sqliteDeleteIndex() when the Index structure itself is cleaned
- ** up.
- */
- int n;
- Table *pTab = pIdx->pTable;
- sqlite3 *db = sqlite3VdbeDb(v);
- pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2);
- if( !pIdx->zColAff ){
- db->mallocFailed = 1;
- return 0;
- }
- for(n=0; n<pIdx->nColumn; n++){
- pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
- }
- pIdx->zColAff[n++] = SQLITE_AFF_INTEGER;
- pIdx->zColAff[n] = 0;
- }
-
- return pIdx->zColAff;
-}
-
-/*
-** Set P4 of the most recently inserted opcode to a column affinity
-** string for table pTab. A column affinity string has one character
-** for each column indexed by the index, according to the affinity of the
-** column:
-**
-** Character Column affinity
-** ------------------------------
-** 'a' TEXT
-** 'b' NONE
-** 'c' NUMERIC
-** 'd' INTEGER
-** 'e' REAL
-*/
-SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
- /* The first time a column affinity string for a particular table
- ** is required, it is allocated and populated here. It is then
- ** stored as a member of the Table structure for subsequent use.
- **
- ** The column affinity string will eventually be deleted by
- ** sqlite3DeleteTable() when the Table structure itself is cleaned up.
- */
- if( !pTab->zColAff ){
- char *zColAff;
- int i;
- sqlite3 *db = sqlite3VdbeDb(v);
-
- zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
- if( !zColAff ){
- db->mallocFailed = 1;
- return;
- }
-
- for(i=0; i<pTab->nCol; i++){
- zColAff[i] = pTab->aCol[i].affinity;
- }
- zColAff[pTab->nCol] = '\0';
-
- pTab->zColAff = zColAff;
- }
-
- sqlite3VdbeChangeP4(v, -1, pTab->zColAff, P4_TRANSIENT);
-}
-
-/*
-** Return non-zero if the table pTab in database iDb or any of its indices
-** have been opened at any point in the VDBE program beginning at location
-** iStartAddr throught the end of the program. This is used to see if
-** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
-** run without using temporary table for the results of the SELECT.
-*/
-static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){
- Vdbe *v = sqlite3GetVdbe(p);
- int i;
- int iEnd = sqlite3VdbeCurrentAddr(v);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0;
-#endif
-
- for(i=iStartAddr; i<iEnd; i++){
- VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
- assert( pOp!=0 );
- if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
- Index *pIndex;
- int tnum = pOp->p2;
- if( tnum==pTab->tnum ){
- return 1;
- }
- for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){
- if( tnum==pIndex->tnum ){
- return 1;
- }
- }
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){
- assert( pOp->p4.pVtab!=0 );
- assert( pOp->p4type==P4_VTAB );
- return 1;
- }
-#endif
- }
- return 0;
-}
-
-#ifndef SQLITE_OMIT_AUTOINCREMENT
-/*
-** Locate or create an AutoincInfo structure associated with table pTab
-** which is in database iDb. Return the register number for the register
-** that holds the maximum rowid.
-**
-** There is at most one AutoincInfo structure per table even if the
-** same table is autoincremented multiple times due to inserts within
-** triggers. A new AutoincInfo structure is created if this is the
-** first use of table pTab. On 2nd and subsequent uses, the original
-** AutoincInfo structure is used.
-**
-** Three memory locations are allocated:
-**
-** (1) Register to hold the name of the pTab table.
-** (2) Register to hold the maximum ROWID of pTab.
-** (3) Register to hold the rowid in sqlite_sequence of pTab
-**
-** The 2nd register is the one that is returned. That is all the
-** insert routine needs to know about.
-*/
-static int autoIncBegin(
- Parse *pParse, /* Parsing context */
- int iDb, /* Index of the database holding pTab */
- Table *pTab /* The table we are writing to */
-){
- int memId = 0; /* Register holding maximum rowid */
- if( pTab->tabFlags & TF_Autoincrement ){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- AutoincInfo *pInfo;
-
- pInfo = pToplevel->pAinc;
- while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
- if( pInfo==0 ){
- pInfo = sqlite3DbMallocRaw(pParse->db, sizeof(*pInfo));
- if( pInfo==0 ) return 0;
- pInfo->pNext = pToplevel->pAinc;
- pToplevel->pAinc = pInfo;
- pInfo->pTab = pTab;
- pInfo->iDb = iDb;
- pToplevel->nMem++; /* Register to hold name of table */
- pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */
- pToplevel->nMem++; /* Rowid in sqlite_sequence */
- }
- memId = pInfo->regCtr;
- }
- return memId;
-}
-
-/*
-** This routine generates code that will initialize all of the
-** register used by the autoincrement tracker.
-*/
-SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
- AutoincInfo *p; /* Information about an AUTOINCREMENT */
- sqlite3 *db = pParse->db; /* The database connection */
- Db *pDb; /* Database only autoinc table */
- int memId; /* Register holding max rowid */
- int addr; /* A VDBE address */
- Vdbe *v = pParse->pVdbe; /* VDBE under construction */
-
- /* This routine is never called during trigger-generation. It is
- ** only called from the top-level */
- assert( pParse->pTriggerTab==0 );
- assert( pParse==sqlite3ParseToplevel(pParse) );
-
- assert( v ); /* We failed long ago if this is not so */
- for(p = pParse->pAinc; p; p = p->pNext){
- pDb = &db->aDb[p->iDb];
- memId = p->regCtr;
- assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
- sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
- sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
- addr = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9);
- sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
- sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
- sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
- sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
- sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
- sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
- sqlite3VdbeAddOp0(v, OP_Close);
- }
-}
-
-/*
-** Update the maximum rowid for an autoincrement calculation.
-**
-** This routine should be called when the top of the stack holds a
-** new rowid that is about to be inserted. If that new rowid is
-** larger than the maximum rowid in the memId memory cell, then the
-** memory cell is updated. The stack is unchanged.
-*/
-static void autoIncStep(Parse *pParse, int memId, int regRowid){
- if( memId>0 ){
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid);
- }
-}
-
-/*
-** This routine generates the code needed to write autoincrement
-** maximum rowid values back into the sqlite_sequence register.
-** Every statement that might do an INSERT into an autoincrement
-** table (either directly or through triggers) needs to call this
-** routine just before the "exit" code.
-*/
-SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
- AutoincInfo *p;
- Vdbe *v = pParse->pVdbe;
- sqlite3 *db = pParse->db;
-
- assert( v );
- for(p = pParse->pAinc; p; p = p->pNext){
- Db *pDb = &db->aDb[p->iDb];
- int j1, j2, j3, j4, j5;
- int iRec;
- int memId = p->regCtr;
-
- iRec = sqlite3GetTempReg(pParse);
- assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
- sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1);
- j2 = sqlite3VdbeAddOp0(v, OP_Rewind);
- j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec);
- j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec);
- sqlite3VdbeAddOp2(v, OP_Next, 0, j3);
- sqlite3VdbeJumpHere(v, j2);
- sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
- j5 = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, j4);
- sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeJumpHere(v, j5);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
- sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- sqlite3VdbeAddOp0(v, OP_Close);
- sqlite3ReleaseTempReg(pParse, iRec);
- }
-}
-#else
-/*
-** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines
-** above are all no-ops
-*/
-# define autoIncBegin(A,B,C) (0)
-# define autoIncStep(A,B,C)
-#endif /* SQLITE_OMIT_AUTOINCREMENT */
-
-
-/*
-** Generate code for a co-routine that will evaluate a subquery one
-** row at a time.
-**
-** The pSelect parameter is the subquery that the co-routine will evaluation.
-** Information about the location of co-routine and the registers it will use
-** is returned by filling in the pDest object.
-**
-** Registers are allocated as follows:
-**
-** pDest->iSDParm The register holding the next entry-point of the
-** co-routine. Run the co-routine to its next breakpoint
-** by calling "OP_Yield $X" where $X is pDest->iSDParm.
-**
-** pDest->iSDParm+1 The register holding the "completed" flag for the
-** co-routine. This register is 0 if the previous Yield
-** generated a new result row, or 1 if the subquery
-** has completed. If the Yield is called again
-** after this register becomes 1, then the VDBE will
-** halt with an SQLITE_INTERNAL error.
-**
-** pDest->iSdst First result register.
-**
-** pDest->nSdst Number of result registers.
-**
-** This routine handles all of the register allocation and fills in the
-** pDest structure appropriately.
-**
-** Here is a schematic of the generated code assuming that X is the
-** co-routine entry-point register reg[pDest->iSDParm], that EOF is the
-** completed flag reg[pDest->iSDParm+1], and R and S are the range of
-** registers that hold the result set, reg[pDest->iSdst] through
-** reg[pDest->iSdst+pDest->nSdst-1]:
-**
-** X <- A
-** EOF <- 0
-** goto B
-** A: setup for the SELECT
-** loop rows in the SELECT
-** load results into registers R..S
-** yield X
-** end loop
-** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** halt-error
-** B:
-**
-** To use this subroutine, the caller generates code as follows:
-**
-** [ Co-routine generated by this subroutine, shown above ]
-** S: yield X
-** if EOF goto E
-** if skip this row, goto C
-** if terminate loop, goto E
-** deal with this row
-** C: goto S
-** E:
-*/
-SQLITE_PRIVATE int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){
- int regYield; /* Register holding co-routine entry-point */
- int regEof; /* Register holding co-routine completion flag */
- int addrTop; /* Top of the co-routine */
- int j1; /* Jump instruction */
- int rc; /* Result code */
- Vdbe *v; /* VDBE under construction */
-
- regYield = ++pParse->nMem;
- regEof = ++pParse->nMem;
- v = sqlite3GetVdbe(pParse);
- addrTop = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_Integer, addrTop+2, regYield); /* X <- A */
- VdbeComment((v, "Co-routine entry point"));
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */
- VdbeComment((v, "Co-routine completion flag"));
- sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield);
- j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
- rc = sqlite3Select(pParse, pSelect, pDest);
- assert( pParse->nErr==0 || rc );
- if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM;
- if( rc ) return rc;
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
- sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */
- sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
- VdbeComment((v, "End of coroutine"));
- sqlite3VdbeJumpHere(v, j1); /* label B: */
- return rc;
-}
-
-
-
-/* Forward declaration */
-static int xferOptimization(
- Parse *pParse, /* Parser context */
- Table *pDest, /* The table we are inserting into */
- Select *pSelect, /* A SELECT statement to use as the data source */
- int onError, /* How to handle constraint errors */
- int iDbDest /* The database of pDest */
-);
-
-/*
-** This routine is call to handle SQL of the following forms:
-**
-** insert into TABLE (IDLIST) values(EXPRLIST)
-** insert into TABLE (IDLIST) select
-**
-** The IDLIST following the table name is always optional. If omitted,
-** then a list of all columns for the table is substituted. The IDLIST
-** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.
-**
-** The pList parameter holds EXPRLIST in the first form of the INSERT
-** statement above, and pSelect is NULL. For the second form, pList is
-** NULL and pSelect is a pointer to the select statement used to generate
-** data for the insert.
-**
-** The code generated follows one of four templates. For a simple
-** select with data coming from a VALUES clause, the code executes
-** once straight down through. Pseudo-code follows (we call this
-** the "1st template"):
-**
-** open write cursor to <table> and its indices
-** puts VALUES clause expressions onto the stack
-** write the resulting record into <table>
-** cleanup
-**
-** The three remaining templates assume the statement is of the form
-**
-** INSERT INTO <table> SELECT ...
-**
-** If the SELECT clause is of the restricted form "SELECT * FROM <table2>" -
-** in other words if the SELECT pulls all columns from a single table
-** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and
-** if <table2> and <table1> are distinct tables but have identical
-** schemas, including all the same indices, then a special optimization
-** is invoked that copies raw records from <table2> over to <table1>.
-** See the xferOptimization() function for the implementation of this
-** template. This is the 2nd template.
-**
-** open a write cursor to <table>
-** open read cursor on <table2>
-** transfer all records in <table2> over to <table>
-** close cursors
-** foreach index on <table>
-** open a write cursor on the <table> index
-** open a read cursor on the corresponding <table2> index
-** transfer all records from the read to the write cursors
-** close cursors
-** end foreach
-**
-** The 3rd template is for when the second template does not apply
-** and the SELECT clause does not read from <table> at any time.
-** The generated code follows this template:
-**
-** EOF <- 0
-** X <- A
-** goto B
-** A: setup for the SELECT
-** loop over the rows in the SELECT
-** load values into registers R..R+n
-** yield X
-** end loop
-** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** goto A
-** B: open write cursor to <table> and its indices
-** C: yield X
-** if EOF goto D
-** insert the select result into <table> from R..R+n
-** goto C
-** D: cleanup
-**
-** The 4th template is used if the insert statement takes its
-** values from a SELECT but the data is being inserted into a table
-** that is also read as part of the SELECT. In the third form,
-** we have to use a intermediate table to store the results of
-** the select. The template is like this:
-**
-** EOF <- 0
-** X <- A
-** goto B
-** A: setup for the SELECT
-** loop over the tables in the SELECT
-** load value into register R..R+n
-** yield X
-** end loop
-** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** halt-error
-** B: open temp table
-** L: yield X
-** if EOF goto M
-** insert row from R..R+n into temp table
-** goto L
-** M: open write cursor to <table> and its indices
-** rewind temp table
-** C: loop over rows of intermediate table
-** transfer values form intermediate table into <table>
-** end loop
-** D: cleanup
-*/
-SQLITE_PRIVATE void sqlite3Insert(
- Parse *pParse, /* Parser context */
- SrcList *pTabList, /* Name of table into which we are inserting */
- ExprList *pList, /* List of values to be inserted */
- Select *pSelect, /* A SELECT statement to use as the data source */
- IdList *pColumn, /* Column names corresponding to IDLIST. */
- int onError /* How to handle constraint errors */
-){
- sqlite3 *db; /* The main database structure */
- Table *pTab; /* The table to insert into. aka TABLE */
- char *zTab; /* Name of the table into which we are inserting */
- const char *zDb; /* Name of the database holding this table */
- int i, j, idx; /* Loop counters */
- Vdbe *v; /* Generate code into this virtual machine */
- Index *pIdx; /* For looping over indices of the table */
- int nColumn; /* Number of columns in the data */
- int nHidden = 0; /* Number of hidden columns if TABLE is virtual */
- int baseCur = 0; /* VDBE Cursor number for pTab */
- int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
- int endOfLoop; /* Label for the end of the insertion loop */
- int useTempTable = 0; /* Store SELECT results in intermediate table */
- int srcTab = 0; /* Data comes from this temporary cursor if >=0 */
- int addrInsTop = 0; /* Jump to label "D" */
- int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */
- int addrSelect = 0; /* Address of coroutine that implements the SELECT */
- SelectDest dest; /* Destination for SELECT on rhs of INSERT */
- int iDb; /* Index of database holding TABLE */
- Db *pDb; /* The database containing table being inserted into */
- int appendFlag = 0; /* True if the insert is likely to be an append */
-
- /* Register allocations */
- int regFromSelect = 0;/* Base register for data coming from SELECT */
- int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */
- int regRowCount = 0; /* Memory cell used for the row counter */
- int regIns; /* Block of regs holding rowid+data being inserted */
- int regRowid; /* registers holding insert rowid */
- int regData; /* register holding first column to insert */
- int regEof = 0; /* Register recording end of SELECT data */
- int *aRegIdx = 0; /* One register allocated to each index */
-
-#ifndef SQLITE_OMIT_TRIGGER
- int isView; /* True if attempting to insert into a view */
- Trigger *pTrigger; /* List of triggers on pTab, if required */
- int tmask; /* Mask of trigger times */
-#endif
-
- db = pParse->db;
- memset(&dest, 0, sizeof(dest));
- if( pParse->nErr || db->mallocFailed ){
- goto insert_cleanup;
- }
-
- /* Locate the table into which we will be inserting new information.
- */
- assert( pTabList->nSrc==1 );
- zTab = pTabList->a[0].zName;
- if( NEVER(zTab==0) ) goto insert_cleanup;
- pTab = sqlite3SrcListLookup(pParse, pTabList);
- if( pTab==0 ){
- goto insert_cleanup;
- }
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- assert( iDb<db->nDb );
- pDb = &db->aDb[iDb];
- zDb = pDb->zName;
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
- goto insert_cleanup;
- }
-
- /* Figure out if we have any triggers and if the table being
- ** inserted into is a view
- */
-#ifndef SQLITE_OMIT_TRIGGER
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask);
- isView = pTab->pSelect!=0;
-#else
-# define pTrigger 0
-# define tmask 0
-# define isView 0
-#endif
-#ifdef SQLITE_OMIT_VIEW
-# undef isView
-# define isView 0
-#endif
- assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
-
- /* If pTab is really a view, make sure it has been initialized.
- ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual
- ** module table).
- */
- if( sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto insert_cleanup;
- }
-
- /* Ensure that:
- * (a) the table is not read-only,
- * (b) that if it is a view then ON INSERT triggers exist
- */
- if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
- goto insert_cleanup;
- }
-
- /* Allocate a VDBE
- */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto insert_cleanup;
- if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb);
-
-#ifndef SQLITE_OMIT_XFER_OPT
- /* If the statement is of the form
- **
- ** INSERT INTO <table1> SELECT * FROM <table2>;
- **
- ** Then special optimizations can be applied that make the transfer
- ** very fast and which reduce fragmentation of indices.
- **
- ** This is the 2nd template.
- */
- if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
- assert( !pTrigger );
- assert( pList==0 );
- goto insert_end;
- }
-#endif /* SQLITE_OMIT_XFER_OPT */
-
- /* If this is an AUTOINCREMENT table, look up the sequence number in the
- ** sqlite_sequence table and store it in memory cell regAutoinc.
- */
- regAutoinc = autoIncBegin(pParse, iDb, pTab);
-
- /* Figure out how many columns of data are supplied. If the data
- ** is coming from a SELECT statement, then generate a co-routine that
- ** produces a single row of the SELECT on each invocation. The
- ** co-routine is the common header to the 3rd and 4th templates.
- */
- if( pSelect ){
- /* Data is coming from a SELECT. Generate a co-routine to run that
- ** SELECT. */
- int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest);
- if( rc ) goto insert_cleanup;
-
- regEof = dest.iSDParm + 1;
- regFromSelect = dest.iSdst;
- assert( pSelect->pEList );
- nColumn = pSelect->pEList->nExpr;
- assert( dest.nSdst==nColumn );
-
- /* Set useTempTable to TRUE if the result of the SELECT statement
- ** should be written into a temporary table (template 4). Set to
- ** FALSE if each* row of the SELECT can be written directly into
- ** the destination table (template 3).
- **
- ** A temp table must be used if the table being updated is also one
- ** of the tables being read by the SELECT statement. Also use a
- ** temp table in the case of row triggers.
- */
- if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){
- useTempTable = 1;
- }
-
- if( useTempTable ){
- /* Invoke the coroutine to extract information from the SELECT
- ** and add it to a transient table srcTab. The code generated
- ** here is from the 4th template:
- **
- ** B: open temp table
- ** L: yield X
- ** if EOF goto M
- ** insert row from R..R+n into temp table
- ** goto L
- ** M: ...
- */
- int regRec; /* Register to hold packed record */
- int regTempRowid; /* Register to hold temp table ROWID */
- int addrTop; /* Label "L" */
- int addrIf; /* Address of jump to M */
-
- srcTab = pParse->nTab++;
- regRec = sqlite3GetTempReg(pParse);
- regTempRowid = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
- addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
- addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
- sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
- sqlite3VdbeJumpHere(v, addrIf);
- sqlite3ReleaseTempReg(pParse, regRec);
- sqlite3ReleaseTempReg(pParse, regTempRowid);
- }
- }else{
- /* This is the case if the data for the INSERT is coming from a VALUES
- ** clause
- */
- NameContext sNC;
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- srcTab = -1;
- assert( useTempTable==0 );
- nColumn = pList ? pList->nExpr : 0;
- for(i=0; i<nColumn; i++){
- if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
- goto insert_cleanup;
- }
- }
- }
-
- /* Make sure the number of columns in the source data matches the number
- ** of columns to be inserted into the table.
- */
- if( IsVirtual(pTab) ){
- for(i=0; i<pTab->nCol; i++){
- nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0);
- }
- }
- if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){
- sqlite3ErrorMsg(pParse,
- "table %S has %d columns but %d values were supplied",
- pTabList, 0, pTab->nCol-nHidden, nColumn);
- goto insert_cleanup;
- }
- if( pColumn!=0 && nColumn!=pColumn->nId ){
- sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
- goto insert_cleanup;
- }
-
- /* If the INSERT statement included an IDLIST term, then make sure
- ** all elements of the IDLIST really are columns of the table and
- ** remember the column indices.
- **
- ** If the table has an INTEGER PRIMARY KEY column and that column
- ** is named in the IDLIST, then record in the keyColumn variable
- ** the index into IDLIST of the primary key column. keyColumn is
- ** the index of the primary key as it appears in IDLIST, not as
- ** is appears in the original table. (The index of the primary
- ** key in the original table is pTab->iPKey.)
- */
- if( pColumn ){
- for(i=0; i<pColumn->nId; i++){
- pColumn->a[i].idx = -1;
- }
- for(i=0; i<pColumn->nId; i++){
- for(j=0; j<pTab->nCol; j++){
- if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
- pColumn->a[i].idx = j;
- if( j==pTab->iPKey ){
- keyColumn = i;
- }
- break;
- }
- }
- if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pColumn->a[i].zName) ){
- keyColumn = i;
- }else{
- sqlite3ErrorMsg(pParse, "table %S has no column named %s",
- pTabList, 0, pColumn->a[i].zName);
- pParse->checkSchema = 1;
- goto insert_cleanup;
- }
- }
- }
- }
-
- /* If there is no IDLIST term but the table has an integer primary
- ** key, the set the keyColumn variable to the primary key column index
- ** in the original table definition.
- */
- if( pColumn==0 && nColumn>0 ){
- keyColumn = pTab->iPKey;
- }
-
- /* Initialize the count of rows to be inserted
- */
- if( db->flags & SQLITE_CountRows ){
- regRowCount = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
- }
-
- /* If this is not a view, open the table and and all indices */
- if( !isView ){
- int nIdx;
-
- baseCur = pParse->nTab;
- nIdx = sqlite3OpenTableAndIndices(pParse, pTab, baseCur, OP_OpenWrite);
- aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
- if( aRegIdx==0 ){
- goto insert_cleanup;
- }
- for(i=0; i<nIdx; i++){
- aRegIdx[i] = ++pParse->nMem;
- }
- }
-
- /* This is the top of the main insertion loop */
- if( useTempTable ){
- /* This block codes the top of loop only. The complete loop is the
- ** following pseudocode (template 4):
- **
- ** rewind temp table
- ** C: loop over rows of intermediate table
- ** transfer values form intermediate table into <table>
- ** end loop
- ** D: ...
- */
- addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab);
- addrCont = sqlite3VdbeCurrentAddr(v);
- }else if( pSelect ){
- /* This block codes the top of loop only. The complete loop is the
- ** following pseudocode (template 3):
- **
- ** C: yield X
- ** if EOF goto D
- ** insert the select result into <table> from R..R+n
- ** goto C
- ** D: ...
- */
- addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
- addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
- }
-
- /* Allocate registers for holding the rowid of the new row,
- ** the content of the new row, and the assemblied row record.
- */
- regRowid = regIns = pParse->nMem+1;
- pParse->nMem += pTab->nCol + 1;
- if( IsVirtual(pTab) ){
- regRowid++;
- pParse->nMem++;
- }
- regData = regRowid+1;
-
- /* Run the BEFORE and INSTEAD OF triggers, if there are any
- */
- endOfLoop = sqlite3VdbeMakeLabel(v);
- if( tmask & TRIGGER_BEFORE ){
- int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);
-
- /* build the NEW.* reference row. Note that if there is an INTEGER
- ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
- ** translated into a unique ID for the row. But on a BEFORE trigger,
- ** we do not know what the unique ID will be (because the insert has
- ** not happened yet) so we substitute a rowid of -1
- */
- if( keyColumn<0 ){
- sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
- }else{
- int j1;
- if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regCols);
- }else{
- assert( pSelect==0 ); /* Otherwise useTempTable is true */
- sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regCols);
- }
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols);
- }
-
- /* Cannot have triggers on a virtual table. If it were possible,
- ** this block would have to account for hidden column.
- */
- assert( !IsVirtual(pTab) );
-
- /* Create the new column data
- */
- for(i=0; i<pTab->nCol; i++){
- if( pColumn==0 ){
- j = i;
- }else{
- for(j=0; j<pColumn->nId; j++){
- if( pColumn->a[j].idx==i ) break;
- }
- }
- if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) ){
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
- }else if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1);
- }else{
- assert( pSelect==0 ); /* Otherwise useTempTable is true */
- sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1);
- }
- }
-
- /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
- ** do not attempt any conversions before assembling the record.
- ** If this is a real table, attempt conversions as required by the
- ** table column affinities.
- */
- if( !isView ){
- sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol);
- sqlite3TableAffinityStr(v, pTab);
- }
-
- /* Fire BEFORE or INSTEAD OF triggers */
- sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE,
- pTab, regCols-pTab->nCol-1, onError, endOfLoop);
-
- sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
- }
-
- /* Push the record number for the new entry onto the stack. The
- ** record number is a randomly generate integer created by NewRowid
- ** except when the table has an INTEGER PRIMARY KEY column, in which
- ** case the record number is the same as that column.
- */
- if( !isView ){
- if( IsVirtual(pTab) ){
- /* The row that the VUpdate opcode will delete: none */
- sqlite3VdbeAddOp2(v, OP_Null, 0, regIns);
- }
- if( keyColumn>=0 ){
- if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid);
- }else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+keyColumn, regRowid);
- }else{
- VdbeOp *pOp;
- sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
- pOp = sqlite3VdbeGetOp(v, -1);
- if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
- appendFlag = 1;
- pOp->opcode = OP_NewRowid;
- pOp->p1 = baseCur;
- pOp->p2 = regRowid;
- pOp->p3 = regAutoinc;
- }
- }
- /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
- ** to generate a unique primary key value.
- */
- if( !appendFlag ){
- int j1;
- if( !IsVirtual(pTab) ){
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
- sqlite3VdbeJumpHere(v, j1);
- }else{
- j1 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2);
- }
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
- }
- }else if( IsVirtual(pTab) ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
- }else{
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
- appendFlag = 1;
- }
- autoIncStep(pParse, regAutoinc, regRowid);
-
- /* Push onto the stack, data for all columns of the new entry, beginning
- ** with the first column.
- */
- nHidden = 0;
- for(i=0; i<pTab->nCol; i++){
- int iRegStore = regRowid+1+i;
- if( i==pTab->iPKey ){
- /* The value of the INTEGER PRIMARY KEY column is always a NULL.
- ** Whenever this column is read, the record number will be substituted
- ** in its place. So will fill this column with a NULL to avoid
- ** taking up data space with information that will never be used. */
- sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore);
- continue;
- }
- if( pColumn==0 ){
- if( IsHiddenColumn(&pTab->aCol[i]) ){
- assert( IsVirtual(pTab) );
- j = -1;
- nHidden++;
- }else{
- j = i - nHidden;
- }
- }else{
- for(j=0; j<pColumn->nId; j++){
- if( pColumn->a[j].idx==i ) break;
- }
- }
- if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore);
- }else if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
- }else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
- }else{
- sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
- }
- }
-
- /* Generate code to check constraints and generate index keys and
- ** do the insertion.
- */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(pTab) ){
- const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
- sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB);
- sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
- sqlite3MayAbort(pParse);
- }else
-#endif
- {
- int isReplace; /* Set to true if constraints may cause a replace */
- sqlite3GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx,
- keyColumn>=0, 0, onError, endOfLoop, &isReplace
- );
- sqlite3FkCheck(pParse, pTab, 0, regIns);
- sqlite3CompleteInsertion(
- pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0
- );
- }
- }
-
- /* Update the count of rows that are inserted
- */
- if( (db->flags & SQLITE_CountRows)!=0 ){
- sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
- }
-
- if( pTrigger ){
- /* Code AFTER triggers */
- sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER,
- pTab, regData-2-pTab->nCol, onError, endOfLoop);
- }
-
- /* The bottom of the main insertion loop, if the data source
- ** is a SELECT statement.
- */
- sqlite3VdbeResolveLabel(v, endOfLoop);
- if( useTempTable ){
- sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont);
- sqlite3VdbeJumpHere(v, addrInsTop);
- sqlite3VdbeAddOp1(v, OP_Close, srcTab);
- }else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrCont);
- sqlite3VdbeJumpHere(v, addrInsTop);
- }
-
- if( !IsVirtual(pTab) && !isView ){
- /* Close all tables opened */
- sqlite3VdbeAddOp1(v, OP_Close, baseCur);
- for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
- sqlite3VdbeAddOp1(v, OP_Close, idx+baseCur);
- }
- }
-
-insert_end:
- /* Update the sqlite_sequence table by storing the content of the
- ** maximum rowid counter values recorded while inserting into
- ** autoincrement tables.
- */
- if( pParse->nested==0 && pParse->pTriggerTab==0 ){
- sqlite3AutoincrementEnd(pParse);
- }
-
- /*
- ** Return the number of rows inserted. If this routine is
- ** generating code because of a call to sqlite3NestedParse(), do not
- ** invoke the callback function.
- */
- if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){
- sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
- }
-
-insert_cleanup:
- sqlite3SrcListDelete(db, pTabList);
- sqlite3ExprListDelete(db, pList);
- sqlite3SelectDelete(db, pSelect);
- sqlite3IdListDelete(db, pColumn);
- sqlite3DbFree(db, aRegIdx);
-}
-
-/* Make sure "isView" and other macros defined above are undefined. Otherwise
-** thely may interfere with compilation of other functions in this file
-** (or in another file, if this file becomes part of the amalgamation). */
-#ifdef isView
- #undef isView
-#endif
-#ifdef pTrigger
- #undef pTrigger
-#endif
-#ifdef tmask
- #undef tmask
-#endif
-
-
-/*
-** Generate code to do constraint checks prior to an INSERT or an UPDATE.
-**
-** The input is a range of consecutive registers as follows:
-**
-** 1. The rowid of the row after the update.
-**
-** 2. The data in the first column of the entry after the update.
-**
-** i. Data from middle columns...
-**
-** N. The data in the last column of the entry after the update.
-**
-** The regRowid parameter is the index of the register containing (1).
-**
-** If isUpdate is true and rowidChng is non-zero, then rowidChng contains
-** the address of a register containing the rowid before the update takes
-** place. isUpdate is true for UPDATEs and false for INSERTs. If isUpdate
-** is false, indicating an INSERT statement, then a non-zero rowidChng
-** indicates that the rowid was explicitly specified as part of the
-** INSERT statement. If rowidChng is false, it means that the rowid is
-** computed automatically in an insert or that the rowid value is not
-** modified by an update.
-**
-** The code generated by this routine store new index entries into
-** registers identified by aRegIdx[]. No index entry is created for
-** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
-** the same as the order of indices on the linked list of indices
-** attached to the table.
-**
-** This routine also generates code to check constraints. NOT NULL,
-** CHECK, and UNIQUE constraints are all checked. If a constraint fails,
-** then the appropriate action is performed. There are five possible
-** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE.
-**
-** Constraint type Action What Happens
-** --------------- ---------- ----------------------------------------
-** any ROLLBACK The current transaction is rolled back and
-** sqlite3_exec() returns immediately with a
-** return code of SQLITE_CONSTRAINT.
-**
-** any ABORT Back out changes from the current command
-** only (do not do a complete rollback) then
-** cause sqlite3_exec() to return immediately
-** with SQLITE_CONSTRAINT.
-**
-** any FAIL Sqlite3_exec() returns immediately with a
-** return code of SQLITE_CONSTRAINT. The
-** transaction is not rolled back and any
-** prior changes are retained.
-**
-** any IGNORE The record number and data is popped from
-** the stack and there is an immediate jump
-** to label ignoreDest.
-**
-** NOT NULL REPLACE The NULL value is replace by the default
-** value for that column. If the default value
-** is NULL, the action is the same as ABORT.
-**
-** UNIQUE REPLACE The other row that conflicts with the row
-** being inserted is removed.
-**
-** CHECK REPLACE Illegal. The results in an exception.
-**
-** Which action to take is determined by the overrideError parameter.
-** Or if overrideError==OE_Default, then the pParse->onError parameter
-** is used. Or if pParse->onError==OE_Default then the onError value
-** for the constraint is used.
-**
-** The calling routine must open a read/write cursor for pTab with
-** cursor number "baseCur". All indices of pTab must also have open
-** read/write cursors with cursor number baseCur+i for the i-th cursor.
-** Except, if there is no possibility of a REPLACE action then
-** cursors do not need to be open for indices where aRegIdx[i]==0.
-*/
-SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
- Parse *pParse, /* The parser context */
- Table *pTab, /* the table into which we are inserting */
- int baseCur, /* Index of a read/write cursor pointing at pTab */
- int regRowid, /* Index of the range of input registers */
- int *aRegIdx, /* Register used by each index. 0 for unused indices */
- int rowidChng, /* True if the rowid might collide with existing entry */
- int isUpdate, /* True for UPDATE, False for INSERT */
- int overrideError, /* Override onError to this if not OE_Default */
- int ignoreDest, /* Jump to this label on an OE_Ignore resolution */
- int *pbMayReplace /* OUT: Set to true if constraint may cause a replace */
-){
- int i; /* loop counter */
- Vdbe *v; /* VDBE under constrution */
- int nCol; /* Number of columns */
- int onError; /* Conflict resolution strategy */
- int j1; /* Addresss of jump instruction */
- int j2 = 0, j3; /* Addresses of jump instructions */
- int regData; /* Register containing first data column */
- int iCur; /* Table cursor number */
- Index *pIdx; /* Pointer to one of the indices */
- sqlite3 *db; /* Database connection */
- int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
- int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid;
-
- db = pParse->db;
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 );
- assert( pTab->pSelect==0 ); /* This table is not a VIEW */
- nCol = pTab->nCol;
- regData = regRowid + 1;
-
- /* Test all NOT NULL constraints.
- */
- for(i=0; i<nCol; i++){
- if( i==pTab->iPKey ){
- continue;
- }
- onError = pTab->aCol[i].notNull;
- if( onError==OE_None ) continue;
- if( overrideError!=OE_Default ){
- onError = overrideError;
- }else if( onError==OE_Default ){
- onError = OE_Abort;
- }
- if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
- onError = OE_Abort;
- }
- assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
- || onError==OE_Ignore || onError==OE_Replace );
- switch( onError ){
- case OE_Abort:
- sqlite3MayAbort(pParse);
- case OE_Rollback:
- case OE_Fail: {
- char *zMsg;
- sqlite3VdbeAddOp3(v, OP_HaltIfNull,
- SQLITE_CONSTRAINT, onError, regData+i);
- zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
- pTab->zName, pTab->aCol[i].zName);
- sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
- break;
- }
- case OE_Ignore: {
- sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest);
- break;
- }
- default: {
- assert( onError==OE_Replace );
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i);
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i);
- sqlite3VdbeJumpHere(v, j1);
- break;
- }
- }
- }
-
- /* Test all CHECK constraints
- */
-#ifndef SQLITE_OMIT_CHECK
- if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
- ExprList *pCheck = pTab->pCheck;
- pParse->ckBase = regData;
- onError = overrideError!=OE_Default ? overrideError : OE_Abort;
- for(i=0; i<pCheck->nExpr; i++){
- int allOk = sqlite3VdbeMakeLabel(v);
- sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
- if( onError==OE_Ignore ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
- }else{
- char *zConsName = pCheck->a[i].zName;
- if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
- if( zConsName ){
- zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
- }else{
- zConsName = 0;
- }
- sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
- }
- sqlite3VdbeResolveLabel(v, allOk);
- }
- }
-#endif /* !defined(SQLITE_OMIT_CHECK) */
-
- /* If we have an INTEGER PRIMARY KEY, make sure the primary key
- ** of the new record does not previously exist. Except, if this
- ** is an UPDATE and the primary key is not changing, that is OK.
- */
- if( rowidChng ){
- onError = pTab->keyConf;
- if( overrideError!=OE_Default ){
- onError = overrideError;
- }else if( onError==OE_Default ){
- onError = OE_Abort;
- }
-
- if( isUpdate ){
- j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng);
- }
- j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
- switch( onError ){
- default: {
- onError = OE_Abort;
- /* Fall thru into the next case */
- }
- case OE_Rollback:
- case OE_Abort:
- case OE_Fail: {
- sqlite3HaltConstraint(
- pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
- break;
- }
- case OE_Replace: {
- /* If there are DELETE triggers on this table and the
- ** recursive-triggers flag is set, call GenerateRowDelete() to
- ** remove the conflicting row from the table. This will fire
- ** the triggers and remove both the table and index b-tree entries.
- **
- ** Otherwise, if there are no triggers or the recursive-triggers
- ** flag is not set, but the table has one or more indexes, call
- ** GenerateRowIndexDelete(). This removes the index b-tree entries
- ** only. The table b-tree entry will be replaced by the new entry
- ** when it is inserted.
- **
- ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called,
- ** also invoke MultiWrite() to indicate that this VDBE may require
- ** statement rollback (if the statement is aborted after the delete
- ** takes place). Earlier versions called sqlite3MultiWrite() regardless,
- ** but being more selective here allows statements like:
- **
- ** REPLACE INTO t(rowid) VALUES($newrowid)
- **
- ** to run without a statement journal if there are no indexes on the
- ** table.
- */
- Trigger *pTrigger = 0;
- if( db->flags&SQLITE_RecTriggers ){
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
- }
- if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
- sqlite3MultiWrite(pParse);
- sqlite3GenerateRowDelete(
- pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace
- );
- }else if( pTab->pIndex ){
- sqlite3MultiWrite(pParse);
- sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
- }
- seenReplace = 1;
- break;
- }
- case OE_Ignore: {
- assert( seenReplace==0 );
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
- break;
- }
- }
- sqlite3VdbeJumpHere(v, j3);
- if( isUpdate ){
- sqlite3VdbeJumpHere(v, j2);
- }
- }
-
- /* Test all UNIQUE constraints by creating entries for each UNIQUE
- ** index and making sure that duplicate entries do not already exist.
- ** Add the new records to the indices as we go.
- */
- for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
- int regIdx;
- int regR;
-
- if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
-
- /* Create a key for accessing the index entry */
- regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
- for(i=0; i<pIdx->nColumn; i++){
- int idx = pIdx->aiColumn[i];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
- }else{
- sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
- }
- }
- sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
- sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
- sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
-
- /* Find out what action to take in case there is an indexing conflict */
- onError = pIdx->onError;
- if( onError==OE_None ){
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
- continue; /* pIdx is not a UNIQUE index */
- }
- if( overrideError!=OE_Default ){
- onError = overrideError;
- }else if( onError==OE_Default ){
- onError = OE_Abort;
- }
- if( seenReplace ){
- if( onError==OE_Ignore ) onError = OE_Replace;
- else if( onError==OE_Fail ) onError = OE_Abort;
- }
-
- /* Check to see if the new index entry will be unique */
- regR = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR);
- j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,
- regR, SQLITE_INT_TO_PTR(regIdx),
- P4_INT32);
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
-
- /* Generate code that executes if the new index entry is not unique */
- assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
- || onError==OE_Ignore || onError==OE_Replace );
- switch( onError ){
- case OE_Rollback:
- case OE_Abort:
- case OE_Fail: {
- int j;
- StrAccum errMsg;
- const char *zSep;
- char *zErr;
-
- sqlite3StrAccumInit(&errMsg, 0, 0, 200);
- errMsg.db = db;
- zSep = pIdx->nColumn>1 ? "columns " : "column ";
- for(j=0; j<pIdx->nColumn; j++){
- char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
- sqlite3StrAccumAppend(&errMsg, zSep, -1);
- zSep = ", ";
- sqlite3StrAccumAppend(&errMsg, zCol, -1);
- }
- sqlite3StrAccumAppend(&errMsg,
- pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
- zErr = sqlite3StrAccumFinish(&errMsg);
- sqlite3HaltConstraint(pParse, onError, zErr, 0);
- sqlite3DbFree(errMsg.db, zErr);
- break;
- }
- case OE_Ignore: {
- assert( seenReplace==0 );
- sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
- break;
- }
- default: {
- Trigger *pTrigger = 0;
- assert( onError==OE_Replace );
- sqlite3MultiWrite(pParse);
- if( db->flags&SQLITE_RecTriggers ){
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
- }
- sqlite3GenerateRowDelete(
- pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
- );
- seenReplace = 1;
- break;
- }
- }
- sqlite3VdbeJumpHere(v, j3);
- sqlite3ReleaseTempReg(pParse, regR);
- }
-
- if( pbMayReplace ){
- *pbMayReplace = seenReplace;
- }
-}
-
-/*
-** This routine generates code to finish the INSERT or UPDATE operation
-** that was started by a prior call to sqlite3GenerateConstraintChecks.
-** A consecutive range of registers starting at regRowid contains the
-** rowid and the content to be inserted.
-**
-** The arguments to this routine should be the same as the first six
-** arguments to sqlite3GenerateConstraintChecks.
-*/
-SQLITE_PRIVATE void sqlite3CompleteInsertion(
- Parse *pParse, /* The parser context */
- Table *pTab, /* the table into which we are inserting */
- int baseCur, /* Index of a read/write cursor pointing at pTab */
- int regRowid, /* Range of content */
- int *aRegIdx, /* Register used by each index. 0 for unused indices */
- int isUpdate, /* True for UPDATE, False for INSERT */
- int appendBias, /* True if this is likely to be an append */
- int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
-){
- int i;
- Vdbe *v;
- int nIdx;
- Index *pIdx;
- u8 pik_flags;
- int regData;
- int regRec;
-
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 );
- assert( pTab->pSelect==0 ); /* This table is not a VIEW */
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
- for(i=nIdx-1; i>=0; i--){
- if( aRegIdx[i]==0 ) continue;
- sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
- if( useSeekResult ){
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
- }
- }
- regData = regRowid + 1;
- regRec = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
- sqlite3TableAffinityStr(v, pTab);
- sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
- if( pParse->nested ){
- pik_flags = 0;
- }else{
- pik_flags = OPFLAG_NCHANGE;
- pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
- }
- if( appendBias ){
- pik_flags |= OPFLAG_APPEND;
- }
- if( useSeekResult ){
- pik_flags |= OPFLAG_USESEEKRESULT;
- }
- sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid);
- if( !pParse->nested ){
- sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
- }
- sqlite3VdbeChangeP5(v, pik_flags);
-}
-
-/*
-** Generate code that will open cursors for a table and for all
-** indices of that table. The "baseCur" parameter is the cursor number used
-** for the table. Indices are opened on subsequent cursors.
-**
-** Return the number of indices on the table.
-*/
-SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
- Parse *pParse, /* Parsing context */
- Table *pTab, /* Table to be opened */
- int baseCur, /* Cursor number assigned to the table */
- int op /* OP_OpenRead or OP_OpenWrite */
-){
- int i;
- int iDb;
- Index *pIdx;
- Vdbe *v;
-
- if( IsVirtual(pTab) ) return 0;
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 );
- sqlite3OpenTable(pParse, baseCur, iDb, pTab, op);
- for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
- assert( pIdx->pSchema==pTab->pSchema );
- sqlite3VdbeAddOp4(v, op, i+baseCur, pIdx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIdx->zName));
- }
- if( pParse->nTab<baseCur+i ){
- pParse->nTab = baseCur+i;
- }
- return i-1;
-}
-
-
-#ifdef SQLITE_TEST
-/*
-** The following global variable is incremented whenever the
-** transfer optimization is used. This is used for testing
-** purposes only - to make sure the transfer optimization really
-** is happening when it is suppose to.
-*/
-SQLITE_API int sqlite3_xferopt_count;
-#endif /* SQLITE_TEST */
-
-
-#ifndef SQLITE_OMIT_XFER_OPT
-/*
-** Check to collation names to see if they are compatible.
-*/
-static int xferCompatibleCollation(const char *z1, const char *z2){
- if( z1==0 ){
- return z2==0;
- }
- if( z2==0 ){
- return 0;
- }
- return sqlite3StrICmp(z1, z2)==0;
-}
-
-
-/*
-** Check to see if index pSrc is compatible as a source of data
-** for index pDest in an insert transfer optimization. The rules
-** for a compatible index:
-**
-** * The index is over the same set of columns
-** * The same DESC and ASC markings occurs on all columns
-** * The same onError processing (OE_Abort, OE_Ignore, etc)
-** * The same collating sequence on each column
-*/
-static int xferCompatibleIndex(Index *pDest, Index *pSrc){
- int i;
- assert( pDest && pSrc );
- assert( pDest->pTable!=pSrc->pTable );
- if( pDest->nColumn!=pSrc->nColumn ){
- return 0; /* Different number of columns */
- }
- if( pDest->onError!=pSrc->onError ){
- return 0; /* Different conflict resolution strategies */
- }
- for(i=0; i<pSrc->nColumn; i++){
- if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
- return 0; /* Different columns indexed */
- }
- if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
- return 0; /* Different sort orders */
- }
- if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
- return 0; /* Different collating sequences */
- }
- }
-
- /* If no test above fails then the indices must be compatible */
- return 1;
-}
-
-/*
-** Attempt the transfer optimization on INSERTs of the form
-**
-** INSERT INTO tab1 SELECT * FROM tab2;
-**
-** The xfer optimization transfers raw records from tab2 over to tab1.
-** Columns are not decoded and reassemblied, which greatly improves
-** performance. Raw index records are transferred in the same way.
-**
-** The xfer optimization is only attempted if tab1 and tab2 are compatible.
-** There are lots of rules for determining compatibility - see comments
-** embedded in the code for details.
-**
-** This routine returns TRUE if the optimization is guaranteed to be used.
-** Sometimes the xfer optimization will only work if the destination table
-** is empty - a factor that can only be determined at run-time. In that
-** case, this routine generates code for the xfer optimization but also
-** does a test to see if the destination table is empty and jumps over the
-** xfer optimization code if the test fails. In that case, this routine
-** returns FALSE so that the caller will know to go ahead and generate
-** an unoptimized transfer. This routine also returns FALSE if there
-** is no chance that the xfer optimization can be applied.
-**
-** This optimization is particularly useful at making VACUUM run faster.
-*/
-static int xferOptimization(
- Parse *pParse, /* Parser context */
- Table *pDest, /* The table we are inserting into */
- Select *pSelect, /* A SELECT statement to use as the data source */
- int onError, /* How to handle constraint errors */
- int iDbDest /* The database of pDest */
-){
- ExprList *pEList; /* The result set of the SELECT */
- Table *pSrc; /* The table in the FROM clause of SELECT */
- Index *pSrcIdx, *pDestIdx; /* Source and destination indices */
- struct SrcList_item *pItem; /* An element of pSelect->pSrc */
- int i; /* Loop counter */
- int iDbSrc; /* The database of pSrc */
- int iSrc, iDest; /* Cursors from source and destination */
- int addr1, addr2; /* Loop addresses */
- int emptyDestTest; /* Address of test for empty pDest */
- int emptySrcTest; /* Address of test for empty pSrc */
- Vdbe *v; /* The VDBE we are building */
- KeyInfo *pKey; /* Key information for an index */
- int regAutoinc; /* Memory register used by AUTOINC */
- int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
- int regData, regRowid; /* Registers holding data and rowid */
-
- if( pSelect==0 ){
- return 0; /* Must be of the form INSERT INTO ... SELECT ... */
- }
- if( sqlite3TriggerList(pParse, pDest) ){
- return 0; /* tab1 must not have triggers */
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pDest->tabFlags & TF_Virtual ){
- return 0; /* tab1 must not be a virtual table */
- }
-#endif
- if( onError==OE_Default ){
- if( pDest->iPKey>=0 ) onError = pDest->keyConf;
- if( onError==OE_Default ) onError = OE_Abort;
- }
- assert(pSelect->pSrc); /* allocated even if there is no FROM clause */
- if( pSelect->pSrc->nSrc!=1 ){
- return 0; /* FROM clause must have exactly one term */
- }
- if( pSelect->pSrc->a[0].pSelect ){
- return 0; /* FROM clause cannot contain a subquery */
- }
- if( pSelect->pWhere ){
- return 0; /* SELECT may not have a WHERE clause */
- }
- if( pSelect->pOrderBy ){
- return 0; /* SELECT may not have an ORDER BY clause */
- }
- /* Do not need to test for a HAVING clause. If HAVING is present but
- ** there is no ORDER BY, we will get an error. */
- if( pSelect->pGroupBy ){
- return 0; /* SELECT may not have a GROUP BY clause */
- }
- if( pSelect->pLimit ){
- return 0; /* SELECT may not have a LIMIT clause */
- }
- assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */
- if( pSelect->pPrior ){
- return 0; /* SELECT may not be a compound query */
- }
- if( pSelect->selFlags & SF_Distinct ){
- return 0; /* SELECT may not be DISTINCT */
- }
- pEList = pSelect->pEList;
- assert( pEList!=0 );
- if( pEList->nExpr!=1 ){
- return 0; /* The result set must have exactly one column */
- }
- assert( pEList->a[0].pExpr );
- if( pEList->a[0].pExpr->op!=TK_ALL ){
- return 0; /* The result set must be the special operator "*" */
- }
-
- /* At this point we have established that the statement is of the
- ** correct syntactic form to participate in this optimization. Now
- ** we have to check the semantics.
- */
- pItem = pSelect->pSrc->a;
- pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
- if( pSrc==0 ){
- return 0; /* FROM clause does not contain a real table */
- }
- if( pSrc==pDest ){
- return 0; /* tab1 and tab2 may not be the same table */
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pSrc->tabFlags & TF_Virtual ){
- return 0; /* tab2 must not be a virtual table */
- }
-#endif
- if( pSrc->pSelect ){
- return 0; /* tab2 may not be a view */
- }
- if( pDest->nCol!=pSrc->nCol ){
- return 0; /* Number of columns must be the same in tab1 and tab2 */
- }
- if( pDest->iPKey!=pSrc->iPKey ){
- return 0; /* Both tables must have the same INTEGER PRIMARY KEY */
- }
- for(i=0; i<pDest->nCol; i++){
- if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){
- return 0; /* Affinity must be the same on all columns */
- }
- if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){
- return 0; /* Collating sequence must be the same on all columns */
- }
- if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){
- return 0; /* tab2 must be NOT NULL if tab1 is */
- }
- }
- for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
- if( pDestIdx->onError!=OE_None ){
- destHasUniqueIdx = 1;
- }
- for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
- if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
- }
- if( pSrcIdx==0 ){
- return 0; /* pDestIdx has no corresponding index in pSrc */
- }
- }
-#ifndef SQLITE_OMIT_CHECK
- if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){
- return 0; /* Tables have different CHECK constraints. Ticket #2252 */
- }
-#endif
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- /* Disallow the transfer optimization if the destination table constains
- ** any foreign key constraints. This is more restrictive than necessary.
- ** But the main beneficiary of the transfer optimization is the VACUUM
- ** command, and the VACUUM command disables foreign key constraints. So
- ** the extra complication to make this rule less restrictive is probably
- ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
- */
- if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
- return 0;
- }
-#endif
- if( (pParse->db->flags & SQLITE_CountRows)!=0 ){
- return 0; /* xfer opt does not play well with PRAGMA count_changes */
- }
-
- /* If we get this far, it means that the xfer optimization is at
- ** least a possibility, though it might only work if the destination
- ** table (tab1) is initially empty.
- */
-#ifdef SQLITE_TEST
- sqlite3_xferopt_count++;
-#endif
- iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema);
- v = sqlite3GetVdbe(pParse);
- sqlite3CodeVerifySchema(pParse, iDbSrc);
- iSrc = pParse->nTab++;
- iDest = pParse->nTab++;
- regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
- sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
- if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
- || destHasUniqueIdx /* (2) */
- || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
- ){
- /* In some circumstances, we are able to run the xfer optimization
- ** only if the destination table is initially empty. This code makes
- ** that determination. Conditions under which the destination must
- ** be empty:
- **
- ** (1) There is no INTEGER PRIMARY KEY but there are indices.
- ** (If the destination is not initially empty, the rowid fields
- ** of index entries might need to change.)
- **
- ** (2) The destination has a unique index. (The xfer optimization
- ** is unable to test uniqueness.)
- **
- ** (3) onError is something other than OE_Abort and OE_Rollback.
- */
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0);
- emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
- sqlite3VdbeJumpHere(v, addr1);
- }else{
- emptyDestTest = 0;
- }
- sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
- emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
- regData = sqlite3GetTempReg(pParse);
- regRowid = sqlite3GetTempReg(pParse);
- if( pDest->iPKey>=0 ){
- addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
- addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
- sqlite3HaltConstraint(
- pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
- sqlite3VdbeJumpHere(v, addr2);
- autoIncStep(pParse, regAutoinc, regRowid);
- }else if( pDest->pIndex==0 ){
- addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
- }else{
- addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
- assert( (pDest->tabFlags & TF_Autoincrement)==0 );
- }
- sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
- sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
- sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
- for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
- for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
- if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
- }
- assert( pSrcIdx );
- sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
- pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
- sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pSrcIdx->zName));
- pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pDestIdx->zName));
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
- sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
- sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
- sqlite3VdbeJumpHere(v, addr1);
- }
- sqlite3VdbeJumpHere(v, emptySrcTest);
- sqlite3ReleaseTempReg(pParse, regRowid);
- sqlite3ReleaseTempReg(pParse, regData);
- sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
- if( emptyDestTest ){
- sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
- sqlite3VdbeJumpHere(v, emptyDestTest);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
- return 0;
- }else{
- return 1;
- }
-}
-#endif /* SQLITE_OMIT_XFER_OPT */
-
-/************** End of insert.c **********************************************/
-/************** Begin file legacy.c ******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** Main file for the SQLite library. The routines in this file
-** implement the programmer interface to the library. Routines in
-** other files are for internal use by SQLite and should not be
-** accessed by users of the library.
-*/
-
-
-/*
-** Execute SQL code. Return one of the SQLITE_ success/failure
-** codes. Also write an error message into memory obtained from
-** malloc() and make *pzErrMsg point to that message.
-**
-** If the SQL is a query, then for each row in the query result
-** the xCallback() function is called. pArg becomes the first
-** argument to xCallback(). If xCallback=NULL then no callback
-** is invoked, even for queries.
-*/
-SQLITE_API int sqlite3_exec(
- sqlite3 *db, /* The database on which the SQL executes */
- const char *zSql, /* The SQL to be executed */
- sqlite3_callback xCallback, /* Invoke this callback routine */
- void *pArg, /* First argument to xCallback() */
- char **pzErrMsg /* Write error messages here */
-){
- int rc = SQLITE_OK; /* Return code */
- const char *zLeftover; /* Tail of unprocessed SQL */
- sqlite3_stmt *pStmt = 0; /* The current SQL statement */
- char **azCols = 0; /* Names of result columns */
- int nRetry = 0; /* Number of retry attempts */
- int callbackIsInit; /* True if callback data is initialized */
-
- if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
- if( zSql==0 ) zSql = "";
-
- sqlite3_mutex_enter(db->mutex);
- sqlite3Error(db, SQLITE_OK, 0);
- while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
- int nCol;
- char **azVals = 0;
-
- pStmt = 0;
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
- assert( rc==SQLITE_OK || pStmt==0 );
- if( rc!=SQLITE_OK ){
- continue;
- }
- if( !pStmt ){
- /* this happens for a comment or white-space */
- zSql = zLeftover;
- continue;
- }
-
- callbackIsInit = 0;
- nCol = sqlite3_column_count(pStmt);
-
- while( 1 ){
- int i;
- rc = sqlite3_step(pStmt);
-
- /* Invoke the callback function if required */
- if( xCallback && (SQLITE_ROW==rc ||
- (SQLITE_DONE==rc && !callbackIsInit
- && db->flags&SQLITE_NullCallback)) ){
- if( !callbackIsInit ){
- azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
- if( azCols==0 ){
- goto exec_out;
- }
- for(i=0; i<nCol; i++){
- azCols[i] = (char *)sqlite3_column_name(pStmt, i);
- /* sqlite3VdbeSetColName() installs column names as UTF8
- ** strings so there is no way for sqlite3_column_name() to fail. */
- assert( azCols[i]!=0 );
- }
- callbackIsInit = 1;
- }
- if( rc==SQLITE_ROW ){
- azVals = &azCols[nCol];
- for(i=0; i<nCol; i++){
- azVals[i] = (char *)sqlite3_column_text(pStmt, i);
- if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
- db->mallocFailed = 1;
- goto exec_out;
- }
- }
- }
- if( xCallback(pArg, nCol, azVals, azCols) ){
- rc = SQLITE_ABORT;
- sqlite3VdbeFinalize((Vdbe *)pStmt);
- pStmt = 0;
- sqlite3Error(db, SQLITE_ABORT, 0);
- goto exec_out;
- }
- }
-
- if( rc!=SQLITE_ROW ){
- rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
- pStmt = 0;
- if( rc!=SQLITE_SCHEMA ){
- nRetry = 0;
- zSql = zLeftover;
- while( sqlite3Isspace(zSql[0]) ) zSql++;
- }
- break;
- }
- }
-
- sqlite3DbFree(db, azCols);
- azCols = 0;
- }
-
-exec_out:
- if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
- sqlite3DbFree(db, azCols);
-
- rc = sqlite3ApiExit(db, rc);
- if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
- int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
- *pzErrMsg = sqlite3Malloc(nErrMsg);
- if( *pzErrMsg ){
- memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
- }else{
- rc = SQLITE_NOMEM;
- sqlite3Error(db, SQLITE_NOMEM, 0);
- }
- }else if( pzErrMsg ){
- *pzErrMsg = 0;
- }
-
- assert( (rc&db->errMask)==rc );
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/************** End of legacy.c **********************************************/
-/************** Begin file loadext.c *****************************************/
-/*
-** 2006 June 7
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code used to dynamically load extensions into
-** the SQLite library.
-*/
-
-#ifndef SQLITE_CORE
- #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
-#endif
-/************** Include sqlite3ext.h in the middle of loadext.c **************/
-/************** Begin file sqlite3ext.h **************************************/
-/*
-** 2006 June 7
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This header file defines the SQLite interface for use by
-** shared libraries that want to be imported as extensions into
-** an SQLite instance. Shared libraries that intend to be loaded
-** as extensions by SQLite should #include this file instead of
-** sqlite3.h.
-*/
-#ifndef _SQLITE3EXT_H_
-#define _SQLITE3EXT_H_
-
-typedef struct sqlite3_api_routines sqlite3_api_routines;
-
-/*
-** The following structure holds pointers to all of the SQLite API
-** routines.
-**
-** WARNING: In order to maintain backwards compatibility, add new
-** interfaces to the end of this structure only. If you insert new
-** interfaces in the middle of this structure, then older different
-** versions of SQLite will not be able to load each others' shared
-** libraries!
-*/
-struct sqlite3_api_routines {
- void * (*aggregate_context)(sqlite3_context*,int nBytes);
- int (*aggregate_count)(sqlite3_context*);
- int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
- int (*bind_double)(sqlite3_stmt*,int,double);
- int (*bind_int)(sqlite3_stmt*,int,int);
- int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
- int (*bind_null)(sqlite3_stmt*,int);
- int (*bind_parameter_count)(sqlite3_stmt*);
- int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
- const char * (*bind_parameter_name)(sqlite3_stmt*,int);
- int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
- int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
- int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
- int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
- int (*busy_timeout)(sqlite3*,int ms);
- int (*changes)(sqlite3*);
- int (*close)(sqlite3*);
- int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
- int eTextRep,const char*));
- int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
- int eTextRep,const void*));
- const void * (*column_blob)(sqlite3_stmt*,int iCol);
- int (*column_bytes)(sqlite3_stmt*,int iCol);
- int (*column_bytes16)(sqlite3_stmt*,int iCol);
- int (*column_count)(sqlite3_stmt*pStmt);
- const char * (*column_database_name)(sqlite3_stmt*,int);
- const void * (*column_database_name16)(sqlite3_stmt*,int);
- const char * (*column_decltype)(sqlite3_stmt*,int i);
- const void * (*column_decltype16)(sqlite3_stmt*,int);
- double (*column_double)(sqlite3_stmt*,int iCol);
- int (*column_int)(sqlite3_stmt*,int iCol);
- sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
- const char * (*column_name)(sqlite3_stmt*,int);
- const void * (*column_name16)(sqlite3_stmt*,int);
- const char * (*column_origin_name)(sqlite3_stmt*,int);
- const void * (*column_origin_name16)(sqlite3_stmt*,int);
- const char * (*column_table_name)(sqlite3_stmt*,int);
- const void * (*column_table_name16)(sqlite3_stmt*,int);
- const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
- const void * (*column_text16)(sqlite3_stmt*,int iCol);
- int (*column_type)(sqlite3_stmt*,int iCol);
- sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
- void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
- int (*complete)(const char*sql);
- int (*complete16)(const void*sql);
- int (*create_collation)(sqlite3*,const char*,int,void*,
- int(*)(void*,int,const void*,int,const void*));
- int (*create_collation16)(sqlite3*,const void*,int,void*,
- int(*)(void*,int,const void*,int,const void*));
- int (*create_function)(sqlite3*,const char*,int,int,void*,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*));
- int (*create_function16)(sqlite3*,const void*,int,int,void*,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*));
- int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
- int (*data_count)(sqlite3_stmt*pStmt);
- sqlite3 * (*db_handle)(sqlite3_stmt*);
- int (*declare_vtab)(sqlite3*,const char*);
- int (*enable_shared_cache)(int);
- int (*errcode)(sqlite3*db);
- const char * (*errmsg)(sqlite3*);
- const void * (*errmsg16)(sqlite3*);
- int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
- int (*expired)(sqlite3_stmt*);
- int (*finalize)(sqlite3_stmt*pStmt);
- void (*free)(void*);
- void (*free_table)(char**result);
- int (*get_autocommit)(sqlite3*);
- void * (*get_auxdata)(sqlite3_context*,int);
- int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
- int (*global_recover)(void);
- void (*interruptx)(sqlite3*);
- sqlite_int64 (*last_insert_rowid)(sqlite3*);
- const char * (*libversion)(void);
- int (*libversion_number)(void);
- void *(*malloc)(int);
- char * (*mprintf)(const char*,...);
- int (*open)(const char*,sqlite3**);
- int (*open16)(const void*,sqlite3**);
- int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
- int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
- void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
- void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
- void *(*realloc)(void*,int);
- int (*reset)(sqlite3_stmt*pStmt);
- void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
- void (*result_double)(sqlite3_context*,double);
- void (*result_error)(sqlite3_context*,const char*,int);
- void (*result_error16)(sqlite3_context*,const void*,int);
- void (*result_int)(sqlite3_context*,int);
- void (*result_int64)(sqlite3_context*,sqlite_int64);
- void (*result_null)(sqlite3_context*);
- void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
- void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
- void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
- void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
- void (*result_value)(sqlite3_context*,sqlite3_value*);
- void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
- int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
- const char*,const char*),void*);
- void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
- char * (*snprintf)(int,char*,const char*,...);
- int (*step)(sqlite3_stmt*);
- int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
- char const**,char const**,int*,int*,int*);
- void (*thread_cleanup)(void);
- int (*total_changes)(sqlite3*);
- void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
- int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
- void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
- sqlite_int64),void*);
- void * (*user_data)(sqlite3_context*);
- const void * (*value_blob)(sqlite3_value*);
- int (*value_bytes)(sqlite3_value*);
- int (*value_bytes16)(sqlite3_value*);
- double (*value_double)(sqlite3_value*);
- int (*value_int)(sqlite3_value*);
- sqlite_int64 (*value_int64)(sqlite3_value*);
- int (*value_numeric_type)(sqlite3_value*);
- const unsigned char * (*value_text)(sqlite3_value*);
- const void * (*value_text16)(sqlite3_value*);
- const void * (*value_text16be)(sqlite3_value*);
- const void * (*value_text16le)(sqlite3_value*);
- int (*value_type)(sqlite3_value*);
- char *(*vmprintf)(const char*,va_list);
- /* Added ??? */
- int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
- /* Added by 3.3.13 */
- int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
- int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
- int (*clear_bindings)(sqlite3_stmt*);
- /* Added by 3.4.1 */
- int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
- void (*xDestroy)(void *));
- /* Added by 3.5.0 */
- int (*bind_zeroblob)(sqlite3_stmt*,int,int);
- int (*blob_bytes)(sqlite3_blob*);
- int (*blob_close)(sqlite3_blob*);
- int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
- int,sqlite3_blob**);
- int (*blob_read)(sqlite3_blob*,void*,int,int);
- int (*blob_write)(sqlite3_blob*,const void*,int,int);
- int (*create_collation_v2)(sqlite3*,const char*,int,void*,
- int(*)(void*,int,const void*,int,const void*),
- void(*)(void*));
- int (*file_control)(sqlite3*,const char*,int,void*);
- sqlite3_int64 (*memory_highwater)(int);
- sqlite3_int64 (*memory_used)(void);
- sqlite3_mutex *(*mutex_alloc)(int);
- void (*mutex_enter)(sqlite3_mutex*);
- void (*mutex_free)(sqlite3_mutex*);
- void (*mutex_leave)(sqlite3_mutex*);
- int (*mutex_try)(sqlite3_mutex*);
- int (*open_v2)(const char*,sqlite3**,int,const char*);
- int (*release_memory)(int);
- void (*result_error_nomem)(sqlite3_context*);
- void (*result_error_toobig)(sqlite3_context*);
- int (*sleep)(int);
- void (*soft_heap_limit)(int);
- sqlite3_vfs *(*vfs_find)(const char*);
- int (*vfs_register)(sqlite3_vfs*,int);
- int (*vfs_unregister)(sqlite3_vfs*);
- int (*xthreadsafe)(void);
- void (*result_zeroblob)(sqlite3_context*,int);
- void (*result_error_code)(sqlite3_context*,int);
- int (*test_control)(int, ...);
- void (*randomness)(int,void*);
- sqlite3 *(*context_db_handle)(sqlite3_context*);
- int (*extended_result_codes)(sqlite3*,int);
- int (*limit)(sqlite3*,int,int);
- sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
- const char *(*sql)(sqlite3_stmt*);
- int (*status)(int,int*,int*,int);
- int (*backup_finish)(sqlite3_backup*);
- sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
- int (*backup_pagecount)(sqlite3_backup*);
- int (*backup_remaining)(sqlite3_backup*);
- int (*backup_step)(sqlite3_backup*,int);
- const char *(*compileoption_get)(int);
- int (*compileoption_used)(const char*);
- int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*),
- void(*xDestroy)(void*));
- int (*db_config)(sqlite3*,int,...);
- sqlite3_mutex *(*db_mutex)(sqlite3*);
- int (*db_status)(sqlite3*,int,int*,int*,int);
- int (*extended_errcode)(sqlite3*);
- void (*log)(int,const char*,...);
- sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
- const char *(*sourceid)(void);
- int (*stmt_status)(sqlite3_stmt*,int,int);
- int (*strnicmp)(const char*,const char*,int);
- int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
- int (*wal_autocheckpoint)(sqlite3*,int);
- int (*wal_checkpoint)(sqlite3*,const char*);
- void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
- int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
- int (*vtab_config)(sqlite3*,int op,...);
- int (*vtab_on_conflict)(sqlite3*);
-};
-
-/*
-** The following macros redefine the API routines so that they are
-** redirected throught the global sqlite3_api structure.
-**
-** This header file is also used by the loadext.c source file
-** (part of the main SQLite library - not an extension) so that
-** it can get access to the sqlite3_api_routines structure
-** definition. But the main library does not want to redefine
-** the API. So the redefinition macros are only valid if the
-** SQLITE_CORE macros is undefined.
-*/
-#ifndef SQLITE_CORE
-#define sqlite3_aggregate_context sqlite3_api->aggregate_context
-#ifndef SQLITE_OMIT_DEPRECATED
-#define sqlite3_aggregate_count sqlite3_api->aggregate_count
-#endif
-#define sqlite3_bind_blob sqlite3_api->bind_blob
-#define sqlite3_bind_double sqlite3_api->bind_double
-#define sqlite3_bind_int sqlite3_api->bind_int
-#define sqlite3_bind_int64 sqlite3_api->bind_int64
-#define sqlite3_bind_null sqlite3_api->bind_null
-#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
-#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
-#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
-#define sqlite3_bind_text sqlite3_api->bind_text
-#define sqlite3_bind_text16 sqlite3_api->bind_text16
-#define sqlite3_bind_value sqlite3_api->bind_value
-#define sqlite3_busy_handler sqlite3_api->busy_handler
-#define sqlite3_busy_timeout sqlite3_api->busy_timeout
-#define sqlite3_changes sqlite3_api->changes
-#define sqlite3_close sqlite3_api->close
-#define sqlite3_collation_needed sqlite3_api->collation_needed
-#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
-#define sqlite3_column_blob sqlite3_api->column_blob
-#define sqlite3_column_bytes sqlite3_api->column_bytes
-#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
-#define sqlite3_column_count sqlite3_api->column_count
-#define sqlite3_column_database_name sqlite3_api->column_database_name
-#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
-#define sqlite3_column_decltype sqlite3_api->column_decltype
-#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
-#define sqlite3_column_double sqlite3_api->column_double
-#define sqlite3_column_int sqlite3_api->column_int
-#define sqlite3_column_int64 sqlite3_api->column_int64
-#define sqlite3_column_name sqlite3_api->column_name
-#define sqlite3_column_name16 sqlite3_api->column_name16
-#define sqlite3_column_origin_name sqlite3_api->column_origin_name
-#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
-#define sqlite3_column_table_name sqlite3_api->column_table_name
-#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
-#define sqlite3_column_text sqlite3_api->column_text
-#define sqlite3_column_text16 sqlite3_api->column_text16
-#define sqlite3_column_type sqlite3_api->column_type
-#define sqlite3_column_value sqlite3_api->column_value
-#define sqlite3_commit_hook sqlite3_api->commit_hook
-#define sqlite3_complete sqlite3_api->complete
-#define sqlite3_complete16 sqlite3_api->complete16
-#define sqlite3_create_collation sqlite3_api->create_collation
-#define sqlite3_create_collation16 sqlite3_api->create_collation16
-#define sqlite3_create_function sqlite3_api->create_function
-#define sqlite3_create_function16 sqlite3_api->create_function16
-#define sqlite3_create_module sqlite3_api->create_module
-#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
-#define sqlite3_data_count sqlite3_api->data_count
-#define sqlite3_db_handle sqlite3_api->db_handle
-#define sqlite3_declare_vtab sqlite3_api->declare_vtab
-#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
-#define sqlite3_errcode sqlite3_api->errcode
-#define sqlite3_errmsg sqlite3_api->errmsg
-#define sqlite3_errmsg16 sqlite3_api->errmsg16
-#define sqlite3_exec sqlite3_api->exec
-#ifndef SQLITE_OMIT_DEPRECATED
-#define sqlite3_expired sqlite3_api->expired
-#endif
-#define sqlite3_finalize sqlite3_api->finalize
-#define sqlite3_free sqlite3_api->free
-#define sqlite3_free_table sqlite3_api->free_table
-#define sqlite3_get_autocommit sqlite3_api->get_autocommit
-#define sqlite3_get_auxdata sqlite3_api->get_auxdata
-#define sqlite3_get_table sqlite3_api->get_table
-#ifndef SQLITE_OMIT_DEPRECATED
-#define sqlite3_global_recover sqlite3_api->global_recover
-#endif
-#define sqlite3_interrupt sqlite3_api->interruptx
-#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
-#define sqlite3_libversion sqlite3_api->libversion
-#define sqlite3_libversion_number sqlite3_api->libversion_number
-#define sqlite3_malloc sqlite3_api->malloc
-#define sqlite3_mprintf sqlite3_api->mprintf
-#define sqlite3_open sqlite3_api->open
-#define sqlite3_open16 sqlite3_api->open16
-#define sqlite3_prepare sqlite3_api->prepare
-#define sqlite3_prepare16 sqlite3_api->prepare16
-#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
-#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
-#define sqlite3_profile sqlite3_api->profile
-#define sqlite3_progress_handler sqlite3_api->progress_handler
-#define sqlite3_realloc sqlite3_api->realloc
-#define sqlite3_reset sqlite3_api->reset
-#define sqlite3_result_blob sqlite3_api->result_blob
-#define sqlite3_result_double sqlite3_api->result_double
-#define sqlite3_result_error sqlite3_api->result_error
-#define sqlite3_result_error16 sqlite3_api->result_error16
-#define sqlite3_result_int sqlite3_api->result_int
-#define sqlite3_result_int64 sqlite3_api->result_int64
-#define sqlite3_result_null sqlite3_api->result_null
-#define sqlite3_result_text sqlite3_api->result_text
-#define sqlite3_result_text16 sqlite3_api->result_text16
-#define sqlite3_result_text16be sqlite3_api->result_text16be
-#define sqlite3_result_text16le sqlite3_api->result_text16le
-#define sqlite3_result_value sqlite3_api->result_value
-#define sqlite3_rollback_hook sqlite3_api->rollback_hook
-#define sqlite3_set_authorizer sqlite3_api->set_authorizer
-#define sqlite3_set_auxdata sqlite3_api->set_auxdata
-#define sqlite3_snprintf sqlite3_api->snprintf
-#define sqlite3_step sqlite3_api->step
-#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
-#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
-#define sqlite3_total_changes sqlite3_api->total_changes
-#define sqlite3_trace sqlite3_api->trace
-#ifndef SQLITE_OMIT_DEPRECATED
-#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
-#endif
-#define sqlite3_update_hook sqlite3_api->update_hook
-#define sqlite3_user_data sqlite3_api->user_data
-#define sqlite3_value_blob sqlite3_api->value_blob
-#define sqlite3_value_bytes sqlite3_api->value_bytes
-#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
-#define sqlite3_value_double sqlite3_api->value_double
-#define sqlite3_value_int sqlite3_api->value_int
-#define sqlite3_value_int64 sqlite3_api->value_int64
-#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
-#define sqlite3_value_text sqlite3_api->value_text
-#define sqlite3_value_text16 sqlite3_api->value_text16
-#define sqlite3_value_text16be sqlite3_api->value_text16be
-#define sqlite3_value_text16le sqlite3_api->value_text16le
-#define sqlite3_value_type sqlite3_api->value_type
-#define sqlite3_vmprintf sqlite3_api->vmprintf
-#define sqlite3_overload_function sqlite3_api->overload_function
-#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
-#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
-#define sqlite3_clear_bindings sqlite3_api->clear_bindings
-#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
-#define sqlite3_blob_bytes sqlite3_api->blob_bytes
-#define sqlite3_blob_close sqlite3_api->blob_close
-#define sqlite3_blob_open sqlite3_api->blob_open
-#define sqlite3_blob_read sqlite3_api->blob_read
-#define sqlite3_blob_write sqlite3_api->blob_write
-#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
-#define sqlite3_file_control sqlite3_api->file_control
-#define sqlite3_memory_highwater sqlite3_api->memory_highwater
-#define sqlite3_memory_used sqlite3_api->memory_used
-#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
-#define sqlite3_mutex_enter sqlite3_api->mutex_enter
-#define sqlite3_mutex_free sqlite3_api->mutex_free
-#define sqlite3_mutex_leave sqlite3_api->mutex_leave
-#define sqlite3_mutex_try sqlite3_api->mutex_try
-#define sqlite3_open_v2 sqlite3_api->open_v2
-#define sqlite3_release_memory sqlite3_api->release_memory
-#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
-#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
-#define sqlite3_sleep sqlite3_api->sleep
-#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
-#define sqlite3_vfs_find sqlite3_api->vfs_find
-#define sqlite3_vfs_register sqlite3_api->vfs_register
-#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
-#define sqlite3_threadsafe sqlite3_api->xthreadsafe
-#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
-#define sqlite3_result_error_code sqlite3_api->result_error_code
-#define sqlite3_test_control sqlite3_api->test_control
-#define sqlite3_randomness sqlite3_api->randomness
-#define sqlite3_context_db_handle sqlite3_api->context_db_handle
-#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
-#define sqlite3_limit sqlite3_api->limit
-#define sqlite3_next_stmt sqlite3_api->next_stmt
-#define sqlite3_sql sqlite3_api->sql
-#define sqlite3_status sqlite3_api->status
-#define sqlite3_backup_finish sqlite3_api->backup_finish
-#define sqlite3_backup_init sqlite3_api->backup_init
-#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
-#define sqlite3_backup_remaining sqlite3_api->backup_remaining
-#define sqlite3_backup_step sqlite3_api->backup_step
-#define sqlite3_compileoption_get sqlite3_api->compileoption_get
-#define sqlite3_compileoption_used sqlite3_api->compileoption_used
-#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
-#define sqlite3_db_config sqlite3_api->db_config
-#define sqlite3_db_mutex sqlite3_api->db_mutex
-#define sqlite3_db_status sqlite3_api->db_status
-#define sqlite3_extended_errcode sqlite3_api->extended_errcode
-#define sqlite3_log sqlite3_api->log
-#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
-#define sqlite3_sourceid sqlite3_api->sourceid
-#define sqlite3_stmt_status sqlite3_api->stmt_status
-#define sqlite3_strnicmp sqlite3_api->strnicmp
-#define sqlite3_unlock_notify sqlite3_api->unlock_notify
-#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
-#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
-#define sqlite3_wal_hook sqlite3_api->wal_hook
-#define sqlite3_blob_reopen sqlite3_api->blob_reopen
-#define sqlite3_vtab_config sqlite3_api->vtab_config
-#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
-#endif /* SQLITE_CORE */
-
-#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0;
-#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v;
-
-#endif /* _SQLITE3EXT_H_ */
-
-/************** End of sqlite3ext.h ******************************************/
-/************** Continuing where we left off in loadext.c ********************/
-/* #include <string.h> */
-
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-
-/*
-** Some API routines are omitted when various features are
-** excluded from a build of SQLite. Substitute a NULL pointer
-** for any missing APIs.
-*/
-#ifndef SQLITE_ENABLE_COLUMN_METADATA
-# define sqlite3_column_database_name 0
-# define sqlite3_column_database_name16 0
-# define sqlite3_column_table_name 0
-# define sqlite3_column_table_name16 0
-# define sqlite3_column_origin_name 0
-# define sqlite3_column_origin_name16 0
-# define sqlite3_table_column_metadata 0
-#endif
-
-#ifdef SQLITE_OMIT_AUTHORIZATION
-# define sqlite3_set_authorizer 0
-#endif
-
-#ifdef SQLITE_OMIT_UTF16
-# define sqlite3_bind_text16 0
-# define sqlite3_collation_needed16 0
-# define sqlite3_column_decltype16 0
-# define sqlite3_column_name16 0
-# define sqlite3_column_text16 0
-# define sqlite3_complete16 0
-# define sqlite3_create_collation16 0
-# define sqlite3_create_function16 0
-# define sqlite3_errmsg16 0
-# define sqlite3_open16 0
-# define sqlite3_prepare16 0
-# define sqlite3_prepare16_v2 0
-# define sqlite3_result_error16 0
-# define sqlite3_result_text16 0
-# define sqlite3_result_text16be 0
-# define sqlite3_result_text16le 0
-# define sqlite3_value_text16 0
-# define sqlite3_value_text16be 0
-# define sqlite3_value_text16le 0
-# define sqlite3_column_database_name16 0
-# define sqlite3_column_table_name16 0
-# define sqlite3_column_origin_name16 0
-#endif
-
-#ifdef SQLITE_OMIT_COMPLETE
-# define sqlite3_complete 0
-# define sqlite3_complete16 0
-#endif
-
-#ifdef SQLITE_OMIT_DECLTYPE
-# define sqlite3_column_decltype16 0
-# define sqlite3_column_decltype 0
-#endif
-
-#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
-# define sqlite3_progress_handler 0
-#endif
-
-#ifdef SQLITE_OMIT_VIRTUALTABLE
-# define sqlite3_create_module 0
-# define sqlite3_create_module_v2 0
-# define sqlite3_declare_vtab 0
-# define sqlite3_vtab_config 0
-# define sqlite3_vtab_on_conflict 0
-#endif
-
-#ifdef SQLITE_OMIT_SHARED_CACHE
-# define sqlite3_enable_shared_cache 0
-#endif
-
-#ifdef SQLITE_OMIT_TRACE
-# define sqlite3_profile 0
-# define sqlite3_trace 0
-#endif
-
-#ifdef SQLITE_OMIT_GET_TABLE
-# define sqlite3_free_table 0
-# define sqlite3_get_table 0
-#endif
-
-#ifdef SQLITE_OMIT_INCRBLOB
-#define sqlite3_bind_zeroblob 0
-#define sqlite3_blob_bytes 0
-#define sqlite3_blob_close 0
-#define sqlite3_blob_open 0
-#define sqlite3_blob_read 0
-#define sqlite3_blob_write 0
-#define sqlite3_blob_reopen 0
-#endif
-
-/*
-** The following structure contains pointers to all SQLite API routines.
-** A pointer to this structure is passed into extensions when they are
-** loaded so that the extension can make calls back into the SQLite
-** library.
-**
-** When adding new APIs, add them to the bottom of this structure
-** in order to preserve backwards compatibility.
-**
-** Extensions that use newer APIs should first call the
-** sqlite3_libversion_number() to make sure that the API they
-** intend to use is supported by the library. Extensions should
-** also check to make sure that the pointer to the function is
-** not NULL before calling it.
-*/
-static const sqlite3_api_routines sqlite3Apis = {
- sqlite3_aggregate_context,
-#ifndef SQLITE_OMIT_DEPRECATED
- sqlite3_aggregate_count,
-#else
- 0,
-#endif
- sqlite3_bind_blob,
- sqlite3_bind_double,
- sqlite3_bind_int,
- sqlite3_bind_int64,
- sqlite3_bind_null,
- sqlite3_bind_parameter_count,
- sqlite3_bind_parameter_index,
- sqlite3_bind_parameter_name,
- sqlite3_bind_text,
- sqlite3_bind_text16,
- sqlite3_bind_value,
- sqlite3_busy_handler,
- sqlite3_busy_timeout,
- sqlite3_changes,
- sqlite3_close,
- sqlite3_collation_needed,
- sqlite3_collation_needed16,
- sqlite3_column_blob,
- sqlite3_column_bytes,
- sqlite3_column_bytes16,
- sqlite3_column_count,
- sqlite3_column_database_name,
- sqlite3_column_database_name16,
- sqlite3_column_decltype,
- sqlite3_column_decltype16,
- sqlite3_column_double,
- sqlite3_column_int,
- sqlite3_column_int64,
- sqlite3_column_name,
- sqlite3_column_name16,
- sqlite3_column_origin_name,
- sqlite3_column_origin_name16,
- sqlite3_column_table_name,
- sqlite3_column_table_name16,
- sqlite3_column_text,
- sqlite3_column_text16,
- sqlite3_column_type,
- sqlite3_column_value,
- sqlite3_commit_hook,
- sqlite3_complete,
- sqlite3_complete16,
- sqlite3_create_collation,
- sqlite3_create_collation16,
- sqlite3_create_function,
- sqlite3_create_function16,
- sqlite3_create_module,
- sqlite3_data_count,
- sqlite3_db_handle,
- sqlite3_declare_vtab,
- sqlite3_enable_shared_cache,
- sqlite3_errcode,
- sqlite3_errmsg,
- sqlite3_errmsg16,
- sqlite3_exec,
-#ifndef SQLITE_OMIT_DEPRECATED
- sqlite3_expired,
-#else
- 0,
-#endif
- sqlite3_finalize,
- sqlite3_free,
- sqlite3_free_table,
- sqlite3_get_autocommit,
- sqlite3_get_auxdata,
- sqlite3_get_table,
- 0, /* Was sqlite3_global_recover(), but that function is deprecated */
- sqlite3_interrupt,
- sqlite3_last_insert_rowid,
- sqlite3_libversion,
- sqlite3_libversion_number,
- sqlite3_malloc,
- sqlite3_mprintf,
- sqlite3_open,
- sqlite3_open16,
- sqlite3_prepare,
- sqlite3_prepare16,
- sqlite3_profile,
- sqlite3_progress_handler,
- sqlite3_realloc,
- sqlite3_reset,
- sqlite3_result_blob,
- sqlite3_result_double,
- sqlite3_result_error,
- sqlite3_result_error16,
- sqlite3_result_int,
- sqlite3_result_int64,
- sqlite3_result_null,
- sqlite3_result_text,
- sqlite3_result_text16,
- sqlite3_result_text16be,
- sqlite3_result_text16le,
- sqlite3_result_value,
- sqlite3_rollback_hook,
- sqlite3_set_authorizer,
- sqlite3_set_auxdata,
- sqlite3_snprintf,
- sqlite3_step,
- sqlite3_table_column_metadata,
-#ifndef SQLITE_OMIT_DEPRECATED
- sqlite3_thread_cleanup,
-#else
- 0,
-#endif
- sqlite3_total_changes,
- sqlite3_trace,
-#ifndef SQLITE_OMIT_DEPRECATED
- sqlite3_transfer_bindings,
-#else
- 0,
-#endif
- sqlite3_update_hook,
- sqlite3_user_data,
- sqlite3_value_blob,
- sqlite3_value_bytes,
- sqlite3_value_bytes16,
- sqlite3_value_double,
- sqlite3_value_int,
- sqlite3_value_int64,
- sqlite3_value_numeric_type,
- sqlite3_value_text,
- sqlite3_value_text16,
- sqlite3_value_text16be,
- sqlite3_value_text16le,
- sqlite3_value_type,
- sqlite3_vmprintf,
- /*
- ** The original API set ends here. All extensions can call any
- ** of the APIs above provided that the pointer is not NULL. But
- ** before calling APIs that follow, extension should check the
- ** sqlite3_libversion_number() to make sure they are dealing with
- ** a library that is new enough to support that API.
- *************************************************************************
- */
- sqlite3_overload_function,
-
- /*
- ** Added after 3.3.13
- */
- sqlite3_prepare_v2,
- sqlite3_prepare16_v2,
- sqlite3_clear_bindings,
-
- /*
- ** Added for 3.4.1
- */
- sqlite3_create_module_v2,
-
- /*
- ** Added for 3.5.0
- */
- sqlite3_bind_zeroblob,
- sqlite3_blob_bytes,
- sqlite3_blob_close,
- sqlite3_blob_open,
- sqlite3_blob_read,
- sqlite3_blob_write,
- sqlite3_create_collation_v2,
- sqlite3_file_control,
- sqlite3_memory_highwater,
- sqlite3_memory_used,
-#ifdef SQLITE_MUTEX_OMIT
- 0,
- 0,
- 0,
- 0,
- 0,
-#else
- sqlite3_mutex_alloc,
- sqlite3_mutex_enter,
- sqlite3_mutex_free,
- sqlite3_mutex_leave,
- sqlite3_mutex_try,
-#endif
- sqlite3_open_v2,
- sqlite3_release_memory,
- sqlite3_result_error_nomem,
- sqlite3_result_error_toobig,
- sqlite3_sleep,
- sqlite3_soft_heap_limit,
- sqlite3_vfs_find,
- sqlite3_vfs_register,
- sqlite3_vfs_unregister,
-
- /*
- ** Added for 3.5.8
- */
- sqlite3_threadsafe,
- sqlite3_result_zeroblob,
- sqlite3_result_error_code,
- sqlite3_test_control,
- sqlite3_randomness,
- sqlite3_context_db_handle,
-
- /*
- ** Added for 3.6.0
- */
- sqlite3_extended_result_codes,
- sqlite3_limit,
- sqlite3_next_stmt,
- sqlite3_sql,
- sqlite3_status,
-
- /*
- ** Added for 3.7.4
- */
- sqlite3_backup_finish,
- sqlite3_backup_init,
- sqlite3_backup_pagecount,
- sqlite3_backup_remaining,
- sqlite3_backup_step,
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
- sqlite3_compileoption_get,
- sqlite3_compileoption_used,
-#else
- 0,
- 0,
-#endif
- sqlite3_create_function_v2,
- sqlite3_db_config,
- sqlite3_db_mutex,
- sqlite3_db_status,
- sqlite3_extended_errcode,
- sqlite3_log,
- sqlite3_soft_heap_limit64,
- sqlite3_sourceid,
- sqlite3_stmt_status,
- sqlite3_strnicmp,
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
- sqlite3_unlock_notify,
-#else
- 0,
-#endif
-#ifndef SQLITE_OMIT_WAL
- sqlite3_wal_autocheckpoint,
- sqlite3_wal_checkpoint,
- sqlite3_wal_hook,
-#else
- 0,
- 0,
- 0,
-#endif
- sqlite3_blob_reopen,
- sqlite3_vtab_config,
- sqlite3_vtab_on_conflict,
-};
-
-/*
-** Attempt to load an SQLite extension library contained in the file
-** zFile. The entry point is zProc. zProc may be 0 in which case a
-** default entry point name (sqlite3_extension_init) is used. Use
-** of the default name is recommended.
-**
-** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong.
-**
-** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with
-** error message text. The calling function should free this memory
-** by calling sqlite3DbFree(db, ).
-*/
-static int sqlite3LoadExtension(
- sqlite3 *db, /* Load the extension into this database connection */
- const char *zFile, /* Name of the shared library containing extension */
- const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
- char **pzErrMsg /* Put error message here if not 0 */
-){
- sqlite3_vfs *pVfs = db->pVfs;
- void *handle;
- int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
- char *zErrmsg = 0;
- void **aHandle;
- int nMsg = 300 + sqlite3Strlen30(zFile);
-
- if( pzErrMsg ) *pzErrMsg = 0;
-
- /* Ticket #1863. To avoid a creating security problems for older
- ** applications that relink against newer versions of SQLite, the
- ** ability to run load_extension is turned off by default. One
- ** must call sqlite3_enable_load_extension() to turn on extension
- ** loading. Otherwise you get the following error.
- */
- if( (db->flags & SQLITE_LoadExtension)==0 ){
- if( pzErrMsg ){
- *pzErrMsg = sqlite3_mprintf("not authorized");
- }
- return SQLITE_ERROR;
- }
-
- if( zProc==0 ){
- zProc = "sqlite3_extension_init";
- }
-
- handle = sqlite3OsDlOpen(pVfs, zFile);
- if( handle==0 ){
- if( pzErrMsg ){
- *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
- if( zErrmsg ){
- sqlite3_snprintf(nMsg, zErrmsg,
- "unable to open shared library [%s]", zFile);
- sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
- }
- }
- return SQLITE_ERROR;
- }
- xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
- sqlite3OsDlSym(pVfs, handle, zProc);
- if( xInit==0 ){
- if( pzErrMsg ){
- nMsg += sqlite3Strlen30(zProc);
- *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
- if( zErrmsg ){
- sqlite3_snprintf(nMsg, zErrmsg,
- "no entry point [%s] in shared library [%s]", zProc,zFile);
- sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
- }
- sqlite3OsDlClose(pVfs, handle);
- }
- return SQLITE_ERROR;
- }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){
- if( pzErrMsg ){
- *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
- }
- sqlite3_free(zErrmsg);
- sqlite3OsDlClose(pVfs, handle);
- return SQLITE_ERROR;
- }
-
- /* Append the new shared library handle to the db->aExtension array. */
- aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
- if( aHandle==0 ){
- return SQLITE_NOMEM;
- }
- if( db->nExtension>0 ){
- memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
- }
- sqlite3DbFree(db, db->aExtension);
- db->aExtension = aHandle;
-
- db->aExtension[db->nExtension++] = handle;
- return SQLITE_OK;
-}
-SQLITE_API int sqlite3_load_extension(
- sqlite3 *db, /* Load the extension into this database connection */
- const char *zFile, /* Name of the shared library containing extension */
- const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
- char **pzErrMsg /* Put error message here if not 0 */
-){
- int rc;
- sqlite3_mutex_enter(db->mutex);
- rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Call this routine when the database connection is closing in order
-** to clean up loaded extensions
-*/
-SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){
- int i;
- assert( sqlite3_mutex_held(db->mutex) );
- for(i=0; i<db->nExtension; i++){
- sqlite3OsDlClose(db->pVfs, db->aExtension[i]);
- }
- sqlite3DbFree(db, db->aExtension);
-}
-
-/*
-** Enable or disable extension loading. Extension loading is disabled by
-** default so as not to open security holes in older applications.
-*/
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
- sqlite3_mutex_enter(db->mutex);
- if( onoff ){
- db->flags |= SQLITE_LoadExtension;
- }else{
- db->flags &= ~SQLITE_LoadExtension;
- }
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-#endif /* SQLITE_OMIT_LOAD_EXTENSION */
-
-/*
-** The auto-extension code added regardless of whether or not extension
-** loading is supported. We need a dummy sqlite3Apis pointer for that
-** code if regular extension loading is not available. This is that
-** dummy pointer.
-*/
-#ifdef SQLITE_OMIT_LOAD_EXTENSION
-static const sqlite3_api_routines sqlite3Apis = { 0 };
-#endif
-
-
-/*
-** The following object holds the list of automatically loaded
-** extensions.
-**
-** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER
-** mutex must be held while accessing this list.
-*/
-typedef struct sqlite3AutoExtList sqlite3AutoExtList;
-static SQLITE_WSD struct sqlite3AutoExtList {
- int nExt; /* Number of entries in aExt[] */
- void (**aExt)(void); /* Pointers to the extension init functions */
-} sqlite3Autoext = { 0, 0 };
-
-/* The "wsdAutoext" macro will resolve to the autoextension
-** state vector. If writable static data is unsupported on the target,
-** we have to locate the state vector at run-time. In the more common
-** case where writable static data is supported, wsdStat can refer directly
-** to the "sqlite3Autoext" state vector declared above.
-*/
-#ifdef SQLITE_OMIT_WSD
-# define wsdAutoextInit \
- sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext)
-# define wsdAutoext x[0]
-#else
-# define wsdAutoextInit
-# define wsdAutoext sqlite3Autoext
-#endif
-
-
-/*
-** Register a statically linked extension that is automatically
-** loaded by every new database connection.
-*/
-SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
- int rc = SQLITE_OK;
-#ifndef SQLITE_OMIT_AUTOINIT
- rc = sqlite3_initialize();
- if( rc ){
- return rc;
- }else
-#endif
- {
- int i;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- wsdAutoextInit;
- sqlite3_mutex_enter(mutex);
- for(i=0; i<wsdAutoext.nExt; i++){
- if( wsdAutoext.aExt[i]==xInit ) break;
- }
- if( i==wsdAutoext.nExt ){
- int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
- void (**aNew)(void);
- aNew = sqlite3_realloc(wsdAutoext.aExt, nByte);
- if( aNew==0 ){
- rc = SQLITE_NOMEM;
- }else{
- wsdAutoext.aExt = aNew;
- wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
- wsdAutoext.nExt++;
- }
- }
- sqlite3_mutex_leave(mutex);
- assert( (rc&0xff)==rc );
- return rc;
- }
-}
-
-/*
-** Reset the automatic extension loading mechanism.
-*/
-SQLITE_API void sqlite3_reset_auto_extension(void){
-#ifndef SQLITE_OMIT_AUTOINIT
- if( sqlite3_initialize()==SQLITE_OK )
-#endif
- {
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- wsdAutoextInit;
- sqlite3_mutex_enter(mutex);
- sqlite3_free(wsdAutoext.aExt);
- wsdAutoext.aExt = 0;
- wsdAutoext.nExt = 0;
- sqlite3_mutex_leave(mutex);
- }
-}
-
-/*
-** Load all automatic extensions.
-**
-** If anything goes wrong, set an error in the database connection.
-*/
-SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
- int i;
- int go = 1;
- int rc;
- int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
-
- wsdAutoextInit;
- if( wsdAutoext.nExt==0 ){
- /* Common case: early out without every having to acquire a mutex */
- return;
- }
- for(i=0; go; i++){
- char *zErrmsg;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-#endif
- sqlite3_mutex_enter(mutex);
- if( i>=wsdAutoext.nExt ){
- xInit = 0;
- go = 0;
- }else{
- xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
- wsdAutoext.aExt[i];
- }
- sqlite3_mutex_leave(mutex);
- zErrmsg = 0;
- if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
- sqlite3Error(db, rc,
- "automatic extension loading failed: %s", zErrmsg);
- go = 0;
- }
- sqlite3_free(zErrmsg);
- }
-}
-
-/************** End of loadext.c *********************************************/
-/************** Begin file pragma.c ******************************************/
-/*
-** 2003 April 6
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code used to implement the PRAGMA command.
-*/
-
-/*
-** Interpret the given string as a safety level. Return 0 for OFF,
-** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
-** unrecognized string argument. The FULL option is disallowed
-** if the omitFull parameter it 1.
-**
-** Note that the values returned are one less that the values that
-** should be passed into sqlite3BtreeSetSafetyLevel(). The is done
-** to support legacy SQL code. The safety level used to be boolean
-** and older scripts may have used numbers 0 for OFF and 1 for ON.
-*/
-static u8 getSafetyLevel(const char *z, int omitFull, int dflt){
- /* 123456789 123456789 */
- static const char zText[] = "onoffalseyestruefull";
- static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16};
- static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4};
- static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2};
- int i, n;
- if( sqlite3Isdigit(*z) ){
- return (u8)sqlite3Atoi(z);
- }
- n = sqlite3Strlen30(z);
- for(i=0; i<ArraySize(iLength)-omitFull; i++){
- if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 ){
- return iValue[i];
- }
- }
- return dflt;
-}
-
-/*
-** Interpret the given string as a boolean value.
-*/
-SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z, int dflt){
- return getSafetyLevel(z,1,dflt)!=0;
-}
-
-/* The sqlite3GetBoolean() function is used by other modules but the
-** remainder of this file is specific to PRAGMA processing. So omit
-** the rest of the file if PRAGMAs are omitted from the build.
-*/
-#if !defined(SQLITE_OMIT_PRAGMA)
-
-/*
-** Interpret the given string as a locking mode value.
-*/
-static int getLockingMode(const char *z){
- if( z ){
- if( 0==sqlite3StrICmp(z, "exclusive") ) return PAGER_LOCKINGMODE_EXCLUSIVE;
- if( 0==sqlite3StrICmp(z, "normal") ) return PAGER_LOCKINGMODE_NORMAL;
- }
- return PAGER_LOCKINGMODE_QUERY;
-}
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
-/*
-** Interpret the given string as an auto-vacuum mode value.
-**
-** The following strings, "none", "full" and "incremental" are
-** acceptable, as are their numeric equivalents: 0, 1 and 2 respectively.
-*/
-static int getAutoVacuum(const char *z){
- int i;
- if( 0==sqlite3StrICmp(z, "none") ) return BTREE_AUTOVACUUM_NONE;
- if( 0==sqlite3StrICmp(z, "full") ) return BTREE_AUTOVACUUM_FULL;
- if( 0==sqlite3StrICmp(z, "incremental") ) return BTREE_AUTOVACUUM_INCR;
- i = sqlite3Atoi(z);
- return (u8)((i>=0&&i<=2)?i:0);
-}
-#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/*
-** Interpret the given string as a temp db location. Return 1 for file
-** backed temporary databases, 2 for the Red-Black tree in memory database
-** and 0 to use the compile-time default.
-*/
-static int getTempStore(const char *z){
- if( z[0]>='0' && z[0]<='2' ){
- return z[0] - '0';
- }else if( sqlite3StrICmp(z, "file")==0 ){
- return 1;
- }else if( sqlite3StrICmp(z, "memory")==0 ){
- return 2;
- }else{
- return 0;
- }
-}
-#endif /* SQLITE_PAGER_PRAGMAS */
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/*
-** Invalidate temp storage, either when the temp storage is changed
-** from default, or when 'file' and the temp_store_directory has changed
-*/
-static int invalidateTempStorage(Parse *pParse){
- sqlite3 *db = pParse->db;
- if( db->aDb[1].pBt!=0 ){
- if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
- sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
- "from within a transaction");
- return SQLITE_ERROR;
- }
- sqlite3BtreeClose(db->aDb[1].pBt);
- db->aDb[1].pBt = 0;
- sqlite3ResetAllSchemasOfConnection(db);
- }
- return SQLITE_OK;
-}
-#endif /* SQLITE_PAGER_PRAGMAS */
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/*
-** If the TEMP database is open, close it and mark the database schema
-** as needing reloading. This must be done when using the SQLITE_TEMP_STORE
-** or DEFAULT_TEMP_STORE pragmas.
-*/
-static int changeTempStorage(Parse *pParse, const char *zStorageType){
- int ts = getTempStore(zStorageType);
- sqlite3 *db = pParse->db;
- if( db->temp_store==ts ) return SQLITE_OK;
- if( invalidateTempStorage( pParse ) != SQLITE_OK ){
- return SQLITE_ERROR;
- }
- db->temp_store = (u8)ts;
- return SQLITE_OK;
-}
-#endif /* SQLITE_PAGER_PRAGMAS */
-
-/*
-** Generate code to return a single integer value.
-*/
-static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
- Vdbe *v = sqlite3GetVdbe(pParse);
- int mem = ++pParse->nMem;
- i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
- if( pI64 ){
- memcpy(pI64, &value, sizeof(value));
- }
- sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
-}
-
-#ifndef SQLITE_OMIT_FLAG_PRAGMAS
-/*
-** Check to see if zRight and zLeft refer to a pragma that queries
-** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
-** Also, implement the pragma.
-*/
-static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
- static const struct sPragmaType {
- const char *zName; /* Name of the pragma */
- int mask; /* Mask for the db->flags value */
- } aPragma[] = {
- { "full_column_names", SQLITE_FullColNames },
- { "short_column_names", SQLITE_ShortColNames },
- { "count_changes", SQLITE_CountRows },
- { "empty_result_callbacks", SQLITE_NullCallback },
- { "legacy_file_format", SQLITE_LegacyFileFmt },
- { "fullfsync", SQLITE_FullFSync },
- { "checkpoint_fullfsync", SQLITE_CkptFullFSync },
- { "reverse_unordered_selects", SQLITE_ReverseOrder },
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
- { "automatic_index", SQLITE_AutoIndex },
-#endif
-#ifdef SQLITE_DEBUG
- { "sql_trace", SQLITE_SqlTrace },
- { "vdbe_listing", SQLITE_VdbeListing },
- { "vdbe_trace", SQLITE_VdbeTrace },
-#endif
-#ifndef SQLITE_OMIT_CHECK
- { "ignore_check_constraints", SQLITE_IgnoreChecks },
-#endif
- /* The following is VERY experimental */
- { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode },
-
- /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
- ** flag if there are any active statements. */
- { "read_uncommitted", SQLITE_ReadUncommitted },
- { "recursive_triggers", SQLITE_RecTriggers },
-
- /* This flag may only be set if both foreign-key and trigger support
- ** are present in the build. */
-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- { "foreign_keys", SQLITE_ForeignKeys },
-#endif
- };
- int i;
- const struct sPragmaType *p;
- for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){
- if( sqlite3StrICmp(zLeft, p->zName)==0 ){
- sqlite3 *db = pParse->db;
- Vdbe *v;
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 ); /* Already allocated by sqlite3Pragma() */
- if( ALWAYS(v) ){
- if( zRight==0 ){
- returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
- }else{
- int mask = p->mask; /* Mask of bits to set or clear. */
- if( db->autoCommit==0 ){
- /* Foreign key support may not be enabled or disabled while not
- ** in auto-commit mode. */
- mask &= ~(SQLITE_ForeignKeys);
- }
-
- if( sqlite3GetBoolean(zRight, 0) ){
- db->flags |= mask;
- }else{
- db->flags &= ~mask;
- }
-
- /* Many of the flag-pragmas modify the code generated by the SQL
- ** compiler (eg. count_changes). So add an opcode to expire all
- ** compiled SQL statements after modifying a pragma value.
- */
- sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
- }
- }
-
- return 1;
- }
- }
- return 0;
-}
-#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
-
-/*
-** Return a human-readable name for a constraint resolution action.
-*/
-#ifndef SQLITE_OMIT_FOREIGN_KEY
-static const char *actionName(u8 action){
- const char *zName;
- switch( action ){
- case OE_SetNull: zName = "SET NULL"; break;
- case OE_SetDflt: zName = "SET DEFAULT"; break;
- case OE_Cascade: zName = "CASCADE"; break;
- case OE_Restrict: zName = "RESTRICT"; break;
- default: zName = "NO ACTION";
- assert( action==OE_None ); break;
- }
- return zName;
-}
-#endif
-
-
-/*
-** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants
-** defined in pager.h. This function returns the associated lowercase
-** journal-mode name.
-*/
-SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){
- static char * const azModeName[] = {
- "delete", "persist", "off", "truncate", "memory"
-#ifndef SQLITE_OMIT_WAL
- , "wal"
-#endif
- };
- assert( PAGER_JOURNALMODE_DELETE==0 );
- assert( PAGER_JOURNALMODE_PERSIST==1 );
- assert( PAGER_JOURNALMODE_OFF==2 );
- assert( PAGER_JOURNALMODE_TRUNCATE==3 );
- assert( PAGER_JOURNALMODE_MEMORY==4 );
- assert( PAGER_JOURNALMODE_WAL==5 );
- assert( eMode>=0 && eMode<=ArraySize(azModeName) );
-
- if( eMode==ArraySize(azModeName) ) return 0;
- return azModeName[eMode];
-}
-
-/*
-** Process a pragma statement.
-**
-** Pragmas are of this form:
-**
-** PRAGMA [database.]id [= value]
-**
-** The identifier might also be a string. The value is a string, and
-** identifier, or a number. If minusFlag is true, then the value is
-** a number that was preceded by a minus sign.
-**
-** If the left side is "database.id" then pId1 is the database name
-** and pId2 is the id. If the left side is just "id" then pId1 is the
-** id and pId2 is any empty string.
-*/
-SQLITE_PRIVATE void sqlite3Pragma(
- Parse *pParse,
- Token *pId1, /* First part of [database.]id field */
- Token *pId2, /* Second part of [database.]id field, or NULL */
- Token *pValue, /* Token for <value>, or NULL */
- int minusFlag /* True if a '-' sign preceded <value> */
-){
- char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */
- char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */
- const char *zDb = 0; /* The database name */
- Token *pId; /* Pointer to <id> token */
- int iDb; /* Database index for <database> */
- char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */
- int rc; /* return value form SQLITE_FCNTL_PRAGMA */
- sqlite3 *db = pParse->db; /* The database connection */
- Db *pDb; /* The specific database being pragmaed */
- Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(db); /* Prepared statement */
-
- if( v==0 ) return;
- sqlite3VdbeRunOnlyOnce(v);
- pParse->nMem = 2;
-
- /* Interpret the [database.] part of the pragma statement. iDb is the
- ** index of the database this pragma is being applied to in db.aDb[]. */
- iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId);
- if( iDb<0 ) return;
- pDb = &db->aDb[iDb];
-
- /* If the temp database has been explicitly named as part of the
- ** pragma, make sure it is open.
- */
- if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){
- return;
- }
-
- zLeft = sqlite3NameFromToken(db, pId);
- if( !zLeft ) return;
- if( minusFlag ){
- zRight = sqlite3MPrintf(db, "-%T", pValue);
- }else{
- zRight = sqlite3NameFromToken(db, pValue);
- }
-
- assert( pId2 );
- zDb = pId2->n>0 ? pDb->zName : 0;
- if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
- goto pragma_out;
- }
-
- /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS
- ** connection. If it returns SQLITE_OK, then assume that the VFS
- ** handled the pragma and generate a no-op prepared statement.
- */
- aFcntl[0] = 0;
- aFcntl[1] = zLeft;
- aFcntl[2] = zRight;
- aFcntl[3] = 0;
- db->busyHandler.nBusy = 0;
- rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
- if( rc==SQLITE_OK ){
- if( aFcntl[0] ){
- int mem = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
- sqlite3_free(aFcntl[0]);
- }
- }else if( rc!=SQLITE_NOTFOUND ){
- if( aFcntl[0] ){
- sqlite3ErrorMsg(pParse, "%s", aFcntl[0]);
- sqlite3_free(aFcntl[0]);
- }
- pParse->nErr++;
- pParse->rc = rc;
- }else
-
-
-#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
- /*
- ** PRAGMA [database.]default_cache_size
- ** PRAGMA [database.]default_cache_size=N
- **
- ** The first form reports the current persistent setting for the
- ** page cache size. The value returned is the maximum number of
- ** pages in the page cache. The second form sets both the current
- ** page cache size value and the persistent page cache size value
- ** stored in the database file.
- **
- ** Older versions of SQLite would set the default cache size to a
- ** negative number to indicate synchronous=OFF. These days, synchronous
- ** is always on by default regardless of the sign of the default cache
- ** size. But continue to take the absolute value of the default cache
- ** size of historical compatibility.
- */
- if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
- static const VdbeOpList getCacheSize[] = {
- { OP_Transaction, 0, 0, 0}, /* 0 */
- { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
- { OP_IfPos, 1, 7, 0},
- { OP_Integer, 0, 2, 0},
- { OP_Subtract, 1, 2, 1},
- { OP_IfPos, 1, 7, 0},
- { OP_Integer, 0, 1, 0}, /* 6 */
- { OP_ResultRow, 1, 1, 0},
- };
- int addr;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3VdbeUsesBtree(v, iDb);
- if( !zRight ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
- pParse->nMem += 2;
- addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
- sqlite3VdbeChangeP1(v, addr, iDb);
- sqlite3VdbeChangeP1(v, addr+1, iDb);
- sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
- }else{
- int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1);
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- pDb->pSchema->cache_size = size;
- sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
- }
- }else
-#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */
-
-#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- /*
- ** PRAGMA [database.]page_size
- ** PRAGMA [database.]page_size=N
- **
- ** The first form reports the current setting for the
- ** database page size in bytes. The second form sets the
- ** database page size value. The value can only be set if
- ** the database has not yet been created.
- */
- if( sqlite3StrICmp(zLeft,"page_size")==0 ){
- Btree *pBt = pDb->pBt;
- assert( pBt!=0 );
- if( !zRight ){
- int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
- returnSingleInt(pParse, "page_size", size);
- }else{
- /* Malloc may fail when setting the page-size, as there is an internal
- ** buffer that the pager module resizes using sqlite3_realloc().
- */
- db->nextPagesize = sqlite3Atoi(zRight);
- if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){
- db->mallocFailed = 1;
- }
- }
- }else
-
- /*
- ** PRAGMA [database.]secure_delete
- ** PRAGMA [database.]secure_delete=ON/OFF
- **
- ** The first form reports the current setting for the
- ** secure_delete flag. The second form changes the secure_delete
- ** flag setting and reports thenew value.
- */
- if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){
- Btree *pBt = pDb->pBt;
- int b = -1;
- assert( pBt!=0 );
- if( zRight ){
- b = sqlite3GetBoolean(zRight, 0);
- }
- if( pId2->n==0 && b>=0 ){
- int ii;
- for(ii=0; ii<db->nDb; ii++){
- sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b);
- }
- }
- b = sqlite3BtreeSecureDelete(pBt, b);
- returnSingleInt(pParse, "secure_delete", b);
- }else
-
- /*
- ** PRAGMA [database.]max_page_count
- ** PRAGMA [database.]max_page_count=N
- **
- ** The first form reports the current setting for the
- ** maximum number of pages in the database file. The
- ** second form attempts to change this setting. Both
- ** forms return the current setting.
- **
- ** The absolute value of N is used. This is undocumented and might
- ** change. The only purpose is to provide an easy way to test
- ** the sqlite3AbsInt32() function.
- **
- ** PRAGMA [database.]page_count
- **
- ** Return the number of pages in the specified database.
- */
- if( sqlite3StrICmp(zLeft,"page_count")==0
- || sqlite3StrICmp(zLeft,"max_page_count")==0
- ){
- int iReg;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3CodeVerifySchema(pParse, iDb);
- iReg = ++pParse->nMem;
- if( sqlite3Tolower(zLeft[0])=='p' ){
- sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
- }else{
- sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg,
- sqlite3AbsInt32(sqlite3Atoi(zRight)));
- }
- sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
- }else
-
- /*
- ** PRAGMA [database.]locking_mode
- ** PRAGMA [database.]locking_mode = (normal|exclusive)
- */
- if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){
- const char *zRet = "normal";
- int eMode = getLockingMode(zRight);
-
- if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){
- /* Simple "PRAGMA locking_mode;" statement. This is a query for
- ** the current default locking mode (which may be different to
- ** the locking-mode of the main database).
- */
- eMode = db->dfltLockMode;
- }else{
- Pager *pPager;
- if( pId2->n==0 ){
- /* This indicates that no database name was specified as part
- ** of the PRAGMA command. In this case the locking-mode must be
- ** set on all attached databases, as well as the main db file.
- **
- ** Also, the sqlite3.dfltLockMode variable is set so that
- ** any subsequently attached databases also use the specified
- ** locking mode.
- */
- int ii;
- assert(pDb==&db->aDb[0]);
- for(ii=2; ii<db->nDb; ii++){
- pPager = sqlite3BtreePager(db->aDb[ii].pBt);
- sqlite3PagerLockingMode(pPager, eMode);
- }
- db->dfltLockMode = (u8)eMode;
- }
- pPager = sqlite3BtreePager(pDb->pBt);
- eMode = sqlite3PagerLockingMode(pPager, eMode);
- }
-
- assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE);
- if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
- zRet = "exclusive";
- }
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }else
-
- /*
- ** PRAGMA [database.]journal_mode
- ** PRAGMA [database.]journal_mode =
- ** (delete|persist|off|truncate|memory|wal|off)
- */
- if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
- int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
- int ii; /* Loop counter */
-
- /* Force the schema to be loaded on all databases. This causes all
- ** database files to be opened and the journal_modes set. This is
- ** necessary because subsequent processing must know if the databases
- ** are in WAL mode. */
- if( sqlite3ReadSchema(pParse) ){
- goto pragma_out;
- }
-
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
-
- if( zRight==0 ){
- /* If there is no "=MODE" part of the pragma, do a query for the
- ** current mode */
- eMode = PAGER_JOURNALMODE_QUERY;
- }else{
- const char *zMode;
- int n = sqlite3Strlen30(zRight);
- for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){
- if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break;
- }
- if( !zMode ){
- /* If the "=MODE" part does not match any known journal mode,
- ** then do a query */
- eMode = PAGER_JOURNALMODE_QUERY;
- }
- }
- if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
- /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */
- iDb = 0;
- pId2->n = 1;
- }
- for(ii=db->nDb-1; ii>=0; ii--){
- if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
- sqlite3VdbeUsesBtree(v, ii);
- sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode);
- }
- }
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }else
-
- /*
- ** PRAGMA [database.]journal_size_limit
- ** PRAGMA [database.]journal_size_limit=N
- **
- ** Get or set the size limit on rollback journal files.
- */
- if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
- Pager *pPager = sqlite3BtreePager(pDb->pBt);
- i64 iLimit = -2;
- if( zRight ){
- sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8);
- if( iLimit<-1 ) iLimit = -1;
- }
- iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
- returnSingleInt(pParse, "journal_size_limit", iLimit);
- }else
-
-#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
-
- /*
- ** PRAGMA [database.]auto_vacuum
- ** PRAGMA [database.]auto_vacuum=N
- **
- ** Get or set the value of the database 'auto-vacuum' parameter.
- ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL
- */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){
- Btree *pBt = pDb->pBt;
- assert( pBt!=0 );
- if( sqlite3ReadSchema(pParse) ){
- goto pragma_out;
- }
- if( !zRight ){
- int auto_vacuum;
- if( ALWAYS(pBt) ){
- auto_vacuum = sqlite3BtreeGetAutoVacuum(pBt);
- }else{
- auto_vacuum = SQLITE_DEFAULT_AUTOVACUUM;
- }
- returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
- }else{
- int eAuto = getAutoVacuum(zRight);
- assert( eAuto>=0 && eAuto<=2 );
- db->nextAutovac = (u8)eAuto;
- if( ALWAYS(eAuto>=0) ){
- /* Call SetAutoVacuum() to set initialize the internal auto and
- ** incr-vacuum flags. This is required in case this connection
- ** creates the database file. It is important that it is created
- ** as an auto-vacuum capable db.
- */
- rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
- if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){
- /* When setting the auto_vacuum mode to either "full" or
- ** "incremental", write the value of meta[6] in the database
- ** file. Before writing to meta[6], check that meta[3] indicates
- ** that this really is an auto-vacuum capable database.
- */
- static const VdbeOpList setMeta6[] = {
- { OP_Transaction, 0, 1, 0}, /* 0 */
- { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
- { OP_If, 1, 0, 0}, /* 2 */
- { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
- { OP_Integer, 0, 1, 0}, /* 4 */
- { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
- };
- int iAddr;
- iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
- sqlite3VdbeChangeP1(v, iAddr, iDb);
- sqlite3VdbeChangeP1(v, iAddr+1, iDb);
- sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
- sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1);
- sqlite3VdbeChangeP1(v, iAddr+5, iDb);
- sqlite3VdbeUsesBtree(v, iDb);
- }
- }
- }
- }else
-#endif
-
- /*
- ** PRAGMA [database.]incremental_vacuum(N)
- **
- ** Do N steps of incremental vacuuming on a database.
- */
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( sqlite3StrICmp(zLeft,"incremental_vacuum")==0 ){
- int iLimit, addr;
- if( sqlite3ReadSchema(pParse) ){
- goto pragma_out;
- }
- if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
- iLimit = 0x7fffffff;
- }
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
- addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb);
- sqlite3VdbeAddOp1(v, OP_ResultRow, 1);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
- sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr);
- sqlite3VdbeJumpHere(v, addr);
- }else
-#endif
-
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
- /*
- ** PRAGMA [database.]cache_size
- ** PRAGMA [database.]cache_size=N
- **
- ** The first form reports the current local setting for the
- ** page cache size. The second form sets the local
- ** page cache size value. If N is positive then that is the
- ** number of pages in the cache. If N is negative, then the
- ** number of pages is adjusted so that the cache uses -N kibibytes
- ** of memory.
- */
- if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- if( !zRight ){
- returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
- }else{
- int size = sqlite3Atoi(zRight);
- pDb->pSchema->cache_size = size;
- sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
- }
- }else
-
- /*
- ** PRAGMA temp_store
- ** PRAGMA temp_store = "default"|"memory"|"file"
- **
- ** Return or set the local value of the temp_store flag. Changing
- ** the local value does not make changes to the disk file and the default
- ** value will be restored the next time the database is opened.
- **
- ** Note that it is possible for the library compile-time options to
- ** override this setting
- */
- if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
- if( !zRight ){
- returnSingleInt(pParse, "temp_store", db->temp_store);
- }else{
- changeTempStorage(pParse, zRight);
- }
- }else
-
- /*
- ** PRAGMA temp_store_directory
- ** PRAGMA temp_store_directory = ""|"directory_name"
- **
- ** Return or set the local value of the temp_store_directory flag. Changing
- ** the value sets a specific directory to be used for temporary files.
- ** Setting to a null string reverts to the default temporary directory search.
- ** If temporary directory is changed, then invalidateTempStorage.
- **
- */
- if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){
- if( !zRight ){
- if( sqlite3_temp_directory ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
- "temp_store_directory", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_temp_directory, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }
- }else{
-#ifndef SQLITE_OMIT_WSD
- if( zRight[0] ){
- int res;
- rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
- if( rc!=SQLITE_OK || res==0 ){
- sqlite3ErrorMsg(pParse, "not a writable directory");
- goto pragma_out;
- }
- }
- if( SQLITE_TEMP_STORE==0
- || (SQLITE_TEMP_STORE==1 && db->temp_store<=1)
- || (SQLITE_TEMP_STORE==2 && db->temp_store==1)
- ){
- invalidateTempStorage(pParse);
- }
- sqlite3_free(sqlite3_temp_directory);
- if( zRight[0] ){
- sqlite3_temp_directory = sqlite3_mprintf("%s", zRight);
- }else{
- sqlite3_temp_directory = 0;
- }
-#endif /* SQLITE_OMIT_WSD */
- }
- }else
-
-#if SQLITE_OS_WIN
- /*
- ** PRAGMA data_store_directory
- ** PRAGMA data_store_directory = ""|"directory_name"
- **
- ** Return or set the local value of the data_store_directory flag. Changing
- ** the value sets a specific directory to be used for database files that
- ** were specified with a relative pathname. Setting to a null string reverts
- ** to the default database directory, which for database files specified with
- ** a relative path will probably be based on the current directory for the
- ** process. Database file specified with an absolute path are not impacted
- ** by this setting, regardless of its value.
- **
- */
- if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){
- if( !zRight ){
- if( sqlite3_data_directory ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
- "data_store_directory", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }
- }else{
-#ifndef SQLITE_OMIT_WSD
- if( zRight[0] ){
- int res;
- rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
- if( rc!=SQLITE_OK || res==0 ){
- sqlite3ErrorMsg(pParse, "not a writable directory");
- goto pragma_out;
- }
- }
- sqlite3_free(sqlite3_data_directory);
- if( zRight[0] ){
- sqlite3_data_directory = sqlite3_mprintf("%s", zRight);
- }else{
- sqlite3_data_directory = 0;
- }
-#endif /* SQLITE_OMIT_WSD */
- }
- }else
-#endif
-
-#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
-# if defined(__APPLE__)
-# define SQLITE_ENABLE_LOCKING_STYLE 1
-# else
-# define SQLITE_ENABLE_LOCKING_STYLE 0
-# endif
-#endif
-#if SQLITE_ENABLE_LOCKING_STYLE
- /*
- ** PRAGMA [database.]lock_proxy_file
- ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path"
- **
- ** Return or set the value of the lock_proxy_file flag. Changing
- ** the value sets a specific file to be used for database access locks.
- **
- */
- if( sqlite3StrICmp(zLeft, "lock_proxy_file")==0 ){
- if( !zRight ){
- Pager *pPager = sqlite3BtreePager(pDb->pBt);
- char *proxy_file_path = NULL;
- sqlite3_file *pFile = sqlite3PagerFile(pPager);
- sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE,
- &proxy_file_path);
-
- if( proxy_file_path ){
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
- "lock_proxy_file", SQLITE_STATIC);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, proxy_file_path, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }
- }else{
- Pager *pPager = sqlite3BtreePager(pDb->pBt);
- sqlite3_file *pFile = sqlite3PagerFile(pPager);
- int res;
- if( zRight[0] ){
- res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
- zRight);
- } else {
- res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE,
- NULL);
- }
- if( res!=SQLITE_OK ){
- sqlite3ErrorMsg(pParse, "failed to set lock proxy file");
- goto pragma_out;
- }
- }
- }else
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-
- /*
- ** PRAGMA [database.]synchronous
- ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL
- **
- ** Return or set the local value of the synchronous flag. Changing
- ** the local value does not make changes to the disk file and the
- ** default value will be restored the next time the database is
- ** opened.
- */
- if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- if( !zRight ){
- returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
- }else{
- if( !db->autoCommit ){
- sqlite3ErrorMsg(pParse,
- "Safety level may not be changed inside a transaction");
- }else{
- pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
- }
- }
- }else
-#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
-
-#ifndef SQLITE_OMIT_FLAG_PRAGMAS
- if( flagPragma(pParse, zLeft, zRight) ){
- /* The flagPragma() subroutine also generates any necessary code
- ** there is nothing more to do here */
- }else
-#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
-
-#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
- /*
- ** PRAGMA table_info(<table>)
- **
- ** Return a single row for each column of the named table. The columns of
- ** the returned data set are:
- **
- ** cid: Column id (numbered from left to right, starting at 0)
- ** name: Column name
- ** type: Column declaration type.
- ** notnull: True if 'NOT NULL' is part of column declaration
- ** dflt_value: The default value for the column, if any.
- */
- if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
- Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pTab = sqlite3FindTable(db, zRight, zDb);
- if( pTab ){
- int i;
- int nHidden = 0;
- Column *pCol;
- sqlite3VdbeSetNumCols(v, 6);
- pParse->nMem = 6;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", SQLITE_STATIC);
- sqlite3ViewGetColumnNames(pParse, pTab);
- for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
- if( IsHiddenColumn(pCol) ){
- nHidden++;
- continue;
- }
- sqlite3VdbeAddOp2(v, OP_Integer, i-nHidden, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pCol->zName, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- pCol->zType ? pCol->zType : "", 0);
- sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
- if( pCol->zDflt ){
- sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
- }
- sqlite3VdbeAddOp2(v, OP_Integer,
- (pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
- }
- }
- }else
-
- if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
- Index *pIdx;
- Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pIdx = sqlite3FindIndex(db, zRight, zDb);
- if( pIdx ){
- int i;
- pTab = pIdx->pTable;
- sqlite3VdbeSetNumCols(v, 3);
- pParse->nMem = 3;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
- for(i=0; i<pIdx->nColumn; i++){
- int cnum = pIdx->aiColumn[i];
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
- assert( pTab->nCol>cnum );
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
- }
- }
- }else
-
- if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
- Index *pIdx;
- Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pTab = sqlite3FindTable(db, zRight, zDb);
- if( pTab ){
- v = sqlite3GetVdbe(pParse);
- pIdx = pTab->pIndex;
- if( pIdx ){
- int i = 0;
- sqlite3VdbeSetNumCols(v, 3);
- pParse->nMem = 3;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
- while(pIdx){
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
- ++i;
- pIdx = pIdx->pNext;
- }
- }
- }
- }else
-
- if( sqlite3StrICmp(zLeft, "database_list")==0 ){
- int i;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3VdbeSetNumCols(v, 3);
- pParse->nMem = 3;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", SQLITE_STATIC);
- for(i=0; i<db->nDb; i++){
- if( db->aDb[i].pBt==0 ) continue;
- assert( db->aDb[i].zName!=0 );
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, db->aDb[i].zName, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
- }
- }else
-
- if( sqlite3StrICmp(zLeft, "collation_list")==0 ){
- int i = 0;
- HashElem *p;
- sqlite3VdbeSetNumCols(v, 2);
- pParse->nMem = 2;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
- CollSeq *pColl = (CollSeq *)sqliteHashData(p);
- sqlite3VdbeAddOp2(v, OP_Integer, i++, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
- }
- }else
-#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
-
-#ifndef SQLITE_OMIT_FOREIGN_KEY
- if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
- FKey *pFK;
- Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pTab = sqlite3FindTable(db, zRight, zDb);
- if( pTab ){
- v = sqlite3GetVdbe(pParse);
- pFK = pTab->pFKey;
- if( pFK ){
- int i = 0;
- sqlite3VdbeSetNumCols(v, 8);
- pParse->nMem = 8;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "on_update", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 6, COLNAME_NAME, "on_delete", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 7, COLNAME_NAME, "match", SQLITE_STATIC);
- while(pFK){
- int j;
- for(j=0; j<pFK->nCol; j++){
- char *zCol = pFK->aCol[j].zCol;
- char *zOnDelete = (char *)actionName(pFK->aAction[0]);
- char *zOnUpdate = (char *)actionName(pFK->aAction[1]);
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, j, 2);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0,
- pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
- sqlite3VdbeAddOp4(v, zCol ? OP_String8 : OP_Null, 0, 5, 0, zCol, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 6, 0, zOnUpdate, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 7, 0, zOnDelete, 0);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 8, 0, "NONE", 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 8);
- }
- ++i;
- pFK = pFK->pNextFrom;
- }
- }
- }
- }else
-#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
-
-#ifndef NDEBUG
- if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
- if( zRight ){
- if( sqlite3GetBoolean(zRight, 0) ){
- sqlite3ParserTrace(stderr, "parser: ");
- }else{
- sqlite3ParserTrace(0, 0);
- }
- }
- }else
-#endif
-
- /* Reinstall the LIKE and GLOB functions. The variant of LIKE
- ** used will be case sensitive or not depending on the RHS.
- */
- if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){
- if( zRight ){
- sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
- }
- }else
-
-#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
-# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
-#endif
-
-#ifndef SQLITE_OMIT_INTEGRITY_CHECK
- /* Pragma "quick_check" is an experimental reduced version of
- ** integrity_check designed to detect most database corruption
- ** without most of the overhead of a full integrity-check.
- */
- if( sqlite3StrICmp(zLeft, "integrity_check")==0
- || sqlite3StrICmp(zLeft, "quick_check")==0
- ){
- int i, j, addr, mxErr;
-
- /* Code that appears at the end of the integrity check. If no error
- ** messages have been generated, output OK. Otherwise output the
- ** error message
- */
- static const VdbeOpList endCode[] = {
- { OP_AddImm, 1, 0, 0}, /* 0 */
- { OP_IfNeg, 1, 0, 0}, /* 1 */
- { OP_String8, 0, 3, 0}, /* 2 */
- { OP_ResultRow, 3, 1, 0},
- };
-
- int isQuick = (sqlite3Tolower(zLeft[0])=='q');
-
- /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check",
- ** then iDb is set to the index of the database identified by <db>.
- ** In this case, the integrity of database iDb only is verified by
- ** the VDBE created below.
- **
- ** Otherwise, if the command was simply "PRAGMA integrity_check" (or
- ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb
- ** to -1 here, to indicate that the VDBE should verify the integrity
- ** of all attached databases. */
- assert( iDb>=0 );
- assert( iDb==0 || pId2->z );
- if( pId2->z==0 ) iDb = -1;
-
- /* Initialize the VDBE program */
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- pParse->nMem = 6;
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
-
- /* Set the maximum error count */
- mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
- if( zRight ){
- sqlite3GetInt32(zRight, &mxErr);
- if( mxErr<=0 ){
- mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
- }
- }
- sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */
-
- /* Do an integrity check on each database file */
- for(i=0; i<db->nDb; i++){
- HashElem *x;
- Hash *pTbls;
- int cnt = 0;
-
- if( OMIT_TEMPDB && i==1 ) continue;
- if( iDb>=0 && i!=iDb ) continue;
-
- sqlite3CodeVerifySchema(pParse, i);
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
-
- /* Do an integrity check of the B-Tree
- **
- ** Begin by filling registers 2, 3, ... with the root pages numbers
- ** for all tables and indices in the database.
- */
- assert( sqlite3SchemaMutexHeld(db, i, 0) );
- pTbls = &db->aDb[i].pSchema->tblHash;
- for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
- Table *pTab = sqliteHashData(x);
- Index *pIdx;
- sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
- cnt++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
- cnt++;
- }
- }
-
- /* Make sure sufficient number of registers have been allocated */
- if( pParse->nMem < cnt+4 ){
- pParse->nMem = cnt+4;
- }
-
- /* Do the b-tree integrity checks */
- sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
- sqlite3VdbeChangeP5(v, (u8)i);
- addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
- P4_DYNAMIC);
- sqlite3VdbeAddOp2(v, OP_Move, 2, 4);
- sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
- sqlite3VdbeJumpHere(v, addr);
-
- /* Make sure all the indices are constructed correctly.
- */
- for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
- Table *pTab = sqliteHashData(x);
- Index *pIdx;
- int loopTop;
-
- if( pTab->pIndex==0 ) continue;
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
- sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, 2); /* reg(2) will count entries */
- loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
- sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- int jmp2;
- int r1;
- static const VdbeOpList idxErr[] = {
- { OP_AddImm, 1, -1, 0},
- { OP_String8, 0, 3, 0}, /* 1 */
- { OP_Rowid, 1, 4, 0},
- { OP_String8, 0, 5, 0}, /* 3 */
- { OP_String8, 0, 6, 0}, /* 4 */
- { OP_Concat, 4, 3, 3},
- { OP_Concat, 5, 3, 3},
- { OP_Concat, 6, 3, 3},
- { OP_ResultRow, 3, 1, 0},
- { OP_IfPos, 1, 0, 0}, /* 9 */
- { OP_Halt, 0, 0, 0},
- };
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);
- jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
- addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
- sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
- sqlite3VdbeJumpHere(v, addr+9);
- sqlite3VdbeJumpHere(v, jmp2);
- }
- sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
- sqlite3VdbeJumpHere(v, loopTop);
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- static const VdbeOpList cntIdx[] = {
- { OP_Integer, 0, 3, 0},
- { OP_Rewind, 0, 0, 0}, /* 1 */
- { OP_AddImm, 3, 1, 0},
- { OP_Next, 0, 0, 0}, /* 3 */
- { OP_Eq, 2, 0, 3}, /* 4 */
- { OP_AddImm, 1, -1, 0},
- { OP_String8, 0, 2, 0}, /* 6 */
- { OP_String8, 0, 3, 0}, /* 7 */
- { OP_Concat, 3, 2, 2},
- { OP_ResultRow, 2, 1, 0},
- };
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
- addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
- sqlite3VdbeChangeP1(v, addr+1, j+2);
- sqlite3VdbeChangeP2(v, addr+1, addr+4);
- sqlite3VdbeChangeP1(v, addr+3, j+2);
- sqlite3VdbeChangeP2(v, addr+3, addr+2);
- sqlite3VdbeJumpHere(v, addr+4);
- sqlite3VdbeChangeP4(v, addr+6,
- "wrong # of entries in index ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT);
- }
- }
- }
- addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
- sqlite3VdbeChangeP2(v, addr, -mxErr);
- sqlite3VdbeJumpHere(v, addr+1);
- sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
- }else
-#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
-
-#ifndef SQLITE_OMIT_UTF16
- /*
- ** PRAGMA encoding
- ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be"
- **
- ** In its first form, this pragma returns the encoding of the main
- ** database. If the database is not initialized, it is initialized now.
- **
- ** The second form of this pragma is a no-op if the main database file
- ** has not already been initialized. In this case it sets the default
- ** encoding that will be used for the main database file if a new file
- ** is created. If an existing main database file is opened, then the
- ** default text encoding for the existing database is used.
- **
- ** In all cases new databases created using the ATTACH command are
- ** created to use the same default text encoding as the main database. If
- ** the main database has not been initialized and/or created when ATTACH
- ** is executed, this is done before the ATTACH operation.
- **
- ** In the second form this pragma sets the text encoding to be used in
- ** new database files created using this database handle. It is only
- ** useful if invoked immediately after the main database i
- */
- if( sqlite3StrICmp(zLeft, "encoding")==0 ){
- static const struct EncName {
- char *zName;
- u8 enc;
- } encnames[] = {
- { "UTF8", SQLITE_UTF8 },
- { "UTF-8", SQLITE_UTF8 }, /* Must be element [1] */
- { "UTF-16le", SQLITE_UTF16LE }, /* Must be element [2] */
- { "UTF-16be", SQLITE_UTF16BE }, /* Must be element [3] */
- { "UTF16le", SQLITE_UTF16LE },
- { "UTF16be", SQLITE_UTF16BE },
- { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */
- { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */
- { 0, 0 }
- };
- const struct EncName *pEnc;
- if( !zRight ){ /* "PRAGMA encoding" */
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", SQLITE_STATIC);
- sqlite3VdbeAddOp2(v, OP_String8, 0, 1);
- assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
- assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
- assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
- sqlite3VdbeChangeP4(v, -1, encnames[ENC(pParse->db)].zName, P4_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }else{ /* "PRAGMA encoding = XXX" */
- /* Only change the value of sqlite.enc if the database handle is not
- ** initialized. If the main database exists, the new sqlite.enc value
- ** will be overwritten when the schema is next loaded. If it does not
- ** already exists, it will be created to use the new encoding value.
- */
- if(
- !(DbHasProperty(db, 0, DB_SchemaLoaded)) ||
- DbHasProperty(db, 0, DB_Empty)
- ){
- for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
- if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
- ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
- break;
- }
- }
- if( !pEnc->zName ){
- sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight);
- }
- }
- }
- }else
-#endif /* SQLITE_OMIT_UTF16 */
-
-#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
- /*
- ** PRAGMA [database.]schema_version
- ** PRAGMA [database.]schema_version = <integer>
- **
- ** PRAGMA [database.]user_version
- ** PRAGMA [database.]user_version = <integer>
- **
- ** The pragma's schema_version and user_version are used to set or get
- ** the value of the schema-version and user-version, respectively. Both
- ** the schema-version and the user-version are 32-bit signed integers
- ** stored in the database header.
- **
- ** The schema-cookie is usually only manipulated internally by SQLite. It
- ** is incremented by SQLite whenever the database schema is modified (by
- ** creating or dropping a table or index). The schema version is used by
- ** SQLite each time a query is executed to ensure that the internal cache
- ** of the schema used when compiling the SQL query matches the schema of
- ** the database against which the compiled query is actually executed.
- ** Subverting this mechanism by using "PRAGMA schema_version" to modify
- ** the schema-version is potentially dangerous and may lead to program
- ** crashes or database corruption. Use with caution!
- **
- ** The user-version is not used internally by SQLite. It may be used by
- ** applications for any purpose.
- */
- if( sqlite3StrICmp(zLeft, "schema_version")==0
- || sqlite3StrICmp(zLeft, "user_version")==0
- || sqlite3StrICmp(zLeft, "freelist_count")==0
- ){
- int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
- sqlite3VdbeUsesBtree(v, iDb);
- switch( zLeft[0] ){
- case 'f': case 'F':
- iCookie = BTREE_FREE_PAGE_COUNT;
- break;
- case 's': case 'S':
- iCookie = BTREE_SCHEMA_VERSION;
- break;
- default:
- iCookie = BTREE_USER_VERSION;
- break;
- }
-
- if( zRight && iCookie!=BTREE_FREE_PAGE_COUNT ){
- /* Write the specified cookie value */
- static const VdbeOpList setCookie[] = {
- { OP_Transaction, 0, 1, 0}, /* 0 */
- { OP_Integer, 0, 1, 0}, /* 1 */
- { OP_SetCookie, 0, 0, 1}, /* 2 */
- };
- int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
- sqlite3VdbeChangeP1(v, addr, iDb);
- sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight));
- sqlite3VdbeChangeP1(v, addr+2, iDb);
- sqlite3VdbeChangeP2(v, addr+2, iCookie);
- }else{
- /* Read the specified cookie value */
- static const VdbeOpList readCookie[] = {
- { OP_Transaction, 0, 0, 0}, /* 0 */
- { OP_ReadCookie, 0, 1, 0}, /* 1 */
- { OP_ResultRow, 1, 1, 0}
- };
- int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
- sqlite3VdbeChangeP1(v, addr, iDb);
- sqlite3VdbeChangeP1(v, addr+1, iDb);
- sqlite3VdbeChangeP3(v, addr+1, iCookie);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
- }
- }else
-#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
-
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
- /*
- ** PRAGMA compile_options
- **
- ** Return the names of all compile-time options used in this build,
- ** one option per row.
- */
- if( sqlite3StrICmp(zLeft, "compile_options")==0 ){
- int i = 0;
- const char *zOpt;
- sqlite3VdbeSetNumCols(v, 1);
- pParse->nMem = 1;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "compile_option", SQLITE_STATIC);
- while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }
- }else
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
-
-#ifndef SQLITE_OMIT_WAL
- /*
- ** PRAGMA [database.]wal_checkpoint = passive|full|restart
- **
- ** Checkpoint the database.
- */
- if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){
- int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
- int eMode = SQLITE_CHECKPOINT_PASSIVE;
- if( zRight ){
- if( sqlite3StrICmp(zRight, "full")==0 ){
- eMode = SQLITE_CHECKPOINT_FULL;
- }else if( sqlite3StrICmp(zRight, "restart")==0 ){
- eMode = SQLITE_CHECKPOINT_RESTART;
- }
- }
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
- sqlite3VdbeSetNumCols(v, 3);
- pParse->nMem = 3;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "log", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "checkpointed", SQLITE_STATIC);
-
- sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
- }else
-
- /*
- ** PRAGMA wal_autocheckpoint
- ** PRAGMA wal_autocheckpoint = N
- **
- ** Configure a database connection to automatically checkpoint a database
- ** after accumulating N frames in the log. Or query for the current value
- ** of N.
- */
- if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){
- if( zRight ){
- sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
- }
- returnSingleInt(pParse, "wal_autocheckpoint",
- db->xWalCallback==sqlite3WalDefaultHook ?
- SQLITE_PTR_TO_INT(db->pWalArg) : 0);
- }else
-#endif
-
- /*
- ** PRAGMA shrink_memory
- **
- ** This pragma attempts to free as much memory as possible from the
- ** current database connection.
- */
- if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){
- sqlite3_db_release_memory(db);
- }else
-
- /*
- ** PRAGMA busy_timeout
- ** PRAGMA busy_timeout = N
- **
- ** Call sqlite3_busy_timeout(db, N). Return the current timeout value
- ** if one is set. If no busy handler or a different busy handler is set
- ** then 0 is returned. Setting the busy_timeout to 0 or negative
- ** disables the timeout.
- */
- if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){
- if( zRight ){
- sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
- }
- returnSingleInt(pParse, "timeout", db->busyTimeout);
- }else
-
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
- /*
- ** Report the current state of file logs for all databases
- */
- if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
- static const char *const azLockName[] = {
- "unlocked", "shared", "reserved", "pending", "exclusive"
- };
- int i;
- sqlite3VdbeSetNumCols(v, 2);
- pParse->nMem = 2;
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC);
- for(i=0; i<db->nDb; i++){
- Btree *pBt;
- const char *zState = "unknown";
- int j;
- if( db->aDb[i].zName==0 ) continue;
- sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC);
- pBt = db->aDb[i].pBt;
- if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
- zState = "closed";
- }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0,
- SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
- zState = azLockName[j];
- }
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
- }
-
- }else
-#endif
-
-#ifdef SQLITE_HAS_CODEC
- if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){
- sqlite3_key(db, zRight, sqlite3Strlen30(zRight));
- }else
- if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){
- sqlite3_rekey(db, zRight, sqlite3Strlen30(zRight));
- }else
- if( zRight && (sqlite3StrICmp(zLeft, "hexkey")==0 ||
- sqlite3StrICmp(zLeft, "hexrekey")==0) ){
- int i, h1, h2;
- char zKey[40];
- for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){
- h1 += 9*(1&(h1>>6));
- h2 += 9*(1&(h2>>6));
- zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4);
- }
- if( (zLeft[3] & 0xf)==0xb ){
- sqlite3_key(db, zKey, i/2);
- }else{
- sqlite3_rekey(db, zKey, i/2);
- }
- }else
-#endif
-#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
- if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){
-#ifdef SQLITE_HAS_CODEC
- if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
- sqlite3_activate_see(&zRight[4]);
- }
-#endif
-#ifdef SQLITE_ENABLE_CEROD
- if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
- sqlite3_activate_cerod(&zRight[6]);
- }
-#endif
- }else
-#endif
-
-
- {/* Empty ELSE clause */}
-
- /*
- ** Reset the safety level, in case the fullfsync flag or synchronous
- ** setting changed.
- */
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
- if( db->autoCommit ){
- sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
- (db->flags&SQLITE_FullFSync)!=0,
- (db->flags&SQLITE_CkptFullFSync)!=0);
- }
-#endif
-pragma_out:
- sqlite3DbFree(db, zLeft);
- sqlite3DbFree(db, zRight);
-}
-
-#endif /* SQLITE_OMIT_PRAGMA */
-
-/************** End of pragma.c **********************************************/
-/************** Begin file prepare.c *****************************************/
-/*
-** 2005 May 25
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the implementation of the sqlite3_prepare()
-** interface, and routines that contribute to loading the database schema
-** from disk.
-*/
-
-/*
-** Fill the InitData structure with an error message that indicates
-** that the database is corrupt.
-*/
-static void corruptSchema(
- InitData *pData, /* Initialization context */
- const char *zObj, /* Object being parsed at the point of error */
- const char *zExtra /* Error information */
-){
- sqlite3 *db = pData->db;
- if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
- if( zObj==0 ) zObj = "?";
- sqlite3SetString(pData->pzErrMsg, db,
- "malformed database schema (%s)", zObj);
- if( zExtra ){
- *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg,
- "%s - %s", *pData->pzErrMsg, zExtra);
- }
- }
- pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
-}
-
-/*
-** This is the callback routine for the code that initializes the
-** database. See sqlite3Init() below for additional information.
-** This routine is also called from the OP_ParseSchema opcode of the VDBE.
-**
-** Each callback contains the following information:
-**
-** argv[0] = name of thing being created
-** argv[1] = root page number for table or index. 0 for trigger or view.
-** argv[2] = SQL text for the CREATE statement.
-**
-*/
-SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
- InitData *pData = (InitData*)pInit;
- sqlite3 *db = pData->db;
- int iDb = pData->iDb;
-
- assert( argc==3 );
- UNUSED_PARAMETER2(NotUsed, argc);
- assert( sqlite3_mutex_held(db->mutex) );
- DbClearProperty(db, iDb, DB_Empty);
- if( db->mallocFailed ){
- corruptSchema(pData, argv[0], 0);
- return 1;
- }
-
- assert( iDb>=0 && iDb<db->nDb );
- if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
- if( argv[1]==0 ){
- corruptSchema(pData, argv[0], 0);
- }else if( argv[2] && argv[2][0] ){
- /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
- ** But because db->init.busy is set to 1, no VDBE code is generated
- ** or executed. All the parser does is build the internal data
- ** structures that describe the table, index, or view.
- */
- int rc;
- sqlite3_stmt *pStmt;
- TESTONLY(int rcp); /* Return code from sqlite3_prepare() */
-
- assert( db->init.busy );
- db->init.iDb = iDb;
- db->init.newTnum = sqlite3Atoi(argv[1]);
- db->init.orphanTrigger = 0;
- TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
- rc = db->errCode;
- assert( (rc&0xFF)==(rcp&0xFF) );
- db->init.iDb = 0;
- if( SQLITE_OK!=rc ){
- if( db->init.orphanTrigger ){
- assert( iDb==1 );
- }else{
- pData->rc = rc;
- if( rc==SQLITE_NOMEM ){
- db->mallocFailed = 1;
- }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
- corruptSchema(pData, argv[0], sqlite3_errmsg(db));
- }
- }
- }
- sqlite3_finalize(pStmt);
- }else if( argv[0]==0 ){
- corruptSchema(pData, 0, 0);
- }else{
- /* If the SQL column is blank it means this is an index that
- ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
- ** constraint for a CREATE TABLE. The index should have already
- ** been created when we processed the CREATE TABLE. All we have
- ** to do here is record the root page number for that index.
- */
- Index *pIndex;
- pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
- if( pIndex==0 ){
- /* This can occur if there exists an index on a TEMP table which
- ** has the same name as another index on a permanent index. Since
- ** the permanent table is hidden by the TEMP table, we can also
- ** safely ignore the index on the permanent table.
- */
- /* Do Nothing */;
- }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){
- corruptSchema(pData, argv[0], "invalid rootpage");
- }
- }
- return 0;
-}
-
-/*
-** Attempt to read the database schema and initialize internal
-** data structures for a single database file. The index of the
-** database file is given by iDb. iDb==0 is used for the main
-** database. iDb==1 should never be used. iDb>=2 is used for
-** auxiliary databases. Return one of the SQLITE_ error codes to
-** indicate success or failure.
-*/
-static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
- int rc;
- int i;
-#ifndef SQLITE_OMIT_DEPRECATED
- int size;
-#endif
- Table *pTab;
- Db *pDb;
- char const *azArg[4];
- int meta[5];
- InitData initData;
- char const *zMasterSchema;
- char const *zMasterName;
- int openedTransaction = 0;
-
- /*
- ** The master database table has a structure like this
- */
- static const char master_schema[] =
- "CREATE TABLE sqlite_master(\n"
- " type text,\n"
- " name text,\n"
- " tbl_name text,\n"
- " rootpage integer,\n"
- " sql text\n"
- ")"
- ;
-#ifndef SQLITE_OMIT_TEMPDB
- static const char temp_master_schema[] =
- "CREATE TEMP TABLE sqlite_temp_master(\n"
- " type text,\n"
- " name text,\n"
- " tbl_name text,\n"
- " rootpage integer,\n"
- " sql text\n"
- ")"
- ;
-#else
- #define temp_master_schema 0
-#endif
-
- assert( iDb>=0 && iDb<db->nDb );
- assert( db->aDb[iDb].pSchema );
- assert( sqlite3_mutex_held(db->mutex) );
- assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
-
- /* zMasterSchema and zInitScript are set to point at the master schema
- ** and initialisation script appropriate for the database being
- ** initialised. zMasterName is the name of the master table.
- */
- if( !OMIT_TEMPDB && iDb==1 ){
- zMasterSchema = temp_master_schema;
- }else{
- zMasterSchema = master_schema;
- }
- zMasterName = SCHEMA_TABLE(iDb);
-
- /* Construct the schema tables. */
- azArg[0] = zMasterName;
- azArg[1] = "1";
- azArg[2] = zMasterSchema;
- azArg[3] = 0;
- initData.db = db;
- initData.iDb = iDb;
- initData.rc = SQLITE_OK;
- initData.pzErrMsg = pzErrMsg;
- sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
- if( initData.rc ){
- rc = initData.rc;
- goto error_out;
- }
- pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName);
- if( ALWAYS(pTab) ){
- pTab->tabFlags |= TF_Readonly;
- }
-
- /* Create a cursor to hold the database open
- */
- pDb = &db->aDb[iDb];
- if( pDb->pBt==0 ){
- if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){
- DbSetProperty(db, 1, DB_SchemaLoaded);
- }
- return SQLITE_OK;
- }
-
- /* If there is not already a read-only (or read-write) transaction opened
- ** on the b-tree database, open one now. If a transaction is opened, it
- ** will be closed before this function returns. */
- sqlite3BtreeEnter(pDb->pBt);
- if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
- rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
- if( rc!=SQLITE_OK ){
- sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto initone_error_out;
- }
- openedTransaction = 1;
- }
-
- /* Get the database meta information.
- **
- ** Meta values are as follows:
- ** meta[0] Schema cookie. Changes with each schema change.
- ** meta[1] File format of schema layer.
- ** meta[2] Size of the page cache.
- ** meta[3] Largest rootpage (auto/incr_vacuum mode)
- ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE
- ** meta[5] User version
- ** meta[6] Incremental vacuum mode
- ** meta[7] unused
- ** meta[8] unused
- ** meta[9] unused
- **
- ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
- ** the possible values of meta[4].
- */
- for(i=0; i<ArraySize(meta); i++){
- sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
- }
- pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
-
- /* If opening a non-empty database, check the text encoding. For the
- ** main database, set sqlite3.enc to the encoding of the main database.
- ** For an attached db, it is an error if the encoding is not the same
- ** as sqlite3.enc.
- */
- if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
- if( iDb==0 ){
- u8 encoding;
- /* If opening the main database, set ENC(db). */
- encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
- if( encoding==0 ) encoding = SQLITE_UTF8;
- ENC(db) = encoding;
- }else{
- /* If opening an attached database, the encoding much match ENC(db) */
- if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
- sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
- " text encoding as main database");
- rc = SQLITE_ERROR;
- goto initone_error_out;
- }
- }
- }else{
- DbSetProperty(db, iDb, DB_Empty);
- }
- pDb->pSchema->enc = ENC(db);
-
- if( pDb->pSchema->cache_size==0 ){
-#ifndef SQLITE_OMIT_DEPRECATED
- size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]);
- if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
- pDb->pSchema->cache_size = size;
-#else
- pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE;
-#endif
- sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
- }
-
- /*
- ** file_format==1 Version 3.0.0.
- ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN
- ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults
- ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants
- */
- pDb->pSchema->file_format = (u8)meta[BTREE_FILE_FORMAT-1];
- if( pDb->pSchema->file_format==0 ){
- pDb->pSchema->file_format = 1;
- }
- if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
- sqlite3SetString(pzErrMsg, db, "unsupported file format");
- rc = SQLITE_ERROR;
- goto initone_error_out;
- }
-
- /* Ticket #2804: When we open a database in the newer file format,
- ** clear the legacy_file_format pragma flag so that a VACUUM will
- ** not downgrade the database and thus invalidate any descending
- ** indices that the user might have created.
- */
- if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){
- db->flags &= ~SQLITE_LegacyFileFmt;
- }
-
- /* Read the schema information out of the schema tables
- */
- assert( db->init.busy );
- {
- char *zSql;
- zSql = sqlite3MPrintf(db,
- "SELECT name, rootpage, sql FROM '%q'.%s ORDER BY rowid",
- db->aDb[iDb].zName, zMasterName);
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
- xAuth = db->xAuth;
- db->xAuth = 0;
-#endif
- rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
-#ifndef SQLITE_OMIT_AUTHORIZATION
- db->xAuth = xAuth;
- }
-#endif
- if( rc==SQLITE_OK ) rc = initData.rc;
- sqlite3DbFree(db, zSql);
-#ifndef SQLITE_OMIT_ANALYZE
- if( rc==SQLITE_OK ){
- sqlite3AnalysisLoad(db, iDb);
- }
-#endif
- }
- if( db->mallocFailed ){
- rc = SQLITE_NOMEM;
- sqlite3ResetAllSchemasOfConnection(db);
- }
- if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
- /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
- ** the schema loaded, even if errors occurred. In this situation the
- ** current sqlite3_prepare() operation will fail, but the following one
- ** will attempt to compile the supplied statement against whatever subset
- ** of the schema was loaded before the error occurred. The primary
- ** purpose of this is to allow access to the sqlite_master table
- ** even when its contents have been corrupted.
- */
- DbSetProperty(db, iDb, DB_SchemaLoaded);
- rc = SQLITE_OK;
- }
-
- /* Jump here for an error that occurs after successfully allocating
- ** curMain and calling sqlite3BtreeEnter(). For an error that occurs
- ** before that point, jump to error_out.
- */
-initone_error_out:
- if( openedTransaction ){
- sqlite3BtreeCommit(pDb->pBt);
- }
- sqlite3BtreeLeave(pDb->pBt);
-
-error_out:
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- db->mallocFailed = 1;
- }
- return rc;
-}
-
-/*
-** Initialize all database files - the main database file, the file
-** used to store temporary tables, and any additional database files
-** created using ATTACH statements. Return a success code. If an
-** error occurs, write an error message into *pzErrMsg.
-**
-** After a database is initialized, the DB_SchemaLoaded bit is set
-** bit is set in the flags field of the Db structure. If the database
-** file was of zero-length, then the DB_Empty flag is also set.
-*/
-SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
- int i, rc;
- int commit_internal = !(db->flags&SQLITE_InternChanges);
-
- assert( sqlite3_mutex_held(db->mutex) );
- rc = SQLITE_OK;
- db->init.busy = 1;
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
- rc = sqlite3InitOne(db, i, pzErrMsg);
- if( rc ){
- sqlite3ResetOneSchema(db, i);
- }
- }
-
- /* Once all the other databases have been initialised, load the schema
- ** for the TEMP database. This is loaded last, as the TEMP database
- ** schema may contain references to objects in other databases.
- */
-#ifndef SQLITE_OMIT_TEMPDB
- if( rc==SQLITE_OK && ALWAYS(db->nDb>1)
- && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
- rc = sqlite3InitOne(db, 1, pzErrMsg);
- if( rc ){
- sqlite3ResetOneSchema(db, 1);
- }
- }
-#endif
-
- db->init.busy = 0;
- if( rc==SQLITE_OK && commit_internal ){
- sqlite3CommitInternalChanges(db);
- }
-
- return rc;
-}
-
-/*
-** This routine is a no-op if the database schema is already initialised.
-** Otherwise, the schema is loaded. An error code is returned.
-*/
-SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){
- int rc = SQLITE_OK;
- sqlite3 *db = pParse->db;
- assert( sqlite3_mutex_held(db->mutex) );
- if( !db->init.busy ){
- rc = sqlite3Init(db, &pParse->zErrMsg);
- }
- if( rc!=SQLITE_OK ){
- pParse->rc = rc;
- pParse->nErr++;
- }
- return rc;
-}
-
-
-/*
-** Check schema cookies in all databases. If any cookie is out
-** of date set pParse->rc to SQLITE_SCHEMA. If all schema cookies
-** make no changes to pParse->rc.
-*/
-static void schemaIsValid(Parse *pParse){
- sqlite3 *db = pParse->db;
- int iDb;
- int rc;
- int cookie;
-
- assert( pParse->checkSchema );
- assert( sqlite3_mutex_held(db->mutex) );
- for(iDb=0; iDb<db->nDb; iDb++){
- int openedTransaction = 0; /* True if a transaction is opened */
- Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */
- if( pBt==0 ) continue;
-
- /* If there is not already a read-only (or read-write) transaction opened
- ** on the b-tree database, open one now. If a transaction is opened, it
- ** will be closed immediately after reading the meta-value. */
- if( !sqlite3BtreeIsInReadTrans(pBt) ){
- rc = sqlite3BtreeBeginTrans(pBt, 0);
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- db->mallocFailed = 1;
- }
- if( rc!=SQLITE_OK ) return;
- openedTransaction = 1;
- }
-
- /* Read the schema cookie from the database. If it does not match the
- ** value stored as part of the in-memory schema representation,
- ** set Parse.rc to SQLITE_SCHEMA. */
- sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
- sqlite3ResetOneSchema(db, iDb);
- pParse->rc = SQLITE_SCHEMA;
- }
-
- /* Close the transaction, if one was opened. */
- if( openedTransaction ){
- sqlite3BtreeCommit(pBt);
- }
- }
-}
-
-/*
-** Convert a schema pointer into the iDb index that indicates
-** which database file in db->aDb[] the schema refers to.
-**
-** If the same database is attached more than once, the first
-** attached database is returned.
-*/
-SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
- int i = -1000000;
-
- /* If pSchema is NULL, then return -1000000. This happens when code in
- ** expr.c is trying to resolve a reference to a transient table (i.e. one
- ** created by a sub-select). In this case the return value of this
- ** function should never be used.
- **
- ** We return -1000000 instead of the more usual -1 simply because using
- ** -1000000 as the incorrect index into db->aDb[] is much
- ** more likely to cause a segfault than -1 (of course there are assert()
- ** statements too, but it never hurts to play the odds).
- */
- assert( sqlite3_mutex_held(db->mutex) );
- if( pSchema ){
- for(i=0; ALWAYS(i<db->nDb); i++){
- if( db->aDb[i].pSchema==pSchema ){
- break;
- }
- }
- assert( i>=0 && i<db->nDb );
- }
- return i;
-}
-
-/*
-** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
-*/
-static int sqlite3Prepare(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
- Vdbe *pReprepare, /* VM being reprepared */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-){
- Parse *pParse; /* Parsing context */
- char *zErrMsg = 0; /* Error message */
- int rc = SQLITE_OK; /* Result code */
- int i; /* Loop counter */
-
- /* Allocate the parsing context */
- pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
- if( pParse==0 ){
- rc = SQLITE_NOMEM;
- goto end_prepare;
- }
- pParse->pReprepare = pReprepare;
- assert( ppStmt && *ppStmt==0 );
- assert( !db->mallocFailed );
- assert( sqlite3_mutex_held(db->mutex) );
-
- /* Check to verify that it is possible to get a read lock on all
- ** database schemas. The inability to get a read lock indicates that
- ** some other database connection is holding a write-lock, which in
- ** turn means that the other connection has made uncommitted changes
- ** to the schema.
- **
- ** Were we to proceed and prepare the statement against the uncommitted
- ** schema changes and if those schema changes are subsequently rolled
- ** back and different changes are made in their place, then when this
- ** prepared statement goes to run the schema cookie would fail to detect
- ** the schema change. Disaster would follow.
- **
- ** This thread is currently holding mutexes on all Btrees (because
- ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it
- ** is not possible for another thread to start a new schema change
- ** while this routine is running. Hence, we do not need to hold
- ** locks on the schema, we just need to make sure nobody else is
- ** holding them.
- **
- ** Note that setting READ_UNCOMMITTED overrides most lock detection,
- ** but it does *not* override schema lock detection, so this all still
- ** works even if READ_UNCOMMITTED is set.
- */
- for(i=0; i<db->nDb; i++) {
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- assert( sqlite3BtreeHoldsMutex(pBt) );
- rc = sqlite3BtreeSchemaLocked(pBt);
- if( rc ){
- const char *zDb = db->aDb[i].zName;
- sqlite3Error(db, rc, "database schema is locked: %s", zDb);
- testcase( db->flags & SQLITE_ReadUncommitted );
- goto end_prepare;
- }
- }
- }
-
- sqlite3VtabUnlockList(db);
-
- pParse->db = db;
- pParse->nQueryLoop = (double)1;
- if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
- char *zSqlCopy;
- int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
- testcase( nBytes==mxLen );
- testcase( nBytes==mxLen+1 );
- if( nBytes>mxLen ){
- sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
- rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
- goto end_prepare;
- }
- zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
- if( zSqlCopy ){
- sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
- sqlite3DbFree(db, zSqlCopy);
- pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
- }else{
- pParse->zTail = &zSql[nBytes];
- }
- }else{
- sqlite3RunParser(pParse, zSql, &zErrMsg);
- }
- assert( 1==(int)pParse->nQueryLoop );
-
- if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
- }
- if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
- if( pParse->checkSchema ){
- schemaIsValid(pParse);
- }
- if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
- }
- if( pzTail ){
- *pzTail = pParse->zTail;
- }
- rc = pParse->rc;
-
-#ifndef SQLITE_OMIT_EXPLAIN
- if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
- static const char * const azColName[] = {
- "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
- "selectid", "order", "from", "detail"
- };
- int iFirst, mx;
- if( pParse->explain==2 ){
- sqlite3VdbeSetNumCols(pParse->pVdbe, 4);
- iFirst = 8;
- mx = 12;
- }else{
- sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
- iFirst = 0;
- mx = 8;
- }
- for(i=iFirst; i<mx; i++){
- sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
- azColName[i], SQLITE_STATIC);
- }
- }
-#endif
-
- assert( db->init.busy==0 || saveSqlFlag==0 );
- if( db->init.busy==0 ){
- Vdbe *pVdbe = pParse->pVdbe;
- sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
- }
- if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
- sqlite3VdbeFinalize(pParse->pVdbe);
- assert(!(*ppStmt));
- }else{
- *ppStmt = (sqlite3_stmt*)pParse->pVdbe;
- }
-
- if( zErrMsg ){
- sqlite3Error(db, rc, "%s", zErrMsg);
- sqlite3DbFree(db, zErrMsg);
- }else{
- sqlite3Error(db, rc, 0);
- }
-
- /* Delete any TriggerPrg structures allocated while parsing this statement. */
- while( pParse->pTriggerPrg ){
- TriggerPrg *pT = pParse->pTriggerPrg;
- pParse->pTriggerPrg = pT->pNext;
- sqlite3DbFree(db, pT);
- }
-
-end_prepare:
-
- sqlite3StackFree(db, pParse);
- rc = sqlite3ApiExit(db, rc);
- assert( (rc&db->errMask)==rc );
- return rc;
-}
-static int sqlite3LockAndPrepare(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
- Vdbe *pOld, /* VM being reprepared */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-){
- int rc;
- assert( ppStmt!=0 );
- *ppStmt = 0;
- if( !sqlite3SafetyCheckOk(db) ){
- return SQLITE_MISUSE_BKPT;
- }
- sqlite3_mutex_enter(db->mutex);
- sqlite3BtreeEnterAll(db);
- rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
- if( rc==SQLITE_SCHEMA ){
- sqlite3_finalize(*ppStmt);
- rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
- }
- sqlite3BtreeLeaveAll(db);
- sqlite3_mutex_leave(db->mutex);
- assert( rc==SQLITE_OK || *ppStmt==0 );
- return rc;
-}
-
-/*
-** Rerun the compilation of a statement after a schema change.
-**
-** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
-** if the statement cannot be recompiled because another connection has
-** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error
-** occurs, return SQLITE_SCHEMA.
-*/
-SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
- int rc;
- sqlite3_stmt *pNew;
- const char *zSql;
- sqlite3 *db;
-
- assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) );
- zSql = sqlite3_sql((sqlite3_stmt *)p);
- assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */
- db = sqlite3VdbeDb(p);
- assert( sqlite3_mutex_held(db->mutex) );
- rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0);
- if( rc ){
- if( rc==SQLITE_NOMEM ){
- db->mallocFailed = 1;
- }
- assert( pNew==0 );
- return rc;
- }else{
- assert( pNew!=0 );
- }
- sqlite3VdbeSwap((Vdbe*)pNew, p);
- sqlite3TransferBindings(pNew, (sqlite3_stmt*)p);
- sqlite3VdbeResetStepResult((Vdbe*)pNew);
- sqlite3VdbeFinalize((Vdbe*)pNew);
- return SQLITE_OK;
-}
-
-
-/*
-** Two versions of the official API. Legacy and new use. In the legacy
-** version, the original SQL text is not saved in the prepared statement
-** and so if a schema change occurs, SQLITE_SCHEMA is returned by
-** sqlite3_step(). In the new version, the original SQL text is retained
-** and the statement is automatically recompiled if an schema change
-** occurs.
-*/
-SQLITE_API int sqlite3_prepare(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-){
- int rc;
- rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
- return rc;
-}
-SQLITE_API int sqlite3_prepare_v2(
- sqlite3 *db, /* Database handle. */
- const char *zSql, /* UTF-8 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char **pzTail /* OUT: End of parsed string */
-){
- int rc;
- rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,0,ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
- return rc;
-}
-
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
-*/
-static int sqlite3Prepare16(
- sqlite3 *db, /* Database handle. */
- const void *zSql, /* UTF-16 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const void **pzTail /* OUT: End of parsed string */
-){
- /* This function currently works by first transforming the UTF-16
- ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
- ** tricky bit is figuring out the pointer to return in *pzTail.
- */
- char *zSql8;
- const char *zTail8 = 0;
- int rc = SQLITE_OK;
-
- assert( ppStmt );
- *ppStmt = 0;
- if( !sqlite3SafetyCheckOk(db) ){
- return SQLITE_MISUSE_BKPT;
- }
- sqlite3_mutex_enter(db->mutex);
- zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
- if( zSql8 ){
- rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
- }
-
- if( zTail8 && pzTail ){
- /* If sqlite3_prepare returns a tail pointer, we calculate the
- ** equivalent pointer into the UTF-16 string by counting the unicode
- ** characters between zSql8 and zTail8, and then returning a pointer
- ** the same number of characters into the UTF-16 string.
- */
- int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8));
- *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);
- }
- sqlite3DbFree(db, zSql8);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Two versions of the official API. Legacy and new use. In the legacy
-** version, the original SQL text is not saved in the prepared statement
-** and so if a schema change occurs, SQLITE_SCHEMA is returned by
-** sqlite3_step(). In the new version, the original SQL text is retained
-** and the statement is automatically recompiled if an schema change
-** occurs.
-*/
-SQLITE_API int sqlite3_prepare16(
- sqlite3 *db, /* Database handle. */
- const void *zSql, /* UTF-16 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const void **pzTail /* OUT: End of parsed string */
-){
- int rc;
- rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
- return rc;
-}
-SQLITE_API int sqlite3_prepare16_v2(
- sqlite3 *db, /* Database handle. */
- const void *zSql, /* UTF-16 encoded SQL statement. */
- int nBytes, /* Length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const void **pzTail /* OUT: End of parsed string */
-){
- int rc;
- rc = sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail);
- assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
- return rc;
-}
-
-#endif /* SQLITE_OMIT_UTF16 */
-
-/************** End of prepare.c *********************************************/
-/************** Begin file select.c ******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains C code routines that are called by the parser
-** to handle SELECT statements in SQLite.
-*/
-
-
-/*
-** Delete all the content of a Select structure but do not deallocate
-** the select structure itself.
-*/
-static void clearSelect(sqlite3 *db, Select *p){
- sqlite3ExprListDelete(db, p->pEList);
- sqlite3SrcListDelete(db, p->pSrc);
- sqlite3ExprDelete(db, p->pWhere);
- sqlite3ExprListDelete(db, p->pGroupBy);
- sqlite3ExprDelete(db, p->pHaving);
- sqlite3ExprListDelete(db, p->pOrderBy);
- sqlite3SelectDelete(db, p->pPrior);
- sqlite3ExprDelete(db, p->pLimit);
- sqlite3ExprDelete(db, p->pOffset);
-}
-
-/*
-** Initialize a SelectDest structure.
-*/
-SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
- pDest->eDest = (u8)eDest;
- pDest->iSDParm = iParm;
- pDest->affSdst = 0;
- pDest->iSdst = 0;
- pDest->nSdst = 0;
-}
-
-
-/*
-** Allocate a new Select structure and return a pointer to that
-** structure.
-*/
-SQLITE_PRIVATE Select *sqlite3SelectNew(
- Parse *pParse, /* Parsing context */
- ExprList *pEList, /* which columns to include in the result */
- SrcList *pSrc, /* the FROM clause -- which tables to scan */
- Expr *pWhere, /* the WHERE clause */
- ExprList *pGroupBy, /* the GROUP BY clause */
- Expr *pHaving, /* the HAVING clause */
- ExprList *pOrderBy, /* the ORDER BY clause */
- int isDistinct, /* true if the DISTINCT keyword is present */
- Expr *pLimit, /* LIMIT value. NULL means not used */
- Expr *pOffset /* OFFSET value. NULL means no offset */
-){
- Select *pNew;
- Select standin;
- sqlite3 *db = pParse->db;
- pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
- assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
- if( pNew==0 ){
- assert( db->mallocFailed );
- pNew = &standin;
- memset(pNew, 0, sizeof(*pNew));
- }
- if( pEList==0 ){
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
- }
- pNew->pEList = pEList;
- if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc));
- pNew->pSrc = pSrc;
- pNew->pWhere = pWhere;
- pNew->pGroupBy = pGroupBy;
- pNew->pHaving = pHaving;
- pNew->pOrderBy = pOrderBy;
- pNew->selFlags = isDistinct ? SF_Distinct : 0;
- pNew->op = TK_SELECT;
- pNew->pLimit = pLimit;
- pNew->pOffset = pOffset;
- assert( pOffset==0 || pLimit!=0 );
- pNew->addrOpenEphm[0] = -1;
- pNew->addrOpenEphm[1] = -1;
- pNew->addrOpenEphm[2] = -1;
- if( db->mallocFailed ) {
- clearSelect(db, pNew);
- if( pNew!=&standin ) sqlite3DbFree(db, pNew);
- pNew = 0;
- }else{
- assert( pNew->pSrc!=0 || pParse->nErr>0 );
- }
- assert( pNew!=&standin );
- return pNew;
-}
-
-/*
-** Delete the given Select structure and all of its substructures.
-*/
-SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
- if( p ){
- clearSelect(db, p);
- sqlite3DbFree(db, p);
- }
-}
-
-/*
-** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
-** type of join. Return an integer constant that expresses that type
-** in terms of the following bit values:
-**
-** JT_INNER
-** JT_CROSS
-** JT_OUTER
-** JT_NATURAL
-** JT_LEFT
-** JT_RIGHT
-**
-** A full outer join is the combination of JT_LEFT and JT_RIGHT.
-**
-** If an illegal or unsupported join type is seen, then still return
-** a join type, but put an error in the pParse structure.
-*/
-SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
- int jointype = 0;
- Token *apAll[3];
- Token *p;
- /* 0123456789 123456789 123456789 123 */
- static const char zKeyText[] = "naturaleftouterightfullinnercross";
- static const struct {
- u8 i; /* Beginning of keyword text in zKeyText[] */
- u8 nChar; /* Length of the keyword in characters */
- u8 code; /* Join type mask */
- } aKeyword[] = {
- /* natural */ { 0, 7, JT_NATURAL },
- /* left */ { 6, 4, JT_LEFT|JT_OUTER },
- /* outer */ { 10, 5, JT_OUTER },
- /* right */ { 14, 5, JT_RIGHT|JT_OUTER },
- /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
- /* inner */ { 23, 5, JT_INNER },
- /* cross */ { 28, 5, JT_INNER|JT_CROSS },
- };
- int i, j;
- apAll[0] = pA;
- apAll[1] = pB;
- apAll[2] = pC;
- for(i=0; i<3 && apAll[i]; i++){
- p = apAll[i];
- for(j=0; j<ArraySize(aKeyword); j++){
- if( p->n==aKeyword[j].nChar
- && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){
- jointype |= aKeyword[j].code;
- break;
- }
- }
- testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 );
- if( j>=ArraySize(aKeyword) ){
- jointype |= JT_ERROR;
- break;
- }
- }
- if(
- (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
- (jointype & JT_ERROR)!=0
- ){
- const char *zSp = " ";
- assert( pB!=0 );
- if( pC==0 ){ zSp++; }
- sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
- "%T %T%s%T", pA, pB, zSp, pC);
- jointype = JT_INNER;
- }else if( (jointype & JT_OUTER)!=0
- && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
- sqlite3ErrorMsg(pParse,
- "RIGHT and FULL OUTER JOINs are not currently supported");
- jointype = JT_INNER;
- }
- return jointype;
-}
-
-/*
-** Return the index of a column in a table. Return -1 if the column
-** is not contained in the table.
-*/
-static int columnIndex(Table *pTab, const char *zCol){
- int i;
- for(i=0; i<pTab->nCol; i++){
- if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
- }
- return -1;
-}
-
-/*
-** Search the first N tables in pSrc, from left to right, looking for a
-** table that has a column named zCol.
-**
-** When found, set *piTab and *piCol to the table index and column index
-** of the matching column and return TRUE.
-**
-** If not found, return FALSE.
-*/
-static int tableAndColumnIndex(
- SrcList *pSrc, /* Array of tables to search */
- int N, /* Number of tables in pSrc->a[] to search */
- const char *zCol, /* Name of the column we are looking for */
- int *piTab, /* Write index of pSrc->a[] here */
- int *piCol /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
-){
- int i; /* For looping over tables in pSrc */
- int iCol; /* Index of column matching zCol */
-
- assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
- for(i=0; i<N; i++){
- iCol = columnIndex(pSrc->a[i].pTab, zCol);
- if( iCol>=0 ){
- if( piTab ){
- *piTab = i;
- *piCol = iCol;
- }
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** This function is used to add terms implied by JOIN syntax to the
-** WHERE clause expression of a SELECT statement. The new term, which
-** is ANDed with the existing WHERE clause, is of the form:
-**
-** (tab1.col1 = tab2.col2)
-**
-** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the
-** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is
-** column iColRight of tab2.
-*/
-static void addWhereTerm(
- Parse *pParse, /* Parsing context */
- SrcList *pSrc, /* List of tables in FROM clause */
- int iLeft, /* Index of first table to join in pSrc */
- int iColLeft, /* Index of column in first table */
- int iRight, /* Index of second table in pSrc */
- int iColRight, /* Index of column in second table */
- int isOuterJoin, /* True if this is an OUTER join */
- Expr **ppWhere /* IN/OUT: The WHERE clause to add to */
-){
- sqlite3 *db = pParse->db;
- Expr *pE1;
- Expr *pE2;
- Expr *pEq;
-
- assert( iLeft<iRight );
- assert( pSrc->nSrc>iRight );
- assert( pSrc->a[iLeft].pTab );
- assert( pSrc->a[iRight].pTab );
-
- pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
- pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);
-
- pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0);
- if( pEq && isOuterJoin ){
- ExprSetProperty(pEq, EP_FromJoin);
- assert( !ExprHasAnyProperty(pEq, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(pEq);
- pEq->iRightJoinTable = (i16)pE2->iTable;
- }
- *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
-}
-
-/*
-** Set the EP_FromJoin property on all terms of the given expression.
-** And set the Expr.iRightJoinTable to iTable for every term in the
-** expression.
-**
-** The EP_FromJoin property is used on terms of an expression to tell
-** the LEFT OUTER JOIN processing logic that this term is part of the
-** join restriction specified in the ON or USING clause and not a part
-** of the more general WHERE clause. These terms are moved over to the
-** WHERE clause during join processing but we need to remember that they
-** originated in the ON or USING clause.
-**
-** The Expr.iRightJoinTable tells the WHERE clause processing that the
-** expression depends on table iRightJoinTable even if that table is not
-** explicitly mentioned in the expression. That information is needed
-** for cases like this:
-**
-** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5
-**
-** The where clause needs to defer the handling of the t1.x=5
-** term until after the t2 loop of the join. In that way, a
-** NULL t2 row will be inserted whenever t1.x!=5. If we do not
-** defer the handling of t1.x=5, it will be processed immediately
-** after the t1 loop and rows with t1.x!=5 will never appear in
-** the output, which is incorrect.
-*/
-static void setJoinExpr(Expr *p, int iTable){
- while( p ){
- ExprSetProperty(p, EP_FromJoin);
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(p);
- p->iRightJoinTable = (i16)iTable;
- setJoinExpr(p->pLeft, iTable);
- p = p->pRight;
- }
-}
-
-/*
-** This routine processes the join information for a SELECT statement.
-** ON and USING clauses are converted into extra terms of the WHERE clause.
-** NATURAL joins also create extra WHERE clause terms.
-**
-** The terms of a FROM clause are contained in the Select.pSrc structure.
-** The left most table is the first entry in Select.pSrc. The right-most
-** table is the last entry. The join operator is held in the entry to
-** the left. Thus entry 0 contains the join operator for the join between
-** entries 0 and 1. Any ON or USING clauses associated with the join are
-** also attached to the left entry.
-**
-** This routine returns the number of errors encountered.
-*/
-static int sqliteProcessJoin(Parse *pParse, Select *p){
- SrcList *pSrc; /* All tables in the FROM clause */
- int i, j; /* Loop counters */
- struct SrcList_item *pLeft; /* Left table being joined */
- struct SrcList_item *pRight; /* Right table being joined */
-
- pSrc = p->pSrc;
- pLeft = &pSrc->a[0];
- pRight = &pLeft[1];
- for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
- Table *pLeftTab = pLeft->pTab;
- Table *pRightTab = pRight->pTab;
- int isOuter;
-
- if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
- isOuter = (pRight->jointype & JT_OUTER)!=0;
-
- /* When the NATURAL keyword is present, add WHERE clause terms for
- ** every column that the two tables have in common.
- */
- if( pRight->jointype & JT_NATURAL ){
- if( pRight->pOn || pRight->pUsing ){
- sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
- "an ON or USING clause", 0);
- return 1;
- }
- for(j=0; j<pRightTab->nCol; j++){
- char *zName; /* Name of column in the right table */
- int iLeft; /* Matching left table */
- int iLeftCol; /* Matching column in the left table */
-
- zName = pRightTab->aCol[j].zName;
- if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){
- addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
- isOuter, &p->pWhere);
- }
- }
- }
-
- /* Disallow both ON and USING clauses in the same join
- */
- if( pRight->pOn && pRight->pUsing ){
- sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
- "clauses in the same join");
- return 1;
- }
-
- /* Add the ON clause to the end of the WHERE clause, connected by
- ** an AND operator.
- */
- if( pRight->pOn ){
- if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor);
- p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn);
- pRight->pOn = 0;
- }
-
- /* Create extra terms on the WHERE clause for each column named
- ** in the USING clause. Example: If the two tables to be joined are
- ** A and B and the USING clause names X, Y, and Z, then add this
- ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
- ** Report an error if any column mentioned in the USING clause is
- ** not contained in both tables to be joined.
- */
- if( pRight->pUsing ){
- IdList *pList = pRight->pUsing;
- for(j=0; j<pList->nId; j++){
- char *zName; /* Name of the term in the USING clause */
- int iLeft; /* Table on the left with matching column name */
- int iLeftCol; /* Column number of matching column on the left */
- int iRightCol; /* Column number of matching column on the right */
-
- zName = pList->a[j].zName;
- iRightCol = columnIndex(pRightTab, zName);
- if( iRightCol<0
- || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol)
- ){
- sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
- "not present in both tables", zName);
- return 1;
- }
- addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol,
- isOuter, &p->pWhere);
- }
- }
- }
- return 0;
-}
-
-/*
-** Insert code into "v" that will push the record on the top of the
-** stack into the sorter.
-*/
-static void pushOntoSorter(
- Parse *pParse, /* Parser context */
- ExprList *pOrderBy, /* The ORDER BY clause */
- Select *pSelect, /* The whole SELECT statement */
- int regData /* Register holding data to be sorted */
-){
- Vdbe *v = pParse->pVdbe;
- int nExpr = pOrderBy->nExpr;
- int regBase = sqlite3GetTempRange(pParse, nExpr+2);
- int regRecord = sqlite3GetTempReg(pParse);
- int op;
- sqlite3ExprCacheClear(pParse);
- sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0);
- sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
- sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);
- if( pSelect->selFlags & SF_UseSorter ){
- op = OP_SorterInsert;
- }else{
- op = OP_IdxInsert;
- }
- sqlite3VdbeAddOp2(v, op, pOrderBy->iECursor, regRecord);
- sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3ReleaseTempRange(pParse, regBase, nExpr+2);
- if( pSelect->iLimit ){
- int addr1, addr2;
- int iLimit;
- if( pSelect->iOffset ){
- iLimit = pSelect->iOffset+1;
- }else{
- iLimit = pSelect->iLimit;
- }
- addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit);
- sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
- addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, addr1);
- sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
- sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor);
- sqlite3VdbeJumpHere(v, addr2);
- }
-}
-
-/*
-** Add code to implement the OFFSET
-*/
-static void codeOffset(
- Vdbe *v, /* Generate code into this VM */
- Select *p, /* The SELECT statement being coded */
- int iContinue /* Jump here to skip the current record */
-){
- if( p->iOffset && iContinue!=0 ){
- int addr;
- sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1);
- addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
- VdbeComment((v, "skip OFFSET records"));
- sqlite3VdbeJumpHere(v, addr);
- }
-}
-
-/*
-** Add code that will check to make sure the N registers starting at iMem
-** form a distinct entry. iTab is a sorting index that holds previously
-** seen combinations of the N values. A new entry is made in iTab
-** if the current N values are new.
-**
-** A jump to addrRepeat is made and the N+1 values are popped from the
-** stack if the top N elements are not distinct.
-*/
-static void codeDistinct(
- Parse *pParse, /* Parsing and code generating context */
- int iTab, /* A sorting index used to test for distinctness */
- int addrRepeat, /* Jump to here if not distinct */
- int N, /* Number of elements */
- int iMem /* First element */
-){
- Vdbe *v;
- int r1;
-
- v = pParse->pVdbe;
- r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1);
- sqlite3ReleaseTempReg(pParse, r1);
-}
-
-#ifndef SQLITE_OMIT_SUBQUERY
-/*
-** Generate an error message when a SELECT is used within a subexpression
-** (example: "a IN (SELECT * FROM table)") but it has more than 1 result
-** column. We do this in a subroutine because the error used to occur
-** in multiple places. (The error only occurs in one place now, but we
-** retain the subroutine to minimize code disruption.)
-*/
-static int checkForMultiColumnSelectError(
- Parse *pParse, /* Parse context. */
- SelectDest *pDest, /* Destination of SELECT results */
- int nExpr /* Number of result columns returned by SELECT */
-){
- int eDest = pDest->eDest;
- if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){
- sqlite3ErrorMsg(pParse, "only a single result allowed for "
- "a SELECT that is part of an expression");
- return 1;
- }else{
- return 0;
- }
-}
-#endif
-
-/*
-** An instance of the following object is used to record information about
-** how to process the DISTINCT keyword, to simplify passing that information
-** into the selectInnerLoop() routine.
-*/
-typedef struct DistinctCtx DistinctCtx;
-struct DistinctCtx {
- u8 isTnct; /* True if the DISTINCT keyword is present */
- u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */
- int tabTnct; /* Ephemeral table used for DISTINCT processing */
- int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */
-};
-
-/*
-** This routine generates the code for the inside of the inner loop
-** of a SELECT.
-**
-** If srcTab and nColumn are both zero, then the pEList expressions
-** are evaluated in order to get the data for this row. If nColumn>0
-** then data is pulled from srcTab and pEList is used only to get the
-** datatypes for each column.
-*/
-static void selectInnerLoop(
- Parse *pParse, /* The parser context */
- Select *p, /* The complete select statement being coded */
- ExprList *pEList, /* List of values being extracted */
- int srcTab, /* Pull data from this table */
- int nColumn, /* Number of columns in the source table */
- ExprList *pOrderBy, /* If not NULL, sort results using this key */
- DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
- SelectDest *pDest, /* How to dispose of the results */
- int iContinue, /* Jump here to continue with next row */
- int iBreak /* Jump here to break out of the inner loop */
-){
- Vdbe *v = pParse->pVdbe;
- int i;
- int hasDistinct; /* True if the DISTINCT keyword is present */
- int regResult; /* Start of memory holding result set */
- int eDest = pDest->eDest; /* How to dispose of results */
- int iParm = pDest->iSDParm; /* First argument to disposal method */
- int nResultCol; /* Number of result columns */
-
- assert( v );
- if( NEVER(v==0) ) return;
- assert( pEList!=0 );
- hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
- if( pOrderBy==0 && !hasDistinct ){
- codeOffset(v, p, iContinue);
- }
-
- /* Pull the requested columns.
- */
- if( nColumn>0 ){
- nResultCol = nColumn;
- }else{
- nResultCol = pEList->nExpr;
- }
- if( pDest->iSdst==0 ){
- pDest->iSdst = pParse->nMem+1;
- pDest->nSdst = nResultCol;
- pParse->nMem += nResultCol;
- }else{
- assert( pDest->nSdst==nResultCol );
- }
- regResult = pDest->iSdst;
- if( nColumn>0 ){
- for(i=0; i<nColumn; i++){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
- }
- }else if( eDest!=SRT_Exists ){
- /* If the destination is an EXISTS(...) expression, the actual
- ** values returned by the SELECT are not required.
- */
- sqlite3ExprCacheClear(pParse);
- sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Output);
- }
- nColumn = nResultCol;
-
- /* If the DISTINCT keyword was present on the SELECT statement
- ** and this row has been seen before, then do not make this row
- ** part of the result.
- */
- if( hasDistinct ){
- assert( pEList!=0 );
- assert( pEList->nExpr==nColumn );
- switch( pDistinct->eTnctType ){
- case WHERE_DISTINCT_ORDERED: {
- VdbeOp *pOp; /* No longer required OpenEphemeral instr. */
- int iJump; /* Jump destination */
- int regPrev; /* Previous row content */
-
- /* Allocate space for the previous row */
- regPrev = pParse->nMem+1;
- pParse->nMem += nColumn;
-
- /* Change the OP_OpenEphemeral coded earlier to an OP_Null
- ** sets the MEM_Cleared bit on the first register of the
- ** previous value. This will cause the OP_Ne below to always
- ** fail on the first iteration of the loop even if the first
- ** row is all NULLs.
- */
- sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
- pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct);
- pOp->opcode = OP_Null;
- pOp->p1 = 1;
- pOp->p2 = regPrev;
-
- iJump = sqlite3VdbeCurrentAddr(v) + nColumn;
- for(i=0; i<nColumn; i++){
- CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
- if( i<nColumn-1 ){
- sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
- }else{
- sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
- }
- sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
- sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
- }
- assert( sqlite3VdbeCurrentAddr(v)==iJump );
- sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nColumn-1);
- break;
- }
-
- case WHERE_DISTINCT_UNIQUE: {
- sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
- break;
- }
-
- default: {
- assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED );
- codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult);
- break;
- }
- }
- if( pOrderBy==0 ){
- codeOffset(v, p, iContinue);
- }
- }
-
- switch( eDest ){
- /* In this mode, write each query result to the key of the temporary
- ** table iParm.
- */
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
- case SRT_Union: {
- int r1;
- r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
- sqlite3ReleaseTempReg(pParse, r1);
- break;
- }
-
- /* Construct a record from the query result, but instead of
- ** saving that record, use it as a key to delete elements from
- ** the temporary table iParm.
- */
- case SRT_Except: {
- sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nColumn);
- break;
- }
-#endif
-
- /* Store the result as data using a unique key.
- */
- case SRT_Table:
- case SRT_EphemTab: {
- int r1 = sqlite3GetTempReg(pParse);
- testcase( eDest==SRT_Table );
- testcase( eDest==SRT_EphemTab );
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
- if( pOrderBy ){
- pushOntoSorter(pParse, pOrderBy, p, r1);
- }else{
- int r2 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
- sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- sqlite3ReleaseTempReg(pParse, r2);
- }
- sqlite3ReleaseTempReg(pParse, r1);
- break;
- }
-
-#ifndef SQLITE_OMIT_SUBQUERY
- /* If we are creating a set for an "expr IN (SELECT ...)" construct,
- ** then there should be a single item on the stack. Write this
- ** item into the set table with bogus data.
- */
- case SRT_Set: {
- assert( nColumn==1 );
- pDest->affSdst =
- sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
- if( pOrderBy ){
- /* At first glance you would think we could optimize out the
- ** ORDER BY in this case since the order of entries in the set
- ** does not matter. But there might be a LIMIT clause, in which
- ** case the order does matter */
- pushOntoSorter(pParse, pOrderBy, p, regResult);
- }else{
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
- sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
- sqlite3ReleaseTempReg(pParse, r1);
- }
- break;
- }
-
- /* If any row exist in the result set, record that fact and abort.
- */
- case SRT_Exists: {
- sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm);
- /* The LIMIT clause will terminate the loop for us */
- break;
- }
-
- /* If this is a scalar select that is part of an expression, then
- ** store the results in the appropriate memory cell and break out
- ** of the scan loop.
- */
- case SRT_Mem: {
- assert( nColumn==1 );
- if( pOrderBy ){
- pushOntoSorter(pParse, pOrderBy, p, regResult);
- }else{
- sqlite3ExprCodeMove(pParse, regResult, iParm, 1);
- /* The LIMIT clause will jump out of the loop for us */
- }
- break;
- }
-#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
-
- /* Send the data to the callback function or to a subroutine. In the
- ** case of a subroutine, the subroutine itself is responsible for
- ** popping the data from the stack.
- */
- case SRT_Coroutine:
- case SRT_Output: {
- testcase( eDest==SRT_Coroutine );
- testcase( eDest==SRT_Output );
- if( pOrderBy ){
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
- pushOntoSorter(pParse, pOrderBy, p, r1);
- sqlite3ReleaseTempReg(pParse, r1);
- }else if( eDest==SRT_Coroutine ){
- sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
- }else{
- sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
- sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn);
- }
- break;
- }
-
-#if !defined(SQLITE_OMIT_TRIGGER)
- /* Discard the results. This is used for SELECT statements inside
- ** the body of a TRIGGER. The purpose of such selects is to call
- ** user-defined functions that have side effects. We do not care
- ** about the actual results of the select.
- */
- default: {
- assert( eDest==SRT_Discard );
- break;
- }
-#endif
- }
-
- /* Jump to the end of the loop if the LIMIT is reached. Except, if
- ** there is a sorter, in which case the sorter has already limited
- ** the output for us.
- */
- if( pOrderBy==0 && p->iLimit ){
- sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
- }
-}
-
-/*
-** Given an expression list, generate a KeyInfo structure that records
-** the collating sequence for each expression in that expression list.
-**
-** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
-** KeyInfo structure is appropriate for initializing a virtual index to
-** implement that clause. If the ExprList is the result set of a SELECT
-** then the KeyInfo structure is appropriate for initializing a virtual
-** index to implement a DISTINCT test.
-**
-** Space to hold the KeyInfo structure is obtain from malloc. The calling
-** function is responsible for seeing that this structure is eventually
-** freed. Add the KeyInfo structure to the P4 field of an opcode using
-** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
-*/
-static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
- sqlite3 *db = pParse->db;
- int nExpr;
- KeyInfo *pInfo;
- struct ExprList_item *pItem;
- int i;
-
- nExpr = pList->nExpr;
- pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
- if( pInfo ){
- pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
- pInfo->nField = (u16)nExpr;
- pInfo->enc = ENC(db);
- pInfo->db = db;
- for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
- CollSeq *pColl;
- pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
- if( !pColl ){
- pColl = db->pDfltColl;
- }
- pInfo->aColl[i] = pColl;
- pInfo->aSortOrder[i] = pItem->sortOrder;
- }
- }
- return pInfo;
-}
-
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-/*
-** Name of the connection operator, used for error messages.
-*/
-static const char *selectOpName(int id){
- char *z;
- switch( id ){
- case TK_ALL: z = "UNION ALL"; break;
- case TK_INTERSECT: z = "INTERSECT"; break;
- case TK_EXCEPT: z = "EXCEPT"; break;
- default: z = "UNION"; break;
- }
- return z;
-}
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
-
-#ifndef SQLITE_OMIT_EXPLAIN
-/*
-** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
-** is a no-op. Otherwise, it adds a single row of output to the EQP result,
-** where the caption is of the form:
-**
-** "USE TEMP B-TREE FOR xxx"
-**
-** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which
-** is determined by the zUsage argument.
-*/
-static void explainTempTable(Parse *pParse, const char *zUsage){
- if( pParse->explain==2 ){
- Vdbe *v = pParse->pVdbe;
- char *zMsg = sqlite3MPrintf(pParse->db, "USE TEMP B-TREE FOR %s", zUsage);
- sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
- }
-}
-
-/*
-** Assign expression b to lvalue a. A second, no-op, version of this macro
-** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code
-** in sqlite3Select() to assign values to structure member variables that
-** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the
-** code with #ifndef directives.
-*/
-# define explainSetInteger(a, b) a = b
-
-#else
-/* No-op versions of the explainXXX() functions and macros. */
-# define explainTempTable(y,z)
-# define explainSetInteger(y,z)
-#endif
-
-#if !defined(SQLITE_OMIT_EXPLAIN) && !defined(SQLITE_OMIT_COMPOUND_SELECT)
-/*
-** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function
-** is a no-op. Otherwise, it adds a single row of output to the EQP result,
-** where the caption is of one of the two forms:
-**
-** "COMPOSITE SUBQUERIES iSub1 and iSub2 (op)"
-** "COMPOSITE SUBQUERIES iSub1 and iSub2 USING TEMP B-TREE (op)"
-**
-** where iSub1 and iSub2 are the integers passed as the corresponding
-** function parameters, and op is the text representation of the parameter
-** of the same name. The parameter "op" must be one of TK_UNION, TK_EXCEPT,
-** TK_INTERSECT or TK_ALL. The first form is used if argument bUseTmp is
-** false, or the second form if it is true.
-*/
-static void explainComposite(
- Parse *pParse, /* Parse context */
- int op, /* One of TK_UNION, TK_EXCEPT etc. */
- int iSub1, /* Subquery id 1 */
- int iSub2, /* Subquery id 2 */
- int bUseTmp /* True if a temp table was used */
-){
- assert( op==TK_UNION || op==TK_EXCEPT || op==TK_INTERSECT || op==TK_ALL );
- if( pParse->explain==2 ){
- Vdbe *v = pParse->pVdbe;
- char *zMsg = sqlite3MPrintf(
- pParse->db, "COMPOUND SUBQUERIES %d AND %d %s(%s)", iSub1, iSub2,
- bUseTmp?"USING TEMP B-TREE ":"", selectOpName(op)
- );
- sqlite3VdbeAddOp4(v, OP_Explain, pParse->iSelectId, 0, 0, zMsg, P4_DYNAMIC);
- }
-}
-#else
-/* No-op versions of the explainXXX() functions and macros. */
-# define explainComposite(v,w,x,y,z)
-#endif
-
-/*
-** If the inner loop was generated using a non-null pOrderBy argument,
-** then the results were placed in a sorter. After the loop is terminated
-** we need to run the sorter and output the results. The following
-** routine generates the code needed to do that.
-*/
-static void generateSortTail(
- Parse *pParse, /* Parsing context */
- Select *p, /* The SELECT statement */
- Vdbe *v, /* Generate code into this VDBE */
- int nColumn, /* Number of columns of data */
- SelectDest *pDest /* Write the sorted results here */
-){
- int addrBreak = sqlite3VdbeMakeLabel(v); /* Jump here to exit loop */
- int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */
- int addr;
- int iTab;
- int pseudoTab = 0;
- ExprList *pOrderBy = p->pOrderBy;
-
- int eDest = pDest->eDest;
- int iParm = pDest->iSDParm;
-
- int regRow;
- int regRowid;
-
- iTab = pOrderBy->iECursor;
- regRow = sqlite3GetTempReg(pParse);
- if( eDest==SRT_Output || eDest==SRT_Coroutine ){
- pseudoTab = pParse->nTab++;
- sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn);
- regRowid = 0;
- }else{
- regRowid = sqlite3GetTempReg(pParse);
- }
- if( p->selFlags & SF_UseSorter ){
- int regSortOut = ++pParse->nMem;
- int ptab2 = pParse->nTab++;
- sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
- addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
- codeOffset(v, p, addrContinue);
- sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
- sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow);
- sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
- }else{
- addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
- codeOffset(v, p, addrContinue);
- sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow);
- }
- switch( eDest ){
- case SRT_Table:
- case SRT_EphemTab: {
- testcase( eDest==SRT_Table );
- testcase( eDest==SRT_EphemTab );
- sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- break;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case SRT_Set: {
- assert( nColumn==1 );
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid,
- &pDest->affSdst, 1);
- sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
- break;
- }
- case SRT_Mem: {
- assert( nColumn==1 );
- sqlite3ExprCodeMove(pParse, regRow, iParm, 1);
- /* The LIMIT clause will terminate the loop for us */
- break;
- }
-#endif
- default: {
- int i;
- assert( eDest==SRT_Output || eDest==SRT_Coroutine );
- testcase( eDest==SRT_Output );
- testcase( eDest==SRT_Coroutine );
- for(i=0; i<nColumn; i++){
- assert( regRow!=pDest->iSdst+i );
- sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i);
- if( i==0 ){
- sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
- }
- }
- if( eDest==SRT_Output ){
- sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
- sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
- }else{
- sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
- }
- break;
- }
- }
- sqlite3ReleaseTempReg(pParse, regRow);
- sqlite3ReleaseTempReg(pParse, regRowid);
-
- /* The bottom of the loop
- */
- sqlite3VdbeResolveLabel(v, addrContinue);
- if( p->selFlags & SF_UseSorter ){
- sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr);
- }else{
- sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
- }
- sqlite3VdbeResolveLabel(v, addrBreak);
- if( eDest==SRT_Output || eDest==SRT_Coroutine ){
- sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0);
- }
-}
-
-/*
-** Return a pointer to a string containing the 'declaration type' of the
-** expression pExpr. The string may be treated as static by the caller.
-**
-** The declaration type is the exact datatype definition extracted from the
-** original CREATE TABLE statement if the expression is a column. The
-** declaration type for a ROWID field is INTEGER. Exactly when an expression
-** is considered a column can be complex in the presence of subqueries. The
-** result-set expression in all of the following SELECT statements is
-** considered a column by this function.
-**
-** SELECT col FROM tbl;
-** SELECT (SELECT col FROM tbl;
-** SELECT (SELECT col FROM tbl);
-** SELECT abc FROM (SELECT col AS abc FROM tbl);
-**
-** The declaration type for any expression other than a column is NULL.
-*/
-static const char *columnType(
- NameContext *pNC,
- Expr *pExpr,
- const char **pzOriginDb,
- const char **pzOriginTab,
- const char **pzOriginCol
-){
- char const *zType = 0;
- char const *zOriginDb = 0;
- char const *zOriginTab = 0;
- char const *zOriginCol = 0;
- int j;
- if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0;
-
- switch( pExpr->op ){
- case TK_AGG_COLUMN:
- case TK_COLUMN: {
- /* The expression is a column. Locate the table the column is being
- ** extracted from in NameContext.pSrcList. This table may be real
- ** database table or a subquery.
- */
- Table *pTab = 0; /* Table structure column is extracted from */
- Select *pS = 0; /* Select the column is extracted from */
- int iCol = pExpr->iColumn; /* Index of column in pTab */
- testcase( pExpr->op==TK_AGG_COLUMN );
- testcase( pExpr->op==TK_COLUMN );
- while( pNC && !pTab ){
- SrcList *pTabList = pNC->pSrcList;
- for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
- if( j<pTabList->nSrc ){
- pTab = pTabList->a[j].pTab;
- pS = pTabList->a[j].pSelect;
- }else{
- pNC = pNC->pNext;
- }
- }
-
- if( pTab==0 ){
- /* At one time, code such as "SELECT new.x" within a trigger would
- ** cause this condition to run. Since then, we have restructured how
- ** trigger code is generated and so this condition is no longer
- ** possible. However, it can still be true for statements like
- ** the following:
- **
- ** CREATE TABLE t1(col INTEGER);
- ** SELECT (SELECT t1.col) FROM FROM t1;
- **
- ** when columnType() is called on the expression "t1.col" in the
- ** sub-select. In this case, set the column type to NULL, even
- ** though it should really be "INTEGER".
- **
- ** This is not a problem, as the column type of "t1.col" is never
- ** used. When columnType() is called on the expression
- ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
- ** branch below. */
- break;
- }
-
- assert( pTab && pExpr->pTab==pTab );
- if( pS ){
- /* The "table" is actually a sub-select or a view in the FROM clause
- ** of the SELECT statement. Return the declaration type and origin
- ** data for the result-set column of the sub-select.
- */
- if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
- /* If iCol is less than zero, then the expression requests the
- ** rowid of the sub-select or view. This expression is legal (see
- ** test case misc2.2.2) - it always evaluates to NULL.
- */
- NameContext sNC;
- Expr *p = pS->pEList->a[iCol].pExpr;
- sNC.pSrcList = pS->pSrc;
- sNC.pNext = pNC;
- sNC.pParse = pNC->pParse;
- zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
- }
- }else if( ALWAYS(pTab->pSchema) ){
- /* A real table */
- assert( !pS );
- if( iCol<0 ) iCol = pTab->iPKey;
- assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
- if( iCol<0 ){
- zType = "INTEGER";
- zOriginCol = "rowid";
- }else{
- zType = pTab->aCol[iCol].zType;
- zOriginCol = pTab->aCol[iCol].zName;
- }
- zOriginTab = pTab->zName;
- if( pNC->pParse ){
- int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
- zOriginDb = pNC->pParse->db->aDb[iDb].zName;
- }
- }
- break;
- }
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_SELECT: {
- /* The expression is a sub-select. Return the declaration type and
- ** origin info for the single column in the result set of the SELECT
- ** statement.
- */
- NameContext sNC;
- Select *pS = pExpr->x.pSelect;
- Expr *p = pS->pEList->a[0].pExpr;
- assert( ExprHasProperty(pExpr, EP_xIsSelect) );
- sNC.pSrcList = pS->pSrc;
- sNC.pNext = pNC;
- sNC.pParse = pNC->pParse;
- zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
- break;
- }
-#endif
- }
-
- if( pzOriginDb ){
- assert( pzOriginTab && pzOriginCol );
- *pzOriginDb = zOriginDb;
- *pzOriginTab = zOriginTab;
- *pzOriginCol = zOriginCol;
- }
- return zType;
-}
-
-/*
-** Generate code that will tell the VDBE the declaration types of columns
-** in the result set.
-*/
-static void generateColumnTypes(
- Parse *pParse, /* Parser context */
- SrcList *pTabList, /* List of tables */
- ExprList *pEList /* Expressions defining the result set */
-){
-#ifndef SQLITE_OMIT_DECLTYPE
- Vdbe *v = pParse->pVdbe;
- int i;
- NameContext sNC;
- sNC.pSrcList = pTabList;
- sNC.pParse = pParse;
- for(i=0; i<pEList->nExpr; i++){
- Expr *p = pEList->a[i].pExpr;
- const char *zType;
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
- const char *zOrigDb = 0;
- const char *zOrigTab = 0;
- const char *zOrigCol = 0;
- zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
-
- /* The vdbe must make its own copy of the column-type and other
- ** column specific strings, in case the schema is reset before this
- ** virtual machine is deleted.
- */
- sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT);
- sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
- sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
-#else
- zType = columnType(&sNC, p, 0, 0, 0);
-#endif
- sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
- }
-#endif /* SQLITE_OMIT_DECLTYPE */
-}
-
-/*
-** Generate code that will tell the VDBE the names of columns
-** in the result set. This information is used to provide the
-** azCol[] values in the callback.
-*/
-static void generateColumnNames(
- Parse *pParse, /* Parser context */
- SrcList *pTabList, /* List of tables */
- ExprList *pEList /* Expressions defining the result set */
-){
- Vdbe *v = pParse->pVdbe;
- int i, j;
- sqlite3 *db = pParse->db;
- int fullNames, shortNames;
-
-#ifndef SQLITE_OMIT_EXPLAIN
- /* If this is an EXPLAIN, skip this step */
- if( pParse->explain ){
- return;
- }
-#endif
-
- if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return;
- pParse->colNamesSet = 1;
- fullNames = (db->flags & SQLITE_FullColNames)!=0;
- shortNames = (db->flags & SQLITE_ShortColNames)!=0;
- sqlite3VdbeSetNumCols(v, pEList->nExpr);
- for(i=0; i<pEList->nExpr; i++){
- Expr *p;
- p = pEList->a[i].pExpr;
- if( NEVER(p==0) ) continue;
- if( pEList->a[i].zName ){
- char *zName = pEList->a[i].zName;
- sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
- }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && pTabList ){
- Table *pTab;
- char *zCol;
- int iCol = p->iColumn;
- for(j=0; ALWAYS(j<pTabList->nSrc); j++){
- if( pTabList->a[j].iCursor==p->iTable ) break;
- }
- assert( j<pTabList->nSrc );
- pTab = pTabList->a[j].pTab;
- if( iCol<0 ) iCol = pTab->iPKey;
- assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
- if( iCol<0 ){
- zCol = "rowid";
- }else{
- zCol = pTab->aCol[iCol].zName;
- }
- if( !shortNames && !fullNames ){
- sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
- }else if( fullNames ){
- char *zName = 0;
- zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol);
- sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC);
- }else{
- sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
- }
- }else{
- sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
- }
- }
- generateColumnTypes(pParse, pTabList, pEList);
-}
-
-/*
-** Given a an expression list (which is really the list of expressions
-** that form the result set of a SELECT statement) compute appropriate
-** column names for a table that would hold the expression list.
-**
-** All column names will be unique.
-**
-** Only the column names are computed. Column.zType, Column.zColl,
-** and other fields of Column are zeroed.
-**
-** Return SQLITE_OK on success. If a memory allocation error occurs,
-** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM.
-*/
-static int selectColumnsFromExprList(
- Parse *pParse, /* Parsing context */
- ExprList *pEList, /* Expr list from which to derive column names */
- i16 *pnCol, /* Write the number of columns here */
- Column **paCol /* Write the new column list here */
-){
- sqlite3 *db = pParse->db; /* Database connection */
- int i, j; /* Loop counters */
- int cnt; /* Index added to make the name unique */
- Column *aCol, *pCol; /* For looping over result columns */
- int nCol; /* Number of columns in the result set */
- Expr *p; /* Expression for a single result column */
- char *zName; /* Column name */
- int nName; /* Size of name in zName[] */
-
- if( pEList ){
- nCol = pEList->nExpr;
- aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
- testcase( aCol==0 );
- }else{
- nCol = 0;
- aCol = 0;
- }
- *pnCol = nCol;
- *paCol = aCol;
-
- for(i=0, pCol=aCol; i<nCol; i++, pCol++){
- /* Get an appropriate name for the column
- */
- p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
- assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
- || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
- if( (zName = pEList->a[i].zName)!=0 ){
- /* If the column contains an "AS <name>" phrase, use <name> as the name */
- zName = sqlite3DbStrDup(db, zName);
- }else{
- Expr *pColExpr = p; /* The expression that is the result column name */
- Table *pTab; /* Table associated with this expression */
- while( pColExpr->op==TK_DOT ){
- pColExpr = pColExpr->pRight;
- assert( pColExpr!=0 );
- }
- if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
- /* For columns use the column name name */
- int iCol = pColExpr->iColumn;
- pTab = pColExpr->pTab;
- if( iCol<0 ) iCol = pTab->iPKey;
- zName = sqlite3MPrintf(db, "%s",
- iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
- }else if( pColExpr->op==TK_ID ){
- assert( !ExprHasProperty(pColExpr, EP_IntValue) );
- zName = sqlite3MPrintf(db, "%s", pColExpr->u.zToken);
- }else{
- /* Use the original text of the column expression as its name */
- zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan);
- }
- }
- if( db->mallocFailed ){
- sqlite3DbFree(db, zName);
- break;
- }
-
- /* Make sure the column name is unique. If the name is not unique,
- ** append a integer to the name so that it becomes unique.
- */
- nName = sqlite3Strlen30(zName);
- for(j=cnt=0; j<i; j++){
- if( sqlite3StrICmp(aCol[j].zName, zName)==0 ){
- char *zNewName;
- zName[nName] = 0;
- zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
- sqlite3DbFree(db, zName);
- zName = zNewName;
- j = -1;
- if( zName==0 ) break;
- }
- }
- pCol->zName = zName;
- }
- if( db->mallocFailed ){
- for(j=0; j<i; j++){
- sqlite3DbFree(db, aCol[j].zName);
- }
- sqlite3DbFree(db, aCol);
- *paCol = 0;
- *pnCol = 0;
- return SQLITE_NOMEM;
- }
- return SQLITE_OK;
-}
-
-/*
-** Add type and collation information to a column list based on
-** a SELECT statement.
-**
-** The column list presumably came from selectColumnNamesFromExprList().
-** The column list has only names, not types or collations. This
-** routine goes through and adds the types and collations.
-**
-** This routine requires that all identifiers in the SELECT
-** statement be resolved.
-*/
-static void selectAddColumnTypeAndCollation(
- Parse *pParse, /* Parsing contexts */
- int nCol, /* Number of columns */
- Column *aCol, /* List of columns */
- Select *pSelect /* SELECT used to determine types and collations */
-){
- sqlite3 *db = pParse->db;
- NameContext sNC;
- Column *pCol;
- CollSeq *pColl;
- int i;
- Expr *p;
- struct ExprList_item *a;
-
- assert( pSelect!=0 );
- assert( (pSelect->selFlags & SF_Resolved)!=0 );
- assert( nCol==pSelect->pEList->nExpr || db->mallocFailed );
- if( db->mallocFailed ) return;
- memset(&sNC, 0, sizeof(sNC));
- sNC.pSrcList = pSelect->pSrc;
- a = pSelect->pEList->a;
- for(i=0, pCol=aCol; i<nCol; i++, pCol++){
- p = a[i].pExpr;
- pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
- pCol->affinity = sqlite3ExprAffinity(p);
- if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
- pColl = sqlite3ExprCollSeq(pParse, p);
- if( pColl ){
- pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
- }
- }
-}
-
-/*
-** Given a SELECT statement, generate a Table structure that describes
-** the result set of that SELECT.
-*/
-SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
- Table *pTab;
- sqlite3 *db = pParse->db;
- int savedFlags;
-
- savedFlags = db->flags;
- db->flags &= ~SQLITE_FullColNames;
- db->flags |= SQLITE_ShortColNames;
- sqlite3SelectPrep(pParse, pSelect, 0);
- if( pParse->nErr ) return 0;
- while( pSelect->pPrior ) pSelect = pSelect->pPrior;
- db->flags = savedFlags;
- pTab = sqlite3DbMallocZero(db, sizeof(Table) );
- if( pTab==0 ){
- return 0;
- }
- /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
- ** is disabled */
- assert( db->lookaside.bEnabled==0 );
- pTab->nRef = 1;
- pTab->zName = 0;
- pTab->nRowEst = 1000000;
- selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);
- pTab->iPKey = -1;
- if( db->mallocFailed ){
- sqlite3DeleteTable(db, pTab);
- return 0;
- }
- return pTab;
-}
-
-/*
-** Get a VDBE for the given parser context. Create a new one if necessary.
-** If an error occurs, return NULL and leave a message in pParse.
-*/
-SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
- Vdbe *v = pParse->pVdbe;
- if( v==0 ){
- v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
-#ifndef SQLITE_OMIT_TRACE
- if( v ){
- sqlite3VdbeAddOp0(v, OP_Trace);
- }
-#endif
- }
- return v;
-}
-
-
-/*
-** Compute the iLimit and iOffset fields of the SELECT based on the
-** pLimit and pOffset expressions. pLimit and pOffset hold the expressions
-** that appear in the original SQL statement after the LIMIT and OFFSET
-** keywords. Or NULL if those keywords are omitted. iLimit and iOffset
-** are the integer memory register numbers for counters used to compute
-** the limit and offset. If there is no limit and/or offset, then
-** iLimit and iOffset are negative.
-**
-** This routine changes the values of iLimit and iOffset only if
-** a limit or offset is defined by pLimit and pOffset. iLimit and
-** iOffset should have been preset to appropriate default values
-** (usually but not always -1) prior to calling this routine.
-** Only if pLimit!=0 or pOffset!=0 do the limit registers get
-** redefined. The UNION ALL operator uses this property to force
-** the reuse of the same limit and offset registers across multiple
-** SELECT statements.
-*/
-static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
- Vdbe *v = 0;
- int iLimit = 0;
- int iOffset;
- int addr1, n;
- if( p->iLimit ) return;
-
- /*
- ** "LIMIT -1" always shows all rows. There is some
- ** contraversy about what the correct behavior should be.
- ** The current implementation interprets "LIMIT 0" to mean
- ** no rows.
- */
- sqlite3ExprCacheClear(pParse);
- assert( p->pOffset==0 || p->pLimit!=0 );
- if( p->pLimit ){
- p->iLimit = iLimit = ++pParse->nMem;
- v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return; /* VDBE should have already been allocated */
- if( sqlite3ExprIsInteger(p->pLimit, &n) ){
- sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
- VdbeComment((v, "LIMIT counter"));
- if( n==0 ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
- }else{
- if( p->nSelectRow > (double)n ) p->nSelectRow = (double)n;
- }
- }else{
- sqlite3ExprCode(pParse, p->pLimit, iLimit);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
- VdbeComment((v, "LIMIT counter"));
- sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
- }
- if( p->pOffset ){
- p->iOffset = iOffset = ++pParse->nMem;
- pParse->nMem++; /* Allocate an extra register for limit+offset */
- sqlite3ExprCode(pParse, p->pOffset, iOffset);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset);
- VdbeComment((v, "OFFSET counter"));
- addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
- sqlite3VdbeJumpHere(v, addr1);
- sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
- VdbeComment((v, "LIMIT+OFFSET"));
- addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
- sqlite3VdbeJumpHere(v, addr1);
- }
- }
-}
-
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-/*
-** Return the appropriate collating sequence for the iCol-th column of
-** the result set for the compound-select statement "p". Return NULL if
-** the column has no default collating sequence.
-**
-** The collating sequence for the compound select is taken from the
-** left-most term of the select that has a collating sequence.
-*/
-static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
- CollSeq *pRet;
- if( p->pPrior ){
- pRet = multiSelectCollSeq(pParse, p->pPrior, iCol);
- }else{
- pRet = 0;
- }
- assert( iCol>=0 );
- if( pRet==0 && iCol<p->pEList->nExpr ){
- pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
- }
- return pRet;
-}
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
-
-/* Forward reference */
-static int multiSelectOrderBy(
- Parse *pParse, /* Parsing context */
- Select *p, /* The right-most of SELECTs to be coded */
- SelectDest *pDest /* What to do with query results */
-);
-
-
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-/*
-** This routine is called to process a compound query form from
-** two or more separate queries using UNION, UNION ALL, EXCEPT, or
-** INTERSECT
-**
-** "p" points to the right-most of the two queries. the query on the
-** left is p->pPrior. The left query could also be a compound query
-** in which case this routine will be called recursively.
-**
-** The results of the total query are to be written into a destination
-** of type eDest with parameter iParm.
-**
-** Example 1: Consider a three-way compound SQL statement.
-**
-** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
-**
-** This statement is parsed up as follows:
-**
-** SELECT c FROM t3
-** |
-** `-----> SELECT b FROM t2
-** |
-** `------> SELECT a FROM t1
-**
-** The arrows in the diagram above represent the Select.pPrior pointer.
-** So if this routine is called with p equal to the t3 query, then
-** pPrior will be the t2 query. p->op will be TK_UNION in this case.
-**
-** Notice that because of the way SQLite parses compound SELECTs, the
-** individual selects always group from left to right.
-*/
-static int multiSelect(
- Parse *pParse, /* Parsing context */
- Select *p, /* The right-most of SELECTs to be coded */
- SelectDest *pDest /* What to do with query results */
-){
- int rc = SQLITE_OK; /* Success code from a subroutine */
- Select *pPrior; /* Another SELECT immediately to our left */
- Vdbe *v; /* Generate code to this VDBE */
- SelectDest dest; /* Alternative data destination */
- Select *pDelete = 0; /* Chain of simple selects to delete */
- sqlite3 *db; /* Database connection */
-#ifndef SQLITE_OMIT_EXPLAIN
- int iSub1; /* EQP id of left-hand query */
- int iSub2; /* EQP id of right-hand query */
-#endif
-
- /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
- ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
- */
- assert( p && p->pPrior ); /* Calling function guarantees this much */
- db = pParse->db;
- pPrior = p->pPrior;
- assert( pPrior->pRightmost!=pPrior );
- assert( pPrior->pRightmost==p->pRightmost );
- dest = *pDest;
- if( pPrior->pOrderBy ){
- sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
- selectOpName(p->op));
- rc = 1;
- goto multi_select_end;
- }
- if( pPrior->pLimit ){
- sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
- selectOpName(p->op));
- rc = 1;
- goto multi_select_end;
- }
-
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 ); /* The VDBE already created by calling function */
-
- /* Create the destination temporary table if necessary
- */
- if( dest.eDest==SRT_EphemTab ){
- assert( p->pEList );
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
- sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
- dest.eDest = SRT_Table;
- }
-
- /* Make sure all SELECTs in the statement have the same number of elements
- ** in their result sets.
- */
- assert( p->pEList && pPrior->pEList );
- if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
- if( p->selFlags & SF_Values ){
- sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
- }else{
- sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
- " do not have the same number of result columns", selectOpName(p->op));
- }
- rc = 1;
- goto multi_select_end;
- }
-
- /* Compound SELECTs that have an ORDER BY clause are handled separately.
- */
- if( p->pOrderBy ){
- return multiSelectOrderBy(pParse, p, pDest);
- }
-
- /* Generate code for the left and right SELECT statements.
- */
- switch( p->op ){
- case TK_ALL: {
- int addr = 0;
- int nLimit;
- assert( !pPrior->pLimit );
- pPrior->pLimit = p->pLimit;
- pPrior->pOffset = p->pOffset;
- explainSetInteger(iSub1, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, pPrior, &dest);
- p->pLimit = 0;
- p->pOffset = 0;
- if( rc ){
- goto multi_select_end;
- }
- p->pPrior = 0;
- p->iLimit = pPrior->iLimit;
- p->iOffset = pPrior->iOffset;
- if( p->iLimit ){
- addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit);
- VdbeComment((v, "Jump ahead if LIMIT reached"));
- }
- explainSetInteger(iSub2, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, p, &dest);
- testcase( rc!=SQLITE_OK );
- pDelete = p->pPrior;
- p->pPrior = pPrior;
- p->nSelectRow += pPrior->nSelectRow;
- if( pPrior->pLimit
- && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
- && p->nSelectRow > (double)nLimit
- ){
- p->nSelectRow = (double)nLimit;
- }
- if( addr ){
- sqlite3VdbeJumpHere(v, addr);
- }
- break;
- }
- case TK_EXCEPT:
- case TK_UNION: {
- int unionTab; /* Cursor number of the temporary table holding result */
- u8 op = 0; /* One of the SRT_ operations to apply to self */
- int priorOp; /* The SRT_ operation to apply to prior selects */
- Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
- int addr;
- SelectDest uniondest;
-
- testcase( p->op==TK_EXCEPT );
- testcase( p->op==TK_UNION );
- priorOp = SRT_Union;
- if( dest.eDest==priorOp && ALWAYS(!p->pLimit &&!p->pOffset) ){
- /* We can reuse a temporary table generated by a SELECT to our
- ** right.
- */
- assert( p->pRightmost!=p ); /* Can only happen for leftward elements
- ** of a 3-way or more compound */
- assert( p->pLimit==0 ); /* Not allowed on leftward elements */
- assert( p->pOffset==0 ); /* Not allowed on leftward elements */
- unionTab = dest.iSDParm;
- }else{
- /* We will need to create our own temporary table to hold the
- ** intermediate results.
- */
- unionTab = pParse->nTab++;
- assert( p->pOrderBy==0 );
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
- assert( p->addrOpenEphm[0] == -1 );
- p->addrOpenEphm[0] = addr;
- p->pRightmost->selFlags |= SF_UsesEphemeral;
- assert( p->pEList );
- }
-
- /* Code the SELECT statements to our left
- */
- assert( !pPrior->pOrderBy );
- sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
- explainSetInteger(iSub1, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, pPrior, &uniondest);
- if( rc ){
- goto multi_select_end;
- }
-
- /* Code the current SELECT statement
- */
- if( p->op==TK_EXCEPT ){
- op = SRT_Except;
- }else{
- assert( p->op==TK_UNION );
- op = SRT_Union;
- }
- p->pPrior = 0;
- pLimit = p->pLimit;
- p->pLimit = 0;
- pOffset = p->pOffset;
- p->pOffset = 0;
- uniondest.eDest = op;
- explainSetInteger(iSub2, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, p, &uniondest);
- testcase( rc!=SQLITE_OK );
- /* Query flattening in sqlite3Select() might refill p->pOrderBy.
- ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
- sqlite3ExprListDelete(db, p->pOrderBy);
- pDelete = p->pPrior;
- p->pPrior = pPrior;
- p->pOrderBy = 0;
- if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow;
- sqlite3ExprDelete(db, p->pLimit);
- p->pLimit = pLimit;
- p->pOffset = pOffset;
- p->iLimit = 0;
- p->iOffset = 0;
-
- /* Convert the data in the temporary table into whatever form
- ** it is that we currently need.
- */
- assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
- if( dest.eDest!=priorOp ){
- int iCont, iBreak, iStart;
- assert( p->pEList );
- if( dest.eDest==SRT_Output ){
- Select *pFirst = p;
- while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
- }
- iBreak = sqlite3VdbeMakeLabel(v);
- iCont = sqlite3VdbeMakeLabel(v);
- computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
- iStart = sqlite3VdbeCurrentAddr(v);
- selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
- 0, 0, &dest, iCont, iBreak);
- sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
- sqlite3VdbeResolveLabel(v, iBreak);
- sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
- }
- break;
- }
- default: assert( p->op==TK_INTERSECT ); {
- int tab1, tab2;
- int iCont, iBreak, iStart;
- Expr *pLimit, *pOffset;
- int addr;
- SelectDest intersectdest;
- int r1;
-
- /* INTERSECT is different from the others since it requires
- ** two temporary tables. Hence it has its own case. Begin
- ** by allocating the tables we will need.
- */
- tab1 = pParse->nTab++;
- tab2 = pParse->nTab++;
- assert( p->pOrderBy==0 );
-
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
- assert( p->addrOpenEphm[0] == -1 );
- p->addrOpenEphm[0] = addr;
- p->pRightmost->selFlags |= SF_UsesEphemeral;
- assert( p->pEList );
-
- /* Code the SELECTs to our left into temporary table "tab1".
- */
- sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
- explainSetInteger(iSub1, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, pPrior, &intersectdest);
- if( rc ){
- goto multi_select_end;
- }
-
- /* Code the current SELECT into temporary table "tab2"
- */
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
- assert( p->addrOpenEphm[1] == -1 );
- p->addrOpenEphm[1] = addr;
- p->pPrior = 0;
- pLimit = p->pLimit;
- p->pLimit = 0;
- pOffset = p->pOffset;
- p->pOffset = 0;
- intersectdest.iSDParm = tab2;
- explainSetInteger(iSub2, pParse->iNextSelectId);
- rc = sqlite3Select(pParse, p, &intersectdest);
- testcase( rc!=SQLITE_OK );
- pDelete = p->pPrior;
- p->pPrior = pPrior;
- if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
- sqlite3ExprDelete(db, p->pLimit);
- p->pLimit = pLimit;
- p->pOffset = pOffset;
-
- /* Generate code to take the intersection of the two temporary
- ** tables.
- */
- assert( p->pEList );
- if( dest.eDest==SRT_Output ){
- Select *pFirst = p;
- while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
- }
- iBreak = sqlite3VdbeMakeLabel(v);
- iCont = sqlite3VdbeMakeLabel(v);
- computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak);
- r1 = sqlite3GetTempReg(pParse);
- iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
- sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
- sqlite3ReleaseTempReg(pParse, r1);
- selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
- 0, 0, &dest, iCont, iBreak);
- sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
- sqlite3VdbeResolveLabel(v, iBreak);
- sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
- sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
- break;
- }
- }
-
- explainComposite(pParse, p->op, iSub1, iSub2, p->op!=TK_ALL);
-
- /* Compute collating sequences used by
- ** temporary tables needed to implement the compound select.
- ** Attach the KeyInfo structure to all temporary tables.
- **
- ** This section is run by the right-most SELECT statement only.
- ** SELECT statements to the left always skip this part. The right-most
- ** SELECT might also skip this part if it has no ORDER BY clause and
- ** no temp tables are required.
- */
- if( p->selFlags & SF_UsesEphemeral ){
- int i; /* Loop counter */
- KeyInfo *pKeyInfo; /* Collating sequence for the result set */
- Select *pLoop; /* For looping through SELECT statements */
- CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
- int nCol; /* Number of columns in result set */
-
- assert( p->pRightmost==p );
- nCol = p->pEList->nExpr;
- pKeyInfo = sqlite3DbMallocZero(db,
- sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
- if( !pKeyInfo ){
- rc = SQLITE_NOMEM;
- goto multi_select_end;
- }
-
- pKeyInfo->enc = ENC(db);
- pKeyInfo->nField = (u16)nCol;
-
- for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
- *apColl = multiSelectCollSeq(pParse, p, i);
- if( 0==*apColl ){
- *apColl = db->pDfltColl;
- }
- }
- pKeyInfo->aSortOrder = (u8*)apColl;
-
- for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
- for(i=0; i<2; i++){
- int addr = pLoop->addrOpenEphm[i];
- if( addr<0 ){
- /* If [0] is unused then [1] is also unused. So we can
- ** always safely abort as soon as the first unused slot is found */
- assert( pLoop->addrOpenEphm[1]<0 );
- break;
- }
- sqlite3VdbeChangeP2(v, addr, nCol);
- sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO);
- pLoop->addrOpenEphm[i] = -1;
- }
- }
- sqlite3DbFree(db, pKeyInfo);
- }
-
-multi_select_end:
- pDest->iSdst = dest.iSdst;
- pDest->nSdst = dest.nSdst;
- sqlite3SelectDelete(db, pDelete);
- return rc;
-}
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
-
-/*
-** Code an output subroutine for a coroutine implementation of a
-** SELECT statment.
-**
-** The data to be output is contained in pIn->iSdst. There are
-** pIn->nSdst columns to be output. pDest is where the output should
-** be sent.
-**
-** regReturn is the number of the register holding the subroutine
-** return address.
-**
-** If regPrev>0 then it is the first register in a vector that
-** records the previous output. mem[regPrev] is a flag that is false
-** if there has been no previous output. If regPrev>0 then code is
-** generated to suppress duplicates. pKeyInfo is used for comparing
-** keys.
-**
-** If the LIMIT found in p->iLimit is reached, jump immediately to
-** iBreak.
-*/
-static int generateOutputSubroutine(
- Parse *pParse, /* Parsing context */
- Select *p, /* The SELECT statement */
- SelectDest *pIn, /* Coroutine supplying data */
- SelectDest *pDest, /* Where to send the data */
- int regReturn, /* The return address register */
- int regPrev, /* Previous result register. No uniqueness if 0 */
- KeyInfo *pKeyInfo, /* For comparing with previous entry */
- int p4type, /* The p4 type for pKeyInfo */
- int iBreak /* Jump here if we hit the LIMIT */
-){
- Vdbe *v = pParse->pVdbe;
- int iContinue;
- int addr;
-
- addr = sqlite3VdbeCurrentAddr(v);
- iContinue = sqlite3VdbeMakeLabel(v);
-
- /* Suppress duplicates for UNION, EXCEPT, and INTERSECT
- */
- if( regPrev ){
- int j1, j2;
- j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
- j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
- (char*)pKeyInfo, p4type);
- sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
- }
- if( pParse->db->mallocFailed ) return 0;
-
- /* Suppress the first OFFSET entries if there is an OFFSET clause
- */
- codeOffset(v, p, iContinue);
-
- switch( pDest->eDest ){
- /* Store the result as data using a unique key.
- */
- case SRT_Table:
- case SRT_EphemTab: {
- int r1 = sqlite3GetTempReg(pParse);
- int r2 = sqlite3GetTempReg(pParse);
- testcase( pDest->eDest==SRT_Table );
- testcase( pDest->eDest==SRT_EphemTab );
- sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
- sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
- sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- sqlite3ReleaseTempReg(pParse, r2);
- sqlite3ReleaseTempReg(pParse, r1);
- break;
- }
-
-#ifndef SQLITE_OMIT_SUBQUERY
- /* If we are creating a set for an "expr IN (SELECT ...)" construct,
- ** then there should be a single item on the stack. Write this
- ** item into the set table with bogus data.
- */
- case SRT_Set: {
- int r1;
- assert( pIn->nSdst==1 );
- pDest->affSdst =
- sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
- r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1);
- sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
- sqlite3ReleaseTempReg(pParse, r1);
- break;
- }
-
-#if 0 /* Never occurs on an ORDER BY query */
- /* If any row exist in the result set, record that fact and abort.
- */
- case SRT_Exists: {
- sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm);
- /* The LIMIT clause will terminate the loop for us */
- break;
- }
-#endif
-
- /* If this is a scalar select that is part of an expression, then
- ** store the results in the appropriate memory cell and break out
- ** of the scan loop.
- */
- case SRT_Mem: {
- assert( pIn->nSdst==1 );
- sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
- /* The LIMIT clause will jump out of the loop for us */
- break;
- }
-#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
-
- /* The results are stored in a sequence of registers
- ** starting at pDest->iSdst. Then the co-routine yields.
- */
- case SRT_Coroutine: {
- if( pDest->iSdst==0 ){
- pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
- pDest->nSdst = pIn->nSdst;
- }
- sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
- sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
- break;
- }
-
- /* If none of the above, then the result destination must be
- ** SRT_Output. This routine is never called with any other
- ** destination other than the ones handled above or SRT_Output.
- **
- ** For SRT_Output, results are stored in a sequence of registers.
- ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to
- ** return the next row of result.
- */
- default: {
- assert( pDest->eDest==SRT_Output );
- sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
- sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
- break;
- }
- }
-
- /* Jump to the end of the loop if the LIMIT is reached.
- */
- if( p->iLimit ){
- sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
- }
-
- /* Generate the subroutine return
- */
- sqlite3VdbeResolveLabel(v, iContinue);
- sqlite3VdbeAddOp1(v, OP_Return, regReturn);
-
- return addr;
-}
-
-/*
-** Alternative compound select code generator for cases when there
-** is an ORDER BY clause.
-**
-** We assume a query of the following form:
-**
-** <selectA> <operator> <selectB> ORDER BY <orderbylist>
-**
-** <operator> is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea
-** is to code both <selectA> and <selectB> with the ORDER BY clause as
-** co-routines. Then run the co-routines in parallel and merge the results
-** into the output. In addition to the two coroutines (called selectA and
-** selectB) there are 7 subroutines:
-**
-** outA: Move the output of the selectA coroutine into the output
-** of the compound query.
-**
-** outB: Move the output of the selectB coroutine into the output
-** of the compound query. (Only generated for UNION and
-** UNION ALL. EXCEPT and INSERTSECT never output a row that
-** appears only in B.)
-**
-** AltB: Called when there is data from both coroutines and A<B.
-**
-** AeqB: Called when there is data from both coroutines and A==B.
-**
-** AgtB: Called when there is data from both coroutines and A>B.
-**
-** EofA: Called when data is exhausted from selectA.
-**
-** EofB: Called when data is exhausted from selectB.
-**
-** The implementation of the latter five subroutines depend on which
-** <operator> is used:
-**
-**
-** UNION ALL UNION EXCEPT INTERSECT
-** ------------- ----------------- -------------- -----------------
-** AltB: outA, nextA outA, nextA outA, nextA nextA
-**
-** AeqB: outA, nextA nextA nextA outA, nextA
-**
-** AgtB: outB, nextB outB, nextB nextB nextB
-**
-** EofA: outB, nextB outB, nextB halt halt
-**
-** EofB: outA, nextA outA, nextA outA, nextA halt
-**
-** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA
-** causes an immediate jump to EofA and an EOF on B following nextB causes
-** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or
-** following nextX causes a jump to the end of the select processing.
-**
-** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled
-** within the output subroutine. The regPrev register set holds the previously
-** output value. A comparison is made against this value and the output
-** is skipped if the next results would be the same as the previous.
-**
-** The implementation plan is to implement the two coroutines and seven
-** subroutines first, then put the control logic at the bottom. Like this:
-**
-** goto Init
-** coA: coroutine for left query (A)
-** coB: coroutine for right query (B)
-** outA: output one row of A
-** outB: output one row of B (UNION and UNION ALL only)
-** EofA: ...
-** EofB: ...
-** AltB: ...
-** AeqB: ...
-** AgtB: ...
-** Init: initialize coroutine registers
-** yield coA
-** if eof(A) goto EofA
-** yield coB
-** if eof(B) goto EofB
-** Cmpr: Compare A, B
-** Jump AltB, AeqB, AgtB
-** End: ...
-**
-** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not
-** actually called using Gosub and they do not Return. EofA and EofB loop
-** until all data is exhausted then jump to the "end" labe. AltB, AeqB,
-** and AgtB jump to either L2 or to one of EofA or EofB.
-*/
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-static int multiSelectOrderBy(
- Parse *pParse, /* Parsing context */
- Select *p, /* The right-most of SELECTs to be coded */
- SelectDest *pDest /* What to do with query results */
-){
- int i, j; /* Loop counters */
- Select *pPrior; /* Another SELECT immediately to our left */
- Vdbe *v; /* Generate code to this VDBE */
- SelectDest destA; /* Destination for coroutine A */
- SelectDest destB; /* Destination for coroutine B */
- int regAddrA; /* Address register for select-A coroutine */
- int regEofA; /* Flag to indicate when select-A is complete */
- int regAddrB; /* Address register for select-B coroutine */
- int regEofB; /* Flag to indicate when select-B is complete */
- int addrSelectA; /* Address of the select-A coroutine */
- int addrSelectB; /* Address of the select-B coroutine */
- int regOutA; /* Address register for the output-A subroutine */
- int regOutB; /* Address register for the output-B subroutine */
- int addrOutA; /* Address of the output-A subroutine */
- int addrOutB = 0; /* Address of the output-B subroutine */
- int addrEofA; /* Address of the select-A-exhausted subroutine */
- int addrEofB; /* Address of the select-B-exhausted subroutine */
- int addrAltB; /* Address of the A<B subroutine */
- int addrAeqB; /* Address of the A==B subroutine */
- int addrAgtB; /* Address of the A>B subroutine */
- int regLimitA; /* Limit register for select-A */
- int regLimitB; /* Limit register for select-A */
- int regPrev; /* A range of registers to hold previous output */
- int savedLimit; /* Saved value of p->iLimit */
- int savedOffset; /* Saved value of p->iOffset */
- int labelCmpr; /* Label for the start of the merge algorithm */
- int labelEnd; /* Label for the end of the overall SELECT stmt */
- int j1; /* Jump instructions that get retargetted */
- int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
- KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
- KeyInfo *pKeyMerge; /* Comparison information for merging rows */
- sqlite3 *db; /* Database connection */
- ExprList *pOrderBy; /* The ORDER BY clause */
- int nOrderBy; /* Number of terms in the ORDER BY clause */
- int *aPermute; /* Mapping from ORDER BY terms to result set columns */
-#ifndef SQLITE_OMIT_EXPLAIN
- int iSub1; /* EQP id of left-hand query */
- int iSub2; /* EQP id of right-hand query */
-#endif
-
- assert( p->pOrderBy!=0 );
- assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */
- db = pParse->db;
- v = pParse->pVdbe;
- assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */
- labelEnd = sqlite3VdbeMakeLabel(v);
- labelCmpr = sqlite3VdbeMakeLabel(v);
-
-
- /* Patch up the ORDER BY clause
- */
- op = p->op;
- pPrior = p->pPrior;
- assert( pPrior->pOrderBy==0 );
- pOrderBy = p->pOrderBy;
- assert( pOrderBy );
- nOrderBy = pOrderBy->nExpr;
-
- /* For operators other than UNION ALL we have to make sure that
- ** the ORDER BY clause covers every term of the result set. Add
- ** terms to the ORDER BY clause as necessary.
- */
- if( op!=TK_ALL ){
- for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
- struct ExprList_item *pItem;
- for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
- assert( pItem->iOrderByCol>0 );
- if( pItem->iOrderByCol==i ) break;
- }
- if( j==nOrderBy ){
- Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
- if( pNew==0 ) return SQLITE_NOMEM;
- pNew->flags |= EP_IntValue;
- pNew->u.iValue = i;
- pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
- if( pOrderBy ) pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
- }
- }
- }
-
- /* Compute the comparison permutation and keyinfo that is used with
- ** the permutation used to determine if the next
- ** row of results comes from selectA or selectB. Also add explicit
- ** collations to the ORDER BY clause terms so that when the subqueries
- ** to the right and the left are evaluated, they use the correct
- ** collation.
- */
- aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
- if( aPermute ){
- struct ExprList_item *pItem;
- for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
- assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
- aPermute[i] = pItem->iOrderByCol - 1;
- }
- pKeyMerge =
- sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
- if( pKeyMerge ){
- pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
- pKeyMerge->nField = (u16)nOrderBy;
- pKeyMerge->enc = ENC(db);
- for(i=0; i<nOrderBy; i++){
- CollSeq *pColl;
- Expr *pTerm = pOrderBy->a[i].pExpr;
- if( pTerm->flags & EP_Collate ){
- pColl = sqlite3ExprCollSeq(pParse, pTerm);
- }else{
- pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
- if( pColl==0 ) pColl = db->pDfltColl;
- pOrderBy->a[i].pExpr =
- sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
- }
- pKeyMerge->aColl[i] = pColl;
- pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
- }
- }
- }else{
- pKeyMerge = 0;
- }
-
- /* Reattach the ORDER BY clause to the query.
- */
- p->pOrderBy = pOrderBy;
- pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0);
-
- /* Allocate a range of temporary registers and the KeyInfo needed
- ** for the logic that removes duplicate result rows when the
- ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL).
- */
- if( op==TK_ALL ){
- regPrev = 0;
- }else{
- int nExpr = p->pEList->nExpr;
- assert( nOrderBy>=nExpr || db->mallocFailed );
- regPrev = sqlite3GetTempRange(pParse, nExpr+1);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
- pKeyDup = sqlite3DbMallocZero(db,
- sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
- if( pKeyDup ){
- pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
- pKeyDup->nField = (u16)nExpr;
- pKeyDup->enc = ENC(db);
- for(i=0; i<nExpr; i++){
- pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
- pKeyDup->aSortOrder[i] = 0;
- }
- }
- }
-
- /* Separate the left and the right query from one another
- */
- p->pPrior = 0;
- sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER");
- if( pPrior->pPrior==0 ){
- sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER");
- }
-
- /* Compute the limit registers */
- computeLimitRegisters(pParse, p, labelEnd);
- if( p->iLimit && op==TK_ALL ){
- regLimitA = ++pParse->nMem;
- regLimitB = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit,
- regLimitA);
- sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB);
- }else{
- regLimitA = regLimitB = 0;
- }
- sqlite3ExprDelete(db, p->pLimit);
- p->pLimit = 0;
- sqlite3ExprDelete(db, p->pOffset);
- p->pOffset = 0;
-
- regAddrA = ++pParse->nMem;
- regEofA = ++pParse->nMem;
- regAddrB = ++pParse->nMem;
- regEofB = ++pParse->nMem;
- regOutA = ++pParse->nMem;
- regOutB = ++pParse->nMem;
- sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
- sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
-
- /* Jump past the various subroutines and coroutines to the main
- ** merge loop
- */
- j1 = sqlite3VdbeAddOp0(v, OP_Goto);
- addrSelectA = sqlite3VdbeCurrentAddr(v);
-
-
- /* Generate a coroutine to evaluate the SELECT statement to the
- ** left of the compound operator - the "A" select.
- */
- VdbeNoopComment((v, "Begin coroutine for left SELECT"));
- pPrior->iLimit = regLimitA;
- explainSetInteger(iSub1, pParse->iNextSelectId);
- sqlite3Select(pParse, pPrior, &destA);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- VdbeNoopComment((v, "End coroutine for left SELECT"));
-
- /* Generate a coroutine to evaluate the SELECT statement on
- ** the right - the "B" select
- */
- addrSelectB = sqlite3VdbeCurrentAddr(v);
- VdbeNoopComment((v, "Begin coroutine for right SELECT"));
- savedLimit = p->iLimit;
- savedOffset = p->iOffset;
- p->iLimit = regLimitB;
- p->iOffset = 0;
- explainSetInteger(iSub2, pParse->iNextSelectId);
- sqlite3Select(pParse, p, &destB);
- p->iLimit = savedLimit;
- p->iOffset = savedOffset;
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofB);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
- VdbeNoopComment((v, "End coroutine for right SELECT"));
-
- /* Generate a subroutine that outputs the current row of the A
- ** select as the next output row of the compound select.
- */
- VdbeNoopComment((v, "Output routine for A"));
- addrOutA = generateOutputSubroutine(pParse,
- p, &destA, pDest, regOutA,
- regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd);
-
- /* Generate a subroutine that outputs the current row of the B
- ** select as the next output row of the compound select.
- */
- if( op==TK_ALL || op==TK_UNION ){
- VdbeNoopComment((v, "Output routine for B"));
- addrOutB = generateOutputSubroutine(pParse,
- p, &destB, pDest, regOutB,
- regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd);
- }
-
- /* Generate a subroutine to run when the results from select A
- ** are exhausted and only data in select B remains.
- */
- VdbeNoopComment((v, "eof-A subroutine"));
- if( op==TK_EXCEPT || op==TK_INTERSECT ){
- addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd);
- }else{
- addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
- p->nSelectRow += pPrior->nSelectRow;
- }
-
- /* Generate a subroutine to run when the results from select B
- ** are exhausted and only data in select A remains.
- */
- if( op==TK_INTERSECT ){
- addrEofB = addrEofA;
- if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
- }else{
- VdbeNoopComment((v, "eof-B subroutine"));
- addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);
- }
-
- /* Generate code to handle the case of A<B
- */
- VdbeNoopComment((v, "A-lt-B subroutine"));
- addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
-
- /* Generate code to handle the case of A==B
- */
- if( op==TK_ALL ){
- addrAeqB = addrAltB;
- }else if( op==TK_INTERSECT ){
- addrAeqB = addrAltB;
- addrAltB++;
- }else{
- VdbeNoopComment((v, "A-eq-B subroutine"));
- addrAeqB =
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
- }
-
- /* Generate code to handle the case of A>B
- */
- VdbeNoopComment((v, "A-gt-B subroutine"));
- addrAgtB = sqlite3VdbeCurrentAddr(v);
- if( op==TK_ALL || op==TK_UNION ){
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
- }
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
- sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
-
- /* This code runs once to initialize everything.
- */
- sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofA);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofB);
- sqlite3VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA);
- sqlite3VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB);
- sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
- sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
-
- /* Implement the main merge loop
- */
- sqlite3VdbeResolveLabel(v, labelCmpr);
- sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
- sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
- (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
- sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
- sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
-
- /* Release temporary registers
- */
- if( regPrev ){
- sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1);
- }
-
- /* Jump to the this point in order to terminate the query.
- */
- sqlite3VdbeResolveLabel(v, labelEnd);
-
- /* Set the number of output columns
- */
- if( pDest->eDest==SRT_Output ){
- Select *pFirst = pPrior;
- while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, 0, pFirst->pEList);
- }
-
- /* Reassembly the compound query so that it will be freed correctly
- ** by the calling function */
- if( p->pPrior ){
- sqlite3SelectDelete(db, p->pPrior);
- }
- p->pPrior = pPrior;
-
- /*** TBD: Insert subroutine calls to close cursors on incomplete
- **** subqueries ****/
- explainComposite(pParse, p->op, iSub1, iSub2, 0);
- return SQLITE_OK;
-}
-#endif
-
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
-/* Forward Declarations */
-static void substExprList(sqlite3*, ExprList*, int, ExprList*);
-static void substSelect(sqlite3*, Select *, int, ExprList *);
-
-/*
-** Scan through the expression pExpr. Replace every reference to
-** a column in table number iTable with a copy of the iColumn-th
-** entry in pEList. (But leave references to the ROWID column
-** unchanged.)
-**
-** This routine is part of the flattening procedure. A subquery
-** whose result set is defined by pEList appears as entry in the
-** FROM clause of a SELECT such that the VDBE cursor assigned to that
-** FORM clause entry is iTable. This routine make the necessary
-** changes to pExpr so that it refers directly to the source table
-** of the subquery rather the result set of the subquery.
-*/
-static Expr *substExpr(
- sqlite3 *db, /* Report malloc errors to this connection */
- Expr *pExpr, /* Expr in which substitution occurs */
- int iTable, /* Table to be substituted */
- ExprList *pEList /* Substitute expressions */
-){
- if( pExpr==0 ) return 0;
- if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
- if( pExpr->iColumn<0 ){
- pExpr->op = TK_NULL;
- }else{
- Expr *pNew;
- assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
- assert( pExpr->pLeft==0 && pExpr->pRight==0 );
- pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
- sqlite3ExprDelete(db, pExpr);
- pExpr = pNew;
- }
- }else{
- pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
- pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- substSelect(db, pExpr->x.pSelect, iTable, pEList);
- }else{
- substExprList(db, pExpr->x.pList, iTable, pEList);
- }
- }
- return pExpr;
-}
-static void substExprList(
- sqlite3 *db, /* Report malloc errors here */
- ExprList *pList, /* List to scan and in which to make substitutes */
- int iTable, /* Table to be substituted */
- ExprList *pEList /* Substitute values */
-){
- int i;
- if( pList==0 ) return;
- for(i=0; i<pList->nExpr; i++){
- pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList);
- }
-}
-static void substSelect(
- sqlite3 *db, /* Report malloc errors here */
- Select *p, /* SELECT statement in which to make substitutions */
- int iTable, /* Table to be replaced */
- ExprList *pEList /* Substitute values */
-){
- SrcList *pSrc;
- struct SrcList_item *pItem;
- int i;
- if( !p ) return;
- substExprList(db, p->pEList, iTable, pEList);
- substExprList(db, p->pGroupBy, iTable, pEList);
- substExprList(db, p->pOrderBy, iTable, pEList);
- p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
- p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
- substSelect(db, p->pPrior, iTable, pEList);
- pSrc = p->pSrc;
- assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
- if( ALWAYS(pSrc) ){
- for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- substSelect(db, pItem->pSelect, iTable, pEList);
- }
- }
-}
-#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
-
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
-/*
-** This routine attempts to flatten subqueries as a performance optimization.
-** This routine returns 1 if it makes changes and 0 if no flattening occurs.
-**
-** To understand the concept of flattening, consider the following
-** query:
-**
-** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
-**
-** The default way of implementing this query is to execute the
-** subquery first and store the results in a temporary table, then
-** run the outer query on that temporary table. This requires two
-** passes over the data. Furthermore, because the temporary table
-** has no indices, the WHERE clause on the outer query cannot be
-** optimized.
-**
-** This routine attempts to rewrite queries such as the above into
-** a single flat select, like this:
-**
-** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
-**
-** The code generated for this simpification gives the same result
-** but only has to scan the data once. And because indices might
-** exist on the table t1, a complete scan of the data might be
-** avoided.
-**
-** Flattening is only attempted if all of the following are true:
-**
-** (1) The subquery and the outer query do not both use aggregates.
-**
-** (2) The subquery is not an aggregate or the outer query is not a join.
-**
-** (3) The subquery is not the right operand of a left outer join
-** (Originally ticket #306. Strengthened by ticket #3300)
-**
-** (4) The subquery is not DISTINCT.
-**
-** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT
-** sub-queries that were excluded from this optimization. Restriction
-** (4) has since been expanded to exclude all DISTINCT subqueries.
-**
-** (6) The subquery does not use aggregates or the outer query is not
-** DISTINCT.
-**
-** (7) The subquery has a FROM clause. TODO: For subqueries without
-** A FROM clause, consider adding a FROM close with the special
-** table sqlite_once that consists of a single row containing a
-** single NULL.
-**
-** (8) The subquery does not use LIMIT or the outer query is not a join.
-**
-** (9) The subquery does not use LIMIT or the outer query does not use
-** aggregates.
-**
-** (10) The subquery does not use aggregates or the outer query does not
-** use LIMIT.
-**
-** (11) The subquery and the outer query do not both have ORDER BY clauses.
-**
-** (**) Not implemented. Subsumed into restriction (3). Was previously
-** a separate restriction deriving from ticket #350.
-**
-** (13) The subquery and outer query do not both use LIMIT.
-**
-** (14) The subquery does not use OFFSET.
-**
-** (15) The outer query is not part of a compound select or the
-** subquery does not have a LIMIT clause.
-** (See ticket #2339 and ticket [02a8e81d44]).
-**
-** (16) The outer query is not an aggregate or the subquery does
-** not contain ORDER BY. (Ticket #2942) This used to not matter
-** until we introduced the group_concat() function.
-**
-** (17) The sub-query is not a compound select, or it is a UNION ALL
-** compound clause made up entirely of non-aggregate queries, and
-** the parent query:
-**
-** * is not itself part of a compound select,
-** * is not an aggregate or DISTINCT query, and
-** * is not a join
-**
-** The parent and sub-query may contain WHERE clauses. Subject to
-** rules (11), (13) and (14), they may also contain ORDER BY,
-** LIMIT and OFFSET clauses. The subquery cannot use any compound
-** operator other than UNION ALL because all the other compound
-** operators have an implied DISTINCT which is disallowed by
-** restriction (4).
-**
-** Also, each component of the sub-query must return the same number
-** of result columns. This is actually a requirement for any compound
-** SELECT statement, but all the code here does is make sure that no
-** such (illegal) sub-query is flattened. The caller will detect the
-** syntax error and return a detailed message.
-**
-** (18) If the sub-query is a compound select, then all terms of the
-** ORDER by clause of the parent must be simple references to
-** columns of the sub-query.
-**
-** (19) The subquery does not use LIMIT or the outer query does not
-** have a WHERE clause.
-**
-** (20) If the sub-query is a compound select, then it must not use
-** an ORDER BY clause. Ticket #3773. We could relax this constraint
-** somewhat by saying that the terms of the ORDER BY clause must
-** appear as unmodified result columns in the outer query. But we
-** have other optimizations in mind to deal with that case.
-**
-** (21) The subquery does not use LIMIT or the outer query is not
-** DISTINCT. (See ticket [752e1646fc]).
-**
-** In this routine, the "p" parameter is a pointer to the outer query.
-** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
-** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
-**
-** If flattening is not attempted, this routine is a no-op and returns 0.
-** If flattening is attempted this routine returns 1.
-**
-** All of the expression analysis must occur on both the outer query and
-** the subquery before this routine runs.
-*/
-static int flattenSubquery(
- Parse *pParse, /* Parsing context */
- Select *p, /* The parent or outer SELECT statement */
- int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
- int isAgg, /* True if outer SELECT uses aggregate functions */
- int subqueryIsAgg /* True if the subquery uses aggregate functions */
-){
- const char *zSavedAuthContext = pParse->zAuthContext;
- Select *pParent;
- Select *pSub; /* The inner query or "subquery" */
- Select *pSub1; /* Pointer to the rightmost select in sub-query */
- SrcList *pSrc; /* The FROM clause of the outer query */
- SrcList *pSubSrc; /* The FROM clause of the subquery */
- ExprList *pList; /* The result set of the outer query */
- int iParent; /* VDBE cursor number of the pSub result set temp table */
- int i; /* Loop counter */
- Expr *pWhere; /* The WHERE clause */
- struct SrcList_item *pSubitem; /* The subquery */
- sqlite3 *db = pParse->db;
-
- /* Check to see if flattening is permitted. Return 0 if not.
- */
- assert( p!=0 );
- assert( p->pPrior==0 ); /* Unable to flatten compound queries */
- if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
- pSrc = p->pSrc;
- assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
- pSubitem = &pSrc->a[iFrom];
- iParent = pSubitem->iCursor;
- pSub = pSubitem->pSelect;
- assert( pSub!=0 );
- if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */
- if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */
- pSubSrc = pSub->pSrc;
- assert( pSubSrc );
- /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
- ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET
- ** because they could be computed at compile-time. But when LIMIT and OFFSET
- ** became arbitrary expressions, we were forced to add restrictions (13)
- ** and (14). */
- if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */
- if( pSub->pOffset ) return 0; /* Restriction (14) */
- if( p->pRightmost && pSub->pLimit ){
- return 0; /* Restriction (15) */
- }
- if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */
- if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */
- if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){
- return 0; /* Restrictions (8)(9) */
- }
- if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){
- return 0; /* Restriction (6) */
- }
- if( p->pOrderBy && pSub->pOrderBy ){
- return 0; /* Restriction (11) */
- }
- if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */
- if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */
- if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
- return 0; /* Restriction (21) */
- }
-
- /* OBSOLETE COMMENT 1:
- ** Restriction 3: If the subquery is a join, make sure the subquery is
- ** not used as the right operand of an outer join. Examples of why this
- ** is not allowed:
- **
- ** t1 LEFT OUTER JOIN (t2 JOIN t3)
- **
- ** If we flatten the above, we would get
- **
- ** (t1 LEFT OUTER JOIN t2) JOIN t3
- **
- ** which is not at all the same thing.
- **
- ** OBSOLETE COMMENT 2:
- ** Restriction 12: If the subquery is the right operand of a left outer
- ** join, make sure the subquery has no WHERE clause.
- ** An examples of why this is not allowed:
- **
- ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
- **
- ** If we flatten the above, we would get
- **
- ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
- **
- ** But the t2.x>0 test will always fail on a NULL row of t2, which
- ** effectively converts the OUTER JOIN into an INNER JOIN.
- **
- ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE:
- ** Ticket #3300 shows that flattening the right term of a LEFT JOIN
- ** is fraught with danger. Best to avoid the whole thing. If the
- ** subquery is the right term of a LEFT JOIN, then do not flatten.
- */
- if( (pSubitem->jointype & JT_OUTER)!=0 ){
- return 0;
- }
-
- /* Restriction 17: If the sub-query is a compound SELECT, then it must
- ** use only the UNION ALL operator. And none of the simple select queries
- ** that make up the compound SELECT are allowed to be aggregate or distinct
- ** queries.
- */
- if( pSub->pPrior ){
- if( pSub->pOrderBy ){
- return 0; /* Restriction 20 */
- }
- if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
- return 0;
- }
- for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
- testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
- testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
- assert( pSub->pSrc!=0 );
- if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
- || (pSub1->pPrior && pSub1->op!=TK_ALL)
- || pSub1->pSrc->nSrc<1
- || pSub->pEList->nExpr!=pSub1->pEList->nExpr
- ){
- return 0;
- }
- testcase( pSub1->pSrc->nSrc>1 );
- }
-
- /* Restriction 18. */
- if( p->pOrderBy ){
- int ii;
- for(ii=0; ii<p->pOrderBy->nExpr; ii++){
- if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0;
- }
- }
- }
-
- /***** If we reach this point, flattening is permitted. *****/
-
- /* Authorize the subquery */
- pParse->zAuthContext = pSubitem->zName;
- TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
- testcase( i==SQLITE_DENY );
- pParse->zAuthContext = zSavedAuthContext;
-
- /* If the sub-query is a compound SELECT statement, then (by restrictions
- ** 17 and 18 above) it must be a UNION ALL and the parent query must
- ** be of the form:
- **
- ** SELECT <expr-list> FROM (<sub-query>) <where-clause>
- **
- ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block
- ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or
- ** OFFSET clauses and joins them to the left-hand-side of the original
- ** using UNION ALL operators. In this case N is the number of simple
- ** select statements in the compound sub-query.
- **
- ** Example:
- **
- ** SELECT a+1 FROM (
- ** SELECT x FROM tab
- ** UNION ALL
- ** SELECT y FROM tab
- ** UNION ALL
- ** SELECT abs(z*2) FROM tab2
- ** ) WHERE a!=5 ORDER BY 1
- **
- ** Transformed into:
- **
- ** SELECT x+1 FROM tab WHERE x+1!=5
- ** UNION ALL
- ** SELECT y+1 FROM tab WHERE y+1!=5
- ** UNION ALL
- ** SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5
- ** ORDER BY 1
- **
- ** We call this the "compound-subquery flattening".
- */
- for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
- Select *pNew;
- ExprList *pOrderBy = p->pOrderBy;
- Expr *pLimit = p->pLimit;
- Select *pPrior = p->pPrior;
- p->pOrderBy = 0;
- p->pSrc = 0;
- p->pPrior = 0;
- p->pLimit = 0;
- pNew = sqlite3SelectDup(db, p, 0);
- p->pLimit = pLimit;
- p->pOrderBy = pOrderBy;
- p->pSrc = pSrc;
- p->op = TK_ALL;
- p->pRightmost = 0;
- if( pNew==0 ){
- pNew = pPrior;
- }else{
- pNew->pPrior = pPrior;
- pNew->pRightmost = 0;
- }
- p->pPrior = pNew;
- if( db->mallocFailed ) return 1;
- }
-
- /* Begin flattening the iFrom-th entry of the FROM clause
- ** in the outer query.
- */
- pSub = pSub1 = pSubitem->pSelect;
-
- /* Delete the transient table structure associated with the
- ** subquery
- */
- sqlite3DbFree(db, pSubitem->zDatabase);
- sqlite3DbFree(db, pSubitem->zName);
- sqlite3DbFree(db, pSubitem->zAlias);
- pSubitem->zDatabase = 0;
- pSubitem->zName = 0;
- pSubitem->zAlias = 0;
- pSubitem->pSelect = 0;
-
- /* Defer deleting the Table object associated with the
- ** subquery until code generation is
- ** complete, since there may still exist Expr.pTab entries that
- ** refer to the subquery even after flattening. Ticket #3346.
- **
- ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
- */
- if( ALWAYS(pSubitem->pTab!=0) ){
- Table *pTabToDel = pSubitem->pTab;
- if( pTabToDel->nRef==1 ){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- pTabToDel->pNextZombie = pToplevel->pZombieTab;
- pToplevel->pZombieTab = pTabToDel;
- }else{
- pTabToDel->nRef--;
- }
- pSubitem->pTab = 0;
- }
-
- /* The following loop runs once for each term in a compound-subquery
- ** flattening (as described above). If we are doing a different kind
- ** of flattening - a flattening other than a compound-subquery flattening -
- ** then this loop only runs once.
- **
- ** This loop moves all of the FROM elements of the subquery into the
- ** the FROM clause of the outer query. Before doing this, remember
- ** the cursor number for the original outer query FROM element in
- ** iParent. The iParent cursor will never be used. Subsequent code
- ** will scan expressions looking for iParent references and replace
- ** those references with expressions that resolve to the subquery FROM
- ** elements we are now copying in.
- */
- for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
- int nSubSrc;
- u8 jointype = 0;
- pSubSrc = pSub->pSrc; /* FROM clause of subquery */
- nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */
- pSrc = pParent->pSrc; /* FROM clause of the outer query */
-
- if( pSrc ){
- assert( pParent==p ); /* First time through the loop */
- jointype = pSubitem->jointype;
- }else{
- assert( pParent!=p ); /* 2nd and subsequent times through the loop */
- pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
- if( pSrc==0 ){
- assert( db->mallocFailed );
- break;
- }
- }
-
- /* The subquery uses a single slot of the FROM clause of the outer
- ** query. If the subquery has more than one element in its FROM clause,
- ** then expand the outer query to make space for it to hold all elements
- ** of the subquery.
- **
- ** Example:
- **
- ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
- **
- ** The outer query has 3 slots in its FROM clause. One slot of the
- ** outer query (the middle slot) is used by the subquery. The next
- ** block of code will expand the out query to 4 slots. The middle
- ** slot is expanded to two slots in order to make space for the
- ** two elements in the FROM clause of the subquery.
- */
- if( nSubSrc>1 ){
- pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
- if( db->mallocFailed ){
- break;
- }
- }
-
- /* Transfer the FROM clause terms from the subquery into the
- ** outer query.
- */
- for(i=0; i<nSubSrc; i++){
- sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
- pSrc->a[i+iFrom] = pSubSrc->a[i];
- memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
- }
- pSrc->a[iFrom].jointype = jointype;
-
- /* Now begin substituting subquery result set expressions for
- ** references to the iParent in the outer query.
- **
- ** Example:
- **
- ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
- ** \ \_____________ subquery __________/ /
- ** \_____________________ outer query ______________________________/
- **
- ** We look at every expression in the outer query and every place we see
- ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
- */
- pList = pParent->pEList;
- for(i=0; i<pList->nExpr; i++){
- if( pList->a[i].zName==0 ){
- char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
- sqlite3Dequote(zName);
- pList->a[i].zName = zName;
- }
- }
- substExprList(db, pParent->pEList, iParent, pSub->pEList);
- if( isAgg ){
- substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
- pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
- }
- if( pSub->pOrderBy ){
- assert( pParent->pOrderBy==0 );
- pParent->pOrderBy = pSub->pOrderBy;
- pSub->pOrderBy = 0;
- }else if( pParent->pOrderBy ){
- substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
- }
- if( pSub->pWhere ){
- pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
- }else{
- pWhere = 0;
- }
- if( subqueryIsAgg ){
- assert( pParent->pHaving==0 );
- pParent->pHaving = pParent->pWhere;
- pParent->pWhere = pWhere;
- pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
- pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
- sqlite3ExprDup(db, pSub->pHaving, 0));
- assert( pParent->pGroupBy==0 );
- pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
- }else{
- pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
- pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
- }
-
- /* The flattened query is distinct if either the inner or the
- ** outer query is distinct.
- */
- pParent->selFlags |= pSub->selFlags & SF_Distinct;
-
- /*
- ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
- **
- ** One is tempted to try to add a and b to combine the limits. But this
- ** does not work if either limit is negative.
- */
- if( pSub->pLimit ){
- pParent->pLimit = pSub->pLimit;
- pSub->pLimit = 0;
- }
- }
-
- /* Finially, delete what is left of the subquery and return
- ** success.
- */
- sqlite3SelectDelete(db, pSub1);
-
- return 1;
-}
-#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
-
-/*
-** Analyze the SELECT statement passed as an argument to see if it
-** is a min() or max() query. Return WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX if
-** it is, or 0 otherwise. At present, a query is considered to be
-** a min()/max() query if:
-**
-** 1. There is a single object in the FROM clause.
-**
-** 2. There is a single expression in the result set, and it is
-** either min(x) or max(x), where x is a column reference.
-*/
-static u8 minMaxQuery(Select *p){
- Expr *pExpr;
- ExprList *pEList = p->pEList;
-
- if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
- pExpr = pEList->a[0].pExpr;
- if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
- if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0;
- pEList = pExpr->x.pList;
- if( pEList==0 || pEList->nExpr!=1 ) return 0;
- if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
- if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){
- return WHERE_ORDERBY_MIN;
- }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){
- return WHERE_ORDERBY_MAX;
- }
- return WHERE_ORDERBY_NORMAL;
-}
-
-/*
-** The select statement passed as the first argument is an aggregate query.
-** The second argment is the associated aggregate-info object. This
-** function tests if the SELECT is of the form:
-**
-** SELECT count(*) FROM <tbl>
-**
-** where table is a database table, not a sub-select or view. If the query
-** does match this pattern, then a pointer to the Table object representing
-** <tbl> is returned. Otherwise, 0 is returned.
-*/
-static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
- Table *pTab;
- Expr *pExpr;
-
- assert( !p->pGroupBy );
-
- if( p->pWhere || p->pEList->nExpr!=1
- || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect
- ){
- return 0;
- }
- pTab = p->pSrc->a[0].pTab;
- pExpr = p->pEList->a[0].pExpr;
- assert( pTab && !pTab->pSelect && pExpr );
-
- if( IsVirtual(pTab) ) return 0;
- if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
- if( NEVER(pAggInfo->nFunc==0) ) return 0;
- if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0;
- if( pExpr->flags&EP_Distinct ) return 0;
-
- return pTab;
-}
-
-/*
-** If the source-list item passed as an argument was augmented with an
-** INDEXED BY clause, then try to locate the specified index. If there
-** was such a clause and the named index cannot be found, return
-** SQLITE_ERROR and leave an error in pParse. Otherwise, populate
-** pFrom->pIndex and return SQLITE_OK.
-*/
-SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){
- if( pFrom->pTab && pFrom->zIndex ){
- Table *pTab = pFrom->pTab;
- char *zIndex = pFrom->zIndex;
- Index *pIdx;
- for(pIdx=pTab->pIndex;
- pIdx && sqlite3StrICmp(pIdx->zName, zIndex);
- pIdx=pIdx->pNext
- );
- if( !pIdx ){
- sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0);
- pParse->checkSchema = 1;
- return SQLITE_ERROR;
- }
- pFrom->pIndex = pIdx;
- }
- return SQLITE_OK;
-}
-
-/*
-** This routine is a Walker callback for "expanding" a SELECT statement.
-** "Expanding" means to do the following:
-**
-** (1) Make sure VDBE cursor numbers have been assigned to every
-** element of the FROM clause.
-**
-** (2) Fill in the pTabList->a[].pTab fields in the SrcList that
-** defines FROM clause. When views appear in the FROM clause,
-** fill pTabList->a[].pSelect with a copy of the SELECT statement
-** that implements the view. A copy is made of the view's SELECT
-** statement so that we can freely modify or delete that statement
-** without worrying about messing up the presistent representation
-** of the view.
-**
-** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword
-** on joins and the ON and USING clause of joins.
-**
-** (4) Scan the list of columns in the result set (pEList) looking
-** for instances of the "*" operator or the TABLE.* operator.
-** If found, expand each "*" to be every column in every table
-** and TABLE.* to be every column in TABLE.
-**
-*/
-static int selectExpander(Walker *pWalker, Select *p){
- Parse *pParse = pWalker->pParse;
- int i, j, k;
- SrcList *pTabList;
- ExprList *pEList;
- struct SrcList_item *pFrom;
- sqlite3 *db = pParse->db;
-
- if( db->mallocFailed ){
- return WRC_Abort;
- }
- if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
- return WRC_Prune;
- }
- p->selFlags |= SF_Expanded;
- pTabList = p->pSrc;
- pEList = p->pEList;
-
- /* Make sure cursor numbers have been assigned to all entries in
- ** the FROM clause of the SELECT statement.
- */
- sqlite3SrcListAssignCursors(pParse, pTabList);
-
- /* Look up every table named in the FROM clause of the select. If
- ** an entry of the FROM clause is a subquery instead of a table or view,
- ** then create a transient table structure to describe the subquery.
- */
- for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
- Table *pTab;
- if( pFrom->pTab!=0 ){
- /* This statement has already been prepared. There is no need
- ** to go further. */
- assert( i==0 );
- return WRC_Prune;
- }
- if( pFrom->zName==0 ){
-#ifndef SQLITE_OMIT_SUBQUERY
- Select *pSel = pFrom->pSelect;
- /* A sub-query in the FROM clause of a SELECT */
- assert( pSel!=0 );
- assert( pFrom->pTab==0 );
- sqlite3WalkSelect(pWalker, pSel);
- pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
- if( pTab==0 ) return WRC_Abort;
- pTab->nRef = 1;
- pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab);
- while( pSel->pPrior ){ pSel = pSel->pPrior; }
- selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
- pTab->iPKey = -1;
- pTab->nRowEst = 1000000;
- pTab->tabFlags |= TF_Ephemeral;
-#endif
- }else{
- /* An ordinary table or view name in the FROM clause */
- assert( pFrom->pTab==0 );
- pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
- if( pTab==0 ) return WRC_Abort;
- pTab->nRef++;
-#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
- if( pTab->pSelect || IsVirtual(pTab) ){
- /* We reach here if the named table is a really a view */
- if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
- assert( pFrom->pSelect==0 );
- pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
- sqlite3WalkSelect(pWalker, pFrom->pSelect);
- }
-#endif
- }
-
- /* Locate the index named by the INDEXED BY clause, if any. */
- if( sqlite3IndexedByLookup(pParse, pFrom) ){
- return WRC_Abort;
- }
- }
-
- /* Process NATURAL keywords, and ON and USING clauses of joins.
- */
- if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){
- return WRC_Abort;
- }
-
- /* For every "*" that occurs in the column list, insert the names of
- ** all columns in all tables. And for every TABLE.* insert the names
- ** of all columns in TABLE. The parser inserted a special expression
- ** with the TK_ALL operator for each "*" that it found in the column list.
- ** The following code just has to locate the TK_ALL expressions and expand
- ** each one to the list of all columns in all tables.
- **
- ** The first loop just checks to see if there are any "*" operators
- ** that need expanding.
- */
- for(k=0; k<pEList->nExpr; k++){
- Expr *pE = pEList->a[k].pExpr;
- if( pE->op==TK_ALL ) break;
- assert( pE->op!=TK_DOT || pE->pRight!=0 );
- assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
- if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
- }
- if( k<pEList->nExpr ){
- /*
- ** If we get here it means the result set contains one or more "*"
- ** operators that need to be expanded. Loop through each expression
- ** in the result set and expand them one by one.
- */
- struct ExprList_item *a = pEList->a;
- ExprList *pNew = 0;
- int flags = pParse->db->flags;
- int longNames = (flags & SQLITE_FullColNames)!=0
- && (flags & SQLITE_ShortColNames)==0;
-
- for(k=0; k<pEList->nExpr; k++){
- Expr *pE = a[k].pExpr;
- assert( pE->op!=TK_DOT || pE->pRight!=0 );
- if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){
- /* This particular expression does not need to be expanded.
- */
- pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
- if( pNew ){
- pNew->a[pNew->nExpr-1].zName = a[k].zName;
- pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan;
- a[k].zName = 0;
- a[k].zSpan = 0;
- }
- a[k].pExpr = 0;
- }else{
- /* This expression is a "*" or a "TABLE.*" and needs to be
- ** expanded. */
- int tableSeen = 0; /* Set to 1 when TABLE matches */
- char *zTName; /* text of name of TABLE */
- if( pE->op==TK_DOT ){
- assert( pE->pLeft!=0 );
- assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
- zTName = pE->pLeft->u.zToken;
- }else{
- zTName = 0;
- }
- for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
- Table *pTab = pFrom->pTab;
- char *zTabName = pFrom->zAlias;
- if( zTabName==0 ){
- zTabName = pTab->zName;
- }
- if( db->mallocFailed ) break;
- if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
- continue;
- }
- tableSeen = 1;
- for(j=0; j<pTab->nCol; j++){
- Expr *pExpr, *pRight;
- char *zName = pTab->aCol[j].zName;
- char *zColname; /* The computed column name */
- char *zToFree; /* Malloced string that needs to be freed */
- Token sColname; /* Computed column name as a token */
-
- /* If a column is marked as 'hidden' (currently only possible
- ** for virtual tables), do not include it in the expanded
- ** result-set list.
- */
- if( IsHiddenColumn(&pTab->aCol[j]) ){
- assert(IsVirtual(pTab));
- continue;
- }
-
- if( i>0 && zTName==0 ){
- if( (pFrom->jointype & JT_NATURAL)!=0
- && tableAndColumnIndex(pTabList, i, zName, 0, 0)
- ){
- /* In a NATURAL join, omit the join columns from the
- ** table to the right of the join */
- continue;
- }
- if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){
- /* In a join with a USING clause, omit columns in the
- ** using clause from the table on the right. */
- continue;
- }
- }
- pRight = sqlite3Expr(db, TK_ID, zName);
- zColname = zName;
- zToFree = 0;
- if( longNames || pTabList->nSrc>1 ){
- Expr *pLeft;
- pLeft = sqlite3Expr(db, TK_ID, zTabName);
- pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- if( longNames ){
- zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
- zToFree = zColname;
- }
- }else{
- pExpr = pRight;
- }
- pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
- sColname.z = zColname;
- sColname.n = sqlite3Strlen30(zColname);
- sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
- sqlite3DbFree(db, zToFree);
- }
- }
- if( !tableSeen ){
- if( zTName ){
- sqlite3ErrorMsg(pParse, "no such table: %s", zTName);
- }else{
- sqlite3ErrorMsg(pParse, "no tables specified");
- }
- }
- }
- }
- sqlite3ExprListDelete(db, pEList);
- p->pEList = pNew;
- }
-#if SQLITE_MAX_COLUMN
- if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many columns in result set");
- }
-#endif
- return WRC_Continue;
-}
-
-/*
-** No-op routine for the parse-tree walker.
-**
-** When this routine is the Walker.xExprCallback then expression trees
-** are walked without any actions being taken at each node. Presumably,
-** when this routine is used for Walker.xExprCallback then
-** Walker.xSelectCallback is set to do something useful for every
-** subquery in the parser tree.
-*/
-static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
- UNUSED_PARAMETER2(NotUsed, NotUsed2);
- return WRC_Continue;
-}
-
-/*
-** This routine "expands" a SELECT statement and all of its subqueries.
-** For additional information on what it means to "expand" a SELECT
-** statement, see the comment on the selectExpand worker callback above.
-**
-** Expanding a SELECT statement is the first step in processing a
-** SELECT statement. The SELECT statement must be expanded before
-** name resolution is performed.
-**
-** If anything goes wrong, an error message is written into pParse.
-** The calling function can detect the problem by looking at pParse->nErr
-** and/or pParse->db->mallocFailed.
-*/
-static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
- Walker w;
- w.xSelectCallback = selectExpander;
- w.xExprCallback = exprWalkNoop;
- w.pParse = pParse;
- sqlite3WalkSelect(&w, pSelect);
-}
-
-
-#ifndef SQLITE_OMIT_SUBQUERY
-/*
-** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo()
-** interface.
-**
-** For each FROM-clause subquery, add Column.zType and Column.zColl
-** information to the Table structure that represents the result set
-** of that subquery.
-**
-** The Table structure that represents the result set was constructed
-** by selectExpander() but the type and collation information was omitted
-** at that point because identifiers had not yet been resolved. This
-** routine is called after identifier resolution.
-*/
-static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
- Parse *pParse;
- int i;
- SrcList *pTabList;
- struct SrcList_item *pFrom;
-
- assert( p->selFlags & SF_Resolved );
- if( (p->selFlags & SF_HasTypeInfo)==0 ){
- p->selFlags |= SF_HasTypeInfo;
- pParse = pWalker->pParse;
- pTabList = p->pSrc;
- for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
- Table *pTab = pFrom->pTab;
- if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){
- /* A sub-query in the FROM clause of a SELECT */
- Select *pSel = pFrom->pSelect;
- assert( pSel );
- while( pSel->pPrior ) pSel = pSel->pPrior;
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
- }
- }
- }
- return WRC_Continue;
-}
-#endif
-
-
-/*
-** This routine adds datatype and collating sequence information to
-** the Table structures of all FROM-clause subqueries in a
-** SELECT statement.
-**
-** Use this routine after name resolution.
-*/
-static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
-#ifndef SQLITE_OMIT_SUBQUERY
- Walker w;
- w.xSelectCallback = selectAddSubqueryTypeInfo;
- w.xExprCallback = exprWalkNoop;
- w.pParse = pParse;
- sqlite3WalkSelect(&w, pSelect);
-#endif
-}
-
-
-/*
-** This routine sets up a SELECT statement for processing. The
-** following is accomplished:
-**
-** * VDBE Cursor numbers are assigned to all FROM-clause terms.
-** * Ephemeral Table objects are created for all FROM-clause subqueries.
-** * ON and USING clauses are shifted into WHERE statements
-** * Wildcards "*" and "TABLE.*" in result sets are expanded.
-** * Identifiers in expression are matched to tables.
-**
-** This routine acts recursively on all subqueries within the SELECT.
-*/
-SQLITE_PRIVATE void sqlite3SelectPrep(
- Parse *pParse, /* The parser context */
- Select *p, /* The SELECT statement being coded. */
- NameContext *pOuterNC /* Name context for container */
-){
- sqlite3 *db;
- if( NEVER(p==0) ) return;
- db = pParse->db;
- if( p->selFlags & SF_HasTypeInfo ) return;
- sqlite3SelectExpand(pParse, p);
- if( pParse->nErr || db->mallocFailed ) return;
- sqlite3ResolveSelectNames(pParse, p, pOuterNC);
- if( pParse->nErr || db->mallocFailed ) return;
- sqlite3SelectAddTypeInfo(pParse, p);
-}
-
-/*
-** Reset the aggregate accumulator.
-**
-** The aggregate accumulator is a set of memory cells that hold
-** intermediate results while calculating an aggregate. This
-** routine generates code that stores NULLs in all of those memory
-** cells.
-*/
-static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
- Vdbe *v = pParse->pVdbe;
- int i;
- struct AggInfo_func *pFunc;
- if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
- return;
- }
- for(i=0; i<pAggInfo->nColumn; i++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem);
- }
- for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem);
- if( pFunc->iDistinct>=0 ){
- Expr *pE = pFunc->pExpr;
- assert( !ExprHasProperty(pE, EP_xIsSelect) );
- if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
- sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
- "argument");
- pFunc->iDistinct = -1;
- }else{
- KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
- sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
- }
- }
- }
-}
-
-/*
-** Invoke the OP_AggFinalize opcode for every aggregate function
-** in the AggInfo structure.
-*/
-static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
- Vdbe *v = pParse->pVdbe;
- int i;
- struct AggInfo_func *pF;
- for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
- ExprList *pList = pF->pExpr->x.pList;
- assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
- sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0,
- (void*)pF->pFunc, P4_FUNCDEF);
- }
-}
-
-/*
-** Update the accumulator memory cells for an aggregate based on
-** the current cursor position.
-*/
-static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
- Vdbe *v = pParse->pVdbe;
- int i;
- int regHit = 0;
- int addrHitTest = 0;
- struct AggInfo_func *pF;
- struct AggInfo_col *pC;
-
- pAggInfo->directMode = 1;
- sqlite3ExprCacheClear(pParse);
- for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
- int nArg;
- int addrNext = 0;
- int regAgg;
- ExprList *pList = pF->pExpr->x.pList;
- assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
- if( pList ){
- nArg = pList->nExpr;
- regAgg = sqlite3GetTempRange(pParse, nArg);
- sqlite3ExprCodeExprList(pParse, pList, regAgg, 1);
- }else{
- nArg = 0;
- regAgg = 0;
- }
- if( pF->iDistinct>=0 ){
- addrNext = sqlite3VdbeMakeLabel(v);
- assert( nArg==1 );
- codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
- }
- if( pF->pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
- CollSeq *pColl = 0;
- struct ExprList_item *pItem;
- int j;
- assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */
- for(j=0, pItem=pList->a; !pColl && j<nArg; j++, pItem++){
- pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
- }
- if( !pColl ){
- pColl = pParse->db->pDfltColl;
- }
- if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
- sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
- }
- sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
- (void*)pF->pFunc, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, (u8)nArg);
- sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
- sqlite3ReleaseTempRange(pParse, regAgg, nArg);
- if( addrNext ){
- sqlite3VdbeResolveLabel(v, addrNext);
- sqlite3ExprCacheClear(pParse);
- }
- }
-
- /* Before populating the accumulator registers, clear the column cache.
- ** Otherwise, if any of the required column values are already present
- ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value
- ** to pC->iMem. But by the time the value is used, the original register
- ** may have been used, invalidating the underlying buffer holding the
- ** text or blob value. See ticket [883034dcb5].
- **
- ** Another solution would be to change the OP_SCopy used to copy cached
- ** values to an OP_Copy.
- */
- if( regHit ){
- addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit);
- }
- sqlite3ExprCacheClear(pParse);
- for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
- sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
- }
- pAggInfo->directMode = 0;
- sqlite3ExprCacheClear(pParse);
- if( addrHitTest ){
- sqlite3VdbeJumpHere(v, addrHitTest);
- }
-}
-
-/*
-** Add a single OP_Explain instruction to the VDBE to explain a simple
-** count(*) query ("SELECT count(*) FROM pTab").
-*/
-#ifndef SQLITE_OMIT_EXPLAIN
-static void explainSimpleCount(
- Parse *pParse, /* Parse context */
- Table *pTab, /* Table being queried */
- Index *pIdx /* Index used to optimize scan, or NULL */
-){
- if( pParse->explain==2 ){
- char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s %s%s(~%d rows)",
- pTab->zName,
- pIdx ? "USING COVERING INDEX " : "",
- pIdx ? pIdx->zName : "",
- pTab->nRowEst
- );
- sqlite3VdbeAddOp4(
- pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
- );
- }
-}
-#else
-# define explainSimpleCount(a,b,c)
-#endif
-
-/*
-** Generate code for the SELECT statement given in the p argument.
-**
-** The results are distributed in various ways depending on the
-** contents of the SelectDest structure pointed to by argument pDest
-** as follows:
-**
-** pDest->eDest Result
-** ------------ -------------------------------------------
-** SRT_Output Generate a row of output (using the OP_ResultRow
-** opcode) for each row in the result set.
-**
-** SRT_Mem Only valid if the result is a single column.
-** Store the first column of the first result row
-** in register pDest->iSDParm then abandon the rest
-** of the query. This destination implies "LIMIT 1".
-**
-** SRT_Set The result must be a single column. Store each
-** row of result as the key in table pDest->iSDParm.
-** Apply the affinity pDest->affSdst before storing
-** results. Used to implement "IN (SELECT ...)".
-**
-** SRT_Union Store results as a key in a temporary table
-** identified by pDest->iSDParm.
-**
-** SRT_Except Remove results from the temporary table pDest->iSDParm.
-**
-** SRT_Table Store results in temporary table pDest->iSDParm.
-** This is like SRT_EphemTab except that the table
-** is assumed to already be open.
-**
-** SRT_EphemTab Create an temporary table pDest->iSDParm and store
-** the result there. The cursor is left open after
-** returning. This is like SRT_Table except that
-** this destination uses OP_OpenEphemeral to create
-** the table first.
-**
-** SRT_Coroutine Generate a co-routine that returns a new row of
-** results each time it is invoked. The entry point
-** of the co-routine is stored in register pDest->iSDParm.
-**
-** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result
-** set is not empty.
-**
-** SRT_Discard Throw the results away. This is used by SELECT
-** statements within triggers whose only purpose is
-** the side-effects of functions.
-**
-** This routine returns the number of errors. If any errors are
-** encountered, then an appropriate error message is left in
-** pParse->zErrMsg.
-**
-** This routine does NOT free the Select structure passed in. The
-** calling function needs to do that.
-*/
-SQLITE_PRIVATE int sqlite3Select(
- Parse *pParse, /* The parser context */
- Select *p, /* The SELECT statement being coded. */
- SelectDest *pDest /* What to do with the query results */
-){
- int i, j; /* Loop counters */
- WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */
- Vdbe *v; /* The virtual machine under construction */
- int isAgg; /* True for select lists like "count(*)" */
- ExprList *pEList; /* List of columns to extract. */
- SrcList *pTabList; /* List of tables to select from */
- Expr *pWhere; /* The WHERE clause. May be NULL */
- ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */
- ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
- Expr *pHaving; /* The HAVING clause. May be NULL */
- int rc = 1; /* Value to return from this function */
- int addrSortIndex; /* Address of an OP_OpenEphemeral instruction */
- DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */
- AggInfo sAggInfo; /* Information used by aggregate queries */
- int iEnd; /* Address of the end of the query */
- sqlite3 *db; /* The database connection */
-
-#ifndef SQLITE_OMIT_EXPLAIN
- int iRestoreSelectId = pParse->iSelectId;
- pParse->iSelectId = pParse->iNextSelectId++;
-#endif
-
- db = pParse->db;
- if( p==0 || db->mallocFailed || pParse->nErr ){
- return 1;
- }
- if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
- memset(&sAggInfo, 0, sizeof(sAggInfo));
-
- if( IgnorableOrderby(pDest) ){
- assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
- pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard);
- /* If ORDER BY makes no difference in the output then neither does
- ** DISTINCT so it can be removed too. */
- sqlite3ExprListDelete(db, p->pOrderBy);
- p->pOrderBy = 0;
- p->selFlags &= ~SF_Distinct;
- }
- sqlite3SelectPrep(pParse, p, 0);
- pOrderBy = p->pOrderBy;
- pTabList = p->pSrc;
- pEList = p->pEList;
- if( pParse->nErr || db->mallocFailed ){
- goto select_end;
- }
- isAgg = (p->selFlags & SF_Aggregate)!=0;
- assert( pEList!=0 );
-
- /* Begin generating code.
- */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto select_end;
-
- /* If writing to memory or generating a set
- ** only a single column may be output.
- */
-#ifndef SQLITE_OMIT_SUBQUERY
- if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
- goto select_end;
- }
-#endif
-
- /* Generate code for all sub-queries in the FROM clause
- */
-#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
- for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
- struct SrcList_item *pItem = &pTabList->a[i];
- SelectDest dest;
- Select *pSub = pItem->pSelect;
- int isAggSub;
-
- if( pSub==0 ) continue;
-
- /* Sometimes the code for a subquery will be generated more than
- ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
- ** for example. In that case, do not regenerate the code to manifest
- ** a view or the co-routine to implement a view. The first instance
- ** is sufficient, though the subroutine to manifest the view does need
- ** to be invoked again. */
- if( pItem->addrFillSub ){
- if( pItem->viaCoroutine==0 ){
- sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
- }
- continue;
- }
-
- /* Increment Parse.nHeight by the height of the largest expression
- ** tree refered to by this, the parent select. The child select
- ** may contain expression trees of at most
- ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
- ** more conservative than necessary, but much easier than enforcing
- ** an exact limit.
- */
- pParse->nHeight += sqlite3SelectExprHeight(p);
-
- isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
- if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
- /* This subquery can be absorbed into its parent. */
- if( isAggSub ){
- isAgg = 1;
- p->selFlags |= SF_Aggregate;
- }
- i = -1;
- }else if( pTabList->nSrc==1 && (p->selFlags & SF_Materialize)==0
- && OptimizationEnabled(db, SQLITE_SubqCoroutine)
- ){
- /* Implement a co-routine that will return a single row of the result
- ** set on each invocation.
- */
- int addrTop;
- int addrEof;
- pItem->regReturn = ++pParse->nMem;
- addrEof = ++pParse->nMem;
- /* Before coding the OP_Goto to jump to the start of the main routine,
- ** ensure that the jump to the verify-schema routine has already
- ** been coded. Otherwise, the verify-schema would likely be coded as
- ** part of the co-routine. If the main routine then accessed the
- ** database before invoking the co-routine for the first time (for
- ** example to initialize a LIMIT register from a sub-select), it would
- ** be doing so without having verified the schema version and obtained
- ** the required db locks. See ticket d6b36be38. */
- sqlite3CodeVerifySchema(pParse, -1);
- sqlite3VdbeAddOp0(v, OP_Goto);
- addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor);
- sqlite3VdbeChangeP5(v, 1);
- VdbeComment((v, "coroutine for %s", pItem->pTab->zName));
- pItem->addrFillSub = addrTop;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, addrEof);
- sqlite3VdbeChangeP5(v, 1);
- sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
- explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
- sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
- pItem->viaCoroutine = 1;
- sqlite3VdbeChangeP2(v, addrTop, dest.iSdst);
- sqlite3VdbeChangeP3(v, addrTop, dest.nSdst);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, addrEof);
- sqlite3VdbeAddOp1(v, OP_Yield, pItem->regReturn);
- VdbeComment((v, "end %s", pItem->pTab->zName));
- sqlite3VdbeJumpHere(v, addrTop-1);
- sqlite3ClearTempRegCache(pParse);
- }else{
- /* Generate a subroutine that will fill an ephemeral table with
- ** the content of this subquery. pItem->addrFillSub will point
- ** to the address of the generated subroutine. pItem->regReturn
- ** is a register allocated to hold the subroutine return address
- */
- int topAddr;
- int onceAddr = 0;
- int retAddr;
- assert( pItem->addrFillSub==0 );
- pItem->regReturn = ++pParse->nMem;
- topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
- pItem->addrFillSub = topAddr+1;
- VdbeNoopComment((v, "materialize %s", pItem->pTab->zName));
- if( pItem->isCorrelated==0 ){
- /* If the subquery is no correlated and if we are not inside of
- ** a trigger, then we only need to compute the value of the subquery
- ** once. */
- onceAddr = sqlite3CodeOnce(pParse);
- }
- sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
- explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
- sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
- if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
- retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
- VdbeComment((v, "end %s", pItem->pTab->zName));
- sqlite3VdbeChangeP1(v, topAddr, retAddr);
- sqlite3ClearTempRegCache(pParse);
- }
- if( /*pParse->nErr ||*/ db->mallocFailed ){
- goto select_end;
- }
- pParse->nHeight -= sqlite3SelectExprHeight(p);
- pTabList = p->pSrc;
- if( !IgnorableOrderby(pDest) ){
- pOrderBy = p->pOrderBy;
- }
- }
- pEList = p->pEList;
-#endif
- pWhere = p->pWhere;
- pGroupBy = p->pGroupBy;
- pHaving = p->pHaving;
- sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;
-
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
- /* If there is are a sequence of queries, do the earlier ones first.
- */
- if( p->pPrior ){
- if( p->pRightmost==0 ){
- Select *pLoop, *pRight = 0;
- int cnt = 0;
- int mxSelect;
- for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){
- pLoop->pRightmost = p;
- pLoop->pNext = pRight;
- pRight = pLoop;
- }
- mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
- if( mxSelect && cnt>mxSelect ){
- sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
- goto select_end;
- }
- }
- rc = multiSelect(pParse, p, pDest);
- explainSetInteger(pParse->iSelectId, iRestoreSelectId);
- return rc;
- }
-#endif
-
- /* If there is both a GROUP BY and an ORDER BY clause and they are
- ** identical, then disable the ORDER BY clause since the GROUP BY
- ** will cause elements to come out in the correct order. This is
- ** an optimization - the correct answer should result regardless.
- ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
- ** to disable this optimization for testing purposes.
- */
- if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
- && OptimizationEnabled(db, SQLITE_GroupByOrder) ){
- pOrderBy = 0;
- }
-
- /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
- ** if the select-list is the same as the ORDER BY list, then this query
- ** can be rewritten as a GROUP BY. In other words, this:
- **
- ** SELECT DISTINCT xyz FROM ... ORDER BY xyz
- **
- ** is transformed to:
- **
- ** SELECT xyz FROM ... GROUP BY xyz
- **
- ** The second form is preferred as a single index (or temp-table) may be
- ** used for both the ORDER BY and DISTINCT processing. As originally
- ** written the query must use a temp-table for at least one of the ORDER
- ** BY and DISTINCT, and an index or separate temp-table for the other.
- */
- if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
- && sqlite3ExprListCompare(pOrderBy, p->pEList)==0
- ){
- p->selFlags &= ~SF_Distinct;
- p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
- pGroupBy = p->pGroupBy;
- pOrderBy = 0;
- /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
- ** the sDistinct.isTnct is still set. Hence, isTnct represents the
- ** original setting of the SF_Distinct flag, not the current setting */
- assert( sDistinct.isTnct );
- }
-
- /* If there is an ORDER BY clause, then this sorting
- ** index might end up being unused if the data can be
- ** extracted in pre-sorted order. If that is the case, then the
- ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
- ** we figure out that the sorting index is not needed. The addrSortIndex
- ** variable is used to facilitate that change.
- */
- if( pOrderBy ){
- KeyInfo *pKeyInfo;
- pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
- pOrderBy->iECursor = pParse->nTab++;
- p->addrOpenEphm[2] = addrSortIndex =
- sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
- pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
- }else{
- addrSortIndex = -1;
- }
-
- /* If the output is destined for a temporary table, open that table.
- */
- if( pDest->eDest==SRT_EphemTab ){
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
- }
-
- /* Set the limiter.
- */
- iEnd = sqlite3VdbeMakeLabel(v);
- p->nSelectRow = (double)LARGEST_INT64;
- computeLimitRegisters(pParse, p, iEnd);
- if( p->iLimit==0 && addrSortIndex>=0 ){
- sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen;
- p->selFlags |= SF_UseSorter;
- }
-
- /* Open a virtual index to use for the distinct set.
- */
- if( p->selFlags & SF_Distinct ){
- sDistinct.tabTnct = pParse->nTab++;
- sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
- sDistinct.tabTnct, 0, 0,
- (char*)keyInfoFromExprList(pParse, p->pEList),
- P4_KEYINFO_HANDOFF);
- sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
- sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
- }else{
- sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
- }
-
- if( !isAgg && pGroupBy==0 ){
- /* No aggregate functions and no GROUP BY clause */
- ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0);
-
- /* Begin the database scan. */
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0);
- if( pWInfo==0 ) goto select_end;
- if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
- if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct;
- if( pOrderBy && pWInfo->nOBSat==pOrderBy->nExpr ) pOrderBy = 0;
-
- /* If sorting index that was created by a prior OP_OpenEphemeral
- ** instruction ended up not being needed, then change the OP_OpenEphemeral
- ** into an OP_Noop.
- */
- if( addrSortIndex>=0 && pOrderBy==0 ){
- sqlite3VdbeChangeToNoop(v, addrSortIndex);
- p->addrOpenEphm[2] = -1;
- }
-
- /* Use the standard inner loop. */
- selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest,
- pWInfo->iContinue, pWInfo->iBreak);
-
- /* End the database scan loop.
- */
- sqlite3WhereEnd(pWInfo);
- }else{
- /* This case when there exist aggregate functions or a GROUP BY clause
- ** or both */
- NameContext sNC; /* Name context for processing aggregate information */
- int iAMem; /* First Mem address for storing current GROUP BY */
- int iBMem; /* First Mem address for previous GROUP BY */
- int iUseFlag; /* Mem address holding flag indicating that at least
- ** one row of the input to the aggregator has been
- ** processed */
- int iAbortFlag; /* Mem address which causes query abort if positive */
- int groupBySort; /* Rows come from source in GROUP BY order */
- int addrEnd; /* End of processing for this SELECT */
- int sortPTab = 0; /* Pseudotable used to decode sorting results */
- int sortOut = 0; /* Output register from the sorter */
-
- /* Remove any and all aliases between the result set and the
- ** GROUP BY clause.
- */
- if( pGroupBy ){
- int k; /* Loop counter */
- struct ExprList_item *pItem; /* For looping over expression in a list */
-
- for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){
- pItem->iAlias = 0;
- }
- for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
- pItem->iAlias = 0;
- }
- if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100;
- }else{
- p->nSelectRow = (double)1;
- }
-
-
- /* Create a label to jump to when we want to abort the query */
- addrEnd = sqlite3VdbeMakeLabel(v);
-
- /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
- ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
- ** SELECT statement.
- */
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- sNC.pSrcList = pTabList;
- sNC.pAggInfo = &sAggInfo;
- sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
- sAggInfo.pGroupBy = pGroupBy;
- sqlite3ExprAnalyzeAggList(&sNC, pEList);
- sqlite3ExprAnalyzeAggList(&sNC, pOrderBy);
- if( pHaving ){
- sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
- }
- sAggInfo.nAccumulator = sAggInfo.nColumn;
- for(i=0; i<sAggInfo.nFunc; i++){
- assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
- sNC.ncFlags |= NC_InAggFunc;
- sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
- sNC.ncFlags &= ~NC_InAggFunc;
- }
- if( db->mallocFailed ) goto select_end;
-
- /* Processing for aggregates with GROUP BY is very different and
- ** much more complex than aggregates without a GROUP BY.
- */
- if( pGroupBy ){
- KeyInfo *pKeyInfo; /* Keying information for the group by clause */
- int j1; /* A-vs-B comparision jump */
- int addrOutputRow; /* Start of subroutine that outputs a result row */
- int regOutputRow; /* Return address register for output subroutine */
- int addrSetAbort; /* Set the abort flag and return */
- int addrTopOfLoop; /* Top of the input loop */
- int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */
- int addrReset; /* Subroutine for resetting the accumulator */
- int regReset; /* Return address register for reset subroutine */
-
- /* If there is a GROUP BY clause we might need a sorting index to
- ** implement it. Allocate that sorting index now. If it turns out
- ** that we do not need it after all, the OP_SorterOpen instruction
- ** will be converted into a Noop.
- */
- sAggInfo.sortingIdx = pParse->nTab++;
- pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
- addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
- sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
- 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
-
- /* Initialize memory locations used by GROUP BY aggregate processing
- */
- iUseFlag = ++pParse->nMem;
- iAbortFlag = ++pParse->nMem;
- regOutputRow = ++pParse->nMem;
- addrOutputRow = sqlite3VdbeMakeLabel(v);
- regReset = ++pParse->nMem;
- addrReset = sqlite3VdbeMakeLabel(v);
- iAMem = pParse->nMem + 1;
- pParse->nMem += pGroupBy->nExpr;
- iBMem = pParse->nMem + 1;
- pParse->nMem += pGroupBy->nExpr;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
- VdbeComment((v, "clear abort flag"));
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
- VdbeComment((v, "indicate accumulator empty"));
- sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
-
- /* Begin a loop that will extract all source rows in GROUP BY order.
- ** This might involve two separate loops with an OP_Sort in between, or
- ** it might be a single loop that uses an index to extract information
- ** in the right order to begin with.
- */
- sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
- if( pWInfo==0 ) goto select_end;
- if( pWInfo->nOBSat==pGroupBy->nExpr ){
- /* The optimizer is able to deliver rows in group by order so
- ** we do not have to sort. The OP_OpenEphemeral table will be
- ** cancelled later because we still need to use the pKeyInfo
- */
- groupBySort = 0;
- }else{
- /* Rows are coming out in undetermined order. We have to push
- ** each row into a sorting index, terminate the first loop,
- ** then loop over the sorting index in order to get the output
- ** in sorted order
- */
- int regBase;
- int regRecord;
- int nCol;
- int nGroupBy;
-
- explainTempTable(pParse,
- (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ?
- "DISTINCT" : "GROUP BY");
-
- groupBySort = 1;
- nGroupBy = pGroupBy->nExpr;
- nCol = nGroupBy + 1;
- j = nGroupBy+1;
- for(i=0; i<sAggInfo.nColumn; i++){
- if( sAggInfo.aCol[i].iSorterColumn>=j ){
- nCol++;
- j++;
- }
- }
- regBase = sqlite3GetTempRange(pParse, nCol);
- sqlite3ExprCacheClear(pParse);
- sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
- sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
- j = nGroupBy+1;
- for(i=0; i<sAggInfo.nColumn; i++){
- struct AggInfo_col *pCol = &sAggInfo.aCol[i];
- if( pCol->iSorterColumn>=j ){
- int r1 = j + regBase;
- int r2;
-
- r2 = sqlite3ExprCodeGetColumn(pParse,
- pCol->pTab, pCol->iColumn, pCol->iTable, r1, 0);
- if( r1!=r2 ){
- sqlite3VdbeAddOp2(v, OP_SCopy, r2, r1);
- }
- j++;
- }
- }
- regRecord = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
- sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord);
- sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3ReleaseTempRange(pParse, regBase, nCol);
- sqlite3WhereEnd(pWInfo);
- sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++;
- sortOut = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
- sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
- VdbeComment((v, "GROUP BY sort"));
- sAggInfo.useSortingIdx = 1;
- sqlite3ExprCacheClear(pParse);
- }
-
- /* Evaluate the current GROUP BY terms and store in b0, b1, b2...
- ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth)
- ** Then compare the current GROUP BY terms against the GROUP BY terms
- ** from the previous row currently stored in a0, a1, a2...
- */
- addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
- sqlite3ExprCacheClear(pParse);
- if( groupBySort ){
- sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
- }
- for(j=0; j<pGroupBy->nExpr; j++){
- if( groupBySort ){
- sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
- if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
- }else{
- sAggInfo.directMode = 1;
- sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
- }
- }
- sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
- (char*)pKeyInfo, P4_KEYINFO);
- j1 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1);
-
- /* Generate code that runs whenever the GROUP BY changes.
- ** Changes in the GROUP BY are detected by the previous code
- ** block. If there were no changes, this block is skipped.
- **
- ** This code copies current group by terms in b0,b1,b2,...
- ** over to a0,a1,a2. It then calls the output subroutine
- ** and resets the aggregate accumulator registers in preparation
- ** for the next GROUP BY batch.
- */
- sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
- VdbeComment((v, "output one row"));
- sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd);
- VdbeComment((v, "check abort flag"));
- sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
- VdbeComment((v, "reset accumulator"));
-
- /* Update the aggregate accumulators based on the content of
- ** the current row
- */
- sqlite3VdbeJumpHere(v, j1);
- updateAccumulator(pParse, &sAggInfo);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
- VdbeComment((v, "indicate data in accumulator"));
-
- /* End of the loop
- */
- if( groupBySort ){
- sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop);
- }else{
- sqlite3WhereEnd(pWInfo);
- sqlite3VdbeChangeToNoop(v, addrSortingIdx);
- }
-
- /* Output the final row of result
- */
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
- VdbeComment((v, "output final row"));
-
- /* Jump over the subroutines
- */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEnd);
-
- /* Generate a subroutine that outputs a single row of the result
- ** set. This subroutine first looks at the iUseFlag. If iUseFlag
- ** is less than or equal to zero, the subroutine is a no-op. If
- ** the processing calls for the query to abort, this subroutine
- ** increments the iAbortFlag memory location before returning in
- ** order to signal the caller to abort.
- */
- addrSetAbort = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
- VdbeComment((v, "set abort flag"));
- sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
- sqlite3VdbeResolveLabel(v, addrOutputRow);
- addrOutputRow = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
- VdbeComment((v, "Groupby result generator entry point"));
- sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
- finalizeAggFunctions(pParse, &sAggInfo);
- sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
- &sDistinct, pDest,
- addrOutputRow+1, addrSetAbort);
- sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
- VdbeComment((v, "end groupby result generator"));
-
- /* Generate a subroutine that will reset the group-by accumulator
- */
- sqlite3VdbeResolveLabel(v, addrReset);
- resetAccumulator(pParse, &sAggInfo);
- sqlite3VdbeAddOp1(v, OP_Return, regReset);
-
- } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
- else {
- ExprList *pDel = 0;
-#ifndef SQLITE_OMIT_BTREECOUNT
- Table *pTab;
- if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
- /* If isSimpleCount() returns a pointer to a Table structure, then
- ** the SQL statement is of the form:
- **
- ** SELECT count(*) FROM <tbl>
- **
- ** where the Table structure returned represents table <tbl>.
- **
- ** This statement is so common that it is optimized specially. The
- ** OP_Count instruction is executed either on the intkey table that
- ** contains the data for table <tbl> or on one of its indexes. It
- ** is better to execute the op on an index, as indexes are almost
- ** always spread across less pages than their corresponding tables.
- */
- const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */
- Index *pIdx; /* Iterator variable */
- KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */
- Index *pBest = 0; /* Best index found so far */
- int iRoot = pTab->tnum; /* Root page of scanned b-tree */
-
- sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
-
- /* Search for the index that has the least amount of columns. If
- ** there is such an index, and it has less columns than the table
- ** does, then we can assume that it consumes less space on disk and
- ** will therefore be cheaper to scan to determine the query result.
- ** In this case set iRoot to the root page number of the index b-tree
- ** and pKeyInfo to the KeyInfo structure required to navigate the
- ** index.
- **
- ** (2011-04-15) Do not do a full scan of an unordered index.
- **
- ** In practice the KeyInfo structure will not be used. It is only
- ** passed to keep OP_OpenRead happy.
- */
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->bUnordered==0 && (!pBest || pIdx->nColumn<pBest->nColumn) ){
- pBest = pIdx;
- }
- }
- if( pBest && pBest->nColumn<pTab->nCol ){
- iRoot = pBest->tnum;
- pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest);
- }
-
- /* Open a read-only cursor, execute the OP_Count, close the cursor. */
- sqlite3VdbeAddOp3(v, OP_OpenRead, iCsr, iRoot, iDb);
- if( pKeyInfo ){
- sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF);
- }
- sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
- sqlite3VdbeAddOp1(v, OP_Close, iCsr);
- explainSimpleCount(pParse, pTab, pBest);
- }else
-#endif /* SQLITE_OMIT_BTREECOUNT */
- {
- /* Check if the query is of one of the following forms:
- **
- ** SELECT min(x) FROM ...
- ** SELECT max(x) FROM ...
- **
- ** If it is, then ask the code in where.c to attempt to sort results
- ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause.
- ** If where.c is able to produce results sorted in this order, then
- ** add vdbe code to break out of the processing loop after the
- ** first iteration (since the first iteration of the loop is
- ** guaranteed to operate on the row with the minimum or maximum
- ** value of x, the only row required).
- **
- ** A special flag must be passed to sqlite3WhereBegin() to slightly
- ** modify behaviour as follows:
- **
- ** + If the query is a "SELECT min(x)", then the loop coded by
- ** where.c should not iterate over any values with a NULL value
- ** for x.
- **
- ** + The optimizer code in where.c (the thing that decides which
- ** index or indices to use) should place a different priority on
- ** satisfying the 'ORDER BY' clause than it does in other cases.
- ** Refer to code and comments in where.c for details.
- */
- ExprList *pMinMax = 0;
- u8 flag = minMaxQuery(p);
- if( flag ){
- assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
- assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
- pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
- pDel = pMinMax;
- if( pMinMax && !db->mallocFailed ){
- pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
- pMinMax->a[0].pExpr->op = TK_COLUMN;
- }
- }
-
- /* This case runs if the aggregate has no GROUP BY clause. The
- ** processing is much simpler since there is only a single row
- ** of output.
- */
- resetAccumulator(pParse, &sAggInfo);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0);
- if( pWInfo==0 ){
- sqlite3ExprListDelete(db, pDel);
- goto select_end;
- }
- updateAccumulator(pParse, &sAggInfo);
- assert( pMinMax==0 || pMinMax->nExpr==1 );
- if( pWInfo->nOBSat>0 ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
- VdbeComment((v, "%s() by index",
- (flag==WHERE_ORDERBY_MIN?"min":"max")));
- }
- sqlite3WhereEnd(pWInfo);
- finalizeAggFunctions(pParse, &sAggInfo);
- }
-
- pOrderBy = 0;
- sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0,
- pDest, addrEnd, addrEnd);
- sqlite3ExprListDelete(db, pDel);
- }
- sqlite3VdbeResolveLabel(v, addrEnd);
-
- } /* endif aggregate query */
-
- if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){
- explainTempTable(pParse, "DISTINCT");
- }
-
- /* If there is an ORDER BY clause, then we need to sort the results
- ** and send them to the callback one by one.
- */
- if( pOrderBy ){
- explainTempTable(pParse, "ORDER BY");
- generateSortTail(pParse, p, v, pEList->nExpr, pDest);
- }
-
- /* Jump here to skip this query
- */
- sqlite3VdbeResolveLabel(v, iEnd);
-
- /* The SELECT was successfully coded. Set the return code to 0
- ** to indicate no errors.
- */
- rc = 0;
-
- /* Control jumps to here if an error is encountered above, or upon
- ** successful coding of the SELECT.
- */
-select_end:
- explainSetInteger(pParse->iSelectId, iRestoreSelectId);
-
- /* Identify column names if results of the SELECT are to be output.
- */
- if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){
- generateColumnNames(pParse, pTabList, pEList);
- }
-
- sqlite3DbFree(db, sAggInfo.aCol);
- sqlite3DbFree(db, sAggInfo.aFunc);
- return rc;
-}
-
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-/*
-** Generate a human-readable description of a the Select object.
-*/
-static void explainOneSelect(Vdbe *pVdbe, Select *p){
- sqlite3ExplainPrintf(pVdbe, "SELECT ");
- if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
- if( p->selFlags & SF_Distinct ){
- sqlite3ExplainPrintf(pVdbe, "DISTINCT ");
- }
- if( p->selFlags & SF_Aggregate ){
- sqlite3ExplainPrintf(pVdbe, "agg_flag ");
- }
- sqlite3ExplainNL(pVdbe);
- sqlite3ExplainPrintf(pVdbe, " ");
- }
- sqlite3ExplainExprList(pVdbe, p->pEList);
- sqlite3ExplainNL(pVdbe);
- if( p->pSrc && p->pSrc->nSrc ){
- int i;
- sqlite3ExplainPrintf(pVdbe, "FROM ");
- sqlite3ExplainPush(pVdbe);
- for(i=0; i<p->pSrc->nSrc; i++){
- struct SrcList_item *pItem = &p->pSrc->a[i];
- sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor);
- if( pItem->pSelect ){
- sqlite3ExplainSelect(pVdbe, pItem->pSelect);
- if( pItem->pTab ){
- sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName);
- }
- }else if( pItem->zName ){
- sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName);
- }
- if( pItem->zAlias ){
- sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias);
- }
- if( pItem->jointype & JT_LEFT ){
- sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN");
- }
- sqlite3ExplainNL(pVdbe);
- }
- sqlite3ExplainPop(pVdbe);
- }
- if( p->pWhere ){
- sqlite3ExplainPrintf(pVdbe, "WHERE ");
- sqlite3ExplainExpr(pVdbe, p->pWhere);
- sqlite3ExplainNL(pVdbe);
- }
- if( p->pGroupBy ){
- sqlite3ExplainPrintf(pVdbe, "GROUPBY ");
- sqlite3ExplainExprList(pVdbe, p->pGroupBy);
- sqlite3ExplainNL(pVdbe);
- }
- if( p->pHaving ){
- sqlite3ExplainPrintf(pVdbe, "HAVING ");
- sqlite3ExplainExpr(pVdbe, p->pHaving);
- sqlite3ExplainNL(pVdbe);
- }
- if( p->pOrderBy ){
- sqlite3ExplainPrintf(pVdbe, "ORDERBY ");
- sqlite3ExplainExprList(pVdbe, p->pOrderBy);
- sqlite3ExplainNL(pVdbe);
- }
- if( p->pLimit ){
- sqlite3ExplainPrintf(pVdbe, "LIMIT ");
- sqlite3ExplainExpr(pVdbe, p->pLimit);
- sqlite3ExplainNL(pVdbe);
- }
- if( p->pOffset ){
- sqlite3ExplainPrintf(pVdbe, "OFFSET ");
- sqlite3ExplainExpr(pVdbe, p->pOffset);
- sqlite3ExplainNL(pVdbe);
- }
-}
-SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
- if( p==0 ){
- sqlite3ExplainPrintf(pVdbe, "(null-select)");
- return;
- }
- while( p->pPrior ) p = p->pPrior;
- sqlite3ExplainPush(pVdbe);
- while( p ){
- explainOneSelect(pVdbe, p);
- p = p->pNext;
- if( p==0 ) break;
- sqlite3ExplainNL(pVdbe);
- sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op));
- }
- sqlite3ExplainPrintf(pVdbe, "END");
- sqlite3ExplainPop(pVdbe);
-}
-
-/* End of the structure debug printing code
-*****************************************************************************/
-#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
-
-/************** End of select.c **********************************************/
-/************** Begin file table.c *******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the sqlite3_get_table() and sqlite3_free_table()
-** interface routines. These are just wrappers around the main
-** interface routine of sqlite3_exec().
-**
-** These routines are in a separate files so that they will not be linked
-** if they are not used.
-*/
-/* #include <stdlib.h> */
-/* #include <string.h> */
-
-#ifndef SQLITE_OMIT_GET_TABLE
-
-/*
-** This structure is used to pass data from sqlite3_get_table() through
-** to the callback function is uses to build the result.
-*/
-typedef struct TabResult {
- char **azResult; /* Accumulated output */
- char *zErrMsg; /* Error message text, if an error occurs */
- int nAlloc; /* Slots allocated for azResult[] */
- int nRow; /* Number of rows in the result */
- int nColumn; /* Number of columns in the result */
- int nData; /* Slots used in azResult[]. (nRow+1)*nColumn */
- int rc; /* Return code from sqlite3_exec() */
-} TabResult;
-
-/*
-** This routine is called once for each row in the result table. Its job
-** is to fill in the TabResult structure appropriately, allocating new
-** memory as necessary.
-*/
-static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
- TabResult *p = (TabResult*)pArg; /* Result accumulator */
- int need; /* Slots needed in p->azResult[] */
- int i; /* Loop counter */
- char *z; /* A single column of result */
-
- /* Make sure there is enough space in p->azResult to hold everything
- ** we need to remember from this invocation of the callback.
- */
- if( p->nRow==0 && argv!=0 ){
- need = nCol*2;
- }else{
- need = nCol;
- }
- if( p->nData + need > p->nAlloc ){
- char **azNew;
- p->nAlloc = p->nAlloc*2 + need;
- azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc );
- if( azNew==0 ) goto malloc_failed;
- p->azResult = azNew;
- }
-
- /* If this is the first row, then generate an extra row containing
- ** the names of all columns.
- */
- if( p->nRow==0 ){
- p->nColumn = nCol;
- for(i=0; i<nCol; i++){
- z = sqlite3_mprintf("%s", colv[i]);
- if( z==0 ) goto malloc_failed;
- p->azResult[p->nData++] = z;
- }
- }else if( p->nColumn!=nCol ){
- sqlite3_free(p->zErrMsg);
- p->zErrMsg = sqlite3_mprintf(
- "sqlite3_get_table() called with two or more incompatible queries"
- );
- p->rc = SQLITE_ERROR;
- return 1;
- }
-
- /* Copy over the row data
- */
- if( argv!=0 ){
- for(i=0; i<nCol; i++){
- if( argv[i]==0 ){
- z = 0;
- }else{
- int n = sqlite3Strlen30(argv[i])+1;
- z = sqlite3_malloc( n );
- if( z==0 ) goto malloc_failed;
- memcpy(z, argv[i], n);
- }
- p->azResult[p->nData++] = z;
- }
- p->nRow++;
- }
- return 0;
-
-malloc_failed:
- p->rc = SQLITE_NOMEM;
- return 1;
-}
-
-/*
-** Query the database. But instead of invoking a callback for each row,
-** malloc() for space to hold the result and return the entire results
-** at the conclusion of the call.
-**
-** The result that is written to ***pazResult is held in memory obtained
-** from malloc(). But the caller cannot free this memory directly.
-** Instead, the entire table should be passed to sqlite3_free_table() when
-** the calling procedure is finished using it.
-*/
-SQLITE_API int sqlite3_get_table(
- sqlite3 *db, /* The database on which the SQL executes */
- const char *zSql, /* The SQL to be executed */
- char ***pazResult, /* Write the result table here */
- int *pnRow, /* Write the number of rows in the result here */
- int *pnColumn, /* Write the number of columns of result here */
- char **pzErrMsg /* Write error messages here */
-){
- int rc;
- TabResult res;
-
- *pazResult = 0;
- if( pnColumn ) *pnColumn = 0;
- if( pnRow ) *pnRow = 0;
- if( pzErrMsg ) *pzErrMsg = 0;
- res.zErrMsg = 0;
- res.nRow = 0;
- res.nColumn = 0;
- res.nData = 1;
- res.nAlloc = 20;
- res.rc = SQLITE_OK;
- res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc );
- if( res.azResult==0 ){
- db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM;
- }
- res.azResult[0] = 0;
- rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
- assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
- res.azResult[0] = SQLITE_INT_TO_PTR(res.nData);
- if( (rc&0xff)==SQLITE_ABORT ){
- sqlite3_free_table(&res.azResult[1]);
- if( res.zErrMsg ){
- if( pzErrMsg ){
- sqlite3_free(*pzErrMsg);
- *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg);
- }
- sqlite3_free(res.zErrMsg);
- }
- db->errCode = res.rc; /* Assume 32-bit assignment is atomic */
- return res.rc;
- }
- sqlite3_free(res.zErrMsg);
- if( rc!=SQLITE_OK ){
- sqlite3_free_table(&res.azResult[1]);
- return rc;
- }
- if( res.nAlloc>res.nData ){
- char **azNew;
- azNew = sqlite3_realloc( res.azResult, sizeof(char*)*res.nData );
- if( azNew==0 ){
- sqlite3_free_table(&res.azResult[1]);
- db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM;
- }
- res.azResult = azNew;
- }
- *pazResult = &res.azResult[1];
- if( pnColumn ) *pnColumn = res.nColumn;
- if( pnRow ) *pnRow = res.nRow;
- return rc;
-}
-
-/*
-** This routine frees the space the sqlite3_get_table() malloced.
-*/
-SQLITE_API void sqlite3_free_table(
- char **azResult /* Result returned from from sqlite3_get_table() */
-){
- if( azResult ){
- int i, n;
- azResult--;
- assert( azResult!=0 );
- n = SQLITE_PTR_TO_INT(azResult[0]);
- for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
- sqlite3_free(azResult);
- }
-}
-
-#endif /* SQLITE_OMIT_GET_TABLE */
-
-/************** End of table.c ***********************************************/
-/************** Begin file trigger.c *****************************************/
-/*
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains the implementation for TRIGGERs
-*/
-
-#ifndef SQLITE_OMIT_TRIGGER
-/*
-** Delete a linked list of TriggerStep structures.
-*/
-SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){
- while( pTriggerStep ){
- TriggerStep * pTmp = pTriggerStep;
- pTriggerStep = pTriggerStep->pNext;
-
- sqlite3ExprDelete(db, pTmp->pWhere);
- sqlite3ExprListDelete(db, pTmp->pExprList);
- sqlite3SelectDelete(db, pTmp->pSelect);
- sqlite3IdListDelete(db, pTmp->pIdList);
-
- sqlite3DbFree(db, pTmp);
- }
-}
-
-/*
-** Given table pTab, return a list of all the triggers attached to
-** the table. The list is connected by Trigger.pNext pointers.
-**
-** All of the triggers on pTab that are in the same database as pTab
-** are already attached to pTab->pTrigger. But there might be additional
-** triggers on pTab in the TEMP schema. This routine prepends all
-** TEMP triggers on pTab to the beginning of the pTab->pTrigger list
-** and returns the combined list.
-**
-** To state it another way: This routine returns a list of all triggers
-** that fire off of pTab. The list will include any TEMP triggers on
-** pTab as well as the triggers lised in pTab->pTrigger.
-*/
-SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
- Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
- Trigger *pList = 0; /* List of triggers to return */
-
- if( pParse->disableTriggers ){
- return 0;
- }
-
- if( pTmpSchema!=pTab->pSchema ){
- HashElem *p;
- assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) );
- for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){
- Trigger *pTrig = (Trigger *)sqliteHashData(p);
- if( pTrig->pTabSchema==pTab->pSchema
- && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
- ){
- pTrig->pNext = (pList ? pList : pTab->pTrigger);
- pList = pTrig;
- }
- }
- }
-
- return (pList ? pList : pTab->pTrigger);
-}
-
-/*
-** This is called by the parser when it sees a CREATE TRIGGER statement
-** up to the point of the BEGIN before the trigger actions. A Trigger
-** structure is generated based on the information available and stored
-** in pParse->pNewTrigger. After the trigger actions have been parsed, the
-** sqlite3FinishTrigger() function is called to complete the trigger
-** construction process.
-*/
-SQLITE_PRIVATE void sqlite3BeginTrigger(
- Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
- Token *pName1, /* The name of the trigger */
- Token *pName2, /* The name of the trigger */
- int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
- int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
- IdList *pColumns, /* column list if this is an UPDATE OF trigger */
- SrcList *pTableName,/* The name of the table/view the trigger applies to */
- Expr *pWhen, /* WHEN clause */
- int isTemp, /* True if the TEMPORARY keyword is present */
- int noErr /* Suppress errors if the trigger already exists */
-){
- Trigger *pTrigger = 0; /* The new trigger */
- Table *pTab; /* Table that the trigger fires off of */
- char *zName = 0; /* Name of the trigger */
- sqlite3 *db = pParse->db; /* The database connection */
- int iDb; /* The database to store the trigger in */
- Token *pName; /* The unqualified db name */
- DbFixer sFix; /* State vector for the DB fixer */
- int iTabDb; /* Index of the database holding pTab */
-
- assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */
- assert( pName2!=0 );
- assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE );
- assert( op>0 && op<0xff );
- if( isTemp ){
- /* If TEMP was specified, then the trigger name may not be qualified. */
- if( pName2->n>0 ){
- sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name");
- goto trigger_cleanup;
- }
- iDb = 1;
- pName = pName1;
- }else{
- /* Figure out the db that the trigger will be created in */
- iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
- if( iDb<0 ){
- goto trigger_cleanup;
- }
- }
- if( !pTableName || db->mallocFailed ){
- goto trigger_cleanup;
- }
-
- /* A long-standing parser bug is that this syntax was allowed:
- **
- ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab ....
- ** ^^^^^^^^
- **
- ** To maintain backwards compatibility, ignore the database
- ** name on pTableName if we are reparsing our of SQLITE_MASTER.
- */
- if( db->init.busy && iDb!=1 ){
- sqlite3DbFree(db, pTableName->a[0].zDatabase);
- pTableName->a[0].zDatabase = 0;
- }
-
- /* If the trigger name was unqualified, and the table is a temp table,
- ** then set iDb to 1 to create the trigger in the temporary database.
- ** If sqlite3SrcListLookup() returns 0, indicating the table does not
- ** exist, the error is caught by the block below.
- */
- pTab = sqlite3SrcListLookup(pParse, pTableName);
- if( db->init.busy==0 && pName2->n==0 && pTab
- && pTab->pSchema==db->aDb[1].pSchema ){
- iDb = 1;
- }
-
- /* Ensure the table name matches database name and that the table exists */
- if( db->mallocFailed ) goto trigger_cleanup;
- assert( pTableName->nSrc==1 );
- if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) &&
- sqlite3FixSrcList(&sFix, pTableName) ){
- goto trigger_cleanup;
- }
- pTab = sqlite3SrcListLookup(pParse, pTableName);
- if( !pTab ){
- /* The table does not exist. */
- if( db->init.iDb==1 ){
- /* Ticket #3810.
- ** Normally, whenever a table is dropped, all associated triggers are
- ** dropped too. But if a TEMP trigger is created on a non-TEMP table
- ** and the table is dropped by a different database connection, the
- ** trigger is not visible to the database connection that does the
- ** drop so the trigger cannot be dropped. This results in an
- ** "orphaned trigger" - a trigger whose associated table is missing.
- */
- db->init.orphanTrigger = 1;
- }
- goto trigger_cleanup;
- }
- if( IsVirtual(pTab) ){
- sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables");
- goto trigger_cleanup;
- }
-
- /* Check that the trigger name is not reserved and that no trigger of the
- ** specified name exists */
- zName = sqlite3NameFromToken(db, pName);
- if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
- goto trigger_cleanup;
- }
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
- zName, sqlite3Strlen30(zName)) ){
- if( !noErr ){
- sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
- }else{
- assert( !db->init.busy );
- sqlite3CodeVerifySchema(pParse, iDb);
- }
- goto trigger_cleanup;
- }
-
- /* Do not create a trigger on a system table */
- if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
- sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
- pParse->nErr++;
- goto trigger_cleanup;
- }
-
- /* INSTEAD of triggers are only for views and views only support INSTEAD
- ** of triggers.
- */
- if( pTab->pSelect && tr_tm!=TK_INSTEAD ){
- sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S",
- (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
- goto trigger_cleanup;
- }
- if( !pTab->pSelect && tr_tm==TK_INSTEAD ){
- sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF"
- " trigger on table: %S", pTableName, 0);
- goto trigger_cleanup;
- }
- iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int code = SQLITE_CREATE_TRIGGER;
- const char *zDb = db->aDb[iTabDb].zName;
- const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
- if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
- if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
- goto trigger_cleanup;
- }
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
- goto trigger_cleanup;
- }
- }
-#endif
-
- /* INSTEAD OF triggers can only appear on views and BEFORE triggers
- ** cannot appear on views. So we might as well translate every
- ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code
- ** elsewhere.
- */
- if (tr_tm == TK_INSTEAD){
- tr_tm = TK_BEFORE;
- }
-
- /* Build the Trigger object */
- pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger));
- if( pTrigger==0 ) goto trigger_cleanup;
- pTrigger->zName = zName;
- zName = 0;
- pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName);
- pTrigger->pSchema = db->aDb[iDb].pSchema;
- pTrigger->pTabSchema = pTab->pSchema;
- pTrigger->op = (u8)op;
- pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
- pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
- pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
- assert( pParse->pNewTrigger==0 );
- pParse->pNewTrigger = pTrigger;
-
-trigger_cleanup:
- sqlite3DbFree(db, zName);
- sqlite3SrcListDelete(db, pTableName);
- sqlite3IdListDelete(db, pColumns);
- sqlite3ExprDelete(db, pWhen);
- if( !pParse->pNewTrigger ){
- sqlite3DeleteTrigger(db, pTrigger);
- }else{
- assert( pParse->pNewTrigger==pTrigger );
- }
-}
-
-/*
-** This routine is called after all of the trigger actions have been parsed
-** in order to complete the process of building the trigger.
-*/
-SQLITE_PRIVATE void sqlite3FinishTrigger(
- Parse *pParse, /* Parser context */
- TriggerStep *pStepList, /* The triggered program */
- Token *pAll /* Token that describes the complete CREATE TRIGGER */
-){
- Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */
- char *zName; /* Name of trigger */
- sqlite3 *db = pParse->db; /* The database */
- DbFixer sFix; /* Fixer object */
- int iDb; /* Database containing the trigger */
- Token nameToken; /* Trigger name for error reporting */
-
- pParse->pNewTrigger = 0;
- if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup;
- zName = pTrig->zName;
- iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
- pTrig->step_list = pStepList;
- while( pStepList ){
- pStepList->pTrig = pTrig;
- pStepList = pStepList->pNext;
- }
- nameToken.z = pTrig->zName;
- nameToken.n = sqlite3Strlen30(nameToken.z);
- if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken)
- && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
- goto triggerfinish_cleanup;
- }
-
- /* if we are not initializing,
- ** build the sqlite_master entry
- */
- if( !db->init.busy ){
- Vdbe *v;
- char *z;
-
- /* Make an entry in the sqlite_master table */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto triggerfinish_cleanup;
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
- sqlite3NestedParse(pParse,
- "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zName,
- pTrig->table, z);
- sqlite3DbFree(db, z);
- sqlite3ChangeCookie(pParse, iDb);
- sqlite3VdbeAddParseSchemaOp(v, iDb,
- sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName));
- }
-
- if( db->init.busy ){
- Trigger *pLink = pTrig;
- Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- pTrig = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), pTrig);
- if( pTrig ){
- db->mallocFailed = 1;
- }else if( pLink->pSchema==pLink->pTabSchema ){
- Table *pTab;
- int n = sqlite3Strlen30(pLink->table);
- pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table, n);
- assert( pTab!=0 );
- pLink->pNext = pTab->pTrigger;
- pTab->pTrigger = pLink;
- }
- }
-
-triggerfinish_cleanup:
- sqlite3DeleteTrigger(db, pTrig);
- assert( !pParse->pNewTrigger );
- sqlite3DeleteTriggerStep(db, pStepList);
-}
-
-/*
-** Turn a SELECT statement (that the pSelect parameter points to) into
-** a trigger step. Return a pointer to a TriggerStep structure.
-**
-** The parser calls this routine when it finds a SELECT statement in
-** body of a TRIGGER.
-*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
- TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
- if( pTriggerStep==0 ) {
- sqlite3SelectDelete(db, pSelect);
- return 0;
- }
- pTriggerStep->op = TK_SELECT;
- pTriggerStep->pSelect = pSelect;
- pTriggerStep->orconf = OE_Default;
- return pTriggerStep;
-}
-
-/*
-** Allocate space to hold a new trigger step. The allocated space
-** holds both the TriggerStep object and the TriggerStep.target.z string.
-**
-** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
-*/
-static TriggerStep *triggerStepAllocate(
- sqlite3 *db, /* Database connection */
- u8 op, /* Trigger opcode */
- Token *pName /* The target name */
-){
- TriggerStep *pTriggerStep;
-
- pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
- if( pTriggerStep ){
- char *z = (char*)&pTriggerStep[1];
- memcpy(z, pName->z, pName->n);
- pTriggerStep->target.z = z;
- pTriggerStep->target.n = pName->n;
- pTriggerStep->op = op;
- }
- return pTriggerStep;
-}
-
-/*
-** Build a trigger step out of an INSERT statement. Return a pointer
-** to the new trigger step.
-**
-** The parser calls this routine when it sees an INSERT inside the
-** body of a trigger.
-*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
- sqlite3 *db, /* The database connection */
- Token *pTableName, /* Name of the table into which we insert */
- IdList *pColumn, /* List of columns in pTableName to insert into */
- ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
- Select *pSelect, /* A SELECT statement that supplies values */
- u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
-){
- TriggerStep *pTriggerStep;
-
- assert(pEList == 0 || pSelect == 0);
- assert(pEList != 0 || pSelect != 0 || db->mallocFailed);
-
- pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
- if( pTriggerStep ){
- pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
- pTriggerStep->pIdList = pColumn;
- pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
- pTriggerStep->orconf = orconf;
- }else{
- sqlite3IdListDelete(db, pColumn);
- }
- sqlite3ExprListDelete(db, pEList);
- sqlite3SelectDelete(db, pSelect);
-
- return pTriggerStep;
-}
-
-/*
-** Construct a trigger step that implements an UPDATE statement and return
-** a pointer to that trigger step. The parser calls this routine when it
-** sees an UPDATE statement inside the body of a CREATE TRIGGER.
-*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
- sqlite3 *db, /* The database connection */
- Token *pTableName, /* Name of the table to be updated */
- ExprList *pEList, /* The SET clause: list of column and new values */
- Expr *pWhere, /* The WHERE clause */
- u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
-){
- TriggerStep *pTriggerStep;
-
- pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
- if( pTriggerStep ){
- pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
- pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
- pTriggerStep->orconf = orconf;
- }
- sqlite3ExprListDelete(db, pEList);
- sqlite3ExprDelete(db, pWhere);
- return pTriggerStep;
-}
-
-/*
-** Construct a trigger step that implements a DELETE statement and return
-** a pointer to that trigger step. The parser calls this routine when it
-** sees a DELETE statement inside the body of a CREATE TRIGGER.
-*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(
- sqlite3 *db, /* Database connection */
- Token *pTableName, /* The table from which rows are deleted */
- Expr *pWhere /* The WHERE clause */
-){
- TriggerStep *pTriggerStep;
-
- pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
- if( pTriggerStep ){
- pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
- pTriggerStep->orconf = OE_Default;
- }
- sqlite3ExprDelete(db, pWhere);
- return pTriggerStep;
-}
-
-/*
-** Recursively delete a Trigger structure
-*/
-SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
- if( pTrigger==0 ) return;
- sqlite3DeleteTriggerStep(db, pTrigger->step_list);
- sqlite3DbFree(db, pTrigger->zName);
- sqlite3DbFree(db, pTrigger->table);
- sqlite3ExprDelete(db, pTrigger->pWhen);
- sqlite3IdListDelete(db, pTrigger->pColumns);
- sqlite3DbFree(db, pTrigger);
-}
-
-/*
-** This function is called to drop a trigger from the database schema.
-**
-** This may be called directly from the parser and therefore identifies
-** the trigger by name. The sqlite3DropTriggerPtr() routine does the
-** same job as this routine except it takes a pointer to the trigger
-** instead of the trigger name.
-**/
-SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
- Trigger *pTrigger = 0;
- int i;
- const char *zDb;
- const char *zName;
- int nName;
- sqlite3 *db = pParse->db;
-
- if( db->mallocFailed ) goto drop_trigger_cleanup;
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
- goto drop_trigger_cleanup;
- }
-
- assert( pName->nSrc==1 );
- zDb = pName->a[0].zDatabase;
- zName = pName->a[0].zName;
- nName = sqlite3Strlen30(zName);
- assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
- for(i=OMIT_TEMPDB; i<db->nDb; i++){
- int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
- if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
- assert( sqlite3SchemaMutexHeld(db, j, 0) );
- pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
- if( pTrigger ) break;
- }
- if( !pTrigger ){
- if( !noErr ){
- sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
- }else{
- sqlite3CodeVerifyNamedSchema(pParse, zDb);
- }
- pParse->checkSchema = 1;
- goto drop_trigger_cleanup;
- }
- sqlite3DropTriggerPtr(pParse, pTrigger);
-
-drop_trigger_cleanup:
- sqlite3SrcListDelete(db, pName);
-}
-
-/*
-** Return a pointer to the Table structure for the table that a trigger
-** is set on.
-*/
-static Table *tableOfTrigger(Trigger *pTrigger){
- int n = sqlite3Strlen30(pTrigger->table);
- return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
-}
-
-
-/*
-** Drop a trigger given a pointer to that trigger.
-*/
-SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
- Table *pTable;
- Vdbe *v;
- sqlite3 *db = pParse->db;
- int iDb;
-
- iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema);
- assert( iDb>=0 && iDb<db->nDb );
- pTable = tableOfTrigger(pTrigger);
- assert( pTable );
- assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int code = SQLITE_DROP_TRIGGER;
- const char *zDb = db->aDb[iDb].zName;
- const char *zTab = SCHEMA_TABLE(iDb);
- if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
- if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
- sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
- return;
- }
- }
-#endif
-
- /* Generate code to destroy the database record of the trigger.
- */
- assert( pTable!=0 );
- if( (v = sqlite3GetVdbe(pParse))!=0 ){
- int base;
- static const VdbeOpList dropTrigger[] = {
- { OP_Rewind, 0, ADDR(9), 0},
- { OP_String8, 0, 1, 0}, /* 1 */
- { OP_Column, 0, 1, 2},
- { OP_Ne, 2, ADDR(8), 1},
- { OP_String8, 0, 1, 0}, /* 4: "trigger" */
- { OP_Column, 0, 0, 2},
- { OP_Ne, 2, ADDR(8), 1},
- { OP_Delete, 0, 0, 0},
- { OP_Next, 0, ADDR(1), 0}, /* 8 */
- };
-
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- sqlite3OpenMasterTable(pParse, iDb);
- base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
- sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT);
- sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
- sqlite3ChangeCookie(pParse, iDb);
- sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
- sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
- if( pParse->nMem<3 ){
- pParse->nMem = 3;
- }
- }
-}
-
-/*
-** Remove a trigger from the hash tables of the sqlite* pointer.
-*/
-SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
- Trigger *pTrigger;
- Hash *pHash;
-
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- pHash = &(db->aDb[iDb].pSchema->trigHash);
- pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0);
- if( ALWAYS(pTrigger) ){
- if( pTrigger->pSchema==pTrigger->pTabSchema ){
- Table *pTab = tableOfTrigger(pTrigger);
- Trigger **pp;
- for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
- *pp = (*pp)->pNext;
- }
- sqlite3DeleteTrigger(db, pTrigger);
- db->flags |= SQLITE_InternChanges;
- }
-}
-
-/*
-** pEList is the SET clause of an UPDATE statement. Each entry
-** in pEList is of the format <id>=<expr>. If any of the entries
-** in pEList have an <id> which matches an identifier in pIdList,
-** then return TRUE. If pIdList==NULL, then it is considered a
-** wildcard that matches anything. Likewise if pEList==NULL then
-** it matches anything so always return true. Return false only
-** if there is no match.
-*/
-static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){
- int e;
- if( pIdList==0 || NEVER(pEList==0) ) return 1;
- for(e=0; e<pEList->nExpr; e++){
- if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
- }
- return 0;
-}
-
-/*
-** Return a list of all triggers on table pTab if there exists at least
-** one trigger that must be fired when an operation of type 'op' is
-** performed on the table, and, if that operation is an UPDATE, if at
-** least one of the columns in pChanges is being modified.
-*/
-SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
- Parse *pParse, /* Parse context */
- Table *pTab, /* The table the contains the triggers */
- int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
- ExprList *pChanges, /* Columns that change in an UPDATE statement */
- int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
-){
- int mask = 0;
- Trigger *pList = 0;
- Trigger *p;
-
- if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){
- pList = sqlite3TriggerList(pParse, pTab);
- }
- assert( pList==0 || IsVirtual(pTab)==0 );
- for(p=pList; p; p=p->pNext){
- if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
- mask |= p->tr_tm;
- }
- }
- if( pMask ){
- *pMask = mask;
- }
- return (mask ? pList : 0);
-}
-
-/*
-** Convert the pStep->target token into a SrcList and return a pointer
-** to that SrcList.
-**
-** This routine adds a specific database name, if needed, to the target when
-** forming the SrcList. This prevents a trigger in one database from
-** referring to a target in another database. An exception is when the
-** trigger is in TEMP in which case it can refer to any other database it
-** wants.
-*/
-static SrcList *targetSrcList(
- Parse *pParse, /* The parsing context */
- TriggerStep *pStep /* The trigger containing the target token */
-){
- int iDb; /* Index of the database to use */
- SrcList *pSrc; /* SrcList to be returned */
-
- pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
- if( pSrc ){
- assert( pSrc->nSrc>0 );
- assert( pSrc->a!=0 );
- iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
- if( iDb==0 || iDb>=2 ){
- sqlite3 *db = pParse->db;
- assert( iDb<pParse->db->nDb );
- pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
- }
- }
- return pSrc;
-}
-
-/*
-** Generate VDBE code for the statements inside the body of a single
-** trigger.
-*/
-static int codeTriggerProgram(
- Parse *pParse, /* The parser context */
- TriggerStep *pStepList, /* List of statements inside the trigger body */
- int orconf /* Conflict algorithm. (OE_Abort, etc) */
-){
- TriggerStep *pStep;
- Vdbe *v = pParse->pVdbe;
- sqlite3 *db = pParse->db;
-
- assert( pParse->pTriggerTab && pParse->pToplevel );
- assert( pStepList );
- assert( v!=0 );
- for(pStep=pStepList; pStep; pStep=pStep->pNext){
- /* Figure out the ON CONFLICT policy that will be used for this step
- ** of the trigger program. If the statement that caused this trigger
- ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use
- ** the ON CONFLICT policy that was specified as part of the trigger
- ** step statement. Example:
- **
- ** CREATE TRIGGER AFTER INSERT ON t1 BEGIN;
- ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b);
- ** END;
- **
- ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy
- ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy
- */
- pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
-
- /* Clear the cookieGoto flag. When coding triggers, the cookieGoto
- ** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
- ** that it is not safe to refactor constants (this happens after the
- ** start of the first loop in the SQL statement is coded - at that
- ** point code may be conditionally executed, so it is no longer safe to
- ** initialize constant register values). */
- assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
- pParse->cookieGoto = 0;
-
- switch( pStep->op ){
- case TK_UPDATE: {
- sqlite3Update(pParse,
- targetSrcList(pParse, pStep),
- sqlite3ExprListDup(db, pStep->pExprList, 0),
- sqlite3ExprDup(db, pStep->pWhere, 0),
- pParse->eOrconf
- );
- break;
- }
- case TK_INSERT: {
- sqlite3Insert(pParse,
- targetSrcList(pParse, pStep),
- sqlite3ExprListDup(db, pStep->pExprList, 0),
- sqlite3SelectDup(db, pStep->pSelect, 0),
- sqlite3IdListDup(db, pStep->pIdList),
- pParse->eOrconf
- );
- break;
- }
- case TK_DELETE: {
- sqlite3DeleteFrom(pParse,
- targetSrcList(pParse, pStep),
- sqlite3ExprDup(db, pStep->pWhere, 0)
- );
- break;
- }
- default: assert( pStep->op==TK_SELECT ); {
- SelectDest sDest;
- Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
- sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
- sqlite3Select(pParse, pSelect, &sDest);
- sqlite3SelectDelete(db, pSelect);
- break;
- }
- }
- if( pStep->op!=TK_SELECT ){
- sqlite3VdbeAddOp0(v, OP_ResetCount);
- }
- }
-
- return 0;
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** This function is used to add VdbeComment() annotations to a VDBE
-** program. It is not used in production code, only for debugging.
-*/
-static const char *onErrorText(int onError){
- switch( onError ){
- case OE_Abort: return "abort";
- case OE_Rollback: return "rollback";
- case OE_Fail: return "fail";
- case OE_Replace: return "replace";
- case OE_Ignore: return "ignore";
- case OE_Default: return "default";
- }
- return "n/a";
-}
-#endif
-
-/*
-** Parse context structure pFrom has just been used to create a sub-vdbe
-** (trigger program). If an error has occurred, transfer error information
-** from pFrom to pTo.
-*/
-static void transferParseError(Parse *pTo, Parse *pFrom){
- assert( pFrom->zErrMsg==0 || pFrom->nErr );
- assert( pTo->zErrMsg==0 || pTo->nErr );
- if( pTo->nErr==0 ){
- pTo->zErrMsg = pFrom->zErrMsg;
- pTo->nErr = pFrom->nErr;
- }else{
- sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
- }
-}
-
-/*
-** Create and populate a new TriggerPrg object with a sub-program
-** implementing trigger pTrigger with ON CONFLICT policy orconf.
-*/
-static TriggerPrg *codeRowTrigger(
- Parse *pParse, /* Current parse context */
- Trigger *pTrigger, /* Trigger to code */
- Table *pTab, /* The table pTrigger is attached to */
- int orconf /* ON CONFLICT policy to code trigger program with */
-){
- Parse *pTop = sqlite3ParseToplevel(pParse);
- sqlite3 *db = pParse->db; /* Database handle */
- TriggerPrg *pPrg; /* Value to return */
- Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */
- Vdbe *v; /* Temporary VM */
- NameContext sNC; /* Name context for sub-vdbe */
- SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */
- Parse *pSubParse; /* Parse context for sub-vdbe */
- int iEndTrigger = 0; /* Label to jump to if WHEN is false */
-
- assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
- assert( pTop->pVdbe );
-
- /* Allocate the TriggerPrg and SubProgram objects. To ensure that they
- ** are freed if an error occurs, link them into the Parse.pTriggerPrg
- ** list of the top-level Parse object sooner rather than later. */
- pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg));
- if( !pPrg ) return 0;
- pPrg->pNext = pTop->pTriggerPrg;
- pTop->pTriggerPrg = pPrg;
- pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram));
- if( !pProgram ) return 0;
- sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram);
- pPrg->pTrigger = pTrigger;
- pPrg->orconf = orconf;
- pPrg->aColmask[0] = 0xffffffff;
- pPrg->aColmask[1] = 0xffffffff;
-
- /* Allocate and populate a new Parse context to use for coding the
- ** trigger sub-program. */
- pSubParse = sqlite3StackAllocZero(db, sizeof(Parse));
- if( !pSubParse ) return 0;
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pSubParse;
- pSubParse->db = db;
- pSubParse->pTriggerTab = pTab;
- pSubParse->pToplevel = pTop;
- pSubParse->zAuthContext = pTrigger->zName;
- pSubParse->eTriggerOp = pTrigger->op;
- pSubParse->nQueryLoop = pParse->nQueryLoop;
-
- v = sqlite3GetVdbe(pSubParse);
- if( v ){
- VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
- pTrigger->zName, onErrorText(orconf),
- (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
- (pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
- (pTrigger->op==TK_INSERT ? "INSERT" : ""),
- (pTrigger->op==TK_DELETE ? "DELETE" : ""),
- pTab->zName
- ));
-#ifndef SQLITE_OMIT_TRACE
- sqlite3VdbeChangeP4(v, -1,
- sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
- );
-#endif
-
- /* If one was specified, code the WHEN clause. If it evaluates to false
- ** (or NULL) the sub-vdbe is immediately halted by jumping to the
- ** OP_Halt inserted at the end of the program. */
- if( pTrigger->pWhen ){
- pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
- if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen)
- && db->mallocFailed==0
- ){
- iEndTrigger = sqlite3VdbeMakeLabel(v);
- sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
- }
- sqlite3ExprDelete(db, pWhen);
- }
-
- /* Code the trigger program into the sub-vdbe. */
- codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
-
- /* Insert an OP_Halt at the end of the sub-program. */
- if( iEndTrigger ){
- sqlite3VdbeResolveLabel(v, iEndTrigger);
- }
- sqlite3VdbeAddOp0(v, OP_Halt);
- VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
-
- transferParseError(pParse, pSubParse);
- if( db->mallocFailed==0 ){
- pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
- }
- pProgram->nMem = pSubParse->nMem;
- pProgram->nCsr = pSubParse->nTab;
- pProgram->nOnce = pSubParse->nOnce;
- pProgram->token = (void *)pTrigger;
- pPrg->aColmask[0] = pSubParse->oldmask;
- pPrg->aColmask[1] = pSubParse->newmask;
- sqlite3VdbeDelete(v);
- }
-
- assert( !pSubParse->pAinc && !pSubParse->pZombieTab );
- assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
- sqlite3StackFree(db, pSubParse);
-
- return pPrg;
-}
-
-/*
-** Return a pointer to a TriggerPrg object containing the sub-program for
-** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such
-** TriggerPrg object exists, a new object is allocated and populated before
-** being returned.
-*/
-static TriggerPrg *getRowTrigger(
- Parse *pParse, /* Current parse context */
- Trigger *pTrigger, /* Trigger to code */
- Table *pTab, /* The table trigger pTrigger is attached to */
- int orconf /* ON CONFLICT algorithm. */
-){
- Parse *pRoot = sqlite3ParseToplevel(pParse);
- TriggerPrg *pPrg;
-
- assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) );
-
- /* It may be that this trigger has already been coded (or is in the
- ** process of being coded). If this is the case, then an entry with
- ** a matching TriggerPrg.pTrigger field will be present somewhere
- ** in the Parse.pTriggerPrg list. Search for such an entry. */
- for(pPrg=pRoot->pTriggerPrg;
- pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf);
- pPrg=pPrg->pNext
- );
-
- /* If an existing TriggerPrg could not be located, create a new one. */
- if( !pPrg ){
- pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf);
- }
-
- return pPrg;
-}
-
-/*
-** Generate code for the trigger program associated with trigger p on
-** table pTab. The reg, orconf and ignoreJump parameters passed to this
-** function are the same as those described in the header function for
-** sqlite3CodeRowTrigger()
-*/
-SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(
- Parse *pParse, /* Parse context */
- Trigger *p, /* Trigger to code */
- Table *pTab, /* The table to code triggers from */
- int reg, /* Reg array containing OLD.* and NEW.* values */
- int orconf, /* ON CONFLICT policy */
- int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
-){
- Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */
- TriggerPrg *pPrg;
- pPrg = getRowTrigger(pParse, p, pTab, orconf);
- assert( pPrg || pParse->nErr || pParse->db->mallocFailed );
-
- /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program
- ** is a pointer to the sub-vdbe containing the trigger program. */
- if( pPrg ){
- int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers));
-
- sqlite3VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem);
- sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM);
- VdbeComment(
- (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf)));
-
- /* Set the P5 operand of the OP_Program instruction to non-zero if
- ** recursive invocation of this trigger program is disallowed. Recursive
- ** invocation is disallowed if (a) the sub-program is really a trigger,
- ** not a foreign key action, and (b) the flag to enable recursive triggers
- ** is clear. */
- sqlite3VdbeChangeP5(v, (u8)bRecursive);
- }
-}
-
-/*
-** This is called to code the required FOR EACH ROW triggers for an operation
-** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE)
-** is given by the op paramater. The tr_tm parameter determines whether the
-** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then
-** parameter pChanges is passed the list of columns being modified.
-**
-** If there are no triggers that fire at the specified time for the specified
-** operation on pTab, this function is a no-op.
-**
-** The reg argument is the address of the first in an array of registers
-** that contain the values substituted for the new.* and old.* references
-** in the trigger program. If N is the number of columns in table pTab
-** (a copy of pTab->nCol), then registers are populated as follows:
-**
-** Register Contains
-** ------------------------------------------------------
-** reg+0 OLD.rowid
-** reg+1 OLD.* value of left-most column of pTab
-** ... ...
-** reg+N OLD.* value of right-most column of pTab
-** reg+N+1 NEW.rowid
-** reg+N+2 OLD.* value of left-most column of pTab
-** ... ...
-** reg+N+N+1 NEW.* value of right-most column of pTab
-**
-** For ON DELETE triggers, the registers containing the NEW.* values will
-** never be accessed by the trigger program, so they are not allocated or
-** populated by the caller (there is no data to populate them with anyway).
-** Similarly, for ON INSERT triggers the values stored in the OLD.* registers
-** are never accessed, and so are not allocated by the caller. So, for an
-** ON INSERT trigger, the value passed to this function as parameter reg
-** is not a readable register, although registers (reg+N) through
-** (reg+N+N+1) are.
-**
-** Parameter orconf is the default conflict resolution algorithm for the
-** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump
-** is the instruction that control should jump to if a trigger program
-** raises an IGNORE exception.
-*/
-SQLITE_PRIVATE void sqlite3CodeRowTrigger(
- Parse *pParse, /* Parse context */
- Trigger *pTrigger, /* List of triggers on table pTab */
- int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
- ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
- int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
- Table *pTab, /* The table to code triggers from */
- int reg, /* The first in an array of registers (see above) */
- int orconf, /* ON CONFLICT policy */
- int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
-){
- Trigger *p; /* Used to iterate through pTrigger list */
-
- assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE );
- assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER );
- assert( (op==TK_UPDATE)==(pChanges!=0) );
-
- for(p=pTrigger; p; p=p->pNext){
-
- /* Sanity checking: The schema for the trigger and for the table are
- ** always defined. The trigger must be in the same schema as the table
- ** or else it must be a TEMP trigger. */
- assert( p->pSchema!=0 );
- assert( p->pTabSchema!=0 );
- assert( p->pSchema==p->pTabSchema
- || p->pSchema==pParse->db->aDb[1].pSchema );
-
- /* Determine whether we should code this trigger */
- if( p->op==op
- && p->tr_tm==tr_tm
- && checkColumnOverlap(p->pColumns, pChanges)
- ){
- sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump);
- }
- }
-}
-
-/*
-** Triggers may access values stored in the old.* or new.* pseudo-table.
-** This function returns a 32-bit bitmask indicating which columns of the
-** old.* or new.* tables actually are used by triggers. This information
-** may be used by the caller, for example, to avoid having to load the entire
-** old.* record into memory when executing an UPDATE or DELETE command.
-**
-** Bit 0 of the returned mask is set if the left-most column of the
-** table may be accessed using an [old|new].<col> reference. Bit 1 is set if
-** the second leftmost column value is required, and so on. If there
-** are more than 32 columns in the table, and at least one of the columns
-** with an index greater than 32 may be accessed, 0xffffffff is returned.
-**
-** It is not possible to determine if the old.rowid or new.rowid column is
-** accessed by triggers. The caller must always assume that it is.
-**
-** Parameter isNew must be either 1 or 0. If it is 0, then the mask returned
-** applies to the old.* table. If 1, the new.* table.
-**
-** Parameter tr_tm must be a mask with one or both of the TRIGGER_BEFORE
-** and TRIGGER_AFTER bits set. Values accessed by BEFORE triggers are only
-** included in the returned mask if the TRIGGER_BEFORE bit is set in the
-** tr_tm parameter. Similarly, values accessed by AFTER triggers are only
-** included in the returned mask if the TRIGGER_AFTER bit is set in tr_tm.
-*/
-SQLITE_PRIVATE u32 sqlite3TriggerColmask(
- Parse *pParse, /* Parse context */
- Trigger *pTrigger, /* List of triggers on table pTab */
- ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
- int isNew, /* 1 for new.* ref mask, 0 for old.* ref mask */
- int tr_tm, /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
- Table *pTab, /* The table to code triggers from */
- int orconf /* Default ON CONFLICT policy for trigger steps */
-){
- const int op = pChanges ? TK_UPDATE : TK_DELETE;
- u32 mask = 0;
- Trigger *p;
-
- assert( isNew==1 || isNew==0 );
- for(p=pTrigger; p; p=p->pNext){
- if( p->op==op && (tr_tm&p->tr_tm)
- && checkColumnOverlap(p->pColumns,pChanges)
- ){
- TriggerPrg *pPrg;
- pPrg = getRowTrigger(pParse, p, pTab, orconf);
- if( pPrg ){
- mask |= pPrg->aColmask[isNew];
- }
- }
- }
-
- return mask;
-}
-
-#endif /* !defined(SQLITE_OMIT_TRIGGER) */
-
-/************** End of trigger.c *********************************************/
-/************** Begin file update.c ******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains C code routines that are called by the parser
-** to handle UPDATE statements.
-*/
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Forward declaration */
-static void updateVirtualTable(
- Parse *pParse, /* The parsing context */
- SrcList *pSrc, /* The virtual table to be modified */
- Table *pTab, /* The virtual table */
- ExprList *pChanges, /* The columns to change in the UPDATE statement */
- Expr *pRowidExpr, /* Expression used to recompute the rowid */
- int *aXRef, /* Mapping from columns of pTab to entries in pChanges */
- Expr *pWhere, /* WHERE clause of the UPDATE statement */
- int onError /* ON CONFLICT strategy */
-);
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/*
-** The most recently coded instruction was an OP_Column to retrieve the
-** i-th column of table pTab. This routine sets the P4 parameter of the
-** OP_Column to the default value, if any.
-**
-** The default value of a column is specified by a DEFAULT clause in the
-** column definition. This was either supplied by the user when the table
-** was created, or added later to the table definition by an ALTER TABLE
-** command. If the latter, then the row-records in the table btree on disk
-** may not contain a value for the column and the default value, taken
-** from the P4 parameter of the OP_Column instruction, is returned instead.
-** If the former, then all row-records are guaranteed to include a value
-** for the column and the P4 value is not required.
-**
-** Column definitions created by an ALTER TABLE command may only have
-** literal default values specified: a number, null or a string. (If a more
-** complicated default expression value was provided, it is evaluated
-** when the ALTER TABLE is executed and one of the literal values written
-** into the sqlite_master table.)
-**
-** Therefore, the P4 parameter is only required if the default value for
-** the column is a literal number, string or null. The sqlite3ValueFromExpr()
-** function is capable of transforming these types of expressions into
-** sqlite3_value objects.
-**
-** If parameter iReg is not negative, code an OP_RealAffinity instruction
-** on register iReg. This is used when an equivalent integer value is
-** stored in place of an 8-byte floating point value in order to save
-** space.
-*/
-SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
- assert( pTab!=0 );
- if( !pTab->pSelect ){
- sqlite3_value *pValue;
- u8 enc = ENC(sqlite3VdbeDb(v));
- Column *pCol = &pTab->aCol[i];
- VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
- assert( i<pTab->nCol );
- sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc,
- pCol->affinity, &pValue);
- if( pValue ){
- sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
- }
-#ifndef SQLITE_OMIT_FLOATING_POINT
- if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
- sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
- }
-#endif
- }
-}
-
-/*
-** Process an UPDATE statement.
-**
-** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
-** \_______/ \________/ \______/ \________________/
-* onError pTabList pChanges pWhere
-*/
-SQLITE_PRIVATE void sqlite3Update(
- Parse *pParse, /* The parser context */
- SrcList *pTabList, /* The table in which we should change things */
- ExprList *pChanges, /* Things to be changed */
- Expr *pWhere, /* The WHERE clause. May be null */
- int onError /* How to handle constraint errors */
-){
- int i, j; /* Loop counters */
- Table *pTab; /* The table to be updated */
- int addr = 0; /* VDBE instruction address of the start of the loop */
- WhereInfo *pWInfo; /* Information about the WHERE clause */
- Vdbe *v; /* The virtual database engine */
- Index *pIdx; /* For looping over indices */
- int nIdx; /* Number of indices that need updating */
- int iCur; /* VDBE Cursor number of pTab */
- sqlite3 *db; /* The database structure */
- int *aRegIdx = 0; /* One register assigned to each index to be updated */
- int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
- ** an expression for the i-th column of the table.
- ** aXRef[i]==-1 if the i-th column is not changed. */
- int chngRowid; /* True if the record number is being changed */
- Expr *pRowidExpr = 0; /* Expression defining the new record number */
- int openAll = 0; /* True if all indices need to be opened */
- AuthContext sContext; /* The authorization context */
- NameContext sNC; /* The name-context to resolve expressions in */
- int iDb; /* Database containing the table being updated */
- int okOnePass; /* True for one-pass algorithm without the FIFO */
- int hasFK; /* True if foreign key processing is required */
-
-#ifndef SQLITE_OMIT_TRIGGER
- int isView; /* True when updating a view (INSTEAD OF trigger) */
- Trigger *pTrigger; /* List of triggers on pTab, if required */
- int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
-#endif
- int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */
-
- /* Register Allocations */
- int regRowCount = 0; /* A count of rows changed */
- int regOldRowid; /* The old rowid */
- int regNewRowid; /* The new rowid */
- int regNew; /* Content of the NEW.* table in triggers */
- int regOld = 0; /* Content of OLD.* table in triggers */
- int regRowSet = 0; /* Rowset of rows to be updated */
-
- memset(&sContext, 0, sizeof(sContext));
- db = pParse->db;
- if( pParse->nErr || db->mallocFailed ){
- goto update_cleanup;
- }
- assert( pTabList->nSrc==1 );
-
- /* Locate the table which we want to update.
- */
- pTab = sqlite3SrcListLookup(pParse, pTabList);
- if( pTab==0 ) goto update_cleanup;
- iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
-
- /* Figure out if we have any triggers and if the table being
- ** updated is a view.
- */
-#ifndef SQLITE_OMIT_TRIGGER
- pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask);
- isView = pTab->pSelect!=0;
- assert( pTrigger || tmask==0 );
-#else
-# define pTrigger 0
-# define isView 0
-# define tmask 0
-#endif
-#ifdef SQLITE_OMIT_VIEW
-# undef isView
-# define isView 0
-#endif
-
- if( sqlite3ViewGetColumnNames(pParse, pTab) ){
- goto update_cleanup;
- }
- if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
- goto update_cleanup;
- }
- aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol );
- if( aXRef==0 ) goto update_cleanup;
- for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
-
- /* Allocate a cursors for the main database table and for all indices.
- ** The index cursors might not be used, but if they are used they
- ** need to occur right after the database cursor. So go ahead and
- ** allocate enough space, just in case.
- */
- pTabList->a[0].iCursor = iCur = pParse->nTab++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- pParse->nTab++;
- }
-
- /* Initialize the name-context */
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pParse;
- sNC.pSrcList = pTabList;
-
- /* Resolve the column names in all the expressions of the
- ** of the UPDATE statement. Also find the column index
- ** for each column to be updated in the pChanges array. For each
- ** column to be updated, make sure we have authorization to change
- ** that column.
- */
- chngRowid = 0;
- for(i=0; i<pChanges->nExpr; i++){
- if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
- goto update_cleanup;
- }
- for(j=0; j<pTab->nCol; j++){
- if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
- if( j==pTab->iPKey ){
- chngRowid = 1;
- pRowidExpr = pChanges->a[i].pExpr;
- }
- aXRef[j] = i;
- break;
- }
- }
- if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pChanges->a[i].zName) ){
- chngRowid = 1;
- pRowidExpr = pChanges->a[i].pExpr;
- }else{
- sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
- pParse->checkSchema = 1;
- goto update_cleanup;
- }
- }
-#ifndef SQLITE_OMIT_AUTHORIZATION
- {
- int rc;
- rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
- pTab->aCol[j].zName, db->aDb[iDb].zName);
- if( rc==SQLITE_DENY ){
- goto update_cleanup;
- }else if( rc==SQLITE_IGNORE ){
- aXRef[j] = -1;
- }
- }
-#endif
- }
-
- hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngRowid);
-
- /* Allocate memory for the array aRegIdx[]. There is one entry in the
- ** array for each index associated with table being updated. Fill in
- ** the value with a register number for indices that are to be used
- ** and with zero for unused indices.
- */
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
- if( nIdx>0 ){
- aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
- if( aRegIdx==0 ) goto update_cleanup;
- }
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- int reg;
- if( hasFK || chngRowid ){
- reg = ++pParse->nMem;
- }else{
- reg = 0;
- for(i=0; i<pIdx->nColumn; i++){
- if( aXRef[pIdx->aiColumn[i]]>=0 ){
- reg = ++pParse->nMem;
- break;
- }
- }
- }
- aRegIdx[j] = reg;
- }
-
- /* Begin generating code. */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto update_cleanup;
- if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
- sqlite3BeginWriteOperation(pParse, 1, iDb);
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Virtual tables must be handled separately */
- if( IsVirtual(pTab) ){
- updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
- pWhere, onError);
- pWhere = 0;
- pTabList = 0;
- goto update_cleanup;
- }
-#endif
-
- /* Allocate required registers. */
- regRowSet = ++pParse->nMem;
- regOldRowid = regNewRowid = ++pParse->nMem;
- if( pTrigger || hasFK ){
- regOld = pParse->nMem + 1;
- pParse->nMem += pTab->nCol;
- }
- if( chngRowid || pTrigger || hasFK ){
- regNewRowid = ++pParse->nMem;
- }
- regNew = pParse->nMem + 1;
- pParse->nMem += pTab->nCol;
-
- /* Start the view context. */
- if( isView ){
- sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
- }
-
- /* If we are trying to update a view, realize that view into
- ** a ephemeral table.
- */
-#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
- if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
- }
-#endif
-
- /* Resolve the column names in all the expressions in the
- ** WHERE clause.
- */
- if( sqlite3ResolveExprNames(&sNC, pWhere) ){
- goto update_cleanup;
- }
-
- /* Begin the database scan
- */
- sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
- pWInfo = sqlite3WhereBegin(
- pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, 0
- );
- if( pWInfo==0 ) goto update_cleanup;
- okOnePass = pWInfo->okOnePass;
-
- /* Remember the rowid of every item to be updated.
- */
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid);
- if( !okOnePass ){
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
- }
-
- /* End the database scan loop.
- */
- sqlite3WhereEnd(pWInfo);
-
- /* Initialize the count of updated rows
- */
- if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
- regRowCount = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
- }
-
- if( !isView ){
- /*
- ** Open every index that needs updating. Note that if any
- ** index could potentially invoke a REPLACE conflict resolution
- ** action, then we need to open all indices because we might need
- ** to be deleting some records.
- */
- if( !okOnePass ) sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite);
- if( onError==OE_Replace ){
- openAll = 1;
- }else{
- openAll = 0;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->onError==OE_Replace ){
- openAll = 1;
- break;
- }
- }
- }
- for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- assert( aRegIdx );
- if( openAll || aRegIdx[i]>0 ){
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- assert( pParse->nTab>iCur+i+1 );
- }
- }
- }
-
- /* Top of the update loop */
- if( okOnePass ){
- int a1 = sqlite3VdbeAddOp1(v, OP_NotNull, regOldRowid);
- addr = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, a1);
- }else{
- addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldRowid);
- }
-
- /* Make cursor iCur point to the record that is being updated. If
- ** this record does not exist for some reason (deleted by a trigger,
- ** for example, then jump to the next iteration of the RowSet loop. */
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
-
- /* If the record number will change, set register regNewRowid to
- ** contain the new value. If the record number is not being modified,
- ** then regNewRowid is the same register as regOldRowid, which is
- ** already populated. */
- assert( chngRowid || pTrigger || hasFK || regOldRowid==regNewRowid );
- if( chngRowid ){
- sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
- }
-
- /* If there are triggers on this table, populate an array of registers
- ** with the required old.* column data. */
- if( hasFK || pTrigger ){
- u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0);
- oldmask |= sqlite3TriggerColmask(pParse,
- pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError
- );
- for(i=0; i<pTab->nCol; i++){
- if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<<i))) ){
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOld+i);
- }else{
- sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
- }
- }
- if( chngRowid==0 ){
- sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
- }
- }
-
- /* Populate the array of registers beginning at regNew with the new
- ** row data. This array is used to check constaints, create the new
- ** table and index records, and as the values for any new.* references
- ** made by triggers.
- **
- ** If there are one or more BEFORE triggers, then do not populate the
- ** registers associated with columns that are (a) not modified by
- ** this UPDATE statement and (b) not accessed by new.* references. The
- ** values for registers not modified by the UPDATE must be reloaded from
- ** the database after the BEFORE triggers are fired anyway (as the trigger
- ** may have modified them). So not loading those that are not going to
- ** be used eliminates some redundant opcodes.
- */
- newmask = sqlite3TriggerColmask(
- pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
- );
- sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);
- for(i=0; i<pTab->nCol; i++){
- if( i==pTab->iPKey ){
- /*sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);*/
- }else{
- j = aXRef[i];
- if( j>=0 ){
- sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
- }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<<i)) ){
- /* This branch loads the value of a column that will not be changed
- ** into a register. This is done if there are no BEFORE triggers, or
- ** if there are one or more BEFORE triggers that use this value via
- ** a new.* reference in a trigger program.
- */
- testcase( i==31 );
- testcase( i==32 );
- sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
- sqlite3ColumnDefault(v, pTab, i, regNew+i);
- }
- }
- }
-
- /* Fire any BEFORE UPDATE triggers. This happens before constraints are
- ** verified. One could argue that this is wrong.
- */
- if( tmask&TRIGGER_BEFORE ){
- sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
- sqlite3TableAffinityStr(v, pTab);
- sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_BEFORE, pTab, regOldRowid, onError, addr);
-
- /* The row-trigger may have deleted the row being updated. In this
- ** case, jump to the next row. No updates or AFTER triggers are
- ** required. This behaviour - what happens when the row being updated
- ** is deleted or renamed by a BEFORE trigger - is left undefined in the
- ** documentation.
- */
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
-
- /* If it did not delete it, the row-trigger may still have modified
- ** some of the columns of the row being updated. Load the values for
- ** all columns not modified by the update statement into their
- ** registers in case this has happened.
- */
- for(i=0; i<pTab->nCol; i++){
- if( aXRef[i]<0 && i!=pTab->iPKey ){
- sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
- sqlite3ColumnDefault(v, pTab, i, regNew+i);
- }
- }
- }
-
- if( !isView ){
- int j1; /* Address of jump instruction */
-
- /* Do constraint checks. */
- sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
- aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0);
-
- /* Do FK constraint checks. */
- if( hasFK ){
- sqlite3FkCheck(pParse, pTab, regOldRowid, 0);
- }
-
- /* Delete the index entries associated with the current record. */
- j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
- sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
-
- /* If changing the record number, delete the old record. */
- if( hasFK || chngRowid ){
- sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
- }
- sqlite3VdbeJumpHere(v, j1);
-
- if( hasFK ){
- sqlite3FkCheck(pParse, pTab, 0, regNewRowid);
- }
-
- /* Insert the new index entries and the new record. */
- sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0);
-
- /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
- ** handle rows (possibly in other tables) that refer via a foreign key
- ** to the row just updated. */
- if( hasFK ){
- sqlite3FkActions(pParse, pTab, pChanges, regOldRowid);
- }
- }
-
- /* Increment the row counter
- */
- if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){
- sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1);
- }
-
- sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_AFTER, pTab, regOldRowid, onError, addr);
-
- /* Repeat the above with the next record to be updated, until
- ** all record selected by the WHERE clause have been updated.
- */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
- sqlite3VdbeJumpHere(v, addr);
-
- /* Close all tables */
- for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- assert( aRegIdx );
- if( openAll || aRegIdx[i]>0 ){
- sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
- }
- }
- sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
-
- /* Update the sqlite_sequence table by storing the content of the
- ** maximum rowid counter values recorded while inserting into
- ** autoincrement tables.
- */
- if( pParse->nested==0 && pParse->pTriggerTab==0 ){
- sqlite3AutoincrementEnd(pParse);
- }
-
- /*
- ** Return the number of rows that were changed. If this routine is
- ** generating code because of a call to sqlite3NestedParse(), do not
- ** invoke the callback function.
- */
- if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){
- sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
- }
-
-update_cleanup:
- sqlite3AuthContextPop(&sContext);
- sqlite3DbFree(db, aRegIdx);
- sqlite3DbFree(db, aXRef);
- sqlite3SrcListDelete(db, pTabList);
- sqlite3ExprListDelete(db, pChanges);
- sqlite3ExprDelete(db, pWhere);
- return;
-}
-/* Make sure "isView" and other macros defined above are undefined. Otherwise
-** thely may interfere with compilation of other functions in this file
-** (or in another file, if this file becomes part of the amalgamation). */
-#ifdef isView
- #undef isView
-#endif
-#ifdef pTrigger
- #undef pTrigger
-#endif
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/*
-** Generate code for an UPDATE of a virtual table.
-**
-** The strategy is that we create an ephemerial table that contains
-** for each row to be changed:
-**
-** (A) The original rowid of that row.
-** (B) The revised rowid for the row. (note1)
-** (C) The content of every column in the row.
-**
-** Then we loop over this ephemeral table and for each row in
-** the ephermeral table call VUpdate.
-**
-** When finished, drop the ephemeral table.
-**
-** (note1) Actually, if we know in advance that (A) is always the same
-** as (B) we only store (A), then duplicate (A) when pulling
-** it out of the ephemeral table before calling VUpdate.
-*/
-static void updateVirtualTable(
- Parse *pParse, /* The parsing context */
- SrcList *pSrc, /* The virtual table to be modified */
- Table *pTab, /* The virtual table */
- ExprList *pChanges, /* The columns to change in the UPDATE statement */
- Expr *pRowid, /* Expression used to recompute the rowid */
- int *aXRef, /* Mapping from columns of pTab to entries in pChanges */
- Expr *pWhere, /* WHERE clause of the UPDATE statement */
- int onError /* ON CONFLICT strategy */
-){
- Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */
- ExprList *pEList = 0; /* The result set of the SELECT statement */
- Select *pSelect = 0; /* The SELECT statement */
- Expr *pExpr; /* Temporary expression */
- int ephemTab; /* Table holding the result of the SELECT */
- int i; /* Loop counter */
- int addr; /* Address of top of loop */
- int iReg; /* First register in set passed to OP_VUpdate */
- sqlite3 *db = pParse->db; /* Database connection */
- const char *pVTab = (const char*)sqlite3GetVTable(db, pTab);
- SelectDest dest;
-
- /* Construct the SELECT statement that will find the new values for
- ** all updated rows.
- */
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_"));
- if( pRowid ){
- pEList = sqlite3ExprListAppend(pParse, pEList,
- sqlite3ExprDup(db, pRowid, 0));
- }
- assert( pTab->iPKey<0 );
- for(i=0; i<pTab->nCol; i++){
- if( aXRef[i]>=0 ){
- pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0);
- }else{
- pExpr = sqlite3Expr(db, TK_ID, pTab->aCol[i].zName);
- }
- pEList = sqlite3ExprListAppend(pParse, pEList, pExpr);
- }
- pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
-
- /* Create the ephemeral table into which the update results will
- ** be stored.
- */
- assert( v );
- ephemTab = pParse->nTab++;
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
- sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
-
- /* fill the ephemeral table
- */
- sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
- sqlite3Select(pParse, pSelect, &dest);
-
- /* Generate code to scan the ephemeral table and call VUpdate. */
- iReg = ++pParse->nMem;
- pParse->nMem += pTab->nCol+1;
- addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
- sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg);
- sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
- for(i=0; i<pTab->nCol; i++){
- sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i);
- }
- sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
- sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
- sqlite3MayAbort(pParse);
- sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1);
- sqlite3VdbeJumpHere(v, addr);
- sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
-
- /* Cleanup */
- sqlite3SelectDelete(db, pSelect);
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/************** End of update.c **********************************************/
-/************** Begin file vacuum.c ******************************************/
-/*
-** 2003 April 6
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code used to implement the VACUUM command.
-**
-** Most of the code in this file may be omitted by defining the
-** SQLITE_OMIT_VACUUM macro.
-*/
-
-#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
-/*
-** Finalize a prepared statement. If there was an error, store the
-** text of the error message in *pzErrMsg. Return the result code.
-*/
-static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
- int rc;
- rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
- if( rc ){
- sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
- }
- return rc;
-}
-
-/*
-** Execute zSql on database db. Return an error code.
-*/
-static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
- sqlite3_stmt *pStmt;
- VVA_ONLY( int rc; )
- if( !zSql ){
- return SQLITE_NOMEM;
- }
- if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
- sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
- return sqlite3_errcode(db);
- }
- VVA_ONLY( rc = ) sqlite3_step(pStmt);
- assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) );
- return vacuumFinalize(db, pStmt, pzErrMsg);
-}
-
-/*
-** Execute zSql on database db. The statement returns exactly
-** one column. Execute this as SQL on the same database.
-*/
-static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
- sqlite3_stmt *pStmt;
- int rc;
-
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ) return rc;
-
- while( SQLITE_ROW==sqlite3_step(pStmt) ){
- rc = execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
- if( rc!=SQLITE_OK ){
- vacuumFinalize(db, pStmt, pzErrMsg);
- return rc;
- }
- }
-
- return vacuumFinalize(db, pStmt, pzErrMsg);
-}
-
-/*
-** The non-standard VACUUM command is used to clean up the database,
-** collapse free space, etc. It is modelled after the VACUUM command
-** in PostgreSQL.
-**
-** In version 1.0.x of SQLite, the VACUUM command would call
-** gdbm_reorganize() on all the database tables. But beginning
-** with 2.0.0, SQLite no longer uses GDBM so this command has
-** become a no-op.
-*/
-SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
- sqlite3VdbeUsesBtree(v, 0);
- }
- return;
-}
-
-/*
-** This routine implements the OP_Vacuum opcode of the VDBE.
-*/
-SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
- int rc = SQLITE_OK; /* Return code from service routines */
- Btree *pMain; /* The database being vacuumed */
- Btree *pTemp; /* The temporary database we vacuum into */
- char *zSql = 0; /* SQL statements */
- int saved_flags; /* Saved value of the db->flags */
- int saved_nChange; /* Saved value of db->nChange */
- int saved_nTotalChange; /* Saved value of db->nTotalChange */
- void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */
- Db *pDb = 0; /* Database to detach at end of vacuum */
- int isMemDb; /* True if vacuuming a :memory: database */
- int nRes; /* Bytes of reserved space at the end of each page */
- int nDb; /* Number of attached databases */
-
- if( !db->autoCommit ){
- sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
- return SQLITE_ERROR;
- }
- if( db->activeVdbeCnt>1 ){
- sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
- return SQLITE_ERROR;
- }
-
- /* Save the current value of the database flags so that it can be
- ** restored before returning. Then set the writable-schema flag, and
- ** disable CHECK and foreign key constraints. */
- saved_flags = db->flags;
- saved_nChange = db->nChange;
- saved_nTotalChange = db->nTotalChange;
- saved_xTrace = db->xTrace;
- db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
- db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
- db->xTrace = 0;
-
- pMain = db->aDb[0].pBt;
- isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
-
- /* Attach the temporary database as 'vacuum_db'. The synchronous pragma
- ** can be set to 'off' for this file, as it is not recovered if a crash
- ** occurs anyway. The integrity of the database is maintained by a
- ** (possibly synchronous) transaction opened on the main database before
- ** sqlite3BtreeCopyFile() is called.
- **
- ** An optimisation would be to use a non-journaled pager.
- ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
- ** that actually made the VACUUM run slower. Very little journalling
- ** actually occurs when doing a vacuum since the vacuum_db is initially
- ** empty. Only the journal header is written. Apparently it takes more
- ** time to parse and run the PRAGMA to turn journalling off than it does
- ** to write the journal header file.
- */
- nDb = db->nDb;
- if( sqlite3TempInMemory(db) ){
- zSql = "ATTACH ':memory:' AS vacuum_db;";
- }else{
- zSql = "ATTACH '' AS vacuum_db;";
- }
- rc = execSql(db, pzErrMsg, zSql);
- if( db->nDb>nDb ){
- pDb = &db->aDb[db->nDb-1];
- assert( strcmp(pDb->zName,"vacuum_db")==0 );
- }
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- pTemp = db->aDb[db->nDb-1].pBt;
-
- /* The call to execSql() to attach the temp database has left the file
- ** locked (as there was more than one active statement when the transaction
- ** to read the schema was concluded. Unlock it here so that this doesn't
- ** cause problems for the call to BtreeSetPageSize() below. */
- sqlite3BtreeCommit(pTemp);
-
- nRes = sqlite3BtreeGetReserve(pMain);
-
- /* A VACUUM cannot change the pagesize of an encrypted database. */
-#ifdef SQLITE_HAS_CODEC
- if( db->nextPagesize ){
- extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
- int nKey;
- char *zKey;
- sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
- if( nKey ) db->nextPagesize = 0;
- }
-#endif
-
- rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
- /* Begin a transaction and take an exclusive lock on the main database
- ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
- ** to ensure that we do not try to change the page-size on a WAL database.
- */
- rc = execSql(db, pzErrMsg, "BEGIN;");
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = sqlite3BtreeBeginTrans(pMain, 2);
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
- /* Do not attempt to change the page size for a WAL database */
- if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
- ==PAGER_JOURNALMODE_WAL ){
- db->nextPagesize = 0;
- }
-
- if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
- || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
- || NEVER(db->mallocFailed)
- ){
- rc = SQLITE_NOMEM;
- goto end_of_vacuum;
- }
-
-#ifndef SQLITE_OMIT_AUTOVACUUM
- sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac :
- sqlite3BtreeGetAutoVacuum(pMain));
-#endif
-
- /* Query the schema of the main database. Create a mirror schema
- ** in the temporary database.
- */
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
- " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
- " AND rootpage>0"
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
- " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
- " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
- /* Loop through the tables in the main database. For each, do
- ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
- ** the contents to the temporary database.
- */
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
- "|| ' SELECT * FROM main.' || quote(name) || ';'"
- "FROM main.sqlite_master "
- "WHERE type = 'table' AND name!='sqlite_sequence' "
- " AND rootpage>0"
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
- /* Copy over the sequence table
- */
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
- "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
- "|| ' SELECT * FROM main.' || quote(name) || ';' "
- "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
-
- /* Copy the triggers, views, and virtual tables from the main database
- ** over to the temporary database. None of these objects has any
- ** associated storage, so all we have to do is copy their entries
- ** from the SQLITE_MASTER table.
- */
- rc = execSql(db, pzErrMsg,
- "INSERT INTO vacuum_db.sqlite_master "
- " SELECT type, name, tbl_name, rootpage, sql"
- " FROM main.sqlite_master"
- " WHERE type='view' OR type='trigger'"
- " OR (type='table' AND rootpage=0)"
- );
- if( rc ) goto end_of_vacuum;
-
- /* At this point, there is a write transaction open on both the
- ** vacuum database and the main database. Assuming no error occurs,
- ** both transactions are closed by this block - the main database
- ** transaction by sqlite3BtreeCopyFile() and the other by an explicit
- ** call to sqlite3BtreeCommit().
- */
- {
- u32 meta;
- int i;
-
- /* This array determines which meta meta values are preserved in the
- ** vacuum. Even entries are the meta value number and odd entries
- ** are an increment to apply to the meta value after the vacuum.
- ** The increment is used to increase the schema cookie so that other
- ** connections to the same database will know to reread the schema.
- */
- static const unsigned char aCopy[] = {
- BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */
- BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */
- BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */
- BTREE_USER_VERSION, 0, /* Preserve the user version */
- };
-
- assert( 1==sqlite3BtreeIsInTrans(pTemp) );
- assert( 1==sqlite3BtreeIsInTrans(pMain) );
-
- /* Copy Btree meta values */
- for(i=0; i<ArraySize(aCopy); i+=2){
- /* GetMeta() and UpdateMeta() cannot fail in this context because
- ** we already have page 1 loaded into cache and marked dirty. */
- sqlite3BtreeGetMeta(pMain, aCopy[i], &meta);
- rc = sqlite3BtreeUpdateMeta(pTemp, aCopy[i], meta+aCopy[i+1]);
- if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum;
- }
-
- rc = sqlite3BtreeCopyFile(pMain, pTemp);
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = sqlite3BtreeCommit(pTemp);
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-#ifndef SQLITE_OMIT_AUTOVACUUM
- sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp));
-#endif
- }
-
- assert( rc==SQLITE_OK );
- rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1);
-
-end_of_vacuum:
- /* Restore the original value of db->flags */
- db->flags = saved_flags;
- db->nChange = saved_nChange;
- db->nTotalChange = saved_nTotalChange;
- db->xTrace = saved_xTrace;
- sqlite3BtreeSetPageSize(pMain, -1, -1, 1);
-
- /* Currently there is an SQL level transaction open on the vacuum
- ** database. No locks are held on any other files (since the main file
- ** was committed at the btree level). So it safe to end the transaction
- ** by manually setting the autoCommit flag to true and detaching the
- ** vacuum database. The vacuum_db journal file is deleted when the pager
- ** is closed by the DETACH.
- */
- db->autoCommit = 1;
-
- if( pDb ){
- sqlite3BtreeClose(pDb->pBt);
- pDb->pBt = 0;
- pDb->pSchema = 0;
- }
-
- /* This both clears the schemas and reduces the size of the db->aDb[]
- ** array. */
- sqlite3ResetAllSchemasOfConnection(db);
-
- return rc;
-}
-
-#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */
-
-/************** End of vacuum.c **********************************************/
-/************** Begin file vtab.c ********************************************/
-/*
-** 2006 June 10
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code used to help implement virtual tables.
-*/
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-
-/*
-** Before a virtual table xCreate() or xConnect() method is invoked, the
-** sqlite3.pVtabCtx member variable is set to point to an instance of
-** this struct allocated on the stack. It is used by the implementation of
-** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
-** are invoked only from within xCreate and xConnect methods.
-*/
-struct VtabCtx {
- VTable *pVTable; /* The virtual table being constructed */
- Table *pTab; /* The Table object to which the virtual table belongs */
-};
-
-/*
-** The actual function that does the work of creating a new module.
-** This function implements the sqlite3_create_module() and
-** sqlite3_create_module_v2() interfaces.
-*/
-static int createModule(
- sqlite3 *db, /* Database in which module is registered */
- const char *zName, /* Name assigned to this module */
- const sqlite3_module *pModule, /* The definition of the module */
- void *pAux, /* Context pointer for xCreate/xConnect */
- void (*xDestroy)(void *) /* Module destructor function */
-){
- int rc = SQLITE_OK;
- int nName;
-
- sqlite3_mutex_enter(db->mutex);
- nName = sqlite3Strlen30(zName);
- if( sqlite3HashFind(&db->aModule, zName, nName) ){
- rc = SQLITE_MISUSE_BKPT;
- }else{
- Module *pMod;
- pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
- if( pMod ){
- Module *pDel;
- char *zCopy = (char *)(&pMod[1]);
- memcpy(zCopy, zName, nName+1);
- pMod->zName = zCopy;
- pMod->pModule = pModule;
- pMod->pAux = pAux;
- pMod->xDestroy = xDestroy;
- pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,nName,(void*)pMod);
- assert( pDel==0 || pDel==pMod );
- if( pDel ){
- db->mallocFailed = 1;
- sqlite3DbFree(db, pDel);
- }
- }
- }
- rc = sqlite3ApiExit(db, rc);
- if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
-
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-
-/*
-** External API function used to create a new virtual-table module.
-*/
-SQLITE_API int sqlite3_create_module(
- sqlite3 *db, /* Database in which module is registered */
- const char *zName, /* Name assigned to this module */
- const sqlite3_module *pModule, /* The definition of the module */
- void *pAux /* Context pointer for xCreate/xConnect */
-){
- return createModule(db, zName, pModule, pAux, 0);
-}
-
-/*
-** External API function used to create a new virtual-table module.
-*/
-SQLITE_API int sqlite3_create_module_v2(
- sqlite3 *db, /* Database in which module is registered */
- const char *zName, /* Name assigned to this module */
- const sqlite3_module *pModule, /* The definition of the module */
- void *pAux, /* Context pointer for xCreate/xConnect */
- void (*xDestroy)(void *) /* Module destructor function */
-){
- return createModule(db, zName, pModule, pAux, xDestroy);
-}
-
-/*
-** Lock the virtual table so that it cannot be disconnected.
-** Locks nest. Every lock should have a corresponding unlock.
-** If an unlock is omitted, resources leaks will occur.
-**
-** If a disconnect is attempted while a virtual table is locked,
-** the disconnect is deferred until all locks have been removed.
-*/
-SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){
- pVTab->nRef++;
-}
-
-
-/*
-** pTab is a pointer to a Table structure representing a virtual-table.
-** Return a pointer to the VTable object used by connection db to access
-** this virtual-table, if one has been created, or NULL otherwise.
-*/
-SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){
- VTable *pVtab;
- assert( IsVirtual(pTab) );
- for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext);
- return pVtab;
-}
-
-/*
-** Decrement the ref-count on a virtual table object. When the ref-count
-** reaches zero, call the xDisconnect() method to delete the object.
-*/
-SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){
- sqlite3 *db = pVTab->db;
-
- assert( db );
- assert( pVTab->nRef>0 );
- assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE );
-
- pVTab->nRef--;
- if( pVTab->nRef==0 ){
- sqlite3_vtab *p = pVTab->pVtab;
- if( p ){
- p->pModule->xDisconnect(p);
- }
- sqlite3DbFree(db, pVTab);
- }
-}
-
-/*
-** Table p is a virtual table. This function moves all elements in the
-** p->pVTable list to the sqlite3.pDisconnect lists of their associated
-** database connections to be disconnected at the next opportunity.
-** Except, if argument db is not NULL, then the entry associated with
-** connection db is left in the p->pVTable list.
-*/
-static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
- VTable *pRet = 0;
- VTable *pVTable = p->pVTable;
- p->pVTable = 0;
-
- /* Assert that the mutex (if any) associated with the BtShared database
- ** that contains table p is held by the caller. See header comments
- ** above function sqlite3VtabUnlockList() for an explanation of why
- ** this makes it safe to access the sqlite3.pDisconnect list of any
- ** database connection that may have an entry in the p->pVTable list.
- */
- assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
-
- while( pVTable ){
- sqlite3 *db2 = pVTable->db;
- VTable *pNext = pVTable->pNext;
- assert( db2 );
- if( db2==db ){
- pRet = pVTable;
- p->pVTable = pRet;
- pRet->pNext = 0;
- }else{
- pVTable->pNext = db2->pDisconnect;
- db2->pDisconnect = pVTable;
- }
- pVTable = pNext;
- }
-
- assert( !db || pRet );
- return pRet;
-}
-
-/*
-** Table *p is a virtual table. This function removes the VTable object
-** for table *p associated with database connection db from the linked
-** list in p->pVTab. It also decrements the VTable ref count. This is
-** used when closing database connection db to free all of its VTable
-** objects without disturbing the rest of the Schema object (which may
-** be being used by other shared-cache connections).
-*/
-SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){
- VTable **ppVTab;
-
- assert( IsVirtual(p) );
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- assert( sqlite3_mutex_held(db->mutex) );
-
- for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){
- if( (*ppVTab)->db==db ){
- VTable *pVTab = *ppVTab;
- *ppVTab = pVTab->pNext;
- sqlite3VtabUnlock(pVTab);
- break;
- }
- }
-}
-
-
-/*
-** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
-**
-** This function may only be called when the mutexes associated with all
-** shared b-tree databases opened using connection db are held by the
-** caller. This is done to protect the sqlite3.pDisconnect list. The
-** sqlite3.pDisconnect list is accessed only as follows:
-**
-** 1) By this function. In this case, all BtShared mutexes and the mutex
-** associated with the database handle itself must be held.
-**
-** 2) By function vtabDisconnectAll(), when it adds a VTable entry to
-** the sqlite3.pDisconnect list. In this case either the BtShared mutex
-** associated with the database the virtual table is stored in is held
-** or, if the virtual table is stored in a non-sharable database, then
-** the database handle mutex is held.
-**
-** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously
-** by multiple threads. It is thread-safe.
-*/
-SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){
- VTable *p = db->pDisconnect;
- db->pDisconnect = 0;
-
- assert( sqlite3BtreeHoldsAllMutexes(db) );
- assert( sqlite3_mutex_held(db->mutex) );
-
- if( p ){
- sqlite3ExpirePreparedStatements(db);
- do {
- VTable *pNext = p->pNext;
- sqlite3VtabUnlock(p);
- p = pNext;
- }while( p );
- }
-}
-
-/*
-** Clear any and all virtual-table information from the Table record.
-** This routine is called, for example, just before deleting the Table
-** record.
-**
-** Since it is a virtual-table, the Table structure contains a pointer
-** to the head of a linked list of VTable structures. Each VTable
-** structure is associated with a single sqlite3* user of the schema.
-** The reference count of the VTable structure associated with database
-** connection db is decremented immediately (which may lead to the
-** structure being xDisconnected and free). Any other VTable structures
-** in the list are moved to the sqlite3.pDisconnect list of the associated
-** database connection.
-*/
-SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
- if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
- if( p->azModuleArg ){
- int i;
- for(i=0; i<p->nModuleArg; i++){
- if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]);
- }
- sqlite3DbFree(db, p->azModuleArg);
- }
-}
-
-/*
-** Add a new module argument to pTable->azModuleArg[].
-** The string is not copied - the pointer is stored. The
-** string will be freed automatically when the table is
-** deleted.
-*/
-static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
- int i = pTable->nModuleArg++;
- int nBytes = sizeof(char *)*(1+pTable->nModuleArg);
- char **azModuleArg;
- azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
- if( azModuleArg==0 ){
- int j;
- for(j=0; j<i; j++){
- sqlite3DbFree(db, pTable->azModuleArg[j]);
- }
- sqlite3DbFree(db, zArg);
- sqlite3DbFree(db, pTable->azModuleArg);
- pTable->nModuleArg = 0;
- }else{
- azModuleArg[i] = zArg;
- azModuleArg[i+1] = 0;
- }
- pTable->azModuleArg = azModuleArg;
-}
-
-/*
-** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE
-** statement. The module name has been parsed, but the optional list
-** of parameters that follow the module name are still pending.
-*/
-SQLITE_PRIVATE void sqlite3VtabBeginParse(
- Parse *pParse, /* Parsing context */
- Token *pName1, /* Name of new table, or database name */
- Token *pName2, /* Name of new table or NULL */
- Token *pModuleName, /* Name of the module for the virtual table */
- int ifNotExists /* No error if the table already exists */
-){
- int iDb; /* The database the table is being created in */
- Table *pTable; /* The new virtual table */
- sqlite3 *db; /* Database connection */
-
- sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists);
- pTable = pParse->pNewTable;
- if( pTable==0 ) return;
- assert( 0==pTable->pIndex );
-
- db = pParse->db;
- iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
- assert( iDb>=0 );
-
- pTable->tabFlags |= TF_Virtual;
- pTable->nModuleArg = 0;
- addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
- addModuleArgument(db, pTable, 0);
- addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
- pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
-
-#ifndef SQLITE_OMIT_AUTHORIZATION
- /* Creating a virtual table invokes the authorization callback twice.
- ** The first invocation, to obtain permission to INSERT a row into the
- ** sqlite_master table, has already been made by sqlite3StartTable().
- ** The second call, to obtain permission to create the table, is made now.
- */
- if( pTable->azModuleArg ){
- sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
- pTable->azModuleArg[0], pParse->db->aDb[iDb].zName);
- }
-#endif
-}
-
-/*
-** This routine takes the module argument that has been accumulating
-** in pParse->zArg[] and appends it to the list of arguments on the
-** virtual table currently under construction in pParse->pTable.
-*/
-static void addArgumentToVtab(Parse *pParse){
- if( pParse->sArg.z && pParse->pNewTable ){
- const char *z = (const char*)pParse->sArg.z;
- int n = pParse->sArg.n;
- sqlite3 *db = pParse->db;
- addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
- }
-}
-
-/*
-** The parser calls this routine after the CREATE VIRTUAL TABLE statement
-** has been completely parsed.
-*/
-SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
- Table *pTab = pParse->pNewTable; /* The table being constructed */
- sqlite3 *db = pParse->db; /* The database connection */
-
- if( pTab==0 ) return;
- addArgumentToVtab(pParse);
- pParse->sArg.z = 0;
- if( pTab->nModuleArg<1 ) return;
-
- /* If the CREATE VIRTUAL TABLE statement is being entered for the
- ** first time (in other words if the virtual table is actually being
- ** created now instead of just being read out of sqlite_master) then
- ** do additional initialization work and store the statement text
- ** in the sqlite_master table.
- */
- if( !db->init.busy ){
- char *zStmt;
- char *zWhere;
- int iDb;
- Vdbe *v;
-
- /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
- if( pEnd ){
- pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n;
- }
- zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
-
- /* A slot for the record has already been allocated in the
- ** SQLITE_MASTER table. We just need to update that slot with all
- ** the information we've collected.
- **
- ** The VM register number pParse->regRowid holds the rowid of an
- ** entry in the sqlite_master table tht was created for this vtab
- ** by sqlite3StartTable().
- */
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- sqlite3NestedParse(pParse,
- "UPDATE %Q.%s "
- "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
- "WHERE rowid=#%d",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
- pTab->zName,
- pTab->zName,
- zStmt,
- pParse->regRowid
- );
- sqlite3DbFree(db, zStmt);
- v = sqlite3GetVdbe(pParse);
- sqlite3ChangeCookie(pParse, iDb);
-
- sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
- zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
- sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
- sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0,
- pTab->zName, sqlite3Strlen30(pTab->zName) + 1);
- }
-
- /* If we are rereading the sqlite_master table create the in-memory
- ** record of the table. The xConnect() method is not called until
- ** the first time the virtual table is used in an SQL statement. This
- ** allows a schema that contains virtual tables to be loaded before
- ** the required virtual table implementations are registered. */
- else {
- Table *pOld;
- Schema *pSchema = pTab->pSchema;
- const char *zName = pTab->zName;
- int nName = sqlite3Strlen30(zName);
- assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
- pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab);
- if( pOld ){
- db->mallocFailed = 1;
- assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
- return;
- }
- pParse->pNewTable = 0;
- }
-}
-
-/*
-** The parser calls this routine when it sees the first token
-** of an argument to the module name in a CREATE VIRTUAL TABLE statement.
-*/
-SQLITE_PRIVATE void sqlite3VtabArgInit(Parse *pParse){
- addArgumentToVtab(pParse);
- pParse->sArg.z = 0;
- pParse->sArg.n = 0;
-}
-
-/*
-** The parser calls this routine for each token after the first token
-** in an argument to the module name in a CREATE VIRTUAL TABLE statement.
-*/
-SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){
- Token *pArg = &pParse->sArg;
- if( pArg->z==0 ){
- pArg->z = p->z;
- pArg->n = p->n;
- }else{
- assert(pArg->z < p->z);
- pArg->n = (int)(&p->z[p->n] - pArg->z);
- }
-}
-
-/*
-** Invoke a virtual table constructor (either xCreate or xConnect). The
-** pointer to the function to invoke is passed as the fourth parameter
-** to this procedure.
-*/
-static int vtabCallConstructor(
- sqlite3 *db,
- Table *pTab,
- Module *pMod,
- int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
- char **pzErr
-){
- VtabCtx sCtx, *pPriorCtx;
- VTable *pVTable;
- int rc;
- const char *const*azArg = (const char *const*)pTab->azModuleArg;
- int nArg = pTab->nModuleArg;
- char *zErr = 0;
- char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
- int iDb;
-
- if( !zModuleName ){
- return SQLITE_NOMEM;
- }
-
- pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
- if( !pVTable ){
- sqlite3DbFree(db, zModuleName);
- return SQLITE_NOMEM;
- }
- pVTable->db = db;
- pVTable->pMod = pMod;
-
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- pTab->azModuleArg[1] = db->aDb[iDb].zName;
-
- /* Invoke the virtual table constructor */
- assert( &db->pVtabCtx );
- assert( xConstruct );
- sCtx.pTab = pTab;
- sCtx.pVTable = pVTable;
- pPriorCtx = db->pVtabCtx;
- db->pVtabCtx = &sCtx;
- rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
- db->pVtabCtx = pPriorCtx;
- if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
-
- if( SQLITE_OK!=rc ){
- if( zErr==0 ){
- *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
- }else {
- *pzErr = sqlite3MPrintf(db, "%s", zErr);
- sqlite3_free(zErr);
- }
- sqlite3DbFree(db, pVTable);
- }else if( ALWAYS(pVTable->pVtab) ){
- /* Justification of ALWAYS(): A correct vtab constructor must allocate
- ** the sqlite3_vtab object if successful. */
- pVTable->pVtab->pModule = pMod->pModule;
- pVTable->nRef = 1;
- if( sCtx.pTab ){
- const char *zFormat = "vtable constructor did not declare schema: %s";
- *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
- sqlite3VtabUnlock(pVTable);
- rc = SQLITE_ERROR;
- }else{
- int iCol;
- /* If everything went according to plan, link the new VTable structure
- ** into the linked list headed by pTab->pVTable. Then loop through the
- ** columns of the table to see if any of them contain the token "hidden".
- ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
- ** the type string. */
- pVTable->pNext = pTab->pVTable;
- pTab->pVTable = pVTable;
-
- for(iCol=0; iCol<pTab->nCol; iCol++){
- char *zType = pTab->aCol[iCol].zType;
- int nType;
- int i = 0;
- if( !zType ) continue;
- nType = sqlite3Strlen30(zType);
- if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
- for(i=0; i<nType; i++){
- if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))
- && (zType[i+7]=='\0' || zType[i+7]==' ')
- ){
- i++;
- break;
- }
- }
- }
- if( i<nType ){
- int j;
- int nDel = 6 + (zType[i+6] ? 1 : 0);
- for(j=i; (j+nDel)<=nType; j++){
- zType[j] = zType[j+nDel];
- }
- if( zType[i]=='\0' && i>0 ){
- assert(zType[i-1]==' ');
- zType[i-1] = '\0';
- }
- pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
- }
- }
- }
- }
-
- sqlite3DbFree(db, zModuleName);
- return rc;
-}
-
-/*
-** This function is invoked by the parser to call the xConnect() method
-** of the virtual table pTab. If an error occurs, an error code is returned
-** and an error left in pParse.
-**
-** This call is a no-op if table pTab is not a virtual table.
-*/
-SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
- sqlite3 *db = pParse->db;
- const char *zMod;
- Module *pMod;
- int rc;
-
- assert( pTab );
- if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
- return SQLITE_OK;
- }
-
- /* Locate the required virtual table module */
- zMod = pTab->azModuleArg[0];
- pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
-
- if( !pMod ){
- const char *zModule = pTab->azModuleArg[0];
- sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
- rc = SQLITE_ERROR;
- }else{
- char *zErr = 0;
- rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
- if( rc!=SQLITE_OK ){
- sqlite3ErrorMsg(pParse, "%s", zErr);
- }
- sqlite3DbFree(db, zErr);
- }
-
- return rc;
-}
-/*
-** Grow the db->aVTrans[] array so that there is room for at least one
-** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise.
-*/
-static int growVTrans(sqlite3 *db){
- const int ARRAY_INCR = 5;
-
- /* Grow the sqlite3.aVTrans array if required */
- if( (db->nVTrans%ARRAY_INCR)==0 ){
- VTable **aVTrans;
- int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
- aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
- if( !aVTrans ){
- return SQLITE_NOMEM;
- }
- memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
- db->aVTrans = aVTrans;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should
-** have already been reserved using growVTrans().
-*/
-static void addToVTrans(sqlite3 *db, VTable *pVTab){
- /* Add pVtab to the end of sqlite3.aVTrans */
- db->aVTrans[db->nVTrans++] = pVTab;
- sqlite3VtabLock(pVTab);
-}
-
-/*
-** This function is invoked by the vdbe to call the xCreate method
-** of the virtual table named zTab in database iDb.
-**
-** If an error occurs, *pzErr is set to point an an English language
-** description of the error and an SQLITE_XXX error code is returned.
-** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
-*/
-SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
- int rc = SQLITE_OK;
- Table *pTab;
- Module *pMod;
- const char *zMod;
-
- pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
- assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
-
- /* Locate the required virtual table module */
- zMod = pTab->azModuleArg[0];
- pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
-
- /* If the module has been registered and includes a Create method,
- ** invoke it now. If the module has not been registered, return an
- ** error. Otherwise, do nothing.
- */
- if( !pMod ){
- *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod);
- rc = SQLITE_ERROR;
- }else{
- rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
- }
-
- /* Justification of ALWAYS(): The xConstructor method is required to
- ** create a valid sqlite3_vtab if it returns SQLITE_OK. */
- if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){
- rc = growVTrans(db);
- if( rc==SQLITE_OK ){
- addToVTrans(db, sqlite3GetVTable(db, pTab));
- }
- }
-
- return rc;
-}
-
-/*
-** This function is used to set the schema of a virtual table. It is only
-** valid to call this function from within the xCreate() or xConnect() of a
-** virtual table module.
-*/
-SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
- Parse *pParse;
-
- int rc = SQLITE_OK;
- Table *pTab;
- char *zErr = 0;
-
- sqlite3_mutex_enter(db->mutex);
- if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
- sqlite3Error(db, SQLITE_MISUSE, 0);
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_MISUSE_BKPT;
- }
- assert( (pTab->tabFlags & TF_Virtual)!=0 );
-
- pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
- if( pParse==0 ){
- rc = SQLITE_NOMEM;
- }else{
- pParse->declareVtab = 1;
- pParse->db = db;
- pParse->nQueryLoop = 1;
-
- if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr)
- && pParse->pNewTable
- && !db->mallocFailed
- && !pParse->pNewTable->pSelect
- && (pParse->pNewTable->tabFlags & TF_Virtual)==0
- ){
- if( !pTab->aCol ){
- pTab->aCol = pParse->pNewTable->aCol;
- pTab->nCol = pParse->pNewTable->nCol;
- pParse->pNewTable->nCol = 0;
- pParse->pNewTable->aCol = 0;
- }
- db->pVtabCtx->pTab = 0;
- }else{
- sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
- sqlite3DbFree(db, zErr);
- rc = SQLITE_ERROR;
- }
- pParse->declareVtab = 0;
-
- if( pParse->pVdbe ){
- sqlite3VdbeFinalize(pParse->pVdbe);
- }
- sqlite3DeleteTable(db, pParse->pNewTable);
- sqlite3StackFree(db, pParse);
- }
-
- assert( (rc&0xff)==rc );
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** This function is invoked by the vdbe to call the xDestroy method
-** of the virtual table named zTab in database iDb. This occurs
-** when a DROP TABLE is mentioned.
-**
-** This call is a no-op if zTab is not a virtual table.
-*/
-SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
- int rc = SQLITE_OK;
- Table *pTab;
-
- pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
- if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
- VTable *p = vtabDisconnectAll(db, pTab);
-
- assert( rc==SQLITE_OK );
- rc = p->pMod->pModule->xDestroy(p->pVtab);
-
- /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
- if( rc==SQLITE_OK ){
- assert( pTab->pVTable==p && p->pNext==0 );
- p->pVtab = 0;
- pTab->pVTable = 0;
- sqlite3VtabUnlock(p);
- }
- }
-
- return rc;
-}
-
-/*
-** This function invokes either the xRollback or xCommit method
-** of each of the virtual tables in the sqlite3.aVTrans array. The method
-** called is identified by the second argument, "offset", which is
-** the offset of the method to call in the sqlite3_module structure.
-**
-** The array is cleared after invoking the callbacks.
-*/
-static void callFinaliser(sqlite3 *db, int offset){
- int i;
- if( db->aVTrans ){
- for(i=0; i<db->nVTrans; i++){
- VTable *pVTab = db->aVTrans[i];
- sqlite3_vtab *p = pVTab->pVtab;
- if( p ){
- int (*x)(sqlite3_vtab *);
- x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset);
- if( x ) x(p);
- }
- pVTab->iSavepoint = 0;
- sqlite3VtabUnlock(pVTab);
- }
- sqlite3DbFree(db, db->aVTrans);
- db->nVTrans = 0;
- db->aVTrans = 0;
- }
-}
-
-/*
-** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans
-** array. Return the error code for the first error that occurs, or
-** SQLITE_OK if all xSync operations are successful.
-**
-** Set *pzErrmsg to point to a buffer that should be released using
-** sqlite3DbFree() containing an error message, if one is available.
-*/
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
- int i;
- int rc = SQLITE_OK;
- VTable **aVTrans = db->aVTrans;
-
- db->aVTrans = 0;
- for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
- int (*x)(sqlite3_vtab *);
- sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
- if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
- rc = x(pVtab);
- sqlite3DbFree(db, *pzErrmsg);
- *pzErrmsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
- sqlite3_free(pVtab->zErrMsg);
- }
- }
- db->aVTrans = aVTrans;
- return rc;
-}
-
-/*
-** Invoke the xRollback method of all virtual tables in the
-** sqlite3.aVTrans array. Then clear the array itself.
-*/
-SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){
- callFinaliser(db, offsetof(sqlite3_module,xRollback));
- return SQLITE_OK;
-}
-
-/*
-** Invoke the xCommit method of all virtual tables in the
-** sqlite3.aVTrans array. Then clear the array itself.
-*/
-SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){
- callFinaliser(db, offsetof(sqlite3_module,xCommit));
- return SQLITE_OK;
-}
-
-/*
-** If the virtual table pVtab supports the transaction interface
-** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is
-** not currently open, invoke the xBegin method now.
-**
-** If the xBegin call is successful, place the sqlite3_vtab pointer
-** in the sqlite3.aVTrans array.
-*/
-SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){
- int rc = SQLITE_OK;
- const sqlite3_module *pModule;
-
- /* Special case: If db->aVTrans is NULL and db->nVTrans is greater
- ** than zero, then this function is being called from within a
- ** virtual module xSync() callback. It is illegal to write to
- ** virtual module tables in this case, so return SQLITE_LOCKED.
- */
- if( sqlite3VtabInSync(db) ){
- return SQLITE_LOCKED;
- }
- if( !pVTab ){
- return SQLITE_OK;
- }
- pModule = pVTab->pVtab->pModule;
-
- if( pModule->xBegin ){
- int i;
-
- /* If pVtab is already in the aVTrans array, return early */
- for(i=0; i<db->nVTrans; i++){
- if( db->aVTrans[i]==pVTab ){
- return SQLITE_OK;
- }
- }
-
- /* Invoke the xBegin method. If successful, add the vtab to the
- ** sqlite3.aVTrans[] array. */
- rc = growVTrans(db);
- if( rc==SQLITE_OK ){
- rc = pModule->xBegin(pVTab->pVtab);
- if( rc==SQLITE_OK ){
- addToVTrans(db, pVTab);
- }
- }
- }
- return rc;
-}
-
-/*
-** Invoke either the xSavepoint, xRollbackTo or xRelease method of all
-** virtual tables that currently have an open transaction. Pass iSavepoint
-** as the second argument to the virtual table method invoked.
-**
-** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is
-** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is
-** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with
-** an open transaction is invoked.
-**
-** If any virtual table method returns an error code other than SQLITE_OK,
-** processing is abandoned and the error returned to the caller of this
-** function immediately. If all calls to virtual table methods are successful,
-** SQLITE_OK is returned.
-*/
-SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
- int rc = SQLITE_OK;
-
- assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
- assert( iSavepoint>=0 );
- if( db->aVTrans ){
- int i;
- for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
- VTable *pVTab = db->aVTrans[i];
- const sqlite3_module *pMod = pVTab->pMod->pModule;
- if( pVTab->pVtab && pMod->iVersion>=2 ){
- int (*xMethod)(sqlite3_vtab *, int);
- switch( op ){
- case SAVEPOINT_BEGIN:
- xMethod = pMod->xSavepoint;
- pVTab->iSavepoint = iSavepoint+1;
- break;
- case SAVEPOINT_ROLLBACK:
- xMethod = pMod->xRollbackTo;
- break;
- default:
- xMethod = pMod->xRelease;
- break;
- }
- if( xMethod && pVTab->iSavepoint>iSavepoint ){
- rc = xMethod(pVTab->pVtab, iSavepoint);
- }
- }
- }
- }
- return rc;
-}
-
-/*
-** The first parameter (pDef) is a function implementation. The
-** second parameter (pExpr) is the first argument to this function.
-** If pExpr is a column in a virtual table, then let the virtual
-** table implementation have an opportunity to overload the function.
-**
-** This routine is used to allow virtual table implementations to
-** overload MATCH, LIKE, GLOB, and REGEXP operators.
-**
-** Return either the pDef argument (indicating no change) or a
-** new FuncDef structure that is marked as ephemeral using the
-** SQLITE_FUNC_EPHEM flag.
-*/
-SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
- sqlite3 *db, /* Database connection for reporting malloc problems */
- FuncDef *pDef, /* Function to possibly overload */
- int nArg, /* Number of arguments to the function */
- Expr *pExpr /* First argument to the function */
-){
- Table *pTab;
- sqlite3_vtab *pVtab;
- sqlite3_module *pMod;
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**) = 0;
- void *pArg = 0;
- FuncDef *pNew;
- int rc = 0;
- char *zLowerName;
- unsigned char *z;
-
-
- /* Check to see the left operand is a column in a virtual table */
- if( NEVER(pExpr==0) ) return pDef;
- if( pExpr->op!=TK_COLUMN ) return pDef;
- pTab = pExpr->pTab;
- if( NEVER(pTab==0) ) return pDef;
- if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
- pVtab = sqlite3GetVTable(db, pTab)->pVtab;
- assert( pVtab!=0 );
- assert( pVtab->pModule!=0 );
- pMod = (sqlite3_module *)pVtab->pModule;
- if( pMod->xFindFunction==0 ) return pDef;
-
- /* Call the xFindFunction method on the virtual table implementation
- ** to see if the implementation wants to overload this function
- */
- zLowerName = sqlite3DbStrDup(db, pDef->zName);
- if( zLowerName ){
- for(z=(unsigned char*)zLowerName; *z; z++){
- *z = sqlite3UpperToLower[*z];
- }
- rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
- sqlite3DbFree(db, zLowerName);
- }
- if( rc==0 ){
- return pDef;
- }
-
- /* Create a new ephemeral function definition for the overloaded
- ** function */
- pNew = sqlite3DbMallocZero(db, sizeof(*pNew)
- + sqlite3Strlen30(pDef->zName) + 1);
- if( pNew==0 ){
- return pDef;
- }
- *pNew = *pDef;
- pNew->zName = (char *)&pNew[1];
- memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
- pNew->xFunc = xFunc;
- pNew->pUserData = pArg;
- pNew->flags |= SQLITE_FUNC_EPHEM;
- return pNew;
-}
-
-/*
-** Make sure virtual table pTab is contained in the pParse->apVirtualLock[]
-** array so that an OP_VBegin will get generated for it. Add pTab to the
-** array if it is missing. If pTab is already in the array, this routine
-** is a no-op.
-*/
-SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
- Parse *pToplevel = sqlite3ParseToplevel(pParse);
- int i, n;
- Table **apVtabLock;
-
- assert( IsVirtual(pTab) );
- for(i=0; i<pToplevel->nVtabLock; i++){
- if( pTab==pToplevel->apVtabLock[i] ) return;
- }
- n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
- apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
- if( apVtabLock ){
- pToplevel->apVtabLock = apVtabLock;
- pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
- }else{
- pToplevel->db->mallocFailed = 1;
- }
-}
-
-/*
-** Return the ON CONFLICT resolution mode in effect for the virtual
-** table update operation currently in progress.
-**
-** The results of this routine are undefined unless it is called from
-** within an xUpdate method.
-*/
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
- static const unsigned char aMap[] = {
- SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE
- };
- assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
- assert( OE_Ignore==4 && OE_Replace==5 );
- assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
- return (int)aMap[db->vtabOnConflict-1];
-}
-
-/*
-** Call from within the xCreate() or xConnect() methods to provide
-** the SQLite core with additional information about the behavior
-** of the virtual table being implemented.
-*/
-SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
- va_list ap;
- int rc = SQLITE_OK;
-
- sqlite3_mutex_enter(db->mutex);
-
- va_start(ap, op);
- switch( op ){
- case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
- VtabCtx *p = db->pVtabCtx;
- if( !p ){
- rc = SQLITE_MISUSE_BKPT;
- }else{
- assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 );
- p->pVTable->bConstraint = (u8)va_arg(ap, int);
- }
- break;
- }
- default:
- rc = SQLITE_MISUSE_BKPT;
- break;
- }
- va_end(ap);
-
- if( rc!=SQLITE_OK ) sqlite3Error(db, rc, 0);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/************** End of vtab.c ************************************************/
-/************** Begin file where.c *******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This module contains C code that generates VDBE code used to process
-** the WHERE clause of SQL statements. This module is responsible for
-** generating the code that loops through a table looking for applicable
-** rows. Indices are selected and used to speed the search when doing
-** so is applicable. Because this module is responsible for selecting
-** indices, you might also think of this module as the "query optimizer".
-*/
-
-
-/*
-** Trace output macros
-*/
-#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
-/***/ int sqlite3WhereTrace = 0;
-#endif
-#if defined(SQLITE_DEBUG) \
- && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
-# define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X
-#else
-# define WHERETRACE(X)
-#endif
-
-/* Forward reference
-*/
-typedef struct WhereClause WhereClause;
-typedef struct WhereMaskSet WhereMaskSet;
-typedef struct WhereOrInfo WhereOrInfo;
-typedef struct WhereAndInfo WhereAndInfo;
-typedef struct WhereCost WhereCost;
-
-/*
-** The query generator uses an array of instances of this structure to
-** help it analyze the subexpressions of the WHERE clause. Each WHERE
-** clause subexpression is separated from the others by AND operators,
-** usually, or sometimes subexpressions separated by OR.
-**
-** All WhereTerms are collected into a single WhereClause structure.
-** The following identity holds:
-**
-** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm
-**
-** When a term is of the form:
-**
-** X <op> <expr>
-**
-** where X is a column name and <op> is one of certain operators,
-** then WhereTerm.leftCursor and WhereTerm.u.leftColumn record the
-** cursor number and column number for X. WhereTerm.eOperator records
-** the <op> using a bitmask encoding defined by WO_xxx below. The
-** use of a bitmask encoding for the operator allows us to search
-** quickly for terms that match any of several different operators.
-**
-** A WhereTerm might also be two or more subterms connected by OR:
-**
-** (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR ....
-**
-** In this second case, wtFlag as the TERM_ORINFO set and eOperator==WO_OR
-** and the WhereTerm.u.pOrInfo field points to auxiliary information that
-** is collected about the
-**
-** If a term in the WHERE clause does not match either of the two previous
-** categories, then eOperator==0. The WhereTerm.pExpr field is still set
-** to the original subexpression content and wtFlags is set up appropriately
-** but no other fields in the WhereTerm object are meaningful.
-**
-** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers,
-** but they do so indirectly. A single WhereMaskSet structure translates
-** cursor number into bits and the translated bit is stored in the prereq
-** fields. The translation is used in order to maximize the number of
-** bits that will fit in a Bitmask. The VDBE cursor numbers might be
-** spread out over the non-negative integers. For example, the cursor
-** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The WhereMaskSet
-** translates these sparse cursor numbers into consecutive integers
-** beginning with 0 in order to make the best possible use of the available
-** bits in the Bitmask. So, in the example above, the cursor numbers
-** would be mapped into integers 0 through 7.
-**
-** The number of terms in a join is limited by the number of bits
-** in prereqRight and prereqAll. The default is 64 bits, hence SQLite
-** is only able to process joins with 64 or fewer tables.
-*/
-typedef struct WhereTerm WhereTerm;
-struct WhereTerm {
- Expr *pExpr; /* Pointer to the subexpression that is this term */
- int iParent; /* Disable pWC->a[iParent] when this term disabled */
- int leftCursor; /* Cursor number of X in "X <op> <expr>" */
- union {
- int leftColumn; /* Column number of X in "X <op> <expr>" */
- WhereOrInfo *pOrInfo; /* Extra information if eOperator==WO_OR */
- WhereAndInfo *pAndInfo; /* Extra information if eOperator==WO_AND */
- } u;
- u16 eOperator; /* A WO_xx value describing <op> */
- u8 wtFlags; /* TERM_xxx bit flags. See below */
- u8 nChild; /* Number of children that must disable us */
- WhereClause *pWC; /* The clause this term is part of */
- Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
- Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
-};
-
-/*
-** Allowed values of WhereTerm.wtFlags
-*/
-#define TERM_DYNAMIC 0x01 /* Need to call sqlite3ExprDelete(db, pExpr) */
-#define TERM_VIRTUAL 0x02 /* Added by the optimizer. Do not code */
-#define TERM_CODED 0x04 /* This term is already coded */
-#define TERM_COPIED 0x08 /* Has a child */
-#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
-#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
-#define TERM_OR_OK 0x40 /* Used during OR-clause processing */
-#ifdef SQLITE_ENABLE_STAT3
-# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
-#else
-# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
-#endif
-
-/*
-** An instance of the following structure holds all information about a
-** WHERE clause. Mostly this is a container for one or more WhereTerms.
-**
-** Explanation of pOuter: For a WHERE clause of the form
-**
-** a AND ((b AND c) OR (d AND e)) AND f
-**
-** There are separate WhereClause objects for the whole clause and for
-** the subclauses "(b AND c)" and "(d AND e)". The pOuter field of the
-** subclauses points to the WhereClause object for the whole clause.
-*/
-struct WhereClause {
- Parse *pParse; /* The parser context */
- WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
- Bitmask vmask; /* Bitmask identifying virtual table cursors */
- WhereClause *pOuter; /* Outer conjunction */
- u8 op; /* Split operator. TK_AND or TK_OR */
- u16 wctrlFlags; /* Might include WHERE_AND_ONLY */
- int nTerm; /* Number of terms */
- int nSlot; /* Number of entries in a[] */
- WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
-#if defined(SQLITE_SMALL_STACK)
- WhereTerm aStatic[1]; /* Initial static space for a[] */
-#else
- WhereTerm aStatic[8]; /* Initial static space for a[] */
-#endif
-};
-
-/*
-** A WhereTerm with eOperator==WO_OR has its u.pOrInfo pointer set to
-** a dynamically allocated instance of the following structure.
-*/
-struct WhereOrInfo {
- WhereClause wc; /* Decomposition into subterms */
- Bitmask indexable; /* Bitmask of all indexable tables in the clause */
-};
-
-/*
-** A WhereTerm with eOperator==WO_AND has its u.pAndInfo pointer set to
-** a dynamically allocated instance of the following structure.
-*/
-struct WhereAndInfo {
- WhereClause wc; /* The subexpression broken out */
-};
-
-/*
-** An instance of the following structure keeps track of a mapping
-** between VDBE cursor numbers and bits of the bitmasks in WhereTerm.
-**
-** The VDBE cursor numbers are small integers contained in
-** SrcList_item.iCursor and Expr.iTable fields. For any given WHERE
-** clause, the cursor numbers might not begin with 0 and they might
-** contain gaps in the numbering sequence. But we want to make maximum
-** use of the bits in our bitmasks. This structure provides a mapping
-** from the sparse cursor numbers into consecutive integers beginning
-** with 0.
-**
-** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask
-** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<<A.
-**
-** For example, if the WHERE clause expression used these VDBE
-** cursors: 4, 5, 8, 29, 57, 73. Then the WhereMaskSet structure
-** would map those cursor numbers into bits 0 through 5.
-**
-** Note that the mapping is not necessarily ordered. In the example
-** above, the mapping might go like this: 4->3, 5->1, 8->2, 29->0,
-** 57->5, 73->4. Or one of 719 other combinations might be used. It
-** does not really matter. What is important is that sparse cursor
-** numbers all get mapped into bit numbers that begin with 0 and contain
-** no gaps.
-*/
-struct WhereMaskSet {
- int n; /* Number of assigned cursor values */
- int ix[BMS]; /* Cursor assigned to each bit */
-};
-
-/*
-** A WhereCost object records a lookup strategy and the estimated
-** cost of pursuing that strategy.
-*/
-struct WhereCost {
- WherePlan plan; /* The lookup strategy */
- double rCost; /* Overall cost of pursuing this search strategy */
- Bitmask used; /* Bitmask of cursors used by this plan */
-};
-
-/*
-** Bitmasks for the operators that indices are able to exploit. An
-** OR-ed combination of these values can be used when searching for
-** terms in the where clause.
-*/
-#define WO_IN 0x001
-#define WO_EQ 0x002
-#define WO_LT (WO_EQ<<(TK_LT-TK_EQ))
-#define WO_LE (WO_EQ<<(TK_LE-TK_EQ))
-#define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
-#define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
-#define WO_MATCH 0x040
-#define WO_ISNULL 0x080
-#define WO_OR 0x100 /* Two or more OR-connected terms */
-#define WO_AND 0x200 /* Two or more AND-connected terms */
-#define WO_NOOP 0x800 /* This term does not restrict search space */
-
-#define WO_ALL 0xfff /* Mask of all possible WO_* values */
-#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */
-
-/*
-** Value for wsFlags returned by bestIndex() and stored in
-** WhereLevel.wsFlags. These flags determine which search
-** strategies are appropriate.
-**
-** The least significant 12 bits is reserved as a mask for WO_ values above.
-** The WhereLevel.wsFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
-** But if the table is the right table of a left join, WhereLevel.wsFlags
-** is set to WO_IN|WO_EQ. The WhereLevel.wsFlags field can then be used as
-** the "op" parameter to findTerm when we are resolving equality constraints.
-** ISNULL constraints will then not be used on the right table of a left
-** join. Tickets #2177 and #2189.
-*/
-#define WHERE_ROWID_EQ 0x00001000 /* rowid=EXPR or rowid IN (...) */
-#define WHERE_ROWID_RANGE 0x00002000 /* rowid<EXPR and/or rowid>EXPR */
-#define WHERE_COLUMN_EQ 0x00010000 /* x=EXPR or x IN (...) or x IS NULL */
-#define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
-#define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
-#define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
-#define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
-#define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
-#define WHERE_IN_ABLE 0x000f1000 /* Able to support an IN operator */
-#define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
-#define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
-#define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
-#define WHERE_IDX_ONLY 0x00400000 /* Use index only - omit table */
-#define WHERE_ORDERED 0x00800000 /* Output will appear in correct order */
-#define WHERE_REVERSE 0x01000000 /* Scan in reverse order */
-#define WHERE_UNIQUE 0x02000000 /* Selects no more than one row */
-#define WHERE_ALL_UNIQUE 0x04000000 /* This and all prior have one row */
-#define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */
-#define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */
-#define WHERE_TEMP_INDEX 0x20000000 /* Uses an ephemeral index */
-#define WHERE_DISTINCT 0x40000000 /* Correct order for DISTINCT */
-#define WHERE_COVER_SCAN 0x80000000 /* Full scan of a covering index */
-
-/*
-** This module contains many separate subroutines that work together to
-** find the best indices to use for accessing a particular table in a query.
-** An instance of the following structure holds context information about the
-** index search so that it can be more easily passed between the various
-** routines.
-*/
-typedef struct WhereBestIdx WhereBestIdx;
-struct WhereBestIdx {
- Parse *pParse; /* Parser context */
- WhereClause *pWC; /* The WHERE clause */
- struct SrcList_item *pSrc; /* The FROM clause term to search */
- Bitmask notReady; /* Mask of cursors not available */
- Bitmask notValid; /* Cursors not available for any purpose */
- ExprList *pOrderBy; /* The ORDER BY clause */
- ExprList *pDistinct; /* The select-list if query is DISTINCT */
- sqlite3_index_info **ppIdxInfo; /* Index information passed to xBestIndex */
- int i, n; /* Which loop is being coded; # of loops */
- WhereLevel *aLevel; /* Info about outer loops */
- WhereCost cost; /* Lowest cost query plan */
-};
-
-/*
-** Return TRUE if the probe cost is less than the baseline cost
-*/
-static int compareCost(const WhereCost *pProbe, const WhereCost *pBaseline){
- if( pProbe->rCost<pBaseline->rCost ) return 1;
- if( pProbe->rCost>pBaseline->rCost ) return 0;
- if( pProbe->plan.nOBSat>pBaseline->plan.nOBSat ) return 1;
- if( pProbe->plan.nRow<pBaseline->plan.nRow ) return 1;
- return 0;
-}
-
-/*
-** Initialize a preallocated WhereClause structure.
-*/
-static void whereClauseInit(
- WhereClause *pWC, /* The WhereClause to be initialized */
- Parse *pParse, /* The parsing context */
- WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmasks */
- u16 wctrlFlags /* Might include WHERE_AND_ONLY */
-){
- pWC->pParse = pParse;
- pWC->pMaskSet = pMaskSet;
- pWC->pOuter = 0;
- pWC->nTerm = 0;
- pWC->nSlot = ArraySize(pWC->aStatic);
- pWC->a = pWC->aStatic;
- pWC->vmask = 0;
- pWC->wctrlFlags = wctrlFlags;
-}
-
-/* Forward reference */
-static void whereClauseClear(WhereClause*);
-
-/*
-** Deallocate all memory associated with a WhereOrInfo object.
-*/
-static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){
- whereClauseClear(&p->wc);
- sqlite3DbFree(db, p);
-}
-
-/*
-** Deallocate all memory associated with a WhereAndInfo object.
-*/
-static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){
- whereClauseClear(&p->wc);
- sqlite3DbFree(db, p);
-}
-
-/*
-** Deallocate a WhereClause structure. The WhereClause structure
-** itself is not freed. This routine is the inverse of whereClauseInit().
-*/
-static void whereClauseClear(WhereClause *pWC){
- int i;
- WhereTerm *a;
- sqlite3 *db = pWC->pParse->db;
- for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
- if( a->wtFlags & TERM_DYNAMIC ){
- sqlite3ExprDelete(db, a->pExpr);
- }
- if( a->wtFlags & TERM_ORINFO ){
- whereOrInfoDelete(db, a->u.pOrInfo);
- }else if( a->wtFlags & TERM_ANDINFO ){
- whereAndInfoDelete(db, a->u.pAndInfo);
- }
- }
- if( pWC->a!=pWC->aStatic ){
- sqlite3DbFree(db, pWC->a);
- }
-}
-
-/*
-** Add a single new WhereTerm entry to the WhereClause object pWC.
-** The new WhereTerm object is constructed from Expr p and with wtFlags.
-** The index in pWC->a[] of the new WhereTerm is returned on success.
-** 0 is returned if the new WhereTerm could not be added due to a memory
-** allocation error. The memory allocation failure will be recorded in
-** the db->mallocFailed flag so that higher-level functions can detect it.
-**
-** This routine will increase the size of the pWC->a[] array as necessary.
-**
-** If the wtFlags argument includes TERM_DYNAMIC, then responsibility
-** for freeing the expression p is assumed by the WhereClause object pWC.
-** This is true even if this routine fails to allocate a new WhereTerm.
-**
-** WARNING: This routine might reallocate the space used to store
-** WhereTerms. All pointers to WhereTerms should be invalidated after
-** calling this routine. Such pointers may be reinitialized by referencing
-** the pWC->a[] array.
-*/
-static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
- WhereTerm *pTerm;
- int idx;
- testcase( wtFlags & TERM_VIRTUAL ); /* EV: R-00211-15100 */
- if( pWC->nTerm>=pWC->nSlot ){
- WhereTerm *pOld = pWC->a;
- sqlite3 *db = pWC->pParse->db;
- pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
- if( pWC->a==0 ){
- if( wtFlags & TERM_DYNAMIC ){
- sqlite3ExprDelete(db, p);
- }
- pWC->a = pOld;
- return 0;
- }
- memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
- if( pOld!=pWC->aStatic ){
- sqlite3DbFree(db, pOld);
- }
- pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
- }
- pTerm = &pWC->a[idx = pWC->nTerm++];
- pTerm->pExpr = p;
- pTerm->wtFlags = wtFlags;
- pTerm->pWC = pWC;
- pTerm->iParent = -1;
- return idx;
-}
-
-/*
-** This routine identifies subexpressions in the WHERE clause where
-** each subexpression is separated by the AND operator or some other
-** operator specified in the op parameter. The WhereClause structure
-** is filled with pointers to subexpressions. For example:
-**
-** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22)
-** \________/ \_______________/ \________________/
-** slot[0] slot[1] slot[2]
-**
-** The original WHERE clause in pExpr is unaltered. All this routine
-** does is make slot[] entries point to substructure within pExpr.
-**
-** In the previous sentence and in the diagram, "slot[]" refers to
-** the WhereClause.a[] array. The slot[] array grows as needed to contain
-** all terms of the WHERE clause.
-*/
-static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
- pWC->op = (u8)op;
- if( pExpr==0 ) return;
- if( pExpr->op!=op ){
- whereClauseInsert(pWC, pExpr, 0);
- }else{
- whereSplit(pWC, pExpr->pLeft, op);
- whereSplit(pWC, pExpr->pRight, op);
- }
-}
-
-/*
-** Initialize an expression mask set (a WhereMaskSet object)
-*/
-#define initMaskSet(P) memset(P, 0, sizeof(*P))
-
-/*
-** Return the bitmask for the given cursor number. Return 0 if
-** iCursor is not in the set.
-*/
-static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){
- int i;
- assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
- for(i=0; i<pMaskSet->n; i++){
- if( pMaskSet->ix[i]==iCursor ){
- return ((Bitmask)1)<<i;
- }
- }
- return 0;
-}
-
-/*
-** Create a new mask for cursor iCursor.
-**
-** There is one cursor per table in the FROM clause. The number of
-** tables in the FROM clause is limited by a test early in the
-** sqlite3WhereBegin() routine. So we know that the pMaskSet->ix[]
-** array will never overflow.
-*/
-static void createMask(WhereMaskSet *pMaskSet, int iCursor){
- assert( pMaskSet->n < ArraySize(pMaskSet->ix) );
- pMaskSet->ix[pMaskSet->n++] = iCursor;
-}
-
-/*
-** This routine walks (recursively) an expression tree and generates
-** a bitmask indicating which tables are used in that expression
-** tree.
-**
-** In order for this routine to work, the calling function must have
-** previously invoked sqlite3ResolveExprNames() on the expression. See
-** the header comment on that routine for additional information.
-** The sqlite3ResolveExprNames() routines looks for column names and
-** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
-** the VDBE cursor number of the table. This routine just has to
-** translate the cursor numbers into bitmask values and OR all
-** the bitmasks together.
-*/
-static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
-static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
-static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){
- Bitmask mask = 0;
- if( p==0 ) return 0;
- if( p->op==TK_COLUMN ){
- mask = getMask(pMaskSet, p->iTable);
- return mask;
- }
- mask = exprTableUsage(pMaskSet, p->pRight);
- mask |= exprTableUsage(pMaskSet, p->pLeft);
- if( ExprHasProperty(p, EP_xIsSelect) ){
- mask |= exprSelectTableUsage(pMaskSet, p->x.pSelect);
- }else{
- mask |= exprListTableUsage(pMaskSet, p->x.pList);
- }
- return mask;
-}
-static Bitmask exprListTableUsage(WhereMaskSet *pMaskSet, ExprList *pList){
- int i;
- Bitmask mask = 0;
- if( pList ){
- for(i=0; i<pList->nExpr; i++){
- mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
- }
- }
- return mask;
-}
-static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){
- Bitmask mask = 0;
- while( pS ){
- SrcList *pSrc = pS->pSrc;
- mask |= exprListTableUsage(pMaskSet, pS->pEList);
- mask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
- mask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
- mask |= exprTableUsage(pMaskSet, pS->pWhere);
- mask |= exprTableUsage(pMaskSet, pS->pHaving);
- if( ALWAYS(pSrc!=0) ){
- int i;
- for(i=0; i<pSrc->nSrc; i++){
- mask |= exprSelectTableUsage(pMaskSet, pSrc->a[i].pSelect);
- mask |= exprTableUsage(pMaskSet, pSrc->a[i].pOn);
- }
- }
- pS = pS->pPrior;
- }
- return mask;
-}
-
-/*
-** Return TRUE if the given operator is one of the operators that is
-** allowed for an indexable WHERE clause term. The allowed operators are
-** "=", "<", ">", "<=", ">=", and "IN".
-**
-** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
-** of one of the following forms: column = expression column > expression
-** column >= expression column < expression column <= expression
-** expression = column expression > column expression >= column
-** expression < column expression <= column column IN
-** (expression-list) column IN (subquery) column IS NULL
-*/
-static int allowedOp(int op){
- assert( TK_GT>TK_EQ && TK_GT<TK_GE );
- assert( TK_LT>TK_EQ && TK_LT<TK_GE );
- assert( TK_LE>TK_EQ && TK_LE<TK_GE );
- assert( TK_GE==TK_EQ+4 );
- return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
-}
-
-/*
-** Swap two objects of type TYPE.
-*/
-#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
-
-/*
-** Commute a comparison operator. Expressions of the form "X op Y"
-** are converted into "Y op X".
-**
-** If left/right precendence rules come into play when determining the
-** collating
-** side of the comparison, it remains associated with the same side after
-** the commutation. So "Y collate NOCASE op X" becomes
-** "X op Y". This is because any collation sequence on
-** the left hand side of a comparison overrides any collation sequence
-** attached to the right. For the same reason the EP_Collate flag
-** is not commuted.
-*/
-static void exprCommute(Parse *pParse, Expr *pExpr){
- u16 expRight = (pExpr->pRight->flags & EP_Collate);
- u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
- assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
- if( expRight==expLeft ){
- /* Either X and Y both have COLLATE operator or neither do */
- if( expRight ){
- /* Both X and Y have COLLATE operators. Make sure X is always
- ** used by clearing the EP_Collate flag from Y. */
- pExpr->pRight->flags &= ~EP_Collate;
- }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
- /* Neither X nor Y have COLLATE operators, but X has a non-default
- ** collating sequence. So add the EP_Collate marker on X to cause
- ** it to be searched first. */
- pExpr->pLeft->flags |= EP_Collate;
- }
- }
- SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
- if( pExpr->op>=TK_GT ){
- assert( TK_LT==TK_GT+2 );
- assert( TK_GE==TK_LE+2 );
- assert( TK_GT>TK_EQ );
- assert( TK_GT<TK_LE );
- assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
- pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT;
- }
-}
-
-/*
-** Translate from TK_xx operator to WO_xx bitmask.
-*/
-static u16 operatorMask(int op){
- u16 c;
- assert( allowedOp(op) );
- if( op==TK_IN ){
- c = WO_IN;
- }else if( op==TK_ISNULL ){
- c = WO_ISNULL;
- }else{
- assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
- c = (u16)(WO_EQ<<(op-TK_EQ));
- }
- assert( op!=TK_ISNULL || c==WO_ISNULL );
- assert( op!=TK_IN || c==WO_IN );
- assert( op!=TK_EQ || c==WO_EQ );
- assert( op!=TK_LT || c==WO_LT );
- assert( op!=TK_LE || c==WO_LE );
- assert( op!=TK_GT || c==WO_GT );
- assert( op!=TK_GE || c==WO_GE );
- return c;
-}
-
-/*
-** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
-** where X is a reference to the iColumn of table iCur and <op> is one of
-** the WO_xx operator codes specified by the op parameter.
-** Return a pointer to the term. Return 0 if not found.
-*/
-static WhereTerm *findTerm(
- WhereClause *pWC, /* The WHERE clause to be searched */
- int iCur, /* Cursor number of LHS */
- int iColumn, /* Column number of LHS */
- Bitmask notReady, /* RHS must not overlap with this mask */
- u32 op, /* Mask of WO_xx values describing operator */
- Index *pIdx /* Must be compatible with this index, if not NULL */
-){
- WhereTerm *pTerm;
- int k;
- assert( iCur>=0 );
- op &= WO_ALL;
- for(; pWC; pWC=pWC->pOuter){
- for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
- if( pTerm->leftCursor==iCur
- && (pTerm->prereqRight & notReady)==0
- && pTerm->u.leftColumn==iColumn
- && (pTerm->eOperator & op)!=0
- ){
- if( iColumn>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){
- Expr *pX = pTerm->pExpr;
- CollSeq *pColl;
- char idxaff;
- int j;
- Parse *pParse = pWC->pParse;
-
- idxaff = pIdx->pTable->aCol[iColumn].affinity;
- if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
-
- /* Figure out the collation sequence required from an index for
- ** it to be useful for optimising expression pX. Store this
- ** value in variable pColl.
- */
- assert(pX->pLeft);
- pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
- if( pColl==0 ) pColl = pParse->db->pDfltColl;
-
- for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
- if( NEVER(j>=pIdx->nColumn) ) return 0;
- }
- if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
- }
- return pTerm;
- }
- }
- }
- return 0;
-}
-
-/* Forward reference */
-static void exprAnalyze(SrcList*, WhereClause*, int);
-
-/*
-** Call exprAnalyze on all terms in a WHERE clause.
-**
-**
-*/
-static void exprAnalyzeAll(
- SrcList *pTabList, /* the FROM clause */
- WhereClause *pWC /* the WHERE clause to be analyzed */
-){
- int i;
- for(i=pWC->nTerm-1; i>=0; i--){
- exprAnalyze(pTabList, pWC, i);
- }
-}
-
-#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
-/*
-** Check to see if the given expression is a LIKE or GLOB operator that
-** can be optimized using inequality constraints. Return TRUE if it is
-** so and false if not.
-**
-** In order for the operator to be optimizible, the RHS must be a string
-** literal that does not begin with a wildcard.
-*/
-static int isLikeOrGlob(
- Parse *pParse, /* Parsing and code generating context */
- Expr *pExpr, /* Test this expression */
- Expr **ppPrefix, /* Pointer to TK_STRING expression with pattern prefix */
- int *pisComplete, /* True if the only wildcard is % in the last character */
- int *pnoCase /* True if uppercase is equivalent to lowercase */
-){
- const char *z = 0; /* String on RHS of LIKE operator */
- Expr *pRight, *pLeft; /* Right and left size of LIKE operator */
- ExprList *pList; /* List of operands to the LIKE operator */
- int c; /* One character in z[] */
- int cnt; /* Number of non-wildcard prefix characters */
- char wc[3]; /* Wildcard characters */
- sqlite3 *db = pParse->db; /* Database connection */
- sqlite3_value *pVal = 0;
- int op; /* Opcode of pRight */
-
- if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){
- return 0;
- }
-#ifdef SQLITE_EBCDIC
- if( *pnoCase ) return 0;
-#endif
- pList = pExpr->x.pList;
- pLeft = pList->a[1].pExpr;
- if( pLeft->op!=TK_COLUMN
- || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->pTab)
- ){
- /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
- ** be the name of an indexed column with TEXT affinity. */
- return 0;
- }
- assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
-
- pRight = pList->a[0].pExpr;
- op = pRight->op;
- if( op==TK_REGISTER ){
- op = pRight->op2;
- }
- if( op==TK_VARIABLE ){
- Vdbe *pReprepare = pParse->pReprepare;
- int iCol = pRight->iColumn;
- pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
- if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
- z = (char *)sqlite3_value_text(pVal);
- }
- sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
- assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
- }else if( op==TK_STRING ){
- z = pRight->u.zToken;
- }
- if( z ){
- cnt = 0;
- while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
- cnt++;
- }
- if( cnt!=0 && 255!=(u8)z[cnt-1] ){
- Expr *pPrefix;
- *pisComplete = c==wc[0] && z[cnt+1]==0;
- pPrefix = sqlite3Expr(db, TK_STRING, z);
- if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
- *ppPrefix = pPrefix;
- if( op==TK_VARIABLE ){
- Vdbe *v = pParse->pVdbe;
- sqlite3VdbeSetVarmask(v, pRight->iColumn);
- if( *pisComplete && pRight->u.zToken[1] ){
- /* If the rhs of the LIKE expression is a variable, and the current
- ** value of the variable means there is no need to invoke the LIKE
- ** function, then no OP_Variable will be added to the program.
- ** This causes problems for the sqlite3_bind_parameter_name()
- ** API. To workaround them, add a dummy OP_Variable here.
- */
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3ExprCodeTarget(pParse, pRight, r1);
- sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0);
- sqlite3ReleaseTempReg(pParse, r1);
- }
- }
- }else{
- z = 0;
- }
- }
-
- sqlite3ValueFree(pVal);
- return (z!=0);
-}
-#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
-
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/*
-** Check to see if the given expression is of the form
-**
-** column MATCH expr
-**
-** If it is then return TRUE. If not, return FALSE.
-*/
-static int isMatchOfColumn(
- Expr *pExpr /* Test this expression */
-){
- ExprList *pList;
-
- if( pExpr->op!=TK_FUNCTION ){
- return 0;
- }
- if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
- return 0;
- }
- pList = pExpr->x.pList;
- if( pList->nExpr!=2 ){
- return 0;
- }
- if( pList->a[1].pExpr->op != TK_COLUMN ){
- return 0;
- }
- return 1;
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-/*
-** If the pBase expression originated in the ON or USING clause of
-** a join, then transfer the appropriate markings over to derived.
-*/
-static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
- pDerived->flags |= pBase->flags & EP_FromJoin;
- pDerived->iRightJoinTable = pBase->iRightJoinTable;
-}
-
-#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
-/*
-** Analyze a term that consists of two or more OR-connected
-** subterms. So in:
-**
-** ... WHERE (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13)
-** ^^^^^^^^^^^^^^^^^^^^
-**
-** This routine analyzes terms such as the middle term in the above example.
-** A WhereOrTerm object is computed and attached to the term under
-** analysis, regardless of the outcome of the analysis. Hence:
-**
-** WhereTerm.wtFlags |= TERM_ORINFO
-** WhereTerm.u.pOrInfo = a dynamically allocated WhereOrTerm object
-**
-** The term being analyzed must have two or more of OR-connected subterms.
-** A single subterm might be a set of AND-connected sub-subterms.
-** Examples of terms under analysis:
-**
-** (A) t1.x=t2.y OR t1.x=t2.z OR t1.y=15 OR t1.z=t3.a+5
-** (B) x=expr1 OR expr2=x OR x=expr3
-** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15)
-** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
-** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
-**
-** CASE 1:
-**
-** If all subterms are of the form T.C=expr for some single column of C
-** a single table T (as shown in example B above) then create a new virtual
-** term that is an equivalent IN expression. In other words, if the term
-** being analyzed is:
-**
-** x = expr1 OR expr2 = x OR x = expr3
-**
-** then create a new virtual term like this:
-**
-** x IN (expr1,expr2,expr3)
-**
-** CASE 2:
-**
-** If all subterms are indexable by a single table T, then set
-**
-** WhereTerm.eOperator = WO_OR
-** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T
-**
-** A subterm is "indexable" if it is of the form
-** "T.C <op> <expr>" where C is any column of table T and
-** <op> is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN".
-** A subterm is also indexable if it is an AND of two or more
-** subsubterms at least one of which is indexable. Indexable AND
-** subterms have their eOperator set to WO_AND and they have
-** u.pAndInfo set to a dynamically allocated WhereAndTerm object.
-**
-** From another point of view, "indexable" means that the subterm could
-** potentially be used with an index if an appropriate index exists.
-** This analysis does not consider whether or not the index exists; that
-** is something the bestIndex() routine will determine. This analysis
-** only looks at whether subterms appropriate for indexing exist.
-**
-** All examples A through E above all satisfy case 2. But if a term
-** also statisfies case 1 (such as B) we know that the optimizer will
-** always prefer case 1, so in that case we pretend that case 2 is not
-** satisfied.
-**
-** It might be the case that multiple tables are indexable. For example,
-** (E) above is indexable on tables P, Q, and R.
-**
-** Terms that satisfy case 2 are candidates for lookup by using
-** separate indices to find rowids for each subterm and composing
-** the union of all rowids using a RowSet object. This is similar
-** to "bitmap indices" in other database engines.
-**
-** OTHERWISE:
-**
-** If neither case 1 nor case 2 apply, then leave the eOperator set to
-** zero. This term is not useful for search.
-*/
-static void exprAnalyzeOrTerm(
- SrcList *pSrc, /* the FROM clause */
- WhereClause *pWC, /* the complete WHERE clause */
- int idxTerm /* Index of the OR-term to be analyzed */
-){
- Parse *pParse = pWC->pParse; /* Parser context */
- sqlite3 *db = pParse->db; /* Database connection */
- WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */
- Expr *pExpr = pTerm->pExpr; /* The expression of the term */
- WhereMaskSet *pMaskSet = pWC->pMaskSet; /* Table use masks */
- int i; /* Loop counters */
- WhereClause *pOrWc; /* Breakup of pTerm into subterms */
- WhereTerm *pOrTerm; /* A Sub-term within the pOrWc */
- WhereOrInfo *pOrInfo; /* Additional information associated with pTerm */
- Bitmask chngToIN; /* Tables that might satisfy case 1 */
- Bitmask indexable; /* Tables that are indexable, satisfying case 2 */
-
- /*
- ** Break the OR clause into its separate subterms. The subterms are
- ** stored in a WhereClause structure containing within the WhereOrInfo
- ** object that is attached to the original OR clause term.
- */
- assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 );
- assert( pExpr->op==TK_OR );
- pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo));
- if( pOrInfo==0 ) return;
- pTerm->wtFlags |= TERM_ORINFO;
- pOrWc = &pOrInfo->wc;
- whereClauseInit(pOrWc, pWC->pParse, pMaskSet, pWC->wctrlFlags);
- whereSplit(pOrWc, pExpr, TK_OR);
- exprAnalyzeAll(pSrc, pOrWc);
- if( db->mallocFailed ) return;
- assert( pOrWc->nTerm>=2 );
-
- /*
- ** Compute the set of tables that might satisfy cases 1 or 2.
- */
- indexable = ~(Bitmask)0;
- chngToIN = ~(pWC->vmask);
- for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
- if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
- WhereAndInfo *pAndInfo;
- assert( pOrTerm->eOperator==0 );
- assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
- chngToIN = 0;
- pAndInfo = sqlite3DbMallocRaw(db, sizeof(*pAndInfo));
- if( pAndInfo ){
- WhereClause *pAndWC;
- WhereTerm *pAndTerm;
- int j;
- Bitmask b = 0;
- pOrTerm->u.pAndInfo = pAndInfo;
- pOrTerm->wtFlags |= TERM_ANDINFO;
- pOrTerm->eOperator = WO_AND;
- pAndWC = &pAndInfo->wc;
- whereClauseInit(pAndWC, pWC->pParse, pMaskSet, pWC->wctrlFlags);
- whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
- exprAnalyzeAll(pSrc, pAndWC);
- pAndWC->pOuter = pWC;
- testcase( db->mallocFailed );
- if( !db->mallocFailed ){
- for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
- assert( pAndTerm->pExpr );
- if( allowedOp(pAndTerm->pExpr->op) ){
- b |= getMask(pMaskSet, pAndTerm->leftCursor);
- }
- }
- }
- indexable &= b;
- }
- }else if( pOrTerm->wtFlags & TERM_COPIED ){
- /* Skip this term for now. We revisit it when we process the
- ** corresponding TERM_VIRTUAL term */
- }else{
- Bitmask b;
- b = getMask(pMaskSet, pOrTerm->leftCursor);
- if( pOrTerm->wtFlags & TERM_VIRTUAL ){
- WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent];
- b |= getMask(pMaskSet, pOther->leftCursor);
- }
- indexable &= b;
- if( pOrTerm->eOperator!=WO_EQ ){
- chngToIN = 0;
- }else{
- chngToIN &= b;
- }
- }
- }
-
- /*
- ** Record the set of tables that satisfy case 2. The set might be
- ** empty.
- */
- pOrInfo->indexable = indexable;
- pTerm->eOperator = indexable==0 ? 0 : WO_OR;
-
- /*
- ** chngToIN holds a set of tables that *might* satisfy case 1. But
- ** we have to do some additional checking to see if case 1 really
- ** is satisfied.
- **
- ** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means
- ** that there is no possibility of transforming the OR clause into an
- ** IN operator because one or more terms in the OR clause contain
- ** something other than == on a column in the single table. The 1-bit
- ** case means that every term of the OR clause is of the form
- ** "table.column=expr" for some single table. The one bit that is set
- ** will correspond to the common table. We still need to check to make
- ** sure the same column is used on all terms. The 2-bit case is when
- ** the all terms are of the form "table1.column=table2.column". It
- ** might be possible to form an IN operator with either table1.column
- ** or table2.column as the LHS if either is common to every term of
- ** the OR clause.
- **
- ** Note that terms of the form "table.column1=table.column2" (the
- ** same table on both sizes of the ==) cannot be optimized.
- */
- if( chngToIN ){
- int okToChngToIN = 0; /* True if the conversion to IN is valid */
- int iColumn = -1; /* Column index on lhs of IN operator */
- int iCursor = -1; /* Table cursor common to all terms */
- int j = 0; /* Loop counter */
-
- /* Search for a table and column that appears on one side or the
- ** other of the == operator in every subterm. That table and column
- ** will be recorded in iCursor and iColumn. There might not be any
- ** such table and column. Set okToChngToIN if an appropriate table
- ** and column is found but leave okToChngToIN false if not found.
- */
- for(j=0; j<2 && !okToChngToIN; j++){
- pOrTerm = pOrWc->a;
- for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
- assert( pOrTerm->eOperator==WO_EQ );
- pOrTerm->wtFlags &= ~TERM_OR_OK;
- if( pOrTerm->leftCursor==iCursor ){
- /* This is the 2-bit case and we are on the second iteration and
- ** current term is from the first iteration. So skip this term. */
- assert( j==1 );
- continue;
- }
- if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){
- /* This term must be of the form t1.a==t2.b where t2 is in the
- ** chngToIN set but t1 is not. This term will be either preceeded
- ** or follwed by an inverted copy (t2.b==t1.a). Skip this term
- ** and use its inversion. */
- testcase( pOrTerm->wtFlags & TERM_COPIED );
- testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
- assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
- continue;
- }
- iColumn = pOrTerm->u.leftColumn;
- iCursor = pOrTerm->leftCursor;
- break;
- }
- if( i<0 ){
- /* No candidate table+column was found. This can only occur
- ** on the second iteration */
- assert( j==1 );
- assert( (chngToIN&(chngToIN-1))==0 );
- assert( chngToIN==getMask(pMaskSet, iCursor) );
- break;
- }
- testcase( j==1 );
-
- /* We have found a candidate table and column. Check to see if that
- ** table and column is common to every term in the OR clause */
- okToChngToIN = 1;
- for(; i>=0 && okToChngToIN; i--, pOrTerm++){
- assert( pOrTerm->eOperator==WO_EQ );
- if( pOrTerm->leftCursor!=iCursor ){
- pOrTerm->wtFlags &= ~TERM_OR_OK;
- }else if( pOrTerm->u.leftColumn!=iColumn ){
- okToChngToIN = 0;
- }else{
- int affLeft, affRight;
- /* If the right-hand side is also a column, then the affinities
- ** of both right and left sides must be such that no type
- ** conversions are required on the right. (Ticket #2249)
- */
- affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight);
- affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft);
- if( affRight!=0 && affRight!=affLeft ){
- okToChngToIN = 0;
- }else{
- pOrTerm->wtFlags |= TERM_OR_OK;
- }
- }
- }
- }
-
- /* At this point, okToChngToIN is true if original pTerm satisfies
- ** case 1. In that case, construct a new virtual term that is
- ** pTerm converted into an IN operator.
- **
- ** EV: R-00211-15100
- */
- if( okToChngToIN ){
- Expr *pDup; /* A transient duplicate expression */
- ExprList *pList = 0; /* The RHS of the IN operator */
- Expr *pLeft = 0; /* The LHS of the IN operator */
- Expr *pNew; /* The complete IN operator */
-
- for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
- if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
- assert( pOrTerm->eOperator==WO_EQ );
- assert( pOrTerm->leftCursor==iCursor );
- assert( pOrTerm->u.leftColumn==iColumn );
- pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
- pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup);
- pLeft = pOrTerm->pExpr->pLeft;
- }
- assert( pLeft!=0 );
- pDup = sqlite3ExprDup(db, pLeft, 0);
- pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0);
- if( pNew ){
- int idxNew;
- transferJoinMarkings(pNew, pExpr);
- assert( !ExprHasProperty(pNew, EP_xIsSelect) );
- pNew->x.pList = pList;
- idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew==0 );
- exprAnalyze(pSrc, pWC, idxNew);
- pTerm = &pWC->a[idxTerm];
- pWC->a[idxNew].iParent = idxTerm;
- pTerm->nChild = 1;
- }else{
- sqlite3ExprListDelete(db, pList);
- }
- pTerm->eOperator = WO_NOOP; /* case 1 trumps case 2 */
- }
- }
-}
-#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
-
-
-/*
-** The input to this routine is an WhereTerm structure with only the
-** "pExpr" field filled in. The job of this routine is to analyze the
-** subexpression and populate all the other fields of the WhereTerm
-** structure.
-**
-** If the expression is of the form "<expr> <op> X" it gets commuted
-** to the standard form of "X <op> <expr>".
-**
-** If the expression is of the form "X <op> Y" where both X and Y are
-** columns, then the original expression is unchanged and a new virtual
-** term of the form "Y <op> X" is added to the WHERE clause and
-** analyzed separately. The original term is marked with TERM_COPIED
-** and the new term is marked with TERM_DYNAMIC (because it's pExpr
-** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it
-** is a commuted copy of a prior term.) The original term has nChild=1
-** and the copy has idxParent set to the index of the original term.
-*/
-static void exprAnalyze(
- SrcList *pSrc, /* the FROM clause */
- WhereClause *pWC, /* the WHERE clause */
- int idxTerm /* Index of the term to be analyzed */
-){
- WhereTerm *pTerm; /* The term to be analyzed */
- WhereMaskSet *pMaskSet; /* Set of table index masks */
- Expr *pExpr; /* The expression to be analyzed */
- Bitmask prereqLeft; /* Prerequesites of the pExpr->pLeft */
- Bitmask prereqAll; /* Prerequesites of pExpr */
- Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */
- Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */
- int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */
- int noCase = 0; /* LIKE/GLOB distinguishes case */
- int op; /* Top-level operator. pExpr->op */
- Parse *pParse = pWC->pParse; /* Parsing context */
- sqlite3 *db = pParse->db; /* Database connection */
-
- if( db->mallocFailed ){
- return;
- }
- pTerm = &pWC->a[idxTerm];
- pMaskSet = pWC->pMaskSet;
- pExpr = sqlite3ExprSkipCollate(pTerm->pExpr);
- prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
- op = pExpr->op;
- if( op==TK_IN ){
- assert( pExpr->pRight==0 );
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect);
- }else{
- pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList);
- }
- }else if( op==TK_ISNULL ){
- pTerm->prereqRight = 0;
- }else{
- pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
- }
- prereqAll = exprTableUsage(pMaskSet, pExpr);
- if( ExprHasProperty(pExpr, EP_FromJoin) ){
- Bitmask x = getMask(pMaskSet, pExpr->iRightJoinTable);
- prereqAll |= x;
- extraRight = x-1; /* ON clause terms may not be used with an index
- ** on left table of a LEFT JOIN. Ticket #3015 */
- }
- pTerm->prereqAll = prereqAll;
- pTerm->leftCursor = -1;
- pTerm->iParent = -1;
- pTerm->eOperator = 0;
- if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
- Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
- Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
- if( pLeft->op==TK_COLUMN ){
- pTerm->leftCursor = pLeft->iTable;
- pTerm->u.leftColumn = pLeft->iColumn;
- pTerm->eOperator = operatorMask(op);
- }
- if( pRight && pRight->op==TK_COLUMN ){
- WhereTerm *pNew;
- Expr *pDup;
- if( pTerm->leftCursor>=0 ){
- int idxNew;
- pDup = sqlite3ExprDup(db, pExpr, 0);
- if( db->mallocFailed ){
- sqlite3ExprDelete(db, pDup);
- return;
- }
- idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
- if( idxNew==0 ) return;
- pNew = &pWC->a[idxNew];
- pNew->iParent = idxTerm;
- pTerm = &pWC->a[idxTerm];
- pTerm->nChild = 1;
- pTerm->wtFlags |= TERM_COPIED;
- }else{
- pDup = pExpr;
- pNew = pTerm;
- }
- exprCommute(pParse, pDup);
- pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
- pNew->leftCursor = pLeft->iTable;
- pNew->u.leftColumn = pLeft->iColumn;
- testcase( (prereqLeft | extraRight) != prereqLeft );
- pNew->prereqRight = prereqLeft | extraRight;
- pNew->prereqAll = prereqAll;
- pNew->eOperator = operatorMask(pDup->op);
- }
- }
-
-#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION
- /* If a term is the BETWEEN operator, create two new virtual terms
- ** that define the range that the BETWEEN implements. For example:
- **
- ** a BETWEEN b AND c
- **
- ** is converted into:
- **
- ** (a BETWEEN b AND c) AND (a>=b) AND (a<=c)
- **
- ** The two new terms are added onto the end of the WhereClause object.
- ** The new terms are "dynamic" and are children of the original BETWEEN
- ** term. That means that if the BETWEEN term is coded, the children are
- ** skipped. Or, if the children are satisfied by an index, the original
- ** BETWEEN term is skipped.
- */
- else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){
- ExprList *pList = pExpr->x.pList;
- int i;
- static const u8 ops[] = {TK_GE, TK_LE};
- assert( pList!=0 );
- assert( pList->nExpr==2 );
- for(i=0; i<2; i++){
- Expr *pNewExpr;
- int idxNew;
- pNewExpr = sqlite3PExpr(pParse, ops[i],
- sqlite3ExprDup(db, pExpr->pLeft, 0),
- sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
- idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew==0 );
- exprAnalyze(pSrc, pWC, idxNew);
- pTerm = &pWC->a[idxTerm];
- pWC->a[idxNew].iParent = idxTerm;
- }
- pTerm->nChild = 2;
- }
-#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */
-
-#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
- /* Analyze a term that is composed of two or more subterms connected by
- ** an OR operator.
- */
- else if( pExpr->op==TK_OR ){
- assert( pWC->op==TK_AND );
- exprAnalyzeOrTerm(pSrc, pWC, idxTerm);
- pTerm = &pWC->a[idxTerm];
- }
-#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
-
-#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION
- /* Add constraints to reduce the search space on a LIKE or GLOB
- ** operator.
- **
- ** A like pattern of the form "x LIKE 'abc%'" is changed into constraints
- **
- ** x>='abc' AND x<'abd' AND x LIKE 'abc%'
- **
- ** The last character of the prefix "abc" is incremented to form the
- ** termination condition "abd".
- */
- if( pWC->op==TK_AND
- && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
- ){
- Expr *pLeft; /* LHS of LIKE/GLOB operator */
- Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */
- Expr *pNewExpr1;
- Expr *pNewExpr2;
- int idxNew1;
- int idxNew2;
- Token sCollSeqName; /* Name of collating sequence */
-
- pLeft = pExpr->x.pList->a[1].pExpr;
- pStr2 = sqlite3ExprDup(db, pStr1, 0);
- if( !db->mallocFailed ){
- u8 c, *pC; /* Last character before the first wildcard */
- pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1];
- c = *pC;
- if( noCase ){
- /* The point is to increment the last character before the first
- ** wildcard. But if we increment '@', that will push it into the
- ** alphabetic range where case conversions will mess up the
- ** inequality. To avoid this, make sure to also run the full
- ** LIKE on all candidate expressions by clearing the isComplete flag
- */
- if( c=='A'-1 ) isComplete = 0; /* EV: R-64339-08207 */
-
-
- c = sqlite3UpperToLower[c];
- }
- *pC = c + 1;
- }
- sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
- sCollSeqName.n = 6;
- pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
- pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
- sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
- pStr1, 0);
- idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew1==0 );
- exprAnalyze(pSrc, pWC, idxNew1);
- pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
- pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
- sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
- pStr2, 0);
- idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew2==0 );
- exprAnalyze(pSrc, pWC, idxNew2);
- pTerm = &pWC->a[idxTerm];
- if( isComplete ){
- pWC->a[idxNew1].iParent = idxTerm;
- pWC->a[idxNew2].iParent = idxTerm;
- pTerm->nChild = 2;
- }
- }
-#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Add a WO_MATCH auxiliary term to the constraint set if the
- ** current expression is of the form: column MATCH expr.
- ** This information is used by the xBestIndex methods of
- ** virtual tables. The native query optimizer does not attempt
- ** to do anything with MATCH functions.
- */
- if( isMatchOfColumn(pExpr) ){
- int idxNew;
- Expr *pRight, *pLeft;
- WhereTerm *pNewTerm;
- Bitmask prereqColumn, prereqExpr;
-
- pRight = pExpr->x.pList->a[0].pExpr;
- pLeft = pExpr->x.pList->a[1].pExpr;
- prereqExpr = exprTableUsage(pMaskSet, pRight);
- prereqColumn = exprTableUsage(pMaskSet, pLeft);
- if( (prereqExpr & prereqColumn)==0 ){
- Expr *pNewExpr;
- pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
- 0, sqlite3ExprDup(db, pRight, 0), 0);
- idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew==0 );
- pNewTerm = &pWC->a[idxNew];
- pNewTerm->prereqRight = prereqExpr;
- pNewTerm->leftCursor = pLeft->iTable;
- pNewTerm->u.leftColumn = pLeft->iColumn;
- pNewTerm->eOperator = WO_MATCH;
- pNewTerm->iParent = idxTerm;
- pTerm = &pWC->a[idxTerm];
- pTerm->nChild = 1;
- pTerm->wtFlags |= TERM_COPIED;
- pNewTerm->prereqAll = pTerm->prereqAll;
- }
- }
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifdef SQLITE_ENABLE_STAT3
- /* When sqlite_stat3 histogram data is available an operator of the
- ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
- ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
- ** virtual term of that form.
- **
- ** Note that the virtual term must be tagged with TERM_VNULL. This
- ** TERM_VNULL tag will suppress the not-null check at the beginning
- ** of the loop. Without the TERM_VNULL flag, the not-null check at
- ** the start of the loop will prevent any results from being returned.
- */
- if( pExpr->op==TK_NOTNULL
- && pExpr->pLeft->op==TK_COLUMN
- && pExpr->pLeft->iColumn>=0
- ){
- Expr *pNewExpr;
- Expr *pLeft = pExpr->pLeft;
- int idxNew;
- WhereTerm *pNewTerm;
-
- pNewExpr = sqlite3PExpr(pParse, TK_GT,
- sqlite3ExprDup(db, pLeft, 0),
- sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0);
-
- idxNew = whereClauseInsert(pWC, pNewExpr,
- TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
- if( idxNew ){
- pNewTerm = &pWC->a[idxNew];
- pNewTerm->prereqRight = 0;
- pNewTerm->leftCursor = pLeft->iTable;
- pNewTerm->u.leftColumn = pLeft->iColumn;
- pNewTerm->eOperator = WO_GT;
- pNewTerm->iParent = idxTerm;
- pTerm = &pWC->a[idxTerm];
- pTerm->nChild = 1;
- pTerm->wtFlags |= TERM_COPIED;
- pNewTerm->prereqAll = pTerm->prereqAll;
- }
- }
-#endif /* SQLITE_ENABLE_STAT */
-
- /* Prevent ON clause terms of a LEFT JOIN from being used to drive
- ** an index for tables to the left of the join.
- */
- pTerm->prereqRight |= extraRight;
-}
-
-/*
-** This function searches the expression list passed as the second argument
-** for an expression of type TK_COLUMN that refers to the same column and
-** uses the same collation sequence as the iCol'th column of index pIdx.
-** Argument iBase is the cursor number used for the table that pIdx refers
-** to.
-**
-** If such an expression is found, its index in pList->a[] is returned. If
-** no expression is found, -1 is returned.
-*/
-static int findIndexCol(
- Parse *pParse, /* Parse context */
- ExprList *pList, /* Expression list to search */
- int iBase, /* Cursor for table associated with pIdx */
- Index *pIdx, /* Index to match column of */
- int iCol /* Column of index to match */
-){
- int i;
- const char *zColl = pIdx->azColl[iCol];
-
- for(i=0; i<pList->nExpr; i++){
- Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
- if( p->op==TK_COLUMN
- && p->iColumn==pIdx->aiColumn[iCol]
- && p->iTable==iBase
- ){
- CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
- if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
- return i;
- }
- }
- }
-
- return -1;
-}
-
-/*
-** This routine determines if pIdx can be used to assist in processing a
-** DISTINCT qualifier. In other words, it tests whether or not using this
-** index for the outer loop guarantees that rows with equal values for
-** all expressions in the pDistinct list are delivered grouped together.
-**
-** For example, the query
-**
-** SELECT DISTINCT a, b, c FROM tbl WHERE a = ?
-**
-** can benefit from any index on columns "b" and "c".
-*/
-static int isDistinctIndex(
- Parse *pParse, /* Parsing context */
- WhereClause *pWC, /* The WHERE clause */
- Index *pIdx, /* The index being considered */
- int base, /* Cursor number for the table pIdx is on */
- ExprList *pDistinct, /* The DISTINCT expressions */
- int nEqCol /* Number of index columns with == */
-){
- Bitmask mask = 0; /* Mask of unaccounted for pDistinct exprs */
- int i; /* Iterator variable */
-
- assert( pDistinct!=0 );
- if( pIdx->zName==0 || pDistinct->nExpr>=BMS ) return 0;
- testcase( pDistinct->nExpr==BMS-1 );
-
- /* Loop through all the expressions in the distinct list. If any of them
- ** are not simple column references, return early. Otherwise, test if the
- ** WHERE clause contains a "col=X" clause. If it does, the expression
- ** can be ignored. If it does not, and the column does not belong to the
- ** same table as index pIdx, return early. Finally, if there is no
- ** matching "col=X" expression and the column is on the same table as pIdx,
- ** set the corresponding bit in variable mask.
- */
- for(i=0; i<pDistinct->nExpr; i++){
- WhereTerm *pTerm;
- Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
- if( p->op!=TK_COLUMN ) return 0;
- pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
- if( pTerm ){
- Expr *pX = pTerm->pExpr;
- CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
- CollSeq *p2 = sqlite3ExprCollSeq(pParse, p);
- if( p1==p2 ) continue;
- }
- if( p->iTable!=base ) return 0;
- mask |= (((Bitmask)1) << i);
- }
-
- for(i=nEqCol; mask && i<pIdx->nColumn; i++){
- int iExpr = findIndexCol(pParse, pDistinct, base, pIdx, i);
- if( iExpr<0 ) break;
- mask &= ~(((Bitmask)1) << iExpr);
- }
-
- return (mask==0);
-}
-
-
-/*
-** Return true if the DISTINCT expression-list passed as the third argument
-** is redundant. A DISTINCT list is redundant if the database contains a
-** UNIQUE index that guarantees that the result of the query will be distinct
-** anyway.
-*/
-static int isDistinctRedundant(
- Parse *pParse,
- SrcList *pTabList,
- WhereClause *pWC,
- ExprList *pDistinct
-){
- Table *pTab;
- Index *pIdx;
- int i;
- int iBase;
-
- /* If there is more than one table or sub-select in the FROM clause of
- ** this query, then it will not be possible to show that the DISTINCT
- ** clause is redundant. */
- if( pTabList->nSrc!=1 ) return 0;
- iBase = pTabList->a[0].iCursor;
- pTab = pTabList->a[0].pTab;
-
- /* If any of the expressions is an IPK column on table iBase, then return
- ** true. Note: The (p->iTable==iBase) part of this test may be false if the
- ** current SELECT is a correlated sub-query.
- */
- for(i=0; i<pDistinct->nExpr; i++){
- Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
- if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
- }
-
- /* Loop through all indices on the table, checking each to see if it makes
- ** the DISTINCT qualifier redundant. It does so if:
- **
- ** 1. The index is itself UNIQUE, and
- **
- ** 2. All of the columns in the index are either part of the pDistinct
- ** list, or else the WHERE clause contains a term of the form "col=X",
- ** where X is a constant value. The collation sequences of the
- ** comparison and select-list expressions must match those of the index.
- **
- ** 3. All of those index columns for which the WHERE clause does not
- ** contain a "col=X" term are subject to a NOT NULL constraint.
- */
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->onError==OE_None ) continue;
- for(i=0; i<pIdx->nColumn; i++){
- int iCol = pIdx->aiColumn[i];
- if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){
- int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i);
- if( iIdxCol<0 || pTab->aCol[pIdx->aiColumn[i]].notNull==0 ){
- break;
- }
- }
- }
- if( i==pIdx->nColumn ){
- /* This index implies that the DISTINCT qualifier is redundant. */
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
-** Prepare a crude estimate of the logarithm of the input value.
-** The results need not be exact. This is only used for estimating
-** the total cost of performing operations with O(logN) or O(NlogN)
-** complexity. Because N is just a guess, it is no great tragedy if
-** logN is a little off.
-*/
-static double estLog(double N){
- double logN = 1;
- double x = 10;
- while( N>x ){
- logN += 1;
- x *= 10;
- }
- return logN;
-}
-
-/*
-** Two routines for printing the content of an sqlite3_index_info
-** structure. Used for testing and debugging only. If neither
-** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
-** are no-ops.
-*/
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG)
-static void TRACE_IDX_INPUTS(sqlite3_index_info *p){
- int i;
- if( !sqlite3WhereTrace ) return;
- for(i=0; i<p->nConstraint; i++){
- sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n",
- i,
- p->aConstraint[i].iColumn,
- p->aConstraint[i].iTermOffset,
- p->aConstraint[i].op,
- p->aConstraint[i].usable);
- }
- for(i=0; i<p->nOrderBy; i++){
- sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n",
- i,
- p->aOrderBy[i].iColumn,
- p->aOrderBy[i].desc);
- }
-}
-static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){
- int i;
- if( !sqlite3WhereTrace ) return;
- for(i=0; i<p->nConstraint; i++){
- sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n",
- i,
- p->aConstraintUsage[i].argvIndex,
- p->aConstraintUsage[i].omit);
- }
- sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum);
- sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr);
- sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed);
- sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost);
-}
-#else
-#define TRACE_IDX_INPUTS(A)
-#define TRACE_IDX_OUTPUTS(A)
-#endif
-
-/*
-** Required because bestIndex() is called by bestOrClauseIndex()
-*/
-static void bestIndex(WhereBestIdx*);
-
-/*
-** This routine attempts to find an scanning strategy that can be used
-** to optimize an 'OR' expression that is part of a WHERE clause.
-**
-** The table associated with FROM clause term pSrc may be either a
-** regular B-Tree table or a virtual table.
-*/
-static void bestOrClauseIndex(WhereBestIdx *p){
-#ifndef SQLITE_OMIT_OR_OPTIMIZATION
- WhereClause *pWC = p->pWC; /* The WHERE clause */
- struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
- const int iCur = pSrc->iCursor; /* The cursor of the table */
- const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */
- WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */
- WhereTerm *pTerm; /* A single term of the WHERE clause */
-
- /* The OR-clause optimization is disallowed if the INDEXED BY or
- ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */
- if( pSrc->notIndexed || pSrc->pIndex!=0 ){
- return;
- }
- if( pWC->wctrlFlags & WHERE_AND_ONLY ){
- return;
- }
-
- /* Search the WHERE clause terms for a usable WO_OR term. */
- for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
- if( pTerm->eOperator==WO_OR
- && ((pTerm->prereqAll & ~maskSrc) & p->notReady)==0
- && (pTerm->u.pOrInfo->indexable & maskSrc)!=0
- ){
- WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
- WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
- WhereTerm *pOrTerm;
- int flags = WHERE_MULTI_OR;
- double rTotal = 0;
- double nRow = 0;
- Bitmask used = 0;
- WhereBestIdx sBOI;
-
- sBOI = *p;
- sBOI.pOrderBy = 0;
- sBOI.pDistinct = 0;
- sBOI.ppIdxInfo = 0;
- for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
- WHERETRACE(("... Multi-index OR testing for term %d of %d....\n",
- (pOrTerm - pOrWC->a), (pTerm - pWC->a)
- ));
- if( pOrTerm->eOperator==WO_AND ){
- sBOI.pWC = &pOrTerm->u.pAndInfo->wc;
- bestIndex(&sBOI);
- }else if( pOrTerm->leftCursor==iCur ){
- WhereClause tempWC;
- tempWC.pParse = pWC->pParse;
- tempWC.pMaskSet = pWC->pMaskSet;
- tempWC.pOuter = pWC;
- tempWC.op = TK_AND;
- tempWC.a = pOrTerm;
- tempWC.wctrlFlags = 0;
- tempWC.nTerm = 1;
- sBOI.pWC = &tempWC;
- bestIndex(&sBOI);
- }else{
- continue;
- }
- rTotal += sBOI.cost.rCost;
- nRow += sBOI.cost.plan.nRow;
- used |= sBOI.cost.used;
- if( rTotal>=p->cost.rCost ) break;
- }
-
- /* If there is an ORDER BY clause, increase the scan cost to account
- ** for the cost of the sort. */
- if( p->pOrderBy!=0 ){
- WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n",
- rTotal, rTotal+nRow*estLog(nRow)));
- rTotal += nRow*estLog(nRow);
- }
-
- /* If the cost of scanning using this OR term for optimization is
- ** less than the current cost stored in pCost, replace the contents
- ** of pCost. */
- WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow));
- if( rTotal<p->cost.rCost ){
- p->cost.rCost = rTotal;
- p->cost.used = used;
- p->cost.plan.nRow = nRow;
- p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
- p->cost.plan.wsFlags = flags;
- p->cost.plan.u.pTerm = pTerm;
- }
- }
- }
-#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
-}
-
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
-/*
-** Return TRUE if the WHERE clause term pTerm is of a form where it
-** could be used with an index to access pSrc, assuming an appropriate
-** index existed.
-*/
-static int termCanDriveIndex(
- WhereTerm *pTerm, /* WHERE clause term to check */
- struct SrcList_item *pSrc, /* Table we are trying to access */
- Bitmask notReady /* Tables in outer loops of the join */
-){
- char aff;
- if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
- if( pTerm->eOperator!=WO_EQ ) return 0;
- if( (pTerm->prereqRight & notReady)!=0 ) return 0;
- aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
- if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
- return 1;
-}
-#endif
-
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
-/*
-** If the query plan for pSrc specified in pCost is a full table scan
-** and indexing is allows (if there is no NOT INDEXED clause) and it
-** possible to construct a transient index that would perform better
-** than a full table scan even when the cost of constructing the index
-** is taken into account, then alter the query plan to use the
-** transient index.
-*/
-static void bestAutomaticIndex(WhereBestIdx *p){
- Parse *pParse = p->pParse; /* The parsing context */
- WhereClause *pWC = p->pWC; /* The WHERE clause */
- struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
- double nTableRow; /* Rows in the input table */
- double logN; /* log(nTableRow) */
- double costTempIdx; /* per-query cost of the transient index */
- WhereTerm *pTerm; /* A single term of the WHERE clause */
- WhereTerm *pWCEnd; /* End of pWC->a[] */
- Table *pTable; /* Table tht might be indexed */
-
- if( pParse->nQueryLoop<=(double)1 ){
- /* There is no point in building an automatic index for a single scan */
- return;
- }
- if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){
- /* Automatic indices are disabled at run-time */
- return;
- }
- if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0
- && (p->cost.plan.wsFlags & WHERE_COVER_SCAN)==0
- ){
- /* We already have some kind of index in use for this query. */
- return;
- }
- if( pSrc->viaCoroutine ){
- /* Cannot index a co-routine */
- return;
- }
- if( pSrc->notIndexed ){
- /* The NOT INDEXED clause appears in the SQL. */
- return;
- }
- if( pSrc->isCorrelated ){
- /* The source is a correlated sub-query. No point in indexing it. */
- return;
- }
-
- assert( pParse->nQueryLoop >= (double)1 );
- pTable = pSrc->pTab;
- nTableRow = pTable->nRowEst;
- logN = estLog(nTableRow);
- costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1);
- if( costTempIdx>=p->cost.rCost ){
- /* The cost of creating the transient table would be greater than
- ** doing the full table scan */
- return;
- }
-
- /* Search for any equality comparison term */
- pWCEnd = &pWC->a[pWC->nTerm];
- for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
- if( termCanDriveIndex(pTerm, pSrc, p->notReady) ){
- WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n",
- p->cost.rCost, costTempIdx));
- p->cost.rCost = costTempIdx;
- p->cost.plan.nRow = logN + 1;
- p->cost.plan.wsFlags = WHERE_TEMP_INDEX;
- p->cost.used = pTerm->prereqRight;
- break;
- }
- }
-}
-#else
-# define bestAutomaticIndex(A) /* no-op */
-#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
-
-
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
-/*
-** Generate code to construct the Index object for an automatic index
-** and to set up the WhereLevel object pLevel so that the code generator
-** makes use of the automatic index.
-*/
-static void constructAutomaticIndex(
- Parse *pParse, /* The parsing context */
- WhereClause *pWC, /* The WHERE clause */
- struct SrcList_item *pSrc, /* The FROM clause term to get the next index */
- Bitmask notReady, /* Mask of cursors that are not available */
- WhereLevel *pLevel /* Write new index here */
-){
- int nColumn; /* Number of columns in the constructed index */
- WhereTerm *pTerm; /* A single term of the WHERE clause */
- WhereTerm *pWCEnd; /* End of pWC->a[] */
- int nByte; /* Byte of memory needed for pIdx */
- Index *pIdx; /* Object describing the transient index */
- Vdbe *v; /* Prepared statement under construction */
- int addrInit; /* Address of the initialization bypass jump */
- Table *pTable; /* The table being indexed */
- KeyInfo *pKeyinfo; /* Key information for the index */
- int addrTop; /* Top of the index fill loop */
- int regRecord; /* Register holding an index record */
- int n; /* Column counter */
- int i; /* Loop counter */
- int mxBitCol; /* Maximum column in pSrc->colUsed */
- CollSeq *pColl; /* Collating sequence to on a column */
- Bitmask idxCols; /* Bitmap of columns used for indexing */
- Bitmask extraCols; /* Bitmap of additional columns */
-
- /* Generate code to skip over the creation and initialization of the
- ** transient index on 2nd and subsequent iterations of the loop. */
- v = pParse->pVdbe;
- assert( v!=0 );
- addrInit = sqlite3CodeOnce(pParse);
-
- /* Count the number of columns that will be added to the index
- ** and used to match WHERE clause constraints */
- nColumn = 0;
- pTable = pSrc->pTab;
- pWCEnd = &pWC->a[pWC->nTerm];
- idxCols = 0;
- for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
- if( termCanDriveIndex(pTerm, pSrc, notReady) ){
- int iCol = pTerm->u.leftColumn;
- Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
- testcase( iCol==BMS );
- testcase( iCol==BMS-1 );
- if( (idxCols & cMask)==0 ){
- nColumn++;
- idxCols |= cMask;
- }
- }
- }
- assert( nColumn>0 );
- pLevel->plan.nEq = nColumn;
-
- /* Count the number of additional columns needed to create a
- ** covering index. A "covering index" is an index that contains all
- ** columns that are needed by the query. With a covering index, the
- ** original table never needs to be accessed. Automatic indices must
- ** be a covering index because the index will not be updated if the
- ** original table changes and the index and table cannot both be used
- ** if they go out of sync.
- */
- extraCols = pSrc->colUsed & (~idxCols | (((Bitmask)1)<<(BMS-1)));
- mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol;
- testcase( pTable->nCol==BMS-1 );
- testcase( pTable->nCol==BMS-2 );
- for(i=0; i<mxBitCol; i++){
- if( extraCols & (((Bitmask)1)<<i) ) nColumn++;
- }
- if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){
- nColumn += pTable->nCol - BMS + 1;
- }
- pLevel->plan.wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WO_EQ;
-
- /* Construct the Index object to describe this index */
- nByte = sizeof(Index);
- nByte += nColumn*sizeof(int); /* Index.aiColumn */
- nByte += nColumn*sizeof(char*); /* Index.azColl */
- nByte += nColumn; /* Index.aSortOrder */
- pIdx = sqlite3DbMallocZero(pParse->db, nByte);
- if( pIdx==0 ) return;
- pLevel->plan.u.pIdx = pIdx;
- pIdx->azColl = (char**)&pIdx[1];
- pIdx->aiColumn = (int*)&pIdx->azColl[nColumn];
- pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn];
- pIdx->zName = "auto-index";
- pIdx->nColumn = nColumn;
- pIdx->pTable = pTable;
- n = 0;
- idxCols = 0;
- for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
- if( termCanDriveIndex(pTerm, pSrc, notReady) ){
- int iCol = pTerm->u.leftColumn;
- Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
- if( (idxCols & cMask)==0 ){
- Expr *pX = pTerm->pExpr;
- idxCols |= cMask;
- pIdx->aiColumn[n] = pTerm->u.leftColumn;
- pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
- pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY";
- n++;
- }
- }
- }
- assert( (u32)n==pLevel->plan.nEq );
-
- /* Add additional columns needed to make the automatic index into
- ** a covering index */
- for(i=0; i<mxBitCol; i++){
- if( extraCols & (((Bitmask)1)<<i) ){
- pIdx->aiColumn[n] = i;
- pIdx->azColl[n] = "BINARY";
- n++;
- }
- }
- if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){
- for(i=BMS-1; i<pTable->nCol; i++){
- pIdx->aiColumn[n] = i;
- pIdx->azColl[n] = "BINARY";
- n++;
- }
- }
- assert( n==nColumn );
-
- /* Create the automatic index */
- pKeyinfo = sqlite3IndexKeyinfo(pParse, pIdx);
- assert( pLevel->iIdxCur>=0 );
- sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
- (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "for %s", pTable->zName));
-
- /* Fill the automatic index with content */
- addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
- regRecord = sqlite3GetTempReg(pParse);
- sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
- sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
- sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
- sqlite3VdbeJumpHere(v, addrTop);
- sqlite3ReleaseTempReg(pParse, regRecord);
-
- /* Jump here when skipping the initialization */
- sqlite3VdbeJumpHere(v, addrInit);
-}
-#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-/*
-** Allocate and populate an sqlite3_index_info structure. It is the
-** responsibility of the caller to eventually release the structure
-** by passing the pointer returned by this function to sqlite3_free().
-*/
-static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
- Parse *pParse = p->pParse;
- WhereClause *pWC = p->pWC;
- struct SrcList_item *pSrc = p->pSrc;
- ExprList *pOrderBy = p->pOrderBy;
- int i, j;
- int nTerm;
- struct sqlite3_index_constraint *pIdxCons;
- struct sqlite3_index_orderby *pIdxOrderBy;
- struct sqlite3_index_constraint_usage *pUsage;
- WhereTerm *pTerm;
- int nOrderBy;
- sqlite3_index_info *pIdxInfo;
-
- WHERETRACE(("Recomputing index info for %s...\n", pSrc->pTab->zName));
-
- /* Count the number of possible WHERE clause constraints referring
- ** to this virtual table */
- for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
- if( pTerm->leftCursor != pSrc->iCursor ) continue;
- assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
- testcase( pTerm->eOperator==WO_IN );
- testcase( pTerm->eOperator==WO_ISNULL );
- if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
- if( pTerm->wtFlags & TERM_VNULL ) continue;
- nTerm++;
- }
-
- /* If the ORDER BY clause contains only columns in the current
- ** virtual table then allocate space for the aOrderBy part of
- ** the sqlite3_index_info structure.
- */
- nOrderBy = 0;
- if( pOrderBy ){
- int n = pOrderBy->nExpr;
- for(i=0; i<n; i++){
- Expr *pExpr = pOrderBy->a[i].pExpr;
- if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
- }
- if( i==n){
- nOrderBy = n;
- }
- }
-
- /* Allocate the sqlite3_index_info structure
- */
- pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
- + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
- + sizeof(*pIdxOrderBy)*nOrderBy );
- if( pIdxInfo==0 ){
- sqlite3ErrorMsg(pParse, "out of memory");
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- return 0;
- }
-
- /* Initialize the structure. The sqlite3_index_info structure contains
- ** many fields that are declared "const" to prevent xBestIndex from
- ** changing them. We have to do some funky casting in order to
- ** initialize those fields.
- */
- pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1];
- pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
- pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
- *(int*)&pIdxInfo->nConstraint = nTerm;
- *(int*)&pIdxInfo->nOrderBy = nOrderBy;
- *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons;
- *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy;
- *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
- pUsage;
-
- for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
- if( pTerm->leftCursor != pSrc->iCursor ) continue;
- assert( (pTerm->eOperator&(pTerm->eOperator-1))==0 );
- testcase( pTerm->eOperator==WO_IN );
- testcase( pTerm->eOperator==WO_ISNULL );
- if( pTerm->eOperator & (WO_IN|WO_ISNULL) ) continue;
- if( pTerm->wtFlags & TERM_VNULL ) continue;
- pIdxCons[j].iColumn = pTerm->u.leftColumn;
- pIdxCons[j].iTermOffset = i;
- pIdxCons[j].op = (u8)pTerm->eOperator;
- /* The direct assignment in the previous line is possible only because
- ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
- ** following asserts verify this fact. */
- assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
- assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
- assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
- assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
- assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
- assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
- assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
- j++;
- }
- for(i=0; i<nOrderBy; i++){
- Expr *pExpr = pOrderBy->a[i].pExpr;
- pIdxOrderBy[i].iColumn = pExpr->iColumn;
- pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
- }
-
- return pIdxInfo;
-}
-
-/*
-** The table object reference passed as the second argument to this function
-** must represent a virtual table. This function invokes the xBestIndex()
-** method of the virtual table with the sqlite3_index_info pointer passed
-** as the argument.
-**
-** If an error occurs, pParse is populated with an error message and a
-** non-zero value is returned. Otherwise, 0 is returned and the output
-** part of the sqlite3_index_info structure is left populated.
-**
-** Whether or not an error is returned, it is the responsibility of the
-** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
-** that this is required.
-*/
-static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
- sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
- int i;
- int rc;
-
- WHERETRACE(("xBestIndex for %s\n", pTab->zName));
- TRACE_IDX_INPUTS(p);
- rc = pVtab->pModule->xBestIndex(pVtab, p);
- TRACE_IDX_OUTPUTS(p);
-
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM ){
- pParse->db->mallocFailed = 1;
- }else if( !pVtab->zErrMsg ){
- sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
- }else{
- sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
- }
- }
- sqlite3_free(pVtab->zErrMsg);
- pVtab->zErrMsg = 0;
-
- for(i=0; i<p->nConstraint; i++){
- if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
- sqlite3ErrorMsg(pParse,
- "table %s: xBestIndex returned an invalid plan", pTab->zName);
- }
- }
-
- return pParse->nErr;
-}
-
-
-/*
-** Compute the best index for a virtual table.
-**
-** The best index is computed by the xBestIndex method of the virtual
-** table module. This routine is really just a wrapper that sets up
-** the sqlite3_index_info structure that is used to communicate with
-** xBestIndex.
-**
-** In a join, this routine might be called multiple times for the
-** same virtual table. The sqlite3_index_info structure is created
-** and initialized on the first invocation and reused on all subsequent
-** invocations. The sqlite3_index_info structure is also used when
-** code is generated to access the virtual table. The whereInfoDelete()
-** routine takes care of freeing the sqlite3_index_info structure after
-** everybody has finished with it.
-*/
-static void bestVirtualIndex(WhereBestIdx *p){
- Parse *pParse = p->pParse; /* The parsing context */
- WhereClause *pWC = p->pWC; /* The WHERE clause */
- struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
- Table *pTab = pSrc->pTab;
- sqlite3_index_info *pIdxInfo;
- struct sqlite3_index_constraint *pIdxCons;
- struct sqlite3_index_constraint_usage *pUsage;
- WhereTerm *pTerm;
- int i, j;
- int nOrderBy;
- double rCost;
-
- /* Make sure wsFlags is initialized to some sane value. Otherwise, if the
- ** malloc in allocateIndexInfo() fails and this function returns leaving
- ** wsFlags in an uninitialized state, the caller may behave unpredictably.
- */
- memset(&p->cost, 0, sizeof(p->cost));
- p->cost.plan.wsFlags = WHERE_VIRTUALTABLE;
-
- /* If the sqlite3_index_info structure has not been previously
- ** allocated and initialized, then allocate and initialize it now.
- */
- pIdxInfo = *p->ppIdxInfo;
- if( pIdxInfo==0 ){
- *p->ppIdxInfo = pIdxInfo = allocateIndexInfo(p);
- }
- if( pIdxInfo==0 ){
- return;
- }
-
- /* At this point, the sqlite3_index_info structure that pIdxInfo points
- ** to will have been initialized, either during the current invocation or
- ** during some prior invocation. Now we just have to customize the
- ** details of pIdxInfo for the current invocation and pass it to
- ** xBestIndex.
- */
-
- /* The module name must be defined. Also, by this point there must
- ** be a pointer to an sqlite3_vtab structure. Otherwise
- ** sqlite3ViewGetColumnNames() would have picked up the error.
- */
- assert( pTab->azModuleArg && pTab->azModuleArg[0] );
- assert( sqlite3GetVTable(pParse->db, pTab) );
-
- /* Set the aConstraint[].usable fields and initialize all
- ** output variables to zero.
- **
- ** aConstraint[].usable is true for constraints where the right-hand
- ** side contains only references to tables to the left of the current
- ** table. In other words, if the constraint is of the form:
- **
- ** column = expr
- **
- ** and we are evaluating a join, then the constraint on column is
- ** only valid if all tables referenced in expr occur to the left
- ** of the table containing column.
- **
- ** The aConstraints[] array contains entries for all constraints
- ** on the current table. That way we only have to compute it once
- ** even though we might try to pick the best index multiple times.
- ** For each attempt at picking an index, the order of tables in the
- ** join might be different so we have to recompute the usable flag
- ** each time.
- */
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
- pUsage = pIdxInfo->aConstraintUsage;
- for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
- j = pIdxCons->iTermOffset;
- pTerm = &pWC->a[j];
- pIdxCons->usable = (pTerm->prereqRight&p->notReady) ? 0 : 1;
- }
- memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
- if( pIdxInfo->needToFreeIdxStr ){
- sqlite3_free(pIdxInfo->idxStr);
- }
- pIdxInfo->idxStr = 0;
- pIdxInfo->idxNum = 0;
- pIdxInfo->needToFreeIdxStr = 0;
- pIdxInfo->orderByConsumed = 0;
- /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
- pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
- nOrderBy = pIdxInfo->nOrderBy;
- if( !p->pOrderBy ){
- pIdxInfo->nOrderBy = 0;
- }
-
- if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
- return;
- }
-
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
- for(i=0; i<pIdxInfo->nConstraint; i++){
- if( pUsage[i].argvIndex>0 ){
- p->cost.used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
- }
- }
-
- /* If there is an ORDER BY clause, and the selected virtual table index
- ** does not satisfy it, increase the cost of the scan accordingly. This
- ** matches the processing for non-virtual tables in bestBtreeIndex().
- */
- rCost = pIdxInfo->estimatedCost;
- if( p->pOrderBy && pIdxInfo->orderByConsumed==0 ){
- rCost += estLog(rCost)*rCost;
- }
-
- /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the
- ** inital value of lowestCost in this loop. If it is, then the
- ** (cost<lowestCost) test below will never be true.
- **
- ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT
- ** is defined.
- */
- if( (SQLITE_BIG_DBL/((double)2))<rCost ){
- p->cost.rCost = (SQLITE_BIG_DBL/((double)2));
- }else{
- p->cost.rCost = rCost;
- }
- p->cost.plan.u.pVtabIdx = pIdxInfo;
- if( pIdxInfo->orderByConsumed ){
- p->cost.plan.wsFlags |= WHERE_ORDERED;
- p->cost.plan.nOBSat = nOrderBy;
- }else{
- p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
- }
- p->cost.plan.nEq = 0;
- pIdxInfo->nOrderBy = nOrderBy;
-
- /* Try to find a more efficient access pattern by using multiple indexes
- ** to optimize an OR expression within the WHERE clause.
- */
- bestOrClauseIndex(p);
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifdef SQLITE_ENABLE_STAT3
-/*
-** Estimate the location of a particular key among all keys in an
-** index. Store the results in aStat as follows:
-**
-** aStat[0] Est. number of rows less than pVal
-** aStat[1] Est. number of rows equal to pVal
-**
-** Return SQLITE_OK on success.
-*/
-static int whereKeyStats(
- Parse *pParse, /* Database connection */
- Index *pIdx, /* Index to consider domain of */
- sqlite3_value *pVal, /* Value to consider */
- int roundUp, /* Round up if true. Round down if false */
- tRowcnt *aStat /* OUT: stats written here */
-){
- tRowcnt n;
- IndexSample *aSample;
- int i, eType;
- int isEq = 0;
- i64 v;
- double r, rS;
-
- assert( roundUp==0 || roundUp==1 );
- assert( pIdx->nSample>0 );
- if( pVal==0 ) return SQLITE_ERROR;
- n = pIdx->aiRowEst[0];
- aSample = pIdx->aSample;
- eType = sqlite3_value_type(pVal);
-
- if( eType==SQLITE_INTEGER ){
- v = sqlite3_value_int64(pVal);
- r = (i64)v;
- for(i=0; i<pIdx->nSample; i++){
- if( aSample[i].eType==SQLITE_NULL ) continue;
- if( aSample[i].eType>=SQLITE_TEXT ) break;
- if( aSample[i].eType==SQLITE_INTEGER ){
- if( aSample[i].u.i>=v ){
- isEq = aSample[i].u.i==v;
- break;
- }
- }else{
- assert( aSample[i].eType==SQLITE_FLOAT );
- if( aSample[i].u.r>=r ){
- isEq = aSample[i].u.r==r;
- break;
- }
- }
- }
- }else if( eType==SQLITE_FLOAT ){
- r = sqlite3_value_double(pVal);
- for(i=0; i<pIdx->nSample; i++){
- if( aSample[i].eType==SQLITE_NULL ) continue;
- if( aSample[i].eType>=SQLITE_TEXT ) break;
- if( aSample[i].eType==SQLITE_FLOAT ){
- rS = aSample[i].u.r;
- }else{
- rS = aSample[i].u.i;
- }
- if( rS>=r ){
- isEq = rS==r;
- break;
- }
- }
- }else if( eType==SQLITE_NULL ){
- i = 0;
- if( aSample[0].eType==SQLITE_NULL ) isEq = 1;
- }else{
- assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
- for(i=0; i<pIdx->nSample; i++){
- if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){
- break;
- }
- }
- if( i<pIdx->nSample ){
- sqlite3 *db = pParse->db;
- CollSeq *pColl;
- const u8 *z;
- if( eType==SQLITE_BLOB ){
- z = (const u8 *)sqlite3_value_blob(pVal);
- pColl = db->pDfltColl;
- assert( pColl->enc==SQLITE_UTF8 );
- }else{
- pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl);
- if( pColl==0 ){
- return SQLITE_ERROR;
- }
- z = (const u8 *)sqlite3ValueText(pVal, pColl->enc);
- if( !z ){
- return SQLITE_NOMEM;
- }
- assert( z && pColl && pColl->xCmp );
- }
- n = sqlite3ValueBytes(pVal, pColl->enc);
-
- for(; i<pIdx->nSample; i++){
- int c;
- int eSampletype = aSample[i].eType;
- if( eSampletype<eType ) continue;
- if( eSampletype!=eType ) break;
-#ifndef SQLITE_OMIT_UTF16
- if( pColl->enc!=SQLITE_UTF8 ){
- int nSample;
- char *zSample = sqlite3Utf8to16(
- db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample
- );
- if( !zSample ){
- assert( db->mallocFailed );
- return SQLITE_NOMEM;
- }
- c = pColl->xCmp(pColl->pUser, nSample, zSample, n, z);
- sqlite3DbFree(db, zSample);
- }else
-#endif
- {
- c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z);
- }
- if( c>=0 ){
- if( c==0 ) isEq = 1;
- break;
- }
- }
- }
- }
-
- /* At this point, aSample[i] is the first sample that is greater than
- ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less
- ** than pVal. If aSample[i]==pVal, then isEq==1.
- */
- if( isEq ){
- assert( i<pIdx->nSample );
- aStat[0] = aSample[i].nLt;
- aStat[1] = aSample[i].nEq;
- }else{
- tRowcnt iLower, iUpper, iGap;
- if( i==0 ){
- iLower = 0;
- iUpper = aSample[0].nLt;
- }else{
- iUpper = i>=pIdx->nSample ? n : aSample[i].nLt;
- iLower = aSample[i-1].nEq + aSample[i-1].nLt;
- }
- aStat[1] = pIdx->avgEq;
- if( iLower>=iUpper ){
- iGap = 0;
- }else{
- iGap = iUpper - iLower;
- }
- if( roundUp ){
- iGap = (iGap*2)/3;
- }else{
- iGap = iGap/3;
- }
- aStat[0] = iLower + iGap;
- }
- return SQLITE_OK;
-}
-#endif /* SQLITE_ENABLE_STAT3 */
-
-/*
-** If expression pExpr represents a literal value, set *pp to point to
-** an sqlite3_value structure containing the same value, with affinity
-** aff applied to it, before returning. It is the responsibility of the
-** caller to eventually release this structure by passing it to
-** sqlite3ValueFree().
-**
-** If the current parse is a recompile (sqlite3Reprepare()) and pExpr
-** is an SQL variable that currently has a non-NULL value bound to it,
-** create an sqlite3_value structure containing this value, again with
-** affinity aff applied to it, instead.
-**
-** If neither of the above apply, set *pp to NULL.
-**
-** If an error occurs, return an error code. Otherwise, SQLITE_OK.
-*/
-#ifdef SQLITE_ENABLE_STAT3
-static int valueFromExpr(
- Parse *pParse,
- Expr *pExpr,
- u8 aff,
- sqlite3_value **pp
-){
- if( pExpr->op==TK_VARIABLE
- || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
- ){
- int iVar = pExpr->iColumn;
- sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
- *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
- return SQLITE_OK;
- }
- return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
-}
-#endif
-
-/*
-** This function is used to estimate the number of rows that will be visited
-** by scanning an index for a range of values. The range may have an upper
-** bound, a lower bound, or both. The WHERE clause terms that set the upper
-** and lower bounds are represented by pLower and pUpper respectively. For
-** example, assuming that index p is on t1(a):
-**
-** ... FROM t1 WHERE a > ? AND a < ? ...
-** |_____| |_____|
-** | |
-** pLower pUpper
-**
-** If either of the upper or lower bound is not present, then NULL is passed in
-** place of the corresponding WhereTerm.
-**
-** The nEq parameter is passed the index of the index column subject to the
-** range constraint. Or, equivalently, the number of equality constraints
-** optimized by the proposed index scan. For example, assuming index p is
-** on t1(a, b), and the SQL query is:
-**
-** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
-**
-** then nEq should be passed the value 1 (as the range restricted column,
-** b, is the second left-most column of the index). Or, if the query is:
-**
-** ... FROM t1 WHERE a > ? AND a < ? ...
-**
-** then nEq should be passed 0.
-**
-** The returned value is an integer divisor to reduce the estimated
-** search space. A return value of 1 means that range constraints are
-** no help at all. A return value of 2 means range constraints are
-** expected to reduce the search space by half. And so forth...
-**
-** In the absence of sqlite_stat3 ANALYZE data, each range inequality
-** reduces the search space by a factor of 4. Hence a single constraint (x>?)
-** results in a return of 4 and a range constraint (x>? AND x<?) results
-** in a return of 16.
-*/
-static int whereRangeScanEst(
- Parse *pParse, /* Parsing & code generating context */
- Index *p, /* The index containing the range-compared column; "x" */
- int nEq, /* index into p->aCol[] of the range-compared column */
- WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
- WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
- double *pRangeDiv /* OUT: Reduce search space by this divisor */
-){
- int rc = SQLITE_OK;
-
-#ifdef SQLITE_ENABLE_STAT3
-
- if( nEq==0 && p->nSample ){
- sqlite3_value *pRangeVal;
- tRowcnt iLower = 0;
- tRowcnt iUpper = p->aiRowEst[0];
- tRowcnt a[2];
- u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;
-
- if( pLower ){
- Expr *pExpr = pLower->pExpr->pRight;
- rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
- assert( pLower->eOperator==WO_GT || pLower->eOperator==WO_GE );
- if( rc==SQLITE_OK
- && whereKeyStats(pParse, p, pRangeVal, 0, a)==SQLITE_OK
- ){
- iLower = a[0];
- if( pLower->eOperator==WO_GT ) iLower += a[1];
- }
- sqlite3ValueFree(pRangeVal);
- }
- if( rc==SQLITE_OK && pUpper ){
- Expr *pExpr = pUpper->pExpr->pRight;
- rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
- assert( pUpper->eOperator==WO_LT || pUpper->eOperator==WO_LE );
- if( rc==SQLITE_OK
- && whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK
- ){
- iUpper = a[0];
- if( pUpper->eOperator==WO_LE ) iUpper += a[1];
- }
- sqlite3ValueFree(pRangeVal);
- }
- if( rc==SQLITE_OK ){
- if( iUpper<=iLower ){
- *pRangeDiv = (double)p->aiRowEst[0];
- }else{
- *pRangeDiv = (double)p->aiRowEst[0]/(double)(iUpper - iLower);
- }
- WHERETRACE(("range scan regions: %u..%u div=%g\n",
- (u32)iLower, (u32)iUpper, *pRangeDiv));
- return SQLITE_OK;
- }
- }
-#else
- UNUSED_PARAMETER(pParse);
- UNUSED_PARAMETER(p);
- UNUSED_PARAMETER(nEq);
-#endif
- assert( pLower || pUpper );
- *pRangeDiv = (double)1;
- if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= (double)4;
- if( pUpper ) *pRangeDiv *= (double)4;
- return rc;
-}
-
-#ifdef SQLITE_ENABLE_STAT3
-/*
-** Estimate the number of rows that will be returned based on
-** an equality constraint x=VALUE and where that VALUE occurs in
-** the histogram data. This only works when x is the left-most
-** column of an index and sqlite_stat3 histogram data is available
-** for that index. When pExpr==NULL that means the constraint is
-** "x IS NULL" instead of "x=VALUE".
-**
-** Write the estimated row count into *pnRow and return SQLITE_OK.
-** If unable to make an estimate, leave *pnRow unchanged and return
-** non-zero.
-**
-** This routine can fail if it is unable to load a collating sequence
-** required for string comparison, or if unable to allocate memory
-** for a UTF conversion required for comparison. The error is stored
-** in the pParse structure.
-*/
-static int whereEqualScanEst(
- Parse *pParse, /* Parsing & code generating context */
- Index *p, /* The index whose left-most column is pTerm */
- Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
- double *pnRow /* Write the revised row estimate here */
-){
- sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */
- u8 aff; /* Column affinity */
- int rc; /* Subfunction return code */
- tRowcnt a[2]; /* Statistics */
-
- assert( p->aSample!=0 );
- assert( p->nSample>0 );
- aff = p->pTable->aCol[p->aiColumn[0]].affinity;
- if( pExpr ){
- rc = valueFromExpr(pParse, pExpr, aff, &pRhs);
- if( rc ) goto whereEqualScanEst_cancel;
- }else{
- pRhs = sqlite3ValueNew(pParse->db);
- }
- if( pRhs==0 ) return SQLITE_NOTFOUND;
- rc = whereKeyStats(pParse, p, pRhs, 0, a);
- if( rc==SQLITE_OK ){
- WHERETRACE(("equality scan regions: %d\n", (int)a[1]));
- *pnRow = a[1];
- }
-whereEqualScanEst_cancel:
- sqlite3ValueFree(pRhs);
- return rc;
-}
-#endif /* defined(SQLITE_ENABLE_STAT3) */
-
-#ifdef SQLITE_ENABLE_STAT3
-/*
-** Estimate the number of rows that will be returned based on
-** an IN constraint where the right-hand side of the IN operator
-** is a list of values. Example:
-**
-** WHERE x IN (1,2,3,4)
-**
-** Write the estimated row count into *pnRow and return SQLITE_OK.
-** If unable to make an estimate, leave *pnRow unchanged and return
-** non-zero.
-**
-** This routine can fail if it is unable to load a collating sequence
-** required for string comparison, or if unable to allocate memory
-** for a UTF conversion required for comparison. The error is stored
-** in the pParse structure.
-*/
-static int whereInScanEst(
- Parse *pParse, /* Parsing & code generating context */
- Index *p, /* The index whose left-most column is pTerm */
- ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
- double *pnRow /* Write the revised row estimate here */
-){
- int rc = SQLITE_OK; /* Subfunction return code */
- double nEst; /* Number of rows for a single term */
- double nRowEst = (double)0; /* New estimate of the number of rows */
- int i; /* Loop counter */
-
- assert( p->aSample!=0 );
- for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
- nEst = p->aiRowEst[0];
- rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst);
- nRowEst += nEst;
- }
- if( rc==SQLITE_OK ){
- if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
- *pnRow = nRowEst;
- WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
- }
- return rc;
-}
-#endif /* defined(SQLITE_ENABLE_STAT3) */
-
-/*
-** Check to see if column iCol of the table with cursor iTab will appear
-** in sorted order according to the current query plan.
-**
-** Return values:
-**
-** 0 iCol is not ordered
-** 1 iCol has only a single value
-** 2 iCol is in ASC order
-** 3 iCol is in DESC order
-*/
-static int isOrderedColumn(
- WhereBestIdx *p,
- int iTab,
- int iCol
-){
- int i, j;
- WhereLevel *pLevel = &p->aLevel[p->i-1];
- Index *pIdx;
- u8 sortOrder;
- for(i=p->i-1; i>=0; i--, pLevel--){
- if( pLevel->iTabCur!=iTab ) continue;
- if( (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
- return 1;
- }
- assert( (pLevel->plan.wsFlags & WHERE_ORDERED)!=0 );
- if( (pIdx = pLevel->plan.u.pIdx)!=0 ){
- if( iCol<0 ){
- sortOrder = 0;
- testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
- }else{
- int n = pIdx->nColumn;
- for(j=0; j<n; j++){
- if( iCol==pIdx->aiColumn[j] ) break;
- }
- if( j>=n ) return 0;
- sortOrder = pIdx->aSortOrder[j];
- testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
- }
- }else{
- if( iCol!=(-1) ) return 0;
- sortOrder = 0;
- testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
- }
- if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ){
- assert( sortOrder==0 || sortOrder==1 );
- testcase( sortOrder==1 );
- sortOrder = 1 - sortOrder;
- }
- return sortOrder+2;
- }
- return 0;
-}
-
-/*
-** This routine decides if pIdx can be used to satisfy the ORDER BY
-** clause, either in whole or in part. The return value is the
-** cumulative number of terms in the ORDER BY clause that are satisfied
-** by the index pIdx and other indices in outer loops.
-**
-** The table being queried has a cursor number of "base". pIdx is the
-** index that is postulated for use to access the table.
-**
-** The *pbRev value is set to 0 order 1 depending on whether or not
-** pIdx should be run in the forward order or in reverse order.
-*/
-static int isSortingIndex(
- WhereBestIdx *p, /* Best index search context */
- Index *pIdx, /* The index we are testing */
- int base, /* Cursor number for the table to be sorted */
- int *pbRev /* Set to 1 for reverse-order scan of pIdx */
-){
- int i; /* Number of pIdx terms used */
- int j; /* Number of ORDER BY terms satisfied */
- int sortOrder = 2; /* 0: forward. 1: backward. 2: unknown */
- int nTerm; /* Number of ORDER BY terms */
- struct ExprList_item *pOBItem;/* A term of the ORDER BY clause */
- Table *pTab = pIdx->pTable; /* Table that owns index pIdx */
- ExprList *pOrderBy; /* The ORDER BY clause */
- Parse *pParse = p->pParse; /* Parser context */
- sqlite3 *db = pParse->db; /* Database connection */
- int nPriorSat; /* ORDER BY terms satisfied by outer loops */
- int seenRowid = 0; /* True if an ORDER BY rowid term is seen */
- int uniqueNotNull; /* pIdx is UNIQUE with all terms are NOT NULL */
-
- if( p->i==0 ){
- nPriorSat = 0;
- }else{
- nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
- if( (p->aLevel[p->i-1].plan.wsFlags & WHERE_ORDERED)==0 ){
- /* This loop cannot be ordered unless the next outer loop is
- ** also ordered */
- return nPriorSat;
- }
- if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ){
- /* Only look at the outer-most loop if the OrderByIdxJoin
- ** optimization is disabled */
- return nPriorSat;
- }
- }
- pOrderBy = p->pOrderBy;
- assert( pOrderBy!=0 );
- if( pIdx->bUnordered ){
- /* Hash indices (indicated by the "unordered" tag on sqlite_stat1) cannot
- ** be used for sorting */
- return nPriorSat;
- }
- nTerm = pOrderBy->nExpr;
- uniqueNotNull = pIdx->onError!=OE_None;
- assert( nTerm>0 );
-
- /* Argument pIdx must either point to a 'real' named index structure,
- ** or an index structure allocated on the stack by bestBtreeIndex() to
- ** represent the rowid index that is part of every table. */
- assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) );
-
- /* Match terms of the ORDER BY clause against columns of
- ** the index.
- **
- ** Note that indices have pIdx->nColumn regular columns plus
- ** one additional column containing the rowid. The rowid column
- ** of the index is also allowed to match against the ORDER BY
- ** clause.
- */
- j = nPriorSat;
- for(i=0,pOBItem=&pOrderBy->a[j]; j<nTerm && i<=pIdx->nColumn; i++){
- Expr *pOBExpr; /* The expression of the ORDER BY pOBItem */
- CollSeq *pColl; /* The collating sequence of pOBExpr */
- int termSortOrder; /* Sort order for this term */
- int iColumn; /* The i-th column of the index. -1 for rowid */
- int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */
- int isEq; /* Subject to an == or IS NULL constraint */
- int isMatch; /* ORDER BY term matches the index term */
- const char *zColl; /* Name of collating sequence for i-th index term */
- WhereTerm *pConstraint; /* A constraint in the WHERE clause */
-
- /* If the next term of the ORDER BY clause refers to anything other than
- ** a column in the "base" table, then this index will not be of any
- ** further use in handling the ORDER BY. */
- pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
- if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
- break;
- }
-
- /* Find column number and collating sequence for the next entry
- ** in the index */
- if( pIdx->zName && i<pIdx->nColumn ){
- iColumn = pIdx->aiColumn[i];
- if( iColumn==pIdx->pTable->iPKey ){
- iColumn = -1;
- }
- iSortOrder = pIdx->aSortOrder[i];
- zColl = pIdx->azColl[i];
- assert( zColl!=0 );
- }else{
- iColumn = -1;
- iSortOrder = 0;
- zColl = 0;
- }
-
- /* Check to see if the column number and collating sequence of the
- ** index match the column number and collating sequence of the ORDER BY
- ** clause entry. Set isMatch to 1 if they both match. */
- if( pOBExpr->iColumn==iColumn ){
- if( zColl ){
- pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
- if( !pColl ) pColl = db->pDfltColl;
- isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
- }else{
- isMatch = 1;
- }
- }else{
- isMatch = 0;
- }
-
- /* termSortOrder is 0 or 1 for whether or not the access loop should
- ** run forward or backwards (respectively) in order to satisfy this
- ** term of the ORDER BY clause. */
- assert( pOBItem->sortOrder==0 || pOBItem->sortOrder==1 );
- assert( iSortOrder==0 || iSortOrder==1 );
- termSortOrder = iSortOrder ^ pOBItem->sortOrder;
-
- /* If X is the column in the index and ORDER BY clause, check to see
- ** if there are any X= or X IS NULL constraints in the WHERE clause. */
- pConstraint = findTerm(p->pWC, base, iColumn, p->notReady,
- WO_EQ|WO_ISNULL|WO_IN, pIdx);
- if( pConstraint==0 ){
- isEq = 0;
- }else if( pConstraint->eOperator==WO_IN ){
- /* Constraints of the form: "X IN ..." cannot be used with an ORDER BY
- ** because we do not know in what order the values on the RHS of the IN
- ** operator will occur. */
- break;
- }else if( pConstraint->eOperator==WO_ISNULL ){
- uniqueNotNull = 0;
- isEq = 1; /* "X IS NULL" means X has only a single value */
- }else if( pConstraint->prereqRight==0 ){
- isEq = 1; /* Constraint "X=constant" means X has only a single value */
- }else{
- Expr *pRight = pConstraint->pExpr->pRight;
- if( pRight->op==TK_COLUMN ){
- WHERETRACE((" .. isOrderedColumn(tab=%d,col=%d)",
- pRight->iTable, pRight->iColumn));
- isEq = isOrderedColumn(p, pRight->iTable, pRight->iColumn);
- WHERETRACE((" -> isEq=%d\n", isEq));
-
- /* If the constraint is of the form X=Y where Y is an ordered value
- ** in an outer loop, then make sure the sort order of Y matches the
- ** sort order required for X. */
- if( isMatch && isEq>=2 && isEq!=pOBItem->sortOrder+2 ){
- testcase( isEq==2 );
- testcase( isEq==3 );
- break;
- }
- }else{
- isEq = 0; /* "X=expr" places no ordering constraints on X */
- }
- }
- if( !isMatch ){
- if( isEq==0 ){
- break;
- }else{
- continue;
- }
- }else if( isEq!=1 ){
- if( sortOrder==2 ){
- sortOrder = termSortOrder;
- }else if( termSortOrder!=sortOrder ){
- break;
- }
- }
- j++;
- pOBItem++;
- if( iColumn<0 ){
- seenRowid = 1;
- break;
- }else if( pTab->aCol[iColumn].notNull==0 && isEq!=1 ){
- testcase( isEq==0 );
- testcase( isEq==2 );
- testcase( isEq==3 );
- uniqueNotNull = 0;
- }
- }
-
- /* If we have not found at least one ORDER BY term that matches the
- ** index, then show no progress. */
- if( pOBItem==&pOrderBy->a[nPriorSat] ) return nPriorSat;
-
- /* Return the necessary scan order back to the caller */
- *pbRev = sortOrder & 1;
-
- /* If there was an "ORDER BY rowid" term that matched, or it is only
- ** possible for a single row from this table to match, then skip over
- ** any additional ORDER BY terms dealing with this table.
- */
- if( seenRowid || (uniqueNotNull && i>=pIdx->nColumn) ){
- /* Advance j over additional ORDER BY terms associated with base */
- WhereMaskSet *pMS = p->pWC->pMaskSet;
- Bitmask m = ~getMask(pMS, base);
- while( j<nTerm && (exprTableUsage(pMS, pOrderBy->a[j].pExpr)&m)==0 ){
- j++;
- }
- }
- return j;
-}
-
-/*
-** Find the best query plan for accessing a particular table. Write the
-** best query plan and its cost into the p->cost.
-**
-** The lowest cost plan wins. The cost is an estimate of the amount of
-** CPU and disk I/O needed to process the requested result.
-** Factors that influence cost include:
-**
-** * The estimated number of rows that will be retrieved. (The
-** fewer the better.)
-**
-** * Whether or not sorting must occur.
-**
-** * Whether or not there must be separate lookups in the
-** index and in the main table.
-**
-** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
-** the SQL statement, then this function only considers plans using the
-** named index. If no such plan is found, then the returned cost is
-** SQLITE_BIG_DBL. If a plan is found that uses the named index,
-** then the cost is calculated in the usual way.
-**
-** If a NOT INDEXED clause was attached to the table
-** in the SELECT statement, then no indexes are considered. However, the
-** selected plan may still take advantage of the built-in rowid primary key
-** index.
-*/
-static void bestBtreeIndex(WhereBestIdx *p){
- Parse *pParse = p->pParse; /* The parsing context */
- WhereClause *pWC = p->pWC; /* The WHERE clause */
- struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
- int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */
- Index *pProbe; /* An index we are evaluating */
- Index *pIdx; /* Copy of pProbe, or zero for IPK index */
- int eqTermMask; /* Current mask of valid equality operators */
- int idxEqTermMask; /* Index mask of valid equality operators */
- Index sPk; /* A fake index object for the primary key */
- tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
- int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
- int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */
- int nPriorSat; /* ORDER BY terms satisfied by outer loops */
- int nOrderBy; /* Number of ORDER BY terms */
- char bSortInit; /* Initializer for bSort in inner loop */
- char bDistInit; /* Initializer for bDist in inner loop */
-
-
- /* Initialize the cost to a worst-case value */
- memset(&p->cost, 0, sizeof(p->cost));
- p->cost.rCost = SQLITE_BIG_DBL;
-
- /* If the pSrc table is the right table of a LEFT JOIN then we may not
- ** use an index to satisfy IS NULL constraints on that table. This is
- ** because columns might end up being NULL if the table does not match -
- ** a circumstance which the index cannot help us discover. Ticket #2177.
- */
- if( pSrc->jointype & JT_LEFT ){
- idxEqTermMask = WO_EQ|WO_IN;
- }else{
- idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL;
- }
-
- if( pSrc->pIndex ){
- /* An INDEXED BY clause specifies a particular index to use */
- pIdx = pProbe = pSrc->pIndex;
- wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
- eqTermMask = idxEqTermMask;
- }else{
- /* There is no INDEXED BY clause. Create a fake Index object in local
- ** variable sPk to represent the rowid primary key index. Make this
- ** fake index the first in a chain of Index objects with all of the real
- ** indices to follow */
- Index *pFirst; /* First of real indices on the table */
- memset(&sPk, 0, sizeof(Index));
- sPk.nColumn = 1;
- sPk.aiColumn = &aiColumnPk;
- sPk.aiRowEst = aiRowEstPk;
- sPk.onError = OE_Replace;
- sPk.pTable = pSrc->pTab;
- aiRowEstPk[0] = pSrc->pTab->nRowEst;
- aiRowEstPk[1] = 1;
- pFirst = pSrc->pTab->pIndex;
- if( pSrc->notIndexed==0 ){
- /* The real indices of the table are only considered if the
- ** NOT INDEXED qualifier is omitted from the FROM clause */
- sPk.pNext = pFirst;
- }
- pProbe = &sPk;
- wsFlagMask = ~(
- WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
- );
- eqTermMask = WO_EQ|WO_IN;
- pIdx = 0;
- }
-
- nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
- if( p->i ){
- nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
- bSortInit = nPriorSat<nOrderBy;
- bDistInit = 0;
- }else{
- nPriorSat = 0;
- bSortInit = nOrderBy>0;
- bDistInit = p->pDistinct!=0;
- }
-
- /* Loop over all indices looking for the best one to use
- */
- for(; pProbe; pIdx=pProbe=pProbe->pNext){
- const tRowcnt * const aiRowEst = pProbe->aiRowEst;
- WhereCost pc; /* Cost of using pProbe */
- double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */
-
- /* The following variables are populated based on the properties of
- ** index being evaluated. They are then used to determine the expected
- ** cost and number of rows returned.
- **
- ** pc.plan.nEq:
- ** Number of equality terms that can be implemented using the index.
- ** In other words, the number of initial fields in the index that
- ** are used in == or IN or NOT NULL constraints of the WHERE clause.
- **
- ** nInMul:
- ** The "in-multiplier". This is an estimate of how many seek operations
- ** SQLite must perform on the index in question. For example, if the
- ** WHERE clause is:
- **
- ** WHERE a IN (1, 2, 3) AND b IN (4, 5, 6)
- **
- ** SQLite must perform 9 lookups on an index on (a, b), so nInMul is
- ** set to 9. Given the same schema and either of the following WHERE
- ** clauses:
- **
- ** WHERE a = 1
- ** WHERE a >= 2
- **
- ** nInMul is set to 1.
- **
- ** If there exists a WHERE term of the form "x IN (SELECT ...)", then
- ** the sub-select is assumed to return 25 rows for the purposes of
- ** determining nInMul.
- **
- ** bInEst:
- ** Set to true if there was at least one "x IN (SELECT ...)" term used
- ** in determining the value of nInMul. Note that the RHS of the
- ** IN operator must be a SELECT, not a value list, for this variable
- ** to be true.
- **
- ** rangeDiv:
- ** An estimate of a divisor by which to reduce the search space due
- ** to inequality constraints. In the absence of sqlite_stat3 ANALYZE
- ** data, a single inequality reduces the search space to 1/4rd its
- ** original size (rangeDiv==4). Two inequalities reduce the search
- ** space to 1/16th of its original size (rangeDiv==16).
- **
- ** bSort:
- ** Boolean. True if there is an ORDER BY clause that will require an
- ** external sort (i.e. scanning the index being evaluated will not
- ** correctly order records).
- **
- ** bDist:
- ** Boolean. True if there is a DISTINCT clause that will require an
- ** external btree.
- **
- ** bLookup:
- ** Boolean. True if a table lookup is required for each index entry
- ** visited. In other words, true if this is not a covering index.
- ** This is always false for the rowid primary key index of a table.
- ** For other indexes, it is true unless all the columns of the table
- ** used by the SELECT statement are present in the index (such an
- ** index is sometimes described as a covering index).
- ** For example, given the index on (a, b), the second of the following
- ** two queries requires table b-tree lookups in order to find the value
- ** of column c, but the first does not because columns a and b are
- ** both available in the index.
- **
- ** SELECT a, b FROM tbl WHERE a = 1;
- ** SELECT a, b, c FROM tbl WHERE a = 1;
- */
- int bInEst = 0; /* True if "x IN (SELECT...)" seen */
- int nInMul = 1; /* Number of distinct equalities to lookup */
- double rangeDiv = (double)1; /* Estimated reduction in search space */
- int nBound = 0; /* Number of range constraints seen */
- char bSort = bSortInit; /* True if external sort required */
- char bDist = bDistInit; /* True if index cannot help with DISTINCT */
- char bLookup = 0; /* True if not a covering index */
- WhereTerm *pTerm; /* A single term of the WHERE clause */
-#ifdef SQLITE_ENABLE_STAT3
- WhereTerm *pFirstTerm = 0; /* First term matching the index */
-#endif
-
- WHERETRACE((
- " %s(%s):\n",
- pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
- ));
- memset(&pc, 0, sizeof(pc));
- pc.plan.nOBSat = nPriorSat;
-
- /* Determine the values of pc.plan.nEq and nInMul */
- for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
- int j = pProbe->aiColumn[pc.plan.nEq];
- pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
- if( pTerm==0 ) break;
- pc.plan.wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
- testcase( pTerm->pWC!=pWC );
- if( pTerm->eOperator & WO_IN ){
- Expr *pExpr = pTerm->pExpr;
- pc.plan.wsFlags |= WHERE_COLUMN_IN;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- /* "x IN (SELECT ...)": Assume the SELECT returns 25 rows */
- nInMul *= 25;
- bInEst = 1;
- }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
- /* "x IN (value, value, ...)" */
- nInMul *= pExpr->x.pList->nExpr;
- }
- }else if( pTerm->eOperator & WO_ISNULL ){
- pc.plan.wsFlags |= WHERE_COLUMN_NULL;
- }
-#ifdef SQLITE_ENABLE_STAT3
- if( pc.plan.nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
-#endif
- pc.used |= pTerm->prereqRight;
- }
-
- /* If the index being considered is UNIQUE, and there is an equality
- ** constraint for all columns in the index, then this search will find
- ** at most a single row. In this case set the WHERE_UNIQUE flag to
- ** indicate this to the caller.
- **
- ** Otherwise, if the search may find more than one row, test to see if
- ** there is a range constraint on indexed column (pc.plan.nEq+1) that can be
- ** optimized using the index.
- */
- if( pc.plan.nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
- testcase( pc.plan.wsFlags & WHERE_COLUMN_IN );
- testcase( pc.plan.wsFlags & WHERE_COLUMN_NULL );
- if( (pc.plan.wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
- pc.plan.wsFlags |= WHERE_UNIQUE;
- if( p->i==0 || (p->aLevel[p->i-1].plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
- pc.plan.wsFlags |= WHERE_ALL_UNIQUE;
- }
- }
- }else if( pProbe->bUnordered==0 ){
- int j;
- j = (pc.plan.nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[pc.plan.nEq]);
- if( findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
- WhereTerm *pTop, *pBtm;
- pTop = findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE, pIdx);
- pBtm = findTerm(pWC, iCur, j, p->notReady, WO_GT|WO_GE, pIdx);
- whereRangeScanEst(pParse, pProbe, pc.plan.nEq, pBtm, pTop, &rangeDiv);
- if( pTop ){
- nBound = 1;
- pc.plan.wsFlags |= WHERE_TOP_LIMIT;
- pc.used |= pTop->prereqRight;
- testcase( pTop->pWC!=pWC );
- }
- if( pBtm ){
- nBound++;
- pc.plan.wsFlags |= WHERE_BTM_LIMIT;
- pc.used |= pBtm->prereqRight;
- testcase( pBtm->pWC!=pWC );
- }
- pc.plan.wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
- }
- }
-
- /* If there is an ORDER BY clause and the index being considered will
- ** naturally scan rows in the required order, set the appropriate flags
- ** in pc.plan.wsFlags. Otherwise, if there is an ORDER BY clause but
- ** the index will scan rows in a different order, set the bSort
- ** variable. */
- if( bSort && (pSrc->jointype & JT_LEFT)==0 ){
- int bRev = 2;
- WHERETRACE((" --> before isSortingIndex: nPriorSat=%d\n",nPriorSat));
- pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev);
- WHERETRACE((" --> after isSortingIndex: bRev=%d nOBSat=%d\n",
- bRev, pc.plan.nOBSat));
- if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_UNIQUE)!=0 ){
- pc.plan.wsFlags |= WHERE_ORDERED;
- }
- if( nOrderBy==pc.plan.nOBSat ){
- bSort = 0;
- pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE;
- }
- if( bRev & 1 ) pc.plan.wsFlags |= WHERE_REVERSE;
- }
-
- /* If there is a DISTINCT qualifier and this index will scan rows in
- ** order of the DISTINCT expressions, clear bDist and set the appropriate
- ** flags in pc.plan.wsFlags. */
- if( bDist
- && isDistinctIndex(pParse, pWC, pProbe, iCur, p->pDistinct, pc.plan.nEq)
- && (pc.plan.wsFlags & WHERE_COLUMN_IN)==0
- ){
- bDist = 0;
- pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT;
- }
-
- /* If currently calculating the cost of using an index (not the IPK
- ** index), determine if all required column data may be obtained without
- ** using the main table (i.e. if the index is a covering
- ** index for this query). If it is, set the WHERE_IDX_ONLY flag in
- ** pc.plan.wsFlags. Otherwise, set the bLookup variable to true. */
- if( pIdx ){
- Bitmask m = pSrc->colUsed;
- int j;
- for(j=0; j<pIdx->nColumn; j++){
- int x = pIdx->aiColumn[j];
- if( x<BMS-1 ){
- m &= ~(((Bitmask)1)<<x);
- }
- }
- if( m==0 ){
- pc.plan.wsFlags |= WHERE_IDX_ONLY;
- }else{
- bLookup = 1;
- }
- }
-
- /*
- ** Estimate the number of rows of output. For an "x IN (SELECT...)"
- ** constraint, do not let the estimate exceed half the rows in the table.
- */
- pc.plan.nRow = (double)(aiRowEst[pc.plan.nEq] * nInMul);
- if( bInEst && pc.plan.nRow*2>aiRowEst[0] ){
- pc.plan.nRow = aiRowEst[0]/2;
- nInMul = (int)(pc.plan.nRow / aiRowEst[pc.plan.nEq]);
- }
-
-#ifdef SQLITE_ENABLE_STAT3
- /* If the constraint is of the form x=VALUE or x IN (E1,E2,...)
- ** and we do not think that values of x are unique and if histogram
- ** data is available for column x, then it might be possible
- ** to get a better estimate on the number of rows based on
- ** VALUE and how common that value is according to the histogram.
- */
- if( pc.plan.nRow>(double)1 && pc.plan.nEq==1
- && pFirstTerm!=0 && aiRowEst[1]>1 ){
- assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 );
- if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
- testcase( pFirstTerm->eOperator==WO_EQ );
- testcase( pFirstTerm->eOperator==WO_ISNULL );
- whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight,
- &pc.plan.nRow);
- }else if( bInEst==0 ){
- assert( pFirstTerm->eOperator==WO_IN );
- whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList,
- &pc.plan.nRow);
- }
- }
-#endif /* SQLITE_ENABLE_STAT3 */
-
- /* Adjust the number of output rows and downward to reflect rows
- ** that are excluded by range constraints.
- */
- pc.plan.nRow = pc.plan.nRow/rangeDiv;
- if( pc.plan.nRow<1 ) pc.plan.nRow = 1;
-
- /* Experiments run on real SQLite databases show that the time needed
- ** to do a binary search to locate a row in a table or index is roughly
- ** log10(N) times the time to move from one row to the next row within
- ** a table or index. The actual times can vary, with the size of
- ** records being an important factor. Both moves and searches are
- ** slower with larger records, presumably because fewer records fit
- ** on one page and hence more pages have to be fetched.
- **
- ** The ANALYZE command and the sqlite_stat1 and sqlite_stat3 tables do
- ** not give us data on the relative sizes of table and index records.
- ** So this computation assumes table records are about twice as big
- ** as index records
- */
- if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED))==WHERE_IDX_ONLY
- && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
- && sqlite3GlobalConfig.bUseCis
- && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan)
- ){
- /* This index is not useful for indexing, but it is a covering index.
- ** A full-scan of the index might be a little faster than a full-scan
- ** of the table, so give this case a cost slightly less than a table
- ** scan. */
- pc.rCost = aiRowEst[0]*3 + pProbe->nColumn;
- pc.plan.wsFlags |= WHERE_COVER_SCAN|WHERE_COLUMN_RANGE;
- }else if( (pc.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
- /* The cost of a full table scan is a number of move operations equal
- ** to the number of rows in the table.
- **
- ** We add an additional 4x penalty to full table scans. This causes
- ** the cost function to err on the side of choosing an index over
- ** choosing a full scan. This 4x full-scan penalty is an arguable
- ** decision and one which we expect to revisit in the future. But
- ** it seems to be working well enough at the moment.
- */
- pc.rCost = aiRowEst[0]*4;
- pc.plan.wsFlags &= ~WHERE_IDX_ONLY;
- if( pIdx ){
- pc.plan.wsFlags &= ~WHERE_ORDERED;
- pc.plan.nOBSat = nPriorSat;
- }
- }else{
- log10N = estLog(aiRowEst[0]);
- pc.rCost = pc.plan.nRow;
- if( pIdx ){
- if( bLookup ){
- /* For an index lookup followed by a table lookup:
- ** nInMul index searches to find the start of each index range
- ** + nRow steps through the index
- ** + nRow table searches to lookup the table entry using the rowid
- */
- pc.rCost += (nInMul + pc.plan.nRow)*log10N;
- }else{
- /* For a covering index:
- ** nInMul index searches to find the initial entry
- ** + nRow steps through the index
- */
- pc.rCost += nInMul*log10N;
- }
- }else{
- /* For a rowid primary key lookup:
- ** nInMult table searches to find the initial entry for each range
- ** + nRow steps through the table
- */
- pc.rCost += nInMul*log10N;
- }
- }
-
- /* Add in the estimated cost of sorting the result. Actual experimental
- ** measurements of sorting performance in SQLite show that sorting time
- ** adds C*N*log10(N) to the cost, where N is the number of rows to be
- ** sorted and C is a factor between 1.95 and 4.3. We will split the
- ** difference and select C of 3.0.
- */
- if( bSort ){
- double m = estLog(pc.plan.nRow*(nOrderBy - pc.plan.nOBSat)/nOrderBy);
- m *= (double)(pc.plan.nOBSat ? 2 : 3);
- pc.rCost += pc.plan.nRow*m;
- }
- if( bDist ){
- pc.rCost += pc.plan.nRow*estLog(pc.plan.nRow)*3;
- }
-
- /**** Cost of using this index has now been computed ****/
-
- /* If there are additional constraints on this table that cannot
- ** be used with the current index, but which might lower the number
- ** of output rows, adjust the nRow value accordingly. This only
- ** matters if the current index is the least costly, so do not bother
- ** with this step if we already know this index will not be chosen.
- ** Also, never reduce the output row count below 2 using this step.
- **
- ** It is critical that the notValid mask be used here instead of
- ** the notReady mask. When computing an "optimal" index, the notReady
- ** mask will only have one bit set - the bit for the current table.
- ** The notValid mask, on the other hand, always has all bits set for
- ** tables that are not in outer loops. If notReady is used here instead
- ** of notValid, then a optimal index that depends on inner joins loops
- ** might be selected even when there exists an optimal index that has
- ** no such dependency.
- */
- if( pc.plan.nRow>2 && pc.rCost<=p->cost.rCost ){
- int k; /* Loop counter */
- int nSkipEq = pc.plan.nEq; /* Number of == constraints to skip */
- int nSkipRange = nBound; /* Number of < constraints to skip */
- Bitmask thisTab; /* Bitmap for pSrc */
-
- thisTab = getMask(pWC->pMaskSet, iCur);
- for(pTerm=pWC->a, k=pWC->nTerm; pc.plan.nRow>2 && k; k--, pTerm++){
- if( pTerm->wtFlags & TERM_VIRTUAL ) continue;
- if( (pTerm->prereqAll & p->notValid)!=thisTab ) continue;
- if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
- if( nSkipEq ){
- /* Ignore the first pc.plan.nEq equality matches since the index
- ** has already accounted for these */
- nSkipEq--;
- }else{
- /* Assume each additional equality match reduces the result
- ** set size by a factor of 10 */
- pc.plan.nRow /= 10;
- }
- }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){
- if( nSkipRange ){
- /* Ignore the first nSkipRange range constraints since the index
- ** has already accounted for these */
- nSkipRange--;
- }else{
- /* Assume each additional range constraint reduces the result
- ** set size by a factor of 3. Indexed range constraints reduce
- ** the search space by a larger factor: 4. We make indexed range
- ** more selective intentionally because of the subjective
- ** observation that indexed range constraints really are more
- ** selective in practice, on average. */
- pc.plan.nRow /= 3;
- }
- }else if( pTerm->eOperator!=WO_NOOP ){
- /* Any other expression lowers the output row count by half */
- pc.plan.nRow /= 2;
- }
- }
- if( pc.plan.nRow<2 ) pc.plan.nRow = 2;
- }
-
-
- WHERETRACE((
- " nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n"
- " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n"
- " used=0x%llx nOBSat=%d\n",
- pc.plan.nEq, nInMul, (int)rangeDiv, bSort, bLookup, pc.plan.wsFlags,
- p->notReady, log10N, pc.plan.nRow, pc.rCost, pc.used,
- pc.plan.nOBSat
- ));
-
- /* If this index is the best we have seen so far, then record this
- ** index and its cost in the p->cost structure.
- */
- if( (!pIdx || pc.plan.wsFlags) && compareCost(&pc, &p->cost) ){
- p->cost = pc;
- p->cost.plan.wsFlags &= wsFlagMask;
- p->cost.plan.u.pIdx = pIdx;
- }
-
- /* If there was an INDEXED BY clause, then only that one index is
- ** considered. */
- if( pSrc->pIndex ) break;
-
- /* Reset masks for the next index in the loop */
- wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
- eqTermMask = idxEqTermMask;
- }
-
- /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
- ** is set, then reverse the order that the index will be scanned
- ** in. This is used for application testing, to help find cases
- ** where application behaviour depends on the (undefined) order that
- ** SQLite outputs rows in in the absence of an ORDER BY clause. */
- if( !p->pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
- p->cost.plan.wsFlags |= WHERE_REVERSE;
- }
-
- assert( p->pOrderBy || (p->cost.plan.wsFlags&WHERE_ORDERED)==0 );
- assert( p->cost.plan.u.pIdx==0 || (p->cost.plan.wsFlags&WHERE_ROWID_EQ)==0 );
- assert( pSrc->pIndex==0
- || p->cost.plan.u.pIdx==0
- || p->cost.plan.u.pIdx==pSrc->pIndex
- );
-
- WHERETRACE((" best index is: %s\n",
- p->cost.plan.u.pIdx ? p->cost.plan.u.pIdx->zName : "ipk"));
-
- bestOrClauseIndex(p);
- bestAutomaticIndex(p);
- p->cost.plan.wsFlags |= eqTermMask;
-}
-
-/*
-** Find the query plan for accessing table pSrc->pTab. Write the
-** best query plan and its cost into the WhereCost object supplied
-** as the last parameter. This function may calculate the cost of
-** both real and virtual table scans.
-**
-** This function does not take ORDER BY or DISTINCT into account. Nor
-** does it remember the virtual table query plan. All it does is compute
-** the cost while determining if an OR optimization is applicable. The
-** details will be reconsidered later if the optimization is found to be
-** applicable.
-*/
-static void bestIndex(WhereBestIdx *p){
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(p->pSrc->pTab) ){
- sqlite3_index_info *pIdxInfo = 0;
- p->ppIdxInfo = &pIdxInfo;
- bestVirtualIndex(p);
- if( pIdxInfo->needToFreeIdxStr ){
- sqlite3_free(pIdxInfo->idxStr);
- }
- sqlite3DbFree(p->pParse->db, pIdxInfo);
- }else
-#endif
- {
- bestBtreeIndex(p);
- }
-}
-
-/*
-** Disable a term in the WHERE clause. Except, do not disable the term
-** if it controls a LEFT OUTER JOIN and it did not originate in the ON
-** or USING clause of that join.
-**
-** Consider the term t2.z='ok' in the following queries:
-**
-** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok'
-** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok'
-** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok'
-**
-** The t2.z='ok' is disabled in the in (2) because it originates
-** in the ON clause. The term is disabled in (3) because it is not part
-** of a LEFT OUTER JOIN. In (1), the term is not disabled.
-**
-** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are
-** completely satisfied by indices.
-**
-** Disabling a term causes that term to not be tested in the inner loop
-** of the join. Disabling is an optimization. When terms are satisfied
-** by indices, we disable them to prevent redundant tests in the inner
-** loop. We would get the correct results if nothing were ever disabled,
-** but joins might run a little slower. The trick is to disable as much
-** as we can without disabling too much. If we disabled in (1), we'd get
-** the wrong answer. See ticket #813.
-*/
-static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
- if( pTerm
- && (pTerm->wtFlags & TERM_CODED)==0
- && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
- ){
- pTerm->wtFlags |= TERM_CODED;
- if( pTerm->iParent>=0 ){
- WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent];
- if( (--pOther->nChild)==0 ){
- disableTerm(pLevel, pOther);
- }
- }
- }
-}
-
-/*
-** Code an OP_Affinity opcode to apply the column affinity string zAff
-** to the n registers starting at base.
-**
-** As an optimization, SQLITE_AFF_NONE entries (which are no-ops) at the
-** beginning and end of zAff are ignored. If all entries in zAff are
-** SQLITE_AFF_NONE, then no code gets generated.
-**
-** This routine makes its own copy of zAff so that the caller is free
-** to modify zAff after this routine returns.
-*/
-static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
- Vdbe *v = pParse->pVdbe;
- if( zAff==0 ){
- assert( pParse->db->mallocFailed );
- return;
- }
- assert( v!=0 );
-
- /* Adjust base and n to skip over SQLITE_AFF_NONE entries at the beginning
- ** and end of the affinity string.
- */
- while( n>0 && zAff[0]==SQLITE_AFF_NONE ){
- n--;
- base++;
- zAff++;
- }
- while( n>1 && zAff[n-1]==SQLITE_AFF_NONE ){
- n--;
- }
-
- /* Code the OP_Affinity opcode if there is anything left to do. */
- if( n>0 ){
- sqlite3VdbeAddOp2(v, OP_Affinity, base, n);
- sqlite3VdbeChangeP4(v, -1, zAff, n);
- sqlite3ExprCacheAffinityChange(pParse, base, n);
- }
-}
-
-
-/*
-** Generate code for a single equality term of the WHERE clause. An equality
-** term can be either X=expr or X IN (...). pTerm is the term to be
-** coded.
-**
-** The current value for the constraint is left in register iReg.
-**
-** For a constraint of the form X=expr, the expression is evaluated and its
-** result is left on the stack. For constraints of the form X IN (...)
-** this routine sets up a loop that will iterate over all values of X.
-*/
-static int codeEqualityTerm(
- Parse *pParse, /* The parsing context */
- WhereTerm *pTerm, /* The term of the WHERE clause to be coded */
- WhereLevel *pLevel, /* When level of the FROM clause we are working on */
- int iTarget /* Attempt to leave results in this register */
-){
- Expr *pX = pTerm->pExpr;
- Vdbe *v = pParse->pVdbe;
- int iReg; /* Register holding results */
-
- assert( iTarget>0 );
- if( pX->op==TK_EQ ){
- iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
- }else if( pX->op==TK_ISNULL ){
- iReg = iTarget;
- sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
-#ifndef SQLITE_OMIT_SUBQUERY
- }else{
- int eType;
- int iTab;
- struct InLoop *pIn;
-
- assert( pX->op==TK_IN );
- iReg = iTarget;
- eType = sqlite3FindInIndex(pParse, pX, 0);
- iTab = pX->iTable;
- sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
- assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
- if( pLevel->u.in.nIn==0 ){
- pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
- }
- pLevel->u.in.nIn++;
- pLevel->u.in.aInLoop =
- sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
- sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
- pIn = pLevel->u.in.aInLoop;
- if( pIn ){
- pIn += pLevel->u.in.nIn - 1;
- pIn->iCur = iTab;
- if( eType==IN_INDEX_ROWID ){
- pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
- }else{
- pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
- }
- sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
- }else{
- pLevel->u.in.nIn = 0;
- }
-#endif
- }
- disableTerm(pLevel, pTerm);
- return iReg;
-}
-
-/*
-** Generate code that will evaluate all == and IN constraints for an
-** index.
-**
-** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c).
-** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10
-** The index has as many as three equality constraints, but in this
-** example, the third "c" value is an inequality. So only two
-** constraints are coded. This routine will generate code to evaluate
-** a==5 and b IN (1,2,3). The current values for a and b will be stored
-** in consecutive registers and the index of the first register is returned.
-**
-** In the example above nEq==2. But this subroutine works for any value
-** of nEq including 0. If nEq==0, this routine is nearly a no-op.
-** The only thing it does is allocate the pLevel->iMem memory cell and
-** compute the affinity string.
-**
-** This routine always allocates at least one memory cell and returns
-** the index of that memory cell. The code that
-** calls this routine will use that memory cell to store the termination
-** key value of the loop. If one or more IN operators appear, then
-** this routine allocates an additional nEq memory cells for internal
-** use.
-**
-** Before returning, *pzAff is set to point to a buffer containing a
-** copy of the column affinity string of the index allocated using
-** sqlite3DbMalloc(). Except, entries in the copy of the string associated
-** with equality constraints that use NONE affinity are set to
-** SQLITE_AFF_NONE. This is to deal with SQL such as the following:
-**
-** CREATE TABLE t1(a TEXT PRIMARY KEY, b);
-** SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b;
-**
-** In the example above, the index on t1(a) has TEXT affinity. But since
-** the right hand side of the equality constraint (t2.b) has NONE affinity,
-** no conversion should be attempted before using a t2.b value as part of
-** a key to search the index. Hence the first byte in the returned affinity
-** string in this example would be set to SQLITE_AFF_NONE.
-*/
-static int codeAllEqualityTerms(
- Parse *pParse, /* Parsing context */
- WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
- WhereClause *pWC, /* The WHERE clause */
- Bitmask notReady, /* Which parts of FROM have not yet been coded */
- int nExtraReg, /* Number of extra registers to allocate */
- char **pzAff /* OUT: Set to point to affinity string */
-){
- int nEq = pLevel->plan.nEq; /* The number of == or IN constraints to code */
- Vdbe *v = pParse->pVdbe; /* The vm under construction */
- Index *pIdx; /* The index being used for this loop */
- int iCur = pLevel->iTabCur; /* The cursor of the table */
- WhereTerm *pTerm; /* A single constraint term */
- int j; /* Loop counter */
- int regBase; /* Base register */
- int nReg; /* Number of registers to allocate */
- char *zAff; /* Affinity string to return */
-
- /* This module is only called on query plans that use an index. */
- assert( pLevel->plan.wsFlags & WHERE_INDEXED );
- pIdx = pLevel->plan.u.pIdx;
-
- /* Figure out how many memory cells we will need then allocate them.
- */
- regBase = pParse->nMem + 1;
- nReg = pLevel->plan.nEq + nExtraReg;
- pParse->nMem += nReg;
-
- zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
- if( !zAff ){
- pParse->db->mallocFailed = 1;
- }
-
- /* Evaluate the equality constraints
- */
- assert( pIdx->nColumn>=nEq );
- for(j=0; j<nEq; j++){
- int r1;
- int k = pIdx->aiColumn[j];
- pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx);
- if( pTerm==0 ) break;
- /* The following true for indices with redundant columns.
- ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
- testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
- r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j);
- if( r1!=regBase+j ){
- if( nReg==1 ){
- sqlite3ReleaseTempReg(pParse, regBase);
- regBase = r1;
- }else{
- sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
- }
- }
- testcase( pTerm->eOperator & WO_ISNULL );
- testcase( pTerm->eOperator & WO_IN );
- if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
- Expr *pRight = pTerm->pExpr->pRight;
- sqlite3ExprCodeIsNullJump(v, pRight, regBase+j, pLevel->addrBrk);
- if( zAff ){
- if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){
- zAff[j] = SQLITE_AFF_NONE;
- }
- if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){
- zAff[j] = SQLITE_AFF_NONE;
- }
- }
- }
- }
- *pzAff = zAff;
- return regBase;
-}
-
-#ifndef SQLITE_OMIT_EXPLAIN
-/*
-** This routine is a helper for explainIndexRange() below
-**
-** pStr holds the text of an expression that we are building up one term
-** at a time. This routine adds a new term to the end of the expression.
-** Terms are separated by AND so add the "AND" text for second and subsequent
-** terms only.
-*/
-static void explainAppendTerm(
- StrAccum *pStr, /* The text expression being built */
- int iTerm, /* Index of this term. First is zero */
- const char *zColumn, /* Name of the column */
- const char *zOp /* Name of the operator */
-){
- if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5);
- sqlite3StrAccumAppend(pStr, zColumn, -1);
- sqlite3StrAccumAppend(pStr, zOp, 1);
- sqlite3StrAccumAppend(pStr, "?", 1);
-}
-
-/*
-** Argument pLevel describes a strategy for scanning table pTab. This
-** function returns a pointer to a string buffer containing a description
-** of the subset of table rows scanned by the strategy in the form of an
-** SQL expression. Or, if all rows are scanned, NULL is returned.
-**
-** For example, if the query:
-**
-** SELECT * FROM t1 WHERE a=1 AND b>2;
-**
-** is run and there is an index on (a, b), then this function returns a
-** string similar to:
-**
-** "a=? AND b>?"
-**
-** The returned pointer points to memory obtained from sqlite3DbMalloc().
-** It is the responsibility of the caller to free the buffer when it is
-** no longer required.
-*/
-static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){
- WherePlan *pPlan = &pLevel->plan;
- Index *pIndex = pPlan->u.pIdx;
- int nEq = pPlan->nEq;
- int i, j;
- Column *aCol = pTab->aCol;
- int *aiColumn = pIndex->aiColumn;
- StrAccum txt;
-
- if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
- return 0;
- }
- sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
- txt.db = db;
- sqlite3StrAccumAppend(&txt, " (", 2);
- for(i=0; i<nEq; i++){
- explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "=");
- }
-
- j = i;
- if( pPlan->wsFlags&WHERE_BTM_LIMIT ){
- char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
- explainAppendTerm(&txt, i++, z, ">");
- }
- if( pPlan->wsFlags&WHERE_TOP_LIMIT ){
- char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
- explainAppendTerm(&txt, i, z, "<");
- }
- sqlite3StrAccumAppend(&txt, ")", 1);
- return sqlite3StrAccumFinish(&txt);
-}
-
-/*
-** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
-** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
-** record is added to the output to describe the table scan strategy in
-** pLevel.
-*/
-static void explainOneScan(
- Parse *pParse, /* Parse context */
- SrcList *pTabList, /* Table list this loop refers to */
- WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */
- int iLevel, /* Value for "level" column of output */
- int iFrom, /* Value for "from" column of output */
- u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
-){
- if( pParse->explain==2 ){
- u32 flags = pLevel->plan.wsFlags;
- struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
- Vdbe *v = pParse->pVdbe; /* VM being constructed */
- sqlite3 *db = pParse->db; /* Database handle */
- char *zMsg; /* Text to add to EQP output */
- sqlite3_int64 nRow; /* Expected number of rows visited by scan */
- int iId = pParse->iSelectId; /* Select id (left-most output column) */
- int isSearch; /* True for a SEARCH. False for SCAN. */
-
- if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
-
- isSearch = (pLevel->plan.nEq>0)
- || (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
- || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
-
- zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
- if( pItem->pSelect ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
- }else{
- zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
- }
-
- if( pItem->zAlias ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
- }
- if( (flags & WHERE_INDEXED)!=0 ){
- char *zWhere = explainIndexRange(db, pLevel, pItem->pTab);
- zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg,
- ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
- ((flags & WHERE_IDX_ONLY)?"COVERING ":""),
- ((flags & WHERE_TEMP_INDEX)?"":" "),
- ((flags & WHERE_TEMP_INDEX)?"": pLevel->plan.u.pIdx->zName),
- zWhere
- );
- sqlite3DbFree(db, zWhere);
- }else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
-
- if( flags&WHERE_ROWID_EQ ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
- }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
- }else if( flags&WHERE_BTM_LIMIT ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
- }else if( flags&WHERE_TOP_LIMIT ){
- zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
- }
- }
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
- sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
- zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
- pVtabIdx->idxNum, pVtabIdx->idxStr);
- }
-#endif
- if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){
- testcase( wctrlFlags & WHERE_ORDERBY_MIN );
- nRow = 1;
- }else{
- nRow = (sqlite3_int64)pLevel->plan.nRow;
- }
- zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow);
- sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
- }
-}
-#else
-# define explainOneScan(u,v,w,x,y,z)
-#endif /* SQLITE_OMIT_EXPLAIN */
-
-
-/*
-** Generate code for the start of the iLevel-th loop in the WHERE clause
-** implementation described by pWInfo.
-*/
-static Bitmask codeOneLoopStart(
- WhereInfo *pWInfo, /* Complete information about the WHERE clause */
- int iLevel, /* Which level of pWInfo->a[] should be coded */
- u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
- Bitmask notReady /* Which tables are currently available */
-){
- int j, k; /* Loop counters */
- int iCur; /* The VDBE cursor for the table */
- int addrNxt; /* Where to jump to continue with the next IN case */
- int omitTable; /* True if we use the index only */
- int bRev; /* True if we need to scan in reverse order */
- WhereLevel *pLevel; /* The where level to be coded */
- WhereClause *pWC; /* Decomposition of the entire WHERE clause */
- WhereTerm *pTerm; /* A WHERE clause term */
- Parse *pParse; /* Parsing context */
- Vdbe *v; /* The prepared stmt under constructions */
- struct SrcList_item *pTabItem; /* FROM clause term being coded */
- int addrBrk; /* Jump here to break out of the loop */
- int addrCont; /* Jump here to continue with next cycle */
- int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
- int iReleaseReg = 0; /* Temp register to free before returning */
-
- pParse = pWInfo->pParse;
- v = pParse->pVdbe;
- pWC = pWInfo->pWC;
- pLevel = &pWInfo->a[iLevel];
- pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
- iCur = pTabItem->iCursor;
- bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
- omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0
- && (wctrlFlags & WHERE_FORCE_TABLE)==0;
-
- /* Create labels for the "break" and "continue" instructions
- ** for the current loop. Jump to addrBrk to break out of a loop.
- ** Jump to cont to go immediately to the next iteration of the
- ** loop.
- **
- ** When there is an IN operator, we also have a "addrNxt" label that
- ** means to continue with the next IN value combination. When
- ** there are no IN operators in the constraints, the "addrNxt" label
- ** is the same as "addrBrk".
- */
- addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
- addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v);
-
- /* If this is the right table of a LEFT OUTER JOIN, allocate and
- ** initialize a memory cell that records if this table matches any
- ** row of the left table of the join.
- */
- if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
- pLevel->iLeftJoin = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
- VdbeComment((v, "init LEFT JOIN no-match flag"));
- }
-
- /* Special case of a FROM clause subquery implemented as a co-routine */
- if( pTabItem->viaCoroutine ){
- int regYield = pTabItem->regReturn;
- sqlite3VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield);
- pLevel->p2 = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
- VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName));
- sqlite3VdbeAddOp2(v, OP_If, regYield+1, addrBrk);
- pLevel->op = OP_Goto;
- }else
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
- /* Case 0: The table is a virtual-table. Use the VFilter and VNext
- ** to access the data.
- */
- int iReg; /* P3 Value for OP_VFilter */
- sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
- int nConstraint = pVtabIdx->nConstraint;
- struct sqlite3_index_constraint_usage *aUsage =
- pVtabIdx->aConstraintUsage;
- const struct sqlite3_index_constraint *aConstraint =
- pVtabIdx->aConstraint;
-
- sqlite3ExprCachePush(pParse);
- iReg = sqlite3GetTempRange(pParse, nConstraint+2);
- for(j=1; j<=nConstraint; j++){
- for(k=0; k<nConstraint; k++){
- if( aUsage[k].argvIndex==j ){
- int iTerm = aConstraint[k].iTermOffset;
- sqlite3ExprCode(pParse, pWC->a[iTerm].pExpr->pRight, iReg+j+1);
- break;
- }
- }
- if( k==nConstraint ) break;
- }
- sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
- sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
- sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrBrk, iReg, pVtabIdx->idxStr,
- pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
- pVtabIdx->needToFreeIdxStr = 0;
- for(j=0; j<nConstraint; j++){
- if( aUsage[j].omit ){
- int iTerm = aConstraint[j].iTermOffset;
- disableTerm(pLevel, &pWC->a[iTerm]);
- }
- }
- pLevel->op = OP_VNext;
- pLevel->p1 = iCur;
- pLevel->p2 = sqlite3VdbeCurrentAddr(v);
- sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
- sqlite3ExprCachePop(pParse, 1);
- }else
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
- if( pLevel->plan.wsFlags & WHERE_ROWID_EQ ){
- /* Case 1: We can directly reference a single row using an
- ** equality comparison against the ROWID field. Or
- ** we reference multiple rows using a "rowid IN (...)"
- ** construct.
- */
- iReleaseReg = sqlite3GetTempReg(pParse);
- pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0);
- assert( pTerm!=0 );
- assert( pTerm->pExpr!=0 );
- assert( pTerm->leftCursor==iCur );
- assert( omitTable==0 );
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
- iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, iReleaseReg);
- addrNxt = pLevel->addrNxt;
- sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
- VdbeComment((v, "pk"));
- pLevel->op = OP_Noop;
- }else if( pLevel->plan.wsFlags & WHERE_ROWID_RANGE ){
- /* Case 2: We have an inequality comparison against the ROWID field.
- */
- int testOp = OP_Noop;
- int start;
- int memEndValue = 0;
- WhereTerm *pStart, *pEnd;
-
- assert( omitTable==0 );
- pStart = findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0);
- pEnd = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0);
- if( bRev ){
- pTerm = pStart;
- pStart = pEnd;
- pEnd = pTerm;
- }
- if( pStart ){
- Expr *pX; /* The expression that defines the start bound */
- int r1, rTemp; /* Registers for holding the start boundary */
-
- /* The following constant maps TK_xx codes into corresponding
- ** seek opcodes. It depends on a particular ordering of TK_xx
- */
- const u8 aMoveOp[] = {
- /* TK_GT */ OP_SeekGt,
- /* TK_LE */ OP_SeekLe,
- /* TK_LT */ OP_SeekLt,
- /* TK_GE */ OP_SeekGe
- };
- assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
- assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
- assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
-
- testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
- pX = pStart->pExpr;
- assert( pX!=0 );
- assert( pStart->leftCursor==iCur );
- r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
- sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
- VdbeComment((v, "pk"));
- sqlite3ExprCacheAffinityChange(pParse, r1, 1);
- sqlite3ReleaseTempReg(pParse, rTemp);
- disableTerm(pLevel, pStart);
- }else{
- sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
- }
- if( pEnd ){
- Expr *pX;
- pX = pEnd->pExpr;
- assert( pX!=0 );
- assert( pEnd->leftCursor==iCur );
- testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
- memEndValue = ++pParse->nMem;
- sqlite3ExprCode(pParse, pX->pRight, memEndValue);
- if( pX->op==TK_LT || pX->op==TK_GT ){
- testOp = bRev ? OP_Le : OP_Ge;
- }else{
- testOp = bRev ? OP_Lt : OP_Gt;
- }
- disableTerm(pLevel, pEnd);
- }
- start = sqlite3VdbeCurrentAddr(v);
- pLevel->op = bRev ? OP_Prev : OP_Next;
- pLevel->p1 = iCur;
- pLevel->p2 = start;
- if( pStart==0 && pEnd==0 ){
- pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
- }else{
- assert( pLevel->p5==0 );
- }
- if( testOp!=OP_Noop ){
- iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
- sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
- sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
- }
- }else if( pLevel->plan.wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
- /* Case 3: A scan using an index.
- **
- ** The WHERE clause may contain zero or more equality
- ** terms ("==" or "IN" operators) that refer to the N
- ** left-most columns of the index. It may also contain
- ** inequality constraints (>, <, >= or <=) on the indexed
- ** column that immediately follows the N equalities. Only
- ** the right-most column can be an inequality - the rest must
- ** use the "==" and "IN" operators. For example, if the
- ** index is on (x,y,z), then the following clauses are all
- ** optimized:
- **
- ** x=5
- ** x=5 AND y=10
- ** x=5 AND y<10
- ** x=5 AND y>5 AND y<10
- ** x=5 AND y=5 AND z<=10
- **
- ** The z<10 term of the following cannot be used, only
- ** the x=5 term:
- **
- ** x=5 AND z<10
- **
- ** N may be zero if there are inequality constraints.
- ** If there are no inequality constraints, then N is at
- ** least one.
- **
- ** This case is also used when there are no WHERE clause
- ** constraints but an index is selected anyway, in order
- ** to force the output order to conform to an ORDER BY.
- */
- static const u8 aStartOp[] = {
- 0,
- 0,
- OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */
- OP_Last, /* 3: (!start_constraints && startEq && bRev) */
- OP_SeekGt, /* 4: (start_constraints && !startEq && !bRev) */
- OP_SeekLt, /* 5: (start_constraints && !startEq && bRev) */
- OP_SeekGe, /* 6: (start_constraints && startEq && !bRev) */
- OP_SeekLe /* 7: (start_constraints && startEq && bRev) */
- };
- static const u8 aEndOp[] = {
- OP_Noop, /* 0: (!end_constraints) */
- OP_IdxGE, /* 1: (end_constraints && !bRev) */
- OP_IdxLT /* 2: (end_constraints && bRev) */
- };
- int nEq = pLevel->plan.nEq; /* Number of == or IN terms */
- int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */
- int regBase; /* Base register holding constraint values */
- int r1; /* Temp register */
- WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */
- WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */
- int startEq; /* True if range start uses ==, >= or <= */
- int endEq; /* True if range end uses ==, >= or <= */
- int start_constraints; /* Start of range is constrained */
- int nConstraint; /* Number of constraint terms */
- Index *pIdx; /* The index we will be using */
- int iIdxCur; /* The VDBE cursor for the index */
- int nExtraReg = 0; /* Number of extra registers needed */
- int op; /* Instruction opcode */
- char *zStartAff; /* Affinity for start of range constraint */
- char *zEndAff; /* Affinity for end of range constraint */
-
- pIdx = pLevel->plan.u.pIdx;
- iIdxCur = pLevel->iIdxCur;
- k = (nEq==pIdx->nColumn ? -1 : pIdx->aiColumn[nEq]);
-
- /* If this loop satisfies a sort order (pOrderBy) request that
- ** was passed to this function to implement a "SELECT min(x) ..."
- ** query, then the caller will only allow the loop to run for
- ** a single iteration. This means that the first row returned
- ** should not have a NULL value stored in 'x'. If column 'x' is
- ** the first one after the nEq equality constraints in the index,
- ** this requires some special handling.
- */
- if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
- && (pLevel->plan.wsFlags&WHERE_ORDERED)
- && (pIdx->nColumn>nEq)
- ){
- /* assert( pOrderBy->nExpr==1 ); */
- /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */
- isMinQuery = 1;
- nExtraReg = 1;
- }
-
- /* Find any inequality constraint terms for the start and end
- ** of the range.
- */
- if( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ){
- pRangeEnd = findTerm(pWC, iCur, k, notReady, (WO_LT|WO_LE), pIdx);
- nExtraReg = 1;
- }
- if( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ){
- pRangeStart = findTerm(pWC, iCur, k, notReady, (WO_GT|WO_GE), pIdx);
- nExtraReg = 1;
- }
-
- /* Generate code to evaluate all constraint terms using == or IN
- ** and store the values of those terms in an array of registers
- ** starting at regBase.
- */
- regBase = codeAllEqualityTerms(
- pParse, pLevel, pWC, notReady, nExtraReg, &zStartAff
- );
- zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
- addrNxt = pLevel->addrNxt;
-
- /* If we are doing a reverse order scan on an ascending index, or
- ** a forward order scan on a descending index, interchange the
- ** start and end terms (pRangeStart and pRangeEnd).
- */
- if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
- || (bRev && pIdx->nColumn==nEq)
- ){
- SWAP(WhereTerm *, pRangeEnd, pRangeStart);
- }
-
- testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
- testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
- startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
- endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
- start_constraints = pRangeStart || nEq>0;
-
- /* Seek the index cursor to the start of the range. */
- nConstraint = nEq;
- if( pRangeStart ){
- Expr *pRight = pRangeStart->pExpr->pRight;
- sqlite3ExprCode(pParse, pRight, regBase+nEq);
- if( (pRangeStart->wtFlags & TERM_VNULL)==0 ){
- sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
- }
- if( zStartAff ){
- if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_NONE){
- /* Since the comparison is to be performed with no conversions
- ** applied to the operands, set the affinity to apply to pRight to
- ** SQLITE_AFF_NONE. */
- zStartAff[nEq] = SQLITE_AFF_NONE;
- }
- if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
- zStartAff[nEq] = SQLITE_AFF_NONE;
- }
- }
- nConstraint++;
- testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
- }else if( isMinQuery ){
- sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
- nConstraint++;
- startEq = 0;
- start_constraints = 1;
- }
- codeApplyAffinity(pParse, regBase, nConstraint, zStartAff);
- op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
- assert( op!=0 );
- testcase( op==OP_Rewind );
- testcase( op==OP_Last );
- testcase( op==OP_SeekGt );
- testcase( op==OP_SeekGe );
- testcase( op==OP_SeekLe );
- testcase( op==OP_SeekLt );
- sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
-
- /* Load the value for the inequality constraint at the end of the
- ** range (if any).
- */
- nConstraint = nEq;
- if( pRangeEnd ){
- Expr *pRight = pRangeEnd->pExpr->pRight;
- sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
- sqlite3ExprCode(pParse, pRight, regBase+nEq);
- if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){
- sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
- }
- if( zEndAff ){
- if( sqlite3CompareAffinity(pRight, zEndAff[nEq])==SQLITE_AFF_NONE){
- /* Since the comparison is to be performed with no conversions
- ** applied to the operands, set the affinity to apply to pRight to
- ** SQLITE_AFF_NONE. */
- zEndAff[nEq] = SQLITE_AFF_NONE;
- }
- if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
- zEndAff[nEq] = SQLITE_AFF_NONE;
- }
- }
- codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
- nConstraint++;
- testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
- }
- sqlite3DbFree(pParse->db, zStartAff);
- sqlite3DbFree(pParse->db, zEndAff);
-
- /* Top of the loop body */
- pLevel->p2 = sqlite3VdbeCurrentAddr(v);
-
- /* Check if the index cursor is past the end of the range. */
- op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
- testcase( op==OP_Noop );
- testcase( op==OP_IdxGE );
- testcase( op==OP_IdxLT );
- if( op!=OP_Noop ){
- sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
- sqlite3VdbeChangeP5(v, endEq!=bRev ?1:0);
- }
-
- /* If there are inequality constraints, check that the value
- ** of the table column that the inequality contrains is not NULL.
- ** If it is, jump to the next iteration of the loop.
- */
- r1 = sqlite3GetTempReg(pParse);
- testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
- testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
- if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
- sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont);
- }
- sqlite3ReleaseTempReg(pParse, r1);
-
- /* Seek the table cursor, if required */
- disableTerm(pLevel, pRangeStart);
- disableTerm(pLevel, pRangeEnd);
- if( !omitTable ){
- iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
- sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
- sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */
- }
-
- /* Record the instruction used to terminate the loop. Disable
- ** WHERE clause terms made redundant by the index range scan.
- */
- if( pLevel->plan.wsFlags & WHERE_UNIQUE ){
- pLevel->op = OP_Noop;
- }else if( bRev ){
- pLevel->op = OP_Prev;
- }else{
- pLevel->op = OP_Next;
- }
- pLevel->p1 = iIdxCur;
- if( pLevel->plan.wsFlags & WHERE_COVER_SCAN ){
- pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
- }else{
- assert( pLevel->p5==0 );
- }
- }else
-
-#ifndef SQLITE_OMIT_OR_OPTIMIZATION
- if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
- /* Case 4: Two or more separately indexed terms connected by OR
- **
- ** Example:
- **
- ** CREATE TABLE t1(a,b,c,d);
- ** CREATE INDEX i1 ON t1(a);
- ** CREATE INDEX i2 ON t1(b);
- ** CREATE INDEX i3 ON t1(c);
- **
- ** SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13)
- **
- ** In the example, there are three indexed terms connected by OR.
- ** The top of the loop looks like this:
- **
- ** Null 1 # Zero the rowset in reg 1
- **
- ** Then, for each indexed term, the following. The arguments to
- ** RowSetTest are such that the rowid of the current row is inserted
- ** into the RowSet. If it is already present, control skips the
- ** Gosub opcode and jumps straight to the code generated by WhereEnd().
- **
- ** sqlite3WhereBegin(<term>)
- ** RowSetTest # Insert rowid into rowset
- ** Gosub 2 A
- ** sqlite3WhereEnd()
- **
- ** Following the above, code to terminate the loop. Label A, the target
- ** of the Gosub above, jumps to the instruction right after the Goto.
- **
- ** Null 1 # Zero the rowset in reg 1
- ** Goto B # The loop is finished.
- **
- ** A: <loop body> # Return data, whatever.
- **
- ** Return 2 # Jump back to the Gosub
- **
- ** B: <after the loop>
- **
- */
- WhereClause *pOrWc; /* The OR-clause broken out into subterms */
- SrcList *pOrTab; /* Shortened table list or OR-clause generation */
- Index *pCov = 0; /* Potential covering index (or NULL) */
- int iCovCur = pParse->nTab++; /* Cursor used for index scans (if any) */
-
- int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */
- int regRowset = 0; /* Register for RowSet object */
- int regRowid = 0; /* Register holding rowid */
- int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */
- int iRetInit; /* Address of regReturn init */
- int untestedTerms = 0; /* Some terms not completely tested */
- int ii; /* Loop counter */
- Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
-
- pTerm = pLevel->plan.u.pTerm;
- assert( pTerm!=0 );
- assert( pTerm->eOperator==WO_OR );
- assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
- pOrWc = &pTerm->u.pOrInfo->wc;
- pLevel->op = OP_Return;
- pLevel->p1 = regReturn;
-
- /* Set up a new SrcList in pOrTab containing the table being scanned
- ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
- ** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
- */
- if( pWInfo->nLevel>1 ){
- int nNotReady; /* The number of notReady tables */
- struct SrcList_item *origSrc; /* Original list of tables */
- nNotReady = pWInfo->nLevel - iLevel - 1;
- pOrTab = sqlite3StackAllocRaw(pParse->db,
- sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
- if( pOrTab==0 ) return notReady;
- pOrTab->nAlloc = (i16)(nNotReady + 1);
- pOrTab->nSrc = pOrTab->nAlloc;
- memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
- origSrc = pWInfo->pTabList->a;
- for(k=1; k<=nNotReady; k++){
- memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k]));
- }
- }else{
- pOrTab = pWInfo->pTabList;
- }
-
- /* Initialize the rowset register to contain NULL. An SQL NULL is
- ** equivalent to an empty rowset.
- **
- ** Also initialize regReturn to contain the address of the instruction
- ** immediately following the OP_Return at the bottom of the loop. This
- ** is required in a few obscure LEFT JOIN cases where control jumps
- ** over the top of the loop into the body of it. In this case the
- ** correct response for the end-of-loop code (the OP_Return) is to
- ** fall through to the next instruction, just as an OP_Next does if
- ** called on an uninitialized cursor.
- */
- if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
- regRowset = ++pParse->nMem;
- regRowid = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
- }
- iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
-
- /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
- ** Then for every term xN, evaluate as the subexpression: xN AND z
- ** That way, terms in y that are factored into the disjunction will
- ** be picked up by the recursive calls to sqlite3WhereBegin() below.
- **
- ** Actually, each subexpression is converted to "xN AND w" where w is
- ** the "interesting" terms of z - terms that did not originate in the
- ** ON or USING clause of a LEFT JOIN, and terms that are usable as
- ** indices.
- */
- if( pWC->nTerm>1 ){
- int iTerm;
- for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
- Expr *pExpr = pWC->a[iTerm].pExpr;
- if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
- if( pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_ORINFO) ) continue;
- if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
- pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
- pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr);
- }
- if( pAndExpr ){
- pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
- }
- }
-
- for(ii=0; ii<pOrWc->nTerm; ii++){
- WhereTerm *pOrTerm = &pOrWc->a[ii];
- if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
- WhereInfo *pSubWInfo; /* Info for single OR-term scan */
- Expr *pOrExpr = pOrTerm->pExpr;
- if( pAndExpr ){
- pAndExpr->pLeft = pOrExpr;
- pOrExpr = pAndExpr;
- }
- /* Loop through table entries that match term pOrTerm. */
- pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
- WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
- WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
- assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed );
- if( pSubWInfo ){
- WhereLevel *pLvl;
- explainOneScan(
- pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
- );
- if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
- int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
- int r;
- r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur,
- regRowid, 0);
- sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset,
- sqlite3VdbeCurrentAddr(v)+2, r, iSet);
- }
- sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
-
- /* The pSubWInfo->untestedTerms flag means that this OR term
- ** contained one or more AND term from a notReady table. The
- ** terms from the notReady table could not be tested and will
- ** need to be tested later.
- */
- if( pSubWInfo->untestedTerms ) untestedTerms = 1;
-
- /* If all of the OR-connected terms are optimized using the same
- ** index, and the index is opened using the same cursor number
- ** by each call to sqlite3WhereBegin() made by this loop, it may
- ** be possible to use that index as a covering index.
- **
- ** If the call to sqlite3WhereBegin() above resulted in a scan that
- ** uses an index, and this is either the first OR-connected term
- ** processed or the index is the same as that used by all previous
- ** terms, set pCov to the candidate covering index. Otherwise, set
- ** pCov to NULL to indicate that no candidate covering index will
- ** be available.
- */
- pLvl = &pSubWInfo->a[0];
- if( (pLvl->plan.wsFlags & WHERE_INDEXED)!=0
- && (pLvl->plan.wsFlags & WHERE_TEMP_INDEX)==0
- && (ii==0 || pLvl->plan.u.pIdx==pCov)
- ){
- assert( pLvl->iIdxCur==iCovCur );
- pCov = pLvl->plan.u.pIdx;
- }else{
- pCov = 0;
- }
-
- /* Finish the loop through table entries that match term pOrTerm. */
- sqlite3WhereEnd(pSubWInfo);
- }
- }
- }
- pLevel->u.pCovidx = pCov;
- if( pCov ) pLevel->iIdxCur = iCovCur;
- if( pAndExpr ){
- pAndExpr->pLeft = 0;
- sqlite3ExprDelete(pParse->db, pAndExpr);
- }
- sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
- sqlite3VdbeResolveLabel(v, iLoopBody);
-
- if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
- if( !untestedTerms ) disableTerm(pLevel, pTerm);
- }else
-#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
-
- {
- /* Case 5: There is no usable index. We must do a complete
- ** scan of the entire table.
- */
- static const u8 aStep[] = { OP_Next, OP_Prev };
- static const u8 aStart[] = { OP_Rewind, OP_Last };
- assert( bRev==0 || bRev==1 );
- assert( omitTable==0 );
- pLevel->op = aStep[bRev];
- pLevel->p1 = iCur;
- pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
- pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
- }
- notReady &= ~getMask(pWC->pMaskSet, iCur);
-
- /* Insert code to test every subexpression that can be completely
- ** computed using the current set of tables.
- **
- ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
- ** the use of indices become tests that are evaluated against each row of
- ** the relevant input tables.
- */
- for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
- Expr *pE;
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
- testcase( pTerm->wtFlags & TERM_CODED );
- if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & notReady)!=0 ){
- testcase( pWInfo->untestedTerms==0
- && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
- pWInfo->untestedTerms = 1;
- continue;
- }
- pE = pTerm->pExpr;
- assert( pE!=0 );
- if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
- continue;
- }
- sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
- pTerm->wtFlags |= TERM_CODED;
- }
-
- /* For a LEFT OUTER JOIN, generate code that will record the fact that
- ** at least one row of the right table has matched the left table.
- */
- if( pLevel->iLeftJoin ){
- pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
- VdbeComment((v, "record LEFT JOIN hit"));
- sqlite3ExprCacheClear(pParse);
- for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
- testcase( pTerm->wtFlags & TERM_CODED );
- if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & notReady)!=0 ){
- assert( pWInfo->untestedTerms );
- continue;
- }
- assert( pTerm->pExpr );
- sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
- pTerm->wtFlags |= TERM_CODED;
- }
- }
- sqlite3ReleaseTempReg(pParse, iReleaseReg);
-
- return notReady;
-}
-
-#if defined(SQLITE_TEST)
-/*
-** The following variable holds a text description of query plan generated
-** by the most recent call to sqlite3WhereBegin(). Each call to WhereBegin
-** overwrites the previous. This information is used for testing and
-** analysis only.
-*/
-SQLITE_API char sqlite3_query_plan[BMS*2*40]; /* Text of the join */
-static int nQPlan = 0; /* Next free slow in _query_plan[] */
-
-#endif /* SQLITE_TEST */
-
-
-/*
-** Free a WhereInfo structure
-*/
-static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
- if( ALWAYS(pWInfo) ){
- int i;
- for(i=0; i<pWInfo->nLevel; i++){
- sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
- if( pInfo ){
- /* assert( pInfo->needToFreeIdxStr==0 || db->mallocFailed ); */
- if( pInfo->needToFreeIdxStr ){
- sqlite3_free(pInfo->idxStr);
- }
- sqlite3DbFree(db, pInfo);
- }
- if( pWInfo->a[i].plan.wsFlags & WHERE_TEMP_INDEX ){
- Index *pIdx = pWInfo->a[i].plan.u.pIdx;
- if( pIdx ){
- sqlite3DbFree(db, pIdx->zColAff);
- sqlite3DbFree(db, pIdx);
- }
- }
- }
- whereClauseClear(pWInfo->pWC);
- sqlite3DbFree(db, pWInfo);
- }
-}
-
-
-/*
-** Generate the beginning of the loop used for WHERE clause processing.
-** The return value is a pointer to an opaque structure that contains
-** information needed to terminate the loop. Later, the calling routine
-** should invoke sqlite3WhereEnd() with the return value of this function
-** in order to complete the WHERE clause processing.
-**
-** If an error occurs, this routine returns NULL.
-**
-** The basic idea is to do a nested loop, one loop for each table in
-** the FROM clause of a select. (INSERT and UPDATE statements are the
-** same as a SELECT with only a single table in the FROM clause.) For
-** example, if the SQL is this:
-**
-** SELECT * FROM t1, t2, t3 WHERE ...;
-**
-** Then the code generated is conceptually like the following:
-**
-** foreach row1 in t1 do \ Code generated
-** foreach row2 in t2 do |-- by sqlite3WhereBegin()
-** foreach row3 in t3 do /
-** ...
-** end \ Code generated
-** end |-- by sqlite3WhereEnd()
-** end /
-**
-** Note that the loops might not be nested in the order in which they
-** appear in the FROM clause if a different order is better able to make
-** use of indices. Note also that when the IN operator appears in
-** the WHERE clause, it might result in additional nested loops for
-** scanning through all values on the right-hand side of the IN.
-**
-** There are Btree cursors associated with each table. t1 uses cursor
-** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor.
-** And so forth. This routine generates code to open those VDBE cursors
-** and sqlite3WhereEnd() generates the code to close them.
-**
-** The code that sqlite3WhereBegin() generates leaves the cursors named
-** in pTabList pointing at their appropriate entries. The [...] code
-** can use OP_Column and OP_Rowid opcodes on these cursors to extract
-** data from the various tables of the loop.
-**
-** If the WHERE clause is empty, the foreach loops must each scan their
-** entire tables. Thus a three-way join is an O(N^3) operation. But if
-** the tables have indices and there are terms in the WHERE clause that
-** refer to those indices, a complete table scan can be avoided and the
-** code will run much faster. Most of the work of this routine is checking
-** to see if there are indices that can be used to speed up the loop.
-**
-** Terms of the WHERE clause are also used to limit which rows actually
-** make it to the "..." in the middle of the loop. After each "foreach",
-** terms of the WHERE clause that use only terms in that loop and outer
-** loops are evaluated and if false a jump is made around all subsequent
-** inner loops (or around the "..." if the test occurs within the inner-
-** most loop)
-**
-** OUTER JOINS
-**
-** An outer join of tables t1 and t2 is conceptally coded as follows:
-**
-** foreach row1 in t1 do
-** flag = 0
-** foreach row2 in t2 do
-** start:
-** ...
-** flag = 1
-** end
-** if flag==0 then
-** move the row2 cursor to a null row
-** goto start
-** fi
-** end
-**
-** ORDER BY CLAUSE PROCESSING
-**
-** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
-** if there is one. If there is no ORDER BY clause or if this routine
-** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
-**
-** If an index can be used so that the natural output order of the table
-** scan is correct for the ORDER BY clause, then that index is used and
-** the returned WhereInfo.nOBSat field is set to pOrderBy->nExpr. This
-** is an optimization that prevents an unnecessary sort of the result set
-** if an index appropriate for the ORDER BY clause already exists.
-**
-** If the where clause loops cannot be arranged to provide the correct
-** output order, then WhereInfo.nOBSat is 0.
-*/
-SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
- Parse *pParse, /* The parser context */
- SrcList *pTabList, /* A list of all tables to be scanned */
- Expr *pWhere, /* The WHERE clause */
- ExprList *pOrderBy, /* An ORDER BY clause, or NULL */
- ExprList *pDistinct, /* The select-list for DISTINCT queries - or NULL */
- u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
- int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */
-){
- int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */
- int nTabList; /* Number of elements in pTabList */
- WhereInfo *pWInfo; /* Will become the return value of this function */
- Vdbe *v = pParse->pVdbe; /* The virtual database engine */
- Bitmask notReady; /* Cursors that are not yet positioned */
- WhereBestIdx sWBI; /* Best index search context */
- WhereMaskSet *pMaskSet; /* The expression mask set */
- WhereLevel *pLevel; /* A single level in pWInfo->a[] */
- int iFrom; /* First unused FROM clause element */
- int andFlags; /* AND-ed combination of all pWC->a[].wtFlags */
- int ii; /* Loop counter */
- sqlite3 *db; /* Database connection */
-
-
- /* Variable initialization */
- memset(&sWBI, 0, sizeof(sWBI));
- sWBI.pParse = pParse;
-
- /* The number of tables in the FROM clause is limited by the number of
- ** bits in a Bitmask
- */
- testcase( pTabList->nSrc==BMS );
- if( pTabList->nSrc>BMS ){
- sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS);
- return 0;
- }
-
- /* This function normally generates a nested loop for all tables in
- ** pTabList. But if the WHERE_ONETABLE_ONLY flag is set, then we should
- ** only generate code for the first table in pTabList and assume that
- ** any cursors associated with subsequent tables are uninitialized.
- */
- nTabList = (wctrlFlags & WHERE_ONETABLE_ONLY) ? 1 : pTabList->nSrc;
-
- /* Allocate and initialize the WhereInfo structure that will become the
- ** return value. A single allocation is used to store the WhereInfo
- ** struct, the contents of WhereInfo.a[], the WhereClause structure
- ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte
- ** field (type Bitmask) it must be aligned on an 8-byte boundary on
- ** some architectures. Hence the ROUND8() below.
- */
- db = pParse->db;
- nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
- pWInfo = sqlite3DbMallocZero(db,
- nByteWInfo +
- sizeof(WhereClause) +
- sizeof(WhereMaskSet)
- );
- if( db->mallocFailed ){
- sqlite3DbFree(db, pWInfo);
- pWInfo = 0;
- goto whereBeginError;
- }
- pWInfo->nLevel = nTabList;
- pWInfo->pParse = pParse;
- pWInfo->pTabList = pTabList;
- pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
- pWInfo->pWC = sWBI.pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
- pWInfo->wctrlFlags = wctrlFlags;
- pWInfo->savedNQueryLoop = pParse->nQueryLoop;
- pMaskSet = (WhereMaskSet*)&sWBI.pWC[1];
- sWBI.aLevel = pWInfo->a;
-
- /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
- ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
- if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0;
-
- /* Split the WHERE clause into separate subexpressions where each
- ** subexpression is separated by an AND operator.
- */
- initMaskSet(pMaskSet);
- whereClauseInit(sWBI.pWC, pParse, pMaskSet, wctrlFlags);
- sqlite3ExprCodeConstants(pParse, pWhere);
- whereSplit(sWBI.pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
-
- /* Special case: a WHERE clause that is constant. Evaluate the
- ** expression and either jump over all of the code or fall thru.
- */
- if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){
- sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);
- pWhere = 0;
- }
-
- /* Assign a bit from the bitmask to every term in the FROM clause.
- **
- ** When assigning bitmask values to FROM clause cursors, it must be
- ** the case that if X is the bitmask for the N-th FROM clause term then
- ** the bitmask for all FROM clause terms to the left of the N-th term
- ** is (X-1). An expression from the ON clause of a LEFT JOIN can use
- ** its Expr.iRightJoinTable value to find the bitmask of the right table
- ** of the join. Subtracting one from the right table bitmask gives a
- ** bitmask for all tables to the left of the join. Knowing the bitmask
- ** for all tables to the left of a left join is important. Ticket #3015.
- **
- ** Configure the WhereClause.vmask variable so that bits that correspond
- ** to virtual table cursors are set. This is used to selectively disable
- ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful
- ** with virtual tables.
- **
- ** Note that bitmasks are created for all pTabList->nSrc tables in
- ** pTabList, not just the first nTabList tables. nTabList is normally
- ** equal to pTabList->nSrc but might be shortened to 1 if the
- ** WHERE_ONETABLE_ONLY flag is set.
- */
- assert( sWBI.pWC->vmask==0 && pMaskSet->n==0 );
- for(ii=0; ii<pTabList->nSrc; ii++){
- createMask(pMaskSet, pTabList->a[ii].iCursor);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( ALWAYS(pTabList->a[ii].pTab) && IsVirtual(pTabList->a[ii].pTab) ){
- sWBI.pWC->vmask |= ((Bitmask)1 << ii);
- }
-#endif
- }
-#ifndef NDEBUG
- {
- Bitmask toTheLeft = 0;
- for(ii=0; ii<pTabList->nSrc; ii++){
- Bitmask m = getMask(pMaskSet, pTabList->a[ii].iCursor);
- assert( (m-1)==toTheLeft );
- toTheLeft |= m;
- }
- }
-#endif
-
- /* Analyze all of the subexpressions. Note that exprAnalyze() might
- ** add new virtual terms onto the end of the WHERE clause. We do not
- ** want to analyze these virtual terms, so start analyzing at the end
- ** and work forward so that the added virtual terms are never processed.
- */
- exprAnalyzeAll(pTabList, sWBI.pWC);
- if( db->mallocFailed ){
- goto whereBeginError;
- }
-
- /* Check if the DISTINCT qualifier, if there is one, is redundant.
- ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to
- ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT.
- */
- if( pDistinct && isDistinctRedundant(pParse, pTabList, sWBI.pWC, pDistinct) ){
- pDistinct = 0;
- pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
- }
-
- /* Chose the best index to use for each table in the FROM clause.
- **
- ** This loop fills in the following fields:
- **
- ** pWInfo->a[].pIdx The index to use for this level of the loop.
- ** pWInfo->a[].wsFlags WHERE_xxx flags associated with pIdx
- ** pWInfo->a[].nEq The number of == and IN constraints
- ** pWInfo->a[].iFrom Which term of the FROM clause is being coded
- ** pWInfo->a[].iTabCur The VDBE cursor for the database table
- ** pWInfo->a[].iIdxCur The VDBE cursor for the index
- ** pWInfo->a[].pTerm When wsFlags==WO_OR, the OR-clause term
- **
- ** This loop also figures out the nesting order of tables in the FROM
- ** clause.
- */
- sWBI.notValid = ~(Bitmask)0;
- sWBI.pOrderBy = pOrderBy;
- sWBI.n = nTabList;
- sWBI.pDistinct = pDistinct;
- andFlags = ~0;
- WHERETRACE(("*** Optimizer Start ***\n"));
- for(sWBI.i=iFrom=0, pLevel=pWInfo->a; sWBI.i<nTabList; sWBI.i++, pLevel++){
- WhereCost bestPlan; /* Most efficient plan seen so far */
- Index *pIdx; /* Index for FROM table at pTabItem */
- int j; /* For looping over FROM tables */
- int bestJ = -1; /* The value of j */
- Bitmask m; /* Bitmask value for j or bestJ */
- int isOptimal; /* Iterator for optimal/non-optimal search */
- int nUnconstrained; /* Number tables without INDEXED BY */
- Bitmask notIndexed; /* Mask of tables that cannot use an index */
-
- memset(&bestPlan, 0, sizeof(bestPlan));
- bestPlan.rCost = SQLITE_BIG_DBL;
- WHERETRACE(("*** Begin search for loop %d ***\n", sWBI.i));
-
- /* Loop through the remaining entries in the FROM clause to find the
- ** next nested loop. The loop tests all FROM clause entries
- ** either once or twice.
- **
- ** The first test is always performed if there are two or more entries
- ** remaining and never performed if there is only one FROM clause entry
- ** to choose from. The first test looks for an "optimal" scan. In
- ** this context an optimal scan is one that uses the same strategy
- ** for the given FROM clause entry as would be selected if the entry
- ** were used as the innermost nested loop. In other words, a table
- ** is chosen such that the cost of running that table cannot be reduced
- ** by waiting for other tables to run first. This "optimal" test works
- ** by first assuming that the FROM clause is on the inner loop and finding
- ** its query plan, then checking to see if that query plan uses any
- ** other FROM clause terms that are sWBI.notValid. If no notValid terms
- ** are used then the "optimal" query plan works.
- **
- ** Note that the WhereCost.nRow parameter for an optimal scan might
- ** not be as small as it would be if the table really were the innermost
- ** join. The nRow value can be reduced by WHERE clause constraints
- ** that do not use indices. But this nRow reduction only happens if the
- ** table really is the innermost join.
- **
- ** The second loop iteration is only performed if no optimal scan
- ** strategies were found by the first iteration. This second iteration
- ** is used to search for the lowest cost scan overall.
- **
- ** Previous versions of SQLite performed only the second iteration -
- ** the next outermost loop was always that with the lowest overall
- ** cost. However, this meant that SQLite could select the wrong plan
- ** for scripts such as the following:
- **
- ** CREATE TABLE t1(a, b);
- ** CREATE TABLE t2(c, d);
- ** SELECT * FROM t2, t1 WHERE t2.rowid = t1.a;
- **
- ** The best strategy is to iterate through table t1 first. However it
- ** is not possible to determine this with a simple greedy algorithm.
- ** Since the cost of a linear scan through table t2 is the same
- ** as the cost of a linear scan through table t1, a simple greedy
- ** algorithm may choose to use t2 for the outer loop, which is a much
- ** costlier approach.
- */
- nUnconstrained = 0;
- notIndexed = 0;
- for(isOptimal=(iFrom<nTabList-1); isOptimal>=0 && bestJ<0; isOptimal--){
- for(j=iFrom, sWBI.pSrc=&pTabList->a[j]; j<nTabList; j++, sWBI.pSrc++){
- int doNotReorder; /* True if this table should not be reordered */
-
- doNotReorder = (sWBI.pSrc->jointype & (JT_LEFT|JT_CROSS))!=0;
- if( j!=iFrom && doNotReorder ) break;
- m = getMask(pMaskSet, sWBI.pSrc->iCursor);
- if( (m & sWBI.notValid)==0 ){
- if( j==iFrom ) iFrom++;
- continue;
- }
- sWBI.notReady = (isOptimal ? m : sWBI.notValid);
- if( sWBI.pSrc->pIndex==0 ) nUnconstrained++;
-
- WHERETRACE((" === trying table %d (%s) with isOptimal=%d ===\n",
- j, sWBI.pSrc->pTab->zName, isOptimal));
- assert( sWBI.pSrc->pTab );
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(sWBI.pSrc->pTab) ){
- sWBI.ppIdxInfo = &pWInfo->a[j].pIdxInfo;
- bestVirtualIndex(&sWBI);
- }else
-#endif
- {
- bestBtreeIndex(&sWBI);
- }
- assert( isOptimal || (sWBI.cost.used&sWBI.notValid)==0 );
-
- /* If an INDEXED BY clause is present, then the plan must use that
- ** index if it uses any index at all */
- assert( sWBI.pSrc->pIndex==0
- || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
- || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex );
-
- if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
- notIndexed |= m;
- }
- if( isOptimal ){
- pWInfo->a[j].rOptCost = sWBI.cost.rCost;
- }else if( iFrom<nTabList-1 ){
- /* If two or more tables have nearly the same outer loop cost,
- ** very different inner loop (optimal) cost, we want to choose
- ** for the outer loop that table which benefits the least from
- ** being in the inner loop. The following code scales the
- ** outer loop cost estimate to accomplish that. */
- WHERETRACE((" scaling cost from %.1f to %.1f\n",
- sWBI.cost.rCost,
- sWBI.cost.rCost/pWInfo->a[j].rOptCost));
- sWBI.cost.rCost /= pWInfo->a[j].rOptCost;
- }
-
- /* Conditions under which this table becomes the best so far:
- **
- ** (1) The table must not depend on other tables that have not
- ** yet run. (In other words, it must not depend on tables
- ** in inner loops.)
- **
- ** (2) (This rule was removed on 2012-11-09. The scaling of the
- ** cost using the optimal scan cost made this rule obsolete.)
- **
- ** (3) All tables have an INDEXED BY clause or this table lacks an
- ** INDEXED BY clause or this table uses the specific
- ** index specified by its INDEXED BY clause. This rule ensures
- ** that a best-so-far is always selected even if an impossible
- ** combination of INDEXED BY clauses are given. The error
- ** will be detected and relayed back to the application later.
- ** The NEVER() comes about because rule (2) above prevents
- ** An indexable full-table-scan from reaching rule (3).
- **
- ** (4) The plan cost must be lower than prior plans, where "cost"
- ** is defined by the compareCost() function above.
- */
- if( (sWBI.cost.used&sWBI.notValid)==0 /* (1) */
- && (nUnconstrained==0 || sWBI.pSrc->pIndex==0 /* (3) */
- || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
- && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan)) /* (4) */
- ){
- WHERETRACE((" === table %d (%s) is best so far\n"
- " cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=%08x\n",
- j, sWBI.pSrc->pTab->zName,
- sWBI.cost.rCost, sWBI.cost.plan.nRow,
- sWBI.cost.plan.nOBSat, sWBI.cost.plan.wsFlags));
- bestPlan = sWBI.cost;
- bestJ = j;
- }
- if( doNotReorder ) break;
- }
- }
- assert( bestJ>=0 );
- assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
- WHERETRACE(("*** Optimizer selects table %d (%s) for loop %d with:\n"
- " cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=0x%08x\n",
- bestJ, pTabList->a[bestJ].pTab->zName,
- pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow,
- bestPlan.plan.nOBSat, bestPlan.plan.wsFlags));
- if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
- assert( pWInfo->eDistinct==0 );
- pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
- }
- andFlags &= bestPlan.plan.wsFlags;
- pLevel->plan = bestPlan.plan;
- pLevel->iTabCur = pTabList->a[bestJ].iCursor;
- testcase( bestPlan.plan.wsFlags & WHERE_INDEXED );
- testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX );
- if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){
- if( (wctrlFlags & WHERE_ONETABLE_ONLY)
- && (bestPlan.plan.wsFlags & WHERE_TEMP_INDEX)==0
- ){
- pLevel->iIdxCur = iIdxCur;
- }else{
- pLevel->iIdxCur = pParse->nTab++;
- }
- }else{
- pLevel->iIdxCur = -1;
- }
- sWBI.notValid &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
- pLevel->iFrom = (u8)bestJ;
- if( bestPlan.plan.nRow>=(double)1 ){
- pParse->nQueryLoop *= bestPlan.plan.nRow;
- }
-
- /* Check that if the table scanned by this loop iteration had an
- ** INDEXED BY clause attached to it, that the named index is being
- ** used for the scan. If not, then query compilation has failed.
- ** Return an error.
- */
- pIdx = pTabList->a[bestJ].pIndex;
- if( pIdx ){
- if( (bestPlan.plan.wsFlags & WHERE_INDEXED)==0 ){
- sqlite3ErrorMsg(pParse, "cannot use index: %s", pIdx->zName);
- goto whereBeginError;
- }else{
- /* If an INDEXED BY clause is used, the bestIndex() function is
- ** guaranteed to find the index specified in the INDEXED BY clause
- ** if it find an index at all. */
- assert( bestPlan.plan.u.pIdx==pIdx );
- }
- }
- }
- WHERETRACE(("*** Optimizer Finished ***\n"));
- if( pParse->nErr || db->mallocFailed ){
- goto whereBeginError;
- }
- if( nTabList ){
- pLevel--;
- pWInfo->nOBSat = pLevel->plan.nOBSat;
- }else{
- pWInfo->nOBSat = 0;
- }
-
- /* If the total query only selects a single row, then the ORDER BY
- ** clause is irrelevant.
- */
- if( (andFlags & WHERE_UNIQUE)!=0 && pOrderBy ){
- assert( nTabList==0 || (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 );
- pWInfo->nOBSat = pOrderBy->nExpr;
- }
-
- /* If the caller is an UPDATE or DELETE statement that is requesting
- ** to use a one-pass algorithm, determine if this is appropriate.
- ** The one-pass algorithm only works if the WHERE clause constraints
- ** the statement to update a single row.
- */
- assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
- if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
- pWInfo->okOnePass = 1;
- pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY;
- }
-
- /* Open all tables in the pTabList and any indices selected for
- ** searching those tables.
- */
- sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
- notReady = ~(Bitmask)0;
- pWInfo->nRowOut = (double)1;
- for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
- Table *pTab; /* Table to open */
- int iDb; /* Index of database containing table/index */
- struct SrcList_item *pTabItem;
-
- pTabItem = &pTabList->a[pLevel->iFrom];
- pTab = pTabItem->pTab;
- pWInfo->nRowOut *= pLevel->plan.nRow;
- iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
- /* Do nothing */
- }else
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
- const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
- int iCur = pTabItem->iCursor;
- sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
- }else if( IsVirtual(pTab) ){
- /* noop */
- }else
-#endif
- if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
- && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
- int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
- sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
- testcase( pTab->nCol==BMS-1 );
- testcase( pTab->nCol==BMS );
- if( !pWInfo->okOnePass && pTab->nCol<BMS ){
- Bitmask b = pTabItem->colUsed;
- int n = 0;
- for(; b; b=b>>1, n++){}
- sqlite3VdbeChangeP4(v, sqlite3VdbeCurrentAddr(v)-1,
- SQLITE_INT_TO_PTR(n), P4_INT32);
- assert( n<=pTab->nCol );
- }
- }else{
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
- }
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
- if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){
- constructAutomaticIndex(pParse, sWBI.pWC, pTabItem, notReady, pLevel);
- }else
-#endif
- if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
- Index *pIx = pLevel->plan.u.pIdx;
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
- int iIndexCur = pLevel->iIdxCur;
- assert( pIx->pSchema==pTab->pSchema );
- assert( iIndexCur>=0 );
- sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIx->zName));
- }
- sqlite3CodeVerifySchema(pParse, iDb);
- notReady &= ~getMask(sWBI.pWC->pMaskSet, pTabItem->iCursor);
- }
- pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
- if( db->mallocFailed ) goto whereBeginError;
-
- /* Generate the code to do the search. Each iteration of the for
- ** loop below generates code for a single nested loop of the VM
- ** program.
- */
- notReady = ~(Bitmask)0;
- for(ii=0; ii<nTabList; ii++){
- pLevel = &pWInfo->a[ii];
- explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
- notReady = codeOneLoopStart(pWInfo, ii, wctrlFlags, notReady);
- pWInfo->iContinue = pLevel->addrCont;
- }
-
-#ifdef SQLITE_TEST /* For testing and debugging use only */
- /* Record in the query plan information about the current table
- ** and the index used to access it (if any). If the table itself
- ** is not used, its name is just '{}'. If no index is used
- ** the index is listed as "{}". If the primary key is used the
- ** index name is '*'.
- */
- for(ii=0; ii<nTabList; ii++){
- char *z;
- int n;
- int w;
- struct SrcList_item *pTabItem;
-
- pLevel = &pWInfo->a[ii];
- w = pLevel->plan.wsFlags;
- pTabItem = &pTabList->a[pLevel->iFrom];
- z = pTabItem->zAlias;
- if( z==0 ) z = pTabItem->pTab->zName;
- n = sqlite3Strlen30(z);
- if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){
- if( (w & WHERE_IDX_ONLY)!=0 && (w & WHERE_COVER_SCAN)==0 ){
- memcpy(&sqlite3_query_plan[nQPlan], "{}", 2);
- nQPlan += 2;
- }else{
- memcpy(&sqlite3_query_plan[nQPlan], z, n);
- nQPlan += n;
- }
- sqlite3_query_plan[nQPlan++] = ' ';
- }
- testcase( w & WHERE_ROWID_EQ );
- testcase( w & WHERE_ROWID_RANGE );
- if( w & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
- memcpy(&sqlite3_query_plan[nQPlan], "* ", 2);
- nQPlan += 2;
- }else if( (w & WHERE_INDEXED)!=0 && (w & WHERE_COVER_SCAN)==0 ){
- n = sqlite3Strlen30(pLevel->plan.u.pIdx->zName);
- if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){
- memcpy(&sqlite3_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n);
- nQPlan += n;
- sqlite3_query_plan[nQPlan++] = ' ';
- }
- }else{
- memcpy(&sqlite3_query_plan[nQPlan], "{} ", 3);
- nQPlan += 3;
- }
- }
- while( nQPlan>0 && sqlite3_query_plan[nQPlan-1]==' ' ){
- sqlite3_query_plan[--nQPlan] = 0;
- }
- sqlite3_query_plan[nQPlan] = 0;
- nQPlan = 0;
-#endif /* SQLITE_TEST // Testing and debugging use only */
-
- /* Record the continuation address in the WhereInfo structure. Then
- ** clean up and return.
- */
- return pWInfo;
-
- /* Jump here if malloc fails */
-whereBeginError:
- if( pWInfo ){
- pParse->nQueryLoop = pWInfo->savedNQueryLoop;
- whereInfoFree(db, pWInfo);
- }
- return 0;
-}
-
-/*
-** Generate the end of the WHERE loop. See comments on
-** sqlite3WhereBegin() for additional information.
-*/
-SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
- Parse *pParse = pWInfo->pParse;
- Vdbe *v = pParse->pVdbe;
- int i;
- WhereLevel *pLevel;
- SrcList *pTabList = pWInfo->pTabList;
- sqlite3 *db = pParse->db;
-
- /* Generate loop termination code.
- */
- sqlite3ExprCacheClear(pParse);
- for(i=pWInfo->nLevel-1; i>=0; i--){
- pLevel = &pWInfo->a[i];
- sqlite3VdbeResolveLabel(v, pLevel->addrCont);
- if( pLevel->op!=OP_Noop ){
- sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
- sqlite3VdbeChangeP5(v, pLevel->p5);
- }
- if( pLevel->plan.wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
- struct InLoop *pIn;
- int j;
- sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
- for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
- sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
- sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->addrInTop);
- sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
- }
- sqlite3DbFree(db, pLevel->u.in.aInLoop);
- }
- sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
- if( pLevel->iLeftJoin ){
- int addr;
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
- assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
- || (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 );
- if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 ){
- sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
- }
- if( pLevel->iIdxCur>=0 ){
- sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
- }
- if( pLevel->op==OP_Return ){
- sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst);
- }else{
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrFirst);
- }
- sqlite3VdbeJumpHere(v, addr);
- }
- }
-
- /* The "break" point is here, just past the end of the outer loop.
- ** Set it.
- */
- sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
-
- /* Close all of the cursors that were opened by sqlite3WhereBegin.
- */
- assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc );
- for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
- Index *pIdx = 0;
- struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
- Table *pTab = pTabItem->pTab;
- assert( pTab!=0 );
- if( (pTab->tabFlags & TF_Ephemeral)==0
- && pTab->pSelect==0
- && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
- ){
- int ws = pLevel->plan.wsFlags;
- if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
- sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
- }
- if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_TEMP_INDEX)==0 ){
- sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
- }
- }
-
- /* If this scan uses an index, make code substitutions to read data
- ** from the index in preference to the table. Sometimes, this means
- ** the table need never be read from. This is a performance boost,
- ** as the vdbe level waits until the table is read before actually
- ** seeking the table cursor to the record corresponding to the current
- ** position in the index.
- **
- ** Calls to the code generator in between sqlite3WhereBegin and
- ** sqlite3WhereEnd will have created code that references the table
- ** directly. This loop scans all that code looking for opcodes
- ** that reference the table and converts them into opcodes that
- ** reference the index.
- */
- if( pLevel->plan.wsFlags & WHERE_INDEXED ){
- pIdx = pLevel->plan.u.pIdx;
- }else if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
- pIdx = pLevel->u.pCovidx;
- }
- if( pIdx && !db->mallocFailed){
- int k, j, last;
- VdbeOp *pOp;
-
- pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
- last = sqlite3VdbeCurrentAddr(v);
- for(k=pWInfo->iTop; k<last; k++, pOp++){
- if( pOp->p1!=pLevel->iTabCur ) continue;
- if( pOp->opcode==OP_Column ){
- for(j=0; j<pIdx->nColumn; j++){
- if( pOp->p2==pIdx->aiColumn[j] ){
- pOp->p2 = j;
- pOp->p1 = pLevel->iIdxCur;
- break;
- }
- }
- assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
- || j<pIdx->nColumn );
- }else if( pOp->opcode==OP_Rowid ){
- pOp->p1 = pLevel->iIdxCur;
- pOp->opcode = OP_IdxRowid;
- }
- }
- }
- }
-
- /* Final cleanup
- */
- pParse->nQueryLoop = pWInfo->savedNQueryLoop;
- whereInfoFree(db, pWInfo);
- return;
-}
-
-/************** End of where.c ***********************************************/
-/************** Begin file parse.c *******************************************/
-/* Driver template for the LEMON parser generator.
-** The author disclaims copyright to this source code.
-**
-** This version of "lempar.c" is modified, slightly, for use by SQLite.
-** The only modifications are the addition of a couple of NEVER()
-** macros to disable tests that are needed in the case of a general
-** LALR(1) grammar but which are always false in the
-** specific grammar used by SQLite.
-*/
-/* First off, code is included that follows the "include" declaration
-** in the input grammar file. */
-/* #include <stdio.h> */
-
-
-/*
-** Disable all error recovery processing in the parser push-down
-** automaton.
-*/
-#define YYNOERRORRECOVERY 1
-
-/*
-** Make yytestcase() the same as testcase()
-*/
-#define yytestcase(X) testcase(X)
-
-/*
-** An instance of this structure holds information about the
-** LIMIT clause of a SELECT statement.
-*/
-struct LimitVal {
- Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */
- Expr *pOffset; /* The OFFSET expression. NULL if there is none */
-};
-
-/*
-** An instance of this structure is used to store the LIKE,
-** GLOB, NOT LIKE, and NOT GLOB operators.
-*/
-struct LikeOp {
- Token eOperator; /* "like" or "glob" or "regexp" */
- int bNot; /* True if the NOT keyword is present */
-};
-
-/*
-** An instance of the following structure describes the event of a
-** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
-** TK_DELETE, or TK_INSTEAD. If the event is of the form
-**
-** UPDATE ON (a,b,c)
-**
-** Then the "b" IdList records the list "a,b,c".
-*/
-struct TrigEvent { int a; IdList * b; };
-
-/*
-** An instance of this structure holds the ATTACH key and the key type.
-*/
-struct AttachKey { int type; Token key; };
-
-/*
-** One or more VALUES claues
-*/
-struct ValueList {
- ExprList *pList;
- Select *pSelect;
-};
-
-
- /* This is a utility routine used to set the ExprSpan.zStart and
- ** ExprSpan.zEnd values of pOut so that the span covers the complete
- ** range of text beginning with pStart and going to the end of pEnd.
- */
- static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
- pOut->zStart = pStart->z;
- pOut->zEnd = &pEnd->z[pEnd->n];
- }
-
- /* Construct a new Expr object from a single identifier. Use the
- ** new Expr to populate pOut. Set the span of pOut to be the identifier
- ** that created the expression.
- */
- static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){
- pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue);
- pOut->zStart = pValue->z;
- pOut->zEnd = &pValue->z[pValue->n];
- }
-
- /* This routine constructs a binary expression node out of two ExprSpan
- ** objects and uses the result to populate a new ExprSpan object.
- */
- static void spanBinaryExpr(
- ExprSpan *pOut, /* Write the result here */
- Parse *pParse, /* The parsing context. Errors accumulate here */
- int op, /* The binary operation */
- ExprSpan *pLeft, /* The left operand */
- ExprSpan *pRight /* The right operand */
- ){
- pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
- pOut->zStart = pLeft->zStart;
- pOut->zEnd = pRight->zEnd;
- }
-
- /* Construct an expression node for a unary postfix operator
- */
- static void spanUnaryPostfix(
- ExprSpan *pOut, /* Write the new expression node here */
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand */
- Token *pPostOp /* The operand token for setting the span */
- ){
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
- pOut->zStart = pOperand->zStart;
- pOut->zEnd = &pPostOp->z[pPostOp->n];
- }
-
- /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
- ** unary TK_ISNULL or TK_NOTNULL expression. */
- static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
- sqlite3 *db = pParse->db;
- if( db->mallocFailed==0 && pY->op==TK_NULL ){
- pA->op = (u8)op;
- sqlite3ExprDelete(db, pA->pRight);
- pA->pRight = 0;
- }
- }
-
- /* Construct an expression node for a unary prefix operator
- */
- static void spanUnaryPrefix(
- ExprSpan *pOut, /* Write the new expression node here */
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand */
- Token *pPreOp /* The operand token for setting the span */
- ){
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
- pOut->zStart = pPreOp->z;
- pOut->zEnd = pOperand->zEnd;
- }
-/* Next is all token values, in a form suitable for use by makeheaders.
-** This section will be null unless lemon is run with the -m switch.
-*/
-/*
-** These constants (all generated automatically by the parser generator)
-** specify the various kinds of tokens (terminals) that the parser
-** understands.
-**
-** Each symbol here is a terminal symbol in the grammar.
-*/
-/* Make sure the INTERFACE macro is defined.
-*/
-#ifndef INTERFACE
-# define INTERFACE 1
-#endif
-/* The next thing included is series of defines which control
-** various aspects of the generated parser.
-** YYCODETYPE is the data type used for storing terminal
-** and nonterminal numbers. "unsigned char" is
-** used if there are fewer than 250 terminals
-** and nonterminals. "int" is used otherwise.
-** YYNOCODE is a number of type YYCODETYPE which corresponds
-** to no legal terminal or nonterminal number. This
-** number is used to fill in empty slots of the hash
-** table.
-** YYFALLBACK If defined, this indicates that one or more tokens
-** have fall-back values which should be used if the
-** original value of the token will not parse.
-** YYACTIONTYPE is the data type used for storing terminal
-** and nonterminal numbers. "unsigned char" is
-** used if there are fewer than 250 rules and
-** states combined. "int" is used otherwise.
-** sqlite3ParserTOKENTYPE is the data type used for minor tokens given
-** directly to the parser from the tokenizer.
-** YYMINORTYPE is the data type used for all minor tokens.
-** This is typically a union of many types, one of
-** which is sqlite3ParserTOKENTYPE. The entry in the union
-** for base tokens is called "yy0".
-** YYSTACKDEPTH is the maximum depth of the parser's stack. If
-** zero the stack is dynamically sized using realloc()
-** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument
-** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument
-** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser
-** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser
-** YYNSTATE the combined number of states.
-** YYNRULE the number of rules in the grammar
-** YYERRORSYMBOL is the code number of the error symbol. If not
-** defined, then do no error processing.
-*/
-#define YYCODETYPE unsigned char
-#define YYNOCODE 251
-#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 67
-#define sqlite3ParserTOKENTYPE Token
-typedef union {
- int yyinit;
- sqlite3ParserTOKENTYPE yy0;
- struct LimitVal yy64;
- Expr* yy122;
- Select* yy159;
- IdList* yy180;
- struct {int value; int mask;} yy207;
- u8 yy258;
- struct LikeOp yy318;
- TriggerStep* yy327;
- ExprSpan yy342;
- SrcList* yy347;
- int yy392;
- struct TrigEvent yy410;
- ExprList* yy442;
- struct ValueList yy487;
-} YYMINORTYPE;
-#ifndef YYSTACKDEPTH
-#define YYSTACKDEPTH 100
-#endif
-#define sqlite3ParserARG_SDECL Parse *pParse;
-#define sqlite3ParserARG_PDECL ,Parse *pParse
-#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
-#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 627
-#define YYNRULE 327
-#define YYFALLBACK 1
-#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
-#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
-#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
-
-/* The yyzerominor constant is used to initialize instances of
-** YYMINORTYPE objects to zero. */
-static const YYMINORTYPE yyzerominor = { 0 };
-
-/* Define the yytestcase() macro to be a no-op if is not already defined
-** otherwise.
-**
-** Applications can choose to define yytestcase() in the %include section
-** to a macro that can assist in verifying code coverage. For production
-** code the yytestcase() macro should be turned off. But it is useful
-** for testing.
-*/
-#ifndef yytestcase
-# define yytestcase(X)
-#endif
-
-
-/* Next are the tables used to determine what action to take based on the
-** current state and lookahead token. These tables are used to implement
-** functions that take a state number and lookahead value and return an
-** action integer.
-**
-** Suppose the action integer is N. Then the action is determined as
-** follows
-**
-** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
-** token onto the stack and goto state N.
-**
-** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
-**
-** N == YYNSTATE+YYNRULE A syntax error has occurred.
-**
-** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
-**
-** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
-** slots in the yy_action[] table.
-**
-** The action table is constructed as a single large table named yy_action[].
-** Given state S and lookahead X, the action is computed as
-**
-** yy_action[ yy_shift_ofst[S] + X ]
-**
-** If the index value yy_shift_ofst[S]+X is out of range or if the value
-** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
-** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
-** and that yy_default[S] should be used instead.
-**
-** The formula above is for computing the action when the lookahead is
-** a terminal symbol. If the lookahead is a non-terminal (as occurs after
-** a reduce action) then the yy_reduce_ofst[] array is used in place of
-** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
-** YY_SHIFT_USE_DFLT.
-**
-** The following are the tables generated in this section:
-**
-** yy_action[] A single table containing all actions.
-** yy_lookahead[] A table containing the lookahead for each entry in
-** yy_action. Used to detect hash collisions.
-** yy_shift_ofst[] For each state, the offset into yy_action for
-** shifting terminals.
-** yy_reduce_ofst[] For each state, the offset into yy_action for
-** shifting non-terminals after a reduce.
-** yy_default[] Default action for each state.
-*/
-#define YY_ACTTAB_COUNT (1564)
-static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 309, 955, 184, 417, 2, 171, 624, 594, 56, 56,
- /* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52,
- /* 20 */ 52, 52, 51, 233, 620, 619, 298, 620, 619, 234,
- /* 30 */ 587, 581, 56, 56, 56, 56, 19, 54, 54, 54,
- /* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 605, 57,
- /* 50 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
- /* 60 */ 56, 56, 541, 54, 54, 54, 54, 53, 53, 52,
- /* 70 */ 52, 52, 51, 233, 309, 594, 325, 196, 195, 194,
- /* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 90 */ 51, 233, 617, 616, 165, 617, 616, 380, 377, 376,
- /* 100 */ 407, 532, 576, 576, 587, 581, 303, 422, 375, 59,
- /* 110 */ 53, 53, 52, 52, 52, 51, 233, 50, 47, 146,
- /* 120 */ 574, 545, 65, 57, 58, 48, 579, 578, 580, 580,
- /* 130 */ 55, 55, 56, 56, 56, 56, 213, 54, 54, 54,
- /* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 223,
- /* 150 */ 539, 420, 170, 176, 138, 280, 383, 275, 382, 168,
- /* 160 */ 489, 551, 409, 668, 620, 619, 271, 438, 409, 438,
- /* 170 */ 550, 604, 67, 482, 507, 618, 599, 412, 587, 581,
- /* 180 */ 600, 483, 618, 412, 618, 598, 91, 439, 440, 439,
- /* 190 */ 335, 598, 73, 669, 222, 266, 480, 57, 58, 48,
- /* 200 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
- /* 210 */ 670, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 220 */ 51, 233, 309, 279, 232, 231, 1, 132, 200, 385,
- /* 230 */ 620, 619, 617, 616, 278, 435, 289, 563, 175, 262,
- /* 240 */ 409, 264, 437, 497, 436, 166, 441, 568, 336, 568,
- /* 250 */ 201, 537, 587, 581, 599, 412, 165, 594, 600, 380,
- /* 260 */ 377, 376, 597, 598, 92, 523, 618, 569, 569, 592,
- /* 270 */ 375, 57, 58, 48, 579, 578, 580, 580, 55, 55,
- /* 280 */ 56, 56, 56, 56, 597, 54, 54, 54, 54, 53,
- /* 290 */ 53, 52, 52, 52, 51, 233, 309, 463, 617, 616,
- /* 300 */ 590, 590, 590, 174, 272, 396, 409, 272, 409, 548,
- /* 310 */ 397, 620, 619, 68, 326, 620, 619, 620, 619, 618,
- /* 320 */ 546, 412, 618, 412, 471, 594, 587, 581, 472, 598,
- /* 330 */ 92, 598, 92, 52, 52, 52, 51, 233, 513, 512,
- /* 340 */ 206, 322, 363, 464, 221, 57, 58, 48, 579, 578,
- /* 350 */ 580, 580, 55, 55, 56, 56, 56, 56, 529, 54,
- /* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
- /* 370 */ 309, 396, 409, 396, 597, 372, 386, 530, 347, 617,
- /* 380 */ 616, 575, 202, 617, 616, 617, 616, 412, 620, 619,
- /* 390 */ 145, 255, 346, 254, 577, 598, 74, 351, 45, 489,
- /* 400 */ 587, 581, 235, 189, 464, 544, 167, 296, 187, 469,
- /* 410 */ 479, 67, 62, 39, 618, 546, 597, 345, 573, 57,
- /* 420 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
- /* 430 */ 56, 56, 6, 54, 54, 54, 54, 53, 53, 52,
- /* 440 */ 52, 52, 51, 233, 309, 562, 558, 407, 528, 576,
- /* 450 */ 576, 344, 255, 346, 254, 182, 617, 616, 503, 504,
- /* 460 */ 314, 409, 557, 235, 166, 271, 409, 352, 564, 181,
- /* 470 */ 407, 546, 576, 576, 587, 581, 412, 537, 556, 561,
- /* 480 */ 517, 412, 618, 249, 598, 16, 7, 36, 467, 598,
- /* 490 */ 92, 516, 618, 57, 58, 48, 579, 578, 580, 580,
- /* 500 */ 55, 55, 56, 56, 56, 56, 541, 54, 54, 54,
- /* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 327,
- /* 520 */ 572, 571, 525, 558, 560, 394, 871, 246, 409, 248,
- /* 530 */ 171, 392, 594, 219, 407, 409, 576, 576, 502, 557,
- /* 540 */ 364, 145, 510, 412, 407, 229, 576, 576, 587, 581,
- /* 550 */ 412, 598, 92, 381, 269, 556, 166, 400, 598, 69,
- /* 560 */ 501, 419, 945, 199, 945, 198, 546, 57, 58, 48,
- /* 570 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
- /* 580 */ 568, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 590 */ 51, 233, 309, 317, 419, 944, 508, 944, 308, 597,
- /* 600 */ 594, 565, 490, 212, 173, 247, 423, 615, 614, 613,
- /* 610 */ 323, 197, 143, 405, 572, 571, 489, 66, 50, 47,
- /* 620 */ 146, 594, 587, 581, 232, 231, 559, 427, 67, 555,
- /* 630 */ 15, 618, 186, 543, 303, 421, 35, 206, 432, 423,
- /* 640 */ 552, 57, 58, 48, 579, 578, 580, 580, 55, 55,
- /* 650 */ 56, 56, 56, 56, 205, 54, 54, 54, 54, 53,
- /* 660 */ 53, 52, 52, 52, 51, 233, 309, 569, 569, 260,
- /* 670 */ 268, 597, 12, 373, 568, 166, 409, 313, 409, 420,
- /* 680 */ 409, 473, 473, 365, 618, 50, 47, 146, 597, 594,
- /* 690 */ 468, 412, 166, 412, 351, 412, 587, 581, 32, 598,
- /* 700 */ 94, 598, 97, 598, 95, 627, 625, 329, 142, 50,
- /* 710 */ 47, 146, 333, 349, 358, 57, 58, 48, 579, 578,
- /* 720 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
- /* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
- /* 740 */ 309, 409, 388, 412, 409, 22, 565, 404, 212, 362,
- /* 750 */ 389, 598, 104, 359, 409, 156, 412, 409, 603, 412,
- /* 760 */ 537, 331, 569, 569, 598, 103, 493, 598, 105, 412,
- /* 770 */ 587, 581, 412, 260, 549, 618, 11, 598, 106, 521,
- /* 780 */ 598, 133, 169, 457, 456, 170, 35, 601, 618, 57,
- /* 790 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
- /* 800 */ 56, 56, 409, 54, 54, 54, 54, 53, 53, 52,
- /* 810 */ 52, 52, 51, 233, 309, 409, 259, 412, 409, 50,
- /* 820 */ 47, 146, 357, 318, 355, 598, 134, 527, 352, 337,
- /* 830 */ 412, 409, 356, 412, 357, 409, 357, 618, 598, 98,
- /* 840 */ 129, 598, 102, 618, 587, 581, 412, 21, 235, 618,
- /* 850 */ 412, 618, 211, 143, 598, 101, 30, 167, 598, 93,
- /* 860 */ 350, 535, 203, 57, 58, 48, 579, 578, 580, 580,
- /* 870 */ 55, 55, 56, 56, 56, 56, 409, 54, 54, 54,
- /* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 409,
- /* 890 */ 526, 412, 409, 425, 215, 305, 597, 551, 141, 598,
- /* 900 */ 100, 40, 409, 38, 412, 409, 550, 412, 409, 228,
- /* 910 */ 220, 314, 598, 77, 500, 598, 96, 412, 587, 581,
- /* 920 */ 412, 338, 253, 412, 218, 598, 137, 379, 598, 136,
- /* 930 */ 28, 598, 135, 270, 715, 210, 481, 57, 58, 48,
- /* 940 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
- /* 950 */ 409, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 960 */ 51, 233, 309, 409, 272, 412, 409, 315, 147, 597,
- /* 970 */ 272, 626, 2, 598, 76, 209, 409, 127, 412, 618,
- /* 980 */ 126, 412, 409, 621, 235, 618, 598, 90, 374, 598,
- /* 990 */ 89, 412, 587, 581, 27, 260, 350, 412, 618, 598,
- /* 1000 */ 75, 321, 541, 541, 125, 598, 88, 320, 278, 597,
- /* 1010 */ 618, 57, 46, 48, 579, 578, 580, 580, 55, 55,
- /* 1020 */ 56, 56, 56, 56, 409, 54, 54, 54, 54, 53,
- /* 1030 */ 53, 52, 52, 52, 51, 233, 309, 409, 450, 412,
- /* 1040 */ 164, 284, 282, 272, 609, 424, 304, 598, 87, 370,
- /* 1050 */ 409, 477, 412, 409, 608, 409, 607, 602, 618, 618,
- /* 1060 */ 598, 99, 586, 585, 122, 412, 587, 581, 412, 618,
- /* 1070 */ 412, 618, 618, 598, 86, 366, 598, 17, 598, 85,
- /* 1080 */ 319, 185, 519, 518, 583, 582, 58, 48, 579, 578,
- /* 1090 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
- /* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
- /* 1110 */ 309, 584, 409, 412, 409, 260, 260, 260, 408, 591,
- /* 1120 */ 474, 598, 84, 170, 409, 466, 518, 412, 121, 412,
- /* 1130 */ 618, 618, 618, 618, 618, 598, 83, 598, 72, 412,
- /* 1140 */ 587, 581, 51, 233, 625, 329, 470, 598, 71, 257,
- /* 1150 */ 159, 120, 14, 462, 157, 158, 117, 260, 448, 447,
- /* 1160 */ 446, 48, 579, 578, 580, 580, 55, 55, 56, 56,
- /* 1170 */ 56, 56, 618, 54, 54, 54, 54, 53, 53, 52,
- /* 1180 */ 52, 52, 51, 233, 44, 403, 260, 3, 409, 459,
- /* 1190 */ 260, 413, 619, 118, 398, 10, 25, 24, 554, 348,
- /* 1200 */ 217, 618, 406, 412, 409, 618, 4, 44, 403, 618,
- /* 1210 */ 3, 598, 82, 618, 413, 619, 455, 542, 115, 412,
- /* 1220 */ 538, 401, 536, 274, 506, 406, 251, 598, 81, 216,
- /* 1230 */ 273, 563, 618, 243, 453, 618, 154, 618, 618, 618,
- /* 1240 */ 449, 416, 623, 110, 401, 618, 409, 236, 64, 123,
- /* 1250 */ 487, 41, 42, 531, 563, 204, 409, 267, 43, 411,
- /* 1260 */ 410, 412, 265, 592, 108, 618, 107, 434, 332, 598,
- /* 1270 */ 80, 412, 618, 263, 41, 42, 443, 618, 409, 598,
- /* 1280 */ 70, 43, 411, 410, 433, 261, 592, 149, 618, 597,
- /* 1290 */ 256, 237, 188, 412, 590, 590, 590, 589, 588, 13,
- /* 1300 */ 618, 598, 18, 328, 235, 618, 44, 403, 360, 3,
- /* 1310 */ 418, 461, 339, 413, 619, 227, 124, 590, 590, 590,
- /* 1320 */ 589, 588, 13, 618, 406, 409, 618, 409, 139, 34,
- /* 1330 */ 403, 387, 3, 148, 622, 312, 413, 619, 311, 330,
- /* 1340 */ 412, 460, 412, 401, 180, 353, 412, 406, 598, 79,
- /* 1350 */ 598, 78, 250, 563, 598, 9, 618, 612, 611, 610,
- /* 1360 */ 618, 8, 452, 442, 242, 415, 401, 618, 239, 235,
- /* 1370 */ 179, 238, 428, 41, 42, 288, 563, 618, 618, 618,
- /* 1380 */ 43, 411, 410, 618, 144, 592, 618, 618, 177, 61,
- /* 1390 */ 618, 596, 391, 620, 619, 287, 41, 42, 414, 618,
- /* 1400 */ 293, 30, 393, 43, 411, 410, 292, 618, 592, 31,
- /* 1410 */ 618, 395, 291, 60, 230, 37, 590, 590, 590, 589,
- /* 1420 */ 588, 13, 214, 553, 183, 290, 172, 301, 300, 299,
- /* 1430 */ 178, 297, 595, 563, 451, 29, 285, 390, 540, 590,
- /* 1440 */ 590, 590, 589, 588, 13, 283, 520, 534, 150, 533,
- /* 1450 */ 241, 281, 384, 192, 191, 324, 515, 514, 276, 240,
- /* 1460 */ 510, 523, 307, 511, 128, 592, 509, 225, 226, 486,
- /* 1470 */ 485, 224, 152, 491, 464, 306, 484, 163, 153, 371,
- /* 1480 */ 478, 151, 162, 258, 369, 161, 367, 208, 475, 476,
- /* 1490 */ 26, 160, 465, 140, 361, 131, 590, 590, 590, 116,
- /* 1500 */ 119, 454, 343, 155, 114, 342, 113, 112, 445, 111,
- /* 1510 */ 130, 109, 431, 316, 426, 430, 23, 429, 20, 606,
- /* 1520 */ 190, 507, 255, 341, 244, 63, 294, 593, 310, 570,
- /* 1530 */ 277, 402, 354, 235, 567, 496, 495, 492, 494, 302,
- /* 1540 */ 458, 378, 286, 245, 566, 5, 252, 547, 193, 444,
- /* 1550 */ 233, 340, 207, 524, 368, 505, 334, 522, 499, 399,
- /* 1560 */ 295, 498, 956, 488,
-};
-static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78,
- /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- /* 20 */ 89, 90, 91, 92, 26, 27, 15, 26, 27, 197,
- /* 30 */ 49, 50, 77, 78, 79, 80, 204, 82, 83, 84,
- /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 23, 68,
- /* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 60 */ 79, 80, 166, 82, 83, 84, 85, 86, 87, 88,
- /* 70 */ 89, 90, 91, 92, 19, 94, 19, 105, 106, 107,
- /* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 90 */ 91, 92, 94, 95, 96, 94, 95, 99, 100, 101,
- /* 100 */ 112, 205, 114, 115, 49, 50, 22, 23, 110, 54,
- /* 110 */ 86, 87, 88, 89, 90, 91, 92, 221, 222, 223,
- /* 120 */ 23, 120, 25, 68, 69, 70, 71, 72, 73, 74,
- /* 130 */ 75, 76, 77, 78, 79, 80, 22, 82, 83, 84,
- /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 92,
- /* 150 */ 23, 67, 25, 96, 97, 98, 99, 100, 101, 102,
- /* 160 */ 150, 32, 150, 118, 26, 27, 109, 150, 150, 150,
- /* 170 */ 41, 161, 162, 180, 181, 165, 113, 165, 49, 50,
- /* 180 */ 117, 188, 165, 165, 165, 173, 174, 170, 171, 170,
- /* 190 */ 171, 173, 174, 118, 184, 16, 186, 68, 69, 70,
- /* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 210 */ 118, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 220 */ 91, 92, 19, 98, 86, 87, 22, 24, 160, 88,
- /* 230 */ 26, 27, 94, 95, 109, 97, 224, 66, 118, 60,
- /* 240 */ 150, 62, 104, 23, 106, 25, 229, 230, 229, 230,
- /* 250 */ 160, 150, 49, 50, 113, 165, 96, 26, 117, 99,
- /* 260 */ 100, 101, 194, 173, 174, 94, 165, 129, 130, 98,
- /* 270 */ 110, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 280 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86,
- /* 290 */ 87, 88, 89, 90, 91, 92, 19, 11, 94, 95,
- /* 300 */ 129, 130, 131, 118, 150, 215, 150, 150, 150, 25,
- /* 310 */ 220, 26, 27, 22, 213, 26, 27, 26, 27, 165,
- /* 320 */ 25, 165, 165, 165, 30, 94, 49, 50, 34, 173,
- /* 330 */ 174, 173, 174, 88, 89, 90, 91, 92, 7, 8,
- /* 340 */ 160, 187, 48, 57, 187, 68, 69, 70, 71, 72,
- /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 23, 82,
- /* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 370 */ 19, 215, 150, 215, 194, 19, 220, 88, 220, 94,
- /* 380 */ 95, 23, 160, 94, 95, 94, 95, 165, 26, 27,
- /* 390 */ 95, 105, 106, 107, 113, 173, 174, 217, 22, 150,
- /* 400 */ 49, 50, 116, 119, 57, 120, 50, 158, 22, 21,
- /* 410 */ 161, 162, 232, 136, 165, 120, 194, 237, 23, 68,
- /* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 430 */ 79, 80, 22, 82, 83, 84, 85, 86, 87, 88,
- /* 440 */ 89, 90, 91, 92, 19, 23, 12, 112, 23, 114,
- /* 450 */ 115, 63, 105, 106, 107, 23, 94, 95, 97, 98,
- /* 460 */ 104, 150, 28, 116, 25, 109, 150, 150, 23, 23,
- /* 470 */ 112, 25, 114, 115, 49, 50, 165, 150, 44, 11,
- /* 480 */ 46, 165, 165, 16, 173, 174, 76, 136, 100, 173,
- /* 490 */ 174, 57, 165, 68, 69, 70, 71, 72, 73, 74,
- /* 500 */ 75, 76, 77, 78, 79, 80, 166, 82, 83, 84,
- /* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 169,
- /* 520 */ 170, 171, 23, 12, 23, 214, 138, 60, 150, 62,
- /* 530 */ 24, 215, 26, 216, 112, 150, 114, 115, 36, 28,
- /* 540 */ 213, 95, 103, 165, 112, 205, 114, 115, 49, 50,
- /* 550 */ 165, 173, 174, 51, 23, 44, 25, 46, 173, 174,
- /* 560 */ 58, 22, 23, 22, 25, 160, 120, 68, 69, 70,
- /* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 580 */ 230, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 590 */ 91, 92, 19, 215, 22, 23, 23, 25, 163, 194,
- /* 600 */ 94, 166, 167, 168, 25, 138, 67, 7, 8, 9,
- /* 610 */ 108, 206, 207, 169, 170, 171, 150, 22, 221, 222,
- /* 620 */ 223, 26, 49, 50, 86, 87, 23, 161, 162, 23,
- /* 630 */ 22, 165, 24, 120, 22, 23, 25, 160, 241, 67,
- /* 640 */ 176, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 650 */ 77, 78, 79, 80, 160, 82, 83, 84, 85, 86,
- /* 660 */ 87, 88, 89, 90, 91, 92, 19, 129, 130, 150,
- /* 670 */ 23, 194, 35, 23, 230, 25, 150, 155, 150, 67,
- /* 680 */ 150, 105, 106, 107, 165, 221, 222, 223, 194, 94,
- /* 690 */ 23, 165, 25, 165, 217, 165, 49, 50, 25, 173,
- /* 700 */ 174, 173, 174, 173, 174, 0, 1, 2, 118, 221,
- /* 710 */ 222, 223, 193, 219, 237, 68, 69, 70, 71, 72,
- /* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
- /* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 740 */ 19, 150, 19, 165, 150, 24, 166, 167, 168, 227,
- /* 750 */ 27, 173, 174, 231, 150, 25, 165, 150, 172, 165,
- /* 760 */ 150, 242, 129, 130, 173, 174, 180, 173, 174, 165,
- /* 770 */ 49, 50, 165, 150, 176, 165, 35, 173, 174, 165,
- /* 780 */ 173, 174, 35, 23, 23, 25, 25, 173, 165, 68,
- /* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88,
- /* 810 */ 89, 90, 91, 92, 19, 150, 193, 165, 150, 221,
- /* 820 */ 222, 223, 150, 213, 19, 173, 174, 23, 150, 97,
- /* 830 */ 165, 150, 27, 165, 150, 150, 150, 165, 173, 174,
- /* 840 */ 22, 173, 174, 165, 49, 50, 165, 52, 116, 165,
- /* 850 */ 165, 165, 206, 207, 173, 174, 126, 50, 173, 174,
- /* 860 */ 128, 27, 160, 68, 69, 70, 71, 72, 73, 74,
- /* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84,
- /* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150,
- /* 890 */ 23, 165, 150, 23, 216, 25, 194, 32, 39, 173,
- /* 900 */ 174, 135, 150, 137, 165, 150, 41, 165, 150, 52,
- /* 910 */ 238, 104, 173, 174, 29, 173, 174, 165, 49, 50,
- /* 920 */ 165, 219, 238, 165, 238, 173, 174, 52, 173, 174,
- /* 930 */ 22, 173, 174, 23, 23, 160, 25, 68, 69, 70,
- /* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 960 */ 91, 92, 19, 150, 150, 165, 150, 245, 246, 194,
- /* 970 */ 150, 144, 145, 173, 174, 160, 150, 22, 165, 165,
- /* 980 */ 22, 165, 150, 150, 116, 165, 173, 174, 52, 173,
- /* 990 */ 174, 165, 49, 50, 22, 150, 128, 165, 165, 173,
- /* 1000 */ 174, 187, 166, 166, 22, 173, 174, 187, 109, 194,
- /* 1010 */ 165, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86,
- /* 1030 */ 87, 88, 89, 90, 91, 92, 19, 150, 193, 165,
- /* 1040 */ 102, 205, 205, 150, 150, 247, 248, 173, 174, 19,
- /* 1050 */ 150, 20, 165, 150, 150, 150, 150, 150, 165, 165,
- /* 1060 */ 173, 174, 49, 50, 104, 165, 49, 50, 165, 165,
- /* 1070 */ 165, 165, 165, 173, 174, 43, 173, 174, 173, 174,
- /* 1080 */ 187, 24, 190, 191, 71, 72, 69, 70, 71, 72,
- /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
- /* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 1110 */ 19, 98, 150, 165, 150, 150, 150, 150, 150, 150,
- /* 1120 */ 59, 173, 174, 25, 150, 190, 191, 165, 53, 165,
- /* 1130 */ 165, 165, 165, 165, 165, 173, 174, 173, 174, 165,
- /* 1140 */ 49, 50, 91, 92, 1, 2, 53, 173, 174, 138,
- /* 1150 */ 104, 22, 5, 1, 35, 118, 127, 150, 193, 193,
- /* 1160 */ 193, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 1170 */ 79, 80, 165, 82, 83, 84, 85, 86, 87, 88,
- /* 1180 */ 89, 90, 91, 92, 19, 20, 150, 22, 150, 27,
- /* 1190 */ 150, 26, 27, 108, 150, 22, 76, 76, 150, 25,
- /* 1200 */ 193, 165, 37, 165, 150, 165, 22, 19, 20, 165,
- /* 1210 */ 22, 173, 174, 165, 26, 27, 23, 150, 119, 165,
- /* 1220 */ 150, 56, 150, 150, 150, 37, 16, 173, 174, 193,
- /* 1230 */ 150, 66, 165, 193, 1, 165, 121, 165, 165, 165,
- /* 1240 */ 20, 146, 147, 119, 56, 165, 150, 152, 16, 154,
- /* 1250 */ 150, 86, 87, 88, 66, 160, 150, 150, 93, 94,
- /* 1260 */ 95, 165, 150, 98, 108, 165, 127, 23, 65, 173,
- /* 1270 */ 174, 165, 165, 150, 86, 87, 128, 165, 150, 173,
- /* 1280 */ 174, 93, 94, 95, 23, 150, 98, 15, 165, 194,
- /* 1290 */ 150, 140, 22, 165, 129, 130, 131, 132, 133, 134,
- /* 1300 */ 165, 173, 174, 3, 116, 165, 19, 20, 150, 22,
- /* 1310 */ 4, 150, 217, 26, 27, 179, 179, 129, 130, 131,
- /* 1320 */ 132, 133, 134, 165, 37, 150, 165, 150, 164, 19,
- /* 1330 */ 20, 150, 22, 246, 149, 249, 26, 27, 249, 244,
- /* 1340 */ 165, 150, 165, 56, 6, 150, 165, 37, 173, 174,
- /* 1350 */ 173, 174, 150, 66, 173, 174, 165, 149, 149, 13,
- /* 1360 */ 165, 25, 150, 150, 150, 149, 56, 165, 150, 116,
- /* 1370 */ 151, 150, 150, 86, 87, 150, 66, 165, 165, 165,
- /* 1380 */ 93, 94, 95, 165, 150, 98, 165, 165, 151, 22,
- /* 1390 */ 165, 194, 150, 26, 27, 150, 86, 87, 159, 165,
- /* 1400 */ 199, 126, 123, 93, 94, 95, 200, 165, 98, 124,
- /* 1410 */ 165, 122, 201, 125, 225, 135, 129, 130, 131, 132,
- /* 1420 */ 133, 134, 5, 157, 157, 202, 118, 10, 11, 12,
- /* 1430 */ 13, 14, 203, 66, 17, 104, 210, 121, 211, 129,
- /* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211,
- /* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42,
- /* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175,
- /* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18,
- /* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157,
- /* 1490 */ 135, 156, 189, 68, 157, 218, 129, 130, 131, 22,
- /* 1500 */ 189, 199, 157, 156, 192, 18, 192, 192, 199, 192,
- /* 1510 */ 218, 189, 40, 157, 38, 157, 240, 157, 240, 153,
- /* 1520 */ 196, 181, 105, 106, 107, 243, 198, 166, 111, 230,
- /* 1530 */ 176, 226, 239, 116, 230, 176, 166, 166, 176, 148,
- /* 1540 */ 199, 177, 209, 209, 166, 196, 239, 208, 185, 199,
- /* 1550 */ 92, 209, 233, 173, 234, 182, 139, 173, 182, 191,
- /* 1560 */ 195, 182, 250, 186,
-};
-#define YY_SHIFT_USE_DFLT (-70)
-#define YY_SHIFT_COUNT (416)
-#define YY_SHIFT_MIN (-69)
-#define YY_SHIFT_MAX (1487)
-static const short yy_shift_ofst[] = {
- /* 0 */ 1143, 1188, 1417, 1188, 1287, 1287, 138, 138, -2, -19,
- /* 10 */ 1287, 1287, 1287, 1287, 347, 362, 129, 129, 795, 1165,
- /* 20 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- /* 30 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- /* 40 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287,
- /* 50 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- /* 60 */ 1287, 1287, 286, 362, 362, 538, 538, 231, 1253, 55,
- /* 70 */ 721, 647, 573, 499, 425, 351, 277, 203, 869, 869,
- /* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869,
- /* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45,
- /* 100 */ -45, -45, -45, -45, -1, 24, 245, 362, 362, 362,
- /* 110 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 120 */ 362, 362, 362, 388, 356, 362, 362, 362, 362, 362,
- /* 130 */ 732, 868, 231, 1051, 1458, -70, -70, -70, 1367, 57,
- /* 140 */ 434, 434, 289, 291, 285, 1, 204, 572, 539, 362,
- /* 150 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 160 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 170 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 180 */ 362, 506, 506, 506, 705, 1253, 1253, 1253, -70, -70,
- /* 190 */ -70, 171, 171, 160, 502, 502, 502, 446, 432, 511,
- /* 200 */ 422, 358, 335, -12, -12, -12, -12, 576, 294, -12,
- /* 210 */ -12, 295, 595, 141, 600, 730, 723, 723, 805, 730,
- /* 220 */ 805, 439, 911, 231, 865, 231, 865, 807, 865, 723,
- /* 230 */ 766, 633, 633, 231, 284, 63, 608, 1476, 1308, 1308,
- /* 240 */ 1472, 1472, 1308, 1477, 1425, 1275, 1487, 1487, 1487, 1487,
- /* 250 */ 1308, 1461, 1275, 1477, 1425, 1425, 1308, 1461, 1355, 1441,
- /* 260 */ 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348, 1348,
- /* 270 */ 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408, 1348,
- /* 280 */ 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308, 1280,
- /* 290 */ 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346, 1338,
- /* 300 */ 1338, 1338, 1338, -70, -70, -70, -70, -70, -70, 1013,
- /* 310 */ 467, 612, 84, 179, -28, 870, 410, 761, 760, 667,
- /* 320 */ 650, 531, 220, 361, 331, 125, 127, 97, 1306, 1300,
- /* 330 */ 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174, 1139,
- /* 340 */ 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184, 1174,
- /* 350 */ 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152, 1147,
- /* 360 */ 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960, 1057,
- /* 370 */ 1031, 1030, 899, 938, 982, 936, 972, 958, 910, 955,
- /* 380 */ 875, 885, 908, 857, 859, 867, 804, 590, 834, 747,
- /* 390 */ 818, 513, 611, 741, 673, 637, 611, 606, 603, 579,
- /* 400 */ 501, 541, 468, 386, 445, 395, 376, 281, 185, 120,
- /* 410 */ 92, 75, 45, 114, 25, 11, 5,
-};
-#define YY_REDUCE_USE_DFLT (-169)
-#define YY_REDUCE_COUNT (308)
-#define YY_REDUCE_MIN (-168)
-#define YY_REDUCE_MAX (1391)
-static const short yy_reduce_ofst[] = {
- /* 0 */ -141, 90, 1095, 222, 158, 156, 19, 17, 10, -104,
- /* 10 */ 378, 316, 311, 12, 180, 249, 598, 464, 397, 1181,
- /* 20 */ 1177, 1175, 1128, 1106, 1096, 1054, 1038, 974, 964, 962,
- /* 30 */ 948, 905, 903, 900, 887, 874, 832, 826, 816, 813,
- /* 40 */ 800, 758, 755, 752, 742, 739, 726, 685, 681, 668,
- /* 50 */ 665, 652, 607, 604, 594, 591, 578, 530, 528, 526,
- /* 60 */ 385, 18, 477, 466, 519, 444, 350, 435, 405, 488,
- /* 70 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- /* 80 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- /* 90 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- /* 100 */ 488, 488, 488, 488, 488, 488, 488, 1040, 678, 1036,
- /* 110 */ 1007, 967, 966, 965, 845, 686, 610, 684, 317, 672,
- /* 120 */ 893, 327, 623, 522, -7, 820, 814, 157, 154, 101,
- /* 130 */ 702, 494, 580, 488, 488, 488, 488, 488, 614, 586,
- /* 140 */ 935, 892, 968, 1245, 1242, 1234, 1225, 798, 798, 1222,
- /* 150 */ 1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
- /* 160 */ 1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
- /* 170 */ 1070, 1067, 1048, 1044, 969, 968, 907, 906, 904, 894,
- /* 180 */ 833, 837, 836, 340, 827, 815, 775, 68, 722, 646,
- /* 190 */ -168, 1384, 1380, 1377, 1379, 1376, 1373, 1339, 1365, 1368,
- /* 200 */ 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1320, 1319, 1365,
- /* 210 */ 1365, 1339, 1378, 1349, 1391, 1350, 1342, 1334, 1307, 1341,
- /* 220 */ 1293, 1364, 1363, 1371, 1362, 1370, 1359, 1340, 1354, 1333,
- /* 230 */ 1305, 1304, 1299, 1361, 1328, 1324, 1366, 1282, 1360, 1358,
- /* 240 */ 1278, 1276, 1356, 1292, 1322, 1309, 1317, 1315, 1314, 1312,
- /* 250 */ 1345, 1347, 1302, 1277, 1311, 1303, 1337, 1335, 1252, 1248,
- /* 260 */ 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301, 1295,
- /* 270 */ 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274, 1281,
- /* 280 */ 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266, 1189,
- /* 290 */ 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219, 1216,
- /* 300 */ 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
-};
-static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 632, 866, 954, 954, 866, 866, 954, 954, 954, 756,
- /* 10 */ 954, 954, 954, 864, 954, 954, 784, 784, 928, 954,
- /* 20 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 30 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 40 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 50 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 60 */ 954, 954, 954, 954, 954, 954, 954, 671, 760, 790,
- /* 70 */ 954, 954, 954, 954, 954, 954, 954, 954, 927, 929,
- /* 80 */ 798, 797, 907, 771, 795, 788, 792, 867, 860, 861,
- /* 90 */ 859, 863, 868, 954, 791, 827, 844, 826, 838, 843,
- /* 100 */ 850, 842, 839, 829, 828, 830, 831, 954, 954, 954,
- /* 110 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 120 */ 954, 954, 954, 658, 725, 954, 954, 954, 954, 954,
- /* 130 */ 954, 954, 954, 832, 833, 847, 846, 845, 954, 663,
- /* 140 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 150 */ 934, 932, 954, 879, 954, 954, 954, 954, 954, 954,
- /* 160 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 170 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 180 */ 638, 756, 756, 756, 632, 954, 954, 954, 946, 760,
- /* 190 */ 750, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 200 */ 954, 954, 954, 800, 739, 917, 919, 954, 900, 737,
- /* 210 */ 660, 758, 673, 748, 640, 794, 773, 773, 912, 794,
- /* 220 */ 912, 696, 719, 954, 784, 954, 784, 693, 784, 773,
- /* 230 */ 862, 954, 954, 954, 757, 748, 954, 939, 764, 764,
- /* 240 */ 931, 931, 764, 806, 729, 794, 736, 736, 736, 736,
- /* 250 */ 764, 655, 794, 806, 729, 729, 764, 655, 906, 904,
- /* 260 */ 764, 764, 655, 764, 655, 764, 655, 872, 727, 727,
- /* 270 */ 727, 711, 876, 876, 872, 727, 696, 727, 711, 727,
- /* 280 */ 727, 777, 772, 777, 772, 777, 772, 764, 764, 954,
- /* 290 */ 789, 778, 787, 785, 794, 954, 714, 648, 648, 637,
- /* 300 */ 637, 637, 637, 951, 951, 946, 698, 698, 681, 954,
- /* 310 */ 954, 954, 954, 954, 954, 954, 881, 954, 954, 954,
- /* 320 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 633,
- /* 330 */ 941, 954, 954, 938, 954, 954, 954, 954, 799, 954,
- /* 340 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 916,
- /* 350 */ 954, 954, 954, 954, 954, 954, 954, 910, 954, 954,
- /* 360 */ 954, 954, 954, 954, 903, 902, 954, 954, 954, 954,
- /* 370 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 380 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 390 */ 954, 954, 786, 954, 779, 954, 865, 954, 954, 954,
- /* 400 */ 954, 954, 954, 954, 954, 954, 954, 742, 815, 954,
- /* 410 */ 814, 818, 813, 665, 954, 646, 954, 629, 634, 950,
- /* 420 */ 953, 952, 949, 948, 947, 942, 940, 937, 936, 935,
- /* 430 */ 933, 930, 926, 885, 883, 890, 889, 888, 887, 886,
- /* 440 */ 884, 882, 880, 801, 796, 793, 925, 878, 738, 735,
- /* 450 */ 734, 654, 943, 909, 918, 805, 804, 807, 915, 914,
- /* 460 */ 913, 911, 908, 895, 803, 802, 730, 870, 869, 657,
- /* 470 */ 899, 898, 897, 901, 905, 896, 766, 656, 653, 662,
- /* 480 */ 717, 718, 726, 724, 723, 722, 721, 720, 716, 664,
- /* 490 */ 672, 710, 695, 694, 875, 877, 874, 873, 703, 702,
- /* 500 */ 708, 707, 706, 705, 704, 701, 700, 699, 692, 691,
- /* 510 */ 697, 690, 713, 712, 709, 689, 733, 732, 731, 728,
- /* 520 */ 688, 687, 686, 818, 685, 684, 824, 823, 811, 854,
- /* 530 */ 753, 752, 751, 763, 762, 775, 774, 809, 808, 776,
- /* 540 */ 761, 755, 754, 770, 769, 768, 767, 759, 749, 781,
- /* 550 */ 783, 782, 780, 856, 765, 853, 924, 923, 922, 921,
- /* 560 */ 920, 858, 857, 825, 822, 676, 677, 893, 892, 894,
- /* 570 */ 891, 679, 678, 675, 674, 855, 744, 743, 851, 848,
- /* 580 */ 840, 836, 852, 849, 841, 837, 835, 834, 820, 819,
- /* 590 */ 817, 816, 812, 821, 667, 745, 741, 740, 810, 747,
- /* 600 */ 746, 683, 682, 680, 661, 659, 652, 650, 649, 651,
- /* 610 */ 647, 645, 644, 643, 642, 641, 670, 669, 668, 666,
- /* 620 */ 665, 639, 636, 635, 631, 630, 628,
-};
-
-/* The next table maps tokens into fallback tokens. If a construct
-** like the following:
-**
-** %fallback ID X Y Z.
-**
-** appears in the grammar, then ID becomes a fallback token for X, Y,
-** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
-** but it does not parse, the type of the token is changed to ID and
-** the parse is retried before an error is thrown.
-*/
-#ifdef YYFALLBACK
-static const YYCODETYPE yyFallback[] = {
- 0, /* $ => nothing */
- 0, /* SEMI => nothing */
- 26, /* EXPLAIN => ID */
- 26, /* QUERY => ID */
- 26, /* PLAN => ID */
- 26, /* BEGIN => ID */
- 0, /* TRANSACTION => nothing */
- 26, /* DEFERRED => ID */
- 26, /* IMMEDIATE => ID */
- 26, /* EXCLUSIVE => ID */
- 0, /* COMMIT => nothing */
- 26, /* END => ID */
- 26, /* ROLLBACK => ID */
- 26, /* SAVEPOINT => ID */
- 26, /* RELEASE => ID */
- 0, /* TO => nothing */
- 0, /* TABLE => nothing */
- 0, /* CREATE => nothing */
- 26, /* IF => ID */
- 0, /* NOT => nothing */
- 0, /* EXISTS => nothing */
- 26, /* TEMP => ID */
- 0, /* LP => nothing */
- 0, /* RP => nothing */
- 0, /* AS => nothing */
- 0, /* COMMA => nothing */
- 0, /* ID => nothing */
- 0, /* INDEXED => nothing */
- 26, /* ABORT => ID */
- 26, /* ACTION => ID */
- 26, /* AFTER => ID */
- 26, /* ANALYZE => ID */
- 26, /* ASC => ID */
- 26, /* ATTACH => ID */
- 26, /* BEFORE => ID */
- 26, /* BY => ID */
- 26, /* CASCADE => ID */
- 26, /* CAST => ID */
- 26, /* COLUMNKW => ID */
- 26, /* CONFLICT => ID */
- 26, /* DATABASE => ID */
- 26, /* DESC => ID */
- 26, /* DETACH => ID */
- 26, /* EACH => ID */
- 26, /* FAIL => ID */
- 26, /* FOR => ID */
- 26, /* IGNORE => ID */
- 26, /* INITIALLY => ID */
- 26, /* INSTEAD => ID */
- 26, /* LIKE_KW => ID */
- 26, /* MATCH => ID */
- 26, /* NO => ID */
- 26, /* KEY => ID */
- 26, /* OF => ID */
- 26, /* OFFSET => ID */
- 26, /* PRAGMA => ID */
- 26, /* RAISE => ID */
- 26, /* REPLACE => ID */
- 26, /* RESTRICT => ID */
- 26, /* ROW => ID */
- 26, /* TRIGGER => ID */
- 26, /* VACUUM => ID */
- 26, /* VIEW => ID */
- 26, /* VIRTUAL => ID */
- 26, /* REINDEX => ID */
- 26, /* RENAME => ID */
- 26, /* CTIME_KW => ID */
-};
-#endif /* YYFALLBACK */
-
-/* The following structure represents a single element of the
-** parser's stack. Information stored includes:
-**
-** + The state number for the parser at this level of the stack.
-**
-** + The value of the token stored at this level of the stack.
-** (In other words, the "major" token.)
-**
-** + The semantic value stored at this level of the stack. This is
-** the information used by the action routines in the grammar.
-** It is sometimes called the "minor" token.
-*/
-struct yyStackEntry {
- YYACTIONTYPE stateno; /* The state-number */
- YYCODETYPE major; /* The major token value. This is the code
- ** number for the token at this stack level */
- YYMINORTYPE minor; /* The user-supplied minor token value. This
- ** is the value of the token */
-};
-typedef struct yyStackEntry yyStackEntry;
-
-/* The state of the parser is completely contained in an instance of
-** the following structure */
-struct yyParser {
- int yyidx; /* Index of top element in stack */
-#ifdef YYTRACKMAXSTACKDEPTH
- int yyidxMax; /* Maximum value of yyidx */
-#endif
- int yyerrcnt; /* Shifts left before out of the error */
- sqlite3ParserARG_SDECL /* A place to hold %extra_argument */
-#if YYSTACKDEPTH<=0
- int yystksz; /* Current side of the stack */
- yyStackEntry *yystack; /* The parser's stack */
-#else
- yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
-#endif
-};
-typedef struct yyParser yyParser;
-
-#ifndef NDEBUG
-/* #include <stdio.h> */
-static FILE *yyTraceFILE = 0;
-static char *yyTracePrompt = 0;
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/*
-** Turn parser tracing on by giving a stream to which to write the trace
-** and a prompt to preface each trace message. Tracing is turned off
-** by making either argument NULL
-**
-** Inputs:
-** <ul>
-** <li> A FILE* to which trace output should be written.
-** If NULL, then tracing is turned off.
-** <li> A prefix string written at the beginning of every
-** line of trace output. If NULL, then tracing is
-** turned off.
-** </ul>
-**
-** Outputs:
-** None.
-*/
-SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){
- yyTraceFILE = TraceFILE;
- yyTracePrompt = zTracePrompt;
- if( yyTraceFILE==0 ) yyTracePrompt = 0;
- else if( yyTracePrompt==0 ) yyTraceFILE = 0;
-}
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/* For tracing shifts, the names of all terminals and nonterminals
-** are required. The following table supplies these names */
-static const char *const yyTokenName[] = {
- "$", "SEMI", "EXPLAIN", "QUERY",
- "PLAN", "BEGIN", "TRANSACTION", "DEFERRED",
- "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END",
- "ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
- "TABLE", "CREATE", "IF", "NOT",
- "EXISTS", "TEMP", "LP", "RP",
- "AS", "COMMA", "ID", "INDEXED",
- "ABORT", "ACTION", "AFTER", "ANALYZE",
- "ASC", "ATTACH", "BEFORE", "BY",
- "CASCADE", "CAST", "COLUMNKW", "CONFLICT",
- "DATABASE", "DESC", "DETACH", "EACH",
- "FAIL", "FOR", "IGNORE", "INITIALLY",
- "INSTEAD", "LIKE_KW", "MATCH", "NO",
- "KEY", "OF", "OFFSET", "PRAGMA",
- "RAISE", "REPLACE", "RESTRICT", "ROW",
- "TRIGGER", "VACUUM", "VIEW", "VIRTUAL",
- "REINDEX", "RENAME", "CTIME_KW", "ANY",
- "OR", "AND", "IS", "BETWEEN",
- "IN", "ISNULL", "NOTNULL", "NE",
- "EQ", "GT", "LE", "LT",
- "GE", "ESCAPE", "BITAND", "BITOR",
- "LSHIFT", "RSHIFT", "PLUS", "MINUS",
- "STAR", "SLASH", "REM", "CONCAT",
- "COLLATE", "BITNOT", "STRING", "JOIN_KW",
- "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY",
- "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR",
- "ON", "INSERT", "DELETE", "UPDATE",
- "SET", "DEFERRABLE", "FOREIGN", "DROP",
- "UNION", "ALL", "EXCEPT", "INTERSECT",
- "SELECT", "DISTINCT", "DOT", "FROM",
- "JOIN", "USING", "ORDER", "GROUP",
- "HAVING", "LIMIT", "WHERE", "INTO",
- "VALUES", "INTEGER", "FLOAT", "BLOB",
- "REGISTER", "VARIABLE", "CASE", "WHEN",
- "THEN", "ELSE", "INDEX", "ALTER",
- "ADD", "error", "input", "cmdlist",
- "ecmd", "explain", "cmdx", "cmd",
- "transtype", "trans_opt", "nm", "savepoint_opt",
- "create_table", "create_table_args", "createkw", "temp",
- "ifnotexists", "dbnm", "columnlist", "conslist_opt",
- "select", "column", "columnid", "type",
- "carglist", "id", "ids", "typetoken",
- "typename", "signed", "plus_num", "minus_num",
- "ccons", "term", "expr", "onconf",
- "sortorder", "autoinc", "idxlist_opt", "refargs",
- "defer_subclause", "refarg", "refact", "init_deferred_pred_opt",
- "conslist", "tconscomma", "tcons", "idxlist",
- "defer_subclause_opt", "orconf", "resolvetype", "raisetype",
- "ifexists", "fullname", "oneselect", "multiselect_op",
- "distinct", "selcollist", "from", "where_opt",
- "groupby_opt", "having_opt", "orderby_opt", "limit_opt",
- "sclp", "as", "seltablist", "stl_prefix",
- "joinop", "indexed_opt", "on_opt", "using_opt",
- "joinop2", "inscollist", "sortlist", "nexprlist",
- "setlist", "insert_cmd", "inscollist_opt", "valuelist",
- "exprlist", "likeop", "between_op", "in_op",
- "case_operand", "case_exprlist", "case_else", "uniqueflag",
- "collate", "nmnum", "number", "trigger_decl",
- "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause",
- "when_clause", "trigger_cmd", "trnm", "tridxby",
- "database_kw_opt", "key_opt", "add_column_fullname", "kwcolumn_opt",
- "create_vtab", "vtabarglist", "vtabarg", "vtabargtoken",
- "lp", "anylist",
-};
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/* For tracing reduce actions, the names of all rules are required.
-*/
-static const char *const yyRuleName[] = {
- /* 0 */ "input ::= cmdlist",
- /* 1 */ "cmdlist ::= cmdlist ecmd",
- /* 2 */ "cmdlist ::= ecmd",
- /* 3 */ "ecmd ::= SEMI",
- /* 4 */ "ecmd ::= explain cmdx SEMI",
- /* 5 */ "explain ::=",
- /* 6 */ "explain ::= EXPLAIN",
- /* 7 */ "explain ::= EXPLAIN QUERY PLAN",
- /* 8 */ "cmdx ::= cmd",
- /* 9 */ "cmd ::= BEGIN transtype trans_opt",
- /* 10 */ "trans_opt ::=",
- /* 11 */ "trans_opt ::= TRANSACTION",
- /* 12 */ "trans_opt ::= TRANSACTION nm",
- /* 13 */ "transtype ::=",
- /* 14 */ "transtype ::= DEFERRED",
- /* 15 */ "transtype ::= IMMEDIATE",
- /* 16 */ "transtype ::= EXCLUSIVE",
- /* 17 */ "cmd ::= COMMIT trans_opt",
- /* 18 */ "cmd ::= END trans_opt",
- /* 19 */ "cmd ::= ROLLBACK trans_opt",
- /* 20 */ "savepoint_opt ::= SAVEPOINT",
- /* 21 */ "savepoint_opt ::=",
- /* 22 */ "cmd ::= SAVEPOINT nm",
- /* 23 */ "cmd ::= RELEASE savepoint_opt nm",
- /* 24 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm",
- /* 25 */ "cmd ::= create_table create_table_args",
- /* 26 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm",
- /* 27 */ "createkw ::= CREATE",
- /* 28 */ "ifnotexists ::=",
- /* 29 */ "ifnotexists ::= IF NOT EXISTS",
- /* 30 */ "temp ::= TEMP",
- /* 31 */ "temp ::=",
- /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP",
- /* 33 */ "create_table_args ::= AS select",
- /* 34 */ "columnlist ::= columnlist COMMA column",
- /* 35 */ "columnlist ::= column",
- /* 36 */ "column ::= columnid type carglist",
- /* 37 */ "columnid ::= nm",
- /* 38 */ "id ::= ID",
- /* 39 */ "id ::= INDEXED",
- /* 40 */ "ids ::= ID|STRING",
- /* 41 */ "nm ::= id",
- /* 42 */ "nm ::= STRING",
- /* 43 */ "nm ::= JOIN_KW",
- /* 44 */ "type ::=",
- /* 45 */ "type ::= typetoken",
- /* 46 */ "typetoken ::= typename",
- /* 47 */ "typetoken ::= typename LP signed RP",
- /* 48 */ "typetoken ::= typename LP signed COMMA signed RP",
- /* 49 */ "typename ::= ids",
- /* 50 */ "typename ::= typename ids",
- /* 51 */ "signed ::= plus_num",
- /* 52 */ "signed ::= minus_num",
- /* 53 */ "carglist ::= carglist ccons",
- /* 54 */ "carglist ::=",
- /* 55 */ "ccons ::= CONSTRAINT nm",
- /* 56 */ "ccons ::= DEFAULT term",
- /* 57 */ "ccons ::= DEFAULT LP expr RP",
- /* 58 */ "ccons ::= DEFAULT PLUS term",
- /* 59 */ "ccons ::= DEFAULT MINUS term",
- /* 60 */ "ccons ::= DEFAULT id",
- /* 61 */ "ccons ::= NULL onconf",
- /* 62 */ "ccons ::= NOT NULL onconf",
- /* 63 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 64 */ "ccons ::= UNIQUE onconf",
- /* 65 */ "ccons ::= CHECK LP expr RP",
- /* 66 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
- /* 67 */ "ccons ::= defer_subclause",
- /* 68 */ "ccons ::= COLLATE ids",
- /* 69 */ "autoinc ::=",
- /* 70 */ "autoinc ::= AUTOINCR",
- /* 71 */ "refargs ::=",
- /* 72 */ "refargs ::= refargs refarg",
- /* 73 */ "refarg ::= MATCH nm",
- /* 74 */ "refarg ::= ON INSERT refact",
- /* 75 */ "refarg ::= ON DELETE refact",
- /* 76 */ "refarg ::= ON UPDATE refact",
- /* 77 */ "refact ::= SET NULL",
- /* 78 */ "refact ::= SET DEFAULT",
- /* 79 */ "refact ::= CASCADE",
- /* 80 */ "refact ::= RESTRICT",
- /* 81 */ "refact ::= NO ACTION",
- /* 82 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 83 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 84 */ "init_deferred_pred_opt ::=",
- /* 85 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 86 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 87 */ "conslist_opt ::=",
- /* 88 */ "conslist_opt ::= COMMA conslist",
- /* 89 */ "conslist ::= conslist tconscomma tcons",
- /* 90 */ "conslist ::= tcons",
- /* 91 */ "tconscomma ::= COMMA",
- /* 92 */ "tconscomma ::=",
- /* 93 */ "tcons ::= CONSTRAINT nm",
- /* 94 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
- /* 95 */ "tcons ::= UNIQUE LP idxlist RP onconf",
- /* 96 */ "tcons ::= CHECK LP expr RP onconf",
- /* 97 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
- /* 98 */ "defer_subclause_opt ::=",
- /* 99 */ "defer_subclause_opt ::= defer_subclause",
- /* 100 */ "onconf ::=",
- /* 101 */ "onconf ::= ON CONFLICT resolvetype",
- /* 102 */ "orconf ::=",
- /* 103 */ "orconf ::= OR resolvetype",
- /* 104 */ "resolvetype ::= raisetype",
- /* 105 */ "resolvetype ::= IGNORE",
- /* 106 */ "resolvetype ::= REPLACE",
- /* 107 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 108 */ "ifexists ::= IF EXISTS",
- /* 109 */ "ifexists ::=",
- /* 110 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
- /* 111 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 112 */ "cmd ::= select",
- /* 113 */ "select ::= oneselect",
- /* 114 */ "select ::= select multiselect_op oneselect",
- /* 115 */ "multiselect_op ::= UNION",
- /* 116 */ "multiselect_op ::= UNION ALL",
- /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 119 */ "distinct ::= DISTINCT",
- /* 120 */ "distinct ::= ALL",
- /* 121 */ "distinct ::=",
- /* 122 */ "sclp ::= selcollist COMMA",
- /* 123 */ "sclp ::=",
- /* 124 */ "selcollist ::= sclp expr as",
- /* 125 */ "selcollist ::= sclp STAR",
- /* 126 */ "selcollist ::= sclp nm DOT STAR",
- /* 127 */ "as ::= AS nm",
- /* 128 */ "as ::= ids",
- /* 129 */ "as ::=",
- /* 130 */ "from ::=",
- /* 131 */ "from ::= FROM seltablist",
- /* 132 */ "stl_prefix ::= seltablist joinop",
- /* 133 */ "stl_prefix ::=",
- /* 134 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 135 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 136 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 137 */ "dbnm ::=",
- /* 138 */ "dbnm ::= DOT nm",
- /* 139 */ "fullname ::= nm dbnm",
- /* 140 */ "joinop ::= COMMA|JOIN",
- /* 141 */ "joinop ::= JOIN_KW JOIN",
- /* 142 */ "joinop ::= JOIN_KW nm JOIN",
- /* 143 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 144 */ "on_opt ::= ON expr",
- /* 145 */ "on_opt ::=",
- /* 146 */ "indexed_opt ::=",
- /* 147 */ "indexed_opt ::= INDEXED BY nm",
- /* 148 */ "indexed_opt ::= NOT INDEXED",
- /* 149 */ "using_opt ::= USING LP inscollist RP",
- /* 150 */ "using_opt ::=",
- /* 151 */ "orderby_opt ::=",
- /* 152 */ "orderby_opt ::= ORDER BY sortlist",
- /* 153 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 154 */ "sortlist ::= expr sortorder",
- /* 155 */ "sortorder ::= ASC",
- /* 156 */ "sortorder ::= DESC",
- /* 157 */ "sortorder ::=",
- /* 158 */ "groupby_opt ::=",
- /* 159 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 160 */ "having_opt ::=",
- /* 161 */ "having_opt ::= HAVING expr",
- /* 162 */ "limit_opt ::=",
- /* 163 */ "limit_opt ::= LIMIT expr",
- /* 164 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 165 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 166 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
- /* 167 */ "where_opt ::=",
- /* 168 */ "where_opt ::= WHERE expr",
- /* 169 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
- /* 170 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 171 */ "setlist ::= nm EQ expr",
- /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist",
- /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
- /* 175 */ "insert_cmd ::= INSERT orconf",
- /* 176 */ "insert_cmd ::= REPLACE",
- /* 177 */ "valuelist ::= VALUES LP nexprlist RP",
- /* 178 */ "valuelist ::= valuelist COMMA LP exprlist RP",
- /* 179 */ "inscollist_opt ::=",
- /* 180 */ "inscollist_opt ::= LP inscollist RP",
- /* 181 */ "inscollist ::= inscollist COMMA nm",
- /* 182 */ "inscollist ::= nm",
- /* 183 */ "expr ::= term",
- /* 184 */ "expr ::= LP expr RP",
- /* 185 */ "term ::= NULL",
- /* 186 */ "expr ::= id",
- /* 187 */ "expr ::= JOIN_KW",
- /* 188 */ "expr ::= nm DOT nm",
- /* 189 */ "expr ::= nm DOT nm DOT nm",
- /* 190 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 191 */ "term ::= STRING",
- /* 192 */ "expr ::= REGISTER",
- /* 193 */ "expr ::= VARIABLE",
- /* 194 */ "expr ::= expr COLLATE ids",
- /* 195 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 196 */ "expr ::= ID LP distinct exprlist RP",
- /* 197 */ "expr ::= ID LP STAR RP",
- /* 198 */ "term ::= CTIME_KW",
- /* 199 */ "expr ::= expr AND expr",
- /* 200 */ "expr ::= expr OR expr",
- /* 201 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 202 */ "expr ::= expr EQ|NE expr",
- /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 204 */ "expr ::= expr PLUS|MINUS expr",
- /* 205 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 206 */ "expr ::= expr CONCAT expr",
- /* 207 */ "likeop ::= LIKE_KW",
- /* 208 */ "likeop ::= NOT LIKE_KW",
- /* 209 */ "likeop ::= MATCH",
- /* 210 */ "likeop ::= NOT MATCH",
- /* 211 */ "expr ::= expr likeop expr",
- /* 212 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 213 */ "expr ::= expr ISNULL|NOTNULL",
- /* 214 */ "expr ::= expr NOT NULL",
- /* 215 */ "expr ::= expr IS expr",
- /* 216 */ "expr ::= expr IS NOT expr",
- /* 217 */ "expr ::= NOT expr",
- /* 218 */ "expr ::= BITNOT expr",
- /* 219 */ "expr ::= MINUS expr",
- /* 220 */ "expr ::= PLUS expr",
- /* 221 */ "between_op ::= BETWEEN",
- /* 222 */ "between_op ::= NOT BETWEEN",
- /* 223 */ "expr ::= expr between_op expr AND expr",
- /* 224 */ "in_op ::= IN",
- /* 225 */ "in_op ::= NOT IN",
- /* 226 */ "expr ::= expr in_op LP exprlist RP",
- /* 227 */ "expr ::= LP select RP",
- /* 228 */ "expr ::= expr in_op LP select RP",
- /* 229 */ "expr ::= expr in_op nm dbnm",
- /* 230 */ "expr ::= EXISTS LP select RP",
- /* 231 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 232 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 233 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 234 */ "case_else ::= ELSE expr",
- /* 235 */ "case_else ::=",
- /* 236 */ "case_operand ::= expr",
- /* 237 */ "case_operand ::=",
- /* 238 */ "exprlist ::= nexprlist",
- /* 239 */ "exprlist ::=",
- /* 240 */ "nexprlist ::= nexprlist COMMA expr",
- /* 241 */ "nexprlist ::= expr",
- /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
- /* 243 */ "uniqueflag ::= UNIQUE",
- /* 244 */ "uniqueflag ::=",
- /* 245 */ "idxlist_opt ::=",
- /* 246 */ "idxlist_opt ::= LP idxlist RP",
- /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder",
- /* 248 */ "idxlist ::= nm collate sortorder",
- /* 249 */ "collate ::=",
- /* 250 */ "collate ::= COLLATE ids",
- /* 251 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 252 */ "cmd ::= VACUUM",
- /* 253 */ "cmd ::= VACUUM nm",
- /* 254 */ "cmd ::= PRAGMA nm dbnm",
- /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 256 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 257 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 258 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 259 */ "nmnum ::= plus_num",
- /* 260 */ "nmnum ::= nm",
- /* 261 */ "nmnum ::= ON",
- /* 262 */ "nmnum ::= DELETE",
- /* 263 */ "nmnum ::= DEFAULT",
- /* 264 */ "plus_num ::= PLUS number",
- /* 265 */ "plus_num ::= number",
- /* 266 */ "minus_num ::= MINUS number",
- /* 267 */ "number ::= INTEGER|FLOAT",
- /* 268 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 269 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 270 */ "trigger_time ::= BEFORE",
- /* 271 */ "trigger_time ::= AFTER",
- /* 272 */ "trigger_time ::= INSTEAD OF",
- /* 273 */ "trigger_time ::=",
- /* 274 */ "trigger_event ::= DELETE|INSERT",
- /* 275 */ "trigger_event ::= UPDATE",
- /* 276 */ "trigger_event ::= UPDATE OF inscollist",
- /* 277 */ "foreach_clause ::=",
- /* 278 */ "foreach_clause ::= FOR EACH ROW",
- /* 279 */ "when_clause ::=",
- /* 280 */ "when_clause ::= WHEN expr",
- /* 281 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 283 */ "trnm ::= nm",
- /* 284 */ "trnm ::= nm DOT nm",
- /* 285 */ "tridxby ::=",
- /* 286 */ "tridxby ::= INDEXED BY nm",
- /* 287 */ "tridxby ::= NOT INDEXED",
- /* 288 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 289 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist",
- /* 290 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
- /* 291 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 292 */ "trigger_cmd ::= select",
- /* 293 */ "expr ::= RAISE LP IGNORE RP",
- /* 294 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 295 */ "raisetype ::= ROLLBACK",
- /* 296 */ "raisetype ::= ABORT",
- /* 297 */ "raisetype ::= FAIL",
- /* 298 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 299 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 300 */ "cmd ::= DETACH database_kw_opt expr",
- /* 301 */ "key_opt ::=",
- /* 302 */ "key_opt ::= KEY expr",
- /* 303 */ "database_kw_opt ::= DATABASE",
- /* 304 */ "database_kw_opt ::=",
- /* 305 */ "cmd ::= REINDEX",
- /* 306 */ "cmd ::= REINDEX nm dbnm",
- /* 307 */ "cmd ::= ANALYZE",
- /* 308 */ "cmd ::= ANALYZE nm dbnm",
- /* 309 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 310 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 311 */ "add_column_fullname ::= fullname",
- /* 312 */ "kwcolumn_opt ::=",
- /* 313 */ "kwcolumn_opt ::= COLUMNKW",
- /* 314 */ "cmd ::= create_vtab",
- /* 315 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 316 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 317 */ "vtabarglist ::= vtabarg",
- /* 318 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 319 */ "vtabarg ::=",
- /* 320 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 321 */ "vtabargtoken ::= ANY",
- /* 322 */ "vtabargtoken ::= lp anylist RP",
- /* 323 */ "lp ::= LP",
- /* 324 */ "anylist ::=",
- /* 325 */ "anylist ::= anylist LP anylist RP",
- /* 326 */ "anylist ::= anylist ANY",
-};
-#endif /* NDEBUG */
-
-
-#if YYSTACKDEPTH<=0
-/*
-** Try to increase the size of the parser stack.
-*/
-static void yyGrowStack(yyParser *p){
- int newSize;
- yyStackEntry *pNew;
-
- newSize = p->yystksz*2 + 100;
- pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
- if( pNew ){
- p->yystack = pNew;
- p->yystksz = newSize;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
- yyTracePrompt, p->yystksz);
- }
-#endif
- }
-}
-#endif
-
-/*
-** This function allocates a new parser.
-** The only argument is a pointer to a function which works like
-** malloc.
-**
-** Inputs:
-** A pointer to the function used to allocate memory.
-**
-** Outputs:
-** A pointer to a parser. This pointer is used in subsequent calls
-** to sqlite3Parser and sqlite3ParserFree.
-*/
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){
- yyParser *pParser;
- pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
- if( pParser ){
- pParser->yyidx = -1;
-#ifdef YYTRACKMAXSTACKDEPTH
- pParser->yyidxMax = 0;
-#endif
-#if YYSTACKDEPTH<=0
- pParser->yystack = NULL;
- pParser->yystksz = 0;
- yyGrowStack(pParser);
-#endif
- }
- return pParser;
-}
-
-/* The following function deletes the value associated with a
-** symbol. The symbol can be either a terminal or nonterminal.
-** "yymajor" is the symbol code, and "yypminor" is a pointer to
-** the value.
-*/
-static void yy_destructor(
- yyParser *yypParser, /* The parser */
- YYCODETYPE yymajor, /* Type code for object to destroy */
- YYMINORTYPE *yypminor /* The object to be destroyed */
-){
- sqlite3ParserARG_FETCH;
- switch( yymajor ){
- /* Here is inserted the actions which take place when a
- ** terminal or non-terminal is destroyed. This can happen
- ** when the symbol is popped from the stack during a
- ** reduce or during error processing or when a parser is
- ** being destroyed before it is finished parsing.
- **
- ** Note: during a reduce, the only symbols destroyed are those
- ** which appear on the RHS of the rule, but which are not used
- ** inside the C code.
- */
- case 160: /* select */
- case 194: /* oneselect */
-{
-sqlite3SelectDelete(pParse->db, (yypminor->yy159));
-}
- break;
- case 173: /* term */
- case 174: /* expr */
-{
-sqlite3ExprDelete(pParse->db, (yypminor->yy342).pExpr);
-}
- break;
- case 178: /* idxlist_opt */
- case 187: /* idxlist */
- case 197: /* selcollist */
- case 200: /* groupby_opt */
- case 202: /* orderby_opt */
- case 204: /* sclp */
- case 214: /* sortlist */
- case 215: /* nexprlist */
- case 216: /* setlist */
- case 220: /* exprlist */
- case 225: /* case_exprlist */
-{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy442));
-}
- break;
- case 193: /* fullname */
- case 198: /* from */
- case 206: /* seltablist */
- case 207: /* stl_prefix */
-{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy347));
-}
- break;
- case 199: /* where_opt */
- case 201: /* having_opt */
- case 210: /* on_opt */
- case 224: /* case_operand */
- case 226: /* case_else */
- case 236: /* when_clause */
- case 241: /* key_opt */
-{
-sqlite3ExprDelete(pParse->db, (yypminor->yy122));
-}
- break;
- case 211: /* using_opt */
- case 213: /* inscollist */
- case 218: /* inscollist_opt */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy180));
-}
- break;
- case 219: /* valuelist */
-{
-
- sqlite3ExprListDelete(pParse->db, (yypminor->yy487).pList);
- sqlite3SelectDelete(pParse->db, (yypminor->yy487).pSelect);
-
-}
- break;
- case 232: /* trigger_cmd_list */
- case 237: /* trigger_cmd */
-{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy327));
-}
- break;
- case 234: /* trigger_event */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy410).b);
-}
- break;
- default: break; /* If no destructor action specified: do nothing */
- }
-}
-
-/*
-** Pop the parser's stack once.
-**
-** If there is a destructor routine associated with the token which
-** is popped from the stack, then call it.
-**
-** Return the major token number for the symbol popped.
-*/
-static int yy_pop_parser_stack(yyParser *pParser){
- YYCODETYPE yymajor;
- yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
-
- /* There is no mechanism by which the parser stack can be popped below
- ** empty in SQLite. */
- if( NEVER(pParser->yyidx<0) ) return 0;
-#ifndef NDEBUG
- if( yyTraceFILE && pParser->yyidx>=0 ){
- fprintf(yyTraceFILE,"%sPopping %s\n",
- yyTracePrompt,
- yyTokenName[yytos->major]);
- }
-#endif
- yymajor = yytos->major;
- yy_destructor(pParser, yymajor, &yytos->minor);
- pParser->yyidx--;
- return yymajor;
-}
-
-/*
-** Deallocate and destroy a parser. Destructors are all called for
-** all stack elements before shutting the parser down.
-**
-** Inputs:
-** <ul>
-** <li> A pointer to the parser. This should be a pointer
-** obtained from sqlite3ParserAlloc.
-** <li> A pointer to a function used to reclaim memory obtained
-** from malloc.
-** </ul>
-*/
-SQLITE_PRIVATE void sqlite3ParserFree(
- void *p, /* The parser to be deleted */
- void (*freeProc)(void*) /* Function used to reclaim memory */
-){
- yyParser *pParser = (yyParser*)p;
- /* In SQLite, we never try to destroy a parser that was not successfully
- ** created in the first place. */
- if( NEVER(pParser==0) ) return;
- while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
-#if YYSTACKDEPTH<=0
- free(pParser->yystack);
-#endif
- (*freeProc)((void*)pParser);
-}
-
-/*
-** Return the peak depth of the stack for a parser.
-*/
-#ifdef YYTRACKMAXSTACKDEPTH
-SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){
- yyParser *pParser = (yyParser*)p;
- return pParser->yyidxMax;
-}
-#endif
-
-/*
-** Find the appropriate action for a parser given the terminal
-** look-ahead token iLookAhead.
-**
-** If the look-ahead token is YYNOCODE, then check to see if the action is
-** independent of the look-ahead. If it is, return the action, otherwise
-** return YY_NO_ACTION.
-*/
-static int yy_find_shift_action(
- yyParser *pParser, /* The parser */
- YYCODETYPE iLookAhead /* The look-ahead token */
-){
- int i;
- int stateno = pParser->yystack[pParser->yyidx].stateno;
-
- if( stateno>YY_SHIFT_COUNT
- || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
- return yy_default[stateno];
- }
- assert( iLookAhead!=YYNOCODE );
- i += iLookAhead;
- if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
- if( iLookAhead>0 ){
-#ifdef YYFALLBACK
- YYCODETYPE iFallback; /* Fallback token */
- if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
- && (iFallback = yyFallback[iLookAhead])!=0 ){
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
- }
-#endif
- return yy_find_shift_action(pParser, iFallback);
- }
-#endif
-#ifdef YYWILDCARD
- {
- int j = i - iLookAhead + YYWILDCARD;
- if(
-#if YY_SHIFT_MIN+YYWILDCARD<0
- j>=0 &&
-#endif
-#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
- j<YY_ACTTAB_COUNT &&
-#endif
- yy_lookahead[j]==YYWILDCARD
- ){
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
- }
-#endif /* NDEBUG */
- return yy_action[j];
- }
- }
-#endif /* YYWILDCARD */
- }
- return yy_default[stateno];
- }else{
- return yy_action[i];
- }
-}
-
-/*
-** Find the appropriate action for a parser given the non-terminal
-** look-ahead token iLookAhead.
-**
-** If the look-ahead token is YYNOCODE, then check to see if the action is
-** independent of the look-ahead. If it is, return the action, otherwise
-** return YY_NO_ACTION.
-*/
-static int yy_find_reduce_action(
- int stateno, /* Current state number */
- YYCODETYPE iLookAhead /* The look-ahead token */
-){
- int i;
-#ifdef YYERRORSYMBOL
- if( stateno>YY_REDUCE_COUNT ){
- return yy_default[stateno];
- }
-#else
- assert( stateno<=YY_REDUCE_COUNT );
-#endif
- i = yy_reduce_ofst[stateno];
- assert( i!=YY_REDUCE_USE_DFLT );
- assert( iLookAhead!=YYNOCODE );
- i += iLookAhead;
-#ifdef YYERRORSYMBOL
- if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
- return yy_default[stateno];
- }
-#else
- assert( i>=0 && i<YY_ACTTAB_COUNT );
- assert( yy_lookahead[i]==iLookAhead );
-#endif
- return yy_action[i];
-}
-
-/*
-** The following routine is called if the stack overflows.
-*/
-static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
- sqlite3ParserARG_FETCH;
- yypParser->yyidx--;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
- }
-#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
- /* Here code is inserted which will execute if the parser
- ** stack every overflows */
-
- UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
- sqlite3ErrorMsg(pParse, "parser stack overflow");
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
-}
-
-/*
-** Perform a shift action.
-*/
-static void yy_shift(
- yyParser *yypParser, /* The parser to be shifted */
- int yyNewState, /* The new state to shift in */
- int yyMajor, /* The major token to shift in */
- YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */
-){
- yyStackEntry *yytos;
- yypParser->yyidx++;
-#ifdef YYTRACKMAXSTACKDEPTH
- if( yypParser->yyidx>yypParser->yyidxMax ){
- yypParser->yyidxMax = yypParser->yyidx;
- }
-#endif
-#if YYSTACKDEPTH>0
- if( yypParser->yyidx>=YYSTACKDEPTH ){
- yyStackOverflow(yypParser, yypMinor);
- return;
- }
-#else
- if( yypParser->yyidx>=yypParser->yystksz ){
- yyGrowStack(yypParser);
- if( yypParser->yyidx>=yypParser->yystksz ){
- yyStackOverflow(yypParser, yypMinor);
- return;
- }
- }
-#endif
- yytos = &yypParser->yystack[yypParser->yyidx];
- yytos->stateno = (YYACTIONTYPE)yyNewState;
- yytos->major = (YYCODETYPE)yyMajor;
- yytos->minor = *yypMinor;
-#ifndef NDEBUG
- if( yyTraceFILE && yypParser->yyidx>0 ){
- int i;
- fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
- fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
- for(i=1; i<=yypParser->yyidx; i++)
- fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
- fprintf(yyTraceFILE,"\n");
- }
-#endif
-}
-
-/* The following table contains information about every rule that
-** is used during the reduce.
-*/
-static const struct {
- YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
- unsigned char nrhs; /* Number of right-hand side symbols in the rule */
-} yyRuleInfo[] = {
- { 142, 1 },
- { 143, 2 },
- { 143, 1 },
- { 144, 1 },
- { 144, 3 },
- { 145, 0 },
- { 145, 1 },
- { 145, 3 },
- { 146, 1 },
- { 147, 3 },
- { 149, 0 },
- { 149, 1 },
- { 149, 2 },
- { 148, 0 },
- { 148, 1 },
- { 148, 1 },
- { 148, 1 },
- { 147, 2 },
- { 147, 2 },
- { 147, 2 },
- { 151, 1 },
- { 151, 0 },
- { 147, 2 },
- { 147, 3 },
- { 147, 5 },
- { 147, 2 },
- { 152, 6 },
- { 154, 1 },
- { 156, 0 },
- { 156, 3 },
- { 155, 1 },
- { 155, 0 },
- { 153, 4 },
- { 153, 2 },
- { 158, 3 },
- { 158, 1 },
- { 161, 3 },
- { 162, 1 },
- { 165, 1 },
- { 165, 1 },
- { 166, 1 },
- { 150, 1 },
- { 150, 1 },
- { 150, 1 },
- { 163, 0 },
- { 163, 1 },
- { 167, 1 },
- { 167, 4 },
- { 167, 6 },
- { 168, 1 },
- { 168, 2 },
- { 169, 1 },
- { 169, 1 },
- { 164, 2 },
- { 164, 0 },
- { 172, 2 },
- { 172, 2 },
- { 172, 4 },
- { 172, 3 },
- { 172, 3 },
- { 172, 2 },
- { 172, 2 },
- { 172, 3 },
- { 172, 5 },
- { 172, 2 },
- { 172, 4 },
- { 172, 4 },
- { 172, 1 },
- { 172, 2 },
- { 177, 0 },
- { 177, 1 },
- { 179, 0 },
- { 179, 2 },
- { 181, 2 },
- { 181, 3 },
- { 181, 3 },
- { 181, 3 },
- { 182, 2 },
- { 182, 2 },
- { 182, 1 },
- { 182, 1 },
- { 182, 2 },
- { 180, 3 },
- { 180, 2 },
- { 183, 0 },
- { 183, 2 },
- { 183, 2 },
- { 159, 0 },
- { 159, 2 },
- { 184, 3 },
- { 184, 1 },
- { 185, 1 },
- { 185, 0 },
- { 186, 2 },
- { 186, 7 },
- { 186, 5 },
- { 186, 5 },
- { 186, 10 },
- { 188, 0 },
- { 188, 1 },
- { 175, 0 },
- { 175, 3 },
- { 189, 0 },
- { 189, 2 },
- { 190, 1 },
- { 190, 1 },
- { 190, 1 },
- { 147, 4 },
- { 192, 2 },
- { 192, 0 },
- { 147, 8 },
- { 147, 4 },
- { 147, 1 },
- { 160, 1 },
- { 160, 3 },
- { 195, 1 },
- { 195, 2 },
- { 195, 1 },
- { 194, 9 },
- { 196, 1 },
- { 196, 1 },
- { 196, 0 },
- { 204, 2 },
- { 204, 0 },
- { 197, 3 },
- { 197, 2 },
- { 197, 4 },
- { 205, 2 },
- { 205, 1 },
- { 205, 0 },
- { 198, 0 },
- { 198, 2 },
- { 207, 2 },
- { 207, 0 },
- { 206, 7 },
- { 206, 7 },
- { 206, 7 },
- { 157, 0 },
- { 157, 2 },
- { 193, 2 },
- { 208, 1 },
- { 208, 2 },
- { 208, 3 },
- { 208, 4 },
- { 210, 2 },
- { 210, 0 },
- { 209, 0 },
- { 209, 3 },
- { 209, 2 },
- { 211, 4 },
- { 211, 0 },
- { 202, 0 },
- { 202, 3 },
- { 214, 4 },
- { 214, 2 },
- { 176, 1 },
- { 176, 1 },
- { 176, 0 },
- { 200, 0 },
- { 200, 3 },
- { 201, 0 },
- { 201, 2 },
- { 203, 0 },
- { 203, 2 },
- { 203, 4 },
- { 203, 4 },
- { 147, 5 },
- { 199, 0 },
- { 199, 2 },
- { 147, 7 },
- { 216, 5 },
- { 216, 3 },
- { 147, 5 },
- { 147, 5 },
- { 147, 6 },
- { 217, 2 },
- { 217, 1 },
- { 219, 4 },
- { 219, 5 },
- { 218, 0 },
- { 218, 3 },
- { 213, 3 },
- { 213, 1 },
- { 174, 1 },
- { 174, 3 },
- { 173, 1 },
- { 174, 1 },
- { 174, 1 },
- { 174, 3 },
- { 174, 5 },
- { 173, 1 },
- { 173, 1 },
- { 174, 1 },
- { 174, 1 },
- { 174, 3 },
- { 174, 6 },
- { 174, 5 },
- { 174, 4 },
- { 173, 1 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 221, 1 },
- { 221, 2 },
- { 221, 1 },
- { 221, 2 },
- { 174, 3 },
- { 174, 5 },
- { 174, 2 },
- { 174, 3 },
- { 174, 3 },
- { 174, 4 },
- { 174, 2 },
- { 174, 2 },
- { 174, 2 },
- { 174, 2 },
- { 222, 1 },
- { 222, 2 },
- { 174, 5 },
- { 223, 1 },
- { 223, 2 },
- { 174, 5 },
- { 174, 3 },
- { 174, 5 },
- { 174, 4 },
- { 174, 4 },
- { 174, 5 },
- { 225, 5 },
- { 225, 4 },
- { 226, 2 },
- { 226, 0 },
- { 224, 1 },
- { 224, 0 },
- { 220, 1 },
- { 220, 0 },
- { 215, 3 },
- { 215, 1 },
- { 147, 11 },
- { 227, 1 },
- { 227, 0 },
- { 178, 0 },
- { 178, 3 },
- { 187, 5 },
- { 187, 3 },
- { 228, 0 },
- { 228, 2 },
- { 147, 4 },
- { 147, 1 },
- { 147, 2 },
- { 147, 3 },
- { 147, 5 },
- { 147, 6 },
- { 147, 5 },
- { 147, 6 },
- { 229, 1 },
- { 229, 1 },
- { 229, 1 },
- { 229, 1 },
- { 229, 1 },
- { 170, 2 },
- { 170, 1 },
- { 171, 2 },
- { 230, 1 },
- { 147, 5 },
- { 231, 11 },
- { 233, 1 },
- { 233, 1 },
- { 233, 2 },
- { 233, 0 },
- { 234, 1 },
- { 234, 1 },
- { 234, 3 },
- { 235, 0 },
- { 235, 3 },
- { 236, 0 },
- { 236, 2 },
- { 232, 3 },
- { 232, 2 },
- { 238, 1 },
- { 238, 3 },
- { 239, 0 },
- { 239, 3 },
- { 239, 2 },
- { 237, 7 },
- { 237, 5 },
- { 237, 5 },
- { 237, 5 },
- { 237, 1 },
- { 174, 4 },
- { 174, 6 },
- { 191, 1 },
- { 191, 1 },
- { 191, 1 },
- { 147, 4 },
- { 147, 6 },
- { 147, 3 },
- { 241, 0 },
- { 241, 2 },
- { 240, 1 },
- { 240, 0 },
- { 147, 1 },
- { 147, 3 },
- { 147, 1 },
- { 147, 3 },
- { 147, 6 },
- { 147, 6 },
- { 242, 1 },
- { 243, 0 },
- { 243, 1 },
- { 147, 1 },
- { 147, 4 },
- { 244, 8 },
- { 245, 1 },
- { 245, 3 },
- { 246, 0 },
- { 246, 2 },
- { 247, 1 },
- { 247, 3 },
- { 248, 1 },
- { 249, 0 },
- { 249, 4 },
- { 249, 2 },
-};
-
-static void yy_accept(yyParser*); /* Forward Declaration */
-
-/*
-** Perform a reduce action and the shift that must immediately
-** follow the reduce.
-*/
-static void yy_reduce(
- yyParser *yypParser, /* The parser */
- int yyruleno /* Number of the rule by which to reduce */
-){
- int yygoto; /* The next state */
- int yyact; /* The next action */
- YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
- yyStackEntry *yymsp; /* The top of the parser's stack */
- int yysize; /* Amount to pop the stack */
- sqlite3ParserARG_FETCH;
- yymsp = &yypParser->yystack[yypParser->yyidx];
-#ifndef NDEBUG
- if( yyTraceFILE && yyruleno>=0
- && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
- fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
- yyRuleName[yyruleno]);
- }
-#endif /* NDEBUG */
-
- /* Silence complaints from purify about yygotominor being uninitialized
- ** in some cases when it is copied into the stack after the following
- ** switch. yygotominor is uninitialized when a rule reduces that does
- ** not set the value of its left-hand side nonterminal. Leaving the
- ** value of the nonterminal uninitialized is utterly harmless as long
- ** as the value is never used. So really the only thing this code
- ** accomplishes is to quieten purify.
- **
- ** 2007-01-16: The wireshark project (www.wireshark.org) reports that
- ** without this code, their parser segfaults. I'm not sure what there
- ** parser is doing to make this happen. This is the second bug report
- ** from wireshark this week. Clearly they are stressing Lemon in ways
- ** that it has not been previously stressed... (SQLite ticket #2172)
- */
- /*memset(&yygotominor, 0, sizeof(yygotominor));*/
- yygotominor = yyzerominor;
-
-
- switch( yyruleno ){
- /* Beginning here are the reduction cases. A typical example
- ** follows:
- ** case 0:
- ** #line <lineno> <grammarfile>
- ** { ... } // User supplied code
- ** #line <lineno> <thisfile>
- ** break;
- */
- case 5: /* explain ::= */
-{ sqlite3BeginParse(pParse, 0); }
- break;
- case 6: /* explain ::= EXPLAIN */
-{ sqlite3BeginParse(pParse, 1); }
- break;
- case 7: /* explain ::= EXPLAIN QUERY PLAN */
-{ sqlite3BeginParse(pParse, 2); }
- break;
- case 8: /* cmdx ::= cmd */
-{ sqlite3FinishCoding(pParse); }
- break;
- case 9: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy392);}
- break;
- case 13: /* transtype ::= */
-{yygotominor.yy392 = TK_DEFERRED;}
- break;
- case 14: /* transtype ::= DEFERRED */
- case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
- case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
- case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115);
- case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117);
-{yygotominor.yy392 = yymsp[0].major;}
- break;
- case 17: /* cmd ::= COMMIT trans_opt */
- case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
-{sqlite3CommitTransaction(pParse);}
- break;
- case 19: /* cmd ::= ROLLBACK trans_opt */
-{sqlite3RollbackTransaction(pParse);}
- break;
- case 22: /* cmd ::= SAVEPOINT nm */
-{
- sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0);
-}
- break;
- case 23: /* cmd ::= RELEASE savepoint_opt nm */
-{
- sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0);
-}
- break;
- case 24: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
-{
- sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
-}
- break;
- case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
-{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy392,0,0,yymsp[-2].minor.yy392);
-}
- break;
- case 27: /* createkw ::= CREATE */
-{
- pParse->db->lookaside.bEnabled = 0;
- yygotominor.yy0 = yymsp[0].minor.yy0;
-}
- break;
- case 28: /* ifnotexists ::= */
- case 31: /* temp ::= */ yytestcase(yyruleno==31);
- case 69: /* autoinc ::= */ yytestcase(yyruleno==69);
- case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
- case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
- case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
- case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
- case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
- case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120);
- case 121: /* distinct ::= */ yytestcase(yyruleno==121);
- case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
- case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
-{yygotominor.yy392 = 0;}
- break;
- case 29: /* ifnotexists ::= IF NOT EXISTS */
- case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
- case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
- case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
- case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
- case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119);
- case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
- case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
-{yygotominor.yy392 = 1;}
- break;
- case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
-{
- sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
-}
- break;
- case 33: /* create_table_args ::= AS select */
-{
- sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy159);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
-}
- break;
- case 36: /* column ::= columnid type carglist */
-{
- yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
- yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
-}
- break;
- case 37: /* columnid ::= nm */
-{
- sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
- yygotominor.yy0 = yymsp[0].minor.yy0;
- pParse->constraintName.n = 0;
-}
- break;
- case 38: /* id ::= ID */
- case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
- case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
- case 41: /* nm ::= id */ yytestcase(yyruleno==41);
- case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
- case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
- case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
- case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
- case 127: /* as ::= AS nm */ yytestcase(yyruleno==127);
- case 128: /* as ::= ids */ yytestcase(yyruleno==128);
- case 138: /* dbnm ::= DOT nm */ yytestcase(yyruleno==138);
- case 147: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==147);
- case 250: /* collate ::= COLLATE ids */ yytestcase(yyruleno==250);
- case 259: /* nmnum ::= plus_num */ yytestcase(yyruleno==259);
- case 260: /* nmnum ::= nm */ yytestcase(yyruleno==260);
- case 261: /* nmnum ::= ON */ yytestcase(yyruleno==261);
- case 262: /* nmnum ::= DELETE */ yytestcase(yyruleno==262);
- case 263: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==263);
- case 264: /* plus_num ::= PLUS number */ yytestcase(yyruleno==264);
- case 265: /* plus_num ::= number */ yytestcase(yyruleno==265);
- case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266);
- case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267);
- case 283: /* trnm ::= nm */ yytestcase(yyruleno==283);
-{yygotominor.yy0 = yymsp[0].minor.yy0;}
- break;
- case 45: /* type ::= typetoken */
-{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
- break;
- case 47: /* typetoken ::= typename LP signed RP */
-{
- yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
- yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
-}
- break;
- case 48: /* typetoken ::= typename LP signed COMMA signed RP */
-{
- yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
- yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
-}
- break;
- case 50: /* typename ::= typename ids */
-{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
- break;
- case 55: /* ccons ::= CONSTRAINT nm */
- case 93: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==93);
-{pParse->constraintName = yymsp[0].minor.yy0;}
- break;
- case 56: /* ccons ::= DEFAULT term */
- case 58: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==58);
-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy342);}
- break;
- case 57: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy342);}
- break;
- case 59: /* ccons ::= DEFAULT MINUS term */
-{
- ExprSpan v;
- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy342.pExpr, 0, 0);
- v.zStart = yymsp[-1].minor.yy0.z;
- v.zEnd = yymsp[0].minor.yy342.zEnd;
- sqlite3AddDefaultValue(pParse,&v);
-}
- break;
- case 60: /* ccons ::= DEFAULT id */
-{
- ExprSpan v;
- spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
- sqlite3AddDefaultValue(pParse,&v);
-}
- break;
- case 62: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy392);}
- break;
- case 63: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy392,yymsp[0].minor.yy392,yymsp[-2].minor.yy392);}
- break;
- case 64: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy392,0,0,0,0);}
- break;
- case 65: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy342.pExpr);}
- break;
- case 66: /* ccons ::= REFERENCES nm idxlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy442,yymsp[0].minor.yy392);}
- break;
- case 67: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy392);}
- break;
- case 68: /* ccons ::= COLLATE ids */
-{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
- break;
- case 71: /* refargs ::= */
-{ yygotominor.yy392 = OE_None*0x0101; /* EV: R-19803-45884 */}
- break;
- case 72: /* refargs ::= refargs refarg */
-{ yygotominor.yy392 = (yymsp[-1].minor.yy392 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
- break;
- case 73: /* refarg ::= MATCH nm */
- case 74: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==74);
-{ yygotominor.yy207.value = 0; yygotominor.yy207.mask = 0x000000; }
- break;
- case 75: /* refarg ::= ON DELETE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392; yygotominor.yy207.mask = 0x0000ff; }
- break;
- case 76: /* refarg ::= ON UPDATE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392<<8; yygotominor.yy207.mask = 0x00ff00; }
- break;
- case 77: /* refact ::= SET NULL */
-{ yygotominor.yy392 = OE_SetNull; /* EV: R-33326-45252 */}
- break;
- case 78: /* refact ::= SET DEFAULT */
-{ yygotominor.yy392 = OE_SetDflt; /* EV: R-33326-45252 */}
- break;
- case 79: /* refact ::= CASCADE */
-{ yygotominor.yy392 = OE_Cascade; /* EV: R-33326-45252 */}
- break;
- case 80: /* refact ::= RESTRICT */
-{ yygotominor.yy392 = OE_Restrict; /* EV: R-33326-45252 */}
- break;
- case 81: /* refact ::= NO ACTION */
-{ yygotominor.yy392 = OE_None; /* EV: R-33326-45252 */}
- break;
- case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 99: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==99);
- case 101: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==101);
- case 104: /* resolvetype ::= raisetype */ yytestcase(yyruleno==104);
-{yygotominor.yy392 = yymsp[0].minor.yy392;}
- break;
- case 87: /* conslist_opt ::= */
-{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
- break;
- case 88: /* conslist_opt ::= COMMA conslist */
-{yygotominor.yy0 = yymsp[-1].minor.yy0;}
- break;
- case 91: /* tconscomma ::= COMMA */
-{pParse->constraintName.n = 0;}
- break;
- case 94: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy442,yymsp[0].minor.yy392,yymsp[-2].minor.yy392,0);}
- break;
- case 95: /* tcons ::= UNIQUE LP idxlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy442,yymsp[0].minor.yy392,0,0,0,0);}
- break;
- case 96: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy342.pExpr);}
- break;
- case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
-{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy442, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[-1].minor.yy392);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy392);
-}
- break;
- case 100: /* onconf ::= */
-{yygotominor.yy392 = OE_Default;}
- break;
- case 102: /* orconf ::= */
-{yygotominor.yy258 = OE_Default;}
- break;
- case 103: /* orconf ::= OR resolvetype */
-{yygotominor.yy258 = (u8)yymsp[0].minor.yy392;}
- break;
- case 105: /* resolvetype ::= IGNORE */
-{yygotominor.yy392 = OE_Ignore;}
- break;
- case 106: /* resolvetype ::= REPLACE */
-{yygotominor.yy392 = OE_Replace;}
- break;
- case 107: /* cmd ::= DROP TABLE ifexists fullname */
-{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392);
-}
- break;
- case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
-{
- sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy159, yymsp[-6].minor.yy392, yymsp[-4].minor.yy392);
-}
- break;
- case 111: /* cmd ::= DROP VIEW ifexists fullname */
-{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392);
-}
- break;
- case 112: /* cmd ::= select */
-{
- SelectDest dest = {SRT_Output, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy159, &dest);
- sqlite3ExplainBegin(pParse->pVdbe);
- sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy159);
- sqlite3ExplainFinish(pParse->pVdbe);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
-}
- break;
- case 113: /* select ::= oneselect */
-{yygotominor.yy159 = yymsp[0].minor.yy159;}
- break;
- case 114: /* select ::= select multiselect_op oneselect */
-{
- if( yymsp[0].minor.yy159 ){
- yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
- yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
- }
- yygotominor.yy159 = yymsp[0].minor.yy159;
-}
- break;
- case 116: /* multiselect_op ::= UNION ALL */
-{yygotominor.yy392 = TK_ALL;}
- break;
- case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
-{
- yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
-}
- break;
- case 122: /* sclp ::= selcollist COMMA */
- case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
-{yygotominor.yy442 = yymsp[-1].minor.yy442;}
- break;
- case 123: /* sclp ::= */
- case 151: /* orderby_opt ::= */ yytestcase(yyruleno==151);
- case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158);
- case 239: /* exprlist ::= */ yytestcase(yyruleno==239);
- case 245: /* idxlist_opt ::= */ yytestcase(yyruleno==245);
-{yygotominor.yy442 = 0;}
- break;
- case 124: /* selcollist ::= sclp expr as */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy442, yymsp[-1].minor.yy342.pExpr);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yygotominor.yy442,&yymsp[-1].minor.yy342);
-}
- break;
- case 125: /* selcollist ::= sclp STAR */
-{
- Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p);
-}
- break;
- case 126: /* selcollist ::= sclp nm DOT STAR */
-{
- Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
- Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
- Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, pDot);
-}
- break;
- case 129: /* as ::= */
-{yygotominor.yy0.n = 0;}
- break;
- case 130: /* from ::= */
-{yygotominor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy347));}
- break;
- case 131: /* from ::= FROM seltablist */
-{
- yygotominor.yy347 = yymsp[0].minor.yy347;
- sqlite3SrcListShiftJoinType(yygotominor.yy347);
-}
- break;
- case 132: /* stl_prefix ::= seltablist joinop */
-{
- yygotominor.yy347 = yymsp[-1].minor.yy347;
- if( ALWAYS(yygotominor.yy347 && yygotominor.yy347->nSrc>0) ) yygotominor.yy347->a[yygotominor.yy347->nSrc-1].jointype = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 133: /* stl_prefix ::= */
-{yygotominor.yy347 = 0;}
- break;
- case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
-{
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- sqlite3SrcListIndexedBy(pParse, yygotominor.yy347, &yymsp[-2].minor.yy0);
-}
- break;
- case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
-{
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy159,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- }
- break;
- case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
-{
- if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
- yygotominor.yy347 = yymsp[-4].minor.yy347;
- }else{
- Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0);
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- }
- }
- break;
- case 137: /* dbnm ::= */
- case 146: /* indexed_opt ::= */ yytestcase(yyruleno==146);
-{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
- break;
- case 139: /* fullname ::= nm dbnm */
-{yygotominor.yy347 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
- break;
- case 140: /* joinop ::= COMMA|JOIN */
-{ yygotominor.yy392 = JT_INNER; }
- break;
- case 141: /* joinop ::= JOIN_KW JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
- break;
- case 142: /* joinop ::= JOIN_KW nm JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
- break;
- case 143: /* joinop ::= JOIN_KW nm nm JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
- break;
- case 144: /* on_opt ::= ON expr */
- case 161: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==161);
- case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168);
- case 234: /* case_else ::= ELSE expr */ yytestcase(yyruleno==234);
- case 236: /* case_operand ::= expr */ yytestcase(yyruleno==236);
-{yygotominor.yy122 = yymsp[0].minor.yy342.pExpr;}
- break;
- case 145: /* on_opt ::= */
- case 160: /* having_opt ::= */ yytestcase(yyruleno==160);
- case 167: /* where_opt ::= */ yytestcase(yyruleno==167);
- case 235: /* case_else ::= */ yytestcase(yyruleno==235);
- case 237: /* case_operand ::= */ yytestcase(yyruleno==237);
-{yygotominor.yy122 = 0;}
- break;
- case 148: /* indexed_opt ::= NOT INDEXED */
-{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
- break;
- case 149: /* using_opt ::= USING LP inscollist RP */
- case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180);
-{yygotominor.yy180 = yymsp[-1].minor.yy180;}
- break;
- case 150: /* using_opt ::= */
- case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
-{yygotominor.yy180 = 0;}
- break;
- case 152: /* orderby_opt ::= ORDER BY sortlist */
- case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159);
- case 238: /* exprlist ::= nexprlist */ yytestcase(yyruleno==238);
-{yygotominor.yy442 = yymsp[0].minor.yy442;}
- break;
- case 153: /* sortlist ::= sortlist COMMA expr sortorder */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442,yymsp[-1].minor.yy342.pExpr);
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 154: /* sortlist ::= expr sortorder */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy342.pExpr);
- if( yygotominor.yy442 && ALWAYS(yygotominor.yy442->a) ) yygotominor.yy442->a[0].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 155: /* sortorder ::= ASC */
- case 157: /* sortorder ::= */ yytestcase(yyruleno==157);
-{yygotominor.yy392 = SQLITE_SO_ASC;}
- break;
- case 156: /* sortorder ::= DESC */
-{yygotominor.yy392 = SQLITE_SO_DESC;}
- break;
- case 162: /* limit_opt ::= */
-{yygotominor.yy64.pLimit = 0; yygotominor.yy64.pOffset = 0;}
- break;
- case 163: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr; yygotominor.yy64.pOffset = 0;}
- break;
- case 164: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy64.pLimit = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pOffset = yymsp[0].minor.yy342.pExpr;}
- break;
- case 165: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy64.pOffset = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr;}
- break;
- case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
-{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy347, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy347,yymsp[0].minor.yy122);
-}
- break;
- case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
-{
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy347, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy442,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy347,yymsp[-1].minor.yy442,yymsp[0].minor.yy122,yymsp[-5].minor.yy258);
-}
- break;
- case 170: /* setlist ::= setlist COMMA nm EQ expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy442, yymsp[0].minor.yy342.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
-}
- break;
- case 171: /* setlist ::= nm EQ expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy342.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
-}
- break;
- case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy347, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
- break;
- case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy347, 0, yymsp[0].minor.yy159, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
- break;
- case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
-{sqlite3Insert(pParse, yymsp[-3].minor.yy347, 0, 0, yymsp[-2].minor.yy180, yymsp[-5].minor.yy258);}
- break;
- case 175: /* insert_cmd ::= INSERT orconf */
-{yygotominor.yy258 = yymsp[0].minor.yy258;}
- break;
- case 176: /* insert_cmd ::= REPLACE */
-{yygotominor.yy258 = OE_Replace;}
- break;
- case 177: /* valuelist ::= VALUES LP nexprlist RP */
-{
- yygotominor.yy487.pList = yymsp[-1].minor.yy442;
- yygotominor.yy487.pSelect = 0;
-}
- break;
- case 178: /* valuelist ::= valuelist COMMA LP exprlist RP */
-{
- Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy442, 0, 0, 0, 0, 0, 0, 0, 0);
- if( yymsp[-4].minor.yy487.pList ){
- yymsp[-4].minor.yy487.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy487.pList, 0, 0, 0, 0, 0, 0, 0, 0);
- yymsp[-4].minor.yy487.pList = 0;
- }
- yygotominor.yy487.pList = 0;
- if( yymsp[-4].minor.yy487.pSelect==0 || pRight==0 ){
- sqlite3SelectDelete(pParse->db, pRight);
- sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy487.pSelect);
- yygotominor.yy487.pSelect = 0;
- }else{
- pRight->op = TK_ALL;
- pRight->pPrior = yymsp[-4].minor.yy487.pSelect;
- pRight->selFlags |= SF_Values;
- pRight->pPrior->selFlags |= SF_Values;
- yygotominor.yy487.pSelect = pRight;
- }
-}
- break;
- case 181: /* inscollist ::= inscollist COMMA nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);}
- break;
- case 182: /* inscollist ::= nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
- break;
- case 183: /* expr ::= term */
-{yygotominor.yy342 = yymsp[0].minor.yy342;}
- break;
- case 184: /* expr ::= LP expr RP */
-{yygotominor.yy342.pExpr = yymsp[-1].minor.yy342.pExpr; spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
- break;
- case 185: /* term ::= NULL */
- case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
- case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
-{spanExpr(&yygotominor.yy342, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
- break;
- case 186: /* expr ::= id */
- case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
-{spanExpr(&yygotominor.yy342, pParse, TK_ID, &yymsp[0].minor.yy0);}
- break;
- case 188: /* expr ::= nm DOT nm */
-{
- Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
- Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
- spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 189: /* expr ::= nm DOT nm DOT nm */
-{
- Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
- Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
- Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
- spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 192: /* expr ::= REGISTER */
-{
- /* When doing a nested parse, one can include terms in an expression
- ** that look like this: #1 #2 ... These terms refer to registers
- ** in the virtual machine. #N is the N-th register. */
- if( pParse->nested==0 ){
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
- yygotominor.yy342.pExpr = 0;
- }else{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
- if( yygotominor.yy342.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy342.pExpr->iTable);
- }
- spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 193: /* expr ::= VARIABLE */
-{
- spanExpr(&yygotominor.yy342, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yygotominor.yy342.pExpr);
- spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 194: /* expr ::= expr COLLATE ids */
-{
- yygotominor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
- yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 195: /* expr ::= CAST LP expr AS typetoken RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy342.pExpr, 0, &yymsp[-1].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 196: /* expr ::= ID LP distinct exprlist RP */
-{
- if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
- sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
- }
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy392 && yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->flags |= EP_Distinct;
- }
-}
- break;
- case 197: /* expr ::= ID LP STAR RP */
-{
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 198: /* term ::= CTIME_KW */
-{
- /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
- ** treated as functions that return constants */
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->op = TK_CONST_FUNC;
- }
- spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
-}
- break;
- case 199: /* expr ::= expr AND expr */
- case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200);
- case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201);
- case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202);
- case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203);
- case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204);
- case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205);
- case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206);
-{spanBinaryExpr(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);}
- break;
- case 207: /* likeop ::= LIKE_KW */
- case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209);
-{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 0;}
- break;
- case 208: /* likeop ::= NOT LIKE_KW */
- case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210);
-{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 1;}
- break;
- case 211: /* expr ::= expr likeop expr */
-{
- ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy342.pExpr);
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy318.eOperator);
- if( yymsp[-1].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
- if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
-}
- break;
- case 212: /* expr ::= expr likeop expr ESCAPE expr */
-{
- ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy318.eOperator);
- if( yymsp[-3].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
- if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
-}
- break;
- case 213: /* expr ::= expr ISNULL|NOTNULL */
-{spanUnaryPostfix(&yygotominor.yy342,pParse,yymsp[0].major,&yymsp[-1].minor.yy342,&yymsp[0].minor.yy0);}
- break;
- case 214: /* expr ::= expr NOT NULL */
-{spanUnaryPostfix(&yygotominor.yy342,pParse,TK_NOTNULL,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy0);}
- break;
- case 215: /* expr ::= expr IS expr */
-{
- spanBinaryExpr(&yygotominor.yy342,pParse,TK_IS,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_ISNULL);
-}
- break;
- case 216: /* expr ::= expr IS NOT expr */
-{
- spanBinaryExpr(&yygotominor.yy342,pParse,TK_ISNOT,&yymsp[-3].minor.yy342,&yymsp[0].minor.yy342);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_NOTNULL);
-}
- break;
- case 217: /* expr ::= NOT expr */
- case 218: /* expr ::= BITNOT expr */ yytestcase(yyruleno==218);
-{spanUnaryPrefix(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
- break;
- case 219: /* expr ::= MINUS expr */
-{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UMINUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
- break;
- case 220: /* expr ::= PLUS expr */
-{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UPLUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
- break;
- case 223: /* expr ::= expr between_op expr AND expr */
-{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pList = pList;
- }else{
- sqlite3ExprListDelete(pParse->db, pList);
- }
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
-}
- break;
- case 226: /* expr ::= expr in_op LP exprlist RP */
-{
- if( yymsp[-1].minor.yy442==0 ){
- /* Expressions of the form
- **
- ** expr1 IN ()
- ** expr1 NOT IN ()
- **
- ** simplify to constants 0 (false) and 1 (true), respectively,
- ** regardless of the value of expr1.
- */
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy392]);
- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy342.pExpr);
- }else{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pList = yymsp[-1].minor.yy442;
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
- }else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442);
- }
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- }
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 227: /* expr ::= LP select RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
- ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
- }
- yygotominor.yy342.zStart = yymsp[-2].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 228: /* expr ::= expr in_op LP select RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
- ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
- }
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 229: /* expr ::= expr in_op nm dbnm */
-{
- SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
- }else{
- sqlite3SrcListDelete(pParse->db, pSrc);
- }
- if( yymsp[-2].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-3].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
- }
- break;
- case 230: /* expr ::= EXISTS LP select RP */
-{
- Expr *p = yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
- if( p ){
- p->x.pSelect = yymsp[-1].minor.yy159;
- ExprSetProperty(p, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, p);
- }else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
- }
- yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
- }
- break;
- case 231: /* expr ::= CASE case_operand case_exprlist case_else END */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, yymsp[-1].minor.yy122, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pList = yymsp[-2].minor.yy442;
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
- }else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442);
- }
- yygotominor.yy342.zStart = yymsp[-4].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 232: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[-2].minor.yy342.pExpr);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
-}
- break;
- case 233: /* case_exprlist ::= WHEN expr THEN expr */
-{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
-}
- break;
- case 240: /* nexprlist ::= nexprlist COMMA expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
- break;
- case 241: /* nexprlist ::= expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
- break;
- case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
-{
- sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
- sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392,
- &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392);
-}
- break;
- case 243: /* uniqueflag ::= UNIQUE */
- case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
-{yygotominor.yy392 = OE_Abort;}
- break;
- case 244: /* uniqueflag ::= */
-{yygotominor.yy392 = OE_None;}
- break;
- case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
-{
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
- sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 248: /* idxlist ::= nm collate sortorder */
-{
- Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
-}
- break;
- case 249: /* collate ::= */
-{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
- break;
- case 251: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy347, yymsp[-1].minor.yy392);}
- break;
- case 252: /* cmd ::= VACUUM */
- case 253: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==253);
-{sqlite3Vacuum(pParse);}
- break;
- case 254: /* cmd ::= PRAGMA nm dbnm */
-{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
- break;
- case 255: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
- break;
- case 256: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
-{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
- break;
- case 257: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
- break;
- case 258: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
-{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
- break;
- case 268: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
-{
- Token all;
- all.z = yymsp[-3].minor.yy0.z;
- all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy327, &all);
-}
- break;
- case 269: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
-{
- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy392, yymsp[-4].minor.yy410.a, yymsp[-4].minor.yy410.b, yymsp[-2].minor.yy347, yymsp[0].minor.yy122, yymsp[-10].minor.yy392, yymsp[-8].minor.yy392);
- yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
-}
- break;
- case 270: /* trigger_time ::= BEFORE */
- case 273: /* trigger_time ::= */ yytestcase(yyruleno==273);
-{ yygotominor.yy392 = TK_BEFORE; }
- break;
- case 271: /* trigger_time ::= AFTER */
-{ yygotominor.yy392 = TK_AFTER; }
- break;
- case 272: /* trigger_time ::= INSTEAD OF */
-{ yygotominor.yy392 = TK_INSTEAD;}
- break;
- case 274: /* trigger_event ::= DELETE|INSERT */
- case 275: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==275);
-{yygotominor.yy410.a = yymsp[0].major; yygotominor.yy410.b = 0;}
- break;
- case 276: /* trigger_event ::= UPDATE OF inscollist */
-{yygotominor.yy410.a = TK_UPDATE; yygotominor.yy410.b = yymsp[0].minor.yy180;}
- break;
- case 279: /* when_clause ::= */
- case 301: /* key_opt ::= */ yytestcase(yyruleno==301);
-{ yygotominor.yy122 = 0; }
- break;
- case 280: /* when_clause ::= WHEN expr */
- case 302: /* key_opt ::= KEY expr */ yytestcase(yyruleno==302);
-{ yygotominor.yy122 = yymsp[0].minor.yy342.pExpr; }
- break;
- case 281: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
-{
- assert( yymsp[-2].minor.yy327!=0 );
- yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327;
- yymsp[-2].minor.yy327->pLast = yymsp[-1].minor.yy327;
- yygotominor.yy327 = yymsp[-2].minor.yy327;
-}
- break;
- case 282: /* trigger_cmd_list ::= trigger_cmd SEMI */
-{
- assert( yymsp[-1].minor.yy327!=0 );
- yymsp[-1].minor.yy327->pLast = yymsp[-1].minor.yy327;
- yygotominor.yy327 = yymsp[-1].minor.yy327;
-}
- break;
- case 284: /* trnm ::= nm DOT nm */
-{
- yygotominor.yy0 = yymsp[0].minor.yy0;
- sqlite3ErrorMsg(pParse,
- "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
- "statements within triggers");
-}
- break;
- case 286: /* tridxby ::= INDEXED BY nm */
-{
- sqlite3ErrorMsg(pParse,
- "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
- "within triggers");
-}
- break;
- case 287: /* tridxby ::= NOT INDEXED */
-{
- sqlite3ErrorMsg(pParse,
- "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
- "within triggers");
-}
- break;
- case 288: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
-{ yygotominor.yy327 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy442, yymsp[0].minor.yy122, yymsp[-5].minor.yy258); }
- break;
- case 289: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */
-{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-4].minor.yy258);}
- break;
- case 290: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
-{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, 0, yymsp[0].minor.yy159, yymsp[-4].minor.yy258);}
- break;
- case 291: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
-{yygotominor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy122);}
- break;
- case 292: /* trigger_cmd ::= select */
-{yygotominor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); }
- break;
- case 293: /* expr ::= RAISE LP IGNORE RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->affinity = OE_Ignore;
- }
- yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 294: /* expr ::= RAISE LP raisetype COMMA nm RP */
-{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
- if( yygotominor.yy342.pExpr ) {
- yygotominor.yy342.pExpr->affinity = (char)yymsp[-3].minor.yy392;
- }
- yygotominor.yy342.zStart = yymsp[-5].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
-}
- break;
- case 295: /* raisetype ::= ROLLBACK */
-{yygotominor.yy392 = OE_Rollback;}
- break;
- case 297: /* raisetype ::= FAIL */
-{yygotominor.yy392 = OE_Fail;}
- break;
- case 298: /* cmd ::= DROP TRIGGER ifexists fullname */
-{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392);
-}
- break;
- case 299: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
-{
- sqlite3Attach(pParse, yymsp[-3].minor.yy342.pExpr, yymsp[-1].minor.yy342.pExpr, yymsp[0].minor.yy122);
-}
- break;
- case 300: /* cmd ::= DETACH database_kw_opt expr */
-{
- sqlite3Detach(pParse, yymsp[0].minor.yy342.pExpr);
-}
- break;
- case 305: /* cmd ::= REINDEX */
-{sqlite3Reindex(pParse, 0, 0);}
- break;
- case 306: /* cmd ::= REINDEX nm dbnm */
-{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
- break;
- case 307: /* cmd ::= ANALYZE */
-{sqlite3Analyze(pParse, 0, 0);}
- break;
- case 308: /* cmd ::= ANALYZE nm dbnm */
-{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
- break;
- case 309: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
-{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0);
-}
- break;
- case 310: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
-{
- sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
-}
- break;
- case 311: /* add_column_fullname ::= fullname */
-{
- pParse->db->lookaside.bEnabled = 0;
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347);
-}
- break;
- case 314: /* cmd ::= create_vtab */
-{sqlite3VtabFinishParse(pParse,0);}
- break;
- case 315: /* cmd ::= create_vtab LP vtabarglist RP */
-{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
- break;
- case 316: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
-{
- sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy392);
-}
- break;
- case 319: /* vtabarg ::= */
-{sqlite3VtabArgInit(pParse);}
- break;
- case 321: /* vtabargtoken ::= ANY */
- case 322: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==322);
- case 323: /* lp ::= LP */ yytestcase(yyruleno==323);
-{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
- break;
- default:
- /* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
- /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
- /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2);
- /* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3);
- /* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4);
- /* (10) trans_opt ::= */ yytestcase(yyruleno==10);
- /* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11);
- /* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12);
- /* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
- /* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
- /* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
- /* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34);
- /* (35) columnlist ::= column */ yytestcase(yyruleno==35);
- /* (44) type ::= */ yytestcase(yyruleno==44);
- /* (51) signed ::= plus_num */ yytestcase(yyruleno==51);
- /* (52) signed ::= minus_num */ yytestcase(yyruleno==52);
- /* (53) carglist ::= carglist ccons */ yytestcase(yyruleno==53);
- /* (54) carglist ::= */ yytestcase(yyruleno==54);
- /* (61) ccons ::= NULL onconf */ yytestcase(yyruleno==61);
- /* (89) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==89);
- /* (90) conslist ::= tcons */ yytestcase(yyruleno==90);
- /* (92) tconscomma ::= */ yytestcase(yyruleno==92);
- /* (277) foreach_clause ::= */ yytestcase(yyruleno==277);
- /* (278) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==278);
- /* (285) tridxby ::= */ yytestcase(yyruleno==285);
- /* (303) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==303);
- /* (304) database_kw_opt ::= */ yytestcase(yyruleno==304);
- /* (312) kwcolumn_opt ::= */ yytestcase(yyruleno==312);
- /* (313) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==313);
- /* (317) vtabarglist ::= vtabarg */ yytestcase(yyruleno==317);
- /* (318) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==318);
- /* (320) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==320);
- /* (324) anylist ::= */ yytestcase(yyruleno==324);
- /* (325) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==325);
- /* (326) anylist ::= anylist ANY */ yytestcase(yyruleno==326);
- break;
- };
- assert( yyruleno>=0 && yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
- yygoto = yyRuleInfo[yyruleno].lhs;
- yysize = yyRuleInfo[yyruleno].nrhs;
- yypParser->yyidx -= yysize;
- yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
- if( yyact < YYNSTATE ){
-#ifdef NDEBUG
- /* If we are not debugging and the reduce action popped at least
- ** one element off the stack, then we can push the new element back
- ** onto the stack here, and skip the stack overflow test in yy_shift().
- ** That gives a significant speed improvement. */
- if( yysize ){
- yypParser->yyidx++;
- yymsp -= yysize-1;
- yymsp->stateno = (YYACTIONTYPE)yyact;
- yymsp->major = (YYCODETYPE)yygoto;
- yymsp->minor = yygotominor;
- }else
-#endif
- {
- yy_shift(yypParser,yyact,yygoto,&yygotominor);
- }
- }else{
- assert( yyact == YYNSTATE + YYNRULE + 1 );
- yy_accept(yypParser);
- }
-}
-
-/*
-** The following code executes when the parse fails
-*/
-#ifndef YYNOERRORRECOVERY
-static void yy_parse_failed(
- yyParser *yypParser /* The parser */
-){
- sqlite3ParserARG_FETCH;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
- }
-#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
- /* Here code is inserted which will be executed whenever the
- ** parser fails */
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-}
-#endif /* YYNOERRORRECOVERY */
-
-/*
-** The following code executes when a syntax error first occurs.
-*/
-static void yy_syntax_error(
- yyParser *yypParser, /* The parser */
- int yymajor, /* The major type of the error token */
- YYMINORTYPE yyminor /* The minor type of the error token */
-){
- sqlite3ParserARG_FETCH;
-#define TOKEN (yyminor.yy0)
-
- UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */
- assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-}
-
-/*
-** The following is executed when the parser accepts
-*/
-static void yy_accept(
- yyParser *yypParser /* The parser */
-){
- sqlite3ParserARG_FETCH;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
- }
-#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
- /* Here code is inserted which will be executed whenever the
- ** parser accepts */
- sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
-}
-
-/* The main parser program.
-** The first argument is a pointer to a structure obtained from
-** "sqlite3ParserAlloc" which describes the current state of the parser.
-** The second argument is the major token number. The third is
-** the minor token. The fourth optional argument is whatever the
-** user wants (and specified in the grammar) and is available for
-** use by the action routines.
-**
-** Inputs:
-** <ul>
-** <li> A pointer to the parser (an opaque structure.)
-** <li> The major token number.
-** <li> The minor token number.
-** <li> An option argument of a grammar-specified type.
-** </ul>
-**
-** Outputs:
-** None.
-*/
-SQLITE_PRIVATE void sqlite3Parser(
- void *yyp, /* The parser */
- int yymajor, /* The major token code number */
- sqlite3ParserTOKENTYPE yyminor /* The value for the token */
- sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */
-){
- YYMINORTYPE yyminorunion;
- int yyact; /* The parser action. */
-#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
- int yyendofinput; /* True if we are at the end of input */
-#endif
-#ifdef YYERRORSYMBOL
- int yyerrorhit = 0; /* True if yymajor has invoked an error */
-#endif
- yyParser *yypParser; /* The parser */
-
- /* (re)initialize the parser, if necessary */
- yypParser = (yyParser*)yyp;
- if( yypParser->yyidx<0 ){
-#if YYSTACKDEPTH<=0
- if( yypParser->yystksz <=0 ){
- /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
- yyminorunion = yyzerominor;
- yyStackOverflow(yypParser, &yyminorunion);
- return;
- }
-#endif
- yypParser->yyidx = 0;
- yypParser->yyerrcnt = -1;
- yypParser->yystack[0].stateno = 0;
- yypParser->yystack[0].major = 0;
- }
- yyminorunion.yy0 = yyminor;
-#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
- yyendofinput = (yymajor==0);
-#endif
- sqlite3ParserARG_STORE;
-
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
- }
-#endif
-
- do{
- yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
- if( yyact<YYNSTATE ){
- yy_shift(yypParser,yyact,yymajor,&yyminorunion);
- yypParser->yyerrcnt--;
- yymajor = YYNOCODE;
- }else if( yyact < YYNSTATE + YYNRULE ){
- yy_reduce(yypParser,yyact-YYNSTATE);
- }else{
- assert( yyact == YY_ERROR_ACTION );
-#ifdef YYERRORSYMBOL
- int yymx;
-#endif
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
- }
-#endif
-#ifdef YYERRORSYMBOL
- /* A syntax error has occurred.
- ** The response to an error depends upon whether or not the
- ** grammar defines an error token "ERROR".
- **
- ** This is what we do if the grammar does define ERROR:
- **
- ** * Call the %syntax_error function.
- **
- ** * Begin popping the stack until we enter a state where
- ** it is legal to shift the error symbol, then shift
- ** the error symbol.
- **
- ** * Set the error count to three.
- **
- ** * Begin accepting and shifting new tokens. No new error
- ** processing will occur until three tokens have been
- ** shifted successfully.
- **
- */
- if( yypParser->yyerrcnt<0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
- }
- yymx = yypParser->yystack[yypParser->yyidx].major;
- if( yymx==YYERRORSYMBOL || yyerrorhit ){
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sDiscard input token %s\n",
- yyTracePrompt,yyTokenName[yymajor]);
- }
-#endif
- yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
- yymajor = YYNOCODE;
- }else{
- while(
- yypParser->yyidx >= 0 &&
- yymx != YYERRORSYMBOL &&
- (yyact = yy_find_reduce_action(
- yypParser->yystack[yypParser->yyidx].stateno,
- YYERRORSYMBOL)) >= YYNSTATE
- ){
- yy_pop_parser_stack(yypParser);
- }
- if( yypParser->yyidx < 0 || yymajor==0 ){
- yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
- yy_parse_failed(yypParser);
- yymajor = YYNOCODE;
- }else if( yymx!=YYERRORSYMBOL ){
- YYMINORTYPE u2;
- u2.YYERRSYMDT = 0;
- yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
- }
- }
- yypParser->yyerrcnt = 3;
- yyerrorhit = 1;
-#elif defined(YYNOERRORRECOVERY)
- /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
- ** do any kind of error recovery. Instead, simply invoke the syntax
- ** error routine and continue going as if nothing had happened.
- **
- ** Applications can set this macro (for example inside %include) if
- ** they intend to abandon the parse upon the first syntax error seen.
- */
- yy_syntax_error(yypParser,yymajor,yyminorunion);
- yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
- yymajor = YYNOCODE;
-
-#else /* YYERRORSYMBOL is not defined */
- /* This is what we do if the grammar does not define ERROR:
- **
- ** * Report an error message, and throw away the input token.
- **
- ** * If the input token is $, then fail the parse.
- **
- ** As before, subsequent error messages are suppressed until
- ** three input tokens have been successfully shifted.
- */
- if( yypParser->yyerrcnt<=0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
- }
- yypParser->yyerrcnt = 3;
- yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
- if( yyendofinput ){
- yy_parse_failed(yypParser);
- }
- yymajor = YYNOCODE;
-#endif
- }
- }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
- return;
-}
-
-/************** End of parse.c ***********************************************/
-/************** Begin file tokenize.c ****************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** An tokenizer for SQL
-**
-** This file contains C code that splits an SQL input string up into
-** individual tokens and sends those tokens one-by-one over to the
-** parser for analysis.
-*/
-/* #include <stdlib.h> */
-
-/*
-** The charMap() macro maps alphabetic characters into their
-** lower-case ASCII equivalent. On ASCII machines, this is just
-** an upper-to-lower case map. On EBCDIC machines we also need
-** to adjust the encoding. Only alphabetic characters and underscores
-** need to be translated.
-*/
-#ifdef SQLITE_ASCII
-# define charMap(X) sqlite3UpperToLower[(unsigned char)X]
-#endif
-#ifdef SQLITE_EBCDIC
-# define charMap(X) ebcdicToAscii[(unsigned char)X]
-const unsigned char ebcdicToAscii[] = {
-/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, /* 6x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7x */
- 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* 8x */
- 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* 9x */
- 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ax */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */
- 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* Cx */
- 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* Dx */
- 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ex */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Fx */
-};
-#endif
-
-/*
-** The sqlite3KeywordCode function looks up an identifier to determine if
-** it is a keyword. If it is a keyword, the token code of that keyword is
-** returned. If the input is not a keyword, TK_ID is returned.
-**
-** The implementation of this routine was generated by a program,
-** mkkeywordhash.h, located in the tool subdirectory of the distribution.
-** The output of the mkkeywordhash.c program is written into a file
-** named keywordhash.h and then included into this source file by
-** the #include below.
-*/
-/************** Include keywordhash.h in the middle of tokenize.c ************/
-/************** Begin file keywordhash.h *************************************/
-/***** This file contains automatically generated code ******
-**
-** The code in this file has been automatically generated by
-**
-** sqlite/tool/mkkeywordhash.c
-**
-** The code in this file implements a function that determines whether
-** or not a given identifier is really an SQL keyword. The same thing
-** might be implemented more directly using a hand-written hash table.
-** But by using this automatically generated code, the size of the code
-** is substantially reduced. This is important for embedded applications
-** on platforms with limited memory.
-*/
-/* Hash score: 175 */
-static int keywordCode(const char *z, int n){
- /* zText[] encodes 811 bytes of keywords in 541 bytes */
- /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
- /* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */
- /* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */
- /* UNIQUERYATTACHAVINGROUPDATEBEGINNERELEASEBETWEENOTNULLIKE */
- /* CASCADELETECASECOLLATECREATECURRENT_DATEDETACHIMMEDIATEJOIN */
- /* SERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHENWHERENAME */
- /* AFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSS */
- /* CURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAILFROMFULLGLOBYIF */
- /* ISNULLORDERESTRICTOUTERIGHTROLLBACKROWUNIONUSINGVACUUMVIEW */
- /* INITIALLY */
- static const char zText[540] = {
- 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
- 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
- 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
- 'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F',
- 'E','R','R','A','B','L','E','L','S','E','X','C','E','P','T','R','A','N',
- 'S','A','C','T','I','O','N','A','T','U','R','A','L','T','E','R','A','I',
- 'S','E','X','C','L','U','S','I','V','E','X','I','S','T','S','A','V','E',
- 'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E',
- 'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T',
- 'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
- 'U','E','R','Y','A','T','T','A','C','H','A','V','I','N','G','R','O','U',
- 'P','D','A','T','E','B','E','G','I','N','N','E','R','E','L','E','A','S',
- 'E','B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C',
- 'A','S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L',
- 'A','T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D',
- 'A','T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E',
- 'J','O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A',
- 'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U',
- 'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W',
- 'H','E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C',
- 'E','A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R',
- 'E','M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M',
- 'M','I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U',
- 'R','R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M',
- 'A','R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T',
- 'D','R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L',
- 'O','B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S',
- 'T','R','I','C','T','O','U','T','E','R','I','G','H','T','R','O','L','L',
- 'B','A','C','K','R','O','W','U','N','I','O','N','U','S','I','N','G','V',
- 'A','C','U','U','M','V','I','E','W','I','N','I','T','I','A','L','L','Y',
- };
- static const unsigned char aHash[127] = {
- 72, 101, 114, 70, 0, 45, 0, 0, 78, 0, 73, 0, 0,
- 42, 12, 74, 15, 0, 113, 81, 50, 108, 0, 19, 0, 0,
- 118, 0, 116, 111, 0, 22, 89, 0, 9, 0, 0, 66, 67,
- 0, 65, 6, 0, 48, 86, 98, 0, 115, 97, 0, 0, 44,
- 0, 99, 24, 0, 17, 0, 119, 49, 23, 0, 5, 106, 25,
- 92, 0, 0, 121, 102, 56, 120, 53, 28, 51, 0, 87, 0,
- 96, 26, 0, 95, 0, 0, 0, 91, 88, 93, 84, 105, 14,
- 39, 104, 0, 77, 0, 18, 85, 107, 32, 0, 117, 76, 109,
- 58, 46, 80, 0, 0, 90, 40, 0, 112, 0, 36, 0, 0,
- 29, 0, 82, 59, 60, 0, 20, 57, 0, 52,
- };
- static const unsigned char aNext[121] = {
- 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
- 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 43, 3, 47,
- 0, 0, 0, 0, 30, 0, 54, 0, 38, 0, 0, 0, 1,
- 62, 0, 0, 63, 0, 41, 0, 0, 0, 0, 0, 0, 0,
- 61, 0, 0, 0, 0, 31, 55, 16, 34, 10, 0, 0, 0,
- 0, 0, 0, 0, 11, 68, 75, 0, 8, 0, 100, 94, 0,
- 103, 0, 83, 0, 71, 0, 0, 110, 27, 37, 69, 79, 0,
- 35, 64, 0, 0,
- };
- static const unsigned char aLen[121] = {
- 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6,
- 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6,
- 11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10,
- 4, 6, 2, 3, 9, 4, 2, 6, 5, 6, 6, 5, 6,
- 5, 5, 7, 7, 7, 3, 2, 4, 4, 7, 3, 6, 4,
- 7, 6, 12, 6, 9, 4, 6, 5, 4, 7, 6, 5, 6,
- 7, 5, 4, 5, 6, 5, 7, 3, 7, 13, 2, 2, 4,
- 6, 6, 8, 5, 17, 12, 7, 8, 8, 2, 4, 4, 4,
- 4, 4, 2, 2, 6, 5, 8, 5, 5, 8, 3, 5, 5,
- 6, 4, 9, 3,
- };
- static const unsigned short int aOffset[121] = {
- 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33,
- 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81,
- 86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
- 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 189, 194, 197,
- 203, 206, 210, 217, 223, 223, 223, 226, 229, 233, 234, 238, 244,
- 248, 255, 261, 273, 279, 288, 290, 296, 301, 303, 310, 315, 320,
- 326, 332, 337, 341, 344, 350, 354, 361, 363, 370, 372, 374, 383,
- 387, 393, 399, 407, 412, 412, 428, 435, 442, 443, 450, 454, 458,
- 462, 466, 469, 471, 473, 479, 483, 491, 495, 500, 508, 511, 516,
- 521, 527, 531, 536,
- };
- static const unsigned char aCode[121] = {
- TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE,
- TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN,
- TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD,
- TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE,
- TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE,
- TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW,
- TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT,
- TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO,
- TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP,
- TK_OR, TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING,
- TK_GROUP, TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RELEASE,
- TK_BETWEEN, TK_NOTNULL, TK_NOT, TK_NO, TK_NULL,
- TK_LIKE_KW, TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE,
- TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE,
- TK_JOIN, TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE,
- TK_PRAGMA, TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT,
- TK_WHEN, TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE,
- TK_AND, TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN,
- TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW,
- TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT,
- TK_IS, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW,
- TK_LIKE_KW, TK_BY, TK_IF, TK_ISNULL, TK_ORDER,
- TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, TK_ROLLBACK, TK_ROW,
- TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY,
- TK_ALL,
- };
- int h, i;
- if( n<2 ) return TK_ID;
- h = ((charMap(z[0])*4) ^
- (charMap(z[n-1])*3) ^
- n) % 127;
- for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
- if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
- testcase( i==0 ); /* REINDEX */
- testcase( i==1 ); /* INDEXED */
- testcase( i==2 ); /* INDEX */
- testcase( i==3 ); /* DESC */
- testcase( i==4 ); /* ESCAPE */
- testcase( i==5 ); /* EACH */
- testcase( i==6 ); /* CHECK */
- testcase( i==7 ); /* KEY */
- testcase( i==8 ); /* BEFORE */
- testcase( i==9 ); /* FOREIGN */
- testcase( i==10 ); /* FOR */
- testcase( i==11 ); /* IGNORE */
- testcase( i==12 ); /* REGEXP */
- testcase( i==13 ); /* EXPLAIN */
- testcase( i==14 ); /* INSTEAD */
- testcase( i==15 ); /* ADD */
- testcase( i==16 ); /* DATABASE */
- testcase( i==17 ); /* AS */
- testcase( i==18 ); /* SELECT */
- testcase( i==19 ); /* TABLE */
- testcase( i==20 ); /* LEFT */
- testcase( i==21 ); /* THEN */
- testcase( i==22 ); /* END */
- testcase( i==23 ); /* DEFERRABLE */
- testcase( i==24 ); /* ELSE */
- testcase( i==25 ); /* EXCEPT */
- testcase( i==26 ); /* TRANSACTION */
- testcase( i==27 ); /* ACTION */
- testcase( i==28 ); /* ON */
- testcase( i==29 ); /* NATURAL */
- testcase( i==30 ); /* ALTER */
- testcase( i==31 ); /* RAISE */
- testcase( i==32 ); /* EXCLUSIVE */
- testcase( i==33 ); /* EXISTS */
- testcase( i==34 ); /* SAVEPOINT */
- testcase( i==35 ); /* INTERSECT */
- testcase( i==36 ); /* TRIGGER */
- testcase( i==37 ); /* REFERENCES */
- testcase( i==38 ); /* CONSTRAINT */
- testcase( i==39 ); /* INTO */
- testcase( i==40 ); /* OFFSET */
- testcase( i==41 ); /* OF */
- testcase( i==42 ); /* SET */
- testcase( i==43 ); /* TEMPORARY */
- testcase( i==44 ); /* TEMP */
- testcase( i==45 ); /* OR */
- testcase( i==46 ); /* UNIQUE */
- testcase( i==47 ); /* QUERY */
- testcase( i==48 ); /* ATTACH */
- testcase( i==49 ); /* HAVING */
- testcase( i==50 ); /* GROUP */
- testcase( i==51 ); /* UPDATE */
- testcase( i==52 ); /* BEGIN */
- testcase( i==53 ); /* INNER */
- testcase( i==54 ); /* RELEASE */
- testcase( i==55 ); /* BETWEEN */
- testcase( i==56 ); /* NOTNULL */
- testcase( i==57 ); /* NOT */
- testcase( i==58 ); /* NO */
- testcase( i==59 ); /* NULL */
- testcase( i==60 ); /* LIKE */
- testcase( i==61 ); /* CASCADE */
- testcase( i==62 ); /* ASC */
- testcase( i==63 ); /* DELETE */
- testcase( i==64 ); /* CASE */
- testcase( i==65 ); /* COLLATE */
- testcase( i==66 ); /* CREATE */
- testcase( i==67 ); /* CURRENT_DATE */
- testcase( i==68 ); /* DETACH */
- testcase( i==69 ); /* IMMEDIATE */
- testcase( i==70 ); /* JOIN */
- testcase( i==71 ); /* INSERT */
- testcase( i==72 ); /* MATCH */
- testcase( i==73 ); /* PLAN */
- testcase( i==74 ); /* ANALYZE */
- testcase( i==75 ); /* PRAGMA */
- testcase( i==76 ); /* ABORT */
- testcase( i==77 ); /* VALUES */
- testcase( i==78 ); /* VIRTUAL */
- testcase( i==79 ); /* LIMIT */
- testcase( i==80 ); /* WHEN */
- testcase( i==81 ); /* WHERE */
- testcase( i==82 ); /* RENAME */
- testcase( i==83 ); /* AFTER */
- testcase( i==84 ); /* REPLACE */
- testcase( i==85 ); /* AND */
- testcase( i==86 ); /* DEFAULT */
- testcase( i==87 ); /* AUTOINCREMENT */
- testcase( i==88 ); /* TO */
- testcase( i==89 ); /* IN */
- testcase( i==90 ); /* CAST */
- testcase( i==91 ); /* COLUMN */
- testcase( i==92 ); /* COMMIT */
- testcase( i==93 ); /* CONFLICT */
- testcase( i==94 ); /* CROSS */
- testcase( i==95 ); /* CURRENT_TIMESTAMP */
- testcase( i==96 ); /* CURRENT_TIME */
- testcase( i==97 ); /* PRIMARY */
- testcase( i==98 ); /* DEFERRED */
- testcase( i==99 ); /* DISTINCT */
- testcase( i==100 ); /* IS */
- testcase( i==101 ); /* DROP */
- testcase( i==102 ); /* FAIL */
- testcase( i==103 ); /* FROM */
- testcase( i==104 ); /* FULL */
- testcase( i==105 ); /* GLOB */
- testcase( i==106 ); /* BY */
- testcase( i==107 ); /* IF */
- testcase( i==108 ); /* ISNULL */
- testcase( i==109 ); /* ORDER */
- testcase( i==110 ); /* RESTRICT */
- testcase( i==111 ); /* OUTER */
- testcase( i==112 ); /* RIGHT */
- testcase( i==113 ); /* ROLLBACK */
- testcase( i==114 ); /* ROW */
- testcase( i==115 ); /* UNION */
- testcase( i==116 ); /* USING */
- testcase( i==117 ); /* VACUUM */
- testcase( i==118 ); /* VIEW */
- testcase( i==119 ); /* INITIALLY */
- testcase( i==120 ); /* ALL */
- return aCode[i];
- }
- }
- return TK_ID;
-}
-SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
- return keywordCode((char*)z, n);
-}
-#define SQLITE_N_KEYWORD 121
-
-/************** End of keywordhash.h *****************************************/
-/************** Continuing where we left off in tokenize.c *******************/
-
-
-/*
-** If X is a character that can be used in an identifier then
-** IdChar(X) will be true. Otherwise it is false.
-**
-** For ASCII, any character with the high-order bit set is
-** allowed in an identifier. For 7-bit characters,
-** sqlite3IsIdChar[X] must be 1.
-**
-** For EBCDIC, the rules are more complex but have the same
-** end result.
-**
-** Ticket #1066. the SQL standard does not allow '$' in the
-** middle of identfiers. But many SQL implementations do.
-** SQLite will allow '$' in identifiers for compatibility.
-** But the feature is undocumented.
-*/
-#ifdef SQLITE_ASCII
-#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0)
-#endif
-#ifdef SQLITE_EBCDIC
-SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = {
-/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 4x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, /* 5x */
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 6x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* 7x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, /* 8x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, /* 9x */
- 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, /* Ax */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Cx */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Dx */
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */
-};
-#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
-#endif
-
-
-/*
-** Return the length of the token that begins at z[0].
-** Store the token type in *tokenType before returning.
-*/
-SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
- int i, c;
- switch( *z ){
- case ' ': case '\t': case '\n': case '\f': case '\r': {
- testcase( z[0]==' ' );
- testcase( z[0]=='\t' );
- testcase( z[0]=='\n' );
- testcase( z[0]=='\f' );
- testcase( z[0]=='\r' );
- for(i=1; sqlite3Isspace(z[i]); i++){}
- *tokenType = TK_SPACE;
- return i;
- }
- case '-': {
- if( z[1]=='-' ){
- /* IMP: R-50417-27976 -- syntax diagram for comments */
- for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
- *tokenType = TK_SPACE; /* IMP: R-22934-25134 */
- return i;
- }
- *tokenType = TK_MINUS;
- return 1;
- }
- case '(': {
- *tokenType = TK_LP;
- return 1;
- }
- case ')': {
- *tokenType = TK_RP;
- return 1;
- }
- case ';': {
- *tokenType = TK_SEMI;
- return 1;
- }
- case '+': {
- *tokenType = TK_PLUS;
- return 1;
- }
- case '*': {
- *tokenType = TK_STAR;
- return 1;
- }
- case '/': {
- if( z[1]!='*' || z[2]==0 ){
- *tokenType = TK_SLASH;
- return 1;
- }
- /* IMP: R-50417-27976 -- syntax diagram for comments */
- for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
- if( c ) i++;
- *tokenType = TK_SPACE; /* IMP: R-22934-25134 */
- return i;
- }
- case '%': {
- *tokenType = TK_REM;
- return 1;
- }
- case '=': {
- *tokenType = TK_EQ;
- return 1 + (z[1]=='=');
- }
- case '<': {
- if( (c=z[1])=='=' ){
- *tokenType = TK_LE;
- return 2;
- }else if( c=='>' ){
- *tokenType = TK_NE;
- return 2;
- }else if( c=='<' ){
- *tokenType = TK_LSHIFT;
- return 2;
- }else{
- *tokenType = TK_LT;
- return 1;
- }
- }
- case '>': {
- if( (c=z[1])=='=' ){
- *tokenType = TK_GE;
- return 2;
- }else if( c=='>' ){
- *tokenType = TK_RSHIFT;
- return 2;
- }else{
- *tokenType = TK_GT;
- return 1;
- }
- }
- case '!': {
- if( z[1]!='=' ){
- *tokenType = TK_ILLEGAL;
- return 2;
- }else{
- *tokenType = TK_NE;
- return 2;
- }
- }
- case '|': {
- if( z[1]!='|' ){
- *tokenType = TK_BITOR;
- return 1;
- }else{
- *tokenType = TK_CONCAT;
- return 2;
- }
- }
- case ',': {
- *tokenType = TK_COMMA;
- return 1;
- }
- case '&': {
- *tokenType = TK_BITAND;
- return 1;
- }
- case '~': {
- *tokenType = TK_BITNOT;
- return 1;
- }
- case '`':
- case '\'':
- case '"': {
- int delim = z[0];
- testcase( delim=='`' );
- testcase( delim=='\'' );
- testcase( delim=='"' );
- for(i=1; (c=z[i])!=0; i++){
- if( c==delim ){
- if( z[i+1]==delim ){
- i++;
- }else{
- break;
- }
- }
- }
- if( c=='\'' ){
- *tokenType = TK_STRING;
- return i+1;
- }else if( c!=0 ){
- *tokenType = TK_ID;
- return i+1;
- }else{
- *tokenType = TK_ILLEGAL;
- return i;
- }
- }
- case '.': {
-#ifndef SQLITE_OMIT_FLOATING_POINT
- if( !sqlite3Isdigit(z[1]) )
-#endif
- {
- *tokenType = TK_DOT;
- return 1;
- }
- /* If the next character is a digit, this is a floating point
- ** number that begins with ".". Fall thru into the next case */
- }
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9': {
- testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' );
- testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' );
- testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' );
- testcase( z[0]=='9' );
- *tokenType = TK_INTEGER;
- for(i=0; sqlite3Isdigit(z[i]); i++){}
-#ifndef SQLITE_OMIT_FLOATING_POINT
- if( z[i]=='.' ){
- i++;
- while( sqlite3Isdigit(z[i]) ){ i++; }
- *tokenType = TK_FLOAT;
- }
- if( (z[i]=='e' || z[i]=='E') &&
- ( sqlite3Isdigit(z[i+1])
- || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2]))
- )
- ){
- i += 2;
- while( sqlite3Isdigit(z[i]) ){ i++; }
- *tokenType = TK_FLOAT;
- }
-#endif
- while( IdChar(z[i]) ){
- *tokenType = TK_ILLEGAL;
- i++;
- }
- return i;
- }
- case '[': {
- for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){}
- *tokenType = c==']' ? TK_ID : TK_ILLEGAL;
- return i;
- }
- case '?': {
- *tokenType = TK_VARIABLE;
- for(i=1; sqlite3Isdigit(z[i]); i++){}
- return i;
- }
- case '#': {
- for(i=1; sqlite3Isdigit(z[i]); i++){}
- if( i>1 ){
- /* Parameters of the form #NNN (where NNN is a number) are used
- ** internally by sqlite3NestedParse. */
- *tokenType = TK_REGISTER;
- return i;
- }
- /* Fall through into the next case if the '#' is not followed by
- ** a digit. Try to match #AAAA where AAAA is a parameter name. */
- }
-#ifndef SQLITE_OMIT_TCL_VARIABLE
- case '$':
-#endif
- case '@': /* For compatibility with MS SQL Server */
- case ':': {
- int n = 0;
- testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' );
- *tokenType = TK_VARIABLE;
- for(i=1; (c=z[i])!=0; i++){
- if( IdChar(c) ){
- n++;
-#ifndef SQLITE_OMIT_TCL_VARIABLE
- }else if( c=='(' && n>0 ){
- do{
- i++;
- }while( (c=z[i])!=0 && !sqlite3Isspace(c) && c!=')' );
- if( c==')' ){
- i++;
- }else{
- *tokenType = TK_ILLEGAL;
- }
- break;
- }else if( c==':' && z[i+1]==':' ){
- i++;
-#endif
- }else{
- break;
- }
- }
- if( n==0 ) *tokenType = TK_ILLEGAL;
- return i;
- }
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- case 'x': case 'X': {
- testcase( z[0]=='x' ); testcase( z[0]=='X' );
- if( z[1]=='\'' ){
- *tokenType = TK_BLOB;
- for(i=2; sqlite3Isxdigit(z[i]); i++){}
- if( z[i]!='\'' || i%2 ){
- *tokenType = TK_ILLEGAL;
- while( z[i] && z[i]!='\'' ){ i++; }
- }
- if( z[i] ) i++;
- return i;
- }
- /* Otherwise fall through to the next case */
- }
-#endif
- default: {
- if( !IdChar(*z) ){
- break;
- }
- for(i=1; IdChar(z[i]); i++){}
- *tokenType = keywordCode((char*)z, i);
- return i;
- }
- }
- *tokenType = TK_ILLEGAL;
- return 1;
-}
-
-/*
-** Run the parser on the given SQL string. The parser structure is
-** passed in. An SQLITE_ status code is returned. If an error occurs
-** then an and attempt is made to write an error message into
-** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
-** error message.
-*/
-SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
- int nErr = 0; /* Number of errors encountered */
- int i; /* Loop counter */
- void *pEngine; /* The LEMON-generated LALR(1) parser */
- int tokenType; /* type of the next token */
- int lastTokenParsed = -1; /* type of the previous token */
- u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */
- sqlite3 *db = pParse->db; /* The database connection */
- int mxSqlLen; /* Max length of an SQL string */
-
-
- mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
- if( db->activeVdbeCnt==0 ){
- db->u1.isInterrupted = 0;
- }
- pParse->rc = SQLITE_OK;
- pParse->zTail = zSql;
- i = 0;
- assert( pzErrMsg!=0 );
- pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc);
- if( pEngine==0 ){
- db->mallocFailed = 1;
- return SQLITE_NOMEM;
- }
- assert( pParse->pNewTable==0 );
- assert( pParse->pNewTrigger==0 );
- assert( pParse->nVar==0 );
- assert( pParse->nzVar==0 );
- assert( pParse->azVar==0 );
- enableLookaside = db->lookaside.bEnabled;
- if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
- while( !db->mallocFailed && zSql[i]!=0 ){
- assert( i>=0 );
- pParse->sLastToken.z = &zSql[i];
- pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
- i += pParse->sLastToken.n;
- if( i>mxSqlLen ){
- pParse->rc = SQLITE_TOOBIG;
- break;
- }
- switch( tokenType ){
- case TK_SPACE: {
- if( db->u1.isInterrupted ){
- sqlite3ErrorMsg(pParse, "interrupt");
- pParse->rc = SQLITE_INTERRUPT;
- goto abort_parse;
- }
- break;
- }
- case TK_ILLEGAL: {
- sqlite3DbFree(db, *pzErrMsg);
- *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
- &pParse->sLastToken);
- nErr++;
- goto abort_parse;
- }
- case TK_SEMI: {
- pParse->zTail = &zSql[i];
- /* Fall thru into the default case */
- }
- default: {
- sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
- lastTokenParsed = tokenType;
- if( pParse->rc!=SQLITE_OK ){
- goto abort_parse;
- }
- break;
- }
- }
- }
-abort_parse:
- if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
- if( lastTokenParsed!=TK_SEMI ){
- sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
- pParse->zTail = &zSql[i];
- }
- sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
- }
-#ifdef YYTRACKMAXSTACKDEPTH
- sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
- sqlite3ParserStackPeak(pEngine)
- );
-#endif /* YYDEBUG */
- sqlite3ParserFree(pEngine, sqlite3_free);
- db->lookaside.bEnabled = enableLookaside;
- if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
- }
- if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
- sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
- }
- assert( pzErrMsg!=0 );
- if( pParse->zErrMsg ){
- *pzErrMsg = pParse->zErrMsg;
- sqlite3_log(pParse->rc, "%s", *pzErrMsg);
- pParse->zErrMsg = 0;
- nErr++;
- }
- if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){
- sqlite3VdbeDelete(pParse->pVdbe);
- pParse->pVdbe = 0;
- }
-#ifndef SQLITE_OMIT_SHARED_CACHE
- if( pParse->nested==0 ){
- sqlite3DbFree(db, pParse->aTableLock);
- pParse->aTableLock = 0;
- pParse->nTableLock = 0;
- }
-#endif
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- sqlite3_free(pParse->apVtabLock);
-#endif
-
- if( !IN_DECLARE_VTAB ){
- /* If the pParse->declareVtab flag is set, do not delete any table
- ** structure built up in pParse->pNewTable. The calling code (see vtab.c)
- ** will take responsibility for freeing the Table structure.
- */
- sqlite3DeleteTable(db, pParse->pNewTable);
- }
-
- sqlite3DeleteTrigger(db, pParse->pNewTrigger);
- for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
- sqlite3DbFree(db, pParse->azVar);
- sqlite3DbFree(db, pParse->aAlias);
- while( pParse->pAinc ){
- AutoincInfo *p = pParse->pAinc;
- pParse->pAinc = p->pNext;
- sqlite3DbFree(db, p);
- }
- while( pParse->pZombieTab ){
- Table *p = pParse->pZombieTab;
- pParse->pZombieTab = p->pNextZombie;
- sqlite3DeleteTable(db, p);
- }
- if( nErr>0 && pParse->rc==SQLITE_OK ){
- pParse->rc = SQLITE_ERROR;
- }
- return nErr;
-}
-
-/************** End of tokenize.c ********************************************/
-/************** Begin file complete.c ****************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** An tokenizer for SQL
-**
-** This file contains C code that implements the sqlite3_complete() API.
-** This code used to be part of the tokenizer.c source file. But by
-** separating it out, the code will be automatically omitted from
-** static links that do not use it.
-*/
-#ifndef SQLITE_OMIT_COMPLETE
-
-/*
-** This is defined in tokenize.c. We just have to import the definition.
-*/
-#ifndef SQLITE_AMALGAMATION
-#ifdef SQLITE_ASCII
-#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0)
-#endif
-#ifdef SQLITE_EBCDIC
-SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
-#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
-#endif
-#endif /* SQLITE_AMALGAMATION */
-
-
-/*
-** Token types used by the sqlite3_complete() routine. See the header
-** comments on that procedure for additional information.
-*/
-#define tkSEMI 0
-#define tkWS 1
-#define tkOTHER 2
-#ifndef SQLITE_OMIT_TRIGGER
-#define tkEXPLAIN 3
-#define tkCREATE 4
-#define tkTEMP 5
-#define tkTRIGGER 6
-#define tkEND 7
-#endif
-
-/*
-** Return TRUE if the given SQL string ends in a semicolon.
-**
-** Special handling is require for CREATE TRIGGER statements.
-** Whenever the CREATE TRIGGER keywords are seen, the statement
-** must end with ";END;".
-**
-** This implementation uses a state machine with 8 states:
-**
-** (0) INVALID We have not yet seen a non-whitespace character.
-**
-** (1) START At the beginning or end of an SQL statement. This routine
-** returns 1 if it ends in the START state and 0 if it ends
-** in any other state.
-**
-** (2) NORMAL We are in the middle of statement which ends with a single
-** semicolon.
-**
-** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
-** a statement.
-**
-** (4) CREATE The keyword CREATE has been seen at the beginning of a
-** statement, possibly preceeded by EXPLAIN and/or followed by
-** TEMP or TEMPORARY
-**
-** (5) TRIGGER We are in the middle of a trigger definition that must be
-** ended by a semicolon, the keyword END, and another semicolon.
-**
-** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at
-** the end of a trigger definition.
-**
-** (7) END We've seen the ";END" of the ";END;" that occurs at the end
-** of a trigger difinition.
-**
-** Transitions between states above are determined by tokens extracted
-** from the input. The following tokens are significant:
-**
-** (0) tkSEMI A semicolon.
-** (1) tkWS Whitespace.
-** (2) tkOTHER Any other SQL token.
-** (3) tkEXPLAIN The "explain" keyword.
-** (4) tkCREATE The "create" keyword.
-** (5) tkTEMP The "temp" or "temporary" keyword.
-** (6) tkTRIGGER The "trigger" keyword.
-** (7) tkEND The "end" keyword.
-**
-** Whitespace never causes a state transition and is always ignored.
-** This means that a SQL string of all whitespace is invalid.
-**
-** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed
-** to recognize the end of a trigger can be omitted. All we have to do
-** is look for a semicolon that is not part of an string or comment.
-*/
-SQLITE_API int sqlite3_complete(const char *zSql){
- u8 state = 0; /* Current state, using numbers defined in header comment */
- u8 token; /* Value of the next token */
-
-#ifndef SQLITE_OMIT_TRIGGER
- /* A complex statement machine used to detect the end of a CREATE TRIGGER
- ** statement. This is the normal case.
- */
- static const u8 trans[8][8] = {
- /* Token: */
- /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */
- /* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, },
- /* 1 START: */ { 1, 1, 2, 3, 4, 2, 2, 2, },
- /* 2 NORMAL: */ { 1, 2, 2, 2, 2, 2, 2, 2, },
- /* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, },
- /* 4 CREATE: */ { 1, 4, 2, 2, 2, 4, 5, 2, },
- /* 5 TRIGGER: */ { 6, 5, 5, 5, 5, 5, 5, 5, },
- /* 6 SEMI: */ { 6, 6, 5, 5, 5, 5, 5, 7, },
- /* 7 END: */ { 1, 7, 5, 5, 5, 5, 5, 5, },
- };
-#else
- /* If triggers are not supported by this compile then the statement machine
- ** used to detect the end of a statement is much simplier
- */
- static const u8 trans[3][3] = {
- /* Token: */
- /* State: ** SEMI WS OTHER */
- /* 0 INVALID: */ { 1, 0, 2, },
- /* 1 START: */ { 1, 1, 2, },
- /* 2 NORMAL: */ { 1, 2, 2, },
- };
-#endif /* SQLITE_OMIT_TRIGGER */
-
- while( *zSql ){
- switch( *zSql ){
- case ';': { /* A semicolon */
- token = tkSEMI;
- break;
- }
- case ' ':
- case '\r':
- case '\t':
- case '\n':
- case '\f': { /* White space is ignored */
- token = tkWS;
- break;
- }
- case '/': { /* C-style comments */
- if( zSql[1]!='*' ){
- token = tkOTHER;
- break;
- }
- zSql += 2;
- while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
- if( zSql[0]==0 ) return 0;
- zSql++;
- token = tkWS;
- break;
- }
- case '-': { /* SQL-style comments from "--" to end of line */
- if( zSql[1]!='-' ){
- token = tkOTHER;
- break;
- }
- while( *zSql && *zSql!='\n' ){ zSql++; }
- if( *zSql==0 ) return state==1;
- token = tkWS;
- break;
- }
- case '[': { /* Microsoft-style identifiers in [...] */
- zSql++;
- while( *zSql && *zSql!=']' ){ zSql++; }
- if( *zSql==0 ) return 0;
- token = tkOTHER;
- break;
- }
- case '`': /* Grave-accent quoted symbols used by MySQL */
- case '"': /* single- and double-quoted strings */
- case '\'': {
- int c = *zSql;
- zSql++;
- while( *zSql && *zSql!=c ){ zSql++; }
- if( *zSql==0 ) return 0;
- token = tkOTHER;
- break;
- }
- default: {
-#ifdef SQLITE_EBCDIC
- unsigned char c;
-#endif
- if( IdChar((u8)*zSql) ){
- /* Keywords and unquoted identifiers */
- int nId;
- for(nId=1; IdChar(zSql[nId]); nId++){}
-#ifdef SQLITE_OMIT_TRIGGER
- token = tkOTHER;
-#else
- switch( *zSql ){
- case 'c': case 'C': {
- if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){
- token = tkCREATE;
- }else{
- token = tkOTHER;
- }
- break;
- }
- case 't': case 'T': {
- if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){
- token = tkTRIGGER;
- }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){
- token = tkTEMP;
- }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){
- token = tkTEMP;
- }else{
- token = tkOTHER;
- }
- break;
- }
- case 'e': case 'E': {
- if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){
- token = tkEND;
- }else
-#ifndef SQLITE_OMIT_EXPLAIN
- if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){
- token = tkEXPLAIN;
- }else
-#endif
- {
- token = tkOTHER;
- }
- break;
- }
- default: {
- token = tkOTHER;
- break;
- }
- }
-#endif /* SQLITE_OMIT_TRIGGER */
- zSql += nId-1;
- }else{
- /* Operators and special symbols */
- token = tkOTHER;
- }
- break;
- }
- }
- state = trans[state][token];
- zSql++;
- }
- return state==1;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** This routine is the same as the sqlite3_complete() routine described
-** above, except that the parameter is required to be UTF-16 encoded, not
-** UTF-8.
-*/
-SQLITE_API int sqlite3_complete16(const void *zSql){
- sqlite3_value *pVal;
- char const *zSql8;
- int rc = SQLITE_NOMEM;
-
-#ifndef SQLITE_OMIT_AUTOINIT
- rc = sqlite3_initialize();
- if( rc ) return rc;
-#endif
- pVal = sqlite3ValueNew(0);
- sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
- zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
- if( zSql8 ){
- rc = sqlite3_complete(zSql8);
- }else{
- rc = SQLITE_NOMEM;
- }
- sqlite3ValueFree(pVal);
- return sqlite3ApiExit(0, rc);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-#endif /* SQLITE_OMIT_COMPLETE */
-
-/************** End of complete.c ********************************************/
-/************** Begin file main.c ********************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** Main file for the SQLite library. The routines in this file
-** implement the programmer interface to the library. Routines in
-** other files are for internal use by SQLite and should not be
-** accessed by users of the library.
-*/
-
-#ifdef SQLITE_ENABLE_FTS3
-/************** Include fts3.h in the middle of main.c ***********************/
-/************** Begin file fts3.h ********************************************/
-/*
-** 2006 Oct 10
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This header file is used by programs that want to link against the
-** FTS3 library. All it does is declare the sqlite3Fts3Init() interface.
-*/
-
-#if 0
-extern "C" {
-#endif /* __cplusplus */
-
-SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db);
-
-#if 0
-} /* extern "C" */
-#endif /* __cplusplus */
-
-/************** End of fts3.h ************************************************/
-/************** Continuing where we left off in main.c ***********************/
-#endif
-#ifdef SQLITE_ENABLE_RTREE
-/************** Include rtree.h in the middle of main.c **********************/
-/************** Begin file rtree.h *******************************************/
-/*
-** 2008 May 26
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This header file is used by programs that want to link against the
-** RTREE library. All it does is declare the sqlite3RtreeInit() interface.
-*/
-
-#if 0
-extern "C" {
-#endif /* __cplusplus */
-
-SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db);
-
-#if 0
-} /* extern "C" */
-#endif /* __cplusplus */
-
-/************** End of rtree.h ***********************************************/
-/************** Continuing where we left off in main.c ***********************/
-#endif
-#ifdef SQLITE_ENABLE_ICU
-/************** Include sqliteicu.h in the middle of main.c ******************/
-/************** Begin file sqliteicu.h ***************************************/
-/*
-** 2008 May 26
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This header file is used by programs that want to link against the
-** ICU extension. All it does is declare the sqlite3IcuInit() interface.
-*/
-
-#if 0
-extern "C" {
-#endif /* __cplusplus */
-
-SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db);
-
-#if 0
-} /* extern "C" */
-#endif /* __cplusplus */
-
-
-/************** End of sqliteicu.h *******************************************/
-/************** Continuing where we left off in main.c ***********************/
-#endif
-
-#ifndef SQLITE_AMALGAMATION
-/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
-** contains the text of SQLITE_VERSION macro.
-*/
-SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
-#endif
-
-/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
-** a pointer to the to the sqlite3_version[] string constant.
-*/
-SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
-
-/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
-** pointer to a string constant whose value is the same as the
-** SQLITE_SOURCE_ID C preprocessor macro.
-*/
-SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
-
-/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
-** returns an integer equal to SQLITE_VERSION_NUMBER.
-*/
-SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
-
-/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns
-** zero if and only if SQLite was compiled with mutexing code omitted due to
-** the SQLITE_THREADSAFE compile-time option being set to 0.
-*/
-SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
-
-#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
-/*
-** If the following function pointer is not NULL and if
-** SQLITE_ENABLE_IOTRACE is enabled, then messages describing
-** I/O active are written using this function. These messages
-** are intended for debugging activity only.
-*/
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*, ...) = 0;
-#endif
-
-/*
-** If the following global variable points to a string which is the
-** name of a directory, then that directory will be used to store
-** temporary files.
-**
-** See also the "PRAGMA temp_store_directory" SQL command.
-*/
-SQLITE_API char *sqlite3_temp_directory = 0;
-
-/*
-** If the following global variable points to a string which is the
-** name of a directory, then that directory will be used to store
-** all database files specified with a relative pathname.
-**
-** See also the "PRAGMA data_store_directory" SQL command.
-*/
-SQLITE_API char *sqlite3_data_directory = 0;
-
-/*
-** Initialize SQLite.
-**
-** This routine must be called to initialize the memory allocation,
-** VFS, and mutex subsystems prior to doing any serious work with
-** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT
-** this routine will be called automatically by key routines such as
-** sqlite3_open().
-**
-** This routine is a no-op except on its very first call for the process,
-** or for the first call after a call to sqlite3_shutdown.
-**
-** The first thread to call this routine runs the initialization to
-** completion. If subsequent threads call this routine before the first
-** thread has finished the initialization process, then the subsequent
-** threads must block until the first thread finishes with the initialization.
-**
-** The first thread might call this routine recursively. Recursive
-** calls to this routine should not block, of course. Otherwise the
-** initialization process would never complete.
-**
-** Let X be the first thread to enter this routine. Let Y be some other
-** thread. Then while the initial invocation of this routine by X is
-** incomplete, it is required that:
-**
-** * Calls to this routine from Y must block until the outer-most
-** call by X completes.
-**
-** * Recursive calls to this routine from thread X return immediately
-** without blocking.
-*/
-SQLITE_API int sqlite3_initialize(void){
- MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
- int rc; /* Result code */
-
-#ifdef SQLITE_OMIT_WSD
- rc = sqlite3_wsd_init(4096, 24);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-#endif
-
- /* If SQLite is already completely initialized, then this call
- ** to sqlite3_initialize() should be a no-op. But the initialization
- ** must be complete. So isInit must not be set until the very end
- ** of this routine.
- */
- if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;
-
-#ifdef SQLITE_ENABLE_SQLLOG
- {
- extern void sqlite3_init_sqllog(void);
- sqlite3_init_sqllog();
- }
-#endif
-
- /* Make sure the mutex subsystem is initialized. If unable to
- ** initialize the mutex subsystem, return early with the error.
- ** If the system is so sick that we are unable to allocate a mutex,
- ** there is not much SQLite is going to be able to do.
- **
- ** The mutex subsystem must take care of serializing its own
- ** initialization.
- */
- rc = sqlite3MutexInit();
- if( rc ) return rc;
-
- /* Initialize the malloc() system and the recursive pInitMutex mutex.
- ** This operation is protected by the STATIC_MASTER mutex. Note that
- ** MutexAlloc() is called for a static mutex prior to initializing the
- ** malloc subsystem - this implies that the allocation of a static
- ** mutex must not require support from the malloc subsystem.
- */
- MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
- sqlite3_mutex_enter(pMaster);
- sqlite3GlobalConfig.isMutexInit = 1;
- if( !sqlite3GlobalConfig.isMallocInit ){
- rc = sqlite3MallocInit();
- }
- if( rc==SQLITE_OK ){
- sqlite3GlobalConfig.isMallocInit = 1;
- if( !sqlite3GlobalConfig.pInitMutex ){
- sqlite3GlobalConfig.pInitMutex =
- sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
- if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
- rc = SQLITE_NOMEM;
- }
- }
- }
- if( rc==SQLITE_OK ){
- sqlite3GlobalConfig.nRefInitMutex++;
- }
- sqlite3_mutex_leave(pMaster);
-
- /* If rc is not SQLITE_OK at this point, then either the malloc
- ** subsystem could not be initialized or the system failed to allocate
- ** the pInitMutex mutex. Return an error in either case. */
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* Do the rest of the initialization under the recursive mutex so
- ** that we will be able to handle recursive calls into
- ** sqlite3_initialize(). The recursive calls normally come through
- ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other
- ** recursive calls might also be possible.
- **
- ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls
- ** to the xInit method, so the xInit method need not be threadsafe.
- **
- ** The following mutex is what serializes access to the appdef pcache xInit
- ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the
- ** call to sqlite3PcacheInitialize().
- */
- sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
- if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- sqlite3GlobalConfig.inProgress = 1;
- memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
- sqlite3RegisterGlobalFunctions();
- if( sqlite3GlobalConfig.isPCacheInit==0 ){
- rc = sqlite3PcacheInitialize();
- }
- if( rc==SQLITE_OK ){
- sqlite3GlobalConfig.isPCacheInit = 1;
- rc = sqlite3OsInit();
- }
- if( rc==SQLITE_OK ){
- sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
- sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
- sqlite3GlobalConfig.isInit = 1;
- }
- sqlite3GlobalConfig.inProgress = 0;
- }
- sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex);
-
- /* Go back under the static mutex and clean up the recursive
- ** mutex to prevent a resource leak.
- */
- sqlite3_mutex_enter(pMaster);
- sqlite3GlobalConfig.nRefInitMutex--;
- if( sqlite3GlobalConfig.nRefInitMutex<=0 ){
- assert( sqlite3GlobalConfig.nRefInitMutex==0 );
- sqlite3_mutex_free(sqlite3GlobalConfig.pInitMutex);
- sqlite3GlobalConfig.pInitMutex = 0;
- }
- sqlite3_mutex_leave(pMaster);
-
- /* The following is just a sanity check to make sure SQLite has
- ** been compiled correctly. It is important to run this code, but
- ** we don't want to run it too often and soak up CPU cycles for no
- ** reason. So we run it once during initialization.
- */
-#ifndef NDEBUG
-#ifndef SQLITE_OMIT_FLOATING_POINT
- /* This section of code's only "output" is via assert() statements. */
- if ( rc==SQLITE_OK ){
- u64 x = (((u64)1)<<63)-1;
- double y;
- assert(sizeof(x)==8);
- assert(sizeof(x)==sizeof(y));
- memcpy(&y, &x, 8);
- assert( sqlite3IsNaN(y) );
- }
-#endif
-#endif
-
- /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT
- ** compile-time option.
- */
-#ifdef SQLITE_EXTRA_INIT
- if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){
- int SQLITE_EXTRA_INIT(const char*);
- rc = SQLITE_EXTRA_INIT(0);
- }
-#endif
-
- return rc;
-}
-
-/*
-** Undo the effects of sqlite3_initialize(). Must not be called while
-** there are outstanding database connections or memory allocations or
-** while any part of SQLite is otherwise in use in any thread. This
-** routine is not threadsafe. But it is safe to invoke this routine
-** on when SQLite is already shut down. If SQLite is already shut down
-** when this routine is invoked, then this routine is a harmless no-op.
-*/
-SQLITE_API int sqlite3_shutdown(void){
- if( sqlite3GlobalConfig.isInit ){
-#ifdef SQLITE_EXTRA_SHUTDOWN
- void SQLITE_EXTRA_SHUTDOWN(void);
- SQLITE_EXTRA_SHUTDOWN();
-#endif
- sqlite3_os_end();
- sqlite3_reset_auto_extension();
- sqlite3GlobalConfig.isInit = 0;
- }
- if( sqlite3GlobalConfig.isPCacheInit ){
- sqlite3PcacheShutdown();
- sqlite3GlobalConfig.isPCacheInit = 0;
- }
- if( sqlite3GlobalConfig.isMallocInit ){
- sqlite3MallocEnd();
- sqlite3GlobalConfig.isMallocInit = 0;
-
-#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES
- /* The heap subsystem has now been shutdown and these values are supposed
- ** to be NULL or point to memory that was obtained from sqlite3_malloc(),
- ** which would rely on that heap subsystem; therefore, make sure these
- ** values cannot refer to heap memory that was just invalidated when the
- ** heap subsystem was shutdown. This is only done if the current call to
- ** this function resulted in the heap subsystem actually being shutdown.
- */
- sqlite3_data_directory = 0;
- sqlite3_temp_directory = 0;
-#endif
- }
- if( sqlite3GlobalConfig.isMutexInit ){
- sqlite3MutexEnd();
- sqlite3GlobalConfig.isMutexInit = 0;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** This API allows applications to modify the global configuration of
-** the SQLite library at run-time.
-**
-** This routine should only be called when there are no outstanding
-** database connections or memory allocations. This routine is not
-** threadsafe. Failure to heed these warnings can lead to unpredictable
-** behavior.
-*/
-SQLITE_API int sqlite3_config(int op, ...){
- va_list ap;
- int rc = SQLITE_OK;
-
- /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while
- ** the SQLite library is in use. */
- if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT;
-
- va_start(ap, op);
- switch( op ){
-
- /* Mutex configuration options are only available in a threadsafe
- ** compile.
- */
-#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0
- case SQLITE_CONFIG_SINGLETHREAD: {
- /* Disable all mutexing */
- sqlite3GlobalConfig.bCoreMutex = 0;
- sqlite3GlobalConfig.bFullMutex = 0;
- break;
- }
- case SQLITE_CONFIG_MULTITHREAD: {
- /* Disable mutexing of database connections */
- /* Enable mutexing of core data structures */
- sqlite3GlobalConfig.bCoreMutex = 1;
- sqlite3GlobalConfig.bFullMutex = 0;
- break;
- }
- case SQLITE_CONFIG_SERIALIZED: {
- /* Enable all mutexing */
- sqlite3GlobalConfig.bCoreMutex = 1;
- sqlite3GlobalConfig.bFullMutex = 1;
- break;
- }
- case SQLITE_CONFIG_MUTEX: {
- /* Specify an alternative mutex implementation */
- sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*);
- break;
- }
- case SQLITE_CONFIG_GETMUTEX: {
- /* Retrieve the current mutex implementation */
- *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex;
- break;
- }
-#endif
-
-
- case SQLITE_CONFIG_MALLOC: {
- /* Specify an alternative malloc implementation */
- sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*);
- break;
- }
- case SQLITE_CONFIG_GETMALLOC: {
- /* Retrieve the current malloc() implementation */
- if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault();
- *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m;
- break;
- }
- case SQLITE_CONFIG_MEMSTATUS: {
- /* Enable or disable the malloc status collection */
- sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
- break;
- }
- case SQLITE_CONFIG_SCRATCH: {
- /* Designate a buffer for scratch memory space */
- sqlite3GlobalConfig.pScratch = va_arg(ap, void*);
- sqlite3GlobalConfig.szScratch = va_arg(ap, int);
- sqlite3GlobalConfig.nScratch = va_arg(ap, int);
- break;
- }
- case SQLITE_CONFIG_PAGECACHE: {
- /* Designate a buffer for page cache memory space */
- sqlite3GlobalConfig.pPage = va_arg(ap, void*);
- sqlite3GlobalConfig.szPage = va_arg(ap, int);
- sqlite3GlobalConfig.nPage = va_arg(ap, int);
- break;
- }
-
- case SQLITE_CONFIG_PCACHE: {
- /* no-op */
- break;
- }
- case SQLITE_CONFIG_GETPCACHE: {
- /* now an error */
- rc = SQLITE_ERROR;
- break;
- }
-
- case SQLITE_CONFIG_PCACHE2: {
- /* Specify an alternative page cache implementation */
- sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*);
- break;
- }
- case SQLITE_CONFIG_GETPCACHE2: {
- if( sqlite3GlobalConfig.pcache2.xInit==0 ){
- sqlite3PCacheSetDefault();
- }
- *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2;
- break;
- }
-
-#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
- case SQLITE_CONFIG_HEAP: {
- /* Designate a buffer for heap memory space */
- sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
- sqlite3GlobalConfig.nHeap = va_arg(ap, int);
- sqlite3GlobalConfig.mnReq = va_arg(ap, int);
-
- if( sqlite3GlobalConfig.mnReq<1 ){
- sqlite3GlobalConfig.mnReq = 1;
- }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){
- /* cap min request size at 2^12 */
- sqlite3GlobalConfig.mnReq = (1<<12);
- }
-
- if( sqlite3GlobalConfig.pHeap==0 ){
- /* If the heap pointer is NULL, then restore the malloc implementation
- ** back to NULL pointers too. This will cause the malloc to go
- ** back to its default implementation when sqlite3_initialize() is
- ** run.
- */
- memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
- }else{
- /* The heap pointer is not NULL, then install one of the
- ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor
- ** ENABLE_MEMSYS5 is defined, return an error.
- */
-#ifdef SQLITE_ENABLE_MEMSYS3
- sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
-#endif
-#ifdef SQLITE_ENABLE_MEMSYS5
- sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5();
-#endif
- }
- break;
- }
-#endif
-
- case SQLITE_CONFIG_LOOKASIDE: {
- sqlite3GlobalConfig.szLookaside = va_arg(ap, int);
- sqlite3GlobalConfig.nLookaside = va_arg(ap, int);
- break;
- }
-
- /* Record a pointer to the logger funcction and its first argument.
- ** The default is NULL. Logging is disabled if the function pointer is
- ** NULL.
- */
- case SQLITE_CONFIG_LOG: {
- /* MSVC is picky about pulling func ptrs from va lists.
- ** http://support.microsoft.com/kb/47961
- ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*));
- */
- typedef void(*LOGFUNC_t)(void*,int,const char*);
- sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t);
- sqlite3GlobalConfig.pLogArg = va_arg(ap, void*);
- break;
- }
-
- case SQLITE_CONFIG_URI: {
- sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
- break;
- }
-
- case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
- sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
- break;
- }
-
-#ifdef SQLITE_ENABLE_SQLLOG
- case SQLITE_CONFIG_SQLLOG: {
- typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
- sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
- sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
- break;
- }
-#endif
-
- default: {
- rc = SQLITE_ERROR;
- break;
- }
- }
- va_end(ap);
- return rc;
-}
-
-/*
-** Set up the lookaside buffers for a database connection.
-** Return SQLITE_OK on success.
-** If lookaside is already active, return SQLITE_BUSY.
-**
-** The sz parameter is the number of bytes in each lookaside slot.
-** The cnt parameter is the number of slots. If pStart is NULL the
-** space for the lookaside memory is obtained from sqlite3_malloc().
-** If pStart is not NULL then it is sz*cnt bytes of memory to use for
-** the lookaside memory.
-*/
-static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
- void *pStart;
- if( db->lookaside.nOut ){
- return SQLITE_BUSY;
- }
- /* Free any existing lookaside buffer for this handle before
- ** allocating a new one so we don't have to have space for
- ** both at the same time.
- */
- if( db->lookaside.bMalloced ){
- sqlite3_free(db->lookaside.pStart);
- }
- /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger
- ** than a pointer to be useful.
- */
- sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */
- if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
- if( cnt<0 ) cnt = 0;
- if( sz==0 || cnt==0 ){
- sz = 0;
- pStart = 0;
- }else if( pBuf==0 ){
- sqlite3BeginBenignMalloc();
- pStart = sqlite3Malloc( sz*cnt ); /* IMP: R-61949-35727 */
- sqlite3EndBenignMalloc();
- if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
- }else{
- pStart = pBuf;
- }
- db->lookaside.pStart = pStart;
- db->lookaside.pFree = 0;
- db->lookaside.sz = (u16)sz;
- if( pStart ){
- int i;
- LookasideSlot *p;
- assert( sz > (int)sizeof(LookasideSlot*) );
- p = (LookasideSlot*)pStart;
- for(i=cnt-1; i>=0; i--){
- p->pNext = db->lookaside.pFree;
- db->lookaside.pFree = p;
- p = (LookasideSlot*)&((u8*)p)[sz];
- }
- db->lookaside.pEnd = p;
- db->lookaside.bEnabled = 1;
- db->lookaside.bMalloced = pBuf==0 ?1:0;
- }else{
- db->lookaside.pEnd = 0;
- db->lookaside.bEnabled = 0;
- db->lookaside.bMalloced = 0;
- }
- return SQLITE_OK;
-}
-
-/*
-** Return the mutex associated with a database connection.
-*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
- return db->mutex;
-}
-
-/*
-** Free up as much memory as we can from the given database
-** connection.
-*/
-SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
- int i;
- sqlite3_mutex_enter(db->mutex);
- sqlite3BtreeEnterAll(db);
- for(i=0; i<db->nDb; i++){
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- Pager *pPager = sqlite3BtreePager(pBt);
- sqlite3PagerShrink(pPager);
- }
- }
- sqlite3BtreeLeaveAll(db);
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-/*
-** Configuration settings for an individual database connection
-*/
-SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
- va_list ap;
- int rc;
- va_start(ap, op);
- switch( op ){
- case SQLITE_DBCONFIG_LOOKASIDE: {
- void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
- int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
- int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */
- rc = setupLookaside(db, pBuf, sz, cnt);
- break;
- }
- default: {
- static const struct {
- int op; /* The opcode */
- u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */
- } aFlagOp[] = {
- { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
- { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
- };
- unsigned int i;
- rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
- for(i=0; i<ArraySize(aFlagOp); i++){
- if( aFlagOp[i].op==op ){
- int onoff = va_arg(ap, int);
- int *pRes = va_arg(ap, int*);
- int oldFlags = db->flags;
- if( onoff>0 ){
- db->flags |= aFlagOp[i].mask;
- }else if( onoff==0 ){
- db->flags &= ~aFlagOp[i].mask;
- }
- if( oldFlags!=db->flags ){
- sqlite3ExpirePreparedStatements(db);
- }
- if( pRes ){
- *pRes = (db->flags & aFlagOp[i].mask)!=0;
- }
- rc = SQLITE_OK;
- break;
- }
- }
- break;
- }
- }
- va_end(ap);
- return rc;
-}
-
-
-/*
-** Return true if the buffer z[0..n-1] contains all spaces.
-*/
-static int allSpaces(const char *z, int n){
- while( n>0 && z[n-1]==' ' ){ n--; }
- return n==0;
-}
-
-/*
-** This is the default collating function named "BINARY" which is always
-** available.
-**
-** If the padFlag argument is not NULL then space padding at the end
-** of strings is ignored. This implements the RTRIM collation.
-*/
-static int binCollFunc(
- void *padFlag,
- int nKey1, const void *pKey1,
- int nKey2, const void *pKey2
-){
- int rc, n;
- n = nKey1<nKey2 ? nKey1 : nKey2;
- rc = memcmp(pKey1, pKey2, n);
- if( rc==0 ){
- if( padFlag
- && allSpaces(((char*)pKey1)+n, nKey1-n)
- && allSpaces(((char*)pKey2)+n, nKey2-n)
- ){
- /* Leave rc unchanged at 0 */
- }else{
- rc = nKey1 - nKey2;
- }
- }
- return rc;
-}
-
-/*
-** Another built-in collating sequence: NOCASE.
-**
-** This collating sequence is intended to be used for "case independant
-** comparison". SQLite's knowledge of upper and lower case equivalents
-** extends only to the 26 characters used in the English language.
-**
-** At the moment there is only a UTF-8 implementation.
-*/
-static int nocaseCollatingFunc(
- void *NotUsed,
- int nKey1, const void *pKey1,
- int nKey2, const void *pKey2
-){
- int r = sqlite3StrNICmp(
- (const char *)pKey1, (const char *)pKey2, (nKey1<nKey2)?nKey1:nKey2);
- UNUSED_PARAMETER(NotUsed);
- if( 0==r ){
- r = nKey1-nKey2;
- }
- return r;
-}
-
-/*
-** Return the ROWID of the most recent insert
-*/
-SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
- return db->lastRowid;
-}
-
-/*
-** Return the number of changes in the most recent call to sqlite3_exec().
-*/
-SQLITE_API int sqlite3_changes(sqlite3 *db){
- return db->nChange;
-}
-
-/*
-** Return the number of changes since the database handle was opened.
-*/
-SQLITE_API int sqlite3_total_changes(sqlite3 *db){
- return db->nTotalChange;
-}
-
-/*
-** Close all open savepoints. This function only manipulates fields of the
-** database handle object, it does not close any savepoints that may be open
-** at the b-tree/pager level.
-*/
-SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){
- while( db->pSavepoint ){
- Savepoint *pTmp = db->pSavepoint;
- db->pSavepoint = pTmp->pNext;
- sqlite3DbFree(db, pTmp);
- }
- db->nSavepoint = 0;
- db->nStatement = 0;
- db->isTransactionSavepoint = 0;
-}
-
-/*
-** Invoke the destructor function associated with FuncDef p, if any. Except,
-** if this is not the last copy of the function, do not invoke it. Multiple
-** copies of a single function are created when create_function() is called
-** with SQLITE_ANY as the encoding.
-*/
-static void functionDestroy(sqlite3 *db, FuncDef *p){
- FuncDestructor *pDestructor = p->pDestructor;
- if( pDestructor ){
- pDestructor->nRef--;
- if( pDestructor->nRef==0 ){
- pDestructor->xDestroy(pDestructor->pUserData);
- sqlite3DbFree(db, pDestructor);
- }
- }
-}
-
-/*
-** Disconnect all sqlite3_vtab objects that belong to database connection
-** db. This is called when db is being closed.
-*/
-static void disconnectAllVtab(sqlite3 *db){
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- int i;
- sqlite3BtreeEnterAll(db);
- for(i=0; i<db->nDb; i++){
- Schema *pSchema = db->aDb[i].pSchema;
- if( db->aDb[i].pSchema ){
- HashElem *p;
- for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
- Table *pTab = (Table *)sqliteHashData(p);
- if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
- }
- }
- }
- sqlite3BtreeLeaveAll(db);
-#else
- UNUSED_PARAMETER(db);
-#endif
-}
-
-/*
-** Return TRUE if database connection db has unfinalized prepared
-** statements or unfinished sqlite3_backup objects.
-*/
-static int connectionIsBusy(sqlite3 *db){
- int j;
- assert( sqlite3_mutex_held(db->mutex) );
- if( db->pVdbe ) return 1;
- for(j=0; j<db->nDb; j++){
- Btree *pBt = db->aDb[j].pBt;
- if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1;
- }
- return 0;
-}
-
-/*
-** Close an existing SQLite database
-*/
-static int sqlite3Close(sqlite3 *db, int forceZombie){
- if( !db ){
- return SQLITE_OK;
- }
- if( !sqlite3SafetyCheckSickOrOk(db) ){
- return SQLITE_MISUSE_BKPT;
- }
- sqlite3_mutex_enter(db->mutex);
-
- /* Force xDisconnect calls on all virtual tables */
- disconnectAllVtab(db);
-
- /* If a transaction is open, the disconnectAllVtab() call above
- ** will not have called the xDisconnect() method on any virtual
- ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
- ** call will do so. We need to do this before the check for active
- ** SQL statements below, as the v-table implementation may be storing
- ** some prepared statements internally.
- */
- sqlite3VtabRollback(db);
-
- /* Legacy behavior (sqlite3_close() behavior) is to return
- ** SQLITE_BUSY if the connection can not be closed immediately.
- */
- if( !forceZombie && connectionIsBusy(db) ){
- sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
- "statements or unfinished backups");
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_BUSY;
- }
-
-#ifdef SQLITE_ENABLE_SQLLOG
- if( sqlite3GlobalConfig.xSqllog ){
- /* Closing the handle. Fourth parameter is passed the value 2. */
- sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2);
- }
-#endif
-
- /* Convert the connection into a zombie and then close it.
- */
- db->magic = SQLITE_MAGIC_ZOMBIE;
- sqlite3LeaveMutexAndCloseZombie(db);
- return SQLITE_OK;
-}
-
-/*
-** Two variations on the public interface for closing a database
-** connection. The sqlite3_close() version returns SQLITE_BUSY and
-** leaves the connection option if there are unfinalized prepared
-** statements or unfinished sqlite3_backups. The sqlite3_close_v2()
-** version forces the connection to become a zombie if there are
-** unclosed resources, and arranges for deallocation when the last
-** prepare statement or sqlite3_backup closes.
-*/
-SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
-SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
-
-
-/*
-** Close the mutex on database connection db.
-**
-** Furthermore, if database connection db is a zombie (meaning that there
-** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and
-** every sqlite3_stmt has now been finalized and every sqlite3_backup has
-** finished, then free all resources.
-*/
-SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
- HashElem *i; /* Hash table iterator */
- int j;
-
- /* If there are outstanding sqlite3_stmt or sqlite3_backup objects
- ** or if the connection has not yet been closed by sqlite3_close_v2(),
- ** then just leave the mutex and return.
- */
- if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){
- sqlite3_mutex_leave(db->mutex);
- return;
- }
-
- /* If we reach this point, it means that the database connection has
- ** closed all sqlite3_stmt and sqlite3_backup objects and has been
- ** pased to sqlite3_close (meaning that it is a zombie). Therefore,
- ** go ahead and free all resources.
- */
-
- /* Free any outstanding Savepoint structures. */
- sqlite3CloseSavepoints(db);
-
- /* Close all database connections */
- for(j=0; j<db->nDb; j++){
- struct Db *pDb = &db->aDb[j];
- if( pDb->pBt ){
- sqlite3BtreeClose(pDb->pBt);
- pDb->pBt = 0;
- if( j!=1 ){
- pDb->pSchema = 0;
- }
- }
- }
- /* Clear the TEMP schema separately and last */
- if( db->aDb[1].pSchema ){
- sqlite3SchemaClear(db->aDb[1].pSchema);
- }
- sqlite3VtabUnlockList(db);
-
- /* Free up the array of auxiliary databases */
- sqlite3CollapseDatabaseArray(db);
- assert( db->nDb<=2 );
- assert( db->aDb==db->aDbStatic );
-
- /* Tell the code in notify.c that the connection no longer holds any
- ** locks and does not require any further unlock-notify callbacks.
- */
- sqlite3ConnectionClosed(db);
-
- for(j=0; j<ArraySize(db->aFunc.a); j++){
- FuncDef *pNext, *pHash, *p;
- for(p=db->aFunc.a[j]; p; p=pHash){
- pHash = p->pHash;
- while( p ){
- functionDestroy(db, p);
- pNext = p->pNext;
- sqlite3DbFree(db, p);
- p = pNext;
- }
- }
- }
- for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
- CollSeq *pColl = (CollSeq *)sqliteHashData(i);
- /* Invoke any destructors registered for collation sequence user data. */
- for(j=0; j<3; j++){
- if( pColl[j].xDel ){
- pColl[j].xDel(pColl[j].pUser);
- }
- }
- sqlite3DbFree(db, pColl);
- }
- sqlite3HashClear(&db->aCollSeq);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
- Module *pMod = (Module *)sqliteHashData(i);
- if( pMod->xDestroy ){
- pMod->xDestroy(pMod->pAux);
- }
- sqlite3DbFree(db, pMod);
- }
- sqlite3HashClear(&db->aModule);
-#endif
-
- sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
- if( db->pErr ){
- sqlite3ValueFree(db->pErr);
- }
- sqlite3CloseExtensions(db);
-
- db->magic = SQLITE_MAGIC_ERROR;
-
- /* The temp-database schema is allocated differently from the other schema
- ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
- ** So it needs to be freed here. Todo: Why not roll the temp schema into
- ** the same sqliteMalloc() as the one that allocates the database
- ** structure?
- */
- sqlite3DbFree(db, db->aDb[1].pSchema);
- sqlite3_mutex_leave(db->mutex);
- db->magic = SQLITE_MAGIC_CLOSED;
- sqlite3_mutex_free(db->mutex);
- assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */
- if( db->lookaside.bMalloced ){
- sqlite3_free(db->lookaside.pStart);
- }
- sqlite3_free(db);
-}
-
-/*
-** Rollback all database files. If tripCode is not SQLITE_OK, then
-** any open cursors are invalidated ("tripped" - as in "tripping a circuit
-** breaker") and made to return tripCode if there are any further
-** attempts to use that cursor.
-*/
-SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
- int i;
- int inTrans = 0;
- assert( sqlite3_mutex_held(db->mutex) );
- sqlite3BeginBenignMalloc();
- for(i=0; i<db->nDb; i++){
- Btree *p = db->aDb[i].pBt;
- if( p ){
- if( sqlite3BtreeIsInTrans(p) ){
- inTrans = 1;
- }
- sqlite3BtreeRollback(p, tripCode);
- db->aDb[i].inTrans = 0;
- }
- }
- sqlite3VtabRollback(db);
- sqlite3EndBenignMalloc();
-
- if( db->flags&SQLITE_InternChanges ){
- sqlite3ExpirePreparedStatements(db);
- sqlite3ResetAllSchemasOfConnection(db);
- }
-
- /* Any deferred constraint violations have now been resolved. */
- db->nDeferredCons = 0;
-
- /* If one has been configured, invoke the rollback-hook callback */
- if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
- db->xRollbackCallback(db->pRollbackArg);
- }
-}
-
-/*
-** Return a static string that describes the kind of error specified in the
-** argument.
-*/
-SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){
- static const char* const aMsg[] = {
- /* SQLITE_OK */ "not an error",
- /* SQLITE_ERROR */ "SQL logic error or missing database",
- /* SQLITE_INTERNAL */ 0,
- /* SQLITE_PERM */ "access permission denied",
- /* SQLITE_ABORT */ "callback requested query abort",
- /* SQLITE_BUSY */ "database is locked",
- /* SQLITE_LOCKED */ "database table is locked",
- /* SQLITE_NOMEM */ "out of memory",
- /* SQLITE_READONLY */ "attempt to write a readonly database",
- /* SQLITE_INTERRUPT */ "interrupted",
- /* SQLITE_IOERR */ "disk I/O error",
- /* SQLITE_CORRUPT */ "database disk image is malformed",
- /* SQLITE_NOTFOUND */ "unknown operation",
- /* SQLITE_FULL */ "database or disk is full",
- /* SQLITE_CANTOPEN */ "unable to open database file",
- /* SQLITE_PROTOCOL */ "locking protocol",
- /* SQLITE_EMPTY */ "table contains no data",
- /* SQLITE_SCHEMA */ "database schema has changed",
- /* SQLITE_TOOBIG */ "string or blob too big",
- /* SQLITE_CONSTRAINT */ "constraint failed",
- /* SQLITE_MISMATCH */ "datatype mismatch",
- /* SQLITE_MISUSE */ "library routine called out of sequence",
- /* SQLITE_NOLFS */ "large file support is disabled",
- /* SQLITE_AUTH */ "authorization denied",
- /* SQLITE_FORMAT */ "auxiliary database format error",
- /* SQLITE_RANGE */ "bind or column index out of range",
- /* SQLITE_NOTADB */ "file is encrypted or is not a database",
- };
- const char *zErr = "unknown error";
- switch( rc ){
- case SQLITE_ABORT_ROLLBACK: {
- zErr = "abort due to ROLLBACK";
- break;
- }
- default: {
- rc &= 0xff;
- if( ALWAYS(rc>=0) && rc<ArraySize(aMsg) && aMsg[rc]!=0 ){
- zErr = aMsg[rc];
- }
- break;
- }
- }
- return zErr;
-}
-
-/*
-** This routine implements a busy callback that sleeps and tries
-** again until a timeout value is reached. The timeout value is
-** an integer number of milliseconds passed in as the first
-** argument.
-*/
-static int sqliteDefaultBusyCallback(
- void *ptr, /* Database connection */
- int count /* Number of times table has been busy */
-){
-#if SQLITE_OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP)
- static const u8 delays[] =
- { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
- static const u8 totals[] =
- { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 };
-# define NDELAY ArraySize(delays)
- sqlite3 *db = (sqlite3 *)ptr;
- int timeout = db->busyTimeout;
- int delay, prior;
-
- assert( count>=0 );
- if( count < NDELAY ){
- delay = delays[count];
- prior = totals[count];
- }else{
- delay = delays[NDELAY-1];
- prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
- }
- if( prior + delay > timeout ){
- delay = timeout - prior;
- if( delay<=0 ) return 0;
- }
- sqlite3OsSleep(db->pVfs, delay*1000);
- return 1;
-#else
- sqlite3 *db = (sqlite3 *)ptr;
- int timeout = ((sqlite3 *)ptr)->busyTimeout;
- if( (count+1)*1000 > timeout ){
- return 0;
- }
- sqlite3OsSleep(db->pVfs, 1000000);
- return 1;
-#endif
-}
-
-/*
-** Invoke the given busy handler.
-**
-** This routine is called when an operation failed with a lock.
-** If this routine returns non-zero, the lock is retried. If it
-** returns 0, the operation aborts with an SQLITE_BUSY error.
-*/
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
- int rc;
- if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0;
- rc = p->xFunc(p->pArg, p->nBusy);
- if( rc==0 ){
- p->nBusy = -1;
- }else{
- p->nBusy++;
- }
- return rc;
-}
-
-/*
-** This routine sets the busy callback for an Sqlite database to the
-** given callback function with the given argument.
-*/
-SQLITE_API int sqlite3_busy_handler(
- sqlite3 *db,
- int (*xBusy)(void*,int),
- void *pArg
-){
- sqlite3_mutex_enter(db->mutex);
- db->busyHandler.xFunc = xBusy;
- db->busyHandler.pArg = pArg;
- db->busyHandler.nBusy = 0;
- db->busyTimeout = 0;
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
-/*
-** This routine sets the progress callback for an Sqlite database to the
-** given callback function with the given argument. The progress callback will
-** be invoked every nOps opcodes.
-*/
-SQLITE_API void sqlite3_progress_handler(
- sqlite3 *db,
- int nOps,
- int (*xProgress)(void*),
- void *pArg
-){
- sqlite3_mutex_enter(db->mutex);
- if( nOps>0 ){
- db->xProgress = xProgress;
- db->nProgressOps = nOps;
- db->pProgressArg = pArg;
- }else{
- db->xProgress = 0;
- db->nProgressOps = 0;
- db->pProgressArg = 0;
- }
- sqlite3_mutex_leave(db->mutex);
-}
-#endif
-
-
-/*
-** This routine installs a default busy handler that waits for the
-** specified number of milliseconds before returning 0.
-*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
- if( ms>0 ){
- sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
- db->busyTimeout = ms;
- }else{
- sqlite3_busy_handler(db, 0, 0);
- }
- return SQLITE_OK;
-}
-
-/*
-** Cause any pending operation to stop at its earliest opportunity.
-*/
-SQLITE_API void sqlite3_interrupt(sqlite3 *db){
- db->u1.isInterrupted = 1;
-}
-
-
-/*
-** This function is exactly the same as sqlite3_create_function(), except
-** that it is designed to be called by internal code. The difference is
-** that if a malloc() fails in sqlite3_create_function(), an error code
-** is returned and the mallocFailed flag cleared.
-*/
-SQLITE_PRIVATE int sqlite3CreateFunc(
- sqlite3 *db,
- const char *zFunctionName,
- int nArg,
- int enc,
- void *pUserData,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
- void (*xStep)(sqlite3_context*,int,sqlite3_value **),
- void (*xFinal)(sqlite3_context*),
- FuncDestructor *pDestructor
-){
- FuncDef *p;
- int nName;
-
- assert( sqlite3_mutex_held(db->mutex) );
- if( zFunctionName==0 ||
- (xFunc && (xFinal || xStep)) ||
- (!xFunc && (xFinal && !xStep)) ||
- (!xFunc && (!xFinal && xStep)) ||
- (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
- (255<(nName = sqlite3Strlen30( zFunctionName))) ){
- return SQLITE_MISUSE_BKPT;
- }
-
-#ifndef SQLITE_OMIT_UTF16
- /* If SQLITE_UTF16 is specified as the encoding type, transform this
- ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
- ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
- **
- ** If SQLITE_ANY is specified, add three versions of the function
- ** to the hash table.
- */
- if( enc==SQLITE_UTF16 ){
- enc = SQLITE_UTF16NATIVE;
- }else if( enc==SQLITE_ANY ){
- int rc;
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
- pUserData, xFunc, xStep, xFinal, pDestructor);
- if( rc==SQLITE_OK ){
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
- pUserData, xFunc, xStep, xFinal, pDestructor);
- }
- if( rc!=SQLITE_OK ){
- return rc;
- }
- enc = SQLITE_UTF16BE;
- }
-#else
- enc = SQLITE_UTF8;
-#endif
-
- /* Check if an existing function is being overridden or deleted. If so,
- ** and there are active VMs, then return SQLITE_BUSY. If a function
- ** is being overridden/deleted but there are no active VMs, allow the
- ** operation to continue but invalidate all precompiled statements.
- */
- p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
- if( p && p->iPrefEnc==enc && p->nArg==nArg ){
- if( db->activeVdbeCnt ){
- sqlite3Error(db, SQLITE_BUSY,
- "unable to delete/modify user-function due to active statements");
- assert( !db->mallocFailed );
- return SQLITE_BUSY;
- }else{
- sqlite3ExpirePreparedStatements(db);
- }
- }
-
- p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
- assert(p || db->mallocFailed);
- if( !p ){
- return SQLITE_NOMEM;
- }
-
- /* If an older version of the function with a configured destructor is
- ** being replaced invoke the destructor function here. */
- functionDestroy(db, p);
-
- if( pDestructor ){
- pDestructor->nRef++;
- }
- p->pDestructor = pDestructor;
- p->flags = 0;
- p->xFunc = xFunc;
- p->xStep = xStep;
- p->xFinalize = xFinal;
- p->pUserData = pUserData;
- p->nArg = (u16)nArg;
- return SQLITE_OK;
-}
-
-/*
-** Create new user functions.
-*/
-SQLITE_API int sqlite3_create_function(
- sqlite3 *db,
- const char *zFunc,
- int nArg,
- int enc,
- void *p,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
- void (*xStep)(sqlite3_context*,int,sqlite3_value **),
- void (*xFinal)(sqlite3_context*)
-){
- return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xFunc, xStep,
- xFinal, 0);
-}
-
-SQLITE_API int sqlite3_create_function_v2(
- sqlite3 *db,
- const char *zFunc,
- int nArg,
- int enc,
- void *p,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
- void (*xStep)(sqlite3_context*,int,sqlite3_value **),
- void (*xFinal)(sqlite3_context*),
- void (*xDestroy)(void *)
-){
- int rc = SQLITE_ERROR;
- FuncDestructor *pArg = 0;
- sqlite3_mutex_enter(db->mutex);
- if( xDestroy ){
- pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
- if( !pArg ){
- xDestroy(p);
- goto out;
- }
- pArg->xDestroy = xDestroy;
- pArg->pUserData = p;
- }
- rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xFunc, xStep, xFinal, pArg);
- if( pArg && pArg->nRef==0 ){
- assert( rc!=SQLITE_OK );
- xDestroy(p);
- sqlite3DbFree(db, pArg);
- }
-
- out:
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_create_function16(
- sqlite3 *db,
- const void *zFunctionName,
- int nArg,
- int eTextRep,
- void *p,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-){
- int rc;
- char *zFunc8;
- sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
- rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal,0);
- sqlite3DbFree(db, zFunc8);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-#endif
-
-
-/*
-** Declare that a function has been overloaded by a virtual table.
-**
-** If the function already exists as a regular global function, then
-** this routine is a no-op. If the function does not exist, then create
-** a new one that always throws a run-time error.
-**
-** When virtual tables intend to provide an overloaded function, they
-** should call this routine to make sure the global function exists.
-** A global function must exist in order for name resolution to work
-** properly.
-*/
-SQLITE_API int sqlite3_overload_function(
- sqlite3 *db,
- const char *zName,
- int nArg
-){
- int nName = sqlite3Strlen30(zName);
- int rc = SQLITE_OK;
- sqlite3_mutex_enter(db->mutex);
- if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
- rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
- 0, sqlite3InvalidFunction, 0, 0, 0);
- }
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_TRACE
-/*
-** Register a trace function. The pArg from the previously registered trace
-** is returned.
-**
-** A NULL trace function means that no tracing is executes. A non-NULL
-** trace is a pointer to a function that is invoked at the start of each
-** SQL statement.
-*/
-SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
- void *pOld;
- sqlite3_mutex_enter(db->mutex);
- pOld = db->pTraceArg;
- db->xTrace = xTrace;
- db->pTraceArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pOld;
-}
-/*
-** Register a profile function. The pArg from the previously registered
-** profile function is returned.
-**
-** A NULL profile function means that no profiling is executes. A non-NULL
-** profile is a pointer to a function that is invoked at the conclusion of
-** each SQL statement that is run.
-*/
-SQLITE_API void *sqlite3_profile(
- sqlite3 *db,
- void (*xProfile)(void*,const char*,sqlite_uint64),
- void *pArg
-){
- void *pOld;
- sqlite3_mutex_enter(db->mutex);
- pOld = db->pProfileArg;
- db->xProfile = xProfile;
- db->pProfileArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pOld;
-}
-#endif /* SQLITE_OMIT_TRACE */
-
-/*
-** Register a function to be invoked when a transaction commits.
-** If the invoked function returns non-zero, then the commit becomes a
-** rollback.
-*/
-SQLITE_API void *sqlite3_commit_hook(
- sqlite3 *db, /* Attach the hook to this database */
- int (*xCallback)(void*), /* Function to invoke on each commit */
- void *pArg /* Argument to the function */
-){
- void *pOld;
- sqlite3_mutex_enter(db->mutex);
- pOld = db->pCommitArg;
- db->xCommitCallback = xCallback;
- db->pCommitArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pOld;
-}
-
-/*
-** Register a callback to be invoked each time a row is updated,
-** inserted or deleted using this database connection.
-*/
-SQLITE_API void *sqlite3_update_hook(
- sqlite3 *db, /* Attach the hook to this database */
- void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
- void *pArg /* Argument to the function */
-){
- void *pRet;
- sqlite3_mutex_enter(db->mutex);
- pRet = db->pUpdateArg;
- db->xUpdateCallback = xCallback;
- db->pUpdateArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pRet;
-}
-
-/*
-** Register a callback to be invoked each time a transaction is rolled
-** back by this database connection.
-*/
-SQLITE_API void *sqlite3_rollback_hook(
- sqlite3 *db, /* Attach the hook to this database */
- void (*xCallback)(void*), /* Callback function */
- void *pArg /* Argument to the function */
-){
- void *pRet;
- sqlite3_mutex_enter(db->mutex);
- pRet = db->pRollbackArg;
- db->xRollbackCallback = xCallback;
- db->pRollbackArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pRet;
-}
-
-#ifndef SQLITE_OMIT_WAL
-/*
-** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
-** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
-** is greater than sqlite3.pWalArg cast to an integer (the value configured by
-** wal_autocheckpoint()).
-*/
-SQLITE_PRIVATE int sqlite3WalDefaultHook(
- void *pClientData, /* Argument */
- sqlite3 *db, /* Connection */
- const char *zDb, /* Database */
- int nFrame /* Size of WAL */
-){
- if( nFrame>=SQLITE_PTR_TO_INT(pClientData) ){
- sqlite3BeginBenignMalloc();
- sqlite3_wal_checkpoint(db, zDb);
- sqlite3EndBenignMalloc();
- }
- return SQLITE_OK;
-}
-#endif /* SQLITE_OMIT_WAL */
-
-/*
-** Configure an sqlite3_wal_hook() callback to automatically checkpoint
-** a database after committing a transaction if there are nFrame or
-** more frames in the log file. Passing zero or a negative value as the
-** nFrame parameter disables automatic checkpoints entirely.
-**
-** The callback registered by this function replaces any existing callback
-** registered using sqlite3_wal_hook(). Likewise, registering a callback
-** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
-** configured by this function.
-*/
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
-#ifdef SQLITE_OMIT_WAL
- UNUSED_PARAMETER(db);
- UNUSED_PARAMETER(nFrame);
-#else
- if( nFrame>0 ){
- sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame));
- }else{
- sqlite3_wal_hook(db, 0, 0);
- }
-#endif
- return SQLITE_OK;
-}
-
-/*
-** Register a callback to be invoked each time a transaction is written
-** into the write-ahead-log by this database connection.
-*/
-SQLITE_API void *sqlite3_wal_hook(
- sqlite3 *db, /* Attach the hook to this db handle */
- int(*xCallback)(void *, sqlite3*, const char*, int),
- void *pArg /* First argument passed to xCallback() */
-){
-#ifndef SQLITE_OMIT_WAL
- void *pRet;
- sqlite3_mutex_enter(db->mutex);
- pRet = db->pWalArg;
- db->xWalCallback = xCallback;
- db->pWalArg = pArg;
- sqlite3_mutex_leave(db->mutex);
- return pRet;
-#else
- return 0;
-#endif
-}
-
-/*
-** Checkpoint database zDb.
-*/
-SQLITE_API int sqlite3_wal_checkpoint_v2(
- sqlite3 *db, /* Database handle */
- const char *zDb, /* Name of attached database (or NULL) */
- int eMode, /* SQLITE_CHECKPOINT_* value */
- int *pnLog, /* OUT: Size of WAL log in frames */
- int *pnCkpt /* OUT: Total number of frames checkpointed */
-){
-#ifdef SQLITE_OMIT_WAL
- return SQLITE_OK;
-#else
- int rc; /* Return code */
- int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */
-
- /* Initialize the output variables to -1 in case an error occurs. */
- if( pnLog ) *pnLog = -1;
- if( pnCkpt ) *pnCkpt = -1;
-
- assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE );
- assert( SQLITE_CHECKPOINT_FULL<SQLITE_CHECKPOINT_RESTART );
- assert( SQLITE_CHECKPOINT_PASSIVE+2==SQLITE_CHECKPOINT_RESTART );
- if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_RESTART ){
- return SQLITE_MISUSE;
- }
-
- sqlite3_mutex_enter(db->mutex);
- if( zDb && zDb[0] ){
- iDb = sqlite3FindDbName(db, zDb);
- }
- if( iDb<0 ){
- rc = SQLITE_ERROR;
- sqlite3Error(db, SQLITE_ERROR, "unknown database: %s", zDb);
- }else{
- rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
- sqlite3Error(db, rc, 0);
- }
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-#endif
-}
-
-
-/*
-** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points
-** to contains a zero-length string, all attached databases are
-** checkpointed.
-*/
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
- return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0);
-}
-
-#ifndef SQLITE_OMIT_WAL
-/*
-** Run a checkpoint on database iDb. This is a no-op if database iDb is
-** not currently open in WAL mode.
-**
-** If a transaction is open on the database being checkpointed, this
-** function returns SQLITE_LOCKED and a checkpoint is not attempted. If
-** an error occurs while running the checkpoint, an SQLite error code is
-** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK.
-**
-** The mutex on database handle db should be held by the caller. The mutex
-** associated with the specific b-tree being checkpointed is taken by
-** this function while the checkpoint is running.
-**
-** If iDb is passed SQLITE_MAX_ATTACHED, then all attached databases are
-** checkpointed. If an error is encountered it is returned immediately -
-** no attempt is made to checkpoint any remaining databases.
-**
-** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
-*/
-SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){
- int rc = SQLITE_OK; /* Return code */
- int i; /* Used to iterate through attached dbs */
- int bBusy = 0; /* True if SQLITE_BUSY has been encountered */
-
- assert( sqlite3_mutex_held(db->mutex) );
- assert( !pnLog || *pnLog==-1 );
- assert( !pnCkpt || *pnCkpt==-1 );
-
- for(i=0; i<db->nDb && rc==SQLITE_OK; i++){
- if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){
- rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt);
- pnLog = 0;
- pnCkpt = 0;
- if( rc==SQLITE_BUSY ){
- bBusy = 1;
- rc = SQLITE_OK;
- }
- }
- }
-
- return (rc==SQLITE_OK && bBusy) ? SQLITE_BUSY : rc;
-}
-#endif /* SQLITE_OMIT_WAL */
-
-/*
-** This function returns true if main-memory should be used instead of
-** a temporary file for transient pager files and statement journals.
-** The value returned depends on the value of db->temp_store (runtime
-** parameter) and the compile time value of SQLITE_TEMP_STORE. The
-** following table describes the relationship between these two values
-** and this functions return value.
-**
-** SQLITE_TEMP_STORE db->temp_store Location of temporary database
-** ----------------- -------------- ------------------------------
-** 0 any file (return 0)
-** 1 1 file (return 0)
-** 1 2 memory (return 1)
-** 1 0 file (return 0)
-** 2 1 file (return 0)
-** 2 2 memory (return 1)
-** 2 0 memory (return 1)
-** 3 any memory (return 1)
-*/
-SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
-#if SQLITE_TEMP_STORE==1
- return ( db->temp_store==2 );
-#endif
-#if SQLITE_TEMP_STORE==2
- return ( db->temp_store!=1 );
-#endif
-#if SQLITE_TEMP_STORE==3
- return 1;
-#endif
-#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
- return 0;
-#endif
-}
-
-/*
-** Return UTF-8 encoded English language explanation of the most recent
-** error.
-*/
-SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
- const char *z;
- if( !db ){
- return sqlite3ErrStr(SQLITE_NOMEM);
- }
- if( !sqlite3SafetyCheckSickOrOk(db) ){
- return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
- }
- sqlite3_mutex_enter(db->mutex);
- if( db->mallocFailed ){
- z = sqlite3ErrStr(SQLITE_NOMEM);
- }else{
- z = (char*)sqlite3_value_text(db->pErr);
- assert( !db->mallocFailed );
- if( z==0 ){
- z = sqlite3ErrStr(db->errCode);
- }
- }
- sqlite3_mutex_leave(db->mutex);
- return z;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Return UTF-16 encoded English language explanation of the most recent
-** error.
-*/
-SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
- static const u16 outOfMem[] = {
- 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
- };
- static const u16 misuse[] = {
- 'l', 'i', 'b', 'r', 'a', 'r', 'y', ' ',
- 'r', 'o', 'u', 't', 'i', 'n', 'e', ' ',
- 'c', 'a', 'l', 'l', 'e', 'd', ' ',
- 'o', 'u', 't', ' ',
- 'o', 'f', ' ',
- 's', 'e', 'q', 'u', 'e', 'n', 'c', 'e', 0
- };
-
- const void *z;
- if( !db ){
- return (void *)outOfMem;
- }
- if( !sqlite3SafetyCheckSickOrOk(db) ){
- return (void *)misuse;
- }
- sqlite3_mutex_enter(db->mutex);
- if( db->mallocFailed ){
- z = (void *)outOfMem;
- }else{
- z = sqlite3_value_text16(db->pErr);
- if( z==0 ){
- sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
- SQLITE_UTF8, SQLITE_STATIC);
- z = sqlite3_value_text16(db->pErr);
- }
- /* A malloc() may have failed within the call to sqlite3_value_text16()
- ** above. If this is the case, then the db->mallocFailed flag needs to
- ** be cleared before returning. Do this directly, instead of via
- ** sqlite3ApiExit(), to avoid setting the database handle error message.
- */
- db->mallocFailed = 0;
- }
- sqlite3_mutex_leave(db->mutex);
- return z;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Return the most recent error code generated by an SQLite routine. If NULL is
-** passed to this function, we assume a malloc() failed during sqlite3_open().
-*/
-SQLITE_API int sqlite3_errcode(sqlite3 *db){
- if( db && !sqlite3SafetyCheckSickOrOk(db) ){
- return SQLITE_MISUSE_BKPT;
- }
- if( !db || db->mallocFailed ){
- return SQLITE_NOMEM;
- }
- return db->errCode & db->errMask;
-}
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
- if( db && !sqlite3SafetyCheckSickOrOk(db) ){
- return SQLITE_MISUSE_BKPT;
- }
- if( !db || db->mallocFailed ){
- return SQLITE_NOMEM;
- }
- return db->errCode;
-}
-
-/*
-** Return a string that describes the kind of error specified in the
-** argument. For now, this simply calls the internal sqlite3ErrStr()
-** function.
-*/
-SQLITE_API const char *sqlite3_errstr(int rc){
- return sqlite3ErrStr(rc);
-}
-
-/*
-** Create a new collating function for database "db". The name is zName
-** and the encoding is enc.
-*/
-static int createCollation(
- sqlite3* db,
- const char *zName,
- u8 enc,
- void* pCtx,
- int(*xCompare)(void*,int,const void*,int,const void*),
- void(*xDel)(void*)
-){
- CollSeq *pColl;
- int enc2;
- int nName = sqlite3Strlen30(zName);
-
- assert( sqlite3_mutex_held(db->mutex) );
-
- /* If SQLITE_UTF16 is specified as the encoding type, transform this
- ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
- ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally.
- */
- enc2 = enc;
- testcase( enc2==SQLITE_UTF16 );
- testcase( enc2==SQLITE_UTF16_ALIGNED );
- if( enc2==SQLITE_UTF16 || enc2==SQLITE_UTF16_ALIGNED ){
- enc2 = SQLITE_UTF16NATIVE;
- }
- if( enc2<SQLITE_UTF8 || enc2>SQLITE_UTF16BE ){
- return SQLITE_MISUSE_BKPT;
- }
-
- /* Check if this call is removing or replacing an existing collation
- ** sequence. If so, and there are active VMs, return busy. If there
- ** are no active VMs, invalidate any pre-compiled statements.
- */
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
- if( pColl && pColl->xCmp ){
- if( db->activeVdbeCnt ){
- sqlite3Error(db, SQLITE_BUSY,
- "unable to delete/modify collation sequence due to active statements");
- return SQLITE_BUSY;
- }
- sqlite3ExpirePreparedStatements(db);
-
- /* If collation sequence pColl was created directly by a call to
- ** sqlite3_create_collation, and not generated by synthCollSeq(),
- ** then any copies made by synthCollSeq() need to be invalidated.
- ** Also, collation destructor - CollSeq.xDel() - function may need
- ** to be called.
- */
- if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){
- CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
- int j;
- for(j=0; j<3; j++){
- CollSeq *p = &aColl[j];
- if( p->enc==pColl->enc ){
- if( p->xDel ){
- p->xDel(p->pUser);
- }
- p->xCmp = 0;
- }
- }
- }
- }
-
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
- if( pColl==0 ) return SQLITE_NOMEM;
- pColl->xCmp = xCompare;
- pColl->pUser = pCtx;
- pColl->xDel = xDel;
- pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED));
- sqlite3Error(db, SQLITE_OK, 0);
- return SQLITE_OK;
-}
-
-
-/*
-** This array defines hard upper bounds on limit values. The
-** initializer must be kept in sync with the SQLITE_LIMIT_*
-** #defines in sqlite3.h.
-*/
-static const int aHardLimit[] = {
- SQLITE_MAX_LENGTH,
- SQLITE_MAX_SQL_LENGTH,
- SQLITE_MAX_COLUMN,
- SQLITE_MAX_EXPR_DEPTH,
- SQLITE_MAX_COMPOUND_SELECT,
- SQLITE_MAX_VDBE_OP,
- SQLITE_MAX_FUNCTION_ARG,
- SQLITE_MAX_ATTACHED,
- SQLITE_MAX_LIKE_PATTERN_LENGTH,
- SQLITE_MAX_VARIABLE_NUMBER,
- SQLITE_MAX_TRIGGER_DEPTH,
-};
-
-/*
-** Make sure the hard limits are set to reasonable values
-*/
-#if SQLITE_MAX_LENGTH<100
-# error SQLITE_MAX_LENGTH must be at least 100
-#endif
-#if SQLITE_MAX_SQL_LENGTH<100
-# error SQLITE_MAX_SQL_LENGTH must be at least 100
-#endif
-#if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH
-# error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH
-#endif
-#if SQLITE_MAX_COMPOUND_SELECT<2
-# error SQLITE_MAX_COMPOUND_SELECT must be at least 2
-#endif
-#if SQLITE_MAX_VDBE_OP<40
-# error SQLITE_MAX_VDBE_OP must be at least 40
-#endif
-#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
-# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
-#endif
-#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62
-# error SQLITE_MAX_ATTACHED must be between 0 and 62
-#endif
-#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
-# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
-#endif
-#if SQLITE_MAX_COLUMN>32767
-# error SQLITE_MAX_COLUMN must not exceed 32767
-#endif
-#if SQLITE_MAX_TRIGGER_DEPTH<1
-# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1
-#endif
-
-
-/*
-** Change the value of a limit. Report the old value.
-** If an invalid limit index is supplied, report -1.
-** Make no changes but still report the old value if the
-** new limit is negative.
-**
-** A new lower limit does not shrink existing constructs.
-** It merely prevents new constructs that exceed the limit
-** from forming.
-*/
-SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
- int oldLimit;
-
-
- /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
- ** there is a hard upper bound set at compile-time by a C preprocessor
- ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
- ** "_MAX_".)
- */
- assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
- assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH );
- assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN );
- assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH );
- assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT);
- assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
- assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
- assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
- assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
- SQLITE_MAX_LIKE_PATTERN_LENGTH );
- assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
- assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
- assert( SQLITE_LIMIT_TRIGGER_DEPTH==(SQLITE_N_LIMIT-1) );
-
-
- if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
- return -1;
- }
- oldLimit = db->aLimit[limitId];
- if( newLimit>=0 ){ /* IMP: R-52476-28732 */
- if( newLimit>aHardLimit[limitId] ){
- newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
- }
- db->aLimit[limitId] = newLimit;
- }
- return oldLimit; /* IMP: R-53341-35419 */
-}
-
-/*
-** This function is used to parse both URIs and non-URI filenames passed by the
-** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database
-** URIs specified as part of ATTACH statements.
-**
-** The first argument to this function is the name of the VFS to use (or
-** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx"
-** query parameter. The second argument contains the URI (or non-URI filename)
-** itself. When this function is called the *pFlags variable should contain
-** the default flags to open the database handle with. The value stored in
-** *pFlags may be updated before returning if the URI filename contains
-** "cache=xxx" or "mode=xxx" query parameters.
-**
-** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to
-** the VFS that should be used to open the database file. *pzFile is set to
-** point to a buffer containing the name of the file to open. It is the
-** responsibility of the caller to eventually call sqlite3_free() to release
-** this buffer.
-**
-** If an error occurs, then an SQLite error code is returned and *pzErrMsg
-** may be set to point to a buffer containing an English language error
-** message. It is the responsibility of the caller to eventually release
-** this buffer by calling sqlite3_free().
-*/
-SQLITE_PRIVATE int sqlite3ParseUri(
- const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */
- const char *zUri, /* Nul-terminated URI to parse */
- unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */
- sqlite3_vfs **ppVfs, /* OUT: VFS to use */
- char **pzFile, /* OUT: Filename component of URI */
- char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */
-){
- int rc = SQLITE_OK;
- unsigned int flags = *pFlags;
- const char *zVfs = zDefaultVfs;
- char *zFile;
- char c;
- int nUri = sqlite3Strlen30(zUri);
-
- assert( *pzErrMsg==0 );
-
- if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri)
- && nUri>=5 && memcmp(zUri, "file:", 5)==0
- ){
- char *zOpt;
- int eState; /* Parser state when parsing URI */
- int iIn; /* Input character index */
- int iOut = 0; /* Output character index */
- int nByte = nUri+2; /* Bytes of space to allocate */
-
- /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen
- ** method that there may be extra parameters following the file-name. */
- flags |= SQLITE_OPEN_URI;
-
- for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&');
- zFile = sqlite3_malloc(nByte);
- if( !zFile ) return SQLITE_NOMEM;
-
- /* Discard the scheme and authority segments of the URI. */
- if( zUri[5]=='/' && zUri[6]=='/' ){
- iIn = 7;
- while( zUri[iIn] && zUri[iIn]!='/' ) iIn++;
-
- if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){
- *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s",
- iIn-7, &zUri[7]);
- rc = SQLITE_ERROR;
- goto parse_uri_out;
- }
- }else{
- iIn = 5;
- }
-
- /* Copy the filename and any query parameters into the zFile buffer.
- ** Decode %HH escape codes along the way.
- **
- ** Within this loop, variable eState may be set to 0, 1 or 2, depending
- ** on the parsing context. As follows:
- **
- ** 0: Parsing file-name.
- ** 1: Parsing name section of a name=value query parameter.
- ** 2: Parsing value section of a name=value query parameter.
- */
- eState = 0;
- while( (c = zUri[iIn])!=0 && c!='#' ){
- iIn++;
- if( c=='%'
- && sqlite3Isxdigit(zUri[iIn])
- && sqlite3Isxdigit(zUri[iIn+1])
- ){
- int octet = (sqlite3HexToInt(zUri[iIn++]) << 4);
- octet += sqlite3HexToInt(zUri[iIn++]);
-
- assert( octet>=0 && octet<256 );
- if( octet==0 ){
- /* This branch is taken when "%00" appears within the URI. In this
- ** case we ignore all text in the remainder of the path, name or
- ** value currently being parsed. So ignore the current character
- ** and skip to the next "?", "=" or "&", as appropriate. */
- while( (c = zUri[iIn])!=0 && c!='#'
- && (eState!=0 || c!='?')
- && (eState!=1 || (c!='=' && c!='&'))
- && (eState!=2 || c!='&')
- ){
- iIn++;
- }
- continue;
- }
- c = octet;
- }else if( eState==1 && (c=='&' || c=='=') ){
- if( zFile[iOut-1]==0 ){
- /* An empty option name. Ignore this option altogether. */
- while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++;
- continue;
- }
- if( c=='&' ){
- zFile[iOut++] = '\0';
- }else{
- eState = 2;
- }
- c = 0;
- }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){
- c = 0;
- eState = 1;
- }
- zFile[iOut++] = c;
- }
- if( eState==1 ) zFile[iOut++] = '\0';
- zFile[iOut++] = '\0';
- zFile[iOut++] = '\0';
-
- /* Check if there were any options specified that should be interpreted
- ** here. Options that are interpreted here include "vfs" and those that
- ** correspond to flags that may be passed to the sqlite3_open_v2()
- ** method. */
- zOpt = &zFile[sqlite3Strlen30(zFile)+1];
- while( zOpt[0] ){
- int nOpt = sqlite3Strlen30(zOpt);
- char *zVal = &zOpt[nOpt+1];
- int nVal = sqlite3Strlen30(zVal);
-
- if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){
- zVfs = zVal;
- }else{
- struct OpenMode {
- const char *z;
- int mode;
- } *aMode = 0;
- char *zModeType = 0;
- int mask = 0;
- int limit = 0;
-
- if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){
- static struct OpenMode aCacheMode[] = {
- { "shared", SQLITE_OPEN_SHAREDCACHE },
- { "private", SQLITE_OPEN_PRIVATECACHE },
- { 0, 0 }
- };
-
- mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE;
- aMode = aCacheMode;
- limit = mask;
- zModeType = "cache";
- }
- if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){
- static struct OpenMode aOpenMode[] = {
- { "ro", SQLITE_OPEN_READONLY },
- { "rw", SQLITE_OPEN_READWRITE },
- { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE },
- { "memory", SQLITE_OPEN_MEMORY },
- { 0, 0 }
- };
-
- mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE
- | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY;
- aMode = aOpenMode;
- limit = mask & flags;
- zModeType = "access";
- }
-
- if( aMode ){
- int i;
- int mode = 0;
- for(i=0; aMode[i].z; i++){
- const char *z = aMode[i].z;
- if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){
- mode = aMode[i].mode;
- break;
- }
- }
- if( mode==0 ){
- *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal);
- rc = SQLITE_ERROR;
- goto parse_uri_out;
- }
- if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){
- *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s",
- zModeType, zVal);
- rc = SQLITE_PERM;
- goto parse_uri_out;
- }
- flags = (flags & ~mask) | mode;
- }
- }
-
- zOpt = &zVal[nVal+1];
- }
-
- }else{
- zFile = sqlite3_malloc(nUri+2);
- if( !zFile ) return SQLITE_NOMEM;
- memcpy(zFile, zUri, nUri);
- zFile[nUri] = '\0';
- zFile[nUri+1] = '\0';
- flags &= ~SQLITE_OPEN_URI;
- }
-
- *ppVfs = sqlite3_vfs_find(zVfs);
- if( *ppVfs==0 ){
- *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs);
- rc = SQLITE_ERROR;
- }
- parse_uri_out:
- if( rc!=SQLITE_OK ){
- sqlite3_free(zFile);
- zFile = 0;
- }
- *pFlags = flags;
- *pzFile = zFile;
- return rc;
-}
-
-
-/*
-** This routine does the work of opening a database on behalf of
-** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"
-** is UTF-8 encoded.
-*/
-static int openDatabase(
- const char *zFilename, /* Database filename UTF-8 encoded */
- sqlite3 **ppDb, /* OUT: Returned database handle */
- unsigned int flags, /* Operational flags */
- const char *zVfs /* Name of the VFS to use */
-){
- sqlite3 *db; /* Store allocated handle here */
- int rc; /* Return code */
- int isThreadsafe; /* True for threadsafe connections */
- char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
- char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
-
- *ppDb = 0;
-#ifndef SQLITE_OMIT_AUTOINIT
- rc = sqlite3_initialize();
- if( rc ) return rc;
-#endif
-
- /* Only allow sensible combinations of bits in the flags argument.
- ** Throw an error if any non-sense combination is used. If we
- ** do not block illegal combinations here, it could trigger
- ** assert() statements in deeper layers. Sensible combinations
- ** are:
- **
- ** 1: SQLITE_OPEN_READONLY
- ** 2: SQLITE_OPEN_READWRITE
- ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
- */
- assert( SQLITE_OPEN_READONLY == 0x01 );
- assert( SQLITE_OPEN_READWRITE == 0x02 );
- assert( SQLITE_OPEN_CREATE == 0x04 );
- testcase( (1<<(flags&7))==0x02 ); /* READONLY */
- testcase( (1<<(flags&7))==0x04 ); /* READWRITE */
- testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */
- if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE_BKPT;
-
- if( sqlite3GlobalConfig.bCoreMutex==0 ){
- isThreadsafe = 0;
- }else if( flags & SQLITE_OPEN_NOMUTEX ){
- isThreadsafe = 0;
- }else if( flags & SQLITE_OPEN_FULLMUTEX ){
- isThreadsafe = 1;
- }else{
- isThreadsafe = sqlite3GlobalConfig.bFullMutex;
- }
- if( flags & SQLITE_OPEN_PRIVATECACHE ){
- flags &= ~SQLITE_OPEN_SHAREDCACHE;
- }else if( sqlite3GlobalConfig.sharedCacheEnabled ){
- flags |= SQLITE_OPEN_SHAREDCACHE;
- }
-
- /* Remove harmful bits from the flags parameter
- **
- ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
- ** dealt with in the previous code block. Besides these, the only
- ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
- ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
- ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask
- ** off all other flags.
- */
- flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
- SQLITE_OPEN_EXCLUSIVE |
- SQLITE_OPEN_MAIN_DB |
- SQLITE_OPEN_TEMP_DB |
- SQLITE_OPEN_TRANSIENT_DB |
- SQLITE_OPEN_MAIN_JOURNAL |
- SQLITE_OPEN_TEMP_JOURNAL |
- SQLITE_OPEN_SUBJOURNAL |
- SQLITE_OPEN_MASTER_JOURNAL |
- SQLITE_OPEN_NOMUTEX |
- SQLITE_OPEN_FULLMUTEX |
- SQLITE_OPEN_WAL
- );
-
- /* Allocate the sqlite data structure */
- db = sqlite3MallocZero( sizeof(sqlite3) );
- if( db==0 ) goto opendb_out;
- if( isThreadsafe ){
- db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
- if( db->mutex==0 ){
- sqlite3_free(db);
- db = 0;
- goto opendb_out;
- }
- }
- sqlite3_mutex_enter(db->mutex);
- db->errMask = 0xff;
- db->nDb = 2;
- db->magic = SQLITE_MAGIC_BUSY;
- db->aDb = db->aDbStatic;
-
- assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
- memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
- db->autoCommit = 1;
- db->nextAutovac = -1;
- db->nextPagesize = 0;
- db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger
-#if SQLITE_DEFAULT_FILE_FORMAT<4
- | SQLITE_LegacyFileFmt
-#endif
-#ifdef SQLITE_ENABLE_LOAD_EXTENSION
- | SQLITE_LoadExtension
-#endif
-#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS
- | SQLITE_RecTriggers
-#endif
-#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
- | SQLITE_ForeignKeys
-#endif
- ;
- sqlite3HashInit(&db->aCollSeq);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- sqlite3HashInit(&db->aModule);
-#endif
-
- /* Add the default collation sequence BINARY. BINARY works for both UTF-8
- ** and UTF-16, so add a version for each to avoid any unnecessary
- ** conversions. The only error that can occur here is a malloc() failure.
- */
- createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0);
- createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0);
- createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0);
- createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
- if( db->mallocFailed ){
- goto opendb_out;
- }
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
- assert( db->pDfltColl!=0 );
-
- /* Also add a UTF-8 case-insensitive collation sequence. */
- createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
-
- /* Parse the filename/URI argument. */
- db->openFlags = flags;
- rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
- sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
- sqlite3_free(zErrMsg);
- goto opendb_out;
- }
-
- /* Open the backend database driver */
- rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0,
- flags | SQLITE_OPEN_MAIN_DB);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_IOERR_NOMEM ){
- rc = SQLITE_NOMEM;
- }
- sqlite3Error(db, rc, 0);
- goto opendb_out;
- }
- db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
- db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
-
-
- /* The default safety_level for the main database is 'full'; for the temp
- ** database it is 'NONE'. This matches the pager layer defaults.
- */
- db->aDb[0].zName = "main";
- db->aDb[0].safety_level = 3;
- db->aDb[1].zName = "temp";
- db->aDb[1].safety_level = 1;
-
- db->magic = SQLITE_MAGIC_OPEN;
- if( db->mallocFailed ){
- goto opendb_out;
- }
-
- /* Register all built-in functions, but do not attempt to read the
- ** database schema yet. This is delayed until the first time the database
- ** is accessed.
- */
- sqlite3Error(db, SQLITE_OK, 0);
- sqlite3RegisterBuiltinFunctions(db);
-
- /* Load automatic extensions - extensions that have been registered
- ** using the sqlite3_automatic_extension() API.
- */
- rc = sqlite3_errcode(db);
- if( rc==SQLITE_OK ){
- sqlite3AutoLoadExtensions(db);
- rc = sqlite3_errcode(db);
- if( rc!=SQLITE_OK ){
- goto opendb_out;
- }
- }
-
-#ifdef SQLITE_ENABLE_FTS1
- if( !db->mallocFailed ){
- extern int sqlite3Fts1Init(sqlite3*);
- rc = sqlite3Fts1Init(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_FTS2
- if( !db->mallocFailed && rc==SQLITE_OK ){
- extern int sqlite3Fts2Init(sqlite3*);
- rc = sqlite3Fts2Init(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_FTS3
- if( !db->mallocFailed && rc==SQLITE_OK ){
- rc = sqlite3Fts3Init(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_ICU
- if( !db->mallocFailed && rc==SQLITE_OK ){
- rc = sqlite3IcuInit(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_RTREE
- if( !db->mallocFailed && rc==SQLITE_OK){
- rc = sqlite3RtreeInit(db);
- }
-#endif
-
- sqlite3Error(db, rc, 0);
-
- /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
- ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
- ** mode. Doing nothing at all also makes NORMAL the default.
- */
-#ifdef SQLITE_DEFAULT_LOCKING_MODE
- db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;
- sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),
- SQLITE_DEFAULT_LOCKING_MODE);
-#endif
-
- /* Enable the lookaside-malloc subsystem */
- setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
- sqlite3GlobalConfig.nLookaside);
-
- sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT);
-
-opendb_out:
- sqlite3_free(zOpen);
- if( db ){
- assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
- sqlite3_mutex_leave(db->mutex);
- }
- rc = sqlite3_errcode(db);
- assert( db!=0 || rc==SQLITE_NOMEM );
- if( rc==SQLITE_NOMEM ){
- sqlite3_close(db);
- db = 0;
- }else if( rc!=SQLITE_OK ){
- db->magic = SQLITE_MAGIC_SICK;
- }
- *ppDb = db;
-#ifdef SQLITE_ENABLE_SQLLOG
- if( sqlite3GlobalConfig.xSqllog ){
- /* Opening a db handle. Fourth parameter is passed 0. */
- void *pArg = sqlite3GlobalConfig.pSqllogArg;
- sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
- }
-#endif
- return sqlite3ApiExit(0, rc);
-}
-
-/*
-** Open a new database handle.
-*/
-SQLITE_API int sqlite3_open(
- const char *zFilename,
- sqlite3 **ppDb
-){
- return openDatabase(zFilename, ppDb,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
-}
-SQLITE_API int sqlite3_open_v2(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb, /* OUT: SQLite db handle */
- int flags, /* Flags */
- const char *zVfs /* Name of VFS module to use */
-){
- return openDatabase(filename, ppDb, (unsigned int)flags, zVfs);
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Open a new database handle.
-*/
-SQLITE_API int sqlite3_open16(
- const void *zFilename,
- sqlite3 **ppDb
-){
- char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */
- sqlite3_value *pVal;
- int rc;
-
- assert( zFilename );
- assert( ppDb );
- *ppDb = 0;
-#ifndef SQLITE_OMIT_AUTOINIT
- rc = sqlite3_initialize();
- if( rc ) return rc;
-#endif
- pVal = sqlite3ValueNew(0);
- sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
- zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
- if( zFilename8 ){
- rc = openDatabase(zFilename8, ppDb,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
- assert( *ppDb || rc==SQLITE_NOMEM );
- if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
- ENC(*ppDb) = SQLITE_UTF16NATIVE;
- }
- }else{
- rc = SQLITE_NOMEM;
- }
- sqlite3ValueFree(pVal);
-
- return sqlite3ApiExit(0, rc);
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Register a new collation sequence with the database handle db.
-*/
-SQLITE_API int sqlite3_create_collation(
- sqlite3* db,
- const char *zName,
- int enc,
- void* pCtx,
- int(*xCompare)(void*,int,const void*,int,const void*)
-){
- int rc;
- sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, 0);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Register a new collation sequence with the database handle db.
-*/
-SQLITE_API int sqlite3_create_collation_v2(
- sqlite3* db,
- const char *zName,
- int enc,
- void* pCtx,
- int(*xCompare)(void*,int,const void*,int,const void*),
- void(*xDel)(void*)
-){
- int rc;
- sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Register a new collation sequence with the database handle db.
-*/
-SQLITE_API int sqlite3_create_collation16(
- sqlite3* db,
- const void *zName,
- int enc,
- void* pCtx,
- int(*xCompare)(void*,int,const void*,int,const void*)
-){
- int rc = SQLITE_OK;
- char *zName8;
- sqlite3_mutex_enter(db->mutex);
- assert( !db->mallocFailed );
- zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE);
- if( zName8 ){
- rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0);
- sqlite3DbFree(db, zName8);
- }
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-/*
-** Register a collation sequence factory callback with the database handle
-** db. Replace any previously installed collation sequence factory.
-*/
-SQLITE_API int sqlite3_collation_needed(
- sqlite3 *db,
- void *pCollNeededArg,
- void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
-){
- sqlite3_mutex_enter(db->mutex);
- db->xCollNeeded = xCollNeeded;
- db->xCollNeeded16 = 0;
- db->pCollNeededArg = pCollNeededArg;
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-#ifndef SQLITE_OMIT_UTF16
-/*
-** Register a collation sequence factory callback with the database handle
-** db. Replace any previously installed collation sequence factory.
-*/
-SQLITE_API int sqlite3_collation_needed16(
- sqlite3 *db,
- void *pCollNeededArg,
- void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
-){
- sqlite3_mutex_enter(db->mutex);
- db->xCollNeeded = 0;
- db->xCollNeeded16 = xCollNeeded16;
- db->pCollNeededArg = pCollNeededArg;
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-#endif /* SQLITE_OMIT_UTF16 */
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** This function is now an anachronism. It used to be used to recover from a
-** malloc() failure, but SQLite now does this automatically.
-*/
-SQLITE_API int sqlite3_global_recover(void){
- return SQLITE_OK;
-}
-#endif
-
-/*
-** Test to see whether or not the database connection is in autocommit
-** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
-** by default. Autocommit is disabled by a BEGIN statement and reenabled
-** by the next COMMIT or ROLLBACK.
-**
-******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
-*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
- return db->autoCommit;
-}
-
-/*
-** The following routines are subtitutes for constants SQLITE_CORRUPT,
-** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
-** constants. They server two purposes:
-**
-** 1. Serve as a convenient place to set a breakpoint in a debugger
-** to detect when version error conditions occurs.
-**
-** 2. Invoke sqlite3_log() to provide the source code location where
-** a low-level error is first detected.
-*/
-SQLITE_PRIVATE int sqlite3CorruptError(int lineno){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_CORRUPT,
- "database corruption at line %d of [%.10s]",
- lineno, 20+sqlite3_sourceid());
- return SQLITE_CORRUPT;
-}
-SQLITE_PRIVATE int sqlite3MisuseError(int lineno){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_MISUSE,
- "misuse at line %d of [%.10s]",
- lineno, 20+sqlite3_sourceid());
- return SQLITE_MISUSE;
-}
-SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_CANTOPEN,
- "cannot open file at line %d of [%.10s]",
- lineno, 20+sqlite3_sourceid());
- return SQLITE_CANTOPEN;
-}
-
-
-#ifndef SQLITE_OMIT_DEPRECATED
-/*
-** This is a convenience routine that makes sure that all thread-specific
-** data for this thread has been deallocated.
-**
-** SQLite no longer uses thread-specific data so this routine is now a
-** no-op. It is retained for historical compatibility.
-*/
-SQLITE_API void sqlite3_thread_cleanup(void){
-}
-#endif
-
-/*
-** Return meta information about a specific column of a database table.
-** See comment in sqlite3.h (sqlite.h.in) for details.
-*/
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
-SQLITE_API int sqlite3_table_column_metadata(
- sqlite3 *db, /* Connection handle */
- const char *zDbName, /* Database name or NULL */
- const char *zTableName, /* Table name */
- const char *zColumnName, /* Column name */
- char const **pzDataType, /* OUTPUT: Declared data type */
- char const **pzCollSeq, /* OUTPUT: Collation sequence name */
- int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
- int *pPrimaryKey, /* OUTPUT: True if column part of PK */
- int *pAutoinc /* OUTPUT: True if column is auto-increment */
-){
- int rc;
- char *zErrMsg = 0;
- Table *pTab = 0;
- Column *pCol = 0;
- int iCol;
-
- char const *zDataType = 0;
- char const *zCollSeq = 0;
- int notnull = 0;
- int primarykey = 0;
- int autoinc = 0;
-
- /* Ensure the database schema has been loaded */
- sqlite3_mutex_enter(db->mutex);
- sqlite3BtreeEnterAll(db);
- rc = sqlite3Init(db, &zErrMsg);
- if( SQLITE_OK!=rc ){
- goto error_out;
- }
-
- /* Locate the table in question */
- pTab = sqlite3FindTable(db, zTableName, zDbName);
- if( !pTab || pTab->pSelect ){
- pTab = 0;
- goto error_out;
- }
-
- /* Find the column for which info is requested */
- if( sqlite3IsRowid(zColumnName) ){
- iCol = pTab->iPKey;
- if( iCol>=0 ){
- pCol = &pTab->aCol[iCol];
- }
- }else{
- for(iCol=0; iCol<pTab->nCol; iCol++){
- pCol = &pTab->aCol[iCol];
- if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
- break;
- }
- }
- if( iCol==pTab->nCol ){
- pTab = 0;
- goto error_out;
- }
- }
-
- /* The following block stores the meta information that will be returned
- ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey
- ** and autoinc. At this point there are two possibilities:
- **
- ** 1. The specified column name was rowid", "oid" or "_rowid_"
- ** and there is no explicitly declared IPK column.
- **
- ** 2. The table is not a view and the column name identified an
- ** explicitly declared column. Copy meta information from *pCol.
- */
- if( pCol ){
- zDataType = pCol->zType;
- zCollSeq = pCol->zColl;
- notnull = pCol->notNull!=0;
- primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
- autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0;
- }else{
- zDataType = "INTEGER";
- primarykey = 1;
- }
- if( !zCollSeq ){
- zCollSeq = "BINARY";
- }
-
-error_out:
- sqlite3BtreeLeaveAll(db);
-
- /* Whether the function call succeeded or failed, set the output parameters
- ** to whatever their local counterparts contain. If an error did occur,
- ** this has the effect of zeroing all output parameters.
- */
- if( pzDataType ) *pzDataType = zDataType;
- if( pzCollSeq ) *pzCollSeq = zCollSeq;
- if( pNotNull ) *pNotNull = notnull;
- if( pPrimaryKey ) *pPrimaryKey = primarykey;
- if( pAutoinc ) *pAutoinc = autoinc;
-
- if( SQLITE_OK==rc && !pTab ){
- sqlite3DbFree(db, zErrMsg);
- zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName,
- zColumnName);
- rc = SQLITE_ERROR;
- }
- sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
- sqlite3DbFree(db, zErrMsg);
- rc = sqlite3ApiExit(db, rc);
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-#endif
-
-/*
-** Sleep for a little while. Return the amount of time slept.
-*/
-SQLITE_API int sqlite3_sleep(int ms){
- sqlite3_vfs *pVfs;
- int rc;
- pVfs = sqlite3_vfs_find(0);
- if( pVfs==0 ) return 0;
-
- /* This function works in milliseconds, but the underlying OsSleep()
- ** API uses microseconds. Hence the 1000's.
- */
- rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000);
- return rc;
-}
-
-/*
-** Enable or disable the extended result codes.
-*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
- sqlite3_mutex_enter(db->mutex);
- db->errMask = onoff ? 0xffffffff : 0xff;
- sqlite3_mutex_leave(db->mutex);
- return SQLITE_OK;
-}
-
-/*
-** Invoke the xFileControl method on a particular database.
-*/
-SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
- int rc = SQLITE_ERROR;
- Btree *pBtree;
-
- sqlite3_mutex_enter(db->mutex);
- pBtree = sqlite3DbNameToBtree(db, zDbName);
- if( pBtree ){
- Pager *pPager;
- sqlite3_file *fd;
- sqlite3BtreeEnter(pBtree);
- pPager = sqlite3BtreePager(pBtree);
- assert( pPager!=0 );
- fd = sqlite3PagerFile(pPager);
- assert( fd!=0 );
- if( op==SQLITE_FCNTL_FILE_POINTER ){
- *(sqlite3_file**)pArg = fd;
- rc = SQLITE_OK;
- }else if( fd->pMethods ){
- rc = sqlite3OsFileControl(fd, op, pArg);
- }else{
- rc = SQLITE_NOTFOUND;
- }
- sqlite3BtreeLeave(pBtree);
- }
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** Interface to the testing logic.
-*/
-SQLITE_API int sqlite3_test_control(int op, ...){
- int rc = 0;
-#ifndef SQLITE_OMIT_BUILTIN_TEST
- va_list ap;
- va_start(ap, op);
- switch( op ){
-
- /*
- ** Save the current state of the PRNG.
- */
- case SQLITE_TESTCTRL_PRNG_SAVE: {
- sqlite3PrngSaveState();
- break;
- }
-
- /*
- ** Restore the state of the PRNG to the last state saved using
- ** PRNG_SAVE. If PRNG_SAVE has never before been called, then
- ** this verb acts like PRNG_RESET.
- */
- case SQLITE_TESTCTRL_PRNG_RESTORE: {
- sqlite3PrngRestoreState();
- break;
- }
-
- /*
- ** Reset the PRNG back to its uninitialized state. The next call
- ** to sqlite3_randomness() will reseed the PRNG using a single call
- ** to the xRandomness method of the default VFS.
- */
- case SQLITE_TESTCTRL_PRNG_RESET: {
- sqlite3PrngResetState();
- break;
- }
-
- /*
- ** sqlite3_test_control(BITVEC_TEST, size, program)
- **
- ** Run a test against a Bitvec object of size. The program argument
- ** is an array of integers that defines the test. Return -1 on a
- ** memory allocation error, 0 on success, or non-zero for an error.
- ** See the sqlite3BitvecBuiltinTest() for additional information.
- */
- case SQLITE_TESTCTRL_BITVEC_TEST: {
- int sz = va_arg(ap, int);
- int *aProg = va_arg(ap, int*);
- rc = sqlite3BitvecBuiltinTest(sz, aProg);
- break;
- }
-
- /*
- ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd)
- **
- ** Register hooks to call to indicate which malloc() failures
- ** are benign.
- */
- case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: {
- typedef void (*void_function)(void);
- void_function xBenignBegin;
- void_function xBenignEnd;
- xBenignBegin = va_arg(ap, void_function);
- xBenignEnd = va_arg(ap, void_function);
- sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd);
- break;
- }
-
- /*
- ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X)
- **
- ** Set the PENDING byte to the value in the argument, if X>0.
- ** Make no changes if X==0. Return the value of the pending byte
- ** as it existing before this routine was called.
- **
- ** IMPORTANT: Changing the PENDING byte from 0x40000000 results in
- ** an incompatible database file format. Changing the PENDING byte
- ** while any database connection is open results in undefined and
- ** dileterious behavior.
- */
- case SQLITE_TESTCTRL_PENDING_BYTE: {
- rc = PENDING_BYTE;
-#ifndef SQLITE_OMIT_WSD
- {
- unsigned int newVal = va_arg(ap, unsigned int);
- if( newVal ) sqlite3PendingByte = newVal;
- }
-#endif
- break;
- }
-
- /*
- ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X)
- **
- ** This action provides a run-time test to see whether or not
- ** assert() was enabled at compile-time. If X is true and assert()
- ** is enabled, then the return value is true. If X is true and
- ** assert() is disabled, then the return value is zero. If X is
- ** false and assert() is enabled, then the assertion fires and the
- ** process aborts. If X is false and assert() is disabled, then the
- ** return value is zero.
- */
- case SQLITE_TESTCTRL_ASSERT: {
- volatile int x = 0;
- assert( (x = va_arg(ap,int))!=0 );
- rc = x;
- break;
- }
-
-
- /*
- ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X)
- **
- ** This action provides a run-time test to see how the ALWAYS and
- ** NEVER macros were defined at compile-time.
- **
- ** The return value is ALWAYS(X).
- **
- ** The recommended test is X==2. If the return value is 2, that means
- ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the
- ** default setting. If the return value is 1, then ALWAYS() is either
- ** hard-coded to true or else it asserts if its argument is false.
- ** The first behavior (hard-coded to true) is the case if
- ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second
- ** behavior (assert if the argument to ALWAYS() is false) is the case if
- ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled.
- **
- ** The run-time test procedure might look something like this:
- **
- ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){
- ** // ALWAYS() and NEVER() are no-op pass-through macros
- ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){
- ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false.
- ** }else{
- ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0.
- ** }
- */
- case SQLITE_TESTCTRL_ALWAYS: {
- int x = va_arg(ap,int);
- rc = ALWAYS(x);
- break;
- }
-
- /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N)
- **
- ** Set the nReserve size to N for the main database on the database
- ** connection db.
- */
- case SQLITE_TESTCTRL_RESERVE: {
- sqlite3 *db = va_arg(ap, sqlite3*);
- int x = va_arg(ap,int);
- sqlite3_mutex_enter(db->mutex);
- sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0);
- sqlite3_mutex_leave(db->mutex);
- break;
- }
-
- /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N)
- **
- ** Enable or disable various optimizations for testing purposes. The
- ** argument N is a bitmask of optimizations to be disabled. For normal
- ** operation N should be 0. The idea is that a test program (like the
- ** SQL Logic Test or SLT test module) can run the same SQL multiple times
- ** with various optimizations disabled to verify that the same answer
- ** is obtained in every case.
- */
- case SQLITE_TESTCTRL_OPTIMIZATIONS: {
- sqlite3 *db = va_arg(ap, sqlite3*);
- db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff);
- break;
- }
-
-#ifdef SQLITE_N_KEYWORD
- /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
- **
- ** If zWord is a keyword recognized by the parser, then return the
- ** number of keywords. Or if zWord is not a keyword, return 0.
- **
- ** This test feature is only available in the amalgamation since
- ** the SQLITE_N_KEYWORD macro is not defined in this file if SQLite
- ** is built using separate source files.
- */
- case SQLITE_TESTCTRL_ISKEYWORD: {
- const char *zWord = va_arg(ap, const char*);
- int n = sqlite3Strlen30(zWord);
- rc = (sqlite3KeywordCode((u8*)zWord, n)!=TK_ID) ? SQLITE_N_KEYWORD : 0;
- break;
- }
-#endif
-
- /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree);
- **
- ** Pass pFree into sqlite3ScratchFree().
- ** If sz>0 then allocate a scratch buffer into pNew.
- */
- case SQLITE_TESTCTRL_SCRATCHMALLOC: {
- void *pFree, **ppNew;
- int sz;
- sz = va_arg(ap, int);
- ppNew = va_arg(ap, void**);
- pFree = va_arg(ap, void*);
- if( sz ) *ppNew = sqlite3ScratchMalloc(sz);
- sqlite3ScratchFree(pFree);
- break;
- }
-
- /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
- **
- ** If parameter onoff is non-zero, configure the wrappers so that all
- ** subsequent calls to localtime() and variants fail. If onoff is zero,
- ** undo this setting.
- */
- case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
- sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
- break;
- }
-
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
- /* sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT,
- ** sqlite3_stmt*,const char**);
- **
- ** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite3_stmt holds
- ** a string that describes the optimized parse tree. This test-control
- ** returns a pointer to that string.
- */
- case SQLITE_TESTCTRL_EXPLAIN_STMT: {
- sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*);
- const char **pzRet = va_arg(ap, const char**);
- *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt);
- break;
- }
-#endif
-
- }
- va_end(ap);
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
- return rc;
-}
-
-/*
-** This is a utility routine, useful to VFS implementations, that checks
-** to see if a database file was a URI that contained a specific query
-** parameter, and if so obtains the value of the query parameter.
-**
-** The zFilename argument is the filename pointer passed into the xOpen()
-** method of a VFS implementation. The zParam argument is the name of the
-** query parameter we seek. This routine returns the value of the zParam
-** parameter if it exists. If the parameter does not exist, this routine
-** returns a NULL pointer.
-*/
-SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
- if( zFilename==0 ) return 0;
- zFilename += sqlite3Strlen30(zFilename) + 1;
- while( zFilename[0] ){
- int x = strcmp(zFilename, zParam);
- zFilename += sqlite3Strlen30(zFilename) + 1;
- if( x==0 ) return zFilename;
- zFilename += sqlite3Strlen30(zFilename) + 1;
- }
- return 0;
-}
-
-/*
-** Return a boolean value for a query parameter.
-*/
-SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
- const char *z = sqlite3_uri_parameter(zFilename, zParam);
- bDflt = bDflt!=0;
- return z ? sqlite3GetBoolean(z, bDflt) : bDflt;
-}
-
-/*
-** Return a 64-bit integer value for a query parameter.
-*/
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(
- const char *zFilename, /* Filename as passed to xOpen */
- const char *zParam, /* URI parameter sought */
- sqlite3_int64 bDflt /* return if parameter is missing */
-){
- const char *z = sqlite3_uri_parameter(zFilename, zParam);
- sqlite3_int64 v;
- if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){
- bDflt = v;
- }
- return bDflt;
-}
-
-/*
-** Return the Btree pointer identified by zDbName. Return NULL if not found.
-*/
-SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
- int i;
- for(i=0; i<db->nDb; i++){
- if( db->aDb[i].pBt
- && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zName)==0)
- ){
- return db->aDb[i].pBt;
- }
- }
- return 0;
-}
-
-/*
-** Return the filename of the database associated with a database
-** connection.
-*/
-SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
- Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
- return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
-}
-
-/*
-** Return 1 if database is read-only or 0 if read/write. Return -1 if
-** no such database exists.
-*/
-SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
- Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
- return pBt ? sqlite3PagerIsreadonly(sqlite3BtreePager(pBt)) : -1;
-}
-
-/************** End of main.c ************************************************/
-/************** Begin file notify.c ******************************************/
-/*
-** 2009 March 3
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains the implementation of the sqlite3_unlock_notify()
-** API method and its associated functionality.
-*/
-
-/* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
-
-/*
-** Public interfaces:
-**
-** sqlite3ConnectionBlocked()
-** sqlite3ConnectionUnlocked()
-** sqlite3ConnectionClosed()
-** sqlite3_unlock_notify()
-*/
-
-#define assertMutexHeld() \
- assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) )
-
-/*
-** Head of a linked list of all sqlite3 objects created by this process
-** for which either sqlite3.pBlockingConnection or sqlite3.pUnlockConnection
-** is not NULL. This variable may only accessed while the STATIC_MASTER
-** mutex is held.
-*/
-static sqlite3 *SQLITE_WSD sqlite3BlockedList = 0;
-
-#ifndef NDEBUG
-/*
-** This function is a complex assert() that verifies the following
-** properties of the blocked connections list:
-**
-** 1) Each entry in the list has a non-NULL value for either
-** pUnlockConnection or pBlockingConnection, or both.
-**
-** 2) All entries in the list that share a common value for
-** xUnlockNotify are grouped together.
-**
-** 3) If the argument db is not NULL, then none of the entries in the
-** blocked connections list have pUnlockConnection or pBlockingConnection
-** set to db. This is used when closing connection db.
-*/
-static void checkListProperties(sqlite3 *db){
- sqlite3 *p;
- for(p=sqlite3BlockedList; p; p=p->pNextBlocked){
- int seen = 0;
- sqlite3 *p2;
-
- /* Verify property (1) */
- assert( p->pUnlockConnection || p->pBlockingConnection );
-
- /* Verify property (2) */
- for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){
- if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1;
- assert( p2->xUnlockNotify==p->xUnlockNotify || !seen );
- assert( db==0 || p->pUnlockConnection!=db );
- assert( db==0 || p->pBlockingConnection!=db );
- }
- }
-}
-#else
-# define checkListProperties(x)
-#endif
-
-/*
-** Remove connection db from the blocked connections list. If connection
-** db is not currently a part of the list, this function is a no-op.
-*/
-static void removeFromBlockedList(sqlite3 *db){
- sqlite3 **pp;
- assertMutexHeld();
- for(pp=&sqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){
- if( *pp==db ){
- *pp = (*pp)->pNextBlocked;
- break;
- }
- }
-}
-
-/*
-** Add connection db to the blocked connections list. It is assumed
-** that it is not already a part of the list.
-*/
-static void addToBlockedList(sqlite3 *db){
- sqlite3 **pp;
- assertMutexHeld();
- for(
- pp=&sqlite3BlockedList;
- *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify;
- pp=&(*pp)->pNextBlocked
- );
- db->pNextBlocked = *pp;
- *pp = db;
-}
-
-/*
-** Obtain the STATIC_MASTER mutex.
-*/
-static void enterMutex(void){
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- checkListProperties(0);
-}
-
-/*
-** Release the STATIC_MASTER mutex.
-*/
-static void leaveMutex(void){
- assertMutexHeld();
- checkListProperties(0);
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-
-/*
-** Register an unlock-notify callback.
-**
-** This is called after connection "db" has attempted some operation
-** but has received an SQLITE_LOCKED error because another connection
-** (call it pOther) in the same process was busy using the same shared
-** cache. pOther is found by looking at db->pBlockingConnection.
-**
-** If there is no blocking connection, the callback is invoked immediately,
-** before this routine returns.
-**
-** If pOther is already blocked on db, then report SQLITE_LOCKED, to indicate
-** a deadlock.
-**
-** Otherwise, make arrangements to invoke xNotify when pOther drops
-** its locks.
-**
-** Each call to this routine overrides any prior callbacks registered
-** on the same "db". If xNotify==0 then any prior callbacks are immediately
-** cancelled.
-*/
-SQLITE_API int sqlite3_unlock_notify(
- sqlite3 *db,
- void (*xNotify)(void **, int),
- void *pArg
-){
- int rc = SQLITE_OK;
-
- sqlite3_mutex_enter(db->mutex);
- enterMutex();
-
- if( xNotify==0 ){
- removeFromBlockedList(db);
- db->pBlockingConnection = 0;
- db->pUnlockConnection = 0;
- db->xUnlockNotify = 0;
- db->pUnlockArg = 0;
- }else if( 0==db->pBlockingConnection ){
- /* The blocking transaction has been concluded. Or there never was a
- ** blocking transaction. In either case, invoke the notify callback
- ** immediately.
- */
- xNotify(&pArg, 1);
- }else{
- sqlite3 *p;
-
- for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){}
- if( p ){
- rc = SQLITE_LOCKED; /* Deadlock detected. */
- }else{
- db->pUnlockConnection = db->pBlockingConnection;
- db->xUnlockNotify = xNotify;
- db->pUnlockArg = pArg;
- removeFromBlockedList(db);
- addToBlockedList(db);
- }
- }
-
- leaveMutex();
- assert( !db->mallocFailed );
- sqlite3Error(db, rc, (rc?"database is deadlocked":0));
- sqlite3_mutex_leave(db->mutex);
- return rc;
-}
-
-/*
-** This function is called while stepping or preparing a statement
-** associated with connection db. The operation will return SQLITE_LOCKED
-** to the user because it requires a lock that will not be available
-** until connection pBlocker concludes its current transaction.
-*/
-SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){
- enterMutex();
- if( db->pBlockingConnection==0 && db->pUnlockConnection==0 ){
- addToBlockedList(db);
- }
- db->pBlockingConnection = pBlocker;
- leaveMutex();
-}
-
-/*
-** This function is called when
-** the transaction opened by database db has just finished. Locks held
-** by database connection db have been released.
-**
-** This function loops through each entry in the blocked connections
-** list and does the following:
-**
-** 1) If the sqlite3.pBlockingConnection member of a list entry is
-** set to db, then set pBlockingConnection=0.
-**
-** 2) If the sqlite3.pUnlockConnection member of a list entry is
-** set to db, then invoke the configured unlock-notify callback and
-** set pUnlockConnection=0.
-**
-** 3) If the two steps above mean that pBlockingConnection==0 and
-** pUnlockConnection==0, remove the entry from the blocked connections
-** list.
-*/
-SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){
- void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */
- int nArg = 0; /* Number of entries in aArg[] */
- sqlite3 **pp; /* Iterator variable */
- void **aArg; /* Arguments to the unlock callback */
- void **aDyn = 0; /* Dynamically allocated space for aArg[] */
- void *aStatic[16]; /* Starter space for aArg[]. No malloc required */
-
- aArg = aStatic;
- enterMutex(); /* Enter STATIC_MASTER mutex */
-
- /* This loop runs once for each entry in the blocked-connections list. */
- for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){
- sqlite3 *p = *pp;
-
- /* Step 1. */
- if( p->pBlockingConnection==db ){
- p->pBlockingConnection = 0;
- }
-
- /* Step 2. */
- if( p->pUnlockConnection==db ){
- assert( p->xUnlockNotify );
- if( p->xUnlockNotify!=xUnlockNotify && nArg!=0 ){
- xUnlockNotify(aArg, nArg);
- nArg = 0;
- }
-
- sqlite3BeginBenignMalloc();
- assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) );
- assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn );
- if( (!aDyn && nArg==(int)ArraySize(aStatic))
- || (aDyn && nArg==(int)(sqlite3MallocSize(aDyn)/sizeof(void*)))
- ){
- /* The aArg[] array needs to grow. */
- void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2);
- if( pNew ){
- memcpy(pNew, aArg, nArg*sizeof(void *));
- sqlite3_free(aDyn);
- aDyn = aArg = pNew;
- }else{
- /* This occurs when the array of context pointers that need to
- ** be passed to the unlock-notify callback is larger than the
- ** aStatic[] array allocated on the stack and the attempt to
- ** allocate a larger array from the heap has failed.
- **
- ** This is a difficult situation to handle. Returning an error
- ** code to the caller is insufficient, as even if an error code
- ** is returned the transaction on connection db will still be
- ** closed and the unlock-notify callbacks on blocked connections
- ** will go unissued. This might cause the application to wait
- ** indefinitely for an unlock-notify callback that will never
- ** arrive.
- **
- ** Instead, invoke the unlock-notify callback with the context
- ** array already accumulated. We can then clear the array and
- ** begin accumulating any further context pointers without
- ** requiring any dynamic allocation. This is sub-optimal because
- ** it means that instead of one callback with a large array of
- ** context pointers the application will receive two or more
- ** callbacks with smaller arrays of context pointers, which will
- ** reduce the applications ability to prioritize multiple
- ** connections. But it is the best that can be done under the
- ** circumstances.
- */
- xUnlockNotify(aArg, nArg);
- nArg = 0;
- }
- }
- sqlite3EndBenignMalloc();
-
- aArg[nArg++] = p->pUnlockArg;
- xUnlockNotify = p->xUnlockNotify;
- p->pUnlockConnection = 0;
- p->xUnlockNotify = 0;
- p->pUnlockArg = 0;
- }
-
- /* Step 3. */
- if( p->pBlockingConnection==0 && p->pUnlockConnection==0 ){
- /* Remove connection p from the blocked connections list. */
- *pp = p->pNextBlocked;
- p->pNextBlocked = 0;
- }else{
- pp = &p->pNextBlocked;
- }
- }
-
- if( nArg!=0 ){
- xUnlockNotify(aArg, nArg);
- }
- sqlite3_free(aDyn);
- leaveMutex(); /* Leave STATIC_MASTER mutex */
-}
-
-/*
-** This is called when the database connection passed as an argument is
-** being closed. The connection is removed from the blocked list.
-*/
-SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){
- sqlite3ConnectionUnlocked(db);
- enterMutex();
- removeFromBlockedList(db);
- checkListProperties(db);
- leaveMutex();
-}
-#endif
-
-/************** End of notify.c **********************************************/
-/************** Begin file fts3.c ********************************************/
-/*
-** 2006 Oct 10
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This is an SQLite module implementing full-text search.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-
-/* The full-text index is stored in a series of b+tree (-like)
-** structures called segments which map terms to doclists. The
-** structures are like b+trees in layout, but are constructed from the
-** bottom up in optimal fashion and are not updatable. Since trees
-** are built from the bottom up, things will be described from the
-** bottom up.
-**
-**
-**** Varints ****
-** The basic unit of encoding is a variable-length integer called a
-** varint. We encode variable-length integers in little-endian order
-** using seven bits * per byte as follows:
-**
-** KEY:
-** A = 0xxxxxxx 7 bits of data and one flag bit
-** B = 1xxxxxxx 7 bits of data and one flag bit
-**
-** 7 bits - A
-** 14 bits - BA
-** 21 bits - BBA
-** and so on.
-**
-** This is similar in concept to how sqlite encodes "varints" but
-** the encoding is not the same. SQLite varints are big-endian
-** are are limited to 9 bytes in length whereas FTS3 varints are
-** little-endian and can be up to 10 bytes in length (in theory).
-**
-** Example encodings:
-**
-** 1: 0x01
-** 127: 0x7f
-** 128: 0x81 0x00
-**
-**
-**** Document lists ****
-** A doclist (document list) holds a docid-sorted list of hits for a
-** given term. Doclists hold docids and associated token positions.
-** A docid is the unique integer identifier for a single document.
-** A position is the index of a word within the document. The first
-** word of the document has a position of 0.
-**
-** FTS3 used to optionally store character offsets using a compile-time
-** option. But that functionality is no longer supported.
-**
-** A doclist is stored like this:
-**
-** array {
-** varint docid; (delta from previous doclist)
-** array { (position list for column 0)
-** varint position; (2 more than the delta from previous position)
-** }
-** array {
-** varint POS_COLUMN; (marks start of position list for new column)
-** varint column; (index of new column)
-** array {
-** varint position; (2 more than the delta from previous position)
-** }
-** }
-** varint POS_END; (marks end of positions for this document.
-** }
-**
-** Here, array { X } means zero or more occurrences of X, adjacent in
-** memory. A "position" is an index of a token in the token stream
-** generated by the tokenizer. Note that POS_END and POS_COLUMN occur
-** in the same logical place as the position element, and act as sentinals
-** ending a position list array. POS_END is 0. POS_COLUMN is 1.
-** The positions numbers are not stored literally but rather as two more
-** than the difference from the prior position, or the just the position plus
-** 2 for the first position. Example:
-**
-** label: A B C D E F G H I J K
-** value: 123 5 9 1 1 14 35 0 234 72 0
-**
-** The 123 value is the first docid. For column zero in this document
-** there are two matches at positions 3 and 10 (5-2 and 9-2+3). The 1
-** at D signals the start of a new column; the 1 at E indicates that the
-** new column is column number 1. There are two positions at 12 and 45
-** (14-2 and 35-2+12). The 0 at H indicate the end-of-document. The
-** 234 at I is the delta to next docid (357). It has one position 70
-** (72-2) and then terminates with the 0 at K.
-**
-** A "position-list" is the list of positions for multiple columns for
-** a single docid. A "column-list" is the set of positions for a single
-** column. Hence, a position-list consists of one or more column-lists,
-** a document record consists of a docid followed by a position-list and
-** a doclist consists of one or more document records.
-**
-** A bare doclist omits the position information, becoming an
-** array of varint-encoded docids.
-**
-**** Segment leaf nodes ****
-** Segment leaf nodes store terms and doclists, ordered by term. Leaf
-** nodes are written using LeafWriter, and read using LeafReader (to
-** iterate through a single leaf node's data) and LeavesReader (to
-** iterate through a segment's entire leaf layer). Leaf nodes have
-** the format:
-**
-** varint iHeight; (height from leaf level, always 0)
-** varint nTerm; (length of first term)
-** char pTerm[nTerm]; (content of first term)
-** varint nDoclist; (length of term's associated doclist)
-** char pDoclist[nDoclist]; (content of doclist)
-** array {
-** (further terms are delta-encoded)
-** varint nPrefix; (length of prefix shared with previous term)
-** varint nSuffix; (length of unshared suffix)
-** char pTermSuffix[nSuffix];(unshared suffix of next term)
-** varint nDoclist; (length of term's associated doclist)
-** char pDoclist[nDoclist]; (content of doclist)
-** }
-**
-** Here, array { X } means zero or more occurrences of X, adjacent in
-** memory.
-**
-** Leaf nodes are broken into blocks which are stored contiguously in
-** the %_segments table in sorted order. This means that when the end
-** of a node is reached, the next term is in the node with the next
-** greater node id.
-**
-** New data is spilled to a new leaf node when the current node
-** exceeds LEAF_MAX bytes (default 2048). New data which itself is
-** larger than STANDALONE_MIN (default 1024) is placed in a standalone
-** node (a leaf node with a single term and doclist). The goal of
-** these settings is to pack together groups of small doclists while
-** making it efficient to directly access large doclists. The
-** assumption is that large doclists represent terms which are more
-** likely to be query targets.
-**
-** TODO(shess) It may be useful for blocking decisions to be more
-** dynamic. For instance, it may make more sense to have a 2.5k leaf
-** node rather than splitting into 2k and .5k nodes. My intuition is
-** that this might extend through 2x or 4x the pagesize.
-**
-**
-**** Segment interior nodes ****
-** Segment interior nodes store blockids for subtree nodes and terms
-** to describe what data is stored by the each subtree. Interior
-** nodes are written using InteriorWriter, and read using
-** InteriorReader. InteriorWriters are created as needed when
-** SegmentWriter creates new leaf nodes, or when an interior node
-** itself grows too big and must be split. The format of interior
-** nodes:
-**
-** varint iHeight; (height from leaf level, always >0)
-** varint iBlockid; (block id of node's leftmost subtree)
-** optional {
-** varint nTerm; (length of first term)
-** char pTerm[nTerm]; (content of first term)
-** array {
-** (further terms are delta-encoded)
-** varint nPrefix; (length of shared prefix with previous term)
-** varint nSuffix; (length of unshared suffix)
-** char pTermSuffix[nSuffix]; (unshared suffix of next term)
-** }
-** }
-**
-** Here, optional { X } means an optional element, while array { X }
-** means zero or more occurrences of X, adjacent in memory.
-**
-** An interior node encodes n terms separating n+1 subtrees. The
-** subtree blocks are contiguous, so only the first subtree's blockid
-** is encoded. The subtree at iBlockid will contain all terms less
-** than the first term encoded (or all terms if no term is encoded).
-** Otherwise, for terms greater than or equal to pTerm[i] but less
-** than pTerm[i+1], the subtree for that term will be rooted at
-** iBlockid+i. Interior nodes only store enough term data to
-** distinguish adjacent children (if the rightmost term of the left
-** child is "something", and the leftmost term of the right child is
-** "wicked", only "w" is stored).
-**
-** New data is spilled to a new interior node at the same height when
-** the current node exceeds INTERIOR_MAX bytes (default 2048).
-** INTERIOR_MIN_TERMS (default 7) keeps large terms from monopolizing
-** interior nodes and making the tree too skinny. The interior nodes
-** at a given height are naturally tracked by interior nodes at
-** height+1, and so on.
-**
-**
-**** Segment directory ****
-** The segment directory in table %_segdir stores meta-information for
-** merging and deleting segments, and also the root node of the
-** segment's tree.
-**
-** The root node is the top node of the segment's tree after encoding
-** the entire segment, restricted to ROOT_MAX bytes (default 1024).
-** This could be either a leaf node or an interior node. If the top
-** node requires more than ROOT_MAX bytes, it is flushed to %_segments
-** and a new root interior node is generated (which should always fit
-** within ROOT_MAX because it only needs space for 2 varints, the
-** height and the blockid of the previous root).
-**
-** The meta-information in the segment directory is:
-** level - segment level (see below)
-** idx - index within level
-** - (level,idx uniquely identify a segment)
-** start_block - first leaf node
-** leaves_end_block - last leaf node
-** end_block - last block (including interior nodes)
-** root - contents of root node
-**
-** If the root node is a leaf node, then start_block,
-** leaves_end_block, and end_block are all 0.
-**
-**
-**** Segment merging ****
-** To amortize update costs, segments are grouped into levels and
-** merged in batches. Each increase in level represents exponentially
-** more documents.
-**
-** New documents (actually, document updates) are tokenized and
-** written individually (using LeafWriter) to a level 0 segment, with
-** incrementing idx. When idx reaches MERGE_COUNT (default 16), all
-** level 0 segments are merged into a single level 1 segment. Level 1
-** is populated like level 0, and eventually MERGE_COUNT level 1
-** segments are merged to a single level 2 segment (representing
-** MERGE_COUNT^2 updates), and so on.
-**
-** A segment merge traverses all segments at a given level in
-** parallel, performing a straightforward sorted merge. Since segment
-** leaf nodes are written in to the %_segments table in order, this
-** merge traverses the underlying sqlite disk structures efficiently.
-** After the merge, all segment blocks from the merged level are
-** deleted.
-**
-** MERGE_COUNT controls how often we merge segments. 16 seems to be
-** somewhat of a sweet spot for insertion performance. 32 and 64 show
-** very similar performance numbers to 16 on insertion, though they're
-** a tiny bit slower (perhaps due to more overhead in merge-time
-** sorting). 8 is about 20% slower than 16, 4 about 50% slower than
-** 16, 2 about 66% slower than 16.
-**
-** At query time, high MERGE_COUNT increases the number of segments
-** which need to be scanned and merged. For instance, with 100k docs
-** inserted:
-**
-** MERGE_COUNT segments
-** 16 25
-** 8 12
-** 4 10
-** 2 6
-**
-** This appears to have only a moderate impact on queries for very
-** frequent terms (which are somewhat dominated by segment merge
-** costs), and infrequent and non-existent terms still seem to be fast
-** even with many segments.
-**
-** TODO(shess) That said, it would be nice to have a better query-side
-** argument for MERGE_COUNT of 16. Also, it is possible/likely that
-** optimizations to things like doclist merging will swing the sweet
-** spot around.
-**
-**
-**
-**** Handling of deletions and updates ****
-** Since we're using a segmented structure, with no docid-oriented
-** index into the term index, we clearly cannot simply update the term
-** index when a document is deleted or updated. For deletions, we
-** write an empty doclist (varint(docid) varint(POS_END)), for updates
-** we simply write the new doclist. Segment merges overwrite older
-** data for a particular docid with newer data, so deletes or updates
-** will eventually overtake the earlier data and knock it out. The
-** query logic likewise merges doclists so that newer data knocks out
-** older data.
-*/
-
-/************** Include fts3Int.h in the middle of fts3.c ********************/
-/************** Begin file fts3Int.h *****************************************/
-/*
-** 2009 Nov 12
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-*/
-#ifndef _FTSINT_H
-#define _FTSINT_H
-
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
-# define NDEBUG 1
-#endif
-
-/*
-** FTS4 is really an extension for FTS3. It is enabled using the
-** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all
-** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3.
-*/
-#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3)
-# define SQLITE_ENABLE_FTS3
-#endif
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/* If not building as part of the core, include sqlite3ext.h. */
-#ifndef SQLITE_CORE
-SQLITE_API extern const sqlite3_api_routines *sqlite3_api;
-#endif
-
-/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
-/************** Begin file fts3_tokenizer.h **********************************/
-/*
-** 2006 July 10
-**
-** The author disclaims copyright to this source code.
-**
-*************************************************************************
-** Defines the interface to tokenizers used by fulltext-search. There
-** are three basic components:
-**
-** sqlite3_tokenizer_module is a singleton defining the tokenizer
-** interface functions. This is essentially the class structure for
-** tokenizers.
-**
-** sqlite3_tokenizer is used to define a particular tokenizer, perhaps
-** including customization information defined at creation time.
-**
-** sqlite3_tokenizer_cursor is generated by a tokenizer to generate
-** tokens from a particular input.
-*/
-#ifndef _FTS3_TOKENIZER_H_
-#define _FTS3_TOKENIZER_H_
-
-/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time.
-** If tokenizers are to be allowed to call sqlite3_*() functions, then
-** we will need a way to register the API consistently.
-*/
-
-/*
-** Structures used by the tokenizer interface. When a new tokenizer
-** implementation is registered, the caller provides a pointer to
-** an sqlite3_tokenizer_module containing pointers to the callback
-** functions that make up an implementation.
-**
-** When an fts3 table is created, it passes any arguments passed to
-** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the
-** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer
-** implementation. The xCreate() function in turn returns an
-** sqlite3_tokenizer structure representing the specific tokenizer to
-** be used for the fts3 table (customized by the tokenizer clause arguments).
-**
-** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen()
-** method is called. It returns an sqlite3_tokenizer_cursor object
-** that may be used to tokenize a specific input buffer based on
-** the tokenization rules supplied by a specific sqlite3_tokenizer
-** object.
-*/
-typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module;
-typedef struct sqlite3_tokenizer sqlite3_tokenizer;
-typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor;
-
-struct sqlite3_tokenizer_module {
-
- /*
- ** Structure version. Should always be set to 0 or 1.
- */
- int iVersion;
-
- /*
- ** Create a new tokenizer. The values in the argv[] array are the
- ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL
- ** TABLE statement that created the fts3 table. For example, if
- ** the following SQL is executed:
- **
- ** CREATE .. USING fts3( ... , tokenizer <tokenizer-name> arg1 arg2)
- **
- ** then argc is set to 2, and the argv[] array contains pointers
- ** to the strings "arg1" and "arg2".
- **
- ** This method should return either SQLITE_OK (0), or an SQLite error
- ** code. If SQLITE_OK is returned, then *ppTokenizer should be set
- ** to point at the newly created tokenizer structure. The generic
- ** sqlite3_tokenizer.pModule variable should not be initialised by
- ** this callback. The caller will do so.
- */
- int (*xCreate)(
- int argc, /* Size of argv array */
- const char *const*argv, /* Tokenizer argument strings */
- sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */
- );
-
- /*
- ** Destroy an existing tokenizer. The fts3 module calls this method
- ** exactly once for each successful call to xCreate().
- */
- int (*xDestroy)(sqlite3_tokenizer *pTokenizer);
-
- /*
- ** Create a tokenizer cursor to tokenize an input buffer. The caller
- ** is responsible for ensuring that the input buffer remains valid
- ** until the cursor is closed (using the xClose() method).
- */
- int (*xOpen)(
- sqlite3_tokenizer *pTokenizer, /* Tokenizer object */
- const char *pInput, int nBytes, /* Input buffer */
- sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */
- );
-
- /*
- ** Destroy an existing tokenizer cursor. The fts3 module calls this
- ** method exactly once for each successful call to xOpen().
- */
- int (*xClose)(sqlite3_tokenizer_cursor *pCursor);
-
- /*
- ** Retrieve the next token from the tokenizer cursor pCursor. This
- ** method should either return SQLITE_OK and set the values of the
- ** "OUT" variables identified below, or SQLITE_DONE to indicate that
- ** the end of the buffer has been reached, or an SQLite error code.
- **
- ** *ppToken should be set to point at a buffer containing the
- ** normalized version of the token (i.e. after any case-folding and/or
- ** stemming has been performed). *pnBytes should be set to the length
- ** of this buffer in bytes. The input text that generated the token is
- ** identified by the byte offsets returned in *piStartOffset and
- ** *piEndOffset. *piStartOffset should be set to the index of the first
- ** byte of the token in the input buffer. *piEndOffset should be set
- ** to the index of the first byte just past the end of the token in
- ** the input buffer.
- **
- ** The buffer *ppToken is set to point at is managed by the tokenizer
- ** implementation. It is only required to be valid until the next call
- ** to xNext() or xClose().
- */
- /* TODO(shess) current implementation requires pInput to be
- ** nul-terminated. This should either be fixed, or pInput/nBytes
- ** should be converted to zInput.
- */
- int (*xNext)(
- sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */
- const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */
- int *piStartOffset, /* OUT: Byte offset of token in input buffer */
- int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */
- int *piPosition /* OUT: Number of tokens returned before this one */
- );
-
- /***********************************************************************
- ** Methods below this point are only available if iVersion>=1.
- */
-
- /*
- ** Configure the language id of a tokenizer cursor.
- */
- int (*xLanguageid)(sqlite3_tokenizer_cursor *pCsr, int iLangid);
-};
-
-struct sqlite3_tokenizer {
- const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */
- /* Tokenizer implementations will typically add additional fields */
-};
-
-struct sqlite3_tokenizer_cursor {
- sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */
- /* Tokenizer implementations will typically add additional fields */
-};
-
-int fts3_global_term_cnt(int iTerm, int iCol);
-int fts3_term_cnt(int iTerm, int iCol);
-
-
-#endif /* _FTS3_TOKENIZER_H_ */
-
-/************** End of fts3_tokenizer.h **************************************/
-/************** Continuing where we left off in fts3Int.h ********************/
-/************** Include fts3_hash.h in the middle of fts3Int.h ***************/
-/************** Begin file fts3_hash.h ***************************************/
-/*
-** 2001 September 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This is the header file for the generic hash-table implemenation
-** used in SQLite. We've modified it slightly to serve as a standalone
-** hash table implementation for the full-text indexing module.
-**
-*/
-#ifndef _FTS3_HASH_H_
-#define _FTS3_HASH_H_
-
-/* Forward declarations of structures. */
-typedef struct Fts3Hash Fts3Hash;
-typedef struct Fts3HashElem Fts3HashElem;
-
-/* A complete hash table is an instance of the following structure.
-** The internals of this structure are intended to be opaque -- client
-** code should not attempt to access or modify the fields of this structure
-** directly. Change this structure only by using the routines below.
-** However, many of the "procedures" and "functions" for modifying and
-** accessing this structure are really macros, so we can't really make
-** this structure opaque.
-*/
-struct Fts3Hash {
- char keyClass; /* HASH_INT, _POINTER, _STRING, _BINARY */
- char copyKey; /* True if copy of key made on insert */
- int count; /* Number of entries in this table */
- Fts3HashElem *first; /* The first element of the array */
- int htsize; /* Number of buckets in the hash table */
- struct _fts3ht { /* the hash table */
- int count; /* Number of entries with this hash */
- Fts3HashElem *chain; /* Pointer to first entry with this hash */
- } *ht;
-};
-
-/* Each element in the hash table is an instance of the following
-** structure. All elements are stored on a single doubly-linked list.
-**
-** Again, this structure is intended to be opaque, but it can't really
-** be opaque because it is used by macros.
-*/
-struct Fts3HashElem {
- Fts3HashElem *next, *prev; /* Next and previous elements in the table */
- void *data; /* Data associated with this element */
- void *pKey; int nKey; /* Key associated with this element */
-};
-
-/*
-** There are 2 different modes of operation for a hash table:
-**
-** FTS3_HASH_STRING pKey points to a string that is nKey bytes long
-** (including the null-terminator, if any). Case
-** is respected in comparisons.
-**
-** FTS3_HASH_BINARY pKey points to binary data nKey bytes long.
-** memcmp() is used to compare keys.
-**
-** A copy of the key is made if the copyKey parameter to fts3HashInit is 1.
-*/
-#define FTS3_HASH_STRING 1
-#define FTS3_HASH_BINARY 2
-
-/*
-** Access routines. To delete, insert a NULL pointer.
-*/
-SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey);
-SQLITE_PRIVATE void *sqlite3Fts3HashInsert(Fts3Hash*, const void *pKey, int nKey, void *pData);
-SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash*, const void *pKey, int nKey);
-SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash*);
-SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const void *, int);
-
-/*
-** Shorthand for the functions above
-*/
-#define fts3HashInit sqlite3Fts3HashInit
-#define fts3HashInsert sqlite3Fts3HashInsert
-#define fts3HashFind sqlite3Fts3HashFind
-#define fts3HashClear sqlite3Fts3HashClear
-#define fts3HashFindElem sqlite3Fts3HashFindElem
-
-/*
-** Macros for looping over all elements of a hash table. The idiom is
-** like this:
-**
-** Fts3Hash h;
-** Fts3HashElem *p;
-** ...
-** for(p=fts3HashFirst(&h); p; p=fts3HashNext(p)){
-** SomeStructure *pData = fts3HashData(p);
-** // do something with pData
-** }
-*/
-#define fts3HashFirst(H) ((H)->first)
-#define fts3HashNext(E) ((E)->next)
-#define fts3HashData(E) ((E)->data)
-#define fts3HashKey(E) ((E)->pKey)
-#define fts3HashKeysize(E) ((E)->nKey)
-
-/*
-** Number of entries in a hash table
-*/
-#define fts3HashCount(H) ((H)->count)
-
-#endif /* _FTS3_HASH_H_ */
-
-/************** End of fts3_hash.h *******************************************/
-/************** Continuing where we left off in fts3Int.h ********************/
-
-/*
-** This constant controls how often segments are merged. Once there are
-** FTS3_MERGE_COUNT segments of level N, they are merged into a single
-** segment of level N+1.
-*/
-#define FTS3_MERGE_COUNT 16
-
-/*
-** This is the maximum amount of data (in bytes) to store in the
-** Fts3Table.pendingTerms hash table. Normally, the hash table is
-** populated as documents are inserted/updated/deleted in a transaction
-** and used to create a new segment when the transaction is committed.
-** However if this limit is reached midway through a transaction, a new
-** segment is created and the hash table cleared immediately.
-*/
-#define FTS3_MAX_PENDING_DATA (1*1024*1024)
-
-/*
-** Macro to return the number of elements in an array. SQLite has a
-** similar macro called ArraySize(). Use a different name to avoid
-** a collision when building an amalgamation with built-in FTS3.
-*/
-#define SizeofArray(X) ((int)(sizeof(X)/sizeof(X[0])))
-
-
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-#ifndef MAX
-# define MAX(x,y) ((x)>(y)?(x):(y))
-#endif
-
-/*
-** Maximum length of a varint encoded integer. The varint format is different
-** from that used by SQLite, so the maximum length is 10, not 9.
-*/
-#define FTS3_VARINT_MAX 10
-
-/*
-** FTS4 virtual tables may maintain multiple indexes - one index of all terms
-** in the document set and zero or more prefix indexes. All indexes are stored
-** as one or more b+-trees in the %_segments and %_segdir tables.
-**
-** It is possible to determine which index a b+-tree belongs to based on the
-** value stored in the "%_segdir.level" column. Given this value L, the index
-** that the b+-tree belongs to is (L<<10). In other words, all b+-trees with
-** level values between 0 and 1023 (inclusive) belong to index 0, all levels
-** between 1024 and 2047 to index 1, and so on.
-**
-** It is considered impossible for an index to use more than 1024 levels. In
-** theory though this may happen, but only after at least
-** (FTS3_MERGE_COUNT^1024) separate flushes of the pending-terms tables.
-*/
-#define FTS3_SEGDIR_MAXLEVEL 1024
-#define FTS3_SEGDIR_MAXLEVEL_STR "1024"
-
-/*
-** The testcase() macro is only used by the amalgamation. If undefined,
-** make it a no-op.
-*/
-#ifndef testcase
-# define testcase(X)
-#endif
-
-/*
-** Terminator values for position-lists and column-lists.
-*/
-#define POS_COLUMN (1) /* Column-list terminator */
-#define POS_END (0) /* Position-list terminator */
-
-/*
-** This section provides definitions to allow the
-** FTS3 extension to be compiled outside of the
-** amalgamation.
-*/
-#ifndef SQLITE_AMALGAMATION
-/*
-** Macros indicating that conditional expressions are always true or
-** false.
-*/
-#ifdef SQLITE_COVERAGE_TEST
-# define ALWAYS(x) (1)
-# define NEVER(X) (0)
-#else
-# define ALWAYS(x) (x)
-# define NEVER(x) (x)
-#endif
-
-/*
-** Internal types used by SQLite.
-*/
-typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */
-typedef short int i16; /* 2-byte (or larger) signed integer */
-typedef unsigned int u32; /* 4-byte unsigned integer */
-typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */
-typedef sqlite3_int64 i64; /* 8-byte signed integer */
-
-/*
-** Macro used to suppress compiler warnings for unused parameters.
-*/
-#define UNUSED_PARAMETER(x) (void)(x)
-
-/*
-** Activate assert() only if SQLITE_TEST is enabled.
-*/
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
-# define NDEBUG 1
-#endif
-
-/*
-** The TESTONLY macro is used to enclose variable declarations or
-** other bits of code that are needed to support the arguments
-** within testcase() and assert() macros.
-*/
-#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
-# define TESTONLY(X) X
-#else
-# define TESTONLY(X)
-#endif
-
-#endif /* SQLITE_AMALGAMATION */
-
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3Fts3Corrupt(void);
-# define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt()
-#else
-# define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB
-#endif
-
-typedef struct Fts3Table Fts3Table;
-typedef struct Fts3Cursor Fts3Cursor;
-typedef struct Fts3Expr Fts3Expr;
-typedef struct Fts3Phrase Fts3Phrase;
-typedef struct Fts3PhraseToken Fts3PhraseToken;
-
-typedef struct Fts3Doclist Fts3Doclist;
-typedef struct Fts3SegFilter Fts3SegFilter;
-typedef struct Fts3DeferredToken Fts3DeferredToken;
-typedef struct Fts3SegReader Fts3SegReader;
-typedef struct Fts3MultiSegReader Fts3MultiSegReader;
-
-/*
-** A connection to a fulltext index is an instance of the following
-** structure. The xCreate and xConnect methods create an instance
-** of this structure and xDestroy and xDisconnect free that instance.
-** All other methods receive a pointer to the structure as one of their
-** arguments.
-*/
-struct Fts3Table {
- sqlite3_vtab base; /* Base class used by SQLite core */
- sqlite3 *db; /* The database connection */
- const char *zDb; /* logical database name */
- const char *zName; /* virtual table name */
- int nColumn; /* number of named columns in virtual table */
- char **azColumn; /* column names. malloced */
- sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */
- char *zContentTbl; /* content=xxx option, or NULL */
- char *zLanguageid; /* languageid=xxx option, or NULL */
- u8 bAutoincrmerge; /* True if automerge=1 */
- u32 nLeafAdd; /* Number of leaf blocks added this trans */
-
- /* Precompiled statements used by the implementation. Each of these
- ** statements is run and reset within a single virtual table API call.
- */
- sqlite3_stmt *aStmt[37];
-
- char *zReadExprlist;
- char *zWriteExprlist;
-
- int nNodeSize; /* Soft limit for node size */
- u8 bFts4; /* True for FTS4, false for FTS3 */
- u8 bHasStat; /* True if %_stat table exists */
- u8 bHasDocsize; /* True if %_docsize table exists */
- u8 bDescIdx; /* True if doclists are in reverse order */
- u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */
- int nPgsz; /* Page size for host database */
- char *zSegmentsTbl; /* Name of %_segments table */
- sqlite3_blob *pSegments; /* Blob handle open on %_segments table */
-
- /*
- ** The following array of hash tables is used to buffer pending index
- ** updates during transactions. All pending updates buffered at any one
- ** time must share a common language-id (see the FTS4 langid= feature).
- ** The current language id is stored in variable iPrevLangid.
- **
- ** A single FTS4 table may have multiple full-text indexes. For each index
- ** there is an entry in the aIndex[] array. Index 0 is an index of all the
- ** terms that appear in the document set. Each subsequent index in aIndex[]
- ** is an index of prefixes of a specific length.
- **
- ** Variable nPendingData contains an estimate the memory consumed by the
- ** pending data structures, including hash table overhead, but not including
- ** malloc overhead. When nPendingData exceeds nMaxPendingData, all hash
- ** tables are flushed to disk. Variable iPrevDocid is the docid of the most
- ** recently inserted record.
- */
- int nIndex; /* Size of aIndex[] */
- struct Fts3Index {
- int nPrefix; /* Prefix length (0 for main terms index) */
- Fts3Hash hPending; /* Pending terms table for this index */
- } *aIndex;
- int nMaxPendingData; /* Max pending data before flush to disk */
- int nPendingData; /* Current bytes of pending data */
- sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */
- int iPrevLangid; /* Langid of recently inserted document */
-
-#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
- /* State variables used for validating that the transaction control
- ** methods of the virtual table are called at appropriate times. These
- ** values do not contribute to FTS functionality; they are used for
- ** verifying the operation of the SQLite core.
- */
- int inTransaction; /* True after xBegin but before xCommit/xRollback */
- int mxSavepoint; /* Largest valid xSavepoint integer */
-#endif
-};
-
-/*
-** When the core wants to read from the virtual table, it creates a
-** virtual table cursor (an instance of the following structure) using
-** the xOpen method. Cursors are destroyed using the xClose method.
-*/
-struct Fts3Cursor {
- sqlite3_vtab_cursor base; /* Base class used by SQLite core */
- i16 eSearch; /* Search strategy (see below) */
- u8 isEof; /* True if at End Of Results */
- u8 isRequireSeek; /* True if must seek pStmt to %_content row */
- sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */
- Fts3Expr *pExpr; /* Parsed MATCH query string */
- int iLangid; /* Language being queried for */
- int nPhrase; /* Number of matchable phrases in query */
- Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */
- sqlite3_int64 iPrevId; /* Previous id read from aDoclist */
- char *pNextId; /* Pointer into the body of aDoclist */
- char *aDoclist; /* List of docids for full-text queries */
- int nDoclist; /* Size of buffer at aDoclist */
- u8 bDesc; /* True to sort in descending order */
- int eEvalmode; /* An FTS3_EVAL_XX constant */
- int nRowAvg; /* Average size of database rows, in pages */
- sqlite3_int64 nDoc; /* Documents in table */
-
- int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */
- u32 *aMatchinfo; /* Information about most recent match */
- int nMatchinfo; /* Number of elements in aMatchinfo[] */
- char *zMatchinfo; /* Matchinfo specification */
-};
-
-#define FTS3_EVAL_FILTER 0
-#define FTS3_EVAL_NEXT 1
-#define FTS3_EVAL_MATCHINFO 2
-
-/*
-** The Fts3Cursor.eSearch member is always set to one of the following.
-** Actualy, Fts3Cursor.eSearch can be greater than or equal to
-** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index
-** of the column to be searched. For example, in
-**
-** CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d);
-** SELECT docid FROM ex1 WHERE b MATCH 'one two three';
-**
-** Because the LHS of the MATCH operator is 2nd column "b",
-** Fts3Cursor.eSearch will be set to FTS3_FULLTEXT_SEARCH+1. (+0 for a,
-** +1 for b, +2 for c, +3 for d.) If the LHS of MATCH were "ex1"
-** indicating that all columns should be searched,
-** then eSearch would be set to FTS3_FULLTEXT_SEARCH+4.
-*/
-#define FTS3_FULLSCAN_SEARCH 0 /* Linear scan of %_content table */
-#define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */
-#define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */
-
-
-struct Fts3Doclist {
- char *aAll; /* Array containing doclist (or NULL) */
- int nAll; /* Size of a[] in bytes */
- char *pNextDocid; /* Pointer to next docid */
-
- sqlite3_int64 iDocid; /* Current docid (if pList!=0) */
- int bFreeList; /* True if pList should be sqlite3_free()d */
- char *pList; /* Pointer to position list following iDocid */
- int nList; /* Length of position list */
-};
-
-/*
-** A "phrase" is a sequence of one or more tokens that must match in
-** sequence. A single token is the base case and the most common case.
-** For a sequence of tokens contained in double-quotes (i.e. "one two three")
-** nToken will be the number of tokens in the string.
-*/
-struct Fts3PhraseToken {
- char *z; /* Text of the token */
- int n; /* Number of bytes in buffer z */
- int isPrefix; /* True if token ends with a "*" character */
- int bFirst; /* True if token must appear at position 0 */
-
- /* Variables above this point are populated when the expression is
- ** parsed (by code in fts3_expr.c). Below this point the variables are
- ** used when evaluating the expression. */
- Fts3DeferredToken *pDeferred; /* Deferred token object for this token */
- Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */
-};
-
-struct Fts3Phrase {
- /* Cache of doclist for this phrase. */
- Fts3Doclist doclist;
- int bIncr; /* True if doclist is loaded incrementally */
- int iDoclistToken;
-
- /* Variables below this point are populated by fts3_expr.c when parsing
- ** a MATCH expression. Everything above is part of the evaluation phase.
- */
- int nToken; /* Number of tokens in the phrase */
- int iColumn; /* Index of column this phrase must match */
- Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */
-};
-
-/*
-** A tree of these objects forms the RHS of a MATCH operator.
-**
-** If Fts3Expr.eType is FTSQUERY_PHRASE and isLoaded is true, then aDoclist
-** points to a malloced buffer, size nDoclist bytes, containing the results
-** of this phrase query in FTS3 doclist format. As usual, the initial
-** "Length" field found in doclists stored on disk is omitted from this
-** buffer.
-**
-** Variable aMI is used only for FTSQUERY_NEAR nodes to store the global
-** matchinfo data. If it is not NULL, it points to an array of size nCol*3,
-** where nCol is the number of columns in the queried FTS table. The array
-** is populated as follows:
-**
-** aMI[iCol*3 + 0] = Undefined
-** aMI[iCol*3 + 1] = Number of occurrences
-** aMI[iCol*3 + 2] = Number of rows containing at least one instance
-**
-** The aMI array is allocated using sqlite3_malloc(). It should be freed
-** when the expression node is.
-*/
-struct Fts3Expr {
- int eType; /* One of the FTSQUERY_XXX values defined below */
- int nNear; /* Valid if eType==FTSQUERY_NEAR */
- Fts3Expr *pParent; /* pParent->pLeft==this or pParent->pRight==this */
- Fts3Expr *pLeft; /* Left operand */
- Fts3Expr *pRight; /* Right operand */
- Fts3Phrase *pPhrase; /* Valid if eType==FTSQUERY_PHRASE */
-
- /* The following are used by the fts3_eval.c module. */
- sqlite3_int64 iDocid; /* Current docid */
- u8 bEof; /* True this expression is at EOF already */
- u8 bStart; /* True if iDocid is valid */
- u8 bDeferred; /* True if this expression is entirely deferred */
-
- u32 *aMI;
-};
-
-/*
-** Candidate values for Fts3Query.eType. Note that the order of the first
-** four values is in order of precedence when parsing expressions. For
-** example, the following:
-**
-** "a OR b AND c NOT d NEAR e"
-**
-** is equivalent to:
-**
-** "a OR (b AND (c NOT (d NEAR e)))"
-*/
-#define FTSQUERY_NEAR 1
-#define FTSQUERY_NOT 2
-#define FTSQUERY_AND 3
-#define FTSQUERY_OR 4
-#define FTSQUERY_PHRASE 5
-
-
-/* fts3_write.c */
-SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*);
-SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *);
-SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *);
-SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *);
-SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(int, int, sqlite3_int64,
- sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**);
-SQLITE_PRIVATE int sqlite3Fts3SegReaderPending(
- Fts3Table*,int,const char*,int,int,Fts3SegReader**);
-SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *);
-SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **);
-SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *);
-SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*);
-
-SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **);
-SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **);
-
-#ifndef SQLITE_DISABLE_FTS4_DEFERRED
-SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *);
-SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int);
-SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *);
-SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *);
-SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
-#else
-# define sqlite3Fts3FreeDeferredTokens(x)
-# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK
-# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK
-# define sqlite3Fts3FreeDeferredDoclists(x)
-# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK
-#endif
-
-SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *);
-SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *);
-
-/* Special values interpreted by sqlite3SegReaderCursor() */
-#define FTS3_SEGCURSOR_PENDING -1
-#define FTS3_SEGCURSOR_ALL -2
-
-SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*);
-SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *);
-SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(Fts3MultiSegReader *);
-
-SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor(Fts3Table *,
- int, int, int, const char *, int, int, int, Fts3MultiSegReader *);
-
-/* Flags allowed as part of the 4th argument to SegmentReaderIterate() */
-#define FTS3_SEGMENT_REQUIRE_POS 0x00000001
-#define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002
-#define FTS3_SEGMENT_COLUMN_FILTER 0x00000004
-#define FTS3_SEGMENT_PREFIX 0x00000008
-#define FTS3_SEGMENT_SCAN 0x00000010
-#define FTS3_SEGMENT_FIRST 0x00000020
-
-/* Type passed as 4th argument to SegmentReaderIterate() */
-struct Fts3SegFilter {
- const char *zTerm;
- int nTerm;
- int iCol;
- int flags;
-};
-
-struct Fts3MultiSegReader {
- /* Used internally by sqlite3Fts3SegReaderXXX() calls */
- Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */
- int nSegment; /* Size of apSegment array */
- int nAdvance; /* How many seg-readers to advance */
- Fts3SegFilter *pFilter; /* Pointer to filter object */
- char *aBuffer; /* Buffer to merge doclists in */
- int nBuffer; /* Allocated size of aBuffer[] in bytes */
-
- int iColFilter; /* If >=0, filter for this column */
- int bRestart;
-
- /* Used by fts3.c only. */
- int nCost; /* Cost of running iterator */
- int bLookup; /* True if a lookup of a single entry. */
-
- /* Output values. Valid only after Fts3SegReaderStep() returns SQLITE_ROW. */
- char *zTerm; /* Pointer to term buffer */
- int nTerm; /* Size of zTerm in bytes */
- char *aDoclist; /* Pointer to doclist buffer */
- int nDoclist; /* Size of aDoclist[] in bytes */
-};
-
-SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
-
-/* fts3.c */
-SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64);
-SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
-SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *);
-SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64);
-SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
-SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
-SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
-SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
-SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
-
-/* fts3_tokenizer.c */
-SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
-SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
-SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
- sqlite3_tokenizer **, char **
-);
-SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char);
-
-/* fts3_snippet.c */
-SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*);
-SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *,
- const char *, const char *, int, int
-);
-SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
-
-/* fts3_expr.c */
-SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
- char **, int, int, int, const char *, int, Fts3Expr **
-);
-SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
-SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
-#endif
-
-SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int,
- sqlite3_tokenizer_cursor **
-);
-
-/* fts3_aux.c */
-SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db);
-
-SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *);
-
-SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart(
- Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
-SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
- Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
-SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **);
-SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
-SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
-
-/* fts3_unicode2.c (functions generated by parsing unicode text files) */
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
-SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int);
-SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int);
-SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int);
-#endif
-
-#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
-#endif /* _FTSINT_H */
-
-/************** End of fts3Int.h *********************************************/
-/************** Continuing where we left off in fts3.c ***********************/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE)
-# define SQLITE_CORE 1
-#endif
-
-/* #include <assert.h> */
-/* #include <stdlib.h> */
-/* #include <stddef.h> */
-/* #include <stdio.h> */
-/* #include <string.h> */
-/* #include <stdarg.h> */
-
-#ifndef SQLITE_CORE
- SQLITE_EXTENSION_INIT1
-#endif
-
-static int fts3EvalNext(Fts3Cursor *pCsr);
-static int fts3EvalStart(Fts3Cursor *pCsr);
-static int fts3TermSegReaderCursor(
- Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
-
-/*
-** Write a 64-bit variable-length integer to memory starting at p[0].
-** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
-** The number of bytes written is returned.
-*/
-SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
- unsigned char *q = (unsigned char *) p;
- sqlite_uint64 vu = v;
- do{
- *q++ = (unsigned char) ((vu & 0x7f) | 0x80);
- vu >>= 7;
- }while( vu!=0 );
- q[-1] &= 0x7f; /* turn off high bit in final byte */
- assert( q - (unsigned char *)p <= FTS3_VARINT_MAX );
- return (int) (q - (unsigned char *)p);
-}
-
-/*
-** Read a 64-bit variable-length integer from memory starting at p[0].
-** Return the number of bytes read, or 0 on error.
-** The value is stored in *v.
-*/
-SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
- const unsigned char *q = (const unsigned char *) p;
- sqlite_uint64 x = 0, y = 1;
- while( (*q&0x80)==0x80 && q-(unsigned char *)p<FTS3_VARINT_MAX ){
- x += y * (*q++ & 0x7f);
- y <<= 7;
- }
- x += y * (*q++);
- *v = (sqlite_int64) x;
- return (int) (q - (unsigned char *)p);
-}
-
-/*
-** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to a
-** 32-bit integer before it is returned.
-*/
-SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){
- sqlite_int64 i;
- int ret = sqlite3Fts3GetVarint(p, &i);
- *pi = (int) i;
- return ret;
-}
-
-/*
-** Return the number of bytes required to encode v as a varint
-*/
-SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64 v){
- int i = 0;
- do{
- i++;
- v >>= 7;
- }while( v!=0 );
- return i;
-}
-
-/*
-** Convert an SQL-style quoted string into a normal string by removing
-** the quote characters. The conversion is done in-place. If the
-** input does not begin with a quote character, then this routine
-** is a no-op.
-**
-** Examples:
-**
-** "abc" becomes abc
-** 'xyz' becomes xyz
-** [pqr] becomes pqr
-** `mno` becomes mno
-**
-*/
-SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){
- char quote; /* Quote character (if any ) */
-
- quote = z[0];
- if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){
- int iIn = 1; /* Index of next byte to read from input */
- int iOut = 0; /* Index of next byte to write to output */
-
- /* If the first byte was a '[', then the close-quote character is a ']' */
- if( quote=='[' ) quote = ']';
-
- while( ALWAYS(z[iIn]) ){
- if( z[iIn]==quote ){
- if( z[iIn+1]!=quote ) break;
- z[iOut++] = quote;
- iIn += 2;
- }else{
- z[iOut++] = z[iIn++];
- }
- }
- z[iOut] = '\0';
- }
-}
-
-/*
-** Read a single varint from the doclist at *pp and advance *pp to point
-** to the first byte past the end of the varint. Add the value of the varint
-** to *pVal.
-*/
-static void fts3GetDeltaVarint(char **pp, sqlite3_int64 *pVal){
- sqlite3_int64 iVal;
- *pp += sqlite3Fts3GetVarint(*pp, &iVal);
- *pVal += iVal;
-}
-
-/*
-** When this function is called, *pp points to the first byte following a
-** varint that is part of a doclist (or position-list, or any other list
-** of varints). This function moves *pp to point to the start of that varint,
-** and sets *pVal by the varint value.
-**
-** Argument pStart points to the first byte of the doclist that the
-** varint is part of.
-*/
-static void fts3GetReverseVarint(
- char **pp,
- char *pStart,
- sqlite3_int64 *pVal
-){
- sqlite3_int64 iVal;
- char *p;
-
- /* Pointer p now points at the first byte past the varint we are
- ** interested in. So, unless the doclist is corrupt, the 0x80 bit is
- ** clear on character p[-1]. */
- for(p = (*pp)-2; p>=pStart && *p&0x80; p--);
- p++;
- *pp = p;
-
- sqlite3Fts3GetVarint(p, &iVal);
- *pVal = iVal;
-}
-
-/*
-** The xDisconnect() virtual table method.
-*/
-static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
- Fts3Table *p = (Fts3Table *)pVtab;
- int i;
-
- assert( p->nPendingData==0 );
- assert( p->pSegments==0 );
-
- /* Free any prepared statements held */
- for(i=0; i<SizeofArray(p->aStmt); i++){
- sqlite3_finalize(p->aStmt[i]);
- }
- sqlite3_free(p->zSegmentsTbl);
- sqlite3_free(p->zReadExprlist);
- sqlite3_free(p->zWriteExprlist);
- sqlite3_free(p->zContentTbl);
- sqlite3_free(p->zLanguageid);
-
- /* Invoke the tokenizer destructor to free the tokenizer. */
- p->pTokenizer->pModule->xDestroy(p->pTokenizer);
-
- sqlite3_free(p);
- return SQLITE_OK;
-}
-
-/*
-** Construct one or more SQL statements from the format string given
-** and then evaluate those statements. The success code is written
-** into *pRc.
-**
-** If *pRc is initially non-zero then this routine is a no-op.
-*/
-static void fts3DbExec(
- int *pRc, /* Success code */
- sqlite3 *db, /* Database in which to run SQL */
- const char *zFormat, /* Format string for SQL */
- ... /* Arguments to the format string */
-){
- va_list ap;
- char *zSql;
- if( *pRc ) return;
- va_start(ap, zFormat);
- zSql = sqlite3_vmprintf(zFormat, ap);
- va_end(ap);
- if( zSql==0 ){
- *pRc = SQLITE_NOMEM;
- }else{
- *pRc = sqlite3_exec(db, zSql, 0, 0, 0);
- sqlite3_free(zSql);
- }
-}
-
-/*
-** The xDestroy() virtual table method.
-*/
-static int fts3DestroyMethod(sqlite3_vtab *pVtab){
- Fts3Table *p = (Fts3Table *)pVtab;
- int rc = SQLITE_OK; /* Return code */
- const char *zDb = p->zDb; /* Name of database (e.g. "main", "temp") */
- sqlite3 *db = p->db; /* Database handle */
-
- /* Drop the shadow tables */
- if( p->zContentTbl==0 ){
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName);
- }
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName);
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName);
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName);
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName);
-
- /* If everything has worked, invoke fts3DisconnectMethod() to free the
- ** memory associated with the Fts3Table structure and return SQLITE_OK.
- ** Otherwise, return an SQLite error code.
- */
- return (rc==SQLITE_OK ? fts3DisconnectMethod(pVtab) : rc);
-}
-
-
-/*
-** Invoke sqlite3_declare_vtab() to declare the schema for the FTS3 table
-** passed as the first argument. This is done as part of the xConnect()
-** and xCreate() methods.
-**
-** If *pRc is non-zero when this function is called, it is a no-op.
-** Otherwise, if an error occurs, an SQLite error code is stored in *pRc
-** before returning.
-*/
-static void fts3DeclareVtab(int *pRc, Fts3Table *p){
- if( *pRc==SQLITE_OK ){
- int i; /* Iterator variable */
- int rc; /* Return code */
- char *zSql; /* SQL statement passed to declare_vtab() */
- char *zCols; /* List of user defined columns */
- const char *zLanguageid;
-
- zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid");
- sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
-
- /* Create a list of user columns for the virtual table */
- zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]);
- for(i=1; zCols && i<p->nColumn; i++){
- zCols = sqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]);
- }
-
- /* Create the whole "CREATE TABLE" statement to pass to SQLite */
- zSql = sqlite3_mprintf(
- "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN, %Q HIDDEN)",
- zCols, p->zName, zLanguageid
- );
- if( !zCols || !zSql ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_declare_vtab(p->db, zSql);
- }
-
- sqlite3_free(zSql);
- sqlite3_free(zCols);
- *pRc = rc;
- }
-}
-
-/*
-** Create the %_stat table if it does not already exist.
-*/
-SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int *pRc, Fts3Table *p){
- fts3DbExec(pRc, p->db,
- "CREATE TABLE IF NOT EXISTS %Q.'%q_stat'"
- "(id INTEGER PRIMARY KEY, value BLOB);",
- p->zDb, p->zName
- );
- if( (*pRc)==SQLITE_OK ) p->bHasStat = 1;
-}
-
-/*
-** Create the backing store tables (%_content, %_segments and %_segdir)
-** required by the FTS3 table passed as the only argument. This is done
-** as part of the vtab xCreate() method.
-**
-** If the p->bHasDocsize boolean is true (indicating that this is an
-** FTS4 table, not an FTS3 table) then also create the %_docsize and
-** %_stat tables required by FTS4.
-*/
-static int fts3CreateTables(Fts3Table *p){
- int rc = SQLITE_OK; /* Return code */
- int i; /* Iterator variable */
- sqlite3 *db = p->db; /* The database connection */
-
- if( p->zContentTbl==0 ){
- const char *zLanguageid = p->zLanguageid;
- char *zContentCols; /* Columns of %_content table */
-
- /* Create a list of user columns for the content table */
- zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
- for(i=0; zContentCols && i<p->nColumn; i++){
- char *z = p->azColumn[i];
- zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
- }
- if( zLanguageid && zContentCols ){
- zContentCols = sqlite3_mprintf("%z, langid", zContentCols, zLanguageid);
- }
- if( zContentCols==0 ) rc = SQLITE_NOMEM;
-
- /* Create the content table */
- fts3DbExec(&rc, db,
- "CREATE TABLE %Q.'%q_content'(%s)",
- p->zDb, p->zName, zContentCols
- );
- sqlite3_free(zContentCols);
- }
-
- /* Create other tables */
- fts3DbExec(&rc, db,
- "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
- p->zDb, p->zName
- );
- fts3DbExec(&rc, db,
- "CREATE TABLE %Q.'%q_segdir'("
- "level INTEGER,"
- "idx INTEGER,"
- "start_block INTEGER,"
- "leaves_end_block INTEGER,"
- "end_block INTEGER,"
- "root BLOB,"
- "PRIMARY KEY(level, idx)"
- ");",
- p->zDb, p->zName
- );
- if( p->bHasDocsize ){
- fts3DbExec(&rc, db,
- "CREATE TABLE %Q.'%q_docsize'(docid INTEGER PRIMARY KEY, size BLOB);",
- p->zDb, p->zName
- );
- }
- assert( p->bHasStat==p->bFts4 );
- if( p->bHasStat ){
- sqlite3Fts3CreateStatTable(&rc, p);
- }
- return rc;
-}
-
-/*
-** Store the current database page-size in bytes in p->nPgsz.
-**
-** If *pRc is non-zero when this function is called, it is a no-op.
-** Otherwise, if an error occurs, an SQLite error code is stored in *pRc
-** before returning.
-*/
-static void fts3DatabasePageSize(int *pRc, Fts3Table *p){
- if( *pRc==SQLITE_OK ){
- int rc; /* Return code */
- char *zSql; /* SQL text "PRAGMA %Q.page_size" */
- sqlite3_stmt *pStmt; /* Compiled "PRAGMA %Q.page_size" statement */
-
- zSql = sqlite3_mprintf("PRAGMA %Q.page_size", p->zDb);
- if( !zSql ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_step(pStmt);
- p->nPgsz = sqlite3_column_int(pStmt, 0);
- rc = sqlite3_finalize(pStmt);
- }else if( rc==SQLITE_AUTH ){
- p->nPgsz = 1024;
- rc = SQLITE_OK;
- }
- }
- assert( p->nPgsz>0 || rc!=SQLITE_OK );
- sqlite3_free(zSql);
- *pRc = rc;
- }
-}
-
-/*
-** "Special" FTS4 arguments are column specifications of the following form:
-**
-** <key> = <value>
-**
-** There may not be whitespace surrounding the "=" character. The <value>
-** term may be quoted, but the <key> may not.
-*/
-static int fts3IsSpecialColumn(
- const char *z,
- int *pnKey,
- char **pzValue
-){
- char *zValue;
- const char *zCsr = z;
-
- while( *zCsr!='=' ){
- if( *zCsr=='\0' ) return 0;
- zCsr++;
- }
-
- *pnKey = (int)(zCsr-z);
- zValue = sqlite3_mprintf("%s", &zCsr[1]);
- if( zValue ){
- sqlite3Fts3Dequote(zValue);
- }
- *pzValue = zValue;
- return 1;
-}
-
-/*
-** Append the output of a printf() style formatting to an existing string.
-*/
-static void fts3Appendf(
- int *pRc, /* IN/OUT: Error code */
- char **pz, /* IN/OUT: Pointer to string buffer */
- const char *zFormat, /* Printf format string to append */
- ... /* Arguments for printf format string */
-){
- if( *pRc==SQLITE_OK ){
- va_list ap;
- char *z;
- va_start(ap, zFormat);
- z = sqlite3_vmprintf(zFormat, ap);
- va_end(ap);
- if( z && *pz ){
- char *z2 = sqlite3_mprintf("%s%s", *pz, z);
- sqlite3_free(z);
- z = z2;
- }
- if( z==0 ) *pRc = SQLITE_NOMEM;
- sqlite3_free(*pz);
- *pz = z;
- }
-}
-
-/*
-** Return a copy of input string zInput enclosed in double-quotes (") and
-** with all double quote characters escaped. For example:
-**
-** fts3QuoteId("un \"zip\"") -> "un \"\"zip\"\""
-**
-** The pointer returned points to memory obtained from sqlite3_malloc(). It
-** is the callers responsibility to call sqlite3_free() to release this
-** memory.
-*/
-static char *fts3QuoteId(char const *zInput){
- int nRet;
- char *zRet;
- nRet = 2 + (int)strlen(zInput)*2 + 1;
- zRet = sqlite3_malloc(nRet);
- if( zRet ){
- int i;
- char *z = zRet;
- *(z++) = '"';
- for(i=0; zInput[i]; i++){
- if( zInput[i]=='"' ) *(z++) = '"';
- *(z++) = zInput[i];
- }
- *(z++) = '"';
- *(z++) = '\0';
- }
- return zRet;
-}
-
-/*
-** Return a list of comma separated SQL expressions and a FROM clause that
-** could be used in a SELECT statement such as the following:
-**
-** SELECT <list of expressions> FROM %_content AS x ...
-**
-** to return the docid, followed by each column of text data in order
-** from left to write. If parameter zFunc is not NULL, then instead of
-** being returned directly each column of text data is passed to an SQL
-** function named zFunc first. For example, if zFunc is "unzip" and the
-** table has the three user-defined columns "a", "b", and "c", the following
-** string is returned:
-**
-** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c') FROM %_content AS x"
-**
-** The pointer returned points to a buffer allocated by sqlite3_malloc(). It
-** is the responsibility of the caller to eventually free it.
-**
-** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and
-** a NULL pointer is returned). Otherwise, if an OOM error is encountered
-** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If
-** no error occurs, *pRc is left unmodified.
-*/
-static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){
- char *zRet = 0;
- char *zFree = 0;
- char *zFunction;
- int i;
-
- if( p->zContentTbl==0 ){
- if( !zFunc ){
- zFunction = "";
- }else{
- zFree = zFunction = fts3QuoteId(zFunc);
- }
- fts3Appendf(pRc, &zRet, "docid");
- for(i=0; i<p->nColumn; i++){
- fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]);
- }
- if( p->zLanguageid ){
- fts3Appendf(pRc, &zRet, ", x.%Q", "langid");
- }
- sqlite3_free(zFree);
- }else{
- fts3Appendf(pRc, &zRet, "rowid");
- for(i=0; i<p->nColumn; i++){
- fts3Appendf(pRc, &zRet, ", x.'%q'", p->azColumn[i]);
- }
- if( p->zLanguageid ){
- fts3Appendf(pRc, &zRet, ", x.%Q", p->zLanguageid);
- }
- }
- fts3Appendf(pRc, &zRet, " FROM '%q'.'%q%s' AS x",
- p->zDb,
- (p->zContentTbl ? p->zContentTbl : p->zName),
- (p->zContentTbl ? "" : "_content")
- );
- return zRet;
-}
-
-/*
-** Return a list of N comma separated question marks, where N is the number
-** of columns in the %_content table (one for the docid plus one for each
-** user-defined text column).
-**
-** If argument zFunc is not NULL, then all but the first question mark
-** is preceded by zFunc and an open bracket, and followed by a closed
-** bracket. For example, if zFunc is "zip" and the FTS3 table has three
-** user-defined text columns, the following string is returned:
-**
-** "?, zip(?), zip(?), zip(?)"
-**
-** The pointer returned points to a buffer allocated by sqlite3_malloc(). It
-** is the responsibility of the caller to eventually free it.
-**
-** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and
-** a NULL pointer is returned). Otherwise, if an OOM error is encountered
-** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If
-** no error occurs, *pRc is left unmodified.
-*/
-static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){
- char *zRet = 0;
- char *zFree = 0;
- char *zFunction;
- int i;
-
- if( !zFunc ){
- zFunction = "";
- }else{
- zFree = zFunction = fts3QuoteId(zFunc);
- }
- fts3Appendf(pRc, &zRet, "?");
- for(i=0; i<p->nColumn; i++){
- fts3Appendf(pRc, &zRet, ",%s(?)", zFunction);
- }
- if( p->zLanguageid ){
- fts3Appendf(pRc, &zRet, ", ?");
- }
- sqlite3_free(zFree);
- return zRet;
-}
-
-/*
-** This function interprets the string at (*pp) as a non-negative integer
-** value. It reads the integer and sets *pnOut to the value read, then
-** sets *pp to point to the byte immediately following the last byte of
-** the integer value.
-**
-** Only decimal digits ('0'..'9') may be part of an integer value.
-**
-** If *pp does not being with a decimal digit SQLITE_ERROR is returned and
-** the output value undefined. Otherwise SQLITE_OK is returned.
-**
-** This function is used when parsing the "prefix=" FTS4 parameter.
-*/
-static int fts3GobbleInt(const char **pp, int *pnOut){
- const char *p; /* Iterator pointer */
- int nInt = 0; /* Output value */
-
- for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
- nInt = nInt * 10 + (p[0] - '0');
- }
- if( p==*pp ) return SQLITE_ERROR;
- *pnOut = nInt;
- *pp = p;
- return SQLITE_OK;
-}
-
-/*
-** This function is called to allocate an array of Fts3Index structures
-** representing the indexes maintained by the current FTS table. FTS tables
-** always maintain the main "terms" index, but may also maintain one or
-** more "prefix" indexes, depending on the value of the "prefix=" parameter
-** (if any) specified as part of the CREATE VIRTUAL TABLE statement.
-**
-** Argument zParam is passed the value of the "prefix=" option if one was
-** specified, or NULL otherwise.
-**
-** If no error occurs, SQLITE_OK is returned and *apIndex set to point to
-** the allocated array. *pnIndex is set to the number of elements in the
-** array. If an error does occur, an SQLite error code is returned.
-**
-** Regardless of whether or not an error is returned, it is the responsibility
-** of the caller to call sqlite3_free() on the output array to free it.
-*/
-static int fts3PrefixParameter(
- const char *zParam, /* ABC in prefix=ABC parameter to parse */
- int *pnIndex, /* OUT: size of *apIndex[] array */
- struct Fts3Index **apIndex /* OUT: Array of indexes for this table */
-){
- struct Fts3Index *aIndex; /* Allocated array */
- int nIndex = 1; /* Number of entries in array */
-
- if( zParam && zParam[0] ){
- const char *p;
- nIndex++;
- for(p=zParam; *p; p++){
- if( *p==',' ) nIndex++;
- }
- }
-
- aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
- *apIndex = aIndex;
- *pnIndex = nIndex;
- if( !aIndex ){
- return SQLITE_NOMEM;
- }
-
- memset(aIndex, 0, sizeof(struct Fts3Index) * nIndex);
- if( zParam ){
- const char *p = zParam;
- int i;
- for(i=1; i<nIndex; i++){
- int nPrefix;
- if( fts3GobbleInt(&p, &nPrefix) ) return SQLITE_ERROR;
- aIndex[i].nPrefix = nPrefix;
- p++;
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** This function is called when initializing an FTS4 table that uses the
-** content=xxx option. It determines the number of and names of the columns
-** of the new FTS4 table.
-**
-** The third argument passed to this function is the value passed to the
-** config=xxx option (i.e. "xxx"). This function queries the database for
-** a table of that name. If found, the output variables are populated
-** as follows:
-**
-** *pnCol: Set to the number of columns table xxx has,
-**
-** *pnStr: Set to the total amount of space required to store a copy
-** of each columns name, including the nul-terminator.
-**
-** *pazCol: Set to point to an array of *pnCol strings. Each string is
-** the name of the corresponding column in table xxx. The array
-** and its contents are allocated using a single allocation. It
-** is the responsibility of the caller to free this allocation
-** by eventually passing the *pazCol value to sqlite3_free().
-**
-** If the table cannot be found, an error code is returned and the output
-** variables are undefined. Or, if an OOM is encountered, SQLITE_NOMEM is
-** returned (and the output variables are undefined).
-*/
-static int fts3ContentColumns(
- sqlite3 *db, /* Database handle */
- const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */
- const char *zTbl, /* Name of content table */
- const char ***pazCol, /* OUT: Malloc'd array of column names */
- int *pnCol, /* OUT: Size of array *pazCol */
- int *pnStr /* OUT: Bytes of string content */
-){
- int rc = SQLITE_OK; /* Return code */
- char *zSql; /* "SELECT *" statement on zTbl */
- sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */
-
- zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl);
- if( !zSql ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
- }
- sqlite3_free(zSql);
-
- if( rc==SQLITE_OK ){
- const char **azCol; /* Output array */
- int nStr = 0; /* Size of all column names (incl. 0x00) */
- int nCol; /* Number of table columns */
- int i; /* Used to iterate through columns */
-
- /* Loop through the returned columns. Set nStr to the number of bytes of
- ** space required to store a copy of each column name, including the
- ** nul-terminator byte. */
- nCol = sqlite3_column_count(pStmt);
- for(i=0; i<nCol; i++){
- const char *zCol = sqlite3_column_name(pStmt, i);
- nStr += (int)strlen(zCol) + 1;
- }
-
- /* Allocate and populate the array to return. */
- azCol = (const char **)sqlite3_malloc(sizeof(char *) * nCol + nStr);
- if( azCol==0 ){
- rc = SQLITE_NOMEM;
- }else{
- char *p = (char *)&azCol[nCol];
- for(i=0; i<nCol; i++){
- const char *zCol = sqlite3_column_name(pStmt, i);
- int n = (int)strlen(zCol)+1;
- memcpy(p, zCol, n);
- azCol[i] = p;
- p += n;
- }
- }
- sqlite3_finalize(pStmt);
-
- /* Set the output variables. */
- *pnCol = nCol;
- *pnStr = nStr;
- *pazCol = azCol;
- }
-
- return rc;
-}
-
-/*
-** This function is the implementation of both the xConnect and xCreate
-** methods of the FTS3 virtual table.
-**
-** The argv[] array contains the following:
-**
-** argv[0] -> module name ("fts3" or "fts4")
-** argv[1] -> database name
-** argv[2] -> table name
-** argv[...] -> "column name" and other module argument fields.
-*/
-static int fts3InitVtab(
- int isCreate, /* True for xCreate, false for xConnect */
- sqlite3 *db, /* The SQLite database connection */
- void *pAux, /* Hash table containing tokenizers */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */
- char **pzErr /* Write any error message here */
-){
- Fts3Hash *pHash = (Fts3Hash *)pAux;
- Fts3Table *p = 0; /* Pointer to allocated vtab */
- int rc = SQLITE_OK; /* Return code */
- int i; /* Iterator variable */
- int nByte; /* Size of allocation used for *p */
- int iCol; /* Column index */
- int nString = 0; /* Bytes required to hold all column names */
- int nCol = 0; /* Number of columns in the FTS table */
- char *zCsr; /* Space for holding column names */
- int nDb; /* Bytes required to hold database name */
- int nName; /* Bytes required to hold table name */
- int isFts4 = (argv[0][3]=='4'); /* True for FTS4, false for FTS3 */
- const char **aCol; /* Array of column names */
- sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */
-
- int nIndex; /* Size of aIndex[] array */
- struct Fts3Index *aIndex = 0; /* Array of indexes for this table */
-
- /* The results of parsing supported FTS4 key=value options: */
- int bNoDocsize = 0; /* True to omit %_docsize table */
- int bDescIdx = 0; /* True to store descending indexes */
- char *zPrefix = 0; /* Prefix parameter value (or NULL) */
- char *zCompress = 0; /* compress=? parameter (or NULL) */
- char *zUncompress = 0; /* uncompress=? parameter (or NULL) */
- char *zContent = 0; /* content=? parameter (or NULL) */
- char *zLanguageid = 0; /* languageid=? parameter (or NULL) */
-
- assert( strlen(argv[0])==4 );
- assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4)
- || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4)
- );
-
- nDb = (int)strlen(argv[1]) + 1;
- nName = (int)strlen(argv[2]) + 1;
-
- aCol = (const char **)sqlite3_malloc(sizeof(const char *) * (argc-2) );
- if( !aCol ) return SQLITE_NOMEM;
- memset((void *)aCol, 0, sizeof(const char *) * (argc-2));
-
- /* Loop through all of the arguments passed by the user to the FTS3/4
- ** module (i.e. all the column names and special arguments). This loop
- ** does the following:
- **
- ** + Figures out the number of columns the FTSX table will have, and
- ** the number of bytes of space that must be allocated to store copies
- ** of the column names.
- **
- ** + If there is a tokenizer specification included in the arguments,
- ** initializes the tokenizer pTokenizer.
- */
- for(i=3; rc==SQLITE_OK && i<argc; i++){
- char const *z = argv[i];
- int nKey;
- char *zVal;
-
- /* Check if this is a tokenizer specification */
- if( !pTokenizer
- && strlen(z)>8
- && 0==sqlite3_strnicmp(z, "tokenize", 8)
- && 0==sqlite3Fts3IsIdChar(z[8])
- ){
- rc = sqlite3Fts3InitTokenizer(pHash, &z[9], &pTokenizer, pzErr);
- }
-
- /* Check if it is an FTS4 special argument. */
- else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){
- struct Fts4Option {
- const char *zOpt;
- int nOpt;
- } aFts4Opt[] = {
- { "matchinfo", 9 }, /* 0 -> MATCHINFO */
- { "prefix", 6 }, /* 1 -> PREFIX */
- { "compress", 8 }, /* 2 -> COMPRESS */
- { "uncompress", 10 }, /* 3 -> UNCOMPRESS */
- { "order", 5 }, /* 4 -> ORDER */
- { "content", 7 }, /* 5 -> CONTENT */
- { "languageid", 10 } /* 6 -> LANGUAGEID */
- };
-
- int iOpt;
- if( !zVal ){
- rc = SQLITE_NOMEM;
- }else{
- for(iOpt=0; iOpt<SizeofArray(aFts4Opt); iOpt++){
- struct Fts4Option *pOp = &aFts4Opt[iOpt];
- if( nKey==pOp->nOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){
- break;
- }
- }
- if( iOpt==SizeofArray(aFts4Opt) ){
- *pzErr = sqlite3_mprintf("unrecognized parameter: %s", z);
- rc = SQLITE_ERROR;
- }else{
- switch( iOpt ){
- case 0: /* MATCHINFO */
- if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
- *pzErr = sqlite3_mprintf("unrecognized matchinfo: %s", zVal);
- rc = SQLITE_ERROR;
- }
- bNoDocsize = 1;
- break;
-
- case 1: /* PREFIX */
- sqlite3_free(zPrefix);
- zPrefix = zVal;
- zVal = 0;
- break;
-
- case 2: /* COMPRESS */
- sqlite3_free(zCompress);
- zCompress = zVal;
- zVal = 0;
- break;
-
- case 3: /* UNCOMPRESS */
- sqlite3_free(zUncompress);
- zUncompress = zVal;
- zVal = 0;
- break;
-
- case 4: /* ORDER */
- if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
- && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
- ){
- *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
- rc = SQLITE_ERROR;
- }
- bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
- break;
-
- case 5: /* CONTENT */
- sqlite3_free(zContent);
- zContent = zVal;
- zVal = 0;
- break;
-
- case 6: /* LANGUAGEID */
- assert( iOpt==6 );
- sqlite3_free(zLanguageid);
- zLanguageid = zVal;
- zVal = 0;
- break;
- }
- }
- sqlite3_free(zVal);
- }
- }
-
- /* Otherwise, the argument is a column name. */
- else {
- nString += (int)(strlen(z) + 1);
- aCol[nCol++] = z;
- }
- }
-
- /* If a content=xxx option was specified, the following:
- **
- ** 1. Ignore any compress= and uncompress= options.
- **
- ** 2. If no column names were specified as part of the CREATE VIRTUAL
- ** TABLE statement, use all columns from the content table.
- */
- if( rc==SQLITE_OK && zContent ){
- sqlite3_free(zCompress);
- sqlite3_free(zUncompress);
- zCompress = 0;
- zUncompress = 0;
- if( nCol==0 ){
- sqlite3_free((void*)aCol);
- aCol = 0;
- rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
-
- /* If a languageid= option was specified, remove the language id
- ** column from the aCol[] array. */
- if( rc==SQLITE_OK && zLanguageid ){
- int j;
- for(j=0; j<nCol; j++){
- if( sqlite3_stricmp(zLanguageid, aCol[j])==0 ){
- int k;
- for(k=j; k<nCol; k++) aCol[k] = aCol[k+1];
- nCol--;
- break;
- }
- }
- }
- }
- }
- if( rc!=SQLITE_OK ) goto fts3_init_out;
-
- if( nCol==0 ){
- assert( nString==0 );
- aCol[0] = "content";
- nString = 8;
- nCol = 1;
- }
-
- if( pTokenizer==0 ){
- rc = sqlite3Fts3InitTokenizer(pHash, "simple", &pTokenizer, pzErr);
- if( rc!=SQLITE_OK ) goto fts3_init_out;
- }
- assert( pTokenizer );
-
- rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex);
- if( rc==SQLITE_ERROR ){
- assert( zPrefix );
- *pzErr = sqlite3_mprintf("error parsing prefix parameter: %s", zPrefix);
- }
- if( rc!=SQLITE_OK ) goto fts3_init_out;
-
- /* Allocate and populate the Fts3Table structure. */
- nByte = sizeof(Fts3Table) + /* Fts3Table */
- nCol * sizeof(char *) + /* azColumn */
- nIndex * sizeof(struct Fts3Index) + /* aIndex */
- nName + /* zName */
- nDb + /* zDb */
- nString; /* Space for azColumn strings */
- p = (Fts3Table*)sqlite3_malloc(nByte);
- if( p==0 ){
- rc = SQLITE_NOMEM;
- goto fts3_init_out;
- }
- memset(p, 0, nByte);
- p->db = db;
- p->nColumn = nCol;
- p->nPendingData = 0;
- p->azColumn = (char **)&p[1];
- p->pTokenizer = pTokenizer;
- p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
- p->bHasDocsize = (isFts4 && bNoDocsize==0);
- p->bHasStat = isFts4;
- p->bFts4 = isFts4;
- p->bDescIdx = bDescIdx;
- p->bAutoincrmerge = 0xff; /* 0xff means setting unknown */
- p->zContentTbl = zContent;
- p->zLanguageid = zLanguageid;
- zContent = 0;
- zLanguageid = 0;
- TESTONLY( p->inTransaction = -1 );
- TESTONLY( p->mxSavepoint = -1 );
-
- p->aIndex = (struct Fts3Index *)&p->azColumn[nCol];
- memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex);
- p->nIndex = nIndex;
- for(i=0; i<nIndex; i++){
- fts3HashInit(&p->aIndex[i].hPending, FTS3_HASH_STRING, 1);
- }
-
- /* Fill in the zName and zDb fields of the vtab structure. */
- zCsr = (char *)&p->aIndex[nIndex];
- p->zName = zCsr;
- memcpy(zCsr, argv[2], nName);
- zCsr += nName;
- p->zDb = zCsr;
- memcpy(zCsr, argv[1], nDb);
- zCsr += nDb;
-
- /* Fill in the azColumn array */
- for(iCol=0; iCol<nCol; iCol++){
- char *z;
- int n = 0;
- z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n);
- memcpy(zCsr, z, n);
- zCsr[n] = '\0';
- sqlite3Fts3Dequote(zCsr);
- p->azColumn[iCol] = zCsr;
- zCsr += n+1;
- assert( zCsr <= &((char *)p)[nByte] );
- }
-
- if( (zCompress==0)!=(zUncompress==0) ){
- char const *zMiss = (zCompress==0 ? "compress" : "uncompress");
- rc = SQLITE_ERROR;
- *pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss);
- }
- p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc);
- p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc);
- if( rc!=SQLITE_OK ) goto fts3_init_out;
-
- /* If this is an xCreate call, create the underlying tables in the
- ** database. TODO: For xConnect(), it could verify that said tables exist.
- */
- if( isCreate ){
- rc = fts3CreateTables(p);
- }
-
- /* Check to see if a legacy fts3 table has been "upgraded" by the
- ** addition of a %_stat table so that it can use incremental merge.
- */
- if( !isFts4 && !isCreate ){
- int rc2 = SQLITE_OK;
- fts3DbExec(&rc2, db, "SELECT 1 FROM %Q.'%q_stat' WHERE id=2",
- p->zDb, p->zName);
- if( rc2==SQLITE_OK ) p->bHasStat = 1;
- }
-
- /* Figure out the page-size for the database. This is required in order to
- ** estimate the cost of loading large doclists from the database. */
- fts3DatabasePageSize(&rc, p);
- p->nNodeSize = p->nPgsz-35;
-
- /* Declare the table schema to SQLite. */
- fts3DeclareVtab(&rc, p);
-
-fts3_init_out:
- sqlite3_free(zPrefix);
- sqlite3_free(aIndex);
- sqlite3_free(zCompress);
- sqlite3_free(zUncompress);
- sqlite3_free(zContent);
- sqlite3_free(zLanguageid);
- sqlite3_free((void *)aCol);
- if( rc!=SQLITE_OK ){
- if( p ){
- fts3DisconnectMethod((sqlite3_vtab *)p);
- }else if( pTokenizer ){
- pTokenizer->pModule->xDestroy(pTokenizer);
- }
- }else{
- assert( p->pSegments==0 );
- *ppVTab = &p->base;
- }
- return rc;
-}
-
-/*
-** The xConnect() and xCreate() methods for the virtual table. All the
-** work is done in function fts3InitVtab().
-*/
-static int fts3ConnectMethod(
- sqlite3 *db, /* Database connection */
- void *pAux, /* Pointer to tokenizer hash table */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
- char **pzErr /* OUT: sqlite3_malloc'd error message */
-){
- return fts3InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr);
-}
-static int fts3CreateMethod(
- sqlite3 *db, /* Database connection */
- void *pAux, /* Pointer to tokenizer hash table */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
- char **pzErr /* OUT: sqlite3_malloc'd error message */
-){
- return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr);
-}
-
-/*
-** Implementation of the xBestIndex method for FTS3 tables. There
-** are three possible strategies, in order of preference:
-**
-** 1. Direct lookup by rowid or docid.
-** 2. Full-text search using a MATCH operator on a non-docid column.
-** 3. Linear scan of %_content table.
-*/
-static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
- Fts3Table *p = (Fts3Table *)pVTab;
- int i; /* Iterator variable */
- int iCons = -1; /* Index of constraint to use */
- int iLangidCons = -1; /* Index of langid=x constraint, if present */
-
- /* By default use a full table scan. This is an expensive option,
- ** so search through the constraints to see if a more efficient
- ** strategy is possible.
- */
- pInfo->idxNum = FTS3_FULLSCAN_SEARCH;
- pInfo->estimatedCost = 500000;
- for(i=0; i<pInfo->nConstraint; i++){
- struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i];
- if( pCons->usable==0 ) continue;
-
- /* A direct lookup on the rowid or docid column. Assign a cost of 1.0. */
- if( iCons<0
- && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ
- && (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1 )
- ){
- pInfo->idxNum = FTS3_DOCID_SEARCH;
- pInfo->estimatedCost = 1.0;
- iCons = i;
- }
-
- /* A MATCH constraint. Use a full-text search.
- **
- ** If there is more than one MATCH constraint available, use the first
- ** one encountered. If there is both a MATCH constraint and a direct
- ** rowid/docid lookup, prefer the MATCH strategy. This is done even
- ** though the rowid/docid lookup is faster than a MATCH query, selecting
- ** it would lead to an "unable to use function MATCH in the requested
- ** context" error.
- */
- if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH
- && pCons->iColumn>=0 && pCons->iColumn<=p->nColumn
- ){
- pInfo->idxNum = FTS3_FULLTEXT_SEARCH + pCons->iColumn;
- pInfo->estimatedCost = 2.0;
- iCons = i;
- }
-
- /* Equality constraint on the langid column */
- if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ
- && pCons->iColumn==p->nColumn + 2
- ){
- iLangidCons = i;
- }
- }
-
- if( iCons>=0 ){
- pInfo->aConstraintUsage[iCons].argvIndex = 1;
- pInfo->aConstraintUsage[iCons].omit = 1;
- }
- if( iLangidCons>=0 ){
- pInfo->aConstraintUsage[iLangidCons].argvIndex = 2;
- }
-
- /* Regardless of the strategy selected, FTS can deliver rows in rowid (or
- ** docid) order. Both ascending and descending are possible.
- */
- if( pInfo->nOrderBy==1 ){
- struct sqlite3_index_orderby *pOrder = &pInfo->aOrderBy[0];
- if( pOrder->iColumn<0 || pOrder->iColumn==p->nColumn+1 ){
- if( pOrder->desc ){
- pInfo->idxStr = "DESC";
- }else{
- pInfo->idxStr = "ASC";
- }
- pInfo->orderByConsumed = 1;
- }
- }
-
- assert( p->pSegments==0 );
- return SQLITE_OK;
-}
-
-/*
-** Implementation of xOpen method.
-*/
-static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
- sqlite3_vtab_cursor *pCsr; /* Allocated cursor */
-
- UNUSED_PARAMETER(pVTab);
-
- /* Allocate a buffer large enough for an Fts3Cursor structure. If the
- ** allocation succeeds, zero it and return SQLITE_OK. Otherwise,
- ** if the allocation fails, return SQLITE_NOMEM.
- */
- *ppCsr = pCsr = (sqlite3_vtab_cursor *)sqlite3_malloc(sizeof(Fts3Cursor));
- if( !pCsr ){
- return SQLITE_NOMEM;
- }
- memset(pCsr, 0, sizeof(Fts3Cursor));
- return SQLITE_OK;
-}
-
-/*
-** Close the cursor. For additional information see the documentation
-** on the xClose method of the virtual table interface.
-*/
-static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
- Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
- assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
- sqlite3_finalize(pCsr->pStmt);
- sqlite3Fts3ExprFree(pCsr->pExpr);
- sqlite3Fts3FreeDeferredTokens(pCsr);
- sqlite3_free(pCsr->aDoclist);
- sqlite3_free(pCsr->aMatchinfo);
- assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-/*
-** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then
-** compose and prepare an SQL statement of the form:
-**
-** "SELECT <columns> FROM %_content WHERE rowid = ?"
-**
-** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
-** it. If an error occurs, return an SQLite error code.
-**
-** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
-*/
-static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
- int rc = SQLITE_OK;
- if( pCsr->pStmt==0 ){
- Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
- char *zSql;
- zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
- if( !zSql ) return SQLITE_NOMEM;
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
- sqlite3_free(zSql);
- }
- *ppStmt = pCsr->pStmt;
- return rc;
-}
-
-/*
-** Position the pCsr->pStmt statement so that it is on the row
-** of the %_content table that contains the last match. Return
-** SQLITE_OK on success.
-*/
-static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
- int rc = SQLITE_OK;
- if( pCsr->isRequireSeek ){
- sqlite3_stmt *pStmt = 0;
-
- rc = fts3CursorSeekStmt(pCsr, &pStmt);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
- pCsr->isRequireSeek = 0;
- if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
- return SQLITE_OK;
- }else{
- rc = sqlite3_reset(pCsr->pStmt);
- if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){
- /* If no row was found and no error has occured, then the %_content
- ** table is missing a row that is present in the full-text index.
- ** The data structures are corrupt. */
- rc = FTS_CORRUPT_VTAB;
- pCsr->isEof = 1;
- }
- }
- }
- }
-
- if( rc!=SQLITE_OK && pContext ){
- sqlite3_result_error_code(pContext, rc);
- }
- return rc;
-}
-
-/*
-** This function is used to process a single interior node when searching
-** a b-tree for a term or term prefix. The node data is passed to this
-** function via the zNode/nNode parameters. The term to search for is
-** passed in zTerm/nTerm.
-**
-** If piFirst is not NULL, then this function sets *piFirst to the blockid
-** of the child node that heads the sub-tree that may contain the term.
-**
-** If piLast is not NULL, then *piLast is set to the right-most child node
-** that heads a sub-tree that may contain a term for which zTerm/nTerm is
-** a prefix.
-**
-** If an OOM error occurs, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK.
-*/
-static int fts3ScanInteriorNode(
- const char *zTerm, /* Term to select leaves for */
- int nTerm, /* Size of term zTerm in bytes */
- const char *zNode, /* Buffer containing segment interior node */
- int nNode, /* Size of buffer at zNode */
- sqlite3_int64 *piFirst, /* OUT: Selected child node */
- sqlite3_int64 *piLast /* OUT: Selected child node */
-){
- int rc = SQLITE_OK; /* Return code */
- const char *zCsr = zNode; /* Cursor to iterate through node */
- const char *zEnd = &zCsr[nNode];/* End of interior node buffer */
- char *zBuffer = 0; /* Buffer to load terms into */
- int nAlloc = 0; /* Size of allocated buffer */
- int isFirstTerm = 1; /* True when processing first term on page */
- sqlite3_int64 iChild; /* Block id of child node to descend to */
-
- /* Skip over the 'height' varint that occurs at the start of every
- ** interior node. Then load the blockid of the left-child of the b-tree
- ** node into variable iChild.
- **
- ** Even if the data structure on disk is corrupted, this (reading two
- ** varints from the buffer) does not risk an overread. If zNode is a
- ** root node, then the buffer comes from a SELECT statement. SQLite does
- ** not make this guarantee explicitly, but in practice there are always
- ** either more than 20 bytes of allocated space following the nNode bytes of
- ** contents, or two zero bytes. Or, if the node is read from the %_segments
- ** table, then there are always 20 bytes of zeroed padding following the
- ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
- */
- zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
- zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
- if( zCsr>zEnd ){
- return FTS_CORRUPT_VTAB;
- }
-
- while( zCsr<zEnd && (piFirst || piLast) ){
- int cmp; /* memcmp() result */
- int nSuffix; /* Size of term suffix */
- int nPrefix = 0; /* Size of term prefix */
- int nBuffer; /* Total term size */
-
- /* Load the next term on the node into zBuffer. Use realloc() to expand
- ** the size of zBuffer if required. */
- if( !isFirstTerm ){
- zCsr += sqlite3Fts3GetVarint32(zCsr, &nPrefix);
- }
- isFirstTerm = 0;
- zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix);
-
- if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
- rc = FTS_CORRUPT_VTAB;
- goto finish_scan;
- }
- if( nPrefix+nSuffix>nAlloc ){
- char *zNew;
- nAlloc = (nPrefix+nSuffix) * 2;
- zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
- if( !zNew ){
- rc = SQLITE_NOMEM;
- goto finish_scan;
- }
- zBuffer = zNew;
- }
- assert( zBuffer );
- memcpy(&zBuffer[nPrefix], zCsr, nSuffix);
- nBuffer = nPrefix + nSuffix;
- zCsr += nSuffix;
-
- /* Compare the term we are searching for with the term just loaded from
- ** the interior node. If the specified term is greater than or equal
- ** to the term from the interior node, then all terms on the sub-tree
- ** headed by node iChild are smaller than zTerm. No need to search
- ** iChild.
- **
- ** If the interior node term is larger than the specified term, then
- ** the tree headed by iChild may contain the specified term.
- */
- cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer));
- if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){
- *piFirst = iChild;
- piFirst = 0;
- }
-
- if( piLast && cmp<0 ){
- *piLast = iChild;
- piLast = 0;
- }
-
- iChild++;
- };
-
- if( piFirst ) *piFirst = iChild;
- if( piLast ) *piLast = iChild;
-
- finish_scan:
- sqlite3_free(zBuffer);
- return rc;
-}
-
-
-/*
-** The buffer pointed to by argument zNode (size nNode bytes) contains an
-** interior node of a b-tree segment. The zTerm buffer (size nTerm bytes)
-** contains a term. This function searches the sub-tree headed by the zNode
-** node for the range of leaf nodes that may contain the specified term
-** or terms for which the specified term is a prefix.
-**
-** If piLeaf is not NULL, then *piLeaf is set to the blockid of the
-** left-most leaf node in the tree that may contain the specified term.
-** If piLeaf2 is not NULL, then *piLeaf2 is set to the blockid of the
-** right-most leaf node that may contain a term for which the specified
-** term is a prefix.
-**
-** It is possible that the range of returned leaf nodes does not contain
-** the specified term or any terms for which it is a prefix. However, if the
-** segment does contain any such terms, they are stored within the identified
-** range. Because this function only inspects interior segment nodes (and
-** never loads leaf nodes into memory), it is not possible to be sure.
-**
-** If an error occurs, an error code other than SQLITE_OK is returned.
-*/
-static int fts3SelectLeaf(
- Fts3Table *p, /* Virtual table handle */
- const char *zTerm, /* Term to select leaves for */
- int nTerm, /* Size of term zTerm in bytes */
- const char *zNode, /* Buffer containing segment interior node */
- int nNode, /* Size of buffer at zNode */
- sqlite3_int64 *piLeaf, /* Selected leaf node */
- sqlite3_int64 *piLeaf2 /* Selected leaf node */
-){
- int rc; /* Return code */
- int iHeight; /* Height of this node in tree */
-
- assert( piLeaf || piLeaf2 );
-
- sqlite3Fts3GetVarint32(zNode, &iHeight);
- rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2);
- assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) );
-
- if( rc==SQLITE_OK && iHeight>1 ){
- char *zBlob = 0; /* Blob read from %_segments table */
- int nBlob; /* Size of zBlob in bytes */
-
- if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){
- rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0);
- if( rc==SQLITE_OK ){
- rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0);
- }
- sqlite3_free(zBlob);
- piLeaf = 0;
- zBlob = 0;
- }
-
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0);
- }
- if( rc==SQLITE_OK ){
- rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2);
- }
- sqlite3_free(zBlob);
- }
-
- return rc;
-}
-
-/*
-** This function is used to create delta-encoded serialized lists of FTS3
-** varints. Each call to this function appends a single varint to a list.
-*/
-static void fts3PutDeltaVarint(
- char **pp, /* IN/OUT: Output pointer */
- sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */
- sqlite3_int64 iVal /* Write this value to the list */
-){
- assert( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) );
- *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev);
- *piPrev = iVal;
-}
-
-/*
-** When this function is called, *ppPoslist is assumed to point to the
-** start of a position-list. After it returns, *ppPoslist points to the
-** first byte after the position-list.
-**
-** A position list is list of positions (delta encoded) and columns for
-** a single document record of a doclist. So, in other words, this
-** routine advances *ppPoslist so that it points to the next docid in
-** the doclist, or to the first byte past the end of the doclist.
-**
-** If pp is not NULL, then the contents of the position list are copied
-** to *pp. *pp is set to point to the first byte past the last byte copied
-** before this function returns.
-*/
-static void fts3PoslistCopy(char **pp, char **ppPoslist){
- char *pEnd = *ppPoslist;
- char c = 0;
-
- /* The end of a position list is marked by a zero encoded as an FTS3
- ** varint. A single POS_END (0) byte. Except, if the 0 byte is preceded by
- ** a byte with the 0x80 bit set, then it is not a varint 0, but the tail
- ** of some other, multi-byte, value.
- **
- ** The following while-loop moves pEnd to point to the first byte that is not
- ** immediately preceded by a byte with the 0x80 bit set. Then increments
- ** pEnd once more so that it points to the byte immediately following the
- ** last byte in the position-list.
- */
- while( *pEnd | c ){
- c = *pEnd++ & 0x80;
- testcase( c!=0 && (*pEnd)==0 );
- }
- pEnd++; /* Advance past the POS_END terminator byte */
-
- if( pp ){
- int n = (int)(pEnd - *ppPoslist);
- char *p = *pp;
- memcpy(p, *ppPoslist, n);
- p += n;
- *pp = p;
- }
- *ppPoslist = pEnd;
-}
-
-/*
-** When this function is called, *ppPoslist is assumed to point to the
-** start of a column-list. After it returns, *ppPoslist points to the
-** to the terminator (POS_COLUMN or POS_END) byte of the column-list.
-**
-** A column-list is list of delta-encoded positions for a single column
-** within a single document within a doclist.
-**
-** The column-list is terminated either by a POS_COLUMN varint (1) or
-** a POS_END varint (0). This routine leaves *ppPoslist pointing to
-** the POS_COLUMN or POS_END that terminates the column-list.
-**
-** If pp is not NULL, then the contents of the column-list are copied
-** to *pp. *pp is set to point to the first byte past the last byte copied
-** before this function returns. The POS_COLUMN or POS_END terminator
-** is not copied into *pp.
-*/
-static void fts3ColumnlistCopy(char **pp, char **ppPoslist){
- char *pEnd = *ppPoslist;
- char c = 0;
-
- /* A column-list is terminated by either a 0x01 or 0x00 byte that is
- ** not part of a multi-byte varint.
- */
- while( 0xFE & (*pEnd | c) ){
- c = *pEnd++ & 0x80;
- testcase( c!=0 && ((*pEnd)&0xfe)==0 );
- }
- if( pp ){
- int n = (int)(pEnd - *ppPoslist);
- char *p = *pp;
- memcpy(p, *ppPoslist, n);
- p += n;
- *pp = p;
- }
- *ppPoslist = pEnd;
-}
-
-/*
-** Value used to signify the end of an position-list. This is safe because
-** it is not possible to have a document with 2^31 terms.
-*/
-#define POSITION_LIST_END 0x7fffffff
-
-/*
-** This function is used to help parse position-lists. When this function is
-** called, *pp may point to the start of the next varint in the position-list
-** being parsed, or it may point to 1 byte past the end of the position-list
-** (in which case **pp will be a terminator bytes POS_END (0) or
-** (1)).
-**
-** If *pp points past the end of the current position-list, set *pi to
-** POSITION_LIST_END and return. Otherwise, read the next varint from *pp,
-** increment the current value of *pi by the value read, and set *pp to
-** point to the next value before returning.
-**
-** Before calling this routine *pi must be initialized to the value of
-** the previous position, or zero if we are reading the first position
-** in the position-list. Because positions are delta-encoded, the value
-** of the previous position is needed in order to compute the value of
-** the next position.
-*/
-static void fts3ReadNextPos(
- char **pp, /* IN/OUT: Pointer into position-list buffer */
- sqlite3_int64 *pi /* IN/OUT: Value read from position-list */
-){
- if( (**pp)&0xFE ){
- fts3GetDeltaVarint(pp, pi);
- *pi -= 2;
- }else{
- *pi = POSITION_LIST_END;
- }
-}
-
-/*
-** If parameter iCol is not 0, write an POS_COLUMN (1) byte followed by
-** the value of iCol encoded as a varint to *pp. This will start a new
-** column list.
-**
-** Set *pp to point to the byte just after the last byte written before
-** returning (do not modify it if iCol==0). Return the total number of bytes
-** written (0 if iCol==0).
-*/
-static int fts3PutColNumber(char **pp, int iCol){
- int n = 0; /* Number of bytes written */
- if( iCol ){
- char *p = *pp; /* Output pointer */
- n = 1 + sqlite3Fts3PutVarint(&p[1], iCol);
- *p = 0x01;
- *pp = &p[n];
- }
- return n;
-}
-
-/*
-** Compute the union of two position lists. The output written
-** into *pp contains all positions of both *pp1 and *pp2 in sorted
-** order and with any duplicates removed. All pointers are
-** updated appropriately. The caller is responsible for insuring
-** that there is enough space in *pp to hold the complete output.
-*/
-static void fts3PoslistMerge(
- char **pp, /* Output buffer */
- char **pp1, /* Left input list */
- char **pp2 /* Right input list */
-){
- char *p = *pp;
- char *p1 = *pp1;
- char *p2 = *pp2;
-
- while( *p1 || *p2 ){
- int iCol1; /* The current column index in pp1 */
- int iCol2; /* The current column index in pp2 */
-
- if( *p1==POS_COLUMN ) sqlite3Fts3GetVarint32(&p1[1], &iCol1);
- else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
- else iCol1 = 0;
-
- if( *p2==POS_COLUMN ) sqlite3Fts3GetVarint32(&p2[1], &iCol2);
- else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
- else iCol2 = 0;
-
- if( iCol1==iCol2 ){
- sqlite3_int64 i1 = 0; /* Last position from pp1 */
- sqlite3_int64 i2 = 0; /* Last position from pp2 */
- sqlite3_int64 iPrev = 0;
- int n = fts3PutColNumber(&p, iCol1);
- p1 += n;
- p2 += n;
-
- /* At this point, both p1 and p2 point to the start of column-lists
- ** for the same column (the column with index iCol1 and iCol2).
- ** A column-list is a list of non-negative delta-encoded varints, each
- ** incremented by 2 before being stored. Each list is terminated by a
- ** POS_END (0) or POS_COLUMN (1). The following block merges the two lists
- ** and writes the results to buffer p. p is left pointing to the byte
- ** after the list written. No terminator (POS_END or POS_COLUMN) is
- ** written to the output.
- */
- fts3GetDeltaVarint(&p1, &i1);
- fts3GetDeltaVarint(&p2, &i2);
- do {
- fts3PutDeltaVarint(&p, &iPrev, (i1<i2) ? i1 : i2);
- iPrev -= 2;
- if( i1==i2 ){
- fts3ReadNextPos(&p1, &i1);
- fts3ReadNextPos(&p2, &i2);
- }else if( i1<i2 ){
- fts3ReadNextPos(&p1, &i1);
- }else{
- fts3ReadNextPos(&p2, &i2);
- }
- }while( i1!=POSITION_LIST_END || i2!=POSITION_LIST_END );
- }else if( iCol1<iCol2 ){
- p1 += fts3PutColNumber(&p, iCol1);
- fts3ColumnlistCopy(&p, &p1);
- }else{
- p2 += fts3PutColNumber(&p, iCol2);
- fts3ColumnlistCopy(&p, &p2);
- }
- }
-
- *p++ = POS_END;
- *pp = p;
- *pp1 = p1 + 1;
- *pp2 = p2 + 1;
-}
-
-/*
-** This function is used to merge two position lists into one. When it is
-** called, *pp1 and *pp2 must both point to position lists. A position-list is
-** the part of a doclist that follows each document id. For example, if a row
-** contains:
-**
-** 'a b c'|'x y z'|'a b b a'
-**
-** Then the position list for this row for token 'b' would consist of:
-**
-** 0x02 0x01 0x02 0x03 0x03 0x00
-**
-** When this function returns, both *pp1 and *pp2 are left pointing to the
-** byte following the 0x00 terminator of their respective position lists.
-**
-** If isSaveLeft is 0, an entry is added to the output position list for
-** each position in *pp2 for which there exists one or more positions in
-** *pp1 so that (pos(*pp2)>pos(*pp1) && pos(*pp2)-pos(*pp1)<=nToken). i.e.
-** when the *pp1 token appears before the *pp2 token, but not more than nToken
-** slots before it.
-**
-** e.g. nToken==1 searches for adjacent positions.
-*/
-static int fts3PoslistPhraseMerge(
- char **pp, /* IN/OUT: Preallocated output buffer */
- int nToken, /* Maximum difference in token positions */
- int isSaveLeft, /* Save the left position */
- int isExact, /* If *pp1 is exactly nTokens before *pp2 */
- char **pp1, /* IN/OUT: Left input list */
- char **pp2 /* IN/OUT: Right input list */
-){
- char *p = *pp;
- char *p1 = *pp1;
- char *p2 = *pp2;
- int iCol1 = 0;
- int iCol2 = 0;
-
- /* Never set both isSaveLeft and isExact for the same invocation. */
- assert( isSaveLeft==0 || isExact==0 );
-
- assert( p!=0 && *p1!=0 && *p2!=0 );
- if( *p1==POS_COLUMN ){
- p1++;
- p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
- }
- if( *p2==POS_COLUMN ){
- p2++;
- p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
- }
-
- while( 1 ){
- if( iCol1==iCol2 ){
- char *pSave = p;
- sqlite3_int64 iPrev = 0;
- sqlite3_int64 iPos1 = 0;
- sqlite3_int64 iPos2 = 0;
-
- if( iCol1 ){
- *p++ = POS_COLUMN;
- p += sqlite3Fts3PutVarint(p, iCol1);
- }
-
- assert( *p1!=POS_END && *p1!=POS_COLUMN );
- assert( *p2!=POS_END && *p2!=POS_COLUMN );
- fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2;
- fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
-
- while( 1 ){
- if( iPos2==iPos1+nToken
- || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken)
- ){
- sqlite3_int64 iSave;
- iSave = isSaveLeft ? iPos1 : iPos2;
- fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2;
- pSave = 0;
- assert( p );
- }
- if( (!isSaveLeft && iPos2<=(iPos1+nToken)) || iPos2<=iPos1 ){
- if( (*p2&0xFE)==0 ) break;
- fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
- }else{
- if( (*p1&0xFE)==0 ) break;
- fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2;
- }
- }
-
- if( pSave ){
- assert( pp && p );
- p = pSave;
- }
-
- fts3ColumnlistCopy(0, &p1);
- fts3ColumnlistCopy(0, &p2);
- assert( (*p1&0xFE)==0 && (*p2&0xFE)==0 );
- if( 0==*p1 || 0==*p2 ) break;
-
- p1++;
- p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
- p2++;
- p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
- }
-
- /* Advance pointer p1 or p2 (whichever corresponds to the smaller of
- ** iCol1 and iCol2) so that it points to either the 0x00 that marks the
- ** end of the position list, or the 0x01 that precedes the next
- ** column-number in the position list.
- */
- else if( iCol1<iCol2 ){
- fts3ColumnlistCopy(0, &p1);
- if( 0==*p1 ) break;
- p1++;
- p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
- }else{
- fts3ColumnlistCopy(0, &p2);
- if( 0==*p2 ) break;
- p2++;
- p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
- }
- }
-
- fts3PoslistCopy(0, &p2);
- fts3PoslistCopy(0, &p1);
- *pp1 = p1;
- *pp2 = p2;
- if( *pp==p ){
- return 0;
- }
- *p++ = 0x00;
- *pp = p;
- return 1;
-}
-
-/*
-** Merge two position-lists as required by the NEAR operator. The argument
-** position lists correspond to the left and right phrases of an expression
-** like:
-**
-** "phrase 1" NEAR "phrase number 2"
-**
-** Position list *pp1 corresponds to the left-hand side of the NEAR
-** expression and *pp2 to the right. As usual, the indexes in the position
-** lists are the offsets of the last token in each phrase (tokens "1" and "2"
-** in the example above).
-**
-** The output position list - written to *pp - is a copy of *pp2 with those
-** entries that are not sufficiently NEAR entries in *pp1 removed.
-*/
-static int fts3PoslistNearMerge(
- char **pp, /* Output buffer */
- char *aTmp, /* Temporary buffer space */
- int nRight, /* Maximum difference in token positions */
- int nLeft, /* Maximum difference in token positions */
- char **pp1, /* IN/OUT: Left input list */
- char **pp2 /* IN/OUT: Right input list */
-){
- char *p1 = *pp1;
- char *p2 = *pp2;
-
- char *pTmp1 = aTmp;
- char *pTmp2;
- char *aTmp2;
- int res = 1;
-
- fts3PoslistPhraseMerge(&pTmp1, nRight, 0, 0, pp1, pp2);
- aTmp2 = pTmp2 = pTmp1;
- *pp1 = p1;
- *pp2 = p2;
- fts3PoslistPhraseMerge(&pTmp2, nLeft, 1, 0, pp2, pp1);
- if( pTmp1!=aTmp && pTmp2!=aTmp2 ){
- fts3PoslistMerge(pp, &aTmp, &aTmp2);
- }else if( pTmp1!=aTmp ){
- fts3PoslistCopy(pp, &aTmp);
- }else if( pTmp2!=aTmp2 ){
- fts3PoslistCopy(pp, &aTmp2);
- }else{
- res = 0;
- }
-
- return res;
-}
-
-/*
-** An instance of this function is used to merge together the (potentially
-** large number of) doclists for each term that matches a prefix query.
-** See function fts3TermSelectMerge() for details.
-*/
-typedef struct TermSelect TermSelect;
-struct TermSelect {
- char *aaOutput[16]; /* Malloc'd output buffers */
- int anOutput[16]; /* Size each output buffer in bytes */
-};
-
-/*
-** This function is used to read a single varint from a buffer. Parameter
-** pEnd points 1 byte past the end of the buffer. When this function is
-** called, if *pp points to pEnd or greater, then the end of the buffer
-** has been reached. In this case *pp is set to 0 and the function returns.
-**
-** If *pp does not point to or past pEnd, then a single varint is read
-** from *pp. *pp is then set to point 1 byte past the end of the read varint.
-**
-** If bDescIdx is false, the value read is added to *pVal before returning.
-** If it is true, the value read is subtracted from *pVal before this
-** function returns.
-*/
-static void fts3GetDeltaVarint3(
- char **pp, /* IN/OUT: Point to read varint from */
- char *pEnd, /* End of buffer */
- int bDescIdx, /* True if docids are descending */
- sqlite3_int64 *pVal /* IN/OUT: Integer value */
-){
- if( *pp>=pEnd ){
- *pp = 0;
- }else{
- sqlite3_int64 iVal;
- *pp += sqlite3Fts3GetVarint(*pp, &iVal);
- if( bDescIdx ){
- *pVal -= iVal;
- }else{
- *pVal += iVal;
- }
- }
-}
-
-/*
-** This function is used to write a single varint to a buffer. The varint
-** is written to *pp. Before returning, *pp is set to point 1 byte past the
-** end of the value written.
-**
-** If *pbFirst is zero when this function is called, the value written to
-** the buffer is that of parameter iVal.
-**
-** If *pbFirst is non-zero when this function is called, then the value
-** written is either (iVal-*piPrev) (if bDescIdx is zero) or (*piPrev-iVal)
-** (if bDescIdx is non-zero).
-**
-** Before returning, this function always sets *pbFirst to 1 and *piPrev
-** to the value of parameter iVal.
-*/
-static void fts3PutDeltaVarint3(
- char **pp, /* IN/OUT: Output pointer */
- int bDescIdx, /* True for descending docids */
- sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */
- int *pbFirst, /* IN/OUT: True after first int written */
- sqlite3_int64 iVal /* Write this value to the list */
-){
- sqlite3_int64 iWrite;
- if( bDescIdx==0 || *pbFirst==0 ){
- iWrite = iVal - *piPrev;
- }else{
- iWrite = *piPrev - iVal;
- }
- assert( *pbFirst || *piPrev==0 );
- assert( *pbFirst==0 || iWrite>0 );
- *pp += sqlite3Fts3PutVarint(*pp, iWrite);
- *piPrev = iVal;
- *pbFirst = 1;
-}
-
-
-/*
-** This macro is used by various functions that merge doclists. The two
-** arguments are 64-bit docid values. If the value of the stack variable
-** bDescDoclist is 0 when this macro is invoked, then it returns (i1-i2).
-** Otherwise, (i2-i1).
-**
-** Using this makes it easier to write code that can merge doclists that are
-** sorted in either ascending or descending order.
-*/
-#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1-i2))
-
-/*
-** This function does an "OR" merge of two doclists (output contains all
-** positions contained in either argument doclist). If the docids in the
-** input doclists are sorted in ascending order, parameter bDescDoclist
-** should be false. If they are sorted in ascending order, it should be
-** passed a non-zero value.
-**
-** If no error occurs, *paOut is set to point at an sqlite3_malloc'd buffer
-** containing the output doclist and SQLITE_OK is returned. In this case
-** *pnOut is set to the number of bytes in the output doclist.
-**
-** If an error occurs, an SQLite error code is returned. The output values
-** are undefined in this case.
-*/
-static int fts3DoclistOrMerge(
- int bDescDoclist, /* True if arguments are desc */
- char *a1, int n1, /* First doclist */
- char *a2, int n2, /* Second doclist */
- char **paOut, int *pnOut /* OUT: Malloc'd doclist */
-){
- sqlite3_int64 i1 = 0;
- sqlite3_int64 i2 = 0;
- sqlite3_int64 iPrev = 0;
- char *pEnd1 = &a1[n1];
- char *pEnd2 = &a2[n2];
- char *p1 = a1;
- char *p2 = a2;
- char *p;
- char *aOut;
- int bFirstOut = 0;
-
- *paOut = 0;
- *pnOut = 0;
-
- /* Allocate space for the output. Both the input and output doclists
- ** are delta encoded. If they are in ascending order (bDescDoclist==0),
- ** then the first docid in each list is simply encoded as a varint. For
- ** each subsequent docid, the varint stored is the difference between the
- ** current and previous docid (a positive number - since the list is in
- ** ascending order).
- **
- ** The first docid written to the output is therefore encoded using the
- ** same number of bytes as it is in whichever of the input lists it is
- ** read from. And each subsequent docid read from the same input list
- ** consumes either the same or less bytes as it did in the input (since
- ** the difference between it and the previous value in the output must
- ** be a positive value less than or equal to the delta value read from
- ** the input list). The same argument applies to all but the first docid
- ** read from the 'other' list. And to the contents of all position lists
- ** that will be copied and merged from the input to the output.
- **
- ** However, if the first docid copied to the output is a negative number,
- ** then the encoding of the first docid from the 'other' input list may
- ** be larger in the output than it was in the input (since the delta value
- ** may be a larger positive integer than the actual docid).
- **
- ** The space required to store the output is therefore the sum of the
- ** sizes of the two inputs, plus enough space for exactly one of the input
- ** docids to grow.
- **
- ** A symetric argument may be made if the doclists are in descending
- ** order.
- */
- aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1);
- if( !aOut ) return SQLITE_NOMEM;
-
- p = aOut;
- fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1);
- fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2);
- while( p1 || p2 ){
- sqlite3_int64 iDiff = DOCID_CMP(i1, i2);
-
- if( p2 && p1 && iDiff==0 ){
- fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1);
- fts3PoslistMerge(&p, &p1, &p2);
- fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
- fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
- }else if( !p2 || (p1 && iDiff<0) ){
- fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1);
- fts3PoslistCopy(&p, &p1);
- fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
- }else{
- fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i2);
- fts3PoslistCopy(&p, &p2);
- fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
- }
- }
-
- *paOut = aOut;
- *pnOut = (int)(p-aOut);
- assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 );
- return SQLITE_OK;
-}
-
-/*
-** This function does a "phrase" merge of two doclists. In a phrase merge,
-** the output contains a copy of each position from the right-hand input
-** doclist for which there is a position in the left-hand input doclist
-** exactly nDist tokens before it.
-**
-** If the docids in the input doclists are sorted in ascending order,
-** parameter bDescDoclist should be false. If they are sorted in ascending
-** order, it should be passed a non-zero value.
-**
-** The right-hand input doclist is overwritten by this function.
-*/
-static void fts3DoclistPhraseMerge(
- int bDescDoclist, /* True if arguments are desc */
- int nDist, /* Distance from left to right (1=adjacent) */
- char *aLeft, int nLeft, /* Left doclist */
- char *aRight, int *pnRight /* IN/OUT: Right/output doclist */
-){
- sqlite3_int64 i1 = 0;
- sqlite3_int64 i2 = 0;
- sqlite3_int64 iPrev = 0;
- char *pEnd1 = &aLeft[nLeft];
- char *pEnd2 = &aRight[*pnRight];
- char *p1 = aLeft;
- char *p2 = aRight;
- char *p;
- int bFirstOut = 0;
- char *aOut = aRight;
-
- assert( nDist>0 );
-
- p = aOut;
- fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1);
- fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2);
-
- while( p1 && p2 ){
- sqlite3_int64 iDiff = DOCID_CMP(i1, i2);
- if( iDiff==0 ){
- char *pSave = p;
- sqlite3_int64 iPrevSave = iPrev;
- int bFirstOutSave = bFirstOut;
-
- fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1);
- if( 0==fts3PoslistPhraseMerge(&p, nDist, 0, 1, &p1, &p2) ){
- p = pSave;
- iPrev = iPrevSave;
- bFirstOut = bFirstOutSave;
- }
- fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
- fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
- }else if( iDiff<0 ){
- fts3PoslistCopy(0, &p1);
- fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1);
- }else{
- fts3PoslistCopy(0, &p2);
- fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2);
- }
- }
-
- *pnRight = (int)(p - aOut);
-}
-
-/*
-** Argument pList points to a position list nList bytes in size. This
-** function checks to see if the position list contains any entries for
-** a token in position 0 (of any column). If so, it writes argument iDelta
-** to the output buffer pOut, followed by a position list consisting only
-** of the entries from pList at position 0, and terminated by an 0x00 byte.
-** The value returned is the number of bytes written to pOut (if any).
-*/
-SQLITE_PRIVATE int sqlite3Fts3FirstFilter(
- sqlite3_int64 iDelta, /* Varint that may be written to pOut */
- char *pList, /* Position list (no 0x00 term) */
- int nList, /* Size of pList in bytes */
- char *pOut /* Write output here */
-){
- int nOut = 0;
- int bWritten = 0; /* True once iDelta has been written */
- char *p = pList;
- char *pEnd = &pList[nList];
-
- if( *p!=0x01 ){
- if( *p==0x02 ){
- nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta);
- pOut[nOut++] = 0x02;
- bWritten = 1;
- }
- fts3ColumnlistCopy(0, &p);
- }
-
- while( p<pEnd && *p==0x01 ){
- sqlite3_int64 iCol;
- p++;
- p += sqlite3Fts3GetVarint(p, &iCol);
- if( *p==0x02 ){
- if( bWritten==0 ){
- nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta);
- bWritten = 1;
- }
- pOut[nOut++] = 0x01;
- nOut += sqlite3Fts3PutVarint(&pOut[nOut], iCol);
- pOut[nOut++] = 0x02;
- }
- fts3ColumnlistCopy(0, &p);
- }
- if( bWritten ){
- pOut[nOut++] = 0x00;
- }
-
- return nOut;
-}
-
-
-/*
-** Merge all doclists in the TermSelect.aaOutput[] array into a single
-** doclist stored in TermSelect.aaOutput[0]. If successful, delete all
-** other doclists (except the aaOutput[0] one) and return SQLITE_OK.
-**
-** If an OOM error occurs, return SQLITE_NOMEM. In this case it is
-** the responsibility of the caller to free any doclists left in the
-** TermSelect.aaOutput[] array.
-*/
-static int fts3TermSelectFinishMerge(Fts3Table *p, TermSelect *pTS){
- char *aOut = 0;
- int nOut = 0;
- int i;
-
- /* Loop through the doclists in the aaOutput[] array. Merge them all
- ** into a single doclist.
- */
- for(i=0; i<SizeofArray(pTS->aaOutput); i++){
- if( pTS->aaOutput[i] ){
- if( !aOut ){
- aOut = pTS->aaOutput[i];
- nOut = pTS->anOutput[i];
- pTS->aaOutput[i] = 0;
- }else{
- int nNew;
- char *aNew;
-
- int rc = fts3DoclistOrMerge(p->bDescIdx,
- pTS->aaOutput[i], pTS->anOutput[i], aOut, nOut, &aNew, &nNew
- );
- if( rc!=SQLITE_OK ){
- sqlite3_free(aOut);
- return rc;
- }
-
- sqlite3_free(pTS->aaOutput[i]);
- sqlite3_free(aOut);
- pTS->aaOutput[i] = 0;
- aOut = aNew;
- nOut = nNew;
- }
- }
- }
-
- pTS->aaOutput[0] = aOut;
- pTS->anOutput[0] = nOut;
- return SQLITE_OK;
-}
-
-/*
-** Merge the doclist aDoclist/nDoclist into the TermSelect object passed
-** as the first argument. The merge is an "OR" merge (see function
-** fts3DoclistOrMerge() for details).
-**
-** This function is called with the doclist for each term that matches
-** a queried prefix. It merges all these doclists into one, the doclist
-** for the specified prefix. Since there can be a very large number of
-** doclists to merge, the merging is done pair-wise using the TermSelect
-** object.
-**
-** This function returns SQLITE_OK if the merge is successful, or an
-** SQLite error code (SQLITE_NOMEM) if an error occurs.
-*/
-static int fts3TermSelectMerge(
- Fts3Table *p, /* FTS table handle */
- TermSelect *pTS, /* TermSelect object to merge into */
- char *aDoclist, /* Pointer to doclist */
- int nDoclist /* Size of aDoclist in bytes */
-){
- if( pTS->aaOutput[0]==0 ){
- /* If this is the first term selected, copy the doclist to the output
- ** buffer using memcpy(). */
- pTS->aaOutput[0] = sqlite3_malloc(nDoclist);
- pTS->anOutput[0] = nDoclist;
- if( pTS->aaOutput[0] ){
- memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
- }else{
- return SQLITE_NOMEM;
- }
- }else{
- char *aMerge = aDoclist;
- int nMerge = nDoclist;
- int iOut;
-
- for(iOut=0; iOut<SizeofArray(pTS->aaOutput); iOut++){
- if( pTS->aaOutput[iOut]==0 ){
- assert( iOut>0 );
- pTS->aaOutput[iOut] = aMerge;
- pTS->anOutput[iOut] = nMerge;
- break;
- }else{
- char *aNew;
- int nNew;
-
- int rc = fts3DoclistOrMerge(p->bDescIdx, aMerge, nMerge,
- pTS->aaOutput[iOut], pTS->anOutput[iOut], &aNew, &nNew
- );
- if( rc!=SQLITE_OK ){
- if( aMerge!=aDoclist ) sqlite3_free(aMerge);
- return rc;
- }
-
- if( aMerge!=aDoclist ) sqlite3_free(aMerge);
- sqlite3_free(pTS->aaOutput[iOut]);
- pTS->aaOutput[iOut] = 0;
-
- aMerge = aNew;
- nMerge = nNew;
- if( (iOut+1)==SizeofArray(pTS->aaOutput) ){
- pTS->aaOutput[iOut] = aMerge;
- pTS->anOutput[iOut] = nMerge;
- }
- }
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** Append SegReader object pNew to the end of the pCsr->apSegment[] array.
-*/
-static int fts3SegReaderCursorAppend(
- Fts3MultiSegReader *pCsr,
- Fts3SegReader *pNew
-){
- if( (pCsr->nSegment%16)==0 ){
- Fts3SegReader **apNew;
- int nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*);
- apNew = (Fts3SegReader **)sqlite3_realloc(pCsr->apSegment, nByte);
- if( !apNew ){
- sqlite3Fts3SegReaderFree(pNew);
- return SQLITE_NOMEM;
- }
- pCsr->apSegment = apNew;
- }
- pCsr->apSegment[pCsr->nSegment++] = pNew;
- return SQLITE_OK;
-}
-
-/*
-** Add seg-reader objects to the Fts3MultiSegReader object passed as the
-** 8th argument.
-**
-** This function returns SQLITE_OK if successful, or an SQLite error code
-** otherwise.
-*/
-static int fts3SegReaderCursor(
- Fts3Table *p, /* FTS3 table handle */
- int iLangid, /* Language id */
- int iIndex, /* Index to search (from 0 to p->nIndex-1) */
- int iLevel, /* Level of segments to scan */
- const char *zTerm, /* Term to query for */
- int nTerm, /* Size of zTerm in bytes */
- int isPrefix, /* True for a prefix search */
- int isScan, /* True to scan from zTerm to EOF */
- Fts3MultiSegReader *pCsr /* Cursor object to populate */
-){
- int rc = SQLITE_OK; /* Error code */
- sqlite3_stmt *pStmt = 0; /* Statement to iterate through segments */
- int rc2; /* Result of sqlite3_reset() */
-
- /* If iLevel is less than 0 and this is not a scan, include a seg-reader
- ** for the pending-terms. If this is a scan, then this call must be being
- ** made by an fts4aux module, not an FTS table. In this case calling
- ** Fts3SegReaderPending might segfault, as the data structures used by
- ** fts4aux are not completely populated. So it's easiest to filter these
- ** calls out here. */
- if( iLevel<0 && p->aIndex ){
- Fts3SegReader *pSeg = 0;
- rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg);
- if( rc==SQLITE_OK && pSeg ){
- rc = fts3SegReaderCursorAppend(pCsr, pSeg);
- }
- }
-
- if( iLevel!=FTS3_SEGCURSOR_PENDING ){
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts3AllSegdirs(p, iLangid, iIndex, iLevel, &pStmt);
- }
-
- while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
- Fts3SegReader *pSeg = 0;
-
- /* Read the values returned by the SELECT into local variables. */
- sqlite3_int64 iStartBlock = sqlite3_column_int64(pStmt, 1);
- sqlite3_int64 iLeavesEndBlock = sqlite3_column_int64(pStmt, 2);
- sqlite3_int64 iEndBlock = sqlite3_column_int64(pStmt, 3);
- int nRoot = sqlite3_column_bytes(pStmt, 4);
- char const *zRoot = sqlite3_column_blob(pStmt, 4);
-
- /* If zTerm is not NULL, and this segment is not stored entirely on its
- ** root node, the range of leaves scanned can be reduced. Do this. */
- if( iStartBlock && zTerm ){
- sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0);
- rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi);
- if( rc!=SQLITE_OK ) goto finished;
- if( isPrefix==0 && isScan==0 ) iLeavesEndBlock = iStartBlock;
- }
-
- rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1,
- (isPrefix==0 && isScan==0),
- iStartBlock, iLeavesEndBlock,
- iEndBlock, zRoot, nRoot, &pSeg
- );
- if( rc!=SQLITE_OK ) goto finished;
- rc = fts3SegReaderCursorAppend(pCsr, pSeg);
- }
- }
-
- finished:
- rc2 = sqlite3_reset(pStmt);
- if( rc==SQLITE_DONE ) rc = rc2;
-
- return rc;
-}
-
-/*
-** Set up a cursor object for iterating through a full-text index or a
-** single level therein.
-*/
-SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor(
- Fts3Table *p, /* FTS3 table handle */
- int iLangid, /* Language-id to search */
- int iIndex, /* Index to search (from 0 to p->nIndex-1) */
- int iLevel, /* Level of segments to scan */
- const char *zTerm, /* Term to query for */
- int nTerm, /* Size of zTerm in bytes */
- int isPrefix, /* True for a prefix search */
- int isScan, /* True to scan from zTerm to EOF */
- Fts3MultiSegReader *pCsr /* Cursor object to populate */
-){
- assert( iIndex>=0 && iIndex<p->nIndex );
- assert( iLevel==FTS3_SEGCURSOR_ALL
- || iLevel==FTS3_SEGCURSOR_PENDING
- || iLevel>=0
- );
- assert( iLevel<FTS3_SEGDIR_MAXLEVEL );
- assert( FTS3_SEGCURSOR_ALL<0 && FTS3_SEGCURSOR_PENDING<0 );
- assert( isPrefix==0 || isScan==0 );
-
- memset(pCsr, 0, sizeof(Fts3MultiSegReader));
- return fts3SegReaderCursor(
- p, iLangid, iIndex, iLevel, zTerm, nTerm, isPrefix, isScan, pCsr
- );
-}
-
-/*
-** In addition to its current configuration, have the Fts3MultiSegReader
-** passed as the 4th argument also scan the doclist for term zTerm/nTerm.
-**
-** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
-*/
-static int fts3SegReaderCursorAddZero(
- Fts3Table *p, /* FTS virtual table handle */
- int iLangid,
- const char *zTerm, /* Term to scan doclist of */
- int nTerm, /* Number of bytes in zTerm */
- Fts3MultiSegReader *pCsr /* Fts3MultiSegReader to modify */
-){
- return fts3SegReaderCursor(p,
- iLangid, 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0,pCsr
- );
-}
-
-/*
-** Open an Fts3MultiSegReader to scan the doclist for term zTerm/nTerm. Or,
-** if isPrefix is true, to scan the doclist for all terms for which
-** zTerm/nTerm is a prefix. If successful, return SQLITE_OK and write
-** a pointer to the new Fts3MultiSegReader to *ppSegcsr. Otherwise, return
-** an SQLite error code.
-**
-** It is the responsibility of the caller to free this object by eventually
-** passing it to fts3SegReaderCursorFree()
-**
-** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
-** Output parameter *ppSegcsr is set to 0 if an error occurs.
-*/
-static int fts3TermSegReaderCursor(
- Fts3Cursor *pCsr, /* Virtual table cursor handle */
- const char *zTerm, /* Term to query for */
- int nTerm, /* Size of zTerm in bytes */
- int isPrefix, /* True for a prefix search */
- Fts3MultiSegReader **ppSegcsr /* OUT: Allocated seg-reader cursor */
-){
- Fts3MultiSegReader *pSegcsr; /* Object to allocate and return */
- int rc = SQLITE_NOMEM; /* Return code */
-
- pSegcsr = sqlite3_malloc(sizeof(Fts3MultiSegReader));
- if( pSegcsr ){
- int i;
- int bFound = 0; /* True once an index has been found */
- Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
-
- if( isPrefix ){
- for(i=1; bFound==0 && i<p->nIndex; i++){
- if( p->aIndex[i].nPrefix==nTerm ){
- bFound = 1;
- rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid,
- i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr
- );
- pSegcsr->bLookup = 1;
- }
- }
-
- for(i=1; bFound==0 && i<p->nIndex; i++){
- if( p->aIndex[i].nPrefix==nTerm+1 ){
- bFound = 1;
- rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid,
- i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr
- );
- if( rc==SQLITE_OK ){
- rc = fts3SegReaderCursorAddZero(
- p, pCsr->iLangid, zTerm, nTerm, pSegcsr
- );
- }
- }
- }
- }
-
- if( bFound==0 ){
- rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid,
- 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, isPrefix, 0, pSegcsr
- );
- pSegcsr->bLookup = !isPrefix;
- }
- }
-
- *ppSegcsr = pSegcsr;
- return rc;
-}
-
-/*
-** Free an Fts3MultiSegReader allocated by fts3TermSegReaderCursor().
-*/
-static void fts3SegReaderCursorFree(Fts3MultiSegReader *pSegcsr){
- sqlite3Fts3SegReaderFinish(pSegcsr);
- sqlite3_free(pSegcsr);
-}
-
-/*
-** This function retreives the doclist for the specified term (or term
-** prefix) from the database.
-*/
-static int fts3TermSelect(
- Fts3Table *p, /* Virtual table handle */
- Fts3PhraseToken *pTok, /* Token to query for */
- int iColumn, /* Column to query (or -ve for all columns) */
- int *pnOut, /* OUT: Size of buffer at *ppOut */
- char **ppOut /* OUT: Malloced result buffer */
-){
- int rc; /* Return code */
- Fts3MultiSegReader *pSegcsr; /* Seg-reader cursor for this term */
- TermSelect tsc; /* Object for pair-wise doclist merging */
- Fts3SegFilter filter; /* Segment term filter configuration */
-
- pSegcsr = pTok->pSegcsr;
- memset(&tsc, 0, sizeof(TermSelect));
-
- filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS
- | (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0)
- | (pTok->bFirst ? FTS3_SEGMENT_FIRST : 0)
- | (iColumn<p->nColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0);
- filter.iCol = iColumn;
- filter.zTerm = pTok->z;
- filter.nTerm = pTok->n;
-
- rc = sqlite3Fts3SegReaderStart(p, pSegcsr, &filter);
- while( SQLITE_OK==rc
- && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pSegcsr))
- ){
- rc = fts3TermSelectMerge(p, &tsc, pSegcsr->aDoclist, pSegcsr->nDoclist);
- }
-
- if( rc==SQLITE_OK ){
- rc = fts3TermSelectFinishMerge(p, &tsc);
- }
- if( rc==SQLITE_OK ){
- *ppOut = tsc.aaOutput[0];
- *pnOut = tsc.anOutput[0];
- }else{
- int i;
- for(i=0; i<SizeofArray(tsc.aaOutput); i++){
- sqlite3_free(tsc.aaOutput[i]);
- }
- }
-
- fts3SegReaderCursorFree(pSegcsr);
- pTok->pSegcsr = 0;
- return rc;
-}
-
-/*
-** This function counts the total number of docids in the doclist stored
-** in buffer aList[], size nList bytes.
-**
-** If the isPoslist argument is true, then it is assumed that the doclist
-** contains a position-list following each docid. Otherwise, it is assumed
-** that the doclist is simply a list of docids stored as delta encoded
-** varints.
-*/
-static int fts3DoclistCountDocids(char *aList, int nList){
- int nDoc = 0; /* Return value */
- if( aList ){
- char *aEnd = &aList[nList]; /* Pointer to one byte after EOF */
- char *p = aList; /* Cursor */
- while( p<aEnd ){
- nDoc++;
- while( (*p++)&0x80 ); /* Skip docid varint */
- fts3PoslistCopy(0, &p); /* Skip over position list */
- }
- }
-
- return nDoc;
-}
-
-/*
-** Advance the cursor to the next row in the %_content table that
-** matches the search criteria. For a MATCH search, this will be
-** the next row that matches. For a full-table scan, this will be
-** simply the next row in the %_content table. For a docid lookup,
-** this routine simply sets the EOF flag.
-**
-** Return SQLITE_OK if nothing goes wrong. SQLITE_OK is returned
-** even if we reach end-of-file. The fts3EofMethod() will be called
-** subsequently to determine whether or not an EOF was hit.
-*/
-static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){
- int rc;
- Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
- if( pCsr->eSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){
- if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){
- pCsr->isEof = 1;
- rc = sqlite3_reset(pCsr->pStmt);
- }else{
- pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0);
- rc = SQLITE_OK;
- }
- }else{
- rc = fts3EvalNext((Fts3Cursor *)pCursor);
- }
- assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
- return rc;
-}
-
-/*
-** This is the xFilter interface for the virtual table. See
-** the virtual table xFilter method documentation for additional
-** information.
-**
-** If idxNum==FTS3_FULLSCAN_SEARCH then do a full table scan against
-** the %_content table.
-**
-** If idxNum==FTS3_DOCID_SEARCH then do a docid lookup for a single entry
-** in the %_content table.
-**
-** If idxNum>=FTS3_FULLTEXT_SEARCH then use the full text index. The
-** column on the left-hand side of the MATCH operator is column
-** number idxNum-FTS3_FULLTEXT_SEARCH, 0 indexed. argv[0] is the right-hand
-** side of the MATCH operator.
-*/
-static int fts3FilterMethod(
- sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
- int idxNum, /* Strategy index */
- const char *idxStr, /* Unused */
- int nVal, /* Number of elements in apVal */
- sqlite3_value **apVal /* Arguments for the indexing scheme */
-){
- int rc;
- char *zSql; /* SQL statement used to access %_content */
- Fts3Table *p = (Fts3Table *)pCursor->pVtab;
- Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
-
- UNUSED_PARAMETER(idxStr);
- UNUSED_PARAMETER(nVal);
-
- assert( idxNum>=0 && idxNum<=(FTS3_FULLTEXT_SEARCH+p->nColumn) );
- assert( nVal==0 || nVal==1 || nVal==2 );
- assert( (nVal==0)==(idxNum==FTS3_FULLSCAN_SEARCH) );
- assert( p->pSegments==0 );
-
- /* In case the cursor has been used before, clear it now. */
- sqlite3_finalize(pCsr->pStmt);
- sqlite3_free(pCsr->aDoclist);
- sqlite3Fts3ExprFree(pCsr->pExpr);
- memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
-
- if( idxStr ){
- pCsr->bDesc = (idxStr[0]=='D');
- }else{
- pCsr->bDesc = p->bDescIdx;
- }
- pCsr->eSearch = (i16)idxNum;
-
- if( idxNum!=FTS3_DOCID_SEARCH && idxNum!=FTS3_FULLSCAN_SEARCH ){
- int iCol = idxNum-FTS3_FULLTEXT_SEARCH;
- const char *zQuery = (const char *)sqlite3_value_text(apVal[0]);
-
- if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
- return SQLITE_NOMEM;
- }
-
- pCsr->iLangid = 0;
- if( nVal==2 ) pCsr->iLangid = sqlite3_value_int(apVal[1]);
-
- rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid,
- p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr
- );
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_ERROR ){
- static const char *zErr = "malformed MATCH expression: [%s]";
- p->base.zErrMsg = sqlite3_mprintf(zErr, zQuery);
- }
- return rc;
- }
-
- rc = sqlite3Fts3ReadLock(p);
- if( rc!=SQLITE_OK ) return rc;
-
- rc = fts3EvalStart(pCsr);
-
- sqlite3Fts3SegmentsClose(p);
- if( rc!=SQLITE_OK ) return rc;
- pCsr->pNextId = pCsr->aDoclist;
- pCsr->iPrevId = 0;
- }
-
- /* Compile a SELECT statement for this cursor. For a full-table-scan, the
- ** statement loops through all rows of the %_content table. For a
- ** full-text query or docid lookup, the statement retrieves a single
- ** row by docid.
- */
- if( idxNum==FTS3_FULLSCAN_SEARCH ){
- zSql = sqlite3_mprintf(
- "SELECT %s ORDER BY rowid %s",
- p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
- );
- if( zSql ){
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
- sqlite3_free(zSql);
- }else{
- rc = SQLITE_NOMEM;
- }
- }else if( idxNum==FTS3_DOCID_SEARCH ){
- rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
- if( rc==SQLITE_OK ){
- rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
- }
- }
- if( rc!=SQLITE_OK ) return rc;
-
- return fts3NextMethod(pCursor);
-}
-
-/*
-** This is the xEof method of the virtual table. SQLite calls this
-** routine to find out if it has reached the end of a result set.
-*/
-static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){
- return ((Fts3Cursor *)pCursor)->isEof;
-}
-
-/*
-** This is the xRowid method. The SQLite core calls this routine to
-** retrieve the rowid for the current row of the result set. fts3
-** exposes %_content.docid as the rowid for the virtual table. The
-** rowid should be written to *pRowid.
-*/
-static int fts3RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
- Fts3Cursor *pCsr = (Fts3Cursor *) pCursor;
- *pRowid = pCsr->iPrevId;
- return SQLITE_OK;
-}
-
-/*
-** This is the xColumn method, called by SQLite to request a value from
-** the row that the supplied cursor currently points to.
-**
-** If:
-**
-** (iCol < p->nColumn) -> The value of the iCol'th user column.
-** (iCol == p->nColumn) -> Magic column with the same name as the table.
-** (iCol == p->nColumn+1) -> Docid column
-** (iCol == p->nColumn+2) -> Langid column
-*/
-static int fts3ColumnMethod(
- sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
- sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
- int iCol /* Index of column to read value from */
-){
- int rc = SQLITE_OK; /* Return Code */
- Fts3Cursor *pCsr = (Fts3Cursor *) pCursor;
- Fts3Table *p = (Fts3Table *)pCursor->pVtab;
-
- /* The column value supplied by SQLite must be in range. */
- assert( iCol>=0 && iCol<=p->nColumn+2 );
-
- if( iCol==p->nColumn+1 ){
- /* This call is a request for the "docid" column. Since "docid" is an
- ** alias for "rowid", use the xRowid() method to obtain the value.
- */
- sqlite3_result_int64(pCtx, pCsr->iPrevId);
- }else if( iCol==p->nColumn ){
- /* The extra column whose name is the same as the table.
- ** Return a blob which is a pointer to the cursor. */
- sqlite3_result_blob(pCtx, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
- }else if( iCol==p->nColumn+2 && pCsr->pExpr ){
- sqlite3_result_int64(pCtx, pCsr->iLangid);
- }else{
- /* The requested column is either a user column (one that contains
- ** indexed data), or the language-id column. */
- rc = fts3CursorSeek(0, pCsr);
-
- if( rc==SQLITE_OK ){
- if( iCol==p->nColumn+2 ){
- int iLangid = 0;
- if( p->zLanguageid ){
- iLangid = sqlite3_column_int(pCsr->pStmt, p->nColumn+1);
- }
- sqlite3_result_int(pCtx, iLangid);
- }else if( sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){
- sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1));
- }
- }
- }
-
- assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
- return rc;
-}
-
-/*
-** This function is the implementation of the xUpdate callback used by
-** FTS3 virtual tables. It is invoked by SQLite each time a row is to be
-** inserted, updated or deleted.
-*/
-static int fts3UpdateMethod(
- sqlite3_vtab *pVtab, /* Virtual table handle */
- int nArg, /* Size of argument array */
- sqlite3_value **apVal, /* Array of arguments */
- sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
-){
- return sqlite3Fts3UpdateMethod(pVtab, nArg, apVal, pRowid);
-}
-
-/*
-** Implementation of xSync() method. Flush the contents of the pending-terms
-** hash-table to the database.
-*/
-static int fts3SyncMethod(sqlite3_vtab *pVtab){
-
- /* Following an incremental-merge operation, assuming that the input
- ** segments are not completely consumed (the usual case), they are updated
- ** in place to remove the entries that have already been merged. This
- ** involves updating the leaf block that contains the smallest unmerged
- ** entry and each block (if any) between the leaf and the root node. So
- ** if the height of the input segment b-trees is N, and input segments
- ** are merged eight at a time, updating the input segments at the end
- ** of an incremental-merge requires writing (8*(1+N)) blocks. N is usually
- ** small - often between 0 and 2. So the overhead of the incremental
- ** merge is somewhere between 8 and 24 blocks. To avoid this overhead
- ** dwarfing the actual productive work accomplished, the incremental merge
- ** is only attempted if it will write at least 64 leaf blocks. Hence
- ** nMinMerge.
- **
- ** Of course, updating the input segments also involves deleting a bunch
- ** of blocks from the segments table. But this is not considered overhead
- ** as it would also be required by a crisis-merge that used the same input
- ** segments.
- */
- const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */
-
- Fts3Table *p = (Fts3Table*)pVtab;
- int rc = sqlite3Fts3PendingTermsFlush(p);
-
- if( rc==SQLITE_OK && p->bAutoincrmerge==1 && p->nLeafAdd>(nMinMerge/16) ){
- int mxLevel = 0; /* Maximum relative level value in db */
- int A; /* Incr-merge parameter A */
-
- rc = sqlite3Fts3MaxLevel(p, &mxLevel);
- assert( rc==SQLITE_OK || mxLevel==0 );
- A = p->nLeafAdd * mxLevel;
- A += (A/2);
- if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, 8);
- }
- sqlite3Fts3SegmentsClose(p);
- return rc;
-}
-
-/*
-** Implementation of xBegin() method. This is a no-op.
-*/
-static int fts3BeginMethod(sqlite3_vtab *pVtab){
- Fts3Table *p = (Fts3Table*)pVtab;
- UNUSED_PARAMETER(pVtab);
- assert( p->pSegments==0 );
- assert( p->nPendingData==0 );
- assert( p->inTransaction!=1 );
- TESTONLY( p->inTransaction = 1 );
- TESTONLY( p->mxSavepoint = -1; );
- p->nLeafAdd = 0;
- return SQLITE_OK;
-}
-
-/*
-** Implementation of xCommit() method. This is a no-op. The contents of
-** the pending-terms hash-table have already been flushed into the database
-** by fts3SyncMethod().
-*/
-static int fts3CommitMethod(sqlite3_vtab *pVtab){
- TESTONLY( Fts3Table *p = (Fts3Table*)pVtab );
- UNUSED_PARAMETER(pVtab);
- assert( p->nPendingData==0 );
- assert( p->inTransaction!=0 );
- assert( p->pSegments==0 );
- TESTONLY( p->inTransaction = 0 );
- TESTONLY( p->mxSavepoint = -1; );
- return SQLITE_OK;
-}
-
-/*
-** Implementation of xRollback(). Discard the contents of the pending-terms
-** hash-table. Any changes made to the database are reverted by SQLite.
-*/
-static int fts3RollbackMethod(sqlite3_vtab *pVtab){
- Fts3Table *p = (Fts3Table*)pVtab;
- sqlite3Fts3PendingTermsClear(p);
- assert( p->inTransaction!=0 );
- TESTONLY( p->inTransaction = 0 );
- TESTONLY( p->mxSavepoint = -1; );
- return SQLITE_OK;
-}
-
-/*
-** When called, *ppPoslist must point to the byte immediately following the
-** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function
-** moves *ppPoslist so that it instead points to the first byte of the
-** same position list.
-*/
-static void fts3ReversePoslist(char *pStart, char **ppPoslist){
- char *p = &(*ppPoslist)[-2];
- char c = 0;
-
- while( p>pStart && (c=*p--)==0 );
- while( p>pStart && (*p & 0x80) | c ){
- c = *p--;
- }
- if( p>pStart ){ p = &p[2]; }
- while( *p++&0x80 );
- *ppPoslist = p;
-}
-
-/*
-** Helper function used by the implementation of the overloaded snippet(),
-** offsets() and optimize() SQL functions.
-**
-** If the value passed as the third argument is a blob of size
-** sizeof(Fts3Cursor*), then the blob contents are copied to the
-** output variable *ppCsr and SQLITE_OK is returned. Otherwise, an error
-** message is written to context pContext and SQLITE_ERROR returned. The
-** string passed via zFunc is used as part of the error message.
-*/
-static int fts3FunctionArg(
- sqlite3_context *pContext, /* SQL function call context */
- const char *zFunc, /* Function name */
- sqlite3_value *pVal, /* argv[0] passed to function */
- Fts3Cursor **ppCsr /* OUT: Store cursor handle here */
-){
- Fts3Cursor *pRet;
- if( sqlite3_value_type(pVal)!=SQLITE_BLOB
- || sqlite3_value_bytes(pVal)!=sizeof(Fts3Cursor *)
- ){
- char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc);
- sqlite3_result_error(pContext, zErr, -1);
- sqlite3_free(zErr);
- return SQLITE_ERROR;
- }
- memcpy(&pRet, sqlite3_value_blob(pVal), sizeof(Fts3Cursor *));
- *ppCsr = pRet;
- return SQLITE_OK;
-}
-
-/*
-** Implementation of the snippet() function for FTS3
-*/
-static void fts3SnippetFunc(
- sqlite3_context *pContext, /* SQLite function call context */
- int nVal, /* Size of apVal[] array */
- sqlite3_value **apVal /* Array of arguments */
-){
- Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */
- const char *zStart = "<b>";
- const char *zEnd = "</b>";
- const char *zEllipsis = "<b>...</b>";
- int iCol = -1;
- int nToken = 15; /* Default number of tokens in snippet */
-
- /* There must be at least one argument passed to this function (otherwise
- ** the non-overloaded version would have been called instead of this one).
- */
- assert( nVal>=1 );
-
- if( nVal>6 ){
- sqlite3_result_error(pContext,
- "wrong number of arguments to function snippet()", -1);
- return;
- }
- if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return;
-
- switch( nVal ){
- case 6: nToken = sqlite3_value_int(apVal[5]);
- case 5: iCol = sqlite3_value_int(apVal[4]);
- case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]);
- case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]);
- case 2: zStart = (const char*)sqlite3_value_text(apVal[1]);
- }
- if( !zEllipsis || !zEnd || !zStart ){
- sqlite3_result_error_nomem(pContext);
- }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
- sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
- }
-}
-
-/*
-** Implementation of the offsets() function for FTS3
-*/
-static void fts3OffsetsFunc(
- sqlite3_context *pContext, /* SQLite function call context */
- int nVal, /* Size of argument array */
- sqlite3_value **apVal /* Array of arguments */
-){
- Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */
-
- UNUSED_PARAMETER(nVal);
-
- assert( nVal==1 );
- if( fts3FunctionArg(pContext, "offsets", apVal[0], &pCsr) ) return;
- assert( pCsr );
- if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
- sqlite3Fts3Offsets(pContext, pCsr);
- }
-}
-
-/*
-** Implementation of the special optimize() function for FTS3. This
-** function merges all segments in the database to a single segment.
-** Example usage is:
-**
-** SELECT optimize(t) FROM t LIMIT 1;
-**
-** where 't' is the name of an FTS3 table.
-*/
-static void fts3OptimizeFunc(
- sqlite3_context *pContext, /* SQLite function call context */
- int nVal, /* Size of argument array */
- sqlite3_value **apVal /* Array of arguments */
-){
- int rc; /* Return code */
- Fts3Table *p; /* Virtual table handle */
- Fts3Cursor *pCursor; /* Cursor handle passed through apVal[0] */
-
- UNUSED_PARAMETER(nVal);
-
- assert( nVal==1 );
- if( fts3FunctionArg(pContext, "optimize", apVal[0], &pCursor) ) return;
- p = (Fts3Table *)pCursor->base.pVtab;
- assert( p );
-
- rc = sqlite3Fts3Optimize(p);
-
- switch( rc ){
- case SQLITE_OK:
- sqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC);
- break;
- case SQLITE_DONE:
- sqlite3_result_text(pContext, "Index already optimal", -1, SQLITE_STATIC);
- break;
- default:
- sqlite3_result_error_code(pContext, rc);
- break;
- }
-}
-
-/*
-** Implementation of the matchinfo() function for FTS3
-*/
-static void fts3MatchinfoFunc(
- sqlite3_context *pContext, /* SQLite function call context */
- int nVal, /* Size of argument array */
- sqlite3_value **apVal /* Array of arguments */
-){
- Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */
- assert( nVal==1 || nVal==2 );
- if( SQLITE_OK==fts3FunctionArg(pContext, "matchinfo", apVal[0], &pCsr) ){
- const char *zArg = 0;
- if( nVal>1 ){
- zArg = (const char *)sqlite3_value_text(apVal[1]);
- }
- sqlite3Fts3Matchinfo(pContext, pCsr, zArg);
- }
-}
-
-/*
-** This routine implements the xFindFunction method for the FTS3
-** virtual table.
-*/
-static int fts3FindFunctionMethod(
- sqlite3_vtab *pVtab, /* Virtual table handle */
- int nArg, /* Number of SQL function arguments */
- const char *zName, /* Name of SQL function */
- void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
- void **ppArg /* Unused */
-){
- struct Overloaded {
- const char *zName;
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
- } aOverload[] = {
- { "snippet", fts3SnippetFunc },
- { "offsets", fts3OffsetsFunc },
- { "optimize", fts3OptimizeFunc },
- { "matchinfo", fts3MatchinfoFunc },
- };
- int i; /* Iterator variable */
-
- UNUSED_PARAMETER(pVtab);
- UNUSED_PARAMETER(nArg);
- UNUSED_PARAMETER(ppArg);
-
- for(i=0; i<SizeofArray(aOverload); i++){
- if( strcmp(zName, aOverload[i].zName)==0 ){
- *pxFunc = aOverload[i].xFunc;
- return 1;
- }
- }
-
- /* No function of the specified name was found. Return 0. */
- return 0;
-}
-
-/*
-** Implementation of FTS3 xRename method. Rename an fts3 table.
-*/
-static int fts3RenameMethod(
- sqlite3_vtab *pVtab, /* Virtual table handle */
- const char *zName /* New name of table */
-){
- Fts3Table *p = (Fts3Table *)pVtab;
- sqlite3 *db = p->db; /* Database connection */
- int rc; /* Return Code */
-
- /* As it happens, the pending terms table is always empty here. This is
- ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction
- ** always opens a savepoint transaction. And the xSavepoint() method
- ** flushes the pending terms table. But leave the (no-op) call to
- ** PendingTermsFlush() in in case that changes.
- */
- assert( p->nPendingData==0 );
- rc = sqlite3Fts3PendingTermsFlush(p);
-
- if( p->zContentTbl==0 ){
- fts3DbExec(&rc, db,
- "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';",
- p->zDb, p->zName, zName
- );
- }
-
- if( p->bHasDocsize ){
- fts3DbExec(&rc, db,
- "ALTER TABLE %Q.'%q_docsize' RENAME TO '%q_docsize';",
- p->zDb, p->zName, zName
- );
- }
- if( p->bHasStat ){
- fts3DbExec(&rc, db,
- "ALTER TABLE %Q.'%q_stat' RENAME TO '%q_stat';",
- p->zDb, p->zName, zName
- );
- }
- fts3DbExec(&rc, db,
- "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';",
- p->zDb, p->zName, zName
- );
- fts3DbExec(&rc, db,
- "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';",
- p->zDb, p->zName, zName
- );
- return rc;
-}
-
-/*
-** The xSavepoint() method.
-**
-** Flush the contents of the pending-terms table to disk.
-*/
-static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
- int rc = SQLITE_OK;
- UNUSED_PARAMETER(iSavepoint);
- assert( ((Fts3Table *)pVtab)->inTransaction );
- assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint );
- TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint );
- if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){
- rc = fts3SyncMethod(pVtab);
- }
- return rc;
-}
-
-/*
-** The xRelease() method.
-**
-** This is a no-op.
-*/
-static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
- TESTONLY( Fts3Table *p = (Fts3Table*)pVtab );
- UNUSED_PARAMETER(iSavepoint);
- UNUSED_PARAMETER(pVtab);
- assert( p->inTransaction );
- assert( p->mxSavepoint >= iSavepoint );
- TESTONLY( p->mxSavepoint = iSavepoint-1 );
- return SQLITE_OK;
-}
-
-/*
-** The xRollbackTo() method.
-**
-** Discard the contents of the pending terms table.
-*/
-static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
- Fts3Table *p = (Fts3Table*)pVtab;
- UNUSED_PARAMETER(iSavepoint);
- assert( p->inTransaction );
- assert( p->mxSavepoint >= iSavepoint );
- TESTONLY( p->mxSavepoint = iSavepoint );
- sqlite3Fts3PendingTermsClear(p);
- return SQLITE_OK;
-}
-
-static const sqlite3_module fts3Module = {
- /* iVersion */ 2,
- /* xCreate */ fts3CreateMethod,
- /* xConnect */ fts3ConnectMethod,
- /* xBestIndex */ fts3BestIndexMethod,
- /* xDisconnect */ fts3DisconnectMethod,
- /* xDestroy */ fts3DestroyMethod,
- /* xOpen */ fts3OpenMethod,
- /* xClose */ fts3CloseMethod,
- /* xFilter */ fts3FilterMethod,
- /* xNext */ fts3NextMethod,
- /* xEof */ fts3EofMethod,
- /* xColumn */ fts3ColumnMethod,
- /* xRowid */ fts3RowidMethod,
- /* xUpdate */ fts3UpdateMethod,
- /* xBegin */ fts3BeginMethod,
- /* xSync */ fts3SyncMethod,
- /* xCommit */ fts3CommitMethod,
- /* xRollback */ fts3RollbackMethod,
- /* xFindFunction */ fts3FindFunctionMethod,
- /* xRename */ fts3RenameMethod,
- /* xSavepoint */ fts3SavepointMethod,
- /* xRelease */ fts3ReleaseMethod,
- /* xRollbackTo */ fts3RollbackToMethod,
-};
-
-/*
-** This function is registered as the module destructor (called when an
-** FTS3 enabled database connection is closed). It frees the memory
-** allocated for the tokenizer hash table.
-*/
-static void hashDestroy(void *p){
- Fts3Hash *pHash = (Fts3Hash *)p;
- sqlite3Fts3HashClear(pHash);
- sqlite3_free(pHash);
-}
-
-/*
-** The fts3 built-in tokenizers - "simple", "porter" and "icu"- are
-** implemented in files fts3_tokenizer1.c, fts3_porter.c and fts3_icu.c
-** respectively. The following three forward declarations are for functions
-** declared in these files used to retrieve the respective implementations.
-**
-** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed
-** to by the argument to point to the "simple" tokenizer implementation.
-** And so on.
-*/
-SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
-SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule);
-#endif
-#ifdef SQLITE_ENABLE_ICU
-SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-#endif
-
-/*
-** Initialise the fts3 extension. If this extension is built as part
-** of the sqlite library, then this function is called directly by
-** SQLite. If fts3 is built as a dynamically loadable extension, this
-** function is called by the sqlite3_extension_init() entry point.
-*/
-SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
- int rc = SQLITE_OK;
- Fts3Hash *pHash = 0;
- const sqlite3_tokenizer_module *pSimple = 0;
- const sqlite3_tokenizer_module *pPorter = 0;
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
- const sqlite3_tokenizer_module *pUnicode = 0;
-#endif
-
-#ifdef SQLITE_ENABLE_ICU
- const sqlite3_tokenizer_module *pIcu = 0;
- sqlite3Fts3IcuTokenizerModule(&pIcu);
-#endif
-
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
- sqlite3Fts3UnicodeTokenizer(&pUnicode);
-#endif
-
-#ifdef SQLITE_TEST
- rc = sqlite3Fts3InitTerm(db);
- if( rc!=SQLITE_OK ) return rc;
-#endif
-
- rc = sqlite3Fts3InitAux(db);
- if( rc!=SQLITE_OK ) return rc;
-
- sqlite3Fts3SimpleTokenizerModule(&pSimple);
- sqlite3Fts3PorterTokenizerModule(&pPorter);
-
- /* Allocate and initialise the hash-table used to store tokenizers. */
- pHash = sqlite3_malloc(sizeof(Fts3Hash));
- if( !pHash ){
- rc = SQLITE_NOMEM;
- }else{
- sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
- }
-
- /* Load the built-in tokenizers into the hash table */
- if( rc==SQLITE_OK ){
- if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
- || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
-
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
- || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode)
-#endif
-#ifdef SQLITE_ENABLE_ICU
- || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu))
-#endif
- ){
- rc = SQLITE_NOMEM;
- }
- }
-
-#ifdef SQLITE_TEST
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts3ExprInitTestInterface(db);
- }
-#endif
-
- /* Create the virtual table wrapper around the hash-table and overload
- ** the two scalar functions. If this is successful, register the
- ** module with sqlite.
- */
- if( SQLITE_OK==rc
- && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer"))
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1))
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1))
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1))
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2))
- && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1))
- ){
- rc = sqlite3_create_module_v2(
- db, "fts3", &fts3Module, (void *)pHash, hashDestroy
- );
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_module_v2(
- db, "fts4", &fts3Module, (void *)pHash, 0
- );
- }
- return rc;
- }
-
- /* An error has occurred. Delete the hash table and return the error code. */
- assert( rc!=SQLITE_OK );
- if( pHash ){
- sqlite3Fts3HashClear(pHash);
- sqlite3_free(pHash);
- }
- return rc;
-}
-
-/*
-** Allocate an Fts3MultiSegReader for each token in the expression headed
-** by pExpr.
-**
-** An Fts3SegReader object is a cursor that can seek or scan a range of
-** entries within a single segment b-tree. An Fts3MultiSegReader uses multiple
-** Fts3SegReader objects internally to provide an interface to seek or scan
-** within the union of all segments of a b-tree. Hence the name.
-**
-** If the allocated Fts3MultiSegReader just seeks to a single entry in a
-** segment b-tree (if the term is not a prefix or it is a prefix for which
-** there exists prefix b-tree of the right length) then it may be traversed
-** and merged incrementally. Otherwise, it has to be merged into an in-memory
-** doclist and then traversed.
-*/
-static void fts3EvalAllocateReaders(
- Fts3Cursor *pCsr, /* FTS cursor handle */
- Fts3Expr *pExpr, /* Allocate readers for this expression */
- int *pnToken, /* OUT: Total number of tokens in phrase. */
- int *pnOr, /* OUT: Total number of OR nodes in expr. */
- int *pRc /* IN/OUT: Error code */
-){
- if( pExpr && SQLITE_OK==*pRc ){
- if( pExpr->eType==FTSQUERY_PHRASE ){
- int i;
- int nToken = pExpr->pPhrase->nToken;
- *pnToken += nToken;
- for(i=0; i<nToken; i++){
- Fts3PhraseToken *pToken = &pExpr->pPhrase->aToken[i];
- int rc = fts3TermSegReaderCursor(pCsr,
- pToken->z, pToken->n, pToken->isPrefix, &pToken->pSegcsr
- );
- if( rc!=SQLITE_OK ){
- *pRc = rc;
- return;
- }
- }
- assert( pExpr->pPhrase->iDoclistToken==0 );
- pExpr->pPhrase->iDoclistToken = -1;
- }else{
- *pnOr += (pExpr->eType==FTSQUERY_OR);
- fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc);
- fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc);
- }
- }
-}
-
-/*
-** Arguments pList/nList contain the doclist for token iToken of phrase p.
-** It is merged into the main doclist stored in p->doclist.aAll/nAll.
-**
-** This function assumes that pList points to a buffer allocated using
-** sqlite3_malloc(). This function takes responsibility for eventually
-** freeing the buffer.
-*/
-static void fts3EvalPhraseMergeToken(
- Fts3Table *pTab, /* FTS Table pointer */
- Fts3Phrase *p, /* Phrase to merge pList/nList into */
- int iToken, /* Token pList/nList corresponds to */
- char *pList, /* Pointer to doclist */
- int nList /* Number of bytes in pList */
-){
- assert( iToken!=p->iDoclistToken );
-
- if( pList==0 ){
- sqlite3_free(p->doclist.aAll);
- p->doclist.aAll = 0;
- p->doclist.nAll = 0;
- }
-
- else if( p->iDoclistToken<0 ){
- p->doclist.aAll = pList;
- p->doclist.nAll = nList;
- }
-
- else if( p->doclist.aAll==0 ){
- sqlite3_free(pList);
- }
-
- else {
- char *pLeft;
- char *pRight;
- int nLeft;
- int nRight;
- int nDiff;
-
- if( p->iDoclistToken<iToken ){
- pLeft = p->doclist.aAll;
- nLeft = p->doclist.nAll;
- pRight = pList;
- nRight = nList;
- nDiff = iToken - p->iDoclistToken;
- }else{
- pRight = p->doclist.aAll;
- nRight = p->doclist.nAll;
- pLeft = pList;
- nLeft = nList;
- nDiff = p->iDoclistToken - iToken;
- }
-
- fts3DoclistPhraseMerge(pTab->bDescIdx, nDiff, pLeft, nLeft, pRight,&nRight);
- sqlite3_free(pLeft);
- p->doclist.aAll = pRight;
- p->doclist.nAll = nRight;
- }
-
- if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken;
-}
-
-/*
-** Load the doclist for phrase p into p->doclist.aAll/nAll. The loaded doclist
-** does not take deferred tokens into account.
-**
-** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
-*/
-static int fts3EvalPhraseLoad(
- Fts3Cursor *pCsr, /* FTS Cursor handle */
- Fts3Phrase *p /* Phrase object */
-){
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- int iToken;
- int rc = SQLITE_OK;
-
- for(iToken=0; rc==SQLITE_OK && iToken<p->nToken; iToken++){
- Fts3PhraseToken *pToken = &p->aToken[iToken];
- assert( pToken->pDeferred==0 || pToken->pSegcsr==0 );
-
- if( pToken->pSegcsr ){
- int nThis = 0;
- char *pThis = 0;
- rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis);
- if( rc==SQLITE_OK ){
- fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis);
- }
- }
- assert( pToken->pSegcsr==0 );
- }
-
- return rc;
-}
-
-/*
-** This function is called on each phrase after the position lists for
-** any deferred tokens have been loaded into memory. It updates the phrases
-** current position list to include only those positions that are really
-** instances of the phrase (after considering deferred tokens). If this
-** means that the phrase does not appear in the current row, doclist.pList
-** and doclist.nList are both zeroed.
-**
-** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
-*/
-static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
- int iToken; /* Used to iterate through phrase tokens */
- char *aPoslist = 0; /* Position list for deferred tokens */
- int nPoslist = 0; /* Number of bytes in aPoslist */
- int iPrev = -1; /* Token number of previous deferred token */
-
- assert( pPhrase->doclist.bFreeList==0 );
-
- for(iToken=0; iToken<pPhrase->nToken; iToken++){
- Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
- Fts3DeferredToken *pDeferred = pToken->pDeferred;
-
- if( pDeferred ){
- char *pList;
- int nList;
- int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList);
- if( rc!=SQLITE_OK ) return rc;
-
- if( pList==0 ){
- sqlite3_free(aPoslist);
- pPhrase->doclist.pList = 0;
- pPhrase->doclist.nList = 0;
- return SQLITE_OK;
-
- }else if( aPoslist==0 ){
- aPoslist = pList;
- nPoslist = nList;
-
- }else{
- char *aOut = pList;
- char *p1 = aPoslist;
- char *p2 = aOut;
-
- assert( iPrev>=0 );
- fts3PoslistPhraseMerge(&aOut, iToken-iPrev, 0, 1, &p1, &p2);
- sqlite3_free(aPoslist);
- aPoslist = pList;
- nPoslist = (int)(aOut - aPoslist);
- if( nPoslist==0 ){
- sqlite3_free(aPoslist);
- pPhrase->doclist.pList = 0;
- pPhrase->doclist.nList = 0;
- return SQLITE_OK;
- }
- }
- iPrev = iToken;
- }
- }
-
- if( iPrev>=0 ){
- int nMaxUndeferred = pPhrase->iDoclistToken;
- if( nMaxUndeferred<0 ){
- pPhrase->doclist.pList = aPoslist;
- pPhrase->doclist.nList = nPoslist;
- pPhrase->doclist.iDocid = pCsr->iPrevId;
- pPhrase->doclist.bFreeList = 1;
- }else{
- int nDistance;
- char *p1;
- char *p2;
- char *aOut;
-
- if( nMaxUndeferred>iPrev ){
- p1 = aPoslist;
- p2 = pPhrase->doclist.pList;
- nDistance = nMaxUndeferred - iPrev;
- }else{
- p1 = pPhrase->doclist.pList;
- p2 = aPoslist;
- nDistance = iPrev - nMaxUndeferred;
- }
-
- aOut = (char *)sqlite3_malloc(nPoslist+8);
- if( !aOut ){
- sqlite3_free(aPoslist);
- return SQLITE_NOMEM;
- }
-
- pPhrase->doclist.pList = aOut;
- if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){
- pPhrase->doclist.bFreeList = 1;
- pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList);
- }else{
- sqlite3_free(aOut);
- pPhrase->doclist.pList = 0;
- pPhrase->doclist.nList = 0;
- }
- sqlite3_free(aPoslist);
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** This function is called for each Fts3Phrase in a full-text query
-** expression to initialize the mechanism for returning rows. Once this
-** function has been called successfully on an Fts3Phrase, it may be
-** used with fts3EvalPhraseNext() to iterate through the matching docids.
-**
-** If parameter bOptOk is true, then the phrase may (or may not) use the
-** incremental loading strategy. Otherwise, the entire doclist is loaded into
-** memory within this call.
-**
-** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
-*/
-static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){
- int rc; /* Error code */
- Fts3PhraseToken *pFirst = &p->aToken[0];
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
-
- if( pCsr->bDesc==pTab->bDescIdx
- && bOptOk==1
- && p->nToken==1
- && pFirst->pSegcsr
- && pFirst->pSegcsr->bLookup
- && pFirst->bFirst==0
- ){
- /* Use the incremental approach. */
- int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
- rc = sqlite3Fts3MsrIncrStart(
- pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n);
- p->bIncr = 1;
-
- }else{
- /* Load the full doclist for the phrase into memory. */
- rc = fts3EvalPhraseLoad(pCsr, p);
- p->bIncr = 0;
- }
-
- assert( rc!=SQLITE_OK || p->nToken<1 || p->aToken[0].pSegcsr==0 || p->bIncr );
- return rc;
-}
-
-/*
-** This function is used to iterate backwards (from the end to start)
-** through doclists. It is used by this module to iterate through phrase
-** doclists in reverse and by the fts3_write.c module to iterate through
-** pending-terms lists when writing to databases with "order=desc".
-**
-** The doclist may be sorted in ascending (parameter bDescIdx==0) or
-** descending (parameter bDescIdx==1) order of docid. Regardless, this
-** function iterates from the end of the doclist to the beginning.
-*/
-SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(
- int bDescIdx, /* True if the doclist is desc */
- char *aDoclist, /* Pointer to entire doclist */
- int nDoclist, /* Length of aDoclist in bytes */
- char **ppIter, /* IN/OUT: Iterator pointer */
- sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */
- int *pnList, /* OUT: List length pointer */
- u8 *pbEof /* OUT: End-of-file flag */
-){
- char *p = *ppIter;
-
- assert( nDoclist>0 );
- assert( *pbEof==0 );
- assert( p || *piDocid==0 );
- assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) );
-
- if( p==0 ){
- sqlite3_int64 iDocid = 0;
- char *pNext = 0;
- char *pDocid = aDoclist;
- char *pEnd = &aDoclist[nDoclist];
- int iMul = 1;
-
- while( pDocid<pEnd ){
- sqlite3_int64 iDelta;
- pDocid += sqlite3Fts3GetVarint(pDocid, &iDelta);
- iDocid += (iMul * iDelta);
- pNext = pDocid;
- fts3PoslistCopy(0, &pDocid);
- while( pDocid<pEnd && *pDocid==0 ) pDocid++;
- iMul = (bDescIdx ? -1 : 1);
- }
-
- *pnList = (int)(pEnd - pNext);
- *ppIter = pNext;
- *piDocid = iDocid;
- }else{
- int iMul = (bDescIdx ? -1 : 1);
- sqlite3_int64 iDelta;
- fts3GetReverseVarint(&p, aDoclist, &iDelta);
- *piDocid -= (iMul * iDelta);
-
- if( p==aDoclist ){
- *pbEof = 1;
- }else{
- char *pSave = p;
- fts3ReversePoslist(aDoclist, &p);
- *pnList = (int)(pSave - p);
- }
- *ppIter = p;
- }
-}
-
-/*
-** Iterate forwards through a doclist.
-*/
-SQLITE_PRIVATE void sqlite3Fts3DoclistNext(
- int bDescIdx, /* True if the doclist is desc */
- char *aDoclist, /* Pointer to entire doclist */
- int nDoclist, /* Length of aDoclist in bytes */
- char **ppIter, /* IN/OUT: Iterator pointer */
- sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */
- u8 *pbEof /* OUT: End-of-file flag */
-){
- char *p = *ppIter;
-
- assert( nDoclist>0 );
- assert( *pbEof==0 );
- assert( p || *piDocid==0 );
- assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) );
-
- if( p==0 ){
- p = aDoclist;
- p += sqlite3Fts3GetVarint(p, piDocid);
- }else{
- fts3PoslistCopy(0, &p);
- if( p>=&aDoclist[nDoclist] ){
- *pbEof = 1;
- }else{
- sqlite3_int64 iVar;
- p += sqlite3Fts3GetVarint(p, &iVar);
- *piDocid += ((bDescIdx ? -1 : 1) * iVar);
- }
- }
-
- *ppIter = p;
-}
-
-/*
-** Attempt to move the phrase iterator to point to the next matching docid.
-** If an error occurs, return an SQLite error code. Otherwise, return
-** SQLITE_OK.
-**
-** If there is no "next" entry and no error occurs, then *pbEof is set to
-** 1 before returning. Otherwise, if no error occurs and the iterator is
-** successfully advanced, *pbEof is set to 0.
-*/
-static int fts3EvalPhraseNext(
- Fts3Cursor *pCsr, /* FTS Cursor handle */
- Fts3Phrase *p, /* Phrase object to advance to next docid */
- u8 *pbEof /* OUT: Set to 1 if EOF */
-){
- int rc = SQLITE_OK;
- Fts3Doclist *pDL = &p->doclist;
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
-
- if( p->bIncr ){
- assert( p->nToken==1 );
- assert( pDL->pNextDocid==0 );
- rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr,
- &pDL->iDocid, &pDL->pList, &pDL->nList
- );
- if( rc==SQLITE_OK && !pDL->pList ){
- *pbEof = 1;
- }
- }else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){
- sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll,
- &pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof
- );
- pDL->pList = pDL->pNextDocid;
- }else{
- char *pIter; /* Used to iterate through aAll */
- char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */
- if( pDL->pNextDocid ){
- pIter = pDL->pNextDocid;
- }else{
- pIter = pDL->aAll;
- }
-
- if( pIter>=pEnd ){
- /* We have already reached the end of this doclist. EOF. */
- *pbEof = 1;
- }else{
- sqlite3_int64 iDelta;
- pIter += sqlite3Fts3GetVarint(pIter, &iDelta);
- if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){
- pDL->iDocid += iDelta;
- }else{
- pDL->iDocid -= iDelta;
- }
- pDL->pList = pIter;
- fts3PoslistCopy(0, &pIter);
- pDL->nList = (int)(pIter - pDL->pList);
-
- /* pIter now points just past the 0x00 that terminates the position-
- ** list for document pDL->iDocid. However, if this position-list was
- ** edited in place by fts3EvalNearTrim(), then pIter may not actually
- ** point to the start of the next docid value. The following line deals
- ** with this case by advancing pIter past the zero-padding added by
- ** fts3EvalNearTrim(). */
- while( pIter<pEnd && *pIter==0 ) pIter++;
-
- pDL->pNextDocid = pIter;
- assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter );
- *pbEof = 0;
- }
- }
-
- return rc;
-}
-
-/*
-**
-** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
-** Otherwise, fts3EvalPhraseStart() is called on all phrases within the
-** expression. Also the Fts3Expr.bDeferred variable is set to true for any
-** expressions for which all descendent tokens are deferred.
-**
-** If parameter bOptOk is zero, then it is guaranteed that the
-** Fts3Phrase.doclist.aAll/nAll variables contain the entire doclist for
-** each phrase in the expression (subject to deferred token processing).
-** Or, if bOptOk is non-zero, then one or more tokens within the expression
-** may be loaded incrementally, meaning doclist.aAll/nAll is not available.
-**
-** If an error occurs within this function, *pRc is set to an SQLite error
-** code before returning.
-*/
-static void fts3EvalStartReaders(
- Fts3Cursor *pCsr, /* FTS Cursor handle */
- Fts3Expr *pExpr, /* Expression to initialize phrases in */
- int bOptOk, /* True to enable incremental loading */
- int *pRc /* IN/OUT: Error code */
-){
- if( pExpr && SQLITE_OK==*pRc ){
- if( pExpr->eType==FTSQUERY_PHRASE ){
- int i;
- int nToken = pExpr->pPhrase->nToken;
- for(i=0; i<nToken; i++){
- if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
- }
- pExpr->bDeferred = (i==nToken);
- *pRc = fts3EvalPhraseStart(pCsr, bOptOk, pExpr->pPhrase);
- }else{
- fts3EvalStartReaders(pCsr, pExpr->pLeft, bOptOk, pRc);
- fts3EvalStartReaders(pCsr, pExpr->pRight, bOptOk, pRc);
- pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred);
- }
- }
-}
-
-/*
-** An array of the following structures is assembled as part of the process
-** of selecting tokens to defer before the query starts executing (as part
-** of the xFilter() method). There is one element in the array for each
-** token in the FTS expression.
-**
-** Tokens are divided into AND/NEAR clusters. All tokens in a cluster belong
-** to phrases that are connected only by AND and NEAR operators (not OR or
-** NOT). When determining tokens to defer, each AND/NEAR cluster is considered
-** separately. The root of a tokens AND/NEAR cluster is stored in
-** Fts3TokenAndCost.pRoot.
-*/
-typedef struct Fts3TokenAndCost Fts3TokenAndCost;
-struct Fts3TokenAndCost {
- Fts3Phrase *pPhrase; /* The phrase the token belongs to */
- int iToken; /* Position of token in phrase */
- Fts3PhraseToken *pToken; /* The token itself */
- Fts3Expr *pRoot; /* Root of NEAR/AND cluster */
- int nOvfl; /* Number of overflow pages to load doclist */
- int iCol; /* The column the token must match */
-};
-
-/*
-** This function is used to populate an allocated Fts3TokenAndCost array.
-**
-** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
-** Otherwise, if an error occurs during execution, *pRc is set to an
-** SQLite error code.
-*/
-static void fts3EvalTokenCosts(
- Fts3Cursor *pCsr, /* FTS Cursor handle */
- Fts3Expr *pRoot, /* Root of current AND/NEAR cluster */
- Fts3Expr *pExpr, /* Expression to consider */
- Fts3TokenAndCost **ppTC, /* Write new entries to *(*ppTC)++ */
- Fts3Expr ***ppOr, /* Write new OR root to *(*ppOr)++ */
- int *pRc /* IN/OUT: Error code */
-){
- if( *pRc==SQLITE_OK ){
- if( pExpr->eType==FTSQUERY_PHRASE ){
- Fts3Phrase *pPhrase = pExpr->pPhrase;
- int i;
- for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){
- Fts3TokenAndCost *pTC = (*ppTC)++;
- pTC->pPhrase = pPhrase;
- pTC->iToken = i;
- pTC->pRoot = pRoot;
- pTC->pToken = &pPhrase->aToken[i];
- pTC->iCol = pPhrase->iColumn;
- *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl);
- }
- }else if( pExpr->eType!=FTSQUERY_NOT ){
- assert( pExpr->eType==FTSQUERY_OR
- || pExpr->eType==FTSQUERY_AND
- || pExpr->eType==FTSQUERY_NEAR
- );
- assert( pExpr->pLeft && pExpr->pRight );
- if( pExpr->eType==FTSQUERY_OR ){
- pRoot = pExpr->pLeft;
- **ppOr = pRoot;
- (*ppOr)++;
- }
- fts3EvalTokenCosts(pCsr, pRoot, pExpr->pLeft, ppTC, ppOr, pRc);
- if( pExpr->eType==FTSQUERY_OR ){
- pRoot = pExpr->pRight;
- **ppOr = pRoot;
- (*ppOr)++;
- }
- fts3EvalTokenCosts(pCsr, pRoot, pExpr->pRight, ppTC, ppOr, pRc);
- }
- }
-}
-
-/*
-** Determine the average document (row) size in pages. If successful,
-** write this value to *pnPage and return SQLITE_OK. Otherwise, return
-** an SQLite error code.
-**
-** The average document size in pages is calculated by first calculating
-** determining the average size in bytes, B. If B is less than the amount
-** of data that will fit on a single leaf page of an intkey table in
-** this database, then the average docsize is 1. Otherwise, it is 1 plus
-** the number of overflow pages consumed by a record B bytes in size.
-*/
-static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){
- if( pCsr->nRowAvg==0 ){
- /* The average document size, which is required to calculate the cost
- ** of each doclist, has not yet been determined. Read the required
- ** data from the %_stat table to calculate it.
- **
- ** Entry 0 of the %_stat table is a blob containing (nCol+1) FTS3
- ** varints, where nCol is the number of columns in the FTS3 table.
- ** The first varint is the number of documents currently stored in
- ** the table. The following nCol varints contain the total amount of
- ** data stored in all rows of each column of the table, from left
- ** to right.
- */
- int rc;
- Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
- sqlite3_stmt *pStmt;
- sqlite3_int64 nDoc = 0;
- sqlite3_int64 nByte = 0;
- const char *pEnd;
- const char *a;
-
- rc = sqlite3Fts3SelectDoctotal(p, &pStmt);
- if( rc!=SQLITE_OK ) return rc;
- a = sqlite3_column_blob(pStmt, 0);
- assert( a );
-
- pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
- a += sqlite3Fts3GetVarint(a, &nDoc);
- while( a<pEnd ){
- a += sqlite3Fts3GetVarint(a, &nByte);
- }
- if( nDoc==0 || nByte==0 ){
- sqlite3_reset(pStmt);
- return FTS_CORRUPT_VTAB;
- }
-
- pCsr->nDoc = nDoc;
- pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
- assert( pCsr->nRowAvg>0 );
- rc = sqlite3_reset(pStmt);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- *pnPage = pCsr->nRowAvg;
- return SQLITE_OK;
-}
-
-/*
-** This function is called to select the tokens (if any) that will be
-** deferred. The array aTC[] has already been populated when this is
-** called.
-**
-** This function is called once for each AND/NEAR cluster in the
-** expression. Each invocation determines which tokens to defer within
-** the cluster with root node pRoot. See comments above the definition
-** of struct Fts3TokenAndCost for more details.
-**
-** If no error occurs, SQLITE_OK is returned and sqlite3Fts3DeferToken()
-** called on each token to defer. Otherwise, an SQLite error code is
-** returned.
-*/
-static int fts3EvalSelectDeferred(
- Fts3Cursor *pCsr, /* FTS Cursor handle */
- Fts3Expr *pRoot, /* Consider tokens with this root node */
- Fts3TokenAndCost *aTC, /* Array of expression tokens and costs */
- int nTC /* Number of entries in aTC[] */
-){
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- int nDocSize = 0; /* Number of pages per doc loaded */
- int rc = SQLITE_OK; /* Return code */
- int ii; /* Iterator variable for various purposes */
- int nOvfl = 0; /* Total overflow pages used by doclists */
- int nToken = 0; /* Total number of tokens in cluster */
-
- int nMinEst = 0; /* The minimum count for any phrase so far. */
- int nLoad4 = 1; /* (Phrases that will be loaded)^4. */
-
- /* Tokens are never deferred for FTS tables created using the content=xxx
- ** option. The reason being that it is not guaranteed that the content
- ** table actually contains the same data as the index. To prevent this from
- ** causing any problems, the deferred token optimization is completely
- ** disabled for content=xxx tables. */
- if( pTab->zContentTbl ){
- return SQLITE_OK;
- }
-
- /* Count the tokens in this AND/NEAR cluster. If none of the doclists
- ** associated with the tokens spill onto overflow pages, or if there is
- ** only 1 token, exit early. No tokens to defer in this case. */
- for(ii=0; ii<nTC; ii++){
- if( aTC[ii].pRoot==pRoot ){
- nOvfl += aTC[ii].nOvfl;
- nToken++;
- }
- }
- if( nOvfl==0 || nToken<2 ) return SQLITE_OK;
-
- /* Obtain the average docsize (in pages). */
- rc = fts3EvalAverageDocsize(pCsr, &nDocSize);
- assert( rc!=SQLITE_OK || nDocSize>0 );
-
-
- /* Iterate through all tokens in this AND/NEAR cluster, in ascending order
- ** of the number of overflow pages that will be loaded by the pager layer
- ** to retrieve the entire doclist for the token from the full-text index.
- ** Load the doclists for tokens that are either:
- **
- ** a. The cheapest token in the entire query (i.e. the one visited by the
- ** first iteration of this loop), or
- **
- ** b. Part of a multi-token phrase.
- **
- ** After each token doclist is loaded, merge it with the others from the
- ** same phrase and count the number of documents that the merged doclist
- ** contains. Set variable "nMinEst" to the smallest number of documents in
- ** any phrase doclist for which 1 or more token doclists have been loaded.
- ** Let nOther be the number of other phrases for which it is certain that
- ** one or more tokens will not be deferred.
- **
- ** Then, for each token, defer it if loading the doclist would result in
- ** loading N or more overflow pages into memory, where N is computed as:
- **
- ** (nMinEst + 4^nOther - 1) / (4^nOther)
- */
- for(ii=0; ii<nToken && rc==SQLITE_OK; ii++){
- int iTC; /* Used to iterate through aTC[] array. */
- Fts3TokenAndCost *pTC = 0; /* Set to cheapest remaining token. */
-
- /* Set pTC to point to the cheapest remaining token. */
- for(iTC=0; iTC<nTC; iTC++){
- if( aTC[iTC].pToken && aTC[iTC].pRoot==pRoot
- && (!pTC || aTC[iTC].nOvfl<pTC->nOvfl)
- ){
- pTC = &aTC[iTC];
- }
- }
- assert( pTC );
-
- if( ii && pTC->nOvfl>=((nMinEst+(nLoad4/4)-1)/(nLoad4/4))*nDocSize ){
- /* The number of overflow pages to load for this (and therefore all
- ** subsequent) tokens is greater than the estimated number of pages
- ** that will be loaded if all subsequent tokens are deferred.
- */
- Fts3PhraseToken *pToken = pTC->pToken;
- rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol);
- fts3SegReaderCursorFree(pToken->pSegcsr);
- pToken->pSegcsr = 0;
- }else{
- /* Set nLoad4 to the value of (4^nOther) for the next iteration of the
- ** for-loop. Except, limit the value to 2^24 to prevent it from
- ** overflowing the 32-bit integer it is stored in. */
- if( ii<12 ) nLoad4 = nLoad4*4;
-
- if( ii==0 || pTC->pPhrase->nToken>1 ){
- /* Either this is the cheapest token in the entire query, or it is
- ** part of a multi-token phrase. Either way, the entire doclist will
- ** (eventually) be loaded into memory. It may as well be now. */
- Fts3PhraseToken *pToken = pTC->pToken;
- int nList = 0;
- char *pList = 0;
- rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList);
- assert( rc==SQLITE_OK || pList==0 );
- if( rc==SQLITE_OK ){
- int nCount;
- fts3EvalPhraseMergeToken(pTab, pTC->pPhrase, pTC->iToken,pList,nList);
- nCount = fts3DoclistCountDocids(
- pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll
- );
- if( ii==0 || nCount<nMinEst ) nMinEst = nCount;
- }
- }
- }
- pTC->pToken = 0;
- }
-
- return rc;
-}
-
-/*
-** This function is called from within the xFilter method. It initializes
-** the full-text query currently stored in pCsr->pExpr. To iterate through
-** the results of a query, the caller does:
-**
-** fts3EvalStart(pCsr);
-** while( 1 ){
-** fts3EvalNext(pCsr);
-** if( pCsr->bEof ) break;
-** ... return row pCsr->iPrevId to the caller ...
-** }
-*/
-static int fts3EvalStart(Fts3Cursor *pCsr){
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- int rc = SQLITE_OK;
- int nToken = 0;
- int nOr = 0;
-
- /* Allocate a MultiSegReader for each token in the expression. */
- fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc);
-
- /* Determine which, if any, tokens in the expression should be deferred. */
-#ifndef SQLITE_DISABLE_FTS4_DEFERRED
- if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){
- Fts3TokenAndCost *aTC;
- Fts3Expr **apOr;
- aTC = (Fts3TokenAndCost *)sqlite3_malloc(
- sizeof(Fts3TokenAndCost) * nToken
- + sizeof(Fts3Expr *) * nOr * 2
- );
- apOr = (Fts3Expr **)&aTC[nToken];
-
- if( !aTC ){
- rc = SQLITE_NOMEM;
- }else{
- int ii;
- Fts3TokenAndCost *pTC = aTC;
- Fts3Expr **ppOr = apOr;
-
- fts3EvalTokenCosts(pCsr, 0, pCsr->pExpr, &pTC, &ppOr, &rc);
- nToken = (int)(pTC-aTC);
- nOr = (int)(ppOr-apOr);
-
- if( rc==SQLITE_OK ){
- rc = fts3EvalSelectDeferred(pCsr, 0, aTC, nToken);
- for(ii=0; rc==SQLITE_OK && ii<nOr; ii++){
- rc = fts3EvalSelectDeferred(pCsr, apOr[ii], aTC, nToken);
- }
- }
-
- sqlite3_free(aTC);
- }
- }
-#endif
-
- fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc);
- return rc;
-}
-
-/*
-** Invalidate the current position list for phrase pPhrase.
-*/
-static void fts3EvalInvalidatePoslist(Fts3Phrase *pPhrase){
- if( pPhrase->doclist.bFreeList ){
- sqlite3_free(pPhrase->doclist.pList);
- }
- pPhrase->doclist.pList = 0;
- pPhrase->doclist.nList = 0;
- pPhrase->doclist.bFreeList = 0;
-}
-
-/*
-** This function is called to edit the position list associated with
-** the phrase object passed as the fifth argument according to a NEAR
-** condition. For example:
-**
-** abc NEAR/5 "def ghi"
-**
-** Parameter nNear is passed the NEAR distance of the expression (5 in
-** the example above). When this function is called, *paPoslist points to
-** the position list, and *pnToken is the number of phrase tokens in, the
-** phrase on the other side of the NEAR operator to pPhrase. For example,
-** if pPhrase refers to the "def ghi" phrase, then *paPoslist points to
-** the position list associated with phrase "abc".
-**
-** All positions in the pPhrase position list that are not sufficiently
-** close to a position in the *paPoslist position list are removed. If this
-** leaves 0 positions, zero is returned. Otherwise, non-zero.
-**
-** Before returning, *paPoslist is set to point to the position lsit
-** associated with pPhrase. And *pnToken is set to the number of tokens in
-** pPhrase.
-*/
-static int fts3EvalNearTrim(
- int nNear, /* NEAR distance. As in "NEAR/nNear". */
- char *aTmp, /* Temporary space to use */
- char **paPoslist, /* IN/OUT: Position list */
- int *pnToken, /* IN/OUT: Tokens in phrase of *paPoslist */
- Fts3Phrase *pPhrase /* The phrase object to trim the doclist of */
-){
- int nParam1 = nNear + pPhrase->nToken;
- int nParam2 = nNear + *pnToken;
- int nNew;
- char *p2;
- char *pOut;
- int res;
-
- assert( pPhrase->doclist.pList );
-
- p2 = pOut = pPhrase->doclist.pList;
- res = fts3PoslistNearMerge(
- &pOut, aTmp, nParam1, nParam2, paPoslist, &p2
- );
- if( res ){
- nNew = (int)(pOut - pPhrase->doclist.pList) - 1;
- assert( pPhrase->doclist.pList[nNew]=='\0' );
- assert( nNew<=pPhrase->doclist.nList && nNew>0 );
- memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew);
- pPhrase->doclist.nList = nNew;
- *paPoslist = pPhrase->doclist.pList;
- *pnToken = pPhrase->nToken;
- }
-
- return res;
-}
-
-/*
-** This function is a no-op if *pRc is other than SQLITE_OK when it is called.
-** Otherwise, it advances the expression passed as the second argument to
-** point to the next matching row in the database. Expressions iterate through
-** matching rows in docid order. Ascending order if Fts3Cursor.bDesc is zero,
-** or descending if it is non-zero.
-**
-** If an error occurs, *pRc is set to an SQLite error code. Otherwise, if
-** successful, the following variables in pExpr are set:
-**
-** Fts3Expr.bEof (non-zero if EOF - there is no next row)
-** Fts3Expr.iDocid (valid if bEof==0. The docid of the next row)
-**
-** If the expression is of type FTSQUERY_PHRASE, and the expression is not
-** at EOF, then the following variables are populated with the position list
-** for the phrase for the visited row:
-**
-** FTs3Expr.pPhrase->doclist.nList (length of pList in bytes)
-** FTs3Expr.pPhrase->doclist.pList (pointer to position list)
-**
-** It says above that this function advances the expression to the next
-** matching row. This is usually true, but there are the following exceptions:
-**
-** 1. Deferred tokens are not taken into account. If a phrase consists
-** entirely of deferred tokens, it is assumed to match every row in
-** the db. In this case the position-list is not populated at all.
-**
-** Or, if a phrase contains one or more deferred tokens and one or
-** more non-deferred tokens, then the expression is advanced to the
-** next possible match, considering only non-deferred tokens. In other
-** words, if the phrase is "A B C", and "B" is deferred, the expression
-** is advanced to the next row that contains an instance of "A * C",
-** where "*" may match any single token. The position list in this case
-** is populated as for "A * C" before returning.
-**
-** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is
-** advanced to point to the next row that matches "x AND y".
-**
-** See fts3EvalTestDeferredAndNear() for details on testing if a row is
-** really a match, taking into account deferred tokens and NEAR operators.
-*/
-static void fts3EvalNextRow(
- Fts3Cursor *pCsr, /* FTS Cursor handle */
- Fts3Expr *pExpr, /* Expr. to advance to next matching row */
- int *pRc /* IN/OUT: Error code */
-){
- if( *pRc==SQLITE_OK ){
- int bDescDoclist = pCsr->bDesc; /* Used by DOCID_CMP() macro */
- assert( pExpr->bEof==0 );
- pExpr->bStart = 1;
-
- switch( pExpr->eType ){
- case FTSQUERY_NEAR:
- case FTSQUERY_AND: {
- Fts3Expr *pLeft = pExpr->pLeft;
- Fts3Expr *pRight = pExpr->pRight;
- assert( !pLeft->bDeferred || !pRight->bDeferred );
-
- if( pLeft->bDeferred ){
- /* LHS is entirely deferred. So we assume it matches every row.
- ** Advance the RHS iterator to find the next row visited. */
- fts3EvalNextRow(pCsr, pRight, pRc);
- pExpr->iDocid = pRight->iDocid;
- pExpr->bEof = pRight->bEof;
- }else if( pRight->bDeferred ){
- /* RHS is entirely deferred. So we assume it matches every row.
- ** Advance the LHS iterator to find the next row visited. */
- fts3EvalNextRow(pCsr, pLeft, pRc);
- pExpr->iDocid = pLeft->iDocid;
- pExpr->bEof = pLeft->bEof;
- }else{
- /* Neither the RHS or LHS are deferred. */
- fts3EvalNextRow(pCsr, pLeft, pRc);
- fts3EvalNextRow(pCsr, pRight, pRc);
- while( !pLeft->bEof && !pRight->bEof && *pRc==SQLITE_OK ){
- sqlite3_int64 iDiff = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
- if( iDiff==0 ) break;
- if( iDiff<0 ){
- fts3EvalNextRow(pCsr, pLeft, pRc);
- }else{
- fts3EvalNextRow(pCsr, pRight, pRc);
- }
- }
- pExpr->iDocid = pLeft->iDocid;
- pExpr->bEof = (pLeft->bEof || pRight->bEof);
- }
- break;
- }
-
- case FTSQUERY_OR: {
- Fts3Expr *pLeft = pExpr->pLeft;
- Fts3Expr *pRight = pExpr->pRight;
- sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
-
- assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid );
- assert( pRight->bStart || pLeft->iDocid==pRight->iDocid );
-
- if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
- fts3EvalNextRow(pCsr, pLeft, pRc);
- }else if( pLeft->bEof || (pRight->bEof==0 && iCmp>0) ){
- fts3EvalNextRow(pCsr, pRight, pRc);
- }else{
- fts3EvalNextRow(pCsr, pLeft, pRc);
- fts3EvalNextRow(pCsr, pRight, pRc);
- }
-
- pExpr->bEof = (pLeft->bEof && pRight->bEof);
- iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
- if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
- pExpr->iDocid = pLeft->iDocid;
- }else{
- pExpr->iDocid = pRight->iDocid;
- }
-
- break;
- }
-
- case FTSQUERY_NOT: {
- Fts3Expr *pLeft = pExpr->pLeft;
- Fts3Expr *pRight = pExpr->pRight;
-
- if( pRight->bStart==0 ){
- fts3EvalNextRow(pCsr, pRight, pRc);
- assert( *pRc!=SQLITE_OK || pRight->bStart );
- }
-
- fts3EvalNextRow(pCsr, pLeft, pRc);
- if( pLeft->bEof==0 ){
- while( !*pRc
- && !pRight->bEof
- && DOCID_CMP(pLeft->iDocid, pRight->iDocid)>0
- ){
- fts3EvalNextRow(pCsr, pRight, pRc);
- }
- }
- pExpr->iDocid = pLeft->iDocid;
- pExpr->bEof = pLeft->bEof;
- break;
- }
-
- default: {
- Fts3Phrase *pPhrase = pExpr->pPhrase;
- fts3EvalInvalidatePoslist(pPhrase);
- *pRc = fts3EvalPhraseNext(pCsr, pPhrase, &pExpr->bEof);
- pExpr->iDocid = pPhrase->doclist.iDocid;
- break;
- }
- }
- }
-}
-
-/*
-** If *pRc is not SQLITE_OK, or if pExpr is not the root node of a NEAR
-** cluster, then this function returns 1 immediately.
-**
-** Otherwise, it checks if the current row really does match the NEAR
-** expression, using the data currently stored in the position lists
-** (Fts3Expr->pPhrase.doclist.pList/nList) for each phrase in the expression.
-**
-** If the current row is a match, the position list associated with each
-** phrase in the NEAR expression is edited in place to contain only those
-** phrase instances sufficiently close to their peers to satisfy all NEAR
-** constraints. In this case it returns 1. If the NEAR expression does not
-** match the current row, 0 is returned. The position lists may or may not
-** be edited if 0 is returned.
-*/
-static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
- int res = 1;
-
- /* The following block runs if pExpr is the root of a NEAR query.
- ** For example, the query:
- **
- ** "w" NEAR "x" NEAR "y" NEAR "z"
- **
- ** which is represented in tree form as:
- **
- ** |
- ** +--NEAR--+ <-- root of NEAR query
- ** | |
- ** +--NEAR--+ "z"
- ** | |
- ** +--NEAR--+ "y"
- ** | |
- ** "w" "x"
- **
- ** The right-hand child of a NEAR node is always a phrase. The
- ** left-hand child may be either a phrase or a NEAR node. There are
- ** no exceptions to this - it's the way the parser in fts3_expr.c works.
- */
- if( *pRc==SQLITE_OK
- && pExpr->eType==FTSQUERY_NEAR
- && pExpr->bEof==0
- && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
- ){
- Fts3Expr *p;
- int nTmp = 0; /* Bytes of temp space */
- char *aTmp; /* Temp space for PoslistNearMerge() */
-
- /* Allocate temporary working space. */
- for(p=pExpr; p->pLeft; p=p->pLeft){
- nTmp += p->pRight->pPhrase->doclist.nList;
- }
- nTmp += p->pPhrase->doclist.nList;
- if( nTmp==0 ){
- res = 0;
- }else{
- aTmp = sqlite3_malloc(nTmp*2);
- if( !aTmp ){
- *pRc = SQLITE_NOMEM;
- res = 0;
- }else{
- char *aPoslist = p->pPhrase->doclist.pList;
- int nToken = p->pPhrase->nToken;
-
- for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
- Fts3Phrase *pPhrase = p->pRight->pPhrase;
- int nNear = p->nNear;
- res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
- }
-
- aPoslist = pExpr->pRight->pPhrase->doclist.pList;
- nToken = pExpr->pRight->pPhrase->nToken;
- for(p=pExpr->pLeft; p && res; p=p->pLeft){
- int nNear;
- Fts3Phrase *pPhrase;
- assert( p->pParent && p->pParent->pLeft==p );
- nNear = p->pParent->nNear;
- pPhrase = (
- p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
- );
- res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
- }
- }
-
- sqlite3_free(aTmp);
- }
- }
-
- return res;
-}
-
-/*
-** This function is a helper function for fts3EvalTestDeferredAndNear().
-** Assuming no error occurs or has occurred, It returns non-zero if the
-** expression passed as the second argument matches the row that pCsr
-** currently points to, or zero if it does not.
-**
-** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
-** If an error occurs during execution of this function, *pRc is set to
-** the appropriate SQLite error code. In this case the returned value is
-** undefined.
-*/
-static int fts3EvalTestExpr(
- Fts3Cursor *pCsr, /* FTS cursor handle */
- Fts3Expr *pExpr, /* Expr to test. May or may not be root. */
- int *pRc /* IN/OUT: Error code */
-){
- int bHit = 1; /* Return value */
- if( *pRc==SQLITE_OK ){
- switch( pExpr->eType ){
- case FTSQUERY_NEAR:
- case FTSQUERY_AND:
- bHit = (
- fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc)
- && fts3EvalTestExpr(pCsr, pExpr->pRight, pRc)
- && fts3EvalNearTest(pExpr, pRc)
- );
-
- /* If the NEAR expression does not match any rows, zero the doclist for
- ** all phrases involved in the NEAR. This is because the snippet(),
- ** offsets() and matchinfo() functions are not supposed to recognize
- ** any instances of phrases that are part of unmatched NEAR queries.
- ** For example if this expression:
- **
- ** ... MATCH 'a OR (b NEAR c)'
- **
- ** is matched against a row containing:
- **
- ** 'a b d e'
- **
- ** then any snippet() should ony highlight the "a" term, not the "b"
- ** (as "b" is part of a non-matching NEAR clause).
- */
- if( bHit==0
- && pExpr->eType==FTSQUERY_NEAR
- && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR)
- ){
- Fts3Expr *p;
- for(p=pExpr; p->pPhrase==0; p=p->pLeft){
- if( p->pRight->iDocid==pCsr->iPrevId ){
- fts3EvalInvalidatePoslist(p->pRight->pPhrase);
- }
- }
- if( p->iDocid==pCsr->iPrevId ){
- fts3EvalInvalidatePoslist(p->pPhrase);
- }
- }
-
- break;
-
- case FTSQUERY_OR: {
- int bHit1 = fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc);
- int bHit2 = fts3EvalTestExpr(pCsr, pExpr->pRight, pRc);
- bHit = bHit1 || bHit2;
- break;
- }
-
- case FTSQUERY_NOT:
- bHit = (
- fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc)
- && !fts3EvalTestExpr(pCsr, pExpr->pRight, pRc)
- );
- break;
-
- default: {
-#ifndef SQLITE_DISABLE_FTS4_DEFERRED
- if( pCsr->pDeferred
- && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred)
- ){
- Fts3Phrase *pPhrase = pExpr->pPhrase;
- assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 );
- if( pExpr->bDeferred ){
- fts3EvalInvalidatePoslist(pPhrase);
- }
- *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase);
- bHit = (pPhrase->doclist.pList!=0);
- pExpr->iDocid = pCsr->iPrevId;
- }else
-#endif
- {
- bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId);
- }
- break;
- }
- }
- }
- return bHit;
-}
-
-/*
-** This function is called as the second part of each xNext operation when
-** iterating through the results of a full-text query. At this point the
-** cursor points to a row that matches the query expression, with the
-** following caveats:
-**
-** * Up until this point, "NEAR" operators in the expression have been
-** treated as "AND".
-**
-** * Deferred tokens have not yet been considered.
-**
-** If *pRc is not SQLITE_OK when this function is called, it immediately
-** returns 0. Otherwise, it tests whether or not after considering NEAR
-** operators and deferred tokens the current row is still a match for the
-** expression. It returns 1 if both of the following are true:
-**
-** 1. *pRc is SQLITE_OK when this function returns, and
-**
-** 2. After scanning the current FTS table row for the deferred tokens,
-** it is determined that the row does *not* match the query.
-**
-** Or, if no error occurs and it seems the current row does match the FTS
-** query, return 0.
-*/
-static int fts3EvalTestDeferredAndNear(Fts3Cursor *pCsr, int *pRc){
- int rc = *pRc;
- int bMiss = 0;
- if( rc==SQLITE_OK ){
-
- /* If there are one or more deferred tokens, load the current row into
- ** memory and scan it to determine the position list for each deferred
- ** token. Then, see if this row is really a match, considering deferred
- ** tokens and NEAR operators (neither of which were taken into account
- ** earlier, by fts3EvalNextRow()).
- */
- if( pCsr->pDeferred ){
- rc = fts3CursorSeek(0, pCsr);
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts3CacheDeferredDoclists(pCsr);
- }
- }
- bMiss = (0==fts3EvalTestExpr(pCsr, pCsr->pExpr, &rc));
-
- /* Free the position-lists accumulated for each deferred token above. */
- sqlite3Fts3FreeDeferredDoclists(pCsr);
- *pRc = rc;
- }
- return (rc==SQLITE_OK && bMiss);
-}
-
-/*
-** Advance to the next document that matches the FTS expression in
-** Fts3Cursor.pExpr.
-*/
-static int fts3EvalNext(Fts3Cursor *pCsr){
- int rc = SQLITE_OK; /* Return Code */
- Fts3Expr *pExpr = pCsr->pExpr;
- assert( pCsr->isEof==0 );
- if( pExpr==0 ){
- pCsr->isEof = 1;
- }else{
- do {
- if( pCsr->isRequireSeek==0 ){
- sqlite3_reset(pCsr->pStmt);
- }
- assert( sqlite3_data_count(pCsr->pStmt)==0 );
- fts3EvalNextRow(pCsr, pExpr, &rc);
- pCsr->isEof = pExpr->bEof;
- pCsr->isRequireSeek = 1;
- pCsr->isMatchinfoNeeded = 1;
- pCsr->iPrevId = pExpr->iDocid;
- }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) );
- }
- return rc;
-}
-
-/*
-** Restart interation for expression pExpr so that the next call to
-** fts3EvalNext() visits the first row. Do not allow incremental
-** loading or merging of phrase doclists for this iteration.
-**
-** If *pRc is other than SQLITE_OK when this function is called, it is
-** a no-op. If an error occurs within this function, *pRc is set to an
-** SQLite error code before returning.
-*/
-static void fts3EvalRestart(
- Fts3Cursor *pCsr,
- Fts3Expr *pExpr,
- int *pRc
-){
- if( pExpr && *pRc==SQLITE_OK ){
- Fts3Phrase *pPhrase = pExpr->pPhrase;
-
- if( pPhrase ){
- fts3EvalInvalidatePoslist(pPhrase);
- if( pPhrase->bIncr ){
- assert( pPhrase->nToken==1 );
- assert( pPhrase->aToken[0].pSegcsr );
- sqlite3Fts3MsrIncrRestart(pPhrase->aToken[0].pSegcsr);
- *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase);
- }
-
- pPhrase->doclist.pNextDocid = 0;
- pPhrase->doclist.iDocid = 0;
- }
-
- pExpr->iDocid = 0;
- pExpr->bEof = 0;
- pExpr->bStart = 0;
-
- fts3EvalRestart(pCsr, pExpr->pLeft, pRc);
- fts3EvalRestart(pCsr, pExpr->pRight, pRc);
- }
-}
-
-/*
-** After allocating the Fts3Expr.aMI[] array for each phrase in the
-** expression rooted at pExpr, the cursor iterates through all rows matched
-** by pExpr, calling this function for each row. This function increments
-** the values in Fts3Expr.aMI[] according to the position-list currently
-** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase
-** expression nodes.
-*/
-static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
- if( pExpr ){
- Fts3Phrase *pPhrase = pExpr->pPhrase;
- if( pPhrase && pPhrase->doclist.pList ){
- int iCol = 0;
- char *p = pPhrase->doclist.pList;
-
- assert( *p );
- while( 1 ){
- u8 c = 0;
- int iCnt = 0;
- while( 0xFE & (*p | c) ){
- if( (c&0x80)==0 ) iCnt++;
- c = *p++ & 0x80;
- }
-
- /* aMI[iCol*3 + 1] = Number of occurrences
- ** aMI[iCol*3 + 2] = Number of rows containing at least one instance
- */
- pExpr->aMI[iCol*3 + 1] += iCnt;
- pExpr->aMI[iCol*3 + 2] += (iCnt>0);
- if( *p==0x00 ) break;
- p++;
- p += sqlite3Fts3GetVarint32(p, &iCol);
- }
- }
-
- fts3EvalUpdateCounts(pExpr->pLeft);
- fts3EvalUpdateCounts(pExpr->pRight);
- }
-}
-
-/*
-** Expression pExpr must be of type FTSQUERY_PHRASE.
-**
-** If it is not already allocated and populated, this function allocates and
-** populates the Fts3Expr.aMI[] array for expression pExpr. If pExpr is part
-** of a NEAR expression, then it also allocates and populates the same array
-** for all other phrases that are part of the NEAR expression.
-**
-** SQLITE_OK is returned if the aMI[] array is successfully allocated and
-** populated. Otherwise, if an error occurs, an SQLite error code is returned.
-*/
-static int fts3EvalGatherStats(
- Fts3Cursor *pCsr, /* Cursor object */
- Fts3Expr *pExpr /* FTSQUERY_PHRASE expression */
-){
- int rc = SQLITE_OK; /* Return code */
-
- assert( pExpr->eType==FTSQUERY_PHRASE );
- if( pExpr->aMI==0 ){
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- Fts3Expr *pRoot; /* Root of NEAR expression */
- Fts3Expr *p; /* Iterator used for several purposes */
-
- sqlite3_int64 iPrevId = pCsr->iPrevId;
- sqlite3_int64 iDocid;
- u8 bEof;
-
- /* Find the root of the NEAR expression */
- pRoot = pExpr;
- while( pRoot->pParent && pRoot->pParent->eType==FTSQUERY_NEAR ){
- pRoot = pRoot->pParent;
- }
- iDocid = pRoot->iDocid;
- bEof = pRoot->bEof;
- assert( pRoot->bStart );
-
- /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */
- for(p=pRoot; p; p=p->pLeft){
- Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight);
- assert( pE->aMI==0 );
- pE->aMI = (u32 *)sqlite3_malloc(pTab->nColumn * 3 * sizeof(u32));
- if( !pE->aMI ) return SQLITE_NOMEM;
- memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32));
- }
-
- fts3EvalRestart(pCsr, pRoot, &rc);
-
- while( pCsr->isEof==0 && rc==SQLITE_OK ){
-
- do {
- /* Ensure the %_content statement is reset. */
- if( pCsr->isRequireSeek==0 ) sqlite3_reset(pCsr->pStmt);
- assert( sqlite3_data_count(pCsr->pStmt)==0 );
-
- /* Advance to the next document */
- fts3EvalNextRow(pCsr, pRoot, &rc);
- pCsr->isEof = pRoot->bEof;
- pCsr->isRequireSeek = 1;
- pCsr->isMatchinfoNeeded = 1;
- pCsr->iPrevId = pRoot->iDocid;
- }while( pCsr->isEof==0
- && pRoot->eType==FTSQUERY_NEAR
- && fts3EvalTestDeferredAndNear(pCsr, &rc)
- );
-
- if( rc==SQLITE_OK && pCsr->isEof==0 ){
- fts3EvalUpdateCounts(pRoot);
- }
- }
-
- pCsr->isEof = 0;
- pCsr->iPrevId = iPrevId;
-
- if( bEof ){
- pRoot->bEof = bEof;
- }else{
- /* Caution: pRoot may iterate through docids in ascending or descending
- ** order. For this reason, even though it seems more defensive, the
- ** do loop can not be written:
- **
- ** do {...} while( pRoot->iDocid<iDocid && rc==SQLITE_OK );
- */
- fts3EvalRestart(pCsr, pRoot, &rc);
- do {
- fts3EvalNextRow(pCsr, pRoot, &rc);
- assert( pRoot->bEof==0 );
- }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK );
- fts3EvalTestDeferredAndNear(pCsr, &rc);
- }
- }
- return rc;
-}
-
-/*
-** This function is used by the matchinfo() module to query a phrase
-** expression node for the following information:
-**
-** 1. The total number of occurrences of the phrase in each column of
-** the FTS table (considering all rows), and
-**
-** 2. For each column, the number of rows in the table for which the
-** column contains at least one instance of the phrase.
-**
-** If no error occurs, SQLITE_OK is returned and the values for each column
-** written into the array aiOut as follows:
-**
-** aiOut[iCol*3 + 1] = Number of occurrences
-** aiOut[iCol*3 + 2] = Number of rows containing at least one instance
-**
-** Caveats:
-**
-** * If a phrase consists entirely of deferred tokens, then all output
-** values are set to the number of documents in the table. In other
-** words we assume that very common tokens occur exactly once in each
-** column of each row of the table.
-**
-** * If a phrase contains some deferred tokens (and some non-deferred
-** tokens), count the potential occurrence identified by considering
-** the non-deferred tokens instead of actual phrase occurrences.
-**
-** * If the phrase is part of a NEAR expression, then only phrase instances
-** that meet the NEAR constraint are included in the counts.
-*/
-SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(
- Fts3Cursor *pCsr, /* FTS cursor handle */
- Fts3Expr *pExpr, /* Phrase expression */
- u32 *aiOut /* Array to write results into (see above) */
-){
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- int rc = SQLITE_OK;
- int iCol;
-
- if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){
- assert( pCsr->nDoc>0 );
- for(iCol=0; iCol<pTab->nColumn; iCol++){
- aiOut[iCol*3 + 1] = (u32)pCsr->nDoc;
- aiOut[iCol*3 + 2] = (u32)pCsr->nDoc;
- }
- }else{
- rc = fts3EvalGatherStats(pCsr, pExpr);
- if( rc==SQLITE_OK ){
- assert( pExpr->aMI );
- for(iCol=0; iCol<pTab->nColumn; iCol++){
- aiOut[iCol*3 + 1] = pExpr->aMI[iCol*3 + 1];
- aiOut[iCol*3 + 2] = pExpr->aMI[iCol*3 + 2];
- }
- }
- }
-
- return rc;
-}
-
-/*
-** The expression pExpr passed as the second argument to this function
-** must be of type FTSQUERY_PHRASE.
-**
-** The returned value is either NULL or a pointer to a buffer containing
-** a position-list indicating the occurrences of the phrase in column iCol
-** of the current row.
-**
-** More specifically, the returned buffer contains 1 varint for each
-** occurence of the phrase in the column, stored using the normal (delta+2)
-** compression and is terminated by either an 0x01 or 0x00 byte. For example,
-** if the requested column contains "a b X c d X X" and the position-list
-** for 'X' is requested, the buffer returned may contain:
-**
-** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00
-**
-** This function works regardless of whether or not the phrase is deferred,
-** incremental, or neither.
-*/
-SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
- Fts3Cursor *pCsr, /* FTS3 cursor object */
- Fts3Expr *pExpr, /* Phrase to return doclist for */
- int iCol, /* Column to return position list for */
- char **ppOut /* OUT: Pointer to position list */
-){
- Fts3Phrase *pPhrase = pExpr->pPhrase;
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- char *pIter;
- int iThis;
- sqlite3_int64 iDocid;
-
- /* If this phrase is applies specifically to some column other than
- ** column iCol, return a NULL pointer. */
- *ppOut = 0;
- assert( iCol>=0 && iCol<pTab->nColumn );
- if( (pPhrase->iColumn<pTab->nColumn && pPhrase->iColumn!=iCol) ){
- return SQLITE_OK;
- }
-
- iDocid = pExpr->iDocid;
- pIter = pPhrase->doclist.pList;
- if( iDocid!=pCsr->iPrevId || pExpr->bEof ){
- int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */
- int bOr = 0;
- u8 bEof = 0;
- Fts3Expr *p;
-
- /* Check if this phrase descends from an OR expression node. If not,
- ** return NULL. Otherwise, the entry that corresponds to docid
- ** pCsr->iPrevId may lie earlier in the doclist buffer. */
- for(p=pExpr->pParent; p; p=p->pParent){
- if( p->eType==FTSQUERY_OR ) bOr = 1;
- }
- if( bOr==0 ) return SQLITE_OK;
-
- /* This is the descendent of an OR node. In this case we cannot use
- ** an incremental phrase. Load the entire doclist for the phrase
- ** into memory in this case. */
- if( pPhrase->bIncr ){
- int rc = SQLITE_OK;
- int bEofSave = pExpr->bEof;
- fts3EvalRestart(pCsr, pExpr, &rc);
- while( rc==SQLITE_OK && !pExpr->bEof ){
- fts3EvalNextRow(pCsr, pExpr, &rc);
- if( bEofSave==0 && pExpr->iDocid==iDocid ) break;
- }
- pIter = pPhrase->doclist.pList;
- assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
- if( rc!=SQLITE_OK ) return rc;
- }
-
- if( pExpr->bEof ){
- pIter = 0;
- iDocid = 0;
- }
- bEof = (pPhrase->doclist.nAll==0);
- assert( bDescDoclist==0 || bDescDoclist==1 );
- assert( pCsr->bDesc==0 || pCsr->bDesc==1 );
-
- if( pCsr->bDesc==bDescDoclist ){
- int dummy;
- while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
- sqlite3Fts3DoclistPrev(
- bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
- &pIter, &iDocid, &dummy, &bEof
- );
- }
- }else{
- while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
- sqlite3Fts3DoclistNext(
- bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
- &pIter, &iDocid, &bEof
- );
- }
- }
-
- if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0;
- }
- if( pIter==0 ) return SQLITE_OK;
-
- if( *pIter==0x01 ){
- pIter++;
- pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
- }else{
- iThis = 0;
- }
- while( iThis<iCol ){
- fts3ColumnlistCopy(0, &pIter);
- if( *pIter==0x00 ) return 0;
- pIter++;
- pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
- }
-
- *ppOut = ((iCol==iThis)?pIter:0);
- return SQLITE_OK;
-}
-
-/*
-** Free all components of the Fts3Phrase structure that were allocated by
-** the eval module. Specifically, this means to free:
-**
-** * the contents of pPhrase->doclist, and
-** * any Fts3MultiSegReader objects held by phrase tokens.
-*/
-SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){
- if( pPhrase ){
- int i;
- sqlite3_free(pPhrase->doclist.aAll);
- fts3EvalInvalidatePoslist(pPhrase);
- memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist));
- for(i=0; i<pPhrase->nToken; i++){
- fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr);
- pPhrase->aToken[i].pSegcsr = 0;
- }
- }
-}
-
-
-/*
-** Return SQLITE_CORRUPT_VTAB.
-*/
-#ifdef SQLITE_DEBUG
-SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
- return SQLITE_CORRUPT_VTAB;
-}
-#endif
-
-#if !SQLITE_CORE
-/*
-** Initialize API pointer table, if required.
-*/
-SQLITE_API int sqlite3_extension_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi)
- return sqlite3Fts3Init(db);
-}
-#endif
-
-#endif
-
-/************** End of fts3.c ************************************************/
-/************** Begin file fts3_aux.c ****************************************/
-/*
-** 2011 Jan 27
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/* #include <string.h> */
-/* #include <assert.h> */
-
-typedef struct Fts3auxTable Fts3auxTable;
-typedef struct Fts3auxCursor Fts3auxCursor;
-
-struct Fts3auxTable {
- sqlite3_vtab base; /* Base class used by SQLite core */
- Fts3Table *pFts3Tab;
-};
-
-struct Fts3auxCursor {
- sqlite3_vtab_cursor base; /* Base class used by SQLite core */
- Fts3MultiSegReader csr; /* Must be right after "base" */
- Fts3SegFilter filter;
- char *zStop;
- int nStop; /* Byte-length of string zStop */
- int isEof; /* True if cursor is at EOF */
- sqlite3_int64 iRowid; /* Current rowid */
-
- int iCol; /* Current value of 'col' column */
- int nStat; /* Size of aStat[] array */
- struct Fts3auxColstats {
- sqlite3_int64 nDoc; /* 'documents' values for current csr row */
- sqlite3_int64 nOcc; /* 'occurrences' values for current csr row */
- } *aStat;
-};
-
-/*
-** Schema of the terms table.
-*/
-#define FTS3_TERMS_SCHEMA "CREATE TABLE x(term, col, documents, occurrences)"
-
-/*
-** This function does all the work for both the xConnect and xCreate methods.
-** These tables have no persistent representation of their own, so xConnect
-** and xCreate are identical operations.
-*/
-static int fts3auxConnectMethod(
- sqlite3 *db, /* Database connection */
- void *pUnused, /* Unused */
- int argc, /* Number of elements in argv array */
- const char * const *argv, /* xCreate/xConnect argument array */
- sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */
- char **pzErr /* OUT: sqlite3_malloc'd error message */
-){
- char const *zDb; /* Name of database (e.g. "main") */
- char const *zFts3; /* Name of fts3 table */
- int nDb; /* Result of strlen(zDb) */
- int nFts3; /* Result of strlen(zFts3) */
- int nByte; /* Bytes of space to allocate here */
- int rc; /* value returned by declare_vtab() */
- Fts3auxTable *p; /* Virtual table object to return */
-
- UNUSED_PARAMETER(pUnused);
-
- /* The user should specify a single argument - the name of an fts3 table. */
- if( argc!=4 ){
- *pzErr = sqlite3_mprintf(
- "wrong number of arguments to fts4aux constructor"
- );
- return SQLITE_ERROR;
- }
-
- zDb = argv[1];
- nDb = (int)strlen(zDb);
- zFts3 = argv[3];
- nFts3 = (int)strlen(zFts3);
-
- rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA);
- if( rc!=SQLITE_OK ) return rc;
-
- nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
- p = (Fts3auxTable *)sqlite3_malloc(nByte);
- if( !p ) return SQLITE_NOMEM;
- memset(p, 0, nByte);
-
- p->pFts3Tab = (Fts3Table *)&p[1];
- p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1];
- p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1];
- p->pFts3Tab->db = db;
- p->pFts3Tab->nIndex = 1;
-
- memcpy((char *)p->pFts3Tab->zDb, zDb, nDb);
- memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3);
- sqlite3Fts3Dequote((char *)p->pFts3Tab->zName);
-
- *ppVtab = (sqlite3_vtab *)p;
- return SQLITE_OK;
-}
-
-/*
-** This function does the work for both the xDisconnect and xDestroy methods.
-** These tables have no persistent representation of their own, so xDisconnect
-** and xDestroy are identical operations.
-*/
-static int fts3auxDisconnectMethod(sqlite3_vtab *pVtab){
- Fts3auxTable *p = (Fts3auxTable *)pVtab;
- Fts3Table *pFts3 = p->pFts3Tab;
- int i;
-
- /* Free any prepared statements held */
- for(i=0; i<SizeofArray(pFts3->aStmt); i++){
- sqlite3_finalize(pFts3->aStmt[i]);
- }
- sqlite3_free(pFts3->zSegmentsTbl);
- sqlite3_free(p);
- return SQLITE_OK;
-}
-
-#define FTS4AUX_EQ_CONSTRAINT 1
-#define FTS4AUX_GE_CONSTRAINT 2
-#define FTS4AUX_LE_CONSTRAINT 4
-
-/*
-** xBestIndex - Analyze a WHERE and ORDER BY clause.
-*/
-static int fts3auxBestIndexMethod(
- sqlite3_vtab *pVTab,
- sqlite3_index_info *pInfo
-){
- int i;
- int iEq = -1;
- int iGe = -1;
- int iLe = -1;
-
- UNUSED_PARAMETER(pVTab);
-
- /* This vtab delivers always results in "ORDER BY term ASC" order. */
- if( pInfo->nOrderBy==1
- && pInfo->aOrderBy[0].iColumn==0
- && pInfo->aOrderBy[0].desc==0
- ){
- pInfo->orderByConsumed = 1;
- }
-
- /* Search for equality and range constraints on the "term" column. */
- for(i=0; i<pInfo->nConstraint; i++){
- if( pInfo->aConstraint[i].usable && pInfo->aConstraint[i].iColumn==0 ){
- int op = pInfo->aConstraint[i].op;
- if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i;
- if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i;
- if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i;
- if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i;
- if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i;
- }
- }
-
- if( iEq>=0 ){
- pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT;
- pInfo->aConstraintUsage[iEq].argvIndex = 1;
- pInfo->estimatedCost = 5;
- }else{
- pInfo->idxNum = 0;
- pInfo->estimatedCost = 20000;
- if( iGe>=0 ){
- pInfo->idxNum += FTS4AUX_GE_CONSTRAINT;
- pInfo->aConstraintUsage[iGe].argvIndex = 1;
- pInfo->estimatedCost /= 2;
- }
- if( iLe>=0 ){
- pInfo->idxNum += FTS4AUX_LE_CONSTRAINT;
- pInfo->aConstraintUsage[iLe].argvIndex = 1 + (iGe>=0);
- pInfo->estimatedCost /= 2;
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** xOpen - Open a cursor.
-*/
-static int fts3auxOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
- Fts3auxCursor *pCsr; /* Pointer to cursor object to return */
-
- UNUSED_PARAMETER(pVTab);
-
- pCsr = (Fts3auxCursor *)sqlite3_malloc(sizeof(Fts3auxCursor));
- if( !pCsr ) return SQLITE_NOMEM;
- memset(pCsr, 0, sizeof(Fts3auxCursor));
-
- *ppCsr = (sqlite3_vtab_cursor *)pCsr;
- return SQLITE_OK;
-}
-
-/*
-** xClose - Close a cursor.
-*/
-static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){
- Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab;
- Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
-
- sqlite3Fts3SegmentsClose(pFts3);
- sqlite3Fts3SegReaderFinish(&pCsr->csr);
- sqlite3_free((void *)pCsr->filter.zTerm);
- sqlite3_free(pCsr->zStop);
- sqlite3_free(pCsr->aStat);
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){
- if( nSize>pCsr->nStat ){
- struct Fts3auxColstats *aNew;
- aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat,
- sizeof(struct Fts3auxColstats) * nSize
- );
- if( aNew==0 ) return SQLITE_NOMEM;
- memset(&aNew[pCsr->nStat], 0,
- sizeof(struct Fts3auxColstats) * (nSize - pCsr->nStat)
- );
- pCsr->aStat = aNew;
- pCsr->nStat = nSize;
- }
- return SQLITE_OK;
-}
-
-/*
-** xNext - Advance the cursor to the next row, if any.
-*/
-static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
- Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
- Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab;
- int rc;
-
- /* Increment our pretend rowid value. */
- pCsr->iRowid++;
-
- for(pCsr->iCol++; pCsr->iCol<pCsr->nStat; pCsr->iCol++){
- if( pCsr->aStat[pCsr->iCol].nDoc>0 ) return SQLITE_OK;
- }
-
- rc = sqlite3Fts3SegReaderStep(pFts3, &pCsr->csr);
- if( rc==SQLITE_ROW ){
- int i = 0;
- int nDoclist = pCsr->csr.nDoclist;
- char *aDoclist = pCsr->csr.aDoclist;
- int iCol;
-
- int eState = 0;
-
- if( pCsr->zStop ){
- int n = (pCsr->nStop<pCsr->csr.nTerm) ? pCsr->nStop : pCsr->csr.nTerm;
- int mc = memcmp(pCsr->zStop, pCsr->csr.zTerm, n);
- if( mc<0 || (mc==0 && pCsr->csr.nTerm>pCsr->nStop) ){
- pCsr->isEof = 1;
- return SQLITE_OK;
- }
- }
-
- if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM;
- memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat);
- iCol = 0;
-
- while( i<nDoclist ){
- sqlite3_int64 v = 0;
-
- i += sqlite3Fts3GetVarint(&aDoclist[i], &v);
- switch( eState ){
- /* State 0. In this state the integer just read was a docid. */
- case 0:
- pCsr->aStat[0].nDoc++;
- eState = 1;
- iCol = 0;
- break;
-
- /* State 1. In this state we are expecting either a 1, indicating
- ** that the following integer will be a column number, or the
- ** start of a position list for column 0.
- **
- ** The only difference between state 1 and state 2 is that if the
- ** integer encountered in state 1 is not 0 or 1, then we need to
- ** increment the column 0 "nDoc" count for this term.
- */
- case 1:
- assert( iCol==0 );
- if( v>1 ){
- pCsr->aStat[1].nDoc++;
- }
- eState = 2;
- /* fall through */
-
- case 2:
- if( v==0 ){ /* 0x00. Next integer will be a docid. */
- eState = 0;
- }else if( v==1 ){ /* 0x01. Next integer will be a column number. */
- eState = 3;
- }else{ /* 2 or greater. A position. */
- pCsr->aStat[iCol+1].nOcc++;
- pCsr->aStat[0].nOcc++;
- }
- break;
-
- /* State 3. The integer just read is a column number. */
- default: assert( eState==3 );
- iCol = (int)v;
- if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM;
- pCsr->aStat[iCol+1].nDoc++;
- eState = 2;
- break;
- }
- }
-
- pCsr->iCol = 0;
- rc = SQLITE_OK;
- }else{
- pCsr->isEof = 1;
- }
- return rc;
-}
-
-/*
-** xFilter - Initialize a cursor to point at the start of its data.
-*/
-static int fts3auxFilterMethod(
- sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */
- int idxNum, /* Strategy index */
- const char *idxStr, /* Unused */
- int nVal, /* Number of elements in apVal */
- sqlite3_value **apVal /* Arguments for the indexing scheme */
-){
- Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
- Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab;
- int rc;
- int isScan;
-
- UNUSED_PARAMETER(nVal);
- UNUSED_PARAMETER(idxStr);
-
- assert( idxStr==0 );
- assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0
- || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT
- || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT)
- );
- isScan = (idxNum!=FTS4AUX_EQ_CONSTRAINT);
-
- /* In case this cursor is being reused, close and zero it. */
- testcase(pCsr->filter.zTerm);
- sqlite3Fts3SegReaderFinish(&pCsr->csr);
- sqlite3_free((void *)pCsr->filter.zTerm);
- sqlite3_free(pCsr->aStat);
- memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr);
-
- pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY;
- if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN;
-
- if( idxNum&(FTS4AUX_EQ_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) ){
- const unsigned char *zStr = sqlite3_value_text(apVal[0]);
- if( zStr ){
- pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr);
- pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]);
- if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM;
- }
- }
- if( idxNum&FTS4AUX_LE_CONSTRAINT ){
- int iIdx = (idxNum&FTS4AUX_GE_CONSTRAINT) ? 1 : 0;
- pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iIdx]));
- pCsr->nStop = sqlite3_value_bytes(apVal[iIdx]);
- if( pCsr->zStop==0 ) return SQLITE_NOMEM;
- }
-
- rc = sqlite3Fts3SegReaderCursor(pFts3, 0, 0, FTS3_SEGCURSOR_ALL,
- pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr
- );
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter);
- }
-
- if( rc==SQLITE_OK ) rc = fts3auxNextMethod(pCursor);
- return rc;
-}
-
-/*
-** xEof - Return true if the cursor is at EOF, or false otherwise.
-*/
-static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){
- Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
- return pCsr->isEof;
-}
-
-/*
-** xColumn - Return a column value.
-*/
-static int fts3auxColumnMethod(
- sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
- sqlite3_context *pContext, /* Context for sqlite3_result_xxx() calls */
- int iCol /* Index of column to read value from */
-){
- Fts3auxCursor *p = (Fts3auxCursor *)pCursor;
-
- assert( p->isEof==0 );
- if( iCol==0 ){ /* Column "term" */
- sqlite3_result_text(pContext, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT);
- }else if( iCol==1 ){ /* Column "col" */
- if( p->iCol ){
- sqlite3_result_int(pContext, p->iCol-1);
- }else{
- sqlite3_result_text(pContext, "*", -1, SQLITE_STATIC);
- }
- }else if( iCol==2 ){ /* Column "documents" */
- sqlite3_result_int64(pContext, p->aStat[p->iCol].nDoc);
- }else{ /* Column "occurrences" */
- sqlite3_result_int64(pContext, p->aStat[p->iCol].nOcc);
- }
-
- return SQLITE_OK;
-}
-
-/*
-** xRowid - Return the current rowid for the cursor.
-*/
-static int fts3auxRowidMethod(
- sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
- sqlite_int64 *pRowid /* OUT: Rowid value */
-){
- Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
- *pRowid = pCsr->iRowid;
- return SQLITE_OK;
-}
-
-/*
-** Register the fts3aux module with database connection db. Return SQLITE_OK
-** if successful or an error code if sqlite3_create_module() fails.
-*/
-SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){
- static const sqlite3_module fts3aux_module = {
- 0, /* iVersion */
- fts3auxConnectMethod, /* xCreate */
- fts3auxConnectMethod, /* xConnect */
- fts3auxBestIndexMethod, /* xBestIndex */
- fts3auxDisconnectMethod, /* xDisconnect */
- fts3auxDisconnectMethod, /* xDestroy */
- fts3auxOpenMethod, /* xOpen */
- fts3auxCloseMethod, /* xClose */
- fts3auxFilterMethod, /* xFilter */
- fts3auxNextMethod, /* xNext */
- fts3auxEofMethod, /* xEof */
- fts3auxColumnMethod, /* xColumn */
- fts3auxRowidMethod, /* xRowid */
- 0, /* xUpdate */
- 0, /* xBegin */
- 0, /* xSync */
- 0, /* xCommit */
- 0, /* xRollback */
- 0, /* xFindFunction */
- 0, /* xRename */
- 0, /* xSavepoint */
- 0, /* xRelease */
- 0 /* xRollbackTo */
- };
- int rc; /* Return code */
-
- rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0);
- return rc;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_aux.c ********************************************/
-/************** Begin file fts3_expr.c ***************************************/
-/*
-** 2008 Nov 28
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This module contains code that implements a parser for fts3 query strings
-** (the right-hand argument to the MATCH operator). Because the supported
-** syntax is relatively simple, the whole tokenizer/parser system is
-** hand-coded.
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/*
-** By default, this module parses the legacy syntax that has been
-** traditionally used by fts3. Or, if SQLITE_ENABLE_FTS3_PARENTHESIS
-** is defined, then it uses the new syntax. The differences between
-** the new and the old syntaxes are:
-**
-** a) The new syntax supports parenthesis. The old does not.
-**
-** b) The new syntax supports the AND and NOT operators. The old does not.
-**
-** c) The old syntax supports the "-" token qualifier. This is not
-** supported by the new syntax (it is replaced by the NOT operator).
-**
-** d) When using the old syntax, the OR operator has a greater precedence
-** than an implicit AND. When using the new, both implicity and explicit
-** AND operators have a higher precedence than OR.
-**
-** If compiled with SQLITE_TEST defined, then this module exports the
-** symbol "int sqlite3_fts3_enable_parentheses". Setting this variable
-** to zero causes the module to use the old syntax. If it is set to
-** non-zero the new syntax is activated. This is so both syntaxes can
-** be tested using a single build of testfixture.
-**
-** The following describes the syntax supported by the fts3 MATCH
-** operator in a similar format to that used by the lemon parser
-** generator. This module does not use actually lemon, it uses a
-** custom parser.
-**
-** query ::= andexpr (OR andexpr)*.
-**
-** andexpr ::= notexpr (AND? notexpr)*.
-**
-** notexpr ::= nearexpr (NOT nearexpr|-TOKEN)*.
-** notexpr ::= LP query RP.
-**
-** nearexpr ::= phrase (NEAR distance_opt nearexpr)*.
-**
-** distance_opt ::= .
-** distance_opt ::= / INTEGER.
-**
-** phrase ::= TOKEN.
-** phrase ::= COLUMN:TOKEN.
-** phrase ::= "TOKEN TOKEN TOKEN...".
-*/
-
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_fts3_enable_parentheses = 0;
-#else
-# ifdef SQLITE_ENABLE_FTS3_PARENTHESIS
-# define sqlite3_fts3_enable_parentheses 1
-# else
-# define sqlite3_fts3_enable_parentheses 0
-# endif
-#endif
-
-/*
-** Default span for NEAR operators.
-*/
-#define SQLITE_FTS3_DEFAULT_NEAR_PARAM 10
-
-/* #include <string.h> */
-/* #include <assert.h> */
-
-/*
-** isNot:
-** This variable is used by function getNextNode(). When getNextNode() is
-** called, it sets ParseContext.isNot to true if the 'next node' is a
-** FTSQUERY_PHRASE with a unary "-" attached to it. i.e. "mysql" in the
-** FTS3 query "sqlite -mysql". Otherwise, ParseContext.isNot is set to
-** zero.
-*/
-typedef struct ParseContext ParseContext;
-struct ParseContext {
- sqlite3_tokenizer *pTokenizer; /* Tokenizer module */
- int iLangid; /* Language id used with tokenizer */
- const char **azCol; /* Array of column names for fts3 table */
- int bFts4; /* True to allow FTS4-only syntax */
- int nCol; /* Number of entries in azCol[] */
- int iDefaultCol; /* Default column to query */
- int isNot; /* True if getNextNode() sees a unary - */
- sqlite3_context *pCtx; /* Write error message here */
- int nNest; /* Number of nested brackets */
-};
-
-/*
-** This function is equivalent to the standard isspace() function.
-**
-** The standard isspace() can be awkward to use safely, because although it
-** is defined to accept an argument of type int, its behaviour when passed
-** an integer that falls outside of the range of the unsigned char type
-** is undefined (and sometimes, "undefined" means segfault). This wrapper
-** is defined to accept an argument of type char, and always returns 0 for
-** any values that fall outside of the range of the unsigned char type (i.e.
-** negative values).
-*/
-static int fts3isspace(char c){
- return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
-}
-
-/*
-** Allocate nByte bytes of memory using sqlite3_malloc(). If successful,
-** zero the memory before returning a pointer to it. If unsuccessful,
-** return NULL.
-*/
-static void *fts3MallocZero(int nByte){
- void *pRet = sqlite3_malloc(nByte);
- if( pRet ) memset(pRet, 0, nByte);
- return pRet;
-}
-
-SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(
- sqlite3_tokenizer *pTokenizer,
- int iLangid,
- const char *z,
- int n,
- sqlite3_tokenizer_cursor **ppCsr
-){
- sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
- sqlite3_tokenizer_cursor *pCsr = 0;
- int rc;
-
- rc = pModule->xOpen(pTokenizer, z, n, &pCsr);
- assert( rc==SQLITE_OK || pCsr==0 );
- if( rc==SQLITE_OK ){
- pCsr->pTokenizer = pTokenizer;
- if( pModule->iVersion>=1 ){
- rc = pModule->xLanguageid(pCsr, iLangid);
- if( rc!=SQLITE_OK ){
- pModule->xClose(pCsr);
- pCsr = 0;
- }
- }
- }
- *ppCsr = pCsr;
- return rc;
-}
-
-
-/*
-** Extract the next token from buffer z (length n) using the tokenizer
-** and other information (column names etc.) in pParse. Create an Fts3Expr
-** structure of type FTSQUERY_PHRASE containing a phrase consisting of this
-** single token and set *ppExpr to point to it. If the end of the buffer is
-** reached before a token is found, set *ppExpr to zero. It is the
-** responsibility of the caller to eventually deallocate the allocated
-** Fts3Expr structure (if any) by passing it to sqlite3_free().
-**
-** Return SQLITE_OK if successful, or SQLITE_NOMEM if a memory allocation
-** fails.
-*/
-static int getNextToken(
- ParseContext *pParse, /* fts3 query parse context */
- int iCol, /* Value for Fts3Phrase.iColumn */
- const char *z, int n, /* Input string */
- Fts3Expr **ppExpr, /* OUT: expression */
- int *pnConsumed /* OUT: Number of bytes consumed */
-){
- sqlite3_tokenizer *pTokenizer = pParse->pTokenizer;
- sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
- int rc;
- sqlite3_tokenizer_cursor *pCursor;
- Fts3Expr *pRet = 0;
- int nConsumed = 0;
-
- rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
- if( rc==SQLITE_OK ){
- const char *zToken;
- int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
- int nByte; /* total space to allocate */
-
- rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
- if( rc==SQLITE_OK ){
- nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
- pRet = (Fts3Expr *)fts3MallocZero(nByte);
- if( !pRet ){
- rc = SQLITE_NOMEM;
- }else{
- pRet->eType = FTSQUERY_PHRASE;
- pRet->pPhrase = (Fts3Phrase *)&pRet[1];
- pRet->pPhrase->nToken = 1;
- pRet->pPhrase->iColumn = iCol;
- pRet->pPhrase->aToken[0].n = nToken;
- pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1];
- memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken);
-
- if( iEnd<n && z[iEnd]=='*' ){
- pRet->pPhrase->aToken[0].isPrefix = 1;
- iEnd++;
- }
-
- while( 1 ){
- if( !sqlite3_fts3_enable_parentheses
- && iStart>0 && z[iStart-1]=='-'
- ){
- pParse->isNot = 1;
- iStart--;
- }else if( pParse->bFts4 && iStart>0 && z[iStart-1]=='^' ){
- pRet->pPhrase->aToken[0].bFirst = 1;
- iStart--;
- }else{
- break;
- }
- }
-
- }
- nConsumed = iEnd;
- }
-
- pModule->xClose(pCursor);
- }
-
- *pnConsumed = nConsumed;
- *ppExpr = pRet;
- return rc;
-}
-
-
-/*
-** Enlarge a memory allocation. If an out-of-memory allocation occurs,
-** then free the old allocation.
-*/
-static void *fts3ReallocOrFree(void *pOrig, int nNew){
- void *pRet = sqlite3_realloc(pOrig, nNew);
- if( !pRet ){
- sqlite3_free(pOrig);
- }
- return pRet;
-}
-
-/*
-** Buffer zInput, length nInput, contains the contents of a quoted string
-** that appeared as part of an fts3 query expression. Neither quote character
-** is included in the buffer. This function attempts to tokenize the entire
-** input buffer and create an Fts3Expr structure of type FTSQUERY_PHRASE
-** containing the results.
-**
-** If successful, SQLITE_OK is returned and *ppExpr set to point at the
-** allocated Fts3Expr structure. Otherwise, either SQLITE_NOMEM (out of memory
-** error) or SQLITE_ERROR (tokenization error) is returned and *ppExpr set
-** to 0.
-*/
-static int getNextString(
- ParseContext *pParse, /* fts3 query parse context */
- const char *zInput, int nInput, /* Input string */
- Fts3Expr **ppExpr /* OUT: expression */
-){
- sqlite3_tokenizer *pTokenizer = pParse->pTokenizer;
- sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
- int rc;
- Fts3Expr *p = 0;
- sqlite3_tokenizer_cursor *pCursor = 0;
- char *zTemp = 0;
- int nTemp = 0;
-
- const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase);
- int nToken = 0;
-
- /* The final Fts3Expr data structure, including the Fts3Phrase,
- ** Fts3PhraseToken structures token buffers are all stored as a single
- ** allocation so that the expression can be freed with a single call to
- ** sqlite3_free(). Setting this up requires a two pass approach.
- **
- ** The first pass, in the block below, uses a tokenizer cursor to iterate
- ** through the tokens in the expression. This pass uses fts3ReallocOrFree()
- ** to assemble data in two dynamic buffers:
- **
- ** Buffer p: Points to the Fts3Expr structure, followed by the Fts3Phrase
- ** structure, followed by the array of Fts3PhraseToken
- ** structures. This pass only populates the Fts3PhraseToken array.
- **
- ** Buffer zTemp: Contains copies of all tokens.
- **
- ** The second pass, in the block that begins "if( rc==SQLITE_DONE )" below,
- ** appends buffer zTemp to buffer p, and fills in the Fts3Expr and Fts3Phrase
- ** structures.
- */
- rc = sqlite3Fts3OpenTokenizer(
- pTokenizer, pParse->iLangid, zInput, nInput, &pCursor);
- if( rc==SQLITE_OK ){
- int ii;
- for(ii=0; rc==SQLITE_OK; ii++){
- const char *zByte;
- int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0;
- rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos);
- if( rc==SQLITE_OK ){
- Fts3PhraseToken *pToken;
-
- p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken));
- if( !p ) goto no_mem;
-
- zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte);
- if( !zTemp ) goto no_mem;
-
- assert( nToken==ii );
- pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii];
- memset(pToken, 0, sizeof(Fts3PhraseToken));
-
- memcpy(&zTemp[nTemp], zByte, nByte);
- nTemp += nByte;
-
- pToken->n = nByte;
- pToken->isPrefix = (iEnd<nInput && zInput[iEnd]=='*');
- pToken->bFirst = (iBegin>0 && zInput[iBegin-1]=='^');
- nToken = ii+1;
- }
- }
-
- pModule->xClose(pCursor);
- pCursor = 0;
- }
-
- if( rc==SQLITE_DONE ){
- int jj;
- char *zBuf = 0;
-
- p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp);
- if( !p ) goto no_mem;
- memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p);
- p->eType = FTSQUERY_PHRASE;
- p->pPhrase = (Fts3Phrase *)&p[1];
- p->pPhrase->iColumn = pParse->iDefaultCol;
- p->pPhrase->nToken = nToken;
-
- zBuf = (char *)&p->pPhrase->aToken[nToken];
- if( zTemp ){
- memcpy(zBuf, zTemp, nTemp);
- sqlite3_free(zTemp);
- }else{
- assert( nTemp==0 );
- }
-
- for(jj=0; jj<p->pPhrase->nToken; jj++){
- p->pPhrase->aToken[jj].z = zBuf;
- zBuf += p->pPhrase->aToken[jj].n;
- }
- rc = SQLITE_OK;
- }
-
- *ppExpr = p;
- return rc;
-no_mem:
-
- if( pCursor ){
- pModule->xClose(pCursor);
- }
- sqlite3_free(zTemp);
- sqlite3_free(p);
- *ppExpr = 0;
- return SQLITE_NOMEM;
-}
-
-/*
-** Function getNextNode(), which is called by fts3ExprParse(), may itself
-** call fts3ExprParse(). So this forward declaration is required.
-*/
-static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *);
-
-/*
-** The output variable *ppExpr is populated with an allocated Fts3Expr
-** structure, or set to 0 if the end of the input buffer is reached.
-**
-** Returns an SQLite error code. SQLITE_OK if everything works, SQLITE_NOMEM
-** if a malloc failure occurs, or SQLITE_ERROR if a parse error is encountered.
-** If SQLITE_ERROR is returned, pContext is populated with an error message.
-*/
-static int getNextNode(
- ParseContext *pParse, /* fts3 query parse context */
- const char *z, int n, /* Input string */
- Fts3Expr **ppExpr, /* OUT: expression */
- int *pnConsumed /* OUT: Number of bytes consumed */
-){
- static const struct Fts3Keyword {
- char *z; /* Keyword text */
- unsigned char n; /* Length of the keyword */
- unsigned char parenOnly; /* Only valid in paren mode */
- unsigned char eType; /* Keyword code */
- } aKeyword[] = {
- { "OR" , 2, 0, FTSQUERY_OR },
- { "AND", 3, 1, FTSQUERY_AND },
- { "NOT", 3, 1, FTSQUERY_NOT },
- { "NEAR", 4, 0, FTSQUERY_NEAR }
- };
- int ii;
- int iCol;
- int iColLen;
- int rc;
- Fts3Expr *pRet = 0;
-
- const char *zInput = z;
- int nInput = n;
-
- pParse->isNot = 0;
-
- /* Skip over any whitespace before checking for a keyword, an open or
- ** close bracket, or a quoted string.
- */
- while( nInput>0 && fts3isspace(*zInput) ){
- nInput--;
- zInput++;
- }
- if( nInput==0 ){
- return SQLITE_DONE;
- }
-
- /* See if we are dealing with a keyword. */
- for(ii=0; ii<(int)(sizeof(aKeyword)/sizeof(struct Fts3Keyword)); ii++){
- const struct Fts3Keyword *pKey = &aKeyword[ii];
-
- if( (pKey->parenOnly & ~sqlite3_fts3_enable_parentheses)!=0 ){
- continue;
- }
-
- if( nInput>=pKey->n && 0==memcmp(zInput, pKey->z, pKey->n) ){
- int nNear = SQLITE_FTS3_DEFAULT_NEAR_PARAM;
- int nKey = pKey->n;
- char cNext;
-
- /* If this is a "NEAR" keyword, check for an explicit nearness. */
- if( pKey->eType==FTSQUERY_NEAR ){
- assert( nKey==4 );
- if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){
- nNear = 0;
- for(nKey=5; zInput[nKey]>='0' && zInput[nKey]<='9'; nKey++){
- nNear = nNear * 10 + (zInput[nKey] - '0');
- }
- }
- }
-
- /* At this point this is probably a keyword. But for that to be true,
- ** the next byte must contain either whitespace, an open or close
- ** parenthesis, a quote character, or EOF.
- */
- cNext = zInput[nKey];
- if( fts3isspace(cNext)
- || cNext=='"' || cNext=='(' || cNext==')' || cNext==0
- ){
- pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr));
- if( !pRet ){
- return SQLITE_NOMEM;
- }
- pRet->eType = pKey->eType;
- pRet->nNear = nNear;
- *ppExpr = pRet;
- *pnConsumed = (int)((zInput - z) + nKey);
- return SQLITE_OK;
- }
-
- /* Turns out that wasn't a keyword after all. This happens if the
- ** user has supplied a token such as "ORacle". Continue.
- */
- }
- }
-
- /* Check for an open bracket. */
- if( sqlite3_fts3_enable_parentheses ){
- if( *zInput=='(' ){
- int nConsumed;
- pParse->nNest++;
- rc = fts3ExprParse(pParse, &zInput[1], nInput-1, ppExpr, &nConsumed);
- if( rc==SQLITE_OK && !*ppExpr ){
- rc = SQLITE_DONE;
- }
- *pnConsumed = (int)((zInput - z) + 1 + nConsumed);
- return rc;
- }
-
- /* Check for a close bracket. */
- if( *zInput==')' ){
- pParse->nNest--;
- *pnConsumed = (int)((zInput - z) + 1);
- return SQLITE_DONE;
- }
- }
-
- /* See if we are dealing with a quoted phrase. If this is the case, then
- ** search for the closing quote and pass the whole string to getNextString()
- ** for processing. This is easy to do, as fts3 has no syntax for escaping
- ** a quote character embedded in a string.
- */
- if( *zInput=='"' ){
- for(ii=1; ii<nInput && zInput[ii]!='"'; ii++);
- *pnConsumed = (int)((zInput - z) + ii + 1);
- if( ii==nInput ){
- return SQLITE_ERROR;
- }
- return getNextString(pParse, &zInput[1], ii-1, ppExpr);
- }
-
-
- /* If control flows to this point, this must be a regular token, or
- ** the end of the input. Read a regular token using the sqlite3_tokenizer
- ** interface. Before doing so, figure out if there is an explicit
- ** column specifier for the token.
- **
- ** TODO: Strangely, it is not possible to associate a column specifier
- ** with a quoted phrase, only with a single token. Not sure if this was
- ** an implementation artifact or an intentional decision when fts3 was
- ** first implemented. Whichever it was, this module duplicates the
- ** limitation.
- */
- iCol = pParse->iDefaultCol;
- iColLen = 0;
- for(ii=0; ii<pParse->nCol; ii++){
- const char *zStr = pParse->azCol[ii];
- int nStr = (int)strlen(zStr);
- if( nInput>nStr && zInput[nStr]==':'
- && sqlite3_strnicmp(zStr, zInput, nStr)==0
- ){
- iCol = ii;
- iColLen = (int)((zInput - z) + nStr + 1);
- break;
- }
- }
- rc = getNextToken(pParse, iCol, &z[iColLen], n-iColLen, ppExpr, pnConsumed);
- *pnConsumed += iColLen;
- return rc;
-}
-
-/*
-** The argument is an Fts3Expr structure for a binary operator (any type
-** except an FTSQUERY_PHRASE). Return an integer value representing the
-** precedence of the operator. Lower values have a higher precedence (i.e.
-** group more tightly). For example, in the C language, the == operator
-** groups more tightly than ||, and would therefore have a higher precedence.
-**
-** When using the new fts3 query syntax (when SQLITE_ENABLE_FTS3_PARENTHESIS
-** is defined), the order of the operators in precedence from highest to
-** lowest is:
-**
-** NEAR
-** NOT
-** AND (including implicit ANDs)
-** OR
-**
-** Note that when using the old query syntax, the OR operator has a higher
-** precedence than the AND operator.
-*/
-static int opPrecedence(Fts3Expr *p){
- assert( p->eType!=FTSQUERY_PHRASE );
- if( sqlite3_fts3_enable_parentheses ){
- return p->eType;
- }else if( p->eType==FTSQUERY_NEAR ){
- return 1;
- }else if( p->eType==FTSQUERY_OR ){
- return 2;
- }
- assert( p->eType==FTSQUERY_AND );
- return 3;
-}
-
-/*
-** Argument ppHead contains a pointer to the current head of a query
-** expression tree being parsed. pPrev is the expression node most recently
-** inserted into the tree. This function adds pNew, which is always a binary
-** operator node, into the expression tree based on the relative precedence
-** of pNew and the existing nodes of the tree. This may result in the head
-** of the tree changing, in which case *ppHead is set to the new root node.
-*/
-static void insertBinaryOperator(
- Fts3Expr **ppHead, /* Pointer to the root node of a tree */
- Fts3Expr *pPrev, /* Node most recently inserted into the tree */
- Fts3Expr *pNew /* New binary node to insert into expression tree */
-){
- Fts3Expr *pSplit = pPrev;
- while( pSplit->pParent && opPrecedence(pSplit->pParent)<=opPrecedence(pNew) ){
- pSplit = pSplit->pParent;
- }
-
- if( pSplit->pParent ){
- assert( pSplit->pParent->pRight==pSplit );
- pSplit->pParent->pRight = pNew;
- pNew->pParent = pSplit->pParent;
- }else{
- *ppHead = pNew;
- }
- pNew->pLeft = pSplit;
- pSplit->pParent = pNew;
-}
-
-/*
-** Parse the fts3 query expression found in buffer z, length n. This function
-** returns either when the end of the buffer is reached or an unmatched
-** closing bracket - ')' - is encountered.
-**
-** If successful, SQLITE_OK is returned, *ppExpr is set to point to the
-** parsed form of the expression and *pnConsumed is set to the number of
-** bytes read from buffer z. Otherwise, *ppExpr is set to 0 and SQLITE_NOMEM
-** (out of memory error) or SQLITE_ERROR (parse error) is returned.
-*/
-static int fts3ExprParse(
- ParseContext *pParse, /* fts3 query parse context */
- const char *z, int n, /* Text of MATCH query */
- Fts3Expr **ppExpr, /* OUT: Parsed query structure */
- int *pnConsumed /* OUT: Number of bytes consumed */
-){
- Fts3Expr *pRet = 0;
- Fts3Expr *pPrev = 0;
- Fts3Expr *pNotBranch = 0; /* Only used in legacy parse mode */
- int nIn = n;
- const char *zIn = z;
- int rc = SQLITE_OK;
- int isRequirePhrase = 1;
-
- while( rc==SQLITE_OK ){
- Fts3Expr *p = 0;
- int nByte = 0;
- rc = getNextNode(pParse, zIn, nIn, &p, &nByte);
- if( rc==SQLITE_OK ){
- int isPhrase;
-
- if( !sqlite3_fts3_enable_parentheses
- && p->eType==FTSQUERY_PHRASE && pParse->isNot
- ){
- /* Create an implicit NOT operator. */
- Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr));
- if( !pNot ){
- sqlite3Fts3ExprFree(p);
- rc = SQLITE_NOMEM;
- goto exprparse_out;
- }
- pNot->eType = FTSQUERY_NOT;
- pNot->pRight = p;
- if( pNotBranch ){
- pNot->pLeft = pNotBranch;
- }
- pNotBranch = pNot;
- p = pPrev;
- }else{
- int eType = p->eType;
- isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft);
-
- /* The isRequirePhrase variable is set to true if a phrase or
- ** an expression contained in parenthesis is required. If a
- ** binary operator (AND, OR, NOT or NEAR) is encounted when
- ** isRequirePhrase is set, this is a syntax error.
- */
- if( !isPhrase && isRequirePhrase ){
- sqlite3Fts3ExprFree(p);
- rc = SQLITE_ERROR;
- goto exprparse_out;
- }
-
- if( isPhrase && !isRequirePhrase ){
- /* Insert an implicit AND operator. */
- Fts3Expr *pAnd;
- assert( pRet && pPrev );
- pAnd = fts3MallocZero(sizeof(Fts3Expr));
- if( !pAnd ){
- sqlite3Fts3ExprFree(p);
- rc = SQLITE_NOMEM;
- goto exprparse_out;
- }
- pAnd->eType = FTSQUERY_AND;
- insertBinaryOperator(&pRet, pPrev, pAnd);
- pPrev = pAnd;
- }
-
- /* This test catches attempts to make either operand of a NEAR
- ** operator something other than a phrase. For example, either of
- ** the following:
- **
- ** (bracketed expression) NEAR phrase
- ** phrase NEAR (bracketed expression)
- **
- ** Return an error in either case.
- */
- if( pPrev && (
- (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE)
- || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR)
- )){
- sqlite3Fts3ExprFree(p);
- rc = SQLITE_ERROR;
- goto exprparse_out;
- }
-
- if( isPhrase ){
- if( pRet ){
- assert( pPrev && pPrev->pLeft && pPrev->pRight==0 );
- pPrev->pRight = p;
- p->pParent = pPrev;
- }else{
- pRet = p;
- }
- }else{
- insertBinaryOperator(&pRet, pPrev, p);
- }
- isRequirePhrase = !isPhrase;
- }
- assert( nByte>0 );
- }
- assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) );
- nIn -= nByte;
- zIn += nByte;
- pPrev = p;
- }
-
- if( rc==SQLITE_DONE && pRet && isRequirePhrase ){
- rc = SQLITE_ERROR;
- }
-
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- if( !sqlite3_fts3_enable_parentheses && pNotBranch ){
- if( !pRet ){
- rc = SQLITE_ERROR;
- }else{
- Fts3Expr *pIter = pNotBranch;
- while( pIter->pLeft ){
- pIter = pIter->pLeft;
- }
- pIter->pLeft = pRet;
- pRet = pNotBranch;
- }
- }
- }
- *pnConsumed = n - nIn;
-
-exprparse_out:
- if( rc!=SQLITE_OK ){
- sqlite3Fts3ExprFree(pRet);
- sqlite3Fts3ExprFree(pNotBranch);
- pRet = 0;
- }
- *ppExpr = pRet;
- return rc;
-}
-
-/*
-** Parameters z and n contain a pointer to and length of a buffer containing
-** an fts3 query expression, respectively. This function attempts to parse the
-** query expression and create a tree of Fts3Expr structures representing the
-** parsed expression. If successful, *ppExpr is set to point to the head
-** of the parsed expression tree and SQLITE_OK is returned. If an error
-** occurs, either SQLITE_NOMEM (out-of-memory error) or SQLITE_ERROR (parse
-** error) is returned and *ppExpr is set to 0.
-**
-** If parameter n is a negative number, then z is assumed to point to a
-** nul-terminated string and the length is determined using strlen().
-**
-** The first parameter, pTokenizer, is passed the fts3 tokenizer module to
-** use to normalize query tokens while parsing the expression. The azCol[]
-** array, which is assumed to contain nCol entries, should contain the names
-** of each column in the target fts3 table, in order from left to right.
-** Column names must be nul-terminated strings.
-**
-** The iDefaultCol parameter should be passed the index of the table column
-** that appears on the left-hand-side of the MATCH operator (the default
-** column to match against for tokens for which a column name is not explicitly
-** specified as part of the query string), or -1 if tokens may by default
-** match any table column.
-*/
-SQLITE_PRIVATE int sqlite3Fts3ExprParse(
- sqlite3_tokenizer *pTokenizer, /* Tokenizer module */
- int iLangid, /* Language id for tokenizer */
- char **azCol, /* Array of column names for fts3 table */
- int bFts4, /* True to allow FTS4-only syntax */
- int nCol, /* Number of entries in azCol[] */
- int iDefaultCol, /* Default column to query */
- const char *z, int n, /* Text of MATCH query */
- Fts3Expr **ppExpr /* OUT: Parsed query structure */
-){
- int nParsed;
- int rc;
- ParseContext sParse;
-
- memset(&sParse, 0, sizeof(ParseContext));
- sParse.pTokenizer = pTokenizer;
- sParse.iLangid = iLangid;
- sParse.azCol = (const char **)azCol;
- sParse.nCol = nCol;
- sParse.iDefaultCol = iDefaultCol;
- sParse.bFts4 = bFts4;
- if( z==0 ){
- *ppExpr = 0;
- return SQLITE_OK;
- }
- if( n<0 ){
- n = (int)strlen(z);
- }
- rc = fts3ExprParse(&sParse, z, n, ppExpr, &nParsed);
-
- /* Check for mismatched parenthesis */
- if( rc==SQLITE_OK && sParse.nNest ){
- rc = SQLITE_ERROR;
- sqlite3Fts3ExprFree(*ppExpr);
- *ppExpr = 0;
- }
-
- return rc;
-}
-
-/*
-** Free a parsed fts3 query expression allocated by sqlite3Fts3ExprParse().
-*/
-SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *p){
- if( p ){
- assert( p->eType==FTSQUERY_PHRASE || p->pPhrase==0 );
- sqlite3Fts3ExprFree(p->pLeft);
- sqlite3Fts3ExprFree(p->pRight);
- sqlite3Fts3EvalPhraseCleanup(p->pPhrase);
- sqlite3_free(p->aMI);
- sqlite3_free(p);
- }
-}
-
-/****************************************************************************
-*****************************************************************************
-** Everything after this point is just test code.
-*/
-
-#ifdef SQLITE_TEST
-
-/* #include <stdio.h> */
-
-/*
-** Function to query the hash-table of tokenizers (see README.tokenizers).
-*/
-static int queryTestTokenizer(
- sqlite3 *db,
- const char *zName,
- const sqlite3_tokenizer_module **pp
-){
- int rc;
- sqlite3_stmt *pStmt;
- const char zSql[] = "SELECT fts3_tokenizer(?)";
-
- *pp = 0;
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
- memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
- }
- }
-
- return sqlite3_finalize(pStmt);
-}
-
-/*
-** Return a pointer to a buffer containing a text representation of the
-** expression passed as the first argument. The buffer is obtained from
-** sqlite3_malloc(). It is the responsibility of the caller to use
-** sqlite3_free() to release the memory. If an OOM condition is encountered,
-** NULL is returned.
-**
-** If the second argument is not NULL, then its contents are prepended to
-** the returned expression text and then freed using sqlite3_free().
-*/
-static char *exprToString(Fts3Expr *pExpr, char *zBuf){
- switch( pExpr->eType ){
- case FTSQUERY_PHRASE: {
- Fts3Phrase *pPhrase = pExpr->pPhrase;
- int i;
- zBuf = sqlite3_mprintf(
- "%zPHRASE %d 0", zBuf, pPhrase->iColumn);
- for(i=0; zBuf && i<pPhrase->nToken; i++){
- zBuf = sqlite3_mprintf("%z %.*s%s", zBuf,
- pPhrase->aToken[i].n, pPhrase->aToken[i].z,
- (pPhrase->aToken[i].isPrefix?"+":"")
- );
- }
- return zBuf;
- }
-
- case FTSQUERY_NEAR:
- zBuf = sqlite3_mprintf("%zNEAR/%d ", zBuf, pExpr->nNear);
- break;
- case FTSQUERY_NOT:
- zBuf = sqlite3_mprintf("%zNOT ", zBuf);
- break;
- case FTSQUERY_AND:
- zBuf = sqlite3_mprintf("%zAND ", zBuf);
- break;
- case FTSQUERY_OR:
- zBuf = sqlite3_mprintf("%zOR ", zBuf);
- break;
- }
-
- if( zBuf ) zBuf = sqlite3_mprintf("%z{", zBuf);
- if( zBuf ) zBuf = exprToString(pExpr->pLeft, zBuf);
- if( zBuf ) zBuf = sqlite3_mprintf("%z} {", zBuf);
-
- if( zBuf ) zBuf = exprToString(pExpr->pRight, zBuf);
- if( zBuf ) zBuf = sqlite3_mprintf("%z}", zBuf);
-
- return zBuf;
-}
-
-/*
-** This is the implementation of a scalar SQL function used to test the
-** expression parser. It should be called as follows:
-**
-** fts3_exprtest(<tokenizer>, <expr>, <column 1>, ...);
-**
-** The first argument, <tokenizer>, is the name of the fts3 tokenizer used
-** to parse the query expression (see README.tokenizers). The second argument
-** is the query expression to parse. Each subsequent argument is the name
-** of a column of the fts3 table that the query expression may refer to.
-** For example:
-**
-** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2');
-*/
-static void fts3ExprTest(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- sqlite3_tokenizer_module const *pModule = 0;
- sqlite3_tokenizer *pTokenizer = 0;
- int rc;
- char **azCol = 0;
- const char *zExpr;
- int nExpr;
- int nCol;
- int ii;
- Fts3Expr *pExpr;
- char *zBuf = 0;
- sqlite3 *db = sqlite3_context_db_handle(context);
-
- if( argc<3 ){
- sqlite3_result_error(context,
- "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1
- );
- return;
- }
-
- rc = queryTestTokenizer(db,
- (const char *)sqlite3_value_text(argv[0]), &pModule);
- if( rc==SQLITE_NOMEM ){
- sqlite3_result_error_nomem(context);
- goto exprtest_out;
- }else if( !pModule ){
- sqlite3_result_error(context, "No such tokenizer module", -1);
- goto exprtest_out;
- }
-
- rc = pModule->xCreate(0, 0, &pTokenizer);
- assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
- if( rc==SQLITE_NOMEM ){
- sqlite3_result_error_nomem(context);
- goto exprtest_out;
- }
- pTokenizer->pModule = pModule;
-
- zExpr = (const char *)sqlite3_value_text(argv[1]);
- nExpr = sqlite3_value_bytes(argv[1]);
- nCol = argc-2;
- azCol = (char **)sqlite3_malloc(nCol*sizeof(char *));
- if( !azCol ){
- sqlite3_result_error_nomem(context);
- goto exprtest_out;
- }
- for(ii=0; ii<nCol; ii++){
- azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
- }
-
- rc = sqlite3Fts3ExprParse(
- pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr
- );
- if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
- sqlite3_result_error(context, "Error parsing expression", -1);
- }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
- sqlite3_result_error_nomem(context);
- }else{
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
- sqlite3_free(zBuf);
- }
-
- sqlite3Fts3ExprFree(pExpr);
-
-exprtest_out:
- if( pModule && pTokenizer ){
- rc = pModule->xDestroy(pTokenizer);
- }
- sqlite3_free(azCol);
-}
-
-/*
-** Register the query expression parser test function fts3_exprtest()
-** with database connection db.
-*/
-SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
- return sqlite3_create_function(
- db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0
- );
-}
-
-#endif
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_expr.c *******************************************/
-/************** Begin file fts3_hash.c ***************************************/
-/*
-** 2001 September 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This is the implementation of generic hash-tables used in SQLite.
-** We've modified it slightly to serve as a standalone hash table
-** implementation for the full-text indexing module.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/* #include <assert.h> */
-/* #include <stdlib.h> */
-/* #include <string.h> */
-
-
-/*
-** Malloc and Free functions
-*/
-static void *fts3HashMalloc(int n){
- void *p = sqlite3_malloc(n);
- if( p ){
- memset(p, 0, n);
- }
- return p;
-}
-static void fts3HashFree(void *p){
- sqlite3_free(p);
-}
-
-/* Turn bulk memory into a hash table object by initializing the
-** fields of the Hash structure.
-**
-** "pNew" is a pointer to the hash table that is to be initialized.
-** keyClass is one of the constants
-** FTS3_HASH_BINARY or FTS3_HASH_STRING. The value of keyClass
-** determines what kind of key the hash table will use. "copyKey" is
-** true if the hash table should make its own private copy of keys and
-** false if it should just use the supplied pointer.
-*/
-SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey){
- assert( pNew!=0 );
- assert( keyClass>=FTS3_HASH_STRING && keyClass<=FTS3_HASH_BINARY );
- pNew->keyClass = keyClass;
- pNew->copyKey = copyKey;
- pNew->first = 0;
- pNew->count = 0;
- pNew->htsize = 0;
- pNew->ht = 0;
-}
-
-/* Remove all entries from a hash table. Reclaim all memory.
-** Call this routine to delete a hash table or to reset a hash table
-** to the empty state.
-*/
-SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash *pH){
- Fts3HashElem *elem; /* For looping over all elements of the table */
-
- assert( pH!=0 );
- elem = pH->first;
- pH->first = 0;
- fts3HashFree(pH->ht);
- pH->ht = 0;
- pH->htsize = 0;
- while( elem ){
- Fts3HashElem *next_elem = elem->next;
- if( pH->copyKey && elem->pKey ){
- fts3HashFree(elem->pKey);
- }
- fts3HashFree(elem);
- elem = next_elem;
- }
- pH->count = 0;
-}
-
-/*
-** Hash and comparison functions when the mode is FTS3_HASH_STRING
-*/
-static int fts3StrHash(const void *pKey, int nKey){
- const char *z = (const char *)pKey;
- int h = 0;
- if( nKey<=0 ) nKey = (int) strlen(z);
- while( nKey > 0 ){
- h = (h<<3) ^ h ^ *z++;
- nKey--;
- }
- return h & 0x7fffffff;
-}
-static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
- if( n1!=n2 ) return 1;
- return strncmp((const char*)pKey1,(const char*)pKey2,n1);
-}
-
-/*
-** Hash and comparison functions when the mode is FTS3_HASH_BINARY
-*/
-static int fts3BinHash(const void *pKey, int nKey){
- int h = 0;
- const char *z = (const char *)pKey;
- while( nKey-- > 0 ){
- h = (h<<3) ^ h ^ *(z++);
- }
- return h & 0x7fffffff;
-}
-static int fts3BinCompare(const void *pKey1, int n1, const void *pKey2, int n2){
- if( n1!=n2 ) return 1;
- return memcmp(pKey1,pKey2,n1);
-}
-
-/*
-** Return a pointer to the appropriate hash function given the key class.
-**
-** The C syntax in this function definition may be unfamilar to some
-** programmers, so we provide the following additional explanation:
-**
-** The name of the function is "ftsHashFunction". The function takes a
-** single parameter "keyClass". The return value of ftsHashFunction()
-** is a pointer to another function. Specifically, the return value
-** of ftsHashFunction() is a pointer to a function that takes two parameters
-** with types "const void*" and "int" and returns an "int".
-*/
-static int (*ftsHashFunction(int keyClass))(const void*,int){
- if( keyClass==FTS3_HASH_STRING ){
- return &fts3StrHash;
- }else{
- assert( keyClass==FTS3_HASH_BINARY );
- return &fts3BinHash;
- }
-}
-
-/*
-** Return a pointer to the appropriate hash function given the key class.
-**
-** For help in interpreted the obscure C code in the function definition,
-** see the header comment on the previous function.
-*/
-static int (*ftsCompareFunction(int keyClass))(const void*,int,const void*,int){
- if( keyClass==FTS3_HASH_STRING ){
- return &fts3StrCompare;
- }else{
- assert( keyClass==FTS3_HASH_BINARY );
- return &fts3BinCompare;
- }
-}
-
-/* Link an element into the hash table
-*/
-static void fts3HashInsertElement(
- Fts3Hash *pH, /* The complete hash table */
- struct _fts3ht *pEntry, /* The entry into which pNew is inserted */
- Fts3HashElem *pNew /* The element to be inserted */
-){
- Fts3HashElem *pHead; /* First element already in pEntry */
- pHead = pEntry->chain;
- if( pHead ){
- pNew->next = pHead;
- pNew->prev = pHead->prev;
- if( pHead->prev ){ pHead->prev->next = pNew; }
- else { pH->first = pNew; }
- pHead->prev = pNew;
- }else{
- pNew->next = pH->first;
- if( pH->first ){ pH->first->prev = pNew; }
- pNew->prev = 0;
- pH->first = pNew;
- }
- pEntry->count++;
- pEntry->chain = pNew;
-}
-
-
-/* Resize the hash table so that it cantains "new_size" buckets.
-** "new_size" must be a power of 2. The hash table might fail
-** to resize if sqliteMalloc() fails.
-**
-** Return non-zero if a memory allocation error occurs.
-*/
-static int fts3Rehash(Fts3Hash *pH, int new_size){
- struct _fts3ht *new_ht; /* The new hash table */
- Fts3HashElem *elem, *next_elem; /* For looping over existing elements */
- int (*xHash)(const void*,int); /* The hash function */
-
- assert( (new_size & (new_size-1))==0 );
- new_ht = (struct _fts3ht *)fts3HashMalloc( new_size*sizeof(struct _fts3ht) );
- if( new_ht==0 ) return 1;
- fts3HashFree(pH->ht);
- pH->ht = new_ht;
- pH->htsize = new_size;
- xHash = ftsHashFunction(pH->keyClass);
- for(elem=pH->first, pH->first=0; elem; elem = next_elem){
- int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
- next_elem = elem->next;
- fts3HashInsertElement(pH, &new_ht[h], elem);
- }
- return 0;
-}
-
-/* This function (for internal use only) locates an element in an
-** hash table that matches the given key. The hash for this key has
-** already been computed and is passed as the 4th parameter.
-*/
-static Fts3HashElem *fts3FindElementByHash(
- const Fts3Hash *pH, /* The pH to be searched */
- const void *pKey, /* The key we are searching for */
- int nKey,
- int h /* The hash for this key. */
-){
- Fts3HashElem *elem; /* Used to loop thru the element list */
- int count; /* Number of elements left to test */
- int (*xCompare)(const void*,int,const void*,int); /* comparison function */
-
- if( pH->ht ){
- struct _fts3ht *pEntry = &pH->ht[h];
- elem = pEntry->chain;
- count = pEntry->count;
- xCompare = ftsCompareFunction(pH->keyClass);
- while( count-- && elem ){
- if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){
- return elem;
- }
- elem = elem->next;
- }
- }
- return 0;
-}
-
-/* Remove a single entry from the hash table given a pointer to that
-** element and a hash on the element's key.
-*/
-static void fts3RemoveElementByHash(
- Fts3Hash *pH, /* The pH containing "elem" */
- Fts3HashElem* elem, /* The element to be removed from the pH */
- int h /* Hash value for the element */
-){
- struct _fts3ht *pEntry;
- if( elem->prev ){
- elem->prev->next = elem->next;
- }else{
- pH->first = elem->next;
- }
- if( elem->next ){
- elem->next->prev = elem->prev;
- }
- pEntry = &pH->ht[h];
- if( pEntry->chain==elem ){
- pEntry->chain = elem->next;
- }
- pEntry->count--;
- if( pEntry->count<=0 ){
- pEntry->chain = 0;
- }
- if( pH->copyKey && elem->pKey ){
- fts3HashFree(elem->pKey);
- }
- fts3HashFree( elem );
- pH->count--;
- if( pH->count<=0 ){
- assert( pH->first==0 );
- assert( pH->count==0 );
- fts3HashClear(pH);
- }
-}
-
-SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(
- const Fts3Hash *pH,
- const void *pKey,
- int nKey
-){
- int h; /* A hash on key */
- int (*xHash)(const void*,int); /* The hash function */
-
- if( pH==0 || pH->ht==0 ) return 0;
- xHash = ftsHashFunction(pH->keyClass);
- assert( xHash!=0 );
- h = (*xHash)(pKey,nKey);
- assert( (pH->htsize & (pH->htsize-1))==0 );
- return fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1));
-}
-
-/*
-** Attempt to locate an element of the hash table pH with a key
-** that matches pKey,nKey. Return the data for this element if it is
-** found, or NULL if there is no match.
-*/
-SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash *pH, const void *pKey, int nKey){
- Fts3HashElem *pElem; /* The element that matches key (if any) */
-
- pElem = sqlite3Fts3HashFindElem(pH, pKey, nKey);
- return pElem ? pElem->data : 0;
-}
-
-/* Insert an element into the hash table pH. The key is pKey,nKey
-** and the data is "data".
-**
-** If no element exists with a matching key, then a new
-** element is created. A copy of the key is made if the copyKey
-** flag is set. NULL is returned.
-**
-** If another element already exists with the same key, then the
-** new data replaces the old data and the old data is returned.
-** The key is not copied in this instance. If a malloc fails, then
-** the new data is returned and the hash table is unchanged.
-**
-** If the "data" parameter to this function is NULL, then the
-** element corresponding to "key" is removed from the hash table.
-*/
-SQLITE_PRIVATE void *sqlite3Fts3HashInsert(
- Fts3Hash *pH, /* The hash table to insert into */
- const void *pKey, /* The key */
- int nKey, /* Number of bytes in the key */
- void *data /* The data */
-){
- int hraw; /* Raw hash value of the key */
- int h; /* the hash of the key modulo hash table size */
- Fts3HashElem *elem; /* Used to loop thru the element list */
- Fts3HashElem *new_elem; /* New element added to the pH */
- int (*xHash)(const void*,int); /* The hash function */
-
- assert( pH!=0 );
- xHash = ftsHashFunction(pH->keyClass);
- assert( xHash!=0 );
- hraw = (*xHash)(pKey, nKey);
- assert( (pH->htsize & (pH->htsize-1))==0 );
- h = hraw & (pH->htsize-1);
- elem = fts3FindElementByHash(pH,pKey,nKey,h);
- if( elem ){
- void *old_data = elem->data;
- if( data==0 ){
- fts3RemoveElementByHash(pH,elem,h);
- }else{
- elem->data = data;
- }
- return old_data;
- }
- if( data==0 ) return 0;
- if( (pH->htsize==0 && fts3Rehash(pH,8))
- || (pH->count>=pH->htsize && fts3Rehash(pH, pH->htsize*2))
- ){
- pH->count = 0;
- return data;
- }
- assert( pH->htsize>0 );
- new_elem = (Fts3HashElem*)fts3HashMalloc( sizeof(Fts3HashElem) );
- if( new_elem==0 ) return data;
- if( pH->copyKey && pKey!=0 ){
- new_elem->pKey = fts3HashMalloc( nKey );
- if( new_elem->pKey==0 ){
- fts3HashFree(new_elem);
- return data;
- }
- memcpy((void*)new_elem->pKey, pKey, nKey);
- }else{
- new_elem->pKey = (void*)pKey;
- }
- new_elem->nKey = nKey;
- pH->count++;
- assert( pH->htsize>0 );
- assert( (pH->htsize & (pH->htsize-1))==0 );
- h = hraw & (pH->htsize-1);
- fts3HashInsertElement(pH, &pH->ht[h], new_elem);
- new_elem->data = data;
- return 0;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_hash.c *******************************************/
-/************** Begin file fts3_porter.c *************************************/
-/*
-** 2006 September 30
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** Implementation of the full-text-search tokenizer that implements
-** a Porter stemmer.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/* #include <assert.h> */
-/* #include <stdlib.h> */
-/* #include <stdio.h> */
-/* #include <string.h> */
-
-
-/*
-** Class derived from sqlite3_tokenizer
-*/
-typedef struct porter_tokenizer {
- sqlite3_tokenizer base; /* Base class */
-} porter_tokenizer;
-
-/*
-** Class derived from sqlite3_tokenizer_cursor
-*/
-typedef struct porter_tokenizer_cursor {
- sqlite3_tokenizer_cursor base;
- const char *zInput; /* input we are tokenizing */
- int nInput; /* size of the input */
- int iOffset; /* current position in zInput */
- int iToken; /* index of next token to be returned */
- char *zToken; /* storage for current token */
- int nAllocated; /* space allocated to zToken buffer */
-} porter_tokenizer_cursor;
-
-
-/*
-** Create a new tokenizer instance.
-*/
-static int porterCreate(
- int argc, const char * const *argv,
- sqlite3_tokenizer **ppTokenizer
-){
- porter_tokenizer *t;
-
- UNUSED_PARAMETER(argc);
- UNUSED_PARAMETER(argv);
-
- t = (porter_tokenizer *) sqlite3_malloc(sizeof(*t));
- if( t==NULL ) return SQLITE_NOMEM;
- memset(t, 0, sizeof(*t));
- *ppTokenizer = &t->base;
- return SQLITE_OK;
-}
-
-/*
-** Destroy a tokenizer
-*/
-static int porterDestroy(sqlite3_tokenizer *pTokenizer){
- sqlite3_free(pTokenizer);
- return SQLITE_OK;
-}
-
-/*
-** Prepare to begin tokenizing a particular string. The input
-** string to be tokenized is zInput[0..nInput-1]. A cursor
-** used to incrementally tokenize this string is returned in
-** *ppCursor.
-*/
-static int porterOpen(
- sqlite3_tokenizer *pTokenizer, /* The tokenizer */
- const char *zInput, int nInput, /* String to be tokenized */
- sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */
-){
- porter_tokenizer_cursor *c;
-
- UNUSED_PARAMETER(pTokenizer);
-
- c = (porter_tokenizer_cursor *) sqlite3_malloc(sizeof(*c));
- if( c==NULL ) return SQLITE_NOMEM;
-
- c->zInput = zInput;
- if( zInput==0 ){
- c->nInput = 0;
- }else if( nInput<0 ){
- c->nInput = (int)strlen(zInput);
- }else{
- c->nInput = nInput;
- }
- c->iOffset = 0; /* start tokenizing at the beginning */
- c->iToken = 0;
- c->zToken = NULL; /* no space allocated, yet. */
- c->nAllocated = 0;
-
- *ppCursor = &c->base;
- return SQLITE_OK;
-}
-
-/*
-** Close a tokenization cursor previously opened by a call to
-** porterOpen() above.
-*/
-static int porterClose(sqlite3_tokenizer_cursor *pCursor){
- porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor;
- sqlite3_free(c->zToken);
- sqlite3_free(c);
- return SQLITE_OK;
-}
-/*
-** Vowel or consonant
-*/
-static const char cType[] = {
- 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0,
- 1, 1, 1, 2, 1
-};
-
-/*
-** isConsonant() and isVowel() determine if their first character in
-** the string they point to is a consonant or a vowel, according
-** to Porter ruls.
-**
-** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'.
-** 'Y' is a consonant unless it follows another consonant,
-** in which case it is a vowel.
-**
-** In these routine, the letters are in reverse order. So the 'y' rule
-** is that 'y' is a consonant unless it is followed by another
-** consonent.
-*/
-static int isVowel(const char*);
-static int isConsonant(const char *z){
- int j;
- char x = *z;
- if( x==0 ) return 0;
- assert( x>='a' && x<='z' );
- j = cType[x-'a'];
- if( j<2 ) return j;
- return z[1]==0 || isVowel(z + 1);
-}
-static int isVowel(const char *z){
- int j;
- char x = *z;
- if( x==0 ) return 0;
- assert( x>='a' && x<='z' );
- j = cType[x-'a'];
- if( j<2 ) return 1-j;
- return isConsonant(z + 1);
-}
-
-/*
-** Let any sequence of one or more vowels be represented by V and let
-** C be sequence of one or more consonants. Then every word can be
-** represented as:
-**
-** [C] (VC){m} [V]
-**
-** In prose: A word is an optional consonant followed by zero or
-** vowel-consonant pairs followed by an optional vowel. "m" is the
-** number of vowel consonant pairs. This routine computes the value
-** of m for the first i bytes of a word.
-**
-** Return true if the m-value for z is 1 or more. In other words,
-** return true if z contains at least one vowel that is followed
-** by a consonant.
-**
-** In this routine z[] is in reverse order. So we are really looking
-** for an instance of of a consonant followed by a vowel.
-*/
-static int m_gt_0(const char *z){
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isConsonant(z) ){ z++; }
- return *z!=0;
-}
-
-/* Like mgt0 above except we are looking for a value of m which is
-** exactly 1
-*/
-static int m_eq_1(const char *z){
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isConsonant(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 1;
- while( isConsonant(z) ){ z++; }
- return *z==0;
-}
-
-/* Like mgt0 above except we are looking for a value of m>1 instead
-** or m>0
-*/
-static int m_gt_1(const char *z){
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isConsonant(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isVowel(z) ){ z++; }
- if( *z==0 ) return 0;
- while( isConsonant(z) ){ z++; }
- return *z!=0;
-}
-
-/*
-** Return TRUE if there is a vowel anywhere within z[0..n-1]
-*/
-static int hasVowel(const char *z){
- while( isConsonant(z) ){ z++; }
- return *z!=0;
-}
-
-/*
-** Return TRUE if the word ends in a double consonant.
-**
-** The text is reversed here. So we are really looking at
-** the first two characters of z[].
-*/
-static int doubleConsonant(const char *z){
- return isConsonant(z) && z[0]==z[1];
-}
-
-/*
-** Return TRUE if the word ends with three letters which
-** are consonant-vowel-consonent and where the final consonant
-** is not 'w', 'x', or 'y'.
-**
-** The word is reversed here. So we are really checking the
-** first three letters and the first one cannot be in [wxy].
-*/
-static int star_oh(const char *z){
- return
- isConsonant(z) &&
- z[0]!='w' && z[0]!='x' && z[0]!='y' &&
- isVowel(z+1) &&
- isConsonant(z+2);
-}
-
-/*
-** If the word ends with zFrom and xCond() is true for the stem
-** of the word that preceeds the zFrom ending, then change the
-** ending to zTo.
-**
-** The input word *pz and zFrom are both in reverse order. zTo
-** is in normal order.
-**
-** Return TRUE if zFrom matches. Return FALSE if zFrom does not
-** match. Not that TRUE is returned even if xCond() fails and
-** no substitution occurs.
-*/
-static int stem(
- char **pz, /* The word being stemmed (Reversed) */
- const char *zFrom, /* If the ending matches this... (Reversed) */
- const char *zTo, /* ... change the ending to this (not reversed) */
- int (*xCond)(const char*) /* Condition that must be true */
-){
- char *z = *pz;
- while( *zFrom && *zFrom==*z ){ z++; zFrom++; }
- if( *zFrom!=0 ) return 0;
- if( xCond && !xCond(z) ) return 1;
- while( *zTo ){
- *(--z) = *(zTo++);
- }
- *pz = z;
- return 1;
-}
-
-/*
-** This is the fallback stemmer used when the porter stemmer is
-** inappropriate. The input word is copied into the output with
-** US-ASCII case folding. If the input word is too long (more
-** than 20 bytes if it contains no digits or more than 6 bytes if
-** it contains digits) then word is truncated to 20 or 6 bytes
-** by taking 10 or 3 bytes from the beginning and end.
-*/
-static void copy_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
- int i, mx, j;
- int hasDigit = 0;
- for(i=0; i<nIn; i++){
- char c = zIn[i];
- if( c>='A' && c<='Z' ){
- zOut[i] = c - 'A' + 'a';
- }else{
- if( c>='0' && c<='9' ) hasDigit = 1;
- zOut[i] = c;
- }
- }
- mx = hasDigit ? 3 : 10;
- if( nIn>mx*2 ){
- for(j=mx, i=nIn-mx; i<nIn; i++, j++){
- zOut[j] = zOut[i];
- }
- i = j;
- }
- zOut[i] = 0;
- *pnOut = i;
-}
-
-
-/*
-** Stem the input word zIn[0..nIn-1]. Store the output in zOut.
-** zOut is at least big enough to hold nIn bytes. Write the actual
-** size of the output word (exclusive of the '\0' terminator) into *pnOut.
-**
-** Any upper-case characters in the US-ASCII character set ([A-Z])
-** are converted to lower case. Upper-case UTF characters are
-** unchanged.
-**
-** Words that are longer than about 20 bytes are stemmed by retaining
-** a few bytes from the beginning and the end of the word. If the
-** word contains digits, 3 bytes are taken from the beginning and
-** 3 bytes from the end. For long words without digits, 10 bytes
-** are taken from each end. US-ASCII case folding still applies.
-**
-** If the input word contains not digits but does characters not
-** in [a-zA-Z] then no stemming is attempted and this routine just
-** copies the input into the input into the output with US-ASCII
-** case folding.
-**
-** Stemming never increases the length of the word. So there is
-** no chance of overflowing the zOut buffer.
-*/
-static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
- int i, j;
- char zReverse[28];
- char *z, *z2;
- if( nIn<3 || nIn>=(int)sizeof(zReverse)-7 ){
- /* The word is too big or too small for the porter stemmer.
- ** Fallback to the copy stemmer */
- copy_stemmer(zIn, nIn, zOut, pnOut);
- return;
- }
- for(i=0, j=sizeof(zReverse)-6; i<nIn; i++, j--){
- char c = zIn[i];
- if( c>='A' && c<='Z' ){
- zReverse[j] = c + 'a' - 'A';
- }else if( c>='a' && c<='z' ){
- zReverse[j] = c;
- }else{
- /* The use of a character not in [a-zA-Z] means that we fallback
- ** to the copy stemmer */
- copy_stemmer(zIn, nIn, zOut, pnOut);
- return;
- }
- }
- memset(&zReverse[sizeof(zReverse)-5], 0, 5);
- z = &zReverse[j+1];
-
-
- /* Step 1a */
- if( z[0]=='s' ){
- if(
- !stem(&z, "sess", "ss", 0) &&
- !stem(&z, "sei", "i", 0) &&
- !stem(&z, "ss", "ss", 0)
- ){
- z++;
- }
- }
-
- /* Step 1b */
- z2 = z;
- if( stem(&z, "dee", "ee", m_gt_0) ){
- /* Do nothing. The work was all in the test */
- }else if(
- (stem(&z, "gni", "", hasVowel) || stem(&z, "de", "", hasVowel))
- && z!=z2
- ){
- if( stem(&z, "ta", "ate", 0) ||
- stem(&z, "lb", "ble", 0) ||
- stem(&z, "zi", "ize", 0) ){
- /* Do nothing. The work was all in the test */
- }else if( doubleConsonant(z) && (*z!='l' && *z!='s' && *z!='z') ){
- z++;
- }else if( m_eq_1(z) && star_oh(z) ){
- *(--z) = 'e';
- }
- }
-
- /* Step 1c */
- if( z[0]=='y' && hasVowel(z+1) ){
- z[0] = 'i';
- }
-
- /* Step 2 */
- switch( z[1] ){
- case 'a':
- stem(&z, "lanoita", "ate", m_gt_0) ||
- stem(&z, "lanoit", "tion", m_gt_0);
- break;
- case 'c':
- stem(&z, "icne", "ence", m_gt_0) ||
- stem(&z, "icna", "ance", m_gt_0);
- break;
- case 'e':
- stem(&z, "rezi", "ize", m_gt_0);
- break;
- case 'g':
- stem(&z, "igol", "log", m_gt_0);
- break;
- case 'l':
- stem(&z, "ilb", "ble", m_gt_0) ||
- stem(&z, "illa", "al", m_gt_0) ||
- stem(&z, "iltne", "ent", m_gt_0) ||
- stem(&z, "ile", "e", m_gt_0) ||
- stem(&z, "ilsuo", "ous", m_gt_0);
- break;
- case 'o':
- stem(&z, "noitazi", "ize", m_gt_0) ||
- stem(&z, "noita", "ate", m_gt_0) ||
- stem(&z, "rota", "ate", m_gt_0);
- break;
- case 's':
- stem(&z, "msila", "al", m_gt_0) ||
- stem(&z, "ssenevi", "ive", m_gt_0) ||
- stem(&z, "ssenluf", "ful", m_gt_0) ||
- stem(&z, "ssensuo", "ous", m_gt_0);
- break;
- case 't':
- stem(&z, "itila", "al", m_gt_0) ||
- stem(&z, "itivi", "ive", m_gt_0) ||
- stem(&z, "itilib", "ble", m_gt_0);
- break;
- }
-
- /* Step 3 */
- switch( z[0] ){
- case 'e':
- stem(&z, "etaci", "ic", m_gt_0) ||
- stem(&z, "evita", "", m_gt_0) ||
- stem(&z, "ezila", "al", m_gt_0);
- break;
- case 'i':
- stem(&z, "itici", "ic", m_gt_0);
- break;
- case 'l':
- stem(&z, "laci", "ic", m_gt_0) ||
- stem(&z, "luf", "", m_gt_0);
- break;
- case 's':
- stem(&z, "ssen", "", m_gt_0);
- break;
- }
-
- /* Step 4 */
- switch( z[1] ){
- case 'a':
- if( z[0]=='l' && m_gt_1(z+2) ){
- z += 2;
- }
- break;
- case 'c':
- if( z[0]=='e' && z[2]=='n' && (z[3]=='a' || z[3]=='e') && m_gt_1(z+4) ){
- z += 4;
- }
- break;
- case 'e':
- if( z[0]=='r' && m_gt_1(z+2) ){
- z += 2;
- }
- break;
- case 'i':
- if( z[0]=='c' && m_gt_1(z+2) ){
- z += 2;
- }
- break;
- case 'l':
- if( z[0]=='e' && z[2]=='b' && (z[3]=='a' || z[3]=='i') && m_gt_1(z+4) ){
- z += 4;
- }
- break;
- case 'n':
- if( z[0]=='t' ){
- if( z[2]=='a' ){
- if( m_gt_1(z+3) ){
- z += 3;
- }
- }else if( z[2]=='e' ){
- stem(&z, "tneme", "", m_gt_1) ||
- stem(&z, "tnem", "", m_gt_1) ||
- stem(&z, "tne", "", m_gt_1);
- }
- }
- break;
- case 'o':
- if( z[0]=='u' ){
- if( m_gt_1(z+2) ){
- z += 2;
- }
- }else if( z[3]=='s' || z[3]=='t' ){
- stem(&z, "noi", "", m_gt_1);
- }
- break;
- case 's':
- if( z[0]=='m' && z[2]=='i' && m_gt_1(z+3) ){
- z += 3;
- }
- break;
- case 't':
- stem(&z, "eta", "", m_gt_1) ||
- stem(&z, "iti", "", m_gt_1);
- break;
- case 'u':
- if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){
- z += 3;
- }
- break;
- case 'v':
- case 'z':
- if( z[0]=='e' && z[2]=='i' && m_gt_1(z+3) ){
- z += 3;
- }
- break;
- }
-
- /* Step 5a */
- if( z[0]=='e' ){
- if( m_gt_1(z+1) ){
- z++;
- }else if( m_eq_1(z+1) && !star_oh(z+1) ){
- z++;
- }
- }
-
- /* Step 5b */
- if( m_gt_1(z) && z[0]=='l' && z[1]=='l' ){
- z++;
- }
-
- /* z[] is now the stemmed word in reverse order. Flip it back
- ** around into forward order and return.
- */
- *pnOut = i = (int)strlen(z);
- zOut[i] = 0;
- while( *z ){
- zOut[--i] = *(z++);
- }
-}
-
-/*
-** Characters that can be part of a token. We assume any character
-** whose value is greater than 0x80 (any UTF character) can be
-** part of a token. In other words, delimiters all must have
-** values of 0x7f or lower.
-*/
-static const char porterIdChar[] = {
-/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
-};
-#define isDelim(C) (((ch=C)&0x80)==0 && (ch<0x30 || !porterIdChar[ch-0x30]))
-
-/*
-** Extract the next token from a tokenization cursor. The cursor must
-** have been opened by a prior call to porterOpen().
-*/
-static int porterNext(
- sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by porterOpen */
- const char **pzToken, /* OUT: *pzToken is the token text */
- int *pnBytes, /* OUT: Number of bytes in token */
- int *piStartOffset, /* OUT: Starting offset of token */
- int *piEndOffset, /* OUT: Ending offset of token */
- int *piPosition /* OUT: Position integer of token */
-){
- porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor;
- const char *z = c->zInput;
-
- while( c->iOffset<c->nInput ){
- int iStartOffset, ch;
-
- /* Scan past delimiter characters */
- while( c->iOffset<c->nInput && isDelim(z[c->iOffset]) ){
- c->iOffset++;
- }
-
- /* Count non-delimiter characters. */
- iStartOffset = c->iOffset;
- while( c->iOffset<c->nInput && !isDelim(z[c->iOffset]) ){
- c->iOffset++;
- }
-
- if( c->iOffset>iStartOffset ){
- int n = c->iOffset-iStartOffset;
- if( n>c->nAllocated ){
- char *pNew;
- c->nAllocated = n+20;
- pNew = sqlite3_realloc(c->zToken, c->nAllocated);
- if( !pNew ) return SQLITE_NOMEM;
- c->zToken = pNew;
- }
- porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes);
- *pzToken = c->zToken;
- *piStartOffset = iStartOffset;
- *piEndOffset = c->iOffset;
- *piPosition = c->iToken++;
- return SQLITE_OK;
- }
- }
- return SQLITE_DONE;
-}
-
-/*
-** The set of routines that implement the porter-stemmer tokenizer
-*/
-static const sqlite3_tokenizer_module porterTokenizerModule = {
- 0,
- porterCreate,
- porterDestroy,
- porterOpen,
- porterClose,
- porterNext,
- 0
-};
-
-/*
-** Allocate a new porter tokenizer. Return a pointer to the new
-** tokenizer in *ppModule
-*/
-SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(
- sqlite3_tokenizer_module const**ppModule
-){
- *ppModule = &porterTokenizerModule;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_porter.c *****************************************/
-/************** Begin file fts3_tokenizer.c **********************************/
-/*
-** 2007 June 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This is part of an SQLite module implementing full-text search.
-** This particular file implements the generic tokenizer interface.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/* #include <assert.h> */
-/* #include <string.h> */
-
-/*
-** Implementation of the SQL scalar function for accessing the underlying
-** hash table. This function may be called as follows:
-**
-** SELECT <function-name>(<key-name>);
-** SELECT <function-name>(<key-name>, <pointer>);
-**
-** where <function-name> is the name passed as the second argument
-** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer').
-**
-** If the <pointer> argument is specified, it must be a blob value
-** containing a pointer to be stored as the hash data corresponding
-** to the string <key-name>. If <pointer> is not specified, then
-** the string <key-name> must already exist in the has table. Otherwise,
-** an error is returned.
-**
-** Whether or not the <pointer> argument is specified, the value returned
-** is a blob containing the pointer stored as the hash data corresponding
-** to string <key-name> (after the hash-table is updated, if applicable).
-*/
-static void scalarFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- Fts3Hash *pHash;
- void *pPtr = 0;
- const unsigned char *zName;
- int nName;
-
- assert( argc==1 || argc==2 );
-
- pHash = (Fts3Hash *)sqlite3_user_data(context);
-
- zName = sqlite3_value_text(argv[0]);
- nName = sqlite3_value_bytes(argv[0])+1;
-
- if( argc==2 ){
- void *pOld;
- int n = sqlite3_value_bytes(argv[1]);
- if( n!=sizeof(pPtr) ){
- sqlite3_result_error(context, "argument type mismatch", -1);
- return;
- }
- pPtr = *(void **)sqlite3_value_blob(argv[1]);
- pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
- if( pOld==pPtr ){
- sqlite3_result_error(context, "out of memory", -1);
- return;
- }
- }else{
- pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
- if( !pPtr ){
- char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
- return;
- }
- }
-
- sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
-}
-
-SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char c){
- static const char isFtsIdChar[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
- 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
- };
- return (c&0x80 || isFtsIdChar[(int)(c)]);
-}
-
-SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *zStr, int *pn){
- const char *z1;
- const char *z2 = 0;
-
- /* Find the start of the next token. */
- z1 = zStr;
- while( z2==0 ){
- char c = *z1;
- switch( c ){
- case '\0': return 0; /* No more tokens here */
- case '\'':
- case '"':
- case '`': {
- z2 = z1;
- while( *++z2 && (*z2!=c || *++z2==c) );
- break;
- }
- case '[':
- z2 = &z1[1];
- while( *z2 && z2[0]!=']' ) z2++;
- if( *z2 ) z2++;
- break;
-
- default:
- if( sqlite3Fts3IsIdChar(*z1) ){
- z2 = &z1[1];
- while( sqlite3Fts3IsIdChar(*z2) ) z2++;
- }else{
- z1++;
- }
- }
- }
-
- *pn = (int)(z2-z1);
- return z1;
-}
-
-SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
- Fts3Hash *pHash, /* Tokenizer hash table */
- const char *zArg, /* Tokenizer name */
- sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */
- char **pzErr /* OUT: Set to malloced error message */
-){
- int rc;
- char *z = (char *)zArg;
- int n = 0;
- char *zCopy;
- char *zEnd; /* Pointer to nul-term of zCopy */
- sqlite3_tokenizer_module *m;
-
- zCopy = sqlite3_mprintf("%s", zArg);
- if( !zCopy ) return SQLITE_NOMEM;
- zEnd = &zCopy[strlen(zCopy)];
-
- z = (char *)sqlite3Fts3NextToken(zCopy, &n);
- z[n] = '\0';
- sqlite3Fts3Dequote(z);
-
- m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1);
- if( !m ){
- *pzErr = sqlite3_mprintf("unknown tokenizer: %s", z);
- rc = SQLITE_ERROR;
- }else{
- char const **aArg = 0;
- int iArg = 0;
- z = &z[n+1];
- while( z<zEnd && (NULL!=(z = (char *)sqlite3Fts3NextToken(z, &n))) ){
- int nNew = sizeof(char *)*(iArg+1);
- char const **aNew = (const char **)sqlite3_realloc((void *)aArg, nNew);
- if( !aNew ){
- sqlite3_free(zCopy);
- sqlite3_free((void *)aArg);
- return SQLITE_NOMEM;
- }
- aArg = aNew;
- aArg[iArg++] = z;
- z[n] = '\0';
- sqlite3Fts3Dequote(z);
- z = &z[n+1];
- }
- rc = m->xCreate(iArg, aArg, ppTok);
- assert( rc!=SQLITE_OK || *ppTok );
- if( rc!=SQLITE_OK ){
- *pzErr = sqlite3_mprintf("unknown tokenizer");
- }else{
- (*ppTok)->pModule = m;
- }
- sqlite3_free((void *)aArg);
- }
-
- sqlite3_free(zCopy);
- return rc;
-}
-
-
-#ifdef SQLITE_TEST
-
-/* #include <tcl.h> */
-/* #include <string.h> */
-
-/*
-** Implementation of a special SQL scalar function for testing tokenizers
-** designed to be used in concert with the Tcl testing framework. This
-** function must be called with two or more arguments:
-**
-** SELECT <function-name>(<key-name>, ..., <input-string>);
-**
-** where <function-name> is the name passed as the second argument
-** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer')
-** concatenated with the string '_test' (e.g. 'fts3_tokenizer_test').
-**
-** The return value is a string that may be interpreted as a Tcl
-** list. For each token in the <input-string>, three elements are
-** added to the returned list. The first is the token position, the
-** second is the token text (folded, stemmed, etc.) and the third is the
-** substring of <input-string> associated with the token. For example,
-** using the built-in "simple" tokenizer:
-**
-** SELECT fts_tokenizer_test('simple', 'I don't see how');
-**
-** will return the string:
-**
-** "{0 i I 1 dont don't 2 see see 3 how how}"
-**
-*/
-static void testFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- Fts3Hash *pHash;
- sqlite3_tokenizer_module *p;
- sqlite3_tokenizer *pTokenizer = 0;
- sqlite3_tokenizer_cursor *pCsr = 0;
-
- const char *zErr = 0;
-
- const char *zName;
- int nName;
- const char *zInput;
- int nInput;
-
- const char *azArg[64];
-
- const char *zToken;
- int nToken = 0;
- int iStart = 0;
- int iEnd = 0;
- int iPos = 0;
- int i;
-
- Tcl_Obj *pRet;
-
- if( argc<2 ){
- sqlite3_result_error(context, "insufficient arguments", -1);
- return;
- }
-
- nName = sqlite3_value_bytes(argv[0]);
- zName = (const char *)sqlite3_value_text(argv[0]);
- nInput = sqlite3_value_bytes(argv[argc-1]);
- zInput = (const char *)sqlite3_value_text(argv[argc-1]);
-
- pHash = (Fts3Hash *)sqlite3_user_data(context);
- p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
-
- if( !p ){
- char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
- sqlite3_result_error(context, zErr, -1);
- sqlite3_free(zErr);
- return;
- }
-
- pRet = Tcl_NewObj();
- Tcl_IncrRefCount(pRet);
-
- for(i=1; i<argc-1; i++){
- azArg[i-1] = (const char *)sqlite3_value_text(argv[i]);
- }
-
- if( SQLITE_OK!=p->xCreate(argc-2, azArg, &pTokenizer) ){
- zErr = "error in xCreate()";
- goto finish;
- }
- pTokenizer->pModule = p;
- if( sqlite3Fts3OpenTokenizer(pTokenizer, 0, zInput, nInput, &pCsr) ){
- zErr = "error in xOpen()";
- goto finish;
- }
-
- while( SQLITE_OK==p->xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos) ){
- Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(iPos));
- Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken));
- zToken = &zInput[iStart];
- nToken = iEnd-iStart;
- Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken));
- }
-
- if( SQLITE_OK!=p->xClose(pCsr) ){
- zErr = "error in xClose()";
- goto finish;
- }
- if( SQLITE_OK!=p->xDestroy(pTokenizer) ){
- zErr = "error in xDestroy()";
- goto finish;
- }
-
-finish:
- if( zErr ){
- sqlite3_result_error(context, zErr, -1);
- }else{
- sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT);
- }
- Tcl_DecrRefCount(pRet);
-}
-
-static
-int registerTokenizer(
- sqlite3 *db,
- char *zName,
- const sqlite3_tokenizer_module *p
-){
- int rc;
- sqlite3_stmt *pStmt;
- const char zSql[] = "SELECT fts3_tokenizer(?, ?)";
-
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
- sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC);
- sqlite3_step(pStmt);
-
- return sqlite3_finalize(pStmt);
-}
-
-static
-int queryTokenizer(
- sqlite3 *db,
- char *zName,
- const sqlite3_tokenizer_module **pp
-){
- int rc;
- sqlite3_stmt *pStmt;
- const char zSql[] = "SELECT fts3_tokenizer(?)";
-
- *pp = 0;
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
- memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
- }
- }
-
- return sqlite3_finalize(pStmt);
-}
-
-SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-
-/*
-** Implementation of the scalar function fts3_tokenizer_internal_test().
-** This function is used for testing only, it is not included in the
-** build unless SQLITE_TEST is defined.
-**
-** The purpose of this is to test that the fts3_tokenizer() function
-** can be used as designed by the C-code in the queryTokenizer and
-** registerTokenizer() functions above. These two functions are repeated
-** in the README.tokenizer file as an example, so it is important to
-** test them.
-**
-** To run the tests, evaluate the fts3_tokenizer_internal_test() scalar
-** function with no arguments. An assert() will fail if a problem is
-** detected. i.e.:
-**
-** SELECT fts3_tokenizer_internal_test();
-**
-*/
-static void intTestFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int rc;
- const sqlite3_tokenizer_module *p1;
- const sqlite3_tokenizer_module *p2;
- sqlite3 *db = (sqlite3 *)sqlite3_user_data(context);
-
- UNUSED_PARAMETER(argc);
- UNUSED_PARAMETER(argv);
-
- /* Test the query function */
- sqlite3Fts3SimpleTokenizerModule(&p1);
- rc = queryTokenizer(db, "simple", &p2);
- assert( rc==SQLITE_OK );
- assert( p1==p2 );
- rc = queryTokenizer(db, "nosuchtokenizer", &p2);
- assert( rc==SQLITE_ERROR );
- assert( p2==0 );
- assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") );
-
- /* Test the storage function */
- rc = registerTokenizer(db, "nosuchtokenizer", p1);
- assert( rc==SQLITE_OK );
- rc = queryTokenizer(db, "nosuchtokenizer", &p2);
- assert( rc==SQLITE_OK );
- assert( p2==p1 );
-
- sqlite3_result_text(context, "ok", -1, SQLITE_STATIC);
-}
-
-#endif
-
-/*
-** Set up SQL objects in database db used to access the contents of
-** the hash table pointed to by argument pHash. The hash table must
-** been initialised to use string keys, and to take a private copy
-** of the key when a value is inserted. i.e. by a call similar to:
-**
-** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
-**
-** This function adds a scalar function (see header comment above
-** scalarFunc() in this file for details) and, if ENABLE_TABLE is
-** defined at compilation time, a temporary virtual table (see header
-** comment above struct HashTableVtab) to the database schema. Both
-** provide read/write access to the contents of *pHash.
-**
-** The third argument to this function, zName, is used as the name
-** of both the scalar and, if created, the virtual table.
-*/
-SQLITE_PRIVATE int sqlite3Fts3InitHashTable(
- sqlite3 *db,
- Fts3Hash *pHash,
- const char *zName
-){
- int rc = SQLITE_OK;
- void *p = (void *)pHash;
- const int any = SQLITE_ANY;
-
-#ifdef SQLITE_TEST
- char *zTest = 0;
- char *zTest2 = 0;
- void *pdb = (void *)db;
- zTest = sqlite3_mprintf("%s_test", zName);
- zTest2 = sqlite3_mprintf("%s_internal_test", zName);
- if( !zTest || !zTest2 ){
- rc = SQLITE_NOMEM;
- }
-#endif
-
- if( SQLITE_OK==rc ){
- rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0);
- }
- if( SQLITE_OK==rc ){
- rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0);
- }
-#ifdef SQLITE_TEST
- if( SQLITE_OK==rc ){
- rc = sqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0);
- }
- if( SQLITE_OK==rc ){
- rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0);
- }
-#endif
-
-#ifdef SQLITE_TEST
- sqlite3_free(zTest);
- sqlite3_free(zTest2);
-#endif
-
- return rc;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_tokenizer.c **************************************/
-/************** Begin file fts3_tokenizer1.c *********************************/
-/*
-** 2006 Oct 10
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** Implementation of the "simple" full-text-search tokenizer.
-*/
-
-/*
-** The code in this file is only compiled if:
-**
-** * The FTS3 module is being built as an extension
-** (in which case SQLITE_CORE is not defined), or
-**
-** * The FTS3 module is being built into the core of
-** SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/* #include <assert.h> */
-/* #include <stdlib.h> */
-/* #include <stdio.h> */
-/* #include <string.h> */
-
-
-typedef struct simple_tokenizer {
- sqlite3_tokenizer base;
- char delim[128]; /* flag ASCII delimiters */
-} simple_tokenizer;
-
-typedef struct simple_tokenizer_cursor {
- sqlite3_tokenizer_cursor base;
- const char *pInput; /* input we are tokenizing */
- int nBytes; /* size of the input */
- int iOffset; /* current position in pInput */
- int iToken; /* index of next token to be returned */
- char *pToken; /* storage for current token */
- int nTokenAllocated; /* space allocated to zToken buffer */
-} simple_tokenizer_cursor;
-
-
-static int simpleDelim(simple_tokenizer *t, unsigned char c){
- return c<0x80 && t->delim[c];
-}
-static int fts3_isalnum(int x){
- return (x>='0' && x<='9') || (x>='A' && x<='Z') || (x>='a' && x<='z');
-}
-
-/*
-** Create a new tokenizer instance.
-*/
-static int simpleCreate(
- int argc, const char * const *argv,
- sqlite3_tokenizer **ppTokenizer
-){
- simple_tokenizer *t;
-
- t = (simple_tokenizer *) sqlite3_malloc(sizeof(*t));
- if( t==NULL ) return SQLITE_NOMEM;
- memset(t, 0, sizeof(*t));
-
- /* TODO(shess) Delimiters need to remain the same from run to run,
- ** else we need to reindex. One solution would be a meta-table to
- ** track such information in the database, then we'd only want this
- ** information on the initial create.
- */
- if( argc>1 ){
- int i, n = (int)strlen(argv[1]);
- for(i=0; i<n; i++){
- unsigned char ch = argv[1][i];
- /* We explicitly don't support UTF-8 delimiters for now. */
- if( ch>=0x80 ){
- sqlite3_free(t);
- return SQLITE_ERROR;
- }
- t->delim[ch] = 1;
- }
- } else {
- /* Mark non-alphanumeric ASCII characters as delimiters */
- int i;
- for(i=1; i<0x80; i++){
- t->delim[i] = !fts3_isalnum(i) ? -1 : 0;
- }
- }
-
- *ppTokenizer = &t->base;
- return SQLITE_OK;
-}
-
-/*
-** Destroy a tokenizer
-*/
-static int simpleDestroy(sqlite3_tokenizer *pTokenizer){
- sqlite3_free(pTokenizer);
- return SQLITE_OK;
-}
-
-/*
-** Prepare to begin tokenizing a particular string. The input
-** string to be tokenized is pInput[0..nBytes-1]. A cursor
-** used to incrementally tokenize this string is returned in
-** *ppCursor.
-*/
-static int simpleOpen(
- sqlite3_tokenizer *pTokenizer, /* The tokenizer */
- const char *pInput, int nBytes, /* String to be tokenized */
- sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */
-){
- simple_tokenizer_cursor *c;
-
- UNUSED_PARAMETER(pTokenizer);
-
- c = (simple_tokenizer_cursor *) sqlite3_malloc(sizeof(*c));
- if( c==NULL ) return SQLITE_NOMEM;
-
- c->pInput = pInput;
- if( pInput==0 ){
- c->nBytes = 0;
- }else if( nBytes<0 ){
- c->nBytes = (int)strlen(pInput);
- }else{
- c->nBytes = nBytes;
- }
- c->iOffset = 0; /* start tokenizing at the beginning */
- c->iToken = 0;
- c->pToken = NULL; /* no space allocated, yet. */
- c->nTokenAllocated = 0;
-
- *ppCursor = &c->base;
- return SQLITE_OK;
-}
-
-/*
-** Close a tokenization cursor previously opened by a call to
-** simpleOpen() above.
-*/
-static int simpleClose(sqlite3_tokenizer_cursor *pCursor){
- simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor;
- sqlite3_free(c->pToken);
- sqlite3_free(c);
- return SQLITE_OK;
-}
-
-/*
-** Extract the next token from a tokenization cursor. The cursor must
-** have been opened by a prior call to simpleOpen().
-*/
-static int simpleNext(
- sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */
- const char **ppToken, /* OUT: *ppToken is the token text */
- int *pnBytes, /* OUT: Number of bytes in token */
- int *piStartOffset, /* OUT: Starting offset of token */
- int *piEndOffset, /* OUT: Ending offset of token */
- int *piPosition /* OUT: Position integer of token */
-){
- simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor;
- simple_tokenizer *t = (simple_tokenizer *) pCursor->pTokenizer;
- unsigned char *p = (unsigned char *)c->pInput;
-
- while( c->iOffset<c->nBytes ){
- int iStartOffset;
-
- /* Scan past delimiter characters */
- while( c->iOffset<c->nBytes && simpleDelim(t, p[c->iOffset]) ){
- c->iOffset++;
- }
-
- /* Count non-delimiter characters. */
- iStartOffset = c->iOffset;
- while( c->iOffset<c->nBytes && !simpleDelim(t, p[c->iOffset]) ){
- c->iOffset++;
- }
-
- if( c->iOffset>iStartOffset ){
- int i, n = c->iOffset-iStartOffset;
- if( n>c->nTokenAllocated ){
- char *pNew;
- c->nTokenAllocated = n+20;
- pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated);
- if( !pNew ) return SQLITE_NOMEM;
- c->pToken = pNew;
- }
- for(i=0; i<n; i++){
- /* TODO(shess) This needs expansion to handle UTF-8
- ** case-insensitivity.
- */
- unsigned char ch = p[iStartOffset+i];
- c->pToken[i] = (char)((ch>='A' && ch<='Z') ? ch-'A'+'a' : ch);
- }
- *ppToken = c->pToken;
- *pnBytes = n;
- *piStartOffset = iStartOffset;
- *piEndOffset = c->iOffset;
- *piPosition = c->iToken++;
-
- return SQLITE_OK;
- }
- }
- return SQLITE_DONE;
-}
-
-/*
-** The set of routines that implement the simple tokenizer
-*/
-static const sqlite3_tokenizer_module simpleTokenizerModule = {
- 0,
- simpleCreate,
- simpleDestroy,
- simpleOpen,
- simpleClose,
- simpleNext,
- 0,
-};
-
-/*
-** Allocate a new simple tokenizer. Return a pointer to the new
-** tokenizer in *ppModule
-*/
-SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(
- sqlite3_tokenizer_module const**ppModule
-){
- *ppModule = &simpleTokenizerModule;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_tokenizer1.c *************************************/
-/************** Begin file fts3_write.c **************************************/
-/*
-** 2009 Oct 23
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file is part of the SQLite FTS3 extension module. Specifically,
-** this file contains code to insert, update and delete rows from FTS3
-** tables. It also contains code to merge FTS3 b-tree segments. Some
-** of the sub-routines used to merge segments are also used by the query
-** code in fts3.c.
-*/
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/* #include <string.h> */
-/* #include <assert.h> */
-/* #include <stdlib.h> */
-
-
-#define FTS_MAX_APPENDABLE_HEIGHT 16
-
-/*
-** When full-text index nodes are loaded from disk, the buffer that they
-** are loaded into has the following number of bytes of padding at the end
-** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer
-** of 920 bytes is allocated for it.
-**
-** This means that if we have a pointer into a buffer containing node data,
-** it is always safe to read up to two varints from it without risking an
-** overread, even if the node data is corrupted.
-*/
-#define FTS3_NODE_PADDING (FTS3_VARINT_MAX*2)
-
-/*
-** Under certain circumstances, b-tree nodes (doclists) can be loaded into
-** memory incrementally instead of all at once. This can be a big performance
-** win (reduced IO and CPU) if SQLite stops calling the virtual table xNext()
-** method before retrieving all query results (as may happen, for example,
-** if a query has a LIMIT clause).
-**
-** Incremental loading is used for b-tree nodes FTS3_NODE_CHUNK_THRESHOLD
-** bytes and larger. Nodes are loaded in chunks of FTS3_NODE_CHUNKSIZE bytes.
-** The code is written so that the hard lower-limit for each of these values
-** is 1. Clearly such small values would be inefficient, but can be useful
-** for testing purposes.
-**
-** If this module is built with SQLITE_TEST defined, these constants may
-** be overridden at runtime for testing purposes. File fts3_test.c contains
-** a Tcl interface to read and write the values.
-*/
-#ifdef SQLITE_TEST
-int test_fts3_node_chunksize = (4*1024);
-int test_fts3_node_chunk_threshold = (4*1024)*4;
-# define FTS3_NODE_CHUNKSIZE test_fts3_node_chunksize
-# define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold
-#else
-# define FTS3_NODE_CHUNKSIZE (4*1024)
-# define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4)
-#endif
-
-/*
-** The two values that may be meaningfully bound to the :1 parameter in
-** statements SQL_REPLACE_STAT and SQL_SELECT_STAT.
-*/
-#define FTS_STAT_DOCTOTAL 0
-#define FTS_STAT_INCRMERGEHINT 1
-#define FTS_STAT_AUTOINCRMERGE 2
-
-/*
-** If FTS_LOG_MERGES is defined, call sqlite3_log() to report each automatic
-** and incremental merge operation that takes place. This is used for
-** debugging FTS only, it should not usually be turned on in production
-** systems.
-*/
-#ifdef FTS3_LOG_MERGES
-static void fts3LogMerge(int nMerge, sqlite3_int64 iAbsLevel){
- sqlite3_log(SQLITE_OK, "%d-way merge from level %d", nMerge, (int)iAbsLevel);
-}
-#else
-#define fts3LogMerge(x, y)
-#endif
-
-
-typedef struct PendingList PendingList;
-typedef struct SegmentNode SegmentNode;
-typedef struct SegmentWriter SegmentWriter;
-
-/*
-** An instance of the following data structure is used to build doclists
-** incrementally. See function fts3PendingListAppend() for details.
-*/
-struct PendingList {
- int nData;
- char *aData;
- int nSpace;
- sqlite3_int64 iLastDocid;
- sqlite3_int64 iLastCol;
- sqlite3_int64 iLastPos;
-};
-
-
-/*
-** Each cursor has a (possibly empty) linked list of the following objects.
-*/
-struct Fts3DeferredToken {
- Fts3PhraseToken *pToken; /* Pointer to corresponding expr token */
- int iCol; /* Column token must occur in */
- Fts3DeferredToken *pNext; /* Next in list of deferred tokens */
- PendingList *pList; /* Doclist is assembled here */
-};
-
-/*
-** An instance of this structure is used to iterate through the terms on
-** a contiguous set of segment b-tree leaf nodes. Although the details of
-** this structure are only manipulated by code in this file, opaque handles
-** of type Fts3SegReader* are also used by code in fts3.c to iterate through
-** terms when querying the full-text index. See functions:
-**
-** sqlite3Fts3SegReaderNew()
-** sqlite3Fts3SegReaderFree()
-** sqlite3Fts3SegReaderIterate()
-**
-** Methods used to manipulate Fts3SegReader structures:
-**
-** fts3SegReaderNext()
-** fts3SegReaderFirstDocid()
-** fts3SegReaderNextDocid()
-*/
-struct Fts3SegReader {
- int iIdx; /* Index within level, or 0x7FFFFFFF for PT */
- u8 bLookup; /* True for a lookup only */
- u8 rootOnly; /* True for a root-only reader */
-
- sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */
- sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */
- sqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */
- sqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */
-
- char *aNode; /* Pointer to node data (or NULL) */
- int nNode; /* Size of buffer at aNode (or 0) */
- int nPopulate; /* If >0, bytes of buffer aNode[] loaded */
- sqlite3_blob *pBlob; /* If not NULL, blob handle to read node */
-
- Fts3HashElem **ppNextElem;
-
- /* Variables set by fts3SegReaderNext(). These may be read directly
- ** by the caller. They are valid from the time SegmentReaderNew() returns
- ** until SegmentReaderNext() returns something other than SQLITE_OK
- ** (i.e. SQLITE_DONE).
- */
- int nTerm; /* Number of bytes in current term */
- char *zTerm; /* Pointer to current term */
- int nTermAlloc; /* Allocated size of zTerm buffer */
- char *aDoclist; /* Pointer to doclist of current entry */
- int nDoclist; /* Size of doclist in current entry */
-
- /* The following variables are used by fts3SegReaderNextDocid() to iterate
- ** through the current doclist (aDoclist/nDoclist).
- */
- char *pOffsetList;
- int nOffsetList; /* For descending pending seg-readers only */
- sqlite3_int64 iDocid;
-};
-
-#define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0)
-#define fts3SegReaderIsRootOnly(p) ((p)->rootOnly!=0)
-
-/*
-** An instance of this structure is used to create a segment b-tree in the
-** database. The internal details of this type are only accessed by the
-** following functions:
-**
-** fts3SegWriterAdd()
-** fts3SegWriterFlush()
-** fts3SegWriterFree()
-*/
-struct SegmentWriter {
- SegmentNode *pTree; /* Pointer to interior tree structure */
- sqlite3_int64 iFirst; /* First slot in %_segments written */
- sqlite3_int64 iFree; /* Next free slot in %_segments */
- char *zTerm; /* Pointer to previous term buffer */
- int nTerm; /* Number of bytes in zTerm */
- int nMalloc; /* Size of malloc'd buffer at zMalloc */
- char *zMalloc; /* Malloc'd space (possibly) used for zTerm */
- int nSize; /* Size of allocation at aData */
- int nData; /* Bytes of data in aData */
- char *aData; /* Pointer to block from malloc() */
-};
-
-/*
-** Type SegmentNode is used by the following three functions to create
-** the interior part of the segment b+-tree structures (everything except
-** the leaf nodes). These functions and type are only ever used by code
-** within the fts3SegWriterXXX() family of functions described above.
-**
-** fts3NodeAddTerm()
-** fts3NodeWrite()
-** fts3NodeFree()
-**
-** When a b+tree is written to the database (either as a result of a merge
-** or the pending-terms table being flushed), leaves are written into the
-** database file as soon as they are completely populated. The interior of
-** the tree is assembled in memory and written out only once all leaves have
-** been populated and stored. This is Ok, as the b+-tree fanout is usually
-** very large, meaning that the interior of the tree consumes relatively
-** little memory.
-*/
-struct SegmentNode {
- SegmentNode *pParent; /* Parent node (or NULL for root node) */
- SegmentNode *pRight; /* Pointer to right-sibling */
- SegmentNode *pLeftmost; /* Pointer to left-most node of this depth */
- int nEntry; /* Number of terms written to node so far */
- char *zTerm; /* Pointer to previous term buffer */
- int nTerm; /* Number of bytes in zTerm */
- int nMalloc; /* Size of malloc'd buffer at zMalloc */
- char *zMalloc; /* Malloc'd space (possibly) used for zTerm */
- int nData; /* Bytes of valid data so far */
- char *aData; /* Node data */
-};
-
-/*
-** Valid values for the second argument to fts3SqlStmt().
-*/
-#define SQL_DELETE_CONTENT 0
-#define SQL_IS_EMPTY 1
-#define SQL_DELETE_ALL_CONTENT 2
-#define SQL_DELETE_ALL_SEGMENTS 3
-#define SQL_DELETE_ALL_SEGDIR 4
-#define SQL_DELETE_ALL_DOCSIZE 5
-#define SQL_DELETE_ALL_STAT 6
-#define SQL_SELECT_CONTENT_BY_ROWID 7
-#define SQL_NEXT_SEGMENT_INDEX 8
-#define SQL_INSERT_SEGMENTS 9
-#define SQL_NEXT_SEGMENTS_ID 10
-#define SQL_INSERT_SEGDIR 11
-#define SQL_SELECT_LEVEL 12
-#define SQL_SELECT_LEVEL_RANGE 13
-#define SQL_SELECT_LEVEL_COUNT 14
-#define SQL_SELECT_SEGDIR_MAX_LEVEL 15
-#define SQL_DELETE_SEGDIR_LEVEL 16
-#define SQL_DELETE_SEGMENTS_RANGE 17
-#define SQL_CONTENT_INSERT 18
-#define SQL_DELETE_DOCSIZE 19
-#define SQL_REPLACE_DOCSIZE 20
-#define SQL_SELECT_DOCSIZE 21
-#define SQL_SELECT_STAT 22
-#define SQL_REPLACE_STAT 23
-
-#define SQL_SELECT_ALL_PREFIX_LEVEL 24
-#define SQL_DELETE_ALL_TERMS_SEGDIR 25
-#define SQL_DELETE_SEGDIR_RANGE 26
-#define SQL_SELECT_ALL_LANGID 27
-#define SQL_FIND_MERGE_LEVEL 28
-#define SQL_MAX_LEAF_NODE_ESTIMATE 29
-#define SQL_DELETE_SEGDIR_ENTRY 30
-#define SQL_SHIFT_SEGDIR_ENTRY 31
-#define SQL_SELECT_SEGDIR 32
-#define SQL_CHOMP_SEGDIR 33
-#define SQL_SEGMENT_IS_APPENDABLE 34
-#define SQL_SELECT_INDEXES 35
-#define SQL_SELECT_MXLEVEL 36
-
-/*
-** This function is used to obtain an SQLite prepared statement handle
-** for the statement identified by the second argument. If successful,
-** *pp is set to the requested statement handle and SQLITE_OK returned.
-** Otherwise, an SQLite error code is returned and *pp is set to 0.
-**
-** If argument apVal is not NULL, then it must point to an array with
-** at least as many entries as the requested statement has bound
-** parameters. The values are bound to the statements parameters before
-** returning.
-*/
-static int fts3SqlStmt(
- Fts3Table *p, /* Virtual table handle */
- int eStmt, /* One of the SQL_XXX constants above */
- sqlite3_stmt **pp, /* OUT: Statement handle */
- sqlite3_value **apVal /* Values to bind to statement */
-){
- const char *azSql[] = {
-/* 0 */ "DELETE FROM %Q.'%q_content' WHERE rowid = ?",
-/* 1 */ "SELECT NOT EXISTS(SELECT docid FROM %Q.'%q_content' WHERE rowid!=?)",
-/* 2 */ "DELETE FROM %Q.'%q_content'",
-/* 3 */ "DELETE FROM %Q.'%q_segments'",
-/* 4 */ "DELETE FROM %Q.'%q_segdir'",
-/* 5 */ "DELETE FROM %Q.'%q_docsize'",
-/* 6 */ "DELETE FROM %Q.'%q_stat'",
-/* 7 */ "SELECT %s WHERE rowid=?",
-/* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1",
-/* 9 */ "REPLACE INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)",
-/* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)",
-/* 11 */ "REPLACE INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)",
-
- /* Return segments in order from oldest to newest.*/
-/* 12 */ "SELECT idx, start_block, leaves_end_block, end_block, root "
- "FROM %Q.'%q_segdir' WHERE level = ? ORDER BY idx ASC",
-/* 13 */ "SELECT idx, start_block, leaves_end_block, end_block, root "
- "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?"
- "ORDER BY level DESC, idx ASC",
-
-/* 14 */ "SELECT count(*) FROM %Q.'%q_segdir' WHERE level = ?",
-/* 15 */ "SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
-
-/* 16 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ?",
-/* 17 */ "DELETE FROM %Q.'%q_segments' WHERE blockid BETWEEN ? AND ?",
-/* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%s)",
-/* 19 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?",
-/* 20 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)",
-/* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?",
-/* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?",
-/* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)",
-/* 24 */ "",
-/* 25 */ "",
-
-/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
-/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'",
-
-/* This statement is used to determine which level to read the input from
-** when performing an incremental merge. It returns the absolute level number
-** of the oldest level in the db that contains at least ? segments. Or,
-** if no level in the FTS index contains more than ? segments, the statement
-** returns zero rows. */
-/* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?"
- " ORDER BY (level %% 1024) ASC LIMIT 1",
-
-/* Estimate the upper limit on the number of leaf nodes in a new segment
-** created by merging the oldest :2 segments from absolute level :1. See
-** function sqlite3Fts3Incrmerge() for details. */
-/* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) "
- " FROM %Q.'%q_segdir' WHERE level = ? AND idx < ?",
-
-/* SQL_DELETE_SEGDIR_ENTRY
-** Delete the %_segdir entry on absolute level :1 with index :2. */
-/* 30 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?",
-
-/* SQL_SHIFT_SEGDIR_ENTRY
-** Modify the idx value for the segment with idx=:3 on absolute level :2
-** to :1. */
-/* 31 */ "UPDATE %Q.'%q_segdir' SET idx = ? WHERE level=? AND idx=?",
-
-/* SQL_SELECT_SEGDIR
-** Read a single entry from the %_segdir table. The entry from absolute
-** level :1 with index value :2. */
-/* 32 */ "SELECT idx, start_block, leaves_end_block, end_block, root "
- "FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?",
-
-/* SQL_CHOMP_SEGDIR
-** Update the start_block (:1) and root (:2) fields of the %_segdir
-** entry located on absolute level :3 with index :4. */
-/* 33 */ "UPDATE %Q.'%q_segdir' SET start_block = ?, root = ?"
- "WHERE level = ? AND idx = ?",
-
-/* SQL_SEGMENT_IS_APPENDABLE
-** Return a single row if the segment with end_block=? is appendable. Or
-** no rows otherwise. */
-/* 34 */ "SELECT 1 FROM %Q.'%q_segments' WHERE blockid=? AND block IS NULL",
-
-/* SQL_SELECT_INDEXES
-** Return the list of valid segment indexes for absolute level ? */
-/* 35 */ "SELECT idx FROM %Q.'%q_segdir' WHERE level=? ORDER BY 1 ASC",
-
-/* SQL_SELECT_MXLEVEL
-** Return the largest relative level in the FTS index or indexes. */
-/* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'"
- };
- int rc = SQLITE_OK;
- sqlite3_stmt *pStmt;
-
- assert( SizeofArray(azSql)==SizeofArray(p->aStmt) );
- assert( eStmt<SizeofArray(azSql) && eStmt>=0 );
-
- pStmt = p->aStmt[eStmt];
- if( !pStmt ){
- char *zSql;
- if( eStmt==SQL_CONTENT_INSERT ){
- zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
- }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
- zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
- }else{
- zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
- }
- if( !zSql ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, NULL);
- sqlite3_free(zSql);
- assert( rc==SQLITE_OK || pStmt==0 );
- p->aStmt[eStmt] = pStmt;
- }
- }
- if( apVal ){
- int i;
- int nParam = sqlite3_bind_parameter_count(pStmt);
- for(i=0; rc==SQLITE_OK && i<nParam; i++){
- rc = sqlite3_bind_value(pStmt, i+1, apVal[i]);
- }
- }
- *pp = pStmt;
- return rc;
-}
-
-
-static int fts3SelectDocsize(
- Fts3Table *pTab, /* FTS3 table handle */
- sqlite3_int64 iDocid, /* Docid to bind for SQL_SELECT_DOCSIZE */
- sqlite3_stmt **ppStmt /* OUT: Statement handle */
-){
- sqlite3_stmt *pStmt = 0; /* Statement requested from fts3SqlStmt() */
- int rc; /* Return code */
-
- rc = fts3SqlStmt(pTab, SQL_SELECT_DOCSIZE, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pStmt, 1, iDocid);
- rc = sqlite3_step(pStmt);
- if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
- rc = sqlite3_reset(pStmt);
- if( rc==SQLITE_OK ) rc = FTS_CORRUPT_VTAB;
- pStmt = 0;
- }else{
- rc = SQLITE_OK;
- }
- }
-
- *ppStmt = pStmt;
- return rc;
-}
-
-SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(
- Fts3Table *pTab, /* Fts3 table handle */
- sqlite3_stmt **ppStmt /* OUT: Statement handle */
-){
- sqlite3_stmt *pStmt = 0;
- int rc;
- rc = fts3SqlStmt(pTab, SQL_SELECT_STAT, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL);
- if( sqlite3_step(pStmt)!=SQLITE_ROW
- || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB
- ){
- rc = sqlite3_reset(pStmt);
- if( rc==SQLITE_OK ) rc = FTS_CORRUPT_VTAB;
- pStmt = 0;
- }
- }
- *ppStmt = pStmt;
- return rc;
-}
-
-SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(
- Fts3Table *pTab, /* Fts3 table handle */
- sqlite3_int64 iDocid, /* Docid to read size data for */
- sqlite3_stmt **ppStmt /* OUT: Statement handle */
-){
- return fts3SelectDocsize(pTab, iDocid, ppStmt);
-}
-
-/*
-** Similar to fts3SqlStmt(). Except, after binding the parameters in
-** array apVal[] to the SQL statement identified by eStmt, the statement
-** is executed.
-**
-** Returns SQLITE_OK if the statement is successfully executed, or an
-** SQLite error code otherwise.
-*/
-static void fts3SqlExec(
- int *pRC, /* Result code */
- Fts3Table *p, /* The FTS3 table */
- int eStmt, /* Index of statement to evaluate */
- sqlite3_value **apVal /* Parameters to bind */
-){
- sqlite3_stmt *pStmt;
- int rc;
- if( *pRC ) return;
- rc = fts3SqlStmt(p, eStmt, &pStmt, apVal);
- if( rc==SQLITE_OK ){
- sqlite3_step(pStmt);
- rc = sqlite3_reset(pStmt);
- }
- *pRC = rc;
-}
-
-
-/*
-** This function ensures that the caller has obtained a shared-cache
-** table-lock on the %_content table. This is required before reading
-** data from the fts3 table. If this lock is not acquired first, then
-** the caller may end up holding read-locks on the %_segments and %_segdir
-** tables, but no read-lock on the %_content table. If this happens
-** a second connection will be able to write to the fts3 table, but
-** attempting to commit those writes might return SQLITE_LOCKED or
-** SQLITE_LOCKED_SHAREDCACHE (because the commit attempts to obtain
-** write-locks on the %_segments and %_segdir ** tables).
-**
-** We try to avoid this because if FTS3 returns any error when committing
-** a transaction, the whole transaction will be rolled back. And this is
-** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
-** still happen if the user reads data directly from the %_segments or
-** %_segdir tables instead of going through FTS3 though.
-**
-** This reasoning does not apply to a content=xxx table.
-*/
-SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *p){
- int rc; /* Return code */
- sqlite3_stmt *pStmt; /* Statement used to obtain lock */
-
- if( p->zContentTbl==0 ){
- rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_null(pStmt, 1);
- sqlite3_step(pStmt);
- rc = sqlite3_reset(pStmt);
- }
- }else{
- rc = SQLITE_OK;
- }
-
- return rc;
-}
-
-/*
-** FTS maintains a separate indexes for each language-id (a 32-bit integer).
-** Within each language id, a separate index is maintained to store the
-** document terms, and each configured prefix size (configured the FTS
-** "prefix=" option). And each index consists of multiple levels ("relative
-** levels").
-**
-** All three of these values (the language id, the specific index and the
-** level within the index) are encoded in 64-bit integer values stored
-** in the %_segdir table on disk. This function is used to convert three
-** separate component values into the single 64-bit integer value that
-** can be used to query the %_segdir table.
-**
-** Specifically, each language-id/index combination is allocated 1024
-** 64-bit integer level values ("absolute levels"). The main terms index
-** for language-id 0 is allocate values 0-1023. The first prefix index
-** (if any) for language-id 0 is allocated values 1024-2047. And so on.
-** Language 1 indexes are allocated immediately following language 0.
-**
-** So, for a system with nPrefix prefix indexes configured, the block of
-** absolute levels that corresponds to language-id iLangid and index
-** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024).
-*/
-static sqlite3_int64 getAbsoluteLevel(
- Fts3Table *p, /* FTS3 table handle */
- int iLangid, /* Language id */
- int iIndex, /* Index in p->aIndex[] */
- int iLevel /* Level of segments */
-){
- sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */
- assert( iLangid>=0 );
- assert( p->nIndex>0 );
- assert( iIndex>=0 && iIndex<p->nIndex );
-
- iBase = ((sqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL;
- return iBase + iLevel;
-}
-
-/*
-** Set *ppStmt to a statement handle that may be used to iterate through
-** all rows in the %_segdir table, from oldest to newest. If successful,
-** return SQLITE_OK. If an error occurs while preparing the statement,
-** return an SQLite error code.
-**
-** There is only ever one instance of this SQL statement compiled for
-** each FTS3 table.
-**
-** The statement returns the following columns from the %_segdir table:
-**
-** 0: idx
-** 1: start_block
-** 2: leaves_end_block
-** 3: end_block
-** 4: root
-*/
-SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(
- Fts3Table *p, /* FTS3 table */
- int iLangid, /* Language being queried */
- int iIndex, /* Index for p->aIndex[] */
- int iLevel, /* Level to select (relative level) */
- sqlite3_stmt **ppStmt /* OUT: Compiled statement */
-){
- int rc;
- sqlite3_stmt *pStmt = 0;
-
- assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel>=0 );
- assert( iLevel<FTS3_SEGDIR_MAXLEVEL );
- assert( iIndex>=0 && iIndex<p->nIndex );
-
- if( iLevel<0 ){
- /* "SELECT * FROM %_segdir WHERE level BETWEEN ? AND ? ORDER BY ..." */
- rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0));
- sqlite3_bind_int64(pStmt, 2,
- getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1)
- );
- }
- }else{
- /* "SELECT * FROM %_segdir WHERE level = ? ORDER BY ..." */
- rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex,iLevel));
- }
- }
- *ppStmt = pStmt;
- return rc;
-}
-
-
-/*
-** Append a single varint to a PendingList buffer. SQLITE_OK is returned
-** if successful, or an SQLite error code otherwise.
-**
-** This function also serves to allocate the PendingList structure itself.
-** For example, to create a new PendingList structure containing two
-** varints:
-**
-** PendingList *p = 0;
-** fts3PendingListAppendVarint(&p, 1);
-** fts3PendingListAppendVarint(&p, 2);
-*/
-static int fts3PendingListAppendVarint(
- PendingList **pp, /* IN/OUT: Pointer to PendingList struct */
- sqlite3_int64 i /* Value to append to data */
-){
- PendingList *p = *pp;
-
- /* Allocate or grow the PendingList as required. */
- if( !p ){
- p = sqlite3_malloc(sizeof(*p) + 100);
- if( !p ){
- return SQLITE_NOMEM;
- }
- p->nSpace = 100;
- p->aData = (char *)&p[1];
- p->nData = 0;
- }
- else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){
- int nNew = p->nSpace * 2;
- p = sqlite3_realloc(p, sizeof(*p) + nNew);
- if( !p ){
- sqlite3_free(*pp);
- *pp = 0;
- return SQLITE_NOMEM;
- }
- p->nSpace = nNew;
- p->aData = (char *)&p[1];
- }
-
- /* Append the new serialized varint to the end of the list. */
- p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i);
- p->aData[p->nData] = '\0';
- *pp = p;
- return SQLITE_OK;
-}
-
-/*
-** Add a docid/column/position entry to a PendingList structure. Non-zero
-** is returned if the structure is sqlite3_realloced as part of adding
-** the entry. Otherwise, zero.
-**
-** If an OOM error occurs, *pRc is set to SQLITE_NOMEM before returning.
-** Zero is always returned in this case. Otherwise, if no OOM error occurs,
-** it is set to SQLITE_OK.
-*/
-static int fts3PendingListAppend(
- PendingList **pp, /* IN/OUT: PendingList structure */
- sqlite3_int64 iDocid, /* Docid for entry to add */
- sqlite3_int64 iCol, /* Column for entry to add */
- sqlite3_int64 iPos, /* Position of term for entry to add */
- int *pRc /* OUT: Return code */
-){
- PendingList *p = *pp;
- int rc = SQLITE_OK;
-
- assert( !p || p->iLastDocid<=iDocid );
-
- if( !p || p->iLastDocid!=iDocid ){
- sqlite3_int64 iDelta = iDocid - (p ? p->iLastDocid : 0);
- if( p ){
- assert( p->nData<p->nSpace );
- assert( p->aData[p->nData]==0 );
- p->nData++;
- }
- if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iDelta)) ){
- goto pendinglistappend_out;
- }
- p->iLastCol = -1;
- p->iLastPos = 0;
- p->iLastDocid = iDocid;
- }
- if( iCol>0 && p->iLastCol!=iCol ){
- if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, 1))
- || SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iCol))
- ){
- goto pendinglistappend_out;
- }
- p->iLastCol = iCol;
- p->iLastPos = 0;
- }
- if( iCol>=0 ){
- assert( iPos>p->iLastPos || (iPos==0 && p->iLastPos==0) );
- rc = fts3PendingListAppendVarint(&p, 2+iPos-p->iLastPos);
- if( rc==SQLITE_OK ){
- p->iLastPos = iPos;
- }
- }
-
- pendinglistappend_out:
- *pRc = rc;
- if( p!=*pp ){
- *pp = p;
- return 1;
- }
- return 0;
-}
-
-/*
-** Free a PendingList object allocated by fts3PendingListAppend().
-*/
-static void fts3PendingListDelete(PendingList *pList){
- sqlite3_free(pList);
-}
-
-/*
-** Add an entry to one of the pending-terms hash tables.
-*/
-static int fts3PendingTermsAddOne(
- Fts3Table *p,
- int iCol,
- int iPos,
- Fts3Hash *pHash, /* Pending terms hash table to add entry to */
- const char *zToken,
- int nToken
-){
- PendingList *pList;
- int rc = SQLITE_OK;
-
- pList = (PendingList *)fts3HashFind(pHash, zToken, nToken);
- if( pList ){
- p->nPendingData -= (pList->nData + nToken + sizeof(Fts3HashElem));
- }
- if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){
- if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){
- /* Malloc failed while inserting the new entry. This can only
- ** happen if there was no previous entry for this token.
- */
- assert( 0==fts3HashFind(pHash, zToken, nToken) );
- sqlite3_free(pList);
- rc = SQLITE_NOMEM;
- }
- }
- if( rc==SQLITE_OK ){
- p->nPendingData += (pList->nData + nToken + sizeof(Fts3HashElem));
- }
- return rc;
-}
-
-/*
-** Tokenize the nul-terminated string zText and add all tokens to the
-** pending-terms hash-table. The docid used is that currently stored in
-** p->iPrevDocid, and the column is specified by argument iCol.
-**
-** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
-*/
-static int fts3PendingTermsAdd(
- Fts3Table *p, /* Table into which text will be inserted */
- int iLangid, /* Language id to use */
- const char *zText, /* Text of document to be inserted */
- int iCol, /* Column into which text is being inserted */
- u32 *pnWord /* IN/OUT: Incr. by number tokens inserted */
-){
- int rc;
- int iStart = 0;
- int iEnd = 0;
- int iPos = 0;
- int nWord = 0;
-
- char const *zToken;
- int nToken = 0;
-
- sqlite3_tokenizer *pTokenizer = p->pTokenizer;
- sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
- sqlite3_tokenizer_cursor *pCsr;
- int (*xNext)(sqlite3_tokenizer_cursor *pCursor,
- const char**,int*,int*,int*,int*);
-
- assert( pTokenizer && pModule );
-
- /* If the user has inserted a NULL value, this function may be called with
- ** zText==0. In this case, add zero token entries to the hash table and
- ** return early. */
- if( zText==0 ){
- *pnWord = 0;
- return SQLITE_OK;
- }
-
- rc = sqlite3Fts3OpenTokenizer(pTokenizer, iLangid, zText, -1, &pCsr);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- xNext = pModule->xNext;
- while( SQLITE_OK==rc
- && SQLITE_OK==(rc = xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos))
- ){
- int i;
- if( iPos>=nWord ) nWord = iPos+1;
-
- /* Positions cannot be negative; we use -1 as a terminator internally.
- ** Tokens must have a non-zero length.
- */
- if( iPos<0 || !zToken || nToken<=0 ){
- rc = SQLITE_ERROR;
- break;
- }
-
- /* Add the term to the terms index */
- rc = fts3PendingTermsAddOne(
- p, iCol, iPos, &p->aIndex[0].hPending, zToken, nToken
- );
-
- /* Add the term to each of the prefix indexes that it is not too
- ** short for. */
- for(i=1; rc==SQLITE_OK && i<p->nIndex; i++){
- struct Fts3Index *pIndex = &p->aIndex[i];
- if( nToken<pIndex->nPrefix ) continue;
- rc = fts3PendingTermsAddOne(
- p, iCol, iPos, &pIndex->hPending, zToken, pIndex->nPrefix
- );
- }
- }
-
- pModule->xClose(pCsr);
- *pnWord += nWord;
- return (rc==SQLITE_DONE ? SQLITE_OK : rc);
-}
-
-/*
-** Calling this function indicates that subsequent calls to
-** fts3PendingTermsAdd() are to add term/position-list pairs for the
-** contents of the document with docid iDocid.
-*/
-static int fts3PendingTermsDocid(
- Fts3Table *p, /* Full-text table handle */
- int iLangid, /* Language id of row being written */
- sqlite_int64 iDocid /* Docid of row being written */
-){
- assert( iLangid>=0 );
-
- /* TODO(shess) Explore whether partially flushing the buffer on
- ** forced-flush would provide better performance. I suspect that if
- ** we ordered the doclists by size and flushed the largest until the
- ** buffer was half empty, that would let the less frequent terms
- ** generate longer doclists.
- */
- if( iDocid<=p->iPrevDocid
- || p->iPrevLangid!=iLangid
- || p->nPendingData>p->nMaxPendingData
- ){
- int rc = sqlite3Fts3PendingTermsFlush(p);
- if( rc!=SQLITE_OK ) return rc;
- }
- p->iPrevDocid = iDocid;
- p->iPrevLangid = iLangid;
- return SQLITE_OK;
-}
-
-/*
-** Discard the contents of the pending-terms hash tables.
-*/
-SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *p){
- int i;
- for(i=0; i<p->nIndex; i++){
- Fts3HashElem *pElem;
- Fts3Hash *pHash = &p->aIndex[i].hPending;
- for(pElem=fts3HashFirst(pHash); pElem; pElem=fts3HashNext(pElem)){
- PendingList *pList = (PendingList *)fts3HashData(pElem);
- fts3PendingListDelete(pList);
- }
- fts3HashClear(pHash);
- }
- p->nPendingData = 0;
-}
-
-/*
-** This function is called by the xUpdate() method as part of an INSERT
-** operation. It adds entries for each term in the new record to the
-** pendingTerms hash table.
-**
-** Argument apVal is the same as the similarly named argument passed to
-** fts3InsertData(). Parameter iDocid is the docid of the new row.
-*/
-static int fts3InsertTerms(
- Fts3Table *p,
- int iLangid,
- sqlite3_value **apVal,
- u32 *aSz
-){
- int i; /* Iterator variable */
- for(i=2; i<p->nColumn+2; i++){
- const char *zText = (const char *)sqlite3_value_text(apVal[i]);
- int rc = fts3PendingTermsAdd(p, iLangid, zText, i-2, &aSz[i-2]);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]);
- }
- return SQLITE_OK;
-}
-
-/*
-** This function is called by the xUpdate() method for an INSERT operation.
-** The apVal parameter is passed a copy of the apVal argument passed by
-** SQLite to the xUpdate() method. i.e:
-**
-** apVal[0] Not used for INSERT.
-** apVal[1] rowid
-** apVal[2] Left-most user-defined column
-** ...
-** apVal[p->nColumn+1] Right-most user-defined column
-** apVal[p->nColumn+2] Hidden column with same name as table
-** apVal[p->nColumn+3] Hidden "docid" column (alias for rowid)
-** apVal[p->nColumn+4] Hidden languageid column
-*/
-static int fts3InsertData(
- Fts3Table *p, /* Full-text table */
- sqlite3_value **apVal, /* Array of values to insert */
- sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */
-){
- int rc; /* Return code */
- sqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */
-
- if( p->zContentTbl ){
- sqlite3_value *pRowid = apVal[p->nColumn+3];
- if( sqlite3_value_type(pRowid)==SQLITE_NULL ){
- pRowid = apVal[1];
- }
- if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){
- return SQLITE_CONSTRAINT;
- }
- *piDocid = sqlite3_value_int64(pRowid);
- return SQLITE_OK;
- }
-
- /* Locate the statement handle used to insert data into the %_content
- ** table. The SQL for this statement is:
- **
- ** INSERT INTO %_content VALUES(?, ?, ?, ...)
- **
- ** The statement features N '?' variables, where N is the number of user
- ** defined columns in the FTS3 table, plus one for the docid field.
- */
- rc = fts3SqlStmt(p, SQL_CONTENT_INSERT, &pContentInsert, &apVal[1]);
- if( rc==SQLITE_OK && p->zLanguageid ){
- rc = sqlite3_bind_int(
- pContentInsert, p->nColumn+2,
- sqlite3_value_int(apVal[p->nColumn+4])
- );
- }
- if( rc!=SQLITE_OK ) return rc;
-
- /* There is a quirk here. The users INSERT statement may have specified
- ** a value for the "rowid" field, for the "docid" field, or for both.
- ** Which is a problem, since "rowid" and "docid" are aliases for the
- ** same value. For example:
- **
- ** INSERT INTO fts3tbl(rowid, docid) VALUES(1, 2);
- **
- ** In FTS3, this is an error. It is an error to specify non-NULL values
- ** for both docid and some other rowid alias.
- */
- if( SQLITE_NULL!=sqlite3_value_type(apVal[3+p->nColumn]) ){
- if( SQLITE_NULL==sqlite3_value_type(apVal[0])
- && SQLITE_NULL!=sqlite3_value_type(apVal[1])
- ){
- /* A rowid/docid conflict. */
- return SQLITE_ERROR;
- }
- rc = sqlite3_bind_value(pContentInsert, 1, apVal[3+p->nColumn]);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- /* Execute the statement to insert the record. Set *piDocid to the
- ** new docid value.
- */
- sqlite3_step(pContentInsert);
- rc = sqlite3_reset(pContentInsert);
-
- *piDocid = sqlite3_last_insert_rowid(p->db);
- return rc;
-}
-
-
-
-/*
-** Remove all data from the FTS3 table. Clear the hash table containing
-** pending terms.
-*/
-static int fts3DeleteAll(Fts3Table *p, int bContent){
- int rc = SQLITE_OK; /* Return code */
-
- /* Discard the contents of the pending-terms hash table. */
- sqlite3Fts3PendingTermsClear(p);
-
- /* Delete everything from the shadow tables. Except, leave %_content as
- ** is if bContent is false. */
- assert( p->zContentTbl==0 || bContent==0 );
- if( bContent ) fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0);
- fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0);
- fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0);
- if( p->bHasDocsize ){
- fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0);
- }
- if( p->bHasStat ){
- fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0);
- }
- return rc;
-}
-
-/*
-**
-*/
-static int langidFromSelect(Fts3Table *p, sqlite3_stmt *pSelect){
- int iLangid = 0;
- if( p->zLanguageid ) iLangid = sqlite3_column_int(pSelect, p->nColumn+1);
- return iLangid;
-}
-
-/*
-** The first element in the apVal[] array is assumed to contain the docid
-** (an integer) of a row about to be deleted. Remove all terms from the
-** full-text index.
-*/
-static void fts3DeleteTerms(
- int *pRC, /* Result code */
- Fts3Table *p, /* The FTS table to delete from */
- sqlite3_value *pRowid, /* The docid to be deleted */
- u32 *aSz, /* Sizes of deleted document written here */
- int *pbFound /* OUT: Set to true if row really does exist */
-){
- int rc;
- sqlite3_stmt *pSelect;
-
- assert( *pbFound==0 );
- if( *pRC ) return;
- rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid);
- if( rc==SQLITE_OK ){
- if( SQLITE_ROW==sqlite3_step(pSelect) ){
- int i;
- int iLangid = langidFromSelect(p, pSelect);
- rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0));
- for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){
- const char *zText = (const char *)sqlite3_column_text(pSelect, i);
- rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[i-1]);
- aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
- }
- if( rc!=SQLITE_OK ){
- sqlite3_reset(pSelect);
- *pRC = rc;
- return;
- }
- *pbFound = 1;
- }
- rc = sqlite3_reset(pSelect);
- }else{
- sqlite3_reset(pSelect);
- }
- *pRC = rc;
-}
-
-/*
-** Forward declaration to account for the circular dependency between
-** functions fts3SegmentMerge() and fts3AllocateSegdirIdx().
-*/
-static int fts3SegmentMerge(Fts3Table *, int, int, int);
-
-/*
-** This function allocates a new level iLevel index in the segdir table.
-** Usually, indexes are allocated within a level sequentially starting
-** with 0, so the allocated index is one greater than the value returned
-** by:
-**
-** SELECT max(idx) FROM %_segdir WHERE level = :iLevel
-**
-** However, if there are already FTS3_MERGE_COUNT indexes at the requested
-** level, they are merged into a single level (iLevel+1) segment and the
-** allocated index is 0.
-**
-** If successful, *piIdx is set to the allocated index slot and SQLITE_OK
-** returned. Otherwise, an SQLite error code is returned.
-*/
-static int fts3AllocateSegdirIdx(
- Fts3Table *p,
- int iLangid, /* Language id */
- int iIndex, /* Index for p->aIndex */
- int iLevel,
- int *piIdx
-){
- int rc; /* Return Code */
- sqlite3_stmt *pNextIdx; /* Query for next idx at level iLevel */
- int iNext = 0; /* Result of query pNextIdx */
-
- assert( iLangid>=0 );
- assert( p->nIndex>=1 );
-
- /* Set variable iNext to the next available segdir index at level iLevel. */
- rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pNextIdx, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(
- pNextIdx, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel)
- );
- if( SQLITE_ROW==sqlite3_step(pNextIdx) ){
- iNext = sqlite3_column_int(pNextIdx, 0);
- }
- rc = sqlite3_reset(pNextIdx);
- }
-
- if( rc==SQLITE_OK ){
- /* If iNext is FTS3_MERGE_COUNT, indicating that level iLevel is already
- ** full, merge all segments in level iLevel into a single iLevel+1
- ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise,
- ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext.
- */
- if( iNext>=FTS3_MERGE_COUNT ){
- fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel));
- rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel);
- *piIdx = 0;
- }else{
- *piIdx = iNext;
- }
- }
-
- return rc;
-}
-
-/*
-** The %_segments table is declared as follows:
-**
-** CREATE TABLE %_segments(blockid INTEGER PRIMARY KEY, block BLOB)
-**
-** This function reads data from a single row of the %_segments table. The
-** specific row is identified by the iBlockid parameter. If paBlob is not
-** NULL, then a buffer is allocated using sqlite3_malloc() and populated
-** with the contents of the blob stored in the "block" column of the
-** identified table row is. Whether or not paBlob is NULL, *pnBlob is set
-** to the size of the blob in bytes before returning.
-**
-** If an error occurs, or the table does not contain the specified row,
-** an SQLite error code is returned. Otherwise, SQLITE_OK is returned. If
-** paBlob is non-NULL, then it is the responsibility of the caller to
-** eventually free the returned buffer.
-**
-** This function may leave an open sqlite3_blob* handle in the
-** Fts3Table.pSegments variable. This handle is reused by subsequent calls
-** to this function. The handle may be closed by calling the
-** sqlite3Fts3SegmentsClose() function. Reusing a blob handle is a handy
-** performance improvement, but the blob handle should always be closed
-** before control is returned to the user (to prevent a lock being held
-** on the database file for longer than necessary). Thus, any virtual table
-** method (xFilter etc.) that may directly or indirectly call this function
-** must call sqlite3Fts3SegmentsClose() before returning.
-*/
-SQLITE_PRIVATE int sqlite3Fts3ReadBlock(
- Fts3Table *p, /* FTS3 table handle */
- sqlite3_int64 iBlockid, /* Access the row with blockid=$iBlockid */
- char **paBlob, /* OUT: Blob data in malloc'd buffer */
- int *pnBlob, /* OUT: Size of blob data */
- int *pnLoad /* OUT: Bytes actually loaded */
-){
- int rc; /* Return code */
-
- /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */
- assert( pnBlob );
-
- if( p->pSegments ){
- rc = sqlite3_blob_reopen(p->pSegments, iBlockid);
- }else{
- if( 0==p->zSegmentsTbl ){
- p->zSegmentsTbl = sqlite3_mprintf("%s_segments", p->zName);
- if( 0==p->zSegmentsTbl ) return SQLITE_NOMEM;
- }
- rc = sqlite3_blob_open(
- p->db, p->zDb, p->zSegmentsTbl, "block", iBlockid, 0, &p->pSegments
- );
- }
-
- if( rc==SQLITE_OK ){
- int nByte = sqlite3_blob_bytes(p->pSegments);
- *pnBlob = nByte;
- if( paBlob ){
- char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING);
- if( !aByte ){
- rc = SQLITE_NOMEM;
- }else{
- if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){
- nByte = FTS3_NODE_CHUNKSIZE;
- *pnLoad = nByte;
- }
- rc = sqlite3_blob_read(p->pSegments, aByte, nByte, 0);
- memset(&aByte[nByte], 0, FTS3_NODE_PADDING);
- if( rc!=SQLITE_OK ){
- sqlite3_free(aByte);
- aByte = 0;
- }
- }
- *paBlob = aByte;
- }
- }
-
- return rc;
-}
-
-/*
-** Close the blob handle at p->pSegments, if it is open. See comments above
-** the sqlite3Fts3ReadBlock() function for details.
-*/
-SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *p){
- sqlite3_blob_close(p->pSegments);
- p->pSegments = 0;
-}
-
-static int fts3SegReaderIncrRead(Fts3SegReader *pReader){
- int nRead; /* Number of bytes to read */
- int rc; /* Return code */
-
- nRead = MIN(pReader->nNode - pReader->nPopulate, FTS3_NODE_CHUNKSIZE);
- rc = sqlite3_blob_read(
- pReader->pBlob,
- &pReader->aNode[pReader->nPopulate],
- nRead,
- pReader->nPopulate
- );
-
- if( rc==SQLITE_OK ){
- pReader->nPopulate += nRead;
- memset(&pReader->aNode[pReader->nPopulate], 0, FTS3_NODE_PADDING);
- if( pReader->nPopulate==pReader->nNode ){
- sqlite3_blob_close(pReader->pBlob);
- pReader->pBlob = 0;
- pReader->nPopulate = 0;
- }
- }
- return rc;
-}
-
-static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){
- int rc = SQLITE_OK;
- assert( !pReader->pBlob
- || (pFrom>=pReader->aNode && pFrom<&pReader->aNode[pReader->nNode])
- );
- while( pReader->pBlob && rc==SQLITE_OK
- && (pFrom - pReader->aNode + nByte)>pReader->nPopulate
- ){
- rc = fts3SegReaderIncrRead(pReader);
- }
- return rc;
-}
-
-/*
-** Set an Fts3SegReader cursor to point at EOF.
-*/
-static void fts3SegReaderSetEof(Fts3SegReader *pSeg){
- if( !fts3SegReaderIsRootOnly(pSeg) ){
- sqlite3_free(pSeg->aNode);
- sqlite3_blob_close(pSeg->pBlob);
- pSeg->pBlob = 0;
- }
- pSeg->aNode = 0;
-}
-
-/*
-** Move the iterator passed as the first argument to the next term in the
-** segment. If successful, SQLITE_OK is returned. If there is no next term,
-** SQLITE_DONE. Otherwise, an SQLite error code.
-*/
-static int fts3SegReaderNext(
- Fts3Table *p,
- Fts3SegReader *pReader,
- int bIncr
-){
- int rc; /* Return code of various sub-routines */
- char *pNext; /* Cursor variable */
- int nPrefix; /* Number of bytes in term prefix */
- int nSuffix; /* Number of bytes in term suffix */
-
- if( !pReader->aDoclist ){
- pNext = pReader->aNode;
- }else{
- pNext = &pReader->aDoclist[pReader->nDoclist];
- }
-
- if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){
-
- if( fts3SegReaderIsPending(pReader) ){
- Fts3HashElem *pElem = *(pReader->ppNextElem);
- if( pElem==0 ){
- pReader->aNode = 0;
- }else{
- PendingList *pList = (PendingList *)fts3HashData(pElem);
- pReader->zTerm = (char *)fts3HashKey(pElem);
- pReader->nTerm = fts3HashKeysize(pElem);
- pReader->nNode = pReader->nDoclist = pList->nData + 1;
- pReader->aNode = pReader->aDoclist = pList->aData;
- pReader->ppNextElem++;
- assert( pReader->aNode );
- }
- return SQLITE_OK;
- }
-
- fts3SegReaderSetEof(pReader);
-
- /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf
- ** blocks have already been traversed. */
- assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock );
- if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){
- return SQLITE_OK;
- }
-
- rc = sqlite3Fts3ReadBlock(
- p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode,
- (bIncr ? &pReader->nPopulate : 0)
- );
- if( rc!=SQLITE_OK ) return rc;
- assert( pReader->pBlob==0 );
- if( bIncr && pReader->nPopulate<pReader->nNode ){
- pReader->pBlob = p->pSegments;
- p->pSegments = 0;
- }
- pNext = pReader->aNode;
- }
-
- assert( !fts3SegReaderIsPending(pReader) );
-
- rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Because of the FTS3_NODE_PADDING bytes of padding, the following is
- ** safe (no risk of overread) even if the node data is corrupted. */
- pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
- pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
- if( nPrefix<0 || nSuffix<=0
- || &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
- ){
- return FTS_CORRUPT_VTAB;
- }
-
- if( nPrefix+nSuffix>pReader->nTermAlloc ){
- int nNew = (nPrefix+nSuffix)*2;
- char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
- if( !zNew ){
- return SQLITE_NOMEM;
- }
- pReader->zTerm = zNew;
- pReader->nTermAlloc = nNew;
- }
-
- rc = fts3SegReaderRequire(pReader, pNext, nSuffix+FTS3_VARINT_MAX);
- if( rc!=SQLITE_OK ) return rc;
-
- memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix);
- pReader->nTerm = nPrefix+nSuffix;
- pNext += nSuffix;
- pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist);
- pReader->aDoclist = pNext;
- pReader->pOffsetList = 0;
-
- /* Check that the doclist does not appear to extend past the end of the
- ** b-tree node. And that the final byte of the doclist is 0x00. If either
- ** of these statements is untrue, then the data structure is corrupt.
- */
- if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
- || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
- ){
- return FTS_CORRUPT_VTAB;
- }
- return SQLITE_OK;
-}
-
-/*
-** Set the SegReader to point to the first docid in the doclist associated
-** with the current term.
-*/
-static int fts3SegReaderFirstDocid(Fts3Table *pTab, Fts3SegReader *pReader){
- int rc = SQLITE_OK;
- assert( pReader->aDoclist );
- assert( !pReader->pOffsetList );
- if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){
- u8 bEof = 0;
- pReader->iDocid = 0;
- pReader->nOffsetList = 0;
- sqlite3Fts3DoclistPrev(0,
- pReader->aDoclist, pReader->nDoclist, &pReader->pOffsetList,
- &pReader->iDocid, &pReader->nOffsetList, &bEof
- );
- }else{
- rc = fts3SegReaderRequire(pReader, pReader->aDoclist, FTS3_VARINT_MAX);
- if( rc==SQLITE_OK ){
- int n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid);
- pReader->pOffsetList = &pReader->aDoclist[n];
- }
- }
- return rc;
-}
-
-/*
-** Advance the SegReader to point to the next docid in the doclist
-** associated with the current term.
-**
-** If arguments ppOffsetList and pnOffsetList are not NULL, then
-** *ppOffsetList is set to point to the first column-offset list
-** in the doclist entry (i.e. immediately past the docid varint).
-** *pnOffsetList is set to the length of the set of column-offset
-** lists, not including the nul-terminator byte. For example:
-*/
-static int fts3SegReaderNextDocid(
- Fts3Table *pTab,
- Fts3SegReader *pReader, /* Reader to advance to next docid */
- char **ppOffsetList, /* OUT: Pointer to current position-list */
- int *pnOffsetList /* OUT: Length of *ppOffsetList in bytes */
-){
- int rc = SQLITE_OK;
- char *p = pReader->pOffsetList;
- char c = 0;
-
- assert( p );
-
- if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){
- /* A pending-terms seg-reader for an FTS4 table that uses order=desc.
- ** Pending-terms doclists are always built up in ascending order, so
- ** we have to iterate through them backwards here. */
- u8 bEof = 0;
- if( ppOffsetList ){
- *ppOffsetList = pReader->pOffsetList;
- *pnOffsetList = pReader->nOffsetList - 1;
- }
- sqlite3Fts3DoclistPrev(0,
- pReader->aDoclist, pReader->nDoclist, &p, &pReader->iDocid,
- &pReader->nOffsetList, &bEof
- );
- if( bEof ){
- pReader->pOffsetList = 0;
- }else{
- pReader->pOffsetList = p;
- }
- }else{
- char *pEnd = &pReader->aDoclist[pReader->nDoclist];
-
- /* Pointer p currently points at the first byte of an offset list. The
- ** following block advances it to point one byte past the end of
- ** the same offset list. */
- while( 1 ){
-
- /* The following line of code (and the "p++" below the while() loop) is
- ** normally all that is required to move pointer p to the desired
- ** position. The exception is if this node is being loaded from disk
- ** incrementally and pointer "p" now points to the first byte passed
- ** the populated part of pReader->aNode[].
- */
- while( *p | c ) c = *p++ & 0x80;
- assert( *p==0 );
-
- if( pReader->pBlob==0 || p<&pReader->aNode[pReader->nPopulate] ) break;
- rc = fts3SegReaderIncrRead(pReader);
- if( rc!=SQLITE_OK ) return rc;
- }
- p++;
-
- /* If required, populate the output variables with a pointer to and the
- ** size of the previous offset-list.
- */
- if( ppOffsetList ){
- *ppOffsetList = pReader->pOffsetList;
- *pnOffsetList = (int)(p - pReader->pOffsetList - 1);
- }
-
- while( p<pEnd && *p==0 ) p++;
-
- /* If there are no more entries in the doclist, set pOffsetList to
- ** NULL. Otherwise, set Fts3SegReader.iDocid to the next docid and
- ** Fts3SegReader.pOffsetList to point to the next offset list before
- ** returning.
- */
- if( p>=pEnd ){
- pReader->pOffsetList = 0;
- }else{
- rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX);
- if( rc==SQLITE_OK ){
- sqlite3_int64 iDelta;
- pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta);
- if( pTab->bDescIdx ){
- pReader->iDocid -= iDelta;
- }else{
- pReader->iDocid += iDelta;
- }
- }
- }
- }
-
- return SQLITE_OK;
-}
-
-
-SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(
- Fts3Cursor *pCsr,
- Fts3MultiSegReader *pMsr,
- int *pnOvfl
-){
- Fts3Table *p = (Fts3Table*)pCsr->base.pVtab;
- int nOvfl = 0;
- int ii;
- int rc = SQLITE_OK;
- int pgsz = p->nPgsz;
-
- assert( p->bFts4 );
- assert( pgsz>0 );
-
- for(ii=0; rc==SQLITE_OK && ii<pMsr->nSegment; ii++){
- Fts3SegReader *pReader = pMsr->apSegment[ii];
- if( !fts3SegReaderIsPending(pReader)
- && !fts3SegReaderIsRootOnly(pReader)
- ){
- sqlite3_int64 jj;
- for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){
- int nBlob;
- rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0);
- if( rc!=SQLITE_OK ) break;
- if( (nBlob+35)>pgsz ){
- nOvfl += (nBlob + 34)/pgsz;
- }
- }
- }
- }
- *pnOvfl = nOvfl;
- return rc;
-}
-
-/*
-** Free all allocations associated with the iterator passed as the
-** second argument.
-*/
-SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
- if( pReader && !fts3SegReaderIsPending(pReader) ){
- sqlite3_free(pReader->zTerm);
- if( !fts3SegReaderIsRootOnly(pReader) ){
- sqlite3_free(pReader->aNode);
- sqlite3_blob_close(pReader->pBlob);
- }
- }
- sqlite3_free(pReader);
-}
-
-/*
-** Allocate a new SegReader object.
-*/
-SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
- int iAge, /* Segment "age". */
- int bLookup, /* True for a lookup only */
- sqlite3_int64 iStartLeaf, /* First leaf to traverse */
- sqlite3_int64 iEndLeaf, /* Final leaf to traverse */
- sqlite3_int64 iEndBlock, /* Final block of segment */
- const char *zRoot, /* Buffer containing root node */
- int nRoot, /* Size of buffer containing root node */
- Fts3SegReader **ppReader /* OUT: Allocated Fts3SegReader */
-){
- Fts3SegReader *pReader; /* Newly allocated SegReader object */
- int nExtra = 0; /* Bytes to allocate segment root node */
-
- assert( iStartLeaf<=iEndLeaf );
- if( iStartLeaf==0 ){
- nExtra = nRoot + FTS3_NODE_PADDING;
- }
-
- pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
- if( !pReader ){
- return SQLITE_NOMEM;
- }
- memset(pReader, 0, sizeof(Fts3SegReader));
- pReader->iIdx = iAge;
- pReader->bLookup = bLookup!=0;
- pReader->iStartBlock = iStartLeaf;
- pReader->iLeafEndBlock = iEndLeaf;
- pReader->iEndBlock = iEndBlock;
-
- if( nExtra ){
- /* The entire segment is stored in the root node. */
- pReader->aNode = (char *)&pReader[1];
- pReader->rootOnly = 1;
- pReader->nNode = nRoot;
- memcpy(pReader->aNode, zRoot, nRoot);
- memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
- }else{
- pReader->iCurrentBlock = iStartLeaf-1;
- }
- *ppReader = pReader;
- return SQLITE_OK;
-}
-
-/*
-** This is a comparison function used as a qsort() callback when sorting
-** an array of pending terms by term. This occurs as part of flushing
-** the contents of the pending-terms hash table to the database.
-*/
-static int fts3CompareElemByTerm(const void *lhs, const void *rhs){
- char *z1 = fts3HashKey(*(Fts3HashElem **)lhs);
- char *z2 = fts3HashKey(*(Fts3HashElem **)rhs);
- int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs);
- int n2 = fts3HashKeysize(*(Fts3HashElem **)rhs);
-
- int n = (n1<n2 ? n1 : n2);
- int c = memcmp(z1, z2, n);
- if( c==0 ){
- c = n1 - n2;
- }
- return c;
-}
-
-/*
-** This function is used to allocate an Fts3SegReader that iterates through
-** a subset of the terms stored in the Fts3Table.pendingTerms array.
-**
-** If the isPrefixIter parameter is zero, then the returned SegReader iterates
-** through each term in the pending-terms table. Or, if isPrefixIter is
-** non-zero, it iterates through each term and its prefixes. For example, if
-** the pending terms hash table contains the terms "sqlite", "mysql" and
-** "firebird", then the iterator visits the following 'terms' (in the order
-** shown):
-**
-** f fi fir fire fireb firebi firebir firebird
-** m my mys mysq mysql
-** s sq sql sqli sqlit sqlite
-**
-** Whereas if isPrefixIter is zero, the terms visited are:
-**
-** firebird mysql sqlite
-*/
-SQLITE_PRIVATE int sqlite3Fts3SegReaderPending(
- Fts3Table *p, /* Virtual table handle */
- int iIndex, /* Index for p->aIndex */
- const char *zTerm, /* Term to search for */
- int nTerm, /* Size of buffer zTerm */
- int bPrefix, /* True for a prefix iterator */
- Fts3SegReader **ppReader /* OUT: SegReader for pending-terms */
-){
- Fts3SegReader *pReader = 0; /* Fts3SegReader object to return */
- Fts3HashElem *pE; /* Iterator variable */
- Fts3HashElem **aElem = 0; /* Array of term hash entries to scan */
- int nElem = 0; /* Size of array at aElem */
- int rc = SQLITE_OK; /* Return Code */
- Fts3Hash *pHash;
-
- pHash = &p->aIndex[iIndex].hPending;
- if( bPrefix ){
- int nAlloc = 0; /* Size of allocated array at aElem */
-
- for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){
- char *zKey = (char *)fts3HashKey(pE);
- int nKey = fts3HashKeysize(pE);
- if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){
- if( nElem==nAlloc ){
- Fts3HashElem **aElem2;
- nAlloc += 16;
- aElem2 = (Fts3HashElem **)sqlite3_realloc(
- aElem, nAlloc*sizeof(Fts3HashElem *)
- );
- if( !aElem2 ){
- rc = SQLITE_NOMEM;
- nElem = 0;
- break;
- }
- aElem = aElem2;
- }
-
- aElem[nElem++] = pE;
- }
- }
-
- /* If more than one term matches the prefix, sort the Fts3HashElem
- ** objects in term order using qsort(). This uses the same comparison
- ** callback as is used when flushing terms to disk.
- */
- if( nElem>1 ){
- qsort(aElem, nElem, sizeof(Fts3HashElem *), fts3CompareElemByTerm);
- }
-
- }else{
- /* The query is a simple term lookup that matches at most one term in
- ** the index. All that is required is a straight hash-lookup.
- **
- ** Because the stack address of pE may be accessed via the aElem pointer
- ** below, the "Fts3HashElem *pE" must be declared so that it is valid
- ** within this entire function, not just this "else{...}" block.
- */
- pE = fts3HashFindElem(pHash, zTerm, nTerm);
- if( pE ){
- aElem = &pE;
- nElem = 1;
- }
- }
-
- if( nElem>0 ){
- int nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *);
- pReader = (Fts3SegReader *)sqlite3_malloc(nByte);
- if( !pReader ){
- rc = SQLITE_NOMEM;
- }else{
- memset(pReader, 0, nByte);
- pReader->iIdx = 0x7FFFFFFF;
- pReader->ppNextElem = (Fts3HashElem **)&pReader[1];
- memcpy(pReader->ppNextElem, aElem, nElem*sizeof(Fts3HashElem *));
- }
- }
-
- if( bPrefix ){
- sqlite3_free(aElem);
- }
- *ppReader = pReader;
- return rc;
-}
-
-/*
-** Compare the entries pointed to by two Fts3SegReader structures.
-** Comparison is as follows:
-**
-** 1) EOF is greater than not EOF.
-**
-** 2) The current terms (if any) are compared using memcmp(). If one
-** term is a prefix of another, the longer term is considered the
-** larger.
-**
-** 3) By segment age. An older segment is considered larger.
-*/
-static int fts3SegReaderCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){
- int rc;
- if( pLhs->aNode && pRhs->aNode ){
- int rc2 = pLhs->nTerm - pRhs->nTerm;
- if( rc2<0 ){
- rc = memcmp(pLhs->zTerm, pRhs->zTerm, pLhs->nTerm);
- }else{
- rc = memcmp(pLhs->zTerm, pRhs->zTerm, pRhs->nTerm);
- }
- if( rc==0 ){
- rc = rc2;
- }
- }else{
- rc = (pLhs->aNode==0) - (pRhs->aNode==0);
- }
- if( rc==0 ){
- rc = pRhs->iIdx - pLhs->iIdx;
- }
- assert( rc!=0 );
- return rc;
-}
-
-/*
-** A different comparison function for SegReader structures. In this
-** version, it is assumed that each SegReader points to an entry in
-** a doclist for identical terms. Comparison is made as follows:
-**
-** 1) EOF (end of doclist in this case) is greater than not EOF.
-**
-** 2) By current docid.
-**
-** 3) By segment age. An older segment is considered larger.
-*/
-static int fts3SegReaderDoclistCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){
- int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0);
- if( rc==0 ){
- if( pLhs->iDocid==pRhs->iDocid ){
- rc = pRhs->iIdx - pLhs->iIdx;
- }else{
- rc = (pLhs->iDocid > pRhs->iDocid) ? 1 : -1;
- }
- }
- assert( pLhs->aNode && pRhs->aNode );
- return rc;
-}
-static int fts3SegReaderDoclistCmpRev(Fts3SegReader *pLhs, Fts3SegReader *pRhs){
- int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0);
- if( rc==0 ){
- if( pLhs->iDocid==pRhs->iDocid ){
- rc = pRhs->iIdx - pLhs->iIdx;
- }else{
- rc = (pLhs->iDocid < pRhs->iDocid) ? 1 : -1;
- }
- }
- assert( pLhs->aNode && pRhs->aNode );
- return rc;
-}
-
-/*
-** Compare the term that the Fts3SegReader object passed as the first argument
-** points to with the term specified by arguments zTerm and nTerm.
-**
-** If the pSeg iterator is already at EOF, return 0. Otherwise, return
-** -ve if the pSeg term is less than zTerm/nTerm, 0 if the two terms are
-** equal, or +ve if the pSeg term is greater than zTerm/nTerm.
-*/
-static int fts3SegReaderTermCmp(
- Fts3SegReader *pSeg, /* Segment reader object */
- const char *zTerm, /* Term to compare to */
- int nTerm /* Size of term zTerm in bytes */
-){
- int res = 0;
- if( pSeg->aNode ){
- if( pSeg->nTerm>nTerm ){
- res = memcmp(pSeg->zTerm, zTerm, nTerm);
- }else{
- res = memcmp(pSeg->zTerm, zTerm, pSeg->nTerm);
- }
- if( res==0 ){
- res = pSeg->nTerm-nTerm;
- }
- }
- return res;
-}
-
-/*
-** Argument apSegment is an array of nSegment elements. It is known that
-** the final (nSegment-nSuspect) members are already in sorted order
-** (according to the comparison function provided). This function shuffles
-** the array around until all entries are in sorted order.
-*/
-static void fts3SegReaderSort(
- Fts3SegReader **apSegment, /* Array to sort entries of */
- int nSegment, /* Size of apSegment array */
- int nSuspect, /* Unsorted entry count */
- int (*xCmp)(Fts3SegReader *, Fts3SegReader *) /* Comparison function */
-){
- int i; /* Iterator variable */
-
- assert( nSuspect<=nSegment );
-
- if( nSuspect==nSegment ) nSuspect--;
- for(i=nSuspect-1; i>=0; i--){
- int j;
- for(j=i; j<(nSegment-1); j++){
- Fts3SegReader *pTmp;
- if( xCmp(apSegment[j], apSegment[j+1])<0 ) break;
- pTmp = apSegment[j+1];
- apSegment[j+1] = apSegment[j];
- apSegment[j] = pTmp;
- }
- }
-
-#ifndef NDEBUG
- /* Check that the list really is sorted now. */
- for(i=0; i<(nSuspect-1); i++){
- assert( xCmp(apSegment[i], apSegment[i+1])<0 );
- }
-#endif
-}
-
-/*
-** Insert a record into the %_segments table.
-*/
-static int fts3WriteSegment(
- Fts3Table *p, /* Virtual table handle */
- sqlite3_int64 iBlock, /* Block id for new block */
- char *z, /* Pointer to buffer containing block data */
- int n /* Size of buffer z in bytes */
-){
- sqlite3_stmt *pStmt;
- int rc = fts3SqlStmt(p, SQL_INSERT_SEGMENTS, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pStmt, 1, iBlock);
- sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC);
- sqlite3_step(pStmt);
- rc = sqlite3_reset(pStmt);
- }
- return rc;
-}
-
-/*
-** Find the largest relative level number in the table. If successful, set
-** *pnMax to this value and return SQLITE_OK. Otherwise, if an error occurs,
-** set *pnMax to zero and return an SQLite error code.
-*/
-SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *p, int *pnMax){
- int rc;
- int mxLevel = 0;
- sqlite3_stmt *pStmt = 0;
-
- rc = fts3SqlStmt(p, SQL_SELECT_MXLEVEL, &pStmt, 0);
- if( rc==SQLITE_OK ){
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- mxLevel = sqlite3_column_int(pStmt, 0);
- }
- rc = sqlite3_reset(pStmt);
- }
- *pnMax = mxLevel;
- return rc;
-}
-
-/*
-** Insert a record into the %_segdir table.
-*/
-static int fts3WriteSegdir(
- Fts3Table *p, /* Virtual table handle */
- sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */
- int iIdx, /* Value for "idx" field */
- sqlite3_int64 iStartBlock, /* Value for "start_block" field */
- sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */
- sqlite3_int64 iEndBlock, /* Value for "end_block" field */
- char *zRoot, /* Blob value for "root" field */
- int nRoot /* Number of bytes in buffer zRoot */
-){
- sqlite3_stmt *pStmt;
- int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pStmt, 1, iLevel);
- sqlite3_bind_int(pStmt, 2, iIdx);
- sqlite3_bind_int64(pStmt, 3, iStartBlock);
- sqlite3_bind_int64(pStmt, 4, iLeafEndBlock);
- sqlite3_bind_int64(pStmt, 5, iEndBlock);
- sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC);
- sqlite3_step(pStmt);
- rc = sqlite3_reset(pStmt);
- }
- return rc;
-}
-
-/*
-** Return the size of the common prefix (if any) shared by zPrev and
-** zNext, in bytes. For example,
-**
-** fts3PrefixCompress("abc", 3, "abcdef", 6) // returns 3
-** fts3PrefixCompress("abX", 3, "abcdef", 6) // returns 2
-** fts3PrefixCompress("abX", 3, "Xbcdef", 6) // returns 0
-*/
-static int fts3PrefixCompress(
- const char *zPrev, /* Buffer containing previous term */
- int nPrev, /* Size of buffer zPrev in bytes */
- const char *zNext, /* Buffer containing next term */
- int nNext /* Size of buffer zNext in bytes */
-){
- int n;
- UNUSED_PARAMETER(nNext);
- for(n=0; n<nPrev && zPrev[n]==zNext[n]; n++);
- return n;
-}
-
-/*
-** Add term zTerm to the SegmentNode. It is guaranteed that zTerm is larger
-** (according to memcmp) than the previous term.
-*/
-static int fts3NodeAddTerm(
- Fts3Table *p, /* Virtual table handle */
- SegmentNode **ppTree, /* IN/OUT: SegmentNode handle */
- int isCopyTerm, /* True if zTerm/nTerm is transient */
- const char *zTerm, /* Pointer to buffer containing term */
- int nTerm /* Size of term in bytes */
-){
- SegmentNode *pTree = *ppTree;
- int rc;
- SegmentNode *pNew;
-
- /* First try to append the term to the current node. Return early if
- ** this is possible.
- */
- if( pTree ){
- int nData = pTree->nData; /* Current size of node in bytes */
- int nReq = nData; /* Required space after adding zTerm */
- int nPrefix; /* Number of bytes of prefix compression */
- int nSuffix; /* Suffix length */
-
- nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm);
- nSuffix = nTerm-nPrefix;
-
- nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix;
- if( nReq<=p->nNodeSize || !pTree->zTerm ){
-
- if( nReq>p->nNodeSize ){
- /* An unusual case: this is the first term to be added to the node
- ** and the static node buffer (p->nNodeSize bytes) is not large
- ** enough. Use a separately malloced buffer instead This wastes
- ** p->nNodeSize bytes, but since this scenario only comes about when
- ** the database contain two terms that share a prefix of almost 2KB,
- ** this is not expected to be a serious problem.
- */
- assert( pTree->aData==(char *)&pTree[1] );
- pTree->aData = (char *)sqlite3_malloc(nReq);
- if( !pTree->aData ){
- return SQLITE_NOMEM;
- }
- }
-
- if( pTree->zTerm ){
- /* There is no prefix-length field for first term in a node */
- nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nPrefix);
- }
-
- nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nSuffix);
- memcpy(&pTree->aData[nData], &zTerm[nPrefix], nSuffix);
- pTree->nData = nData + nSuffix;
- pTree->nEntry++;
-
- if( isCopyTerm ){
- if( pTree->nMalloc<nTerm ){
- char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2);
- if( !zNew ){
- return SQLITE_NOMEM;
- }
- pTree->nMalloc = nTerm*2;
- pTree->zMalloc = zNew;
- }
- pTree->zTerm = pTree->zMalloc;
- memcpy(pTree->zTerm, zTerm, nTerm);
- pTree->nTerm = nTerm;
- }else{
- pTree->zTerm = (char *)zTerm;
- pTree->nTerm = nTerm;
- }
- return SQLITE_OK;
- }
- }
-
- /* If control flows to here, it was not possible to append zTerm to the
- ** current node. Create a new node (a right-sibling of the current node).
- ** If this is the first node in the tree, the term is added to it.
- **
- ** Otherwise, the term is not added to the new node, it is left empty for
- ** now. Instead, the term is inserted into the parent of pTree. If pTree
- ** has no parent, one is created here.
- */
- pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize);
- if( !pNew ){
- return SQLITE_NOMEM;
- }
- memset(pNew, 0, sizeof(SegmentNode));
- pNew->nData = 1 + FTS3_VARINT_MAX;
- pNew->aData = (char *)&pNew[1];
-
- if( pTree ){
- SegmentNode *pParent = pTree->pParent;
- rc = fts3NodeAddTerm(p, &pParent, isCopyTerm, zTerm, nTerm);
- if( pTree->pParent==0 ){
- pTree->pParent = pParent;
- }
- pTree->pRight = pNew;
- pNew->pLeftmost = pTree->pLeftmost;
- pNew->pParent = pParent;
- pNew->zMalloc = pTree->zMalloc;
- pNew->nMalloc = pTree->nMalloc;
- pTree->zMalloc = 0;
- }else{
- pNew->pLeftmost = pNew;
- rc = fts3NodeAddTerm(p, &pNew, isCopyTerm, zTerm, nTerm);
- }
-
- *ppTree = pNew;
- return rc;
-}
-
-/*
-** Helper function for fts3NodeWrite().
-*/
-static int fts3TreeFinishNode(
- SegmentNode *pTree,
- int iHeight,
- sqlite3_int64 iLeftChild
-){
- int nStart;
- assert( iHeight>=1 && iHeight<128 );
- nStart = FTS3_VARINT_MAX - sqlite3Fts3VarintLen(iLeftChild);
- pTree->aData[nStart] = (char)iHeight;
- sqlite3Fts3PutVarint(&pTree->aData[nStart+1], iLeftChild);
- return nStart;
-}
-
-/*
-** Write the buffer for the segment node pTree and all of its peers to the
-** database. Then call this function recursively to write the parent of
-** pTree and its peers to the database.
-**
-** Except, if pTree is a root node, do not write it to the database. Instead,
-** set output variables *paRoot and *pnRoot to contain the root node.
-**
-** If successful, SQLITE_OK is returned and output variable *piLast is
-** set to the largest blockid written to the database (or zero if no
-** blocks were written to the db). Otherwise, an SQLite error code is
-** returned.
-*/
-static int fts3NodeWrite(
- Fts3Table *p, /* Virtual table handle */
- SegmentNode *pTree, /* SegmentNode handle */
- int iHeight, /* Height of this node in tree */
- sqlite3_int64 iLeaf, /* Block id of first leaf node */
- sqlite3_int64 iFree, /* Block id of next free slot in %_segments */
- sqlite3_int64 *piLast, /* OUT: Block id of last entry written */
- char **paRoot, /* OUT: Data for root node */
- int *pnRoot /* OUT: Size of root node in bytes */
-){
- int rc = SQLITE_OK;
-
- if( !pTree->pParent ){
- /* Root node of the tree. */
- int nStart = fts3TreeFinishNode(pTree, iHeight, iLeaf);
- *piLast = iFree-1;
- *pnRoot = pTree->nData - nStart;
- *paRoot = &pTree->aData[nStart];
- }else{
- SegmentNode *pIter;
- sqlite3_int64 iNextFree = iFree;
- sqlite3_int64 iNextLeaf = iLeaf;
- for(pIter=pTree->pLeftmost; pIter && rc==SQLITE_OK; pIter=pIter->pRight){
- int nStart = fts3TreeFinishNode(pIter, iHeight, iNextLeaf);
- int nWrite = pIter->nData - nStart;
-
- rc = fts3WriteSegment(p, iNextFree, &pIter->aData[nStart], nWrite);
- iNextFree++;
- iNextLeaf += (pIter->nEntry+1);
- }
- if( rc==SQLITE_OK ){
- assert( iNextLeaf==iFree );
- rc = fts3NodeWrite(
- p, pTree->pParent, iHeight+1, iFree, iNextFree, piLast, paRoot, pnRoot
- );
- }
- }
-
- return rc;
-}
-
-/*
-** Free all memory allocations associated with the tree pTree.
-*/
-static void fts3NodeFree(SegmentNode *pTree){
- if( pTree ){
- SegmentNode *p = pTree->pLeftmost;
- fts3NodeFree(p->pParent);
- while( p ){
- SegmentNode *pRight = p->pRight;
- if( p->aData!=(char *)&p[1] ){
- sqlite3_free(p->aData);
- }
- assert( pRight==0 || p->zMalloc==0 );
- sqlite3_free(p->zMalloc);
- sqlite3_free(p);
- p = pRight;
- }
- }
-}
-
-/*
-** Add a term to the segment being constructed by the SegmentWriter object
-** *ppWriter. When adding the first term to a segment, *ppWriter should
-** be passed NULL. This function will allocate a new SegmentWriter object
-** and return it via the input/output variable *ppWriter in this case.
-**
-** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
-*/
-static int fts3SegWriterAdd(
- Fts3Table *p, /* Virtual table handle */
- SegmentWriter **ppWriter, /* IN/OUT: SegmentWriter handle */
- int isCopyTerm, /* True if buffer zTerm must be copied */
- const char *zTerm, /* Pointer to buffer containing term */
- int nTerm, /* Size of term in bytes */
- const char *aDoclist, /* Pointer to buffer containing doclist */
- int nDoclist /* Size of doclist in bytes */
-){
- int nPrefix; /* Size of term prefix in bytes */
- int nSuffix; /* Size of term suffix in bytes */
- int nReq; /* Number of bytes required on leaf page */
- int nData;
- SegmentWriter *pWriter = *ppWriter;
-
- if( !pWriter ){
- int rc;
- sqlite3_stmt *pStmt;
-
- /* Allocate the SegmentWriter structure */
- pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter));
- if( !pWriter ) return SQLITE_NOMEM;
- memset(pWriter, 0, sizeof(SegmentWriter));
- *ppWriter = pWriter;
-
- /* Allocate a buffer in which to accumulate data */
- pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize);
- if( !pWriter->aData ) return SQLITE_NOMEM;
- pWriter->nSize = p->nNodeSize;
-
- /* Find the next free blockid in the %_segments table */
- rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0);
- if( rc!=SQLITE_OK ) return rc;
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- pWriter->iFree = sqlite3_column_int64(pStmt, 0);
- pWriter->iFirst = pWriter->iFree;
- }
- rc = sqlite3_reset(pStmt);
- if( rc!=SQLITE_OK ) return rc;
- }
- nData = pWriter->nData;
-
- nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm);
- nSuffix = nTerm-nPrefix;
-
- /* Figure out how many bytes are required by this new entry */
- nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */
- sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */
- nSuffix + /* Term suffix */
- sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */
- nDoclist; /* Doclist data */
-
- if( nData>0 && nData+nReq>p->nNodeSize ){
- int rc;
-
- /* The current leaf node is full. Write it out to the database. */
- rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData);
- if( rc!=SQLITE_OK ) return rc;
- p->nLeafAdd++;
-
- /* Add the current term to the interior node tree. The term added to
- ** the interior tree must:
- **
- ** a) be greater than the largest term on the leaf node just written
- ** to the database (still available in pWriter->zTerm), and
- **
- ** b) be less than or equal to the term about to be added to the new
- ** leaf node (zTerm/nTerm).
- **
- ** In other words, it must be the prefix of zTerm 1 byte longer than
- ** the common prefix (if any) of zTerm and pWriter->zTerm.
- */
- assert( nPrefix<nTerm );
- rc = fts3NodeAddTerm(p, &pWriter->pTree, isCopyTerm, zTerm, nPrefix+1);
- if( rc!=SQLITE_OK ) return rc;
-
- nData = 0;
- pWriter->nTerm = 0;
-
- nPrefix = 0;
- nSuffix = nTerm;
- nReq = 1 + /* varint containing prefix size */
- sqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */
- nTerm + /* Term suffix */
- sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */
- nDoclist; /* Doclist data */
- }
-
- /* If the buffer currently allocated is too small for this entry, realloc
- ** the buffer to make it large enough.
- */
- if( nReq>pWriter->nSize ){
- char *aNew = sqlite3_realloc(pWriter->aData, nReq);
- if( !aNew ) return SQLITE_NOMEM;
- pWriter->aData = aNew;
- pWriter->nSize = nReq;
- }
- assert( nData+nReq<=pWriter->nSize );
-
- /* Append the prefix-compressed term and doclist to the buffer. */
- nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix);
- nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix);
- memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix);
- nData += nSuffix;
- nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist);
- memcpy(&pWriter->aData[nData], aDoclist, nDoclist);
- pWriter->nData = nData + nDoclist;
-
- /* Save the current term so that it can be used to prefix-compress the next.
- ** If the isCopyTerm parameter is true, then the buffer pointed to by
- ** zTerm is transient, so take a copy of the term data. Otherwise, just
- ** store a copy of the pointer.
- */
- if( isCopyTerm ){
- if( nTerm>pWriter->nMalloc ){
- char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2);
- if( !zNew ){
- return SQLITE_NOMEM;
- }
- pWriter->nMalloc = nTerm*2;
- pWriter->zMalloc = zNew;
- pWriter->zTerm = zNew;
- }
- assert( pWriter->zTerm==pWriter->zMalloc );
- memcpy(pWriter->zTerm, zTerm, nTerm);
- }else{
- pWriter->zTerm = (char *)zTerm;
- }
- pWriter->nTerm = nTerm;
-
- return SQLITE_OK;
-}
-
-/*
-** Flush all data associated with the SegmentWriter object pWriter to the
-** database. This function must be called after all terms have been added
-** to the segment using fts3SegWriterAdd(). If successful, SQLITE_OK is
-** returned. Otherwise, an SQLite error code.
-*/
-static int fts3SegWriterFlush(
- Fts3Table *p, /* Virtual table handle */
- SegmentWriter *pWriter, /* SegmentWriter to flush to the db */
- sqlite3_int64 iLevel, /* Value for 'level' column of %_segdir */
- int iIdx /* Value for 'idx' column of %_segdir */
-){
- int rc; /* Return code */
- if( pWriter->pTree ){
- sqlite3_int64 iLast = 0; /* Largest block id written to database */
- sqlite3_int64 iLastLeaf; /* Largest leaf block id written to db */
- char *zRoot = NULL; /* Pointer to buffer containing root node */
- int nRoot = 0; /* Size of buffer zRoot */
-
- iLastLeaf = pWriter->iFree;
- rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, pWriter->nData);
- if( rc==SQLITE_OK ){
- rc = fts3NodeWrite(p, pWriter->pTree, 1,
- pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot);
- }
- if( rc==SQLITE_OK ){
- rc = fts3WriteSegdir(
- p, iLevel, iIdx, pWriter->iFirst, iLastLeaf, iLast, zRoot, nRoot);
- }
- }else{
- /* The entire tree fits on the root node. Write it to the segdir table. */
- rc = fts3WriteSegdir(
- p, iLevel, iIdx, 0, 0, 0, pWriter->aData, pWriter->nData);
- }
- p->nLeafAdd++;
- return rc;
-}
-
-/*
-** Release all memory held by the SegmentWriter object passed as the
-** first argument.
-*/
-static void fts3SegWriterFree(SegmentWriter *pWriter){
- if( pWriter ){
- sqlite3_free(pWriter->aData);
- sqlite3_free(pWriter->zMalloc);
- fts3NodeFree(pWriter->pTree);
- sqlite3_free(pWriter);
- }
-}
-
-/*
-** The first value in the apVal[] array is assumed to contain an integer.
-** This function tests if there exist any documents with docid values that
-** are different from that integer. i.e. if deleting the document with docid
-** pRowid would mean the FTS3 table were empty.
-**
-** If successful, *pisEmpty is set to true if the table is empty except for
-** document pRowid, or false otherwise, and SQLITE_OK is returned. If an
-** error occurs, an SQLite error code is returned.
-*/
-static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){
- sqlite3_stmt *pStmt;
- int rc;
- if( p->zContentTbl ){
- /* If using the content=xxx option, assume the table is never empty */
- *pisEmpty = 0;
- rc = SQLITE_OK;
- }else{
- rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid);
- if( rc==SQLITE_OK ){
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- *pisEmpty = sqlite3_column_int(pStmt, 0);
- }
- rc = sqlite3_reset(pStmt);
- }
- }
- return rc;
-}
-
-/*
-** Set *pnMax to the largest segment level in the database for the index
-** iIndex.
-**
-** Segment levels are stored in the 'level' column of the %_segdir table.
-**
-** Return SQLITE_OK if successful, or an SQLite error code if not.
-*/
-static int fts3SegmentMaxLevel(
- Fts3Table *p,
- int iLangid,
- int iIndex,
- sqlite3_int64 *pnMax
-){
- sqlite3_stmt *pStmt;
- int rc;
- assert( iIndex>=0 && iIndex<p->nIndex );
-
- /* Set pStmt to the compiled version of:
- **
- ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?
- **
- ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR).
- */
- rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0);
- if( rc!=SQLITE_OK ) return rc;
- sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0));
- sqlite3_bind_int64(pStmt, 2,
- getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1)
- );
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- *pnMax = sqlite3_column_int64(pStmt, 0);
- }
- return sqlite3_reset(pStmt);
-}
-
-/*
-** Delete all entries in the %_segments table associated with the segment
-** opened with seg-reader pSeg. This function does not affect the contents
-** of the %_segdir table.
-*/
-static int fts3DeleteSegment(
- Fts3Table *p, /* FTS table handle */
- Fts3SegReader *pSeg /* Segment to delete */
-){
- int rc = SQLITE_OK; /* Return code */
- if( pSeg->iStartBlock ){
- sqlite3_stmt *pDelete; /* SQL statement to delete rows */
- rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDelete, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pDelete, 1, pSeg->iStartBlock);
- sqlite3_bind_int64(pDelete, 2, pSeg->iEndBlock);
- sqlite3_step(pDelete);
- rc = sqlite3_reset(pDelete);
- }
- }
- return rc;
-}
-
-/*
-** This function is used after merging multiple segments into a single large
-** segment to delete the old, now redundant, segment b-trees. Specifically,
-** it:
-**
-** 1) Deletes all %_segments entries for the segments associated with
-** each of the SegReader objects in the array passed as the third
-** argument, and
-**
-** 2) deletes all %_segdir entries with level iLevel, or all %_segdir
-** entries regardless of level if (iLevel<0).
-**
-** SQLITE_OK is returned if successful, otherwise an SQLite error code.
-*/
-static int fts3DeleteSegdir(
- Fts3Table *p, /* Virtual table handle */
- int iLangid, /* Language id */
- int iIndex, /* Index for p->aIndex */
- int iLevel, /* Level of %_segdir entries to delete */
- Fts3SegReader **apSegment, /* Array of SegReader objects */
- int nReader /* Size of array apSegment */
-){
- int rc = SQLITE_OK; /* Return Code */
- int i; /* Iterator variable */
- sqlite3_stmt *pDelete = 0; /* SQL statement to delete rows */
-
- for(i=0; rc==SQLITE_OK && i<nReader; i++){
- rc = fts3DeleteSegment(p, apSegment[i]);
- }
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- assert( iLevel>=0 || iLevel==FTS3_SEGCURSOR_ALL );
- if( iLevel==FTS3_SEGCURSOR_ALL ){
- rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, 0));
- sqlite3_bind_int64(pDelete, 2,
- getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1)
- );
- }
- }else{
- rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pDelete, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(
- pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel)
- );
- }
- }
-
- if( rc==SQLITE_OK ){
- sqlite3_step(pDelete);
- rc = sqlite3_reset(pDelete);
- }
-
- return rc;
-}
-
-/*
-** When this function is called, buffer *ppList (size *pnList bytes) contains
-** a position list that may (or may not) feature multiple columns. This
-** function adjusts the pointer *ppList and the length *pnList so that they
-** identify the subset of the position list that corresponds to column iCol.
-**
-** If there are no entries in the input position list for column iCol, then
-** *pnList is set to zero before returning.
-*/
-static void fts3ColumnFilter(
- int iCol, /* Column to filter on */
- char **ppList, /* IN/OUT: Pointer to position list */
- int *pnList /* IN/OUT: Size of buffer *ppList in bytes */
-){
- char *pList = *ppList;
- int nList = *pnList;
- char *pEnd = &pList[nList];
- int iCurrent = 0;
- char *p = pList;
-
- assert( iCol>=0 );
- while( 1 ){
- char c = 0;
- while( p<pEnd && (c | *p)&0xFE ) c = *p++ & 0x80;
-
- if( iCol==iCurrent ){
- nList = (int)(p - pList);
- break;
- }
-
- nList -= (int)(p - pList);
- pList = p;
- if( nList==0 ){
- break;
- }
- p = &pList[1];
- p += sqlite3Fts3GetVarint32(p, &iCurrent);
- }
-
- *ppList = pList;
- *pnList = nList;
-}
-
-/*
-** Cache data in the Fts3MultiSegReader.aBuffer[] buffer (overwriting any
-** existing data). Grow the buffer if required.
-**
-** If successful, return SQLITE_OK. Otherwise, if an OOM error is encountered
-** trying to resize the buffer, return SQLITE_NOMEM.
-*/
-static int fts3MsrBufferData(
- Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */
- char *pList,
- int nList
-){
- if( nList>pMsr->nBuffer ){
- char *pNew;
- pMsr->nBuffer = nList*2;
- pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer);
- if( !pNew ) return SQLITE_NOMEM;
- pMsr->aBuffer = pNew;
- }
-
- memcpy(pMsr->aBuffer, pList, nList);
- return SQLITE_OK;
-}
-
-SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
- Fts3Table *p, /* Virtual table handle */
- Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */
- sqlite3_int64 *piDocid, /* OUT: Docid value */
- char **paPoslist, /* OUT: Pointer to position list */
- int *pnPoslist /* OUT: Size of position list in bytes */
-){
- int nMerge = pMsr->nAdvance;
- Fts3SegReader **apSegment = pMsr->apSegment;
- int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
- p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp
- );
-
- if( nMerge==0 ){
- *paPoslist = 0;
- return SQLITE_OK;
- }
-
- while( 1 ){
- Fts3SegReader *pSeg;
- pSeg = pMsr->apSegment[0];
-
- if( pSeg->pOffsetList==0 ){
- *paPoslist = 0;
- break;
- }else{
- int rc;
- char *pList;
- int nList;
- int j;
- sqlite3_int64 iDocid = apSegment[0]->iDocid;
-
- rc = fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
- j = 1;
- while( rc==SQLITE_OK
- && j<nMerge
- && apSegment[j]->pOffsetList
- && apSegment[j]->iDocid==iDocid
- ){
- rc = fts3SegReaderNextDocid(p, apSegment[j], 0, 0);
- j++;
- }
- if( rc!=SQLITE_OK ) return rc;
- fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp);
-
- if( pMsr->iColFilter>=0 ){
- fts3ColumnFilter(pMsr->iColFilter, &pList, &nList);
- }
-
- if( nList>0 ){
- if( fts3SegReaderIsPending(apSegment[0]) ){
- rc = fts3MsrBufferData(pMsr, pList, nList+1);
- if( rc!=SQLITE_OK ) return rc;
- *paPoslist = pMsr->aBuffer;
- assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 );
- }else{
- *paPoslist = pList;
- }
- *piDocid = iDocid;
- *pnPoslist = nList;
- break;
- }
- }
- }
-
- return SQLITE_OK;
-}
-
-static int fts3SegReaderStart(
- Fts3Table *p, /* Virtual table handle */
- Fts3MultiSegReader *pCsr, /* Cursor object */
- const char *zTerm, /* Term searched for (or NULL) */
- int nTerm /* Length of zTerm in bytes */
-){
- int i;
- int nSeg = pCsr->nSegment;
-
- /* If the Fts3SegFilter defines a specific term (or term prefix) to search
- ** for, then advance each segment iterator until it points to a term of
- ** equal or greater value than the specified term. This prevents many
- ** unnecessary merge/sort operations for the case where single segment
- ** b-tree leaf nodes contain more than one term.
- */
- for(i=0; pCsr->bRestart==0 && i<pCsr->nSegment; i++){
- int res = 0;
- Fts3SegReader *pSeg = pCsr->apSegment[i];
- do {
- int rc = fts3SegReaderNext(p, pSeg, 0);
- if( rc!=SQLITE_OK ) return rc;
- }while( zTerm && (res = fts3SegReaderTermCmp(pSeg, zTerm, nTerm))<0 );
-
- if( pSeg->bLookup && res!=0 ){
- fts3SegReaderSetEof(pSeg);
- }
- }
- fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp);
-
- return SQLITE_OK;
-}
-
-SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(
- Fts3Table *p, /* Virtual table handle */
- Fts3MultiSegReader *pCsr, /* Cursor object */
- Fts3SegFilter *pFilter /* Restrictions on range of iteration */
-){
- pCsr->pFilter = pFilter;
- return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm);
-}
-
-SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart(
- Fts3Table *p, /* Virtual table handle */
- Fts3MultiSegReader *pCsr, /* Cursor object */
- int iCol, /* Column to match on. */
- const char *zTerm, /* Term to iterate through a doclist for */
- int nTerm /* Number of bytes in zTerm */
-){
- int i;
- int rc;
- int nSegment = pCsr->nSegment;
- int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
- p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp
- );
-
- assert( pCsr->pFilter==0 );
- assert( zTerm && nTerm>0 );
-
- /* Advance each segment iterator until it points to the term zTerm/nTerm. */
- rc = fts3SegReaderStart(p, pCsr, zTerm, nTerm);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Determine how many of the segments actually point to zTerm/nTerm. */
- for(i=0; i<nSegment; i++){
- Fts3SegReader *pSeg = pCsr->apSegment[i];
- if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){
- break;
- }
- }
- pCsr->nAdvance = i;
-
- /* Advance each of the segments to point to the first docid. */
- for(i=0; i<pCsr->nAdvance; i++){
- rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]);
- if( rc!=SQLITE_OK ) return rc;
- }
- fts3SegReaderSort(pCsr->apSegment, i, i, xCmp);
-
- assert( iCol<0 || iCol<p->nColumn );
- pCsr->iColFilter = iCol;
-
- return SQLITE_OK;
-}
-
-/*
-** This function is called on a MultiSegReader that has been started using
-** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also
-** have been made. Calling this function puts the MultiSegReader in such
-** a state that if the next two calls are:
-**
-** sqlite3Fts3SegReaderStart()
-** sqlite3Fts3SegReaderStep()
-**
-** then the entire doclist for the term is available in
-** MultiSegReader.aDoclist/nDoclist.
-*/
-SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){
- int i; /* Used to iterate through segment-readers */
-
- assert( pCsr->zTerm==0 );
- assert( pCsr->nTerm==0 );
- assert( pCsr->aDoclist==0 );
- assert( pCsr->nDoclist==0 );
-
- pCsr->nAdvance = 0;
- pCsr->bRestart = 1;
- for(i=0; i<pCsr->nSegment; i++){
- pCsr->apSegment[i]->pOffsetList = 0;
- pCsr->apSegment[i]->nOffsetList = 0;
- pCsr->apSegment[i]->iDocid = 0;
- }
-
- return SQLITE_OK;
-}
-
-
-SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(
- Fts3Table *p, /* Virtual table handle */
- Fts3MultiSegReader *pCsr /* Cursor object */
-){
- int rc = SQLITE_OK;
-
- int isIgnoreEmpty = (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY);
- int isRequirePos = (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS);
- int isColFilter = (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER);
- int isPrefix = (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX);
- int isScan = (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN);
- int isFirst = (pCsr->pFilter->flags & FTS3_SEGMENT_FIRST);
-
- Fts3SegReader **apSegment = pCsr->apSegment;
- int nSegment = pCsr->nSegment;
- Fts3SegFilter *pFilter = pCsr->pFilter;
- int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
- p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp
- );
-
- if( pCsr->nSegment==0 ) return SQLITE_OK;
-
- do {
- int nMerge;
- int i;
-
- /* Advance the first pCsr->nAdvance entries in the apSegment[] array
- ** forward. Then sort the list in order of current term again.
- */
- for(i=0; i<pCsr->nAdvance; i++){
- Fts3SegReader *pSeg = apSegment[i];
- if( pSeg->bLookup ){
- fts3SegReaderSetEof(pSeg);
- }else{
- rc = fts3SegReaderNext(p, pSeg, 0);
- }
- if( rc!=SQLITE_OK ) return rc;
- }
- fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp);
- pCsr->nAdvance = 0;
-
- /* If all the seg-readers are at EOF, we're finished. return SQLITE_OK. */
- assert( rc==SQLITE_OK );
- if( apSegment[0]->aNode==0 ) break;
-
- pCsr->nTerm = apSegment[0]->nTerm;
- pCsr->zTerm = apSegment[0]->zTerm;
-
- /* If this is a prefix-search, and if the term that apSegment[0] points
- ** to does not share a suffix with pFilter->zTerm/nTerm, then all
- ** required callbacks have been made. In this case exit early.
- **
- ** Similarly, if this is a search for an exact match, and the first term
- ** of segment apSegment[0] is not a match, exit early.
- */
- if( pFilter->zTerm && !isScan ){
- if( pCsr->nTerm<pFilter->nTerm
- || (!isPrefix && pCsr->nTerm>pFilter->nTerm)
- || memcmp(pCsr->zTerm, pFilter->zTerm, pFilter->nTerm)
- ){
- break;
- }
- }
-
- nMerge = 1;
- while( nMerge<nSegment
- && apSegment[nMerge]->aNode
- && apSegment[nMerge]->nTerm==pCsr->nTerm
- && 0==memcmp(pCsr->zTerm, apSegment[nMerge]->zTerm, pCsr->nTerm)
- ){
- nMerge++;
- }
-
- assert( isIgnoreEmpty || (isRequirePos && !isColFilter) );
- if( nMerge==1
- && !isIgnoreEmpty
- && !isFirst
- && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
- ){
- pCsr->nDoclist = apSegment[0]->nDoclist;
- if( fts3SegReaderIsPending(apSegment[0]) ){
- rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
- pCsr->aDoclist = pCsr->aBuffer;
- }else{
- pCsr->aDoclist = apSegment[0]->aDoclist;
- }
- if( rc==SQLITE_OK ) rc = SQLITE_ROW;
- }else{
- int nDoclist = 0; /* Size of doclist */
- sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */
-
- /* The current term of the first nMerge entries in the array
- ** of Fts3SegReader objects is the same. The doclists must be merged
- ** and a single term returned with the merged doclist.
- */
- for(i=0; i<nMerge; i++){
- fts3SegReaderFirstDocid(p, apSegment[i]);
- }
- fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp);
- while( apSegment[0]->pOffsetList ){
- int j; /* Number of segments that share a docid */
- char *pList;
- int nList;
- int nByte;
- sqlite3_int64 iDocid = apSegment[0]->iDocid;
- fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
- j = 1;
- while( j<nMerge
- && apSegment[j]->pOffsetList
- && apSegment[j]->iDocid==iDocid
- ){
- fts3SegReaderNextDocid(p, apSegment[j], 0, 0);
- j++;
- }
-
- if( isColFilter ){
- fts3ColumnFilter(pFilter->iCol, &pList, &nList);
- }
-
- if( !isIgnoreEmpty || nList>0 ){
-
- /* Calculate the 'docid' delta value to write into the merged
- ** doclist. */
- sqlite3_int64 iDelta;
- if( p->bDescIdx && nDoclist>0 ){
- iDelta = iPrev - iDocid;
- }else{
- iDelta = iDocid - iPrev;
- }
- assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) );
- assert( nDoclist>0 || iDelta==iDocid );
-
- nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0);
- if( nDoclist+nByte>pCsr->nBuffer ){
- char *aNew;
- pCsr->nBuffer = (nDoclist+nByte)*2;
- aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer);
- if( !aNew ){
- return SQLITE_NOMEM;
- }
- pCsr->aBuffer = aNew;
- }
-
- if( isFirst ){
- char *a = &pCsr->aBuffer[nDoclist];
- int nWrite;
-
- nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a);
- if( nWrite ){
- iPrev = iDocid;
- nDoclist += nWrite;
- }
- }else{
- nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta);
- iPrev = iDocid;
- if( isRequirePos ){
- memcpy(&pCsr->aBuffer[nDoclist], pList, nList);
- nDoclist += nList;
- pCsr->aBuffer[nDoclist++] = '\0';
- }
- }
- }
-
- fts3SegReaderSort(apSegment, nMerge, j, xCmp);
- }
- if( nDoclist>0 ){
- pCsr->aDoclist = pCsr->aBuffer;
- pCsr->nDoclist = nDoclist;
- rc = SQLITE_ROW;
- }
- }
- pCsr->nAdvance = nMerge;
- }while( rc==SQLITE_OK );
-
- return rc;
-}
-
-
-SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(
- Fts3MultiSegReader *pCsr /* Cursor object */
-){
- if( pCsr ){
- int i;
- for(i=0; i<pCsr->nSegment; i++){
- sqlite3Fts3SegReaderFree(pCsr->apSegment[i]);
- }
- sqlite3_free(pCsr->apSegment);
- sqlite3_free(pCsr->aBuffer);
-
- pCsr->nSegment = 0;
- pCsr->apSegment = 0;
- pCsr->aBuffer = 0;
- }
-}
-
-/*
-** Merge all level iLevel segments in the database into a single
-** iLevel+1 segment. Or, if iLevel<0, merge all segments into a
-** single segment with a level equal to the numerically largest level
-** currently present in the database.
-**
-** If this function is called with iLevel<0, but there is only one
-** segment in the database, SQLITE_DONE is returned immediately.
-** Otherwise, if successful, SQLITE_OK is returned. If an error occurs,
-** an SQLite error code is returned.
-*/
-static int fts3SegmentMerge(
- Fts3Table *p,
- int iLangid, /* Language id to merge */
- int iIndex, /* Index in p->aIndex[] to merge */
- int iLevel /* Level to merge */
-){
- int rc; /* Return code */
- int iIdx = 0; /* Index of new segment */
- sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */
- SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */
- Fts3SegFilter filter; /* Segment term filter condition */
- Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */
- int bIgnoreEmpty = 0; /* True to ignore empty segments */
-
- assert( iLevel==FTS3_SEGCURSOR_ALL
- || iLevel==FTS3_SEGCURSOR_PENDING
- || iLevel>=0
- );
- assert( iLevel<FTS3_SEGDIR_MAXLEVEL );
- assert( iIndex>=0 && iIndex<p->nIndex );
-
- rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr);
- if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished;
-
- if( iLevel==FTS3_SEGCURSOR_ALL ){
- /* This call is to merge all segments in the database to a single
- ** segment. The level of the new segment is equal to the numerically
- ** greatest segment level currently present in the database for this
- ** index. The idx of the new segment is always 0. */
- if( csr.nSegment==1 ){
- rc = SQLITE_DONE;
- goto finished;
- }
- rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iNewLevel);
- bIgnoreEmpty = 1;
-
- }else if( iLevel==FTS3_SEGCURSOR_PENDING ){
- iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, 0);
- rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, 0, &iIdx);
- }else{
- /* This call is to merge all segments at level iLevel. find the next
- ** available segment index at level iLevel+1. The call to
- ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to
- ** a single iLevel+2 segment if necessary. */
- rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx);
- iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1);
- }
- if( rc!=SQLITE_OK ) goto finished;
- assert( csr.nSegment>0 );
- assert( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) );
- assert( iNewLevel<getAbsoluteLevel(p, iLangid, iIndex,FTS3_SEGDIR_MAXLEVEL) );
-
- memset(&filter, 0, sizeof(Fts3SegFilter));
- filter.flags = FTS3_SEGMENT_REQUIRE_POS;
- filter.flags |= (bIgnoreEmpty ? FTS3_SEGMENT_IGNORE_EMPTY : 0);
-
- rc = sqlite3Fts3SegReaderStart(p, &csr, &filter);
- while( SQLITE_OK==rc ){
- rc = sqlite3Fts3SegReaderStep(p, &csr);
- if( rc!=SQLITE_ROW ) break;
- rc = fts3SegWriterAdd(p, &pWriter, 1,
- csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist);
- }
- if( rc!=SQLITE_OK ) goto finished;
- assert( pWriter );
-
- if( iLevel!=FTS3_SEGCURSOR_PENDING ){
- rc = fts3DeleteSegdir(
- p, iLangid, iIndex, iLevel, csr.apSegment, csr.nSegment
- );
- if( rc!=SQLITE_OK ) goto finished;
- }
- rc = fts3SegWriterFlush(p, pWriter, iNewLevel, iIdx);
-
- finished:
- fts3SegWriterFree(pWriter);
- sqlite3Fts3SegReaderFinish(&csr);
- return rc;
-}
-
-
-/*
-** Flush the contents of pendingTerms to level 0 segments.
-*/
-SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){
- int rc = SQLITE_OK;
- int i;
-
- for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){
- rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING);
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
- }
- sqlite3Fts3PendingTermsClear(p);
-
- /* Determine the auto-incr-merge setting if unknown. If enabled,
- ** estimate the number of leaf blocks of content to be written
- */
- if( rc==SQLITE_OK && p->bHasStat
- && p->bAutoincrmerge==0xff && p->nLeafAdd>0
- ){
- sqlite3_stmt *pStmt = 0;
- rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE);
- rc = sqlite3_step(pStmt);
- p->bAutoincrmerge = (rc==SQLITE_ROW && sqlite3_column_int(pStmt, 0));
- rc = sqlite3_reset(pStmt);
- }
- }
- return rc;
-}
-
-/*
-** Encode N integers as varints into a blob.
-*/
-static void fts3EncodeIntArray(
- int N, /* The number of integers to encode */
- u32 *a, /* The integer values */
- char *zBuf, /* Write the BLOB here */
- int *pNBuf /* Write number of bytes if zBuf[] used here */
-){
- int i, j;
- for(i=j=0; i<N; i++){
- j += sqlite3Fts3PutVarint(&zBuf[j], (sqlite3_int64)a[i]);
- }
- *pNBuf = j;
-}
-
-/*
-** Decode a blob of varints into N integers
-*/
-static void fts3DecodeIntArray(
- int N, /* The number of integers to decode */
- u32 *a, /* Write the integer values */
- const char *zBuf, /* The BLOB containing the varints */
- int nBuf /* size of the BLOB */
-){
- int i, j;
- UNUSED_PARAMETER(nBuf);
- for(i=j=0; i<N; i++){
- sqlite3_int64 x;
- j += sqlite3Fts3GetVarint(&zBuf[j], &x);
- assert(j<=nBuf);
- a[i] = (u32)(x & 0xffffffff);
- }
-}
-
-/*
-** Insert the sizes (in tokens) for each column of the document
-** with docid equal to p->iPrevDocid. The sizes are encoded as
-** a blob of varints.
-*/
-static void fts3InsertDocsize(
- int *pRC, /* Result code */
- Fts3Table *p, /* Table into which to insert */
- u32 *aSz /* Sizes of each column, in tokens */
-){
- char *pBlob; /* The BLOB encoding of the document size */
- int nBlob; /* Number of bytes in the BLOB */
- sqlite3_stmt *pStmt; /* Statement used to insert the encoding */
- int rc; /* Result code from subfunctions */
-
- if( *pRC ) return;
- pBlob = sqlite3_malloc( 10*p->nColumn );
- if( pBlob==0 ){
- *pRC = SQLITE_NOMEM;
- return;
- }
- fts3EncodeIntArray(p->nColumn, aSz, pBlob, &nBlob);
- rc = fts3SqlStmt(p, SQL_REPLACE_DOCSIZE, &pStmt, 0);
- if( rc ){
- sqlite3_free(pBlob);
- *pRC = rc;
- return;
- }
- sqlite3_bind_int64(pStmt, 1, p->iPrevDocid);
- sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, sqlite3_free);
- sqlite3_step(pStmt);
- *pRC = sqlite3_reset(pStmt);
-}
-
-/*
-** Record 0 of the %_stat table contains a blob consisting of N varints,
-** where N is the number of user defined columns in the fts3 table plus
-** two. If nCol is the number of user defined columns, then values of the
-** varints are set as follows:
-**
-** Varint 0: Total number of rows in the table.
-**
-** Varint 1..nCol: For each column, the total number of tokens stored in
-** the column for all rows of the table.
-**
-** Varint 1+nCol: The total size, in bytes, of all text values in all
-** columns of all rows of the table.
-**
-*/
-static void fts3UpdateDocTotals(
- int *pRC, /* The result code */
- Fts3Table *p, /* Table being updated */
- u32 *aSzIns, /* Size increases */
- u32 *aSzDel, /* Size decreases */
- int nChng /* Change in the number of documents */
-){
- char *pBlob; /* Storage for BLOB written into %_stat */
- int nBlob; /* Size of BLOB written into %_stat */
- u32 *a; /* Array of integers that becomes the BLOB */
- sqlite3_stmt *pStmt; /* Statement for reading and writing */
- int i; /* Loop counter */
- int rc; /* Result code from subfunctions */
-
- const int nStat = p->nColumn+2;
-
- if( *pRC ) return;
- a = sqlite3_malloc( (sizeof(u32)+10)*nStat );
- if( a==0 ){
- *pRC = SQLITE_NOMEM;
- return;
- }
- pBlob = (char*)&a[nStat];
- rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0);
- if( rc ){
- sqlite3_free(a);
- *pRC = rc;
- return;
- }
- sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL);
- if( sqlite3_step(pStmt)==SQLITE_ROW ){
- fts3DecodeIntArray(nStat, a,
- sqlite3_column_blob(pStmt, 0),
- sqlite3_column_bytes(pStmt, 0));
- }else{
- memset(a, 0, sizeof(u32)*(nStat) );
- }
- rc = sqlite3_reset(pStmt);
- if( rc!=SQLITE_OK ){
- sqlite3_free(a);
- *pRC = rc;
- return;
- }
- if( nChng<0 && a[0]<(u32)(-nChng) ){
- a[0] = 0;
- }else{
- a[0] += nChng;
- }
- for(i=0; i<p->nColumn+1; i++){
- u32 x = a[i+1];
- if( x+aSzIns[i] < aSzDel[i] ){
- x = 0;
- }else{
- x = x + aSzIns[i] - aSzDel[i];
- }
- a[i+1] = x;
- }
- fts3EncodeIntArray(nStat, a, pBlob, &nBlob);
- rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0);
- if( rc ){
- sqlite3_free(a);
- *pRC = rc;
- return;
- }
- sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL);
- sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC);
- sqlite3_step(pStmt);
- *pRC = sqlite3_reset(pStmt);
- sqlite3_free(a);
-}
-
-/*
-** Merge the entire database so that there is one segment for each
-** iIndex/iLangid combination.
-*/
-static int fts3DoOptimize(Fts3Table *p, int bReturnDone){
- int bSeenDone = 0;
- int rc;
- sqlite3_stmt *pAllLangid = 0;
-
- rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
- if( rc==SQLITE_OK ){
- int rc2;
- sqlite3_bind_int(pAllLangid, 1, p->nIndex);
- while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
- int i;
- int iLangid = sqlite3_column_int(pAllLangid, 0);
- for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){
- rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL);
- if( rc==SQLITE_DONE ){
- bSeenDone = 1;
- rc = SQLITE_OK;
- }
- }
- }
- rc2 = sqlite3_reset(pAllLangid);
- if( rc==SQLITE_OK ) rc = rc2;
- }
-
- sqlite3Fts3SegmentsClose(p);
- sqlite3Fts3PendingTermsClear(p);
-
- return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc;
-}
-
-/*
-** This function is called when the user executes the following statement:
-**
-** INSERT INTO <tbl>(<tbl>) VALUES('rebuild');
-**
-** The entire FTS index is discarded and rebuilt. If the table is one
-** created using the content=xxx option, then the new index is based on
-** the current contents of the xxx table. Otherwise, it is rebuilt based
-** on the contents of the %_content table.
-*/
-static int fts3DoRebuild(Fts3Table *p){
- int rc; /* Return Code */
-
- rc = fts3DeleteAll(p, 0);
- if( rc==SQLITE_OK ){
- u32 *aSz = 0;
- u32 *aSzIns = 0;
- u32 *aSzDel = 0;
- sqlite3_stmt *pStmt = 0;
- int nEntry = 0;
-
- /* Compose and prepare an SQL statement to loop through the content table */
- char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
- if( !zSql ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- }
-
- if( rc==SQLITE_OK ){
- int nByte = sizeof(u32) * (p->nColumn+1)*3;
- aSz = (u32 *)sqlite3_malloc(nByte);
- if( aSz==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memset(aSz, 0, nByte);
- aSzIns = &aSz[p->nColumn+1];
- aSzDel = &aSzIns[p->nColumn+1];
- }
- }
-
- while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
- int iCol;
- int iLangid = langidFromSelect(p, pStmt);
- rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
- memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
- for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
- const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
- rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
- aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
- }
- if( p->bHasDocsize ){
- fts3InsertDocsize(&rc, p, aSz);
- }
- if( rc!=SQLITE_OK ){
- sqlite3_finalize(pStmt);
- pStmt = 0;
- }else{
- nEntry++;
- for(iCol=0; iCol<=p->nColumn; iCol++){
- aSzIns[iCol] += aSz[iCol];
- }
- }
- }
- if( p->bFts4 ){
- fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry);
- }
- sqlite3_free(aSz);
-
- if( pStmt ){
- int rc2 = sqlite3_finalize(pStmt);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
-
- return rc;
-}
-
-
-/*
-** This function opens a cursor used to read the input data for an
-** incremental merge operation. Specifically, it opens a cursor to scan
-** the oldest nSeg segments (idx=0 through idx=(nSeg-1)) in absolute
-** level iAbsLevel.
-*/
-static int fts3IncrmergeCsr(
- Fts3Table *p, /* FTS3 table handle */
- sqlite3_int64 iAbsLevel, /* Absolute level to open */
- int nSeg, /* Number of segments to merge */
- Fts3MultiSegReader *pCsr /* Cursor object to populate */
-){
- int rc; /* Return Code */
- sqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */
- int nByte; /* Bytes allocated at pCsr->apSegment[] */
-
- /* Allocate space for the Fts3MultiSegReader.aCsr[] array */
- memset(pCsr, 0, sizeof(*pCsr));
- nByte = sizeof(Fts3SegReader *) * nSeg;
- pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc(nByte);
-
- if( pCsr->apSegment==0 ){
- rc = SQLITE_NOMEM;
- }else{
- memset(pCsr->apSegment, 0, nByte);
- rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0);
- }
- if( rc==SQLITE_OK ){
- int i;
- int rc2;
- sqlite3_bind_int64(pStmt, 1, iAbsLevel);
- assert( pCsr->nSegment==0 );
- for(i=0; rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW && i<nSeg; i++){
- rc = sqlite3Fts3SegReaderNew(i, 0,
- sqlite3_column_int64(pStmt, 1), /* segdir.start_block */
- sqlite3_column_int64(pStmt, 2), /* segdir.leaves_end_block */
- sqlite3_column_int64(pStmt, 3), /* segdir.end_block */
- sqlite3_column_blob(pStmt, 4), /* segdir.root */
- sqlite3_column_bytes(pStmt, 4), /* segdir.root */
- &pCsr->apSegment[i]
- );
- pCsr->nSegment++;
- }
- rc2 = sqlite3_reset(pStmt);
- if( rc==SQLITE_OK ) rc = rc2;
- }
-
- return rc;
-}
-
-typedef struct IncrmergeWriter IncrmergeWriter;
-typedef struct NodeWriter NodeWriter;
-typedef struct Blob Blob;
-typedef struct NodeReader NodeReader;
-
-/*
-** An instance of the following structure is used as a dynamic buffer
-** to build up nodes or other blobs of data in.
-**
-** The function blobGrowBuffer() is used to extend the allocation.
-*/
-struct Blob {
- char *a; /* Pointer to allocation */
- int n; /* Number of valid bytes of data in a[] */
- int nAlloc; /* Allocated size of a[] (nAlloc>=n) */
-};
-
-/*
-** This structure is used to build up buffers containing segment b-tree
-** nodes (blocks).
-*/
-struct NodeWriter {
- sqlite3_int64 iBlock; /* Current block id */
- Blob key; /* Last key written to the current block */
- Blob block; /* Current block image */
-};
-
-/*
-** An object of this type contains the state required to create or append
-** to an appendable b-tree segment.
-*/
-struct IncrmergeWriter {
- int nLeafEst; /* Space allocated for leaf blocks */
- int nWork; /* Number of leaf pages flushed */
- sqlite3_int64 iAbsLevel; /* Absolute level of input segments */
- int iIdx; /* Index of *output* segment in iAbsLevel+1 */
- sqlite3_int64 iStart; /* Block number of first allocated block */
- sqlite3_int64 iEnd; /* Block number of last allocated block */
- NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT];
-};
-
-/*
-** An object of the following type is used to read data from a single
-** FTS segment node. See the following functions:
-**
-** nodeReaderInit()
-** nodeReaderNext()
-** nodeReaderRelease()
-*/
-struct NodeReader {
- const char *aNode;
- int nNode;
- int iOff; /* Current offset within aNode[] */
-
- /* Output variables. Containing the current node entry. */
- sqlite3_int64 iChild; /* Pointer to child node */
- Blob term; /* Current term */
- const char *aDoclist; /* Pointer to doclist */
- int nDoclist; /* Size of doclist in bytes */
-};
-
-/*
-** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
-** Otherwise, if the allocation at pBlob->a is not already at least nMin
-** bytes in size, extend (realloc) it to be so.
-**
-** If an OOM error occurs, set *pRc to SQLITE_NOMEM and leave pBlob->a
-** unmodified. Otherwise, if the allocation succeeds, update pBlob->nAlloc
-** to reflect the new size of the pBlob->a[] buffer.
-*/
-static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){
- if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){
- int nAlloc = nMin;
- char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc);
- if( a ){
- pBlob->nAlloc = nAlloc;
- pBlob->a = a;
- }else{
- *pRc = SQLITE_NOMEM;
- }
- }
-}
-
-/*
-** Attempt to advance the node-reader object passed as the first argument to
-** the next entry on the node.
-**
-** Return an error code if an error occurs (SQLITE_NOMEM is possible).
-** Otherwise return SQLITE_OK. If there is no next entry on the node
-** (e.g. because the current entry is the last) set NodeReader->aNode to
-** NULL to indicate EOF. Otherwise, populate the NodeReader structure output
-** variables for the new entry.
-*/
-static int nodeReaderNext(NodeReader *p){
- int bFirst = (p->term.n==0); /* True for first term on the node */
- int nPrefix = 0; /* Bytes to copy from previous term */
- int nSuffix = 0; /* Bytes to append to the prefix */
- int rc = SQLITE_OK; /* Return code */
-
- assert( p->aNode );
- if( p->iChild && bFirst==0 ) p->iChild++;
- if( p->iOff>=p->nNode ){
- /* EOF */
- p->aNode = 0;
- }else{
- if( bFirst==0 ){
- p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
- }
- p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
-
- blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
- if( rc==SQLITE_OK ){
- memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
- p->term.n = nPrefix+nSuffix;
- p->iOff += nSuffix;
- if( p->iChild==0 ){
- p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
- p->aDoclist = &p->aNode[p->iOff];
- p->iOff += p->nDoclist;
- }
- }
- }
-
- assert( p->iOff<=p->nNode );
-
- return rc;
-}
-
-/*
-** Release all dynamic resources held by node-reader object *p.
-*/
-static void nodeReaderRelease(NodeReader *p){
- sqlite3_free(p->term.a);
-}
-
-/*
-** Initialize a node-reader object to read the node in buffer aNode/nNode.
-**
-** If successful, SQLITE_OK is returned and the NodeReader object set to
-** point to the first entry on the node (if any). Otherwise, an SQLite
-** error code is returned.
-*/
-static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){
- memset(p, 0, sizeof(NodeReader));
- p->aNode = aNode;
- p->nNode = nNode;
-
- /* Figure out if this is a leaf or an internal node. */
- if( p->aNode[0] ){
- /* An internal node. */
- p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild);
- }else{
- p->iOff = 1;
- }
-
- return nodeReaderNext(p);
-}
-
-/*
-** This function is called while writing an FTS segment each time a leaf o
-** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed
-** to be greater than the largest key on the node just written, but smaller
-** than or equal to the first key that will be written to the next leaf
-** node.
-**
-** The block id of the leaf node just written to disk may be found in
-** (pWriter->aNodeWriter[0].iBlock) when this function is called.
-*/
-static int fts3IncrmergePush(
- Fts3Table *p, /* Fts3 table handle */
- IncrmergeWriter *pWriter, /* Writer object */
- const char *zTerm, /* Term to write to internal node */
- int nTerm /* Bytes at zTerm */
-){
- sqlite3_int64 iPtr = pWriter->aNodeWriter[0].iBlock;
- int iLayer;
-
- assert( nTerm>0 );
- for(iLayer=1; ALWAYS(iLayer<FTS_MAX_APPENDABLE_HEIGHT); iLayer++){
- sqlite3_int64 iNextPtr = 0;
- NodeWriter *pNode = &pWriter->aNodeWriter[iLayer];
- int rc = SQLITE_OK;
- int nPrefix;
- int nSuffix;
- int nSpace;
-
- /* Figure out how much space the key will consume if it is written to
- ** the current node of layer iLayer. Due to the prefix compression,
- ** the space required changes depending on which node the key is to
- ** be added to. */
- nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm);
- nSuffix = nTerm - nPrefix;
- nSpace = sqlite3Fts3VarintLen(nPrefix);
- nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
-
- if( pNode->key.n==0 || (pNode->block.n + nSpace)<=p->nNodeSize ){
- /* If the current node of layer iLayer contains zero keys, or if adding
- ** the key to it will not cause it to grow to larger than nNodeSize
- ** bytes in size, write the key here. */
-
- Blob *pBlk = &pNode->block;
- if( pBlk->n==0 ){
- blobGrowBuffer(pBlk, p->nNodeSize, &rc);
- if( rc==SQLITE_OK ){
- pBlk->a[0] = (char)iLayer;
- pBlk->n = 1 + sqlite3Fts3PutVarint(&pBlk->a[1], iPtr);
- }
- }
- blobGrowBuffer(pBlk, pBlk->n + nSpace, &rc);
- blobGrowBuffer(&pNode->key, nTerm, &rc);
-
- if( rc==SQLITE_OK ){
- if( pNode->key.n ){
- pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix);
- }
- pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix);
- memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix);
- pBlk->n += nSuffix;
-
- memcpy(pNode->key.a, zTerm, nTerm);
- pNode->key.n = nTerm;
- }
- }else{
- /* Otherwise, flush the current node of layer iLayer to disk.
- ** Then allocate a new, empty sibling node. The key will be written
- ** into the parent of this node. */
- rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n);
-
- assert( pNode->block.nAlloc>=p->nNodeSize );
- pNode->block.a[0] = (char)iLayer;
- pNode->block.n = 1 + sqlite3Fts3PutVarint(&pNode->block.a[1], iPtr+1);
-
- iNextPtr = pNode->iBlock;
- pNode->iBlock++;
- pNode->key.n = 0;
- }
-
- if( rc!=SQLITE_OK || iNextPtr==0 ) return rc;
- iPtr = iNextPtr;
- }
-
- assert( 0 );
- return 0;
-}
-
-/*
-** Append a term and (optionally) doclist to the FTS segment node currently
-** stored in blob *pNode. The node need not contain any terms, but the
-** header must be written before this function is called.
-**
-** A node header is a single 0x00 byte for a leaf node, or a height varint
-** followed by the left-hand-child varint for an internal node.
-**
-** The term to be appended is passed via arguments zTerm/nTerm. For a
-** leaf node, the doclist is passed as aDoclist/nDoclist. For an internal
-** node, both aDoclist and nDoclist must be passed 0.
-**
-** If the size of the value in blob pPrev is zero, then this is the first
-** term written to the node. Otherwise, pPrev contains a copy of the
-** previous term. Before this function returns, it is updated to contain a
-** copy of zTerm/nTerm.
-**
-** It is assumed that the buffer associated with pNode is already large
-** enough to accommodate the new entry. The buffer associated with pPrev
-** is extended by this function if requrired.
-**
-** If an error (i.e. OOM condition) occurs, an SQLite error code is
-** returned. Otherwise, SQLITE_OK.
-*/
-static int fts3AppendToNode(
- Blob *pNode, /* Current node image to append to */
- Blob *pPrev, /* Buffer containing previous term written */
- const char *zTerm, /* New term to write */
- int nTerm, /* Size of zTerm in bytes */
- const char *aDoclist, /* Doclist (or NULL) to write */
- int nDoclist /* Size of aDoclist in bytes */
-){
- int rc = SQLITE_OK; /* Return code */
- int bFirst = (pPrev->n==0); /* True if this is the first term written */
- int nPrefix; /* Size of term prefix in bytes */
- int nSuffix; /* Size of term suffix in bytes */
-
- /* Node must have already been started. There must be a doclist for a
- ** leaf node, and there must not be a doclist for an internal node. */
- assert( pNode->n>0 );
- assert( (pNode->a[0]=='\0')==(aDoclist!=0) );
-
- blobGrowBuffer(pPrev, nTerm, &rc);
- if( rc!=SQLITE_OK ) return rc;
-
- nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm);
- nSuffix = nTerm - nPrefix;
- memcpy(pPrev->a, zTerm, nTerm);
- pPrev->n = nTerm;
-
- if( bFirst==0 ){
- pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix);
- }
- pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix);
- memcpy(&pNode->a[pNode->n], &zTerm[nPrefix], nSuffix);
- pNode->n += nSuffix;
-
- if( aDoclist ){
- pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nDoclist);
- memcpy(&pNode->a[pNode->n], aDoclist, nDoclist);
- pNode->n += nDoclist;
- }
-
- assert( pNode->n<=pNode->nAlloc );
-
- return SQLITE_OK;
-}
-
-/*
-** Append the current term and doclist pointed to by cursor pCsr to the
-** appendable b-tree segment opened for writing by pWriter.
-**
-** Return SQLITE_OK if successful, or an SQLite error code otherwise.
-*/
-static int fts3IncrmergeAppend(
- Fts3Table *p, /* Fts3 table handle */
- IncrmergeWriter *pWriter, /* Writer object */
- Fts3MultiSegReader *pCsr /* Cursor containing term and doclist */
-){
- const char *zTerm = pCsr->zTerm;
- int nTerm = pCsr->nTerm;
- const char *aDoclist = pCsr->aDoclist;
- int nDoclist = pCsr->nDoclist;
- int rc = SQLITE_OK; /* Return code */
- int nSpace; /* Total space in bytes required on leaf */
- int nPrefix; /* Size of prefix shared with previous term */
- int nSuffix; /* Size of suffix (nTerm - nPrefix) */
- NodeWriter *pLeaf; /* Object used to write leaf nodes */
-
- pLeaf = &pWriter->aNodeWriter[0];
- nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm);
- nSuffix = nTerm - nPrefix;
-
- nSpace = sqlite3Fts3VarintLen(nPrefix);
- nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
- nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist;
-
- /* If the current block is not empty, and if adding this term/doclist
- ** to the current block would make it larger than Fts3Table.nNodeSize
- ** bytes, write this block out to the database. */
- if( pLeaf->block.n>0 && (pLeaf->block.n + nSpace)>p->nNodeSize ){
- rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n);
- pWriter->nWork++;
-
- /* Add the current term to the parent node. The term added to the
- ** parent must:
- **
- ** a) be greater than the largest term on the leaf node just written
- ** to the database (still available in pLeaf->key), and
- **
- ** b) be less than or equal to the term about to be added to the new
- ** leaf node (zTerm/nTerm).
- **
- ** In other words, it must be the prefix of zTerm 1 byte longer than
- ** the common prefix (if any) of zTerm and pWriter->zTerm.
- */
- if( rc==SQLITE_OK ){
- rc = fts3IncrmergePush(p, pWriter, zTerm, nPrefix+1);
- }
-
- /* Advance to the next output block */
- pLeaf->iBlock++;
- pLeaf->key.n = 0;
- pLeaf->block.n = 0;
-
- nSuffix = nTerm;
- nSpace = 1;
- nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
- nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist;
- }
-
- blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc);
-
- if( rc==SQLITE_OK ){
- if( pLeaf->block.n==0 ){
- pLeaf->block.n = 1;
- pLeaf->block.a[0] = '\0';
- }
- rc = fts3AppendToNode(
- &pLeaf->block, &pLeaf->key, zTerm, nTerm, aDoclist, nDoclist
- );
- }
-
- return rc;
-}
-
-/*
-** This function is called to release all dynamic resources held by the
-** merge-writer object pWriter, and if no error has occurred, to flush
-** all outstanding node buffers held by pWriter to disk.
-**
-** If *pRc is not SQLITE_OK when this function is called, then no attempt
-** is made to write any data to disk. Instead, this function serves only
-** to release outstanding resources.
-**
-** Otherwise, if *pRc is initially SQLITE_OK and an error occurs while
-** flushing buffers to disk, *pRc is set to an SQLite error code before
-** returning.
-*/
-static void fts3IncrmergeRelease(
- Fts3Table *p, /* FTS3 table handle */
- IncrmergeWriter *pWriter, /* Merge-writer object */
- int *pRc /* IN/OUT: Error code */
-){
- int i; /* Used to iterate through non-root layers */
- int iRoot; /* Index of root in pWriter->aNodeWriter */
- NodeWriter *pRoot; /* NodeWriter for root node */
- int rc = *pRc; /* Error code */
-
- /* Set iRoot to the index in pWriter->aNodeWriter[] of the output segment
- ** root node. If the segment fits entirely on a single leaf node, iRoot
- ** will be set to 0. If the root node is the parent of the leaves, iRoot
- ** will be 1. And so on. */
- for(iRoot=FTS_MAX_APPENDABLE_HEIGHT-1; iRoot>=0; iRoot--){
- NodeWriter *pNode = &pWriter->aNodeWriter[iRoot];
- if( pNode->block.n>0 ) break;
- assert( *pRc || pNode->block.nAlloc==0 );
- assert( *pRc || pNode->key.nAlloc==0 );
- sqlite3_free(pNode->block.a);
- sqlite3_free(pNode->key.a);
- }
-
- /* Empty output segment. This is a no-op. */
- if( iRoot<0 ) return;
-
- /* The entire output segment fits on a single node. Normally, this means
- ** the node would be stored as a blob in the "root" column of the %_segdir
- ** table. However, this is not permitted in this case. The problem is that
- ** space has already been reserved in the %_segments table, and so the
- ** start_block and end_block fields of the %_segdir table must be populated.
- ** And, by design or by accident, released versions of FTS cannot handle
- ** segments that fit entirely on the root node with start_block!=0.
- **
- ** Instead, create a synthetic root node that contains nothing but a
- ** pointer to the single content node. So that the segment consists of a
- ** single leaf and a single interior (root) node.
- **
- ** Todo: Better might be to defer allocating space in the %_segments
- ** table until we are sure it is needed.
- */
- if( iRoot==0 ){
- Blob *pBlock = &pWriter->aNodeWriter[1].block;
- blobGrowBuffer(pBlock, 1 + FTS3_VARINT_MAX, &rc);
- if( rc==SQLITE_OK ){
- pBlock->a[0] = 0x01;
- pBlock->n = 1 + sqlite3Fts3PutVarint(
- &pBlock->a[1], pWriter->aNodeWriter[0].iBlock
- );
- }
- iRoot = 1;
- }
- pRoot = &pWriter->aNodeWriter[iRoot];
-
- /* Flush all currently outstanding nodes to disk. */
- for(i=0; i<iRoot; i++){
- NodeWriter *pNode = &pWriter->aNodeWriter[i];
- if( pNode->block.n>0 && rc==SQLITE_OK ){
- rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n);
- }
- sqlite3_free(pNode->block.a);
- sqlite3_free(pNode->key.a);
- }
-
- /* Write the %_segdir record. */
- if( rc==SQLITE_OK ){
- rc = fts3WriteSegdir(p,
- pWriter->iAbsLevel+1, /* level */
- pWriter->iIdx, /* idx */
- pWriter->iStart, /* start_block */
- pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */
- pWriter->iEnd, /* end_block */
- pRoot->block.a, pRoot->block.n /* root */
- );
- }
- sqlite3_free(pRoot->block.a);
- sqlite3_free(pRoot->key.a);
-
- *pRc = rc;
-}
-
-/*
-** Compare the term in buffer zLhs (size in bytes nLhs) with that in
-** zRhs (size in bytes nRhs) using memcmp. If one term is a prefix of
-** the other, it is considered to be smaller than the other.
-**
-** Return -ve if zLhs is smaller than zRhs, 0 if it is equal, or +ve
-** if it is greater.
-*/
-static int fts3TermCmp(
- const char *zLhs, int nLhs, /* LHS of comparison */
- const char *zRhs, int nRhs /* RHS of comparison */
-){
- int nCmp = MIN(nLhs, nRhs);
- int res;
-
- res = memcmp(zLhs, zRhs, nCmp);
- if( res==0 ) res = nLhs - nRhs;
-
- return res;
-}
-
-
-/*
-** Query to see if the entry in the %_segments table with blockid iEnd is
-** NULL. If no error occurs and the entry is NULL, set *pbRes 1 before
-** returning. Otherwise, set *pbRes to 0.
-**
-** Or, if an error occurs while querying the database, return an SQLite
-** error code. The final value of *pbRes is undefined in this case.
-**
-** This is used to test if a segment is an "appendable" segment. If it
-** is, then a NULL entry has been inserted into the %_segments table
-** with blockid %_segdir.end_block.
-*/
-static int fts3IsAppendable(Fts3Table *p, sqlite3_int64 iEnd, int *pbRes){
- int bRes = 0; /* Result to set *pbRes to */
- sqlite3_stmt *pCheck = 0; /* Statement to query database with */
- int rc; /* Return code */
-
- rc = fts3SqlStmt(p, SQL_SEGMENT_IS_APPENDABLE, &pCheck, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pCheck, 1, iEnd);
- if( SQLITE_ROW==sqlite3_step(pCheck) ) bRes = 1;
- rc = sqlite3_reset(pCheck);
- }
-
- *pbRes = bRes;
- return rc;
-}
-
-/*
-** This function is called when initializing an incremental-merge operation.
-** It checks if the existing segment with index value iIdx at absolute level
-** (iAbsLevel+1) can be appended to by the incremental merge. If it can, the
-** merge-writer object *pWriter is initialized to write to it.
-**
-** An existing segment can be appended to by an incremental merge if:
-**
-** * It was initially created as an appendable segment (with all required
-** space pre-allocated), and
-**
-** * The first key read from the input (arguments zKey and nKey) is
-** greater than the largest key currently stored in the potential
-** output segment.
-*/
-static int fts3IncrmergeLoad(
- Fts3Table *p, /* Fts3 table handle */
- sqlite3_int64 iAbsLevel, /* Absolute level of input segments */
- int iIdx, /* Index of candidate output segment */
- const char *zKey, /* First key to write */
- int nKey, /* Number of bytes in nKey */
- IncrmergeWriter *pWriter /* Populate this object */
-){
- int rc; /* Return code */
- sqlite3_stmt *pSelect = 0; /* SELECT to read %_segdir entry */
-
- rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pSelect, 0);
- if( rc==SQLITE_OK ){
- sqlite3_int64 iStart = 0; /* Value of %_segdir.start_block */
- sqlite3_int64 iLeafEnd = 0; /* Value of %_segdir.leaves_end_block */
- sqlite3_int64 iEnd = 0; /* Value of %_segdir.end_block */
- const char *aRoot = 0; /* Pointer to %_segdir.root buffer */
- int nRoot = 0; /* Size of aRoot[] in bytes */
- int rc2; /* Return code from sqlite3_reset() */
- int bAppendable = 0; /* Set to true if segment is appendable */
-
- /* Read the %_segdir entry for index iIdx absolute level (iAbsLevel+1) */
- sqlite3_bind_int64(pSelect, 1, iAbsLevel+1);
- sqlite3_bind_int(pSelect, 2, iIdx);
- if( sqlite3_step(pSelect)==SQLITE_ROW ){
- iStart = sqlite3_column_int64(pSelect, 1);
- iLeafEnd = sqlite3_column_int64(pSelect, 2);
- iEnd = sqlite3_column_int64(pSelect, 3);
- nRoot = sqlite3_column_bytes(pSelect, 4);
- aRoot = sqlite3_column_blob(pSelect, 4);
- }else{
- return sqlite3_reset(pSelect);
- }
-
- /* Check for the zero-length marker in the %_segments table */
- rc = fts3IsAppendable(p, iEnd, &bAppendable);
-
- /* Check that zKey/nKey is larger than the largest key the candidate */
- if( rc==SQLITE_OK && bAppendable ){
- char *aLeaf = 0;
- int nLeaf = 0;
-
- rc = sqlite3Fts3ReadBlock(p, iLeafEnd, &aLeaf, &nLeaf, 0);
- if( rc==SQLITE_OK ){
- NodeReader reader;
- for(rc = nodeReaderInit(&reader, aLeaf, nLeaf);
- rc==SQLITE_OK && reader.aNode;
- rc = nodeReaderNext(&reader)
- ){
- assert( reader.aNode );
- }
- if( fts3TermCmp(zKey, nKey, reader.term.a, reader.term.n)<=0 ){
- bAppendable = 0;
- }
- nodeReaderRelease(&reader);
- }
- sqlite3_free(aLeaf);
- }
-
- if( rc==SQLITE_OK && bAppendable ){
- /* It is possible to append to this segment. Set up the IncrmergeWriter
- ** object to do so. */
- int i;
- int nHeight = (int)aRoot[0];
- NodeWriter *pNode;
-
- pWriter->nLeafEst = (int)((iEnd - iStart) + 1)/FTS_MAX_APPENDABLE_HEIGHT;
- pWriter->iStart = iStart;
- pWriter->iEnd = iEnd;
- pWriter->iAbsLevel = iAbsLevel;
- pWriter->iIdx = iIdx;
-
- for(i=nHeight+1; i<FTS_MAX_APPENDABLE_HEIGHT; i++){
- pWriter->aNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst;
- }
-
- pNode = &pWriter->aNodeWriter[nHeight];
- pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight;
- blobGrowBuffer(&pNode->block, MAX(nRoot, p->nNodeSize), &rc);
- if( rc==SQLITE_OK ){
- memcpy(pNode->block.a, aRoot, nRoot);
- pNode->block.n = nRoot;
- }
-
- for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
- NodeReader reader;
- pNode = &pWriter->aNodeWriter[i];
-
- rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
- while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
- blobGrowBuffer(&pNode->key, reader.term.n, &rc);
- if( rc==SQLITE_OK ){
- memcpy(pNode->key.a, reader.term.a, reader.term.n);
- pNode->key.n = reader.term.n;
- if( i>0 ){
- char *aBlock = 0;
- int nBlock = 0;
- pNode = &pWriter->aNodeWriter[i-1];
- pNode->iBlock = reader.iChild;
- rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0);
- blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize), &rc);
- if( rc==SQLITE_OK ){
- memcpy(pNode->block.a, aBlock, nBlock);
- pNode->block.n = nBlock;
- }
- sqlite3_free(aBlock);
- }
- }
- nodeReaderRelease(&reader);
- }
- }
-
- rc2 = sqlite3_reset(pSelect);
- if( rc==SQLITE_OK ) rc = rc2;
- }
-
- return rc;
-}
-
-/*
-** Determine the largest segment index value that exists within absolute
-** level iAbsLevel+1. If no error occurs, set *piIdx to this value plus
-** one before returning SQLITE_OK. Or, if there are no segments at all
-** within level iAbsLevel, set *piIdx to zero.
-**
-** If an error occurs, return an SQLite error code. The final value of
-** *piIdx is undefined in this case.
-*/
-static int fts3IncrmergeOutputIdx(
- Fts3Table *p, /* FTS Table handle */
- sqlite3_int64 iAbsLevel, /* Absolute index of input segments */
- int *piIdx /* OUT: Next free index at iAbsLevel+1 */
-){
- int rc;
- sqlite3_stmt *pOutputIdx = 0; /* SQL used to find output index */
-
- rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pOutputIdx, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pOutputIdx, 1, iAbsLevel+1);
- sqlite3_step(pOutputIdx);
- *piIdx = sqlite3_column_int(pOutputIdx, 0);
- rc = sqlite3_reset(pOutputIdx);
- }
-
- return rc;
-}
-
-/*
-** Allocate an appendable output segment on absolute level iAbsLevel+1
-** with idx value iIdx.
-**
-** In the %_segdir table, a segment is defined by the values in three
-** columns:
-**
-** start_block
-** leaves_end_block
-** end_block
-**
-** When an appendable segment is allocated, it is estimated that the
-** maximum number of leaf blocks that may be required is the sum of the
-** number of leaf blocks consumed by the input segments, plus the number
-** of input segments, multiplied by two. This value is stored in stack
-** variable nLeafEst.
-**
-** A total of 16*nLeafEst blocks are allocated when an appendable segment
-** is created ((1 + end_block - start_block)==16*nLeafEst). The contiguous
-** array of leaf nodes starts at the first block allocated. The array
-** of interior nodes that are parents of the leaf nodes start at block
-** (start_block + (1 + end_block - start_block) / 16). And so on.
-**
-** In the actual code below, the value "16" is replaced with the
-** pre-processor macro FTS_MAX_APPENDABLE_HEIGHT.
-*/
-static int fts3IncrmergeWriter(
- Fts3Table *p, /* Fts3 table handle */
- sqlite3_int64 iAbsLevel, /* Absolute level of input segments */
- int iIdx, /* Index of new output segment */
- Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */
- IncrmergeWriter *pWriter /* Populate this object */
-){
- int rc; /* Return Code */
- int i; /* Iterator variable */
- int nLeafEst = 0; /* Blocks allocated for leaf nodes */
- sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */
- sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */
-
- /* Calculate nLeafEst. */
- rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pLeafEst, 1, iAbsLevel);
- sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment);
- if( SQLITE_ROW==sqlite3_step(pLeafEst) ){
- nLeafEst = sqlite3_column_int(pLeafEst, 0);
- }
- rc = sqlite3_reset(pLeafEst);
- }
- if( rc!=SQLITE_OK ) return rc;
-
- /* Calculate the first block to use in the output segment */
- rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pFirstBlock, 0);
- if( rc==SQLITE_OK ){
- if( SQLITE_ROW==sqlite3_step(pFirstBlock) ){
- pWriter->iStart = sqlite3_column_int64(pFirstBlock, 0);
- pWriter->iEnd = pWriter->iStart - 1;
- pWriter->iEnd += nLeafEst * FTS_MAX_APPENDABLE_HEIGHT;
- }
- rc = sqlite3_reset(pFirstBlock);
- }
- if( rc!=SQLITE_OK ) return rc;
-
- /* Insert the marker in the %_segments table to make sure nobody tries
- ** to steal the space just allocated. This is also used to identify
- ** appendable segments. */
- rc = fts3WriteSegment(p, pWriter->iEnd, 0, 0);
- if( rc!=SQLITE_OK ) return rc;
-
- pWriter->iAbsLevel = iAbsLevel;
- pWriter->nLeafEst = nLeafEst;
- pWriter->iIdx = iIdx;
-
- /* Set up the array of NodeWriter objects */
- for(i=0; i<FTS_MAX_APPENDABLE_HEIGHT; i++){
- pWriter->aNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst;
- }
- return SQLITE_OK;
-}
-
-/*
-** Remove an entry from the %_segdir table. This involves running the
-** following two statements:
-**
-** DELETE FROM %_segdir WHERE level = :iAbsLevel AND idx = :iIdx
-** UPDATE %_segdir SET idx = idx - 1 WHERE level = :iAbsLevel AND idx > :iIdx
-**
-** The DELETE statement removes the specific %_segdir level. The UPDATE
-** statement ensures that the remaining segments have contiguously allocated
-** idx values.
-*/
-static int fts3RemoveSegdirEntry(
- Fts3Table *p, /* FTS3 table handle */
- sqlite3_int64 iAbsLevel, /* Absolute level to delete from */
- int iIdx /* Index of %_segdir entry to delete */
-){
- int rc; /* Return code */
- sqlite3_stmt *pDelete = 0; /* DELETE statement */
-
- rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_ENTRY, &pDelete, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pDelete, 1, iAbsLevel);
- sqlite3_bind_int(pDelete, 2, iIdx);
- sqlite3_step(pDelete);
- rc = sqlite3_reset(pDelete);
- }
-
- return rc;
-}
-
-/*
-** One or more segments have just been removed from absolute level iAbsLevel.
-** Update the 'idx' values of the remaining segments in the level so that
-** the idx values are a contiguous sequence starting from 0.
-*/
-static int fts3RepackSegdirLevel(
- Fts3Table *p, /* FTS3 table handle */
- sqlite3_int64 iAbsLevel /* Absolute level to repack */
-){
- int rc; /* Return code */
- int *aIdx = 0; /* Array of remaining idx values */
- int nIdx = 0; /* Valid entries in aIdx[] */
- int nAlloc = 0; /* Allocated size of aIdx[] */
- int i; /* Iterator variable */
- sqlite3_stmt *pSelect = 0; /* Select statement to read idx values */
- sqlite3_stmt *pUpdate = 0; /* Update statement to modify idx values */
-
- rc = fts3SqlStmt(p, SQL_SELECT_INDEXES, &pSelect, 0);
- if( rc==SQLITE_OK ){
- int rc2;
- sqlite3_bind_int64(pSelect, 1, iAbsLevel);
- while( SQLITE_ROW==sqlite3_step(pSelect) ){
- if( nIdx>=nAlloc ){
- int *aNew;
- nAlloc += 16;
- aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int));
- if( !aNew ){
- rc = SQLITE_NOMEM;
- break;
- }
- aIdx = aNew;
- }
- aIdx[nIdx++] = sqlite3_column_int(pSelect, 0);
- }
- rc2 = sqlite3_reset(pSelect);
- if( rc==SQLITE_OK ) rc = rc2;
- }
-
- if( rc==SQLITE_OK ){
- rc = fts3SqlStmt(p, SQL_SHIFT_SEGDIR_ENTRY, &pUpdate, 0);
- }
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pUpdate, 2, iAbsLevel);
- }
-
- assert( p->bIgnoreSavepoint==0 );
- p->bIgnoreSavepoint = 1;
- for(i=0; rc==SQLITE_OK && i<nIdx; i++){
- if( aIdx[i]!=i ){
- sqlite3_bind_int(pUpdate, 3, aIdx[i]);
- sqlite3_bind_int(pUpdate, 1, i);
- sqlite3_step(pUpdate);
- rc = sqlite3_reset(pUpdate);
- }
- }
- p->bIgnoreSavepoint = 0;
-
- sqlite3_free(aIdx);
- return rc;
-}
-
-static void fts3StartNode(Blob *pNode, int iHeight, sqlite3_int64 iChild){
- pNode->a[0] = (char)iHeight;
- if( iChild ){
- assert( pNode->nAlloc>=1+sqlite3Fts3VarintLen(iChild) );
- pNode->n = 1 + sqlite3Fts3PutVarint(&pNode->a[1], iChild);
- }else{
- assert( pNode->nAlloc>=1 );
- pNode->n = 1;
- }
-}
-
-/*
-** The first two arguments are a pointer to and the size of a segment b-tree
-** node. The node may be a leaf or an internal node.
-**
-** This function creates a new node image in blob object *pNew by copying
-** all terms that are greater than or equal to zTerm/nTerm (for leaf nodes)
-** or greater than zTerm/nTerm (for internal nodes) from aNode/nNode.
-*/
-static int fts3TruncateNode(
- const char *aNode, /* Current node image */
- int nNode, /* Size of aNode in bytes */
- Blob *pNew, /* OUT: Write new node image here */
- const char *zTerm, /* Omit all terms smaller than this */
- int nTerm, /* Size of zTerm in bytes */
- sqlite3_int64 *piBlock /* OUT: Block number in next layer down */
-){
- NodeReader reader; /* Reader object */
- Blob prev = {0, 0, 0}; /* Previous term written to new node */
- int rc = SQLITE_OK; /* Return code */
- int bLeaf = aNode[0]=='\0'; /* True for a leaf node */
-
- /* Allocate required output space */
- blobGrowBuffer(pNew, nNode, &rc);
- if( rc!=SQLITE_OK ) return rc;
- pNew->n = 0;
-
- /* Populate new node buffer */
- for(rc = nodeReaderInit(&reader, aNode, nNode);
- rc==SQLITE_OK && reader.aNode;
- rc = nodeReaderNext(&reader)
- ){
- if( pNew->n==0 ){
- int res = fts3TermCmp(reader.term.a, reader.term.n, zTerm, nTerm);
- if( res<0 || (bLeaf==0 && res==0) ) continue;
- fts3StartNode(pNew, (int)aNode[0], reader.iChild);
- *piBlock = reader.iChild;
- }
- rc = fts3AppendToNode(
- pNew, &prev, reader.term.a, reader.term.n,
- reader.aDoclist, reader.nDoclist
- );
- if( rc!=SQLITE_OK ) break;
- }
- if( pNew->n==0 ){
- fts3StartNode(pNew, (int)aNode[0], reader.iChild);
- *piBlock = reader.iChild;
- }
- assert( pNew->n<=pNew->nAlloc );
-
- nodeReaderRelease(&reader);
- sqlite3_free(prev.a);
- return rc;
-}
-
-/*
-** Remove all terms smaller than zTerm/nTerm from segment iIdx in absolute
-** level iAbsLevel. This may involve deleting entries from the %_segments
-** table, and modifying existing entries in both the %_segments and %_segdir
-** tables.
-**
-** SQLITE_OK is returned if the segment is updated successfully. Or an
-** SQLite error code otherwise.
-*/
-static int fts3TruncateSegment(
- Fts3Table *p, /* FTS3 table handle */
- sqlite3_int64 iAbsLevel, /* Absolute level of segment to modify */
- int iIdx, /* Index within level of segment to modify */
- const char *zTerm, /* Remove terms smaller than this */
- int nTerm /* Number of bytes in buffer zTerm */
-){
- int rc = SQLITE_OK; /* Return code */
- Blob root = {0,0,0}; /* New root page image */
- Blob block = {0,0,0}; /* Buffer used for any other block */
- sqlite3_int64 iBlock = 0; /* Block id */
- sqlite3_int64 iNewStart = 0; /* New value for iStartBlock */
- sqlite3_int64 iOldStart = 0; /* Old value for iStartBlock */
- sqlite3_stmt *pFetch = 0; /* Statement used to fetch segdir */
-
- rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pFetch, 0);
- if( rc==SQLITE_OK ){
- int rc2; /* sqlite3_reset() return code */
- sqlite3_bind_int64(pFetch, 1, iAbsLevel);
- sqlite3_bind_int(pFetch, 2, iIdx);
- if( SQLITE_ROW==sqlite3_step(pFetch) ){
- const char *aRoot = sqlite3_column_blob(pFetch, 4);
- int nRoot = sqlite3_column_bytes(pFetch, 4);
- iOldStart = sqlite3_column_int64(pFetch, 1);
- rc = fts3TruncateNode(aRoot, nRoot, &root, zTerm, nTerm, &iBlock);
- }
- rc2 = sqlite3_reset(pFetch);
- if( rc==SQLITE_OK ) rc = rc2;
- }
-
- while( rc==SQLITE_OK && iBlock ){
- char *aBlock = 0;
- int nBlock = 0;
- iNewStart = iBlock;
-
- rc = sqlite3Fts3ReadBlock(p, iBlock, &aBlock, &nBlock, 0);
- if( rc==SQLITE_OK ){
- rc = fts3TruncateNode(aBlock, nBlock, &block, zTerm, nTerm, &iBlock);
- }
- if( rc==SQLITE_OK ){
- rc = fts3WriteSegment(p, iNewStart, block.a, block.n);
- }
- sqlite3_free(aBlock);
- }
-
- /* Variable iNewStart now contains the first valid leaf node. */
- if( rc==SQLITE_OK && iNewStart ){
- sqlite3_stmt *pDel = 0;
- rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDel, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pDel, 1, iOldStart);
- sqlite3_bind_int64(pDel, 2, iNewStart-1);
- sqlite3_step(pDel);
- rc = sqlite3_reset(pDel);
- }
- }
-
- if( rc==SQLITE_OK ){
- sqlite3_stmt *pChomp = 0;
- rc = fts3SqlStmt(p, SQL_CHOMP_SEGDIR, &pChomp, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pChomp, 1, iNewStart);
- sqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC);
- sqlite3_bind_int64(pChomp, 3, iAbsLevel);
- sqlite3_bind_int(pChomp, 4, iIdx);
- sqlite3_step(pChomp);
- rc = sqlite3_reset(pChomp);
- }
- }
-
- sqlite3_free(root.a);
- sqlite3_free(block.a);
- return rc;
-}
-
-/*
-** This function is called after an incrmental-merge operation has run to
-** merge (or partially merge) two or more segments from absolute level
-** iAbsLevel.
-**
-** Each input segment is either removed from the db completely (if all of
-** its data was copied to the output segment by the incrmerge operation)
-** or modified in place so that it no longer contains those entries that
-** have been duplicated in the output segment.
-*/
-static int fts3IncrmergeChomp(
- Fts3Table *p, /* FTS table handle */
- sqlite3_int64 iAbsLevel, /* Absolute level containing segments */
- Fts3MultiSegReader *pCsr, /* Chomp all segments opened by this cursor */
- int *pnRem /* Number of segments not deleted */
-){
- int i;
- int nRem = 0;
- int rc = SQLITE_OK;
-
- for(i=pCsr->nSegment-1; i>=0 && rc==SQLITE_OK; i--){
- Fts3SegReader *pSeg = 0;
- int j;
-
- /* Find the Fts3SegReader object with Fts3SegReader.iIdx==i. It is hiding
- ** somewhere in the pCsr->apSegment[] array. */
- for(j=0; ALWAYS(j<pCsr->nSegment); j++){
- pSeg = pCsr->apSegment[j];
- if( pSeg->iIdx==i ) break;
- }
- assert( j<pCsr->nSegment && pSeg->iIdx==i );
-
- if( pSeg->aNode==0 ){
- /* Seg-reader is at EOF. Remove the entire input segment. */
- rc = fts3DeleteSegment(p, pSeg);
- if( rc==SQLITE_OK ){
- rc = fts3RemoveSegdirEntry(p, iAbsLevel, pSeg->iIdx);
- }
- *pnRem = 0;
- }else{
- /* The incremental merge did not copy all the data from this
- ** segment to the upper level. The segment is modified in place
- ** so that it contains no keys smaller than zTerm/nTerm. */
- const char *zTerm = pSeg->zTerm;
- int nTerm = pSeg->nTerm;
- rc = fts3TruncateSegment(p, iAbsLevel, pSeg->iIdx, zTerm, nTerm);
- nRem++;
- }
- }
-
- if( rc==SQLITE_OK && nRem!=pCsr->nSegment ){
- rc = fts3RepackSegdirLevel(p, iAbsLevel);
- }
-
- *pnRem = nRem;
- return rc;
-}
-
-/*
-** Store an incr-merge hint in the database.
-*/
-static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){
- sqlite3_stmt *pReplace = 0;
- int rc; /* Return code */
-
- rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pReplace, 0);
- if( rc==SQLITE_OK ){
- sqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT);
- sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC);
- sqlite3_step(pReplace);
- rc = sqlite3_reset(pReplace);
- }
-
- return rc;
-}
-
-/*
-** Load an incr-merge hint from the database. The incr-merge hint, if one
-** exists, is stored in the rowid==1 row of the %_stat table.
-**
-** If successful, populate blob *pHint with the value read from the %_stat
-** table and return SQLITE_OK. Otherwise, if an error occurs, return an
-** SQLite error code.
-*/
-static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){
- sqlite3_stmt *pSelect = 0;
- int rc;
-
- pHint->n = 0;
- rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pSelect, 0);
- if( rc==SQLITE_OK ){
- int rc2;
- sqlite3_bind_int(pSelect, 1, FTS_STAT_INCRMERGEHINT);
- if( SQLITE_ROW==sqlite3_step(pSelect) ){
- const char *aHint = sqlite3_column_blob(pSelect, 0);
- int nHint = sqlite3_column_bytes(pSelect, 0);
- if( aHint ){
- blobGrowBuffer(pHint, nHint, &rc);
- if( rc==SQLITE_OK ){
- memcpy(pHint->a, aHint, nHint);
- pHint->n = nHint;
- }
- }
- }
- rc2 = sqlite3_reset(pSelect);
- if( rc==SQLITE_OK ) rc = rc2;
- }
-
- return rc;
-}
-
-/*
-** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
-** Otherwise, append an entry to the hint stored in blob *pHint. Each entry
-** consists of two varints, the absolute level number of the input segments
-** and the number of input segments.
-**
-** If successful, leave *pRc set to SQLITE_OK and return. If an error occurs,
-** set *pRc to an SQLite error code before returning.
-*/
-static void fts3IncrmergeHintPush(
- Blob *pHint, /* Hint blob to append to */
- i64 iAbsLevel, /* First varint to store in hint */
- int nInput, /* Second varint to store in hint */
- int *pRc /* IN/OUT: Error code */
-){
- blobGrowBuffer(pHint, pHint->n + 2*FTS3_VARINT_MAX, pRc);
- if( *pRc==SQLITE_OK ){
- pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], iAbsLevel);
- pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], (i64)nInput);
- }
-}
-
-/*
-** Read the last entry (most recently pushed) from the hint blob *pHint
-** and then remove the entry. Write the two values read to *piAbsLevel and
-** *pnInput before returning.
-**
-** If no error occurs, return SQLITE_OK. If the hint blob in *pHint does
-** not contain at least two valid varints, return SQLITE_CORRUPT_VTAB.
-*/
-static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){
- const int nHint = pHint->n;
- int i;
-
- i = pHint->n-2;
- while( i>0 && (pHint->a[i-1] & 0x80) ) i--;
- while( i>0 && (pHint->a[i-1] & 0x80) ) i--;
-
- pHint->n = i;
- i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
- i += sqlite3Fts3GetVarint32(&pHint->a[i], pnInput);
- if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
-
- return SQLITE_OK;
-}
-
-
-/*
-** Attempt an incremental merge that writes nMerge leaf blocks.
-**
-** Incremental merges happen nMin segments at a time. The two
-** segments to be merged are the nMin oldest segments (the ones with
-** the smallest indexes) in the highest level that contains at least
-** nMin segments. Multiple merges might occur in an attempt to write the
-** quota of nMerge leaf blocks.
-*/
-SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
- int rc; /* Return code */
- int nRem = nMerge; /* Number of leaf pages yet to be written */
- Fts3MultiSegReader *pCsr; /* Cursor used to read input data */
- Fts3SegFilter *pFilter; /* Filter used with cursor pCsr */
- IncrmergeWriter *pWriter; /* Writer object */
- int nSeg = 0; /* Number of input segments */
- sqlite3_int64 iAbsLevel = 0; /* Absolute level number to work on */
- Blob hint = {0, 0, 0}; /* Hint read from %_stat table */
- int bDirtyHint = 0; /* True if blob 'hint' has been modified */
-
- /* Allocate space for the cursor, filter and writer objects */
- const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter);
- pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc);
- if( !pWriter ) return SQLITE_NOMEM;
- pFilter = (Fts3SegFilter *)&pWriter[1];
- pCsr = (Fts3MultiSegReader *)&pFilter[1];
-
- rc = fts3IncrmergeHintLoad(p, &hint);
- while( rc==SQLITE_OK && nRem>0 ){
- const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex;
- sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */
- int bUseHint = 0; /* True if attempting to append */
-
- /* Search the %_segdir table for the absolute level with the smallest
- ** relative level number that contains at least nMin segments, if any.
- ** If one is found, set iAbsLevel to the absolute level number and
- ** nSeg to nMin. If no level with at least nMin segments can be found,
- ** set nSeg to -1.
- */
- rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0);
- sqlite3_bind_int(pFindLevel, 1, nMin);
- if( sqlite3_step(pFindLevel)==SQLITE_ROW ){
- iAbsLevel = sqlite3_column_int64(pFindLevel, 0);
- nSeg = nMin;
- }else{
- nSeg = -1;
- }
- rc = sqlite3_reset(pFindLevel);
-
- /* If the hint read from the %_stat table is not empty, check if the
- ** last entry in it specifies a relative level smaller than or equal
- ** to the level identified by the block above (if any). If so, this
- ** iteration of the loop will work on merging at the hinted level.
- */
- if( rc==SQLITE_OK && hint.n ){
- int nHint = hint.n;
- sqlite3_int64 iHintAbsLevel = 0; /* Hint level */
- int nHintSeg = 0; /* Hint number of segments */
-
- rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg);
- if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){
- iAbsLevel = iHintAbsLevel;
- nSeg = nHintSeg;
- bUseHint = 1;
- bDirtyHint = 1;
- }else{
- /* This undoes the effect of the HintPop() above - so that no entry
- ** is removed from the hint blob. */
- hint.n = nHint;
- }
- }
-
- /* If nSeg is less that zero, then there is no level with at least
- ** nMin segments and no hint in the %_stat table. No work to do.
- ** Exit early in this case. */
- if( nSeg<0 ) break;
-
- /* Open a cursor to iterate through the contents of the oldest nSeg
- ** indexes of absolute level iAbsLevel. If this cursor is opened using
- ** the 'hint' parameters, it is possible that there are less than nSeg
- ** segments available in level iAbsLevel. In this case, no work is
- ** done on iAbsLevel - fall through to the next iteration of the loop
- ** to start work on some other level. */
- memset(pWriter, 0, nAlloc);
- pFilter->flags = FTS3_SEGMENT_REQUIRE_POS;
- if( rc==SQLITE_OK ){
- rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr);
- }
- if( SQLITE_OK==rc && pCsr->nSegment==nSeg
- && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter))
- && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pCsr))
- ){
- int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */
- rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx);
- if( rc==SQLITE_OK ){
- if( bUseHint && iIdx>0 ){
- const char *zKey = pCsr->zTerm;
- int nKey = pCsr->nTerm;
- rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter);
- }else{
- rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter);
- }
- }
-
- if( rc==SQLITE_OK && pWriter->nLeafEst ){
- fts3LogMerge(nSeg, iAbsLevel);
- do {
- rc = fts3IncrmergeAppend(p, pWriter, pCsr);
- if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr);
- if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK;
- }while( rc==SQLITE_ROW );
-
- /* Update or delete the input segments */
- if( rc==SQLITE_OK ){
- nRem -= (1 + pWriter->nWork);
- rc = fts3IncrmergeChomp(p, iAbsLevel, pCsr, &nSeg);
- if( nSeg!=0 ){
- bDirtyHint = 1;
- fts3IncrmergeHintPush(&hint, iAbsLevel, nSeg, &rc);
- }
- }
- }
-
- fts3IncrmergeRelease(p, pWriter, &rc);
- }
-
- sqlite3Fts3SegReaderFinish(pCsr);
- }
-
- /* Write the hint values into the %_stat table for the next incr-merger */
- if( bDirtyHint && rc==SQLITE_OK ){
- rc = fts3IncrmergeHintStore(p, &hint);
- }
-
- sqlite3_free(pWriter);
- sqlite3_free(hint.a);
- return rc;
-}
-
-/*
-** Convert the text beginning at *pz into an integer and return
-** its value. Advance *pz to point to the first character past
-** the integer.
-*/
-static int fts3Getint(const char **pz){
- const char *z = *pz;
- int i = 0;
- while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0';
- *pz = z;
- return i;
-}
-
-/*
-** Process statements of the form:
-**
-** INSERT INTO table(table) VALUES('merge=A,B');
-**
-** A and B are integers that decode to be the number of leaf pages
-** written for the merge, and the minimum number of segments on a level
-** before it will be selected for a merge, respectively.
-*/
-static int fts3DoIncrmerge(
- Fts3Table *p, /* FTS3 table handle */
- const char *zParam /* Nul-terminated string containing "A,B" */
-){
- int rc;
- int nMin = (FTS3_MERGE_COUNT / 2);
- int nMerge = 0;
- const char *z = zParam;
-
- /* Read the first integer value */
- nMerge = fts3Getint(&z);
-
- /* If the first integer value is followed by a ',', read the second
- ** integer value. */
- if( z[0]==',' && z[1]!='\0' ){
- z++;
- nMin = fts3Getint(&z);
- }
-
- if( z[0]!='\0' || nMin<2 ){
- rc = SQLITE_ERROR;
- }else{
- rc = SQLITE_OK;
- if( !p->bHasStat ){
- assert( p->bFts4==0 );
- sqlite3Fts3CreateStatTable(&rc, p);
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts3Incrmerge(p, nMerge, nMin);
- }
- sqlite3Fts3SegmentsClose(p);
- }
- return rc;
-}
-
-/*
-** Process statements of the form:
-**
-** INSERT INTO table(table) VALUES('automerge=X');
-**
-** where X is an integer. X==0 means to turn automerge off. X!=0 means
-** turn it on. The setting is persistent.
-*/
-static int fts3DoAutoincrmerge(
- Fts3Table *p, /* FTS3 table handle */
- const char *zParam /* Nul-terminated string containing boolean */
-){
- int rc = SQLITE_OK;
- sqlite3_stmt *pStmt = 0;
- p->bAutoincrmerge = fts3Getint(&zParam)!=0;
- if( !p->bHasStat ){
- assert( p->bFts4==0 );
- sqlite3Fts3CreateStatTable(&rc, p);
- if( rc ) return rc;
- }
- rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0);
- if( rc ) return rc;;
- sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE);
- sqlite3_bind_int(pStmt, 2, p->bAutoincrmerge);
- sqlite3_step(pStmt);
- rc = sqlite3_reset(pStmt);
- return rc;
-}
-
-/*
-** Return a 64-bit checksum for the FTS index entry specified by the
-** arguments to this function.
-*/
-static u64 fts3ChecksumEntry(
- const char *zTerm, /* Pointer to buffer containing term */
- int nTerm, /* Size of zTerm in bytes */
- int iLangid, /* Language id for current row */
- int iIndex, /* Index (0..Fts3Table.nIndex-1) */
- i64 iDocid, /* Docid for current row. */
- int iCol, /* Column number */
- int iPos /* Position */
-){
- int i;
- u64 ret = (u64)iDocid;
-
- ret += (ret<<3) + iLangid;
- ret += (ret<<3) + iIndex;
- ret += (ret<<3) + iCol;
- ret += (ret<<3) + iPos;
- for(i=0; i<nTerm; i++) ret += (ret<<3) + zTerm[i];
-
- return ret;
-}
-
-/*
-** Return a checksum of all entries in the FTS index that correspond to
-** language id iLangid. The checksum is calculated by XORing the checksums
-** of each individual entry (see fts3ChecksumEntry()) together.
-**
-** If successful, the checksum value is returned and *pRc set to SQLITE_OK.
-** Otherwise, if an error occurs, *pRc is set to an SQLite error code. The
-** return value is undefined in this case.
-*/
-static u64 fts3ChecksumIndex(
- Fts3Table *p, /* FTS3 table handle */
- int iLangid, /* Language id to return cksum for */
- int iIndex, /* Index to cksum (0..p->nIndex-1) */
- int *pRc /* OUT: Return code */
-){
- Fts3SegFilter filter;
- Fts3MultiSegReader csr;
- int rc;
- u64 cksum = 0;
-
- assert( *pRc==SQLITE_OK );
-
- memset(&filter, 0, sizeof(filter));
- memset(&csr, 0, sizeof(csr));
- filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY;
- filter.flags |= FTS3_SEGMENT_SCAN;
-
- rc = sqlite3Fts3SegReaderCursor(
- p, iLangid, iIndex, FTS3_SEGCURSOR_ALL, 0, 0, 0, 1,&csr
- );
- if( rc==SQLITE_OK ){
- rc = sqlite3Fts3SegReaderStart(p, &csr, &filter);
- }
-
- if( rc==SQLITE_OK ){
- while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){
- char *pCsr = csr.aDoclist;
- char *pEnd = &pCsr[csr.nDoclist];
-
- i64 iDocid = 0;
- i64 iCol = 0;
- i64 iPos = 0;
-
- pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid);
- while( pCsr<pEnd ){
- i64 iVal = 0;
- pCsr += sqlite3Fts3GetVarint(pCsr, &iVal);
- if( pCsr<pEnd ){
- if( iVal==0 || iVal==1 ){
- iCol = 0;
- iPos = 0;
- if( iVal ){
- pCsr += sqlite3Fts3GetVarint(pCsr, &iCol);
- }else{
- pCsr += sqlite3Fts3GetVarint(pCsr, &iVal);
- iDocid += iVal;
- }
- }else{
- iPos += (iVal - 2);
- cksum = cksum ^ fts3ChecksumEntry(
- csr.zTerm, csr.nTerm, iLangid, iIndex, iDocid,
- (int)iCol, (int)iPos
- );
- }
- }
- }
- }
- }
- sqlite3Fts3SegReaderFinish(&csr);
-
- *pRc = rc;
- return cksum;
-}
-
-/*
-** Check if the contents of the FTS index match the current contents of the
-** content table. If no error occurs and the contents do match, set *pbOk
-** to true and return SQLITE_OK. Or if the contents do not match, set *pbOk
-** to false before returning.
-**
-** If an error occurs (e.g. an OOM or IO error), return an SQLite error
-** code. The final value of *pbOk is undefined in this case.
-*/
-static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
- int rc = SQLITE_OK; /* Return code */
- u64 cksum1 = 0; /* Checksum based on FTS index contents */
- u64 cksum2 = 0; /* Checksum based on %_content contents */
- sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */
-
- /* This block calculates the checksum according to the FTS index. */
- rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
- if( rc==SQLITE_OK ){
- int rc2;
- sqlite3_bind_int(pAllLangid, 1, p->nIndex);
- while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
- int iLangid = sqlite3_column_int(pAllLangid, 0);
- int i;
- for(i=0; i<p->nIndex; i++){
- cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc);
- }
- }
- rc2 = sqlite3_reset(pAllLangid);
- if( rc==SQLITE_OK ) rc = rc2;
- }
-
- /* This block calculates the checksum according to the %_content table */
- rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
- if( rc==SQLITE_OK ){
- sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule;
- sqlite3_stmt *pStmt = 0;
- char *zSql;
-
- zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
- if( !zSql ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
- sqlite3_free(zSql);
- }
-
- while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
- i64 iDocid = sqlite3_column_int64(pStmt, 0);
- int iLang = langidFromSelect(p, pStmt);
- int iCol;
-
- for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
- const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1);
- int nText = sqlite3_column_bytes(pStmt, iCol+1);
- sqlite3_tokenizer_cursor *pT = 0;
-
- rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT);
- while( rc==SQLITE_OK ){
- char const *zToken; /* Buffer containing token */
- int nToken = 0; /* Number of bytes in token */
- int iDum1 = 0, iDum2 = 0; /* Dummy variables */
- int iPos = 0; /* Position of token in zText */
-
- rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
- if( rc==SQLITE_OK ){
- int i;
- cksum2 = cksum2 ^ fts3ChecksumEntry(
- zToken, nToken, iLang, 0, iDocid, iCol, iPos
- );
- for(i=1; i<p->nIndex; i++){
- if( p->aIndex[i].nPrefix<=nToken ){
- cksum2 = cksum2 ^ fts3ChecksumEntry(
- zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos
- );
- }
- }
- }
- }
- if( pT ) pModule->xClose(pT);
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
- }
- }
-
- sqlite3_finalize(pStmt);
- }
-
- *pbOk = (cksum1==cksum2);
- return rc;
-}
-
-/*
-** Run the integrity-check. If no error occurs and the current contents of
-** the FTS index are correct, return SQLITE_OK. Or, if the contents of the
-** FTS index are incorrect, return SQLITE_CORRUPT_VTAB.
-**
-** Or, if an error (e.g. an OOM or IO error) occurs, return an SQLite
-** error code.
-**
-** The integrity-check works as follows. For each token and indexed token
-** prefix in the document set, a 64-bit checksum is calculated (by code
-** in fts3ChecksumEntry()) based on the following:
-**
-** + The index number (0 for the main index, 1 for the first prefix
-** index etc.),
-** + The token (or token prefix) text itself,
-** + The language-id of the row it appears in,
-** + The docid of the row it appears in,
-** + The column it appears in, and
-** + The tokens position within that column.
-**
-** The checksums for all entries in the index are XORed together to create
-** a single checksum for the entire index.
-**
-** The integrity-check code calculates the same checksum in two ways:
-**
-** 1. By scanning the contents of the FTS index, and
-** 2. By scanning and tokenizing the content table.
-**
-** If the two checksums are identical, the integrity-check is deemed to have
-** passed.
-*/
-static int fts3DoIntegrityCheck(
- Fts3Table *p /* FTS3 table handle */
-){
- int rc;
- int bOk = 0;
- rc = fts3IntegrityCheck(p, &bOk);
- if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB;
- return rc;
-}
-
-/*
-** Handle a 'special' INSERT of the form:
-**
-** "INSERT INTO tbl(tbl) VALUES(<expr>)"
-**
-** Argument pVal contains the result of <expr>. Currently the only
-** meaningful value to insert is the text 'optimize'.
-*/
-static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
- int rc; /* Return Code */
- const char *zVal = (const char *)sqlite3_value_text(pVal);
- int nVal = sqlite3_value_bytes(pVal);
-
- if( !zVal ){
- return SQLITE_NOMEM;
- }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){
- rc = fts3DoOptimize(p, 0);
- }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){
- rc = fts3DoRebuild(p);
- }else if( nVal==15 && 0==sqlite3_strnicmp(zVal, "integrity-check", 15) ){
- rc = fts3DoIntegrityCheck(p);
- }else if( nVal>6 && 0==sqlite3_strnicmp(zVal, "merge=", 6) ){
- rc = fts3DoIncrmerge(p, &zVal[6]);
- }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){
- rc = fts3DoAutoincrmerge(p, &zVal[10]);
-#ifdef SQLITE_TEST
- }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
- p->nNodeSize = atoi(&zVal[9]);
- rc = SQLITE_OK;
- }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
- p->nMaxPendingData = atoi(&zVal[11]);
- rc = SQLITE_OK;
-#endif
- }else{
- rc = SQLITE_ERROR;
- }
-
- return rc;
-}
-
-#ifndef SQLITE_DISABLE_FTS4_DEFERRED
-/*
-** Delete all cached deferred doclists. Deferred doclists are cached
-** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function.
-*/
-SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){
- Fts3DeferredToken *pDef;
- for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){
- fts3PendingListDelete(pDef->pList);
- pDef->pList = 0;
- }
-}
-
-/*
-** Free all entries in the pCsr->pDeffered list. Entries are added to
-** this list using sqlite3Fts3DeferToken().
-*/
-SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){
- Fts3DeferredToken *pDef;
- Fts3DeferredToken *pNext;
- for(pDef=pCsr->pDeferred; pDef; pDef=pNext){
- pNext = pDef->pNext;
- fts3PendingListDelete(pDef->pList);
- sqlite3_free(pDef);
- }
- pCsr->pDeferred = 0;
-}
-
-/*
-** Generate deferred-doclists for all tokens in the pCsr->pDeferred list
-** based on the row that pCsr currently points to.
-**
-** A deferred-doclist is like any other doclist with position information
-** included, except that it only contains entries for a single row of the
-** table, not for all rows.
-*/
-SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){
- int rc = SQLITE_OK; /* Return code */
- if( pCsr->pDeferred ){
- int i; /* Used to iterate through table columns */
- sqlite3_int64 iDocid; /* Docid of the row pCsr points to */
- Fts3DeferredToken *pDef; /* Used to iterate through deferred tokens */
-
- Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
- sqlite3_tokenizer *pT = p->pTokenizer;
- sqlite3_tokenizer_module const *pModule = pT->pModule;
-
- assert( pCsr->isRequireSeek==0 );
- iDocid = sqlite3_column_int64(pCsr->pStmt, 0);
-
- for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){
- const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1);
- sqlite3_tokenizer_cursor *pTC = 0;
-
- rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
- while( rc==SQLITE_OK ){
- char const *zToken; /* Buffer containing token */
- int nToken = 0; /* Number of bytes in token */
- int iDum1 = 0, iDum2 = 0; /* Dummy variables */
- int iPos = 0; /* Position of token in zText */
-
- rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
- for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
- Fts3PhraseToken *pPT = pDef->pToken;
- if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
- && (pPT->bFirst==0 || iPos==0)
- && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
- && (0==memcmp(zToken, pPT->z, pPT->n))
- ){
- fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
- }
- }
- }
- if( pTC ) pModule->xClose(pTC);
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
- }
-
- for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
- if( pDef->pList ){
- rc = fts3PendingListAppendVarint(&pDef->pList, 0);
- }
- }
- }
-
- return rc;
-}
-
-SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(
- Fts3DeferredToken *p,
- char **ppData,
- int *pnData
-){
- char *pRet;
- int nSkip;
- sqlite3_int64 dummy;
-
- *ppData = 0;
- *pnData = 0;
-
- if( p->pList==0 ){
- return SQLITE_OK;
- }
-
- pRet = (char *)sqlite3_malloc(p->pList->nData);
- if( !pRet ) return SQLITE_NOMEM;
-
- nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy);
- *pnData = p->pList->nData - nSkip;
- *ppData = pRet;
-
- memcpy(pRet, &p->pList->aData[nSkip], *pnData);
- return SQLITE_OK;
-}
-
-/*
-** Add an entry for token pToken to the pCsr->pDeferred list.
-*/
-SQLITE_PRIVATE int sqlite3Fts3DeferToken(
- Fts3Cursor *pCsr, /* Fts3 table cursor */
- Fts3PhraseToken *pToken, /* Token to defer */
- int iCol /* Column that token must appear in (or -1) */
-){
- Fts3DeferredToken *pDeferred;
- pDeferred = sqlite3_malloc(sizeof(*pDeferred));
- if( !pDeferred ){
- return SQLITE_NOMEM;
- }
- memset(pDeferred, 0, sizeof(*pDeferred));
- pDeferred->pToken = pToken;
- pDeferred->pNext = pCsr->pDeferred;
- pDeferred->iCol = iCol;
- pCsr->pDeferred = pDeferred;
-
- assert( pToken->pDeferred==0 );
- pToken->pDeferred = pDeferred;
-
- return SQLITE_OK;
-}
-#endif
-
-/*
-** SQLite value pRowid contains the rowid of a row that may or may not be
-** present in the FTS3 table. If it is, delete it and adjust the contents
-** of subsiduary data structures accordingly.
-*/
-static int fts3DeleteByRowid(
- Fts3Table *p,
- sqlite3_value *pRowid,
- int *pnChng, /* IN/OUT: Decrement if row is deleted */
- u32 *aSzDel
-){
- int rc = SQLITE_OK; /* Return code */
- int bFound = 0; /* True if *pRowid really is in the table */
-
- fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound);
- if( bFound && rc==SQLITE_OK ){
- int isEmpty = 0; /* Deleting *pRowid leaves the table empty */
- rc = fts3IsEmpty(p, pRowid, &isEmpty);
- if( rc==SQLITE_OK ){
- if( isEmpty ){
- /* Deleting this row means the whole table is empty. In this case
- ** delete the contents of all three tables and throw away any
- ** data in the pendingTerms hash table. */
- rc = fts3DeleteAll(p, 1);
- *pnChng = 0;
- memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2);
- }else{
- *pnChng = *pnChng - 1;
- if( p->zContentTbl==0 ){
- fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
- }
- if( p->bHasDocsize ){
- fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
- }
- }
- }
- }
-
- return rc;
-}
-
-/*
-** This function does the work for the xUpdate method of FTS3 virtual
-** tables. The schema of the virtual table being:
-**
-** CREATE TABLE <table name>(
-** <user columns>,
-** <table name> HIDDEN,
-** docid HIDDEN,
-** <langid> HIDDEN
-** );
-**
-**
-*/
-SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
- sqlite3_vtab *pVtab, /* FTS3 vtab object */
- int nArg, /* Size of argument array */
- sqlite3_value **apVal, /* Array of arguments */
- sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
-){
- Fts3Table *p = (Fts3Table *)pVtab;
- int rc = SQLITE_OK; /* Return Code */
- int isRemove = 0; /* True for an UPDATE or DELETE */
- u32 *aSzIns = 0; /* Sizes of inserted documents */
- u32 *aSzDel = 0; /* Sizes of deleted documents */
- int nChng = 0; /* Net change in number of documents */
- int bInsertDone = 0;
-
- assert( p->pSegments==0 );
- assert(
- nArg==1 /* DELETE operations */
- || nArg==(2 + p->nColumn + 3) /* INSERT or UPDATE operations */
- );
-
- /* Check for a "special" INSERT operation. One of the form:
- **
- ** INSERT INTO xyz(xyz) VALUES('command');
- */
- if( nArg>1
- && sqlite3_value_type(apVal[0])==SQLITE_NULL
- && sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL
- ){
- rc = fts3SpecialInsert(p, apVal[p->nColumn+2]);
- goto update_out;
- }
-
- if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){
- rc = SQLITE_CONSTRAINT;
- goto update_out;
- }
-
- /* Allocate space to hold the change in document sizes */
- aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 );
- if( aSzDel==0 ){
- rc = SQLITE_NOMEM;
- goto update_out;
- }
- aSzIns = &aSzDel[p->nColumn+1];
- memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);
-
- /* If this is an INSERT operation, or an UPDATE that modifies the rowid
- ** value, then this operation requires constraint handling.
- **
- ** If the on-conflict mode is REPLACE, this means that the existing row
- ** should be deleted from the database before inserting the new row. Or,
- ** if the on-conflict mode is other than REPLACE, then this method must
- ** detect the conflict and return SQLITE_CONSTRAINT before beginning to
- ** modify the database file.
- */
- if( nArg>1 && p->zContentTbl==0 ){
- /* Find the value object that holds the new rowid value. */
- sqlite3_value *pNewRowid = apVal[3+p->nColumn];
- if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){
- pNewRowid = apVal[1];
- }
-
- if( sqlite3_value_type(pNewRowid)!=SQLITE_NULL && (
- sqlite3_value_type(apVal[0])==SQLITE_NULL
- || sqlite3_value_int64(apVal[0])!=sqlite3_value_int64(pNewRowid)
- )){
- /* The new rowid is not NULL (in this case the rowid will be
- ** automatically assigned and there is no chance of a conflict), and
- ** the statement is either an INSERT or an UPDATE that modifies the
- ** rowid column. So if the conflict mode is REPLACE, then delete any
- ** existing row with rowid=pNewRowid.
- **
- ** Or, if the conflict mode is not REPLACE, insert the new record into
- ** the %_content table. If we hit the duplicate rowid constraint (or any
- ** other error) while doing so, return immediately.
- **
- ** This branch may also run if pNewRowid contains a value that cannot
- ** be losslessly converted to an integer. In this case, the eventual
- ** call to fts3InsertData() (either just below or further on in this
- ** function) will return SQLITE_MISMATCH. If fts3DeleteByRowid is
- ** invoked, it will delete zero rows (since no row will have
- ** docid=$pNewRowid if $pNewRowid is not an integer value).
- */
- if( sqlite3_vtab_on_conflict(p->db)==SQLITE_REPLACE ){
- rc = fts3DeleteByRowid(p, pNewRowid, &nChng, aSzDel);
- }else{
- rc = fts3InsertData(p, apVal, pRowid);
- bInsertDone = 1;
- }
- }
- }
- if( rc!=SQLITE_OK ){
- goto update_out;
- }
-
- /* If this is a DELETE or UPDATE operation, remove the old record. */
- if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
- assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
- rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
- isRemove = 1;
- }
-
- /* If this is an INSERT or UPDATE operation, insert the new record. */
- if( nArg>1 && rc==SQLITE_OK ){
- int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]);
- if( bInsertDone==0 ){
- rc = fts3InsertData(p, apVal, pRowid);
- if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
- rc = FTS_CORRUPT_VTAB;
- }
- }
- if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
- rc = fts3PendingTermsDocid(p, iLangid, *pRowid);
- }
- if( rc==SQLITE_OK ){
- assert( p->iPrevDocid==*pRowid );
- rc = fts3InsertTerms(p, iLangid, apVal, aSzIns);
- }
- if( p->bHasDocsize ){
- fts3InsertDocsize(&rc, p, aSzIns);
- }
- nChng++;
- }
-
- if( p->bFts4 ){
- fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng);
- }
-
- update_out:
- sqlite3_free(aSzDel);
- sqlite3Fts3SegmentsClose(p);
- return rc;
-}
-
-/*
-** Flush any data in the pending-terms hash table to disk. If successful,
-** merge all segments in the database (including the new segment, if
-** there was any data to flush) into a single segment.
-*/
-SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){
- int rc;
- rc = sqlite3_exec(p->db, "SAVEPOINT fts3", 0, 0, 0);
- if( rc==SQLITE_OK ){
- rc = fts3DoOptimize(p, 1);
- if( rc==SQLITE_OK || rc==SQLITE_DONE ){
- int rc2 = sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0);
- if( rc2!=SQLITE_OK ) rc = rc2;
- }else{
- sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0);
- sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0);
- }
- }
- sqlite3Fts3SegmentsClose(p);
- return rc;
-}
-
-#endif
-
-/************** End of fts3_write.c ******************************************/
-/************** Begin file fts3_snippet.c ************************************/
-/*
-** 2009 Oct 23
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-*/
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/* #include <string.h> */
-/* #include <assert.h> */
-
-/*
-** Characters that may appear in the second argument to matchinfo().
-*/
-#define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */
-#define FTS3_MATCHINFO_NCOL 'c' /* 1 value */
-#define FTS3_MATCHINFO_NDOC 'n' /* 1 value */
-#define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */
-#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */
-#define FTS3_MATCHINFO_LCS 's' /* nCol values */
-#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
-
-/*
-** The default value for the second argument to matchinfo().
-*/
-#define FTS3_MATCHINFO_DEFAULT "pcx"
-
-
-/*
-** Used as an fts3ExprIterate() context when loading phrase doclists to
-** Fts3Expr.aDoclist[]/nDoclist.
-*/
-typedef struct LoadDoclistCtx LoadDoclistCtx;
-struct LoadDoclistCtx {
- Fts3Cursor *pCsr; /* FTS3 Cursor */
- int nPhrase; /* Number of phrases seen so far */
- int nToken; /* Number of tokens seen so far */
-};
-
-/*
-** The following types are used as part of the implementation of the
-** fts3BestSnippet() routine.
-*/
-typedef struct SnippetIter SnippetIter;
-typedef struct SnippetPhrase SnippetPhrase;
-typedef struct SnippetFragment SnippetFragment;
-
-struct SnippetIter {
- Fts3Cursor *pCsr; /* Cursor snippet is being generated from */
- int iCol; /* Extract snippet from this column */
- int nSnippet; /* Requested snippet length (in tokens) */
- int nPhrase; /* Number of phrases in query */
- SnippetPhrase *aPhrase; /* Array of size nPhrase */
- int iCurrent; /* First token of current snippet */
-};
-
-struct SnippetPhrase {
- int nToken; /* Number of tokens in phrase */
- char *pList; /* Pointer to start of phrase position list */
- int iHead; /* Next value in position list */
- char *pHead; /* Position list data following iHead */
- int iTail; /* Next value in trailing position list */
- char *pTail; /* Position list data following iTail */
-};
-
-struct SnippetFragment {
- int iCol; /* Column snippet is extracted from */
- int iPos; /* Index of first token in snippet */
- u64 covered; /* Mask of query phrases covered */
- u64 hlmask; /* Mask of snippet terms to highlight */
-};
-
-/*
-** This type is used as an fts3ExprIterate() context object while
-** accumulating the data returned by the matchinfo() function.
-*/
-typedef struct MatchInfo MatchInfo;
-struct MatchInfo {
- Fts3Cursor *pCursor; /* FTS3 Cursor */
- int nCol; /* Number of columns in table */
- int nPhrase; /* Number of matchable phrases in query */
- sqlite3_int64 nDoc; /* Number of docs in database */
- u32 *aMatchinfo; /* Pre-allocated buffer */
-};
-
-
-
-/*
-** The snippet() and offsets() functions both return text values. An instance
-** of the following structure is used to accumulate those values while the
-** functions are running. See fts3StringAppend() for details.
-*/
-typedef struct StrBuffer StrBuffer;
-struct StrBuffer {
- char *z; /* Pointer to buffer containing string */
- int n; /* Length of z in bytes (excl. nul-term) */
- int nAlloc; /* Allocated size of buffer z in bytes */
-};
-
-
-/*
-** This function is used to help iterate through a position-list. A position
-** list is a list of unique integers, sorted from smallest to largest. Each
-** element of the list is represented by an FTS3 varint that takes the value
-** of the difference between the current element and the previous one plus
-** two. For example, to store the position-list:
-**
-** 4 9 113
-**
-** the three varints:
-**
-** 6 7 106
-**
-** are encoded.
-**
-** When this function is called, *pp points to the start of an element of
-** the list. *piPos contains the value of the previous entry in the list.
-** After it returns, *piPos contains the value of the next element of the
-** list and *pp is advanced to the following varint.
-*/
-static void fts3GetDeltaPosition(char **pp, int *piPos){
- int iVal;
- *pp += sqlite3Fts3GetVarint32(*pp, &iVal);
- *piPos += (iVal-2);
-}
-
-/*
-** Helper function for fts3ExprIterate() (see below).
-*/
-static int fts3ExprIterate2(
- Fts3Expr *pExpr, /* Expression to iterate phrases of */
- int *piPhrase, /* Pointer to phrase counter */
- int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */
- void *pCtx /* Second argument to pass to callback */
-){
- int rc; /* Return code */
- int eType = pExpr->eType; /* Type of expression node pExpr */
-
- if( eType!=FTSQUERY_PHRASE ){
- assert( pExpr->pLeft && pExpr->pRight );
- rc = fts3ExprIterate2(pExpr->pLeft, piPhrase, x, pCtx);
- if( rc==SQLITE_OK && eType!=FTSQUERY_NOT ){
- rc = fts3ExprIterate2(pExpr->pRight, piPhrase, x, pCtx);
- }
- }else{
- rc = x(pExpr, *piPhrase, pCtx);
- (*piPhrase)++;
- }
- return rc;
-}
-
-/*
-** Iterate through all phrase nodes in an FTS3 query, except those that
-** are part of a sub-tree that is the right-hand-side of a NOT operator.
-** For each phrase node found, the supplied callback function is invoked.
-**
-** If the callback function returns anything other than SQLITE_OK,
-** the iteration is abandoned and the error code returned immediately.
-** Otherwise, SQLITE_OK is returned after a callback has been made for
-** all eligible phrase nodes.
-*/
-static int fts3ExprIterate(
- Fts3Expr *pExpr, /* Expression to iterate phrases of */
- int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */
- void *pCtx /* Second argument to pass to callback */
-){
- int iPhrase = 0; /* Variable used as the phrase counter */
- return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
-}
-
-/*
-** This is an fts3ExprIterate() callback used while loading the doclists
-** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
-** fts3ExprLoadDoclists().
-*/
-static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
- int rc = SQLITE_OK;
- Fts3Phrase *pPhrase = pExpr->pPhrase;
- LoadDoclistCtx *p = (LoadDoclistCtx *)ctx;
-
- UNUSED_PARAMETER(iPhrase);
-
- p->nPhrase++;
- p->nToken += pPhrase->nToken;
-
- return rc;
-}
-
-/*
-** Load the doclists for each phrase in the query associated with FTS3 cursor
-** pCsr.
-**
-** If pnPhrase is not NULL, then *pnPhrase is set to the number of matchable
-** phrases in the expression (all phrases except those directly or
-** indirectly descended from the right-hand-side of a NOT operator). If
-** pnToken is not NULL, then it is set to the number of tokens in all
-** matchable phrases of the expression.
-*/
-static int fts3ExprLoadDoclists(
- Fts3Cursor *pCsr, /* Fts3 cursor for current query */
- int *pnPhrase, /* OUT: Number of phrases in query */
- int *pnToken /* OUT: Number of tokens in query */
-){
- int rc; /* Return Code */
- LoadDoclistCtx sCtx = {0,0,0}; /* Context for fts3ExprIterate() */
- sCtx.pCsr = pCsr;
- rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb, (void *)&sCtx);
- if( pnPhrase ) *pnPhrase = sCtx.nPhrase;
- if( pnToken ) *pnToken = sCtx.nToken;
- return rc;
-}
-
-static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
- (*(int *)ctx)++;
- UNUSED_PARAMETER(pExpr);
- UNUSED_PARAMETER(iPhrase);
- return SQLITE_OK;
-}
-static int fts3ExprPhraseCount(Fts3Expr *pExpr){
- int nPhrase = 0;
- (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase);
- return nPhrase;
-}
-
-/*
-** Advance the position list iterator specified by the first two
-** arguments so that it points to the first element with a value greater
-** than or equal to parameter iNext.
-*/
-static void fts3SnippetAdvance(char **ppIter, int *piIter, int iNext){
- char *pIter = *ppIter;
- if( pIter ){
- int iIter = *piIter;
-
- while( iIter<iNext ){
- if( 0==(*pIter & 0xFE) ){
- iIter = -1;
- pIter = 0;
- break;
- }
- fts3GetDeltaPosition(&pIter, &iIter);
- }
-
- *piIter = iIter;
- *ppIter = pIter;
- }
-}
-
-/*
-** Advance the snippet iterator to the next candidate snippet.
-*/
-static int fts3SnippetNextCandidate(SnippetIter *pIter){
- int i; /* Loop counter */
-
- if( pIter->iCurrent<0 ){
- /* The SnippetIter object has just been initialized. The first snippet
- ** candidate always starts at offset 0 (even if this candidate has a
- ** score of 0.0).
- */
- pIter->iCurrent = 0;
-
- /* Advance the 'head' iterator of each phrase to the first offset that
- ** is greater than or equal to (iNext+nSnippet).
- */
- for(i=0; i<pIter->nPhrase; i++){
- SnippetPhrase *pPhrase = &pIter->aPhrase[i];
- fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, pIter->nSnippet);
- }
- }else{
- int iStart;
- int iEnd = 0x7FFFFFFF;
-
- for(i=0; i<pIter->nPhrase; i++){
- SnippetPhrase *pPhrase = &pIter->aPhrase[i];
- if( pPhrase->pHead && pPhrase->iHead<iEnd ){
- iEnd = pPhrase->iHead;
- }
- }
- if( iEnd==0x7FFFFFFF ){
- return 1;
- }
-
- pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1;
- for(i=0; i<pIter->nPhrase; i++){
- SnippetPhrase *pPhrase = &pIter->aPhrase[i];
- fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, iEnd+1);
- fts3SnippetAdvance(&pPhrase->pTail, &pPhrase->iTail, iStart);
- }
- }
-
- return 0;
-}
-
-/*
-** Retrieve information about the current candidate snippet of snippet
-** iterator pIter.
-*/
-static void fts3SnippetDetails(
- SnippetIter *pIter, /* Snippet iterator */
- u64 mCovered, /* Bitmask of phrases already covered */
- int *piToken, /* OUT: First token of proposed snippet */
- int *piScore, /* OUT: "Score" for this snippet */
- u64 *pmCover, /* OUT: Bitmask of phrases covered */
- u64 *pmHighlight /* OUT: Bitmask of terms to highlight */
-){
- int iStart = pIter->iCurrent; /* First token of snippet */
- int iScore = 0; /* Score of this snippet */
- int i; /* Loop counter */
- u64 mCover = 0; /* Mask of phrases covered by this snippet */
- u64 mHighlight = 0; /* Mask of tokens to highlight in snippet */
-
- for(i=0; i<pIter->nPhrase; i++){
- SnippetPhrase *pPhrase = &pIter->aPhrase[i];
- if( pPhrase->pTail ){
- char *pCsr = pPhrase->pTail;
- int iCsr = pPhrase->iTail;
-
- while( iCsr<(iStart+pIter->nSnippet) ){
- int j;
- u64 mPhrase = (u64)1 << i;
- u64 mPos = (u64)1 << (iCsr - iStart);
- assert( iCsr>=iStart );
- if( (mCover|mCovered)&mPhrase ){
- iScore++;
- }else{
- iScore += 1000;
- }
- mCover |= mPhrase;
-
- for(j=0; j<pPhrase->nToken; j++){
- mHighlight |= (mPos>>j);
- }
-
- if( 0==(*pCsr & 0x0FE) ) break;
- fts3GetDeltaPosition(&pCsr, &iCsr);
- }
- }
- }
-
- /* Set the output variables before returning. */
- *piToken = iStart;
- *piScore = iScore;
- *pmCover = mCover;
- *pmHighlight = mHighlight;
-}
-
-/*
-** This function is an fts3ExprIterate() callback used by fts3BestSnippet().
-** Each invocation populates an element of the SnippetIter.aPhrase[] array.
-*/
-static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
- SnippetIter *p = (SnippetIter *)ctx;
- SnippetPhrase *pPhrase = &p->aPhrase[iPhrase];
- char *pCsr;
- int rc;
-
- pPhrase->nToken = pExpr->pPhrase->nToken;
- rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr);
- assert( rc==SQLITE_OK || pCsr==0 );
- if( pCsr ){
- int iFirst = 0;
- pPhrase->pList = pCsr;
- fts3GetDeltaPosition(&pCsr, &iFirst);
- assert( iFirst>=0 );
- pPhrase->pHead = pCsr;
- pPhrase->pTail = pCsr;
- pPhrase->iHead = iFirst;
- pPhrase->iTail = iFirst;
- }else{
- assert( rc!=SQLITE_OK || (
- pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0
- ));
- }
-
- return rc;
-}
-
-/*
-** Select the fragment of text consisting of nFragment contiguous tokens
-** from column iCol that represent the "best" snippet. The best snippet
-** is the snippet with the highest score, where scores are calculated
-** by adding:
-**
-** (a) +1 point for each occurence of a matchable phrase in the snippet.
-**
-** (b) +1000 points for the first occurence of each matchable phrase in
-** the snippet for which the corresponding mCovered bit is not set.
-**
-** The selected snippet parameters are stored in structure *pFragment before
-** returning. The score of the selected snippet is stored in *piScore
-** before returning.
-*/
-static int fts3BestSnippet(
- int nSnippet, /* Desired snippet length */
- Fts3Cursor *pCsr, /* Cursor to create snippet for */
- int iCol, /* Index of column to create snippet from */
- u64 mCovered, /* Mask of phrases already covered */
- u64 *pmSeen, /* IN/OUT: Mask of phrases seen */
- SnippetFragment *pFragment, /* OUT: Best snippet found */
- int *piScore /* OUT: Score of snippet pFragment */
-){
- int rc; /* Return Code */
- int nList; /* Number of phrases in expression */
- SnippetIter sIter; /* Iterates through snippet candidates */
- int nByte; /* Number of bytes of space to allocate */
- int iBestScore = -1; /* Best snippet score found so far */
- int i; /* Loop counter */
-
- memset(&sIter, 0, sizeof(sIter));
-
- /* Iterate through the phrases in the expression to count them. The same
- ** callback makes sure the doclists are loaded for each phrase.
- */
- rc = fts3ExprLoadDoclists(pCsr, &nList, 0);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* Now that it is known how many phrases there are, allocate and zero
- ** the required space using malloc().
- */
- nByte = sizeof(SnippetPhrase) * nList;
- sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc(nByte);
- if( !sIter.aPhrase ){
- return SQLITE_NOMEM;
- }
- memset(sIter.aPhrase, 0, nByte);
-
- /* Initialize the contents of the SnippetIter object. Then iterate through
- ** the set of phrases in the expression to populate the aPhrase[] array.
- */
- sIter.pCsr = pCsr;
- sIter.iCol = iCol;
- sIter.nSnippet = nSnippet;
- sIter.nPhrase = nList;
- sIter.iCurrent = -1;
- (void)fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
-
- /* Set the *pmSeen output variable. */
- for(i=0; i<nList; i++){
- if( sIter.aPhrase[i].pHead ){
- *pmSeen |= (u64)1 << i;
- }
- }
-
- /* Loop through all candidate snippets. Store the best snippet in
- ** *pFragment. Store its associated 'score' in iBestScore.
- */
- pFragment->iCol = iCol;
- while( !fts3SnippetNextCandidate(&sIter) ){
- int iPos;
- int iScore;
- u64 mCover;
- u64 mHighlight;
- fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover, &mHighlight);
- assert( iScore>=0 );
- if( iScore>iBestScore ){
- pFragment->iPos = iPos;
- pFragment->hlmask = mHighlight;
- pFragment->covered = mCover;
- iBestScore = iScore;
- }
- }
-
- sqlite3_free(sIter.aPhrase);
- *piScore = iBestScore;
- return SQLITE_OK;
-}
-
-
-/*
-** Append a string to the string-buffer passed as the first argument.
-**
-** If nAppend is negative, then the length of the string zAppend is
-** determined using strlen().
-*/
-static int fts3StringAppend(
- StrBuffer *pStr, /* Buffer to append to */
- const char *zAppend, /* Pointer to data to append to buffer */
- int nAppend /* Size of zAppend in bytes (or -1) */
-){
- if( nAppend<0 ){
- nAppend = (int)strlen(zAppend);
- }
-
- /* If there is insufficient space allocated at StrBuffer.z, use realloc()
- ** to grow the buffer until so that it is big enough to accomadate the
- ** appended data.
- */
- if( pStr->n+nAppend+1>=pStr->nAlloc ){
- int nAlloc = pStr->nAlloc+nAppend+100;
- char *zNew = sqlite3_realloc(pStr->z, nAlloc);
- if( !zNew ){
- return SQLITE_NOMEM;
- }
- pStr->z = zNew;
- pStr->nAlloc = nAlloc;
- }
-
- /* Append the data to the string buffer. */
- memcpy(&pStr->z[pStr->n], zAppend, nAppend);
- pStr->n += nAppend;
- pStr->z[pStr->n] = '\0';
-
- return SQLITE_OK;
-}
-
-/*
-** The fts3BestSnippet() function often selects snippets that end with a
-** query term. That is, the final term of the snippet is always a term
-** that requires highlighting. For example, if 'X' is a highlighted term
-** and '.' is a non-highlighted term, BestSnippet() may select:
-**
-** ........X.....X
-**
-** This function "shifts" the beginning of the snippet forward in the
-** document so that there are approximately the same number of
-** non-highlighted terms to the right of the final highlighted term as there
-** are to the left of the first highlighted term. For example, to this:
-**
-** ....X.....X....
-**
-** This is done as part of extracting the snippet text, not when selecting
-** the snippet. Snippet selection is done based on doclists only, so there
-** is no way for fts3BestSnippet() to know whether or not the document
-** actually contains terms that follow the final highlighted term.
-*/
-static int fts3SnippetShift(
- Fts3Table *pTab, /* FTS3 table snippet comes from */
- int iLangid, /* Language id to use in tokenizing */
- int nSnippet, /* Number of tokens desired for snippet */
- const char *zDoc, /* Document text to extract snippet from */
- int nDoc, /* Size of buffer zDoc in bytes */
- int *piPos, /* IN/OUT: First token of snippet */
- u64 *pHlmask /* IN/OUT: Mask of tokens to highlight */
-){
- u64 hlmask = *pHlmask; /* Local copy of initial highlight-mask */
-
- if( hlmask ){
- int nLeft; /* Tokens to the left of first highlight */
- int nRight; /* Tokens to the right of last highlight */
- int nDesired; /* Ideal number of tokens to shift forward */
-
- for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++);
- for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++);
- nDesired = (nLeft-nRight)/2;
-
- /* Ideally, the start of the snippet should be pushed forward in the
- ** document nDesired tokens. This block checks if there are actually
- ** nDesired tokens to the right of the snippet. If so, *piPos and
- ** *pHlMask are updated to shift the snippet nDesired tokens to the
- ** right. Otherwise, the snippet is shifted by the number of tokens
- ** available.
- */
- if( nDesired>0 ){
- int nShift; /* Number of tokens to shift snippet by */
- int iCurrent = 0; /* Token counter */
- int rc; /* Return Code */
- sqlite3_tokenizer_module *pMod;
- sqlite3_tokenizer_cursor *pC;
- pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule;
-
- /* Open a cursor on zDoc/nDoc. Check if there are (nSnippet+nDesired)
- ** or more tokens in zDoc/nDoc.
- */
- rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){
- const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0;
- rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent);
- }
- pMod->xClose(pC);
- if( rc!=SQLITE_OK && rc!=SQLITE_DONE ){ return rc; }
-
- nShift = (rc==SQLITE_DONE)+iCurrent-nSnippet;
- assert( nShift<=nDesired );
- if( nShift>0 ){
- *piPos += nShift;
- *pHlmask = hlmask >> nShift;
- }
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** Extract the snippet text for fragment pFragment from cursor pCsr and
-** append it to string buffer pOut.
-*/
-static int fts3SnippetText(
- Fts3Cursor *pCsr, /* FTS3 Cursor */
- SnippetFragment *pFragment, /* Snippet to extract */
- int iFragment, /* Fragment number */
- int isLast, /* True for final fragment in snippet */
- int nSnippet, /* Number of tokens in extracted snippet */
- const char *zOpen, /* String inserted before highlighted term */
- const char *zClose, /* String inserted after highlighted term */
- const char *zEllipsis, /* String inserted between snippets */
- StrBuffer *pOut /* Write output here */
-){
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- int rc; /* Return code */
- const char *zDoc; /* Document text to extract snippet from */
- int nDoc; /* Size of zDoc in bytes */
- int iCurrent = 0; /* Current token number of document */
- int iEnd = 0; /* Byte offset of end of current token */
- int isShiftDone = 0; /* True after snippet is shifted */
- int iPos = pFragment->iPos; /* First token of snippet */
- u64 hlmask = pFragment->hlmask; /* Highlight-mask for snippet */
- int iCol = pFragment->iCol+1; /* Query column to extract text from */
- sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */
- sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */
-
- zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol);
- if( zDoc==0 ){
- if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){
- return SQLITE_NOMEM;
- }
- return SQLITE_OK;
- }
- nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol);
-
- /* Open a token cursor on the document. */
- pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule;
- rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- while( rc==SQLITE_OK ){
- const char *ZDUMMY; /* Dummy argument used with tokenizer */
- int DUMMY1 = -1; /* Dummy argument used with tokenizer */
- int iBegin = 0; /* Offset in zDoc of start of token */
- int iFin = 0; /* Offset in zDoc of end of token */
- int isHighlight = 0; /* True for highlighted terms */
-
- /* Variable DUMMY1 is initialized to a negative value above. Elsewhere
- ** in the FTS code the variable that the third argument to xNext points to
- ** is initialized to zero before the first (*but not necessarily
- ** subsequent*) call to xNext(). This is done for a particular application
- ** that needs to know whether or not the tokenizer is being used for
- ** snippet generation or for some other purpose.
- **
- ** Extreme care is required when writing code to depend on this
- ** initialization. It is not a documented part of the tokenizer interface.
- ** If a tokenizer is used directly by any code outside of FTS, this
- ** convention might not be respected. */
- rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent);
- if( rc!=SQLITE_OK ){
- if( rc==SQLITE_DONE ){
- /* Special case - the last token of the snippet is also the last token
- ** of the column. Append any punctuation that occurred between the end
- ** of the previous token and the end of the document to the output.
- ** Then break out of the loop. */
- rc = fts3StringAppend(pOut, &zDoc[iEnd], -1);
- }
- break;
- }
- if( iCurrent<iPos ){ continue; }
-
- if( !isShiftDone ){
- int n = nDoc - iBegin;
- rc = fts3SnippetShift(
- pTab, pCsr->iLangid, nSnippet, &zDoc[iBegin], n, &iPos, &hlmask
- );
- isShiftDone = 1;
-
- /* Now that the shift has been done, check if the initial "..." are
- ** required. They are required if (a) this is not the first fragment,
- ** or (b) this fragment does not begin at position 0 of its column.
- */
- if( rc==SQLITE_OK && (iPos>0 || iFragment>0) ){
- rc = fts3StringAppend(pOut, zEllipsis, -1);
- }
- if( rc!=SQLITE_OK || iCurrent<iPos ) continue;
- }
-
- if( iCurrent>=(iPos+nSnippet) ){
- if( isLast ){
- rc = fts3StringAppend(pOut, zEllipsis, -1);
- }
- break;
- }
-
- /* Set isHighlight to true if this term should be highlighted. */
- isHighlight = (hlmask & ((u64)1 << (iCurrent-iPos)))!=0;
-
- if( iCurrent>iPos ) rc = fts3StringAppend(pOut, &zDoc[iEnd], iBegin-iEnd);
- if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zOpen, -1);
- if( rc==SQLITE_OK ) rc = fts3StringAppend(pOut, &zDoc[iBegin], iFin-iBegin);
- if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zClose, -1);
-
- iEnd = iFin;
- }
-
- pMod->xClose(pC);
- return rc;
-}
-
-
-/*
-** This function is used to count the entries in a column-list (a
-** delta-encoded list of term offsets within a single column of a single
-** row). When this function is called, *ppCollist should point to the
-** beginning of the first varint in the column-list (the varint that
-** contains the position of the first matching term in the column data).
-** Before returning, *ppCollist is set to point to the first byte after
-** the last varint in the column-list (either the 0x00 signifying the end
-** of the position-list, or the 0x01 that precedes the column number of
-** the next column in the position-list).
-**
-** The number of elements in the column-list is returned.
-*/
-static int fts3ColumnlistCount(char **ppCollist){
- char *pEnd = *ppCollist;
- char c = 0;
- int nEntry = 0;
-
- /* A column-list is terminated by either a 0x01 or 0x00. */
- while( 0xFE & (*pEnd | c) ){
- c = *pEnd++ & 0x80;
- if( !c ) nEntry++;
- }
-
- *ppCollist = pEnd;
- return nEntry;
-}
-
-/*
-** fts3ExprIterate() callback used to collect the "global" matchinfo stats
-** for a single query.
-**
-** fts3ExprIterate() callback to load the 'global' elements of a
-** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements
-** of the matchinfo array that are constant for all rows returned by the
-** current query.
-**
-** Argument pCtx is actually a pointer to a struct of type MatchInfo. This
-** function populates Matchinfo.aMatchinfo[] as follows:
-**
-** for(iCol=0; iCol<nCol; iCol++){
-** aMatchinfo[3*iPhrase*nCol + 3*iCol + 1] = X;
-** aMatchinfo[3*iPhrase*nCol + 3*iCol + 2] = Y;
-** }
-**
-** where X is the number of matches for phrase iPhrase is column iCol of all
-** rows of the table. Y is the number of rows for which column iCol contains
-** at least one instance of phrase iPhrase.
-**
-** If the phrase pExpr consists entirely of deferred tokens, then all X and
-** Y values are set to nDoc, where nDoc is the number of documents in the
-** file system. This is done because the full-text index doclist is required
-** to calculate these values properly, and the full-text index doclist is
-** not available for deferred tokens.
-*/
-static int fts3ExprGlobalHitsCb(
- Fts3Expr *pExpr, /* Phrase expression node */
- int iPhrase, /* Phrase number (numbered from zero) */
- void *pCtx /* Pointer to MatchInfo structure */
-){
- MatchInfo *p = (MatchInfo *)pCtx;
- return sqlite3Fts3EvalPhraseStats(
- p->pCursor, pExpr, &p->aMatchinfo[3*iPhrase*p->nCol]
- );
-}
-
-/*
-** fts3ExprIterate() callback used to collect the "local" part of the
-** FTS3_MATCHINFO_HITS array. The local stats are those elements of the
-** array that are different for each row returned by the query.
-*/
-static int fts3ExprLocalHitsCb(
- Fts3Expr *pExpr, /* Phrase expression node */
- int iPhrase, /* Phrase number */
- void *pCtx /* Pointer to MatchInfo structure */
-){
- int rc = SQLITE_OK;
- MatchInfo *p = (MatchInfo *)pCtx;
- int iStart = iPhrase * p->nCol * 3;
- int i;
-
- for(i=0; i<p->nCol && rc==SQLITE_OK; i++){
- char *pCsr;
- rc = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i, &pCsr);
- if( pCsr ){
- p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr);
- }else{
- p->aMatchinfo[iStart+i*3] = 0;
- }
- }
-
- return rc;
-}
-
-static int fts3MatchinfoCheck(
- Fts3Table *pTab,
- char cArg,
- char **pzErr
-){
- if( (cArg==FTS3_MATCHINFO_NPHRASE)
- || (cArg==FTS3_MATCHINFO_NCOL)
- || (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4)
- || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4)
- || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
- || (cArg==FTS3_MATCHINFO_LCS)
- || (cArg==FTS3_MATCHINFO_HITS)
- ){
- return SQLITE_OK;
- }
- *pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg);
- return SQLITE_ERROR;
-}
-
-static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
- int nVal; /* Number of integers output by cArg */
-
- switch( cArg ){
- case FTS3_MATCHINFO_NDOC:
- case FTS3_MATCHINFO_NPHRASE:
- case FTS3_MATCHINFO_NCOL:
- nVal = 1;
- break;
-
- case FTS3_MATCHINFO_AVGLENGTH:
- case FTS3_MATCHINFO_LENGTH:
- case FTS3_MATCHINFO_LCS:
- nVal = pInfo->nCol;
- break;
-
- default:
- assert( cArg==FTS3_MATCHINFO_HITS );
- nVal = pInfo->nCol * pInfo->nPhrase * 3;
- break;
- }
-
- return nVal;
-}
-
-static int fts3MatchinfoSelectDoctotal(
- Fts3Table *pTab,
- sqlite3_stmt **ppStmt,
- sqlite3_int64 *pnDoc,
- const char **paLen
-){
- sqlite3_stmt *pStmt;
- const char *a;
- sqlite3_int64 nDoc;
-
- if( !*ppStmt ){
- int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt);
- if( rc!=SQLITE_OK ) return rc;
- }
- pStmt = *ppStmt;
- assert( sqlite3_data_count(pStmt)==1 );
-
- a = sqlite3_column_blob(pStmt, 0);
- a += sqlite3Fts3GetVarint(a, &nDoc);
- if( nDoc==0 ) return FTS_CORRUPT_VTAB;
- *pnDoc = (u32)nDoc;
-
- if( paLen ) *paLen = a;
- return SQLITE_OK;
-}
-
-/*
-** An instance of the following structure is used to store state while
-** iterating through a multi-column position-list corresponding to the
-** hits for a single phrase on a single row in order to calculate the
-** values for a matchinfo() FTS3_MATCHINFO_LCS request.
-*/
-typedef struct LcsIterator LcsIterator;
-struct LcsIterator {
- Fts3Expr *pExpr; /* Pointer to phrase expression */
- int iPosOffset; /* Tokens count up to end of this phrase */
- char *pRead; /* Cursor used to iterate through aDoclist */
- int iPos; /* Current position */
-};
-
-/*
-** If LcsIterator.iCol is set to the following value, the iterator has
-** finished iterating through all offsets for all columns.
-*/
-#define LCS_ITERATOR_FINISHED 0x7FFFFFFF;
-
-static int fts3MatchinfoLcsCb(
- Fts3Expr *pExpr, /* Phrase expression node */
- int iPhrase, /* Phrase number (numbered from zero) */
- void *pCtx /* Pointer to MatchInfo structure */
-){
- LcsIterator *aIter = (LcsIterator *)pCtx;
- aIter[iPhrase].pExpr = pExpr;
- return SQLITE_OK;
-}
-
-/*
-** Advance the iterator passed as an argument to the next position. Return
-** 1 if the iterator is at EOF or if it now points to the start of the
-** position list for the next column.
-*/
-static int fts3LcsIteratorAdvance(LcsIterator *pIter){
- char *pRead = pIter->pRead;
- sqlite3_int64 iRead;
- int rc = 0;
-
- pRead += sqlite3Fts3GetVarint(pRead, &iRead);
- if( iRead==0 || iRead==1 ){
- pRead = 0;
- rc = 1;
- }else{
- pIter->iPos += (int)(iRead-2);
- }
-
- pIter->pRead = pRead;
- return rc;
-}
-
-/*
-** This function implements the FTS3_MATCHINFO_LCS matchinfo() flag.
-**
-** If the call is successful, the longest-common-substring lengths for each
-** column are written into the first nCol elements of the pInfo->aMatchinfo[]
-** array before returning. SQLITE_OK is returned in this case.
-**
-** Otherwise, if an error occurs, an SQLite error code is returned and the
-** data written to the first nCol elements of pInfo->aMatchinfo[] is
-** undefined.
-*/
-static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
- LcsIterator *aIter;
- int i;
- int iCol;
- int nToken = 0;
-
- /* Allocate and populate the array of LcsIterator objects. The array
- ** contains one element for each matchable phrase in the query.
- **/
- aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase);
- if( !aIter ) return SQLITE_NOMEM;
- memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
- (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
-
- for(i=0; i<pInfo->nPhrase; i++){
- LcsIterator *pIter = &aIter[i];
- nToken -= pIter->pExpr->pPhrase->nToken;
- pIter->iPosOffset = nToken;
- }
-
- for(iCol=0; iCol<pInfo->nCol; iCol++){
- int nLcs = 0; /* LCS value for this column */
- int nLive = 0; /* Number of iterators in aIter not at EOF */
-
- for(i=0; i<pInfo->nPhrase; i++){
- int rc;
- LcsIterator *pIt = &aIter[i];
- rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead);
- if( rc!=SQLITE_OK ) return rc;
- if( pIt->pRead ){
- pIt->iPos = pIt->iPosOffset;
- fts3LcsIteratorAdvance(&aIter[i]);
- nLive++;
- }
- }
-
- while( nLive>0 ){
- LcsIterator *pAdv = 0; /* The iterator to advance by one position */
- int nThisLcs = 0; /* LCS for the current iterator positions */
-
- for(i=0; i<pInfo->nPhrase; i++){
- LcsIterator *pIter = &aIter[i];
- if( pIter->pRead==0 ){
- /* This iterator is already at EOF for this column. */
- nThisLcs = 0;
- }else{
- if( pAdv==0 || pIter->iPos<pAdv->iPos ){
- pAdv = pIter;
- }
- if( nThisLcs==0 || pIter->iPos==pIter[-1].iPos ){
- nThisLcs++;
- }else{
- nThisLcs = 1;
- }
- if( nThisLcs>nLcs ) nLcs = nThisLcs;
- }
- }
- if( fts3LcsIteratorAdvance(pAdv) ) nLive--;
- }
-
- pInfo->aMatchinfo[iCol] = nLcs;
- }
-
- sqlite3_free(aIter);
- return SQLITE_OK;
-}
-
-/*
-** Populate the buffer pInfo->aMatchinfo[] with an array of integers to
-** be returned by the matchinfo() function. Argument zArg contains the
-** format string passed as the second argument to matchinfo (or the
-** default value "pcx" if no second argument was specified). The format
-** string has already been validated and the pInfo->aMatchinfo[] array
-** is guaranteed to be large enough for the output.
-**
-** If bGlobal is true, then populate all fields of the matchinfo() output.
-** If it is false, then assume that those fields that do not change between
-** rows (i.e. FTS3_MATCHINFO_NPHRASE, NCOL, NDOC, AVGLENGTH and part of HITS)
-** have already been populated.
-**
-** Return SQLITE_OK if successful, or an SQLite error code if an error
-** occurs. If a value other than SQLITE_OK is returned, the state the
-** pInfo->aMatchinfo[] buffer is left in is undefined.
-*/
-static int fts3MatchinfoValues(
- Fts3Cursor *pCsr, /* FTS3 cursor object */
- int bGlobal, /* True to grab the global stats */
- MatchInfo *pInfo, /* Matchinfo context object */
- const char *zArg /* Matchinfo format string */
-){
- int rc = SQLITE_OK;
- int i;
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- sqlite3_stmt *pSelect = 0;
-
- for(i=0; rc==SQLITE_OK && zArg[i]; i++){
-
- switch( zArg[i] ){
- case FTS3_MATCHINFO_NPHRASE:
- if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase;
- break;
-
- case FTS3_MATCHINFO_NCOL:
- if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol;
- break;
-
- case FTS3_MATCHINFO_NDOC:
- if( bGlobal ){
- sqlite3_int64 nDoc = 0;
- rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0);
- pInfo->aMatchinfo[0] = (u32)nDoc;
- }
- break;
-
- case FTS3_MATCHINFO_AVGLENGTH:
- if( bGlobal ){
- sqlite3_int64 nDoc; /* Number of rows in table */
- const char *a; /* Aggregate column length array */
-
- rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a);
- if( rc==SQLITE_OK ){
- int iCol;
- for(iCol=0; iCol<pInfo->nCol; iCol++){
- u32 iVal;
- sqlite3_int64 nToken;
- a += sqlite3Fts3GetVarint(a, &nToken);
- iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc);
- pInfo->aMatchinfo[iCol] = iVal;
- }
- }
- }
- break;
-
- case FTS3_MATCHINFO_LENGTH: {
- sqlite3_stmt *pSelectDocsize = 0;
- rc = sqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize);
- if( rc==SQLITE_OK ){
- int iCol;
- const char *a = sqlite3_column_blob(pSelectDocsize, 0);
- for(iCol=0; iCol<pInfo->nCol; iCol++){
- sqlite3_int64 nToken;
- a += sqlite3Fts3GetVarint(a, &nToken);
- pInfo->aMatchinfo[iCol] = (u32)nToken;
- }
- }
- sqlite3_reset(pSelectDocsize);
- break;
- }
-
- case FTS3_MATCHINFO_LCS:
- rc = fts3ExprLoadDoclists(pCsr, 0, 0);
- if( rc==SQLITE_OK ){
- rc = fts3MatchinfoLcs(pCsr, pInfo);
- }
- break;
-
- default: {
- Fts3Expr *pExpr;
- assert( zArg[i]==FTS3_MATCHINFO_HITS );
- pExpr = pCsr->pExpr;
- rc = fts3ExprLoadDoclists(pCsr, 0, 0);
- if( rc!=SQLITE_OK ) break;
- if( bGlobal ){
- if( pCsr->pDeferred ){
- rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0);
- if( rc!=SQLITE_OK ) break;
- }
- rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
- if( rc!=SQLITE_OK ) break;
- }
- (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);
- break;
- }
- }
-
- pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]);
- }
-
- sqlite3_reset(pSelect);
- return rc;
-}
-
-
-/*
-** Populate pCsr->aMatchinfo[] with data for the current row. The
-** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32).
-*/
-static int fts3GetMatchinfo(
- Fts3Cursor *pCsr, /* FTS3 Cursor object */
- const char *zArg /* Second argument to matchinfo() function */
-){
- MatchInfo sInfo;
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- int rc = SQLITE_OK;
- int bGlobal = 0; /* Collect 'global' stats as well as local */
-
- memset(&sInfo, 0, sizeof(MatchInfo));
- sInfo.pCursor = pCsr;
- sInfo.nCol = pTab->nColumn;
-
- /* If there is cached matchinfo() data, but the format string for the
- ** cache does not match the format string for this request, discard
- ** the cached data. */
- if( pCsr->zMatchinfo && strcmp(pCsr->zMatchinfo, zArg) ){
- assert( pCsr->aMatchinfo );
- sqlite3_free(pCsr->aMatchinfo);
- pCsr->zMatchinfo = 0;
- pCsr->aMatchinfo = 0;
- }
-
- /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the
- ** matchinfo function has been called for this query. In this case
- ** allocate the array used to accumulate the matchinfo data and
- ** initialize those elements that are constant for every row.
- */
- if( pCsr->aMatchinfo==0 ){
- int nMatchinfo = 0; /* Number of u32 elements in match-info */
- int nArg; /* Bytes in zArg */
- int i; /* Used to iterate through zArg */
-
- /* Determine the number of phrases in the query */
- pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr);
- sInfo.nPhrase = pCsr->nPhrase;
-
- /* Determine the number of integers in the buffer returned by this call. */
- for(i=0; zArg[i]; i++){
- nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]);
- }
-
- /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */
- nArg = (int)strlen(zArg);
- pCsr->aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo + nArg + 1);
- if( !pCsr->aMatchinfo ) return SQLITE_NOMEM;
-
- pCsr->zMatchinfo = (char *)&pCsr->aMatchinfo[nMatchinfo];
- pCsr->nMatchinfo = nMatchinfo;
- memcpy(pCsr->zMatchinfo, zArg, nArg+1);
- memset(pCsr->aMatchinfo, 0, sizeof(u32)*nMatchinfo);
- pCsr->isMatchinfoNeeded = 1;
- bGlobal = 1;
- }
-
- sInfo.aMatchinfo = pCsr->aMatchinfo;
- sInfo.nPhrase = pCsr->nPhrase;
- if( pCsr->isMatchinfoNeeded ){
- rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
- pCsr->isMatchinfoNeeded = 0;
- }
-
- return rc;
-}
-
-/*
-** Implementation of snippet() function.
-*/
-SQLITE_PRIVATE void sqlite3Fts3Snippet(
- sqlite3_context *pCtx, /* SQLite function call context */
- Fts3Cursor *pCsr, /* Cursor object */
- const char *zStart, /* Snippet start text - "<b>" */
- const char *zEnd, /* Snippet end text - "</b>" */
- const char *zEllipsis, /* Snippet ellipsis text - "<b>...</b>" */
- int iCol, /* Extract snippet from this column */
- int nToken /* Approximate number of tokens in snippet */
-){
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- int rc = SQLITE_OK;
- int i;
- StrBuffer res = {0, 0, 0};
-
- /* The returned text includes up to four fragments of text extracted from
- ** the data in the current row. The first iteration of the for(...) loop
- ** below attempts to locate a single fragment of text nToken tokens in
- ** size that contains at least one instance of all phrases in the query
- ** expression that appear in the current row. If such a fragment of text
- ** cannot be found, the second iteration of the loop attempts to locate
- ** a pair of fragments, and so on.
- */
- int nSnippet = 0; /* Number of fragments in this snippet */
- SnippetFragment aSnippet[4]; /* Maximum of 4 fragments per snippet */
- int nFToken = -1; /* Number of tokens in each fragment */
-
- if( !pCsr->pExpr ){
- sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC);
- return;
- }
-
- for(nSnippet=1; 1; nSnippet++){
-
- int iSnip; /* Loop counter 0..nSnippet-1 */
- u64 mCovered = 0; /* Bitmask of phrases covered by snippet */
- u64 mSeen = 0; /* Bitmask of phrases seen by BestSnippet() */
-
- if( nToken>=0 ){
- nFToken = (nToken+nSnippet-1) / nSnippet;
- }else{
- nFToken = -1 * nToken;
- }
-
- for(iSnip=0; iSnip<nSnippet; iSnip++){
- int iBestScore = -1; /* Best score of columns checked so far */
- int iRead; /* Used to iterate through columns */
- SnippetFragment *pFragment = &aSnippet[iSnip];
-
- memset(pFragment, 0, sizeof(*pFragment));
-
- /* Loop through all columns of the table being considered for snippets.
- ** If the iCol argument to this function was negative, this means all
- ** columns of the FTS3 table. Otherwise, only column iCol is considered.
- */
- for(iRead=0; iRead<pTab->nColumn; iRead++){
- SnippetFragment sF = {0, 0, 0, 0};
- int iS;
- if( iCol>=0 && iRead!=iCol ) continue;
-
- /* Find the best snippet of nFToken tokens in column iRead. */
- rc = fts3BestSnippet(nFToken, pCsr, iRead, mCovered, &mSeen, &sF, &iS);
- if( rc!=SQLITE_OK ){
- goto snippet_out;
- }
- if( iS>iBestScore ){
- *pFragment = sF;
- iBestScore = iS;
- }
- }
-
- mCovered |= pFragment->covered;
- }
-
- /* If all query phrases seen by fts3BestSnippet() are present in at least
- ** one of the nSnippet snippet fragments, break out of the loop.
- */
- assert( (mCovered&mSeen)==mCovered );
- if( mSeen==mCovered || nSnippet==SizeofArray(aSnippet) ) break;
- }
-
- assert( nFToken>0 );
-
- for(i=0; i<nSnippet && rc==SQLITE_OK; i++){
- rc = fts3SnippetText(pCsr, &aSnippet[i],
- i, (i==nSnippet-1), nFToken, zStart, zEnd, zEllipsis, &res
- );
- }
-
- snippet_out:
- sqlite3Fts3SegmentsClose(pTab);
- if( rc!=SQLITE_OK ){
- sqlite3_result_error_code(pCtx, rc);
- sqlite3_free(res.z);
- }else{
- sqlite3_result_text(pCtx, res.z, -1, sqlite3_free);
- }
-}
-
-
-typedef struct TermOffset TermOffset;
-typedef struct TermOffsetCtx TermOffsetCtx;
-
-struct TermOffset {
- char *pList; /* Position-list */
- int iPos; /* Position just read from pList */
- int iOff; /* Offset of this term from read positions */
-};
-
-struct TermOffsetCtx {
- Fts3Cursor *pCsr;
- int iCol; /* Column of table to populate aTerm for */
- int iTerm;
- sqlite3_int64 iDocid;
- TermOffset *aTerm;
-};
-
-/*
-** This function is an fts3ExprIterate() callback used by sqlite3Fts3Offsets().
-*/
-static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
- TermOffsetCtx *p = (TermOffsetCtx *)ctx;
- int nTerm; /* Number of tokens in phrase */
- int iTerm; /* For looping through nTerm phrase terms */
- char *pList; /* Pointer to position list for phrase */
- int iPos = 0; /* First position in position-list */
- int rc;
-
- UNUSED_PARAMETER(iPhrase);
- rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pList);
- nTerm = pExpr->pPhrase->nToken;
- if( pList ){
- fts3GetDeltaPosition(&pList, &iPos);
- assert( iPos>=0 );
- }
-
- for(iTerm=0; iTerm<nTerm; iTerm++){
- TermOffset *pT = &p->aTerm[p->iTerm++];
- pT->iOff = nTerm-iTerm-1;
- pT->pList = pList;
- pT->iPos = iPos;
- }
-
- return rc;
-}
-
-/*
-** Implementation of offsets() function.
-*/
-SQLITE_PRIVATE void sqlite3Fts3Offsets(
- sqlite3_context *pCtx, /* SQLite function call context */
- Fts3Cursor *pCsr /* Cursor object */
-){
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule;
- int rc; /* Return Code */
- int nToken; /* Number of tokens in query */
- int iCol; /* Column currently being processed */
- StrBuffer res = {0, 0, 0}; /* Result string */
- TermOffsetCtx sCtx; /* Context for fts3ExprTermOffsetInit() */
-
- if( !pCsr->pExpr ){
- sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC);
- return;
- }
-
- memset(&sCtx, 0, sizeof(sCtx));
- assert( pCsr->isRequireSeek==0 );
-
- /* Count the number of terms in the query */
- rc = fts3ExprLoadDoclists(pCsr, 0, &nToken);
- if( rc!=SQLITE_OK ) goto offsets_out;
-
- /* Allocate the array of TermOffset iterators. */
- sCtx.aTerm = (TermOffset *)sqlite3_malloc(sizeof(TermOffset)*nToken);
- if( 0==sCtx.aTerm ){
- rc = SQLITE_NOMEM;
- goto offsets_out;
- }
- sCtx.iDocid = pCsr->iPrevId;
- sCtx.pCsr = pCsr;
-
- /* Loop through the table columns, appending offset information to
- ** string-buffer res for each column.
- */
- for(iCol=0; iCol<pTab->nColumn; iCol++){
- sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */
- const char *ZDUMMY; /* Dummy argument used with xNext() */
- int NDUMMY = 0; /* Dummy argument used with xNext() */
- int iStart = 0;
- int iEnd = 0;
- int iCurrent = 0;
- const char *zDoc;
- int nDoc;
-
- /* Initialize the contents of sCtx.aTerm[] for column iCol. There is
- ** no way that this operation can fail, so the return code from
- ** fts3ExprIterate() can be discarded.
- */
- sCtx.iCol = iCol;
- sCtx.iTerm = 0;
- (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void *)&sCtx);
-
- /* Retreive the text stored in column iCol. If an SQL NULL is stored
- ** in column iCol, jump immediately to the next iteration of the loop.
- ** If an OOM occurs while retrieving the data (this can happen if SQLite
- ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
- ** to the caller.
- */
- zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol+1);
- nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol+1);
- if( zDoc==0 ){
- if( sqlite3_column_type(pCsr->pStmt, iCol+1)==SQLITE_NULL ){
- continue;
- }
- rc = SQLITE_NOMEM;
- goto offsets_out;
- }
-
- /* Initialize a tokenizer iterator to iterate through column iCol. */
- rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid,
- zDoc, nDoc, &pC
- );
- if( rc!=SQLITE_OK ) goto offsets_out;
-
- rc = pMod->xNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent);
- while( rc==SQLITE_OK ){
- int i; /* Used to loop through terms */
- int iMinPos = 0x7FFFFFFF; /* Position of next token */
- TermOffset *pTerm = 0; /* TermOffset associated with next token */
-
- for(i=0; i<nToken; i++){
- TermOffset *pT = &sCtx.aTerm[i];
- if( pT->pList && (pT->iPos-pT->iOff)<iMinPos ){
- iMinPos = pT->iPos-pT->iOff;
- pTerm = pT;
- }
- }
-
- if( !pTerm ){
- /* All offsets for this column have been gathered. */
- rc = SQLITE_DONE;
- }else{
- assert( iCurrent<=iMinPos );
- if( 0==(0xFE&*pTerm->pList) ){
- pTerm->pList = 0;
- }else{
- fts3GetDeltaPosition(&pTerm->pList, &pTerm->iPos);
- }
- while( rc==SQLITE_OK && iCurrent<iMinPos ){
- rc = pMod->xNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent);
- }
- if( rc==SQLITE_OK ){
- char aBuffer[64];
- sqlite3_snprintf(sizeof(aBuffer), aBuffer,
- "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart
- );
- rc = fts3StringAppend(&res, aBuffer, -1);
- }else if( rc==SQLITE_DONE && pTab->zContentTbl==0 ){
- rc = FTS_CORRUPT_VTAB;
- }
- }
- }
- if( rc==SQLITE_DONE ){
- rc = SQLITE_OK;
- }
-
- pMod->xClose(pC);
- if( rc!=SQLITE_OK ) goto offsets_out;
- }
-
- offsets_out:
- sqlite3_free(sCtx.aTerm);
- assert( rc!=SQLITE_DONE );
- sqlite3Fts3SegmentsClose(pTab);
- if( rc!=SQLITE_OK ){
- sqlite3_result_error_code(pCtx, rc);
- sqlite3_free(res.z);
- }else{
- sqlite3_result_text(pCtx, res.z, res.n-1, sqlite3_free);
- }
- return;
-}
-
-/*
-** Implementation of matchinfo() function.
-*/
-SQLITE_PRIVATE void sqlite3Fts3Matchinfo(
- sqlite3_context *pContext, /* Function call context */
- Fts3Cursor *pCsr, /* FTS3 table cursor */
- const char *zArg /* Second arg to matchinfo() function */
-){
- Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
- int rc;
- int i;
- const char *zFormat;
-
- if( zArg ){
- for(i=0; zArg[i]; i++){
- char *zErr = 0;
- if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
- sqlite3_result_error(pContext, zErr, -1);
- sqlite3_free(zErr);
- return;
- }
- }
- zFormat = zArg;
- }else{
- zFormat = FTS3_MATCHINFO_DEFAULT;
- }
-
- if( !pCsr->pExpr ){
- sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC);
- return;
- }
-
- /* Retrieve matchinfo() data. */
- rc = fts3GetMatchinfo(pCsr, zFormat);
- sqlite3Fts3SegmentsClose(pTab);
-
- if( rc!=SQLITE_OK ){
- sqlite3_result_error_code(pContext, rc);
- }else{
- int n = pCsr->nMatchinfo * sizeof(u32);
- sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
- }
-}
-
-#endif
-
-/************** End of fts3_snippet.c ****************************************/
-/************** Begin file fts3_unicode.c ************************************/
-/*
-** 2012 May 24
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** Implementation of the "unicode" full-text-search tokenizer.
-*/
-
-#ifdef SQLITE_ENABLE_FTS4_UNICODE61
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-
-/* #include <assert.h> */
-/* #include <stdlib.h> */
-/* #include <stdio.h> */
-/* #include <string.h> */
-
-
-/*
-** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied
-** from the sqlite3 source file utf.c. If this file is compiled as part
-** of the amalgamation, they are not required.
-*/
-#ifndef SQLITE_AMALGAMATION
-
-static const unsigned char sqlite3Utf8Trans1[] = {
- 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,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
-};
-
-#define READ_UTF8(zIn, zTerm, c) \
- c = *(zIn++); \
- if( c>=0xc0 ){ \
- c = sqlite3Utf8Trans1[c-0xc0]; \
- while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
- c = (c<<6) + (0x3f & *(zIn++)); \
- } \
- if( c<0x80 \
- || (c&0xFFFFF800)==0xD800 \
- || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
- }
-
-#define WRITE_UTF8(zOut, c) { \
- if( c<0x00080 ){ \
- *zOut++ = (u8)(c&0xFF); \
- } \
- else if( c<0x00800 ){ \
- *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \
- *zOut++ = 0x80 + (u8)(c & 0x3F); \
- } \
- else if( c<0x10000 ){ \
- *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \
- *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
- *zOut++ = 0x80 + (u8)(c & 0x3F); \
- }else{ \
- *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \
- *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \
- *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
- *zOut++ = 0x80 + (u8)(c & 0x3F); \
- } \
-}
-
-#endif /* ifndef SQLITE_AMALGAMATION */
-
-typedef struct unicode_tokenizer unicode_tokenizer;
-typedef struct unicode_cursor unicode_cursor;
-
-struct unicode_tokenizer {
- sqlite3_tokenizer base;
- int bRemoveDiacritic;
- int nException;
- int *aiException;
-};
-
-struct unicode_cursor {
- sqlite3_tokenizer_cursor base;
- const unsigned char *aInput; /* Input text being tokenized */
- int nInput; /* Size of aInput[] in bytes */
- int iOff; /* Current offset within aInput[] */
- int iToken; /* Index of next token to be returned */
- char *zToken; /* storage for current token */
- int nAlloc; /* space allocated at zToken */
-};
-
-
-/*
-** Destroy a tokenizer allocated by unicodeCreate().
-*/
-static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){
- if( pTokenizer ){
- unicode_tokenizer *p = (unicode_tokenizer *)pTokenizer;
- sqlite3_free(p->aiException);
- sqlite3_free(p);
- }
- return SQLITE_OK;
-}
-
-/*
-** As part of a tokenchars= or separators= option, the CREATE VIRTUAL TABLE
-** statement has specified that the tokenizer for this table shall consider
-** all characters in string zIn/nIn to be separators (if bAlnum==0) or
-** token characters (if bAlnum==1).
-**
-** For each codepoint in the zIn/nIn string, this function checks if the
-** sqlite3FtsUnicodeIsalnum() function already returns the desired result.
-** If so, no action is taken. Otherwise, the codepoint is added to the
-** unicode_tokenizer.aiException[] array. For the purposes of tokenization,
-** the return value of sqlite3FtsUnicodeIsalnum() is inverted for all
-** codepoints in the aiException[] array.
-**
-** If a standalone diacritic mark (one that sqlite3FtsUnicodeIsdiacritic()
-** identifies as a diacritic) occurs in the zIn/nIn string it is ignored.
-** It is not possible to change the behaviour of the tokenizer with respect
-** to these codepoints.
-*/
-static int unicodeAddExceptions(
- unicode_tokenizer *p, /* Tokenizer to add exceptions to */
- int bAlnum, /* Replace Isalnum() return value with this */
- const char *zIn, /* Array of characters to make exceptions */
- int nIn /* Length of z in bytes */
-){
- const unsigned char *z = (const unsigned char *)zIn;
- const unsigned char *zTerm = &z[nIn];
- int iCode;
- int nEntry = 0;
-
- assert( bAlnum==0 || bAlnum==1 );
-
- while( z<zTerm ){
- READ_UTF8(z, zTerm, iCode);
- assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
- if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
- && sqlite3FtsUnicodeIsdiacritic(iCode)==0
- ){
- nEntry++;
- }
- }
-
- if( nEntry ){
- int *aNew; /* New aiException[] array */
- int nNew; /* Number of valid entries in array aNew[] */
-
- aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int));
- if( aNew==0 ) return SQLITE_NOMEM;
- nNew = p->nException;
-
- z = (const unsigned char *)zIn;
- while( z<zTerm ){
- READ_UTF8(z, zTerm, iCode);
- if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
- && sqlite3FtsUnicodeIsdiacritic(iCode)==0
- ){
- int i, j;
- for(i=0; i<nNew && aNew[i]<iCode; i++);
- for(j=nNew; j>i; j--) aNew[j] = aNew[j-1];
- aNew[i] = iCode;
- nNew++;
- }
- }
- p->aiException = aNew;
- p->nException = nNew;
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Return true if the p->aiException[] array contains the value iCode.
-*/
-static int unicodeIsException(unicode_tokenizer *p, int iCode){
- if( p->nException>0 ){
- int *a = p->aiException;
- int iLo = 0;
- int iHi = p->nException-1;
-
- while( iHi>=iLo ){
- int iTest = (iHi + iLo) / 2;
- if( iCode==a[iTest] ){
- return 1;
- }else if( iCode>a[iTest] ){
- iLo = iTest+1;
- }else{
- iHi = iTest-1;
- }
- }
- }
-
- return 0;
-}
-
-/*
-** Return true if, for the purposes of tokenization, codepoint iCode is
-** considered a token character (not a separator).
-*/
-static int unicodeIsAlnum(unicode_tokenizer *p, int iCode){
- assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
- return sqlite3FtsUnicodeIsalnum(iCode) ^ unicodeIsException(p, iCode);
-}
-
-/*
-** Create a new tokenizer instance.
-*/
-static int unicodeCreate(
- int nArg, /* Size of array argv[] */
- const char * const *azArg, /* Tokenizer creation arguments */
- sqlite3_tokenizer **pp /* OUT: New tokenizer handle */
-){
- unicode_tokenizer *pNew; /* New tokenizer object */
- int i;
- int rc = SQLITE_OK;
-
- pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
- if( pNew==NULL ) return SQLITE_NOMEM;
- memset(pNew, 0, sizeof(unicode_tokenizer));
- pNew->bRemoveDiacritic = 1;
-
- for(i=0; rc==SQLITE_OK && i<nArg; i++){
- const char *z = azArg[i];
- int n = strlen(z);
-
- if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
- pNew->bRemoveDiacritic = 1;
- }
- else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){
- pNew->bRemoveDiacritic = 0;
- }
- else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){
- rc = unicodeAddExceptions(pNew, 1, &z[11], n-11);
- }
- else if( n>=11 && memcmp("separators=", z, 11)==0 ){
- rc = unicodeAddExceptions(pNew, 0, &z[11], n-11);
- }
- else{
- /* Unrecognized argument */
- rc = SQLITE_ERROR;
- }
- }
-
- if( rc!=SQLITE_OK ){
- unicodeDestroy((sqlite3_tokenizer *)pNew);
- pNew = 0;
- }
- *pp = (sqlite3_tokenizer *)pNew;
- return rc;
-}
-
-/*
-** Prepare to begin tokenizing a particular string. The input
-** string to be tokenized is pInput[0..nBytes-1]. A cursor
-** used to incrementally tokenize this string is returned in
-** *ppCursor.
-*/
-static int unicodeOpen(
- sqlite3_tokenizer *p, /* The tokenizer */
- const char *aInput, /* Input string */
- int nInput, /* Size of string aInput in bytes */
- sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */
-){
- unicode_cursor *pCsr;
-
- pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor));
- if( pCsr==0 ){
- return SQLITE_NOMEM;
- }
- memset(pCsr, 0, sizeof(unicode_cursor));
-
- pCsr->aInput = (const unsigned char *)aInput;
- if( aInput==0 ){
- pCsr->nInput = 0;
- }else if( nInput<0 ){
- pCsr->nInput = (int)strlen(aInput);
- }else{
- pCsr->nInput = nInput;
- }
-
- *pp = &pCsr->base;
- UNUSED_PARAMETER(p);
- return SQLITE_OK;
-}
-
-/*
-** Close a tokenization cursor previously opened by a call to
-** simpleOpen() above.
-*/
-static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){
- unicode_cursor *pCsr = (unicode_cursor *) pCursor;
- sqlite3_free(pCsr->zToken);
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-/*
-** Extract the next token from a tokenization cursor. The cursor must
-** have been opened by a prior call to simpleOpen().
-*/
-static int unicodeNext(
- sqlite3_tokenizer_cursor *pC, /* Cursor returned by simpleOpen */
- const char **paToken, /* OUT: Token text */
- int *pnToken, /* OUT: Number of bytes at *paToken */
- int *piStart, /* OUT: Starting offset of token */
- int *piEnd, /* OUT: Ending offset of token */
- int *piPos /* OUT: Position integer of token */
-){
- unicode_cursor *pCsr = (unicode_cursor *)pC;
- unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
- int iCode;
- char *zOut;
- const unsigned char *z = &pCsr->aInput[pCsr->iOff];
- const unsigned char *zStart = z;
- const unsigned char *zEnd;
- const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput];
-
- /* Scan past any delimiter characters before the start of the next token.
- ** Return SQLITE_DONE early if this takes us all the way to the end of
- ** the input. */
- while( z<zTerm ){
- READ_UTF8(z, zTerm, iCode);
- if( unicodeIsAlnum(p, iCode) ) break;
- zStart = z;
- }
- if( zStart>=zTerm ) return SQLITE_DONE;
-
- zOut = pCsr->zToken;
- do {
- int iOut;
-
- /* Grow the output buffer if required. */
- if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
- char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
- if( !zNew ) return SQLITE_NOMEM;
- zOut = &zNew[zOut - pCsr->zToken];
- pCsr->zToken = zNew;
- pCsr->nAlloc += 64;
- }
-
- /* Write the folded case of the last character read to the output */
- zEnd = z;
- iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic);
- if( iOut ){
- WRITE_UTF8(zOut, iOut);
- }
-
- /* If the cursor is not at EOF, read the next character */
- if( z>=zTerm ) break;
- READ_UTF8(z, zTerm, iCode);
- }while( unicodeIsAlnum(p, iCode)
- || sqlite3FtsUnicodeIsdiacritic(iCode)
- );
-
- /* Set the output variables and return. */
- pCsr->iOff = (z - pCsr->aInput);
- *paToken = pCsr->zToken;
- *pnToken = zOut - pCsr->zToken;
- *piStart = (zStart - pCsr->aInput);
- *piEnd = (zEnd - pCsr->aInput);
- *piPos = pCsr->iToken++;
- return SQLITE_OK;
-}
-
-/*
-** Set *ppModule to a pointer to the sqlite3_tokenizer_module
-** structure for the unicode tokenizer.
-*/
-SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){
- static const sqlite3_tokenizer_module module = {
- 0,
- unicodeCreate,
- unicodeDestroy,
- unicodeOpen,
- unicodeClose,
- unicodeNext,
- 0,
- };
- *ppModule = &module;
-}
-
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-#endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */
-
-/************** End of fts3_unicode.c ****************************************/
-/************** Begin file fts3_unicode2.c ***********************************/
-/*
-** 2012 May 25
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-*/
-
-/*
-** DO NOT EDIT THIS MACHINE GENERATED FILE.
-*/
-
-#if defined(SQLITE_ENABLE_FTS4_UNICODE61)
-#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
-
-/* #include <assert.h> */
-
-/*
-** Return true if the argument corresponds to a unicode codepoint
-** classified as either a letter or a number. Otherwise false.
-**
-** The results are undefined if the value passed to this function
-** is less than zero.
-*/
-SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
- /* Each unsigned integer in the following array corresponds to a contiguous
- ** range of unicode codepoints that are not either letters or numbers (i.e.
- ** codepoints for which this function should return 0).
- **
- ** The most significant 22 bits in each 32-bit value contain the first
- ** codepoint in the range. The least significant 10 bits are used to store
- ** the size of the range (always at least 1). In other words, the value
- ** ((C<<22) + N) represents a range of N codepoints starting with codepoint
- ** C. It is not possible to represent a range larger than 1023 codepoints
- ** using this format.
- */
- const static unsigned int aEntry[] = {
- 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
- 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
- 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
- 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
- 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
- 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
- 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
- 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401,
- 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804,
- 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
- 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812,
- 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001,
- 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802,
- 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805,
- 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401,
- 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
- 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807,
- 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
- 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
- 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804,
- 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001,
- 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
- 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01,
- 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06,
- 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007,
- 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006,
- 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417,
- 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14,
- 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07,
- 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01,
- 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001,
- 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802,
- 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F,
- 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002,
- 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802,
- 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006,
- 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D,
- 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802,
- 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027,
- 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
- 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805,
- 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04,
- 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
- 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
- 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B,
- 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A,
- 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
- 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59,
- 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
- 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
- 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
- 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
- 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
- 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
- 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
- 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012,
- 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004,
- 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002,
- 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
- 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
- 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
- 0x037FFC02, 0x03E3FC01, 0x03EC7801, 0x03ECA401, 0x03EEC810,
- 0x03F4F802, 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023,
- 0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807,
- 0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405,
- 0x04040003, 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E,
- 0x040E7C01, 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01,
- 0x04280403, 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01,
- 0x04294009, 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016,
- 0x04420003, 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004,
- 0x04460003, 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004,
- 0x05BD442E, 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5,
- 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01,
- 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401,
- 0x075EA401, 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064,
- 0x07C2800F, 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F,
- 0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009,
- 0x07C94002, 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014,
- 0x07CE8025, 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001,
- 0x07D108B6, 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018,
- 0x07D7EC46, 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401,
- 0x38008060, 0x380400F0, 0x3C000001, 0x3FFFF401, 0x40000001,
- 0x43FFF401,
- };
- static const unsigned int aAscii[4] = {
- 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
- };
-
- if( c<128 ){
- return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
- }else if( c<(1<<22) ){
- unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
- int iRes;
- int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
- int iLo = 0;
- while( iHi>=iLo ){
- int iTest = (iHi + iLo) / 2;
- if( key >= aEntry[iTest] ){
- iRes = iTest;
- iLo = iTest+1;
- }else{
- iHi = iTest-1;
- }
- }
- assert( aEntry[0]<key );
- assert( key>=aEntry[iRes] );
- return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
- }
- return 1;
-}
-
-
-/*
-** If the argument is a codepoint corresponding to a lowercase letter
-** in the ASCII range with a diacritic added, return the codepoint
-** of the ASCII letter only. For example, if passed 235 - "LATIN
-** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER
-** E"). The resuls of passing a codepoint that corresponds to an
-** uppercase letter are undefined.
-*/
-static int remove_diacritic(int c){
- unsigned short aDia[] = {
- 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
- 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
- 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
- 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
- 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
- 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
- 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
- 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
- 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
- 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
- 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
- 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
- 62924, 63050, 63082, 63274, 63390,
- };
- char aChar[] = {
- '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
- 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
- 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
- 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
- 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
- '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
- 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
- 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
- 'e', 'i', 'o', 'u', 'y',
- };
-
- unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
- int iRes = 0;
- int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
- int iLo = 0;
- while( iHi>=iLo ){
- int iTest = (iHi + iLo) / 2;
- if( key >= aDia[iTest] ){
- iRes = iTest;
- iLo = iTest+1;
- }else{
- iHi = iTest-1;
- }
- }
- assert( key>=aDia[iRes] );
- return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
-};
-
-
-/*
-** Return true if the argument interpreted as a unicode codepoint
-** is a diacritical modifier character.
-*/
-SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
- unsigned int mask0 = 0x08029FDF;
- unsigned int mask1 = 0x000361F8;
- if( c<768 || c>817 ) return 0;
- return (c < 768+32) ?
- (mask0 & (1 << (c-768))) :
- (mask1 & (1 << (c-768-32)));
-}
-
-
-/*
-** Interpret the argument as a unicode codepoint. If the codepoint
-** is an upper case character that has a lower case equivalent,
-** return the codepoint corresponding to the lower case version.
-** Otherwise, return a copy of the argument.
-**
-** The results are undefined if the value passed to this function
-** is less than zero.
-*/
-SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
- /* Each entry in the following array defines a rule for folding a range
- ** of codepoints to lower case. The rule applies to a range of nRange
- ** codepoints starting at codepoint iCode.
- **
- ** If the least significant bit in flags is clear, then the rule applies
- ** to all nRange codepoints (i.e. all nRange codepoints are upper case and
- ** need to be folded). Or, if it is set, then the rule only applies to
- ** every second codepoint in the range, starting with codepoint C.
- **
- ** The 7 most significant bits in flags are an index into the aiOff[]
- ** array. If a specific codepoint C does require folding, then its lower
- ** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF).
- **
- ** The contents of this array are generated by parsing the CaseFolding.txt
- ** file distributed as part of the "Unicode Character Database". See
- ** http://www.unicode.org for details.
- */
- static const struct TableEntry {
- unsigned short iCode;
- unsigned char flags;
- unsigned char nRange;
- } aEntry[] = {
- {65, 14, 26}, {181, 64, 1}, {192, 14, 23},
- {216, 14, 7}, {256, 1, 48}, {306, 1, 6},
- {313, 1, 16}, {330, 1, 46}, {376, 116, 1},
- {377, 1, 6}, {383, 104, 1}, {385, 50, 1},
- {386, 1, 4}, {390, 44, 1}, {391, 0, 1},
- {393, 42, 2}, {395, 0, 1}, {398, 32, 1},
- {399, 38, 1}, {400, 40, 1}, {401, 0, 1},
- {403, 42, 1}, {404, 46, 1}, {406, 52, 1},
- {407, 48, 1}, {408, 0, 1}, {412, 52, 1},
- {413, 54, 1}, {415, 56, 1}, {416, 1, 6},
- {422, 60, 1}, {423, 0, 1}, {425, 60, 1},
- {428, 0, 1}, {430, 60, 1}, {431, 0, 1},
- {433, 58, 2}, {435, 1, 4}, {439, 62, 1},
- {440, 0, 1}, {444, 0, 1}, {452, 2, 1},
- {453, 0, 1}, {455, 2, 1}, {456, 0, 1},
- {458, 2, 1}, {459, 1, 18}, {478, 1, 18},
- {497, 2, 1}, {498, 1, 4}, {502, 122, 1},
- {503, 134, 1}, {504, 1, 40}, {544, 110, 1},
- {546, 1, 18}, {570, 70, 1}, {571, 0, 1},
- {573, 108, 1}, {574, 68, 1}, {577, 0, 1},
- {579, 106, 1}, {580, 28, 1}, {581, 30, 1},
- {582, 1, 10}, {837, 36, 1}, {880, 1, 4},
- {886, 0, 1}, {902, 18, 1}, {904, 16, 3},
- {908, 26, 1}, {910, 24, 2}, {913, 14, 17},
- {931, 14, 9}, {962, 0, 1}, {975, 4, 1},
- {976, 140, 1}, {977, 142, 1}, {981, 146, 1},
- {982, 144, 1}, {984, 1, 24}, {1008, 136, 1},
- {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1},
- {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1},
- {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32},
- {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1},
- {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38},
- {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1},
- {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1},
- {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6},
- {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6},
- {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8},
- {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2},
- {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1},
- {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2},
- {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2},
- {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2},
- {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1},
- {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16},
- {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47},
- {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1},
- {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1},
- {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1},
- {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2},
- {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1},
- {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14},
- {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1},
- {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1},
- {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1},
- {65313, 14, 26},
- };
- static const unsigned short aiOff[] = {
- 1, 2, 8, 15, 16, 26, 28, 32,
- 37, 38, 40, 48, 63, 64, 69, 71,
- 79, 80, 116, 202, 203, 205, 206, 207,
- 209, 210, 211, 213, 214, 217, 218, 219,
- 775, 7264, 10792, 10795, 23228, 23256, 30204, 54721,
- 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274,
- 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406,
- 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462,
- 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511,
- 65514, 65521, 65527, 65528, 65529,
- };
-
- int ret = c;
-
- assert( c>=0 );
- assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
-
- if( c<128 ){
- if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
- }else if( c<65536 ){
- int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
- int iLo = 0;
- int iRes = -1;
-
- while( iHi>=iLo ){
- int iTest = (iHi + iLo) / 2;
- int cmp = (c - aEntry[iTest].iCode);
- if( cmp>=0 ){
- iRes = iTest;
- iLo = iTest+1;
- }else{
- iHi = iTest-1;
- }
- }
- assert( iRes<0 || c>=aEntry[iRes].iCode );
-
- if( iRes>=0 ){
- const struct TableEntry *p = &aEntry[iRes];
- if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
- ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
- assert( ret>0 );
- }
- }
-
- if( bRemoveDiacritic ) ret = remove_diacritic(ret);
- }
-
- else if( c>=66560 && c<66600 ){
- ret = c + 40;
- }
-
- return ret;
-}
-#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
-#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */
-
-/************** End of fts3_unicode2.c ***************************************/
-/************** Begin file rtree.c *******************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file contains code for implementations of the r-tree and r*-tree
-** algorithms packaged as an SQLite virtual table module.
-*/
-
-/*
-** Database Format of R-Tree Tables
-** --------------------------------
-**
-** The data structure for a single virtual r-tree table is stored in three
-** native SQLite tables declared as follows. In each case, the '%' character
-** in the table name is replaced with the user-supplied name of the r-tree
-** table.
-**
-** CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB)
-** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
-** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
-**
-** The data for each node of the r-tree structure is stored in the %_node
-** table. For each node that is not the root node of the r-tree, there is
-** an entry in the %_parent table associating the node with its parent.
-** And for each row of data in the table, there is an entry in the %_rowid
-** table that maps from the entries rowid to the id of the node that it
-** is stored on.
-**
-** The root node of an r-tree always exists, even if the r-tree table is
-** empty. The nodeno of the root node is always 1. All other nodes in the
-** table must be the same size as the root node. The content of each node
-** is formatted as follows:
-**
-** 1. If the node is the root node (node 1), then the first 2 bytes
-** of the node contain the tree depth as a big-endian integer.
-** For non-root nodes, the first 2 bytes are left unused.
-**
-** 2. The next 2 bytes contain the number of entries currently
-** stored in the node.
-**
-** 3. The remainder of the node contains the node entries. Each entry
-** consists of a single 8-byte integer followed by an even number
-** of 4-byte coordinates. For leaf nodes the integer is the rowid
-** of a record. For internal nodes it is the node number of a
-** child page.
-*/
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
-
-/*
-** This file contains an implementation of a couple of different variants
-** of the r-tree algorithm. See the README file for further details. The
-** same data-structure is used for all, but the algorithms for insert and
-** delete operations vary. The variants used are selected at compile time
-** by defining the following symbols:
-*/
-
-/* Either, both or none of the following may be set to activate
-** r*tree variant algorithms.
-*/
-#define VARIANT_RSTARTREE_CHOOSESUBTREE 0
-#define VARIANT_RSTARTREE_REINSERT 1
-
-/*
-** Exactly one of the following must be set to 1.
-*/
-#define VARIANT_GUTTMAN_QUADRATIC_SPLIT 0
-#define VARIANT_GUTTMAN_LINEAR_SPLIT 0
-#define VARIANT_RSTARTREE_SPLIT 1
-
-#define VARIANT_GUTTMAN_SPLIT \
- (VARIANT_GUTTMAN_LINEAR_SPLIT||VARIANT_GUTTMAN_QUADRATIC_SPLIT)
-
-#if VARIANT_GUTTMAN_QUADRATIC_SPLIT
- #define PickNext QuadraticPickNext
- #define PickSeeds QuadraticPickSeeds
- #define AssignCells splitNodeGuttman
-#endif
-#if VARIANT_GUTTMAN_LINEAR_SPLIT
- #define PickNext LinearPickNext
- #define PickSeeds LinearPickSeeds
- #define AssignCells splitNodeGuttman
-#endif
-#if VARIANT_RSTARTREE_SPLIT
- #define AssignCells splitNodeStartree
-#endif
-
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
-# define NDEBUG 1
-#endif
-
-#ifndef SQLITE_CORE
- SQLITE_EXTENSION_INIT1
-#else
-#endif
-
-/* #include <string.h> */
-/* #include <assert.h> */
-
-#ifndef SQLITE_AMALGAMATION
-#include "sqlite3rtree.h"
-typedef sqlite3_int64 i64;
-typedef unsigned char u8;
-typedef unsigned int u32;
-#endif
-
-/* The following macro is used to suppress compiler warnings.
-*/
-#ifndef UNUSED_PARAMETER
-# define UNUSED_PARAMETER(x) (void)(x)
-#endif
-
-typedef struct Rtree Rtree;
-typedef struct RtreeCursor RtreeCursor;
-typedef struct RtreeNode RtreeNode;
-typedef struct RtreeCell RtreeCell;
-typedef struct RtreeConstraint RtreeConstraint;
-typedef struct RtreeMatchArg RtreeMatchArg;
-typedef struct RtreeGeomCallback RtreeGeomCallback;
-typedef union RtreeCoord RtreeCoord;
-
-/* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */
-#define RTREE_MAX_DIMENSIONS 5
-
-/* Size of hash table Rtree.aHash. This hash table is not expected to
-** ever contain very many entries, so a fixed number of buckets is
-** used.
-*/
-#define HASHSIZE 128
-
-/*
-** An rtree virtual-table object.
-*/
-struct Rtree {
- sqlite3_vtab base;
- sqlite3 *db; /* Host database connection */
- int iNodeSize; /* Size in bytes of each node in the node table */
- int nDim; /* Number of dimensions */
- int nBytesPerCell; /* Bytes consumed per cell */
- int iDepth; /* Current depth of the r-tree structure */
- char *zDb; /* Name of database containing r-tree table */
- char *zName; /* Name of r-tree table */
- RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */
- int nBusy; /* Current number of users of this structure */
-
- /* List of nodes removed during a CondenseTree operation. List is
- ** linked together via the pointer normally used for hash chains -
- ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree
- ** headed by the node (leaf nodes have RtreeNode.iNode==0).
- */
- RtreeNode *pDeleted;
- int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */
-
- /* Statements to read/write/delete a record from xxx_node */
- sqlite3_stmt *pReadNode;
- sqlite3_stmt *pWriteNode;
- sqlite3_stmt *pDeleteNode;
-
- /* Statements to read/write/delete a record from xxx_rowid */
- sqlite3_stmt *pReadRowid;
- sqlite3_stmt *pWriteRowid;
- sqlite3_stmt *pDeleteRowid;
-
- /* Statements to read/write/delete a record from xxx_parent */
- sqlite3_stmt *pReadParent;
- sqlite3_stmt *pWriteParent;
- sqlite3_stmt *pDeleteParent;
-
- int eCoordType;
-};
-
-/* Possible values for eCoordType: */
-#define RTREE_COORD_REAL32 0
-#define RTREE_COORD_INT32 1
-
-/*
-** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will
-** only deal with integer coordinates. No floating point operations
-** will be done.
-*/
-#ifdef SQLITE_RTREE_INT_ONLY
- typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */
- typedef int RtreeValue; /* Low accuracy coordinate */
-#else
- typedef double RtreeDValue; /* High accuracy coordinate */
- typedef float RtreeValue; /* Low accuracy coordinate */
-#endif
-
-/*
-** The minimum number of cells allowed for a node is a third of the
-** maximum. In Gutman's notation:
-**
-** m = M/3
-**
-** If an R*-tree "Reinsert" operation is required, the same number of
-** cells are removed from the overfull node and reinserted into the tree.
-*/
-#define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3)
-#define RTREE_REINSERT(p) RTREE_MINCELLS(p)
-#define RTREE_MAXCELLS 51
-
-/*
-** The smallest possible node-size is (512-64)==448 bytes. And the largest
-** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates).
-** Therefore all non-root nodes must contain at least 3 entries. Since
-** 2^40 is greater than 2^64, an r-tree structure always has a depth of
-** 40 or less.
-*/
-#define RTREE_MAX_DEPTH 40
-
-/*
-** An rtree cursor object.
-*/
-struct RtreeCursor {
- sqlite3_vtab_cursor base;
- RtreeNode *pNode; /* Node cursor is currently pointing at */
- int iCell; /* Index of current cell in pNode */
- int iStrategy; /* Copy of idxNum search parameter */
- int nConstraint; /* Number of entries in aConstraint */
- RtreeConstraint *aConstraint; /* Search constraints. */
-};
-
-union RtreeCoord {
- RtreeValue f;
- int i;
-};
-
-/*
-** The argument is an RtreeCoord. Return the value stored within the RtreeCoord
-** formatted as a RtreeDValue (double or int64). This macro assumes that local
-** variable pRtree points to the Rtree structure associated with the
-** RtreeCoord.
-*/
-#ifdef SQLITE_RTREE_INT_ONLY
-# define DCOORD(coord) ((RtreeDValue)coord.i)
-#else
-# define DCOORD(coord) ( \
- (pRtree->eCoordType==RTREE_COORD_REAL32) ? \
- ((double)coord.f) : \
- ((double)coord.i) \
- )
-#endif
-
-/*
-** A search constraint.
-*/
-struct RtreeConstraint {
- int iCoord; /* Index of constrained coordinate */
- int op; /* Constraining operation */
- RtreeDValue rValue; /* Constraint value. */
- int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
- sqlite3_rtree_geometry *pGeom; /* Constraint callback argument for a MATCH */
-};
-
-/* Possible values for RtreeConstraint.op */
-#define RTREE_EQ 0x41
-#define RTREE_LE 0x42
-#define RTREE_LT 0x43
-#define RTREE_GE 0x44
-#define RTREE_GT 0x45
-#define RTREE_MATCH 0x46
-
-/*
-** An rtree structure node.
-*/
-struct RtreeNode {
- RtreeNode *pParent; /* Parent node */
- i64 iNode;
- int nRef;
- int isDirty;
- u8 *zData;
- RtreeNode *pNext; /* Next node in this hash chain */
-};
-#define NCELL(pNode) readInt16(&(pNode)->zData[2])
-
-/*
-** Structure to store a deserialized rtree record.
-*/
-struct RtreeCell {
- i64 iRowid;
- RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2];
-};
-
-
-/*
-** Value for the first field of every RtreeMatchArg object. The MATCH
-** operator tests that the first field of a blob operand matches this
-** value to avoid operating on invalid blobs (which could cause a segfault).
-*/
-#define RTREE_GEOMETRY_MAGIC 0x891245AB
-
-/*
-** An instance of this structure must be supplied as a blob argument to
-** the right-hand-side of an SQL MATCH operator used to constrain an
-** r-tree query.
-*/
-struct RtreeMatchArg {
- u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
- int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *);
- void *pContext;
- int nParam;
- RtreeDValue aParam[1];
-};
-
-/*
-** When a geometry callback is created (see sqlite3_rtree_geometry_callback),
-** a single instance of the following structure is allocated. It is used
-** as the context for the user-function created by by s_r_g_c(). The object
-** is eventually deleted by the destructor mechanism provided by
-** sqlite3_create_function_v2() (which is called by s_r_g_c() to create
-** the geometry callback function).
-*/
-struct RtreeGeomCallback {
- int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
- void *pContext;
-};
-
-#ifndef MAX
-# define MAX(x,y) ((x) < (y) ? (y) : (x))
-#endif
-#ifndef MIN
-# define MIN(x,y) ((x) > (y) ? (y) : (x))
-#endif
-
-/*
-** Functions to deserialize a 16 bit integer, 32 bit real number and
-** 64 bit integer. The deserialized value is returned.
-*/
-static int readInt16(u8 *p){
- return (p[0]<<8) + p[1];
-}
-static void readCoord(u8 *p, RtreeCoord *pCoord){
- u32 i = (
- (((u32)p[0]) << 24) +
- (((u32)p[1]) << 16) +
- (((u32)p[2]) << 8) +
- (((u32)p[3]) << 0)
- );
- *(u32 *)pCoord = i;
-}
-static i64 readInt64(u8 *p){
- return (
- (((i64)p[0]) << 56) +
- (((i64)p[1]) << 48) +
- (((i64)p[2]) << 40) +
- (((i64)p[3]) << 32) +
- (((i64)p[4]) << 24) +
- (((i64)p[5]) << 16) +
- (((i64)p[6]) << 8) +
- (((i64)p[7]) << 0)
- );
-}
-
-/*
-** Functions to serialize a 16 bit integer, 32 bit real number and
-** 64 bit integer. The value returned is the number of bytes written
-** to the argument buffer (always 2, 4 and 8 respectively).
-*/
-static int writeInt16(u8 *p, int i){
- p[0] = (i>> 8)&0xFF;
- p[1] = (i>> 0)&0xFF;
- return 2;
-}
-static int writeCoord(u8 *p, RtreeCoord *pCoord){
- u32 i;
- assert( sizeof(RtreeCoord)==4 );
- assert( sizeof(u32)==4 );
- i = *(u32 *)pCoord;
- p[0] = (i>>24)&0xFF;
- p[1] = (i>>16)&0xFF;
- p[2] = (i>> 8)&0xFF;
- p[3] = (i>> 0)&0xFF;
- return 4;
-}
-static int writeInt64(u8 *p, i64 i){
- p[0] = (i>>56)&0xFF;
- p[1] = (i>>48)&0xFF;
- p[2] = (i>>40)&0xFF;
- p[3] = (i>>32)&0xFF;
- p[4] = (i>>24)&0xFF;
- p[5] = (i>>16)&0xFF;
- p[6] = (i>> 8)&0xFF;
- p[7] = (i>> 0)&0xFF;
- return 8;
-}
-
-/*
-** Increment the reference count of node p.
-*/
-static void nodeReference(RtreeNode *p){
- if( p ){
- p->nRef++;
- }
-}
-
-/*
-** Clear the content of node p (set all bytes to 0x00).
-*/
-static void nodeZero(Rtree *pRtree, RtreeNode *p){
- memset(&p->zData[2], 0, pRtree->iNodeSize-2);
- p->isDirty = 1;
-}
-
-/*
-** Given a node number iNode, return the corresponding key to use
-** in the Rtree.aHash table.
-*/
-static int nodeHash(i64 iNode){
- return (
- (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^
- (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0)
- ) % HASHSIZE;
-}
-
-/*
-** Search the node hash table for node iNode. If found, return a pointer
-** to it. Otherwise, return 0.
-*/
-static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){
- RtreeNode *p;
- for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext);
- return p;
-}
-
-/*
-** Add node pNode to the node hash table.
-*/
-static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){
- int iHash;
- assert( pNode->pNext==0 );
- iHash = nodeHash(pNode->iNode);
- pNode->pNext = pRtree->aHash[iHash];
- pRtree->aHash[iHash] = pNode;
-}
-
-/*
-** Remove node pNode from the node hash table.
-*/
-static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){
- RtreeNode **pp;
- if( pNode->iNode!=0 ){
- pp = &pRtree->aHash[nodeHash(pNode->iNode)];
- for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); }
- *pp = pNode->pNext;
- pNode->pNext = 0;
- }
-}
-
-/*
-** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0),
-** indicating that node has not yet been assigned a node number. It is
-** assigned a node number when nodeWrite() is called to write the
-** node contents out to the database.
-*/
-static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
- RtreeNode *pNode;
- pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
- if( pNode ){
- memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize);
- pNode->zData = (u8 *)&pNode[1];
- pNode->nRef = 1;
- pNode->pParent = pParent;
- pNode->isDirty = 1;
- nodeReference(pParent);
- }
- return pNode;
-}
-
-/*
-** Obtain a reference to an r-tree node.
-*/
-static int
-nodeAcquire(
- Rtree *pRtree, /* R-tree structure */
- i64 iNode, /* Node number to load */
- RtreeNode *pParent, /* Either the parent node or NULL */
- RtreeNode **ppNode /* OUT: Acquired node */
-){
- int rc;
- int rc2 = SQLITE_OK;
- RtreeNode *pNode;
-
- /* Check if the requested node is already in the hash table. If so,
- ** increase its reference count and return it.
- */
- if( (pNode = nodeHashLookup(pRtree, iNode)) ){
- assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
- if( pParent && !pNode->pParent ){
- nodeReference(pParent);
- pNode->pParent = pParent;
- }
- pNode->nRef++;
- *ppNode = pNode;
- return SQLITE_OK;
- }
-
- sqlite3_bind_int64(pRtree->pReadNode, 1, iNode);
- rc = sqlite3_step(pRtree->pReadNode);
- if( rc==SQLITE_ROW ){
- const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0);
- if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){
- pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
- if( !pNode ){
- rc2 = SQLITE_NOMEM;
- }else{
- pNode->pParent = pParent;
- pNode->zData = (u8 *)&pNode[1];
- pNode->nRef = 1;
- pNode->iNode = iNode;
- pNode->isDirty = 0;
- pNode->pNext = 0;
- memcpy(pNode->zData, zBlob, pRtree->iNodeSize);
- nodeReference(pParent);
- }
- }
- }
- rc = sqlite3_reset(pRtree->pReadNode);
- if( rc==SQLITE_OK ) rc = rc2;
-
- /* If the root node was just loaded, set pRtree->iDepth to the height
- ** of the r-tree structure. A height of zero means all data is stored on
- ** the root node. A height of one means the children of the root node
- ** are the leaves, and so on. If the depth as specified on the root node
- ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
- */
- if( pNode && iNode==1 ){
- pRtree->iDepth = readInt16(pNode->zData);
- if( pRtree->iDepth>RTREE_MAX_DEPTH ){
- rc = SQLITE_CORRUPT_VTAB;
- }
- }
-
- /* If no error has occurred so far, check if the "number of entries"
- ** field on the node is too large. If so, set the return code to
- ** SQLITE_CORRUPT_VTAB.
- */
- if( pNode && rc==SQLITE_OK ){
- if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){
- rc = SQLITE_CORRUPT_VTAB;
- }
- }
-
- if( rc==SQLITE_OK ){
- if( pNode!=0 ){
- nodeHashInsert(pRtree, pNode);
- }else{
- rc = SQLITE_CORRUPT_VTAB;
- }
- *ppNode = pNode;
- }else{
- sqlite3_free(pNode);
- *ppNode = 0;
- }
-
- return rc;
-}
-
-/*
-** Overwrite cell iCell of node pNode with the contents of pCell.
-*/
-static void nodeOverwriteCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell,
- int iCell
-){
- int ii;
- u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
- p += writeInt64(p, pCell->iRowid);
- for(ii=0; ii<(pRtree->nDim*2); ii++){
- p += writeCoord(p, &pCell->aCoord[ii]);
- }
- pNode->isDirty = 1;
-}
-
-/*
-** Remove cell the cell with index iCell from node pNode.
-*/
-static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){
- u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
- u8 *pSrc = &pDst[pRtree->nBytesPerCell];
- int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell;
- memmove(pDst, pSrc, nByte);
- writeInt16(&pNode->zData[2], NCELL(pNode)-1);
- pNode->isDirty = 1;
-}
-
-/*
-** Insert the contents of cell pCell into node pNode. If the insert
-** is successful, return SQLITE_OK.
-**
-** If there is not enough free space in pNode, return SQLITE_FULL.
-*/
-static int
-nodeInsertCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell
-){
- int nCell; /* Current number of cells in pNode */
- int nMaxCell; /* Maximum number of cells for pNode */
-
- nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell;
- nCell = NCELL(pNode);
-
- assert( nCell<=nMaxCell );
- if( nCell<nMaxCell ){
- nodeOverwriteCell(pRtree, pNode, pCell, nCell);
- writeInt16(&pNode->zData[2], nCell+1);
- pNode->isDirty = 1;
- }
-
- return (nCell==nMaxCell);
-}
-
-/*
-** If the node is dirty, write it out to the database.
-*/
-static int
-nodeWrite(Rtree *pRtree, RtreeNode *pNode){
- int rc = SQLITE_OK;
- if( pNode->isDirty ){
- sqlite3_stmt *p = pRtree->pWriteNode;
- if( pNode->iNode ){
- sqlite3_bind_int64(p, 1, pNode->iNode);
- }else{
- sqlite3_bind_null(p, 1);
- }
- sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC);
- sqlite3_step(p);
- pNode->isDirty = 0;
- rc = sqlite3_reset(p);
- if( pNode->iNode==0 && rc==SQLITE_OK ){
- pNode->iNode = sqlite3_last_insert_rowid(pRtree->db);
- nodeHashInsert(pRtree, pNode);
- }
- }
- return rc;
-}
-
-/*
-** Release a reference to a node. If the node is dirty and the reference
-** count drops to zero, the node data is written to the database.
-*/
-static int
-nodeRelease(Rtree *pRtree, RtreeNode *pNode){
- int rc = SQLITE_OK;
- if( pNode ){
- assert( pNode->nRef>0 );
- pNode->nRef--;
- if( pNode->nRef==0 ){
- if( pNode->iNode==1 ){
- pRtree->iDepth = -1;
- }
- if( pNode->pParent ){
- rc = nodeRelease(pRtree, pNode->pParent);
- }
- if( rc==SQLITE_OK ){
- rc = nodeWrite(pRtree, pNode);
- }
- nodeHashDelete(pRtree, pNode);
- sqlite3_free(pNode);
- }
- }
- return rc;
-}
-
-/*
-** Return the 64-bit integer value associated with cell iCell of
-** node pNode. If pNode is a leaf node, this is a rowid. If it is
-** an internal node, then the 64-bit integer is a child page number.
-*/
-static i64 nodeGetRowid(
- Rtree *pRtree,
- RtreeNode *pNode,
- int iCell
-){
- assert( iCell<NCELL(pNode) );
- return readInt64(&pNode->zData[4 + pRtree->nBytesPerCell*iCell]);
-}
-
-/*
-** Return coordinate iCoord from cell iCell in node pNode.
-*/
-static void nodeGetCoord(
- Rtree *pRtree,
- RtreeNode *pNode,
- int iCell,
- int iCoord,
- RtreeCoord *pCoord /* Space to write result to */
-){
- readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord);
-}
-
-/*
-** Deserialize cell iCell of node pNode. Populate the structure pointed
-** to by pCell with the results.
-*/
-static void nodeGetCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- int iCell,
- RtreeCell *pCell
-){
- int ii;
- pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
- for(ii=0; ii<pRtree->nDim*2; ii++){
- nodeGetCoord(pRtree, pNode, iCell, ii, &pCell->aCoord[ii]);
- }
-}
-
-
-/* Forward declaration for the function that does the work of
-** the virtual table module xCreate() and xConnect() methods.
-*/
-static int rtreeInit(
- sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int
-);
-
-/*
-** Rtree virtual table module xCreate method.
-*/
-static int rtreeCreate(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1);
-}
-
-/*
-** Rtree virtual table module xConnect method.
-*/
-static int rtreeConnect(
- sqlite3 *db,
- void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVtab,
- char **pzErr
-){
- return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0);
-}
-
-/*
-** Increment the r-tree reference count.
-*/
-static void rtreeReference(Rtree *pRtree){
- pRtree->nBusy++;
-}
-
-/*
-** Decrement the r-tree reference count. When the reference count reaches
-** zero the structure is deleted.
-*/
-static void rtreeRelease(Rtree *pRtree){
- pRtree->nBusy--;
- if( pRtree->nBusy==0 ){
- sqlite3_finalize(pRtree->pReadNode);
- sqlite3_finalize(pRtree->pWriteNode);
- sqlite3_finalize(pRtree->pDeleteNode);
- sqlite3_finalize(pRtree->pReadRowid);
- sqlite3_finalize(pRtree->pWriteRowid);
- sqlite3_finalize(pRtree->pDeleteRowid);
- sqlite3_finalize(pRtree->pReadParent);
- sqlite3_finalize(pRtree->pWriteParent);
- sqlite3_finalize(pRtree->pDeleteParent);
- sqlite3_free(pRtree);
- }
-}
-
-/*
-** Rtree virtual table module xDisconnect method.
-*/
-static int rtreeDisconnect(sqlite3_vtab *pVtab){
- rtreeRelease((Rtree *)pVtab);
- return SQLITE_OK;
-}
-
-/*
-** Rtree virtual table module xDestroy method.
-*/
-static int rtreeDestroy(sqlite3_vtab *pVtab){
- Rtree *pRtree = (Rtree *)pVtab;
- int rc;
- char *zCreate = sqlite3_mprintf(
- "DROP TABLE '%q'.'%q_node';"
- "DROP TABLE '%q'.'%q_rowid';"
- "DROP TABLE '%q'.'%q_parent';",
- pRtree->zDb, pRtree->zName,
- pRtree->zDb, pRtree->zName,
- pRtree->zDb, pRtree->zName
- );
- if( !zCreate ){
- rc = SQLITE_NOMEM;
- }else{
- rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0);
- sqlite3_free(zCreate);
- }
- if( rc==SQLITE_OK ){
- rtreeRelease(pRtree);
- }
-
- return rc;
-}
-
-/*
-** Rtree virtual table module xOpen method.
-*/
-static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
- int rc = SQLITE_NOMEM;
- RtreeCursor *pCsr;
-
- pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
- if( pCsr ){
- memset(pCsr, 0, sizeof(RtreeCursor));
- pCsr->base.pVtab = pVTab;
- rc = SQLITE_OK;
- }
- *ppCursor = (sqlite3_vtab_cursor *)pCsr;
-
- return rc;
-}
-
-
-/*
-** Free the RtreeCursor.aConstraint[] array and its contents.
-*/
-static void freeCursorConstraints(RtreeCursor *pCsr){
- if( pCsr->aConstraint ){
- int i; /* Used to iterate through constraint array */
- for(i=0; i<pCsr->nConstraint; i++){
- sqlite3_rtree_geometry *pGeom = pCsr->aConstraint[i].pGeom;
- if( pGeom ){
- if( pGeom->xDelUser ) pGeom->xDelUser(pGeom->pUser);
- sqlite3_free(pGeom);
- }
- }
- sqlite3_free(pCsr->aConstraint);
- pCsr->aConstraint = 0;
- }
-}
-
-/*
-** Rtree virtual table module xClose method.
-*/
-static int rtreeClose(sqlite3_vtab_cursor *cur){
- Rtree *pRtree = (Rtree *)(cur->pVtab);
- int rc;
- RtreeCursor *pCsr = (RtreeCursor *)cur;
- freeCursorConstraints(pCsr);
- rc = nodeRelease(pRtree, pCsr->pNode);
- sqlite3_free(pCsr);
- return rc;
-}
-
-/*
-** Rtree virtual table module xEof method.
-**
-** Return non-zero if the cursor does not currently point to a valid
-** record (i.e if the scan has finished), or zero otherwise.
-*/
-static int rtreeEof(sqlite3_vtab_cursor *cur){
- RtreeCursor *pCsr = (RtreeCursor *)cur;
- return (pCsr->pNode==0);
-}
-
-/*
-** The r-tree constraint passed as the second argument to this function is
-** guaranteed to be a MATCH constraint.
-*/
-static int testRtreeGeom(
- Rtree *pRtree, /* R-Tree object */
- RtreeConstraint *pConstraint, /* MATCH constraint to test */
- RtreeCell *pCell, /* Cell to test */
- int *pbRes /* OUT: Test result */
-){
- int i;
- RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2];
- int nCoord = pRtree->nDim*2;
-
- assert( pConstraint->op==RTREE_MATCH );
- assert( pConstraint->pGeom );
-
- for(i=0; i<nCoord; i++){
- aCoord[i] = DCOORD(pCell->aCoord[i]);
- }
- return pConstraint->xGeom(pConstraint->pGeom, nCoord, aCoord, pbRes);
-}
-
-/*
-** Cursor pCursor currently points to a cell in a non-leaf page.
-** Set *pbEof to true if the sub-tree headed by the cell is filtered
-** (excluded) by the constraints in the pCursor->aConstraint[]
-** array, or false otherwise.
-**
-** Return SQLITE_OK if successful or an SQLite error code if an error
-** occurs within a geometry callback.
-*/
-static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){
- RtreeCell cell;
- int ii;
- int bRes = 0;
- int rc = SQLITE_OK;
-
- nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
- for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){
- RtreeConstraint *p = &pCursor->aConstraint[ii];
- RtreeDValue cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
- RtreeDValue cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]);
-
- assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
- || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
- );
-
- switch( p->op ){
- case RTREE_LE: case RTREE_LT:
- bRes = p->rValue<cell_min;
- break;
-
- case RTREE_GE: case RTREE_GT:
- bRes = p->rValue>cell_max;
- break;
-
- case RTREE_EQ:
- bRes = (p->rValue>cell_max || p->rValue<cell_min);
- break;
-
- default: {
- assert( p->op==RTREE_MATCH );
- rc = testRtreeGeom(pRtree, p, &cell, &bRes);
- bRes = !bRes;
- break;
- }
- }
- }
-
- *pbEof = bRes;
- return rc;
-}
-
-/*
-** Test if the cell that cursor pCursor currently points to
-** would be filtered (excluded) by the constraints in the
-** pCursor->aConstraint[] array. If so, set *pbEof to true before
-** returning. If the cell is not filtered (excluded) by the constraints,
-** set pbEof to zero.
-**
-** Return SQLITE_OK if successful or an SQLite error code if an error
-** occurs within a geometry callback.
-**
-** This function assumes that the cell is part of a leaf node.
-*/
-static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){
- RtreeCell cell;
- int ii;
- *pbEof = 0;
-
- nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
- for(ii=0; ii<pCursor->nConstraint; ii++){
- RtreeConstraint *p = &pCursor->aConstraint[ii];
- RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]);
- int res;
- assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
- || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
- );
- switch( p->op ){
- case RTREE_LE: res = (coord<=p->rValue); break;
- case RTREE_LT: res = (coord<p->rValue); break;
- case RTREE_GE: res = (coord>=p->rValue); break;
- case RTREE_GT: res = (coord>p->rValue); break;
- case RTREE_EQ: res = (coord==p->rValue); break;
- default: {
- int rc;
- assert( p->op==RTREE_MATCH );
- rc = testRtreeGeom(pRtree, p, &cell, &res);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- break;
- }
- }
-
- if( !res ){
- *pbEof = 1;
- return SQLITE_OK;
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Cursor pCursor currently points at a node that heads a sub-tree of
-** height iHeight (if iHeight==0, then the node is a leaf). Descend
-** to point to the left-most cell of the sub-tree that matches the
-** configured constraints.
-*/
-static int descendToCell(
- Rtree *pRtree,
- RtreeCursor *pCursor,
- int iHeight,
- int *pEof /* OUT: Set to true if cannot descend */
-){
- int isEof;
- int rc;
- int ii;
- RtreeNode *pChild;
- sqlite3_int64 iRowid;
-
- RtreeNode *pSavedNode = pCursor->pNode;
- int iSavedCell = pCursor->iCell;
-
- assert( iHeight>=0 );
-
- if( iHeight==0 ){
- rc = testRtreeEntry(pRtree, pCursor, &isEof);
- }else{
- rc = testRtreeCell(pRtree, pCursor, &isEof);
- }
- if( rc!=SQLITE_OK || isEof || iHeight==0 ){
- goto descend_to_cell_out;
- }
-
- iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell);
- rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild);
- if( rc!=SQLITE_OK ){
- goto descend_to_cell_out;
- }
-
- nodeRelease(pRtree, pCursor->pNode);
- pCursor->pNode = pChild;
- isEof = 1;
- for(ii=0; isEof && ii<NCELL(pChild); ii++){
- pCursor->iCell = ii;
- rc = descendToCell(pRtree, pCursor, iHeight-1, &isEof);
- if( rc!=SQLITE_OK ){
- goto descend_to_cell_out;
- }
- }
-
- if( isEof ){
- assert( pCursor->pNode==pChild );
- nodeReference(pSavedNode);
- nodeRelease(pRtree, pChild);
- pCursor->pNode = pSavedNode;
- pCursor->iCell = iSavedCell;
- }
-
-descend_to_cell_out:
- *pEof = isEof;
- return rc;
-}
-
-/*
-** One of the cells in node pNode is guaranteed to have a 64-bit
-** integer value equal to iRowid. Return the index of this cell.
-*/
-static int nodeRowidIndex(
- Rtree *pRtree,
- RtreeNode *pNode,
- i64 iRowid,
- int *piIndex
-){
- int ii;
- int nCell = NCELL(pNode);
- for(ii=0; ii<nCell; ii++){
- if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){
- *piIndex = ii;
- return SQLITE_OK;
- }
- }
- return SQLITE_CORRUPT_VTAB;
-}
-
-/*
-** Return the index of the cell containing a pointer to node pNode
-** in its parent. If pNode is the root node, return -1.
-*/
-static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){
- RtreeNode *pParent = pNode->pParent;
- if( pParent ){
- return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex);
- }
- *piIndex = -1;
- return SQLITE_OK;
-}
-
-/*
-** Rtree virtual table module xNext method.
-*/
-static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){
- Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab);
- RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
- int rc = SQLITE_OK;
-
- /* RtreeCursor.pNode must not be NULL. If is is NULL, then this cursor is
- ** already at EOF. It is against the rules to call the xNext() method of
- ** a cursor that has already reached EOF.
- */
- assert( pCsr->pNode );
-
- if( pCsr->iStrategy==1 ){
- /* This "scan" is a direct lookup by rowid. There is no next entry. */
- nodeRelease(pRtree, pCsr->pNode);
- pCsr->pNode = 0;
- }else{
- /* Move to the next entry that matches the configured constraints. */
- int iHeight = 0;
- while( pCsr->pNode ){
- RtreeNode *pNode = pCsr->pNode;
- int nCell = NCELL(pNode);
- for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){
- int isEof;
- rc = descendToCell(pRtree, pCsr, iHeight, &isEof);
- if( rc!=SQLITE_OK || !isEof ){
- return rc;
- }
- }
- pCsr->pNode = pNode->pParent;
- rc = nodeParentIndex(pRtree, pNode, &pCsr->iCell);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- nodeReference(pCsr->pNode);
- nodeRelease(pRtree, pNode);
- iHeight++;
- }
- }
-
- return rc;
-}
-
-/*
-** Rtree virtual table module xRowid method.
-*/
-static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
- Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
- RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
-
- assert(pCsr->pNode);
- *pRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
-
- return SQLITE_OK;
-}
-
-/*
-** Rtree virtual table module xColumn method.
-*/
-static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
- Rtree *pRtree = (Rtree *)cur->pVtab;
- RtreeCursor *pCsr = (RtreeCursor *)cur;
-
- if( i==0 ){
- i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
- sqlite3_result_int64(ctx, iRowid);
- }else{
- RtreeCoord c;
- nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c);
-#ifndef SQLITE_RTREE_INT_ONLY
- if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- sqlite3_result_double(ctx, c.f);
- }else
-#endif
- {
- assert( pRtree->eCoordType==RTREE_COORD_INT32 );
- sqlite3_result_int(ctx, c.i);
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Use nodeAcquire() to obtain the leaf node containing the record with
-** rowid iRowid. If successful, set *ppLeaf to point to the node and
-** return SQLITE_OK. If there is no such record in the table, set
-** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf
-** to zero and return an SQLite error code.
-*/
-static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){
- int rc;
- *ppLeaf = 0;
- sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid);
- if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){
- i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0);
- rc = nodeAcquire(pRtree, iNode, 0, ppLeaf);
- sqlite3_reset(pRtree->pReadRowid);
- }else{
- rc = sqlite3_reset(pRtree->pReadRowid);
- }
- return rc;
-}
-
-/*
-** This function is called to configure the RtreeConstraint object passed
-** as the second argument for a MATCH constraint. The value passed as the
-** first argument to this function is the right-hand operand to the MATCH
-** operator.
-*/
-static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
- RtreeMatchArg *p;
- sqlite3_rtree_geometry *pGeom;
- int nBlob;
-
- /* Check that value is actually a blob. */
- if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
-
- /* Check that the blob is roughly the right size. */
- nBlob = sqlite3_value_bytes(pValue);
- if( nBlob<(int)sizeof(RtreeMatchArg)
- || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
- ){
- return SQLITE_ERROR;
- }
-
- pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc(
- sizeof(sqlite3_rtree_geometry) + nBlob
- );
- if( !pGeom ) return SQLITE_NOMEM;
- memset(pGeom, 0, sizeof(sqlite3_rtree_geometry));
- p = (RtreeMatchArg *)&pGeom[1];
-
- memcpy(p, sqlite3_value_blob(pValue), nBlob);
- if( p->magic!=RTREE_GEOMETRY_MAGIC
- || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue))
- ){
- sqlite3_free(pGeom);
- return SQLITE_ERROR;
- }
-
- pGeom->pContext = p->pContext;
- pGeom->nParam = p->nParam;
- pGeom->aParam = p->aParam;
-
- pCons->xGeom = p->xGeom;
- pCons->pGeom = pGeom;
- return SQLITE_OK;
-}
-
-/*
-** Rtree virtual table module xFilter method.
-*/
-static int rtreeFilter(
- sqlite3_vtab_cursor *pVtabCursor,
- int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv
-){
- Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
- RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
-
- RtreeNode *pRoot = 0;
- int ii;
- int rc = SQLITE_OK;
-
- rtreeReference(pRtree);
-
- freeCursorConstraints(pCsr);
- pCsr->iStrategy = idxNum;
-
- if( idxNum==1 ){
- /* Special case - lookup by rowid. */
- RtreeNode *pLeaf; /* Leaf on which the required cell resides */
- i64 iRowid = sqlite3_value_int64(argv[0]);
- rc = findLeafNode(pRtree, iRowid, &pLeaf);
- pCsr->pNode = pLeaf;
- if( pLeaf ){
- assert( rc==SQLITE_OK );
- rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &pCsr->iCell);
- }
- }else{
- /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array
- ** with the configured constraints.
- */
- if( argc>0 ){
- pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
- pCsr->nConstraint = argc;
- if( !pCsr->aConstraint ){
- rc = SQLITE_NOMEM;
- }else{
- memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc);
- assert( (idxStr==0 && argc==0)
- || (idxStr && (int)strlen(idxStr)==argc*2) );
- for(ii=0; ii<argc; ii++){
- RtreeConstraint *p = &pCsr->aConstraint[ii];
- p->op = idxStr[ii*2];
- p->iCoord = idxStr[ii*2+1]-'a';
- if( p->op==RTREE_MATCH ){
- /* A MATCH operator. The right-hand-side must be a blob that
- ** can be cast into an RtreeMatchArg object. One created using
- ** an sqlite3_rtree_geometry_callback() SQL user function.
- */
- rc = deserializeGeometry(argv[ii], p);
- if( rc!=SQLITE_OK ){
- break;
- }
- }else{
-#ifdef SQLITE_RTREE_INT_ONLY
- p->rValue = sqlite3_value_int64(argv[ii]);
-#else
- p->rValue = sqlite3_value_double(argv[ii]);
-#endif
- }
- }
- }
- }
-
- if( rc==SQLITE_OK ){
- pCsr->pNode = 0;
- rc = nodeAcquire(pRtree, 1, 0, &pRoot);
- }
- if( rc==SQLITE_OK ){
- int isEof = 1;
- int nCell = NCELL(pRoot);
- pCsr->pNode = pRoot;
- for(pCsr->iCell=0; rc==SQLITE_OK && pCsr->iCell<nCell; pCsr->iCell++){
- assert( pCsr->pNode==pRoot );
- rc = descendToCell(pRtree, pCsr, pRtree->iDepth, &isEof);
- if( !isEof ){
- break;
- }
- }
- if( rc==SQLITE_OK && isEof ){
- assert( pCsr->pNode==pRoot );
- nodeRelease(pRtree, pRoot);
- pCsr->pNode = 0;
- }
- assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) );
- }
- }
-
- rtreeRelease(pRtree);
- return rc;
-}
-
-/*
-** Rtree virtual table module xBestIndex method. There are three
-** table scan strategies to choose from (in order from most to
-** least desirable):
-**
-** idxNum idxStr Strategy
-** ------------------------------------------------
-** 1 Unused Direct lookup by rowid.
-** 2 See below R-tree query or full-table scan.
-** ------------------------------------------------
-**
-** If strategy 1 is used, then idxStr is not meaningful. If strategy
-** 2 is used, idxStr is formatted to contain 2 bytes for each
-** constraint used. The first two bytes of idxStr correspond to
-** the constraint in sqlite3_index_info.aConstraintUsage[] with
-** (argvIndex==1) etc.
-**
-** The first of each pair of bytes in idxStr identifies the constraint
-** operator as follows:
-**
-** Operator Byte Value
-** ----------------------
-** = 0x41 ('A')
-** <= 0x42 ('B')
-** < 0x43 ('C')
-** >= 0x44 ('D')
-** > 0x45 ('E')
-** MATCH 0x46 ('F')
-** ----------------------
-**
-** The second of each pair of bytes identifies the coordinate column
-** to which the constraint applies. The leftmost coordinate column
-** is 'a', the second from the left 'b' etc.
-*/
-static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
- int rc = SQLITE_OK;
- int ii;
-
- int iIdx = 0;
- char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
- memset(zIdxStr, 0, sizeof(zIdxStr));
- UNUSED_PARAMETER(tab);
-
- assert( pIdxInfo->idxStr==0 );
- for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
- struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
-
- if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
- /* We have an equality constraint on the rowid. Use strategy 1. */
- int jj;
- for(jj=0; jj<ii; jj++){
- pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
- pIdxInfo->aConstraintUsage[jj].omit = 0;
- }
- pIdxInfo->idxNum = 1;
- pIdxInfo->aConstraintUsage[ii].argvIndex = 1;
- pIdxInfo->aConstraintUsage[jj].omit = 1;
-
- /* This strategy involves a two rowid lookups on an B-Tree structures
- ** and then a linear search of an R-Tree node. This should be
- ** considered almost as quick as a direct rowid lookup (for which
- ** sqlite uses an internal cost of 0.0).
- */
- pIdxInfo->estimatedCost = 10.0;
- return SQLITE_OK;
- }
-
- if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
- u8 op;
- switch( p->op ){
- case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
- case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
- case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
- case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
- case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
- default:
- assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
- op = RTREE_MATCH;
- break;
- }
- zIdxStr[iIdx++] = op;
- zIdxStr[iIdx++] = p->iColumn - 1 + 'a';
- pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
- pIdxInfo->aConstraintUsage[ii].omit = 1;
- }
- }
-
- pIdxInfo->idxNum = 2;
- pIdxInfo->needToFreeIdxStr = 1;
- if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
- return SQLITE_NOMEM;
- }
- assert( iIdx>=0 );
- pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1));
- return rc;
-}
-
-/*
-** Return the N-dimensional volumn of the cell stored in *p.
-*/
-static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
- RtreeDValue area = (RtreeDValue)1;
- int ii;
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])));
- }
- return area;
-}
-
-/*
-** Return the margin length of cell p. The margin length is the sum
-** of the objects size in each dimension.
-*/
-static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
- RtreeDValue margin = (RtreeDValue)0;
- int ii;
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
- }
- return margin;
-}
-
-/*
-** Store the union of cells p1 and p2 in p1.
-*/
-static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
- int ii;
- if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f);
- p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f);
- }
- }else{
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i);
- p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i);
- }
- }
-}
-
-/*
-** Return true if the area covered by p2 is a subset of the area covered
-** by p1. False otherwise.
-*/
-static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
- int ii;
- int isInt = (pRtree->eCoordType==RTREE_COORD_INT32);
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- RtreeCoord *a1 = &p1->aCoord[ii];
- RtreeCoord *a2 = &p2->aCoord[ii];
- if( (!isInt && (a2[0].f<a1[0].f || a2[1].f>a1[1].f))
- || ( isInt && (a2[0].i<a1[0].i || a2[1].i>a1[1].i))
- ){
- return 0;
- }
- }
- return 1;
-}
-
-/*
-** Return the amount cell p would grow by if it were unioned with pCell.
-*/
-static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
- RtreeDValue area;
- RtreeCell cell;
- memcpy(&cell, p, sizeof(RtreeCell));
- area = cellArea(pRtree, &cell);
- cellUnion(pRtree, &cell, pCell);
- return (cellArea(pRtree, &cell)-area);
-}
-
-#if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT
-static RtreeDValue cellOverlap(
- Rtree *pRtree,
- RtreeCell *p,
- RtreeCell *aCell,
- int nCell,
- int iExclude
-){
- int ii;
- RtreeDValue overlap = 0.0;
- for(ii=0; ii<nCell; ii++){
-#if VARIANT_RSTARTREE_CHOOSESUBTREE
- if( ii!=iExclude )
-#else
- assert( iExclude==-1 );
- UNUSED_PARAMETER(iExclude);
-#endif
- {
- int jj;
- RtreeDValue o = (RtreeDValue)1;
- for(jj=0; jj<(pRtree->nDim*2); jj+=2){
- RtreeDValue x1, x2;
-
- x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
- x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
-
- if( x2<x1 ){
- o = 0.0;
- break;
- }else{
- o = o * (x2-x1);
- }
- }
- overlap += o;
- }
- }
- return overlap;
-}
-#endif
-
-#if VARIANT_RSTARTREE_CHOOSESUBTREE
-static RtreeDValue cellOverlapEnlargement(
- Rtree *pRtree,
- RtreeCell *p,
- RtreeCell *pInsert,
- RtreeCell *aCell,
- int nCell,
- int iExclude
-){
- RtreeDValue before, after;
- before = cellOverlap(pRtree, p, aCell, nCell, iExclude);
- cellUnion(pRtree, p, pInsert);
- after = cellOverlap(pRtree, p, aCell, nCell, iExclude);
- return (after-before);
-}
-#endif
-
-
-/*
-** This function implements the ChooseLeaf algorithm from Gutman[84].
-** ChooseSubTree in r*tree terminology.
-*/
-static int ChooseLeaf(
- Rtree *pRtree, /* Rtree table */
- RtreeCell *pCell, /* Cell to insert into rtree */
- int iHeight, /* Height of sub-tree rooted at pCell */
- RtreeNode **ppLeaf /* OUT: Selected leaf page */
-){
- int rc;
- int ii;
- RtreeNode *pNode;
- rc = nodeAcquire(pRtree, 1, 0, &pNode);
-
- for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
- int iCell;
- sqlite3_int64 iBest = 0;
-
- RtreeDValue fMinGrowth = 0.0;
- RtreeDValue fMinArea = 0.0;
-#if VARIANT_RSTARTREE_CHOOSESUBTREE
- RtreeDValue fMinOverlap = 0.0;
- RtreeDValue overlap;
-#endif
-
- int nCell = NCELL(pNode);
- RtreeCell cell;
- RtreeNode *pChild;
-
- RtreeCell *aCell = 0;
-
-#if VARIANT_RSTARTREE_CHOOSESUBTREE
- if( ii==(pRtree->iDepth-1) ){
- int jj;
- aCell = sqlite3_malloc(sizeof(RtreeCell)*nCell);
- if( !aCell ){
- rc = SQLITE_NOMEM;
- nodeRelease(pRtree, pNode);
- pNode = 0;
- continue;
- }
- for(jj=0; jj<nCell; jj++){
- nodeGetCell(pRtree, pNode, jj, &aCell[jj]);
- }
- }
-#endif
-
- /* Select the child node which will be enlarged the least if pCell
- ** is inserted into it. Resolve ties by choosing the entry with
- ** the smallest area.
- */
- for(iCell=0; iCell<nCell; iCell++){
- int bBest = 0;
- RtreeDValue growth;
- RtreeDValue area;
- nodeGetCell(pRtree, pNode, iCell, &cell);
- growth = cellGrowth(pRtree, &cell, pCell);
- area = cellArea(pRtree, &cell);
-
-#if VARIANT_RSTARTREE_CHOOSESUBTREE
- if( ii==(pRtree->iDepth-1) ){
- overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
- }else{
- overlap = 0.0;
- }
- if( (iCell==0)
- || (overlap<fMinOverlap)
- || (overlap==fMinOverlap && growth<fMinGrowth)
- || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
- ){
- bBest = 1;
- fMinOverlap = overlap;
- }
-#else
- if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){
- bBest = 1;
- }
-#endif
- if( bBest ){
- fMinGrowth = growth;
- fMinArea = area;
- iBest = cell.iRowid;
- }
- }
-
- sqlite3_free(aCell);
- rc = nodeAcquire(pRtree, iBest, pNode, &pChild);
- nodeRelease(pRtree, pNode);
- pNode = pChild;
- }
-
- *ppLeaf = pNode;
- return rc;
-}
-
-/*
-** A cell with the same content as pCell has just been inserted into
-** the node pNode. This function updates the bounding box cells in
-** all ancestor elements.
-*/
-static int AdjustTree(
- Rtree *pRtree, /* Rtree table */
- RtreeNode *pNode, /* Adjust ancestry of this node. */
- RtreeCell *pCell /* This cell was just inserted */
-){
- RtreeNode *p = pNode;
- while( p->pParent ){
- RtreeNode *pParent = p->pParent;
- RtreeCell cell;
- int iCell;
-
- if( nodeParentIndex(pRtree, p, &iCell) ){
- return SQLITE_CORRUPT_VTAB;
- }
-
- nodeGetCell(pRtree, pParent, iCell, &cell);
- if( !cellContains(pRtree, &cell, pCell) ){
- cellUnion(pRtree, &cell, pCell);
- nodeOverwriteCell(pRtree, pParent, &cell, iCell);
- }
-
- p = pParent;
- }
- return SQLITE_OK;
-}
-
-/*
-** Write mapping (iRowid->iNode) to the <rtree>_rowid table.
-*/
-static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){
- sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid);
- sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode);
- sqlite3_step(pRtree->pWriteRowid);
- return sqlite3_reset(pRtree->pWriteRowid);
-}
-
-/*
-** Write mapping (iNode->iPar) to the <rtree>_parent table.
-*/
-static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){
- sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode);
- sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar);
- sqlite3_step(pRtree->pWriteParent);
- return sqlite3_reset(pRtree->pWriteParent);
-}
-
-static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int);
-
-#if VARIANT_GUTTMAN_LINEAR_SPLIT
-/*
-** Implementation of the linear variant of the PickNext() function from
-** Guttman[84].
-*/
-static RtreeCell *LinearPickNext(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- RtreeCell *pLeftBox,
- RtreeCell *pRightBox,
- int *aiUsed
-){
- int ii;
- for(ii=0; aiUsed[ii]; ii++);
- aiUsed[ii] = 1;
- return &aCell[ii];
-}
-
-/*
-** Implementation of the linear variant of the PickSeeds() function from
-** Guttman[84].
-*/
-static void LinearPickSeeds(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- int *piLeftSeed,
- int *piRightSeed
-){
- int i;
- int iLeftSeed = 0;
- int iRightSeed = 1;
- RtreeDValue maxNormalInnerWidth = (RtreeDValue)0;
-
- /* Pick two "seed" cells from the array of cells. The algorithm used
- ** here is the LinearPickSeeds algorithm from Gutman[1984]. The
- ** indices of the two seed cells in the array are stored in local
- ** variables iLeftSeek and iRightSeed.
- */
- for(i=0; i<pRtree->nDim; i++){
- RtreeDValue x1 = DCOORD(aCell[0].aCoord[i*2]);
- RtreeDValue x2 = DCOORD(aCell[0].aCoord[i*2+1]);
- RtreeDValue x3 = x1;
- RtreeDValue x4 = x2;
- int jj;
-
- int iCellLeft = 0;
- int iCellRight = 0;
-
- for(jj=1; jj<nCell; jj++){
- RtreeDValue left = DCOORD(aCell[jj].aCoord[i*2]);
- RtreeDValue right = DCOORD(aCell[jj].aCoord[i*2+1]);
-
- if( left<x1 ) x1 = left;
- if( right>x4 ) x4 = right;
- if( left>x3 ){
- x3 = left;
- iCellRight = jj;
- }
- if( right<x2 ){
- x2 = right;
- iCellLeft = jj;
- }
- }
-
- if( x4!=x1 ){
- RtreeDValue normalwidth = (x3 - x2) / (x4 - x1);
- if( normalwidth>maxNormalInnerWidth ){
- iLeftSeed = iCellLeft;
- iRightSeed = iCellRight;
- }
- }
- }
-
- *piLeftSeed = iLeftSeed;
- *piRightSeed = iRightSeed;
-}
-#endif /* VARIANT_GUTTMAN_LINEAR_SPLIT */
-
-#if VARIANT_GUTTMAN_QUADRATIC_SPLIT
-/*
-** Implementation of the quadratic variant of the PickNext() function from
-** Guttman[84].
-*/
-static RtreeCell *QuadraticPickNext(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- RtreeCell *pLeftBox,
- RtreeCell *pRightBox,
- int *aiUsed
-){
- #define FABS(a) ((a)<0.0?-1.0*(a):(a))
-
- int iSelect = -1;
- RtreeDValue fDiff;
- int ii;
- for(ii=0; ii<nCell; ii++){
- if( aiUsed[ii]==0 ){
- RtreeDValue left = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
- RtreeDValue right = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
- RtreeDValue diff = FABS(right-left);
- if( iSelect<0 || diff>fDiff ){
- fDiff = diff;
- iSelect = ii;
- }
- }
- }
- aiUsed[iSelect] = 1;
- return &aCell[iSelect];
-}
-
-/*
-** Implementation of the quadratic variant of the PickSeeds() function from
-** Guttman[84].
-*/
-static void QuadraticPickSeeds(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- int *piLeftSeed,
- int *piRightSeed
-){
- int ii;
- int jj;
-
- int iLeftSeed = 0;
- int iRightSeed = 1;
- RtreeDValue fWaste = 0.0;
-
- for(ii=0; ii<nCell; ii++){
- for(jj=ii+1; jj<nCell; jj++){
- RtreeDValue right = cellArea(pRtree, &aCell[jj]);
- RtreeDValue growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]);
- RtreeDValue waste = growth - right;
-
- if( waste>fWaste ){
- iLeftSeed = ii;
- iRightSeed = jj;
- fWaste = waste;
- }
- }
- }
-
- *piLeftSeed = iLeftSeed;
- *piRightSeed = iRightSeed;
-}
-#endif /* VARIANT_GUTTMAN_QUADRATIC_SPLIT */
-
-/*
-** Arguments aIdx, aDistance and aSpare all point to arrays of size
-** nIdx. The aIdx array contains the set of integers from 0 to
-** (nIdx-1) in no particular order. This function sorts the values
-** in aIdx according to the indexed values in aDistance. For
-** example, assuming the inputs:
-**
-** aIdx = { 0, 1, 2, 3 }
-** aDistance = { 5.0, 2.0, 7.0, 6.0 }
-**
-** this function sets the aIdx array to contain:
-**
-** aIdx = { 0, 1, 2, 3 }
-**
-** The aSpare array is used as temporary working space by the
-** sorting algorithm.
-*/
-static void SortByDistance(
- int *aIdx,
- int nIdx,
- RtreeDValue *aDistance,
- int *aSpare
-){
- if( nIdx>1 ){
- int iLeft = 0;
- int iRight = 0;
-
- int nLeft = nIdx/2;
- int nRight = nIdx-nLeft;
- int *aLeft = aIdx;
- int *aRight = &aIdx[nLeft];
-
- SortByDistance(aLeft, nLeft, aDistance, aSpare);
- SortByDistance(aRight, nRight, aDistance, aSpare);
-
- memcpy(aSpare, aLeft, sizeof(int)*nLeft);
- aLeft = aSpare;
-
- while( iLeft<nLeft || iRight<nRight ){
- if( iLeft==nLeft ){
- aIdx[iLeft+iRight] = aRight[iRight];
- iRight++;
- }else if( iRight==nRight ){
- aIdx[iLeft+iRight] = aLeft[iLeft];
- iLeft++;
- }else{
- RtreeDValue fLeft = aDistance[aLeft[iLeft]];
- RtreeDValue fRight = aDistance[aRight[iRight]];
- if( fLeft<fRight ){
- aIdx[iLeft+iRight] = aLeft[iLeft];
- iLeft++;
- }else{
- aIdx[iLeft+iRight] = aRight[iRight];
- iRight++;
- }
- }
- }
-
-#if 0
- /* Check that the sort worked */
- {
- int jj;
- for(jj=1; jj<nIdx; jj++){
- RtreeDValue left = aDistance[aIdx[jj-1]];
- RtreeDValue right = aDistance[aIdx[jj]];
- assert( left<=right );
- }
- }
-#endif
- }
-}
-
-/*
-** Arguments aIdx, aCell and aSpare all point to arrays of size
-** nIdx. The aIdx array contains the set of integers from 0 to
-** (nIdx-1) in no particular order. This function sorts the values
-** in aIdx according to dimension iDim of the cells in aCell. The
-** minimum value of dimension iDim is considered first, the
-** maximum used to break ties.
-**
-** The aSpare array is used as temporary working space by the
-** sorting algorithm.
-*/
-static void SortByDimension(
- Rtree *pRtree,
- int *aIdx,
- int nIdx,
- int iDim,
- RtreeCell *aCell,
- int *aSpare
-){
- if( nIdx>1 ){
-
- int iLeft = 0;
- int iRight = 0;
-
- int nLeft = nIdx/2;
- int nRight = nIdx-nLeft;
- int *aLeft = aIdx;
- int *aRight = &aIdx[nLeft];
-
- SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare);
- SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare);
-
- memcpy(aSpare, aLeft, sizeof(int)*nLeft);
- aLeft = aSpare;
- while( iLeft<nLeft || iRight<nRight ){
- RtreeDValue xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]);
- RtreeDValue xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]);
- RtreeDValue xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]);
- RtreeDValue xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]);
- if( (iLeft!=nLeft) && ((iRight==nRight)
- || (xleft1<xright1)
- || (xleft1==xright1 && xleft2<xright2)
- )){
- aIdx[iLeft+iRight] = aLeft[iLeft];
- iLeft++;
- }else{
- aIdx[iLeft+iRight] = aRight[iRight];
- iRight++;
- }
- }
-
-#if 0
- /* Check that the sort worked */
- {
- int jj;
- for(jj=1; jj<nIdx; jj++){
- RtreeDValue xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2];
- RtreeDValue xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1];
- RtreeDValue xright1 = aCell[aIdx[jj]].aCoord[iDim*2];
- RtreeDValue xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1];
- assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) );
- }
- }
-#endif
- }
-}
-
-#if VARIANT_RSTARTREE_SPLIT
-/*
-** Implementation of the R*-tree variant of SplitNode from Beckman[1990].
-*/
-static int splitNodeStartree(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- RtreeNode *pLeft,
- RtreeNode *pRight,
- RtreeCell *pBboxLeft,
- RtreeCell *pBboxRight
-){
- int **aaSorted;
- int *aSpare;
- int ii;
-
- int iBestDim = 0;
- int iBestSplit = 0;
- RtreeDValue fBestMargin = 0.0;
-
- int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
-
- aaSorted = (int **)sqlite3_malloc(nByte);
- if( !aaSorted ){
- return SQLITE_NOMEM;
- }
-
- aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell];
- memset(aaSorted, 0, nByte);
- for(ii=0; ii<pRtree->nDim; ii++){
- int jj;
- aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell];
- for(jj=0; jj<nCell; jj++){
- aaSorted[ii][jj] = jj;
- }
- SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare);
- }
-
- for(ii=0; ii<pRtree->nDim; ii++){
- RtreeDValue margin = 0.0;
- RtreeDValue fBestOverlap = 0.0;
- RtreeDValue fBestArea = 0.0;
- int iBestLeft = 0;
- int nLeft;
-
- for(
- nLeft=RTREE_MINCELLS(pRtree);
- nLeft<=(nCell-RTREE_MINCELLS(pRtree));
- nLeft++
- ){
- RtreeCell left;
- RtreeCell right;
- int kk;
- RtreeDValue overlap;
- RtreeDValue area;
-
- memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell));
- memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell));
- for(kk=1; kk<(nCell-1); kk++){
- if( kk<nLeft ){
- cellUnion(pRtree, &left, &aCell[aaSorted[ii][kk]]);
- }else{
- cellUnion(pRtree, &right, &aCell[aaSorted[ii][kk]]);
- }
- }
- margin += cellMargin(pRtree, &left);
- margin += cellMargin(pRtree, &right);
- overlap = cellOverlap(pRtree, &left, &right, 1, -1);
- area = cellArea(pRtree, &left) + cellArea(pRtree, &right);
- if( (nLeft==RTREE_MINCELLS(pRtree))
- || (overlap<fBestOverlap)
- || (overlap==fBestOverlap && area<fBestArea)
- ){
- iBestLeft = nLeft;
- fBestOverlap = overlap;
- fBestArea = area;
- }
- }
-
- if( ii==0 || margin<fBestMargin ){
- iBestDim = ii;
- fBestMargin = margin;
- iBestSplit = iBestLeft;
- }
- }
-
- memcpy(pBboxLeft, &aCell[aaSorted[iBestDim][0]], sizeof(RtreeCell));
- memcpy(pBboxRight, &aCell[aaSorted[iBestDim][iBestSplit]], sizeof(RtreeCell));
- for(ii=0; ii<nCell; ii++){
- RtreeNode *pTarget = (ii<iBestSplit)?pLeft:pRight;
- RtreeCell *pBbox = (ii<iBestSplit)?pBboxLeft:pBboxRight;
- RtreeCell *pCell = &aCell[aaSorted[iBestDim][ii]];
- nodeInsertCell(pRtree, pTarget, pCell);
- cellUnion(pRtree, pBbox, pCell);
- }
-
- sqlite3_free(aaSorted);
- return SQLITE_OK;
-}
-#endif
-
-#if VARIANT_GUTTMAN_SPLIT
-/*
-** Implementation of the regular R-tree SplitNode from Guttman[1984].
-*/
-static int splitNodeGuttman(
- Rtree *pRtree,
- RtreeCell *aCell,
- int nCell,
- RtreeNode *pLeft,
- RtreeNode *pRight,
- RtreeCell *pBboxLeft,
- RtreeCell *pBboxRight
-){
- int iLeftSeed = 0;
- int iRightSeed = 1;
- int *aiUsed;
- int i;
-
- aiUsed = sqlite3_malloc(sizeof(int)*nCell);
- if( !aiUsed ){
- return SQLITE_NOMEM;
- }
- memset(aiUsed, 0, sizeof(int)*nCell);
-
- PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed);
-
- memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell));
- memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell));
- nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]);
- nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]);
- aiUsed[iLeftSeed] = 1;
- aiUsed[iRightSeed] = 1;
-
- for(i=nCell-2; i>0; i--){
- RtreeCell *pNext;
- pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed);
- RtreeDValue diff =
- cellGrowth(pRtree, pBboxLeft, pNext) -
- cellGrowth(pRtree, pBboxRight, pNext)
- ;
- if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i)
- || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i))
- ){
- nodeInsertCell(pRtree, pRight, pNext);
- cellUnion(pRtree, pBboxRight, pNext);
- }else{
- nodeInsertCell(pRtree, pLeft, pNext);
- cellUnion(pRtree, pBboxLeft, pNext);
- }
- }
-
- sqlite3_free(aiUsed);
- return SQLITE_OK;
-}
-#endif
-
-static int updateMapping(
- Rtree *pRtree,
- i64 iRowid,
- RtreeNode *pNode,
- int iHeight
-){
- int (*xSetMapping)(Rtree *, sqlite3_int64, sqlite3_int64);
- xSetMapping = ((iHeight==0)?rowidWrite:parentWrite);
- if( iHeight>0 ){
- RtreeNode *pChild = nodeHashLookup(pRtree, iRowid);
- if( pChild ){
- nodeRelease(pRtree, pChild->pParent);
- nodeReference(pNode);
- pChild->pParent = pNode;
- }
- }
- return xSetMapping(pRtree, iRowid, pNode->iNode);
-}
-
-static int SplitNode(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell,
- int iHeight
-){
- int i;
- int newCellIsRight = 0;
-
- int rc = SQLITE_OK;
- int nCell = NCELL(pNode);
- RtreeCell *aCell;
- int *aiUsed;
-
- RtreeNode *pLeft = 0;
- RtreeNode *pRight = 0;
-
- RtreeCell leftbbox;
- RtreeCell rightbbox;
-
- /* Allocate an array and populate it with a copy of pCell and
- ** all cells from node pLeft. Then zero the original node.
- */
- aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
- if( !aCell ){
- rc = SQLITE_NOMEM;
- goto splitnode_out;
- }
- aiUsed = (int *)&aCell[nCell+1];
- memset(aiUsed, 0, sizeof(int)*(nCell+1));
- for(i=0; i<nCell; i++){
- nodeGetCell(pRtree, pNode, i, &aCell[i]);
- }
- nodeZero(pRtree, pNode);
- memcpy(&aCell[nCell], pCell, sizeof(RtreeCell));
- nCell++;
-
- if( pNode->iNode==1 ){
- pRight = nodeNew(pRtree, pNode);
- pLeft = nodeNew(pRtree, pNode);
- pRtree->iDepth++;
- pNode->isDirty = 1;
- writeInt16(pNode->zData, pRtree->iDepth);
- }else{
- pLeft = pNode;
- pRight = nodeNew(pRtree, pLeft->pParent);
- nodeReference(pLeft);
- }
-
- if( !pLeft || !pRight ){
- rc = SQLITE_NOMEM;
- goto splitnode_out;
- }
-
- memset(pLeft->zData, 0, pRtree->iNodeSize);
- memset(pRight->zData, 0, pRtree->iNodeSize);
-
- rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox);
- if( rc!=SQLITE_OK ){
- goto splitnode_out;
- }
-
- /* Ensure both child nodes have node numbers assigned to them by calling
- ** nodeWrite(). Node pRight always needs a node number, as it was created
- ** by nodeNew() above. But node pLeft sometimes already has a node number.
- ** In this case avoid the all to nodeWrite().
- */
- if( SQLITE_OK!=(rc = nodeWrite(pRtree, pRight))
- || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft)))
- ){
- goto splitnode_out;
- }
-
- rightbbox.iRowid = pRight->iNode;
- leftbbox.iRowid = pLeft->iNode;
-
- if( pNode->iNode==1 ){
- rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1);
- if( rc!=SQLITE_OK ){
- goto splitnode_out;
- }
- }else{
- RtreeNode *pParent = pLeft->pParent;
- int iCell;
- rc = nodeParentIndex(pRtree, pLeft, &iCell);
- if( rc==SQLITE_OK ){
- nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell);
- rc = AdjustTree(pRtree, pParent, &leftbbox);
- }
- if( rc!=SQLITE_OK ){
- goto splitnode_out;
- }
- }
- if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){
- goto splitnode_out;
- }
-
- for(i=0; i<NCELL(pRight); i++){
- i64 iRowid = nodeGetRowid(pRtree, pRight, i);
- rc = updateMapping(pRtree, iRowid, pRight, iHeight);
- if( iRowid==pCell->iRowid ){
- newCellIsRight = 1;
- }
- if( rc!=SQLITE_OK ){
- goto splitnode_out;
- }
- }
- if( pNode->iNode==1 ){
- for(i=0; i<NCELL(pLeft); i++){
- i64 iRowid = nodeGetRowid(pRtree, pLeft, i);
- rc = updateMapping(pRtree, iRowid, pLeft, iHeight);
- if( rc!=SQLITE_OK ){
- goto splitnode_out;
- }
- }
- }else if( newCellIsRight==0 ){
- rc = updateMapping(pRtree, pCell->iRowid, pLeft, iHeight);
- }
-
- if( rc==SQLITE_OK ){
- rc = nodeRelease(pRtree, pRight);
- pRight = 0;
- }
- if( rc==SQLITE_OK ){
- rc = nodeRelease(pRtree, pLeft);
- pLeft = 0;
- }
-
-splitnode_out:
- nodeRelease(pRtree, pRight);
- nodeRelease(pRtree, pLeft);
- sqlite3_free(aCell);
- return rc;
-}
-
-/*
-** If node pLeaf is not the root of the r-tree and its pParent pointer is
-** still NULL, load all ancestor nodes of pLeaf into memory and populate
-** the pLeaf->pParent chain all the way up to the root node.
-**
-** This operation is required when a row is deleted (or updated - an update
-** is implemented as a delete followed by an insert). SQLite provides the
-** rowid of the row to delete, which can be used to find the leaf on which
-** the entry resides (argument pLeaf). Once the leaf is located, this
-** function is called to determine its ancestry.
-*/
-static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){
- int rc = SQLITE_OK;
- RtreeNode *pChild = pLeaf;
- while( rc==SQLITE_OK && pChild->iNode!=1 && pChild->pParent==0 ){
- int rc2 = SQLITE_OK; /* sqlite3_reset() return code */
- sqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode);
- rc = sqlite3_step(pRtree->pReadParent);
- if( rc==SQLITE_ROW ){
- RtreeNode *pTest; /* Used to test for reference loops */
- i64 iNode; /* Node number of parent node */
-
- /* Before setting pChild->pParent, test that we are not creating a
- ** loop of references (as we would if, say, pChild==pParent). We don't
- ** want to do this as it leads to a memory leak when trying to delete
- ** the referenced counted node structures.
- */
- iNode = sqlite3_column_int64(pRtree->pReadParent, 0);
- for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent);
- if( !pTest ){
- rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent);
- }
- }
- rc = sqlite3_reset(pRtree->pReadParent);
- if( rc==SQLITE_OK ) rc = rc2;
- if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB;
- pChild = pChild->pParent;
- }
- return rc;
-}
-
-static int deleteCell(Rtree *, RtreeNode *, int, int);
-
-static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
- int rc;
- int rc2;
- RtreeNode *pParent = 0;
- int iCell;
-
- assert( pNode->nRef==1 );
-
- /* Remove the entry in the parent cell. */
- rc = nodeParentIndex(pRtree, pNode, &iCell);
- if( rc==SQLITE_OK ){
- pParent = pNode->pParent;
- pNode->pParent = 0;
- rc = deleteCell(pRtree, pParent, iCell, iHeight+1);
- }
- rc2 = nodeRelease(pRtree, pParent);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* Remove the xxx_node entry. */
- sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode);
- sqlite3_step(pRtree->pDeleteNode);
- if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){
- return rc;
- }
-
- /* Remove the xxx_parent entry. */
- sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode);
- sqlite3_step(pRtree->pDeleteParent);
- if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){
- return rc;
- }
-
- /* Remove the node from the in-memory hash table and link it into
- ** the Rtree.pDeleted list. Its contents will be re-inserted later on.
- */
- nodeHashDelete(pRtree, pNode);
- pNode->iNode = iHeight;
- pNode->pNext = pRtree->pDeleted;
- pNode->nRef++;
- pRtree->pDeleted = pNode;
-
- return SQLITE_OK;
-}
-
-static int fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){
- RtreeNode *pParent = pNode->pParent;
- int rc = SQLITE_OK;
- if( pParent ){
- int ii;
- int nCell = NCELL(pNode);
- RtreeCell box; /* Bounding box for pNode */
- nodeGetCell(pRtree, pNode, 0, &box);
- for(ii=1; ii<nCell; ii++){
- RtreeCell cell;
- nodeGetCell(pRtree, pNode, ii, &cell);
- cellUnion(pRtree, &box, &cell);
- }
- box.iRowid = pNode->iNode;
- rc = nodeParentIndex(pRtree, pNode, &ii);
- if( rc==SQLITE_OK ){
- nodeOverwriteCell(pRtree, pParent, &box, ii);
- rc = fixBoundingBox(pRtree, pParent);
- }
- }
- return rc;
-}
-
-/*
-** Delete the cell at index iCell of node pNode. After removing the
-** cell, adjust the r-tree data structure if required.
-*/
-static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){
- RtreeNode *pParent;
- int rc;
-
- if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){
- return rc;
- }
-
- /* Remove the cell from the node. This call just moves bytes around
- ** the in-memory node image, so it cannot fail.
- */
- nodeDeleteCell(pRtree, pNode, iCell);
-
- /* If the node is not the tree root and now has less than the minimum
- ** number of cells, remove it from the tree. Otherwise, update the
- ** cell in the parent node so that it tightly contains the updated
- ** node.
- */
- pParent = pNode->pParent;
- assert( pParent || pNode->iNode==1 );
- if( pParent ){
- if( NCELL(pNode)<RTREE_MINCELLS(pRtree) ){
- rc = removeNode(pRtree, pNode, iHeight);
- }else{
- rc = fixBoundingBox(pRtree, pNode);
- }
- }
-
- return rc;
-}
-
-static int Reinsert(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell,
- int iHeight
-){
- int *aOrder;
- int *aSpare;
- RtreeCell *aCell;
- RtreeDValue *aDistance;
- int nCell;
- RtreeDValue aCenterCoord[RTREE_MAX_DIMENSIONS];
- int iDim;
- int ii;
- int rc = SQLITE_OK;
- int n;
-
- memset(aCenterCoord, 0, sizeof(RtreeDValue)*RTREE_MAX_DIMENSIONS);
-
- nCell = NCELL(pNode)+1;
- n = (nCell+1)&(~1);
-
- /* Allocate the buffers used by this operation. The allocation is
- ** relinquished before this function returns.
- */
- aCell = (RtreeCell *)sqlite3_malloc(n * (
- sizeof(RtreeCell) + /* aCell array */
- sizeof(int) + /* aOrder array */
- sizeof(int) + /* aSpare array */
- sizeof(RtreeDValue) /* aDistance array */
- ));
- if( !aCell ){
- return SQLITE_NOMEM;
- }
- aOrder = (int *)&aCell[n];
- aSpare = (int *)&aOrder[n];
- aDistance = (RtreeDValue *)&aSpare[n];
-
- for(ii=0; ii<nCell; ii++){
- if( ii==(nCell-1) ){
- memcpy(&aCell[ii], pCell, sizeof(RtreeCell));
- }else{
- nodeGetCell(pRtree, pNode, ii, &aCell[ii]);
- }
- aOrder[ii] = ii;
- for(iDim=0; iDim<pRtree->nDim; iDim++){
- aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]);
- aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]);
- }
- }
- for(iDim=0; iDim<pRtree->nDim; iDim++){
- aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2));
- }
-
- for(ii=0; ii<nCell; ii++){
- aDistance[ii] = 0.0;
- for(iDim=0; iDim<pRtree->nDim; iDim++){
- RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) -
- DCOORD(aCell[ii].aCoord[iDim*2]));
- aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]);
- }
- }
-
- SortByDistance(aOrder, nCell, aDistance, aSpare);
- nodeZero(pRtree, pNode);
-
- for(ii=0; rc==SQLITE_OK && ii<(nCell-(RTREE_MINCELLS(pRtree)+1)); ii++){
- RtreeCell *p = &aCell[aOrder[ii]];
- nodeInsertCell(pRtree, pNode, p);
- if( p->iRowid==pCell->iRowid ){
- if( iHeight==0 ){
- rc = rowidWrite(pRtree, p->iRowid, pNode->iNode);
- }else{
- rc = parentWrite(pRtree, p->iRowid, pNode->iNode);
- }
- }
- }
- if( rc==SQLITE_OK ){
- rc = fixBoundingBox(pRtree, pNode);
- }
- for(; rc==SQLITE_OK && ii<nCell; ii++){
- /* Find a node to store this cell in. pNode->iNode currently contains
- ** the height of the sub-tree headed by the cell.
- */
- RtreeNode *pInsert;
- RtreeCell *p = &aCell[aOrder[ii]];
- rc = ChooseLeaf(pRtree, p, iHeight, &pInsert);
- if( rc==SQLITE_OK ){
- int rc2;
- rc = rtreeInsertCell(pRtree, pInsert, p, iHeight);
- rc2 = nodeRelease(pRtree, pInsert);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
-
- sqlite3_free(aCell);
- return rc;
-}
-
-/*
-** Insert cell pCell into node pNode. Node pNode is the head of a
-** subtree iHeight high (leaf nodes have iHeight==0).
-*/
-static int rtreeInsertCell(
- Rtree *pRtree,
- RtreeNode *pNode,
- RtreeCell *pCell,
- int iHeight
-){
- int rc = SQLITE_OK;
- if( iHeight>0 ){
- RtreeNode *pChild = nodeHashLookup(pRtree, pCell->iRowid);
- if( pChild ){
- nodeRelease(pRtree, pChild->pParent);
- nodeReference(pNode);
- pChild->pParent = pNode;
- }
- }
- if( nodeInsertCell(pRtree, pNode, pCell) ){
-#if VARIANT_RSTARTREE_REINSERT
- if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){
- rc = SplitNode(pRtree, pNode, pCell, iHeight);
- }else{
- pRtree->iReinsertHeight = iHeight;
- rc = Reinsert(pRtree, pNode, pCell, iHeight);
- }
-#else
- rc = SplitNode(pRtree, pNode, pCell, iHeight);
-#endif
- }else{
- rc = AdjustTree(pRtree, pNode, pCell);
- if( rc==SQLITE_OK ){
- if( iHeight==0 ){
- rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode);
- }else{
- rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode);
- }
- }
- }
- return rc;
-}
-
-static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){
- int ii;
- int rc = SQLITE_OK;
- int nCell = NCELL(pNode);
-
- for(ii=0; rc==SQLITE_OK && ii<nCell; ii++){
- RtreeNode *pInsert;
- RtreeCell cell;
- nodeGetCell(pRtree, pNode, ii, &cell);
-
- /* Find a node to store this cell in. pNode->iNode currently contains
- ** the height of the sub-tree headed by the cell.
- */
- rc = ChooseLeaf(pRtree, &cell, (int)pNode->iNode, &pInsert);
- if( rc==SQLITE_OK ){
- int rc2;
- rc = rtreeInsertCell(pRtree, pInsert, &cell, (int)pNode->iNode);
- rc2 = nodeRelease(pRtree, pInsert);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
- return rc;
-}
-
-/*
-** Select a currently unused rowid for a new r-tree record.
-*/
-static int newRowid(Rtree *pRtree, i64 *piRowid){
- int rc;
- sqlite3_bind_null(pRtree->pWriteRowid, 1);
- sqlite3_bind_null(pRtree->pWriteRowid, 2);
- sqlite3_step(pRtree->pWriteRowid);
- rc = sqlite3_reset(pRtree->pWriteRowid);
- *piRowid = sqlite3_last_insert_rowid(pRtree->db);
- return rc;
-}
-
-/*
-** Remove the entry with rowid=iDelete from the r-tree structure.
-*/
-static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
- int rc; /* Return code */
- RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */
- int iCell; /* Index of iDelete cell in pLeaf */
- RtreeNode *pRoot; /* Root node of rtree structure */
-
-
- /* Obtain a reference to the root node to initialise Rtree.iDepth */
- rc = nodeAcquire(pRtree, 1, 0, &pRoot);
-
- /* Obtain a reference to the leaf node that contains the entry
- ** about to be deleted.
- */
- if( rc==SQLITE_OK ){
- rc = findLeafNode(pRtree, iDelete, &pLeaf);
- }
-
- /* Delete the cell in question from the leaf node. */
- if( rc==SQLITE_OK ){
- int rc2;
- rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell);
- if( rc==SQLITE_OK ){
- rc = deleteCell(pRtree, pLeaf, iCell, 0);
- }
- rc2 = nodeRelease(pRtree, pLeaf);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
-
- /* Delete the corresponding entry in the <rtree>_rowid table. */
- if( rc==SQLITE_OK ){
- sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete);
- sqlite3_step(pRtree->pDeleteRowid);
- rc = sqlite3_reset(pRtree->pDeleteRowid);
- }
-
- /* Check if the root node now has exactly one child. If so, remove
- ** it, schedule the contents of the child for reinsertion and
- ** reduce the tree height by one.
- **
- ** This is equivalent to copying the contents of the child into
- ** the root node (the operation that Gutman's paper says to perform
- ** in this scenario).
- */
- if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
- int rc2;
- RtreeNode *pChild;
- i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
- rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
- if( rc==SQLITE_OK ){
- rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
- }
- rc2 = nodeRelease(pRtree, pChild);
- if( rc==SQLITE_OK ) rc = rc2;
- if( rc==SQLITE_OK ){
- pRtree->iDepth--;
- writeInt16(pRoot->zData, pRtree->iDepth);
- pRoot->isDirty = 1;
- }
- }
-
- /* Re-insert the contents of any underfull nodes removed from the tree. */
- for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){
- if( rc==SQLITE_OK ){
- rc = reinsertNodeContent(pRtree, pLeaf);
- }
- pRtree->pDeleted = pLeaf->pNext;
- sqlite3_free(pLeaf);
- }
-
- /* Release the reference to the root node. */
- if( rc==SQLITE_OK ){
- rc = nodeRelease(pRtree, pRoot);
- }else{
- nodeRelease(pRtree, pRoot);
- }
-
- return rc;
-}
-
-/*
-** Rounding constants for float->double conversion.
-*/
-#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */
-#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */
-
-#if !defined(SQLITE_RTREE_INT_ONLY)
-/*
-** Convert an sqlite3_value into an RtreeValue (presumably a float)
-** while taking care to round toward negative or positive, respectively.
-*/
-static RtreeValue rtreeValueDown(sqlite3_value *v){
- double d = sqlite3_value_double(v);
- float f = (float)d;
- if( f>d ){
- f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS));
- }
- return f;
-}
-static RtreeValue rtreeValueUp(sqlite3_value *v){
- double d = sqlite3_value_double(v);
- float f = (float)d;
- if( f<d ){
- f = (float)(d*(d<0 ? RNDTOWARDS : RNDAWAY));
- }
- return f;
-}
-#endif /* !defined(SQLITE_RTREE_INT_ONLY) */
-
-
-/*
-** The xUpdate method for rtree module virtual tables.
-*/
-static int rtreeUpdate(
- sqlite3_vtab *pVtab,
- int nData,
- sqlite3_value **azData,
- sqlite_int64 *pRowid
-){
- Rtree *pRtree = (Rtree *)pVtab;
- int rc = SQLITE_OK;
- RtreeCell cell; /* New cell to insert if nData>1 */
- int bHaveRowid = 0; /* Set to 1 after new rowid is determined */
-
- rtreeReference(pRtree);
- assert(nData>=1);
-
- /* Constraint handling. A write operation on an r-tree table may return
- ** SQLITE_CONSTRAINT for two reasons:
- **
- ** 1. A duplicate rowid value, or
- ** 2. The supplied data violates the "x2>=x1" constraint.
- **
- ** In the first case, if the conflict-handling mode is REPLACE, then
- ** the conflicting row can be removed before proceeding. In the second
- ** case, SQLITE_CONSTRAINT must be returned regardless of the
- ** conflict-handling mode specified by the user.
- */
- if( nData>1 ){
- int ii;
-
- /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
- assert( nData==(pRtree->nDim*2 + 3) );
-#ifndef SQLITE_RTREE_INT_ONLY
- if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
- cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
- if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
- rc = SQLITE_CONSTRAINT;
- goto constraint;
- }
- }
- }else
-#endif
- {
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
- cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
- if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
- rc = SQLITE_CONSTRAINT;
- goto constraint;
- }
- }
- }
-
- /* If a rowid value was supplied, check if it is already present in
- ** the table. If so, the constraint has failed. */
- if( sqlite3_value_type(azData[2])!=SQLITE_NULL ){
- cell.iRowid = sqlite3_value_int64(azData[2]);
- if( sqlite3_value_type(azData[0])==SQLITE_NULL
- || sqlite3_value_int64(azData[0])!=cell.iRowid
- ){
- int steprc;
- sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
- steprc = sqlite3_step(pRtree->pReadRowid);
- rc = sqlite3_reset(pRtree->pReadRowid);
- if( SQLITE_ROW==steprc ){
- if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){
- rc = rtreeDeleteRowid(pRtree, cell.iRowid);
- }else{
- rc = SQLITE_CONSTRAINT;
- goto constraint;
- }
- }
- }
- bHaveRowid = 1;
- }
- }
-
- /* If azData[0] is not an SQL NULL value, it is the rowid of a
- ** record to delete from the r-tree table. The following block does
- ** just that.
- */
- if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){
- rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(azData[0]));
- }
-
- /* If the azData[] array contains more than one element, elements
- ** (azData[2]..azData[argc-1]) contain a new record to insert into
- ** the r-tree structure.
- */
- if( rc==SQLITE_OK && nData>1 ){
- /* Insert the new record into the r-tree */
- RtreeNode *pLeaf = 0;
-
- /* Figure out the rowid of the new row. */
- if( bHaveRowid==0 ){
- rc = newRowid(pRtree, &cell.iRowid);
- }
- *pRowid = cell.iRowid;
-
- if( rc==SQLITE_OK ){
- rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf);
- }
- if( rc==SQLITE_OK ){
- int rc2;
- pRtree->iReinsertHeight = -1;
- rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
- rc2 = nodeRelease(pRtree, pLeaf);
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
-
-constraint:
- rtreeRelease(pRtree);
- return rc;
-}
-
-/*
-** The xRename method for rtree module virtual tables.
-*/
-static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
- Rtree *pRtree = (Rtree *)pVtab;
- int rc = SQLITE_NOMEM;
- char *zSql = sqlite3_mprintf(
- "ALTER TABLE %Q.'%q_node' RENAME TO \"%w_node\";"
- "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";"
- "ALTER TABLE %Q.'%q_rowid' RENAME TO \"%w_rowid\";"
- , pRtree->zDb, pRtree->zName, zNewName
- , pRtree->zDb, pRtree->zName, zNewName
- , pRtree->zDb, pRtree->zName, zNewName
- );
- if( zSql ){
- rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
- sqlite3_free(zSql);
- }
- return rc;
-}
-
-static sqlite3_module rtreeModule = {
- 0, /* iVersion */
- rtreeCreate, /* xCreate - create a table */
- rtreeConnect, /* xConnect - connect to an existing table */
- rtreeBestIndex, /* xBestIndex - Determine search strategy */
- rtreeDisconnect, /* xDisconnect - Disconnect from a table */
- rtreeDestroy, /* xDestroy - Drop a table */
- rtreeOpen, /* xOpen - open a cursor */
- rtreeClose, /* xClose - close a cursor */
- rtreeFilter, /* xFilter - configure scan constraints */
- rtreeNext, /* xNext - advance a cursor */
- rtreeEof, /* xEof */
- rtreeColumn, /* xColumn - read data */
- rtreeRowid, /* xRowid - read data */
- rtreeUpdate, /* xUpdate - write data */
- 0, /* xBegin - begin transaction */
- 0, /* xSync - sync transaction */
- 0, /* xCommit - commit transaction */
- 0, /* xRollback - rollback transaction */
- 0, /* xFindFunction - function overloading */
- rtreeRename, /* xRename - rename the table */
- 0, /* xSavepoint */
- 0, /* xRelease */
- 0 /* xRollbackTo */
-};
-
-static int rtreeSqlInit(
- Rtree *pRtree,
- sqlite3 *db,
- const char *zDb,
- const char *zPrefix,
- int isCreate
-){
- int rc = SQLITE_OK;
-
- #define N_STATEMENT 9
- static const char *azSql[N_STATEMENT] = {
- /* Read and write the xxx_node table */
- "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1",
- "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
- "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
-
- /* Read and write the xxx_rowid table */
- "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1",
- "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)",
- "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1",
-
- /* Read and write the xxx_parent table */
- "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1",
- "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)",
- "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1"
- };
- sqlite3_stmt **appStmt[N_STATEMENT];
- int i;
-
- pRtree->db = db;
-
- if( isCreate ){
- char *zCreate = sqlite3_mprintf(
-"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);"
-"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);"
-"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY, parentnode INTEGER);"
-"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))",
- zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize
- );
- if( !zCreate ){
- return SQLITE_NOMEM;
- }
- rc = sqlite3_exec(db, zCreate, 0, 0, 0);
- sqlite3_free(zCreate);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- }
-
- appStmt[0] = &pRtree->pReadNode;
- appStmt[1] = &pRtree->pWriteNode;
- appStmt[2] = &pRtree->pDeleteNode;
- appStmt[3] = &pRtree->pReadRowid;
- appStmt[4] = &pRtree->pWriteRowid;
- appStmt[5] = &pRtree->pDeleteRowid;
- appStmt[6] = &pRtree->pReadParent;
- appStmt[7] = &pRtree->pWriteParent;
- appStmt[8] = &pRtree->pDeleteParent;
-
- for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
- char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
- if( zSql ){
- rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0);
- }else{
- rc = SQLITE_NOMEM;
- }
- sqlite3_free(zSql);
- }
-
- return rc;
-}
-
-/*
-** The second argument to this function contains the text of an SQL statement
-** that returns a single integer value. The statement is compiled and executed
-** using database connection db. If successful, the integer value returned
-** is written to *piVal and SQLITE_OK returned. Otherwise, an SQLite error
-** code is returned and the value of *piVal after returning is not defined.
-*/
-static int getIntFromStmt(sqlite3 *db, const char *zSql, int *piVal){
- int rc = SQLITE_NOMEM;
- if( zSql ){
- sqlite3_stmt *pStmt = 0;
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
- if( rc==SQLITE_OK ){
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
- *piVal = sqlite3_column_int(pStmt, 0);
- }
- rc = sqlite3_finalize(pStmt);
- }
- }
- return rc;
-}
-
-/*
-** This function is called from within the xConnect() or xCreate() method to
-** determine the node-size used by the rtree table being created or connected
-** to. If successful, pRtree->iNodeSize is populated and SQLITE_OK returned.
-** Otherwise, an SQLite error code is returned.
-**
-** If this function is being called as part of an xConnect(), then the rtree
-** table already exists. In this case the node-size is determined by inspecting
-** the root node of the tree.
-**
-** Otherwise, for an xCreate(), use 64 bytes less than the database page-size.
-** This ensures that each node is stored on a single database page. If the
-** database page-size is so large that more than RTREE_MAXCELLS entries
-** would fit in a single node, use a smaller node-size.
-*/
-static int getNodeSize(
- sqlite3 *db, /* Database handle */
- Rtree *pRtree, /* Rtree handle */
- int isCreate /* True for xCreate, false for xConnect */
-){
- int rc;
- char *zSql;
- if( isCreate ){
- int iPageSize = 0;
- zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb);
- rc = getIntFromStmt(db, zSql, &iPageSize);
- if( rc==SQLITE_OK ){
- pRtree->iNodeSize = iPageSize-64;
- if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){
- pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS;
- }
- }
- }else{
- zSql = sqlite3_mprintf(
- "SELECT length(data) FROM '%q'.'%q_node' WHERE nodeno = 1",
- pRtree->zDb, pRtree->zName
- );
- rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
- }
-
- sqlite3_free(zSql);
- return rc;
-}
-
-/*
-** This function is the implementation of both the xConnect and xCreate
-** methods of the r-tree virtual table.
-**
-** argv[0] -> module name
-** argv[1] -> database name
-** argv[2] -> table name
-** argv[...] -> column names...
-*/
-static int rtreeInit(
- sqlite3 *db, /* Database connection */
- void *pAux, /* One of the RTREE_COORD_* constants */
- int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */
- sqlite3_vtab **ppVtab, /* OUT: New virtual table */
- char **pzErr, /* OUT: Error message, if any */
- int isCreate /* True for xCreate, false for xConnect */
-){
- int rc = SQLITE_OK;
- Rtree *pRtree;
- int nDb; /* Length of string argv[1] */
- int nName; /* Length of string argv[2] */
- int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32);
-
- const char *aErrMsg[] = {
- 0, /* 0 */
- "Wrong number of columns for an rtree table", /* 1 */
- "Too few columns for an rtree table", /* 2 */
- "Too many columns for an rtree table" /* 3 */
- };
-
- int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2;
- if( aErrMsg[iErr] ){
- *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
- return SQLITE_ERROR;
- }
-
- sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
-
- /* Allocate the sqlite3_vtab structure */
- nDb = (int)strlen(argv[1]);
- nName = (int)strlen(argv[2]);
- pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
- if( !pRtree ){
- return SQLITE_NOMEM;
- }
- memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2);
- pRtree->nBusy = 1;
- pRtree->base.pModule = &rtreeModule;
- pRtree->zDb = (char *)&pRtree[1];
- pRtree->zName = &pRtree->zDb[nDb+1];
- pRtree->nDim = (argc-4)/2;
- pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2;
- pRtree->eCoordType = eCoordType;
- memcpy(pRtree->zDb, argv[1], nDb);
- memcpy(pRtree->zName, argv[2], nName);
-
- /* Figure out the node size to use. */
- rc = getNodeSize(db, pRtree, isCreate);
-
- /* Create/Connect to the underlying relational database schema. If
- ** that is successful, call sqlite3_declare_vtab() to configure
- ** the r-tree table schema.
- */
- if( rc==SQLITE_OK ){
- if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){
- *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
- }else{
- char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]);
- char *zTmp;
- int ii;
- for(ii=4; zSql && ii<argc; ii++){
- zTmp = zSql;
- zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]);
- sqlite3_free(zTmp);
- }
- if( zSql ){
- zTmp = zSql;
- zSql = sqlite3_mprintf("%s);", zTmp);
- sqlite3_free(zTmp);
- }
- if( !zSql ){
- rc = SQLITE_NOMEM;
- }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){
- *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
- }
- sqlite3_free(zSql);
- }
- }
-
- if( rc==SQLITE_OK ){
- *ppVtab = (sqlite3_vtab *)pRtree;
- }else{
- rtreeRelease(pRtree);
- }
- return rc;
-}
-
-
-/*
-** Implementation of a scalar function that decodes r-tree nodes to
-** human readable strings. This can be used for debugging and analysis.
-**
-** The scalar function takes two arguments, a blob of data containing
-** an r-tree node, and the number of dimensions the r-tree indexes.
-** For a two-dimensional r-tree structure called "rt", to deserialize
-** all nodes, a statement like:
-**
-** SELECT rtreenode(2, data) FROM rt_node;
-**
-** The human readable string takes the form of a Tcl list with one
-** entry for each cell in the r-tree node. Each entry is itself a
-** list, containing the 8-byte rowid/pageno followed by the
-** <num-dimension>*2 coordinates.
-*/
-static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
- char *zText = 0;
- RtreeNode node;
- Rtree tree;
- int ii;
-
- UNUSED_PARAMETER(nArg);
- memset(&node, 0, sizeof(RtreeNode));
- memset(&tree, 0, sizeof(Rtree));
- tree.nDim = sqlite3_value_int(apArg[0]);
- tree.nBytesPerCell = 8 + 8 * tree.nDim;
- node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
-
- for(ii=0; ii<NCELL(&node); ii++){
- char zCell[512];
- int nCell = 0;
- RtreeCell cell;
- int jj;
-
- nodeGetCell(&tree, &node, ii, &cell);
- sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
- nCell = (int)strlen(zCell);
- for(jj=0; jj<tree.nDim*2; jj++){
-#ifndef SQLITE_RTREE_INT_ONLY
- sqlite3_snprintf(512-nCell,&zCell[nCell], " %f",
- (double)cell.aCoord[jj].f);
-#else
- sqlite3_snprintf(512-nCell,&zCell[nCell], " %d",
- cell.aCoord[jj].i);
-#endif
- nCell = (int)strlen(zCell);
- }
-
- if( zText ){
- char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell);
- sqlite3_free(zText);
- zText = zTextNew;
- }else{
- zText = sqlite3_mprintf("{%s}", zCell);
- }
- }
-
- sqlite3_result_text(ctx, zText, -1, sqlite3_free);
-}
-
-static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
- UNUSED_PARAMETER(nArg);
- if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB
- || sqlite3_value_bytes(apArg[0])<2
- ){
- sqlite3_result_error(ctx, "Invalid argument to rtreedepth()", -1);
- }else{
- u8 *zBlob = (u8 *)sqlite3_value_blob(apArg[0]);
- sqlite3_result_int(ctx, readInt16(zBlob));
- }
-}
-
-/*
-** Register the r-tree module with database handle db. This creates the
-** virtual table module "rtree" and the debugging/analysis scalar
-** function "rtreenode".
-*/
-SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){
- const int utf8 = SQLITE_UTF8;
- int rc;
-
- rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
- }
- if( rc==SQLITE_OK ){
-#ifdef SQLITE_RTREE_INT_ONLY
- void *c = (void *)RTREE_COORD_INT32;
-#else
- void *c = (void *)RTREE_COORD_REAL32;
-#endif
- rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0);
- }
- if( rc==SQLITE_OK ){
- void *c = (void *)RTREE_COORD_INT32;
- rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
- }
-
- return rc;
-}
-
-/*
-** A version of sqlite3_free() that can be used as a callback. This is used
-** in two places - as the destructor for the blob value returned by the
-** invocation of a geometry function, and as the destructor for the geometry
-** functions themselves.
-*/
-static void doSqlite3Free(void *p){
- sqlite3_free(p);
-}
-
-/*
-** Each call to sqlite3_rtree_geometry_callback() creates an ordinary SQLite
-** scalar user function. This C function is the callback used for all such
-** registered SQL functions.
-**
-** The scalar user functions return a blob that is interpreted by r-tree
-** table MATCH operators.
-*/
-static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
- RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
- RtreeMatchArg *pBlob;
- int nBlob;
-
- nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
- pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
- if( !pBlob ){
- sqlite3_result_error_nomem(ctx);
- }else{
- int i;
- pBlob->magic = RTREE_GEOMETRY_MAGIC;
- pBlob->xGeom = pGeomCtx->xGeom;
- pBlob->pContext = pGeomCtx->pContext;
- pBlob->nParam = nArg;
- for(i=0; i<nArg; i++){
-#ifdef SQLITE_RTREE_INT_ONLY
- pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
-#else
- pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
-#endif
- }
- sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free);
- }
-}
-
-/*
-** Register a new geometry function for use with the r-tree MATCH operator.
-*/
-SQLITE_API int sqlite3_rtree_geometry_callback(
- sqlite3 *db,
- const char *zGeom,
- int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue *, int *),
- void *pContext
-){
- RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */
-
- /* Allocate and populate the context object. */
- pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
- if( !pGeomCtx ) return SQLITE_NOMEM;
- pGeomCtx->xGeom = xGeom;
- pGeomCtx->pContext = pContext;
-
- /* Create the new user-function. Register a destructor function to delete
- ** the context object when it is no longer required. */
- return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY,
- (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free
- );
-}
-
-#if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi)
- return sqlite3RtreeInit(db);
-}
-#endif
-
-#endif
-
-/************** End of rtree.c ***********************************************/
-/************** Begin file icu.c *********************************************/
-/*
-** 2007 May 6
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** $Id$
-**
-** This file implements an integration between the ICU library
-** ("International Components for Unicode", an open-source library
-** for handling unicode data) and SQLite. The integration uses
-** ICU to provide the following to SQLite:
-**
-** * An implementation of the SQL regexp() function (and hence REGEXP
-** operator) using the ICU uregex_XX() APIs.
-**
-** * Implementations of the SQL scalar upper() and lower() functions
-** for case mapping.
-**
-** * Integration of ICU and SQLite collation seqences.
-**
-** * An implementation of the LIKE operator that uses ICU to
-** provide case-independent matching.
-*/
-
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
-
-/* Include ICU headers */
-#include <unicode/utypes.h>
-#include <unicode/uregex.h>
-#include <unicode/ustring.h>
-#include <unicode/ucol.h>
-
-/* #include <assert.h> */
-
-#ifndef SQLITE_CORE
- SQLITE_EXTENSION_INIT1
-#else
-#endif
-
-/*
-** Maximum length (in bytes) of the pattern in a LIKE or GLOB
-** operator.
-*/
-#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
-# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
-#endif
-
-/*
-** Version of sqlite3_free() that is always a function, never a macro.
-*/
-static void xFree(void *p){
- sqlite3_free(p);
-}
-
-/*
-** Compare two UTF-8 strings for equality where the first string is
-** a "LIKE" expression. Return true (1) if they are the same and
-** false (0) if they are different.
-*/
-static int icuLikeCompare(
- const uint8_t *zPattern, /* LIKE pattern */
- const uint8_t *zString, /* The UTF-8 string to compare against */
- const UChar32 uEsc /* The escape character */
-){
- static const int MATCH_ONE = (UChar32)'_';
- static const int MATCH_ALL = (UChar32)'%';
-
- int iPattern = 0; /* Current byte index in zPattern */
- int iString = 0; /* Current byte index in zString */
-
- int prevEscape = 0; /* True if the previous character was uEsc */
-
- while( zPattern[iPattern]!=0 ){
-
- /* Read (and consume) the next character from the input pattern. */
- UChar32 uPattern;
- U8_NEXT_UNSAFE(zPattern, iPattern, uPattern);
- assert(uPattern!=0);
-
- /* There are now 4 possibilities:
- **
- ** 1. uPattern is an unescaped match-all character "%",
- ** 2. uPattern is an unescaped match-one character "_",
- ** 3. uPattern is an unescaped escape character, or
- ** 4. uPattern is to be handled as an ordinary character
- */
- if( !prevEscape && uPattern==MATCH_ALL ){
- /* Case 1. */
- uint8_t c;
-
- /* Skip any MATCH_ALL or MATCH_ONE characters that follow a
- ** MATCH_ALL. For each MATCH_ONE, skip one character in the
- ** test string.
- */
- while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){
- if( c==MATCH_ONE ){
- if( zString[iString]==0 ) return 0;
- U8_FWD_1_UNSAFE(zString, iString);
- }
- iPattern++;
- }
-
- if( zPattern[iPattern]==0 ) return 1;
-
- while( zString[iString] ){
- if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){
- return 1;
- }
- U8_FWD_1_UNSAFE(zString, iString);
- }
- return 0;
-
- }else if( !prevEscape && uPattern==MATCH_ONE ){
- /* Case 2. */
- if( zString[iString]==0 ) return 0;
- U8_FWD_1_UNSAFE(zString, iString);
-
- }else if( !prevEscape && uPattern==uEsc){
- /* Case 3. */
- prevEscape = 1;
-
- }else{
- /* Case 4. */
- UChar32 uString;
- U8_NEXT_UNSAFE(zString, iString, uString);
- uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
- uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
- if( uString!=uPattern ){
- return 0;
- }
- prevEscape = 0;
- }
- }
-
- return zString[iString]==0;
-}
-
-/*
-** Implementation of the like() SQL function. This function implements
-** the build-in LIKE operator. The first argument to the function is the
-** pattern and the second argument is the string. So, the SQL statements:
-**
-** A LIKE B
-**
-** is implemented as like(B, A). If there is an escape character E,
-**
-** A LIKE B ESCAPE E
-**
-** is mapped to like(B, A, E).
-*/
-static void icuLikeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- const unsigned char *zA = sqlite3_value_text(argv[0]);
- const unsigned char *zB = sqlite3_value_text(argv[1]);
- UChar32 uEsc = 0;
-
- /* Limit the length of the LIKE or GLOB pattern to avoid problems
- ** of deep recursion and N*N behavior in patternCompare().
- */
- if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){
- sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
- return;
- }
-
-
- if( argc==3 ){
- /* The escape character string must consist of a single UTF-8 character.
- ** Otherwise, return an error.
- */
- int nE= sqlite3_value_bytes(argv[2]);
- const unsigned char *zE = sqlite3_value_text(argv[2]);
- int i = 0;
- if( zE==0 ) return;
- U8_NEXT(zE, i, nE, uEsc);
- if( i!=nE){
- sqlite3_result_error(context,
- "ESCAPE expression must be a single character", -1);
- return;
- }
- }
-
- if( zA && zB ){
- sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc));
- }
-}
-
-/*
-** This function is called when an ICU function called from within
-** the implementation of an SQL scalar function returns an error.
-**
-** The scalar function context passed as the first argument is
-** loaded with an error message based on the following two args.
-*/
-static void icuFunctionError(
- sqlite3_context *pCtx, /* SQLite scalar function context */
- const char *zName, /* Name of ICU function that failed */
- UErrorCode e /* Error code returned by ICU function */
-){
- char zBuf[128];
- sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
- zBuf[127] = '\0';
- sqlite3_result_error(pCtx, zBuf, -1);
-}
-
-/*
-** Function to delete compiled regexp objects. Registered as
-** a destructor function with sqlite3_set_auxdata().
-*/
-static void icuRegexpDelete(void *p){
- URegularExpression *pExpr = (URegularExpression *)p;
- uregex_close(pExpr);
-}
-
-/*
-** Implementation of SQLite REGEXP operator. This scalar function takes
-** two arguments. The first is a regular expression pattern to compile
-** the second is a string to match against that pattern. If either
-** argument is an SQL NULL, then NULL Is returned. Otherwise, the result
-** is 1 if the string matches the pattern, or 0 otherwise.
-**
-** SQLite maps the regexp() function to the regexp() operator such
-** that the following two are equivalent:
-**
-** zString REGEXP zPattern
-** regexp(zPattern, zString)
-**
-** Uses the following ICU regexp APIs:
-**
-** uregex_open()
-** uregex_matches()
-** uregex_close()
-*/
-static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
- UErrorCode status = U_ZERO_ERROR;
- URegularExpression *pExpr;
- UBool res;
- const UChar *zString = sqlite3_value_text16(apArg[1]);
-
- (void)nArg; /* Unused parameter */
-
- /* If the left hand side of the regexp operator is NULL,
- ** then the result is also NULL.
- */
- if( !zString ){
- return;
- }
-
- pExpr = sqlite3_get_auxdata(p, 0);
- if( !pExpr ){
- const UChar *zPattern = sqlite3_value_text16(apArg[0]);
- if( !zPattern ){
- return;
- }
- pExpr = uregex_open(zPattern, -1, 0, 0, &status);
-
- if( U_SUCCESS(status) ){
- sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);
- }else{
- assert(!pExpr);
- icuFunctionError(p, "uregex_open", status);
- return;
- }
- }
-
- /* Configure the text that the regular expression operates on. */
- uregex_setText(pExpr, zString, -1, &status);
- if( !U_SUCCESS(status) ){
- icuFunctionError(p, "uregex_setText", status);
- return;
- }
-
- /* Attempt the match */
- res = uregex_matches(pExpr, 0, &status);
- if( !U_SUCCESS(status) ){
- icuFunctionError(p, "uregex_matches", status);
- return;
- }
-
- /* Set the text that the regular expression operates on to a NULL
- ** pointer. This is not really necessary, but it is tidier than
- ** leaving the regular expression object configured with an invalid
- ** pointer after this function returns.
- */
- uregex_setText(pExpr, 0, 0, &status);
-
- /* Return 1 or 0. */
- sqlite3_result_int(p, res ? 1 : 0);
-}
-
-/*
-** Implementations of scalar functions for case mapping - upper() and
-** lower(). Function upper() converts its input to upper-case (ABC).
-** Function lower() converts to lower-case (abc).
-**
-** ICU provides two types of case mapping, "general" case mapping and
-** "language specific". Refer to ICU documentation for the differences
-** between the two.
-**
-** To utilise "general" case mapping, the upper() or lower() scalar
-** functions are invoked with one argument:
-**
-** upper('ABC') -> 'abc'
-** lower('abc') -> 'ABC'
-**
-** To access ICU "language specific" case mapping, upper() or lower()
-** should be invoked with two arguments. The second argument is the name
-** of the locale to use. Passing an empty string ("") or SQL NULL value
-** as the second argument is the same as invoking the 1 argument version
-** of upper() or lower().
-**
-** lower('I', 'en_us') -> 'i'
-** lower('I', 'tr_tr') -> 'ı' (small dotless i)
-**
-** http://www.icu-project.org/userguide/posix.html#case_mappings
-*/
-static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
- const UChar *zInput;
- UChar *zOutput;
- int nInput;
- int nOutput;
-
- UErrorCode status = U_ZERO_ERROR;
- const char *zLocale = 0;
-
- assert(nArg==1 || nArg==2);
- if( nArg==2 ){
- zLocale = (const char *)sqlite3_value_text(apArg[1]);
- }
-
- zInput = sqlite3_value_text16(apArg[0]);
- if( !zInput ){
- return;
- }
- nInput = sqlite3_value_bytes16(apArg[0]);
-
- nOutput = nInput * 2 + 2;
- zOutput = sqlite3_malloc(nOutput);
- if( !zOutput ){
- return;
- }
-
- if( sqlite3_user_data(p) ){
- u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
- }else{
- u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
- }
-
- if( !U_SUCCESS(status) ){
- icuFunctionError(p, "u_strToLower()/u_strToUpper", status);
- return;
- }
-
- sqlite3_result_text16(p, zOutput, -1, xFree);
-}
-
-/*
-** Collation sequence destructor function. The pCtx argument points to
-** a UCollator structure previously allocated using ucol_open().
-*/
-static void icuCollationDel(void *pCtx){
- UCollator *p = (UCollator *)pCtx;
- ucol_close(p);
-}
-
-/*
-** Collation sequence comparison function. The pCtx argument points to
-** a UCollator structure previously allocated using ucol_open().
-*/
-static int icuCollationColl(
- void *pCtx,
- int nLeft,
- const void *zLeft,
- int nRight,
- const void *zRight
-){
- UCollationResult res;
- UCollator *p = (UCollator *)pCtx;
- res = ucol_strcoll(p, (UChar *)zLeft, nLeft/2, (UChar *)zRight, nRight/2);
- switch( res ){
- case UCOL_LESS: return -1;
- case UCOL_GREATER: return +1;
- case UCOL_EQUAL: return 0;
- }
- assert(!"Unexpected return value from ucol_strcoll()");
- return 0;
-}
-
-/*
-** Implementation of the scalar function icu_load_collation().
-**
-** This scalar function is used to add ICU collation based collation
-** types to an SQLite database connection. It is intended to be called
-** as follows:
-**
-** SELECT icu_load_collation(<locale>, <collation-name>);
-**
-** Where <locale> is a string containing an ICU locale identifier (i.e.
-** "en_AU", "tr_TR" etc.) and <collation-name> is the name of the
-** collation sequence to create.
-*/
-static void icuLoadCollation(
- sqlite3_context *p,
- int nArg,
- sqlite3_value **apArg
-){
- sqlite3 *db = (sqlite3 *)sqlite3_user_data(p);
- UErrorCode status = U_ZERO_ERROR;
- const char *zLocale; /* Locale identifier - (eg. "jp_JP") */
- const char *zName; /* SQL Collation sequence name (eg. "japanese") */
- UCollator *pUCollator; /* ICU library collation object */
- int rc; /* Return code from sqlite3_create_collation_x() */
-
- assert(nArg==2);
- zLocale = (const char *)sqlite3_value_text(apArg[0]);
- zName = (const char *)sqlite3_value_text(apArg[1]);
-
- if( !zLocale || !zName ){
- return;
- }
-
- pUCollator = ucol_open(zLocale, &status);
- if( !U_SUCCESS(status) ){
- icuFunctionError(p, "ucol_open", status);
- return;
- }
- assert(p);
-
- rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator,
- icuCollationColl, icuCollationDel
- );
- if( rc!=SQLITE_OK ){
- ucol_close(pUCollator);
- sqlite3_result_error(p, "Error registering collation function", -1);
- }
-}
-
-/*
-** Register the ICU extension functions with database db.
-*/
-SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
- struct IcuScalar {
- const char *zName; /* Function name */
- int nArg; /* Number of arguments */
- int enc; /* Optimal text encoding */
- void *pContext; /* sqlite3_user_data() context */
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
- } scalars[] = {
- {"regexp", 2, SQLITE_ANY, 0, icuRegexpFunc},
-
- {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16},
- {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16},
- {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16},
- {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16},
-
- {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16},
- {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16},
- {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16},
- {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16},
-
- {"like", 2, SQLITE_UTF8, 0, icuLikeFunc},
- {"like", 3, SQLITE_UTF8, 0, icuLikeFunc},
-
- {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation},
- };
-
- int rc = SQLITE_OK;
- int i;
-
- for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){
- struct IcuScalar *p = &scalars[i];
- rc = sqlite3_create_function(
- db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0
- );
- }
-
- return rc;
-}
-
-#if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
- sqlite3 *db,
- char **pzErrMsg,
- const sqlite3_api_routines *pApi
-){
- SQLITE_EXTENSION_INIT2(pApi)
- return sqlite3IcuInit(db);
-}
-#endif
-
-#endif
-
-/************** End of icu.c *************************************************/
-/************** Begin file fts3_icu.c ****************************************/
-/*
-** 2007 June 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This file implements a tokenizer for fts3 based on the ICU library.
-*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
-#ifdef SQLITE_ENABLE_ICU
-
-/* #include <assert.h> */
-/* #include <string.h> */
-
-#include <unicode/ubrk.h>
-/* #include <unicode/ucol.h> */
-/* #include <unicode/ustring.h> */
-#include <unicode/utf16.h>
-
-typedef struct IcuTokenizer IcuTokenizer;
-typedef struct IcuCursor IcuCursor;
-
-struct IcuTokenizer {
- sqlite3_tokenizer base;
- char *zLocale;
-};
-
-struct IcuCursor {
- sqlite3_tokenizer_cursor base;
-
- UBreakIterator *pIter; /* ICU break-iterator object */
- int nChar; /* Number of UChar elements in pInput */
- UChar *aChar; /* Copy of input using utf-16 encoding */
- int *aOffset; /* Offsets of each character in utf-8 input */
-
- int nBuffer;
- char *zBuffer;
-
- int iToken;
-};
-
-/*
-** Create a new tokenizer instance.
-*/
-static int icuCreate(
- int argc, /* Number of entries in argv[] */
- const char * const *argv, /* Tokenizer creation arguments */
- sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */
-){
- IcuTokenizer *p;
- int n = 0;
-
- if( argc>0 ){
- n = strlen(argv[0])+1;
- }
- p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n);
- if( !p ){
- return SQLITE_NOMEM;
- }
- memset(p, 0, sizeof(IcuTokenizer));
-
- if( n ){
- p->zLocale = (char *)&p[1];
- memcpy(p->zLocale, argv[0], n);
- }
-
- *ppTokenizer = (sqlite3_tokenizer *)p;
-
- return SQLITE_OK;
-}
-
-/*
-** Destroy a tokenizer
-*/
-static int icuDestroy(sqlite3_tokenizer *pTokenizer){
- IcuTokenizer *p = (IcuTokenizer *)pTokenizer;
- sqlite3_free(p);
- return SQLITE_OK;
-}
-
-/*
-** Prepare to begin tokenizing a particular string. The input
-** string to be tokenized is pInput[0..nBytes-1]. A cursor
-** used to incrementally tokenize this string is returned in
-** *ppCursor.
-*/
-static int icuOpen(
- sqlite3_tokenizer *pTokenizer, /* The tokenizer */
- const char *zInput, /* Input string */
- int nInput, /* Length of zInput in bytes */
- sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */
-){
- IcuTokenizer *p = (IcuTokenizer *)pTokenizer;
- IcuCursor *pCsr;
-
- const int32_t opt = U_FOLD_CASE_DEFAULT;
- UErrorCode status = U_ZERO_ERROR;
- int nChar;
-
- UChar32 c;
- int iInput = 0;
- int iOut = 0;
-
- *ppCursor = 0;
-
- if( zInput==0 ){
- nInput = 0;
- zInput = "";
- }else if( nInput<0 ){
- nInput = strlen(zInput);
- }
- nChar = nInput+1;
- pCsr = (IcuCursor *)sqlite3_malloc(
- sizeof(IcuCursor) + /* IcuCursor */
- ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */
- (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */
- );
- if( !pCsr ){
- return SQLITE_NOMEM;
- }
- memset(pCsr, 0, sizeof(IcuCursor));
- pCsr->aChar = (UChar *)&pCsr[1];
- pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3];
-
- pCsr->aOffset[iOut] = iInput;
- U8_NEXT(zInput, iInput, nInput, c);
- while( c>0 ){
- int isError = 0;
- c = u_foldCase(c, opt);
- U16_APPEND(pCsr->aChar, iOut, nChar, c, isError);
- if( isError ){
- sqlite3_free(pCsr);
- return SQLITE_ERROR;
- }
- pCsr->aOffset[iOut] = iInput;
-
- if( iInput<nInput ){
- U8_NEXT(zInput, iInput, nInput, c);
- }else{
- c = 0;
- }
- }
-
- pCsr->pIter = ubrk_open(UBRK_WORD, p->zLocale, pCsr->aChar, iOut, &status);
- if( !U_SUCCESS(status) ){
- sqlite3_free(pCsr);
- return SQLITE_ERROR;
- }
- pCsr->nChar = iOut;
-
- ubrk_first(pCsr->pIter);
- *ppCursor = (sqlite3_tokenizer_cursor *)pCsr;
- return SQLITE_OK;
-}
-
-/*
-** Close a tokenization cursor previously opened by a call to icuOpen().
-*/
-static int icuClose(sqlite3_tokenizer_cursor *pCursor){
- IcuCursor *pCsr = (IcuCursor *)pCursor;
- ubrk_close(pCsr->pIter);
- sqlite3_free(pCsr->zBuffer);
- sqlite3_free(pCsr);
- return SQLITE_OK;
-}
-
-/*
-** Extract the next token from a tokenization cursor.
-*/
-static int icuNext(
- sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */
- const char **ppToken, /* OUT: *ppToken is the token text */
- int *pnBytes, /* OUT: Number of bytes in token */
- int *piStartOffset, /* OUT: Starting offset of token */
- int *piEndOffset, /* OUT: Ending offset of token */
- int *piPosition /* OUT: Position integer of token */
-){
- IcuCursor *pCsr = (IcuCursor *)pCursor;
-
- int iStart = 0;
- int iEnd = 0;
- int nByte = 0;
-
- while( iStart==iEnd ){
- UChar32 c;
-
- iStart = ubrk_current(pCsr->pIter);
- iEnd = ubrk_next(pCsr->pIter);
- if( iEnd==UBRK_DONE ){
- return SQLITE_DONE;
- }
-
- while( iStart<iEnd ){
- int iWhite = iStart;
- U16_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
- if( u_isspace(c) ){
- iStart = iWhite;
- }else{
- break;
- }
- }
- assert(iStart<=iEnd);
- }
-
- do {
- UErrorCode status = U_ZERO_ERROR;
- if( nByte ){
- char *zNew = sqlite3_realloc(pCsr->zBuffer, nByte);
- if( !zNew ){
- return SQLITE_NOMEM;
- }
- pCsr->zBuffer = zNew;
- pCsr->nBuffer = nByte;
- }
-
- u_strToUTF8(
- pCsr->zBuffer, pCsr->nBuffer, &nByte, /* Output vars */
- &pCsr->aChar[iStart], iEnd-iStart, /* Input vars */
- &status /* Output success/failure */
- );
- } while( nByte>pCsr->nBuffer );
-
- *ppToken = pCsr->zBuffer;
- *pnBytes = nByte;
- *piStartOffset = pCsr->aOffset[iStart];
- *piEndOffset = pCsr->aOffset[iEnd];
- *piPosition = pCsr->iToken++;
-
- return SQLITE_OK;
-}
-
-/*
-** The set of routines that implement the simple tokenizer
-*/
-static const sqlite3_tokenizer_module icuTokenizerModule = {
- 0, /* iVersion */
- icuCreate, /* xCreate */
- icuDestroy, /* xCreate */
- icuOpen, /* xOpen */
- icuClose, /* xClose */
- icuNext, /* xNext */
-};
-
-/*
-** Set *ppModule to point at the implementation of the ICU tokenizer.
-*/
-SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
- sqlite3_tokenizer_module const**ppModule
-){
- *ppModule = &icuTokenizerModule;
-}
-
-#endif /* defined(SQLITE_ENABLE_ICU) */
-#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
-
-/************** End of fts3_icu.c ********************************************/
diff --git a/security/nss/lib/sqlite/sqlite3.h b/security/nss/lib/sqlite/sqlite3.h
deleted file mode 100644
index 2cbf62104..000000000
--- a/security/nss/lib/sqlite/sqlite3.h
+++ /dev/null
@@ -1,7160 +0,0 @@
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** This header file defines the interface that the SQLite library
-** presents to client programs. If a C-function, structure, datatype,
-** or constant definition does not appear in this file, then it is
-** not a published API of SQLite, is subject to change without
-** notice, and should not be referenced by programs that use SQLite.
-**
-** Some of the definitions that are in this file are marked as
-** "experimental". Experimental interfaces are normally new
-** features recently added to SQLite. We do not anticipate changes
-** to experimental interfaces but reserve the right to make minor changes
-** if experience from use "in the wild" suggest such changes are prudent.
-**
-** The official C-language API documentation for SQLite is derived
-** from comments in this file. This file is the authoritative source
-** on how SQLite interfaces are suppose to operate.
-**
-** The name of this file under configuration management is "sqlite.h.in".
-** The makefile makes some minor changes to this file (such as inserting
-** the version number) and changes its name to "sqlite3.h" as
-** part of the build process.
-*/
-#ifndef _SQLITE3_H_
-#define _SQLITE3_H_
-#include <stdarg.h> /* Needed for the definition of va_list */
-
-/*
-** Make sure we can call this stuff from C++.
-*/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
-** Add the ability to override 'extern'
-*/
-#ifndef SQLITE_EXTERN
-# define SQLITE_EXTERN extern
-#endif
-
-#ifndef SQLITE_API
-# define SQLITE_API
-#endif
-
-
-/*
-** These no-op macros are used in front of interfaces to mark those
-** interfaces as either deprecated or experimental. New applications
-** should not use deprecated interfaces - they are support for backwards
-** compatibility only. Application writers should be aware that
-** experimental interfaces are subject to change in point releases.
-**
-** These macros used to resolve to various kinds of compiler magic that
-** would generate warning messages when they were used. But that
-** compiler magic ended up generating such a flurry of bug reports
-** that we have taken it all out and gone back to using simple
-** noop macros.
-*/
-#define SQLITE_DEPRECATED
-#define SQLITE_EXPERIMENTAL
-
-/*
-** Ensure these symbols were not defined by some previous header file.
-*/
-#ifdef SQLITE_VERSION
-# undef SQLITE_VERSION
-#endif
-#ifdef SQLITE_VERSION_NUMBER
-# undef SQLITE_VERSION_NUMBER
-#endif
-
-/*
-** CAPI3REF: Compile-Time Library Version Numbers
-**
-** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header
-** evaluates to a string literal that is the SQLite version in the
-** format "X.Y.Z" where X is the major version number (always 3 for
-** SQLite3) and Y is the minor version number and Z is the release number.)^
-** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer
-** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
-** numbers used in [SQLITE_VERSION].)^
-** The SQLITE_VERSION_NUMBER for any given release of SQLite will also
-** be larger than the release from which it is derived. Either Y will
-** be held constant and Z will be incremented or else Y will be incremented
-** and Z will be reset to zero.
-**
-** Since version 3.6.18, SQLite source code has been stored in the
-** <a href="http://www.fossil-scm.org/">Fossil configuration management
-** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
-** a string which identifies a particular check-in of SQLite
-** within its configuration management system. ^The SQLITE_SOURCE_ID
-** string contains the date and time of the check-in (UTC) and an SHA1
-** hash of the entire source tree.
-**
-** See also: [sqlite3_libversion()],
-** [sqlite3_libversion_number()], [sqlite3_sourceid()],
-** [sqlite_version()] and [sqlite_source_id()].
-*/
-#define SQLITE_VERSION "3.7.15"
-#define SQLITE_VERSION_NUMBER 3007015
-#define SQLITE_SOURCE_ID "2012-12-12 13:36:53 cd0b37c52658bfdf992b1e3dc467bae1835a94ae"
-
-/*
-** CAPI3REF: Run-Time Library Version Numbers
-** KEYWORDS: sqlite3_version, sqlite3_sourceid
-**
-** These interfaces provide the same information as the [SQLITE_VERSION],
-** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
-** but are associated with the library instead of the header file. ^(Cautious
-** programmers might include assert() statements in their application to
-** verify that values returned by these interfaces match the macros in
-** the header, and thus insure that the application is
-** compiled with matching library and header files.
-**
-** <blockquote><pre>
-** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
-** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
-** </pre></blockquote>)^
-**
-** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION]
-** macro. ^The sqlite3_libversion() function returns a pointer to the
-** to the sqlite3_version[] string constant. The sqlite3_libversion()
-** function is provided for use in DLLs since DLL users usually do not have
-** direct access to string constants within the DLL. ^The
-** sqlite3_libversion_number() function returns an integer equal to
-** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns
-** a pointer to a string constant whose value is the same as the
-** [SQLITE_SOURCE_ID] C preprocessor macro.
-**
-** See also: [sqlite_version()] and [sqlite_source_id()].
-*/
-SQLITE_API SQLITE_EXTERN const char sqlite3_version[];
-SQLITE_API const char *sqlite3_libversion(void);
-SQLITE_API const char *sqlite3_sourceid(void);
-SQLITE_API int sqlite3_libversion_number(void);
-
-/*
-** CAPI3REF: Run-Time Library Compilation Options Diagnostics
-**
-** ^The sqlite3_compileoption_used() function returns 0 or 1
-** indicating whether the specified option was defined at
-** compile time. ^The SQLITE_ prefix may be omitted from the
-** option name passed to sqlite3_compileoption_used().
-**
-** ^The sqlite3_compileoption_get() function allows iterating
-** over the list of options that were defined at compile time by
-** returning the N-th compile time option string. ^If N is out of range,
-** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_
-** prefix is omitted from any strings returned by
-** sqlite3_compileoption_get().
-**
-** ^Support for the diagnostic functions sqlite3_compileoption_used()
-** and sqlite3_compileoption_get() may be omitted by specifying the
-** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time.
-**
-** See also: SQL functions [sqlite_compileoption_used()] and
-** [sqlite_compileoption_get()] and the [compile_options pragma].
-*/
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
-SQLITE_API const char *sqlite3_compileoption_get(int N);
-#endif
-
-/*
-** CAPI3REF: Test To See If The Library Is Threadsafe
-**
-** ^The sqlite3_threadsafe() function returns zero if and only if
-** SQLite was compiled with mutexing code omitted due to the
-** [SQLITE_THREADSAFE] compile-time option being set to 0.
-**
-** SQLite can be compiled with or without mutexes. When
-** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
-** are enabled and SQLite is threadsafe. When the
-** [SQLITE_THREADSAFE] macro is 0,
-** the mutexes are omitted. Without the mutexes, it is not safe
-** to use SQLite concurrently from more than one thread.
-**
-** Enabling mutexes incurs a measurable performance penalty.
-** So if speed is of utmost importance, it makes sense to disable
-** the mutexes. But for maximum safety, mutexes should be enabled.
-** ^The default behavior is for mutexes to be enabled.
-**
-** This interface can be used by an application to make sure that the
-** version of SQLite that it is linking against was compiled with
-** the desired setting of the [SQLITE_THREADSAFE] macro.
-**
-** This interface only reports on the compile-time mutex setting
-** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with
-** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
-** can be fully or partially disabled using a call to [sqlite3_config()]
-** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
-** or [SQLITE_CONFIG_MUTEX]. ^(The return value of the
-** sqlite3_threadsafe() function shows only the compile-time setting of
-** thread safety, not any run-time changes to that setting made by
-** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
-** is unchanged by calls to sqlite3_config().)^
-**
-** See the [threading mode] documentation for additional information.
-*/
-SQLITE_API int sqlite3_threadsafe(void);
-
-/*
-** CAPI3REF: Database Connection Handle
-** KEYWORDS: {database connection} {database connections}
-**
-** Each open SQLite database is represented by a pointer to an instance of
-** the opaque structure named "sqlite3". It is useful to think of an sqlite3
-** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and
-** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
-** and [sqlite3_close_v2()] are its destructors. There are many other
-** interfaces (such as
-** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
-** [sqlite3_busy_timeout()] to name but three) that are methods on an
-** sqlite3 object.
-*/
-typedef struct sqlite3 sqlite3;
-
-/*
-** CAPI3REF: 64-Bit Integer Types
-** KEYWORDS: sqlite_int64 sqlite_uint64
-**
-** Because there is no cross-platform way to specify 64-bit integer types
-** SQLite includes typedefs for 64-bit signed and unsigned integers.
-**
-** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions.
-** The sqlite_int64 and sqlite_uint64 types are supported for backwards
-** compatibility only.
-**
-** ^The sqlite3_int64 and sqlite_int64 types can store integer values
-** between -9223372036854775808 and +9223372036854775807 inclusive. ^The
-** sqlite3_uint64 and sqlite_uint64 types can store integer values
-** between 0 and +18446744073709551615 inclusive.
-*/
-#ifdef SQLITE_INT64_TYPE
- typedef SQLITE_INT64_TYPE sqlite_int64;
- typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
-#elif defined(_MSC_VER) || defined(__BORLANDC__)
- typedef __int64 sqlite_int64;
- typedef unsigned __int64 sqlite_uint64;
-#else
- typedef long long int sqlite_int64;
- typedef unsigned long long int sqlite_uint64;
-#endif
-typedef sqlite_int64 sqlite3_int64;
-typedef sqlite_uint64 sqlite3_uint64;
-
-/*
-** If compiling for a processor that lacks floating point support,
-** substitute integer for floating-point.
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# define double sqlite3_int64
-#endif
-
-/*
-** CAPI3REF: Closing A Database Connection
-**
-** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
-** for the [sqlite3] object.
-** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
-** the [sqlite3] object is successfully destroyed and all associated
-** resources are deallocated.
-**
-** ^If the database connection is associated with unfinalized prepared
-** statements or unfinished sqlite3_backup objects then sqlite3_close()
-** will leave the database connection open and return [SQLITE_BUSY].
-** ^If sqlite3_close_v2() is called with unfinalized prepared statements
-** and unfinished sqlite3_backups, then the database connection becomes
-** an unusable "zombie" which will automatically be deallocated when the
-** last prepared statement is finalized or the last sqlite3_backup is
-** finished. The sqlite3_close_v2() interface is intended for use with
-** host languages that are garbage collected, and where the order in which
-** destructors are called is arbitrary.
-**
-** Applications should [sqlite3_finalize | finalize] all [prepared statements],
-** [sqlite3_blob_close | close] all [BLOB handles], and
-** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
-** with the [sqlite3] object prior to attempting to close the object. ^If
-** sqlite3_close() is called on a [database connection] that still has
-** outstanding [prepared statements], [BLOB handles], and/or
-** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
-** of resources is deferred until all [prepared statements], [BLOB handles],
-** and [sqlite3_backup] objects are also destroyed.
-**
-** ^If an [sqlite3] object is destroyed while a transaction is open,
-** the transaction is automatically rolled back.
-**
-** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
-** must be either a NULL
-** pointer or an [sqlite3] object pointer obtained
-** from [sqlite3_open()], [sqlite3_open16()], or
-** [sqlite3_open_v2()], and not previously closed.
-** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
-** argument is a harmless no-op.
-*/
-SQLITE_API int sqlite3_close(sqlite3*);
-SQLITE_API int sqlite3_close_v2(sqlite3*);
-
-/*
-** The type for a callback function.
-** This is legacy and deprecated. It is included for historical
-** compatibility and is not documented.
-*/
-typedef int (*sqlite3_callback)(void*,int,char**, char**);
-
-/*
-** CAPI3REF: One-Step Query Execution Interface
-**
-** The sqlite3_exec() interface is a convenience wrapper around
-** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
-** that allows an application to run multiple statements of SQL
-** without having to use a lot of C code.
-**
-** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded,
-** semicolon-separate SQL statements passed into its 2nd argument,
-** in the context of the [database connection] passed in as its 1st
-** argument. ^If the callback function of the 3rd argument to
-** sqlite3_exec() is not NULL, then it is invoked for each result row
-** coming out of the evaluated SQL statements. ^The 4th argument to
-** sqlite3_exec() is relayed through to the 1st argument of each
-** callback invocation. ^If the callback pointer to sqlite3_exec()
-** is NULL, then no callback is ever invoked and result rows are
-** ignored.
-**
-** ^If an error occurs while evaluating the SQL statements passed into
-** sqlite3_exec(), then execution of the current statement stops and
-** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec()
-** is not NULL then any error message is written into memory obtained
-** from [sqlite3_malloc()] and passed back through the 5th parameter.
-** To avoid memory leaks, the application should invoke [sqlite3_free()]
-** on error message strings returned through the 5th parameter of
-** of sqlite3_exec() after the error message string is no longer needed.
-** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
-** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
-** NULL before returning.
-**
-** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec()
-** routine returns SQLITE_ABORT without invoking the callback again and
-** without running any subsequent SQL statements.
-**
-** ^The 2nd argument to the sqlite3_exec() callback function is the
-** number of columns in the result. ^The 3rd argument to the sqlite3_exec()
-** callback is an array of pointers to strings obtained as if from
-** [sqlite3_column_text()], one for each column. ^If an element of a
-** result row is NULL then the corresponding string pointer for the
-** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the
-** sqlite3_exec() callback is an array of pointers to strings where each
-** entry represents the name of corresponding result column as obtained
-** from [sqlite3_column_name()].
-**
-** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer
-** to an empty string, or a pointer that contains only whitespace and/or
-** SQL comments, then no SQL statements are evaluated and the database
-** is not changed.
-**
-** Restrictions:
-**
-** <ul>
-** <li> The application must insure that the 1st parameter to sqlite3_exec()
-** is a valid and open [database connection].
-** <li> The application must not close [database connection] specified by
-** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
-** <li> The application must not modify the SQL statement text passed into
-** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
-** </ul>
-*/
-SQLITE_API int sqlite3_exec(
- sqlite3*, /* An open database */
- const char *sql, /* SQL to be evaluated */
- int (*callback)(void*,int,char**,char**), /* Callback function */
- void *, /* 1st argument to callback */
- char **errmsg /* Error msg written here */
-);
-
-/*
-** CAPI3REF: Result Codes
-** KEYWORDS: SQLITE_OK {error code} {error codes}
-** KEYWORDS: {result code} {result codes}
-**
-** Many SQLite functions return an integer result code from the set shown
-** here in order to indicate success or failure.
-**
-** New error codes may be added in future versions of SQLite.
-**
-** See also: [SQLITE_IOERR_READ | extended result codes],
-** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes].
-*/
-#define SQLITE_OK 0 /* Successful result */
-/* beginning-of-error-codes */
-#define SQLITE_ERROR 1 /* SQL error or missing database */
-#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */
-#define SQLITE_PERM 3 /* Access permission denied */
-#define SQLITE_ABORT 4 /* Callback routine requested an abort */
-#define SQLITE_BUSY 5 /* The database file is locked */
-#define SQLITE_LOCKED 6 /* A table in the database is locked */
-#define SQLITE_NOMEM 7 /* A malloc() failed */
-#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
-#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
-#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
-#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
-#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */
-#define SQLITE_FULL 13 /* Insertion failed because database is full */
-#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
-#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
-#define SQLITE_EMPTY 16 /* Database is empty */
-#define SQLITE_SCHEMA 17 /* The database schema changed */
-#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
-#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
-#define SQLITE_MISMATCH 20 /* Data type mismatch */
-#define SQLITE_MISUSE 21 /* Library used incorrectly */
-#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
-#define SQLITE_AUTH 23 /* Authorization denied */
-#define SQLITE_FORMAT 24 /* Auxiliary database format error */
-#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
-#define SQLITE_NOTADB 26 /* File opened that is not a database file */
-#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
-#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
-/* end-of-error-codes */
-
-/*
-** CAPI3REF: Extended Result Codes
-** KEYWORDS: {extended error code} {extended error codes}
-** KEYWORDS: {extended result code} {extended result codes}
-**
-** In its default configuration, SQLite API routines return one of 26 integer
-** [SQLITE_OK | result codes]. However, experience has shown that many of
-** these result codes are too coarse-grained. They do not provide as
-** much information about problems as programmers might like. In an effort to
-** address this, newer versions of SQLite (version 3.3.8 and later) include
-** support for additional result codes that provide more detailed information
-** about errors. The extended result codes are enabled or disabled
-** on a per database connection basis using the
-** [sqlite3_extended_result_codes()] API.
-**
-** Some of the available extended result codes are listed here.
-** One may expect the number of extended result codes will be expand
-** over time. Software that uses extended result codes should expect
-** to see new result codes in future releases of SQLite.
-**
-** The SQLITE_OK result code will never be extended. It will always
-** be exactly zero.
-*/
-#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
-#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
-#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
-#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8))
-#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8))
-#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8))
-#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8))
-#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8))
-#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8))
-#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8))
-#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8))
-#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8))
-#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8))
-#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
-#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8))
-#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8))
-#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8))
-#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8))
-#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8))
-#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
-#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
-#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
-#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
-#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
-#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
-#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
-#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
-#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
-#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
-#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
-#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
-#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
-
-/*
-** CAPI3REF: Flags For File Open Operations
-**
-** These bit values are intended for use in the
-** 3rd parameter to the [sqlite3_open_v2()] interface and
-** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
-*/
-#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
-#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
-#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */
-#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
-#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
-#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
-#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
-#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
-#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
-#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
-#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
-#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
-
-/* Reserved: 0x00F00000 */
-
-/*
-** CAPI3REF: Device Characteristics
-**
-** The xDeviceCharacteristics method of the [sqlite3_io_methods]
-** object returns an integer which is a vector of these
-** bit values expressing I/O characteristics of the mass storage
-** device that holds the file that the [sqlite3_io_methods]
-** refers to.
-**
-** The SQLITE_IOCAP_ATOMIC property means that all writes of
-** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values
-** mean that writes of blocks that are nnn bytes in size and
-** are aligned to an address which is an integer multiple of
-** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means
-** that when data is appended to a file, the data is appended
-** first then the size of the file is extended, never the other
-** way around. The SQLITE_IOCAP_SEQUENTIAL property means that
-** information is written to disk in the same order as calls
-** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that
-** after reboot following a crash or power loss, the only bytes in a
-** file that were written at the application level might have changed
-** and that adjacent bytes, even bytes within the same sector are
-** guaranteed to be unchanged.
-*/
-#define SQLITE_IOCAP_ATOMIC 0x00000001
-#define SQLITE_IOCAP_ATOMIC512 0x00000002
-#define SQLITE_IOCAP_ATOMIC1K 0x00000004
-#define SQLITE_IOCAP_ATOMIC2K 0x00000008
-#define SQLITE_IOCAP_ATOMIC4K 0x00000010
-#define SQLITE_IOCAP_ATOMIC8K 0x00000020
-#define SQLITE_IOCAP_ATOMIC16K 0x00000040
-#define SQLITE_IOCAP_ATOMIC32K 0x00000080
-#define SQLITE_IOCAP_ATOMIC64K 0x00000100
-#define SQLITE_IOCAP_SAFE_APPEND 0x00000200
-#define SQLITE_IOCAP_SEQUENTIAL 0x00000400
-#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
-#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
-
-/*
-** CAPI3REF: File Locking Levels
-**
-** SQLite uses one of these integer values as the second
-** argument to calls it makes to the xLock() and xUnlock() methods
-** of an [sqlite3_io_methods] object.
-*/
-#define SQLITE_LOCK_NONE 0
-#define SQLITE_LOCK_SHARED 1
-#define SQLITE_LOCK_RESERVED 2
-#define SQLITE_LOCK_PENDING 3
-#define SQLITE_LOCK_EXCLUSIVE 4
-
-/*
-** CAPI3REF: Synchronization Type Flags
-**
-** When SQLite invokes the xSync() method of an
-** [sqlite3_io_methods] object it uses a combination of
-** these integer values as the second argument.
-**
-** When the SQLITE_SYNC_DATAONLY flag is used, it means that the
-** sync operation only needs to flush data to mass storage. Inode
-** information need not be flushed. If the lower four bits of the flag
-** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics.
-** If the lower four bits equal SQLITE_SYNC_FULL, that means
-** to use Mac OS X style fullsync instead of fsync().
-**
-** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags
-** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL
-** settings. The [synchronous pragma] determines when calls to the
-** xSync VFS method occur and applies uniformly across all platforms.
-** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how
-** energetic or rigorous or forceful the sync operations are and
-** only make a difference on Mac OSX for the default SQLite code.
-** (Third-party VFS implementations might also make the distinction
-** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the
-** operating systems natively supported by SQLite, only Mac OSX
-** cares about the difference.)
-*/
-#define SQLITE_SYNC_NORMAL 0x00002
-#define SQLITE_SYNC_FULL 0x00003
-#define SQLITE_SYNC_DATAONLY 0x00010
-
-/*
-** CAPI3REF: OS Interface Open File Handle
-**
-** An [sqlite3_file] object represents an open file in the
-** [sqlite3_vfs | OS interface layer]. Individual OS interface
-** implementations will
-** want to subclass this object by appending additional fields
-** for their own use. The pMethods entry is a pointer to an
-** [sqlite3_io_methods] object that defines methods for performing
-** I/O operations on the open file.
-*/
-typedef struct sqlite3_file sqlite3_file;
-struct sqlite3_file {
- const struct sqlite3_io_methods *pMethods; /* Methods for an open file */
-};
-
-/*
-** CAPI3REF: OS Interface File Virtual Methods Object
-**
-** Every file opened by the [sqlite3_vfs.xOpen] method populates an
-** [sqlite3_file] object (or, more commonly, a subclass of the
-** [sqlite3_file] object) with a pointer to an instance of this object.
-** This object defines the methods used to perform various operations
-** against the open file represented by the [sqlite3_file] object.
-**
-** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element
-** to a non-NULL pointer, then the sqlite3_io_methods.xClose method
-** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The
-** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen]
-** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element
-** to NULL.
-**
-** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or
-** [SQLITE_SYNC_FULL]. The first choice is the normal fsync().
-** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY]
-** flag may be ORed in to indicate that only the data of the file
-** and not its inode needs to be synced.
-**
-** The integer values to xLock() and xUnlock() are one of
-** <ul>
-** <li> [SQLITE_LOCK_NONE],
-** <li> [SQLITE_LOCK_SHARED],
-** <li> [SQLITE_LOCK_RESERVED],
-** <li> [SQLITE_LOCK_PENDING], or
-** <li> [SQLITE_LOCK_EXCLUSIVE].
-** </ul>
-** xLock() increases the lock. xUnlock() decreases the lock.
-** The xCheckReservedLock() method checks whether any database connection,
-** either in this process or in some other process, is holding a RESERVED,
-** PENDING, or EXCLUSIVE lock on the file. It returns true
-** if such a lock exists and false otherwise.
-**
-** The xFileControl() method is a generic interface that allows custom
-** VFS implementations to directly control an open file using the
-** [sqlite3_file_control()] interface. The second "op" argument is an
-** integer opcode. The third argument is a generic pointer intended to
-** point to a structure that may contain arguments or space in which to
-** write return values. Potential uses for xFileControl() might be
-** functions to enable blocking locks with timeouts, to change the
-** locking strategy (for example to use dot-file locks), to inquire
-** about the status of a lock, or to break stale locks. The SQLite
-** core reserves all opcodes less than 100 for its own use.
-** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
-** Applications that define a custom xFileControl method should use opcodes
-** greater than 100 to avoid conflicts. VFS implementations should
-** return [SQLITE_NOTFOUND] for file control opcodes that they do not
-** recognize.
-**
-** The xSectorSize() method returns the sector size of the
-** device that underlies the file. The sector size is the
-** minimum write that can be performed without disturbing
-** other bytes in the file. The xDeviceCharacteristics()
-** method returns a bit vector describing behaviors of the
-** underlying device:
-**
-** <ul>
-** <li> [SQLITE_IOCAP_ATOMIC]
-** <li> [SQLITE_IOCAP_ATOMIC512]
-** <li> [SQLITE_IOCAP_ATOMIC1K]
-** <li> [SQLITE_IOCAP_ATOMIC2K]
-** <li> [SQLITE_IOCAP_ATOMIC4K]
-** <li> [SQLITE_IOCAP_ATOMIC8K]
-** <li> [SQLITE_IOCAP_ATOMIC16K]
-** <li> [SQLITE_IOCAP_ATOMIC32K]
-** <li> [SQLITE_IOCAP_ATOMIC64K]
-** <li> [SQLITE_IOCAP_SAFE_APPEND]
-** <li> [SQLITE_IOCAP_SEQUENTIAL]
-** </ul>
-**
-** The SQLITE_IOCAP_ATOMIC property means that all writes of
-** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values
-** mean that writes of blocks that are nnn bytes in size and
-** are aligned to an address which is an integer multiple of
-** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means
-** that when data is appended to a file, the data is appended
-** first then the size of the file is extended, never the other
-** way around. The SQLITE_IOCAP_SEQUENTIAL property means that
-** information is written to disk in the same order as calls
-** to xWrite().
-**
-** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill
-** in the unread portions of the buffer with zeros. A VFS that
-** fails to zero-fill short reads might seem to work. However,
-** failure to zero-fill short reads will eventually lead to
-** database corruption.
-*/
-typedef struct sqlite3_io_methods sqlite3_io_methods;
-struct sqlite3_io_methods {
- int iVersion;
- int (*xClose)(sqlite3_file*);
- int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
- int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
- int (*xTruncate)(sqlite3_file*, sqlite3_int64 size);
- int (*xSync)(sqlite3_file*, int flags);
- int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
- int (*xLock)(sqlite3_file*, int);
- int (*xUnlock)(sqlite3_file*, int);
- int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
- int (*xFileControl)(sqlite3_file*, int op, void *pArg);
- int (*xSectorSize)(sqlite3_file*);
- int (*xDeviceCharacteristics)(sqlite3_file*);
- /* Methods above are valid for version 1 */
- int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
- int (*xShmLock)(sqlite3_file*, int offset, int n, int flags);
- void (*xShmBarrier)(sqlite3_file*);
- int (*xShmUnmap)(sqlite3_file*, int deleteFlag);
- /* Methods above are valid for version 2 */
- /* Additional methods may be added in future releases */
-};
-
-/*
-** CAPI3REF: Standard File Control Opcodes
-**
-** These integer constants are opcodes for the xFileControl method
-** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
-** interface.
-**
-** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This
-** opcode causes the xFileControl method to write the current state of
-** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
-** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
-** into an integer that the pArg argument points to. This capability
-** is used during testing and only needs to be supported when SQLITE_TEST
-** is defined.
-** <ul>
-** <li>[[SQLITE_FCNTL_SIZE_HINT]]
-** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
-** layer a hint of how large the database file will grow to be during the
-** current transaction. This hint is not guaranteed to be accurate but it
-** is often close. The underlying VFS might choose to preallocate database
-** file space based on this hint in order to help writes to the database
-** file run faster.
-**
-** <li>[[SQLITE_FCNTL_CHUNK_SIZE]]
-** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS
-** extends and truncates the database file in chunks of a size specified
-** by the user. The fourth argument to [sqlite3_file_control()] should
-** point to an integer (type int) containing the new chunk-size to use
-** for the nominated database. Allocating database file space in large
-** chunks (say 1MB at a time), may reduce file-system fragmentation and
-** improve performance on some systems.
-**
-** <li>[[SQLITE_FCNTL_FILE_POINTER]]
-** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
-** to the [sqlite3_file] object associated with a particular database
-** connection. See the [sqlite3_file_control()] documentation for
-** additional information.
-**
-** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
-** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
-** SQLite and sent to all VFSes in place of a call to the xSync method
-** when the database connection has [PRAGMA synchronous] set to OFF.)^
-** Some specialized VFSes need this signal in order to operate correctly
-** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most
-** VFSes do not need this signal and should silently ignore this opcode.
-** Applications should not call [sqlite3_file_control()] with this
-** opcode as doing so may disrupt the operation of the specialized VFSes
-** that do require it.
-**
-** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]]
-** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
-** retry counts and intervals for certain disk I/O operations for the
-** windows [VFS] in order to provide robustness in the presence of
-** anti-virus programs. By default, the windows VFS will retry file read,
-** file write, and file delete operations up to 10 times, with a delay
-** of 25 milliseconds before the first retry and with the delay increasing
-** by an additional 25 milliseconds with each subsequent retry. This
-** opcode allows these two values (10 retries and 25 milliseconds of delay)
-** to be adjusted. The values are changed for all database connections
-** within the same process. The argument is a pointer to an array of two
-** integers where the first integer i the new retry count and the second
-** integer is the delay. If either integer is negative, then the setting
-** is not changed but instead the prior value of that setting is written
-** into the array entry, allowing the current retry settings to be
-** interrogated. The zDbName parameter is ignored.
-**
-** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
-** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
-** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary
-** write ahead log and shared memory files used for transaction control
-** are automatically deleted when the latest connection to the database
-** closes. Setting persistent WAL mode causes those files to persist after
-** close. Persisting the files is useful when other processes that do not
-** have write permission on the directory containing the database file want
-** to read the database file, as the WAL and shared memory files must exist
-** in order for the database to be readable. The fourth parameter to
-** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
-** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
-** WAL mode. If the integer is -1, then it is overwritten with the current
-** WAL persistence setting.
-**
-** <li>[[SQLITE_FCNTL_POWERSAFE_OVERWRITE]]
-** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the
-** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting
-** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the
-** xDeviceCharacteristics methods. The fourth parameter to
-** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
-** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage
-** mode. If the integer is -1, then it is overwritten with the current
-** zero-damage mode setting.
-**
-** <li>[[SQLITE_FCNTL_OVERWRITE]]
-** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
-** a write transaction to indicate that, unless it is rolled back for some
-** reason, the entire database file will be overwritten by the current
-** transaction. This is used by VACUUM operations.
-**
-** <li>[[SQLITE_FCNTL_VFSNAME]]
-** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of
-** all [VFSes] in the VFS stack. The names are of all VFS shims and the
-** final bottom-level VFS are written into memory obtained from
-** [sqlite3_malloc()] and the result is stored in the char* variable
-** that the fourth parameter of [sqlite3_file_control()] points to.
-** The caller is responsible for freeing the memory when done. As with
-** all file-control actions, there is no guarantee that this will actually
-** do anything. Callers should initialize the char* variable to a NULL
-** pointer in case this file-control is not implemented. This file-control
-** is intended for diagnostic use only.
-**
-** <li>[[SQLITE_FCNTL_PRAGMA]]
-** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA]
-** file control is sent to the open [sqlite3_file] object corresponding
-** to the database file to which the pragma statement refers. ^The argument
-** to the [SQLITE_FCNTL_PRAGMA] file control is an array of
-** pointers to strings (char**) in which the second element of the array
-** is the name of the pragma and the third element is the argument to the
-** pragma or NULL if the pragma has no argument. ^The handler for an
-** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element
-** of the char** argument point to a string obtained from [sqlite3_mprintf()]
-** or the equivalent and that string will become the result of the pragma or
-** the error message if the pragma fails. ^If the
-** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal
-** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA]
-** file control returns [SQLITE_OK], then the parser assumes that the
-** VFS has handled the PRAGMA itself and the parser generates a no-op
-** prepared statement. ^If the [SQLITE_FCNTL_PRAGMA] file control returns
-** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
-** that the VFS encountered an error while handling the [PRAGMA] and the
-** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA]
-** file control occurs at the beginning of pragma statement analysis and so
-** it is able to override built-in [PRAGMA] statements.
-**
-** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
-** ^This file-control may be invoked by SQLite on the database file handle
-** shortly after it is opened in order to provide a custom VFS with access
-** to the connections busy-handler callback. The argument is of type (void **)
-** - an array of two (void *) values. The first (void *) actually points
-** to a function of type (int (*)(void *)). In order to invoke the connections
-** busy-handler, this function should be invoked with the second (void *) in
-** the array as the only argument. If it returns non-zero, then the operation
-** should be retried. If it returns zero, the custom VFS should abandon the
-** current operation.
-**
-** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
-** ^Application can invoke this file-control to have SQLite generate a
-** temporary filename using the same algorithm that is followed to generate
-** temporary filenames for TEMP tables and other internal uses. The
-** argument should be a char** which will be filled with the filename
-** written into memory obtained from [sqlite3_malloc()]. The caller should
-** invoke [sqlite3_free()] on the result to avoid a memory leak.
-**
-** </ul>
-*/
-#define SQLITE_FCNTL_LOCKSTATE 1
-#define SQLITE_GET_LOCKPROXYFILE 2
-#define SQLITE_SET_LOCKPROXYFILE 3
-#define SQLITE_LAST_ERRNO 4
-#define SQLITE_FCNTL_SIZE_HINT 5
-#define SQLITE_FCNTL_CHUNK_SIZE 6
-#define SQLITE_FCNTL_FILE_POINTER 7
-#define SQLITE_FCNTL_SYNC_OMITTED 8
-#define SQLITE_FCNTL_WIN32_AV_RETRY 9
-#define SQLITE_FCNTL_PERSIST_WAL 10
-#define SQLITE_FCNTL_OVERWRITE 11
-#define SQLITE_FCNTL_VFSNAME 12
-#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13
-#define SQLITE_FCNTL_PRAGMA 14
-#define SQLITE_FCNTL_BUSYHANDLER 15
-#define SQLITE_FCNTL_TEMPFILENAME 16
-
-/*
-** CAPI3REF: Mutex Handle
-**
-** The mutex module within SQLite defines [sqlite3_mutex] to be an
-** abstract type for a mutex object. The SQLite core never looks
-** at the internal representation of an [sqlite3_mutex]. It only
-** deals with pointers to the [sqlite3_mutex] object.
-**
-** Mutexes are created using [sqlite3_mutex_alloc()].
-*/
-typedef struct sqlite3_mutex sqlite3_mutex;
-
-/*
-** CAPI3REF: OS Interface Object
-**
-** An instance of the sqlite3_vfs object defines the interface between
-** the SQLite core and the underlying operating system. The "vfs"
-** in the name of the object stands for "virtual file system". See
-** the [VFS | VFS documentation] for further information.
-**
-** The value of the iVersion field is initially 1 but may be larger in
-** future versions of SQLite. Additional fields may be appended to this
-** object when the iVersion value is increased. Note that the structure
-** of the sqlite3_vfs object changes in the transaction between
-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
-** modified.
-**
-** The szOsFile field is the size of the subclassed [sqlite3_file]
-** structure used by this VFS. mxPathname is the maximum length of
-** a pathname in this VFS.
-**
-** Registered sqlite3_vfs objects are kept on a linked list formed by
-** the pNext pointer. The [sqlite3_vfs_register()]
-** and [sqlite3_vfs_unregister()] interfaces manage this list
-** in a thread-safe way. The [sqlite3_vfs_find()] interface
-** searches the list. Neither the application code nor the VFS
-** implementation should use the pNext pointer.
-**
-** The pNext field is the only field in the sqlite3_vfs
-** structure that SQLite will ever modify. SQLite will only access
-** or modify this field while holding a particular static mutex.
-** The application should never modify anything within the sqlite3_vfs
-** object once the object has been registered.
-**
-** The zName field holds the name of the VFS module. The name must
-** be unique across all VFS modules.
-**
-** [[sqlite3_vfs.xOpen]]
-** ^SQLite guarantees that the zFilename parameter to xOpen
-** is either a NULL pointer or string obtained
-** from xFullPathname() with an optional suffix added.
-** ^If a suffix is added to the zFilename parameter, it will
-** consist of a single "-" character followed by no more than
-** 11 alphanumeric and/or "-" characters.
-** ^SQLite further guarantees that
-** the string will be valid and unchanged until xClose() is
-** called. Because of the previous sentence,
-** the [sqlite3_file] can safely store a pointer to the
-** filename if it needs to remember the filename for some reason.
-** If the zFilename parameter to xOpen is a NULL pointer then xOpen
-** must invent its own temporary name for the file. ^Whenever the
-** xFilename parameter is NULL it will also be the case that the
-** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
-**
-** The flags argument to xOpen() includes all bits set in
-** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()]
-** or [sqlite3_open16()] is used, then flags includes at least
-** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE].
-** If xOpen() opens a file read-only then it sets *pOutFlags to
-** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set.
-**
-** ^(SQLite will also add one of the following flags to the xOpen()
-** call, depending on the object being opened:
-**
-** <ul>
-** <li> [SQLITE_OPEN_MAIN_DB]
-** <li> [SQLITE_OPEN_MAIN_JOURNAL]
-** <li> [SQLITE_OPEN_TEMP_DB]
-** <li> [SQLITE_OPEN_TEMP_JOURNAL]
-** <li> [SQLITE_OPEN_TRANSIENT_DB]
-** <li> [SQLITE_OPEN_SUBJOURNAL]
-** <li> [SQLITE_OPEN_MASTER_JOURNAL]
-** <li> [SQLITE_OPEN_WAL]
-** </ul>)^
-**
-** The file I/O implementation can use the object type flags to
-** change the way it deals with files. For example, an application
-** that does not care about crash recovery or rollback might make
-** the open of a journal file a no-op. Writes to this journal would
-** also be no-ops, and any attempt to read the journal would return
-** SQLITE_IOERR. Or the implementation might recognize that a database
-** file will be doing page-aligned sector reads and writes in a random
-** order and set up its I/O subsystem accordingly.
-**
-** SQLite might also add one of the following flags to the xOpen method:
-**
-** <ul>
-** <li> [SQLITE_OPEN_DELETEONCLOSE]
-** <li> [SQLITE_OPEN_EXCLUSIVE]
-** </ul>
-**
-** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
-** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE]
-** will be set for TEMP databases and their journals, transient
-** databases, and subjournals.
-**
-** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
-** with the [SQLITE_OPEN_CREATE] flag, which are both directly
-** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
-** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the
-** SQLITE_OPEN_CREATE, is used to indicate that file should always
-** be created, and that it is an error if it already exists.
-** It is <i>not</i> used to indicate the file should be opened
-** for exclusive access.
-**
-** ^At least szOsFile bytes of memory are allocated by SQLite
-** to hold the [sqlite3_file] structure passed as the third
-** argument to xOpen. The xOpen method does not have to
-** allocate the structure; it should just fill it in. Note that
-** the xOpen method must set the sqlite3_file.pMethods to either
-** a valid [sqlite3_io_methods] object or to NULL. xOpen must do
-** this even if the open fails. SQLite expects that the sqlite3_file.pMethods
-** element will be valid after xOpen returns regardless of the success
-** or failure of the xOpen call.
-**
-** [[sqlite3_vfs.xAccess]]
-** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS]
-** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to
-** test whether a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test whether a file is at least readable. The file can be a
-** directory.
-**
-** ^SQLite will always allocate at least mxPathname+1 bytes for the
-** output buffer xFullPathname. The exact size of the output buffer
-** is also passed as a parameter to both methods. If the output buffer
-** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
-** handled as a fatal error by SQLite, vfs implementations should endeavor
-** to prevent this by setting mxPathname to a sufficiently large value.
-**
-** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64()
-** interfaces are not strictly a part of the filesystem, but they are
-** included in the VFS structure for completeness.
-** The xRandomness() function attempts to return nBytes bytes
-** of good-quality randomness into zOut. The return value is
-** the actual number of bytes of randomness obtained.
-** The xSleep() method causes the calling thread to sleep for at
-** least the number of microseconds given. ^The xCurrentTime()
-** method returns a Julian Day Number for the current date and time as
-** a floating point value.
-** ^The xCurrentTimeInt64() method returns, as an integer, the Julian
-** Day Number multiplied by 86400000 (the number of milliseconds in
-** a 24-hour day).
-** ^SQLite will use the xCurrentTimeInt64() method to get the current
-** date and time if that method is available (if iVersion is 2 or
-** greater and the function pointer is not NULL) and will fall back
-** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
-**
-** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces
-** are not used by the SQLite core. These optional interfaces are provided
-** by some VFSes to facilitate testing of the VFS code. By overriding
-** system calls with functions under its control, a test program can
-** simulate faults and error conditions that would otherwise be difficult
-** or impossible to induce. The set of system calls that can be overridden
-** varies from one VFS to another, and from one version of the same VFS to the
-** next. Applications that use these interfaces must be prepared for any
-** or all of these interfaces to be NULL or for their behavior to change
-** from one release to the next. Applications must not attempt to access
-** any of these methods if the iVersion of the VFS is less than 3.
-*/
-typedef struct sqlite3_vfs sqlite3_vfs;
-typedef void (*sqlite3_syscall_ptr)(void);
-struct sqlite3_vfs {
- int iVersion; /* Structure version number (currently 3) */
- int szOsFile; /* Size of subclassed sqlite3_file */
- int mxPathname; /* Maximum file pathname length */
- sqlite3_vfs *pNext; /* Next registered VFS */
- const char *zName; /* Name of this virtual file system */
- void *pAppData; /* Pointer to application-specific data */
- int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
- int flags, int *pOutFlags);
- int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
- int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
- int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
- void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
- void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
- void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
- void (*xDlClose)(sqlite3_vfs*, void*);
- int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
- int (*xSleep)(sqlite3_vfs*, int microseconds);
- int (*xCurrentTime)(sqlite3_vfs*, double*);
- int (*xGetLastError)(sqlite3_vfs*, int, char *);
- /*
- ** The methods above are in version 1 of the sqlite_vfs object
- ** definition. Those that follow are added in version 2 or later
- */
- int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
- /*
- ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
- ** Those below are for version 3 and greater.
- */
- int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr);
- sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName);
- const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
- /*
- ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
- ** New fields may be appended in figure versions. The iVersion
- ** value will increment whenever this happens.
- */
-};
-
-/*
-** CAPI3REF: Flags for the xAccess VFS method
-**
-** These integer constants can be used as the third parameter to
-** the xAccess method of an [sqlite3_vfs] object. They determine
-** what kind of permissions the xAccess method is looking for.
-** With SQLITE_ACCESS_EXISTS, the xAccess method
-** simply checks whether the file exists.
-** With SQLITE_ACCESS_READWRITE, the xAccess method
-** checks whether the named directory is both readable and writable
-** (in other words, if files can be added, removed, and renamed within
-** the directory).
-** The SQLITE_ACCESS_READWRITE constant is currently used only by the
-** [temp_store_directory pragma], though this could change in a future
-** release of SQLite.
-** With SQLITE_ACCESS_READ, the xAccess method
-** checks whether the file is readable. The SQLITE_ACCESS_READ constant is
-** currently unused, though it might be used in a future release of
-** SQLite.
-*/
-#define SQLITE_ACCESS_EXISTS 0
-#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */
-#define SQLITE_ACCESS_READ 2 /* Unused */
-
-/*
-** CAPI3REF: Flags for the xShmLock VFS method
-**
-** These integer constants define the various locking operations
-** allowed by the xShmLock method of [sqlite3_io_methods]. The
-** following are the only legal combinations of flags to the
-** xShmLock method:
-**
-** <ul>
-** <li> SQLITE_SHM_LOCK | SQLITE_SHM_SHARED
-** <li> SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE
-** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED
-** <li> SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE
-** </ul>
-**
-** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
-** was given no the corresponding lock.
-**
-** The xShmLock method can transition between unlocked and SHARED or
-** between unlocked and EXCLUSIVE. It cannot transition between SHARED
-** and EXCLUSIVE.
-*/
-#define SQLITE_SHM_UNLOCK 1
-#define SQLITE_SHM_LOCK 2
-#define SQLITE_SHM_SHARED 4
-#define SQLITE_SHM_EXCLUSIVE 8
-
-/*
-** CAPI3REF: Maximum xShmLock index
-**
-** The xShmLock method on [sqlite3_io_methods] may use values
-** between 0 and this upper bound as its "offset" argument.
-** The SQLite core will never attempt to acquire or release a
-** lock outside of this range
-*/
-#define SQLITE_SHM_NLOCK 8
-
-
-/*
-** CAPI3REF: Initialize The SQLite Library
-**
-** ^The sqlite3_initialize() routine initializes the
-** SQLite library. ^The sqlite3_shutdown() routine
-** deallocates any resources that were allocated by sqlite3_initialize().
-** These routines are designed to aid in process initialization and
-** shutdown on embedded systems. Workstation applications using
-** SQLite normally do not need to invoke either of these routines.
-**
-** A call to sqlite3_initialize() is an "effective" call if it is
-** the first time sqlite3_initialize() is invoked during the lifetime of
-** the process, or if it is the first time sqlite3_initialize() is invoked
-** following a call to sqlite3_shutdown(). ^(Only an effective call
-** of sqlite3_initialize() does any initialization. All other calls
-** are harmless no-ops.)^
-**
-** A call to sqlite3_shutdown() is an "effective" call if it is the first
-** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only
-** an effective call to sqlite3_shutdown() does any deinitialization.
-** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^
-**
-** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown()
-** is not. The sqlite3_shutdown() interface must only be called from a
-** single thread. All open [database connections] must be closed and all
-** other SQLite resources must be deallocated prior to invoking
-** sqlite3_shutdown().
-**
-** Among other things, ^sqlite3_initialize() will invoke
-** sqlite3_os_init(). Similarly, ^sqlite3_shutdown()
-** will invoke sqlite3_os_end().
-**
-** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success.
-** ^If for some reason, sqlite3_initialize() is unable to initialize
-** the library (perhaps it is unable to allocate a needed resource such
-** as a mutex) it returns an [error code] other than [SQLITE_OK].
-**
-** ^The sqlite3_initialize() routine is called internally by many other
-** SQLite interfaces so that an application usually does not need to
-** invoke sqlite3_initialize() directly. For example, [sqlite3_open()]
-** calls sqlite3_initialize() so the SQLite library will be automatically
-** initialized when [sqlite3_open()] is called if it has not be initialized
-** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT]
-** compile-time option, then the automatic calls to sqlite3_initialize()
-** are omitted and the application must call sqlite3_initialize() directly
-** prior to using any other SQLite interface. For maximum portability,
-** it is recommended that applications always invoke sqlite3_initialize()
-** directly prior to using any other SQLite interface. Future releases
-** of SQLite may require this. In other words, the behavior exhibited
-** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the
-** default behavior in some future release of SQLite.
-**
-** The sqlite3_os_init() routine does operating-system specific
-** initialization of the SQLite library. The sqlite3_os_end()
-** routine undoes the effect of sqlite3_os_init(). Typical tasks
-** performed by these routines include allocation or deallocation
-** of static resources, initialization of global variables,
-** setting up a default [sqlite3_vfs] module, or setting up
-** a default configuration using [sqlite3_config()].
-**
-** The application should never invoke either sqlite3_os_init()
-** or sqlite3_os_end() directly. The application should only invoke
-** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init()
-** interface is called automatically by sqlite3_initialize() and
-** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate
-** implementations for sqlite3_os_init() and sqlite3_os_end()
-** are built into SQLite when it is compiled for Unix, Windows, or OS/2.
-** When [custom builds | built for other platforms]
-** (using the [SQLITE_OS_OTHER=1] compile-time
-** option) the application must supply a suitable implementation for
-** sqlite3_os_init() and sqlite3_os_end(). An application-supplied
-** implementation of sqlite3_os_init() or sqlite3_os_end()
-** must return [SQLITE_OK] on success and some other [error code] upon
-** failure.
-*/
-SQLITE_API int sqlite3_initialize(void);
-SQLITE_API int sqlite3_shutdown(void);
-SQLITE_API int sqlite3_os_init(void);
-SQLITE_API int sqlite3_os_end(void);
-
-/*
-** CAPI3REF: Configuring The SQLite Library
-**
-** The sqlite3_config() interface is used to make global configuration
-** changes to SQLite in order to tune SQLite to the specific needs of
-** the application. The default configuration is recommended for most
-** applications and so this routine is usually not necessary. It is
-** provided to support rare applications with unusual needs.
-**
-** The sqlite3_config() interface is not threadsafe. The application
-** must insure that no other SQLite interfaces are invoked by other
-** threads while sqlite3_config() is running. Furthermore, sqlite3_config()
-** may only be invoked prior to library initialization using
-** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
-** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
-** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
-** Note, however, that ^sqlite3_config() can be called as part of the
-** implementation of an application-defined [sqlite3_os_init()].
-**
-** The first argument to sqlite3_config() is an integer
-** [configuration option] that determines
-** what property of SQLite is to be configured. Subsequent arguments
-** vary depending on the [configuration option]
-** in the first argument.
-**
-** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
-** ^If the option is unknown or SQLite is unable to set the option
-** then this routine returns a non-zero [error code].
-*/
-SQLITE_API int sqlite3_config(int, ...);
-
-/*
-** CAPI3REF: Configure database connections
-**
-** The sqlite3_db_config() interface is used to make configuration
-** changes to a [database connection]. The interface is similar to
-** [sqlite3_config()] except that the changes apply to a single
-** [database connection] (specified in the first argument).
-**
-** The second argument to sqlite3_db_config(D,V,...) is the
-** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code
-** that indicates what aspect of the [database connection] is being configured.
-** Subsequent arguments vary depending on the configuration verb.
-**
-** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
-** the call is considered successful.
-*/
-SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
-
-/*
-** CAPI3REF: Memory Allocation Routines
-**
-** An instance of this object defines the interface between SQLite
-** and low-level memory allocation routines.
-**
-** This object is used in only one place in the SQLite interface.
-** A pointer to an instance of this object is the argument to
-** [sqlite3_config()] when the configuration option is
-** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC].
-** By creating an instance of this object
-** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC])
-** during configuration, an application can specify an alternative
-** memory allocation subsystem for SQLite to use for all of its
-** dynamic memory needs.
-**
-** Note that SQLite comes with several [built-in memory allocators]
-** that are perfectly adequate for the overwhelming majority of applications
-** and that this object is only useful to a tiny minority of applications
-** with specialized memory allocation requirements. This object is
-** also used during testing of SQLite in order to specify an alternative
-** memory allocator that simulates memory out-of-memory conditions in
-** order to verify that SQLite recovers gracefully from such
-** conditions.
-**
-** The xMalloc, xRealloc, and xFree methods must work like the
-** malloc(), realloc() and free() functions from the standard C library.
-** ^SQLite guarantees that the second argument to
-** xRealloc is always a value returned by a prior call to xRoundup.
-**
-** xSize should return the allocated size of a memory allocation
-** previously obtained from xMalloc or xRealloc. The allocated size
-** is always at least as big as the requested size but may be larger.
-**
-** The xRoundup method returns what would be the allocated size of
-** a memory allocation given a particular requested size. Most memory
-** allocators round up memory allocations at least to the next multiple
-** of 8. Some allocators round up to a larger multiple or to a power of 2.
-** Every memory allocation request coming in through [sqlite3_malloc()]
-** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0,
-** that causes the corresponding memory allocation to fail.
-**
-** The xInit method initializes the memory allocator. (For example,
-** it might allocate any require mutexes or initialize internal data
-** structures. The xShutdown method is invoked (indirectly) by
-** [sqlite3_shutdown()] and should deallocate any resources acquired
-** by xInit. The pAppData pointer is used as the only parameter to
-** xInit and xShutdown.
-**
-** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes
-** the xInit method, so the xInit method need not be threadsafe. The
-** xShutdown method is only called from [sqlite3_shutdown()] so it does
-** not need to be threadsafe either. For all other methods, SQLite
-** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the
-** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which
-** it is by default) and so the methods are automatically serialized.
-** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other
-** methods must be threadsafe or else make their own arrangements for
-** serialization.
-**
-** SQLite will never invoke xInit() more than once without an intervening
-** call to xShutdown().
-*/
-typedef struct sqlite3_mem_methods sqlite3_mem_methods;
-struct sqlite3_mem_methods {
- void *(*xMalloc)(int); /* Memory allocation function */
- void (*xFree)(void*); /* Free a prior allocation */
- void *(*xRealloc)(void*,int); /* Resize an allocation */
- int (*xSize)(void*); /* Return the size of an allocation */
- int (*xRoundup)(int); /* Round up request size to allocation size */
- int (*xInit)(void*); /* Initialize the memory allocator */
- void (*xShutdown)(void*); /* Deinitialize the memory allocator */
- void *pAppData; /* Argument to xInit() and xShutdown() */
-};
-
-/*
-** CAPI3REF: Configuration Options
-** KEYWORDS: {configuration option}
-**
-** These constants are the available integer configuration options that
-** can be passed as the first argument to the [sqlite3_config()] interface.
-**
-** New configuration options may be added in future releases of SQLite.
-** Existing configuration options might be discontinued. Applications
-** should check the return code from [sqlite3_config()] to make sure that
-** the call worked. The [sqlite3_config()] interface will return a
-** non-zero [error code] if a discontinued or unsupported configuration option
-** is invoked.
-**
-** <dl>
-** [[SQLITE_CONFIG_SINGLETHREAD]] <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
-** <dd>There are no arguments to this option. ^This option sets the
-** [threading mode] to Single-thread. In other words, it disables
-** all mutexing and puts SQLite into a mode where it can only be used
-** by a single thread. ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** it is not possible to change the [threading mode] from its default
-** value of Single-thread and so [sqlite3_config()] will return
-** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD
-** configuration option.</dd>
-**
-** [[SQLITE_CONFIG_MULTITHREAD]] <dt>SQLITE_CONFIG_MULTITHREAD</dt>
-** <dd>There are no arguments to this option. ^This option sets the
-** [threading mode] to Multi-thread. In other words, it disables
-** mutexing on [database connection] and [prepared statement] objects.
-** The application is responsible for serializing access to
-** [database connections] and [prepared statements]. But other mutexes
-** are enabled so that SQLite will be safe to use in a multi-threaded
-** environment as long as no two threads attempt to use the same
-** [database connection] at the same time. ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** it is not possible to set the Multi-thread [threading mode] and
-** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
-** SQLITE_CONFIG_MULTITHREAD configuration option.</dd>
-**
-** [[SQLITE_CONFIG_SERIALIZED]] <dt>SQLITE_CONFIG_SERIALIZED</dt>
-** <dd>There are no arguments to this option. ^This option sets the
-** [threading mode] to Serialized. In other words, this option enables
-** all mutexes including the recursive
-** mutexes on [database connection] and [prepared statement] objects.
-** In this mode (which is the default when SQLite is compiled with
-** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access
-** to [database connections] and [prepared statements] so that the
-** application is free to use the same [database connection] or the
-** same [prepared statement] in different threads at the same time.
-** ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** it is not possible to set the Serialized [threading mode] and
-** [sqlite3_config()] will return [SQLITE_ERROR] if called with the
-** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
-**
-** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure. The argument specifies
-** alternative low-level memory allocation routines to be used in place of
-** the memory allocation routines built into SQLite.)^ ^SQLite makes
-** its own private copy of the content of the [sqlite3_mem_methods] structure
-** before the [sqlite3_config()] call returns.</dd>
-**
-** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure. The [sqlite3_mem_methods]
-** structure is filled with the currently defined memory allocation routines.)^
-** This option can be used to overload the default memory allocation
-** routines with a wrapper that simulations memory allocation failure or
-** tracks memory usage, for example. </dd>
-**
-** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
-** <dd> ^This option takes single argument of type int, interpreted as a
-** boolean, which enables or disables the collection of memory allocation
-** statistics. ^(When memory allocation statistics are disabled, the
-** following SQLite interfaces become non-operational:
-** <ul>
-** <li> [sqlite3_memory_used()]
-** <li> [sqlite3_memory_highwater()]
-** <li> [sqlite3_soft_heap_limit64()]
-** <li> [sqlite3_status()]
-** </ul>)^
-** ^Memory allocation statistics are enabled by default unless SQLite is
-** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
-** allocation statistics are disabled by default.
-** </dd>
-**
-** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite can use for
-** scratch memory. There are three arguments: A pointer an 8-byte
-** aligned memory buffer from which the scratch allocations will be
-** drawn, the size of each scratch allocation (sz),
-** and the maximum number of scratch allocations (N). The sz
-** argument must be a multiple of 16.
-** The first argument must be a pointer to an 8-byte aligned buffer
-** of at least sz*N bytes of memory.
-** ^SQLite will use no more than two scratch buffers per thread. So
-** N should be set to twice the expected maximum number of threads.
-** ^SQLite will never require a scratch buffer that is more than 6
-** times the database page size. ^If SQLite needs needs additional
-** scratch memory beyond what is provided by this configuration option, then
-** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
-**
-** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite can use for
-** the database page cache with the default page cache implementation.
-** This configuration should not be used if an application-define page
-** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.
-** There are three arguments to this option: A pointer to 8-byte aligned
-** memory, the size of each page buffer (sz), and the number of pages (N).
-** The sz argument should be the size of the largest database page
-** (a power of two between 512 and 32768) plus a little extra for each
-** page header. ^The page header size is 20 to 40 bytes depending on
-** the host architecture. ^It is harmless, apart from the wasted memory,
-** to make sz a little too large. The first
-** argument should point to an allocation of at least sz*N bytes of memory.
-** ^SQLite will use the memory provided by the first argument to satisfy its
-** memory needs for the first N pages that it adds to cache. ^If additional
-** page cache memory is needed beyond what is provided by this option, then
-** SQLite goes to [sqlite3_malloc()] for the additional storage space.
-** The pointer in the first argument must
-** be aligned to an 8-byte boundary or subsequent behavior of SQLite
-** will be undefined.</dd>
-**
-** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite will use
-** for all of its dynamic memory allocation needs beyond those provided
-** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
-** There are three arguments: An 8-byte aligned pointer to the memory,
-** the number of bytes in the memory buffer, and the minimum allocation size.
-** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts
-** to using its default memory allocator (the system malloc() implementation),
-** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the
-** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
-** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
-** allocator is engaged to handle all of SQLites memory allocation needs.
-** The first pointer (the memory pointer) must be aligned to an 8-byte
-** boundary or subsequent behavior of SQLite will be undefined.
-** The minimum allocation size is capped at 2**12. Reasonable values
-** for the minimum allocation size are 2**5 through 2**8.</dd>
-**
-** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure. The argument specifies
-** alternative low-level mutex routines to be used in place
-** the mutex routines built into SQLite.)^ ^SQLite makes a copy of the
-** content of the [sqlite3_mutex_methods] structure before the call to
-** [sqlite3_config()] returns. ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** the entire mutexing subsystem is omitted from the build and hence calls to
-** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will
-** return [SQLITE_ERROR].</dd>
-**
-** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure. The
-** [sqlite3_mutex_methods]
-** structure is filled with the currently defined mutex routines.)^
-** This option can be used to overload the default mutex allocation
-** routines with a wrapper used to track mutex usage for performance
-** profiling or testing, for example. ^If SQLite is compiled with
-** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
-** the entire mutexing subsystem is omitted from the build and hence calls to
-** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
-** return [SQLITE_ERROR].</dd>
-**
-** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
-** <dd> ^(This option takes two arguments that determine the default
-** memory allocation for the lookaside memory allocator on each
-** [database connection]. The first argument is the
-** size of each lookaside buffer slot and the second is the number of
-** slots allocated to each database connection.)^ ^(This option sets the
-** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
-** verb to [sqlite3_db_config()] can be used to change the lookaside
-** configuration on individual connections.)^ </dd>
-**
-** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
-** <dd> ^(This option takes a single argument which is a pointer to
-** an [sqlite3_pcache_methods2] object. This object specifies the interface
-** to a custom page cache implementation.)^ ^SQLite makes a copy of the
-** object and uses it for page cache memory allocations.</dd>
-**
-** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** [sqlite3_pcache_methods2] object. SQLite copies of the current
-** page cache implementation into that object.)^ </dd>
-**
-** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
-** <dd> ^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a
-** function with a call signature of void(*)(void*,int,const char*),
-** and a pointer to void. ^If the function pointer is not NULL, it is
-** invoked by [sqlite3_log()] to process each logging event. ^If the
-** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op.
-** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is
-** passed through as the first parameter to the application-defined logger
-** function whenever that function is invoked. ^The second parameter to
-** the logger function is a copy of the first parameter to the corresponding
-** [sqlite3_log()] call and is intended to be a [result code] or an
-** [extended result code]. ^The third parameter passed to the logger is
-** log message after formatting via [sqlite3_snprintf()].
-** The SQLite logging interface is not reentrant; the logger function
-** supplied by the application must not invoke any SQLite interface.
-** In a multi-threaded application, the application-defined logger
-** function must be threadsafe. </dd>
-**
-** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
-** <dd> This option takes a single argument of type int. If non-zero, then
-** URI handling is globally enabled. If the parameter is zero, then URI handling
-** is globally disabled. If URI handling is globally enabled, all filenames
-** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
-** specified as part of [ATTACH] commands are interpreted as URIs, regardless
-** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
-** connection is opened. If it is globally disabled, filenames are
-** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
-** database connection is opened. By default, URI handling is globally
-** disabled. The default value may be changed by compiling with the
-** [SQLITE_USE_URI] symbol defined.
-**
-** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
-** <dd> This option takes a single integer argument which is interpreted as
-** a boolean in order to enable or disable the use of covering indices for
-** full table scans in the query optimizer. The default setting is determined
-** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
-** if that compile-time option is omitted.
-** The ability to disable the use of covering indices for full table scans
-** is because some incorrectly coded legacy applications might malfunction
-** malfunction when the optimization is enabled. Providing the ability to
-** disable the optimization allows the older, buggy application code to work
-** without change even with newer versions of SQLite.
-**
-** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
-** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
-** <dd> These options are obsolete and should not be used by new code.
-** They are retained for backwards compatibility but are now no-ops.
-** </dl>
-**
-** [[SQLITE_CONFIG_SQLLOG]]
-** <dt>SQLITE_CONFIG_SQLLOG
-** <dd>This option is only available if sqlite is compiled with the
-** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should
-** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int).
-** The second should be of type (void*). The callback is invoked by the library
-** in three separate circumstances, identified by the value passed as the
-** fourth parameter. If the fourth parameter is 0, then the database connection
-** passed as the second argument has just been opened. The third argument
-** points to a buffer containing the name of the main database file. If the
-** fourth parameter is 1, then the SQL statement that the third parameter
-** points to has just been executed. Or, if the fourth parameter is 2, then
-** the connection being passed as the second parameter is being closed. The
-** third parameter is passed NULL In this case.
-** </dl>
-*/
-#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
-#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
-#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
-#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */
-#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
-#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
-#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
-#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */
-#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */
-/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
-#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */
-#define SQLITE_CONFIG_PCACHE 14 /* no-op */
-#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */
-#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */
-#define SQLITE_CONFIG_URI 17 /* int */
-#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
-#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
-#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
-#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
-
-/*
-** CAPI3REF: Database Connection Configuration Options
-**
-** These constants are the available integer configuration options that
-** can be passed as the second argument to the [sqlite3_db_config()] interface.
-**
-** New configuration options may be added in future releases of SQLite.
-** Existing configuration options might be discontinued. Applications
-** should check the return code from [sqlite3_db_config()] to make sure that
-** the call worked. ^The [sqlite3_db_config()] interface will return a
-** non-zero [error code] if a discontinued or unsupported configuration option
-** is invoked.
-**
-** <dl>
-** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
-** <dd> ^This option takes three additional arguments that determine the
-** [lookaside memory allocator] configuration for the [database connection].
-** ^The first argument (the third parameter to [sqlite3_db_config()] is a
-** pointer to a memory buffer to use for lookaside memory.
-** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
-** may be NULL in which case SQLite will allocate the
-** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the
-** size of each lookaside buffer slot. ^The third argument is the number of
-** slots. The size of the buffer in the first argument must be greater than
-** or equal to the product of the second and third arguments. The buffer
-** must be aligned to an 8-byte boundary. ^If the second argument to
-** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
-** rounded down to the next smaller multiple of 8. ^(The lookaside memory
-** configuration for a database connection can only be changed when that
-** connection is not currently using lookaside memory, or in other words
-** when the "current value" returned by
-** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
-** Any attempt to change the lookaside memory configuration when lookaside
-** memory is in use leaves the configuration unchanged and returns
-** [SQLITE_BUSY].)^</dd>
-**
-** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
-** <dd> ^This option is used to enable or disable the enforcement of
-** [foreign key constraints]. There should be two additional arguments.
-** The first argument is an integer which is 0 to disable FK enforcement,
-** positive to enable FK enforcement or negative to leave FK enforcement
-** unchanged. The second parameter is a pointer to an integer into which
-** is written 0 or 1 to indicate whether FK enforcement is off or on
-** following this call. The second parameter may be a NULL pointer, in
-** which case the FK enforcement setting is not reported back. </dd>
-**
-** <dt>SQLITE_DBCONFIG_ENABLE_TRIGGER</dt>
-** <dd> ^This option is used to enable or disable [CREATE TRIGGER | triggers].
-** There should be two additional arguments.
-** The first argument is an integer which is 0 to disable triggers,
-** positive to enable triggers or negative to leave the setting unchanged.
-** The second parameter is a pointer to an integer into which
-** is written 0 or 1 to indicate whether triggers are disabled or enabled
-** following this call. The second parameter may be a NULL pointer, in
-** which case the trigger setting is not reported back. </dd>
-**
-** </dl>
-*/
-#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
-#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
-#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
-
-
-/*
-** CAPI3REF: Enable Or Disable Extended Result Codes
-**
-** ^The sqlite3_extended_result_codes() routine enables or disables the
-** [extended result codes] feature of SQLite. ^The extended result
-** codes are disabled by default for historical compatibility.
-*/
-SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
-
-/*
-** CAPI3REF: Last Insert Rowid
-**
-** ^Each entry in an SQLite table has a unique 64-bit signed
-** integer key called the [ROWID | "rowid"]. ^The rowid is always available
-** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
-** names are not also used by explicitly declared columns. ^If
-** the table has a column of type [INTEGER PRIMARY KEY] then that column
-** is another alias for the rowid.
-**
-** ^This routine returns the [rowid] of the most recent
-** successful [INSERT] into the database from the [database connection]
-** in the first argument. ^As of SQLite version 3.7.7, this routines
-** records the last insert rowid of both ordinary tables and [virtual tables].
-** ^If no successful [INSERT]s
-** have ever occurred on that database connection, zero is returned.
-**
-** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
-** method, then this routine will return the [rowid] of the inserted
-** row as long as the trigger or virtual table method is running.
-** But once the trigger or virtual table method ends, the value returned
-** by this routine reverts to what it was before the trigger or virtual
-** table method began.)^
-**
-** ^An [INSERT] that fails due to a constraint violation is not a
-** successful [INSERT] and does not change the value returned by this
-** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK,
-** and INSERT OR ABORT make no changes to the return value of this
-** routine when their insertion fails. ^(When INSERT OR REPLACE
-** encounters a constraint violation, it does not fail. The
-** INSERT continues to completion after deleting rows that caused
-** the constraint problem so INSERT OR REPLACE will always change
-** the return value of this interface.)^
-**
-** ^For the purposes of this routine, an [INSERT] is considered to
-** be successful even if it is subsequently rolled back.
-**
-** This function is accessible to SQL statements via the
-** [last_insert_rowid() SQL function].
-**
-** If a separate thread performs a new [INSERT] on the same
-** database connection while the [sqlite3_last_insert_rowid()]
-** function is running and thus changes the last insert [rowid],
-** then the value returned by [sqlite3_last_insert_rowid()] is
-** unpredictable and might not equal either the old or the new
-** last insert [rowid].
-*/
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
-
-/*
-** CAPI3REF: Count The Number Of Rows Modified
-**
-** ^This function returns the number of database rows that were changed
-** or inserted or deleted by the most recently completed SQL statement
-** on the [database connection] specified by the first parameter.
-** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
-** or [DELETE] statement are counted. Auxiliary changes caused by
-** triggers or [foreign key actions] are not counted.)^ Use the
-** [sqlite3_total_changes()] function to find the total number of changes
-** including changes caused by triggers and foreign key actions.
-**
-** ^Changes to a view that are simulated by an [INSTEAD OF trigger]
-** are not counted. Only real table changes are counted.
-**
-** ^(A "row change" is a change to a single row of a single table
-** caused by an INSERT, DELETE, or UPDATE statement. Rows that
-** are changed as side effects of [REPLACE] constraint resolution,
-** rollback, ABORT processing, [DROP TABLE], or by any other
-** mechanisms do not count as direct row changes.)^
-**
-** A "trigger context" is a scope of execution that begins and
-** ends with the script of a [CREATE TRIGGER | trigger].
-** Most SQL statements are
-** evaluated outside of any trigger. This is the "top level"
-** trigger context. If a trigger fires from the top level, a
-** new trigger context is entered for the duration of that one
-** trigger. Subtriggers create subcontexts for their duration.
-**
-** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
-** not create a new trigger context.
-**
-** ^This function returns the number of direct row changes in the
-** most recent INSERT, UPDATE, or DELETE statement within the same
-** trigger context.
-**
-** ^Thus, when called from the top level, this function returns the
-** number of changes in the most recent INSERT, UPDATE, or DELETE
-** that also occurred at the top level. ^(Within the body of a trigger,
-** the sqlite3_changes() interface can be called to find the number of
-** changes in the most recently completed INSERT, UPDATE, or DELETE
-** statement within the body of the same trigger.
-** However, the number returned does not include changes
-** caused by subtriggers since those have their own context.)^
-**
-** See also the [sqlite3_total_changes()] interface, the
-** [count_changes pragma], and the [changes() SQL function].
-**
-** If a separate thread makes changes on the same database connection
-** while [sqlite3_changes()] is running then the value returned
-** is unpredictable and not meaningful.
-*/
-SQLITE_API int sqlite3_changes(sqlite3*);
-
-/*
-** CAPI3REF: Total Number Of Rows Modified
-**
-** ^This function returns the number of row changes caused by [INSERT],
-** [UPDATE] or [DELETE] statements since the [database connection] was opened.
-** ^(The count returned by sqlite3_total_changes() includes all changes
-** from all [CREATE TRIGGER | trigger] contexts and changes made by
-** [foreign key actions]. However,
-** the count does not include changes used to implement [REPLACE] constraints,
-** do rollbacks or ABORT processing, or [DROP TABLE] processing. The
-** count does not include rows of views that fire an [INSTEAD OF trigger],
-** though if the INSTEAD OF trigger makes changes of its own, those changes
-** are counted.)^
-** ^The sqlite3_total_changes() function counts the changes as soon as
-** the statement that makes them is completed (when the statement handle
-** is passed to [sqlite3_reset()] or [sqlite3_finalize()]).
-**
-** See also the [sqlite3_changes()] interface, the
-** [count_changes pragma], and the [total_changes() SQL function].
-**
-** If a separate thread makes changes on the same database connection
-** while [sqlite3_total_changes()] is running then the value
-** returned is unpredictable and not meaningful.
-*/
-SQLITE_API int sqlite3_total_changes(sqlite3*);
-
-/*
-** CAPI3REF: Interrupt A Long-Running Query
-**
-** ^This function causes any pending database operation to abort and
-** return at its earliest opportunity. This routine is typically
-** called in response to a user action such as pressing "Cancel"
-** or Ctrl-C where the user wants a long query operation to halt
-** immediately.
-**
-** ^It is safe to call this routine from a thread different from the
-** thread that is currently running the database operation. But it
-** is not safe to call this routine with a [database connection] that
-** is closed or might close before sqlite3_interrupt() returns.
-**
-** ^If an SQL operation is very nearly finished at the time when
-** sqlite3_interrupt() is called, then it might not have an opportunity
-** to be interrupted and might continue to completion.
-**
-** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT].
-** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE
-** that is inside an explicit transaction, then the entire transaction
-** will be rolled back automatically.
-**
-** ^The sqlite3_interrupt(D) call is in effect until all currently running
-** SQL statements on [database connection] D complete. ^Any new SQL statements
-** that are started after the sqlite3_interrupt() call and before the
-** running statements reaches zero are interrupted as if they had been
-** running prior to the sqlite3_interrupt() call. ^New SQL statements
-** that are started after the running statement count reaches zero are
-** not effected by the sqlite3_interrupt().
-** ^A call to sqlite3_interrupt(D) that occurs when there are no running
-** SQL statements is a no-op and has no effect on SQL statements
-** that are started after the sqlite3_interrupt() call returns.
-**
-** If the database connection closes while [sqlite3_interrupt()]
-** is running then bad things will likely happen.
-*/
-SQLITE_API void sqlite3_interrupt(sqlite3*);
-
-/*
-** CAPI3REF: Determine If An SQL Statement Is Complete
-**
-** These routines are useful during command-line input to determine if the
-** currently entered text seems to form a complete SQL statement or
-** if additional input is needed before sending the text into
-** SQLite for parsing. ^These routines return 1 if the input string
-** appears to be a complete SQL statement. ^A statement is judged to be
-** complete if it ends with a semicolon token and is not a prefix of a
-** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within
-** string literals or quoted identifier names or comments are not
-** independent tokens (they are part of the token in which they are
-** embedded) and thus do not count as a statement terminator. ^Whitespace
-** and comments that follow the final semicolon are ignored.
-**
-** ^These routines return 0 if the statement is incomplete. ^If a
-** memory allocation fails, then SQLITE_NOMEM is returned.
-**
-** ^These routines do not parse the SQL statements thus
-** will not detect syntactically incorrect SQL.
-**
-** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior
-** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked
-** automatically by sqlite3_complete16(). If that initialization fails,
-** then the return value from sqlite3_complete16() will be non-zero
-** regardless of whether or not the input SQL is complete.)^
-**
-** The input to [sqlite3_complete()] must be a zero-terminated
-** UTF-8 string.
-**
-** The input to [sqlite3_complete16()] must be a zero-terminated
-** UTF-16 string in native byte order.
-*/
-SQLITE_API int sqlite3_complete(const char *sql);
-SQLITE_API int sqlite3_complete16(const void *sql);
-
-/*
-** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
-**
-** ^This routine sets a callback function that might be invoked whenever
-** an attempt is made to open a database table that another thread
-** or process has locked.
-**
-** ^If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
-** is returned immediately upon encountering the lock. ^If the busy callback
-** is not NULL, then the callback might be invoked with two arguments.
-**
-** ^The first argument to the busy handler is a copy of the void* pointer which
-** is the third argument to sqlite3_busy_handler(). ^The second argument to
-** the busy handler callback is the number of times that the busy handler has
-** been invoked for this locking event. ^If the
-** busy callback returns 0, then no additional attempts are made to
-** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned.
-** ^If the callback returns non-zero, then another attempt
-** is made to open the database for reading and the cycle repeats.
-**
-** The presence of a busy handler does not guarantee that it will be invoked
-** when there is lock contention. ^If SQLite determines that invoking the busy
-** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY]
-** or [SQLITE_IOERR_BLOCKED] instead of invoking the busy handler.
-** Consider a scenario where one process is holding a read lock that
-** it is trying to promote to a reserved lock and
-** a second process is holding a reserved lock that it is trying
-** to promote to an exclusive lock. The first process cannot proceed
-** because it is blocked by the second and the second process cannot
-** proceed because it is blocked by the first. If both processes
-** invoke the busy handlers, neither will make any progress. Therefore,
-** SQLite returns [SQLITE_BUSY] for the first process, hoping that this
-** will induce the first process to release its read lock and allow
-** the second process to proceed.
-**
-** ^The default busy callback is NULL.
-**
-** ^The [SQLITE_BUSY] error is converted to [SQLITE_IOERR_BLOCKED]
-** when SQLite is in the middle of a large transaction where all the
-** changes will not fit into the in-memory cache. SQLite will
-** already hold a RESERVED lock on the database file, but it needs
-** to promote this lock to EXCLUSIVE so that it can spill cache
-** pages into the database file without harm to concurrent
-** readers. ^If it is unable to promote the lock, then the in-memory
-** cache will be left in an inconsistent state and so the error
-** code is promoted from the relatively benign [SQLITE_BUSY] to
-** the more severe [SQLITE_IOERR_BLOCKED]. ^This error code promotion
-** forces an automatic rollback of the changes. See the
-** <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
-** CorruptionFollowingBusyError</a> wiki page for a discussion of why
-** this is important.
-**
-** ^(There can only be a single busy handler defined for each
-** [database connection]. Setting a new busy handler clears any
-** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()]
-** will also set or clear the busy handler.
-**
-** The busy callback should not take any actions which modify the
-** database connection that invoked the busy handler. Any such actions
-** result in undefined behavior.
-**
-** A busy handler must not close the database connection
-** or [prepared statement] that invoked the busy handler.
-*/
-SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
-
-/*
-** CAPI3REF: Set A Busy Timeout
-**
-** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
-** for a specified amount of time when a table is locked. ^The handler
-** will sleep multiple times until at least "ms" milliseconds of sleeping
-** have accumulated. ^After at least "ms" milliseconds of sleeping,
-** the handler returns 0 which causes [sqlite3_step()] to return
-** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
-**
-** ^Calling this routine with an argument less than or equal to zero
-** turns off all busy handlers.
-**
-** ^(There can only be a single busy handler for a particular
-** [database connection] any any given moment. If another busy handler
-** was defined (using [sqlite3_busy_handler()]) prior to calling
-** this routine, that other busy handler is cleared.)^
-*/
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
-
-/*
-** CAPI3REF: Convenience Routines For Running Queries
-**
-** This is a legacy interface that is preserved for backwards compatibility.
-** Use of this interface is not recommended.
-**
-** Definition: A <b>result table</b> is memory data structure created by the
-** [sqlite3_get_table()] interface. A result table records the
-** complete query results from one or more queries.
-**
-** The table conceptually has a number of rows and columns. But
-** these numbers are not part of the result table itself. These
-** numbers are obtained separately. Let N be the number of rows
-** and M be the number of columns.
-**
-** A result table is an array of pointers to zero-terminated UTF-8 strings.
-** There are (N+1)*M elements in the array. The first M pointers point
-** to zero-terminated strings that contain the names of the columns.
-** The remaining entries all point to query results. NULL values result
-** in NULL pointers. All other values are in their UTF-8 zero-terminated
-** string representation as returned by [sqlite3_column_text()].
-**
-** A result table might consist of one or more memory allocations.
-** It is not safe to pass a result table directly to [sqlite3_free()].
-** A result table should be deallocated using [sqlite3_free_table()].
-**
-** ^(As an example of the result table format, suppose a query result
-** is as follows:
-**
-** <blockquote><pre>
-** Name | Age
-** -----------------------
-** Alice | 43
-** Bob | 28
-** Cindy | 21
-** </pre></blockquote>
-**
-** There are two column (M==2) and three rows (N==3). Thus the
-** result table has 8 entries. Suppose the result table is stored
-** in an array names azResult. Then azResult holds this content:
-**
-** <blockquote><pre>
-** azResult&#91;0] = "Name";
-** azResult&#91;1] = "Age";
-** azResult&#91;2] = "Alice";
-** azResult&#91;3] = "43";
-** azResult&#91;4] = "Bob";
-** azResult&#91;5] = "28";
-** azResult&#91;6] = "Cindy";
-** azResult&#91;7] = "21";
-** </pre></blockquote>)^
-**
-** ^The sqlite3_get_table() function evaluates one or more
-** semicolon-separated SQL statements in the zero-terminated UTF-8
-** string of its 2nd parameter and returns a result table to the
-** pointer given in its 3rd parameter.
-**
-** After the application has finished with the result from sqlite3_get_table(),
-** it must pass the result table pointer to sqlite3_free_table() in order to
-** release the memory that was malloced. Because of the way the
-** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
-** function must not try to call [sqlite3_free()] directly. Only
-** [sqlite3_free_table()] is able to release the memory properly and safely.
-**
-** The sqlite3_get_table() interface is implemented as a wrapper around
-** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access
-** to any internal data structures of SQLite. It uses only the public
-** interface defined here. As a consequence, errors that occur in the
-** wrapper layer outside of the internal [sqlite3_exec()] call are not
-** reflected in subsequent calls to [sqlite3_errcode()] or
-** [sqlite3_errmsg()].
-*/
-SQLITE_API int sqlite3_get_table(
- sqlite3 *db, /* An open database */
- const char *zSql, /* SQL to be evaluated */
- char ***pazResult, /* Results of the query */
- int *pnRow, /* Number of result rows written here */
- int *pnColumn, /* Number of result columns written here */
- char **pzErrmsg /* Error msg written here */
-);
-SQLITE_API void sqlite3_free_table(char **result);
-
-/*
-** CAPI3REF: Formatted String Printing Functions
-**
-** These routines are work-alikes of the "printf()" family of functions
-** from the standard C library.
-**
-** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
-** results into memory obtained from [sqlite3_malloc()].
-** The strings returned by these two routines should be
-** released by [sqlite3_free()]. ^Both routines return a
-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
-** memory to hold the resulting string.
-**
-** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
-** the standard C library. The result is written into the
-** buffer supplied as the second parameter whose size is given by
-** the first parameter. Note that the order of the
-** first two parameters is reversed from snprintf().)^ This is an
-** historical accident that cannot be fixed without breaking
-** backwards compatibility. ^(Note also that sqlite3_snprintf()
-** returns a pointer to its buffer instead of the number of
-** characters actually written into the buffer.)^ We admit that
-** the number of characters written would be a more useful return
-** value but we cannot change the implementation of sqlite3_snprintf()
-** now without breaking compatibility.
-**
-** ^As long as the buffer size is greater than zero, sqlite3_snprintf()
-** guarantees that the buffer is always zero-terminated. ^The first
-** parameter "n" is the total size of the buffer, including space for
-** the zero terminator. So the longest string that can be completely
-** written will be n-1 characters.
-**
-** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
-**
-** These routines all implement some additional formatting
-** options that are useful for constructing SQL statements.
-** All of the usual printf() formatting options apply. In addition, there
-** is are "%q", "%Q", and "%z" options.
-**
-** ^(The %q option works like %s in that it substitutes a nul-terminated
-** string from the argument list. But %q also doubles every '\'' character.
-** %q is designed for use inside a string literal.)^ By doubling each '\''
-** character it escapes that character and allows it to be inserted into
-** the string.
-**
-** For example, assume the string variable zText contains text as follows:
-**
-** <blockquote><pre>
-** char *zText = "It's a happy day!";
-** </pre></blockquote>
-**
-** One can use this text in an SQL statement as follows:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** Because the %q format string is used, the '\'' character in zText
-** is escaped and the SQL generated is as follows:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It''s a happy day!')
-** </pre></blockquote>
-**
-** This is correct. Had we used %s instead of %q, the generated SQL
-** would have looked like this:
-**
-** <blockquote><pre>
-** INSERT INTO table1 VALUES('It's a happy day!');
-** </pre></blockquote>
-**
-** This second example is an SQL syntax error. As a general rule you should
-** always use %q instead of %s when inserting text into a string literal.
-**
-** ^(The %Q option works like %q except it also adds single quotes around
-** the outside of the total string. Additionally, if the parameter in the
-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
-** single quotes).)^ So, for example, one could say:
-**
-** <blockquote><pre>
-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
-** sqlite3_exec(db, zSQL, 0, 0, 0);
-** sqlite3_free(zSQL);
-** </pre></blockquote>
-**
-** The code above will render a correct SQL statement in the zSQL
-** variable even if the zText variable is a NULL pointer.
-**
-** ^(The "%z" formatting option works like "%s" but with the
-** addition that after the string has been read and copied into
-** the result, [sqlite3_free()] is called on the input string.)^
-*/
-SQLITE_API char *sqlite3_mprintf(const char*,...);
-SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
-
-/*
-** CAPI3REF: Memory Allocation Subsystem
-**
-** The SQLite core uses these three routines for all of its own
-** internal memory allocation needs. "Core" in the previous sentence
-** does not include operating-system specific VFS implementation. The
-** Windows VFS uses native malloc() and free() for some operations.
-**
-** ^The sqlite3_malloc() routine returns a pointer to a block
-** of memory at least N bytes in length, where N is the parameter.
-** ^If sqlite3_malloc() is unable to obtain sufficient free
-** memory, it returns a NULL pointer. ^If the parameter N to
-** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
-** a NULL pointer.
-**
-** ^Calling sqlite3_free() with a pointer previously returned
-** by sqlite3_malloc() or sqlite3_realloc() releases that memory so
-** that it might be reused. ^The sqlite3_free() routine is
-** a no-op if is called with a NULL pointer. Passing a NULL pointer
-** to sqlite3_free() is harmless. After being freed, memory
-** should neither be read nor written. Even reading previously freed
-** memory might result in a segmentation fault or other severe error.
-** Memory corruption, a segmentation fault, or other severe error
-** might result if sqlite3_free() is called with a non-NULL pointer that
-** was not obtained from sqlite3_malloc() or sqlite3_realloc().
-**
-** ^(The sqlite3_realloc() interface attempts to resize a
-** prior memory allocation to be at least N bytes, where N is the
-** second parameter. The memory allocation to be resized is the first
-** parameter.)^ ^ If the first parameter to sqlite3_realloc()
-** is a NULL pointer then its behavior is identical to calling
-** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc().
-** ^If the second parameter to sqlite3_realloc() is zero or
-** negative then the behavior is exactly the same as calling
-** sqlite3_free(P) where P is the first parameter to sqlite3_realloc().
-** ^sqlite3_realloc() returns a pointer to a memory allocation
-** of at least N bytes in size or NULL if sufficient memory is unavailable.
-** ^If M is the size of the prior allocation, then min(N,M) bytes
-** of the prior allocation are copied into the beginning of buffer returned
-** by sqlite3_realloc() and the prior allocation is freed.
-** ^If sqlite3_realloc() returns NULL, then the prior allocation
-** is not freed.
-**
-** ^The memory returned by sqlite3_malloc() and sqlite3_realloc()
-** is always aligned to at least an 8 byte boundary, or to a
-** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
-** option is used.
-**
-** In SQLite version 3.5.0 and 3.5.1, it was possible to define
-** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
-** implementation of these routines to be omitted. That capability
-** is no longer provided. Only built-in memory allocators can be used.
-**
-** Prior to SQLite version 3.7.10, the Windows OS interface layer called
-** the system malloc() and free() directly when converting
-** filenames between the UTF-8 encoding used by SQLite
-** and whatever filename encoding is used by the particular Windows
-** installation. Memory allocation errors were detected, but
-** they were reported back as [SQLITE_CANTOPEN] or
-** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
-**
-** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
-** must be either NULL or else pointers obtained from a prior
-** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
-** not yet been released.
-**
-** The application must not read or write any part of
-** a block of memory after it has been released using
-** [sqlite3_free()] or [sqlite3_realloc()].
-*/
-SQLITE_API void *sqlite3_malloc(int);
-SQLITE_API void *sqlite3_realloc(void*, int);
-SQLITE_API void sqlite3_free(void*);
-
-/*
-** CAPI3REF: Memory Allocator Statistics
-**
-** SQLite provides these two interfaces for reporting on the status
-** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
-** routines, which form the built-in memory allocation subsystem.
-**
-** ^The [sqlite3_memory_used()] routine returns the number of bytes
-** of memory currently outstanding (malloced but not freed).
-** ^The [sqlite3_memory_highwater()] routine returns the maximum
-** value of [sqlite3_memory_used()] since the high-water mark
-** was last reset. ^The values returned by [sqlite3_memory_used()] and
-** [sqlite3_memory_highwater()] include any overhead
-** added by SQLite in its implementation of [sqlite3_malloc()],
-** but not overhead added by the any underlying system library
-** routines that [sqlite3_malloc()] may call.
-**
-** ^The memory high-water mark is reset to the current value of
-** [sqlite3_memory_used()] if and only if the parameter to
-** [sqlite3_memory_highwater()] is true. ^The value returned
-** by [sqlite3_memory_highwater(1)] is the high-water mark
-** prior to the reset.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
-
-/*
-** CAPI3REF: Pseudo-Random Number Generator
-**
-** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
-** select random [ROWID | ROWIDs] when inserting new records into a table that
-** already uses the largest possible [ROWID]. The PRNG is also used for
-** the build-in random() and randomblob() SQL functions. This interface allows
-** applications to access the same PRNG for other purposes.
-**
-** ^A call to this routine stores N bytes of randomness into buffer P.
-**
-** ^The first time this routine is invoked (either internally or by
-** the application) the PRNG is seeded using randomness obtained
-** from the xRandomness method of the default [sqlite3_vfs] object.
-** ^On all subsequent invocations, the pseudo-randomness is generated
-** internally and without recourse to the [sqlite3_vfs] xRandomness
-** method.
-*/
-SQLITE_API void sqlite3_randomness(int N, void *P);
-
-/*
-** CAPI3REF: Compile-Time Authorization Callbacks
-**
-** ^This routine registers an authorizer callback with a particular
-** [database connection], supplied in the first argument.
-** ^The authorizer callback is invoked as SQL statements are being compiled
-** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()],
-** [sqlite3_prepare16()] and [sqlite3_prepare16_v2()]. ^At various
-** points during the compilation process, as logic is being created
-** to perform various actions, the authorizer callback is invoked to
-** see if those actions are allowed. ^The authorizer callback should
-** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the
-** specific action but allow the SQL statement to continue to be
-** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be
-** rejected with an error. ^If the authorizer callback returns
-** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
-** then the [sqlite3_prepare_v2()] or equivalent call that triggered
-** the authorizer will fail with an error message.
-**
-** When the callback returns [SQLITE_OK], that means the operation
-** requested is ok. ^When the callback returns [SQLITE_DENY], the
-** [sqlite3_prepare_v2()] or equivalent call that triggered the
-** authorizer will fail with an error message explaining that
-** access is denied.
-**
-** ^The first parameter to the authorizer callback is a copy of the third
-** parameter to the sqlite3_set_authorizer() interface. ^The second parameter
-** to the callback is an integer [SQLITE_COPY | action code] that specifies
-** the particular action to be authorized. ^The third through sixth parameters
-** to the callback are zero-terminated strings that contain additional
-** details about the action to be authorized.
-**
-** ^If the action code is [SQLITE_READ]
-** and the callback returns [SQLITE_IGNORE] then the
-** [prepared statement] statement is constructed to substitute
-** a NULL value in place of the table column that would have
-** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE]
-** return can be used to deny an untrusted user access to individual
-** columns of a table.
-** ^If the action code is [SQLITE_DELETE] and the callback returns
-** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the
-** [truncate optimization] is disabled and all rows are deleted individually.
-**
-** An authorizer is used when [sqlite3_prepare | preparing]
-** SQL statements from an untrusted source, to ensure that the SQL statements
-** do not try to access data they are not allowed to see, or that they do not
-** try to execute malicious statements that damage the database. For
-** example, an application may allow a user to enter arbitrary
-** SQL queries for evaluation by a database. But the application does
-** not want the user to be able to make arbitrary changes to the
-** database. An authorizer could then be put in place while the
-** user-entered SQL is being [sqlite3_prepare | prepared] that
-** disallows everything except [SELECT] statements.
-**
-** Applications that need to process SQL from untrusted sources
-** might also consider lowering resource limits using [sqlite3_limit()]
-** and limiting database size using the [max_page_count] [PRAGMA]
-** in addition to using an authorizer.
-**
-** ^(Only a single authorizer can be in place on a database connection
-** at a time. Each call to sqlite3_set_authorizer overrides the
-** previous call.)^ ^Disable the authorizer by installing a NULL callback.
-** The authorizer is disabled by default.
-**
-** The authorizer callback must not do anything that will modify
-** the database connection that invoked the authorizer callback.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the
-** statement might be re-prepared during [sqlite3_step()] due to a
-** schema change. Hence, the application should ensure that the
-** correct authorizer callback remains in place during the [sqlite3_step()].
-**
-** ^Note that the authorizer callback is invoked only during
-** [sqlite3_prepare()] or its variants. Authorization is not
-** performed during statement evaluation in [sqlite3_step()], unless
-** as stated in the previous paragraph, sqlite3_step() invokes
-** sqlite3_prepare_v2() to reprepare a statement after a schema change.
-*/
-SQLITE_API int sqlite3_set_authorizer(
- sqlite3*,
- int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
- void *pUserData
-);
-
-/*
-** CAPI3REF: Authorizer Return Codes
-**
-** The [sqlite3_set_authorizer | authorizer callback function] must
-** return either [SQLITE_OK] or one of these two constants in order
-** to signal SQLite whether or not the action is permitted. See the
-** [sqlite3_set_authorizer | authorizer documentation] for additional
-** information.
-**
-** Note that SQLITE_IGNORE is also used as a [SQLITE_ROLLBACK | return code]
-** from the [sqlite3_vtab_on_conflict()] interface.
-*/
-#define SQLITE_DENY 1 /* Abort the SQL statement with an error */
-#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
-
-/*
-** CAPI3REF: Authorizer Action Codes
-**
-** The [sqlite3_set_authorizer()] interface registers a callback function
-** that is invoked to authorize certain SQL statement actions. The
-** second parameter to the callback is an integer code that specifies
-** what action is being authorized. These are the integer action codes that
-** the authorizer callback may be passed.
-**
-** These action code values signify what kind of operation is to be
-** authorized. The 3rd and 4th parameters to the authorization
-** callback function will be parameters or NULL depending on which of these
-** codes is used as the second parameter. ^(The 5th parameter to the
-** authorizer callback is the name of the database ("main", "temp",
-** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback
-** is the name of the inner-most trigger or view that is responsible for
-** the access attempt or NULL if this access attempt is directly from
-** top-level SQL code.
-*/
-/******************************************* 3rd ************ 4th ***********/
-#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
-#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */
-#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
-#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */
-#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */
-#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */
-#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */
-#define SQLITE_CREATE_VIEW 8 /* View Name NULL */
-#define SQLITE_DELETE 9 /* Table Name NULL */
-#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */
-#define SQLITE_DROP_TABLE 11 /* Table Name NULL */
-#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */
-#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */
-#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */
-#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */
-#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */
-#define SQLITE_DROP_VIEW 17 /* View Name NULL */
-#define SQLITE_INSERT 18 /* Table Name NULL */
-#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
-#define SQLITE_READ 20 /* Table Name Column Name */
-#define SQLITE_SELECT 21 /* NULL NULL */
-#define SQLITE_TRANSACTION 22 /* Operation NULL */
-#define SQLITE_UPDATE 23 /* Table Name Column Name */
-#define SQLITE_ATTACH 24 /* Filename NULL */
-#define SQLITE_DETACH 25 /* Database Name NULL */
-#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */
-#define SQLITE_REINDEX 27 /* Index Name NULL */
-#define SQLITE_ANALYZE 28 /* Table Name NULL */
-#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */
-#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
-#define SQLITE_FUNCTION 31 /* NULL Function Name */
-#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
-#define SQLITE_COPY 0 /* No longer used */
-
-/*
-** CAPI3REF: Tracing And Profiling Functions
-**
-** These routines register callback functions that can be used for
-** tracing and profiling the execution of SQL statements.
-**
-** ^The callback function registered by sqlite3_trace() is invoked at
-** various times when an SQL statement is being run by [sqlite3_step()].
-** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the
-** SQL statement text as the statement first begins executing.
-** ^(Additional sqlite3_trace() callbacks might occur
-** as each triggered subprogram is entered. The callbacks for triggers
-** contain a UTF-8 SQL comment that identifies the trigger.)^
-**
-** ^The callback function registered by sqlite3_profile() is invoked
-** as each SQL statement finishes. ^The profile callback contains
-** the original statement text and an estimate of wall-clock time
-** of how long that statement took to run. ^The profile callback
-** time is in units of nanoseconds, however the current implementation
-** is only capable of millisecond resolution so the six least significant
-** digits in the time are meaningless. Future versions of SQLite
-** might provide greater resolution on the profiler callback. The
-** sqlite3_profile() function is considered experimental and is
-** subject to change in future versions of SQLite.
-*/
-SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
- void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
-
-/*
-** CAPI3REF: Query Progress Callbacks
-**
-** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
-** function X to be invoked periodically during long running calls to
-** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
-** database connection D. An example use for this
-** interface is to keep a GUI updated during a large query.
-**
-** ^The parameter P is passed through as the only parameter to the
-** callback function X. ^The parameter N is the number of
-** [virtual machine instructions] that are evaluated between successive
-** invocations of the callback X.
-**
-** ^Only a single progress handler may be defined at one time per
-** [database connection]; setting a new progress handler cancels the
-** old one. ^Setting parameter X to NULL disables the progress handler.
-** ^The progress handler is also disabled by setting N to a value less
-** than 1.
-**
-** ^If the progress callback returns non-zero, the operation is
-** interrupted. This feature can be used to implement a
-** "Cancel" button on a GUI progress dialog box.
-**
-** The progress handler callback must not do anything that will modify
-** the database connection that invoked the progress handler.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-*/
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
-
-/*
-** CAPI3REF: Opening A New Database Connection
-**
-** ^These routines open an SQLite database file as specified by the
-** filename argument. ^The filename argument is interpreted as UTF-8 for
-** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte
-** order for sqlite3_open16(). ^(A [database connection] handle is usually
-** returned in *ppDb, even if an error occurs. The only exception is that
-** if SQLite is unable to allocate memory to hold the [sqlite3] object,
-** a NULL will be written into *ppDb instead of a pointer to the [sqlite3]
-** object.)^ ^(If the database is opened (and/or created) successfully, then
-** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The
-** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
-** an English language description of the error following a failure of any
-** of the sqlite3_open() routines.
-**
-** ^The default encoding for the database will be UTF-8 if
-** sqlite3_open() or sqlite3_open_v2() is called and
-** UTF-16 in the native byte order if sqlite3_open16() is used.
-**
-** Whether or not an error occurs when it is opened, resources
-** associated with the [database connection] handle should be released by
-** passing it to [sqlite3_close()] when it is no longer required.
-**
-** The sqlite3_open_v2() interface works like sqlite3_open()
-** except that it accepts two additional parameters for additional control
-** over the new database connection. ^(The flags parameter to
-** sqlite3_open_v2() can take one of
-** the following three values, optionally combined with the
-** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
-** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^
-**
-** <dl>
-** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
-** <dd>The database is opened in read-only mode. If the database does not
-** already exist, an error is returned.</dd>)^
-**
-** ^(<dt>[SQLITE_OPEN_READWRITE]</dt>
-** <dd>The database is opened for reading and writing if possible, or reading
-** only if the file is write protected by the operating system. In either
-** case the database must already exist, otherwise an error is returned.</dd>)^
-**
-** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
-** <dd>The database is opened for reading and writing, and is created if
-** it does not already exist. This is the behavior that is always used for
-** sqlite3_open() and sqlite3_open16().</dd>)^
-** </dl>
-**
-** If the 3rd parameter to sqlite3_open_v2() is not one of the
-** combinations shown above optionally combined with other
-** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
-** then the behavior is undefined.
-**
-** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
-** opens in the multi-thread [threading mode] as long as the single-thread
-** mode has not been set at compile-time or start-time. ^If the
-** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
-** in the serialized [threading mode] unless single-thread was
-** previously selected at compile-time or start-time.
-** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be
-** eligible to use [shared cache mode], regardless of whether or not shared
-** cache is enabled using [sqlite3_enable_shared_cache()]. ^The
-** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not
-** participate in [shared cache mode] even if it is enabled.
-**
-** ^The fourth parameter to sqlite3_open_v2() is the name of the
-** [sqlite3_vfs] object that defines the operating system interface that
-** the new database connection should use. ^If the fourth parameter is
-** a NULL pointer then the default [sqlite3_vfs] object is used.
-**
-** ^If the filename is ":memory:", then a private, temporary in-memory database
-** is created for the connection. ^This in-memory database will vanish when
-** the database connection is closed. Future versions of SQLite might
-** make use of additional special filenames that begin with the ":" character.
-** It is recommended that when a database filename actually does begin with
-** a ":" character you should prefix the filename with a pathname such as
-** "./" to avoid ambiguity.
-**
-** ^If the filename is an empty string, then a private, temporary
-** on-disk database will be created. ^This private database will be
-** automatically deleted as soon as the database connection is closed.
-**
-** [[URI filenames in sqlite3_open()]] <h3>URI Filenames</h3>
-**
-** ^If [URI filename] interpretation is enabled, and the filename argument
-** begins with "file:", then the filename is interpreted as a URI. ^URI
-** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
-** set in the fourth argument to sqlite3_open_v2(), or if it has
-** been enabled globally using the [SQLITE_CONFIG_URI] option with the
-** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
-** As of SQLite version 3.7.7, URI filename interpretation is turned off
-** by default, but future releases of SQLite might enable URI filename
-** interpretation by default. See "[URI filenames]" for additional
-** information.
-**
-** URI filenames are parsed according to RFC 3986. ^If the URI contains an
-** authority, then it must be either an empty string or the string
-** "localhost". ^If the authority is not an empty string or "localhost", an
-** error is returned to the caller. ^The fragment component of a URI, if
-** present, is ignored.
-**
-** ^SQLite uses the path component of the URI as the name of the disk file
-** which contains the database. ^If the path begins with a '/' character,
-** then it is interpreted as an absolute path. ^If the path does not begin
-** with a '/' (meaning that the authority section is omitted from the URI)
-** then the path is interpreted as a relative path.
-** ^On windows, the first component of an absolute path
-** is a drive specification (e.g. "C:").
-**
-** [[core URI query parameters]]
-** The query component of a URI may contain parameters that are interpreted
-** either by SQLite itself, or by a [VFS | custom VFS implementation].
-** SQLite interprets the following three query parameters:
-**
-** <ul>
-** <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
-** a VFS object that provides the operating system interface that should
-** be used to access the database file on disk. ^If this option is set to
-** an empty string the default VFS object is used. ^Specifying an unknown
-** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is
-** present, then the VFS specified by the option takes precedence over
-** the value passed as the fourth parameter to sqlite3_open_v2().
-**
-** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw",
-** "rwc", or "memory". Attempting to set it to any other value is
-** an error)^.
-** ^If "ro" is specified, then the database is opened for read-only
-** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the
-** third argument to sqlite3_open_v2(). ^If the mode option is set to
-** "rw", then the database is opened for read-write (but not create)
-** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had
-** been set. ^Value "rwc" is equivalent to setting both
-** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is
-** set to "memory" then a pure [in-memory database] that never reads
-** or writes from disk is used. ^It is an error to specify a value for
-** the mode parameter that is less restrictive than that specified by
-** the flags passed in the third parameter to sqlite3_open_v2().
-**
-** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or
-** "private". ^Setting it to "shared" is equivalent to setting the
-** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
-** sqlite3_open_v2(). ^Setting the cache parameter to "private" is
-** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
-** ^If sqlite3_open_v2() is used and the "cache" parameter is present in
-** a URI filename, its value overrides any behaviour requested by setting
-** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
-** </ul>
-**
-** ^Specifying an unknown parameter in the query component of a URI is not an
-** error. Future versions of SQLite might understand additional query
-** parameters. See "[query parameters with special meaning to SQLite]" for
-** additional information.
-**
-** [[URI filename examples]] <h3>URI filename examples</h3>
-**
-** <table border="1" align=center cellpadding=5>
-** <tr><th> URI filenames <th> Results
-** <tr><td> file:data.db <td>
-** Open the file "data.db" in the current directory.
-** <tr><td> file:/home/fred/data.db<br>
-** file:///home/fred/data.db <br>
-** file://localhost/home/fred/data.db <br> <td>
-** Open the database file "/home/fred/data.db".
-** <tr><td> file://darkstar/home/fred/data.db <td>
-** An error. "darkstar" is not a recognized authority.
-** <tr><td style="white-space:nowrap">
-** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db
-** <td> Windows only: Open the file "data.db" on fred's desktop on drive
-** C:. Note that the %20 escaping in this example is not strictly
-** necessary - space characters can be used literally
-** in URI filenames.
-** <tr><td> file:data.db?mode=ro&cache=private <td>
-** Open file "data.db" in the current directory for read-only access.
-** Regardless of whether or not shared-cache mode is enabled by
-** default, use a private cache.
-** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td>
-** Open file "/home/fred/data.db". Use the special VFS "unix-nolock".
-** <tr><td> file:data.db?mode=readonly <td>
-** An error. "readonly" is not a valid option for the "mode" parameter.
-** </table>
-**
-** ^URI hexadecimal escape sequences (%HH) are supported within the path and
-** query components of a URI. A hexadecimal escape sequence consists of a
-** percent sign - "%" - followed by exactly two hexadecimal digits
-** specifying an octet value. ^Before the path or query components of a
-** URI filename are interpreted, they are encoded using UTF-8 and all
-** hexadecimal escape sequences replaced by a single byte containing the
-** corresponding octet. If this process generates an invalid UTF-8 encoding,
-** the results are undefined.
-**
-** <b>Note to Windows users:</b> The encoding used for the filename argument
-** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever
-** codepage is currently defined. Filenames containing international
-** characters must be converted to UTF-8 prior to passing them into
-** sqlite3_open() or sqlite3_open_v2().
-**
-** <b>Note to Windows Runtime users:</b> The temporary directory must be set
-** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various
-** features that require the use of temporary files may fail.
-**
-** See also: [sqlite3_temp_directory]
-*/
-SQLITE_API int sqlite3_open(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb /* OUT: SQLite db handle */
-);
-SQLITE_API int sqlite3_open16(
- const void *filename, /* Database filename (UTF-16) */
- sqlite3 **ppDb /* OUT: SQLite db handle */
-);
-SQLITE_API int sqlite3_open_v2(
- const char *filename, /* Database filename (UTF-8) */
- sqlite3 **ppDb, /* OUT: SQLite db handle */
- int flags, /* Flags */
- const char *zVfs /* Name of VFS module to use */
-);
-
-/*
-** CAPI3REF: Obtain Values For URI Parameters
-**
-** These are utility routines, useful to VFS implementations, that check
-** to see if a database file was a URI that contained a specific query
-** parameter, and if so obtains the value of that query parameter.
-**
-** If F is the database filename pointer passed into the xOpen() method of
-** a VFS implementation when the flags parameter to xOpen() has one or
-** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and
-** P is the name of the query parameter, then
-** sqlite3_uri_parameter(F,P) returns the value of the P
-** parameter if it exists or a NULL pointer if P does not appear as a
-** query parameter on F. If P is a query parameter of F
-** has no explicit value, then sqlite3_uri_parameter(F,P) returns
-** a pointer to an empty string.
-**
-** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean
-** parameter and returns true (1) or false (0) according to the value
-** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the
-** value of query parameter P is one of "yes", "true", or "on" in any
-** case or if the value begins with a non-zero number. The
-** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of
-** query parameter P is one of "no", "false", or "off" in any case or
-** if the value begins with a numeric zero. If P is not a query
-** parameter on F or if the value of P is does not match any of the
-** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0).
-**
-** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
-** 64-bit signed integer and returns that integer, or D if P does not
-** exist. If the value of P is something other than an integer, then
-** zero is returned.
-**
-** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
-** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and
-** is not a database file pathname pointer that SQLite passed into the xOpen
-** VFS method, then the behavior of this routine is undefined and probably
-** undesirable.
-*/
-SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
-SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
-
-
-/*
-** CAPI3REF: Error Codes And Messages
-**
-** ^The sqlite3_errcode() interface returns the numeric [result code] or
-** [extended result code] for the most recent failed sqlite3_* API call
-** associated with a [database connection]. If a prior API call failed
-** but the most recent API call succeeded, the return value from
-** sqlite3_errcode() is undefined. ^The sqlite3_extended_errcode()
-** interface is the same except that it always returns the
-** [extended result code] even when extended result codes are
-** disabled.
-**
-** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
-** text that describes the error, as either UTF-8 or UTF-16 respectively.
-** ^(Memory to hold the error message string is managed internally.
-** The application does not need to worry about freeing the result.
-** However, the error string might be overwritten or deallocated by
-** subsequent calls to other SQLite interface functions.)^
-**
-** ^The sqlite3_errstr() interface returns the English-language text
-** that describes the [result code], as UTF-8.
-** ^(Memory to hold the error message string is managed internally
-** and must not be freed by the application)^.
-**
-** When the serialized [threading mode] is in use, it might be the
-** case that a second error occurs on a separate thread in between
-** the time of the first error and the call to these interfaces.
-** When that happens, the second error will be reported since these
-** interfaces always report the most recent result. To avoid
-** this, each thread can obtain exclusive use of the [database connection] D
-** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning
-** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after
-** all calls to the interfaces listed here are completed.
-**
-** If an interface fails with SQLITE_MISUSE, that means the interface
-** was invoked incorrectly by the application. In that case, the
-** error code and message may or may not be set.
-*/
-SQLITE_API int sqlite3_errcode(sqlite3 *db);
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
-SQLITE_API const char *sqlite3_errstr(int);
-
-/*
-** CAPI3REF: SQL Statement Object
-** KEYWORDS: {prepared statement} {prepared statements}
-**
-** An instance of this object represents a single SQL statement.
-** This object is variously known as a "prepared statement" or a
-** "compiled SQL statement" or simply as a "statement".
-**
-** The life of a statement object goes something like this:
-**
-** <ol>
-** <li> Create the object using [sqlite3_prepare_v2()] or a related
-** function.
-** <li> Bind values to [host parameters] using the sqlite3_bind_*()
-** interfaces.
-** <li> Run the SQL by calling [sqlite3_step()] one or more times.
-** <li> Reset the statement using [sqlite3_reset()] then go back
-** to step 2. Do this zero or more times.
-** <li> Destroy the object using [sqlite3_finalize()].
-** </ol>
-**
-** Refer to documentation on individual methods above for additional
-** information.
-*/
-typedef struct sqlite3_stmt sqlite3_stmt;
-
-/*
-** CAPI3REF: Run-time Limits
-**
-** ^(This interface allows the size of various constructs to be limited
-** on a connection by connection basis. The first parameter is the
-** [database connection] whose limit is to be set or queried. The
-** second parameter is one of the [limit categories] that define a
-** class of constructs to be size limited. The third parameter is the
-** new limit for that construct.)^
-**
-** ^If the new limit is a negative number, the limit is unchanged.
-** ^(For each limit category SQLITE_LIMIT_<i>NAME</i> there is a
-** [limits | hard upper bound]
-** set at compile-time by a C preprocessor macro called
-** [limits | SQLITE_MAX_<i>NAME</i>].
-** (The "_LIMIT_" in the name is changed to "_MAX_".))^
-** ^Attempts to increase a limit above its hard upper bound are
-** silently truncated to the hard upper bound.
-**
-** ^Regardless of whether or not the limit was changed, the
-** [sqlite3_limit()] interface returns the prior value of the limit.
-** ^Hence, to find the current value of a limit without changing it,
-** simply invoke this interface with the third parameter set to -1.
-**
-** Run-time limits are intended for use in applications that manage
-** both their own internal database and also databases that are controlled
-** by untrusted external sources. An example application might be a
-** web browser that has its own databases for storing history and
-** separate databases controlled by JavaScript applications downloaded
-** off the Internet. The internal databases can be given the
-** large, default limits. Databases managed by external sources can
-** be given much smaller limits designed to prevent a denial of service
-** attack. Developers might also want to use the [sqlite3_set_authorizer()]
-** interface to further control untrusted SQL. The size of the database
-** created by an untrusted script can be contained using the
-** [max_page_count] [PRAGMA].
-**
-** New run-time limit categories may be added in future releases.
-*/
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
-
-/*
-** CAPI3REF: Run-Time Limit Categories
-** KEYWORDS: {limit category} {*limit categories}
-**
-** These constants define various performance limits
-** that can be lowered at run-time using [sqlite3_limit()].
-** The synopsis of the meanings of the various limits is shown below.
-** Additional information is available at [limits | Limits in SQLite].
-**
-** <dl>
-** [[SQLITE_LIMIT_LENGTH]] ^(<dt>SQLITE_LIMIT_LENGTH</dt>
-** <dd>The maximum size of any string or BLOB or table row, in bytes.<dd>)^
-**
-** [[SQLITE_LIMIT_SQL_LENGTH]] ^(<dt>SQLITE_LIMIT_SQL_LENGTH</dt>
-** <dd>The maximum length of an SQL statement, in bytes.</dd>)^
-**
-** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt>
-** <dd>The maximum number of columns in a table definition or in the
-** result set of a [SELECT] or the maximum number of columns in an index
-** or in an ORDER BY or GROUP BY clause.</dd>)^
-**
-** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
-** <dd>The maximum depth of the parse tree on any expression.</dd>)^
-**
-** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
-** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
-**
-** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
-** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement. This limit is not currently
-** enforced, though that might be added in some future release of
-** SQLite.</dd>)^
-**
-** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
-** <dd>The maximum number of arguments on a function.</dd>)^
-**
-** [[SQLITE_LIMIT_ATTACHED]] ^(<dt>SQLITE_LIMIT_ATTACHED</dt>
-** <dd>The maximum number of [ATTACH | attached databases].)^</dd>
-**
-** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]]
-** ^(<dt>SQLITE_LIMIT_LIKE_PATTERN_LENGTH</dt>
-** <dd>The maximum length of the pattern argument to the [LIKE] or
-** [GLOB] operators.</dd>)^
-**
-** [[SQLITE_LIMIT_VARIABLE_NUMBER]]
-** ^(<dt>SQLITE_LIMIT_VARIABLE_NUMBER</dt>
-** <dd>The maximum index number of any [parameter] in an SQL statement.)^
-**
-** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
-** <dd>The maximum depth of recursion for triggers.</dd>)^
-** </dl>
-*/
-#define SQLITE_LIMIT_LENGTH 0
-#define SQLITE_LIMIT_SQL_LENGTH 1
-#define SQLITE_LIMIT_COLUMN 2
-#define SQLITE_LIMIT_EXPR_DEPTH 3
-#define SQLITE_LIMIT_COMPOUND_SELECT 4
-#define SQLITE_LIMIT_VDBE_OP 5
-#define SQLITE_LIMIT_FUNCTION_ARG 6
-#define SQLITE_LIMIT_ATTACHED 7
-#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8
-#define SQLITE_LIMIT_VARIABLE_NUMBER 9
-#define SQLITE_LIMIT_TRIGGER_DEPTH 10
-
-/*
-** CAPI3REF: Compiling An SQL Statement
-** KEYWORDS: {SQL statement compiler}
-**
-** To execute an SQL query, it must first be compiled into a byte-code
-** program using one of these routines.
-**
-** The first argument, "db", is a [database connection] obtained from a
-** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or
-** [sqlite3_open16()]. The database connection must not have been closed.
-**
-** The second argument, "zSql", is the statement to be compiled, encoded
-** as either UTF-8 or UTF-16. The sqlite3_prepare() and sqlite3_prepare_v2()
-** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
-** use UTF-16.
-**
-** ^If the nByte argument is less than zero, then zSql is read up to the
-** first zero terminator. ^If nByte is non-negative, then it is the maximum
-** number of bytes read from zSql. ^When nByte is non-negative, the
-** zSql string ends at either the first '\000' or '\u0000' character or
-** the nByte-th byte, whichever comes first. If the caller knows
-** that the supplied string is nul-terminated, then there is a small
-** performance advantage to be gained by passing an nByte parameter that
-** is equal to the number of bytes in the input string <i>including</i>
-** the nul-terminator bytes as this saves SQLite from having to
-** make a copy of the input string.
-**
-** ^If pzTail is not NULL then *pzTail is made to point to the first byte
-** past the end of the first SQL statement in zSql. These routines only
-** compile the first statement in zSql, so *pzTail is left pointing to
-** what remains uncompiled.
-**
-** ^*ppStmt is left pointing to a compiled [prepared statement] that can be
-** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set
-** to NULL. ^If the input text contains no SQL (if the input is an empty
-** string or a comment) then *ppStmt is set to NULL.
-** The calling procedure is responsible for deleting the compiled
-** SQL statement using [sqlite3_finalize()] after it has finished with it.
-** ppStmt may not be NULL.
-**
-** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK];
-** otherwise an [error code] is returned.
-**
-** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
-** recommended for all new programs. The two older interfaces are retained
-** for backwards compatibility, but their use is discouraged.
-** ^In the "v2" interfaces, the prepared statement
-** that is returned (the [sqlite3_stmt] object) contains a copy of the
-** original SQL text. This causes the [sqlite3_step()] interface to
-** behave differently in three ways:
-**
-** <ol>
-** <li>
-** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it
-** always used to do, [sqlite3_step()] will automatically recompile the SQL
-** statement and try to run it again.
-** </li>
-**
-** <li>
-** ^When an error occurs, [sqlite3_step()] will return one of the detailed
-** [error codes] or [extended error codes]. ^The legacy behavior was that
-** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
-** and the application would have to make a second call to [sqlite3_reset()]
-** in order to find the underlying cause of the problem. With the "v2" prepare
-** interfaces, the underlying reason for the error is returned immediately.
-** </li>
-**
-** <li>
-** ^If the specific value bound to [parameter | host parameter] in the
-** WHERE clause might influence the choice of query plan for a statement,
-** then the statement will be automatically recompiled, as if there had been
-** a schema change, on the first [sqlite3_step()] call following any change
-** to the [sqlite3_bind_text | bindings] of that [parameter].
-** ^The specific value of WHERE-clause [parameter] might influence the
-** choice of query plan if the parameter is the left-hand side of a [LIKE]
-** or [GLOB] operator or if the parameter is compared to an indexed column
-** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
-** the
-** </li>
-** </ol>
-*/
-SQLITE_API int sqlite3_prepare(
- sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare_v2(
- sqlite3 *db, /* Database handle */
- const char *zSql, /* SQL statement, UTF-8 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const char **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-SQLITE_API int sqlite3_prepare16_v2(
- sqlite3 *db, /* Database handle */
- const void *zSql, /* SQL statement, UTF-16 encoded */
- int nByte, /* Maximum length of zSql in bytes. */
- sqlite3_stmt **ppStmt, /* OUT: Statement handle */
- const void **pzTail /* OUT: Pointer to unused portion of zSql */
-);
-
-/*
-** CAPI3REF: Retrieving Statement SQL
-**
-** ^This interface can be used to retrieve a saved copy of the original
-** SQL text used to create a [prepared statement] if that statement was
-** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
-*/
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Determine If An SQL Statement Writes The Database
-**
-** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
-** and only if the [prepared statement] X makes no direct changes to
-** the content of the database file.
-**
-** Note that [application-defined SQL functions] or
-** [virtual tables] might change the database indirectly as a side effect.
-** ^(For example, if an application defines a function "eval()" that
-** calls [sqlite3_exec()], then the following SQL statement would
-** change the database file through side-effects:
-**
-** <blockquote><pre>
-** SELECT eval('DELETE FROM t1') FROM t2;
-** </pre></blockquote>
-**
-** But because the [SELECT] statement does not change the database file
-** directly, sqlite3_stmt_readonly() would still return true.)^
-**
-** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK],
-** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true,
-** since the statements themselves do not actually modify the database but
-** rather they control the timing of when other statements modify the
-** database. ^The [ATTACH] and [DETACH] statements also cause
-** sqlite3_stmt_readonly() to return true since, while those statements
-** change the configuration of a database connection, they do not make
-** changes to the content of the database files on disk.
-*/
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Determine If A Prepared Statement Has Been Reset
-**
-** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
-** [prepared statement] S has been stepped at least once using
-** [sqlite3_step(S)] but has not run to completion and/or has not
-** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S)
-** interface returns false if S is a NULL pointer. If S is not a
-** NULL pointer and is not a pointer to a valid [prepared statement]
-** object, then the behavior is undefined and probably undesirable.
-**
-** This interface can be used in combination [sqlite3_next_stmt()]
-** to locate all prepared statements associated with a database
-** connection that are in need of being reset. This can be used,
-** for example, in diagnostic routines to search for prepared
-** statements that are holding a transaction open.
-*/
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Dynamically Typed Value Object
-** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
-**
-** SQLite uses the sqlite3_value object to represent all values
-** that can be stored in a database table. SQLite uses dynamic typing
-** for the values it stores. ^Values stored in sqlite3_value objects
-** can be integers, floating point values, strings, BLOBs, or NULL.
-**
-** An sqlite3_value object may be either "protected" or "unprotected".
-** Some interfaces require a protected sqlite3_value. Other interfaces
-** will accept either a protected or an unprotected sqlite3_value.
-** Every interface that accepts sqlite3_value arguments specifies
-** whether or not it requires a protected sqlite3_value.
-**
-** The terms "protected" and "unprotected" refer to whether or not
-** a mutex is held. An internal mutex is held for a protected
-** sqlite3_value object but no mutex is held for an unprotected
-** sqlite3_value object. If SQLite is compiled to be single-threaded
-** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
-** or if SQLite is run in one of reduced mutex modes
-** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD]
-** then there is no distinction between protected and unprotected
-** sqlite3_value objects and they can be used interchangeably. However,
-** for maximum code portability it is recommended that applications
-** still make the distinction between protected and unprotected
-** sqlite3_value objects even when not strictly required.
-**
-** ^The sqlite3_value objects that are passed as parameters into the
-** implementation of [application-defined SQL functions] are protected.
-** ^The sqlite3_value object returned by
-** [sqlite3_column_value()] is unprotected.
-** Unprotected sqlite3_value objects may only be used with
-** [sqlite3_result_value()] and [sqlite3_bind_value()].
-** The [sqlite3_value_blob | sqlite3_value_type()] family of
-** interfaces require protected sqlite3_value objects.
-*/
-typedef struct Mem sqlite3_value;
-
-/*
-** CAPI3REF: SQL Function Context Object
-**
-** The context in which an SQL function executes is stored in an
-** sqlite3_context object. ^A pointer to an sqlite3_context object
-** is always first parameter to [application-defined SQL functions].
-** The application-defined SQL function implementation will pass this
-** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
-** [sqlite3_aggregate_context()], [sqlite3_user_data()],
-** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
-** and/or [sqlite3_set_auxdata()].
-*/
-typedef struct sqlite3_context sqlite3_context;
-
-/*
-** CAPI3REF: Binding Values To Prepared Statements
-** KEYWORDS: {host parameter} {host parameters} {host parameter name}
-** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
-**
-** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
-** literals may be replaced by a [parameter] that matches one of following
-** templates:
-**
-** <ul>
-** <li> ?
-** <li> ?NNN
-** <li> :VVV
-** <li> @VVV
-** <li> $VVV
-** </ul>
-**
-** In the templates above, NNN represents an integer literal,
-** and VVV represents an alphanumeric identifier.)^ ^The values of these
-** parameters (also called "host parameter names" or "SQL parameters")
-** can be set using the sqlite3_bind_*() routines defined here.
-**
-** ^The first argument to the sqlite3_bind_*() routines is always
-** a pointer to the [sqlite3_stmt] object returned from
-** [sqlite3_prepare_v2()] or its variants.
-**
-** ^The second argument is the index of the SQL parameter to be set.
-** ^The leftmost SQL parameter has an index of 1. ^When the same named
-** SQL parameter is used more than once, second and subsequent
-** occurrences have the same index as the first occurrence.
-** ^The index for named parameters can be looked up using the
-** [sqlite3_bind_parameter_index()] API if desired. ^The index
-** for "?NNN" parameters is the value of NNN.
-** ^The NNN value must be between 1 and the [sqlite3_limit()]
-** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
-**
-** ^The third argument is the value to bind to the parameter.
-**
-** ^(In those routines that have a fourth argument, its value is the
-** number of bytes in the parameter. To be clear: the value is the
-** number of <u>bytes</u> in the value, not the number of characters.)^
-** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
-** is negative, then the length of the string is
-** the number of bytes up to the first zero terminator.
-** If the fourth parameter to sqlite3_bind_blob() is negative, then
-** the behavior is undefined.
-** If a non-negative fourth parameter is provided to sqlite3_bind_text()
-** or sqlite3_bind_text16() then that parameter must be the byte offset
-** where the NUL terminator would occur assuming the string were NUL
-** terminated. If any NUL characters occur at byte offsets less than
-** the value of the fourth parameter then the resulting string value will
-** contain embedded NULs. The result of expressions involving strings
-** with embedded NULs is undefined.
-**
-** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
-** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
-** string after SQLite has finished with it. ^The destructor is called
-** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
-** sqlite3_bind_text(), or sqlite3_bind_text16() fails.
-** ^If the fifth argument is
-** the special value [SQLITE_STATIC], then SQLite assumes that the
-** information is in static, unmanaged space and does not need to be freed.
-** ^If the fifth argument has the value [SQLITE_TRANSIENT], then
-** SQLite makes its own private copy of the data immediately, before
-** the sqlite3_bind_*() routine returns.
-**
-** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
-** is filled with zeroes. ^A zeroblob uses a fixed amount of memory
-** (just an integer to hold its size) while it is being processed.
-** Zeroblobs are intended to serve as placeholders for BLOBs whose
-** content is later written using
-** [sqlite3_blob_open | incremental BLOB I/O] routines.
-** ^A negative value for the zeroblob results in a zero-length BLOB.
-**
-** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
-** for the [prepared statement] or with a prepared statement for which
-** [sqlite3_step()] has been called more recently than [sqlite3_reset()],
-** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_()
-** routine is passed a [prepared statement] that has been finalized, the
-** result is undefined and probably harmful.
-**
-** ^Bindings are not cleared by the [sqlite3_reset()] routine.
-** ^Unbound parameters are interpreted as NULL.
-**
-** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an
-** [error code] if anything goes wrong.
-** ^[SQLITE_RANGE] is returned if the parameter
-** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails.
-**
-** See also: [sqlite3_bind_parameter_count()],
-** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
-*/
-SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
-
-/*
-** CAPI3REF: Number Of SQL Parameters
-**
-** ^This routine can be used to find the number of [SQL parameters]
-** in a [prepared statement]. SQL parameters are tokens of the
-** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
-** placeholders for values that are [sqlite3_bind_blob | bound]
-** to the parameters at a later time.
-**
-** ^(This routine actually returns the index of the largest (rightmost)
-** parameter. For all forms except ?NNN, this will correspond to the
-** number of unique parameters. If parameters of the ?NNN form are used,
-** there may be gaps in the list.)^
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_name()], and
-** [sqlite3_bind_parameter_index()].
-*/
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Name Of A Host Parameter
-**
-** ^The sqlite3_bind_parameter_name(P,N) interface returns
-** the name of the N-th [SQL parameter] in the [prepared statement] P.
-** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA"
-** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA"
-** respectively.
-** In other words, the initial ":" or "$" or "@" or "?"
-** is included as part of the name.)^
-** ^Parameters of the form "?" without a following integer have no name
-** and are referred to as "nameless" or "anonymous parameters".
-**
-** ^The first host parameter has an index of 1, not 0.
-**
-** ^If the value N is out of range or if the N-th parameter is
-** nameless, then NULL is returned. ^The returned string is
-** always in UTF-8 encoding even if the named parameter was
-** originally specified as UTF-16 in [sqlite3_prepare16()] or
-** [sqlite3_prepare16_v2()].
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
-*/
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
-
-/*
-** CAPI3REF: Index Of A Parameter With A Given Name
-**
-** ^Return the index of an SQL parameter given its name. ^The
-** index value returned is suitable for use as the second
-** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero
-** is returned if no matching parameter is found. ^The parameter
-** name must be given in UTF-8 even if the original statement
-** was prepared from UTF-16 text using [sqlite3_prepare16_v2()].
-**
-** See also: [sqlite3_bind_blob|sqlite3_bind()],
-** [sqlite3_bind_parameter_count()], and
-** [sqlite3_bind_parameter_index()].
-*/
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
-
-/*
-** CAPI3REF: Reset All Bindings On A Prepared Statement
-**
-** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
-** the [sqlite3_bind_blob | bindings] on a [prepared statement].
-** ^Use this routine to reset all host parameters to NULL.
-*/
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Number Of Columns In A Result Set
-**
-** ^Return the number of columns in the result set returned by the
-** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
-** statement that does not return data (for example an [UPDATE]).
-**
-** See also: [sqlite3_data_count()]
-*/
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Column Names In A Result Set
-**
-** ^These routines return the name assigned to a particular column
-** in the result set of a [SELECT] statement. ^The sqlite3_column_name()
-** interface returns a pointer to a zero-terminated UTF-8 string
-** and sqlite3_column_name16() returns a pointer to a zero-terminated
-** UTF-16 string. ^The first parameter is the [prepared statement]
-** that implements the [SELECT] statement. ^The second parameter is the
-** column number. ^The leftmost column is number 0.
-**
-** ^The returned string pointer is valid until either the [prepared statement]
-** is destroyed by [sqlite3_finalize()] or until the statement is automatically
-** reprepared by the first call to [sqlite3_step()] for a particular run
-** or until the next call to
-** sqlite3_column_name() or sqlite3_column_name16() on the same column.
-**
-** ^If sqlite3_malloc() fails during the processing of either routine
-** (for example during a conversion from UTF-8 to UTF-16) then a
-** NULL pointer is returned.
-**
-** ^The name of a result column is the value of the "AS" clause for
-** that column, if there is an AS clause. If there is no AS clause
-** then the name of the column is unspecified and may change from
-** one release of SQLite to the next.
-*/
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
-
-/*
-** CAPI3REF: Source Of Data In A Query Result
-**
-** ^These routines provide a means to determine the database, table, and
-** table column that is the origin of a particular result column in
-** [SELECT] statement.
-** ^The name of the database or table or column can be returned as
-** either a UTF-8 or UTF-16 string. ^The _database_ routines return
-** the database name, the _table_ routines return the table name, and
-** the origin_ routines return the column name.
-** ^The returned string is valid until the [prepared statement] is destroyed
-** using [sqlite3_finalize()] or until the statement is automatically
-** reprepared by the first call to [sqlite3_step()] for a particular run
-** or until the same information is requested
-** again in a different encoding.
-**
-** ^The names returned are the original un-aliased names of the
-** database, table, and column.
-**
-** ^The first argument to these interfaces is a [prepared statement].
-** ^These functions return information about the Nth result column returned by
-** the statement, where N is the second function argument.
-** ^The left-most column is column 0 for these routines.
-**
-** ^If the Nth column returned by the statement is an expression or
-** subquery and is not a column value, then all of these functions return
-** NULL. ^These routine might also return NULL if a memory allocation error
-** occurs. ^Otherwise, they return the name of the attached database, table,
-** or column that query result column was extracted from.
-**
-** ^As with all other SQLite APIs, those whose names end with "16" return
-** UTF-16 encoded strings and the other functions return UTF-8.
-**
-** ^These APIs are only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol.
-**
-** If two or more threads call one or more of these routines against the same
-** prepared statement and column at the same time then the results are
-** undefined.
-**
-** If two or more threads call one or more
-** [sqlite3_column_database_name | column metadata interfaces]
-** for the same [prepared statement] and result column
-** at the same time then the results are undefined.
-*/
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
-
-/*
-** CAPI3REF: Declared Datatype Of A Query Result
-**
-** ^(The first parameter is a [prepared statement].
-** If this statement is a [SELECT] statement and the Nth column of the
-** returned result set of that [SELECT] is a table column (not an
-** expression or subquery) then the declared type of the table
-** column is returned.)^ ^If the Nth column of the result set is an
-** expression or subquery, then a NULL pointer is returned.
-** ^The returned string is always UTF-8 encoded.
-**
-** ^(For example, given the database schema:
-**
-** CREATE TABLE t1(c1 VARIANT);
-**
-** and the following statement to be compiled:
-**
-** SELECT c1 + 1, c1 FROM t1;
-**
-** this routine would return the string "VARIANT" for the second result
-** column (i==1), and a NULL pointer for the first result column (i==0).)^
-**
-** ^SQLite uses dynamic run-time typing. ^So just because a column
-** is declared to contain a particular type does not mean that the
-** data stored in that column is of the declared type. SQLite is
-** strongly typed, but the typing is dynamic not static. ^Type
-** is associated with individual values, not with the containers
-** used to hold those values.
-*/
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
-
-/*
-** CAPI3REF: Evaluate An SQL Statement
-**
-** After a [prepared statement] has been prepared using either
-** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
-** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
-** must be called one or more times to evaluate the statement.
-**
-** The details of the behavior of the sqlite3_step() interface depend
-** on whether the statement was prepared using the newer "v2" interface
-** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy
-** interface [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the
-** new "v2" interface is recommended for new applications but the legacy
-** interface will continue to be supported.
-**
-** ^In the legacy interface, the return value will be either [SQLITE_BUSY],
-** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
-** ^With the "v2" interface, any of the other [result codes] or
-** [extended result codes] might be returned as well.
-**
-** ^[SQLITE_BUSY] means that the database engine was unable to acquire the
-** database locks it needs to do its job. ^If the statement is a [COMMIT]
-** or occurs outside of an explicit transaction, then you can retry the
-** statement. If the statement is not a [COMMIT] and occurs within an
-** explicit transaction then you should rollback the transaction before
-** continuing.
-**
-** ^[SQLITE_DONE] means that the statement has finished executing
-** successfully. sqlite3_step() should not be called again on this virtual
-** machine without first calling [sqlite3_reset()] to reset the virtual
-** machine back to its initial state.
-**
-** ^If the SQL statement being executed returns any data, then [SQLITE_ROW]
-** is returned each time a new row of data is ready for processing by the
-** caller. The values may be accessed using the [column access functions].
-** sqlite3_step() is called again to retrieve the next row of data.
-**
-** ^[SQLITE_ERROR] means that a run-time error (such as a constraint
-** violation) has occurred. sqlite3_step() should not be called again on
-** the VM. More information may be found by calling [sqlite3_errmsg()].
-** ^With the legacy interface, a more specific error code (for example,
-** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth)
-** can be obtained by calling [sqlite3_reset()] on the
-** [prepared statement]. ^In the "v2" interface,
-** the more specific error code is returned directly by sqlite3_step().
-**
-** [SQLITE_MISUSE] means that the this routine was called inappropriately.
-** Perhaps it was called on a [prepared statement] that has
-** already been [sqlite3_finalize | finalized] or on one that had
-** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could
-** be the case that the same database connection is being used by two or
-** more threads at the same moment in time.
-**
-** For all versions of SQLite up to and including 3.6.23.1, a call to
-** [sqlite3_reset()] was required after sqlite3_step() returned anything
-** other than [SQLITE_ROW] before any subsequent invocation of
-** sqlite3_step(). Failure to reset the prepared statement using
-** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
-** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began
-** calling [sqlite3_reset()] automatically in this circumstance rather
-** than returning [SQLITE_MISUSE]. This is not considered a compatibility
-** break because any application that ever receives an SQLITE_MISUSE error
-** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option
-** can be used to restore the legacy behavior.
-**
-** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
-** API always returns a generic error code, [SQLITE_ERROR], following any
-** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call
-** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
-** specific [error codes] that better describes the error.
-** We admit that this is a goofy design. The problem has been fixed
-** with the "v2" interface. If you prepare all of your SQL statements
-** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
-** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
-** then the more specific [error codes] are returned directly
-** by sqlite3_step(). The use of the "v2" interface is recommended.
-*/
-SQLITE_API int sqlite3_step(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Number of columns in a result set
-**
-** ^The sqlite3_data_count(P) interface returns the number of columns in the
-** current row of the result set of [prepared statement] P.
-** ^If prepared statement P does not have results ready to return
-** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
-** interfaces) then sqlite3_data_count(P) returns 0.
-** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
-** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
-** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P)
-** will return non-zero if previous call to [sqlite3_step](P) returned
-** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
-** where it always returns zero since each step of that multi-step
-** pragma returns 0 columns of data.
-**
-** See also: [sqlite3_column_count()]
-*/
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Fundamental Datatypes
-** KEYWORDS: SQLITE_TEXT
-**
-** ^(Every value in SQLite has one of five fundamental datatypes:
-**
-** <ul>
-** <li> 64-bit signed integer
-** <li> 64-bit IEEE floating point number
-** <li> string
-** <li> BLOB
-** <li> NULL
-** </ul>)^
-**
-** These constants are codes for each of those types.
-**
-** Note that the SQLITE_TEXT constant was also used in SQLite version 2
-** for a completely different meaning. Software that links against both
-** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not
-** SQLITE_TEXT.
-*/
-#define SQLITE_INTEGER 1
-#define SQLITE_FLOAT 2
-#define SQLITE_BLOB 4
-#define SQLITE_NULL 5
-#ifdef SQLITE_TEXT
-# undef SQLITE_TEXT
-#else
-# define SQLITE_TEXT 3
-#endif
-#define SQLITE3_TEXT 3
-
-/*
-** CAPI3REF: Result Values From A Query
-** KEYWORDS: {column access functions}
-**
-** These routines form the "result set" interface.
-**
-** ^These routines return information about a single column of the current
-** result row of a query. ^In every case the first argument is a pointer
-** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
-** that was returned from [sqlite3_prepare_v2()] or one of its variants)
-** and the second argument is the index of the column for which information
-** should be returned. ^The leftmost column of the result set has the index 0.
-** ^The number of columns in the result can be determined using
-** [sqlite3_column_count()].
-**
-** If the SQL statement does not currently point to a valid row, or if the
-** column index is out of range, the result is undefined.
-** These routines may only be called when the most recent call to
-** [sqlite3_step()] has returned [SQLITE_ROW] and neither
-** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
-** If any of these routines are called after [sqlite3_reset()] or
-** [sqlite3_finalize()] or after [sqlite3_step()] has returned
-** something other than [SQLITE_ROW], the results are undefined.
-** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
-** are called from a different thread while any of these routines
-** are pending, then the results are undefined.
-**
-** ^The sqlite3_column_type() routine returns the
-** [SQLITE_INTEGER | datatype code] for the initial data type
-** of the result column. ^The returned value is one of [SQLITE_INTEGER],
-** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. The value
-** returned by sqlite3_column_type() is only meaningful if no type
-** conversions have occurred as described below. After a type conversion,
-** the value returned by sqlite3_column_type() is undefined. Future
-** versions of SQLite may change the behavior of sqlite3_column_type()
-** following a type conversion.
-**
-** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes()
-** routine returns the number of bytes in that BLOB or string.
-** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts
-** the string to UTF-8 and then returns the number of bytes.
-** ^If the result is a numeric value then sqlite3_column_bytes() uses
-** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns
-** the number of bytes in that string.
-** ^If the result is NULL, then sqlite3_column_bytes() returns zero.
-**
-** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16()
-** routine returns the number of bytes in that BLOB or string.
-** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts
-** the string to UTF-16 and then returns the number of bytes.
-** ^If the result is a numeric value then sqlite3_column_bytes16() uses
-** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns
-** the number of bytes in that string.
-** ^If the result is NULL, then sqlite3_column_bytes16() returns zero.
-**
-** ^The values returned by [sqlite3_column_bytes()] and
-** [sqlite3_column_bytes16()] do not include the zero terminators at the end
-** of the string. ^For clarity: the values returned by
-** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
-** bytes in the string, not the number of characters.
-**
-** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
-** even empty strings, are always zero-terminated. ^The return
-** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
-**
-** ^The object returned by [sqlite3_column_value()] is an
-** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
-** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
-** If the [unprotected sqlite3_value] object returned by
-** [sqlite3_column_value()] is used in any other way, including calls
-** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
-** or [sqlite3_value_bytes()], then the behavior is undefined.
-**
-** These routines attempt to convert the value where appropriate. ^For
-** example, if the internal representation is FLOAT and a text result
-** is requested, [sqlite3_snprintf()] is used internally to perform the
-** conversion automatically. ^(The following table details the conversions
-** that are applied:
-**
-** <blockquote>
-** <table border="1">
-** <tr><th> Internal<br>Type <th> Requested<br>Type <th> Conversion
-**
-** <tr><td> NULL <td> INTEGER <td> Result is 0
-** <tr><td> NULL <td> FLOAT <td> Result is 0.0
-** <tr><td> NULL <td> TEXT <td> Result is NULL pointer
-** <tr><td> NULL <td> BLOB <td> Result is NULL pointer
-** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float
-** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer
-** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT
-** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer
-** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float
-** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT
-** <tr><td> TEXT <td> INTEGER <td> Use atoi()
-** <tr><td> TEXT <td> FLOAT <td> Use atof()
-** <tr><td> TEXT <td> BLOB <td> No change
-** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi()
-** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof()
-** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
-** </table>
-** </blockquote>)^
-**
-** The table above makes reference to standard C library functions atoi()
-** and atof(). SQLite does not really use these functions. It has its
-** own equivalent internal routines. The atoi() and atof() names are
-** used in the table for brevity and because they are familiar to most
-** C programmers.
-**
-** Note that when type conversions occur, pointers returned by prior
-** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
-** sqlite3_column_text16() may be invalidated.
-** Type conversions and pointer invalidations might occur
-** in the following cases:
-**
-** <ul>
-** <li> The initial content is a BLOB and sqlite3_column_text() or
-** sqlite3_column_text16() is called. A zero-terminator might
-** need to be added to the string.</li>
-** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
-** sqlite3_column_text16() is called. The content must be converted
-** to UTF-16.</li>
-** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
-** sqlite3_column_text() is called. The content must be converted
-** to UTF-8.</li>
-** </ul>
-**
-** ^Conversions between UTF-16be and UTF-16le are always done in place and do
-** not invalidate a prior pointer, though of course the content of the buffer
-** that the prior pointer references will have been modified. Other kinds
-** of conversion are done in place when it is possible, but sometimes they
-** are not possible and in those cases prior pointers are invalidated.
-**
-** The safest and easiest to remember policy is to invoke these routines
-** in one of the following ways:
-**
-** <ul>
-** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
-** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
-** <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
-** </ul>
-**
-** In other words, you should call sqlite3_column_text(),
-** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
-** into the desired format, then invoke sqlite3_column_bytes() or
-** sqlite3_column_bytes16() to find the size of the result. Do not mix calls
-** to sqlite3_column_text() or sqlite3_column_blob() with calls to
-** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
-** with calls to sqlite3_column_bytes().
-**
-** ^The pointers returned are valid until a type conversion occurs as
-** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
-** [sqlite3_finalize()] is called. ^The memory space used to hold strings
-** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
-** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
-** [sqlite3_free()].
-**
-** ^(If a memory allocation error occurs during the evaluation of any
-** of these routines, a default value is returned. The default value
-** is either the integer 0, the floating point number 0.0, or a NULL
-** pointer. Subsequent calls to [sqlite3_errcode()] will return
-** [SQLITE_NOMEM].)^
-*/
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
-
-/*
-** CAPI3REF: Destroy A Prepared Statement Object
-**
-** ^The sqlite3_finalize() function is called to delete a [prepared statement].
-** ^If the most recent evaluation of the statement encountered no errors
-** or if the statement is never been evaluated, then sqlite3_finalize() returns
-** SQLITE_OK. ^If the most recent evaluation of statement S failed, then
-** sqlite3_finalize(S) returns the appropriate [error code] or
-** [extended error code].
-**
-** ^The sqlite3_finalize(S) routine can be called at any point during
-** the life cycle of [prepared statement] S:
-** before statement S is ever evaluated, after
-** one or more calls to [sqlite3_reset()], or after any call
-** to [sqlite3_step()] regardless of whether or not the statement has
-** completed execution.
-**
-** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.
-**
-** The application must finalize every [prepared statement] in order to avoid
-** resource leaks. It is a grievous error for the application to try to use
-** a prepared statement after it has been finalized. Any use of a prepared
-** statement after it has been finalized can result in undefined and
-** undesirable behavior such as segfaults and heap corruption.
-*/
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Reset A Prepared Statement Object
-**
-** The sqlite3_reset() function is called to reset a [prepared statement]
-** object back to its initial state, ready to be re-executed.
-** ^Any SQL statement variables that had values bound to them using
-** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
-** Use [sqlite3_clear_bindings()] to reset the bindings.
-**
-** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S
-** back to the beginning of its program.
-**
-** ^If the most recent call to [sqlite3_step(S)] for the
-** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],
-** or if [sqlite3_step(S)] has never before been called on S,
-** then [sqlite3_reset(S)] returns [SQLITE_OK].
-**
-** ^If the most recent call to [sqlite3_step(S)] for the
-** [prepared statement] S indicated an error, then
-** [sqlite3_reset(S)] returns an appropriate [error code].
-**
-** ^The [sqlite3_reset(S)] interface does not change the values
-** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
-*/
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Create Or Redefine SQL Functions
-** KEYWORDS: {function creation routines}
-** KEYWORDS: {application-defined SQL function}
-** KEYWORDS: {application-defined SQL functions}
-**
-** ^These functions (collectively known as "function creation routines")
-** are used to add SQL functions or aggregates or to redefine the behavior
-** of existing SQL functions or aggregates. The only differences between
-** these routines are the text encoding expected for
-** the second parameter (the name of the function being created)
-** and the presence or absence of a destructor callback for
-** the application data pointer.
-**
-** ^The first parameter is the [database connection] to which the SQL
-** function is to be added. ^If an application uses more than one database
-** connection then application-defined SQL functions must be added
-** to each database connection separately.
-**
-** ^The second parameter is the name of the SQL function to be created or
-** redefined. ^The length of the name is limited to 255 bytes in a UTF-8
-** representation, exclusive of the zero-terminator. ^Note that the name
-** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes.
-** ^Any attempt to create a function with a longer name
-** will result in [SQLITE_MISUSE] being returned.
-**
-** ^The third parameter (nArg)
-** is the number of arguments that the SQL function or
-** aggregate takes. ^If this parameter is -1, then the SQL function or
-** aggregate may take any number of arguments between 0 and the limit
-** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third
-** parameter is less than -1 or greater than 127 then the behavior is
-** undefined.
-**
-** ^The fourth parameter, eTextRep, specifies what
-** [SQLITE_UTF8 | text encoding] this SQL function prefers for
-** its parameters. Every SQL function implementation must be able to work
-** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be
-** more efficient with one encoding than another. ^An application may
-** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
-** times with the same function but with different values of eTextRep.
-** ^When multiple implementations of the same function are available, SQLite
-** will pick the one that involves the least amount of data conversion.
-** If there is only a single implementation which does not care what text
-** encoding is used, then the fourth argument should be [SQLITE_ANY].
-**
-** ^(The fifth parameter is an arbitrary pointer. The implementation of the
-** function can gain access to this pointer using [sqlite3_user_data()].)^
-**
-** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
-** pointers to C-language functions that implement the SQL function or
-** aggregate. ^A scalar SQL function requires an implementation of the xFunc
-** callback only; NULL pointers must be passed as the xStep and xFinal
-** parameters. ^An aggregate SQL function requires an implementation of xStep
-** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing
-** SQL function or aggregate, pass NULL pointers for all three function
-** callbacks.
-**
-** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
-** then it is destructor for the application data pointer.
-** The destructor is invoked when the function is deleted, either by being
-** overloaded or when the database connection closes.)^
-** ^The destructor is also invoked if the call to
-** sqlite3_create_function_v2() fails.
-** ^When the destructor callback of the tenth parameter is invoked, it
-** is passed a single argument which is a copy of the application data
-** pointer which was the fifth parameter to sqlite3_create_function_v2().
-**
-** ^It is permitted to register multiple implementations of the same
-** functions with the same name but with either differing numbers of
-** arguments or differing preferred text encodings. ^SQLite will use
-** the implementation that most closely matches the way in which the
-** SQL function is used. ^A function implementation with a non-negative
-** nArg parameter is a better match than a function implementation with
-** a negative nArg. ^A function where the preferred text encoding
-** matches the database encoding is a better
-** match than a function where the encoding is different.
-** ^A function where the encoding difference is between UTF16le and UTF16be
-** is a closer match than a function where the encoding difference is
-** between UTF8 and UTF16.
-**
-** ^Built-in functions may be overloaded by new application-defined functions.
-**
-** ^An application-defined function is permitted to call other
-** SQLite interfaces. However, such calls must not
-** close the database connection nor finalize or reset the prepared
-** statement in which the function is running.
-*/
-SQLITE_API int sqlite3_create_function(
- sqlite3 *db,
- const char *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-);
-SQLITE_API int sqlite3_create_function16(
- sqlite3 *db,
- const void *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*)
-);
-SQLITE_API int sqlite3_create_function_v2(
- sqlite3 *db,
- const char *zFunctionName,
- int nArg,
- int eTextRep,
- void *pApp,
- void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
- void (*xStep)(sqlite3_context*,int,sqlite3_value**),
- void (*xFinal)(sqlite3_context*),
- void(*xDestroy)(void*)
-);
-
-/*
-** CAPI3REF: Text Encodings
-**
-** These constant define integer codes that represent the various
-** text encodings supported by SQLite.
-*/
-#define SQLITE_UTF8 1
-#define SQLITE_UTF16LE 2
-#define SQLITE_UTF16BE 3
-#define SQLITE_UTF16 4 /* Use native byte order */
-#define SQLITE_ANY 5 /* sqlite3_create_function only */
-#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
-
-/*
-** CAPI3REF: Deprecated Functions
-** DEPRECATED
-**
-** These functions are [deprecated]. In order to maintain
-** backwards compatibility with older code, these functions continue
-** to be supported. However, new applications should avoid
-** the use of these functions. To help encourage people to avoid
-** using these functions, we are not going to tell you what they do.
-*/
-#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64);
-#endif
-
-/*
-** CAPI3REF: Obtaining SQL Function Parameter Values
-**
-** The C-language implementation of SQL functions and aggregates uses
-** this set of interface routines to access the parameter values on
-** the function or aggregate.
-**
-** The xFunc (for scalar functions) or xStep (for aggregates) parameters
-** to [sqlite3_create_function()] and [sqlite3_create_function16()]
-** define callbacks that implement the SQL functions and aggregates.
-** The 3rd parameter to these callbacks is an array of pointers to
-** [protected sqlite3_value] objects. There is one [sqlite3_value] object for
-** each parameter to the SQL function. These routines are used to
-** extract values from the [sqlite3_value] objects.
-**
-** These routines work only with [protected sqlite3_value] objects.
-** Any attempt to use these routines on an [unprotected sqlite3_value]
-** object results in undefined behavior.
-**
-** ^These routines work just like the corresponding [column access functions]
-** except that these routines take a single [protected sqlite3_value] object
-** pointer instead of a [sqlite3_stmt*] pointer and an integer column number.
-**
-** ^The sqlite3_value_text16() interface extracts a UTF-16 string
-** in the native byte-order of the host machine. ^The
-** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
-** extract UTF-16 strings as big-endian and little-endian respectively.
-**
-** ^(The sqlite3_value_numeric_type() interface attempts to apply
-** numeric affinity to the value. This means that an attempt is
-** made to convert the value to an integer or floating point. If
-** such a conversion is possible without loss of information (in other
-** words, if the value is a string that looks like a number)
-** then the conversion is performed. Otherwise no conversion occurs.
-** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
-**
-** Please pay particular attention to the fact that the pointer returned
-** from [sqlite3_value_blob()], [sqlite3_value_text()], or
-** [sqlite3_value_text16()] can be invalidated by a subsequent call to
-** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
-** or [sqlite3_value_text16()].
-**
-** These routines must be called from the same thread as
-** the SQL function that supplied the [sqlite3_value*] parameters.
-*/
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double sqlite3_value_double(sqlite3_value*);
-SQLITE_API int sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int sqlite3_value_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
-
-/*
-** CAPI3REF: Obtain Aggregate Function Context
-**
-** Implementations of aggregate SQL functions use this
-** routine to allocate memory for storing their state.
-**
-** ^The first time the sqlite3_aggregate_context(C,N) routine is called
-** for a particular aggregate function, SQLite
-** allocates N of memory, zeroes out that memory, and returns a pointer
-** to the new memory. ^On second and subsequent calls to
-** sqlite3_aggregate_context() for the same aggregate function instance,
-** the same buffer is returned. Sqlite3_aggregate_context() is normally
-** called once for each invocation of the xStep callback and then one
-** last time when the xFinal callback is invoked. ^(When no rows match
-** an aggregate query, the xStep() callback of the aggregate function
-** implementation is never called and xFinal() is called exactly once.
-** In those cases, sqlite3_aggregate_context() might be called for the
-** first time from within xFinal().)^
-**
-** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer if N is
-** less than or equal to zero or if a memory allocate error occurs.
-**
-** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
-** determined by the N parameter on first successful call. Changing the
-** value of N in subsequent call to sqlite3_aggregate_context() within
-** the same aggregate function instance will not resize the memory
-** allocation.)^
-**
-** ^SQLite automatically frees the memory allocated by
-** sqlite3_aggregate_context() when the aggregate query concludes.
-**
-** The first parameter must be a copy of the
-** [sqlite3_context | SQL function context] that is the first parameter
-** to the xStep or xFinal callback routine that implements the aggregate
-** function.
-**
-** This routine must be called from the same thread in which
-** the aggregate SQL function is running.
-*/
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
-
-/*
-** CAPI3REF: User Data For Functions
-**
-** ^The sqlite3_user_data() interface returns a copy of
-** the pointer that was the pUserData parameter (the 5th parameter)
-** of the [sqlite3_create_function()]
-** and [sqlite3_create_function16()] routines that originally
-** registered the application defined function.
-**
-** This routine must be called from the same thread in which
-** the application-defined function is running.
-*/
-SQLITE_API void *sqlite3_user_data(sqlite3_context*);
-
-/*
-** CAPI3REF: Database Connection For Functions
-**
-** ^The sqlite3_context_db_handle() interface returns a copy of
-** the pointer to the [database connection] (the 1st parameter)
-** of the [sqlite3_create_function()]
-** and [sqlite3_create_function16()] routines that originally
-** registered the application defined function.
-*/
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
-
-/*
-** CAPI3REF: Function Auxiliary Data
-**
-** The following two functions may be used by scalar SQL functions to
-** associate metadata with argument values. If the same value is passed to
-** multiple invocations of the same SQL function during query execution, under
-** some circumstances the associated metadata may be preserved. This may
-** be used, for example, to add a regular-expression matching scalar
-** function. The compiled version of the regular expression is stored as
-** metadata associated with the SQL value passed as the regular expression
-** pattern. The compiled regular expression can be reused on multiple
-** invocations of the same function so that the original pattern string
-** does not need to be recompiled on each invocation.
-**
-** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
-** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. ^If no metadata has been ever
-** been set for the Nth argument of the function, or if the corresponding
-** function parameter has changed since the meta-data was set,
-** then sqlite3_get_auxdata() returns a NULL pointer.
-**
-** ^The sqlite3_set_auxdata() interface saves the metadata
-** pointed to by its 3rd parameter as the metadata for the N-th
-** argument of the application-defined function. Subsequent
-** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed.
-** ^If it is not NULL, SQLite will invoke the destructor
-** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the metadata when the corresponding function parameter changes
-** or when the SQL statement completes, whichever comes first.
-**
-** SQLite is free to call the destructor and drop metadata on any
-** parameter of any function at any time. ^The only guarantee is that
-** the destructor will be called before the metadata is dropped.
-**
-** ^(In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and [parameters].)^
-**
-** These routines must be called from the same thread in which
-** the SQL function is running.
-*/
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
-
-
-/*
-** CAPI3REF: Constants Defining Special Destructor Behavior
-**
-** These are special values for the destructor that is passed in as the
-** final argument to routines like [sqlite3_result_blob()]. ^If the destructor
-** argument is SQLITE_STATIC, it means that the content pointer is constant
-** and will never change. It does not need to be destroyed. ^The
-** SQLITE_TRANSIENT value means that the content will likely change in
-** the near future and that SQLite should make its own private copy of
-** the content before returning.
-**
-** The typedef is necessary to work around problems in certain
-** C++ compilers. See ticket #2191.
-*/
-typedef void (*sqlite3_destructor_type)(void*);
-#define SQLITE_STATIC ((sqlite3_destructor_type)0)
-#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1)
-
-/*
-** CAPI3REF: Setting The Result Of An SQL Function
-**
-** These routines are used by the xFunc or xFinal callbacks that
-** implement SQL functions and aggregates. See
-** [sqlite3_create_function()] and [sqlite3_create_function16()]
-** for additional information.
-**
-** These functions work very much like the [parameter binding] family of
-** functions used to bind values to host parameters in prepared statements.
-** Refer to the [SQL parameter] documentation for additional information.
-**
-** ^The sqlite3_result_blob() interface sets the result from
-** an application-defined function to be the BLOB whose content is pointed
-** to by the second parameter and which is N bytes long where N is the
-** third parameter.
-**
-** ^The sqlite3_result_zeroblob() interfaces set the result of
-** the application-defined function to be a BLOB containing all zero
-** bytes and N bytes in size, where N is the value of the 2nd parameter.
-**
-** ^The sqlite3_result_double() interface sets the result from
-** an application-defined function to be a floating point value specified
-** by its 2nd argument.
-**
-** ^The sqlite3_result_error() and sqlite3_result_error16() functions
-** cause the implemented SQL function to throw an exception.
-** ^SQLite uses the string pointed to by the
-** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
-** as the text of an error message. ^SQLite interprets the error
-** message string from sqlite3_result_error() as UTF-8. ^SQLite
-** interprets the string from sqlite3_result_error16() as UTF-16 in native
-** byte order. ^If the third parameter to sqlite3_result_error()
-** or sqlite3_result_error16() is negative then SQLite takes as the error
-** message all text up through the first zero character.
-** ^If the third parameter to sqlite3_result_error() or
-** sqlite3_result_error16() is non-negative then SQLite takes that many
-** bytes (not characters) from the 2nd parameter as the error message.
-** ^The sqlite3_result_error() and sqlite3_result_error16()
-** routines make a private copy of the error message text before
-** they return. Hence, the calling function can deallocate or
-** modify the text after they return without harm.
-** ^The sqlite3_result_error_code() function changes the error code
-** returned by SQLite as a result of an error in a function. ^By default,
-** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error()
-** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
-**
-** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an
-** error indicating that a string or BLOB is too long to represent.
-**
-** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an
-** error indicating that a memory allocation failed.
-**
-** ^The sqlite3_result_int() interface sets the return value
-** of the application-defined function to be the 32-bit signed integer
-** value given in the 2nd argument.
-** ^The sqlite3_result_int64() interface sets the return value
-** of the application-defined function to be the 64-bit signed integer
-** value given in the 2nd argument.
-**
-** ^The sqlite3_result_null() interface sets the return value
-** of the application-defined function to be NULL.
-**
-** ^The sqlite3_result_text(), sqlite3_result_text16(),
-** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces
-** set the return value of the application-defined function to be
-** a text string which is represented as UTF-8, UTF-16 native byte order,
-** UTF-16 little endian, or UTF-16 big endian, respectively.
-** ^SQLite takes the text result from the application from
-** the 2nd parameter of the sqlite3_result_text* interfaces.
-** ^If the 3rd parameter to the sqlite3_result_text* interfaces
-** is negative, then SQLite takes result text from the 2nd parameter
-** through the first zero character.
-** ^If the 3rd parameter to the sqlite3_result_text* interfaces
-** is non-negative, then as many bytes (not characters) of the text
-** pointed to by the 2nd parameter are taken as the application-defined
-** function result. If the 3rd parameter is non-negative, then it
-** must be the byte offset into the string where the NUL terminator would
-** appear if the string where NUL terminated. If any NUL characters occur
-** in the string at a byte offset that is less than the value of the 3rd
-** parameter, then the resulting string will contain embedded NULs and the
-** result of expressions operating on strings with embedded NULs is undefined.
-** ^If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
-** function as the destructor on the text or BLOB result when it has
-** finished using that result.
-** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
-** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite
-** assumes that the text or BLOB result is in constant space and does not
-** copy the content of the parameter nor call a destructor on the content
-** when it has finished using that result.
-** ^If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
-** then SQLite makes a copy of the result into space obtained from
-** from [sqlite3_malloc()] before it returns.
-**
-** ^The sqlite3_result_value() interface sets the result of
-** the application-defined function to be a copy the
-** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
-** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
-** so that the [sqlite3_value] specified in the parameter may change or
-** be deallocated after sqlite3_result_value() returns without harm.
-** ^A [protected sqlite3_value] object may always be used where an
-** [unprotected sqlite3_value] object is required, so either
-** kind of [sqlite3_value] object can be used with this interface.
-**
-** If these routines are called from within the different thread
-** than the one containing the application-defined function that received
-** the [sqlite3_context] pointer, the results are undefined.
-*/
-SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void sqlite3_result_null(sqlite3_context*);
-SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
-
-/*
-** CAPI3REF: Define New Collating Sequences
-**
-** ^These functions add, remove, or modify a [collation] associated
-** with the [database connection] specified as the first argument.
-**
-** ^The name of the collation is a UTF-8 string
-** for sqlite3_create_collation() and sqlite3_create_collation_v2()
-** and a UTF-16 string in native byte order for sqlite3_create_collation16().
-** ^Collation names that compare equal according to [sqlite3_strnicmp()] are
-** considered to be the same name.
-**
-** ^(The third argument (eTextRep) must be one of the constants:
-** <ul>
-** <li> [SQLITE_UTF8],
-** <li> [SQLITE_UTF16LE],
-** <li> [SQLITE_UTF16BE],
-** <li> [SQLITE_UTF16], or
-** <li> [SQLITE_UTF16_ALIGNED].
-** </ul>)^
-** ^The eTextRep argument determines the encoding of strings passed
-** to the collating function callback, xCallback.
-** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
-** force strings to be UTF16 with native byte order.
-** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
-** on an even byte address.
-**
-** ^The fourth argument, pArg, is an application data pointer that is passed
-** through as the first argument to the collating function callback.
-**
-** ^The fifth argument, xCallback, is a pointer to the collating function.
-** ^Multiple collating functions can be registered using the same name but
-** with different eTextRep parameters and SQLite will use whichever
-** function requires the least amount of data transformation.
-** ^If the xCallback argument is NULL then the collating function is
-** deleted. ^When all collating functions having the same name are deleted,
-** that collation is no longer usable.
-**
-** ^The collating function callback is invoked with a copy of the pArg
-** application data pointer and with two strings in the encoding specified
-** by the eTextRep argument. The collating function must return an
-** integer that is negative, zero, or positive
-** if the first string is less than, equal to, or greater than the second,
-** respectively. A collating function must always return the same answer
-** given the same inputs. If two or more collating functions are registered
-** to the same collation name (using different eTextRep values) then all
-** must give an equivalent answer when invoked with equivalent strings.
-** The collating function must obey the following properties for all
-** strings A, B, and C:
-**
-** <ol>
-** <li> If A==B then B==A.
-** <li> If A==B and B==C then A==C.
-** <li> If A&lt;B THEN B&gt;A.
-** <li> If A&lt;B and B&lt;C then A&lt;C.
-** </ol>
-**
-** If a collating function fails any of the above constraints and that
-** collating function is registered and used, then the behavior of SQLite
-** is undefined.
-**
-** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation()
-** with the addition that the xDestroy callback is invoked on pArg when
-** the collating function is deleted.
-** ^Collating functions are deleted when they are overridden by later
-** calls to the collation creation functions or when the
-** [database connection] is closed using [sqlite3_close()].
-**
-** ^The xDestroy callback is <u>not</u> called if the
-** sqlite3_create_collation_v2() function fails. Applications that invoke
-** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should
-** check the return code and dispose of the application data pointer
-** themselves rather than expecting SQLite to deal with it for them.
-** This is different from every other SQLite interface. The inconsistency
-** is unfortunate but cannot be changed without breaking backwards
-** compatibility.
-**
-** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
-*/
-SQLITE_API int sqlite3_create_collation(
- sqlite3*,
- const char *zName,
- int eTextRep,
- void *pArg,
- int(*xCompare)(void*,int,const void*,int,const void*)
-);
-SQLITE_API int sqlite3_create_collation_v2(
- sqlite3*,
- const char *zName,
- int eTextRep,
- void *pArg,
- int(*xCompare)(void*,int,const void*,int,const void*),
- void(*xDestroy)(void*)
-);
-SQLITE_API int sqlite3_create_collation16(
- sqlite3*,
- const void *zName,
- int eTextRep,
- void *pArg,
- int(*xCompare)(void*,int,const void*,int,const void*)
-);
-
-/*
-** CAPI3REF: Collation Needed Callbacks
-**
-** ^To avoid having to register all collation sequences before a database
-** can be used, a single callback function may be registered with the
-** [database connection] to be invoked whenever an undefined collation
-** sequence is required.
-**
-** ^If the function is registered using the sqlite3_collation_needed() API,
-** then it is passed the names of undefined collation sequences as strings
-** encoded in UTF-8. ^If sqlite3_collation_needed16() is used,
-** the names are passed as UTF-16 in machine native byte order.
-** ^A call to either function replaces the existing collation-needed callback.
-**
-** ^(When the callback is invoked, the first argument passed is a copy
-** of the second argument to sqlite3_collation_needed() or
-** sqlite3_collation_needed16(). The second argument is the database
-** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE],
-** or [SQLITE_UTF16LE], indicating the most desirable form of the collation
-** sequence function required. The fourth parameter is the name of the
-** required collation sequence.)^
-**
-** The callback function should register the desired collation using
-** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
-** [sqlite3_create_collation_v2()].
-*/
-SQLITE_API int sqlite3_collation_needed(
- sqlite3*,
- void*,
- void(*)(void*,sqlite3*,int eTextRep,const char*)
-);
-SQLITE_API int sqlite3_collation_needed16(
- sqlite3*,
- void*,
- void(*)(void*,sqlite3*,int eTextRep,const void*)
-);
-
-#ifdef SQLITE_HAS_CODEC
-/*
-** Specify the key for an encrypted database. This routine should be
-** called right after sqlite3_open().
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_key(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The key */
-);
-
-/*
-** Change the key on an open database. If the current database is not
-** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
-** database is decrypted.
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_rekey(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The new key */
-);
-
-/*
-** Specify the activation key for a SEE database. Unless
-** activated, none of the SEE routines will work.
-*/
-SQLITE_API void sqlite3_activate_see(
- const char *zPassPhrase /* Activation phrase */
-);
-#endif
-
-#ifdef SQLITE_ENABLE_CEROD
-/*
-** Specify the activation key for a CEROD database. Unless
-** activated, none of the CEROD routines will work.
-*/
-SQLITE_API void sqlite3_activate_cerod(
- const char *zPassPhrase /* Activation phrase */
-);
-#endif
-
-/*
-** CAPI3REF: Suspend Execution For A Short Time
-**
-** The sqlite3_sleep() function causes the current thread to suspend execution
-** for at least a number of milliseconds specified in its parameter.
-**
-** If the operating system does not support sleep requests with
-** millisecond time resolution, then the time will be rounded up to
-** the nearest second. The number of milliseconds of sleep actually
-** requested from the operating system is returned.
-**
-** ^SQLite implements this interface by calling the xSleep()
-** method of the default [sqlite3_vfs] object. If the xSleep() method
-** of the default VFS is not implemented correctly, or not implemented at
-** all, then the behavior of sqlite3_sleep() may deviate from the description
-** in the previous paragraphs.
-*/
-SQLITE_API int sqlite3_sleep(int);
-
-/*
-** CAPI3REF: Name Of The Folder Holding Temporary Files
-**
-** ^(If this global variable is made to point to a string which is
-** the name of a folder (a.k.a. directory), then all temporary files
-** created by SQLite when using a built-in [sqlite3_vfs | VFS]
-** will be placed in that directory.)^ ^If this variable
-** is a NULL pointer, then SQLite performs a search for an appropriate
-** temporary file directory.
-**
-** It is not safe to read or modify this variable in more than one
-** thread at a time. It is not safe to read or modify this variable
-** if a [database connection] is being used at the same time in a separate
-** thread.
-** It is intended that this variable be set once
-** as part of process initialization and before any SQLite interface
-** routines have been called and that this variable remain unchanged
-** thereafter.
-**
-** ^The [temp_store_directory pragma] may modify this variable and cause
-** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore,
-** the [temp_store_directory pragma] always assumes that any string
-** that this variable points to is held in memory obtained from
-** [sqlite3_malloc] and the pragma may attempt to free that memory
-** using [sqlite3_free].
-** Hence, if this variable is modified directly, either it should be
-** made NULL or made to point to memory obtained from [sqlite3_malloc]
-** or else the use of the [temp_store_directory pragma] should be avoided.
-**
-** <b>Note to Windows Runtime users:</b> The temporary directory must be set
-** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various
-** features that require the use of temporary files may fail. Here is an
-** example of how to do this using C++ with the Windows Runtime:
-**
-** <blockquote><pre>
-** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
-** &nbsp; TemporaryFolder->Path->Data();
-** char zPathBuf&#91;MAX_PATH + 1&#93;;
-** memset(zPathBuf, 0, sizeof(zPathBuf));
-** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
-** &nbsp; NULL, NULL);
-** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
-** </pre></blockquote>
-*/
-SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
-
-/*
-** CAPI3REF: Name Of The Folder Holding Database Files
-**
-** ^(If this global variable is made to point to a string which is
-** the name of a folder (a.k.a. directory), then all database files
-** specified with a relative pathname and created or accessed by
-** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed
-** to be relative to that directory.)^ ^If this variable is a NULL
-** pointer, then SQLite assumes that all database files specified
-** with a relative pathname are relative to the current directory
-** for the process. Only the windows VFS makes use of this global
-** variable; it is ignored by the unix VFS.
-**
-** Changing the value of this variable while a database connection is
-** open can result in a corrupt database.
-**
-** It is not safe to read or modify this variable in more than one
-** thread at a time. It is not safe to read or modify this variable
-** if a [database connection] is being used at the same time in a separate
-** thread.
-** It is intended that this variable be set once
-** as part of process initialization and before any SQLite interface
-** routines have been called and that this variable remain unchanged
-** thereafter.
-**
-** ^The [data_store_directory pragma] may modify this variable and cause
-** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore,
-** the [data_store_directory pragma] always assumes that any string
-** that this variable points to is held in memory obtained from
-** [sqlite3_malloc] and the pragma may attempt to free that memory
-** using [sqlite3_free].
-** Hence, if this variable is modified directly, either it should be
-** made NULL or made to point to memory obtained from [sqlite3_malloc]
-** or else the use of the [data_store_directory pragma] should be avoided.
-*/
-SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
-
-/*
-** CAPI3REF: Test For Auto-Commit Mode
-** KEYWORDS: {autocommit mode}
-**
-** ^The sqlite3_get_autocommit() interface returns non-zero or
-** zero if the given database connection is or is not in autocommit mode,
-** respectively. ^Autocommit mode is on by default.
-** ^Autocommit mode is disabled by a [BEGIN] statement.
-** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
-**
-** If certain kinds of errors occur on a statement within a multi-statement
-** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
-** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
-** transaction might be rolled back automatically. The only way to
-** find out whether SQLite automatically rolled back the transaction after
-** an error is to use this function.
-**
-** If another thread changes the autocommit status of the database
-** connection while this routine is running, then the return value
-** is undefined.
-*/
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
-
-/*
-** CAPI3REF: Find The Database Handle Of A Prepared Statement
-**
-** ^The sqlite3_db_handle interface returns the [database connection] handle
-** to which a [prepared statement] belongs. ^The [database connection]
-** returned by sqlite3_db_handle is the same [database connection]
-** that was the first argument
-** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
-** create the statement in the first place.
-*/
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
-
-/*
-** CAPI3REF: Return The Filename For A Database Connection
-**
-** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
-** associated with database N of connection D. ^The main database file
-** has the name "main". If there is no attached database N on the database
-** connection D, or if database N is a temporary or in-memory database, then
-** a NULL pointer is returned.
-**
-** ^The filename returned by this function is the output of the
-** xFullPathname method of the [VFS]. ^In other words, the filename
-** will be an absolute pathname, even if the filename used
-** to open the database originally was a URI or relative pathname.
-*/
-SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
-
-/*
-** CAPI3REF: Determine if a database is read-only
-**
-** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
-** of connection D is read-only, 0 if it is read/write, or -1 if N is not
-** the name of a database on connection D.
-*/
-SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
-
-/*
-** CAPI3REF: Find the next prepared statement
-**
-** ^This interface returns a pointer to the next [prepared statement] after
-** pStmt associated with the [database connection] pDb. ^If pStmt is NULL
-** then this interface returns a pointer to the first prepared statement
-** associated with the database connection pDb. ^If no prepared statement
-** satisfies the conditions of this routine, it returns NULL.
-**
-** The [database connection] pointer D in a call to
-** [sqlite3_next_stmt(D,S)] must refer to an open database
-** connection and in particular must not be a NULL pointer.
-*/
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
-
-/*
-** CAPI3REF: Commit And Rollback Notification Callbacks
-**
-** ^The sqlite3_commit_hook() interface registers a callback
-** function to be invoked whenever a transaction is [COMMIT | committed].
-** ^Any callback set by a previous call to sqlite3_commit_hook()
-** for the same database connection is overridden.
-** ^The sqlite3_rollback_hook() interface registers a callback
-** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
-** ^Any callback set by a previous call to sqlite3_rollback_hook()
-** for the same database connection is overridden.
-** ^The pArg argument is passed through to the callback.
-** ^If the callback on a commit hook function returns non-zero,
-** then the commit is converted into a rollback.
-**
-** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions
-** return the P argument from the previous call of the same function
-** on the same [database connection] D, or NULL for
-** the first call for each function on D.
-**
-** The commit and rollback hook callbacks are not reentrant.
-** The callback implementation must not do anything that will modify
-** the database connection that invoked the callback. Any actions
-** to modify the database connection must be deferred until after the
-** completion of the [sqlite3_step()] call that triggered the commit
-** or rollback hook in the first place.
-** Note that running any other SQL statements, including SELECT statements,
-** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify
-** the database connections for the meaning of "modify" in this paragraph.
-**
-** ^Registering a NULL function disables the callback.
-**
-** ^When the commit hook callback routine returns zero, the [COMMIT]
-** operation is allowed to continue normally. ^If the commit hook
-** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
-** ^The rollback hook is invoked on a rollback that results from a commit
-** hook returning non-zero, just as it would be with any other rollback.
-**
-** ^For the purposes of this API, a transaction is said to have been
-** rolled back if an explicit "ROLLBACK" statement is executed, or
-** an error or constraint causes an implicit rollback to occur.
-** ^The rollback callback is not invoked if a transaction is
-** automatically rolled back because the database connection is closed.
-**
-** See also the [sqlite3_update_hook()] interface.
-*/
-SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
-
-/*
-** CAPI3REF: Data Change Notification Callbacks
-**
-** ^The sqlite3_update_hook() interface registers a callback function
-** with the [database connection] identified by the first argument
-** to be invoked whenever a row is updated, inserted or deleted.
-** ^Any callback set by a previous call to this function
-** for the same database connection is overridden.
-**
-** ^The second argument is a pointer to the function to invoke when a
-** row is updated, inserted or deleted.
-** ^The first argument to the callback is a copy of the third argument
-** to sqlite3_update_hook().
-** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
-** or [SQLITE_UPDATE], depending on the operation that caused the callback
-** to be invoked.
-** ^The third and fourth arguments to the callback contain pointers to the
-** database and table name containing the affected row.
-** ^The final callback parameter is the [rowid] of the row.
-** ^In the case of an update, this is the [rowid] after the update takes place.
-**
-** ^(The update hook is not invoked when internal system tables are
-** modified (i.e. sqlite_master and sqlite_sequence).)^
-**
-** ^In the current implementation, the update hook
-** is not invoked when duplication rows are deleted because of an
-** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
-** invoked when rows are deleted using the [truncate optimization].
-** The exceptions defined in this paragraph might change in a future
-** release of SQLite.
-**
-** The update hook implementation must not do anything that will modify
-** the database connection that invoked the update hook. Any actions
-** to modify the database connection must be deferred until after the
-** completion of the [sqlite3_step()] call that triggered the update hook.
-** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
-** database connections for the meaning of "modify" in this paragraph.
-**
-** ^The sqlite3_update_hook(D,C,P) function
-** returns the P argument from the previous call
-** on the same [database connection] D, or NULL for
-** the first call on D.
-**
-** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
-** interfaces.
-*/
-SQLITE_API void *sqlite3_update_hook(
- sqlite3*,
- void(*)(void *,int ,char const *,char const *,sqlite3_int64),
- void*
-);
-
-/*
-** CAPI3REF: Enable Or Disable Shared Pager Cache
-**
-** ^(This routine enables or disables the sharing of the database cache
-** and schema data structures between [database connection | connections]
-** to the same database. Sharing is enabled if the argument is true
-** and disabled if the argument is false.)^
-**
-** ^Cache sharing is enabled and disabled for an entire process.
-** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
-** sharing was enabled or disabled for each thread separately.
-**
-** ^(The cache sharing mode set by this interface effects all subsequent
-** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
-** Existing database connections continue use the sharing mode
-** that was in effect at the time they were opened.)^
-**
-** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled
-** successfully. An [error code] is returned otherwise.)^
-**
-** ^Shared cache is disabled by default. But this might change in
-** future releases of SQLite. Applications that care about shared
-** cache setting should set it explicitly.
-**
-** This interface is threadsafe on processors where writing a
-** 32-bit integer is atomic.
-**
-** See Also: [SQLite Shared-Cache Mode]
-*/
-SQLITE_API int sqlite3_enable_shared_cache(int);
-
-/*
-** CAPI3REF: Attempt To Free Heap Memory
-**
-** ^The sqlite3_release_memory() interface attempts to free N bytes
-** of heap memory by deallocating non-essential memory allocations
-** held by the database library. Memory used to cache database
-** pages to improve performance is an example of non-essential memory.
-** ^sqlite3_release_memory() returns the number of bytes actually freed,
-** which might be more or less than the amount requested.
-** ^The sqlite3_release_memory() routine is a no-op returning zero
-** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT].
-**
-** See also: [sqlite3_db_release_memory()]
-*/
-SQLITE_API int sqlite3_release_memory(int);
-
-/*
-** CAPI3REF: Free Memory Used By A Database Connection
-**
-** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
-** memory as possible from database connection D. Unlike the
-** [sqlite3_release_memory()] interface, this interface is effect even
-** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
-** omitted.
-**
-** See also: [sqlite3_release_memory()]
-*/
-SQLITE_API int sqlite3_db_release_memory(sqlite3*);
-
-/*
-** CAPI3REF: Impose A Limit On Heap Size
-**
-** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
-** soft limit on the amount of heap memory that may be allocated by SQLite.
-** ^SQLite strives to keep heap memory utilization below the soft heap
-** limit by reducing the number of pages held in the page cache
-** as heap memory usages approaches the limit.
-** ^The soft heap limit is "soft" because even though SQLite strives to stay
-** below the limit, it will exceed the limit rather than generate
-** an [SQLITE_NOMEM] error. In other words, the soft heap limit
-** is advisory only.
-**
-** ^The return value from sqlite3_soft_heap_limit64() is the size of
-** the soft heap limit prior to the call, or negative in the case of an
-** error. ^If the argument N is negative
-** then no change is made to the soft heap limit. Hence, the current
-** size of the soft heap limit can be determined by invoking
-** sqlite3_soft_heap_limit64() with a negative argument.
-**
-** ^If the argument N is zero then the soft heap limit is disabled.
-**
-** ^(The soft heap limit is not enforced in the current implementation
-** if one or more of following conditions are true:
-**
-** <ul>
-** <li> The soft heap limit is set to zero.
-** <li> Memory accounting is disabled using a combination of the
-** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
-** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
-** <li> An alternative page cache implementation is specified using
-** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...).
-** <li> The page cache allocates from its own memory pool supplied
-** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than
-** from the heap.
-** </ul>)^
-**
-** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
-** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
-** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
-** the soft heap limit is enforced on every memory allocation. Without
-** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced
-** when memory is allocated by the page cache. Testing suggests that because
-** the page cache is the predominate memory user in SQLite, most
-** applications will achieve adequate soft heap limit enforcement without
-** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT].
-**
-** The circumstances under which SQLite will enforce the soft heap limit may
-** changes in future releases of SQLite.
-*/
-SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
-
-/*
-** CAPI3REF: Deprecated Soft Heap Limit Interface
-** DEPRECATED
-**
-** This is a deprecated version of the [sqlite3_soft_heap_limit64()]
-** interface. This routine is provided for historical compatibility
-** only. All new applications should use the
-** [sqlite3_soft_heap_limit64()] interface rather than this one.
-*/
-SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
-
-
-/*
-** CAPI3REF: Extract Metadata About A Column Of A Table
-**
-** ^This routine returns metadata about a specific column of a specific
-** database table accessible using the [database connection] handle
-** passed as the first function argument.
-**
-** ^The column is identified by the second, third and fourth parameters to
-** this function. ^The second parameter is either the name of the database
-** (i.e. "main", "temp", or an attached database) containing the specified
-** table or NULL. ^If it is NULL, then all attached databases are searched
-** for the table using the same algorithm used by the database engine to
-** resolve unqualified table references.
-**
-** ^The third and fourth parameters to this function are the table and column
-** name of the desired column, respectively. Neither of these parameters
-** may be NULL.
-**
-** ^Metadata is returned by writing to the memory locations passed as the 5th
-** and subsequent parameters to this function. ^Any of these arguments may be
-** NULL, in which case the corresponding element of metadata is omitted.
-**
-** ^(<blockquote>
-** <table border="1">
-** <tr><th> Parameter <th> Output<br>Type <th> Description
-**
-** <tr><td> 5th <td> const char* <td> Data type
-** <tr><td> 6th <td> const char* <td> Name of default collation sequence
-** <tr><td> 7th <td> int <td> True if column has a NOT NULL constraint
-** <tr><td> 8th <td> int <td> True if column is part of the PRIMARY KEY
-** <tr><td> 9th <td> int <td> True if column is [AUTOINCREMENT]
-** </table>
-** </blockquote>)^
-**
-** ^The memory pointed to by the character pointers returned for the
-** declaration type and collation sequence is valid only until the next
-** call to any SQLite API function.
-**
-** ^If the specified table is actually a view, an [error code] is returned.
-**
-** ^If the specified column is "rowid", "oid" or "_rowid_" and an
-** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
-** parameters are set for the explicitly declared column. ^(If there is no
-** explicitly declared [INTEGER PRIMARY KEY] column, then the output
-** parameters are set as follows:
-**
-** <pre>
-** data type: "INTEGER"
-** collation sequence: "BINARY"
-** not null: 0
-** primary key: 1
-** auto increment: 0
-** </pre>)^
-**
-** ^(This function may load one or more schemas from database files. If an
-** error occurs during this process, or if the requested table or column
-** cannot be found, an [error code] is returned and an error message left
-** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
-**
-** ^This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
-*/
-SQLITE_API int sqlite3_table_column_metadata(
- sqlite3 *db, /* Connection handle */
- const char *zDbName, /* Database name or NULL */
- const char *zTableName, /* Table name */
- const char *zColumnName, /* Column name */
- char const **pzDataType, /* OUTPUT: Declared data type */
- char const **pzCollSeq, /* OUTPUT: Collation sequence name */
- int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */
- int *pPrimaryKey, /* OUTPUT: True if column part of PK */
- int *pAutoinc /* OUTPUT: True if column is auto-increment */
-);
-
-/*
-** CAPI3REF: Load An Extension
-**
-** ^This interface loads an SQLite extension library from the named file.
-**
-** ^The sqlite3_load_extension() interface attempts to load an
-** SQLite extension library contained in the file zFile.
-**
-** ^The entry point is zProc.
-** ^zProc may be 0, in which case the name of the entry point
-** defaults to "sqlite3_extension_init".
-** ^The sqlite3_load_extension() interface returns
-** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
-** ^If an error occurs and pzErrMsg is not 0, then the
-** [sqlite3_load_extension()] interface shall attempt to
-** fill *pzErrMsg with error message text stored in memory
-** obtained from [sqlite3_malloc()]. The calling function
-** should free this memory by calling [sqlite3_free()].
-**
-** ^Extension loading must be enabled using
-** [sqlite3_enable_load_extension()] prior to calling this API,
-** otherwise an error will be returned.
-**
-** See also the [load_extension() SQL function].
-*/
-SQLITE_API int sqlite3_load_extension(
- sqlite3 *db, /* Load the extension into this database connection */
- const char *zFile, /* Name of the shared library containing extension */
- const char *zProc, /* Entry point. Derived from zFile if 0 */
- char **pzErrMsg /* Put error message here if not 0 */
-);
-
-/*
-** CAPI3REF: Enable Or Disable Extension Loading
-**
-** ^So as not to open security holes in older applications that are
-** unprepared to deal with extension loading, and as a means of disabling
-** extension loading while evaluating user-entered SQL, the following API
-** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
-**
-** ^Extension loading is off by default. See ticket #1863.
-** ^Call the sqlite3_enable_load_extension() routine with onoff==1
-** to turn extension loading on and call it with onoff==0 to turn
-** it back off again.
-*/
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
-
-/*
-** CAPI3REF: Automatically Load Statically Linked Extensions
-**
-** ^This interface causes the xEntryPoint() function to be invoked for
-** each new [database connection] that is created. The idea here is that
-** xEntryPoint() is the entry point for a statically linked SQLite extension
-** that is to be automatically loaded into all new database connections.
-**
-** ^(Even though the function prototype shows that xEntryPoint() takes
-** no arguments and returns void, SQLite invokes xEntryPoint() with three
-** arguments and expects and integer result as if the signature of the
-** entry point where as follows:
-**
-** <blockquote><pre>
-** &nbsp; int xEntryPoint(
-** &nbsp; sqlite3 *db,
-** &nbsp; const char **pzErrMsg,
-** &nbsp; const struct sqlite3_api_routines *pThunk
-** &nbsp; );
-** </pre></blockquote>)^
-**
-** If the xEntryPoint routine encounters an error, it should make *pzErrMsg
-** point to an appropriate error message (obtained from [sqlite3_mprintf()])
-** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg
-** is NULL before calling the xEntryPoint(). ^SQLite will invoke
-** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any
-** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()],
-** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail.
-**
-** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
-** on the list of automatic extensions is a harmless no-op. ^No entry point
-** will be called more than once for each database connection that is opened.
-**
-** See also: [sqlite3_reset_auto_extension()].
-*/
-SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
-
-/*
-** CAPI3REF: Reset Automatic Extension Loading
-**
-** ^This interface disables all automatic extensions previously
-** registered using [sqlite3_auto_extension()].
-*/
-SQLITE_API void sqlite3_reset_auto_extension(void);
-
-/*
-** The interface to the virtual-table mechanism is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-*/
-
-/*
-** Structures used by the virtual table interface
-*/
-typedef struct sqlite3_vtab sqlite3_vtab;
-typedef struct sqlite3_index_info sqlite3_index_info;
-typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
-typedef struct sqlite3_module sqlite3_module;
-
-/*
-** CAPI3REF: Virtual Table Object
-** KEYWORDS: sqlite3_module {virtual table module}
-**
-** This structure, sometimes called a "virtual table module",
-** defines the implementation of a [virtual tables].
-** This structure consists mostly of methods for the module.
-**
-** ^A virtual table module is created by filling in a persistent
-** instance of this structure and passing a pointer to that instance
-** to [sqlite3_create_module()] or [sqlite3_create_module_v2()].
-** ^The registration remains valid until it is replaced by a different
-** module or until the [database connection] closes. The content
-** of this structure must not change while it is registered with
-** any database connection.
-*/
-struct sqlite3_module {
- int iVersion;
- int (*xCreate)(sqlite3*, void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVTab, char**);
- int (*xConnect)(sqlite3*, void *pAux,
- int argc, const char *const*argv,
- sqlite3_vtab **ppVTab, char**);
- int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
- int (*xDisconnect)(sqlite3_vtab *pVTab);
- int (*xDestroy)(sqlite3_vtab *pVTab);
- int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
- int (*xClose)(sqlite3_vtab_cursor*);
- int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
- int argc, sqlite3_value **argv);
- int (*xNext)(sqlite3_vtab_cursor*);
- int (*xEof)(sqlite3_vtab_cursor*);
- int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
- int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid);
- int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *);
- int (*xBegin)(sqlite3_vtab *pVTab);
- int (*xSync)(sqlite3_vtab *pVTab);
- int (*xCommit)(sqlite3_vtab *pVTab);
- int (*xRollback)(sqlite3_vtab *pVTab);
- int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName,
- void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
- void **ppArg);
- int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
- /* The methods above are in version 1 of the sqlite_module object. Those
- ** below are for version 2 and greater. */
- int (*xSavepoint)(sqlite3_vtab *pVTab, int);
- int (*xRelease)(sqlite3_vtab *pVTab, int);
- int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
-};
-
-/*
-** CAPI3REF: Virtual Table Indexing Information
-** KEYWORDS: sqlite3_index_info
-**
-** The sqlite3_index_info structure and its substructures is used as part
-** of the [virtual table] interface to
-** pass information into and receive the reply from the [xBestIndex]
-** method of a [virtual table module]. The fields under **Inputs** are the
-** inputs to xBestIndex and are read-only. xBestIndex inserts its
-** results into the **Outputs** fields.
-**
-** ^(The aConstraint[] array records WHERE clause constraints of the form:
-**
-** <blockquote>column OP expr</blockquote>
-**
-** where OP is =, &lt;, &lt;=, &gt;, or &gt;=.)^ ^(The particular operator is
-** stored in aConstraint[].op using one of the
-** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^
-** ^(The index of the column is stored in
-** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the
-** expr on the right-hand side can be evaluated (and thus the constraint
-** is usable) and false if it cannot.)^
-**
-** ^The optimizer automatically inverts terms of the form "expr OP column"
-** and makes other simplifications to the WHERE clause in an attempt to
-** get as many WHERE clause terms into the form shown above as possible.
-** ^The aConstraint[] array only reports WHERE clause terms that are
-** relevant to the particular virtual table being queried.
-**
-** ^Information about the ORDER BY clause is stored in aOrderBy[].
-** ^Each term of aOrderBy records a column of the ORDER BY clause.
-**
-** The [xBestIndex] method must fill aConstraintUsage[] with information
-** about what parameters to pass to xFilter. ^If argvIndex>0 then
-** the right-hand side of the corresponding aConstraint[] is evaluated
-** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit
-** is true, then the constraint is assumed to be fully handled by the
-** virtual table and is not checked again by SQLite.)^
-**
-** ^The idxNum and idxPtr values are recorded and passed into the
-** [xFilter] method.
-** ^[sqlite3_free()] is used to free idxPtr if and only if
-** needToFreeIdxPtr is true.
-**
-** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
-** the correct order to satisfy the ORDER BY clause so that no separate
-** sorting step is required.
-**
-** ^The estimatedCost value is an estimate of the cost of doing the
-** particular lookup. A full scan of a table with N entries should have
-** a cost of N. A binary search of a table of N entries should have a
-** cost of approximately log(N).
-*/
-struct sqlite3_index_info {
- /* Inputs */
- int nConstraint; /* Number of entries in aConstraint */
- struct sqlite3_index_constraint {
- int iColumn; /* Column on left-hand side of constraint */
- unsigned char op; /* Constraint operator */
- unsigned char usable; /* True if this constraint is usable */
- int iTermOffset; /* Used internally - xBestIndex should ignore */
- } *aConstraint; /* Table of WHERE clause constraints */
- int nOrderBy; /* Number of terms in the ORDER BY clause */
- struct sqlite3_index_orderby {
- int iColumn; /* Column number */
- unsigned char desc; /* True for DESC. False for ASC. */
- } *aOrderBy; /* The ORDER BY clause */
- /* Outputs */
- struct sqlite3_index_constraint_usage {
- int argvIndex; /* if >0, constraint is part of argv to xFilter */
- unsigned char omit; /* Do not code a test for this constraint */
- } *aConstraintUsage;
- int idxNum; /* Number used to identify the index */
- char *idxStr; /* String, possibly obtained from sqlite3_malloc */
- int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
- int orderByConsumed; /* True if output is already ordered */
- double estimatedCost; /* Estimated cost of using this index */
-};
-
-/*
-** CAPI3REF: Virtual Table Constraint Operator Codes
-**
-** These macros defined the allowed values for the
-** [sqlite3_index_info].aConstraint[].op field. Each value represents
-** an operator that is part of a constraint term in the wHERE clause of
-** a query that uses a [virtual table].
-*/
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
-#define SQLITE_INDEX_CONSTRAINT_GT 4
-#define SQLITE_INDEX_CONSTRAINT_LE 8
-#define SQLITE_INDEX_CONSTRAINT_LT 16
-#define SQLITE_INDEX_CONSTRAINT_GE 32
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
-
-/*
-** CAPI3REF: Register A Virtual Table Implementation
-**
-** ^These routines are used to register a new [virtual table module] name.
-** ^Module names must be registered before
-** creating a new [virtual table] using the module and before using a
-** preexisting [virtual table] for the module.
-**
-** ^The module name is registered on the [database connection] specified
-** by the first parameter. ^The name of the module is given by the
-** second parameter. ^The third parameter is a pointer to
-** the implementation of the [virtual table module]. ^The fourth
-** parameter is an arbitrary client data pointer that is passed through
-** into the [xCreate] and [xConnect] methods of the virtual table module
-** when a new virtual table is be being created or reinitialized.
-**
-** ^The sqlite3_create_module_v2() interface has a fifth parameter which
-** is a pointer to a destructor for the pClientData. ^SQLite will
-** invoke the destructor function (if it is not NULL) when SQLite
-** no longer needs the pClientData pointer. ^The destructor will also
-** be invoked if the call to sqlite3_create_module_v2() fails.
-** ^The sqlite3_create_module()
-** interface is equivalent to sqlite3_create_module_v2() with a NULL
-** destructor.
-*/
-SQLITE_API int sqlite3_create_module(
- sqlite3 *db, /* SQLite connection to register module with */
- const char *zName, /* Name of the module */
- const sqlite3_module *p, /* Methods for the module */
- void *pClientData /* Client data for xCreate/xConnect */
-);
-SQLITE_API int sqlite3_create_module_v2(
- sqlite3 *db, /* SQLite connection to register module with */
- const char *zName, /* Name of the module */
- const sqlite3_module *p, /* Methods for the module */
- void *pClientData, /* Client data for xCreate/xConnect */
- void(*xDestroy)(void*) /* Module destructor function */
-);
-
-/*
-** CAPI3REF: Virtual Table Instance Object
-** KEYWORDS: sqlite3_vtab
-**
-** Every [virtual table module] implementation uses a subclass
-** of this object to describe a particular instance
-** of the [virtual table]. Each subclass will
-** be tailored to the specific needs of the module implementation.
-** The purpose of this superclass is to define certain fields that are
-** common to all module implementations.
-**
-** ^Virtual tables methods can set an error message by assigning a
-** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should
-** take care that any prior string is freed by a call to [sqlite3_free()]
-** prior to assigning a new string to zErrMsg. ^After the error message
-** is delivered up to the client application, the string will be automatically
-** freed by sqlite3_free() and the zErrMsg field will be zeroed.
-*/
-struct sqlite3_vtab {
- const sqlite3_module *pModule; /* The module for this virtual table */
- int nRef; /* NO LONGER USED */
- char *zErrMsg; /* Error message from sqlite3_mprintf() */
- /* Virtual table implementations will typically add additional fields */
-};
-
-/*
-** CAPI3REF: Virtual Table Cursor Object
-** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor}
-**
-** Every [virtual table module] implementation uses a subclass of the
-** following structure to describe cursors that point into the
-** [virtual table] and are used
-** to loop through the virtual table. Cursors are created using the
-** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed
-** by the [sqlite3_module.xClose | xClose] method. Cursors are used
-** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods
-** of the module. Each module implementation will define
-** the content of a cursor structure to suit its own needs.
-**
-** This superclass exists in order to define fields of the cursor that
-** are common to all implementations.
-*/
-struct sqlite3_vtab_cursor {
- sqlite3_vtab *pVtab; /* Virtual table of this cursor */
- /* Virtual table implementations will typically add additional fields */
-};
-
-/*
-** CAPI3REF: Declare The Schema Of A Virtual Table
-**
-** ^The [xCreate] and [xConnect] methods of a
-** [virtual table module] call this interface
-** to declare the format (the names and datatypes of the columns) of
-** the virtual tables they implement.
-*/
-SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
-
-/*
-** CAPI3REF: Overload A Function For A Virtual Table
-**
-** ^(Virtual tables can provide alternative implementations of functions
-** using the [xFindFunction] method of the [virtual table module].
-** But global versions of those functions
-** must exist in order to be overloaded.)^
-**
-** ^(This API makes sure a global version of a function with a particular
-** name and number of parameters exists. If no such function exists
-** before this API is called, a new function is created.)^ ^The implementation
-** of the new function always causes an exception to be thrown. So
-** the new function is not good for anything by itself. Its only
-** purpose is to be a placeholder function that can be overloaded
-** by a [virtual table].
-*/
-SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
-
-/*
-** The interface to the virtual-table mechanism defined above (back up
-** to a comment remarkably similar to this one) is currently considered
-** to be experimental. The interface might change in incompatible ways.
-** If this is a problem for you, do not use the interface at this time.
-**
-** When the virtual-table mechanism stabilizes, we will declare the
-** interface fixed, support it indefinitely, and remove this comment.
-*/
-
-/*
-** CAPI3REF: A Handle To An Open BLOB
-** KEYWORDS: {BLOB handle} {BLOB handles}
-**
-** An instance of this object represents an open BLOB on which
-** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
-** ^Objects of this type are created by [sqlite3_blob_open()]
-** and destroyed by [sqlite3_blob_close()].
-** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces
-** can be used to read or write small subsections of the BLOB.
-** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes.
-*/
-typedef struct sqlite3_blob sqlite3_blob;
-
-/*
-** CAPI3REF: Open A BLOB For Incremental I/O
-**
-** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
-** in row iRow, column zColumn, table zTable in database zDb;
-** in other words, the same BLOB that would be selected by:
-**
-** <pre>
-** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
-** </pre>)^
-**
-** ^If the flags parameter is non-zero, then the BLOB is opened for read
-** and write access. ^If it is zero, the BLOB is opened for read access.
-** ^It is not possible to open a column that is part of an index or primary
-** key for writing. ^If [foreign key constraints] are enabled, it is
-** not possible to open a column that is part of a [child key] for writing.
-**
-** ^Note that the database name is not the filename that contains
-** the database but rather the symbolic name of the database that
-** appears after the AS keyword when the database is connected using [ATTACH].
-** ^For the main database file, the database name is "main".
-** ^For TEMP tables, the database name is "temp".
-**
-** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
-** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
-** to be a null pointer.)^
-** ^This function sets the [database connection] error code and message
-** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
-** functions. ^Note that the *ppBlob variable is always initialized in a
-** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
-** regardless of the success or failure of this routine.
-**
-** ^(If the row that a BLOB handle points to is modified by an
-** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
-** then the BLOB handle is marked as "expired".
-** This is true if any column of the row is changed, even a column
-** other than the one the BLOB handle is open on.)^
-** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
-** an expired BLOB handle fail with a return code of [SQLITE_ABORT].
-** ^(Changes written into a BLOB prior to the BLOB expiring are not
-** rolled back by the expiration of the BLOB. Such changes will eventually
-** commit if the transaction continues to completion.)^
-**
-** ^Use the [sqlite3_blob_bytes()] interface to determine the size of
-** the opened blob. ^The size of a blob may not be changed by this
-** interface. Use the [UPDATE] SQL command to change the size of a
-** blob.
-**
-** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
-** and the built-in [zeroblob] SQL function can be used, if desired,
-** to create an empty, zero-filled blob in which to read or write using
-** this interface.
-**
-** To avoid a resource leak, every open [BLOB handle] should eventually
-** be released by a call to [sqlite3_blob_close()].
-*/
-SQLITE_API int sqlite3_blob_open(
- sqlite3*,
- const char *zDb,
- const char *zTable,
- const char *zColumn,
- sqlite3_int64 iRow,
- int flags,
- sqlite3_blob **ppBlob
-);
-
-/*
-** CAPI3REF: Move a BLOB Handle to a New Row
-**
-** ^This function is used to move an existing blob handle so that it points
-** to a different row of the same database table. ^The new row is identified
-** by the rowid value passed as the second argument. Only the row can be
-** changed. ^The database, table and column on which the blob handle is open
-** remain the same. Moving an existing blob handle to a new row can be
-** faster than closing the existing handle and opening a new one.
-**
-** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
-** it must exist and there must be either a blob or text value stored in
-** the nominated column.)^ ^If the new row is not present in the table, or if
-** it does not contain a blob or text value, or if another error occurs, an
-** SQLite error code is returned and the blob handle is considered aborted.
-** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or
-** [sqlite3_blob_reopen()] on an aborted blob handle immediately return
-** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
-** always returns zero.
-**
-** ^This function sets the database handle error code and message.
-*/
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
-
-/*
-** CAPI3REF: Close A BLOB Handle
-**
-** ^Closes an open [BLOB handle].
-**
-** ^Closing a BLOB shall cause the current transaction to commit
-** if there are no other BLOBs, no pending prepared statements, and the
-** database connection is in [autocommit mode].
-** ^If any writes were made to the BLOB, they might be held in cache
-** until the close operation if they will fit.
-**
-** ^(Closing the BLOB often forces the changes
-** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed. Any errors that occur during
-** closing are reported as a non-zero return value.)^
-**
-** ^(The BLOB is closed unconditionally. Even if this routine returns
-** an error code, the BLOB is still closed.)^
-**
-** ^Calling this routine with a null pointer (such as would be returned
-** by a failed call to [sqlite3_blob_open()]) is a harmless no-op.
-*/
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
-
-/*
-** CAPI3REF: Return The Size Of An Open BLOB
-**
-** ^Returns the size in bytes of the BLOB accessible via the
-** successfully opened [BLOB handle] in its only argument. ^The
-** incremental blob I/O routines can only read or overwriting existing
-** blob content; they cannot change the size of a blob.
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-*/
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
-
-/*
-** CAPI3REF: Read Data From A BLOB Incrementally
-**
-** ^(This function is used to read data from an open [BLOB handle] into a
-** caller-supplied buffer. N bytes of data are copied into buffer Z
-** from the open BLOB, starting at offset iOffset.)^
-**
-** ^If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is
-** less than zero, [SQLITE_ERROR] is returned and no data is read.
-** ^The size of the blob (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
-**
-** ^An attempt to read from an expired [BLOB handle] fails with an
-** error code of [SQLITE_ABORT].
-**
-** ^(On success, sqlite3_blob_read() returns SQLITE_OK.
-** Otherwise, an [error code] or an [extended error code] is returned.)^
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** See also: [sqlite3_blob_write()].
-*/
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
-
-/*
-** CAPI3REF: Write Data Into A BLOB Incrementally
-**
-** ^This function is used to write data into an open [BLOB handle] from a
-** caller-supplied buffer. ^N bytes of data are copied from the buffer Z
-** into the open BLOB, starting at offset iOffset.
-**
-** ^If the [BLOB handle] passed as the first argument was not opened for
-** writing (the flags parameter to [sqlite3_blob_open()] was zero),
-** this function returns [SQLITE_READONLY].
-**
-** ^This function may only modify the contents of the BLOB; it is
-** not possible to increase the size of a BLOB using this API.
-** ^If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is written. ^If N is
-** less than zero [SQLITE_ERROR] is returned and no data is written.
-** The size of the BLOB (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
-**
-** ^An attempt to write to an expired [BLOB handle] fails with an
-** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred
-** before the [BLOB handle] expired are not rolled back by the
-** expiration of the handle, though of course those changes might
-** have been overwritten by the statement that expired the BLOB handle
-** or by other independent statements.
-**
-** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
-** Otherwise, an [error code] or an [extended error code] is returned.)^
-**
-** This routine only works on a [BLOB handle] which has been created
-** by a prior successful call to [sqlite3_blob_open()] and which has not
-** been closed by [sqlite3_blob_close()]. Passing any other pointer in
-** to this routine results in undefined and probably undesirable behavior.
-**
-** See also: [sqlite3_blob_read()].
-*/
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
-
-/*
-** CAPI3REF: Virtual File System Objects
-**
-** A virtual filesystem (VFS) is an [sqlite3_vfs] object
-** that SQLite uses to interact
-** with the underlying operating system. Most SQLite builds come with a
-** single default VFS that is appropriate for the host computer.
-** New VFSes can be registered and existing VFSes can be unregistered.
-** The following interfaces are provided.
-**
-** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name.
-** ^Names are case sensitive.
-** ^Names are zero-terminated UTF-8 strings.
-** ^If there is no match, a NULL pointer is returned.
-** ^If zVfsName is NULL then the default VFS is returned.
-**
-** ^New VFSes are registered with sqlite3_vfs_register().
-** ^Each new VFS becomes the default VFS if the makeDflt flag is set.
-** ^The same VFS can be registered multiple times without injury.
-** ^To make an existing VFS into the default VFS, register it again
-** with the makeDflt flag set. If two different VFSes with the
-** same name are registered, the behavior is undefined. If a
-** VFS is registered with a name that is NULL or an empty string,
-** then the behavior is undefined.
-**
-** ^Unregister a VFS with the sqlite3_vfs_unregister() interface.
-** ^(If the default VFS is unregistered, another VFS is chosen as
-** the default. The choice for the new VFS is arbitrary.)^
-*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
-
-/*
-** CAPI3REF: Mutexes
-**
-** The SQLite core uses these routines for thread
-** synchronization. Though they are intended for internal
-** use by SQLite, code that links against SQLite is
-** permitted to use any of these routines.
-**
-** The SQLite source code contains multiple implementations
-** of these mutex routines. An appropriate implementation
-** is selected automatically at compile-time. ^(The following
-** implementations are available in the SQLite core:
-**
-** <ul>
-** <li> SQLITE_MUTEX_PTHREADS
-** <li> SQLITE_MUTEX_W32
-** <li> SQLITE_MUTEX_NOOP
-** </ul>)^
-**
-** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
-** that does no real locking and is appropriate for use in
-** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS and
-** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
-** and Windows.
-**
-** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
-** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
-** implementation is included with the library. In this case the
-** application must supply a custom mutex implementation using the
-** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
-** before calling sqlite3_initialize() or any other public sqlite3_
-** function that calls sqlite3_initialize().)^
-**
-** ^The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. ^If it returns NULL
-** that means that a mutex could not be allocated. ^SQLite
-** will unwind its stack and return an error. ^(The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
-**
-** <ul>
-** <li> SQLITE_MUTEX_FAST
-** <li> SQLITE_MUTEX_RECURSIVE
-** <li> SQLITE_MUTEX_STATIC_MASTER
-** <li> SQLITE_MUTEX_STATIC_MEM
-** <li> SQLITE_MUTEX_STATIC_MEM2
-** <li> SQLITE_MUTEX_STATIC_PRNG
-** <li> SQLITE_MUTEX_STATIC_LRU
-** <li> SQLITE_MUTEX_STATIC_LRU2
-** </ul>)^
-**
-** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
-** cause sqlite3_mutex_alloc() to create
-** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
-** The mutex implementation does not need to make a distinction
-** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to. ^SQLite will only request a recursive mutex in
-** cases where it really needs one. ^If a faster non-recursive mutex
-** implementation is available on the host platform, the mutex subsystem
-** might return such a mutex in response to SQLITE_MUTEX_FAST.
-**
-** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
-** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
-** a pointer to a static preexisting mutex. ^Six static mutexes are
-** used by the current version of SQLite. Future versions of SQLite
-** may add additional static mutexes. Static mutexes are for internal
-** use by SQLite only. Applications that use SQLite mutexes should
-** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-** SQLITE_MUTEX_RECURSIVE.
-**
-** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
-** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call. ^But for the static
-** mutex types, the same mutex is returned on every call that has
-** the same type number.
-**
-** ^The sqlite3_mutex_free() routine deallocates a previously
-** allocated dynamic mutex. ^SQLite is careful to deallocate every
-** dynamic mutex that it allocates. The dynamic mutexes must not be in
-** use when they are deallocated. Attempting to deallocate a static
-** mutex results in undefined behavior. ^SQLite never deallocates
-** a static mutex.
-**
-** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-** to enter a mutex. ^If another thread is already within the mutex,
-** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
-** upon successful entry. ^(Mutexes created using
-** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
-** In such cases the,
-** mutex must be exited an equal number of times before another thread
-** can enter.)^ ^(If the same thread tries to enter any other
-** kind of mutex more than once, the behavior is undefined.
-** SQLite will never exhibit
-** such behavior in its own use of mutexes.)^
-**
-** ^(Some systems (for example, Windows 95) do not support the operation
-** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try()
-** will always return SQLITE_BUSY. The SQLite core only ever uses
-** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^
-**
-** ^The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread. ^(The behavior
-** is undefined if the mutex is not currently entered by the
-** calling thread or is not currently allocated. SQLite will
-** never do either.)^
-**
-** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
-** sqlite3_mutex_leave() is a NULL pointer, then all three routines
-** behave as no-ops.
-**
-** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
-*/
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
-
-/*
-** CAPI3REF: Mutex Methods Object
-**
-** An instance of this structure defines the low-level routines
-** used to allocate and use mutexes.
-**
-** Usually, the default mutex implementations provided by SQLite are
-** sufficient, however the user has the option of substituting a custom
-** implementation for specialized deployments or systems for which SQLite
-** does not provide a suitable implementation. In this case, the user
-** creates and populates an instance of this structure to pass
-** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
-** Additionally, an instance of this structure can be used as an
-** output variable when querying the system for the current mutex
-** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
-**
-** ^The xMutexInit method defined by this structure is invoked as
-** part of system initialization by the sqlite3_initialize() function.
-** ^The xMutexInit routine is called by SQLite exactly once for each
-** effective call to [sqlite3_initialize()].
-**
-** ^The xMutexEnd method defined by this structure is invoked as
-** part of system shutdown by the sqlite3_shutdown() function. The
-** implementation of this method is expected to release all outstanding
-** resources obtained by the mutex methods implementation, especially
-** those obtained by the xMutexInit method. ^The xMutexEnd()
-** interface is invoked exactly once for each call to [sqlite3_shutdown()].
-**
-** ^(The remaining seven methods defined by this structure (xMutexAlloc,
-** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and
-** xMutexNotheld) implement the following interfaces (respectively):
-**
-** <ul>
-** <li> [sqlite3_mutex_alloc()] </li>
-** <li> [sqlite3_mutex_free()] </li>
-** <li> [sqlite3_mutex_enter()] </li>
-** <li> [sqlite3_mutex_try()] </li>
-** <li> [sqlite3_mutex_leave()] </li>
-** <li> [sqlite3_mutex_held()] </li>
-** <li> [sqlite3_mutex_notheld()] </li>
-** </ul>)^
-**
-** The only difference is that the public sqlite3_XXX functions enumerated
-** above silently ignore any invocations that pass a NULL pointer instead
-** of a valid mutex handle. The implementations of the methods defined
-** by this structure are not required to handle this case, the results
-** of passing a NULL pointer instead of a valid mutex handle are undefined
-** (i.e. it is acceptable to provide an implementation that segfaults if
-** it is passed a NULL pointer).
-**
-** The xMutexInit() method must be threadsafe. ^It must be harmless to
-** invoke xMutexInit() multiple times within the same process and without
-** intervening calls to xMutexEnd(). Second and subsequent calls to
-** xMutexInit() must be no-ops.
-**
-** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
-** and its associates). ^Similarly, xMutexAlloc() must not use SQLite memory
-** allocation for a static mutex. ^However xMutexAlloc() may use SQLite
-** memory allocation for a fast or recursive mutex.
-**
-** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is
-** called, but only if the prior call to xMutexInit returned SQLITE_OK.
-** If xMutexInit fails in any way, it is expected to clean up after itself
-** prior to returning.
-*/
-typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
-struct sqlite3_mutex_methods {
- int (*xMutexInit)(void);
- int (*xMutexEnd)(void);
- sqlite3_mutex *(*xMutexAlloc)(int);
- void (*xMutexFree)(sqlite3_mutex *);
- void (*xMutexEnter)(sqlite3_mutex *);
- int (*xMutexTry)(sqlite3_mutex *);
- void (*xMutexLeave)(sqlite3_mutex *);
- int (*xMutexHeld)(sqlite3_mutex *);
- int (*xMutexNotheld)(sqlite3_mutex *);
-};
-
-/*
-** CAPI3REF: Mutex Verification Routines
-**
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements. ^The SQLite core
-** never uses these routines except inside an assert() and applications
-** are advised to follow the lead of the core. ^The SQLite core only
-** provides implementations for these routines when it is compiled
-** with the SQLITE_DEBUG flag. ^External mutex implementations
-** are only required to provide these routines if SQLITE_DEBUG is
-** defined and if NDEBUG is not defined.
-**
-** ^These routines should return true if the mutex in their argument
-** is held or not held, respectively, by the calling thread.
-**
-** ^The implementation is not required to provide versions of these
-** routines that actually work. If the implementation does not provide working
-** versions of these routines, it should at least provide stubs that always
-** return true so that one does not get spurious assertion failures.
-**
-** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
-** the routine should return 1. This seems counter-intuitive since
-** clearly the mutex cannot be held if it does not exist. But
-** the reason the mutex does not exist is because the build is not
-** using mutexes. And we do not want the assert() containing the
-** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do. ^The sqlite3_mutex_notheld()
-** interface should also return 1 when given a NULL pointer.
-*/
-#ifndef NDEBUG
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
-#endif
-
-/*
-** CAPI3REF: Mutex Types
-**
-** The [sqlite3_mutex_alloc()] interface takes a single argument
-** which is one of these integer constants.
-**
-** The set of static mutexes may change from one SQLite release to the
-** next. Applications that override the built-in mutex logic must be
-** prepared to accommodate additional static mutexes.
-*/
-#define SQLITE_MUTEX_FAST 0
-#define SQLITE_MUTEX_RECURSIVE 1
-#define SQLITE_MUTEX_STATIC_MASTER 2
-#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
-#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
-#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
-#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */
-#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
-#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
-#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
-
-/*
-** CAPI3REF: Retrieve the mutex for a database connection
-**
-** ^This interface returns a pointer the [sqlite3_mutex] object that
-** serializes access to the [database connection] given in the argument
-** when the [threading mode] is Serialized.
-** ^If the [threading mode] is Single-thread or Multi-thread then this
-** routine returns a NULL pointer.
-*/
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
-
-/*
-** CAPI3REF: Low-Level Control Of Database Files
-**
-** ^The [sqlite3_file_control()] interface makes a direct call to the
-** xFileControl method for the [sqlite3_io_methods] object associated
-** with a particular database identified by the second argument. ^The
-** name of the database is "main" for the main database or "temp" for the
-** TEMP database, or the name that appears after the AS keyword for
-** databases that are added using the [ATTACH] SQL command.
-** ^A NULL pointer can be used in place of "main" to refer to the
-** main database file.
-** ^The third and fourth parameters to this routine
-** are passed directly through to the second and third parameters of
-** the xFileControl method. ^The return value of the xFileControl
-** method becomes the return value of this routine.
-**
-** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
-** a pointer to the underlying [sqlite3_file] object to be written into
-** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER
-** case is a short-circuit path which does not actually invoke the
-** underlying sqlite3_io_methods.xFileControl method.
-**
-** ^If the second parameter (zDbName) does not match the name of any
-** open database file, then SQLITE_ERROR is returned. ^This error
-** code is not remembered and will not be recalled by [sqlite3_errcode()]
-** or [sqlite3_errmsg()]. The underlying xFileControl method might
-** also return SQLITE_ERROR. There is no way to distinguish between
-** an incorrect zDbName and an SQLITE_ERROR return from the underlying
-** xFileControl method.
-**
-** See also: [SQLITE_FCNTL_LOCKSTATE]
-*/
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
-
-/*
-** CAPI3REF: Testing Interface
-**
-** ^The sqlite3_test_control() interface is used to read out internal
-** state of SQLite and to inject faults into SQLite for testing
-** purposes. ^The first parameter is an operation code that determines
-** the number, meaning, and operation of all subsequent parameters.
-**
-** This interface is not for use by applications. It exists solely
-** for verifying the correct operation of the SQLite library. Depending
-** on how the SQLite library is compiled, this interface might not exist.
-**
-** The details of the operation codes, their meanings, the parameters
-** they take, and what they do are all subject to change without notice.
-** Unlike most of the SQLite API, this function is not guaranteed to
-** operate consistently from one release to the next.
-*/
-SQLITE_API int sqlite3_test_control(int op, ...);
-
-/*
-** CAPI3REF: Testing Interface Operation Codes
-**
-** These constants are the valid operation code parameters used
-** as the first argument to [sqlite3_test_control()].
-**
-** These parameters and their meanings are subject to change
-** without notice. These values are for testing purposes only.
-** Applications should not use any of these parameters or the
-** [sqlite3_test_control()] interface.
-*/
-#define SQLITE_TESTCTRL_FIRST 5
-#define SQLITE_TESTCTRL_PRNG_SAVE 5
-#define SQLITE_TESTCTRL_PRNG_RESTORE 6
-#define SQLITE_TESTCTRL_PRNG_RESET 7
-#define SQLITE_TESTCTRL_BITVEC_TEST 8
-#define SQLITE_TESTCTRL_FAULT_INSTALL 9
-#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
-#define SQLITE_TESTCTRL_PENDING_BYTE 11
-#define SQLITE_TESTCTRL_ASSERT 12
-#define SQLITE_TESTCTRL_ALWAYS 13
-#define SQLITE_TESTCTRL_RESERVE 14
-#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
-#define SQLITE_TESTCTRL_ISKEYWORD 16
-#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
-#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
-#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
-#define SQLITE_TESTCTRL_LAST 19
-
-/*
-** CAPI3REF: SQLite Runtime Status
-**
-** ^This interface is used to retrieve runtime status information
-** about the performance of SQLite, and optionally to reset various
-** highwater marks. ^The first argument is an integer code for
-** the specific parameter to measure. ^(Recognized integer codes
-** are of the form [status parameters | SQLITE_STATUS_...].)^
-** ^The current value of the parameter is returned into *pCurrent.
-** ^The highest recorded value is returned in *pHighwater. ^If the
-** resetFlag is true, then the highest record value is reset after
-** *pHighwater is written. ^(Some parameters do not record the highest
-** value. For those parameters
-** nothing is written into *pHighwater and the resetFlag is ignored.)^
-** ^(Other parameters record only the highwater mark and not the current
-** value. For these latter parameters nothing is written into *pCurrent.)^
-**
-** ^The sqlite3_status() routine returns SQLITE_OK on success and a
-** non-zero [error code] on failure.
-**
-** This routine is threadsafe but is not atomic. This routine can be
-** called while other threads are running the same or different SQLite
-** interfaces. However the values returned in *pCurrent and
-** *pHighwater reflect the status of SQLite at different points in time
-** and it is possible that another thread might change the parameter
-** in between the times when *pCurrent and *pHighwater are written.
-**
-** See also: [sqlite3_db_status()]
-*/
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
-
-
-/*
-** CAPI3REF: Status Parameters
-** KEYWORDS: {status parameters}
-**
-** These integer constants designate various run-time status parameters
-** that can be returned by [sqlite3_status()].
-**
-** <dl>
-** [[SQLITE_STATUS_MEMORY_USED]] ^(<dt>SQLITE_STATUS_MEMORY_USED</dt>
-** <dd>This parameter is the current amount of memory checked out
-** using [sqlite3_malloc()], either directly or indirectly. The
-** figure includes calls made to [sqlite3_malloc()] by the application
-** and internal memory usage by the SQLite library. Scratch memory
-** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
-** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
-** this parameter. The amount returned is the sum of the allocation
-** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
-**
-** [[SQLITE_STATUS_MALLOC_SIZE]] ^(<dt>SQLITE_STATUS_MALLOC_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
-** internal equivalents). Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>)^
-**
-** [[SQLITE_STATUS_MALLOC_COUNT]] ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt>
-** <dd>This parameter records the number of separate memory allocations
-** currently checked out.</dd>)^
-**
-** [[SQLITE_STATUS_PAGECACHE_USED]] ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt>
-** <dd>This parameter returns the number of pages used out of the
-** [pagecache memory allocator] that was configured using
-** [SQLITE_CONFIG_PAGECACHE]. The
-** value returned is in pages, not in bytes.</dd>)^
-**
-** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]]
-** ^(<dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of page cache
-** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The
-** returned value includes allocations that overflowed because they
-** where too large (they were larger than the "sz" parameter to
-** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because
-** no space was left in the page cache.</dd>)^
-**
-** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [pagecache memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>)^
-**
-** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
-** <dd>This parameter returns the number of allocations used out of the
-** [scratch memory allocator] configured using
-** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
-** in bytes. Since a single thread may only have one scratch allocation
-** outstanding at time, this parameter also reports the number of threads
-** using scratch memory at the same time.</dd>)^
-**
-** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of scratch memory
-** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The values
-** returned include overflows because the requested allocation was too
-** larger (that is, because the requested allocation was larger than the
-** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
-** slots were available.
-** </dd>)^
-**
-** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [scratch memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>)^
-**
-** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
-** <dd>This parameter records the deepest parser stack. It is only
-** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].</dd>)^
-** </dl>
-**
-** New status parameters may be added from time to time.
-*/
-#define SQLITE_STATUS_MEMORY_USED 0
-#define SQLITE_STATUS_PAGECACHE_USED 1
-#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
-#define SQLITE_STATUS_SCRATCH_USED 3
-#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
-#define SQLITE_STATUS_MALLOC_SIZE 5
-#define SQLITE_STATUS_PARSER_STACK 6
-#define SQLITE_STATUS_PAGECACHE_SIZE 7
-#define SQLITE_STATUS_SCRATCH_SIZE 8
-#define SQLITE_STATUS_MALLOC_COUNT 9
-
-/*
-** CAPI3REF: Database Connection Status
-**
-** ^This interface is used to retrieve runtime status information
-** about a single [database connection]. ^The first argument is the
-** database connection object to be interrogated. ^The second argument
-** is an integer constant, taken from the set of
-** [SQLITE_DBSTATUS options], that
-** determines the parameter to interrogate. The set of
-** [SQLITE_DBSTATUS options] is likely
-** to grow in future releases of SQLite.
-**
-** ^The current value of the requested parameter is written into *pCur
-** and the highest instantaneous value is written into *pHiwtr. ^If
-** the resetFlg is true, then the highest instantaneous value is
-** reset back down to the current value.
-**
-** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
-** non-zero [error code] on failure.
-**
-** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
-*/
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
-
-/*
-** CAPI3REF: Status Parameters for database connections
-** KEYWORDS: {SQLITE_DBSTATUS options}
-**
-** These constants are the available integer "verbs" that can be passed as
-** the second argument to the [sqlite3_db_status()] interface.
-**
-** New verbs may be added in future releases of SQLite. Existing verbs
-** might be discontinued. Applications should check the return code from
-** [sqlite3_db_status()] to make sure that the call worked.
-** The [sqlite3_db_status()] interface will return a non-zero error code
-** if a discontinued or unsupported verb is invoked.
-**
-** <dl>
-** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt>
-** <dd>This parameter returns the number of lookaside memory slots currently
-** checked out.</dd>)^
-**
-** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
-** <dd>This parameter returns the number malloc attempts that were
-** satisfied using lookaside memory. Only the high-water value is meaningful;
-** the current value is always zero.)^
-**
-** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]]
-** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
-** <dd>This parameter returns the number malloc attempts that might have
-** been satisfied using lookaside memory but failed due to the amount of
-** memory requested being larger than the lookaside slot size.
-** Only the high-water value is meaningful;
-** the current value is always zero.)^
-**
-** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]]
-** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt>
-** <dd>This parameter returns the number malloc attempts that might have
-** been satisfied using lookaside memory but failed due to all lookaside
-** memory already being in use.
-** Only the high-water value is meaningful;
-** the current value is always zero.)^
-**
-** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
-** memory used by all pager caches associated with the database connection.)^
-** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
-**
-** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
-** memory used to store the schema for all databases associated
-** with the connection - main, temp, and any [ATTACH]-ed databases.)^
-** ^The full amount of memory used by the schemas is reported, even if the
-** schema memory is shared with other database connections due to
-** [shared cache mode] being enabled.
-** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
-**
-** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
-** and lookaside memory used by all prepared statements associated with
-** the database connection.)^
-** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
-** </dd>
-**
-** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
-** <dd>This parameter returns the number of pager cache hits that have
-** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT
-** is always 0.
-** </dd>
-**
-** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
-** <dd>This parameter returns the number of pager cache misses that have
-** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS
-** is always 0.
-** </dd>
-**
-** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt>
-** <dd>This parameter returns the number of dirty cache entries that have
-** been written to disk. Specifically, the number of pages written to the
-** wal file in wal mode databases, or the number of pages written to the
-** database file in rollback mode databases. Any pages written as part of
-** transaction rollback or database recovery operations are not included.
-** If an IO or other error occurs while writing a page to disk, the effect
-** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
-** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
-** </dd>
-** </dl>
-*/
-#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
-#define SQLITE_DBSTATUS_CACHE_USED 1
-#define SQLITE_DBSTATUS_SCHEMA_USED 2
-#define SQLITE_DBSTATUS_STMT_USED 3
-#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
-#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
-#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
-#define SQLITE_DBSTATUS_CACHE_HIT 7
-#define SQLITE_DBSTATUS_CACHE_MISS 8
-#define SQLITE_DBSTATUS_CACHE_WRITE 9
-#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
-
-
-/*
-** CAPI3REF: Prepared Statement Status
-**
-** ^(Each prepared statement maintains various
-** [SQLITE_STMTSTATUS counters] that measure the number
-** of times it has performed specific operations.)^ These counters can
-** be used to monitor the performance characteristics of the prepared
-** statements. For example, if the number of table steps greatly exceeds
-** the number of table searches or result rows, that would tend to indicate
-** that the prepared statement is using a full table scan rather than
-** an index.
-**
-** ^(This interface is used to retrieve and reset counter values from
-** a [prepared statement]. The first argument is the prepared statement
-** object to be interrogated. The second argument
-** is an integer code for a specific [SQLITE_STMTSTATUS counter]
-** to be interrogated.)^
-** ^The current value of the requested counter is returned.
-** ^If the resetFlg is true, then the counter is reset to zero after this
-** interface call returns.
-**
-** See also: [sqlite3_status()] and [sqlite3_db_status()].
-*/
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
-
-/*
-** CAPI3REF: Status Parameters for prepared statements
-** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters}
-**
-** These preprocessor macros define integer codes that name counter
-** values associated with the [sqlite3_stmt_status()] interface.
-** The meanings of the various counters are as follows:
-**
-** <dl>
-** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt>
-** <dd>^This is the number of times that SQLite has stepped forward in
-** a table as part of a full table scan. Large numbers for this counter
-** may indicate opportunities for performance improvement through
-** careful use of indices.</dd>
-**
-** [[SQLITE_STMTSTATUS_SORT]] <dt>SQLITE_STMTSTATUS_SORT</dt>
-** <dd>^This is the number of sort operations that have occurred.
-** A non-zero value in this counter may indicate an opportunity to
-** improvement performance through careful use of indices.</dd>
-**
-** [[SQLITE_STMTSTATUS_AUTOINDEX]] <dt>SQLITE_STMTSTATUS_AUTOINDEX</dt>
-** <dd>^This is the number of rows inserted into transient indices that
-** were created automatically in order to help joins run faster.
-** A non-zero value in this counter may indicate an opportunity to
-** improvement performance by adding permanent indices that do not
-** need to be reinitialized each time the statement is run.</dd>
-** </dl>
-*/
-#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
-#define SQLITE_STMTSTATUS_SORT 2
-#define SQLITE_STMTSTATUS_AUTOINDEX 3
-
-/*
-** CAPI3REF: Custom Page Cache Object
-**
-** The sqlite3_pcache type is opaque. It is implemented by
-** the pluggable module. The SQLite core has no knowledge of
-** its size or internal structure and never deals with the
-** sqlite3_pcache object except by holding and passing pointers
-** to the object.
-**
-** See [sqlite3_pcache_methods2] for additional information.
-*/
-typedef struct sqlite3_pcache sqlite3_pcache;
-
-/*
-** CAPI3REF: Custom Page Cache Object
-**
-** The sqlite3_pcache_page object represents a single page in the
-** page cache. The page cache will allocate instances of this
-** object. Various methods of the page cache use pointers to instances
-** of this object as parameters or as their return value.
-**
-** See [sqlite3_pcache_methods2] for additional information.
-*/
-typedef struct sqlite3_pcache_page sqlite3_pcache_page;
-struct sqlite3_pcache_page {
- void *pBuf; /* The content of the page */
- void *pExtra; /* Extra information associated with the page */
-};
-
-/*
-** CAPI3REF: Application Defined Page Cache.
-** KEYWORDS: {page cache}
-**
-** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can
-** register an alternative page cache implementation by passing in an
-** instance of the sqlite3_pcache_methods2 structure.)^
-** In many applications, most of the heap memory allocated by
-** SQLite is used for the page cache.
-** By implementing a
-** custom page cache using this API, an application can better control
-** the amount of memory consumed by SQLite, the way in which
-** that memory is allocated and released, and the policies used to
-** determine exactly which parts of a database file are cached and for
-** how long.
-**
-** The alternative page cache mechanism is an
-** extreme measure that is only needed by the most demanding applications.
-** The built-in page cache is recommended for most uses.
-**
-** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an
-** internal buffer by SQLite within the call to [sqlite3_config]. Hence
-** the application may discard the parameter after the call to
-** [sqlite3_config()] returns.)^
-**
-** [[the xInit() page cache method]]
-** ^(The xInit() method is called once for each effective
-** call to [sqlite3_initialize()])^
-** (usually only once during the lifetime of the process). ^(The xInit()
-** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^
-** The intent of the xInit() method is to set up global data structures
-** required by the custom page cache implementation.
-** ^(If the xInit() method is NULL, then the
-** built-in default page cache is used instead of the application defined
-** page cache.)^
-**
-** [[the xShutdown() page cache method]]
-** ^The xShutdown() method is called by [sqlite3_shutdown()].
-** It can be used to clean up
-** any outstanding resources before process shutdown, if required.
-** ^The xShutdown() method may be NULL.
-**
-** ^SQLite automatically serializes calls to the xInit method,
-** so the xInit method need not be threadsafe. ^The
-** xShutdown method is only called from [sqlite3_shutdown()] so it does
-** not need to be threadsafe either. All other methods must be threadsafe
-** in multithreaded applications.
-**
-** ^SQLite will never invoke xInit() more than once without an intervening
-** call to xShutdown().
-**
-** [[the xCreate() page cache methods]]
-** ^SQLite invokes the xCreate() method to construct a new cache instance.
-** SQLite will typically create one cache instance for each open database file,
-** though this is not guaranteed. ^The
-** first parameter, szPage, is the size in bytes of the pages that must
-** be allocated by the cache. ^szPage will always a power of two. ^The
-** second parameter szExtra is a number of bytes of extra storage
-** associated with each page cache entry. ^The szExtra parameter will
-** a number less than 250. SQLite will use the
-** extra szExtra bytes on each page to store metadata about the underlying
-** database page on disk. The value passed into szExtra depends
-** on the SQLite version, the target platform, and how SQLite was compiled.
-** ^The third argument to xCreate(), bPurgeable, is true if the cache being
-** created will be used to cache database pages of a file stored on disk, or
-** false if it is used for an in-memory database. The cache implementation
-** does not have to do anything special based with the value of bPurgeable;
-** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will
-** never invoke xUnpin() except to deliberately delete a page.
-** ^In other words, calls to xUnpin() on a cache with bPurgeable set to
-** false will always have the "discard" flag set to true.
-** ^Hence, a cache created with bPurgeable false will
-** never contain any unpinned pages.
-**
-** [[the xCachesize() page cache method]]
-** ^(The xCachesize() method may be called at any time by SQLite to set the
-** suggested maximum cache-size (number of pages stored by) the cache
-** instance passed as the first argument. This is the value configured using
-** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable
-** parameter, the implementation is not required to do anything with this
-** value; it is advisory only.
-**
-** [[the xPagecount() page cache methods]]
-** The xPagecount() method must return the number of pages currently
-** stored in the cache, both pinned and unpinned.
-**
-** [[the xFetch() page cache methods]]
-** The xFetch() method locates a page in the cache and returns a pointer to
-** an sqlite3_pcache_page object associated with that page, or a NULL pointer.
-** The pBuf element of the returned sqlite3_pcache_page object will be a
-** pointer to a buffer of szPage bytes used to store the content of a
-** single database page. The pExtra element of sqlite3_pcache_page will be
-** a pointer to the szExtra bytes of extra storage that SQLite has requested
-** for each entry in the page cache.
-**
-** The page to be fetched is determined by the key. ^The minimum key value
-** is 1. After it has been retrieved using xFetch, the page is considered
-** to be "pinned".
-**
-** If the requested page is already in the page cache, then the page cache
-** implementation must return a pointer to the page buffer with its content
-** intact. If the requested page is not already in the cache, then the
-** cache implementation should use the value of the createFlag
-** parameter to help it determined what action to take:
-**
-** <table border=1 width=85% align=center>
-** <tr><th> createFlag <th> Behaviour when page is not already in cache
-** <tr><td> 0 <td> Do not allocate a new page. Return NULL.
-** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
-** Otherwise return NULL.
-** <tr><td> 2 <td> Make every effort to allocate a new page. Only return
-** NULL if allocating a new page is effectively impossible.
-** </table>
-**
-** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite
-** will only use a createFlag of 2 after a prior call with a createFlag of 1
-** failed.)^ In between the to xFetch() calls, SQLite may
-** attempt to unpin one or more cache pages by spilling the content of
-** pinned pages to disk and synching the operating system disk cache.
-**
-** [[the xUnpin() page cache method]]
-** ^xUnpin() is called by SQLite with a pointer to a currently pinned page
-** as its second argument. If the third parameter, discard, is non-zero,
-** then the page must be evicted from the cache.
-** ^If the discard parameter is
-** zero, then the page may be discarded or retained at the discretion of
-** page cache implementation. ^The page cache implementation
-** may choose to evict unpinned pages at any time.
-**
-** The cache must not perform any reference counting. A single
-** call to xUnpin() unpins the page regardless of the number of prior calls
-** to xFetch().
-**
-** [[the xRekey() page cache methods]]
-** The xRekey() method is used to change the key value associated with the
-** page passed as the second argument. If the cache
-** previously contains an entry associated with newKey, it must be
-** discarded. ^Any prior cache entry associated with newKey is guaranteed not
-** to be pinned.
-**
-** When SQLite calls the xTruncate() method, the cache must discard all
-** existing cache entries with page numbers (keys) greater than or equal
-** to the value of the iLimit parameter passed to xTruncate(). If any
-** of these pages are pinned, they are implicitly unpinned, meaning that
-** they can be safely discarded.
-**
-** [[the xDestroy() page cache method]]
-** ^The xDestroy() method is used to delete a cache allocated by xCreate().
-** All resources associated with the specified cache should be freed. ^After
-** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
-** handle invalid, and will not use it with any other sqlite3_pcache_methods2
-** functions.
-**
-** [[the xShrink() page cache method]]
-** ^SQLite invokes the xShrink() method when it wants the page cache to
-** free up as much of heap memory as possible. The page cache implementation
-** is not obligated to free any memory, but well-behaved implementations should
-** do their best.
-*/
-typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2;
-struct sqlite3_pcache_methods2 {
- int iVersion;
- void *pArg;
- int (*xInit)(void*);
- void (*xShutdown)(void*);
- sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable);
- void (*xCachesize)(sqlite3_pcache*, int nCachesize);
- int (*xPagecount)(sqlite3_pcache*);
- sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
- void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard);
- void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*,
- unsigned oldKey, unsigned newKey);
- void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
- void (*xDestroy)(sqlite3_pcache*);
- void (*xShrink)(sqlite3_pcache*);
-};
-
-/*
-** This is the obsolete pcache_methods object that has now been replaced
-** by sqlite3_pcache_methods2. This object is not used by SQLite. It is
-** retained in the header file for backwards compatibility only.
-*/
-typedef struct sqlite3_pcache_methods sqlite3_pcache_methods;
-struct sqlite3_pcache_methods {
- void *pArg;
- int (*xInit)(void*);
- void (*xShutdown)(void*);
- sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable);
- void (*xCachesize)(sqlite3_pcache*, int nCachesize);
- int (*xPagecount)(sqlite3_pcache*);
- void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag);
- void (*xUnpin)(sqlite3_pcache*, void*, int discard);
- void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
- void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
- void (*xDestroy)(sqlite3_pcache*);
-};
-
-
-/*
-** CAPI3REF: Online Backup Object
-**
-** The sqlite3_backup object records state information about an ongoing
-** online backup operation. ^The sqlite3_backup object is created by
-** a call to [sqlite3_backup_init()] and is destroyed by a call to
-** [sqlite3_backup_finish()].
-**
-** See Also: [Using the SQLite Online Backup API]
-*/
-typedef struct sqlite3_backup sqlite3_backup;
-
-/*
-** CAPI3REF: Online Backup API.
-**
-** The backup API copies the content of one database into another.
-** It is useful either for creating backups of databases or
-** for copying in-memory databases to or from persistent files.
-**
-** See Also: [Using the SQLite Online Backup API]
-**
-** ^SQLite holds a write transaction open on the destination database file
-** for the duration of the backup operation.
-** ^The source database is read-locked only while it is being read;
-** it is not locked continuously for the entire backup operation.
-** ^Thus, the backup may be performed on a live source database without
-** preventing other database connections from
-** reading or writing to the source database while the backup is underway.
-**
-** ^(To perform a backup operation:
-** <ol>
-** <li><b>sqlite3_backup_init()</b> is called once to initialize the
-** backup,
-** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer
-** the data between the two databases, and finally
-** <li><b>sqlite3_backup_finish()</b> is called to release all resources
-** associated with the backup operation.
-** </ol>)^
-** There should be exactly one call to sqlite3_backup_finish() for each
-** successful call to sqlite3_backup_init().
-**
-** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b>
-**
-** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the
-** [database connection] associated with the destination database
-** and the database name, respectively.
-** ^The database name is "main" for the main database, "temp" for the
-** temporary database, or the name specified after the AS keyword in
-** an [ATTACH] statement for an attached database.
-** ^The S and M arguments passed to
-** sqlite3_backup_init(D,N,S,M) identify the [database connection]
-** and database name of the source database, respectively.
-** ^The source and destination [database connections] (parameters S and D)
-** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
-** an error.
-**
-** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
-** returned and an error code and error message are stored in the
-** destination [database connection] D.
-** ^The error code and message for the failed call to sqlite3_backup_init()
-** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
-** [sqlite3_errmsg16()] functions.
-** ^A successful call to sqlite3_backup_init() returns a pointer to an
-** [sqlite3_backup] object.
-** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and
-** sqlite3_backup_finish() functions to perform the specified backup
-** operation.
-**
-** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b>
-**
-** ^Function sqlite3_backup_step(B,N) will copy up to N pages between
-** the source and destination databases specified by [sqlite3_backup] object B.
-** ^If N is negative, all remaining source pages are copied.
-** ^If sqlite3_backup_step(B,N) successfully copies N pages and there
-** are still more pages to be copied, then the function returns [SQLITE_OK].
-** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
-** from source to destination, then it returns [SQLITE_DONE].
-** ^If an error occurs while running sqlite3_backup_step(B,N),
-** then an [error code] is returned. ^As well as [SQLITE_OK] and
-** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
-** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
-**
-** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
-** <ol>
-** <li> the destination database was opened read-only, or
-** <li> the destination database is using write-ahead-log journaling
-** and the destination and source page sizes differ, or
-** <li> the destination database is an in-memory database and the
-** destination and source page sizes differ.
-** </ol>)^
-**
-** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
-** the [sqlite3_busy_handler | busy-handler function]
-** is invoked (if one is specified). ^If the
-** busy-handler returns non-zero before the lock is available, then
-** [SQLITE_BUSY] is returned to the caller. ^In this case the call to
-** sqlite3_backup_step() can be retried later. ^If the source
-** [database connection]
-** is being used to write to the source database when sqlite3_backup_step()
-** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this
-** case the call to sqlite3_backup_step() can be retried later on. ^(If
-** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
-** [SQLITE_READONLY] is returned, then
-** there is no point in retrying the call to sqlite3_backup_step(). These
-** errors are considered fatal.)^ The application must accept
-** that the backup operation has failed and pass the backup operation handle
-** to the sqlite3_backup_finish() to release associated resources.
-**
-** ^The first call to sqlite3_backup_step() obtains an exclusive lock
-** on the destination file. ^The exclusive lock is not released until either
-** sqlite3_backup_finish() is called or the backup operation is complete
-** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to
-** sqlite3_backup_step() obtains a [shared lock] on the source database that
-** lasts for the duration of the sqlite3_backup_step() call.
-** ^Because the source database is not locked between calls to
-** sqlite3_backup_step(), the source database may be modified mid-way
-** through the backup process. ^If the source database is modified by an
-** external process or via a database connection other than the one being
-** used by the backup operation, then the backup will be automatically
-** restarted by the next call to sqlite3_backup_step(). ^If the source
-** database is modified by the using the same database connection as is used
-** by the backup operation, then the backup database is automatically
-** updated at the same time.
-**
-** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b>
-**
-** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the
-** application wishes to abandon the backup operation, the application
-** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish().
-** ^The sqlite3_backup_finish() interfaces releases all
-** resources associated with the [sqlite3_backup] object.
-** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any
-** active write-transaction on the destination database is rolled back.
-** The [sqlite3_backup] object is invalid
-** and may not be used following a call to sqlite3_backup_finish().
-**
-** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no
-** sqlite3_backup_step() errors occurred, regardless or whether or not
-** sqlite3_backup_step() completed.
-** ^If an out-of-memory condition or IO error occurred during any prior
-** sqlite3_backup_step() call on the same [sqlite3_backup] object, then
-** sqlite3_backup_finish() returns the corresponding [error code].
-**
-** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step()
-** is not a permanent error and does not affect the return value of
-** sqlite3_backup_finish().
-**
-** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
-** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
-**
-** ^Each call to sqlite3_backup_step() sets two values inside
-** the [sqlite3_backup] object: the number of pages still to be backed
-** up and the total number of pages in the source database file.
-** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces
-** retrieve these two values, respectively.
-**
-** ^The values returned by these functions are only updated by
-** sqlite3_backup_step(). ^If the source database is modified during a backup
-** operation, then the values are not updated to account for any extra
-** pages that need to be updated or the size of the source database file
-** changing.
-**
-** <b>Concurrent Usage of Database Handles</b>
-**
-** ^The source [database connection] may be used by the application for other
-** purposes while a backup operation is underway or being initialized.
-** ^If SQLite is compiled and configured to support threadsafe database
-** connections, then the source database connection may be used concurrently
-** from within other threads.
-**
-** However, the application must guarantee that the destination
-** [database connection] is not passed to any other API (by any thread) after
-** sqlite3_backup_init() is called and before the corresponding call to
-** sqlite3_backup_finish(). SQLite does not currently check to see
-** if the application incorrectly accesses the destination [database connection]
-** and so no error code is reported, but the operations may malfunction
-** nevertheless. Use of the destination database connection while a
-** backup is in progress might also also cause a mutex deadlock.
-**
-** If running in [shared cache mode], the application must
-** guarantee that the shared cache used by the destination database
-** is not accessed while the backup is running. In practice this means
-** that the application must guarantee that the disk file being
-** backed up to is not accessed by any connection within the process,
-** not just the specific connection that was passed to sqlite3_backup_init().
-**
-** The [sqlite3_backup] object itself is partially threadsafe. Multiple
-** threads may safely make multiple concurrent calls to sqlite3_backup_step().
-** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
-** APIs are not strictly speaking threadsafe. If they are invoked at the
-** same time as another thread is invoking sqlite3_backup_step() it is
-** possible that they return invalid values.
-*/
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
- sqlite3 *pDest, /* Destination database handle */
- const char *zDestName, /* Destination database name */
- sqlite3 *pSource, /* Source database handle */
- const char *zSourceName /* Source database name */
-);
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
-
-/*
-** CAPI3REF: Unlock Notification
-**
-** ^When running in shared-cache mode, a database operation may fail with
-** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
-** individual tables within the shared-cache cannot be obtained. See
-** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
-** ^This API may be used to register a callback that SQLite will invoke
-** when the connection currently holding the required lock relinquishes it.
-** ^This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined.
-**
-** See Also: [Using the SQLite Unlock Notification Feature].
-**
-** ^Shared-cache locks are released when a database connection concludes
-** its current transaction, either by committing it or rolling it back.
-**
-** ^When a connection (known as the blocked connection) fails to obtain a
-** shared-cache lock and SQLITE_LOCKED is returned to the caller, the
-** identity of the database connection (the blocking connection) that
-** has locked the required resource is stored internally. ^After an
-** application receives an SQLITE_LOCKED error, it may call the
-** sqlite3_unlock_notify() method with the blocked connection handle as
-** the first argument to register for a callback that will be invoked
-** when the blocking connections current transaction is concluded. ^The
-** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
-** call that concludes the blocking connections transaction.
-**
-** ^(If sqlite3_unlock_notify() is called in a multi-threaded application,
-** there is a chance that the blocking connection will have already
-** concluded its transaction by the time sqlite3_unlock_notify() is invoked.
-** If this happens, then the specified callback is invoked immediately,
-** from within the call to sqlite3_unlock_notify().)^
-**
-** ^If the blocked connection is attempting to obtain a write-lock on a
-** shared-cache table, and more than one other connection currently holds
-** a read-lock on the same table, then SQLite arbitrarily selects one of
-** the other connections to use as the blocking connection.
-**
-** ^(There may be at most one unlock-notify callback registered by a
-** blocked connection. If sqlite3_unlock_notify() is called when the
-** blocked connection already has a registered unlock-notify callback,
-** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is
-** called with a NULL pointer as its second argument, then any existing
-** unlock-notify callback is canceled. ^The blocked connections
-** unlock-notify callback may also be canceled by closing the blocked
-** connection using [sqlite3_close()].
-**
-** The unlock-notify callback is not reentrant. If an application invokes
-** any sqlite3_xxx API functions from within an unlock-notify callback, a
-** crash or deadlock may be the result.
-**
-** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always
-** returns SQLITE_OK.
-**
-** <b>Callback Invocation Details</b>
-**
-** When an unlock-notify callback is registered, the application provides a
-** single void* pointer that is passed to the callback when it is invoked.
-** However, the signature of the callback function allows SQLite to pass
-** it an array of void* context pointers. The first argument passed to
-** an unlock-notify callback is a pointer to an array of void* pointers,
-** and the second is the number of entries in the array.
-**
-** When a blocking connections transaction is concluded, there may be
-** more than one blocked connection that has registered for an unlock-notify
-** callback. ^If two or more such blocked connections have specified the
-** same callback function, then instead of invoking the callback function
-** multiple times, it is invoked once with the set of void* context pointers
-** specified by the blocked connections bundled together into an array.
-** This gives the application an opportunity to prioritize any actions
-** related to the set of unblocked database connections.
-**
-** <b>Deadlock Detection</b>
-**
-** Assuming that after registering for an unlock-notify callback a
-** database waits for the callback to be issued before taking any further
-** action (a reasonable assumption), then using this API may cause the
-** application to deadlock. For example, if connection X is waiting for
-** connection Y's transaction to be concluded, and similarly connection
-** Y is waiting on connection X's transaction, then neither connection
-** will proceed and the system may remain deadlocked indefinitely.
-**
-** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock
-** detection. ^If a given call to sqlite3_unlock_notify() would put the
-** system in a deadlocked state, then SQLITE_LOCKED is returned and no
-** unlock-notify callback is registered. The system is said to be in
-** a deadlocked state if connection A has registered for an unlock-notify
-** callback on the conclusion of connection B's transaction, and connection
-** B has itself registered for an unlock-notify callback when connection
-** A's transaction is concluded. ^Indirect deadlock is also detected, so
-** the system is also considered to be deadlocked if connection B has
-** registered for an unlock-notify callback on the conclusion of connection
-** C's transaction, where connection C is waiting on connection A. ^Any
-** number of levels of indirection are allowed.
-**
-** <b>The "DROP TABLE" Exception</b>
-**
-** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost
-** always appropriate to call sqlite3_unlock_notify(). There is however,
-** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement,
-** SQLite checks if there are any currently executing SELECT statements
-** that belong to the same connection. If there are, SQLITE_LOCKED is
-** returned. In this case there is no "blocking connection", so invoking
-** sqlite3_unlock_notify() results in the unlock-notify callback being
-** invoked immediately. If the application then re-attempts the "DROP TABLE"
-** or "DROP INDEX" query, an infinite loop might be the result.
-**
-** One way around this problem is to check the extended error code returned
-** by an sqlite3_step() call. ^(If there is a blocking connection, then the
-** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in
-** the special "DROP TABLE/INDEX" case, the extended error code is just
-** SQLITE_LOCKED.)^
-*/
-SQLITE_API int sqlite3_unlock_notify(
- sqlite3 *pBlocked, /* Waiting connection */
- void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
- void *pNotifyArg /* Argument to pass to xNotify */
-);
-
-
-/*
-** CAPI3REF: String Comparison
-**
-** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications
-** and extensions to compare the contents of two buffers containing UTF-8
-** strings in a case-independent fashion, using the same definition of "case
-** independence" that SQLite uses internally when comparing identifiers.
-*/
-SQLITE_API int sqlite3_stricmp(const char *, const char *);
-SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
-
-/*
-** CAPI3REF: Error Logging Interface
-**
-** ^The [sqlite3_log()] interface writes a message into the error log
-** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()].
-** ^If logging is enabled, the zFormat string and subsequent arguments are
-** used with [sqlite3_snprintf()] to generate the final output string.
-**
-** The sqlite3_log() interface is intended for use by extensions such as
-** virtual tables, collating functions, and SQL functions. While there is
-** nothing to prevent an application from calling sqlite3_log(), doing so
-** is considered bad form.
-**
-** The zFormat string must not be NULL.
-**
-** To avoid deadlocks and other threading problems, the sqlite3_log() routine
-** will not use dynamically allocated memory. The log message is stored in
-** a fixed-length buffer on the stack. If the log message is longer than
-** a few hundred characters, it will be truncated to the length of the
-** buffer.
-*/
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
-
-/*
-** CAPI3REF: Write-Ahead Log Commit Hook
-**
-** ^The [sqlite3_wal_hook()] function is used to register a callback that
-** will be invoked each time a database connection commits data to a
-** [write-ahead log] (i.e. whenever a transaction is committed in
-** [journal_mode | journal_mode=WAL mode]).
-**
-** ^The callback is invoked by SQLite after the commit has taken place and
-** the associated write-lock on the database released, so the implementation
-** may read, write or [checkpoint] the database as required.
-**
-** ^The first parameter passed to the callback function when it is invoked
-** is a copy of the third parameter passed to sqlite3_wal_hook() when
-** registering the callback. ^The second is a copy of the database handle.
-** ^The third parameter is the name of the database that was written to -
-** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter
-** is the number of pages currently in the write-ahead log file,
-** including those that were just committed.
-**
-** The callback function should normally return [SQLITE_OK]. ^If an error
-** code is returned, that error will propagate back up through the
-** SQLite code base to cause the statement that provoked the callback
-** to report an error, though the commit will have still occurred. If the
-** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value
-** that does not correspond to any valid SQLite error code, the results
-** are undefined.
-**
-** A single database handle may have at most a single write-ahead log callback
-** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any
-** previously registered write-ahead log callback. ^Note that the
-** [sqlite3_wal_autocheckpoint()] interface and the
-** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
-** those overwrite any prior [sqlite3_wal_hook()] settings.
-*/
-SQLITE_API void *sqlite3_wal_hook(
- sqlite3*,
- int(*)(void *,sqlite3*,const char*,int),
- void*
-);
-
-/*
-** CAPI3REF: Configure an auto-checkpoint
-**
-** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
-** [sqlite3_wal_hook()] that causes any database on [database connection] D
-** to automatically [checkpoint]
-** after committing a transaction if there are N or
-** more frames in the [write-ahead log] file. ^Passing zero or
-** a negative value as the nFrame parameter disables automatic
-** checkpoints entirely.
-**
-** ^The callback registered by this function replaces any existing callback
-** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback
-** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism
-** configured by this function.
-**
-** ^The [wal_autocheckpoint pragma] can be used to invoke this interface
-** from SQL.
-**
-** ^Every new [database connection] defaults to having the auto-checkpoint
-** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
-** pages. The use of this interface
-** is only necessary if the default setting is found to be suboptimal
-** for a particular application.
-*/
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
-
-/*
-** CAPI3REF: Checkpoint a database
-**
-** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X
-** on [database connection] D to be [checkpointed]. ^If X is NULL or an
-** empty string, then a checkpoint is run on all databases of
-** connection D. ^If the database connection D is not in
-** [WAL | write-ahead log mode] then this interface is a harmless no-op.
-**
-** ^The [wal_checkpoint pragma] can be used to invoke this interface
-** from SQL. ^The [sqlite3_wal_autocheckpoint()] interface and the
-** [wal_autocheckpoint pragma] can be used to cause this interface to be
-** run whenever the WAL reaches a certain size threshold.
-**
-** See also: [sqlite3_wal_checkpoint_v2()]
-*/
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
-
-/*
-** CAPI3REF: Checkpoint a database
-**
-** Run a checkpoint operation on WAL database zDb attached to database
-** handle db. The specific operation is determined by the value of the
-** eMode parameter:
-**
-** <dl>
-** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
-** Checkpoint as many frames as possible without waiting for any database
-** readers or writers to finish. Sync the db file if all frames in the log
-** are checkpointed. This mode is the same as calling
-** sqlite3_wal_checkpoint(). The busy-handler callback is never invoked.
-**
-** <dt>SQLITE_CHECKPOINT_FULL<dd>
-** This mode blocks (calls the busy-handler callback) until there is no
-** database writer and all readers are reading from the most recent database
-** snapshot. It then checkpoints all frames in the log file and syncs the
-** database file. This call blocks database writers while it is running,
-** but not database readers.
-**
-** <dt>SQLITE_CHECKPOINT_RESTART<dd>
-** This mode works the same way as SQLITE_CHECKPOINT_FULL, except after
-** checkpointing the log file it blocks (calls the busy-handler callback)
-** until all readers are reading from the database file only. This ensures
-** that the next client to write to the database file restarts the log file
-** from the beginning. This call blocks database writers while it is running,
-** but not database readers.
-** </dl>
-**
-** If pnLog is not NULL, then *pnLog is set to the total number of frames in
-** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to
-** the total number of checkpointed frames (including any that were already
-** checkpointed when this function is called). *pnLog and *pnCkpt may be
-** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK.
-** If no values are available because of an error, they are both set to -1
-** before returning to communicate this to the caller.
-**
-** All calls obtain an exclusive "checkpoint" lock on the database file. If
-** any other process is running a checkpoint operation at the same time, the
-** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a
-** busy-handler configured, it will not be invoked in this case.
-**
-** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive
-** "writer" lock on the database file. If the writer lock cannot be obtained
-** immediately, and a busy-handler is configured, it is invoked and the writer
-** lock retried until either the busy-handler returns 0 or the lock is
-** successfully obtained. The busy-handler is also invoked while waiting for
-** database readers as described above. If the busy-handler returns 0 before
-** the writer lock is obtained or while waiting for database readers, the
-** checkpoint operation proceeds from that point in the same way as
-** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible
-** without blocking any further. SQLITE_BUSY is returned in this case.
-**
-** If parameter zDb is NULL or points to a zero length string, then the
-** specified operation is attempted on all WAL databases. In this case the
-** values written to output parameters *pnLog and *pnCkpt are undefined. If
-** an SQLITE_BUSY error is encountered when processing one or more of the
-** attached WAL databases, the operation is still attempted on any remaining
-** attached databases and SQLITE_BUSY is returned to the caller. If any other
-** error occurs while processing an attached database, processing is abandoned
-** and the error code returned to the caller immediately. If no error
-** (SQLITE_BUSY or otherwise) is encountered while processing the attached
-** databases, SQLITE_OK is returned.
-**
-** If database zDb is the name of an attached database that is not in WAL
-** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If
-** zDb is not NULL (or a zero length string) and is not the name of any
-** attached database, SQLITE_ERROR is returned to the caller.
-*/
-SQLITE_API int sqlite3_wal_checkpoint_v2(
- sqlite3 *db, /* Database handle */
- const char *zDb, /* Name of attached database (or NULL) */
- int eMode, /* SQLITE_CHECKPOINT_* value */
- int *pnLog, /* OUT: Size of WAL log in frames */
- int *pnCkpt /* OUT: Total number of frames checkpointed */
-);
-
-/*
-** CAPI3REF: Checkpoint operation parameters
-**
-** These constants can be used as the 3rd parameter to
-** [sqlite3_wal_checkpoint_v2()]. See the [sqlite3_wal_checkpoint_v2()]
-** documentation for additional information about the meaning and use of
-** each of these values.
-*/
-#define SQLITE_CHECKPOINT_PASSIVE 0
-#define SQLITE_CHECKPOINT_FULL 1
-#define SQLITE_CHECKPOINT_RESTART 2
-
-/*
-** CAPI3REF: Virtual Table Interface Configuration
-**
-** This function may be called by either the [xConnect] or [xCreate] method
-** of a [virtual table] implementation to configure
-** various facets of the virtual table interface.
-**
-** If this interface is invoked outside the context of an xConnect or
-** xCreate virtual table method then the behavior is undefined.
-**
-** At present, there is only one option that may be configured using
-** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options
-** may be added in the future.
-*/
-SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
-
-/*
-** CAPI3REF: Virtual Table Configuration Options
-**
-** These macros define the various options to the
-** [sqlite3_vtab_config()] interface that [virtual table] implementations
-** can use to customize and optimize their behavior.
-**
-** <dl>
-** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
-** <dd>Calls of the form
-** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
-** where X is an integer. If X is zero, then the [virtual table] whose
-** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
-** support constraints. In this configuration (which is the default) if
-** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire
-** statement is rolled back as if [ON CONFLICT | OR ABORT] had been
-** specified as part of the users SQL statement, regardless of the actual
-** ON CONFLICT mode specified.
-**
-** If X is non-zero, then the virtual table implementation guarantees
-** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before
-** any modifications to internal or persistent data structures have been made.
-** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite
-** is able to roll back a statement or database transaction, and abandon
-** or continue processing the current SQL statement as appropriate.
-** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns
-** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode
-** had been ABORT.
-**
-** Virtual table implementations that are required to handle OR REPLACE
-** must do so within the [xUpdate] method. If a call to the
-** [sqlite3_vtab_on_conflict()] function indicates that the current ON
-** CONFLICT policy is REPLACE, the virtual table implementation should
-** silently replace the appropriate rows within the xUpdate callback and
-** return SQLITE_OK. Or, if this is not possible, it may return
-** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT
-** constraint handling.
-** </dl>
-*/
-#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
-
-/*
-** CAPI3REF: Determine The Virtual Table Conflict Policy
-**
-** This function may only be called from within a call to the [xUpdate] method
-** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The
-** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
-** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
-** of the SQL statement that triggered the call to the [xUpdate] method of the
-** [virtual table].
-*/
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
-
-/*
-** CAPI3REF: Conflict resolution modes
-**
-** These constants are returned by [sqlite3_vtab_on_conflict()] to
-** inform a [virtual table] implementation what the [ON CONFLICT] mode
-** is for the SQL statement being evaluated.
-**
-** Note that the [SQLITE_IGNORE] constant is also used as a potential
-** return value from the [sqlite3_set_authorizer()] callback and that
-** [SQLITE_ABORT] is also a [result code].
-*/
-#define SQLITE_ROLLBACK 1
-/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */
-#define SQLITE_FAIL 3
-/* #define SQLITE_ABORT 4 // Also an error code */
-#define SQLITE_REPLACE 5
-
-
-
-/*
-** Undo the hack that converts floating point types to integer for
-** builds on processors without floating point support.
-*/
-#ifdef SQLITE_OMIT_FLOATING_POINT
-# undef double
-#endif
-
-#ifdef __cplusplus
-} /* End of the 'extern "C"' block */
-#endif
-#endif
-
-/*
-** 2010 August 30
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-*/
-
-#ifndef _SQLITE3RTREE_H_
-#define _SQLITE3RTREE_H_
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
-
-/*
-** Register a geometry callback named zGeom that can be used as part of an
-** R-Tree geometry query as follows:
-**
-** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
-*/
-SQLITE_API int sqlite3_rtree_geometry_callback(
- sqlite3 *db,
- const char *zGeom,
-#ifdef SQLITE_RTREE_INT_ONLY
- int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes),
-#else
- int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes),
-#endif
- void *pContext
-);
-
-
-/*
-** A pointer to a structure of the following type is passed as the first
-** argument to callbacks registered using rtree_geometry_callback().
-*/
-struct sqlite3_rtree_geometry {
- void *pContext; /* Copy of pContext passed to s_r_g_c() */
- int nParam; /* Size of array aParam[] */
- double *aParam; /* Parameters passed to SQL geom function */
- void *pUser; /* Callback implementation user data */
- void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */
-};
-
-
-#ifdef __cplusplus
-} /* end of the 'extern "C"' block */
-#endif
-
-#endif /* ifndef _SQLITE3RTREE_H_ */
-
diff --git a/security/nss/lib/ssl/Makefile b/security/nss/lib/ssl/Makefile
deleted file mode 100644
index d56cbf29e..000000000
--- a/security/nss/lib/ssl/Makefile
+++ /dev/null
@@ -1,63 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-CSRCS += win32err.c
-DEFINES += -DIN_LIBSSL
-else
-ifeq ($(OS_TARGET),OS2)
-CSRCS += os2_err.c
-else
-CSRCS += unix_err.c
-endif
-endif
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
-ifndef NSS_NO_PKCS11_BYPASS
-# indicates dependency on freebl static lib
-$(SHARED_LIBRARY): $(CRYPTOLIB)
-endif
diff --git a/security/nss/lib/ssl/SSLerrs.h b/security/nss/lib/ssl/SSLerrs.h
deleted file mode 100644
index 1fe57a00a..000000000
--- a/security/nss/lib/ssl/SSLerrs.h
+++ /dev/null
@@ -1,405 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* SSL-specific security error codes */
-/* caller must include "sslerr.h" */
-
-ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
-"Unable to communicate securely. Peer does not support high-grade encryption.")
-
-ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
-"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
-
-ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
-"Cannot communicate securely with peer: no common encryption algorithm(s).")
-
-ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
-"Unable to find the certificate or key necessary for authentication.")
-
-ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
-"Unable to communicate securely with peer: peers's certificate was rejected.")
-
-ER3(SSL_ERROR_UNUSED_5, SSL_ERROR_BASE + 5,
-"Unrecognized SSL error code.")
-
-ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
-"The server has encountered bad data from the client.")
-
-ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
-"The client has encountered bad data from the server.")
-
-ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
-"Unsupported certificate type.")
-
-ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
-"Peer using unsupported version of security protocol.")
-
-ER3(SSL_ERROR_UNUSED_10, SSL_ERROR_BASE + 10,
-"Unrecognized SSL error code.")
-
-ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
-"Client authentication failed: private key in key database does not match public key in certificate database.")
-
-ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
-"Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
-
-ER3(SSL_ERROR_POST_WARNING, SSL_ERROR_BASE + 13,
-"Unrecognized SSL error code.")
-
-ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
-"Peer only supports SSL version 2, which is locally disabled.")
-
-
-ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
-"SSL received a record with an incorrect Message Authentication Code.")
-
-ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
-"SSL peer reports incorrect Message Authentication Code.")
-
-ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
-"SSL peer cannot verify your certificate.")
-
-ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
-"SSL peer rejected your certificate as revoked.")
-
-ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
-"SSL peer rejected your certificate as expired.")
-
-ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
-"Cannot connect: SSL is disabled.")
-
-ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
-"Cannot connect: SSL peer is in another FORTEZZA domain.")
-
-ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
-"An unknown SSL cipher suite has been requested.")
-
-ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23),
-"No cipher suites are present and enabled in this program.")
-
-ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24),
-"SSL received a record with bad block padding.")
-
-ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25),
-"SSL received a record that exceeded the maximum permissible length.")
-
-ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26),
-"SSL attempted to send a record that exceeded the maximum permissible length.")
-
-/*
- * Received a malformed (too long or short or invalid content) SSL handshake.
- */
-ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27),
-"SSL received a malformed Hello Request handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28),
-"SSL received a malformed Client Hello handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29),
-"SSL received a malformed Server Hello handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30),
-"SSL received a malformed Certificate handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31),
-"SSL received a malformed Server Key Exchange handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32),
-"SSL received a malformed Certificate Request handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33),
-"SSL received a malformed Server Hello Done handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34),
-"SSL received a malformed Certificate Verify handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35),
-"SSL received a malformed Client Key Exchange handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36),
-"SSL received a malformed Finished handshake message.")
-
-/*
- * Received a malformed (too long or short) SSL record.
- */
-ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37),
-"SSL received a malformed Change Cipher Spec record.")
-
-ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38),
-"SSL received a malformed Alert record.")
-
-ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39),
-"SSL received a malformed Handshake record.")
-
-ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40),
-"SSL received a malformed Application Data record.")
-
-/*
- * Received an SSL handshake that was inappropriate for the state we're in.
- * E.g. Server received message from server, or wrong state in state machine.
- */
-ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41),
-"SSL received an unexpected Hello Request handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42),
-"SSL received an unexpected Client Hello handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43),
-"SSL received an unexpected Server Hello handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44),
-"SSL received an unexpected Certificate handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45),
-"SSL received an unexpected Server Key Exchange handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46),
-"SSL received an unexpected Certificate Request handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47),
-"SSL received an unexpected Server Hello Done handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
-"SSL received an unexpected Certificate Verify handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
-"SSL received an unexpected Client Key Exchange handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
-"SSL received an unexpected Finished handshake message.")
-
-/*
- * Received an SSL record that was inappropriate for the state we're in.
- */
-ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51),
-"SSL received an unexpected Change Cipher Spec record.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52),
-"SSL received an unexpected Alert record.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53),
-"SSL received an unexpected Handshake record.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54),
-"SSL received an unexpected Application Data record.")
-
-/*
- * Received record/message with unknown discriminant.
- */
-ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55),
-"SSL received a record with an unknown content type.")
-
-ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56),
-"SSL received a handshake message with an unknown message type.")
-
-ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57),
-"SSL received an alert record with an unknown alert description.")
-
-/*
- * Received an alert reporting what we did wrong. (more alerts above)
- */
-ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58),
-"SSL peer has closed this connection.")
-
-ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
-"SSL peer was not expecting a handshake message it received.")
-
-ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
-"SSL peer was unable to successfully decompress an SSL record it received.")
-
-ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
-"SSL peer was unable to negotiate an acceptable set of security parameters.")
-
-ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62),
-"SSL peer rejected a handshake message for unacceptable content.")
-
-ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63),
-"SSL peer does not support certificates of the type it received.")
-
-ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64),
-"SSL peer had some unspecified issue with the certificate it received.")
-
-
-ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65),
-"SSL experienced a failure of its random number generator.")
-
-ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66),
-"Unable to digitally sign data required to verify your certificate.")
-
-ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67),
-"SSL was unable to extract the public key from the peer's certificate.")
-
-ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68),
-"Unspecified failure while processing SSL Server Key Exchange handshake.")
-
-ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69),
-"Unspecified failure while processing SSL Client Key Exchange handshake.")
-
-ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70),
-"Bulk data encryption algorithm failed in selected cipher suite.")
-
-ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71),
-"Bulk data decryption algorithm failed in selected cipher suite.")
-
-ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72),
-"Attempt to write encrypted data to underlying socket failed.")
-
-ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73),
-"MD5 digest function failed.")
-
-ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74),
-"SHA-1 digest function failed.")
-
-ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75),
-"MAC computation failed.")
-
-ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76),
-"Failure to create Symmetric Key context.")
-
-ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77),
-"Failure to unwrap the Symmetric key in Client Key Exchange message.")
-
-ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78),
-"SSL Server attempted to use domestic-grade public key with export cipher suite.")
-
-ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79),
-"PKCS11 code failed to translate an IV into a param.")
-
-ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80),
-"Failed to initialize the selected cipher suite.")
-
-ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81),
-"Client failed to generate session keys for SSL session.")
-
-ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82),
-"Server has no key for the attempted key exchange algorithm.")
-
-ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83),
-"PKCS#11 token was inserted or removed while operation was in progress.")
-
-ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84),
-"No PKCS#11 token could be found to do a required operation.")
-
-ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85),
-"Cannot communicate securely with peer: no common compression algorithm(s).")
-
-ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86),
-"Cannot perform the operation until the handshake is complete.")
-
-ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87),
-"Received incorrect handshakes hash values from peer.")
-
-ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88),
-"The certificate provided cannot be used with the selected key exchange algorithm.")
-
-ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89),
-"No certificate authority is trusted for SSL client authentication.")
-
-ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90),
-"Client's SSL session ID not found in server's session cache.")
-
-ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91),
-"Peer was unable to decrypt an SSL record it received.")
-
-ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92),
-"Peer received an SSL record that was longer than is permitted.")
-
-ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93),
-"Peer does not recognize and trust the CA that issued your certificate.")
-
-ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94),
-"Peer received a valid certificate, but access was denied.")
-
-ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95),
-"Peer could not decode an SSL handshake message.")
-
-ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96),
-"Peer reports failure of signature verification or key exchange.")
-
-ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97),
-"Peer reports negotiation not in compliance with export regulations.")
-
-ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98),
-"Peer reports incompatible or unsupported protocol version.")
-
-ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99),
-"Server requires ciphers more secure than those supported by client.")
-
-ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100),
-"Peer reports it experienced an internal error.")
-
-ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101),
-"Peer user canceled handshake.")
-
-ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102),
-"Peer does not permit renegotiation of SSL security parameters.")
-
-ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103),
-"SSL server cache not configured and not disabled for this socket.")
-
-ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104),
-"SSL peer does not support requested TLS hello extension.")
-
-ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105),
-"SSL peer could not obtain your certificate from the supplied URL.")
-
-ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106),
-"SSL peer has no certificate for the requested DNS name.")
-
-ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107),
-"SSL peer was unable to get an OCSP response for its certificate.")
-
-ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108),
-"SSL peer reported bad certificate hash value.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 109),
-"SSL received an unexpected New Session Ticket handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 110),
-"SSL received a malformed New Session Ticket handshake message.")
-
-ER3(SSL_ERROR_DECOMPRESSION_FAILURE, (SSL_ERROR_BASE + 111),
-"SSL received a compressed record that could not be decompressed.")
-
-ER3(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, (SSL_ERROR_BASE + 112),
-"Renegotiation is not allowed on this SSL socket.")
-
-ER3(SSL_ERROR_UNSAFE_NEGOTIATION, (SSL_ERROR_BASE + 113),
-"Peer attempted old style (potentially vulnerable) handshake.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD, (SSL_ERROR_BASE + 114),
-"SSL received an unexpected uncompressed record.")
-
-ER3(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY, (SSL_ERROR_BASE + 115),
-"SSL received a weak ephemeral Diffie-Hellman key in Server Key Exchange handshake message.")
-
-ER3(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID, (SSL_ERROR_BASE + 116),
-"SSL received invalid NPN extension data.")
-
-ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2, (SSL_ERROR_BASE + 117),
-"SSL feature not supported for SSL 2.0 connections.")
-
-ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS, (SSL_ERROR_BASE + 118),
-"SSL feature not supported for servers.")
-
-ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS, (SSL_ERROR_BASE + 119),
-"SSL feature not supported for clients.")
-
-ER3(SSL_ERROR_INVALID_VERSION_RANGE, (SSL_ERROR_BASE + 120),
-"SSL version range is not valid.")
-
-ER3(SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION, (SSL_ERROR_BASE + 121),
-"SSL peer selected a cipher suite disallowed for the selected protocol version.")
-
-ER3(SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 122),
-"SSL received a malformed Hello Verify Request handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 123),
-"SSL received an unexpected Hello Verify Request handshake message.")
-
-ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION, (SSL_ERROR_BASE + 124),
-"SSL feature not supported for the protocol version.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS, (SSL_ERROR_BASE + 125),
-"SSL received an unexpected Certificate Status handshake message.")
diff --git a/security/nss/lib/ssl/authcert.c b/security/nss/lib/ssl/authcert.c
deleted file mode 100644
index b45f0a6ed..000000000
--- a/security/nss/lib/ssl/authcert.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * NSS utility functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <string.h>
-#include "prerror.h"
-#include "secitem.h"
-#include "prnetdb.h"
-#include "cert.h"
-#include "nspr.h"
-#include "secder.h"
-#include "key.h"
-#include "nss.h"
-#include "ssl.h"
-#include "pk11func.h" /* for PK11_ function calls */
-
-/*
- * This callback used by SSL to pull client sertificate upon
- * server request
- */
-SECStatus
-NSS_GetClientAuthData(void * arg,
- PRFileDesc * socket,
- struct CERTDistNamesStr * caNames,
- struct CERTCertificateStr ** pRetCert,
- struct SECKEYPrivateKeyStr **pRetKey)
-{
- CERTCertificate * cert = NULL;
- SECKEYPrivateKey * privkey = NULL;
- char * chosenNickName = (char *)arg; /* CONST */
- void * proto_win = NULL;
- SECStatus rv = SECFailure;
-
- proto_win = SSL_RevealPinArg(socket);
-
- if (chosenNickName) {
- cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
- chosenNickName, certUsageSSLClient,
- PR_FALSE, proto_win);
- if ( cert ) {
- privkey = PK11_FindKeyByAnyCert(cert, proto_win);
- if ( privkey ) {
- rv = SECSuccess;
- } else {
- CERT_DestroyCertificate(cert);
- }
- }
- } else { /* no name given, automatically find the right cert. */
- CERTCertNicknames * names;
- int i;
-
- names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
- SEC_CERT_NICKNAMES_USER, proto_win);
- if (names != NULL) {
- for (i = 0; i < names->numnicknames; i++) {
- cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
- names->nicknames[i], certUsageSSLClient,
- PR_FALSE, proto_win);
- if ( !cert )
- continue;
- /* Only check unexpired certs */
- if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) !=
- secCertTimeValid ) {
- CERT_DestroyCertificate(cert);
- continue;
- }
- rv = NSS_CmpCertChainWCANames(cert, caNames);
- if ( rv == SECSuccess ) {
- privkey = PK11_FindKeyByAnyCert(cert, proto_win);
- if ( privkey )
- break;
- }
- rv = SECFailure;
- CERT_DestroyCertificate(cert);
- }
- CERT_FreeNicknames(names);
- }
- }
- if (rv == SECSuccess) {
- *pRetCert = cert;
- *pRetKey = privkey;
- }
- return rv;
-}
-
diff --git a/security/nss/lib/ssl/cmpcert.c b/security/nss/lib/ssl/cmpcert.c
deleted file mode 100644
index b40500c95..000000000
--- a/security/nss/lib/ssl/cmpcert.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * NSS utility functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include <stdio.h>
-#include <string.h>
-#include "prerror.h"
-#include "secitem.h"
-#include "prnetdb.h"
-#include "cert.h"
-#include "nspr.h"
-#include "secder.h"
-#include "key.h"
-#include "nss.h"
-
-/*
- * Look to see if any of the signers in the cert chain for "cert" are found
- * in the list of caNames.
- * Returns SECSuccess if so, SECFailure if not.
- */
-SECStatus
-NSS_CmpCertChainWCANames(CERTCertificate *cert, CERTDistNames *caNames)
-{
- SECItem * caname;
- CERTCertificate * curcert;
- CERTCertificate * oldcert;
- PRInt32 contentlen;
- int j;
- int headerlen;
- int depth;
- SECStatus rv;
- SECItem issuerName;
- SECItem compatIssuerName;
-
- if (!cert || !caNames || !caNames->nnames || !caNames->names ||
- !caNames->names->data)
- return SECFailure;
- depth=0;
- curcert = CERT_DupCertificate(cert);
-
- while( curcert ) {
- issuerName = curcert->derIssuer;
-
- /* compute an alternate issuer name for compatibility with 2.0
- * enterprise server, which send the CA names without
- * the outer layer of DER header
- */
- rv = DER_Lengths(&issuerName, &headerlen, (PRUint32 *)&contentlen);
- if ( rv == SECSuccess ) {
- compatIssuerName.data = &issuerName.data[headerlen];
- compatIssuerName.len = issuerName.len - headerlen;
- } else {
- compatIssuerName.data = NULL;
- compatIssuerName.len = 0;
- }
-
- for (j = 0; j < caNames->nnames; j++) {
- caname = &caNames->names[j];
- if (SECITEM_CompareItem(&issuerName, caname) == SECEqual) {
- rv = SECSuccess;
- CERT_DestroyCertificate(curcert);
- goto done;
- } else if (SECITEM_CompareItem(&compatIssuerName, caname) == SECEqual) {
- rv = SECSuccess;
- CERT_DestroyCertificate(curcert);
- goto done;
- }
- }
- if ( ( depth <= 20 ) &&
- ( SECITEM_CompareItem(&curcert->derIssuer, &curcert->derSubject)
- != SECEqual ) ) {
- oldcert = curcert;
- curcert = CERT_FindCertByName(curcert->dbhandle,
- &curcert->derIssuer);
- CERT_DestroyCertificate(oldcert);
- depth++;
- } else {
- CERT_DestroyCertificate(curcert);
- curcert = NULL;
- }
- }
- rv = SECFailure;
-
-done:
- return rv;
-}
-
diff --git a/security/nss/lib/ssl/config.mk b/security/nss/lib/ssl/config.mk
deleted file mode 100644
index 1a717fa90..000000000
--- a/security/nss/lib/ssl/config.mk
+++ /dev/null
@@ -1,92 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-ifdef NISCC_TEST
-DEFINES += -DNISCC_TEST
-endif
-
-ifdef NSS_SURVIVE_DOUBLE_BYPASS_FAILURE
-DEFINES += -DNSS_SURVIVE_DOUBLE_BYPASS_FAILURE
-endif
-
-ifdef NSS_NO_PKCS11_BYPASS
-DEFINES += -DNO_PKCS11_BYPASS
-else
-CRYPTOLIB=$(SOFTOKEN_LIB_DIR)/$(LIB_PREFIX)freebl.$(LIB_SUFFIX)
-
-EXTRA_LIBS += \
- $(CRYPTOLIB) \
- $(NULL)
-endif
-
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
-
-RES = $(OBJDIR)/ssl.res
-RESNAME = ssl.rc
-
-ifdef NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -lnss3 \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-else # ! NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- $(DIST)/lib/nss3.lib \
- $(DIST)/lib/nssutil3.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-
-else
-
-# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -lnss3 \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-
-ifeq ($(OS_ARCH), BeOS)
-EXTRA_SHARED_LIBS += -lbe
-endif
-
-endif
-
-# Mozilla's mozilla/modules/zlib/src/zconf.h adds the MOZ_Z_ prefix to zlib
-# exported symbols, which causes problem when NSS is built as part of Mozilla.
-# So we add a NSS_ENABLE_ZLIB variable to allow Mozilla to turn this off.
-NSS_ENABLE_ZLIB = 1
-ifdef NSS_ENABLE_ZLIB
-
-DEFINES += -DNSS_ENABLE_ZLIB
-
-# If a platform has a system zlib, set USE_SYSTEM_ZLIB to 1 and
-# ZLIB_LIBS to the linker command-line arguments for the system zlib
-# (for example, -lz) in the platform's config file in coreconf.
-ifdef USE_SYSTEM_ZLIB
-OS_LIBS += $(ZLIB_LIBS)
-else
-ZLIB_LIBS = $(DIST)/lib/$(LIB_PREFIX)zlib.$(LIB_SUFFIX)
-EXTRA_LIBS += $(ZLIB_LIBS)
-endif
-
-endif
diff --git a/security/nss/lib/ssl/derive.c b/security/nss/lib/ssl/derive.c
deleted file mode 100644
index fb21350c0..000000000
--- a/security/nss/lib/ssl/derive.c
+++ /dev/null
@@ -1,865 +0,0 @@
-/*
- * Key Derivation that doesn't use PKCS11
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "ssl.h" /* prereq to sslimpl.h */
-#include "certt.h" /* prereq to sslimpl.h */
-#include "keythi.h" /* prereq to sslimpl.h */
-#include "sslimpl.h"
-#ifndef NO_PKCS11_BYPASS
-#include "blapi.h"
-#endif
-
-#include "keyhi.h"
-#include "pk11func.h"
-#include "secasn1.h"
-#include "cert.h"
-#include "secmodt.h"
-
-#include "sslproto.h"
-#include "sslerr.h"
-
-#ifndef NO_PKCS11_BYPASS
-/* make this a macro! */
-#ifdef NOT_A_MACRO
-static void
-buildSSLKey(unsigned char * keyBlock, unsigned int keyLen, SECItem * result,
- const char * label)
-{
- result->type = siBuffer;
- result->data = keyBlock;
- result->len = keyLen;
- PRINT_BUF(100, (NULL, label, keyBlock, keyLen));
-}
-#else
-#define buildSSLKey(keyBlock, keyLen, result, label) \
-{ \
- (result)->type = siBuffer; \
- (result)->data = keyBlock; \
- (result)->len = keyLen; \
- PRINT_BUF(100, (NULL, label, keyBlock, keyLen)); \
-}
-#endif
-
-/*
- * SSL Key generation given pre master secret
- */
-#ifndef NUM_MIXERS
-#define NUM_MIXERS 9
-#endif
-static const char * const mixers[NUM_MIXERS] = {
- "A",
- "BB",
- "CCC",
- "DDDD",
- "EEEEE",
- "FFFFFF",
- "GGGGGGG",
- "HHHHHHHH",
- "IIIIIIIII"
-};
-
-
-SECStatus
-ssl3_KeyAndMacDeriveBypass(
- ssl3CipherSpec * pwSpec,
- const unsigned char * cr,
- const unsigned char * sr,
- PRBool isTLS,
- PRBool isExport)
-{
- const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
- unsigned char * key_block = pwSpec->key_block;
- unsigned char * key_block2 = NULL;
- unsigned int block_bytes = 0;
- unsigned int block_needed = 0;
- unsigned int i;
- unsigned int keySize; /* actual size of cipher keys */
- unsigned int effKeySize; /* effective size of cipher keys */
- unsigned int macSize; /* size of MAC secret */
- unsigned int IVSize; /* size of IV */
- SECStatus rv = SECFailure;
- SECStatus status = SECSuccess;
- PRBool isFIPS = PR_FALSE;
-
- SECItem srcr;
- SECItem crsr;
-
- unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2];
- unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
- PRUint64 md5buf[22];
- PRUint64 shabuf[40];
-
-#define md5Ctx ((MD5Context *)md5buf)
-#define shaCtx ((SHA1Context *)shabuf)
-
- static const SECItem zed = { siBuffer, NULL, 0 };
-
- if (pwSpec->msItem.data == NULL ||
- pwSpec->msItem.len != SSL3_MASTER_SECRET_LENGTH) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return rv;
- }
-
- PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data,
- pwSpec->msItem.len));
-
- /* figure out how much is needed */
- macSize = pwSpec->mac_size;
- keySize = cipher_def->key_size;
- effKeySize = cipher_def->secret_key_size;
- IVSize = cipher_def->iv_size;
- if (keySize == 0) {
- effKeySize = IVSize = 0; /* only MACing */
- }
- block_needed = 2 * (macSize + effKeySize + ((!isExport) * IVSize));
-
- /*
- * clear out our returned keys so we can recover on failure
- */
- pwSpec->client.write_key_item = zed;
- pwSpec->client.write_mac_key_item = zed;
- pwSpec->server.write_key_item = zed;
- pwSpec->server.write_mac_key_item = zed;
-
- /* initialize the server random, client random block */
- srcr.type = siBuffer;
- srcr.data = srcrdata;
- srcr.len = sizeof srcrdata;
- PORT_Memcpy(srcrdata, sr, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, cr, SSL3_RANDOM_LENGTH);
-
- /* initialize the client random, server random block */
- crsr.type = siBuffer;
- crsr.data = crsrdata;
- crsr.len = sizeof crsrdata;
- PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH);
- PRINT_BUF(100, (NULL, "Key & MAC CRSR", crsr.data, crsr.len));
-
- /*
- * generate the key material:
- */
- if (isTLS) {
- SECItem keyblk;
-
- keyblk.type = siBuffer;
- keyblk.data = key_block;
- keyblk.len = block_needed;
-
- status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk,
- isFIPS);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- block_bytes = keyblk.len;
- } else {
- /* key_block =
- * MD5(master_secret + SHA('A' + master_secret +
- * ServerHello.random + ClientHello.random)) +
- * MD5(master_secret + SHA('BB' + master_secret +
- * ServerHello.random + ClientHello.random)) +
- * MD5(master_secret + SHA('CCC' + master_secret +
- * ServerHello.random + ClientHello.random)) +
- * [...];
- */
- unsigned int made = 0;
- for (i = 0; made < block_needed && i < NUM_MIXERS; ++i) {
- unsigned int outLen;
- unsigned char sha_out[SHA1_LENGTH];
-
- SHA1_Begin(shaCtx);
- SHA1_Update(shaCtx, (unsigned char*)(mixers[i]), i+1);
- SHA1_Update(shaCtx, pwSpec->msItem.data, pwSpec->msItem.len);
- SHA1_Update(shaCtx, srcr.data, srcr.len);
- SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH);
- PORT_Assert(outLen == SHA1_LENGTH);
-
- MD5_Begin(md5Ctx);
- MD5_Update(md5Ctx, pwSpec->msItem.data, pwSpec->msItem.len);
- MD5_Update(md5Ctx, sha_out, outLen);
- MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH);
- PORT_Assert(outLen == MD5_LENGTH);
- made += MD5_LENGTH;
- }
- block_bytes = made;
- }
- PORT_Assert(block_bytes >= block_needed);
- PORT_Assert(block_bytes <= sizeof pwSpec->key_block);
- PRINT_BUF(100, (NULL, "key block", key_block, block_bytes));
-
- /*
- * Put the key material where it goes.
- */
- key_block2 = key_block + block_bytes;
- i = 0; /* now shows how much consumed */
-
- /*
- * The key_block is partitioned as follows:
- * client_write_MAC_secret[CipherSpec.hash_size]
- */
- buildSSLKey(&key_block[i],macSize, &pwSpec->client.write_mac_key_item, \
- "Client Write MAC Secret");
- i += macSize;
-
- /*
- * server_write_MAC_secret[CipherSpec.hash_size]
- */
- buildSSLKey(&key_block[i],macSize, &pwSpec->server.write_mac_key_item, \
- "Server Write MAC Secret");
- i += macSize;
-
- if (!keySize) {
- /* only MACing */
- buildSSLKey(NULL, 0, &pwSpec->client.write_key_item, \
- "Client Write Key (MAC only)");
- buildSSLKey(NULL, 0, &pwSpec->server.write_key_item, \
- "Server Write Key (MAC only)");
- buildSSLKey(NULL, 0, &pwSpec->client.write_iv_item, \
- "Client Write IV (MAC only)");
- buildSSLKey(NULL, 0, &pwSpec->server.write_iv_item, \
- "Server Write IV (MAC only)");
- } else if (!isExport) {
- /*
- ** Generate Domestic write keys and IVs.
- ** client_write_key[CipherSpec.key_material]
- */
- buildSSLKey(&key_block[i], keySize, &pwSpec->client.write_key_item, \
- "Domestic Client Write Key");
- i += keySize;
-
- /*
- ** server_write_key[CipherSpec.key_material]
- */
- buildSSLKey(&key_block[i], keySize, &pwSpec->server.write_key_item, \
- "Domestic Server Write Key");
- i += keySize;
-
- if (IVSize > 0) {
- /*
- ** client_write_IV[CipherSpec.IV_size]
- */
- buildSSLKey(&key_block[i], IVSize, &pwSpec->client.write_iv_item, \
- "Domestic Client Write IV");
- i += IVSize;
-
- /*
- ** server_write_IV[CipherSpec.IV_size]
- */
- buildSSLKey(&key_block[i], IVSize, &pwSpec->server.write_iv_item, \
- "Domestic Server Write IV");
- i += IVSize;
- }
- PORT_Assert(i <= block_bytes);
-
- } else if (!isTLS) {
- /*
- ** Generate SSL3 Export write keys and IVs.
- */
- unsigned int outLen;
-
- /*
- ** client_write_key[CipherSpec.key_material]
- ** final_client_write_key = MD5(client_write_key +
- ** ClientHello.random + ServerHello.random);
- */
- MD5_Begin(md5Ctx);
- MD5_Update(md5Ctx, &key_block[i], effKeySize);
- MD5_Update(md5Ctx, crsr.data, crsr.len);
- MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
- i += effKeySize;
- buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, \
- "SSL3 Export Client Write Key");
- key_block2 += keySize;
-
- /*
- ** server_write_key[CipherSpec.key_material]
- ** final_server_write_key = MD5(server_write_key +
- ** ServerHello.random + ClientHello.random);
- */
- MD5_Begin(md5Ctx);
- MD5_Update(md5Ctx, &key_block[i], effKeySize);
- MD5_Update(md5Ctx, srcr.data, srcr.len);
- MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
- i += effKeySize;
- buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, \
- "SSL3 Export Server Write Key");
- key_block2 += keySize;
- PORT_Assert(i <= block_bytes);
-
- if (IVSize) {
- /*
- ** client_write_IV =
- ** MD5(ClientHello.random + ServerHello.random);
- */
- MD5_Begin(md5Ctx);
- MD5_Update(md5Ctx, crsr.data, crsr.len);
- MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
- buildSSLKey(key_block2, IVSize, &pwSpec->client.write_iv_item, \
- "SSL3 Export Client Write IV");
- key_block2 += IVSize;
-
- /*
- ** server_write_IV =
- ** MD5(ServerHello.random + ClientHello.random);
- */
- MD5_Begin(md5Ctx);
- MD5_Update(md5Ctx, srcr.data, srcr.len);
- MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
- buildSSLKey(key_block2, IVSize, &pwSpec->server.write_iv_item, \
- "SSL3 Export Server Write IV");
- key_block2 += IVSize;
- }
-
- PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block);
- } else {
- /*
- ** Generate TLS Export write keys and IVs.
- */
- SECItem secret ;
- SECItem keyblk ;
-
- secret.type = siBuffer;
- keyblk.type = siBuffer;
- /*
- ** client_write_key[CipherSpec.key_material]
- ** final_client_write_key = PRF(client_write_key,
- ** "client write key",
- ** client_random + server_random);
- */
- secret.data = &key_block[i];
- secret.len = effKeySize;
- i += effKeySize;
- keyblk.data = key_block2;
- keyblk.len = keySize;
- status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, isFIPS);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, \
- "TLS Export Client Write Key");
- key_block2 += keySize;
-
- /*
- ** server_write_key[CipherSpec.key_material]
- ** final_server_write_key = PRF(server_write_key,
- ** "server write key",
- ** client_random + server_random);
- */
- secret.data = &key_block[i];
- secret.len = effKeySize;
- i += effKeySize;
- keyblk.data = key_block2;
- keyblk.len = keySize;
- status = TLS_PRF(&secret, "server write key", &crsr, &keyblk, isFIPS);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, \
- "TLS Export Server Write Key");
- key_block2 += keySize;
-
- /*
- ** iv_block = PRF("", "IV block", client_random + server_random);
- ** client_write_IV[SecurityParameters.IV_size]
- ** server_write_IV[SecurityParameters.IV_size]
- */
- if (IVSize) {
- secret.data = NULL;
- secret.len = 0;
- keyblk.data = key_block2;
- keyblk.len = 2 * IVSize;
- status = TLS_PRF(&secret, "IV block", &crsr, &keyblk, isFIPS);
- if (status != SECSuccess) {
- goto key_and_mac_derive_fail;
- }
- buildSSLKey(key_block2, IVSize, \
- &pwSpec->client.write_iv_item, \
- "TLS Export Client Write IV");
- buildSSLKey(key_block2 + IVSize, IVSize, \
- &pwSpec->server.write_iv_item, \
- "TLS Export Server Write IV");
- key_block2 += 2 * IVSize;
- }
- PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block);
- }
- rv = SECSuccess;
-
-key_and_mac_derive_fail:
-
- MD5_DestroyContext(md5Ctx, PR_FALSE);
- SHA1_DestroyContext(shaCtx, PR_FALSE);
-
- if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- }
-
- return rv;
-}
-
-
-/* derive the Master Secret from the PMS */
-/* Presently, this is only done wtih RSA PMS, and only on the server side,
- * so isRSA is always true.
- */
-SECStatus
-ssl3_MasterKeyDeriveBypass(
- ssl3CipherSpec * pwSpec,
- const unsigned char * cr,
- const unsigned char * sr,
- const SECItem * pms,
- PRBool isTLS,
- PRBool isRSA)
-{
- unsigned char * key_block = pwSpec->key_block;
- SECStatus rv = SECSuccess;
- PRBool isFIPS = PR_FALSE;
-
- SECItem crsr;
-
- unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2];
- PRUint64 md5buf[22];
- PRUint64 shabuf[40];
-
-#define md5Ctx ((MD5Context *)md5buf)
-#define shaCtx ((SHA1Context *)shabuf)
-
- /* first do the consistancy checks */
- if (isRSA) {
- PORT_Assert(pms->len == SSL3_RSA_PMS_LENGTH);
- if (pms->len != SSL3_RSA_PMS_LENGTH) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- /* caller must test PMS version for rollback */
- }
-
- /* initialize the client random, server random block */
- crsr.type = siBuffer;
- crsr.data = crsrdata;
- crsr.len = sizeof crsrdata;
- PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH);
- PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len));
-
- /* finally do the key gen */
- if (isTLS) {
- SECItem master = { siBuffer, NULL, 0 };
-
- master.data = key_block;
- master.len = SSL3_MASTER_SECRET_LENGTH;
-
- rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS);
- if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- }
- } else {
- int i;
- unsigned int made = 0;
- for (i = 0; i < 3; i++) {
- unsigned int outLen;
- unsigned char sha_out[SHA1_LENGTH];
-
- SHA1_Begin(shaCtx);
- SHA1_Update(shaCtx, (unsigned char*) mixers[i], i+1);
- SHA1_Update(shaCtx, pms->data, pms->len);
- SHA1_Update(shaCtx, crsr.data, crsr.len);
- SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH);
- PORT_Assert(outLen == SHA1_LENGTH);
-
- MD5_Begin(md5Ctx);
- MD5_Update(md5Ctx, pms->data, pms->len);
- MD5_Update(md5Ctx, sha_out, outLen);
- MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH);
- PORT_Assert(outLen == MD5_LENGTH);
- made += outLen;
- }
- }
-
- /* store the results */
- PORT_Memcpy(pwSpec->raw_master_secret, key_block,
- SSL3_MASTER_SECRET_LENGTH);
- pwSpec->msItem.data = pwSpec->raw_master_secret;
- pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
- PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data,
- pwSpec->msItem.len));
-
- return rv;
-}
-
-static SECStatus
-ssl_canExtractMS(PK11SymKey *pms, PRBool isTLS, PRBool isDH, PRBool *pcbp)
-{ SECStatus rv;
- PK11SymKey * ms = NULL;
- SECItem params = {siBuffer, NULL, 0};
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
- unsigned char rand[SSL3_RANDOM_LENGTH];
- CK_VERSION pms_version;
- CK_MECHANISM_TYPE master_derive;
- CK_MECHANISM_TYPE key_derive;
- CK_FLAGS keyFlags;
-
- if (pms == NULL)
- return(SECFailure);
-
- PORT_Memset(rand, 0, SSL3_RANDOM_LENGTH);
-
- if (isTLS) {
- if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH;
- else master_derive = CKM_TLS_MASTER_KEY_DERIVE;
- key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
- keyFlags = CKF_SIGN | CKF_VERIFY;
- } else {
- if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH;
- else master_derive = CKM_SSL3_MASTER_KEY_DERIVE;
- key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE;
- keyFlags = 0;
- }
-
- master_params.pVersion = &pms_version;
- master_params.RandomInfo.pClientRandom = rand;
- master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
- master_params.RandomInfo.pServerRandom = rand;
- master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
-
- params.data = (unsigned char *) &master_params;
- params.len = sizeof master_params;
-
- ms = PK11_DeriveWithFlags(pms, master_derive, &params, key_derive,
- CKA_DERIVE, 0, keyFlags);
- if (ms == NULL)
- return(SECFailure);
-
- rv = PK11_ExtractKeyValue(ms);
- *pcbp = (rv == SECSuccess);
- PK11_FreeSymKey(ms);
-
- return(rv);
-
-}
-#endif /* !NO_PKCS11_BYPASS */
-
-/* Check the key exchange algorithm for each cipher in the list to see if
- * a master secret key can be extracted. If the KEA will use keys from the
- * specified cert make sure the extract operation is attempted from the slot
- * where the private key resides.
- * If MS can be extracted for all ciphers, (*pcanbypass) is set to TRUE and
- * SECSuccess is returned. In all other cases but one (*pcanbypass) is
- * set to FALSE and SECFailure is returned.
- * In that last case Derive() has been called successfully but the MS is null,
- * CanBypass sets (*pcanbypass) to FALSE and returns SECSuccess indicating the
- * arguments were all valid but the slot cannot be bypassed.
- */
-
-/* XXX Add SSL_CBP_TLS1_1 and test it in protocolmask when setting isTLS. */
-
-SECStatus
-SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey,
- PRUint32 protocolmask, PRUint16 *ciphersuites, int nsuites,
- PRBool *pcanbypass, void *pwArg)
-{
-#ifdef NO_PKCS11_BYPASS
- if (!pcanbypass) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- *pcanbypass = PR_FALSE;
- return SECSuccess;
-#else
- SECStatus rv;
- int i;
- PRUint16 suite;
- PK11SymKey * pms = NULL;
- SECKEYPublicKey * srvPubkey = NULL;
- KeyType privKeytype;
- PK11SlotInfo * slot = NULL;
- SECItem param;
- CK_VERSION version;
- CK_MECHANISM_TYPE mechanism_array[2];
- SECItem enc_pms = {siBuffer, NULL, 0};
- PRBool isTLS = PR_FALSE;
- SSLCipherSuiteInfo csdef;
- PRBool testrsa = PR_FALSE;
- PRBool testrsa_export = PR_FALSE;
- PRBool testecdh = PR_FALSE;
- PRBool testecdhe = PR_FALSE;
-#ifdef NSS_ENABLE_ECC
- SECKEYECParams ecParams = { siBuffer, NULL, 0 };
-#endif
-
- if (!cert || !srvPrivkey || !ciphersuites || !pcanbypass) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- srvPubkey = CERT_ExtractPublicKey(cert);
- if (!srvPubkey)
- return SECFailure;
-
- *pcanbypass = PR_TRUE;
- rv = SECFailure;
-
- /* determine which KEAs to test */
- /* 0 (SSL_NULL_WITH_NULL_NULL) is used as a list terminator because
- * SSL3 and TLS specs forbid negotiating that cipher suite number.
- */
- for (i=0; i < nsuites && (suite = *ciphersuites++) != 0; i++) {
- /* skip SSL2 cipher suites and ones NSS doesn't support */
- if (SSL_GetCipherSuiteInfo(suite, &csdef, sizeof(csdef)) != SECSuccess
- || SSL_IS_SSL2_CIPHER(suite) )
- continue;
- switch (csdef.keaType) {
- case ssl_kea_rsa:
- switch (csdef.cipherSuite) {
- case TLS_RSA_EXPORT1024_WITH_RC4_56_SHA:
- case TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA:
- case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
- case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
- testrsa_export = PR_TRUE;
- }
- if (!testrsa_export)
- testrsa = PR_TRUE;
- break;
- case ssl_kea_ecdh:
- if (strcmp(csdef.keaTypeName, "ECDHE") == 0) /* ephemeral? */
- testecdhe = PR_TRUE;
- else
- testecdh = PR_TRUE;
- break;
- case ssl_kea_dh:
- /* this is actually DHE */
- default:
- continue;
- }
- }
-
- /* For each protocol try to derive and extract an MS.
- * Failure of function any function except MS extract means
- * continue with the next cipher test. Stop testing when the list is
- * exhausted or when the first MS extract--not derive--fails.
- */
- privKeytype = SECKEY_GetPrivateKeyType(srvPrivkey);
- protocolmask &= SSL_CBP_SSL3|SSL_CBP_TLS1_0;
- while (protocolmask) {
- if (protocolmask & SSL_CBP_SSL3) {
- isTLS = PR_FALSE;
- protocolmask ^= SSL_CBP_SSL3;
- } else {
- isTLS = PR_TRUE;
- protocolmask ^= SSL_CBP_TLS1_0;
- }
-
- if (privKeytype == rsaKey && testrsa_export) {
- if (PK11_GetPrivateModulusLen(srvPrivkey) > EXPORT_RSA_KEY_LENGTH) {
- *pcanbypass = PR_FALSE;
- rv = SECSuccess;
- break;
- } else
- testrsa = PR_TRUE;
- }
- for (; privKeytype == rsaKey && testrsa; ) {
- /* TLS_RSA */
- unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
- unsigned int outLen = 0;
- CK_MECHANISM_TYPE target;
- SECStatus irv;
-
- mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN;
- mechanism_array[1] = CKM_RSA_PKCS;
-
- slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg);
- if (slot == NULL) {
- PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND);
- break;
- }
-
- /* Generate the pre-master secret ... (client side) */
- version.major = 3 /*MSB(clientHelloVersion)*/;
- version.minor = 0 /*LSB(clientHelloVersion)*/;
- param.data = (unsigned char *)&version;
- param.len = sizeof version;
- pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, &param, 0, pwArg);
- PK11_FreeSlot(slot);
- if (!pms)
- break;
- /* now wrap it */
- enc_pms.len = SECKEY_PublicKeyStrength(srvPubkey);
- enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len);
- if (enc_pms.data == NULL) {
- PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
- break;
- }
- irv = PK11_PubWrapSymKey(CKM_RSA_PKCS, srvPubkey, pms, &enc_pms);
- if (irv != SECSuccess)
- break;
- PK11_FreeSymKey(pms);
- pms = NULL;
- /* now do the server side--check the triple bypass first */
- rv = PK11_PrivDecryptPKCS1(srvPrivkey, rsaPmsBuf, &outLen,
- sizeof rsaPmsBuf,
- (unsigned char *)enc_pms.data,
- enc_pms.len);
- /* if decrypt worked we're done with the RSA test */
- if (rv == SECSuccess) {
- *pcanbypass = PR_TRUE;
- break;
- }
- /* check for fallback to double bypass */
- target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE
- : CKM_SSL3_MASTER_KEY_DERIVE;
- pms = PK11_PubUnwrapSymKey(srvPrivkey, &enc_pms,
- target, CKA_DERIVE, 0);
- rv = ssl_canExtractMS(pms, isTLS, PR_FALSE, pcanbypass);
- if (rv == SECSuccess && *pcanbypass == PR_FALSE)
- goto done;
- break;
- }
-
- /* Check for NULL to avoid double free.
- * SECItem_FreeItem sets data NULL in secitem.c#265
- */
- if (enc_pms.data != NULL) {
- SECITEM_FreeItem(&enc_pms, PR_FALSE);
- }
-#ifdef NSS_ENABLE_ECC
- for (; (privKeytype == ecKey && ( testecdh || testecdhe)) ||
- (privKeytype == rsaKey && testecdhe); ) {
- CK_MECHANISM_TYPE target;
- SECKEYPublicKey *keapub = NULL;
- SECKEYPrivateKey *keapriv;
- SECKEYPublicKey *cpub = NULL; /* client's ephemeral ECDH keys */
- SECKEYPrivateKey *cpriv = NULL;
- SECKEYECParams *pecParams = NULL;
-
- if (privKeytype == ecKey && testecdhe) {
- /* TLS_ECDHE_ECDSA */
- pecParams = &srvPubkey->u.ec.DEREncodedParams;
- } else if (privKeytype == rsaKey && testecdhe) {
- /* TLS_ECDHE_RSA */
- ECName ec_curve;
- int serverKeyStrengthInBits;
- int signatureKeyStrength;
- int requiredECCbits;
-
- /* find a curve of equivalent strength to the RSA key's */
- requiredECCbits = PK11_GetPrivateModulusLen(srvPrivkey);
- if (requiredECCbits < 0)
- break;
- requiredECCbits *= BPB;
- serverKeyStrengthInBits = srvPubkey->u.rsa.modulus.len;
- if (srvPubkey->u.rsa.modulus.data[0] == 0) {
- serverKeyStrengthInBits--;
- }
- /* convert to strength in bits */
- serverKeyStrengthInBits *= BPB;
-
- signatureKeyStrength =
- SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits);
-
- if ( requiredECCbits > signatureKeyStrength )
- requiredECCbits = signatureKeyStrength;
-
- ec_curve =
- ssl3_GetCurveWithECKeyStrength(SSL3_SUPPORTED_CURVES_MASK,
- requiredECCbits);
- rv = ssl3_ECName2Params(NULL, ec_curve, &ecParams);
- if (rv == SECFailure) {
- break;
- }
- pecParams = &ecParams;
- }
-
- if (testecdhe) {
- /* generate server's ephemeral keys */
- keapriv = SECKEY_CreateECPrivateKey(pecParams, &keapub, NULL);
- if (!keapriv || !keapub) {
- if (keapriv)
- SECKEY_DestroyPrivateKey(keapriv);
- if (keapub)
- SECKEY_DestroyPublicKey(keapub);
- PORT_SetError(SEC_ERROR_KEYGEN_FAIL);
- rv = SECFailure;
- break;
- }
- } else {
- /* TLS_ECDH_ECDSA */
- keapub = srvPubkey;
- keapriv = srvPrivkey;
- pecParams = &srvPubkey->u.ec.DEREncodedParams;
- }
-
- /* perform client side ops */
- /* generate a pair of ephemeral keys using server's parms */
- cpriv = SECKEY_CreateECPrivateKey(pecParams, &cpub, NULL);
- if (!cpriv || !cpub) {
- if (testecdhe) {
- SECKEY_DestroyPrivateKey(keapriv);
- SECKEY_DestroyPublicKey(keapub);
- }
- PORT_SetError(SEC_ERROR_KEYGEN_FAIL);
- rv = SECFailure;
- break;
- }
- /* now do the server side */
- /* determine the PMS using client's public value */
- target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE_DH
- : CKM_SSL3_MASTER_KEY_DERIVE_DH;
- pms = PK11_PubDeriveWithKDF(keapriv, cpub, PR_FALSE, NULL, NULL,
- CKM_ECDH1_DERIVE,
- target,
- CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
- rv = ssl_canExtractMS(pms, isTLS, PR_TRUE, pcanbypass);
- SECKEY_DestroyPrivateKey(cpriv);
- SECKEY_DestroyPublicKey(cpub);
- if (testecdhe) {
- SECKEY_DestroyPrivateKey(keapriv);
- SECKEY_DestroyPublicKey(keapub);
- }
- if (rv == SECSuccess && *pcanbypass == PR_FALSE)
- goto done;
- break;
- }
- /* Check for NULL to avoid double free. */
- if (ecParams.data != NULL) {
- PORT_Free(ecParams.data);
- ecParams.data = NULL;
- }
-#endif /* NSS_ENABLE_ECC */
- if (pms)
- PK11_FreeSymKey(pms);
- }
-
- /* *pcanbypass has been set */
- rv = SECSuccess;
-
- done:
- if (pms)
- PK11_FreeSymKey(pms);
-
- /* Check for NULL to avoid double free.
- * SECItem_FreeItem sets data NULL in secitem.c#265
- */
- if (enc_pms.data != NULL) {
- SECITEM_FreeItem(&enc_pms, PR_FALSE);
- }
-#ifdef NSS_ENABLE_ECC
- if (ecParams.data != NULL) {
- PORT_Free(ecParams.data);
- ecParams.data = NULL;
- }
-#endif /* NSS_ENABLE_ECC */
-
- if (srvPubkey) {
- SECKEY_DestroyPublicKey(srvPubkey);
- srvPubkey = NULL;
- }
-
-
- return rv;
-#endif /* NO_PKCS11_BYPASS */
-}
-
diff --git a/security/nss/lib/ssl/dtlscon.c b/security/nss/lib/ssl/dtlscon.c
deleted file mode 100644
index e3468717c..000000000
--- a/security/nss/lib/ssl/dtlscon.c
+++ /dev/null
@@ -1,1133 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * DTLS Protocol
- */
-/* $Id$ */
-
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-
-#ifndef PR_ARRAY_SIZE
-#define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
-#endif
-
-static SECStatus dtls_TransmitMessageFlight(sslSocket *ss);
-static void dtls_RetransmitTimerExpiredCb(sslSocket *ss);
-static SECStatus dtls_SendSavedWriteData(sslSocket *ss);
-
-/* -28 adjusts for the IP/UDP header */
-static const PRUint16 COMMON_MTU_VALUES[] = {
- 1500 - 28, /* Ethernet MTU */
- 1280 - 28, /* IPv6 minimum MTU */
- 576 - 28, /* Common assumption */
- 256 - 28 /* We're in serious trouble now */
-};
-
-#define DTLS_COOKIE_BYTES 32
-
-/* List copied from ssl3con.c:cipherSuites */
-static const ssl3CipherSuite nonDTLSSuites[] = {
-#ifdef NSS_ENABLE_ECC
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDHE_RSA_WITH_RC4_128_SHA,
-#endif /* NSS_ENABLE_ECC */
- TLS_DHE_DSS_WITH_RC4_128_SHA,
-#ifdef NSS_ENABLE_ECC
- TLS_ECDH_RSA_WITH_RC4_128_SHA,
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
-#endif /* NSS_ENABLE_ECC */
- SSL_RSA_WITH_RC4_128_MD5,
- SSL_RSA_WITH_RC4_128_SHA,
- TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
- SSL_RSA_EXPORT_WITH_RC4_40_MD5,
- 0 /* End of list marker */
-};
-
-/* Map back and forth between TLS and DTLS versions in wire format.
- * Mapping table is:
- *
- * TLS DTLS
- * 1.1 (0302) 1.0 (feff)
- */
-SSL3ProtocolVersion
-dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv)
-{
- /* Anything other than TLS 1.1 is an error, so return
- * the invalid version ffff. */
- if (tlsv != SSL_LIBRARY_VERSION_TLS_1_1)
- return 0xffff;
-
- return SSL_LIBRARY_VERSION_DTLS_1_0_WIRE;
-}
-
-/* Map known DTLS versions to known TLS versions.
- * - Invalid versions (< 1.0) return a version of 0
- * - Versions > known return a version one higher than we know of
- * to accomodate a theoretically newer version */
-SSL3ProtocolVersion
-dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv)
-{
- if (MSB(dtlsv) == 0xff) {
- return 0;
- }
-
- if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_0_WIRE)
- return SSL_LIBRARY_VERSION_TLS_1_1;
-
- /* Return a fictional higher version than we know of */
- return SSL_LIBRARY_VERSION_TLS_1_1 + 1;
-}
-
-/* On this socket, Disable non-DTLS cipher suites in the argument's list */
-SECStatus
-ssl3_DisableNonDTLSSuites(sslSocket * ss)
-{
- const ssl3CipherSuite * suite;
-
- for (suite = nonDTLSSuites; *suite; ++suite) {
- SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
-
- PORT_Assert(rv == SECSuccess); /* else is coding error */
- }
- return SECSuccess;
-}
-
-/* Allocate a DTLSQueuedMessage.
- *
- * Called from dtls_QueueMessage()
- */
-static DTLSQueuedMessage *
-dtls_AllocQueuedMessage(PRUint16 epoch, SSL3ContentType type,
- const unsigned char *data, PRUint32 len)
-{
- DTLSQueuedMessage *msg = NULL;
-
- msg = PORT_ZAlloc(sizeof(DTLSQueuedMessage));
- if (!msg)
- return NULL;
-
- msg->data = PORT_Alloc(len);
- if (!msg->data) {
- PORT_Free(msg);
- return NULL;
- }
- PORT_Memcpy(msg->data, data, len);
-
- msg->len = len;
- msg->epoch = epoch;
- msg->type = type;
-
- return msg;
-}
-
-/*
- * Free a handshake message
- *
- * Called from dtls_FreeHandshakeMessages()
- */
-static void
-dtls_FreeHandshakeMessage(DTLSQueuedMessage *msg)
-{
- if (!msg)
- return;
-
- PORT_ZFree(msg->data, msg->len);
- PORT_Free(msg);
-}
-
-/*
- * Free a list of handshake messages
- *
- * Called from:
- * dtls_HandleHandshake()
- * ssl3_DestroySSL3Info()
- */
-void
-dtls_FreeHandshakeMessages(PRCList *list)
-{
- PRCList *cur_p;
-
- while (!PR_CLIST_IS_EMPTY(list)) {
- cur_p = PR_LIST_TAIL(list);
- PR_REMOVE_LINK(cur_p);
- dtls_FreeHandshakeMessage((DTLSQueuedMessage *)cur_p);
- }
-}
-
-/* Called only from ssl3_HandleRecord, for each (deciphered) DTLS record.
- * origBuf is the decrypted ssl record content and is expected to contain
- * complete handshake records
- * Caller must hold the handshake and RecvBuf locks.
- *
- * Note that this code uses msg_len for two purposes:
- *
- * (1) To pass the length to ssl3_HandleHandshakeMessage()
- * (2) To carry the length of a message currently being reassembled
- *
- * However, unlike ssl3_HandleHandshake(), it is not used to carry
- * the state of reassembly (i.e., whether one is in progress). That
- * is carried in recvdHighWater and recvdFragments.
- */
-#define OFFSET_BYTE(o) (o/8)
-#define OFFSET_MASK(o) (1 << (o%8))
-
-SECStatus
-dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
-{
- /* XXX OK for now.
- * This doesn't work properly with asynchronous certificate validation.
- * because that returns a WOULDBLOCK error. The current DTLS
- * applications do not need asynchronous validation, but in the
- * future we will need to add this.
- */
- sslBuffer buf = *origBuf;
- SECStatus rv = SECSuccess;
-
- PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
- PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- while (buf.len > 0) {
- PRUint8 type;
- PRUint32 message_length;
- PRUint16 message_seq;
- PRUint32 fragment_offset;
- PRUint32 fragment_length;
- PRUint32 offset;
-
- if (buf.len < 12) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
- rv = SECFailure;
- break;
- }
-
- /* Parse the header */
- type = buf.buf[0];
- message_length = (buf.buf[1] << 16) | (buf.buf[2] << 8) | buf.buf[3];
- message_seq = (buf.buf[4] << 8) | buf.buf[5];
- fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8];
- fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11];
-
-#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
- if (message_length > MAX_HANDSHAKE_MSG_LEN) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- return SECFailure;
- }
-#undef MAX_HANDSHAKE_MSG_LEN
-
- buf.buf += 12;
- buf.len -= 12;
-
- /* This fragment must be complete */
- if (buf.len < fragment_length) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
- rv = SECFailure;
- break;
- }
-
- /* Sanity check the packet contents */
- if ((fragment_length + fragment_offset) > message_length) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
- rv = SECFailure;
- break;
- }
-
- /* There are three ways we could not be ready for this packet.
- *
- * 1. It's a partial next message.
- * 2. It's a partial or complete message beyond the next
- * 3. It's a message we've already seen
- *
- * If it's the complete next message we accept it right away.
- * This is the common case for short messages
- */
- if ((message_seq == ss->ssl3.hs.recvMessageSeq)
- && (fragment_offset == 0)
- && (fragment_length == message_length)) {
- /* Complete next message. Process immediately */
- ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
- ss->ssl3.hs.msg_len = message_length;
-
- /* At this point we are advancing our state machine, so
- * we can free our last flight of messages */
- dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
- ss->ssl3.hs.recvdHighWater = -1;
- dtls_CancelTimer(ss);
-
- /* Reset the timer to the initial value if the retry counter
- * is 0, per Sec. 4.2.4.1 */
- if (ss->ssl3.hs.rtRetries == 0) {
- ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
- }
-
- rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len);
- if (rv == SECFailure) {
- /* Do not attempt to process rest of messages in this record */
- break;
- }
- } else {
- if (message_seq < ss->ssl3.hs.recvMessageSeq) {
- /* Case 3: we do an immediate retransmit if we're
- * in a waiting state*/
- if (ss->ssl3.hs.rtTimerCb == NULL) {
- /* Ignore */
- } else if (ss->ssl3.hs.rtTimerCb ==
- dtls_RetransmitTimerExpiredCb) {
- SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected",
- SSL_GETPID(), ss->fd));
- /* Check to see if we retransmitted recently. If so,
- * suppress the triggered retransmit. This avoids
- * retransmit wars after packet loss.
- * This is not in RFC 5346 but should be
- */
- if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
- (ss->ssl3.hs.rtTimeoutMs / 4)) {
- SSL_TRC(30,
- ("%d: SSL3[%d]: Shortcutting retransmit timer",
- SSL_GETPID(), ss->fd));
-
- /* Cancel the timer and call the CB,
- * which re-arms the timer */
- dtls_CancelTimer(ss);
- dtls_RetransmitTimerExpiredCb(ss);
- rv = SECSuccess;
- break;
- } else {
- SSL_TRC(30,
- ("%d: SSL3[%d]: We just retransmitted. Ignoring.",
- SSL_GETPID(), ss->fd));
- rv = SECSuccess;
- break;
- }
- } else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
- /* Retransmit the messages and re-arm the timer
- * Note that we are not backing off the timer here.
- * The spec isn't clear and my reasoning is that this
- * may be a re-ordered packet rather than slowness,
- * so let's be aggressive. */
- dtls_CancelTimer(ss);
- rv = dtls_TransmitMessageFlight(ss);
- if (rv == SECSuccess) {
- rv = dtls_StartTimer(ss, dtls_FinishedTimerCb);
- }
- if (rv != SECSuccess)
- return rv;
- break;
- }
- } else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
- /* Case 2
- *
- * Ignore this message. This means we don't handle out of
- * order complete messages that well, but we're still
- * compliant and this probably does not happen often
- *
- * XXX OK for now. Maybe do something smarter at some point?
- */
- } else {
- /* Case 1
- *
- * Buffer the fragment for reassembly
- */
- /* Make room for the message */
- if (ss->ssl3.hs.recvdHighWater == -1) {
- PRUint32 map_length = OFFSET_BYTE(message_length) + 1;
-
- rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, message_length);
- if (rv != SECSuccess)
- break;
- /* Make room for the fragment map */
- rv = sslBuffer_Grow(&ss->ssl3.hs.recvdFragments,
- map_length);
- if (rv != SECSuccess)
- break;
-
- /* Reset the reassembly map */
- ss->ssl3.hs.recvdHighWater = 0;
- PORT_Memset(ss->ssl3.hs.recvdFragments.buf, 0,
- ss->ssl3.hs.recvdFragments.space);
- ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
- ss->ssl3.hs.msg_len = message_length;
- }
-
- /* If we have a message length mismatch, abandon the reassembly
- * in progress and hope that the next retransmit will give us
- * something sane
- */
- if (message_length != ss->ssl3.hs.msg_len) {
- ss->ssl3.hs.recvdHighWater = -1;
- PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
- rv = SECFailure;
- break;
- }
-
- /* Now copy this fragment into the buffer */
- PORT_Assert((fragment_offset + fragment_length) <=
- ss->ssl3.hs.msg_body.space);
- PORT_Memcpy(ss->ssl3.hs.msg_body.buf + fragment_offset,
- buf.buf, fragment_length);
-
- /* This logic is a bit tricky. We have two values for
- * reassembly state:
- *
- * - recvdHighWater contains the highest contiguous number of
- * bytes received
- * - recvdFragments contains a bitmask of packets received
- * above recvdHighWater
- *
- * This avoids having to fill in the bitmask in the common
- * case of adjacent fragments received in sequence
- */
- if (fragment_offset <= ss->ssl3.hs.recvdHighWater) {
- /* Either this is the adjacent fragment or an overlapping
- * fragment */
- ss->ssl3.hs.recvdHighWater = fragment_offset +
- fragment_length;
- } else {
- for (offset = fragment_offset;
- offset < fragment_offset + fragment_length;
- offset++) {
- ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] |=
- OFFSET_MASK(offset);
- }
- }
-
- /* Now figure out the new high water mark if appropriate */
- for (offset = ss->ssl3.hs.recvdHighWater;
- offset < ss->ssl3.hs.msg_len; offset++) {
- /* Note that this loop is not efficient, since it counts
- * bit by bit. If we have a lot of out-of-order packets,
- * we should optimize this */
- if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] &
- OFFSET_MASK(offset)) {
- ss->ssl3.hs.recvdHighWater++;
- } else {
- break;
- }
- }
-
- /* If we have all the bytes, then we are good to go */
- if (ss->ssl3.hs.recvdHighWater == ss->ssl3.hs.msg_len) {
- ss->ssl3.hs.recvdHighWater = -1;
-
- rv = ssl3_HandleHandshakeMessage(ss,
- ss->ssl3.hs.msg_body.buf,
- ss->ssl3.hs.msg_len);
- if (rv == SECFailure)
- break; /* Skip rest of record */
-
- /* At this point we are advancing our state machine, so
- * we can free our last flight of messages */
- dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
- dtls_CancelTimer(ss);
-
- /* If there have been no retries this time, reset the
- * timer value to the default per Section 4.2.4.1 */
- if (ss->ssl3.hs.rtRetries == 0) {
- ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
- }
- }
- }
- }
-
- buf.buf += fragment_length;
- buf.len -= fragment_length;
- }
-
- origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
-
- /* XXX OK for now. In future handle rv == SECWouldBlock safely in order
- * to deal with asynchronous certificate verification */
- return rv;
-}
-
-/* Enqueue a message (either handshake or CCS)
- *
- * Called from:
- * dtls_StageHandshakeMessage()
- * ssl3_SendChangeCipherSpecs()
- */
-SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
- const SSL3Opaque *pIn, PRInt32 nIn)
-{
- SECStatus rv = SECSuccess;
- DTLSQueuedMessage *msg = NULL;
-
- PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
- msg = dtls_AllocQueuedMessage(ss->ssl3.cwSpec->epoch, type, pIn, nIn);
-
- if (!msg) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- } else {
- PR_APPEND_LINK(&msg->link, &ss->ssl3.hs.lastMessageFlight);
- }
-
- return rv;
-}
-
-/* Add DTLS handshake message to the pending queue
- * Empty the sendBuf buffer.
- * This function returns SECSuccess or SECFailure, never SECWouldBlock.
- * Always set sendBuf.len to 0, even when returning SECFailure.
- *
- * Called from:
- * ssl3_AppendHandshakeHeader()
- * dtls_FlushHandshake()
- */
-SECStatus
-dtls_StageHandshakeMessage(sslSocket *ss)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
- /* This function is sometimes called when no data is actually to
- * be staged, so just return SECSuccess. */
- if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
- return rv;
-
- rv = dtls_QueueMessage(ss, content_handshake,
- ss->sec.ci.sendBuf.buf, ss->sec.ci.sendBuf.len);
-
- /* Whether we succeeded or failed, toss the old handshake data. */
- ss->sec.ci.sendBuf.len = 0;
- return rv;
-}
-
-/* Enqueue the handshake message in sendBuf (if any) and then
- * transmit the resulting flight of handshake messages.
- *
- * Called from:
- * ssl3_FlushHandshake()
- */
-SECStatus
-dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
- rv = dtls_StageHandshakeMessage(ss);
- if (rv != SECSuccess)
- return rv;
-
- if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
- rv = dtls_TransmitMessageFlight(ss);
- if (rv != SECSuccess)
- return rv;
-
- if (!(flags & ssl_SEND_FLAG_NO_RETRANSMIT)) {
- ss->ssl3.hs.rtRetries = 0;
- rv = dtls_StartTimer(ss, dtls_RetransmitTimerExpiredCb);
- }
- }
-
- return rv;
-}
-
-/* The callback for when the retransmit timer expires
- *
- * Called from:
- * dtls_CheckTimer()
- * dtls_HandleHandshake()
- */
-static void
-dtls_RetransmitTimerExpiredCb(sslSocket *ss)
-{
- SECStatus rv = SECFailure;
-
- ss->ssl3.hs.rtRetries++;
-
- if (!(ss->ssl3.hs.rtRetries % 3)) {
- /* If one of the messages was potentially greater than > MTU,
- * then downgrade. Do this every time we have retransmitted a
- * message twice, per RFC 6347 Sec. 4.1.1 */
- dtls_SetMTU(ss, ss->ssl3.hs.maxMessageSent - 1);
- }
-
- rv = dtls_TransmitMessageFlight(ss);
- if (rv == SECSuccess) {
-
- /* Re-arm the timer */
- rv = dtls_RestartTimer(ss, PR_TRUE, dtls_RetransmitTimerExpiredCb);
- }
-
- if (rv == SECFailure) {
- /* XXX OK for now. In future maybe signal the stack that we couldn't
- * transmit. For now, let the read handle any real network errors */
- }
-}
-
-/* Transmit a flight of handshake messages, stuffing them
- * into as few records as seems reasonable
- *
- * Called from:
- * dtls_FlushHandshake()
- * dtls_RetransmitTimerExpiredCb()
- */
-static SECStatus
-dtls_TransmitMessageFlight(sslSocket *ss)
-{
- SECStatus rv = SECSuccess;
- PRCList *msg_p;
- PRUint16 room_left = ss->ssl3.mtu;
- PRInt32 sent;
-
- ssl_GetXmitBufLock(ss);
- ssl_GetSpecReadLock(ss);
-
- /* DTLS does not buffer its handshake messages in
- * ss->pendingBuf, but rather in the lastMessageFlight
- * structure. This is just a sanity check that
- * some programming error hasn't inadvertantly
- * stuffed something in ss->pendingBuf
- */
- PORT_Assert(!ss->pendingBuf.len);
- for (msg_p = PR_LIST_HEAD(&ss->ssl3.hs.lastMessageFlight);
- msg_p != &ss->ssl3.hs.lastMessageFlight;
- msg_p = PR_NEXT_LINK(msg_p)) {
- DTLSQueuedMessage *msg = (DTLSQueuedMessage *)msg_p;
-
- /* The logic here is:
- *
- * 1. If this is a message that will not fit into the remaining
- * space, then flush.
- * 2. If the message will now fit into the remaining space,
- * encrypt, buffer, and loop.
- * 3. If the message will not fit, then fragment.
- *
- * At the end of the function, flush.
- */
- if ((msg->len + SSL3_BUFFER_FUDGE) > room_left) {
- /* The message will not fit into the remaining space, so flush */
- rv = dtls_SendSavedWriteData(ss);
- if (rv != SECSuccess)
- break;
-
- room_left = ss->ssl3.mtu;
- }
-
- if ((msg->len + SSL3_BUFFER_FUDGE) <= room_left) {
- /* The message will fit, so encrypt and then continue with the
- * next packet */
- sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
- msg->data, msg->len,
- ssl_SEND_FLAG_FORCE_INTO_BUFFER |
- ssl_SEND_FLAG_USE_EPOCH);
- if (sent != msg->len) {
- rv = SECFailure;
- if (sent != -1) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- }
- break;
- }
-
- room_left = ss->ssl3.mtu - ss->pendingBuf.len;
- } else {
- /* The message will not fit, so fragment.
- *
- * XXX OK for now. Arrange to coalesce the last fragment
- * of this message with the next message if possible.
- * That would be more efficient.
- */
- PRUint32 fragment_offset = 0;
- unsigned char fragment[DTLS_MAX_MTU]; /* >= than largest
- * plausible MTU */
-
- /* Assert that we have already flushed */
- PORT_Assert(room_left == ss->ssl3.mtu);
-
- /* Case 3: We now need to fragment this message
- * DTLS only supports fragmenting handshaking messages */
- PORT_Assert(msg->type == content_handshake);
-
- /* The headers consume 12 bytes so the smalles possible
- * message (i.e., an empty one) is 12 bytes
- */
- PORT_Assert(msg->len >= 12);
-
- while ((fragment_offset + 12) < msg->len) {
- PRUint32 fragment_len;
- const unsigned char *content = msg->data + 12;
- PRUint32 content_len = msg->len - 12;
-
- /* The reason we use 8 here is that that's the length of
- * the new DTLS data that we add to the header */
- fragment_len = PR_MIN(room_left - (SSL3_BUFFER_FUDGE + 8),
- content_len - fragment_offset);
- PORT_Assert(fragment_len < DTLS_MAX_MTU - 12);
- /* Make totally sure that we are within the buffer.
- * Note that the only way that fragment len could get
- * adjusted here is if
- *
- * (a) we are in release mode so the PORT_Assert is compiled out
- * (b) either the MTU table is inconsistent with DTLS_MAX_MTU
- * or ss->ssl3.mtu has become corrupt.
- */
- fragment_len = PR_MIN(fragment_len, DTLS_MAX_MTU - 12);
-
- /* Construct an appropriate-sized fragment */
- /* Type, length, sequence */
- PORT_Memcpy(fragment, msg->data, 6);
-
- /* Offset */
- fragment[6] = (fragment_offset >> 16) & 0xff;
- fragment[7] = (fragment_offset >> 8) & 0xff;
- fragment[8] = (fragment_offset) & 0xff;
-
- /* Fragment length */
- fragment[9] = (fragment_len >> 16) & 0xff;
- fragment[10] = (fragment_len >> 8) & 0xff;
- fragment[11] = (fragment_len) & 0xff;
-
- PORT_Memcpy(fragment + 12, content + fragment_offset,
- fragment_len);
-
- /*
- * Send the record. We do this in two stages
- * 1. Encrypt
- */
- sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
- fragment, fragment_len + 12,
- ssl_SEND_FLAG_FORCE_INTO_BUFFER |
- ssl_SEND_FLAG_USE_EPOCH);
- if (sent != (fragment_len + 12)) {
- rv = SECFailure;
- if (sent != -1) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- }
- break;
- }
-
- /* 2. Flush */
- rv = dtls_SendSavedWriteData(ss);
- if (rv != SECSuccess)
- break;
-
- fragment_offset += fragment_len;
- }
- }
- }
-
- /* Finally, we need to flush */
- if (rv == SECSuccess)
- rv = dtls_SendSavedWriteData(ss);
-
- /* Give up the locks */
- ssl_ReleaseSpecReadLock(ss);
- ssl_ReleaseXmitBufLock(ss);
-
- return rv;
-}
-
-/* Flush the data in the pendingBuf and update the max message sent
- * so we can adjust the MTU estimate if we need to.
- * Wrapper for ssl_SendSavedWriteData.
- *
- * Called from dtls_TransmitMessageFlight()
- */
-static
-SECStatus dtls_SendSavedWriteData(sslSocket *ss)
-{
- PRInt32 sent;
-
- sent = ssl_SendSavedWriteData(ss);
- if (sent < 0)
- return SECFailure;
-
- /* We should always have complete writes b/c datagram sockets
- * don't really block */
- if (ss->pendingBuf.len > 0) {
- ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
- return SECFailure;
- }
-
- /* Update the largest message sent so we can adjust the MTU
- * estimate if necessary */
- if (sent > ss->ssl3.hs.maxMessageSent)
- ss->ssl3.hs.maxMessageSent = sent;
-
- return SECSuccess;
-}
-
-/* Compress, MAC, encrypt a DTLS record. Allows specification of
- * the epoch using epoch value. If use_epoch is PR_TRUE then
- * we use the provided epoch. If use_epoch is PR_FALSE then
- * whatever the current value is in effect is used.
- *
- * Called from ssl3_SendRecord()
- */
-SECStatus
-dtls_CompressMACEncryptRecord(sslSocket * ss,
- DTLSEpoch epoch,
- PRBool use_epoch,
- SSL3ContentType type,
- const SSL3Opaque * pIn,
- PRUint32 contentLen,
- sslBuffer * wrBuf)
-{
- SECStatus rv = SECFailure;
- ssl3CipherSpec * cwSpec;
-
- ssl_GetSpecReadLock(ss); /********************************/
-
- /* The reason for this switch-hitting code is that we might have
- * a flight of records spanning an epoch boundary, e.g.,
- *
- * ClientKeyExchange (epoch = 0)
- * ChangeCipherSpec (epoch = 0)
- * Finished (epoch = 1)
- *
- * Thus, each record needs a different cipher spec. The information
- * about which epoch to use is carried with the record.
- */
- if (use_epoch) {
- if (ss->ssl3.cwSpec->epoch == epoch)
- cwSpec = ss->ssl3.cwSpec;
- else if (ss->ssl3.pwSpec->epoch == epoch)
- cwSpec = ss->ssl3.pwSpec;
- else
- cwSpec = NULL;
- } else {
- cwSpec = ss->ssl3.cwSpec;
- }
-
- if (cwSpec) {
- rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
- PR_FALSE, type, pIn, contentLen,
- wrBuf);
- } else {
- PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- }
- ssl_ReleaseSpecReadLock(ss); /************************************/
-
- return rv;
-}
-
-/* Start a timer
- *
- * Called from:
- * dtls_HandleHandshake()
- * dtls_FlushHAndshake()
- * dtls_RestartTimer()
- */
-SECStatus
-dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb)
-{
- PORT_Assert(ss->ssl3.hs.rtTimerCb == NULL);
-
- ss->ssl3.hs.rtTimerStarted = PR_IntervalNow();
- ss->ssl3.hs.rtTimerCb = cb;
-
- return SECSuccess;
-}
-
-/* Restart a timer with optional backoff
- *
- * Called from dtls_RetransmitTimerExpiredCb()
- */
-SECStatus
-dtls_RestartTimer(sslSocket *ss, PRBool backoff, DTLSTimerCb cb)
-{
- if (backoff) {
- ss->ssl3.hs.rtTimeoutMs *= 2;
- if (ss->ssl3.hs.rtTimeoutMs > MAX_DTLS_TIMEOUT_MS)
- ss->ssl3.hs.rtTimeoutMs = MAX_DTLS_TIMEOUT_MS;
- }
-
- return dtls_StartTimer(ss, cb);
-}
-
-/* Cancel a pending timer
- *
- * Called from:
- * dtls_HandleHandshake()
- * dtls_CheckTimer()
- */
-void
-dtls_CancelTimer(sslSocket *ss)
-{
- PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
-
- ss->ssl3.hs.rtTimerCb = NULL;
-}
-
-/* Check the pending timer and fire the callback if it expired
- *
- * Called from ssl3_GatherCompleteHandshake()
- */
-void
-dtls_CheckTimer(sslSocket *ss)
-{
- if (!ss->ssl3.hs.rtTimerCb)
- return;
-
- if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
- PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs)) {
- /* Timer has expired */
- DTLSTimerCb cb = ss->ssl3.hs.rtTimerCb;
-
- /* Cancel the timer so that we can call the CB safely */
- dtls_CancelTimer(ss);
-
- /* Now call the CB */
- cb(ss);
- }
-}
-
-/* The callback to fire when the holddown timer for the Finished
- * message expires and we can delete it
- *
- * Called from dtls_CheckTimer()
- */
-void
-dtls_FinishedTimerCb(sslSocket *ss)
-{
- ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
-}
-
-/* Cancel the Finished hold-down timer and destroy the
- * pending cipher spec. Note that this means that
- * successive rehandshakes will fail if the Finished is
- * lost.
- *
- * XXX OK for now. Figure out how to handle the combination
- * of Finished lost and rehandshake
- */
-void
-dtls_RehandshakeCleanup(sslSocket *ss)
-{
- dtls_CancelTimer(ss);
- ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE);
- ss->ssl3.hs.sendMessageSeq = 0;
- ss->ssl3.hs.recvMessageSeq = 0;
-}
-
-/* Set the MTU to the next step less than or equal to the
- * advertised value. Also used to downgrade the MTU by
- * doing dtls_SetMTU(ss, biggest packet set).
- *
- * Passing 0 means set this to the largest MTU known
- * (effectively resetting the PMTU backoff value).
- *
- * Called by:
- * ssl3_InitState()
- * dtls_RetransmitTimerExpiredCb()
- */
-void
-dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
-{
- int i;
-
- if (advertised == 0) {
- ss->ssl3.mtu = COMMON_MTU_VALUES[0];
- SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
- return;
- }
-
- for (i = 0; i < PR_ARRAY_SIZE(COMMON_MTU_VALUES); i++) {
- if (COMMON_MTU_VALUES[i] <= advertised) {
- ss->ssl3.mtu = COMMON_MTU_VALUES[i];
- SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
- return;
- }
- }
-
- /* Fallback */
- ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES)-1];
- SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a
- * DTLS hello_verify_request
- * Caller must hold Handshake and RecvBuf locks.
- */
-SECStatus
-dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
- SECStatus rv;
- PRInt32 temp;
- SECItem cookie = {siBuffer, NULL, 0};
- SSL3AlertDescription desc = illegal_parameter;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
- PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- if (ss->ssl3.hs.ws != wait_server_hello) {
- errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST;
- desc = unexpected_message;
- goto alert_loser;
- }
-
- /* The version */
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (temp < 0) {
- goto loser; /* alert has been sent */
- }
-
- if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE) {
- /* Note: this will need adjustment for DTLS 1.2 per Section 4.2.1 */
- goto alert_loser;
- }
-
- /* The cookie */
- rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* alert has been sent */
- }
- if (cookie.len > DTLS_COOKIE_BYTES) {
- desc = decode_error;
- goto alert_loser; /* malformed. */
- }
-
- PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len);
- ss->ssl3.hs.cookieLen = cookie.len;
-
-
- ssl_GetXmitBufLock(ss); /*******************************/
-
- /* Now re-send the client hello */
- rv = ssl3_SendClientHello(ss, PR_TRUE);
-
- ssl_ReleaseXmitBufLock(ss); /*******************************/
-
- if (rv == SECSuccess)
- return rv;
-
-alert_loser:
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-
-loser:
- errCode = ssl_MapLowLevelError(errCode);
- return SECFailure;
-}
-
-/* Initialize the DTLS anti-replay window
- *
- * Called from:
- * ssl3_SetupPendingCipherSpec()
- * ssl3_InitCipherSpec()
- */
-void
-dtls_InitRecvdRecords(DTLSRecvdRecords *records)
-{
- PORT_Memset(records->data, 0, sizeof(records->data));
- records->left = 0;
- records->right = DTLS_RECVD_RECORDS_WINDOW - 1;
-}
-
-/*
- * Has this DTLS record been received? Return values are:
- * -1 -- out of range to the left
- * 0 -- not received yet
- * 1 -- replay
- *
- * Called from: dtls_HandleRecord()
- */
-int
-dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
-{
- PRUint64 offset;
-
- /* Out of range to the left */
- if (seq < records->left) {
- return -1;
- }
-
- /* Out of range to the right; since we advance the window on
- * receipt, that means that this packet has not been received
- * yet */
- if (seq > records->right)
- return 0;
-
- offset = seq % DTLS_RECVD_RECORDS_WINDOW;
-
- return !!(records->data[offset / 8] & (1 << (offset % 8)));
-}
-
-/* Update the DTLS anti-replay window
- *
- * Called from ssl3_HandleRecord()
- */
-void
-dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
-{
- PRUint64 offset;
-
- if (seq < records->left)
- return;
-
- if (seq > records->right) {
- PRUint64 new_left;
- PRUint64 new_right;
- PRUint64 right;
-
- /* Slide to the right; this is the tricky part
- *
- * 1. new_top is set to have room for seq, on the
- * next byte boundary by setting the right 8
- * bits of seq
- * 2. new_left is set to compensate.
- * 3. Zero all bits between top and new_top. Since
- * this is a ring, this zeroes everything as-yet
- * unseen. Because we always operate on byte
- * boundaries, we can zero one byte at a time
- */
- new_right = seq | 0x07;
- new_left = (new_right - DTLS_RECVD_RECORDS_WINDOW) + 1;
-
- for (right = records->right + 8; right <= new_right; right += 8) {
- offset = right % DTLS_RECVD_RECORDS_WINDOW;
- records->data[offset / 8] = 0;
- }
-
- records->right = new_right;
- records->left = new_left;
- }
-
- offset = seq % DTLS_RECVD_RECORDS_WINDOW;
-
- records->data[offset / 8] |= (1 << (offset % 8));
-}
-
-SECStatus
-DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
-{
- sslSocket * ss = NULL;
- PRIntervalTime elapsed;
- PRIntervalTime desired;
-
- ss = ssl_FindSocket(socket);
-
- if (!ss)
- return SECFailure;
-
- if (!IS_DTLS(ss))
- return SECFailure;
-
- if (!ss->ssl3.hs.rtTimerCb)
- return SECFailure;
-
- elapsed = PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted;
- desired = PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs);
- if (elapsed > desired) {
- /* Timer expired */
- *timeout = PR_INTERVAL_NO_WAIT;
- } else {
- *timeout = desired - elapsed;
- }
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/ssl/manifest.mn b/security/nss/lib/ssl/manifest.mn
deleted file mode 100644
index 3bb28a2f0..000000000
--- a/security/nss/lib/ssl/manifest.mn
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-
-# DEFINES = -DTRACE
-
-EXPORTS = \
- ssl.h \
- sslt.h \
- sslerr.h \
- sslproto.h \
- preenc.h \
- $(NULL)
-
-MODULE = nss
-MAPFILE = $(OBJDIR)/ssl.def
-
-CSRCS = \
- derive.c \
- dtlscon.c \
- prelib.c \
- ssl3con.c \
- ssl3gthr.c \
- sslauth.c \
- sslcon.c \
- ssldef.c \
- sslenum.c \
- sslerr.c \
- sslerrstrs.c \
- sslinit.c \
- ssl3ext.c \
- sslgathr.c \
- sslmutex.c \
- sslnonce.c \
- sslreveal.c \
- sslsecur.c \
- sslsnce.c \
- sslsock.c \
- ssltrace.c \
- sslver.c \
- authcert.c \
- cmpcert.c \
- sslinfo.c \
- ssl3ecc.c \
- $(NULL)
-
-LIBRARY_NAME = ssl
-LIBRARY_VERSION = 3
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/ssl/notes.txt b/security/nss/lib/ssl/notes.txt
deleted file mode 100644
index a71c08ef2..000000000
--- a/security/nss/lib/ssl/notes.txt
+++ /dev/null
@@ -1,134 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-SSL's Buffers: enumerated and explained.
-
----------------------------------------------------------------------------
-incoming:
-
-gs = ss->gather
-hs = ss->ssl3->hs
-
-gs->inbuf SSL3 only: incoming (encrypted) ssl records are placed here,
- and then decrypted (or copied) to gs->buf.
-
-gs->buf SSL2: incoming SSL records are put here, and then decrypted
- in place.
- SSL3: ssl3_HandleHandshake puts decrypted ssl records here.
-
-hs.msg_body (SSL3 only) When an incoming handshake message spans more
- than one ssl record, the first part(s) of it are accumulated
- here until it all arrives.
-
-hs.msgState (SSL3 only) an alternative set of pointers/lengths for gs->buf.
- Used only when a handleHandshake function returns SECWouldBlock.
- ssl3_HandleHandshake remembers how far it previously got by
- using these pointers instead of gs->buf when it is called
- after a previous SECWouldBlock return.
-
----------------------------------------------------------------------------
-outgoing:
-
-sec = ss->sec
-ci = ss->sec->ci /* connect info */
-
-ci->sendBuf Outgoing handshake messages are appended to this buffer.
- This buffer will then be sent as a single SSL record.
-
-sec->writeBuf outgoing ssl records are constructed here and encrypted in
- place before being written or copied to pendingBuf.
-
-ss->pendingBuf contains outgoing ciphertext that was saved after a write
- attempt to the socket failed, e.g. EWouldBlock.
- Generally empty with blocking sockets (should be no incomplete
- writes).
-
-ss->saveBuf Used only by socks code. Intended to be used to buffer
- outgoing data until a socks handshake completes. However,
- this buffer is always empty. There is no code to put
- anything into it.
-
----------------------------------------------------------------------------
-
-SECWouldBlock means that the function cannot make progress because it is
-waiting for some event OTHER THAN socket I/O completion (e.g. waiting for
-user dialog to finish). It is not the same as EWOULDBLOCK.
-
----------------------------------------------------------------------------
-
-Rank (order) of locks
-
-recvLock ->\ firstHandshake -> recvbuf -> ssl3Handshake -> xmitbuf -> "spec"
-sendLock ->/
-
-crypto and hash Data that must be protected while turning plaintext into
-ciphertext:
-
-SSL2: (in ssl2_Send*)
- sec->hash*
- sec->hashcx (ptr and data)
- sec->enc
- sec->writecx* (ptr and content)
- sec->sendSecret*(ptr and content)
- sec->sendSequence locked by xmitBufLock
- sec->blockSize
- sec->writeBuf* (ptr & content) locked by xmitBufLock
- "in" locked by xmitBufLock
-
-SSl3: (in ssl3_SendPlainText)
- ss->ssl3 (the pointer)
- ss->ssl3->current_write* (the pointer and the data in the spec
- and any data referenced by the spec.
-
- ss->sec->isServer
- ss->sec->writebuf* (ptr & content) locked by xmitBufLock
- "buf" locked by xmitBufLock
-
-crypto and hash data that must be protected while turning ciphertext into
-plaintext:
-
-SSL2: (in ssl2_GatherData)
- gs->* (locked by recvBufLock )
- sec->dec
- sec->readcx
- sec->hash* (ptr and data)
- sec->hashcx (ptr and data)
-
-SSL3: (in ssl3_HandleRecord )
- ssl3->current_read* (the pointer and all data refernced)
- ss->sec->isServer
-
-
-Data that must be protected while being used by a "writer":
-
-ss->pendingBuf.*
-ss->saveBuf.* (which is dead)
-
-in ssl3_sendPlainText
-
-ss->ssl3->current_write-> (spec)
-ss->sec->writeBuf.*
-ss->sec->isServer
-
-in SendBlock
-
-ss->sec->hash->length
-ss->sec->blockSize
-ss->sec->writeBuf.*
-ss->sec->sendSecret
-ss->sec->sendSequence
-ss->sec->writecx *
-ss->pendingBuf
-
---------------------------------------------------------------------------
-
-Data variables (not const) protected by the "sslGlobalDataLock".
-Note, this really should be a reader/writer lock.
-
-allowedByPolicy sslcon.c
-maybeAllowedByPolicy sslcon.c
-chosenPreference sslcon.c
-policyWasSet sslcon.c
-
-cipherSuites[] ssl3con.c
diff --git a/security/nss/lib/ssl/os2_err.c b/security/nss/lib/ssl/os2_err.c
deleted file mode 100644
index ee760034e..000000000
--- a/security/nss/lib/ssl/os2_err.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * this code will continue to need to be replicated.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "prerror.h"
-#include "prlog.h"
-#include <errno.h>
-
-
-/*
- * Based on win32err.c
- * OS2TODO Stub everything for now to build. HCT
- */
-
-/* forward declaration. */
-void nss_MD_os2_map_default_error(PRInt32 err);
-
-void nss_MD_os2_map_opendir_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_closedir_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_readdir_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_delete_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-/* The error code for stat() is in errno. */
-void nss_MD_os2_map_stat_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_fstat_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_rename_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-/* The error code for access() is in errno. */
-void nss_MD_os2_map_access_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_mkdir_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_rmdir_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_read_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_transmitfile_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_write_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_lseek_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_fsync_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-/*
- * For both CloseHandle() and closesocket().
- */
-void nss_MD_os2_map_close_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_socket_error(PRInt32 err)
-{
-// PR_ASSERT(err != WSANOTINITIALISED);
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_recv_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_recvfrom_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_send_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
-// case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_os2_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_os2_map_sendto_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
-// case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_os2_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_os2_map_accept_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
-// case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
-// case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
- default: nss_MD_os2_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_os2_map_acceptex_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_connect_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
-// case WSAEWOULDBLOCK: prError = PR_IN_PROGRESS_ERROR; break;
-// case WSAEINVAL: prError = PR_ALREADY_INITIATED_ERROR; break;
-// case WSAETIMEDOUT: prError = PR_IO_TIMEOUT_ERROR; break;
- default: nss_MD_os2_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_os2_map_bind_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
-// case WSAEINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
- default: nss_MD_os2_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_os2_map_listen_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
-// case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
-// case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
- default: nss_MD_os2_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_os2_map_shutdown_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_getsockname_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
-// case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
- default: nss_MD_os2_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_os2_map_getpeername_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_getsockopt_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_setsockopt_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_open_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-void nss_MD_os2_map_gethostname_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-/* Win32 select() only works on sockets. So in this
-** context, WSAENOTSOCK is equivalent to EBADF on Unix.
-*/
-void nss_MD_os2_map_select_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
-// case WSAENOTSOCK: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- default: nss_MD_os2_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_os2_map_lockf_error(PRInt32 err)
-{
- nss_MD_os2_map_default_error(err);
-}
-
-
-
-void nss_MD_os2_map_default_error(PRInt32 err)
-{
- PRErrorCode prError;
-
- switch (err) {
-// case ENOENT: prError = PR_FILE_NOT_FOUND_ERROR; break;
-// case ERROR_ACCESS_DENIED: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
-// case ERROR_ALREADY_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
-// case ERROR_DISK_CORRUPT: prError = PR_IO_ERROR; break;
-// case ERROR_DISK_FULL: prError = PR_NO_DEVICE_SPACE_ERROR; break;
-// case ERROR_DISK_OPERATION_FAILED: prError = PR_IO_ERROR; break;
-// case ERROR_DRIVE_LOCKED: prError = PR_FILE_IS_LOCKED_ERROR; break;
-// case ERROR_FILENAME_EXCED_RANGE: prError = PR_NAME_TOO_LONG_ERROR; break;
-// case ERROR_FILE_CORRUPT: prError = PR_IO_ERROR; break;
-// case ERROR_FILE_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
-// case ERROR_FILE_INVALID: prError = PR_BAD_DESCRIPTOR_ERROR; break;
-#if ERROR_FILE_NOT_FOUND != ENOENT
-// case ERROR_FILE_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
-#endif
- default: prError = PR_UNKNOWN_ERROR; break;
- }
- PR_SetError(prError, err);
-}
-
diff --git a/security/nss/lib/ssl/os2_err.h b/security/nss/lib/ssl/os2_err.h
deleted file mode 100644
index 21defa9e5..000000000
--- a/security/nss/lib/ssl/os2_err.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * This code will continue to need to be replicated.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* NSPR doesn't make these functions public, so we have to duplicate
-** them in NSS.
-*/
-
-//HCT Based on Win32err.h
-extern void nss_MD_os2_map_accept_error(PRInt32 err);
-extern void nss_MD_os2_map_acceptex_error(PRInt32 err);
-extern void nss_MD_os2_map_access_error(PRInt32 err);
-extern void nss_MD_os2_map_bind_error(PRInt32 err);
-extern void nss_MD_os2_map_close_error(PRInt32 err);
-extern void nss_MD_os2_map_closedir_error(PRInt32 err);
-extern void nss_MD_os2_map_connect_error(PRInt32 err);
-extern void nss_MD_os2_map_default_error(PRInt32 err);
-extern void nss_MD_os2_map_delete_error(PRInt32 err);
-extern void nss_MD_os2_map_fstat_error(PRInt32 err);
-extern void nss_MD_os2_map_fsync_error(PRInt32 err);
-extern void nss_MD_os2_map_gethostname_error(PRInt32 err);
-extern void nss_MD_os2_map_getpeername_error(PRInt32 err);
-extern void nss_MD_os2_map_getsockname_error(PRInt32 err);
-extern void nss_MD_os2_map_getsockopt_error(PRInt32 err);
-extern void nss_MD_os2_map_listen_error(PRInt32 err);
-extern void nss_MD_os2_map_lockf_error(PRInt32 err);
-extern void nss_MD_os2_map_lseek_error(PRInt32 err);
-extern void nss_MD_os2_map_mkdir_error(PRInt32 err);
-extern void nss_MD_os2_map_open_error(PRInt32 err);
-extern void nss_MD_os2_map_opendir_error(PRInt32 err);
-extern void nss_MD_os2_map_read_error(PRInt32 err);
-extern void nss_MD_os2_map_readdir_error(PRInt32 err);
-extern void nss_MD_os2_map_recv_error(PRInt32 err);
-extern void nss_MD_os2_map_recvfrom_error(PRInt32 err);
-extern void nss_MD_os2_map_rename_error(PRInt32 err);
-extern void nss_MD_os2_map_rmdir_error(PRInt32 err);
-extern void nss_MD_os2_map_select_error(PRInt32 err);
-extern void nss_MD_os2_map_send_error(PRInt32 err);
-extern void nss_MD_os2_map_sendto_error(PRInt32 err);
-extern void nss_MD_os2_map_setsockopt_error(PRInt32 err);
-extern void nss_MD_os2_map_shutdown_error(PRInt32 err);
-extern void nss_MD_os2_map_socket_error(PRInt32 err);
-extern void nss_MD_os2_map_stat_error(PRInt32 err);
-extern void nss_MD_os2_map_transmitfile_error(PRInt32 err);
-extern void nss_MD_os2_map_write_error(PRInt32 err);
diff --git a/security/nss/lib/ssl/preenc.h b/security/nss/lib/ssl/preenc.h
deleted file mode 100644
index 1b735ecd4..000000000
--- a/security/nss/lib/ssl/preenc.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-
-/*
- * Fortezza support is removed.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* Fortezza support is removed.
- * This file remains so that old programs will continue to compile,
- * But this functionality is no longer supported or implemented.
- */
-
-#include "seccomon.h"
-#include "prio.h"
-
-typedef struct PEHeaderStr PEHeader;
-
-#define PE_MIME_TYPE "application/pre-encrypted"
-
-typedef struct PEFortezzaHeaderStr PEFortezzaHeader;
-typedef struct PEFortezzaGeneratedHeaderStr PEFortezzaGeneratedHeader;
-typedef struct PEFixedKeyHeaderStr PEFixedKeyHeader;
-typedef struct PERSAKeyHeaderStr PERSAKeyHeader;
-
-struct PEFortezzaHeaderStr {
- unsigned char key[12];
- unsigned char iv[24];
- unsigned char hash[20];
- unsigned char serial[8];
-};
-
-struct PEFortezzaGeneratedHeaderStr {
- unsigned char key[12];
- unsigned char iv[24];
- unsigned char hash[20];
- unsigned char Ra[128];
- unsigned char Y[128];
-};
-
-struct PEFixedKeyHeaderStr {
- unsigned char pkcs11Mech[4];
- unsigned char labelLen[2];
- unsigned char keyIDLen[2];
- unsigned char ivLen[2];
- unsigned char keyLen[2];
- unsigned char data[1];
-};
-
-struct PERSAKeyHeaderStr {
- unsigned char pkcs11Mech[4];
- unsigned char issuerLen[2];
- unsigned char serialLen[2];
- unsigned char ivLen[2];
- unsigned char keyLen[2];
- unsigned char data[1];
-};
-
-#define PEFIXED_Label(header) (header->data)
-#define PEFIXED_KeyID(header) (&header->data[GetInt2(header->labelLen)])
-#define PEFIXED_IV(header) (&header->data[GetInt2(header->labelLen)\
- +GetInt2(header->keyIDLen)])
-#define PEFIXED_Key(header) (&header->data[GetInt2(header->labelLen)\
- +GetInt2(header->keyIDLen)+GetInt2(header->keyLen)])
-#define PERSA_Issuer(header) (header->data)
-#define PERSA_Serial(header) (&header->data[GetInt2(header->issuerLen)])
-#define PERSA_IV(header) (&header->data[GetInt2(header->issuerLen)\
- +GetInt2(header->serialLen)])
-#define PERSA_Key(header) (&header->data[GetInt2(header->issuerLen)\
- +GetInt2(header->serialLen)+GetInt2(header->keyLen)])
-struct PEHeaderStr {
- unsigned char magic [2];
- unsigned char len [2];
- unsigned char type [2];
- unsigned char version[2];
- union {
- PEFortezzaHeader fortezza;
- PEFortezzaGeneratedHeader g_fortezza;
- PEFixedKeyHeader fixed;
- PERSAKeyHeader rsa;
- } u;
-};
-
-#define PE_CRYPT_INTRO_LEN 8
-#define PE_INTRO_LEN 4
-#define PE_BASE_HEADER_LEN 8
-
-#define PRE_BLOCK_SIZE 8
-
-
-#define GetInt2(c) ((c[0] << 8) | c[1])
-#define GetInt4(c) (((unsigned long)c[0] << 24)|((unsigned long)c[1] << 16)\
- |((unsigned long)c[2] << 8)| ((unsigned long)c[3]))
-#define PutInt2(c,i) ((c[1] = (i) & 0xff), (c[0] = ((i) >> 8) & 0xff))
-#define PutInt4(c,i) ((c[0]=((i) >> 24) & 0xff),(c[1]=((i) >> 16) & 0xff),\
- (c[2] = ((i) >> 8) & 0xff), (c[3] = (i) & 0xff))
-
-#define PRE_MAGIC 0xc0de
-#define PRE_VERSION 0x1010
-#define PRE_FORTEZZA_FILE 0x00ff
-#define PRE_FORTEZZA_STREAM 0x00f5
-#define PRE_FORTEZZA_GEN_STREAM 0x00f6
-#define PRE_FIXED_FILE 0x000f
-#define PRE_RSA_FILE 0x001f
-#define PRE_FIXED_STREAM 0x0005
-
-PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *,
- int *headerSize);
-
-PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *,
- int *headerSize);
-
diff --git a/security/nss/lib/ssl/prelib.c b/security/nss/lib/ssl/prelib.c
deleted file mode 100644
index 0c8036f4d..000000000
--- a/security/nss/lib/ssl/prelib.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-
-/*
- * Functions used by https servers to send (download) pre-encrypted files
- * over SSL connections that use Fortezza ciphersuites.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "cert.h"
-#include "ssl.h"
-#include "keyhi.h"
-#include "secitem.h"
-#include "sslimpl.h"
-#include "pkcs11t.h"
-#include "preenc.h"
-#include "pk11func.h"
-
-PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *inHeader,
- int *headerSize)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
-}
-
-PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *header,
- int *headerSize)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
-}
-
-
diff --git a/security/nss/lib/ssl/ssl.def b/security/nss/lib/ssl/ssl.def
deleted file mode 100644
index 15dbfede7..000000000
--- a/security/nss/lib/ssl/ssl.def
+++ /dev/null
@@ -1,165 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+
-;+NSS_3.2 { # NSS 3.2 release
-;+ global:
-LIBRARY ssl3 ;-
-EXPORTS ;-
-SSL_ImplementedCiphers DATA ;
-SSL_NumImplementedCiphers DATA ;
-NSS_CmpCertChainWCANames;
-NSS_FindCertKEAType;
-NSS_GetClientAuthData;
-NSS_SetDomesticPolicy;
-NSS_SetExportPolicy;
-NSS_SetFrancePolicy;
-SSL_AuthCertificate;
-SSL_AuthCertificateHook;
-SSL_BadCertHook;
-SSL_CertDBHandleSet;
-SSL_CipherPolicyGet;
-SSL_CipherPolicySet;
-SSL_CipherPrefGet;
-SSL_CipherPrefGetDefault;
-SSL_CipherPrefSet;
-SSL_CipherPrefSetDefault;
-SSL_ClearSessionCache;
-SSL_ConfigMPServerSIDCache;
-SSL_ConfigSecureServer;
-SSL_ConfigServerSessionIDCache;
-SSL_DataPending;
-SSL_ForceHandshake;
-SSL_GetClientAuthDataHook;
-SSL_GetSessionID;
-SSL_GetStatistics;
-SSL_HandshakeCallback;
-SSL_ImportFD;
-SSL_InheritMPServerSIDCache;
-SSL_InvalidateSession;
-SSL_OptionGet;
-SSL_OptionGetDefault;
-SSL_OptionSet;
-SSL_OptionSetDefault;
-SSL_PeerCertificate;
-SSL_PreencryptedFileToStream;
-SSL_PreencryptedStreamToFile;
-SSL_ReHandshake;
-SSL_ResetHandshake;
-SSL_RestartHandshakeAfterCertReq;
-SSL_RestartHandshakeAfterServerCert;
-SSL_RevealCert;
-SSL_RevealPinArg;
-SSL_RevealURL;
-SSL_SecurityStatus;
-SSL_SetPKCS11PinArg;
-SSL_SetSockPeerID;
-SSL_SetURL;
-;+ local:
-;+*;
-;+};
-;+NSS_3.2.1 { # NSS 3.2.1 release
-;+ global:
-NSSSSL_VersionCheck;
-;+ local:
-;+*;
-;+};
-;+NSS_3.4 { # NSS 3.4 release
-;+ global:
-SSL_GetChannelInfo;
-SSL_GetCipherSuiteInfo;
-SSL_GetMaxServerCacheLocks;
-SSL_LocalCertificate;
-SSL_SetMaxServerCacheLocks;
-;+ local:
-;+*;
-;+};
-;+NSS_3.7.4 { # NSS 3.7.4 release
-;+ global:
-SSL_ShutdownServerSessionIDCache;
-;+ local:
-;+*;
-;+};
-;+NSS_3.11.4 { # NSS 3.11.4 release
-;+ global:
-SSL_ForceHandshakeWithTimeout;
-SSL_ReHandshakeWithTimeout;
-;+ local:
-;+*;
-;+};
-;+NSS_3.11.8 { # NSS 3.11.8 release
-;+ global:
-SSL_CanBypass;
-;+ local:
-;+*;
-;+};
-;+NSS_3.12.6 { # NSS 3.12.6 release
-;+ global:
-SSL_ConfigServerSessionIDCacheWithOpt;
-SSL_GetImplementedCiphers;
-SSL_GetNegotiatedHostInfo;
-SSL_GetNumImplementedCiphers;
-SSL_HandshakeNegotiatedExtension;
-SSL_ReconfigFD;
-SSL_SetTrustAnchors;
-SSL_SNISocketConfigHook;
-;+ local:
-;+*;
-;+};
-;+NSS_3.12.10 { # NSS 3.12.10 release
-;+ global:
-SSL_ConfigSecureServerWithCertChain;
-;+ local:
-;+*;
-;+};
-;+NSS_3.13 { # NSS 3.13 release
-;+ global:
-NSSSSL_GetVersion;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.13.2 { # NSS 3.13.2 release
-;+ global:
-SSL_SetNextProtoCallback;
-SSL_SetNextProtoNego;
-SSL_GetNextProto;
-SSL_AuthCertificateComplete;
-;+ local:
-;+ *;
-;+};
-;+NSS_3.14 { # NSS 3.14 release
-;+ global:
-DTLS_GetHandshakeTimeout;
-DTLS_ImportFD;
-SSL_ExportKeyingMaterial;
-SSL_VersionRangeGet;
-SSL_VersionRangeGetDefault;
-SSL_VersionRangeGetSupported;
-SSL_VersionRangeSet;
-SSL_VersionRangeSetDefault;
-SSL_GetSRTPCipher;
-SSL_SetSRTPCiphers;
-;+ local:
-;+*;
-;+};
-;+NSS_3.14.2 { # NSS 3.14.2 release
-;+ global:
-SSL_PeerStapledOCSPResponses;
-SSL_SetStapledOCSPResponses;
-;+ local:
-;+*;
-;+};
diff --git a/security/nss/lib/ssl/ssl.h b/security/nss/lib/ssl/ssl.h
deleted file mode 100644
index 4ad55151f..000000000
--- a/security/nss/lib/ssl/ssl.h
+++ /dev/null
@@ -1,980 +0,0 @@
-/*
- * This file contains prototypes for the public SSL functions.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef __ssl_h_
-#define __ssl_h_
-
-#include "prtypes.h"
-#include "prerror.h"
-#include "prio.h"
-#include "seccomon.h"
-#include "cert.h"
-#include "keyt.h"
-
-#include "sslt.h" /* public ssl data types */
-
-#if defined(_WIN32) && !defined(IN_LIBSSL) && !defined(NSS_USE_STATIC_LIBS)
-#define SSL_IMPORT extern __declspec(dllimport)
-#else
-#define SSL_IMPORT extern
-#endif
-
-SEC_BEGIN_PROTOS
-
-/* constant table enumerating all implemented SSL 2 and 3 cipher suites. */
-SSL_IMPORT const PRUint16 SSL_ImplementedCiphers[];
-
-/* the same as the above, but is a function */
-SSL_IMPORT const PRUint16 *SSL_GetImplementedCiphers(void);
-
-/* number of entries in the above table. */
-SSL_IMPORT const PRUint16 SSL_NumImplementedCiphers;
-
-/* the same as the above, but is a function */
-SSL_IMPORT PRUint16 SSL_GetNumImplementedCiphers(void);
-
-/* Macro to tell which ciphers in table are SSL2 vs SSL3/TLS. */
-#define SSL_IS_SSL2_CIPHER(which) (((which) & 0xfff0) == 0xff00)
-
-/*
-** Imports fd into SSL, returning a new socket. Copies SSL configuration
-** from model.
-*/
-SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
-
-/*
-** Imports fd into DTLS, returning a new socket. Copies DTLS configuration
-** from model.
-*/
-SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
-
-/*
-** Enable/disable an ssl mode
-**
-** SSL_SECURITY:
-** enable/disable use of SSL security protocol before connect
-**
-** SSL_SOCKS:
-** enable/disable use of socks before connect
-** (No longer supported).
-**
-** SSL_REQUEST_CERTIFICATE:
-** require a certificate during secure connect
-*/
-/* options */
-#define SSL_SECURITY 1 /* (on by default) */
-#define SSL_SOCKS 2 /* (off by default) */
-#define SSL_REQUEST_CERTIFICATE 3 /* (off by default) */
-#define SSL_HANDSHAKE_AS_CLIENT 5 /* force accept to hs as client */
- /* (off by default) */
-#define SSL_HANDSHAKE_AS_SERVER 6 /* force connect to hs as server */
- /* (off by default) */
-
-/* OBSOLETE: SSL v2 is obsolete and may be removed soon. */
-#define SSL_ENABLE_SSL2 7 /* enable ssl v2 (off by default) */
-
-/* OBSOLETE: See "SSL Version Range API" below for the replacement and a
-** description of the non-obvious semantics of using SSL_ENABLE_SSL3.
-*/
-#define SSL_ENABLE_SSL3 8 /* enable ssl v3 (on by default) */
-
-#define SSL_NO_CACHE 9 /* don't use the session cache */
- /* (off by default) */
-#define SSL_REQUIRE_CERTIFICATE 10 /* (SSL_REQUIRE_FIRST_HANDSHAKE */
- /* by default) */
-#define SSL_ENABLE_FDX 11 /* permit simultaneous read/write */
- /* (off by default) */
-
-/* OBSOLETE: SSL v2 compatible hellos are not accepted by some TLS servers
-** and cannot negotiate extensions. SSL v2 is obsolete. This option may be
-** removed soon.
-*/
-#define SSL_V2_COMPATIBLE_HELLO 12 /* send v3 client hello in v2 fmt */
- /* (off by default) */
-
-/* OBSOLETE: See "SSL Version Range API" below for the replacement and a
-** description of the non-obvious semantics of using SSL_ENABLE_TLS.
-*/
-#define SSL_ENABLE_TLS 13 /* enable TLS (on by default) */
-
-#define SSL_ROLLBACK_DETECTION 14 /* for compatibility, default: on */
-#define SSL_NO_STEP_DOWN 15 /* Disable export cipher suites */
- /* if step-down keys are needed. */
- /* default: off, generate */
- /* step-down keys if needed. */
-#define SSL_BYPASS_PKCS11 16 /* use PKCS#11 for pub key only */
-#define SSL_NO_LOCKS 17 /* Don't use locks for protection */
-#define SSL_ENABLE_SESSION_TICKETS 18 /* Enable TLS SessionTicket */
- /* extension (off by default) */
-#define SSL_ENABLE_DEFLATE 19 /* Enable TLS compression with */
- /* DEFLATE (off by default) */
-#define SSL_ENABLE_RENEGOTIATION 20 /* Values below (default: never) */
-#define SSL_REQUIRE_SAFE_NEGOTIATION 21 /* Peer must send Signaling */
- /* Cipher Suite Value (SCSV) or */
- /* Renegotiation Info (RI) */
- /* extension in ALL handshakes. */
- /* default: off */
-#define SSL_ENABLE_FALSE_START 22 /* Enable SSL false start (off by */
- /* default, applies only to */
- /* clients). False start is a */
-/* mode where an SSL client will start sending application data before */
-/* verifying the server's Finished message. This means that we could end up */
-/* sending data to an imposter. However, the data will be encrypted and */
-/* only the true server can derive the session key. Thus, so long as the */
-/* cipher isn't broken this is safe. Because of this, False Start will only */
-/* occur on RSA or DH ciphersuites where the cipher's key length is >= 80 */
-/* bits. The advantage of False Start is that it saves a round trip for */
-/* client-speaks-first protocols when performing a full handshake. */
-
-/* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks
- * on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting
- * non-empty application_data records into two records; the first record has
- * only the first byte of plaintext, and the second has the rest.
- *
- * This only prevents the attack in the sending direction; the connection may
- * still be vulnerable to such attacks if the peer does not implement a similar
- * countermeasure.
- *
- * This protection mechanism is on by default; the default can be overridden by
- * setting NSS_SSL_CBC_RANDOM_IV=0 in the environment prior to execution,
- * and/or by the application setting the option SSL_CBC_RANDOM_IV to PR_FALSE.
- *
- * The per-record IV in TLS 1.1 and later adds one block of overhead per
- * record, whereas this hack will add at least two blocks of overhead per
- * record, so TLS 1.1+ will always be more efficient.
- *
- * Other implementations (e.g. some versions of OpenSSL, in some
- * configurations) prevent the same attack by prepending an empty
- * application_data record to every application_data record they send; we do
- * not do that because some implementations cannot handle empty
- * application_data records. Also, we only split application_data records and
- * not other types of records, because some implementations will not accept
- * fragmented records of some other types (e.g. some versions of NSS do not
- * accept fragmented alerts).
- */
-#define SSL_CBC_RANDOM_IV 23
-#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */
-
-#ifdef SSL_DEPRECATED_FUNCTION
-/* Old deprecated function names */
-SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);
-SSL_IMPORT SECStatus SSL_EnableDefault(int option, PRBool on);
-#endif
-
-/* New function names */
-SSL_IMPORT SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 option, PRBool on);
-SSL_IMPORT SECStatus SSL_OptionGet(PRFileDesc *fd, PRInt32 option, PRBool *on);
-SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, PRBool on);
-SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on);
-SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle);
-
-/* SSLNextProtoCallback is called during the handshake for the client, when a
- * Next Protocol Negotiation (NPN) extension has been received from the server.
- * |protos| and |protosLen| define a buffer which contains the server's
- * advertisement. This data is guaranteed to be well formed per the NPN spec.
- * |protoOut| is a buffer provided by the caller, of length 255 (the maximum
- * allowed by the protocol). On successful return, the protocol to be announced
- * to the server will be in |protoOut| and its length in |*protoOutLen|.
- *
- * The callback must return SECFailure or SECSuccess (not SECWouldBlock).
- */
-typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)(
- void *arg,
- PRFileDesc *fd,
- const unsigned char* protos,
- unsigned int protosLen,
- unsigned char* protoOut,
- unsigned int* protoOutLen,
- unsigned int protoMaxOut);
-
-/* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol
- * Negotiation. It causes a client to advertise NPN. */
-SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd,
- SSLNextProtoCallback callback,
- void *arg);
-
-/* SSL_SetNextProtoNego can be used as an alternative to
- * SSL_SetNextProtoCallback. It also causes a client to advertise NPN and
- * installs a default callback function which selects the first supported
- * protocol in server-preference order. If no matching protocol is found it
- * selects the first supported protocol.
- *
- * The supported protocols are specified in |data| in wire-format (8-bit
- * length-prefixed). For example: "\010http/1.1\006spdy/2". */
-SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd,
- const unsigned char *data,
- unsigned int length);
-
-typedef enum SSLNextProtoState {
- SSL_NEXT_PROTO_NO_SUPPORT = 0, /* No peer support */
- SSL_NEXT_PROTO_NEGOTIATED = 1, /* Mutual agreement */
- SSL_NEXT_PROTO_NO_OVERLAP = 2 /* No protocol overlap found */
-} SSLNextProtoState;
-
-/* SSL_GetNextProto can be used in the HandshakeCallback or any time after
- * a handshake to retrieve the result of the Next Protocol negotiation.
- *
- * The length of the negotiated protocol, if any, is written into *bufLen.
- * If the negotiated protocol is longer than bufLenMax, then SECFailure is
- * returned. Otherwise, the negotiated protocol, if any, is written into buf,
- * and SECSuccess is returned. */
-SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd,
- SSLNextProtoState *state,
- unsigned char *buf,
- unsigned int *bufLen,
- unsigned int bufLenMax);
-
-/*
-** Control ciphers that SSL uses. If on is non-zero then the named cipher
-** is enabled, otherwise it is disabled.
-** The "cipher" values are defined in sslproto.h (the SSL_EN_* values).
-** EnableCipher records user preferences.
-** SetPolicy sets the policy according to the policy module.
-*/
-#ifdef SSL_DEPRECATED_FUNCTION
-/* Old deprecated function names */
-SSL_IMPORT SECStatus SSL_EnableCipher(long which, PRBool enabled);
-SSL_IMPORT SECStatus SSL_SetPolicy(long which, int policy);
-#endif
-
-/* New function names */
-SSL_IMPORT SECStatus SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 cipher, PRBool enabled);
-SSL_IMPORT SECStatus SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 cipher, PRBool *enabled);
-SSL_IMPORT SECStatus SSL_CipherPrefSetDefault(PRInt32 cipher, PRBool enabled);
-SSL_IMPORT SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled);
-SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy);
-SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
-
-/* SSL Version Range API
-**
-** This API should be used to control SSL 3.0 & TLS support instead of the
-** older SSL_Option* API; however, the SSL_Option* API MUST still be used to
-** control SSL 2.0 support. In this version of libssl, SSL 3.0 and TLS 1.0 are
-** enabled by default. Future versions of libssl may change which versions of
-** the protocol are enabled by default.
-**
-** The SSLProtocolVariant enum indicates whether the protocol is of type
-** stream or datagram. This must be provided to the functions that do not
-** take an fd. Functions which take an fd will get the variant from the fd,
-** which is typed.
-**
-** Using the new version range API in conjunction with the older
-** SSL_OptionSet-based API for controlling the enabled protocol versions may
-** cause unexpected results. Going forward, we guarantee only the following:
-**
-** SSL_OptionGet(SSL_ENABLE_TLS) will return PR_TRUE if *ANY* versions of TLS
-** are enabled.
-**
-** SSL_OptionSet(SSL_ENABLE_TLS, PR_FALSE) will disable *ALL* versions of TLS,
-** including TLS 1.0 and later.
-**
-** The above two properties provide compatibility for applications that use
-** SSL_OptionSet to implement the insecure fallback from TLS 1.x to SSL 3.0.
-**
-** SSL_OptionSet(SSL_ENABLE_TLS, PR_TRUE) will enable TLS 1.0, and may also
-** enable some later versions of TLS, if it is necessary to do so in order to
-** keep the set of enabled versions contiguous. For example, if TLS 1.2 is
-** enabled, then after SSL_OptionSet(SSL_ENABLE_TLS, PR_TRUE), TLS 1.0,
-** TLS 1.1, and TLS 1.2 will be enabled, and the call will have no effect on
-** whether SSL 3.0 is enabled. If no later versions of TLS are enabled at the
-** time SSL_OptionSet(SSL_ENABLE_TLS, PR_TRUE) is called, then no later
-** versions of TLS will be enabled by the call.
-**
-** SSL_OptionSet(SSL_ENABLE_SSL3, PR_FALSE) will disable SSL 3.0, and will not
-** change the set of TLS versions that are enabled.
-**
-** SSL_OptionSet(SSL_ENABLE_SSL3, PR_TRUE) will enable SSL 3.0, and may also
-** enable some versions of TLS if TLS 1.1 or later is enabled at the time of
-** the call, the same way SSL_OptionSet(SSL_ENABLE_TLS, PR_TRUE) works, in
-** order to keep the set of enabled versions contiguous.
-*/
-
-/* Returns, in |*vrange|, the range of SSL3/TLS versions supported for the
-** given protocol variant by the version of libssl linked-to at runtime.
-*/
-SSL_IMPORT SECStatus SSL_VersionRangeGetSupported(
- SSLProtocolVariant protocolVariant, SSLVersionRange *vrange);
-
-/* Returns, in |*vrange|, the range of SSL3/TLS versions enabled by default
-** for the given protocol variant.
-*/
-SSL_IMPORT SECStatus SSL_VersionRangeGetDefault(
- SSLProtocolVariant protocolVariant, SSLVersionRange *vrange);
-
-/* Sets the range of enabled-by-default SSL3/TLS versions for the given
-** protocol variant to |*vrange|.
-*/
-SSL_IMPORT SECStatus SSL_VersionRangeSetDefault(
- SSLProtocolVariant protocolVariant, const SSLVersionRange *vrange);
-
-/* Returns, in |*vrange|, the range of enabled SSL3/TLS versions for |fd|. */
-SSL_IMPORT SECStatus SSL_VersionRangeGet(PRFileDesc *fd,
- SSLVersionRange *vrange);
-
-/* Sets the range of enabled SSL3/TLS versions for |fd| to |*vrange|. */
-SSL_IMPORT SECStatus SSL_VersionRangeSet(PRFileDesc *fd,
- const SSLVersionRange *vrange);
-
-
-/* Values for "policy" argument to SSL_PolicySet */
-/* Values returned by SSL_CipherPolicyGet. */
-#define SSL_NOT_ALLOWED 0 /* or invalid or unimplemented */
-#define SSL_ALLOWED 1
-#define SSL_RESTRICTED 2 /* only with "Step-Up" certs. */
-
-/* Values for "on" with SSL_REQUIRE_CERTIFICATE. */
-#define SSL_REQUIRE_NEVER ((PRBool)0)
-#define SSL_REQUIRE_ALWAYS ((PRBool)1)
-#define SSL_REQUIRE_FIRST_HANDSHAKE ((PRBool)2)
-#define SSL_REQUIRE_NO_ERROR ((PRBool)3)
-
-/* Values for "on" with SSL_ENABLE_RENEGOTIATION */
-/* Never renegotiate at all. */
-#define SSL_RENEGOTIATE_NEVER ((PRBool)0)
-/* Renegotiate without restriction, whether or not the peer's client hello */
-/* bears the renegotiation info extension. Vulnerable, as in the past. */
-#define SSL_RENEGOTIATE_UNRESTRICTED ((PRBool)1)
-/* Only renegotiate if the peer's hello bears the TLS renegotiation_info */
-/* extension. This is safe renegotiation. */
-#define SSL_RENEGOTIATE_REQUIRES_XTN ((PRBool)2)
-/* Disallow unsafe renegotiation in server sockets only, but allow clients */
-/* to continue to renegotiate with vulnerable servers. */
-/* This value should only be used during the transition period when few */
-/* servers have been upgraded. */
-#define SSL_RENEGOTIATE_TRANSITIONAL ((PRBool)3)
-
-/*
-** Reset the handshake state for fd. This will make the complete SSL
-** handshake protocol execute from the ground up on the next i/o
-** operation.
-*/
-SSL_IMPORT SECStatus SSL_ResetHandshake(PRFileDesc *fd, PRBool asServer);
-
-/*
-** Force the handshake for fd to complete immediately. This blocks until
-** the complete SSL handshake protocol is finished.
-*/
-SSL_IMPORT SECStatus SSL_ForceHandshake(PRFileDesc *fd);
-
-/*
-** Same as above, but with an I/O timeout.
- */
-SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
- PRIntervalTime timeout);
-
-/*
-** Query security status of socket. *on is set to one if security is
-** enabled. *keySize will contain the stream key size used. *issuer will
-** contain the RFC1485 verison of the name of the issuer of the
-** certificate at the other end of the connection. For a client, this is
-** the issuer of the server's certificate; for a server, this is the
-** issuer of the client's certificate (if any). Subject is the subject of
-** the other end's certificate. The pointers can be zero if the desired
-** data is not needed. All strings returned by this function are owned
-** by the caller, and need to be freed with PORT_Free.
-*/
-SSL_IMPORT SECStatus SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher,
- int *keySize, int *secretKeySize,
- char **issuer, char **subject);
-
-/* Values for "on" */
-#define SSL_SECURITY_STATUS_NOOPT -1
-#define SSL_SECURITY_STATUS_OFF 0
-#define SSL_SECURITY_STATUS_ON_HIGH 1
-#define SSL_SECURITY_STATUS_ON_LOW 2
-#define SSL_SECURITY_STATUS_FORTEZZA 3 /* NO LONGER SUPPORTED */
-
-/*
-** Return the certificate for our SSL peer. If the client calls this
-** it will always return the server's certificate. If the server calls
-** this, it may return NULL if client authentication is not enabled or
-** if the client had no certificate when asked.
-** "fd" the socket "file" descriptor
-*/
-SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
-
-/* SSL_PeerStapledOCSPResponses returns the OCSP responses that were provided
- * by the TLS server. The return value is a pointer to an internal SECItemArray
- * that contains the returned OCSP responses; it is only valid until the
- * callback function that calls SSL_PeerStapledOCSPResponses returns.
- *
- * If no OCSP responses were given by the server then the result will be empty.
- * If there was an error, then the result will be NULL.
- *
- * You must set the SSL_ENABLE_OCSP_STAPLING option to enable OCSP stapling.
- * to be provided by a server.
- *
- * libssl does not do any validation of the OCSP response itself; the
- * authenticate certificate hook is responsible for doing so. The default
- * authenticate certificate hook, SSL_AuthCertificate, does not implement
- * any OCSP stapling funtionality, but this may change in future versions.
- */
-SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd);
-
-/* SSL_SetStapledOCSPResponses stores an array of one or multiple OCSP responses
- * in the fd's data, which may be sent as part of a server side cert_status
- * handshake message.
- * If takeOwnership is false, the function will duplicate the responses.
- * If takeOwnership is true, the ownership of responses is transfered into the
- * SSL library, and the caller must stop using it.
- */
-SSL_IMPORT SECStatus
-SSL_SetStapledOCSPResponses(PRFileDesc *fd, SECItemArray *responses,
- PRBool takeOwnership);
-
-/*
-** Authenticate certificate hook. Called when a certificate comes in
-** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the
-** certificate.
-**
-** The authenticate certificate hook must return SECSuccess to indicate the
-** certificate is valid, SECFailure to indicate the certificate is invalid,
-** or SECWouldBlock if the application will authenticate the certificate
-** asynchronously. SECWouldBlock is only supported for non-blocking sockets.
-**
-** If the authenticate certificate hook returns SECFailure, then the bad cert
-** hook will be called. The bad cert handler is NEVER called if the
-** authenticate certificate hook returns SECWouldBlock. If the application
-** needs to handle and/or override a bad cert, it should do so before it
-** calls SSL_AuthCertificateComplete (modifying the error it passes to
-** SSL_AuthCertificateComplete as needed).
-**
-** See the documentation for SSL_AuthCertificateComplete for more information
-** about the asynchronous behavior that occurs when the authenticate
-** certificate hook returns SECWouldBlock.
-**
-** RFC 6066 says that clients should send the bad_certificate_status_response
-** alert when they encounter an error processing the stapled OCSP response.
-** libssl does not provide a way for the authenticate certificate hook to
-** indicate that an OCSP error (SEC_ERROR_OCSP_*) that it returns is an error
-** in the stapled OCSP response or an error in some other OCSP response.
-** Further, NSS does not provide a convenient way to control or determine
-** which OCSP response(s) were used to validate a certificate chain.
-** Consequently, the current version of libssl does not ever send the
-** bad_certificate_status_response alert. This may change in future releases.
-*/
-typedef SECStatus (PR_CALLBACK *SSLAuthCertificate)(void *arg, PRFileDesc *fd,
- PRBool checkSig,
- PRBool isServer);
-
-SSL_IMPORT SECStatus SSL_AuthCertificateHook(PRFileDesc *fd,
- SSLAuthCertificate f,
- void *arg);
-
-/* An implementation of the certificate authentication hook */
-SSL_IMPORT SECStatus SSL_AuthCertificate(void *arg, PRFileDesc *fd,
- PRBool checkSig, PRBool isServer);
-
-/*
- * Prototype for SSL callback to get client auth data from the application.
- * arg - application passed argument
- * caNames - pointer to distinguished names of CAs that the server likes
- * pRetCert - pointer to pointer to cert, for return of cert
- * pRetKey - pointer to key pointer, for return of key
- */
-typedef SECStatus (PR_CALLBACK *SSLGetClientAuthData)(void *arg,
- PRFileDesc *fd,
- CERTDistNames *caNames,
- CERTCertificate **pRetCert,/*return */
- SECKEYPrivateKey **pRetKey);/* return */
-
-/*
- * Set the client side callback for SSL to retrieve user's private key
- * and certificate.
- * fd - the file descriptor for the connection in question
- * f - the application's callback that delivers the key and cert
- * a - application specific data
- */
-SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
- SSLGetClientAuthData f, void *a);
-
-
-/*
-** SNI extension processing callback function.
-** It is called when SSL socket receives SNI extension in ClientHello message.
-** Upon this callback invocation, application is responsible to reconfigure the
-** socket with the data for a particular server name.
-** There are three potential outcomes of this function invocation:
-** * application does not recognize the name or the type and wants the
-** "unrecognized_name" alert be sent to the client. In this case the callback
-** function must return SSL_SNI_SEND_ALERT status.
-** * application does not recognize the name, but wants to continue with
-** the handshake using the current socket configuration. In this case,
-** no socket reconfiguration is needed and the function should return
-** SSL_SNI_CURRENT_CONFIG_IS_USED.
-** * application recognizes the name and reconfigures the socket with
-** appropriate certs, key, etc. There are many ways to reconfigure. NSS
-** provides SSL_ReconfigFD function that can be used to update the socket
-** data from model socket. To continue with the rest of the handshake, the
-** implementation function should return an index of a name it has chosen.
-** LibSSL will ignore any SNI extension received in a ClientHello message
-** if application does not register a SSLSNISocketConfig callback.
-** Each type field of SECItem indicates the name type.
-** NOTE: currently RFC3546 defines only one name type: sni_host_name.
-** Client is allowed to send only one name per known type. LibSSL will
-** send an "unrecognized_name" alert if SNI extension name list contains more
-** then one name of a type.
-*/
-typedef PRInt32 (PR_CALLBACK *SSLSNISocketConfig)(PRFileDesc *fd,
- const SECItem *srvNameArr,
- PRUint32 srvNameArrSize,
- void *arg);
-
-/*
-** SSLSNISocketConfig should return an index within 0 and srvNameArrSize-1
-** when it has reconfigured the socket fd to use certs and keys, etc
-** for a specific name. There are two other allowed return values. One
-** tells libSSL to use the default cert and key. The other tells libSSL
-** to send the "unrecognized_name" alert. These values are:
-**/
-#define SSL_SNI_CURRENT_CONFIG_IS_USED -1
-#define SSL_SNI_SEND_ALERT -2
-
-/*
-** Set application implemented SNISocketConfig callback.
-*/
-SSL_IMPORT SECStatus SSL_SNISocketConfigHook(PRFileDesc *fd,
- SSLSNISocketConfig f,
- void *arg);
-
-/*
-** Reconfigure fd SSL socket with model socket parameters. Sets
-** server certs and keys, list of trust anchor, socket options
-** and all SSL socket call backs and parameters.
-*/
-SSL_IMPORT PRFileDesc *SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd);
-
-/*
- * Set the client side argument for SSL to retrieve PKCS #11 pin.
- * fd - the file descriptor for the connection in question
- * a - pkcs11 application specific data
- */
-SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a);
-
-/*
-** This is a callback for dealing with server certs that are not authenticated
-** by the client. The client app can decide that it actually likes the
-** cert by some external means and restart the connection.
-**
-** The bad cert hook must return SECSuccess to override the result of the
-** authenticate certificate hook, SECFailure if the certificate should still be
-** considered invalid, or SECWouldBlock if the application will authenticate
-** the certificate asynchronously. SECWouldBlock is only supported for
-** non-blocking sockets.
-**
-** See the documentation for SSL_AuthCertificateComplete for more information
-** about the asynchronous behavior that occurs when the bad cert hook returns
-** SECWouldBlock.
-*/
-typedef SECStatus (PR_CALLBACK *SSLBadCertHandler)(void *arg, PRFileDesc *fd);
-SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f,
- void *arg);
-
-/*
-** Configure SSL socket for running a secure server. Needs the
-** certificate for the server and the servers private key. The arguments
-** are copied.
-*/
-SSL_IMPORT SECStatus SSL_ConfigSecureServer(
- PRFileDesc *fd, CERTCertificate *cert,
- SECKEYPrivateKey *key, SSLKEAType kea);
-
-/*
-** Allows SSL socket configuration with caller-supplied certificate chain.
-** If certChainOpt is NULL, tries to find one.
-*/
-SSL_IMPORT SECStatus
-SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
- const CERTCertificateList *certChainOpt,
- SECKEYPrivateKey *key, SSLKEAType kea);
-
-/*
-** Configure a secure server's session-id cache. Define the maximum number
-** of entries in the cache, the longevity of the entires, and the directory
-** where the cache files will be placed. These values can be zero, and
-** if so, the implementation will choose defaults.
-** This version of the function is for use in applications that have only one
-** process that uses the cache (even if that process has multiple threads).
-*/
-SSL_IMPORT SECStatus SSL_ConfigServerSessionIDCache(int maxCacheEntries,
- PRUint32 timeout,
- PRUint32 ssl3_timeout,
- const char * directory);
-
-/* Configure a secure server's session-id cache. Depends on value of
- * enableMPCache, configures malti-proc or single proc cache. */
-SSL_IMPORT SECStatus SSL_ConfigServerSessionIDCacheWithOpt(
- PRUint32 timeout,
- PRUint32 ssl3_timeout,
- const char * directory,
- int maxCacheEntries,
- int maxCertCacheEntries,
- int maxSrvNameCacheEntries,
- PRBool enableMPCache);
-
-/*
-** Like SSL_ConfigServerSessionIDCache, with one important difference.
-** If the application will run multiple processes (as opposed to, or in
-** addition to multiple threads), then it must call this function, instead
-** of calling SSL_ConfigServerSessionIDCache().
-** This has nothing to do with the number of processORs, only processEs.
-** This function sets up a Server Session ID (SID) cache that is safe for
-** access by multiple processes on the same system.
-*/
-SSL_IMPORT SECStatus SSL_ConfigMPServerSIDCache(int maxCacheEntries,
- PRUint32 timeout,
- PRUint32 ssl3_timeout,
- const char * directory);
-
-/* Get and set the configured maximum number of mutexes used for the
-** server's store of SSL sessions. This value is used by the server
-** session ID cache initialization functions shown above. Note that on
-** some platforms, these mutexes are actually implemented with POSIX
-** semaphores, or with unnamed pipes. The default value varies by platform.
-** An attempt to set a too-low maximum will return an error and the
-** configured value will not be changed.
-*/
-SSL_IMPORT PRUint32 SSL_GetMaxServerCacheLocks(void);
-SSL_IMPORT SECStatus SSL_SetMaxServerCacheLocks(PRUint32 maxLocks);
-
-/* environment variable set by SSL_ConfigMPServerSIDCache, and queried by
- * SSL_InheritMPServerSIDCache when envString is NULL.
- */
-#define SSL_ENV_VAR_NAME "SSL_INHERITANCE"
-
-/* called in child to inherit SID Cache variables.
- * If envString is NULL, this function will use the value of the environment
- * variable "SSL_INHERITANCE", otherwise the string value passed in will be
- * used.
- */
-SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
-
-/*
-** Set the callback on a particular socket that gets called when we finish
-** performing a handshake.
-*/
-typedef void (PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
- void *client_data);
-SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
- SSLHandshakeCallback cb, void *client_data);
-
-/*
-** For the server, request a new handshake. For the client, begin a new
-** handshake. If flushCache is non-zero, the SSL3 cache entry will be
-** flushed first, ensuring that a full SSL handshake will be done.
-** If flushCache is zero, and an SSL connection is established, it will
-** do the much faster session restart handshake. This will change the
-** session keys without doing another private key operation.
-*/
-SSL_IMPORT SECStatus SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache);
-
-/*
-** Same as above, but with an I/O timeout.
- */
-SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
- PRBool flushCache,
- PRIntervalTime timeout);
-
-
-#ifdef SSL_DEPRECATED_FUNCTION
-/* deprecated!
-** For the server, request a new handshake. For the client, begin a new
-** handshake. Flushes SSL3 session cache entry first, ensuring that a
-** full handshake will be done.
-** This call is equivalent to SSL_ReHandshake(fd, PR_TRUE)
-*/
-SSL_IMPORT SECStatus SSL_RedoHandshake(PRFileDesc *fd);
-#endif
-
-/*
- * Allow the application to pass a URL or hostname into the SSL library.
- */
-SSL_IMPORT SECStatus SSL_SetURL(PRFileDesc *fd, const char *url);
-
-/*
- * Allow an application to define a set of trust anchors for peer
- * cert validation.
- */
-SSL_IMPORT SECStatus SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *list);
-
-/*
-** Return the number of bytes that SSL has waiting in internal buffers.
-** Return 0 if security is not enabled.
-*/
-SSL_IMPORT int SSL_DataPending(PRFileDesc *fd);
-
-/*
-** Invalidate the SSL session associated with fd.
-*/
-SSL_IMPORT SECStatus SSL_InvalidateSession(PRFileDesc *fd);
-
-/*
-** Return a SECItem containing the SSL session ID associated with the fd.
-*/
-SSL_IMPORT SECItem *SSL_GetSessionID(PRFileDesc *fd);
-
-/*
-** Clear out the client's SSL session cache, not the server's session cache.
-*/
-SSL_IMPORT void SSL_ClearSessionCache(void);
-
-/*
-** Close the server's SSL session cache.
-*/
-SSL_IMPORT SECStatus SSL_ShutdownServerSessionIDCache(void);
-
-/*
-** Set peer information so we can correctly look up SSL session later.
-** You only have to do this if you're tunneling through a proxy.
-*/
-SSL_IMPORT SECStatus SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID);
-
-/*
-** Reveal the security information for the peer.
-*/
-SSL_IMPORT CERTCertificate * SSL_RevealCert(PRFileDesc * socket);
-SSL_IMPORT void * SSL_RevealPinArg(PRFileDesc * socket);
-SSL_IMPORT char * SSL_RevealURL(PRFileDesc * socket);
-
-/* This callback may be passed to the SSL library via a call to
- * SSL_GetClientAuthDataHook() for each SSL client socket.
- * It will be invoked when SSL needs to know what certificate and private key
- * (if any) to use to respond to a request for client authentication.
- * If arg is non-NULL, it is a pointer to a NULL-terminated string containing
- * the nickname of the cert/key pair to use.
- * If arg is NULL, this function will search the cert and key databases for
- * a suitable match and send it if one is found.
- */
-SSL_IMPORT SECStatus
-NSS_GetClientAuthData(void * arg,
- PRFileDesc * socket,
- struct CERTDistNamesStr * caNames,
- struct CERTCertificateStr ** pRetCert,
- struct SECKEYPrivateKeyStr **pRetKey);
-
-/*
-** Configure DTLS-SRTP (RFC 5764) cipher suite preferences.
-** Input is a list of ciphers in descending preference order and a length
-** of the list. As a side effect, this causes the use_srtp extension to be
-** negotiated.
-**
-** Invalid or unimplemented cipher suites in |ciphers| are ignored. If at
-** least one cipher suite in |ciphers| is implemented, returns SECSuccess.
-** Otherwise returns SECFailure.
-*/
-SSL_IMPORT SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
- const PRUint16 *ciphers,
- unsigned int numCiphers);
-
-/*
-** Get the selected DTLS-SRTP cipher suite (if any).
-** To be called after the handshake completes.
-** Returns SECFailure if not negotiated.
-*/
-SSL_IMPORT SECStatus SSL_GetSRTPCipher(PRFileDesc *fd,
- PRUint16 *cipher);
-
-/*
- * Look to see if any of the signers in the cert chain for "cert" are found
- * in the list of caNames.
- * Returns SECSuccess if so, SECFailure if not.
- * Used by NSS_GetClientAuthData. May be used by other callback functions.
- */
-SSL_IMPORT SECStatus NSS_CmpCertChainWCANames(CERTCertificate *cert,
- CERTDistNames *caNames);
-
-/*
- * Returns key exchange type of the keys in an SSL server certificate.
- */
-SSL_IMPORT SSLKEAType NSS_FindCertKEAType(CERTCertificate * cert);
-
-/* Set cipher policies to a predefined Domestic (U.S.A.) policy.
- * This essentially enables all supported ciphers.
- */
-SSL_IMPORT SECStatus NSS_SetDomesticPolicy(void);
-
-/* Set cipher policies to a predefined Policy that is exportable from the USA
- * according to present U.S. policies as we understand them.
- * See documentation for the list.
- * Note that your particular application program may be able to obtain
- * an export license with more or fewer capabilities than those allowed
- * by this function. In that case, you should use SSL_SetPolicy()
- * to explicitly allow those ciphers you may legally export.
- */
-SSL_IMPORT SECStatus NSS_SetExportPolicy(void);
-
-/* Set cipher policies to a predefined Policy that is exportable from the USA
- * according to present U.S. policies as we understand them, and that the
- * nation of France will permit to be imported into their country.
- * See documentation for the list.
- */
-SSL_IMPORT SECStatus NSS_SetFrancePolicy(void);
-
-SSL_IMPORT SSL3Statistics * SSL_GetStatistics(void);
-
-/* Report more information than SSL_SecurityStatus.
-** Caller supplies the info struct. Function fills it in.
-*/
-SSL_IMPORT SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info,
- PRUintn len);
-SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
- SSLCipherSuiteInfo *info, PRUintn len);
-
-/* Returnes negotiated through SNI host info. */
-SSL_IMPORT SECItem *SSL_GetNegotiatedHostInfo(PRFileDesc *fd);
-
-/* Export keying material according to RFC 5705.
-** fd must correspond to a TLS 1.0 or higher socket and out must
-** already be allocated. If hasContext is false, it uses the no-context
-** construction from the RFC and ignores the context and contextLen
-** arguments.
-*/
-SSL_IMPORT SECStatus SSL_ExportKeyingMaterial(PRFileDesc *fd,
- const char *label,
- unsigned int labelLen,
- PRBool hasContext,
- const unsigned char *context,
- unsigned int contextLen,
- unsigned char *out,
- unsigned int outLen);
-
-/*
-** Return a new reference to the certificate that was most recently sent
-** to the peer on this SSL/TLS connection, or NULL if none has been sent.
-*/
-SSL_IMPORT CERTCertificate * SSL_LocalCertificate(PRFileDesc *fd);
-
-/* Test an SSL configuration to see if SSL_BYPASS_PKCS11 can be turned on.
-** Check the key exchange algorithm for each cipher in the list to see if
-** a master secret key can be extracted after being derived with the mechanism
-** required by the protocolmask argument. If the KEA will use keys from the
-** specified cert make sure the extract operation is attempted from the slot
-** where the private key resides.
-** If MS can be extracted for all ciphers, (*pcanbypass) is set to TRUE and
-** SECSuccess is returned. In all other cases but one (*pcanbypass) is
-** set to FALSE and SECFailure is returned.
-** In that last case Derive() has been called successfully but the MS is null,
-** CanBypass sets (*pcanbypass) to FALSE and returns SECSuccess indicating the
-** arguments were all valid but the slot cannot be bypassed.
-**
-** Note: A TRUE return code from CanBypass means "Your configuration will perform
-** NO WORSE with the bypass enabled than without"; it does NOT mean that every
-** cipher suite listed will work properly with the selected protocols.
-**
-** Caveat: If export cipher suites are included in the argument list Canbypass
-** will return FALSE.
-**/
-
-/* protocol mask bits */
-#define SSL_CBP_SSL3 0x0001 /* test SSL v3 mechanisms */
-#define SSL_CBP_TLS1_0 0x0002 /* test TLS v1.0 mechanisms */
-
-SSL_IMPORT SECStatus SSL_CanBypass(CERTCertificate *cert,
- SECKEYPrivateKey *privKey,
- PRUint32 protocolmask,
- PRUint16 *ciphers, int nciphers,
- PRBool *pcanbypass, void *pwArg);
-
-/*
-** Did the handshake with the peer negotiate the given extension?
-** Output parameter valid only if function returns SECSuccess
-*/
-SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
- SSLExtensionType extId,
- PRBool *yes);
-
-/*
-** How long should we wait before retransmitting the next flight of
-** the DTLS handshake? Returns SECFailure if not DTLS or not in a
-** handshake.
-*/
-SSL_IMPORT SECStatus DTLS_GetHandshakeTimeout(PRFileDesc *socket,
- PRIntervalTime *timeout);
-
-/*
- * Return a boolean that indicates whether the underlying library
- * will perform as the caller expects.
- *
- * The only argument is a string, which should be the version
- * identifier of the NSS library. That string will be compared
- * against a string that represents the actual build version of
- * the SSL library.
- */
-extern PRBool NSSSSL_VersionCheck(const char *importedVersion);
-
-/*
- * Returns a const string of the SSL library version.
- */
-extern const char *NSSSSL_GetVersion(void);
-
-/* Restart an SSL connection that was paused to do asynchronous certificate
- * chain validation (when the auth certificate hook or bad cert handler
- * returned SECWouldBlock).
- *
- * This function only works for non-blocking sockets; Do not use it for
- * blocking sockets. Currently, this function works only for the client role of
- * a connection; it does not work for the server role.
- *
- * The application must call SSL_AuthCertificateComplete with 0 as the value of
- * the error parameter after it has successfully validated the peer's
- * certificate, in order to continue the SSL handshake.
- *
- * The application may call SSL_AuthCertificateComplete with a non-zero value
- * for error (e.g. SEC_ERROR_REVOKED_CERTIFICATE) when certificate validation
- * fails, before it closes the connection. If the application does so, an
- * alert corresponding to the error (e.g. certificate_revoked) will be sent to
- * the peer. See the source code of the internal function
- * ssl3_SendAlertForCertError for the current mapping of error to alert. This
- * mapping may change in future versions of libssl.
- *
- * This function will not complete the entire handshake. The application must
- * call SSL_ForceHandshake, PR_Recv, PR_Send, etc. after calling this function
- * to force the handshake to complete.
- *
- * On the first handshake of a connection, libssl will wait for the peer's
- * certificate to be authenticated before calling the handshake callback,
- * sending a client certificate, sending any application data, or returning
- * any application data to the application. On subsequent (renegotiation)
- * handshakes, libssl will block the handshake unconditionally while the
- * certificate is being validated.
- *
- * libssl may send and receive handshake messages while waiting for the
- * application to call SSL_AuthCertificateComplete, and it may call other
- * callbacks (e.g, the client auth data hook) before
- * SSL_AuthCertificateComplete has been called.
- *
- * An application that uses this asynchronous mechanism will usually have lower
- * handshake latency if it has to do public key operations on the certificate
- * chain and/or CRL/OCSP/cert fetching during the authentication, especially if
- * it does so in parallel on another thread. However, if the application can
- * authenticate the peer's certificate quickly then it may be more efficient
- * to use the synchronous mechanism (i.e. returning SECFailure/SECSuccess
- * instead of SECWouldBlock from the authenticate certificate hook).
- *
- * Be careful about converting an application from synchronous cert validation
- * to asynchronous certificate validation. A naive conversion is likely to
- * result in deadlocks; e.g. the application will wait in PR_Poll for network
- * I/O on the connection while all network I/O on the connection is blocked
- * waiting for this function to be called.
- *
- * Returns SECFailure on failure, SECSuccess on success. Never returns
- * SECWouldBlock. Note that SSL_AuthCertificateComplete will (usually) return
- * SECSuccess; do not interpret the return value of SSL_AuthCertificateComplete
- * as an indicator of whether it is OK to continue using the connection. For
- * example, SSL_AuthCertificateComplete(fd, SEC_ERROR_REVOKED_CERTIFICATE) will
- * return SECSuccess (normally), but that does not mean that the application
- * should continue using the connection. If the application passes a non-zero
- * value for second argument (error), or if SSL_AuthCertificateComplete returns
- * anything other than SECSuccess, then the application should close the
- * connection.
- */
-SSL_IMPORT SECStatus SSL_AuthCertificateComplete(PRFileDesc *fd,
- PRErrorCode error);
-SEC_END_PROTOS
-
-#endif /* __ssl_h_ */
diff --git a/security/nss/lib/ssl/ssl.rc b/security/nss/lib/ssl/ssl.rc
deleted file mode 100644
index 809a07e5f..000000000
--- a/security/nss/lib/ssl/ssl.rc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nss.h"
-#include <winver.h>
-
-#define MY_LIBNAME "ssl"
-#define MY_FILEDESCRIPTION "NSS SSL Library"
-
-#define STRINGIZE(x) #x
-#define STRINGIZE2(x) STRINGIZE(x)
-#define NSS_VMAJOR_STR STRINGIZE2(NSS_VMAJOR)
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if NSS_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME NSS_VMAJOR_STR
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
- PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Mozilla Foundation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", NSS_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", NSS_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
deleted file mode 100644
index 1971d2087..000000000
--- a/security/nss/lib/ssl/ssl3con.c
+++ /dev/null
@@ -1,10825 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * SSL3 Protocol
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
-
-#include "cert.h"
-#include "ssl.h"
-#include "cryptohi.h" /* for DSAU_ stuff */
-#include "keyhi.h"
-#include "secder.h"
-#include "secitem.h"
-
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "sslerr.h"
-#include "prtime.h"
-#include "prinrval.h"
-#include "prerror.h"
-#include "pratom.h"
-#include "prthread.h"
-
-#include "pk11func.h"
-#include "secmod.h"
-#ifndef NO_PKCS11_BYPASS
-#include "blapi.h"
-#endif
-
-#include <stdio.h>
-#ifdef NSS_ENABLE_ZLIB
-#include "zlib.h"
-#endif
-
-#ifndef PK11_SETATTRS
-#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
- (x)->pValue=(v); (x)->ulValueLen = (l);
-#endif
-
-static void ssl3_CleanupPeerCerts(sslSocket *ss);
-static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
- PK11SlotInfo * serverKeySlot);
-static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms);
-static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss);
-static SECStatus ssl3_HandshakeFailure( sslSocket *ss);
-static SECStatus ssl3_InitState( sslSocket *ss);
-static SECStatus ssl3_SendCertificate( sslSocket *ss);
-static SECStatus ssl3_SendCertificateStatus( sslSocket *ss);
-static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
-static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
-static SECStatus ssl3_SendNextProto( sslSocket *ss);
-static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags);
-static SECStatus ssl3_SendServerHello( sslSocket *ss);
-static SECStatus ssl3_SendServerHelloDone( sslSocket *ss);
-static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss);
-static SECStatus ssl3_NewHandshakeHashes( sslSocket *ss);
-static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss,
- const unsigned char *b,
- unsigned int l);
-static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
-
-static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen,
- int maxOutputLen, const unsigned char *input,
- int inputLen);
-
-#define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */
-#define MIN_SEND_BUF_LENGTH 4000
-
-/* This list of SSL3 cipher suites is sorted in descending order of
- * precedence (desirability). It only includes cipher suites we implement.
- * This table is modified by SSL3_SetPolicy(). The ordering of cipher suites
- * in this table must match the ordering in SSL_ImplementedCiphers (sslenum.c)
- */
-static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
- /* cipher_suite policy enabled is_present*/
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
- { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
-
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
- { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { TLS_RSA_WITH_SEED_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
- { SSL_RSA_WITH_RC4_128_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
- { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
-
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
- { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE},
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
- { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
-
-
- { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
- { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
-
- { SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
- { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
-
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDH_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
- { TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
- { SSL_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
- { SSL_RSA_WITH_NULL_MD5, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
-
-};
-
-/* This list of SSL3 compression methods is sorted in descending order of
- * precedence (desirability). It only includes compression methods we
- * implement.
- */
-static const /*SSLCompressionMethod*/ uint8 compressions [] = {
-#ifdef NSS_ENABLE_ZLIB
- ssl_compression_deflate,
-#endif
- ssl_compression_null
-};
-
-static const int compressionMethodsCount =
- sizeof(compressions) / sizeof(compressions[0]);
-
-/* compressionEnabled returns true iff the compression algorithm is enabled
- * for the given SSL socket. */
-static PRBool
-compressionEnabled(sslSocket *ss, SSLCompressionMethod compression)
-{
- switch (compression) {
- case ssl_compression_null:
- return PR_TRUE; /* Always enabled */
-#ifdef NSS_ENABLE_ZLIB
- case ssl_compression_deflate:
- return ss->opt.enableDeflate;
-#endif
- default:
- return PR_FALSE;
- }
-}
-
-static const /*SSL3ClientCertificateType */ uint8 certificate_types [] = {
- ct_RSA_sign,
- ct_DSS_sign,
-#ifdef NSS_ENABLE_ECC
- ct_ECDSA_sign,
-#endif /* NSS_ENABLE_ECC */
-};
-
-#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
-
-
-/* This global item is used only in servers. It is is initialized by
-** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
-*/
-CERTDistNames *ssl3_server_ca_list = NULL;
-static SSL3Statistics ssl3stats;
-
-/* indexed by SSL3BulkCipher */
-static const ssl3BulkCipherDef bulk_cipher_defs[] = {
- /* cipher calg keySz secretSz type ivSz BlkSz keygen */
- {cipher_null, calg_null, 0, 0, type_stream, 0, 0, kg_null},
- {cipher_rc4, calg_rc4, 16, 16, type_stream, 0, 0, kg_strong},
- {cipher_rc4_40, calg_rc4, 16, 5, type_stream, 0, 0, kg_export},
- {cipher_rc4_56, calg_rc4, 16, 7, type_stream, 0, 0, kg_export},
- {cipher_rc2, calg_rc2, 16, 16, type_block, 8, 8, kg_strong},
- {cipher_rc2_40, calg_rc2, 16, 5, type_block, 8, 8, kg_export},
- {cipher_des, calg_des, 8, 8, type_block, 8, 8, kg_strong},
- {cipher_3des, calg_3des, 24, 24, type_block, 8, 8, kg_strong},
- {cipher_des40, calg_des, 8, 5, type_block, 8, 8, kg_export},
- {cipher_idea, calg_idea, 16, 16, type_block, 8, 8, kg_strong},
- {cipher_aes_128, calg_aes, 16, 16, type_block, 16,16, kg_strong},
- {cipher_aes_256, calg_aes, 32, 32, type_block, 16,16, kg_strong},
- {cipher_camellia_128, calg_camellia,16, 16, type_block, 16,16, kg_strong},
- {cipher_camellia_256, calg_camellia,32, 32, type_block, 16,16, kg_strong},
- {cipher_seed, calg_seed, 16, 16, type_block, 16,16, kg_strong},
- {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, kg_null},
-};
-
-static const ssl3KEADef kea_defs[] =
-{ /* indexed by SSL3KeyExchangeAlgorithm */
- /* kea exchKeyType signKeyType is_limited limit tls_keygen */
- {kea_null, kt_null, sign_null, PR_FALSE, 0, PR_FALSE},
- {kea_rsa, kt_rsa, sign_rsa, PR_FALSE, 0, PR_FALSE},
- {kea_rsa_export, kt_rsa, sign_rsa, PR_TRUE, 512, PR_FALSE},
- {kea_rsa_export_1024,kt_rsa, sign_rsa, PR_TRUE, 1024, PR_FALSE},
- {kea_dh_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE},
- {kea_dh_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE},
- {kea_dh_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE},
- {kea_dh_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE},
- {kea_dhe_dss, kt_dh, sign_dsa, PR_FALSE, 0, PR_FALSE},
- {kea_dhe_dss_export, kt_dh, sign_dsa, PR_TRUE, 512, PR_FALSE},
- {kea_dhe_rsa, kt_dh, sign_rsa, PR_FALSE, 0, PR_FALSE},
- {kea_dhe_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE},
- {kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE},
- {kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE},
- {kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE },
-#ifdef NSS_ENABLE_ECC
- {kea_ecdh_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE},
- {kea_ecdhe_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE},
- {kea_ecdh_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE},
- {kea_ecdhe_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE},
- {kea_ecdh_anon, kt_ecdh, sign_null, PR_FALSE, 0, PR_FALSE},
-#endif /* NSS_ENABLE_ECC */
-};
-
-/* must use ssl_LookupCipherSuiteDef to access */
-static const ssl3CipherSuiteDef cipher_suite_defs[] =
-{
-/* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg */
-
- {SSL_NULL_WITH_NULL_NULL, cipher_null, mac_null, kea_null},
- {SSL_RSA_WITH_NULL_MD5, cipher_null, mac_md5, kea_rsa},
- {SSL_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_rsa},
- {SSL_RSA_EXPORT_WITH_RC4_40_MD5,cipher_rc4_40, mac_md5, kea_rsa_export},
- {SSL_RSA_WITH_RC4_128_MD5, cipher_rc4, mac_md5, kea_rsa},
- {SSL_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_rsa},
- {SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- cipher_rc2_40, mac_md5, kea_rsa_export},
-#if 0 /* not implemented */
- {SSL_RSA_WITH_IDEA_CBC_SHA, cipher_idea, mac_sha, kea_rsa},
- {SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_rsa_export},
-#endif
- {SSL_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa},
- {SSL_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa},
- {SSL_DHE_DSS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_dss},
- {SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- cipher_3des, mac_sha, kea_dhe_dss},
- {TLS_DHE_DSS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_dhe_dss},
-#if 0 /* not implemented */
- {SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_dss_export},
- {SSL_DH_DSS_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_dss},
- {SSL_DH_DSS_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_dss},
- {SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_rsa_export},
- {SSL_DH_RSA_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_rsa},
- {SSL_DH_RSA_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_rsa},
- {SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_dss_export},
- {SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_rsa_export},
-#endif
- {SSL_DHE_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_dhe_rsa},
- {SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- cipher_3des, mac_sha, kea_dhe_rsa},
-#if 0
- {SSL_DH_ANON_EXPORT_RC4_40_MD5, cipher_rc4_40, mac_md5, kea_dh_anon_export},
- {SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA,
- cipher_des40, mac_sha, kea_dh_anon_export},
- {SSL_DH_ANON_DES_CBC_SHA, cipher_des, mac_sha, kea_dh_anon},
- {SSL_DH_ANON_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_anon},
-#endif
-
-
-/* New TLS cipher suites */
- {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa},
- {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_dss},
- {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_rsa},
- {TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_rsa},
- {TLS_DHE_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_dss},
- {TLS_DHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_rsa},
-#if 0
- {TLS_DH_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_dss},
- {TLS_DH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_rsa},
- {TLS_DH_ANON_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_anon},
- {TLS_DH_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_dss},
- {TLS_DH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_rsa},
- {TLS_DH_ANON_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_anon},
-#endif
-
- {TLS_RSA_WITH_SEED_CBC_SHA, cipher_seed, mac_sha, kea_rsa},
-
- {TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, cipher_camellia_128, mac_sha, kea_rsa},
- {TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
- cipher_camellia_128, mac_sha, kea_dhe_dss},
- {TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
- cipher_camellia_128, mac_sha, kea_dhe_rsa},
- {TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, cipher_camellia_256, mac_sha, kea_rsa},
- {TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
- cipher_camellia_256, mac_sha, kea_dhe_dss},
- {TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
- cipher_camellia_256, mac_sha, kea_dhe_rsa},
-
- {TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
- cipher_des, mac_sha,kea_rsa_export_1024},
- {TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
- cipher_rc4_56, mac_sha,kea_rsa_export_1024},
-
- {SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa_fips},
- {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa_fips},
-
-#ifdef NSS_ENABLE_ECC
- {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa},
- {TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa},
- {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_ecdsa},
- {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_ecdsa},
- {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_ecdsa},
-
- {TLS_ECDHE_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_ecdsa},
- {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_ecdsa},
- {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_ecdsa},
- {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa},
- {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_ecdsa},
-
- {TLS_ECDH_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_rsa},
- {TLS_ECDH_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_rsa},
- {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_rsa},
- {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_rsa},
- {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_rsa},
-
- {TLS_ECDHE_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_rsa},
- {TLS_ECDHE_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_rsa},
- {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_rsa},
- {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_rsa},
- {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_rsa},
-
-#if 0
- {TLS_ECDH_anon_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_anon},
- {TLS_ECDH_anon_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_anon},
- {TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_anon},
- {TLS_ECDH_anon_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_anon},
- {TLS_ECDH_anon_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_anon},
-#endif
-#endif /* NSS_ENABLE_ECC */
-};
-
-static const CK_MECHANISM_TYPE kea_alg_defs[] = {
- 0x80000000L,
- CKM_RSA_PKCS,
- CKM_DH_PKCS_DERIVE,
- CKM_KEA_KEY_DERIVE,
- CKM_ECDH1_DERIVE
-};
-
-typedef struct SSLCipher2MechStr {
- SSLCipherAlgorithm calg;
- CK_MECHANISM_TYPE cmech;
-} SSLCipher2Mech;
-
-/* indexed by type SSLCipherAlgorithm */
-static const SSLCipher2Mech alg2Mech[] = {
- /* calg, cmech */
- { calg_null , (CK_MECHANISM_TYPE)0x80000000L },
- { calg_rc4 , CKM_RC4 },
- { calg_rc2 , CKM_RC2_CBC },
- { calg_des , CKM_DES_CBC },
- { calg_3des , CKM_DES3_CBC },
- { calg_idea , CKM_IDEA_CBC },
- { calg_fortezza , CKM_SKIPJACK_CBC64 },
- { calg_aes , CKM_AES_CBC },
- { calg_camellia , CKM_CAMELLIA_CBC },
- { calg_seed , CKM_SEED_CBC },
-/* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */
-};
-
-#define mmech_null (CK_MECHANISM_TYPE)0x80000000L
-#define mmech_md5 CKM_SSL3_MD5_MAC
-#define mmech_sha CKM_SSL3_SHA1_MAC
-#define mmech_md5_hmac CKM_MD5_HMAC
-#define mmech_sha_hmac CKM_SHA_1_HMAC
-
-static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */
- /* mac mmech pad_size mac_size */
- { mac_null, mmech_null, 0, 0 },
- { mac_md5, mmech_md5, 48, MD5_LENGTH },
- { mac_sha, mmech_sha, 40, SHA1_LENGTH},
- {hmac_md5, mmech_md5_hmac, 48, MD5_LENGTH },
- {hmac_sha, mmech_sha_hmac, 40, SHA1_LENGTH},
-};
-
-/* indexed by SSL3BulkCipher */
-const char * const ssl3_cipherName[] = {
- "NULL",
- "RC4",
- "RC4-40",
- "RC4-56",
- "RC2-CBC",
- "RC2-CBC-40",
- "DES-CBC",
- "3DES-EDE-CBC",
- "DES-CBC-40",
- "IDEA-CBC",
- "AES-128",
- "AES-256",
- "Camellia-128",
- "Camellia-256",
- "SEED-CBC",
- "missing"
-};
-
-#ifdef NSS_ENABLE_ECC
-/* The ECCWrappedKeyInfo structure defines how various pieces of
- * information are laid out within wrappedSymmetricWrappingkey
- * for ECDH key exchange. Since wrappedSymmetricWrappingkey is
- * a 512-byte buffer (see sslimpl.h), the variable length field
- * in ECCWrappedKeyInfo can be at most (512 - 8) = 504 bytes.
- *
- * XXX For now, NSS only supports named elliptic curves of size 571 bits
- * or smaller. The public value will fit within 145 bytes and EC params
- * will fit within 12 bytes. We'll need to revisit this when NSS
- * supports arbitrary curves.
- */
-#define MAX_EC_WRAPPED_KEY_BUFLEN 504
-
-typedef struct ECCWrappedKeyInfoStr {
- PRUint16 size; /* EC public key size in bits */
- PRUint16 encodedParamLen; /* length (in bytes) of DER encoded EC params */
- PRUint16 pubValueLen; /* length (in bytes) of EC public value */
- PRUint16 wrappedKeyLen; /* length (in bytes) of the wrapped key */
- PRUint8 var[MAX_EC_WRAPPED_KEY_BUFLEN]; /* this buffer contains the */
- /* EC public-key params, the EC public value and the wrapped key */
-} ECCWrappedKeyInfo;
-#endif /* NSS_ENABLE_ECC */
-
-#if defined(TRACE)
-
-static char *
-ssl3_DecodeHandshakeType(int msgType)
-{
- char * rv;
- static char line[40];
-
- switch(msgType) {
- case hello_request: rv = "hello_request (0)"; break;
- case client_hello: rv = "client_hello (1)"; break;
- case server_hello: rv = "server_hello (2)"; break;
- case hello_verify_request: rv = "hello_verify_request (3)"; break;
- case certificate: rv = "certificate (11)"; break;
- case server_key_exchange: rv = "server_key_exchange (12)"; break;
- case certificate_request: rv = "certificate_request (13)"; break;
- case server_hello_done: rv = "server_hello_done (14)"; break;
- case certificate_verify: rv = "certificate_verify (15)"; break;
- case client_key_exchange: rv = "client_key_exchange (16)"; break;
- case finished: rv = "finished (20)"; break;
- default:
- sprintf(line, "*UNKNOWN* handshake type! (%d)", msgType);
- rv = line;
- }
- return rv;
-}
-
-static char *
-ssl3_DecodeContentType(int msgType)
-{
- char * rv;
- static char line[40];
-
- switch(msgType) {
- case content_change_cipher_spec:
- rv = "change_cipher_spec (20)"; break;
- case content_alert: rv = "alert (21)"; break;
- case content_handshake: rv = "handshake (22)"; break;
- case content_application_data:
- rv = "application_data (23)"; break;
- default:
- sprintf(line, "*UNKNOWN* record type! (%d)", msgType);
- rv = line;
- }
- return rv;
-}
-
-#endif
-
-SSL3Statistics *
-SSL_GetStatistics(void)
-{
- return &ssl3stats;
-}
-
-typedef struct tooLongStr {
-#if defined(IS_LITTLE_ENDIAN)
- PRInt32 low;
- PRInt32 high;
-#else
- PRInt32 high;
- PRInt32 low;
-#endif
-} tooLong;
-
-void SSL_AtomicIncrementLong(long * x)
-{
- if ((sizeof *x) == sizeof(PRInt32)) {
- PR_ATOMIC_INCREMENT((PRInt32 *)x);
- } else {
- tooLong * tl = (tooLong *)x;
- if (PR_ATOMIC_INCREMENT(&tl->low) == 0)
- PR_ATOMIC_INCREMENT(&tl->high);
- }
-}
-
-static PRBool
-ssl3_CipherSuiteAllowedForVersion(ssl3CipherSuite cipherSuite,
- SSL3ProtocolVersion version)
-{
- switch (cipherSuite) {
- /* See RFC 4346 A.5. Export cipher suites must not be used in TLS 1.1 or
- * later. This set of cipher suites is similar to, but different from, the
- * set of cipher suites considered exportable by SSL_IsExportCipherSuite.
- */
- case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
- case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
- /* SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: never implemented
- * SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5: never implemented
- * SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA: never implemented
- */
- return version <= SSL_LIBRARY_VERSION_TLS_1_0;
- default:
- return PR_TRUE;
- }
-}
-
-/* return pointer to ssl3CipherSuiteDef for suite, or NULL */
-/* XXX This does a linear search. A binary search would be better. */
-static const ssl3CipherSuiteDef *
-ssl_LookupCipherSuiteDef(ssl3CipherSuite suite)
-{
- int cipher_suite_def_len =
- sizeof(cipher_suite_defs) / sizeof(cipher_suite_defs[0]);
- int i;
-
- for (i = 0; i < cipher_suite_def_len; i++) {
- if (cipher_suite_defs[i].cipher_suite == suite)
- return &cipher_suite_defs[i];
- }
- PORT_Assert(PR_FALSE); /* We should never get here. */
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return NULL;
-}
-
-/* Find the cipher configuration struct associate with suite */
-/* XXX This does a linear search. A binary search would be better. */
-static ssl3CipherSuiteCfg *
-ssl_LookupCipherSuiteCfg(ssl3CipherSuite suite, ssl3CipherSuiteCfg *suites)
-{
- int i;
-
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- if (suites[i].cipher_suite == suite)
- return &suites[i];
- }
- /* return NULL and let the caller handle it. */
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return NULL;
-}
-
-
-/* Initialize the suite->isPresent value for config_match
- * Returns count of enabled ciphers supported by extant tokens,
- * regardless of policy or user preference.
- * If this returns zero, the user cannot do SSL v3.
- */
-int
-ssl3_config_match_init(sslSocket *ss)
-{
- ssl3CipherSuiteCfg * suite;
- const ssl3CipherSuiteDef *cipher_def;
- SSLCipherAlgorithm cipher_alg;
- CK_MECHANISM_TYPE cipher_mech;
- SSL3KEAType exchKeyType;
- int i;
- int numPresent = 0;
- int numEnabled = 0;
- PRBool isServer;
- sslServerCerts *svrAuth;
-
- PORT_Assert(ss);
- if (!ss) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return 0;
- }
- if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- return 0;
- }
- isServer = (PRBool)(ss->sec.isServer != 0);
-
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- suite = &ss->cipherSuites[i];
- if (suite->enabled) {
- ++numEnabled;
- /* We need the cipher defs to see if we have a token that can handle
- * this cipher. It isn't part of the static definition.
- */
- cipher_def = ssl_LookupCipherSuiteDef(suite->cipher_suite);
- if (!cipher_def) {
- suite->isPresent = PR_FALSE;
- continue;
- }
- cipher_alg = bulk_cipher_defs[cipher_def->bulk_cipher_alg].calg;
- PORT_Assert( alg2Mech[cipher_alg].calg == cipher_alg);
- cipher_mech = alg2Mech[cipher_alg].cmech;
- exchKeyType =
- kea_defs[cipher_def->key_exchange_alg].exchKeyType;
-#ifndef NSS_ENABLE_ECC
- svrAuth = ss->serverCerts + exchKeyType;
-#else
- /* XXX SSLKEAType isn't really a good choice for
- * indexing certificates. It doesn't work for
- * (EC)DHE-* ciphers. Here we use a hack to ensure
- * that the server uses an RSA cert for (EC)DHE-RSA.
- */
- switch (cipher_def->key_exchange_alg) {
- case kea_ecdhe_rsa:
-#if NSS_SERVER_DHE_IMPLEMENTED
- /* XXX NSS does not yet implement the server side of _DHE_
- * cipher suites. Correcting the computation for svrAuth,
- * as the case below does, causes NSS SSL servers to begin to
- * negotiate cipher suites they do not implement. So, until
- * server side _DHE_ is implemented, keep this disabled.
- */
- case kea_dhe_rsa:
-#endif
- svrAuth = ss->serverCerts + kt_rsa;
- break;
- case kea_ecdh_ecdsa:
- case kea_ecdh_rsa:
- /*
- * XXX We ought to have different indices for
- * ECDSA- and RSA-signed EC certificates so
- * we could support both key exchange mechanisms
- * simultaneously. For now, both of them use
- * whatever is in the certificate slot for kt_ecdh
- */
- default:
- svrAuth = ss->serverCerts + exchKeyType;
- break;
- }
-#endif /* NSS_ENABLE_ECC */
-
- /* Mark the suites that are backed by real tokens, certs and keys */
- suite->isPresent = (PRBool)
- (((exchKeyType == kt_null) ||
- ((!isServer || (svrAuth->serverKeyPair &&
- svrAuth->SERVERKEY &&
- svrAuth->serverCertChain)) &&
- PK11_TokenExists(kea_alg_defs[exchKeyType]))) &&
- ((cipher_alg == calg_null) || PK11_TokenExists(cipher_mech)));
- if (suite->isPresent)
- ++numPresent;
- }
- }
- PORT_Assert(numPresent > 0 || numEnabled == 0);
- if (numPresent <= 0) {
- PORT_SetError(SSL_ERROR_NO_CIPHERS_SUPPORTED);
- }
- return numPresent;
-}
-
-
-/* return PR_TRUE if suite matches policy and enabled state */
-/* It would be a REALLY BAD THING (tm) if we ever permitted the use
-** of a cipher that was NOT_ALLOWED. So, if this is ever called with
-** policy == SSL_NOT_ALLOWED, report no match.
-*/
-/* adjust suite enabled to the availability of a token that can do the
- * cipher suite. */
-static PRBool
-config_match(ssl3CipherSuiteCfg *suite, int policy, PRBool enabled)
-{
- PORT_Assert(policy != SSL_NOT_ALLOWED && enabled != PR_FALSE);
- if (policy == SSL_NOT_ALLOWED || !enabled)
- return PR_FALSE;
- return (PRBool)(suite->enabled &&
- suite->isPresent &&
- suite->policy != SSL_NOT_ALLOWED &&
- suite->policy <= policy);
-}
-
-/* return number of cipher suites that match policy and enabled state */
-/* called from ssl3_SendClientHello and ssl3_ConstructV2CipherSpecsHack */
-static int
-count_cipher_suites(sslSocket *ss, int policy, PRBool enabled)
-{
- int i, count = 0;
-
- if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- return 0;
- }
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- if (config_match(&ss->cipherSuites[i], policy, enabled))
- count++;
- }
- if (count <= 0) {
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- }
- return count;
-}
-
-/*
- * Null compression, mac and encryption functions
- */
-
-static SECStatus
-Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,
- const unsigned char *input, int inputLen)
-{
- *outputLen = inputLen;
- if (input != output)
- PORT_Memcpy(output, input, inputLen);
- return SECSuccess;
-}
-
-/*
- * SSL3 Utility functions
- */
-
-/* allowLargerPeerVersion controls whether the function will select the
- * highest enabled SSL version or fail when peerVersion is greater than the
- * highest enabled version.
- *
- * If allowLargerPeerVersion is true, peerVersion is the peer's highest
- * enabled version rather than the peer's selected version.
- */
-SECStatus
-ssl3_NegotiateVersion(sslSocket *ss, SSL3ProtocolVersion peerVersion,
- PRBool allowLargerPeerVersion)
-{
- if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- return SECFailure;
- }
-
- if (peerVersion < ss->vrange.min ||
- (peerVersion > ss->vrange.max && !allowLargerPeerVersion)) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
-
- ss->version = PR_MIN(peerVersion, ss->vrange.max);
- PORT_Assert(ssl3_VersionIsSupported(ss->protocolVariant, ss->version));
-
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_GetNewRandom(SSL3Random *random)
-{
- PRUint32 gmt = ssl_Time();
- SECStatus rv;
-
- random->rand[0] = (unsigned char)(gmt >> 24);
- random->rand[1] = (unsigned char)(gmt >> 16);
- random->rand[2] = (unsigned char)(gmt >> 8);
- random->rand[3] = (unsigned char)(gmt);
-
- /* first 4 bytes are reserverd for time */
- rv = PK11_GenerateRandom(&random->rand[4], SSL3_RANDOM_LENGTH - 4);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
- }
- return rv;
-}
-
-/* Called by ssl3_SendServerKeyExchange and ssl3_SendCertificateVerify */
-SECStatus
-ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,
- PRBool isTLS)
-{
- SECStatus rv = SECFailure;
- PRBool doDerEncode = PR_FALSE;
- int signatureLen;
- SECItem hashItem;
-
- buf->data = NULL;
- signatureLen = PK11_SignatureLen(key);
- if (signatureLen <= 0) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- goto done;
- }
-
- buf->len = (unsigned)signatureLen;
- buf->data = (unsigned char *)PORT_Alloc(signatureLen);
- if (!buf->data)
- goto done; /* error code was set. */
-
- switch (key->keyType) {
- case rsaKey:
- hashItem.data = hash->md5;
- hashItem.len = sizeof(SSL3Hashes);
- break;
- case dsaKey:
- doDerEncode = isTLS;
- hashItem.data = hash->sha;
- hashItem.len = sizeof(hash->sha);
- break;
-#ifdef NSS_ENABLE_ECC
- case ecKey:
- doDerEncode = PR_TRUE;
- hashItem.data = hash->sha;
- hashItem.len = sizeof(hash->sha);
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- goto done;
- }
- PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len));
-
- rv = PK11_Sign(key, buf, &hashItem);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SIGN_HASHES_FAILURE);
- } else if (doDerEncode) {
- SECItem derSig = {siBuffer, NULL, 0};
-
- /* This also works for an ECDSA signature */
- rv = DSAU_EncodeDerSigWithLen(&derSig, buf, buf->len);
- if (rv == SECSuccess) {
- PORT_Free(buf->data); /* discard unencoded signature. */
- *buf = derSig; /* give caller encoded signature. */
- } else if (derSig.data) {
- PORT_Free(derSig.data);
- }
- }
-
- PRINT_BUF(60, (NULL, "signed hashes", (unsigned char*)buf->data, buf->len));
-done:
- if (rv != SECSuccess && buf->data) {
- PORT_Free(buf->data);
- buf->data = NULL;
- }
- return rv;
-}
-
-/* Called from ssl3_HandleServerKeyExchange, ssl3_HandleCertificateVerify */
-SECStatus
-ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
- SECItem *buf, PRBool isTLS, void *pwArg)
-{
- SECKEYPublicKey * key;
- SECItem * signature = NULL;
- SECStatus rv;
- SECItem hashItem;
-#ifdef NSS_ENABLE_ECC
- unsigned int len;
-#endif /* NSS_ENABLE_ECC */
-
-
- PRINT_BUF(60, (NULL, "check signed hashes",
- buf->data, buf->len));
-
- key = CERT_ExtractPublicKey(cert);
- if (key == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- return SECFailure;
- }
-
- switch (key->keyType) {
- case rsaKey:
- hashItem.data = hash->md5;
- hashItem.len = sizeof(SSL3Hashes);
- break;
- case dsaKey:
- hashItem.data = hash->sha;
- hashItem.len = sizeof(hash->sha);
- /* Allow DER encoded DSA signatures in SSL 3.0 */
- if (isTLS || buf->len != SECKEY_SignatureLen(key)) {
- signature = DSAU_DecodeDerSig(buf);
- if (!signature) {
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- buf = signature;
- }
- break;
-
-#ifdef NSS_ENABLE_ECC
- case ecKey:
- hashItem.data = hash->sha;
- hashItem.len = sizeof(hash->sha);
- /*
- * ECDSA signatures always encode the integers r and s
- * using ASN (unlike DSA where ASN encoding is used
- * with TLS but not with SSL3)
- */
- len = SECKEY_SignatureLen(key);
- if (len == 0) {
- SECKEY_DestroyPublicKey(key);
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- return SECFailure;
- }
- signature = DSAU_DecodeDerSigToLen(buf, len);
- if (!signature) {
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- buf = signature;
- break;
-#endif /* NSS_ENABLE_ECC */
-
- default:
- SECKEY_DestroyPublicKey(key);
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
- }
-
- PRINT_BUF(60, (NULL, "hash(es) to be verified",
- hashItem.data, hashItem.len));
-
- rv = PK11_Verify(key, buf, &hashItem, pwArg);
- SECKEY_DestroyPublicKey(key);
- if (signature) {
- SECITEM_FreeItem(signature, PR_TRUE);
- }
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- }
- return rv;
-}
-
-
-/* Caller must set hiLevel error code. */
-/* Called from ssl3_ComputeExportRSAKeyHash
- * ssl3_ComputeDHKeyHash
- * which are called from ssl3_HandleServerKeyExchange.
- */
-SECStatus
-ssl3_ComputeCommonKeyHash(PRUint8 * hashBuf, unsigned int bufLen,
- SSL3Hashes *hashes, PRBool bypassPKCS11)
-{
- SECStatus rv = SECSuccess;
-
-#ifndef NO_PKCS11_BYPASS
- if (bypassPKCS11) {
- MD5_HashBuf (hashes->md5, hashBuf, bufLen);
- SHA1_HashBuf(hashes->sha, hashBuf, bufLen);
- } else
-#endif
- {
- rv = PK11_HashBuf(SEC_OID_MD5, hashes->md5, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto done;
- }
-
- rv = PK11_HashBuf(SEC_OID_SHA1, hashes->sha, hashBuf, bufLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- }
- }
-done:
- return rv;
-}
-
-/* Caller must set hiLevel error code.
-** Called from ssl3_SendServerKeyExchange and
-** ssl3_HandleServerKeyExchange.
-*/
-static SECStatus
-ssl3_ComputeExportRSAKeyHash(SECItem modulus, SECItem publicExponent,
- SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes, PRBool bypassPKCS11)
-{
- PRUint8 * hashBuf;
- PRUint8 * pBuf;
- SECStatus rv = SECSuccess;
- unsigned int bufLen;
- PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];
-
- bufLen = 2*SSL3_RANDOM_LENGTH + 2 + modulus.len + 2 + publicExponent.len;
- if (bufLen <= sizeof buf) {
- hashBuf = buf;
- } else {
- hashBuf = PORT_Alloc(bufLen);
- if (!hashBuf) {
- return SECFailure;
- }
- }
-
- memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
- pBuf = hashBuf + SSL3_RANDOM_LENGTH;
- memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
- pBuf += SSL3_RANDOM_LENGTH;
- pBuf[0] = (PRUint8)(modulus.len >> 8);
- pBuf[1] = (PRUint8)(modulus.len);
- pBuf += 2;
- memcpy(pBuf, modulus.data, modulus.len);
- pBuf += modulus.len;
- pBuf[0] = (PRUint8)(publicExponent.len >> 8);
- pBuf[1] = (PRUint8)(publicExponent.len);
- pBuf += 2;
- memcpy(pBuf, publicExponent.data, publicExponent.len);
- pBuf += publicExponent.len;
- PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
-
- rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
-
- PRINT_BUF(95, (NULL, "RSAkey hash: ", hashBuf, bufLen));
- PRINT_BUF(95, (NULL, "RSAkey hash: MD5 result", hashes->md5, MD5_LENGTH));
- PRINT_BUF(95, (NULL, "RSAkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
-
- if (hashBuf != buf && hashBuf != NULL)
- PORT_Free(hashBuf);
- return rv;
-}
-
-/* Caller must set hiLevel error code. */
-/* Called from ssl3_HandleServerKeyExchange. */
-static SECStatus
-ssl3_ComputeDHKeyHash(SECItem dh_p, SECItem dh_g, SECItem dh_Ys,
- SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes, PRBool bypassPKCS11)
-{
- PRUint8 * hashBuf;
- PRUint8 * pBuf;
- SECStatus rv = SECSuccess;
- unsigned int bufLen;
- PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 4096/8 + 2 + 4096/8];
-
- bufLen = 2*SSL3_RANDOM_LENGTH + 2 + dh_p.len + 2 + dh_g.len + 2 + dh_Ys.len;
- if (bufLen <= sizeof buf) {
- hashBuf = buf;
- } else {
- hashBuf = PORT_Alloc(bufLen);
- if (!hashBuf) {
- return SECFailure;
- }
- }
-
- memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
- pBuf = hashBuf + SSL3_RANDOM_LENGTH;
- memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
- pBuf += SSL3_RANDOM_LENGTH;
- pBuf[0] = (PRUint8)(dh_p.len >> 8);
- pBuf[1] = (PRUint8)(dh_p.len);
- pBuf += 2;
- memcpy(pBuf, dh_p.data, dh_p.len);
- pBuf += dh_p.len;
- pBuf[0] = (PRUint8)(dh_g.len >> 8);
- pBuf[1] = (PRUint8)(dh_g.len);
- pBuf += 2;
- memcpy(pBuf, dh_g.data, dh_g.len);
- pBuf += dh_g.len;
- pBuf[0] = (PRUint8)(dh_Ys.len >> 8);
- pBuf[1] = (PRUint8)(dh_Ys.len);
- pBuf += 2;
- memcpy(pBuf, dh_Ys.data, dh_Ys.len);
- pBuf += dh_Ys.len;
- PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
-
- rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
-
- PRINT_BUF(95, (NULL, "DHkey hash: ", hashBuf, bufLen));
- PRINT_BUF(95, (NULL, "DHkey hash: MD5 result", hashes->md5, MD5_LENGTH));
- PRINT_BUF(95, (NULL, "DHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
-
- if (hashBuf != buf && hashBuf != NULL)
- PORT_Free(hashBuf);
- return rv;
-}
-
-static void
-ssl3_BumpSequenceNumber(SSL3SequenceNumber *num)
-{
- num->low++;
- if (num->low == 0)
- num->high++;
-}
-
-/* Called twice, only from ssl3_DestroyCipherSpec (immediately below). */
-static void
-ssl3_CleanupKeyMaterial(ssl3KeyMaterial *mat)
-{
- if (mat->write_key != NULL) {
- PK11_FreeSymKey(mat->write_key);
- mat->write_key = NULL;
- }
- if (mat->write_mac_key != NULL) {
- PK11_FreeSymKey(mat->write_mac_key);
- mat->write_mac_key = NULL;
- }
- if (mat->write_mac_context != NULL) {
- PK11_DestroyContext(mat->write_mac_context, PR_TRUE);
- mat->write_mac_context = NULL;
- }
-}
-
-/* Called from ssl3_SendChangeCipherSpecs() and
-** ssl3_HandleChangeCipherSpecs()
-** ssl3_DestroySSL3Info
-** Caller must hold SpecWriteLock.
-*/
-void
-ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName)
-{
- PRBool freeit = (PRBool)(!spec->bypassCiphers);
-/* PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); Don't have ss! */
- if (spec->destroy) {
- spec->destroy(spec->encodeContext, freeit);
- spec->destroy(spec->decodeContext, freeit);
- spec->encodeContext = NULL; /* paranoia */
- spec->decodeContext = NULL;
- }
- if (spec->destroyCompressContext && spec->compressContext) {
- spec->destroyCompressContext(spec->compressContext, 1);
- spec->compressContext = NULL;
- }
- if (spec->destroyDecompressContext && spec->decompressContext) {
- spec->destroyDecompressContext(spec->decompressContext, 1);
- spec->decompressContext = NULL;
- }
- if (freeSrvName && spec->srvVirtName.data) {
- SECITEM_FreeItem(&spec->srvVirtName, PR_FALSE);
- }
- if (spec->master_secret != NULL) {
- PK11_FreeSymKey(spec->master_secret);
- spec->master_secret = NULL;
- }
- spec->msItem.data = NULL;
- spec->msItem.len = 0;
- ssl3_CleanupKeyMaterial(&spec->client);
- ssl3_CleanupKeyMaterial(&spec->server);
- spec->bypassCiphers = PR_FALSE;
- spec->destroy=NULL;
- spec->destroyCompressContext = NULL;
- spec->destroyDecompressContext = NULL;
-}
-
-/* Fill in the pending cipher spec with info from the selected ciphersuite.
-** This is as much initialization as we can do without having key material.
-** Called from ssl3_HandleServerHello(), ssl3_SendServerHello()
-** Caller must hold the ssl3 handshake lock.
-** Acquires & releases SpecWriteLock.
-*/
-static SECStatus
-ssl3_SetupPendingCipherSpec(sslSocket *ss)
-{
- ssl3CipherSpec * pwSpec;
- ssl3CipherSpec * cwSpec;
- ssl3CipherSuite suite = ss->ssl3.hs.cipher_suite;
- SSL3MACAlgorithm mac;
- SSL3BulkCipher cipher;
- SSL3KeyExchangeAlgorithm kea;
- const ssl3CipherSuiteDef *suite_def;
- PRBool isTLS;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- ssl_GetSpecWriteLock(ss); /*******************************/
-
- pwSpec = ss->ssl3.pwSpec;
- PORT_Assert(pwSpec == ss->ssl3.prSpec);
-
- /* This hack provides maximal interoperability with SSL 3 servers. */
- cwSpec = ss->ssl3.cwSpec;
- if (cwSpec->mac_def->mac == mac_null) {
- /* SSL records are not being MACed. */
- cwSpec->version = ss->version;
- }
-
- pwSpec->version = ss->version;
- isTLS = (PRBool)(pwSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- SSL_TRC(3, ("%d: SSL3[%d]: Set XXX Pending Cipher Suite to 0x%04x",
- SSL_GETPID(), ss->fd, suite));
-
- suite_def = ssl_LookupCipherSuiteDef(suite);
- if (suite_def == NULL) {
- ssl_ReleaseSpecWriteLock(ss);
- return SECFailure; /* error code set by ssl_LookupCipherSuiteDef */
- }
-
- if (IS_DTLS(ss)) {
- /* Double-check that we did not pick an RC4 suite */
- PORT_Assert((suite_def->bulk_cipher_alg != cipher_rc4) &&
- (suite_def->bulk_cipher_alg != cipher_rc4_40) &&
- (suite_def->bulk_cipher_alg != cipher_rc4_56));
- }
-
- cipher = suite_def->bulk_cipher_alg;
- kea = suite_def->key_exchange_alg;
- mac = suite_def->mac_alg;
- if (isTLS)
- mac += 2;
-
- ss->ssl3.hs.suite_def = suite_def;
- ss->ssl3.hs.kea_def = &kea_defs[kea];
- PORT_Assert(ss->ssl3.hs.kea_def->kea == kea);
-
- pwSpec->cipher_def = &bulk_cipher_defs[cipher];
- PORT_Assert(pwSpec->cipher_def->cipher == cipher);
-
- pwSpec->mac_def = &mac_defs[mac];
- PORT_Assert(pwSpec->mac_def->mac == mac);
-
- ss->sec.keyBits = pwSpec->cipher_def->key_size * BPB;
- ss->sec.secretKeyBits = pwSpec->cipher_def->secret_key_size * BPB;
- ss->sec.cipherType = cipher;
-
- pwSpec->encodeContext = NULL;
- pwSpec->decodeContext = NULL;
-
- pwSpec->mac_size = pwSpec->mac_def->mac_size;
-
- pwSpec->compression_method = ss->ssl3.hs.compression;
- pwSpec->compressContext = NULL;
- pwSpec->decompressContext = NULL;
-
- ssl_ReleaseSpecWriteLock(ss); /*******************************/
- return SECSuccess;
-}
-
-#ifdef NSS_ENABLE_ZLIB
-#define SSL3_DEFLATE_CONTEXT_SIZE sizeof(z_stream)
-
-static SECStatus
-ssl3_MapZlibError(int zlib_error)
-{
- switch (zlib_error) {
- case Z_OK:
- return SECSuccess;
- default:
- return SECFailure;
- }
-}
-
-static SECStatus
-ssl3_DeflateInit(void *void_context)
-{
- z_stream *context = void_context;
- context->zalloc = NULL;
- context->zfree = NULL;
- context->opaque = NULL;
-
- return ssl3_MapZlibError(deflateInit(context, Z_DEFAULT_COMPRESSION));
-}
-
-static SECStatus
-ssl3_InflateInit(void *void_context)
-{
- z_stream *context = void_context;
- context->zalloc = NULL;
- context->zfree = NULL;
- context->opaque = NULL;
- context->next_in = NULL;
- context->avail_in = 0;
-
- return ssl3_MapZlibError(inflateInit(context));
-}
-
-static SECStatus
-ssl3_DeflateCompress(void *void_context, unsigned char *out, int *out_len,
- int maxout, const unsigned char *in, int inlen)
-{
- z_stream *context = void_context;
-
- if (!inlen) {
- *out_len = 0;
- return SECSuccess;
- }
-
- context->next_in = (unsigned char*) in;
- context->avail_in = inlen;
- context->next_out = out;
- context->avail_out = maxout;
- if (deflate(context, Z_SYNC_FLUSH) != Z_OK) {
- return SECFailure;
- }
- if (context->avail_out == 0) {
- /* We ran out of space! */
- SSL_TRC(3, ("%d: SSL3[%d] Ran out of buffer while compressing",
- SSL_GETPID()));
- return SECFailure;
- }
-
- *out_len = maxout - context->avail_out;
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_DeflateDecompress(void *void_context, unsigned char *out, int *out_len,
- int maxout, const unsigned char *in, int inlen)
-{
- z_stream *context = void_context;
-
- if (!inlen) {
- *out_len = 0;
- return SECSuccess;
- }
-
- context->next_in = (unsigned char*) in;
- context->avail_in = inlen;
- context->next_out = out;
- context->avail_out = maxout;
- if (inflate(context, Z_SYNC_FLUSH) != Z_OK) {
- PORT_SetError(SSL_ERROR_DECOMPRESSION_FAILURE);
- return SECFailure;
- }
-
- *out_len = maxout - context->avail_out;
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_DestroyCompressContext(void *void_context, PRBool unused)
-{
- deflateEnd(void_context);
- PORT_Free(void_context);
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_DestroyDecompressContext(void *void_context, PRBool unused)
-{
- inflateEnd(void_context);
- PORT_Free(void_context);
- return SECSuccess;
-}
-
-#endif /* NSS_ENABLE_ZLIB */
-
-/* Initialize the compression functions and contexts for the given
- * CipherSpec. */
-static SECStatus
-ssl3_InitCompressionContext(ssl3CipherSpec *pwSpec)
-{
- /* Setup the compression functions */
- switch (pwSpec->compression_method) {
- case ssl_compression_null:
- pwSpec->compressor = NULL;
- pwSpec->decompressor = NULL;
- pwSpec->compressContext = NULL;
- pwSpec->decompressContext = NULL;
- pwSpec->destroyCompressContext = NULL;
- pwSpec->destroyDecompressContext = NULL;
- break;
-#ifdef NSS_ENABLE_ZLIB
- case ssl_compression_deflate:
- pwSpec->compressor = ssl3_DeflateCompress;
- pwSpec->decompressor = ssl3_DeflateDecompress;
- pwSpec->compressContext = PORT_Alloc(SSL3_DEFLATE_CONTEXT_SIZE);
- pwSpec->decompressContext = PORT_Alloc(SSL3_DEFLATE_CONTEXT_SIZE);
- pwSpec->destroyCompressContext = ssl3_DestroyCompressContext;
- pwSpec->destroyDecompressContext = ssl3_DestroyDecompressContext;
- ssl3_DeflateInit(pwSpec->compressContext);
- ssl3_InflateInit(pwSpec->decompressContext);
- break;
-#endif /* NSS_ENABLE_ZLIB */
- default:
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-#ifndef NO_PKCS11_BYPASS
-/* Initialize encryption and MAC contexts for pending spec.
- * Master Secret already is derived in spec->msItem
- * Caller holds Spec write lock.
- */
-static SECStatus
-ssl3_InitPendingContextsBypass(sslSocket *ss)
-{
- ssl3CipherSpec * pwSpec;
- const ssl3BulkCipherDef *cipher_def;
- void * serverContext = NULL;
- void * clientContext = NULL;
- BLapiInitContextFunc initFn = (BLapiInitContextFunc)NULL;
- int mode = 0;
- unsigned int optArg1 = 0;
- unsigned int optArg2 = 0;
- PRBool server_encrypts = ss->sec.isServer;
- CK_ULONG macLength;
- SSLCipherAlgorithm calg;
- SSLCompressionMethod compression_method;
- SECStatus rv;
-
- PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert(ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
-
- pwSpec = ss->ssl3.pwSpec;
- cipher_def = pwSpec->cipher_def;
- macLength = pwSpec->mac_size;
-
- /* MAC setup is done when computing the mac, not here.
- * Now setup the crypto contexts.
- */
-
- calg = cipher_def->calg;
- compression_method = pwSpec->compression_method;
-
- serverContext = pwSpec->server.cipher_context;
- clientContext = pwSpec->client.cipher_context;
-
- switch (calg) {
- case ssl_calg_null:
- pwSpec->encode = Null_Cipher;
- pwSpec->decode = Null_Cipher;
- pwSpec->destroy = NULL;
- goto success;
-
- case ssl_calg_rc4:
- initFn = (BLapiInitContextFunc)RC4_InitContext;
- pwSpec->encode = (SSLCipher) RC4_Encrypt;
- pwSpec->decode = (SSLCipher) RC4_Decrypt;
- pwSpec->destroy = (SSLDestroy) RC4_DestroyContext;
- break;
- case ssl_calg_rc2:
- initFn = (BLapiInitContextFunc)RC2_InitContext;
- mode = NSS_RC2_CBC;
- optArg1 = cipher_def->key_size;
- pwSpec->encode = (SSLCipher) RC2_Encrypt;
- pwSpec->decode = (SSLCipher) RC2_Decrypt;
- pwSpec->destroy = (SSLDestroy) RC2_DestroyContext;
- break;
- case ssl_calg_des:
- initFn = (BLapiInitContextFunc)DES_InitContext;
- mode = NSS_DES_CBC;
- optArg1 = server_encrypts;
- pwSpec->encode = (SSLCipher) DES_Encrypt;
- pwSpec->decode = (SSLCipher) DES_Decrypt;
- pwSpec->destroy = (SSLDestroy) DES_DestroyContext;
- break;
- case ssl_calg_3des:
- initFn = (BLapiInitContextFunc)DES_InitContext;
- mode = NSS_DES_EDE3_CBC;
- optArg1 = server_encrypts;
- pwSpec->encode = (SSLCipher) DES_Encrypt;
- pwSpec->decode = (SSLCipher) DES_Decrypt;
- pwSpec->destroy = (SSLDestroy) DES_DestroyContext;
- break;
- case ssl_calg_aes:
- initFn = (BLapiInitContextFunc)AES_InitContext;
- mode = NSS_AES_CBC;
- optArg1 = server_encrypts;
- optArg2 = AES_BLOCK_SIZE;
- pwSpec->encode = (SSLCipher) AES_Encrypt;
- pwSpec->decode = (SSLCipher) AES_Decrypt;
- pwSpec->destroy = (SSLDestroy) AES_DestroyContext;
- break;
-
- case ssl_calg_camellia:
- initFn = (BLapiInitContextFunc)Camellia_InitContext;
- mode = NSS_CAMELLIA_CBC;
- optArg1 = server_encrypts;
- optArg2 = CAMELLIA_BLOCK_SIZE;
- pwSpec->encode = (SSLCipher) Camellia_Encrypt;
- pwSpec->decode = (SSLCipher) Camellia_Decrypt;
- pwSpec->destroy = (SSLDestroy) Camellia_DestroyContext;
- break;
-
- case ssl_calg_seed:
- initFn = (BLapiInitContextFunc)SEED_InitContext;
- mode = NSS_SEED_CBC;
- optArg1 = server_encrypts;
- optArg2 = SEED_BLOCK_SIZE;
- pwSpec->encode = (SSLCipher) SEED_Encrypt;
- pwSpec->decode = (SSLCipher) SEED_Decrypt;
- pwSpec->destroy = (SSLDestroy) SEED_DestroyContext;
- break;
-
- case ssl_calg_idea:
- case ssl_calg_fortezza :
- default:
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- goto bail_out;
- }
- rv = (*initFn)(serverContext,
- pwSpec->server.write_key_item.data,
- pwSpec->server.write_key_item.len,
- pwSpec->server.write_iv_item.data,
- mode, optArg1, optArg2);
- if (rv != SECSuccess) {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- goto bail_out;
- }
-
- switch (calg) {
- case ssl_calg_des:
- case ssl_calg_3des:
- case ssl_calg_aes:
- case ssl_calg_camellia:
- case ssl_calg_seed:
- /* For block ciphers, if the server is encrypting, then the client
- * is decrypting, and vice versa.
- */
- optArg1 = !optArg1;
- break;
- /* kill warnings. */
- case ssl_calg_null:
- case ssl_calg_rc4:
- case ssl_calg_rc2:
- case ssl_calg_idea:
- case ssl_calg_fortezza:
- break;
- }
-
- rv = (*initFn)(clientContext,
- pwSpec->client.write_key_item.data,
- pwSpec->client.write_key_item.len,
- pwSpec->client.write_iv_item.data,
- mode, optArg1, optArg2);
- if (rv != SECSuccess) {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- goto bail_out;
- }
-
- pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
- pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;
-
- ssl3_InitCompressionContext(pwSpec);
-
-success:
- return SECSuccess;
-
-bail_out:
- return SECFailure;
-}
-#endif
-
-/* This function should probably be moved to pk11wrap and be named
- * PK11_ParamFromIVAndEffectiveKeyBits
- */
-static SECItem *
-ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype, SECItem *iv, CK_ULONG ulEffectiveBits)
-{
- SECItem * param = PK11_ParamFromIV(mtype, iv);
- if (param && param->data && param->len >= sizeof(CK_RC2_PARAMS)) {
- switch (mtype) {
- case CKM_RC2_KEY_GEN:
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- case CKM_RC2_MAC:
- case CKM_RC2_MAC_GENERAL:
- case CKM_RC2_CBC_PAD:
- *(CK_RC2_PARAMS *)param->data = ulEffectiveBits;
- default: break;
- }
- }
- return param;
-}
-
-/* Initialize encryption and MAC contexts for pending spec.
- * Master Secret already is derived.
- * Caller holds Spec write lock.
- */
-static SECStatus
-ssl3_InitPendingContextsPKCS11(sslSocket *ss)
-{
- ssl3CipherSpec * pwSpec;
- const ssl3BulkCipherDef *cipher_def;
- PK11Context * serverContext = NULL;
- PK11Context * clientContext = NULL;
- SECItem * param;
- CK_MECHANISM_TYPE mechanism;
- CK_MECHANISM_TYPE mac_mech;
- CK_ULONG macLength;
- CK_ULONG effKeyBits;
- SECItem iv;
- SECItem mac_param;
- SSLCipherAlgorithm calg;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
-
- pwSpec = ss->ssl3.pwSpec;
- cipher_def = pwSpec->cipher_def;
- macLength = pwSpec->mac_size;
-
- /*
- ** Now setup the MAC contexts,
- ** crypto contexts are setup below.
- */
-
- pwSpec->client.write_mac_context = NULL;
- pwSpec->server.write_mac_context = NULL;
- mac_mech = pwSpec->mac_def->mmech;
- mac_param.data = (unsigned char *)&macLength;
- mac_param.len = sizeof(macLength);
- mac_param.type = 0;
-
- pwSpec->client.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech, CKA_SIGN, pwSpec->client.write_mac_key, &mac_param);
- if (pwSpec->client.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
- pwSpec->server.write_mac_context = PK11_CreateContextBySymKey(
- mac_mech, CKA_SIGN, pwSpec->server.write_mac_key, &mac_param);
- if (pwSpec->server.write_mac_context == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
-
- /*
- ** Now setup the crypto contexts.
- */
-
- calg = cipher_def->calg;
- PORT_Assert(alg2Mech[calg].calg == calg);
-
- if (calg == calg_null) {
- pwSpec->encode = Null_Cipher;
- pwSpec->decode = Null_Cipher;
- pwSpec->destroy = NULL;
- return SECSuccess;
- }
- mechanism = alg2Mech[calg].cmech;
- effKeyBits = cipher_def->key_size * BPB;
-
- /*
- * build the server context
- */
- iv.data = pwSpec->server.write_iv;
- iv.len = cipher_def->iv_size;
- param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
- if (param == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
- goto fail;
- }
- serverContext = PK11_CreateContextBySymKey(mechanism,
- (ss->sec.isServer ? CKA_ENCRYPT : CKA_DECRYPT),
- pwSpec->server.write_key, param);
- iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);
- if (iv.data)
- PORT_Memcpy(pwSpec->server.write_iv, iv.data, iv.len);
- SECITEM_FreeItem(param, PR_TRUE);
- if (serverContext == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
-
- /*
- * build the client context
- */
- iv.data = pwSpec->client.write_iv;
- iv.len = cipher_def->iv_size;
-
- param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits);
- if (param == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE);
- goto fail;
- }
- clientContext = PK11_CreateContextBySymKey(mechanism,
- (ss->sec.isServer ? CKA_DECRYPT : CKA_ENCRYPT),
- pwSpec->client.write_key, param);
- iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len);
- if (iv.data)
- PORT_Memcpy(pwSpec->client.write_iv, iv.data, iv.len);
- SECITEM_FreeItem(param,PR_TRUE);
- if (clientContext == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE);
- goto fail;
- }
- pwSpec->encode = (SSLCipher) PK11_CipherOp;
- pwSpec->decode = (SSLCipher) PK11_CipherOp;
- pwSpec->destroy = (SSLDestroy) PK11_DestroyContext;
-
- pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext;
- pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext;
-
- serverContext = NULL;
- clientContext = NULL;
-
- ssl3_InitCompressionContext(pwSpec);
-
- return SECSuccess;
-
-fail:
- if (serverContext != NULL) PK11_DestroyContext(serverContext, PR_TRUE);
- if (clientContext != NULL) PK11_DestroyContext(clientContext, PR_TRUE);
- if (pwSpec->client.write_mac_context != NULL) {
- PK11_DestroyContext(pwSpec->client.write_mac_context,PR_TRUE);
- pwSpec->client.write_mac_context = NULL;
- }
- if (pwSpec->server.write_mac_context != NULL) {
- PK11_DestroyContext(pwSpec->server.write_mac_context,PR_TRUE);
- pwSpec->server.write_mac_context = NULL;
- }
-
- return SECFailure;
-}
-
-/* Complete the initialization of all keys, ciphers, MACs and their contexts
- * for the pending Cipher Spec.
- * Called from: ssl3_SendClientKeyExchange (for Full handshake)
- * ssl3_HandleRSAClientKeyExchange (for Full handshake)
- * ssl3_HandleServerHello (for session restart)
- * ssl3_HandleClientHello (for session restart)
- * Sets error code, but caller probably should override to disambiguate.
- * NULL pms means re-use old master_secret.
- *
- * This code is common to the bypass and PKCS11 execution paths.
- * For the bypass case, pms is NULL.
- */
-SECStatus
-ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms)
-{
- ssl3CipherSpec * pwSpec;
- ssl3CipherSpec * cwSpec;
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- ssl_GetSpecWriteLock(ss); /**************************************/
-
- PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
-
- pwSpec = ss->ssl3.pwSpec;
- cwSpec = ss->ssl3.cwSpec;
-
- if (pms || (!pwSpec->msItem.len && !pwSpec->master_secret)) {
- rv = ssl3_DeriveMasterSecret(ss, pms);
- if (rv != SECSuccess) {
- goto done; /* err code set by ssl3_DeriveMasterSecret */
- }
- }
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11 && pwSpec->msItem.len && pwSpec->msItem.data) {
- /* Double Bypass succeeded in extracting the master_secret */
- const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
- PRBool isTLS = (PRBool)(kea_def->tls_keygen ||
- (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
- pwSpec->bypassCiphers = PR_TRUE;
- rv = ssl3_KeyAndMacDeriveBypass( pwSpec,
- (const unsigned char *)&ss->ssl3.hs.client_random,
- (const unsigned char *)&ss->ssl3.hs.server_random,
- isTLS,
- (PRBool)(kea_def->is_limited));
- if (rv == SECSuccess) {
- rv = ssl3_InitPendingContextsBypass(ss);
- }
- } else
-#endif
- if (pwSpec->master_secret) {
- rv = ssl3_DeriveConnectionKeysPKCS11(ss);
- if (rv == SECSuccess) {
- rv = ssl3_InitPendingContextsPKCS11(ss);
- }
- } else {
- PORT_Assert(pwSpec->master_secret);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- }
- if (rv != SECSuccess) {
- goto done;
- }
-
- /* Generic behaviors -- common to all crypto methods */
- if (!IS_DTLS(ss)) {
- pwSpec->read_seq_num.high = pwSpec->write_seq_num.high = 0;
- } else {
- if (cwSpec->epoch == PR_UINT16_MAX) {
- /* The problem here is that we have rehandshaked too many
- * times (you are not allowed to wrap the epoch). The
- * spec says you should be discarding the connection
- * and start over, so not much we can do here. */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- goto done;
- }
- /* The sequence number has the high 16 bits as the epoch. */
- pwSpec->epoch = cwSpec->epoch + 1;
- pwSpec->read_seq_num.high = pwSpec->write_seq_num.high =
- pwSpec->epoch << 16;
-
- dtls_InitRecvdRecords(&pwSpec->recvdRecords);
- }
- pwSpec->read_seq_num.low = pwSpec->write_seq_num.low = 0;
-
-done:
- ssl_ReleaseSpecWriteLock(ss); /******************************/
- if (rv != SECSuccess)
- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return rv;
-}
-
-/*
- * 60 bytes is 3 times the maximum length MAC size that is supported.
- */
-static const unsigned char mac_pad_1 [60] = {
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36
-};
-static const unsigned char mac_pad_2 [60] = {
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
- 0x5c, 0x5c, 0x5c, 0x5c
-};
-
-/* Called from: ssl3_SendRecord()
-** Caller must already hold the SpecReadLock. (wish we could assert that!)
-*/
-static SECStatus
-ssl3_ComputeRecordMAC(
- ssl3CipherSpec * spec,
- PRBool useServerMacKey,
- PRBool isDTLS,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seq_num,
- const SSL3Opaque * input,
- int inputLength,
- unsigned char * outbuf,
- unsigned int * outLength)
-{
- const ssl3MACDef * mac_def;
- SECStatus rv;
-#ifndef NO_PKCS11_BYPASS
- PRBool isTLS;
-#endif
- unsigned int tempLen;
- unsigned char temp[MAX_MAC_LENGTH];
-
- temp[0] = (unsigned char)(seq_num.high >> 24);
- temp[1] = (unsigned char)(seq_num.high >> 16);
- temp[2] = (unsigned char)(seq_num.high >> 8);
- temp[3] = (unsigned char)(seq_num.high >> 0);
- temp[4] = (unsigned char)(seq_num.low >> 24);
- temp[5] = (unsigned char)(seq_num.low >> 16);
- temp[6] = (unsigned char)(seq_num.low >> 8);
- temp[7] = (unsigned char)(seq_num.low >> 0);
- temp[8] = type;
-
- /* TLS MAC includes the record's version field, SSL's doesn't.
- ** We decide which MAC defintiion to use based on the version of
- ** the protocol that was negotiated when the spec became current,
- ** NOT based on the version value in the record itself.
- ** But, we use the record'v version value in the computation.
- */
- if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
- temp[9] = MSB(inputLength);
- temp[10] = LSB(inputLength);
- tempLen = 11;
-#ifndef NO_PKCS11_BYPASS
- isTLS = PR_FALSE;
-#endif
- } else {
- /* New TLS hash includes version. */
- if (isDTLS) {
- SSL3ProtocolVersion dtls_version;
-
- dtls_version = dtls_TLSVersionToDTLSVersion(version);
- temp[9] = MSB(dtls_version);
- temp[10] = LSB(dtls_version);
- } else {
- temp[9] = MSB(version);
- temp[10] = LSB(version);
- }
- temp[11] = MSB(inputLength);
- temp[12] = LSB(inputLength);
- tempLen = 13;
-#ifndef NO_PKCS11_BYPASS
- isTLS = PR_TRUE;
-#endif
- }
-
- PRINT_BUF(95, (NULL, "frag hash1: temp", temp, tempLen));
- PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength));
-
- mac_def = spec->mac_def;
- if (mac_def->mac == mac_null) {
- *outLength = 0;
- return SECSuccess;
- }
-#ifndef NO_PKCS11_BYPASS
- if (spec->bypassCiphers) {
- /* bypass version */
- const SECHashObject *hashObj = NULL;
- unsigned int pad_bytes = 0;
- PRUint64 write_mac_context[MAX_MAC_CONTEXT_LLONGS];
-
- switch (mac_def->mac) {
- case ssl_mac_null:
- *outLength = 0;
- return SECSuccess;
- case ssl_mac_md5:
- pad_bytes = 48;
- hashObj = HASH_GetRawHashObject(HASH_AlgMD5);
- break;
- case ssl_mac_sha:
- pad_bytes = 40;
- hashObj = HASH_GetRawHashObject(HASH_AlgSHA1);
- break;
- case ssl_hmac_md5: /* used with TLS */
- hashObj = HASH_GetRawHashObject(HASH_AlgMD5);
- break;
- case ssl_hmac_sha: /* used with TLS */
- hashObj = HASH_GetRawHashObject(HASH_AlgSHA1);
- break;
- default:
- break;
- }
- if (!hashObj) {
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- if (!isTLS) {
- /* compute "inner" part of SSL3 MAC */
- hashObj->begin(write_mac_context);
- if (useServerMacKey)
- hashObj->update(write_mac_context,
- spec->server.write_mac_key_item.data,
- spec->server.write_mac_key_item.len);
- else
- hashObj->update(write_mac_context,
- spec->client.write_mac_key_item.data,
- spec->client.write_mac_key_item.len);
- hashObj->update(write_mac_context, mac_pad_1, pad_bytes);
- hashObj->update(write_mac_context, temp, tempLen);
- hashObj->update(write_mac_context, input, inputLength);
- hashObj->end(write_mac_context, temp, &tempLen, sizeof temp);
-
- /* compute "outer" part of SSL3 MAC */
- hashObj->begin(write_mac_context);
- if (useServerMacKey)
- hashObj->update(write_mac_context,
- spec->server.write_mac_key_item.data,
- spec->server.write_mac_key_item.len);
- else
- hashObj->update(write_mac_context,
- spec->client.write_mac_key_item.data,
- spec->client.write_mac_key_item.len);
- hashObj->update(write_mac_context, mac_pad_2, pad_bytes);
- hashObj->update(write_mac_context, temp, tempLen);
- hashObj->end(write_mac_context, outbuf, outLength, spec->mac_size);
- rv = SECSuccess;
- } else { /* is TLS */
-#define cx ((HMACContext *)write_mac_context)
- if (useServerMacKey) {
- rv = HMAC_Init(cx, hashObj,
- spec->server.write_mac_key_item.data,
- spec->server.write_mac_key_item.len, PR_FALSE);
- } else {
- rv = HMAC_Init(cx, hashObj,
- spec->client.write_mac_key_item.data,
- spec->client.write_mac_key_item.len, PR_FALSE);
- }
- if (rv == SECSuccess) {
- HMAC_Begin(cx);
- HMAC_Update(cx, temp, tempLen);
- HMAC_Update(cx, input, inputLength);
- rv = HMAC_Finish(cx, outbuf, outLength, spec->mac_size);
- HMAC_Destroy(cx, PR_FALSE);
- }
-#undef cx
- }
- } else
-#endif
- {
- PK11Context *mac_context =
- (useServerMacKey ? spec->server.write_mac_context
- : spec->client.write_mac_context);
- rv = PK11_DigestBegin(mac_context);
- rv |= PK11_DigestOp(mac_context, temp, tempLen);
- rv |= PK11_DigestOp(mac_context, input, inputLength);
- rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size);
- }
-
- PORT_Assert(rv != SECSuccess || *outLength == (unsigned)spec->mac_size);
-
- PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength));
-
- if (rv != SECSuccess) {
- rv = SECFailure;
- ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
- }
- return rv;
-}
-
-/* Called from: ssl3_HandleRecord()
- * Caller must already hold the SpecReadLock. (wish we could assert that!)
- *
- * On entry:
- * originalLen >= inputLen >= MAC size
-*/
-static SECStatus
-ssl3_ComputeRecordMACConstantTime(
- ssl3CipherSpec * spec,
- PRBool useServerMacKey,
- PRBool isDTLS,
- SSL3ContentType type,
- SSL3ProtocolVersion version,
- SSL3SequenceNumber seq_num,
- const SSL3Opaque * input,
- int inputLen,
- int originalLen,
- unsigned char * outbuf,
- unsigned int * outLen)
-{
- CK_MECHANISM_TYPE macType;
- CK_NSS_MAC_CONSTANT_TIME_PARAMS params;
- SECItem param, inputItem, outputItem;
- SECStatus rv;
- unsigned char header[13];
- PK11SymKey * key;
- int recordLength;
-
- PORT_Assert(inputLen >= spec->mac_size);
- PORT_Assert(originalLen >= inputLen);
-
- if (spec->bypassCiphers) {
- /* This function doesn't support PKCS#11 bypass. We fallback on the
- * non-constant time version. */
- goto fallback;
- }
-
- if (spec->mac_def->mac == mac_null) {
- *outLen = 0;
- return SECSuccess;
- }
-
- header[0] = (unsigned char)(seq_num.high >> 24);
- header[1] = (unsigned char)(seq_num.high >> 16);
- header[2] = (unsigned char)(seq_num.high >> 8);
- header[3] = (unsigned char)(seq_num.high >> 0);
- header[4] = (unsigned char)(seq_num.low >> 24);
- header[5] = (unsigned char)(seq_num.low >> 16);
- header[6] = (unsigned char)(seq_num.low >> 8);
- header[7] = (unsigned char)(seq_num.low >> 0);
- header[8] = type;
-
- macType = CKM_NSS_HMAC_CONSTANT_TIME;
- recordLength = inputLen - spec->mac_size;
- if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
- macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME;
- header[9] = recordLength >> 8;
- header[10] = recordLength;
- params.ulHeaderLen = 11;
- } else {
- if (isDTLS) {
- SSL3ProtocolVersion dtls_version;
-
- dtls_version = dtls_TLSVersionToDTLSVersion(version);
- header[9] = dtls_version >> 8;
- header[10] = dtls_version;
- } else {
- header[9] = version >> 8;
- header[10] = version;
- }
- header[11] = recordLength >> 8;
- header[12] = recordLength;
- params.ulHeaderLen = 13;
- }
-
- params.macAlg = spec->mac_def->mmech;
- params.ulBodyTotalLen = originalLen;
- params.pHeader = header;
-
- param.data = (unsigned char*) &params;
- param.len = sizeof(params);
- param.type = 0;
-
- inputItem.data = (unsigned char *) input;
- inputItem.len = inputLen;
- inputItem.type = 0;
-
- outputItem.data = outbuf;
- outputItem.len = *outLen;
- outputItem.type = 0;
-
- key = spec->server.write_mac_key;
- if (!useServerMacKey) {
- key = spec->client.write_mac_key;
- }
-
- rv = PK11_SignWithSymKey(key, macType, &param, &outputItem, &inputItem);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SEC_ERROR_INVALID_ALGORITHM) {
- goto fallback;
- }
-
- *outLen = 0;
- rv = SECFailure;
- ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
- return rv;
- }
-
- PORT_Assert(outputItem.len == (unsigned)spec->mac_size);
- *outLen = outputItem.len;
-
- return rv;
-
-fallback:
- /* ssl3_ComputeRecordMAC expects the MAC to have been removed from the
- * length already. */
- inputLen -= spec->mac_size;
- return ssl3_ComputeRecordMAC(spec, useServerMacKey, isDTLS, type,
- version, seq_num, input, inputLen,
- outbuf, outLen);
-}
-
-static PRBool
-ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
- PK11SlotInfo *slot = NULL;
- PRBool isPresent = PR_TRUE;
-
- /* we only care if we are doing client auth */
- if (!sid || !sid->u.ssl3.clAuthValid) {
- return PR_TRUE;
- }
-
- /* get the slot */
- slot = SECMOD_LookupSlot(sid->u.ssl3.clAuthModuleID,
- sid->u.ssl3.clAuthSlotID);
- if (slot == NULL ||
- !PK11_IsPresent(slot) ||
- sid->u.ssl3.clAuthSeries != PK11_GetSlotSeries(slot) ||
- sid->u.ssl3.clAuthSlotID != PK11_GetSlotID(slot) ||
- sid->u.ssl3.clAuthModuleID != PK11_GetModuleID(slot) ||
- (PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL))) {
- isPresent = PR_FALSE;
- }
- if (slot) {
- PK11_FreeSlot(slot);
- }
- return isPresent;
-}
-
-/* Caller must hold the spec read lock. */
-SECStatus
-ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
- PRBool isServer,
- PRBool isDTLS,
- PRBool capRecordVersion,
- SSL3ContentType type,
- const SSL3Opaque * pIn,
- PRUint32 contentLen,
- sslBuffer * wrBuf)
-{
- const ssl3BulkCipherDef * cipher_def;
- SECStatus rv;
- PRUint32 macLen = 0;
- PRUint32 fragLen;
- PRUint32 p1Len, p2Len, oddLen = 0;
- PRUint16 headerLen;
- int ivLen = 0;
- int cipherBytes = 0;
-
- cipher_def = cwSpec->cipher_def;
- headerLen = isDTLS ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH;
-
- if (cipher_def->type == type_block &&
- cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
- /* Prepend the per-record explicit IV using technique 2b from
- * RFC 4346 section 6.2.3.2: The IV is a cryptographically
- * strong random number XORed with the CBC residue from the previous
- * record.
- */
- ivLen = cipher_def->iv_size;
- if (ivLen > wrBuf->space - headerLen) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- rv = PK11_GenerateRandom(wrBuf->buf + headerLen, ivLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
- return rv;
- }
- rv = cwSpec->encode( cwSpec->encodeContext,
- wrBuf->buf + headerLen,
- &cipherBytes, /* output and actual outLen */
- ivLen, /* max outlen */
- wrBuf->buf + headerLen,
- ivLen); /* input and inputLen*/
- if (rv != SECSuccess || cipherBytes != ivLen) {
- PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
- return SECFailure;
- }
- }
-
- if (cwSpec->compressor) {
- int outlen;
- rv = cwSpec->compressor(
- cwSpec->compressContext,
- wrBuf->buf + headerLen + ivLen, &outlen,
- wrBuf->space - headerLen - ivLen, pIn, contentLen);
- if (rv != SECSuccess)
- return rv;
- pIn = wrBuf->buf + headerLen + ivLen;
- contentLen = outlen;
- }
-
- /*
- * Add the MAC
- */
- rv = ssl3_ComputeRecordMAC( cwSpec, isServer, isDTLS,
- type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen,
- wrBuf->buf + headerLen + ivLen + contentLen, &macLen);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
- return SECFailure;
- }
- p1Len = contentLen;
- p2Len = macLen;
- fragLen = contentLen + macLen; /* needs to be encrypted */
- PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024);
-
- /*
- * Pad the text (if we're doing a block cipher)
- * then Encrypt it
- */
- if (cipher_def->type == type_block) {
- unsigned char * pBuf;
- int padding_length;
- int i;
-
- oddLen = contentLen % cipher_def->block_size;
- /* Assume blockSize is a power of two */
- padding_length = cipher_def->block_size - 1 -
- ((fragLen) & (cipher_def->block_size - 1));
- fragLen += padding_length + 1;
- PORT_Assert((fragLen % cipher_def->block_size) == 0);
-
- /* Pad according to TLS rules (also acceptable to SSL3). */
- pBuf = &wrBuf->buf[headerLen + ivLen + fragLen - 1];
- for (i = padding_length + 1; i > 0; --i) {
- *pBuf-- = padding_length;
- }
- /* now, if contentLen is not a multiple of block size, fix it */
- p2Len = fragLen - p1Len;
- }
- if (p1Len < 256) {
- oddLen = p1Len;
- p1Len = 0;
- } else {
- p1Len -= oddLen;
- }
- if (oddLen) {
- p2Len += oddLen;
- PORT_Assert( (cipher_def->block_size < 2) || \
- (p2Len % cipher_def->block_size) == 0);
- memmove(wrBuf->buf + headerLen + ivLen + p1Len, pIn + p1Len, oddLen);
- }
- if (p1Len > 0) {
- int cipherBytesPart1 = -1;
- rv = cwSpec->encode( cwSpec->encodeContext,
- wrBuf->buf + headerLen + ivLen, /* output */
- &cipherBytesPart1, /* actual outlen */
- p1Len, /* max outlen */
- pIn, p1Len); /* input, and inputlen */
- PORT_Assert(rv == SECSuccess && cipherBytesPart1 == (int) p1Len);
- if (rv != SECSuccess || cipherBytesPart1 != (int) p1Len) {
- PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
- return SECFailure;
- }
- cipherBytes += cipherBytesPart1;
- }
- if (p2Len > 0) {
- int cipherBytesPart2 = -1;
- rv = cwSpec->encode( cwSpec->encodeContext,
- wrBuf->buf + headerLen + ivLen + p1Len,
- &cipherBytesPart2, /* output and actual outLen */
- p2Len, /* max outlen */
- wrBuf->buf + headerLen + ivLen + p1Len,
- p2Len); /* input and inputLen*/
- PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int) p2Len);
- if (rv != SECSuccess || cipherBytesPart2 != (int) p2Len) {
- PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
- return SECFailure;
- }
- cipherBytes += cipherBytesPart2;
- }
- PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024);
-
- wrBuf->len = cipherBytes + headerLen;
- wrBuf->buf[0] = type;
- if (isDTLS) {
- SSL3ProtocolVersion version;
-
- version = dtls_TLSVersionToDTLSVersion(cwSpec->version);
- wrBuf->buf[1] = MSB(version);
- wrBuf->buf[2] = LSB(version);
- wrBuf->buf[3] = (unsigned char)(cwSpec->write_seq_num.high >> 24);
- wrBuf->buf[4] = (unsigned char)(cwSpec->write_seq_num.high >> 16);
- wrBuf->buf[5] = (unsigned char)(cwSpec->write_seq_num.high >> 8);
- wrBuf->buf[6] = (unsigned char)(cwSpec->write_seq_num.high >> 0);
- wrBuf->buf[7] = (unsigned char)(cwSpec->write_seq_num.low >> 24);
- wrBuf->buf[8] = (unsigned char)(cwSpec->write_seq_num.low >> 16);
- wrBuf->buf[9] = (unsigned char)(cwSpec->write_seq_num.low >> 8);
- wrBuf->buf[10] = (unsigned char)(cwSpec->write_seq_num.low >> 0);
- wrBuf->buf[11] = MSB(cipherBytes);
- wrBuf->buf[12] = LSB(cipherBytes);
- } else {
- SSL3ProtocolVersion version = cwSpec->version;
-
- if (capRecordVersion) {
- version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version);
- }
- wrBuf->buf[1] = MSB(version);
- wrBuf->buf[2] = LSB(version);
- wrBuf->buf[3] = MSB(cipherBytes);
- wrBuf->buf[4] = LSB(cipherBytes);
- }
-
- ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);
-
- return SECSuccess;
-}
-
-/* Process the plain text before sending it.
- * Returns the number of bytes of plaintext that were successfully sent
- * plus the number of bytes of plaintext that were copied into the
- * output (write) buffer.
- * Returns SECFailure on a hard IO error, memory error, or crypto error.
- * Does NOT return SECWouldBlock.
- *
- * Notes on the use of the private ssl flags:
- * (no private SSL flags)
- * Attempt to make and send SSL records for all plaintext
- * If non-blocking and a send gets WOULD_BLOCK,
- * or if the pending (ciphertext) buffer is not empty,
- * then buffer remaining bytes of ciphertext into pending buf,
- * and continue to do that for all succssive records until all
- * bytes are used.
- * ssl_SEND_FLAG_FORCE_INTO_BUFFER
- * As above, except this suppresses all write attempts, and forces
- * all ciphertext into the pending ciphertext buffer.
- * ssl_SEND_FLAG_USE_EPOCH (for DTLS)
- * Forces the use of the provided epoch
- * ssl_SEND_FLAG_CAP_RECORD_VERSION
- * Caps the record layer version number of TLS ClientHello to { 3, 1 }
- * (TLS 1.0). Some TLS 1.0 servers (which seem to use F5 BIG-IP) ignore
- * ClientHello.client_version and use the record layer version number
- * (TLSPlaintext.version) instead when negotiating protocol versions. In
- * addition, if the record layer version number of ClientHello is { 3, 2 }
- * (TLS 1.1) or higher, these servers reset the TCP connections. Set this
- * flag to work around such servers.
- */
-PRInt32
-ssl3_SendRecord( sslSocket * ss,
- DTLSEpoch epoch, /* DTLS only */
- SSL3ContentType type,
- const SSL3Opaque * pIn, /* input buffer */
- PRInt32 nIn, /* bytes of input */
- PRInt32 flags)
-{
- sslBuffer * wrBuf = &ss->sec.writeBuf;
- SECStatus rv;
- PRInt32 totalSent = 0;
- PRBool capRecordVersion;
-
- SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
- SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
- nIn));
- PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-
- capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
-
- if (capRecordVersion) {
- /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the
- * TLS initial ClientHello. */
- PORT_Assert(!IS_DTLS(ss));
- PORT_Assert(!ss->firstHsDone);
- PORT_Assert(type == content_handshake);
- PORT_Assert(ss->ssl3.hs.ws == wait_server_hello);
- }
-
- if (ss->ssl3.initialized == PR_FALSE) {
- /* This can happen on a server if the very first incoming record
- ** looks like a defective ssl3 record (e.g. too long), and we're
- ** trying to send an alert.
- */
- PR_ASSERT(type == content_alert);
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- return SECFailure; /* ssl3_InitState has set the error code. */
- }
- }
-
- /* check for Token Presence */
- if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
- PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
- return SECFailure;
- }
-
- while (nIn > 0) {
- PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
- unsigned int spaceNeeded;
- unsigned int numRecords;
-
- ssl_GetSpecReadLock(ss); /********************************/
-
- if (nIn > 1 && ss->opt.cbcRandomIV &&
- ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_1 &&
- type == content_application_data &&
- ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) {
- /* We will split the first byte of the record into its own record,
- * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h
- */
- numRecords = 2;
- } else {
- numRecords = 1;
- }
-
- spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE);
- if (ss->ssl3.cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
- ss->ssl3.cwSpec->cipher_def->type == type_block) {
- spaceNeeded += ss->ssl3.cwSpec->cipher_def->iv_size;
- }
- if (spaceNeeded > wrBuf->space) {
- rv = sslBuffer_Grow(wrBuf, spaceNeeded);
- if (rv != SECSuccess) {
- SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
- SSL_GETPID(), ss->fd, spaceNeeded));
- goto spec_locked_loser; /* sslBuffer_Grow set error code. */
- }
- }
-
- if (numRecords == 2) {
- sslBuffer secondRecord;
-
- rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
- ss->sec.isServer, IS_DTLS(ss),
- capRecordVersion, type, pIn,
- 1, wrBuf);
- if (rv != SECSuccess)
- goto spec_locked_loser;
-
- PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:",
- wrBuf->buf, wrBuf->len));
-
- secondRecord.buf = wrBuf->buf + wrBuf->len;
- secondRecord.len = 0;
- secondRecord.space = wrBuf->space - wrBuf->len;
-
- rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
- ss->sec.isServer, IS_DTLS(ss),
- capRecordVersion, type,
- pIn + 1, contentLen - 1,
- &secondRecord);
- if (rv == SECSuccess) {
- PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
- secondRecord.buf, secondRecord.len));
- wrBuf->len += secondRecord.len;
- }
- } else {
- if (!IS_DTLS(ss)) {
- rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
- ss->sec.isServer,
- IS_DTLS(ss),
- capRecordVersion,
- type, pIn,
- contentLen, wrBuf);
- } else {
- rv = dtls_CompressMACEncryptRecord(ss, epoch,
- !!(flags & ssl_SEND_FLAG_USE_EPOCH),
- type, pIn,
- contentLen, wrBuf);
- }
-
- if (rv == SECSuccess) {
- PRINT_BUF(50, (ss, "send (encrypted) record data:",
- wrBuf->buf, wrBuf->len));
- }
- }
-
-spec_locked_loser:
- ssl_ReleaseSpecReadLock(ss); /************************************/
-
- if (rv != SECSuccess)
- return SECFailure;
-
- pIn += contentLen;
- nIn -= contentLen;
- PORT_Assert( nIn >= 0 );
-
- /* If there's still some previously saved ciphertext,
- * or the caller doesn't want us to send the data yet,
- * then add all our new ciphertext to the amount previously saved.
- */
- if ((ss->pendingBuf.len > 0) ||
- (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
-
- rv = ssl_SaveWriteData(ss, wrBuf->buf, wrBuf->len);
- if (rv != SECSuccess) {
- /* presumably a memory error, SEC_ERROR_NO_MEMORY */
- return SECFailure;
- }
- wrBuf->len = 0; /* All cipher text is saved away. */
-
- if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
- PRInt32 sent;
- ss->handshakeBegun = 1;
- sent = ssl_SendSavedWriteData(ss);
- if (sent < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) {
- ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
- return SECFailure;
- }
- if (ss->pendingBuf.len) {
- flags |= ssl_SEND_FLAG_FORCE_INTO_BUFFER;
- }
- }
- } else if (wrBuf->len > 0) {
- PRInt32 sent;
- ss->handshakeBegun = 1;
- sent = ssl_DefSend(ss, wrBuf->buf, wrBuf->len,
- flags & ~ssl_SEND_FLAG_MASK);
- if (sent < 0) {
- if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
- ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);
- return SECFailure;
- }
- /* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */
- sent = 0;
- }
- wrBuf->len -= sent;
- if (wrBuf->len) {
- if (IS_DTLS(ss)) {
- /* DTLS just says no in this case. No buffering */
- PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
- return SECFailure;
- }
- /* now take all the remaining unsent new ciphertext and
- * append it to the buffer of previously unsent ciphertext.
- */
- rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len);
- if (rv != SECSuccess) {
- /* presumably a memory error, SEC_ERROR_NO_MEMORY */
- return SECFailure;
- }
- }
- }
- totalSent += contentLen;
- }
- return totalSent;
-}
-
-#define SSL3_PENDING_HIGH_WATER 1024
-
-/* Attempt to send the content of "in" in an SSL application_data record.
- * Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess.
- */
-int
-ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
- PRInt32 len, PRInt32 flags)
-{
- PRInt32 totalSent = 0;
- PRInt32 discarded = 0;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
- /* These flags for internal use only */
- PORT_Assert(!(flags & (ssl_SEND_FLAG_USE_EPOCH |
- ssl_SEND_FLAG_NO_RETRANSMIT)));
- if (len < 0 || !in) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
-
- if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER &&
- !ssl_SocketIsBlocking(ss)) {
- PORT_Assert(!ssl_SocketIsBlocking(ss));
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- return SECFailure;
- }
-
- if (ss->appDataBuffered && len) {
- PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered));
- if (in[0] != (unsigned char)(ss->appDataBuffered)) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- in++;
- len--;
- discarded = 1;
- }
- while (len > totalSent) {
- PRInt32 sent, toSend;
-
- if (totalSent > 0) {
- /*
- * The thread yield is intended to give the reader thread a
- * chance to get some cycles while the writer thread is in
- * the middle of a large application data write. (See
- * Bugzilla bug 127740, comment #1.)
- */
- ssl_ReleaseXmitBufLock(ss);
- PR_Sleep(PR_INTERVAL_NO_WAIT); /* PR_Yield(); */
- ssl_GetXmitBufLock(ss);
- }
- toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH);
- /*
- * Note that the 0 epoch is OK because flags will never require
- * its use, as guaranteed by the PORT_Assert above.
- */
- sent = ssl3_SendRecord(ss, 0, content_application_data,
- in + totalSent, toSend, flags);
- if (sent < 0) {
- if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) {
- PORT_Assert(ss->lastWriteBlocked);
- break;
- }
- return SECFailure; /* error code set by ssl3_SendRecord */
- }
- totalSent += sent;
- if (ss->pendingBuf.len) {
- /* must be a non-blocking socket */
- PORT_Assert(!ssl_SocketIsBlocking(ss));
- PORT_Assert(ss->lastWriteBlocked);
- break;
- }
- }
- if (ss->pendingBuf.len) {
- /* Must be non-blocking. */
- PORT_Assert(!ssl_SocketIsBlocking(ss));
- if (totalSent > 0) {
- ss->appDataBuffered = 0x100 | in[totalSent - 1];
- }
-
- totalSent = totalSent + discarded - 1;
- if (totalSent <= 0) {
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- totalSent = SECFailure;
- }
- return totalSent;
- }
- ss->appDataBuffered = 0;
- return totalSent + discarded;
-}
-
-/* Attempt to send buffered handshake messages.
- * This function returns SECSuccess or SECFailure, never SECWouldBlock.
- * Always set sendBuf.len to 0, even when returning SECFailure.
- *
- * Depending on whether we are doing DTLS or not, this either calls
- *
- * - ssl3_FlushHandshakeMessages if non-DTLS
- * - dtls_FlushHandshakeMessages if DTLS
- *
- * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(),
- * ssl3_AppendHandshake(), ssl3_SendClientHello(),
- * ssl3_SendHelloRequest(), ssl3_SendServerHelloDone(),
- * ssl3_SendFinished(),
- */
-static SECStatus
-ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
-{
- if (IS_DTLS(ss)) {
- return dtls_FlushHandshakeMessages(ss, flags);
- } else {
- return ssl3_FlushHandshakeMessages(ss, flags);
- }
-}
-
-/* Attempt to send the content of sendBuf buffer in an SSL handshake record.
- * This function returns SECSuccess or SECFailure, never SECWouldBlock.
- * Always set sendBuf.len to 0, even when returning SECFailure.
- *
- * Called from ssl3_FlushHandshake
- */
-static SECStatus
-ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags)
-{
- static const PRInt32 allowedFlags = ssl_SEND_FLAG_FORCE_INTO_BUFFER |
- ssl_SEND_FLAG_CAP_RECORD_VERSION;
- PRInt32 rv = SECSuccess;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-
- if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len)
- return rv;
-
- /* only these flags are allowed */
- PORT_Assert(!(flags & ~allowedFlags));
- if ((flags & ~allowedFlags) != 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- } else {
- rv = ssl3_SendRecord(ss, 0, content_handshake, ss->sec.ci.sendBuf.buf,
- ss->sec.ci.sendBuf.len, flags);
- }
- if (rv < 0) {
- int err = PORT_GetError();
- PORT_Assert(err != PR_WOULD_BLOCK_ERROR);
- if (err == PR_WOULD_BLOCK_ERROR) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- }
- } else if (rv < ss->sec.ci.sendBuf.len) {
- /* short write should never happen */
- PORT_Assert(rv >= ss->sec.ci.sendBuf.len);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- } else {
- rv = SECSuccess;
- }
-
- /* Whether we succeeded or failed, toss the old handshake data. */
- ss->sec.ci.sendBuf.len = 0;
- return rv;
-}
-
-/*
- * Called from ssl3_HandleAlert and from ssl3_HandleCertificate when
- * the remote client sends a negative response to our certificate request.
- * Returns SECFailure if the application has required client auth.
- * SECSuccess otherwise.
- */
-static SECStatus
-ssl3_HandleNoCertificate(sslSocket *ss)
-{
- if (ss->sec.peerCert != NULL) {
- if (ss->sec.peerKey != NULL) {
- SECKEY_DestroyPublicKey(ss->sec.peerKey);
- ss->sec.peerKey = NULL;
- }
- CERT_DestroyCertificate(ss->sec.peerCert);
- ss->sec.peerCert = NULL;
- }
- ssl3_CleanupPeerCerts(ss);
-
- /* If the server has required client-auth blindly but doesn't
- * actually look at the certificate it won't know that no
- * certificate was presented so we shutdown the socket to ensure
- * an error. We only do this if we haven't already completed the
- * first handshake because if we're redoing the handshake we
- * know the server is paying attention to the certificate.
- */
- if ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
- (!ss->firstHsDone &&
- (ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) {
- PRFileDesc * lower;
-
- if (ss->sec.uncache)
- ss->sec.uncache(ss->sec.ci.sid);
- SSL3_SendAlert(ss, alert_fatal, bad_certificate);
-
- lower = ss->fd->lower;
-#ifdef _WIN32
- lower->methods->shutdown(lower, PR_SHUTDOWN_SEND);
-#else
- lower->methods->shutdown(lower, PR_SHUTDOWN_BOTH);
-#endif
- PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/************************************************************************
- * Alerts
- */
-
-/*
-** Acquires both handshake and XmitBuf locks.
-** Called from: ssl3_IllegalParameter <-
-** ssl3_HandshakeFailure <-
-** ssl3_HandleAlert <- ssl3_HandleRecord.
-** ssl3_HandleChangeCipherSpecs <- ssl3_HandleRecord
-** ssl3_ConsumeHandshakeVariable <-
-** ssl3_HandleHelloRequest <-
-** ssl3_HandleServerHello <-
-** ssl3_HandleServerKeyExchange <-
-** ssl3_HandleCertificateRequest <-
-** ssl3_HandleServerHelloDone <-
-** ssl3_HandleClientHello <-
-** ssl3_HandleV2ClientHello <-
-** ssl3_HandleCertificateVerify <-
-** ssl3_HandleClientKeyExchange <-
-** ssl3_HandleCertificate <-
-** ssl3_HandleFinished <-
-** ssl3_HandleHandshakeMessage <-
-** ssl3_HandleRecord <-
-**
-*/
-SECStatus
-SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc)
-{
- uint8 bytes[2];
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send alert record, level=%d desc=%d",
- SSL_GETPID(), ss->fd, level, desc));
-
- bytes[0] = level;
- bytes[1] = desc;
-
- ssl_GetSSL3HandshakeLock(ss);
- if (level == alert_fatal) {
- if (!ss->opt.noCache && ss->sec.ci.sid && ss->sec.uncache) {
- ss->sec.uncache(ss->sec.ci.sid);
- }
- }
- ssl_GetXmitBufLock(ss);
- rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
- if (rv == SECSuccess) {
- PRInt32 sent;
- sent = ssl3_SendRecord(ss, 0, content_alert, bytes, 2,
- desc == no_certificate
- ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0);
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
- }
- ssl_ReleaseXmitBufLock(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv; /* error set by ssl3_FlushHandshake or ssl3_SendRecord */
-}
-
-/*
- * Send illegal_parameter alert. Set generic error number.
- */
-static SECStatus
-ssl3_IllegalParameter(sslSocket *ss)
-{
- PRBool isTLS;
-
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
- : SSL_ERROR_BAD_SERVER );
- return SECFailure;
-}
-
-/*
- * Send handshake_Failure alert. Set generic error number.
- */
-static SECStatus
-ssl3_HandshakeFailure(sslSocket *ss)
-{
- (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
- PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
- : SSL_ERROR_BAD_SERVER );
- return SECFailure;
-}
-
-static void
-ssl3_SendAlertForCertError(sslSocket * ss, PRErrorCode errCode)
-{
- SSL3AlertDescription desc = bad_certificate;
- PRBool isTLS = ss->version >= SSL_LIBRARY_VERSION_3_1_TLS;
-
- switch (errCode) {
- case SEC_ERROR_LIBRARY_FAILURE: desc = unsupported_certificate; break;
- case SEC_ERROR_EXPIRED_CERTIFICATE: desc = certificate_expired; break;
- case SEC_ERROR_REVOKED_CERTIFICATE: desc = certificate_revoked; break;
- case SEC_ERROR_INADEQUATE_KEY_USAGE:
- case SEC_ERROR_INADEQUATE_CERT_TYPE:
- desc = certificate_unknown; break;
- case SEC_ERROR_UNTRUSTED_CERT:
- desc = isTLS ? access_denied : certificate_unknown; break;
- case SEC_ERROR_UNKNOWN_ISSUER:
- case SEC_ERROR_UNTRUSTED_ISSUER:
- desc = isTLS ? unknown_ca : certificate_unknown; break;
- case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
- desc = isTLS ? unknown_ca : certificate_expired; break;
-
- case SEC_ERROR_CERT_NOT_IN_NAME_SPACE:
- case SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID:
- case SEC_ERROR_CA_CERT_INVALID:
- case SEC_ERROR_BAD_SIGNATURE:
- default: desc = bad_certificate; break;
- }
- SSL_DBG(("%d: SSL3[%d]: peer certificate is no good: error=%d",
- SSL_GETPID(), ss->fd, errCode));
-
- (void) SSL3_SendAlert(ss, alert_fatal, desc);
-}
-
-
-/*
- * Send decode_error alert. Set generic error number.
- */
-SECStatus
-ssl3_DecodeError(sslSocket *ss)
-{
- (void)SSL3_SendAlert(ss, alert_fatal,
- ss->version > SSL_LIBRARY_VERSION_3_0 ? decode_error
- : illegal_parameter);
- PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT
- : SSL_ERROR_BAD_SERVER );
- return SECFailure;
-}
-
-/* Called from ssl3_HandleRecord.
-** Caller must hold both RecvBuf and Handshake locks.
-*/
-static SECStatus
-ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
-{
- SSL3AlertLevel level;
- SSL3AlertDescription desc;
- int error;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle alert record", SSL_GETPID(), ss->fd));
-
- if (buf->len != 2) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_ALERT);
- return SECFailure;
- }
- level = (SSL3AlertLevel)buf->buf[0];
- desc = (SSL3AlertDescription)buf->buf[1];
- buf->len = 0;
- SSL_TRC(5, ("%d: SSL3[%d] received alert, level = %d, description = %d",
- SSL_GETPID(), ss->fd, level, desc));
-
- switch (desc) {
- case close_notify: ss->recvdCloseNotify = 1;
- error = SSL_ERROR_CLOSE_NOTIFY_ALERT; break;
- case unexpected_message: error = SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT;
- break;
- case bad_record_mac: error = SSL_ERROR_BAD_MAC_ALERT; break;
- case decryption_failed_RESERVED:
- error = SSL_ERROR_DECRYPTION_FAILED_ALERT;
- break;
- case record_overflow: error = SSL_ERROR_RECORD_OVERFLOW_ALERT; break;
- case decompression_failure: error = SSL_ERROR_DECOMPRESSION_FAILURE_ALERT;
- break;
- case handshake_failure: error = SSL_ERROR_HANDSHAKE_FAILURE_ALERT;
- break;
- case no_certificate: error = SSL_ERROR_NO_CERTIFICATE; break;
- case bad_certificate: error = SSL_ERROR_BAD_CERT_ALERT; break;
- case unsupported_certificate:error = SSL_ERROR_UNSUPPORTED_CERT_ALERT;break;
- case certificate_revoked: error = SSL_ERROR_REVOKED_CERT_ALERT; break;
- case certificate_expired: error = SSL_ERROR_EXPIRED_CERT_ALERT; break;
- case certificate_unknown: error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT;
- break;
- case illegal_parameter: error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT;break;
-
- /* All alerts below are TLS only. */
- case unknown_ca: error = SSL_ERROR_UNKNOWN_CA_ALERT; break;
- case access_denied: error = SSL_ERROR_ACCESS_DENIED_ALERT; break;
- case decode_error: error = SSL_ERROR_DECODE_ERROR_ALERT; break;
- case decrypt_error: error = SSL_ERROR_DECRYPT_ERROR_ALERT; break;
- case export_restriction: error = SSL_ERROR_EXPORT_RESTRICTION_ALERT;
- break;
- case protocol_version: error = SSL_ERROR_PROTOCOL_VERSION_ALERT; break;
- case insufficient_security: error = SSL_ERROR_INSUFFICIENT_SECURITY_ALERT;
- break;
- case internal_error: error = SSL_ERROR_INTERNAL_ERROR_ALERT; break;
- case user_canceled: error = SSL_ERROR_USER_CANCELED_ALERT; break;
- case no_renegotiation: error = SSL_ERROR_NO_RENEGOTIATION_ALERT; break;
-
- /* Alerts for TLS client hello extensions */
- case unsupported_extension:
- error = SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT; break;
- case certificate_unobtainable:
- error = SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT; break;
- case unrecognized_name:
- error = SSL_ERROR_UNRECOGNIZED_NAME_ALERT; break;
- case bad_certificate_status_response:
- error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break;
- case bad_certificate_hash_value:
- error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT; break;
- default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break;
- }
- if (level == alert_fatal) {
- if (!ss->opt.noCache) {
- if (ss->sec.uncache)
- ss->sec.uncache(ss->sec.ci.sid);
- }
- if ((ss->ssl3.hs.ws == wait_server_hello) &&
- (desc == handshake_failure)) {
- /* XXX This is a hack. We're assuming that any handshake failure
- * XXX on the client hello is a failure to match ciphers.
- */
- error = SSL_ERROR_NO_CYPHER_OVERLAP;
- }
- PORT_SetError(error);
- return SECFailure;
- }
- if ((desc == no_certificate) && (ss->ssl3.hs.ws == wait_client_cert)) {
- /* I'm a server. I've requested a client cert. He hasn't got one. */
- SECStatus rv;
-
- PORT_Assert(ss->sec.isServer);
- ss->ssl3.hs.ws = wait_client_key;
- rv = ssl3_HandleNoCertificate(ss);
- return rv;
- }
- return SECSuccess;
-}
-
-/*
- * Change Cipher Specs
- * Called from ssl3_HandleServerHelloDone,
- * ssl3_HandleClientHello,
- * and ssl3_HandleFinished
- *
- * Acquires and releases spec write lock, to protect switching the current
- * and pending write spec pointers.
- */
-
-static SECStatus
-ssl3_SendChangeCipherSpecs(sslSocket *ss)
-{
- uint8 change = change_cipher_spec_choice;
- ssl3CipherSpec * pwSpec;
- SECStatus rv;
- PRInt32 sent;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send change_cipher_spec record",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
- if (!IS_DTLS(ss)) {
- sent = ssl3_SendRecord(ss, 0, content_change_cipher_spec, &change, 1,
- ssl_SEND_FLAG_FORCE_INTO_BUFFER);
- if (sent < 0) {
- return (SECStatus)sent; /* error code set by ssl3_SendRecord */
- }
- } else {
- rv = dtls_QueueMessage(ss, content_change_cipher_spec, &change, 1);
- if (rv != SECSuccess) {
- return rv;
- }
- }
-
- /* swap the pending and current write specs. */
- ssl_GetSpecWriteLock(ss); /**************************************/
- pwSpec = ss->ssl3.pwSpec;
-
- ss->ssl3.pwSpec = ss->ssl3.cwSpec;
- ss->ssl3.cwSpec = pwSpec;
-
- SSL_TRC(3, ("%d: SSL3[%d] Set Current Write Cipher Suite to Pending",
- SSL_GETPID(), ss->fd ));
-
- /* We need to free up the contexts, keys and certs ! */
- /* If we are really through with the old cipher spec
- * (Both the read and write sides have changed) destroy it.
- */
- if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
- if (!IS_DTLS(ss)) {
- ssl3_DestroyCipherSpec(ss->ssl3.pwSpec, PR_FALSE/*freeSrvName*/);
- } else {
- /* With DTLS, we need to set a holddown timer in case the final
- * message got lost */
- ss->ssl3.hs.rtTimeoutMs = DTLS_FINISHED_TIMER_MS;
- dtls_StartTimer(ss, dtls_FinishedTimerCb);
- }
- }
- ssl_ReleaseSpecWriteLock(ss); /**************************************/
-
- return SECSuccess;
-}
-
-/* Called from ssl3_HandleRecord.
-** Caller must hold both RecvBuf and Handshake locks.
- *
- * Acquires and releases spec write lock, to protect switching the current
- * and pending write spec pointers.
-*/
-static SECStatus
-ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf)
-{
- ssl3CipherSpec * prSpec;
- SSL3WaitState ws = ss->ssl3.hs.ws;
- SSL3ChangeCipherSpecChoice change;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle change_cipher_spec record",
- SSL_GETPID(), ss->fd));
-
- if (ws != wait_change_cipher) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER);
- return SECFailure;
- }
-
- if(buf->len != 1) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
- return SECFailure;
- }
- change = (SSL3ChangeCipherSpecChoice)buf->buf[0];
- if (change != change_cipher_spec_choice) {
- /* illegal_parameter is correct here for both SSL3 and TLS. */
- (void)ssl3_IllegalParameter(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER);
- return SECFailure;
- }
- buf->len = 0;
-
- /* Swap the pending and current read specs. */
- ssl_GetSpecWriteLock(ss); /*************************************/
- prSpec = ss->ssl3.prSpec;
-
- ss->ssl3.prSpec = ss->ssl3.crSpec;
- ss->ssl3.crSpec = prSpec;
- ss->ssl3.hs.ws = wait_finished;
-
- SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending",
- SSL_GETPID(), ss->fd ));
-
- /* If we are really through with the old cipher prSpec
- * (Both the read and write sides have changed) destroy it.
- */
- if (ss->ssl3.prSpec == ss->ssl3.pwSpec) {
- ssl3_DestroyCipherSpec(ss->ssl3.prSpec, PR_FALSE/*freeSrvName*/);
- }
- ssl_ReleaseSpecWriteLock(ss); /*************************************/
- return SECSuccess;
-}
-
-/* This method uses PKCS11 to derive the MS from the PMS, where PMS
-** is a PKCS11 symkey. This is used in all cases except the
-** "triple bypass" with RSA key exchange.
-** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec.
-*/
-static SECStatus
-ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms)
-{
- ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
- const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def;
- unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random;
- unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random;
- PRBool isTLS = (PRBool)(kea_def->tls_keygen ||
- (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
- /*
- * Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH
- * which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size
- * data into a 48-byte value.
- */
- PRBool isDH = (PRBool) ((ss->ssl3.hs.kea_def->exchKeyType == kt_dh) ||
- (ss->ssl3.hs.kea_def->exchKeyType == kt_ecdh));
- SECStatus rv = SECFailure;
- CK_MECHANISM_TYPE master_derive;
- CK_MECHANISM_TYPE key_derive;
- SECItem params;
- CK_FLAGS keyFlags;
- CK_VERSION pms_version;
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
- if (isTLS) {
- if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH;
- else master_derive = CKM_TLS_MASTER_KEY_DERIVE;
- key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
- keyFlags = CKF_SIGN | CKF_VERIFY;
- } else {
- if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH;
- else master_derive = CKM_SSL3_MASTER_KEY_DERIVE;
- key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE;
- keyFlags = 0;
- }
-
- if (pms || !pwSpec->master_secret) {
- if (isDH) {
- master_params.pVersion = NULL;
- } else {
- master_params.pVersion = &pms_version;
- }
- master_params.RandomInfo.pClientRandom = cr;
- master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
- master_params.RandomInfo.pServerRandom = sr;
- master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
-
- params.data = (unsigned char *) &master_params;
- params.len = sizeof master_params;
- }
-
- if (pms != NULL) {
-#if defined(TRACE)
- if (ssl_trace >= 100) {
- SECStatus extractRV = PK11_ExtractKeyValue(pms);
- if (extractRV == SECSuccess) {
- SECItem * keyData = PK11_GetKeyData(pms);
- if (keyData && keyData->data && keyData->len) {
- ssl_PrintBuf(ss, "Pre-Master Secret",
- keyData->data, keyData->len);
- }
- }
- }
-#endif
- pwSpec->master_secret = PK11_DeriveWithFlags(pms, master_derive,
- &params, key_derive, CKA_DERIVE, 0, keyFlags);
- if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) {
- SSL3ProtocolVersion client_version;
- client_version = pms_version.major << 8 | pms_version.minor;
-
- if (IS_DTLS(ss)) {
- client_version = dtls_DTLSVersionToTLSVersion(client_version);
- }
-
- if (client_version != ss->clientHelloVersion) {
- /* Destroy it. Version roll-back detected. */
- PK11_FreeSymKey(pwSpec->master_secret);
- pwSpec->master_secret = NULL;
- }
- }
- if (pwSpec->master_secret == NULL) {
- /* Generate a faux master secret in the same slot as the old one. */
- PK11SlotInfo * slot = PK11_GetSlotFromKey((PK11SymKey *)pms);
- PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
-
- PK11_FreeSlot(slot);
- if (fpms != NULL) {
- pwSpec->master_secret = PK11_DeriveWithFlags(fpms,
- master_derive, &params, key_derive,
- CKA_DERIVE, 0, keyFlags);
- PK11_FreeSymKey(fpms);
- }
- }
- }
- if (pwSpec->master_secret == NULL) {
- /* Generate a faux master secret from the internal slot. */
- PK11SlotInfo * slot = PK11_GetInternalSlot();
- PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
-
- PK11_FreeSlot(slot);
- if (fpms != NULL) {
- pwSpec->master_secret = PK11_DeriveWithFlags(fpms,
- master_derive, &params, key_derive,
- CKA_DERIVE, 0, keyFlags);
- if (pwSpec->master_secret == NULL) {
- pwSpec->master_secret = fpms; /* use the fpms as the master. */
- fpms = NULL;
- }
- }
- if (fpms) {
- PK11_FreeSymKey(fpms);
- }
- }
- if (pwSpec->master_secret == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return rv;
- }
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- SECItem * keydata;
- /* In hope of doing a "double bypass",
- * need to extract the master secret's value from the key object
- * and store it raw in the sslSocket struct.
- */
- rv = PK11_ExtractKeyValue(pwSpec->master_secret);
- if (rv != SECSuccess) {
-#if defined(NSS_SURVIVE_DOUBLE_BYPASS_FAILURE)
- /* The double bypass failed.
- * Attempt to revert to an all PKCS#11, non-bypass method.
- * Do we need any unacquired locks here?
- */
- ss->opt.bypassPKCS11 = 0;
- rv = ssl3_NewHandshakeHashes(ss);
- if (rv == SECSuccess) {
- rv = ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.messages.buf,
- ss->ssl3.hs.messages.len);
- }
-#endif
- return rv;
- }
- /* This returns the address of the secItem inside the key struct,
- * not a copy or a reference. So, there's no need to free it.
- */
- keydata = PK11_GetKeyData(pwSpec->master_secret);
- if (keydata && keydata->len <= sizeof pwSpec->raw_master_secret) {
- memcpy(pwSpec->raw_master_secret, keydata->data, keydata->len);
- pwSpec->msItem.data = pwSpec->raw_master_secret;
- pwSpec->msItem.len = keydata->len;
- } else {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- }
-#endif
- return SECSuccess;
-}
-
-
-/*
- * Derive encryption and MAC Keys (and IVs) from master secret
- * Sets a useful error code when returning SECFailure.
- *
- * Called only from ssl3_InitPendingCipherSpec(),
- * which in turn is called from
- * sendRSAClientKeyExchange (for Full handshake)
- * sendDHClientKeyExchange (for Full handshake)
- * ssl3_HandleClientKeyExchange (for Full handshake)
- * ssl3_HandleServerHello (for session restart)
- * ssl3_HandleClientHello (for session restart)
- * Caller MUST hold the specWriteLock, and SSL3HandshakeLock.
- * ssl3_InitPendingCipherSpec does that.
- *
- */
-static SECStatus
-ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss)
-{
- ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
- const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
- unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random;
- unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random;
- PRBool isTLS = (PRBool)(kea_def->tls_keygen ||
- (pwSpec->version > SSL_LIBRARY_VERSION_3_0));
- /* following variables used in PKCS11 path */
- const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
- PK11SlotInfo * slot = NULL;
- PK11SymKey * symKey = NULL;
- void * pwArg = ss->pkcs11PinArg;
- int keySize;
- CK_SSL3_KEY_MAT_PARAMS key_material_params;
- CK_SSL3_KEY_MAT_OUT returnedKeys;
- CK_MECHANISM_TYPE key_derive;
- CK_MECHANISM_TYPE bulk_mechanism;
- SSLCipherAlgorithm calg;
- SECItem params;
- PRBool skipKeysAndIVs = (PRBool)(cipher_def->calg == calg_null);
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
-
- if (!pwSpec->master_secret) {
- PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return SECFailure;
- }
- /*
- * generate the key material
- */
- key_material_params.ulMacSizeInBits = pwSpec->mac_size * BPB;
- key_material_params.ulKeySizeInBits = cipher_def->secret_key_size* BPB;
- key_material_params.ulIVSizeInBits = cipher_def->iv_size * BPB;
-
- key_material_params.bIsExport = (CK_BBOOL)(kea_def->is_limited);
- /* was: (CK_BBOOL)(cipher_def->keygen_mode != kg_strong); */
-
- key_material_params.RandomInfo.pClientRandom = cr;
- key_material_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH;
- key_material_params.RandomInfo.pServerRandom = sr;
- key_material_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH;
- key_material_params.pReturnedKeyMaterial = &returnedKeys;
-
- returnedKeys.pIVClient = pwSpec->client.write_iv;
- returnedKeys.pIVServer = pwSpec->server.write_iv;
- keySize = cipher_def->key_size;
-
- if (skipKeysAndIVs) {
- keySize = 0;
- key_material_params.ulKeySizeInBits = 0;
- key_material_params.ulIVSizeInBits = 0;
- returnedKeys.pIVClient = NULL;
- returnedKeys.pIVServer = NULL;
- }
-
- calg = cipher_def->calg;
- PORT_Assert( alg2Mech[calg].calg == calg);
- bulk_mechanism = alg2Mech[calg].cmech;
-
- params.data = (unsigned char *)&key_material_params;
- params.len = sizeof(key_material_params);
-
- if (isTLS) {
- key_derive = CKM_TLS_KEY_AND_MAC_DERIVE;
- } else {
- key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE;
- }
-
- /* CKM_SSL3_KEY_AND_MAC_DERIVE is defined to set ENCRYPT, DECRYPT, and
- * DERIVE by DEFAULT */
- symKey = PK11_Derive(pwSpec->master_secret, key_derive, &params,
- bulk_mechanism, CKA_ENCRYPT, keySize);
- if (!symKey) {
- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return SECFailure;
- }
- /* we really should use the actual mac'ing mechanism here, but we
- * don't because these types are used to map keytype anyway and both
- * mac's map to the same keytype.
- */
- slot = PK11_GetSlotFromKey(symKey);
-
- PK11_FreeSlot(slot); /* slot is held until the key is freed */
- pwSpec->client.write_mac_key =
- PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
- CKM_SSL3_SHA1_MAC, returnedKeys.hClientMacSecret, PR_TRUE, pwArg);
- if (pwSpec->client.write_mac_key == NULL ) {
- goto loser; /* loser sets err */
- }
- pwSpec->server.write_mac_key =
- PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
- CKM_SSL3_SHA1_MAC, returnedKeys.hServerMacSecret, PR_TRUE, pwArg);
- if (pwSpec->server.write_mac_key == NULL ) {
- goto loser; /* loser sets err */
- }
- if (!skipKeysAndIVs) {
- pwSpec->client.write_key =
- PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
- bulk_mechanism, returnedKeys.hClientKey, PR_TRUE, pwArg);
- if (pwSpec->client.write_key == NULL ) {
- goto loser; /* loser sets err */
- }
- pwSpec->server.write_key =
- PK11_SymKeyFromHandle(slot, symKey, PK11_OriginDerive,
- bulk_mechanism, returnedKeys.hServerKey, PR_TRUE, pwArg);
- if (pwSpec->server.write_key == NULL ) {
- goto loser; /* loser sets err */
- }
- }
- PK11_FreeSymKey(symKey);
- return SECSuccess;
-
-
-loser:
- if (symKey) PK11_FreeSymKey(symKey);
- ssl_MapLowLevelError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
- return SECFailure;
-}
-
-static SECStatus
-ssl3_RestartHandshakeHashes(sslSocket *ss)
-{
- SECStatus rv = SECSuccess;
-
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- ss->ssl3.hs.messages.len = 0;
- MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
- SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
- } else
-#endif
- {
- rv = PK11_DigestBegin(ss->ssl3.hs.md5);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return rv;
- }
- rv = PK11_DigestBegin(ss->ssl3.hs.sha);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return rv;
- }
- }
- return rv;
-}
-
-static SECStatus
-ssl3_NewHandshakeHashes(sslSocket *ss)
-{
- PK11Context *md5 = NULL;
- PK11Context *sha = NULL;
-
- /*
- * note: We should probably lookup an SSL3 slot for these
- * handshake hashes in hopes that we wind up with the same slots
- * that the master secret will wind up in ...
- */
- SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space);
- ss->ssl3.hs.messages.buf = NULL;
- ss->ssl3.hs.messages.space = 0;
- } else
-#endif
- {
- ss->ssl3.hs.md5 = md5 = PK11_CreateDigestContext(SEC_OID_MD5);
- ss->ssl3.hs.sha = sha = PK11_CreateDigestContext(SEC_OID_SHA1);
- if (md5 == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- goto loser;
- }
- if (sha == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- goto loser;
- }
- }
- if (SECSuccess == ssl3_RestartHandshakeHashes(ss)) {
- return SECSuccess;
- }
-
-loser:
- if (md5 != NULL) {
- PK11_DestroyContext(md5, PR_TRUE);
- ss->ssl3.hs.md5 = NULL;
- }
- if (sha != NULL) {
- PK11_DestroyContext(sha, PR_TRUE);
- ss->ssl3.hs.sha = NULL;
- }
- return SECFailure;
-
-}
-
-/*
- * Handshake messages
- */
-/* Called from ssl3_AppendHandshake()
-** ssl3_StartHandshakeHash()
-** ssl3_HandleV2ClientHello()
-** ssl3_HandleHandshakeMessage()
-** Caller must hold the ssl3Handshake lock.
-*/
-static SECStatus
-ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b,
- unsigned int l)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- PRINT_BUF(90, (NULL, "MD5 & SHA handshake hash input:", b, l));
-
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l);
- SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l);
-#if defined(NSS_SURVIVE_DOUBLE_BYPASS_FAILURE)
- rv = sslBuffer_Append(&ss->ssl3.hs.messages, b, l);
-#endif
- return rv;
- }
-#endif
- rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return rv;
- }
- rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- return rv;
- }
- return rv;
-}
-
-/**************************************************************************
- * Append Handshake functions.
- * All these functions set appropriate error codes.
- * Most rely on ssl3_AppendHandshake to set the error code.
- **************************************************************************/
-SECStatus
-ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes)
-{
- unsigned char * src = (unsigned char *)void_src;
- int room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len;
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); /* protects sendBuf. */
-
- if (!bytes)
- return SECSuccess;
- if (ss->sec.ci.sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) {
- rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH,
- PR_MIN(MAX_SEND_BUF_LENGTH, ss->sec.ci.sendBuf.len + bytes)));
- if (rv != SECSuccess)
- return rv; /* sslBuffer_Grow has set a memory error code. */
- room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len;
- }
-
- PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char*)void_src, bytes));
- rv = ssl3_UpdateHandshakeHashes(ss, src, bytes);
- if (rv != SECSuccess)
- return rv; /* error code set by ssl3_UpdateHandshakeHashes */
-
- while (bytes > room) {
- if (room > 0)
- PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src,
- room);
- ss->sec.ci.sendBuf.len += room;
- rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
- bytes -= room;
- src += room;
- room = ss->sec.ci.sendBuf.space;
- PORT_Assert(ss->sec.ci.sendBuf.len == 0);
- }
- PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, bytes);
- ss->sec.ci.sendBuf.len += bytes;
- return SECSuccess;
-}
-
-SECStatus
-ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize)
-{
- SECStatus rv;
- uint8 b[4];
- uint8 * p = b;
-
- switch (lenSize) {
- case 4:
- *p++ = (num >> 24) & 0xff;
- case 3:
- *p++ = (num >> 16) & 0xff;
- case 2:
- *p++ = (num >> 8) & 0xff;
- case 1:
- *p = num & 0xff;
- }
- SSL_TRC(60, ("%d: number:", SSL_GETPID()));
- rv = ssl3_AppendHandshake(ss, &b[0], lenSize);
- return rv; /* error code set by AppendHandshake, if applicable. */
-}
-
-SECStatus
-ssl3_AppendHandshakeVariable(
- sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize)
-{
- SECStatus rv;
-
- PORT_Assert((bytes < (1<<8) && lenSize == 1) ||
- (bytes < (1L<<16) && lenSize == 2) ||
- (bytes < (1L<<24) && lenSize == 3));
-
- SSL_TRC(60,("%d: append variable:", SSL_GETPID()));
- rv = ssl3_AppendHandshakeNumber(ss, bytes, lenSize);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
- SSL_TRC(60, ("data:"));
- rv = ssl3_AppendHandshake(ss, src, bytes);
- return rv; /* error code set by AppendHandshake, if applicable. */
-}
-
-SECStatus
-ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length)
-{
- SECStatus rv;
-
- /* If we already have a message in place, we need to enqueue it.
- * This empties the buffer. This is a convenient place to call
- * dtls_StageHandshakeMessage to mark the message boundary.
- */
- if (IS_DTLS(ss)) {
- rv = dtls_StageHandshakeMessage(ss);
- if (rv != SECSuccess) {
- return rv;
- }
- }
-
- SSL_TRC(30,("%d: SSL3[%d]: append handshake header: type %s",
- SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)));
- PRINT_BUF(60, (ss, "MD5 handshake hash:",
- (unsigned char*)ss->ssl3.hs.md5_cx, MD5_LENGTH));
- PRINT_BUF(95, (ss, "SHA handshake hash:",
- (unsigned char*)ss->ssl3.hs.sha_cx, SHA1_LENGTH));
-
- rv = ssl3_AppendHandshakeNumber(ss, t, 1);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, length, 3);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
-
- if (IS_DTLS(ss)) {
- /* Note that we make an unfragmented message here. We fragment in the
- * transmission code, if necessary */
- rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.sendMessageSeq, 2);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
- ss->ssl3.hs.sendMessageSeq++;
-
- /* 0 is the fragment offset, because it's not fragmented yet */
- rv = ssl3_AppendHandshakeNumber(ss, 0, 3);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
-
- /* Fragment length -- set to the packet length because not fragmented */
- rv = ssl3_AppendHandshakeNumber(ss, length, 3);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake, if applicable. */
- }
- }
-
- return rv; /* error code set by AppendHandshake, if applicable. */
-}
-
-/**************************************************************************
- * Consume Handshake functions.
- *
- * All data used in these functions is protected by two locks,
- * the RecvBufLock and the SSL3HandshakeLock
- **************************************************************************/
-
-/* Read up the next "bytes" number of bytes from the (decrypted) input
- * stream "b" (which is *length bytes long). Copy them into buffer "v".
- * Reduces *length by bytes. Advances *b by bytes.
- *
- * If this function returns SECFailure, it has already sent an alert,
- * and has set a generic error code. The caller should probably
- * override the generic error code by setting another.
- */
-SECStatus
-ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b,
- PRUint32 *length)
-{
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if ((PRUint32)bytes > *length) {
- return ssl3_DecodeError(ss);
- }
- PORT_Memcpy(v, *b, bytes);
- PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));
- *b += bytes;
- *length -= bytes;
- return SECSuccess;
-}
-
-/* Read up the next "bytes" number of bytes from the (decrypted) input
- * stream "b" (which is *length bytes long), and interpret them as an
- * integer in network byte order. Returns the received value.
- * Reduces *length by bytes. Advances *b by bytes.
- *
- * Returns SECFailure (-1) on failure.
- * This value is indistinguishable from the equivalent received value.
- * Only positive numbers are to be received this way.
- * Thus, the largest value that may be sent this way is 0x7fffffff.
- * On error, an alert has been sent, and a generic error code has been set.
- */
-PRInt32
-ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b,
- PRUint32 *length)
-{
- uint8 *buf = *b;
- int i;
- PRInt32 num = 0;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( bytes <= sizeof num);
-
- if ((PRUint32)bytes > *length) {
- return ssl3_DecodeError(ss);
- }
- PRINT_BUF(60, (ss, "consume bytes:", *b, bytes));
-
- for (i = 0; i < bytes; i++)
- num = (num << 8) + buf[i];
- *b += bytes;
- *length -= bytes;
- return num;
-}
-
-/* Read in two values from the incoming decrypted byte stream "b", which is
- * *length bytes long. The first value is a number whose size is "bytes"
- * bytes long. The second value is a byte-string whose size is the value
- * of the first number received. The latter byte-string, and its length,
- * is returned in the SECItem i.
- *
- * Returns SECFailure (-1) on failure.
- * On error, an alert has been sent, and a generic error code has been set.
- *
- * RADICAL CHANGE for NSS 3.11. All callers of this function make copies
- * of the data returned in the SECItem *i, so making a copy of it here
- * is simply wasteful. So, This function now just sets SECItem *i to
- * point to the values in the buffer **b.
- */
-SECStatus
-ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes,
- SSL3Opaque **b, PRUint32 *length)
-{
- PRInt32 count;
-
- PORT_Assert(bytes <= 3);
- i->len = 0;
- i->data = NULL;
- count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length);
- if (count < 0) { /* Can't test for SECSuccess here. */
- return SECFailure;
- }
- if (count > 0) {
- if ((PRUint32)count > *length) {
- return ssl3_DecodeError(ss);
- }
- i->data = *b;
- i->len = count;
- *b += count;
- *length -= count;
- }
- return SECSuccess;
-}
-
-/**************************************************************************
- * end of Consume Handshake functions.
- **************************************************************************/
-
-/* Extract the hashes of handshake messages to this point.
- * Called from ssl3_SendCertificateVerify
- * ssl3_SendFinished
- * ssl3_HandleHandshakeMessage
- *
- * Caller must hold the SSL3HandshakeLock.
- * Caller must hold a read or write lock on the Spec R/W lock.
- * (There is presently no way to assert on a Read lock.)
- */
-static SECStatus
-ssl3_ComputeHandshakeHashes(sslSocket * ss,
- ssl3CipherSpec *spec, /* uses ->master_secret */
- SSL3Hashes * hashes, /* output goes here. */
- PRUint32 sender)
-{
- SECStatus rv = SECSuccess;
- PRBool isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
- unsigned int outLength;
- SSL3Opaque md5_inner[MAX_MAC_LENGTH];
- SSL3Opaque sha_inner[MAX_MAC_LENGTH];
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- /* compute them without PKCS11 */
- PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS];
- PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
-
-#define md5cx ((MD5Context *)md5_cx)
-#define shacx ((SHA1Context *)sha_cx)
-
- if (!spec->msItem.data) {
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
- return SECFailure;
- }
-
- MD5_Clone (md5cx, (MD5Context *)ss->ssl3.hs.md5_cx);
- SHA1_Clone(shacx, (SHA1Context *)ss->ssl3.hs.sha_cx);
-
- if (!isTLS) {
- /* compute hashes for SSL3. */
- unsigned char s[4];
-
- s[0] = (unsigned char)(sender >> 24);
- s[1] = (unsigned char)(sender >> 16);
- s[2] = (unsigned char)(sender >> 8);
- s[3] = (unsigned char)sender;
-
- if (sender != 0) {
- MD5_Update(md5cx, s, 4);
- PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
- }
-
- PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1,
- mac_defs[mac_md5].pad_size));
-
- MD5_Update(md5cx, spec->msItem.data, spec->msItem.len);
- MD5_Update(md5cx, mac_pad_1, mac_defs[mac_md5].pad_size);
- MD5_End(md5cx, md5_inner, &outLength, MD5_LENGTH);
-
- PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));
-
- if (sender != 0) {
- SHA1_Update(shacx, s, 4);
- PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
- }
-
- PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1,
- mac_defs[mac_sha].pad_size));
-
- SHA1_Update(shacx, spec->msItem.data, spec->msItem.len);
- SHA1_Update(shacx, mac_pad_1, mac_defs[mac_sha].pad_size);
- SHA1_End(shacx, sha_inner, &outLength, SHA1_LENGTH);
-
- PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
- PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2,
- mac_defs[mac_md5].pad_size));
- PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));
-
- MD5_Begin(md5cx);
- MD5_Update(md5cx, spec->msItem.data, spec->msItem.len);
- MD5_Update(md5cx, mac_pad_2, mac_defs[mac_md5].pad_size);
- MD5_Update(md5cx, md5_inner, MD5_LENGTH);
- }
- MD5_End(md5cx, hashes->md5, &outLength, MD5_LENGTH);
-
- PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH));
-
- if (!isTLS) {
- PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2,
- mac_defs[mac_sha].pad_size));
- PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));
-
- SHA1_Begin(shacx);
- SHA1_Update(shacx, spec->msItem.data, spec->msItem.len);
- SHA1_Update(shacx, mac_pad_2, mac_defs[mac_sha].pad_size);
- SHA1_Update(shacx, sha_inner, SHA1_LENGTH);
- }
- SHA1_End(shacx, hashes->sha, &outLength, SHA1_LENGTH);
-
- PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH));
-
- rv = SECSuccess;
-#undef md5cx
-#undef shacx
- } else
-#endif
- {
- /* compute hases with PKCS11 */
- PK11Context * md5;
- PK11Context * sha = NULL;
- unsigned char *md5StateBuf = NULL;
- unsigned char *shaStateBuf = NULL;
- unsigned int md5StateLen, shaStateLen;
- unsigned char md5StackBuf[256];
- unsigned char shaStackBuf[512];
-
- if (!spec->master_secret) {
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
- return SECFailure;
- }
-
- md5StateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.md5, md5StackBuf,
- sizeof md5StackBuf, &md5StateLen);
- if (md5StateBuf == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- goto loser;
- }
- md5 = ss->ssl3.hs.md5;
-
- shaStateBuf = PK11_SaveContextAlloc(ss->ssl3.hs.sha, shaStackBuf,
- sizeof shaStackBuf, &shaStateLen);
- if (shaStateBuf == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- goto loser;
- }
- sha = ss->ssl3.hs.sha;
-
- if (!isTLS) {
- /* compute hashes for SSL3. */
- unsigned char s[4];
-
- s[0] = (unsigned char)(sender >> 24);
- s[1] = (unsigned char)(sender >> 16);
- s[2] = (unsigned char)(sender >> 8);
- s[3] = (unsigned char)sender;
-
- if (sender != 0) {
- rv |= PK11_DigestOp(md5, s, 4);
- PRINT_BUF(95, (NULL, "MD5 inner: sender", s, 4));
- }
-
- PRINT_BUF(95, (NULL, "MD5 inner: MAC Pad 1", mac_pad_1,
- mac_defs[mac_md5].pad_size));
-
- rv |= PK11_DigestKey(md5,spec->master_secret);
- rv |= PK11_DigestOp(md5, mac_pad_1, mac_defs[mac_md5].pad_size);
- rv |= PK11_DigestFinal(md5, md5_inner, &outLength, MD5_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
-
- PRINT_BUF(95, (NULL, "MD5 inner: result", md5_inner, outLength));
-
- if (sender != 0) {
- rv |= PK11_DigestOp(sha, s, 4);
- PRINT_BUF(95, (NULL, "SHA inner: sender", s, 4));
- }
-
- PRINT_BUF(95, (NULL, "SHA inner: MAC Pad 1", mac_pad_1,
- mac_defs[mac_sha].pad_size));
-
- rv |= PK11_DigestKey(sha, spec->master_secret);
- rv |= PK11_DigestOp(sha, mac_pad_1, mac_defs[mac_sha].pad_size);
- rv |= PK11_DigestFinal(sha, sha_inner, &outLength, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
-
- PRINT_BUF(95, (NULL, "SHA inner: result", sha_inner, outLength));
-
- PRINT_BUF(95, (NULL, "MD5 outer: MAC Pad 2", mac_pad_2,
- mac_defs[mac_md5].pad_size));
- PRINT_BUF(95, (NULL, "MD5 outer: MD5 inner", md5_inner, MD5_LENGTH));
-
- rv |= PK11_DigestBegin(md5);
- rv |= PK11_DigestKey(md5, spec->master_secret);
- rv |= PK11_DigestOp(md5, mac_pad_2, mac_defs[mac_md5].pad_size);
- rv |= PK11_DigestOp(md5, md5_inner, MD5_LENGTH);
- }
- rv |= PK11_DigestFinal(md5, hashes->md5, &outLength, MD5_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
-
- PRINT_BUF(60, (NULL, "MD5 outer: result", hashes->md5, MD5_LENGTH));
-
- if (!isTLS) {
- PRINT_BUF(95, (NULL, "SHA outer: MAC Pad 2", mac_pad_2,
- mac_defs[mac_sha].pad_size));
- PRINT_BUF(95, (NULL, "SHA outer: SHA inner", sha_inner, SHA1_LENGTH));
-
- rv |= PK11_DigestBegin(sha);
- rv |= PK11_DigestKey(sha,spec->master_secret);
- rv |= PK11_DigestOp(sha, mac_pad_2, mac_defs[mac_sha].pad_size);
- rv |= PK11_DigestOp(sha, sha_inner, SHA1_LENGTH);
- }
- rv |= PK11_DigestFinal(sha, hashes->sha, &outLength, SHA1_LENGTH);
- PORT_Assert(rv != SECSuccess || outLength == SHA1_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
-
- PRINT_BUF(60, (NULL, "SHA outer: result", hashes->sha, SHA1_LENGTH));
-
- rv = SECSuccess;
-
- loser:
- if (md5StateBuf) {
- if (PK11_RestoreContext(ss->ssl3.hs.md5, md5StateBuf, md5StateLen)
- != SECSuccess)
- {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- }
- if (md5StateBuf != md5StackBuf) {
- PORT_ZFree(md5StateBuf, md5StateLen);
- }
- }
- if (shaStateBuf) {
- if (PK11_RestoreContext(ss->ssl3.hs.sha, shaStateBuf, shaStateLen)
- != SECSuccess)
- {
- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
- rv = SECFailure;
- }
- if (shaStateBuf != shaStackBuf) {
- PORT_ZFree(shaStateBuf, shaStateLen);
- }
- }
- }
- return rv;
-}
-
-/*
- * SSL 2 based implementations pass in the initial outbound buffer
- * so that the handshake hash can contain the included information.
- *
- * Called from ssl2_BeginClientHandshake() in sslcon.c
- */
-SECStatus
-ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length)
-{
- SECStatus rv;
-
- ssl_GetSSL3HandshakeLock(ss); /**************************************/
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- goto done; /* ssl3_InitState has set the error code. */
- }
-
- PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(
- &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - SSL_CHALLENGE_BYTES],
- &ss->sec.ci.clientChallenge,
- SSL_CHALLENGE_BYTES);
-
- rv = ssl3_UpdateHandshakeHashes(ss, buf, length);
- /* if it failed, ssl3_UpdateHandshakeHashes has set the error code. */
-
-done:
- ssl_ReleaseSSL3HandshakeLock(ss); /**************************************/
- return rv;
-}
-
-/**************************************************************************
- * end of Handshake Hash functions.
- * Begin Send and Handle functions for handshakes.
- **************************************************************************/
-
-/* Called from ssl3_HandleHelloRequest(),
- * ssl3_RedoHandshake()
- * ssl2_BeginClientHandshake (when resuming ssl3 session)
- * dtls_HandleHelloVerifyRequest(with resending=PR_TRUE)
- */
-SECStatus
-ssl3_SendClientHello(sslSocket *ss, PRBool resending)
-{
- sslSessionID * sid;
- ssl3CipherSpec * cwSpec;
- SECStatus rv;
- int i;
- int length;
- int num_suites;
- int actual_count = 0;
- PRBool isTLS = PR_FALSE;
- PRBool requestingResume = PR_FALSE;
- PRInt32 total_exten_len = 0;
- unsigned numCompressionMethods;
- PRInt32 flags;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),
- ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- return rv; /* ssl3_InitState has set the error code. */
- }
- ss->ssl3.hs.sendingSCSV = PR_FALSE; /* Must be reset every handshake */
- PORT_Assert(IS_DTLS(ss) || !resending);
-
- /* We might be starting a session renegotiation in which case we should
- * clear previous state.
- */
- PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
-
- SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
- SSL_GETPID(), ss->fd ));
- rv = ssl3_RestartHandshakeHashes(ss);
- if (rv != SECSuccess) {
- return rv;
- }
-
- /*
- * During a renegotiation, ss->clientHelloVersion will be used again to
- * work around a Windows SChannel bug. Ensure that it is still enabled.
- */
- if (ss->firstHsDone) {
- if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- return SECFailure;
- }
-
- if (ss->clientHelloVersion < ss->vrange.min ||
- ss->clientHelloVersion > ss->vrange.max) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
- }
-
- /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup
- * handles expired entries and other details.
- * XXX If we've been called from ssl2_BeginClientHandshake, then
- * this lookup is duplicative and wasteful.
- */
- sid = (ss->opt.noCache) ? NULL
- : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url);
-
- /* We can't resume based on a different token. If the sid exists,
- * make sure the token that holds the master secret still exists ...
- * If we previously did client-auth, make sure that the token that holds
- * the private key still exists, is logged in, hasn't been removed, etc.
- */
- if (sid) {
- PRBool sidOK = PR_TRUE;
- if (sid->u.ssl3.keys.msIsWrapped) {
- /* Session key was wrapped, which means it was using PKCS11, */
- PK11SlotInfo *slot = NULL;
- if (sid->u.ssl3.masterValid && !ss->opt.bypassPKCS11) {
- slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
- sid->u.ssl3.masterSlotID);
- }
- if (slot == NULL) {
- sidOK = PR_FALSE;
- } else {
- PK11SymKey *wrapKey = NULL;
- if (!PK11_IsPresent(slot) ||
- ((wrapKey = PK11_GetWrapKey(slot,
- sid->u.ssl3.masterWrapIndex,
- sid->u.ssl3.masterWrapMech,
- sid->u.ssl3.masterWrapSeries,
- ss->pkcs11PinArg)) == NULL) ) {
- sidOK = PR_FALSE;
- }
- if (wrapKey) PK11_FreeSymKey(wrapKey);
- PK11_FreeSlot(slot);
- slot = NULL;
- }
- }
- /* If we previously did client-auth, make sure that the token that
- ** holds the private key still exists, is logged in, hasn't been
- ** removed, etc.
- */
- if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) {
- sidOK = PR_FALSE;
- }
-
- /* TLS 1.0 (RFC 2246) Appendix E says:
- * Whenever a client already knows the highest protocol known to
- * a server (for example, when resuming a session), it should
- * initiate the connection in that native protocol.
- * So we pass sid->version to ssl3_NegotiateVersion() here, except
- * when renegotiating.
- *
- * Windows SChannel compares the client_version inside the RSA
- * EncryptedPreMasterSecret of a renegotiation with the
- * client_version of the initial ClientHello rather than the
- * ClientHello in the renegotiation. To work around this bug, we
- * continue to use the client_version used in the initial
- * ClientHello when renegotiating.
- */
- if (sidOK) {
- if (ss->firstHsDone) {
- /*
- * The client_version of the initial ClientHello is still
- * available in ss->clientHelloVersion. Ensure that
- * sid->version is bounded within
- * [ss->vrange.min, ss->clientHelloVersion], otherwise we
- * can't use sid.
- */
- if (sid->version >= ss->vrange.min &&
- sid->version <= ss->clientHelloVersion) {
- ss->version = ss->clientHelloVersion;
- } else {
- sidOK = PR_FALSE;
- }
- } else {
- if (ssl3_NegotiateVersion(ss, sid->version,
- PR_FALSE) != SECSuccess) {
- sidOK = PR_FALSE;
- }
- }
- }
-
- if (!sidOK) {
- SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok );
- if (ss->sec.uncache)
- (*ss->sec.uncache)(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
- }
-
- if (sid) {
- requestingResume = PR_TRUE;
- SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
-
- /* Are we attempting a stateless session resume? */
- if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
- sid->u.ssl3.sessionTicket.ticket.data)
- SSL_AtomicIncrementLong(& ssl3stats.sch_sid_stateless_resumes );
-
- PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
- sid->u.ssl3.sessionIDLength));
-
- ss->ssl3.policy = sid->u.ssl3.policy;
- } else {
- SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses );
-
- /*
- * Windows SChannel compares the client_version inside the RSA
- * EncryptedPreMasterSecret of a renegotiation with the
- * client_version of the initial ClientHello rather than the
- * ClientHello in the renegotiation. To work around this bug, we
- * continue to use the client_version used in the initial
- * ClientHello when renegotiating.
- */
- if (ss->firstHsDone) {
- ss->version = ss->clientHelloVersion;
- } else {
- rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
- PR_TRUE);
- if (rv != SECSuccess)
- return rv; /* error code was set */
- }
-
- sid = ssl3_NewSessionID(ss, PR_FALSE);
- if (!sid) {
- return SECFailure; /* memory error is set */
- }
- }
-
- isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
- ssl_GetSpecWriteLock(ss);
- cwSpec = ss->ssl3.cwSpec;
- if (cwSpec->mac_def->mac == mac_null) {
- /* SSL records are not being MACed. */
- cwSpec->version = ss->version;
- }
- ssl_ReleaseSpecWriteLock(ss);
-
- if (ss->sec.ci.sid != NULL) {
- ssl_FreeSID(ss->sec.ci.sid); /* decrement ref count, free if zero */
- }
- ss->sec.ci.sid = sid;
-
- ss->sec.send = ssl3_SendApplicationData;
-
- /* shouldn't get here if SSL3 is disabled, but ... */
- if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- PR_NOT_REACHED("No versions of SSL 3.0 or later are enabled");
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- return SECFailure;
- }
-
- /* how many suites does our PKCS11 support (regardless of policy)? */
- num_suites = ssl3_config_match_init(ss);
- if (!num_suites)
- return SECFailure; /* ssl3_config_match_init has set error code. */
-
- /* HACK for SCSV in SSL 3.0. On initial handshake, prepend SCSV,
- * only if we're willing to complete an SSL 3.0 handshake.
- */
- if (!ss->firstHsDone && ss->vrange.min == SSL_LIBRARY_VERSION_3_0) {
- /* Must set this before calling Hello Extension Senders,
- * to suppress sending of empty RI extension.
- */
- ss->ssl3.hs.sendingSCSV = PR_TRUE;
- }
-
- if (isTLS || (ss->firstHsDone && ss->peerRequestedProtection)) {
- PRUint32 maxBytes = 65535; /* 2^16 - 1 */
- PRInt32 extLen;
-
- extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL);
- if (extLen < 0) {
- return SECFailure;
- }
- maxBytes -= extLen;
- total_exten_len += extLen;
-
- if (total_exten_len > 0)
- total_exten_len += 2;
- }
-
-#if defined(NSS_ENABLE_ECC)
- if (!total_exten_len || !isTLS) {
- /* not sending the elliptic_curves and ec_point_formats extensions */
- ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
- }
-#endif
-
- if (IS_DTLS(ss)) {
- ssl3_DisableNonDTLSSuites(ss);
- }
-
- /* how many suites are permitted by policy and user preference? */
- num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE);
- if (!num_suites)
- return SECFailure; /* count_cipher_suites has set error code. */
- if (ss->ssl3.hs.sendingSCSV) {
- ++num_suites; /* make room for SCSV */
- }
-
- /* count compression methods */
- numCompressionMethods = 0;
- for (i = 0; i < compressionMethodsCount; i++) {
- if (compressionEnabled(ss, compressions[i]))
- numCompressionMethods++;
- }
-
- length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH +
- 1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) +
- 2 + num_suites*sizeof(ssl3CipherSuite) +
- 1 + numCompressionMethods + total_exten_len;
- if (IS_DTLS(ss)) {
- length += 1 + ss->ssl3.hs.cookieLen;
- }
-
- rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
- if (ss->firstHsDone) {
- /* The client hello version must stay unchanged to work around
- * the Windows SChannel bug described above. */
- PORT_Assert(ss->version == ss->clientHelloVersion);
- }
- ss->clientHelloVersion = ss->version;
- if (IS_DTLS(ss)) {
- PRUint16 version;
-
- version = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
- rv = ssl3_AppendHandshakeNumber(ss, version, 2);
- } else {
- rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);
- }
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
- if (!resending) { /* Don't re-generate if we are in DTLS re-sending mode */
- rv = ssl3_GetNewRandom(&ss->ssl3.hs.client_random);
- if (rv != SECSuccess) {
- return rv; /* err set by GetNewRandom. */
- }
- }
- rv = ssl3_AppendHandshake(ss, &ss->ssl3.hs.client_random,
- SSL3_RANDOM_LENGTH);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
- if (sid)
- rv = ssl3_AppendHandshakeVariable(
- ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
- else
- rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
- if (IS_DTLS(ss)) {
- rv = ssl3_AppendHandshakeVariable(
- ss, ss->ssl3.hs.cookie, ss->ssl3.hs.cookieLen, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- }
-
- rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
-
- if (ss->ssl3.hs.sendingSCSV) {
- /* Add the actual SCSV */
- rv = ssl3_AppendHandshakeNumber(ss, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
- sizeof(ssl3CipherSuite));
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- actual_count++;
- }
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (config_match(suite, ss->ssl3.policy, PR_TRUE)) {
- actual_count++;
- if (actual_count > num_suites) {
- /* set error card removal/insertion error */
- PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
- return SECFailure;
- }
- rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite,
- sizeof(ssl3CipherSuite));
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- }
- }
-
- /* if cards were removed or inserted between count_cipher_suites and
- * generating our list, detect the error here rather than send it off to
- * the server.. */
- if (actual_count != num_suites) {
- /* Card removal/insertion error */
- PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
- return SECFailure;
- }
-
- rv = ssl3_AppendHandshakeNumber(ss, numCompressionMethods, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- for (i = 0; i < compressionMethodsCount; i++) {
- if (!compressionEnabled(ss, compressions[i]))
- continue;
- rv = ssl3_AppendHandshakeNumber(ss, compressions[i], 1);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_AppendHandshake* */
- }
- }
-
- if (total_exten_len) {
- PRUint32 maxBytes = total_exten_len - 2;
- PRInt32 extLen;
-
- rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
-
- extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL);
- if (extLen < 0) {
- return SECFailure;
- }
- maxBytes -= extLen;
- PORT_Assert(!maxBytes);
- }
- if (ss->ssl3.hs.sendingSCSV) {
- /* Since we sent the SCSV, pretend we sent empty RI extension. */
- TLSExtensionData *xtnData = &ss->xtnData;
- xtnData->advertised[xtnData->numAdvertised++] =
- ssl_renegotiation_info_xtn;
- }
-
- flags = 0;
- if (!ss->firstHsDone && !requestingResume && !IS_DTLS(ss)) {
- flags |= ssl_SEND_FLAG_CAP_RECORD_VERSION;
- }
- rv = ssl3_FlushHandshake(ss, flags);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
-
- ss->ssl3.hs.ws = wait_server_hello;
- return rv;
-}
-
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Hello Request.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleHelloRequest(sslSocket *ss)
-{
- sslSessionID *sid = ss->sec.ci.sid;
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle hello_request handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3.hs.ws == wait_server_hello)
- return SECSuccess;
- if (ss->ssl3.hs.ws != idle_handshake || ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST);
- return SECFailure;
- }
- if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
- ssl_GetXmitBufLock(ss);
- rv = SSL3_SendAlert(ss, alert_warning, no_renegotiation);
- ssl_ReleaseXmitBufLock(ss);
- PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
- return SECFailure;
- }
-
- if (sid) {
- if (ss->sec.uncache)
- ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- ss->sec.ci.sid = NULL;
- }
-
- if (IS_DTLS(ss)) {
- dtls_RehandshakeCleanup(ss);
- }
-
- ssl_GetXmitBufLock(ss);
- rv = ssl3_SendClientHello(ss, PR_FALSE);
- ssl_ReleaseXmitBufLock(ss);
-
- return rv;
-}
-
-#define UNKNOWN_WRAP_MECHANISM 0x7fffffff
-
-static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = {
- CKM_DES3_ECB,
- CKM_CAST5_ECB,
- CKM_DES_ECB,
- CKM_KEY_WRAP_LYNKS,
- CKM_IDEA_ECB,
- CKM_CAST3_ECB,
- CKM_CAST_ECB,
- CKM_RC5_ECB,
- CKM_RC2_ECB,
- CKM_CDMF_ECB,
- CKM_SKIPJACK_WRAP,
- CKM_SKIPJACK_CBC64,
- CKM_AES_ECB,
- CKM_CAMELLIA_ECB,
- CKM_SEED_ECB,
- UNKNOWN_WRAP_MECHANISM
-};
-
-static int
-ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech)
-{
- const CK_MECHANISM_TYPE *pMech = wrapMechanismList;
-
- while (mech != *pMech && *pMech != UNKNOWN_WRAP_MECHANISM) {
- ++pMech;
- }
- return (*pMech == UNKNOWN_WRAP_MECHANISM) ? -1
- : (pMech - wrapMechanismList);
-}
-
-static PK11SymKey *
-ssl_UnwrapSymWrappingKey(
- SSLWrappedSymWrappingKey *pWswk,
- SECKEYPrivateKey * svrPrivKey,
- SSL3KEAType exchKeyType,
- CK_MECHANISM_TYPE masterWrapMech,
- void * pwArg)
-{
- PK11SymKey * unwrappedWrappingKey = NULL;
- SECItem wrappedKey;
-#ifdef NSS_ENABLE_ECC
- PK11SymKey * Ks;
- SECKEYPublicKey pubWrapKey;
- ECCWrappedKeyInfo *ecWrapped;
-#endif /* NSS_ENABLE_ECC */
-
- /* found the wrapping key on disk. */
- PORT_Assert(pWswk->symWrapMechanism == masterWrapMech);
- PORT_Assert(pWswk->exchKeyType == exchKeyType);
- if (pWswk->symWrapMechanism != masterWrapMech ||
- pWswk->exchKeyType != exchKeyType) {
- goto loser;
- }
- wrappedKey.type = siBuffer;
- wrappedKey.data = pWswk->wrappedSymmetricWrappingkey;
- wrappedKey.len = pWswk->wrappedSymKeyLen;
- PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey);
-
- switch (exchKeyType) {
-
- case kt_rsa:
- unwrappedWrappingKey =
- PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
- masterWrapMech, CKA_UNWRAP, 0);
- break;
-
-#ifdef NSS_ENABLE_ECC
- case kt_ecdh:
- /*
- * For kt_ecdh, we first create an EC public key based on
- * data stored with the wrappedSymmetricWrappingkey. Next,
- * we do an ECDH computation involving this public key and
- * the SSL server's (long-term) EC private key. The resulting
- * shared secret is treated the same way as Fortezza's Ks, i.e.,
- * it is used to recover the symmetric wrapping key.
- *
- * The data in wrappedSymmetricWrappingkey is laid out as defined
- * in the ECCWrappedKeyInfo structure.
- */
- ecWrapped = (ECCWrappedKeyInfo *) pWswk->wrappedSymmetricWrappingkey;
-
- PORT_Assert(ecWrapped->encodedParamLen + ecWrapped->pubValueLen +
- ecWrapped->wrappedKeyLen <= MAX_EC_WRAPPED_KEY_BUFLEN);
-
- if (ecWrapped->encodedParamLen + ecWrapped->pubValueLen +
- ecWrapped->wrappedKeyLen > MAX_EC_WRAPPED_KEY_BUFLEN) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- goto loser;
- }
-
- pubWrapKey.keyType = ecKey;
- pubWrapKey.u.ec.size = ecWrapped->size;
- pubWrapKey.u.ec.DEREncodedParams.len = ecWrapped->encodedParamLen;
- pubWrapKey.u.ec.DEREncodedParams.data = ecWrapped->var;
- pubWrapKey.u.ec.publicValue.len = ecWrapped->pubValueLen;
- pubWrapKey.u.ec.publicValue.data = ecWrapped->var +
- ecWrapped->encodedParamLen;
-
- wrappedKey.len = ecWrapped->wrappedKeyLen;
- wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen +
- ecWrapped->pubValueLen;
-
- /* Derive Ks using ECDH */
- Ks = PK11_PubDeriveWithKDF(svrPrivKey, &pubWrapKey, PR_FALSE, NULL,
- NULL, CKM_ECDH1_DERIVE, masterWrapMech,
- CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
- if (Ks == NULL) {
- goto loser;
- }
-
- /* Use Ks to unwrap the wrapping key */
- unwrappedWrappingKey = PK11_UnwrapSymKey(Ks, masterWrapMech, NULL,
- &wrappedKey, masterWrapMech,
- CKA_UNWRAP, 0);
- PK11_FreeSymKey(Ks);
-
- break;
-#endif
-
- default:
- /* Assert? */
- SET_ERROR_CODE
- goto loser;
- }
-loser:
- return unwrappedWrappingKey;
-}
-
-/* Each process sharing the server session ID cache has its own array of
- * SymKey pointers for the symmetric wrapping keys that are used to wrap
- * the master secrets. There is one key for each KEA type. These Symkeys
- * correspond to the wrapped SymKeys kept in the server session cache.
- */
-
-typedef struct {
- PK11SymKey * symWrapKey[kt_kea_size];
-} ssl3SymWrapKey;
-
-static PZLock * symWrapKeysLock = NULL;
-static ssl3SymWrapKey symWrapKeys[SSL_NUM_WRAP_MECHS];
-
-SECStatus ssl_FreeSymWrapKeysLock(void)
-{
- if (symWrapKeysLock) {
- PZ_DestroyLock(symWrapKeysLock);
- symWrapKeysLock = NULL;
- return SECSuccess;
- }
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
-}
-
-SECStatus
-SSL3_ShutdownServerCache(void)
-{
- int i, j;
-
- if (!symWrapKeysLock)
- return SECSuccess; /* lock was never initialized */
- PZ_Lock(symWrapKeysLock);
- /* get rid of all symWrapKeys */
- for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) {
- for (j = 0; j < kt_kea_size; ++j) {
- PK11SymKey ** pSymWrapKey;
- pSymWrapKey = &symWrapKeys[i].symWrapKey[j];
- if (*pSymWrapKey) {
- PK11_FreeSymKey(*pSymWrapKey);
- *pSymWrapKey = NULL;
- }
- }
- }
-
- PZ_Unlock(symWrapKeysLock);
- ssl_FreeSessionCacheLocks();
- return SECSuccess;
-}
-
-SECStatus ssl_InitSymWrapKeysLock(void)
-{
- symWrapKeysLock = PZ_NewLock(nssILockOther);
- return symWrapKeysLock ? SECSuccess : SECFailure;
-}
-
-/* Try to get wrapping key for mechanism from in-memory array.
- * If that fails, look for one on disk.
- * If that fails, generate a new one, put the new one on disk,
- * Put the new key in the in-memory array.
- */
-static PK11SymKey *
-getWrappingKey( sslSocket * ss,
- PK11SlotInfo * masterSecretSlot,
- SSL3KEAType exchKeyType,
- CK_MECHANISM_TYPE masterWrapMech,
- void * pwArg)
-{
- SECKEYPrivateKey * svrPrivKey;
- SECKEYPublicKey * svrPubKey = NULL;
- PK11SymKey * unwrappedWrappingKey = NULL;
- PK11SymKey ** pSymWrapKey;
- CK_MECHANISM_TYPE asymWrapMechanism = CKM_INVALID_MECHANISM;
- int length;
- int symWrapMechIndex;
- SECStatus rv;
- SECItem wrappedKey;
- SSLWrappedSymWrappingKey wswk;
-#ifdef NSS_ENABLE_ECC
- PK11SymKey * Ks = NULL;
- SECKEYPublicKey *pubWrapKey = NULL;
- SECKEYPrivateKey *privWrapKey = NULL;
- ECCWrappedKeyInfo *ecWrapped;
-#endif /* NSS_ENABLE_ECC */
-
- svrPrivKey = ss->serverCerts[exchKeyType].SERVERKEY;
- PORT_Assert(svrPrivKey != NULL);
- if (!svrPrivKey) {
- return NULL; /* why are we here?!? */
- }
-
- symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech);
- PORT_Assert(symWrapMechIndex >= 0);
- if (symWrapMechIndex < 0)
- return NULL; /* invalid masterWrapMech. */
-
- pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[exchKeyType];
-
- ssl_InitSessionCacheLocks(PR_TRUE);
-
- PZ_Lock(symWrapKeysLock);
-
- unwrappedWrappingKey = *pSymWrapKey;
- if (unwrappedWrappingKey != NULL) {
- if (PK11_VerifyKeyOK(unwrappedWrappingKey)) {
- unwrappedWrappingKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
- goto done;
- }
- /* slot series has changed, so this key is no good any more. */
- PK11_FreeSymKey(unwrappedWrappingKey);
- *pSymWrapKey = unwrappedWrappingKey = NULL;
- }
-
- /* Try to get wrapped SymWrapping key out of the (disk) cache. */
- /* Following call fills in wswk on success. */
- if (ssl_GetWrappingKey(symWrapMechIndex, exchKeyType, &wswk)) {
- /* found the wrapped sym wrapping key on disk. */
- unwrappedWrappingKey =
- ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType,
- masterWrapMech, pwArg);
- if (unwrappedWrappingKey) {
- goto install;
- }
- }
-
- if (!masterSecretSlot) /* caller doesn't want to create a new one. */
- goto loser;
-
- length = PK11_GetBestKeyLength(masterSecretSlot, masterWrapMech);
- /* Zero length means fixed key length algorithm, or error.
- * It's ambiguous.
- */
- unwrappedWrappingKey = PK11_KeyGen(masterSecretSlot, masterWrapMech, NULL,
- length, pwArg);
- if (!unwrappedWrappingKey) {
- goto loser;
- }
-
- /* Prepare the buffer to receive the wrappedWrappingKey,
- * the symmetric wrapping key wrapped using the server's pub key.
- */
- PORT_Memset(&wswk, 0, sizeof wswk); /* eliminate UMRs. */
-
- if (ss->serverCerts[exchKeyType].serverKeyPair) {
- svrPubKey = ss->serverCerts[exchKeyType].serverKeyPair->pubKey;
- }
- if (svrPubKey == NULL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- goto loser;
- }
- wrappedKey.type = siBuffer;
- wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey);
- wrappedKey.data = wswk.wrappedSymmetricWrappingkey;
-
- PORT_Assert(wrappedKey.len <= sizeof wswk.wrappedSymmetricWrappingkey);
- if (wrappedKey.len > sizeof wswk.wrappedSymmetricWrappingkey)
- goto loser;
-
- /* wrap symmetric wrapping key in server's public key. */
- switch (exchKeyType) {
- case kt_rsa:
- asymWrapMechanism = CKM_RSA_PKCS;
- rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey,
- unwrappedWrappingKey, &wrappedKey);
- break;
-
-#ifdef NSS_ENABLE_ECC
- case kt_ecdh:
- /*
- * We generate an ephemeral EC key pair. Perform an ECDH
- * computation involving this ephemeral EC public key and
- * the SSL server's (long-term) EC private key. The resulting
- * shared secret is treated in the same way as Fortezza's Ks,
- * i.e., it is used to wrap the wrapping key. To facilitate
- * unwrapping in ssl_UnwrapWrappingKey, we also store all
- * relevant info about the ephemeral EC public key in
- * wswk.wrappedSymmetricWrappingkey and lay it out as
- * described in the ECCWrappedKeyInfo structure.
- */
- PORT_Assert(svrPubKey->keyType == ecKey);
- if (svrPubKey->keyType != ecKey) {
- /* something is wrong in sslsecur.c if this isn't an ecKey */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
- goto ec_cleanup;
- }
-
- privWrapKey = SECKEY_CreateECPrivateKey(
- &svrPubKey->u.ec.DEREncodedParams, &pubWrapKey, NULL);
- if ((privWrapKey == NULL) || (pubWrapKey == NULL)) {
- rv = SECFailure;
- goto ec_cleanup;
- }
-
- /* Set the key size in bits */
- if (pubWrapKey->u.ec.size == 0) {
- pubWrapKey->u.ec.size = SECKEY_PublicKeyStrengthInBits(svrPubKey);
- }
-
- PORT_Assert(pubWrapKey->u.ec.DEREncodedParams.len +
- pubWrapKey->u.ec.publicValue.len < MAX_EC_WRAPPED_KEY_BUFLEN);
- if (pubWrapKey->u.ec.DEREncodedParams.len +
- pubWrapKey->u.ec.publicValue.len >= MAX_EC_WRAPPED_KEY_BUFLEN) {
- PORT_SetError(SEC_ERROR_INVALID_KEY);
- rv = SECFailure;
- goto ec_cleanup;
- }
-
- /* Derive Ks using ECDH */
- Ks = PK11_PubDeriveWithKDF(svrPrivKey, pubWrapKey, PR_FALSE, NULL,
- NULL, CKM_ECDH1_DERIVE, masterWrapMech,
- CKA_DERIVE, 0, CKD_NULL, NULL, NULL);
- if (Ks == NULL) {
- rv = SECFailure;
- goto ec_cleanup;
- }
-
- ecWrapped = (ECCWrappedKeyInfo *) (wswk.wrappedSymmetricWrappingkey);
- ecWrapped->size = pubWrapKey->u.ec.size;
- ecWrapped->encodedParamLen = pubWrapKey->u.ec.DEREncodedParams.len;
- PORT_Memcpy(ecWrapped->var, pubWrapKey->u.ec.DEREncodedParams.data,
- pubWrapKey->u.ec.DEREncodedParams.len);
-
- ecWrapped->pubValueLen = pubWrapKey->u.ec.publicValue.len;
- PORT_Memcpy(ecWrapped->var + ecWrapped->encodedParamLen,
- pubWrapKey->u.ec.publicValue.data,
- pubWrapKey->u.ec.publicValue.len);
-
- wrappedKey.len = MAX_EC_WRAPPED_KEY_BUFLEN -
- (ecWrapped->encodedParamLen + ecWrapped->pubValueLen);
- wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen +
- ecWrapped->pubValueLen;
-
- /* wrap symmetricWrapping key with the local Ks */
- rv = PK11_WrapSymKey(masterWrapMech, NULL, Ks,
- unwrappedWrappingKey, &wrappedKey);
-
- if (rv != SECSuccess) {
- goto ec_cleanup;
- }
-
- /* Write down the length of wrapped key in the buffer
- * wswk.wrappedSymmetricWrappingkey at the appropriate offset
- */
- ecWrapped->wrappedKeyLen = wrappedKey.len;
-
-ec_cleanup:
- if (privWrapKey) SECKEY_DestroyPrivateKey(privWrapKey);
- if (pubWrapKey) SECKEY_DestroyPublicKey(pubWrapKey);
- if (Ks) PK11_FreeSymKey(Ks);
- asymWrapMechanism = masterWrapMech;
- break;
-#endif /* NSS_ENABLE_ECC */
-
- default:
- rv = SECFailure;
- break;
- }
-
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- PORT_Assert(asymWrapMechanism != CKM_INVALID_MECHANISM);
-
- wswk.symWrapMechanism = masterWrapMech;
- wswk.symWrapMechIndex = symWrapMechIndex;
- wswk.asymWrapMechanism = asymWrapMechanism;
- wswk.exchKeyType = exchKeyType;
- wswk.wrappedSymKeyLen = wrappedKey.len;
-
- /* put it on disk. */
- /* If the wrapping key for this KEA type has already been set,
- * then abandon the value we just computed and
- * use the one we got from the disk.
- */
- if (ssl_SetWrappingKey(&wswk)) {
- /* somebody beat us to it. The original contents of our wswk
- * has been replaced with the content on disk. Now, discard
- * the key we just created and unwrap this new one.
- */
- PK11_FreeSymKey(unwrappedWrappingKey);
-
- unwrappedWrappingKey =
- ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, exchKeyType,
- masterWrapMech, pwArg);
- }
-
-install:
- if (unwrappedWrappingKey) {
- *pSymWrapKey = PK11_ReferenceSymKey(unwrappedWrappingKey);
- }
-
-loser:
-done:
- PZ_Unlock(symWrapKeysLock);
- return unwrappedWrappingKey;
-}
-
-/* hexEncode hex encodes |length| bytes from |in| and writes it as |length*2|
- * bytes to |out|. */
-static void
-hexEncode(char *out, const unsigned char *in, unsigned int length)
-{
- static const char hextable[] = "0123456789abcdef";
- unsigned int i;
-
- for (i = 0; i < length; i++) {
- *(out++) = hextable[in[i] >> 4];
- *(out++) = hextable[in[i] & 15];
- }
-}
-
-/* Called from ssl3_SendClientKeyExchange(). */
-/* Presently, this always uses PKCS11. There is no bypass for this. */
-static SECStatus
-sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
-{
- PK11SymKey * pms = NULL;
- SECStatus rv = SECFailure;
- SECItem enc_pms = {siBuffer, NULL, 0};
- PRBool isTLS;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
- /* Generate the pre-master secret ... */
- ssl_GetSpecWriteLock(ss);
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.pwSpec, NULL);
- ssl_ReleaseSpecWriteLock(ss);
- if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- /* Get the wrapped (encrypted) pre-master secret, enc_pms */
- enc_pms.len = SECKEY_PublicKeyStrength(svrPubKey);
- enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len);
- if (enc_pms.data == NULL) {
- goto loser; /* err set by PORT_Alloc */
- }
-
- /* wrap pre-master secret in server's public key. */
- rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, pms, &enc_pms);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- if (ssl_keylog_iob) {
- SECStatus extractRV = PK11_ExtractKeyValue(pms);
- if (extractRV == SECSuccess) {
- SECItem * keyData = PK11_GetKeyData(pms);
- if (keyData && keyData->data && keyData->len) {
-#ifdef TRACE
- if (ssl_trace >= 100) {
- ssl_PrintBuf(ss, "Pre-Master Secret",
- keyData->data, keyData->len);
- }
-#endif
- if (ssl_keylog_iob && enc_pms.len >= 8 && keyData->len == 48) {
- /* https://developer.mozilla.org/en/NSS_Key_Log_Format */
-
- /* There could be multiple, concurrent writers to the
- * keylog, so we have to do everything in a single call to
- * fwrite. */
- char buf[4 + 8*2 + 1 + 48*2 + 1];
-
- strcpy(buf, "RSA ");
- hexEncode(buf + 4, enc_pms.data, 8);
- buf[20] = ' ';
- hexEncode(buf + 21, keyData->data, 48);
- buf[sizeof(buf) - 1] = '\n';
-
- fwrite(buf, sizeof(buf), 1, ssl_keylog_iob);
- fflush(ssl_keylog_iob);
- }
- }
- }
- }
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
- isTLS ? enc_pms.len + 2 : enc_pms.len);
- if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
- if (isTLS) {
- rv = ssl3_AppendHandshakeVariable(ss, enc_pms.data, enc_pms.len, 2);
- } else {
- rv = ssl3_AppendHandshake(ss, enc_pms.data, enc_pms.len);
- }
- if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
-
- rv = SECSuccess;
-
-loser:
- if (enc_pms.data != NULL) {
- PORT_Free(enc_pms.data);
- }
- if (pms != NULL) {
- PK11_FreeSymKey(pms);
- }
- return rv;
-}
-
-/* Called from ssl3_SendClientKeyExchange(). */
-/* Presently, this always uses PKCS11. There is no bypass for this. */
-static SECStatus
-sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
-{
- PK11SymKey * pms = NULL;
- SECStatus rv = SECFailure;
- PRBool isTLS;
- CK_MECHANISM_TYPE target;
-
- SECKEYDHParams dhParam; /* DH parameters */
- SECKEYPublicKey *pubKey = NULL; /* Ephemeral DH key */
- SECKEYPrivateKey *privKey = NULL; /* Ephemeral DH key */
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- /* Copy DH parameters from server key */
-
- if (svrPubKey->keyType != dhKey) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- goto loser;
- }
- dhParam.prime.data = svrPubKey->u.dh.prime.data;
- dhParam.prime.len = svrPubKey->u.dh.prime.len;
- dhParam.base.data = svrPubKey->u.dh.base.data;
- dhParam.base.len = svrPubKey->u.dh.base.len;
-
- /* Generate ephemeral DH keypair */
- privKey = SECKEY_CreateDHPrivateKey(&dhParam, &pubKey, NULL);
- if (!privKey || !pubKey) {
- ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- rv = SECFailure;
- goto loser;
- }
- PRINT_BUF(50, (ss, "DH public value:",
- pubKey->u.dh.publicValue.data,
- pubKey->u.dh.publicValue.len));
-
- if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
- else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
-
- /* Determine the PMS */
-
- pms = PK11_PubDerive(privKey, svrPubKey, PR_FALSE, NULL, NULL,
- CKM_DH_PKCS_DERIVE, target, CKA_DERIVE, 0, NULL);
-
- if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- SECKEY_DestroyPrivateKey(privKey);
- privKey = NULL;
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
- pubKey->u.dh.publicValue.len + 2);
- if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
- rv = ssl3_AppendHandshakeVariable(ss,
- pubKey->u.dh.publicValue.data,
- pubKey->u.dh.publicValue.len, 2);
- SECKEY_DestroyPublicKey(pubKey);
- pubKey = NULL;
-
- if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
-
- rv = SECSuccess;
-
-
-loser:
-
- if(pms) PK11_FreeSymKey(pms);
- if(privKey) SECKEY_DestroyPrivateKey(privKey);
- if(pubKey) SECKEY_DestroyPublicKey(pubKey);
- return rv;
-}
-
-
-
-
-
-/* Called from ssl3_HandleServerHelloDone(). */
-static SECStatus
-ssl3_SendClientKeyExchange(sslSocket *ss)
-{
- SECKEYPublicKey * serverKey = NULL;
- SECStatus rv = SECFailure;
- PRBool isTLS;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send client_key_exchange handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- if (ss->sec.peerKey == NULL) {
- serverKey = CERT_ExtractPublicKey(ss->sec.peerCert);
- if (serverKey == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- return SECFailure;
- }
- } else {
- serverKey = ss->sec.peerKey;
- ss->sec.peerKey = NULL; /* we're done with it now */
- }
-
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- /* enforce limits on kea key sizes. */
- if (ss->ssl3.hs.kea_def->is_limited) {
- int keyLen = SECKEY_PublicKeyStrength(serverKey); /* bytes */
-
- if (keyLen * BPB > ss->ssl3.hs.kea_def->key_size_limit) {
- if (isTLS)
- (void)SSL3_SendAlert(ss, alert_fatal, export_restriction);
- else
- (void)ssl3_HandshakeFailure(ss);
- PORT_SetError(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED);
- goto loser;
- }
- }
-
- ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType;
- ss->sec.keaKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey);
-
- switch (ss->ssl3.hs.kea_def->exchKeyType) {
- case kt_rsa:
- rv = sendRSAClientKeyExchange(ss, serverKey);
- break;
-
- case kt_dh:
- rv = sendDHClientKeyExchange(ss, serverKey);
- break;
-
-#ifdef NSS_ENABLE_ECC
- case kt_ecdh:
- rv = ssl3_SendECDHClientKeyExchange(ss, serverKey);
- break;
-#endif /* NSS_ENABLE_ECC */
-
- default:
- /* got an unknown or unsupported Key Exchange Algorithm. */
- SEND_ALERT
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- break;
- }
-
- SSL_TRC(3, ("%d: SSL3[%d]: DONE sending client_key_exchange",
- SSL_GETPID(), ss->fd));
-
-loser:
- if (serverKey)
- SECKEY_DestroyPublicKey(serverKey);
- return rv; /* err code already set. */
-}
-
-/* Called from ssl3_HandleServerHelloDone(). */
-static SECStatus
-ssl3_SendCertificateVerify(sslSocket *ss)
-{
- SECStatus rv = SECFailure;
- PRBool isTLS;
- SECItem buf = {siBuffer, NULL, 0};
- SSL3Hashes hashes;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- SSL_TRC(3, ("%d: SSL3[%d]: send certificate_verify handshake",
- SSL_GETPID(), ss->fd));
-
- ssl_GetSpecReadLock(ss);
- rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
- ssl_ReleaseSpecReadLock(ss);
- if (rv != SECSuccess) {
- goto done; /* err code was set by ssl3_ComputeHandshakeHashes */
- }
-
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_SignHashes(&hashes, ss->ssl3.clientPrivateKey, &buf, isTLS);
- if (rv == SECSuccess) {
- PK11SlotInfo * slot;
- sslSessionID * sid = ss->sec.ci.sid;
-
- /* Remember the info about the slot that did the signing.
- ** Later, when doing an SSL restart handshake, verify this.
- ** These calls are mere accessors, and can't fail.
- */
- slot = PK11_GetSlotFromPrivateKey(ss->ssl3.clientPrivateKey);
- sid->u.ssl3.clAuthSeries = PK11_GetSlotSeries(slot);
- sid->u.ssl3.clAuthSlotID = PK11_GetSlotID(slot);
- sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot);
- sid->u.ssl3.clAuthValid = PR_TRUE;
- PK11_FreeSlot(slot);
- }
- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
- ss->ssl3.clientPrivateKey = NULL;
- if (rv != SECSuccess) {
- goto done; /* err code was set by ssl3_SignHashes */
- }
-
- rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, buf.len + 2);
- if (rv != SECSuccess) {
- goto done; /* error code set by AppendHandshake */
- }
- rv = ssl3_AppendHandshakeVariable(ss, buf.data, buf.len, 2);
- if (rv != SECSuccess) {
- goto done; /* error code set by AppendHandshake */
- }
-
-done:
- if (buf.data)
- PORT_Free(buf.data);
- return rv;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 ServerHello message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- sslSessionID *sid = ss->sec.ci.sid;
- PRInt32 temp; /* allow for consume number failure */
- PRBool suite_found = PR_FALSE;
- int i;
- int errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
- SECStatus rv;
- SECItem sidBytes = {siBuffer, NULL, 0};
- PRBool sid_match;
- PRBool isTLS = PR_FALSE;
- SSL3AlertDescription desc = illegal_parameter;
- SSL3ProtocolVersion version;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError(); /* ssl3_InitState has set the error code. */
- goto alert_loser;
- }
- if (ss->ssl3.hs.ws != wait_server_hello) {
- errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO;
- desc = unexpected_message;
- goto alert_loser;
- }
-
- /* clean up anything left from previous handshake. */
- if (ss->ssl3.clientCertChain != NULL) {
- CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
- ss->ssl3.clientCertChain = NULL;
- }
- if (ss->ssl3.clientCertificate != NULL) {
- CERT_DestroyCertificate(ss->ssl3.clientCertificate);
- ss->ssl3.clientCertificate = NULL;
- }
- if (ss->ssl3.clientPrivateKey != NULL) {
- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
- ss->ssl3.clientPrivateKey = NULL;
- }
-
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (temp < 0) {
- goto loser; /* alert has been sent */
- }
- version = (SSL3ProtocolVersion)temp;
-
- if (IS_DTLS(ss)) {
- /* RFC 4347 required that you verify that the server versions
- * match (Section 4.2.1) in the HelloVerifyRequest and the
- * ServerHello.
- *
- * RFC 6347 suggests (SHOULD) that servers always use 1.0
- * in HelloVerifyRequest and allows the versions not to match,
- * especially when 1.2 is being negotiated.
- *
- * Therefore we do not check for matching here.
- */
- version = dtls_DTLSVersionToTLSVersion(version);
- if (version == 0) { /* Insane version number */
- goto alert_loser;
- }
- }
-
- rv = ssl3_NegotiateVersion(ss, version, PR_FALSE);
- if (rv != SECSuccess) {
- desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
- : handshake_failure;
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
- }
- isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
-
- rv = ssl3_ConsumeHandshake(
- ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* alert has been sent */
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* alert has been sent */
- }
- if (sidBytes.len > SSL3_SESSIONID_BYTES) {
- if (isTLS)
- desc = decode_error;
- goto alert_loser; /* malformed. */
- }
-
- /* find selected cipher suite in our list. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (temp < 0) {
- goto loser; /* alert has been sent */
- }
- ssl3_config_match_init(ss);
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (temp == suite->cipher_suite) {
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE)) {
- break; /* failure */
- }
- if (!ssl3_CipherSuiteAllowedForVersion(suite->cipher_suite,
- ss->version)) {
- desc = handshake_failure;
- errCode = SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION;
- goto alert_loser;
- }
-
- suite_found = PR_TRUE;
- break; /* success */
- }
- }
- if (!suite_found) {
- desc = handshake_failure;
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
- }
- ss->ssl3.hs.cipher_suite = (ssl3CipherSuite)temp;
- ss->ssl3.hs.suite_def = ssl_LookupCipherSuiteDef((ssl3CipherSuite)temp);
- PORT_Assert(ss->ssl3.hs.suite_def);
- if (!ss->ssl3.hs.suite_def) {
- PORT_SetError(errCode = SEC_ERROR_LIBRARY_FAILURE);
- goto loser; /* we don't send alerts for our screw-ups. */
- }
-
- /* find selected compression method in our list. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length);
- if (temp < 0) {
- goto loser; /* alert has been sent */
- }
- suite_found = PR_FALSE;
- for (i = 0; i < compressionMethodsCount; i++) {
- if (temp == compressions[i]) {
- if (!compressionEnabled(ss, compressions[i])) {
- break; /* failure */
- }
- suite_found = PR_TRUE;
- break; /* success */
- }
- }
- if (!suite_found) {
- desc = handshake_failure;
- errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
- goto alert_loser;
- }
- ss->ssl3.hs.compression = (SSLCompressionMethod)temp;
-
- /* Note that if !isTLS and the extra stuff is not extensions, we
- * do NOT goto alert_loser.
- * There are some old SSL 3.0 implementations that do send stuff
- * after the end of the server hello, and we deliberately ignore
- * such stuff in the interest of maximal interoperability (being
- * "generous in what you accept").
- * Update: Starting in NSS 3.12.6, we handle the renegotiation_info
- * extension in SSL 3.0.
- */
- if (length != 0) {
- SECItem extensions;
- rv = ssl3_ConsumeHandshakeVariable(ss, &extensions, 2, &b, &length);
- if (rv != SECSuccess || length != 0) {
- if (isTLS)
- goto alert_loser;
- } else {
- rv = ssl3_HandleHelloExtensions(ss, &extensions.data,
- &extensions.len);
- if (rv != SECSuccess)
- goto alert_loser;
- }
- }
- if ((ss->opt.requireSafeNegotiation ||
- (ss->firstHsDone && (ss->peerRequestedProtection ||
- ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN))) &&
- !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
- desc = handshake_failure;
- errCode = ss->firstHsDone ? SSL_ERROR_RENEGOTIATION_NOT_ALLOWED
- : SSL_ERROR_UNSAFE_NEGOTIATION;
- goto alert_loser;
- }
-
- /* Any errors after this point are not "malformed" errors. */
- desc = handshake_failure;
-
- /* we need to call ssl3_SetupPendingCipherSpec here so we can check the
- * key exchange algorithm. */
- rv = ssl3_SetupPendingCipherSpec(ss);
- if (rv != SECSuccess) {
- goto alert_loser; /* error code is set. */
- }
-
- /* We may or may not have sent a session id, we may get one back or
- * not and if so it may match the one we sent.
- * Attempt to restore the master secret to see if this is so...
- * Don't consider failure to find a matching SID an error.
- */
- sid_match = (PRBool)(sidBytes.len > 0 &&
- sidBytes.len == sid->u.ssl3.sessionIDLength &&
- !PORT_Memcmp(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len));
-
- if (sid_match &&
- sid->version == ss->version &&
- sid->u.ssl3.cipherSuite == ss->ssl3.hs.cipher_suite) do {
- ssl3CipherSpec *pwSpec = ss->ssl3.pwSpec;
-
- SECItem wrappedMS; /* wrapped master secret. */
-
- ss->sec.authAlgorithm = sid->authAlgorithm;
- ss->sec.authKeyBits = sid->authKeyBits;
- ss->sec.keaType = sid->keaType;
- ss->sec.keaKeyBits = sid->keaKeyBits;
-
- /* 3 cases here:
- * a) key is wrapped (implies using PKCS11)
- * b) key is unwrapped, but we're still using PKCS11
- * c) key is unwrapped, and we're bypassing PKCS11.
- */
- if (sid->u.ssl3.keys.msIsWrapped) {
- PK11SlotInfo *slot;
- PK11SymKey * wrapKey; /* wrapping key */
- CK_FLAGS keyFlags = 0;
-
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- /* we cannot restart a non-bypass session in a
- ** bypass socket.
- */
- break;
- }
-#endif
- /* unwrap master secret with PKCS11 */
- slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,
- sid->u.ssl3.masterSlotID);
- if (slot == NULL) {
- break; /* not considered an error. */
- }
- if (!PK11_IsPresent(slot)) {
- PK11_FreeSlot(slot);
- break; /* not considered an error. */
- }
- wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,
- sid->u.ssl3.masterWrapMech,
- sid->u.ssl3.masterWrapSeries,
- ss->pkcs11PinArg);
- PK11_FreeSlot(slot);
- if (wrapKey == NULL) {
- break; /* not considered an error. */
- }
-
- if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- keyFlags = CKF_SIGN | CKF_VERIFY;
- }
-
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- pwSpec->master_secret =
- PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
- NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
- CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
- errCode = PORT_GetError();
- PK11_FreeSymKey(wrapKey);
- if (pwSpec->master_secret == NULL) {
- break; /* errorCode set just after call to UnwrapSymKey. */
- }
-#ifndef NO_PKCS11_BYPASS
- } else if (ss->opt.bypassPKCS11) {
- /* MS is not wrapped */
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
- pwSpec->msItem.data = pwSpec->raw_master_secret;
- pwSpec->msItem.len = wrappedMS.len;
-#endif
- } else {
- /* We CAN restart a bypass session in a non-bypass socket. */
- /* need to import the raw master secret to session object */
- PK11SlotInfo *slot = PK11_GetInternalSlot();
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- pwSpec->master_secret =
- PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE,
- PK11_OriginUnwrap, CKA_ENCRYPT,
- &wrappedMS, NULL);
- PK11_FreeSlot(slot);
- if (pwSpec->master_secret == NULL) {
- break;
- }
- }
-
- /* Got a Match */
- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits );
-
- /* If we sent a session ticket, then this is a stateless resume. */
- if (sid->version > SSL_LIBRARY_VERSION_3_0 &&
- sid->u.ssl3.sessionTicket.ticket.data != NULL)
- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_stateless_resumes );
-
- if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
- ss->ssl3.hs.ws = wait_new_session_ticket;
- else
- ss->ssl3.hs.ws = wait_change_cipher;
-
- ss->ssl3.hs.isResuming = PR_TRUE;
-
- /* copy the peer cert from the SID */
- if (sid->peerCert != NULL) {
- ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
- }
-
- /* NULL value for PMS signifies re-use of the old MS */
- rv = ssl3_InitPendingCipherSpec(ss, NULL);
- if (rv != SECSuccess) {
- goto alert_loser; /* err code was set */
- }
- return SECSuccess;
- } while (0);
-
- if (sid_match)
- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok );
- else
- SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_misses );
-
- /* throw the old one away */
- sid->u.ssl3.keys.resumable = PR_FALSE;
- if (ss->sec.uncache)
- (*ss->sec.uncache)(sid);
- ssl_FreeSID(sid);
-
- /* get a new sid */
- ss->sec.ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE);
- if (sid == NULL) {
- goto alert_loser; /* memory error is set. */
- }
-
- sid->version = ss->version;
- sid->u.ssl3.sessionIDLength = sidBytes.len;
- PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data, sidBytes.len);
-
- ss->ssl3.hs.isResuming = PR_FALSE;
- ss->ssl3.hs.ws = wait_server_cert;
- return SECSuccess;
-
-alert_loser:
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-
-loser:
- errCode = ssl_MapLowLevelError(errCode);
- return SECFailure;
-}
-
-/* ssl3_BigIntGreaterThanOne returns true iff |mpint|, taken as an unsigned,
- * big-endian integer is > 1 */
-static PRBool
-ssl3_BigIntGreaterThanOne(const SECItem* mpint) {
- unsigned char firstNonZeroByte = 0;
- unsigned int i;
-
- for (i = 0; i < mpint->len; i++) {
- if (mpint->data[i]) {
- firstNonZeroByte = mpint->data[i];
- break;
- }
- }
-
- if (firstNonZeroByte == 0)
- return PR_FALSE;
- if (firstNonZeroByte > 1)
- return PR_TRUE;
-
- /* firstNonZeroByte == 1, therefore mpint > 1 iff the first non-zero byte
- * is followed by another byte. */
- return (i < mpint->len - 1);
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 ServerKeyExchange message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- PRArenaPool * arena = NULL;
- SECKEYPublicKey *peerKey = NULL;
- PRBool isTLS;
- SECStatus rv;
- int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
- SSL3AlertDescription desc = illegal_parameter;
- SSL3Hashes hashes;
- SECItem signature = {siBuffer, NULL, 0};
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle server_key_exchange handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3.hs.ws != wait_server_key &&
- ss->ssl3.hs.ws != wait_server_cert) {
- errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
- desc = unexpected_message;
- goto alert_loser;
- }
- if (ss->sec.peerCert == NULL) {
- errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
- desc = unexpected_message;
- goto alert_loser;
- }
-
- isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- switch (ss->ssl3.hs.kea_def->exchKeyType) {
-
- case kt_rsa: {
- SECItem modulus = {siBuffer, NULL, 0};
- SECItem exponent = {siBuffer, NULL, 0};
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &modulus, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- if (length != 0) {
- if (isTLS)
- desc = decode_error;
- goto alert_loser; /* malformed. */
- }
-
- /* failures after this point are not malformed handshakes. */
- /* TLS: send decrypt_error if signature failed. */
- desc = isTLS ? decrypt_error : handshake_failure;
-
- /*
- * check to make sure the hash is signed by right guy
- */
- rv = ssl3_ComputeExportRSAKeyHash(modulus, exponent,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
- rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
- isTLS, ss->pkcs11PinArg);
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
-
- /*
- * we really need to build a new key here because we can no longer
- * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate
- * pkcs11 slots and ID's.
- */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto no_memory;
- }
-
- peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
- if (peerKey == NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- goto no_memory;
- }
-
- peerKey->arena = arena;
- peerKey->keyType = rsaKey;
- peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_HANDLE;
- if (SECITEM_CopyItem(arena, &peerKey->u.rsa.modulus, &modulus) ||
- SECITEM_CopyItem(arena, &peerKey->u.rsa.publicExponent, &exponent))
- {
- PORT_FreeArena(arena, PR_FALSE);
- goto no_memory;
- }
- ss->sec.peerKey = peerKey;
- ss->ssl3.hs.ws = wait_cert_request;
- return SECSuccess;
- }
-
- case kt_dh: {
- SECItem dh_p = {siBuffer, NULL, 0};
- SECItem dh_g = {siBuffer, NULL, 0};
- SECItem dh_Ys = {siBuffer, NULL, 0};
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- if (dh_p.len < 512/8) {
- errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
- goto alert_loser;
- }
- rv = ssl3_ConsumeHandshakeVariable(ss, &dh_g, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_g))
- goto alert_loser;
- rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_Ys))
- goto alert_loser;
- rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- if (length != 0) {
- if (isTLS)
- desc = decode_error;
- goto alert_loser; /* malformed. */
- }
-
- PRINT_BUF(60, (NULL, "Server DH p", dh_p.data, dh_p.len));
- PRINT_BUF(60, (NULL, "Server DH g", dh_g.data, dh_g.len));
- PRINT_BUF(60, (NULL, "Server DH Ys", dh_Ys.data, dh_Ys.len));
-
- /* failures after this point are not malformed handshakes. */
- /* TLS: send decrypt_error if signature failed. */
- desc = isTLS ? decrypt_error : handshake_failure;
-
- /*
- * check to make sure the hash is signed by right guy
- */
- rv = ssl3_ComputeDHKeyHash(dh_p, dh_g, dh_Ys,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
- rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
- isTLS, ss->pkcs11PinArg);
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
-
- /*
- * we really need to build a new key here because we can no longer
- * ignore calling SECKEY_DestroyPublicKey. Using the key may allocate
- * pkcs11 slots and ID's.
- */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto no_memory;
- }
-
- ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
- if (peerKey == NULL) {
- goto no_memory;
- }
-
- peerKey->arena = arena;
- peerKey->keyType = dhKey;
- peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_HANDLE;
-
- if (SECITEM_CopyItem(arena, &peerKey->u.dh.prime, &dh_p) ||
- SECITEM_CopyItem(arena, &peerKey->u.dh.base, &dh_g) ||
- SECITEM_CopyItem(arena, &peerKey->u.dh.publicValue, &dh_Ys))
- {
- PORT_FreeArena(arena, PR_FALSE);
- goto no_memory;
- }
- ss->sec.peerKey = peerKey;
- ss->ssl3.hs.ws = wait_cert_request;
- return SECSuccess;
- }
-
-#ifdef NSS_ENABLE_ECC
- case kt_ecdh:
- rv = ssl3_HandleECDHServerKeyExchange(ss, b, length);
- return rv;
-#endif /* NSS_ENABLE_ECC */
-
- default:
- desc = handshake_failure;
- errCode = SEC_ERROR_UNSUPPORTED_KEYALG;
- break; /* goto alert_loser; */
- }
-
-alert_loser:
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-loser:
- PORT_SetError( errCode );
- return SECFailure;
-
-no_memory: /* no-memory error has already been set. */
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return SECFailure;
-}
-
-
-typedef struct dnameNode {
- struct dnameNode *next;
- SECItem name;
-} dnameNode;
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Certificate Request message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- PRArenaPool * arena = NULL;
- dnameNode * node;
- PRInt32 remaining;
- PRBool isTLS = PR_FALSE;
- int i;
- int errCode = SSL_ERROR_RX_MALFORMED_CERT_REQUEST;
- int nnames = 0;
- SECStatus rv;
- SSL3AlertDescription desc = illegal_parameter;
- SECItem cert_types = {siBuffer, NULL, 0};
- CERTDistNames ca_list;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3.hs.ws != wait_cert_request &&
- ss->ssl3.hs.ws != wait_server_key) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST;
- goto alert_loser;
- }
-
- PORT_Assert(ss->ssl3.clientCertChain == NULL);
- PORT_Assert(ss->ssl3.clientCertificate == NULL);
- PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
-
- isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length);
- if (rv != SECSuccess)
- goto loser; /* malformed, alert has been sent */
-
- arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL)
- goto no_mem;
-
- remaining = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (remaining < 0)
- goto loser; /* malformed, alert has been sent */
-
- if ((PRUint32)remaining > length)
- goto alert_loser;
-
- ca_list.head = node = PORT_ArenaZNew(arena, dnameNode);
- if (node == NULL)
- goto no_mem;
-
- while (remaining > 0) {
- PRInt32 len;
-
- if (remaining < 2)
- goto alert_loser; /* malformed */
-
- node->name.len = len = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (len <= 0)
- goto loser; /* malformed, alert has been sent */
-
- remaining -= 2;
- if (remaining < len)
- goto alert_loser; /* malformed */
-
- node->name.data = b;
- b += len;
- length -= len;
- remaining -= len;
- nnames++;
- if (remaining <= 0)
- break; /* success */
-
- node->next = PORT_ArenaZNew(arena, dnameNode);
- node = node->next;
- if (node == NULL)
- goto no_mem;
- }
-
- ca_list.nnames = nnames;
- ca_list.names = PORT_ArenaNewArray(arena, SECItem, nnames);
- if (nnames > 0 && ca_list.names == NULL)
- goto no_mem;
-
- for(i = 0, node = (dnameNode*)ca_list.head;
- i < nnames;
- i++, node = node->next) {
- ca_list.names[i] = node->name;
- }
-
- if (length != 0)
- goto alert_loser; /* malformed */
-
- desc = no_certificate;
- ss->ssl3.hs.ws = wait_hello_done;
-
- if (ss->getClientAuthData != NULL) {
- /* XXX Should pass cert_types in this call!! */
- rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
- ss->fd, &ca_list,
- &ss->ssl3.clientCertificate,
- &ss->ssl3.clientPrivateKey);
- } else {
- rv = SECFailure; /* force it to send a no_certificate alert */
- }
- switch (rv) {
- case SECWouldBlock: /* getClientAuthData has put up a dialog box. */
- ssl3_SetAlwaysBlock(ss);
- break; /* not an error */
-
- case SECSuccess:
- /* check what the callback function returned */
- if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
- /* we are missing either the key or cert */
- if (ss->ssl3.clientCertificate) {
- /* got a cert, but no key - free it */
- CERT_DestroyCertificate(ss->ssl3.clientCertificate);
- ss->ssl3.clientCertificate = NULL;
- }
- if (ss->ssl3.clientPrivateKey) {
- /* got a key, but no cert - free it */
- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
- ss->ssl3.clientPrivateKey = NULL;
- }
- goto send_no_certificate;
- }
- /* Setting ssl3.clientCertChain non-NULL will cause
- * ssl3_HandleServerHelloDone to call SendCertificate.
- */
- ss->ssl3.clientCertChain = CERT_CertChainFromCert(
- ss->ssl3.clientCertificate,
- certUsageSSLClient, PR_FALSE);
- if (ss->ssl3.clientCertChain == NULL) {
- if (ss->ssl3.clientCertificate != NULL) {
- CERT_DestroyCertificate(ss->ssl3.clientCertificate);
- ss->ssl3.clientCertificate = NULL;
- }
- if (ss->ssl3.clientPrivateKey != NULL) {
- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
- ss->ssl3.clientPrivateKey = NULL;
- }
- goto send_no_certificate;
- }
- break; /* not an error */
-
- case SECFailure:
- default:
-send_no_certificate:
- if (isTLS) {
- ss->ssl3.sendEmptyCert = PR_TRUE;
- } else {
- (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
- }
- rv = SECSuccess;
- break;
- }
- goto done;
-
-no_mem:
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- goto done;
-
-alert_loser:
- if (isTLS && desc == illegal_parameter)
- desc = decode_error;
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-loser:
- PORT_SetError(errCode);
- rv = SECFailure;
-done:
- if (arena != NULL)
- PORT_FreeArena(arena, PR_FALSE);
- return rv;
-}
-
-PRBool
-ssl3_CanFalseStart(sslSocket *ss) {
- PRBool rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- /* XXX: does not take into account whether we are waiting for
- * SSL_AuthCertificateComplete or SSL_RestartHandshakeAfterCertReq. If/when
- * that is done, this function could return different results each time it
- * would be called.
- */
-
- ssl_GetSpecReadLock(ss);
- rv = ss->opt.enableFalseStart &&
- !ss->sec.isServer &&
- !ss->ssl3.hs.isResuming &&
- ss->ssl3.cwSpec &&
-
- /* An attacker can control the selected ciphersuite so we only wish to
- * do False Start in the case that the selected ciphersuite is
- * sufficiently strong that the attack can gain no advantage.
- * Therefore we require an 80-bit cipher and a forward-secret key
- * exchange. */
- ss->ssl3.cwSpec->cipher_def->secret_key_size >= 10 &&
- (ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
- ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
- ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
- ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa);
- ssl_ReleaseSpecReadLock(ss);
- return rv;
-}
-
-static SECStatus ssl3_SendClientSecondRound(sslSocket *ss);
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Server Hello Done message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleServerHelloDone(sslSocket *ss)
-{
- SECStatus rv;
- SSL3WaitState ws = ss->ssl3.hs.ws;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle server_hello_done handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ws != wait_hello_done &&
- ws != wait_server_cert &&
- ws != wait_server_key &&
- ws != wait_cert_request) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
- return SECFailure;
- }
-
- rv = ssl3_SendClientSecondRound(ss);
-
- return rv;
-}
-
-/* Called from ssl3_HandleServerHelloDone and ssl3_AuthCertificateComplete.
- *
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_SendClientSecondRound(sslSocket *ss)
-{
- SECStatus rv;
- PRBool sendClientCert;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- sendClientCert = !ss->ssl3.sendEmptyCert &&
- ss->ssl3.clientCertChain != NULL &&
- ss->ssl3.clientPrivateKey != NULL;
-
- /* We must wait for the server's certificate to be authenticated before
- * sending the client certificate in order to disclosing the client
- * certificate to an attacker that does not have a valid cert for the
- * domain we are connecting to.
- *
- * XXX: We should do the same for the NPN extension, but for that we
- * need an option to give the application the ability to leak the NPN
- * information to get better performance.
- *
- * During the initial handshake on a connection, we never send/receive
- * application data until we have authenticated the server's certificate;
- * i.e. we have fully authenticated the handshake before using the cipher
- * specs agreed upon for that handshake. During a renegotiation, we may
- * continue sending and receiving application data during the handshake
- * interleaved with the handshake records. If we were to send the client's
- * second round for a renegotiation before the server's certificate was
- * authenticated, then the application data sent/received after this point
- * would be using cipher spec that hadn't been authenticated. By waiting
- * until the server's certificate has been authenticated during
- * renegotiations, we ensure that renegotiations have the same property
- * as initial handshakes; i.e. we have fully authenticated the handshake
- * before using the cipher specs agreed upon for that handshake for
- * application data.
- */
- if (ss->ssl3.hs.restartTarget) {
- PR_NOT_REACHED("unexpected ss->ssl3.hs.restartTarget");
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- if (ss->ssl3.hs.authCertificatePending &&
- (sendClientCert || ss->ssl3.sendEmptyCert || ss->firstHsDone)) {
- ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound;
- return SECWouldBlock;
- }
-
- ssl_GetXmitBufLock(ss); /*******************************/
-
- if (ss->ssl3.sendEmptyCert) {
- ss->ssl3.sendEmptyCert = PR_FALSE;
- rv = ssl3_SendEmptyCertificate(ss);
- /* Don't send verify */
- if (rv != SECSuccess) {
- goto loser; /* error code is set. */
- }
- } else if (sendClientCert) {
- rv = ssl3_SendCertificate(ss);
- if (rv != SECSuccess) {
- goto loser; /* error code is set. */
- }
- }
-
- rv = ssl3_SendClientKeyExchange(ss);
- if (rv != SECSuccess) {
- goto loser; /* err is set. */
- }
-
- if (sendClientCert) {
- rv = ssl3_SendCertificateVerify(ss);
- if (rv != SECSuccess) {
- goto loser; /* err is set. */
- }
- }
-
- rv = ssl3_SendChangeCipherSpecs(ss);
- if (rv != SECSuccess) {
- goto loser; /* err code was set. */
- }
-
- /* XXX: If the server's certificate hasn't been authenticated by this
- * point, then we may be leaking this NPN message to an attacker.
- */
- if (!ss->firstHsDone) {
- rv = ssl3_SendNextProto(ss);
- if (rv != SECSuccess) {
- goto loser; /* err code was set. */
- }
- }
-
- rv = ssl3_SendFinished(ss, 0);
- if (rv != SECSuccess) {
- goto loser; /* err code was set. */
- }
-
- ssl_ReleaseXmitBufLock(ss); /*******************************/
-
- if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn))
- ss->ssl3.hs.ws = wait_new_session_ticket;
- else
- ss->ssl3.hs.ws = wait_change_cipher;
-
- /* Do the handshake callback for sslv3 here, if we can false start. */
- if (ss->handshakeCallback != NULL && ssl3_CanFalseStart(ss)) {
- (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
- }
-
- return SECSuccess;
-
-loser:
- ssl_ReleaseXmitBufLock(ss);
- return rv;
-}
-
-/*
- * Routines used by servers
- */
-static SECStatus
-ssl3_SendHelloRequest(sslSocket *ss)
-{
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send hello_request handshake", SSL_GETPID(),
- ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-
- rv = ssl3_AppendHandshakeHeader(ss, hello_request, 0);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake */
- }
- rv = ssl3_FlushHandshake(ss, 0);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
- ss->ssl3.hs.ws = wait_client_hello;
- return SECSuccess;
-}
-
-/*
- * Called from:
- * ssl3_HandleClientHello()
- */
-static SECComparison
-ssl3_ServerNameCompare(const SECItem *name1, const SECItem *name2)
-{
- if (!name1 != !name2) {
- return SECLessThan;
- }
- if (!name1) {
- return SECEqual;
- }
- if (name1->type != name2->type) {
- return SECLessThan;
- }
- return SECITEM_CompareItem(name1, name2);
-}
-
-/* Sets memory error when returning NULL.
- * Called from:
- * ssl3_SendClientHello()
- * ssl3_HandleServerHello()
- * ssl3_HandleClientHello()
- * ssl3_HandleV2ClientHello()
- */
-sslSessionID *
-ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
-{
- sslSessionID *sid;
-
- sid = PORT_ZNew(sslSessionID);
- if (sid == NULL)
- return sid;
-
- if (is_server) {
- const SECItem * srvName;
- SECStatus rv = SECSuccess;
-
- ssl_GetSpecReadLock(ss); /********************************/
- srvName = &ss->ssl3.prSpec->srvVirtName;
- if (srvName->len && srvName->data) {
- rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.srvName, srvName);
- }
- ssl_ReleaseSpecReadLock(ss); /************************************/
- if (rv != SECSuccess) {
- PORT_Free(sid);
- return NULL;
- }
- }
- sid->peerID = (ss->peerID == NULL) ? NULL : PORT_Strdup(ss->peerID);
- sid->urlSvrName = (ss->url == NULL) ? NULL : PORT_Strdup(ss->url);
- sid->addr = ss->sec.ci.peer;
- sid->port = ss->sec.ci.port;
- sid->references = 1;
- sid->cached = never_cached;
- sid->version = ss->version;
-
- sid->u.ssl3.keys.resumable = PR_TRUE;
- sid->u.ssl3.policy = SSL_ALLOWED;
- sid->u.ssl3.clientWriteKey = NULL;
- sid->u.ssl3.serverWriteKey = NULL;
-
- if (is_server) {
- SECStatus rv;
- int pid = SSL_GETPID();
-
- sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
- sid->u.ssl3.sessionID[0] = (pid >> 8) & 0xff;
- sid->u.ssl3.sessionID[1] = pid & 0xff;
- rv = PK11_GenerateRandom(sid->u.ssl3.sessionID + 2,
- SSL3_SESSIONID_BYTES -2);
- if (rv != SECSuccess) {
- ssl_FreeSID(sid);
- ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
- return NULL;
- }
- }
- return sid;
-}
-
-/* Called from: ssl3_HandleClientHello, ssl3_HandleV2ClientHello */
-static SECStatus
-ssl3_SendServerHelloSequence(sslSocket *ss)
-{
- const ssl3KEADef *kea_def;
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: begin send server_hello sequence",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-
- rv = ssl3_SendServerHello(ss);
- if (rv != SECSuccess) {
- return rv; /* err code is set. */
- }
- rv = ssl3_SendCertificate(ss);
- if (rv != SECSuccess) {
- return rv; /* error code is set. */
- }
- rv = ssl3_SendCertificateStatus(ss);
- if (rv != SECSuccess) {
- return rv; /* error code is set. */
- }
- /* We have to do this after the call to ssl3_SendServerHello,
- * because kea_def is set up by ssl3_SendServerHello().
- */
- kea_def = ss->ssl3.hs.kea_def;
- ss->ssl3.hs.usedStepDownKey = PR_FALSE;
-
- if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
- /* see if we can legally use the key in the cert. */
- int keyLen; /* bytes */
-
- keyLen = PK11_GetPrivateModulusLen(
- ss->serverCerts[kea_def->exchKeyType].SERVERKEY);
-
- if (keyLen > 0 &&
- keyLen * BPB <= kea_def->key_size_limit ) {
- /* XXX AND cert is not signing only!! */
- /* just fall through and use it. */
- } else if (ss->stepDownKeyPair != NULL) {
- ss->ssl3.hs.usedStepDownKey = PR_TRUE;
- rv = ssl3_SendServerKeyExchange(ss);
- if (rv != SECSuccess) {
- return rv; /* err code was set. */
- }
- } else {
-#ifndef HACKED_EXPORT_SERVER
- PORT_SetError(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED);
- return rv;
-#endif
- }
-#ifdef NSS_ENABLE_ECC
- } else if ((kea_def->kea == kea_ecdhe_rsa) ||
- (kea_def->kea == kea_ecdhe_ecdsa)) {
- rv = ssl3_SendServerKeyExchange(ss);
- if (rv != SECSuccess) {
- return rv; /* err code was set. */
- }
-#endif /* NSS_ENABLE_ECC */
- }
-
- if (ss->opt.requestCertificate) {
- rv = ssl3_SendCertificateRequest(ss);
- if (rv != SECSuccess) {
- return rv; /* err code is set. */
- }
- }
- rv = ssl3_SendServerHelloDone(ss);
- if (rv != SECSuccess) {
- return rv; /* err code is set. */
- }
-
- ss->ssl3.hs.ws = (ss->opt.requestCertificate) ? wait_client_cert
- : wait_client_key;
- return SECSuccess;
-}
-
-/* An empty TLS Renegotiation Info (RI) extension */
-static const PRUint8 emptyRIext[5] = {0xff, 0x01, 0x00, 0x01, 0x00};
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Client Hello message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- sslSessionID * sid = NULL;
- PRInt32 tmp;
- unsigned int i;
- int j;
- SECStatus rv;
- int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
- SSL3AlertDescription desc = illegal_parameter;
- SSL3AlertLevel level = alert_fatal;
- SSL3ProtocolVersion version;
- SECItem sidBytes = {siBuffer, NULL, 0};
- SECItem cookieBytes = {siBuffer, NULL, 0};
- SECItem suites = {siBuffer, NULL, 0};
- SECItem comps = {siBuffer, NULL, 0};
- PRBool haveSpecWriteLock = PR_FALSE;
- PRBool haveXmitBufLock = PR_FALSE;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle client_hello handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- /* Get peer name of client */
- rv = ssl_GetPeerInfo(ss);
- if (rv != SECSuccess) {
- return rv; /* error code is set. */
- }
-
- /* Clearing the handshake pointers so that ssl_Do1stHandshake won't
- * call ssl2_HandleMessage.
- *
- * The issue here is that TLS ordinarily starts out in
- * ssl2_HandleV3HandshakeRecord() because of the backward-compatibility
- * code paths. That function zeroes these next pointers. But with DTLS,
- * we don't even try to do the v2 ClientHello so we skip that function
- * and need to reset these values here.
- */
- if (IS_DTLS(ss)) {
- ss->nextHandshake = 0;
- ss->securityHandshake = 0;
- }
-
- /* We might be starting session renegotiation in which case we should
- * clear previous state.
- */
- PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
- ss->statelessResume = PR_FALSE;
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- return rv; /* ssl3_InitState has set the error code. */
- }
-
- if ((ss->ssl3.hs.ws != wait_client_hello) &&
- (ss->ssl3.hs.ws != idle_handshake)) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
- goto alert_loser;
- }
- if (ss->ssl3.hs.ws == idle_handshake &&
- ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
- desc = no_renegotiation;
- level = alert_warning;
- errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
- goto alert_loser;
- }
-
- if (IS_DTLS(ss)) {
- dtls_RehandshakeCleanup(ss);
- }
-
- tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (tmp < 0)
- goto loser; /* malformed, alert already sent */
-
- /* Translate the version */
- if (IS_DTLS(ss)) {
- ss->clientHelloVersion = version =
- dtls_DTLSVersionToTLSVersion((SSL3ProtocolVersion)tmp);
- } else {
- ss->clientHelloVersion = version = (SSL3ProtocolVersion)tmp;
- }
-
- rv = ssl3_NegotiateVersion(ss, version, PR_TRUE);
- if (rv != SECSuccess) {
- desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version
- : handshake_failure;
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
- }
-
- /* grab the client random data. */
- rv = ssl3_ConsumeHandshake(
- ss, &ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- /* grab the client's SID, if present. */
- rv = ssl3_ConsumeHandshakeVariable(ss, &sidBytes, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- /* grab the client's cookie, if present. */
- if (IS_DTLS(ss)) {
- rv = ssl3_ConsumeHandshakeVariable(ss, &cookieBytes, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
- }
-
- /* grab the list of cipher suites. */
- rv = ssl3_ConsumeHandshakeVariable(ss, &suites, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- /* grab the list of compression methods. */
- rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
-
- desc = handshake_failure;
-
- /* Handle TLS hello extensions for SSL3 & TLS. We do not know if
- * we are restarting a previous session until extensions have been
- * parsed, since we might have received a SessionTicket extension.
- * Note: we allow extensions even when negotiating SSL3 for the sake
- * of interoperability (and backwards compatibility).
- */
-
- if (length) {
- /* Get length of hello extensions */
- PRInt32 extension_length;
- extension_length = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
- if (extension_length < 0) {
- goto loser; /* alert already sent */
- }
- if (extension_length != length) {
- ssl3_DecodeError(ss); /* send alert */
- goto loser;
- }
- rv = ssl3_HandleHelloExtensions(ss, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed */
- }
- }
- if (!ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
- /* If we didn't receive an RI extension, look for the SCSV,
- * and if found, treat it just like an empty RI extension
- * by processing a local copy of an empty RI extension.
- */
- for (i = 0; i + 1 < suites.len; i += 2) {
- PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
- if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) {
- SSL3Opaque * b2 = (SSL3Opaque *)emptyRIext;
- PRUint32 L2 = sizeof emptyRIext;
- (void)ssl3_HandleHelloExtensions(ss, &b2, &L2);
- break;
- }
- }
- }
- if (ss->firstHsDone &&
- (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_REQUIRES_XTN ||
- ss->opt.enableRenegotiation == SSL_RENEGOTIATE_TRANSITIONAL) &&
- !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
- desc = no_renegotiation;
- level = alert_warning;
- errCode = SSL_ERROR_RENEGOTIATION_NOT_ALLOWED;
- goto alert_loser;
- }
- if ((ss->opt.requireSafeNegotiation ||
- (ss->firstHsDone && ss->peerRequestedProtection)) &&
- !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
- desc = handshake_failure;
- errCode = SSL_ERROR_UNSAFE_NEGOTIATION;
- goto alert_loser;
- }
-
- /* We do stateful resumes only if either of the following
- * conditions are satisfied: (1) the client does not support the
- * session ticket extension, or (2) the client support the session
- * ticket extension, but sent an empty ticket.
- */
- if (!ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) ||
- ss->xtnData.emptySessionTicket) {
- if (sidBytes.len > 0 && !ss->opt.noCache) {
- SSL_TRC(7, ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
- SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
- ss->sec.ci.peer.pr_s6_addr32[1],
- ss->sec.ci.peer.pr_s6_addr32[2],
- ss->sec.ci.peer.pr_s6_addr32[3]));
- if (ssl_sid_lookup) {
- sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sidBytes.data,
- sidBytes.len, ss->dbHandle);
- } else {
- errCode = SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED;
- goto loser;
- }
- }
- } else if (ss->statelessResume) {
- /* Fill in the client's session ID if doing a stateless resume.
- * (When doing stateless resumes, server echos client's SessionID.)
- */
- sid = ss->sec.ci.sid;
- PORT_Assert(sid != NULL); /* Should have already been filled in.*/
-
- if (sidBytes.len > 0 && sidBytes.len <= SSL3_SESSIONID_BYTES) {
- sid->u.ssl3.sessionIDLength = sidBytes.len;
- PORT_Memcpy(sid->u.ssl3.sessionID, sidBytes.data,
- sidBytes.len);
- sid->u.ssl3.sessionIDLength = sidBytes.len;
- } else {
- sid->u.ssl3.sessionIDLength = 0;
- }
- ss->sec.ci.sid = NULL;
- }
-
- /* We only send a session ticket extension if the client supports
- * the extension and we are unable to do either a stateful or
- * stateless resume.
- *
- * TODO: send a session ticket if performing a stateful
- * resumption. (As per RFC4507, a server may issue a session
- * ticket while doing a (stateless or stateful) session resume,
- * but OpenSSL-0.9.8g does not accept session tickets while
- * resuming.)
- */
- if (ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn) && sid == NULL) {
- ssl3_RegisterServerHelloExtensionSender(ss,
- ssl_session_ticket_xtn, ssl3_SendSessionTicketXtn);
- }
-
- if (sid != NULL) {
- /* We've found a session cache entry for this client.
- * Now, if we're going to require a client-auth cert,
- * and we don't already have this client's cert in the session cache,
- * and this is the first handshake on this connection (not a redo),
- * then drop this old cache entry and start a new session.
- */
- if ((sid->peerCert == NULL) && ss->opt.requestCertificate &&
- ((ss->opt.requireCertificate == SSL_REQUIRE_ALWAYS) ||
- (ss->opt.requireCertificate == SSL_REQUIRE_NO_ERROR) ||
- ((ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE)
- && !ss->firstHsDone))) {
-
- SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok );
- if (ss->sec.uncache)
- ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
- }
-
-#ifdef NSS_ENABLE_ECC
- /* Disable any ECC cipher suites for which we have no cert. */
- ssl3_FilterECCipherSuitesByServerCerts(ss);
-#endif
-
- if (IS_DTLS(ss)) {
- ssl3_DisableNonDTLSSuites(ss);
- }
-
-#ifdef PARANOID
- /* Look for a matching cipher suite. */
- j = ssl3_config_match_init(ss);
- if (j <= 0) { /* no ciphers are working/supported by PK11 */
- errCode = PORT_GetError(); /* error code is already set. */
- goto alert_loser;
- }
-#endif
-
- /* If we already have a session for this client, be sure to pick the
- ** same cipher suite and compression method we picked before.
- ** This is not a loop, despite appearances.
- */
- if (sid) do {
- ssl3CipherSuiteCfg *suite;
-
- /* Check that the cached compression method is still enabled. */
- if (!compressionEnabled(ss, sid->u.ssl3.compression))
- break;
-
- /* Check that the cached compression method is in the client's list */
- for (i = 0; i < comps.len; i++) {
- if (comps.data[i] == sid->u.ssl3.compression)
- break;
- }
- if (i == comps.len)
- break;
-
- suite = ss->cipherSuites;
- /* Find the entry for the cipher suite used in the cached session. */
- for (j = ssl_V3_SUITES_IMPLEMENTED; j > 0; --j, ++suite) {
- if (suite->cipher_suite == sid->u.ssl3.cipherSuite)
- break;
- }
- PORT_Assert(j > 0);
- if (j <= 0)
- break;
-#ifdef PARANOID
- /* Double check that the cached cipher suite is still enabled,
- * implemented, and allowed by policy. Might have been disabled.
- * The product policy won't change during the process lifetime.
- * Implemented ("isPresent") shouldn't change for servers.
- */
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE))
- break;
-#else
- if (!suite->enabled)
- break;
-#endif
- /* Double check that the cached cipher suite is in the client's list */
- for (i = 0; i + 1 < suites.len; i += 2) {
- PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
- if (suite_i == suite->cipher_suite) {
- ss->ssl3.hs.cipher_suite = suite->cipher_suite;
- ss->ssl3.hs.suite_def =
- ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
-
- /* Use the cached compression method. */
- ss->ssl3.hs.compression = sid->u.ssl3.compression;
- goto compression_found;
- }
- }
- } while (0);
-
- /* START A NEW SESSION */
-
-#ifndef PARANOID
- /* Look for a matching cipher suite. */
- j = ssl3_config_match_init(ss);
- if (j <= 0) { /* no ciphers are working/supported by PK11 */
- errCode = PORT_GetError(); /* error code is already set. */
- goto alert_loser;
- }
-#endif
-
- /* Select a cipher suite.
- **
- ** NOTE: This suite selection algorithm should be the same as the one in
- ** ssl3_HandleV2ClientHello().
- **
- ** If TLS 1.0 is enabled, we could handle the case where the client
- ** offered TLS 1.1 but offered only export cipher suites by choosing TLS
- ** 1.0 and selecting one of those export cipher suites. However, a secure
- ** TLS 1.1 client should not have export cipher suites enabled at all,
- ** and a TLS 1.1 client should definitely not be offering *only* export
- ** cipher suites. Therefore, we refuse to negotiate export cipher suites
- ** with any client that indicates support for TLS 1.1 or higher when we
- ** (the server) have TLS 1.1 support enabled.
- */
- for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE) ||
- !ssl3_CipherSuiteAllowedForVersion(suite->cipher_suite,
- ss->version)) {
- continue;
- }
- for (i = 0; i + 1 < suites.len; i += 2) {
- PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
- if (suite_i == suite->cipher_suite) {
- ss->ssl3.hs.cipher_suite = suite->cipher_suite;
- ss->ssl3.hs.suite_def =
- ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
- goto suite_found;
- }
- }
- }
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
-
-suite_found:
- /* Look for a matching compression algorithm. */
- for (i = 0; i < comps.len; i++) {
- if (!compressionEnabled(ss, comps.data[i]))
- continue;
- for (j = 0; j < compressionMethodsCount; j++) {
- if (comps.data[i] == compressions[j]) {
- ss->ssl3.hs.compression =
- (SSLCompressionMethod)compressions[j];
- goto compression_found;
- }
- }
- }
- errCode = SSL_ERROR_NO_COMPRESSION_OVERLAP;
- /* null compression must be supported */
- goto alert_loser;
-
-compression_found:
- suites.data = NULL;
- comps.data = NULL;
-
- ss->sec.send = ssl3_SendApplicationData;
-
- /* If there are any failures while processing the old sid,
- * we don't consider them to be errors. Instead, We just behave
- * as if the client had sent us no sid to begin with, and make a new one.
- */
- if (sid != NULL) do {
- ssl3CipherSpec *pwSpec;
- SECItem wrappedMS; /* wrapped key */
-
- if (sid->version != ss->version ||
- sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite ||
- sid->u.ssl3.compression != ss->ssl3.hs.compression) {
- break; /* not an error */
- }
-
- if (ss->sec.ci.sid) {
- if (ss->sec.uncache)
- ss->sec.uncache(ss->sec.ci.sid);
- PORT_Assert(ss->sec.ci.sid != sid); /* should be impossible, but ... */
- if (ss->sec.ci.sid != sid) {
- ssl_FreeSID(ss->sec.ci.sid);
- }
- ss->sec.ci.sid = NULL;
- }
- /* we need to resurrect the master secret.... */
-
- ssl_GetSpecWriteLock(ss); haveSpecWriteLock = PR_TRUE;
- pwSpec = ss->ssl3.pwSpec;
- if (sid->u.ssl3.keys.msIsWrapped) {
- PK11SymKey * wrapKey; /* wrapping key */
- CK_FLAGS keyFlags = 0;
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- /* we cannot restart a non-bypass session in a
- ** bypass socket.
- */
- break;
- }
-#endif
-
- wrapKey = getWrappingKey(ss, NULL, sid->u.ssl3.exchKeyType,
- sid->u.ssl3.masterWrapMech,
- ss->pkcs11PinArg);
- if (!wrapKey) {
- /* we have a SID cache entry, but no wrapping key for it??? */
- break;
- }
-
- if (ss->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- keyFlags = CKF_SIGN | CKF_VERIFY;
- }
-
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
-
- /* unwrap the master secret. */
- pwSpec->master_secret =
- PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
- NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
- CKA_DERIVE, sizeof(SSL3MasterSecret), keyFlags);
- PK11_FreeSymKey(wrapKey);
- if (pwSpec->master_secret == NULL) {
- break; /* not an error */
- }
-#ifndef NO_PKCS11_BYPASS
- } else if (ss->opt.bypassPKCS11) {
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- memcpy(pwSpec->raw_master_secret, wrappedMS.data, wrappedMS.len);
- pwSpec->msItem.data = pwSpec->raw_master_secret;
- pwSpec->msItem.len = wrappedMS.len;
-#endif
- } else {
- /* We CAN restart a bypass session in a non-bypass socket. */
- /* need to import the raw master secret to session object */
- PK11SlotInfo * slot;
- wrappedMS.data = sid->u.ssl3.keys.wrapped_master_secret;
- wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
- slot = PK11_GetInternalSlot();
- pwSpec->master_secret =
- PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE,
- PK11_OriginUnwrap, CKA_ENCRYPT, &wrappedMS,
- NULL);
- PK11_FreeSlot(slot);
- if (pwSpec->master_secret == NULL) {
- break; /* not an error */
- }
- }
- ss->sec.ci.sid = sid;
- if (sid->peerCert != NULL) {
- ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
- }
-
- /*
- * Old SID passed all tests, so resume this old session.
- *
- * XXX make sure compression still matches
- */
- SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_hits );
- if (ss->statelessResume)
- SSL_AtomicIncrementLong(& ssl3stats.hch_sid_stateless_resumes );
- ss->ssl3.hs.isResuming = PR_TRUE;
-
- ss->sec.authAlgorithm = sid->authAlgorithm;
- ss->sec.authKeyBits = sid->authKeyBits;
- ss->sec.keaType = sid->keaType;
- ss->sec.keaKeyBits = sid->keaKeyBits;
-
- /* server sids don't remember the server cert we previously sent,
- ** but they do remember the kea type we originally used, so we
- ** can locate it again, provided that the current ssl socket
- ** has had its server certs configured the same as the previous one.
- */
- ss->sec.localCert =
- CERT_DupCertificate(ss->serverCerts[sid->keaType].serverCert);
-
- /* Copy cached name in to pending spec */
- if (sid != NULL &&
- sid->version > SSL_LIBRARY_VERSION_3_0 &&
- sid->u.ssl3.srvName.len && sid->u.ssl3.srvName.data) {
- /* Set server name from sid */
- SECItem *sidName = &sid->u.ssl3.srvName;
- SECItem *pwsName = &ss->ssl3.pwSpec->srvVirtName;
- if (pwsName->data) {
- SECITEM_FreeItem(pwsName, PR_FALSE);
- }
- rv = SECITEM_CopyItem(NULL, pwsName, sidName);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- desc = internal_error;
- goto alert_loser;
- }
- }
-
- /* Clean up sni name array */
- if (ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn) &&
- ss->xtnData.sniNameArr) {
- PORT_Free(ss->xtnData.sniNameArr);
- ss->xtnData.sniNameArr = NULL;
- ss->xtnData.sniNameArrSize = 0;
- }
-
- ssl_GetXmitBufLock(ss); haveXmitBufLock = PR_TRUE;
-
- rv = ssl3_SendServerHello(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
- }
-
- /* NULL value for PMS signifies re-use of the old MS */
- rv = ssl3_InitPendingCipherSpec(ss, NULL);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- rv = ssl3_SendChangeCipherSpecs(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
- rv = ssl3_SendFinished(ss, 0);
- ss->ssl3.hs.ws = wait_change_cipher;
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- if (haveXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss);
- haveXmitBufLock = PR_FALSE;
- }
-
- return SECSuccess;
- } while (0);
-
- if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
- }
-
- if (sid) { /* we had a sid, but it's no longer valid, free it */
- SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok );
- if (ss->sec.uncache)
- ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- }
- SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses );
-
- if (ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
- int ret = 0;
- if (ss->sniSocketConfig) do { /* not a loop */
- ret = SSL_SNI_SEND_ALERT;
- /* If extension is negotiated, the len of names should > 0. */
- if (ss->xtnData.sniNameArrSize) {
- /* Calling client callback to reconfigure the socket. */
- ret = (SECStatus)(*ss->sniSocketConfig)(ss->fd,
- ss->xtnData.sniNameArr,
- ss->xtnData.sniNameArrSize,
- ss->sniSocketConfigArg);
- }
- if (ret <= SSL_SNI_SEND_ALERT) {
- /* Application does not know the name or was not able to
- * properly reconfigure the socket. */
- errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
- desc = unrecognized_name;
- break;
- } else if (ret == SSL_SNI_CURRENT_CONFIG_IS_USED) {
- SECStatus rv = SECSuccess;
- SECItem * cwsName, *pwsName;
-
- ssl_GetSpecWriteLock(ss); /*******************************/
- pwsName = &ss->ssl3.pwSpec->srvVirtName;
- cwsName = &ss->ssl3.cwSpec->srvVirtName;
-#ifndef SSL_SNI_ALLOW_NAME_CHANGE_2HS
- /* not allow name change on the 2d HS */
- if (ss->firstHsDone) {
- if (ssl3_ServerNameCompare(pwsName, cwsName)) {
- ssl_ReleaseSpecWriteLock(ss); /******************/
- errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
- desc = handshake_failure;
- ret = SSL_SNI_SEND_ALERT;
- break;
- }
- }
-#endif
- if (pwsName->data) {
- SECITEM_FreeItem(pwsName, PR_FALSE);
- }
- if (cwsName->data) {
- rv = SECITEM_CopyItem(NULL, pwsName, cwsName);
- }
- ssl_ReleaseSpecWriteLock(ss); /**************************/
- if (rv != SECSuccess) {
- errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
- desc = internal_error;
- ret = SSL_SNI_SEND_ALERT;
- break;
- }
- } else if (ret < ss->xtnData.sniNameArrSize) {
- /* Application has configured new socket info. Lets check it
- * and save the name. */
- SECStatus rv;
- SECItem * name = &ss->xtnData.sniNameArr[ret];
- int configedCiphers;
- SECItem * pwsName;
-
- /* get rid of the old name and save the newly picked. */
- /* This code is protected by ssl3HandshakeLock. */
- ssl_GetSpecWriteLock(ss); /*******************************/
-#ifndef SSL_SNI_ALLOW_NAME_CHANGE_2HS
- /* not allow name change on the 2d HS */
- if (ss->firstHsDone) {
- SECItem *cwsName = &ss->ssl3.cwSpec->srvVirtName;
- if (ssl3_ServerNameCompare(name, cwsName)) {
- ssl_ReleaseSpecWriteLock(ss); /******************/
- errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
- desc = handshake_failure;
- ret = SSL_SNI_SEND_ALERT;
- break;
- }
- }
-#endif
- pwsName = &ss->ssl3.pwSpec->srvVirtName;
- if (pwsName->data) {
- SECITEM_FreeItem(pwsName, PR_FALSE);
- }
- rv = SECITEM_CopyItem(NULL, pwsName, name);
- ssl_ReleaseSpecWriteLock(ss); /***************************/
- if (rv != SECSuccess) {
- errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
- desc = internal_error;
- ret = SSL_SNI_SEND_ALERT;
- break;
- }
- configedCiphers = ssl3_config_match_init(ss);
- if (configedCiphers <= 0) {
- /* no ciphers are working/supported */
- errCode = PORT_GetError();
- desc = handshake_failure;
- ret = SSL_SNI_SEND_ALERT;
- break;
- }
- /* Need to tell the client that application has picked
- * the name from the offered list and reconfigured the socket.
- */
- ssl3_RegisterServerHelloExtensionSender(ss, ssl_server_name_xtn,
- ssl3_SendServerNameXtn);
- } else {
- /* Callback returned index outside of the boundary. */
- PORT_Assert(ret < ss->xtnData.sniNameArrSize);
- errCode = SSL_ERROR_INTERNAL_ERROR_ALERT;
- desc = internal_error;
- ret = SSL_SNI_SEND_ALERT;
- break;
- }
- } while (0);
- /* Free sniNameArr. The data that each SECItem in the array
- * points into is the data from the input buffer "b". It will
- * not be available outside the scope of this or it's child
- * functions.*/
- if (ss->xtnData.sniNameArr) {
- PORT_Free(ss->xtnData.sniNameArr);
- ss->xtnData.sniNameArr = NULL;
- ss->xtnData.sniNameArrSize = 0;
- }
- if (ret <= SSL_SNI_SEND_ALERT) {
- /* desc and errCode should be set. */
- goto alert_loser;
- }
- }
-#ifndef SSL_SNI_ALLOW_NAME_CHANGE_2HS
- else if (ss->firstHsDone) {
- /* Check that we don't have the name is current spec
- * if this extension was not negotiated on the 2d hs. */
- PRBool passed = PR_TRUE;
- ssl_GetSpecReadLock(ss); /*******************************/
- if (ss->ssl3.cwSpec->srvVirtName.data) {
- passed = PR_FALSE;
- }
- ssl_ReleaseSpecReadLock(ss); /***************************/
- if (!passed) {
- errCode = SSL_ERROR_UNRECOGNIZED_NAME_ALERT;
- desc = handshake_failure;
- goto alert_loser;
- }
- }
-#endif
-
- sid = ssl3_NewSessionID(ss, PR_TRUE);
- if (sid == NULL) {
- errCode = PORT_GetError();
- goto loser; /* memory error is set. */
- }
- ss->sec.ci.sid = sid;
-
- ss->ssl3.hs.isResuming = PR_FALSE;
- ssl_GetXmitBufLock(ss);
- rv = ssl3_SendServerHelloSequence(ss);
- ssl_ReleaseXmitBufLock(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- if (haveXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss);
- haveXmitBufLock = PR_FALSE;
- }
-
- return SECSuccess;
-
-alert_loser:
- if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
- }
- (void)SSL3_SendAlert(ss, level, desc);
- /* FALLTHRU */
-loser:
- if (haveSpecWriteLock) {
- ssl_ReleaseSpecWriteLock(ss);
- haveSpecWriteLock = PR_FALSE;
- }
-
- if (haveXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss);
- haveXmitBufLock = PR_FALSE;
- }
-
- PORT_SetError(errCode);
- return SECFailure;
-}
-
-/*
- * ssl3_HandleV2ClientHello is used when a V2 formatted hello comes
- * in asking to use the V3 handshake.
- * Called from ssl2_HandleClientHelloMessage() in sslcon.c
- */
-SECStatus
-ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length)
-{
- sslSessionID * sid = NULL;
- unsigned char * suites;
- unsigned char * random;
- SSL3ProtocolVersion version;
- SECStatus rv;
- int i;
- int j;
- int sid_length;
- int suite_length;
- int rand_length;
- int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO;
- SSL3AlertDescription desc = handshake_failure;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle v2 client_hello", SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
-
- ssl_GetSSL3HandshakeLock(ss);
-
- PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
-
- rv = ssl3_InitState(ss);
- if (rv != SECSuccess) {
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv; /* ssl3_InitState has set the error code. */
- }
-
- if (ss->ssl3.hs.ws != wait_client_hello) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO;
- goto loser; /* alert_loser */
- }
-
- version = (buffer[1] << 8) | buffer[2];
- suite_length = (buffer[3] << 8) | buffer[4];
- sid_length = (buffer[5] << 8) | buffer[6];
- rand_length = (buffer[7] << 8) | buffer[8];
- ss->clientHelloVersion = version;
-
- rv = ssl3_NegotiateVersion(ss, version, PR_TRUE);
- if (rv != SECSuccess) {
- /* send back which ever alert client will understand. */
- desc = (version > SSL_LIBRARY_VERSION_3_0) ? protocol_version : handshake_failure;
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
- }
-
- /* if we get a non-zero SID, just ignore it. */
- if (length !=
- SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length + rand_length) {
- SSL_DBG(("%d: SSL3[%d]: bad v2 client hello message, len=%d should=%d",
- SSL_GETPID(), ss->fd, length,
- SSL_HL_CLIENT_HELLO_HBYTES + suite_length + sid_length +
- rand_length));
- goto loser; /* malformed */ /* alert_loser */
- }
-
- suites = buffer + SSL_HL_CLIENT_HELLO_HBYTES;
- random = suites + suite_length + sid_length;
-
- if (rand_length < SSL_MIN_CHALLENGE_BYTES ||
- rand_length > SSL_MAX_CHALLENGE_BYTES) {
- goto loser; /* malformed */ /* alert_loser */
- }
-
- PORT_Assert(SSL_MAX_CHALLENGE_BYTES == SSL3_RANDOM_LENGTH);
-
- PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
- PORT_Memcpy(
- &ss->ssl3.hs.client_random.rand[SSL3_RANDOM_LENGTH - rand_length],
- random, rand_length);
-
- PRINT_BUF(60, (ss, "client random:", &ss->ssl3.hs.client_random.rand[0],
- SSL3_RANDOM_LENGTH));
-#ifdef NSS_ENABLE_ECC
- /* Disable any ECC cipher suites for which we have no cert. */
- ssl3_FilterECCipherSuitesByServerCerts(ss);
-#endif
- i = ssl3_config_match_init(ss);
- if (i <= 0) {
- errCode = PORT_GetError(); /* error code is already set. */
- goto alert_loser;
- }
-
- /* Select a cipher suite.
- **
- ** NOTE: This suite selection algorithm should be the same as the one in
- ** ssl3_HandleClientHello().
- **
- ** See the comments about export cipher suites in ssl3_HandleClientHello().
- */
- for (j = 0; j < ssl_V3_SUITES_IMPLEMENTED; j++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[j];
- if (!config_match(suite, ss->ssl3.policy, PR_TRUE) ||
- !ssl3_CipherSuiteAllowedForVersion(suite->cipher_suite,
- ss->version)) {
- continue;
- }
- for (i = 0; i+2 < suite_length; i += 3) {
- PRUint32 suite_i = (suites[i] << 16)|(suites[i+1] << 8)|suites[i+2];
- if (suite_i == suite->cipher_suite) {
- ss->ssl3.hs.cipher_suite = suite->cipher_suite;
- ss->ssl3.hs.suite_def =
- ssl_LookupCipherSuiteDef(ss->ssl3.hs.cipher_suite);
- goto suite_found;
- }
- }
- }
- errCode = SSL_ERROR_NO_CYPHER_OVERLAP;
- goto alert_loser;
-
-suite_found:
-
- /* Look for the SCSV, and if found, treat it just like an empty RI
- * extension by processing a local copy of an empty RI extension.
- */
- for (i = 0; i+2 < suite_length; i += 3) {
- PRUint32 suite_i = (suites[i] << 16) | (suites[i+1] << 8) | suites[i+2];
- if (suite_i == TLS_EMPTY_RENEGOTIATION_INFO_SCSV) {
- SSL3Opaque * b2 = (SSL3Opaque *)emptyRIext;
- PRUint32 L2 = sizeof emptyRIext;
- (void)ssl3_HandleHelloExtensions(ss, &b2, &L2);
- break;
- }
- }
-
- if (ss->opt.requireSafeNegotiation &&
- !ssl3_ExtensionNegotiated(ss, ssl_renegotiation_info_xtn)) {
- desc = handshake_failure;
- errCode = SSL_ERROR_UNSAFE_NEGOTIATION;
- goto alert_loser;
- }
-
- ss->ssl3.hs.compression = ssl_compression_null;
- ss->sec.send = ssl3_SendApplicationData;
-
- /* we don't even search for a cache hit here. It's just a miss. */
- SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses );
- sid = ssl3_NewSessionID(ss, PR_TRUE);
- if (sid == NULL) {
- errCode = PORT_GetError();
- goto loser; /* memory error is set. */
- }
- ss->sec.ci.sid = sid;
- /* do not worry about memory leak of sid since it now belongs to ci */
-
- /* We have to update the handshake hashes before we can send stuff */
- rv = ssl3_UpdateHandshakeHashes(ss, buffer, length);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- ssl_GetXmitBufLock(ss);
- rv = ssl3_SendServerHelloSequence(ss);
- ssl_ReleaseXmitBufLock(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
-
- /* XXX_1 The call stack to here is:
- * ssl_Do1stHandshake -> ssl2_HandleClientHelloMessage -> here.
- * ssl2_HandleClientHelloMessage returns whatever we return here.
- * ssl_Do1stHandshake will continue looping if it gets back either
- * SECSuccess or SECWouldBlock.
- * SECSuccess is preferable here. See XXX_1 in sslgathr.c.
- */
- ssl_ReleaseSSL3HandshakeLock(ss);
- return SECSuccess;
-
-alert_loser:
- SSL3_SendAlert(ss, alert_fatal, desc);
-loser:
- ssl_ReleaseSSL3HandshakeLock(ss);
- PORT_SetError(errCode);
- return SECFailure;
-}
-
-/* The negotiated version number has been already placed in ss->version.
-**
-** Called from: ssl3_HandleClientHello (resuming session),
-** ssl3_SendServerHelloSequence <- ssl3_HandleClientHello (new session),
-** ssl3_SendServerHelloSequence <- ssl3_HandleV2ClientHello (new session)
-*/
-static SECStatus
-ssl3_SendServerHello(sslSocket *ss)
-{
- sslSessionID *sid;
- SECStatus rv;
- PRUint32 maxBytes = 65535;
- PRUint32 length;
- PRInt32 extensions_len = 0;
- SSL3ProtocolVersion version;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(),
- ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- if (!IS_DTLS(ss)) {
- PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0));
-
- if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_3_0)) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
- } else {
- PORT_Assert(MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_DTLS_1_0));
-
- if (MSB(ss->version) != MSB(SSL_LIBRARY_VERSION_DTLS_1_0)) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
- }
-
- sid = ss->sec.ci.sid;
-
- extensions_len = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes,
- &ss->xtnData.serverSenders[0]);
- if (extensions_len > 0)
- extensions_len += 2; /* Add sizeof total extension length */
-
- length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + 1 +
- ((sid == NULL) ? 0: sid->u.ssl3.sessionIDLength) +
- sizeof(ssl3CipherSuite) + 1 + extensions_len;
- rv = ssl3_AppendHandshakeHeader(ss, server_hello, length);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
-
- if (IS_DTLS(ss)) {
- version = dtls_TLSVersionToDTLSVersion(ss->version);
- } else {
- version = ss->version;
- }
-
- rv = ssl3_AppendHandshakeNumber(ss, version, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_GetNewRandom(&ss->ssl3.hs.server_random);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
- return rv;
- }
- rv = ssl3_AppendHandshake(
- ss, &ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
-
- if (sid)
- rv = ssl3_AppendHandshakeVariable(
- ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);
- else
- rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.cipher_suite, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.hs.compression, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- if (extensions_len) {
- PRInt32 sent_len;
-
- extensions_len -= 2;
- rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2);
- if (rv != SECSuccess)
- return rv; /* err set by ssl3_SetupPendingCipherSpec */
- sent_len = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, extensions_len,
- &ss->xtnData.serverSenders[0]);
- PORT_Assert(sent_len == extensions_len);
- if (sent_len != extensions_len) {
- if (sent_len >= 0)
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- }
- rv = ssl3_SetupPendingCipherSpec(ss);
- if (rv != SECSuccess) {
- return rv; /* err set by ssl3_SetupPendingCipherSpec */
- }
-
- return SECSuccess;
-}
-
-
-static SECStatus
-ssl3_SendServerKeyExchange(sslSocket *ss)
-{
- const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
- SECStatus rv = SECFailure;
- int length;
- PRBool isTLS;
- SECItem signed_hash = {siBuffer, NULL, 0};
- SSL3Hashes hashes;
- SECKEYPublicKey * sdPub; /* public key for step-down */
-
- SSL_TRC(3, ("%d: SSL3[%d]: send server_key_exchange handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- switch (kea_def->exchKeyType) {
- case kt_rsa:
- /* Perform SSL Step-Down here. */
- sdPub = ss->stepDownKeyPair->pubKey;
- PORT_Assert(sdPub != NULL);
- if (!sdPub) {
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
- rv = ssl3_ComputeExportRSAKeyHash(sdPub->u.rsa.modulus,
- sdPub->u.rsa.publicExponent,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return rv;
- }
-
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_SignHashes(&hashes, ss->serverCerts[kt_rsa].SERVERKEY,
- &signed_hash, isTLS);
- if (rv != SECSuccess) {
- goto loser; /* ssl3_SignHashes has set err. */
- }
- if (signed_hash.data == NULL) {
- /* how can this happen and rv == SECSuccess ?? */
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
- length = 2 + sdPub->u.rsa.modulus.len +
- 2 + sdPub->u.rsa.publicExponent.len +
- 2 + signed_hash.len;
-
- rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss, sdPub->u.rsa.modulus.data,
- sdPub->u.rsa.modulus.len, 2);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(
- ss, sdPub->u.rsa.publicExponent.data,
- sdPub->u.rsa.publicExponent.len, 2);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
- signed_hash.len, 2);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
- PORT_Free(signed_hash.data);
- return SECSuccess;
-
-#ifdef NSS_ENABLE_ECC
- case kt_ecdh: {
- rv = ssl3_SendECDHServerKeyExchange(ss);
- return rv;
- }
-#endif /* NSS_ENABLE_ECC */
-
- case kt_dh:
- case kt_null:
- default:
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- break;
- }
-loser:
- if (signed_hash.data != NULL)
- PORT_Free(signed_hash.data);
- return SECFailure;
-}
-
-
-static SECStatus
-ssl3_SendCertificateRequest(sslSocket *ss)
-{
- SECItem * name;
- CERTDistNames *ca_list;
- const uint8 * certTypes;
- SECItem * names = NULL;
- SECStatus rv;
- int length;
- int i;
- int calen = 0;
- int nnames = 0;
- int certTypesLength;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- /* ssl3.ca_list is initialized to NULL, and never changed. */
- ca_list = ss->ssl3.ca_list;
- if (!ca_list) {
- ca_list = ssl3_server_ca_list;
- }
-
- if (ca_list != NULL) {
- names = ca_list->names;
- nnames = ca_list->nnames;
- }
-
- for (i = 0, name = names; i < nnames; i++, name++) {
- calen += 2 + name->len;
- }
-
- certTypes = certificate_types;
- certTypesLength = sizeof certificate_types;
-
- length = 1 + certTypesLength + 2 + calen;
-
- rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_AppendHandshakeVariable(ss, certTypes, certTypesLength, 1);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, calen, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- for (i = 0, name = names; i < nnames; i++, name++) {
- rv = ssl3_AppendHandshakeVariable(ss, name->data, name->len, 2);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- }
-
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_SendServerHelloDone(sslSocket *ss)
-{
- SECStatus rv;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send server_hello_done handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- rv = ssl3_AppendHandshakeHeader(ss, server_hello_done, 0);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_FlushHandshake(ss, 0);
- if (rv != SECSuccess) {
- return rv; /* error code set by ssl3_FlushHandshake */
- }
- return SECSuccess;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Certificate Verify message
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- SSL3Hashes *hashes)
-{
- SECItem signed_hash = {siBuffer, NULL, 0};
- SECStatus rv;
- int errCode = SSL_ERROR_RX_MALFORMED_CERT_VERIFY;
- SSL3AlertDescription desc = handshake_failure;
- PRBool isTLS;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_verify handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3.hs.ws != wait_cert_verify || ss->sec.peerCert == NULL) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY;
- goto alert_loser;
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &signed_hash, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-
- isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- /* XXX verify that the key & kea match */
- rv = ssl3_VerifySignedHashes(hashes, ss->sec.peerCert, &signed_hash,
- isTLS, ss->pkcs11PinArg);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- desc = isTLS ? decrypt_error : handshake_failure;
- goto alert_loser;
- }
-
- signed_hash.data = NULL;
-
- if (length != 0) {
- desc = isTLS ? decode_error : illegal_parameter;
- goto alert_loser; /* malformed */
- }
- ss->ssl3.hs.ws = wait_change_cipher;
- return SECSuccess;
-
-alert_loser:
- SSL3_SendAlert(ss, alert_fatal, desc);
-loser:
- PORT_SetError(errCode);
- return SECFailure;
-}
-
-
-/* find a slot that is able to generate a PMS and wrap it with RSA.
- * Then generate and return the PMS.
- * If the serverKeySlot parameter is non-null, this function will use
- * that slot to do the job, otherwise it will find a slot.
- *
- * Called from ssl3_DeriveConnectionKeysPKCS11() (above)
- * sendRSAClientKeyExchange() (above)
- * ssl3_HandleRSAClientKeyExchange() (below)
- * Caller must hold the SpecWriteLock, the SSL3HandshakeLock
- */
-static PK11SymKey *
-ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
- PK11SlotInfo * serverKeySlot)
-{
- PK11SymKey * pms = NULL;
- PK11SlotInfo * slot = serverKeySlot;
- void * pwArg = ss->pkcs11PinArg;
- SECItem param;
- CK_VERSION version;
- CK_MECHANISM_TYPE mechanism_array[3];
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (slot == NULL) {
- SSLCipherAlgorithm calg;
- /* The specReadLock would suffice here, but we cannot assert on
- ** read locks. Also, all the callers who call with a non-null
- ** slot already hold the SpecWriteLock.
- */
- PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss));
- PORT_Assert(ss->ssl3.prSpec == ss->ssl3.pwSpec);
-
- calg = spec->cipher_def->calg;
- PORT_Assert(alg2Mech[calg].calg == calg);
-
- /* First get an appropriate slot. */
- mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN;
- mechanism_array[1] = CKM_RSA_PKCS;
- mechanism_array[2] = alg2Mech[calg].cmech;
-
- slot = PK11_GetBestSlotMultiple(mechanism_array, 3, pwArg);
- if (slot == NULL) {
- /* can't find a slot with all three, find a slot with the minimum */
- slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg);
- if (slot == NULL) {
- PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND);
- return pms; /* which is NULL */
- }
- }
- }
-
- /* Generate the pre-master secret ... */
- if (IS_DTLS(ss)) {
- SSL3ProtocolVersion temp;
-
- temp = dtls_TLSVersionToDTLSVersion(ss->clientHelloVersion);
- version.major = MSB(temp);
- version.minor = LSB(temp);
- } else {
- version.major = MSB(ss->clientHelloVersion);
- version.minor = LSB(ss->clientHelloVersion);
- }
-
- param.data = (unsigned char *)&version;
- param.len = sizeof version;
-
- pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, &param, 0, pwArg);
- if (!serverKeySlot)
- PK11_FreeSlot(slot);
- if (pms == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- }
- return pms;
-}
-
-/* Note: The Bleichenbacher attack on PKCS#1 necessitates that we NEVER
- * return any indication of failure of the Client Key Exchange message,
- * where that failure is caused by the content of the client's message.
- * This function must not return SECFailure for any reason that is directly
- * or indirectly caused by the content of the client's encrypted PMS.
- * We must not send an alert and also not drop the connection.
- * Instead, we generate a random PMS. This will cause a failure
- * in the processing the finished message, which is exactly where
- * the failure must occur.
- *
- * Called from ssl3_HandleClientKeyExchange
- */
-static SECStatus
-ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
- SSL3Opaque *b,
- PRUint32 length,
- SECKEYPrivateKey *serverKey)
-{
- PK11SymKey * pms;
-#ifndef NO_PKCS11_BYPASS
- unsigned char * cr = (unsigned char *)&ss->ssl3.hs.client_random;
- unsigned char * sr = (unsigned char *)&ss->ssl3.hs.server_random;
- ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec;
- unsigned int outLen = 0;
-#endif
- PRBool isTLS = PR_FALSE;
- SECStatus rv;
- SECItem enc_pms;
- unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH];
- SECItem pmsItem = {siBuffer, NULL, 0};
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- enc_pms.data = b;
- enc_pms.len = length;
- pmsItem.data = rsaPmsBuf;
- pmsItem.len = sizeof rsaPmsBuf;
-
- if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */
- PRInt32 kLen;
- kLen = ssl3_ConsumeHandshakeNumber(ss, 2, &enc_pms.data, &enc_pms.len);
- if (kLen < 0) {
- PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
- if ((unsigned)kLen < enc_pms.len) {
- enc_pms.len = kLen;
- }
- isTLS = PR_TRUE;
- } else {
- isTLS = (PRBool)(ss->ssl3.hs.kea_def->tls_keygen != 0);
- }
-
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- /* TRIPLE BYPASS, get PMS directly from RSA decryption.
- * Use PK11_PrivDecryptPKCS1 to decrypt the PMS to a buffer,
- * then, check for version rollback attack, then
- * do the equivalent of ssl3_DeriveMasterSecret, placing the MS in
- * pwSpec->msItem. Finally call ssl3_InitPendingCipherSpec with
- * ss and NULL, so that it will use the MS we've already derived here.
- */
-
- rv = PK11_PrivDecryptPKCS1(serverKey, rsaPmsBuf, &outLen,
- sizeof rsaPmsBuf, enc_pms.data, enc_pms.len);
- if (rv != SECSuccess) {
- /* triple bypass failed. Let's try for a double bypass. */
- goto double_bypass;
- } else if (ss->opt.detectRollBack) {
- SSL3ProtocolVersion client_version =
- (rsaPmsBuf[0] << 8) | rsaPmsBuf[1];
-
- if (IS_DTLS(ss)) {
- client_version = dtls_DTLSVersionToTLSVersion(client_version);
- }
-
- if (client_version != ss->clientHelloVersion) {
- /* Version roll-back detected. ensure failure. */
- rv = PK11_GenerateRandom(rsaPmsBuf, sizeof rsaPmsBuf);
- }
- }
- /* have PMS, build MS without PKCS11 */
- rv = ssl3_MasterKeyDeriveBypass(pwSpec, cr, sr, &pmsItem, isTLS,
- PR_TRUE);
- if (rv != SECSuccess) {
- pwSpec->msItem.data = pwSpec->raw_master_secret;
- pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH;
- PK11_GenerateRandom(pwSpec->msItem.data, pwSpec->msItem.len);
- }
- rv = ssl3_InitPendingCipherSpec(ss, NULL);
- } else
-#endif
- {
-#ifndef NO_PKCS11_BYPASS
-double_bypass:
-#endif
- /*
- * unwrap pms out of the incoming buffer
- * Note: CKM_SSL3_MASTER_KEY_DERIVE is NOT the mechanism used to do
- * the unwrap. Rather, it is the mechanism with which the
- * unwrapped pms will be used.
- */
- pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
- CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
- if (pms != NULL) {
- PRINT_BUF(60, (ss, "decrypted premaster secret:",
- PK11_GetKeyData(pms)->data,
- PK11_GetKeyData(pms)->len));
- } else {
- /* unwrap failed. Generate a bogus PMS and carry on. */
- PK11SlotInfo * slot = PK11_GetSlotFromPrivateKey(serverKey);
-
- ssl_GetSpecWriteLock(ss);
- pms = ssl3_GenerateRSAPMS(ss, ss->ssl3.prSpec, slot);
- ssl_ReleaseSpecWriteLock(ss);
- PK11_FreeSlot(slot);
- }
-
- if (pms == NULL) {
- /* last gasp. */
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
-
- /* This step will derive the MS from the PMS, among other things. */
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms);
- }
-
- if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
- }
- return SECSuccess;
-}
-
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 ClientKeyExchange message from the remote client
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- SECKEYPrivateKey *serverKey = NULL;
- SECStatus rv;
- const ssl3KEADef *kea_def;
- ssl3KeyPair *serverKeyPair = NULL;
-#ifdef NSS_ENABLE_ECC
- SECKEYPublicKey *serverPubKey = NULL;
-#endif /* NSS_ENABLE_ECC */
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle client_key_exchange handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3.hs.ws != wait_client_key) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
- return SECFailure;
- }
-
- kea_def = ss->ssl3.hs.kea_def;
-
- if (ss->ssl3.hs.usedStepDownKey) {
- PORT_Assert(kea_def->is_limited /* XXX OR cert is signing only */
- && kea_def->exchKeyType == kt_rsa
- && ss->stepDownKeyPair != NULL);
- if (!kea_def->is_limited ||
- kea_def->exchKeyType != kt_rsa ||
- ss->stepDownKeyPair == NULL) {
- /* shouldn't happen, don't use step down if it does */
- goto skip;
- }
- serverKeyPair = ss->stepDownKeyPair;
- ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB;
- } else
-skip:
-#ifdef NSS_ENABLE_ECC
- /* XXX Using SSLKEAType to index server certifiates
- * does not work for (EC)DHE ciphers. Until we have
- * an indexing mechanism general enough for all key
- * exchange algorithms, we'll need to deal with each
- * one seprately.
- */
- if ((kea_def->kea == kea_ecdhe_rsa) ||
- (kea_def->kea == kea_ecdhe_ecdsa)) {
- if (ss->ephemeralECDHKeyPair != NULL) {
- serverKeyPair = ss->ephemeralECDHKeyPair;
- if (serverKeyPair->pubKey) {
- ss->sec.keaKeyBits =
- SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey);
- }
- }
- } else
-#endif
- {
- sslServerCerts * sc = ss->serverCerts + kea_def->exchKeyType;
- serverKeyPair = sc->serverKeyPair;
- ss->sec.keaKeyBits = sc->serverKeyBits;
- }
-
- if (serverKeyPair) {
- serverKey = serverKeyPair->privKey;
- }
-
- if (serverKey == NULL) {
- SEND_ALERT
- PORT_SetError(SSL_ERROR_NO_SERVER_KEY_FOR_ALG);
- return SECFailure;
- }
-
- ss->sec.keaType = kea_def->exchKeyType;
-
- switch (kea_def->exchKeyType) {
- case kt_rsa:
- rv = ssl3_HandleRSAClientKeyExchange(ss, b, length, serverKey);
- if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* error code set */
- }
- break;
-
-
-#ifdef NSS_ENABLE_ECC
- case kt_ecdh:
- /* XXX We really ought to be able to store multiple
- * EC certs (a requirement if we wish to support both
- * ECDH-RSA and ECDH-ECDSA key exchanges concurrently).
- * When we make that change, we'll need an index other
- * than kt_ecdh to pick the right EC certificate.
- */
- if (serverKeyPair) {
- serverPubKey = serverKeyPair->pubKey;
- }
- if (serverPubKey == NULL) {
- /* XXX Is this the right error code? */
- PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
- return SECFailure;
- }
- rv = ssl3_HandleECDHClientKeyExchange(ss, b, length,
- serverPubKey, serverKey);
- if (rv != SECSuccess) {
- return SECFailure; /* error code set */
- }
- break;
-#endif /* NSS_ENABLE_ECC */
-
- default:
- (void) ssl3_HandshakeFailure(ss);
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
- }
- ss->ssl3.hs.ws = ss->sec.peerCert ? wait_cert_verify : wait_change_cipher;
- return SECSuccess;
-
-}
-
-/* This is TLS's equivalent of sending a no_certificate alert. */
-static SECStatus
-ssl3_SendEmptyCertificate(sslSocket *ss)
-{
- SECStatus rv;
-
- rv = ssl3_AppendHandshakeHeader(ss, certificate, 3);
- if (rv == SECSuccess) {
- rv = ssl3_AppendHandshakeNumber(ss, 0, 3);
- }
- return rv; /* error, if any, set by functions called above. */
-}
-
-SECStatus
-ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- SECStatus rv;
- NewSessionTicket session_ticket;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle session_ticket handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (ss->ssl3.hs.ws != wait_new_session_ticket) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET);
- return SECFailure;
- }
-
- session_ticket.received_timestamp = ssl_Time();
- if (length < 4) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
- return SECFailure;
- }
- session_ticket.ticket_lifetime_hint =
- (PRUint32)ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length);
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &session_ticket.ticket, 2,
- &b, &length);
- if (length != 0 || rv != SECSuccess) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
- return SECFailure; /* malformed */
- }
-
- rv = ssl3_SetSIDSessionTicket(ss->sec.ci.sid, &session_ticket);
- if (rv != SECSuccess) {
- (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
- PORT_SetError(SSL_ERROR_INTERNAL_ERROR_ALERT);
- return SECFailure;
- }
- ss->ssl3.hs.ws = wait_change_cipher;
- return SECSuccess;
-}
-
-#ifdef NISCC_TEST
-static PRInt32 connNum = 0;
-
-static SECStatus
-get_fake_cert(SECItem *pCertItem, int *pIndex)
-{
- PRFileDesc *cf;
- char * testdir;
- char * startat;
- char * stopat;
- const char *extension;
- int fileNum;
- PRInt32 numBytes = 0;
- PRStatus prStatus;
- PRFileInfo info;
- char cfn[100];
-
- pCertItem->data = 0;
- if ((testdir = PR_GetEnv("NISCC_TEST")) == NULL) {
- return SECSuccess;
- }
- *pIndex = (NULL != strstr(testdir, "root"));
- extension = (strstr(testdir, "simple") ? "" : ".der");
- fileNum = PR_ATOMIC_INCREMENT(&connNum) - 1;
- if ((startat = PR_GetEnv("START_AT")) != NULL) {
- fileNum += atoi(startat);
- }
- if ((stopat = PR_GetEnv("STOP_AT")) != NULL &&
- fileNum >= atoi(stopat)) {
- *pIndex = -1;
- return SECSuccess;
- }
- sprintf(cfn, "%s/%08d%s", testdir, fileNum, extension);
- cf = PR_Open(cfn, PR_RDONLY, 0);
- if (!cf) {
- goto loser;
- }
- prStatus = PR_GetOpenFileInfo(cf, &info);
- if (prStatus != PR_SUCCESS) {
- PR_Close(cf);
- goto loser;
- }
- pCertItem = SECITEM_AllocItem(NULL, pCertItem, info.size);
- if (pCertItem) {
- numBytes = PR_Read(cf, pCertItem->data, info.size);
- }
- PR_Close(cf);
- if (numBytes != info.size) {
- SECITEM_FreeItem(pCertItem, PR_FALSE);
- PORT_SetError(SEC_ERROR_IO);
- goto loser;
- }
- fprintf(stderr, "using %s\n", cfn);
- return SECSuccess;
-
-loser:
- fprintf(stderr, "failed to use %s\n", cfn);
- *pIndex = -1;
- return SECFailure;
-}
-#endif
-
-/*
- * Used by both client and server.
- * Called from HandleServerHelloDone and from SendServerHelloSequence.
- */
-static SECStatus
-ssl3_SendCertificate(sslSocket *ss)
-{
- SECStatus rv;
- CERTCertificateList *certChain;
- int len = 0;
- int i;
- SSL3KEAType certIndex;
-#ifdef NISCC_TEST
- SECItem fakeCert;
- int ndex = -1;
-#endif
-
- SSL_TRC(3, ("%d: SSL3[%d]: send certificate handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- if (ss->sec.localCert)
- CERT_DestroyCertificate(ss->sec.localCert);
- if (ss->sec.isServer) {
- sslServerCerts * sc = NULL;
-
- /* XXX SSLKEAType isn't really a good choice for
- * indexing certificates (it breaks when we deal
- * with (EC)DHE-* cipher suites. This hack ensures
- * the RSA cert is picked for (EC)DHE-RSA.
- * Revisit this when we add server side support
- * for ECDHE-ECDSA or client-side authentication
- * using EC certificates.
- */
- if ((ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) ||
- (ss->ssl3.hs.kea_def->kea == kea_dhe_rsa)) {
- certIndex = kt_rsa;
- } else {
- certIndex = ss->ssl3.hs.kea_def->exchKeyType;
- }
- sc = ss->serverCerts + certIndex;
- certChain = sc->serverCertChain;
- ss->sec.authKeyBits = sc->serverKeyBits;
- ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType;
- ss->sec.localCert = CERT_DupCertificate(sc->serverCert);
- } else {
- certChain = ss->ssl3.clientCertChain;
- ss->sec.localCert = CERT_DupCertificate(ss->ssl3.clientCertificate);
- }
-
-#ifdef NISCC_TEST
- rv = get_fake_cert(&fakeCert, &ndex);
-#endif
-
- if (certChain) {
- for (i = 0; i < certChain->len; i++) {
-#ifdef NISCC_TEST
- if (fakeCert.len > 0 && i == ndex) {
- len += fakeCert.len + 3;
- } else {
- len += certChain->certs[i].len + 3;
- }
-#else
- len += certChain->certs[i].len + 3;
-#endif
- }
- }
-
- rv = ssl3_AppendHandshakeHeader(ss, certificate, len + 3);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, len, 3);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- if (certChain) {
- for (i = 0; i < certChain->len; i++) {
-#ifdef NISCC_TEST
- if (fakeCert.len > 0 && i == ndex) {
- rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data,
- fakeCert.len, 3);
- SECITEM_FreeItem(&fakeCert, PR_FALSE);
- } else {
- rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
- certChain->certs[i].len, 3);
- }
-#else
- rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data,
- certChain->certs[i].len, 3);
-#endif
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- }
- }
-
- return SECSuccess;
-}
-
-/*
- * Used by server only.
- * single-stapling, send only a single cert status
- */
-static SECStatus
-ssl3_SendCertificateStatus(sslSocket *ss)
-{
- SECStatus rv;
- CERTCertificateList *certChain;
- int len = 0;
- int i;
- SSL3KEAType certIndex;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send certificate status handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- if (!ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn))
- return SECSuccess;
-
- if (!ss->certStatusArray)
- return SECSuccess;
-
- /* Use the array's first item only (single stapling) */
- len = 1 + ss->certStatusArray->items[0].len + 3;
-
- rv = ssl3_AppendHandshakeHeader(ss, certificate_status, len);
- if (rv != SECSuccess) {
- return rv; /* err set by AppendHandshake. */
- }
- rv = ssl3_AppendHandshakeNumber(ss, 1 /*ocsp*/, 1);
- if (rv != SECSuccess)
- return rv; /* err set by AppendHandshake. */
-
- rv = ssl3_AppendHandshakeVariable(ss,
- ss->certStatusArray->items[0].data,
- ss->certStatusArray->items[0].len,
- 3);
- if (rv != SECSuccess)
- return rv; /* err set by AppendHandshake. */
-
- return SECSuccess;
-}
-
-/* This is used to delete the CA certificates in the peer certificate chain
- * from the cert database after they've been validated.
- */
-static void
-ssl3_CleanupPeerCerts(sslSocket *ss)
-{
- PRArenaPool * arena = ss->ssl3.peerCertArena;
- ssl3CertNode *certs = (ssl3CertNode *)ss->ssl3.peerCertChain;
-
- for (; certs; certs = certs->next) {
- CERT_DestroyCertificate(certs->cert);
- }
- if (arena) PORT_FreeArena(arena, PR_FALSE);
- ss->ssl3.peerCertArena = NULL;
- ss->ssl3.peerCertChain = NULL;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 CertificateStatus message.
- * Caller must hold Handshake and RecvBuf locks.
- * This is always called before ssl3_HandleCertificate, even if the Certificate
- * message is sent first.
- */
-static SECStatus
-ssl3_HandleCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- PRInt32 status, len;
- PORT_Assert(ss->ssl3.hs.ws == wait_certificate_status);
-
- /* Consume the CertificateStatusType enum */
- status = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length);
- if (status != 1 /* ocsp */) {
- goto format_loser;
- }
-
- len = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (len != length) {
- goto format_loser;
- }
-
-#define MAX_CERTSTATUS_LEN 0x1ffff /* 128k - 1 */
- if (length > MAX_CERTSTATUS_LEN)
- goto format_loser;
-#undef MAX_CERTSTATUS_LEN
-
- /* Array size 1, because we currently implement single-stapling only*/
- SECITEM_AllocArray(NULL, &ss->sec.ci.sid->peerCertStatus, 1);
- if (!ss->sec.ci.sid->peerCertStatus.items)
- return SECFailure;
-
- ss->sec.ci.sid->peerCertStatus.items[0].data = PORT_Alloc(length);
-
- if (!ss->sec.ci.sid->peerCertStatus.items[0].data) {
- SECITEM_FreeArray(&ss->sec.ci.sid->peerCertStatus, PR_FALSE);
- return SECFailure;
- }
-
- PORT_Memcpy(ss->sec.ci.sid->peerCertStatus.items[0].data, b, length);
- ss->sec.ci.sid->peerCertStatus.items[0].len = length;
- ss->sec.ci.sid->peerCertStatus.items[0].type = siBuffer;
- return SECSuccess;
-
-format_loser:
- return ssl3_DecodeError(ss);
-}
-
-static SECStatus ssl3_AuthCertificate(sslSocket *ss);
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Certificate message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- ssl3CertNode * c;
- ssl3CertNode * lastCert = NULL;
- PRInt32 remaining = 0;
- PRInt32 size;
- SECStatus rv;
- PRBool isServer = (PRBool)(!!ss->sec.isServer);
- PRBool isTLS;
- SSL3AlertDescription desc;
- int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE;
- SECItem certItem;
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle certificate handshake",
- SSL_GETPID(), ss->fd));
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if ((ss->ssl3.hs.ws != wait_server_cert) &&
- (ss->ssl3.hs.ws != wait_client_cert)) {
- desc = unexpected_message;
- errCode = SSL_ERROR_RX_UNEXPECTED_CERTIFICATE;
- goto alert_loser;
- }
-
- if (ss->sec.peerCert != NULL) {
- if (ss->sec.peerKey) {
- SECKEY_DestroyPublicKey(ss->sec.peerKey);
- ss->sec.peerKey = NULL;
- }
- CERT_DestroyCertificate(ss->sec.peerCert);
- ss->sec.peerCert = NULL;
- }
-
- ssl3_CleanupPeerCerts(ss);
- isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- /* It is reported that some TLS client sends a Certificate message
- ** with a zero-length message body. We'll treat that case like a
- ** normal no_certificates message to maximize interoperability.
- */
- if (length) {
- remaining = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (remaining < 0)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
- if ((PRUint32)remaining > length)
- goto decode_loser;
- }
-
- if (!remaining) {
- if (!(isTLS && isServer)) {
- desc = bad_certificate;
- goto alert_loser;
- }
- /* This is TLS's version of a no_certificate alert. */
- /* I'm a server. I've requested a client cert. He hasn't got one. */
- rv = ssl3_HandleNoCertificate(ss);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser;
- }
- ss->ssl3.hs.ws = wait_client_key;
- return SECSuccess;
- }
-
- ss->ssl3.peerCertArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (ss->ssl3.peerCertArena == NULL) {
- goto loser; /* don't send alerts on memory errors */
- }
-
- /* First get the peer cert. */
- remaining -= 3;
- if (remaining < 0)
- goto decode_loser;
-
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (size <= 0)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- if (remaining < size)
- goto decode_loser;
-
- certItem.data = b;
- certItem.len = size;
- b += size;
- length -= size;
- remaining -= size;
-
- ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
- if (ss->sec.peerCert == NULL) {
- /* We should report an alert if the cert was bad, but not if the
- * problem was just some local problem, like memory error.
- */
- goto ambiguous_err;
- }
-
- /* Now get all of the CA certs. */
- while (remaining > 0) {
- remaining -= 3;
- if (remaining < 0)
- goto decode_loser;
-
- size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length);
- if (size <= 0)
- goto loser; /* fatal alert already sent by ConsumeHandshake. */
-
- if (remaining < size)
- goto decode_loser;
-
- certItem.data = b;
- certItem.len = size;
- b += size;
- length -= size;
- remaining -= size;
-
- c = PORT_ArenaNew(ss->ssl3.peerCertArena, ssl3CertNode);
- if (c == NULL) {
- goto loser; /* don't send alerts on memory errors */
- }
-
- c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
- if (c->cert == NULL) {
- goto ambiguous_err;
- }
-
- c->next = NULL;
- if (lastCert) {
- lastCert->next = c;
- } else {
- ss->ssl3.peerCertChain = c;
- }
- lastCert = c;
- }
-
- if (remaining != 0)
- goto decode_loser;
-
- SECKEY_UpdateCertPQG(ss->sec.peerCert);
-
- if (!isServer && ssl3_ExtensionNegotiated(ss, ssl_cert_status_xtn)) {
- ss->ssl3.hs.ws = wait_certificate_status;
- rv = SECSuccess;
- } else {
- rv = ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
- }
-
- return rv;
-
-ambiguous_err:
- errCode = PORT_GetError();
- switch (errCode) {
- case PR_OUT_OF_MEMORY_ERROR:
- case SEC_ERROR_BAD_DATABASE:
- case SEC_ERROR_NO_MEMORY:
- if (isTLS) {
- desc = internal_error;
- goto alert_loser;
- }
- goto loser;
- }
- ssl3_SendAlertForCertError(ss, errCode);
- goto loser;
-
-decode_loser:
- desc = isTLS ? decode_error : bad_certificate;
-
-alert_loser:
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-
-loser:
- (void)ssl_MapLowLevelError(errCode);
- return SECFailure;
-}
-
-static SECStatus
-ssl3_AuthCertificate(sslSocket *ss)
-{
- SECStatus rv;
- PRBool isServer = (PRBool)(!!ss->sec.isServer);
- int errCode;
-
- ss->ssl3.hs.authCertificatePending = PR_FALSE;
-
- /*
- * Ask caller-supplied callback function to validate cert chain.
- */
- rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd,
- PR_TRUE, isServer);
- if (rv) {
- errCode = PORT_GetError();
- if (rv != SECWouldBlock) {
- if (ss->handleBadCert) {
- rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
- }
- }
-
- if (rv == SECWouldBlock) {
- if (ss->sec.isServer) {
- errCode = SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS;
- rv = SECFailure;
- goto loser;
- }
-
- ss->ssl3.hs.authCertificatePending = PR_TRUE;
- rv = SECSuccess;
-
- /* XXX: Async cert validation and False Start don't work together
- * safely yet; if we leave False Start enabled, we may end up false
- * starting (sending application data) before we
- * SSL_AuthCertificateComplete has been called.
- */
- ss->opt.enableFalseStart = PR_FALSE;
- }
-
- if (rv != SECSuccess) {
- ssl3_SendAlertForCertError(ss, errCode);
- goto loser;
- }
- }
-
- ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
-
- if (!ss->sec.isServer) {
- CERTCertificate *cert = ss->sec.peerCert;
-
- /* set the server authentication and key exchange types and sizes
- ** from the value in the cert. If the key exchange key is different,
- ** it will get fixed when we handle the server key exchange message.
- */
- SECKEYPublicKey * pubKey = CERT_ExtractPublicKey(cert);
- ss->sec.authAlgorithm = ss->ssl3.hs.kea_def->signKeyType;
- ss->sec.keaType = ss->ssl3.hs.kea_def->exchKeyType;
- if (pubKey) {
- ss->sec.keaKeyBits = ss->sec.authKeyBits =
- SECKEY_PublicKeyStrengthInBits(pubKey);
-#ifdef NSS_ENABLE_ECC
- if (ss->sec.keaType == kt_ecdh) {
- /* Get authKeyBits from signing key.
- * XXX The code below uses a quick approximation of
- * key size based on cert->signatureWrap.signature.data
- * (which contains the DER encoded signature). The field
- * cert->signatureWrap.signature.len contains the
- * length of the encoded signature in bits.
- */
- if (ss->ssl3.hs.kea_def->kea == kea_ecdh_ecdsa) {
- ss->sec.authKeyBits =
- cert->signatureWrap.signature.data[3]*8;
- if (cert->signatureWrap.signature.data[4] == 0x00)
- ss->sec.authKeyBits -= 8;
- /*
- * XXX: if cert is not signed by ecdsa we should
- * destroy pubKey and goto bad_cert
- */
- } else if (ss->ssl3.hs.kea_def->kea == kea_ecdh_rsa) {
- ss->sec.authKeyBits = cert->signatureWrap.signature.len;
- /*
- * XXX: if cert is not signed by rsa we should
- * destroy pubKey and goto bad_cert
- */
- }
- }
-#endif /* NSS_ENABLE_ECC */
- SECKEY_DestroyPublicKey(pubKey);
- pubKey = NULL;
- }
-
- ss->ssl3.hs.ws = wait_cert_request; /* disallow server_key_exchange */
- if (ss->ssl3.hs.kea_def->is_limited ||
- /* XXX OR server cert is signing only. */
-#ifdef NSS_ENABLE_ECC
- ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
- ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa ||
-#endif /* NSS_ENABLE_ECC */
- ss->ssl3.hs.kea_def->exchKeyType == kt_dh) {
- ss->ssl3.hs.ws = wait_server_key; /* allow server_key_exchange */
- }
- } else {
- ss->ssl3.hs.ws = wait_client_key;
- }
-
- PORT_Assert(rv == SECSuccess);
- if (rv != SECSuccess) {
- errCode = SEC_ERROR_LIBRARY_FAILURE;
- rv = SECFailure;
- goto loser;
- }
-
- return rv;
-
-loser:
- (void)ssl_MapLowLevelError(errCode);
- return SECFailure;
-}
-
-static SECStatus ssl3_FinishHandshake(sslSocket *ss);
-
-static SECStatus
-ssl3_AlwaysFail(sslSocket * ss)
-{
- PORT_SetError(PR_INVALID_STATE_ERROR);
- return SECFailure;
-}
-
-/* Caller must hold 1stHandshakeLock.
-*/
-SECStatus
-ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error)
-{
- SECStatus rv;
-
- PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
-
- if (ss->sec.isServer) {
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS);
- return SECFailure;
- }
-
- ssl_GetRecvBufLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- if (!ss->ssl3.hs.authCertificatePending) {
- PORT_SetError(PR_INVALID_STATE_ERROR);
- rv = SECFailure;
- goto done;
- }
-
- ss->ssl3.hs.authCertificatePending = PR_FALSE;
-
- if (error != 0) {
- ss->ssl3.hs.restartTarget = ssl3_AlwaysFail;
- ssl3_SendAlertForCertError(ss, error);
- rv = SECSuccess;
- } else if (ss->ssl3.hs.restartTarget != NULL) {
- sslRestartTarget target = ss->ssl3.hs.restartTarget;
- ss->ssl3.hs.restartTarget = NULL;
- rv = target(ss);
- /* Even if we blocked here, we have accomplished enough to claim
- * success. Any remaining work will be taken care of by subsequent
- * calls to SSL_ForceHandshake/PR_Send/PR_Read/etc.
- */
- if (rv == SECWouldBlock) {
- rv = SECSuccess;
- }
- } else {
- rv = SECSuccess;
- }
-
-done:
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_ReleaseRecvBufLock(ss);
-
- return rv;
-}
-
-static SECStatus
-ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
- PRBool isServer,
- const SSL3Finished * hashes,
- TLSFinished * tlsFinished)
-{
- const char * label;
- unsigned int len;
- SECStatus rv;
-
- label = isServer ? "server finished" : "client finished";
- len = 15;
-
- rv = ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->md5,
- sizeof *hashes, tlsFinished->verify_data,
- sizeof tlsFinished->verify_data);
-
- return rv;
-}
-
-/* The calling function must acquire and release the appropriate
- * lock (e.g., ssl_GetSpecReadLock / ssl_ReleaseSpecReadLock for
- * ss->ssl3.crSpec).
- */
-SECStatus
-ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label,
- unsigned int labelLen, const unsigned char *val, unsigned int valLen,
- unsigned char *out, unsigned int outLen)
-{
- SECStatus rv = SECSuccess;
-
- if (spec->master_secret && !spec->bypassCiphers) {
- SECItem param = {siBuffer, NULL, 0};
- PK11Context *prf_context =
- PK11_CreateContextBySymKey(CKM_TLS_PRF_GENERAL, CKA_SIGN,
- spec->master_secret, &param);
- unsigned int retLen;
-
- if (!prf_context)
- return SECFailure;
-
- rv = PK11_DigestBegin(prf_context);
- rv |= PK11_DigestOp(prf_context, (unsigned char *) label, labelLen);
- rv |= PK11_DigestOp(prf_context, val, valLen);
- rv |= PK11_DigestFinal(prf_context, out, &retLen, outLen);
- PORT_Assert(rv != SECSuccess || retLen == outLen);
-
- PK11_DestroyContext(prf_context, PR_TRUE);
- } else {
- /* bypass PKCS11 */
-#ifdef NO_PKCS11_BYPASS
- PORT_Assert(spec->master_secret);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- rv = SECFailure;
-#else
- SECItem inData = { siBuffer, };
- SECItem outData = { siBuffer, };
- PRBool isFIPS = PR_FALSE;
-
- inData.data = (unsigned char *) val;
- inData.len = valLen;
- outData.data = out;
- outData.len = outLen;
- rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS);
- PORT_Assert(rv != SECSuccess || outData.len == outLen);
-#endif
- }
- return rv;
-}
-
-/* called from ssl3_HandleServerHelloDone
- */
-static SECStatus
-ssl3_SendNextProto(sslSocket *ss)
-{
- SECStatus rv;
- int padding_len;
- static const unsigned char padding[32] = {0};
-
- if (ss->ssl3.nextProto.len == 0)
- return SECSuccess;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32);
-
- rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len +
- 2 + padding_len);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshakeHeader */
- }
- rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data,
- ss->ssl3.nextProto.len, 1);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake */
- }
- rv = ssl3_AppendHandshakeVariable(ss, padding, padding_len, 1);
- if (rv != SECSuccess) {
- return rv; /* error code set by AppendHandshake */
- }
- return rv;
-}
-
-/* called from ssl3_SendFinished
- *
- * This function is simply a debugging aid and therefore does not return a
- * SECStatus. */
-static void
-ssl3_RecordKeyLog(sslSocket *ss)
-{
- sslSessionID *sid;
- SECStatus rv;
- SECItem *keyData;
- char buf[14 /* "CLIENT_RANDOM " */ +
- SSL3_RANDOM_LENGTH*2 /* client_random */ +
- 1 /* " " */ +
- 48*2 /* master secret */ +
- 1 /* new line */];
- unsigned int j;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- sid = ss->sec.ci.sid;
-
- if (!ssl_keylog_iob)
- return;
-
- rv = PK11_ExtractKeyValue(ss->ssl3.cwSpec->master_secret);
- if (rv != SECSuccess)
- return;
-
- ssl_GetSpecReadLock(ss);
-
- /* keyData does not need to be freed. */
- keyData = PK11_GetKeyData(ss->ssl3.cwSpec->master_secret);
- if (!keyData || !keyData->data || keyData->len != 48) {
- ssl_ReleaseSpecReadLock(ss);
- return;
- }
-
- /* https://developer.mozilla.org/en/NSS_Key_Log_Format */
-
- /* There could be multiple, concurrent writers to the
- * keylog, so we have to do everything in a single call to
- * fwrite. */
-
- memcpy(buf, "CLIENT_RANDOM ", 14);
- j = 14;
- hexEncode(buf + j, ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
- j += SSL3_RANDOM_LENGTH*2;
- buf[j++] = ' ';
- hexEncode(buf + j, keyData->data, 48);
- j += 48*2;
- buf[j++] = '\n';
-
- PORT_Assert(j == sizeof(buf));
-
- ssl_ReleaseSpecReadLock(ss);
-
- if (fwrite(buf, sizeof(buf), 1, ssl_keylog_iob) != 1)
- return;
- fflush(ssl_keylog_iob);
- return;
-}
-
-/* called from ssl3_HandleServerHelloDone
- * ssl3_HandleClientHello
- * ssl3_HandleFinished
- */
-static SECStatus
-ssl3_SendFinished(sslSocket *ss, PRInt32 flags)
-{
- ssl3CipherSpec *cwSpec;
- PRBool isTLS;
- PRBool isServer = ss->sec.isServer;
- SECStatus rv;
- SSL3Sender sender = isServer ? sender_server : sender_client;
- SSL3Finished hashes;
- TLSFinished tlsFinished;
-
- SSL_TRC(3, ("%d: SSL3[%d]: send finished handshake", SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- ssl_GetSpecReadLock(ss);
- cwSpec = ss->ssl3.cwSpec;
- isTLS = (PRBool)(cwSpec->version > SSL_LIBRARY_VERSION_3_0);
- rv = ssl3_ComputeHandshakeHashes(ss, cwSpec, &hashes, sender);
- if (isTLS && rv == SECSuccess) {
- rv = ssl3_ComputeTLSFinished(cwSpec, isServer, &hashes, &tlsFinished);
- }
- ssl_ReleaseSpecReadLock(ss);
- if (rv != SECSuccess) {
- goto fail; /* err code was set by ssl3_ComputeHandshakeHashes */
- }
-
- if (isTLS) {
- if (isServer)
- ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished;
- else
- ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished;
- ss->ssl3.hs.finishedBytes = sizeof tlsFinished;
- rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof tlsFinished);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- rv = ssl3_AppendHandshake(ss, &tlsFinished, sizeof tlsFinished);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- } else {
- if (isServer)
- ss->ssl3.hs.finishedMsgs.sFinished[1] = hashes;
- else
- ss->ssl3.hs.finishedMsgs.sFinished[0] = hashes;
- ss->ssl3.hs.finishedBytes = sizeof hashes;
- rv = ssl3_AppendHandshakeHeader(ss, finished, sizeof hashes);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- rv = ssl3_AppendHandshake(ss, &hashes, sizeof hashes);
- if (rv != SECSuccess)
- goto fail; /* err set by AppendHandshake. */
- }
- rv = ssl3_FlushHandshake(ss, flags);
- if (rv != SECSuccess) {
- goto fail; /* error code set by ssl3_FlushHandshake */
- }
-
- ssl3_RecordKeyLog(ss);
-
- return SECSuccess;
-
-fail:
- return rv;
-}
-
-/* wrap the master secret, and put it into the SID.
- * Caller holds the Spec read lock.
- */
-SECStatus
-ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid,
- ssl3CipherSpec *spec, SSL3KEAType effectiveExchKeyType)
-{
- PK11SymKey * wrappingKey = NULL;
- PK11SlotInfo * symKeySlot;
- void * pwArg = ss->pkcs11PinArg;
- SECStatus rv = SECFailure;
- PRBool isServer = ss->sec.isServer;
- CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
- symKeySlot = PK11_GetSlotFromKey(spec->master_secret);
- if (!isServer) {
- int wrapKeyIndex;
- int incarnation;
-
- /* these next few functions are mere accessors and don't fail. */
- sid->u.ssl3.masterWrapIndex = wrapKeyIndex =
- PK11_GetCurrentWrapIndex(symKeySlot);
- PORT_Assert(wrapKeyIndex == 0); /* array has only one entry! */
-
- sid->u.ssl3.masterWrapSeries = incarnation =
- PK11_GetSlotSeries(symKeySlot);
- sid->u.ssl3.masterSlotID = PK11_GetSlotID(symKeySlot);
- sid->u.ssl3.masterModuleID = PK11_GetModuleID(symKeySlot);
- sid->u.ssl3.masterValid = PR_TRUE;
- /* Get the default wrapping key, for wrapping the master secret before
- * placing it in the SID cache entry. */
- wrappingKey = PK11_GetWrapKey(symKeySlot, wrapKeyIndex,
- CKM_INVALID_MECHANISM, incarnation,
- pwArg);
- if (wrappingKey) {
- mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
- } else {
- int keyLength;
- /* if the wrappingKey doesn't exist, attempt to create it.
- * Note: we intentionally ignore errors here. If we cannot
- * generate a wrapping key, it is not fatal to this SSL connection,
- * but we will not be able to restart this session.
- */
- mechanism = PK11_GetBestWrapMechanism(symKeySlot);
- keyLength = PK11_GetBestKeyLength(symKeySlot, mechanism);
- /* Zero length means fixed key length algorithm, or error.
- * It's ambiguous.
- */
- wrappingKey = PK11_KeyGen(symKeySlot, mechanism, NULL,
- keyLength, pwArg);
- if (wrappingKey) {
- PK11_SetWrapKey(symKeySlot, wrapKeyIndex, wrappingKey);
- }
- }
- } else {
- /* server socket using session cache. */
- mechanism = PK11_GetBestWrapMechanism(symKeySlot);
- if (mechanism != CKM_INVALID_MECHANISM) {
- wrappingKey =
- getWrappingKey(ss, symKeySlot, effectiveExchKeyType,
- mechanism, pwArg);
- if (wrappingKey) {
- mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
- }
- }
- }
-
- sid->u.ssl3.masterWrapMech = mechanism;
- PK11_FreeSlot(symKeySlot);
-
- if (wrappingKey) {
- SECItem wmsItem;
-
- wmsItem.data = sid->u.ssl3.keys.wrapped_master_secret;
- wmsItem.len = sizeof sid->u.ssl3.keys.wrapped_master_secret;
- rv = PK11_WrapSymKey(mechanism, NULL, wrappingKey,
- spec->master_secret, &wmsItem);
- /* rv is examined below. */
- sid->u.ssl3.keys.wrapped_master_secret_len = wmsItem.len;
- PK11_FreeSymKey(wrappingKey);
- }
- return rv;
-}
-
-/* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
- * ssl3 Finished message from the peer.
- * Caller must hold Handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
- const SSL3Hashes *hashes)
-{
- sslSessionID * sid = ss->sec.ci.sid;
- SECStatus rv = SECSuccess;
- PRBool isServer = ss->sec.isServer;
- PRBool isTLS;
- SSL3KEAType effectiveExchKeyType;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- SSL_TRC(3, ("%d: SSL3[%d]: handle finished handshake",
- SSL_GETPID(), ss->fd));
-
- if (ss->ssl3.hs.ws != wait_finished) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_FINISHED);
- return SECFailure;
- }
-
- isTLS = (PRBool)(ss->ssl3.crSpec->version > SSL_LIBRARY_VERSION_3_0);
- if (isTLS) {
- TLSFinished tlsFinished;
-
- if (length != sizeof tlsFinished) {
- (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
- return SECFailure;
- }
- rv = ssl3_ComputeTLSFinished(ss->ssl3.crSpec, !isServer,
- hashes, &tlsFinished);
- if (!isServer)
- ss->ssl3.hs.finishedMsgs.tFinished[1] = tlsFinished;
- else
- ss->ssl3.hs.finishedMsgs.tFinished[0] = tlsFinished;
- ss->ssl3.hs.finishedBytes = sizeof tlsFinished;
- if (rv != SECSuccess ||
- 0 != NSS_SecureMemcmp(&tlsFinished, b, length)) {
- (void)SSL3_SendAlert(ss, alert_fatal, decrypt_error);
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- } else {
- if (length != sizeof(SSL3Hashes)) {
- (void)ssl3_IllegalParameter(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_FINISHED);
- return SECFailure;
- }
-
- if (!isServer)
- ss->ssl3.hs.finishedMsgs.sFinished[1] = *hashes;
- else
- ss->ssl3.hs.finishedMsgs.sFinished[0] = *hashes;
- ss->ssl3.hs.finishedBytes = sizeof *hashes;
- if (0 != NSS_SecureMemcmp(hashes, b, length)) {
- (void)ssl3_HandshakeFailure(ss);
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- }
-
- ssl_GetXmitBufLock(ss); /*************************************/
-
- if ((isServer && !ss->ssl3.hs.isResuming) ||
- (!isServer && ss->ssl3.hs.isResuming)) {
- PRInt32 flags = 0;
-
- /* Send a NewSessionTicket message if the client sent us
- * either an empty session ticket, or one that did not verify.
- * (Note that if either of these conditions was met, then the
- * server has sent a SessionTicket extension in the
- * ServerHello message.)
- */
- if (isServer && !ss->ssl3.hs.isResuming &&
- ssl3_ExtensionNegotiated(ss, ssl_session_ticket_xtn)) {
- rv = ssl3_SendNewSessionTicket(ss);
- if (rv != SECSuccess) {
- goto xmit_loser;
- }
- }
-
- rv = ssl3_SendChangeCipherSpecs(ss);
- if (rv != SECSuccess) {
- goto xmit_loser; /* err is set. */
- }
- /* If this thread is in SSL_SecureSend (trying to write some data)
- ** then set the ssl_SEND_FLAG_FORCE_INTO_BUFFER flag, so that the
- ** last two handshake messages (change cipher spec and finished)
- ** will be sent in the same send/write call as the application data.
- */
- if (ss->writerThread == PR_GetCurrentThread()) {
- flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER;
- }
-
- if (!isServer && !ss->firstHsDone) {
- rv = ssl3_SendNextProto(ss);
- if (rv != SECSuccess) {
- goto xmit_loser; /* err code was set. */
- }
- }
-
- if (IS_DTLS(ss)) {
- flags |= ssl_SEND_FLAG_NO_RETRANSMIT;
- }
-
- rv = ssl3_SendFinished(ss, flags);
- if (rv != SECSuccess) {
- goto xmit_loser; /* err is set. */
- }
- }
-
-xmit_loser:
- ssl_ReleaseXmitBufLock(ss); /*************************************/
- if (rv != SECSuccess) {
- return rv;
- }
-
- ss->gs.writeOffset = 0;
- ss->gs.readOffset = 0;
-
- if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
- effectiveExchKeyType = kt_rsa;
- } else {
- effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
- }
-
- if (sid->cached == never_cached && !ss->opt.noCache && ss->sec.cache) {
- /* fill in the sid */
- sid->u.ssl3.cipherSuite = ss->ssl3.hs.cipher_suite;
- sid->u.ssl3.compression = ss->ssl3.hs.compression;
- sid->u.ssl3.policy = ss->ssl3.policy;
-#ifdef NSS_ENABLE_ECC
- sid->u.ssl3.negotiatedECCurves = ss->ssl3.hs.negotiatedECCurves;
-#endif
- sid->u.ssl3.exchKeyType = effectiveExchKeyType;
- sid->version = ss->version;
- sid->authAlgorithm = ss->sec.authAlgorithm;
- sid->authKeyBits = ss->sec.authKeyBits;
- sid->keaType = ss->sec.keaType;
- sid->keaKeyBits = ss->sec.keaKeyBits;
- sid->lastAccessTime = sid->creationTime = ssl_Time();
- sid->expirationTime = sid->creationTime + ssl3_sid_timeout;
- sid->localCert = CERT_DupCertificate(ss->sec.localCert);
-
- ssl_GetSpecReadLock(ss); /*************************************/
-
- /* Copy the master secret (wrapped or unwrapped) into the sid */
- if (ss->ssl3.crSpec->msItem.len && ss->ssl3.crSpec->msItem.data) {
- sid->u.ssl3.keys.wrapped_master_secret_len =
- ss->ssl3.crSpec->msItem.len;
- memcpy(sid->u.ssl3.keys.wrapped_master_secret,
- ss->ssl3.crSpec->msItem.data, ss->ssl3.crSpec->msItem.len);
- sid->u.ssl3.masterValid = PR_TRUE;
- sid->u.ssl3.keys.msIsWrapped = PR_FALSE;
- rv = SECSuccess;
- } else {
- rv = ssl3_CacheWrappedMasterSecret(ss, ss->sec.ci.sid,
- ss->ssl3.crSpec,
- effectiveExchKeyType);
- sid->u.ssl3.keys.msIsWrapped = PR_TRUE;
- }
- ssl_ReleaseSpecReadLock(ss); /*************************************/
-
- /* If the wrap failed, we don't cache the sid.
- * The connection continues normally however.
- */
- ss->ssl3.hs.cacheSID = rv == SECSuccess;
- }
-
- if (ss->ssl3.hs.authCertificatePending) {
- if (ss->ssl3.hs.restartTarget) {
- PR_NOT_REACHED("ssl3_HandleFinished: unexpected restartTarget");
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- ss->ssl3.hs.restartTarget = ssl3_FinishHandshake;
- return SECWouldBlock;
- }
-
- rv = ssl3_FinishHandshake(ss);
- return rv;
-}
-
-SECStatus
-ssl3_FinishHandshake(sslSocket * ss)
-{
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->ssl3.hs.restartTarget == NULL );
-
- /* The first handshake is now completed. */
- ss->handshake = NULL;
- ss->firstHsDone = PR_TRUE;
-
- if (ss->ssl3.hs.cacheSID) {
- (*ss->sec.cache)(ss->sec.ci.sid);
- ss->ssl3.hs.cacheSID = PR_FALSE;
- }
-
- ss->ssl3.hs.ws = idle_handshake;
-
- /* Do the handshake callback for sslv3 here, if we cannot false start. */
- if (ss->handshakeCallback != NULL && !ssl3_CanFalseStart(ss)) {
- (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
- }
-
- return SECSuccess;
-}
-
-/* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3
- * hanshake message.
- * Caller must hold Handshake and RecvBuf locks.
- */
-SECStatus
-ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- SECStatus rv = SECSuccess;
- SSL3HandshakeType type = ss->ssl3.hs.msg_type;
- SSL3Hashes hashes; /* computed hashes are put here. */
- PRUint8 hdr[4];
- PRUint8 dtlsData[8];
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- /*
- * We have to compute the hashes before we update them with the
- * current message.
- */
- ssl_GetSpecReadLock(ss); /************************************/
- if((type == finished) || (type == certificate_verify)) {
- SSL3Sender sender = (SSL3Sender)0;
- ssl3CipherSpec *rSpec = ss->ssl3.prSpec;
-
- if (type == finished) {
- sender = ss->sec.isServer ? sender_client : sender_server;
- rSpec = ss->ssl3.crSpec;
- }
- rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender);
- }
- ssl_ReleaseSpecReadLock(ss); /************************************/
- if (rv != SECSuccess) {
- return rv; /* error code was set by ssl3_ComputeHandshakeHashes*/
- }
- SSL_TRC(30,("%d: SSL3[%d]: handle handshake message: %s", SSL_GETPID(),
- ss->fd, ssl3_DecodeHandshakeType(ss->ssl3.hs.msg_type)));
- PRINT_BUF(60, (ss, "MD5 handshake hash:",
- (unsigned char*)ss->ssl3.hs.md5_cx, MD5_LENGTH));
- PRINT_BUF(95, (ss, "SHA handshake hash:",
- (unsigned char*)ss->ssl3.hs.sha_cx, SHA1_LENGTH));
-
- hdr[0] = (PRUint8)ss->ssl3.hs.msg_type;
- hdr[1] = (PRUint8)(length >> 16);
- hdr[2] = (PRUint8)(length >> 8);
- hdr[3] = (PRUint8)(length );
-
- /* Start new handshake hashes when we start a new handshake */
- if (ss->ssl3.hs.msg_type == client_hello) {
- SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
- SSL_GETPID(), ss->fd ));
- rv = ssl3_RestartHandshakeHashes(ss);
- if (rv != SECSuccess) {
- return rv;
- }
- }
- /* We should not include hello_request and hello_verify_request messages
- * in the handshake hashes */
- if ((ss->ssl3.hs.msg_type != hello_request) &&
- (ss->ssl3.hs.msg_type != hello_verify_request)) {
- rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) hdr, 4);
- if (rv != SECSuccess) return rv; /* err code already set. */
-
- /* Extra data to simulate a complete DTLS handshake fragment */
- if (IS_DTLS(ss)) {
- /* Sequence number */
- dtlsData[0] = MSB(ss->ssl3.hs.recvMessageSeq);
- dtlsData[1] = LSB(ss->ssl3.hs.recvMessageSeq);
-
- /* Fragment offset */
- dtlsData[2] = 0;
- dtlsData[3] = 0;
- dtlsData[4] = 0;
-
- /* Fragment length */
- dtlsData[5] = (PRUint8)(length >> 16);
- dtlsData[6] = (PRUint8)(length >> 8);
- dtlsData[7] = (PRUint8)(length );
-
- rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char*) dtlsData,
- sizeof(dtlsData));
- if (rv != SECSuccess) return rv; /* err code already set. */
- }
-
- /* The message body */
- rv = ssl3_UpdateHandshakeHashes(ss, b, length);
- if (rv != SECSuccess) return rv; /* err code already set. */
- }
-
- PORT_SetError(0); /* each message starts with no error. */
-
- /* The CertificateStatus message is optional. We process the message if we
- * get one when it is allowed, but otherwise we just carry on.
- */
- if (ss->ssl3.hs.ws == wait_certificate_status) {
- /* We must process any CertificateStatus message before we call
- * ssl3_AuthCertificate, as ssl3_AuthCertificate needs any stapled OCSP
- * response we get.
- */
- if (ss->ssl3.hs.msg_type == certificate_status) {
- rv = ssl3_HandleCertificateStatus(ss, b, length);
- if (rv != SECSuccess)
- return rv;
- }
-
- /* Regardless of whether we got a CertificateStatus message, we must
- * authenticate the cert before we handle any more handshake messages.
- */
- rv = ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
- } else switch (ss->ssl3.hs.msg_type) {
- case hello_request:
- if (length != 0) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST);
- return SECFailure;
- }
- if (ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST);
- return SECFailure;
- }
- rv = ssl3_HandleHelloRequest(ss);
- break;
- case client_hello:
- if (!ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO);
- return SECFailure;
- }
- rv = ssl3_HandleClientHello(ss, b, length);
- break;
- case server_hello:
- if (ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO);
- return SECFailure;
- }
- rv = ssl3_HandleServerHello(ss, b, length);
- break;
- case hello_verify_request:
- if (!IS_DTLS(ss) || ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST);
- return SECFailure;
- }
- rv = dtls_HandleHelloVerifyRequest(ss, b, length);
- break;
- case certificate:
- rv = ssl3_HandleCertificate(ss, b, length);
- break;
- case certificate_status:
- /* The good case is handled above */
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS);
- rv = SECFailure;
- break;
- case server_key_exchange:
- if (ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH);
- return SECFailure;
- }
- rv = ssl3_HandleServerKeyExchange(ss, b, length);
- break;
- case certificate_request:
- if (ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST);
- return SECFailure;
- }
- rv = ssl3_HandleCertificateRequest(ss, b, length);
- break;
- case server_hello_done:
- if (length != 0) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_DONE);
- return SECFailure;
- }
- if (ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE);
- return SECFailure;
- }
- rv = ssl3_HandleServerHelloDone(ss);
- break;
- case certificate_verify:
- if (!ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY);
- return SECFailure;
- }
- rv = ssl3_HandleCertificateVerify(ss, b, length, &hashes);
- break;
- case client_key_exchange:
- if (!ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH);
- return SECFailure;
- }
- rv = ssl3_HandleClientKeyExchange(ss, b, length);
- break;
- case new_session_ticket:
- if (ss->sec.isServer) {
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET);
- return SECFailure;
- }
- rv = ssl3_HandleNewSessionTicket(ss, b, length);
- break;
- case finished:
- rv = ssl3_HandleFinished(ss, b, length, &hashes);
- break;
- default:
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNKNOWN_HANDSHAKE);
- rv = SECFailure;
- }
-
- if (IS_DTLS(ss) && (rv == SECSuccess)) {
- /* Increment the expected sequence number */
- ss->ssl3.hs.recvMessageSeq++;
- }
-
- return rv;
-}
-
-/* Called only from ssl3_HandleRecord, for each (deciphered) ssl3 record.
- * origBuf is the decrypted ssl record content.
- * Caller must hold the handshake and RecvBuf locks.
- */
-static SECStatus
-ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
-{
- /*
- * There may be a partial handshake message already in the handshake
- * state. The incoming buffer may contain another portion, or a
- * complete message or several messages followed by another portion.
- *
- * Each message is made contiguous before being passed to the actual
- * message parser.
- */
- sslBuffer *buf = &ss->ssl3.hs.msgState; /* do not lose the original buffer pointer */
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (buf->buf == NULL) {
- *buf = *origBuf;
- }
- while (buf->len > 0) {
- if (ss->ssl3.hs.header_bytes < 4) {
- uint8 t;
- t = *(buf->buf++);
- buf->len--;
- if (ss->ssl3.hs.header_bytes++ == 0)
- ss->ssl3.hs.msg_type = (SSL3HandshakeType)t;
- else
- ss->ssl3.hs.msg_len = (ss->ssl3.hs.msg_len << 8) + t;
- if (ss->ssl3.hs.header_bytes < 4)
- continue;
-
-#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
- if (ss->ssl3.hs.msg_len > MAX_HANDSHAKE_MSG_LEN) {
- (void)ssl3_DecodeError(ss);
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- return SECFailure;
- }
-#undef MAX_HANDSHAKE_MSG_LEN
-
- /* If msg_len is zero, be sure we fall through,
- ** even if buf->len is zero.
- */
- if (ss->ssl3.hs.msg_len > 0)
- continue;
- }
-
- /*
- * Header has been gathered and there is at least one byte of new
- * data available for this message. If it can be done right out
- * of the original buffer, then use it from there.
- */
- if (ss->ssl3.hs.msg_body.len == 0 && buf->len >= ss->ssl3.hs.msg_len) {
- /* handle it from input buffer */
- rv = ssl3_HandleHandshakeMessage(ss, buf->buf, ss->ssl3.hs.msg_len);
- if (rv == SECFailure) {
- /* This test wants to fall through on either
- * SECSuccess or SECWouldBlock.
- * ssl3_HandleHandshakeMessage MUST set the error code.
- */
- return rv;
- }
- buf->buf += ss->ssl3.hs.msg_len;
- buf->len -= ss->ssl3.hs.msg_len;
- ss->ssl3.hs.msg_len = 0;
- ss->ssl3.hs.header_bytes = 0;
- if (rv != SECSuccess) { /* return if SECWouldBlock. */
- return rv;
- }
- } else {
- /* must be copied to msg_body and dealt with from there */
- unsigned int bytes;
-
- PORT_Assert(ss->ssl3.hs.msg_body.len < ss->ssl3.hs.msg_len);
- bytes = PR_MIN(buf->len, ss->ssl3.hs.msg_len - ss->ssl3.hs.msg_body.len);
-
- /* Grow the buffer if needed */
- rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, ss->ssl3.hs.msg_len);
- if (rv != SECSuccess) {
- /* sslBuffer_Grow has set a memory error code. */
- return SECFailure;
- }
-
- PORT_Memcpy(ss->ssl3.hs.msg_body.buf + ss->ssl3.hs.msg_body.len,
- buf->buf, bytes);
- ss->ssl3.hs.msg_body.len += bytes;
- buf->buf += bytes;
- buf->len -= bytes;
-
- PORT_Assert(ss->ssl3.hs.msg_body.len <= ss->ssl3.hs.msg_len);
-
- /* if we have a whole message, do it */
- if (ss->ssl3.hs.msg_body.len == ss->ssl3.hs.msg_len) {
- rv = ssl3_HandleHandshakeMessage(
- ss, ss->ssl3.hs.msg_body.buf, ss->ssl3.hs.msg_len);
- if (rv == SECFailure) {
- /* This test wants to fall through on either
- * SECSuccess or SECWouldBlock.
- * ssl3_HandleHandshakeMessage MUST set error code.
- */
- return rv;
- }
- ss->ssl3.hs.msg_body.len = 0;
- ss->ssl3.hs.msg_len = 0;
- ss->ssl3.hs.header_bytes = 0;
- if (rv != SECSuccess) { /* return if SECWouldBlock. */
- return rv;
- }
- } else {
- PORT_Assert(buf->len == 0);
- break;
- }
- }
- } /* end loop */
-
- origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
- buf->buf = NULL; /* not a leak. */
- return SECSuccess;
-}
-
-/* These macros return the given value with the MSB copied to all the other
- * bits. They use the fact that arithmetic shift shifts-in the sign bit.
- * However, this is not ensured by the C standard so you may need to replace
- * them with something else for odd compilers. */
-#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
-#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
-
-/* SECStatusToMask returns, in constant time, a mask value of all ones if
- * rv == SECSuccess. Otherwise it returns zero. */
-static unsigned int
-SECStatusToMask(SECStatus rv)
-{
- unsigned int good;
- /* rv ^ SECSuccess is zero iff rv == SECSuccess. Subtracting one results
- * in the MSB being set to one iff it was zero before. */
- good = rv ^ SECSuccess;
- good--;
- return DUPLICATE_MSB_TO_ALL(good);
-}
-
-/* ssl_ConstantTimeGE returns 0xff if a>=b and 0x00 otherwise. */
-static unsigned char
-ssl_ConstantTimeGE(unsigned int a, unsigned int b)
-{
- a -= b;
- return DUPLICATE_MSB_TO_ALL(~a);
-}
-
-/* ssl_ConstantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
-static unsigned char
-ssl_ConstantTimeEQ8(unsigned char a, unsigned char b)
-{
- unsigned int c = a ^ b;
- c--;
- return DUPLICATE_MSB_TO_ALL_8(c);
-}
-
-static SECStatus
-ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext,
- unsigned int blockSize,
- unsigned int macSize)
-{
- unsigned int paddingLength, good, t;
- const unsigned int overhead = 1 /* padding length byte */ + macSize;
-
- /* These lengths are all public so we can test them in non-constant
- * time. */
- if (overhead > plaintext->len) {
- return SECFailure;
- }
-
- paddingLength = plaintext->buf[plaintext->len-1];
- /* SSLv3 padding bytes are random and cannot be checked. */
- t = plaintext->len;
- t -= paddingLength+overhead;
- /* If len >= padding_length+overhead then the MSB of t is zero. */
- good = DUPLICATE_MSB_TO_ALL(~t);
- /* SSLv3 requires that the padding is minimal. */
- t = blockSize - (paddingLength+1);
- good &= DUPLICATE_MSB_TO_ALL(~t);
- plaintext->len -= good & (paddingLength+1);
- return (good & SECSuccess) | (~good & SECFailure);
-}
-
-static SECStatus
-ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
-{
- unsigned int paddingLength, good, t, toCheck, i;
- const unsigned int overhead = 1 /* padding length byte */ + macSize;
-
- /* These lengths are all public so we can test them in non-constant
- * time. */
- if (overhead > plaintext->len) {
- return SECFailure;
- }
-
- paddingLength = plaintext->buf[plaintext->len-1];
- t = plaintext->len;
- t -= paddingLength+overhead;
- /* If len >= paddingLength+overhead then the MSB of t is zero. */
- good = DUPLICATE_MSB_TO_ALL(~t);
-
- /* The padding consists of a length byte at the end of the record and then
- * that many bytes of padding, all with the same value as the length byte.
- * Thus, with the length byte included, there are paddingLength+1 bytes of
- * padding.
- *
- * We can't check just |paddingLength+1| bytes because that leaks
- * decrypted information. Therefore we always have to check the maximum
- * amount of padding possible. (Again, the length of the record is
- * public information so we can use it.) */
- toCheck = 255; /* maximum amount of padding. */
- if (toCheck > plaintext->len-1) {
- toCheck = plaintext->len-1;
- }
-
- for (i = 0; i < toCheck; i++) {
- unsigned int t = paddingLength - i;
- /* If i <= paddingLength then the MSB of t is zero and mask is
- * 0xff. Otherwise, mask is 0. */
- unsigned char mask = DUPLICATE_MSB_TO_ALL(~t);
- unsigned char b = plaintext->buf[plaintext->len-1-i];
- /* The final |paddingLength+1| bytes should all have the value
- * |paddingLength|. Therefore the XOR should be zero. */
- good &= ~(mask&(paddingLength ^ b));
- }
-
- /* If any of the final |paddingLength+1| bytes had the wrong value,
- * one or more of the lower eight bits of |good| will be cleared. We
- * AND the bottom 8 bits together and duplicate the result to all the
- * bits. */
- good &= good >> 4;
- good &= good >> 2;
- good &= good >> 1;
- good <<= sizeof(good)*8-1;
- good = DUPLICATE_MSB_TO_ALL(good);
-
- plaintext->len -= good & (paddingLength+1);
- return (good & SECSuccess) | (~good & SECFailure);
-}
-
-/* On entry:
- * originalLength >= macSize
- * macSize <= MAX_MAC_LENGTH
- * plaintext->len >= macSize
- */
-static void
-ssl_CBCExtractMAC(sslBuffer *plaintext,
- unsigned int originalLength,
- SSL3Opaque* out,
- unsigned int macSize)
-{
- unsigned char rotatedMac[MAX_MAC_LENGTH];
- /* macEnd is the index of |plaintext->buf| just after the end of the
- * MAC. */
- unsigned macEnd = plaintext->len;
- unsigned macStart = macEnd - macSize;
- /* scanStart contains the number of bytes that we can ignore because
- * the MAC's position can only vary by 255 bytes. */
- unsigned scanStart = 0;
- unsigned i, j, divSpoiler;
- unsigned char rotateOffset;
-
- if (originalLength > macSize + 255 + 1)
- scanStart = originalLength - (macSize + 255 + 1);
-
- /* divSpoiler contains a multiple of macSize that is used to cause the
- * modulo operation to be constant time. Without this, the time varies
- * based on the amount of padding when running on Intel chips at least.
- *
- * The aim of right-shifting macSize is so that the compiler doesn't
- * figure out that it can remove divSpoiler as that would require it
- * to prove that macSize is always even, which I hope is beyond it. */
- divSpoiler = macSize >> 1;
- divSpoiler <<= (sizeof(divSpoiler)-1)*8;
- rotateOffset = (divSpoiler + macStart - scanStart) % macSize;
-
- memset(rotatedMac, 0, macSize);
- for (i = scanStart; i < originalLength;) {
- for (j = 0; j < macSize && i < originalLength; i++, j++) {
- unsigned char macStarted = ssl_ConstantTimeGE(i, macStart);
- unsigned char macEnded = ssl_ConstantTimeGE(i, macEnd);
- unsigned char b = 0;
- b = plaintext->buf[i];
- rotatedMac[j] |= b & macStarted & ~macEnded;
- }
- }
-
- /* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line
- * we could line-align |rotatedMac| and rotate in place. */
- memset(out, 0, macSize);
- for (i = 0; i < macSize; i++) {
- unsigned char offset =
- (divSpoiler + macSize - rotateOffset + i) % macSize;
- for (j = 0; j < macSize; j++) {
- out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, offset);
- }
- }
-}
-
-/* if cText is non-null, then decipher, check MAC, and decompress the
- * SSL record from cText->buf (typically gs->inbuf)
- * into databuf (typically gs->buf), and any previous contents of databuf
- * is lost. Then handle databuf according to its SSL record type,
- * unless it's an application record.
- *
- * If cText is NULL, then the ciphertext has previously been deciphered and
- * checked, and is already sitting in databuf. It is processed as an SSL
- * Handshake message.
- *
- * DOES NOT process the decrypted/decompressed application data.
- * On return, databuf contains the decrypted/decompressed record.
- *
- * Called from ssl3_GatherCompleteHandshake
- * ssl3_RestartHandshakeAfterCertReq
- *
- * Caller must hold the RecvBufLock.
- *
- * This function aquires and releases the SSL3Handshake Lock, holding the
- * lock around any calls to functions that handle records other than
- * Application Data records.
- */
-SECStatus
-ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
-{
- const ssl3BulkCipherDef *cipher_def;
- ssl3CipherSpec * crSpec;
- SECStatus rv;
- unsigned int hashBytes = MAX_MAC_LENGTH + 1;
- PRBool isTLS;
- SSL3ContentType rType;
- SSL3Opaque hash[MAX_MAC_LENGTH];
- SSL3Opaque givenHashBuf[MAX_MAC_LENGTH];
- SSL3Opaque *givenHash;
- sslBuffer *plaintext;
- sslBuffer temp_buf;
- PRUint64 dtls_seq_num;
- unsigned int ivLen = 0;
- unsigned int originalLen = 0;
- unsigned int good;
- unsigned int minLength;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
-
- if (!ss->ssl3.initialized) {
- ssl_GetSSL3HandshakeLock(ss);
- rv = ssl3_InitState(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
- if (rv != SECSuccess) {
- return rv; /* ssl3_InitState has set the error code. */
- }
- }
-
- /* check for Token Presence */
- if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
- PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
- return SECFailure;
- }
-
- /* cText is NULL when we're called from ssl3_RestartHandshakeAfterXXX().
- * This implies that databuf holds a previously deciphered SSL Handshake
- * message.
- */
- if (cText == NULL) {
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, resuming handshake",
- SSL_GETPID(), ss->fd));
- rType = content_handshake;
- goto process_it;
- }
-
- ssl_GetSpecReadLock(ss); /******************************************/
-
- crSpec = ss->ssl3.crSpec;
- cipher_def = crSpec->cipher_def;
-
- /*
- * DTLS relevance checks:
- * Note that this code currently ignores all out-of-epoch packets,
- * which means we lose some in the case of rehandshake +
- * loss/reordering. Since DTLS is explicitly unreliable, this
- * seems like a good tradeoff for implementation effort and is
- * consistent with the guidance of RFC 6347 Sections 4.1 and 4.2.4.1
- */
- if (IS_DTLS(ss)) {
- DTLSEpoch epoch = (cText->seq_num.high >> 16) & 0xffff;
-
- if (crSpec->epoch != epoch) {
- ssl_ReleaseSpecReadLock(ss);
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, received packet "
- "from irrelevant epoch %d", SSL_GETPID(), ss->fd, epoch));
- /* Silently drop the packet */
- databuf->len = 0; /* Needed to ensure data not left around */
- return SECSuccess;
- }
-
- dtls_seq_num = (((PRUint64)(cText->seq_num.high & 0xffff)) << 32) |
- ((PRUint64)cText->seq_num.low);
-
- if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) {
- ssl_ReleaseSpecReadLock(ss);
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting "
- "potentially replayed packet", SSL_GETPID(), ss->fd));
- /* Silently drop the packet */
- databuf->len = 0; /* Needed to ensure data not left around */
- return SECSuccess;
- }
- }
-
- good = (unsigned)-1;
- minLength = crSpec->mac_size;
- if (cipher_def->type == type_block) {
- /* CBC records have a padding length byte at the end. */
- minLength++;
- if (crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
- /* With >= TLS 1.1, CBC records have an explicit IV. */
- minLength += cipher_def->iv_size;
- }
- }
-
- /* We can perform this test in variable time because the record's total
- * length and the ciphersuite are both public knowledge. */
- if (cText->buf->len < minLength) {
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, record too small.",
- SSL_GETPID(), ss->fd));
- /* must not hold spec lock when calling SSL3_SendAlert. */
- ssl_ReleaseSpecReadLock(ss);
- SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
- /* always log mac error, in case attacker can read server logs. */
- PORT_SetError(SSL_ERROR_BAD_MAC_READ);
- return SECFailure;
- }
-
- if (cipher_def->type == type_block &&
- crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
- /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states
- * "The receiver decrypts the entire GenericBlockCipher structure and
- * then discards the first cipher block corresponding to the IV
- * component." Instead, we decrypt the first cipher block and then
- * discard it before decrypting the rest.
- */
- SSL3Opaque iv[MAX_IV_LENGTH];
- int decoded;
-
- ivLen = cipher_def->iv_size;
- if (ivLen < 8 || ivLen > sizeof(iv)) {
- ssl_ReleaseSpecReadLock(ss);
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- PRINT_BUF(80, (ss, "IV (ciphertext):", cText->buf->buf, ivLen));
-
- /* The decryption result is garbage, but since we just throw away
- * the block it doesn't matter. The decryption of the next block
- * depends only on the ciphertext of the IV block.
- */
- rv = crSpec->decode(crSpec->decodeContext, iv, &decoded,
- sizeof(iv), cText->buf->buf, ivLen);
-
- good &= SECStatusToMask(rv);
- }
-
- /* If we will be decompressing the buffer we need to decrypt somewhere
- * other than into databuf */
- if (crSpec->decompressor) {
- temp_buf.buf = NULL;
- temp_buf.space = 0;
- plaintext = &temp_buf;
- } else {
- plaintext = databuf;
- }
-
- plaintext->len = 0; /* filled in by decode call below. */
- if (plaintext->space < MAX_FRAGMENT_LENGTH) {
- rv = sslBuffer_Grow(plaintext, MAX_FRAGMENT_LENGTH + 2048);
- if (rv != SECSuccess) {
- ssl_ReleaseSpecReadLock(ss);
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",
- SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048));
- /* sslBuffer_Grow has set a memory error code. */
- /* Perhaps we should send an alert. (but we have no memory!) */
- return SECFailure;
- }
- }
-
- PRINT_BUF(80, (ss, "ciphertext:", cText->buf->buf + ivLen,
- cText->buf->len - ivLen));
-
- isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- if (isTLS && cText->buf->len - ivLen > (MAX_FRAGMENT_LENGTH + 2048)) {
- ssl_ReleaseSpecReadLock(ss);
- SSL3_SendAlert(ss, alert_fatal, record_overflow);
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- return SECFailure;
- }
-
- /* decrypt from cText buf to plaintext. */
- rv = crSpec->decode(
- crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len,
- plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen);
- good &= SECStatusToMask(rv);
-
- PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len));
-
- originalLen = plaintext->len;
-
- /* If it's a block cipher, check and strip the padding. */
- if (cipher_def->type == type_block) {
- const unsigned int blockSize = cipher_def->iv_size;
- const unsigned int macSize = crSpec->mac_size;
-
- if (crSpec->version <= SSL_LIBRARY_VERSION_3_0) {
- good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding(
- plaintext, blockSize, macSize));
- } else {
- good &= SECStatusToMask(ssl_RemoveTLSCBCPadding(
- plaintext, macSize));
- }
- }
-
- /* compute the MAC */
- rType = cText->type;
- if (cipher_def->type == type_block) {
- rv = ssl3_ComputeRecordMACConstantTime(
- crSpec, (PRBool)(!ss->sec.isServer),
- IS_DTLS(ss), rType, cText->version,
- IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
- plaintext->buf, plaintext->len, originalLen,
- hash, &hashBytes);
-
- ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf,
- crSpec->mac_size);
- givenHash = givenHashBuf;
-
- /* plaintext->len will always have enough space to remove the MAC
- * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust
- * plaintext->len if the result has enough space for the MAC and we
- * tested the unadjusted size against minLength, above. */
- plaintext->len -= crSpec->mac_size;
- } else {
- /* This is safe because we checked the minLength above. */
- plaintext->len -= crSpec->mac_size;
-
- rv = ssl3_ComputeRecordMAC(
- crSpec, (PRBool)(!ss->sec.isServer),
- IS_DTLS(ss), rType, cText->version,
- IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
- plaintext->buf, plaintext->len,
- hash, &hashBytes);
-
- /* We can read the MAC directly from the record because its location is
- * public when a stream cipher is used. */
- givenHash = plaintext->buf + plaintext->len;
- }
-
- good &= SECStatusToMask(rv);
-
- if (hashBytes != (unsigned)crSpec->mac_size ||
- NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) {
- /* We're allowed to leak whether or not the MAC check was correct */
- good = 0;
- }
-
- if (good == 0) {
- /* must not hold spec lock when calling SSL3_SendAlert. */
- ssl_ReleaseSpecReadLock(ss);
-
- SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd));
-
- if (!IS_DTLS(ss)) {
- SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
- /* always log mac error, in case attacker can read server logs. */
- PORT_SetError(SSL_ERROR_BAD_MAC_READ);
- return SECFailure;
- } else {
- /* Silently drop the packet */
- databuf->len = 0; /* Needed to ensure data not left around */
- return SECSuccess;
- }
- }
-
- if (!IS_DTLS(ss)) {
- ssl3_BumpSequenceNumber(&crSpec->read_seq_num);
- } else {
- dtls_RecordSetRecvd(&crSpec->recvdRecords, dtls_seq_num);
- }
-
- ssl_ReleaseSpecReadLock(ss); /*****************************************/
-
- /*
- * The decrypted data is now in plaintext.
- */
-
- /* possibly decompress the record. If we aren't using compression then
- * plaintext == databuf and so the uncompressed data is already in
- * databuf. */
- if (crSpec->decompressor) {
- if (databuf->space < plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION) {
- rv = sslBuffer_Grow(
- databuf, plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION);
- if (rv != SECSuccess) {
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",
- SSL_GETPID(), ss->fd,
- plaintext->len + SSL3_COMPRESSION_MAX_EXPANSION));
- /* sslBuffer_Grow has set a memory error code. */
- /* Perhaps we should send an alert. (but we have no memory!) */
- PORT_Free(plaintext->buf);
- return SECFailure;
- }
- }
-
- rv = crSpec->decompressor(crSpec->decompressContext,
- databuf->buf,
- (int*) &databuf->len,
- databuf->space,
- plaintext->buf,
- plaintext->len);
-
- if (rv != SECSuccess) {
- int err = ssl_MapLowLevelError(SSL_ERROR_DECOMPRESSION_FAILURE);
- SSL3_SendAlert(ss, alert_fatal,
- isTLS ? decompression_failure : bad_record_mac);
-
- /* There appears to be a bug with (at least) Apache + OpenSSL where
- * resumed SSLv3 connections don't actually use compression. See
- * comments 93-95 of
- * https://bugzilla.mozilla.org/show_bug.cgi?id=275744
- *
- * So, if we get a decompression error, and the record appears to
- * be already uncompressed, then we return a more specific error
- * code to hopefully save somebody some debugging time in the
- * future.
- */
- if (plaintext->len >= 4) {
- unsigned int len = ((unsigned int) plaintext->buf[1] << 16) |
- ((unsigned int) plaintext->buf[2] << 8) |
- (unsigned int) plaintext->buf[3];
- if (len == plaintext->len - 4) {
- /* This appears to be uncompressed already */
- err = SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD;
- }
- }
-
- PORT_Free(plaintext->buf);
- PORT_SetError(err);
- return SECFailure;
- }
-
- PORT_Free(plaintext->buf);
- }
-
- /*
- ** Having completed the decompression, check the length again.
- */
- if (isTLS && databuf->len > (MAX_FRAGMENT_LENGTH + 1024)) {
- SSL3_SendAlert(ss, alert_fatal, record_overflow);
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- return SECFailure;
- }
-
- /* Application data records are processed by the caller of this
- ** function, not by this function.
- */
- if (rType == content_application_data) {
- if (ss->firstHsDone)
- return SECSuccess;
- (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- PORT_SetError(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA);
- return SECFailure;
- }
-
- /* It's a record that must be handled by ssl itself, not the application.
- */
-process_it:
- /* XXX Get the xmit lock here. Odds are very high that we'll be xmiting
- * data ang getting the xmit lock here prevents deadlocks.
- */
- ssl_GetSSL3HandshakeLock(ss);
-
- /* All the functions called in this switch MUST set error code if
- ** they return SECFailure or SECWouldBlock.
- */
- switch (rType) {
- case content_change_cipher_spec:
- rv = ssl3_HandleChangeCipherSpecs(ss, databuf);
- break;
- case content_alert:
- rv = ssl3_HandleAlert(ss, databuf);
- break;
- case content_handshake:
- if (!IS_DTLS(ss)) {
- rv = ssl3_HandleHandshake(ss, databuf);
- } else {
- rv = dtls_HandleHandshake(ss, databuf);
- }
- break;
- /*
- case content_application_data is handled before this switch
- */
- default:
- SSL_DBG(("%d: SSL3[%d]: bogus content type=%d",
- SSL_GETPID(), ss->fd, cText->type));
- /* XXX Send an alert ??? */
- PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);
- rv = SECFailure;
- break;
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- return rv;
-
-}
-
-/*
- * Initialization functions
- */
-
-/* Called from ssl3_InitState, immediately below. */
-/* Caller must hold the SpecWriteLock. */
-static void
-ssl3_InitCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
-{
- spec->cipher_def = &bulk_cipher_defs[cipher_null];
- PORT_Assert(spec->cipher_def->cipher == cipher_null);
- spec->mac_def = &mac_defs[mac_null];
- PORT_Assert(spec->mac_def->mac == mac_null);
- spec->encode = Null_Cipher;
- spec->decode = Null_Cipher;
- spec->destroy = NULL;
- spec->compressor = NULL;
- spec->decompressor = NULL;
- spec->destroyCompressContext = NULL;
- spec->destroyDecompressContext = NULL;
- spec->mac_size = 0;
- spec->master_secret = NULL;
- spec->bypassCiphers = PR_FALSE;
-
- spec->msItem.data = NULL;
- spec->msItem.len = 0;
-
- spec->client.write_key = NULL;
- spec->client.write_mac_key = NULL;
- spec->client.write_mac_context = NULL;
-
- spec->server.write_key = NULL;
- spec->server.write_mac_key = NULL;
- spec->server.write_mac_context = NULL;
-
- spec->write_seq_num.high = 0;
- spec->write_seq_num.low = 0;
-
- spec->read_seq_num.high = 0;
- spec->read_seq_num.low = 0;
-
- spec->epoch = 0;
- dtls_InitRecvdRecords(&spec->recvdRecords);
-
- spec->version = ss->vrange.max;
-}
-
-/* Called from: ssl3_SendRecord
-** ssl3_StartHandshakeHash() <- ssl2_BeginClientHandshake()
-** ssl3_SendClientHello()
-** ssl3_HandleServerHello()
-** ssl3_HandleClientHello()
-** ssl3_HandleV2ClientHello()
-** ssl3_HandleRecord()
-**
-** This function should perhaps acquire and release the SpecWriteLock.
-**
-**
-*/
-static SECStatus
-ssl3_InitState(sslSocket *ss)
-{
- SECStatus rv;
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- if (ss->ssl3.initialized)
- return SECSuccess; /* Function should be idempotent */
-
- ss->ssl3.policy = SSL_ALLOWED;
-
- ssl_GetSpecWriteLock(ss);
- ss->ssl3.crSpec = ss->ssl3.cwSpec = &ss->ssl3.specs[0];
- ss->ssl3.prSpec = ss->ssl3.pwSpec = &ss->ssl3.specs[1];
- ss->ssl3.hs.sendingSCSV = PR_FALSE;
- ssl3_InitCipherSpec(ss, ss->ssl3.crSpec);
- ssl3_InitCipherSpec(ss, ss->ssl3.prSpec);
-
- ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello;
-#ifdef NSS_ENABLE_ECC
- ss->ssl3.hs.negotiatedECCurves = SSL3_SUPPORTED_CURVES_MASK;
-#endif
- ssl_ReleaseSpecWriteLock(ss);
-
- PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
-
- if (IS_DTLS(ss)) {
- ss->ssl3.hs.sendMessageSeq = 0;
- ss->ssl3.hs.recvMessageSeq = 0;
- ss->ssl3.hs.rtTimeoutMs = INITIAL_DTLS_TIMEOUT_MS;
- ss->ssl3.hs.rtRetries = 0;
- ss->ssl3.hs.recvdHighWater = -1;
- PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
- dtls_SetMTU(ss, 0); /* Set the MTU to the highest plateau */
- }
-
- rv = ssl3_NewHandshakeHashes(ss);
- if (rv == SECSuccess) {
- ss->ssl3.initialized = PR_TRUE;
- }
-
- return rv;
-}
-
-/* Returns a reference counted object that contains a key pair.
- * Or NULL on failure. Initial ref count is 1.
- * Uses the keys in the pair as input.
- */
-ssl3KeyPair *
-ssl3_NewKeyPair( SECKEYPrivateKey * privKey, SECKEYPublicKey * pubKey)
-{
- ssl3KeyPair * pair;
-
- if (!privKey || !pubKey) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return NULL;
- }
- pair = PORT_ZNew(ssl3KeyPair);
- if (!pair)
- return NULL; /* error code is set. */
- pair->refCount = 1;
- pair->privKey = privKey;
- pair->pubKey = pubKey;
- return pair; /* success */
-}
-
-ssl3KeyPair *
-ssl3_GetKeyPairRef(ssl3KeyPair * keyPair)
-{
- PR_ATOMIC_INCREMENT(&keyPair->refCount);
- return keyPair;
-}
-
-void
-ssl3_FreeKeyPair(ssl3KeyPair * keyPair)
-{
- PRInt32 newCount = PR_ATOMIC_DECREMENT(&keyPair->refCount);
- if (!newCount) {
- if (keyPair->privKey)
- SECKEY_DestroyPrivateKey(keyPair->privKey);
- if (keyPair->pubKey)
- SECKEY_DestroyPublicKey( keyPair->pubKey);
- PORT_Free(keyPair);
- }
-}
-
-
-
-/*
- * Creates the public and private RSA keys for SSL Step down.
- * Called from SSL_ConfigSecureServer in sslsecur.c
- */
-SECStatus
-ssl3_CreateRSAStepDownKeys(sslSocket *ss)
-{
- SECStatus rv = SECSuccess;
- SECKEYPrivateKey * privKey; /* RSA step down key */
- SECKEYPublicKey * pubKey; /* RSA step down key */
-
- if (ss->stepDownKeyPair)
- ssl3_FreeKeyPair(ss->stepDownKeyPair);
- ss->stepDownKeyPair = NULL;
-#ifndef HACKED_EXPORT_SERVER
- /* Sigh, should have a get key strength call for private keys */
- if (PK11_GetPrivateModulusLen(ss->serverCerts[kt_rsa].SERVERKEY) >
- EXPORT_RSA_KEY_LENGTH) {
- /* need to ask for the key size in bits */
- privKey = SECKEY_CreateRSAPrivateKey(EXPORT_RSA_KEY_LENGTH * BPB,
- &pubKey, NULL);
- if (!privKey || !pubKey ||
- !(ss->stepDownKeyPair = ssl3_NewKeyPair(privKey, pubKey))) {
- ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- rv = SECFailure;
- }
- }
-#endif
- return rv;
-}
-
-
-/* record the export policy for this cipher suite */
-SECStatus
-ssl3_SetPolicy(ssl3CipherSuite which, int policy)
-{
- ssl3CipherSuiteCfg *suite;
-
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
- if (suite == NULL) {
- return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
- }
- suite->policy = policy;
-
- return SECSuccess;
-}
-
-SECStatus
-ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *oPolicy)
-{
- ssl3CipherSuiteCfg *suite;
- PRInt32 policy;
- SECStatus rv;
-
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
- if (suite) {
- policy = suite->policy;
- rv = SECSuccess;
- } else {
- policy = SSL_NOT_ALLOWED;
- rv = SECFailure; /* err code was set by Lookup. */
- }
- *oPolicy = policy;
- return rv;
-}
-
-/* record the user preference for this suite */
-SECStatus
-ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool enabled)
-{
- ssl3CipherSuiteCfg *suite;
-
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
- if (suite == NULL) {
- return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
- }
- suite->enabled = enabled;
- return SECSuccess;
-}
-
-/* return the user preference for this suite */
-SECStatus
-ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *enabled)
-{
- ssl3CipherSuiteCfg *suite;
- PRBool pref;
- SECStatus rv;
-
- suite = ssl_LookupCipherSuiteCfg(which, cipherSuites);
- if (suite) {
- pref = suite->enabled;
- rv = SECSuccess;
- } else {
- pref = SSL_NOT_ALLOWED;
- rv = SECFailure; /* err code was set by Lookup. */
- }
- *enabled = pref;
- return rv;
-}
-
-SECStatus
-ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool enabled)
-{
- ssl3CipherSuiteCfg *suite;
-
- suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites);
- if (suite == NULL) {
- return SECFailure; /* err code was set by ssl_LookupCipherSuiteCfg */
- }
- suite->enabled = enabled;
- return SECSuccess;
-}
-
-SECStatus
-ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *enabled)
-{
- ssl3CipherSuiteCfg *suite;
- PRBool pref;
- SECStatus rv;
-
- suite = ssl_LookupCipherSuiteCfg(which, ss->cipherSuites);
- if (suite) {
- pref = suite->enabled;
- rv = SECSuccess;
- } else {
- pref = SSL_NOT_ALLOWED;
- rv = SECFailure; /* err code was set by Lookup. */
- }
- *enabled = pref;
- return rv;
-}
-
-/* copy global default policy into socket. */
-void
-ssl3_InitSocketPolicy(sslSocket *ss)
-{
- PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites);
-}
-
-/* ssl3_config_match_init must have already been called by
- * the caller of this function.
- */
-SECStatus
-ssl3_ConstructV2CipherSpecsHack(sslSocket *ss, unsigned char *cs, int *size)
-{
- int i, count = 0;
-
- PORT_Assert(ss != 0);
- if (!ss) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- if (SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- *size = 0;
- return SECSuccess;
- }
- if (cs == NULL) {
- *size = count_cipher_suites(ss, SSL_ALLOWED, PR_TRUE);
- return SECSuccess;
- }
-
- /* ssl3_config_match_init was called by the caller of this function. */
- for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
- ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
- if (config_match(suite, SSL_ALLOWED, PR_TRUE)) {
- if (cs != NULL) {
- *cs++ = 0x00;
- *cs++ = (suite->cipher_suite >> 8) & 0xFF;
- *cs++ = suite->cipher_suite & 0xFF;
- }
- count++;
- }
- }
- *size = count;
- return SECSuccess;
-}
-
-/*
-** If ssl3 socket has completed the first handshake, and is in idle state,
-** then start a new handshake.
-** If flushCache is true, the SID cache will be flushed first, forcing a
-** "Full" handshake (not a session restart handshake), to be done.
-**
-** called from SSL_RedoHandshake(), which already holds the handshake locks.
-*/
-SECStatus
-ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache)
-{
- sslSessionID * sid = ss->sec.ci.sid;
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- if (!ss->firstHsDone ||
- ((ss->version >= SSL_LIBRARY_VERSION_3_0) &&
- ss->ssl3.initialized &&
- (ss->ssl3.hs.ws != idle_handshake))) {
- PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
- return SECFailure;
- }
-
- if (IS_DTLS(ss)) {
- dtls_RehandshakeCleanup(ss);
- }
-
- if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
- PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
- return SECFailure;
- }
- if (sid && flushCache) {
- if (ss->sec.uncache)
- ss->sec.uncache(sid); /* remove it from whichever cache it's in. */
- ssl_FreeSID(sid); /* dec ref count and free if zero. */
- ss->sec.ci.sid = NULL;
- }
-
- ssl_GetXmitBufLock(ss); /**************************************/
-
- /* start off a new handshake. */
- rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss)
- : ssl3_SendClientHello(ss, PR_FALSE);
-
- ssl_ReleaseXmitBufLock(ss); /**************************************/
- return rv;
-}
-
-/* Called from ssl_DestroySocketContents() in sslsock.c */
-void
-ssl3_DestroySSL3Info(sslSocket *ss)
-{
-
- if (ss->ssl3.clientCertificate != NULL)
- CERT_DestroyCertificate(ss->ssl3.clientCertificate);
-
- if (ss->ssl3.clientPrivateKey != NULL)
- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
-
- if (ss->ssl3.peerCertArena != NULL)
- ssl3_CleanupPeerCerts(ss);
-
- if (ss->ssl3.clientCertChain != NULL) {
- CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
- ss->ssl3.clientCertChain = NULL;
- }
-
- /* clean up handshake */
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
- MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE);
- }
-#endif
- if (ss->ssl3.hs.md5) {
- PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE);
- }
- if (ss->ssl3.hs.sha) {
- PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE);
- }
- if (ss->ssl3.hs.messages.buf) {
- PORT_Free(ss->ssl3.hs.messages.buf);
- ss->ssl3.hs.messages.buf = NULL;
- ss->ssl3.hs.messages.len = 0;
- ss->ssl3.hs.messages.space = 0;
- }
-
- /* free the SSL3Buffer (msg_body) */
- PORT_Free(ss->ssl3.hs.msg_body.buf);
-
- /* free up the CipherSpecs */
- ssl3_DestroyCipherSpec(&ss->ssl3.specs[0], PR_TRUE/*freeSrvName*/);
- ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/);
-
- /* Destroy the DTLS data */
- if (IS_DTLS(ss)) {
- dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight);
- if (ss->ssl3.hs.recvdFragments.buf) {
- PORT_Free(ss->ssl3.hs.recvdFragments.buf);
- }
- }
-
- ss->ssl3.initialized = PR_FALSE;
-
- SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
-}
-
-/* End of ssl3con.c */
diff --git a/security/nss/lib/ssl/ssl3ecc.c b/security/nss/lib/ssl/ssl3ecc.c
deleted file mode 100644
index 23b8cbc19..000000000
--- a/security/nss/lib/ssl/ssl3ecc.c
+++ /dev/null
@@ -1,1158 +0,0 @@
-/*
- * SSL3 Protocol
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* ECC code moved here from ssl3con.c */
-/* $Id$ */
-
-#include "nss.h"
-#include "cert.h"
-#include "ssl.h"
-#include "cryptohi.h" /* for DSAU_ stuff */
-#include "keyhi.h"
-#include "secder.h"
-#include "secitem.h"
-
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "sslerr.h"
-#include "prtime.h"
-#include "prinrval.h"
-#include "prerror.h"
-#include "pratom.h"
-#include "prthread.h"
-#include "prinit.h"
-
-#include "pk11func.h"
-#include "secmod.h"
-
-#include <stdio.h>
-
-#ifdef NSS_ENABLE_ECC
-
-#ifndef PK11_SETATTRS
-#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
- (x)->pValue=(v); (x)->ulValueLen = (l);
-#endif
-
-#define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \
- (ss->serverCerts[type].serverKeyPair ? \
- ss->serverCerts[type].serverKeyPair->pubKey : NULL)
-
-#define SSL_IS_CURVE_NEGOTIATED(curvemsk, curveName) \
- ((curveName > ec_noName) && \
- (curveName < ec_pastLastName) && \
- ((1UL << curveName) & curvemsk) != 0)
-
-
-
-static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve);
-
-#define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName))
-
-/* Table containing OID tags for elliptic curves named in the
- * ECC-TLS IETF draft.
- */
-static const SECOidTag ecName2OIDTag[] = {
- 0,
- SEC_OID_SECG_EC_SECT163K1, /* 1 */
- SEC_OID_SECG_EC_SECT163R1, /* 2 */
- SEC_OID_SECG_EC_SECT163R2, /* 3 */
- SEC_OID_SECG_EC_SECT193R1, /* 4 */
- SEC_OID_SECG_EC_SECT193R2, /* 5 */
- SEC_OID_SECG_EC_SECT233K1, /* 6 */
- SEC_OID_SECG_EC_SECT233R1, /* 7 */
- SEC_OID_SECG_EC_SECT239K1, /* 8 */
- SEC_OID_SECG_EC_SECT283K1, /* 9 */
- SEC_OID_SECG_EC_SECT283R1, /* 10 */
- SEC_OID_SECG_EC_SECT409K1, /* 11 */
- SEC_OID_SECG_EC_SECT409R1, /* 12 */
- SEC_OID_SECG_EC_SECT571K1, /* 13 */
- SEC_OID_SECG_EC_SECT571R1, /* 14 */
- SEC_OID_SECG_EC_SECP160K1, /* 15 */
- SEC_OID_SECG_EC_SECP160R1, /* 16 */
- SEC_OID_SECG_EC_SECP160R2, /* 17 */
- SEC_OID_SECG_EC_SECP192K1, /* 18 */
- SEC_OID_SECG_EC_SECP192R1, /* 19 */
- SEC_OID_SECG_EC_SECP224K1, /* 20 */
- SEC_OID_SECG_EC_SECP224R1, /* 21 */
- SEC_OID_SECG_EC_SECP256K1, /* 22 */
- SEC_OID_SECG_EC_SECP256R1, /* 23 */
- SEC_OID_SECG_EC_SECP384R1, /* 24 */
- SEC_OID_SECG_EC_SECP521R1, /* 25 */
-};
-
-static const PRUint16 curve2bits[] = {
- 0, /* ec_noName = 0, */
- 163, /* ec_sect163k1 = 1, */
- 163, /* ec_sect163r1 = 2, */
- 163, /* ec_sect163r2 = 3, */
- 193, /* ec_sect193r1 = 4, */
- 193, /* ec_sect193r2 = 5, */
- 233, /* ec_sect233k1 = 6, */
- 233, /* ec_sect233r1 = 7, */
- 239, /* ec_sect239k1 = 8, */
- 283, /* ec_sect283k1 = 9, */
- 283, /* ec_sect283r1 = 10, */
- 409, /* ec_sect409k1 = 11, */
- 409, /* ec_sect409r1 = 12, */
- 571, /* ec_sect571k1 = 13, */
- 571, /* ec_sect571r1 = 14, */
- 160, /* ec_secp160k1 = 15, */
- 160, /* ec_secp160r1 = 16, */
- 160, /* ec_secp160r2 = 17, */
- 192, /* ec_secp192k1 = 18, */
- 192, /* ec_secp192r1 = 19, */
- 224, /* ec_secp224k1 = 20, */
- 224, /* ec_secp224r1 = 21, */
- 256, /* ec_secp256k1 = 22, */
- 256, /* ec_secp256r1 = 23, */
- 384, /* ec_secp384r1 = 24, */
- 521, /* ec_secp521r1 = 25, */
- 65535 /* ec_pastLastName */
-};
-
-typedef struct Bits2CurveStr {
- PRUint16 bits;
- ECName curve;
-} Bits2Curve;
-
-static const Bits2Curve bits2curve [] = {
- { 192, ec_secp192r1 /* = 19, fast */ },
- { 160, ec_secp160r2 /* = 17, fast */ },
- { 160, ec_secp160k1 /* = 15, */ },
- { 160, ec_secp160r1 /* = 16, */ },
- { 163, ec_sect163k1 /* = 1, */ },
- { 163, ec_sect163r1 /* = 2, */ },
- { 163, ec_sect163r2 /* = 3, */ },
- { 192, ec_secp192k1 /* = 18, */ },
- { 193, ec_sect193r1 /* = 4, */ },
- { 193, ec_sect193r2 /* = 5, */ },
- { 224, ec_secp224r1 /* = 21, fast */ },
- { 224, ec_secp224k1 /* = 20, */ },
- { 233, ec_sect233k1 /* = 6, */ },
- { 233, ec_sect233r1 /* = 7, */ },
- { 239, ec_sect239k1 /* = 8, */ },
- { 256, ec_secp256r1 /* = 23, fast */ },
- { 256, ec_secp256k1 /* = 22, */ },
- { 283, ec_sect283k1 /* = 9, */ },
- { 283, ec_sect283r1 /* = 10, */ },
- { 384, ec_secp384r1 /* = 24, fast */ },
- { 409, ec_sect409k1 /* = 11, */ },
- { 409, ec_sect409r1 /* = 12, */ },
- { 521, ec_secp521r1 /* = 25, fast */ },
- { 571, ec_sect571k1 /* = 13, */ },
- { 571, ec_sect571r1 /* = 14, */ },
- { 65535, ec_noName }
-};
-
-typedef struct ECDHEKeyPairStr {
- ssl3KeyPair * pair;
- int error; /* error code of the call-once function */
- PRCallOnceType once;
-} ECDHEKeyPair;
-
-/* arrays of ECDHE KeyPairs */
-static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName];
-
-SECStatus
-ssl3_ECName2Params(PRArenaPool * arena, ECName curve, SECKEYECParams * params)
-{
- SECOidData *oidData = NULL;
-
- if ((curve <= ec_noName) || (curve >= ec_pastLastName) ||
- ((oidData = SECOID_FindOIDByTag(ecName2OIDTag[curve])) == NULL)) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- return SECFailure;
- }
-
- SECITEM_AllocItem(arena, params, (2 + oidData->oid.len));
- /*
- * params->data needs to contain the ASN encoding of an object ID (OID)
- * representing the named curve. The actual OID is in
- * oidData->oid.data so we simply prepend 0x06 and OID length
- */
- params->data[0] = SEC_ASN1_OBJECT_ID;
- params->data[1] = oidData->oid.len;
- memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
-
- return SECSuccess;
-}
-
-static ECName
-params2ecName(SECKEYECParams * params)
-{
- SECItem oid = { siBuffer, NULL, 0};
- SECOidData *oidData = NULL;
- ECName i;
-
- /*
- * params->data needs to contain the ASN encoding of an object ID (OID)
- * representing a named curve. Here, we strip away everything
- * before the actual OID and use the OID to look up a named curve.
- */
- if (params->data[0] != SEC_ASN1_OBJECT_ID) return ec_noName;
- oid.len = params->len - 2;
- oid.data = params->data + 2;
- if ((oidData = SECOID_FindOID(&oid)) == NULL) return ec_noName;
- for (i = ec_noName + 1; i < ec_pastLastName; i++) {
- if (ecName2OIDTag[i] == oidData->offset)
- return i;
- }
-
- return ec_noName;
-}
-
-/* Caller must set hiLevel error code. */
-static SECStatus
-ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint,
- SSL3Random *client_rand, SSL3Random *server_rand,
- SSL3Hashes *hashes, PRBool bypassPKCS11)
-{
- PRUint8 * hashBuf;
- PRUint8 * pBuf;
- SECStatus rv = SECSuccess;
- unsigned int bufLen;
- /*
- * XXX For now, we only support named curves (the appropriate
- * checks are made before this method is called) so ec_params
- * takes up only two bytes. ECPoint needs to fit in 256 bytes
- * (because the spec says the length must fit in one byte)
- */
- PRUint8 buf[2*SSL3_RANDOM_LENGTH + 2 + 1 + 256];
-
- bufLen = 2*SSL3_RANDOM_LENGTH + ec_params.len + 1 + server_ecpoint.len;
- if (bufLen <= sizeof buf) {
- hashBuf = buf;
- } else {
- hashBuf = PORT_Alloc(bufLen);
- if (!hashBuf) {
- return SECFailure;
- }
- }
-
- memcpy(hashBuf, client_rand, SSL3_RANDOM_LENGTH);
- pBuf = hashBuf + SSL3_RANDOM_LENGTH;
- memcpy(pBuf, server_rand, SSL3_RANDOM_LENGTH);
- pBuf += SSL3_RANDOM_LENGTH;
- memcpy(pBuf, ec_params.data, ec_params.len);
- pBuf += ec_params.len;
- pBuf[0] = (PRUint8)(server_ecpoint.len);
- pBuf += 1;
- memcpy(pBuf, server_ecpoint.data, server_ecpoint.len);
- pBuf += server_ecpoint.len;
- PORT_Assert((unsigned int)(pBuf - hashBuf) == bufLen);
-
- rv = ssl3_ComputeCommonKeyHash(hashBuf, bufLen, hashes, bypassPKCS11);
-
- PRINT_BUF(95, (NULL, "ECDHkey hash: ", hashBuf, bufLen));
- PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", hashes->md5, MD5_LENGTH));
- PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH));
-
- if (hashBuf != buf)
- PORT_Free(hashBuf);
- return rv;
-}
-
-
-/* Called from ssl3_SendClientKeyExchange(). */
-SECStatus
-ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
-{
- PK11SymKey * pms = NULL;
- SECStatus rv = SECFailure;
- PRBool isTLS;
- CK_MECHANISM_TYPE target;
- SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */
- SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- /* Generate ephemeral EC keypair */
- if (svrPubKey->keyType != ecKey) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- goto loser;
- }
- /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */
- privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams,
- &pubKey, ss->pkcs11PinArg);
- if (!privKey || !pubKey) {
- ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- rv = SECFailure;
- goto loser;
- }
- PRINT_BUF(50, (ss, "ECDH public value:",
- pubKey->u.ec.publicValue.data,
- pubKey->u.ec.publicValue.len));
-
- if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
- else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
-
- /* Determine the PMS */
- pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL,
- CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
- CKD_NULL, NULL, NULL);
-
- if (pms == NULL) {
- SSL3AlertDescription desc = illegal_parameter;
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- SECKEY_DestroyPrivateKey(privKey);
- privKey = NULL;
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms); pms = NULL;
-
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
- pubKey->u.ec.publicValue.len + 1);
- if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss,
- pubKey->u.ec.publicValue.data,
- pubKey->u.ec.publicValue.len, 1);
- SECKEY_DestroyPublicKey(pubKey);
- pubKey = NULL;
-
- if (rv != SECSuccess) {
- goto loser; /* err set by ssl3_AppendHandshake* */
- }
-
- rv = SECSuccess;
-
-loser:
- if(pms) PK11_FreeSymKey(pms);
- if(privKey) SECKEY_DestroyPrivateKey(privKey);
- if(pubKey) SECKEY_DestroyPublicKey(pubKey);
- return rv;
-}
-
-
-/*
-** Called from ssl3_HandleClientKeyExchange()
-*/
-SECStatus
-ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
- PRUint32 length,
- SECKEYPublicKey *srvrPubKey,
- SECKEYPrivateKey *srvrPrivKey)
-{
- PK11SymKey * pms;
- SECStatus rv;
- SECKEYPublicKey clntPubKey;
- CK_MECHANISM_TYPE target;
- PRBool isTLS;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
-
- clntPubKey.keyType = ecKey;
- clntPubKey.u.ec.DEREncodedParams.len =
- srvrPubKey->u.ec.DEREncodedParams.len;
- clntPubKey.u.ec.DEREncodedParams.data =
- srvrPubKey->u.ec.DEREncodedParams.data;
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue,
- 1, &b, &length);
- if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* XXX Who sets the error code?? */
- }
-
- isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;
- else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;
-
- /* Determine the PMS */
- pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL,
- CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0,
- CKD_NULL, NULL, NULL);
-
- if (pms == NULL) {
- /* last gasp. */
- ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
-
- rv = ssl3_InitPendingCipherSpec(ss, pms);
- PK11_FreeSymKey(pms);
- if (rv != SECSuccess) {
- SEND_ALERT
- return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
- }
- return SECSuccess;
-}
-
-ECName
-ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits)
-{
- int i;
-
- for ( i = 0; bits2curve[i].curve != ec_noName; i++) {
- if (bits2curve[i].bits < requiredECCbits)
- continue;
- if (SSL_IS_CURVE_NEGOTIATED(curvemsk, bits2curve[i].curve)) {
- return bits2curve[i].curve;
- }
- }
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return ec_noName;
-}
-
-/* find the "weakest link". Get strength of signature key and of sym key.
- * choose curve for the weakest of those two.
- */
-ECName
-ssl3_GetCurveNameForServerSocket(sslSocket *ss)
-{
- SECKEYPublicKey * svrPublicKey = NULL;
- ECName ec_curve = ec_noName;
- int signatureKeyStrength = 521;
- int requiredECCbits = ss->sec.secretKeyBits * 2;
-
- if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) {
- svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh);
- if (svrPublicKey)
- ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams);
- if (!SSL_IS_CURVE_NEGOTIATED(ss->ssl3.hs.negotiatedECCurves, ec_curve)) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return ec_noName;
- }
- signatureKeyStrength = curve2bits[ ec_curve ];
- } else {
- /* RSA is our signing cert */
- int serverKeyStrengthInBits;
-
- svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa);
- if (!svrPublicKey) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return ec_noName;
- }
-
- /* currently strength in bytes */
- serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len;
- if (svrPublicKey->u.rsa.modulus.data[0] == 0) {
- serverKeyStrengthInBits--;
- }
- /* convert to strength in bits */
- serverKeyStrengthInBits *= BPB;
-
- signatureKeyStrength =
- SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits);
- }
- if ( requiredECCbits > signatureKeyStrength )
- requiredECCbits = signatureKeyStrength;
-
- return ssl3_GetCurveWithECKeyStrength(ss->ssl3.hs.negotiatedECCurves,
- requiredECCbits);
-}
-
-/* function to clear out the lists */
-static SECStatus
-ssl3_ShutdownECDHECurves(void *appData, void *nssData)
-{
- int i;
- ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0];
-
- for (i=0; i < ec_pastLastName; i++, keyPair++) {
- if (keyPair->pair) {
- ssl3_FreeKeyPair(keyPair->pair);
- }
- }
- memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs);
- return SECSuccess;
-}
-
-static PRStatus
-ssl3_ECRegister(void)
-{
- SECStatus rv;
- rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs);
- if (rv != SECSuccess) {
- gECDHEKeyPairs[ec_noName].error = PORT_GetError();
- }
- return (PRStatus)rv;
-}
-
-/* CallOnce function, called once for each named curve. */
-static PRStatus
-ssl3_CreateECDHEphemeralKeyPair(void * arg)
-{
- SECKEYPrivateKey * privKey = NULL;
- SECKEYPublicKey * pubKey = NULL;
- ssl3KeyPair * keyPair = NULL;
- ECName ec_curve = (ECName)arg;
- SECKEYECParams ecParams = { siBuffer, NULL, 0 };
-
- PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL);
-
- /* ok, no one has generated a global key for this curve yet, do so */
- if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) {
- gECDHEKeyPairs[ec_curve].error = PORT_GetError();
- return PR_FAILURE;
- }
-
- privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL);
- SECITEM_FreeItem(&ecParams, PR_FALSE);
-
- if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) {
- if (privKey) {
- SECKEY_DestroyPrivateKey(privKey);
- }
- if (pubKey) {
- SECKEY_DestroyPublicKey(pubKey);
- }
- ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);
- gECDHEKeyPairs[ec_curve].error = PORT_GetError();
- return PR_FAILURE;
- }
-
- gECDHEKeyPairs[ec_curve].pair = keyPair;
- return PR_SUCCESS;
-}
-
-/*
- * Creates the ephemeral public and private ECDH keys used by
- * server in ECDHE_RSA and ECDHE_ECDSA handshakes.
- * For now, the elliptic curve is chosen to be the same
- * strength as the signing certificate (ECC or RSA).
- * We need an API to specify the curve. This won't be a real
- * issue until we further develop server-side support for ECC
- * cipher suites.
- */
-static SECStatus
-ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve)
-{
- ssl3KeyPair * keyPair = NULL;
-
- /* if there's no global key for this curve, make one. */
- if (gECDHEKeyPairs[ec_curve].pair == NULL) {
- PRStatus status;
-
- status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister);
- if (status != PR_SUCCESS) {
- PORT_SetError(gECDHEKeyPairs[ec_noName].error);
- return SECFailure;
- }
- status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once,
- ssl3_CreateECDHEphemeralKeyPair,
- (void *)ec_curve);
- if (status != PR_SUCCESS) {
- PORT_SetError(gECDHEKeyPairs[ec_curve].error);
- return SECFailure;
- }
- }
-
- keyPair = gECDHEKeyPairs[ec_curve].pair;
- PORT_Assert(keyPair != NULL);
- if (!keyPair)
- return SECFailure;
- ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair);
-
- return SECSuccess;
-}
-
-SECStatus
-ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
-{
- PRArenaPool * arena = NULL;
- SECKEYPublicKey *peerKey = NULL;
- PRBool isTLS;
- SECStatus rv;
- int errCode = SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH;
- SSL3AlertDescription desc = illegal_parameter;
- SSL3Hashes hashes;
- SECItem signature = {siBuffer, NULL, 0};
-
- SECItem ec_params = {siBuffer, NULL, 0};
- SECItem ec_point = {siBuffer, NULL, 0};
- unsigned char paramBuf[3]; /* only for curve_type == named_curve */
-
- isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- /* XXX This works only for named curves, revisit this when
- * we support generic curves.
- */
- ec_params.len = sizeof paramBuf;
- ec_params.data = paramBuf;
- rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-
- /* Fail if the curve is not a named curve */
- if ((ec_params.data[0] != ec_type_named) ||
- (ec_params.data[1] != 0) ||
- !supportedCurve(ec_params.data[2])) {
- errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
- desc = handshake_failure;
- goto alert_loser;
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &ec_point, 1, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
- /* Fail if the ec point uses compressed representation */
- if (ec_point.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
- errCode = SEC_ERROR_UNSUPPORTED_EC_POINT_FORM;
- desc = handshake_failure;
- goto alert_loser;
- }
-
- rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length);
- if (rv != SECSuccess) {
- goto loser; /* malformed. */
- }
-
- if (length != 0) {
- if (isTLS)
- desc = decode_error;
- goto alert_loser; /* malformed. */
- }
-
- PRINT_BUF(60, (NULL, "Server EC params", ec_params.data,
- ec_params.len));
- PRINT_BUF(60, (NULL, "Server EC point", ec_point.data, ec_point.len));
-
- /* failures after this point are not malformed handshakes. */
- /* TLS: send decrypt_error if signature failed. */
- desc = isTLS ? decrypt_error : handshake_failure;
-
- /*
- * check to make sure the hash is signed by right guy
- */
- rv = ssl3_ComputeECDHKeyHash(ec_params, ec_point,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
-
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
- rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature,
- isTLS, ss->pkcs11PinArg);
- if (rv != SECSuccess) {
- errCode =
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto alert_loser;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- goto no_memory;
- }
-
- ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey);
- if (peerKey == NULL) {
- goto no_memory;
- }
-
- peerKey->arena = arena;
- peerKey->keyType = ecKey;
-
- /* set up EC parameters in peerKey */
- if (ssl3_ECName2Params(arena, ec_params.data[2],
- &peerKey->u.ec.DEREncodedParams) != SECSuccess) {
- /* we should never get here since we already
- * checked that we are dealing with a supported curve
- */
- errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
- goto alert_loser;
- }
-
- /* copy publicValue in peerKey */
- if (SECITEM_CopyItem(arena, &peerKey->u.ec.publicValue, &ec_point))
- {
- PORT_FreeArena(arena, PR_FALSE);
- goto no_memory;
- }
- peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_HANDLE;
-
- ss->sec.peerKey = peerKey;
- ss->ssl3.hs.ws = wait_cert_request;
-
- return SECSuccess;
-
-alert_loser:
- (void)SSL3_SendAlert(ss, alert_fatal, desc);
-loser:
- PORT_SetError( errCode );
- return SECFailure;
-
-no_memory: /* no-memory error has already been set. */
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return SECFailure;
-}
-
-SECStatus
-ssl3_SendECDHServerKeyExchange(sslSocket *ss)
-{
-const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def;
- SECStatus rv = SECFailure;
- int length;
- PRBool isTLS;
- SECItem signed_hash = {siBuffer, NULL, 0};
- SSL3Hashes hashes;
-
- SECKEYPublicKey * ecdhePub;
- SECItem ec_params = {siBuffer, NULL, 0};
- unsigned char paramBuf[3];
- ECName curve;
- SSL3KEAType certIndex;
-
-
- /* Generate ephemeral ECDH key pair and send the public key */
- curve = ssl3_GetCurveNameForServerSocket(ss);
- if (curve == ec_noName) {
- goto loser;
- }
- rv = ssl3_CreateECDHEphemeralKeys(ss, curve);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
- ecdhePub = ss->ephemeralECDHKeyPair->pubKey;
- PORT_Assert(ecdhePub != NULL);
- if (!ecdhePub) {
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- return SECFailure;
- }
-
- ec_params.len = sizeof paramBuf;
- ec_params.data = paramBuf;
- curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams);
- if (curve != ec_noName) {
- ec_params.data[0] = ec_type_named;
- ec_params.data[1] = 0x00;
- ec_params.data[2] = curve;
- } else {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
- goto loser;
- }
-
- rv = ssl3_ComputeECDHKeyHash(ec_params, ecdhePub->u.ec.publicValue,
- &ss->ssl3.hs.client_random,
- &ss->ssl3.hs.server_random,
- &hashes, ss->opt.bypassPKCS11);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
-
- /* XXX SSLKEAType isn't really a good choice for
- * indexing certificates but that's all we have
- * for now.
- */
- if (kea_def->kea == kea_ecdhe_rsa)
- certIndex = kt_rsa;
- else /* kea_def->kea == kea_ecdhe_ecdsa */
- certIndex = kt_ecdh;
-
- rv = ssl3_SignHashes(&hashes, ss->serverCerts[certIndex].SERVERKEY,
- &signed_hash, isTLS);
- if (rv != SECSuccess) {
- goto loser; /* ssl3_SignHashes has set err. */
- }
- if (signed_hash.data == NULL) {
- /* how can this happen and rv == SECSuccess ?? */
- PORT_SetError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE);
- goto loser;
- }
-
- length = ec_params.len +
- 1 + ecdhePub->u.ec.publicValue.len +
- 2 + signed_hash.len;
-
- rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshake(ss, ec_params.data, ec_params.len);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss, ecdhePub->u.ec.publicValue.data,
- ecdhePub->u.ec.publicValue.len, 1);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- rv = ssl3_AppendHandshakeVariable(ss, signed_hash.data,
- signed_hash.len, 2);
- if (rv != SECSuccess) {
- goto loser; /* err set by AppendHandshake. */
- }
-
- PORT_Free(signed_hash.data);
- return SECSuccess;
-
-loser:
- if (signed_hash.data != NULL)
- PORT_Free(signed_hash.data);
- return SECFailure;
-}
-
-/* Lists of ECC cipher suites for searching and disabling. */
-
-static const ssl3CipherSuite ecdh_suites[] = {
- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_NULL_SHA,
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
- TLS_ECDH_RSA_WITH_NULL_SHA,
- TLS_ECDH_RSA_WITH_RC4_128_SHA,
- 0 /* end of list marker */
-};
-
-static const ssl3CipherSuite ecdh_ecdsa_suites[] = {
- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_NULL_SHA,
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- 0 /* end of list marker */
-};
-
-static const ssl3CipherSuite ecdh_rsa_suites[] = {
- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
- TLS_ECDH_RSA_WITH_NULL_SHA,
- TLS_ECDH_RSA_WITH_RC4_128_SHA,
- 0 /* end of list marker */
-};
-
-static const ssl3CipherSuite ecdhe_ecdsa_suites[] = {
- TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_NULL_SHA,
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- 0 /* end of list marker */
-};
-
-static const ssl3CipherSuite ecdhe_rsa_suites[] = {
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- TLS_ECDHE_RSA_WITH_NULL_SHA,
- TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- 0 /* end of list marker */
-};
-
-/* List of all ECC cipher suites */
-static const ssl3CipherSuite ecSuites[] = {
- TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_NULL_SHA,
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- TLS_ECDHE_RSA_WITH_NULL_SHA,
- TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_NULL_SHA,
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
- TLS_ECDH_RSA_WITH_NULL_SHA,
- TLS_ECDH_RSA_WITH_RC4_128_SHA,
- 0 /* end of list marker */
-};
-
-/* On this socket, Disable the ECC cipher suites in the argument's list */
-SECStatus
-ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite)
-{
- if (!suite)
- suite = ecSuites;
- for (; *suite; ++suite) {
- SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE);
-
- PORT_Assert(rv == SECSuccess); /* else is coding error */
- }
- return SECSuccess;
-}
-
-/* Look at the server certs configured on this socket, and disable any
- * ECC cipher suites that are not supported by those certs.
- */
-void
-ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss)
-{
- CERTCertificate * svrCert;
-
- svrCert = ss->serverCerts[kt_rsa].serverCert;
- if (!svrCert) {
- ssl3_DisableECCSuites(ss, ecdhe_rsa_suites);
- }
-
- svrCert = ss->serverCerts[kt_ecdh].serverCert;
- if (!svrCert) {
- ssl3_DisableECCSuites(ss, ecdh_suites);
- ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
- } else {
- SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature);
-
- switch (sigTag) {
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
- ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
- break;
- case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
- case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
- case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
- ssl3_DisableECCSuites(ss, ecdh_rsa_suites);
- break;
- default:
- ssl3_DisableECCSuites(ss, ecdh_suites);
- break;
- }
- }
-}
-
-/* Ask: is ANY ECC cipher suite enabled on this socket? */
-/* Order(N^2). Yuk. Also, this ignores export policy. */
-PRBool
-ssl3_IsECCEnabled(sslSocket * ss)
-{
- const ssl3CipherSuite * suite;
-
- for (suite = ecSuites; *suite; ++suite) {
- PRBool enabled = PR_FALSE;
- SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled);
-
- PORT_Assert(rv == SECSuccess); /* else is coding error */
- if (rv == SECSuccess && enabled)
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-#define BE(n) 0, n
-
-#ifndef NSS_ECC_MORE_THAN_SUITE_B
-/* Prefabricated TLS client hello extension, Elliptic Curves List,
- * offers only 3 curves, the Suite B curves, 23-25
- */
-static const PRUint8 EClist[12] = {
- BE(10), /* Extension type */
- BE( 8), /* octets that follow ( 3 pairs + 1 length pair) */
- BE( 6), /* octets that follow ( 3 pairs) */
- BE(23), BE(24), BE(25)
-};
-#else
-/* Prefabricated TLS client hello extension, Elliptic Curves List,
- * offers curves 1-25.
- */
-static const PRUint8 EClist[56] = {
- BE(10), /* Extension type */
- BE(52), /* octets that follow (25 pairs + 1 length pair) */
- BE(50), /* octets that follow (25 pairs) */
- BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7),
- BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15),
- BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23),
- BE(24), BE(25)
-};
-#endif
-
-static const PRUint8 ECPtFmt[6] = {
- BE(11), /* Extension type */
- BE( 2), /* octets that follow */
- 1, /* octets that follow */
- 0 /* uncompressed type only */
-};
-
-/* Send our "canned" (precompiled) Supported Elliptic Curves extension,
- * which says that we support all TLS-defined named curves.
- */
-PRInt32
-ssl3_SendSupportedCurvesXtn(
- sslSocket * ss,
- PRBool append,
- PRUint32 maxBytes)
-{
- if (!ss || !ssl3_IsECCEnabled(ss))
- return 0;
- if (append && maxBytes >= (sizeof EClist)) {
- SECStatus rv = ssl3_AppendHandshake(ss, EClist, (sizeof EClist));
- if (rv != SECSuccess)
- return -1;
- if (!ss->sec.isServer) {
- TLSExtensionData *xtnData = &ss->xtnData;
- xtnData->advertised[xtnData->numAdvertised++] =
- ssl_elliptic_curves_xtn;
- }
- }
- return (sizeof EClist);
-}
-
-/* Send our "canned" (precompiled) Supported Point Formats extension,
- * which says that we only support uncompressed points.
- */
-PRInt32
-ssl3_SendSupportedPointFormatsXtn(
- sslSocket * ss,
- PRBool append,
- PRUint32 maxBytes)
-{
- if (!ss || !ssl3_IsECCEnabled(ss))
- return 0;
- if (append && maxBytes >= (sizeof ECPtFmt)) {
- SECStatus rv = ssl3_AppendHandshake(ss, ECPtFmt, (sizeof ECPtFmt));
- if (rv != SECSuccess)
- return -1;
- if (!ss->sec.isServer) {
- TLSExtensionData *xtnData = &ss->xtnData;
- xtnData->advertised[xtnData->numAdvertised++] =
- ssl_ec_point_formats_xtn;
- }
- }
- return (sizeof ECPtFmt);
-}
-
-/* Just make sure that the remote client supports uncompressed points,
- * Since that is all we support. Disable ECC cipher suites if it doesn't.
- */
-SECStatus
-ssl3_HandleSupportedPointFormatsXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- int i;
-
- if (data->len < 2 || data->len > 255 || !data->data ||
- data->len != (unsigned int)data->data[0] + 1) {
- /* malformed */
- goto loser;
- }
- for (i = data->len; --i > 0; ) {
- if (data->data[i] == 0) {
- /* indicate that we should send a reply */
- SECStatus rv;
- rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
- &ssl3_SendSupportedPointFormatsXtn);
- return rv;
- }
- }
-loser:
- /* evil client doesn't support uncompressed */
- ssl3_DisableECCSuites(ss, ecSuites);
- return SECFailure;
-}
-
-
-#define SSL3_GET_SERVER_PUBLICKEY(sock, type) \
- (ss->serverCerts[type].serverKeyPair ? \
- ss->serverCerts[type].serverKeyPair->pubKey : NULL)
-
-/* Extract the TLS curve name for the public key in our EC server cert. */
-ECName ssl3_GetSvrCertCurveName(sslSocket *ss)
-{
- SECKEYPublicKey *srvPublicKey;
- ECName ec_curve = ec_noName;
-
- srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh);
- if (srvPublicKey) {
- ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams);
- }
- return ec_curve;
-}
-
-/* Ensure that the curve in our server cert is one of the ones suppored
- * by the remote client, and disable all ECC cipher suites if not.
- */
-SECStatus
-ssl3_HandleSupportedCurvesXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
-{
- PRInt32 list_len;
- PRUint32 peerCurves = 0;
- PRUint32 mutualCurves = 0;
- PRUint16 svrCertCurveName;
-
- if (!data->data || data->len < 4 || data->len > 65535)
- goto loser;
- /* get the length of elliptic_curve_list */
- list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
- if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) {
- /* malformed */
- goto loser;
- }
- /* build bit vector of peer's supported curve names */
- while (data->len) {
- PRInt32 curve_name =
- ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
- if (curve_name > ec_noName && curve_name < ec_pastLastName) {
- peerCurves |= (1U << curve_name);
- }
- }
- /* What curves do we support in common? */
- mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves;
- if (!mutualCurves) { /* no mutually supported EC Curves */
- goto loser;
- }
-
- /* if our ECC cert doesn't use one of these supported curves,
- * disable ECC cipher suites that require an ECC cert.
- */
- svrCertCurveName = ssl3_GetSvrCertCurveName(ss);
- if (svrCertCurveName != ec_noName &&
- (mutualCurves & (1U << svrCertCurveName)) != 0) {
- return SECSuccess;
- }
- /* Our EC cert doesn't contain a mutually supported curve.
- * Disable all ECC cipher suites that require an EC cert
- */
- ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
- ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites);
- return SECFailure;
-
-loser:
- /* no common curve supported */
- ssl3_DisableECCSuites(ss, ecSuites);
- return SECFailure;
-}
-
-#endif /* NSS_ENABLE_ECC */
diff --git a/security/nss/lib/ssl/ssl3ext.c b/security/nss/lib/ssl/ssl3ext.c
deleted file mode 100644
index 5a36aaa53..000000000
--- a/security/nss/lib/ssl/ssl3ext.c
+++ /dev/null
@@ -1,1989 +0,0 @@
-/*
- * SSL3 Protocol
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* TLS extension code moved here from ssl3ecc.c */
-/* $Id$ */
-
-#include "nssrenam.h"
-#include "nss.h"
-#include "ssl.h"
-#include "sslproto.h"
-#include "sslimpl.h"
-#include "pk11pub.h"
-#ifdef NO_PKCS11_BYPASS
-#include "blapit.h"
-#else
-#include "blapi.h"
-#endif
-#include "prinit.h"
-
-static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN];
-static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL;
-static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL;
-
-#ifndef NO_PKCS11_BYPASS
-static unsigned char session_ticket_enc_key[AES_256_KEY_LENGTH];
-static unsigned char session_ticket_mac_key[SHA256_LENGTH];
-
-static PRBool session_ticket_keys_initialized = PR_FALSE;
-#endif
-static PRCallOnceType generate_session_keys_once;
-
-/* forward static function declarations */
-static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss,
- SECItem *data, EncryptedSessionTicket *enc_session_ticket);
-static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf,
- PRUint32 bytes);
-static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num,
- PRInt32 lenSize);
-static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss,
- PK11SymKey **aes_key, PK11SymKey **mac_key);
-#ifndef NO_PKCS11_BYPASS
-static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
- PRUint32 *aes_key_length, const unsigned char **mac_key,
- PRUint32 *mac_key_length);
-#endif
-static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss,
- PRBool append, PRUint32 maxBytes);
-static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
-static SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
-static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
-static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type,
- SECItem *data);
-static SECStatus ssl3_ServerSendStatusRequestXtn(sslSocket * ss,
- PRBool append, PRUint32 maxBytes);
-static SECStatus ssl3_ServerHandleStatusRequestXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
-static SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss,
- PRUint16 ex_type,
- SECItem *data);
-static PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
- PRUint32 maxBytes);
-
-/*
- * Write bytes. Using this function means the SECItem structure
- * cannot be freed. The caller is expected to call this function
- * on a shallow copy of the structure.
- */
-static SECStatus
-ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
-{
- if (bytes > item->len)
- return SECFailure;
-
- PORT_Memcpy(item->data, buf, bytes);
- item->data += bytes;
- item->len -= bytes;
- return SECSuccess;
-}
-
-/*
- * Write a number in network byte order. Using this function means the
- * SECItem structure cannot be freed. The caller is expected to call
- * this function on a shallow copy of the structure.
- */
-static SECStatus
-ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize)
-{
- SECStatus rv;
- uint8 b[4];
- uint8 * p = b;
-
- switch (lenSize) {
- case 4:
- *p++ = (uint8) (num >> 24);
- case 3:
- *p++ = (uint8) (num >> 16);
- case 2:
- *p++ = (uint8) (num >> 8);
- case 1:
- *p = (uint8) num;
- }
- rv = ssl3_AppendToItem(item, &b[0], lenSize);
- return rv;
-}
-
-static SECStatus ssl3_SessionTicketShutdown(void* appData, void* nssData)
-{
- if (session_ticket_enc_key_pkcs11) {
- PK11_FreeSymKey(session_ticket_enc_key_pkcs11);
- session_ticket_enc_key_pkcs11 = NULL;
- }
- if (session_ticket_mac_key_pkcs11) {
- PK11_FreeSymKey(session_ticket_mac_key_pkcs11);
- session_ticket_mac_key_pkcs11 = NULL;
- }
- PORT_Memset(&generate_session_keys_once, 0,
- sizeof(generate_session_keys_once));
- return SECSuccess;
-}
-
-
-static PRStatus
-ssl3_GenerateSessionTicketKeysPKCS11(void *data)
-{
- SECStatus rv;
- sslSocket *ss = (sslSocket *)data;
- SECKEYPrivateKey *svrPrivKey = ss->serverCerts[kt_rsa].SERVERKEY;
- SECKEYPublicKey *svrPubKey = ss->serverCerts[kt_rsa].serverKeyPair->pubKey;
-
- if (svrPrivKey == NULL || svrPubKey == NULL) {
- SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.",
- SSL_GETPID(), ss->fd));
- goto loser;
- }
-
- /* Get a copy of the session keys from shared memory. */
- PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
- sizeof(SESS_TICKET_KEY_NAME_PREFIX));
- if (!ssl_GetSessionTicketKeysPKCS11(svrPrivKey, svrPubKey,
- ss->pkcs11PinArg, &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
- &session_ticket_enc_key_pkcs11, &session_ticket_mac_key_pkcs11))
- return PR_FAILURE;
-
- rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL);
- if (rv != SECSuccess)
- goto loser;
-
- return PR_SUCCESS;
-
-loser:
- ssl3_SessionTicketShutdown(NULL, NULL);
- return PR_FAILURE;
-}
-
-static SECStatus
-ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, PK11SymKey **aes_key,
- PK11SymKey **mac_key)
-{
- if (PR_CallOnceWithArg(&generate_session_keys_once,
- ssl3_GenerateSessionTicketKeysPKCS11, ss) != PR_SUCCESS)
- return SECFailure;
-
- if (session_ticket_enc_key_pkcs11 == NULL ||
- session_ticket_mac_key_pkcs11 == NULL)
- return SECFailure;
-
- *aes_key = session_ticket_enc_key_pkcs11;
- *mac_key = session_ticket_mac_key_pkcs11;
- return SECSuccess;
-}
-
-#ifndef NO_PKCS11_BYPASS
-static PRStatus
-ssl3_GenerateSessionTicketKeys(void)
-{
- PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
- sizeof(SESS_TICKET_KEY_NAME_PREFIX));
-
- if (!ssl_GetSessionTicketKeys(&key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
- session_ticket_enc_key, session_ticket_mac_key))
- return PR_FAILURE;
-
- session_ticket_keys_initialized = PR_TRUE;
- return PR_SUCCESS;
-}
-
-static SECStatus
-ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
- PRUint32 *aes_key_length, const unsigned char **mac_key,
- PRUint32 *mac_key_length)
-{
- if (PR_CallOnce(&generate_session_keys_once,
- ssl3_GenerateSessionTicketKeys) != SECSuccess)
- return SECFailure;
-
- if (!session_ticket_keys_initialized)
- return SECFailure;
-
- *aes_key = session_ticket_enc_key;
- *aes_key_length = sizeof(session_ticket_enc_key);
- *mac_key = session_ticket_mac_key;
- *mac_key_length = sizeof(session_ticket_mac_key);
-
- return SECSuccess;
-}
-#endif
-
-/* Table of handlers for received TLS hello extensions, one per extension.
- * In the second generation, this table will be dynamic, and functions
- * will be registered here.
- */
-/* This table is used by the server, to handle client hello extensions. */
-static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
- { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
-#ifdef NSS_ENABLE_ECC
- { ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
- { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
-#endif
- { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
- { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
- { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
- { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
- { -1, NULL }
-};
-
-/* These two tables are used by the client, to handle server hello
- * extensions. */
-static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
- { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
- /* TODO: add a handler for ssl_ec_point_formats_xtn */
- { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
- { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
- { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn },
- { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
- { -1, NULL }
-};
-
-static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
- { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { -1, NULL }
-};
-
-/* Tables of functions to format TLS hello extensions, one function per
- * extension.
- * These static tables are for the formatting of client hello extensions.
- * The server's table of hello senders is dynamic, in the socket struct,
- * and sender functions are registered there.
- */
-static const
-ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
- { ssl_server_name_xtn, &ssl3_SendServerNameXtn },
- { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
-#ifdef NSS_ENABLE_ECC
- { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
- { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
-#endif
- { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
- { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn },
- { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }
- /* any extra entries will appear as { 0, NULL } */
-};
-
-static const
-ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = {
- { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }
- /* any extra entries will appear as { 0, NULL } */
-};
-
-static PRBool
-arrayContainsExtension(const PRUint16 *array, PRUint32 len, PRUint16 ex_type)
-{
- int i;
- for (i = 0; i < len; i++) {
- if (ex_type == array[i])
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-PRBool
-ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type) {
- TLSExtensionData *xtnData = &ss->xtnData;
- return arrayContainsExtension(xtnData->negotiated,
- xtnData->numNegotiated, ex_type);
-}
-
-static PRBool
-ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
- TLSExtensionData *xtnData = &ss->xtnData;
- return arrayContainsExtension(xtnData->advertised,
- xtnData->numAdvertised, ex_type);
-}
-
-/* Format an SNI extension, using the name from the socket's URL,
- * unless that name is a dotted decimal string.
- * Used by client and server.
- */
-PRInt32
-ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
- PRUint32 maxBytes)
-{
- SECStatus rv;
- if (!ss)
- return 0;
- if (!ss->sec.isServer) {
- PRUint32 len;
- PRNetAddr netAddr;
-
- /* must have a hostname */
- if (!ss->url || !ss->url[0])
- return 0;
- /* must not be an IPv4 or IPv6 address */
- if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) {
- /* is an IP address (v4 or v6) */
- return 0;
- }
- len = PORT_Strlen(ss->url);
- if (append && maxBytes >= len + 9) {
- /* extension_type */
- rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
- if (rv != SECSuccess) return -1;
- /* length of extension_data */
- rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);
- if (rv != SECSuccess) return -1;
- /* length of server_name_list */
- rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
- if (rv != SECSuccess) return -1;
- /* Name Type (sni_host_name) */
- rv = ssl3_AppendHandshake(ss, "\0", 1);
- if (rv != SECSuccess) return -1;
- /* HostName (length and value) */
- rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2);
- if (rv != SECSuccess) return -1;
- if (!ss->sec.isServer) {
- TLSExtensionData *xtnData = &ss->xtnData;
- xtnData->advertised[xtnData->numAdvertised++] =
- ssl_server_name_xtn;
- }
- }
- return len + 9;
- }
- /* Server side */
- if (append && maxBytes >= 4) {
- rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
- if (rv != SECSuccess) return -1;
- /* length of extension_data */
- rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
- if (rv != SECSuccess) return -1;
- }
- return 4;
-}
-
-/* handle an incoming SNI extension, by ignoring it. */
-SECStatus
-ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
-{
- SECItem *names = NULL;
- PRUint32 listCount = 0, namesPos = 0, i;
- TLSExtensionData *xtnData = &ss->xtnData;
- SECItem ldata;
- PRInt32 listLenBytes = 0;
-
- if (!ss->sec.isServer) {
- /* Verify extension_data is empty. */
- if (data->data || data->len ||
- !ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) {
- /* malformed or was not initiated by the client.*/
- return SECFailure;
- }
- return SECSuccess;
- }
-
- /* Server side - consume client data and register server sender. */
- /* do not parse the data if don't have user extension handling function. */
- if (!ss->sniSocketConfig) {
- return SECSuccess;
- }
- /* length of server_name_list */
- listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
- if (listLenBytes == 0 || listLenBytes != data->len) {
- return SECFailure;
- }
- ldata = *data;
- /* Calculate the size of the array.*/
- while (listLenBytes > 0) {
- SECItem litem;
- SECStatus rv;
- PRInt32 type;
- /* Name Type (sni_host_name) */
- type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len);
- if (!ldata.len) {
- return SECFailure;
- }
- rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* Adjust total length for cunsumed item, item len and type.*/
- listLenBytes -= litem.len + 3;
- if (listLenBytes > 0 && !ldata.len) {
- return SECFailure;
- }
- listCount += 1;
- }
- if (!listCount) {
- return SECFailure;
- }
- names = PORT_ZNewArray(SECItem, listCount);
- if (!names) {
- return SECFailure;
- }
- for (i = 0;i < listCount;i++) {
- int j;
- PRInt32 type;
- SECStatus rv;
- PRBool nametypePresent = PR_FALSE;
- /* Name Type (sni_host_name) */
- type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len);
- /* Check if we have such type in the list */
- for (j = 0;j < listCount && names[j].data;j++) {
- if (names[j].type == type) {
- nametypePresent = PR_TRUE;
- break;
- }
- }
- /* HostName (length and value) */
- rv = ssl3_ConsumeHandshakeVariable(ss, &names[namesPos], 2,
- &data->data, &data->len);
- if (rv != SECSuccess) {
- goto loser;
- }
- if (nametypePresent == PR_FALSE) {
- namesPos += 1;
- }
- }
- /* Free old and set the new data. */
- if (xtnData->sniNameArr) {
- PORT_Free(ss->xtnData.sniNameArr);
- }
- xtnData->sniNameArr = names;
- xtnData->sniNameArrSize = namesPos;
- xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn;
-
- return SECSuccess;
-
-loser:
- PORT_Free(names);
- return SECFailure;
-}
-
-/* Called by both clients and servers.
- * Clients sends a filled in session ticket if one is available, and otherwise
- * sends an empty ticket. Servers always send empty tickets.
- */
-PRInt32
-ssl3_SendSessionTicketXtn(
- sslSocket * ss,
- PRBool append,
- PRUint32 maxBytes)
-{
- PRInt32 extension_length;
- NewSessionTicket *session_ticket = NULL;
-
- /* Ignore the SessionTicket extension if processing is disabled. */
- if (!ss->opt.enableSessionTickets)
- return 0;
-
- /* Empty extension length = extension_type (2-bytes) +
- * length(extension_data) (2-bytes)
- */
- extension_length = 4;
-
- /* If we are a client then send a session ticket if one is availble.
- * Servers that support the extension and are willing to negotiate the
- * the extension always respond with an empty extension.
- */
- if (!ss->sec.isServer) {
- sslSessionID *sid = ss->sec.ci.sid;
- session_ticket = &sid->u.ssl3.sessionTicket;
- if (session_ticket->ticket.data) {
- if (ss->xtnData.ticketTimestampVerified) {
- extension_length += session_ticket->ticket.len;
- } else if (!append &&
- (session_ticket->ticket_lifetime_hint == 0 ||
- (session_ticket->ticket_lifetime_hint +
- session_ticket->received_timestamp > ssl_Time()))) {
- extension_length += session_ticket->ticket.len;
- ss->xtnData.ticketTimestampVerified = PR_TRUE;
- }
- }
- }
-
- if (append && maxBytes >= extension_length) {
- SECStatus rv;
- /* extension_type */
- rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
- if (rv != SECSuccess)
- goto loser;
- if (session_ticket && session_ticket->ticket.data &&
- ss->xtnData.ticketTimestampVerified) {
- rv = ssl3_AppendHandshakeVariable(ss, session_ticket->ticket.data,
- session_ticket->ticket.len, 2);
- ss->xtnData.ticketTimestampVerified = PR_FALSE;
- } else {
- rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
- }
- if (rv != SECSuccess)
- goto loser;
-
- if (!ss->sec.isServer) {
- TLSExtensionData *xtnData = &ss->xtnData;
- xtnData->advertised[xtnData->numAdvertised++] =
- ssl_session_ticket_xtn;
- }
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
- }
- return extension_length;
-
- loser:
- ss->xtnData.ticketTimestampVerified = PR_FALSE;
- return -1;
-}
-
-/* handle an incoming Next Protocol Negotiation extension. */
-static SECStatus
-ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
-{
- if (ss->firstHsDone || data->len != 0) {
- /* Clients MUST send an empty NPN extension, if any. */
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
- return SECFailure;
- }
-
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
-
- /* TODO: server side NPN support would require calling
- * ssl3_RegisterServerHelloExtensionSender here in order to echo the
- * extension back to the client. */
-
- return SECSuccess;
-}
-
-/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none
- * of the lengths may be 0 and the sum of the lengths must equal the length of
- * the block. */
-SECStatus
-ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned int length)
-{
- unsigned int offset = 0;
-
- while (offset < length) {
- unsigned int newOffset = offset + 1 + (unsigned int) data[offset];
- /* Reject embedded nulls to protect against buggy applications that
- * store protocol identifiers in null-terminated strings.
- */
- if (newOffset > length || data[offset] == 0) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
- return SECFailure;
- }
- offset = newOffset;
- }
-
- if (offset > length) {
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- SECStatus rv;
- unsigned char resultBuffer[255];
- SECItem result = { siBuffer, resultBuffer, 0 };
-
- PORT_Assert(!ss->firstHsDone);
-
- rv = ssl3_ValidateNextProtoNego(data->data, data->len);
- if (rv != SECSuccess)
- return rv;
-
- /* ss->nextProtoCallback cannot normally be NULL if we negotiated the
- * extension. However, It is possible that an application erroneously
- * cleared the callback between the time we sent the ClientHello and now.
- */
- PORT_Assert(ss->nextProtoCallback != NULL);
- if (!ss->nextProtoCallback) {
- /* XXX Use a better error code. This is an application error, not an
- * NSS bug. */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
-
- rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
- result.data, &result.len, sizeof resultBuffer);
- if (rv != SECSuccess)
- return rv;
- /* If the callback wrote more than allowed to |result| it has corrupted our
- * stack. */
- if (result.len > sizeof resultBuffer) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
-
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
-
- SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
- return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result);
-}
-
-static PRInt32
-ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, PRBool append,
- PRUint32 maxBytes)
-{
- PRInt32 extension_length;
-
- /* Renegotiations do not send this extension. */
- if (!ss->nextProtoCallback || ss->firstHsDone) {
- return 0;
- }
-
- extension_length = 4;
-
- if (append && maxBytes >= extension_length) {
- SECStatus rv;
- rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_nego_xtn, 2);
- if (rv != SECSuccess)
- goto loser;
- rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
- if (rv != SECSuccess)
- goto loser;
- ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
- ssl_next_proto_nego_xtn;
- } else if (maxBytes < extension_length) {
- return 0;
- }
-
- return extension_length;
-
-loser:
- return -1;
-}
-
-static SECStatus
-ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- /* The echoed extension must be empty. */
- if (data->len != 0)
- return SECFailure;
-
- /* Keep track of negotiated extensions. */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
-
- return SECSuccess;
-}
-
-static PRInt32
-ssl3_ServerSendStatusRequestXtn(
- sslSocket * ss,
- PRBool append,
- PRUint32 maxBytes)
-{
- PRInt32 extension_length;
- SECStatus rv;
-
- if (!ss->certStatusArray)
- return 0;
-
- extension_length = 2 + 2;
- if (append && maxBytes >= extension_length) {
- /* extension_type */
- rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
- if (rv != SECSuccess)
- return -1;
- /* length of extension_data */
- rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
- if (rv != SECSuccess)
- return -1;
- }
-
- return extension_length;
-}
-
-/* ssl3_ClientSendStatusRequestXtn builds the status_request extension on the
- * client side. See RFC 4366 section 3.6. */
-static PRInt32
-ssl3_ClientSendStatusRequestXtn(sslSocket * ss, PRBool append,
- PRUint32 maxBytes)
-{
- PRInt32 extension_length;
-
- if (!ss->opt.enableOCSPStapling)
- return 0;
-
- /* extension_type (2-bytes) +
- * length(extension_data) (2-bytes) +
- * status_type (1) +
- * responder_id_list length (2) +
- * request_extensions length (2)
- */
- extension_length = 9;
-
- if (append && maxBytes >= extension_length) {
- SECStatus rv;
- TLSExtensionData *xtnData;
-
- /* extension_type */
- rv = ssl3_AppendHandshakeNumber(ss, ssl_cert_status_xtn, 2);
- if (rv != SECSuccess)
- return -1;
- rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
- if (rv != SECSuccess)
- return -1;
- rv = ssl3_AppendHandshakeNumber(ss, 1 /* status_type ocsp */, 1);
- if (rv != SECSuccess)
- return -1;
- /* A zero length responder_id_list means that the responders are
- * implicitly known to the server. */
- rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
- if (rv != SECSuccess)
- return -1;
- /* A zero length request_extensions means that there are no extensions.
- * Specifically, we don't set the id-pkix-ocsp-nonce extension. This
- * means that the server can replay a cached OCSP response to us. */
- rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
- if (rv != SECSuccess)
- return -1;
-
- xtnData = &ss->xtnData;
- xtnData->advertised[xtnData->numAdvertised++] = ssl_cert_status_xtn;
- } else if (maxBytes < extension_length) {
- PORT_Assert(0);
- return 0;
- }
- return extension_length;
-}
-
-/*
- * NewSessionTicket
- * Called from ssl3_HandleFinished
- */
-SECStatus
-ssl3_SendNewSessionTicket(sslSocket *ss)
-{
- int i;
- SECStatus rv;
- NewSessionTicket ticket;
- SECItem plaintext;
- SECItem plaintext_item = {0, NULL, 0};
- SECItem ciphertext = {0, NULL, 0};
- PRUint32 ciphertext_length;
- PRBool ms_is_wrapped;
- unsigned char wrapped_ms[SSL3_MASTER_SECRET_LENGTH];
- SECItem ms_item = {0, NULL, 0};
- SSL3KEAType effectiveExchKeyType = ssl_kea_null;
- PRUint32 padding_length;
- PRUint32 message_length;
- PRUint32 cert_length;
- uint8 length_buf[4];
- PRUint32 now;
- PK11SymKey *aes_key_pkcs11;
- PK11SymKey *mac_key_pkcs11;
-#ifndef NO_PKCS11_BYPASS
- const unsigned char *aes_key;
- const unsigned char *mac_key;
- PRUint32 aes_key_length;
- PRUint32 mac_key_length;
- PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
- AESContext *aes_ctx;
- const SECHashObject *hashObj = NULL;
- PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
- HMACContext *hmac_ctx;
-#endif
- CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
- PK11Context *aes_ctx_pkcs11;
- CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
- PK11Context *hmac_ctx_pkcs11;
- unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
- unsigned int computed_mac_length;
- unsigned char iv[AES_BLOCK_SIZE];
- SECItem ivItem;
- SECItem *srvName = NULL;
- PRUint32 srvNameLen = 0;
- CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value,
- * must be >= 0 */
-
- SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake",
- SSL_GETPID(), ss->fd));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
-
- ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT;
- cert_length = (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) ?
- 3 + ss->sec.ci.sid->peerCert->derCert.len : 0;
-
- /* Get IV and encryption keys */
- ivItem.data = iv;
- ivItem.len = sizeof(iv);
- rv = PK11_GenerateRandom(iv, sizeof(iv));
- if (rv != SECSuccess) goto loser;
-
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
- &mac_key, &mac_key_length);
- } else
-#endif
- {
- rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
- &mac_key_pkcs11);
- }
- if (rv != SECSuccess) goto loser;
-
- if (ss->ssl3.pwSpec->msItem.len && ss->ssl3.pwSpec->msItem.data) {
- /* The master secret is available unwrapped. */
- ms_item.data = ss->ssl3.pwSpec->msItem.data;
- ms_item.len = ss->ssl3.pwSpec->msItem.len;
- ms_is_wrapped = PR_FALSE;
- } else {
- /* Extract the master secret wrapped. */
- sslSessionID sid;
- PORT_Memset(&sid, 0, sizeof(sslSessionID));
-
- if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa) {
- effectiveExchKeyType = kt_rsa;
- } else {
- effectiveExchKeyType = ss->ssl3.hs.kea_def->exchKeyType;
- }
-
- rv = ssl3_CacheWrappedMasterSecret(ss, &sid, ss->ssl3.pwSpec,
- effectiveExchKeyType);
- if (rv == SECSuccess) {
- if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms))
- goto loser;
- memcpy(wrapped_ms, sid.u.ssl3.keys.wrapped_master_secret,
- sid.u.ssl3.keys.wrapped_master_secret_len);
- ms_item.data = wrapped_ms;
- ms_item.len = sid.u.ssl3.keys.wrapped_master_secret_len;
- msWrapMech = sid.u.ssl3.masterWrapMech;
- } else {
- /* TODO: else send an empty ticket. */
- goto loser;
- }
- ms_is_wrapped = PR_TRUE;
- }
- /* Prep to send negotiated name */
- srvName = &ss->ssl3.pwSpec->srvVirtName;
- if (srvName->data && srvName->len) {
- srvNameLen = 2 + srvName->len; /* len bytes + name len */
- }
-
- ciphertext_length =
- sizeof(PRUint16) /* ticket_version */
- + sizeof(SSL3ProtocolVersion) /* ssl_version */
- + sizeof(ssl3CipherSuite) /* ciphersuite */
- + 1 /* compression */
- + 10 /* cipher spec parameters */
- + 1 /* SessionTicket.ms_is_wrapped */
- + 1 /* effectiveExchKeyType */
- + 4 /* msWrapMech */
- + 2 /* master_secret.length */
- + ms_item.len /* master_secret */
- + 1 /* client_auth_type */
- + cert_length /* cert */
- + 1 /* server name type */
- + srvNameLen /* name len + length field */
- + sizeof(ticket.ticket_lifetime_hint);
- padding_length = AES_BLOCK_SIZE -
- (ciphertext_length % AES_BLOCK_SIZE);
- ciphertext_length += padding_length;
-
- message_length =
- sizeof(ticket.ticket_lifetime_hint) /* ticket_lifetime_hint */
- + 2 /* length field for NewSessionTicket.ticket */
- + SESS_TICKET_KEY_NAME_LEN /* key_name */
- + AES_BLOCK_SIZE /* iv */
- + 2 /* length field for NewSessionTicket.ticket.encrypted_state */
- + ciphertext_length /* encrypted_state */
- + TLS_EX_SESS_TICKET_MAC_LENGTH; /* mac */
-
- if (SECITEM_AllocItem(NULL, &plaintext_item, ciphertext_length) == NULL)
- goto loser;
-
- plaintext = plaintext_item;
-
- /* ticket_version */
- rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION,
- sizeof(PRUint16));
- if (rv != SECSuccess) goto loser;
-
- /* ssl_version */
- rv = ssl3_AppendNumberToItem(&plaintext, ss->version,
- sizeof(SSL3ProtocolVersion));
- if (rv != SECSuccess) goto loser;
-
- /* ciphersuite */
- rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.cipher_suite,
- sizeof(ssl3CipherSuite));
- if (rv != SECSuccess) goto loser;
-
- /* compression */
- rv = ssl3_AppendNumberToItem(&plaintext, ss->ssl3.hs.compression, 1);
- if (rv != SECSuccess) goto loser;
-
- /* cipher spec parameters */
- rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authAlgorithm, 1);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.authKeyBits, 4);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaType, 1);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendNumberToItem(&plaintext, ss->sec.keaKeyBits, 4);
- if (rv != SECSuccess) goto loser;
-
- /* master_secret */
- rv = ssl3_AppendNumberToItem(&plaintext, ms_is_wrapped, 1);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendNumberToItem(&plaintext, effectiveExchKeyType, 1);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendNumberToItem(&plaintext, msWrapMech, 4);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendNumberToItem(&plaintext, ms_item.len, 2);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendToItem(&plaintext, ms_item.data, ms_item.len);
- if (rv != SECSuccess) goto loser;
-
- /* client_identity */
- if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) {
- rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendNumberToItem(&plaintext,
- ss->sec.ci.sid->peerCert->derCert.len, 3);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendToItem(&plaintext,
- ss->sec.ci.sid->peerCert->derCert.data,
- ss->sec.ci.sid->peerCert->derCert.len);
- if (rv != SECSuccess) goto loser;
- } else {
- rv = ssl3_AppendNumberToItem(&plaintext, 0, 1);
- if (rv != SECSuccess) goto loser;
- }
-
- /* timestamp */
- now = ssl_Time();
- rv = ssl3_AppendNumberToItem(&plaintext, now,
- sizeof(ticket.ticket_lifetime_hint));
- if (rv != SECSuccess) goto loser;
-
- if (srvNameLen) {
- /* Name Type (sni_host_name) */
- rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1);
- if (rv != SECSuccess) goto loser;
- /* HostName (length and value) */
- rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2);
- if (rv != SECSuccess) goto loser;
- rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len);
- if (rv != SECSuccess) goto loser;
- } else {
- /* No Name */
- rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME,
- 1);
- if (rv != SECSuccess) goto loser;
- }
-
- PORT_Assert(plaintext.len == padding_length);
- for (i = 0; i < padding_length; i++)
- plaintext.data[i] = (unsigned char)padding_length;
-
- if (SECITEM_AllocItem(NULL, &ciphertext, ciphertext_length) == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- /* Generate encrypted portion of ticket. */
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- aes_ctx = (AESContext *)aes_ctx_buf;
- rv = AES_InitContext(aes_ctx, aes_key, aes_key_length, iv,
- NSS_AES_CBC, 1, AES_BLOCK_SIZE);
- if (rv != SECSuccess) goto loser;
-
- rv = AES_Encrypt(aes_ctx, ciphertext.data, &ciphertext.len,
- ciphertext.len, plaintext_item.data,
- plaintext_item.len);
- if (rv != SECSuccess) goto loser;
- } else
-#endif
- {
- aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
- CKA_ENCRYPT, aes_key_pkcs11, &ivItem);
- if (!aes_ctx_pkcs11)
- goto loser;
-
- rv = PK11_CipherOp(aes_ctx_pkcs11, ciphertext.data,
- (int *)&ciphertext.len, ciphertext.len,
- plaintext_item.data, plaintext_item.len);
- PK11_Finalize(aes_ctx_pkcs11);
- PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
- if (rv != SECSuccess) goto loser;
- }
-
- /* Convert ciphertext length to network order. */
- length_buf[0] = (ciphertext.len >> 8) & 0xff;
- length_buf[1] = (ciphertext.len ) & 0xff;
-
- /* Compute MAC. */
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- hmac_ctx = (HMACContext *)hmac_ctx_buf;
- hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
- if (HMAC_Init(hmac_ctx, hashObj, mac_key,
- mac_key_length, PR_FALSE) != SECSuccess)
- goto loser;
-
- HMAC_Begin(hmac_ctx);
- HMAC_Update(hmac_ctx, key_name, SESS_TICKET_KEY_NAME_LEN);
- HMAC_Update(hmac_ctx, iv, sizeof(iv));
- HMAC_Update(hmac_ctx, (unsigned char *)length_buf, 2);
- HMAC_Update(hmac_ctx, ciphertext.data, ciphertext.len);
- HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
- sizeof(computed_mac));
- } else
-#endif
- {
- SECItem macParam;
- macParam.data = NULL;
- macParam.len = 0;
- hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
- CKA_SIGN, mac_key_pkcs11, &macParam);
- if (!hmac_ctx_pkcs11)
- goto loser;
-
- rv = PK11_DigestBegin(hmac_ctx_pkcs11);
- rv = PK11_DigestOp(hmac_ctx_pkcs11, key_name,
- SESS_TICKET_KEY_NAME_LEN);
- rv = PK11_DigestOp(hmac_ctx_pkcs11, iv, sizeof(iv));
- rv = PK11_DigestOp(hmac_ctx_pkcs11, (unsigned char *)length_buf, 2);
- rv = PK11_DigestOp(hmac_ctx_pkcs11, ciphertext.data, ciphertext.len);
- rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
- &computed_mac_length, sizeof(computed_mac));
- PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
- if (rv != SECSuccess) goto loser;
- }
-
- /* Serialize the handshake message. */
- rv = ssl3_AppendHandshakeHeader(ss, new_session_ticket, message_length);
- if (rv != SECSuccess) goto loser;
-
- rv = ssl3_AppendHandshakeNumber(ss, ticket.ticket_lifetime_hint,
- sizeof(ticket.ticket_lifetime_hint));
- if (rv != SECSuccess) goto loser;
-
- rv = ssl3_AppendHandshakeNumber(ss,
- message_length - sizeof(ticket.ticket_lifetime_hint) - 2, 2);
- if (rv != SECSuccess) goto loser;
-
- rv = ssl3_AppendHandshake(ss, key_name, SESS_TICKET_KEY_NAME_LEN);
- if (rv != SECSuccess) goto loser;
-
- rv = ssl3_AppendHandshake(ss, iv, sizeof(iv));
- if (rv != SECSuccess) goto loser;
-
- rv = ssl3_AppendHandshakeVariable(ss, ciphertext.data, ciphertext.len, 2);
- if (rv != SECSuccess) goto loser;
-
- rv = ssl3_AppendHandshake(ss, computed_mac, computed_mac_length);
- if (rv != SECSuccess) goto loser;
-
-loser:
- if (plaintext_item.data)
- SECITEM_FreeItem(&plaintext_item, PR_FALSE);
- if (ciphertext.data)
- SECITEM_FreeItem(&ciphertext, PR_FALSE);
-
- return rv;
-}
-
-/* When a client receives a SessionTicket extension a NewSessionTicket
- * message is expected during the handshake.
- */
-SECStatus
-ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- if (data->len != 0)
- return SECFailure;
-
- /* Keep track of negotiated extensions. */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- return SECSuccess;
-}
-
-SECStatus
-ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- SECStatus rv;
- SECItem *decrypted_state = NULL;
- SessionTicket *parsed_session_ticket = NULL;
- sslSessionID *sid = NULL;
- SSL3Statistics *ssl3stats;
-
- /* Ignore the SessionTicket extension if processing is disabled. */
- if (!ss->opt.enableSessionTickets)
- return SECSuccess;
-
- /* Keep track of negotiated extensions. */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
-
- /* Parse the received ticket sent in by the client. We are
- * lenient about some parse errors, falling back to a fullshake
- * instead of terminating the current connection.
- */
- if (data->len == 0) {
- ss->xtnData.emptySessionTicket = PR_TRUE;
- } else {
- int i;
- SECItem extension_data;
- EncryptedSessionTicket enc_session_ticket;
- unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
- unsigned int computed_mac_length;
-#ifndef NO_PKCS11_BYPASS
- const SECHashObject *hashObj;
- const unsigned char *aes_key;
- const unsigned char *mac_key;
- PRUint32 aes_key_length;
- PRUint32 mac_key_length;
- PRUint64 hmac_ctx_buf[MAX_MAC_CONTEXT_LLONGS];
- HMACContext *hmac_ctx;
- PRUint64 aes_ctx_buf[MAX_CIPHER_CONTEXT_LLONGS];
- AESContext *aes_ctx;
-#endif
- PK11SymKey *aes_key_pkcs11;
- PK11SymKey *mac_key_pkcs11;
- PK11Context *hmac_ctx_pkcs11;
- CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC;
- PK11Context *aes_ctx_pkcs11;
- CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
- unsigned char * padding;
- PRUint32 padding_length;
- unsigned char *buffer;
- unsigned int buffer_len;
- PRInt32 temp;
- SECItem cert_item;
- PRInt8 nameType = TLS_STE_NO_SERVER_NAME;
-
- /* Turn off stateless session resumption if the client sends a
- * SessionTicket extension, even if the extension turns out to be
- * malformed (ss->sec.ci.sid is non-NULL when doing session
- * renegotiation.)
- */
- if (ss->sec.ci.sid != NULL) {
- if (ss->sec.uncache)
- ss->sec.uncache(ss->sec.ci.sid);
- ssl_FreeSID(ss->sec.ci.sid);
- ss->sec.ci.sid = NULL;
- }
-
- extension_data.data = data->data; /* Keep a copy for future use. */
- extension_data.len = data->len;
-
- if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket)
- != SECSuccess)
- return SECFailure;
-
- /* Get session ticket keys. */
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- rv = ssl3_GetSessionTicketKeys(&aes_key, &aes_key_length,
- &mac_key, &mac_key_length);
- } else
-#endif
- {
- rv = ssl3_GetSessionTicketKeysPKCS11(ss, &aes_key_pkcs11,
- &mac_key_pkcs11);
- }
- if (rv != SECSuccess) {
- SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.",
- SSL_GETPID(), ss->fd));
- goto loser;
- }
-
- /* If the ticket sent by the client was generated under a key different
- * from the one we have, bypass ticket processing.
- */
- if (PORT_Memcmp(enc_session_ticket.key_name, key_name,
- SESS_TICKET_KEY_NAME_LEN) != 0) {
- SSL_DBG(("%d: SSL[%d]: Session ticket key_name sent mismatch.",
- SSL_GETPID(), ss->fd));
- goto no_ticket;
- }
-
- /* Verify the MAC on the ticket. MAC verification may also
- * fail if the MAC key has been recently refreshed.
- */
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- hmac_ctx = (HMACContext *)hmac_ctx_buf;
- hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
- if (HMAC_Init(hmac_ctx, hashObj, mac_key,
- sizeof(session_ticket_mac_key), PR_FALSE) != SECSuccess)
- goto no_ticket;
- HMAC_Begin(hmac_ctx);
- HMAC_Update(hmac_ctx, extension_data.data,
- extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
- if (HMAC_Finish(hmac_ctx, computed_mac, &computed_mac_length,
- sizeof(computed_mac)) != SECSuccess)
- goto no_ticket;
- } else
-#endif
- {
- SECItem macParam;
- macParam.data = NULL;
- macParam.len = 0;
- hmac_ctx_pkcs11 = PK11_CreateContextBySymKey(macMech,
- CKA_SIGN, mac_key_pkcs11, &macParam);
- if (!hmac_ctx_pkcs11) {
- SSL_DBG(("%d: SSL[%d]: Unable to create HMAC context: %d.",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- goto no_ticket;
- } else {
- SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.",
- SSL_GETPID(), ss->fd));
- }
- rv = PK11_DigestBegin(hmac_ctx_pkcs11);
- rv = PK11_DigestOp(hmac_ctx_pkcs11, extension_data.data,
- extension_data.len - TLS_EX_SESS_TICKET_MAC_LENGTH);
- if (rv != SECSuccess) {
- PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
- goto no_ticket;
- }
- rv = PK11_DigestFinal(hmac_ctx_pkcs11, computed_mac,
- &computed_mac_length, sizeof(computed_mac));
- PK11_DestroyContext(hmac_ctx_pkcs11, PR_TRUE);
- if (rv != SECSuccess)
- goto no_ticket;
- }
- if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac,
- computed_mac_length) != 0) {
- SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.",
- SSL_GETPID(), ss->fd));
- goto no_ticket;
- }
-
- /* We ignore key_name for now.
- * This is ok as MAC verification succeeded.
- */
-
- /* Decrypt the ticket. */
-
- /* Plaintext is shorter than the ciphertext due to padding. */
- decrypted_state = SECITEM_AllocItem(NULL, NULL,
- enc_session_ticket.encrypted_state.len);
-
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11) {
- aes_ctx = (AESContext *)aes_ctx_buf;
- rv = AES_InitContext(aes_ctx, aes_key,
- sizeof(session_ticket_enc_key), enc_session_ticket.iv,
- NSS_AES_CBC, 0,AES_BLOCK_SIZE);
- if (rv != SECSuccess) {
- SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
- SSL_GETPID(), ss->fd));
- goto no_ticket;
- }
-
- rv = AES_Decrypt(aes_ctx, decrypted_state->data,
- &decrypted_state->len, decrypted_state->len,
- enc_session_ticket.encrypted_state.data,
- enc_session_ticket.encrypted_state.len);
- if (rv != SECSuccess)
- goto no_ticket;
- } else
-#endif
- {
- SECItem ivItem;
- ivItem.data = enc_session_ticket.iv;
- ivItem.len = AES_BLOCK_SIZE;
- aes_ctx_pkcs11 = PK11_CreateContextBySymKey(cipherMech,
- CKA_DECRYPT, aes_key_pkcs11, &ivItem);
- if (!aes_ctx_pkcs11) {
- SSL_DBG(("%d: SSL[%d]: Unable to create AES context.",
- SSL_GETPID(), ss->fd));
- goto no_ticket;
- }
-
- rv = PK11_CipherOp(aes_ctx_pkcs11, decrypted_state->data,
- (int *)&decrypted_state->len, decrypted_state->len,
- enc_session_ticket.encrypted_state.data,
- enc_session_ticket.encrypted_state.len);
- PK11_Finalize(aes_ctx_pkcs11);
- PK11_DestroyContext(aes_ctx_pkcs11, PR_TRUE);
- if (rv != SECSuccess)
- goto no_ticket;
- }
-
- /* Check padding. */
- padding_length =
- (PRUint32)decrypted_state->data[decrypted_state->len - 1];
- if (padding_length == 0 || padding_length > AES_BLOCK_SIZE)
- goto no_ticket;
-
- padding = &decrypted_state->data[decrypted_state->len - padding_length];
- for (i = 0; i < padding_length; i++, padding++) {
- if (padding_length != (PRUint32)*padding)
- goto no_ticket;
- }
-
- /* Deserialize session state. */
- buffer = decrypted_state->data;
- buffer_len = decrypted_state->len;
-
- parsed_session_ticket = PORT_ZAlloc(sizeof(SessionTicket));
- if (parsed_session_ticket == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- /* Read ticket_version (which is ignored for now.) */
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp;
-
- /* Read SSLVersion. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp;
-
- /* Read cipher_suite. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp;
-
- /* Read compression_method. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->compression_method = (SSLCompressionMethod)temp;
-
- /* Read cipher spec parameters. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->authAlgorithm = (SSLSignType)temp;
- temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->authKeyBits = (PRUint32)temp;
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->keaType = (SSLKEAType)temp;
- temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->keaKeyBits = (PRUint32)temp;
-
- /* Read wrapped master_secret. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->ms_is_wrapped = (PRBool)temp;
-
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->exchKeyType = (SSL3KEAType)temp;
-
- temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp;
-
- temp = ssl3_ConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len);
- if (temp < 0) goto no_ticket;
- parsed_session_ticket->ms_length = (PRUint16)temp;
- if (parsed_session_ticket->ms_length == 0 || /* sanity check MS. */
- parsed_session_ticket->ms_length >
- sizeof(parsed_session_ticket->master_secret))
- goto no_ticket;
-
- /* Allow for the wrapped master secret to be longer. */
- if (buffer_len < sizeof(SSL3_MASTER_SECRET_LENGTH))
- goto no_ticket;
- PORT_Memcpy(parsed_session_ticket->master_secret, buffer,
- parsed_session_ticket->ms_length);
- buffer += parsed_session_ticket->ms_length;
- buffer_len -= parsed_session_ticket->ms_length;
-
- /* Read client_identity */
- temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
- if (temp < 0)
- goto no_ticket;
- parsed_session_ticket->client_identity.client_auth_type =
- (ClientAuthenticationType)temp;
- switch(parsed_session_ticket->client_identity.client_auth_type) {
- case CLIENT_AUTH_ANONYMOUS:
- break;
- case CLIENT_AUTH_CERTIFICATE:
- rv = ssl3_ConsumeHandshakeVariable(ss, &cert_item, 3,
- &buffer, &buffer_len);
- if (rv != SECSuccess) goto no_ticket;
- rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert,
- &cert_item);
- if (rv != SECSuccess) goto no_ticket;
- break;
- default:
- goto no_ticket;
- }
- /* Read timestamp. */
- temp = ssl3_ConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len);
- if (temp < 0)
- goto no_ticket;
- parsed_session_ticket->timestamp = (PRUint32)temp;
-
- /* Read server name */
- nameType =
- ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
- if (nameType != TLS_STE_NO_SERVER_NAME) {
- SECItem name_item;
- rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer,
- &buffer_len);
- if (rv != SECSuccess) goto no_ticket;
- rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName,
- &name_item);
- if (rv != SECSuccess) goto no_ticket;
- parsed_session_ticket->srvName.type = nameType;
- }
-
- /* Done parsing. Check that all bytes have been consumed. */
- if (buffer_len != padding_length)
- goto no_ticket;
-
- /* Use the ticket if it has not expired, otherwise free the allocated
- * memory since the ticket is of no use.
- */
- if (parsed_session_ticket->timestamp != 0 &&
- parsed_session_ticket->timestamp +
- TLS_EX_SESS_TICKET_LIFETIME_HINT > ssl_Time()) {
-
- sid = ssl3_NewSessionID(ss, PR_TRUE);
- if (sid == NULL) {
- rv = SECFailure;
- goto loser;
- }
-
- /* Copy over parameters. */
- sid->version = parsed_session_ticket->ssl_version;
- sid->u.ssl3.cipherSuite = parsed_session_ticket->cipher_suite;
- sid->u.ssl3.compression = parsed_session_ticket->compression_method;
- sid->authAlgorithm = parsed_session_ticket->authAlgorithm;
- sid->authKeyBits = parsed_session_ticket->authKeyBits;
- sid->keaType = parsed_session_ticket->keaType;
- sid->keaKeyBits = parsed_session_ticket->keaKeyBits;
-
- /* Copy master secret. */
-#ifndef NO_PKCS11_BYPASS
- if (ss->opt.bypassPKCS11 &&
- parsed_session_ticket->ms_is_wrapped)
- goto no_ticket;
-#endif
- if (parsed_session_ticket->ms_length >
- sizeof(sid->u.ssl3.keys.wrapped_master_secret))
- goto no_ticket;
- PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret,
- parsed_session_ticket->master_secret,
- parsed_session_ticket->ms_length);
- sid->u.ssl3.keys.wrapped_master_secret_len =
- parsed_session_ticket->ms_length;
- sid->u.ssl3.exchKeyType = parsed_session_ticket->exchKeyType;
- sid->u.ssl3.masterWrapMech = parsed_session_ticket->msWrapMech;
- sid->u.ssl3.keys.msIsWrapped =
- parsed_session_ticket->ms_is_wrapped;
- sid->u.ssl3.masterValid = PR_TRUE;
- sid->u.ssl3.keys.resumable = PR_TRUE;
-
- /* Copy over client cert from session ticket if there is one. */
- if (parsed_session_ticket->peer_cert.data != NULL) {
- if (sid->peerCert != NULL)
- CERT_DestroyCertificate(sid->peerCert);
- sid->peerCert = CERT_NewTempCertificate(ss->dbHandle,
- &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE);
- if (sid->peerCert == NULL) {
- rv = SECFailure;
- goto loser;
- }
- }
- if (parsed_session_ticket->srvName.data != NULL) {
- sid->u.ssl3.srvName = parsed_session_ticket->srvName;
- }
- ss->statelessResume = PR_TRUE;
- ss->sec.ci.sid = sid;
- }
- }
-
- if (0) {
-no_ticket:
- SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.",
- SSL_GETPID(), ss->fd));
- ssl3stats = SSL_GetStatistics();
- SSL_AtomicIncrementLong(& ssl3stats->hch_sid_ticket_parse_failures );
- }
- rv = SECSuccess;
-
-loser:
- /* ss->sec.ci.sid == sid if it did NOT come here via goto statement
- * in that case do not free sid
- */
- if (sid && (ss->sec.ci.sid != sid)) {
- ssl_FreeSID(sid);
- sid = NULL;
- }
- if (decrypted_state != NULL) {
- SECITEM_FreeItem(decrypted_state, PR_TRUE);
- decrypted_state = NULL;
- }
-
- if (parsed_session_ticket != NULL) {
- if (parsed_session_ticket->peer_cert.data) {
- SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE);
- }
- PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket));
- }
-
- return rv;
-}
-
-/*
- * Read bytes. Using this function means the SECItem structure
- * cannot be freed. The caller is expected to call this function
- * on a shallow copy of the structure.
- */
-static SECStatus
-ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes)
-{
- if (bytes > item->len)
- return SECFailure;
-
- *buf = item->data;
- item->data += bytes;
- item->len -= bytes;
- return SECSuccess;
-}
-
-static SECStatus
-ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data,
- EncryptedSessionTicket *enc_session_ticket)
-{
- if (ssl3_ConsumeFromItem(data, &enc_session_ticket->key_name,
- SESS_TICKET_KEY_NAME_LEN) != SECSuccess)
- return SECFailure;
- if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv,
- AES_BLOCK_SIZE) != SECSuccess)
- return SECFailure;
- if (ssl3_ConsumeHandshakeVariable(ss, &enc_session_ticket->encrypted_state,
- 2, &data->data, &data->len) != SECSuccess)
- return SECFailure;
- if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac,
- TLS_EX_SESS_TICKET_MAC_LENGTH) != SECSuccess)
- return SECFailure;
- if (data->len != 0) /* Make sure that we have consumed all bytes. */
- return SECFailure;
-
- return SECSuccess;
-}
-
-/* go through hello extensions in buffer "b".
- * For each one, find the extension handler in the table, and
- * if present, invoke that handler.
- * Servers ignore any extensions with unknown extension types.
- * Clients reject any extensions with unadvertised extension types.
- */
-SECStatus
-ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
-{
- const ssl3HelloExtensionHandler * handlers;
-
- if (ss->sec.isServer) {
- handlers = clientHelloHandlers;
- } else if (ss->version > SSL_LIBRARY_VERSION_3_0) {
- handlers = serverHelloHandlersTLS;
- } else {
- handlers = serverHelloHandlersSSL3;
- }
-
- while (*length) {
- const ssl3HelloExtensionHandler * handler;
- SECStatus rv;
- PRInt32 extension_type;
- SECItem extension_data;
-
- /* Get the extension's type field */
- extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length);
- if (extension_type < 0) /* failure to decode extension_type */
- return SECFailure; /* alert already sent */
-
- /* get the data for this extension, so we can pass it or skip it. */
- rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length);
- if (rv != SECSuccess)
- return rv;
-
- /* Check whether the server sent an extension which was not advertised
- * in the ClientHello.
- */
- if (!ss->sec.isServer &&
- !ssl3_ClientExtensionAdvertised(ss, extension_type))
- return SECFailure; /* TODO: send unsupported_extension alert */
-
- /* Check whether an extension has been sent multiple times. */
- if (ssl3_ExtensionNegotiated(ss, extension_type))
- return SECFailure;
-
- /* find extension_type in table of Hello Extension Handlers */
- for (handler = handlers; handler->ex_type >= 0; handler++) {
- /* if found, call this handler */
- if (handler->ex_type == extension_type) {
- rv = (*handler->ex_handler)(ss, (PRUint16)extension_type,
- &extension_data);
- /* Ignore this result */
- /* Treat all bad extensions as unrecognized types. */
- break;
- }
- }
- }
- return SECSuccess;
-}
-
-/* Add a callback function to the table of senders of server hello extensions.
- */
-SECStatus
-ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
- ssl3HelloExtensionSenderFunc cb)
-{
- int i;
- ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0];
-
- for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
- if (!sender->ex_sender) {
- sender->ex_type = ex_type;
- sender->ex_sender = cb;
- return SECSuccess;
- }
- /* detect duplicate senders */
- PORT_Assert(sender->ex_type != ex_type);
- if (sender->ex_type == ex_type) {
- /* duplicate */
- break;
- }
- }
- PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
-}
-
-/* call each of the extension senders and return the accumulated length */
-PRInt32
-ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
- const ssl3HelloExtensionSender *sender)
-{
- PRInt32 total_exten_len = 0;
- int i;
-
- if (!sender) {
- sender = ss->version > SSL_LIBRARY_VERSION_3_0 ?
- &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0];
- }
-
- for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) {
- if (sender->ex_sender) {
- PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
- if (extLen < 0)
- return -1;
- maxBytes -= extLen;
- total_exten_len += extLen;
- }
- }
- return total_exten_len;
-}
-
-
-/* Extension format:
- * Extension number: 2 bytes
- * Extension length: 2 bytes
- * Verify Data Length: 1 byte
- * Verify Data (TLS): 12 bytes (client) or 24 bytes (server)
- * Verify Data (SSL): 36 bytes (client) or 72 bytes (server)
- */
-static PRInt32
-ssl3_SendRenegotiationInfoXtn(
- sslSocket * ss,
- PRBool append,
- PRUint32 maxBytes)
-{
- PRInt32 len, needed;
-
- /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send
- * both the SCSV and the empty RI, so when we send SCSV in
- * the initial handshake, we don't also send RI.
- */
- if (!ss || ss->ssl3.hs.sendingSCSV)
- return 0;
- len = !ss->firstHsDone ? 0 :
- (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2
- : ss->ssl3.hs.finishedBytes);
- needed = 5 + len;
- if (append && maxBytes >= needed) {
- SECStatus rv;
- /* extension_type */
- rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);
- if (rv != SECSuccess) return -1;
- /* length of extension_data */
- rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2);
- if (rv != SECSuccess) return -1;
- /* verify_Data from previous Finished message(s) */
- rv = ssl3_AppendHandshakeVariable(ss,
- ss->ssl3.hs.finishedMsgs.data, len, 1);
- if (rv != SECSuccess) return -1;
- if (!ss->sec.isServer) {
- TLSExtensionData *xtnData = &ss->xtnData;
- xtnData->advertised[xtnData->numAdvertised++] =
- ssl_renegotiation_info_xtn;
- }
- }
- return needed;
-}
-
-static SECStatus
-ssl3_ServerHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type,
- SECItem *data)
-{
- SECStatus rv = SECSuccess;
- PRUint32 len = 0;
-
- /* remember that we got this extension. */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- PORT_Assert(ss->sec.isServer);
- /* prepare to send back the appropriate response */
- rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
- ssl3_ServerSendStatusRequestXtn);
- return rv;
-}
-
-/* This function runs in both the client and server. */
-static SECStatus
-ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
-{
- SECStatus rv = SECSuccess;
- PRUint32 len = 0;
-
- if (ss->firstHsDone) {
- len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes
- : ss->ssl3.hs.finishedBytes * 2;
- }
- if (data->len != 1 + len ||
- data->data[0] != len || (len &&
- NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
- data->data + 1, len))) {
- /* Can we do this here? Or, must we arrange for the caller to do it? */
- (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
- PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
- return SECFailure;
- }
- /* remember that we got this extension and it was correct. */
- ss->peerRequestedProtection = 1;
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type;
- if (ss->sec.isServer) {
- /* prepare to send back the appropriate response */
- rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type,
- ssl3_SendRenegotiationInfoXtn);
- }
- return rv;
-}
-
-static PRInt32
-ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes)
-{
- PRUint32 ext_data_len;
- PRInt16 i;
- SECStatus rv;
-
- if (!ss)
- return 0;
-
- if (!ss->sec.isServer) {
- /* Client side */
-
- if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount)
- return 0; /* Not relevant */
-
- ext_data_len = 2 + 2 * ss->ssl3.dtlsSRTPCipherCount + 1;
-
- if (append && maxBytes >= 4 + ext_data_len) {
- /* Extension type */
- rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
- if (rv != SECSuccess) return -1;
- /* Length of extension data */
- rv = ssl3_AppendHandshakeNumber(ss, ext_data_len, 2);
- if (rv != SECSuccess) return -1;
- /* Length of the SRTP cipher list */
- rv = ssl3_AppendHandshakeNumber(ss,
- 2 * ss->ssl3.dtlsSRTPCipherCount,
- 2);
- if (rv != SECSuccess) return -1;
- /* The SRTP ciphers */
- for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
- rv = ssl3_AppendHandshakeNumber(ss,
- ss->ssl3.dtlsSRTPCiphers[i],
- 2);
- }
- /* Empty MKI value */
- ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
-
- ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
- ssl_use_srtp_xtn;
- }
-
- return 4 + ext_data_len;
- }
-
- /* Server side */
- if (append && maxBytes >= 9) {
- /* Extension type */
- rv = ssl3_AppendHandshakeNumber(ss, ssl_use_srtp_xtn, 2);
- if (rv != SECSuccess) return -1;
- /* Length of extension data */
- rv = ssl3_AppendHandshakeNumber(ss, 5, 2);
- if (rv != SECSuccess) return -1;
- /* Length of the SRTP cipher list */
- rv = ssl3_AppendHandshakeNumber(ss, 2, 2);
- if (rv != SECSuccess) return -1;
- /* The selected cipher */
- rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.dtlsSRTPCipherSuite, 2);
- if (rv != SECSuccess) return -1;
- /* Empty MKI value */
- ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);
- }
-
- return 9;
-}
-
-static SECStatus
-ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
-{
- SECStatus rv;
- SECItem ciphers = {siBuffer, NULL, 0};
- PRUint16 i;
- unsigned int j;
- PRUint16 cipher = 0;
- PRBool found = PR_FALSE;
- SECItem litem;
-
- if (!ss->sec.isServer) {
- /* Client side */
- if (!data->data || !data->len) {
- /* malformed */
- return SECFailure;
- }
-
- /* Get the cipher list */
- rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
- &data->data, &data->len);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* Now check that the number of ciphers listed is 1 (len = 2) */
- if (ciphers.len != 2) {
- return SECFailure;
- }
-
- /* Get the selected cipher */
- cipher = (ciphers.data[0] << 8) | ciphers.data[1];
-
- /* Now check that this is one of the ciphers we offered */
- for (i = 0; i < ss->ssl3.dtlsSRTPCipherCount; i++) {
- if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
- found = PR_TRUE;
- break;
- }
- }
-
- if (!found) {
- return SECFailure;
- }
-
- /* Get the srtp_mki value */
- rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1,
- &data->data, &data->len);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
- /* We didn't offer an MKI, so this must be 0 length */
- /* XXX RFC 5764 Section 4.1.3 says:
- * If the client detects a nonzero-length MKI in the server's
- * response that is different than the one the client offered,
- * then the client MUST abort the handshake and SHOULD send an
- * invalid_parameter alert.
- *
- * Due to a limitation of the ssl3_HandleHelloExtensions function,
- * returning SECFailure here won't abort the handshake. It will
- * merely cause the use_srtp extension to be not negotiated. We
- * should fix this. See NSS bug 753136.
- */
- if (litem.len != 0) {
- return SECFailure;
- }
-
- if (data->len != 0) {
- /* malformed */
- return SECFailure;
- }
-
- /* OK, this looks fine. */
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
- ss->ssl3.dtlsSRTPCipherSuite = cipher;
- return SECSuccess;
- }
-
- /* Server side */
- if (!IS_DTLS(ss) || !ss->ssl3.dtlsSRTPCipherCount) {
- /* Ignore the extension if we aren't doing DTLS or no DTLS-SRTP
- * preferences have been set. */
- return SECSuccess;
- }
-
- if (!data->data || data->len < 5) {
- /* malformed */
- return SECFailure;
- }
-
- /* Get the cipher list */
- rv = ssl3_ConsumeHandshakeVariable(ss, &ciphers, 2,
- &data->data, &data->len);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- /* Check that the list is even length */
- if (ciphers.len % 2) {
- return SECFailure;
- }
-
- /* Walk through the offered list and pick the most preferred of our
- * ciphers, if any */
- for (i = 0; !found && i < ss->ssl3.dtlsSRTPCipherCount; i++) {
- for (j = 0; j + 1 < ciphers.len; j += 2) {
- cipher = (ciphers.data[j] << 8) | ciphers.data[j + 1];
- if (cipher == ss->ssl3.dtlsSRTPCiphers[i]) {
- found = PR_TRUE;
- break;
- }
- }
- }
-
- /* Get the srtp_mki value */
- rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 1, &data->data, &data->len);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
- if (data->len != 0) {
- return SECFailure; /* Malformed */
- }
-
- /* Now figure out what to do */
- if (!found) {
- /* No matching ciphers */
- return SECSuccess;
- }
-
- /* OK, we have a valid cipher and we've selected it */
- ss->ssl3.dtlsSRTPCipherSuite = cipher;
- ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_use_srtp_xtn;
-
- return ssl3_RegisterServerHelloExtensionSender(ss, ssl_use_srtp_xtn,
- ssl3_SendUseSRTPXtn);
-}
diff --git a/security/nss/lib/ssl/ssl3gthr.c b/security/nss/lib/ssl/ssl3gthr.c
deleted file mode 100644
index 48886e10f..000000000
--- a/security/nss/lib/ssl/ssl3gthr.c
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Gather (Read) entire SSL3 records from socket into buffer.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "ssl3prot.h"
-
-/*
- * Attempt to read in an entire SSL3 record.
- * Blocks here for blocking sockets, otherwise returns -1 with
- * PR_WOULD_BLOCK_ERROR when socket would block.
- *
- * returns 1 if received a complete SSL3 record.
- * returns 0 if recv returns EOF
- * returns -1 if recv returns < 0
- * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
- *
- * Caller must hold the recv buf lock.
- *
- * The Gather state machine has 3 states: GS_INIT, GS_HEADER, GS_DATA.
- * GS_HEADER: waiting for the 5-byte SSL3 record header to come in.
- * GS_DATA: waiting for the body of the SSL3 record to come in.
- *
- * This loop returns when either
- * (a) an error or EOF occurs,
- * (b) PR_WOULD_BLOCK_ERROR,
- * (c) data (entire SSL3 record) has been received.
- */
-static int
-ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
-{
- unsigned char *bp;
- unsigned char *lbp;
- int nb;
- int err;
- int rv = 1;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- if (gs->state == GS_INIT) {
- gs->state = GS_HEADER;
- gs->remainder = 5;
- gs->offset = 0;
- gs->writeOffset = 0;
- gs->readOffset = 0;
- gs->inbuf.len = 0;
- }
-
- lbp = gs->inbuf.buf;
- for(;;) {
- SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)",
- SSL_GETPID(), ss->fd, gs->state, gs->remainder));
- bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset;
- nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
-
- if (nb > 0) {
- PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
- } else if (nb == 0) {
- /* EOF */
- SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
- rv = 0;
- break;
- } else /* if (nb < 0) */ {
- SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
- PR_GetError()));
- rv = SECFailure;
- break;
- }
-
- PORT_Assert( nb <= gs->remainder );
- if (nb > gs->remainder) {
- /* ssl_DefRecv is misbehaving! this error is fatal to SSL. */
- gs->state = GS_INIT; /* so we don't crash next time */
- rv = SECFailure;
- break;
- }
-
- gs->offset += nb;
- gs->remainder -= nb;
- if (gs->state == GS_DATA)
- gs->inbuf.len += nb;
-
- /* if there's more to go, read some more. */
- if (gs->remainder > 0) {
- continue;
- }
-
- /* have received entire record header, or entire record. */
- switch (gs->state) {
- case GS_HEADER:
- /*
- ** Have received SSL3 record header in gs->hdr.
- ** Now extract the length of the following encrypted data,
- ** and then read in the rest of the SSL3 record into gs->inbuf.
- */
- gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
-
- /* This is the max fragment length for an encrypted fragment
- ** plus the size of the record header.
- */
- if(gs->remainder > (MAX_FRAGMENT_LENGTH + 2048 + 5)) {
- SSL3_SendAlert(ss, alert_fatal, unexpected_message);
- gs->state = GS_INIT;
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- return SECFailure;
- }
-
- gs->state = GS_DATA;
- gs->offset = 0;
- gs->inbuf.len = 0;
-
- if (gs->remainder > gs->inbuf.space) {
- err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
- if (err) { /* realloc has set error code to no mem. */
- return err;
- }
- lbp = gs->inbuf.buf;
- }
- break; /* End this case. Continue around the loop. */
-
-
- case GS_DATA:
- /*
- ** SSL3 record has been completely received.
- */
- gs->state = GS_INIT;
- return 1;
- }
- }
-
- return rv;
-}
-
-/*
- * Read in an entire DTLS record.
- *
- * Blocks here for blocking sockets, otherwise returns -1 with
- * PR_WOULD_BLOCK_ERROR when socket would block.
- *
- * This is simpler than SSL because we are reading on a datagram socket
- * and datagrams must contain >=1 complete records.
- *
- * returns 1 if received a complete DTLS record.
- * returns 0 if recv returns EOF
- * returns -1 if recv returns < 0
- * (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
- *
- * Caller must hold the recv buf lock.
- *
- * This loop returns when either
- * (a) an error or EOF occurs,
- * (b) PR_WOULD_BLOCK_ERROR,
- * (c) data (entire DTLS record) has been received.
- */
-static int
-dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
-{
- int nb;
- int err;
- int rv = 1;
-
- SSL_TRC(30, ("dtls_GatherData"));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
-
- gs->state = GS_HEADER;
- gs->offset = 0;
-
- if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */
- gs->dtlsPacketOffset = 0;
- gs->dtlsPacket.len = 0;
-
- /* Resize to the maximum possible size so we can fit a full datagram */
- /* This is the max fragment length for an encrypted fragment
- ** plus the size of the record header.
- ** This magic constant is copied from ssl3_GatherData, with 5 changed
- ** to 13 (the size of the record header).
- */
- if (gs->dtlsPacket.space < MAX_FRAGMENT_LENGTH + 2048 + 13) {
- err = sslBuffer_Grow(&gs->dtlsPacket,
- MAX_FRAGMENT_LENGTH + 2048 + 13);
- if (err) { /* realloc has set error code to no mem. */
- return err;
- }
- }
-
- /* recv() needs to read a full datagram at a time */
- nb = ssl_DefRecv(ss, gs->dtlsPacket.buf, gs->dtlsPacket.space, flags);
-
- if (nb > 0) {
- PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb));
- } else if (nb == 0) {
- /* EOF */
- SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
- rv = 0;
- return rv;
- } else /* if (nb < 0) */ {
- SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
- PR_GetError()));
- rv = SECFailure;
- return rv;
- }
-
- gs->dtlsPacket.len = nb;
- }
-
- /* At this point we should have >=1 complete records lined up in
- * dtlsPacket. Read off the header.
- */
- if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < 13) {
- SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet "
- "too short to contain header", SSL_GETPID(), ss->fd));
- PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
- gs->dtlsPacketOffset = 0;
- gs->dtlsPacket.len = 0;
- rv = SECFailure;
- return rv;
- }
- memcpy(gs->hdr, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 13);
- gs->dtlsPacketOffset += 13;
-
- /* Have received SSL3 record header in gs->hdr. */
- gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12];
-
- if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < gs->remainder) {
- SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short "
- "to contain rest of body", SSL_GETPID(), ss->fd));
- PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
- gs->dtlsPacketOffset = 0;
- gs->dtlsPacket.len = 0;
- rv = SECFailure;
- return rv;
- }
-
- /* OK, we have at least one complete packet, copy into inbuf */
- if (gs->remainder > gs->inbuf.space) {
- err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
- if (err) { /* realloc has set error code to no mem. */
- return err;
- }
- }
-
- memcpy(gs->inbuf.buf, gs->dtlsPacket.buf + gs->dtlsPacketOffset,
- gs->remainder);
- gs->inbuf.len = gs->remainder;
- gs->offset = gs->remainder;
- gs->dtlsPacketOffset += gs->remainder;
- gs->state = GS_INIT;
-
- return 1;
-}
-
-/* Gather in a record and when complete, Handle that record.
- * Repeat this until the handshake is complete,
- * or until application data is available.
- *
- * Returns 1 when the handshake is completed without error, or
- * application data is available.
- * Returns 0 if ssl3_GatherData hits EOF.
- * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
- * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
- *
- * Called from ssl_GatherRecord1stHandshake in sslcon.c,
- * and from SSL_ForceHandshake in sslsecur.c
- * and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
- *
- * Caller must hold the recv buf lock.
- */
-int
-ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
-{
- SSL3Ciphertext cText;
- int rv;
- PRBool canFalseStart = PR_FALSE;
-
- SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- do {
- /* Without this, we may end up wrongly reporting
- * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
- * peer while we are waiting to be restarted.
- */
- ssl_GetSSL3HandshakeLock(ss);
- rv = ss->ssl3.hs.restartTarget == NULL ? SECSuccess : SECFailure;
- ssl_ReleaseSSL3HandshakeLock(ss);
- if (rv != SECSuccess) {
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- return (int) SECFailure;
- }
-
- /* Treat an empty msgState like a NULL msgState. (Most of the time
- * when ssl3_HandleHandshake returns SECWouldBlock, it leaves
- * behind a non-NULL but zero-length msgState).
- * Test: async_cert_restart_server_sends_hello_request_first_in_separate_record
- */
- if (ss->ssl3.hs.msgState.buf != NULL) {
- if (ss->ssl3.hs.msgState.len == 0) {
- ss->ssl3.hs.msgState.buf = NULL;
- }
- }
-
- if (ss->ssl3.hs.msgState.buf != NULL) {
- /* ssl3_HandleHandshake previously returned SECWouldBlock and the
- * as-yet-unprocessed plaintext of that previous handshake record.
- * We need to process it now before we overwrite it with the next
- * handshake record.
- */
- rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
- } else {
- /* bring in the next sslv3 record. */
- if (!IS_DTLS(ss)) {
- rv = ssl3_GatherData(ss, &ss->gs, flags);
- } else {
- rv = dtls_GatherData(ss, &ss->gs, flags);
-
- /* If we got a would block error, that means that no data was
- * available, so we check the timer to see if it's time to
- * retransmit */
- if (rv == SECFailure &&
- (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
- ssl_GetSSL3HandshakeLock(ss);
- dtls_CheckTimer(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
- /* Restore the error in case something succeeded */
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- }
- }
-
- if (rv <= 0) {
- return rv;
- }
-
- /* decipher it, and handle it if it's a handshake.
- * If it's application data, ss->gs.buf will not be empty upon return.
- * If it's a change cipher spec, alert, or handshake message,
- * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
- */
- cText.type = (SSL3ContentType)ss->gs.hdr[0];
- cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
-
- if (IS_DTLS(ss)) {
- int i;
-
- cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
- /* DTLS sequence number */
- cText.seq_num.high = 0; cText.seq_num.low = 0;
- for (i = 0; i < 4; i++) {
- cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
- cText.seq_num.high |= ss->gs.hdr[3 + i];
- cText.seq_num.low |= ss->gs.hdr[7 + i];
- }
- }
-
- cText.buf = &ss->gs.inbuf;
- rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
- }
- if (rv < 0) {
- return ss->recvdCloseNotify ? 0 : rv;
- }
-
- /* If we kicked off a false start in ssl3_HandleServerHelloDone, break
- * out of this loop early without finishing the handshake.
- */
- if (ss->opt.enableFalseStart) {
- ssl_GetSSL3HandshakeLock(ss);
- canFalseStart = (ss->ssl3.hs.ws == wait_change_cipher ||
- ss->ssl3.hs.ws == wait_new_session_ticket) &&
- ssl3_CanFalseStart(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
- }
- } while (ss->ssl3.hs.ws != idle_handshake &&
- !canFalseStart &&
- ss->gs.buf.len == 0);
-
- ss->gs.readOffset = 0;
- ss->gs.writeOffset = ss->gs.buf.len;
- return 1;
-}
-
-/* Repeatedly gather in a record and when complete, Handle that record.
- * Repeat this until some application data is received.
- *
- * Returns 1 when application data is available.
- * Returns 0 if ssl3_GatherData hits EOF.
- * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
- * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
- *
- * Called from DoRecv in sslsecur.c
- * Caller must hold the recv buf lock.
- */
-int
-ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
-{
- int rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- do {
- rv = ssl3_GatherCompleteHandshake(ss, flags);
- } while (rv > 0 && ss->gs.buf.len == 0);
-
- return rv;
-}
diff --git a/security/nss/lib/ssl/ssl3prot.h b/security/nss/lib/ssl/ssl3prot.h
deleted file mode 100644
index aabf1403f..000000000
--- a/security/nss/lib/ssl/ssl3prot.h
+++ /dev/null
@@ -1,323 +0,0 @@
-/* Private header file of libSSL.
- * Various and sundry protocol constants. DON'T CHANGE THESE. These
- * values are defined by the SSL 3.0 protocol specification.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef __ssl3proto_h_
-#define __ssl3proto_h_
-
-typedef uint8 SSL3Opaque;
-
-typedef uint16 SSL3ProtocolVersion;
-/* version numbers are defined in sslproto.h */
-
-typedef uint16 ssl3CipherSuite;
-/* The cipher suites are defined in sslproto.h */
-
-#define MAX_CERT_TYPES 10
-#define MAX_COMPRESSION_METHODS 10
-#define MAX_MAC_LENGTH 64
-#define MAX_PADDING_LENGTH 64
-#define MAX_KEY_LENGTH 64
-#define EXPORT_KEY_LENGTH 5
-#define SSL3_RANDOM_LENGTH 32
-
-#define SSL3_RECORD_HEADER_LENGTH 5
-
-/* SSL3_RECORD_HEADER_LENGTH + epoch/sequence_number */
-#define DTLS_RECORD_HEADER_LENGTH 13
-
-#define MAX_FRAGMENT_LENGTH 16384
-
-typedef enum {
- content_change_cipher_spec = 20,
- content_alert = 21,
- content_handshake = 22,
- content_application_data = 23
-} SSL3ContentType;
-
-typedef struct {
- SSL3ContentType type;
- SSL3ProtocolVersion version;
- uint16 length;
- SECItem fragment;
-} SSL3Plaintext;
-
-typedef struct {
- SSL3ContentType type;
- SSL3ProtocolVersion version;
- uint16 length;
- SECItem fragment;
-} SSL3Compressed;
-
-typedef struct {
- SECItem content;
- SSL3Opaque MAC[MAX_MAC_LENGTH];
-} SSL3GenericStreamCipher;
-
-typedef struct {
- SECItem content;
- SSL3Opaque MAC[MAX_MAC_LENGTH];
- uint8 padding[MAX_PADDING_LENGTH];
- uint8 padding_length;
-} SSL3GenericBlockCipher;
-
-typedef enum { change_cipher_spec_choice = 1 } SSL3ChangeCipherSpecChoice;
-
-typedef struct {
- SSL3ChangeCipherSpecChoice choice;
-} SSL3ChangeCipherSpec;
-
-typedef enum { alert_warning = 1, alert_fatal = 2 } SSL3AlertLevel;
-
-typedef enum {
- close_notify = 0,
- unexpected_message = 10,
- bad_record_mac = 20,
- decryption_failed_RESERVED = 21, /* do not send; see RFC 5246 */
- record_overflow = 22, /* TLS only */
- decompression_failure = 30,
- handshake_failure = 40,
- no_certificate = 41, /* SSL3 only, NOT TLS */
- bad_certificate = 42,
- unsupported_certificate = 43,
- certificate_revoked = 44,
- certificate_expired = 45,
- certificate_unknown = 46,
- illegal_parameter = 47,
-
-/* All alerts below are TLS only. */
- unknown_ca = 48,
- access_denied = 49,
- decode_error = 50,
- decrypt_error = 51,
- export_restriction = 60,
- protocol_version = 70,
- insufficient_security = 71,
- internal_error = 80,
- user_canceled = 90,
- no_renegotiation = 100,
-
-/* Alerts for client hello extensions */
- unsupported_extension = 110,
- certificate_unobtainable = 111,
- unrecognized_name = 112,
- bad_certificate_status_response = 113,
- bad_certificate_hash_value = 114
-
-} SSL3AlertDescription;
-
-typedef struct {
- SSL3AlertLevel level;
- SSL3AlertDescription description;
-} SSL3Alert;
-
-typedef enum {
- hello_request = 0,
- client_hello = 1,
- server_hello = 2,
- hello_verify_request = 3,
- new_session_ticket = 4,
- certificate = 11,
- server_key_exchange = 12,
- certificate_request = 13,
- server_hello_done = 14,
- certificate_verify = 15,
- client_key_exchange = 16,
- finished = 20,
- certificate_status = 22,
- next_proto = 67
-} SSL3HandshakeType;
-
-typedef struct {
- uint8 empty;
-} SSL3HelloRequest;
-
-typedef struct {
- SSL3Opaque rand[SSL3_RANDOM_LENGTH];
-} SSL3Random;
-
-typedef struct {
- SSL3Opaque id[32];
- uint8 length;
-} SSL3SessionID;
-
-typedef struct {
- SSL3ProtocolVersion client_version;
- SSL3Random random;
- SSL3SessionID session_id;
- SECItem cipher_suites;
- uint8 cm_count;
- SSLCompressionMethod compression_methods[MAX_COMPRESSION_METHODS];
-} SSL3ClientHello;
-
-typedef struct {
- SSL3ProtocolVersion server_version;
- SSL3Random random;
- SSL3SessionID session_id;
- ssl3CipherSuite cipher_suite;
- SSLCompressionMethod compression_method;
-} SSL3ServerHello;
-
-typedef struct {
- SECItem list;
-} SSL3Certificate;
-
-/* SSL3SignType moved to ssl.h */
-
-/* The SSL key exchange method used */
-typedef enum {
- kea_null,
- kea_rsa,
- kea_rsa_export,
- kea_rsa_export_1024,
- kea_dh_dss,
- kea_dh_dss_export,
- kea_dh_rsa,
- kea_dh_rsa_export,
- kea_dhe_dss,
- kea_dhe_dss_export,
- kea_dhe_rsa,
- kea_dhe_rsa_export,
- kea_dh_anon,
- kea_dh_anon_export,
- kea_rsa_fips,
- kea_ecdh_ecdsa,
- kea_ecdhe_ecdsa,
- kea_ecdh_rsa,
- kea_ecdhe_rsa,
- kea_ecdh_anon
-} SSL3KeyExchangeAlgorithm;
-
-typedef struct {
- SECItem modulus;
- SECItem exponent;
-} SSL3ServerRSAParams;
-
-typedef struct {
- SECItem p;
- SECItem g;
- SECItem Ys;
-} SSL3ServerDHParams;
-
-typedef struct {
- union {
- SSL3ServerDHParams dh;
- SSL3ServerRSAParams rsa;
- } u;
-} SSL3ServerParams;
-
-typedef struct {
- uint8 md5[16];
- uint8 sha[20];
-} SSL3Hashes;
-
-typedef struct {
- union {
- SSL3Opaque anonymous;
- SSL3Hashes certified;
- } u;
-} SSL3ServerKeyExchange;
-
-typedef enum {
- ct_RSA_sign = 1,
- ct_DSS_sign = 2,
- ct_RSA_fixed_DH = 3,
- ct_DSS_fixed_DH = 4,
- ct_RSA_ephemeral_DH = 5,
- ct_DSS_ephemeral_DH = 6,
- ct_ECDSA_sign = 64,
- ct_RSA_fixed_ECDH = 65,
- ct_ECDSA_fixed_ECDH = 66
-
-} SSL3ClientCertificateType;
-
-typedef SECItem *SSL3DistinquishedName;
-
-typedef struct {
- SSL3Opaque client_version[2];
- SSL3Opaque random[46];
-} SSL3RSAPreMasterSecret;
-
-typedef SECItem SSL3EncryptedPreMasterSecret;
-
-
-typedef SSL3Opaque SSL3MasterSecret[48];
-
-typedef enum { implicit, explicit } SSL3PublicValueEncoding;
-
-typedef struct {
- union {
- SSL3Opaque implicit;
- SECItem explicit;
- } dh_public;
-} SSL3ClientDiffieHellmanPublic;
-
-typedef struct {
- union {
- SSL3EncryptedPreMasterSecret rsa;
- SSL3ClientDiffieHellmanPublic diffie_helman;
- } exchange_keys;
-} SSL3ClientKeyExchange;
-
-typedef SSL3Hashes SSL3PreSignedCertificateVerify;
-
-typedef SECItem SSL3CertificateVerify;
-
-typedef enum {
- sender_client = 0x434c4e54,
- sender_server = 0x53525652
-} SSL3Sender;
-
-typedef SSL3Hashes SSL3Finished;
-
-typedef struct {
- SSL3Opaque verify_data[12];
-} TLSFinished;
-
-/*
- * TLS extension related data structures and constants.
- */
-
-/* SessionTicket extension related data structures. */
-
-/* NewSessionTicket handshake message. */
-typedef struct {
- uint32 received_timestamp;
- uint32 ticket_lifetime_hint;
- SECItem ticket;
-} NewSessionTicket;
-
-typedef enum {
- CLIENT_AUTH_ANONYMOUS = 0,
- CLIENT_AUTH_CERTIFICATE = 1
-} ClientAuthenticationType;
-
-typedef struct {
- ClientAuthenticationType client_auth_type;
- union {
- SSL3Opaque *certificate_list;
- } identity;
-} ClientIdentity;
-
-#define SESS_TICKET_KEY_NAME_LEN 16
-#define SESS_TICKET_KEY_NAME_PREFIX "NSS!"
-#define SESS_TICKET_KEY_NAME_PREFIX_LEN 4
-#define SESS_TICKET_KEY_VAR_NAME_LEN 12
-
-typedef struct {
- unsigned char *key_name;
- unsigned char *iv;
- SECItem encrypted_state;
- unsigned char *mac;
-} EncryptedSessionTicket;
-
-#define TLS_EX_SESS_TICKET_MAC_LENGTH 32
-
-#define TLS_STE_NO_SERVER_NAME -1
-
-#endif /* __ssl3proto_h_ */
diff --git a/security/nss/lib/ssl/sslauth.c b/security/nss/lib/ssl/sslauth.c
deleted file mode 100644
index e83e351cd..000000000
--- a/security/nss/lib/ssl/sslauth.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#include "cert.h"
-#include "secitem.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "pk11func.h"
-#include "ocsp.h"
-
-/* NEED LOCKS IN HERE. */
-CERTCertificate *
-SSL_PeerCertificate(PRFileDesc *fd)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
- SSL_GETPID(), fd));
- return 0;
- }
- if (ss->opt.useSecurity && ss->sec.peerCert) {
- return CERT_DupCertificate(ss->sec.peerCert);
- }
- return 0;
-}
-
-/* NEED LOCKS IN HERE. */
-CERTCertificate *
-SSL_LocalCertificate(PRFileDesc *fd)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
- SSL_GETPID(), fd));
- return NULL;
- }
- if (ss->opt.useSecurity) {
- if (ss->sec.localCert) {
- return CERT_DupCertificate(ss->sec.localCert);
- }
- if (ss->sec.ci.sid && ss->sec.ci.sid->localCert) {
- return CERT_DupCertificate(ss->sec.ci.sid->localCert);
- }
- }
- return NULL;
-}
-
-
-
-/* NEED LOCKS IN HERE. */
-SECStatus
-SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
- char **ip, char **sp)
-{
- sslSocket *ss;
- const char *cipherName;
- PRBool isDes = PR_FALSE;
- PRBool enoughFirstHsDone = PR_FALSE;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (cp) *cp = 0;
- if (kp0) *kp0 = 0;
- if (kp1) *kp1 = 0;
- if (ip) *ip = 0;
- if (sp) *sp = 0;
- if (op) {
- *op = SSL_SECURITY_STATUS_OFF;
- }
-
- if (ss->firstHsDone) {
- enoughFirstHsDone = PR_TRUE;
- } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
- ssl3_CanFalseStart(ss)) {
- enoughFirstHsDone = PR_TRUE;
- }
-
- if (ss->opt.useSecurity && enoughFirstHsDone) {
- if (ss->version < SSL_LIBRARY_VERSION_3_0) {
- cipherName = ssl_cipherName[ss->sec.cipherType];
- } else {
- cipherName = ssl3_cipherName[ss->sec.cipherType];
- }
- PORT_Assert(cipherName);
- if (cipherName) {
- if (PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE;
-
- if (cp) {
- *cp = PORT_Strdup(cipherName);
- }
- }
-
- if (kp0) {
- *kp0 = ss->sec.keyBits;
- if (isDes) *kp0 = (*kp0 * 7) / 8;
- }
- if (kp1) {
- *kp1 = ss->sec.secretKeyBits;
- if (isDes) *kp1 = (*kp1 * 7) / 8;
- }
- if (op) {
- if (ss->sec.keyBits == 0) {
- *op = SSL_SECURITY_STATUS_OFF;
- } else if (ss->sec.secretKeyBits < 90) {
- *op = SSL_SECURITY_STATUS_ON_LOW;
-
- } else {
- *op = SSL_SECURITY_STATUS_ON_HIGH;
- }
- }
-
- if (ip || sp) {
- CERTCertificate *cert;
-
- cert = ss->sec.peerCert;
- if (cert) {
- if (ip) {
- *ip = CERT_NameToAscii(&cert->issuer);
- }
- if (sp) {
- *sp = CERT_NameToAscii(&cert->subject);
- }
- } else {
- if (ip) {
- *ip = PORT_Strdup("no certificate");
- }
- if (sp) {
- *sp = PORT_Strdup("no certificate");
- }
- }
- }
- }
-
- return SECSuccess;
-}
-
-/************************************************************************/
-
-/* NEED LOCKS IN HERE. */
-SECStatus
-SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook",
- SSL_GETPID(), s));
- return SECFailure;
- }
-
- ss->authCertificate = func;
- ss->authCertificateArg = arg;
-
- return SECSuccess;
-}
-
-/* NEED LOCKS IN HERE. */
-SECStatus
-SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
- void *arg)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
- SSL_GETPID(), s));
- return SECFailure;
- }
-
- ss->getClientAuthData = func;
- ss->getClientAuthDataArg = arg;
- return SECSuccess;
-}
-
-/* NEED LOCKS IN HERE. */
-SECStatus
-SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
- SSL_GETPID(), s));
- return SECFailure;
- }
-
- ss->pkcs11PinArg = arg;
- return SECSuccess;
-}
-
-
-/* This is the "default" authCert callback function. It is called when a
- * certificate message is received from the peer and the local application
- * has not registered an authCert callback function.
- */
-SECStatus
-SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
-{
- SECStatus rv;
- CERTCertDBHandle * handle;
- sslSocket * ss;
- SECCertUsage certUsage;
- const char * hostname = NULL;
- PRTime now = PR_Now();
- SECItemArray *certStatusArray;
- unsigned int i;
-
- ss = ssl_FindSocket(fd);
- PORT_Assert(ss != NULL);
- if (!ss) {
- return SECFailure;
- }
-
- handle = (CERTCertDBHandle *)arg;
- certStatusArray = &ss->sec.ci.sid->peerCertStatus;
-
- for (i = 0; i < certStatusArray->len; ++i) {
- CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert,
- now, &certStatusArray->items[i], arg);
- }
-
- /* this may seem backwards, but isn't. */
- certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
-
- rv = CERT_VerifyCert(handle, ss->sec.peerCert, checkSig, certUsage,
- now, ss->pkcs11PinArg, NULL);
-
- if ( rv != SECSuccess || isServer )
- return rv;
-
- /* cert is OK. This is the client side of an SSL connection.
- * Now check the name field in the cert against the desired hostname.
- * NB: This is our only defense against Man-In-The-Middle (MITM) attacks!
- */
- hostname = ss->url;
- if (hostname && hostname[0])
- rv = CERT_VerifyCertName(ss->sec.peerCert, hostname);
- else
- rv = SECFailure;
- if (rv != SECSuccess)
- PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
-
- return rv;
-}
diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c
deleted file mode 100644
index 419366e9d..000000000
--- a/security/nss/lib/ssl/sslcon.c
+++ /dev/null
@@ -1,3697 +0,0 @@
-/*
- * SSL v2 handshake functions, and functions common to SSL2 and SSL3.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "nssrenam.h"
-#include "cert.h"
-#include "secitem.h"
-#include "sechash.h"
-#include "cryptohi.h" /* for SGN_ funcs */
-#include "keyhi.h" /* for SECKEY_ high level functions. */
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "ssl3prot.h"
-#include "sslerr.h"
-#include "pk11func.h"
-#include "prinit.h"
-#include "prtime.h" /* for PR_Now() */
-
-#define XXX
-static PRBool policyWasSet;
-
-/* This ordered list is indexed by (SSL_CK_xx * 3) */
-/* Second and third bytes are MSB and LSB of master key length. */
-static const PRUint8 allCipherSuites[] = {
- 0, 0, 0,
- SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80,
- SSL_CK_IDEA_128_CBC_WITH_MD5, 0x00, 0x80,
- SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40,
- SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0,
- 0, 0, 0
-};
-
-#define ssl2_NUM_SUITES_IMPLEMENTED 6
-
-/* This list is sent back to the client when the client-hello message
- * contains no overlapping ciphers, so the client can report what ciphers
- * are supported by the server. Unlike allCipherSuites (above), this list
- * is sorted by descending preference, not by cipherSuite number.
- */
-static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] = {
- SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80,
- SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0,
- SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40,
- SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80,
- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80
-};
-
-typedef struct ssl2SpecsStr {
- PRUint8 nkm; /* do this many hashes to generate key material. */
- PRUint8 nkd; /* size of readKey and writeKey in bytes. */
- PRUint8 blockSize;
- PRUint8 blockShift;
- CK_MECHANISM_TYPE mechanism;
- PRUint8 keyLen; /* cipher symkey size in bytes. */
- PRUint8 pubLen; /* publicly reveal this many bytes of key. */
- PRUint8 ivLen; /* length of IV data at *ca. */
-} ssl2Specs;
-
-static const ssl2Specs ssl_Specs[] = {
-/* NONE */
- { 0, 0, 0, 0, },
-/* SSL_CK_RC4_128_WITH_MD5 */
- { 2, 16, 1, 0, CKM_RC4, 16, 0, 0, },
-/* SSL_CK_RC4_128_EXPORT40_WITH_MD5 */
- { 2, 16, 1, 0, CKM_RC4, 16, 11, 0, },
-/* SSL_CK_RC2_128_CBC_WITH_MD5 */
- { 2, 16, 8, 3, CKM_RC2_CBC, 16, 0, 8, },
-/* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 */
- { 2, 16, 8, 3, CKM_RC2_CBC, 16, 11, 8, },
-/* SSL_CK_IDEA_128_CBC_WITH_MD5 */
- { 0, 0, 0, 0, },
-/* SSL_CK_DES_64_CBC_WITH_MD5 */
- { 1, 8, 8, 3, CKM_DES_CBC, 8, 0, 8, },
-/* SSL_CK_DES_192_EDE3_CBC_WITH_MD5 */
- { 3, 24, 8, 3, CKM_DES3_CBC, 24, 0, 8, },
-};
-
-#define SET_ERROR_CODE /* reminder */
-#define TEST_FOR_FAILURE /* reminder */
-
-/*
-** Put a string tag in the library so that we can examine an executable
-** and see what kind of security it supports.
-*/
-const char *ssl_version = "SECURITY_VERSION:"
- " +us"
- " +export"
-#ifdef TRACE
- " +trace"
-#endif
-#ifdef DEBUG
- " +debug"
-#endif
- ;
-
-const char * const ssl_cipherName[] = {
- "unknown",
- "RC4",
- "RC4-Export",
- "RC2-CBC",
- "RC2-CBC-Export",
- "IDEA-CBC",
- "DES-CBC",
- "DES-EDE3-CBC",
- "unknown",
- "unknown", /* was fortezza, NO LONGER USED */
-};
-
-
-/* bit-masks, showing which SSLv2 suites are allowed.
- * lsb corresponds to first cipher suite in allCipherSuites[].
- */
-static PRUint16 allowedByPolicy; /* all off by default */
-static PRUint16 maybeAllowedByPolicy; /* all off by default */
-static PRUint16 chosenPreference = 0xff; /* all on by default */
-
-/* bit values for the above two bit masks */
-#define SSL_CB_RC4_128_WITH_MD5 (1 << SSL_CK_RC4_128_WITH_MD5)
-#define SSL_CB_RC4_128_EXPORT40_WITH_MD5 (1 << SSL_CK_RC4_128_EXPORT40_WITH_MD5)
-#define SSL_CB_RC2_128_CBC_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_WITH_MD5)
-#define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)
-#define SSL_CB_IDEA_128_CBC_WITH_MD5 (1 << SSL_CK_IDEA_128_CBC_WITH_MD5)
-#define SSL_CB_DES_64_CBC_WITH_MD5 (1 << SSL_CK_DES_64_CBC_WITH_MD5)
-#define SSL_CB_DES_192_EDE3_CBC_WITH_MD5 (1 << SSL_CK_DES_192_EDE3_CBC_WITH_MD5)
-#define SSL_CB_IMPLEMENTED \
- (SSL_CB_RC4_128_WITH_MD5 | \
- SSL_CB_RC4_128_EXPORT40_WITH_MD5 | \
- SSL_CB_RC2_128_CBC_WITH_MD5 | \
- SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \
- SSL_CB_DES_64_CBC_WITH_MD5 | \
- SSL_CB_DES_192_EDE3_CBC_WITH_MD5)
-
-
-/* Construct a socket's list of cipher specs from the global default values.
- */
-static SECStatus
-ssl2_ConstructCipherSpecs(sslSocket *ss)
-{
- PRUint8 * cs = NULL;
- unsigned int allowed;
- unsigned int count;
- int ssl3_count = 0;
- int final_count;
- int i;
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- count = 0;
- PORT_Assert(ss != 0);
- allowed = !ss->opt.enableSSL2 ? 0 :
- (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
- while (allowed) {
- if (allowed & 1)
- ++count;
- allowed >>= 1;
- }
-
- /* Call ssl3_config_match_init() once here,
- * instead of inside ssl3_ConstructV2CipherSpecsHack(),
- * because the latter gets called twice below,
- * and then again in ssl2_BeginClientHandshake().
- */
- ssl3_config_match_init(ss);
-
- /* ask SSL3 how many cipher suites it has. */
- rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count);
- if (rv < 0)
- return rv;
- count += ssl3_count;
-
- /* Allocate memory to hold cipher specs */
- if (count > 0)
- cs = (PRUint8*) PORT_Alloc(count * 3);
- else
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- if (cs == NULL)
- return SECFailure;
-
- if (ss->cipherSpecs != NULL) {
- PORT_Free(ss->cipherSpecs);
- }
- ss->cipherSpecs = cs;
- ss->sizeCipherSpecs = count * 3;
-
- /* fill in cipher specs for SSL2 cipher suites */
- allowed = !ss->opt.enableSSL2 ? 0 :
- (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
- for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) {
- const PRUint8 * hs = implementedCipherSuites + i;
- int ok = allowed & (1U << hs[0]);
- if (ok) {
- cs[0] = hs[0];
- cs[1] = hs[1];
- cs[2] = hs[2];
- cs += 3;
- }
- }
-
- /* now have SSL3 add its suites onto the end */
- rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count);
-
- /* adjust for any difference between first pass and second pass */
- ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3;
-
- return rv;
-}
-
-/* This function is called immediately after ssl2_ConstructCipherSpecs()
-** at the beginning of a handshake. It detects cases where a protocol
-** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites
-** for that protocol have been disabled. If such cases, it clears the
-** enable bit for the protocol. If no protocols remain enabled, or
-** if no cipher suites are found, it sets the error code and returns
-** SECFailure, otherwise it returns SECSuccess.
-*/
-static SECStatus
-ssl2_CheckConfigSanity(sslSocket *ss)
-{
- unsigned int allowed;
- int ssl3CipherCount = 0;
- SECStatus rv;
-
- /* count the SSL2 and SSL3 enabled ciphers.
- * if either is zero, clear the socket's enable for that protocol.
- */
- if (!ss->cipherSpecs)
- goto disabled;
-
- allowed = ss->allowedByPolicy & ss->chosenPreference;
- if (! allowed)
- ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */
-
- /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */
- /* Ask how many ssl3 CipherSuites were enabled. */
- rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount);
- if (rv != SECSuccess || ssl3CipherCount <= 0) {
- /* SSL3/TLS not really enabled if no ciphers */
- ss->vrange.min = SSL_LIBRARY_VERSION_NONE;
- ss->vrange.max = SSL_LIBRARY_VERSION_NONE;
- }
-
- if (!ss->opt.enableSSL2 && SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.",
- SSL_GETPID(), ss->fd));
-disabled:
- PORT_SetError(SSL_ERROR_SSL_DISABLED);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/*
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this. Probably want a global lock.
- */
-SECStatus
-ssl2_SetPolicy(PRInt32 which, PRInt32 policy)
-{
- PRUint32 bitMask;
- SECStatus rv = SECSuccess;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return SECFailure;
- }
-
- if (policy == SSL_ALLOWED) {
- allowedByPolicy |= bitMask;
- maybeAllowedByPolicy |= bitMask;
- } else if (policy == SSL_RESTRICTED) {
- allowedByPolicy &= ~bitMask;
- maybeAllowedByPolicy |= bitMask;
- } else {
- allowedByPolicy &= ~bitMask;
- maybeAllowedByPolicy &= ~bitMask;
- }
- allowedByPolicy &= SSL_CB_IMPLEMENTED;
- maybeAllowedByPolicy &= SSL_CB_IMPLEMENTED;
-
- policyWasSet = PR_TRUE;
- return rv;
-}
-
-SECStatus
-ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy)
-{
- PRUint32 bitMask;
- PRInt32 policy;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- /* Caller assures oPolicy is not null. */
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- *oPolicy = SSL_NOT_ALLOWED;
- return SECFailure;
- }
-
- if (maybeAllowedByPolicy & bitMask) {
- policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED;
- } else {
- policy = SSL_NOT_ALLOWED;
- }
-
- *oPolicy = policy;
- return SECSuccess;
-}
-
-/*
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this. Probably want a global lock.
- * Called from SSL_CipherPrefSetDefault in sslsock.c
- * These changes have no effect on any sslSockets already created.
- */
-SECStatus
-ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
-{
- PRUint32 bitMask;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return SECFailure;
- }
-
- if (enabled)
- chosenPreference |= bitMask;
- else
- chosenPreference &= ~bitMask;
- chosenPreference &= SSL_CB_IMPLEMENTED;
-
- return SECSuccess;
-}
-
-SECStatus
-ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
-{
- PRBool rv = PR_FALSE;
- PRUint32 bitMask;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- *enabled = PR_FALSE;
- return SECFailure;
- }
-
- rv = (PRBool)((chosenPreference & bitMask) != 0);
- *enabled = rv;
- return SECSuccess;
-}
-
-SECStatus
-ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled)
-{
- PRUint32 bitMask;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- return SECFailure;
- }
-
- if (enabled)
- ss->chosenPreference |= bitMask;
- else
- ss->chosenPreference &= ~bitMask;
- ss->chosenPreference &= SSL_CB_IMPLEMENTED;
-
- return SECSuccess;
-}
-
-SECStatus
-ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled)
-{
- PRBool rv = PR_FALSE;
- PRUint32 bitMask;
-
- which &= 0x000f;
- bitMask = 1 << which;
-
- if (!(bitMask & SSL_CB_IMPLEMENTED)) {
- PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
- *enabled = PR_FALSE;
- return SECFailure;
- }
-
- rv = (PRBool)((ss->chosenPreference & bitMask) != 0);
- *enabled = rv;
- return SECSuccess;
-}
-
-
-/* copy global default policy into socket. */
-void
-ssl2_InitSocketPolicy(sslSocket *ss)
-{
- ss->allowedByPolicy = allowedByPolicy;
- ss->maybeAllowedByPolicy = maybeAllowedByPolicy;
- ss->chosenPreference = chosenPreference;
-}
-
-
-/************************************************************************/
-
-/* Called from ssl2_CreateSessionCypher(), which already holds handshake lock.
- */
-static SECStatus
-ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey,
- int cipherChoice)
-{
- switch (cipherChoice) {
-
- case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
- case SSL_CK_RC2_128_CBC_WITH_MD5:
- case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
- case SSL_CK_RC4_128_WITH_MD5:
- case SSL_CK_DES_64_CBC_WITH_MD5:
- case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
- sec->hash = HASH_GetHashObject(HASH_AlgMD5);
- SECITEM_CopyItem(0, &sec->sendSecret, writeKey);
- SECITEM_CopyItem(0, &sec->rcvSecret, readKey);
- break;
-
- default:
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
- sec->hashcx = (*sec->hash->create)();
- if (sec->hashcx == NULL)
- return SECFailure;
- return SECSuccess;
-}
-
-/************************************************************************
- * All the Send functions below must acquire and release the socket's
- * xmitBufLock.
- */
-
-/* Called from all the Send* functions below. */
-static SECStatus
-ssl2_GetSendBuffer(sslSocket *ss, unsigned int len)
-{
- SECStatus rv = SECSuccess;
-
- PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
-
- if (len < 128) {
- len = 128;
- }
- if (len > ss->sec.ci.sendBuf.space) {
- rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len);
- if (rv != SECSuccess) {
- SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes",
- SSL_GETPID(), ss->fd, len));
- rv = SECFailure;
- }
- }
- return rv;
-}
-
-/* Called from:
- * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
- * ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() <-
- ssl_Do1stHandshake()
- * ssl2_HandleMessage() <- ssl_Do1stHandshake()
- * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake()
- after ssl2_BeginClientHandshake()
- * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake()
- after ssl2_BeginServerHandshake()
- *
- * Acquires and releases the socket's xmitBufLock.
- */
-int
-ssl2_SendErrorMessage(sslSocket *ss, int error)
-{
- int rv;
- PRUint8 msg[SSL_HL_ERROR_HBYTES];
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- msg[0] = SSL_MT_ERROR;
- msg[1] = MSB(error);
- msg[2] = LSB(error);
-
- ssl_GetXmitBufLock(ss); /***************************************/
-
- SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));
-
- ss->handshakeBegun = 1;
- rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0);
- if (rv >= 0) {
- rv = SECSuccess;
- }
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_TryToFinish().
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendClientFinishedMessage(sslSocket *ss)
-{
- SECStatus rv = SECSuccess;
- int sent;
- PRUint8 msg[1 + SSL_CONNECTIONID_BYTES];
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetXmitBufLock(ss); /***************************************/
-
- if (ss->sec.ci.sentFinished == 0) {
- ss->sec.ci.sentFinished = 1;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending client-finished",
- SSL_GETPID(), ss->fd));
-
- msg[0] = SSL_MT_CLIENT_FINISHED;
- PORT_Memcpy(msg+1, ss->sec.ci.connectionID,
- sizeof(ss->sec.ci.connectionID));
-
- DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID)));
- sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0);
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
- }
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from
- * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage()
- * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake()
- after ssl2_BeginServerHandshake()
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendServerVerifyMessage(sslSocket *ss)
-{
- PRUint8 * msg;
- int sendLen;
- int sent;
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetXmitBufLock(ss); /***************************************/
-
- sendLen = 1 + SSL_CHALLENGE_BYTES;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess) {
- goto done;
- }
-
- msg = ss->sec.ci.sendBuf.buf;
- msg[0] = SSL_MT_SERVER_VERIFY;
- PORT_Memcpy(msg+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
-
- DUMP_MSG(29, (ss, msg, sendLen));
- sent = (*ss->sec.send)(ss, msg, sendLen, 0);
-
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_TryToFinish().
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendServerFinishedMessage(sslSocket *ss)
-{
- sslSessionID * sid;
- PRUint8 * msg;
- int sendLen, sent;
- SECStatus rv = SECSuccess;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetXmitBufLock(ss); /***************************************/
-
- if (ss->sec.ci.sentFinished == 0) {
- ss->sec.ci.sentFinished = 1;
- PORT_Assert(ss->sec.ci.sid != 0);
- sid = ss->sec.ci.sid;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending server-finished",
- SSL_GETPID(), ss->fd));
-
- sendLen = 1 + sizeof(sid->u.ssl2.sessionID);
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess) {
- goto done;
- }
-
- msg = ss->sec.ci.sendBuf.buf;
- msg[0] = SSL_MT_SERVER_FINISHED;
- PORT_Memcpy(msg+1, sid->u.ssl2.sessionID,
- sizeof(sid->u.ssl2.sessionID));
-
- DUMP_MSG(29, (ss, msg, sendLen));
- sent = (*ss->sec.send)(ss, msg, sendLen, 0);
-
- if (sent < 0) {
- /* If send failed, it is now a bogus session-id */
- if (ss->sec.uncache)
- (*ss->sec.uncache)(sid);
- rv = (SECStatus)sent;
- } else if (!ss->opt.noCache) {
- /* Put the sid in session-id cache, (may already be there) */
- (*ss->sec.cache)(sid);
- rv = SECSuccess;
- }
- ssl_FreeSID(sid);
- ss->sec.ci.sid = 0;
- }
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_ClientSetupSessionCypher() <-
- * ssl2_HandleServerHelloMessage()
- * after ssl2_BeginClientHandshake()
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize,
- PRUint8 *ca, int caLen,
- PRUint8 *ck, int ckLen,
- PRUint8 *ek, int ekLen)
-{
- PRUint8 * msg;
- int sendLen;
- int sent;
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetXmitBufLock(ss); /***************************************/
-
- sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess)
- goto done;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key",
- SSL_GETPID(), ss->fd));
-
- msg = ss->sec.ci.sendBuf.buf;
- msg[0] = SSL_MT_CLIENT_MASTER_KEY;
- msg[1] = cipher;
- msg[2] = MSB(keySize);
- msg[3] = LSB(keySize);
- msg[4] = MSB(ckLen);
- msg[5] = LSB(ckLen);
- msg[6] = MSB(ekLen);
- msg[7] = LSB(ekLen);
- msg[8] = MSB(caLen);
- msg[9] = LSB(caLen);
- PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen);
- PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen);
- PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen);
-
- DUMP_MSG(29, (ss, msg, sendLen));
- sent = (*ss->sec.send)(ss, msg, sendLen, 0);
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage()
- * Acquires and releases the socket's xmitBufLock.
- */
-static SECStatus
-ssl2_SendCertificateRequestMessage(sslSocket *ss)
-{
- PRUint8 * msg;
- int sent;
- int sendLen;
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetXmitBufLock(ss); /***************************************/
-
- sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess)
- goto done;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending certificate request",
- SSL_GETPID(), ss->fd));
-
- /* Generate random challenge for client to encrypt */
- PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
-
- msg = ss->sec.ci.sendBuf.buf;
- msg[0] = SSL_MT_REQUEST_CERTIFICATE;
- msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION;
- PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES,
- ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
-
- DUMP_MSG(29, (ss, msg, sendLen));
- sent = (*ss->sec.send)(ss, msg, sendLen, 0);
- rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage()
- * Acquires and releases the socket's xmitBufLock.
- */
-static int
-ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert,
- SECItem *encCode)
-{
- PRUint8 *msg;
- int rv, sendLen;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetXmitBufLock(ss); /***************************************/
-
- sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv)
- goto done;
-
- SSL_TRC(3, ("%d: SSL[%d]: sending certificate response",
- SSL_GETPID(), ss->fd));
-
- msg = ss->sec.ci.sendBuf.buf;
- msg[0] = SSL_MT_CLIENT_CERTIFICATE;
- msg[1] = SSL_CT_X509_CERTIFICATE;
- msg[2] = MSB(cert->len);
- msg[3] = LSB(cert->len);
- msg[4] = MSB(encCode->len);
- msg[5] = LSB(encCode->len);
- PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len);
- PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len,
- encCode->data, encCode->len);
-
- DUMP_MSG(29, (ss, msg, sendLen));
- rv = (*ss->sec.send)(ss, msg, sendLen, 0);
- if (rv >= 0) {
- rv = SECSuccess;
- }
-done:
- ssl_ReleaseXmitBufLock(ss); /***************************************/
- return rv;
-}
-
-/********************************************************************
-** Send functions above this line must aquire & release the socket's
-** xmitBufLock.
-** All the ssl2_Send functions below this line are called vis ss->sec.send
-** and require that the caller hold the xmitBufLock.
-*/
-
-/*
-** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear.
-*/
-static SECStatus
-ssl2_CalcMAC(PRUint8 * result,
- sslSecurityInfo * sec,
- const PRUint8 * data,
- unsigned int dataLen,
- unsigned int paddingLen)
-{
- const PRUint8 * secret = sec->sendSecret.data;
- unsigned int secretLen = sec->sendSecret.len;
- unsigned long sequenceNumber = sec->sendSequence;
- unsigned int nout;
- PRUint8 seq[4];
- PRUint8 padding[32];/* XXX max blocksize? */
-
- if (!sec->hash || !sec->hash->length)
- return SECSuccess;
- if (!sec->hashcx)
- return SECFailure;
-
- /* Reset hash function */
- (*sec->hash->begin)(sec->hashcx);
-
- /* Feed hash the data */
- (*sec->hash->update)(sec->hashcx, secret, secretLen);
- (*sec->hash->update)(sec->hashcx, data, dataLen);
- PORT_Memset(padding, paddingLen, paddingLen);
- (*sec->hash->update)(sec->hashcx, padding, paddingLen);
-
- seq[0] = (PRUint8) (sequenceNumber >> 24);
- seq[1] = (PRUint8) (sequenceNumber >> 16);
- seq[2] = (PRUint8) (sequenceNumber >> 8);
- seq[3] = (PRUint8) (sequenceNumber);
-
- PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen));
- PRINT_BUF(60, (0, "calc-mac data:", data, dataLen));
- PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen));
- PRINT_BUF(60, (0, "calc-mac seq:", seq, 4));
-
- (*sec->hash->update)(sec->hashcx, seq, 4);
-
- /* Get result */
- (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length);
-
- return SECSuccess;
-}
-
-/*
-** Maximum transmission amounts. These are tiny bit smaller than they
-** need to be (they account for the MAC length plus some padding),
-** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes
-** long. This gives an additional 9 bytes of slop to work within.
-*/
-#define MAX_STREAM_CYPHER_LEN 0x7fe0
-#define MAX_BLOCK_CYPHER_LEN 0x3fe0
-
-/*
-** Send some data in the clear.
-** Package up data with the length header and send it.
-**
-** Return count of bytes successfully written, or negative number (failure).
-*/
-static PRInt32
-ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
-{
- PRUint8 * out;
- int rv;
- int amount;
- int count = 0;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-
- SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear",
- SSL_GETPID(), ss->fd, len));
- PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
-
- while (len) {
- amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
- if (amount + 2 > ss->sec.writeBuf.space) {
- rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2);
- if (rv != SECSuccess) {
- count = rv;
- break;
- }
- }
- out = ss->sec.writeBuf.buf;
-
- /*
- ** Construct message.
- */
- out[0] = 0x80 | MSB(amount);
- out[1] = LSB(amount);
- PORT_Memcpy(&out[2], in, amount);
-
- /* Now send the data */
- rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK);
- if (rv < 0) {
- if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
- rv = 0;
- } else {
- /* Return short write if some data already went out... */
- if (count == 0)
- count = rv;
- break;
- }
- }
-
- if ((unsigned)rv < (amount + 2)) {
- /* Short write. Save the data and return. */
- if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv)
- == SECFailure) {
- count = SECFailure;
- } else {
- count += amount;
- ss->sec.sendSequence++;
- }
- break;
- }
-
- ss->sec.sendSequence++;
- in += amount;
- count += amount;
- len -= amount;
- }
-
- return count;
-}
-
-/*
-** Send some data, when using a stream cipher. Stream ciphers have a
-** block size of 1. Package up the data with the length header
-** and send it.
-*/
-static PRInt32
-ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
-{
- PRUint8 * out;
- int rv;
- int count = 0;
-
- int amount;
- PRUint8 macLen;
- int nout;
- int buflen;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-
- SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher",
- SSL_GETPID(), ss->fd, len));
- PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
-
- while (len) {
- ssl_GetSpecReadLock(ss); /*************************************/
-
- macLen = ss->sec.hash->length;
- amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
- buflen = amount + 2 + macLen;
- if (buflen > ss->sec.writeBuf.space) {
- rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- out = ss->sec.writeBuf.buf;
- nout = amount + macLen;
- out[0] = 0x80 | MSB(nout);
- out[1] = LSB(nout);
-
- /* Calculate MAC */
- rv = ssl2_CalcMAC(out+2, /* put MAC here */
- &ss->sec,
- in, amount, /* input addr & length */
- 0); /* no padding */
- if (rv != SECSuccess)
- goto loser;
-
- /* Encrypt MAC */
- rv = (*ss->sec.enc)(ss->sec.writecx, out+2, &nout, macLen, out+2, macLen);
- if (rv) goto loser;
-
- /* Encrypt data from caller */
- rv = (*ss->sec.enc)(ss->sec.writecx, out+2+macLen, &nout, amount, in, amount);
- if (rv) goto loser;
-
- ssl_ReleaseSpecReadLock(ss); /*************************************/
-
- PRINT_BUF(50, (ss, "encrypted data:", out, buflen));
-
- rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK);
- if (rv < 0) {
- if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
- SSL_TRC(50, ("%d: SSL[%d]: send stream would block, "
- "saving data", SSL_GETPID(), ss->fd));
- rv = 0;
- } else {
- SSL_TRC(10, ("%d: SSL[%d]: send stream error %d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- /* Return short write if some data already went out... */
- if (count == 0)
- count = rv;
- goto done;
- }
- }
-
- if ((unsigned)rv < buflen) {
- /* Short write. Save the data and return. */
- if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) {
- count = SECFailure;
- } else {
- count += amount;
- ss->sec.sendSequence++;
- }
- goto done;
- }
-
- ss->sec.sendSequence++;
- in += amount;
- count += amount;
- len -= amount;
- }
-
-done:
- return count;
-
-loser:
- ssl_ReleaseSpecReadLock(ss);
- return SECFailure;
-}
-
-/*
-** Send some data, when using a block cipher. Package up the data with
-** the length header and send it.
-*/
-/* XXX assumes blocksize is > 7 */
-static PRInt32
-ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
-{
- PRUint8 * out; /* begining of output buffer. */
- PRUint8 * op; /* next output byte goes here. */
- int rv; /* value from funcs we called. */
- int count = 0; /* this function's return value. */
-
- unsigned int hlen; /* output record hdr len, 2 or 3 */
- unsigned int macLen; /* MAC is this many bytes long. */
- int amount; /* of plaintext to go in record. */
- unsigned int padding; /* add this many padding byte. */
- int nout; /* ciphertext size after header. */
- int buflen; /* size of generated record. */
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
-
- SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher",
- SSL_GETPID(), ss->fd, len));
- PRINT_BUF(50, (ss, "clear data:", in, len));
-
- while (len) {
- ssl_GetSpecReadLock(ss); /*************************************/
-
- macLen = ss->sec.hash->length;
- /* Figure out how much to send, including mac and padding */
- amount = PR_MIN( len, MAX_BLOCK_CYPHER_LEN );
- nout = amount + macLen;
- padding = nout & (ss->sec.blockSize - 1);
- if (padding) {
- hlen = 3;
- padding = ss->sec.blockSize - padding;
- nout += padding;
- } else {
- hlen = 2;
- }
- buflen = hlen + nout;
- if (buflen > ss->sec.writeBuf.space) {
- rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- out = ss->sec.writeBuf.buf;
-
- /* Construct header */
- op = out;
- if (padding) {
- *op++ = MSB(nout);
- *op++ = LSB(nout);
- *op++ = padding;
- } else {
- *op++ = 0x80 | MSB(nout);
- *op++ = LSB(nout);
- }
-
- /* Calculate MAC */
- rv = ssl2_CalcMAC(op, /* MAC goes here. */
- &ss->sec,
- in, amount, /* intput addr, len */
- padding);
- if (rv != SECSuccess)
- goto loser;
- op += macLen;
-
- /* Copy in the input data */
- /* XXX could eliminate the copy by folding it into the encryption */
- PORT_Memcpy(op, in, amount);
- op += amount;
- if (padding) {
- PORT_Memset(op, padding, padding);
- op += padding;
- }
-
- /* Encrypt result */
- rv = (*ss->sec.enc)(ss->sec.writecx, out+hlen, &nout, buflen-hlen,
- out+hlen, op - (out + hlen));
- if (rv)
- goto loser;
-
- ssl_ReleaseSpecReadLock(ss); /*************************************/
-
- PRINT_BUF(50, (ss, "final xmit data:", out, op - out));
-
- rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK);
- if (rv < 0) {
- if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
- rv = 0;
- } else {
- SSL_TRC(10, ("%d: SSL[%d]: send block error %d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- /* Return short write if some data already went out... */
- if (count == 0)
- count = rv;
- goto done;
- }
- }
-
- if (rv < (op - out)) {
- /* Short write. Save the data and return. */
- if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) {
- count = SECFailure;
- } else {
- count += amount;
- ss->sec.sendSequence++;
- }
- goto done;
- }
-
- ss->sec.sendSequence++;
- in += amount;
- count += amount;
- len -= amount;
- }
-
-done:
- return count;
-
-loser:
- ssl_ReleaseSpecReadLock(ss);
- return SECFailure;
-}
-
-/*
-** Called from: ssl2_HandleServerHelloMessage,
-** ssl2_HandleClientSessionKeyMessage,
-** ssl2_HandleClientHelloMessage,
-**
-*/
-static void
-ssl2_UseEncryptedSendFunc(sslSocket *ss)
-{
- ssl_GetXmitBufLock(ss);
- PORT_Assert(ss->sec.hashcx != 0);
-
- ss->gs.encrypted = 1;
- ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream;
- ssl_ReleaseXmitBufLock(ss);
-}
-
-/* Called while initializing socket in ssl_CreateSecurityInfo().
-** This function allows us to keep the name of ssl2_SendClear static.
-*/
-void
-ssl2_UseClearSendFunc(sslSocket *ss)
-{
- ss->sec.send = ssl2_SendClear;
-}
-
-/************************************************************************
-** END of Send functions. *
-*************************************************************************/
-
-/***********************************************************************
- * For SSL3, this gathers in and handles records/messages until either
- * the handshake is complete or application data is available.
- *
- * For SSL2, this gathers in only the next SSLV2 record.
- *
- * Called from ssl_Do1stHandshake() via function pointer ss->handshake.
- * Caller must hold handshake lock.
- * This function acquires and releases the RecvBufLock.
- *
- * returns SECSuccess for success.
- * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or
- * ssl3_GatherCompleteHandshake().
- * returns SECFailure on all other errors.
- *
- * The gather functions called by ssl_GatherRecord1stHandshake are expected
- * to return values interpreted as follows:
- * 1 : the function completed without error.
- * 0 : the function read EOF.
- * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
- * -2 : the function wants ssl_GatherRecord1stHandshake to be called again
- * immediately, by ssl_Do1stHandshake.
- *
- * This code is similar to, and easily confused with, DoRecv() in sslsecur.c
- *
- * This function is called from ssl_Do1stHandshake().
- * The following functions put ssl_GatherRecord1stHandshake into ss->handshake:
- * ssl2_HandleMessage
- * ssl2_HandleVerifyMessage
- * ssl2_HandleServerHelloMessage
- * ssl2_BeginClientHandshake
- * ssl2_HandleClientSessionKeyMessage
- * ssl3_RestartHandshakeAfterCertReq
- * ssl3_RestartHandshakeAfterServerCert
- * ssl2_HandleClientHelloMessage
- * ssl2_BeginServerHandshake
- */
-SECStatus
-ssl_GatherRecord1stHandshake(sslSocket *ss)
-{
- int rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetRecvBufLock(ss);
-
- /* The special case DTLS logic is needed here because the SSL/TLS
- * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake
- * (ss->version == 0) but with DTLS it gets confused, so we force the
- * SSL3 version.
- */
- if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) {
- /* Wait for handshake to complete, or application data to arrive. */
- rv = ssl3_GatherCompleteHandshake(ss, 0);
- } else {
- /* See if we have a complete record */
- rv = ssl2_GatherRecord(ss, 0);
- }
- SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d",
- SSL_GETPID(), ss->fd, rv));
-
- ssl_ReleaseRecvBufLock(ss);
-
- if (rv <= 0) {
- if (rv == SECWouldBlock) {
- /* Progress is blocked waiting for callback completion. */
- SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)",
- SSL_GETPID(), ss->fd, ss->gs.remainder));
- return SECWouldBlock;
- }
- if (rv == 0) {
- /* EOF. Loser */
- PORT_SetError(PR_END_OF_FILE_ERROR);
- }
- return SECFailure; /* rv is < 0 here. */
- }
-
- SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes",
- SSL_GETPID(), ss->fd, ss->gs.recordLen));
-
- ss->handshake = 0; /* makes ssl_Do1stHandshake call ss->nextHandshake.*/
- return SECSuccess;
-}
-
-/************************************************************************/
-
-/* Called from ssl2_ServerSetupSessionCypher()
- * ssl2_ClientSetupSessionCypher()
- */
-static SECStatus
-ssl2_FillInSID(sslSessionID * sid,
- int cipher,
- PRUint8 *keyData,
- int keyLen,
- PRUint8 *ca,
- int caLen,
- int keyBits,
- int secretKeyBits,
- SSLSignType authAlgorithm,
- PRUint32 authKeyBits,
- SSLKEAType keaType,
- PRUint32 keaKeyBits)
-{
- PORT_Assert(sid->references == 1);
- PORT_Assert(sid->cached == never_cached);
- PORT_Assert(sid->u.ssl2.masterKey.data == 0);
- PORT_Assert(sid->u.ssl2.cipherArg.data == 0);
-
- sid->version = SSL_LIBRARY_VERSION_2;
-
- sid->u.ssl2.cipherType = cipher;
- sid->u.ssl2.masterKey.data = (PRUint8*) PORT_Alloc(keyLen);
- if (!sid->u.ssl2.masterKey.data) {
- return SECFailure;
- }
- PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen);
- sid->u.ssl2.masterKey.len = keyLen;
- sid->u.ssl2.keyBits = keyBits;
- sid->u.ssl2.secretKeyBits = secretKeyBits;
- sid->authAlgorithm = authAlgorithm;
- sid->authKeyBits = authKeyBits;
- sid->keaType = keaType;
- sid->keaKeyBits = keaKeyBits;
- sid->lastAccessTime = sid->creationTime = ssl_Time();
- sid->expirationTime = sid->creationTime + ssl_sid_timeout;
-
- if (caLen) {
- sid->u.ssl2.cipherArg.data = (PRUint8*) PORT_Alloc(caLen);
- if (!sid->u.ssl2.cipherArg.data) {
- return SECFailure;
- }
- sid->u.ssl2.cipherArg.len = caLen;
- PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen);
- }
- return SECSuccess;
-}
-
-/*
-** Construct session keys given the masterKey (tied to the session-id),
-** the client's challenge and the server's nonce.
-**
-** Called from ssl2_CreateSessionCypher() <-
-*/
-static SECStatus
-ssl2_ProduceKeys(sslSocket * ss,
- SECItem * readKey,
- SECItem * writeKey,
- SECItem * masterKey,
- PRUint8 * challenge,
- PRUint8 * nonce,
- int cipherType)
-{
- PK11Context * cx = 0;
- unsigned nkm = 0; /* number of hashes to generate key mat. */
- unsigned nkd = 0; /* size of readKey and writeKey. */
- unsigned part;
- unsigned i;
- unsigned off;
- SECStatus rv;
- PRUint8 countChar;
- PRUint8 km[3*16]; /* buffer for key material. */
-
- readKey->data = 0;
- writeKey->data = 0;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- rv = SECSuccess;
- cx = PK11_CreateDigestContext(SEC_OID_MD5);
- if (cx == NULL) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- return SECFailure;
- }
-
- nkm = ssl_Specs[cipherType].nkm;
- nkd = ssl_Specs[cipherType].nkd;
-
- readKey->data = (PRUint8*) PORT_Alloc(nkd);
- if (!readKey->data)
- goto loser;
- readKey->len = nkd;
-
- writeKey->data = (PRUint8*) PORT_Alloc(nkd);
- if (!writeKey->data)
- goto loser;
- writeKey->len = nkd;
-
- /* Produce key material */
- countChar = '0';
- for (i = 0, off = 0; i < nkm; i++, off += 16) {
- rv = PK11_DigestBegin(cx);
- rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len);
- rv |= PK11_DigestOp(cx, &countChar, 1);
- rv |= PK11_DigestOp(cx, challenge, SSL_CHALLENGE_BYTES);
- rv |= PK11_DigestOp(cx, nonce, SSL_CONNECTIONID_BYTES);
- rv |= PK11_DigestFinal(cx, km+off, &part, MD5_LENGTH);
- if (rv != SECSuccess) {
- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
- rv = SECFailure;
- goto loser;
- }
- countChar++;
- }
-
- /* Produce keys */
- PORT_Memcpy(readKey->data, km, nkd);
- PORT_Memcpy(writeKey->data, km + nkd, nkd);
-
-loser:
- PK11_DestroyContext(cx, PR_TRUE);
- return rv;
-}
-
-/* Called from ssl2_ServerSetupSessionCypher()
-** <- ssl2_HandleClientSessionKeyMessage()
-** <- ssl2_HandleClientHelloMessage()
-** and from ssl2_ClientSetupSessionCypher()
-** <- ssl2_HandleServerHelloMessage()
-*/
-static SECStatus
-ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient)
-{
- SECItem * rk = NULL;
- SECItem * wk = NULL;
- SECItem * param;
- SECStatus rv;
- int cipherType = sid->u.ssl2.cipherType;
- PK11SlotInfo * slot = NULL;
- CK_MECHANISM_TYPE mechanism;
- SECItem readKey;
- SECItem writeKey;
-
- void *readcx = 0;
- void *writecx = 0;
- readKey.data = 0;
- writeKey.data = 0;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- if (ss->sec.ci.sid == 0)
- goto sec_loser; /* don't crash if asserts are off */
-
- /* Trying to cut down on all these switch statements that should be tables.
- * So, test cipherType once, here, and then use tables below.
- */
- switch (cipherType) {
- case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
- case SSL_CK_RC4_128_WITH_MD5:
- case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
- case SSL_CK_RC2_128_CBC_WITH_MD5:
- case SSL_CK_DES_64_CBC_WITH_MD5:
- case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
- break;
-
- default:
- SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d",
- SSL_GETPID(), ss->fd, cipherType));
- PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT);
- goto sec_loser;
- }
-
- rk = isClient ? &readKey : &writeKey;
- wk = isClient ? &writeKey : &readKey;
-
- /* Produce the keys for this session */
- rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey,
- ss->sec.ci.clientChallenge, ss->sec.ci.connectionID,
- cipherType);
- if (rv != SECSuccess)
- goto loser;
- PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len));
- PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len));
-
- PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len);
- PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len);
- ss->sec.ci.keySize = readKey.len;
-
- /* Setup the MAC */
- rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType);
- if (rv != SECSuccess)
- goto loser;
-
- /* First create the session key object */
- SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd,
- ssl_cipherName[cipherType]));
-
-
- mechanism = ssl_Specs[cipherType].mechanism;
-
- /* set destructer before we call loser... */
- ss->sec.destroy = (void (*)(void*, PRBool)) PK11_DestroyContext;
- slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg);
- if (slot == NULL)
- goto loser;
-
- param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
- if (param == NULL)
- goto loser;
- readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
- CKA_DECRYPT, rk, param,
- ss->pkcs11PinArg);
- SECITEM_FreeItem(param, PR_TRUE);
- if (readcx == NULL)
- goto loser;
-
- /* build the client context */
- param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
- if (param == NULL)
- goto loser;
- writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
- CKA_ENCRYPT, wk, param,
- ss->pkcs11PinArg);
- SECITEM_FreeItem(param,PR_TRUE);
- if (writecx == NULL)
- goto loser;
- PK11_FreeSlot(slot);
-
- rv = SECSuccess;
- ss->sec.enc = (SSLCipher) PK11_CipherOp;
- ss->sec.dec = (SSLCipher) PK11_CipherOp;
- ss->sec.readcx = (void *) readcx;
- ss->sec.writecx = (void *) writecx;
- ss->sec.blockSize = ssl_Specs[cipherType].blockSize;
- ss->sec.blockShift = ssl_Specs[cipherType].blockShift;
- ss->sec.cipherType = sid->u.ssl2.cipherType;
- ss->sec.keyBits = sid->u.ssl2.keyBits;
- ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits;
- goto done;
-
- loser:
- if (ss->sec.destroy) {
- if (readcx) (*ss->sec.destroy)(readcx, PR_TRUE);
- if (writecx) (*ss->sec.destroy)(writecx, PR_TRUE);
- }
- ss->sec.destroy = NULL;
- if (slot) PK11_FreeSlot(slot);
-
- sec_loser:
- rv = SECFailure;
-
- done:
- if (rk) {
- SECITEM_ZfreeItem(rk, PR_FALSE);
- }
- if (wk) {
- SECITEM_ZfreeItem(wk, PR_FALSE);
- }
- return rv;
-}
-
-/*
-** Setup the server ciphers given information from a CLIENT-MASTER-KEY
-** message.
-** "ss" pointer to the ssl-socket object
-** "cipher" the cipher type to use
-** "keyBits" the size of the final cipher key
-** "ck" the clear-key data
-** "ckLen" the number of bytes of clear-key data
-** "ek" the encrypted-key data
-** "ekLen" the number of bytes of encrypted-key data
-** "ca" the cipher-arg data
-** "caLen" the number of bytes of cipher-arg data
-**
-** The MASTER-KEY is constructed by first decrypting the encrypted-key
-** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by
-** concatenating the clear-key data with the SECRET-KEY-DATA. This code
-** checks to make sure that the client didn't send us an improper amount
-** of SECRET-KEY-DATA (it restricts the length of that data to match the
-** spec).
-**
-** Called from ssl2_HandleClientSessionKeyMessage().
-*/
-static SECStatus
-ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
- PRUint8 *ck, unsigned int ckLen,
- PRUint8 *ek, unsigned int ekLen,
- PRUint8 *ca, unsigned int caLen)
-{
- PRUint8 * dk = NULL; /* decrypted master key */
- sslSessionID * sid;
- sslServerCerts * sc = ss->serverCerts + kt_rsa;
- PRUint8 * kbuf = 0; /* buffer for RSA decrypted data. */
- unsigned int ddLen; /* length of RSA decrypted data in kbuf */
- unsigned int keySize;
- unsigned int dkLen; /* decrypted key length in bytes */
- int modulusLen;
- SECStatus rv;
- PRUint16 allowed; /* cipher kinds enabled and allowed by policy */
- PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES];
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert((sc->SERVERKEY != 0));
- PORT_Assert((ss->sec.ci.sid != 0));
- sid = ss->sec.ci.sid;
-
- /* Trying to cut down on all these switch statements that should be tables.
- * So, test cipherType once, here, and then use tables below.
- */
- switch (cipher) {
- case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
- case SSL_CK_RC4_128_WITH_MD5:
- case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
- case SSL_CK_RC2_128_CBC_WITH_MD5:
- case SSL_CK_DES_64_CBC_WITH_MD5:
- case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
- break;
-
- default:
- SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d",
- SSL_GETPID(), ss->fd, cipher));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
- allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED;
- if (!(allowed & (1 << cipher))) {
- /* client chose a kind we don't allow! */
- SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d",
- SSL_GETPID(), ss->fd, cipher));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
- keySize = ssl_Specs[cipher].keyLen;
- if (keyBits != keySize * BPB) {
- SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!",
- SSL_GETPID(), ss->fd, keyBits));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
- if (ckLen != ssl_Specs[cipher].pubLen) {
- SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!",
- SSL_GETPID(), ss->fd, ckLen));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
- if (caLen != ssl_Specs[cipher].ivLen) {
- SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!",
- SSL_GETPID(), ss->fd, caLen));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
- modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY);
- if (modulusLen == -1) {
- /* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */
- modulusLen = ekLen;
- }
- if (ekLen > modulusLen || ekLen + ckLen < keySize) {
- SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!",
- SSL_GETPID(), ss->fd, ekLen));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto loser;
- }
-
- /* allocate the buffer to hold the decrypted portion of the key. */
- kbuf = (PRUint8*)PORT_Alloc(modulusLen);
- if (!kbuf) {
- goto loser;
- }
- dkLen = keySize - ckLen;
- dk = kbuf + modulusLen - dkLen;
-
- /* Decrypt encrypted half of the key.
- ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is
- ** desired behavior here.
- */
- rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen);
- if (rv != SECSuccess)
- goto hide_loser;
-
- /* Is the length of the decrypted data (ddLen) the expected value? */
- if (modulusLen != ddLen)
- goto hide_loser;
-
- /* Cheaply verify that PKCS#1 was used to format the encryption block */
- if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) {
- SSL_DBG(("%d: SSL[%d]: strange encryption block",
- SSL_GETPID(), ss->fd));
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto hide_loser;
- }
-
- /* Make sure we're not subject to a version rollback attack. */
- if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03 };
-
- if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) {
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- goto hide_loser;
- }
- }
- if (0) {
-hide_loser:
- /* Defense against the Bleichenbacher attack.
- * Provide the client with NO CLUES that the decrypted master key
- * was erroneous. Don't send any error messages.
- * Instead, Generate a completely bogus master key .
- */
- PK11_GenerateRandom(dk, dkLen);
- }
-
- /*
- ** Construct master key out of the pieces.
- */
- if (ckLen) {
- PORT_Memcpy(mkbuf, ck, ckLen);
- }
- PORT_Memcpy(mkbuf + ckLen, dk, dkLen);
-
- /* Fill in session-id */
- rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen,
- keyBits, keyBits - (ckLen<<3),
- ss->sec.authAlgorithm, ss->sec.authKeyBits,
- ss->sec.keaType, ss->sec.keaKeyBits);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* Create session ciphers */
- rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d",
- SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
- ckLen<<3, keySize<<3));
- rv = SECSuccess;
- goto done;
-
- loser:
- rv = SECFailure;
-
- done:
- PORT_Free(kbuf);
- return rv;
-}
-
-/************************************************************************/
-
-/*
-** Rewrite the incoming cipher specs, comparing to list of specs we support,
-** (ss->cipherSpecs) and eliminating anything we don't support
-**
-* Note: Our list may contain SSL v3 ciphers.
-* We MUST NOT match on any of those.
-* Fortunately, this is easy to detect because SSLv3 ciphers have zero
-* in the first byte, and none of the SSLv2 ciphers do.
-*
-* Called from ssl2_HandleClientHelloMessage().
-* Returns the number of bytes of "qualified cipher specs",
-* which is typically a multiple of 3, but will be zero if there are none.
-*/
-static int
-ssl2_QualifyCypherSpecs(sslSocket *ss,
- PRUint8 * cs, /* cipher specs in client hello msg. */
- int csLen)
-{
- PRUint8 * ms;
- PRUint8 * hs;
- PRUint8 * qs;
- int mc;
- int hc;
- PRUint8 qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3];
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
-
- if (!ss->cipherSpecs) {
- SECStatus rv = ssl2_ConstructCipherSpecs(ss);
- if (rv != SECSuccess || !ss->cipherSpecs)
- return 0;
- }
-
- PRINT_BUF(10, (ss, "specs from client:", cs, csLen));
- qs = qualifiedSpecs;
- ms = ss->cipherSpecs;
- for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) {
- if (ms[0] == 0)
- continue;
- for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) {
- if ((hs[0] == ms[0]) &&
- (hs[1] == ms[1]) &&
- (hs[2] == ms[2])) {
- /* Copy this cipher spec into the "keep" section */
- qs[0] = hs[0];
- qs[1] = hs[1];
- qs[2] = hs[2];
- qs += 3;
- break;
- }
- }
- }
- hc = qs - qualifiedSpecs;
- PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc));
- PORT_Memcpy(cs, qualifiedSpecs, hc);
- return hc;
-}
-
-/*
-** Pick the best cipher we can find, given the array of server cipher
-** specs. Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap.
-** If successful, stores the master key size (bytes) in *pKeyLen.
-**
-** This is correct only for the client side, but presently
-** this function is only called from
-** ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
-**
-** Note that most servers only return a single cipher suite in their
-** ServerHello messages. So, the code below for finding the "best" cipher
-** suite usually has only one choice. The client and server should send
-** their cipher suite lists sorted in descending order by preference.
-*/
-static int
-ssl2_ChooseSessionCypher(sslSocket *ss,
- int hc, /* number of cs's in hs. */
- PRUint8 * hs, /* server hello's cipher suites. */
- int * pKeyLen) /* out: sym key size in bytes. */
-{
- PRUint8 * ms;
- unsigned int i;
- int bestKeySize;
- int bestRealKeySize;
- int bestCypher;
- int keySize;
- int realKeySize;
- PRUint8 * ohs = hs;
- const PRUint8 * preferred;
- static const PRUint8 noneSuch[3] = { 0, 0, 0 };
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
-
- if (!ss->cipherSpecs) {
- SECStatus rv = ssl2_ConstructCipherSpecs(ss);
- if (rv != SECSuccess || !ss->cipherSpecs)
- goto loser;
- }
-
- if (!ss->preferredCipher) {
- unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference &
- SSL_CB_IMPLEMENTED;
- if (allowed) {
- preferred = implementedCipherSuites;
- for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) {
- if (0 != (allowed & (1U << preferred[0]))) {
- ss->preferredCipher = preferred;
- break;
- }
- preferred += 3;
- }
- }
- }
- preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch;
- /*
- ** Scan list of ciphers received from peer and look for a match in
- ** our list.
- * Note: Our list may contain SSL v3 ciphers.
- * We MUST NOT match on any of those.
- * Fortunately, this is easy to detect because SSLv3 ciphers have zero
- * in the first byte, and none of the SSLv2 ciphers do.
- */
- bestKeySize = bestRealKeySize = 0;
- bestCypher = -1;
- while (--hc >= 0) {
- for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) {
- if ((hs[0] == preferred[0]) &&
- (hs[1] == preferred[1]) &&
- (hs[2] == preferred[2]) &&
- hs[0] != 0) {
- /* Pick this cipher immediately! */
- *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3;
- return hs[0];
- }
- if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) &&
- hs[0] != 0) {
- /* Found a match */
-
- /* Use secret keySize to determine which cipher is best */
- realKeySize = (hs[1] << 8) | hs[2];
- switch (hs[0]) {
- case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
- case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
- keySize = 40;
- break;
- default:
- keySize = realKeySize;
- break;
- }
- if (keySize > bestKeySize) {
- bestCypher = hs[0];
- bestKeySize = keySize;
- bestRealKeySize = realKeySize;
- }
- }
- }
- hs += 3;
- }
- if (bestCypher < 0) {
- /*
- ** No overlap between server and client. Re-examine server list
- ** to see what kind of ciphers it does support so that we can set
- ** the error code appropriately.
- */
- if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) ||
- (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) {
- PORT_SetError(SSL_ERROR_US_ONLY_SERVER);
- } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) ||
- (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) {
- PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER);
- } else {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- }
- SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd));
- goto loser;
- }
- *pKeyLen = (bestRealKeySize + 7) >> 3;
- return bestCypher;
-
- loser:
- return -1;
-}
-
-static SECStatus
-ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen)
-{
- CERTCertificate *cert = NULL;
- SECItem certItem;
-
- certItem.data = certData;
- certItem.len = certLen;
-
- /* decode the certificate */
- cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
-
- if (cert == NULL) {
- SSL_DBG(("%d: SSL[%d]: decode of server certificate fails",
- SSL_GETPID(), ss->fd));
- PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
- return SECFailure;
- }
-
-#ifdef TRACE
- {
- if (ssl_trace >= 1) {
- char *issuer;
- char *subject;
- issuer = CERT_NameToAscii(&cert->issuer);
- subject = CERT_NameToAscii(&cert->subject);
- SSL_TRC(1,("%d: server certificate issuer: '%s'",
- SSL_GETPID(), issuer ? issuer : "OOPS"));
- SSL_TRC(1,("%d: server name: '%s'",
- SSL_GETPID(), subject ? subject : "OOPS"));
- PORT_Free(issuer);
- PORT_Free(subject);
- }
- }
-#endif
-
- ss->sec.peerCert = cert;
- return SECSuccess;
-}
-
-
-/*
- * Format one block of data for public/private key encryption using
- * the rules defined in PKCS #1. SSL2 does this itself to handle the
- * rollback detection.
- */
-#define RSA_BLOCK_MIN_PAD_LEN 8
-#define RSA_BLOCK_FIRST_OCTET 0x00
-#define RSA_BLOCK_AFTER_PAD_OCTET 0x00
-#define RSA_BLOCK_PUBLIC_OCTET 0x02
-unsigned char *
-ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data)
-{
- unsigned char *block;
- unsigned char *bp;
- int padLen;
- SECStatus rv;
- int i;
-
- if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) {
- PORT_SetError(SEC_ERROR_BAD_KEY);
- return NULL;
- }
- block = (unsigned char *) PORT_Alloc(modulusLen);
- if (block == NULL)
- return NULL;
-
- bp = block;
-
- /*
- * All RSA blocks start with two octets:
- * 0x00 || BlockType
- */
- *bp++ = RSA_BLOCK_FIRST_OCTET;
- *bp++ = RSA_BLOCK_PUBLIC_OCTET;
-
- /*
- * 0x00 || BT || Pad || 0x00 || ActualData
- * 1 1 padLen 1 data->len
- * Pad is all non-zero random bytes.
- */
- padLen = modulusLen - data->len - 3;
- PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
- rv = PK11_GenerateRandom(bp, padLen);
- if (rv == SECFailure) goto loser;
- /* replace all the 'zero' bytes */
- for (i = 0; i < padLen; i++) {
- while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
- rv = PK11_GenerateRandom(bp+i, 1);
- if (rv == SECFailure) goto loser;
- }
- }
- bp += padLen;
- *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
- PORT_Memcpy (bp, data->data, data->len);
-
- return block;
-loser:
- if (block) PORT_Free(block);
- return NULL;
-}
-
-/*
-** Given the server's public key and cipher specs, generate a session key
-** that is ready to use for encrypting/decrypting the byte stream. At
-** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and
-** send it to the server.
-**
-** Called from ssl2_HandleServerHelloMessage()
-*/
-static SECStatus
-ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
-{
- sslSessionID * sid;
- PRUint8 * ca; /* points to iv data, or NULL if none. */
- PRUint8 * ekbuf = 0;
- CERTCertificate * cert = 0;
- SECKEYPublicKey * serverKey = 0;
- unsigned modulusLen = 0;
- SECStatus rv;
- int cipher;
- int keyLen; /* cipher symkey size in bytes. */
- int ckLen; /* publicly reveal this many bytes of key. */
- int caLen; /* length of IV data at *ca. */
- int nc;
-
- unsigned char *eblock; /* holds unencrypted PKCS#1 formatted key. */
- SECItem rek; /* holds portion of symkey to be encrypted. */
-
- PRUint8 keyData[SSL_MAX_MASTER_KEY_BYTES];
- PRUint8 iv [8];
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- eblock = NULL;
-
- sid = ss->sec.ci.sid;
- PORT_Assert(sid != 0);
-
- cert = ss->sec.peerCert;
-
- serverKey = CERT_ExtractPublicKey(cert);
- if (!serverKey) {
- SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
- rv = SECFailure;
- goto loser2;
- }
-
- ss->sec.authAlgorithm = ssl_sign_rsa;
- ss->sec.keaType = ssl_kea_rsa;
- ss->sec.keaKeyBits = \
- ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey);
-
- /* Choose a compatible cipher with the server */
- nc = csLen / 3;
- cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen);
- if (cipher < 0) {
- /* ssl2_ChooseSessionCypher has set error code. */
- ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
- goto loser;
- }
-
- /* Generate the random keys */
- PK11_GenerateRandom(keyData, sizeof(keyData));
-
- /*
- ** Next, carve up the keys into clear and encrypted portions. The
- ** clear data is taken from the start of keyData and the encrypted
- ** portion from the remainder. Note that each of these portions is
- ** carved in half, one half for the read-key and one for the
- ** write-key.
- */
- ca = 0;
-
- /* We know that cipher is a legit value here, because
- * ssl2_ChooseSessionCypher doesn't return bogus values.
- */
- ckLen = ssl_Specs[cipher].pubLen; /* cleartext key length. */
- caLen = ssl_Specs[cipher].ivLen; /* IV length. */
- if (caLen) {
- PORT_Assert(sizeof iv >= caLen);
- PK11_GenerateRandom(iv, caLen);
- ca = iv;
- }
-
- /* Fill in session-id */
- rv = ssl2_FillInSID(sid, cipher, keyData, keyLen,
- ca, caLen, keyLen << 3, (keyLen - ckLen) << 3,
- ss->sec.authAlgorithm, ss->sec.authKeyBits,
- ss->sec.keaType, ss->sec.keaKeyBits);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d",
- SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
- ckLen<<3, keyLen<<3));
-
- /* Now setup read and write ciphers */
- rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /*
- ** Fill in the encryption buffer with some random bytes. Then
- ** copy in the portion of the session key we are encrypting.
- */
- modulusLen = SECKEY_PublicKeyStrength(serverKey);
- rek.data = keyData + ckLen;
- rek.len = keyLen - ckLen;
- eblock = ssl_FormatSSL2Block(modulusLen, &rek);
- if (eblock == NULL)
- goto loser;
-
- /* Set up the padding for version 2 rollback detection. */
- /* XXX We should really use defines here */
- if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- PORT_Assert((modulusLen - rek.len) > 12);
- PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8);
- }
- ekbuf = (PRUint8*) PORT_Alloc(modulusLen);
- if (!ekbuf)
- goto loser;
- PRINT_BUF(10, (ss, "master key encryption block:",
- eblock, modulusLen));
-
- /* Encrypt ekitem */
- rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen,
- ss->pkcs11PinArg);
- if (rv)
- goto loser;
-
- /* Now we have everything ready to send */
- rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen,
- keyData, ckLen, ekbuf, modulusLen);
- if (rv != SECSuccess) {
- goto loser;
- }
- rv = SECSuccess;
- goto done;
-
- loser:
- rv = SECFailure;
-
- loser2:
- done:
- PORT_Memset(keyData, 0, sizeof(keyData));
- PORT_ZFree(ekbuf, modulusLen);
- PORT_ZFree(eblock, modulusLen);
- SECKEY_DestroyPublicKey(serverKey);
- return rv;
-}
-
-/************************************************************************/
-
-/*
- * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message.
- * Caller holds recvBufLock and handshakeLock
- */
-static void
-ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s)
-{
- sslSessionID *sid = ss->sec.ci.sid;
-
- /* Record entry in nonce cache */
- if (sid->peerCert == NULL) {
- PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID));
- sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
-
- }
- if (!ss->opt.noCache)
- (*ss->sec.cache)(sid);
-}
-
-/* Called from ssl2_HandleMessage() */
-static SECStatus
-ssl2_TriggerNextMessage(sslSocket *ss)
-{
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) &&
- !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) {
- ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE;
- rv = ssl2_SendCertificateRequestMessage(ss);
- return rv;
- }
- return SECSuccess;
-}
-
-/* See if it's time to send our finished message, or if the handshakes are
-** complete. Send finished message if appropriate.
-** Returns SECSuccess unless anything goes wrong.
-**
-** Called from ssl2_HandleMessage,
-** ssl2_HandleVerifyMessage
-** ssl2_HandleServerHelloMessage
-** ssl2_HandleClientSessionKeyMessage
-*/
-static SECStatus
-ssl2_TryToFinish(sslSocket *ss)
-{
- SECStatus rv;
- char e, ef;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- e = ss->sec.ci.elements;
- ef = e | CIS_HAVE_FINISHED;
- if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
- if (ss->sec.isServer) {
- /* Send server finished message if we already didn't */
- rv = ssl2_SendServerFinishedMessage(ss);
- } else {
- /* Send client finished message if we already didn't */
- rv = ssl2_SendClientFinishedMessage(ss);
- }
- if (rv != SECSuccess) {
- return rv;
- }
- if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
- /* Totally finished */
- ss->handshake = 0;
- return SECSuccess;
- }
- }
- return SECSuccess;
-}
-
-/*
-** Called from ssl2_HandleRequestCertificate
-*/
-static SECStatus
-ssl2_SignResponse(sslSocket *ss,
- SECKEYPrivateKey *key,
- SECItem *response)
-{
- SGNContext * sgn = NULL;
- PRUint8 * challenge;
- unsigned int len;
- SECStatus rv = SECFailure;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- challenge = ss->sec.ci.serverChallenge;
- len = ss->sec.ci.serverChallengeLen;
-
- /* Sign the expected data... */
- sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key);
- if (!sgn)
- goto done;
- rv = SGN_Begin(sgn);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_Update(sgn, challenge, len);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data,
- ss->sec.peerCert->derCert.len);
- if (rv != SECSuccess)
- goto done;
- rv = SGN_End(sgn, response);
- if (rv != SECSuccess)
- goto done;
-
-done:
- SGN_DestroyContext(sgn, PR_TRUE);
- return rv == SECSuccess ? SECSuccess : SECFailure;
-}
-
-/*
-** Try to handle a request-certificate message. Get client's certificate
-** and private key and sign a message for the server to see.
-** Caller must hold handshakeLock
-**
-** Called from ssl2_HandleMessage().
-*/
-static int
-ssl2_HandleRequestCertificate(sslSocket *ss)
-{
- CERTCertificate * cert = NULL; /* app-selected client cert. */
- SECKEYPrivateKey *key = NULL; /* priv key for cert. */
- SECStatus rv;
- SECItem response;
- int ret = 0;
- PRUint8 authType;
-
-
- /*
- * These things all need to be initialized before we can "goto loser".
- */
- response.data = NULL;
-
- /* get challenge info from connectionInfo */
- authType = ss->sec.ci.authType;
-
- if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) {
- SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(),
- ss->fd, authType));
- goto no_cert_error;
- }
-
- /* Get certificate and private-key from client */
- if (!ss->getClientAuthData) {
- SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth",
- SSL_GETPID(), ss->fd));
- goto no_cert_error;
- }
- ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd,
- NULL, &cert, &key);
- if ( ret == SECWouldBlock ) {
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
- ret = -1;
- goto loser;
- }
-
- if (ret) {
- goto no_cert_error;
- }
-
- /* check what the callback function returned */
- if ((!cert) || (!key)) {
- /* we are missing either the key or cert */
- if (cert) {
- /* got a cert, but no key - free it */
- CERT_DestroyCertificate(cert);
- cert = NULL;
- }
- if (key) {
- /* got a key, but no cert - free it */
- SECKEY_DestroyPrivateKey(key);
- key = NULL;
- }
- goto no_cert_error;
- }
-
- rv = ssl2_SignResponse(ss, key, &response);
- if ( rv != SECSuccess ) {
- ret = -1;
- goto loser;
- }
-
- /* Send response message */
- ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
-
- /* Now, remember the cert we sent. But first, forget any previous one. */
- if (ss->sec.localCert) {
- CERT_DestroyCertificate(ss->sec.localCert);
- }
- ss->sec.localCert = CERT_DupCertificate(cert);
- PORT_Assert(!ss->sec.ci.sid->localCert);
- if (ss->sec.ci.sid->localCert) {
- CERT_DestroyCertificate(ss->sec.ci.sid->localCert);
- }
- ss->sec.ci.sid->localCert = cert;
- cert = NULL;
-
- goto done;
-
- no_cert_error:
- SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(),
- ss->fd, ret));
- ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
-
- loser:
- done:
- if ( cert ) {
- CERT_DestroyCertificate(cert);
- }
- if ( key ) {
- SECKEY_DestroyPrivateKey(key);
- }
- if ( response.data ) {
- PORT_Free(response.data);
- }
-
- return ret;
-}
-
-/*
-** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message.
-** Caller must hold HandshakeLock and RecvBufLock, since cd and response
-** are contained in the gathered input data.
-*/
-static SECStatus
-ssl2_HandleClientCertificate(sslSocket * ss,
- PRUint8 certType, /* XXX unused */
- PRUint8 * cd,
- unsigned int cdLen,
- PRUint8 * response,
- unsigned int responseLen)
-{
- CERTCertificate *cert = NULL;
- SECKEYPublicKey *pubKey = NULL;
- VFYContext * vfy = NULL;
- SECItem * derCert;
- SECStatus rv = SECFailure;
- SECItem certItem;
- SECItem rep;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
-
- /* Extract the certificate */
- certItem.data = cd;
- certItem.len = cdLen;
-
- cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
- if (cert == NULL) {
- goto loser;
- }
-
- /* save the certificate, since the auth routine will need it */
- ss->sec.peerCert = cert;
-
- /* Extract the public key */
- pubKey = CERT_ExtractPublicKey(cert);
- if (!pubKey)
- goto loser;
-
- /* Verify the response data... */
- rep.data = response;
- rep.len = responseLen;
- /* SSL 2.0 only supports RSA certs, so we don't have to worry about
- * DSA here. */
- vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION,
- ss->pkcs11PinArg);
- if (!vfy)
- goto loser;
- rv = VFY_Begin(vfy);
- if (rv)
- goto loser;
-
- rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize);
- if (rv)
- goto loser;
- rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize);
- if (rv)
- goto loser;
- rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
- if (rv)
- goto loser;
-
- derCert = &ss->serverCerts[kt_rsa].serverCert->derCert;
- rv = VFY_Update(vfy, derCert->data, derCert->len);
- if (rv)
- goto loser;
- rv = VFY_End(vfy);
- if (rv)
- goto loser;
-
- /* Now ask the server application if it likes the certificate... */
- rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg,
- ss->fd, PR_TRUE, PR_TRUE);
- /* Hey, it liked it. */
- if (SECSuccess == rv)
- goto done;
-
-loser:
- ss->sec.peerCert = NULL;
- CERT_DestroyCertificate(cert);
-
-done:
- VFY_DestroyContext(vfy, PR_TRUE);
- SECKEY_DestroyPublicKey(pubKey);
- return rv;
-}
-
-/*
-** Handle remaining messages between client/server. Process finished
-** messages from either side and any authentication requests.
-** This should only be called for SSLv2 handshake messages,
-** not for application data records.
-** Caller must hold handshake lock.
-**
-** Called from ssl_Do1stHandshake().
-**
-*/
-static SECStatus
-ssl2_HandleMessage(sslSocket *ss)
-{
- PRUint8 * data;
- PRUint8 * cid;
- unsigned len, certType, certLen, responseLen;
- int rv;
- int rv2;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- ssl_GetRecvBufLock(ss);
-
- data = ss->gs.buf.buf + ss->gs.recordOffset;
-
- if (ss->gs.recordLen < 1) {
- goto bad_peer;
- }
- SSL_TRC(3, ("%d: SSL[%d]: received %d message",
- SSL_GETPID(), ss->fd, data[0]));
- DUMP_MSG(29, (ss, data, ss->gs.recordLen));
-
- switch (data[0]) {
- case SSL_MT_CLIENT_FINISHED:
- if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
- SSL_DBG(("%d: SSL[%d]: dup client-finished message",
- SSL_GETPID(), ss->fd));
- goto bad_peer;
- }
-
- /* See if nonce matches */
- len = ss->gs.recordLen - 1;
- cid = data + 1;
- if ((len != sizeof(ss->sec.ci.connectionID)) ||
- (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) {
- SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd));
- PRINT_BUF(5, (ss, "sent connection-id",
- ss->sec.ci.connectionID,
- sizeof(ss->sec.ci.connectionID)));
- PRINT_BUF(5, (ss, "rcvd connection-id", cid, len));
- goto bad_peer;
- }
-
- SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d",
- SSL_GETPID(), ss->fd,
- ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
- ss->sec.ci.elements |= CIS_HAVE_FINISHED;
- break;
-
- case SSL_MT_SERVER_FINISHED:
- if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
- SSL_DBG(("%d: SSL[%d]: dup server-finished message",
- SSL_GETPID(), ss->fd));
- goto bad_peer;
- }
-
- if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) {
- SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d",
- SSL_GETPID(), ss->fd, ss->gs.recordLen));
- goto bad_peer;
- }
- ssl2_ClientRegSessionID(ss, data+1);
- SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d",
- SSL_GETPID(), ss->fd,
- ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
- ss->sec.ci.elements |= CIS_HAVE_FINISHED;
- break;
-
- case SSL_MT_REQUEST_CERTIFICATE:
- len = ss->gs.recordLen - 2;
- if ((len < SSL_MIN_CHALLENGE_BYTES) ||
- (len > SSL_MAX_CHALLENGE_BYTES)) {
- /* Bad challenge */
- SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d",
- SSL_GETPID(), ss->fd, len));
- goto bad_peer;
- }
-
- /* save auth request info */
- ss->sec.ci.authType = data[1];
- ss->sec.ci.serverChallengeLen = len;
- PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len);
-
- rv = ssl2_HandleRequestCertificate(ss);
- if (rv == SECWouldBlock) {
- SSL_TRC(3, ("%d: SSL[%d]: async cert request",
- SSL_GETPID(), ss->fd));
- /* someone is handling this asynchronously */
- ssl_ReleaseRecvBufLock(ss);
- return SECWouldBlock;
- }
- if (rv) {
- SET_ERROR_CODE
- goto loser;
- }
- break;
-
- case SSL_MT_CLIENT_CERTIFICATE:
- if (!ss->authCertificate) {
- /* Server asked for authentication and can't handle it */
- PORT_SetError(SSL_ERROR_BAD_SERVER);
- goto loser;
- }
- if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) {
- SET_ERROR_CODE
- goto loser;
- }
- certType = data[1];
- certLen = (data[2] << 8) | data[3];
- responseLen = (data[4] << 8) | data[5];
- if (certType != SSL_CT_X509_CERTIFICATE) {
- PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
- goto loser;
- }
- if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES
- > ss->gs.recordLen) {
- /* prevent overflow crash. */
- rv = SECFailure;
- } else
- rv = ssl2_HandleClientCertificate(ss, data[1],
- data + SSL_HL_CLIENT_CERTIFICATE_HBYTES,
- certLen,
- data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen,
- responseLen);
- if (rv) {
- rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
- SET_ERROR_CODE
- goto loser;
- }
- ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE;
- break;
-
- case SSL_MT_ERROR:
- rv = (data[1] << 8) | data[2];
- SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x",
- SSL_GETPID(), ss->fd, rv));
-
- /* Convert protocol error number into API error number */
- switch (rv) {
- case SSL_PE_NO_CYPHERS:
- rv = SSL_ERROR_NO_CYPHER_OVERLAP;
- break;
- case SSL_PE_NO_CERTIFICATE:
- rv = SSL_ERROR_NO_CERTIFICATE;
- break;
- case SSL_PE_BAD_CERTIFICATE:
- rv = SSL_ERROR_BAD_CERTIFICATE;
- break;
- case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE:
- rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
- break;
- default:
- goto bad_peer;
- }
- /* XXX make certificate-request optionally fail... */
- PORT_SetError(rv);
- goto loser;
-
- default:
- SSL_DBG(("%d: SSL[%d]: unknown message %d",
- SSL_GETPID(), ss->fd, data[0]));
- goto loser;
- }
-
- SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x",
- SSL_GETPID(), ss->fd, data[0],
- ss->sec.ci.requiredElements, ss->sec.ci.elements));
-
- rv = ssl2_TryToFinish(ss);
- if (rv != SECSuccess)
- goto loser;
-
- ss->gs.recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- if (ss->handshake == 0) {
- return SECSuccess;
- }
-
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleMessage;
- return ssl2_TriggerNextMessage(ss);
-
- bad_peer:
- PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER);
- /* FALL THROUGH */
-
- loser:
- ssl_ReleaseRecvBufLock(ss);
- return SECFailure;
-}
-
-/************************************************************************/
-
-/* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage.
-*/
-static SECStatus
-ssl2_HandleVerifyMessage(sslSocket *ss)
-{
- PRUint8 * data;
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- ssl_GetRecvBufLock(ss);
-
- data = ss->gs.buf.buf + ss->gs.recordOffset;
- DUMP_MSG(29, (ss, data, ss->gs.recordLen));
- if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) ||
- (data[0] != SSL_MT_SERVER_VERIFY) ||
- NSS_SecureMemcmp(data+1, ss->sec.ci.clientChallenge,
- SSL_CHALLENGE_BYTES)) {
- /* Bad server */
- PORT_SetError(SSL_ERROR_BAD_SERVER);
- goto loser;
- }
- ss->sec.ci.elements |= CIS_HAVE_VERIFY;
-
- SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x",
- SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
- ss->sec.ci.elements));
-
- rv = ssl2_TryToFinish(ss);
- if (rv)
- goto loser;
-
- ss->gs.recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- if (ss->handshake == 0) {
- return SECSuccess;
- }
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleMessage;
- return SECSuccess;
-
-
- loser:
- ssl_ReleaseRecvBufLock(ss);
- return SECFailure;
-}
-
-/* Not static because ssl2_GatherData() tests ss->nextHandshake for this value.
- * ICK!
- * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake()
- */
-SECStatus
-ssl2_HandleServerHelloMessage(sslSocket *ss)
-{
- sslSessionID * sid;
- PRUint8 * cert;
- PRUint8 * cs;
- PRUint8 * data;
- SECStatus rv;
- int needed, sidHit, certLen, csLen, cidLen, certType, err;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- if (!ss->opt.enableSSL2) {
- PORT_SetError(SSL_ERROR_SSL2_DISABLED);
- return SECFailure;
- }
-
- ssl_GetRecvBufLock(ss);
-
- PORT_Assert(ss->sec.ci.sid != 0);
- sid = ss->sec.ci.sid;
-
- data = ss->gs.buf.buf + ss->gs.recordOffset;
- DUMP_MSG(29, (ss, data, ss->gs.recordLen));
-
- /* Make sure first message has some data and is the server hello message */
- if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES)
- || (data[0] != SSL_MT_SERVER_HELLO)) {
- if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) {
- err = (data[1] << 8) | data[2];
- if (err == SSL_PE_NO_CYPHERS) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- goto loser;
- }
- }
- goto bad_server;
- }
-
- sidHit = data[1];
- certType = data[2];
- ss->version = (data[3] << 8) | data[4];
- certLen = (data[5] << 8) | data[6];
- csLen = (data[7] << 8) | data[8];
- cidLen = (data[9] << 8) | data[10];
- cert = data + SSL_HL_SERVER_HELLO_HBYTES;
- cs = cert + certLen;
-
- SSL_TRC(5,
- ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d",
- SSL_GETPID(), ss->fd, sidHit, ss->version, certLen,
- csLen, cidLen));
- if (ss->version != SSL_LIBRARY_VERSION_2) {
- if (ss->version < SSL_LIBRARY_VERSION_2) {
- SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)",
- SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2,
- ss->version));
- } else {
- SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)",
- SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
- /* server claims to be newer but does not follow protocol */
- PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
- goto loser;
- }
- }
-
- if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen
- > ss->gs.recordLen)
- || (csLen % 3) != 0
- /* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32 */
- ) {
- goto bad_server;
- }
-
- /* Save connection-id.
- ** This code only saves the first 16 byte of the connectionID.
- ** If the connectionID is shorter than 16 bytes, it is zero-padded.
- */
- if (cidLen < sizeof ss->sec.ci.connectionID)
- memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID);
- cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID);
- PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen);
-
- /* See if session-id hit */
- needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY;
- if (sidHit) {
- if (certLen || csLen) {
- /* Uh oh - bogus server */
- SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d",
- SSL_GETPID(), ss->fd, sidHit, certLen, csLen));
- goto bad_server;
- }
-
- /* Total winner. */
- SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x "
- "port=0x%04x",
- SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port));
- ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
- ss->sec.authAlgorithm = sid->authAlgorithm;
- ss->sec.authKeyBits = sid->authKeyBits;
- ss->sec.keaType = sid->keaType;
- ss->sec.keaKeyBits = sid->keaKeyBits;
- rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
- if (rv != SECSuccess) {
- goto loser;
- }
- } else {
- if (certType != SSL_CT_X509_CERTIFICATE) {
- PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
- goto loser;
- }
- if (csLen == 0) {
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- SSL_DBG(("%d: SSL[%d]: no cipher overlap",
- SSL_GETPID(), ss->fd));
- goto loser;
- }
- if (certLen == 0) {
- SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d",
- SSL_GETPID(), ss->fd, certLen, csLen));
- goto bad_server;
- }
-
- if (sid->cached != never_cached) {
- /* Forget our session-id - server didn't like it */
- SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id",
- SSL_GETPID(), ss->fd));
- if (ss->sec.uncache)
- (*ss->sec.uncache)(sid);
- ssl_FreeSID(sid);
- ss->sec.ci.sid = sid = PORT_ZNew(sslSessionID);
- if (!sid) {
- goto loser;
- }
- sid->references = 1;
- sid->addr = ss->sec.ci.peer;
- sid->port = ss->sec.ci.port;
- }
-
- /* decode the server's certificate */
- rv = ssl2_ClientHandleServerCert(ss, cert, certLen);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
- (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
- }
- goto loser;
- }
-
- /* Setup new session cipher */
- rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen);
- if (rv != SECSuccess) {
- if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
- (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
- }
- goto loser;
- }
- }
-
- /* Build up final list of required elements */
- ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
- ss->sec.ci.requiredElements = needed;
-
- if (!sidHit) {
- /* verify the server's certificate. if sidHit, don't check signatures */
- rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd,
- (PRBool)(!sidHit), PR_FALSE);
- if (rv) {
- if (ss->handleBadCert) {
- rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
- if ( rv ) {
- if ( rv == SECWouldBlock ) {
- SSL_DBG(("%d: SSL[%d]: SSL2 bad cert handler returned "
- "SECWouldBlock", SSL_GETPID(), ss->fd));
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
- rv = SECFailure;
- } else {
- /* cert is bad */
- SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- }
- goto loser;
- }
- /* cert is good */
- } else {
- SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- goto loser;
- }
- }
- }
- /*
- ** At this point we have a completed session key and our session
- ** cipher is setup and ready to go. Switch to encrypted write routine
- ** as all future message data is to be encrypted.
- */
- ssl2_UseEncryptedSendFunc(ss);
-
- rv = ssl2_TryToFinish(ss);
- if (rv != SECSuccess)
- goto loser;
-
- ss->gs.recordLen = 0;
-
- ssl_ReleaseRecvBufLock(ss);
-
- if (ss->handshake == 0) {
- return SECSuccess;
- }
-
- SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
- SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
- ss->sec.ci.elements));
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleVerifyMessage;
- return SECSuccess;
-
- bad_server:
- PORT_SetError(SSL_ERROR_BAD_SERVER);
- /* FALL THROUGH */
-
- loser:
- ssl_ReleaseRecvBufLock(ss);
- return SECFailure;
-}
-
-/* Sends out the initial client Hello message on the connection.
- * Acquires and releases the socket's xmitBufLock.
- */
-SECStatus
-ssl2_BeginClientHandshake(sslSocket *ss)
-{
- sslSessionID *sid;
- PRUint8 *msg;
- PRUint8 *cp;
- PRUint8 *localCipherSpecs = NULL;
- unsigned int localCipherSize;
- unsigned int i;
- int sendLen, sidLen = 0;
- SECStatus rv;
- TLSExtensionData *xtnData;
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- ss->sec.isServer = 0;
- ss->sec.sendSequence = 0;
- ss->sec.rcvSequence = 0;
- ssl_ChooseSessionIDProcs(&ss->sec);
-
- if (!ss->cipherSpecs) {
- rv = ssl2_ConstructCipherSpecs(ss);
- if (rv != SECSuccess)
- goto loser;
- }
-
- /* count the SSL2 and SSL3 enabled ciphers.
- * if either is zero, clear the socket's enable for that protocol.
- */
- rv = ssl2_CheckConfigSanity(ss);
- if (rv != SECSuccess)
- goto loser;
-
- /* Get peer name of server */
- rv = ssl_GetPeerInfo(ss);
- if (rv < 0) {
-#ifdef HPUX11
- /*
- * On some HP-UX B.11.00 systems, getpeername() occasionally
- * fails with ENOTCONN after a successful completion of
- * non-blocking connect. I found that if we do a write()
- * and then retry getpeername(), it will work.
- */
- if (PR_GetError() == PR_NOT_CONNECTED_ERROR) {
- char dummy;
- (void) PR_Write(ss->fd->lower, &dummy, 0);
- rv = ssl_GetPeerInfo(ss);
- if (rv < 0) {
- goto loser;
- }
- }
-#else
- goto loser;
-#endif
- }
-
- SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd));
-
- /* Try to find server in our session-id cache */
- if (ss->opt.noCache) {
- sid = NULL;
- } else {
- sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID,
- ss->url);
- }
- while (sid) { /* this isn't really a loop */
- PRBool sidVersionEnabled =
- (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) &&
- sid->version >= ss->vrange.min &&
- sid->version <= ss->vrange.max) ||
- (sid->version < SSL_LIBRARY_VERSION_3_0 && ss->opt.enableSSL2);
-
- /* if we're not doing this SID's protocol any more, drop it. */
- if (!sidVersionEnabled) {
- if (ss->sec.uncache)
- ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- break;
- }
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- /* If the cipher in this sid is not enabled, drop it. */
- for (i = 0; i < ss->sizeCipherSpecs; i += 3) {
- if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType)
- break;
- }
- if (i >= ss->sizeCipherSpecs) {
- if (ss->sec.uncache)
- ss->sec.uncache(sid);
- ssl_FreeSID(sid);
- sid = NULL;
- break;
- }
- }
- sidLen = sizeof(sid->u.ssl2.sessionID);
- PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID,
- sidLen));
- ss->version = sid->version;
- PORT_Assert(!ss->sec.localCert);
- if (ss->sec.localCert) {
- CERT_DestroyCertificate(ss->sec.localCert);
- }
- ss->sec.localCert = CERT_DupCertificate(sid->localCert);
- break; /* this isn't really a loop */
- }
- if (!sid) {
- sidLen = 0;
- sid = PORT_ZNew(sslSessionID);
- if (!sid) {
- goto loser;
- }
- sid->references = 1;
- sid->cached = never_cached;
- sid->addr = ss->sec.ci.peer;
- sid->port = ss->sec.ci.port;
- if (ss->peerID != NULL) {
- sid->peerID = PORT_Strdup(ss->peerID);
- }
- if (ss->url != NULL) {
- sid->urlSvrName = PORT_Strdup(ss->url);
- }
- }
- ss->sec.ci.sid = sid;
-
- PORT_Assert(sid != NULL);
-
- if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) &&
- !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- ss->gs.state = GS_INIT;
- ss->handshake = ssl_GatherRecord1stHandshake;
-
- /* ssl3_SendClientHello will override this if it succeeds. */
- ss->version = SSL_LIBRARY_VERSION_3_0;
-
- ssl_GetSSL3HandshakeLock(ss);
- ssl_GetXmitBufLock(ss);
- rv = ssl3_SendClientHello(ss, PR_FALSE);
- ssl_ReleaseXmitBufLock(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
-
- return rv;
- }
-#if defined(NSS_ENABLE_ECC)
- /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */
- ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
- if (ss->cipherSpecs != NULL) {
- PORT_Free(ss->cipherSpecs);
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0;
- }
-#endif
-
- if (!ss->cipherSpecs) {
- rv = ssl2_ConstructCipherSpecs(ss);
- if (rv < 0) {
- return rv;
- }
- }
- localCipherSpecs = ss->cipherSpecs;
- localCipherSize = ss->sizeCipherSpecs;
-
- /* Add 3 for SCSV */
- sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + 3 + sidLen +
- SSL_CHALLENGE_BYTES;
-
- /* Generate challenge bytes for server */
- PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
-
- ssl_GetXmitBufLock(ss); /***************************************/
-
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv)
- goto unlock_loser;
-
- /* Construct client-hello message */
- cp = msg = ss->sec.ci.sendBuf.buf;
- msg[0] = SSL_MT_CLIENT_HELLO;
- ss->clientHelloVersion = SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) ?
- SSL_LIBRARY_VERSION_2 : ss->vrange.max;
-
- msg[1] = MSB(ss->clientHelloVersion);
- msg[2] = LSB(ss->clientHelloVersion);
- /* Add 3 for SCSV */
- msg[3] = MSB(localCipherSize + 3);
- msg[4] = LSB(localCipherSize + 3);
- msg[5] = MSB(sidLen);
- msg[6] = LSB(sidLen);
- msg[7] = MSB(SSL_CHALLENGE_BYTES);
- msg[8] = LSB(SSL_CHALLENGE_BYTES);
- cp += SSL_HL_CLIENT_HELLO_HBYTES;
- PORT_Memcpy(cp, localCipherSpecs, localCipherSize);
- cp += localCipherSize;
- /*
- * Add SCSV. SSL 2.0 cipher suites are listed before SSL 3.0 cipher
- * suites in localCipherSpecs for compatibility with SSL 2.0 servers.
- * Since SCSV looks like an SSL 3.0 cipher suite, we can't add it at
- * the beginning.
- */
- cp[0] = 0x00;
- cp[1] = 0x00;
- cp[2] = 0xff;
- cp += 3;
- if (sidLen) {
- PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen);
- cp += sidLen;
- }
- PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
-
- /* Send it to the server */
- DUMP_MSG(29, (ss, msg, sendLen));
- ss->handshakeBegun = 1;
- rv = (*ss->sec.send)(ss, msg, sendLen, 0);
-
- ssl_ReleaseXmitBufLock(ss); /***************************************/
-
- if (rv < 0) {
- goto loser;
- }
-
- rv = ssl3_StartHandshakeHash(ss, msg, sendLen);
- if (rv < 0) {
- goto loser;
- }
-
- /*
- * Since we sent the SCSV, pretend we sent empty RI extension. We need
- * to record the extension has been advertised after ssl3_InitState has
- * been called, which ssl3_StartHandshakeHash took care for us above.
- */
- xtnData = &ss->xtnData;
- xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn;
-
- /* Setup to receive servers hello message */
- ssl_GetRecvBufLock(ss);
- ss->gs.recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleServerHelloMessage;
- return SECSuccess;
-
-unlock_loser:
- ssl_ReleaseXmitBufLock(ss);
-loser:
- return SECFailure;
-}
-
-/************************************************************************/
-
-/* Handle the CLIENT-MASTER-KEY message.
-** Acquires and releases RecvBufLock.
-** Called from ssl2_HandleClientHelloMessage().
-*/
-static SECStatus
-ssl2_HandleClientSessionKeyMessage(sslSocket *ss)
-{
- PRUint8 * data;
- unsigned int caLen;
- unsigned int ckLen;
- unsigned int ekLen;
- unsigned int keyBits;
- int cipher;
- SECStatus rv;
-
-
- ssl_GetRecvBufLock(ss);
-
- data = ss->gs.buf.buf + ss->gs.recordOffset;
- DUMP_MSG(29, (ss, data, ss->gs.recordLen));
-
- if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES)
- || (data[0] != SSL_MT_CLIENT_MASTER_KEY)) {
- goto bad_client;
- }
- cipher = data[1];
- keyBits = (data[2] << 8) | data[3];
- ckLen = (data[4] << 8) | data[5];
- ekLen = (data[6] << 8) | data[7];
- caLen = (data[8] << 8) | data[9];
-
- SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d",
- SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen));
-
- if (ss->gs.recordLen <
- SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) {
- SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d",
- SSL_GETPID(), ss->fd, ss->gs.recordLen));
- goto bad_client;
- }
-
- /* Use info from client to setup session key */
- rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits,
- data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ckLen,
- data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ekLen,
- data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen);
- ss->gs.recordLen = 0; /* we're done with this record. */
-
- ssl_ReleaseRecvBufLock(ss);
-
- if (rv != SECSuccess) {
- goto loser;
- }
- ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY;
- ssl2_UseEncryptedSendFunc(ss);
-
- /* Send server verify message now that keys are established */
- rv = ssl2_SendServerVerifyMessage(ss);
- if (rv != SECSuccess)
- goto loser;
-
- rv = ssl2_TryToFinish(ss);
- if (rv != SECSuccess)
- goto loser;
- if (ss->handshake == 0) {
- return SECSuccess;
- }
-
- SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d",
- SSL_GETPID(), ss->fd,
- ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleMessage;
-
- return ssl2_TriggerNextMessage(ss);
-
-bad_client:
- ssl_ReleaseRecvBufLock(ss);
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- /* FALLTHROUGH */
-
-loser:
- return SECFailure;
-}
-
-/*
-** Handle the initial hello message from the client
-**
-** not static because ssl2_GatherData() tests ss->nextHandshake for this value.
-*/
-SECStatus
-ssl2_HandleClientHelloMessage(sslSocket *ss)
-{
- sslSessionID *sid;
- sslServerCerts * sc;
- CERTCertificate *serverCert;
- PRUint8 *msg;
- PRUint8 *data;
- PRUint8 *cs;
- PRUint8 *sd;
- PRUint8 *cert = NULL;
- PRUint8 *challenge;
- unsigned int challengeLen;
- SECStatus rv;
- int csLen;
- int sendLen;
- int sdLen;
- int certLen;
- int pid;
- int sent;
- int gotXmitBufLock = 0;
-#if defined(SOLARIS) && defined(i386)
- volatile PRUint8 hit;
-#else
- int hit;
-#endif
- PRUint8 csImpl[sizeof implementedCipherSuites];
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- sc = ss->serverCerts + kt_rsa;
- serverCert = sc->serverCert;
-
- ssl_GetRecvBufLock(ss);
-
-
- data = ss->gs.buf.buf + ss->gs.recordOffset;
- DUMP_MSG(29, (ss, data, ss->gs.recordLen));
-
- /* Make sure first message has some data and is the client hello message */
- if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES)
- || (data[0] != SSL_MT_CLIENT_HELLO)) {
- goto bad_client;
- }
-
- /* Get peer name of client */
- rv = ssl_GetPeerInfo(ss);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- /* Examine version information */
- /*
- * See if this might be a V2 client hello asking to use the V3 protocol
- */
- if ((data[0] == SSL_MT_CLIENT_HELLO) &&
- (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) &&
- !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
- rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen);
- if (rv != SECFailure) { /* Success */
- ss->handshake = NULL;
- ss->nextHandshake = ssl_GatherRecord1stHandshake;
- ss->securityHandshake = NULL;
- ss->gs.state = GS_INIT;
-
- /* ssl3_HandleV3ClientHello has set ss->version,
- ** and has gotten us a brand new sid.
- */
- ss->sec.ci.sid->version = ss->version;
- }
- ssl_ReleaseRecvBufLock(ss);
- return rv;
- }
- /* Previously, there was a test here to see if SSL2 was enabled.
- ** If not, an error code was set, and SECFailure was returned,
- ** without sending any error code to the other end of the connection.
- ** That test has been removed. If SSL2 has been disabled, there
- ** should be no SSL2 ciphers enabled, and consequently, the code
- ** below should send the ssl2 error message SSL_PE_NO_CYPHERS.
- ** We now believe this is the correct thing to do, even when SSL2
- ** has been explicitly disabled by the application.
- */
-
- /* Extract info from message */
- ss->version = (data[1] << 8) | data[2];
-
- /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it. */
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- ss->version = SSL_LIBRARY_VERSION_2;
- }
-
- csLen = (data[3] << 8) | data[4];
- sdLen = (data[5] << 8) | data[6];
- challengeLen = (data[7] << 8) | data[8];
- cs = data + SSL_HL_CLIENT_HELLO_HBYTES;
- sd = cs + csLen;
- challenge = sd + sdLen;
- PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen));
-
- if (!csLen || (csLen % 3) != 0 ||
- (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) ||
- challengeLen < SSL_MIN_CHALLENGE_BYTES ||
- challengeLen > SSL_MAX_CHALLENGE_BYTES ||
- (unsigned)ss->gs.recordLen !=
- SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) {
- SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d",
- SSL_GETPID(), ss->fd, ss->gs.recordLen,
- SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen));
- goto bad_client;
- }
-
- SSL_TRC(3, ("%d: SSL[%d]: client version is %x",
- SSL_GETPID(), ss->fd, ss->version));
- if (ss->version != SSL_LIBRARY_VERSION_2) {
- if (ss->version > SSL_LIBRARY_VERSION_2) {
- /*
- ** Newer client than us. Things are ok because new clients
- ** are required to be backwards compatible with old servers.
- ** Change version number to our version number so that client
- ** knows whats up.
- */
- ss->version = SSL_LIBRARY_VERSION_2;
- } else {
- SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)",
- SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
- PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
- goto loser;
- }
- }
-
- /* Qualify cipher specs before returning them to client */
- csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
- if (csLen == 0) {
- /* no overlap, send client our list of supported SSL v2 ciphers. */
- cs = csImpl;
- csLen = sizeof implementedCipherSuites;
- PORT_Memcpy(cs, implementedCipherSuites, csLen);
- csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
- if (csLen == 0) {
- /* We don't support any SSL v2 ciphers! */
- ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- goto loser;
- }
- /* Since this handhsake is going to fail, don't cache it. */
- ss->opt.noCache = 1;
- }
-
- /* Squirrel away the challenge for later */
- PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen);
-
- /* Examine message and see if session-id is good */
- ss->sec.ci.elements = 0;
- if (sdLen > 0 && !ss->opt.noCache) {
- SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
- SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
- ss->sec.ci.peer.pr_s6_addr32[1],
- ss->sec.ci.peer.pr_s6_addr32[2],
- ss->sec.ci.peer.pr_s6_addr32[3]));
- sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle);
- } else {
- sid = NULL;
- }
- if (sid) {
- /* Got a good session-id. Short cut! */
- SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)",
- SSL_GETPID(), ss->fd, ss->sec.ci.peer,
- ssl_Time() - sid->creationTime));
- PRINT_BUF(1, (ss, "session-id value:", sd, sdLen));
- ss->sec.ci.sid = sid;
- ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
- hit = 1;
- certLen = 0;
- csLen = 0;
-
- ss->sec.authAlgorithm = sid->authAlgorithm;
- ss->sec.authKeyBits = sid->authKeyBits;
- ss->sec.keaType = sid->keaType;
- ss->sec.keaKeyBits = sid->keaKeyBits;
-
- rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
- if (rv != SECSuccess) {
- goto loser;
- }
- } else {
- SECItem * derCert = &serverCert->derCert;
-
- SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed",
- SSL_GETPID(), ss->fd));
- if (!serverCert) {
- SET_ERROR_CODE
- goto loser;
- }
- hit = 0;
- sid = PORT_ZNew(sslSessionID);
- if (!sid) {
- goto loser;
- }
- sid->references = 1;
- sid->addr = ss->sec.ci.peer;
- sid->port = ss->sec.ci.port;
-
- /* Invent a session-id */
- ss->sec.ci.sid = sid;
- PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2);
-
- pid = SSL_GETPID();
- sid->u.ssl2.sessionID[0] = MSB(pid);
- sid->u.ssl2.sessionID[1] = LSB(pid);
- cert = derCert->data;
- certLen = derCert->len;
-
- /* pretend that server sids remember the local cert. */
- PORT_Assert(!sid->localCert);
- if (sid->localCert) {
- CERT_DestroyCertificate(sid->localCert);
- }
- sid->localCert = CERT_DupCertificate(serverCert);
-
- ss->sec.authAlgorithm = ssl_sign_rsa;
- ss->sec.keaType = ssl_kea_rsa;
- ss->sec.keaKeyBits = \
- ss->sec.authKeyBits = ss->serverCerts[kt_rsa].serverKeyBits;
- }
-
- /* server sids don't remember the local cert, so whether we found
- ** a sid or not, just "remember" we used the rsa server cert.
- */
- if (ss->sec.localCert) {
- CERT_DestroyCertificate(ss->sec.localCert);
- }
- ss->sec.localCert = CERT_DupCertificate(serverCert);
-
- /* Build up final list of required elements */
- ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED;
- if (ss->opt.requestCertificate) {
- ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE;
- }
- ss->sec.ci.sentElements = 0;
-
- /* Send hello message back to client */
- sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen
- + SSL_CONNECTIONID_BYTES;
-
- ssl_GetXmitBufLock(ss); gotXmitBufLock = 1;
- rv = ssl2_GetSendBuffer(ss, sendLen);
- if (rv != SECSuccess) {
- goto loser;
- }
-
- SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)",
- SSL_GETPID(), ss->fd, sendLen));
-
- msg = ss->sec.ci.sendBuf.buf;
- msg[0] = SSL_MT_SERVER_HELLO;
- msg[1] = hit;
- msg[2] = SSL_CT_X509_CERTIFICATE;
- msg[3] = MSB(ss->version);
- msg[4] = LSB(ss->version);
- msg[5] = MSB(certLen);
- msg[6] = LSB(certLen);
- msg[7] = MSB(csLen);
- msg[8] = LSB(csLen);
- msg[9] = MSB(SSL_CONNECTIONID_BYTES);
- msg[10] = LSB(SSL_CONNECTIONID_BYTES);
- if (certLen) {
- PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen);
- }
- if (csLen) {
- PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen);
- }
- PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen,
- ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES);
-
- DUMP_MSG(29, (ss, msg, sendLen));
-
- ss->handshakeBegun = 1;
- sent = (*ss->sec.send)(ss, msg, sendLen, 0);
- if (sent < 0) {
- goto loser;
- }
- ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
-
- ss->gs.recordLen = 0;
- ss->handshake = ssl_GatherRecord1stHandshake;
- if (hit) {
- /* Old SID Session key is good. Go encrypted */
- ssl2_UseEncryptedSendFunc(ss);
-
- /* Send server verify message now that keys are established */
- rv = ssl2_SendServerVerifyMessage(ss);
- if (rv != SECSuccess)
- goto loser;
-
- ss->nextHandshake = ssl2_HandleMessage;
- ssl_ReleaseRecvBufLock(ss);
- rv = ssl2_TriggerNextMessage(ss);
- return rv;
- }
- ss->nextHandshake = ssl2_HandleClientSessionKeyMessage;
- ssl_ReleaseRecvBufLock(ss);
- return SECSuccess;
-
- bad_client:
- PORT_SetError(SSL_ERROR_BAD_CLIENT);
- /* FALLTHROUGH */
-
- loser:
- if (gotXmitBufLock) {
- ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
- }
- SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage",
- SSL_GETPID(), ss->fd));
- ssl_ReleaseRecvBufLock(ss);
- return SECFailure;
-}
-
-SECStatus
-ssl2_BeginServerHandshake(sslSocket *ss)
-{
- SECStatus rv;
- sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa;
-
- ss->sec.isServer = 1;
- ssl_ChooseSessionIDProcs(&ss->sec);
- ss->sec.sendSequence = 0;
- ss->sec.rcvSequence = 0;
-
- /* don't turn on SSL2 if we don't have an RSA key and cert */
- if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY ||
- !rsaAuth->serverCert) {
- ss->opt.enableSSL2 = PR_FALSE;
- }
-
- if (!ss->cipherSpecs) {
- rv = ssl2_ConstructCipherSpecs(ss);
- if (rv != SECSuccess)
- goto loser;
- }
-
- /* count the SSL2 and SSL3 enabled ciphers.
- * if either is zero, clear the socket's enable for that protocol.
- */
- rv = ssl2_CheckConfigSanity(ss);
- if (rv != SECSuccess)
- goto loser;
-
- /*
- ** Generate connection-id. Always do this, even if things fail
- ** immediately. This way the random number generator is always
- ** rolling around, every time we get a connection.
- */
- PK11_GenerateRandom(ss->sec.ci.connectionID,
- sizeof(ss->sec.ci.connectionID));
-
- ss->gs.recordLen = 0;
- ss->handshake = ssl_GatherRecord1stHandshake;
- ss->nextHandshake = ssl2_HandleClientHelloMessage;
- return SECSuccess;
-
-loser:
- return SECFailure;
-}
-
-/* This function doesn't really belong in this file.
-** It's here to keep AIX compilers from optimizing it away,
-** and not including it in the DSO.
-*/
-
-#include "nss.h"
-extern const char __nss_ssl_rcsid[];
-extern const char __nss_ssl_sccsid[];
-
-PRBool
-NSSSSL_VersionCheck(const char *importedVersion)
-{
- /*
- * This is the secret handshake algorithm.
- *
- * This release has a simple version compatibility
- * check algorithm. This release is not backward
- * compatible with previous major releases. It is
- * not compatible with future major, minor, or
- * patch releases.
- */
- volatile char c; /* force a reference that won't get optimized away */
-
- c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0];
- return NSS_VersionCheck(importedVersion);
-}
-
-const char *
-NSSSSL_GetVersion(void)
-{
- return NSS_VERSION;
-}
diff --git a/security/nss/lib/ssl/ssldef.c b/security/nss/lib/ssl/ssldef.c
deleted file mode 100644
index e4aafe3b5..000000000
--- a/security/nss/lib/ssl/ssldef.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-
-#if defined(WIN32)
-#define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); }
-#define DEFINE_ERROR PRErrorCode err = PR_GetError();
-#else
-#define MAP_ERROR(from,to)
-#define DEFINE_ERROR
-#endif
-
-int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->connect(lower, sa, ss->cTimeout);
- return rv;
-}
-
-int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->bind(lower, addr);
- return rv;
-}
-
-int ssl_DefListen(sslSocket *ss, int backlog)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->listen(lower, backlog);
- return rv;
-}
-
-int ssl_DefShutdown(sslSocket *ss, int how)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->shutdown(lower, how);
- return rv;
-}
-
-int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout);
- if (rv < 0) {
- DEFINE_ERROR
- MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
- } else if (rv > len) {
- PORT_Assert(rv <= len);
- PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
- rv = SECFailure;
- }
- return rv;
-}
-
-/* Default (unencrypted) send.
- * For blocking sockets, always returns len or SECFailure, no short writes.
- * For non-blocking sockets:
- * Returns positive count if any data was written, else returns SECFailure.
- * Short writes may occur. Does not return SECWouldBlock.
- */
-int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
-{
- PRFileDesc *lower = ss->fd->lower;
- int sent = 0;
-
-#if NSS_DISABLE_NAGLE_DELAYS
- /* Although this is overkill, we disable Nagle delays completely for
- ** SSL sockets.
- */
- if (ss->opt.useSecurity && !ss->delayDisabled) {
- ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */
- ss->delayDisabled = 1;
- }
-#endif
- do {
- int rv = lower->methods->send(lower, (const void *)(buf + sent),
- len - sent, flags, ss->wTimeout);
- if (rv < 0) {
- PRErrorCode err = PR_GetError();
- if (err == PR_WOULD_BLOCK_ERROR) {
- ss->lastWriteBlocked = 1;
- return sent ? sent : SECFailure;
- }
- ss->lastWriteBlocked = 0;
- MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
- /* Loser */
- return rv;
- }
- sent += rv;
-
- if (IS_DTLS(ss) && (len > sent)) {
- /* We got a partial write so just return it */
- return sent;
- }
- } while (len > sent);
- ss->lastWriteBlocked = 0;
- return sent;
-}
-
-int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->read(lower, (void *)buf, len);
- if (rv < 0) {
- DEFINE_ERROR
- MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
- }
- return rv;
-}
-
-int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len)
-{
- PRFileDesc *lower = ss->fd->lower;
- int sent = 0;
-
- do {
- int rv = lower->methods->write(lower, (const void *)(buf + sent),
- len - sent);
- if (rv < 0) {
- PRErrorCode err = PR_GetError();
- if (err == PR_WOULD_BLOCK_ERROR) {
- ss->lastWriteBlocked = 1;
- return sent ? sent : SECFailure;
- }
- ss->lastWriteBlocked = 0;
- MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
- /* Loser */
- return rv;
- }
- sent += rv;
- } while (len > sent);
- ss->lastWriteBlocked = 0;
- return sent;
-}
-
-int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->getpeername(lower, name);
- return rv;
-}
-
-int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
-{
- PRFileDesc *lower = ss->fd->lower;
- int rv;
-
- rv = lower->methods->getsockname(lower, name);
- return rv;
-}
-
-int ssl_DefClose(sslSocket *ss)
-{
- PRFileDesc *fd;
- PRFileDesc *popped;
- int rv;
-
- fd = ss->fd;
-
- /* First, remove the SSL layer PRFileDesc from the socket's stack,
- ** then invoke the SSL layer's PRFileDesc destructor.
- ** This must happen before the next layer down is closed.
- */
- PORT_Assert(fd->higher == NULL);
- if (fd->higher) {
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- return SECFailure;
- }
- ss->fd = NULL;
-
- /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on
- ** the stack, and then remove the second one. This way, the address
- ** of the PRFileDesc on the top of the stack doesn't change.
- */
- popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
- popped->dtor(popped);
-
- /* fd is now the PRFileDesc for the next layer down.
- ** Now close the underlying socket.
- */
- rv = fd->methods->close(fd);
-
- ssl_FreeSocket(ss);
-
- SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d",
- SSL_GETPID(), fd, rv, PORT_GetError()));
- return rv;
-}
diff --git a/security/nss/lib/ssl/sslenum.c b/security/nss/lib/ssl/sslenum.c
deleted file mode 100644
index ee431ab60..000000000
--- a/security/nss/lib/ssl/sslenum.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Table enumerating all implemented cipher suites
- * Part of public API.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "ssl.h"
-#include "sslproto.h"
-
-/*
- * The ciphers are listed in the following order:
- * - stronger ciphers before weaker ciphers
- * - national ciphers before international ciphers
- * - faster ciphers before slower ciphers
- *
- * National ciphers such as Camellia are listed before international ciphers
- * such as AES and RC4 to allow servers that prefer Camellia to negotiate
- * Camellia without having to disable AES and RC4, which are needed for
- * interoperability with clients that don't yet implement Camellia.
- *
- * The ordering of cipher suites in this table must match the ordering in
- * the cipherSuites table in ssl3con.c.
- *
- * If new ECC cipher suites are added, also update the ssl3CipherSuite arrays
- * in ssl3ecc.c.
- */
-const PRUint16 SSL_ImplementedCiphers[] = {
- /* 256-bit */
-#ifdef NSS_ENABLE_ECC
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
- TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
- TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
-#ifdef NSS_ENABLE_ECC
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
- TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
- TLS_RSA_WITH_AES_256_CBC_SHA,
-
- /* 128-bit */
-#ifdef NSS_ENABLE_ECC
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
- TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
- TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
- TLS_DHE_DSS_WITH_RC4_128_SHA,
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
-#ifdef NSS_ENABLE_ECC
- TLS_ECDH_RSA_WITH_RC4_128_SHA,
- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
- TLS_RSA_WITH_SEED_CBC_SHA,
- TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
- SSL_RSA_WITH_RC4_128_SHA,
- SSL_RSA_WITH_RC4_128_MD5,
- TLS_RSA_WITH_AES_128_CBC_SHA,
-
- /* 112-bit 3DES */
-#ifdef NSS_ENABLE_ECC
- TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
- SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
-#ifdef NSS_ENABLE_ECC
- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
-#endif /* NSS_ENABLE_ECC */
- SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
- SSL_RSA_WITH_3DES_EDE_CBC_SHA,
-
- /* 56-bit DES "domestic" cipher suites */
- SSL_DHE_RSA_WITH_DES_CBC_SHA,
- SSL_DHE_DSS_WITH_DES_CBC_SHA,
- SSL_RSA_FIPS_WITH_DES_CBC_SHA,
- SSL_RSA_WITH_DES_CBC_SHA,
-
- /* export ciphersuites with 1024-bit public key exchange keys */
- TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
- TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
-
- /* export ciphersuites with 512-bit public key exchange keys */
- SSL_RSA_EXPORT_WITH_RC4_40_MD5,
- SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
-
- /* ciphersuites with no encryption */
-#ifdef NSS_ENABLE_ECC
- TLS_ECDHE_ECDSA_WITH_NULL_SHA,
- TLS_ECDHE_RSA_WITH_NULL_SHA,
- TLS_ECDH_RSA_WITH_NULL_SHA,
- TLS_ECDH_ECDSA_WITH_NULL_SHA,
-#endif /* NSS_ENABLE_ECC */
- SSL_RSA_WITH_NULL_SHA,
- SSL_RSA_WITH_NULL_MD5,
-
- /* SSL2 cipher suites. */
- SSL_EN_RC4_128_WITH_MD5,
- SSL_EN_RC2_128_CBC_WITH_MD5,
- SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* actually 112, not 192 */
- SSL_EN_DES_64_CBC_WITH_MD5,
- SSL_EN_RC4_128_EXPORT40_WITH_MD5,
- SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,
-
- 0
-
-};
-
-const PRUint16 SSL_NumImplementedCiphers =
- (sizeof SSL_ImplementedCiphers) / (sizeof SSL_ImplementedCiphers[0]) - 1;
-
-const PRUint16 *
-SSL_GetImplementedCiphers(void)
-{
- return SSL_ImplementedCiphers;
-}
-
-PRUint16
-SSL_GetNumImplementedCiphers(void)
-{
- return SSL_NumImplementedCiphers;
-}
diff --git a/security/nss/lib/ssl/sslerr.c b/security/nss/lib/ssl/sslerr.c
deleted file mode 100644
index 0afdb184c..000000000
--- a/security/nss/lib/ssl/sslerr.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Function to set error code only when meaningful error has not already
- * been set.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "prerror.h"
-#include "secerr.h"
-#include "sslerr.h"
-#include "seccomon.h"
-
-/* look at the current value of PR_GetError, and evaluate it to see
- * if it is meaningful or meaningless (out of context).
- * If it is meaningless, replace it with the hiLevelError.
- * Returns the chosen error value.
- */
-int
-ssl_MapLowLevelError(int hiLevelError)
-{
- int oldErr = PORT_GetError();
-
- switch (oldErr) {
-
- case 0:
- case PR_IO_ERROR:
- case SEC_ERROR_IO:
- case SEC_ERROR_BAD_DATA:
- case SEC_ERROR_LIBRARY_FAILURE:
- case SEC_ERROR_EXTENSION_NOT_FOUND:
- case SSL_ERROR_BAD_CLIENT:
- case SSL_ERROR_BAD_SERVER:
- case SSL_ERROR_SESSION_NOT_FOUND:
- PORT_SetError(hiLevelError);
- return hiLevelError;
-
- default: /* leave the majority of error codes alone. */
- return oldErr;
- }
-}
diff --git a/security/nss/lib/ssl/sslerr.h b/security/nss/lib/ssl/sslerr.h
deleted file mode 100644
index 6b07af426..000000000
--- a/security/nss/lib/ssl/sslerr.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Enumeration of all SSL-specific error codes.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#ifndef __SSL_ERR_H_
-#define __SSL_ERR_H_
-
-
-#define SSL_ERROR_BASE (-0x3000)
-#define SSL_ERROR_LIMIT (SSL_ERROR_BASE + 1000)
-
-#define IS_SSL_ERROR(code) \
- (((code) >= SSL_ERROR_BASE) && ((code) < SSL_ERROR_LIMIT))
-
-#ifndef NO_SECURITY_ERROR_ENUM
-typedef enum {
-SSL_ERROR_EXPORT_ONLY_SERVER = (SSL_ERROR_BASE + 0),
-SSL_ERROR_US_ONLY_SERVER = (SSL_ERROR_BASE + 1),
-SSL_ERROR_NO_CYPHER_OVERLAP = (SSL_ERROR_BASE + 2),
-/*
- * Received an alert reporting what we did wrong. (more alerts below)
- */
-SSL_ERROR_NO_CERTIFICATE /*_ALERT */ = (SSL_ERROR_BASE + 3),
-SSL_ERROR_BAD_CERTIFICATE = (SSL_ERROR_BASE + 4),
-SSL_ERROR_UNUSED_5 = (SSL_ERROR_BASE + 5),
- /* error 5 is obsolete */
-SSL_ERROR_BAD_CLIENT = (SSL_ERROR_BASE + 6),
-SSL_ERROR_BAD_SERVER = (SSL_ERROR_BASE + 7),
-SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE = (SSL_ERROR_BASE + 8),
-SSL_ERROR_UNSUPPORTED_VERSION = (SSL_ERROR_BASE + 9),
-SSL_ERROR_UNUSED_10 = (SSL_ERROR_BASE + 10),
- /* error 10 is obsolete */
-SSL_ERROR_WRONG_CERTIFICATE = (SSL_ERROR_BASE + 11),
-SSL_ERROR_BAD_CERT_DOMAIN = (SSL_ERROR_BASE + 12),
-SSL_ERROR_POST_WARNING = (SSL_ERROR_BASE + 13),
-SSL_ERROR_SSL2_DISABLED = (SSL_ERROR_BASE + 14),
-SSL_ERROR_BAD_MAC_READ = (SSL_ERROR_BASE + 15),
-/*
- * Received an alert reporting what we did wrong.
- * (two more alerts above, and many more below)
- */
-SSL_ERROR_BAD_MAC_ALERT = (SSL_ERROR_BASE + 16),
-SSL_ERROR_BAD_CERT_ALERT = (SSL_ERROR_BASE + 17),
-SSL_ERROR_REVOKED_CERT_ALERT = (SSL_ERROR_BASE + 18),
-SSL_ERROR_EXPIRED_CERT_ALERT = (SSL_ERROR_BASE + 19),
-
-SSL_ERROR_SSL_DISABLED = (SSL_ERROR_BASE + 20),
-SSL_ERROR_FORTEZZA_PQG = (SSL_ERROR_BASE + 21),
-SSL_ERROR_UNKNOWN_CIPHER_SUITE = (SSL_ERROR_BASE + 22),
-SSL_ERROR_NO_CIPHERS_SUPPORTED = (SSL_ERROR_BASE + 23),
-SSL_ERROR_BAD_BLOCK_PADDING = (SSL_ERROR_BASE + 24),
-SSL_ERROR_RX_RECORD_TOO_LONG = (SSL_ERROR_BASE + 25),
-SSL_ERROR_TX_RECORD_TOO_LONG = (SSL_ERROR_BASE + 26),
-/*
- * Received a malformed (too long or short) SSL handshake.
- */
-SSL_ERROR_RX_MALFORMED_HELLO_REQUEST = (SSL_ERROR_BASE + 27),
-SSL_ERROR_RX_MALFORMED_CLIENT_HELLO = (SSL_ERROR_BASE + 28),
-SSL_ERROR_RX_MALFORMED_SERVER_HELLO = (SSL_ERROR_BASE + 29),
-SSL_ERROR_RX_MALFORMED_CERTIFICATE = (SSL_ERROR_BASE + 30),
-SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH = (SSL_ERROR_BASE + 31),
-SSL_ERROR_RX_MALFORMED_CERT_REQUEST = (SSL_ERROR_BASE + 32),
-SSL_ERROR_RX_MALFORMED_HELLO_DONE = (SSL_ERROR_BASE + 33),
-SSL_ERROR_RX_MALFORMED_CERT_VERIFY = (SSL_ERROR_BASE + 34),
-SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH = (SSL_ERROR_BASE + 35),
-SSL_ERROR_RX_MALFORMED_FINISHED = (SSL_ERROR_BASE + 36),
-/*
- * Received a malformed (too long or short) SSL record.
- */
-SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER = (SSL_ERROR_BASE + 37),
-SSL_ERROR_RX_MALFORMED_ALERT = (SSL_ERROR_BASE + 38),
-SSL_ERROR_RX_MALFORMED_HANDSHAKE = (SSL_ERROR_BASE + 39),
-SSL_ERROR_RX_MALFORMED_APPLICATION_DATA = (SSL_ERROR_BASE + 40),
-/*
- * Received an SSL handshake that was inappropriate for the state we're in.
- * E.g. Server received message from server, or wrong state in state machine.
- */
-SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST = (SSL_ERROR_BASE + 41),
-SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO = (SSL_ERROR_BASE + 42),
-SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO = (SSL_ERROR_BASE + 43),
-SSL_ERROR_RX_UNEXPECTED_CERTIFICATE = (SSL_ERROR_BASE + 44),
-SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH = (SSL_ERROR_BASE + 45),
-SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST = (SSL_ERROR_BASE + 46),
-SSL_ERROR_RX_UNEXPECTED_HELLO_DONE = (SSL_ERROR_BASE + 47),
-SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY = (SSL_ERROR_BASE + 48),
-SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH = (SSL_ERROR_BASE + 49),
-SSL_ERROR_RX_UNEXPECTED_FINISHED = (SSL_ERROR_BASE + 50),
-/*
- * Received an SSL record that was inappropriate for the state we're in.
- */
-SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER = (SSL_ERROR_BASE + 51),
-SSL_ERROR_RX_UNEXPECTED_ALERT = (SSL_ERROR_BASE + 52),
-SSL_ERROR_RX_UNEXPECTED_HANDSHAKE = (SSL_ERROR_BASE + 53),
-SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA= (SSL_ERROR_BASE + 54),
-/*
- * Received record/message with unknown discriminant.
- */
-SSL_ERROR_RX_UNKNOWN_RECORD_TYPE = (SSL_ERROR_BASE + 55),
-SSL_ERROR_RX_UNKNOWN_HANDSHAKE = (SSL_ERROR_BASE + 56),
-SSL_ERROR_RX_UNKNOWN_ALERT = (SSL_ERROR_BASE + 57),
-/*
- * Received an alert reporting what we did wrong. (more alerts above)
- */
-SSL_ERROR_CLOSE_NOTIFY_ALERT = (SSL_ERROR_BASE + 58),
-SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT = (SSL_ERROR_BASE + 59),
-SSL_ERROR_DECOMPRESSION_FAILURE_ALERT = (SSL_ERROR_BASE + 60),
-SSL_ERROR_HANDSHAKE_FAILURE_ALERT = (SSL_ERROR_BASE + 61),
-SSL_ERROR_ILLEGAL_PARAMETER_ALERT = (SSL_ERROR_BASE + 62),
-SSL_ERROR_UNSUPPORTED_CERT_ALERT = (SSL_ERROR_BASE + 63),
-SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT = (SSL_ERROR_BASE + 64),
-
-SSL_ERROR_GENERATE_RANDOM_FAILURE = (SSL_ERROR_BASE + 65),
-SSL_ERROR_SIGN_HASHES_FAILURE = (SSL_ERROR_BASE + 66),
-SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE = (SSL_ERROR_BASE + 67),
-SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 68),
-SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 69),
-
-SSL_ERROR_ENCRYPTION_FAILURE = (SSL_ERROR_BASE + 70),
-SSL_ERROR_DECRYPTION_FAILURE = (SSL_ERROR_BASE + 71), /* don't use */
-SSL_ERROR_SOCKET_WRITE_FAILURE = (SSL_ERROR_BASE + 72),
-
-SSL_ERROR_MD5_DIGEST_FAILURE = (SSL_ERROR_BASE + 73),
-SSL_ERROR_SHA_DIGEST_FAILURE = (SSL_ERROR_BASE + 74),
-SSL_ERROR_MAC_COMPUTATION_FAILURE = (SSL_ERROR_BASE + 75),
-SSL_ERROR_SYM_KEY_CONTEXT_FAILURE = (SSL_ERROR_BASE + 76),
-SSL_ERROR_SYM_KEY_UNWRAP_FAILURE = (SSL_ERROR_BASE + 77),
-SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED = (SSL_ERROR_BASE + 78),
-SSL_ERROR_IV_PARAM_FAILURE = (SSL_ERROR_BASE + 79),
-SSL_ERROR_INIT_CIPHER_SUITE_FAILURE = (SSL_ERROR_BASE + 80),
-SSL_ERROR_SESSION_KEY_GEN_FAILURE = (SSL_ERROR_BASE + 81),
-SSL_ERROR_NO_SERVER_KEY_FOR_ALG = (SSL_ERROR_BASE + 82),
-SSL_ERROR_TOKEN_INSERTION_REMOVAL = (SSL_ERROR_BASE + 83),
-SSL_ERROR_TOKEN_SLOT_NOT_FOUND = (SSL_ERROR_BASE + 84),
-SSL_ERROR_NO_COMPRESSION_OVERLAP = (SSL_ERROR_BASE + 85),
-SSL_ERROR_HANDSHAKE_NOT_COMPLETED = (SSL_ERROR_BASE + 86),
-SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE = (SSL_ERROR_BASE + 87),
-SSL_ERROR_CERT_KEA_MISMATCH = (SSL_ERROR_BASE + 88),
-/* SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA became obsolete in NSS 3.14. */
-SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA = (SSL_ERROR_BASE + 89),
-SSL_ERROR_SESSION_NOT_FOUND = (SSL_ERROR_BASE + 90),
-
-SSL_ERROR_DECRYPTION_FAILED_ALERT = (SSL_ERROR_BASE + 91),
-SSL_ERROR_RECORD_OVERFLOW_ALERT = (SSL_ERROR_BASE + 92),
-SSL_ERROR_UNKNOWN_CA_ALERT = (SSL_ERROR_BASE + 93),
-SSL_ERROR_ACCESS_DENIED_ALERT = (SSL_ERROR_BASE + 94),
-SSL_ERROR_DECODE_ERROR_ALERT = (SSL_ERROR_BASE + 95),
-SSL_ERROR_DECRYPT_ERROR_ALERT = (SSL_ERROR_BASE + 96),
-SSL_ERROR_EXPORT_RESTRICTION_ALERT = (SSL_ERROR_BASE + 97),
-SSL_ERROR_PROTOCOL_VERSION_ALERT = (SSL_ERROR_BASE + 98),
-SSL_ERROR_INSUFFICIENT_SECURITY_ALERT = (SSL_ERROR_BASE + 99),
-SSL_ERROR_INTERNAL_ERROR_ALERT = (SSL_ERROR_BASE + 100),
-SSL_ERROR_USER_CANCELED_ALERT = (SSL_ERROR_BASE + 101),
-SSL_ERROR_NO_RENEGOTIATION_ALERT = (SSL_ERROR_BASE + 102),
-
-SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED = (SSL_ERROR_BASE + 103),
-
-SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT = (SSL_ERROR_BASE + 104),
-SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT = (SSL_ERROR_BASE + 105),
-SSL_ERROR_UNRECOGNIZED_NAME_ALERT = (SSL_ERROR_BASE + 106),
-SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT = (SSL_ERROR_BASE + 107),
-SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT = (SSL_ERROR_BASE + 108),
-
-SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET = (SSL_ERROR_BASE + 109),
-SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET = (SSL_ERROR_BASE + 110),
-
-SSL_ERROR_DECOMPRESSION_FAILURE = (SSL_ERROR_BASE + 111),
-SSL_ERROR_RENEGOTIATION_NOT_ALLOWED = (SSL_ERROR_BASE + 112),
-SSL_ERROR_UNSAFE_NEGOTIATION = (SSL_ERROR_BASE + 113),
-
-SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_ERROR_BASE + 114),
-
-SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY = (SSL_ERROR_BASE + 115),
-
-SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID = (SSL_ERROR_BASE + 116),
-
-SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2 = (SSL_ERROR_BASE + 117),
-SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS = (SSL_ERROR_BASE + 118),
-SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS = (SSL_ERROR_BASE + 119),
-
-SSL_ERROR_INVALID_VERSION_RANGE = (SSL_ERROR_BASE + 120),
-SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION = (SSL_ERROR_BASE + 121),
-
-SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 122),
-SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 123),
-
-SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION = (SSL_ERROR_BASE + 124),
-
-SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 125),
-
-SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
-} SSLErrorCodes;
-#endif /* NO_SECURITY_ERROR_ENUM */
-
-#endif /* __SSL_ERR_H_ */
diff --git a/security/nss/lib/ssl/sslerrstrs.c b/security/nss/lib/ssl/sslerrstrs.c
deleted file mode 100644
index 34f4ea9b9..000000000
--- a/security/nss/lib/ssl/sslerrstrs.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "prerror.h"
-#include "sslerr.h"
-#include "prinit.h"
-#include "nssutil.h"
-#include "ssl.h"
-
-#define ER3(name, value, str) {#name, str},
-
-static const struct PRErrorMessage ssltext[] = {
-#include "SSLerrs.h"
- {0,0}
-};
-
-static const struct PRErrorTable ssl_et = {
- ssltext, "sslerr", SSL_ERROR_BASE,
- (sizeof ssltext)/(sizeof ssltext[0])
-};
-
-static PRStatus
-ssl_InitializePRErrorTableOnce(void) {
- return PR_ErrorInstallTable(&ssl_et);
-}
-
-static PRCallOnceType once;
-
-SECStatus
-ssl_InitializePRErrorTable(void)
-{
- return (PR_SUCCESS == PR_CallOnce(&once, ssl_InitializePRErrorTableOnce))
- ? SECSuccess : SECFailure;
-}
diff --git a/security/nss/lib/ssl/sslgathr.c b/security/nss/lib/ssl/sslgathr.c
deleted file mode 100644
index 4dd2dc95a..000000000
--- a/security/nss/lib/ssl/sslgathr.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Gather (Read) entire SSL2 records from socket into buffer.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-
-/* Forward static declarations */
-static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss);
-
-/*
-** Gather a single record of data from the receiving stream. This code
-** first gathers the header (2 or 3 bytes long depending on the value of
-** the most significant bit in the first byte) then gathers up the data
-** for the record into gs->buf. This code handles non-blocking I/O
-** and is to be called multiple times until ss->sec.recordLen != 0.
-** This function decrypts the gathered record in place, in gs_buf.
- *
- * Caller must hold RecvBufLock.
- *
- * Returns +1 when it has gathered a complete SSLV2 record.
- * Returns 0 if it hits EOF.
- * Returns -1 (SECFailure) on any error
- * Returns -2 (SECWouldBlock) when it gathers an SSL v3 client hello header.
-**
-** The SSL2 Gather State machine has 4 states:
-** GS_INIT - Done reading in previous record. Haven't begun to read in
-** next record. When ssl2_GatherData is called with the machine
-** in this state, the machine will attempt to read the first 3
-** bytes of the SSL2 record header, and will advance the state
-** to GS_HEADER.
-**
-** GS_HEADER - The machine is in this state while waiting for the completion
-** of the first 3 bytes of the SSL2 record. When complete, the
-** machine will compute the remaining unread length of this record
-** and will initiate a read of that many bytes. The machine will
-** advance to one of two states, depending on whether the record
-** is encrypted (GS_MAC), or unencrypted (GS_DATA).
-**
-** GS_MAC - The machine is in this state while waiting for the remainder
-** of the SSL2 record to be read in. When the read is completed,
-** the machine checks the record for valid length, decrypts it,
-** and checks and discards the MAC, then advances to GS_INIT.
-**
-** GS_DATA - The machine is in this state while waiting for the remainder
-** of the unencrypted SSL2 record to be read in. Upon completion,
-** the machine advances to the GS_INIT state and returns the data.
-*/
-int
-ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags)
-{
- unsigned char * bp;
- unsigned char * pBuf;
- int nb, err, rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
-
- if (gs->state == GS_INIT) {
- /* Initialize gathering engine */
- gs->state = GS_HEADER;
- gs->remainder = 3;
- gs->count = 3;
- gs->offset = 0;
- gs->recordLen = 0;
- gs->recordPadding = 0;
- gs->hdr[2] = 0;
-
- gs->writeOffset = 0;
- gs->readOffset = 0;
- }
- if (gs->encrypted) {
- PORT_Assert(ss->sec.hash != 0);
- }
-
- pBuf = gs->buf.buf;
- for (;;) {
- SSL_TRC(30, ("%d: SSL[%d]: gather state %d (need %d more)",
- SSL_GETPID(), ss->fd, gs->state, gs->remainder));
- bp = ((gs->state != GS_HEADER) ? pBuf : gs->hdr) + gs->offset;
- nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
- if (nb > 0) {
- PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
- }
- if (nb == 0) {
- /* EOF */
- SSL_TRC(30, ("%d: SSL[%d]: EOF", SSL_GETPID(), ss->fd));
- rv = 0;
- break;
- }
- if (nb < 0) {
- SSL_DBG(("%d: SSL[%d]: recv error %d", SSL_GETPID(), ss->fd,
- PR_GetError()));
- rv = SECFailure;
- break;
- }
-
- gs->offset += nb;
- gs->remainder -= nb;
-
- if (gs->remainder > 0) {
- continue;
- }
-
- /* Probably finished this piece */
- switch (gs->state) {
- case GS_HEADER:
- if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) && !ss->firstHsDone) {
-
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- /* If this looks like an SSL3 handshake record,
- ** and we're expecting an SSL2 Hello message from our peer,
- ** handle it here.
- */
- if (gs->hdr[0] == content_handshake) {
- if ((ss->nextHandshake == ssl2_HandleClientHelloMessage) ||
- (ss->nextHandshake == ssl2_HandleServerHelloMessage)) {
- rv = ssl2_HandleV3HandshakeRecord(ss);
- if (rv == SECFailure) {
- return SECFailure;
- }
- }
- /* XXX_1 The call stack to here is:
- * ssl_Do1stHandshake -> ssl_GatherRecord1stHandshake ->
- * ssl2_GatherRecord -> here.
- * We want to return all the way out to ssl_Do1stHandshake,
- * and have it call ssl_GatherRecord1stHandshake again.
- * ssl_GatherRecord1stHandshake will call
- * ssl3_GatherCompleteHandshake when it is called again.
- *
- * Returning SECWouldBlock here causes
- * ssl_GatherRecord1stHandshake to return without clearing
- * ss->handshake, ensuring that ssl_Do1stHandshake will
- * call it again immediately.
- *
- * If we return 1 here, ssl_GatherRecord1stHandshake will
- * clear ss->handshake before returning, and thus will not
- * be called again by ssl_Do1stHandshake.
- */
- return SECWouldBlock;
- } else if (gs->hdr[0] == content_alert) {
- if (ss->nextHandshake == ssl2_HandleServerHelloMessage) {
- /* XXX This is a hack. We're assuming that any failure
- * XXX on the client hello is a failure to match
- * XXX ciphers.
- */
- PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
- return SECFailure;
- }
- }
- }
-
- /* we've got the first 3 bytes. The header may be two or three. */
- if (gs->hdr[0] & 0x80) {
- /* This record has a 2-byte header, and no padding */
- gs->count = ((gs->hdr[0] & 0x7f) << 8) | gs->hdr[1];
- gs->recordPadding = 0;
- } else {
- /* This record has a 3-byte header that is all read in now. */
- gs->count = ((gs->hdr[0] & 0x3f) << 8) | gs->hdr[1];
- /* is_escape = (gs->hdr[0] & 0x40) != 0; */
- gs->recordPadding = gs->hdr[2];
- }
- if (!gs->count) {
- PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
- goto cleanup;
- }
-
- if (gs->count > gs->buf.space) {
- err = sslBuffer_Grow(&gs->buf, gs->count);
- if (err) {
- return err;
- }
- pBuf = gs->buf.buf;
- }
-
-
- if (gs->hdr[0] & 0x80) {
- /* we've already read in the first byte of the body.
- ** Put it into the buffer.
- */
- pBuf[0] = gs->hdr[2];
- gs->offset = 1;
- gs->remainder = gs->count - 1;
- } else {
- gs->offset = 0;
- gs->remainder = gs->count;
- }
-
- if (gs->encrypted) {
- gs->state = GS_MAC;
- gs->recordLen = gs->count - gs->recordPadding
- - ss->sec.hash->length;
- } else {
- gs->state = GS_DATA;
- gs->recordLen = gs->count;
- }
-
- break;
-
-
- case GS_MAC:
- /* Have read in entire rest of the ciphertext.
- ** Check for valid length.
- ** Decrypt it.
- ** Check the MAC.
- */
- PORT_Assert(gs->encrypted);
-
- {
- unsigned int macLen;
- int nout;
- unsigned char mac[SSL_MAX_MAC_BYTES];
-
- ssl_GetSpecReadLock(ss); /**********************************/
-
- /* If this is a stream cipher, blockSize will be 1,
- * and this test will always be false.
- * If this is a block cipher, this will detect records
- * that are not a multiple of the blocksize in length.
- */
- if (gs->count & (ss->sec.blockSize - 1)) {
- /* This is an error. Sender is misbehaving */
- SSL_DBG(("%d: SSL[%d]: sender, count=%d blockSize=%d",
- SSL_GETPID(), ss->fd, gs->count,
- ss->sec.blockSize));
- PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
- rv = SECFailure;
- goto spec_locked_done;
- }
- PORT_Assert(gs->count == gs->offset);
-
- if (gs->offset == 0) {
- rv = 0; /* means EOF. */
- goto spec_locked_done;
- }
-
- /* Decrypt the portion of data that we just received.
- ** Decrypt it in place.
- */
- rv = (*ss->sec.dec)(ss->sec.readcx, pBuf, &nout, gs->offset,
- pBuf, gs->offset);
- if (rv != SECSuccess) {
- goto spec_locked_done;
- }
-
-
- /* Have read in all the MAC portion of record
- **
- ** Prepare MAC by resetting it and feeding it the shared secret
- */
- macLen = ss->sec.hash->length;
- if (gs->offset >= macLen) {
- PRUint32 sequenceNumber = ss->sec.rcvSequence++;
- unsigned char seq[4];
-
- seq[0] = (unsigned char) (sequenceNumber >> 24);
- seq[1] = (unsigned char) (sequenceNumber >> 16);
- seq[2] = (unsigned char) (sequenceNumber >> 8);
- seq[3] = (unsigned char) (sequenceNumber);
-
- (*ss->sec.hash->begin)(ss->sec.hashcx);
- (*ss->sec.hash->update)(ss->sec.hashcx, ss->sec.rcvSecret.data,
- ss->sec.rcvSecret.len);
- (*ss->sec.hash->update)(ss->sec.hashcx, pBuf + macLen,
- gs->offset - macLen);
- (*ss->sec.hash->update)(ss->sec.hashcx, seq, 4);
- (*ss->sec.hash->end)(ss->sec.hashcx, mac, &macLen, macLen);
-
- PORT_Assert(macLen == ss->sec.hash->length);
-
- ssl_ReleaseSpecReadLock(ss); /******************************/
-
- if (NSS_SecureMemcmp(mac, pBuf, macLen) != 0) {
- /* MAC's didn't match... */
- SSL_DBG(("%d: SSL[%d]: mac check failed, seq=%d",
- SSL_GETPID(), ss->fd, ss->sec.rcvSequence));
- PRINT_BUF(1, (ss, "computed mac:", mac, macLen));
- PRINT_BUF(1, (ss, "received mac:", pBuf, macLen));
- PORT_SetError(SSL_ERROR_BAD_MAC_READ);
- rv = SECFailure;
- goto cleanup;
- }
- } else {
- ssl_ReleaseSpecReadLock(ss); /******************************/
- }
-
- if (gs->recordPadding + macLen <= gs->offset) {
- gs->recordOffset = macLen;
- gs->readOffset = macLen;
- gs->writeOffset = gs->offset - gs->recordPadding;
- rv = 1;
- } else {
- PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
-cleanup:
- /* nothing in the buffer any more. */
- gs->recordOffset = 0;
- gs->readOffset = 0;
- gs->writeOffset = 0;
- rv = SECFailure;
- }
-
- gs->recordLen = gs->writeOffset - gs->readOffset;
- gs->recordPadding = 0; /* forget we did any padding. */
- gs->state = GS_INIT;
-
-
- if (rv > 0) {
- PRINT_BUF(50, (ss, "recv clear record:",
- pBuf + gs->recordOffset, gs->recordLen));
- }
- return rv;
-
-spec_locked_done:
- ssl_ReleaseSpecReadLock(ss);
- return rv;
- }
-
- case GS_DATA:
- /* Have read in all the DATA portion of record */
-
- gs->recordOffset = 0;
- gs->readOffset = 0;
- gs->writeOffset = gs->offset;
- PORT_Assert(gs->recordLen == gs->writeOffset - gs->readOffset);
- gs->recordLen = gs->offset;
- gs->recordPadding = 0;
- gs->state = GS_INIT;
-
- ++ss->sec.rcvSequence;
-
- PRINT_BUF(50, (ss, "recv clear record:",
- pBuf + gs->recordOffset, gs->recordLen));
- return 1;
-
- } /* end switch gs->state */
- } /* end gather loop. */
- return rv;
-}
-
-/*
-** Gather a single record of data from the receiving stream. This code
-** first gathers the header (2 or 3 bytes long depending on the value of
-** the most significant bit in the first byte) then gathers up the data
-** for the record into the readBuf. This code handles non-blocking I/O
-** and is to be called multiple times until ss->sec.recordLen != 0.
- *
- * Returns +1 when it has gathered a complete SSLV2 record.
- * Returns 0 if it hits EOF.
- * Returns -1 (SECFailure) on any error
- * Returns -2 (SECWouldBlock)
- *
- * Called by ssl_GatherRecord1stHandshake in sslcon.c,
- * and by DoRecv in sslsecur.c
- * Caller must hold RecvBufLock.
- */
-int
-ssl2_GatherRecord(sslSocket *ss, int flags)
-{
- return ssl2_GatherData(ss, &ss->gs, flags);
-}
-
-/*
- * Returns +1 when it has gathered a complete SSLV2 record.
- * Returns 0 if it hits EOF.
- * Returns -1 (SECFailure) on any error
- * Returns -2 (SECWouldBlock)
- *
- * Called from SocksStartGather in sslsocks.c
- * Caller must hold RecvBufLock.
- */
-int
-ssl2_StartGatherBytes(sslSocket *ss, sslGather *gs, unsigned int count)
-{
- int rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- gs->state = GS_DATA;
- gs->remainder = count;
- gs->count = count;
- gs->offset = 0;
- if (count > gs->buf.space) {
- rv = sslBuffer_Grow(&gs->buf, count);
- if (rv) {
- return rv;
- }
- }
- return ssl2_GatherData(ss, gs, 0);
-}
-
-/* Caller should hold RecvBufLock. */
-SECStatus
-ssl_InitGather(sslGather *gs)
-{
- SECStatus status;
-
- gs->state = GS_INIT;
- gs->writeOffset = 0;
- gs->readOffset = 0;
- gs->dtlsPacketOffset = 0;
- gs->dtlsPacket.len = 0;
- status = sslBuffer_Grow(&gs->buf, 4096);
- return status;
-}
-
-/* Caller must hold RecvBufLock. */
-void
-ssl_DestroyGather(sslGather *gs)
-{
- if (gs) { /* the PORT_*Free functions check for NULL pointers. */
- PORT_ZFree(gs->buf.buf, gs->buf.space);
- PORT_Free(gs->inbuf.buf);
- PORT_Free(gs->dtlsPacket.buf);
- }
-}
-
-/* Caller must hold RecvBufLock. */
-static SECStatus
-ssl2_HandleV3HandshakeRecord(sslSocket *ss)
-{
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
- PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
-
- /* We've read in 3 bytes, there are 2 more to go in an ssl3 header. */
- ss->gs.remainder = 2;
- ss->gs.count = 0;
-
- /* Clearing these handshake pointers ensures that
- * ssl_Do1stHandshake won't call ssl2_HandleMessage when we return.
- */
- ss->nextHandshake = 0;
- ss->securityHandshake = 0;
-
- /* Setting ss->version to an SSL 3.x value will cause
- ** ssl_GatherRecord1stHandshake to invoke ssl3_GatherCompleteHandshake()
- ** the next time it is called.
- **/
- rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
- PR_TRUE);
- if (rv != SECSuccess) {
- return rv;
- }
-
- ss->sec.send = ssl3_SendApplicationData;
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h
deleted file mode 100644
index 4f99710c7..000000000
--- a/security/nss/lib/ssl/sslimpl.h
+++ /dev/null
@@ -1,1805 +0,0 @@
-/*
- * This file is PRIVATE to SSL and should be the first thing included by
- * any SSL implementation file.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef __sslimpl_h_
-#define __sslimpl_h_
-
-#ifdef DEBUG
-#undef NDEBUG
-#else
-#undef NDEBUG
-#define NDEBUG
-#endif
-#include "secport.h"
-#include "secerr.h"
-#include "sslerr.h"
-#include "ssl3prot.h"
-#include "hasht.h"
-#include "nssilock.h"
-#include "pkcs11t.h"
-#if defined(XP_UNIX) || defined(XP_BEOS)
-#include "unistd.h"
-#endif
-#include "nssrwlk.h"
-#include "prthread.h"
-#include "prclist.h"
-
-#include "sslt.h" /* for some formerly private types, now public */
-
-/* to make some of these old enums public without namespace pollution,
-** it was necessary to prepend ssl_ to the names.
-** These #defines preserve compatibility with the old code here in libssl.
-*/
-typedef SSLKEAType SSL3KEAType;
-typedef SSLMACAlgorithm SSL3MACAlgorithm;
-typedef SSLSignType SSL3SignType;
-
-#define sign_null ssl_sign_null
-#define sign_rsa ssl_sign_rsa
-#define sign_dsa ssl_sign_dsa
-#define sign_ecdsa ssl_sign_ecdsa
-
-#define calg_null ssl_calg_null
-#define calg_rc4 ssl_calg_rc4
-#define calg_rc2 ssl_calg_rc2
-#define calg_des ssl_calg_des
-#define calg_3des ssl_calg_3des
-#define calg_idea ssl_calg_idea
-#define calg_fortezza ssl_calg_fortezza /* deprecated, must preserve */
-#define calg_aes ssl_calg_aes
-#define calg_camellia ssl_calg_camellia
-#define calg_seed ssl_calg_seed
-
-#define mac_null ssl_mac_null
-#define mac_md5 ssl_mac_md5
-#define mac_sha ssl_mac_sha
-#define hmac_md5 ssl_hmac_md5
-#define hmac_sha ssl_hmac_sha
-
-#define SET_ERROR_CODE /* reminder */
-#define SEND_ALERT /* reminder */
-#define TEST_FOR_FAILURE /* reminder */
-#define DEAL_WITH_FAILURE /* reminder */
-
-#if defined(DEBUG) || defined(TRACE)
-#ifdef __cplusplus
-#define Debug 1
-#else
-extern int Debug;
-#endif
-#else
-#undef Debug
-#endif
-
-#if defined(DEBUG) && !defined(TRACE) && !defined(NISCC_TEST)
-#define TRACE
-#endif
-
-#ifdef TRACE
-#define SSL_TRC(a,b) if (ssl_trace >= (a)) ssl_Trace b
-#define PRINT_BUF(a,b) if (ssl_trace >= (a)) ssl_PrintBuf b
-#define DUMP_MSG(a,b) if (ssl_trace >= (a)) ssl_DumpMsg b
-#else
-#define SSL_TRC(a,b)
-#define PRINT_BUF(a,b)
-#define DUMP_MSG(a,b)
-#endif
-
-#ifdef DEBUG
-#define SSL_DBG(b) if (ssl_debug) ssl_Trace b
-#else
-#define SSL_DBG(b)
-#endif
-
-#include "private/pprthred.h" /* for PR_InMonitor() */
-#define ssl_InMonitor(m) PZ_InMonitor(m)
-
-#define LSB(x) ((unsigned char) ((x) & 0xff))
-#define MSB(x) ((unsigned char) (((unsigned)(x)) >> 8))
-
-/************************************************************************/
-
-typedef enum { SSLAppOpRead = 0,
- SSLAppOpWrite,
- SSLAppOpRDWR,
- SSLAppOpPost,
- SSLAppOpHeader
-} SSLAppOperation;
-
-#define SSL_MIN_MASTER_KEY_BYTES 5
-#define SSL_MAX_MASTER_KEY_BYTES 64
-
-#define SSL2_SESSIONID_BYTES 16
-#define SSL3_SESSIONID_BYTES 32
-
-#define SSL_MIN_CHALLENGE_BYTES 16
-#define SSL_MAX_CHALLENGE_BYTES 32
-#define SSL_CHALLENGE_BYTES 16
-
-#define SSL_CONNECTIONID_BYTES 16
-
-#define SSL_MIN_CYPHER_ARG_BYTES 0
-#define SSL_MAX_CYPHER_ARG_BYTES 32
-
-#define SSL_MAX_MAC_BYTES 16
-
-#define SSL3_RSA_PMS_LENGTH 48
-#define SSL3_MASTER_SECRET_LENGTH 48
-
-/* number of wrap mechanisms potentially used to wrap master secrets. */
-#define SSL_NUM_WRAP_MECHS 16
-
-/* This makes the cert cache entry exactly 4k. */
-#define SSL_MAX_CACHED_CERT_LEN 4060
-
-#define NUM_MIXERS 9
-
-/* Mask of the 25 named curves we support. */
-#ifndef NSS_ECC_MORE_THAN_SUITE_B
-#define SSL3_SUPPORTED_CURVES_MASK 0x3800000 /* only 3 curves, suite B*/
-#else
-#define SSL3_SUPPORTED_CURVES_MASK 0x3fffffe
-#endif
-
-#ifndef BPB
-#define BPB 8 /* Bits Per Byte */
-#endif
-
-#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
-
-#define INITIAL_DTLS_TIMEOUT_MS 1000 /* Default value from RFC 4347 = 1s*/
-#define MAX_DTLS_TIMEOUT_MS 60000 /* 1 minute */
-#define DTLS_FINISHED_TIMER_MS 120000 /* Time to wait in FINISHED state */
-
-typedef struct sslBufferStr sslBuffer;
-typedef struct sslConnectInfoStr sslConnectInfo;
-typedef struct sslGatherStr sslGather;
-typedef struct sslSecurityInfoStr sslSecurityInfo;
-typedef struct sslSessionIDStr sslSessionID;
-typedef struct sslSocketStr sslSocket;
-typedef struct sslSocketOpsStr sslSocketOps;
-
-typedef struct ssl3StateStr ssl3State;
-typedef struct ssl3CertNodeStr ssl3CertNode;
-typedef struct ssl3BulkCipherDefStr ssl3BulkCipherDef;
-typedef struct ssl3MACDefStr ssl3MACDef;
-typedef struct ssl3KeyPairStr ssl3KeyPair;
-
-struct ssl3CertNodeStr {
- struct ssl3CertNodeStr *next;
- CERTCertificate * cert;
-};
-
-typedef SECStatus (*sslHandshakeFunc)(sslSocket *ss);
-
-/* This type points to the low layer send func,
-** e.g. ssl2_SendStream or ssl3_SendPlainText.
-** These functions return the same values as PR_Send,
-** i.e. >= 0 means number of bytes sent, < 0 means error.
-*/
-typedef PRInt32 (*sslSendFunc)(sslSocket *ss, const unsigned char *buf,
- PRInt32 n, PRInt32 flags);
-
-typedef void (*sslSessionIDCacheFunc) (sslSessionID *sid);
-typedef void (*sslSessionIDUncacheFunc)(sslSessionID *sid);
-typedef sslSessionID *(*sslSessionIDLookupFunc)(const PRIPv6Addr *addr,
- unsigned char* sid,
- unsigned int sidLen,
- CERTCertDBHandle * dbHandle);
-
-/* registerable callback function that either appends extension to buffer
- * or returns length of data that it would have appended.
- */
-typedef PRInt32 (*ssl3HelloExtensionSenderFunc)(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-
-/* registerable callback function that handles a received extension,
- * of the given type.
- */
-typedef SECStatus (* ssl3HelloExtensionHandlerFunc)(sslSocket *ss,
- PRUint16 ex_type,
- SECItem * data);
-
-/* row in a table of hello extension senders */
-typedef struct {
- PRInt32 ex_type;
- ssl3HelloExtensionSenderFunc ex_sender;
-} ssl3HelloExtensionSender;
-
-/* row in a table of hello extension handlers */
-typedef struct {
- PRInt32 ex_type;
- ssl3HelloExtensionHandlerFunc ex_handler;
-} ssl3HelloExtensionHandler;
-
-extern SECStatus
-ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
- ssl3HelloExtensionSenderFunc cb);
-
-extern PRInt32
-ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
- const ssl3HelloExtensionSender *sender);
-
-/* Socket ops */
-struct sslSocketOpsStr {
- int (*connect) (sslSocket *, const PRNetAddr *);
- PRFileDesc *(*accept) (sslSocket *, PRNetAddr *);
- int (*bind) (sslSocket *, const PRNetAddr *);
- int (*listen) (sslSocket *, int);
- int (*shutdown)(sslSocket *, int);
- int (*close) (sslSocket *);
-
- int (*recv) (sslSocket *, unsigned char *, int, int);
-
- /* points to the higher-layer send func, e.g. ssl_SecureSend. */
- int (*send) (sslSocket *, const unsigned char *, int, int);
- int (*read) (sslSocket *, unsigned char *, int);
- int (*write) (sslSocket *, const unsigned char *, int);
-
- int (*getpeername)(sslSocket *, PRNetAddr *);
- int (*getsockname)(sslSocket *, PRNetAddr *);
-};
-
-/* Flags interpreted by ssl send functions. */
-#define ssl_SEND_FLAG_FORCE_INTO_BUFFER 0x40000000
-#define ssl_SEND_FLAG_NO_BUFFER 0x20000000
-#define ssl_SEND_FLAG_USE_EPOCH 0x10000000 /* DTLS only */
-#define ssl_SEND_FLAG_NO_RETRANSMIT 0x08000000 /* DTLS only */
-#define ssl_SEND_FLAG_CAP_RECORD_VERSION \
- 0x04000000 /* TLS only */
-#define ssl_SEND_FLAG_MASK 0x7f000000
-
-/*
-** A buffer object.
-*/
-struct sslBufferStr {
- unsigned char * buf;
- unsigned int len;
- unsigned int space;
-};
-
-/*
-** SSL3 cipher suite policy and preference struct.
-*/
-typedef struct {
-#if !defined(_WIN32)
- unsigned int cipher_suite : 16;
- unsigned int policy : 8;
- unsigned int enabled : 1;
- unsigned int isPresent : 1;
-#else
- ssl3CipherSuite cipher_suite;
- PRUint8 policy;
- unsigned char enabled : 1;
- unsigned char isPresent : 1;
-#endif
-} ssl3CipherSuiteCfg;
-
-#ifdef NSS_ENABLE_ECC
-#define ssl_V3_SUITES_IMPLEMENTED 50
-#else
-#define ssl_V3_SUITES_IMPLEMENTED 30
-#endif /* NSS_ENABLE_ECC */
-
-#define MAX_DTLS_SRTP_CIPHER_SUITES 4
-
-typedef struct sslOptionsStr {
- /* If SSL_SetNextProtoNego has been called, then this contains the
- * list of supported protocols. */
- SECItem nextProtoNego;
-
- unsigned int useSecurity : 1; /* 1 */
- unsigned int useSocks : 1; /* 2 */
- unsigned int requestCertificate : 1; /* 3 */
- unsigned int requireCertificate : 2; /* 4-5 */
- unsigned int handshakeAsClient : 1; /* 6 */
- unsigned int handshakeAsServer : 1; /* 7 */
- unsigned int enableSSL2 : 1; /* 8 */
- unsigned int unusedBit9 : 1; /* 9 */
- unsigned int unusedBit10 : 1; /* 10 */
- unsigned int noCache : 1; /* 11 */
- unsigned int fdx : 1; /* 12 */
- unsigned int v2CompatibleHello : 1; /* 13 */
- unsigned int detectRollBack : 1; /* 14 */
- unsigned int noStepDown : 1; /* 15 */
- unsigned int bypassPKCS11 : 1; /* 16 */
- unsigned int noLocks : 1; /* 17 */
- unsigned int enableSessionTickets : 1; /* 18 */
- unsigned int enableDeflate : 1; /* 19 */
- unsigned int enableRenegotiation : 2; /* 20-21 */
- unsigned int requireSafeNegotiation : 1; /* 22 */
- unsigned int enableFalseStart : 1; /* 23 */
- unsigned int cbcRandomIV : 1; /* 24 */
- unsigned int enableOCSPStapling : 1; /* 25 */
-} sslOptions;
-
-typedef enum { sslHandshakingUndetermined = 0,
- sslHandshakingAsClient,
- sslHandshakingAsServer
-} sslHandshakingType;
-
-typedef struct sslServerCertsStr {
- /* Configuration state for server sockets */
- CERTCertificate * serverCert;
- CERTCertificateList * serverCertChain;
- ssl3KeyPair * serverKeyPair;
- unsigned int serverKeyBits;
-} sslServerCerts;
-
-#define SERVERKEY serverKeyPair->privKey
-
-#define SSL_LOCK_RANK_SPEC 255
-#define SSL_LOCK_RANK_GLOBAL NSS_RWLOCK_RANK_NONE
-
-/* These are the valid values for shutdownHow.
-** These values are each 1 greater than the NSPR values, and the code
-** depends on that relation to efficiently convert PR_SHUTDOWN values
-** into ssl_SHUTDOWN values. These values use one bit for read, and
-** another bit for write, and can be used as bitmasks.
-*/
-#define ssl_SHUTDOWN_NONE 0 /* NOT shutdown at all */
-#define ssl_SHUTDOWN_RCV 1 /* PR_SHUTDOWN_RCV +1 */
-#define ssl_SHUTDOWN_SEND 2 /* PR_SHUTDOWN_SEND +1 */
-#define ssl_SHUTDOWN_BOTH 3 /* PR_SHUTDOWN_BOTH +1 */
-
-/*
-** A gather object. Used to read some data until a count has been
-** satisfied. Primarily for support of async sockets.
-** Everything in here is protected by the recvBufLock.
-*/
-struct sslGatherStr {
- int state; /* see GS_ values below. */ /* ssl 2 & 3 */
-
- /* "buf" holds received plaintext SSL records, after decrypt and MAC check.
- * SSL2: recv'd ciphertext records are put here, then decrypted in place.
- * SSL3: recv'd ciphertext records are put in inbuf (see below), then
- * decrypted into buf.
- */
- sslBuffer buf; /*recvBufLock*/ /* ssl 2 & 3 */
-
- /* number of bytes previously read into hdr or buf(ssl2) or inbuf (ssl3).
- ** (offset - writeOffset) is the number of ciphertext bytes read in but
- ** not yet deciphered.
- */
- unsigned int offset; /* ssl 2 & 3 */
-
- /* number of bytes to read in next call to ssl_DefRecv (recv) */
- unsigned int remainder; /* ssl 2 & 3 */
-
- /* Number of ciphertext bytes to read in after 2-byte SSL record header. */
- unsigned int count; /* ssl2 only */
-
- /* size of the final plaintext record.
- ** == count - (recordPadding + MAC size)
- */
- unsigned int recordLen; /* ssl2 only */
-
- /* number of bytes of padding to be removed after decrypting. */
- /* This value is taken from the record's hdr[2], which means a too large
- * value could crash us.
- */
- unsigned int recordPadding; /* ssl2 only */
-
- /* plaintext DATA begins this many bytes into "buf". */
- unsigned int recordOffset; /* ssl2 only */
-
- int encrypted; /* SSL2 session is now encrypted. ssl2 only */
-
- /* These next two values are used by SSL2 and SSL3.
- ** DoRecv uses them to extract application data.
- ** The difference between writeOffset and readOffset is the amount of
- ** data available to the application. Note that the actual offset of
- ** the data in "buf" is recordOffset (above), not readOffset.
- ** In the current implementation, this is made available before the
- ** MAC is checked!!
- */
- unsigned int readOffset; /* Spot where DATA reader (e.g. application
- ** or handshake code) will read next.
- ** Always zero for SSl3 application data.
- */
- /* offset in buf/inbuf/hdr into which new data will be read from socket. */
- unsigned int writeOffset;
-
- /* Buffer for ssl3 to read (encrypted) data from the socket */
- sslBuffer inbuf; /*recvBufLock*/ /* ssl3 only */
-
- /* The ssl[23]_GatherData functions read data into this buffer, rather
- ** than into buf or inbuf, while in the GS_HEADER state.
- ** The portion of the SSL record header put here always comes off the wire
- ** as plaintext, never ciphertext.
- ** For SSL2, the plaintext portion is two bytes long. For SSl3 it is 5.
- ** For DTLS it is 13.
- */
- unsigned char hdr[13]; /* ssl 2 & 3 or dtls */
-
- /* Buffer for DTLS data read off the wire as a single datagram */
- sslBuffer dtlsPacket;
-
- /* the start of the buffered DTLS record in dtlsPacket */
- unsigned int dtlsPacketOffset;
-};
-
-/* sslGather.state */
-#define GS_INIT 0
-#define GS_HEADER 1
-#define GS_MAC 2
-#define GS_DATA 3
-#define GS_PAD 4
-
-typedef SECStatus (*SSLCipher)(void * context,
- unsigned char * out,
- int * outlen,
- int maxout,
- const unsigned char *in,
- int inlen);
-typedef SECStatus (*SSLCompressor)(void * context,
- unsigned char * out,
- int * outlen,
- int maxout,
- const unsigned char *in,
- int inlen);
-typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit);
-
-
-
-/*
-** ssl3State and CipherSpec structs
-*/
-
-/* The SSL bulk cipher definition */
-typedef enum {
- cipher_null,
- cipher_rc4,
- cipher_rc4_40,
- cipher_rc4_56,
- cipher_rc2,
- cipher_rc2_40,
- cipher_des,
- cipher_3des,
- cipher_des40,
- cipher_idea,
- cipher_aes_128,
- cipher_aes_256,
- cipher_camellia_128,
- cipher_camellia_256,
- cipher_seed,
- cipher_missing /* reserved for no such supported cipher */
- /* This enum must match ssl3_cipherName[] in ssl3con.c. */
-} SSL3BulkCipher;
-
-typedef enum { type_stream, type_block } CipherType;
-
-#define MAX_IV_LENGTH 24
-
-/*
- * Do not depend upon 64 bit arithmetic in the underlying machine.
- */
-typedef struct {
- PRUint32 high;
- PRUint32 low;
-} SSL3SequenceNumber;
-
-typedef PRUint16 DTLSEpoch;
-
-typedef void (*DTLSTimerCb)(sslSocket *);
-
-#define MAX_MAC_CONTEXT_BYTES 400
-#define MAX_MAC_CONTEXT_LLONGS (MAX_MAC_CONTEXT_BYTES / 8)
-
-#define MAX_CIPHER_CONTEXT_BYTES 2080
-#define MAX_CIPHER_CONTEXT_LLONGS (MAX_CIPHER_CONTEXT_BYTES / 8)
-
-typedef struct {
- SSL3Opaque wrapped_master_secret[48];
- PRUint16 wrapped_master_secret_len;
- PRUint8 msIsWrapped;
- PRUint8 resumable;
-} ssl3SidKeys; /* 52 bytes */
-
-typedef struct {
- PK11SymKey *write_key;
- PK11SymKey *write_mac_key;
- PK11Context *write_mac_context;
- SECItem write_key_item;
- SECItem write_iv_item;
- SECItem write_mac_key_item;
- SSL3Opaque write_iv[MAX_IV_LENGTH];
- PRUint64 cipher_context[MAX_CIPHER_CONTEXT_LLONGS];
-} ssl3KeyMaterial;
-
-/* The DTLS anti-replay window. Defined here because we need it in
- * the cipher spec. Note that this is a ring buffer but left and
- * right represent the true window, with modular arithmetic used to
- * map them onto the buffer.
- */
-#define DTLS_RECVD_RECORDS_WINDOW 1024 /* Packets; approximate
- * Must be divisible by 8
- */
-typedef struct DTLSRecvdRecordsStr {
- unsigned char data[DTLS_RECVD_RECORDS_WINDOW/8];
- PRUint64 left;
- PRUint64 right;
-} DTLSRecvdRecords;
-
-/*
-** These are the "specs" in the "ssl3" struct.
-** Access to the pointers to these specs, and all the specs' contents
-** (direct and indirect) is protected by the reader/writer lock ss->specLock.
-*/
-typedef struct {
- const ssl3BulkCipherDef *cipher_def;
- const ssl3MACDef * mac_def;
- SSLCompressionMethod compression_method;
- int mac_size;
- SSLCipher encode;
- SSLCipher decode;
- SSLDestroy destroy;
- void * encodeContext;
- void * decodeContext;
- SSLCompressor compressor; /* Don't name these fields compress */
- SSLCompressor decompressor; /* and uncompress because zconf.h */
- /* may define them as macros. */
- SSLDestroy destroyCompressContext;
- void * compressContext;
- SSLDestroy destroyDecompressContext;
- void * decompressContext;
- PRBool bypassCiphers; /* did double bypass (at least) */
- PK11SymKey * master_secret;
- SSL3SequenceNumber write_seq_num;
- SSL3SequenceNumber read_seq_num;
- SSL3ProtocolVersion version;
- ssl3KeyMaterial client;
- ssl3KeyMaterial server;
- SECItem msItem;
- unsigned char key_block[NUM_MIXERS * MD5_LENGTH];
- unsigned char raw_master_secret[56];
- SECItem srvVirtName; /* for server: name that was negotiated
- * with a client. For client - is
- * always set to NULL.*/
- DTLSEpoch epoch;
- DTLSRecvdRecords recvdRecords;
-} ssl3CipherSpec;
-
-typedef enum { never_cached,
- in_client_cache,
- in_server_cache,
- invalid_cache /* no longer in any cache. */
-} Cached;
-
-struct sslSessionIDStr {
- sslSessionID * next; /* chain used for client sockets, only */
-
- CERTCertificate * peerCert;
- SECItemArray peerCertStatus; /* client only */
- const char * peerID; /* client only */
- const char * urlSvrName; /* client only */
- CERTCertificate * localCert;
-
- PRIPv6Addr addr;
- PRUint16 port;
-
- SSL3ProtocolVersion version;
-
- PRUint32 creationTime; /* seconds since Jan 1, 1970 */
- PRUint32 lastAccessTime; /* seconds since Jan 1, 1970 */
- PRUint32 expirationTime; /* seconds since Jan 1, 1970 */
- Cached cached;
- int references;
-
- SSLSignType authAlgorithm;
- PRUint32 authKeyBits;
- SSLKEAType keaType;
- PRUint32 keaKeyBits;
-
- union {
- struct {
- /* the V2 code depends upon the size of sessionID. */
- unsigned char sessionID[SSL2_SESSIONID_BYTES];
-
- /* Stuff used to recreate key and read/write cipher objects */
- SECItem masterKey; /* never wrapped */
- int cipherType;
- SECItem cipherArg;
- int keyBits;
- int secretKeyBits;
- } ssl2;
- struct {
- /* values that are copied into the server's on-disk SID cache. */
- uint8 sessionIDLength;
- SSL3Opaque sessionID[SSL3_SESSIONID_BYTES];
-
- ssl3CipherSuite cipherSuite;
- SSLCompressionMethod compression;
- int policy;
- ssl3SidKeys keys;
- CK_MECHANISM_TYPE masterWrapMech;
- /* mechanism used to wrap master secret */
- SSL3KEAType exchKeyType;
- /* key type used in exchange algorithm,
- * and to wrap the sym wrapping key. */
-#ifdef NSS_ENABLE_ECC
- PRUint32 negotiatedECCurves;
-#endif /* NSS_ENABLE_ECC */
-
- /* The following values are NOT restored from the server's on-disk
- * session cache, but are restored from the client's cache.
- */
- PK11SymKey * clientWriteKey;
- PK11SymKey * serverWriteKey;
-
- /* The following values pertain to the slot that wrapped the
- ** master secret. (used only in client)
- */
- SECMODModuleID masterModuleID;
- /* what module wrapped the master secret */
- CK_SLOT_ID masterSlotID;
- PRUint16 masterWrapIndex;
- /* what's the key index for the wrapping key */
- PRUint16 masterWrapSeries;
- /* keep track of the slot series, so we don't
- * accidently try to use new keys after the
- * card gets removed and replaced.*/
-
- /* The following values pertain to the slot that did the signature
- ** for client auth. (used only in client)
- */
- SECMODModuleID clAuthModuleID;
- CK_SLOT_ID clAuthSlotID;
- PRUint16 clAuthSeries;
-
- char masterValid;
- char clAuthValid;
-
- /* Session ticket if we have one, is sent as an extension in the
- * ClientHello message. This field is used by clients.
- */
- NewSessionTicket sessionTicket;
- SECItem srvName;
- } ssl3;
- } u;
-};
-
-
-typedef struct ssl3CipherSuiteDefStr {
- ssl3CipherSuite cipher_suite;
- SSL3BulkCipher bulk_cipher_alg;
- SSL3MACAlgorithm mac_alg;
- SSL3KeyExchangeAlgorithm key_exchange_alg;
-} ssl3CipherSuiteDef;
-
-/*
-** There are tables of these, all const.
-*/
-typedef struct {
- SSL3KeyExchangeAlgorithm kea;
- SSL3KEAType exchKeyType;
- SSL3SignType signKeyType;
- PRBool is_limited;
- int key_size_limit;
- PRBool tls_keygen;
-} ssl3KEADef;
-
-typedef enum { kg_null, kg_strong, kg_export } SSL3KeyGenMode;
-
-/*
-** There are tables of these, all const.
-*/
-struct ssl3BulkCipherDefStr {
- SSL3BulkCipher cipher;
- SSLCipherAlgorithm calg;
- int key_size;
- int secret_key_size;
- CipherType type;
- int iv_size;
- int block_size;
- SSL3KeyGenMode keygen_mode;
-};
-
-/*
-** There are tables of these, all const.
-*/
-struct ssl3MACDefStr {
- SSL3MACAlgorithm mac;
- CK_MECHANISM_TYPE mmech;
- int pad_size;
- int mac_size;
-};
-
-typedef enum {
- wait_client_hello,
- wait_client_cert,
- wait_client_key,
- wait_cert_verify,
- wait_change_cipher,
- wait_finished,
- wait_server_hello,
- wait_certificate_status,
- wait_server_cert,
- wait_server_key,
- wait_cert_request,
- wait_hello_done,
- wait_new_session_ticket,
- idle_handshake
-} SSL3WaitState;
-
-/*
- * TLS extension related constants and data structures.
- */
-typedef struct TLSExtensionDataStr TLSExtensionData;
-typedef struct SessionTicketDataStr SessionTicketData;
-
-struct TLSExtensionDataStr {
- /* registered callbacks that send server hello extensions */
- ssl3HelloExtensionSender serverSenders[SSL_MAX_EXTENSIONS];
- /* Keep track of the extensions that are negotiated. */
- PRUint16 numAdvertised;
- PRUint16 numNegotiated;
- PRUint16 advertised[SSL_MAX_EXTENSIONS];
- PRUint16 negotiated[SSL_MAX_EXTENSIONS];
-
- /* SessionTicket Extension related data. */
- PRBool ticketTimestampVerified;
- PRBool emptySessionTicket;
-
- /* SNI Extension related data
- * Names data is not coppied from the input buffer. It can not be
- * used outside the scope where input buffer is defined and that
- * is beyond ssl3_HandleClientHello function. */
- SECItem *sniNameArr;
- PRUint32 sniNameArrSize;
-};
-
-typedef SECStatus (*sslRestartTarget)(sslSocket *);
-
-/*
-** A DTLS queued message (potentially to be retransmitted)
-*/
-typedef struct DTLSQueuedMessageStr {
- PRCList link; /* The linked list link */
- DTLSEpoch epoch; /* The epoch to use */
- SSL3ContentType type; /* The message type */
- unsigned char *data; /* The data */
- PRUint16 len; /* The data length */
-} DTLSQueuedMessage;
-
-/*
-** This is the "hs" member of the "ssl3" struct.
-** This entire struct is protected by ssl3HandshakeLock
-*/
-typedef struct SSL3HandshakeStateStr {
- SSL3Random server_random;
- SSL3Random client_random;
- SSL3WaitState ws;
- PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS];
- PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
- PK11Context * md5; /* handshake running hashes */
- PK11Context * sha;
-const ssl3KEADef * kea_def;
- ssl3CipherSuite cipher_suite;
-const ssl3CipherSuiteDef *suite_def;
- SSLCompressionMethod compression;
- sslBuffer msg_body; /* protected by recvBufLock */
- /* partial handshake message from record layer */
- unsigned int header_bytes;
- /* number of bytes consumed from handshake */
- /* message for message type and header length */
- SSL3HandshakeType msg_type;
- unsigned long msg_len;
- SECItem ca_list; /* used only by client */
- PRBool isResuming; /* are we resuming a session */
- PRBool usedStepDownKey; /* we did a server key exchange. */
- PRBool sendingSCSV; /* instead of empty RI */
- sslBuffer msgState; /* current state for handshake messages*/
- /* protected by recvBufLock */
- sslBuffer messages; /* Accumulated handshake messages */
- PRUint16 finishedBytes; /* size of single finished below */
- union {
- TLSFinished tFinished[2]; /* client, then server */
- SSL3Hashes sFinished[2];
- SSL3Opaque data[72];
- } finishedMsgs;
-#ifdef NSS_ENABLE_ECC
- PRUint32 negotiatedECCurves; /* bit mask */
-#endif /* NSS_ENABLE_ECC */
-
- PRBool authCertificatePending;
- /* Which function should SSL_RestartHandshake* call if we're blocked?
- * One of NULL, ssl3_SendClientSecondRound, ssl3_FinishHandshake,
- * or ssl3_AlwaysFail */
- sslRestartTarget restartTarget;
- /* Shared state between ssl3_HandleFinished and ssl3_FinishHandshake */
- PRBool cacheSID;
-
- /* This group of values is used for DTLS */
- PRUint16 sendMessageSeq; /* The sending message sequence
- * number */
- PRCList lastMessageFlight; /* The last message flight we
- * sent */
- PRUint16 maxMessageSent; /* The largest message we sent */
- PRUint16 recvMessageSeq; /* The receiving message sequence
- * number */
- sslBuffer recvdFragments; /* The fragments we have received in
- * a bitmask */
- PRInt32 recvdHighWater; /* The high water mark for fragments
- * received. -1 means no reassembly
- * in progress. */
- unsigned char cookie[32]; /* The cookie */
- unsigned char cookieLen; /* The length of the cookie */
- PRIntervalTime rtTimerStarted; /* When the timer was started */
- DTLSTimerCb rtTimerCb; /* The function to call on expiry */
- PRUint32 rtTimeoutMs; /* The length of the current timeout
- * used for backoff (in ms) */
- PRUint32 rtRetries; /* The retry counter */
-} SSL3HandshakeState;
-
-
-
-/*
-** This is the "ssl3" struct, as in "ss->ssl3".
-** note:
-** usually, crSpec == cwSpec and prSpec == pwSpec.
-** Sometimes, crSpec == pwSpec and prSpec == cwSpec.
-** But there are never more than 2 actual specs.
-** No spec must ever be modified if either "current" pointer points to it.
-*/
-struct ssl3StateStr {
-
- /*
- ** The following Specs and Spec pointers must be protected using the
- ** Spec Lock.
- */
- ssl3CipherSpec * crSpec; /* current read spec. */
- ssl3CipherSpec * prSpec; /* pending read spec. */
- ssl3CipherSpec * cwSpec; /* current write spec. */
- ssl3CipherSpec * pwSpec; /* pending write spec. */
-
- CERTCertificate * clientCertificate; /* used by client */
- SECKEYPrivateKey * clientPrivateKey; /* used by client */
- CERTCertificateList *clientCertChain; /* used by client */
- PRBool sendEmptyCert; /* used by client */
-
- int policy;
- /* This says what cipher suites we can do, and should
- * be either SSL_ALLOWED or SSL_RESTRICTED
- */
- PRArenaPool * peerCertArena;
- /* These are used to keep track of the peer CA */
- void * peerCertChain;
- /* chain while we are trying to validate it. */
- CERTDistNames * ca_list;
- /* used by server. trusted CAs for this socket. */
- PRBool initialized;
- SSL3HandshakeState hs;
- ssl3CipherSpec specs[2]; /* one is current, one is pending. */
-
- /* In a client: if the server supports Next Protocol Negotiation, then
- * this is the protocol that was negotiated.
- */
- SECItem nextProto;
- SSLNextProtoState nextProtoState;
-
- PRUint16 mtu; /* Our estimate of the MTU */
-
- /* DTLS-SRTP cipher suite preferences (if any) */
- PRUint16 dtlsSRTPCiphers[MAX_DTLS_SRTP_CIPHER_SUITES];
- PRUint16 dtlsSRTPCipherCount;
- PRUint16 dtlsSRTPCipherSuite; /* 0 if not selected */
-};
-
-#define DTLS_MAX_MTU 1500 /* Ethernet MTU but without subtracting the
- * headers, so slightly larger than expected */
-#define IS_DTLS(ss) (ss->protocolVariant == ssl_variant_datagram)
-
-typedef struct {
- SSL3ContentType type;
- SSL3ProtocolVersion version;
- SSL3SequenceNumber seq_num; /* DTLS only */
- sslBuffer * buf;
-} SSL3Ciphertext;
-
-struct ssl3KeyPairStr {
- SECKEYPrivateKey * privKey;
- SECKEYPublicKey * pubKey;
- PRInt32 refCount; /* use PR_Atomic calls for this. */
-};
-
-typedef struct SSLWrappedSymWrappingKeyStr {
- SSL3Opaque wrappedSymmetricWrappingkey[512];
- CK_MECHANISM_TYPE symWrapMechanism;
- /* unwrapped symmetric wrapping key uses this mechanism */
- CK_MECHANISM_TYPE asymWrapMechanism;
- /* mechanism used to wrap the SymmetricWrappingKey using
- * server's public and/or private keys. */
- SSL3KEAType exchKeyType; /* type of keys used to wrap SymWrapKey*/
- PRInt32 symWrapMechIndex;
- PRUint16 wrappedSymKeyLen;
-} SSLWrappedSymWrappingKey;
-
-typedef struct SessionTicketStr {
- uint16 ticket_version;
- SSL3ProtocolVersion ssl_version;
- ssl3CipherSuite cipher_suite;
- SSLCompressionMethod compression_method;
- SSLSignType authAlgorithm;
- uint32 authKeyBits;
- SSLKEAType keaType;
- uint32 keaKeyBits;
- /*
- * exchKeyType and msWrapMech contain meaningful values only if
- * ms_is_wrapped is true.
- */
- uint8 ms_is_wrapped;
- SSLKEAType exchKeyType; /* XXX(wtc): same as keaType above? */
- CK_MECHANISM_TYPE msWrapMech;
- uint16 ms_length;
- SSL3Opaque master_secret[48];
- ClientIdentity client_identity;
- SECItem peer_cert;
- uint32 timestamp;
- SECItem srvName; /* negotiated server name */
-} SessionTicket;
-
-/*
- * SSL2 buffers used in SSL3.
- * writeBuf in the SecurityInfo maintained by sslsecur.c is used
- * to hold the data just about to be passed to the kernel
- * sendBuf in the ConnectInfo maintained by sslcon.c is used
- * to hold handshake messages as they are accumulated
- */
-
-/*
-** This is "ci", as in "ss->sec.ci".
-**
-** Protection: All the variables in here are protected by
-** firstHandshakeLock AND (in ssl3) ssl3HandshakeLock
-*/
-struct sslConnectInfoStr {
- /* outgoing handshakes appended to this. */
- sslBuffer sendBuf; /*xmitBufLock*/ /* ssl 2 & 3 */
-
- PRIPv6Addr peer; /* ssl 2 & 3 */
- unsigned short port; /* ssl 2 & 3 */
-
- sslSessionID *sid; /* ssl 2 & 3 */
-
- /* see CIS_HAVE defines below for the bit values in *elements. */
- char elements; /* ssl2 only */
- char requiredElements; /* ssl2 only */
- char sentElements; /* ssl2 only */
-
- char sentFinished; /* ssl2 only */
-
- /* Length of server challenge. Used by client when saving challenge */
- int serverChallengeLen; /* ssl2 only */
- /* type of authentication requested by server */
- unsigned char authType; /* ssl2 only */
-
- /* Challenge sent by client to server in client-hello message */
- /* SSL3 gets a copy of this. See ssl3_StartHandshakeHash(). */
- unsigned char clientChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl 2 & 3 */
-
- /* Connection-id sent by server to client in server-hello message */
- unsigned char connectionID[SSL_CONNECTIONID_BYTES]; /* ssl2 only */
-
- /* Challenge sent by server to client in request-certificate message */
- unsigned char serverChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl2 only */
-
- /* Information kept to handle a request-certificate message */
- unsigned char readKey[SSL_MAX_MASTER_KEY_BYTES]; /* ssl2 only */
- unsigned char writeKey[SSL_MAX_MASTER_KEY_BYTES]; /* ssl2 only */
- unsigned keySize; /* ssl2 only */
-};
-
-/* bit values for ci->elements, ci->requiredElements, sentElements. */
-#define CIS_HAVE_MASTER_KEY 0x01
-#define CIS_HAVE_CERTIFICATE 0x02
-#define CIS_HAVE_FINISHED 0x04
-#define CIS_HAVE_VERIFY 0x08
-
-/* Note: The entire content of this struct and whatever it points to gets
- * blown away by SSL_ResetHandshake(). This is "sec" as in "ss->sec".
- *
- * Unless otherwise specified below, the contents of this struct are
- * protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock.
- */
-struct sslSecurityInfoStr {
- sslSendFunc send; /*xmitBufLock*/ /* ssl 2 & 3 */
- int isServer; /* Spec Lock?*/ /* ssl 2 & 3 */
- sslBuffer writeBuf; /*xmitBufLock*/ /* ssl 2 & 3 */
-
- int cipherType; /* ssl 2 & 3 */
- int keyBits; /* ssl 2 & 3 */
- int secretKeyBits; /* ssl 2 & 3 */
- CERTCertificate *localCert; /* ssl 2 & 3 */
- CERTCertificate *peerCert; /* ssl 2 & 3 */
- SECKEYPublicKey *peerKey; /* ssl3 only */
-
- SSLSignType authAlgorithm;
- PRUint32 authKeyBits;
- SSLKEAType keaType;
- PRUint32 keaKeyBits;
-
- /*
- ** Procs used for SID cache (nonce) management.
- ** Different implementations exist for clients/servers
- ** The lookup proc is only used for servers. Baloney!
- */
- sslSessionIDCacheFunc cache; /* ssl 2 & 3 */
- sslSessionIDUncacheFunc uncache; /* ssl 2 & 3 */
-
- /*
- ** everything below here is for ssl2 only.
- ** This stuff is equivalent to SSL3's "spec", and is protected by the
- ** same "Spec Lock" as used for SSL3's specs.
- */
- PRUint32 sendSequence; /*xmitBufLock*/ /* ssl2 only */
- PRUint32 rcvSequence; /*recvBufLock*/ /* ssl2 only */
-
- /* Hash information; used for one-way-hash functions (MD2, MD5, etc.) */
- const SECHashObject *hash; /* Spec Lock */ /* ssl2 only */
- void *hashcx; /* Spec Lock */ /* ssl2 only */
-
- SECItem sendSecret; /* Spec Lock */ /* ssl2 only */
- SECItem rcvSecret; /* Spec Lock */ /* ssl2 only */
-
- /* Session cypher contexts; one for each direction */
- void *readcx; /* Spec Lock */ /* ssl2 only */
- void *writecx; /* Spec Lock */ /* ssl2 only */
- SSLCipher enc; /* Spec Lock */ /* ssl2 only */
- SSLCipher dec; /* Spec Lock */ /* ssl2 only */
- void (*destroy)(void *, PRBool); /* Spec Lock */ /* ssl2 only */
-
- /* Blocking information for the session cypher */
- int blockShift; /* Spec Lock */ /* ssl2 only */
- int blockSize; /* Spec Lock */ /* ssl2 only */
-
- /* These are used during a connection handshake */
- sslConnectInfo ci; /* ssl 2 & 3 */
-
-};
-
-/*
-** SSL Socket struct
-**
-** Protection: XXX
-*/
-struct sslSocketStr {
- PRFileDesc * fd;
-
- /* Pointer to operations vector for this socket */
- const sslSocketOps * ops;
-
- /* SSL socket options */
- sslOptions opt;
- /* Enabled version range */
- SSLVersionRange vrange;
-
- /* State flags */
- unsigned long clientAuthRequested;
- unsigned long delayDisabled; /* Nagle delay disabled */
- unsigned long firstHsDone; /* first handshake is complete. */
- unsigned long handshakeBegun;
- unsigned long lastWriteBlocked;
- unsigned long recvdCloseNotify; /* received SSL EOF. */
- unsigned long TCPconnected;
- unsigned long appDataBuffered;
- unsigned long peerRequestedProtection; /* from old renegotiation */
-
- /* version of the protocol to use */
- SSL3ProtocolVersion version;
- SSL3ProtocolVersion clientHelloVersion; /* version sent in client hello. */
-
- sslSecurityInfo sec; /* not a pointer any more */
-
- /* protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. */
- const char *url; /* ssl 2 & 3 */
-
- sslHandshakeFunc handshake; /*firstHandshakeLock*/
- sslHandshakeFunc nextHandshake; /*firstHandshakeLock*/
- sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/
-
- /* the following variable is only used with socks or other proxies. */
- char * peerID; /* String uniquely identifies target server. */
-
- unsigned char * cipherSpecs;
- unsigned int sizeCipherSpecs;
-const unsigned char * preferredCipher;
-
- ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */
-
- /* Callbacks */
- SSLAuthCertificate authCertificate;
- void *authCertificateArg;
- SSLGetClientAuthData getClientAuthData;
- void *getClientAuthDataArg;
- SSLSNISocketConfig sniSocketConfig;
- void *sniSocketConfigArg;
- SSLBadCertHandler handleBadCert;
- void *badCertArg;
- SSLHandshakeCallback handshakeCallback;
- void *handshakeCallbackData;
- void *pkcs11PinArg;
- SSLNextProtoCallback nextProtoCallback;
- void *nextProtoArg;
-
- PRIntervalTime rTimeout; /* timeout for NSPR I/O */
- PRIntervalTime wTimeout; /* timeout for NSPR I/O */
- PRIntervalTime cTimeout; /* timeout for NSPR I/O */
-
- PZLock * recvLock; /* lock against multiple reader threads. */
- PZLock * sendLock; /* lock against multiple sender threads. */
-
- PZMonitor * recvBufLock; /* locks low level recv buffers. */
- PZMonitor * xmitBufLock; /* locks low level xmit buffers. */
-
- /* Only one thread may operate on the socket until the initial handshake
- ** is complete. This Monitor ensures that. Since SSL2 handshake is
- ** only done once, this is also effectively the SSL2 handshake lock.
- */
- PZMonitor * firstHandshakeLock;
-
- /* This monitor protects the ssl3 handshake state machine data.
- ** Only one thread (reader or writer) may be in the ssl3 handshake state
- ** machine at any time. */
- PZMonitor * ssl3HandshakeLock;
-
- /* reader/writer lock, protects the secret data needed to encrypt and MAC
- ** outgoing records, and to decrypt and MAC check incoming ciphertext
- ** records. */
- NSSRWLock * specLock;
-
- /* handle to perm cert db (and implicitly to the temp cert db) used
- ** with this socket.
- */
- CERTCertDBHandle * dbHandle;
-
- PRThread * writerThread; /* thread holds SSL_LOCK_WRITER lock */
-
- PRUint16 shutdownHow; /* See ssl_SHUTDOWN defines below. */
-
- PRUint16 allowedByPolicy; /* copy of global policy bits. */
- PRUint16 maybeAllowedByPolicy; /* copy of global policy bits. */
- PRUint16 chosenPreference; /* SSL2 cipher preferences. */
-
- sslHandshakingType handshaking;
-
- /* Gather object used for gathering data */
- sslGather gs; /*recvBufLock*/
-
- sslBuffer saveBuf; /*xmitBufLock*/
- sslBuffer pendingBuf; /*xmitBufLock*/
-
- /* Configuration state for server sockets */
- /* server cert and key for each KEA type */
- sslServerCerts serverCerts[kt_kea_size];
- SECItemArray * certStatusArray;
-
- ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
- ssl3KeyPair * ephemeralECDHKeyPair; /* for ECDHE-* handshake */
-
- /* SSL3 state info. Formerly was a pointer */
- ssl3State ssl3;
-
- /*
- * TLS extension related data.
- */
- /* True when the current session is a stateless resume. */
- PRBool statelessResume;
- TLSExtensionData xtnData;
-
- /* Whether we are doing stream or datagram mode */
- SSLProtocolVariant protocolVariant;
-};
-
-
-
-/* All the global data items declared here should be protected using the
-** ssl_global_data_lock, which is a reader/writer lock.
-*/
-extern NSSRWLock * ssl_global_data_lock;
-extern char ssl_debug;
-extern char ssl_trace;
-extern FILE * ssl_trace_iob;
-extern FILE * ssl_keylog_iob;
-extern CERTDistNames * ssl3_server_ca_list;
-extern PRUint32 ssl_sid_timeout;
-extern PRUint32 ssl3_sid_timeout;
-
-extern const char * const ssl_cipherName[];
-extern const char * const ssl3_cipherName[];
-
-extern sslSessionIDLookupFunc ssl_sid_lookup;
-extern sslSessionIDCacheFunc ssl_sid_cache;
-extern sslSessionIDUncacheFunc ssl_sid_uncache;
-
-/************************************************************************/
-
-SEC_BEGIN_PROTOS
-
-/* Internal initialization and installation of the SSL error tables */
-extern SECStatus ssl_Init(void);
-extern SECStatus ssl_InitializePRErrorTable(void);
-
-/* Implementation of ops for default (non socks, non secure) case */
-extern int ssl_DefConnect(sslSocket *ss, const PRNetAddr *addr);
-extern PRFileDesc *ssl_DefAccept(sslSocket *ss, PRNetAddr *addr);
-extern int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr);
-extern int ssl_DefListen(sslSocket *ss, int backlog);
-extern int ssl_DefShutdown(sslSocket *ss, int how);
-extern int ssl_DefClose(sslSocket *ss);
-extern int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags);
-extern int ssl_DefSend(sslSocket *ss, const unsigned char *buf,
- int len, int flags);
-extern int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len);
-extern int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len);
-extern int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name);
-extern int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name);
-extern int ssl_DefGetsockopt(sslSocket *ss, PRSockOption optname,
- void *optval, PRInt32 *optlen);
-extern int ssl_DefSetsockopt(sslSocket *ss, PRSockOption optname,
- const void *optval, PRInt32 optlen);
-
-/* Implementation of ops for socks only case */
-extern int ssl_SocksConnect(sslSocket *ss, const PRNetAddr *addr);
-extern PRFileDesc *ssl_SocksAccept(sslSocket *ss, PRNetAddr *addr);
-extern int ssl_SocksBind(sslSocket *ss, const PRNetAddr *addr);
-extern int ssl_SocksListen(sslSocket *ss, int backlog);
-extern int ssl_SocksGetsockname(sslSocket *ss, PRNetAddr *name);
-extern int ssl_SocksRecv(sslSocket *ss, unsigned char *buf, int len, int flags);
-extern int ssl_SocksSend(sslSocket *ss, const unsigned char *buf,
- int len, int flags);
-extern int ssl_SocksRead(sslSocket *ss, unsigned char *buf, int len);
-extern int ssl_SocksWrite(sslSocket *ss, const unsigned char *buf, int len);
-
-/* Implementation of ops for secure only case */
-extern int ssl_SecureConnect(sslSocket *ss, const PRNetAddr *addr);
-extern PRFileDesc *ssl_SecureAccept(sslSocket *ss, PRNetAddr *addr);
-extern int ssl_SecureRecv(sslSocket *ss, unsigned char *buf,
- int len, int flags);
-extern int ssl_SecureSend(sslSocket *ss, const unsigned char *buf,
- int len, int flags);
-extern int ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len);
-extern int ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len);
-extern int ssl_SecureShutdown(sslSocket *ss, int how);
-extern int ssl_SecureClose(sslSocket *ss);
-
-/* Implementation of ops for secure socks case */
-extern int ssl_SecureSocksConnect(sslSocket *ss, const PRNetAddr *addr);
-extern PRFileDesc *ssl_SecureSocksAccept(sslSocket *ss, PRNetAddr *addr);
-extern PRFileDesc *ssl_FindTop(sslSocket *ss);
-
-/* Gather funcs. */
-extern sslGather * ssl_NewGather(void);
-extern SECStatus ssl_InitGather(sslGather *gs);
-extern void ssl_DestroyGather(sslGather *gs);
-extern int ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags);
-extern int ssl2_GatherRecord(sslSocket *ss, int flags);
-extern SECStatus ssl_GatherRecord1stHandshake(sslSocket *ss);
-
-extern SECStatus ssl2_HandleClientHelloMessage(sslSocket *ss);
-extern SECStatus ssl2_HandleServerHelloMessage(sslSocket *ss);
-extern int ssl2_StartGatherBytes(sslSocket *ss, sslGather *gs,
- unsigned int count);
-
-extern SECStatus ssl_CreateSecurityInfo(sslSocket *ss);
-extern SECStatus ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os);
-extern void ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset);
-extern void ssl_DestroySecurityInfo(sslSecurityInfo *sec);
-
-extern void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *cp, int len);
-extern void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len);
-
-extern int ssl_SendSavedWriteData(sslSocket *ss);
-extern SECStatus ssl_SaveWriteData(sslSocket *ss,
- const void* p, unsigned int l);
-extern SECStatus ssl2_BeginClientHandshake(sslSocket *ss);
-extern SECStatus ssl2_BeginServerHandshake(sslSocket *ss);
-extern int ssl_Do1stHandshake(sslSocket *ss);
-
-extern SECStatus sslBuffer_Grow(sslBuffer *b, unsigned int newLen);
-extern SECStatus sslBuffer_Append(sslBuffer *b, const void * data,
- unsigned int len);
-
-extern void ssl2_UseClearSendFunc(sslSocket *ss);
-extern void ssl_ChooseSessionIDProcs(sslSecurityInfo *sec);
-
-extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server);
-extern sslSessionID *ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port,
- const char *peerID, const char *urlSvrName);
-extern void ssl_FreeSID(sslSessionID *sid);
-
-extern int ssl3_SendApplicationData(sslSocket *ss, const PRUint8 *in,
- int len, int flags);
-
-extern PRBool ssl_FdIsBlocking(PRFileDesc *fd);
-
-extern PRBool ssl_SocketIsBlocking(sslSocket *ss);
-
-extern void ssl3_SetAlwaysBlock(sslSocket *ss);
-
-extern SECStatus ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled);
-
-extern PRBool ssl3_CanFalseStart(sslSocket *ss);
-extern SECStatus
-ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
- PRBool isServer,
- PRBool isDTLS,
- PRBool capRecordVersion,
- SSL3ContentType type,
- const SSL3Opaque * pIn,
- PRUint32 contentLen,
- sslBuffer * wrBuf);
-extern PRInt32 ssl3_SendRecord(sslSocket *ss, DTLSEpoch epoch,
- SSL3ContentType type,
- const SSL3Opaque* pIn, PRInt32 nIn,
- PRInt32 flags);
-
-#ifdef NSS_ENABLE_ZLIB
-/*
- * The DEFLATE algorithm can result in an expansion of 0.1% + 12 bytes. For a
- * maximum TLS record payload of 2**14 bytes, that's 29 bytes.
- */
-#define SSL3_COMPRESSION_MAX_EXPANSION 29
-#else /* !NSS_ENABLE_ZLIB */
-#define SSL3_COMPRESSION_MAX_EXPANSION 0
-#endif
-
-/*
- * make sure there is room in the write buffer for padding and
- * other compression and cryptographic expansions.
- */
-#define SSL3_BUFFER_FUDGE 100 + SSL3_COMPRESSION_MAX_EXPANSION
-
-#define SSL_LOCK_READER(ss) if (ss->recvLock) PZ_Lock(ss->recvLock)
-#define SSL_UNLOCK_READER(ss) if (ss->recvLock) PZ_Unlock(ss->recvLock)
-#define SSL_LOCK_WRITER(ss) if (ss->sendLock) PZ_Lock(ss->sendLock)
-#define SSL_UNLOCK_WRITER(ss) if (ss->sendLock) PZ_Unlock(ss->sendLock)
-
-/* firstHandshakeLock -> recvBufLock */
-#define ssl_Get1stHandshakeLock(ss) \
- { if (!ss->opt.noLocks) { \
- PORT_Assert(PZ_InMonitor((ss)->firstHandshakeLock) || \
- !ssl_HaveRecvBufLock(ss)); \
- PZ_EnterMonitor((ss)->firstHandshakeLock); \
- } }
-#define ssl_Release1stHandshakeLock(ss) \
- { if (!ss->opt.noLocks) PZ_ExitMonitor((ss)->firstHandshakeLock); }
-#define ssl_Have1stHandshakeLock(ss) \
- (PZ_InMonitor((ss)->firstHandshakeLock))
-
-/* ssl3HandshakeLock -> xmitBufLock */
-#define ssl_GetSSL3HandshakeLock(ss) \
- { if (!ss->opt.noLocks) { \
- PORT_Assert(!ssl_HaveXmitBufLock(ss)); \
- PZ_EnterMonitor((ss)->ssl3HandshakeLock); \
- } }
-#define ssl_ReleaseSSL3HandshakeLock(ss) \
- { if (!ss->opt.noLocks) PZ_ExitMonitor((ss)->ssl3HandshakeLock); }
-#define ssl_HaveSSL3HandshakeLock(ss) \
- (PZ_InMonitor((ss)->ssl3HandshakeLock))
-
-#define ssl_GetSpecReadLock(ss) \
- { if (!ss->opt.noLocks) NSSRWLock_LockRead((ss)->specLock); }
-#define ssl_ReleaseSpecReadLock(ss) \
- { if (!ss->opt.noLocks) NSSRWLock_UnlockRead((ss)->specLock); }
-/* NSSRWLock_HaveReadLock is not exported so there's no
- * ssl_HaveSpecReadLock macro. */
-
-#define ssl_GetSpecWriteLock(ss) \
- { if (!ss->opt.noLocks) NSSRWLock_LockWrite((ss)->specLock); }
-#define ssl_ReleaseSpecWriteLock(ss) \
- { if (!ss->opt.noLocks) NSSRWLock_UnlockWrite((ss)->specLock); }
-#define ssl_HaveSpecWriteLock(ss) \
- (NSSRWLock_HaveWriteLock((ss)->specLock))
-
-/* recvBufLock -> ssl3HandshakeLock -> xmitBufLock */
-#define ssl_GetRecvBufLock(ss) \
- { if (!ss->opt.noLocks) { \
- PORT_Assert(!ssl_HaveSSL3HandshakeLock(ss)); \
- PORT_Assert(!ssl_HaveXmitBufLock(ss)); \
- PZ_EnterMonitor((ss)->recvBufLock); \
- } }
-#define ssl_ReleaseRecvBufLock(ss) \
- { if (!ss->opt.noLocks) PZ_ExitMonitor( (ss)->recvBufLock); }
-#define ssl_HaveRecvBufLock(ss) \
- (PZ_InMonitor((ss)->recvBufLock))
-
-/* xmitBufLock -> specLock */
-#define ssl_GetXmitBufLock(ss) \
- { if (!ss->opt.noLocks) PZ_EnterMonitor((ss)->xmitBufLock); }
-#define ssl_ReleaseXmitBufLock(ss) \
- { if (!ss->opt.noLocks) PZ_ExitMonitor( (ss)->xmitBufLock); }
-#define ssl_HaveXmitBufLock(ss) \
- (PZ_InMonitor((ss)->xmitBufLock))
-
-/* Placeholder value used in version ranges when SSL 3.0 and all
- * versions of TLS are disabled.
- */
-#define SSL_LIBRARY_VERSION_NONE 0
-
-/* SSL_LIBRARY_VERSION_MAX_SUPPORTED is the maximum version that this version
- * of libssl supports. Applications should use SSL_VersionRangeGetSupported at
- * runtime to determine which versions are supported by the version of libssl
- * in use.
- */
-#define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_1
-
-/* Rename this macro SSL_ALL_VERSIONS_DISABLED when SSL 2.0 is removed. */
-#define SSL3_ALL_VERSIONS_DISABLED(vrange) \
- ((vrange)->min == SSL_LIBRARY_VERSION_NONE)
-
-extern PRBool ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
- SSL3ProtocolVersion version);
-
-extern SECStatus ssl3_KeyAndMacDeriveBypass(ssl3CipherSpec * pwSpec,
- const unsigned char * cr, const unsigned char * sr,
- PRBool isTLS, PRBool isExport);
-extern SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec,
- const unsigned char * cr, const unsigned char * sr,
- const SECItem * pms, PRBool isTLS, PRBool isRSA);
-
-/* These functions are called from secnav, even though they're "private". */
-
-extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error);
-extern int SSL_RestartHandshakeAfterCertReq(struct sslSocketStr *ss,
- CERTCertificate *cert,
- SECKEYPrivateKey *key,
- CERTCertificateList *certChain);
-extern sslSocket *ssl_FindSocket(PRFileDesc *fd);
-extern void ssl_FreeSocket(struct sslSocketStr *ssl);
-extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level,
- SSL3AlertDescription desc);
-extern SECStatus ssl3_DecodeError(sslSocket *ss);
-
-extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
-
-/*
- * for dealing with SSL 3.0 clients sending SSL 2.0 format hellos
- */
-extern SECStatus ssl3_HandleV2ClientHello(
- sslSocket *ss, unsigned char *buffer, int length);
-extern SECStatus ssl3_StartHandshakeHash(
- sslSocket *ss, unsigned char *buf, int length);
-
-/*
- * SSL3 specific routines
- */
-SECStatus ssl3_SendClientHello(sslSocket *ss, PRBool resending);
-
-/*
- * input into the SSL3 machinery from the actualy network reading code
- */
-SECStatus ssl3_HandleRecord(
- sslSocket *ss, SSL3Ciphertext *cipher, sslBuffer *out);
-
-int ssl3_GatherAppDataRecord(sslSocket *ss, int flags);
-int ssl3_GatherCompleteHandshake(sslSocket *ss, int flags);
-/*
- * When talking to export clients or using export cipher suites, servers
- * with public RSA keys larger than 512 bits need to use a 512-bit public
- * key, signed by the larger key. The smaller key is a "step down" key.
- * Generate that key pair and keep it around.
- */
-extern SECStatus ssl3_CreateRSAStepDownKeys(sslSocket *ss);
-
-#ifdef NSS_ENABLE_ECC
-extern void ssl3_FilterECCipherSuitesByServerCerts(sslSocket *ss);
-extern PRBool ssl3_IsECCEnabled(sslSocket *ss);
-extern SECStatus ssl3_DisableECCSuites(sslSocket * ss,
- const ssl3CipherSuite * suite);
-
-/* Macro for finding a curve equivalent in strength to RSA key's */
-#define SSL_RSASTRENGTH_TO_ECSTRENGTH(s) \
- ((s <= 1024) ? 160 \
- : ((s <= 2048) ? 224 \
- : ((s <= 3072) ? 256 \
- : ((s <= 7168) ? 384 : 521 ) ) ) )
-
-/* Types and names of elliptic curves used in TLS */
-typedef enum { ec_type_explicitPrime = 1,
- ec_type_explicitChar2Curve = 2,
- ec_type_named
-} ECType;
-
-typedef enum { ec_noName = 0,
- ec_sect163k1 = 1,
- ec_sect163r1 = 2,
- ec_sect163r2 = 3,
- ec_sect193r1 = 4,
- ec_sect193r2 = 5,
- ec_sect233k1 = 6,
- ec_sect233r1 = 7,
- ec_sect239k1 = 8,
- ec_sect283k1 = 9,
- ec_sect283r1 = 10,
- ec_sect409k1 = 11,
- ec_sect409r1 = 12,
- ec_sect571k1 = 13,
- ec_sect571r1 = 14,
- ec_secp160k1 = 15,
- ec_secp160r1 = 16,
- ec_secp160r2 = 17,
- ec_secp192k1 = 18,
- ec_secp192r1 = 19,
- ec_secp224k1 = 20,
- ec_secp224r1 = 21,
- ec_secp256k1 = 22,
- ec_secp256r1 = 23,
- ec_secp384r1 = 24,
- ec_secp521r1 = 25,
- ec_pastLastName
-} ECName;
-
-extern SECStatus ssl3_ECName2Params(PRArenaPool *arena, ECName curve,
- SECKEYECParams *params);
-ECName ssl3_GetCurveWithECKeyStrength(PRUint32 curvemsk, int requiredECCbits);
-
-
-#endif /* NSS_ENABLE_ECC */
-
-extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on);
-extern SECStatus ssl3_CipherPrefGetDefault(ssl3CipherSuite which, PRBool *on);
-extern SECStatus ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled);
-extern SECStatus ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled);
-
-extern SECStatus ssl3_CipherPrefSet(sslSocket *ss, ssl3CipherSuite which, PRBool on);
-extern SECStatus ssl3_CipherPrefGet(sslSocket *ss, ssl3CipherSuite which, PRBool *on);
-extern SECStatus ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled);
-extern SECStatus ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled);
-
-extern SECStatus ssl3_SetPolicy(ssl3CipherSuite which, PRInt32 policy);
-extern SECStatus ssl3_GetPolicy(ssl3CipherSuite which, PRInt32 *policy);
-extern SECStatus ssl2_SetPolicy(PRInt32 which, PRInt32 policy);
-extern SECStatus ssl2_GetPolicy(PRInt32 which, PRInt32 *policy);
-
-extern void ssl2_InitSocketPolicy(sslSocket *ss);
-extern void ssl3_InitSocketPolicy(sslSocket *ss);
-
-extern SECStatus ssl3_ConstructV2CipherSpecsHack(sslSocket *ss,
- unsigned char *cs, int *size);
-
-extern SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache);
-extern SECStatus ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b,
- PRUint32 length);
-
-extern void ssl3_DestroySSL3Info(sslSocket *ss);
-
-extern SECStatus ssl3_NegotiateVersion(sslSocket *ss,
- SSL3ProtocolVersion peerVersion,
- PRBool allowLargerPeerVersion);
-
-extern SECStatus ssl_GetPeerInfo(sslSocket *ss);
-
-#ifdef NSS_ENABLE_ECC
-/* ECDH functions */
-extern SECStatus ssl3_SendECDHClientKeyExchange(sslSocket * ss,
- SECKEYPublicKey * svrPubKey);
-extern SECStatus ssl3_HandleECDHServerKeyExchange(sslSocket *ss,
- SSL3Opaque *b, PRUint32 length);
-extern SECStatus ssl3_HandleECDHClientKeyExchange(sslSocket *ss,
- SSL3Opaque *b, PRUint32 length,
- SECKEYPublicKey *srvrPubKey,
- SECKEYPrivateKey *srvrPrivKey);
-extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss);
-#endif
-
-extern SECStatus ssl3_ComputeCommonKeyHash(PRUint8 * hashBuf,
- unsigned int bufLen, SSL3Hashes *hashes,
- PRBool bypassPKCS11);
-extern void ssl3_DestroyCipherSpec(ssl3CipherSpec *spec, PRBool freeSrvName);
-extern SECStatus ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms);
-extern SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src,
- PRInt32 bytes);
-extern SECStatus ssl3_AppendHandshakeHeader(sslSocket *ss,
- SSL3HandshakeType t, PRUint32 length);
-extern SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num,
- PRInt32 lenSize);
-extern SECStatus ssl3_AppendHandshakeVariable( sslSocket *ss,
- const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize);
-extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes,
- SSL3Opaque **b, PRUint32 *length);
-extern PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes,
- SSL3Opaque **b, PRUint32 *length);
-extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i,
- PRInt32 bytes, SSL3Opaque **b, PRUint32 *length);
-extern SECStatus ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key,
- SECItem *buf, PRBool isTLS);
-extern SECStatus ssl3_VerifySignedHashes(SSL3Hashes *hash,
- CERTCertificate *cert, SECItem *buf, PRBool isTLS,
- void *pwArg);
-extern SECStatus ssl3_CacheWrappedMasterSecret(sslSocket *ss,
- sslSessionID *sid, ssl3CipherSpec *spec,
- SSL3KEAType effectiveExchKeyType);
-
-/* Functions that handle ClientHello and ServerHello extensions. */
-extern SECStatus ssl3_HandleServerNameXtn(sslSocket * ss,
- PRUint16 ex_type, SECItem *data);
-extern SECStatus ssl3_HandleSupportedCurvesXtn(sslSocket * ss,
- PRUint16 ex_type, SECItem *data);
-extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslSocket * ss,
- PRUint16 ex_type, SECItem *data);
-extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
-extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss,
- PRUint16 ex_type, SECItem *data);
-
-/* ClientHello and ServerHello extension senders.
- * Note that not all extension senders are exposed here; only those that
- * that need exposure.
- */
-extern PRInt32 ssl3_SendSessionTicketXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-
-/* ClientHello and ServerHello extension senders.
- * The code is in ssl3ext.c.
- */
-extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append,
- PRUint32 maxBytes);
-
-/* Assigns new cert, cert chain and keys to ss->serverCerts
- * struct. If certChain is NULL, tries to find one. Aborts if
- * fails to do so. If cert and keyPair are NULL - unconfigures
- * sslSocket of kea type.*/
-extern SECStatus ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert,
- const CERTCertificateList *certChain,
- ssl3KeyPair *keyPair, SSLKEAType kea);
-
-#ifdef NSS_ENABLE_ECC
-extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss,
- PRBool append, PRUint32 maxBytes);
-extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss,
- PRBool append, PRUint32 maxBytes);
-#endif
-
-/* call the registered extension handlers. */
-extern SECStatus ssl3_HandleHelloExtensions(sslSocket *ss,
- SSL3Opaque **b, PRUint32 *length);
-
-/* Hello Extension related routines. */
-extern PRBool ssl3_ExtensionNegotiated(sslSocket *ss, PRUint16 ex_type);
-extern SECStatus ssl3_SetSIDSessionTicket(sslSessionID *sid,
- NewSessionTicket *session_ticket);
-extern SECStatus ssl3_SendNewSessionTicket(sslSocket *ss);
-extern PRBool ssl_GetSessionTicketKeys(unsigned char *keyName,
- unsigned char *encKey, unsigned char *macKey);
-extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
- SECKEYPublicKey *svrPubKey, void *pwArg,
- unsigned char *keyName, PK11SymKey **aesKey,
- PK11SymKey **macKey);
-
-/* Tell clients to consider tickets valid for this long. */
-#define TLS_EX_SESS_TICKET_LIFETIME_HINT (2 * 24 * 60 * 60) /* 2 days */
-#define TLS_EX_SESS_TICKET_VERSION (0x0100)
-
-extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
- unsigned int length);
-
-/* Construct a new NSPR socket for the app to use */
-extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd);
-extern void ssl_FreePRSocket(PRFileDesc *fd);
-
-/* Internal config function so SSL2 can initialize the present state of
- * various ciphers */
-extern int ssl3_config_match_init(sslSocket *);
-
-
-/* Create a new ref counted key pair object from two keys. */
-extern ssl3KeyPair * ssl3_NewKeyPair( SECKEYPrivateKey * privKey,
- SECKEYPublicKey * pubKey);
-
-/* get a new reference (bump ref count) to an ssl3KeyPair. */
-extern ssl3KeyPair * ssl3_GetKeyPairRef(ssl3KeyPair * keyPair);
-
-/* Decrement keypair's ref count and free if zero. */
-extern void ssl3_FreeKeyPair(ssl3KeyPair * keyPair);
-
-/* calls for accessing wrapping keys across processes. */
-extern PRBool
-ssl_GetWrappingKey( PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk);
-
-/* The caller passes in the new value it wants
- * to set. This code tests the wrapped sym key entry in the file on disk.
- * If it is uninitialized, this function writes the caller's value into
- * the disk entry, and returns false.
- * Otherwise, it overwrites the caller's wswk with the value obtained from
- * the disk, and returns PR_TRUE.
- * This is all done while holding the locks/semaphores necessary to make
- * the operation atomic.
- */
-extern PRBool
-ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk);
-
-/* get rid of the symmetric wrapping key references. */
-extern SECStatus SSL3_ShutdownServerCache(void);
-
-extern SECStatus ssl_InitSymWrapKeysLock(void);
-
-extern SECStatus ssl_FreeSymWrapKeysLock(void);
-
-extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit);
-
-extern SECStatus ssl_FreeSessionCacheLocks(void);
-
-
-/**************** DTLS-specific functions **************/
-extern void dtls_FreeQueuedMessage(DTLSQueuedMessage *msg);
-extern void dtls_FreeQueuedMessages(PRCList *lst);
-extern void dtls_FreeHandshakeMessages(PRCList *lst);
-
-extern SECStatus dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf);
-extern SECStatus dtls_HandleHelloVerifyRequest(sslSocket *ss,
- SSL3Opaque *b, PRUint32 length);
-extern SECStatus dtls_StageHandshakeMessage(sslSocket *ss);
-extern SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
- const SSL3Opaque *pIn, PRInt32 nIn);
-extern SECStatus dtls_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
-extern SECStatus dtls_CompressMACEncryptRecord(sslSocket *ss,
- DTLSEpoch epoch,
- PRBool use_epoch,
- SSL3ContentType type,
- const SSL3Opaque *pIn,
- PRUint32 contentLen,
- sslBuffer *wrBuf);
-SECStatus ssl3_DisableNonDTLSSuites(sslSocket * ss);
-extern SECStatus dtls_StartTimer(sslSocket *ss, DTLSTimerCb cb);
-extern SECStatus dtls_RestartTimer(sslSocket *ss, PRBool backoff,
- DTLSTimerCb cb);
-extern void dtls_CheckTimer(sslSocket *ss);
-extern void dtls_CancelTimer(sslSocket *ss);
-extern void dtls_FinishedTimerCb(sslSocket *ss);
-extern void dtls_SetMTU(sslSocket *ss, PRUint16 advertised);
-extern void dtls_InitRecvdRecords(DTLSRecvdRecords *records);
-extern int dtls_RecordGetRecvd(DTLSRecvdRecords *records, PRUint64 seq);
-extern void dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq);
-extern void dtls_RehandshakeCleanup(sslSocket *ss);
-extern SSL3ProtocolVersion
-dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv);
-extern SSL3ProtocolVersion
-dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv);
-
-/********************** misc calls *********************/
-
-extern int ssl_MapLowLevelError(int hiLevelError);
-
-extern PRUint32 ssl_Time(void);
-
-extern void SSL_AtomicIncrementLong(long * x);
-
-SECStatus SSL_DisableDefaultExportCipherSuites(void);
-SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd);
-PRBool SSL_IsExportCipherSuite(PRUint16 cipherSuite);
-
-extern SECStatus
-ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec,
- const char *label, unsigned int labelLen,
- const unsigned char *val, unsigned int valLen,
- unsigned char *out, unsigned int outLen);
-
-#ifdef TRACE
-#define SSL_TRACE(msg) ssl_Trace msg
-#else
-#define SSL_TRACE(msg)
-#endif
-
-void ssl_Trace(const char *format, ...);
-
-SEC_END_PROTOS
-
-#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
-#define SSL_GETPID getpid
-#elif defined(WIN32)
-extern int __cdecl _getpid(void);
-#define SSL_GETPID _getpid
-#else
-#define SSL_GETPID() 0
-#endif
-
-#endif /* __sslimpl_h_ */
diff --git a/security/nss/lib/ssl/sslinfo.c b/security/nss/lib/ssl/sslinfo.c
deleted file mode 100644
index 38b7f0e95..000000000
--- a/security/nss/lib/ssl/sslinfo.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-
-static const char *
-ssl_GetCompressionMethodName(SSLCompressionMethod compression)
-{
- switch (compression) {
- case ssl_compression_null:
- return "NULL";
-#ifdef NSS_ENABLE_ZLIB
- case ssl_compression_deflate:
- return "DEFLATE";
-#endif
- default:
- return "???";
- }
-}
-
-SECStatus
-SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
-{
- sslSocket * ss;
- SSLChannelInfo inf;
- sslSessionID * sid;
- PRBool enoughFirstHsDone = PR_FALSE;
-
- if (!info || len < sizeof inf.length) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- memset(&inf, 0, sizeof inf);
- inf.length = PR_MIN(sizeof inf, len);
-
- if (ss->firstHsDone) {
- enoughFirstHsDone = PR_TRUE;
- } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
- ssl3_CanFalseStart(ss)) {
- enoughFirstHsDone = PR_TRUE;
- }
-
- if (ss->opt.useSecurity && enoughFirstHsDone) {
- sid = ss->sec.ci.sid;
- inf.protocolVersion = ss->version;
- inf.authKeyBits = ss->sec.authKeyBits;
- inf.keaKeyBits = ss->sec.keaKeyBits;
- if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
- inf.cipherSuite = ss->sec.cipherType | 0xff00;
- inf.compressionMethod = ssl_compression_null;
- inf.compressionMethodName = "N/A";
- } else if (ss->ssl3.initialized) { /* SSL3 and TLS */
- ssl_GetSpecReadLock(ss);
- /* XXX The cipher suite should be in the specs and this
- * function should get it from cwSpec rather than from the "hs".
- * See bug 275744 comment 69 and bug 766137.
- */
- inf.cipherSuite = ss->ssl3.hs.cipher_suite;
- inf.compressionMethod = ss->ssl3.cwSpec->compression_method;
- ssl_ReleaseSpecReadLock(ss);
- inf.compressionMethodName =
- ssl_GetCompressionMethodName(inf.compressionMethod);
- }
- if (sid) {
- inf.creationTime = sid->creationTime;
- inf.lastAccessTime = sid->lastAccessTime;
- inf.expirationTime = sid->expirationTime;
- if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
- inf.sessionIDLength = SSL2_SESSIONID_BYTES;
- memcpy(inf.sessionID, sid->u.ssl2.sessionID,
- SSL2_SESSIONID_BYTES);
- } else {
- unsigned int sidLen = sid->u.ssl3.sessionIDLength;
- sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
- inf.sessionIDLength = sidLen;
- memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
- }
- }
- }
-
- memcpy(info, &inf, inf.length);
-
- return SECSuccess;
-}
-
-
-#define CS(x) x, #x
-#define CK(x) x | 0xff00, #x
-
-#define S_DSA "DSA", ssl_auth_dsa
-#define S_RSA "RSA", ssl_auth_rsa
-#define S_KEA "KEA", ssl_auth_kea
-#define S_ECDSA "ECDSA", ssl_auth_ecdsa
-
-#define K_DHE "DHE", kt_dh
-#define K_RSA "RSA", kt_rsa
-#define K_KEA "KEA", kt_kea
-#define K_ECDH "ECDH", kt_ecdh
-#define K_ECDHE "ECDHE", kt_ecdh
-
-#define C_SEED "SEED", calg_seed
-#define C_CAMELLIA "CAMELLIA", calg_camellia
-#define C_AES "AES", calg_aes
-#define C_RC4 "RC4", calg_rc4
-#define C_RC2 "RC2", calg_rc2
-#define C_DES "DES", calg_des
-#define C_3DES "3DES", calg_3des
-#define C_NULL "NULL", calg_null
-#define C_SJ "SKIPJACK", calg_sj
-
-#define B_256 256, 256, 256
-#define B_128 128, 128, 128
-#define B_3DES 192, 156, 112
-#define B_SJ 96, 80, 80
-#define B_DES 64, 56, 56
-#define B_56 128, 56, 56
-#define B_40 128, 40, 40
-#define B_0 0, 0, 0
-
-#define M_SHA "SHA1", ssl_mac_sha, 160
-#define M_MD5 "MD5", ssl_mac_md5, 128
-
-static const SSLCipherSuiteInfo suiteInfo[] = {
-/* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
-{0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
-{0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
-{0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
-{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0, },
-{0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, },
-{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0, },
-
-{0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
-{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, },
-{0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0, },
-{0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, },
-{0,CS(SSL_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0, },
-{0,CS(SSL_RSA_WITH_RC4_128_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
-{0,CS(TLS_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_SHA, 1, 0, 0, },
-
-{0,CS(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
-{0,CS(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
-{0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 1, },
-{0,CS(SSL_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
-
-{0,CS(SSL_DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
-{0,CS(SSL_DHE_DSS_WITH_DES_CBC_SHA), S_DSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
-{0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 1, },
-{0,CS(SSL_RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 0, },
-
-{0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA), S_RSA, K_RSA, C_RC4, B_56, M_SHA, 0, 1, 0, },
-{0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 1, 0, },
-{0,CS(SSL_RSA_EXPORT_WITH_RC4_40_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0, },
-{0,CS(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0, },
-{0,CS(SSL_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0, },
-{0,CS(SSL_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0, },
-
-#ifdef NSS_ENABLE_ECC
-/* ECC cipher suites */
-{0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
-
-{0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
-
-{0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, },
-
-{0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
-{0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, },
-{0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, },
-#endif /* NSS_ENABLE_ECC */
-
-/* SSL 2 table */
-{0,CK(SSL_CK_RC4_128_WITH_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0, },
-{0,CK(SSL_CK_RC2_128_CBC_WITH_MD5), S_RSA, K_RSA, C_RC2, B_128, M_MD5, 0, 0, 0, },
-{0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5), S_RSA, K_RSA, C_3DES,B_3DES,M_MD5, 0, 0, 0, },
-{0,CK(SSL_CK_DES_64_CBC_WITH_MD5), S_RSA, K_RSA, C_DES, B_DES, M_MD5, 0, 0, 0, },
-{0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0, },
-{0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0, }
-};
-
-#define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
-
-
-SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
- SSLCipherSuiteInfo *info, PRUintn len)
-{
- unsigned int i;
-
- len = PR_MIN(len, sizeof suiteInfo[0]);
- if (!info || len < sizeof suiteInfo[0].length) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- for (i = 0; i < NUM_SUITEINFOS; i++) {
- if (suiteInfo[i].cipherSuite == cipherSuite) {
- memcpy(info, &suiteInfo[i], len);
- info->length = len;
- return SECSuccess;
- }
- }
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
-}
-
-/* This function might be a candidate to be public.
- * Disables all export ciphers in the default set of enabled ciphers.
- */
-SECStatus
-SSL_DisableDefaultExportCipherSuites(void)
-{
- const SSLCipherSuiteInfo * pInfo = suiteInfo;
- unsigned int i;
- SECStatus rv;
-
- for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
- if (pInfo->isExportable) {
- rv = SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE);
- PORT_Assert(rv == SECSuccess);
- }
- }
- return SECSuccess;
-}
-
-/* This function might be a candidate to be public,
- * except that it takes an sslSocket pointer as an argument.
- * A Public version would take a PRFileDesc pointer.
- * Disables all export ciphers in the default set of enabled ciphers.
- */
-SECStatus
-SSL_DisableExportCipherSuites(PRFileDesc * fd)
-{
- const SSLCipherSuiteInfo * pInfo = suiteInfo;
- unsigned int i;
- SECStatus rv;
-
- for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
- if (pInfo->isExportable) {
- rv = SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE);
- PORT_Assert(rv == SECSuccess);
- }
- }
- return SECSuccess;
-}
-
-/* Tells us if the named suite is exportable
- * returns false for unknown suites.
- */
-PRBool
-SSL_IsExportCipherSuite(PRUint16 cipherSuite)
-{
- unsigned int i;
- for (i = 0; i < NUM_SUITEINFOS; i++) {
- if (suiteInfo[i].cipherSuite == cipherSuite) {
- return (PRBool)(suiteInfo[i].isExportable);
- }
- }
- return PR_FALSE;
-}
-
-SECItem*
-SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
-{
- SECItem *sniName = NULL;
- sslSocket *ss;
- char *name = NULL;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
- SSL_GETPID(), fd));
- return NULL;
- }
-
- if (ss->sec.isServer) {
- if (ss->version > SSL_LIBRARY_VERSION_3_0 &&
- ss->ssl3.initialized) { /* TLS */
- SECItem *crsName;
- ssl_GetSpecReadLock(ss); /*********************************/
- crsName = &ss->ssl3.cwSpec->srvVirtName;
- if (crsName->data) {
- sniName = SECITEM_DupItem(crsName);
- }
- ssl_ReleaseSpecReadLock(ss); /*----------------------------*/
- }
- return sniName;
- }
- name = SSL_RevealURL(fd);
- if (name) {
- sniName = PORT_ZNew(SECItem);
- if (!sniName) {
- PORT_Free(name);
- return NULL;
- }
- sniName->data = (void*)name;
- sniName->len = PORT_Strlen(name);
- }
- return sniName;
-}
-
-SECStatus
-SSL_ExportKeyingMaterial(PRFileDesc *fd,
- const char *label, unsigned int labelLen,
- PRBool hasContext,
- const unsigned char *context, unsigned int contextLen,
- unsigned char *out, unsigned int outLen)
-{
- sslSocket *ss;
- unsigned char *val = NULL;
- unsigned int valLen, i;
- SECStatus rv = SECFailure;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) {
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
- return SECFailure;
- }
-
- /* construct PRF arguments */
- valLen = SSL3_RANDOM_LENGTH * 2;
- if (hasContext) {
- valLen += 2 /* uint16 length */ + contextLen;
- }
- val = PORT_Alloc(valLen);
- if (!val) {
- return SECFailure;
- }
- i = 0;
- PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
- i += SSL3_RANDOM_LENGTH;
- PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH);
- i += SSL3_RANDOM_LENGTH;
- if (hasContext) {
- val[i++] = contextLen >> 8;
- val[i++] = contextLen;
- PORT_Memcpy(val + i, context, contextLen);
- i += contextLen;
- }
- PORT_Assert(i == valLen);
-
- /* Allow TLS keying material to be exported sooner, when the master
- * secret is available and we have sent ChangeCipherSpec.
- */
- ssl_GetSpecReadLock(ss);
- if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) {
- PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
- rv = SECFailure;
- } else {
- rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val,
- valLen, out, outLen);
- }
- ssl_ReleaseSpecReadLock(ss);
-
- PORT_ZFree(val, valLen);
- return rv;
-}
diff --git a/security/nss/lib/ssl/sslinit.c b/security/nss/lib/ssl/sslinit.c
deleted file mode 100644
index 92679bf03..000000000
--- a/security/nss/lib/ssl/sslinit.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * NSS utility functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "prtypes.h"
-#include "prinit.h"
-#include "seccomon.h"
-#include "secerr.h"
-#include "ssl.h"
-#include "sslimpl.h"
-
-static int ssl_inited = 0;
-
-SECStatus
-ssl_Init(void)
-{
- if (!ssl_inited) {
- if (ssl_InitializePRErrorTable() != SECSuccess) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return (SECFailure);
- }
- ssl_inited = 1;
- }
- return SECSuccess;
-}
diff --git a/security/nss/lib/ssl/sslmutex.c b/security/nss/lib/ssl/sslmutex.c
deleted file mode 100644
index a9f60d9b4..000000000
--- a/security/nss/lib/ssl/sslmutex.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "seccomon.h"
-/* This ifdef should match the one in sslsnce.c */
-#if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)
-
-#include "sslmutex.h"
-#include "prerr.h"
-
-static SECStatus single_process_sslMutex_Init(sslMutex* pMutex)
-{
- PR_ASSERT(pMutex != 0 && pMutex->u.sslLock == 0 );
-
- pMutex->u.sslLock = PR_NewLock();
- if (!pMutex->u.sslLock) {
- return SECFailure;
- }
- return SECSuccess;
-}
-
-static SECStatus single_process_sslMutex_Destroy(sslMutex* pMutex)
-{
- PR_ASSERT(pMutex != 0);
- PR_ASSERT(pMutex->u.sslLock!= 0);
- if (!pMutex->u.sslLock) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- PR_DestroyLock(pMutex->u.sslLock);
- return SECSuccess;
-}
-
-static SECStatus single_process_sslMutex_Unlock(sslMutex* pMutex)
-{
- PR_ASSERT(pMutex != 0 );
- PR_ASSERT(pMutex->u.sslLock !=0);
- if (!pMutex->u.sslLock) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- PR_Unlock(pMutex->u.sslLock);
- return SECSuccess;
-}
-
-static SECStatus single_process_sslMutex_Lock(sslMutex* pMutex)
-{
- PR_ASSERT(pMutex != 0);
- PR_ASSERT(pMutex->u.sslLock != 0 );
- if (!pMutex->u.sslLock) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- PR_Lock(pMutex->u.sslLock);
- return SECSuccess;
-}
-
-#if defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD)
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-#include "unix_err.h"
-#include "pratom.h"
-
-#define SSL_MUTEX_MAGIC 0xfeedfd
-#define NONBLOCKING_POSTS 1 /* maybe this is faster */
-
-#if NONBLOCKING_POSTS
-
-#ifndef FNONBLOCK
-#define FNONBLOCK O_NONBLOCK
-#endif
-
-static int
-setNonBlocking(int fd, int nonBlocking)
-{
- int flags;
- int err;
-
- flags = fcntl(fd, F_GETFL, 0);
- if (0 > flags)
- return flags;
- if (nonBlocking)
- flags |= FNONBLOCK;
- else
- flags &= ~FNONBLOCK;
- err = fcntl(fd, F_SETFL, flags);
- return err;
-}
-#endif
-
-SECStatus
-sslMutex_Init(sslMutex *pMutex, int shared)
-{
- int err;
- PR_ASSERT(pMutex);
- pMutex->isMultiProcess = (PRBool)(shared != 0);
- if (!shared) {
- return single_process_sslMutex_Init(pMutex);
- }
- pMutex->u.pipeStr.mPipes[0] = -1;
- pMutex->u.pipeStr.mPipes[1] = -1;
- pMutex->u.pipeStr.mPipes[2] = -1;
- pMutex->u.pipeStr.nWaiters = 0;
-
- err = pipe(pMutex->u.pipeStr.mPipes);
- if (err) {
- nss_MD_unix_map_default_error(errno);
- return err;
- }
-#if NONBLOCKING_POSTS
- err = setNonBlocking(pMutex->u.pipeStr.mPipes[1], 1);
- if (err)
- goto loser;
-#endif
-
- pMutex->u.pipeStr.mPipes[2] = SSL_MUTEX_MAGIC;
-
-#if defined(LINUX) && defined(i386)
- /* Pipe starts out empty */
- return SECSuccess;
-#else
- /* Pipe starts with one byte. */
- return sslMutex_Unlock(pMutex);
-#endif
-
-loser:
- nss_MD_unix_map_default_error(errno);
- close(pMutex->u.pipeStr.mPipes[0]);
- close(pMutex->u.pipeStr.mPipes[1]);
- return SECFailure;
-}
-
-SECStatus
-sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
-{
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Destroy(pMutex);
- }
- if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- close(pMutex->u.pipeStr.mPipes[0]);
- close(pMutex->u.pipeStr.mPipes[1]);
-
- if (processLocal) {
- return SECSuccess;
- }
-
- pMutex->u.pipeStr.mPipes[0] = -1;
- pMutex->u.pipeStr.mPipes[1] = -1;
- pMutex->u.pipeStr.mPipes[2] = -1;
- pMutex->u.pipeStr.nWaiters = 0;
-
- return SECSuccess;
-}
-
-#if defined(LINUX) && defined(i386)
-/* No memory barrier needed for this platform */
-
-/* nWaiters includes the holder of the lock (if any) and the number
-** threads waiting for it. After incrementing nWaiters, if the count
-** is exactly 1, then you have the lock and may proceed. If the
-** count is greater than 1, then you must wait on the pipe.
-*/
-
-
-SECStatus
-sslMutex_Unlock(sslMutex *pMutex)
-{
- PRInt32 newValue;
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Unlock(pMutex);
- }
-
- if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- /* Do Memory Barrier here. */
- newValue = PR_ATOMIC_DECREMENT(&pMutex->u.pipeStr.nWaiters);
- if (newValue > 0) {
- int cc;
- char c = 1;
- do {
- cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1);
- } while (cc < 0 && (errno == EINTR || errno == EAGAIN));
- if (cc != 1) {
- if (cc < 0)
- nss_MD_unix_map_default_error(errno);
- else
- PORT_SetError(PR_UNKNOWN_ERROR);
- return SECFailure;
- }
- }
- return SECSuccess;
-}
-
-SECStatus
-sslMutex_Lock(sslMutex *pMutex)
-{
- PRInt32 newValue;
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Lock(pMutex);
- }
-
- if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- newValue = PR_ATOMIC_INCREMENT(&pMutex->u.pipeStr.nWaiters);
- /* Do Memory Barrier here. */
- if (newValue > 1) {
- int cc;
- char c;
- do {
- cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1);
- } while (cc < 0 && errno == EINTR);
- if (cc != 1) {
- if (cc < 0)
- nss_MD_unix_map_default_error(errno);
- else
- PORT_SetError(PR_UNKNOWN_ERROR);
- return SECFailure;
- }
- }
- return SECSuccess;
-}
-
-#else
-
-/* Using Atomic operations requires the use of a memory barrier instruction
-** on PowerPC, Sparc, and Alpha. NSPR's PR_Atomic functions do not perform
-** them, and NSPR does not provide a function that does them (e.g. PR_Barrier).
-** So, we don't use them on those platforms.
-*/
-
-SECStatus
-sslMutex_Unlock(sslMutex *pMutex)
-{
- int cc;
- char c = 1;
-
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Unlock(pMutex);
- }
-
- if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- do {
- cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1);
- } while (cc < 0 && (errno == EINTR || errno == EAGAIN));
- if (cc != 1) {
- if (cc < 0)
- nss_MD_unix_map_default_error(errno);
- else
- PORT_SetError(PR_UNKNOWN_ERROR);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-SECStatus
-sslMutex_Lock(sslMutex *pMutex)
-{
- int cc;
- char c;
-
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Lock(pMutex);
- }
-
- if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
-
- do {
- cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1);
- } while (cc < 0 && errno == EINTR);
- if (cc != 1) {
- if (cc < 0)
- nss_MD_unix_map_default_error(errno);
- else
- PORT_SetError(PR_UNKNOWN_ERROR);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-#endif
-
-#elif defined(WIN32)
-
-#include "win32err.h"
-
-/* on Windows, we need to find the optimal type of locking mechanism to use
- for the sslMutex.
-
- There are 3 cases :
- 1) single-process, use a PRLock, as for all other platforms
- 2) Win95 multi-process, use a Win32 mutex
- 3) on WINNT multi-process, use a PRLock + a Win32 mutex
-
-*/
-
-#ifdef WINNT
-
-SECStatus sslMutex_2LevelInit(sslMutex *sem)
-{
- /* the following adds a PRLock to sslMutex . This is done in each
- process of a multi-process server and is only needed on WINNT, if
- using fibers. We can't tell if native threads or fibers are used, so
- we always do it on WINNT
- */
- PR_ASSERT(sem);
- if (sem) {
- /* we need to reset the sslLock in the children or the single_process init
- function below will assert */
- sem->u.sslLock = NULL;
- }
- return single_process_sslMutex_Init(sem);
-}
-
-static SECStatus sslMutex_2LevelDestroy(sslMutex *sem)
-{
- return single_process_sslMutex_Destroy(sem);
-}
-
-#endif
-
-SECStatus
-sslMutex_Init(sslMutex *pMutex, int shared)
-{
-#ifdef WINNT
- SECStatus retvalue;
-#endif
- HANDLE hMutex;
- SECURITY_ATTRIBUTES attributes =
- { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
-
- PR_ASSERT(pMutex != 0 && (pMutex->u.sslMutx == 0 ||
- pMutex->u.sslMutx == INVALID_HANDLE_VALUE) );
-
- pMutex->isMultiProcess = (PRBool)(shared != 0);
-
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Init(pMutex);
- }
-
-#ifdef WINNT
- /* we need a lock on WINNT for fibers in the parent process */
- retvalue = sslMutex_2LevelInit(pMutex);
- if (SECSuccess != retvalue)
- return SECFailure;
-#endif
-
- if (!pMutex || ((hMutex = pMutex->u.sslMutx) != 0 &&
- hMutex != INVALID_HANDLE_VALUE)) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- attributes.bInheritHandle = (shared ? TRUE : FALSE);
- hMutex = CreateMutex(&attributes, FALSE, NULL);
- if (hMutex == NULL) {
- hMutex = INVALID_HANDLE_VALUE;
- nss_MD_win32_map_default_error(GetLastError());
- return SECFailure;
- }
- pMutex->u.sslMutx = hMutex;
- return SECSuccess;
-}
-
-SECStatus
-sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
-{
- HANDLE hMutex;
- int rv;
- int retvalue = SECSuccess;
-
- PR_ASSERT(pMutex != 0);
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Destroy(pMutex);
- }
-
- /* multi-process mode */
-#ifdef WINNT
- /* on NT, get rid of the PRLock used for fibers within a process */
- retvalue = sslMutex_2LevelDestroy(pMutex);
-#endif
-
- PR_ASSERT( pMutex->u.sslMutx != 0 &&
- pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
- if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0
- || hMutex == INVALID_HANDLE_VALUE) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
-
- rv = CloseHandle(hMutex); /* ignore error */
- if (!processLocal && rv) {
- pMutex->u.sslMutx = hMutex = INVALID_HANDLE_VALUE;
- }
- if (!rv) {
- nss_MD_win32_map_default_error(GetLastError());
- retvalue = SECFailure;
- }
- return retvalue;
-}
-
-int
-sslMutex_Unlock(sslMutex *pMutex)
-{
- BOOL success = FALSE;
- HANDLE hMutex;
-
- PR_ASSERT(pMutex != 0 );
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Unlock(pMutex);
- }
-
- PR_ASSERT(pMutex->u.sslMutx != 0 &&
- pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
- if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 ||
- hMutex == INVALID_HANDLE_VALUE) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure;
- }
- success = ReleaseMutex(hMutex);
- if (!success) {
- nss_MD_win32_map_default_error(GetLastError());
- return SECFailure;
- }
-#ifdef WINNT
- return single_process_sslMutex_Unlock(pMutex);
- /* release PRLock for other fibers in the process */
-#else
- return SECSuccess;
-#endif
-}
-
-int
-sslMutex_Lock(sslMutex *pMutex)
-{
- HANDLE hMutex;
- DWORD event;
- DWORD lastError;
- SECStatus rv;
- SECStatus retvalue = SECSuccess;
- PR_ASSERT(pMutex != 0);
-
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Lock(pMutex);
- }
-#ifdef WINNT
- /* lock first to preserve from other threads/fibers
- in the same process */
- retvalue = single_process_sslMutex_Lock(pMutex);
-#endif
- PR_ASSERT(pMutex->u.sslMutx != 0 &&
- pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
- if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 ||
- hMutex == INVALID_HANDLE_VALUE) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return SECFailure; /* what else ? */
- }
- /* acquire the mutex to be the only owner accross all other processes */
- event = WaitForSingleObject(hMutex, INFINITE);
- switch (event) {
- case WAIT_OBJECT_0:
- case WAIT_ABANDONED:
- rv = SECSuccess;
- break;
-
- case WAIT_TIMEOUT:
-#if defined(WAIT_IO_COMPLETION)
- case WAIT_IO_COMPLETION:
-#endif
- default: /* should never happen. nothing we can do. */
- PR_ASSERT(!("WaitForSingleObject returned invalid value."));
- PORT_SetError(PR_UNKNOWN_ERROR);
- rv = SECFailure;
- break;
-
- case WAIT_FAILED: /* failure returns this */
- rv = SECFailure;
- lastError = GetLastError(); /* for debugging */
- nss_MD_win32_map_default_error(lastError);
- break;
- }
-
- if (! (SECSuccess == retvalue && SECSuccess == rv)) {
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-#elif defined(XP_UNIX)
-
-#include <errno.h>
-#include "unix_err.h"
-
-SECStatus
-sslMutex_Init(sslMutex *pMutex, int shared)
-{
- int rv;
- PR_ASSERT(pMutex);
- pMutex->isMultiProcess = (PRBool)(shared != 0);
- if (!shared) {
- return single_process_sslMutex_Init(pMutex);
- }
- do {
- rv = sem_init(&pMutex->u.sem, shared, 1);
- } while (rv < 0 && errno == EINTR);
- if (rv < 0) {
- nss_MD_unix_map_default_error(errno);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
-{
- int rv;
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Destroy(pMutex);
- }
-
- /* semaphores are global resources. See SEM_DESTROY(3) man page */
- if (processLocal) {
- return SECSuccess;
- }
- do {
- rv = sem_destroy(&pMutex->u.sem);
- } while (rv < 0 && errno == EINTR);
- if (rv < 0) {
- nss_MD_unix_map_default_error(errno);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-sslMutex_Unlock(sslMutex *pMutex)
-{
- int rv;
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Unlock(pMutex);
- }
- do {
- rv = sem_post(&pMutex->u.sem);
- } while (rv < 0 && errno == EINTR);
- if (rv < 0) {
- nss_MD_unix_map_default_error(errno);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-SECStatus
-sslMutex_Lock(sslMutex *pMutex)
-{
- int rv;
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Lock(pMutex);
- }
- do {
- rv = sem_wait(&pMutex->u.sem);
- } while (rv < 0 && errno == EINTR);
- if (rv < 0) {
- nss_MD_unix_map_default_error(errno);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-#else
-
-SECStatus
-sslMutex_Init(sslMutex *pMutex, int shared)
-{
- PR_ASSERT(pMutex);
- pMutex->isMultiProcess = (PRBool)(shared != 0);
- if (!shared) {
- return single_process_sslMutex_Init(pMutex);
- }
- PORT_Assert(!("sslMutex_Init not implemented for multi-process applications !"));
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-SECStatus
-sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
-{
- PR_ASSERT(pMutex);
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Destroy(pMutex);
- }
- PORT_Assert(!("sslMutex_Destroy not implemented for multi-process applications !"));
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-SECStatus
-sslMutex_Unlock(sslMutex *pMutex)
-{
- PR_ASSERT(pMutex);
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Unlock(pMutex);
- }
- PORT_Assert(!("sslMutex_Unlock not implemented for multi-process applications !"));
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-SECStatus
-sslMutex_Lock(sslMutex *pMutex)
-{
- PR_ASSERT(pMutex);
- if (PR_FALSE == pMutex->isMultiProcess) {
- return single_process_sslMutex_Lock(pMutex);
- }
- PORT_Assert(!("sslMutex_Lock not implemented for multi-process applications !"));
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return SECFailure;
-}
-
-#endif
-
-#endif
diff --git a/security/nss/lib/ssl/sslmutex.h b/security/nss/lib/ssl/sslmutex.h
deleted file mode 100644
index 591498692..000000000
--- a/security/nss/lib/ssl/sslmutex.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#ifndef __SSLMUTEX_H_
-#define __SSLMUTEX_H_ 1
-
-/* What SSL really wants is portable process-shared unnamed mutexes in
- * shared memory, that have the property that if the process that holds
- * them dies, they are released automatically, and that (unlike fcntl
- * record locking) lock to the thread, not to the process.
- * NSPR doesn't provide that.
- * Windows has mutexes that meet that description, but they're not portable.
- * POSIX mutexes are not automatically released when the holder dies,
- * and other processes/threads cannot release the mutex on behalf of the
- * dead holder.
- * POSIX semaphores can be used to accomplish this on systems that implement
- * process-shared unnamed POSIX semaphores, because a watchdog thread can
- * discover and release semaphores that were held by a dead process.
- * On systems that do not support process-shared POSIX unnamed semaphores,
- * they can be emulated using pipes.
- * The performance cost of doing that is not yet measured.
- *
- * So, this API looks a lot like POSIX pthread mutexes.
- */
-
-#include "prtypes.h"
-#include "prlock.h"
-
-#if defined(NETBSD)
-#include <sys/param.h> /* for __NetBSD_Version__ */
-#endif
-
-#if defined(WIN32)
-
-#include <wtypes.h>
-
-typedef struct
-{
- PRBool isMultiProcess;
-#ifdef WINNT
- /* on WINNT we need both the PRLock and the Win32 mutex for fibers */
- struct {
-#else
- union {
-#endif
- PRLock* sslLock;
- HANDLE sslMutx;
- } u;
-} sslMutex;
-
-typedef int sslPID;
-
-#elif defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD)
-
-#include <sys/types.h>
-#include "prtypes.h"
-
-typedef struct {
- PRBool isMultiProcess;
- union {
- PRLock* sslLock;
- struct {
- int mPipes[3];
- PRInt32 nWaiters;
- } pipeStr;
- } u;
-} sslMutex;
-typedef pid_t sslPID;
-
-#elif defined(XP_UNIX) /* other types of Unix */
-
-#include <sys/types.h> /* for pid_t */
-#include <semaphore.h> /* for sem_t, and sem_* functions */
-
-typedef struct
-{
- PRBool isMultiProcess;
- union {
- PRLock* sslLock;
- sem_t sem;
- } u;
-} sslMutex;
-
-typedef pid_t sslPID;
-
-#else
-
-/* what platform is this ?? */
-
-typedef struct {
- PRBool isMultiProcess;
- union {
- PRLock* sslLock;
- /* include cross-process locking mechanism here */
- } u;
-} sslMutex;
-
-typedef int sslPID;
-
-#endif
-
-#include "seccomon.h"
-
-SEC_BEGIN_PROTOS
-
-extern SECStatus sslMutex_Init(sslMutex *sem, int shared);
-
-/* If processLocal is set to true, then just free resources which are *only* associated
- * with the current process. Leave any shared resources (including the state of
- * shared memory) intact. */
-extern SECStatus sslMutex_Destroy(sslMutex *sem, PRBool processLocal);
-
-extern SECStatus sslMutex_Unlock(sslMutex *sem);
-
-extern SECStatus sslMutex_Lock(sslMutex *sem);
-
-#ifdef WINNT
-
-extern SECStatus sslMutex_2LevelInit(sslMutex *sem);
-
-#endif
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/ssl/sslnonce.c b/security/nss/lib/ssl/sslnonce.c
deleted file mode 100644
index fdfb77aab..000000000
--- a/security/nss/lib/ssl/sslnonce.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * This file implements the CLIENT Session ID cache.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "cert.h"
-#include "pk11pub.h"
-#include "secitem.h"
-#include "ssl.h"
-#include "nss.h"
-
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "nssilock.h"
-#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
-#include <time.h>
-#endif
-
-PRUint32 ssl_sid_timeout = 100;
-PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */
-
-static sslSessionID *cache = NULL;
-static PZLock * cacheLock = NULL;
-
-/* sids can be in one of 4 states:
- *
- * never_cached, created, but not yet put into cache.
- * in_client_cache, in the client cache's linked list.
- * in_server_cache, entry came from the server's cache file.
- * invalid_cache has been removed from the cache.
- */
-
-#define LOCK_CACHE lock_cache()
-#define UNLOCK_CACHE PZ_Unlock(cacheLock)
-
-static SECStatus
-ssl_InitClientSessionCacheLock(void)
-{
- cacheLock = PZ_NewLock(nssILockCache);
- return cacheLock ? SECSuccess : SECFailure;
-}
-
-static SECStatus
-ssl_FreeClientSessionCacheLock(void)
-{
- if (cacheLock) {
- PZ_DestroyLock(cacheLock);
- cacheLock = NULL;
- return SECSuccess;
- }
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
-}
-
-static PRBool LocksInitializedEarly = PR_FALSE;
-
-static SECStatus
-FreeSessionCacheLocks()
-{
- SECStatus rv1, rv2;
- rv1 = ssl_FreeSymWrapKeysLock();
- rv2 = ssl_FreeClientSessionCacheLock();
- if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) {
- return SECSuccess;
- }
- return SECFailure;
-}
-
-static SECStatus
-InitSessionCacheLocks(void)
-{
- SECStatus rv1, rv2;
- PRErrorCode rc;
- rv1 = ssl_InitSymWrapKeysLock();
- rv2 = ssl_InitClientSessionCacheLock();
- if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) {
- return SECSuccess;
- }
- rc = PORT_GetError();
- FreeSessionCacheLocks();
- PORT_SetError(rc);
- return SECFailure;
-}
-
-/* free the session cache locks if they were initialized early */
-SECStatus
-ssl_FreeSessionCacheLocks()
-{
- PORT_Assert(PR_TRUE == LocksInitializedEarly);
- if (!LocksInitializedEarly) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
- FreeSessionCacheLocks();
- LocksInitializedEarly = PR_FALSE;
- return SECSuccess;
-}
-
-static PRCallOnceType lockOnce;
-
-/* free the session cache locks if they were initialized lazily */
-static SECStatus ssl_ShutdownLocks(void* appData, void* nssData)
-{
- PORT_Assert(PR_FALSE == LocksInitializedEarly);
- if (LocksInitializedEarly) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return SECFailure;
- }
- FreeSessionCacheLocks();
- memset(&lockOnce, 0, sizeof(lockOnce));
- return SECSuccess;
-}
-
-static PRStatus initSessionCacheLocksLazily(void)
-{
- SECStatus rv = InitSessionCacheLocks();
- if (SECSuccess != rv) {
- return PR_FAILURE;
- }
- rv = NSS_RegisterShutdown(ssl_ShutdownLocks, NULL);
- PORT_Assert(SECSuccess == rv);
- if (SECSuccess != rv) {
- return PR_FAILURE;
- }
- return PR_SUCCESS;
-}
-
-/* lazyInit means that the call is not happening during a 1-time
- * initialization function, but rather during dynamic, lazy initialization
- */
-SECStatus
-ssl_InitSessionCacheLocks(PRBool lazyInit)
-{
- if (LocksInitializedEarly) {
- return SECSuccess;
- }
-
- if (lazyInit) {
- return (PR_SUCCESS ==
- PR_CallOnce(&lockOnce, initSessionCacheLocksLazily)) ?
- SECSuccess : SECFailure;
- }
-
- if (SECSuccess == InitSessionCacheLocks()) {
- LocksInitializedEarly = PR_TRUE;
- return SECSuccess;
- }
-
- return SECFailure;
-}
-
-static void
-lock_cache(void)
-{
- ssl_InitSessionCacheLocks(PR_TRUE);
- PZ_Lock(cacheLock);
-}
-
-/* BEWARE: This function gets called for both client and server SIDs !!
- * If the unreferenced sid is not in the cache, Free sid and its contents.
- */
-static void
-ssl_DestroySID(sslSessionID *sid)
-{
- SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
- PORT_Assert((sid->references == 0));
-
- if (sid->cached == in_client_cache)
- return; /* it will get taken care of next time cache is traversed. */
-
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
- SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
- }
- if (sid->peerID != NULL)
- PORT_Free((void *)sid->peerID); /* CONST */
-
- if (sid->urlSvrName != NULL)
- PORT_Free((void *)sid->urlSvrName); /* CONST */
-
- if ( sid->peerCert ) {
- CERT_DestroyCertificate(sid->peerCert);
- }
- if (sid->peerCertStatus.len) {
- SECITEM_FreeArray(&sid->peerCertStatus, PR_FALSE);
- sid->peerCertStatus.items = NULL;
- sid->peerCertStatus.len = 0;
- }
-
- if ( sid->localCert ) {
- CERT_DestroyCertificate(sid->localCert);
- }
- if (sid->u.ssl3.sessionTicket.ticket.data) {
- SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE);
- }
- if (sid->u.ssl3.srvName.data) {
- SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
- }
-
- PORT_ZFree(sid, sizeof(sslSessionID));
-}
-
-/* BEWARE: This function gets called for both client and server SIDs !!
- * Decrement reference count, and
- * free sid if ref count is zero, and sid is not in the cache.
- * Does NOT remove from the cache first.
- * If the sid is still in the cache, it is left there until next time
- * the cache list is traversed.
- */
-static void
-ssl_FreeLockedSID(sslSessionID *sid)
-{
- PORT_Assert(sid->references >= 1);
- if (--sid->references == 0) {
- ssl_DestroySID(sid);
- }
-}
-
-/* BEWARE: This function gets called for both client and server SIDs !!
- * Decrement reference count, and
- * free sid if ref count is zero, and sid is not in the cache.
- * Does NOT remove from the cache first.
- * These locks are necessary because the sid _might_ be in the cache list.
- */
-void
-ssl_FreeSID(sslSessionID *sid)
-{
- LOCK_CACHE;
- ssl_FreeLockedSID(sid);
- UNLOCK_CACHE;
-}
-
-/************************************************************************/
-
-/*
-** Lookup sid entry in cache by Address, port, and peerID string.
-** If found, Increment reference count, and return pointer to caller.
-** If it has timed out or ref count is zero, remove from list and free it.
-*/
-
-sslSessionID *
-ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
- const char * urlSvrName)
-{
- sslSessionID **sidp;
- sslSessionID * sid;
- PRUint32 now;
-
- if (!urlSvrName)
- return NULL;
- now = ssl_Time();
- LOCK_CACHE;
- sidp = &cache;
- while ((sid = *sidp) != 0) {
- PORT_Assert(sid->cached == in_client_cache);
- PORT_Assert(sid->references >= 1);
-
- SSL_TRC(8, ("SSL: Lookup1: sid=0x%x", sid));
-
- if (sid->expirationTime < now || !sid->references) {
- /*
- ** This session-id timed out, or was orphaned.
- ** Don't even care who it belongs to, blow it out of our cache.
- */
- SSL_TRC(7, ("SSL: lookup1, throwing sid out, age=%d refs=%d",
- now - sid->creationTime, sid->references));
-
- *sidp = sid->next; /* delink it from the list. */
- sid->cached = invalid_cache; /* mark not on list. */
- if (!sid->references)
- ssl_DestroySID(sid);
- else
- ssl_FreeLockedSID(sid); /* drop ref count, free. */
-
- } else if (!memcmp(&sid->addr, addr, sizeof(PRIPv6Addr)) && /* server IP addr matches */
- (sid->port == port) && /* server port matches */
- /* proxy (peerID) matches */
- (((peerID == NULL) && (sid->peerID == NULL)) ||
- ((peerID != NULL) && (sid->peerID != NULL) &&
- PORT_Strcmp(sid->peerID, peerID) == 0)) &&
- /* is cacheable */
- (sid->version < SSL_LIBRARY_VERSION_3_0 ||
- sid->u.ssl3.keys.resumable) &&
- /* server hostname matches. */
- (sid->urlSvrName != NULL) &&
- ((0 == PORT_Strcmp(urlSvrName, sid->urlSvrName)) ||
- ((sid->peerCert != NULL) && (SECSuccess ==
- CERT_VerifyCertName(sid->peerCert, urlSvrName))) )
- ) {
- /* Hit */
- sid->lastAccessTime = now;
- sid->references++;
- break;
- } else {
- sidp = &sid->next;
- }
- }
- UNLOCK_CACHE;
- return sid;
-}
-
-/*
-** Add an sid to the cache or return a previously cached entry to the cache.
-** Although this is static, it is called via ss->sec.cache().
-*/
-static void
-CacheSID(sslSessionID *sid)
-{
- PRUint32 expirationPeriod;
- SSL_TRC(8, ("SSL: Cache: sid=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
- "time=%x cached=%d",
- sid, sid->cached, sid->addr.pr_s6_addr32[0],
- sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2],
- sid->addr.pr_s6_addr32[3], sid->port, sid->creationTime,
- sid->cached));
-
- if (sid->cached == in_client_cache)
- return;
-
- if (!sid->urlSvrName) {
- /* don't cache this SID because it can never be matched */
- return;
- }
-
- /* XXX should be different trace for version 2 vs. version 3 */
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- expirationPeriod = ssl_sid_timeout;
- PRINT_BUF(8, (0, "sessionID:",
- sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID)));
- PRINT_BUF(8, (0, "masterKey:",
- sid->u.ssl2.masterKey.data, sid->u.ssl2.masterKey.len));
- PRINT_BUF(8, (0, "cipherArg:",
- sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len));
- } else {
- if (sid->u.ssl3.sessionIDLength == 0 &&
- sid->u.ssl3.sessionTicket.ticket.data == NULL)
- return;
- /* Client generates the SessionID if this was a stateless resume. */
- if (sid->u.ssl3.sessionIDLength == 0) {
- SECStatus rv;
- rv = PK11_GenerateRandom(sid->u.ssl3.sessionID,
- SSL3_SESSIONID_BYTES);
- if (rv != SECSuccess)
- return;
- sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
- }
- expirationPeriod = ssl3_sid_timeout;
- PRINT_BUF(8, (0, "sessionID:",
- sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength));
- }
- PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0);
- if (!sid->creationTime)
- sid->lastAccessTime = sid->creationTime = ssl_Time();
- if (!sid->expirationTime)
- sid->expirationTime = sid->creationTime + expirationPeriod;
-
- /*
- * Put sid into the cache. Bump reference count to indicate that
- * cache is holding a reference. Uncache will reduce the cache
- * reference.
- */
- LOCK_CACHE;
- sid->references++;
- sid->cached = in_client_cache;
- sid->next = cache;
- cache = sid;
- UNLOCK_CACHE;
-}
-
-/*
- * If sid "zap" is in the cache,
- * removes sid from cache, and decrements reference count.
- * Caller must hold cache lock.
- */
-static void
-UncacheSID(sslSessionID *zap)
-{
- sslSessionID **sidp = &cache;
- sslSessionID *sid;
-
- if (zap->cached != in_client_cache) {
- return;
- }
-
- SSL_TRC(8,("SSL: Uncache: zap=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
- "time=%x cipher=%d",
- zap, zap->cached, zap->addr.pr_s6_addr32[0],
- zap->addr.pr_s6_addr32[1], zap->addr.pr_s6_addr32[2],
- zap->addr.pr_s6_addr32[3], zap->port, zap->creationTime,
- zap->u.ssl2.cipherType));
- if (zap->version < SSL_LIBRARY_VERSION_3_0) {
- PRINT_BUF(8, (0, "sessionID:",
- zap->u.ssl2.sessionID, sizeof(zap->u.ssl2.sessionID)));
- PRINT_BUF(8, (0, "masterKey:",
- zap->u.ssl2.masterKey.data, zap->u.ssl2.masterKey.len));
- PRINT_BUF(8, (0, "cipherArg:",
- zap->u.ssl2.cipherArg.data, zap->u.ssl2.cipherArg.len));
- }
-
- /* See if it's in the cache, if so nuke it */
- while ((sid = *sidp) != 0) {
- if (sid == zap) {
- /*
- ** Bingo. Reduce reference count by one so that when
- ** everyone is done with the sid we can free it up.
- */
- *sidp = zap->next;
- zap->cached = invalid_cache;
- ssl_FreeLockedSID(zap);
- return;
- }
- sidp = &sid->next;
- }
-}
-
-/* If sid "zap" is in the cache,
- * removes sid from cache, and decrements reference count.
- * Although this function is static, it is called externally via
- * ss->sec.uncache().
- */
-static void
-LockAndUncacheSID(sslSessionID *zap)
-{
- LOCK_CACHE;
- UncacheSID(zap);
- UNLOCK_CACHE;
-
-}
-
-/* choose client or server cache functions for this sslsocket. */
-void
-ssl_ChooseSessionIDProcs(sslSecurityInfo *sec)
-{
- if (sec->isServer) {
- sec->cache = ssl_sid_cache;
- sec->uncache = ssl_sid_uncache;
- } else {
- sec->cache = CacheSID;
- sec->uncache = LockAndUncacheSID;
- }
-}
-
-/* wipe out the entire client session cache. */
-void
-SSL_ClearSessionCache(void)
-{
- LOCK_CACHE;
- while(cache != NULL)
- UncacheSID(cache);
- UNLOCK_CACHE;
-}
-
-/* returns an unsigned int containing the number of seconds in PR_Now() */
-PRUint32
-ssl_Time(void)
-{
- PRUint32 myTime;
-#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
- myTime = time(NULL); /* accurate until the year 2038. */
-#else
- /* portable, but possibly slower */
- PRTime now;
- PRInt64 ll;
-
- now = PR_Now();
- LL_I2L(ll, 1000000L);
- LL_DIV(now, now, ll);
- LL_L2UI(myTime, now);
-#endif
- return myTime;
-}
-
-SECStatus
-ssl3_SetSIDSessionTicket(sslSessionID *sid, NewSessionTicket *session_ticket)
-{
- SECStatus rv;
-
- /* We need to lock the cache, as this sid might already be in the cache. */
- LOCK_CACHE;
-
- /* A server might have sent us an empty ticket, which has the
- * effect of clearing the previously known ticket.
- */
- if (sid->u.ssl3.sessionTicket.ticket.data)
- SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE);
- if (session_ticket->ticket.len > 0) {
- rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.sessionTicket.ticket,
- &session_ticket->ticket);
- if (rv != SECSuccess) {
- UNLOCK_CACHE;
- return rv;
- }
- } else {
- sid->u.ssl3.sessionTicket.ticket.data = NULL;
- sid->u.ssl3.sessionTicket.ticket.len = 0;
- }
- sid->u.ssl3.sessionTicket.received_timestamp =
- session_ticket->received_timestamp;
- sid->u.ssl3.sessionTicket.ticket_lifetime_hint =
- session_ticket->ticket_lifetime_hint;
-
- UNLOCK_CACHE;
- return SECSuccess;
-}
diff --git a/security/nss/lib/ssl/sslproto.h b/security/nss/lib/ssl/sslproto.h
deleted file mode 100644
index 4acf6ab9e..000000000
--- a/security/nss/lib/ssl/sslproto.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Various and sundry protocol constants. DON'T CHANGE THESE. These values
- * are mostly defined by the SSL2, SSL3, or TLS protocol specifications.
- * Cipher kinds and ciphersuites are part of the public API.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef __sslproto_h_
-#define __sslproto_h_
-
-/* All versions less than 3_0 are treated as SSL version 2 */
-#define SSL_LIBRARY_VERSION_2 0x0002
-#define SSL_LIBRARY_VERSION_3_0 0x0300
-#define SSL_LIBRARY_VERSION_TLS_1_0 0x0301
-#define SSL_LIBRARY_VERSION_TLS_1_1 0x0302
-/* Note: this is the internal format, not the wire format */
-#define SSL_LIBRARY_VERSION_DTLS_1_0 0x0302
-
-/* deprecated old name */
-#define SSL_LIBRARY_VERSION_3_1_TLS SSL_LIBRARY_VERSION_TLS_1_0
-
-/* The DTLS version used in the spec */
-#define SSL_LIBRARY_VERSION_DTLS_1_0_WIRE ((~0x0100) & 0xffff)
-
-/* Header lengths of some of the messages */
-#define SSL_HL_ERROR_HBYTES 3
-#define SSL_HL_CLIENT_HELLO_HBYTES 9
-#define SSL_HL_CLIENT_MASTER_KEY_HBYTES 10
-#define SSL_HL_CLIENT_FINISHED_HBYTES 1
-#define SSL_HL_SERVER_HELLO_HBYTES 11
-#define SSL_HL_SERVER_VERIFY_HBYTES 1
-#define SSL_HL_SERVER_FINISHED_HBYTES 1
-#define SSL_HL_REQUEST_CERTIFICATE_HBYTES 2
-#define SSL_HL_CLIENT_CERTIFICATE_HBYTES 6
-
-/* Security handshake protocol codes */
-#define SSL_MT_ERROR 0
-#define SSL_MT_CLIENT_HELLO 1
-#define SSL_MT_CLIENT_MASTER_KEY 2
-#define SSL_MT_CLIENT_FINISHED 3
-#define SSL_MT_SERVER_HELLO 4
-#define SSL_MT_SERVER_VERIFY 5
-#define SSL_MT_SERVER_FINISHED 6
-#define SSL_MT_REQUEST_CERTIFICATE 7
-#define SSL_MT_CLIENT_CERTIFICATE 8
-
-/* Certificate types */
-#define SSL_CT_X509_CERTIFICATE 0x01
-#if 0 /* XXX Not implemented yet */
-#define SSL_PKCS6_CERTIFICATE 0x02
-#endif
-#define SSL_AT_MD5_WITH_RSA_ENCRYPTION 0x01
-
-/* Error codes */
-#define SSL_PE_NO_CYPHERS 0x0001
-#define SSL_PE_NO_CERTIFICATE 0x0002
-#define SSL_PE_BAD_CERTIFICATE 0x0004
-#define SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
-
-/* Cypher kinds (not the spec version!) */
-#define SSL_CK_RC4_128_WITH_MD5 0x01
-#define SSL_CK_RC4_128_EXPORT40_WITH_MD5 0x02
-#define SSL_CK_RC2_128_CBC_WITH_MD5 0x03
-#define SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x04
-#define SSL_CK_IDEA_128_CBC_WITH_MD5 0x05
-#define SSL_CK_DES_64_CBC_WITH_MD5 0x06
-#define SSL_CK_DES_192_EDE3_CBC_WITH_MD5 0x07
-
-/* Cipher enables. These are used only for SSL_EnableCipher
- * These values define the SSL2 suites, and do not colide with the
- * SSL3 Cipher suites defined below.
- */
-#define SSL_EN_RC4_128_WITH_MD5 0xFF01
-#define SSL_EN_RC4_128_EXPORT40_WITH_MD5 0xFF02
-#define SSL_EN_RC2_128_CBC_WITH_MD5 0xFF03
-#define SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 0xFF04
-#define SSL_EN_IDEA_128_CBC_WITH_MD5 0xFF05
-#define SSL_EN_DES_64_CBC_WITH_MD5 0xFF06
-#define SSL_EN_DES_192_EDE3_CBC_WITH_MD5 0xFF07
-
-/* SSL v3 Cipher Suites */
-#define SSL_NULL_WITH_NULL_NULL 0x0000
-
-#define SSL_RSA_WITH_NULL_MD5 0x0001
-#define SSL_RSA_WITH_NULL_SHA 0x0002
-#define SSL_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
-#define SSL_RSA_WITH_RC4_128_MD5 0x0004
-#define SSL_RSA_WITH_RC4_128_SHA 0x0005
-#define SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 0x0006
-#define SSL_RSA_WITH_IDEA_CBC_SHA 0x0007
-#define SSL_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0008
-#define SSL_RSA_WITH_DES_CBC_SHA 0x0009
-#define SSL_RSA_WITH_3DES_EDE_CBC_SHA 0x000a
-
-#define SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA 0x000b
-#define SSL_DH_DSS_WITH_DES_CBC_SHA 0x000c
-#define SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA 0x000d
-#define SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA 0x000e
-#define SSL_DH_RSA_WITH_DES_CBC_SHA 0x000f
-#define SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA 0x0010
-
-#define SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA 0x0011
-#define SSL_DHE_DSS_WITH_DES_CBC_SHA 0x0012
-#define SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA 0x0013
-#define SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA 0x0014
-#define SSL_DHE_RSA_WITH_DES_CBC_SHA 0x0015
-#define SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016
-
-#define SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5 0x0017
-#define SSL_DH_ANON_WITH_RC4_128_MD5 0x0018
-#define SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA 0x0019
-#define SSL_DH_ANON_WITH_DES_CBC_SHA 0x001a
-#define SSL_DH_ANON_WITH_3DES_EDE_CBC_SHA 0x001b
-
-#define SSL_FORTEZZA_DMS_WITH_NULL_SHA 0x001c /* deprecated */
-#define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d /* deprecated */
-#define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e /* deprecated */
-
-/* New TLS cipher suites */
-#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F
-#define TLS_DH_DSS_WITH_AES_128_CBC_SHA 0x0030
-#define TLS_DH_RSA_WITH_AES_128_CBC_SHA 0x0031
-#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA 0x0032
-#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033
-#define TLS_DH_ANON_WITH_AES_128_CBC_SHA 0x0034
-
-#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
-#define TLS_DH_DSS_WITH_AES_256_CBC_SHA 0x0036
-#define TLS_DH_RSA_WITH_AES_256_CBC_SHA 0x0037
-#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038
-#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039
-#define TLS_DH_ANON_WITH_AES_256_CBC_SHA 0x003A
-
-#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0041
-#define TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x0042
-#define TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0043
-#define TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x0044
-#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x0045
-#define TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA 0x0046
-
-#define TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x0062
-#define TLS_RSA_EXPORT1024_WITH_RC4_56_SHA 0x0064
-
-#define TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x0063
-#define TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x0065
-#define TLS_DHE_DSS_WITH_RC4_128_SHA 0x0066
-
-#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0084
-#define TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x0085
-#define TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0086
-#define TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x0087
-#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x0088
-#define TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA 0x0089
-
-#define TLS_RSA_WITH_SEED_CBC_SHA 0x0096
-
-/* TLS "Signaling Cipher Suite Value" (SCSV). May be requested by client.
- * Must NEVER be chosen by server. SSL 3.0 server acknowledges by sending
- * back an empty Renegotiation Info (RI) server hello extension.
- */
-#define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00FF
-
-/* Cipher Suite Values starting with 0xC000 are defined in informational
- * RFCs.
- */
-#define TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001
-#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002
-#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003
-#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004
-#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005
-
-#define TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006
-#define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007
-#define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008
-#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009
-#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A
-
-#define TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B
-#define TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C
-#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D
-#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E
-#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F
-
-#define TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010
-#define TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011
-#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012
-#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013
-#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014
-
-#define TLS_ECDH_anon_WITH_NULL_SHA 0xC015
-#define TLS_ECDH_anon_WITH_RC4_128_SHA 0xC016
-#define TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA 0xC017
-#define TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018
-#define TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019
-
-/* Netscape "experimental" cipher suites. */
-#define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
-#define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1
-
-/* New non-experimental openly spec'ed versions of those cipher suites. */
-#define SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA 0xfeff
-#define SSL_RSA_FIPS_WITH_DES_CBC_SHA 0xfefe
-
-/* DTLS-SRTP cipher suites from RFC 5764 */
-/* If you modify this, also modify MAX_DTLS_SRTP_CIPHER_SUITES in sslimpl.h */
-#define SRTP_AES128_CM_HMAC_SHA1_80 0x0001
-#define SRTP_AES128_CM_HMAC_SHA1_32 0x0002
-#define SRTP_NULL_HMAC_SHA1_80 0x0005
-#define SRTP_NULL_HMAC_SHA1_32 0x0006
-
-#endif /* __sslproto_h_ */
diff --git a/security/nss/lib/ssl/sslreveal.c b/security/nss/lib/ssl/sslreveal.c
deleted file mode 100644
index 612847997..000000000
--- a/security/nss/lib/ssl/sslreveal.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Accessor functions for SSLSocket private members.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "cert.h"
-#include "ssl.h"
-#include "certt.h"
-#include "sslimpl.h"
-
-/* given PRFileDesc, returns a copy of certificate associated with the socket
- * the caller should delete the cert when done with SSL_DestroyCertificate
- */
-CERTCertificate *
-SSL_RevealCert(PRFileDesc * fd)
-{
- CERTCertificate * cert = NULL;
- sslSocket * sslsocket = NULL;
-
- sslsocket = ssl_FindSocket(fd);
-
- /* CERT_DupCertificate increases reference count and returns pointer to
- * the same cert
- */
- if (sslsocket && sslsocket->sec.peerCert)
- cert = CERT_DupCertificate(sslsocket->sec.peerCert);
-
- return cert;
-}
-
-/* given PRFileDesc, returns a pointer to PinArg associated with the socket
- */
-void *
-SSL_RevealPinArg(PRFileDesc * fd)
-{
- sslSocket * sslsocket = NULL;
- void * PinArg = NULL;
-
- sslsocket = ssl_FindSocket(fd);
-
- /* is pkcs11PinArg part of the sslSocket or sslSecurityInfo ? */
- if (sslsocket)
- PinArg = sslsocket->pkcs11PinArg;
-
- return PinArg;
-}
-
-
-/* given PRFileDesc, returns a pointer to the URL associated with the socket
- * the caller should free url when done
- */
-char *
-SSL_RevealURL(PRFileDesc * fd)
-{
- sslSocket * sslsocket = NULL;
- char * url = NULL;
-
- sslsocket = ssl_FindSocket(fd);
-
- if (sslsocket && sslsocket->url)
- url = PL_strdup(sslsocket->url);
-
- return url;
-}
-
-
-/* given PRFileDesc, returns status information related to extensions
- * negotiated with peer during the handshake.
- */
-
-SECStatus
-SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
- SSLExtensionType extId,
- PRBool *pYes)
-{
- /* some decisions derived from SSL_GetChannelInfo */
- sslSocket * sslsocket = NULL;
- SECStatus rv = SECFailure;
- PRBool enoughFirstHsDone = PR_FALSE;
-
- if (!pYes)
- return rv;
-
- sslsocket = ssl_FindSocket(socket);
- if (!sslsocket) {
- SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeNegotiatedExtension",
- SSL_GETPID(), socket));
- return rv;
- }
-
- if (sslsocket->firstHsDone) {
- enoughFirstHsDone = PR_TRUE;
- } else if (sslsocket->ssl3.initialized && ssl3_CanFalseStart(sslsocket)) {
- enoughFirstHsDone = PR_TRUE;
- }
-
- /* according to public API SSL_GetChannelInfo, this doesn't need a lock */
- if (sslsocket->opt.useSecurity && enoughFirstHsDone) {
- if (sslsocket->ssl3.initialized) { /* SSL3 and TLS */
- /* now we know this socket went through ssl3_InitState() and
- * ss->xtnData got initialized, which is the only member accessed by
- * ssl3_ExtensionNegotiated();
- * Member xtnData appears to get accessed in functions that handle
- * the handshake (hello messages and extension sending),
- * therefore the handshake lock should be sufficient.
- */
- ssl_GetSSL3HandshakeLock(sslsocket);
- *pYes = ssl3_ExtensionNegotiated(sslsocket, extId);
- ssl_ReleaseSSL3HandshakeLock(sslsocket);
- rv = SECSuccess;
- }
- }
-
- return rv;
-}
diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c
deleted file mode 100644
index e17a7cb06..000000000
--- a/security/nss/lib/ssl/sslsecur.c
+++ /dev/null
@@ -1,1505 +0,0 @@
-/*
- * Various SSL functions.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#include "cert.h"
-#include "secitem.h"
-#include "keyhi.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "secoid.h" /* for SECOID_GetALgorithmTag */
-#include "pk11func.h" /* for PK11_GenerateRandom */
-#include "nss.h" /* for NSS_RegisterShutdown */
-#include "prinit.h" /* for PR_CallOnceWithArg */
-
-#define MAX_BLOCK_CYPHER_SIZE 32
-
-#define TEST_FOR_FAILURE /* reminder */
-#define SET_ERROR_CODE /* reminder */
-
-/* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock.
- *
- * Currently, the list of functions called through ss->handshake is:
- *
- * In sslsocks.c:
- * SocksGatherRecord
- * SocksHandleReply
- * SocksStartGather
- *
- * In sslcon.c:
- * ssl_GatherRecord1stHandshake
- * ssl2_HandleClientSessionKeyMessage
- * ssl2_HandleMessage
- * ssl2_HandleVerifyMessage
- * ssl2_BeginClientHandshake
- * ssl2_BeginServerHandshake
- * ssl2_HandleClientHelloMessage
- * ssl2_HandleServerHelloMessage
- *
- * The ss->handshake function returns SECWouldBlock under these conditions:
- * 1. ssl_GatherRecord1stHandshake called ssl2_GatherData which read in
- * the beginning of an SSL v3 hello message and returned SECWouldBlock
- * to switch to SSL v3 handshake processing.
- *
- * 2. ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming
- * v2 client hello msg, and called ssl3_HandleV2ClientHello which
- * returned SECWouldBlock.
- *
- * 3. SECWouldBlock was returned by one of the callback functions, via
- * one of these paths:
- * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() ->
- * ss->getClientAuthData()
- *
- * - ssl2_HandleServerHelloMessage() -> ss->handleBadCert()
- *
- * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
- * ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
- * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() ->
- * ss->handleBadCert()
- *
- * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() ->
- * ssl3_HandleRecord() -> ssl3_HandleHandshake() ->
- * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() ->
- * ss->getClientAuthData()
- *
- * Called from: SSL_ForceHandshake (below),
- * ssl_SecureRecv (below) and
- * ssl_SecureSend (below)
- * from: WaitForResponse in sslsocks.c
- * ssl_SocksRecv in sslsocks.c
- * ssl_SocksSend in sslsocks.c
- *
- * Caller must hold the (write) handshakeLock.
- */
-int
-ssl_Do1stHandshake(sslSocket *ss)
-{
- int rv = SECSuccess;
- int loopCount = 0;
-
- do {
- PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
- PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
- PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
- PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss));
-
- if (ss->handshake == 0) {
- /* Previous handshake finished. Switch to next one */
- ss->handshake = ss->nextHandshake;
- ss->nextHandshake = 0;
- }
- if (ss->handshake == 0) {
- /* Previous handshake finished. Switch to security handshake */
- ss->handshake = ss->securityHandshake;
- ss->securityHandshake = 0;
- }
- if (ss->handshake == 0) {
- ssl_GetRecvBufLock(ss);
- ss->gs.recordLen = 0;
- ssl_ReleaseRecvBufLock(ss);
-
- SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",
- SSL_GETPID(), ss->fd));
- /* call handshake callback for ssl v2 */
- /* for v3 this is done in ssl3_HandleFinished() */
- if ((ss->handshakeCallback != NULL) && /* has callback */
- (!ss->firstHsDone) && /* only first time */
- (ss->version < SSL_LIBRARY_VERSION_3_0)) { /* not ssl3 */
- ss->firstHsDone = PR_TRUE;
- (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
- }
- ss->firstHsDone = PR_TRUE;
- ss->gs.writeOffset = 0;
- ss->gs.readOffset = 0;
- break;
- }
- rv = (*ss->handshake)(ss);
- ++loopCount;
- /* This code must continue to loop on SECWouldBlock,
- * or any positive value. See XXX_1 comments.
- */
- } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */
-
- PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
- PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
- PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss));
-
- if (rv == SECWouldBlock) {
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- rv = SECFailure;
- }
- return rv;
-}
-
-/*
- * Handshake function that blocks. Used to force a
- * retry on a connection on the next read/write.
- */
-static SECStatus
-ssl3_AlwaysBlock(sslSocket *ss)
-{
- PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */
- return SECWouldBlock;
-}
-
-/*
- * set the initial handshake state machine to block
- */
-void
-ssl3_SetAlwaysBlock(sslSocket *ss)
-{
- if (!ss->firstHsDone) {
- ss->handshake = ssl3_AlwaysBlock;
- ss->nextHandshake = 0;
- }
-}
-
-static SECStatus
-ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd));
- return SECFailure;
- }
- SSL_LOCK_READER(ss);
- ss->rTimeout = timeout;
- if (ss->opt.fdx) {
- SSL_LOCK_WRITER(ss);
- }
- ss->wTimeout = timeout;
- if (ss->opt.fdx) {
- SSL_UNLOCK_WRITER(ss);
- }
- SSL_UNLOCK_READER(ss);
- return SECSuccess;
-}
-
-/* Acquires and releases HandshakeLock.
-*/
-SECStatus
-SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
-{
- sslSocket *ss;
- SECStatus status;
- PRNetAddr addr;
-
- ss = ssl_FindSocket(s);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s));
- return SECFailure;
- }
-
- /* Don't waste my time */
- if (!ss->opt.useSecurity)
- return SECSuccess;
-
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- /* Reset handshake state */
- ssl_Get1stHandshakeLock(ss);
-
- ss->firstHsDone = PR_FALSE;
- if ( asServer ) {
- ss->handshake = ssl2_BeginServerHandshake;
- ss->handshaking = sslHandshakingAsServer;
- } else {
- ss->handshake = ssl2_BeginClientHandshake;
- ss->handshaking = sslHandshakingAsClient;
- }
- ss->nextHandshake = 0;
- ss->securityHandshake = 0;
-
- ssl_GetRecvBufLock(ss);
- status = ssl_InitGather(&ss->gs);
- ssl_ReleaseRecvBufLock(ss);
-
- ssl_GetSSL3HandshakeLock(ss);
-
- /*
- ** Blow away old security state and get a fresh setup.
- */
- ssl_GetXmitBufLock(ss);
- ssl_ResetSecurityInfo(&ss->sec, PR_TRUE);
- status = ssl_CreateSecurityInfo(ss);
- ssl_ReleaseXmitBufLock(ss);
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- if (!ss->TCPconnected)
- ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
-
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss);
-
- return status;
-}
-
-/* For SSLv2, does nothing but return an error.
-** For SSLv3, flushes SID cache entry (if requested),
-** and then starts new client hello or hello request.
-** Acquires and releases HandshakeLock.
-*/
-SECStatus
-SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache)
-{
- sslSocket *ss;
- SECStatus rv;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (!ss->opt.useSecurity)
- return SECSuccess;
-
- ssl_Get1stHandshakeLock(ss);
-
- /* SSL v2 protocol does not support subsequent handshakes. */
- if (ss->version < SSL_LIBRARY_VERSION_3_0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- } else {
- ssl_GetSSL3HandshakeLock(ss);
- rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
- ssl_ReleaseSSL3HandshakeLock(ss);
- }
-
- ssl_Release1stHandshakeLock(ss);
-
- return rv;
-}
-
-/*
-** Same as above, but with an I/O timeout.
- */
-SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
- PRBool flushCache,
- PRIntervalTime timeout)
-{
- if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
- return SECFailure;
- }
- return SSL_ReHandshake(fd, flushCache);
-}
-
-SECStatus
-SSL_RedoHandshake(PRFileDesc *fd)
-{
- return SSL_ReHandshake(fd, PR_TRUE);
-}
-
-/* Register an application callback to be called when SSL handshake completes.
-** Acquires and releases HandshakeLock.
-*/
-SECStatus
-SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb,
- void *client_data)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (!ss->opt.useSecurity) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- ss->handshakeCallback = cb;
- ss->handshakeCallbackData = client_data;
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return SECSuccess;
-}
-
-/* Try to make progress on an SSL handshake by attempting to read the
-** next handshake from the peer, and sending any responses.
-** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot
-** read the next handshake from the underlying socket.
-** For SSLv2, returns when handshake is complete or fatal error occurs.
-** For SSLv3, returns when handshake is complete, or application data has
-** arrived that must be taken by application before handshake can continue,
-** or a fatal error occurs.
-** Application should use handshake completion callback to tell which.
-*/
-SECStatus
-SSL_ForceHandshake(PRFileDesc *fd)
-{
- sslSocket *ss;
- SECStatus rv = SECFailure;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake",
- SSL_GETPID(), fd));
- return rv;
- }
-
- /* Don't waste my time */
- if (!ss->opt.useSecurity)
- return SECSuccess;
-
- if (!ssl_SocketIsBlocking(ss)) {
- ssl_GetXmitBufLock(ss);
- if (ss->pendingBuf.len != 0) {
- int sent = ssl_SendSavedWriteData(ss);
- if ((sent < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) {
- ssl_ReleaseXmitBufLock(ss);
- return SECFailure;
- }
- }
- ssl_ReleaseXmitBufLock(ss);
- }
-
- ssl_Get1stHandshakeLock(ss);
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- int gatherResult;
-
- ssl_GetRecvBufLock(ss);
- gatherResult = ssl3_GatherCompleteHandshake(ss, 0);
- ssl_ReleaseRecvBufLock(ss);
- if (gatherResult > 0) {
- rv = SECSuccess;
- } else if (gatherResult == 0) {
- PORT_SetError(PR_END_OF_FILE_ERROR);
- } else if (gatherResult == SECWouldBlock) {
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- }
- } else if (!ss->firstHsDone) {
- rv = ssl_Do1stHandshake(ss);
- } else {
- /* tried to force handshake on an SSL 2 socket that has
- ** already completed the handshake. */
- rv = SECSuccess; /* just pretend we did it. */
- }
-
- ssl_Release1stHandshakeLock(ss);
-
- return rv;
-}
-
-/*
- ** Same as above, but with an I/O timeout.
- */
-SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
- PRIntervalTime timeout)
-{
- if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
- return SECFailure;
- }
- return SSL_ForceHandshake(fd);
-}
-
-
-/************************************************************************/
-
-/*
-** Grow a buffer to hold newLen bytes of data.
-** Called for both recv buffers and xmit buffers.
-** Caller must hold xmitBufLock or recvBufLock, as appropriate.
-*/
-SECStatus
-sslBuffer_Grow(sslBuffer *b, unsigned int newLen)
-{
- newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048);
- if (newLen > b->space) {
- unsigned char *newBuf;
- if (b->buf) {
- newBuf = (unsigned char *) PORT_Realloc(b->buf, newLen);
- } else {
- newBuf = (unsigned char *) PORT_Alloc(newLen);
- }
- if (!newBuf) {
- return SECFailure;
- }
- SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d",
- SSL_GETPID(), b->space, newLen));
- b->buf = newBuf;
- b->space = newLen;
- }
- return SECSuccess;
-}
-
-SECStatus
-sslBuffer_Append(sslBuffer *b, const void * data, unsigned int len)
-{
- unsigned int newLen = b->len + len;
- SECStatus rv;
-
- rv = sslBuffer_Grow(b, newLen);
- if (rv != SECSuccess)
- return rv;
- PORT_Memcpy(b->buf + b->len, data, len);
- b->len += len;
- return SECSuccess;
-}
-
-/*
-** Save away write data that is trying to be written before the security
-** handshake has been completed. When the handshake is completed, we will
-** flush this data out.
-** Caller must hold xmitBufLock
-*/
-SECStatus
-ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len)
-{
- SECStatus rv;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
- rv = sslBuffer_Append(&ss->pendingBuf, data, len);
- SSL_TRC(5, ("%d: SSL[%d]: saving %u bytes of data (%u total saved so far)",
- SSL_GETPID(), ss->fd, len, ss->pendingBuf.len));
- return rv;
-}
-
-/*
-** Send saved write data. This will flush out data sent prior to a
-** complete security handshake. Hopefully there won't be too much of it.
-** Returns count of the bytes sent, NOT a SECStatus.
-** Caller must hold xmitBufLock
-*/
-int
-ssl_SendSavedWriteData(sslSocket *ss)
-{
- int rv = 0;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
- if (ss->pendingBuf.len != 0) {
- SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data",
- SSL_GETPID(), ss->fd, ss->pendingBuf.len));
- rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0);
- if (rv < 0) {
- return rv;
- }
- ss->pendingBuf.len -= rv;
- if (ss->pendingBuf.len > 0 && rv > 0) {
- /* UGH !! This shifts the whole buffer down by copying it */
- PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv,
- ss->pendingBuf.len);
- }
- }
- return rv;
-}
-
-/************************************************************************/
-
-/*
-** Receive some application data on a socket. Reads SSL records from the input
-** stream, decrypts them and then copies them to the output buffer.
-** Called from ssl_SecureRecv() below.
-**
-** Caller does NOT hold 1stHandshakeLock because that handshake is over.
-** Caller doesn't call this until initial handshake is complete.
-** For SSLv2, there is no subsequent handshake.
-** For SSLv3, the call to ssl3_GatherAppDataRecord may encounter handshake
-** messages from a subsequent handshake.
-**
-** This code is similar to, and easily confused with,
-** ssl_GatherRecord1stHandshake() in sslcon.c
-*/
-static int
-DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
-{
- int rv;
- int amount;
- int available;
-
- ssl_GetRecvBufLock(ss);
-
- available = ss->gs.writeOffset - ss->gs.readOffset;
- if (available == 0) {
- /* Get some more data */
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- /* Wait for application data to arrive. */
- rv = ssl3_GatherAppDataRecord(ss, 0);
- } else {
- /* See if we have a complete record */
- rv = ssl2_GatherRecord(ss, 0);
- }
- if (rv <= 0) {
- if (rv == 0) {
- /* EOF */
- SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF",
- SSL_GETPID(), ss->fd));
- goto done;
- }
- if ((rv != SECWouldBlock) &&
- (PR_GetError() != PR_WOULD_BLOCK_ERROR)) {
- /* Some random error */
- goto done;
- }
-
- /*
- ** Gather record is blocked waiting for more record data to
- ** arrive. Try to process what we have already received
- */
- } else {
- /* Gather record has finished getting a complete record */
- }
-
- /* See if any clear data is now available */
- available = ss->gs.writeOffset - ss->gs.readOffset;
- if (available == 0) {
- /*
- ** No partial data is available. Force error code to
- ** EWOULDBLOCK so that caller will try again later. Note
- ** that the error code is probably EWOULDBLOCK already,
- ** but if it isn't (for example, if we received a zero
- ** length record) then this will force it to be correct.
- */
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- rv = SECFailure;
- goto done;
- }
- SSL_TRC(30, ("%d: SSL[%d]: partial data ready, available=%d",
- SSL_GETPID(), ss->fd, available));
- }
-
- /* Dole out clear data to reader */
- amount = PR_MIN(len, available);
- PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount);
- if (!(flags & PR_MSG_PEEK)) {
- ss->gs.readOffset += amount;
- }
- PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset);
- rv = amount;
-
- SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d",
- SSL_GETPID(), ss->fd, amount, available));
- PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount));
-
-done:
- ssl_ReleaseRecvBufLock(ss);
- return rv;
-}
-
-/************************************************************************/
-
-/*
-** Return SSLKEAType derived from cert's Public Key algorithm info.
-*/
-SSLKEAType
-NSS_FindCertKEAType(CERTCertificate * cert)
-{
- SSLKEAType keaType = kt_null;
- int tag;
-
- if (!cert) goto loser;
-
- tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
-
- switch (tag) {
- case SEC_OID_X500_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- keaType = kt_rsa;
- break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- keaType = kt_dh;
- break;
-#ifdef NSS_ENABLE_ECC
- case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
- keaType = kt_ecdh;
- break;
-#endif /* NSS_ENABLE_ECC */
- default:
- keaType = kt_null;
- }
-
- loser:
-
- return keaType;
-}
-
-static const PRCallOnceType pristineCallOnce;
-static PRCallOnceType setupServerCAListOnce;
-
-static SECStatus serverCAListShutdown(void* appData, void* nssData)
-{
- PORT_Assert(ssl3_server_ca_list);
- if (ssl3_server_ca_list) {
- CERT_FreeDistNames(ssl3_server_ca_list);
- ssl3_server_ca_list = NULL;
- }
- setupServerCAListOnce = pristineCallOnce;
- return SECSuccess;
-}
-
-static PRStatus serverCAListSetup(void *arg)
-{
- CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg;
- SECStatus rv = NSS_RegisterShutdown(serverCAListShutdown, NULL);
- PORT_Assert(SECSuccess == rv);
- if (SECSuccess == rv) {
- ssl3_server_ca_list = CERT_GetSSLCACerts(dbHandle);
- return PR_SUCCESS;
- }
- return PR_FAILURE;
-}
-
-SECStatus
-ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert,
- const CERTCertificateList *certChain,
- ssl3KeyPair *keyPair, SSLKEAType kea)
-{
- CERTCertificateList *localCertChain = NULL;
- sslServerCerts *sc = ss->serverCerts + kea;
-
- /* load the server certificate */
- if (sc->serverCert != NULL) {
- CERT_DestroyCertificate(sc->serverCert);
- sc->serverCert = NULL;
- sc->serverKeyBits = 0;
- }
- /* load the server cert chain */
- if (sc->serverCertChain != NULL) {
- CERT_DestroyCertificateList(sc->serverCertChain);
- sc->serverCertChain = NULL;
- }
- if (cert) {
- sc->serverCert = CERT_DupCertificate(cert);
- /* get the size of the cert's public key, and remember it */
- sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey);
- if (!certChain) {
- localCertChain =
- CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer,
- PR_TRUE);
- if (!localCertChain)
- goto loser;
- }
- sc->serverCertChain = (certChain) ? CERT_DupCertList(certChain) :
- localCertChain;
- if (!sc->serverCertChain) {
- goto loser;
- }
- localCertChain = NULL; /* consumed */
- }
-
- /* get keyPair */
- if (sc->serverKeyPair != NULL) {
- ssl3_FreeKeyPair(sc->serverKeyPair);
- sc->serverKeyPair = NULL;
- }
- if (keyPair) {
- SECKEY_CacheStaticFlags(keyPair->privKey);
- sc->serverKeyPair = ssl3_GetKeyPairRef(keyPair);
- }
- if (kea == kt_rsa && cert && sc->serverKeyBits > 512 &&
- !ss->opt.noStepDown && !ss->stepDownKeyPair) {
- if (ssl3_CreateRSAStepDownKeys(ss) != SECSuccess) {
- goto loser;
- }
- }
- return SECSuccess;
-
-loser:
- if (localCertChain) {
- CERT_DestroyCertificateList(localCertChain);
- }
- if (sc->serverCert != NULL) {
- CERT_DestroyCertificate(sc->serverCert);
- sc->serverCert = NULL;
- }
- if (sc->serverCertChain != NULL) {
- CERT_DestroyCertificateList(sc->serverCertChain);
- sc->serverCertChain = NULL;
- }
- if (sc->serverKeyPair != NULL) {
- ssl3_FreeKeyPair(sc->serverKeyPair);
- sc->serverKeyPair = NULL;
- }
- return SECFailure;
-}
-
-/* XXX need to protect the data that gets changed here.!! */
-
-SECStatus
-SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert,
- SECKEYPrivateKey *key, SSL3KEAType kea)
-{
-
- return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea);
-}
-
-SECStatus
-SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
- const CERTCertificateList *certChainOpt,
- SECKEYPrivateKey *key, SSL3KEAType kea)
-{
- sslSocket *ss;
- SECKEYPublicKey *pubKey = NULL;
- ssl3KeyPair *keyPair = NULL;
- SECStatus rv = SECFailure;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- return SECFailure;
- }
-
- /* Both key and cert must have a value or be NULL */
- /* Passing a value of NULL will turn off key exchange algorithms that were
- * previously turned on */
- if (!cert != !key) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* make sure the key exchange is recognized */
- if ((kea >= kt_kea_size) || (kea < kt_null)) {
- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
- return SECFailure;
- }
-
- if (kea != NSS_FindCertKEAType(cert)) {
- PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH);
- return SECFailure;
- }
-
- if (cert) {
- /* get the size of the cert's public key, and remember it */
- pubKey = CERT_ExtractPublicKey(cert);
- if (!pubKey)
- return SECFailure;
- }
-
- if (key) {
- SECKEYPrivateKey * keyCopy = NULL;
- CK_MECHANISM_TYPE keyMech = CKM_INVALID_MECHANISM;
-
- if (key->pkcs11Slot) {
- PK11SlotInfo * bestSlot;
- bestSlot = PK11_ReferenceSlot(key->pkcs11Slot);
- if (bestSlot) {
- keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
- PK11_FreeSlot(bestSlot);
- }
- }
- if (keyCopy == NULL)
- keyMech = PK11_MapSignKeyType(key->keyType);
- if (keyMech != CKM_INVALID_MECHANISM) {
- PK11SlotInfo * bestSlot;
- /* XXX Maybe should be bestSlotMultiple? */
- bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */);
- if (bestSlot) {
- keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
- PK11_FreeSlot(bestSlot);
- }
- }
- if (keyCopy == NULL)
- keyCopy = SECKEY_CopyPrivateKey(key);
- if (keyCopy == NULL)
- goto loser;
- keyPair = ssl3_NewKeyPair(keyCopy, pubKey);
- if (keyPair == NULL) {
- SECKEY_DestroyPrivateKey(keyCopy);
- goto loser;
- }
- pubKey = NULL; /* adopted by serverKeyPair */
- }
- if (ssl_ConfigSecureServer(ss, cert, certChainOpt,
- keyPair, kea) == SECFailure) {
- goto loser;
- }
-
- /* Only do this once because it's global. */
- if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce,
- &serverCAListSetup,
- (void *)(ss->dbHandle))) {
- rv = SECSuccess;
- }
-
-loser:
- if (keyPair) {
- ssl3_FreeKeyPair(keyPair);
- }
- if (pubKey) {
- SECKEY_DestroyPublicKey(pubKey);
- pubKey = NULL;
- }
- return rv;
-}
-
-/************************************************************************/
-
-SECStatus
-ssl_CreateSecurityInfo(sslSocket *ss)
-{
- SECStatus status;
-
- /* initialize sslv2 socket to send data in the clear. */
- ssl2_UseClearSendFunc(ss);
-
- ss->sec.blockSize = 1;
- ss->sec.blockShift = 0;
-
- ssl_GetXmitBufLock(ss);
- status = sslBuffer_Grow(&ss->sec.writeBuf, 4096);
- ssl_ReleaseXmitBufLock(ss);
-
- return status;
-}
-
-SECStatus
-ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os)
-{
- ss->sec.send = os->sec.send;
- ss->sec.isServer = os->sec.isServer;
- ss->sec.keyBits = os->sec.keyBits;
- ss->sec.secretKeyBits = os->sec.secretKeyBits;
-
- ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert);
- if (os->sec.peerCert && !ss->sec.peerCert)
- goto loser;
-
- ss->sec.cache = os->sec.cache;
- ss->sec.uncache = os->sec.uncache;
-
- /* we don't dup the connection info. */
-
- ss->sec.sendSequence = os->sec.sendSequence;
- ss->sec.rcvSequence = os->sec.rcvSequence;
-
- if (os->sec.hash && os->sec.hashcx) {
- ss->sec.hash = os->sec.hash;
- ss->sec.hashcx = os->sec.hash->clone(os->sec.hashcx);
- if (os->sec.hashcx && !ss->sec.hashcx)
- goto loser;
- } else {
- ss->sec.hash = NULL;
- ss->sec.hashcx = NULL;
- }
-
- SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret);
- if (os->sec.sendSecret.data && !ss->sec.sendSecret.data)
- goto loser;
- SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret);
- if (os->sec.rcvSecret.data && !ss->sec.rcvSecret.data)
- goto loser;
-
- /* XXX following code is wrong if either cx != 0 */
- PORT_Assert(os->sec.readcx == 0);
- PORT_Assert(os->sec.writecx == 0);
- ss->sec.readcx = os->sec.readcx;
- ss->sec.writecx = os->sec.writecx;
- ss->sec.destroy = 0;
-
- ss->sec.enc = os->sec.enc;
- ss->sec.dec = os->sec.dec;
-
- ss->sec.blockShift = os->sec.blockShift;
- ss->sec.blockSize = os->sec.blockSize;
-
- return SECSuccess;
-
-loser:
- return SECFailure;
-}
-
-/* Reset sec back to its initial state.
-** Caller holds any relevant locks.
-*/
-void
-ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset)
-{
- /* Destroy MAC */
- if (sec->hash && sec->hashcx) {
- (*sec->hash->destroy)(sec->hashcx, PR_TRUE);
- sec->hashcx = NULL;
- sec->hash = NULL;
- }
- SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE);
- SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE);
-
- /* Destroy ciphers */
- if (sec->destroy) {
- (*sec->destroy)(sec->readcx, PR_TRUE);
- (*sec->destroy)(sec->writecx, PR_TRUE);
- sec->readcx = NULL;
- sec->writecx = NULL;
- } else {
- PORT_Assert(sec->readcx == 0);
- PORT_Assert(sec->writecx == 0);
- }
- sec->readcx = 0;
- sec->writecx = 0;
-
- if (sec->localCert) {
- CERT_DestroyCertificate(sec->localCert);
- sec->localCert = NULL;
- }
- if (sec->peerCert) {
- CERT_DestroyCertificate(sec->peerCert);
- sec->peerCert = NULL;
- }
- if (sec->peerKey) {
- SECKEY_DestroyPublicKey(sec->peerKey);
- sec->peerKey = NULL;
- }
-
- /* cleanup the ci */
- if (sec->ci.sid != NULL) {
- ssl_FreeSID(sec->ci.sid);
- }
- PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space);
- if (doMemset) {
- memset(&sec->ci, 0, sizeof sec->ci);
- }
-
-}
-
-/*
-** Called from SSL_ResetHandshake (above), and
-** from ssl_FreeSocket in sslsock.c
-** Caller should hold relevant locks (e.g. XmitBufLock)
-*/
-void
-ssl_DestroySecurityInfo(sslSecurityInfo *sec)
-{
- ssl_ResetSecurityInfo(sec, PR_FALSE);
-
- PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space);
- sec->writeBuf.buf = 0;
-
- memset(sec, 0, sizeof *sec);
-}
-
-/************************************************************************/
-
-int
-ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa)
-{
- PRFileDesc *osfd = ss->fd->lower;
- int rv;
-
- if ( ss->opt.handshakeAsServer ) {
- ss->securityHandshake = ssl2_BeginServerHandshake;
- ss->handshaking = sslHandshakingAsServer;
- } else {
- ss->securityHandshake = ssl2_BeginClientHandshake;
- ss->handshaking = sslHandshakingAsClient;
- }
-
- /* connect to server */
- rv = osfd->methods->connect(osfd, sa, ss->cTimeout);
- if (rv == PR_SUCCESS) {
- ss->TCPconnected = 1;
- } else {
- int err = PR_GetError();
- SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d",
- SSL_GETPID(), ss->fd, err));
- if (err == PR_IS_CONNECTED_ERROR) {
- ss->TCPconnected = 1;
- }
- }
-
- SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d",
- SSL_GETPID(), ss->fd, rv));
- return rv;
-}
-
-/*
- * The TLS 1.2 RFC 5246, Section 7.2.1 says:
- *
- * Unless some other fatal alert has been transmitted, each party is
- * required to send a close_notify alert before closing the write side
- * of the connection. The other party MUST respond with a close_notify
- * alert of its own and close down the connection immediately,
- * discarding any pending writes. It is not required for the initiator
- * of the close to wait for the responding close_notify alert before
- * closing the read side of the connection.
- *
- * The second sentence requires that we send a close_notify alert when we
- * have received a close_notify alert. In practice, all SSL implementations
- * close the socket immediately after sending a close_notify alert (which is
- * allowed by the third sentence), so responding with a close_notify alert
- * would result in a write failure with the ECONNRESET error. This is why
- * we don't respond with a close_notify alert.
- *
- * Also, in the unlikely event that the TCP pipe is full and the peer stops
- * reading, the SSL3_SendAlert call in ssl_SecureClose and ssl_SecureShutdown
- * may block indefinitely in blocking mode, and may fail (without retrying)
- * in non-blocking mode.
- */
-
-int
-ssl_SecureClose(sslSocket *ss)
-{
- int rv;
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
- !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
- ss->firstHsDone &&
- !ss->recvdCloseNotify &&
- ss->ssl3.initialized) {
-
- /* We don't want the final alert to be Nagle delayed. */
- if (!ss->delayDisabled) {
- ssl_EnableNagleDelay(ss, PR_FALSE);
- ss->delayDisabled = 1;
- }
-
- (void) SSL3_SendAlert(ss, alert_warning, close_notify);
- }
- rv = ssl_DefClose(ss);
- return rv;
-}
-
-/* Caller handles all locking */
-int
-ssl_SecureShutdown(sslSocket *ss, int nsprHow)
-{
- PRFileDesc *osfd = ss->fd->lower;
- int rv;
- PRIntn sslHow = nsprHow + 1;
-
- if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return PR_FAILURE;
- }
-
- if ((sslHow & ssl_SHUTDOWN_SEND) != 0 &&
- ss->version >= SSL_LIBRARY_VERSION_3_0 &&
- !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
- ss->firstHsDone &&
- !ss->recvdCloseNotify &&
- ss->ssl3.initialized) {
-
- (void) SSL3_SendAlert(ss, alert_warning, close_notify);
- }
-
- rv = osfd->methods->shutdown(osfd, nsprHow);
-
- ss->shutdownHow |= sslHow;
-
- return rv;
-}
-
-/************************************************************************/
-
-
-int
-ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
-{
- sslSecurityInfo *sec;
- int rv = 0;
-
- sec = &ss->sec;
-
- if (ss->shutdownHow & ssl_SHUTDOWN_RCV) {
- PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
- return PR_FAILURE;
- }
- if (flags & ~PR_MSG_PEEK) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- return PR_FAILURE;
- }
-
- if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) {
- ssl_GetXmitBufLock(ss);
- if (ss->pendingBuf.len != 0) {
- rv = ssl_SendSavedWriteData(ss);
- if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) {
- ssl_ReleaseXmitBufLock(ss);
- return SECFailure;
- }
- }
- ssl_ReleaseXmitBufLock(ss);
- }
-
- rv = 0;
- /* If any of these is non-zero, the initial handshake is not done. */
- if (!ss->firstHsDone) {
- ssl_Get1stHandshakeLock(ss);
- if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
- rv = ssl_Do1stHandshake(ss);
- }
- ssl_Release1stHandshakeLock(ss);
- }
- if (rv < 0) {
- return rv;
- }
-
- if (len == 0) return 0;
-
- rv = DoRecv(ss, (unsigned char*) buf, len, flags);
- SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)",
- SSL_GETPID(), ss->fd, rv, PORT_GetError()));
- return rv;
-}
-
-int
-ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len)
-{
- return ssl_SecureRecv(ss, buf, len, 0);
-}
-
-/* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */
-int
-ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
-{
- int rv = 0;
-
- SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
- SSL_GETPID(), ss->fd, len));
-
- if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
- PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
- rv = PR_FAILURE;
- goto done;
- }
- if (flags) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- rv = PR_FAILURE;
- goto done;
- }
-
- ssl_GetXmitBufLock(ss);
- if (ss->pendingBuf.len != 0) {
- PORT_Assert(ss->pendingBuf.len > 0);
- rv = ssl_SendSavedWriteData(ss);
- if (rv >= 0 && ss->pendingBuf.len != 0) {
- PORT_Assert(ss->pendingBuf.len > 0);
- PORT_SetError(PR_WOULD_BLOCK_ERROR);
- rv = SECFailure;
- }
- }
- ssl_ReleaseXmitBufLock(ss);
- if (rv < 0) {
- goto done;
- }
-
- if (len > 0)
- ss->writerThread = PR_GetCurrentThread();
- /* If any of these is non-zero, the initial handshake is not done. */
- if (!ss->firstHsDone) {
- PRBool canFalseStart = PR_FALSE;
- ssl_Get1stHandshakeLock(ss);
- if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
- ssl_GetSSL3HandshakeLock(ss);
- if ((ss->ssl3.hs.ws == wait_change_cipher ||
- ss->ssl3.hs.ws == wait_finished ||
- ss->ssl3.hs.ws == wait_new_session_ticket) &&
- ssl3_CanFalseStart(ss)) {
- canFalseStart = PR_TRUE;
- }
- ssl_ReleaseSSL3HandshakeLock(ss);
- }
- if (!canFalseStart &&
- (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
- rv = ssl_Do1stHandshake(ss);
- }
- ssl_Release1stHandshakeLock(ss);
- }
- if (rv < 0) {
- ss->writerThread = NULL;
- goto done;
- }
-
- /* Check for zero length writes after we do housekeeping so we make forward
- * progress.
- */
- if (len == 0) {
- rv = 0;
- goto done;
- }
- PORT_Assert(buf != NULL);
- if (!buf) {
- PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
- rv = PR_FAILURE;
- goto done;
- }
-
- /* Send out the data using one of these functions:
- * ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock,
- * ssl3_SendApplicationData
- */
- ssl_GetXmitBufLock(ss);
- rv = (*ss->sec.send)(ss, buf, len, flags);
- ssl_ReleaseXmitBufLock(ss);
- ss->writerThread = NULL;
-done:
- if (rv < 0) {
- SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d",
- SSL_GETPID(), ss->fd, rv, PORT_GetError()));
- } else {
- SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count",
- SSL_GETPID(), ss->fd, rv));
- }
- return rv;
-}
-
-int
-ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len)
-{
- return ssl_SecureSend(ss, buf, len, 0);
-}
-
-SECStatus
-SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- ss->handleBadCert = f;
- ss->badCertArg = arg;
-
- return SECSuccess;
-}
-
-/*
- * Allow the application to pass the url or hostname into the SSL library
- * so that we can do some checking on it. It will be used for the value in
- * SNI extension of client hello message.
- */
-SECStatus
-SSL_SetURL(PRFileDesc *fd, const char *url)
-{
- sslSocket * ss = ssl_FindSocket(fd);
- SECStatus rv = SECSuccess;
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL",
- SSL_GETPID(), fd));
- return SECFailure;
- }
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- if ( ss->url ) {
- PORT_Free((void *)ss->url); /* CONST */
- }
-
- ss->url = (const char *)PORT_Strdup(url);
- if ( ss->url == NULL ) {
- rv = SECFailure;
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return rv;
-}
-
-/*
- * Allow the application to pass the set of trust anchors
- */
-SECStatus
-SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList)
-{
- sslSocket * ss = ssl_FindSocket(fd);
- CERTDistNames *names = NULL;
-
- if (!certList) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- names = CERT_DistNamesFromCertList(certList);
- if (names == NULL) {
- return SECFailure;
- }
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
- if (ss->ssl3.ca_list) {
- CERT_FreeDistNames(ss->ssl3.ca_list);
- }
- ss->ssl3.ca_list = names;
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return SECSuccess;
-}
-
-/*
-** Returns Negative number on error, zero or greater on success.
-** Returns the amount of data immediately available to be read.
-*/
-int
-SSL_DataPending(PRFileDesc *fd)
-{
- sslSocket *ss;
- int rv = 0;
-
- ss = ssl_FindSocket(fd);
-
- if (ss && ss->opt.useSecurity) {
- ssl_GetRecvBufLock(ss);
- rv = ss->gs.writeOffset - ss->gs.readOffset;
- ssl_ReleaseRecvBufLock(ss);
- }
-
- return rv;
-}
-
-SECStatus
-SSL_InvalidateSession(PRFileDesc *fd)
-{
- sslSocket * ss = ssl_FindSocket(fd);
- SECStatus rv = SECFailure;
-
- if (ss) {
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- if (ss->sec.ci.sid && ss->sec.uncache) {
- ss->sec.uncache(ss->sec.ci.sid);
- rv = SECSuccess;
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
- }
- return rv;
-}
-
-SECItem *
-SSL_GetSessionID(PRFileDesc *fd)
-{
- sslSocket * ss;
- SECItem * item = NULL;
-
- ss = ssl_FindSocket(fd);
- if (ss) {
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) {
- item = (SECItem *)PORT_Alloc(sizeof(SECItem));
- if (item) {
- sslSessionID * sid = ss->sec.ci.sid;
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- item->len = SSL2_SESSIONID_BYTES;
- item->data = (unsigned char*)PORT_Alloc(item->len);
- PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len);
- } else {
- item->len = sid->u.ssl3.sessionIDLength;
- item->data = (unsigned char*)PORT_Alloc(item->len);
- PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len);
- }
- }
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
- }
- return item;
-}
-
-SECStatus
-SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle)
-{
- sslSocket * ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss)
- return SECFailure;
- if (!dbHandle) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- ss->dbHandle = dbHandle;
- return SECSuccess;
-}
-
-/* DO NOT USE. This function was exported in ssl.def with the wrong signature;
- * this implementation exists to maintain link-time compatibility.
- */
-int
-SSL_RestartHandshakeAfterCertReq(sslSocket * ss,
- CERTCertificate * cert,
- SECKEYPrivateKey * key,
- CERTCertificateList *certChain)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return -1;
-}
-
-/* DO NOT USE. This function was exported in ssl.def with the wrong signature;
- * this implementation exists to maintain link-time compatibility.
- */
-int
-SSL_RestartHandshakeAfterServerCert(sslSocket * ss)
-{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return -1;
-}
-
-/* See documentation in ssl.h */
-SECStatus
-SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error)
-{
- SECStatus rv;
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- ssl_Get1stHandshakeLock(ss);
-
- if (!ss->ssl3.initialized) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- } else if (ss->version < SSL_LIBRARY_VERSION_3_0) {
- PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
- rv = SECFailure;
- } else {
- rv = ssl3_AuthCertificateComplete(ss, error);
- }
-
- ssl_Release1stHandshakeLock(ss);
-
- return rv;
-}
-
-/* For more info see ssl.h */
-SECStatus
-SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func,
- void *arg)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- ss->sniSocketConfig = func;
- ss->sniSocketConfigArg = arg;
- return SECSuccess;
-}
diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c
deleted file mode 100644
index 46e944cb1..000000000
--- a/security/nss/lib/ssl/sslsnce.c
+++ /dev/null
@@ -1,2214 +0,0 @@
-/* This file implements the SERVER Session ID cache.
- * NOTE: The contents of this file are NOT used by the client.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server
- * cache sids!
- *
- * About record locking among different server processes:
- *
- * All processes that are part of the same conceptual server (serving on
- * the same address and port) MUST share a common SSL session cache.
- * This code makes the content of the shared cache accessible to all
- * processes on the same "server". This code works on Unix and Win32 only.
- *
- * We use NSPR anonymous shared memory and move data to & from shared memory.
- * We must do explicit locking of the records for all reads and writes.
- * The set of Cache entries are divided up into "sets" of 128 entries.
- * Each set is protected by a lock. There may be one or more sets protected
- * by each lock. That is, locks to sets are 1:N.
- * There is one lock for the entire cert cache.
- * There is one lock for the set of wrapped sym wrap keys.
- *
- * The anonymous shared memory is laid out as if it were declared like this:
- *
- * struct {
- * cacheDescriptor desc;
- * sidCacheLock sidCacheLocks[ numSIDCacheLocks];
- * sidCacheLock keyCacheLock;
- * sidCacheLock certCacheLock;
- * sidCacheSet sidCacheSets[ numSIDCacheSets ];
- * sidCacheEntry sidCacheData[ numSIDCacheEntries];
- * certCacheEntry certCacheData[numCertCacheEntries];
- * SSLWrappedSymWrappingKey keyCacheData[kt_kea_size][SSL_NUM_WRAP_MECHS];
- * uint8 keyNameSuffix[SESS_TICKET_KEY_VAR_NAME_LEN]
- * encKeyCacheEntry ticketEncKey; // Wrapped in non-bypass mode
- * encKeyCacheEntry ticketMacKey; // Wrapped in non-bypass mode
- * PRBool ticketKeysValid;
- * sidCacheLock srvNameCacheLock;
- * srvNameCacheEntry srvNameData[ numSrvNameCacheEntries ];
- * } cacheMemCacheData;
- */
-#include "seccomon.h"
-
-#if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)
-
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "pk11func.h"
-#include "base64.h"
-#include "keyhi.h"
-#ifdef NO_PKCS11_BYPASS
-#include "blapit.h"
-#include "sechash.h"
-#else
-#include "blapi.h"
-#endif
-
-#include <stdio.h>
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
-
-#include <syslog.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include "unix_err.h"
-
-#else
-
-#ifdef XP_WIN32
-#include <wtypes.h>
-#include "win32err.h"
-#endif
-
-#endif
-#include <sys/types.h>
-
-#define SET_ERROR_CODE /* reminder */
-
-#include "nspr.h"
-#include "sslmutex.h"
-
-/*
-** Format of a cache entry in the shared memory.
-*/
-struct sidCacheEntryStr {
-/* 16 */ PRIPv6Addr addr; /* client's IP address */
-/* 4 */ PRUint32 creationTime;
-/* 4 */ PRUint32 lastAccessTime;
-/* 4 */ PRUint32 expirationTime;
-/* 2 */ PRUint16 version;
-/* 1 */ PRUint8 valid;
-/* 1 */ PRUint8 sessionIDLength;
-/* 32 */ PRUint8 sessionID[SSL3_SESSIONID_BYTES];
-/* 2 */ PRUint16 authAlgorithm;
-/* 2 */ PRUint16 authKeyBits;
-/* 2 */ PRUint16 keaType;
-/* 2 */ PRUint16 keaKeyBits;
-/* 72 - common header total */
-
- union {
- struct {
-/* 64 */ PRUint8 masterKey[SSL_MAX_MASTER_KEY_BYTES];
-/* 32 */ PRUint8 cipherArg[SSL_MAX_CYPHER_ARG_BYTES];
-
-/* 1 */ PRUint8 cipherType;
-/* 1 */ PRUint8 masterKeyLen;
-/* 1 */ PRUint8 keyBits;
-/* 1 */ PRUint8 secretKeyBits;
-/* 1 */ PRUint8 cipherArgLen;
-/*101 */} ssl2;
-
- struct {
-/* 2 */ ssl3CipherSuite cipherSuite;
-/* 2 */ PRUint16 compression; /* SSLCompressionMethod */
-
-/* 52 */ ssl3SidKeys keys; /* keys, wrapped as needed. */
-
-/* 4 */ PRUint32 masterWrapMech;
-/* 4 */ SSL3KEAType exchKeyType;
-/* 4 */ PRInt32 certIndex;
-/* 4 */ PRInt32 srvNameIndex;
-/* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */
-/*104 */} ssl3;
-/* force sizeof(sidCacheEntry) to be a multiple of cache line size */
- struct {
-/*120 */ PRUint8 filler[120]; /* 72+120==192, a multiple of 16 */
- } forceSize;
- } u;
-};
-typedef struct sidCacheEntryStr sidCacheEntry;
-
-/* The length of this struct is supposed to be a power of 2, e.g. 4KB */
-struct certCacheEntryStr {
- PRUint16 certLength; /* 2 */
- PRUint16 sessionIDLength; /* 2 */
- PRUint8 sessionID[SSL3_SESSIONID_BYTES]; /* 32 */
- PRUint8 cert[SSL_MAX_CACHED_CERT_LEN]; /* 4060 */
-}; /* total 4096 */
-typedef struct certCacheEntryStr certCacheEntry;
-
-struct sidCacheLockStr {
- PRUint32 timeStamp;
- sslMutex mutex;
- sslPID pid;
-};
-typedef struct sidCacheLockStr sidCacheLock;
-
-struct sidCacheSetStr {
- PRIntn next;
-};
-typedef struct sidCacheSetStr sidCacheSet;
-
-struct encKeyCacheEntryStr {
- PRUint8 bytes[512];
- PRInt32 length;
-};
-typedef struct encKeyCacheEntryStr encKeyCacheEntry;
-
-#define SSL_MAX_DNS_HOST_NAME 1024
-
-struct srvNameCacheEntryStr {
- PRUint16 type; /* 2 */
- PRUint16 nameLen; /* 2 */
- PRUint8 name[SSL_MAX_DNS_HOST_NAME + 12]; /* 1034 */
- PRUint8 nameHash[SHA256_LENGTH]; /* 32 */
- /* 1072 */
-};
-typedef struct srvNameCacheEntryStr srvNameCacheEntry;
-
-
-struct cacheDescStr {
-
- PRUint32 cacheMemSize;
-
- PRUint32 numSIDCacheLocks;
- PRUint32 numSIDCacheSets;
- PRUint32 numSIDCacheSetsPerLock;
-
- PRUint32 numSIDCacheEntries;
- PRUint32 sidCacheSize;
-
- PRUint32 numCertCacheEntries;
- PRUint32 certCacheSize;
-
- PRUint32 numKeyCacheEntries;
- PRUint32 keyCacheSize;
-
- PRUint32 numSrvNameCacheEntries;
- PRUint32 srvNameCacheSize;
-
- PRUint32 ssl2Timeout;
- PRUint32 ssl3Timeout;
-
- PRUint32 numSIDCacheLocksInitialized;
-
- /* These values are volatile, and are accessed through sharedCache-> */
- PRUint32 nextCertCacheEntry; /* certCacheLock protects */
- PRBool stopPolling;
- PRBool everInherited;
-
- /* The private copies of these values are pointers into shared mem */
- /* The copies of these values in shared memory are merely offsets */
- sidCacheLock * sidCacheLocks;
- sidCacheLock * keyCacheLock;
- sidCacheLock * certCacheLock;
- sidCacheLock * srvNameCacheLock;
- sidCacheSet * sidCacheSets;
- sidCacheEntry * sidCacheData;
- certCacheEntry * certCacheData;
- SSLWrappedSymWrappingKey * keyCacheData;
- uint8 * ticketKeyNameSuffix;
- encKeyCacheEntry * ticketEncKey;
- encKeyCacheEntry * ticketMacKey;
- PRUint32 * ticketKeysValid;
- srvNameCacheEntry * srvNameCacheData;
-
- /* Only the private copies of these pointers are valid */
- char * cacheMem;
- struct cacheDescStr * sharedCache; /* shared copy of this struct */
- PRFileMap * cacheMemMap;
- PRThread * poller;
- PRUint32 mutexTimeout;
- PRBool shared;
-};
-typedef struct cacheDescStr cacheDesc;
-
-static cacheDesc globalCache;
-
-static const char envVarName[] = { SSL_ENV_VAR_NAME };
-
-static PRBool isMultiProcess = PR_FALSE;
-
-
-#define DEF_SID_CACHE_ENTRIES 10000
-#define DEF_CERT_CACHE_ENTRIES 250
-#define MIN_CERT_CACHE_ENTRIES 125 /* the effective size in old releases. */
-#define DEF_KEY_CACHE_ENTRIES 250
-#define DEF_NAME_CACHE_ENTRIES 1000
-
-#define SID_CACHE_ENTRIES_PER_SET 128
-#define SID_ALIGNMENT 16
-
-#define DEF_SSL2_TIMEOUT 100 /* seconds */
-#define MAX_SSL2_TIMEOUT 100 /* seconds */
-#define MIN_SSL2_TIMEOUT 5 /* seconds */
-
-#define DEF_SSL3_TIMEOUT 86400L /* 24 hours */
-#define MAX_SSL3_TIMEOUT 86400L /* 24 hours */
-#define MIN_SSL3_TIMEOUT 5 /* seconds */
-
-#if defined(AIX) || defined(LINUX) || defined(NETBSD) || defined(OPENBSD)
-#define MAX_SID_CACHE_LOCKS 8 /* two FDs per lock */
-#elif defined(OSF1)
-#define MAX_SID_CACHE_LOCKS 16 /* one FD per lock */
-#else
-#define MAX_SID_CACHE_LOCKS 256
-#endif
-
-#define SID_HOWMANY(val, size) (((val) + ((size) - 1)) / (size))
-#define SID_ROUNDUP(val, size) ((size) * SID_HOWMANY((val), (size)))
-
-
-static sslPID myPid;
-static PRUint32 ssl_max_sid_cache_locks = MAX_SID_CACHE_LOCKS;
-
-/* forward static function declarations */
-static PRUint32 SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s,
- unsigned nl);
-static SECStatus LaunchLockPoller(cacheDesc *cache);
-static SECStatus StopLockPoller(cacheDesc *cache);
-
-
-struct inheritanceStr {
- PRUint32 cacheMemSize;
- PRUint32 fmStrLen;
-};
-
-typedef struct inheritanceStr inheritance;
-
-#if defined(_WIN32) || defined(XP_OS2)
-
-#define DEFAULT_CACHE_DIRECTORY "\\temp"
-
-#endif /* _win32 */
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
-
-#define DEFAULT_CACHE_DIRECTORY "/tmp"
-
-#endif /* XP_UNIX || XP_BEOS */
-
-
-/************************************************************************/
-
-static PRUint32
-LockSidCacheLock(sidCacheLock *lock, PRUint32 now)
-{
- SECStatus rv = sslMutex_Lock(&lock->mutex);
- if (rv != SECSuccess)
- return 0;
- if (!now)
- now = ssl_Time();
- lock->timeStamp = now;
- lock->pid = myPid;
- return now;
-}
-
-static SECStatus
-UnlockSidCacheLock(sidCacheLock *lock)
-{
- SECStatus rv;
-
- lock->pid = 0;
- rv = sslMutex_Unlock(&lock->mutex);
- return rv;
-}
-
-/* returns the value of ssl_Time on success, zero on failure. */
-static PRUint32
-LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now)
-{
- PRUint32 lockNum = set % cache->numSIDCacheLocks;
- sidCacheLock * lock = cache->sidCacheLocks + lockNum;
-
- return LockSidCacheLock(lock, now);
-}
-
-static SECStatus
-UnlockSet(cacheDesc *cache, PRUint32 set)
-{
- PRUint32 lockNum = set % cache->numSIDCacheLocks;
- sidCacheLock * lock = cache->sidCacheLocks + lockNum;
-
- return UnlockSidCacheLock(lock);
-}
-
-/************************************************************************/
-
-
-/* Put a certificate in the cache. Update the cert index in the sce.
-*/
-static PRUint32
-CacheCert(cacheDesc * cache, CERTCertificate *cert, sidCacheEntry *sce)
-{
- PRUint32 now;
- certCacheEntry cce;
-
- if ((cert->derCert.len > SSL_MAX_CACHED_CERT_LEN) ||
- (cert->derCert.len <= 0) ||
- (cert->derCert.data == NULL)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return 0;
- }
-
- cce.sessionIDLength = sce->sessionIDLength;
- PORT_Memcpy(cce.sessionID, sce->sessionID, cce.sessionIDLength);
-
- cce.certLength = cert->derCert.len;
- PORT_Memcpy(cce.cert, cert->derCert.data, cce.certLength);
-
- /* get lock on cert cache */
- now = LockSidCacheLock(cache->certCacheLock, 0);
- if (now) {
-
- /* Find where to place the next cert cache entry. */
- cacheDesc * sharedCache = cache->sharedCache;
- PRUint32 ndx = sharedCache->nextCertCacheEntry;
-
- /* write the entry */
- cache->certCacheData[ndx] = cce;
-
- /* remember where we put it. */
- sce->u.ssl3.certIndex = ndx;
-
- /* update the "next" cache entry index */
- sharedCache->nextCertCacheEntry =
- (ndx + 1) % cache->numCertCacheEntries;
-
- UnlockSidCacheLock(cache->certCacheLock);
- }
- return now;
-
-}
-
-/* Server configuration hash tables need to account the SECITEM.type
- * field as well. These functions accomplish that. */
-static PLHashNumber
-Get32BitNameHash(const SECItem *name)
-{
- PLHashNumber rv = SECITEM_Hash(name);
-
- PRUint8 *rvc = (PRUint8 *)&rv;
- rvc[ name->len % sizeof(rv) ] ^= name->type;
-
- return rv;
-}
-
-/* Put a name in the cache. Update the cert index in the sce.
-*/
-static PRUint32
-CacheSrvName(cacheDesc * cache, SECItem *name, sidCacheEntry *sce)
-{
- PRUint32 now;
- PRUint32 ndx;
- srvNameCacheEntry snce;
-
- if (!name || name->len <= 0 ||
- name->len > SSL_MAX_DNS_HOST_NAME) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return 0;
- }
-
- snce.type = name->type;
- snce.nameLen = name->len;
- PORT_Memcpy(snce.name, name->data, snce.nameLen);
-#ifdef NO_PKCS11_BYPASS
- HASH_HashBuf(HASH_AlgSHA256, snce.nameHash, name->data, name->len);
-#else
- SHA256_HashBuf(snce.nameHash, (unsigned char*)name->data,
- name->len);
-#endif
- /* get index of the next name */
- ndx = Get32BitNameHash(name);
- /* get lock on cert cache */
- now = LockSidCacheLock(cache->srvNameCacheLock, 0);
- if (now) {
- if (cache->numSrvNameCacheEntries > 0) {
- /* Fit the index into array */
- ndx %= cache->numSrvNameCacheEntries;
- /* write the entry */
- cache->srvNameCacheData[ndx] = snce;
- /* remember where we put it. */
- sce->u.ssl3.srvNameIndex = ndx;
- /* Copy hash into sid hash */
- PORT_Memcpy(sce->u.ssl3.srvNameHash, snce.nameHash, SHA256_LENGTH);
- }
- UnlockSidCacheLock(cache->srvNameCacheLock);
- }
- return now;
-}
-
-/*
-** Convert local SID to shared memory one
-*/
-static void
-ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
-{
- to->valid = 1;
- to->version = from->version;
- to->addr = from->addr;
- to->creationTime = from->creationTime;
- to->lastAccessTime = from->lastAccessTime;
- to->expirationTime = from->expirationTime;
- to->authAlgorithm = from->authAlgorithm;
- to->authKeyBits = from->authKeyBits;
- to->keaType = from->keaType;
- to->keaKeyBits = from->keaKeyBits;
-
- if (from->version < SSL_LIBRARY_VERSION_3_0) {
- if ((from->u.ssl2.masterKey.len > SSL_MAX_MASTER_KEY_BYTES) ||
- (from->u.ssl2.cipherArg.len > SSL_MAX_CYPHER_ARG_BYTES)) {
- SSL_DBG(("%d: SSL: masterKeyLen=%d cipherArgLen=%d",
- myPid, from->u.ssl2.masterKey.len,
- from->u.ssl2.cipherArg.len));
- to->valid = 0;
- return;
- }
-
- to->u.ssl2.cipherType = from->u.ssl2.cipherType;
- to->u.ssl2.masterKeyLen = from->u.ssl2.masterKey.len;
- to->u.ssl2.cipherArgLen = from->u.ssl2.cipherArg.len;
- to->u.ssl2.keyBits = from->u.ssl2.keyBits;
- to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
- to->sessionIDLength = SSL2_SESSIONID_BYTES;
- PORT_Memcpy(to->sessionID, from->u.ssl2.sessionID, SSL2_SESSIONID_BYTES);
- PORT_Memcpy(to->u.ssl2.masterKey, from->u.ssl2.masterKey.data,
- from->u.ssl2.masterKey.len);
- PORT_Memcpy(to->u.ssl2.cipherArg, from->u.ssl2.cipherArg.data,
- from->u.ssl2.cipherArg.len);
-#ifdef DEBUG
- PORT_Memset(to->u.ssl2.masterKey+from->u.ssl2.masterKey.len, 0,
- sizeof(to->u.ssl2.masterKey) - from->u.ssl2.masterKey.len);
- PORT_Memset(to->u.ssl2.cipherArg+from->u.ssl2.cipherArg.len, 0,
- sizeof(to->u.ssl2.cipherArg) - from->u.ssl2.cipherArg.len);
-#endif
- SSL_TRC(8, ("%d: SSL: ConvertSID: masterKeyLen=%d cipherArgLen=%d "
- "time=%d addr=0x%08x%08x%08x%08x cipherType=%d", myPid,
- to->u.ssl2.masterKeyLen, to->u.ssl2.cipherArgLen,
- to->creationTime, to->addr.pr_s6_addr32[0],
- to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2],
- to->addr.pr_s6_addr32[3], to->u.ssl2.cipherType));
- } else {
- /* This is an SSL v3 session */
-
- to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
- to->u.ssl3.compression = (uint16)from->u.ssl3.compression;
- to->u.ssl3.keys = from->u.ssl3.keys;
- to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
- to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
- to->sessionIDLength = from->u.ssl3.sessionIDLength;
- to->u.ssl3.certIndex = -1;
- to->u.ssl3.srvNameIndex = -1;
-
- PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID,
- to->sessionIDLength);
-
- SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x "
- "cipherSuite=%d",
- myPid, to->creationTime, to->addr.pr_s6_addr32[0],
- to->addr.pr_s6_addr32[1], to->addr.pr_s6_addr32[2],
- to->addr.pr_s6_addr32[3], to->u.ssl3.cipherSuite));
- }
-}
-
-/*
-** Convert shared memory cache-entry to local memory based one
-** This is only called from ServerSessionIDLookup().
-** Caller must hold cache lock when calling this.
-*/
-static sslSessionID *
-ConvertToSID(sidCacheEntry * from,
- certCacheEntry * pcce,
- srvNameCacheEntry *psnce,
- CERTCertDBHandle * dbHandle)
-{
- sslSessionID *to;
- uint16 version = from->version;
-
- to = PORT_ZNew(sslSessionID);
- if (!to) {
- return 0;
- }
-
- if (version < SSL_LIBRARY_VERSION_3_0) {
- /* This is an SSL v2 session */
- to->u.ssl2.masterKey.data =
- (unsigned char*) PORT_Alloc(from->u.ssl2.masterKeyLen);
- if (!to->u.ssl2.masterKey.data) {
- goto loser;
- }
- if (from->u.ssl2.cipherArgLen) {
- to->u.ssl2.cipherArg.data =
- (unsigned char*)PORT_Alloc(from->u.ssl2.cipherArgLen);
- if (!to->u.ssl2.cipherArg.data) {
- goto loser;
- }
- PORT_Memcpy(to->u.ssl2.cipherArg.data, from->u.ssl2.cipherArg,
- from->u.ssl2.cipherArgLen);
- }
-
- to->u.ssl2.cipherType = from->u.ssl2.cipherType;
- to->u.ssl2.masterKey.len = from->u.ssl2.masterKeyLen;
- to->u.ssl2.cipherArg.len = from->u.ssl2.cipherArgLen;
- to->u.ssl2.keyBits = from->u.ssl2.keyBits;
- to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
-/* to->sessionIDLength = SSL2_SESSIONID_BYTES; */
- PORT_Memcpy(to->u.ssl2.sessionID, from->sessionID, SSL2_SESSIONID_BYTES);
- PORT_Memcpy(to->u.ssl2.masterKey.data, from->u.ssl2.masterKey,
- from->u.ssl2.masterKeyLen);
-
- SSL_TRC(8, ("%d: SSL: ConvertToSID: masterKeyLen=%d cipherArgLen=%d "
- "time=%d addr=0x%08x%08x%08x%08x cipherType=%d",
- myPid, to->u.ssl2.masterKey.len,
- to->u.ssl2.cipherArg.len, to->creationTime,
- to->addr.pr_s6_addr32[0], to->addr.pr_s6_addr32[1],
- to->addr.pr_s6_addr32[2], to->addr.pr_s6_addr32[3],
- to->u.ssl2.cipherType));
- } else {
- /* This is an SSL v3 session */
-
- to->u.ssl3.sessionIDLength = from->sessionIDLength;
- to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
- to->u.ssl3.compression = (SSLCompressionMethod)from->u.ssl3.compression;
- to->u.ssl3.keys = from->u.ssl3.keys;
- to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
- to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
- if (from->u.ssl3.srvNameIndex != -1 && psnce) {
- SECItem name;
- SECStatus rv;
- name.type = psnce->type;
- name.len = psnce->nameLen;
- name.data = psnce->name;
- rv = SECITEM_CopyItem(NULL, &to->u.ssl3.srvName, &name);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
-
- PORT_Memcpy(to->u.ssl3.sessionID, from->sessionID, from->sessionIDLength);
-
- /* the portions of the SID that are only restored on the client
- * are set to invalid values on the server.
- */
- to->u.ssl3.clientWriteKey = NULL;
- to->u.ssl3.serverWriteKey = NULL;
-
- to->urlSvrName = NULL;
-
- to->u.ssl3.masterModuleID = (SECMODModuleID)-1; /* invalid value */
- to->u.ssl3.masterSlotID = (CK_SLOT_ID)-1; /* invalid value */
- to->u.ssl3.masterWrapIndex = 0;
- to->u.ssl3.masterWrapSeries = 0;
- to->u.ssl3.masterValid = PR_FALSE;
-
- to->u.ssl3.clAuthModuleID = (SECMODModuleID)-1; /* invalid value */
- to->u.ssl3.clAuthSlotID = (CK_SLOT_ID)-1; /* invalid value */
- to->u.ssl3.clAuthSeries = 0;
- to->u.ssl3.clAuthValid = PR_FALSE;
-
- if (from->u.ssl3.certIndex != -1 && pcce) {
- SECItem derCert;
-
- derCert.len = pcce->certLength;
- derCert.data = pcce->cert;
-
- to->peerCert = CERT_NewTempCertificate(dbHandle, &derCert, NULL,
- PR_FALSE, PR_TRUE);
- if (to->peerCert == NULL)
- goto loser;
- }
- }
-
- to->version = from->version;
- to->creationTime = from->creationTime;
- to->lastAccessTime = from->lastAccessTime;
- to->expirationTime = from->expirationTime;
- to->cached = in_server_cache;
- to->addr = from->addr;
- to->references = 1;
- to->authAlgorithm = from->authAlgorithm;
- to->authKeyBits = from->authKeyBits;
- to->keaType = from->keaType;
- to->keaKeyBits = from->keaKeyBits;
-
- return to;
-
- loser:
- if (to) {
- if (version < SSL_LIBRARY_VERSION_3_0) {
- if (to->u.ssl2.masterKey.data)
- PORT_Free(to->u.ssl2.masterKey.data);
- if (to->u.ssl2.cipherArg.data)
- PORT_Free(to->u.ssl2.cipherArg.data);
- } else {
- SECITEM_FreeItem(&to->u.ssl3.srvName, PR_FALSE);
- }
- PORT_Free(to);
- }
- return NULL;
-}
-
-
-
-/*
-** Perform some mumbo jumbo on the ip-address and the session-id value to
-** compute a hash value.
-*/
-static PRUint32
-SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl)
-{
- PRUint32 rv;
- PRUint32 x[8];
-
- memset(x, 0, sizeof x);
- if (nl > sizeof x)
- nl = sizeof x;
- memcpy(x, s, nl);
-
- rv = (addr->pr_s6_addr32[0] ^ addr->pr_s6_addr32[1] ^
- addr->pr_s6_addr32[2] ^ addr->pr_s6_addr32[3] ^
- x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7])
- % cache->numSIDCacheSets;
- return rv;
-}
-
-
-
-/*
-** Look something up in the cache. This will invalidate old entries
-** in the process. Caller has locked the cache set!
-** Returns PR_TRUE if found a valid match. PR_FALSE otherwise.
-*/
-static sidCacheEntry *
-FindSID(cacheDesc *cache, PRUint32 setNum, PRUint32 now,
- const PRIPv6Addr *addr, unsigned char *sessionID,
- unsigned sessionIDLength)
-{
- PRUint32 ndx = cache->sidCacheSets[setNum].next;
- int i;
-
- sidCacheEntry * set = cache->sidCacheData +
- (setNum * SID_CACHE_ENTRIES_PER_SET);
-
- for (i = SID_CACHE_ENTRIES_PER_SET; i > 0; --i) {
- sidCacheEntry * sce;
-
- ndx = (ndx - 1) % SID_CACHE_ENTRIES_PER_SET;
- sce = set + ndx;
-
- if (!sce->valid)
- continue;
-
- if (now > sce->expirationTime) {
- /* SessionID has timed out. Invalidate the entry. */
- SSL_TRC(7, ("%d: timed out sid entry addr=%08x%08x%08x%08x now=%x "
- "time+=%x",
- myPid, sce->addr.pr_s6_addr32[0],
- sce->addr.pr_s6_addr32[1], sce->addr.pr_s6_addr32[2],
- sce->addr.pr_s6_addr32[3], now,
- sce->expirationTime ));
- sce->valid = 0;
- continue;
- }
-
- /*
- ** Next, examine specific session-id/addr data to see if the cache
- ** entry matches our addr+session-id value
- */
- if (sessionIDLength == sce->sessionIDLength &&
- !memcmp(&sce->addr, addr, sizeof(PRIPv6Addr)) &&
- !memcmp(sce->sessionID, sessionID, sessionIDLength)) {
- /* Found it */
- return sce;
- }
- }
-
- PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND);
- return NULL;
-}
-
-/************************************************************************/
-
-/* This is the primary function for finding entries in the server's sid cache.
- * Although it is static, this function is called via the global function
- * pointer ssl_sid_lookup.
- */
-static sslSessionID *
-ServerSessionIDLookup(const PRIPv6Addr *addr,
- unsigned char *sessionID,
- unsigned int sessionIDLength,
- CERTCertDBHandle * dbHandle)
-{
- sslSessionID * sid = 0;
- sidCacheEntry * psce;
- certCacheEntry *pcce = 0;
- srvNameCacheEntry *psnce = 0;
- cacheDesc * cache = &globalCache;
- PRUint32 now;
- PRUint32 set;
- PRInt32 cndx;
- sidCacheEntry sce;
- certCacheEntry cce;
- srvNameCacheEntry snce;
-
- set = SIDindex(cache, addr, sessionID, sessionIDLength);
- now = LockSet(cache, set, 0);
- if (!now)
- return NULL;
-
- psce = FindSID(cache, set, now, addr, sessionID, sessionIDLength);
- if (psce) {
- if (psce->version >= SSL_LIBRARY_VERSION_3_0) {
- if ((cndx = psce->u.ssl3.certIndex) != -1) {
-
- PRUint32 gotLock = LockSidCacheLock(cache->certCacheLock, now);
- if (gotLock) {
- pcce = &cache->certCacheData[cndx];
-
- /* See if the cert's session ID matches the sce cache. */
- if ((pcce->sessionIDLength == psce->sessionIDLength) &&
- !PORT_Memcmp(pcce->sessionID, psce->sessionID,
- pcce->sessionIDLength)) {
- cce = *pcce;
- } else {
- /* The cert doesen't match the SID cache entry,
- ** so invalidate the SID cache entry.
- */
- psce->valid = 0;
- psce = 0;
- pcce = 0;
- }
- UnlockSidCacheLock(cache->certCacheLock);
- } else {
- /* what the ??. Didn't get the cert cache lock.
- ** Don't invalidate the SID cache entry, but don't find it.
- */
- PORT_Assert(!("Didn't get cert Cache Lock!"));
- psce = 0;
- pcce = 0;
- }
- }
- if (psce && ((cndx = psce->u.ssl3.srvNameIndex) != -1)) {
- PRUint32 gotLock = LockSidCacheLock(cache->srvNameCacheLock,
- now);
- if (gotLock) {
- psnce = &cache->srvNameCacheData[cndx];
-
- if (!PORT_Memcmp(psnce->nameHash, psce->u.ssl3.srvNameHash,
- SHA256_LENGTH)) {
- snce = *psnce;
- } else {
- /* The name doesen't match the SID cache entry,
- ** so invalidate the SID cache entry.
- */
- psce->valid = 0;
- psce = 0;
- psnce = 0;
- }
- UnlockSidCacheLock(cache->srvNameCacheLock);
- } else {
- /* what the ??. Didn't get the cert cache lock.
- ** Don't invalidate the SID cache entry, but don't find it.
- */
- PORT_Assert(!("Didn't get name Cache Lock!"));
- psce = 0;
- psnce = 0;
- }
-
- }
- }
- if (psce) {
- psce->lastAccessTime = now;
- sce = *psce; /* grab a copy while holding the lock */
- }
- }
- UnlockSet(cache, set);
- if (psce) {
- /* sce conains a copy of the cache entry.
- ** Convert shared memory format to local format
- */
- sid = ConvertToSID(&sce, pcce ? &cce : 0, psnce ? &snce : 0, dbHandle);
- }
- return sid;
-}
-
-/*
-** Place a sid into the cache, if it isn't already there.
-*/
-static void
-ServerSessionIDCache(sslSessionID *sid)
-{
- sidCacheEntry sce;
- PRUint32 now = 0;
- uint16 version = sid->version;
- cacheDesc * cache = &globalCache;
-
- if ((version >= SSL_LIBRARY_VERSION_3_0) &&
- (sid->u.ssl3.sessionIDLength == 0)) {
- return;
- }
-
- if (sid->cached == never_cached || sid->cached == invalid_cache) {
- PRUint32 set;
-
- PORT_Assert(sid->creationTime != 0);
- if (!sid->creationTime)
- sid->lastAccessTime = sid->creationTime = ssl_Time();
- if (version < SSL_LIBRARY_VERSION_3_0) {
- /* override caller's expiration time, which uses client timeout
- * duration, not server timeout duration.
- */
- sid->expirationTime = sid->creationTime + cache->ssl2Timeout;
- SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x "
- "cipher=%d", myPid, sid->cached,
- sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
- sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
- sid->creationTime, sid->u.ssl2.cipherType));
- PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID,
- SSL2_SESSIONID_BYTES));
- PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
- sid->u.ssl2.masterKey.len));
- PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
- sid->u.ssl2.cipherArg.len));
-
- } else {
- /* override caller's expiration time, which uses client timeout
- * duration, not server timeout duration.
- */
- sid->expirationTime = sid->creationTime + cache->ssl3Timeout;
- SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x "
- "cipherSuite=%d", myPid, sid->cached,
- sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
- sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
- sid->creationTime, sid->u.ssl3.cipherSuite));
- PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID,
- sid->u.ssl3.sessionIDLength));
- }
-
- ConvertFromSID(&sce, sid);
-
- if (version >= SSL_LIBRARY_VERSION_3_0) {
- SECItem *name = &sid->u.ssl3.srvName;
- if (name->len && name->data) {
- now = CacheSrvName(cache, name, &sce);
- }
- if (sid->peerCert != NULL) {
- now = CacheCert(cache, sid->peerCert, &sce);
- }
- }
-
- set = SIDindex(cache, &sce.addr, sce.sessionID, sce.sessionIDLength);
- now = LockSet(cache, set, now);
- if (now) {
- PRUint32 next = cache->sidCacheSets[set].next;
- PRUint32 ndx = set * SID_CACHE_ENTRIES_PER_SET + next;
-
- /* Write out new cache entry */
- cache->sidCacheData[ndx] = sce;
-
- cache->sidCacheSets[set].next =
- (next + 1) % SID_CACHE_ENTRIES_PER_SET;
-
- UnlockSet(cache, set);
- sid->cached = in_server_cache;
- }
- }
-}
-
-/*
-** Although this is static, it is called from ssl via global function pointer
-** ssl_sid_uncache. This invalidates the referenced cache entry.
-*/
-static void
-ServerSessionIDUncache(sslSessionID *sid)
-{
- cacheDesc * cache = &globalCache;
- PRUint8 * sessionID;
- unsigned int sessionIDLength;
- PRErrorCode err;
- PRUint32 set;
- PRUint32 now;
- sidCacheEntry *psce;
-
- if (sid == NULL)
- return;
-
- /* Uncaching a SID should never change the error code.
- ** So save it here and restore it before exiting.
- */
- err = PR_GetError();
-
- if (sid->version < SSL_LIBRARY_VERSION_3_0) {
- sessionID = sid->u.ssl2.sessionID;
- sessionIDLength = SSL2_SESSIONID_BYTES;
- SSL_TRC(8, ("%d: SSL: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x "
- "cipher=%d", myPid, sid->cached,
- sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
- sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
- sid->creationTime, sid->u.ssl2.cipherType));
- PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength));
- PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
- sid->u.ssl2.masterKey.len));
- PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
- sid->u.ssl2.cipherArg.len));
- } else {
- sessionID = sid->u.ssl3.sessionID;
- sessionIDLength = sid->u.ssl3.sessionIDLength;
- SSL_TRC(8, ("%d: SSL3: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x "
- "cipherSuite=%d", myPid, sid->cached,
- sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1],
- sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3],
- sid->creationTime, sid->u.ssl3.cipherSuite));
- PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength));
- }
- set = SIDindex(cache, &sid->addr, sessionID, sessionIDLength);
- now = LockSet(cache, set, 0);
- if (now) {
- psce = FindSID(cache, set, now, &sid->addr, sessionID, sessionIDLength);
- if (psce) {
- psce->valid = 0;
- }
- UnlockSet(cache, set);
- }
- sid->cached = invalid_cache;
- PORT_SetError(err);
-}
-
-#ifdef XP_OS2
-
-#define INCL_DOSPROCESS
-#include <os2.h>
-
-long gettid(void)
-{
- PTIB ptib;
- PPIB ppib;
- DosGetInfoBlocks(&ptib, &ppib);
- return ((long)ptib->tib_ordinal); /* thread id */
-}
-#endif
-
-static void
-CloseCache(cacheDesc *cache)
-{
- int locks_initialized = cache->numSIDCacheLocksInitialized;
-
- if (cache->cacheMem) {
- if (cache->sharedCache) {
- sidCacheLock *pLock = cache->sidCacheLocks;
- for (; locks_initialized > 0; --locks_initialized, ++pLock ) {
- /* If everInherited is true, this shared cache was (and may
- ** still be) in use by multiple processes. We do not wish to
- ** destroy the mutexes while they are still in use, but we do
- ** want to free mutex resources associated with this process.
- */
- sslMutex_Destroy(&pLock->mutex,
- cache->sharedCache->everInherited);
- }
- }
- if (cache->shared) {
- PR_MemUnmap(cache->cacheMem, cache->cacheMemSize);
- } else {
- PORT_Free(cache->cacheMem);
- }
- cache->cacheMem = NULL;
- }
- if (cache->cacheMemMap) {
- PR_CloseFileMap(cache->cacheMemMap);
- cache->cacheMemMap = NULL;
- }
- memset(cache, 0, sizeof *cache);
-}
-
-static SECStatus
-InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
- int maxSrvNameCacheEntries, PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout, const char *directory, PRBool shared)
-{
- ptrdiff_t ptr;
- sidCacheLock *pLock;
- char * cacheMem;
- PRFileMap * cacheMemMap;
- char * cfn = NULL; /* cache file name */
- int locks_initialized = 0;
- int locks_to_initialize = 0;
- PRUint32 init_time;
-
- if ( (!cache) || (maxCacheEntries < 0) || (!directory) ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (cache->cacheMem) {
- /* Already done */
- return SECSuccess;
- }
-
- /* make sure loser can clean up properly */
- cache->shared = shared;
- cache->cacheMem = cacheMem = NULL;
- cache->cacheMemMap = cacheMemMap = NULL;
- cache->sharedCache = (cacheDesc *)0;
-
- cache->numSIDCacheLocksInitialized = 0;
- cache->nextCertCacheEntry = 0;
- cache->stopPolling = PR_FALSE;
- cache->everInherited = PR_FALSE;
- cache->poller = NULL;
- cache->mutexTimeout = 0;
-
- cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries
- : DEF_SID_CACHE_ENTRIES;
- cache->numSIDCacheSets =
- SID_HOWMANY(cache->numSIDCacheEntries, SID_CACHE_ENTRIES_PER_SET);
-
- cache->numSIDCacheEntries =
- cache->numSIDCacheSets * SID_CACHE_ENTRIES_PER_SET;
-
- cache->numSIDCacheLocks =
- PR_MIN(cache->numSIDCacheSets, ssl_max_sid_cache_locks);
-
- cache->numSIDCacheSetsPerLock =
- SID_HOWMANY(cache->numSIDCacheSets, cache->numSIDCacheLocks);
-
- cache->numCertCacheEntries = (maxCertCacheEntries > 0) ?
- maxCertCacheEntries : 0;
- cache->numSrvNameCacheEntries = (maxSrvNameCacheEntries >= 0) ?
- maxSrvNameCacheEntries : DEF_NAME_CACHE_ENTRIES;
-
- /* compute size of shared memory, and offsets of all pointers */
- ptr = 0;
- cache->cacheMem = (char *)ptr;
- ptr += SID_ROUNDUP(sizeof(cacheDesc), SID_ALIGNMENT);
-
- cache->sidCacheLocks = (sidCacheLock *)ptr;
- cache->keyCacheLock = cache->sidCacheLocks + cache->numSIDCacheLocks;
- cache->certCacheLock = cache->keyCacheLock + 1;
- cache->srvNameCacheLock = cache->certCacheLock + 1;
- ptr = (ptrdiff_t)(cache->srvNameCacheLock + 1);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->sidCacheSets = (sidCacheSet *)ptr;
- ptr = (ptrdiff_t)(cache->sidCacheSets + cache->numSIDCacheSets);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->sidCacheData = (sidCacheEntry *)ptr;
- ptr = (ptrdiff_t)(cache->sidCacheData + cache->numSIDCacheEntries);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->certCacheData = (certCacheEntry *)ptr;
- cache->sidCacheSize =
- (char *)cache->certCacheData - (char *)cache->sidCacheData;
-
- if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES) {
- /* This is really a poor way to computer this! */
- cache->numCertCacheEntries = cache->sidCacheSize / sizeof(certCacheEntry);
- if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES)
- cache->numCertCacheEntries = MIN_CERT_CACHE_ENTRIES;
- }
- ptr = (ptrdiff_t)(cache->certCacheData + cache->numCertCacheEntries);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->keyCacheData = (SSLWrappedSymWrappingKey *)ptr;
- cache->certCacheSize =
- (char *)cache->keyCacheData - (char *)cache->certCacheData;
-
- cache->numKeyCacheEntries = kt_kea_size * SSL_NUM_WRAP_MECHS;
- ptr = (ptrdiff_t)(cache->keyCacheData + cache->numKeyCacheEntries);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->keyCacheSize = (char *)ptr - (char *)cache->keyCacheData;
-
- cache->ticketKeyNameSuffix = (uint8 *)ptr;
- ptr = (ptrdiff_t)(cache->ticketKeyNameSuffix +
- SESS_TICKET_KEY_VAR_NAME_LEN);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->ticketEncKey = (encKeyCacheEntry *)ptr;
- ptr = (ptrdiff_t)(cache->ticketEncKey + 1);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->ticketMacKey = (encKeyCacheEntry *)ptr;
- ptr = (ptrdiff_t)(cache->ticketMacKey + 1);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->ticketKeysValid = (PRUint32 *)ptr;
- ptr = (ptrdiff_t)(cache->ticketKeysValid + 1);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->srvNameCacheData = (srvNameCacheEntry *)ptr;
- cache->srvNameCacheSize =
- cache->numSrvNameCacheEntries * sizeof(srvNameCacheEntry);
- ptr = (ptrdiff_t)(cache->srvNameCacheData + cache->numSrvNameCacheEntries);
- ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
-
- cache->cacheMemSize = ptr;
-
- if (ssl2_timeout) {
- if (ssl2_timeout > MAX_SSL2_TIMEOUT) {
- ssl2_timeout = MAX_SSL2_TIMEOUT;
- }
- if (ssl2_timeout < MIN_SSL2_TIMEOUT) {
- ssl2_timeout = MIN_SSL2_TIMEOUT;
- }
- cache->ssl2Timeout = ssl2_timeout;
- } else {
- cache->ssl2Timeout = DEF_SSL2_TIMEOUT;
- }
-
- if (ssl3_timeout) {
- if (ssl3_timeout > MAX_SSL3_TIMEOUT) {
- ssl3_timeout = MAX_SSL3_TIMEOUT;
- }
- if (ssl3_timeout < MIN_SSL3_TIMEOUT) {
- ssl3_timeout = MIN_SSL3_TIMEOUT;
- }
- cache->ssl3Timeout = ssl3_timeout;
- } else {
- cache->ssl3Timeout = DEF_SSL3_TIMEOUT;
- }
-
- if (shared) {
- /* Create file names */
-#if defined(XP_UNIX) || defined(XP_BEOS)
- /* there's some confusion here about whether PR_OpenAnonFileMap wants
- ** a directory name or a file name for its first argument.
- cfn = PR_smprintf("%s/.sslsvrcache.%d", directory, myPid);
- */
- cfn = PR_smprintf("%s", directory);
-#elif defined(XP_WIN32)
- cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid,
- GetCurrentThreadId());
-#elif defined(XP_OS2)
- cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid,
- gettid());
-#else
-#error "Don't know how to create file name for this platform!"
-#endif
- if (!cfn) {
- goto loser;
- }
-
- /* Create cache */
- cacheMemMap = PR_OpenAnonFileMap(cfn, cache->cacheMemSize,
- PR_PROT_READWRITE);
-
- PR_smprintf_free(cfn);
- if(!cacheMemMap) {
- goto loser;
- }
-
- cacheMem = PR_MemMap(cacheMemMap, 0, cache->cacheMemSize);
- } else {
- cacheMem = PORT_Alloc(cache->cacheMemSize);
- }
-
- if (! cacheMem) {
- goto loser;
- }
-
- /* Initialize shared memory. This may not be necessary on all platforms */
- memset(cacheMem, 0, cache->cacheMemSize);
-
- /* Copy cache descriptor header into shared memory */
- memcpy(cacheMem, cache, sizeof *cache);
-
- /* save private copies of these values */
- cache->cacheMemMap = cacheMemMap;
- cache->cacheMem = cacheMem;
- cache->sharedCache = (cacheDesc *)cacheMem;
-
- /* Fix pointers in our private copy of cache descriptor to point to
- ** spaces in shared memory
- */
- ptr = (ptrdiff_t)cache->cacheMem;
- *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
- *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
- *(ptrdiff_t *)(&cache->certCacheLock) += ptr;
- *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
- *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
- *(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
- *(ptrdiff_t *)(&cache->certCacheData) += ptr;
- *(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
- *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
- *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
- *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
- *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
- *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;
-
- /* initialize the locks */
- init_time = ssl_Time();
- pLock = cache->sidCacheLocks;
- for (locks_to_initialize = cache->numSIDCacheLocks + 3;
- locks_initialized < locks_to_initialize;
- ++locks_initialized, ++pLock ) {
-
- SECStatus err = sslMutex_Init(&pLock->mutex, shared);
- if (err) {
- cache->numSIDCacheLocksInitialized = locks_initialized;
- goto loser;
- }
- pLock->timeStamp = init_time;
- pLock->pid = 0;
- }
- cache->numSIDCacheLocksInitialized = locks_initialized;
-
- return SECSuccess;
-
-loser:
- CloseCache(cache);
- return SECFailure;
-}
-
-PRUint32
-SSL_GetMaxServerCacheLocks(void)
-{
- return ssl_max_sid_cache_locks + 2;
- /* The extra two are the cert cache lock and the key cache lock. */
-}
-
-SECStatus
-SSL_SetMaxServerCacheLocks(PRUint32 maxLocks)
-{
- /* Minimum is 1 sid cache lock, 1 cert cache lock and 1 key cache lock.
- ** We'd like to test for a maximum value, but not all platforms' header
- ** files provide a symbol or function or other means of determining
- ** the maximum, other than trial and error.
- */
- if (maxLocks < 3) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- ssl_max_sid_cache_locks = maxLocks - 2;
- /* The extra two are the cert cache lock and the key cache lock. */
- return SECSuccess;
-}
-
-static SECStatus
-ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory,
- PRBool shared,
- int maxCacheEntries,
- int maxCertCacheEntries,
- int maxSrvNameCacheEntries)
-{
- SECStatus rv;
-
- PORT_Assert(sizeof(sidCacheEntry) == 192);
- PORT_Assert(sizeof(certCacheEntry) == 4096);
- PORT_Assert(sizeof(srvNameCacheEntry) == 1072);
-
- rv = ssl_Init();
- if (rv != SECSuccess) {
- return rv;
- }
-
- myPid = SSL_GETPID();
- if (!directory) {
- directory = DEFAULT_CACHE_DIRECTORY;
- }
- rv = InitCache(cache, maxCacheEntries, maxCertCacheEntries,
- maxSrvNameCacheEntries, ssl2_timeout, ssl3_timeout,
- directory, shared);
- if (rv) {
- SET_ERROR_CODE
- return SECFailure;
- }
-
- ssl_sid_lookup = ServerSessionIDLookup;
- ssl_sid_cache = ServerSessionIDCache;
- ssl_sid_uncache = ServerSessionIDUncache;
- return SECSuccess;
-}
-
-SECStatus
-SSL_ConfigServerSessionIDCacheInstance( cacheDesc *cache,
- int maxCacheEntries,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory, PRBool shared)
-{
- return ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache,
- ssl2_timeout,
- ssl3_timeout,
- directory,
- shared,
- maxCacheEntries,
- -1, -1);
-}
-
-SECStatus
-SSL_ConfigServerSessionIDCache( int maxCacheEntries,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory)
-{
- ssl_InitSessionCacheLocks(PR_FALSE);
- return SSL_ConfigServerSessionIDCacheInstance(&globalCache,
- maxCacheEntries, ssl2_timeout, ssl3_timeout, directory, PR_FALSE);
-}
-
-SECStatus
-SSL_ShutdownServerSessionIDCacheInstance(cacheDesc *cache)
-{
- CloseCache(cache);
- return SECSuccess;
-}
-
-SECStatus
-SSL_ShutdownServerSessionIDCache(void)
-{
-#if defined(XP_UNIX) || defined(XP_BEOS)
- /* Stop the thread that polls cache for expired locks on Unix */
- StopLockPoller(&globalCache);
-#endif
- SSL3_ShutdownServerCache();
- return SSL_ShutdownServerSessionIDCacheInstance(&globalCache);
-}
-
-/* Use this function, instead of SSL_ConfigServerSessionIDCache,
- * if the cache will be shared by multiple processes.
- */
-static SECStatus
-ssl_ConfigMPServerSIDCacheWithOpt( PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory,
- int maxCacheEntries,
- int maxCertCacheEntries,
- int maxSrvNameCacheEntries)
-{
- char * envValue;
- char * inhValue;
- cacheDesc * cache = &globalCache;
- PRUint32 fmStrLen;
- SECStatus result;
- PRStatus prStatus;
- SECStatus putEnvFailed;
- inheritance inherit;
- char fmString[PR_FILEMAP_STRING_BUFSIZE];
-
- isMultiProcess = PR_TRUE;
- result = ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache,
- ssl2_timeout, ssl3_timeout, directory, PR_TRUE,
- maxCacheEntries, maxCacheEntries, maxSrvNameCacheEntries);
- if (result != SECSuccess)
- return result;
-
- prStatus = PR_ExportFileMapAsString(cache->cacheMemMap,
- sizeof fmString, fmString);
- if ((prStatus != PR_SUCCESS) || !(fmStrLen = strlen(fmString))) {
- SET_ERROR_CODE
- return SECFailure;
- }
-
- inherit.cacheMemSize = cache->cacheMemSize;
- inherit.fmStrLen = fmStrLen;
-
- inhValue = BTOA_DataToAscii((unsigned char *)&inherit, sizeof inherit);
- if (!inhValue || !strlen(inhValue)) {
- SET_ERROR_CODE
- return SECFailure;
- }
- envValue = PR_smprintf("%s,%s", inhValue, fmString);
- if (!envValue || !strlen(envValue)) {
- SET_ERROR_CODE
- return SECFailure;
- }
- PORT_Free(inhValue);
-
- putEnvFailed = (SECStatus)NSS_PutEnv(envVarName, envValue);
- PR_smprintf_free(envValue);
- if (putEnvFailed) {
- SET_ERROR_CODE
- result = SECFailure;
- }
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
- /* Launch thread to poll cache for expired locks on Unix */
- LaunchLockPoller(cache);
-#endif
- return result;
-}
-
-/* Use this function, instead of SSL_ConfigServerSessionIDCache,
- * if the cache will be shared by multiple processes.
- */
-SECStatus
-SSL_ConfigMPServerSIDCache( int maxCacheEntries,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory)
-{
- return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout,
- ssl3_timeout,
- directory,
- maxCacheEntries,
- -1, -1);
-}
-
-SECStatus
-SSL_ConfigServerSessionIDCacheWithOpt(
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory,
- int maxCacheEntries,
- int maxCertCacheEntries,
- int maxSrvNameCacheEntries,
- PRBool enableMPCache)
-{
- if (!enableMPCache) {
- ssl_InitSessionCacheLocks(PR_FALSE);
- return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache,
- ssl2_timeout, ssl3_timeout, directory, PR_FALSE,
- maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
- } else {
- return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout, ssl3_timeout,
- directory, maxCacheEntries, maxCertCacheEntries,
- maxSrvNameCacheEntries);
- }
-}
-
-SECStatus
-SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char * envString)
-{
- unsigned char * decoString = NULL;
- char * fmString = NULL;
- char * myEnvString = NULL;
- unsigned int decoLen;
- ptrdiff_t ptr;
- inheritance inherit;
- cacheDesc my;
-#ifdef WINNT
- sidCacheLock* newLocks;
- int locks_initialized = 0;
- int locks_to_initialize = 0;
-#endif
- SECStatus status = ssl_Init();
-
- if (status != SECSuccess) {
- return status;
- }
-
- myPid = SSL_GETPID();
-
- /* If this child was created by fork(), and not by exec() on unix,
- ** then isMultiProcess will already be set.
- ** If not, we'll set it below.
- */
- if (isMultiProcess) {
- if (cache && cache->sharedCache) {
- cache->sharedCache->everInherited = PR_TRUE;
- }
- return SECSuccess; /* already done. */
- }
-
- ssl_InitSessionCacheLocks(PR_FALSE);
-
- ssl_sid_lookup = ServerSessionIDLookup;
- ssl_sid_cache = ServerSessionIDCache;
- ssl_sid_uncache = ServerSessionIDUncache;
-
- if (!envString) {
- envString = getenv(envVarName);
- if (!envString) {
- SET_ERROR_CODE
- return SECFailure;
- }
- }
- myEnvString = PORT_Strdup(envString);
- if (!myEnvString)
- return SECFailure;
- fmString = strchr(myEnvString, ',');
- if (!fmString)
- goto loser;
- *fmString++ = 0;
-
- decoString = ATOB_AsciiToData(myEnvString, &decoLen);
- if (!decoString) {
- SET_ERROR_CODE
- goto loser;
- }
- if (decoLen != sizeof inherit) {
- SET_ERROR_CODE
- goto loser;
- }
-
- PORT_Memcpy(&inherit, decoString, sizeof inherit);
-
- if (strlen(fmString) != inherit.fmStrLen ) {
- goto loser;
- }
-
- memset(cache, 0, sizeof *cache);
- cache->cacheMemSize = inherit.cacheMemSize;
-
- /* Create cache */
- cache->cacheMemMap = PR_ImportFileMapFromString(fmString);
- if(! cache->cacheMemMap) {
- goto loser;
- }
- cache->cacheMem = PR_MemMap(cache->cacheMemMap, 0, cache->cacheMemSize);
- if (! cache->cacheMem) {
- goto loser;
- }
- cache->sharedCache = (cacheDesc *)cache->cacheMem;
-
- if (cache->sharedCache->cacheMemSize != cache->cacheMemSize) {
- SET_ERROR_CODE
- goto loser;
- }
-
- /* We're now going to overwrite the local cache instance with the
- ** shared copy of the cache struct, then update several values in
- ** the local cache using the values for cache->cacheMemMap and
- ** cache->cacheMem computed just above. So, we copy cache into
- ** the automatic variable "my", to preserve the variables while
- ** cache is overwritten.
- */
- my = *cache; /* save values computed above. */
- memcpy(cache, cache->sharedCache, sizeof *cache); /* overwrite */
-
- /* Fix pointers in our private copy of cache descriptor to point to
- ** spaces in shared memory, whose address is now in "my".
- */
- ptr = (ptrdiff_t)my.cacheMem;
- *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
- *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
- *(ptrdiff_t *)(&cache->certCacheLock) += ptr;
- *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
- *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
- *(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
- *(ptrdiff_t *)(&cache->certCacheData) += ptr;
- *(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
- *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
- *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
- *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
- *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
- *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;
-
- cache->cacheMemMap = my.cacheMemMap;
- cache->cacheMem = my.cacheMem;
- cache->sharedCache = (cacheDesc *)cache->cacheMem;
-
-#ifdef WINNT
- /* On Windows NT we need to "fix" the sidCacheLocks here to support fibers
- ** When NT fibers are used in a multi-process server, a second level of
- ** locking is needed to prevent a deadlock, in case a fiber acquires the
- ** cross-process mutex, yields, and another fiber is later scheduled on
- ** the same native thread and tries to acquire the cross-process mutex.
- ** We do this by using a PRLock in the sslMutex. However, it is stored in
- ** shared memory as part of sidCacheLocks, and we don't want to overwrite
- ** the PRLock of the parent process. So we need to make new, private
- ** copies of sidCacheLocks before modifying the sslMutex with our own
- ** PRLock
- */
-
- /* note from jpierre : this should be free'd in child processes when
- ** a function is added to delete the SSL session cache in the future.
- */
- locks_to_initialize = cache->numSIDCacheLocks + 3;
- newLocks = PORT_NewArray(sidCacheLock, locks_to_initialize);
- if (!newLocks)
- goto loser;
- /* copy the old locks */
- memcpy(newLocks, cache->sidCacheLocks,
- locks_to_initialize * sizeof(sidCacheLock));
- cache->sidCacheLocks = newLocks;
- /* fix the locks */
- for (; locks_initialized < locks_to_initialize; ++locks_initialized) {
- /* now, make a local PRLock in this sslMutex for this child process */
- SECStatus err;
- err = sslMutex_2LevelInit(&newLocks[locks_initialized].mutex);
- if (err != SECSuccess) {
- cache->numSIDCacheLocksInitialized = locks_initialized;
- goto loser;
- }
- }
- cache->numSIDCacheLocksInitialized = locks_initialized;
-
- /* also fix the key and cert cache which use the last 2 lock entries */
- cache->keyCacheLock = cache->sidCacheLocks + cache->numSIDCacheLocks;
- cache->certCacheLock = cache->keyCacheLock + 1;
- cache->srvNameCacheLock = cache->certCacheLock + 1;
-#endif
-
- PORT_Free(myEnvString);
- PORT_Free(decoString);
-
- /* mark that we have inherited this. */
- cache->sharedCache->everInherited = PR_TRUE;
- isMultiProcess = PR_TRUE;
-
- return SECSuccess;
-
-loser:
- PORT_Free(myEnvString);
- if (decoString)
- PORT_Free(decoString);
- CloseCache(cache);
- return SECFailure;
-}
-
-SECStatus
-SSL_InheritMPServerSIDCache(const char * envString)
-{
- return SSL_InheritMPServerSIDCacheInstance(&globalCache, envString);
-}
-
-#if defined(XP_UNIX) || defined(XP_BEOS)
-
-#define SID_LOCK_EXPIRATION_TIMEOUT 30 /* seconds */
-
-static void
-LockPoller(void * arg)
-{
- cacheDesc * cache = (cacheDesc *)arg;
- cacheDesc * sharedCache = cache->sharedCache;
- sidCacheLock * pLock;
- PRIntervalTime timeout;
- PRUint32 now;
- PRUint32 then;
- int locks_polled = 0;
- int locks_to_poll = cache->numSIDCacheLocks + 2;
- PRUint32 expiration = cache->mutexTimeout;
-
- timeout = PR_SecondsToInterval(expiration);
- while(!sharedCache->stopPolling) {
- PR_Sleep(timeout);
- if (sharedCache->stopPolling)
- break;
-
- now = ssl_Time();
- then = now - expiration;
- for (pLock = cache->sidCacheLocks, locks_polled = 0;
- locks_to_poll > locks_polled && !sharedCache->stopPolling;
- ++locks_polled, ++pLock ) {
- pid_t pid;
-
- if (pLock->timeStamp < then &&
- pLock->timeStamp != 0 &&
- (pid = pLock->pid) != 0) {
-
- /* maybe we should try the lock? */
- int result = kill(pid, 0);
- if (result < 0 && errno == ESRCH) {
- SECStatus rv;
- /* No process exists by that pid any more.
- ** Treat this mutex as abandoned.
- */
- pLock->timeStamp = now;
- pLock->pid = 0;
- rv = sslMutex_Unlock(&pLock->mutex);
- if (rv != SECSuccess) {
- /* Now what? */
- }
- }
- }
- } /* end of loop over locks */
- } /* end of entire polling loop */
-}
-
-/* Launch thread to poll cache for expired locks */
-static SECStatus
-LaunchLockPoller(cacheDesc *cache)
-{
- const char * timeoutString;
- PRThread * pollerThread;
-
- cache->mutexTimeout = SID_LOCK_EXPIRATION_TIMEOUT;
- timeoutString = getenv("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT");
- if (timeoutString) {
- long newTime = strtol(timeoutString, 0, 0);
- if (newTime == 0)
- return SECSuccess; /* application doesn't want poller thread */
- if (newTime > 0)
- cache->mutexTimeout = (PRUint32)newTime;
- /* if error (newTime < 0) ignore it and use default */
- }
-
- pollerThread =
- PR_CreateThread(PR_USER_THREAD, LockPoller, cache, PR_PRIORITY_NORMAL,
- PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
- if (!pollerThread) {
- return SECFailure;
- }
- cache->poller = pollerThread;
- return SECSuccess;
-}
-
-/* Stop the thread that polls cache for expired locks */
-static SECStatus
-StopLockPoller(cacheDesc *cache)
-{
- if (!cache->poller) {
- return SECSuccess;
- }
- cache->sharedCache->stopPolling = PR_TRUE;
- if (PR_Interrupt(cache->poller) != PR_SUCCESS) {
- return SECFailure;
- }
- if (PR_JoinThread(cache->poller) != PR_SUCCESS) {
- return SECFailure;
- }
- cache->poller = NULL;
- return SECSuccess;
-}
-#endif
-
-/************************************************************************
- * Code dealing with shared wrapped symmetric wrapping keys below *
- ************************************************************************/
-
-/* If now is zero, it implies that the lock is not held, and must be
-** aquired here.
-*/
-static PRBool
-getSvrWrappingKey(PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk,
- cacheDesc * cache,
- PRUint32 lockTime)
-{
- PRUint32 ndx = (exchKeyType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex;
- SSLWrappedSymWrappingKey * pwswk = cache->keyCacheData + ndx;
- PRUint32 now = 0;
- PRBool rv = PR_FALSE;
-
- if (!cache->cacheMem) { /* cache is uninitialized */
- PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
- return rv;
- }
- if (!lockTime) {
- lockTime = now = LockSidCacheLock(cache->keyCacheLock, now);
- if (!lockTime) {
- return rv;
- }
- }
- if (pwswk->exchKeyType == exchKeyType &&
- pwswk->symWrapMechIndex == symWrapMechIndex &&
- pwswk->wrappedSymKeyLen != 0) {
- *wswk = *pwswk;
- rv = PR_TRUE;
- }
- if (now) {
- UnlockSidCacheLock(cache->keyCacheLock);
- }
- return rv;
-}
-
-PRBool
-ssl_GetWrappingKey( PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk)
-{
- PRBool rv;
-
- PORT_Assert( (unsigned)exchKeyType < kt_kea_size);
- PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
- if ((unsigned)exchKeyType < kt_kea_size &&
- (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS) {
- rv = getSvrWrappingKey(symWrapMechIndex, exchKeyType, wswk,
- &globalCache, 0);
- } else {
- rv = PR_FALSE;
- }
-
- return rv;
-}
-
-/* Wrap and cache a session ticket key. */
-static PRBool
-WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey,
- const char *keyName, encKeyCacheEntry* cacheEntry)
-{
- SECItem wrappedKey = {siBuffer, NULL, 0};
-
- wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey);
- PORT_Assert(wrappedKey.len <= sizeof(cacheEntry->bytes));
- if (wrappedKey.len > sizeof(cacheEntry->bytes))
- return PR_FALSE;
- wrappedKey.data = cacheEntry->bytes;
-
- if (PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, symKey, &wrappedKey)
- != SECSuccess) {
- SSL_DBG(("%d: SSL[%s]: Unable to wrap session ticket %s.",
- SSL_GETPID(), "unknown", keyName));
- return PR_FALSE;
- }
- cacheEntry->length = wrappedKey.len;
- return PR_TRUE;
-}
-
-static PRBool
-GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey,
- PK11SymKey **macKey)
-{
- PK11SlotInfo *slot;
- CK_MECHANISM_TYPE mechanismArray[2];
- PK11SymKey *aesKeyTmp = NULL;
- PK11SymKey *macKeyTmp = NULL;
- cacheDesc *cache = &globalCache;
- uint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN];
- uint8 *ticketKeyNameSuffix;
-
- if (!cache->cacheMem) {
- /* cache is not initalized. Use stack buffer */
- ticketKeyNameSuffix = ticketKeyNameSuffixLocal;
- } else {
- ticketKeyNameSuffix = cache->ticketKeyNameSuffix;
- }
-
- if (PK11_GenerateRandom(ticketKeyNameSuffix,
- SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess) {
- SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.",
- SSL_GETPID(), "unknown"));
- goto loser;
- }
-
- mechanismArray[0] = CKM_AES_CBC;
- mechanismArray[1] = CKM_SHA256_HMAC;
-
- slot = PK11_GetBestSlotMultiple(mechanismArray, 2, pwArg);
- if (slot) {
- aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL,
- AES_256_KEY_LENGTH, pwArg);
- macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL,
- SHA256_LENGTH, pwArg);
- PK11_FreeSlot(slot);
- }
-
- if (aesKeyTmp == NULL || macKeyTmp == NULL) {
- SSL_DBG(("%d: SSL[%s]: Unable to generate session ticket keys.",
- SSL_GETPID(), "unknown"));
- goto loser;
- }
- PORT_Memcpy(keyName, ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN);
- *aesKey = aesKeyTmp;
- *macKey = macKeyTmp;
- return PR_TRUE;
-
-loser:
- if (aesKeyTmp)
- PK11_FreeSymKey(aesKeyTmp);
- if (macKeyTmp)
- PK11_FreeSymKey(macKeyTmp);
- return PR_FALSE;
-}
-
-static PRBool
-GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg,
- unsigned char *keyName, PK11SymKey **aesKey,
- PK11SymKey **macKey)
-{
- PK11SymKey *aesKeyTmp = NULL;
- PK11SymKey *macKeyTmp = NULL;
- cacheDesc *cache = &globalCache;
-
- if (!GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp)) {
- goto loser;
- }
-
- if (cache->cacheMem) {
- /* Export the keys to the shared cache in wrapped form. */
- if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey))
- goto loser;
- if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey))
- goto loser;
- }
- *aesKey = aesKeyTmp;
- *macKey = macKeyTmp;
- return PR_TRUE;
-
-loser:
- if (aesKeyTmp)
- PK11_FreeSymKey(aesKeyTmp);
- if (macKeyTmp)
- PK11_FreeSymKey(macKeyTmp);
- return PR_FALSE;
-}
-
-static PRBool
-UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName,
- PK11SymKey **aesKey, PK11SymKey **macKey)
-{
- SECItem wrappedKey = {siBuffer, NULL, 0};
- PK11SymKey *aesKeyTmp = NULL;
- PK11SymKey *macKeyTmp = NULL;
- cacheDesc *cache = &globalCache;
-
- wrappedKey.data = cache->ticketEncKey->bytes;
- wrappedKey.len = cache->ticketEncKey->length;
- PORT_Assert(wrappedKey.len <= sizeof(cache->ticketEncKey->bytes));
- aesKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
- CKM_AES_CBC, CKA_DECRYPT, 0);
-
- wrappedKey.data = cache->ticketMacKey->bytes;
- wrappedKey.len = cache->ticketMacKey->length;
- PORT_Assert(wrappedKey.len <= sizeof(cache->ticketMacKey->bytes));
- macKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
- CKM_SHA256_HMAC, CKA_SIGN, 0);
-
- if (aesKeyTmp == NULL || macKeyTmp == NULL) {
- SSL_DBG(("%d: SSL[%s]: Unable to unwrap session ticket keys.",
- SSL_GETPID(), "unknown"));
- goto loser;
- }
- SSL_DBG(("%d: SSL[%s]: Successfully unwrapped session ticket keys.",
- SSL_GETPID(), "unknown"));
-
- PORT_Memcpy(keyName, cache->ticketKeyNameSuffix,
- SESS_TICKET_KEY_VAR_NAME_LEN);
- *aesKey = aesKeyTmp;
- *macKey = macKeyTmp;
- return PR_TRUE;
-
-loser:
- if (aesKeyTmp)
- PK11_FreeSymKey(aesKeyTmp);
- if (macKeyTmp)
- PK11_FreeSymKey(macKeyTmp);
- return PR_FALSE;
-}
-
-PRBool
-ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
- SECKEYPublicKey *svrPubKey, void *pwArg,
- unsigned char *keyName, PK11SymKey **aesKey,
- PK11SymKey **macKey)
-{
- PRUint32 now = 0;
- PRBool rv = PR_FALSE;
- PRBool keysGenerated = PR_FALSE;
- cacheDesc *cache = &globalCache;
-
- if (!cache->cacheMem) {
- /* cache is uninitialized. Generate keys and return them
- * without caching. */
- return GenerateTicketKeys(pwArg, keyName, aesKey, macKey);
- }
-
- now = LockSidCacheLock(cache->keyCacheLock, now);
- if (!now)
- return rv;
-
- if (!*(cache->ticketKeysValid)) {
- /* Keys do not exist, create them. */
- if (!GenerateAndWrapTicketKeys(svrPubKey, pwArg, keyName,
- aesKey, macKey))
- goto loser;
- keysGenerated = PR_TRUE;
- *(cache->ticketKeysValid) = 1;
- }
-
- rv = PR_TRUE;
-
- loser:
- UnlockSidCacheLock(cache->keyCacheLock);
- if (rv && !keysGenerated)
- rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, aesKey, macKey);
- return rv;
-}
-
-PRBool
-ssl_GetSessionTicketKeys(unsigned char *keyName, unsigned char *encKey,
- unsigned char *macKey)
-{
- PRBool rv = PR_FALSE;
- PRUint32 now = 0;
- cacheDesc *cache = &globalCache;
- uint8 ticketMacKey[AES_256_KEY_LENGTH], ticketEncKey[SHA256_LENGTH];
- uint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN];
- uint8 *ticketMacKeyPtr, *ticketEncKeyPtr, *ticketKeyNameSuffix;
- PRBool cacheIsEnabled = PR_TRUE;
-
- if (!cache->cacheMem) { /* cache is uninitialized */
- cacheIsEnabled = PR_FALSE;
- ticketKeyNameSuffix = ticketKeyNameSuffixLocal;
- ticketEncKeyPtr = ticketEncKey;
- ticketMacKeyPtr = ticketMacKey;
- } else {
- /* these values have constant memory locations in the cache.
- * Ok to reference them without holding the lock. */
- ticketKeyNameSuffix = cache->ticketKeyNameSuffix;
- ticketEncKeyPtr = cache->ticketEncKey->bytes;
- ticketMacKeyPtr = cache->ticketMacKey->bytes;
- }
-
- if (cacheIsEnabled) {
- /* Grab lock if initialized. */
- now = LockSidCacheLock(cache->keyCacheLock, now);
- if (!now)
- return rv;
- }
- /* Going to regenerate keys on every call if cache was not
- * initialized. */
- if (!cacheIsEnabled || !*(cache->ticketKeysValid)) {
- if (PK11_GenerateRandom(ticketKeyNameSuffix,
- SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess)
- goto loser;
- if (PK11_GenerateRandom(ticketEncKeyPtr,
- AES_256_KEY_LENGTH) != SECSuccess)
- goto loser;
- if (PK11_GenerateRandom(ticketMacKeyPtr,
- SHA256_LENGTH) != SECSuccess)
- goto loser;
- if (cacheIsEnabled) {
- *(cache->ticketKeysValid) = 1;
- }
- }
-
- rv = PR_TRUE;
-
- loser:
- if (cacheIsEnabled) {
- UnlockSidCacheLock(cache->keyCacheLock);
- }
- if (rv) {
- PORT_Memcpy(keyName, ticketKeyNameSuffix,
- SESS_TICKET_KEY_VAR_NAME_LEN);
- PORT_Memcpy(encKey, ticketEncKeyPtr, AES_256_KEY_LENGTH);
- PORT_Memcpy(macKey, ticketMacKeyPtr, SHA256_LENGTH);
- }
- return rv;
-}
-
-/* The caller passes in the new value it wants
- * to set. This code tests the wrapped sym key entry in the shared memory.
- * If it is uninitialized, this function writes the caller's value into
- * the disk entry, and returns false.
- * Otherwise, it overwrites the caller's wswk with the value obtained from
- * the disk, and returns PR_TRUE.
- * This is all done while holding the locks/mutexes necessary to make
- * the operation atomic.
- */
-PRBool
-ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
-{
- cacheDesc * cache = &globalCache;
- PRBool rv = PR_FALSE;
- SSL3KEAType exchKeyType = wswk->exchKeyType;
- /* type of keys used to wrap SymWrapKey*/
- PRInt32 symWrapMechIndex = wswk->symWrapMechIndex;
- PRUint32 ndx;
- PRUint32 now = 0;
- SSLWrappedSymWrappingKey myWswk;
-
- if (!cache->cacheMem) { /* cache is uninitialized */
- PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
- return 0;
- }
-
- PORT_Assert( (unsigned)exchKeyType < kt_kea_size);
- if ((unsigned)exchKeyType >= kt_kea_size)
- return 0;
-
- PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
- if ((unsigned)symWrapMechIndex >= SSL_NUM_WRAP_MECHS)
- return 0;
-
- ndx = (exchKeyType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex;
- PORT_Memset(&myWswk, 0, sizeof myWswk); /* eliminate UMRs. */
-
- now = LockSidCacheLock(cache->keyCacheLock, now);
- if (now) {
- rv = getSvrWrappingKey(wswk->symWrapMechIndex, wswk->exchKeyType,
- &myWswk, cache, now);
- if (rv) {
- /* we found it on disk, copy it out to the caller. */
- PORT_Memcpy(wswk, &myWswk, sizeof *wswk);
- } else {
- /* Wasn't on disk, and we're still holding the lock, so write it. */
- cache->keyCacheData[ndx] = *wswk;
- }
- UnlockSidCacheLock(cache->keyCacheLock);
- }
- return rv;
-}
-
-#else /* MAC version or other platform */
-
-#include "seccomon.h"
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-
-SECStatus
-SSL_ConfigServerSessionIDCache( int maxCacheEntries,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory)
-{
- PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigServerSessionIDCache)");
- return SECFailure;
-}
-
-SECStatus
-SSL_ConfigMPServerSIDCache( int maxCacheEntries,
- PRUint32 ssl2_timeout,
- PRUint32 ssl3_timeout,
- const char * directory)
-{
- PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigMPServerSIDCache)");
- return SECFailure;
-}
-
-SECStatus
-SSL_InheritMPServerSIDCache(const char * envString)
-{
- PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_InheritMPServerSIDCache)");
- return SECFailure;
-}
-
-PRBool
-ssl_GetWrappingKey( PRInt32 symWrapMechIndex,
- SSL3KEAType exchKeyType,
- SSLWrappedSymWrappingKey *wswk)
-{
- PRBool rv = PR_FALSE;
- PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_GetWrappingKey)");
- return rv;
-}
-
-/* This is a kind of test-and-set. The caller passes in the new value it wants
- * to set. This code tests the wrapped sym key entry in the shared memory.
- * If it is uninitialized, this function writes the caller's value into
- * the disk entry, and returns false.
- * Otherwise, it overwrites the caller's wswk with the value obtained from
- * the disk, and returns PR_TRUE.
- * This is all done while holding the locks/mutexes necessary to make
- * the operation atomic.
- */
-PRBool
-ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
-{
- PRBool rv = PR_FALSE;
- PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_SetWrappingKey)");
- return rv;
-}
-
-PRUint32
-SSL_GetMaxServerCacheLocks(void)
-{
- PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_GetMaxServerCacheLocks)");
- return -1;
-}
-
-SECStatus
-SSL_SetMaxServerCacheLocks(PRUint32 maxLocks)
-{
- PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_SetMaxServerCacheLocks)");
- return SECFailure;
-}
-
-#endif /* XP_UNIX || XP_WIN32 */
diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
deleted file mode 100644
index a0d347266..000000000
--- a/security/nss/lib/ssl/sslsock.c
+++ /dev/null
@@ -1,3003 +0,0 @@
-/*
- * vtables (and methods that call through them) for the 4 types of
- * SSLSockets supported. Only one type is still supported.
- * Various other functions.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#include "seccomon.h"
-#include "cert.h"
-#include "keyhi.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "nspr.h"
-#include "private/pprio.h"
-#ifndef NO_PKCS11_BYPASS
-#include "blapi.h"
-#endif
-#include "nss.h"
-
-#define SET_ERROR_CODE /* reminder */
-
-struct cipherPolicyStr {
- int cipher;
- unsigned char export; /* policy value for export policy */
- unsigned char france; /* policy value for france policy */
-};
-
-typedef struct cipherPolicyStr cipherPolicy;
-
-/* This table contains two preconfigured policies: Export and France.
-** It is used only by the functions SSL_SetDomesticPolicy,
-** SSL_SetExportPolicy, and SSL_SetFrancyPolicy.
-** Order of entries is not important.
-*/
-static cipherPolicy ssl_ciphers[] = { /* Export France */
- { SSL_EN_RC4_128_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_EN_RC4_128_EXPORT40_WITH_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_EN_RC2_128_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_EN_DES_64_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_EN_DES_192_EDE3_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_WITH_RC4_128_MD5, SSL_RESTRICTED, SSL_NOT_ALLOWED },
- { SSL_RSA_WITH_RC4_128_SHA, SSL_RESTRICTED, SSL_NOT_ALLOWED },
- { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RESTRICTED, SSL_NOT_ALLOWED },
- { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { SSL_RSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED },
- { SSL_RSA_WITH_NULL_MD5, SSL_ALLOWED, SSL_ALLOWED },
- { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_RSA_WITH_SEED_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED },
-#ifdef NSS_ENABLE_ECC
- { TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED },
- { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED },
- { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDH_RSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED },
- { TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED },
- { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
- { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
-#endif /* NSS_ENABLE_ECC */
- { 0, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }
-};
-
-static const sslSocketOps ssl_default_ops = { /* No SSL. */
- ssl_DefConnect,
- NULL,
- ssl_DefBind,
- ssl_DefListen,
- ssl_DefShutdown,
- ssl_DefClose,
- ssl_DefRecv,
- ssl_DefSend,
- ssl_DefRead,
- ssl_DefWrite,
- ssl_DefGetpeername,
- ssl_DefGetsockname
-};
-
-static const sslSocketOps ssl_secure_ops = { /* SSL. */
- ssl_SecureConnect,
- NULL,
- ssl_DefBind,
- ssl_DefListen,
- ssl_SecureShutdown,
- ssl_SecureClose,
- ssl_SecureRecv,
- ssl_SecureSend,
- ssl_SecureRead,
- ssl_SecureWrite,
- ssl_DefGetpeername,
- ssl_DefGetsockname
-};
-
-/*
-** default settings for socket enables
-*/
-static sslOptions ssl_defaults = {
- { siBuffer, NULL, 0 }, /* nextProtoNego */
- PR_TRUE, /* useSecurity */
- PR_FALSE, /* useSocks */
- PR_FALSE, /* requestCertificate */
- 2, /* requireCertificate */
- PR_FALSE, /* handshakeAsClient */
- PR_FALSE, /* handshakeAsServer */
- PR_FALSE, /* enableSSL2 */ /* now defaults to off in NSS 3.13 */
- PR_FALSE, /* unusedBit9 */
- PR_FALSE, /* unusedBit10 */
- PR_FALSE, /* noCache */
- PR_FALSE, /* fdx */
- PR_FALSE, /* v2CompatibleHello */ /* now defaults to off in NSS 3.13 */
- PR_TRUE, /* detectRollBack */
- PR_FALSE, /* noStepDown */
- PR_FALSE, /* bypassPKCS11 */
- PR_FALSE, /* noLocks */
- PR_FALSE, /* enableSessionTickets */
- PR_FALSE, /* enableDeflate */
- 2, /* enableRenegotiation (default: requires extension) */
- PR_FALSE, /* requireSafeNegotiation */
- PR_FALSE, /* enableFalseStart */
- PR_TRUE, /* cbcRandomIV */
- PR_FALSE /* enableOCSPStapling */
-};
-
-/*
- * default range of enabled SSL/TLS protocols
- */
-static SSLVersionRange versions_defaults_stream = {
- SSL_LIBRARY_VERSION_3_0,
- SSL_LIBRARY_VERSION_TLS_1_0
-};
-
-static SSLVersionRange versions_defaults_datagram = {
- SSL_LIBRARY_VERSION_TLS_1_1,
- SSL_LIBRARY_VERSION_TLS_1_1
-};
-
-#define VERSIONS_DEFAULTS(variant) \
- (variant == ssl_variant_stream ? &versions_defaults_stream : \
- &versions_defaults_datagram)
-
-sslSessionIDLookupFunc ssl_sid_lookup;
-sslSessionIDCacheFunc ssl_sid_cache;
-sslSessionIDUncacheFunc ssl_sid_uncache;
-
-static PRBool ssl_inited = PR_FALSE;
-static PRDescIdentity ssl_layer_id;
-
-PRBool locksEverDisabled; /* implicitly PR_FALSE */
-PRBool ssl_force_locks; /* implicitly PR_FALSE */
-int ssl_lock_readers = 1; /* default true. */
-char ssl_debug;
-char ssl_trace;
-FILE * ssl_trace_iob;
-FILE * ssl_keylog_iob;
-char lockStatus[] = "Locks are ENABLED. ";
-#define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
-
-/* SRTP_NULL_HMAC_SHA1_80 and SRTP_NULL_HMAC_SHA1_32 are not implemented. */
-static const PRUint16 srtpCiphers[] = {
- SRTP_AES128_CM_HMAC_SHA1_80,
- SRTP_AES128_CM_HMAC_SHA1_32,
- 0
-};
-
-/* forward declarations. */
-static sslSocket *ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant variant);
-static SECStatus ssl_MakeLocks(sslSocket *ss);
-static void ssl_SetDefaultsFromEnvironment(void);
-static PRStatus ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
- PRDescIdentity id);
-
-/************************************************************************/
-
-/*
-** Lookup a socket structure from a file descriptor.
-** Only functions called through the PRIOMethods table should use this.
-** Other app-callable functions should use ssl_FindSocket.
-*/
-static sslSocket *
-ssl_GetPrivate(PRFileDesc *fd)
-{
- sslSocket *ss;
-
- PORT_Assert(fd != NULL);
- PORT_Assert(fd->methods->file_type == PR_DESC_LAYERED);
- PORT_Assert(fd->identity == ssl_layer_id);
-
- if (fd->methods->file_type != PR_DESC_LAYERED ||
- fd->identity != ssl_layer_id) {
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- return NULL;
- }
-
- ss = (sslSocket *)fd->secret;
- ss->fd = fd;
- return ss;
-}
-
-/* This function tries to find the SSL layer in the stack.
- * It searches for the first SSL layer at or below the argument fd,
- * and failing that, it searches for the nearest SSL layer above the
- * argument fd. It returns the private sslSocket from the found layer.
- */
-sslSocket *
-ssl_FindSocket(PRFileDesc *fd)
-{
- PRFileDesc *layer;
- sslSocket *ss;
-
- PORT_Assert(fd != NULL);
- PORT_Assert(ssl_layer_id != 0);
-
- layer = PR_GetIdentitiesLayer(fd, ssl_layer_id);
- if (layer == NULL) {
- PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
- return NULL;
- }
-
- ss = (sslSocket *)layer->secret;
- ss->fd = layer;
- return ss;
-}
-
-static sslSocket *
-ssl_DupSocket(sslSocket *os)
-{
- sslSocket *ss;
- SECStatus rv;
-
- ss = ssl_NewSocket((PRBool)(!os->opt.noLocks), os->protocolVariant);
- if (ss) {
- ss->opt = os->opt;
- ss->opt.useSocks = PR_FALSE;
- ss->vrange = os->vrange;
-
- ss->peerID = !os->peerID ? NULL : PORT_Strdup(os->peerID);
- ss->url = !os->url ? NULL : PORT_Strdup(os->url);
-
- ss->ops = os->ops;
- ss->rTimeout = os->rTimeout;
- ss->wTimeout = os->wTimeout;
- ss->cTimeout = os->cTimeout;
- ss->dbHandle = os->dbHandle;
-
- /* copy ssl2&3 policy & prefs, even if it's not selected (yet) */
- ss->allowedByPolicy = os->allowedByPolicy;
- ss->maybeAllowedByPolicy= os->maybeAllowedByPolicy;
- ss->chosenPreference = os->chosenPreference;
- PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);
- PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers,
- sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount);
- ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount;
-
- if (os->cipherSpecs) {
- ss->cipherSpecs = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
- if (ss->cipherSpecs)
- PORT_Memcpy(ss->cipherSpecs, os->cipherSpecs,
- os->sizeCipherSpecs);
- ss->sizeCipherSpecs = os->sizeCipherSpecs;
- ss->preferredCipher = os->preferredCipher;
- } else {
- ss->cipherSpecs = NULL; /* produced lazily */
- ss->sizeCipherSpecs = 0;
- ss->preferredCipher = NULL;
- }
- if (ss->opt.useSecurity) {
- /* This int should be SSLKEAType, but CC on Irix complains,
- * during the for loop.
- */
- int i;
- sslServerCerts * oc = os->serverCerts;
- sslServerCerts * sc = ss->serverCerts;
-
- for (i=kt_null; i < kt_kea_size; i++, oc++, sc++) {
- if (oc->serverCert && oc->serverCertChain) {
- sc->serverCert = CERT_DupCertificate(oc->serverCert);
- sc->serverCertChain = CERT_DupCertList(oc->serverCertChain);
- if (!sc->serverCertChain)
- goto loser;
- } else {
- sc->serverCert = NULL;
- sc->serverCertChain = NULL;
- }
- sc->serverKeyPair = oc->serverKeyPair ?
- ssl3_GetKeyPairRef(oc->serverKeyPair) : NULL;
- if (oc->serverKeyPair && !sc->serverKeyPair)
- goto loser;
- sc->serverKeyBits = oc->serverKeyBits;
- }
- ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :
- ssl3_GetKeyPairRef(os->stepDownKeyPair);
- ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
- ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
- ss->certStatusArray = !os->certStatusArray ? NULL :
- SECITEM_DupArray(NULL, os->certStatusArray);
-/*
- * XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL.
- * XXX We should detect this, and not just march on with NULL pointers.
- */
- ss->authCertificate = os->authCertificate;
- ss->authCertificateArg = os->authCertificateArg;
- ss->getClientAuthData = os->getClientAuthData;
- ss->getClientAuthDataArg = os->getClientAuthDataArg;
- ss->sniSocketConfig = os->sniSocketConfig;
- ss->sniSocketConfigArg = os->sniSocketConfigArg;
- ss->handleBadCert = os->handleBadCert;
- ss->badCertArg = os->badCertArg;
- ss->handshakeCallback = os->handshakeCallback;
- ss->handshakeCallbackData = os->handshakeCallbackData;
- ss->pkcs11PinArg = os->pkcs11PinArg;
-
- /* Create security data */
- rv = ssl_CopySecurityInfo(ss, os);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
- }
- return ss;
-
-loser:
- ssl_FreeSocket(ss);
- return NULL;
-}
-
-static void
-ssl_DestroyLocks(sslSocket *ss)
-{
- /* Destroy locks. */
- if (ss->firstHandshakeLock) {
- PZ_DestroyMonitor(ss->firstHandshakeLock);
- ss->firstHandshakeLock = NULL;
- }
- if (ss->ssl3HandshakeLock) {
- PZ_DestroyMonitor(ss->ssl3HandshakeLock);
- ss->ssl3HandshakeLock = NULL;
- }
- if (ss->specLock) {
- NSSRWLock_Destroy(ss->specLock);
- ss->specLock = NULL;
- }
-
- if (ss->recvLock) {
- PZ_DestroyLock(ss->recvLock);
- ss->recvLock = NULL;
- }
- if (ss->sendLock) {
- PZ_DestroyLock(ss->sendLock);
- ss->sendLock = NULL;
- }
- if (ss->xmitBufLock) {
- PZ_DestroyMonitor(ss->xmitBufLock);
- ss->xmitBufLock = NULL;
- }
- if (ss->recvBufLock) {
- PZ_DestroyMonitor(ss->recvBufLock);
- ss->recvBufLock = NULL;
- }
-}
-
-/* Caller holds any relevant locks */
-static void
-ssl_DestroySocketContents(sslSocket *ss)
-{
- /* "i" should be of type SSLKEAType, but CC on IRIX complains during
- * the for loop.
- */
- int i;
-
- /* Free up socket */
- ssl_DestroySecurityInfo(&ss->sec);
-
- ssl3_DestroySSL3Info(ss);
-
- PORT_Free(ss->saveBuf.buf);
- PORT_Free(ss->pendingBuf.buf);
- ssl_DestroyGather(&ss->gs);
-
- if (ss->peerID != NULL)
- PORT_Free(ss->peerID);
- if (ss->url != NULL)
- PORT_Free((void *)ss->url); /* CONST */
- if (ss->cipherSpecs) {
- PORT_Free(ss->cipherSpecs);
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0;
- }
-
- /* Clean up server configuration */
- for (i=kt_null; i < kt_kea_size; i++) {
- sslServerCerts * sc = ss->serverCerts + i;
- if (sc->serverCert != NULL)
- CERT_DestroyCertificate(sc->serverCert);
- if (sc->serverCertChain != NULL)
- CERT_DestroyCertificateList(sc->serverCertChain);
- if (sc->serverKeyPair != NULL)
- ssl3_FreeKeyPair(sc->serverKeyPair);
- }
- if (ss->stepDownKeyPair) {
- ssl3_FreeKeyPair(ss->stepDownKeyPair);
- ss->stepDownKeyPair = NULL;
- }
- if (ss->ephemeralECDHKeyPair) {
- ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
- ss->ephemeralECDHKeyPair = NULL;
- }
- if (ss->certStatusArray) {
- SECITEM_FreeArray(ss->certStatusArray, PR_TRUE);
- ss->certStatusArray = NULL;
- }
- SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
- PORT_Assert(!ss->xtnData.sniNameArr);
- if (ss->xtnData.sniNameArr) {
- PORT_Free(ss->xtnData.sniNameArr);
- ss->xtnData.sniNameArr = NULL;
- }
-}
-
-/*
- * free an sslSocket struct, and all the stuff that hangs off of it
- */
-void
-ssl_FreeSocket(sslSocket *ss)
-{
-/* Get every lock you can imagine!
-** Caller already holds these:
-** SSL_LOCK_READER(ss);
-** SSL_LOCK_WRITER(ss);
-*/
- ssl_Get1stHandshakeLock(ss);
- ssl_GetRecvBufLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
- ssl_GetXmitBufLock(ss);
- ssl_GetSpecWriteLock(ss);
-
- ssl_DestroySocketContents(ss);
-
- /* Release all the locks acquired above. */
- SSL_UNLOCK_READER(ss);
- SSL_UNLOCK_WRITER(ss);
- ssl_Release1stHandshakeLock(ss);
- ssl_ReleaseRecvBufLock(ss);
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_ReleaseXmitBufLock(ss);
- ssl_ReleaseSpecWriteLock(ss);
-
- ssl_DestroyLocks(ss);
-
-#ifdef DEBUG
- PORT_Memset(ss, 0x1f, sizeof *ss);
-#endif
- PORT_Free(ss);
- return;
-}
-
-/************************************************************************/
-SECStatus
-ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled)
-{
- PRFileDesc * osfd = ss->fd->lower;
- SECStatus rv = SECFailure;
- PRSocketOptionData opt;
-
- opt.option = PR_SockOpt_NoDelay;
- opt.value.no_delay = (PRBool)!enabled;
-
- if (osfd->methods->setsocketoption) {
- rv = (SECStatus) osfd->methods->setsocketoption(osfd, &opt);
- } else {
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- }
-
- return rv;
-}
-
-static void
-ssl_ChooseOps(sslSocket *ss)
-{
- ss->ops = ss->opt.useSecurity ? &ssl_secure_ops : &ssl_default_ops;
-}
-
-/* Called from SSL_Enable (immediately below) */
-static SECStatus
-PrepareSocket(sslSocket *ss)
-{
- SECStatus rv = SECSuccess;
-
- ssl_ChooseOps(ss);
- return rv;
-}
-
-SECStatus
-SSL_Enable(PRFileDesc *fd, int which, PRBool on)
-{
- return SSL_OptionSet(fd, which, on);
-}
-
-#ifndef NO_PKCS11_BYPASS
-static const PRCallOnceType pristineCallOnce;
-static PRCallOnceType setupBypassOnce;
-
-static SECStatus SSL_BypassShutdown(void* appData, void* nssData)
-{
- /* unload freeBL shared library from memory */
- BL_Unload();
- setupBypassOnce = pristineCallOnce;
- return SECSuccess;
-}
-
-static PRStatus SSL_BypassRegisterShutdown(void)
-{
- SECStatus rv = NSS_RegisterShutdown(SSL_BypassShutdown, NULL);
- PORT_Assert(SECSuccess == rv);
- return SECSuccess == rv ? PR_SUCCESS : PR_FAILURE;
-}
-#endif
-
-static PRStatus SSL_BypassSetup(void)
-{
-#ifdef NO_PKCS11_BYPASS
- /* Guarantee binary compatibility */
- return PR_SUCCESS;
-#else
- return PR_CallOnce(&setupBypassOnce, &SSL_BypassRegisterShutdown);
-#endif
-}
-
-/* Implements the semantics for SSL_OptionSet(SSL_ENABLE_TLS, on) described in
- * ssl.h in the section "SSL version range setting API".
- */
-static void
-ssl_EnableTLS(SSLVersionRange *vrange, PRBool on)
-{
- if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
- if (on) {
- vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
- vrange->max = SSL_LIBRARY_VERSION_TLS_1_0;
- } /* else don't change anything */
- return;
- }
-
- if (on) {
- /* Expand the range of enabled version to include TLS 1.0 */
- vrange->min = PR_MIN(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
- vrange->max = PR_MAX(vrange->max, SSL_LIBRARY_VERSION_TLS_1_0);
- } else {
- /* Disable all TLS versions, leaving only SSL 3.0 if it was enabled */
- if (vrange->min == SSL_LIBRARY_VERSION_3_0) {
- vrange->max = SSL_LIBRARY_VERSION_3_0;
- } else {
- /* Only TLS was enabled, so now no versions are. */
- vrange->min = SSL_LIBRARY_VERSION_NONE;
- vrange->max = SSL_LIBRARY_VERSION_NONE;
- }
- }
-}
-
-/* Implements the semantics for SSL_OptionSet(SSL_ENABLE_SSL3, on) described in
- * ssl.h in the section "SSL version range setting API".
- */
-static void
-ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on)
-{
- if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
- if (on) {
- vrange->min = SSL_LIBRARY_VERSION_3_0;
- vrange->max = SSL_LIBRARY_VERSION_3_0;
- } /* else don't change anything */
- return;
- }
-
- if (on) {
- /* Expand the range of enabled versions to include SSL 3.0. We know
- * SSL 3.0 or some version of TLS is already enabled at this point, so
- * we don't need to change vrange->max.
- */
- vrange->min = SSL_LIBRARY_VERSION_3_0;
- } else {
- /* Disable SSL 3.0, leaving TLS unaffected. */
- if (vrange->max > SSL_LIBRARY_VERSION_3_0) {
- vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
- } else {
- /* Only SSL 3.0 was enabled, so now no versions are. */
- vrange->min = SSL_LIBRARY_VERSION_NONE;
- vrange->max = SSL_LIBRARY_VERSION_NONE;
- }
- }
-}
-
-SECStatus
-SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
-{
- sslSocket *ss = ssl_FindSocket(fd);
- SECStatus rv = SECSuccess;
- PRBool holdingLocks;
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
- return SECFailure;
- }
-
- holdingLocks = (!ss->opt.noLocks);
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- switch (which) {
- case SSL_SOCKS:
- ss->opt.useSocks = PR_FALSE;
- rv = PrepareSocket(ss);
- if (on) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
- break;
-
- case SSL_SECURITY:
- ss->opt.useSecurity = on;
- rv = PrepareSocket(ss);
- break;
-
- case SSL_REQUEST_CERTIFICATE:
- ss->opt.requestCertificate = on;
- break;
-
- case SSL_REQUIRE_CERTIFICATE:
- ss->opt.requireCertificate = on;
- break;
-
- case SSL_HANDSHAKE_AS_CLIENT:
- if ( ss->opt.handshakeAsServer && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- break;
- }
- ss->opt.handshakeAsClient = on;
- break;
-
- case SSL_HANDSHAKE_AS_SERVER:
- if ( ss->opt.handshakeAsClient && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- break;
- }
- ss->opt.handshakeAsServer = on;
- break;
-
- case SSL_ENABLE_TLS:
- if (IS_DTLS(ss)) {
- if (on) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure; /* not allowed */
- }
- break;
- }
- ssl_EnableTLS(&ss->vrange, on);
- ss->preferredCipher = NULL;
- if (ss->cipherSpecs) {
- PORT_Free(ss->cipherSpecs);
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0;
- }
- break;
-
- case SSL_ENABLE_SSL3:
- if (IS_DTLS(ss)) {
- if (on) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure; /* not allowed */
- }
- break;
- }
- ssl_EnableSSL3(&ss->vrange, on);
- ss->preferredCipher = NULL;
- if (ss->cipherSpecs) {
- PORT_Free(ss->cipherSpecs);
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0;
- }
- break;
-
- case SSL_ENABLE_SSL2:
- if (IS_DTLS(ss)) {
- if (on) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure; /* not allowed */
- }
- break;
- }
- ss->opt.enableSSL2 = on;
- if (on) {
- ss->opt.v2CompatibleHello = on;
- }
- ss->preferredCipher = NULL;
- if (ss->cipherSpecs) {
- PORT_Free(ss->cipherSpecs);
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0;
- }
- break;
-
- case SSL_NO_CACHE:
- ss->opt.noCache = on;
- break;
-
- case SSL_ENABLE_FDX:
- if (on && ss->opt.noLocks) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
- ss->opt.fdx = on;
- break;
-
- case SSL_V2_COMPATIBLE_HELLO:
- if (IS_DTLS(ss)) {
- if (on) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure; /* not allowed */
- }
- break;
- }
- ss->opt.v2CompatibleHello = on;
- if (!on) {
- ss->opt.enableSSL2 = on;
- }
- break;
-
- case SSL_ROLLBACK_DETECTION:
- ss->opt.detectRollBack = on;
- break;
-
- case SSL_NO_STEP_DOWN:
- ss->opt.noStepDown = on;
- if (on)
- SSL_DisableExportCipherSuites(fd);
- break;
-
- case SSL_BYPASS_PKCS11:
- if (ss->handshakeBegun) {
- PORT_SetError(PR_INVALID_STATE_ERROR);
- rv = SECFailure;
- } else {
- if (PR_FALSE != on) {
- if (PR_SUCCESS == SSL_BypassSetup() ) {
-#ifdef NO_PKCS11_BYPASS
- ss->opt.bypassPKCS11 = PR_FALSE;
-#else
- ss->opt.bypassPKCS11 = on;
-#endif
- } else {
- rv = SECFailure;
- }
- } else {
- ss->opt.bypassPKCS11 = PR_FALSE;
- }
- }
- break;
-
- case SSL_NO_LOCKS:
- if (on && ss->opt.fdx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
- if (on && ssl_force_locks)
- on = PR_FALSE; /* silent override */
- ss->opt.noLocks = on;
- if (on) {
- locksEverDisabled = PR_TRUE;
- strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
- } else if (!holdingLocks) {
- rv = ssl_MakeLocks(ss);
- if (rv != SECSuccess) {
- ss->opt.noLocks = PR_TRUE;
- }
- }
- break;
-
- case SSL_ENABLE_SESSION_TICKETS:
- ss->opt.enableSessionTickets = on;
- break;
-
- case SSL_ENABLE_DEFLATE:
- ss->opt.enableDeflate = on;
- break;
-
- case SSL_ENABLE_RENEGOTIATION:
- ss->opt.enableRenegotiation = on;
- break;
-
- case SSL_REQUIRE_SAFE_NEGOTIATION:
- ss->opt.requireSafeNegotiation = on;
- break;
-
- case SSL_ENABLE_FALSE_START:
- ss->opt.enableFalseStart = on;
- break;
-
- case SSL_CBC_RANDOM_IV:
- ss->opt.cbcRandomIV = on;
- break;
-
- case SSL_ENABLE_OCSP_STAPLING:
- ss->opt.enableOCSPStapling = on;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
-
- /* We can't use the macros for releasing the locks here,
- * because ss->opt.noLocks might have changed just above.
- * We must release these locks (monitors) here, if we aquired them above,
- * regardless of the current value of ss->opt.noLocks.
- */
- if (holdingLocks) {
- PZ_ExitMonitor((ss)->ssl3HandshakeLock);
- PZ_ExitMonitor((ss)->firstHandshakeLock);
- }
-
- return rv;
-}
-
-SECStatus
-SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
-{
- sslSocket *ss = ssl_FindSocket(fd);
- SECStatus rv = SECSuccess;
- PRBool on = PR_FALSE;
-
- if (!pOn) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
- *pOn = PR_FALSE;
- return SECFailure;
- }
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- switch (which) {
- case SSL_SOCKS: on = PR_FALSE; break;
- case SSL_SECURITY: on = ss->opt.useSecurity; break;
- case SSL_REQUEST_CERTIFICATE: on = ss->opt.requestCertificate; break;
- case SSL_REQUIRE_CERTIFICATE: on = ss->opt.requireCertificate; break;
- case SSL_HANDSHAKE_AS_CLIENT: on = ss->opt.handshakeAsClient; break;
- case SSL_HANDSHAKE_AS_SERVER: on = ss->opt.handshakeAsServer; break;
- case SSL_ENABLE_TLS:
- on = ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_0;
- break;
- case SSL_ENABLE_SSL3:
- on = ss->vrange.min == SSL_LIBRARY_VERSION_3_0;
- break;
- case SSL_ENABLE_SSL2: on = ss->opt.enableSSL2; break;
- case SSL_NO_CACHE: on = ss->opt.noCache; break;
- case SSL_ENABLE_FDX: on = ss->opt.fdx; break;
- case SSL_V2_COMPATIBLE_HELLO: on = ss->opt.v2CompatibleHello; break;
- case SSL_ROLLBACK_DETECTION: on = ss->opt.detectRollBack; break;
- case SSL_NO_STEP_DOWN: on = ss->opt.noStepDown; break;
- case SSL_BYPASS_PKCS11: on = ss->opt.bypassPKCS11; break;
- case SSL_NO_LOCKS: on = ss->opt.noLocks; break;
- case SSL_ENABLE_SESSION_TICKETS:
- on = ss->opt.enableSessionTickets;
- break;
- case SSL_ENABLE_DEFLATE: on = ss->opt.enableDeflate; break;
- case SSL_ENABLE_RENEGOTIATION:
- on = ss->opt.enableRenegotiation; break;
- case SSL_REQUIRE_SAFE_NEGOTIATION:
- on = ss->opt.requireSafeNegotiation; break;
- case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break;
- case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break;
- case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- *pOn = on;
- return rv;
-}
-
-SECStatus
-SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
-{
- SECStatus rv = SECSuccess;
- PRBool on = PR_FALSE;
-
- if (!pOn) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- ssl_SetDefaultsFromEnvironment();
-
- switch (which) {
- case SSL_SOCKS: on = PR_FALSE; break;
- case SSL_SECURITY: on = ssl_defaults.useSecurity; break;
- case SSL_REQUEST_CERTIFICATE: on = ssl_defaults.requestCertificate; break;
- case SSL_REQUIRE_CERTIFICATE: on = ssl_defaults.requireCertificate; break;
- case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient; break;
- case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer; break;
- case SSL_ENABLE_TLS:
- on = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0;
- break;
- case SSL_ENABLE_SSL3:
- on = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0;
- break;
- case SSL_ENABLE_SSL2: on = ssl_defaults.enableSSL2; break;
- case SSL_NO_CACHE: on = ssl_defaults.noCache; break;
- case SSL_ENABLE_FDX: on = ssl_defaults.fdx; break;
- case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello; break;
- case SSL_ROLLBACK_DETECTION: on = ssl_defaults.detectRollBack; break;
- case SSL_NO_STEP_DOWN: on = ssl_defaults.noStepDown; break;
- case SSL_BYPASS_PKCS11: on = ssl_defaults.bypassPKCS11; break;
- case SSL_NO_LOCKS: on = ssl_defaults.noLocks; break;
- case SSL_ENABLE_SESSION_TICKETS:
- on = ssl_defaults.enableSessionTickets;
- break;
- case SSL_ENABLE_DEFLATE: on = ssl_defaults.enableDeflate; break;
- case SSL_ENABLE_RENEGOTIATION:
- on = ssl_defaults.enableRenegotiation; break;
- case SSL_REQUIRE_SAFE_NEGOTIATION:
- on = ssl_defaults.requireSafeNegotiation;
- break;
- case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break;
- case SSL_CBC_RANDOM_IV: on = ssl_defaults.cbcRandomIV; break;
- case SSL_ENABLE_OCSP_STAPLING:
- on = ssl_defaults.enableOCSPStapling;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
-
- *pOn = on;
- return rv;
-}
-
-/* XXX Use Global Lock to protect this stuff. */
-SECStatus
-SSL_EnableDefault(int which, PRBool on)
-{
- return SSL_OptionSetDefault(which, on);
-}
-
-SECStatus
-SSL_OptionSetDefault(PRInt32 which, PRBool on)
-{
- SECStatus status = ssl_Init();
-
- if (status != SECSuccess) {
- return status;
- }
-
- ssl_SetDefaultsFromEnvironment();
-
- switch (which) {
- case SSL_SOCKS:
- ssl_defaults.useSocks = PR_FALSE;
- if (on) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- break;
-
- case SSL_SECURITY:
- ssl_defaults.useSecurity = on;
- break;
-
- case SSL_REQUEST_CERTIFICATE:
- ssl_defaults.requestCertificate = on;
- break;
-
- case SSL_REQUIRE_CERTIFICATE:
- ssl_defaults.requireCertificate = on;
- break;
-
- case SSL_HANDSHAKE_AS_CLIENT:
- if ( ssl_defaults.handshakeAsServer && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- ssl_defaults.handshakeAsClient = on;
- break;
-
- case SSL_HANDSHAKE_AS_SERVER:
- if ( ssl_defaults.handshakeAsClient && on ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- ssl_defaults.handshakeAsServer = on;
- break;
-
- case SSL_ENABLE_TLS:
- ssl_EnableTLS(&versions_defaults_stream, on);
- break;
-
- case SSL_ENABLE_SSL3:
- ssl_EnableSSL3(&versions_defaults_stream, on);
- break;
-
- case SSL_ENABLE_SSL2:
- ssl_defaults.enableSSL2 = on;
- if (on) {
- ssl_defaults.v2CompatibleHello = on;
- }
- break;
-
- case SSL_NO_CACHE:
- ssl_defaults.noCache = on;
- break;
-
- case SSL_ENABLE_FDX:
- if (on && ssl_defaults.noLocks) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- ssl_defaults.fdx = on;
- break;
-
- case SSL_V2_COMPATIBLE_HELLO:
- ssl_defaults.v2CompatibleHello = on;
- if (!on) {
- ssl_defaults.enableSSL2 = on;
- }
- break;
-
- case SSL_ROLLBACK_DETECTION:
- ssl_defaults.detectRollBack = on;
- break;
-
- case SSL_NO_STEP_DOWN:
- ssl_defaults.noStepDown = on;
- if (on)
- SSL_DisableDefaultExportCipherSuites();
- break;
-
- case SSL_BYPASS_PKCS11:
- if (PR_FALSE != on) {
- if (PR_SUCCESS == SSL_BypassSetup()) {
-#ifdef NO_PKCS11_BYPASS
- ssl_defaults.bypassPKCS11 = PR_FALSE;
-#else
- ssl_defaults.bypassPKCS11 = on;
-#endif
- } else {
- return SECFailure;
- }
- } else {
- ssl_defaults.bypassPKCS11 = PR_FALSE;
- }
- break;
-
- case SSL_NO_LOCKS:
- if (on && ssl_defaults.fdx) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (on && ssl_force_locks)
- on = PR_FALSE; /* silent override */
- ssl_defaults.noLocks = on;
- if (on) {
- locksEverDisabled = PR_TRUE;
- strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
- }
- break;
-
- case SSL_ENABLE_SESSION_TICKETS:
- ssl_defaults.enableSessionTickets = on;
- break;
-
- case SSL_ENABLE_DEFLATE:
- ssl_defaults.enableDeflate = on;
- break;
-
- case SSL_ENABLE_RENEGOTIATION:
- ssl_defaults.enableRenegotiation = on;
- break;
-
- case SSL_REQUIRE_SAFE_NEGOTIATION:
- ssl_defaults.requireSafeNegotiation = on;
- break;
-
- case SSL_ENABLE_FALSE_START:
- ssl_defaults.enableFalseStart = on;
- break;
-
- case SSL_CBC_RANDOM_IV:
- ssl_defaults.cbcRandomIV = on;
- break;
-
- case SSL_ENABLE_OCSP_STAPLING:
- ssl_defaults.enableOCSPStapling = on;
- break;
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-/* function tells us if the cipher suite is one that we no longer support. */
-static PRBool
-ssl_IsRemovedCipherSuite(PRInt32 suite)
-{
- switch (suite) {
- case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
- case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
- case SSL_FORTEZZA_DMS_WITH_RC4_128_SHA:
- return PR_TRUE;
- default:
- return PR_FALSE;
- }
-}
-
-/* Part of the public NSS API.
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this. Probably want a global lock.
- */
-SECStatus
-SSL_SetPolicy(long which, int policy)
-{
- if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
- /* one of the two old FIPS ciphers */
- if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
- which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
- else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
- which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
- }
- if (ssl_IsRemovedCipherSuite(which))
- return SECSuccess;
- return SSL_CipherPolicySet(which, policy);
-}
-
-SECStatus
-SSL_CipherPolicySet(PRInt32 which, PRInt32 policy)
-{
- SECStatus rv = ssl_Init();
-
- if (rv != SECSuccess) {
- return rv;
- }
-
- if (ssl_IsRemovedCipherSuite(which)) {
- rv = SECSuccess;
- } else if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_SetPolicy(which, policy);
- } else {
- rv = ssl3_SetPolicy((ssl3CipherSuite)which, policy);
- }
- return rv;
-}
-
-SECStatus
-SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
-{
- SECStatus rv;
-
- if (!oPolicy) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (ssl_IsRemovedCipherSuite(which)) {
- *oPolicy = SSL_NOT_ALLOWED;
- rv = SECSuccess;
- } else if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_GetPolicy(which, oPolicy);
- } else {
- rv = ssl3_GetPolicy((ssl3CipherSuite)which, oPolicy);
- }
- return rv;
-}
-
-/* Part of the public NSS API.
- * Since this is a global (not per-socket) setting, we cannot use the
- * HandshakeLock to protect this. Probably want a global lock.
- * These changes have no effect on any sslSockets already created.
- */
-SECStatus
-SSL_EnableCipher(long which, PRBool enabled)
-{
- if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
- /* one of the two old FIPS ciphers */
- if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
- which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
- else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
- which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
- }
- if (ssl_IsRemovedCipherSuite(which))
- return SECSuccess;
- return SSL_CipherPrefSetDefault(which, enabled);
-}
-
-SECStatus
-SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
-{
- SECStatus rv = ssl_Init();
-
- if (rv != SECSuccess) {
- return rv;
- }
-
- if (ssl_IsRemovedCipherSuite(which))
- return SECSuccess;
- if (enabled && ssl_defaults.noStepDown && SSL_IsExportCipherSuite(which)) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
- if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_CipherPrefSetDefault(which, enabled);
- } else {
- rv = ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
- }
- return rv;
-}
-
-SECStatus
-SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
-{
- SECStatus rv;
-
- if (!enabled) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (ssl_IsRemovedCipherSuite(which)) {
- *enabled = PR_FALSE;
- rv = SECSuccess;
- } else if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_CipherPrefGetDefault(which, enabled);
- } else {
- rv = ssl3_CipherPrefGetDefault((ssl3CipherSuite)which, enabled);
- }
- return rv;
-}
-
-SECStatus
-SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
-{
- SECStatus rv;
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd));
- return SECFailure;
- }
- if (ssl_IsRemovedCipherSuite(which))
- return SECSuccess;
- if (enabled && ss->opt.noStepDown && SSL_IsExportCipherSuite(which)) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
- if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_CipherPrefSet(ss, which, enabled);
- } else {
- rv = ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
- }
- return rv;
-}
-
-SECStatus
-SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
-{
- SECStatus rv;
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!enabled) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefGet", SSL_GETPID(), fd));
- *enabled = PR_FALSE;
- return SECFailure;
- }
- if (ssl_IsRemovedCipherSuite(which)) {
- *enabled = PR_FALSE;
- rv = SECSuccess;
- } else if (SSL_IS_SSL2_CIPHER(which)) {
- rv = ssl2_CipherPrefGet(ss, which, enabled);
- } else {
- rv = ssl3_CipherPrefGet(ss, (ssl3CipherSuite)which, enabled);
- }
- return rv;
-}
-
-SECStatus
-NSS_SetDomesticPolicy(void)
-{
- SECStatus status = SECSuccess;
- cipherPolicy * policy;
-
- for (policy = ssl_ciphers; policy->cipher != 0; ++policy) {
- status = SSL_SetPolicy(policy->cipher, SSL_ALLOWED);
- if (status != SECSuccess)
- break;
- }
- return status;
-}
-
-SECStatus
-NSS_SetExportPolicy(void)
-{
- return NSS_SetDomesticPolicy();
-}
-
-SECStatus
-NSS_SetFrancePolicy(void)
-{
- return NSS_SetDomesticPolicy();
-}
-
-
-
-/* LOCKS ??? XXX */
-static PRFileDesc *
-ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
-{
- sslSocket * ns = NULL;
- PRStatus rv;
- PRNetAddr addr;
- SECStatus status = ssl_Init();
-
- if (status != SECSuccess) {
- return NULL;
- }
-
- if (model == NULL) {
- /* Just create a default socket if we're given NULL for the model */
- ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks), variant);
- } else {
- sslSocket * ss = ssl_FindSocket(model);
- if (ss == NULL || ss->protocolVariant != variant) {
- SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD",
- SSL_GETPID(), model));
- return NULL;
- }
- ns = ssl_DupSocket(ss);
- }
- if (ns == NULL)
- return NULL;
-
- rv = ssl_PushIOLayer(ns, fd, PR_TOP_IO_LAYER);
- if (rv != PR_SUCCESS) {
- ssl_FreeSocket(ns);
- SET_ERROR_CODE
- return NULL;
- }
-#ifdef _WIN32
- PR_Sleep(PR_INTERVAL_NO_WAIT); /* workaround NT winsock connect bug. */
-#endif
- ns = ssl_FindSocket(fd);
- PORT_Assert(ns);
- if (ns)
- ns->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ns, &addr));
- return fd;
-}
-
-PRFileDesc *
-SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
-{
- return ssl_ImportFD(model, fd, ssl_variant_stream);
-}
-
-PRFileDesc *
-DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd)
-{
- return ssl_ImportFD(model, fd, ssl_variant_datagram);
-}
-
-SECStatus
-SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
- void *arg)
-{
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoCallback", SSL_GETPID(),
- fd));
- return SECFailure;
- }
-
- ssl_GetSSL3HandshakeLock(ss);
- ss->nextProtoCallback = callback;
- ss->nextProtoArg = arg;
- ssl_ReleaseSSL3HandshakeLock(ss);
-
- return SECSuccess;
-}
-
-/* ssl_NextProtoNegoCallback is set as an NPN callback for the case when
- * SSL_SetNextProtoNego is used.
- */
-static SECStatus
-ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
- const unsigned char *protos, unsigned int protos_len,
- unsigned char *protoOut, unsigned int *protoOutLen,
- unsigned int protoMaxLen)
-{
- unsigned int i, j;
- const unsigned char *result;
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in ssl_NextProtoNegoCallback",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (protos_len == 0) {
- /* The server supports the extension, but doesn't have any protocols
- * configured. In this case we request our favoured protocol. */
- goto pick_first;
- }
-
- /* For each protocol in server preference, see if we support it. */
- for (i = 0; i < protos_len; ) {
- for (j = 0; j < ss->opt.nextProtoNego.len; ) {
- if (protos[i] == ss->opt.nextProtoNego.data[j] &&
- PORT_Memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1],
- protos[i]) == 0) {
- /* We found a match. */
- ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
- result = &protos[i];
- goto found;
- }
- j += 1 + (unsigned int)ss->opt.nextProtoNego.data[j];
- }
- i += 1 + (unsigned int)protos[i];
- }
-
-pick_first:
- ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
- result = ss->opt.nextProtoNego.data;
-
-found:
- if (protoMaxLen < result[0]) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- memcpy(protoOut, result + 1, result[0]);
- *protoOutLen = result[0];
- return SECSuccess;
-}
-
-SECStatus
-SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
- unsigned int length)
-{
- sslSocket *ss;
- SECStatus rv;
- SECItem dataItem = { siBuffer, (unsigned char *) data, length };
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess)
- return SECFailure;
-
- ssl_GetSSL3HandshakeLock(ss);
- SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
- rv = SECITEM_CopyItem(NULL, &ss->opt.nextProtoNego, &dataItem);
- ssl_ReleaseSSL3HandshakeLock(ss);
-
- if (rv != SECSuccess)
- return rv;
-
- return SSL_SetNextProtoCallback(fd, ssl_NextProtoNegoCallback, NULL);
-}
-
-SECStatus
-SSL_GetNextProto(PRFileDesc *fd, SSLNextProtoState *state, unsigned char *buf,
- unsigned int *bufLen, unsigned int bufLenMax)
-{
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(),
- fd));
- return SECFailure;
- }
-
- if (!state || !buf || !bufLen) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- *state = ss->ssl3.nextProtoState;
-
- if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
- ss->ssl3.nextProto.data) {
- if (ss->ssl3.nextProto.len > bufLenMax) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- PORT_Memcpy(buf, ss->ssl3.nextProto.data, ss->ssl3.nextProto.len);
- *bufLen = ss->ssl3.nextProto.len;
- } else {
- *bufLen = 0;
- }
-
- return SECSuccess;
-}
-
-SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
- const PRUint16 *ciphers,
- unsigned int numCiphers)
-{
- sslSocket *ss;
- unsigned int i;
-
- ss = ssl_FindSocket(fd);
- if (!ss || !IS_DTLS(ss)) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSRTPCiphers",
- SSL_GETPID(), fd));
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (numCiphers > MAX_DTLS_SRTP_CIPHER_SUITES) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- ss->ssl3.dtlsSRTPCipherCount = 0;
- for (i = 0; i < numCiphers; i++) {
- const PRUint16 *srtpCipher = srtpCiphers;
-
- while (*srtpCipher) {
- if (ciphers[i] == *srtpCipher)
- break;
- srtpCipher++;
- }
- if (*srtpCipher) {
- ss->ssl3.dtlsSRTPCiphers[ss->ssl3.dtlsSRTPCipherCount++] =
- ciphers[i];
- } else {
- SSL_DBG(("%d: SSL[%d]: invalid or unimplemented SRTP cipher "
- "suite specified: 0x%04hx", SSL_GETPID(), fd,
- ciphers[i]));
- }
- }
-
- if (ss->ssl3.dtlsSRTPCipherCount == 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-SECStatus
-SSL_GetSRTPCipher(PRFileDesc *fd, PRUint16 *cipher)
-{
- sslSocket * ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetSRTPCipher",
- SSL_GETPID(), fd));
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (!ss->ssl3.dtlsSRTPCipherSuite) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- *cipher = ss->ssl3.dtlsSRTPCipherSuite;
- return SECSuccess;
-}
-
-PRFileDesc *
-SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
-{
- sslSocket * sm = NULL, *ss = NULL;
- int i;
- sslServerCerts * mc = NULL;
- sslServerCerts * sc = NULL;
-
- if (model == NULL) {
- PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
- return NULL;
- }
- sm = ssl_FindSocket(model);
- if (sm == NULL) {
- SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ReconfigFD",
- SSL_GETPID(), model));
- return NULL;
- }
- ss = ssl_FindSocket(fd);
- PORT_Assert(ss);
- if (ss == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- ss->opt = sm->opt;
- ss->vrange = sm->vrange;
- PORT_Memcpy(ss->cipherSuites, sm->cipherSuites, sizeof sm->cipherSuites);
- PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers,
- sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount);
- ss->ssl3.dtlsSRTPCipherCount = sm->ssl3.dtlsSRTPCipherCount;
-
- if (!ss->opt.useSecurity) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
- /* This int should be SSLKEAType, but CC on Irix complains,
- * during the for loop.
- */
- for (i=kt_null; i < kt_kea_size; i++) {
- mc = &(sm->serverCerts[i]);
- sc = &(ss->serverCerts[i]);
- if (mc->serverCert && mc->serverCertChain) {
- if (sc->serverCert) {
- CERT_DestroyCertificate(sc->serverCert);
- }
- sc->serverCert = CERT_DupCertificate(mc->serverCert);
- if (sc->serverCertChain) {
- CERT_DestroyCertificateList(sc->serverCertChain);
- }
- sc->serverCertChain = CERT_DupCertList(mc->serverCertChain);
- if (!sc->serverCertChain)
- goto loser;
- }
- if (mc->serverKeyPair) {
- if (sc->serverKeyPair) {
- ssl3_FreeKeyPair(sc->serverKeyPair);
- }
- sc->serverKeyPair = ssl3_GetKeyPairRef(mc->serverKeyPair);
- sc->serverKeyBits = mc->serverKeyBits;
- }
- }
- if (sm->stepDownKeyPair) {
- if (ss->stepDownKeyPair) {
- ssl3_FreeKeyPair(ss->stepDownKeyPair);
- }
- ss->stepDownKeyPair = ssl3_GetKeyPairRef(sm->stepDownKeyPair);
- }
- if (sm->ephemeralECDHKeyPair) {
- if (ss->ephemeralECDHKeyPair) {
- ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
- }
- ss->ephemeralECDHKeyPair =
- ssl3_GetKeyPairRef(sm->ephemeralECDHKeyPair);
- }
- if (sm->certStatusArray) {
- if (ss->certStatusArray) {
- SECITEM_FreeArray(ss->certStatusArray, PR_TRUE);
- ss->certStatusArray = NULL;
- }
- ss->certStatusArray = SECITEM_DupArray(NULL, sm->certStatusArray);
- }
- /* copy trust anchor names */
- if (sm->ssl3.ca_list) {
- if (ss->ssl3.ca_list) {
- CERT_FreeDistNames(ss->ssl3.ca_list);
- }
- ss->ssl3.ca_list = CERT_DupDistNames(sm->ssl3.ca_list);
- if (!ss->ssl3.ca_list) {
- goto loser;
- }
- }
-
- if (sm->authCertificate)
- ss->authCertificate = sm->authCertificate;
- if (sm->authCertificateArg)
- ss->authCertificateArg = sm->authCertificateArg;
- if (sm->getClientAuthData)
- ss->getClientAuthData = sm->getClientAuthData;
- if (sm->getClientAuthDataArg)
- ss->getClientAuthDataArg = sm->getClientAuthDataArg;
- if (sm->sniSocketConfig)
- ss->sniSocketConfig = sm->sniSocketConfig;
- if (sm->sniSocketConfigArg)
- ss->sniSocketConfigArg = sm->sniSocketConfigArg;
- if (sm->handleBadCert)
- ss->handleBadCert = sm->handleBadCert;
- if (sm->badCertArg)
- ss->badCertArg = sm->badCertArg;
- if (sm->handshakeCallback)
- ss->handshakeCallback = sm->handshakeCallback;
- if (sm->handshakeCallbackData)
- ss->handshakeCallbackData = sm->handshakeCallbackData;
- if (sm->pkcs11PinArg)
- ss->pkcs11PinArg = sm->pkcs11PinArg;
- return fd;
-loser:
- return NULL;
-}
-
-PRBool
-ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
- SSL3ProtocolVersion version)
-{
- switch (protocolVariant) {
- case ssl_variant_stream:
- return (version >= SSL_LIBRARY_VERSION_3_0 &&
- version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
- case ssl_variant_datagram:
- return (version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
- version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
- default:
- /* Can't get here */
- PORT_Assert(PR_FALSE);
- return PR_FALSE;
- }
-}
-
-/* Returns PR_TRUE if the given version range is valid and
-** fully supported; otherwise, returns PR_FALSE.
-*/
-static PRBool
-ssl3_VersionRangeIsValid(SSLProtocolVariant protocolVariant,
- const SSLVersionRange *vrange)
-{
- return vrange &&
- vrange->min <= vrange->max &&
- ssl3_VersionIsSupported(protocolVariant, vrange->min) &&
- ssl3_VersionIsSupported(protocolVariant, vrange->max);
-}
-
-SECStatus
-SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
- SSLVersionRange *vrange)
-{
- if (!vrange) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- switch (protocolVariant) {
- case ssl_variant_stream:
- vrange->min = SSL_LIBRARY_VERSION_3_0;
- vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
- break;
- case ssl_variant_datagram:
- vrange->min = SSL_LIBRARY_VERSION_TLS_1_1;
- vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-SECStatus
-SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
- SSLVersionRange *vrange)
-{
- if ((protocolVariant != ssl_variant_stream &&
- protocolVariant != ssl_variant_datagram) || !vrange) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- *vrange = *VERSIONS_DEFAULTS(protocolVariant);
-
- return SECSuccess;
-}
-
-SECStatus
-SSL_VersionRangeSetDefault(SSLProtocolVariant protocolVariant,
- const SSLVersionRange *vrange)
-{
- if (!ssl3_VersionRangeIsValid(protocolVariant, vrange)) {
- PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
- return SECFailure;
- }
-
- *VERSIONS_DEFAULTS(protocolVariant) = *vrange;
-
- return SECSuccess;
-}
-
-SECStatus
-SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange)
-{
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeGet",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (!vrange) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- *vrange = ss->vrange;
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return SECSuccess;
-}
-
-SECStatus
-SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
-{
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeSet",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (!ssl3_VersionRangeIsValid(ss->protocolVariant, vrange)) {
- PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
- return SECFailure;
- }
-
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- ss->vrange = *vrange;
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
-
- return SECSuccess;
-}
-
-const SECItemArray *
-SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
-{
- sslSocket *ss = ssl_FindSocket(fd);
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerStapledOCSPResponses",
- SSL_GETPID(), fd));
- return NULL;
- }
-
- if (!ss->sec.ci.sid) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return NULL;
- }
-
- return &ss->sec.ci.sid->peerCertStatus;
-}
-
-/************************************************************************/
-/* The following functions are the TOP LEVEL SSL functions.
-** They all get called through the NSPRIOMethods table below.
-*/
-
-static PRFileDesc * PR_CALLBACK
-ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
-{
- sslSocket *ss;
- sslSocket *ns = NULL;
- PRFileDesc *newfd = NULL;
- PRFileDesc *osfd;
- PRStatus status;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in accept", SSL_GETPID(), fd));
- return NULL;
- }
-
- /* IF this is a listen socket, there shouldn't be any I/O going on */
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
- ssl_Get1stHandshakeLock(ss);
- ssl_GetSSL3HandshakeLock(ss);
-
- ss->cTimeout = timeout;
-
- osfd = ss->fd->lower;
-
- /* First accept connection */
- newfd = osfd->methods->accept(osfd, sockaddr, timeout);
- if (newfd == NULL) {
- SSL_DBG(("%d: SSL[%d]: accept failed, errno=%d",
- SSL_GETPID(), ss->fd, PORT_GetError()));
- } else {
- /* Create ssl module */
- ns = ssl_DupSocket(ss);
- }
-
- ssl_ReleaseSSL3HandshakeLock(ss);
- ssl_Release1stHandshakeLock(ss);
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss); /* ss isn't used below here. */
-
- if (ns == NULL)
- goto loser;
-
- /* push ssl module onto the new socket */
- status = ssl_PushIOLayer(ns, newfd, PR_TOP_IO_LAYER);
- if (status != PR_SUCCESS)
- goto loser;
-
- /* Now start server connection handshake with client.
- ** Don't need locks here because nobody else has a reference to ns yet.
- */
- if ( ns->opt.useSecurity ) {
- if ( ns->opt.handshakeAsClient ) {
- ns->handshake = ssl2_BeginClientHandshake;
- ss->handshaking = sslHandshakingAsClient;
- } else {
- ns->handshake = ssl2_BeginServerHandshake;
- ss->handshaking = sslHandshakingAsServer;
- }
- }
- ns->TCPconnected = 1;
- return newfd;
-
-loser:
- if (ns != NULL)
- ssl_FreeSocket(ns);
- if (newfd != NULL)
- PR_Close(newfd);
- return NULL;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Connect(PRFileDesc *fd, const PRNetAddr *sockaddr, PRIntervalTime timeout)
-{
- sslSocket *ss;
- PRStatus rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in connect", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
-
- /* IF this is a listen socket, there shouldn't be any I/O going on */
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- ss->cTimeout = timeout;
- rv = (PRStatus)(*ss->ops->connect)(ss, sockaddr);
-#ifdef _WIN32
- PR_Sleep(PR_INTERVAL_NO_WAIT); /* workaround NT winsock connect bug. */
-#endif
-
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss);
-
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Bind(PRFileDesc *fd, const PRNetAddr *addr)
-{
- sslSocket * ss = ssl_GetPrivate(fd);
- PRStatus rv;
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in bind", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- rv = (PRStatus)(*ss->ops->bind)(ss, addr);
-
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss);
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Listen(PRFileDesc *fd, PRIntn backlog)
-{
- sslSocket * ss = ssl_GetPrivate(fd);
- PRStatus rv;
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in listen", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- rv = (PRStatus)(*ss->ops->listen)(ss, backlog);
-
- SSL_UNLOCK_WRITER(ss);
- SSL_UNLOCK_READER(ss);
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Shutdown(PRFileDesc *fd, PRIntn how)
-{
- sslSocket * ss = ssl_GetPrivate(fd);
- PRStatus rv;
-
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in shutdown", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
- SSL_LOCK_READER(ss);
- }
- if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
- SSL_LOCK_WRITER(ss);
- }
-
- rv = (PRStatus)(*ss->ops->shutdown)(ss, how);
-
- if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
- SSL_UNLOCK_WRITER(ss);
- }
- if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
- SSL_UNLOCK_READER(ss);
- }
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_Close(PRFileDesc *fd)
-{
- sslSocket *ss;
- PRStatus rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in close", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
-
- /* There must not be any I/O going on */
- SSL_LOCK_READER(ss);
- SSL_LOCK_WRITER(ss);
-
- /* By the time this function returns,
- ** ss is an invalid pointer, and the locks to which it points have
- ** been unlocked and freed. So, this is the ONE PLACE in all of SSL
- ** where the LOCK calls and the corresponding UNLOCK calls are not in
- ** the same function scope. The unlock calls are in ssl_FreeSocket().
- */
- rv = (PRStatus)(*ss->ops->close)(ss);
-
- return rv;
-}
-
-static int PR_CALLBACK
-ssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
- PRIntervalTime timeout)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in recv", SSL_GETPID(), fd));
- return SECFailure;
- }
- SSL_LOCK_READER(ss);
- ss->rTimeout = timeout;
- if (!ss->opt.fdx)
- ss->wTimeout = timeout;
- rv = (*ss->ops->recv)(ss, (unsigned char*)buf, len, flags);
- SSL_UNLOCK_READER(ss);
- return rv;
-}
-
-static int PR_CALLBACK
-ssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
- PRIntervalTime timeout)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in send", SSL_GETPID(), fd));
- return SECFailure;
- }
- SSL_LOCK_WRITER(ss);
- ss->wTimeout = timeout;
- if (!ss->opt.fdx)
- ss->rTimeout = timeout;
- rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags);
- SSL_UNLOCK_WRITER(ss);
- return rv;
-}
-
-static int PR_CALLBACK
-ssl_Read(PRFileDesc *fd, void *buf, PRInt32 len)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in read", SSL_GETPID(), fd));
- return SECFailure;
- }
- SSL_LOCK_READER(ss);
- ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
- if (!ss->opt.fdx)
- ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
- rv = (*ss->ops->read)(ss, (unsigned char*)buf, len);
- SSL_UNLOCK_READER(ss);
- return rv;
-}
-
-static int PR_CALLBACK
-ssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
-{
- sslSocket *ss;
- int rv;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in write", SSL_GETPID(), fd));
- return SECFailure;
- }
- SSL_LOCK_WRITER(ss);
- ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
- if (!ss->opt.fdx)
- ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
- rv = (*ss->ops->write)(ss, (const unsigned char*)buf, len);
- SSL_UNLOCK_WRITER(ss);
- return rv;
-}
-
-static PRStatus PR_CALLBACK
-ssl_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
-{
- sslSocket *ss;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in getpeername", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- return (PRStatus)(*ss->ops->getpeername)(ss, addr);
-}
-
-/*
-*/
-SECStatus
-ssl_GetPeerInfo(sslSocket *ss)
-{
- PRFileDesc * osfd;
- int rv;
- PRNetAddr sin;
-
- osfd = ss->fd->lower;
-
- PORT_Memset(&sin, 0, sizeof(sin));
- rv = osfd->methods->getpeername(osfd, &sin);
- if (rv < 0) {
- return SECFailure;
- }
- ss->TCPconnected = 1;
- if (sin.inet.family == PR_AF_INET) {
- PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ss->sec.ci.peer);
- ss->sec.ci.port = sin.inet.port;
- } else if (sin.ipv6.family == PR_AF_INET6) {
- ss->sec.ci.peer = sin.ipv6.ip;
- ss->sec.ci.port = sin.ipv6.port;
- } else {
- PORT_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR);
- return SECFailure;
- }
- return SECSuccess;
-}
-
-static PRStatus PR_CALLBACK
-ssl_GetSockName(PRFileDesc *fd, PRNetAddr *name)
-{
- sslSocket *ss;
-
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in getsockname", SSL_GETPID(), fd));
- return PR_FAILURE;
- }
- return (PRStatus)(*ss->ops->getsockname)(ss, name);
-}
-
-SECStatus
-SSL_SetStapledOCSPResponses(PRFileDesc *fd, SECItemArray *responses,
- PRBool takeOwnership)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetStapledOCSPResponses",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (ss->certStatusArray) {
- SECITEM_FreeArray(ss->certStatusArray, PR_TRUE);
- ss->certStatusArray = NULL;
- }
- if (responses) {
- if (takeOwnership) {
- ss->certStatusArray = responses;
- }
- else {
- ss->certStatusArray = SECITEM_DupArray(NULL, responses);
- }
- }
- return (ss->certStatusArray || !responses) ? SECSuccess : SECFailure;
-}
-
-SECStatus
-SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID)
-{
- sslSocket *ss;
-
- ss = ssl_FindSocket(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSockPeerID",
- SSL_GETPID(), fd));
- return SECFailure;
- }
-
- if (ss->peerID) {
- PORT_Free(ss->peerID);
- ss->peerID = NULL;
- }
- if (peerID)
- ss->peerID = PORT_Strdup(peerID);
- return (ss->peerID || !peerID) ? SECSuccess : SECFailure;
-}
-
-#define PR_POLL_RW (PR_POLL_WRITE | PR_POLL_READ)
-
-static PRInt16 PR_CALLBACK
-ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
-{
- sslSocket *ss;
- PRInt16 new_flags = how_flags; /* should select on these flags. */
- PRNetAddr addr;
-
- *p_out_flags = 0;
- ss = ssl_GetPrivate(fd);
- if (!ss) {
- SSL_DBG(("%d: SSL[%d]: bad socket in SSL_Poll",
- SSL_GETPID(), fd));
- return 0; /* don't poll on this socket */
- }
-
- if (ss->opt.useSecurity &&
- ss->handshaking != sslHandshakingUndetermined &&
- !ss->firstHsDone &&
- (how_flags & PR_POLL_RW)) {
- if (!ss->TCPconnected) {
- ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
- }
- /* If it's not connected, then presumably the application is polling
- ** on read or write appropriately, so don't change it.
- */
- if (ss->TCPconnected) {
- if (!ss->handshakeBegun) {
- /* If the handshake has not begun, poll on read or write
- ** based on the local application's role in the handshake,
- ** not based on what the application requested.
- */
- new_flags &= ~PR_POLL_RW;
- if (ss->handshaking == sslHandshakingAsClient) {
- new_flags |= PR_POLL_WRITE;
- } else { /* handshaking as server */
- new_flags |= PR_POLL_READ;
- }
- } else
- /* First handshake is in progress */
- if (ss->lastWriteBlocked) {
- if (new_flags & PR_POLL_READ) {
- /* The caller is waiting for data to be received,
- ** but the initial handshake is blocked on write, or the
- ** client's first handshake record has not been written.
- ** The code should select on write, not read.
- */
- new_flags ^= PR_POLL_READ; /* don't select on read. */
- new_flags |= PR_POLL_WRITE; /* do select on write. */
- }
- } else if (new_flags & PR_POLL_WRITE) {
- /* The caller is trying to write, but the handshake is
- ** blocked waiting for data to read, and the first
- ** handshake has been sent. so do NOT to poll on write.
- */
- new_flags ^= PR_POLL_WRITE; /* don't select on write. */
- new_flags |= PR_POLL_READ; /* do select on read. */
- }
- }
- } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
- *p_out_flags = PR_POLL_READ; /* it's ready already. */
- return new_flags;
- } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) &&
- (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */
- new_flags |= PR_POLL_WRITE; /* also select on write. */
- }
-
- if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
- ss->ssl3.hs.restartTarget != NULL) {
- /* Read and write will block until the asynchronous callback completes
- * (e.g. until SSL_AuthCertificateComplete is called), so don't tell
- * the caller to poll the socket unless there is pending write data.
- */
- if (ss->lastWriteBlocked && ss->pendingBuf.len != 0) {
- /* Ignore any newly-received data on the socket, but do wait for
- * the socket to become writable again. Here, it is OK for an error
- * to be detected, because our logic for sending pending write data
- * will allow us to report the error to the caller without the risk
- * of the application spinning.
- */
- new_flags &= (PR_POLL_WRITE | PR_POLL_EXCEPT);
- } else {
- /* Unfortunately, clearing new_flags will make it impossible for
- * the application to detect errors that it would otherwise be
- * able to detect with PR_POLL_EXCEPT, until the asynchronous
- * callback completes. However, we must clear all the flags to
- * prevent the application from spinning (alternating between
- * calling PR_Poll that would return PR_POLL_EXCEPT, and send/recv
- * which won't actually report the I/O error while we are waiting
- * for the asynchronous callback to complete).
- */
- new_flags = 0;
- }
- }
-
- if (new_flags && (fd->lower->methods->poll != NULL)) {
- PRInt16 lower_out_flags = 0;
- PRInt16 lower_new_flags;
- lower_new_flags = fd->lower->methods->poll(fd->lower, new_flags,
- &lower_out_flags);
- if ((lower_new_flags & lower_out_flags) && (how_flags != new_flags)) {
- PRInt16 out_flags = lower_out_flags & ~PR_POLL_RW;
- if (lower_out_flags & PR_POLL_READ)
- out_flags |= PR_POLL_WRITE;
- if (lower_out_flags & PR_POLL_WRITE)
- out_flags |= PR_POLL_READ;
- *p_out_flags = out_flags;
- new_flags = how_flags;
- } else {
- *p_out_flags = lower_out_flags;
- new_flags = lower_new_flags;
- }
- }
-
- return new_flags;
-}
-
-static PRInt32 PR_CALLBACK
-ssl_TransmitFile(PRFileDesc *sd, PRFileDesc *fd,
- const void *headers, PRInt32 hlen,
- PRTransmitFileFlags flags, PRIntervalTime timeout)
-{
- PRSendFileData sfd;
-
- sfd.fd = fd;
- sfd.file_offset = 0;
- sfd.file_nbytes = 0;
- sfd.header = headers;
- sfd.hlen = hlen;
- sfd.trailer = NULL;
- sfd.tlen = 0;
-
- return sd->methods->sendfile(sd, &sfd, flags, timeout);
-}
-
-
-PRBool
-ssl_FdIsBlocking(PRFileDesc *fd)
-{
- PRSocketOptionData opt;
- PRStatus status;
-
- opt.option = PR_SockOpt_Nonblocking;
- opt.value.non_blocking = PR_FALSE;
- status = PR_GetSocketOption(fd, &opt);
- if (status != PR_SUCCESS)
- return PR_FALSE;
- return (PRBool)!opt.value.non_blocking;
-}
-
-PRBool
-ssl_SocketIsBlocking(sslSocket *ss)
-{
- return ssl_FdIsBlocking(ss->fd);
-}
-
-PRInt32 sslFirstBufSize = 8 * 1024;
-PRInt32 sslCopyLimit = 1024;
-
-static PRInt32 PR_CALLBACK
-ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
- PRIntervalTime timeout)
-{
- PRInt32 bufLen;
- PRInt32 left;
- PRInt32 rv;
- PRInt32 sent = 0;
- const PRInt32 first_len = sslFirstBufSize;
- const PRInt32 limit = sslCopyLimit;
- PRBool blocking;
- PRIOVec myIov = { 0, 0 };
- char buf[MAX_FRAGMENT_LENGTH];
-
- if (vectors > PR_MAX_IOVECTOR_SIZE) {
- PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
- return -1;
- }
- blocking = ssl_FdIsBlocking(fd);
-
-#define K16 sizeof(buf)
-#define KILL_VECTORS while (vectors && !iov->iov_len) { ++iov; --vectors; }
-#define GET_VECTOR do { myIov = *iov++; --vectors; KILL_VECTORS } while (0)
-#define HANDLE_ERR(rv, len) \
- if (rv != len) { \
- if (rv < 0) { \
- if (!blocking \
- && (PR_GetError() == PR_WOULD_BLOCK_ERROR) \
- && (sent > 0)) { \
- return sent; \
- } else { \
- return -1; \
- } \
- } \
- /* Only a nonblocking socket can have partial sends */ \
- PR_ASSERT(!blocking); \
- return sent + rv; \
- }
-#define SEND(bfr, len) \
- do { \
- rv = ssl_Send(fd, bfr, len, 0, timeout); \
- HANDLE_ERR(rv, len) \
- sent += len; \
- } while (0)
-
- /* Make sure the first write is at least 8 KB, if possible. */
- KILL_VECTORS
- if (!vectors)
- return ssl_Send(fd, 0, 0, 0, timeout);
- GET_VECTOR;
- if (!vectors) {
- return ssl_Send(fd, myIov.iov_base, myIov.iov_len, 0, timeout);
- }
- if (myIov.iov_len < first_len) {
- PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
- bufLen = myIov.iov_len;
- left = first_len - bufLen;
- while (vectors && left) {
- int toCopy;
- GET_VECTOR;
- toCopy = PR_MIN(left, myIov.iov_len);
- PORT_Memcpy(buf + bufLen, myIov.iov_base, toCopy);
- bufLen += toCopy;
- left -= toCopy;
- myIov.iov_base += toCopy;
- myIov.iov_len -= toCopy;
- }
- SEND( buf, bufLen );
- }
-
- while (vectors || myIov.iov_len) {
- PRInt32 addLen;
- if (!myIov.iov_len) {
- GET_VECTOR;
- }
- while (myIov.iov_len >= K16) {
- SEND(myIov.iov_base, K16);
- myIov.iov_base += K16;
- myIov.iov_len -= K16;
- }
- if (!myIov.iov_len)
- continue;
-
- if (!vectors || myIov.iov_len > limit) {
- addLen = 0;
- } else if ((addLen = iov->iov_len % K16) + myIov.iov_len <= limit) {
- /* Addlen is already computed. */;
- } else if (vectors > 1 &&
- iov[1].iov_len % K16 + addLen + myIov.iov_len <= 2 * limit) {
- addLen = limit - myIov.iov_len;
- } else
- addLen = 0;
-
- if (!addLen) {
- SEND( myIov.iov_base, myIov.iov_len );
- myIov.iov_len = 0;
- continue;
- }
- PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
- bufLen = myIov.iov_len;
- do {
- GET_VECTOR;
- PORT_Memcpy(buf + bufLen, myIov.iov_base, addLen);
- myIov.iov_base += addLen;
- myIov.iov_len -= addLen;
- bufLen += addLen;
-
- left = PR_MIN( limit, K16 - bufLen);
- if (!vectors /* no more left */
- || myIov.iov_len > 0 /* we didn't use that one all up */
- || bufLen >= K16 /* it's full. */
- ) {
- addLen = 0;
- } else if ((addLen = iov->iov_len % K16) <= left) {
- /* Addlen is already computed. */;
- } else if (vectors > 1 &&
- iov[1].iov_len % K16 + addLen <= left + limit) {
- addLen = left;
- } else
- addLen = 0;
-
- } while (addLen);
- SEND( buf, bufLen );
- }
- return sent;
-}
-
-/*
- * These functions aren't implemented.
- */
-
-static PRInt32 PR_CALLBACK
-ssl_Available(PRFileDesc *fd)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return SECFailure;
-}
-
-static PRInt64 PR_CALLBACK
-ssl_Available64(PRFileDesc *fd)
-{
- PRInt64 res;
-
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- LL_I2L(res, -1L);
- return res;
-}
-
-static PRStatus PR_CALLBACK
-ssl_FSync(PRFileDesc *fd)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return PR_FAILURE;
-}
-
-static PRInt32 PR_CALLBACK
-ssl_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) {
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return SECFailure;
-}
-
-static PRInt64 PR_CALLBACK
-ssl_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence how) {
- PRInt64 res;
-
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- LL_I2L(res, -1L);
- return res;
-}
-
-static PRStatus PR_CALLBACK
-ssl_FileInfo(PRFileDesc *fd, PRFileInfo *info)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return PR_FAILURE;
-}
-
-static PRStatus PR_CALLBACK
-ssl_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return PR_FAILURE;
-}
-
-static PRInt32 PR_CALLBACK
-ssl_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
- PRNetAddr *addr, PRIntervalTime timeout)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return SECFailure;
-}
-
-static PRInt32 PR_CALLBACK
-ssl_SendTo(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
- const PRNetAddr *addr, PRIntervalTime timeout)
-{
- PORT_Assert(0);
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return SECFailure;
-}
-
-static const PRIOMethods ssl_methods = {
- PR_DESC_LAYERED,
- ssl_Close, /* close */
- ssl_Read, /* read */
- ssl_Write, /* write */
- ssl_Available, /* available */
- ssl_Available64, /* available64 */
- ssl_FSync, /* fsync */
- ssl_Seek, /* seek */
- ssl_Seek64, /* seek64 */
- ssl_FileInfo, /* fileInfo */
- ssl_FileInfo64, /* fileInfo64 */
- ssl_WriteV, /* writev */
- ssl_Connect, /* connect */
- ssl_Accept, /* accept */
- ssl_Bind, /* bind */
- ssl_Listen, /* listen */
- ssl_Shutdown, /* shutdown */
- ssl_Recv, /* recv */
- ssl_Send, /* send */
- ssl_RecvFrom, /* recvfrom */
- ssl_SendTo, /* sendto */
- ssl_Poll, /* poll */
- PR_EmulateAcceptRead, /* acceptread */
- ssl_TransmitFile, /* transmitfile */
- ssl_GetSockName, /* getsockname */
- ssl_GetPeerName, /* getpeername */
- NULL, /* getsockopt OBSOLETE */
- NULL, /* setsockopt OBSOLETE */
- NULL, /* getsocketoption */
- NULL, /* setsocketoption */
- PR_EmulateSendFile, /* Send a (partial) file with header/trailer*/
- NULL, /* reserved for future use */
- NULL, /* reserved for future use */
- NULL, /* reserved for future use */
- NULL, /* reserved for future use */
- NULL /* reserved for future use */
-};
-
-
-static PRIOMethods combined_methods;
-
-static void
-ssl_SetupIOMethods(void)
-{
- PRIOMethods *new_methods = &combined_methods;
- const PRIOMethods *nspr_methods = PR_GetDefaultIOMethods();
- const PRIOMethods *my_methods = &ssl_methods;
-
- *new_methods = *nspr_methods;
-
- new_methods->file_type = my_methods->file_type;
- new_methods->close = my_methods->close;
- new_methods->read = my_methods->read;
- new_methods->write = my_methods->write;
- new_methods->available = my_methods->available;
- new_methods->available64 = my_methods->available64;
- new_methods->fsync = my_methods->fsync;
- new_methods->seek = my_methods->seek;
- new_methods->seek64 = my_methods->seek64;
- new_methods->fileInfo = my_methods->fileInfo;
- new_methods->fileInfo64 = my_methods->fileInfo64;
- new_methods->writev = my_methods->writev;
- new_methods->connect = my_methods->connect;
- new_methods->accept = my_methods->accept;
- new_methods->bind = my_methods->bind;
- new_methods->listen = my_methods->listen;
- new_methods->shutdown = my_methods->shutdown;
- new_methods->recv = my_methods->recv;
- new_methods->send = my_methods->send;
- new_methods->recvfrom = my_methods->recvfrom;
- new_methods->sendto = my_methods->sendto;
- new_methods->poll = my_methods->poll;
- new_methods->acceptread = my_methods->acceptread;
- new_methods->transmitfile = my_methods->transmitfile;
- new_methods->getsockname = my_methods->getsockname;
- new_methods->getpeername = my_methods->getpeername;
-/* new_methods->getsocketoption = my_methods->getsocketoption; */
-/* new_methods->setsocketoption = my_methods->setsocketoption; */
- new_methods->sendfile = my_methods->sendfile;
-
-}
-
-static PRCallOnceType initIoLayerOnce;
-
-static PRStatus
-ssl_InitIOLayer(void)
-{
- ssl_layer_id = PR_GetUniqueIdentity("SSL");
- ssl_SetupIOMethods();
- ssl_inited = PR_TRUE;
- return PR_SUCCESS;
-}
-
-static PRStatus
-ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
-{
- PRFileDesc *layer = NULL;
- PRStatus status;
-
- if (!ssl_inited) {
- status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
- if (status != PR_SUCCESS)
- goto loser;
- }
-
- if (ns == NULL)
- goto loser;
-
- layer = PR_CreateIOLayerStub(ssl_layer_id, &combined_methods);
- if (layer == NULL)
- goto loser;
- layer->secret = (PRFilePrivate *)ns;
-
- /* Here, "stack" points to the PRFileDesc on the top of the stack.
- ** "layer" points to a new FD that is to be inserted into the stack.
- ** If layer is being pushed onto the top of the stack, then
- ** PR_PushIOLayer switches the contents of stack and layer, and then
- ** puts stack on top of layer, so that after it is done, the top of
- ** stack is the same "stack" as it was before, and layer is now the
- ** FD for the former top of stack.
- ** After this call, stack always points to the top PRFD on the stack.
- ** If this function fails, the contents of stack and layer are as
- ** they were before the call.
- */
- status = PR_PushIOLayer(stack, id, layer);
- if (status != PR_SUCCESS)
- goto loser;
-
- ns->fd = (id == PR_TOP_IO_LAYER) ? stack : layer;
- return PR_SUCCESS;
-
-loser:
- if (layer) {
- layer->dtor(layer); /* free layer */
- }
- return PR_FAILURE;
-}
-
-/* if this fails, caller must destroy socket. */
-static SECStatus
-ssl_MakeLocks(sslSocket *ss)
-{
- ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL);
- if (!ss->firstHandshakeLock)
- goto loser;
- ss->ssl3HandshakeLock = PZ_NewMonitor(nssILockSSL);
- if (!ss->ssl3HandshakeLock)
- goto loser;
- ss->specLock = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
- if (!ss->specLock)
- goto loser;
- ss->recvBufLock = PZ_NewMonitor(nssILockSSL);
- if (!ss->recvBufLock)
- goto loser;
- ss->xmitBufLock = PZ_NewMonitor(nssILockSSL);
- if (!ss->xmitBufLock)
- goto loser;
- ss->writerThread = NULL;
- if (ssl_lock_readers) {
- ss->recvLock = PZ_NewLock(nssILockSSL);
- if (!ss->recvLock)
- goto loser;
- ss->sendLock = PZ_NewLock(nssILockSSL);
- if (!ss->sendLock)
- goto loser;
- }
- return SECSuccess;
-loser:
- ssl_DestroyLocks(ss);
- return SECFailure;
-}
-
-#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)
-#define NSS_HAVE_GETENV 1
-#endif
-
-#define LOWER(x) (x | 0x20) /* cheap ToLower function ignores LOCALE */
-
-static void
-ssl_SetDefaultsFromEnvironment(void)
-{
-#if defined( NSS_HAVE_GETENV )
- static int firsttime = 1;
-
- if (firsttime) {
- char * ev;
- firsttime = 0;
-#ifdef DEBUG
- ev = getenv("SSLDEBUGFILE");
- if (ev && ev[0]) {
- ssl_trace_iob = fopen(ev, "w");
- }
- if (!ssl_trace_iob) {
- ssl_trace_iob = stderr;
- }
-#ifdef TRACE
- ev = getenv("SSLTRACE");
- if (ev && ev[0]) {
- ssl_trace = atoi(ev);
- SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
- }
-#endif /* TRACE */
- ev = getenv("SSLDEBUG");
- if (ev && ev[0]) {
- ssl_debug = atoi(ev);
- SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
- }
-#endif /* DEBUG */
- ev = getenv("SSLKEYLOGFILE");
- if (ev && ev[0]) {
- ssl_keylog_iob = fopen(ev, "a");
- if (!ssl_keylog_iob) {
- SSL_TRACE(("SSL: failed to open key log file"));
- } else {
- if (ftell(ssl_keylog_iob) == 0) {
- fputs("# SSL/TLS secrets log file, generated by NSS\n",
- ssl_keylog_iob);
- }
- SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev));
- }
- }
-#ifndef NO_PKCS11_BYPASS
- ev = getenv("SSLBYPASS");
- if (ev && ev[0]) {
- ssl_defaults.bypassPKCS11 = (ev[0] == '1');
- SSL_TRACE(("SSL: bypass default set to %d", \
- ssl_defaults.bypassPKCS11));
- }
-#endif /* NO_PKCS11_BYPASS */
- ev = getenv("SSLFORCELOCKS");
- if (ev && ev[0] == '1') {
- ssl_force_locks = PR_TRUE;
- ssl_defaults.noLocks = 0;
- strcpy(lockStatus + LOCKSTATUS_OFFSET, "FORCED. ");
- SSL_TRACE(("SSL: force_locks set to %d", ssl_force_locks));
- }
- ev = getenv("NSS_SSL_ENABLE_RENEGOTIATION");
- if (ev) {
- if (ev[0] == '1' || LOWER(ev[0]) == 'u')
- ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_UNRESTRICTED;
- else if (ev[0] == '0' || LOWER(ev[0]) == 'n')
- ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_NEVER;
- else if (ev[0] == '2' || LOWER(ev[0]) == 'r')
- ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_REQUIRES_XTN;
- else if (ev[0] == '3' || LOWER(ev[0]) == 't')
- ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_TRANSITIONAL;
- SSL_TRACE(("SSL: enableRenegotiation set to %d",
- ssl_defaults.enableRenegotiation));
- }
- ev = getenv("NSS_SSL_REQUIRE_SAFE_NEGOTIATION");
- if (ev && ev[0] == '1') {
- ssl_defaults.requireSafeNegotiation = PR_TRUE;
- SSL_TRACE(("SSL: requireSafeNegotiation set to %d",
- PR_TRUE));
- }
- ev = getenv("NSS_SSL_CBC_RANDOM_IV");
- if (ev && ev[0] == '0') {
- ssl_defaults.cbcRandomIV = PR_FALSE;
- SSL_TRACE(("SSL: cbcRandomIV set to 0"));
- }
- }
-#endif /* NSS_HAVE_GETENV */
-}
-
-/*
-** Create a newsocket structure for a file descriptor.
-*/
-static sslSocket *
-ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
-{
- sslSocket *ss;
-
- ssl_SetDefaultsFromEnvironment();
-
- if (ssl_force_locks)
- makeLocks = PR_TRUE;
-
- /* Make a new socket and get it ready */
- ss = (sslSocket*) PORT_ZAlloc(sizeof(sslSocket));
- if (ss) {
- /* This should be of type SSLKEAType, but CC on IRIX
- * complains during the for loop.
- */
- int i;
- SECStatus status;
-
- ss->opt = ssl_defaults;
- ss->opt.useSocks = PR_FALSE;
- ss->opt.noLocks = !makeLocks;
- ss->vrange = *VERSIONS_DEFAULTS(protocolVariant);
-
- ss->peerID = NULL;
- ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
- ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
- ss->cTimeout = PR_INTERVAL_NO_TIMEOUT;
- ss->cipherSpecs = NULL;
- ss->sizeCipherSpecs = 0; /* produced lazily */
- ss->preferredCipher = NULL;
- ss->url = NULL;
-
- for (i=kt_null; i < kt_kea_size; i++) {
- sslServerCerts * sc = ss->serverCerts + i;
- sc->serverCert = NULL;
- sc->serverCertChain = NULL;
- sc->serverKeyPair = NULL;
- sc->serverKeyBits = 0;
- }
- ss->stepDownKeyPair = NULL;
- ss->dbHandle = CERT_GetDefaultCertDB();
- ss->certStatusArray = NULL;
-
- /* Provide default implementation of hooks */
- ss->authCertificate = SSL_AuthCertificate;
- ss->authCertificateArg = (void *)ss->dbHandle;
- ss->sniSocketConfig = NULL;
- ss->sniSocketConfigArg = NULL;
- ss->getClientAuthData = NULL;
- ss->handleBadCert = NULL;
- ss->badCertArg = NULL;
- ss->pkcs11PinArg = NULL;
-
- ssl_ChooseOps(ss);
- ssl2_InitSocketPolicy(ss);
- ssl3_InitSocketPolicy(ss);
- PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
-
- if (makeLocks) {
- status = ssl_MakeLocks(ss);
- if (status != SECSuccess)
- goto loser;
- }
- status = ssl_CreateSecurityInfo(ss);
- if (status != SECSuccess)
- goto loser;
- status = ssl_InitGather(&ss->gs);
- if (status != SECSuccess) {
-loser:
- ssl_DestroySocketContents(ss);
- ssl_DestroyLocks(ss);
- PORT_Free(ss);
- ss = NULL;
- }
- ss->protocolVariant = protocolVariant;
- }
- return ss;
-}
-
diff --git a/security/nss/lib/ssl/sslt.h b/security/nss/lib/ssl/sslt.h
deleted file mode 100644
index c3b82ffec..000000000
--- a/security/nss/lib/ssl/sslt.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * This file contains prototypes for the public SSL functions.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef __sslt_h_
-#define __sslt_h_
-
-#include "prtypes.h"
-
-typedef struct SSL3StatisticsStr {
- /* statistics from ssl3_SendClientHello (sch) */
- long sch_sid_cache_hits;
- long sch_sid_cache_misses;
- long sch_sid_cache_not_ok;
-
- /* statistics from ssl3_HandleServerHello (hsh) */
- long hsh_sid_cache_hits;
- long hsh_sid_cache_misses;
- long hsh_sid_cache_not_ok;
-
- /* statistics from ssl3_HandleClientHello (hch) */
- long hch_sid_cache_hits;
- long hch_sid_cache_misses;
- long hch_sid_cache_not_ok;
-
- /* statistics related to stateless resume */
- long sch_sid_stateless_resumes;
- long hsh_sid_stateless_resumes;
- long hch_sid_stateless_resumes;
- long hch_sid_ticket_parse_failures;
-} SSL3Statistics;
-
-/* Key Exchange algorithm values */
-typedef enum {
- ssl_kea_null = 0,
- ssl_kea_rsa = 1,
- ssl_kea_dh = 2,
- ssl_kea_fortezza = 3, /* deprecated, now unused */
- ssl_kea_ecdh = 4,
- ssl_kea_size /* number of ssl_kea_ algorithms */
-} SSLKEAType;
-
-/* The following defines are for backwards compatibility.
-** They will be removed in a forthcoming release to reduce namespace pollution.
-** programs that use the kt_ symbols should convert to the ssl_kt_ symbols
-** soon.
-*/
-#define kt_null ssl_kea_null
-#define kt_rsa ssl_kea_rsa
-#define kt_dh ssl_kea_dh
-#define kt_fortezza ssl_kea_fortezza /* deprecated, now unused */
-#define kt_ecdh ssl_kea_ecdh
-#define kt_kea_size ssl_kea_size
-
-typedef enum {
- ssl_sign_null = 0,
- ssl_sign_rsa = 1,
- ssl_sign_dsa = 2,
- ssl_sign_ecdsa = 3
-} SSLSignType;
-
-typedef enum {
- ssl_auth_null = 0,
- ssl_auth_rsa = 1,
- ssl_auth_dsa = 2,
- ssl_auth_kea = 3,
- ssl_auth_ecdsa = 4
-} SSLAuthType;
-
-typedef enum {
- ssl_calg_null = 0,
- ssl_calg_rc4 = 1,
- ssl_calg_rc2 = 2,
- ssl_calg_des = 3,
- ssl_calg_3des = 4,
- ssl_calg_idea = 5,
- ssl_calg_fortezza = 6, /* deprecated, now unused */
- ssl_calg_aes = 7, /* coming soon */
- ssl_calg_camellia = 8,
- ssl_calg_seed = 9
-} SSLCipherAlgorithm;
-
-typedef enum {
- ssl_mac_null = 0,
- ssl_mac_md5 = 1,
- ssl_mac_sha = 2,
- ssl_hmac_md5 = 3, /* TLS HMAC version of mac_md5 */
- ssl_hmac_sha = 4 /* TLS HMAC version of mac_sha */
-} SSLMACAlgorithm;
-
-typedef enum {
- ssl_compression_null = 0,
- ssl_compression_deflate = 1 /* RFC 3749 */
-} SSLCompressionMethod;
-
-typedef struct SSLChannelInfoStr {
- PRUint32 length;
- PRUint16 protocolVersion;
- PRUint16 cipherSuite;
-
- /* server authentication info */
- PRUint32 authKeyBits;
-
- /* key exchange algorithm info */
- PRUint32 keaKeyBits;
-
- /* session info */
- PRUint32 creationTime; /* seconds since Jan 1, 1970 */
- PRUint32 lastAccessTime; /* seconds since Jan 1, 1970 */
- PRUint32 expirationTime; /* seconds since Jan 1, 1970 */
- PRUint32 sessionIDLength; /* up to 32 */
- PRUint8 sessionID [32];
-
- /* The following fields are added in NSS 3.12.5. */
-
- /* compression method info */
- const char * compressionMethodName;
- SSLCompressionMethod compressionMethod;
-} SSLChannelInfo;
-
-typedef struct SSLCipherSuiteInfoStr {
- PRUint16 length;
- PRUint16 cipherSuite;
-
- /* Cipher Suite Name */
- const char * cipherSuiteName;
-
- /* server authentication info */
- const char * authAlgorithmName;
- SSLAuthType authAlgorithm;
-
- /* key exchange algorithm info */
- const char * keaTypeName;
- SSLKEAType keaType;
-
- /* symmetric encryption info */
- const char * symCipherName;
- SSLCipherAlgorithm symCipher;
- PRUint16 symKeyBits;
- PRUint16 symKeySpace;
- PRUint16 effectiveKeyBits;
-
- /* MAC info */
- const char * macAlgorithmName;
- SSLMACAlgorithm macAlgorithm;
- PRUint16 macBits;
-
- PRUintn isFIPS : 1;
- PRUintn isExportable : 1;
- PRUintn nonStandard : 1;
- PRUintn reservedBits :29;
-
-} SSLCipherSuiteInfo;
-
-typedef enum {
- ssl_variant_stream = 0,
- ssl_variant_datagram = 1
-} SSLProtocolVariant;
-
-typedef struct SSLVersionRangeStr {
- PRUint16 min;
- PRUint16 max;
-} SSLVersionRange;
-
-typedef enum {
- SSL_sni_host_name = 0,
- SSL_sni_type_total
-} SSLSniNameType;
-
-/* Supported extensions. */
-/* Update SSL_MAX_EXTENSIONS whenever a new extension type is added. */
-typedef enum {
- ssl_server_name_xtn = 0,
- ssl_cert_status_xtn = 5,
-#ifdef NSS_ENABLE_ECC
- ssl_elliptic_curves_xtn = 10,
- ssl_ec_point_formats_xtn = 11,
-#endif
- ssl_use_srtp_xtn = 14,
- ssl_session_ticket_xtn = 35,
- ssl_next_proto_nego_xtn = 13172,
- ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
-} SSLExtensionType;
-
-#define SSL_MAX_EXTENSIONS 8
-
-#endif /* __sslt_h_ */
diff --git a/security/nss/lib/ssl/ssltrace.c b/security/nss/lib/ssl/ssltrace.c
deleted file mode 100644
index c1c6cddf9..000000000
--- a/security/nss/lib/ssl/ssltrace.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Functions to trace SSL protocol behavior in DEBUG builds.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#include <stdarg.h>
-#include "cert.h"
-#include "ssl.h"
-#include "sslimpl.h"
-#include "sslproto.h"
-#include "prprf.h"
-
-#if defined(DEBUG) || defined(TRACE)
-static const char *hex = "0123456789abcdef";
-
-static const char printable[257] = {
- "................" /* 0x */
- "................" /* 1x */
- " !\"#$%&'()*+,-./" /* 2x */
- "0123456789:;<=>?" /* 3x */
- "@ABCDEFGHIJKLMNO" /* 4x */
- "PQRSTUVWXYZ[\\]^_" /* 5x */
- "`abcdefghijklmno" /* 6x */
- "pqrstuvwxyz{|}~." /* 7x */
- "................" /* 8x */
- "................" /* 9x */
- "................" /* ax */
- "................" /* bx */
- "................" /* cx */
- "................" /* dx */
- "................" /* ex */
- "................" /* fx */
-};
-
-void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *vp, int len)
-{
- const unsigned char *cp = (const unsigned char *)vp;
- char buf[80];
- char *bp;
- char *ap;
-
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss->fd,
- msg, len));
- } else {
- SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg, len));
- }
- memset(buf, ' ', sizeof buf);
- bp = buf;
- ap = buf + 50;
- while (--len >= 0) {
- unsigned char ch = *cp++;
- *bp++ = hex[(ch >> 4) & 0xf];
- *bp++ = hex[ch & 0xf];
- *bp++ = ' ';
- *ap++ = printable[ch];
- if (ap - buf >= 66) {
- *ap = 0;
- SSL_TRACE((" %s", buf));
- memset(buf, ' ', sizeof buf);
- bp = buf;
- ap = buf + 50;
- }
- }
- if (bp > buf) {
- *ap = 0;
- SSL_TRACE((" %s", buf));
- }
-}
-
-#define LEN(cp) (((cp)[0] << 8) | ((cp)[1]))
-
-static void PrintType(sslSocket *ss, char *msg)
-{
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: dump-msg: %s", SSL_GETPID(), ss->fd,
- msg));
- } else {
- SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg));
- }
-}
-
-static void PrintInt(sslSocket *ss, char *msg, unsigned v)
-{
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s=%u", SSL_GETPID(), ss->fd,
- msg, v));
- } else {
- SSL_TRACE(("%d: SSL: %s=%u", SSL_GETPID(), msg, v));
- }
-}
-
-/* PrintBuf is just like ssl_PrintBuf above, except that:
- * a) It prefixes each line of the buffer with "XX: SSL[xxx] "
- * b) It dumps only hex, not ASCII.
- */
-static void PrintBuf(sslSocket *ss, char *msg, unsigned char *cp, int len)
-{
- char buf[80];
- char *bp;
-
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]",
- SSL_GETPID(), ss->fd, msg, len));
- } else {
- SSL_TRACE(("%d: SSL: %s [Len: %d]",
- SSL_GETPID(), msg, len));
- }
- bp = buf;
- while (--len >= 0) {
- unsigned char ch = *cp++;
- *bp++ = hex[(ch >> 4) & 0xf];
- *bp++ = hex[ch & 0xf];
- *bp++ = ' ';
- if (bp + 4 > buf + 50) {
- *bp = 0;
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s",
- SSL_GETPID(), ss->fd, buf));
- } else {
- SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf));
- }
- bp = buf;
- }
- }
- if (bp > buf) {
- *bp = 0;
- if (ss) {
- SSL_TRACE(("%d: SSL[%d]: %s",
- SSL_GETPID(), ss->fd, buf));
- } else {
- SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf));
- }
- }
-}
-
-void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len)
-{
- switch (bp[0]) {
- case SSL_MT_ERROR:
- PrintType(ss, "Error");
- PrintInt(ss, "error", LEN(bp+1));
- break;
-
- case SSL_MT_CLIENT_HELLO:
- {
- unsigned lcs = LEN(bp+3);
- unsigned ls = LEN(bp+5);
- unsigned lc = LEN(bp+7);
-
- PrintType(ss, "Client-Hello");
-
- PrintInt(ss, "version (Major)", bp[1]);
- PrintInt(ss, "version (minor)", bp[2]);
-
- PrintBuf(ss, "cipher-specs", bp+9, lcs);
- PrintBuf(ss, "session-id", bp+9+lcs, ls);
- PrintBuf(ss, "challenge", bp+9+lcs+ls, lc);
- }
- break;
- case SSL_MT_CLIENT_MASTER_KEY:
- {
- unsigned lck = LEN(bp+4);
- unsigned lek = LEN(bp+6);
- unsigned lka = LEN(bp+8);
-
- PrintType(ss, "Client-Master-Key");
-
- PrintInt(ss, "cipher-choice", bp[1]);
- PrintInt(ss, "key-length", LEN(bp+2));
-
- PrintBuf(ss, "clear-key", bp+10, lck);
- PrintBuf(ss, "encrypted-key", bp+10+lck, lek);
- PrintBuf(ss, "key-arg", bp+10+lck+lek, lka);
- }
- break;
- case SSL_MT_CLIENT_FINISHED:
- PrintType(ss, "Client-Finished");
- PrintBuf(ss, "connection-id", bp+1, len-1);
- break;
- case SSL_MT_SERVER_HELLO:
- {
- unsigned lc = LEN(bp+5);
- unsigned lcs = LEN(bp+7);
- unsigned lci = LEN(bp+9);
-
- PrintType(ss, "Server-Hello");
-
- PrintInt(ss, "session-id-hit", bp[1]);
- PrintInt(ss, "certificate-type", bp[2]);
- PrintInt(ss, "version (Major)", bp[3]);
- PrintInt(ss, "version (minor)", bp[3]);
- PrintBuf(ss, "certificate", bp+11, lc);
- PrintBuf(ss, "cipher-specs", bp+11+lc, lcs);
- PrintBuf(ss, "connection-id", bp+11+lc+lcs, lci);
- }
- break;
- case SSL_MT_SERVER_VERIFY:
- PrintType(ss, "Server-Verify");
- PrintBuf(ss, "challenge", bp+1, len-1);
- break;
- case SSL_MT_SERVER_FINISHED:
- PrintType(ss, "Server-Finished");
- PrintBuf(ss, "session-id", bp+1, len-1);
- break;
- case SSL_MT_REQUEST_CERTIFICATE:
- PrintType(ss, "Request-Certificate");
- PrintInt(ss, "authentication-type", bp[1]);
- PrintBuf(ss, "certificate-challenge", bp+2, len-2);
- break;
- case SSL_MT_CLIENT_CERTIFICATE:
- {
- unsigned lc = LEN(bp+2);
- unsigned lr = LEN(bp+4);
- PrintType(ss, "Client-Certificate");
- PrintInt(ss, "certificate-type", bp[1]);
- PrintBuf(ss, "certificate", bp+6, lc);
- PrintBuf(ss, "response", bp+6+lc, lr);
- }
- break;
- default:
- ssl_PrintBuf(ss, "sending *unknown* message type", bp, len);
- return;
- }
-}
-
-void
-ssl_Trace(const char *format, ... )
-{
- char buf[2000];
- va_list args;
-
- if (ssl_trace_iob) {
- va_start(args, format);
- PR_vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
-
- fputs(buf, ssl_trace_iob);
- fputs("\n", ssl_trace_iob);
- }
-}
-#endif
diff --git a/security/nss/lib/ssl/sslver.c b/security/nss/lib/ssl/sslver.c
deleted file mode 100644
index 35e0317ea..000000000
--- a/security/nss/lib/ssl/sslver.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Library identity and versioning */
-
-#include "nss.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_ssl_rcsid[] = "$Header: NSS " NSS_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_ssl_sccsid[] = "@(#)NSS " NSS_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
diff --git a/security/nss/lib/ssl/unix_err.c b/security/nss/lib/ssl/unix_err.c
deleted file mode 100644
index 21c966375..000000000
--- a/security/nss/lib/ssl/unix_err.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * this code will continue to need to be replicated.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#if 0
-#include "primpl.h"
-#else
-#define _PR_POLL_AVAILABLE 1
-#include "prerror.h"
-#endif
-
-#if defined (__bsdi__) || defined(NTO) || defined(DARWIN) || defined(BEOS)
-#undef _PR_POLL_AVAILABLE
-#endif
-
-#if defined(_PR_POLL_AVAILABLE)
-#include <poll.h>
-#endif
-#include <errno.h>
-
-/* forward declarations. */
-void nss_MD_unix_map_default_error(int err);
-
-void nss_MD_unix_map_opendir_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_closedir_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_readdir_error(int err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case ENOENT: prError = PR_NO_MORE_FILES_ERROR; break;
-#ifdef EOVERFLOW
- case EOVERFLOW: prError = PR_IO_ERROR; break;
-#endif
- case EINVAL: prError = PR_IO_ERROR; break;
- case ENXIO: prError = PR_IO_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_unlink_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EPERM: prError = PR_IS_DIRECTORY_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_stat_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_fstat_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_rename_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EEXIST: prError = PR_DIRECTORY_NOT_EMPTY_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_access_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_mkdir_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_rmdir_error(int err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case EEXIST: prError = PR_DIRECTORY_NOT_EMPTY_ERROR; break;
- case EINVAL: prError = PR_DIRECTORY_NOT_EMPTY_ERROR; break;
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_read_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_INVALID_METHOD_ERROR; break;
- case ENXIO: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_write_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_INVALID_METHOD_ERROR; break;
- case ENXIO: prError = PR_INVALID_METHOD_ERROR; break;
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_lseek_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_fsync_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- case EINVAL: prError = PR_INVALID_METHOD_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_close_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_socket_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_socketavailable_error(int err)
-{
- PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
-}
-
-void nss_MD_unix_map_recv_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_recvfrom_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_send_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_sendto_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_writev_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_accept_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ENODEV: prError = PR_NOT_TCP_SOCKET_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_connect_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EACCES: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
-#if defined(UNIXWARE) || defined(SNI) || defined(NEC)
- /*
- * On some platforms, if we connect to a port on the local host
- * (the loopback address) that no process is listening on, we get
- * EIO instead of ECONNREFUSED.
- */
- case EIO: prError = PR_CONNECT_REFUSED_ERROR; break;
-#endif
- case ELOOP: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ENOENT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ENXIO: prError = PR_IO_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_bind_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
- /*
- * UNIX domain sockets are not supported in NSPR
- */
- case EIO: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case EISDIR: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ELOOP: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ENOENT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ENOTDIR: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case EROFS: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_listen_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_shutdown_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_socketpair_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_getsockname_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_getpeername_error(int err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_getsockopt_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_BUFFER_OVERFLOW_ERROR; break;
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_setsockopt_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_BUFFER_OVERFLOW_ERROR; break;
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_open_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EAGAIN: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case EBUSY: prError = PR_IO_ERROR; break;
- case ENODEV: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_mmap_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EAGAIN: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case EMFILE: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ENODEV: prError = PR_OPERATION_NOT_SUPPORTED_ERROR; break;
- case ENXIO: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_gethostname_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-void nss_MD_unix_map_select_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-
-#ifdef _PR_POLL_AVAILABLE
-void nss_MD_unix_map_poll_error(int err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case EAGAIN: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_poll_revents_error(int err)
-{
- if (err & POLLNVAL)
- PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
- else if (err & POLLHUP)
- PR_SetError(PR_CONNECT_RESET_ERROR, EPIPE);
- else if (err & POLLERR)
- PR_SetError(PR_IO_ERROR, EIO);
- else
- PR_SetError(PR_UNKNOWN_ERROR, err);
-}
-#endif /* _PR_POLL_AVAILABLE */
-
-
-void nss_MD_unix_map_flock_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EINVAL: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- case EWOULDBLOCK: prError = PR_FILE_IS_LOCKED_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_unix_map_lockf_error(int err)
-{
- PRErrorCode prError;
- switch (err) {
- case EACCES: prError = PR_FILE_IS_LOCKED_ERROR; break;
- case EDEADLK: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- default: nss_MD_unix_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-#ifdef HPUX11
-void nss_MD_hpux_map_sendfile_error(int err)
-{
- nss_MD_unix_map_default_error(err);
-}
-#endif /* HPUX11 */
-
-
-void nss_MD_unix_map_default_error(int err)
-{
- PRErrorCode prError;
- switch (err ) {
- case EACCES: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case EADDRINUSE: prError = PR_ADDRESS_IN_USE_ERROR; break;
- case EADDRNOTAVAIL: prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; break;
- case EAFNOSUPPORT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case EAGAIN: prError = PR_WOULD_BLOCK_ERROR; break;
- /*
- * On QNX and Neutrino, EALREADY is defined as EBUSY.
- */
-#if EALREADY != EBUSY
- case EALREADY: prError = PR_ALREADY_INITIATED_ERROR; break;
-#endif
- case EBADF: prError = PR_BAD_DESCRIPTOR_ERROR; break;
-#ifdef EBADMSG
- case EBADMSG: prError = PR_IO_ERROR; break;
-#endif
- case EBUSY: prError = PR_FILESYSTEM_MOUNTED_ERROR; break;
- case ECONNREFUSED: prError = PR_CONNECT_REFUSED_ERROR; break;
- case ECONNRESET: prError = PR_CONNECT_RESET_ERROR; break;
- case EDEADLK: prError = PR_DEADLOCK_ERROR; break;
-#ifdef EDIRCORRUPTED
- case EDIRCORRUPTED: prError = PR_DIRECTORY_CORRUPTED_ERROR; break;
-#endif
-#ifdef EDQUOT
- case EDQUOT: prError = PR_NO_DEVICE_SPACE_ERROR; break;
-#endif
- case EEXIST: prError = PR_FILE_EXISTS_ERROR; break;
- case EFAULT: prError = PR_ACCESS_FAULT_ERROR; break;
- case EFBIG: prError = PR_FILE_TOO_BIG_ERROR; break;
- case EINPROGRESS: prError = PR_IN_PROGRESS_ERROR; break;
- case EINTR: prError = PR_PENDING_INTERRUPT_ERROR; break;
- case EINVAL: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case EIO: prError = PR_IO_ERROR; break;
- case EISCONN: prError = PR_IS_CONNECTED_ERROR; break;
- case EISDIR: prError = PR_IS_DIRECTORY_ERROR; break;
- case ELOOP: prError = PR_LOOP_ERROR; break;
- case EMFILE: prError = PR_PROC_DESC_TABLE_FULL_ERROR; break;
- case EMLINK: prError = PR_MAX_DIRECTORY_ENTRIES_ERROR; break;
- case EMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
-#ifdef EMULTIHOP
- case EMULTIHOP: prError = PR_REMOTE_FILE_ERROR; break;
-#endif
- case ENAMETOOLONG: prError = PR_NAME_TOO_LONG_ERROR; break;
- case ENETUNREACH: prError = PR_NETWORK_UNREACHABLE_ERROR; break;
- case ENFILE: prError = PR_SYS_DESC_TABLE_FULL_ERROR; break;
-#if !defined(SCO)
- case ENOBUFS: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
-#endif
- case ENODEV: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ENOENT: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ENOLCK: prError = PR_FILE_IS_LOCKED_ERROR; break;
-#ifdef ENOLINK
- case ENOLINK: prError = PR_REMOTE_FILE_ERROR; break;
-#endif
- case ENOMEM: prError = PR_OUT_OF_MEMORY_ERROR; break;
- case ENOPROTOOPT: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case ENOSPC: prError = PR_NO_DEVICE_SPACE_ERROR; break;
-#ifdef ENOSR
- case ENOSR: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
-#endif
- case ENOTCONN: prError = PR_NOT_CONNECTED_ERROR; break;
- case ENOTDIR: prError = PR_NOT_DIRECTORY_ERROR; break;
- case ENOTSOCK: prError = PR_NOT_SOCKET_ERROR; break;
- case ENXIO: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case EOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
-#ifdef EOVERFLOW
- case EOVERFLOW: prError = PR_BUFFER_OVERFLOW_ERROR; break;
-#endif
- case EPERM: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case EPIPE: prError = PR_CONNECT_RESET_ERROR; break;
-#ifdef EPROTO
- case EPROTO: prError = PR_IO_ERROR; break;
-#endif
- case EPROTONOSUPPORT: prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; break;
- case EPROTOTYPE: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case ERANGE: prError = PR_INVALID_METHOD_ERROR; break;
- case EROFS: prError = PR_READ_ONLY_FILESYSTEM_ERROR; break;
- case ESPIPE: prError = PR_INVALID_METHOD_ERROR; break;
- case ETIMEDOUT: prError = PR_IO_TIMEOUT_ERROR; break;
-#if EWOULDBLOCK != EAGAIN
- case EWOULDBLOCK: prError = PR_WOULD_BLOCK_ERROR; break;
-#endif
- case EXDEV: prError = PR_NOT_SAME_DEVICE_ERROR; break;
-
- default: prError = PR_UNKNOWN_ERROR; break;
- }
- PR_SetError(prError, err);
-}
diff --git a/security/nss/lib/ssl/unix_err.h b/security/nss/lib/ssl/unix_err.h
deleted file mode 100644
index bf4f77e5e..000000000
--- a/security/nss/lib/ssl/unix_err.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * this code will continue to need to be replicated.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* NSPR doesn't make these functions public, so we have to duplicate
-** them in NSS.
-*/
-extern void nss_MD_hpux_map_sendfile_error(int err);
-extern void nss_MD_unix_map_accept_error(int err);
-extern void nss_MD_unix_map_access_error(int err);
-extern void nss_MD_unix_map_bind_error(int err);
-extern void nss_MD_unix_map_close_error(int err);
-extern void nss_MD_unix_map_closedir_error(int err);
-extern void nss_MD_unix_map_connect_error(int err);
-extern void nss_MD_unix_map_default_error(int err);
-extern void nss_MD_unix_map_flock_error(int err);
-extern void nss_MD_unix_map_fstat_error(int err);
-extern void nss_MD_unix_map_fsync_error(int err);
-extern void nss_MD_unix_map_gethostname_error(int err);
-extern void nss_MD_unix_map_getpeername_error(int err);
-extern void nss_MD_unix_map_getsockname_error(int err);
-extern void nss_MD_unix_map_getsockopt_error(int err);
-extern void nss_MD_unix_map_listen_error(int err);
-extern void nss_MD_unix_map_lockf_error(int err);
-extern void nss_MD_unix_map_lseek_error(int err);
-extern void nss_MD_unix_map_mkdir_error(int err);
-extern void nss_MD_unix_map_mmap_error(int err);
-extern void nss_MD_unix_map_open_error(int err);
-extern void nss_MD_unix_map_opendir_error(int err);
-extern void nss_MD_unix_map_poll_error(int err);
-extern void nss_MD_unix_map_poll_revents_error(int err);
-extern void nss_MD_unix_map_read_error(int err);
-extern void nss_MD_unix_map_readdir_error(int err);
-extern void nss_MD_unix_map_recv_error(int err);
-extern void nss_MD_unix_map_recvfrom_error(int err);
-extern void nss_MD_unix_map_rename_error(int err);
-extern void nss_MD_unix_map_rmdir_error(int err);
-extern void nss_MD_unix_map_select_error(int err);
-extern void nss_MD_unix_map_send_error(int err);
-extern void nss_MD_unix_map_sendto_error(int err);
-extern void nss_MD_unix_map_setsockopt_error(int err);
-extern void nss_MD_unix_map_shutdown_error(int err);
-extern void nss_MD_unix_map_socket_error(int err);
-extern void nss_MD_unix_map_socketavailable_error(int err);
-extern void nss_MD_unix_map_socketpair_error(int err);
-extern void nss_MD_unix_map_stat_error(int err);
-extern void nss_MD_unix_map_unlink_error(int err);
-extern void nss_MD_unix_map_write_error(int err);
-extern void nss_MD_unix_map_writev_error(int err);
diff --git a/security/nss/lib/ssl/win32err.c b/security/nss/lib/ssl/win32err.c
deleted file mode 100644
index 9d38e3804..000000000
--- a/security/nss/lib/ssl/win32err.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * this code will continue to need to be replicated.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#include "prerror.h"
-#include "prlog.h"
-#include <errno.h>
-#include <windows.h>
-
-/*
- * On Win32, we map three kinds of error codes:
- * - GetLastError(): for Win32 functions
- * - WSAGetLastError(): for Winsock functions
- * - errno: for standard C library functions
- *
- * We do not check for WSAEINPROGRESS and WSAEINTR because we do not
- * use blocking Winsock 1.1 calls.
- *
- * Except for the 'socket' call, we do not check for WSAEINITIALISED.
- * It is assumed that if Winsock is not initialized, that fact will
- * be detected at the time we create new sockets.
- */
-
-/* forward declaration. */
-void nss_MD_win32_map_default_error(PRInt32 err);
-
-void nss_MD_win32_map_opendir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_closedir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_readdir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_delete_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-/* The error code for stat() is in errno. */
-void nss_MD_win32_map_stat_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_fstat_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_rename_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-/* The error code for access() is in errno. */
-void nss_MD_win32_map_access_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_mkdir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_rmdir_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_read_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_transmitfile_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_write_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_lseek_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_fsync_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-/*
- * For both CloseHandle() and closesocket().
- */
-void nss_MD_win32_map_close_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_socket_error(PRInt32 err)
-{
- PR_ASSERT(err != WSANOTINITIALISED);
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_recv_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_recvfrom_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_send_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_sendto_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_accept_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
- case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_acceptex_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_connect_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEWOULDBLOCK: prError = PR_IN_PROGRESS_ERROR; break;
- case WSAEINVAL: prError = PR_ALREADY_INITIATED_ERROR; break;
- case WSAETIMEDOUT: prError = PR_IO_TIMEOUT_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_bind_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_listen_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
- case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_shutdown_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_getsockname_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_getpeername_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_getsockopt_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_setsockopt_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_open_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-void nss_MD_win32_map_gethostname_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-/* Win32 select() only works on sockets. So in this
-** context, WSAENOTSOCK is equivalent to EBADF on Unix.
-*/
-void nss_MD_win32_map_select_error(PRInt32 err)
-{
- PRErrorCode prError;
- switch (err) {
- case WSAENOTSOCK: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- default: nss_MD_win32_map_default_error(err); return;
- }
- PR_SetError(prError, err);
-}
-
-void nss_MD_win32_map_lockf_error(PRInt32 err)
-{
- nss_MD_win32_map_default_error(err);
-}
-
-
-
-void nss_MD_win32_map_default_error(PRInt32 err)
-{
- PRErrorCode prError;
-
- switch (err) {
- case EACCES: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case ENOENT: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ERROR_ACCESS_DENIED: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case ERROR_ALREADY_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
- case ERROR_DISK_CORRUPT: prError = PR_IO_ERROR; break;
- case ERROR_DISK_FULL: prError = PR_NO_DEVICE_SPACE_ERROR; break;
- case ERROR_DISK_OPERATION_FAILED: prError = PR_IO_ERROR; break;
- case ERROR_DRIVE_LOCKED: prError = PR_FILE_IS_LOCKED_ERROR; break;
- case ERROR_FILENAME_EXCED_RANGE: prError = PR_NAME_TOO_LONG_ERROR; break;
- case ERROR_FILE_CORRUPT: prError = PR_IO_ERROR; break;
- case ERROR_FILE_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
- case ERROR_FILE_INVALID: prError = PR_BAD_DESCRIPTOR_ERROR; break;
-#if ERROR_FILE_NOT_FOUND != ENOENT
- case ERROR_FILE_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
-#endif
- case ERROR_HANDLE_DISK_FULL: prError = PR_NO_DEVICE_SPACE_ERROR; break;
- case ERROR_INVALID_ADDRESS: prError = PR_ACCESS_FAULT_ERROR; break;
- case ERROR_INVALID_HANDLE: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- case ERROR_INVALID_NAME: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case ERROR_INVALID_PARAMETER: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case ERROR_INVALID_USER_BUFFER: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ERROR_LOCKED: prError = PR_FILE_IS_LOCKED_ERROR; break;
- case ERROR_NETNAME_DELETED: prError = PR_CONNECT_RESET_ERROR; break;
- case ERROR_NOACCESS: prError = PR_ACCESS_FAULT_ERROR; break;
- case ERROR_NOT_ENOUGH_MEMORY: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ERROR_NOT_ENOUGH_QUOTA: prError = PR_OUT_OF_MEMORY_ERROR; break;
- case ERROR_NOT_READY: prError = PR_IO_ERROR; break;
- case ERROR_NO_MORE_FILES: prError = PR_NO_MORE_FILES_ERROR; break;
- case ERROR_OPEN_FAILED: prError = PR_IO_ERROR; break;
- case ERROR_OPEN_FILES: prError = PR_IO_ERROR; break;
- case ERROR_OUTOFMEMORY: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case ERROR_PATH_BUSY: prError = PR_IO_ERROR; break;
- case ERROR_PATH_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
- case ERROR_SEEK_ON_DEVICE: prError = PR_IO_ERROR; break;
- case ERROR_SHARING_VIOLATION: prError = PR_FILE_IS_BUSY_ERROR; break;
- case ERROR_STACK_OVERFLOW: prError = PR_ACCESS_FAULT_ERROR; break;
- case ERROR_TOO_MANY_OPEN_FILES: prError = PR_SYS_DESC_TABLE_FULL_ERROR; break;
- case ERROR_WRITE_PROTECT: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case WSAEACCES: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
- case WSAEADDRINUSE: prError = PR_ADDRESS_IN_USE_ERROR; break;
- case WSAEADDRNOTAVAIL: prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; break;
- case WSAEAFNOSUPPORT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
- case WSAEALREADY: prError = PR_ALREADY_INITIATED_ERROR; break;
- case WSAEBADF: prError = PR_BAD_DESCRIPTOR_ERROR; break;
- case WSAECONNABORTED: prError = PR_CONNECT_ABORTED_ERROR; break;
- case WSAECONNREFUSED: prError = PR_CONNECT_REFUSED_ERROR; break;
- case WSAECONNRESET: prError = PR_CONNECT_RESET_ERROR; break;
- case WSAEDESTADDRREQ: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAEFAULT: prError = PR_ACCESS_FAULT_ERROR; break;
- case WSAEHOSTUNREACH: prError = PR_HOST_UNREACHABLE_ERROR; break;
- case WSAEINVAL: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAEISCONN: prError = PR_IS_CONNECTED_ERROR; break;
- case WSAEMFILE: prError = PR_PROC_DESC_TABLE_FULL_ERROR; break;
- case WSAEMSGSIZE: prError = PR_BUFFER_OVERFLOW_ERROR; break;
- case WSAENETDOWN: prError = PR_NETWORK_DOWN_ERROR; break;
- case WSAENETRESET: prError = PR_CONNECT_ABORTED_ERROR; break;
- case WSAENETUNREACH: prError = PR_NETWORK_UNREACHABLE_ERROR; break;
- case WSAENOBUFS: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
- case WSAENOPROTOOPT: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAENOTCONN: prError = PR_NOT_CONNECTED_ERROR; break;
- case WSAENOTSOCK: prError = PR_NOT_SOCKET_ERROR; break;
- case WSAEOPNOTSUPP: prError = PR_OPERATION_NOT_SUPPORTED_ERROR; break;
- case WSAEPROTONOSUPPORT: prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; break;
- case WSAEPROTOTYPE: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAESHUTDOWN: prError = PR_SOCKET_SHUTDOWN_ERROR; break;
- case WSAESOCKTNOSUPPORT: prError = PR_INVALID_ARGUMENT_ERROR; break;
- case WSAETIMEDOUT: prError = PR_CONNECT_ABORTED_ERROR; break;
- case WSAEWOULDBLOCK: prError = PR_WOULD_BLOCK_ERROR; break;
- default: prError = PR_UNKNOWN_ERROR; break;
- }
- PR_SetError(prError, err);
-}
-
diff --git a/security/nss/lib/ssl/win32err.h b/security/nss/lib/ssl/win32err.h
deleted file mode 100644
index a72548da2..000000000
--- a/security/nss/lib/ssl/win32err.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * This file essentially replicates NSPR's source for the functions that
- * map system-specific error codes to NSPR error codes. We would use
- * NSPR's functions, instead of duplicating them, but they're private.
- * As long as SSL's server session cache code must do platform native I/O
- * to accomplish its job, and NSPR's error mapping functions remain private,
- * This code will continue to need to be replicated.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-/* NSPR doesn't make these functions public, so we have to duplicate
-** them in NSS.
-*/
-extern void nss_MD_win32_map_accept_error(PRInt32 err);
-extern void nss_MD_win32_map_acceptex_error(PRInt32 err);
-extern void nss_MD_win32_map_access_error(PRInt32 err);
-extern void nss_MD_win32_map_bind_error(PRInt32 err);
-extern void nss_MD_win32_map_close_error(PRInt32 err);
-extern void nss_MD_win32_map_closedir_error(PRInt32 err);
-extern void nss_MD_win32_map_connect_error(PRInt32 err);
-extern void nss_MD_win32_map_default_error(PRInt32 err);
-extern void nss_MD_win32_map_delete_error(PRInt32 err);
-extern void nss_MD_win32_map_fstat_error(PRInt32 err);
-extern void nss_MD_win32_map_fsync_error(PRInt32 err);
-extern void nss_MD_win32_map_gethostname_error(PRInt32 err);
-extern void nss_MD_win32_map_getpeername_error(PRInt32 err);
-extern void nss_MD_win32_map_getsockname_error(PRInt32 err);
-extern void nss_MD_win32_map_getsockopt_error(PRInt32 err);
-extern void nss_MD_win32_map_listen_error(PRInt32 err);
-extern void nss_MD_win32_map_lockf_error(PRInt32 err);
-extern void nss_MD_win32_map_lseek_error(PRInt32 err);
-extern void nss_MD_win32_map_mkdir_error(PRInt32 err);
-extern void nss_MD_win32_map_open_error(PRInt32 err);
-extern void nss_MD_win32_map_opendir_error(PRInt32 err);
-extern void nss_MD_win32_map_read_error(PRInt32 err);
-extern void nss_MD_win32_map_readdir_error(PRInt32 err);
-extern void nss_MD_win32_map_recv_error(PRInt32 err);
-extern void nss_MD_win32_map_recvfrom_error(PRInt32 err);
-extern void nss_MD_win32_map_rename_error(PRInt32 err);
-extern void nss_MD_win32_map_rmdir_error(PRInt32 err);
-extern void nss_MD_win32_map_select_error(PRInt32 err);
-extern void nss_MD_win32_map_send_error(PRInt32 err);
-extern void nss_MD_win32_map_sendto_error(PRInt32 err);
-extern void nss_MD_win32_map_setsockopt_error(PRInt32 err);
-extern void nss_MD_win32_map_shutdown_error(PRInt32 err);
-extern void nss_MD_win32_map_socket_error(PRInt32 err);
-extern void nss_MD_win32_map_stat_error(PRInt32 err);
-extern void nss_MD_win32_map_transmitfile_error(PRInt32 err);
-extern void nss_MD_win32_map_write_error(PRInt32 err);
diff --git a/security/nss/lib/sysinit/Makefile b/security/nss/lib/sysinit/Makefile
deleted file mode 100644
index fe59954df..000000000
--- a/security/nss/lib/sysinit/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-#include ../platlibs.mk
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-
-#include ../platrules.mk
-
diff --git a/security/nss/lib/sysinit/config.mk b/security/nss/lib/sysinit/config.mk
deleted file mode 100644
index 037641b11..000000000
--- a/security/nss/lib/sysinit/config.mk
+++ /dev/null
@@ -1,80 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
-
-RES = $(OBJDIR)/$(LIBRARY_NAME).res
-RESNAME = $(LIBRARY_NAME).rc
-
-ifdef NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4\
- $(NULL)
-else # ! NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- $(DIST)/lib/nssutil3.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-
-else
-
-# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
-# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSSUTIL_LIB_DIR) \
- -lnssutil3 \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-
-endif
-
-
-# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
-
-ifeq ($(OS_TARGET),SunOS)
-ifeq ($(BUILD_SUN_PKG), 1)
-# The -R '$ORIGIN' linker option instructs this library to search for its
-# dependencies in the same directory where it resides.
-ifeq ($(USE_64), 1)
-MKSHLIB += -R '$$ORIGIN:/usr/lib/mps/secv1/64:/usr/lib/mps/64'
-else
-MKSHLIB += -R '$$ORIGIN:/usr/lib/mps/secv1:/usr/lib/mps'
-endif
-else
-MKSHLIB += -R '$$ORIGIN'
-endif
-endif
-
-ifeq ($(OS_ARCH), HP-UX)
-ifneq ($(OS_TEST), ia64)
-# pa-risc
-ifeq ($(USE_64), 1)
-MKSHLIB += +b '$$ORIGIN'
-endif
-endif
-endif
diff --git a/security/nss/lib/sysinit/manifest.mn b/security/nss/lib/sysinit/manifest.mn
deleted file mode 100644
index bb413beef..000000000
--- a/security/nss/lib/sysinit/manifest.mn
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-CORE_DEPTH = ../../..
-
-# MODULE public and private header directories are implicitly REQUIRED.
-MODULE = nss
-
-CSRCS = nsssysinit.c
-
-LIBRARY_NAME = nsssysinit
-#LIBRARY_VERSION = 3
-
diff --git a/security/nss/lib/sysinit/nsssysinit.c b/security/nss/lib/sysinit/nsssysinit.c
deleted file mode 100644
index 60015dd70..000000000
--- a/security/nss/lib/sysinit/nsssysinit.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "seccomon.h"
-#include "prio.h"
-#include "prprf.h"
-#include "plhash.h"
-
-/*
- * The following provides a default example for operating systems to set up
- * and manage applications loading NSS on their OS globally.
- *
- * This code hooks in to the system pkcs11.txt, which controls all the loading
- * of pkcs11 modules common to all applications.
- */
-
-/*
- * OS Specific function to get where the NSS user database should reside.
- */
-
-#ifdef XP_UNIX
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-static int
-testdir(char *dir)
-{
- struct stat buf;
- memset(&buf, 0, sizeof(buf));
-
- if (stat(dir,&buf) < 0) {
- return 0;
- }
-
- return S_ISDIR(buf.st_mode);
-}
-
-#define NSS_USER_PATH1 "/.pki"
-#define NSS_USER_PATH2 "/nssdb"
-static char *
-getUserDB(void)
-{
- char *userdir = getenv("HOME");
- char *nssdir = NULL;
-
- if (userdir == NULL) {
- return NULL;
- }
-
- nssdir = PORT_Alloc(strlen(userdir)
- +sizeof(NSS_USER_PATH1)+sizeof(NSS_USER_PATH2));
- if (nssdir == NULL) {
- return NULL;
- }
- PORT_Strcpy(nssdir, userdir);
- /* verify it exists */
- if (!testdir(nssdir)) {
- PORT_Free(nssdir);
- return NULL;
- }
- PORT_Strcat(nssdir, NSS_USER_PATH1);
- if (!testdir(nssdir) && mkdir(nssdir, 0760)) {
- PORT_Free(nssdir);
- return NULL;
- }
- PORT_Strcat(nssdir, NSS_USER_PATH2);
- if (!testdir(nssdir) && mkdir(nssdir, 0760)) {
- PORT_Free(nssdir);
- return NULL;
- }
- return nssdir;
-}
-
-#define NSS_DEFAULT_SYSTEM "/etc/pki/nssdb"
-static char *
-getSystemDB(void) {
- return PORT_Strdup(NSS_DEFAULT_SYSTEM);
-}
-
-static PRBool
-userIsRoot()
-{
- /* this works for linux and all unixes that we know off
- though it isn't stated as such in POSIX documentation */
- return getuid() == 0;
-}
-
-static PRBool
-userCanModifySystemDB()
-{
- return (access(NSS_DEFAULT_SYSTEM, W_OK) == 0);
-}
-
-#else
-#ifdef XP_WIN
-static char *
-getUserDB(void)
-{
- /* use the registry to find the user's NSS_DIR. if no entry exists, create
- * one in the users Appdir location */
- return NULL;
-}
-
-static char *
-getSystemDB(void)
-{
- /* use the registry to find the system's NSS_DIR. if no entry exists, create
- * one based on the windows system data area */
- return NULL;
-}
-
-static PRBool
-userIsRoot()
-{
- /* use the registry to find if the user is the system administrator. */
- return PR_FALSE;
-}
-
-static PRBool
-userCanModifySystemDB()
-{
- /* use the registry to find if the user has administrative privilege
- * to modify the system's nss database. */
- return PR_FALSE;
-}
-
-#else
-#error "Need to write getUserDB, SystemDB, userIsRoot, and userCanModifySystemDB functions"
-#endif
-#endif
-
-static PRBool
-getFIPSEnv(void)
-{
- char *fipsEnv = getenv("NSS_FIPS");
- if (!fipsEnv) {
- return PR_FALSE;
- }
- if ((strcasecmp(fipsEnv,"fips") == 0) ||
- (strcasecmp(fipsEnv,"true") == 0) ||
- (strcasecmp(fipsEnv,"on") == 0) ||
- (strcasecmp(fipsEnv,"1") == 0)) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-#ifdef XP_LINUX
-
-static PRBool
-getFIPSMode(void)
-{
- FILE *f;
- char d;
- size_t size;
-
- f = fopen("/proc/sys/crypto/fips_enabled", "r");
- if (!f) {
- /* if we don't have a proc flag, fall back to the
- * environment variable */
- return getFIPSEnv();
- }
-
- size = fread(&d, 1, 1, f);
- fclose(f);
- if (size != 1)
- return PR_FALSE;
- if (d != '1')
- return PR_FALSE;
- return PR_TRUE;
-}
-
-#else
-static PRBool
-getFIPSMode(void)
-{
- return getFIPSEnv();
-}
-#endif
-
-
-#define NSS_DEFAULT_FLAGS "flags=readonly"
-
-/* configuration flags according to
- * https://developer.mozilla.org/en/PKCS11_Module_Specs
- * As stated there the slotParams start with a slot name which is a slotID
- * Slots 1 through 3 are reserved for the nss internal modules as follows:
- * 1 for crypto operations slot non-fips,
- * 2 for the key slot, and
- * 3 for the crypto operations slot fips
- */
-#define CIPHER_ORDER_FLAGS "cipherOrder=100"
-#define SLOT_FLAGS \
- "[slotFlags=RSA,RC4,RC2,DES,DH,SHA1,MD5,MD2,SSL,TLS,AES,RANDOM" \
- " askpw=any timeout=30 ]"
-
-static const char *nssDefaultFlags =
- CIPHER_ORDER_FLAGS " slotParams={0x00000001=" SLOT_FLAGS " } ";
-
-static const char *nssDefaultFIPSFlags =
- CIPHER_ORDER_FLAGS " slotParams={0x00000003=" SLOT_FLAGS " } ";
-
-/*
- * This function builds the list of databases and modules to load, and sets
- * their configuration. For the sample we have a fixed set.
- * 1. We load the user's home nss database.
- * 2. We load the user's custom PKCS #11 modules.
- * 3. We load the system nss database readonly.
- *
- * Any space allocated in get_list must be freed in release_list.
- * This function can use whatever information is available to the application.
- * it is running in the process of the application for which it is making
- * decisions, so it's possible to acquire the application name as part of
- * the decision making process.
- *
- */
-static char **
-get_list(char *filename, char *stripped_parameters)
-{
- char **module_list = PORT_ZNewArray(char *, 5);
- char *userdb, *sysdb;
- int isFIPS = getFIPSMode();
- const char *nssflags = isFIPS ? nssDefaultFIPSFlags : nssDefaultFlags;
- int next = 0;
-
- /* can't get any space */
- if (module_list == NULL) {
- return NULL;
- }
-
- sysdb = getSystemDB();
- userdb = getUserDB();
-
- /* Don't open root's user DB */
- if (userdb != NULL && !userIsRoot()) {
- /* return a list of databases to open. First the user Database */
- module_list[next++] = PR_smprintf(
- "library= "
- "module=\"NSS User database\" "
- "parameters=\"configdir='sql:%s' %s tokenDescription='NSS user database'\" "
- "NSS=\"trustOrder=75 %sflags=internal%s\"",
- userdb, stripped_parameters, nssflags,
- isFIPS ? ",FIPS" : "");
-
- /* now open the user's defined PKCS #11 modules */
- /* skip the local user DB entry */
- module_list[next++] = PR_smprintf(
- "library= "
- "module=\"NSS User database\" "
- "parameters=\"configdir='sql:%s' %s\" "
- "NSS=\"flags=internal,moduleDBOnly,defaultModDB,skipFirst\"",
- userdb, stripped_parameters);
- }
-
- /* now the system database (always read only unless it's root) */
- if (sysdb) {
- const char *readonly = userCanModifySystemDB() ? "" : "flags=readonly";
- module_list[next++] = PR_smprintf(
- "library= "
- "module=\"NSS system database\" "
- "parameters=\"configdir='sql:%s' tokenDescription='NSS system database' %s\" "
- "NSS=\"trustOrder=80 %sflags=internal,critical\"",sysdb, readonly, nssflags);
- }
-
- /* that was the last module */
- module_list[next] = 0;
-
- PORT_Free(userdb);
- PORT_Free(sysdb);
-
- return module_list;
-}
-
-static char **
-release_list(char **arg)
-{
- static char *success = "Success";
- int next;
-
- for (next = 0; arg[next]; next++) {
- free(arg[next]);
- }
- PORT_Free(arg);
- return &success;
-}
-
-
-#include "utilpars.h"
-
-#define TARGET_SPEC_COPY(new, start, end) \
- if (end > start) { \
- int _cnt = end - start; \
- PORT_Memcpy(new, start, _cnt); \
- new += _cnt; \
- }
-
-/*
- * According the strcpy man page:
- *
- * The strings may not overlap, and the destination string dest must be
- * large enough to receive the copy.
- *
- * This implementation allows target to overlap with src.
- * It does not allow the src to overlap the target.
- * example: overlapstrcpy(string, string+4) is fine
- * overlapstrcpy(string+4, string) is not.
- */
-static void
-overlapstrcpy(char *target, char *src)
-{
- while (*src) {
- *target++ = *src++;
- }
- *target = 0;
-}
-
-/* determine what options the user was trying to open this database with */
-/* filename is the directory pointed to by configdir= */
-/* stripped is the rest of the parameters with configdir= stripped out */
-static SECStatus
-parse_parameters(char *parameters, char **filename, char **stripped)
-{
- char *sourcePrev;
- char *sourceCurr;
- char *targetCurr;
- char *newStripped;
- *filename = NULL;
- *stripped = NULL;
-
- newStripped = PORT_Alloc(PORT_Strlen(parameters)+2);
- targetCurr = newStripped;
- sourcePrev = parameters;
- sourceCurr = NSSUTIL_ArgStrip(parameters);
- TARGET_SPEC_COPY(targetCurr, sourcePrev, sourceCurr);
-
- while (*sourceCurr) {
- int next;
- sourcePrev = sourceCurr;
- NSSUTIL_HANDLE_STRING_ARG(sourceCurr, *filename, "configdir=",
- sourcePrev = sourceCurr; )
- NSSUTIL_HANDLE_FINAL_ARG(sourceCurr);
- TARGET_SPEC_COPY(targetCurr, sourcePrev, sourceCurr);
- }
- *targetCurr = 0;
- if (*filename == NULL) {
- PORT_Free(newStripped);
- return SECFailure;
- }
- /* strip off any directives from the filename */
- if (strncmp("sql:", *filename, 4) == 0) {
- overlapstrcpy(*filename, (*filename)+4);
- } else if (strncmp("dbm:", *filename, 4) == 0) {
- overlapstrcpy(*filename, (*filename)+4);
- } else if (strncmp("extern:", *filename, 7) == 0) {
- overlapstrcpy(*filename, (*filename)+7);
- }
- *stripped = newStripped;
- return SECSuccess;
-}
-
-/* entry point */
-char **
-NSS_ReturnModuleSpecData(unsigned long function, char *parameters, void *args)
-{
- char *filename = NULL;
- char *stripped = NULL;
- char **retString = NULL;
- SECStatus rv;
-
- rv = parse_parameters(parameters, &filename, &stripped);
- if (rv != SECSuccess) {
- /* use defaults */
- filename = getSystemDB();
- if (!filename) {
- return NULL;
- }
- stripped = PORT_Strdup(NSS_DEFAULT_FLAGS);
- if (!stripped) {
- free(filename);
- return NULL;
- }
- }
- switch (function) {
- case SECMOD_MODULE_DB_FUNCTION_FIND:
- retString = get_list(filename, stripped);
- break;
- case SECMOD_MODULE_DB_FUNCTION_RELEASE:
- retString = release_list((char **)args);
- break;
- /* can't add or delete from this module DB */
- case SECMOD_MODULE_DB_FUNCTION_ADD:
- case SECMOD_MODULE_DB_FUNCTION_DEL:
- retString = NULL;
- break;
- default:
- retString = NULL;
- break;
- }
-
- PORT_Free(filename);
- PORT_Free(stripped);
- return retString;
-}
diff --git a/security/nss/lib/util/Makefile b/security/nss/lib/util/Makefile
deleted file mode 100644
index 0a9b74923..000000000
--- a/security/nss/lib/util/Makefile
+++ /dev/null
@@ -1,56 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-# include $(CORE_DEPTH)/coreconf/arch.mk
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-
-export:: private_export
-
-test: $(OBJDIR)/test_utf8
-
-$(OBJDIR)/test_utf8: utf8.c
- @$(MAKE_OBJDIR)
- $(CCF) -o $(OBJDIR)/test_utf8 -DTEST_UTF8 utf8.c $(OS_LIBS)
diff --git a/security/nss/lib/util/SECerrs.h b/security/nss/lib/util/SECerrs.h
deleted file mode 100644
index 8b6b36f22..000000000
--- a/security/nss/lib/util/SECerrs.h
+++ /dev/null
@@ -1,553 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* General security error codes */
-/* Caller must #include "secerr.h" */
-
-ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0,
-"An I/O error occurred during security authorization.")
-
-ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1,
-"security library failure.")
-
-ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2,
-"security library: received bad data.")
-
-ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3,
-"security library: output length error.")
-
-ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4,
-"security library has experienced an input length error.")
-
-ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5,
-"security library: invalid arguments.")
-
-ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6,
-"security library: invalid algorithm.")
-
-ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7,
-"security library: invalid AVA.")
-
-ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8,
-"Improperly formatted time string.")
-
-ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9,
-"security library: improperly formatted DER-encoded message.")
-
-ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10,
-"Peer's certificate has an invalid signature.")
-
-ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11,
-"Peer's Certificate has expired.")
-
-ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12,
-"Peer's Certificate has been revoked.")
-
-ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13,
-"Peer's Certificate issuer is not recognized.")
-
-ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14,
-"Peer's public key is invalid.")
-
-ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15,
-"The security password entered is incorrect.")
-
-ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16,
-"New password entered incorrectly. Please try again.")
-
-ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17,
-"security library: no nodelock.")
-
-ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18,
-"security library: bad database.")
-
-ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19,
-"security library: memory allocation failure.")
-
-ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20,
-"Peer's certificate issuer has been marked as not trusted by the user.")
-
-ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21,
-"Peer's certificate has been marked as not trusted by the user.")
-
-ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22),
-"Certificate already exists in your database.")
-
-ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23),
-"Downloaded certificate's name duplicates one already in your database.")
-
-ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24),
-"Error adding certificate to database.")
-
-ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25),
-"Error refiling the key for this certificate.")
-
-ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26),
-"The private key for this certificate cannot be found in key database")
-
-ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27),
-"This certificate is valid.")
-
-ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28),
-"This certificate is not valid.")
-
-ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29),
-"Cert Library: No Response")
-
-ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30),
-"The certificate issuer's certificate has expired. Check your system date and time.")
-
-ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31),
-"The CRL for the certificate's issuer has expired. Update it or check your system date and time.")
-
-ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32),
-"The CRL for the certificate's issuer has an invalid signature.")
-
-ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33),
-"New CRL has an invalid format.")
-
-ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34),
-"Certificate extension value is invalid.")
-
-ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35),
-"Certificate extension not found.")
-
-ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36),
-"Issuer certificate is invalid.")
-
-ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37),
-"Certificate path length constraint is invalid.")
-
-ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
-"Certificate usages field is invalid.")
-
-ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
-"**Internal ONLY module**")
-
-ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
-"The key does not support the requested operation.")
-
-ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
-"Certificate contains unknown critical extension.")
-
-ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42),
-"New CRL is not later than the current one.")
-
-ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43),
-"Not encrypted or signed: you do not yet have an email certificate.")
-
-ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44),
-"Not encrypted: you do not have certificates for each of the recipients.")
-
-ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45),
-"Cannot decrypt: you are not a recipient, or matching certificate and \
-private key not found.")
-
-ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46),
-"Cannot decrypt: key encryption algorithm does not match your certificate.")
-
-ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47),
-"Signature verification failed: no signer found, too many signers found, \
-or improper or corrupted data.")
-
-ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48),
-"Unsupported or unknown key algorithm.")
-
-ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49),
-"Cannot decrypt: encrypted using a disallowed algorithm or key size.")
-
-
-/* Fortezza Alerts */
-ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50),
-"Fortezza card has not been properly initialized. \
-Please remove it and return it to your issuer.")
-
-ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51),
-"No Fortezza cards Found")
-
-ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52),
-"No Fortezza card selected")
-
-ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53),
-"Please select a personality to get more info on")
-
-ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54),
-"Personality not found")
-
-ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55),
-"No more information on that Personality")
-
-ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56),
-"Invalid Pin")
-
-ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57),
-"Couldn't initialize Fortezza personalities.")
-/* end fortezza alerts. */
-
-ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58),
-"No KRL for this site's certificate has been found.")
-
-ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59),
-"The KRL for this site's certificate has expired.")
-
-ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60),
-"The KRL for this site's certificate has an invalid signature.")
-
-ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61),
-"The key for this site's certificate has been revoked.")
-
-ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62),
-"New KRL has an invalid format.")
-
-ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63),
-"security library: need random data.")
-
-ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64),
-"security library: no security module can perform the requested operation.")
-
-ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65),
-"The security card or token does not exist, needs to be initialized, or has been removed.")
-
-ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66),
-"security library: read-only database.")
-
-ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67),
-"No slot or token was selected.")
-
-ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68),
-"A certificate with the same nickname already exists.")
-
-ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69),
-"A key with the same nickname already exists.")
-
-ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70),
-"error while creating safe object")
-
-ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71),
-"error while creating baggage object")
-
-ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72),
-"Couldn't remove the principal")
-
-ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73),
-"Couldn't delete the privilege")
-
-ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74),
-"This principal doesn't have a certificate")
-
-ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75),
-"Required algorithm is not allowed.")
-
-ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76),
-"Error attempting to export certificates.")
-
-ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77),
-"Error attempting to import certificates.")
-
-ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78),
-"Unable to import. Decoding error. File not valid.")
-
-ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79),
-"Unable to import. Invalid MAC. Incorrect password or corrupt file.")
-
-ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80),
-"Unable to import. MAC algorithm not supported.")
-
-ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81),
-"Unable to import. Only password integrity and privacy modes supported.")
-
-ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82),
-"Unable to import. File structure is corrupt.")
-
-ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83),
-"Unable to import. Encryption algorithm not supported.")
-
-ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84),
-"Unable to import. File version not supported.")
-
-ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85),
-"Unable to import. Incorrect privacy password.")
-
-ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86),
-"Unable to import. Same nickname already exists in database.")
-
-ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87),
-"The user pressed cancel.")
-
-ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88),
-"Not imported, already in database.")
-
-ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89),
-"Message not sent.")
-
-ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90),
-"Certificate key usage inadequate for attempted operation.")
-
-ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91),
-"Certificate type not approved for application.")
-
-ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92),
-"Address in signing certificate does not match address in message headers.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93),
-"Unable to import. Error attempting to import private key.")
-
-ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94),
-"Unable to import. Error attempting to import certificate chain.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95),
-"Unable to export. Unable to locate certificate or key by nickname.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96),
-"Unable to export. Private Key could not be located and exported.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97),
-"Unable to export. Unable to write the export file.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98),
-"Unable to import. Unable to read the import file.")
-
-ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99),
-"Unable to export. Key database corrupt or deleted.")
-
-ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100),
-"Unable to generate public/private key pair.")
-
-ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101),
-"Password entered is invalid. Please pick a different one.")
-
-ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102),
-"Old password entered incorrectly. Please try again.")
-
-ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103),
-"Certificate nickname already in use.")
-
-ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104),
-"Peer FORTEZZA chain has a non-FORTEZZA Certificate.")
-
-ER3(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, (SEC_ERROR_BASE + 105),
-"A sensitive key cannot be moved to the slot where it is needed.")
-
-ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106),
-"Invalid module name.")
-
-ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107),
-"Invalid module path/filename")
-
-ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108),
-"Unable to add module")
-
-ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109),
-"Unable to delete module")
-
-ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110),
-"New KRL is not later than the current one.")
-
-ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111),
-"New CKL has different issuer than current CKL. Delete current CKL.")
-
-ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112),
-"The Certifying Authority for this certificate is not permitted to issue a \
-certificate with this name.")
-
-ER3(SEC_ERROR_KRL_NOT_YET_VALID, (SEC_ERROR_BASE + 113),
-"The key revocation list for this certificate is not yet valid.")
-
-ER3(SEC_ERROR_CRL_NOT_YET_VALID, (SEC_ERROR_BASE + 114),
-"The certificate revocation list for this certificate is not yet valid.")
-
-ER3(SEC_ERROR_UNKNOWN_CERT, (SEC_ERROR_BASE + 115),
-"The requested certificate could not be found.")
-
-ER3(SEC_ERROR_UNKNOWN_SIGNER, (SEC_ERROR_BASE + 116),
-"The signer's certificate could not be found.")
-
-ER3(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, (SEC_ERROR_BASE + 117),
-"The location for the certificate status server has invalid format.")
-
-ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, (SEC_ERROR_BASE + 118),
-"The OCSP response cannot be fully decoded; it is of an unknown type.")
-
-ER3(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 119),
-"The OCSP server returned unexpected/invalid HTTP data.")
-
-ER3(SEC_ERROR_OCSP_MALFORMED_REQUEST, (SEC_ERROR_BASE + 120),
-"The OCSP server found the request to be corrupted or improperly formed.")
-
-ER3(SEC_ERROR_OCSP_SERVER_ERROR, (SEC_ERROR_BASE + 121),
-"The OCSP server experienced an internal error.")
-
-ER3(SEC_ERROR_OCSP_TRY_SERVER_LATER, (SEC_ERROR_BASE + 122),
-"The OCSP server suggests trying again later.")
-
-ER3(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, (SEC_ERROR_BASE + 123),
-"The OCSP server requires a signature on this request.")
-
-ER3(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, (SEC_ERROR_BASE + 124),
-"The OCSP server has refused this request as unauthorized.")
-
-ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, (SEC_ERROR_BASE + 125),
-"The OCSP server returned an unrecognizable status.")
-
-ER3(SEC_ERROR_OCSP_UNKNOWN_CERT, (SEC_ERROR_BASE + 126),
-"The OCSP server has no status for the certificate.")
-
-ER3(SEC_ERROR_OCSP_NOT_ENABLED, (SEC_ERROR_BASE + 127),
-"You must enable OCSP before performing this operation.")
-
-ER3(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, (SEC_ERROR_BASE + 128),
-"You must set the OCSP default responder before performing this operation.")
-
-ER3(SEC_ERROR_OCSP_MALFORMED_RESPONSE, (SEC_ERROR_BASE + 129),
-"The response from the OCSP server was corrupted or improperly formed.")
-
-ER3(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, (SEC_ERROR_BASE + 130),
-"The signer of the OCSP response is not authorized to give status for \
-this certificate.")
-
-ER3(SEC_ERROR_OCSP_FUTURE_RESPONSE, (SEC_ERROR_BASE + 131),
-"The OCSP response is not yet valid (contains a date in the future).")
-
-ER3(SEC_ERROR_OCSP_OLD_RESPONSE, (SEC_ERROR_BASE + 132),
-"The OCSP response contains out-of-date information.")
-
-ER3(SEC_ERROR_DIGEST_NOT_FOUND, (SEC_ERROR_BASE + 133),
-"The CMS or PKCS #7 Digest was not found in signed message.")
-
-ER3(SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, (SEC_ERROR_BASE + 134),
-"The CMS or PKCS #7 Message type is unsupported.")
-
-ER3(SEC_ERROR_MODULE_STUCK, (SEC_ERROR_BASE + 135),
-"PKCS #11 module could not be removed because it is still in use.")
-
-ER3(SEC_ERROR_BAD_TEMPLATE, (SEC_ERROR_BASE + 136),
-"Could not decode ASN.1 data. Specified template was invalid.")
-
-ER3(SEC_ERROR_CRL_NOT_FOUND, (SEC_ERROR_BASE + 137),
-"No matching CRL was found.")
-
-ER3(SEC_ERROR_REUSED_ISSUER_AND_SERIAL, (SEC_ERROR_BASE + 138),
-"You are attempting to import a cert with the same issuer/serial as \
-an existing cert, but that is not the same cert.")
-
-ER3(SEC_ERROR_BUSY, (SEC_ERROR_BASE + 139),
-"NSS could not shutdown. Objects are still in use.")
-
-ER3(SEC_ERROR_EXTRA_INPUT, (SEC_ERROR_BASE + 140),
-"DER-encoded message contained extra unused data.")
-
-ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141),
-"Unsupported elliptic curve.")
-
-ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142),
-"Unsupported elliptic curve point form.")
-
-ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143),
-"Unrecognized Object Identifier.")
-
-ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144),
-"Invalid OCSP signing certificate in OCSP response.")
-
-ER3(SEC_ERROR_REVOKED_CERTIFICATE_CRL, (SEC_ERROR_BASE + 145),
-"Certificate is revoked in issuer's certificate revocation list.")
-
-ER3(SEC_ERROR_REVOKED_CERTIFICATE_OCSP, (SEC_ERROR_BASE + 146),
-"Issuer's OCSP responder reports certificate is revoked.")
-
-ER3(SEC_ERROR_CRL_INVALID_VERSION, (SEC_ERROR_BASE + 147),
-"Issuer's Certificate Revocation List has an unknown version number.")
-
-ER3(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 148),
-"Issuer's V1 Certificate Revocation List has a critical extension.")
-
-ER3(SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 149),
-"Issuer's V2 Certificate Revocation List has an unknown critical extension.")
-
-ER3(SEC_ERROR_UNKNOWN_OBJECT_TYPE, (SEC_ERROR_BASE + 150),
-"Unknown object type specified.")
-
-ER3(SEC_ERROR_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151),
-"PKCS #11 driver violates the spec in an incompatible way.")
-
-ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152),
-"No new slot event is available at this time.")
-
-ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153),
-"CRL already exists.")
-
-ER3(SEC_ERROR_NOT_INITIALIZED, (SEC_ERROR_BASE + 154),
-"NSS is not initialized.")
-
-ER3(SEC_ERROR_TOKEN_NOT_LOGGED_IN, (SEC_ERROR_BASE + 155),
-"The operation failed because the PKCS#11 token is not logged in.")
-
-ER3(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID, (SEC_ERROR_BASE + 156),
-"Configured OCSP responder's certificate is invalid.")
-
-ER3(SEC_ERROR_OCSP_BAD_SIGNATURE, (SEC_ERROR_BASE + 157),
-"OCSP response has an invalid signature.")
-
-ER3(SEC_ERROR_OUT_OF_SEARCH_LIMITS, (SEC_ERROR_BASE + 158),
-"Cert validation search is out of search limits")
-
-ER3(SEC_ERROR_INVALID_POLICY_MAPPING, (SEC_ERROR_BASE + 159),
-"Policy mapping contains anypolicy")
-
-ER3(SEC_ERROR_POLICY_VALIDATION_FAILED, (SEC_ERROR_BASE + 160),
-"Cert chain fails policy validation")
-
-ER3(SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE, (SEC_ERROR_BASE + 161),
-"Unknown location type in cert AIA extension")
-
-ER3(SEC_ERROR_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 162),
-"Server returned bad HTTP response")
-
-ER3(SEC_ERROR_BAD_LDAP_RESPONSE, (SEC_ERROR_BASE + 163),
-"Server returned bad LDAP response")
-
-ER3(SEC_ERROR_FAILED_TO_ENCODE_DATA, (SEC_ERROR_BASE + 164),
-"Failed to encode data with ASN1 encoder")
-
-ER3(SEC_ERROR_BAD_INFO_ACCESS_LOCATION, (SEC_ERROR_BASE + 165),
-"Bad information access location in cert extension")
-
-ER3(SEC_ERROR_LIBPKIX_INTERNAL, (SEC_ERROR_BASE + 166),
-"Libpkix internal error occurred during cert validation.")
-
-ER3(SEC_ERROR_PKCS11_GENERAL_ERROR, (SEC_ERROR_BASE + 167),
-"A PKCS #11 module returned CKR_GENERAL_ERROR, indicating that an unrecoverable error has occurred.")
-
-ER3(SEC_ERROR_PKCS11_FUNCTION_FAILED, (SEC_ERROR_BASE + 168),
-"A PKCS #11 module returned CKR_FUNCTION_FAILED, indicating that the requested function could not be performed. Trying the same operation again might succeed.")
-
-ER3(SEC_ERROR_PKCS11_DEVICE_ERROR, (SEC_ERROR_BASE + 169),
-"A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot.")
-
-ER3(SEC_ERROR_BAD_INFO_ACCESS_METHOD, (SEC_ERROR_BASE + 170),
-"Unknown information access method in certificate extension.")
-
-ER3(SEC_ERROR_CRL_IMPORT_FAILED, (SEC_ERROR_BASE + 171),
-"Error attempting to import a CRL.")
-
-ER3(SEC_ERROR_EXPIRED_PASSWORD, (SEC_ERROR_BASE + 172),
-"The password expired.")
-
-ER3(SEC_ERROR_LOCKED_PASSWORD, (SEC_ERROR_BASE + 173),
-"The password is locked.")
-
-ER3(SEC_ERROR_UNKNOWN_PKCS11_ERROR, (SEC_ERROR_BASE + 174),
-"Unknown PKCS #11 error.")
-
-ER3(SEC_ERROR_BAD_CRL_DP_URL, (SEC_ERROR_BASE + 175),
-"Invalid or unsupported URL in CRL distribution point name.")
-
-ER3(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED, (SEC_ERROR_BASE + 176),
-"The certificate was signed using a signature algorithm that is disabled because it is not secure.")
-
-ER3(SEC_ERROR_LEGACY_DATABASE, (SEC_ERROR_BASE + 177),
-"The certificate/key database is in an old, unsupported format.")
-
-ER3(SEC_ERROR_APPLICATION_CALLBACK_ERROR, (SEC_ERROR_BASE + 178),
-"The certificate was rejected by extra checks in the application.")
-
diff --git a/security/nss/lib/util/base64.h b/security/nss/lib/util/base64.h
deleted file mode 100644
index 1bd42ab8b..000000000
--- a/security/nss/lib/util/base64.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * base64.h - prototypes for base64 encoding/decoding
- * Note: These functions are deprecated; see nssb64.h for new routines.
- *
- * $Id$
- */
-#ifndef _BASE64_H_
-#define _BASE64_H_
-
-#include "utilrename.h"
-#include "seccomon.h"
-
-SEC_BEGIN_PROTOS
-
-/*
-** Return an PORT_Alloc'd ascii string which is the base64 encoded
-** version of the input string.
-*/
-extern char *BTOA_DataToAscii(const unsigned char *data, unsigned int len);
-
-/*
-** Return an PORT_Alloc'd string which is the base64 decoded version
-** of the input string; set *lenp to the length of the returned data.
-*/
-extern unsigned char *ATOB_AsciiToData(const char *string, unsigned int *lenp);
-
-/*
-** Convert from ascii to binary encoding of an item.
-*/
-extern SECStatus ATOB_ConvertAsciiToItem(SECItem *binary_item, const char *ascii);
-
-/*
-** Convert from binary encoding of an item to ascii.
-*/
-extern char *BTOA_ConvertItemToAscii(SECItem *binary_item);
-
-SEC_END_PROTOS
-
-#endif /* _BASE64_H_ */
diff --git a/security/nss/lib/util/ciferfam.h b/security/nss/lib/util/ciferfam.h
deleted file mode 100644
index 8d288a926..000000000
--- a/security/nss/lib/util/ciferfam.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * ciferfam.h - cipher familie IDs used for configuring ciphers for export
- * control
- *
- * $Id$
- */
-
-#ifndef _CIFERFAM_H_
-#define _CIFERFAM_H_
-
-#include "utilrename.h"
-/* Cipher Suite "Families" */
-#define CIPHER_FAMILY_PKCS12 "PKCS12"
-#define CIPHER_FAMILY_SMIME "SMIME"
-#define CIPHER_FAMILY_SSL2 "SSLv2"
-#define CIPHER_FAMILY_SSL3 "SSLv3"
-#define CIPHER_FAMILY_SSL "SSL"
-#define CIPHER_FAMILY_ALL ""
-#define CIPHER_FAMILY_UNKNOWN "UNKNOWN"
-
-#define CIPHER_FAMILYID_MASK 0xFFFF0000L
-#define CIPHER_FAMILYID_SSL 0x00000000L
-#define CIPHER_FAMILYID_SMIME 0x00010000L
-#define CIPHER_FAMILYID_PKCS12 0x00020000L
-
-/* SMIME "Cipher Suites" */
-/*
- * Note that it is assumed that the cipher number itself can be used
- * as a bit position in a mask, and that mask is currently 32 bits wide.
- * So, if you want to add a cipher that is greater than 0037, secmime.c
- * needs to be made smarter at the same time.
- */
-#define SMIME_RC2_CBC_40 (CIPHER_FAMILYID_SMIME | 0001)
-#define SMIME_RC2_CBC_64 (CIPHER_FAMILYID_SMIME | 0002)
-#define SMIME_RC2_CBC_128 (CIPHER_FAMILYID_SMIME | 0003)
-#define SMIME_DES_CBC_56 (CIPHER_FAMILYID_SMIME | 0011)
-#define SMIME_DES_EDE3_168 (CIPHER_FAMILYID_SMIME | 0012)
-#define SMIME_AES_CBC_128 (CIPHER_FAMILYID_SMIME | 0013)
-#define SMIME_AES_CBC_256 (CIPHER_FAMILYID_SMIME | 0014)
-#define SMIME_RC5PAD_64_16_40 (CIPHER_FAMILYID_SMIME | 0021)
-#define SMIME_RC5PAD_64_16_64 (CIPHER_FAMILYID_SMIME | 0022)
-#define SMIME_RC5PAD_64_16_128 (CIPHER_FAMILYID_SMIME | 0023)
-#define SMIME_FORTEZZA (CIPHER_FAMILYID_SMIME | 0031)
-
-/* PKCS12 "Cipher Suites" */
-
-#define PKCS12_RC2_CBC_40 (CIPHER_FAMILYID_PKCS12 | 0001)
-#define PKCS12_RC2_CBC_128 (CIPHER_FAMILYID_PKCS12 | 0002)
-#define PKCS12_RC4_40 (CIPHER_FAMILYID_PKCS12 | 0011)
-#define PKCS12_RC4_128 (CIPHER_FAMILYID_PKCS12 | 0012)
-#define PKCS12_DES_56 (CIPHER_FAMILYID_PKCS12 | 0021)
-#define PKCS12_DES_EDE3_168 (CIPHER_FAMILYID_PKCS12 | 0022)
-
-/* SMIME version numbers are negative, to avoid colliding with SSL versions */
-#define SMIME_LIBRARY_VERSION_1_0 -0x0100
-
-#endif /* _CIFERFAM_H_ */
diff --git a/security/nss/lib/util/config.mk b/security/nss/lib/util/config.mk
deleted file mode 100644
index a3e720218..000000000
--- a/security/nss/lib/util/config.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-# don't want the 32 in the shared library name
-SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX)
-
-RES = $(OBJDIR)/$(LIBRARY_NAME).res
-RESNAME = $(LIBRARY_NAME).rc
-
-ifdef NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4\
- $(NULL)
-else # ! NS_USE_GCC
-EXTRA_SHARED_LIBS += \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-
-else
-
-# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
-# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
-EXTRA_SHARED_LIBS += \
- -L$(DIST)/lib \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-
-endif
-
diff --git a/security/nss/lib/util/derdec.c b/security/nss/lib/util/derdec.c
deleted file mode 100644
index c62191487..000000000
--- a/security/nss/lib/util/derdec.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secder.h"
-#include "secerr.h"
-
-static PRUint32
-der_indefinite_length(unsigned char *buf, unsigned char *end)
-{
- PRUint32 len, ret, dataLen;
- unsigned char tag, lenCode;
- int dataLenLen;
-
- len = 0;
- while ( 1 ) {
- if ((buf + 2) > end) {
- return(0);
- }
-
- tag = *buf++;
- lenCode = *buf++;
- len += 2;
-
- if ( ( tag == 0 ) && ( lenCode == 0 ) ) {
- return(len);
- }
-
- if ( lenCode == 0x80 ) { /* indefinite length */
- ret = der_indefinite_length(buf, end); /* recurse to find length */
- if (ret == 0)
- return 0;
- len += ret;
- buf += ret;
- } else { /* definite length */
- if (lenCode & 0x80) {
- /* Length of data is in multibyte format */
- dataLenLen = lenCode & 0x7f;
- switch (dataLenLen) {
- case 1:
- dataLen = buf[0];
- break;
- case 2:
- dataLen = (buf[0]<<8)|buf[1];
- break;
- case 3:
- dataLen = ((unsigned long)buf[0]<<16)|(buf[1]<<8)|buf[2];
- break;
- case 4:
- dataLen = ((unsigned long)buf[0]<<24)|
- ((unsigned long)buf[1]<<16)|(buf[2]<<8)|buf[3];
- break;
- default:
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECFailure;
- }
- } else {
- /* Length of data is in single byte */
- dataLen = lenCode;
- dataLenLen = 0;
- }
-
- /* skip this item */
- buf = buf + dataLenLen + dataLen;
- len = len + dataLenLen + dataLen;
- }
- }
-}
-
-/*
-** Capture the next thing in the buffer.
-** Returns the length of the header and the length of the contents.
-*/
-static SECStatus
-der_capture(unsigned char *buf, unsigned char *end,
- int *header_len_p, PRUint32 *contents_len_p)
-{
- unsigned char *bp;
- unsigned char whole_tag;
- PRUint32 contents_len;
- int tag_number;
-
- if ((buf + 2) > end) {
- *header_len_p = 0;
- *contents_len_p = 0;
- if (buf == end)
- return SECSuccess;
- return SECFailure;
- }
-
- bp = buf;
-
- /* Get tag and verify that it is ok. */
- whole_tag = *bp++;
- tag_number = whole_tag & DER_TAGNUM_MASK;
-
- /*
- * XXX This code does not (yet) handle the high-tag-number form!
- */
- if (tag_number == DER_HIGH_TAG_NUMBER) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECFailure;
- }
-
- if ((whole_tag & DER_CLASS_MASK) == DER_UNIVERSAL) {
- /* Check that the universal tag number is one we implement. */
- switch (tag_number) {
- case DER_BOOLEAN:
- case DER_INTEGER:
- case DER_BIT_STRING:
- case DER_OCTET_STRING:
- case DER_NULL:
- case DER_OBJECT_ID:
- case DER_SEQUENCE:
- case DER_SET:
- case DER_PRINTABLE_STRING:
- case DER_T61_STRING:
- case DER_IA5_STRING:
- case DER_VISIBLE_STRING:
- case DER_UTC_TIME:
- case 0: /* end-of-contents tag */
- break;
- default:
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECFailure;
- }
- }
-
- /*
- * Get first byte of length code (might contain entire length, might not).
- */
- contents_len = *bp++;
-
- /*
- * If the high bit is set, then the length is in multibyte format,
- * or the thing has an indefinite-length.
- */
- if (contents_len & 0x80) {
- int bytes_of_encoded_len;
-
- bytes_of_encoded_len = contents_len & 0x7f;
- contents_len = 0;
-
- switch (bytes_of_encoded_len) {
- case 4:
- contents_len |= *bp++;
- contents_len <<= 8;
- /* fallthru */
- case 3:
- contents_len |= *bp++;
- contents_len <<= 8;
- /* fallthru */
- case 2:
- contents_len |= *bp++;
- contents_len <<= 8;
- /* fallthru */
- case 1:
- contents_len |= *bp++;
- break;
-
- case 0:
- contents_len = der_indefinite_length (bp, end);
- if (contents_len)
- break;
- /* fallthru */
- default:
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECFailure;
- }
- }
-
- if ((bp + contents_len) > end) {
- /* Ran past end of buffer */
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECFailure;
- }
-
- *header_len_p = bp - buf;
- *contents_len_p = contents_len;
-
- return SECSuccess;
-}
-
-SECStatus
-DER_Lengths(SECItem *item, int *header_len_p, PRUint32 *contents_len_p)
-{
- return(der_capture(item->data, &item->data[item->len], header_len_p,
- contents_len_p));
-}
diff --git a/security/nss/lib/util/derenc.c b/security/nss/lib/util/derenc.c
deleted file mode 100644
index 459878b3f..000000000
--- a/security/nss/lib/util/derenc.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secder.h"
-#include "secerr.h"
-
-#if 0
-/*
- * Generic templates for individual/simple items.
- */
-
-DERTemplate SECAnyTemplate[] = {
- { DER_ANY,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECBitStringTemplate[] = {
- { DER_BIT_STRING,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECBooleanTemplate[] = {
- { DER_BOOLEAN,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECIA5StringTemplate[] = {
- { DER_IA5_STRING,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECIntegerTemplate[] = {
- { DER_INTEGER,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECNullTemplate[] = {
- { DER_NULL,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECObjectIDTemplate[] = {
- { DER_OBJECT_ID,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECOctetStringTemplate[] = {
- { DER_OCTET_STRING,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECPrintableStringTemplate[] = {
- { DER_PRINTABLE_STRING,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECT61StringTemplate[] = {
- { DER_T61_STRING,
- 0, NULL, sizeof(SECItem) }
-};
-
-DERTemplate SECUTCTimeTemplate[] = {
- { DER_UTC_TIME,
- 0, NULL, sizeof(SECItem) }
-};
-
-#endif
-
-static int
-header_length(DERTemplate *dtemplate, PRUint32 contents_len)
-{
- PRUint32 len;
- unsigned long encode_kind, under_kind;
- PRBool explicit, optional, universal;
-
- encode_kind = dtemplate->kind;
-
- explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
- optional = (encode_kind & DER_OPTIONAL) ? PR_TRUE : PR_FALSE;
- universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
- ? PR_TRUE : PR_FALSE;
-
- PORT_Assert (!(explicit && universal)); /* bad templates */
-
- if (encode_kind & DER_POINTER) {
- if (dtemplate->sub != NULL) {
- under_kind = dtemplate->sub->kind;
- if (universal) {
- encode_kind = under_kind;
- }
- } else if (universal) {
- under_kind = encode_kind & ~DER_POINTER;
- } else {
- under_kind = dtemplate->arg;
- }
- } else if (encode_kind & DER_INLINE) {
- PORT_Assert (dtemplate->sub != NULL);
- under_kind = dtemplate->sub->kind;
- if (universal) {
- encode_kind = under_kind;
- }
- } else if (universal) {
- under_kind = encode_kind;
- } else {
- under_kind = dtemplate->arg;
- }
-
- /* This is only used in decoding; it plays no part in encoding. */
- if (under_kind & DER_DERPTR)
- return 0;
-
- /* No header at all for an "empty" optional. */
- if ((contents_len == 0) && optional)
- return 0;
-
- /* And no header for a full DER_ANY. */
- if (encode_kind & DER_ANY)
- return 0;
-
- /*
- * The common case: one octet for identifier and as many octets
- * as necessary to hold the content length.
- */
- len = 1 + DER_LengthLength(contents_len);
-
- /* Account for the explicit wrapper, if necessary. */
- if (explicit) {
-#if 0 /*
- * Well, I was trying to do something useful, but these
- * assertions are too restrictive on valid templates.
- * I wanted to make sure that the top-level "kind" of
- * a template does not also specify DER_EXPLICIT, which
- * should only modify a component field. Maybe later
- * I can figure out a better way to detect such a problem,
- * but for now I must remove these checks altogether.
- */
- /*
- * This modifier applies only to components of a set or sequence;
- * it should never be used on a set/sequence itself -- confirm.
- */
- PORT_Assert (under_kind != DER_SEQUENCE);
- PORT_Assert (under_kind != DER_SET);
-#endif
-
- len += 1 + DER_LengthLength(len + contents_len);
- }
-
- return len;
-}
-
-
-static PRUint32
-contents_length(DERTemplate *dtemplate, void *src)
-{
- PRUint32 len;
- unsigned long encode_kind, under_kind;
- PRBool universal;
-
-
- PORT_Assert (src != NULL);
-
- encode_kind = dtemplate->kind;
-
- universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
- ? PR_TRUE : PR_FALSE;
- encode_kind &= ~DER_OPTIONAL;
-
- if (encode_kind & DER_POINTER) {
- src = *(void **)src;
- if (src == NULL) {
- return 0;
- }
- if (dtemplate->sub != NULL) {
- dtemplate = dtemplate->sub;
- under_kind = dtemplate->kind;
- src = (void *)((char *)src + dtemplate->offset);
- } else if (universal) {
- under_kind = encode_kind & ~DER_POINTER;
- } else {
- under_kind = dtemplate->arg;
- }
- } else if (encode_kind & DER_INLINE) {
- PORT_Assert (dtemplate->sub != NULL);
- dtemplate = dtemplate->sub;
- under_kind = dtemplate->kind;
- src = (void *)((char *)src + dtemplate->offset);
- } else if (universal) {
- under_kind = encode_kind;
- } else {
- under_kind = dtemplate->arg;
- }
-
- /* Having any of these bits is not expected here... */
- PORT_Assert ((under_kind & (DER_EXPLICIT | DER_INLINE | DER_OPTIONAL
- | DER_POINTER | DER_SKIP)) == 0);
-
- /* This is only used in decoding; it plays no part in encoding. */
- if (under_kind & DER_DERPTR)
- return 0;
-
- if (under_kind & DER_INDEFINITE) {
- PRUint32 sub_len;
- void **indp = *(void ***)src;
-
- if (indp == NULL)
- return 0;
-
- len = 0;
- under_kind &= ~DER_INDEFINITE;
-
- if (under_kind == DER_SET || under_kind == DER_SEQUENCE) {
- DERTemplate *tmpt = dtemplate->sub;
- PORT_Assert (tmpt != NULL);
-
- for (; *indp != NULL; indp++) {
- void *sub_src = (void *)((char *)(*indp) + tmpt->offset);
- sub_len = contents_length (tmpt, sub_src);
- len += sub_len + header_length (tmpt, sub_len);
- }
- } else {
- /*
- * XXX Lisa is not sure this code (for handling, for example,
- * DER_INDEFINITE | DER_OCTET_STRING) is right.
- */
- for (; *indp != NULL; indp++) {
- SECItem *item = (SECItem *)(*indp);
- sub_len = item->len;
- if (under_kind == DER_BIT_STRING) {
- sub_len = (sub_len + 7) >> 3;
- /* bit string contents involve an extra octet */
- if (sub_len)
- sub_len++;
- }
- if (under_kind != DER_ANY)
- len += 1 + DER_LengthLength (sub_len);
- }
- }
-
- return len;
- }
-
- switch (under_kind) {
- case DER_SEQUENCE:
- case DER_SET:
- {
- DERTemplate *tmpt;
- void *sub_src;
- PRUint32 sub_len;
-
- len = 0;
- for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) {
- sub_src = (void *)((char *)src + tmpt->offset);
- sub_len = contents_length (tmpt, sub_src);
- len += sub_len + header_length (tmpt, sub_len);
- }
- }
- break;
-
- case DER_BIT_STRING:
- len = (((SECItem *)src)->len + 7) >> 3;
- /* bit string contents involve an extra octet */
- if (len)
- len++;
- break;
-
- default:
- len = ((SECItem *)src)->len;
- break;
- }
-
- return len;
-}
-
-
-static unsigned char *
-der_encode(unsigned char *buf, DERTemplate *dtemplate, void *src)
-{
- int header_len;
- PRUint32 contents_len;
- unsigned long encode_kind, under_kind;
- PRBool explicit, optional, universal;
-
-
- /*
- * First figure out how long the encoding will be. Do this by
- * traversing the template from top to bottom and accumulating
- * the length of each leaf item.
- */
- contents_len = contents_length (dtemplate, src);
- header_len = header_length (dtemplate, contents_len);
-
- /*
- * Enough smarts was involved already, so that if both the
- * header and the contents have a length of zero, then we
- * are not doing any encoding for this element.
- */
- if (header_len == 0 && contents_len == 0)
- return buf;
-
- encode_kind = dtemplate->kind;
-
- explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
- optional = (encode_kind & DER_OPTIONAL) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~DER_OPTIONAL;
- universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
- ? PR_TRUE : PR_FALSE;
-
- if (encode_kind & DER_POINTER) {
- if (contents_len) {
- src = *(void **)src;
- PORT_Assert (src != NULL);
- }
- if (dtemplate->sub != NULL) {
- dtemplate = dtemplate->sub;
- under_kind = dtemplate->kind;
- if (universal) {
- encode_kind = under_kind;
- }
- src = (void *)((char *)src + dtemplate->offset);
- } else if (universal) {
- under_kind = encode_kind & ~DER_POINTER;
- } else {
- under_kind = dtemplate->arg;
- }
- } else if (encode_kind & DER_INLINE) {
- dtemplate = dtemplate->sub;
- under_kind = dtemplate->kind;
- if (universal) {
- encode_kind = under_kind;
- }
- src = (void *)((char *)src + dtemplate->offset);
- } else if (universal) {
- under_kind = encode_kind;
- } else {
- under_kind = dtemplate->arg;
- }
-
- if (explicit) {
- buf = DER_StoreHeader (buf, encode_kind,
- (1 + DER_LengthLength(contents_len)
- + contents_len));
- encode_kind = under_kind;
- }
-
- if ((encode_kind & DER_ANY) == 0) { /* DER_ANY already contains header */
- buf = DER_StoreHeader (buf, encode_kind, contents_len);
- }
-
- /* If no real contents to encode, then we are done. */
- if (contents_len == 0)
- return buf;
-
- if (under_kind & DER_INDEFINITE) {
- void **indp;
-
- indp = *(void ***)src;
- PORT_Assert (indp != NULL);
-
- under_kind &= ~DER_INDEFINITE;
- if (under_kind == DER_SET || under_kind == DER_SEQUENCE) {
- DERTemplate *tmpt = dtemplate->sub;
- PORT_Assert (tmpt != NULL);
- for (; *indp != NULL; indp++) {
- void *sub_src = (void *)((char *)(*indp) + tmpt->offset);
- buf = der_encode (buf, tmpt, sub_src);
- }
- } else {
- for (; *indp != NULL; indp++) {
- SECItem *item;
- int sub_len;
-
- item = (SECItem *)(*indp);
- sub_len = item->len;
- if (under_kind == DER_BIT_STRING) {
- if (sub_len) {
- int rem;
-
- sub_len = (sub_len + 7) >> 3;
- buf = DER_StoreHeader (buf, under_kind, sub_len + 1);
- rem = (sub_len << 3) - item->len;
- *buf++ = rem; /* remaining bits */
- } else {
- buf = DER_StoreHeader (buf, under_kind, 0);
- }
- } else if (under_kind != DER_ANY) {
- buf = DER_StoreHeader (buf, under_kind, sub_len);
- }
- PORT_Memcpy (buf, item->data, sub_len);
- buf += sub_len;
- }
- }
- return buf;
- }
-
- switch (under_kind) {
- case DER_SEQUENCE:
- case DER_SET:
- {
- DERTemplate *tmpt;
- void *sub_src;
-
- for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) {
- sub_src = (void *)((char *)src + tmpt->offset);
- buf = der_encode (buf, tmpt, sub_src);
- }
- }
- break;
-
- case DER_BIT_STRING:
- {
- SECItem *item;
- int rem;
-
- /*
- * The contents length includes our extra octet; subtract
- * it off so we just have the real string length there.
- */
- contents_len--;
- item = (SECItem *)src;
- PORT_Assert (contents_len == ((item->len + 7) >> 3));
- rem = (contents_len << 3) - item->len;
- *buf++ = rem; /* remaining bits */
- PORT_Memcpy (buf, item->data, contents_len);
- buf += contents_len;
- }
- break;
-
- default:
- {
- SECItem *item;
-
- item = (SECItem *)src;
- PORT_Assert (contents_len == item->len);
- PORT_Memcpy (buf, item->data, contents_len);
- buf += contents_len;
- }
- break;
- }
-
- return buf;
-}
-
-
-SECStatus
-DER_Encode(PRArenaPool *arena, SECItem *dest, DERTemplate *dtemplate, void *src)
-{
- unsigned int contents_len, header_len;
-
- src = (void **)((char *)src + dtemplate->offset);
-
- /*
- * First figure out how long the encoding will be. Do this by
- * traversing the template from top to bottom and accumulating
- * the length of each leaf item.
- */
- contents_len = contents_length (dtemplate, src);
- header_len = header_length (dtemplate, contents_len);
-
- dest->len = contents_len + header_len;
-
- /* Allocate storage to hold the encoding */
- dest->data = (unsigned char*) PORT_ArenaAlloc(arena, dest->len);
- if (dest->data == NULL) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-
- /* Now encode into the buffer */
- (void) der_encode (dest->data, dtemplate, src);
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/util/dersubr.c b/security/nss/lib/util/dersubr.c
deleted file mode 100644
index 103613935..000000000
--- a/security/nss/lib/util/dersubr.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secder.h"
-#include <limits.h>
-#include "secerr.h"
-
-int
-DER_LengthLength(PRUint32 len)
-{
- if (len > 127) {
- if (len > 255) {
- if (len > 65535L) {
- if (len > 16777215L) {
- return 5;
- } else {
- return 4;
- }
- } else {
- return 3;
- }
- } else {
- return 2;
- }
- } else {
- return 1;
- }
-}
-
-unsigned char *
-DER_StoreHeader(unsigned char *buf, unsigned int code, PRUint32 len)
-{
- unsigned char b[4];
-
- b[0] = (unsigned char)(len >> 24);
- b[1] = (unsigned char)(len >> 16);
- b[2] = (unsigned char)(len >> 8);
- b[3] = (unsigned char)len;
- if ((code & DER_TAGNUM_MASK) == DER_SET
- || (code & DER_TAGNUM_MASK) == DER_SEQUENCE)
- code |= DER_CONSTRUCTED;
- *buf++ = code;
- if (len > 127) {
- if (len > 255) {
- if (len > 65535) {
- if (len > 16777215) {
- *buf++ = 0x84;
- *buf++ = b[0];
- *buf++ = b[1];
- *buf++ = b[2];
- *buf++ = b[3];
- } else {
- *buf++ = 0x83;
- *buf++ = b[1];
- *buf++ = b[2];
- *buf++ = b[3];
- }
- } else {
- *buf++ = 0x82;
- *buf++ = b[2];
- *buf++ = b[3];
- }
- } else {
- *buf++ = 0x81;
- *buf++ = b[3];
- }
- } else {
- *buf++ = b[3];
- }
- return buf;
-}
-
-/*
- * XXX This should be rewritten, generalized, to take a long instead
- * of a PRInt32.
- */
-SECStatus
-DER_SetInteger(PRArenaPool *arena, SECItem *it, PRInt32 i)
-{
- unsigned char bb[4];
- unsigned len;
-
- bb[0] = (unsigned char) (i >> 24);
- bb[1] = (unsigned char) (i >> 16);
- bb[2] = (unsigned char) (i >> 8);
- bb[3] = (unsigned char) (i);
-
- /*
- ** Small integers are encoded in a single byte. Larger integers
- ** require progressively more space.
- */
- if (i < -128) {
- if (i < -32768L) {
- if (i < -8388608L) {
- len = 4;
- } else {
- len = 3;
- }
- } else {
- len = 2;
- }
- } else if (i > 127) {
- if (i > 32767L) {
- if (i > 8388607L) {
- len = 4;
- } else {
- len = 3;
- }
- } else {
- len = 2;
- }
- } else {
- len = 1;
- }
- it->data = (unsigned char*) PORT_ArenaAlloc(arena, len);
- if (!it->data) {
- return SECFailure;
- }
- it->len = len;
- PORT_Memcpy(it->data, bb + (4 - len), len);
- return SECSuccess;
-}
-
-/*
- * XXX This should be rewritten, generalized, to take an unsigned long instead
- * of a PRUint32.
- */
-SECStatus
-DER_SetUInteger(PRArenaPool *arena, SECItem *it, PRUint32 ui)
-{
- unsigned char bb[5];
- int len;
-
- bb[0] = 0;
- bb[1] = (unsigned char) (ui >> 24);
- bb[2] = (unsigned char) (ui >> 16);
- bb[3] = (unsigned char) (ui >> 8);
- bb[4] = (unsigned char) (ui);
-
- /*
- ** Small integers are encoded in a single byte. Larger integers
- ** require progressively more space.
- */
- if (ui > 0x7f) {
- if (ui > 0x7fff) {
- if (ui > 0x7fffffL) {
- if (ui >= 0x80000000L) {
- len = 5;
- } else {
- len = 4;
- }
- } else {
- len = 3;
- }
- } else {
- len = 2;
- }
- } else {
- len = 1;
- }
-
- it->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
- if (it->data == NULL) {
- return SECFailure;
- }
-
- it->len = len;
- PORT_Memcpy(it->data, bb + (sizeof(bb) - len), len);
-
- return SECSuccess;
-}
-
-/*
-** Convert a der encoded *signed* integer into a machine integral value.
-** If an underflow/overflow occurs, sets error code and returns min/max.
-*/
-long
-DER_GetInteger(SECItem *it)
-{
- long ival = 0;
- unsigned len = it->len;
- unsigned char *cp = it->data;
- unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1);
- unsigned long ofloinit;
-
- PORT_Assert(len);
- if (!len) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return 0;
- }
-
- if (*cp & 0x80)
- ival = -1L;
- ofloinit = ival & overflow;
-
- while (len) {
- if ((ival & overflow) != ofloinit) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- if (ival < 0) {
- return LONG_MIN;
- }
- return LONG_MAX;
- }
- ival = ival << 8;
- ival |= *cp++;
- --len;
- }
- return ival;
-}
-
-/*
-** Convert a der encoded *unsigned* integer into a machine integral value.
-** If an overflow occurs, sets error code and returns max.
-*/
-unsigned long
-DER_GetUInteger(SECItem *it)
-{
- unsigned long ival = 0;
- unsigned len = it->len;
- unsigned char *cp = it->data;
- unsigned long overflow = 0xffUL << ((sizeof(ival) - 1) * 8);
-
- PORT_Assert(len);
- if (!len) {
- PORT_SetError(SEC_ERROR_INPUT_LEN);
- return 0;
- }
-
- /* Cannot put a negative value into an unsigned container. */
- if (*cp & 0x80) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- return 0;
- }
-
- while (len) {
- if (ival & overflow) {
- PORT_SetError(SEC_ERROR_BAD_DER);
- return ULONG_MAX;
- }
- ival = ival << 8;
- ival |= *cp++;
- --len;
- }
- return ival;
-}
diff --git a/security/nss/lib/util/dertime.c b/security/nss/lib/util/dertime.c
deleted file mode 100644
index 53e97ab55..000000000
--- a/security/nss/lib/util/dertime.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "prtypes.h"
-#include "prtime.h"
-#include "secder.h"
-#include "prlong.h"
-#include "secerr.h"
-
-#define HIDIGIT(v) (((v) / 10) + '0')
-#define LODIGIT(v) (((v) % 10) + '0')
-
-#define ISDIGIT(dig) (((dig) >= '0') && ((dig) <= '9'))
-#define CAPTURE(var,p,label) \
-{ \
- if (!ISDIGIT((p)[0]) || !ISDIGIT((p)[1])) goto label; \
- (var) = ((p)[0] - '0') * 10 + ((p)[1] - '0'); \
- p += 2; \
-}
-
-static const PRTime January1st1 = (PRTime) LL_INIT(0xff234001U, 0x00d44000U);
-static const PRTime January1st1950 = (PRTime) LL_INIT(0xfffdc1f8U, 0x793da000U);
-static const PRTime January1st2050 = LL_INIT(0x0008f81e, 0x1b098000);
-static const PRTime January1st10000 = LL_INIT(0x0384440c, 0xcc736000);
-
-/* gmttime must contains UTC time in micro-seconds unit */
-SECStatus
-DER_TimeToUTCTimeArena(PRArenaPool* arenaOpt, SECItem *dst, int64 gmttime)
-{
- PRExplodedTime printableTime;
- unsigned char *d;
-
- if ( (gmttime < January1st1950) || (gmttime >= January1st2050) ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- dst->len = 13;
- if (arenaOpt) {
- dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len);
- } else {
- dst->data = d = (unsigned char*) PORT_Alloc(dst->len);
- }
- dst->type = siUTCTime;
- if (!d) {
- return SECFailure;
- }
-
- /* Convert an int64 time to a printable format. */
- PR_ExplodeTime(gmttime, PR_GMTParameters, &printableTime);
-
- /* The month in UTC time is base one */
- printableTime.tm_month++;
-
- /* remove the century since it's added to the tm_year by the
- PR_ExplodeTime routine, but is not needed for UTC time */
- printableTime.tm_year %= 100;
-
- d[0] = HIDIGIT(printableTime.tm_year);
- d[1] = LODIGIT(printableTime.tm_year);
- d[2] = HIDIGIT(printableTime.tm_month);
- d[3] = LODIGIT(printableTime.tm_month);
- d[4] = HIDIGIT(printableTime.tm_mday);
- d[5] = LODIGIT(printableTime.tm_mday);
- d[6] = HIDIGIT(printableTime.tm_hour);
- d[7] = LODIGIT(printableTime.tm_hour);
- d[8] = HIDIGIT(printableTime.tm_min);
- d[9] = LODIGIT(printableTime.tm_min);
- d[10] = HIDIGIT(printableTime.tm_sec);
- d[11] = LODIGIT(printableTime.tm_sec);
- d[12] = 'Z';
- return SECSuccess;
-}
-
-SECStatus
-DER_TimeToUTCTime(SECItem *dst, int64 gmttime)
-{
- return DER_TimeToUTCTimeArena(NULL, dst, gmttime);
-}
-
-static SECStatus /* forward */
-der_TimeStringToTime(PRTime *dst, const char *string, int generalized,
- const char **endptr);
-
-#define GEN_STRING 2 /* TimeString is a GeneralizedTime */
-#define UTC_STRING 0 /* TimeString is a UTCTime */
-
-/* The caller of DER_AsciiToItem MUST ENSURE that either
-** a) "string" points to a null-terminated ASCII string, or
-** b) "string" points to a buffer containing a valid UTCTime,
-** whether null terminated or not, or
-** c) "string" contains at least 19 characters, with or without null char.
-** otherwise, this function may UMR and/or crash.
-** It suffices to ensure that the input "string" is at least 17 bytes long.
-*/
-SECStatus
-DER_AsciiToTime(int64 *dst, const char *string)
-{
- return der_TimeStringToTime(dst, string, UTC_STRING, NULL);
-}
-
-SECStatus
-DER_UTCTimeToTime(int64 *dst, const SECItem *time)
-{
- /* Minimum valid UTCTime is yymmddhhmmZ which is 11 bytes.
- ** Maximum valid UTCTime is yymmddhhmmss+0000 which is 17 bytes.
- ** 20 should be large enough for all valid encoded times.
- */
- unsigned int i;
- char localBuf[20];
- const char *end = NULL;
- SECStatus rv;
-
- if (!time || !time->data || time->len < 11 || time->len > 17) {
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return SECFailure;
- }
-
- for (i = 0; i < time->len; i++) {
- if (time->data[i] == '\0') {
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return SECFailure;
- }
- localBuf[i] = time->data[i];
- }
- localBuf[i] = '\0';
-
- rv = der_TimeStringToTime(dst, localBuf, UTC_STRING, &end);
- if (rv == SECSuccess && *end != '\0') {
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return SECFailure;
- }
- return rv;
-}
-
-/*
- gmttime must contains UTC time in micro-seconds unit.
- Note: the caller should make sure that Generalized time
- should only be used for certifiate validities after the
- year 2049. Otherwise, UTC time should be used. This routine
- does not check this case, since it can be used to encode
- certificate extension, which does not have this restriction.
- */
-SECStatus
-DER_TimeToGeneralizedTimeArena(PRArenaPool* arenaOpt, SECItem *dst, int64 gmttime)
-{
- PRExplodedTime printableTime;
- unsigned char *d;
-
- if ( (gmttime<January1st1) || (gmttime>=January1st10000) ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- dst->len = 15;
- if (arenaOpt) {
- dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len);
- } else {
- dst->data = d = (unsigned char*) PORT_Alloc(dst->len);
- }
- dst->type = siGeneralizedTime;
- if (!d) {
- return SECFailure;
- }
-
- /* Convert an int64 time to a printable format. */
- PR_ExplodeTime(gmttime, PR_GMTParameters, &printableTime);
-
- /* The month in Generalized time is base one */
- printableTime.tm_month++;
-
- d[0] = (printableTime.tm_year /1000) + '0';
- d[1] = ((printableTime.tm_year % 1000) / 100) + '0';
- d[2] = ((printableTime.tm_year % 100) / 10) + '0';
- d[3] = (printableTime.tm_year % 10) + '0';
- d[4] = HIDIGIT(printableTime.tm_month);
- d[5] = LODIGIT(printableTime.tm_month);
- d[6] = HIDIGIT(printableTime.tm_mday);
- d[7] = LODIGIT(printableTime.tm_mday);
- d[8] = HIDIGIT(printableTime.tm_hour);
- d[9] = LODIGIT(printableTime.tm_hour);
- d[10] = HIDIGIT(printableTime.tm_min);
- d[11] = LODIGIT(printableTime.tm_min);
- d[12] = HIDIGIT(printableTime.tm_sec);
- d[13] = LODIGIT(printableTime.tm_sec);
- d[14] = 'Z';
- return SECSuccess;
-}
-
-SECStatus
-DER_TimeToGeneralizedTime(SECItem *dst, int64 gmttime)
-{
- return DER_TimeToGeneralizedTimeArena(NULL, dst, gmttime);
-}
-
-
-SECStatus
-DER_GeneralizedTimeToTime(int64 *dst, const SECItem *time)
-{
- /* Minimum valid GeneralizedTime is ccyymmddhhmmZ which is 13 bytes.
- ** Maximum valid GeneralizedTime is ccyymmddhhmmss+0000 which is 19 bytes.
- ** 20 should be large enough for all valid encoded times.
- */
- unsigned int i;
- char localBuf[20];
- const char *end = NULL;
- SECStatus rv;
-
- if (!time || !time->data || time->len < 13 || time->len > 19) {
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return SECFailure;
- }
-
- for (i = 0; i < time->len; i++) {
- if (time->data[i] == '\0') {
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return SECFailure;
- }
- localBuf[i] = time->data[i];
- }
- localBuf[i] = '\0';
-
- rv = der_TimeStringToTime(dst, localBuf, GEN_STRING, &end);
- if (rv == SECSuccess && *end != '\0') {
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return SECFailure;
- }
- return rv;
-}
-
-static SECStatus
-der_TimeStringToTime(PRTime *dst, const char *string, int generalized,
- const char **endptr)
-{
- PRExplodedTime genTime;
- long hourOff = 0, minOff = 0;
- uint16 century;
- char signum;
-
- if (string == NULL || dst == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* Verify time is formatted properly and capture information */
- memset(&genTime, 0, sizeof genTime);
-
- if (generalized == UTC_STRING) {
- CAPTURE(genTime.tm_year, string, loser);
- century = (genTime.tm_year < 50) ? 20 : 19;
- } else {
- CAPTURE(century, string, loser);
- CAPTURE(genTime.tm_year, string, loser);
- }
- genTime.tm_year += century * 100;
-
- CAPTURE(genTime.tm_month, string, loser);
- if ((genTime.tm_month == 0) || (genTime.tm_month > 12))
- goto loser;
-
- /* NSPR month base is 0 */
- --genTime.tm_month;
-
- CAPTURE(genTime.tm_mday, string, loser);
- if ((genTime.tm_mday == 0) || (genTime.tm_mday > 31))
- goto loser;
-
- CAPTURE(genTime.tm_hour, string, loser);
- if (genTime.tm_hour > 23)
- goto loser;
-
- CAPTURE(genTime.tm_min, string, loser);
- if (genTime.tm_min > 59)
- goto loser;
-
- if (ISDIGIT(string[0])) {
- CAPTURE(genTime.tm_sec, string, loser);
- if (genTime.tm_sec > 59)
- goto loser;
- }
- signum = *string++;
- if (signum == '+' || signum == '-') {
- CAPTURE(hourOff, string, loser);
- if (hourOff > 23)
- goto loser;
- CAPTURE(minOff, string, loser);
- if (minOff > 59)
- goto loser;
- if (signum == '-') {
- hourOff = -hourOff;
- minOff = -minOff;
- }
- } else if (signum != 'Z') {
- goto loser;
- }
-
- if (endptr)
- *endptr = string;
-
- /* Convert the GMT offset to seconds and save it in genTime
- * for the implode time call.
- */
- genTime.tm_params.tp_gmt_offset = (PRInt32)((hourOff * 60L + minOff) * 60L);
- *dst = PR_ImplodeTime(&genTime);
- return SECSuccess;
-
-loser:
- PORT_SetError(SEC_ERROR_INVALID_TIME);
- return SECFailure;
-}
diff --git a/security/nss/lib/util/errstrs.c b/security/nss/lib/util/errstrs.c
deleted file mode 100644
index a47554d62..000000000
--- a/security/nss/lib/util/errstrs.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#include "prerror.h"
-#include "secerr.h"
-#include "secport.h"
-#include "prinit.h"
-#include "prprf.h"
-#include "prtypes.h"
-#include "prlog.h"
-#include "plstr.h"
-#include "nssutil.h"
-#include <string.h>
-
-#define ER3(name, value, str) {#name, str},
-
-static const struct PRErrorMessage sectext[] = {
-#include "SECerrs.h"
- {0,0}
-};
-
-static const struct PRErrorTable sec_et = {
- sectext, "secerrstrings", SEC_ERROR_BASE,
- (sizeof sectext)/(sizeof sectext[0])
-};
-
-static PRStatus
-nss_InitializePRErrorTableOnce(void) {
- return PR_ErrorInstallTable(&sec_et);
-}
-
-static PRCallOnceType once;
-
-SECStatus
-NSS_InitializePRErrorTable(void)
-{
- return (PR_SUCCESS == PR_CallOnce(&once, nss_InitializePRErrorTableOnce))
- ? SECSuccess : SECFailure;
-}
-
diff --git a/security/nss/lib/util/hasht.h b/security/nss/lib/util/hasht.h
deleted file mode 100644
index 6fd12f13a..000000000
--- a/security/nss/lib/util/hasht.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _HASHT_H_
-#define _HASHT_H_
-
-/* Opaque objects */
-typedef struct SECHashObjectStr SECHashObject;
-typedef struct HASHContextStr HASHContext;
-
-/*
- * The hash functions the security library supports
- * NOTE the order must match the definition of SECHashObjects[]!
- */
-typedef enum {
- HASH_AlgNULL = 0,
- HASH_AlgMD2 = 1,
- HASH_AlgMD5 = 2,
- HASH_AlgSHA1 = 3,
- HASH_AlgSHA256 = 4,
- HASH_AlgSHA384 = 5,
- HASH_AlgSHA512 = 6,
- HASH_AlgSHA224 = 7,
- HASH_AlgTOTAL
-} HASH_HashType;
-
-/*
- * Number of bytes each hash algorithm produces
- */
-#define MD2_LENGTH 16
-#define MD5_LENGTH 16
-#define SHA1_LENGTH 20
-#define SHA224_LENGTH 28
-#define SHA256_LENGTH 32
-#define SHA384_LENGTH 48
-#define SHA512_LENGTH 64
-#define HASH_LENGTH_MAX SHA512_LENGTH
-
-/*
- * Structure to hold hash computation info and routines
- */
-struct SECHashObjectStr {
- unsigned int length; /* hash output length (in bytes) */
- void * (*create)(void);
- void * (*clone)(void *);
- void (*destroy)(void *, PRBool);
- void (*begin)(void *);
- void (*update)(void *, const unsigned char *, unsigned int);
- void (*end)(void *, unsigned char *, unsigned int *, unsigned int);
- unsigned int blocklength; /* hash input block size (in bytes) */
- HASH_HashType type;
- void (*end_raw)(void *, unsigned char *, unsigned int *, unsigned int);
-};
-
-struct HASHContextStr {
- const struct SECHashObjectStr *hashobj;
- void *hash_context;
-};
-
-#endif /* _HASHT_H_ */
diff --git a/security/nss/lib/util/manifest.mn b/security/nss/lib/util/manifest.mn
deleted file mode 100644
index 60ccaff08..000000000
--- a/security/nss/lib/util/manifest.mn
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-CORE_DEPTH = ../../..
-
-EXPORTS = \
- base64.h \
- ciferfam.h \
- hasht.h \
- nssb64.h \
- nssb64t.h \
- nsslocks.h \
- nssilock.h \
- nssilckt.h \
- nssrwlk.h \
- nssrwlkt.h \
- nssutil.h \
- pkcs11.h \
- pkcs11f.h \
- pkcs11p.h \
- pkcs11t.h \
- pkcs11n.h \
- pkcs11u.h \
- portreg.h \
- secasn1.h \
- secasn1t.h \
- seccomon.h \
- secder.h \
- secdert.h \
- secdig.h \
- secdigt.h \
- secitem.h \
- secoid.h \
- secoidt.h \
- secport.h \
- secerr.h \
- utilmodt.h \
- utilrename.h \
- utilpars.h \
- utilparst.h \
- $(NULL)
-
-PRIVATE_EXPORTS = \
- templates.c \
- $(NULL)
-
-CSRCS = \
- quickder.c \
- secdig.c \
- derdec.c \
- derenc.c \
- dersubr.c \
- dertime.c \
- errstrs.c \
- nssb64d.c \
- nssb64e.c \
- nssrwlk.c \
- nssilock.c \
- oidstring.c \
- portreg.c \
- secalgid.c \
- secasn1d.c \
- secasn1e.c \
- secasn1u.c \
- secitem.c \
- secload.c \
- secoid.c \
- sectime.c \
- secport.c \
- templates.c \
- utf8.c \
- utilmod.c \
- utilpars.c \
- $(NULL)
-
-MODULE = nss
-
-# don't duplicate module name in REQUIRES
-MAPFILE = $(OBJDIR)/nssutil.def
-
-LIBRARY_NAME = nssutil
-LIBRARY_VERSION = 3
-
-# This part of the code, including all sub-dirs, can be optimized for size
-export ALLOW_OPT_CODE_SIZE = 1
diff --git a/security/nss/lib/util/nssb64.h b/security/nss/lib/util/nssb64.h
deleted file mode 100644
index 76e7d9e76..000000000
--- a/security/nss/lib/util/nssb64.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Public prototypes for base64 encoding/decoding.
- *
- * $Id$
- */
-#ifndef _NSSB64_H_
-#define _NSSB64_H_
-
-#include "utilrename.h"
-#include "seccomon.h"
-#include "nssb64t.h"
-
-SEC_BEGIN_PROTOS
-
-/*
- * Functions to start a base64 decoding/encoding context.
- */
-
-extern NSSBase64Decoder *
-NSSBase64Decoder_Create (PRInt32 (*output_fn) (void *, const unsigned char *,
- PRInt32),
- void *output_arg);
-
-extern NSSBase64Encoder *
-NSSBase64Encoder_Create (PRInt32 (*output_fn) (void *, const char *, PRInt32),
- void *output_arg);
-
-/*
- * Push data through the decoder/encoder, causing the output_fn (provided
- * to Create) to be called with the decoded/encoded data.
- */
-
-extern SECStatus
-NSSBase64Decoder_Update (NSSBase64Decoder *data, const char *buffer,
- PRUint32 size);
-
-extern SECStatus
-NSSBase64Encoder_Update (NSSBase64Encoder *data, const unsigned char *buffer,
- PRUint32 size);
-
-/*
- * When you're done processing, call this to close the context.
- * If "abort_p" is false, then calling this may cause the output_fn
- * to be called one last time (as the last buffered data is flushed out).
- */
-
-extern SECStatus
-NSSBase64Decoder_Destroy (NSSBase64Decoder *data, PRBool abort_p);
-
-extern SECStatus
-NSSBase64Encoder_Destroy (NSSBase64Encoder *data, PRBool abort_p);
-
-/*
- * Perform base64 decoding from an ascii string "inStr" to an Item.
- * The length of the input must be provided as "inLen". The Item
- * may be provided (as "outItemOpt"); you can also pass in a NULL
- * and the Item will be allocated for you.
- *
- * In any case, the data within the Item will be allocated for you.
- * All allocation will happen out of the passed-in "arenaOpt", if non-NULL.
- * If "arenaOpt" is NULL, standard allocation (heap) will be used and
- * you will want to free the result via SECITEM_FreeItem.
- *
- * Return value is NULL on error, the Item (allocated or provided) otherwise.
- */
-extern SECItem *
-NSSBase64_DecodeBuffer (PLArenaPool *arenaOpt, SECItem *outItemOpt,
- const char *inStr, unsigned int inLen);
-
-/*
- * Perform base64 encoding of binary data "inItem" to an ascii string.
- * The output buffer may be provided (as "outStrOpt"); you can also pass
- * in a NULL and the buffer will be allocated for you. The result will
- * be null-terminated, and if the buffer is provided, "maxOutLen" must
- * specify the maximum length of the buffer and will be checked to
- * supply sufficient space space for the encoded result. (If "outStrOpt"
- * is NULL, "maxOutLen" is ignored.)
- *
- * If "outStrOpt" is NULL, allocation will happen out of the passed-in
- * "arenaOpt", if *it* is non-NULL, otherwise standard allocation (heap)
- * will be used.
- *
- * Return value is NULL on error, the output buffer (allocated or provided)
- * otherwise.
- */
-extern char *
-NSSBase64_EncodeItem (PLArenaPool *arenaOpt, char *outStrOpt,
- unsigned int maxOutLen, SECItem *inItem);
-
-SEC_END_PROTOS
-
-#endif /* _NSSB64_H_ */
diff --git a/security/nss/lib/util/nssb64d.c b/security/nss/lib/util/nssb64d.c
deleted file mode 100644
index 0cf587cc9..000000000
--- a/security/nss/lib/util/nssb64d.c
+++ /dev/null
@@ -1,838 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Base64 decoding (ascii to binary).
- *
- * $Id$
- */
-
-#include "nssb64.h"
-#include "nspr.h"
-#include "secitem.h"
-#include "secerr.h"
-
-/*
- * XXX We want this basic support to go into NSPR (the PL part).
- * Until that can happen, the PL interface is going to be kept entirely
- * internal here -- all static functions and opaque data structures.
- * When someone can get it moved over into NSPR, that should be done:
- * - giving everything names that are accepted by the NSPR module owners
- * (though I tried to choose ones that would work without modification)
- * - exporting the functions (remove static declarations and add
- * to nssutil.def as necessary)
- * - put prototypes into appropriate header file (probably replacing
- * the entire current lib/libc/include/plbase64.h in NSPR)
- * along with a typedef for the context structure (which should be
- * kept opaque -- definition in the source file only, but typedef
- * ala "typedef struct PLBase64FooStr PLBase64Foo;" in header file)
- * - modify anything else as necessary to conform to NSPR required style
- * (I looked but found no formatting guide to follow)
- *
- * You will want to move over everything from here down to the comment
- * which says "XXX End of base64 decoding code to be moved into NSPR",
- * into a new file in NSPR.
- */
-
-/*
- **************************************************************
- * XXX Beginning of base64 decoding code to be moved into NSPR.
- */
-
-/*
- * This typedef would belong in the NSPR header file (i.e. plbase64.h).
- */
-typedef struct PLBase64DecoderStr PLBase64Decoder;
-
-/*
- * The following implementation of base64 decoding was based on code
- * found in libmime (specifically, in mimeenc.c). It has been adapted to
- * use PR types and naming as well as to provide other necessary semantics
- * (like buffer-in/buffer-out in addition to "streaming" without undue
- * performance hit of extra copying if you made the buffer versions
- * use the output_fn). It also incorporates some aspects of the current
- * NSPR base64 decoding code. As such, you may find similarities to
- * both of those implementations. I tried to use names that reflected
- * the original code when possible. For this reason you may find some
- * inconsistencies -- libmime used lots of "in" and "out" whereas the
- * NSPR version uses "src" and "dest"; sometimes I changed one to the other
- * and sometimes I left them when I thought the subroutines were at least
- * self-consistent.
- */
-
-PR_BEGIN_EXTERN_C
-
-/*
- * Opaque object used by the decoder to store state.
- */
-struct PLBase64DecoderStr {
- /* Current token (or portion, if token_size < 4) being decoded. */
- unsigned char token[4];
- int token_size;
-
- /*
- * Where to write the decoded data (used when streaming, not when
- * doing all in-memory (buffer) operations).
- *
- * Note that this definition is chosen to be compatible with PR_Write.
- */
- PRInt32 (*output_fn) (void *output_arg, const unsigned char *buf,
- PRInt32 size);
- void *output_arg;
-
- /*
- * Where the decoded output goes -- either temporarily (in the streaming
- * case, staged here before it goes to the output function) or what will
- * be the entire buffered result for users of the buffer version.
- */
- unsigned char *output_buffer;
- PRUint32 output_buflen; /* the total length of allocated buffer */
- PRUint32 output_length; /* the length that is currently populated */
-};
-
-PR_END_EXTERN_C
-
-
-/*
- * Table to convert an ascii "code" to its corresponding binary value.
- * For ease of use, the binary values in the table are the actual values
- * PLUS ONE. This is so that the special value of zero can denote an
- * invalid mapping; that was much easier than trying to fill in the other
- * values with some value other than zero, and to check for it.
- * Just remember to SUBTRACT ONE when using the value retrieved.
- */
-static unsigned char base64_codetovaluep1[256] = {
-/* 0: */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* 8: */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* 16: */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* 24: */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* 32: */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* 40: */ 0, 0, 0, 63, 0, 0, 0, 64,
-/* 48: */ 53, 54, 55, 56, 57, 58, 59, 60,
-/* 56: */ 61, 62, 0, 0, 0, 0, 0, 0,
-/* 64: */ 0, 1, 2, 3, 4, 5, 6, 7,
-/* 72: */ 8, 9, 10, 11, 12, 13, 14, 15,
-/* 80: */ 16, 17, 18, 19, 20, 21, 22, 23,
-/* 88: */ 24, 25, 26, 0, 0, 0, 0, 0,
-/* 96: */ 0, 27, 28, 29, 30, 31, 32, 33,
-/* 104: */ 34, 35, 36, 37, 38, 39, 40, 41,
-/* 112: */ 42, 43, 44, 45, 46, 47, 48, 49,
-/* 120: */ 50, 51, 52, 0, 0, 0, 0, 0,
-/* 128: */ 0, 0, 0, 0, 0, 0, 0, 0
-/* and rest are all zero as well */
-};
-
-#define B64_PAD '='
-
-
-/*
- * Reads 4; writes 3 (known, or expected, to have no trailing padding).
- * Returns bytes written; -1 on error (unexpected character).
- */
-static int
-pl_base64_decode_4to3 (const unsigned char *in, unsigned char *out)
-{
- int j;
- PRUint32 num = 0;
- unsigned char bits;
-
- for (j = 0; j < 4; j++) {
- bits = base64_codetovaluep1[in[j]];
- if (bits == 0)
- return -1;
- num = (num << 6) | (bits - 1);
- }
-
- out[0] = (unsigned char) (num >> 16);
- out[1] = (unsigned char) ((num >> 8) & 0xFF);
- out[2] = (unsigned char) (num & 0xFF);
-
- return 3;
-}
-
-/*
- * Reads 3; writes 2 (caller already confirmed EOF or trailing padding).
- * Returns bytes written; -1 on error (unexpected character).
- */
-static int
-pl_base64_decode_3to2 (const unsigned char *in, unsigned char *out)
-{
- PRUint32 num = 0;
- unsigned char bits1, bits2, bits3;
-
- bits1 = base64_codetovaluep1[in[0]];
- bits2 = base64_codetovaluep1[in[1]];
- bits3 = base64_codetovaluep1[in[2]];
-
- if ((bits1 == 0) || (bits2 == 0) || (bits3 == 0))
- return -1;
-
- num = ((PRUint32)(bits1 - 1)) << 10;
- num |= ((PRUint32)(bits2 - 1)) << 4;
- num |= ((PRUint32)(bits3 - 1)) >> 2;
-
- out[0] = (unsigned char) (num >> 8);
- out[1] = (unsigned char) (num & 0xFF);
-
- return 2;
-}
-
-/*
- * Reads 2; writes 1 (caller already confirmed EOF or trailing padding).
- * Returns bytes written; -1 on error (unexpected character).
- */
-static int
-pl_base64_decode_2to1 (const unsigned char *in, unsigned char *out)
-{
- PRUint32 num = 0;
- unsigned char bits1, bits2;
-
- bits1 = base64_codetovaluep1[in[0]];
- bits2 = base64_codetovaluep1[in[1]];
-
- if ((bits1 == 0) || (bits2 == 0))
- return -1;
-
- num = ((PRUint32)(bits1 - 1)) << 2;
- num |= ((PRUint32)(bits2 - 1)) >> 4;
-
- out[0] = (unsigned char) num;
-
- return 1;
-}
-
-/*
- * Reads 4; writes 0-3. Returns bytes written or -1 on error.
- * (Writes less than 3 only at (presumed) EOF.)
- */
-static int
-pl_base64_decode_token (const unsigned char *in, unsigned char *out)
-{
- if (in[3] != B64_PAD)
- return pl_base64_decode_4to3 (in, out);
-
- if (in[2] == B64_PAD)
- return pl_base64_decode_2to1 (in, out);
-
- return pl_base64_decode_3to2 (in, out);
-}
-
-static PRStatus
-pl_base64_decode_buffer (PLBase64Decoder *data, const unsigned char *in,
- PRUint32 length)
-{
- unsigned char *out = data->output_buffer;
- unsigned char *token = data->token;
- int i, n = 0;
-
- i = data->token_size;
- data->token_size = 0;
-
- while (length > 0) {
- while (i < 4 && length > 0) {
- /*
- * XXX Note that the following simply ignores any unexpected
- * characters. This is exactly what the original code in
- * libmime did, and I am leaving it. We certainly want to skip
- * over whitespace (we must); this does much more than that.
- * I am not confident changing it, and I don't want to slow
- * the processing down doing more complicated checking, but
- * someone else might have different ideas in the future.
- */
- if (base64_codetovaluep1[*in] > 0 || *in == B64_PAD)
- token[i++] = *in;
- in++;
- length--;
- }
-
- if (i < 4) {
- /* Didn't get enough for a complete token. */
- data->token_size = i;
- break;
- }
- i = 0;
-
- PR_ASSERT((out - data->output_buffer + 3) <= data->output_buflen);
-
- /*
- * Assume we are not at the end; the following function only works
- * for an internal token (no trailing padding characters) but is
- * faster that way. If it hits an invalid character (padding) it
- * will return an error; we break out of the loop and try again
- * calling the routine that will handle a final token.
- * Note that we intentionally do it this way rather than explicitly
- * add a check for padding here (because that would just slow down
- * the normal case) nor do we rely on checking whether we have more
- * input to process (because that would also slow it down but also
- * because we want to allow trailing garbage, especially white space
- * and cannot tell that without read-ahead, also a slow proposition).
- * Whew. Understand?
- */
- n = pl_base64_decode_4to3 (token, out);
- if (n < 0)
- break;
-
- /* Advance "out" by the number of bytes just written to it. */
- out += n;
- n = 0;
- }
-
- /*
- * See big comment above, before call to pl_base64_decode_4to3.
- * Here we check if we error'd out of loop, and allow for the case
- * that we are processing the last interesting token. If the routine
- * which should handle padding characters also fails, then we just
- * have bad input and give up.
- */
- if (n < 0) {
- n = pl_base64_decode_token (token, out);
- if (n < 0)
- return PR_FAILURE;
-
- out += n;
- }
-
- /*
- * As explained above, we can get here with more input remaining, but
- * it should be all characters we do not care about (i.e. would be
- * ignored when transferring from "in" to "token" in loop above,
- * except here we choose to ignore extraneous pad characters, too).
- * Swallow it, performing that check. If we find more characters that
- * we would expect to decode, something is wrong.
- */
- while (length > 0) {
- if (base64_codetovaluep1[*in] > 0)
- return PR_FAILURE;
- in++;
- length--;
- }
-
- /* Record the length of decoded data we have left in output_buffer. */
- data->output_length = (PRUint32) (out - data->output_buffer);
- return PR_SUCCESS;
-}
-
-/*
- * Flush any remaining buffered characters. Given well-formed input,
- * this will have nothing to do. If the input was missing the padding
- * characters at the end, though, there could be 1-3 characters left
- * behind -- we will tolerate that by adding the padding for them.
- */
-static PRStatus
-pl_base64_decode_flush (PLBase64Decoder *data)
-{
- int count;
-
- /*
- * If no remaining characters, or all are padding (also not well-formed
- * input, but again, be tolerant), then nothing more to do. (And, that
- * is considered successful.)
- */
- if (data->token_size == 0 || data->token[0] == B64_PAD)
- return PR_SUCCESS;
-
- /*
- * Assume we have all the interesting input except for some expected
- * padding characters. Add them and decode the resulting token.
- */
- while (data->token_size < 4)
- data->token[data->token_size++] = B64_PAD;
-
- data->token_size = 0; /* so a subsequent flush call is a no-op */
-
- count = pl_base64_decode_token (data->token,
- data->output_buffer + data->output_length);
- if (count < 0)
- return PR_FAILURE;
-
- /*
- * If there is an output function, call it with this last bit of data.
- * Otherwise we are doing all buffered output, and the decoded bytes
- * are now there, we just need to reflect that in the length.
- */
- if (data->output_fn != NULL) {
- PRInt32 output_result;
-
- PR_ASSERT(data->output_length == 0);
- output_result = data->output_fn (data->output_arg,
- data->output_buffer,
- (PRInt32) count);
- if (output_result < 0)
- return PR_FAILURE;
- } else {
- data->output_length += count;
- }
-
- return PR_SUCCESS;
-}
-
-
-/*
- * The maximum space needed to hold the output of the decoder given
- * input data of length "size".
- */
-static PRUint32
-PL_Base64MaxDecodedLength (PRUint32 size)
-{
- return ((size * 3) / 4);
-}
-
-
-/*
- * A distinct internal creation function for the buffer version to use.
- * (It does not want to specify an output_fn, and we want the normal
- * Create function to require that.) If more common initialization
- * of the decoding context needs to be done, it should be done *here*.
- */
-static PLBase64Decoder *
-pl_base64_create_decoder (void)
-{
- return PR_NEWZAP(PLBase64Decoder);
-}
-
-/*
- * Function to start a base64 decoding context.
- * An "output_fn" is required; the "output_arg" parameter to that is optional.
- */
-static PLBase64Decoder *
-PL_CreateBase64Decoder (PRInt32 (*output_fn) (void *, const unsigned char *,
- PRInt32),
- void *output_arg)
-{
- PLBase64Decoder *data;
-
- if (output_fn == NULL) {
- PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0);
- return NULL;
- }
-
- data = pl_base64_create_decoder ();
- if (data != NULL) {
- data->output_fn = output_fn;
- data->output_arg = output_arg;
- }
- return data;
-}
-
-
-/*
- * Push data through the decoder, causing the output_fn (provided to Create)
- * to be called with the decoded data.
- */
-static PRStatus
-PL_UpdateBase64Decoder (PLBase64Decoder *data, const char *buffer,
- PRUint32 size)
-{
- PRUint32 need_length;
- PRStatus status;
-
- /* XXX Should we do argument checking only in debug build? */
- if (data == NULL || buffer == NULL || size == 0) {
- PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0);
- return PR_FAILURE;
- }
-
- /*
- * How much space could this update need for decoding?
- */
- need_length = PL_Base64MaxDecodedLength (size + data->token_size);
-
- /*
- * Make sure we have at least that much. If not, (re-)allocate.
- */
- if (need_length > data->output_buflen) {
- unsigned char *output_buffer = data->output_buffer;
-
- if (output_buffer != NULL)
- output_buffer = (unsigned char *) PR_Realloc(output_buffer,
- need_length);
- else
- output_buffer = (unsigned char *) PR_Malloc(need_length);
-
- if (output_buffer == NULL)
- return PR_FAILURE;
-
- data->output_buffer = output_buffer;
- data->output_buflen = need_length;
- }
-
- /* There should not have been any leftover output data in the buffer. */
- PR_ASSERT(data->output_length == 0);
- data->output_length = 0;
-
- status = pl_base64_decode_buffer (data, (const unsigned char *) buffer,
- size);
-
- /* Now that we have some decoded data, write it. */
- if (status == PR_SUCCESS && data->output_length > 0) {
- PRInt32 output_result;
-
- PR_ASSERT(data->output_fn != NULL);
- output_result = data->output_fn (data->output_arg,
- data->output_buffer,
- (PRInt32) data->output_length);
- if (output_result < 0)
- status = PR_FAILURE;
- }
-
- data->output_length = 0;
- return status;
-}
-
-
-/*
- * When you're done decoding, call this to free the data. If "abort_p"
- * is false, then calling this may cause the output_fn to be called
- * one last time (as the last buffered data is flushed out).
- */
-static PRStatus
-PL_DestroyBase64Decoder (PLBase64Decoder *data, PRBool abort_p)
-{
- PRStatus status = PR_SUCCESS;
-
- /* XXX Should we do argument checking only in debug build? */
- if (data == NULL) {
- PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0);
- return PR_FAILURE;
- }
-
- /* Flush out the last few buffered characters. */
- if (!abort_p)
- status = pl_base64_decode_flush (data);
-
- if (data->output_buffer != NULL)
- PR_Free(data->output_buffer);
- PR_Free(data);
-
- return status;
-}
-
-
-/*
- * Perform base64 decoding from an input buffer to an output buffer.
- * The output buffer can be provided (as "dest"); you can also pass in
- * a NULL and this function will allocate a buffer large enough for you,
- * and return it. If you do provide the output buffer, you must also
- * provide the maximum length of that buffer (as "maxdestlen").
- * The actual decoded length of output will be returned to you in
- * "output_destlen".
- *
- * Return value is NULL on error, the output buffer (allocated or provided)
- * otherwise.
- */
-static unsigned char *
-PL_Base64DecodeBuffer (const char *src, PRUint32 srclen, unsigned char *dest,
- PRUint32 maxdestlen, PRUint32 *output_destlen)
-{
- PRUint32 need_length;
- unsigned char *output_buffer = NULL;
- PLBase64Decoder *data = NULL;
- PRStatus status;
-
- PR_ASSERT(srclen > 0);
- if (srclen == 0) {
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return NULL;
- }
-
- /*
- * How much space could we possibly need for decoding this input?
- */
- need_length = PL_Base64MaxDecodedLength (srclen);
-
- /*
- * Make sure we have at least that much, if output buffer provided.
- * If no output buffer provided, then we allocate that much.
- */
- if (dest != NULL) {
- PR_ASSERT(maxdestlen >= need_length);
- if (maxdestlen < need_length) {
- PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
- goto loser;
- }
- output_buffer = dest;
- } else {
- output_buffer = (unsigned char *) PR_Malloc(need_length);
- if (output_buffer == NULL)
- goto loser;
- maxdestlen = need_length;
- }
-
- data = pl_base64_create_decoder();
- if (data == NULL)
- goto loser;
-
- data->output_buflen = maxdestlen;
- data->output_buffer = output_buffer;
-
- status = pl_base64_decode_buffer (data, (const unsigned char *) src,
- srclen);
-
- /*
- * We do not wait for Destroy to flush, because Destroy will also
- * get rid of our decoder context, which we need to look at first!
- */
- if (status == PR_SUCCESS)
- status = pl_base64_decode_flush (data);
-
- /* Must clear this or Destroy will free it. */
- data->output_buffer = NULL;
-
- if (status == PR_SUCCESS) {
- *output_destlen = data->output_length;
- status = PL_DestroyBase64Decoder (data, PR_FALSE);
- data = NULL;
- if (status == PR_FAILURE)
- goto loser;
- return output_buffer;
- }
-
-loser:
- if (dest == NULL && output_buffer != NULL)
- PR_Free(output_buffer);
- if (data != NULL)
- (void) PL_DestroyBase64Decoder (data, PR_TRUE);
- return NULL;
-}
-
-
-/*
- * XXX End of base64 decoding code to be moved into NSPR.
- ********************************************************
- */
-
-/*
- * This is the beginning of the NSS cover functions. These will
- * provide the interface we want to expose as NSS-ish. For example,
- * they will operate on our Items, do any special handling or checking
- * we want to do, etc.
- */
-
-
-PR_BEGIN_EXTERN_C
-
-/*
- * A boring cover structure for now. Perhaps someday it will include
- * some more interesting fields.
- */
-struct NSSBase64DecoderStr {
- PLBase64Decoder *pl_data;
-};
-
-PR_END_EXTERN_C
-
-
-/*
- * Function to start a base64 decoding context.
- */
-NSSBase64Decoder *
-NSSBase64Decoder_Create (PRInt32 (*output_fn) (void *, const unsigned char *,
- PRInt32),
- void *output_arg)
-{
- PLBase64Decoder *pl_data;
- NSSBase64Decoder *nss_data;
-
- nss_data = PORT_ZNew(NSSBase64Decoder);
- if (nss_data == NULL)
- return NULL;
-
- pl_data = PL_CreateBase64Decoder (output_fn, output_arg);
- if (pl_data == NULL) {
- PORT_Free(nss_data);
- return NULL;
- }
-
- nss_data->pl_data = pl_data;
- return nss_data;
-}
-
-
-/*
- * Push data through the decoder, causing the output_fn (provided to Create)
- * to be called with the decoded data.
- */
-SECStatus
-NSSBase64Decoder_Update (NSSBase64Decoder *data, const char *buffer,
- PRUint32 size)
-{
- PRStatus pr_status;
-
- /* XXX Should we do argument checking only in debug build? */
- if (data == NULL) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- pr_status = PL_UpdateBase64Decoder (data->pl_data, buffer, size);
- if (pr_status == PR_FAILURE)
- return SECFailure;
-
- return SECSuccess;
-}
-
-
-/*
- * When you're done decoding, call this to free the data. If "abort_p"
- * is false, then calling this may cause the output_fn to be called
- * one last time (as the last buffered data is flushed out).
- */
-SECStatus
-NSSBase64Decoder_Destroy (NSSBase64Decoder *data, PRBool abort_p)
-{
- PRStatus pr_status;
-
- /* XXX Should we do argument checking only in debug build? */
- if (data == NULL) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- pr_status = PL_DestroyBase64Decoder (data->pl_data, abort_p);
-
- PORT_Free(data);
-
- if (pr_status == PR_FAILURE)
- return SECFailure;
-
- return SECSuccess;
-}
-
-
-/*
- * Perform base64 decoding from an ascii string "inStr" to an Item.
- * The length of the input must be provided as "inLen". The Item
- * may be provided (as "outItemOpt"); you can also pass in a NULL
- * and the Item will be allocated for you.
- *
- * In any case, the data within the Item will be allocated for you.
- * All allocation will happen out of the passed-in "arenaOpt", if non-NULL.
- * If "arenaOpt" is NULL, standard allocation (heap) will be used and
- * you will want to free the result via SECITEM_FreeItem.
- *
- * Return value is NULL on error, the Item (allocated or provided) otherwise.
- */
-SECItem *
-NSSBase64_DecodeBuffer (PRArenaPool *arenaOpt, SECItem *outItemOpt,
- const char *inStr, unsigned int inLen)
-{
- SECItem *out_item = NULL;
- PRUint32 max_out_len = 0;
- PRUint32 out_len;
- void *mark = NULL;
- unsigned char *dummy;
-
- if ((outItemOpt != NULL && outItemOpt->data != NULL) || inLen == 0) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- if (arenaOpt != NULL)
- mark = PORT_ArenaMark (arenaOpt);
-
- max_out_len = PL_Base64MaxDecodedLength (inLen);
- out_item = SECITEM_AllocItem (arenaOpt, outItemOpt, max_out_len);
- if (out_item == NULL) {
- if (arenaOpt != NULL)
- PORT_ArenaRelease (arenaOpt, mark);
- return NULL;
- }
-
- dummy = PL_Base64DecodeBuffer (inStr, inLen, out_item->data,
- max_out_len, &out_len);
- if (dummy == NULL) {
- if (arenaOpt != NULL) {
- PORT_ArenaRelease (arenaOpt, mark);
- if (outItemOpt != NULL) {
- outItemOpt->data = NULL;
- outItemOpt->len = 0;
- }
- } else {
- SECITEM_FreeItem (out_item,
- (outItemOpt == NULL) ? PR_TRUE : PR_FALSE);
- }
- return NULL;
- }
-
- if (arenaOpt != NULL)
- PORT_ArenaUnmark (arenaOpt, mark);
- out_item->len = out_len;
- return out_item;
-}
-
-
-/*
- * XXX Everything below is deprecated. If you add new stuff, put it
- * *above*, not below.
- */
-
-/*
- * XXX The following "ATOB" functions are provided for backward compatibility
- * with current code. They should be considered strongly deprecated.
- * When we can convert all our code over to using the new NSSBase64Decoder_
- * functions defined above, we should get rid of these altogether. (Remove
- * protoypes from base64.h as well -- actually, remove that file completely).
- * If someone thinks either of these functions provides such a very useful
- * interface (though, as shown, the same functionality can already be
- * obtained by calling NSSBase64_DecodeBuffer directly), fine -- but then
- * that API should be provided with a nice new NSSFoo name and using
- * appropriate types, etc.
- */
-
-#include "base64.h"
-
-/*
-** Return an PORT_Alloc'd string which is the base64 decoded version
-** of the input string; set *lenp to the length of the returned data.
-*/
-unsigned char *
-ATOB_AsciiToData(const char *string, unsigned int *lenp)
-{
- SECItem binary_item, *dummy;
-
- binary_item.data = NULL;
- binary_item.len = 0;
-
- dummy = NSSBase64_DecodeBuffer (NULL, &binary_item, string,
- (PRUint32) PORT_Strlen(string));
- if (dummy == NULL)
- return NULL;
-
- PORT_Assert(dummy == &binary_item);
-
- *lenp = dummy->len;
- return dummy->data;
-}
-
-/*
-** Convert from ascii to binary encoding of an item.
-*/
-SECStatus
-ATOB_ConvertAsciiToItem(SECItem *binary_item, const char *ascii)
-{
- SECItem *dummy;
-
- if (binary_item == NULL) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /*
- * XXX Would prefer to assert here if data is non-null (actually,
- * don't need to, just let NSSBase64_DecodeBuffer do it), so as to
- * to catch unintended memory leaks, but callers are not clean in
- * this respect so we need to explicitly clear here to avoid the
- * assert in NSSBase64_DecodeBuffer.
- */
- binary_item->data = NULL;
- binary_item->len = 0;
-
- dummy = NSSBase64_DecodeBuffer (NULL, binary_item, ascii,
- (PRUint32) PORT_Strlen(ascii));
-
- if (dummy == NULL)
- return SECFailure;
-
- return SECSuccess;
-}
diff --git a/security/nss/lib/util/nssb64e.c b/security/nss/lib/util/nssb64e.c
deleted file mode 100644
index 4aff4ff59..000000000
--- a/security/nss/lib/util/nssb64e.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Base64 encoding (binary to ascii).
- *
- * $Id$
- */
-
-#include "nssb64.h"
-#include "nspr.h"
-#include "secitem.h"
-#include "secerr.h"
-
-/*
- * XXX See the big comment at the top of nssb64d.c about moving the
- * bulk of this code over into NSPR (the PL part). It all applies
- * here but I didn't want to duplicate it, to avoid divergence problems.
- */
-
-/*
- **************************************************************
- * XXX Beginning of base64 encoding code to be moved into NSPR.
- */
-
-
-struct PLBase64EncodeStateStr {
- unsigned chunks;
- unsigned saved;
- unsigned char buf[3];
-};
-
-/*
- * This typedef would belong in the NSPR header file (i.e. plbase64.h).
- */
-typedef struct PLBase64EncoderStr PLBase64Encoder;
-
-/*
- * The following implementation of base64 encoding was based on code
- * found in libmime (specifically, in mimeenc.c). It has been adapted to
- * use PR types and naming as well as to provide other necessary semantics
- * (like buffer-in/buffer-out in addition to "streaming" without undue
- * performance hit of extra copying if you made the buffer versions
- * use the output_fn). It also incorporates some aspects of the current
- * NSPR base64 encoding code. As such, you may find similarities to
- * both of those implementations. I tried to use names that reflected
- * the original code when possible. For this reason you may find some
- * inconsistencies -- libmime used lots of "in" and "out" whereas the
- * NSPR version uses "src" and "dest"; sometimes I changed one to the other
- * and sometimes I left them when I thought the subroutines were at least
- * self-consistent.
- */
-
-PR_BEGIN_EXTERN_C
-
-/*
- * Opaque object used by the encoder to store state.
- */
-struct PLBase64EncoderStr {
- /*
- * The one or two bytes pending. (We need 3 to create a "token",
- * and hold the leftovers here. in_buffer_count is *only* ever
- * 0, 1, or 2.
- */
- unsigned char in_buffer[2];
- int in_buffer_count;
-
- /*
- * If the caller wants linebreaks added, line_length specifies
- * where they come out. It must be a multiple of 4; if the caller
- * provides one that isn't, we round it down to the nearest
- * multiple of 4.
- *
- * The value of current_column counts how many characters have been
- * added since the last linebreaks (or since the beginning, on the
- * first line). It is also always a multiple of 4; it is unused when
- * line_length is 0.
- */
- PRUint32 line_length;
- PRUint32 current_column;
-
- /*
- * Where to write the encoded data (used when streaming, not when
- * doing all in-memory (buffer) operations).
- *
- * Note that this definition is chosen to be compatible with PR_Write.
- */
- PRInt32 (*output_fn) (void *output_arg, const char *buf, PRInt32 size);
- void *output_arg;
-
- /*
- * Where the encoded output goes -- either temporarily (in the streaming
- * case, staged here before it goes to the output function) or what will
- * be the entire buffered result for users of the buffer version.
- */
- char *output_buffer;
- PRUint32 output_buflen; /* the total length of allocated buffer */
- PRUint32 output_length; /* the length that is currently populated */
-};
-
-PR_END_EXTERN_C
-
-
-/*
- * Table to convert a binary value to its corresponding ascii "code".
- */
-static unsigned char base64_valuetocode[64] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-#define B64_PAD '='
-#define B64_CR '\r'
-#define B64_LF '\n'
-
-static PRStatus
-pl_base64_encode_buffer (PLBase64Encoder *data, const unsigned char *in,
- PRUint32 size)
-{
- const unsigned char *end = in + size;
- char *out = data->output_buffer + data->output_length;
- unsigned int i = data->in_buffer_count;
- PRUint32 n = 0;
- int off;
- PRUint32 output_threshold;
-
- /* If this input buffer is too small, wait until next time. */
- if (size < (3 - i)) {
- data->in_buffer[i++] = in[0];
- if (size > 1)
- data->in_buffer[i++] = in[1];
- PR_ASSERT(i < 3);
- data->in_buffer_count = i;
- return PR_SUCCESS;
- }
-
- /* If there are bytes that were put back last time, take them now. */
- if (i > 0) {
- n = data->in_buffer[0];
- if (i > 1)
- n = (n << 8) | data->in_buffer[1];
- data->in_buffer_count = 0;
- }
-
- /* If our total is not a multiple of three, put one or two bytes back. */
- off = (size + i) % 3;
- if (off > 0) {
- size -= off;
- data->in_buffer[0] = in[size];
- if (off > 1)
- data->in_buffer[1] = in[size + 1];
- data->in_buffer_count = off;
- end -= off;
- }
-
- output_threshold = data->output_buflen - 3;
-
- /*
- * Populate the output buffer with base64 data, one line (or buffer)
- * at a time.
- */
- while (in < end) {
- int j, k;
-
- while (i < 3) {
- n = (n << 8) | *in++;
- i++;
- }
- i = 0;
-
- if (data->line_length > 0) {
- if (data->current_column >= data->line_length) {
- data->current_column = 0;
- *out++ = B64_CR;
- *out++ = B64_LF;
- data->output_length += 2;
- }
- data->current_column += 4; /* the bytes we are about to add */
- }
-
- for (j = 18; j >= 0; j -= 6) {
- k = (n >> j) & 0x3F;
- *out++ = base64_valuetocode[k];
- }
- n = 0;
- data->output_length += 4;
-
- if (data->output_length >= output_threshold) {
- PR_ASSERT(data->output_length <= data->output_buflen);
- if (data->output_fn != NULL) {
- PRInt32 output_result;
-
- output_result = data->output_fn (data->output_arg,
- data->output_buffer,
- (PRInt32) data->output_length);
- if (output_result < 0)
- return PR_FAILURE;
-
- out = data->output_buffer;
- data->output_length = 0;
- } else {
- /*
- * Check that we are about to exit the loop. (Since we
- * are over the threshold, there isn't enough room in the
- * output buffer for another trip around.)
- */
- PR_ASSERT(in == end);
- if (in < end) {
- PR_SetError (PR_BUFFER_OVERFLOW_ERROR, 0);
- return PR_FAILURE;
- }
- }
- }
- }
-
- return PR_SUCCESS;
-}
-
-static PRStatus
-pl_base64_encode_flush (PLBase64Encoder *data)
-{
- int i = data->in_buffer_count;
-
- if (i == 0 && data->output_length == 0)
- return PR_SUCCESS;
-
- if (i > 0) {
- char *out = data->output_buffer + data->output_length;
- PRUint32 n;
- int j, k;
-
- n = ((PRUint32) data->in_buffer[0]) << 16;
- if (i > 1)
- n |= ((PRUint32) data->in_buffer[1] << 8);
-
- data->in_buffer_count = 0;
-
- if (data->line_length > 0) {
- if (data->current_column >= data->line_length) {
- data->current_column = 0;
- *out++ = B64_CR;
- *out++ = B64_LF;
- data->output_length += 2;
- }
- }
-
- /*
- * This will fill in more than we really have data for, but the
- * valid parts will end up in the correct position and the extras
- * will be over-written with pad characters below.
- */
- for (j = 18; j >= 0; j -= 6) {
- k = (n >> j) & 0x3F;
- *out++ = base64_valuetocode[k];
- }
-
- /* Pad with equal-signs. */
- if (i == 1)
- out[-2] = B64_PAD;
- out[-1] = B64_PAD;
-
- data->output_length += 4;
- }
-
- if (data->output_fn != NULL) {
- PRInt32 output_result;
-
- output_result = data->output_fn (data->output_arg, data->output_buffer,
- (PRInt32) data->output_length);
- data->output_length = 0;
-
- if (output_result < 0)
- return PR_FAILURE;
- }
-
- return PR_SUCCESS;
-}
-
-
-/*
- * The maximum space needed to hold the output of the encoder given input
- * data of length "size", and allowing for CRLF added at least every
- * line_length bytes (we will add it at nearest lower multiple of 4).
- * There is no trailing CRLF.
- */
-static PRUint32
-PL_Base64MaxEncodedLength (PRUint32 size, PRUint32 line_length)
-{
- PRUint32 tokens, tokens_per_line, full_lines, line_break_chars, remainder;
-
- tokens = (size + 2) / 3;
-
- if (line_length == 0)
- return tokens * 4;
-
- if (line_length < 4) /* too small! */
- line_length = 4;
-
- tokens_per_line = line_length / 4;
- full_lines = tokens / tokens_per_line;
- remainder = (tokens - (full_lines * tokens_per_line)) * 4;
- line_break_chars = full_lines * 2;
- if (remainder == 0)
- line_break_chars -= 2;
-
- return (full_lines * tokens_per_line * 4) + line_break_chars + remainder;
-}
-
-
-/*
- * A distinct internal creation function for the buffer version to use.
- * (It does not want to specify an output_fn, and we want the normal
- * Create function to require that.) All common initialization of the
- * encoding context should be done *here*.
- *
- * Save "line_length", rounded down to nearest multiple of 4 (if not
- * already even multiple). Allocate output_buffer, if not provided --
- * based on given size if specified, otherwise based on line_length.
- */
-static PLBase64Encoder *
-pl_base64_create_encoder (PRUint32 line_length, char *output_buffer,
- PRUint32 output_buflen)
-{
- PLBase64Encoder *data;
- PRUint32 line_tokens;
-
- data = PR_NEWZAP(PLBase64Encoder);
- if (data == NULL)
- return NULL;
-
- if (line_length > 0 && line_length < 4) /* too small! */
- line_length = 4;
-
- line_tokens = line_length / 4;
- data->line_length = line_tokens * 4;
-
- if (output_buffer == NULL) {
- if (output_buflen == 0) {
- if (data->line_length > 0) /* need to include room for CRLF */
- output_buflen = data->line_length + 2;
- else
- output_buflen = 64; /* XXX what is a good size? */
- }
-
- output_buffer = (char *) PR_Malloc(output_buflen);
- if (output_buffer == NULL) {
- PR_Free(data);
- return NULL;
- }
- }
-
- data->output_buffer = output_buffer;
- data->output_buflen = output_buflen;
- return data;
-}
-
-/*
- * Function to start a base64 encoding context.
- * An "output_fn" is required; the "output_arg" parameter to that is optional.
- * If linebreaks in the encoded output are desired, "line_length" specifies
- * where to place them -- it will be rounded down to the nearest multiple of 4
- * (if it is not already an even multiple of 4). If it is zero, no linebreaks
- * will be added. (FYI, a linebreak is CRLF -- two characters.)
- */
-static PLBase64Encoder *
-PL_CreateBase64Encoder (PRInt32 (*output_fn) (void *, const char *, PRInt32),
- void *output_arg, PRUint32 line_length)
-{
- PLBase64Encoder *data;
-
- if (output_fn == NULL) {
- PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0);
- return NULL;
- }
-
- data = pl_base64_create_encoder (line_length, NULL, 0);
- if (data == NULL)
- return NULL;
-
- data->output_fn = output_fn;
- data->output_arg = output_arg;
-
- return data;
-}
-
-
-/*
- * Push data through the encoder, causing the output_fn (provided to Create)
- * to be called with the encoded data.
- */
-static PRStatus
-PL_UpdateBase64Encoder (PLBase64Encoder *data, const unsigned char *buffer,
- PRUint32 size)
-{
- /* XXX Should we do argument checking only in debug build? */
- if (data == NULL || buffer == NULL || size == 0) {
- PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0);
- return PR_FAILURE;
- }
-
- return pl_base64_encode_buffer (data, buffer, size);
-}
-
-
-/*
- * When you're done encoding, call this to free the data. If "abort_p"
- * is false, then calling this may cause the output_fn to be called
- * one last time (as the last buffered data is flushed out).
- */
-static PRStatus
-PL_DestroyBase64Encoder (PLBase64Encoder *data, PRBool abort_p)
-{
- PRStatus status = PR_SUCCESS;
-
- /* XXX Should we do argument checking only in debug build? */
- if (data == NULL) {
- PR_SetError (PR_INVALID_ARGUMENT_ERROR, 0);
- return PR_FAILURE;
- }
-
- /* Flush out the last few buffered characters. */
- if (!abort_p)
- status = pl_base64_encode_flush (data);
-
- if (data->output_buffer != NULL)
- PR_Free(data->output_buffer);
- PR_Free(data);
-
- return status;
-}
-
-
-/*
- * Perform base64 encoding from an input buffer to an output buffer.
- * The output buffer can be provided (as "dest"); you can also pass in
- * a NULL and this function will allocate a buffer large enough for you,
- * and return it. If you do provide the output buffer, you must also
- * provide the maximum length of that buffer (as "maxdestlen").
- * The actual encoded length of output will be returned to you in
- * "output_destlen".
- *
- * If linebreaks in the encoded output are desired, "line_length" specifies
- * where to place them -- it will be rounded down to the nearest multiple of 4
- * (if it is not already an even multiple of 4). If it is zero, no linebreaks
- * will be added. (FYI, a linebreak is CRLF -- two characters.)
- *
- * Return value is NULL on error, the output buffer (allocated or provided)
- * otherwise.
- */
-static char *
-PL_Base64EncodeBuffer (const unsigned char *src, PRUint32 srclen,
- PRUint32 line_length, char *dest, PRUint32 maxdestlen,
- PRUint32 *output_destlen)
-{
- PRUint32 need_length;
- PLBase64Encoder *data = NULL;
- PRStatus status;
-
- PR_ASSERT(srclen > 0);
- if (srclen == 0)
- return dest;
-
- /*
- * How much space could we possibly need for encoding this input?
- */
- need_length = PL_Base64MaxEncodedLength (srclen, line_length);
-
- /*
- * Make sure we have at least that much, if output buffer provided.
- */
- if (dest != NULL) {
- PR_ASSERT(maxdestlen >= need_length);
- if (maxdestlen < need_length) {
- PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
- return NULL;
- }
- } else {
- maxdestlen = need_length;
- }
-
- data = pl_base64_create_encoder(line_length, dest, maxdestlen);
- if (data == NULL)
- return NULL;
-
- status = pl_base64_encode_buffer (data, src, srclen);
-
- /*
- * We do not wait for Destroy to flush, because Destroy will also
- * get rid of our encoder context, which we need to look at first!
- */
- if (status == PR_SUCCESS)
- status = pl_base64_encode_flush (data);
-
- if (status != PR_SUCCESS) {
- (void) PL_DestroyBase64Encoder (data, PR_TRUE);
- return NULL;
- }
-
- dest = data->output_buffer;
-
- /* Must clear this or Destroy will free it. */
- data->output_buffer = NULL;
-
- *output_destlen = data->output_length;
- status = PL_DestroyBase64Encoder (data, PR_FALSE);
- if (status == PR_FAILURE) {
- PR_Free(dest);
- return NULL;
- }
-
- return dest;
-}
-
-/*
- * XXX End of base64 encoding code to be moved into NSPR.
- ********************************************************
- */
-
-/*
- * This is the beginning of the NSS cover functions. These will
- * provide the interface we want to expose as NSS-ish. For example,
- * they will operate on our Items, do any special handling or checking
- * we want to do, etc.
- */
-
-
-PR_BEGIN_EXTERN_C
-
-/*
- * A boring cover structure for now. Perhaps someday it will include
- * some more interesting fields.
- */
-struct NSSBase64EncoderStr {
- PLBase64Encoder *pl_data;
-};
-
-PR_END_EXTERN_C
-
-
-/*
- * Function to start a base64 encoding context.
- */
-NSSBase64Encoder *
-NSSBase64Encoder_Create (PRInt32 (*output_fn) (void *, const char *, PRInt32),
- void *output_arg)
-{
- PLBase64Encoder *pl_data;
- NSSBase64Encoder *nss_data;
-
- nss_data = PORT_ZNew(NSSBase64Encoder);
- if (nss_data == NULL)
- return NULL;
-
- pl_data = PL_CreateBase64Encoder (output_fn, output_arg, 64);
- if (pl_data == NULL) {
- PORT_Free(nss_data);
- return NULL;
- }
-
- nss_data->pl_data = pl_data;
- return nss_data;
-}
-
-
-/*
- * Push data through the encoder, causing the output_fn (provided to Create)
- * to be called with the encoded data.
- */
-SECStatus
-NSSBase64Encoder_Update (NSSBase64Encoder *data, const unsigned char *buffer,
- PRUint32 size)
-{
- PRStatus pr_status;
-
- /* XXX Should we do argument checking only in debug build? */
- if (data == NULL) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- pr_status = PL_UpdateBase64Encoder (data->pl_data, buffer, size);
- if (pr_status == PR_FAILURE)
- return SECFailure;
-
- return SECSuccess;
-}
-
-
-/*
- * When you're done encoding, call this to free the data. If "abort_p"
- * is false, then calling this may cause the output_fn to be called
- * one last time (as the last buffered data is flushed out).
- */
-SECStatus
-NSSBase64Encoder_Destroy (NSSBase64Encoder *data, PRBool abort_p)
-{
- PRStatus pr_status;
-
- /* XXX Should we do argument checking only in debug build? */
- if (data == NULL) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- pr_status = PL_DestroyBase64Encoder (data->pl_data, abort_p);
-
- PORT_Free(data);
-
- if (pr_status == PR_FAILURE)
- return SECFailure;
-
- return SECSuccess;
-}
-
-
-/*
- * Perform base64 encoding of binary data "inItem" to an ascii string.
- * The output buffer may be provided (as "outStrOpt"); you can also pass
- * in a NULL and the buffer will be allocated for you. The result will
- * be null-terminated, and if the buffer is provided, "maxOutLen" must
- * specify the maximum length of the buffer and will be checked to
- * supply sufficient space space for the encoded result. (If "outStrOpt"
- * is NULL, "maxOutLen" is ignored.)
- *
- * If "outStrOpt" is NULL, allocation will happen out of the passed-in
- * "arenaOpt", if *it* is non-NULL, otherwise standard allocation (heap)
- * will be used.
- *
- * Return value is NULL on error, the output buffer (allocated or provided)
- * otherwise.
- */
-char *
-NSSBase64_EncodeItem (PRArenaPool *arenaOpt, char *outStrOpt,
- unsigned int maxOutLen, SECItem *inItem)
-{
- char *out_string = outStrOpt;
- PRUint32 max_out_len;
- PRUint32 out_len;
- void *mark = NULL;
- char *dummy;
-
- PORT_Assert(inItem != NULL && inItem->data != NULL && inItem->len != 0);
- if (inItem == NULL || inItem->data == NULL || inItem->len == 0) {
- PORT_SetError (SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-
- max_out_len = PL_Base64MaxEncodedLength (inItem->len, 64);
-
- if (arenaOpt != NULL)
- mark = PORT_ArenaMark (arenaOpt);
-
- if (out_string == NULL) {
- if (arenaOpt != NULL)
- out_string = PORT_ArenaAlloc (arenaOpt, max_out_len + 1);
- else
- out_string = PORT_Alloc (max_out_len + 1);
-
- if (out_string == NULL) {
- if (arenaOpt != NULL)
- PORT_ArenaRelease (arenaOpt, mark);
- return NULL;
- }
- } else {
- if ((max_out_len + 1) > maxOutLen) {
- PORT_SetError (SEC_ERROR_OUTPUT_LEN);
- return NULL;
- }
- max_out_len = maxOutLen;
- }
-
-
- dummy = PL_Base64EncodeBuffer (inItem->data, inItem->len, 64,
- out_string, max_out_len, &out_len);
- if (dummy == NULL) {
- if (arenaOpt != NULL) {
- PORT_ArenaRelease (arenaOpt, mark);
- } else {
- PORT_Free (out_string);
- }
- return NULL;
- }
-
- if (arenaOpt != NULL)
- PORT_ArenaUnmark (arenaOpt, mark);
-
- out_string[out_len] = '\0';
- return out_string;
-}
-
-
-/*
- * XXX Everything below is deprecated. If you add new stuff, put it
- * *above*, not below.
- */
-
-/*
- * XXX The following "BTOA" functions are provided for backward compatibility
- * with current code. They should be considered strongly deprecated.
- * When we can convert all our code over to using the new NSSBase64Encoder_
- * functions defined above, we should get rid of these altogether. (Remove
- * protoypes from base64.h as well -- actually, remove that file completely).
- * If someone thinks either of these functions provides such a very useful
- * interface (though, as shown, the same functionality can already be
- * obtained by calling NSSBase64_EncodeItem directly), fine -- but then
- * that API should be provided with a nice new NSSFoo name and using
- * appropriate types, etc.
- */
-
-#include "base64.h"
-
-/*
-** Return an PORT_Alloc'd ascii string which is the base64 encoded
-** version of the input string.
-*/
-char *
-BTOA_DataToAscii(const unsigned char *data, unsigned int len)
-{
- SECItem binary_item;
-
- binary_item.data = (unsigned char *)data;
- binary_item.len = len;
-
- return NSSBase64_EncodeItem (NULL, NULL, 0, &binary_item);
-}
-
-/*
-** Convert from binary encoding of an item to ascii.
-*/
-char *
-BTOA_ConvertItemToAscii (SECItem *binary_item)
-{
- return NSSBase64_EncodeItem (NULL, NULL, 0, binary_item);
-}
diff --git a/security/nss/lib/util/nssb64t.h b/security/nss/lib/util/nssb64t.h
deleted file mode 100644
index 6717858a4..000000000
--- a/security/nss/lib/util/nssb64t.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Public data structures for base64 encoding/decoding.
- *
- * $Id$
- */
-#ifndef _NSSB64T_H_
-#define _NSSB64T_H_
-
-#include "utilrename.h"
-typedef struct NSSBase64DecoderStr NSSBase64Decoder;
-typedef struct NSSBase64EncoderStr NSSBase64Encoder;
-
-#endif /* _NSSB64T_H_ */
diff --git a/security/nss/lib/util/nssilckt.h b/security/nss/lib/util/nssilckt.h
deleted file mode 100644
index 7108e0c28..000000000
--- a/security/nss/lib/util/nssilckt.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-** nssilock.h - Instrumented locking functions for NSS
-**
-** Description:
-** nssilock provides instrumentation for locks and monitors in
-** the NSS libraries. The instrumentation, when enabled, causes
-** each call to the instrumented function to record data about
-** the call to an external file. The external file
-** subsequently used to extract performance data and other
-** statistical information about the operation of locks used in
-** the nss library.
-**
-** To enable compilation with instrumentation, build NSS with
-** the compile time switch NEED_NSS_ILOCK defined.
-**
-** say: "gmake OS_CFLAGS+=-DNEED_NSS_ILOCK" at make time.
-**
-** At runtime, to enable recording from nssilock, one or more
-** environment variables must be set. For each nssILockType to
-** be recorded, an environment variable of the form NSS_ILOCK_x
-** must be set to 1. For example:
-**
-** set NSS_ILOCK_Cert=1
-**
-** nssilock uses PRLOG is used to record to trace data. The
-** PRLogModule name associated with nssilock data is: "nssilock".
-** To enable recording of nssilock data you will need to set the
-** environment variable NSPR_LOG_MODULES to enable
-** recording for the nssilock log module. Similarly, you will
-** need to set the environment variable NSPR_LOG_FILE to specify
-** the filename to receive the recorded data. See prlog.h for usage.
-** Example:
-**
-** export NSPR_LOG_MODULES=nssilock:6
-** export NSPR_LOG_FILE=xxxLogfile
-**
-** Operation:
-** nssilock wraps calls to NSPR's PZLock and PZMonitor functions
-** with similarly named functions: PZ_NewLock(), etc. When NSS is
-** built with lock instrumentation enabled, the PZ* functions are
-** compiled into NSS; when lock instrumentation is disabled,
-** calls to PZ* functions are directly mapped to PR* functions
-** and the instrumentation arguments to the PZ* functions are
-** compiled away.
-**
-**
-** File Format:
-** The format of the external file is implementation
-** dependent. Where NSPR's PR_LOG() function is used, the file
-** contains data defined for PR_LOG() plus the data written by
-** the wrapped function. On some platforms and under some
-** circumstances, platform dependent logging or
-** instrumentation probes may be used. In any case, the
-** relevant data provided by the lock instrumentation is:
-**
-** lockType, func, address, duration, line, file [heldTime]
-**
-** where:
-**
-** lockType: a character representation of nssILockType for the
-** call. e.g. ... "cert"
-**
-** func: the function doing the tracing. e.g. "NewLock"
-**
-** address: address of the instrumented lock or monitor
-**
-** duration: is how long was spent in the instrumented function,
-** in PRIntervalTime "ticks".
-**
-** line: the line number within the calling function
-**
-** file: the file from which the call was made
-**
-** heldTime: how long the lock/monitor was held. field
-** present only for PZ_Unlock() and PZ_ExitMonitor().
-**
-** Design Notes:
-** The design for lock instrumentation was influenced by the
-** need to gather performance data on NSS 3.x. It is intended
-** that the effort to modify NSS to use lock instrumentation
-** be minimized. Existing calls to locking functions need only
-** have their names changed to the instrumentation function
-** names.
-**
-** Private NSS Interface:
-** nssilock.h defines a private interface for use by NSS.
-** nssilock.h is experimental in nature and is subject to
-** change or revocation without notice. ... Don't mess with
-** it.
-**
-*/
-
-/*
- * $Id:
- */
-
-#ifndef _NSSILCKT_H_
-#define _NSSILCKT_H_
-
-#include "utilrename.h"
-#include "prtypes.h"
-#include "prmon.h"
-#include "prlock.h"
-#include "prcvar.h"
-
-typedef enum {
- nssILockArena = 0,
- nssILockSession = 1,
- nssILockObject = 2,
- nssILockRefLock = 3,
- nssILockCert = 4,
- nssILockCertDB = 5,
- nssILockDBM = 6,
- nssILockCache = 7,
- nssILockSSL = 8,
- nssILockList = 9,
- nssILockSlot = 10,
- nssILockFreelist = 11,
- nssILockOID = 12,
- nssILockAttribute = 13,
- nssILockPK11cxt = 14, /* pk11context */
- nssILockRWLock = 15,
- nssILockOther = 16,
- nssILockSelfServ = 17,
- nssILockKeyDB = 18,
- nssILockLast /* don't use this one! */
-} nssILockType;
-
-/*
-** conditionally compile in nssilock features
-*/
-#if defined(NEED_NSS_ILOCK)
-
-/*
-** Declare operation type enumerator
-** enumerations identify the function being performed
-*/
-typedef enum {
- FlushTT = 0,
- NewLock = 1,
- Lock = 2,
- Unlock = 3,
- DestroyLock = 4,
- NewCondVar = 5,
- WaitCondVar = 6,
- NotifyCondVar = 7,
- NotifyAllCondVar = 8,
- DestroyCondVar = 9,
- NewMonitor = 10,
- EnterMonitor = 11,
- ExitMonitor = 12,
- Notify = 13,
- NotifyAll = 14,
- Wait = 15,
- DestroyMonitor = 16
-} nssILockOp;
-
-/*
-** Declare the trace record
-*/
-struct pzTrace_s {
- PRUint32 threadID; /* PR_GetThreadID() */
- nssILockOp op; /* operation being performed */
- nssILockType ltype; /* lock type identifier */
- PRIntervalTime callTime; /* time spent in function */
- PRIntervalTime heldTime; /* lock held time, or -1 */
- void *lock; /* address of lock structure */
- PRIntn line; /* line number */
- char file[24]; /* filename */
-};
-
-/*
-** declare opaque types. See: nssilock.c
-*/
-typedef struct pzlock_s PZLock;
-typedef struct pzcondvar_s PZCondVar;
-typedef struct pzmonitor_s PZMonitor;
-
-#else /* NEED_NSS_ILOCK */
-
-#define PZLock PRLock
-#define PZCondVar PRCondVar
-#define PZMonitor PRMonitor
-
-#endif /* NEED_NSS_ILOCK */
-
-#endif /* _NSSILCKT_H_ */
diff --git a/security/nss/lib/util/nssilock.c b/security/nss/lib/util/nssilock.c
deleted file mode 100644
index 2799635fa..000000000
--- a/security/nss/lib/util/nssilock.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * nssilock.c - NSS lock instrumentation wrapper functions
- *
- * NOTE - These are not public interfaces
- *
- * Implementation Notes:
- * I've tried to make the instrumentation relatively non-intrusive.
- * To do this, I have used a single PR_LOG() call in each
- * instrumented function. There's room for improvement.
- *
- *
- */
-
-#include "prinit.h"
-#include "prerror.h"
-#include "prlock.h"
-#include "prmem.h"
-#include "prenv.h"
-#include "prcvar.h"
-#include "prio.h"
-
-#if defined(NEED_NSS_ILOCK)
-#include "prlog.h"
-#include "nssilock.h"
-
-/*
-** Declare the instrumented PZLock
-*/
-struct pzlock_s {
- PRLock *lock; /* the PZLock to be instrumented */
- PRIntervalTime time; /* timestamp when the lock was aquired */
- nssILockType ltype;
-};
-
-/*
-** Declare the instrumented PZMonitor
-*/
-struct pzmonitor_s {
- PRMonitor *mon; /* the PZMonitor to be instrumented */
- PRIntervalTime time; /* timestamp when the monitor was aquired */
- nssILockType ltype;
-};
-
-/*
-** Declare the instrumented PZCondVar
-*/
-struct pzcondvar_s {
- PRCondVar *cvar; /* the PZCondVar to be instrumented */
- nssILockType ltype;
-};
-
-
-/*
-** Define a CallOnce type to ensure serialized self-initialization
-*/
-static PRCallOnceType coNssILock; /* CallOnce type */
-static PRIntn nssILockInitialized; /* initialization done when 1 */
-static PRLogModuleInfo *nssILog; /* Log instrumentation to this handle */
-
-
-#define NUM_TT_ENTRIES 6000000
-static PRInt32 traceIndex = -1; /* index into trace table */
-static struct pzTrace_s *tt; /* pointer to trace table */
-static PRInt32 ttBufSize = (NUM_TT_ENTRIES * sizeof(struct pzTrace_s ));
-static PRCondVar *ttCVar;
-static PRLock *ttLock;
-static PRFileDesc *ttfd; /* trace table file */
-
-/*
-** Vtrace() -- Trace events, write events to external media
-**
-** Vtrace() records traced events in an in-memory trace table
-** when the trace table fills, Vtrace writes the entire table
-** to a file.
-**
-** data can be lost!
-**
-*/
-static void Vtrace(
- nssILockOp op,
- nssILockType ltype,
- PRIntervalTime callTime,
- PRIntervalTime heldTime,
- void *lock,
- PRIntn line,
- char *file
-) {
- PRInt32 idx;
- struct pzTrace_s *tp;
-
-RetryTrace:
- idx = PR_ATOMIC_INCREMENT( &traceIndex );
- while( NUM_TT_ENTRIES <= idx || op == FlushTT ) {
- if( NUM_TT_ENTRIES == idx || op == FlushTT ) {
- int writeSize = idx * sizeof(struct pzTrace_s);
- PR_Lock(ttLock);
- PR_Write( ttfd, tt, writeSize );
- traceIndex = -1;
- PR_NotifyAllCondVar( ttCVar );
- PR_Unlock(ttLock);
- goto RetryTrace;
- } else {
- PR_Lock(ttLock);
- while( NUM_TT_ENTRIES < idx )
- PR_WaitCondVar(ttCVar, PR_INTERVAL_NO_WAIT);
- PR_Unlock(ttLock);
- goto RetryTrace;
- }
- } /* end while() */
-
- /* create the trace entry */
- tp = tt + idx;
- tp->threadID = PR_GetThreadID(PR_GetCurrentThread());
- tp->op = op;
- tp->ltype = ltype;
- tp->callTime = callTime;
- tp->heldTime = heldTime;
- tp->lock = lock;
- tp ->line = line;
- strcpy(tp->file, file );
- return;
-} /* --- end Vtrace() --- */
-
-/*
-** pz_TraceFlush() -- Force trace table write to file
-**
-*/
-extern void pz_TraceFlush( void )
-{
- Vtrace( FlushTT, nssILockSelfServ, 0, 0, NULL, 0, "" );
- return;
-} /* --- end pz_TraceFlush() --- */
-
-/*
-** nssILockInit() -- Initialization for nssilock
-**
-** This function is called from the CallOnce mechanism.
-*/
-static PRStatus
- nssILockInit( void )
-{
- int i;
- nssILockInitialized = 1;
-
- /* new log module */
- nssILog = PR_NewLogModule("nssilock");
- if ( NULL == nssILog ) {
- return(PR_FAILURE);
- }
-
- tt = PR_Calloc( NUM_TT_ENTRIES, sizeof(struct pzTrace_s));
- if (NULL == tt ) {
- fprintf(stderr, "nssilock: can't allocate trace table\n");
- exit(1);
- }
-
- ttfd = PR_Open( "xxxTTLog", PR_CREATE_FILE | PR_WRONLY, 0666 );
- if ( NULL == ttfd ) {
- fprintf( stderr, "Oh Drat! Can't open 'xxxTTLog'\n");
- exit(1);
- }
-
- ttLock = PR_NewLock();
- ttCVar = PR_NewCondVar(ttLock);
-
- return(PR_SUCCESS);
-} /* --- end nssILockInit() --- */
-
-extern PZLock * pz_NewLock(
- nssILockType ltype,
- char *file,
- PRIntn line )
-{
- PRStatus rc;
- PZLock *lock;
-
- /* Self Initialize the nssILock feature */
- if (!nssILockInitialized) {
- rc = PR_CallOnce( &coNssILock, nssILockInit );
- if ( PR_FAILURE == rc ) {
- PR_SetError( PR_UNKNOWN_ERROR, 0 );
- return( NULL );
- }
- }
-
- lock = PR_NEWZAP( PZLock );
- if ( NULL != lock ) {
- lock->ltype = ltype;
- lock->lock = PR_NewLock();
- if ( NULL == lock->lock ) {
- PR_DELETE( lock );
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
-
- Vtrace( NewLock, ltype, 0, 0, lock, line, file );
- return(lock);
-} /* --- end pz_NewLock() --- */
-
-extern void
- pz_Lock(
- PZLock *lock,
- char *file,
- PRIntn line
- )
-{
- PRIntervalTime callTime;
-
- callTime = PR_IntervalNow();
- PR_Lock( lock->lock );
- lock->time = PR_IntervalNow();
- callTime = lock->time - callTime;
-
- Vtrace( Lock, lock->ltype, callTime, 0, lock, line, file );
- return;
-} /* --- end pz_Lock() --- */
-
-extern PRStatus
- pz_Unlock(
- PZLock *lock,
- char *file,
- PRIntn line
- )
-{
- PRStatus rc;
- PRIntervalTime callTime, now, heldTime;
-
- callTime = PR_IntervalNow();
- rc = PR_Unlock( lock->lock );
- now = PR_IntervalNow();
- callTime = now - callTime;
- heldTime = now - lock->time;
- Vtrace( Unlock, lock->ltype, callTime, heldTime, lock, line, file );
- return( rc );
-} /* --- end pz_Unlock() --- */
-
-extern void
- pz_DestroyLock(
- PZLock *lock,
- char *file,
- PRIntn line
- )
-{
- Vtrace( DestroyLock, lock->ltype, 0, 0, lock, line, file );
- PR_DestroyLock( lock->lock );
- PR_DELETE( lock );
- return;
-} /* --- end pz_DestroyLock() --- */
-
-
-
-extern PZCondVar *
- pz_NewCondVar(
- PZLock *lock,
- char *file,
- PRIntn line
- )
-{
- PZCondVar *cvar;
-
- cvar = PR_NEWZAP( PZCondVar );
- if ( NULL == cvar ) {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- } else {
- cvar->ltype = lock->ltype;
- cvar->cvar = PR_NewCondVar( lock->lock );
- if ( NULL == cvar->cvar ) {
- PR_DELETE( cvar );
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
-
- }
- Vtrace( NewCondVar, lock->ltype, 0, 0, cvar, line, file );
- return( cvar );
-} /* --- end pz_NewCondVar() --- */
-
-extern void
- pz_DestroyCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- )
-{
- Vtrace( DestroyCondVar, cvar->ltype, 0, 0, cvar, line, file );
- PR_DestroyCondVar( cvar->cvar );
- PR_DELETE( cvar );
-} /* --- end pz_DestroyCondVar() --- */
-
-extern PRStatus
- pz_WaitCondVar(
- PZCondVar *cvar,
- PRIntervalTime timeout,
- char *file,
- PRIntn line
- )
-{
- PRStatus rc;
- PRIntervalTime callTime;
-
- callTime = PR_IntervalNow();
- rc = PR_WaitCondVar( cvar->cvar, timeout );
- callTime = PR_IntervalNow() - callTime;
-
- Vtrace( WaitCondVar, cvar->ltype, callTime, 0, cvar, line, file );
- return(rc);
-} /* --- end pz_WaitCondVar() --- */
-
-extern PRStatus
- pz_NotifyCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- )
-{
- PRStatus rc;
-
- rc = PR_NotifyCondVar( cvar->cvar );
-
- Vtrace( NotifyCondVar, cvar->ltype, 0, 0, cvar, line, file );
- return(rc);
-} /* --- end pz_NotifyCondVar() --- */
-
-extern PRStatus
- pz_NotifyAllCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- )
-{
- PRStatus rc;
-
- rc = PR_NotifyAllCondVar( cvar->cvar );
-
- Vtrace( NotifyAllCondVar, cvar->ltype, 0, 0, cvar, line, file );
- return(rc);
-} /* --- end pz_NotifyAllCondVar() --- */
-
-extern PZMonitor *
- pz_NewMonitor(
- nssILockType ltype,
- char *file,
- PRIntn line
- )
-{
- PRStatus rc;
- PZMonitor *mon;
-
- /* Self Initialize the nssILock feature */
- if (!nssILockInitialized) {
- rc = PR_CallOnce( &coNssILock, nssILockInit );
- if ( PR_FAILURE == rc ) {
- PR_SetError( PR_UNKNOWN_ERROR, 0 );
- return( NULL );
- }
- }
-
- mon = PR_NEWZAP( PZMonitor );
- if ( NULL != mon ) {
- mon->ltype = ltype;
- mon->mon = PR_NewMonitor();
- if ( NULL == mon->mon ) {
- PR_DELETE( mon );
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- } else {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
-
- Vtrace( NewMonitor, ltype, 0, 0, mon, line, file );
- return(mon);
-} /* --- end pz_NewMonitor() --- */
-
-extern void
- pz_DestroyMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
-{
- Vtrace( DestroyMonitor, mon->ltype, 0, 0, mon, line, file );
- PR_DestroyMonitor( mon->mon );
- PR_DELETE( mon );
- return;
-} /* --- end pz_DestroyMonitor() --- */
-
-extern void
- pz_EnterMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
-{
- PRIntervalTime callTime, now;
-
- callTime = PR_IntervalNow();
- PR_EnterMonitor( mon->mon );
- now = PR_IntervalNow();
- callTime = now - callTime;
- if ( PR_GetMonitorEntryCount(mon->mon) == 1 ) {
- mon->time = now;
- }
- Vtrace( EnterMonitor, mon->ltype, callTime, 0, mon, line, file );
- return;
-} /* --- end pz_EnterMonitor() --- */
-
-extern PRStatus
- pz_ExitMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
-{
- PRStatus rc;
- PRIntervalTime callTime, now, heldTime;
- PRIntn mec = PR_GetMonitorEntryCount( mon->mon );
-
- heldTime = (PRIntervalTime)-1;
- callTime = PR_IntervalNow();
- rc = PR_ExitMonitor( mon->mon );
- now = PR_IntervalNow();
- callTime = now - callTime;
- if ( mec == 1 )
- heldTime = now - mon->time;
- Vtrace( ExitMonitor, mon->ltype, callTime, heldTime, mon, line, file );
- return( rc );
-} /* --- end pz_ExitMonitor() --- */
-
-extern PRIntn
- pz_GetMonitorEntryCount(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
-{
- return( PR_GetMonitorEntryCount(mon->mon));
-} /* --- end pz_GetMonitorEntryCount() --- */
-
-
-extern PRStatus
- pz_Wait(
- PZMonitor *mon,
- PRIntervalTime ticks,
- char *file,
- PRIntn line
- )
-{
- PRStatus rc;
- PRIntervalTime callTime;
-
- callTime = PR_IntervalNow();
- rc = PR_Wait( mon->mon, ticks );
- callTime = PR_IntervalNow() - callTime;
- Vtrace( Wait, mon->ltype, callTime, 0, mon, line, file );
- return( rc );
-} /* --- end pz_Wait() --- */
-
-extern PRStatus
- pz_Notify(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
-{
- PRStatus rc;
- PRIntervalTime callTime;
-
- callTime = PR_IntervalNow();
- rc = PR_Notify( mon->mon );
- callTime = PR_IntervalNow() - callTime;
- Vtrace( Notify, mon->ltype, callTime, 0, mon, line, file );
- return( rc );
-} /* --- end pz_Notify() --- */
-
-extern PRStatus
- pz_NotifyAll(
- PZMonitor *mon,
- char *file,
- PRIntn line
- )
-{
- PRStatus rc;
- PRIntervalTime callTime;
-
- callTime = PR_IntervalNow();
- rc = PR_NotifyAll( mon->mon );
- callTime = PR_IntervalNow() - callTime;
- Vtrace( NotifyAll, mon->ltype, callTime, 0, mon, line, file );
- return( rc );
-} /* --- end pz_NotifyAll() --- */
-
-#endif /* NEED_NSS_ILOCK */
-/* --- end nssilock.c --------------------------------- */
diff --git a/security/nss/lib/util/nssilock.h b/security/nss/lib/util/nssilock.h
deleted file mode 100644
index a796e4afa..000000000
--- a/security/nss/lib/util/nssilock.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-** nssilock.h - Instrumented locking functions for NSS
-**
-** Description:
-** nssilock provides instrumentation for locks and monitors in
-** the NSS libraries. The instrumentation, when enabled, causes
-** each call to the instrumented function to record data about
-** the call to an external file. The external file
-** subsequently used to extract performance data and other
-** statistical information about the operation of locks used in
-** the nss library.
-**
-** To enable compilation with instrumentation, build NSS with
-** the compile time switch NEED_NSS_ILOCK defined.
-**
-** say: "gmake OS_CFLAGS+=-DNEED_NSS_ILOCK" at make time.
-**
-** At runtime, to enable recording from nssilock, one or more
-** environment variables must be set. For each nssILockType to
-** be recorded, an environment variable of the form NSS_ILOCK_x
-** must be set to 1. For example:
-**
-** set NSS_ILOCK_Cert=1
-**
-** nssilock uses PRLOG is used to record to trace data. The
-** PRLogModule name associated with nssilock data is: "nssilock".
-** To enable recording of nssilock data you will need to set the
-** environment variable NSPR_LOG_MODULES to enable
-** recording for the nssilock log module. Similarly, you will
-** need to set the environment variable NSPR_LOG_FILE to specify
-** the filename to receive the recorded data. See prlog.h for usage.
-** Example:
-**
-** export NSPR_LOG_MODULES=nssilock:6
-** export NSPR_LOG_FILE=xxxLogfile
-**
-** Operation:
-** nssilock wraps calls to NSPR's PZLock and PZMonitor functions
-** with similarly named functions: PZ_NewLock(), etc. When NSS is
-** built with lock instrumentation enabled, the PZ* functions are
-** compiled into NSS; when lock instrumentation is disabled,
-** calls to PZ* functions are directly mapped to PR* functions
-** and the instrumentation arguments to the PZ* functions are
-** compiled away.
-**
-**
-** File Format:
-** The format of the external file is implementation
-** dependent. Where NSPR's PR_LOG() function is used, the file
-** contains data defined for PR_LOG() plus the data written by
-** the wrapped function. On some platforms and under some
-** circumstances, platform dependent logging or
-** instrumentation probes may be used. In any case, the
-** relevant data provided by the lock instrumentation is:
-**
-** lockType, func, address, duration, line, file [heldTime]
-**
-** where:
-**
-** lockType: a character representation of nssILockType for the
-** call. e.g. ... "cert"
-**
-** func: the function doing the tracing. e.g. "NewLock"
-**
-** address: address of the instrumented lock or monitor
-**
-** duration: is how long was spent in the instrumented function,
-** in PRIntervalTime "ticks".
-**
-** line: the line number within the calling function
-**
-** file: the file from which the call was made
-**
-** heldTime: how long the lock/monitor was held. field
-** present only for PZ_Unlock() and PZ_ExitMonitor().
-**
-** Design Notes:
-** The design for lock instrumentation was influenced by the
-** need to gather performance data on NSS 3.x. It is intended
-** that the effort to modify NSS to use lock instrumentation
-** be minimized. Existing calls to locking functions need only
-** have their names changed to the instrumentation function
-** names.
-**
-** Private NSS Interface:
-** nssilock.h defines a private interface for use by NSS.
-** nssilock.h is experimental in nature and is subject to
-** change or revocation without notice. ... Don't mess with
-** it.
-**
-*/
-
-/*
- * $Id:
- */
-
-#ifndef _NSSILOCK_H_
-#define _NSSILOCK_H_
-
-#include "utilrename.h"
-#include "prtypes.h"
-#include "prmon.h"
-#include "prlock.h"
-#include "prcvar.h"
-
-#include "nssilckt.h"
-
-PR_BEGIN_EXTERN_C
-
-#if defined(NEED_NSS_ILOCK)
-
-#define PZ_NewLock(t) pz_NewLock((t),__FILE__,__LINE__)
-extern PZLock *
- pz_NewLock(
- nssILockType ltype,
- char *file,
- PRIntn line
- );
-
-#define PZ_Lock(k) pz_Lock((k),__FILE__,__LINE__)
-extern void
- pz_Lock(
- PZLock *lock,
- char *file,
- PRIntn line
- );
-
-#define PZ_Unlock(k) pz_Unlock((k),__FILE__,__LINE__)
-extern PRStatus
- pz_Unlock(
- PZLock *lock,
- char *file,
- PRIntn line
- );
-
-#define PZ_DestroyLock(k) pz_DestroyLock((k),__FILE__,__LINE__)
-extern void
- pz_DestroyLock(
- PZLock *lock,
- char *file,
- PRIntn line
- );
-
-
-#define PZ_NewCondVar(l) pz_NewCondVar((l),__FILE__,__LINE__)
-extern PZCondVar *
- pz_NewCondVar(
- PZLock *lock,
- char *file,
- PRIntn line
- );
-
-#define PZ_DestroyCondVar(v) pz_DestroyCondVar((v),__FILE__,__LINE__)
-extern void
- pz_DestroyCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- );
-
-#define PZ_WaitCondVar(v,t) pz_WaitCondVar((v),(t),__FILE__,__LINE__)
-extern PRStatus
- pz_WaitCondVar(
- PZCondVar *cvar,
- PRIntervalTime timeout,
- char *file,
- PRIntn line
- );
-
-#define PZ_NotifyCondVar(v) pz_NotifyCondVar((v),__FILE__,__LINE__)
-extern PRStatus
- pz_NotifyCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- );
-
-#define PZ_NotifyAllCondVar(v) pz_NotifyAllCondVar((v),__FILE__,__LINE__)
-extern PRStatus
- pz_NotifyAllCondVar(
- PZCondVar *cvar,
- char *file,
- PRIntn line
- );
-
-
-#define PZ_NewMonitor(t) pz_NewMonitor((t),__FILE__,__LINE__)
-extern PZMonitor *
- pz_NewMonitor(
- nssILockType ltype,
- char *file,
- PRIntn line
- );
-
-#define PZ_DestroyMonitor(m) pz_DestroyMonitor((m),__FILE__,__LINE__)
-extern void
- pz_DestroyMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
-
-#define PZ_EnterMonitor(m) pz_EnterMonitor((m),__FILE__,__LINE__)
-extern void
- pz_EnterMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
-
-
-#define PZ_ExitMonitor(m) pz_ExitMonitor((m),__FILE__,__LINE__)
-extern PRStatus
- pz_ExitMonitor(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
-
-#define PZ_InMonitor(m) (PZ_GetMonitorEntryCount(m) > 0 )
-#define PZ_GetMonitorEntryCount(m) pz_GetMonitorEntryCount((m),__FILE__,__LINE__)
-extern PRIntn
- pz_GetMonitorEntryCount(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
-
-#define PZ_Wait(m,i) pz_Wait((m),((i)),__FILE__,__LINE__)
-extern PRStatus
- pz_Wait(
- PZMonitor *mon,
- PRIntervalTime ticks,
- char *file,
- PRIntn line
- );
-
-#define PZ_Notify(m) pz_Notify((m),__FILE__,__LINE__)
-extern PRStatus
- pz_Notify(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
-
-#define PZ_NotifyAll(m) pz_NotifyAll((m),__FILE__,__LINE__)
-extern PRStatus
- pz_NotifyAll(
- PZMonitor *mon,
- char *file,
- PRIntn line
- );
-
-#define PZ_TraceFlush() pz_TraceFlush()
-extern void pz_TraceFlush( void );
-
-#else /* NEED_NSS_ILOCK */
-
-#define PZ_NewLock(t) PR_NewLock()
-#define PZ_DestroyLock(k) PR_DestroyLock((k))
-#define PZ_Lock(k) PR_Lock((k))
-#define PZ_Unlock(k) PR_Unlock((k))
-
-#define PZ_NewCondVar(l) PR_NewCondVar((l))
-#define PZ_DestroyCondVar(v) PR_DestroyCondVar((v))
-#define PZ_WaitCondVar(v,t) PR_WaitCondVar((v),(t))
-#define PZ_NotifyCondVar(v) PR_NotifyCondVar((v))
-#define PZ_NotifyAllCondVar(v) PR_NotifyAllCondVar((v))
-
-#define PZ_NewMonitor(t) PR_NewMonitor()
-#define PZ_DestroyMonitor(m) PR_DestroyMonitor((m))
-#define PZ_EnterMonitor(m) PR_EnterMonitor((m))
-#define PZ_ExitMonitor(m) PR_ExitMonitor((m))
-#define PZ_InMonitor(m) PR_InMonitor((m))
-#define PZ_Wait(m,t) PR_Wait(((m)),((t)))
-#define PZ_Notify(m) PR_Notify((m))
-#define PZ_NotifyAll(m) PR_Notify((m))
-#define PZ_TraceFlush() /* nothing */
-
-
-#endif /* NEED_NSS_ILOCK */
-
-PR_END_EXTERN_C
-#endif /* _NSSILOCK_H_ */
diff --git a/security/nss/lib/util/nsslocks.h b/security/nss/lib/util/nsslocks.h
deleted file mode 100644
index e294285c3..000000000
--- a/security/nss/lib/util/nsslocks.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * nsslocks.h - threadsafe functions to initialize lock pointers.
- *
- * NOTE - The interfaces formerly in this header were private and are now all
- * obsolete.
- *
- * $Id$
- */
-
diff --git a/security/nss/lib/util/nssrwlk.c b/security/nss/lib/util/nssrwlk.c
deleted file mode 100644
index 65fceda2e..000000000
--- a/security/nss/lib/util/nssrwlk.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nssrwlk.h"
-#include "nspr.h"
-
-PR_BEGIN_EXTERN_C
-
-/*
- * Reader-writer lock
- */
-struct nssRWLockStr {
- PZLock * rw_lock;
- char * rw_name; /* lock name */
- PRUint32 rw_rank; /* rank of the lock */
- PRInt32 rw_writer_locks; /* == 0, if unlocked */
- PRInt32 rw_reader_locks; /* == 0, if unlocked */
- /* > 0 , # of read locks */
- PRUint32 rw_waiting_readers; /* number of waiting readers */
- PRUint32 rw_waiting_writers; /* number of waiting writers */
- PZCondVar * rw_reader_waitq; /* cvar for readers */
- PZCondVar * rw_writer_waitq; /* cvar for writers */
- PRThread * rw_owner; /* lock owner for write-lock */
- /* Non-null if write lock held. */
-};
-
-PR_END_EXTERN_C
-
-#include <string.h>
-
-#ifdef DEBUG_RANK_ORDER
-#define NSS_RWLOCK_RANK_ORDER_DEBUG /* enable deadlock detection using
- rank-order for locks
- */
-#endif
-
-#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG
-
-static PRUintn nss_thread_rwlock_initialized;
-static PRUintn nss_thread_rwlock; /* TPD key for lock stack */
-static PRUintn nss_thread_rwlock_alloc_failed;
-
-#define _NSS_RWLOCK_RANK_ORDER_LIMIT 10
-
-typedef struct thread_rwlock_stack {
- PRInt32 trs_index; /* top of stack */
- NSSRWLock *trs_stack[_NSS_RWLOCK_RANK_ORDER_LIMIT]; /* stack of lock
- pointers */
-} thread_rwlock_stack;
-
-/* forward static declarations. */
-static PRUint32 nssRWLock_GetThreadRank(PRThread *me);
-static void nssRWLock_SetThreadRank(PRThread *me, NSSRWLock *rwlock);
-static void nssRWLock_UnsetThreadRank(PRThread *me, NSSRWLock *rwlock);
-static void nssRWLock_ReleaseLockStack(void *lock_stack);
-
-#endif
-
-#define UNTIL(x) while(!(x))
-
-/*
- * Reader/Writer Locks
- */
-
-/*
- * NSSRWLock_New
- * Create a reader-writer lock, with the given lock rank and lock name
- *
- */
-
-NSSRWLock *
-NSSRWLock_New(PRUint32 lock_rank, const char *lock_name)
-{
- NSSRWLock *rwlock;
-
- rwlock = PR_NEWZAP(NSSRWLock);
- if (rwlock == NULL)
- return NULL;
-
- rwlock->rw_lock = PZ_NewLock(nssILockRWLock);
- if (rwlock->rw_lock == NULL) {
- goto loser;
- }
- rwlock->rw_reader_waitq = PZ_NewCondVar(rwlock->rw_lock);
- if (rwlock->rw_reader_waitq == NULL) {
- goto loser;
- }
- rwlock->rw_writer_waitq = PZ_NewCondVar(rwlock->rw_lock);
- if (rwlock->rw_writer_waitq == NULL) {
- goto loser;
- }
- if (lock_name != NULL) {
- rwlock->rw_name = (char*) PR_Malloc(strlen(lock_name) + 1);
- if (rwlock->rw_name == NULL) {
- goto loser;
- }
- strcpy(rwlock->rw_name, lock_name);
- } else {
- rwlock->rw_name = NULL;
- }
- rwlock->rw_rank = lock_rank;
- rwlock->rw_waiting_readers = 0;
- rwlock->rw_waiting_writers = 0;
- rwlock->rw_reader_locks = 0;
- rwlock->rw_writer_locks = 0;
-
- return rwlock;
-
-loser:
- NSSRWLock_Destroy(rwlock);
- return(NULL);
-}
-
-/*
-** Destroy the given RWLock "lock".
-*/
-void
-NSSRWLock_Destroy(NSSRWLock *rwlock)
-{
- PR_ASSERT(rwlock != NULL);
- PR_ASSERT(rwlock->rw_waiting_readers == 0);
-
- /* XXX Shouldn't we lock the PZLock before destroying this?? */
-
- if (rwlock->rw_name)
- PR_Free(rwlock->rw_name);
- if (rwlock->rw_reader_waitq)
- PZ_DestroyCondVar(rwlock->rw_reader_waitq);
- if (rwlock->rw_writer_waitq)
- PZ_DestroyCondVar(rwlock->rw_writer_waitq);
- if (rwlock->rw_lock)
- PZ_DestroyLock(rwlock->rw_lock);
- PR_DELETE(rwlock);
-}
-
-/*
-** Read-lock the RWLock.
-*/
-void
-NSSRWLock_LockRead(NSSRWLock *rwlock)
-{
- PRThread *me = PR_GetCurrentThread();
-
- PZ_Lock(rwlock->rw_lock);
-#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG
-
- /*
- * assert that rank ordering is not violated; the rank of 'rwlock' should
- * be equal to or greater than the highest rank of all the locks held by
- * the thread.
- */
- PR_ASSERT((rwlock->rw_rank == NSS_RWLOCK_RANK_NONE) ||
- (rwlock->rw_rank >= nssRWLock_GetThreadRank(me)));
-#endif
- /*
- * wait if write-locked or if a writer is waiting; preference for writers
- */
- UNTIL ( (rwlock->rw_owner == me) || /* I own it, or */
- ((rwlock->rw_owner == NULL) && /* no-one owns it, and */
- (rwlock->rw_waiting_writers == 0))) { /* no-one is waiting to own */
-
- rwlock->rw_waiting_readers++;
- PZ_WaitCondVar(rwlock->rw_reader_waitq, PR_INTERVAL_NO_TIMEOUT);
- rwlock->rw_waiting_readers--;
- }
- rwlock->rw_reader_locks++; /* Increment read-lock count */
-
- PZ_Unlock(rwlock->rw_lock);
-
-#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG
- nssRWLock_SetThreadRank(me, rwlock);/* update thread's lock rank */
-#endif
-}
-
-/* Unlock a Read lock held on this RW lock.
-*/
-void
-NSSRWLock_UnlockRead(NSSRWLock *rwlock)
-{
- PZ_Lock(rwlock->rw_lock);
-
- PR_ASSERT(rwlock->rw_reader_locks > 0); /* lock must be read locked */
-
- if (( rwlock->rw_reader_locks > 0) && /* caller isn't screwey */
- (--rwlock->rw_reader_locks == 0) && /* not read locked any more */
- ( rwlock->rw_owner == NULL) && /* not write locked */
- ( rwlock->rw_waiting_writers > 0)) { /* someone's waiting. */
-
- PZ_NotifyCondVar(rwlock->rw_writer_waitq); /* wake him up. */
- }
-
- PZ_Unlock(rwlock->rw_lock);
-
-#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG
- /*
- * update thread's lock rank
- */
- nssRWLock_UnsetThreadRank(me, rwlock);
-#endif
- return;
-}
-
-/*
-** Write-lock the RWLock.
-*/
-void
-NSSRWLock_LockWrite(NSSRWLock *rwlock)
-{
- PRThread *me = PR_GetCurrentThread();
-
- PZ_Lock(rwlock->rw_lock);
-#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG
- /*
- * assert that rank ordering is not violated; the rank of 'rwlock' should
- * be equal to or greater than the highest rank of all the locks held by
- * the thread.
- */
- PR_ASSERT((rwlock->rw_rank == NSS_RWLOCK_RANK_NONE) ||
- (rwlock->rw_rank >= nssRWLock_GetThreadRank(me)));
-#endif
- /*
- * wait if read locked or write locked.
- */
- PR_ASSERT(rwlock->rw_reader_locks >= 0);
- PR_ASSERT(me != NULL);
-
- UNTIL ( (rwlock->rw_owner == me) || /* I own write lock, or */
- ((rwlock->rw_owner == NULL) && /* no writer and */
- (rwlock->rw_reader_locks == 0))) { /* no readers, either. */
-
- rwlock->rw_waiting_writers++;
- PZ_WaitCondVar(rwlock->rw_writer_waitq, PR_INTERVAL_NO_TIMEOUT);
- rwlock->rw_waiting_writers--;
- PR_ASSERT(rwlock->rw_reader_locks >= 0);
- }
-
- PR_ASSERT(rwlock->rw_reader_locks == 0);
- /*
- * apply write lock
- */
- rwlock->rw_owner = me;
- rwlock->rw_writer_locks++; /* Increment write-lock count */
-
- PZ_Unlock(rwlock->rw_lock);
-
-#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG
- /*
- * update thread's lock rank
- */
- nssRWLock_SetThreadRank(me,rwlock);
-#endif
-}
-
-/* Unlock a Read lock held on this RW lock.
-*/
-void
-NSSRWLock_UnlockWrite(NSSRWLock *rwlock)
-{
- PRThread *me = PR_GetCurrentThread();
-
- PZ_Lock(rwlock->rw_lock);
- PR_ASSERT(rwlock->rw_owner == me); /* lock must be write-locked by me. */
- PR_ASSERT(rwlock->rw_writer_locks > 0); /* lock must be write locked */
-
- if ( rwlock->rw_owner == me && /* I own it, and */
- rwlock->rw_writer_locks > 0 && /* I own it, and */
- --rwlock->rw_writer_locks == 0) { /* I'm all done with it */
-
- rwlock->rw_owner = NULL; /* I don't own it any more. */
-
- /* Give preference to waiting writers. */
- if (rwlock->rw_waiting_writers > 0) {
- if (rwlock->rw_reader_locks == 0)
- PZ_NotifyCondVar(rwlock->rw_writer_waitq);
- } else if (rwlock->rw_waiting_readers > 0) {
- PZ_NotifyAllCondVar(rwlock->rw_reader_waitq);
- }
- }
- PZ_Unlock(rwlock->rw_lock);
-
-#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG
- /*
- * update thread's lock rank
- */
- nssRWLock_UnsetThreadRank(me, rwlock);
-#endif
- return;
-}
-
-/* This is primarily for debugging, i.e. for inclusion in ASSERT calls. */
-PRBool
-NSSRWLock_HaveWriteLock(NSSRWLock *rwlock) {
- PRBool ownWriteLock;
- PRThread *me = PR_GetCurrentThread();
-
- /* This lock call isn't really necessary.
- ** If this thread is the owner, that fact cannot change during this call,
- ** because this thread is in this call.
- ** If this thread is NOT the owner, the owner could change, but it
- ** could not become this thread.
- */
-#if UNNECESSARY
- PZ_Lock(rwlock->rw_lock);
-#endif
- ownWriteLock = (PRBool)(me == rwlock->rw_owner);
-#if UNNECESSARY
- PZ_Unlock(rwlock->rw_lock);
-#endif
- return ownWriteLock;
-}
-
-#ifdef NSS_RWLOCK_RANK_ORDER_DEBUG
-
-/*
- * nssRWLock_SetThreadRank
- * Set a thread's lock rank, which is the highest of the ranks of all
- * the locks held by the thread. Pointers to the locks are added to a
- * per-thread list, which is anchored off a thread-private data key.
- */
-
-static void
-nssRWLock_SetThreadRank(PRThread *me, NSSRWLock *rwlock)
-{
- thread_rwlock_stack *lock_stack;
- PRStatus rv;
-
- /*
- * allocated thread-private-data for rwlock list, if not already allocated
- */
- if (!nss_thread_rwlock_initialized) {
- /*
- * allocate tpd, only if not failed already
- */
- if (!nss_thread_rwlock_alloc_failed) {
- if (PR_NewThreadPrivateIndex(&nss_thread_rwlock,
- nssRWLock_ReleaseLockStack)
- == PR_FAILURE) {
- nss_thread_rwlock_alloc_failed = 1;
- return;
- }
- } else
- return;
- }
- /*
- * allocate a lock stack
- */
- if ((lock_stack = PR_GetThreadPrivate(nss_thread_rwlock)) == NULL) {
- lock_stack = (thread_rwlock_stack *)
- PR_CALLOC(1 * sizeof(thread_rwlock_stack));
- if (lock_stack) {
- rv = PR_SetThreadPrivate(nss_thread_rwlock, lock_stack);
- if (rv == PR_FAILURE) {
- PR_DELETE(lock_stack);
- nss_thread_rwlock_alloc_failed = 1;
- return;
- }
- } else {
- nss_thread_rwlock_alloc_failed = 1;
- return;
- }
- }
- /*
- * add rwlock to lock stack, if limit is not exceeded
- */
- if (lock_stack) {
- if (lock_stack->trs_index < _NSS_RWLOCK_RANK_ORDER_LIMIT)
- lock_stack->trs_stack[lock_stack->trs_index++] = rwlock;
- }
- nss_thread_rwlock_initialized = 1;
-}
-
-static void
-nssRWLock_ReleaseLockStack(void *lock_stack)
-{
- PR_ASSERT(lock_stack);
- PR_DELETE(lock_stack);
-}
-
-/*
- * nssRWLock_GetThreadRank
- *
- * return thread's lock rank. If thread-private-data for the lock
- * stack is not allocated, return NSS_RWLOCK_RANK_NONE.
- */
-
-static PRUint32
-nssRWLock_GetThreadRank(PRThread *me)
-{
- thread_rwlock_stack *lock_stack;
-
- if (nss_thread_rwlock_initialized) {
- if ((lock_stack = PR_GetThreadPrivate(nss_thread_rwlock)) == NULL)
- return (NSS_RWLOCK_RANK_NONE);
- else
- return(lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank);
-
- } else
- return (NSS_RWLOCK_RANK_NONE);
-}
-
-/*
- * nssRWLock_UnsetThreadRank
- *
- * remove the rwlock from the lock stack. Since locks may not be
- * unlocked in a FIFO order, the entire lock stack is searched.
- */
-
-static void
-nssRWLock_UnsetThreadRank(PRThread *me, NSSRWLock *rwlock)
-{
- thread_rwlock_stack *lock_stack;
- int new_index = 0, index, done = 0;
-
- if (!nss_thread_rwlock_initialized)
- return;
-
- lock_stack = PR_GetThreadPrivate(nss_thread_rwlock);
-
- PR_ASSERT(lock_stack != NULL);
-
- index = lock_stack->trs_index - 1;
- while (index-- >= 0) {
- if ((lock_stack->trs_stack[index] == rwlock) && !done) {
- /*
- * reset the slot for rwlock
- */
- lock_stack->trs_stack[index] = NULL;
- done = 1;
- }
- /*
- * search for the lowest-numbered empty slot, above which there are
- * no non-empty slots
- */
- if ((lock_stack->trs_stack[index] != NULL) && !new_index)
- new_index = index + 1;
- if (done && new_index)
- break;
- }
- /*
- * set top of stack to highest numbered empty slot
- */
- lock_stack->trs_index = new_index;
-
-}
-
-#endif /* NSS_RWLOCK_RANK_ORDER_DEBUG */
diff --git a/security/nss/lib/util/nssrwlk.h b/security/nss/lib/util/nssrwlk.h
deleted file mode 100644
index 3402c82e1..000000000
--- a/security/nss/lib/util/nssrwlk.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-** File: nsrwlock.h
-** Description: API to basic reader-writer lock functions of NSS.
-** These are re-entrant reader writer locks; that is,
-** If I hold the write lock, I can ask for it and get it again.
-** If I hold the write lock, I can also ask for and get a read lock.
-** I can then release the locks in any order (read or write).
-** I must release each lock type as many times as I acquired it.
-** Otherwise, these are normal reader/writer locks.
-**
-** For deadlock detection, locks should be ranked, and no lock may be aquired
-** while I hold a lock of higher rank number.
-** If you don't want that feature, always use NSS_RWLOCK_RANK_NONE.
-** Lock name is for debugging, and is optional (may be NULL)
-**/
-
-#ifndef nssrwlk_h___
-#define nssrwlk_h___
-
-#include "utilrename.h"
-#include "prtypes.h"
-#include "nssrwlkt.h"
-
-#define NSS_RWLOCK_RANK_NONE 0
-
-/* SEC_BEGIN_PROTOS */
-PR_BEGIN_EXTERN_C
-
-/***********************************************************************
-** FUNCTION: NSSRWLock_New
-** DESCRIPTION:
-** Returns a pointer to a newly created reader-writer lock object.
-** INPUTS: Lock rank
-** Lock name
-** OUTPUTS: void
-** RETURN: NSSRWLock*
-** If the lock cannot be created because of resource constraints, NULL
-** is returned.
-**
-***********************************************************************/
-extern NSSRWLock* NSSRWLock_New(PRUint32 lock_rank, const char *lock_name);
-
-/***********************************************************************
-** FUNCTION: NSSRWLock_AtomicCreate
-** DESCRIPTION:
-** Given the address of a NULL pointer to a NSSRWLock,
-** atomically initializes that pointer to a newly created NSSRWLock.
-** Returns the value placed into that pointer, or NULL.
-**
-** INPUTS: address of NSRWLock pointer
-** Lock rank
-** Lock name
-** OUTPUTS: NSSRWLock*
-** RETURN: NSSRWLock*
-** If the lock cannot be created because of resource constraints,
-** the pointer will be left NULL.
-**
-***********************************************************************/
-extern NSSRWLock *
-nssRWLock_AtomicCreate( NSSRWLock ** prwlock,
- PRUint32 lock_rank,
- const char * lock_name);
-
-/***********************************************************************
-** FUNCTION: NSSRWLock_Destroy
-** DESCRIPTION:
-** Destroys a given RW lock object.
-** INPUTS: NSSRWLock *lock - Lock to be freed.
-** OUTPUTS: void
-** RETURN: None
-***********************************************************************/
-extern void NSSRWLock_Destroy(NSSRWLock *lock);
-
-/***********************************************************************
-** FUNCTION: NSSRWLock_LockRead
-** DESCRIPTION:
-** Apply a read lock (non-exclusive) on a RWLock
-** INPUTS: NSSRWLock *lock - Lock to be read-locked.
-** OUTPUTS: void
-** RETURN: None
-***********************************************************************/
-extern void NSSRWLock_LockRead(NSSRWLock *lock);
-
-/***********************************************************************
-** FUNCTION: NSSRWLock_LockWrite
-** DESCRIPTION:
-** Apply a write lock (exclusive) on a RWLock
-** INPUTS: NSSRWLock *lock - Lock to write-locked.
-** OUTPUTS: void
-** RETURN: None
-***********************************************************************/
-extern void NSSRWLock_LockWrite(NSSRWLock *lock);
-
-/***********************************************************************
-** FUNCTION: NSSRWLock_UnlockRead
-** DESCRIPTION:
-** Release a Read lock. Unlocking an unlocked lock has undefined results.
-** INPUTS: NSSRWLock *lock - Lock to unlocked.
-** OUTPUTS: void
-** RETURN: void
-***********************************************************************/
-extern void NSSRWLock_UnlockRead(NSSRWLock *lock);
-
-/***********************************************************************
-** FUNCTION: NSSRWLock_UnlockWrite
-** DESCRIPTION:
-** Release a Write lock. Unlocking an unlocked lock has undefined results.
-** INPUTS: NSSRWLock *lock - Lock to unlocked.
-** OUTPUTS: void
-** RETURN: void
-***********************************************************************/
-extern void NSSRWLock_UnlockWrite(NSSRWLock *lock);
-
-/***********************************************************************
-** FUNCTION: NSSRWLock_HaveWriteLock
-** DESCRIPTION:
-** Tells caller whether the current thread holds the write lock, or not.
-** INPUTS: NSSRWLock *lock - Lock to test.
-** OUTPUTS: void
-** RETURN: PRBool PR_TRUE IFF the current thread holds the write lock.
-***********************************************************************/
-
-extern PRBool NSSRWLock_HaveWriteLock(NSSRWLock *rwlock);
-
-/* SEC_END_PROTOS */
-PR_END_EXTERN_C
-
-#endif /* nsrwlock_h___ */
diff --git a/security/nss/lib/util/nssrwlkt.h b/security/nss/lib/util/nssrwlkt.h
deleted file mode 100644
index 57251035f..000000000
--- a/security/nss/lib/util/nssrwlkt.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nssrwlkt_h___
-#define nssrwlkt_h___
-
-#include "utilrename.h"
-#include "nssilock.h"
-/*
- * NSSRWLock --
- *
- * The reader writer lock, NSSRWLock, is an opaque object to the clients
- * of NSS. All routines operate on a pointer to this opaque entity.
- */
-
-typedef struct nssRWLockStr NSSRWLock;
-
-
-#endif /* nsrwlock_h___ */
diff --git a/security/nss/lib/util/nssutil.def b/security/nss/lib/util/nssutil.def
deleted file mode 100644
index b7a94b219..000000000
--- a/security/nss/lib/util/nssutil.def
+++ /dev/null
@@ -1,272 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-;+# 1. For all unix platforms, the string ";-" means "remove this line"
-;+# 2. For all unix platforms, the string " DATA " will be removed from any
-;+# line on which it occurs.
-;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-;+# On AIX, lines containing ";+" will be removed.
-;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-;+# 5. For all unix platforms, after the above processing has taken place,
-;+# all characters after the first ";" on the line will be removed.
-;+# And for AIX, the first ";" will also be removed.
-;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-;+# directives are hidden behind ";", ";+", and ";-"
-;+NSSUTIL_3.12 { # NSS Utilities 3.12 release
-;+ global:
-LIBRARY nssutil3 ;-
-EXPORTS ;-
-ATOB_AsciiToData_Util;
-ATOB_ConvertAsciiToItem_Util;
-BTOA_ConvertItemToAscii_Util;
-BTOA_DataToAscii_Util;
-CERT_GenTime2FormattedAscii_Util;
-DER_AsciiToTime_Util;
-DER_DecodeTimeChoice_Util;
-DER_Encode_Util;
-DER_EncodeTimeChoice_Util;
-DER_GeneralizedDayToAscii_Util;
-DER_GeneralizedTimeToTime_Util;
-DER_GetInteger_Util;
-DER_GetUInteger;
-DER_LengthLength;
-DER_Lengths_Util;
-DER_SetUInteger;
-DER_StoreHeader;
-DER_TimeChoiceDayToAscii_Util;
-DER_TimeToGeneralizedTime_Util;
-DER_TimeToGeneralizedTimeArena_Util;
-DER_TimeToUTCTime_Util;
-DER_UTCDayToAscii_Util;
-DER_UTCTimeToAscii_Util;
-DER_UTCTimeToTime_Util;
-NSS_PutEnv_Util;
-NSSBase64_DecodeBuffer_Util;
-NSSBase64_EncodeItem_Util;
-NSSBase64Decoder_Create_Util;
-NSSBase64Decoder_Destroy_Util;
-NSSBase64Decoder_Update_Util;
-NSSBase64Encoder_Create_Util;
-NSSBase64Encoder_Destroy_Util;
-NSSBase64Encoder_Update_Util;
-NSSRWLock_Destroy_Util;
-NSSRWLock_HaveWriteLock_Util;
-NSSRWLock_LockRead_Util;
-NSSRWLock_LockWrite_Util;
-NSSRWLock_New_Util;
-NSSRWLock_UnlockRead_Util;
-NSSRWLock_UnlockWrite_Util;
-PORT_Alloc_Util;
-PORT_ArenaAlloc_Util;
-PORT_ArenaGrow_Util;
-PORT_ArenaMark_Util;
-PORT_ArenaRelease_Util;
-PORT_ArenaStrdup_Util;
-PORT_ArenaUnmark_Util;
-PORT_ArenaZAlloc_Util;
-PORT_Free_Util;
-PORT_FreeArena_Util;
-PORT_GetError_Util;
-PORT_ISO88591_UTF8Conversion;
-PORT_NewArena_Util;
-PORT_Realloc_Util;
-PORT_RegExpCaseSearch;
-PORT_RegExpValid;
-PORT_SetError_Util;
-PORT_SetUCS2_ASCIIConversionFunction_Util;
-PORT_SetUCS2_UTF8ConversionFunction_Util;
-PORT_SetUCS4_UTF8ConversionFunction_Util;
-PORT_Strdup_Util;
-PORT_UCS2_ASCIIConversion_Util;
-PORT_UCS2_UTF8Conversion_Util;
-PORT_UCS4_UTF8Conversion;
-PORT_ZAlloc_Util;
-PORT_ZFree_Util;
-SEC_ASN1Decode_Util;
-SEC_ASN1DecodeInteger_Util;
-SEC_ASN1DecodeItem_Util;
-SEC_ASN1DecoderAbort_Util;
-SEC_ASN1DecoderClearFilterProc_Util;
-SEC_ASN1DecoderClearNotifyProc_Util;
-SEC_ASN1DecoderFinish_Util;
-SEC_ASN1DecoderSetFilterProc_Util;
-SEC_ASN1DecoderSetNotifyProc_Util;
-SEC_ASN1DecoderStart_Util;
-SEC_ASN1DecoderUpdate_Util;
-SEC_ASN1Encode_Util;
-SEC_ASN1EncodeInteger_Util;
-SEC_ASN1EncodeItem_Util;
-SEC_ASN1EncoderAbort_Util;
-SEC_ASN1EncoderClearNotifyProc_Util;
-SEC_ASN1EncoderClearStreaming_Util;
-SEC_ASN1EncoderClearTakeFromBuf_Util;
-SEC_ASN1EncoderFinish_Util;
-SEC_ASN1EncoderSetNotifyProc_Util;
-SEC_ASN1EncoderSetStreaming_Util;
-SEC_ASN1EncoderSetTakeFromBuf_Util;
-SEC_ASN1EncoderStart_Util;
-SEC_ASN1EncoderUpdate_Util;
-SEC_ASN1EncodeUnsignedInteger_Util;
-SEC_ASN1LengthLength_Util;
-SEC_QuickDERDecodeItem_Util;
-SEC_StringToOID;
-SECITEM_AllocItem_Util;
-SECITEM_ArenaDupItem_Util;
-SECITEM_CompareItem_Util;
-SECITEM_CopyItem_Util;
-SECITEM_DupItem_Util;
-SECITEM_FreeItem_Util;
-SECITEM_Hash;
-SECITEM_HashCompare;
-SECITEM_ItemsAreEqual_Util;
-SECITEM_ZfreeItem_Util;
-SECOID_AddEntry_Util;
-SECOID_CompareAlgorithmID_Util;
-SECOID_CopyAlgorithmID_Util;
-SECOID_DestroyAlgorithmID_Util;
-SECOID_FindOID_Util;
-SECOID_FindOIDByMechanism;
-SECOID_FindOIDByTag_Util;
-SECOID_FindOIDTag_Util;
-SECOID_FindOIDTagDescription_Util;
-SECOID_GetAlgorithmTag_Util;
-SECOID_Init;
-SECOID_KnownCertExtenOID;
-SECOID_SetAlgorithmID_Util;
-SECOID_Shutdown;
-SGN_CompareDigestInfo_Util;
-SGN_CopyDigestInfo_Util;
-SGN_CreateDigestInfo_Util;
-SGN_DecodeDigestInfo;
-SGN_DestroyDigestInfo_Util;
-;+#
-;+# Data objects
-;+#
-;+# Don't export these DATA symbols on Windows because they don't work right.
-;+# Use the SEC_ASN1_GET / SEC_ASN1_SUB / SEC_ASN1_XTRN macros to access them.
-;;SEC_AnyTemplate_Util DATA ;
-;;SEC_BitStringTemplate_Util DATA ;
-;;SEC_BMPStringTemplate_Util DATA ;
-;;SEC_BooleanTemplate_Util DATA ;
-;;SEC_EnumeratedTemplate DATA ;
-;;SEC_GeneralizedTimeTemplate_Util DATA ;
-;;SEC_IA5StringTemplate_Util DATA ;
-;;SEC_IntegerTemplate_Util DATA ;
-;;SEC_NullTemplate_Util DATA ;
-;;SEC_ObjectIDTemplate_Util DATA ;
-;;SEC_OctetStringTemplate_Util DATA ;
-;;SEC_PointerToAnyTemplate_Util DATA ;
-;;SEC_PointerToEnumeratedTemplate DATA ;
-;;SEC_PointerToGeneralizedTimeTemplate DATA ;
-;;SEC_PointerToOctetStringTemplate_Util DATA ;
-;;SEC_PrintableStringTemplate DATA ;
-;;SEC_SequenceOfAnyTemplate DATA ;
-;;SEC_SequenceOfObjectIDTemplate DATA ;
-;;SEC_SetOfAnyTemplate_Util DATA ;
-;;SEC_SkipTemplate DATA ;
-;;SEC_T61StringTemplate DATA ;
-;;SEC_UniversalStringTemplate DATA ;
-;;SEC_UTF8StringTemplate_Util DATA ;
-;;SECOID_AlgorithmIDTemplate_Util DATA ;
-;;sgn_DigestInfoTemplate_Util DATA ;
-NSS_Get_SEC_AnyTemplate_Util;
-NSS_Get_SEC_BitStringTemplate_Util;
-NSS_Get_SEC_BMPStringTemplate_Util;
-NSS_Get_SEC_BooleanTemplate_Util;
-NSS_Get_SEC_EnumeratedTemplate;
-NSS_Get_SEC_GeneralizedTimeTemplate_Util;
-NSS_Get_SEC_IA5StringTemplate_Util;
-NSS_Get_SEC_IntegerTemplate_Util;
-NSS_Get_SEC_NullTemplate_Util;
-NSS_Get_SEC_ObjectIDTemplate_Util;
-NSS_Get_SEC_OctetStringTemplate_Util;
-NSS_Get_SEC_PointerToAnyTemplate_Util;
-NSS_Get_SEC_PointerToEnumeratedTemplate;
-NSS_Get_SEC_PointerToGeneralizedTimeTemplate;
-NSS_Get_SEC_PointerToOctetStringTemplate_Util;
-NSS_Get_SEC_PrintableStringTemplate;
-NSS_Get_SEC_SequenceOfAnyTemplate;
-NSS_Get_SEC_SequenceOfObjectIDTemplate;
-NSS_Get_SEC_SetOfAnyTemplate_Util;
-NSS_Get_SEC_SkipTemplate;
-NSS_Get_SEC_T61StringTemplate;
-NSS_Get_SEC_UniversalStringTemplate;
-NSS_Get_SEC_UTF8StringTemplate_Util;
-NSS_Get_SECOID_AlgorithmIDTemplate_Util;
-NSS_Get_sgn_DigestInfoTemplate_Util;
-;+ local:
-;+ *;
-;+};
-;+NSSUTIL_3.12.3 { # NSS Utilities 3.12.3 release
-;+ global:
-NSS_GetAlgorithmPolicy;
-NSS_SetAlgorithmPolicy;
-SECITEM_ReallocItem;
-UTIL_SetForkState;
-;+ local:
-;+ *;
-;+};
-;+NSSUTIL_3.12.5 { # NSS Utilities 3.12.5 release
-;+ global:
-NSS_SecureMemcmp;
-PORT_LoadLibraryFromOrigin;
-;+ local:
-;+ *;
-;+};
-;+NSSUTIL_3.12.7 { # NSS Utilities 3.12.7 release
-;+ global:
-PORT_RegExpSearch;
-;+ local:
-;+ *;
-;+};
-;+NSSUTIL_3.13 { # NSS Utilities 3.13 release
-;+ global:
-NSSUTIL_GetVersion;
-NSS_InitializePRErrorTable;
-;+ local:
-;+ *;
-;+};
-;+NSSUTIL_3.14 { # NSS Utilities 3.14 release
-;+ global:
-;+# private exports for softoken
-_NSSUTIL_GetSecmodName;
-_NSSUTIL_EvaluateConfigDir;
-;+# public exports
-NSSUTIL_ArgDecodeNumber;
-NSSUTIL_ArgFetchValue;
-NSSUTIL_ArgGetParamValue;
-NSSUTIL_ArgGetLabel;
-NSSUTIL_ArgHasFlag;
-NSSUTIL_ArgIsBlank;
-NSSUTIL_ArgParseCipherFlags;
-NSSUTIL_ArgParseModuleSpec;
-NSSUTIL_ArgParseSlotFlags;
-NSSUTIL_ArgParseSlotInfo;
-NSSUTIL_ArgReadLong;
-NSSUTIL_ArgSkipParameter;
-NSSUTIL_ArgStrip;
-NSSUTIL_DoModuleDBFunction;
-NSSUTIL_DoubleEscape;
-NSSUTIL_DoubleEscapeSize;
-NSSUTIL_Escape;
-NSSUTIL_EscapeSize;
-NSSUTIL_MkModuleSpec;
-NSSUTIL_MkNSSString;
-NSSUTIL_MkSlotString;
-NSSUTIL_Quote;
-NSSUTIL_QuoteSize;
-;+ local:
-;+ *;
-;+};
-;+NSSUTIL_3.14.2 { # NSS Utilities 3.14.2 release
-;+ global:
-SECITEM_AllocArray;
-SECITEM_DupArray;
-SECITEM_FreeArray;
-SECITEM_ZfreeArray;
-;+ local:
-;+ *;
-;+};
diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h
deleted file mode 100644
index a1b46bd84..000000000
--- a/security/nss/lib/util/nssutil.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * NSS utility functions
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __nssutil_h_
-#define __nssutil_h_
-
-#ifndef RC_INVOKED
-#include "seccomon.h"
-#endif
-
-/*
- * NSS utilities's major version, minor version, patch level, build number,
- * and whether this is a beta release.
- *
- * The format of the version string should be
- * "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
- */
-#define NSSUTIL_VERSION "3.14.4.0 Beta"
-#define NSSUTIL_VMAJOR 3
-#define NSSUTIL_VMINOR 14
-#define NSSUTIL_VPATCH 4
-#define NSSUTIL_VBUILD 0
-#define NSSUTIL_BETA PR_TRUE
-
-SEC_BEGIN_PROTOS
-
-/*
- * Returns a const string of the UTIL library version.
- */
-extern const char *NSSUTIL_GetVersion(void);
-
-extern SECStatus
-NSS_InitializePRErrorTable(void);
-
-SEC_END_PROTOS
-
-#endif /* __nssutil_h_ */
diff --git a/security/nss/lib/util/nssutil.rc b/security/nss/lib/util/nssutil.rc
deleted file mode 100644
index 65d4e68b2..000000000
--- a/security/nss/lib/util/nssutil.rc
+++ /dev/null
@@ -1,68 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nssutil.h"
-#include <winver.h>
-
-#define MY_LIBNAME "nssutil"
-#define MY_FILEDESCRIPTION "NSS Utility Library"
-
-#define STRINGIZE(x) #x
-#define STRINGIZE2(x) STRINGIZE(x)
-#define NSSUTIL_VMAJOR_STR STRINGIZE2(NSSUTIL_VMAJOR)
-
-#ifdef _DEBUG
-#define MY_DEBUG_STR " (debug)"
-#define MY_FILEFLAGS_1 VS_FF_DEBUG
-#else
-#define MY_DEBUG_STR ""
-#define MY_FILEFLAGS_1 0x0L
-#endif
-#if NSSUTIL_BETA
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-#else
-#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-#endif
-
-#ifdef WINNT
-#define MY_FILEOS VOS_NT_WINDOWS32
-#else
-#define MY_FILEOS VOS__WINDOWS32
-#endif
-
-#define MY_INTERNAL_NAME MY_LIBNAME NSSUTIL_VMAJOR_STR
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version-information resource
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION NSSUTIL_VMAJOR,NSSUTIL_VMINOR,NSSUTIL_VPATCH,NSSUTIL_VBUILD
- PRODUCTVERSION NSSUTIL_VMAJOR,NSSUTIL_VMINOR,NSSUTIL_VPATCH,NSSUTIL_VBUILD
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
- FILEFLAGS MY_FILEFLAGS_2
- FILEOS MY_FILEOS
- FILETYPE VFT_DLL
- FILESUBTYPE 0x0L // not used
-
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904B0" // Lang=US English, CharSet=Unicode
- BEGIN
- VALUE "CompanyName", "Mozilla Foundation\0"
- VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
- VALUE "FileVersion", NSSUTIL_VERSION "\0"
- VALUE "InternalName", MY_INTERNAL_NAME "\0"
- VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
- VALUE "ProductName", "Network Security Services\0"
- VALUE "ProductVersion", NSSUTIL_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/security/nss/lib/util/oidstring.c b/security/nss/lib/util/oidstring.c
deleted file mode 100644
index 8bb963e08..000000000
--- a/security/nss/lib/util/oidstring.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <string.h>
-#include "secitem.h"
-#include "secport.h"
-#include "secerr.h"
-
-/* if to->data is not NULL, and to->len is large enough to hold the result,
- * then the resultant OID will be copyed into to->data, and to->len will be
- * changed to show the actual OID length.
- * Otherwise, memory for the OID will be allocated (from the caller's
- * PLArenaPool, if pool is non-NULL) and to->data will receive the address
- * of the allocated data, and to->len will receive the OID length.
- * The original value of to->data is not freed when a new buffer is allocated.
- *
- * The input string may begin with "OID." and this still be ignored.
- * The length of the input string is given in len. If len == 0, then
- * len will be computed as strlen(from), meaning it must be NUL terminated.
- * It is an error if from == NULL, or if *from == '\0'.
- */
-
-SECStatus
-SEC_StringToOID(PLArenaPool *pool, SECItem *to, const char *from, PRUint32 len)
-{
- PRUint32 decimal_numbers = 0;
- PRUint32 result_bytes = 0;
- SECStatus rv;
- PRUint8 result[1024];
-
- static const PRUint32 max_decimal = (0xffffffff / 10);
- static const char OIDstring[] = {"OID."};
-
- if (!from || !to) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- if (!len) {
- len = PL_strlen(from);
- }
- if (len >= 4 && !PL_strncasecmp(from, OIDstring, 4)) {
- from += 4; /* skip leading "OID." if present */
- len -= 4;
- }
- if (!len) {
-bad_data:
- PORT_SetError(SEC_ERROR_BAD_DATA);
- return SECFailure;
- }
- do {
- PRUint32 decimal = 0;
- while (len > 0 && isdigit(*from)) {
- PRUint32 addend = (*from++ - '0');
- --len;
- if (decimal > max_decimal) /* overflow */
- goto bad_data;
- decimal = (decimal * 10) + addend;
- if (decimal < addend) /* overflow */
- goto bad_data;
- }
- if (len != 0 && *from != '.') {
- goto bad_data;
- }
- if (decimal_numbers == 0) {
- if (decimal > 2)
- goto bad_data;
- result[0] = decimal * 40;
- result_bytes = 1;
- } else if (decimal_numbers == 1) {
- if (decimal > 40)
- goto bad_data;
- result[0] += decimal;
- } else {
- /* encode the decimal number, */
- PRUint8 * rp;
- PRUint32 num_bytes = 0;
- PRUint32 tmp = decimal;
- while (tmp) {
- num_bytes++;
- tmp >>= 7;
- }
- if (!num_bytes )
- ++num_bytes; /* use one byte for a zero value */
- if (num_bytes + result_bytes > sizeof result)
- goto bad_data;
- tmp = num_bytes;
- rp = result + result_bytes - 1;
- rp[tmp] = (PRUint8)(decimal & 0x7f);
- decimal >>= 7;
- while (--tmp > 0) {
- rp[tmp] = (PRUint8)(decimal | 0x80);
- decimal >>= 7;
- }
- result_bytes += num_bytes;
- }
- ++decimal_numbers;
- if (len > 0) { /* skip trailing '.' */
- ++from;
- --len;
- }
- } while (len > 0);
- /* now result contains result_bytes of data */
- if (to->data && to->len >= result_bytes) {
- PORT_Memcpy(to->data, result, to->len = result_bytes);
- rv = SECSuccess;
- } else {
- SECItem result_item = {siBuffer, NULL, 0 };
- result_item.data = result;
- result_item.len = result_bytes;
- rv = SECITEM_CopyItem(pool, to, &result_item);
- }
- return rv;
-}
diff --git a/security/nss/lib/util/pkcs11.h b/security/nss/lib/util/pkcs11.h
deleted file mode 100644
index 74ac250e0..000000000
--- a/security/nss/lib/util/pkcs11.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security In.c Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- *
- * The latest version of this header can be found at:
- * http://www.rsalabs.com/pkcs/pkcs-11/index.html
- */
-#ifndef _PKCS11_H_
-#define _PKCS11_H_ 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Before including this file (pkcs11.h) (or pkcs11t.h by
- * itself), 6 platform-specific macros must be defined. These
- * macros are described below, and typical definitions for them
- * are also given. Be advised that these definitions can depend
- * on both the platform and the compiler used (and possibly also
- * on whether a PKCS #11 library is linked statically or
- * dynamically).
- *
- * In addition to defining these 6 macros, the packing convention
- * for PKCS #11 structures should be set. The PKCS #11
- * convention on packing is that structures should be 1-byte
- * aligned.
- *
- * In a Win32 environment, this might be done by using the
- * following preprocessor directive before including pkcs11.h
- * or pkcs11t.h:
- *
- * #pragma pack(push, cryptoki, 1)
- *
- * and using the following preprocessor directive after including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(pop, cryptoki)
- *
- * In a UNIX environment, you're on your own here. You might
- * not need to do anything.
- *
- *
- * Now for the macros:
- *
- *
- * 1. CK_PTR: The indirection string for making a pointer to an
- * object. It can be used like this:
- *
- * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
- *
- * In a Win32 environment, it might be defined by
- *
- * #define CK_PTR *
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_PTR *
- *
- *
- * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
- * an exportable PKCS #11 library function definition out of a
- * return type and a function name. It should be used in the
- * following fashion to define the exposed PKCS #11 functions in
- * a PKCS #11 library:
- *
- * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
- * CK_VOID_PTR pReserved
- * )
- * {
- * ...
- * }
- *
- * For defining a function in a Win32 PKCS #11 .dll, it might be
- * defined by
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- * returnType __declspec(dllexport) name
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- * returnType name
- *
- *
- * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
- * an importable PKCS #11 library function declaration out of a
- * return type and a function name. It should be used in the
- * following fashion:
- *
- * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
- * CK_VOID_PTR pReserved
- * );
- *
- * For declaring a function in a Win32 PKCS #11 .dll, it might
- * be defined by
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- * returnType __declspec(dllimport) name
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- * returnType name
- *
- *
- * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
- * which makes a PKCS #11 API function pointer declaration or
- * function pointer type declaration out of a return type and a
- * function name. It should be used in the following fashion:
- *
- * // Define funcPtr to be a pointer to a PKCS #11 API function
- * // taking arguments args and returning CK_RV.
- * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
- *
- * or
- *
- * // Define funcPtrType to be the type of a pointer to a
- * // PKCS #11 API function taking arguments args and returning
- * // CK_RV, and then define funcPtr to be a variable of type
- * // funcPtrType.
- * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
- * funcPtrType funcPtr;
- *
- * For accessing functions in a Win32 PKCS #11 .dll, in might be
- * defined by
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- * returnType __declspec(dllimport) (* name)
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- * returnType (* name)
- *
- *
- * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
- * a function pointer type for an application callback out of
- * a return type for the callback and a name for the callback.
- * It should be used in the following fashion:
- *
- * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
- *
- * to declare a function pointer, myCallback, to a callback
- * which takes arguments args and returns a CK_RV. It can also
- * be used like this:
- *
- * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
- * myCallbackType myCallback;
- *
- * In a Win32 environment, it might be defined by
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- * returnType (* name)
- *
- * In a UNIX environment, it might be defined by
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- * returnType (* name)
- *
- *
- * 6. NULL_PTR: This macro is the value of a NULL pointer.
- *
- * In any ANSI/ISO C environment (and in many others as well),
- * this should be defined by
- *
- * #ifndef NULL_PTR
- * #define NULL_PTR 0
- * #endif
- */
-
-
-/* All the various PKCS #11 types and #define'd values are in the
- * file pkcs11t.h. */
-#include "pkcs11t.h"
-
-#define __PASTE(x,y) x##y
-
-
-/* packing defines */
-#include "pkcs11p.h"
-/* ==============================================================
- * Define the "extern" form of all the entry points.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST 1
-#define CK_PKCS11_FUNCTION_INFO(name) \
- CK_DECLARE_FUNCTION(CK_RV, name)
-
-/* pkcs11f.h has all the information about the PKCS #11
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define the typedef form of all the entry points. That is, for
- * each PKCS #11 function C_XXX, define a type CK_C_XXX which is
- * a pointer to that kind of function.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST 1
-#define CK_PKCS11_FUNCTION_INFO(name) \
- typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
-
-/* pkcs11f.h has all the information about the PKCS #11
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define structed vector of entry points. A CK_FUNCTION_LIST
- * contains a CK_VERSION indicating a library's PKCS #11 version
- * and then a whole slew of function pointers to the routines in
- * the library. This type was declared, but not defined, in
- * pkcs11t.h.
- * ==============================================================
- */
-
-#define CK_PKCS11_FUNCTION_INFO(name) \
- __PASTE(CK_,name) name;
-
-struct CK_FUNCTION_LIST {
-
- CK_VERSION version; /* PKCS #11 version */
-
-/* Pile all the function pointers into the CK_FUNCTION_LIST. */
-/* pkcs11f.h has all the information about the PKCS #11
- * function prototypes. */
-#include "pkcs11f.h"
-
-};
-
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-#undef __PASTE
-
-/* unpack */
-#include "pkcs11u.h"
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/security/nss/lib/util/pkcs11f.h b/security/nss/lib/util/pkcs11f.h
deleted file mode 100644
index 732b1a159..000000000
--- a/security/nss/lib/util/pkcs11f.h
+++ /dev/null
@@ -1,905 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security In.c Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- */
-/* This function contains pretty much everything about all the */
-/* PKCS #11 function prototypes. Because this information is */
-/* used for more than just declaring function prototypes, the */
-/* order of the functions appearing herein is important, and */
-/* should not be altered. */
-
-
-
-/* General-purpose */
-
-/* C_Initialize initializes the PKCS #11 library. */
-CK_PKCS11_FUNCTION_INFO(C_Initialize)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
- * cast to CK_C_INITIALIZE_ARGS_PTR
- * and dereferenced */
-);
-#endif
-
-
-/* C_Finalize indicates that an application is done with the
- * PKCS #11 library. */
-CK_PKCS11_FUNCTION_INFO(C_Finalize)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
-);
-#endif
-
-
-/* C_GetInfo returns general information about PKCS #11. */
-CK_PKCS11_FUNCTION_INFO(C_GetInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_INFO_PTR pInfo /* location that receives information */
-);
-#endif
-
-
-/* C_GetFunctionList returns the function list. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
- * function list */
-);
-#endif
-
-
-
-/* Slot and token management */
-
-/* C_GetSlotList obtains a list of slots in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_BBOOL tokenPresent, /* only slots with tokens? */
- CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
- CK_ULONG_PTR pulCount /* receives number of slots */
-);
-#endif
-
-
-/* C_GetSlotInfo obtains information about a particular slot in
- * the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* the ID of the slot */
- CK_SLOT_INFO_PTR pInfo /* receives the slot information */
-);
-#endif
-
-
-/* C_GetTokenInfo obtains information about a particular token
- * in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_TOKEN_INFO_PTR pInfo /* receives the token information */
-);
-#endif
-
-
-/* C_GetMechanismList obtains a list of mechanism types
- * supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of token's slot */
- CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
- CK_ULONG_PTR pulCount /* gets # of mechs. */
-);
-#endif
-
-
-/* C_GetMechanismInfo obtains information about a particular
- * mechanism possibly supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_MECHANISM_TYPE type, /* type of mechanism */
- CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
-);
-#endif
-
-
-/* C_InitToken initializes a token. */
-CK_PKCS11_FUNCTION_INFO(C_InitToken)
-#ifdef CK_NEED_ARG_LIST
-/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
-(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
- CK_ULONG ulPinLen, /* length in bytes of the PIN */
- CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
-);
-#endif
-
-
-/* C_InitPIN initializes the normal user's PIN. */
-CK_PKCS11_FUNCTION_INFO(C_InitPIN)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
- CK_ULONG ulPinLen /* length in bytes of the PIN */
-);
-#endif
-
-
-/* C_SetPIN modifies the PIN of the user who is logged in. */
-CK_PKCS11_FUNCTION_INFO(C_SetPIN)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
- CK_ULONG ulOldLen, /* length of the old PIN */
- CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
- CK_ULONG ulNewLen /* length of the new PIN */
-);
-#endif
-
-
-
-/* Session management */
-
-/* C_OpenSession opens a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_OpenSession)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID, /* the slot's ID */
- CK_FLAGS flags, /* from CK_SESSION_INFO */
- CK_VOID_PTR pApplication, /* passed to callback */
- CK_NOTIFY Notify, /* callback function */
- CK_SESSION_HANDLE_PTR phSession /* gets session handle */
-);
-#endif
-
-
-/* C_CloseSession closes a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseSession)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-/* C_CloseAllSessions closes all sessions with a token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SLOT_ID slotID /* the token's slot */
-);
-#endif
-
-
-/* C_GetSessionInfo obtains information about the session. */
-CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_SESSION_INFO_PTR pInfo /* receives session info */
-);
-#endif
-
-
-/* C_GetOperationState obtains the state of the cryptographic operation
- * in a session. */
-CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pOperationState, /* gets state */
- CK_ULONG_PTR pulOperationStateLen /* gets state length */
-);
-#endif
-
-
-/* C_SetOperationState restores the state of the cryptographic
- * operation in a session. */
-CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pOperationState, /* holds state */
- CK_ULONG ulOperationStateLen, /* holds state length */
- CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
- CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
-);
-#endif
-
-
-/* C_Login logs a user into a token. */
-CK_PKCS11_FUNCTION_INFO(C_Login)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_USER_TYPE userType, /* the user type */
- CK_UTF8CHAR_PTR pPin, /* the user's PIN */
- CK_ULONG ulPinLen /* the length of the PIN */
-);
-#endif
-
-
-/* C_Logout logs a user out from a token. */
-CK_PKCS11_FUNCTION_INFO(C_Logout)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-
-/* Object management */
-
-/* C_CreateObject creates a new object. */
-CK_PKCS11_FUNCTION_INFO(C_CreateObject)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
- CK_ULONG ulCount, /* attributes in template */
- CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
-);
-#endif
-
-
-/* C_CopyObject copies an object, creating a new object for the
- * copy. */
-CK_PKCS11_FUNCTION_INFO(C_CopyObject)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
- CK_ULONG ulCount, /* attributes in template */
- CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
-);
-#endif
-
-
-/* C_DestroyObject destroys an object. */
-CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject /* the object's handle */
-);
-#endif
-
-
-/* C_GetObjectSize gets the size of an object in bytes. */
-CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ULONG_PTR pulSize /* receives size of object */
-);
-#endif
-
-
-/* C_GetAttributeValue obtains the value of one or more object
- * attributes. */
-CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
- CK_ULONG ulCount /* attributes in template */
-);
-#endif
-
-
-/* C_SetAttributeValue modifies the value of one or more object
- * attributes */
-CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hObject, /* the object's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
- CK_ULONG ulCount /* attributes in template */
-);
-#endif
-
-
-/* C_FindObjectsInit initializes a search for token and session
- * objects that match a template. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
- CK_ULONG ulCount /* attrs in search template */
-);
-#endif
-
-
-/* C_FindObjects continues a search for token and session
- * objects that match a template, obtaining additional object
- * handles. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjects)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
- CK_ULONG ulMaxObjectCount, /* max handles to get */
- CK_ULONG_PTR pulObjectCount /* actual # returned */
-);
-#endif
-
-
-/* C_FindObjectsFinal finishes a search for token and session
- * objects. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-
-/* Encryption and decryption */
-
-/* C_EncryptInit initializes an encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
- CK_OBJECT_HANDLE hKey /* handle of encryption key */
-);
-#endif
-
-
-/* C_Encrypt encrypts single-part data. */
-CK_PKCS11_FUNCTION_INFO(C_Encrypt)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pData, /* the plaintext data */
- CK_ULONG ulDataLen, /* bytes of plaintext */
- CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptUpdate continues a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pPart, /* the plaintext data */
- CK_ULONG ulPartLen, /* plaintext data len */
- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptFinal finishes a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session handle */
- CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
- CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
-);
-#endif
-
-
-/* C_DecryptInit initializes a decryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
- CK_OBJECT_HANDLE hKey /* handle of decryption key */
-);
-#endif
-
-
-/* C_Decrypt decrypts encrypted data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Decrypt)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedData, /* ciphertext */
- CK_ULONG ulEncryptedDataLen, /* ciphertext length */
- CK_BYTE_PTR pData, /* gets plaintext */
- CK_ULONG_PTR pulDataLen /* gets p-text size */
-);
-#endif
-
-
-/* C_DecryptUpdate continues a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedPart, /* encrypted data */
- CK_ULONG ulEncryptedPartLen, /* input length */
- CK_BYTE_PTR pPart, /* gets plaintext */
- CK_ULONG_PTR pulPartLen /* p-text size */
-);
-#endif
-
-
-/* C_DecryptFinal finishes a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pLastPart, /* gets plaintext */
- CK_ULONG_PTR pulLastPartLen /* p-text size */
-);
-#endif
-
-
-
-/* Message digesting */
-
-/* C_DigestInit initializes a message-digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
-);
-#endif
-
-
-/* C_Digest digests data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Digest)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* data to be digested */
- CK_ULONG ulDataLen, /* bytes of data to digest */
- CK_BYTE_PTR pDigest, /* gets the message digest */
- CK_ULONG_PTR pulDigestLen /* gets digest length */
-);
-#endif
-
-
-/* C_DigestUpdate continues a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pPart, /* data to be digested */
- CK_ULONG ulPartLen /* bytes of data to be digested */
-);
-#endif
-
-
-/* C_DigestKey continues a multi-part message-digesting
- * operation, by digesting the value of a secret key as part of
- * the data already digested. */
-CK_PKCS11_FUNCTION_INFO(C_DigestKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_OBJECT_HANDLE hKey /* secret key to digest */
-);
-#endif
-
-
-/* C_DigestFinal finishes a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pDigest, /* gets the message digest */
- CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
-);
-#endif
-
-
-
-/* Signing and MACing */
-
-/* C_SignInit initializes a signature (private key encryption)
- * operation, where the signature is (will be) an appendix to
- * the data, and plaintext cannot be recovered from the
- *signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
- CK_OBJECT_HANDLE hKey /* handle of signature key */
-);
-#endif
-
-
-/* C_Sign signs (encrypts with private key) data in a single
- * part, where the signature is (will be) an appendix to the
- * data, and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Sign)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* the data to sign */
- CK_ULONG ulDataLen, /* count of bytes to sign */
- CK_BYTE_PTR pSignature, /* gets the signature */
- CK_ULONG_PTR pulSignatureLen /* gets signature length */
-);
-#endif
-
-
-/* C_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pPart, /* the data to sign */
- CK_ULONG ulPartLen /* count of bytes to sign */
-);
-#endif
-
-
-/* C_SignFinal finishes a multiple-part signature operation,
- * returning the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSignature, /* gets the signature */
- CK_ULONG_PTR pulSignatureLen /* gets signature length */
-);
-#endif
-
-
-/* C_SignRecoverInit initializes a signature operation, where
- * the data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
- CK_OBJECT_HANDLE hKey /* handle of the signature key */
-);
-#endif
-
-
-/* C_SignRecover signs data in a single operation, where the
- * data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecover)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* the data to sign */
- CK_ULONG ulDataLen, /* count of bytes to sign */
- CK_BYTE_PTR pSignature, /* gets the signature */
- CK_ULONG_PTR pulSignatureLen /* gets signature length */
-);
-#endif
-
-
-
-/* Verifying signatures and MACs */
-
-/* C_VerifyInit initializes a verification operation, where the
- * signature is an appendix to the data, and plaintext cannot
- * cannot be recovered from the signature (e.g. DSA). */
-CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
- CK_OBJECT_HANDLE hKey /* verification key */
-);
-#endif
-
-
-/* C_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data, and plaintext
- * cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Verify)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pData, /* signed data */
- CK_ULONG ulDataLen, /* length of signed data */
- CK_BYTE_PTR pSignature, /* signature */
- CK_ULONG ulSignatureLen /* signature length*/
-);
-#endif
-
-
-/* C_VerifyUpdate continues a multiple-part verification
- * operation, where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pPart, /* signed data */
- CK_ULONG ulPartLen /* length of signed data */
-);
-#endif
-
-
-/* C_VerifyFinal finishes a multiple-part verification
- * operation, checking the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSignature, /* signature to verify */
- CK_ULONG ulSignatureLen /* signature length */
-);
-#endif
-
-
-/* C_VerifyRecoverInit initializes a signature verification
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
- CK_OBJECT_HANDLE hKey /* verification key */
-);
-#endif
-
-
-/* C_VerifyRecover verifies a signature in a single-part
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSignature, /* signature to verify */
- CK_ULONG ulSignatureLen, /* signature length */
- CK_BYTE_PTR pData, /* gets signed data */
- CK_ULONG_PTR pulDataLen /* gets signed data len */
-);
-#endif
-
-
-
-/* Dual-function cryptographic operations */
-
-/* C_DigestEncryptUpdate continues a multiple-part digesting
- * and encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pPart, /* the plaintext data */
- CK_ULONG ulPartLen, /* plaintext length */
- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptDigestUpdate continues a multiple-part decryption and
- * digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedPart, /* ciphertext */
- CK_ULONG ulEncryptedPartLen, /* ciphertext length */
- CK_BYTE_PTR pPart, /* gets plaintext */
- CK_ULONG_PTR pulPartLen /* gets plaintext len */
-);
-#endif
-
-
-/* C_SignEncryptUpdate continues a multiple-part signing and
- * encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pPart, /* the plaintext data */
- CK_ULONG ulPartLen, /* plaintext length */
- CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
- CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptVerifyUpdate continues a multiple-part decryption and
- * verify operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_BYTE_PTR pEncryptedPart, /* ciphertext */
- CK_ULONG ulEncryptedPartLen, /* ciphertext length */
- CK_BYTE_PTR pPart, /* gets plaintext */
- CK_ULONG_PTR pulPartLen /* gets p-text length */
-);
-#endif
-
-
-
-/* Key management */
-
-/* C_GenerateKey generates a secret key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* key generation mech. */
- CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
- CK_ULONG ulCount, /* # of attrs in template */
- CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
-);
-#endif
-
-
-/* C_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session
- * handle */
- CK_MECHANISM_PTR pMechanism, /* key-gen
- * mech. */
- CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
- * for pub.
- * key */
- CK_ULONG ulPublicKeyAttributeCount, /* # pub.
- * attrs. */
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
- * for priv.
- * key */
- CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
- * attrs. */
- CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
- * key
- * handle */
- CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
- * priv. key
- * handle */
-);
-#endif
-
-
-/* C_WrapKey wraps (i.e., encrypts) a key. */
-CK_PKCS11_FUNCTION_INFO(C_WrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
- CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
- CK_OBJECT_HANDLE hKey, /* key to be wrapped */
- CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
- CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
-);
-#endif
-
-
-/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
- * key object. */
-CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
- CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
- CK_BYTE_PTR pWrappedKey, /* the wrapped key */
- CK_ULONG ulWrappedKeyLen, /* wrapped key len */
- CK_ATTRIBUTE_PTR pTemplate, /* new key template */
- CK_ULONG ulAttributeCount, /* template length */
- CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-);
-#endif
-
-
-/* C_DeriveKey derives a key from a base key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* session's handle */
- CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
- CK_OBJECT_HANDLE hBaseKey, /* base key */
- CK_ATTRIBUTE_PTR pTemplate, /* new key template */
- CK_ULONG ulAttributeCount, /* template length */
- CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-);
-#endif
-
-
-
-/* Random number generation */
-
-/* C_SeedRandom mixes additional seed material into the token's
- * random number generator. */
-CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR pSeed, /* the seed material */
- CK_ULONG ulSeedLen /* length of seed material */
-);
-#endif
-
-
-/* C_GenerateRandom generates random data. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_BYTE_PTR RandomData, /* receives the random data */
- CK_ULONG ulRandomLen /* # of bytes to generate */
-);
-#endif
-
-
-
-/* Parallel function management */
-
-/* C_GetFunctionStatus is a legacy function; it obtains an
- * updated status of a function running in parallel with an
- * application. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-/* C_CancelFunction is a legacy function; it cancels a function
- * running in parallel. */
-CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE hSession /* the session's handle */
-);
-#endif
-
-
-
-/* Functions added in for PKCS #11 Version 2.01 or later */
-
-/* C_WaitForSlotEvent waits for a slot event (token insertion,
- * removal, etc.) to occur. */
-CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_FLAGS flags, /* blocking/nonblocking flag */
- CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
- CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
-);
-#endif
diff --git a/security/nss/lib/util/pkcs11n.h b/security/nss/lib/util/pkcs11n.h
deleted file mode 100644
index 2e88eb4fc..000000000
--- a/security/nss/lib/util/pkcs11n.h
+++ /dev/null
@@ -1,464 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _PKCS11N_H_
-#define _PKCS11N_H_
-
-#ifdef DEBUG
-static const char CKT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-/*
- * pkcs11n.h
- *
- * This file contains the NSS-specific type definitions for Cryptoki
- * (PKCS#11).
- */
-
-/*
- * NSSCK_VENDOR_NSS
- *
- * Cryptoki reserves the high half of all the number spaces for
- * vendor-defined use. I'd like to keep all of our NSS-
- * specific values together, but not in the oh-so-obvious
- * 0x80000001, 0x80000002, etc. area. So I've picked an offset,
- * and constructed values for the beginnings of our spaces.
- *
- * Note that some "historical" Netscape values don't fall within
- * this range.
- */
-#define NSSCK_VENDOR_NSS 0x4E534350 /* NSCP */
-
-/*
- * NSS-defined object classes
- *
- */
-#define CKO_NSS (CKO_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
-
-#define CKO_NSS_CRL (CKO_NSS + 1)
-#define CKO_NSS_SMIME (CKO_NSS + 2)
-#define CKO_NSS_TRUST (CKO_NSS + 3)
-#define CKO_NSS_BUILTIN_ROOT_LIST (CKO_NSS + 4)
-#define CKO_NSS_NEWSLOT (CKO_NSS + 5)
-#define CKO_NSS_DELSLOT (CKO_NSS + 6)
-
-
-/*
- * NSS-defined key types
- *
- */
-#define CKK_NSS (CKK_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
-
-#define CKK_NSS_PKCS8 (CKK_NSS + 1)
-
-#define CKK_NSS_JPAKE_ROUND1 (CKK_NSS + 2)
-#define CKK_NSS_JPAKE_ROUND2 (CKK_NSS + 3)
-
-/*
- * NSS-defined certificate types
- *
- */
-#define CKC_NSS (CKC_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
-
-/* FAKE PKCS #11 defines */
-#define CKA_DIGEST 0x81000000L
-#define CKA_FLAGS_ONLY 0 /* CKA_CLASS */
-
-/*
- * NSS-defined object attributes
- *
- */
-#define CKA_NSS (CKA_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
-
-#define CKA_NSS_URL (CKA_NSS + 1)
-#define CKA_NSS_EMAIL (CKA_NSS + 2)
-#define CKA_NSS_SMIME_INFO (CKA_NSS + 3)
-#define CKA_NSS_SMIME_TIMESTAMP (CKA_NSS + 4)
-#define CKA_NSS_PKCS8_SALT (CKA_NSS + 5)
-#define CKA_NSS_PASSWORD_CHECK (CKA_NSS + 6)
-#define CKA_NSS_EXPIRES (CKA_NSS + 7)
-#define CKA_NSS_KRL (CKA_NSS + 8)
-
-#define CKA_NSS_PQG_COUNTER (CKA_NSS + 20)
-#define CKA_NSS_PQG_SEED (CKA_NSS + 21)
-#define CKA_NSS_PQG_H (CKA_NSS + 22)
-#define CKA_NSS_PQG_SEED_BITS (CKA_NSS + 23)
-#define CKA_NSS_MODULE_SPEC (CKA_NSS + 24)
-#define CKA_NSS_OVERRIDE_EXTENSIONS (CKA_NSS + 25)
-
-#define CKA_NSS_JPAKE_SIGNERID (CKA_NSS + 26)
-#define CKA_NSS_JPAKE_PEERID (CKA_NSS + 27)
-#define CKA_NSS_JPAKE_GX1 (CKA_NSS + 28)
-#define CKA_NSS_JPAKE_GX2 (CKA_NSS + 29)
-#define CKA_NSS_JPAKE_GX3 (CKA_NSS + 30)
-#define CKA_NSS_JPAKE_GX4 (CKA_NSS + 31)
-#define CKA_NSS_JPAKE_X2 (CKA_NSS + 32)
-#define CKA_NSS_JPAKE_X2S (CKA_NSS + 33)
-
-/*
- * Trust attributes:
- *
- * If trust goes standard, these probably will too. So I'll
- * put them all in one place.
- */
-
-#define CKA_TRUST (CKA_NSS + 0x2000)
-
-/* "Usage" key information */
-#define CKA_TRUST_DIGITAL_SIGNATURE (CKA_TRUST + 1)
-#define CKA_TRUST_NON_REPUDIATION (CKA_TRUST + 2)
-#define CKA_TRUST_KEY_ENCIPHERMENT (CKA_TRUST + 3)
-#define CKA_TRUST_DATA_ENCIPHERMENT (CKA_TRUST + 4)
-#define CKA_TRUST_KEY_AGREEMENT (CKA_TRUST + 5)
-#define CKA_TRUST_KEY_CERT_SIGN (CKA_TRUST + 6)
-#define CKA_TRUST_CRL_SIGN (CKA_TRUST + 7)
-
-/* "Purpose" trust information */
-#define CKA_TRUST_SERVER_AUTH (CKA_TRUST + 8)
-#define CKA_TRUST_CLIENT_AUTH (CKA_TRUST + 9)
-#define CKA_TRUST_CODE_SIGNING (CKA_TRUST + 10)
-#define CKA_TRUST_EMAIL_PROTECTION (CKA_TRUST + 11)
-#define CKA_TRUST_IPSEC_END_SYSTEM (CKA_TRUST + 12)
-#define CKA_TRUST_IPSEC_TUNNEL (CKA_TRUST + 13)
-#define CKA_TRUST_IPSEC_USER (CKA_TRUST + 14)
-#define CKA_TRUST_TIME_STAMPING (CKA_TRUST + 15)
-#define CKA_TRUST_STEP_UP_APPROVED (CKA_TRUST + 16)
-
-#define CKA_CERT_SHA1_HASH (CKA_TRUST + 100)
-#define CKA_CERT_MD5_HASH (CKA_TRUST + 101)
-
-/* NSS trust stuff */
-
-/* HISTORICAL: define used to pass in the database key for DSA private keys */
-#define CKA_NETSCAPE_DB 0xD5A0DB00L
-#define CKA_NETSCAPE_TRUST 0x80000001L
-
-/* FAKE PKCS #11 defines */
-#define CKM_FAKE_RANDOM 0x80000efeUL
-#define CKM_INVALID_MECHANISM 0xffffffffUL
-
-/*
- * NSS-defined crypto mechanisms
- *
- */
-#define CKM_NSS (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
-
-#define CKM_NSS_AES_KEY_WRAP (CKM_NSS + 1)
-#define CKM_NSS_AES_KEY_WRAP_PAD (CKM_NSS + 2)
-
-/* HKDF key derivation mechanisms. See CK_NSS_HKDFParams for documentation. */
-#define CKM_NSS_HKDF_SHA1 (CKM_NSS + 3)
-#define CKM_NSS_HKDF_SHA256 (CKM_NSS + 4)
-#define CKM_NSS_HKDF_SHA384 (CKM_NSS + 5)
-#define CKM_NSS_HKDF_SHA512 (CKM_NSS + 6)
-
-/* J-PAKE round 1 key generation mechanisms.
- *
- * Required template attributes: CKA_PRIME, CKA_SUBPRIME, CKA_BASE,
- * CKA_NSS_JPAKE_SIGNERID
- * Output key type: CKK_NSS_JPAKE_ROUND1
- * Output key class: CKO_PRIVATE_KEY
- * Parameter type: CK_NSS_JPAKERound1Params
- *
- */
-#define CKM_NSS_JPAKE_ROUND1_SHA1 (CKM_NSS + 7)
-#define CKM_NSS_JPAKE_ROUND1_SHA256 (CKM_NSS + 8)
-#define CKM_NSS_JPAKE_ROUND1_SHA384 (CKM_NSS + 9)
-#define CKM_NSS_JPAKE_ROUND1_SHA512 (CKM_NSS + 10)
-
-/* J-PAKE round 2 key derivation mechanisms.
- *
- * Required template attributes: CKA_NSS_JPAKE_PEERID
- * Input key type: CKK_NSS_JPAKE_ROUND1
- * Output key type: CKK_NSS_JPAKE_ROUND2
- * Output key class: CKO_PRIVATE_KEY
- * Parameter type: CK_NSS_JPAKERound2Params
- */
-#define CKM_NSS_JPAKE_ROUND2_SHA1 (CKM_NSS + 11)
-#define CKM_NSS_JPAKE_ROUND2_SHA256 (CKM_NSS + 12)
-#define CKM_NSS_JPAKE_ROUND2_SHA384 (CKM_NSS + 13)
-#define CKM_NSS_JPAKE_ROUND2_SHA512 (CKM_NSS + 14)
-
-/* J-PAKE final key material derivation mechanisms
- *
- * Input key type: CKK_NSS_JPAKE_ROUND2
- * Output key type: CKK_GENERIC_SECRET
- * Output key class: CKO_SECRET_KEY
- * Parameter type: CK_NSS_JPAKEFinalParams
- *
- * You must apply a KDF (e.g. CKM_NSS_HKDF_*) to resultant keying material
- * to get a key with uniformly distributed bits.
- */
-#define CKM_NSS_JPAKE_FINAL_SHA1 (CKM_NSS + 15)
-#define CKM_NSS_JPAKE_FINAL_SHA256 (CKM_NSS + 16)
-#define CKM_NSS_JPAKE_FINAL_SHA384 (CKM_NSS + 17)
-#define CKM_NSS_JPAKE_FINAL_SHA512 (CKM_NSS + 18)
-
-/* Constant-time MAC mechanisms:
- *
- * These operations verify a padded, MAC-then-encrypt block of data in
- * constant-time. Because of the order of operations, the padding bytes are not
- * protected by the MAC. However, disclosing the value of the padding bytes
- * gives an attacker the ability to decrypt ciphertexts. Such disclosure can be
- * as subtle as taking slightly less time to perform the MAC when the padding
- * is one byte longer. See https://www.isg.rhul.ac.uk/tls/
- *
- * CKM_NSS_HMAC_CONSTANT_TIME: performs an HMAC authentication.
- * CKM_NSS_SSL3_MAC_CONSTANT_TIME: performs an authentication with SSLv3 MAC.
- *
- * Parameter type: CK_NSS_MAC_CONSTANT_TIME_PARAMS
- */
-#define CKM_NSS_HMAC_CONSTANT_TIME (CKM_NSS + 19)
-#define CKM_NSS_SSL3_MAC_CONSTANT_TIME (CKM_NSS + 20)
-
-/*
- * HISTORICAL:
- * Do not attempt to use these. They are only used by NETSCAPE's internal
- * PKCS #11 interface. Most of these are place holders for other mechanism
- * and will change in the future.
- */
-#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002UL
-#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003UL
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004UL
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005UL
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006UL
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007UL
-#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008UL
-#define CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN 0x80000009UL
-#define CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN 0x8000000aUL
-#define CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN 0x8000000bUL
-
-#define CKM_TLS_PRF_GENERAL 0x80000373UL
-
-typedef struct CK_NSS_JPAKEPublicValue {
- CK_BYTE * pGX;
- CK_ULONG ulGXLen;
- CK_BYTE * pGV;
- CK_ULONG ulGVLen;
- CK_BYTE * pR;
- CK_ULONG ulRLen;
-} CK_NSS_JPAKEPublicValue;
-
-typedef struct CK_NSS_JPAKERound1Params {
- CK_NSS_JPAKEPublicValue gx1; /* out */
- CK_NSS_JPAKEPublicValue gx2; /* out */
-} CK_NSS_JPAKERound1Params;
-
-typedef struct CK_NSS_JPAKERound2Params {
- CK_BYTE * pSharedKey; /* in */
- CK_ULONG ulSharedKeyLen; /* in */
- CK_NSS_JPAKEPublicValue gx3; /* in */
- CK_NSS_JPAKEPublicValue gx4; /* in */
- CK_NSS_JPAKEPublicValue A; /* out */
-} CK_NSS_JPAKERound2Params;
-
-typedef struct CK_NSS_JPAKEFinalParams {
- CK_NSS_JPAKEPublicValue B; /* in */
-} CK_NSS_JPAKEFinalParams;
-
-/* macAlg: the MAC algorithm to use. This determines the hash function used in
- * the HMAC/SSLv3 MAC calculations.
- * ulBodyTotalLen: the total length of the data, including padding bytes and
- * padding length.
- * pHeader: points to a block of data that contains additional data to
- * authenticate. For TLS this includes the sequence number etc. For SSLv3,
- * this also includes the initial padding bytes.
- *
- * NOTE: the softoken's implementation of CKM_NSS_HMAC_CONSTANT_TIME and
- * CKM_NSS_SSL3_MAC_CONSTANT_TIME requires that the sum of ulBodyTotalLen
- * and ulHeaderLen be much smaller than 2^32 / 8 bytes because it uses an
- * unsigned int variable to represent the length in bits. This should not
- * be a problem because the SSL/TLS protocol limits the size of an SSL
- * record to something considerably less than 2^32 bytes.
- */
-typedef struct CK_NSS_MAC_CONSTANT_TIME_PARAMS {
- CK_MECHANISM_TYPE macAlg; /* in */
- CK_ULONG ulBodyTotalLen; /* in */
- CK_BYTE * pHeader; /* in */
- CK_ULONG ulHeaderLen; /* in */
-} CK_NSS_MAC_CONSTANT_TIME_PARAMS;
-
-/*
- * NSS-defined return values
- *
- */
-#define CKR_NSS (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
-
-#define CKR_NSS_CERTDB_FAILED (CKR_NSS + 1)
-#define CKR_NSS_KEYDB_FAILED (CKR_NSS + 2)
-
-/* Mandatory parameter for the CKM_NSS_HKDF_* key deriviation mechanisms.
- See RFC 5869.
-
- bExtract: If set, HKDF-Extract will be applied to the input key. If
- the optional salt is given, it is used; otherwise, the salt is
- set to a sequence of zeros equal in length to the HMAC output.
- If bExpand is not set, then the key template given to
- C_DeriveKey must indicate an output key size less than or equal
- to the output size of the HMAC.
-
- bExpand: If set, HKDF-Expand will be applied to the input key (if
- bExtract is not set) or to the result of HKDF-Extract (if
- bExtract is set). Any info given in the optional pInfo field will
- be included in the calculation.
-
- The size of the output key must be specified in the template passed to
- C_DeriveKey.
-*/
-typedef struct CK_NSS_HKDFParams {
- CK_BBOOL bExtract;
- CK_BYTE_PTR pSalt;
- CK_ULONG ulSaltLen;
- CK_BBOOL bExpand;
- CK_BYTE_PTR pInfo;
- CK_ULONG ulInfoLen;
-} CK_NSS_HKDFParams;
-
-/*
- * Trust info
- *
- * This isn't part of the Cryptoki standard (yet), so I'm putting
- * all the definitions here. Some of this would move to nssckt.h
- * if trust info were made part of the standard. In view of this
- * possibility, I'm putting my (NSS) values in the NSS
- * vendor space, like everything else.
- */
-
-typedef CK_ULONG CK_TRUST;
-
-/* The following trust types are defined: */
-#define CKT_VENDOR_DEFINED 0x80000000
-
-#define CKT_NSS (CKT_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
-
-/* If trust goes standard, these'll probably drop out of vendor space. */
-#define CKT_NSS_TRUSTED (CKT_NSS + 1)
-#define CKT_NSS_TRUSTED_DELEGATOR (CKT_NSS + 2)
-#define CKT_NSS_MUST_VERIFY_TRUST (CKT_NSS + 3)
-#define CKT_NSS_NOT_TRUSTED (CKT_NSS + 10)
-#define CKT_NSS_TRUST_UNKNOWN (CKT_NSS + 5) /* default */
-
-/*
- * These may well remain NSS-specific; I'm only using them
- * to cache resolution data.
- */
-#define CKT_NSS_VALID_DELEGATOR (CKT_NSS + 11)
-
-
-/*
- * old definitions. They still exist, but the plain meaning of the
- * labels have never been accurate to what was really implemented.
- * The new labels correctly reflect what the values effectively mean.
- */
-#if defined(__GNUC__) && (__GNUC__ > 3)
-/* make GCC warn when we use these #defines */
-/*
- * This is really painful because GCC doesn't allow us to mark random
- * #defines as deprecated. We can only mark the following:
- * functions, variables, and types.
- * const variables will create extra storage for everyone including this
- * header file, so it's undesirable.
- * functions could be inlined to prevent storage creation, but will fail
- * when constant values are expected (like switch statements).
- * enum types do not seem to pay attention to the deprecated attribute.
- *
- * That leaves typedefs. We declare new types that we then deprecate, then
- * cast the resulting value to the deprecated type in the #define, thus
- * producting the warning when the #define is used.
- */
-#if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
-/* The mac doesn't like the friendlier deprecate messages. I'm assuming this
- * is a gcc version issue rather than mac or ppc specific */
-typedef CK_TRUST __CKT_NSS_UNTRUSTED __attribute__((deprecated));
-typedef CK_TRUST __CKT_NSS_VALID __attribute__ ((deprecated));
-typedef CK_TRUST __CKT_NSS_MUST_VERIFY __attribute__((deprecated));
-#else
-/* when possible, get a full deprecation warning. This works on gcc 4.5
- * it may work on earlier versions of gcc */
-typedef CK_TRUST __CKT_NSS_UNTRUSTED __attribute__((deprecated
- ("CKT_NSS_UNTRUSTED really means CKT_NSS_MUST_VERIFY_TRUST")));
-typedef CK_TRUST __CKT_NSS_VALID __attribute__ ((deprecated
- ("CKT_NSS_VALID really means CKT_NSS_NOT_TRUSTED")));
-typedef CK_TRUST __CKT_NSS_MUST_VERIFY __attribute__((deprecated
- ("CKT_NSS_MUST_VERIFY really functions as CKT_NSS_TRUST_UNKNOWN")));
-#endif
-#define CKT_NSS_UNTRUSTED ((__CKT_NSS_UNTRUSTED)CKT_NSS_MUST_VERIFY_TRUST)
-#define CKT_NSS_VALID ((__CKT_NSS_VALID) CKT_NSS_NOT_TRUSTED)
-/* keep the old value for compatibility reasons*/
-#define CKT_NSS_MUST_VERIFY ((__CKT_NSS_MUST_VERIFY)(CKT_NSS +4))
-#else
-#ifdef _WIN32
-/* This magic gets the windows compiler to give us a deprecation
- * warning */
-#pragma deprecated(CKT_NSS_UNTRUSTED, CKT_NSS_MUST_VERIFY, CKT_NSS_VALID)
-#endif
-/* CKT_NSS_UNTRUSTED really means CKT_NSS_MUST_VERIFY_TRUST */
-#define CKT_NSS_UNTRUSTED CKT_NSS_MUST_VERIFY_TRUST
-/* CKT_NSS_VALID really means CKT_NSS_NOT_TRUSTED */
-#define CKT_NSS_VALID CKT_NSS_NOT_TRUSTED
-/* CKT_NSS_MUST_VERIFY was always treated as CKT_NSS_TRUST_UNKNOWN */
-#define CKT_NSS_MUST_VERIFY (CKT_NSS + 4) /*really means trust unknown*/
-#endif
-
-/* don't leave old programs in a lurch just yet, give them the old NETSCAPE
- * synonym */
-#define CKO_NETSCAPE_CRL CKO_NSS_CRL
-#define CKO_NETSCAPE_SMIME CKO_NSS_SMIME
-#define CKO_NETSCAPE_TRUST CKO_NSS_TRUST
-#define CKO_NETSCAPE_BUILTIN_ROOT_LIST CKO_NSS_BUILTIN_ROOT_LIST
-#define CKO_NETSCAPE_NEWSLOT CKO_NSS_NEWSLOT
-#define CKO_NETSCAPE_DELSLOT CKO_NSS_DELSLOT
-#define CKK_NETSCAPE_PKCS8 CKK_NSS_PKCS8
-#define CKA_NETSCAPE_URL CKA_NSS_URL
-#define CKA_NETSCAPE_EMAIL CKA_NSS_EMAIL
-#define CKA_NETSCAPE_SMIME_INFO CKA_NSS_SMIME_INFO
-#define CKA_NETSCAPE_SMIME_TIMESTAMP CKA_NSS_SMIME_TIMESTAMP
-#define CKA_NETSCAPE_PKCS8_SALT CKA_NSS_PKCS8_SALT
-#define CKA_NETSCAPE_PASSWORD_CHECK CKA_NSS_PASSWORD_CHECK
-#define CKA_NETSCAPE_EXPIRES CKA_NSS_EXPIRES
-#define CKA_NETSCAPE_KRL CKA_NSS_KRL
-#define CKA_NETSCAPE_PQG_COUNTER CKA_NSS_PQG_COUNTER
-#define CKA_NETSCAPE_PQG_SEED CKA_NSS_PQG_SEED
-#define CKA_NETSCAPE_PQG_H CKA_NSS_PQG_H
-#define CKA_NETSCAPE_PQG_SEED_BITS CKA_NSS_PQG_SEED_BITS
-#define CKA_NETSCAPE_MODULE_SPEC CKA_NSS_MODULE_SPEC
-#define CKM_NETSCAPE_AES_KEY_WRAP CKM_NSS_AES_KEY_WRAP
-#define CKM_NETSCAPE_AES_KEY_WRAP_PAD CKM_NSS_AES_KEY_WRAP_PAD
-#define CKR_NETSCAPE_CERTDB_FAILED CKR_NSS_CERTDB_FAILED
-#define CKR_NETSCAPE_KEYDB_FAILED CKR_NSS_KEYDB_FAILED
-
-#define CKT_NETSCAPE_TRUSTED CKT_NSS_TRUSTED
-#define CKT_NETSCAPE_TRUSTED_DELEGATOR CKT_NSS_TRUSTED_DELEGATOR
-#define CKT_NETSCAPE_UNTRUSTED CKT_NSS_UNTRUSTED
-#define CKT_NETSCAPE_MUST_VERIFY CKT_NSS_MUST_VERIFY
-#define CKT_NETSCAPE_TRUST_UNKNOWN CKT_NSS_TRUST_UNKNOWN
-#define CKT_NETSCAPE_VALID CKT_NSS_VALID
-#define CKT_NETSCAPE_VALID_DELEGATOR CKT_NSS_VALID_DELEGATOR
-
-/*
- * These are not really PKCS #11 values specifically. They are the 'loadable'
- * module spec NSS uses. The are available for others to use as well, but not
- * part of the formal PKCS #11 spec.
- *
- * The function 'FIND' returns an array of PKCS #11 initialization strings
- * The function 'ADD' takes a PKCS #11 initialization string and stores it.
- * The function 'DEL' takes a 'name= library=' value and deletes the associated
- * string.
- * The function 'RELEASE' frees the array returned by 'FIND'
- */
-#define SECMOD_MODULE_DB_FUNCTION_FIND 0
-#define SECMOD_MODULE_DB_FUNCTION_ADD 1
-#define SECMOD_MODULE_DB_FUNCTION_DEL 2
-#define SECMOD_MODULE_DB_FUNCTION_RELEASE 3
-typedef char ** (PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
- char *parameters, void *moduleSpec);
-
-/* softoken slot ID's */
-#define SFTK_MIN_USER_SLOT_ID 4
-#define SFTK_MAX_USER_SLOT_ID 100
-#define SFTK_MIN_FIPS_USER_SLOT_ID 101
-#define SFTK_MAX_FIPS_USER_SLOT_ID 127
-
-
-#endif /* _PKCS11N_H_ */
diff --git a/security/nss/lib/util/pkcs11p.h b/security/nss/lib/util/pkcs11p.h
deleted file mode 100644
index 744c82034..000000000
--- a/security/nss/lib/util/pkcs11p.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security Inc. Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- */
-/* these data types are platform/implementation dependent. */
-/*
- * Packing was removed from the shipped RSA header files, even
- * though it's still needed. put in a central file to help merging..
- */
-
-#if defined(_WIN32)
-#ifdef _MSC_VER
-#pragma warning(disable:4103)
-#endif
-#pragma pack(push, cryptoki, 1)
-#endif
-
diff --git a/security/nss/lib/util/pkcs11t.h b/security/nss/lib/util/pkcs11t.h
deleted file mode 100644
index b00346162..000000000
--- a/security/nss/lib/util/pkcs11t.h
+++ /dev/null
@@ -1,1793 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-
-#ifndef _PKCS11T_H_
-#define _PKCS11T_H_ 1
-
-#define CK_TRUE 1
-#define CK_FALSE 0
-
-#include "prtypes.h"
-
-#define CK_PTR *
-#define CK_NULL_PTR 0
-#define CK_CALLBACK_FUNCTION(rtype,func) rtype (PR_CALLBACK * func)
-#define CK_DECLARE_FUNCTION(rtype,func) extern rtype func
-#define CK_DECLARE_FUNCTION_POINTER(rtype,func) rtype (PR_CALLBACK * func)
-
-#define CK_INVALID_SESSION 0
-
-/* an unsigned 8-bit value */
-typedef unsigned char CK_BYTE;
-
-/* an unsigned 8-bit character */
-typedef CK_BYTE CK_CHAR;
-
-/* an 8-bit UTF-8 character */
-typedef CK_BYTE CK_UTF8CHAR;
-
-/* a BYTE-sized Boolean flag */
-typedef CK_BYTE CK_BBOOL;
-
-/* an unsigned value, at least 32 bits long */
-typedef unsigned long int CK_ULONG;
-
-/* a signed value, the same size as a CK_ULONG */
-/* CK_LONG is new for v2.0 */
-typedef long int CK_LONG;
-
-/* at least 32 bits; each bit is a Boolean flag */
-typedef CK_ULONG CK_FLAGS;
-
-
-/* some special values for certain CK_ULONG variables */
-#define CK_UNAVAILABLE_INFORMATION (~0UL)
-#define CK_EFFECTIVELY_INFINITE 0
-
-
-typedef CK_BYTE CK_PTR CK_BYTE_PTR;
-typedef CK_CHAR CK_PTR CK_CHAR_PTR;
-typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
-typedef CK_ULONG CK_PTR CK_ULONG_PTR;
-typedef void CK_PTR CK_VOID_PTR;
-
-/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
-typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
-
-
-/* The following value is always invalid if used as a session */
-/* handle or object handle */
-#define CK_INVALID_HANDLE 0
-
-
-/* pack */
-#include "pkcs11p.h"
-
-typedef struct CK_VERSION {
- CK_BYTE major; /* integer portion of version number */
- CK_BYTE minor; /* 1/100ths portion of version number */
-} CK_VERSION;
-
-typedef CK_VERSION CK_PTR CK_VERSION_PTR;
-
-
-typedef struct CK_INFO {
- /* manufacturerID and libraryDecription have been changed from
- * CK_CHAR to CK_UTF8CHAR for v2.10 */
- CK_VERSION cryptokiVersion; /* PKCS #11 interface ver */
- CK_UTF8CHAR manufacturerID[32]; /* blank padded */
- CK_FLAGS flags; /* must be zero */
-
- /* libraryDescription and libraryVersion are new for v2.0 */
- CK_UTF8CHAR libraryDescription[32]; /* blank padded */
- CK_VERSION libraryVersion; /* version of library */
-} CK_INFO;
-
-typedef CK_INFO CK_PTR CK_INFO_PTR;
-
-
-/* CK_NOTIFICATION enumerates the types of notifications that
- * PKCS #11 provides to an application */
-/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_NOTIFICATION;
-#define CKN_SURRENDER 0
-
-
-typedef CK_ULONG CK_SLOT_ID;
-
-typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
-
-
-/* CK_SLOT_INFO provides information about a slot */
-typedef struct CK_SLOT_INFO {
- /* slotDescription and manufacturerID have been changed from
- * CK_CHAR to CK_UTF8CHAR for v2.10 */
- CK_UTF8CHAR slotDescription[64]; /* blank padded */
- CK_UTF8CHAR manufacturerID[32]; /* blank padded */
- CK_FLAGS flags;
-
- /* hardwareVersion and firmwareVersion are new for v2.0 */
- CK_VERSION hardwareVersion; /* version of hardware */
- CK_VERSION firmwareVersion; /* version of firmware */
-} CK_SLOT_INFO;
-
-/* flags: bit flags that provide capabilities of the slot
- * Bit Flag Mask Meaning
- */
-#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
-#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
-#define CKF_HW_SLOT 0x00000004 /* hardware slot */
-
-typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
-
-
-/* CK_TOKEN_INFO provides information about a token */
-typedef struct CK_TOKEN_INFO {
- /* label, manufacturerID, and model have been changed from
- * CK_CHAR to CK_UTF8CHAR for v2.10 */
- CK_UTF8CHAR label[32]; /* blank padded */
- CK_UTF8CHAR manufacturerID[32]; /* blank padded */
- CK_UTF8CHAR model[16]; /* blank padded */
- CK_CHAR serialNumber[16]; /* blank padded */
- CK_FLAGS flags; /* see below */
-
- /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
- * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
- * changed from CK_USHORT to CK_ULONG for v2.0 */
- CK_ULONG ulMaxSessionCount; /* max open sessions */
- CK_ULONG ulSessionCount; /* sess. now open */
- CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
- CK_ULONG ulRwSessionCount; /* R/W sess. now open */
- CK_ULONG ulMaxPinLen; /* in bytes */
- CK_ULONG ulMinPinLen; /* in bytes */
- CK_ULONG ulTotalPublicMemory; /* in bytes */
- CK_ULONG ulFreePublicMemory; /* in bytes */
- CK_ULONG ulTotalPrivateMemory; /* in bytes */
- CK_ULONG ulFreePrivateMemory; /* in bytes */
-
- /* hardwareVersion, firmwareVersion, and time are new for
- * v2.0 */
- CK_VERSION hardwareVersion; /* version of hardware */
- CK_VERSION firmwareVersion; /* version of firmware */
- CK_CHAR utcTime[16]; /* time */
-} CK_TOKEN_INFO;
-
-/* The flags parameter is defined as follows:
- * Bit Flag Mask Meaning
- */
-#define CKF_RNG 0x00000001 /* has random #
- * generator */
-#define CKF_WRITE_PROTECTED 0x00000002 /* token is
- * write-
- * protected */
-#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
- * login */
-#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
- * PIN is set */
-
-/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
- * that means that *every* time the state of cryptographic
- * operations of a session is successfully saved, all keys
- * needed to continue those operations are stored in the state */
-#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
-
-/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
- * that the token has some sort of clock. The time on that
- * clock is returned in the token info structure */
-#define CKF_CLOCK_ON_TOKEN 0x00000040
-
-/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
- * set, that means that there is some way for the user to login
- * without sending a PIN through the PKCS #11 library itself */
-#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
-
-/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
- * that means that a single session with the token can perform
- * dual simultaneous cryptographic operations (digest and
- * encrypt; decrypt and digest; sign and encrypt; and decrypt
- * and sign) */
-#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
-
-/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
- * token has been initialized using C_InitializeToken or an
- * equivalent mechanism outside the scope of PKCS #11.
- * Calling C_InitializeToken when this flag is set will cause
- * the token to be reinitialized. */
-#define CKF_TOKEN_INITIALIZED 0x00000400
-
-/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
- * true, the token supports secondary authentication for
- * private key objects. This flag is deprecated in v2.11 and
- onwards. */
-#define CKF_SECONDARY_AUTHENTICATION 0x00000800
-
-/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect user login PIN has been entered at least once
- * since the last successful authentication. */
-#define CKF_USER_PIN_COUNT_LOW 0x00010000
-
-/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect user PIN will it to become locked. */
-#define CKF_USER_PIN_FINAL_TRY 0x00020000
-
-/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
- * user PIN has been locked. User login to the token is not
- * possible. */
-#define CKF_USER_PIN_LOCKED 0x00040000
-
-/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the user PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
-
-/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect SO login PIN has been entered at least once since
- * the last successful authentication. */
-#define CKF_SO_PIN_COUNT_LOW 0x00100000
-
-/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect SO PIN will it to become locked. */
-#define CKF_SO_PIN_FINAL_TRY 0x00200000
-
-/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
- * PIN has been locked. SO login to the token is not possible.
- */
-#define CKF_SO_PIN_LOCKED 0x00400000
-
-/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the SO PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
-
-typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
-
-
-/* CK_SESSION_HANDLE is a PKCS #11-assigned value that
- * identifies a session */
-typedef CK_ULONG CK_SESSION_HANDLE;
-
-typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
-
-
-/* CK_USER_TYPE enumerates the types of PKCS #11 users */
-/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_USER_TYPE;
-/* Security Officer */
-#define CKU_SO 0
-/* Normal user */
-#define CKU_USER 1
-/* Context specific (added in v2.20) */
-#define CKU_CONTEXT_SPECIFIC 2
-
-/* CK_STATE enumerates the session states */
-/* CK_STATE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_STATE;
-#define CKS_RO_PUBLIC_SESSION 0
-#define CKS_RO_USER_FUNCTIONS 1
-#define CKS_RW_PUBLIC_SESSION 2
-#define CKS_RW_USER_FUNCTIONS 3
-#define CKS_RW_SO_FUNCTIONS 4
-
-
-/* CK_SESSION_INFO provides information about a session */
-typedef struct CK_SESSION_INFO {
- CK_SLOT_ID slotID;
- CK_STATE state;
- CK_FLAGS flags; /* see below */
-
- /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulDeviceError; /* device-dependent error code */
-} CK_SESSION_INFO;
-
-/* The flags are defined in the following table:
- * Bit Flag Mask Meaning
- */
-#define CKF_RW_SESSION 0x00000002 /* session is r/w */
-#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
-
-typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
-
-
-/* CK_OBJECT_HANDLE is a token-specific identifier for an
- * object */
-typedef CK_ULONG CK_OBJECT_HANDLE;
-
-typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
-
-
-/* CK_OBJECT_CLASS is a value that identifies the classes (or
- * types) of objects that PKCS #11 recognizes. It is defined
- * as follows: */
-/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_OBJECT_CLASS;
-
-/* The following classes of objects are defined: */
-/* CKO_HW_FEATURE is new for v2.10 */
-/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
-/* CKO_MECHANISM is new for v2.20 */
-#define CKO_DATA 0x00000000
-#define CKO_CERTIFICATE 0x00000001
-#define CKO_PUBLIC_KEY 0x00000002
-#define CKO_PRIVATE_KEY 0x00000003
-#define CKO_SECRET_KEY 0x00000004
-#define CKO_HW_FEATURE 0x00000005
-#define CKO_DOMAIN_PARAMETERS 0x00000006
-#define CKO_MECHANISM 0x00000007
-#define CKO_VENDOR_DEFINED 0x80000000
-
-typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
-
-/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
- * value that identifies the hardware feature type of an object
- * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
-typedef CK_ULONG CK_HW_FEATURE_TYPE;
-
-/* The following hardware feature types are defined */
-/* CKH_USER_INTERFACE is new for v2.20 */
-#define CKH_MONOTONIC_COUNTER 0x00000001
-#define CKH_CLOCK 0x00000002
-#define CKH_USER_INTERFACE 0x00000003
-#define CKH_VENDOR_DEFINED 0x80000000
-
-/* CK_KEY_TYPE is a value that identifies a key type */
-/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG CK_KEY_TYPE;
-
-/* the following key types are defined: */
-#define CKK_RSA 0x00000000
-#define CKK_DSA 0x00000001
-#define CKK_DH 0x00000002
-
-/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
-#define CKK_ECDSA 0x00000003
-#define CKK_EC 0x00000003
-#define CKK_X9_42_DH 0x00000004
-#define CKK_KEA 0x00000005
-
-#define CKK_GENERIC_SECRET 0x00000010
-#define CKK_RC2 0x00000011
-#define CKK_RC4 0x00000012
-#define CKK_DES 0x00000013
-#define CKK_DES2 0x00000014
-#define CKK_DES3 0x00000015
-
-/* all these key types are new for v2.0 */
-#define CKK_CAST 0x00000016
-#define CKK_CAST3 0x00000017
-/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
-#define CKK_CAST5 0x00000018
-#define CKK_CAST128 0x00000018
-#define CKK_RC5 0x00000019
-#define CKK_IDEA 0x0000001A
-#define CKK_SKIPJACK 0x0000001B
-#define CKK_BATON 0x0000001C
-#define CKK_JUNIPER 0x0000001D
-#define CKK_CDMF 0x0000001E
-#define CKK_AES 0x0000001F
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKK_BLOWFISH 0x00000020
-#define CKK_TWOFISH 0x00000021
-
-/* Camellia is proposed for v2.20 Amendment 3 */
-#define CKK_CAMELLIA 0x00000025
-
-#define CKK_SEED 0x00000026
-
-#define CKK_VENDOR_DEFINED 0x80000000
-
-
-/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
- * type */
-/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_CERTIFICATE_TYPE;
-
-/* The following certificate types are defined: */
-/* CKC_X_509_ATTR_CERT is new for v2.10 */
-/* CKC_WTLS is new for v2.20 */
-#define CKC_X_509 0x00000000
-#define CKC_X_509_ATTR_CERT 0x00000001
-#define CKC_WTLS 0x00000002
-#define CKC_VENDOR_DEFINED 0x80000000
-
-
-/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
- * type */
-/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_ATTRIBUTE_TYPE;
-
-/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
- consists of an array of values. */
-#define CKF_ARRAY_ATTRIBUTE 0x40000000
-
-/* The following attribute types are defined: */
-#define CKA_CLASS 0x00000000
-#define CKA_TOKEN 0x00000001
-#define CKA_PRIVATE 0x00000002
-#define CKA_LABEL 0x00000003
-#define CKA_APPLICATION 0x00000010
-#define CKA_VALUE 0x00000011
-
-/* CKA_OBJECT_ID is new for v2.10 */
-#define CKA_OBJECT_ID 0x00000012
-
-#define CKA_CERTIFICATE_TYPE 0x00000080
-#define CKA_ISSUER 0x00000081
-#define CKA_SERIAL_NUMBER 0x00000082
-
-/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
- * for v2.10 */
-#define CKA_AC_ISSUER 0x00000083
-#define CKA_OWNER 0x00000084
-#define CKA_ATTR_TYPES 0x00000085
-
-/* CKA_TRUSTED is new for v2.11 */
-#define CKA_TRUSTED 0x00000086
-
-/* CKA_CERTIFICATE_CATEGORY ...
- * CKA_CHECK_VALUE are new for v2.20 */
-#define CKA_CERTIFICATE_CATEGORY 0x00000087
-#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088
-#define CKA_URL 0x00000089
-#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A
-#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B
-#define CKA_CHECK_VALUE 0x00000090
-
-#define CKA_KEY_TYPE 0x00000100
-#define CKA_SUBJECT 0x00000101
-#define CKA_ID 0x00000102
-#define CKA_SENSITIVE 0x00000103
-#define CKA_ENCRYPT 0x00000104
-#define CKA_DECRYPT 0x00000105
-#define CKA_WRAP 0x00000106
-#define CKA_UNWRAP 0x00000107
-#define CKA_SIGN 0x00000108
-#define CKA_SIGN_RECOVER 0x00000109
-#define CKA_VERIFY 0x0000010A
-#define CKA_VERIFY_RECOVER 0x0000010B
-#define CKA_DERIVE 0x0000010C
-#define CKA_START_DATE 0x00000110
-#define CKA_END_DATE 0x00000111
-#define CKA_MODULUS 0x00000120
-#define CKA_MODULUS_BITS 0x00000121
-#define CKA_PUBLIC_EXPONENT 0x00000122
-#define CKA_PRIVATE_EXPONENT 0x00000123
-#define CKA_PRIME_1 0x00000124
-#define CKA_PRIME_2 0x00000125
-#define CKA_EXPONENT_1 0x00000126
-#define CKA_EXPONENT_2 0x00000127
-#define CKA_COEFFICIENT 0x00000128
-#define CKA_PRIME 0x00000130
-#define CKA_SUBPRIME 0x00000131
-#define CKA_BASE 0x00000132
-
-/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
-#define CKA_PRIME_BITS 0x00000133
-#define CKA_SUBPRIME_BITS 0x00000134
-#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
-/* (To retain backwards-compatibility) */
-
-#define CKA_VALUE_BITS 0x00000160
-#define CKA_VALUE_LEN 0x00000161
-
-/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
- * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
- * and CKA_EC_POINT are new for v2.0 */
-#define CKA_EXTRACTABLE 0x00000162
-#define CKA_LOCAL 0x00000163
-#define CKA_NEVER_EXTRACTABLE 0x00000164
-#define CKA_ALWAYS_SENSITIVE 0x00000165
-
-/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
-#define CKA_KEY_GEN_MECHANISM 0x00000166
-
-#define CKA_MODIFIABLE 0x00000170
-
-/* CKA_ECDSA_PARAMS is deprecated in v2.11,
- * CKA_EC_PARAMS is preferred. */
-#define CKA_ECDSA_PARAMS 0x00000180
-#define CKA_EC_PARAMS 0x00000180
-
-#define CKA_EC_POINT 0x00000181
-
-/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
- * are new for v2.10. Deprecated in v2.11 and onwards. */
-#define CKA_SECONDARY_AUTH 0x00000200
-#define CKA_AUTH_PIN_FLAGS 0x00000201
-
-/* CKA_ALWAYS_AUTHENTICATE ...
- * CKA_UNWRAP_TEMPLATE are new for v2.20 */
-#define CKA_ALWAYS_AUTHENTICATE 0x00000202
-
-#define CKA_WRAP_WITH_TRUSTED 0x00000210
-#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211)
-#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212)
-
-/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
- * are new for v2.10 */
-#define CKA_HW_FEATURE_TYPE 0x00000300
-#define CKA_RESET_ON_INIT 0x00000301
-#define CKA_HAS_RESET 0x00000302
-
-/* The following attributes are new for v2.20 */
-#define CKA_PIXEL_X 0x00000400
-#define CKA_PIXEL_Y 0x00000401
-#define CKA_RESOLUTION 0x00000402
-#define CKA_CHAR_ROWS 0x00000403
-#define CKA_CHAR_COLUMNS 0x00000404
-#define CKA_COLOR 0x00000405
-#define CKA_BITS_PER_PIXEL 0x00000406
-#define CKA_CHAR_SETS 0x00000480
-#define CKA_ENCODING_METHODS 0x00000481
-#define CKA_MIME_TYPES 0x00000482
-#define CKA_MECHANISM_TYPE 0x00000500
-#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501
-#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502
-#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503
-#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600)
-
-#define CKA_VENDOR_DEFINED 0x80000000
-
-
-/* CK_ATTRIBUTE is a structure that includes the type, length
- * and value of an attribute */
-typedef struct CK_ATTRIBUTE {
- CK_ATTRIBUTE_TYPE type;
- CK_VOID_PTR pValue;
-
- /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
- CK_ULONG ulValueLen; /* in bytes */
-} CK_ATTRIBUTE;
-
-typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
-
-
-/* CK_DATE is a structure that defines a date */
-typedef struct CK_DATE{
- CK_CHAR year[4]; /* the year ("1900" - "9999") */
- CK_CHAR month[2]; /* the month ("01" - "12") */
- CK_CHAR day[2]; /* the day ("01" - "31") */
-} CK_DATE;
-
-
-/* CK_MECHANISM_TYPE is a value that identifies a mechanism
- * type */
-/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG CK_MECHANISM_TYPE;
-
-/* the following mechanism types are defined: */
-#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
-#define CKM_RSA_PKCS 0x00000001
-#define CKM_RSA_9796 0x00000002
-#define CKM_RSA_X_509 0x00000003
-
-/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
- * are new for v2.0. They are mechanisms which hash and sign */
-#define CKM_MD2_RSA_PKCS 0x00000004
-#define CKM_MD5_RSA_PKCS 0x00000005
-#define CKM_SHA1_RSA_PKCS 0x00000006
-
-/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
- * CKM_RSA_PKCS_OAEP are new for v2.10 */
-#define CKM_RIPEMD128_RSA_PKCS 0x00000007
-#define CKM_RIPEMD160_RSA_PKCS 0x00000008
-#define CKM_RSA_PKCS_OAEP 0x00000009
-
-/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
- * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
-#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
-#define CKM_RSA_X9_31 0x0000000B
-#define CKM_SHA1_RSA_X9_31 0x0000000C
-#define CKM_RSA_PKCS_PSS 0x0000000D
-#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
-
-#define CKM_DSA_KEY_PAIR_GEN 0x00000010
-#define CKM_DSA 0x00000011
-#define CKM_DSA_SHA1 0x00000012
-#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
-#define CKM_DH_PKCS_DERIVE 0x00000021
-
-/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
- * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
- * v2.11 */
-#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
-#define CKM_X9_42_DH_DERIVE 0x00000031
-#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
-#define CKM_X9_42_MQV_DERIVE 0x00000033
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_RSA_PKCS 0x00000040
-#define CKM_SHA384_RSA_PKCS 0x00000041
-#define CKM_SHA512_RSA_PKCS 0x00000042
-#define CKM_SHA256_RSA_PKCS_PSS 0x00000043
-#define CKM_SHA384_RSA_PKCS_PSS 0x00000044
-#define CKM_SHA512_RSA_PKCS_PSS 0x00000045
-
-/* CKM_SHA224 new for v2.20 amendment 3 */
-#define CKM_SHA224_RSA_PKCS 0x00000046
-#define CKM_SHA224_RSA_PKCS_PSS 0x00000047
-
-#define CKM_RC2_KEY_GEN 0x00000100
-#define CKM_RC2_ECB 0x00000101
-#define CKM_RC2_CBC 0x00000102
-#define CKM_RC2_MAC 0x00000103
-
-/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
-#define CKM_RC2_MAC_GENERAL 0x00000104
-#define CKM_RC2_CBC_PAD 0x00000105
-
-#define CKM_RC4_KEY_GEN 0x00000110
-#define CKM_RC4 0x00000111
-#define CKM_DES_KEY_GEN 0x00000120
-#define CKM_DES_ECB 0x00000121
-#define CKM_DES_CBC 0x00000122
-#define CKM_DES_MAC 0x00000123
-
-/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
-#define CKM_DES_MAC_GENERAL 0x00000124
-#define CKM_DES_CBC_PAD 0x00000125
-
-#define CKM_DES2_KEY_GEN 0x00000130
-#define CKM_DES3_KEY_GEN 0x00000131
-#define CKM_DES3_ECB 0x00000132
-#define CKM_DES3_CBC 0x00000133
-#define CKM_DES3_MAC 0x00000134
-
-/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
- * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
- * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
-#define CKM_DES3_MAC_GENERAL 0x00000135
-#define CKM_DES3_CBC_PAD 0x00000136
-#define CKM_CDMF_KEY_GEN 0x00000140
-#define CKM_CDMF_ECB 0x00000141
-#define CKM_CDMF_CBC 0x00000142
-#define CKM_CDMF_MAC 0x00000143
-#define CKM_CDMF_MAC_GENERAL 0x00000144
-#define CKM_CDMF_CBC_PAD 0x00000145
-
-/* the following four DES mechanisms are new for v2.20 */
-#define CKM_DES_OFB64 0x00000150
-#define CKM_DES_OFB8 0x00000151
-#define CKM_DES_CFB64 0x00000152
-#define CKM_DES_CFB8 0x00000153
-
-#define CKM_MD2 0x00000200
-
-/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD2_HMAC 0x00000201
-#define CKM_MD2_HMAC_GENERAL 0x00000202
-
-#define CKM_MD5 0x00000210
-
-/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD5_HMAC 0x00000211
-#define CKM_MD5_HMAC_GENERAL 0x00000212
-
-#define CKM_SHA_1 0x00000220
-
-/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
-#define CKM_SHA_1_HMAC 0x00000221
-#define CKM_SHA_1_HMAC_GENERAL 0x00000222
-
-/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
- * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
- * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
-#define CKM_RIPEMD128 0x00000230
-#define CKM_RIPEMD128_HMAC 0x00000231
-#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
-#define CKM_RIPEMD160 0x00000240
-#define CKM_RIPEMD160_HMAC 0x00000241
-#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256 0x00000250
-#define CKM_SHA256_HMAC 0x00000251
-#define CKM_SHA256_HMAC_GENERAL 0x00000252
-#define CKM_SHA384 0x00000260
-#define CKM_SHA384_HMAC 0x00000261
-#define CKM_SHA384_HMAC_GENERAL 0x00000262
-#define CKM_SHA512 0x00000270
-#define CKM_SHA512_HMAC 0x00000271
-#define CKM_SHA512_HMAC_GENERAL 0x00000272
-
-/* CKM_SHA224 new for v2.20 amendment 3 */
-#define CKM_SHA224 0x00000255
-#define CKM_SHA224_HMAC 0x00000256
-#define CKM_SHA224_HMAC_GENERAL 0x00000257
-
-/* All of the following mechanisms are new for v2.0 */
-/* Note that CAST128 and CAST5 are the same algorithm */
-#define CKM_CAST_KEY_GEN 0x00000300
-#define CKM_CAST_ECB 0x00000301
-#define CKM_CAST_CBC 0x00000302
-#define CKM_CAST_MAC 0x00000303
-#define CKM_CAST_MAC_GENERAL 0x00000304
-#define CKM_CAST_CBC_PAD 0x00000305
-#define CKM_CAST3_KEY_GEN 0x00000310
-#define CKM_CAST3_ECB 0x00000311
-#define CKM_CAST3_CBC 0x00000312
-#define CKM_CAST3_MAC 0x00000313
-#define CKM_CAST3_MAC_GENERAL 0x00000314
-#define CKM_CAST3_CBC_PAD 0x00000315
-#define CKM_CAST5_KEY_GEN 0x00000320
-#define CKM_CAST128_KEY_GEN 0x00000320
-#define CKM_CAST5_ECB 0x00000321
-#define CKM_CAST128_ECB 0x00000321
-#define CKM_CAST5_CBC 0x00000322
-#define CKM_CAST128_CBC 0x00000322
-#define CKM_CAST5_MAC 0x00000323
-#define CKM_CAST128_MAC 0x00000323
-#define CKM_CAST5_MAC_GENERAL 0x00000324
-#define CKM_CAST128_MAC_GENERAL 0x00000324
-#define CKM_CAST5_CBC_PAD 0x00000325
-#define CKM_CAST128_CBC_PAD 0x00000325
-#define CKM_RC5_KEY_GEN 0x00000330
-#define CKM_RC5_ECB 0x00000331
-#define CKM_RC5_CBC 0x00000332
-#define CKM_RC5_MAC 0x00000333
-#define CKM_RC5_MAC_GENERAL 0x00000334
-#define CKM_RC5_CBC_PAD 0x00000335
-#define CKM_IDEA_KEY_GEN 0x00000340
-#define CKM_IDEA_ECB 0x00000341
-#define CKM_IDEA_CBC 0x00000342
-#define CKM_IDEA_MAC 0x00000343
-#define CKM_IDEA_MAC_GENERAL 0x00000344
-#define CKM_IDEA_CBC_PAD 0x00000345
-#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
-#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
-#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
-#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
-#define CKM_XOR_BASE_AND_DATA 0x00000364
-#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
-#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
-#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
-#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
-
-/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
- * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
- * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
-#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
-#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
-#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
-#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
-#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
-
-/* CKM_TLS_PRF is new for v2.20 */
-#define CKM_TLS_PRF 0x00000378
-
-#define CKM_SSL3_MD5_MAC 0x00000380
-#define CKM_SSL3_SHA1_MAC 0x00000381
-#define CKM_MD5_KEY_DERIVATION 0x00000390
-#define CKM_MD2_KEY_DERIVATION 0x00000391
-#define CKM_SHA1_KEY_DERIVATION 0x00000392
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_KEY_DERIVATION 0x00000393
-#define CKM_SHA384_KEY_DERIVATION 0x00000394
-#define CKM_SHA512_KEY_DERIVATION 0x00000395
-
-/* CKM_SHA224 new for v2.20 amendment 3 */
-#define CKM_SHA224_KEY_DERIVATION 0x00000396
-
-#define CKM_PBE_MD2_DES_CBC 0x000003A0
-#define CKM_PBE_MD5_DES_CBC 0x000003A1
-#define CKM_PBE_MD5_CAST_CBC 0x000003A2
-#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
-#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
-#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
-#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
-#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
-#define CKM_PBE_SHA1_RC4_128 0x000003A6
-#define CKM_PBE_SHA1_RC4_40 0x000003A7
-#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
-#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
-#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
-#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
-
-/* CKM_PKCS5_PBKD2 is new for v2.10 */
-#define CKM_PKCS5_PBKD2 0x000003B0
-
-#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
-
-/* WTLS mechanisms are new for v2.20 */
-#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0
-#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1
-#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2
-#define CKM_WTLS_PRF 0x000003D3
-#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4
-#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5
-
-#define CKM_KEY_WRAP_LYNKS 0x00000400
-#define CKM_KEY_WRAP_SET_OAEP 0x00000401
-
-/* CKM_CMS_SIG is new for v2.20 */
-#define CKM_CMS_SIG 0x00000500
-
-/* Fortezza mechanisms */
-#define CKM_SKIPJACK_KEY_GEN 0x00001000
-#define CKM_SKIPJACK_ECB64 0x00001001
-#define CKM_SKIPJACK_CBC64 0x00001002
-#define CKM_SKIPJACK_OFB64 0x00001003
-#define CKM_SKIPJACK_CFB64 0x00001004
-#define CKM_SKIPJACK_CFB32 0x00001005
-#define CKM_SKIPJACK_CFB16 0x00001006
-#define CKM_SKIPJACK_CFB8 0x00001007
-#define CKM_SKIPJACK_WRAP 0x00001008
-#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
-#define CKM_SKIPJACK_RELAYX 0x0000100a
-#define CKM_KEA_KEY_PAIR_GEN 0x00001010
-#define CKM_KEA_KEY_DERIVE 0x00001011
-#define CKM_FORTEZZA_TIMESTAMP 0x00001020
-#define CKM_BATON_KEY_GEN 0x00001030
-#define CKM_BATON_ECB128 0x00001031
-#define CKM_BATON_ECB96 0x00001032
-#define CKM_BATON_CBC128 0x00001033
-#define CKM_BATON_COUNTER 0x00001034
-#define CKM_BATON_SHUFFLE 0x00001035
-#define CKM_BATON_WRAP 0x00001036
-
-/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
- * CKM_EC_KEY_PAIR_GEN is preferred */
-#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
-#define CKM_EC_KEY_PAIR_GEN 0x00001040
-
-#define CKM_ECDSA 0x00001041
-#define CKM_ECDSA_SHA1 0x00001042
-
-/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
- * are new for v2.11 */
-#define CKM_ECDH1_DERIVE 0x00001050
-#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
-#define CKM_ECMQV_DERIVE 0x00001052
-
-#define CKM_JUNIPER_KEY_GEN 0x00001060
-#define CKM_JUNIPER_ECB128 0x00001061
-#define CKM_JUNIPER_CBC128 0x00001062
-#define CKM_JUNIPER_COUNTER 0x00001063
-#define CKM_JUNIPER_SHUFFLE 0x00001064
-#define CKM_JUNIPER_WRAP 0x00001065
-#define CKM_FASTHASH 0x00001070
-
-/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
- * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
- * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
- * new for v2.11 */
-#define CKM_AES_KEY_GEN 0x00001080
-#define CKM_AES_ECB 0x00001081
-#define CKM_AES_CBC 0x00001082
-#define CKM_AES_MAC 0x00001083
-#define CKM_AES_MAC_GENERAL 0x00001084
-#define CKM_AES_CBC_PAD 0x00001085
-/* new for v2.20 amendment 3 */
-#define CKM_AES_CTR 0x00001086
-/* new for v2.30 */
-#define CKM_AES_GCM 0x00001087
-#define CKM_AES_CCM 0x00001088
-#define CKM_AES_CTS 0x00001089
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKM_BLOWFISH_KEY_GEN 0x00001090
-#define CKM_BLOWFISH_CBC 0x00001091
-#define CKM_TWOFISH_KEY_GEN 0x00001092
-#define CKM_TWOFISH_CBC 0x00001093
-
-/* Camellia is proposed for v2.20 Amendment 3 */
-#define CKM_CAMELLIA_KEY_GEN 0x00000550
-#define CKM_CAMELLIA_ECB 0x00000551
-#define CKM_CAMELLIA_CBC 0x00000552
-#define CKM_CAMELLIA_MAC 0x00000553
-#define CKM_CAMELLIA_MAC_GENERAL 0x00000554
-#define CKM_CAMELLIA_CBC_PAD 0x00000555
-#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556
-#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557
-
-#define CKM_SEED_KEY_GEN 0x00000650
-#define CKM_SEED_ECB 0x00000651
-#define CKM_SEED_CBC 0x00000652
-#define CKM_SEED_MAC 0x00000653
-#define CKM_SEED_MAC_GENERAL 0x00000654
-#define CKM_SEED_CBC_PAD 0x00000655
-#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656
-#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657
-
-/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
-#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100
-#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101
-#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102
-#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103
-#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104
-#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105
-
-#define CKM_DSA_PARAMETER_GEN 0x00002000
-#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
-#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
-
-#define CKM_VENDOR_DEFINED 0x80000000
-
-typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
-
-
-/* CK_MECHANISM is a structure that specifies a particular
- * mechanism */
-typedef struct CK_MECHANISM {
- CK_MECHANISM_TYPE mechanism;
- CK_VOID_PTR pParameter;
-
- /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulParameterLen; /* in bytes */
-} CK_MECHANISM;
-
-typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
-
-
-/* CK_MECHANISM_INFO provides information about a particular
- * mechanism */
-typedef struct CK_MECHANISM_INFO {
- CK_ULONG ulMinKeySize;
- CK_ULONG ulMaxKeySize;
- CK_FLAGS flags;
-} CK_MECHANISM_INFO;
-
-/* The flags are defined as follows:
- * Bit Flag Mask Meaning */
-#define CKF_HW 0x00000001 /* performed by HW */
-
-/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
- * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
- * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
- * and CKF_DERIVE are new for v2.0. They specify whether or not
- * a mechanism can be used for a particular task */
-#define CKF_ENCRYPT 0x00000100
-#define CKF_DECRYPT 0x00000200
-#define CKF_DIGEST 0x00000400
-#define CKF_SIGN 0x00000800
-#define CKF_SIGN_RECOVER 0x00001000
-#define CKF_VERIFY 0x00002000
-#define CKF_VERIFY_RECOVER 0x00004000
-#define CKF_GENERATE 0x00008000
-#define CKF_GENERATE_KEY_PAIR 0x00010000
-#define CKF_WRAP 0x00020000
-#define CKF_UNWRAP 0x00040000
-#define CKF_DERIVE 0x00080000
-
-/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
- * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
- * describe a token's EC capabilities not available in mechanism
- * information. */
-#define CKF_EC_F_P 0x00100000
-#define CKF_EC_F_2M 0x00200000
-#define CKF_EC_ECPARAMETERS 0x00400000
-#define CKF_EC_NAMEDCURVE 0x00800000
-#define CKF_EC_UNCOMPRESS 0x01000000
-#define CKF_EC_COMPRESS 0x02000000
-
-#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
-
-typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
-
-
-/* CK_RV is a value that identifies the return value of a
- * PKCS #11 function */
-/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG CK_RV;
-
-#define CKR_OK 0x00000000
-#define CKR_CANCEL 0x00000001
-#define CKR_HOST_MEMORY 0x00000002
-#define CKR_SLOT_ID_INVALID 0x00000003
-
-/* CKR_FLAGS_INVALID was removed for v2.0 */
-
-/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
-#define CKR_GENERAL_ERROR 0x00000005
-#define CKR_FUNCTION_FAILED 0x00000006
-
-/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
- * and CKR_CANT_LOCK are new for v2.01 */
-#define CKR_ARGUMENTS_BAD 0x00000007
-#define CKR_NO_EVENT 0x00000008
-#define CKR_NEED_TO_CREATE_THREADS 0x00000009
-#define CKR_CANT_LOCK 0x0000000A
-
-#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
-#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
-#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
-#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
-#define CKR_DATA_INVALID 0x00000020
-#define CKR_DATA_LEN_RANGE 0x00000021
-#define CKR_DEVICE_ERROR 0x00000030
-#define CKR_DEVICE_MEMORY 0x00000031
-#define CKR_DEVICE_REMOVED 0x00000032
-#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
-#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
-#define CKR_FUNCTION_CANCELED 0x00000050
-#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
-
-/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
-#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
-
-#define CKR_KEY_HANDLE_INVALID 0x00000060
-
-/* CKR_KEY_SENSITIVE was removed for v2.0 */
-
-#define CKR_KEY_SIZE_RANGE 0x00000062
-#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
-
-/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
- * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
- * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
- * v2.0 */
-#define CKR_KEY_NOT_NEEDED 0x00000064
-#define CKR_KEY_CHANGED 0x00000065
-#define CKR_KEY_NEEDED 0x00000066
-#define CKR_KEY_INDIGESTIBLE 0x00000067
-#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
-#define CKR_KEY_NOT_WRAPPABLE 0x00000069
-#define CKR_KEY_UNEXTRACTABLE 0x0000006A
-
-#define CKR_MECHANISM_INVALID 0x00000070
-#define CKR_MECHANISM_PARAM_INVALID 0x00000071
-
-/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
- * were removed for v2.0 */
-#define CKR_OBJECT_HANDLE_INVALID 0x00000082
-#define CKR_OPERATION_ACTIVE 0x00000090
-#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
-#define CKR_PIN_INCORRECT 0x000000A0
-#define CKR_PIN_INVALID 0x000000A1
-#define CKR_PIN_LEN_RANGE 0x000000A2
-
-/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
-#define CKR_PIN_EXPIRED 0x000000A3
-#define CKR_PIN_LOCKED 0x000000A4
-
-#define CKR_SESSION_CLOSED 0x000000B0
-#define CKR_SESSION_COUNT 0x000000B1
-#define CKR_SESSION_HANDLE_INVALID 0x000000B3
-#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
-#define CKR_SESSION_READ_ONLY 0x000000B5
-#define CKR_SESSION_EXISTS 0x000000B6
-
-/* CKR_SESSION_READ_ONLY_EXISTS and
- * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
-#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
-#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
-
-#define CKR_SIGNATURE_INVALID 0x000000C0
-#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
-#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
-#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
-#define CKR_TOKEN_NOT_PRESENT 0x000000E0
-#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
-#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
-#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
-#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
-#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
-#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
-#define CKR_USER_NOT_LOGGED_IN 0x00000101
-#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
-#define CKR_USER_TYPE_INVALID 0x00000103
-
-/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
- * are new to v2.01 */
-#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
-#define CKR_USER_TOO_MANY_TYPES 0x00000105
-
-#define CKR_WRAPPED_KEY_INVALID 0x00000110
-#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
-#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
-#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
-#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
-#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
-
-/* These are new to v2.0 */
-#define CKR_RANDOM_NO_RNG 0x00000121
-
-/* These are new to v2.11 */
-#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
-
-/* These are new to v2.0 */
-#define CKR_BUFFER_TOO_SMALL 0x00000150
-#define CKR_SAVED_STATE_INVALID 0x00000160
-#define CKR_INFORMATION_SENSITIVE 0x00000170
-#define CKR_STATE_UNSAVEABLE 0x00000180
-
-/* These are new to v2.01 */
-#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
-#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
-#define CKR_MUTEX_BAD 0x000001A0
-#define CKR_MUTEX_NOT_LOCKED 0x000001A1
-
-/* This is new to v2.20 */
-#define CKR_FUNCTION_REJECTED 0x00000200
-
-#define CKR_VENDOR_DEFINED 0x80000000
-
-
-/* CK_NOTIFY is an application callback that processes events */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
- CK_SESSION_HANDLE hSession, /* the session's handle */
- CK_NOTIFICATION event,
- CK_VOID_PTR pApplication /* passed to C_OpenSession */
-);
-
-
-/* CK_FUNCTION_LIST is a structure holding a PKCS #11 spec
- * version and pointers of appropriate types to all the
- * PKCS #11 functions */
-/* CK_FUNCTION_LIST is new for v2.0 */
-typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
-
-typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
-
-typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
-
-
-/* CK_CREATEMUTEX is an application callback for creating a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
- CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
-);
-
-
-/* CK_DESTROYMUTEX is an application callback for destroying a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_LOCKMUTEX is an application callback for locking a mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_UNLOCKMUTEX is an application callback for unlocking a
- * mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
- CK_VOID_PTR pMutex /* pointer to mutex */
-);
-
-
-/* CK_C_INITIALIZE_ARGS provides the optional arguments to
- * C_Initialize */
-typedef struct CK_C_INITIALIZE_ARGS {
- CK_CREATEMUTEX CreateMutex;
- CK_DESTROYMUTEX DestroyMutex;
- CK_LOCKMUTEX LockMutex;
- CK_UNLOCKMUTEX UnlockMutex;
- CK_FLAGS flags;
- /* The official PKCS #11 spec does not have a 'LibraryParameters' field, but
- * a reserved field. NSS needs a way to pass instance-specific information
- * to the library (like where to find its config files, etc). This
- * information is usually provided by the installer and passed uninterpreted
- * by NSS to the library, though NSS does know the specifics of the softoken
- * version of this parameter. Most compliant PKCS#11 modules expect this
- * parameter to be NULL, and will return CKR_ARGUMENTS_BAD from
- * C_Initialize if Library parameters is supplied. */
- CK_CHAR_PTR *LibraryParameters;
- /* This field is only present if the LibraryParameters is not NULL. It must
- * be NULL in all cases */
- CK_VOID_PTR pReserved;
-} CK_C_INITIALIZE_ARGS;
-
-/* flags: bit flags that provide capabilities of the slot
- * Bit Flag Mask Meaning
- */
-#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
-#define CKF_OS_LOCKING_OK 0x00000002
-
-typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
-
-
-/* additional flags for parameters to functions */
-
-/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
-#define CKF_DONT_BLOCK 1
-
-/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
- * Generation Function (MGF) applied to a message block when
- * formatting a message block for the PKCS #1 OAEP encryption
- * scheme. */
-typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
-
-typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
-
-/* The following MGFs are defined */
-/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
- * are new for v2.20 */
-#define CKG_MGF1_SHA1 0x00000001
-#define CKG_MGF1_SHA256 0x00000002
-#define CKG_MGF1_SHA384 0x00000003
-#define CKG_MGF1_SHA512 0x00000004
-
-/* v2.20 amendment 3 */
-#define CKG_MGF1_SHA224 0x00000005
-
-/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
- * of the encoding parameter when formatting a message block
- * for the PKCS #1 OAEP encryption scheme. */
-typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
-
-typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
-
-/* The following encoding parameter sources are defined */
-#define CKZ_DATA_SPECIFIED 0x00000001
-
-/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
- * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_OAEP mechanism. */
-typedef struct CK_RSA_PKCS_OAEP_PARAMS {
- CK_MECHANISM_TYPE hashAlg;
- CK_RSA_PKCS_MGF_TYPE mgf;
- CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
- CK_VOID_PTR pSourceData;
- CK_ULONG ulSourceDataLen;
-} CK_RSA_PKCS_OAEP_PARAMS;
-
-typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
-
-/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
- * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_PSS mechanism(s). */
-typedef struct CK_RSA_PKCS_PSS_PARAMS {
- CK_MECHANISM_TYPE hashAlg;
- CK_RSA_PKCS_MGF_TYPE mgf;
- CK_ULONG sLen;
-} CK_RSA_PKCS_PSS_PARAMS;
-
-typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
-
-/* CK_EC_KDF_TYPE is new for v2.11. */
-typedef CK_ULONG CK_EC_KDF_TYPE;
-
-/* The following EC Key Derivation Functions are defined */
-#define CKD_NULL 0x00000001
-#define CKD_SHA1_KDF 0x00000002
-#define CKD_SHA224_KDF 0x00000005
-#define CKD_SHA256_KDF 0x00000006
-#define CKD_SHA384_KDF 0x00000007
-#define CKD_SHA512_KDF 0x00000008
-
-/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
- * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
- * where each party contributes one key pair.
- */
-typedef struct CK_ECDH1_DERIVE_PARAMS {
- CK_EC_KDF_TYPE kdf;
- CK_ULONG ulSharedDataLen;
- CK_BYTE_PTR pSharedData;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
-} CK_ECDH1_DERIVE_PARAMS;
-
-typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
-
-
-/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
- * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
-typedef struct CK_ECDH2_DERIVE_PARAMS {
- CK_EC_KDF_TYPE kdf;
- CK_ULONG ulSharedDataLen;
- CK_BYTE_PTR pSharedData;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPrivateDataLen;
- CK_OBJECT_HANDLE hPrivateData;
- CK_ULONG ulPublicDataLen2;
- CK_BYTE_PTR pPublicData2;
-} CK_ECDH2_DERIVE_PARAMS;
-
-typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_ECMQV_DERIVE_PARAMS {
- CK_EC_KDF_TYPE kdf;
- CK_ULONG ulSharedDataLen;
- CK_BYTE_PTR pSharedData;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPrivateDataLen;
- CK_OBJECT_HANDLE hPrivateData;
- CK_ULONG ulPublicDataLen2;
- CK_BYTE_PTR pPublicData2;
- CK_OBJECT_HANDLE publicKey;
-} CK_ECMQV_DERIVE_PARAMS;
-
-typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
-
-/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
- * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
-typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
-typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
-
-/* The following X9.42 DH key derivation functions are defined
- (besides CKD_NULL already defined : */
-#define CKD_SHA1_KDF_ASN1 0x00000003
-#define CKD_SHA1_KDF_CONCATENATE 0x00000004
-
-/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
- * contributes one key pair */
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
- CK_X9_42_DH_KDF_TYPE kdf;
- CK_ULONG ulOtherInfoLen;
- CK_BYTE_PTR pOtherInfo;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
-} CK_X9_42_DH1_DERIVE_PARAMS;
-
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
-
-/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
- * mechanisms, where each party contributes two key pairs */
-typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
- CK_X9_42_DH_KDF_TYPE kdf;
- CK_ULONG ulOtherInfoLen;
- CK_BYTE_PTR pOtherInfo;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPrivateDataLen;
- CK_OBJECT_HANDLE hPrivateData;
- CK_ULONG ulPublicDataLen2;
- CK_BYTE_PTR pPublicData2;
-} CK_X9_42_DH2_DERIVE_PARAMS;
-
-typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
- CK_X9_42_DH_KDF_TYPE kdf;
- CK_ULONG ulOtherInfoLen;
- CK_BYTE_PTR pOtherInfo;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPrivateDataLen;
- CK_OBJECT_HANDLE hPrivateData;
- CK_ULONG ulPublicDataLen2;
- CK_BYTE_PTR pPublicData2;
- CK_OBJECT_HANDLE publicKey;
-} CK_X9_42_MQV_DERIVE_PARAMS;
-
-typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
-
-/* CK_KEA_DERIVE_PARAMS provides the parameters to the
- * CKM_KEA_DERIVE mechanism */
-/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
-typedef struct CK_KEA_DERIVE_PARAMS {
- CK_BBOOL isSender;
- CK_ULONG ulRandomLen;
- CK_BYTE_PTR pRandomA;
- CK_BYTE_PTR pRandomB;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
-} CK_KEA_DERIVE_PARAMS;
-
-typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
-
-
-/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
- * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
- * holds the effective keysize */
-typedef CK_ULONG CK_RC2_PARAMS;
-
-typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
-
-
-/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
- * mechanism */
-typedef struct CK_RC2_CBC_PARAMS {
- /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
-
- CK_BYTE iv[8]; /* IV for CBC mode */
-} CK_RC2_CBC_PARAMS;
-
-typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
-
-
-/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC2_MAC_GENERAL mechanism */
-/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC2_MAC_GENERAL_PARAMS {
- CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
- CK_ULONG ulMacLength; /* Length of MAC in bytes */
-} CK_RC2_MAC_GENERAL_PARAMS;
-
-typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
- CK_RC2_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
- * CKM_RC5_MAC mechanisms */
-/* CK_RC5_PARAMS is new for v2.0 */
-typedef struct CK_RC5_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
-} CK_RC5_PARAMS;
-
-typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
-
-
-/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
- * mechanism */
-/* CK_RC5_CBC_PARAMS is new for v2.0 */
-typedef struct CK_RC5_CBC_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
- CK_BYTE_PTR pIv; /* pointer to IV */
- CK_ULONG ulIvLen; /* length of IV in bytes */
-} CK_RC5_CBC_PARAMS;
-
-typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
-
-
-/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC5_MAC_GENERAL mechanism */
-/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC5_MAC_GENERAL_PARAMS {
- CK_ULONG ulWordsize; /* wordsize in bits */
- CK_ULONG ulRounds; /* number of rounds */
- CK_ULONG ulMacLength; /* Length of MAC in bytes */
-} CK_RC5_MAC_GENERAL_PARAMS;
-
-typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
- CK_RC5_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
- * ciphers' MAC_GENERAL mechanisms. Its value is the length of
- * the MAC */
-/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
-
-typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
-
-/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
-typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
- CK_BYTE iv[8];
- CK_BYTE_PTR pData;
- CK_ULONG length;
-} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
- CK_BYTE iv[16];
- CK_BYTE_PTR pData;
- CK_ULONG length;
-} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
-typedef struct CK_AES_CTR_PARAMS {
- CK_ULONG ulCounterBits;
- CK_BYTE cb[16];
-} CK_AES_CTR_PARAMS;
-
-typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
-
-/* CK_GCM_PARAMS is new for version 2.30 */
-typedef struct CK_GCM_PARAMS {
- CK_BYTE_PTR pIv;
- CK_ULONG ulIvLen;
- CK_BYTE_PTR pAAD;
- CK_ULONG ulAADLen;
- CK_ULONG ulTagBits;
-} CK_GCM_PARAMS;
-
-typedef CK_GCM_PARAMS CK_PTR CK_GCM_PARAMS_PTR;
-
-/* CK_CCM_PARAMS is new for version 2.30 */
-typedef struct CK_CCM_PARAMS {
- CK_ULONG ulDataLen;
- CK_BYTE_PTR pNonce;
- CK_ULONG ulNonceLen;
- CK_BYTE_PTR pAAD;
- CK_ULONG ulAADLen;
- CK_ULONG ulMACLen;
-} CK_CCM_PARAMS;
-
-typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR;
-
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
- * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
- CK_ULONG ulPasswordLen;
- CK_BYTE_PTR pPassword;
- CK_ULONG ulPublicDataLen;
- CK_BYTE_PTR pPublicData;
- CK_ULONG ulPAndGLen;
- CK_ULONG ulQLen;
- CK_ULONG ulRandomLen;
- CK_BYTE_PTR pRandomA;
- CK_BYTE_PTR pPrimeP;
- CK_BYTE_PTR pBaseG;
- CK_BYTE_PTR pSubprimeQ;
-} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
-
-typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
- CK_SKIPJACK_PRIVATE_WRAP_PTR;
-
-
-/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
- * CKM_SKIPJACK_RELAYX mechanism */
-/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_RELAYX_PARAMS {
- CK_ULONG ulOldWrappedXLen;
- CK_BYTE_PTR pOldWrappedX;
- CK_ULONG ulOldPasswordLen;
- CK_BYTE_PTR pOldPassword;
- CK_ULONG ulOldPublicDataLen;
- CK_BYTE_PTR pOldPublicData;
- CK_ULONG ulOldRandomLen;
- CK_BYTE_PTR pOldRandomA;
- CK_ULONG ulNewPasswordLen;
- CK_BYTE_PTR pNewPassword;
- CK_ULONG ulNewPublicDataLen;
- CK_BYTE_PTR pNewPublicData;
- CK_ULONG ulNewRandomLen;
- CK_BYTE_PTR pNewRandomA;
-} CK_SKIPJACK_RELAYX_PARAMS;
-
-typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
- CK_SKIPJACK_RELAYX_PARAMS_PTR;
-
-
-typedef struct CK_PBE_PARAMS {
- CK_BYTE_PTR pInitVector;
- CK_UTF8CHAR_PTR pPassword;
- CK_ULONG ulPasswordLen;
- CK_BYTE_PTR pSalt;
- CK_ULONG ulSaltLen;
- CK_ULONG ulIteration;
-} CK_PBE_PARAMS;
-
-typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
-
-
-/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
- * CKM_KEY_WRAP_SET_OAEP mechanism */
-/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
-typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
- CK_BYTE bBC; /* block contents byte */
- CK_BYTE_PTR pX; /* extra data */
- CK_ULONG ulXLen; /* length of extra data in bytes */
-} CK_KEY_WRAP_SET_OAEP_PARAMS;
-
-typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
- CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_RANDOM_DATA {
- CK_BYTE_PTR pClientRandom;
- CK_ULONG ulClientRandomLen;
- CK_BYTE_PTR pServerRandom;
- CK_ULONG ulServerRandomLen;
-} CK_SSL3_RANDOM_DATA;
-
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_VERSION_PTR pVersion;
-} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
- CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_OUT {
- CK_OBJECT_HANDLE hClientMacSecret;
- CK_OBJECT_HANDLE hServerMacSecret;
- CK_OBJECT_HANDLE hClientKey;
- CK_OBJECT_HANDLE hServerKey;
- CK_BYTE_PTR pIVClient;
- CK_BYTE_PTR pIVServer;
-} CK_SSL3_KEY_MAT_OUT;
-
-typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_PARAMS {
- CK_ULONG ulMacSizeInBits;
- CK_ULONG ulKeySizeInBits;
- CK_ULONG ulIVSizeInBits;
- CK_BBOOL bIsExport;
- CK_SSL3_RANDOM_DATA RandomInfo;
- CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_SSL3_KEY_MAT_PARAMS;
-
-typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
-
-/* CK_TLS_PRF_PARAMS is new for version 2.20 */
-typedef struct CK_TLS_PRF_PARAMS {
- CK_BYTE_PTR pSeed;
- CK_ULONG ulSeedLen;
- CK_BYTE_PTR pLabel;
- CK_ULONG ulLabelLen;
- CK_BYTE_PTR pOutput;
- CK_ULONG_PTR pulOutputLen;
-} CK_TLS_PRF_PARAMS;
-
-typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
-
-/* WTLS is new for version 2.20 */
-typedef struct CK_WTLS_RANDOM_DATA {
- CK_BYTE_PTR pClientRandom;
- CK_ULONG ulClientRandomLen;
- CK_BYTE_PTR pServerRandom;
- CK_ULONG ulServerRandomLen;
-} CK_WTLS_RANDOM_DATA;
-
-typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
-
-typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
- CK_MECHANISM_TYPE DigestMechanism;
- CK_WTLS_RANDOM_DATA RandomInfo;
- CK_BYTE_PTR pVersion;
-} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
-
-typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
- CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-typedef struct CK_WTLS_PRF_PARAMS {
- CK_MECHANISM_TYPE DigestMechanism;
- CK_BYTE_PTR pSeed;
- CK_ULONG ulSeedLen;
- CK_BYTE_PTR pLabel;
- CK_ULONG ulLabelLen;
- CK_BYTE_PTR pOutput;
- CK_ULONG_PTR pulOutputLen;
-} CK_WTLS_PRF_PARAMS;
-
-typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_OUT {
- CK_OBJECT_HANDLE hMacSecret;
- CK_OBJECT_HANDLE hKey;
- CK_BYTE_PTR pIV;
-} CK_WTLS_KEY_MAT_OUT;
-
-typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_PARAMS {
- CK_MECHANISM_TYPE DigestMechanism;
- CK_ULONG ulMacSizeInBits;
- CK_ULONG ulKeySizeInBits;
- CK_ULONG ulIVSizeInBits;
- CK_ULONG ulSequenceNumber;
- CK_BBOOL bIsExport;
- CK_WTLS_RANDOM_DATA RandomInfo;
- CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_WTLS_KEY_MAT_PARAMS;
-
-typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
-
-/* CMS is new for version 2.20 */
-typedef struct CK_CMS_SIG_PARAMS {
- CK_OBJECT_HANDLE certificateHandle;
- CK_MECHANISM_PTR pSigningMechanism;
- CK_MECHANISM_PTR pDigestMechanism;
- CK_UTF8CHAR_PTR pContentType;
- CK_BYTE_PTR pRequestedAttributes;
- CK_ULONG ulRequestedAttributesLen;
- CK_BYTE_PTR pRequiredAttributes;
- CK_ULONG ulRequiredAttributesLen;
-} CK_CMS_SIG_PARAMS;
-
-typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
-
-typedef struct CK_KEY_DERIVATION_STRING_DATA {
- CK_BYTE_PTR pData;
- CK_ULONG ulLen;
-} CK_KEY_DERIVATION_STRING_DATA;
-
-typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
- CK_KEY_DERIVATION_STRING_DATA_PTR;
-
-
-/* The CK_EXTRACT_PARAMS is used for the
- * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
- * of the base key should be used as the first bit of the
- * derived key */
-/* CK_EXTRACT_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_EXTRACT_PARAMS;
-
-typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-
-/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
- * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
- * indicate the Pseudo-Random Function (PRF) used to generate
- * key bits using PKCS #5 PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
-
-typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
-
-/* The following PRFs are defined in PKCS #5 v2.0. */
-#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
-
-
-/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
- * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
- * source of the salt value when deriving a key using PKCS #5
- * PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
-
-typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
-
-/* The following salt value sources are defined in PKCS #5 v2.0. */
-#define CKZ_SALT_SPECIFIED 0x00000001
-
-/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
- * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
- * parameters to the CKM_PKCS5_PBKD2 mechanism. */
-typedef struct CK_PKCS5_PBKD2_PARAMS {
- CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
- CK_VOID_PTR pSaltSourceData;
- CK_ULONG ulSaltSourceDataLen;
- CK_ULONG iterations;
- CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
- CK_VOID_PTR pPrfData;
- CK_ULONG ulPrfDataLen;
- CK_UTF8CHAR_PTR pPassword;
- CK_ULONG_PTR ulPasswordLen;
-} CK_PKCS5_PBKD2_PARAMS;
-
-typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
-
-/* NSS Specific defines */
-
-/* defines that have been deprecated in 2.20, but maintained in our
- * header file for backward compatibility */
-#define CKO_KG_PARAMETERS CKO_DOMAIN_PARAMETERS
-#define CKF_EC_FP CKF_EC_F_P
-/* new in v2.11 deprecated by 2.20 */
-#define CKR_KEY_PARAMS_INVALID 0x0000006B
-
-/* stuff that for historic reasons is in this header file but should have
- * been in pkcs11n.h */
-#define CKK_INVALID_KEY_TYPE 0xffffffff
-
-#include "pkcs11n.h"
-
-/* undo packing */
-#include "pkcs11u.h"
-
-#endif
diff --git a/security/nss/lib/util/pkcs11u.h b/security/nss/lib/util/pkcs11u.h
deleted file mode 100644
index f670094a9..000000000
--- a/security/nss/lib/util/pkcs11u.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
- * is granted provided that it is identified as "RSA Security Inc. Public-Key
- * Cryptography Standards (PKCS)" in all material mentioning or referencing
- * this document.
- */
-/*
- * reset any packing set by pkcs11p.h
- */
-
-#if defined (_WIN32)
-#ifdef _MSC_VER
-#pragma warning(disable:4103)
-#endif
-#pragma pack(pop, cryptoki)
-#endif
-
diff --git a/security/nss/lib/util/portreg.c b/security/nss/lib/util/portreg.c
deleted file mode 100644
index ba2b3ce91..000000000
--- a/security/nss/lib/util/portreg.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * shexp.c: shell-like wildcard match routines
- *
- * See shexp.h for public documentation.
- */
-
-#include "seccomon.h"
-#include "portreg.h"
-
-/* ----------------------------- shexp_valid ------------------------------ */
-
-
-static int
-_valid_subexp(const char *exp, char stop1, char stop2)
-{
- register int x;
- int nsc = 0; /* Number of special characters */
- int np; /* Number of pipe characters in union */
- int tld = 0; /* Number of tilde characters */
-
- for (x = 0; exp[x] && (exp[x] != stop1) && (exp[x] != stop2); ++x) {
- switch(exp[x]) {
- case '~':
- if(tld) /* at most one exclusion */
- return INVALID_SXP;
- if (stop1) /* no exclusions within unions */
- return INVALID_SXP;
- if (!exp[x+1]) /* exclusion cannot be last character */
- return INVALID_SXP;
- if (!x) /* exclusion cannot be first character */
- return INVALID_SXP;
- ++tld;
- /* fall through */
- case '*':
- case '?':
- case '$':
- ++nsc;
- break;
- case '[':
- ++nsc;
- if((!exp[++x]) || (exp[x] == ']'))
- return INVALID_SXP;
- for(; exp[x] && (exp[x] != ']'); ++x) {
- if(exp[x] == '\\' && !exp[++x])
- return INVALID_SXP;
- }
- if(!exp[x])
- return INVALID_SXP;
- break;
- case '(':
- ++nsc;
- if (stop1) /* no nested unions */
- return INVALID_SXP;
- np = -1;
- do {
- int t = _valid_subexp(&exp[++x], ')', '|');
- if(t == 0 || t == INVALID_SXP)
- return INVALID_SXP;
- x+=t;
- if(!exp[x])
- return INVALID_SXP;
- ++np;
- } while (exp[x] == '|' );
- if(np < 1) /* must be at least one pipe */
- return INVALID_SXP;
- break;
- case ')':
- case '|':
- case ']':
- return INVALID_SXP;
- case '\\':
- ++nsc;
- if(!exp[++x])
- return INVALID_SXP;
- break;
- default:
- break;
- }
- }
- if((!stop1) && (!nsc)) /* must be at least one special character */
- return NON_SXP;
- return ((exp[x] == stop1 || exp[x] == stop2) ? x : INVALID_SXP);
-}
-
-int
-PORT_RegExpValid(const char *exp)
-{
- int x;
-
- x = _valid_subexp(exp, '\0', '\0');
- return (x < 0 ? x : VALID_SXP);
-}
-
-
-/* ----------------------------- shexp_match ----------------------------- */
-
-
-#define MATCH 0
-#define NOMATCH 1
-#define ABORTED -1
-
-static int
-_shexp_match(const char *str, const char *exp, PRBool case_insensitive,
- unsigned int level);
-
-/* Count characters until we reach a NUL character or either of the
- * two delimiter characters, stop1 or stop2. If we encounter a bracketed
- * expression, look only for NUL or ']' inside it. Do not look for stop1
- * or stop2 inside it. Return ABORTED if bracketed expression is unterminated.
- * Handle all escaping.
- * Return index in input string of first stop found, or ABORTED if not found.
- * If "dest" is non-NULL, copy counted characters to it and NUL terminate.
- */
-static int
-_scan_and_copy(const char *exp, char stop1, char stop2, char *dest)
-{
- register int sx; /* source index */
- register char cc;
-
- for (sx = 0; (cc = exp[sx]) && cc != stop1 && cc != stop2; sx++) {
- if (cc == '\\') {
- if (!exp[++sx])
- return ABORTED; /* should be impossible */
- } else if (cc == '[') {
- while ((cc = exp[++sx]) && cc != ']') {
- if(cc == '\\' && !exp[++sx])
- return ABORTED;
- }
- if (!cc)
- return ABORTED; /* should be impossible */
- }
- }
- if (dest && sx) {
- /* Copy all but the closing delimiter. */
- memcpy(dest, exp, sx);
- dest[sx] = 0;
- }
- return cc ? sx : ABORTED; /* index of closing delimiter */
-}
-
-/* On input, exp[0] is the opening parenthesis of a union.
- * See if any of the alternatives in the union matches as a pattern.
- * The strategy is to take each of the alternatives, in turn, and append
- * the rest of the expression (after the closing ')' that marks the end of
- * this union) to that alternative, and then see if the resultant expression
- * matches the input string. Repeat this until some alternative matches,
- * or we have an abort.
- */
-static int
-_handle_union(const char *str, const char *exp, PRBool case_insensitive,
- unsigned int level)
-{
- register int sx; /* source index */
- int cp; /* source index of closing parenthesis */
- int count;
- int ret = NOMATCH;
- char *e2;
-
- /* Find the closing parenthesis that ends this union in the expression */
- cp = _scan_and_copy(exp, ')', '\0', NULL);
- if (cp == ABORTED || cp < 4) /* must be at least "(a|b" before ')' */
- return ABORTED;
- ++cp; /* now index of char after closing parenthesis */
- e2 = (char *) PORT_Alloc(1 + strlen(exp));
- if (!e2)
- return ABORTED;
- for (sx = 1; ; ++sx) {
- /* Here, exp[sx] is one character past the preceding '(' or '|'. */
- /* Copy everything up to the next delimiter to e2 */
- count = _scan_and_copy(exp + sx, ')', '|', e2);
- if (count == ABORTED || !count) {
- ret = ABORTED;
- break;
- }
- sx += count;
- /* Append everything after closing parenthesis to e2. This is safe. */
- strcpy(e2+count, exp+cp);
- ret = _shexp_match(str, e2, case_insensitive, level + 1);
- if (ret != NOMATCH || !exp[sx] || exp[sx] == ')')
- break;
- }
- PORT_Free(e2);
- if (sx < 2)
- ret = ABORTED;
- return ret;
-}
-
-/* returns 1 if val is in range from start..end, case insensitive. */
-static int
-_is_char_in_range(int start, int end, int val)
-{
- char map[256];
- memset(map, 0, sizeof map);
- while (start <= end)
- map[tolower(start++)] = 1;
- return map[tolower(val)];
-}
-
-static int
-_shexp_match(const char *str, const char *exp, PRBool case_insensitive,
- unsigned int level)
-{
- register int x; /* input string index */
- register int y; /* expression index */
- int ret,neg;
-
- if (level > 20) /* Don't let the stack get too deep. */
- return ABORTED;
- for(x = 0, y = 0; exp[y]; ++y, ++x) {
- if((!str[x]) && (exp[y] != '$') && (exp[y] != '*')) {
- return NOMATCH;
- }
- switch(exp[y]) {
- case '$':
- if(str[x])
- return NOMATCH;
- --x; /* we don't want loop to increment x */
- break;
- case '*':
- while(exp[++y] == '*'){}
- if(!exp[y])
- return MATCH;
- while(str[x]) {
- ret = _shexp_match(&str[x++], &exp[y], case_insensitive,
- level + 1);
- switch(ret) {
- case NOMATCH:
- continue;
- case ABORTED:
- return ABORTED;
- default:
- return MATCH;
- }
- }
- if((exp[y] == '$') && (exp[y+1] == '\0') && (!str[x]))
- return MATCH;
- else
- return NOMATCH;
- case '[': {
- int start, end = 0, i;
- neg = ((exp[++y] == '^') && (exp[y+1] != ']'));
- if (neg)
- ++y;
- i = y;
- start = (unsigned char)(exp[i++]);
- if (start == '\\')
- start = (unsigned char)(exp[i++]);
- if (isalnum(start) && exp[i++] == '-') {
- end = (unsigned char)(exp[i++]);
- if (end == '\\')
- end = (unsigned char)(exp[i++]);
- }
- if (isalnum(end) && exp[i] == ']') {
- /* This is a range form: a-b */
- int val = (unsigned char)(str[x]);
- if (end < start) { /* swap them */
- start ^= end;
- end ^= start;
- start ^= end;
- }
- if (case_insensitive && isalpha(val)) {
- val = _is_char_in_range(start, end, val);
- if (neg == val)
- return NOMATCH;
- } else if (neg != ((val < start) || (val > end))) {
- return NOMATCH;
- }
- y = i;
- } else {
- /* Not range form */
- int matched = 0;
- for (; exp[y] != ']'; y++) {
- if (exp[y] == '\\')
- ++y;
- if(case_insensitive) {
- matched |= (toupper(str[x]) == toupper(exp[y]));
- } else {
- matched |= (str[x] == exp[y]);
- }
- }
- if (neg == matched)
- return NOMATCH;
- }
- }
- break;
- case '(':
- if (!exp[y+1])
- return ABORTED;
- return _handle_union(&str[x], &exp[y], case_insensitive, level);
- case '?':
- break;
- case '|':
- case ']':
- case ')':
- return ABORTED;
- case '\\':
- ++y;
- /* fall through */
- default:
- if(case_insensitive) {
- if(toupper(str[x]) != toupper(exp[y]))
- return NOMATCH;
- } else {
- if(str[x] != exp[y])
- return NOMATCH;
- }
- break;
- }
- }
- return (str[x] ? NOMATCH : MATCH);
-}
-
-static int
-port_RegExpMatch(const char *str, const char *xp, PRBool case_insensitive)
-{
- char *exp = 0;
- int x, ret = MATCH;
-
- if (!strchr(xp, '~'))
- return _shexp_match(str, xp, case_insensitive, 0);
-
- exp = PORT_Strdup(xp);
- if(!exp)
- return NOMATCH;
-
- x = _scan_and_copy(exp, '~', '\0', NULL);
- if (x != ABORTED && exp[x] == '~') {
- exp[x++] = '\0';
- ret = _shexp_match(str, &exp[x], case_insensitive, 0);
- switch (ret) {
- case NOMATCH: ret = MATCH; break;
- case MATCH: ret = NOMATCH; break;
- default: break;
- }
- }
- if (ret == MATCH)
- ret = _shexp_match(str, exp, case_insensitive, 0);
-
- PORT_Free(exp);
- return ret;
-}
-
-
-/* ------------------------------ shexp_cmp ------------------------------- */
-
-int
-PORT_RegExpSearch(const char *str, const char *exp)
-{
- switch(PORT_RegExpValid(exp))
- {
- case INVALID_SXP:
- return -1;
- case NON_SXP:
- return (strcmp(exp,str) ? 1 : 0);
- default:
- return port_RegExpMatch(str, exp, PR_FALSE);
- }
-}
-
-int
-PORT_RegExpCaseSearch(const char *str, const char *exp)
-{
- switch(PORT_RegExpValid(exp))
- {
- case INVALID_SXP:
- return -1;
- case NON_SXP:
- return (PORT_Strcasecmp(exp,str) ? 1 : 0);
- default:
- return port_RegExpMatch(str, exp, PR_TRUE);
- }
-}
-
diff --git a/security/nss/lib/util/portreg.h b/security/nss/lib/util/portreg.h
deleted file mode 100644
index 811f04539..000000000
--- a/security/nss/lib/util/portreg.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * shexp.h: Defines and prototypes for shell exp. match routines
- *
- * This routine will match a string with a shell expression. The expressions
- * accepted are based loosely on the expressions accepted by zsh.
- *
- * o * matches anything
- * o ? matches one character
- * o \ will escape a special character
- * o $ matches the end of the string
- * Bracketed expressions:
- * o [abc] matches one occurence of a, b, or c.
- * o [^abc] matches any character except a, b, or c.
- * To be matched between [ and ], these characters must be escaped: \ ]
- * No other characters need be escaped between brackets.
- * Unnecessary escaping is permitted.
- * o [a-z] matches any character between a and z, inclusive.
- * The two range-definition characters must be alphanumeric ASCII.
- * If one is upper case and the other is lower case, then the ASCII
- * non-alphanumeric characters between Z and a will also be in range.
- * o [^a-z] matches any character except those between a and z, inclusive.
- * These forms cannot be combined, e.g [a-gp-z] does not work.
- * o Exclusions:
- * As a top level, outter-most expression only, the expression
- * foo~bar will match the expression foo, provided it does not also
- * match the expression bar. Either expression or both may be a union.
- * Except between brackets, any unescaped ~ is an exclusion.
- * At most one exclusion is permitted.
- * Exclusions cannot be nested (contain other exclusions).
- * example: *~abc will match any string except abc
- * o Unions:
- * (foo|bar) will match either the expression foo, or the expression bar.
- * At least one '|' separator is required. More are permitted.
- * Expressions inside unions may not include unions or exclusions.
- * Inside a union, to be matched and not treated as a special character,
- * these characters must be escaped: \ ( | ) [ ~ except when they occur
- * inside a bracketed expression, where only \ and ] require escaping.
- *
- * The public interface to these routines is documented below.
- *
- */
-
-#ifndef SHEXP_H
-#define SHEXP_H
-
-#include "utilrename.h"
-/*
- * Requires that the macro MALLOC be set to a "safe" malloc that will
- * exit if no memory is available.
- */
-
-
-/* --------------------------- Public routines ---------------------------- */
-
-
-/*
- * shexp_valid takes a shell expression exp as input. It returns:
- *
- * NON_SXP if exp is a standard string
- * INVALID_SXP if exp is a shell expression, but invalid
- * VALID_SXP if exp is a valid shell expression
- */
-
-#define NON_SXP -1
-#define INVALID_SXP -2
-#define VALID_SXP 1
-
-SEC_BEGIN_PROTOS
-
-extern int PORT_RegExpValid(const char *exp);
-
-extern int PORT_RegExpSearch(const char *str, const char *exp);
-
-/* same as above but uses case insensitive search */
-extern int PORT_RegExpCaseSearch(const char *str, const char *exp);
-
-SEC_END_PROTOS
-
-#endif
diff --git a/security/nss/lib/util/quickder.c b/security/nss/lib/util/quickder.c
deleted file mode 100644
index 2374ba29c..000000000
--- a/security/nss/lib/util/quickder.c
+++ /dev/null
@@ -1,897 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- Optimized ASN.1 DER decoder
-
-*/
-
-#include "secerr.h"
-#include "secasn1.h" /* for SEC_ASN1GetSubtemplate */
-#include "secitem.h"
-
-/*
- * simple definite-length ASN.1 decoder
- */
-
-static unsigned char* definite_length_decoder(const unsigned char *buf,
- const unsigned int length,
- unsigned int *data_length,
- PRBool includeTag)
-{
- unsigned char tag;
- unsigned int used_length= 0;
- unsigned int data_len;
-
- if (used_length >= length)
- {
- return NULL;
- }
- tag = buf[used_length++];
-
- /* blow out when we come to the end */
- if (tag == 0)
- {
- return NULL;
- }
-
- if (used_length >= length)
- {
- return NULL;
- }
- data_len = buf[used_length++];
-
- if (data_len&0x80)
- {
- int len_count = data_len & 0x7f;
-
- data_len = 0;
-
- while (len_count-- > 0)
- {
- if (used_length >= length)
- {
- return NULL;
- }
- data_len = (data_len << 8) | buf[used_length++];
- }
- }
-
- if (data_len > (length-used_length) )
- {
- return NULL;
- }
- if (includeTag) data_len += used_length;
-
- *data_length = data_len;
- return ((unsigned char*)buf + (includeTag ? 0 : used_length));
-}
-
-static SECStatus GetItem(SECItem* src, SECItem* dest, PRBool includeTag)
-{
- if ( (!src) || (!dest) || (!src->data && src->len) )
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (!src->len)
- {
- /* reaching the end of the buffer is not an error */
- dest->data = NULL;
- dest->len = 0;
- return SECSuccess;
- }
-
- dest->data = definite_length_decoder(src->data, src->len, &dest->len,
- includeTag);
- if (dest->data == NULL)
- {
- PORT_SetError(SEC_ERROR_BAD_DER);
- return SECFailure;
- }
- src->len -= (dest->data - src->data) + dest->len;
- src->data = dest->data + dest->len;
- return SECSuccess;
-}
-
-/* check if the actual component's type matches the type in the template */
-
-static SECStatus MatchComponentType(const SEC_ASN1Template* templateEntry,
- SECItem* item, PRBool* match, void* dest)
-{
- unsigned long kind = 0;
- unsigned char tag = 0;
-
- if ( (!item) || (!item->data && item->len) || (!templateEntry) || (!match) )
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (!item->len)
- {
- *match = PR_FALSE;
- return SECSuccess;
- }
-
- kind = templateEntry->kind;
- tag = *(unsigned char*) item->data;
-
- if ( ( (kind & SEC_ASN1_INLINE) ||
- (kind & SEC_ASN1_POINTER) ) &&
- (0 == (kind & SEC_ASN1_TAG_MASK) ) )
- {
- /* These cases are special because the template's "kind" does not
- give us the information for the ASN.1 tag of the next item. It can
- only be figured out from the subtemplate. */
- if (!(kind & SEC_ASN1_OPTIONAL))
- {
- /* This is a required component. If there is a type mismatch,
- the decoding of the subtemplate will fail, so assume this
- is a match at the parent level and let it fail later. This
- avoids a redundant check in matching cases */
- *match = PR_TRUE;
- return SECSuccess;
- }
- else
- {
- /* optional component. This is the hard case. Now we need to
- look at the subtemplate to get the expected kind */
- const SEC_ASN1Template* subTemplate =
- SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE);
- if (!subTemplate)
- {
- PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
- return SECFailure;
- }
- if ( (subTemplate->kind & SEC_ASN1_INLINE) ||
- (subTemplate->kind & SEC_ASN1_POINTER) )
- {
- /* disallow nesting SEC_ASN1_POINTER and SEC_ASN1_INLINE,
- otherwise you may get a false positive due to the recursion
- optimization above that always matches the type if the
- component is required . Nesting these should never be
- required, so that no one should miss this ability */
- PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
- return SECFailure;
- }
- return MatchComponentType(subTemplate, item, match,
- (void*)((char*)dest + templateEntry->offset));
- }
- }
-
- if (kind & SEC_ASN1_CHOICE)
- {
- /* we need to check the component's tag against each choice's tag */
- /* XXX it would be nice to save the index of the choice here so that
- DecodeChoice wouldn't have to do this again. However, due to the
- recursivity of MatchComponentType, we don't know if we are in a
- required or optional component, so we can't write anywhere in
- the destination within this function */
- unsigned choiceIndex = 1;
- const SEC_ASN1Template* choiceEntry;
- while ( (choiceEntry = &templateEntry[choiceIndex++]) && (choiceEntry->kind))
- {
- if ( (SECSuccess == MatchComponentType(choiceEntry, item, match,
- (void*)((char*)dest + choiceEntry->offset))) &&
- (PR_TRUE == *match) )
- {
- return SECSuccess;
- }
- }
- /* no match, caller must decide if this is BAD DER, or not. */
- *match = PR_FALSE;
- return SECSuccess;
- }
-
- if (kind & SEC_ASN1_ANY)
- {
- /* SEC_ASN1_ANY always matches */
- *match = PR_TRUE;
- return SECSuccess;
- }
-
- if ( (0 == ((unsigned char)kind & SEC_ASN1_TAGNUM_MASK)) &&
- (!(kind & SEC_ASN1_EXPLICIT)) &&
- ( ( (kind & SEC_ASN1_SAVE) ||
- (kind & SEC_ASN1_SKIP) ) &&
- (!(kind & SEC_ASN1_OPTIONAL))
- )
- )
- {
- /* when saving or skipping a required component, a type is not
- required in the template. This is for legacy support of
- SEC_ASN1_SAVE and SEC_ASN1_SKIP only. XXX I would like to
- deprecate these usages and always require a type, as this
- disables type checking, and effectively forbids us from
- transparently ignoring optional components we aren't aware of */
- *match = PR_TRUE;
- return SECSuccess;
- }
-
- /* first, do a class check */
- if ( (tag & SEC_ASN1_CLASS_MASK) !=
- (((unsigned char)kind) & SEC_ASN1_CLASS_MASK) )
- {
-#ifdef DEBUG
- /* this is only to help debugging of the decoder in case of problems */
- unsigned char tagclass = tag & SEC_ASN1_CLASS_MASK;
- unsigned char expectedclass = (unsigned char)kind & SEC_ASN1_CLASS_MASK;
- tagclass = tagclass;
- expectedclass = expectedclass;
-#endif
- *match = PR_FALSE;
- return SECSuccess;
- }
-
- /* now do a tag check */
- if ( ((unsigned char)kind & SEC_ASN1_TAGNUM_MASK) !=
- (tag & SEC_ASN1_TAGNUM_MASK))
- {
- *match = PR_FALSE;
- return SECSuccess;
- }
-
- /* now, do a method check. This depends on the class */
- switch (tag & SEC_ASN1_CLASS_MASK)
- {
- case SEC_ASN1_UNIVERSAL:
- /* For types of the SEC_ASN1_UNIVERSAL class, we know which must be
- primitive or constructed based on the tag */
- switch (tag & SEC_ASN1_TAGNUM_MASK)
- {
- case SEC_ASN1_SEQUENCE:
- case SEC_ASN1_SET:
- case SEC_ASN1_EMBEDDED_PDV:
- /* this component must be a constructed type */
- /* XXX add any new universal constructed type here */
- if (tag & SEC_ASN1_CONSTRUCTED)
- {
- *match = PR_TRUE;
- return SECSuccess;
- }
- break;
-
- default:
- /* this component must be a primitive type */
- if (! (tag & SEC_ASN1_CONSTRUCTED))
- {
- *match = PR_TRUE;
- return SECSuccess;
- }
- break;
- }
- break;
-
- default:
- /* for all other classes, we check the method based on the template */
- if ( (unsigned char)(kind & SEC_ASN1_METHOD_MASK) ==
- (tag & SEC_ASN1_METHOD_MASK) )
- {
- *match = PR_TRUE;
- return SECSuccess;
- }
- /* method does not match between template and component */
- break;
- }
-
- *match = PR_FALSE;
- return SECSuccess;
-}
-
-#ifdef DEBUG
-
-static SECStatus CheckSequenceTemplate(const SEC_ASN1Template* sequenceTemplate)
-{
- SECStatus rv = SECSuccess;
- const SEC_ASN1Template* sequenceEntry = NULL;
- unsigned long seqIndex = 0;
- unsigned long lastEntryIndex = 0;
- unsigned long ambiguityIndex = 0;
- PRBool foundAmbiguity = PR_FALSE;
-
- do
- {
- sequenceEntry = &sequenceTemplate[seqIndex++];
- if (sequenceEntry->kind)
- {
- /* ensure that we don't have an optional component of SEC_ASN1_ANY
- in the middle of the sequence, since we could not handle it */
- /* XXX this function needs to dig into the subtemplates to find
- the next tag */
- if ( (PR_FALSE == foundAmbiguity) &&
- (sequenceEntry->kind & SEC_ASN1_OPTIONAL) &&
- (sequenceEntry->kind & SEC_ASN1_ANY) )
- {
- foundAmbiguity = PR_TRUE;
- ambiguityIndex = seqIndex - 1;
- }
- }
- } while (sequenceEntry->kind);
-
- lastEntryIndex = seqIndex - 2;
-
- if (PR_FALSE != foundAmbiguity)
- {
- if (ambiguityIndex < lastEntryIndex)
- {
- /* ambiguity can only be tolerated on the last entry */
- PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
- rv = SECFailure;
- }
- }
-
- /* XXX also enforce ASN.1 requirement that tags be
- distinct for consecutive optional components */
-
- return rv;
-}
-
-#endif
-
-static SECStatus DecodeItem(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PRArenaPool* arena, PRBool checkTag);
-
-static SECStatus DecodeSequence(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PRArenaPool* arena)
-{
- SECStatus rv = SECSuccess;
- SECItem source;
- SECItem sequence;
- const SEC_ASN1Template* sequenceTemplate = &(templateEntry[1]);
- const SEC_ASN1Template* sequenceEntry = NULL;
- unsigned long seqindex = 0;
-
-#ifdef DEBUG
- /* for a sequence, we need to validate the template. */
- rv = CheckSequenceTemplate(sequenceTemplate);
-#endif
-
- source = *src;
-
- /* get the sequence */
- if (SECSuccess == rv)
- {
- rv = GetItem(&source, &sequence, PR_FALSE);
- }
-
- /* process it */
- if (SECSuccess == rv)
- do
- {
- sequenceEntry = &sequenceTemplate[seqindex++];
- if ( (sequenceEntry && sequenceEntry->kind) &&
- (sequenceEntry->kind != SEC_ASN1_SKIP_REST) )
- {
- rv = DecodeItem(dest, sequenceEntry, &sequence, arena, PR_TRUE);
- }
- } while ( (SECSuccess == rv) &&
- (sequenceEntry->kind &&
- sequenceEntry->kind != SEC_ASN1_SKIP_REST) );
- /* we should have consumed all the bytes in the sequence by now
- unless the caller doesn't care about the rest of the sequence */
- if (SECSuccess == rv && sequence.len &&
- sequenceEntry && sequenceEntry->kind != SEC_ASN1_SKIP_REST)
- {
- /* it isn't 100% clear whether this is a bad DER or a bad template.
- The problem is that logically, they don't match - there is extra
- data in the DER that the template doesn't know about */
- PORT_SetError(SEC_ERROR_BAD_DER);
- rv = SECFailure;
- }
-
- return rv;
-}
-
-static SECStatus DecodeInline(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PRArenaPool* arena, PRBool checkTag)
-{
- const SEC_ASN1Template* inlineTemplate =
- SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE);
- return DecodeItem((void*)((char*)dest + templateEntry->offset),
- inlineTemplate, src, arena, checkTag);
-}
-
-static SECStatus DecodePointer(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PRArenaPool* arena, PRBool checkTag)
-{
- const SEC_ASN1Template* ptrTemplate =
- SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE);
- void* subdata = PORT_ArenaZAlloc(arena, ptrTemplate->size);
- *(void**)((char*)dest + templateEntry->offset) = subdata;
- if (subdata)
- {
- return DecodeItem(subdata, ptrTemplate, src, arena, checkTag);
- }
- else
- {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return SECFailure;
- }
-}
-
-static SECStatus DecodeImplicit(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PRArenaPool* arena)
-{
- if (templateEntry->kind & SEC_ASN1_POINTER)
- {
- return DecodePointer((void*)((char*)dest ),
- templateEntry, src, arena, PR_FALSE);
- }
- else
- {
- return DecodeInline((void*)((char*)dest ),
- templateEntry, src, arena, PR_FALSE);
- }
-}
-
-static SECStatus DecodeChoice(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PRArenaPool* arena)
-{
- SECStatus rv = SECSuccess;
- SECItem choice;
- const SEC_ASN1Template* choiceTemplate = &(templateEntry[1]);
- const SEC_ASN1Template* choiceEntry = NULL;
- unsigned long choiceindex = 0;
-
- /* XXX for a choice component, we should validate the template to make
- sure the tags are distinct, in debug builds. This hasn't been
- implemented yet */
- /* rv = CheckChoiceTemplate(sequenceTemplate); */
-
- /* process it */
- do
- {
- choice = *src;
- choiceEntry = &choiceTemplate[choiceindex++];
- if (choiceEntry->kind)
- {
- rv = DecodeItem(dest, choiceEntry, &choice, arena, PR_TRUE);
- }
- } while ( (SECFailure == rv) && (choiceEntry->kind));
-
- if (SECFailure == rv)
- {
- /* the component didn't match any of the choices */
- PORT_SetError(SEC_ERROR_BAD_DER);
- }
- else
- {
- /* set the type in the union here */
- int *which = (int *)((char *)dest + templateEntry->offset);
- *which = (int)choiceEntry->size;
- }
-
- /* we should have consumed all the bytes by now */
- /* fail if we have not */
- if (SECSuccess == rv && choice.len)
- {
- /* there is extra data that isn't listed in the template */
- PORT_SetError(SEC_ERROR_BAD_DER);
- rv = SECFailure;
- }
- return rv;
-}
-
-static SECStatus DecodeGroup(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PRArenaPool* arena)
-{
- SECStatus rv = SECSuccess;
- SECItem source;
- SECItem group;
- PRUint32 totalEntries = 0;
- PRUint32 entryIndex = 0;
- void** entries = NULL;
-
- const SEC_ASN1Template* subTemplate =
- SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE);
-
- source = *src;
-
- /* get the group */
- if (SECSuccess == rv)
- {
- rv = GetItem(&source, &group, PR_FALSE);
- }
-
- /* XXX we should check the subtemplate in debug builds */
- if (SECSuccess == rv)
- {
- /* first, count the number of entries. Benchmarking showed that this
- counting pass is more efficient than trying to allocate entries as
- we read the DER, even if allocating many entries at a time
- */
- SECItem counter = group;
- do
- {
- SECItem anitem;
- rv = GetItem(&counter, &anitem, PR_TRUE);
- if (SECSuccess == rv && (anitem.len) )
- {
- totalEntries++;
- }
- } while ( (SECSuccess == rv) && (counter.len) );
-
- if (SECSuccess == rv)
- {
- /* allocate room for pointer array and entries */
- /* we want to allocate the array even if there is 0 entry */
- entries = (void**)PORT_ArenaZAlloc(arena, sizeof(void*)*
- (totalEntries + 1 ) + /* the extra one is for NULL termination */
- subTemplate->size*totalEntries);
-
- if (entries)
- {
- entries[totalEntries] = NULL; /* terminate the array */
- }
- else
- {
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- rv = SECFailure;
- }
- if (SECSuccess == rv)
- {
- void* entriesData = (unsigned char*)entries + (unsigned long)(sizeof(void*)*(totalEntries + 1 ));
- /* and fix the pointers in the array */
- PRUint32 entriesIndex = 0;
- for (entriesIndex = 0;entriesIndex<totalEntries;entriesIndex++)
- {
- entries[entriesIndex] =
- (char*)entriesData + (subTemplate->size*entriesIndex);
- }
- }
- }
- }
-
- if (SECSuccess == rv && totalEntries)
- do
- {
- if (!(entryIndex<totalEntries))
- {
- rv = SECFailure;
- break;
- }
- rv = DecodeItem(entries[entryIndex++], subTemplate, &group, arena, PR_TRUE);
- } while ( (SECSuccess == rv) && (group.len) );
- /* we should be at the end of the set by now */
- /* save the entries where requested */
- memcpy(((char*)dest + templateEntry->offset), &entries, sizeof(void**));
-
- return rv;
-}
-
-static SECStatus DecodeExplicit(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PRArenaPool* arena)
-{
- SECStatus rv = SECSuccess;
- SECItem subItem;
- SECItem constructed = *src;
-
- rv = GetItem(&constructed, &subItem, PR_FALSE);
-
- if (SECSuccess == rv)
- {
- if (templateEntry->kind & SEC_ASN1_POINTER)
- {
- rv = DecodePointer(dest, templateEntry, &subItem, arena, PR_TRUE);
- }
- else
- {
- rv = DecodeInline(dest, templateEntry, &subItem, arena, PR_TRUE);
- }
- }
-
- return rv;
-}
-
-/* new decoder implementation. This is a recursive function */
-
-static SECStatus DecodeItem(void* dest,
- const SEC_ASN1Template* templateEntry,
- SECItem* src, PRArenaPool* arena, PRBool checkTag)
-{
- SECStatus rv = SECSuccess;
- SECItem temp;
- SECItem mark;
- PRBool pop = PR_FALSE;
- PRBool decode = PR_TRUE;
- PRBool save = PR_FALSE;
- unsigned long kind;
- PRBool match = PR_TRUE;
- PRBool optional = PR_FALSE;
-
- PR_ASSERT(src && dest && templateEntry && arena);
-#if 0
- if (!src || !dest || !templateEntry || !arena)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
-#endif
-
- if (SECSuccess == rv)
- {
- /* do the template validation */
- kind = templateEntry->kind;
- optional = (0 != (kind & SEC_ASN1_OPTIONAL));
- if (!kind)
- {
- PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
- rv = SECFailure;
- }
- }
-
- if (SECSuccess == rv)
- {
-#ifdef DEBUG
- if (kind & SEC_ASN1_DEBUG_BREAK)
- {
- /* when debugging the decoder or a template that fails to
- decode, put SEC_ASN1_DEBUG in the component that gives you
- trouble. The decoder will then get to this block and assert.
- If you want to debug the rest of the code, you can set a
- breakpoint and set dontassert to PR_TRUE, which will let
- you skip over the assert and continue the debugging session
- past it. */
- PRBool dontassert = PR_FALSE;
- PR_ASSERT(dontassert); /* set bkpoint here & set dontassert*/
- }
-#endif
-
- if ((kind & SEC_ASN1_SKIP) ||
- (kind & SEC_ASN1_SAVE))
- {
- /* if skipping or saving this component, don't decode it */
- decode = PR_FALSE;
- }
-
- if (kind & (SEC_ASN1_SAVE | SEC_ASN1_OPTIONAL))
- {
- /* if saving this component, or if it is optional, we may not want to
- move past it, so save the position in case we have to rewind */
- mark = *src;
- if (kind & SEC_ASN1_SAVE)
- {
- save = PR_TRUE;
- if (0 == (kind & SEC_ASN1_SKIP))
- {
- /* we will for sure have to rewind when saving this
- component and not skipping it. This is true for all
- legacy uses of SEC_ASN1_SAVE where the following entry
- in the template would causes the same component to be
- processed again */
- pop = PR_TRUE;
- }
- }
- }
-
- rv = GetItem(src, &temp, PR_TRUE);
- }
-
- if (SECSuccess == rv)
- {
- /* now check if the component matches what we expect in the template */
-
- if (PR_TRUE == checkTag)
-
- {
- rv = MatchComponentType(templateEntry, &temp, &match, dest);
- }
-
- if ( (SECSuccess == rv) && (PR_TRUE != match) )
- {
- if (kind & SEC_ASN1_OPTIONAL)
- {
-
- /* the optional component is missing. This is not fatal. */
- /* Rewind, don't decode, and don't save */
- pop = PR_TRUE;
- decode = PR_FALSE;
- save = PR_FALSE;
- }
- else
- {
- /* a required component is missing. abort */
- PORT_SetError(SEC_ERROR_BAD_DER);
- rv = SECFailure;
- }
- }
- }
-
- if ((SECSuccess == rv) && (PR_TRUE == decode))
- {
- /* the order of processing here is is the tricky part */
- /* we start with our special cases */
- /* first, check the component class */
- if (kind & SEC_ASN1_INLINE)
- {
- /* decode inline template */
- rv = DecodeInline(dest, templateEntry, &temp , arena, PR_TRUE);
- }
-
- else
- if (kind & SEC_ASN1_EXPLICIT)
- {
- rv = DecodeExplicit(dest, templateEntry, &temp, arena);
- }
- else
- if ( (SEC_ASN1_UNIVERSAL != (kind & SEC_ASN1_CLASS_MASK)) &&
-
- (!(kind & SEC_ASN1_EXPLICIT)))
- {
-
- /* decode implicitly tagged components */
- rv = DecodeImplicit(dest, templateEntry, &temp , arena);
- }
- else
- if (kind & SEC_ASN1_POINTER)
- {
- rv = DecodePointer(dest, templateEntry, &temp, arena, PR_TRUE);
- }
- else
- if (kind & SEC_ASN1_CHOICE)
- {
- rv = DecodeChoice(dest, templateEntry, &temp, arena);
- }
- else
- if (kind & SEC_ASN1_ANY)
- {
- /* catch-all ANY type, don't decode */
- save = PR_TRUE;
- if (kind & SEC_ASN1_INNER)
- {
- /* skip the tag and length */
- SECItem newtemp = temp;
- rv = GetItem(&newtemp, &temp, PR_FALSE);
- }
- }
- else
- if (kind & SEC_ASN1_GROUP)
- {
- if ( (SEC_ASN1_SEQUENCE == (kind & SEC_ASN1_TAGNUM_MASK)) ||
- (SEC_ASN1_SET == (kind & SEC_ASN1_TAGNUM_MASK)) )
- {
- rv = DecodeGroup(dest, templateEntry, &temp , arena);
- }
- else
- {
- /* a group can only be a SET OF or SEQUENCE OF */
- PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
- rv = SECFailure;
- }
- }
- else
- if (SEC_ASN1_SEQUENCE == (kind & SEC_ASN1_TAGNUM_MASK))
- {
- /* plain SEQUENCE */
- rv = DecodeSequence(dest, templateEntry, &temp , arena);
- }
- else
- {
- /* handle all other types as "save" */
- /* we should only get here for primitive universal types */
- SECItem newtemp = temp;
- rv = GetItem(&newtemp, &temp, PR_FALSE);
- save = PR_TRUE;
- if ((SECSuccess == rv) &&
- SEC_ASN1_UNIVERSAL == (kind & SEC_ASN1_CLASS_MASK))
- {
- unsigned long tagnum = kind & SEC_ASN1_TAGNUM_MASK;
- if ( temp.len == 0 && (tagnum == SEC_ASN1_BOOLEAN ||
- tagnum == SEC_ASN1_INTEGER ||
- tagnum == SEC_ASN1_BIT_STRING ||
- tagnum == SEC_ASN1_OBJECT_ID ||
- tagnum == SEC_ASN1_ENUMERATED ||
- tagnum == SEC_ASN1_UTC_TIME ||
- tagnum == SEC_ASN1_GENERALIZED_TIME) )
- {
- /* these types MUST have at least one content octet */
- PORT_SetError(SEC_ERROR_BAD_DER);
- rv = SECFailure;
- }
- else
- switch (tagnum)
- {
- /* special cases of primitive types */
- case SEC_ASN1_INTEGER:
- {
- /* remove leading zeroes if the caller requested
- siUnsignedInteger
- This is to allow RSA key operations to work */
- SECItem* destItem = (SECItem*) ((char*)dest +
- templateEntry->offset);
- if (destItem && (siUnsignedInteger == destItem->type))
- {
- while (temp.len > 1 && temp.data[0] == 0)
- { /* leading 0 */
- temp.data++;
- temp.len--;
- }
- }
- break;
- }
-
- case SEC_ASN1_BIT_STRING:
- {
- /* change the length in the SECItem to be the number
- of bits */
- temp.len = (temp.len-1)*8 - (temp.data[0] & 0x7);
- temp.data++;
- break;
- }
-
- default:
- {
- break;
- }
- }
- }
- }
- }
-
- if ((SECSuccess == rv) && (PR_TRUE == save))
- {
- SECItem* destItem = (SECItem*) ((char*)dest + templateEntry->offset);
- if (destItem)
- {
- /* we leave the type alone in the destination SECItem.
- If part of the destination was allocated by the decoder, in
- cases of POINTER, SET OF and SEQUENCE OF, then type is set to
- siBuffer due to the use of PORT_ArenaZAlloc*/
- destItem->data = temp.len ? temp.data : NULL;
- destItem->len = temp.len;
- }
- else
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
- }
-
- if (PR_TRUE == pop)
- {
- /* we don't want to move ahead, so restore the position */
- *src = mark;
- }
- return rv;
-}
-
-/* the function below is the public one */
-
-SECStatus SEC_QuickDERDecodeItem(PRArenaPool* arena, void* dest,
- const SEC_ASN1Template* templateEntry,
- const SECItem* src)
-{
- SECStatus rv = SECSuccess;
- SECItem newsrc;
-
- if (!arena || !templateEntry || !src)
- {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- rv = SECFailure;
- }
-
- if (SECSuccess == rv)
- {
- newsrc = *src;
- rv = DecodeItem(dest, templateEntry, &newsrc, arena, PR_TRUE);
- if (SECSuccess == rv && newsrc.len)
- {
- rv = SECFailure;
- PORT_SetError(SEC_ERROR_EXTRA_INPUT);
- }
- }
-
- return rv;
-}
-
diff --git a/security/nss/lib/util/secalgid.c b/security/nss/lib/util/secalgid.c
deleted file mode 100644
index d7a1259d7..000000000
--- a/security/nss/lib/util/secalgid.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secoid.h"
-#include "secder.h" /* XXX remove this when remove the DERTemplate */
-#include "secasn1.h"
-#include "secitem.h"
-#include "secerr.h"
-
-SECOidTag
-SECOID_GetAlgorithmTag(SECAlgorithmID *id)
-{
- if (id == NULL || id->algorithm.data == NULL)
- return SEC_OID_UNKNOWN;
-
- return SECOID_FindOIDTag (&(id->algorithm));
-}
-
-SECStatus
-SECOID_SetAlgorithmID(PRArenaPool *arena, SECAlgorithmID *id, SECOidTag which,
- SECItem *params)
-{
- SECOidData *oiddata;
- PRBool add_null_param;
-
- oiddata = SECOID_FindOIDByTag(which);
- if ( !oiddata ) {
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return SECFailure;
- }
-
- if (SECITEM_CopyItem(arena, &id->algorithm, &oiddata->oid))
- return SECFailure;
-
- switch (which) {
- case SEC_OID_MD2:
- case SEC_OID_MD4:
- case SEC_OID_MD5:
- case SEC_OID_SHA1:
- case SEC_OID_SHA224:
- case SEC_OID_SHA256:
- case SEC_OID_SHA384:
- case SEC_OID_SHA512:
- case SEC_OID_PKCS1_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
- case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
- add_null_param = PR_TRUE;
- break;
- default:
- add_null_param = PR_FALSE;
- break;
- }
-
- if (params) {
- /*
- * I am specifically *not* enforcing the following assertion
- * (by following it up with an error and a return of failure)
- * because I do not want to introduce any change in the current
- * behavior. But I do want for us to notice if the following is
- * ever true, because I do not think it should be so and probably
- * signifies an error/bug somewhere.
- */
- PORT_Assert(!add_null_param || (params->len == 2
- && params->data[0] == SEC_ASN1_NULL
- && params->data[1] == 0));
- if (SECITEM_CopyItem(arena, &id->parameters, params)) {
- return SECFailure;
- }
- } else {
- /*
- * Again, this is not considered an error. But if we assume
- * that nobody tries to set the parameters field themselves
- * (but always uses this routine to do that), then we should
- * not hit the following assertion. Unless they forgot to zero
- * the structure, which could also be a bad (and wrong) thing.
- */
- PORT_Assert(id->parameters.data == NULL);
-
- if (add_null_param) {
- (void) SECITEM_AllocItem(arena, &id->parameters, 2);
- if (id->parameters.data == NULL) {
- return SECFailure;
- }
- id->parameters.data[0] = SEC_ASN1_NULL;
- id->parameters.data[1] = 0;
- }
- }
-
- return SECSuccess;
-}
-
-SECStatus
-SECOID_CopyAlgorithmID(PRArenaPool *arena, SECAlgorithmID *to, SECAlgorithmID *from)
-{
- SECStatus rv;
-
- rv = SECITEM_CopyItem(arena, &to->algorithm, &from->algorithm);
- if (rv) return rv;
- rv = SECITEM_CopyItem(arena, &to->parameters, &from->parameters);
- return rv;
-}
-
-void SECOID_DestroyAlgorithmID(SECAlgorithmID *algid, PRBool freeit)
-{
- SECITEM_FreeItem(&algid->parameters, PR_FALSE);
- SECITEM_FreeItem(&algid->algorithm, PR_FALSE);
- if(freeit == PR_TRUE)
- PORT_Free(algid);
-}
-
-SECComparison
-SECOID_CompareAlgorithmID(SECAlgorithmID *a, SECAlgorithmID *b)
-{
- SECComparison rv;
-
- rv = SECITEM_CompareItem(&a->algorithm, &b->algorithm);
- if (rv) return rv;
- rv = SECITEM_CompareItem(&a->parameters, &b->parameters);
- return rv;
-}
diff --git a/security/nss/lib/util/secasn1.h b/security/nss/lib/util/secasn1.h
deleted file mode 100644
index 7b3dd0ed5..000000000
--- a/security/nss/lib/util/secasn1.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Support for encoding/decoding of ASN.1 using BER/DER (Basic/Distinguished
- * Encoding Rules). The routines are found in and used extensively by the
- * security library, but exported for other use.
- *
- * $Id$
- */
-
-#ifndef _SECASN1_H_
-#define _SECASN1_H_
-
-#include "utilrename.h"
-#include "plarena.h"
-
-#include "seccomon.h"
-#include "secasn1t.h"
-
-
-/************************************************************************/
-SEC_BEGIN_PROTOS
-
-/*
- * XXX These function prototypes need full, explanatory comments.
- */
-
-/*
-** Decoding.
-*/
-
-extern SEC_ASN1DecoderContext *SEC_ASN1DecoderStart(PLArenaPool *pool,
- void *dest,
- const SEC_ASN1Template *t);
-
-/* XXX char or unsigned char? */
-extern SECStatus SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx,
- const char *buf,
- unsigned long len);
-
-extern SECStatus SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx);
-
-/* Higher level code detected an error, abort the rest of the processing */
-extern void SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error);
-
-extern void SEC_ASN1DecoderSetFilterProc(SEC_ASN1DecoderContext *cx,
- SEC_ASN1WriteProc fn,
- void *arg, PRBool no_store);
-
-extern void SEC_ASN1DecoderClearFilterProc(SEC_ASN1DecoderContext *cx);
-
-extern void SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx,
- SEC_ASN1NotifyProc fn,
- void *arg);
-
-extern void SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx);
-
-extern SECStatus SEC_ASN1Decode(PLArenaPool *pool, void *dest,
- const SEC_ASN1Template *t,
- const char *buf, long len);
-
-/* Both classic ASN.1 and QuickDER have a feature that removes leading zeroes
- out of SEC_ASN1_INTEGER if the caller sets siUnsignedInteger in the type
- field of the target SECItem prior to calling the decoder. Otherwise, the
- type field is ignored and untouched. For SECItem that are dynamically
- allocated (from POINTER, SET OF, SEQUENCE OF) the decoder sets the type
- field to siBuffer. */
-
-extern SECStatus SEC_ASN1DecodeItem(PLArenaPool *pool, void *dest,
- const SEC_ASN1Template *t,
- const SECItem *src);
-
-extern SECStatus SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest,
- const SEC_ASN1Template* templateEntry,
- const SECItem* src);
-
-/*
-** Encoding.
-*/
-
-extern SEC_ASN1EncoderContext *SEC_ASN1EncoderStart(const void *src,
- const SEC_ASN1Template *t,
- SEC_ASN1WriteProc fn,
- void *output_arg);
-
-/* XXX char or unsigned char? */
-extern SECStatus SEC_ASN1EncoderUpdate(SEC_ASN1EncoderContext *cx,
- const char *buf,
- unsigned long len);
-
-extern void SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx);
-
-/* Higher level code detected an error, abort the rest of the processing */
-extern void SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error);
-
-extern void SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx,
- SEC_ASN1NotifyProc fn,
- void *arg);
-
-extern void SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx);
-
-extern void SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx);
-
-extern void SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx);
-
-extern void sec_ASN1EncoderSetDER(SEC_ASN1EncoderContext *cx);
-
-extern void sec_ASN1EncoderClearDER(SEC_ASN1EncoderContext *cx);
-
-extern void SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx);
-
-extern void SEC_ASN1EncoderClearTakeFromBuf(SEC_ASN1EncoderContext *cx);
-
-extern SECStatus SEC_ASN1Encode(const void *src, const SEC_ASN1Template *t,
- SEC_ASN1WriteProc output_proc,
- void *output_arg);
-
-/*
- * If both pool and dest are NULL, the caller should free the returned SECItem
- * with a SECITEM_FreeItem(..., PR_TRUE) call. If pool is NULL but dest is
- * not NULL, the caller should free the data buffer pointed to by dest with a
- * SECITEM_FreeItem(dest, PR_FALSE) or PORT_Free(dest->data) call.
- */
-extern SECItem * SEC_ASN1EncodeItem(PLArenaPool *pool, SECItem *dest,
- const void *src, const SEC_ASN1Template *t);
-
-extern SECItem * SEC_ASN1EncodeInteger(PLArenaPool *pool,
- SECItem *dest, long value);
-
-extern SECItem * SEC_ASN1EncodeUnsignedInteger(PLArenaPool *pool,
- SECItem *dest,
- unsigned long value);
-
-extern SECStatus SEC_ASN1DecodeInteger(SECItem *src,
- unsigned long *value);
-
-/*
-** Utilities.
-*/
-
-/*
- * We have a length that needs to be encoded; how many bytes will the
- * encoding take?
- */
-extern int SEC_ASN1LengthLength (unsigned long len);
-
-/* encode the length and return the number of bytes we encoded. Buffer
- * must be pre allocated */
-extern int SEC_ASN1EncodeLength(unsigned char *buf,int value);
-
-/*
- * Find the appropriate subtemplate for the given template.
- * This may involve calling a "chooser" function, or it may just
- * be right there. In either case, it is expected to *have* a
- * subtemplate; this is asserted in debug builds (in non-debug
- * builds, NULL will be returned).
- *
- * "thing" is a pointer to the structure being encoded/decoded
- * "encoding", when true, means that we are in the process of encoding
- * (as opposed to in the process of decoding)
- */
-extern const SEC_ASN1Template *
-SEC_ASN1GetSubtemplate (const SEC_ASN1Template *inTemplate, void *thing,
- PRBool encoding);
-
-/* whether the template is for a primitive type or a choice of
- * primitive types
- */
-extern PRBool SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate);
-
-/************************************************************************/
-
-/*
- * Generic Templates
- * One for each of the simple types, plus a special one for ANY, plus:
- * - a pointer to each one of those
- * - a set of each one of those
- * - a sequence of each one of those
- *
- * Note that these are alphabetical (case insensitive); please add new
- * ones in the appropriate place.
- */
-
-extern const SEC_ASN1Template SEC_AnyTemplate[];
-extern const SEC_ASN1Template SEC_BitStringTemplate[];
-extern const SEC_ASN1Template SEC_BMPStringTemplate[];
-extern const SEC_ASN1Template SEC_BooleanTemplate[];
-extern const SEC_ASN1Template SEC_EnumeratedTemplate[];
-extern const SEC_ASN1Template SEC_GeneralizedTimeTemplate[];
-extern const SEC_ASN1Template SEC_IA5StringTemplate[];
-extern const SEC_ASN1Template SEC_IntegerTemplate[];
-extern const SEC_ASN1Template SEC_NullTemplate[];
-extern const SEC_ASN1Template SEC_ObjectIDTemplate[];
-extern const SEC_ASN1Template SEC_OctetStringTemplate[];
-extern const SEC_ASN1Template SEC_PrintableStringTemplate[];
-extern const SEC_ASN1Template SEC_T61StringTemplate[];
-extern const SEC_ASN1Template SEC_UniversalStringTemplate[];
-extern const SEC_ASN1Template SEC_UTCTimeTemplate[];
-extern const SEC_ASN1Template SEC_UTF8StringTemplate[];
-extern const SEC_ASN1Template SEC_VisibleStringTemplate[];
-
-extern const SEC_ASN1Template SEC_PointerToAnyTemplate[];
-extern const SEC_ASN1Template SEC_PointerToBitStringTemplate[];
-extern const SEC_ASN1Template SEC_PointerToBMPStringTemplate[];
-extern const SEC_ASN1Template SEC_PointerToBooleanTemplate[];
-extern const SEC_ASN1Template SEC_PointerToEnumeratedTemplate[];
-extern const SEC_ASN1Template SEC_PointerToGeneralizedTimeTemplate[];
-extern const SEC_ASN1Template SEC_PointerToIA5StringTemplate[];
-extern const SEC_ASN1Template SEC_PointerToIntegerTemplate[];
-extern const SEC_ASN1Template SEC_PointerToNullTemplate[];
-extern const SEC_ASN1Template SEC_PointerToObjectIDTemplate[];
-extern const SEC_ASN1Template SEC_PointerToOctetStringTemplate[];
-extern const SEC_ASN1Template SEC_PointerToPrintableStringTemplate[];
-extern const SEC_ASN1Template SEC_PointerToT61StringTemplate[];
-extern const SEC_ASN1Template SEC_PointerToUniversalStringTemplate[];
-extern const SEC_ASN1Template SEC_PointerToUTCTimeTemplate[];
-extern const SEC_ASN1Template SEC_PointerToUTF8StringTemplate[];
-extern const SEC_ASN1Template SEC_PointerToVisibleStringTemplate[];
-
-extern const SEC_ASN1Template SEC_SequenceOfAnyTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfBitStringTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfBMPStringTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfBooleanTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfEnumeratedTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfGeneralizedTimeTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfIA5StringTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfIntegerTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfNullTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfObjectIDTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfOctetStringTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfPrintableStringTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfT61StringTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfUniversalStringTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfUTCTimeTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfUTF8StringTemplate[];
-extern const SEC_ASN1Template SEC_SequenceOfVisibleStringTemplate[];
-
-extern const SEC_ASN1Template SEC_SetOfAnyTemplate[];
-extern const SEC_ASN1Template SEC_SetOfBitStringTemplate[];
-extern const SEC_ASN1Template SEC_SetOfBMPStringTemplate[];
-extern const SEC_ASN1Template SEC_SetOfBooleanTemplate[];
-extern const SEC_ASN1Template SEC_SetOfEnumeratedTemplate[];
-extern const SEC_ASN1Template SEC_SetOfGeneralizedTimeTemplate[];
-extern const SEC_ASN1Template SEC_SetOfIA5StringTemplate[];
-extern const SEC_ASN1Template SEC_SetOfIntegerTemplate[];
-extern const SEC_ASN1Template SEC_SetOfNullTemplate[];
-extern const SEC_ASN1Template SEC_SetOfObjectIDTemplate[];
-extern const SEC_ASN1Template SEC_SetOfOctetStringTemplate[];
-extern const SEC_ASN1Template SEC_SetOfPrintableStringTemplate[];
-extern const SEC_ASN1Template SEC_SetOfT61StringTemplate[];
-extern const SEC_ASN1Template SEC_SetOfUniversalStringTemplate[];
-extern const SEC_ASN1Template SEC_SetOfUTCTimeTemplate[];
-extern const SEC_ASN1Template SEC_SetOfUTF8StringTemplate[];
-extern const SEC_ASN1Template SEC_SetOfVisibleStringTemplate[];
-
-/*
- * Template for skipping a subitem; this only makes sense when decoding.
- */
-extern const SEC_ASN1Template SEC_SkipTemplate[];
-
-/* These functions simply return the address of the above-declared templates.
-** This is necessary for Windows DLLs. Sigh.
-*/
-SEC_ASN1_CHOOSER_DECLARE(SEC_AnyTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_BMPStringTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_BooleanTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_BitStringTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_GeneralizedTimeTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_IA5StringTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_IntegerTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_NullTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_ObjectIDTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_OctetStringTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_UTCTimeTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_UTF8StringTemplate)
-
-SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToAnyTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToOctetStringTemplate)
-
-SEC_ASN1_CHOOSER_DECLARE(SEC_SetOfAnyTemplate)
-
-SEC_ASN1_CHOOSER_DECLARE(SEC_EnumeratedTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToEnumeratedTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfAnyTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_SequenceOfObjectIDTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_SkipTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_UniversalStringTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_PrintableStringTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_T61StringTemplate)
-SEC_ASN1_CHOOSER_DECLARE(SEC_PointerToGeneralizedTimeTemplate)
-SEC_END_PROTOS
-#endif /* _SECASN1_H_ */
diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c
deleted file mode 100644
index 9e751df20..000000000
--- a/security/nss/lib/util/secasn1d.c
+++ /dev/null
@@ -1,3237 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Support for DEcoding ASN.1 data based on BER/DER (Basic/Distinguished
- * Encoding Rules).
- *
- * $Id$
- */
-
-/* #define DEBUG_ASN1D_STATES 1 */
-
-#ifdef DEBUG_ASN1D_STATES
-#include <stdio.h>
-#define PR_Assert sec_asn1d_Assert
-#endif
-
-#include "secasn1.h"
-#include "secerr.h"
-
-typedef enum {
- beforeIdentifier,
- duringIdentifier,
- afterIdentifier,
- beforeLength,
- duringLength,
- afterLength,
- beforeBitString,
- duringBitString,
- duringConstructedString,
- duringGroup,
- duringLeaf,
- duringSaveEncoding,
- duringSequence,
- afterConstructedString,
- afterGroup,
- afterExplicit,
- afterImplicit,
- afterInline,
- afterPointer,
- afterSaveEncoding,
- beforeEndOfContents,
- duringEndOfContents,
- afterEndOfContents,
- beforeChoice,
- duringChoice,
- afterChoice,
- notInUse
-} sec_asn1d_parse_place;
-
-#ifdef DEBUG_ASN1D_STATES
-static const char * const place_names[] = {
- "beforeIdentifier",
- "duringIdentifier",
- "afterIdentifier",
- "beforeLength",
- "duringLength",
- "afterLength",
- "beforeBitString",
- "duringBitString",
- "duringConstructedString",
- "duringGroup",
- "duringLeaf",
- "duringSaveEncoding",
- "duringSequence",
- "afterConstructedString",
- "afterGroup",
- "afterExplicit",
- "afterImplicit",
- "afterInline",
- "afterPointer",
- "afterSaveEncoding",
- "beforeEndOfContents",
- "duringEndOfContents",
- "afterEndOfContents",
- "beforeChoice",
- "duringChoice",
- "afterChoice",
- "notInUse"
-};
-
-static const char * const class_names[] = {
- "UNIVERSAL",
- "APPLICATION",
- "CONTEXT_SPECIFIC",
- "PRIVATE"
-};
-
-static const char * const method_names[] = { "PRIMITIVE", "CONSTRUCTED" };
-
-static const char * const type_names[] = {
- "END_OF_CONTENTS",
- "BOOLEAN",
- "INTEGER",
- "BIT_STRING",
- "OCTET_STRING",
- "NULL",
- "OBJECT_ID",
- "OBJECT_DESCRIPTOR",
- "(type 08)",
- "REAL",
- "ENUMERATED",
- "EMBEDDED",
- "UTF8_STRING",
- "(type 0d)",
- "(type 0e)",
- "(type 0f)",
- "SEQUENCE",
- "SET",
- "NUMERIC_STRING",
- "PRINTABLE_STRING",
- "T61_STRING",
- "VIDEOTEXT_STRING",
- "IA5_STRING",
- "UTC_TIME",
- "GENERALIZED_TIME",
- "GRAPHIC_STRING",
- "VISIBLE_STRING",
- "GENERAL_STRING",
- "UNIVERSAL_STRING",
- "(type 1d)",
- "BMP_STRING",
- "HIGH_TAG_VALUE"
-};
-
-static const char * const flag_names[] = { /* flags, right to left */
- "OPTIONAL",
- "EXPLICIT",
- "ANY",
- "INLINE",
- "POINTER",
- "GROUP",
- "DYNAMIC",
- "SKIP",
- "INNER",
- "SAVE",
- "", /* decoder ignores "MAY_STREAM", */
- "SKIP_REST",
- "CHOICE",
- "NO_STREAM",
- "DEBUG_BREAK",
- "unknown 08",
- "unknown 10",
- "unknown 20",
- "unknown 40",
- "unknown 80"
-};
-
-static int /* bool */
-formatKind(unsigned long kind, char * buf)
-{
- int i;
- unsigned long k = kind & SEC_ASN1_TAGNUM_MASK;
- unsigned long notag = kind & (SEC_ASN1_CHOICE | SEC_ASN1_POINTER |
- SEC_ASN1_INLINE | SEC_ASN1_ANY | SEC_ASN1_SAVE);
-
- buf[0] = 0;
- if ((kind & SEC_ASN1_CLASS_MASK) != SEC_ASN1_UNIVERSAL) {
- sprintf(buf, " %s", class_names[(kind & SEC_ASN1_CLASS_MASK) >> 6] );
- buf += strlen(buf);
- }
- if (kind & SEC_ASN1_METHOD_MASK) {
- sprintf(buf, " %s", method_names[1]);
- buf += strlen(buf);
- }
- if ((kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) {
- if (k || !notag) {
- sprintf(buf, " %s", type_names[k] );
- if ((k == SEC_ASN1_SET || k == SEC_ASN1_SEQUENCE) &&
- (kind & SEC_ASN1_GROUP)) {
- buf += strlen(buf);
- sprintf(buf, "_OF");
- }
- }
- } else {
- sprintf(buf, " [%d]", k);
- }
- buf += strlen(buf);
-
- for (k = kind >> 8, i = 0; k; k >>= 1, ++i) {
- if (k & 1) {
- sprintf(buf, " %s", flag_names[i]);
- buf += strlen(buf);
- }
- }
- return notag != 0;
-}
-
-#endif /* DEBUG_ASN1D_STATES */
-
-typedef enum {
- allDone,
- decodeError,
- keepGoing,
- needBytes
-} sec_asn1d_parse_status;
-
-struct subitem {
- const void *data;
- unsigned long len; /* only used for substrings */
- struct subitem *next;
-};
-
-typedef struct sec_asn1d_state_struct {
- SEC_ASN1DecoderContext *top;
- const SEC_ASN1Template *theTemplate;
- void *dest;
-
- void *our_mark; /* free on completion */
-
- struct sec_asn1d_state_struct *parent; /* aka prev */
- struct sec_asn1d_state_struct *child; /* aka next */
-
- sec_asn1d_parse_place place;
-
- /*
- * XXX explain the next fields as clearly as possible...
- */
- unsigned char found_tag_modifiers;
- unsigned char expect_tag_modifiers;
- unsigned long check_tag_mask;
- unsigned long found_tag_number;
- unsigned long expect_tag_number;
- unsigned long underlying_kind;
-
- unsigned long contents_length;
- unsigned long pending;
- unsigned long consumed;
-
- int depth;
-
- /*
- * Bit strings have their length adjusted -- the first octet of the
- * contents contains a value between 0 and 7 which says how many bits
- * at the end of the octets are not actually part of the bit string;
- * when parsing bit strings we put that value here because we need it
- * later, for adjustment of the length (when the whole string is done).
- */
- unsigned int bit_string_unused_bits;
-
- /*
- * The following are used for indefinite-length constructed strings.
- */
- struct subitem *subitems_head;
- struct subitem *subitems_tail;
-
- PRPackedBool
- allocate, /* when true, need to allocate the destination */
- endofcontents, /* this state ended up parsing end-of-contents octets */
- explicit, /* we are handling an explicit header */
- indefinite, /* the current item has indefinite-length encoding */
- missing, /* an optional field that was not present */
- optional, /* the template says this field may be omitted */
- substring; /* this is a substring of a constructed string */
-
-} sec_asn1d_state;
-
-#define IS_HIGH_TAG_NUMBER(n) ((n) == SEC_ASN1_HIGH_TAG_NUMBER)
-#define LAST_TAG_NUMBER_BYTE(b) (((b) & 0x80) == 0)
-#define TAG_NUMBER_BITS 7
-#define TAG_NUMBER_MASK 0x7f
-
-#define LENGTH_IS_SHORT_FORM(b) (((b) & 0x80) == 0)
-#define LONG_FORM_LENGTH(b) ((b) & 0x7f)
-
-#define HIGH_BITS(field,cnt) ((field) >> ((sizeof(field) * 8) - (cnt)))
-
-
-/*
- * An "outsider" will have an opaque pointer to this, created by calling
- * SEC_ASN1DecoderStart(). It will be passed back in to all subsequent
- * calls to SEC_ASN1DecoderUpdate(), and when done it is passed to
- * SEC_ASN1DecoderFinish().
- */
-struct sec_DecoderContext_struct {
- PRArenaPool *our_pool; /* for our internal allocs */
- PRArenaPool *their_pool; /* for destination structure allocs */
-#ifdef SEC_ASN1D_FREE_ON_ERROR /*
- * XXX see comment below (by same
- * ifdef) that explains why this
- * does not work (need more smarts
- * in order to free back to mark)
- */
- /*
- * XXX how to make their_mark work in the case where they do NOT
- * give us a pool pointer?
- */
- void *their_mark; /* free on error */
-#endif
-
- sec_asn1d_state *current;
- sec_asn1d_parse_status status;
-
- SEC_ASN1NotifyProc notify_proc; /* call before/after handling field */
- void *notify_arg; /* argument to notify_proc */
- PRBool during_notify; /* true during call to notify_proc */
-
- SEC_ASN1WriteProc filter_proc; /* pass field bytes to this */
- void *filter_arg; /* argument to that function */
- PRBool filter_only; /* do not allocate/store fields */
-};
-
-
-/*
- * XXX this is a fairly generic function that may belong elsewhere
- */
-static void *
-sec_asn1d_alloc (PRArenaPool *poolp, unsigned long len)
-{
- void *thing;
-
- if (poolp != NULL) {
- /*
- * Allocate from the pool.
- */
- thing = PORT_ArenaAlloc (poolp, len);
- } else {
- /*
- * Allocate generically.
- */
- thing = PORT_Alloc (len);
- }
-
- return thing;
-}
-
-
-/*
- * XXX this is a fairly generic function that may belong elsewhere
- */
-static void *
-sec_asn1d_zalloc (PRArenaPool *poolp, unsigned long len)
-{
- void *thing;
-
- thing = sec_asn1d_alloc (poolp, len);
- if (thing != NULL)
- PORT_Memset (thing, 0, len);
- return thing;
-}
-
-
-static sec_asn1d_state *
-sec_asn1d_push_state (SEC_ASN1DecoderContext *cx,
- const SEC_ASN1Template *theTemplate,
- void *dest, PRBool new_depth)
-{
- sec_asn1d_state *state, *new_state;
-
- state = cx->current;
-
- PORT_Assert (state == NULL || state->child == NULL);
-
- if (state != NULL) {
- PORT_Assert (state->our_mark == NULL);
- state->our_mark = PORT_ArenaMark (cx->our_pool);
- }
-
- new_state = (sec_asn1d_state*)sec_asn1d_zalloc (cx->our_pool,
- sizeof(*new_state));
- if (new_state == NULL) {
- goto loser;
- }
-
- new_state->top = cx;
- new_state->parent = state;
- new_state->theTemplate = theTemplate;
- new_state->place = notInUse;
- if (dest != NULL)
- new_state->dest = (char *)dest + theTemplate->offset;
-
- if (state != NULL) {
- new_state->depth = state->depth;
- if (new_depth) {
- if (++new_state->depth > SEC_ASN1D_MAX_DEPTH) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- goto loser;
- }
- }
- state->child = new_state;
- }
-
- cx->current = new_state;
- return new_state;
-
-loser:
- cx->status = decodeError;
- if (state != NULL) {
- PORT_ArenaRelease(cx->our_pool, state->our_mark);
- state->our_mark = NULL;
- }
- return NULL;
-}
-
-
-static void
-sec_asn1d_scrub_state (sec_asn1d_state *state)
-{
- /*
- * Some default "scrubbing".
- * XXX right set of initializations?
- */
- state->place = beforeIdentifier;
- state->endofcontents = PR_FALSE;
- state->indefinite = PR_FALSE;
- state->missing = PR_FALSE;
- PORT_Assert (state->consumed == 0);
-}
-
-
-static void
-sec_asn1d_notify_before (SEC_ASN1DecoderContext *cx, void *dest, int depth)
-{
- if (cx->notify_proc == NULL)
- return;
-
- cx->during_notify = PR_TRUE;
- (* cx->notify_proc) (cx->notify_arg, PR_TRUE, dest, depth);
- cx->during_notify = PR_FALSE;
-}
-
-
-static void
-sec_asn1d_notify_after (SEC_ASN1DecoderContext *cx, void *dest, int depth)
-{
- if (cx->notify_proc == NULL)
- return;
-
- cx->during_notify = PR_TRUE;
- (* cx->notify_proc) (cx->notify_arg, PR_FALSE, dest, depth);
- cx->during_notify = PR_FALSE;
-}
-
-
-static sec_asn1d_state *
-sec_asn1d_init_state_based_on_template (sec_asn1d_state *state)
-{
- PRBool explicit, optional, universal;
- unsigned char expect_tag_modifiers;
- unsigned long encode_kind, under_kind;
- unsigned long check_tag_mask, expect_tag_number;
-
-
- /* XXX Check that both of these tests are really needed/appropriate. */
- if (state == NULL || state->top->status == decodeError)
- return state;
-
- encode_kind = state->theTemplate->kind;
-
- if (encode_kind & SEC_ASN1_SAVE) {
- /*
- * This is a "magic" field that saves away all bytes, allowing
- * the immediately following field to still be decoded from this
- * same spot -- sort of a fork.
- */
- /* check that there are no extraneous bits */
- PORT_Assert (encode_kind == SEC_ASN1_SAVE);
- if (state->top->filter_only) {
- /*
- * If we are not storing, then we do not do the SAVE field
- * at all. Just move ahead to the "real" field instead,
- * doing the appropriate notify calls before and after.
- */
- sec_asn1d_notify_after (state->top, state->dest, state->depth);
- /*
- * Since we are not storing, allow for our current dest value
- * to be NULL. (This might not actually occur, but right now I
- * cannot convince myself one way or the other.) If it is NULL,
- * assume that our parent dest can help us out.
- */
- if (state->dest == NULL)
- state->dest = state->parent->dest;
- else
- state->dest = (char *)state->dest - state->theTemplate->offset;
- state->theTemplate++;
- if (state->dest != NULL)
- state->dest = (char *)state->dest + state->theTemplate->offset;
- sec_asn1d_notify_before (state->top, state->dest, state->depth);
- encode_kind = state->theTemplate->kind;
- PORT_Assert ((encode_kind & SEC_ASN1_SAVE) == 0);
- } else {
- sec_asn1d_scrub_state (state);
- state->place = duringSaveEncoding;
- state = sec_asn1d_push_state (state->top, SEC_AnyTemplate,
- state->dest, PR_FALSE);
- if (state != NULL)
- state = sec_asn1d_init_state_based_on_template (state);
- return state;
- }
- }
-
-
- universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL)
- ? PR_TRUE : PR_FALSE;
-
- explicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~SEC_ASN1_EXPLICIT;
-
- optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~SEC_ASN1_OPTIONAL;
-
- PORT_Assert (!(explicit && universal)); /* bad templates */
-
- encode_kind &= ~SEC_ASN1_DYNAMIC;
- encode_kind &= ~SEC_ASN1_MAY_STREAM;
-
- if (encode_kind & SEC_ASN1_CHOICE) {
-#if 0 /* XXX remove? */
- sec_asn1d_state *child = sec_asn1d_push_state(state->top, state->theTemplate, state->dest, PR_FALSE);
- if ((sec_asn1d_state *)NULL == child) {
- return (sec_asn1d_state *)NULL;
- }
-
- child->allocate = state->allocate;
- child->place = beforeChoice;
- return child;
-#else
- state->place = beforeChoice;
- return state;
-#endif
- }
-
- if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || (!universal
- && !explicit)) {
- const SEC_ASN1Template *subt;
- void *dest;
- PRBool child_allocate;
-
- PORT_Assert ((encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) == 0);
-
- sec_asn1d_scrub_state (state);
- child_allocate = PR_FALSE;
-
- if (encode_kind & SEC_ASN1_POINTER) {
- /*
- * A POINTER means we need to allocate the destination for
- * this field. But, since it may also be an optional field,
- * we defer the allocation until later; we just record that
- * it needs to be done.
- *
- * There are two possible scenarios here -- one is just a
- * plain POINTER (kind of like INLINE, except with allocation)
- * and the other is an implicitly-tagged POINTER. We don't
- * need to do anything special here for the two cases, but
- * since the template definition can be tricky, we do check
- * that there are no extraneous bits set in encode_kind.
- *
- * XXX The same conditions which assert should set an error.
- */
- if (universal) {
- /*
- * "universal" means this entry is a standalone POINTER;
- * there should be no other bits set in encode_kind.
- */
- PORT_Assert (encode_kind == SEC_ASN1_POINTER);
- } else {
- /*
- * If we get here we have an implicitly-tagged field
- * that needs to be put into a POINTER. The subtemplate
- * will determine how to decode the field, but encode_kind
- * describes the (implicit) tag we are looking for.
- * The non-tag bits of encode_kind will be ignored by
- * the code below; none of them should be set, however,
- * except for the POINTER bit itself -- so check that.
- */
- PORT_Assert ((encode_kind & ~SEC_ASN1_TAG_MASK)
- == SEC_ASN1_POINTER);
- }
- if (!state->top->filter_only)
- child_allocate = PR_TRUE;
- dest = NULL;
- state->place = afterPointer;
- } else {
- dest = state->dest;
- if (encode_kind & SEC_ASN1_INLINE) {
- /* check that there are no extraneous bits */
- PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional);
- state->place = afterInline;
- } else {
- state->place = afterImplicit;
- }
- }
-
- state->optional = optional;
- subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->dest, PR_FALSE);
- state = sec_asn1d_push_state (state->top, subt, dest, PR_FALSE);
- if (state == NULL)
- return NULL;
-
- state->allocate = child_allocate;
-
- if (universal) {
- state = sec_asn1d_init_state_based_on_template (state);
- if (state != NULL) {
- /*
- * If this field is optional, we need to record that on
- * the pushed child so it won't fail if the field isn't
- * found. I can't think of a way that this new state
- * could already have optional set (which we would wipe
- * out below if our local optional is not set) -- but
- * just to be sure, assert that it isn't set.
- */
- PORT_Assert (!state->optional);
- state->optional = optional;
- }
- return state;
- }
-
- under_kind = state->theTemplate->kind;
- under_kind &= ~SEC_ASN1_MAY_STREAM;
- } else if (explicit) {
- /*
- * For explicit, we only need to match the encoding tag next,
- * then we will push another state to handle the entire inner
- * part. In this case, there is no underlying kind which plays
- * any part in the determination of the outer, explicit tag.
- * So we just set under_kind to 0, which is not a valid tag,
- * and the rest of the tag matching stuff should be okay.
- */
- under_kind = 0;
- } else {
- /*
- * Nothing special; the underlying kind and the given encoding
- * information are the same.
- */
- under_kind = encode_kind;
- }
-
- /* XXX is this the right set of bits to test here? */
- PORT_Assert ((under_kind & (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL
- | SEC_ASN1_MAY_STREAM
- | SEC_ASN1_INLINE | SEC_ASN1_POINTER)) == 0);
-
- if (encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) {
- PORT_Assert (encode_kind == under_kind);
- if (encode_kind & SEC_ASN1_SKIP) {
- PORT_Assert (!optional);
- PORT_Assert (encode_kind == SEC_ASN1_SKIP);
- state->dest = NULL;
- }
- check_tag_mask = 0;
- expect_tag_modifiers = 0;
- expect_tag_number = 0;
- } else {
- check_tag_mask = SEC_ASN1_TAG_MASK;
- expect_tag_modifiers = (unsigned char)encode_kind & SEC_ASN1_TAG_MASK
- & ~SEC_ASN1_TAGNUM_MASK;
- /*
- * XXX This assumes only single-octet identifiers. To handle
- * the HIGH TAG form we would need to do some more work, especially
- * in how to specify them in the template, because right now we
- * do not provide a way to specify more *tag* bits in encode_kind.
- */
- expect_tag_number = encode_kind & SEC_ASN1_TAGNUM_MASK;
-
- switch (under_kind & SEC_ASN1_TAGNUM_MASK) {
- case SEC_ASN1_SET:
- /*
- * XXX A plain old SET (as opposed to a SET OF) is not implemented.
- * If it ever is, remove this assert...
- */
- PORT_Assert ((under_kind & SEC_ASN1_GROUP) != 0);
- /* fallthru */
- case SEC_ASN1_SEQUENCE:
- expect_tag_modifiers |= SEC_ASN1_CONSTRUCTED;
- break;
- case SEC_ASN1_BIT_STRING:
- case SEC_ASN1_BMP_STRING:
- case SEC_ASN1_GENERALIZED_TIME:
- case SEC_ASN1_IA5_STRING:
- case SEC_ASN1_OCTET_STRING:
- case SEC_ASN1_PRINTABLE_STRING:
- case SEC_ASN1_T61_STRING:
- case SEC_ASN1_UNIVERSAL_STRING:
- case SEC_ASN1_UTC_TIME:
- case SEC_ASN1_UTF8_STRING:
- case SEC_ASN1_VISIBLE_STRING:
- check_tag_mask &= ~SEC_ASN1_CONSTRUCTED;
- break;
- }
- }
-
- state->check_tag_mask = check_tag_mask;
- state->expect_tag_modifiers = expect_tag_modifiers;
- state->expect_tag_number = expect_tag_number;
- state->underlying_kind = under_kind;
- state->explicit = explicit;
- state->optional = optional;
-
- sec_asn1d_scrub_state (state);
-
- return state;
-}
-
-static sec_asn1d_state *
-sec_asn1d_get_enclosing_construct(sec_asn1d_state *state)
-{
- for (state = state->parent; state; state = state->parent) {
- sec_asn1d_parse_place place = state->place;
- if (place != afterImplicit &&
- place != afterPointer &&
- place != afterInline &&
- place != afterSaveEncoding &&
- place != duringSaveEncoding &&
- place != duringChoice) {
-
- /* we've walked up the stack to a state that represents
- ** the enclosing construct.
- */
- break;
- }
- }
- return state;
-}
-
-static PRBool
-sec_asn1d_parent_allows_EOC(sec_asn1d_state *state)
-{
- /* get state of enclosing construct. */
- state = sec_asn1d_get_enclosing_construct(state);
- if (state) {
- sec_asn1d_parse_place place = state->place;
- /* Is it one of the types that permits an unexpected EOC? */
- int eoc_permitted =
- (place == duringGroup ||
- place == duringConstructedString ||
- state->child->optional);
- return (state->indefinite && eoc_permitted) ? PR_TRUE : PR_FALSE;
- }
- return PR_FALSE;
-}
-
-static unsigned long
-sec_asn1d_parse_identifier (sec_asn1d_state *state,
- const char *buf, unsigned long len)
-{
- unsigned char byte;
- unsigned char tag_number;
-
- PORT_Assert (state->place == beforeIdentifier);
-
- if (len == 0) {
- state->top->status = needBytes;
- return 0;
- }
-
- byte = (unsigned char) *buf;
-#ifdef DEBUG_ASN1D_STATES
- {
- char kindBuf[256];
- formatKind(byte, kindBuf);
- printf("Found tag %02x %s\n", byte, kindBuf);
- }
-#endif
- tag_number = byte & SEC_ASN1_TAGNUM_MASK;
-
- if (IS_HIGH_TAG_NUMBER (tag_number)) {
- state->place = duringIdentifier;
- state->found_tag_number = 0;
- /*
- * Actually, we have no idea how many bytes are pending, but we
- * do know that it is at least 1. That is all we know; we have
- * to look at each byte to know if there is another, etc.
- */
- state->pending = 1;
- } else {
- if (byte == 0 && sec_asn1d_parent_allows_EOC(state)) {
- /*
- * Our parent has indefinite-length encoding, and the
- * entire tag found is 0, so it seems that we have hit the
- * end-of-contents octets. To handle this, we just change
- * our state to that which expects to get the bytes of the
- * end-of-contents octets and let that code re-read this byte
- * so that our categorization of field types is correct.
- * After that, our parent will then deal with everything else.
- */
- state->place = duringEndOfContents;
- state->pending = 2;
- state->found_tag_number = 0;
- state->found_tag_modifiers = 0;
- /*
- * We might be an optional field that is, as we now find out,
- * missing. Give our parent a clue that this happened.
- */
- if (state->optional)
- state->missing = PR_TRUE;
- return 0;
- }
- state->place = afterIdentifier;
- state->found_tag_number = tag_number;
- }
- state->found_tag_modifiers = byte & ~SEC_ASN1_TAGNUM_MASK;
-
- return 1;
-}
-
-
-static unsigned long
-sec_asn1d_parse_more_identifier (sec_asn1d_state *state,
- const char *buf, unsigned long len)
-{
- unsigned char byte;
- int count;
-
- PORT_Assert (state->pending == 1);
- PORT_Assert (state->place == duringIdentifier);
-
- if (len == 0) {
- state->top->status = needBytes;
- return 0;
- }
-
- count = 0;
-
- while (len && state->pending) {
- if (HIGH_BITS (state->found_tag_number, TAG_NUMBER_BITS) != 0) {
- /*
- * The given high tag number overflows our container;
- * just give up. This is not likely to *ever* happen.
- */
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return 0;
- }
-
- state->found_tag_number <<= TAG_NUMBER_BITS;
-
- byte = (unsigned char) buf[count++];
- state->found_tag_number |= (byte & TAG_NUMBER_MASK);
-
- len--;
- if (LAST_TAG_NUMBER_BYTE (byte))
- state->pending = 0;
- }
-
- if (state->pending == 0)
- state->place = afterIdentifier;
-
- return count;
-}
-
-
-static void
-sec_asn1d_confirm_identifier (sec_asn1d_state *state)
-{
- PRBool match;
-
- PORT_Assert (state->place == afterIdentifier);
-
- match = (PRBool)(((state->found_tag_modifiers & state->check_tag_mask)
- == state->expect_tag_modifiers)
- && ((state->found_tag_number & state->check_tag_mask)
- == state->expect_tag_number));
- if (match) {
- state->place = beforeLength;
- } else {
- if (state->optional) {
- state->missing = PR_TRUE;
- state->place = afterEndOfContents;
- } else {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- }
- }
-}
-
-
-static unsigned long
-sec_asn1d_parse_length (sec_asn1d_state *state,
- const char *buf, unsigned long len)
-{
- unsigned char byte;
-
- PORT_Assert (state->place == beforeLength);
-
- if (len == 0) {
- state->top->status = needBytes;
- return 0;
- }
-
- /*
- * The default/likely outcome. It may get adjusted below.
- */
- state->place = afterLength;
-
- byte = (unsigned char) *buf;
-
- if (LENGTH_IS_SHORT_FORM (byte)) {
- state->contents_length = byte;
- } else {
- state->contents_length = 0;
- state->pending = LONG_FORM_LENGTH (byte);
- if (state->pending == 0) {
- state->indefinite = PR_TRUE;
- } else {
- state->place = duringLength;
- }
- }
-
- /* If we're parsing an ANY, SKIP, or SAVE template, and
- ** the object being saved is definite length encoded and constructed,
- ** there's no point in decoding that construct's members.
- ** So, just forget it's constructed and treat it as primitive.
- ** (SAVE appears as an ANY at this point)
- */
- if (!state->indefinite &&
- (state->underlying_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP))) {
- state->found_tag_modifiers &= ~SEC_ASN1_CONSTRUCTED;
- }
-
- return 1;
-}
-
-
-static unsigned long
-sec_asn1d_parse_more_length (sec_asn1d_state *state,
- const char *buf, unsigned long len)
-{
- int count;
-
- PORT_Assert (state->pending > 0);
- PORT_Assert (state->place == duringLength);
-
- if (len == 0) {
- state->top->status = needBytes;
- return 0;
- }
-
- count = 0;
-
- while (len && state->pending) {
- if (HIGH_BITS (state->contents_length, 9) != 0) {
- /*
- * The given full content length overflows our container;
- * just give up.
- */
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return 0;
- }
-
- state->contents_length <<= 8;
- state->contents_length |= (unsigned char) buf[count++];
-
- len--;
- state->pending--;
- }
-
- if (state->pending == 0)
- state->place = afterLength;
-
- return count;
-}
-
-
-static void
-sec_asn1d_prepare_for_contents (sec_asn1d_state *state)
-{
- SECItem *item;
- PRArenaPool *poolp;
- unsigned long alloc_len;
-
-#ifdef DEBUG_ASN1D_STATES
- {
- printf("Found Length %d %s\n", state->contents_length,
- state->indefinite ? "indefinite" : "");
- }
-#endif
-
- /*
- * XXX I cannot decide if this allocation should exclude the case
- * where state->endofcontents is true -- figure it out!
- */
- if (state->allocate) {
- void *dest;
-
- PORT_Assert (state->dest == NULL);
- /*
- * We are handling a POINTER or a member of a GROUP, and need to
- * allocate for the data structure.
- */
- dest = sec_asn1d_zalloc (state->top->their_pool,
- state->theTemplate->size);
- if (dest == NULL) {
- state->top->status = decodeError;
- return;
- }
- state->dest = (char *)dest + state->theTemplate->offset;
-
- /*
- * For a member of a GROUP, our parent will later put the
- * pointer wherever it belongs. But for a POINTER, we need
- * to record the destination now, in case notify or filter
- * procs need access to it -- they cannot find it otherwise,
- * until it is too late (for one-pass processing).
- */
- if (state->parent->place == afterPointer) {
- void **placep;
-
- placep = state->parent->dest;
- *placep = dest;
- }
- }
-
- /*
- * Remember, length may be indefinite here! In that case,
- * both contents_length and pending will be zero.
- */
- state->pending = state->contents_length;
-
- /* If this item has definite length encoding, and
- ** is enclosed by a definite length constructed type,
- ** make sure it isn't longer than the remaining space in that
- ** constructed type.
- */
- if (state->contents_length > 0) {
- sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(state);
- if (parent && !parent->indefinite &&
- state->consumed + state->contents_length > parent->pending) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return;
- }
- }
-
- /*
- * An EXPLICIT is nothing but an outer header, which we have
- * already parsed and accepted. Now we need to do the inner
- * header and its contents.
- */
- if (state->explicit) {
- state->place = afterExplicit;
- state = sec_asn1d_push_state (state->top,
- SEC_ASN1GetSubtemplate(state->theTemplate,
- state->dest,
- PR_FALSE),
- state->dest, PR_TRUE);
- if (state != NULL)
- state = sec_asn1d_init_state_based_on_template (state);
- return;
- }
-
- /*
- * For GROUP (SET OF, SEQUENCE OF), even if we know the length here
- * we cannot tell how many items we will end up with ... so push a
- * state that can keep track of "children" (the individual members
- * of the group; we will allocate as we go and put them all together
- * at the end.
- */
- if (state->underlying_kind & SEC_ASN1_GROUP) {
- /* XXX If this assertion holds (should be able to confirm it via
- * inspection, too) then move this code into the switch statement
- * below under cases SET_OF and SEQUENCE_OF; it will be cleaner.
- */
- PORT_Assert (state->underlying_kind == SEC_ASN1_SET_OF
- || state->underlying_kind == SEC_ASN1_SEQUENCE_OF
- || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC)
- || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC)
- );
- if (state->contents_length != 0 || state->indefinite) {
- const SEC_ASN1Template *subt;
-
- state->place = duringGroup;
- subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->dest,
- PR_FALSE);
- state = sec_asn1d_push_state (state->top, subt, NULL, PR_TRUE);
- if (state != NULL) {
- if (!state->top->filter_only)
- state->allocate = PR_TRUE; /* XXX propogate this? */
- /*
- * Do the "before" field notification for next in group.
- */
- sec_asn1d_notify_before (state->top, state->dest, state->depth);
- state = sec_asn1d_init_state_based_on_template (state);
- }
- } else {
- /*
- * A group of zero; we are done.
- * Set state to afterGroup and let that code plant the NULL.
- */
- state->place = afterGroup;
- }
- return;
- }
-
- switch (state->underlying_kind) {
- case SEC_ASN1_SEQUENCE:
- /*
- * We need to push a child to handle the individual fields.
- */
- state->place = duringSequence;
- state = sec_asn1d_push_state (state->top, state->theTemplate + 1,
- state->dest, PR_TRUE);
- if (state != NULL) {
- /*
- * Do the "before" field notification.
- */
- sec_asn1d_notify_before (state->top, state->dest, state->depth);
- state = sec_asn1d_init_state_based_on_template (state);
- }
- break;
-
- case SEC_ASN1_SET: /* XXX SET is not really implemented */
- /*
- * XXX A plain SET requires special handling; scanning of a
- * template to see where a field should go (because by definition,
- * they are not in any particular order, and you have to look at
- * each tag to disambiguate what the field is). We may never
- * implement this because in practice, it seems to be unused.
- */
- PORT_Assert(0);
- PORT_SetError (SEC_ERROR_BAD_DER); /* XXX */
- state->top->status = decodeError;
- break;
-
- case SEC_ASN1_NULL:
- /*
- * The NULL type, by definition, is "nothing", content length of zero.
- * An indefinite-length encoding is not alloweed.
- */
- if (state->contents_length || state->indefinite) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- break;
- }
- if (state->dest != NULL) {
- item = (SECItem *)(state->dest);
- item->data = NULL;
- item->len = 0;
- }
- state->place = afterEndOfContents;
- break;
-
- case SEC_ASN1_BMP_STRING:
- /* Error if length is not divisable by 2 */
- if (state->contents_length % 2) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- break;
- }
- /* otherwise, handle as other string types */
- goto regular_string_type;
-
- case SEC_ASN1_UNIVERSAL_STRING:
- /* Error if length is not divisable by 4 */
- if (state->contents_length % 4) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- break;
- }
- /* otherwise, handle as other string types */
- goto regular_string_type;
-
- case SEC_ASN1_SKIP:
- case SEC_ASN1_ANY:
- case SEC_ASN1_ANY_CONTENTS:
- /*
- * These are not (necessarily) strings, but they need nearly
- * identical handling (especially when we need to deal with
- * constructed sub-pieces), so we pretend they are.
- */
- /* fallthru */
-regular_string_type:
- case SEC_ASN1_BIT_STRING:
- case SEC_ASN1_IA5_STRING:
- case SEC_ASN1_OCTET_STRING:
- case SEC_ASN1_PRINTABLE_STRING:
- case SEC_ASN1_T61_STRING:
- case SEC_ASN1_UTC_TIME:
- case SEC_ASN1_UTF8_STRING:
- case SEC_ASN1_VISIBLE_STRING:
- /*
- * We are allocating for a primitive or a constructed string.
- * If it is a constructed string, it may also be indefinite-length.
- * If it is primitive, the length can (legally) be zero.
- * Our first order of business is to allocate the memory for
- * the string, if we can (if we know the length).
- */
- item = (SECItem *)(state->dest);
-
- /*
- * If the item is a definite-length constructed string, then
- * the contents_length is actually larger than what we need
- * (because it also counts each intermediate header which we
- * will be throwing away as we go), but it is a perfectly good
- * upper bound that we just allocate anyway, and then concat
- * as we go; we end up wasting a few extra bytes but save a
- * whole other copy.
- */
- alloc_len = state->contents_length;
- poolp = NULL; /* quiet compiler warnings about unused... */
-
- if (item == NULL || state->top->filter_only) {
- if (item != NULL) {
- item->data = NULL;
- item->len = 0;
- }
- alloc_len = 0;
- } else if (state->substring) {
- /*
- * If we are a substring of a constructed string, then we may
- * not have to allocate anything (because our parent, the
- * actual constructed string, did it for us). If we are a
- * substring and we *do* have to allocate, that means our
- * parent is an indefinite-length, so we allocate from our pool;
- * later our parent will copy our string into the aggregated
- * whole and free our pool allocation.
- */
- if (item->data == NULL) {
- PORT_Assert (item->len == 0);
- poolp = state->top->our_pool;
- } else {
- alloc_len = 0;
- }
- } else {
- item->len = 0;
- item->data = NULL;
- poolp = state->top->their_pool;
- }
-
- if (alloc_len || ((! state->indefinite)
- && (state->subitems_head != NULL))) {
- struct subitem *subitem;
- int len;
-
- PORT_Assert (item);
- if (!item) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return;
- }
- PORT_Assert (item->len == 0 && item->data == NULL);
- /*
- * Check for and handle an ANY which has stashed aside the
- * header (identifier and length) bytes for us to include
- * in the saved contents.
- */
- if (state->subitems_head != NULL) {
- PORT_Assert (state->underlying_kind == SEC_ASN1_ANY);
- for (subitem = state->subitems_head;
- subitem != NULL; subitem = subitem->next)
- alloc_len += subitem->len;
- }
-
- item->data = (unsigned char*)sec_asn1d_zalloc (poolp, alloc_len);
- if (item->data == NULL) {
- state->top->status = decodeError;
- break;
- }
-
- len = 0;
- for (subitem = state->subitems_head;
- subitem != NULL; subitem = subitem->next) {
- PORT_Memcpy (item->data + len, subitem->data, subitem->len);
- len += subitem->len;
- }
- item->len = len;
-
- /*
- * Because we use arenas and have a mark set, we later free
- * everything we have allocated, so this does *not* present
- * a memory leak (it is just temporarily left dangling).
- */
- state->subitems_head = state->subitems_tail = NULL;
- }
-
- if (state->contents_length == 0 && (! state->indefinite)) {
- /*
- * A zero-length simple or constructed string; we are done.
- */
- state->place = afterEndOfContents;
- } else if (state->found_tag_modifiers & SEC_ASN1_CONSTRUCTED) {
- const SEC_ASN1Template *sub;
-
- switch (state->underlying_kind) {
- case SEC_ASN1_ANY:
- case SEC_ASN1_ANY_CONTENTS:
- sub = SEC_AnyTemplate;
- break;
- case SEC_ASN1_BIT_STRING:
- sub = SEC_BitStringTemplate;
- break;
- case SEC_ASN1_BMP_STRING:
- sub = SEC_BMPStringTemplate;
- break;
- case SEC_ASN1_GENERALIZED_TIME:
- sub = SEC_GeneralizedTimeTemplate;
- break;
- case SEC_ASN1_IA5_STRING:
- sub = SEC_IA5StringTemplate;
- break;
- case SEC_ASN1_OCTET_STRING:
- sub = SEC_OctetStringTemplate;
- break;
- case SEC_ASN1_PRINTABLE_STRING:
- sub = SEC_PrintableStringTemplate;
- break;
- case SEC_ASN1_T61_STRING:
- sub = SEC_T61StringTemplate;
- break;
- case SEC_ASN1_UNIVERSAL_STRING:
- sub = SEC_UniversalStringTemplate;
- break;
- case SEC_ASN1_UTC_TIME:
- sub = SEC_UTCTimeTemplate;
- break;
- case SEC_ASN1_UTF8_STRING:
- sub = SEC_UTF8StringTemplate;
- break;
- case SEC_ASN1_VISIBLE_STRING:
- sub = SEC_VisibleStringTemplate;
- break;
- case SEC_ASN1_SKIP:
- sub = SEC_SkipTemplate;
- break;
- default: /* redundant given outer switch cases, but */
- PORT_Assert(0); /* the compiler does not seem to know that, */
- sub = NULL; /* so just do enough to quiet it. */
- break;
- }
-
- state->place = duringConstructedString;
- state = sec_asn1d_push_state (state->top, sub, item, PR_TRUE);
- if (state != NULL) {
- state->substring = PR_TRUE; /* XXX propogate? */
- state = sec_asn1d_init_state_based_on_template (state);
- }
- } else if (state->indefinite) {
- /*
- * An indefinite-length string *must* be constructed!
- */
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- } else {
- /*
- * A non-zero-length simple string.
- */
- if (state->underlying_kind == SEC_ASN1_BIT_STRING)
- state->place = beforeBitString;
- else
- state->place = duringLeaf;
- }
- break;
-
- default:
- /*
- * We are allocating for a simple leaf item.
- */
- if (state->contents_length) {
- if (state->dest != NULL) {
- item = (SECItem *)(state->dest);
- item->len = 0;
- if (state->top->filter_only) {
- item->data = NULL;
- } else {
- item->data = (unsigned char*)
- sec_asn1d_zalloc (state->top->their_pool,
- state->contents_length);
- if (item->data == NULL) {
- state->top->status = decodeError;
- return;
- }
- }
- }
- state->place = duringLeaf;
- } else {
- /*
- * An indefinite-length or zero-length item is not allowed.
- * (All legal cases of such were handled above.)
- */
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- }
- }
-}
-
-
-static void
-sec_asn1d_free_child (sec_asn1d_state *state, PRBool error)
-{
- if (state->child != NULL) {
- PORT_Assert (error || state->child->consumed == 0);
- PORT_Assert (state->our_mark != NULL);
- PORT_ArenaZRelease (state->top->our_pool, state->our_mark);
- if (error && state->top->their_pool == NULL) {
- /*
- * XXX We need to free anything allocated.
- * At this point, we failed in the middle of decoding. But we
- * can't free the data we previously allocated with PR_Malloc
- * unless we keep track of every pointer. So instead we have a
- * memory leak when decoding fails half-way, unless an arena is
- * used. See bug 95311 .
- */
- }
- state->child = NULL;
- state->our_mark = NULL;
- } else {
- /*
- * It is important that we do not leave a mark unreleased/unmarked.
- * But I do not think we should ever have one set in this case, only
- * if we had a child (handled above). So check for that. If this
- * assertion should ever get hit, then we probably need to add code
- * here to release back to our_mark (and then set our_mark to NULL).
- */
- PORT_Assert (state->our_mark == NULL);
- }
- state->place = beforeEndOfContents;
-}
-
-/* We have just saved an entire encoded ASN.1 object (type) for a SAVE
-** template, and now in the next template, we are going to decode that
-** saved data by calling SEC_ASN1DecoderUpdate recursively.
-** If that recursive call fails with needBytes, it is a fatal error,
-** because the encoded object should have been complete.
-** If that recursive call fails with decodeError, it will have already
-** cleaned up the state stack, so we must bail out quickly.
-**
-** These checks of the status returned by the recursive call are now
-** done in the caller of this function, immediately after it returns.
-*/
-static void
-sec_asn1d_reuse_encoding (sec_asn1d_state *state)
-{
- sec_asn1d_state *child;
- unsigned long consumed;
- SECItem *item;
- void *dest;
-
-
- child = state->child;
- PORT_Assert (child != NULL);
-
- consumed = child->consumed;
- child->consumed = 0;
-
- item = (SECItem *)(state->dest);
- PORT_Assert (item != NULL);
-
- PORT_Assert (item->len == consumed);
-
- /*
- * Free any grandchild.
- */
- sec_asn1d_free_child (child, PR_FALSE);
-
- /*
- * Notify after the SAVE field.
- */
- sec_asn1d_notify_after (state->top, state->dest, state->depth);
-
- /*
- * Adjust to get new dest and move forward.
- */
- dest = (char *)state->dest - state->theTemplate->offset;
- state->theTemplate++;
- child->dest = (char *)dest + state->theTemplate->offset;
- child->theTemplate = state->theTemplate;
-
- /*
- * Notify before the "real" field.
- */
- PORT_Assert (state->depth == child->depth);
- sec_asn1d_notify_before (state->top, child->dest, child->depth);
-
- /*
- * This will tell DecoderUpdate to return when it is done.
- */
- state->place = afterSaveEncoding;
-
- /*
- * We already have a child; "push" it by making it current.
- */
- state->top->current = child;
-
- /*
- * And initialize it so it is ready to parse.
- */
- (void) sec_asn1d_init_state_based_on_template(child);
-
- /*
- * Now parse that out of our data.
- */
- if (SEC_ASN1DecoderUpdate (state->top,
- (char *) item->data, item->len) != SECSuccess)
- return;
- if (state->top->status == needBytes) {
- return;
- }
-
- PORT_Assert (state->top->current == state);
- PORT_Assert (state->child == child);
-
- /*
- * That should have consumed what we consumed before.
- */
- PORT_Assert (consumed == child->consumed);
- child->consumed = 0;
-
- /*
- * Done.
- */
- state->consumed += consumed;
- child->place = notInUse;
- state->place = afterEndOfContents;
-}
-
-
-static unsigned long
-sec_asn1d_parse_leaf (sec_asn1d_state *state,
- const char *buf, unsigned long len)
-{
- SECItem *item;
- unsigned long bufLen;
-
- if (len == 0) {
- state->top->status = needBytes;
- return 0;
- }
-
- if (state->pending < len)
- len = state->pending;
-
- bufLen = len;
-
- item = (SECItem *)(state->dest);
- if (item != NULL && item->data != NULL) {
- /* Strip leading zeroes when target is unsigned integer */
- if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */
- item->len == 0 && /* MSB */
- item->type == siUnsignedInteger) /* unsigned */
- {
- while (len > 1 && buf[0] == 0) { /* leading 0 */
- buf++;
- len--;
- }
- }
- PORT_Memcpy (item->data + item->len, buf, len);
- item->len += len;
- }
- state->pending -= bufLen;
- if (state->pending == 0)
- state->place = beforeEndOfContents;
-
- return bufLen;
-}
-
-
-static unsigned long
-sec_asn1d_parse_bit_string (sec_asn1d_state *state,
- const char *buf, unsigned long len)
-{
- unsigned char byte;
-
- /*PORT_Assert (state->pending > 0); */
- PORT_Assert (state->place == beforeBitString);
-
- if (state->pending == 0) {
- if (state->dest != NULL) {
- SECItem *item = (SECItem *)(state->dest);
- item->data = NULL;
- item->len = 0;
- state->place = beforeEndOfContents;
- return 0;
- }
- }
-
- if (len == 0) {
- state->top->status = needBytes;
- return 0;
- }
-
- byte = (unsigned char) *buf;
- if (byte > 7) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return 0;
- }
-
- state->bit_string_unused_bits = byte;
- state->place = duringBitString;
- state->pending -= 1;
-
- return 1;
-}
-
-
-static unsigned long
-sec_asn1d_parse_more_bit_string (sec_asn1d_state *state,
- const char *buf, unsigned long len)
-{
- PORT_Assert (state->place == duringBitString);
- if (state->pending == 0) {
- /* An empty bit string with some unused bits is invalid. */
- if (state->bit_string_unused_bits) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- } else {
- /* An empty bit string with no unused bits is OK. */
- state->place = beforeEndOfContents;
- }
- return 0;
- }
-
- len = sec_asn1d_parse_leaf (state, buf, len);
- if (state->place == beforeEndOfContents && state->dest != NULL) {
- SECItem *item;
-
- item = (SECItem *)(state->dest);
- if (item->len)
- item->len = (item->len << 3) - state->bit_string_unused_bits;
- }
-
- return len;
-}
-
-
-/*
- * XXX All callers should be looking at return value to detect
- * out-of-memory errors (and stop!).
- */
-static struct subitem *
-sec_asn1d_add_to_subitems (sec_asn1d_state *state,
- const void *data, unsigned long len,
- PRBool copy_data)
-{
- struct subitem *thing;
-
- thing = (struct subitem*)sec_asn1d_zalloc (state->top->our_pool,
- sizeof (struct subitem));
- if (thing == NULL) {
- state->top->status = decodeError;
- return NULL;
- }
-
- if (copy_data) {
- void *copy;
- copy = sec_asn1d_alloc (state->top->our_pool, len);
- if (copy == NULL) {
- state->top->status = decodeError;
- if (!state->top->our_pool)
- PORT_Free(thing);
- return NULL;
- }
- PORT_Memcpy (copy, data, len);
- thing->data = copy;
- } else {
- thing->data = data;
- }
- thing->len = len;
- thing->next = NULL;
-
- if (state->subitems_head == NULL) {
- PORT_Assert (state->subitems_tail == NULL);
- state->subitems_head = state->subitems_tail = thing;
- } else {
- state->subitems_tail->next = thing;
- state->subitems_tail = thing;
- }
-
- return thing;
-}
-
-
-static void
-sec_asn1d_record_any_header (sec_asn1d_state *state,
- const char *buf,
- unsigned long len)
-{
- SECItem *item;
-
- item = (SECItem *)(state->dest);
- if (item != NULL && item->data != NULL) {
- PORT_Assert (state->substring);
- PORT_Memcpy (item->data + item->len, buf, len);
- item->len += len;
- } else {
- sec_asn1d_add_to_subitems (state, buf, len, PR_TRUE);
- }
-}
-
-
-/*
- * We are moving along through the substrings of a constructed string,
- * and have just finished parsing one -- we need to save our child data
- * (if the child was not already writing directly into the destination)
- * and then move forward by one.
- *
- * We also have to detect when we are done:
- * - a definite-length encoding stops when our pending value hits 0
- * - an indefinite-length encoding stops when our child is empty
- * (which means it was the end-of-contents octets)
- */
-static void
-sec_asn1d_next_substring (sec_asn1d_state *state)
-{
- sec_asn1d_state *child;
- SECItem *item;
- unsigned long child_consumed;
- PRBool done;
-
- PORT_Assert (state->place == duringConstructedString);
- PORT_Assert (state->child != NULL);
-
- child = state->child;
-
- child_consumed = child->consumed;
- child->consumed = 0;
- state->consumed += child_consumed;
-
- done = PR_FALSE;
-
- if (state->pending) {
- PORT_Assert (!state->indefinite);
- if (child_consumed > state->pending) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return;
- }
-
- state->pending -= child_consumed;
- if (state->pending == 0)
- done = PR_TRUE;
- } else {
- PORT_Assert (state->indefinite);
-
- item = (SECItem *)(child->dest);
- if (item != NULL && item->data != NULL) {
- /*
- * Save the string away for later concatenation.
- */
- PORT_Assert (item->data != NULL);
- sec_asn1d_add_to_subitems (state, item->data, item->len, PR_FALSE);
- /*
- * Clear the child item for the next round.
- */
- item->data = NULL;
- item->len = 0;
- }
-
- /*
- * If our child was just our end-of-contents octets, we are done.
- */
- if (child->endofcontents)
- done = PR_TRUE;
- }
-
- /*
- * Stop or do the next one.
- */
- if (done) {
- child->place = notInUse;
- state->place = afterConstructedString;
- } else {
- sec_asn1d_scrub_state (child);
- state->top->current = child;
- }
-}
-
-
-/*
- * We are doing a SET OF or SEQUENCE OF, and have just finished an item.
- */
-static void
-sec_asn1d_next_in_group (sec_asn1d_state *state)
-{
- sec_asn1d_state *child;
- unsigned long child_consumed;
-
- PORT_Assert (state->place == duringGroup);
- PORT_Assert (state->child != NULL);
-
- child = state->child;
-
- child_consumed = child->consumed;
- child->consumed = 0;
- state->consumed += child_consumed;
-
- /*
- * If our child was just our end-of-contents octets, we are done.
- */
- if (child->endofcontents) {
- /* XXX I removed the PORT_Assert (child->dest == NULL) because there
- * was a bug in that a template that was a sequence of which also had
- * a child of a sequence of, in an indefinite group was not working
- * properly. This fix seems to work, (added the if statement below),
- * and nothing appears broken, but I am putting this note here just
- * in case. */
- /*
- * XXX No matter how many times I read that comment,
- * I cannot figure out what case he was fixing. I believe what he
- * did was deliberate, so I am loathe to touch it. I need to
- * understand how it could ever be that child->dest != NULL but
- * child->endofcontents is true, and why it is important to check
- * that state->subitems_head is NULL. This really needs to be
- * figured out, as I am not sure if the following code should be
- * compensating for "offset", as is done a little farther below
- * in the more normal case.
- */
- PORT_Assert (state->indefinite);
- PORT_Assert (state->pending == 0);
- if(child->dest && !state->subitems_head) {
- sec_asn1d_add_to_subitems (state, child->dest, 0, PR_FALSE);
- child->dest = NULL;
- }
-
- child->place = notInUse;
- state->place = afterGroup;
- return;
- }
-
- /*
- * Do the "after" field notification for next in group.
- */
- sec_asn1d_notify_after (state->top, child->dest, child->depth);
-
- /*
- * Save it away (unless we are not storing).
- */
- if (child->dest != NULL) {
- void *dest;
-
- dest = child->dest;
- dest = (char *)dest - child->theTemplate->offset;
- sec_asn1d_add_to_subitems (state, dest, 0, PR_FALSE);
- child->dest = NULL;
- }
-
- /*
- * Account for those bytes; see if we are done.
- */
- if (state->pending) {
- PORT_Assert (!state->indefinite);
- if (child_consumed > state->pending) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return;
- }
-
- state->pending -= child_consumed;
- if (state->pending == 0) {
- child->place = notInUse;
- state->place = afterGroup;
- return;
- }
- }
-
- /*
- * Do the "before" field notification for next item in group.
- */
- sec_asn1d_notify_before (state->top, child->dest, child->depth);
-
- /*
- * Now we do the next one.
- */
- sec_asn1d_scrub_state (child);
-
- /* Initialize child state from the template */
- sec_asn1d_init_state_based_on_template(child);
-
- state->top->current = child;
-}
-
-
-/*
- * We are moving along through a sequence; move forward by one,
- * (detecting end-of-sequence when it happens).
- * XXX The handling of "missing" is ugly. Fix it.
- */
-static void
-sec_asn1d_next_in_sequence (sec_asn1d_state *state)
-{
- sec_asn1d_state *child;
- unsigned long child_consumed;
- PRBool child_missing;
-
- PORT_Assert (state->place == duringSequence);
- PORT_Assert (state->child != NULL);
-
- child = state->child;
-
- /*
- * Do the "after" field notification.
- */
- sec_asn1d_notify_after (state->top, child->dest, child->depth);
-
- child_missing = (PRBool) child->missing;
- child_consumed = child->consumed;
- child->consumed = 0;
-
- /*
- * Take care of accounting.
- */
- if (child_missing) {
- PORT_Assert (child->optional);
- } else {
- state->consumed += child_consumed;
- /*
- * Free any grandchild.
- */
- sec_asn1d_free_child (child, PR_FALSE);
- if (state->pending) {
- PORT_Assert (!state->indefinite);
- if (child_consumed > state->pending) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return;
- }
- state->pending -= child_consumed;
- if (state->pending == 0) {
- child->theTemplate++;
- while (child->theTemplate->kind != 0) {
- if ((child->theTemplate->kind & SEC_ASN1_OPTIONAL) == 0) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return;
- }
- child->theTemplate++;
- }
- child->place = notInUse;
- state->place = afterEndOfContents;
- return;
- }
- }
- }
-
- /*
- * Move forward.
- */
- child->theTemplate++;
- if (child->theTemplate->kind == 0) {
- /*
- * We are done with this sequence.
- */
- child->place = notInUse;
- if (state->pending) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- } else if (child_missing) {
- /*
- * We got to the end, but have a child that started parsing
- * and ended up "missing". The only legitimate reason for
- * this is that we had one or more optional fields at the
- * end of our sequence, and we were encoded indefinite-length,
- * so when we went looking for those optional fields we
- * found our end-of-contents octets instead.
- * (Yes, this is ugly; dunno a better way to handle it.)
- * So, first confirm the situation, and then mark that we
- * are done.
- */
- if (state->indefinite && child->endofcontents) {
- PORT_Assert (child_consumed == 2);
- if (child_consumed != 2) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- } else {
- state->consumed += child_consumed;
- state->place = afterEndOfContents;
- }
- } else {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- }
- } else {
- /*
- * We have to finish out, maybe reading end-of-contents octets;
- * let the normal logic do the right thing.
- */
- state->place = beforeEndOfContents;
- }
- } else {
- unsigned char child_found_tag_modifiers = 0;
- unsigned long child_found_tag_number = 0;
-
- /*
- * Reset state and push.
- */
- if (state->dest != NULL)
- child->dest = (char *)state->dest + child->theTemplate->offset;
-
- /*
- * Do the "before" field notification.
- */
- sec_asn1d_notify_before (state->top, child->dest, child->depth);
-
- if (child_missing) { /* if previous child was missing, copy the tag data we already have */
- child_found_tag_modifiers = child->found_tag_modifiers;
- child_found_tag_number = child->found_tag_number;
- }
- state->top->current = child;
- child = sec_asn1d_init_state_based_on_template (child);
- if (child_missing && child) {
- child->place = afterIdentifier;
- child->found_tag_modifiers = child_found_tag_modifiers;
- child->found_tag_number = child_found_tag_number;
- child->consumed = child_consumed;
- if (child->underlying_kind == SEC_ASN1_ANY
- && !child->top->filter_only) {
- /*
- * If the new field is an ANY, and we are storing, then
- * we need to save the tag out. We would have done this
- * already in the normal case, but since we were looking
- * for an optional field, and we did not find it, we only
- * now realize we need to save the tag.
- */
- unsigned char identifier;
-
- /*
- * Check that we did not end up with a high tag; for that
- * we need to re-encode the tag into multiple bytes in order
- * to store it back to look like what we parsed originally.
- * In practice this does not happen, but for completeness
- * sake it should probably be made to work at some point.
- */
- PORT_Assert (child_found_tag_number < SEC_ASN1_HIGH_TAG_NUMBER);
- identifier = (unsigned char)(child_found_tag_modifiers | child_found_tag_number);
- sec_asn1d_record_any_header (child, (char *) &identifier, 1);
- }
- }
- }
-}
-
-
-static void
-sec_asn1d_concat_substrings (sec_asn1d_state *state)
-{
- PORT_Assert (state->place == afterConstructedString);
-
- if (state->subitems_head != NULL) {
- struct subitem *substring;
- unsigned long alloc_len, item_len;
- unsigned char *where;
- SECItem *item;
- PRBool is_bit_string;
-
- item_len = 0;
- is_bit_string = (state->underlying_kind == SEC_ASN1_BIT_STRING)
- ? PR_TRUE : PR_FALSE;
-
- substring = state->subitems_head;
- while (substring != NULL) {
- /*
- * All bit-string substrings except the last one should be
- * a clean multiple of 8 bits.
- */
- if (is_bit_string && (substring->next == NULL)
- && (substring->len & 0x7)) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return;
- }
- item_len += substring->len;
- substring = substring->next;
- }
-
- if (is_bit_string) {
- alloc_len = ((item_len + 7) >> 3);
- } else {
- /*
- * Add 2 for the end-of-contents octets of an indefinite-length
- * ANY that is *not* also an INNER. Because we zero-allocate
- * below, all we need to do is increase the length here.
- */
- if (state->underlying_kind == SEC_ASN1_ANY && state->indefinite)
- item_len += 2;
- alloc_len = item_len;
- }
-
- item = (SECItem *)(state->dest);
- PORT_Assert (item != NULL);
- PORT_Assert (item->data == NULL);
- item->data = (unsigned char*)sec_asn1d_zalloc (state->top->their_pool,
- alloc_len);
- if (item->data == NULL) {
- state->top->status = decodeError;
- return;
- }
- item->len = item_len;
-
- where = item->data;
- substring = state->subitems_head;
- while (substring != NULL) {
- if (is_bit_string)
- item_len = (substring->len + 7) >> 3;
- else
- item_len = substring->len;
- PORT_Memcpy (where, substring->data, item_len);
- where += item_len;
- substring = substring->next;
- }
-
- /*
- * Because we use arenas and have a mark set, we later free
- * everything we have allocated, so this does *not* present
- * a memory leak (it is just temporarily left dangling).
- */
- state->subitems_head = state->subitems_tail = NULL;
- }
-
- state->place = afterEndOfContents;
-}
-
-
-static void
-sec_asn1d_concat_group (sec_asn1d_state *state)
-{
- const void ***placep;
-
- PORT_Assert (state->place == afterGroup);
-
- placep = (const void***)state->dest;
- PORT_Assert(state->subitems_head == NULL || placep != NULL);
- if (placep != NULL) {
- struct subitem *item;
- const void **group;
- int count;
-
- count = 0;
- item = state->subitems_head;
- while (item != NULL) {
- PORT_Assert (item->next != NULL || item == state->subitems_tail);
- count++;
- item = item->next;
- }
-
- group = (const void**)sec_asn1d_zalloc (state->top->their_pool,
- (count + 1) * (sizeof(void *)));
- if (group == NULL) {
- state->top->status = decodeError;
- return;
- }
-
- *placep = group;
-
- item = state->subitems_head;
- while (item != NULL) {
- *group++ = item->data;
- item = item->next;
- }
- *group = NULL;
-
- /*
- * Because we use arenas and have a mark set, we later free
- * everything we have allocated, so this does *not* present
- * a memory leak (it is just temporarily left dangling).
- */
- state->subitems_head = state->subitems_tail = NULL;
- }
-
- state->place = afterEndOfContents;
-}
-
-
-/*
- * For those states that push a child to handle a subtemplate,
- * "absorb" that child (transfer necessary information).
- */
-static void
-sec_asn1d_absorb_child (sec_asn1d_state *state)
-{
- /*
- * There is absolutely supposed to be a child there.
- */
- PORT_Assert (state->child != NULL);
-
- /*
- * Inherit the missing status of our child, and do the ugly
- * backing-up if necessary.
- */
- state->missing = state->child->missing;
- if (state->missing) {
- state->found_tag_number = state->child->found_tag_number;
- state->found_tag_modifiers = state->child->found_tag_modifiers;
- state->endofcontents = state->child->endofcontents;
- }
-
- /*
- * Add in number of bytes consumed by child.
- * (Only EXPLICIT should have already consumed bytes itself.)
- */
- PORT_Assert (state->place == afterExplicit || state->consumed == 0);
- state->consumed += state->child->consumed;
-
- /*
- * Subtract from bytes pending; this only applies to a definite-length
- * EXPLICIT field.
- */
- if (state->pending) {
- PORT_Assert (!state->indefinite);
- PORT_Assert (state->place == afterExplicit);
-
- /*
- * If we had a definite-length explicit, then what the child
- * consumed should be what was left pending.
- */
- if (state->pending != state->child->consumed) {
- if (state->pending < state->child->consumed) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return;
- }
- /*
- * Okay, this is a hack. It *should* be an error whether
- * pending is too big or too small, but it turns out that
- * we had a bug in our *old* DER encoder that ended up
- * counting an explicit header twice in the case where
- * the underlying type was an ANY. So, because we cannot
- * prevent receiving these (our own certificate server can
- * send them to us), we need to be lenient and accept them.
- * To do so, we need to pretend as if we read all of the
- * bytes that the header said we would find, even though
- * we actually came up short.
- */
- state->consumed += (state->pending - state->child->consumed);
- }
- state->pending = 0;
- }
-
- /*
- * Indicate that we are done with child.
- */
- state->child->consumed = 0;
-
- /*
- * And move on to final state.
- * (Technically everybody could move to afterEndOfContents except
- * for an indefinite-length EXPLICIT; for simplicity though we assert
- * that but let the end-of-contents code do the real determination.)
- */
- PORT_Assert (state->place == afterExplicit || (! state->indefinite));
- state->place = beforeEndOfContents;
-}
-
-
-static void
-sec_asn1d_prepare_for_end_of_contents (sec_asn1d_state *state)
-{
- PORT_Assert (state->place == beforeEndOfContents);
-
- if (state->indefinite) {
- state->place = duringEndOfContents;
- state->pending = 2;
- } else {
- state->place = afterEndOfContents;
- }
-}
-
-
-static unsigned long
-sec_asn1d_parse_end_of_contents (sec_asn1d_state *state,
- const char *buf, unsigned long len)
-{
- unsigned int i;
-
- PORT_Assert (state->pending <= 2);
- PORT_Assert (state->place == duringEndOfContents);
-
- if (len == 0) {
- state->top->status = needBytes;
- return 0;
- }
-
- if (state->pending < len)
- len = state->pending;
-
- for (i = 0; i < len; i++) {
- if (buf[i] != 0) {
- /*
- * We expect to find only zeros; if not, just give up.
- */
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return 0;
- }
- }
-
- state->pending -= len;
-
- if (state->pending == 0) {
- state->place = afterEndOfContents;
- state->endofcontents = PR_TRUE;
- }
-
- return len;
-}
-
-
-static void
-sec_asn1d_pop_state (sec_asn1d_state *state)
-{
-#if 0 /* XXX I think this should always be handled explicitly by parent? */
- /*
- * Account for our child.
- */
- if (state->child != NULL) {
- state->consumed += state->child->consumed;
- if (state->pending) {
- PORT_Assert (!state->indefinite);
- if (state->child->consumed > state->pending) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- } else {
- state->pending -= state->child->consumed;
- }
- }
- state->child->consumed = 0;
- }
-#endif /* XXX */
-
- /*
- * Free our child.
- */
- sec_asn1d_free_child (state, PR_FALSE);
-
- /*
- * Just make my parent be the current state. It will then clean
- * up after me and free me (or reuse me).
- */
- state->top->current = state->parent;
-}
-
-static sec_asn1d_state *
-sec_asn1d_before_choice (sec_asn1d_state *state)
-{
- sec_asn1d_state *child;
-
- if (state->allocate) {
- void *dest;
-
- dest = sec_asn1d_zalloc(state->top->their_pool, state->theTemplate->size);
- if ((void *)NULL == dest) {
- state->top->status = decodeError;
- return (sec_asn1d_state *)NULL;
- }
-
- state->dest = (char *)dest + state->theTemplate->offset;
- }
-
- child = sec_asn1d_push_state(state->top, state->theTemplate + 1,
- (char *)state->dest - state->theTemplate->offset,
- PR_FALSE);
- if ((sec_asn1d_state *)NULL == child) {
- return (sec_asn1d_state *)NULL;
- }
-
- sec_asn1d_scrub_state(child);
- child = sec_asn1d_init_state_based_on_template(child);
- if ((sec_asn1d_state *)NULL == child) {
- return (sec_asn1d_state *)NULL;
- }
-
- child->optional = PR_TRUE;
-
- state->place = duringChoice;
-
- return child;
-}
-
-static sec_asn1d_state *
-sec_asn1d_during_choice (sec_asn1d_state *state)
-{
- sec_asn1d_state *child = state->child;
-
- PORT_Assert((sec_asn1d_state *)NULL != child);
-
- if (child->missing) {
- unsigned char child_found_tag_modifiers = 0;
- unsigned long child_found_tag_number = 0;
- void * dest;
-
- state->consumed += child->consumed;
-
- if (child->endofcontents) {
- /* This choice is probably the first item in a GROUP
- ** (e.g. SET_OF) that was indefinite-length encoded.
- ** We're actually at the end of that GROUP.
- ** We look up the stack to be sure that we find
- ** a state with indefinite length encoding before we
- ** find a state (like a SEQUENCE) that is definite.
- */
- child->place = notInUse;
- state->place = afterChoice;
- state->endofcontents = PR_TRUE; /* propagate this up */
- if (sec_asn1d_parent_allows_EOC(state))
- return state;
- PORT_SetError(SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return NULL;
- }
-
- dest = (char *)child->dest - child->theTemplate->offset;
- child->theTemplate++;
-
- if (0 == child->theTemplate->kind) {
- /* Ran out of choices */
- PORT_SetError(SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return (sec_asn1d_state *)NULL;
- }
- child->dest = (char *)dest + child->theTemplate->offset;
-
- /* cargo'd from next_in_sequence innards */
- if (state->pending) {
- PORT_Assert(!state->indefinite);
- if (child->consumed > state->pending) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return NULL;
- }
- state->pending -= child->consumed;
- if (0 == state->pending) {
- /* XXX uh.. not sure if I should have stopped this
- * from happening before. */
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_BAD_DER);
- state->top->status = decodeError;
- return (sec_asn1d_state *)NULL;
- }
- }
-
- child->consumed = 0;
- sec_asn1d_scrub_state(child);
-
- /* move it on top again */
- state->top->current = child;
-
- child_found_tag_modifiers = child->found_tag_modifiers;
- child_found_tag_number = child->found_tag_number;
-
- child = sec_asn1d_init_state_based_on_template(child);
- if ((sec_asn1d_state *)NULL == child) {
- return (sec_asn1d_state *)NULL;
- }
-
- /* copy our findings to the new top */
- child->found_tag_modifiers = child_found_tag_modifiers;
- child->found_tag_number = child_found_tag_number;
-
- child->optional = PR_TRUE;
- child->place = afterIdentifier;
-
- return child;
- }
- if ((void *)NULL != state->dest) {
- /* Store the enum */
- int *which = (int *)state->dest;
- *which = (int)child->theTemplate->size;
- }
-
- child->place = notInUse;
-
- state->place = afterChoice;
- return state;
-}
-
-static void
-sec_asn1d_after_choice (sec_asn1d_state *state)
-{
- state->consumed += state->child->consumed;
- state->child->consumed = 0;
- state->place = afterEndOfContents;
- sec_asn1d_pop_state(state);
-}
-
-unsigned long
-sec_asn1d_uinteger(SECItem *src)
-{
- unsigned long value;
- int len;
-
- if (src->len > 5 || (src->len > 4 && src->data[0] == 0))
- return 0;
-
- value = 0;
- len = src->len;
- while (len) {
- value <<= 8;
- value |= src->data[--len];
- }
- return value;
-}
-
-SECStatus
-SEC_ASN1DecodeInteger(SECItem *src, unsigned long *value)
-{
- unsigned long v;
- unsigned int i;
-
- if (src == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (src->len > sizeof(unsigned long)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (src->data == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (src->data[0] & 0x80)
- v = -1; /* signed and negative - start with all 1's */
- else
- v = 0;
-
- for (i= 0; i < src->len; i++) {
- /* shift in next byte */
- v <<= 8;
- v |= src->data[i];
- }
- *value = v;
- return SECSuccess;
-}
-
-#ifdef DEBUG_ASN1D_STATES
-static void
-dump_states(SEC_ASN1DecoderContext *cx)
-{
- sec_asn1d_state *state;
- char kindBuf[256];
-
- for (state = cx->current; state->parent; state = state->parent) {
- ;
- }
-
- for (; state; state = state->child) {
- int i;
- for (i = 0; i < state->depth; i++) {
- printf(" ");
- }
-
- i = formatKind(state->theTemplate->kind, kindBuf);
- printf("%s: tmpl %08x, kind%s",
- (state == cx->current) ? "STATE" : "State",
- state->theTemplate,
- kindBuf);
- printf(" %s", (state->place >= 0 && state->place <= notInUse)
- ? place_names[ state->place ]
- : "(undefined)");
- if (!i)
- printf(", expect 0x%02x",
- state->expect_tag_number | state->expect_tag_modifiers);
-
- printf("%s%s%s %d\n",
- state->indefinite ? ", indef" : "",
- state->missing ? ", miss" : "",
- state->endofcontents ? ", EOC" : "",
- state->pending
- );
- }
-
- return;
-}
-#endif /* DEBUG_ASN1D_STATES */
-
-SECStatus
-SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx,
- const char *buf, unsigned long len)
-{
- sec_asn1d_state *state = NULL;
- unsigned long consumed;
- SEC_ASN1EncodingPart what;
- sec_asn1d_state *stateEnd = cx->current;
-
- if (cx->status == needBytes)
- cx->status = keepGoing;
-
- while (cx->status == keepGoing) {
- state = cx->current;
- what = SEC_ASN1_Contents;
- consumed = 0;
-#ifdef DEBUG_ASN1D_STATES
- printf("\nPLACE = %s, next byte = 0x%02x, %08x[%d]\n",
- (state->place >= 0 && state->place <= notInUse) ?
- place_names[ state->place ] : "(undefined)",
- (unsigned int)((unsigned char *)buf)[ consumed ],
- buf, consumed);
- dump_states(cx);
-#endif /* DEBUG_ASN1D_STATES */
- switch (state->place) {
- case beforeIdentifier:
- consumed = sec_asn1d_parse_identifier (state, buf, len);
- what = SEC_ASN1_Identifier;
- break;
- case duringIdentifier:
- consumed = sec_asn1d_parse_more_identifier (state, buf, len);
- what = SEC_ASN1_Identifier;
- break;
- case afterIdentifier:
- sec_asn1d_confirm_identifier (state);
- break;
- case beforeLength:
- consumed = sec_asn1d_parse_length (state, buf, len);
- what = SEC_ASN1_Length;
- break;
- case duringLength:
- consumed = sec_asn1d_parse_more_length (state, buf, len);
- what = SEC_ASN1_Length;
- break;
- case afterLength:
- sec_asn1d_prepare_for_contents (state);
- break;
- case beforeBitString:
- consumed = sec_asn1d_parse_bit_string (state, buf, len);
- break;
- case duringBitString:
- consumed = sec_asn1d_parse_more_bit_string (state, buf, len);
- break;
- case duringConstructedString:
- sec_asn1d_next_substring (state);
- break;
- case duringGroup:
- sec_asn1d_next_in_group (state);
- break;
- case duringLeaf:
- consumed = sec_asn1d_parse_leaf (state, buf, len);
- break;
- case duringSaveEncoding:
- sec_asn1d_reuse_encoding (state);
- if (cx->status == decodeError) {
- /* recursive call has already popped all states from stack.
- ** Bail out quickly.
- */
- return SECFailure;
- }
- if (cx->status == needBytes) {
- /* recursive call wanted more data. Fatal. Clean up below. */
- PORT_SetError (SEC_ERROR_BAD_DER);
- cx->status = decodeError;
- }
- break;
- case duringSequence:
- sec_asn1d_next_in_sequence (state);
- break;
- case afterConstructedString:
- sec_asn1d_concat_substrings (state);
- break;
- case afterExplicit:
- case afterImplicit:
- case afterInline:
- case afterPointer:
- sec_asn1d_absorb_child (state);
- break;
- case afterGroup:
- sec_asn1d_concat_group (state);
- break;
- case afterSaveEncoding:
- /* SEC_ASN1DecoderUpdate has called itself recursively to
- ** decode SAVEd encoded data, and now is done decoding that.
- ** Return to the calling copy of SEC_ASN1DecoderUpdate.
- */
- return SECSuccess;
- case beforeEndOfContents:
- sec_asn1d_prepare_for_end_of_contents (state);
- break;
- case duringEndOfContents:
- consumed = sec_asn1d_parse_end_of_contents (state, buf, len);
- what = SEC_ASN1_EndOfContents;
- break;
- case afterEndOfContents:
- sec_asn1d_pop_state (state);
- break;
- case beforeChoice:
- state = sec_asn1d_before_choice(state);
- break;
- case duringChoice:
- state = sec_asn1d_during_choice(state);
- break;
- case afterChoice:
- sec_asn1d_after_choice(state);
- break;
- case notInUse:
- default:
- /* This is not an error, but rather a plain old BUG! */
- PORT_Assert (0);
- PORT_SetError (SEC_ERROR_BAD_DER);
- cx->status = decodeError;
- break;
- }
-
- if (cx->status == decodeError)
- break;
-
- /* We should not consume more than we have. */
- PORT_Assert (consumed <= len);
- if (consumed > len) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- cx->status = decodeError;
- break;
- }
-
- /* It might have changed, so we have to update our local copy. */
- state = cx->current;
-
- /* If it is NULL, we have popped all the way to the top. */
- if (state == NULL) {
- PORT_Assert (consumed == 0);
-#if 0 /* XXX I want this here, but it seems that we have situations (like
- * downloading a pkcs7 cert chain from some issuers) that give us a
- * length which is greater than the entire encoding. So, we cannot
- * have this be an error.
- */
- if (len > 0) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- cx->status = decodeError;
- } else
-#endif
- cx->status = allDone;
- break;
- }
- else if (state->theTemplate->kind == SEC_ASN1_SKIP_REST) {
- cx->status = allDone;
- break;
- }
-
- if (consumed == 0)
- continue;
-
- /*
- * The following check is specifically looking for an ANY
- * that is *not* also an INNER, because we need to save aside
- * all bytes in that case -- the contents parts will get
- * handled like all other contents, and the end-of-contents
- * bytes are added by the concat code, but the outer header
- * bytes need to get saved too, so we do them explicitly here.
- */
- if (state->underlying_kind == SEC_ASN1_ANY
- && !cx->filter_only && (what == SEC_ASN1_Identifier
- || what == SEC_ASN1_Length)) {
- sec_asn1d_record_any_header (state, buf, consumed);
- }
-
- /*
- * We had some number of good, accepted bytes. If the caller
- * has registered to see them, pass them along.
- */
- if (state->top->filter_proc != NULL) {
- int depth;
-
- depth = state->depth;
- if (what == SEC_ASN1_EndOfContents && !state->indefinite) {
- PORT_Assert (state->parent != NULL
- && state->parent->indefinite);
- depth--;
- PORT_Assert (depth == state->parent->depth);
- }
- (* state->top->filter_proc) (state->top->filter_arg,
- buf, consumed, depth, what);
- }
-
- state->consumed += consumed;
- buf += consumed;
- len -= consumed;
- }
-
- if (cx->status == decodeError) {
- while (state != NULL && stateEnd->parent!=state) {
- sec_asn1d_free_child (state, PR_TRUE);
- state = state->parent;
- }
-#ifdef SEC_ASN1D_FREE_ON_ERROR /*
- * XXX This does not work because we can
- * end up leaving behind dangling pointers
- * to stuff that was allocated. In order
- * to make this really work (which would
- * be a good thing, I think), we need to
- * keep track of every place/pointer that
- * was allocated and make sure to NULL it
- * out before we then free back to the mark.
- */
- if (cx->their_pool != NULL) {
- PORT_Assert (cx->their_mark != NULL);
- PORT_ArenaRelease (cx->their_pool, cx->their_mark);
- }
-#endif
- return SECFailure;
- }
-
-#if 0 /* XXX This is what I want, but cannot have because it seems we
- * have situations (like when downloading a pkcs7 cert chain from
- * some issuers) that give us a total length which is greater than
- * the entire encoding. So, we have to allow allDone to have a
- * remaining length greater than zero. I wanted to catch internal
- * bugs with this, noticing when we do not have the right length.
- * Oh well.
- */
- PORT_Assert (len == 0
- && (cx->status == needBytes || cx->status == allDone));
-#else
- PORT_Assert ((len == 0 && cx->status == needBytes)
- || cx->status == allDone);
-#endif
- return SECSuccess;
-}
-
-
-SECStatus
-SEC_ASN1DecoderFinish (SEC_ASN1DecoderContext *cx)
-{
- SECStatus rv;
-
- if (cx->status == needBytes) {
- PORT_SetError (SEC_ERROR_BAD_DER);
- rv = SECFailure;
- } else {
- rv = SECSuccess;
- }
-
- /*
- * XXX anything else that needs to be finished?
- */
-
- PORT_FreeArena (cx->our_pool, PR_TRUE);
-
- return rv;
-}
-
-
-SEC_ASN1DecoderContext *
-SEC_ASN1DecoderStart (PRArenaPool *their_pool, void *dest,
- const SEC_ASN1Template *theTemplate)
-{
- PRArenaPool *our_pool;
- SEC_ASN1DecoderContext *cx;
-
- our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (our_pool == NULL)
- return NULL;
-
- cx = (SEC_ASN1DecoderContext*)PORT_ArenaZAlloc (our_pool, sizeof(*cx));
- if (cx == NULL) {
- PORT_FreeArena (our_pool, PR_FALSE);
- return NULL;
- }
-
- cx->our_pool = our_pool;
- if (their_pool != NULL) {
- cx->their_pool = their_pool;
-#ifdef SEC_ASN1D_FREE_ON_ERROR
- cx->their_mark = PORT_ArenaMark (their_pool);
-#endif
- }
-
- cx->status = needBytes;
-
- if (sec_asn1d_push_state(cx, theTemplate, dest, PR_FALSE) == NULL
- || sec_asn1d_init_state_based_on_template (cx->current) == NULL) {
- /*
- * Trouble initializing (probably due to failed allocations)
- * requires that we just give up.
- */
- PORT_FreeArena (our_pool, PR_FALSE);
- return NULL;
- }
-
- return cx;
-}
-
-
-void
-SEC_ASN1DecoderSetFilterProc (SEC_ASN1DecoderContext *cx,
- SEC_ASN1WriteProc fn, void *arg,
- PRBool only)
-{
- /* check that we are "between" fields here */
- PORT_Assert (cx->during_notify);
-
- cx->filter_proc = fn;
- cx->filter_arg = arg;
- cx->filter_only = only;
-}
-
-
-void
-SEC_ASN1DecoderClearFilterProc (SEC_ASN1DecoderContext *cx)
-{
- /* check that we are "between" fields here */
- PORT_Assert (cx->during_notify);
-
- cx->filter_proc = NULL;
- cx->filter_arg = NULL;
- cx->filter_only = PR_FALSE;
-}
-
-
-void
-SEC_ASN1DecoderSetNotifyProc (SEC_ASN1DecoderContext *cx,
- SEC_ASN1NotifyProc fn, void *arg)
-{
- cx->notify_proc = fn;
- cx->notify_arg = arg;
-}
-
-
-void
-SEC_ASN1DecoderClearNotifyProc (SEC_ASN1DecoderContext *cx)
-{
- cx->notify_proc = NULL;
- cx->notify_arg = NULL; /* not necessary; just being clean */
-}
-
-void
-SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error)
-{
- PORT_Assert(cx);
- PORT_SetError(error);
- cx->status = decodeError;
-}
-
-
-SECStatus
-SEC_ASN1Decode (PRArenaPool *poolp, void *dest,
- const SEC_ASN1Template *theTemplate,
- const char *buf, long len)
-{
- SEC_ASN1DecoderContext *dcx;
- SECStatus urv, frv;
-
- dcx = SEC_ASN1DecoderStart (poolp, dest, theTemplate);
- if (dcx == NULL)
- return SECFailure;
-
- urv = SEC_ASN1DecoderUpdate (dcx, buf, len);
- frv = SEC_ASN1DecoderFinish (dcx);
-
- if (urv != SECSuccess)
- return urv;
-
- return frv;
-}
-
-
-SECStatus
-SEC_ASN1DecodeItem (PRArenaPool *poolp, void *dest,
- const SEC_ASN1Template *theTemplate,
- const SECItem *src)
-{
- return SEC_ASN1Decode (poolp, dest, theTemplate,
- (const char *)src->data, src->len);
-}
-
-#ifdef DEBUG_ASN1D_STATES
-void sec_asn1d_Assert(const char *s, const char *file, PRIntn ln)
-{
- printf("Assertion failed, \"%s\", file %s, line %d\n", s, file, ln);
- fflush(stdout);
-}
-#endif
-
-/*
- * Generic templates for individual/simple items and pointers to
- * and sets of same.
- *
- * If you need to add a new one, please note the following:
- * - For each new basic type you should add *four* templates:
- * one plain, one PointerTo, one SequenceOf and one SetOf.
- * - If the new type can be constructed (meaning, it is a
- * *string* type according to BER/DER rules), then you should
- * or-in SEC_ASN1_MAY_STREAM to the type in the basic template.
- * See the definition of the OctetString template for an example.
- * - It may not be obvious, but these are in *alphabetical*
- * order based on the SEC_ASN1_XXX name; so put new ones in
- * the appropriate place.
- */
-
-const SEC_ASN1Template SEC_SequenceOfAnyTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate }
-};
-
-#if 0
-
-const SEC_ASN1Template SEC_PointerToBitStringTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_BitStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfBitStringTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_BitStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfBitStringTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_BitStringTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToBMPStringTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_BMPStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfBMPStringTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_BMPStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfBMPStringTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_BMPStringTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToBooleanTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_BooleanTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfBooleanTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_BooleanTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfBooleanTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_BooleanTemplate }
-};
-
-#endif
-
-const SEC_ASN1Template SEC_EnumeratedTemplate[] = {
- { SEC_ASN1_ENUMERATED, 0, NULL, sizeof(SECItem) }
-};
-
-const SEC_ASN1Template SEC_PointerToEnumeratedTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_EnumeratedTemplate }
-};
-
-#if 0
-
-const SEC_ASN1Template SEC_SequenceOfEnumeratedTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_EnumeratedTemplate }
-};
-
-#endif
-
-const SEC_ASN1Template SEC_SetOfEnumeratedTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_EnumeratedTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToGeneralizedTimeTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_GeneralizedTimeTemplate }
-};
-
-#if 0
-
-const SEC_ASN1Template SEC_SequenceOfGeneralizedTimeTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_GeneralizedTimeTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfGeneralizedTimeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_GeneralizedTimeTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToIA5StringTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_IA5StringTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfIA5StringTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_IA5StringTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfIA5StringTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_IA5StringTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToIntegerTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_IntegerTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfIntegerTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_IntegerTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfIntegerTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_IntegerTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToNullTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_NullTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfNullTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_NullTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfNullTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_NullTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToObjectIDTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_ObjectIDTemplate }
-};
-
-#endif
-
-const SEC_ASN1Template SEC_SequenceOfObjectIDTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_ObjectIDTemplate }
-};
-
-#if 0
-
-const SEC_ASN1Template SEC_SetOfObjectIDTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_ObjectIDTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfOctetStringTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_OctetStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfOctetStringTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_OctetStringTemplate }
-};
-
-#endif
-
-const SEC_ASN1Template SEC_PrintableStringTemplate[] = {
- { SEC_ASN1_PRINTABLE_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
-};
-
-#if 0
-
-const SEC_ASN1Template SEC_PointerToPrintableStringTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_PrintableStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfPrintableStringTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_PrintableStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfPrintableStringTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_PrintableStringTemplate }
-};
-
-#endif
-
-const SEC_ASN1Template SEC_T61StringTemplate[] = {
- { SEC_ASN1_T61_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
-};
-
-#if 0
-
-const SEC_ASN1Template SEC_PointerToT61StringTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_T61StringTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfT61StringTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_T61StringTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfT61StringTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_T61StringTemplate }
-};
-
-#endif
-
-const SEC_ASN1Template SEC_UniversalStringTemplate[] = {
- { SEC_ASN1_UNIVERSAL_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
-};
-
-#if 0
-
-const SEC_ASN1Template SEC_PointerToUniversalStringTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_UniversalStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfUniversalStringTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_UniversalStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfUniversalStringTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_UniversalStringTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToUTCTimeTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_UTCTimeTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfUTCTimeTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_UTCTimeTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfUTCTimeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_UTCTimeTemplate }
-};
-
-const SEC_ASN1Template SEC_PointerToUTF8StringTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_UTF8StringTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfUTF8StringTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_UTF8StringTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfUTF8StringTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_UTF8StringTemplate }
-};
-
-#endif
-
-const SEC_ASN1Template SEC_VisibleStringTemplate[] = {
- { SEC_ASN1_VISIBLE_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
-};
-
-#if 0
-
-const SEC_ASN1Template SEC_PointerToVisibleStringTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_VisibleStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SequenceOfVisibleStringTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_VisibleStringTemplate }
-};
-
-const SEC_ASN1Template SEC_SetOfVisibleStringTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_VisibleStringTemplate }
-};
-
-#endif
-
-/*
- * Template for skipping a subitem.
- *
- * Note that it only makes sense to use this for decoding (when you want
- * to decode something where you are only interested in one or two of
- * the fields); you cannot encode a SKIP!
- */
-const SEC_ASN1Template SEC_SkipTemplate[] = {
- { SEC_ASN1_SKIP }
-};
-
-
-/* These functions simply return the address of the above-declared templates.
-** This is necessary for Windows DLLs. Sigh.
-*/
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_EnumeratedTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToEnumeratedTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfAnyTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SequenceOfObjectIDTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SkipTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_UniversalStringTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PrintableStringTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_T61StringTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToGeneralizedTimeTemplate)
-
diff --git a/security/nss/lib/util/secasn1e.c b/security/nss/lib/util/secasn1e.c
deleted file mode 100644
index 5a98f0946..000000000
--- a/security/nss/lib/util/secasn1e.c
+++ /dev/null
@@ -1,1615 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Support for ENcoding ASN.1 data based on BER/DER (Basic/Distinguished
- * Encoding Rules).
- *
- * $Id$
- */
-
-#include "secasn1.h"
-
-typedef enum {
- beforeHeader,
- duringContents,
- duringGroup,
- duringSequence,
- afterContents,
- afterImplicit,
- afterInline,
- afterPointer,
- afterChoice,
- notInUse
-} sec_asn1e_parse_place;
-
-typedef enum {
- allDone,
- encodeError,
- keepGoing,
- needBytes
-} sec_asn1e_parse_status;
-
-typedef enum {
- hdr_normal = 0, /* encode header normally */
- hdr_any = 1, /* header already encoded in content */
- hdr_decoder = 2, /* template only used by decoder. skip it. */
- hdr_optional = 3, /* optional component, to be omitted */
- hdr_placeholder = 4 /* place holder for from_buf content */
-} sec_asn1e_hdr_encoding;
-
-typedef struct sec_asn1e_state_struct {
- SEC_ASN1EncoderContext *top;
- const SEC_ASN1Template *theTemplate;
- void *src;
-
- struct sec_asn1e_state_struct *parent; /* aka prev */
- struct sec_asn1e_state_struct *child; /* aka next */
-
- sec_asn1e_parse_place place; /* where we are in encoding process */
-
- /*
- * XXX explain the next fields as clearly as possible...
- */
- unsigned char tag_modifiers;
- unsigned char tag_number;
- unsigned long underlying_kind;
-
- int depth;
-
- PRBool isExplicit, /* we are handling an isExplicit header */
- indefinite, /* need end-of-contents */
- is_string, /* encoding a simple string or an ANY */
- may_stream, /* when streaming, do indefinite encoding */
- optional, /* omit field if it has no contents */
- disallowStreaming; /* disallow streaming in all sub-templates */
-} sec_asn1e_state;
-
-/*
- * An "outsider" will have an opaque pointer to this, created by calling
- * SEC_ASN1EncoderStart(). It will be passed back in to all subsequent
- * calls to SEC_ASN1EncoderUpdate() and related routines, and when done
- * it is passed to SEC_ASN1EncoderFinish().
- */
-struct sec_EncoderContext_struct {
- PRArenaPool *our_pool; /* for our internal allocs */
-
- sec_asn1e_state *current;
- sec_asn1e_parse_status status;
-
- PRBool streaming;
- PRBool from_buf;
-
- SEC_ASN1NotifyProc notify_proc; /* call before/after handling field */
- void *notify_arg; /* argument to notify_proc */
- PRBool during_notify; /* true during call to notify_proc */
-
- SEC_ASN1WriteProc output_proc; /* pass encoded bytes to this */
- void *output_arg; /* argument to that function */
-};
-
-
-static sec_asn1e_state *
-sec_asn1e_push_state (SEC_ASN1EncoderContext *cx,
- const SEC_ASN1Template *theTemplate,
- const void *src, PRBool new_depth)
-{
- sec_asn1e_state *state, *new_state;
-
- state = cx->current;
-
- new_state = (sec_asn1e_state*)PORT_ArenaZAlloc (cx->our_pool,
- sizeof(*new_state));
- if (new_state == NULL) {
- cx->status = encodeError;
- return NULL;
- }
-
- new_state->top = cx;
- new_state->parent = state;
- new_state->theTemplate = theTemplate;
- new_state->place = notInUse;
- if (src != NULL)
- new_state->src = (char *)src + theTemplate->offset;
-
- if (state != NULL) {
- new_state->depth = state->depth;
- if (new_depth)
- new_state->depth++;
- state->child = new_state;
- }
-
- cx->current = new_state;
- return new_state;
-}
-
-
-static void
-sec_asn1e_scrub_state (sec_asn1e_state *state)
-{
- /*
- * Some default "scrubbing".
- * XXX right set of initializations?
- */
- state->place = beforeHeader;
- state->indefinite = PR_FALSE;
-}
-
-
-static void
-sec_asn1e_notify_before (SEC_ASN1EncoderContext *cx, void *src, int depth)
-{
- if (cx->notify_proc == NULL)
- return;
-
- cx->during_notify = PR_TRUE;
- (* cx->notify_proc) (cx->notify_arg, PR_TRUE, src, depth);
- cx->during_notify = PR_FALSE;
-}
-
-
-static void
-sec_asn1e_notify_after (SEC_ASN1EncoderContext *cx, void *src, int depth)
-{
- if (cx->notify_proc == NULL)
- return;
-
- cx->during_notify = PR_TRUE;
- (* cx->notify_proc) (cx->notify_arg, PR_FALSE, src, depth);
- cx->during_notify = PR_FALSE;
-}
-
-
-static sec_asn1e_state *
-sec_asn1e_init_state_based_on_template (sec_asn1e_state *state)
-{
- PRBool isExplicit, is_string, may_stream, optional, universal;
- PRBool disallowStreaming;
- unsigned char tag_modifiers;
- unsigned long encode_kind, under_kind;
- unsigned long tag_number;
- PRBool isInline = PR_FALSE;
-
-
- encode_kind = state->theTemplate->kind;
-
- universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL)
- ? PR_TRUE : PR_FALSE;
-
- isExplicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~SEC_ASN1_EXPLICIT;
-
- optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~SEC_ASN1_OPTIONAL;
-
- PORT_Assert (!(isExplicit && universal)); /* bad templates */
-
- may_stream = (encode_kind & SEC_ASN1_MAY_STREAM) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~SEC_ASN1_MAY_STREAM;
-
- disallowStreaming = (encode_kind & SEC_ASN1_NO_STREAM) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~SEC_ASN1_NO_STREAM;
-
- /* Just clear this to get it out of the way; we do not need it here */
- encode_kind &= ~SEC_ASN1_DYNAMIC;
-
- if( encode_kind & SEC_ASN1_CHOICE ) {
- under_kind = SEC_ASN1_CHOICE;
- } else if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) ||
- (!universal && !isExplicit)) {
- const SEC_ASN1Template *subt;
- void *src = NULL;
-
- PORT_Assert ((encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) == 0);
-
- sec_asn1e_scrub_state (state);
-
- if (encode_kind & SEC_ASN1_POINTER) {
- src = *(void **)state->src;
- state->place = afterPointer;
-
- if (src == NULL) {
- /*
- * If this is optional, but NULL, then the field does
- * not need to be encoded. In this case we are done;
- * we do not want to push a subtemplate.
- */
- if (optional)
- return state;
-
- /*
- * XXX this is an error; need to figure out
- * how to handle this
- */
- }
- } else {
- src = state->src;
- if (encode_kind & SEC_ASN1_INLINE) {
- /* check that there are no extraneous bits */
- /* PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional); */
- state->place = afterInline;
- isInline = PR_TRUE;
- } else {
- /*
- * Save the tag modifiers and tag number here before moving
- * on to the next state in case this is a member of a
- * SEQUENCE OF
- */
- state->tag_modifiers = (unsigned char)
- (encode_kind & (SEC_ASN1_TAG_MASK & ~SEC_ASN1_TAGNUM_MASK));
- state->tag_number = (unsigned char)
- (encode_kind & SEC_ASN1_TAGNUM_MASK);
-
- state->place = afterImplicit;
- state->optional = optional;
- }
- }
-
- subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->src, PR_TRUE);
- if (isInline && optional) {
- /* we only handle a very limited set of optional inline cases at
- this time */
- if (PR_FALSE != SEC_ASN1IsTemplateSimple(subt)) {
- /* we now know that the target is a SECItem*, so we can check
- if the source contains one */
- SECItem* target = (SECItem*)state->src;
- if (!target || !target->data || !target->len) {
- /* no valid data to encode subtemplate */
- return state;
- }
- } else {
- PORT_Assert(0); /* complex templates are not handled as
- inline optional */
- }
- }
- state = sec_asn1e_push_state (state->top, subt, src, PR_FALSE);
- if (state == NULL)
- return state;
-
- if (universal) {
- /*
- * This is a POINTER or INLINE; just init based on that
- * and we are done.
- */
- return sec_asn1e_init_state_based_on_template (state);
- }
-
- /*
- * This is an implicit, non-universal (meaning, application-private
- * or context-specific) field. This results in a "magic" tag but
- * encoding based on the underlying type. We pushed a new state
- * that is based on the subtemplate (the underlying type), but
- * now we will sort of alias it to give it some of our properties
- * (tag, optional status, etc.).
- *
- * NB: ALL the following flags in the subtemplate are disallowed
- * and/or ignored: EXPLICIT, OPTIONAL, INNER, INLINE, POINTER.
- */
-
- under_kind = state->theTemplate->kind;
- if ((under_kind & SEC_ASN1_MAY_STREAM) && !disallowStreaming) {
- may_stream = PR_TRUE;
- }
- under_kind &= ~(SEC_ASN1_MAY_STREAM | SEC_ASN1_DYNAMIC);
- } else {
- under_kind = encode_kind;
- }
-
- /*
- * Sanity check that there are no unwanted bits marked in under_kind.
- * These bits were either removed above (after we recorded them) or
- * they simply should not be found (signalling a bad/broken template).
- * XXX is this the right set of bits to test here? (i.e. need to add
- * or remove any?)
- */
-#define UNEXPECTED_FLAGS \
- (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_SKIP | SEC_ASN1_INNER | \
- SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM | SEC_ASN1_INLINE | SEC_ASN1_POINTER)
-
- PORT_Assert ((under_kind & UNEXPECTED_FLAGS) == 0);
- under_kind &= ~UNEXPECTED_FLAGS;
-#undef UNEXPECTED_FLAGS
-
- if (encode_kind & SEC_ASN1_ANY) {
- PORT_Assert (encode_kind == under_kind);
- tag_modifiers = 0;
- tag_number = 0;
- is_string = PR_TRUE;
- } else {
- tag_modifiers = (unsigned char)
- (encode_kind & (SEC_ASN1_TAG_MASK & ~SEC_ASN1_TAGNUM_MASK));
- /*
- * XXX This assumes only single-octet identifiers. To handle
- * the HIGH TAG form we would need to do some more work, especially
- * in how to specify them in the template, because right now we
- * do not provide a way to specify more *tag* bits in encode_kind.
- */
- tag_number = encode_kind & SEC_ASN1_TAGNUM_MASK;
-
- is_string = PR_FALSE;
- switch (under_kind & SEC_ASN1_TAGNUM_MASK) {
- case SEC_ASN1_SET:
- /*
- * XXX A plain old SET (as opposed to a SET OF) is not implemented.
- * If it ever is, remove this assert...
- */
- PORT_Assert ((under_kind & SEC_ASN1_GROUP) != 0);
- /* fallthru */
- case SEC_ASN1_SEQUENCE:
- tag_modifiers |= SEC_ASN1_CONSTRUCTED;
- break;
- case SEC_ASN1_BIT_STRING:
- case SEC_ASN1_BMP_STRING:
- case SEC_ASN1_GENERALIZED_TIME:
- case SEC_ASN1_IA5_STRING:
- case SEC_ASN1_OCTET_STRING:
- case SEC_ASN1_PRINTABLE_STRING:
- case SEC_ASN1_T61_STRING:
- case SEC_ASN1_UNIVERSAL_STRING:
- case SEC_ASN1_UTC_TIME:
- case SEC_ASN1_UTF8_STRING:
- case SEC_ASN1_VISIBLE_STRING:
- /*
- * We do not yet know if we will be constructing the string,
- * so we have to wait to do this final tag modification.
- */
- is_string = PR_TRUE;
- break;
- }
- }
-
- state->tag_modifiers = tag_modifiers;
- state->tag_number = (unsigned char)tag_number;
- state->underlying_kind = under_kind;
- state->isExplicit = isExplicit;
- state->may_stream = may_stream;
- state->is_string = is_string;
- state->optional = optional;
- state->disallowStreaming = disallowStreaming;
-
- sec_asn1e_scrub_state (state);
-
- return state;
-}
-
-
-static void
-sec_asn1e_write_part (sec_asn1e_state *state,
- const char *buf, unsigned long len,
- SEC_ASN1EncodingPart part)
-{
- SEC_ASN1EncoderContext *cx;
-
- cx = state->top;
- (* cx->output_proc) (cx->output_arg, buf, len, state->depth, part);
-}
-
-
-/*
- * XXX This assumes only single-octet identifiers. To handle
- * the HIGH TAG form we would need to modify this interface and
- * teach it to properly encode the special form.
- */
-static void
-sec_asn1e_write_identifier_bytes (sec_asn1e_state *state, unsigned char value)
-{
- char byte;
-
- byte = (char) value;
- sec_asn1e_write_part (state, &byte, 1, SEC_ASN1_Identifier);
-}
-
-int
-SEC_ASN1EncodeLength(unsigned char *buf,int value) {
- int lenlen;
-
- lenlen = SEC_ASN1LengthLength (value);
- if (lenlen == 1) {
- buf[0] = value;
- } else {
- int i;
-
- i = lenlen - 1;
- buf[0] = 0x80 | i;
- while (i) {
- buf[i--] = value;
- value >>= 8;
- }
- PORT_Assert (value == 0);
- }
- return lenlen;
-}
-
-static void
-sec_asn1e_write_length_bytes (sec_asn1e_state *state, unsigned long value,
- PRBool indefinite)
-{
- int lenlen;
- unsigned char buf[sizeof(unsigned long) + 1];
-
- if (indefinite) {
- PORT_Assert (value == 0);
- buf[0] = 0x80;
- lenlen = 1;
- } else {
- lenlen = SEC_ASN1EncodeLength(buf,value);
- }
-
- sec_asn1e_write_part (state, (char *) buf, lenlen, SEC_ASN1_Length);
-}
-
-
-static void
-sec_asn1e_write_contents_bytes (sec_asn1e_state *state,
- const char *buf, unsigned long len)
-{
- sec_asn1e_write_part (state, buf, len, SEC_ASN1_Contents);
-}
-
-
-static void
-sec_asn1e_write_end_of_contents_bytes (sec_asn1e_state *state)
-{
- const char eoc[2] = {0, 0};
-
- sec_asn1e_write_part (state, eoc, 2, SEC_ASN1_EndOfContents);
-}
-
-static int
-sec_asn1e_which_choice
-(
- void *src,
- const SEC_ASN1Template *theTemplate
-)
-{
- int rv;
- unsigned int which = *(unsigned int *)src;
-
- for( rv = 1, theTemplate++; theTemplate->kind != 0; rv++, theTemplate++ ) {
- if( which == theTemplate->size ) {
- return rv;
- }
- }
-
- return 0;
-}
-
-static unsigned long
-sec_asn1e_contents_length (const SEC_ASN1Template *theTemplate, void *src,
- PRBool disallowStreaming, PRBool insideIndefinite,
- sec_asn1e_hdr_encoding *pHdrException)
-{
- unsigned long encode_kind, underlying_kind;
- PRBool isExplicit, optional, universal, may_stream;
- unsigned long len;
-
- /*
- * This function currently calculates the length in all cases
- * except the following: when writing out the contents of a
- * template that belongs to a state where it was a sub-template
- * with the SEC_ASN1_MAY_STREAM bit set and it's parent had the
- * optional bit set. The information that the parent is optional
- * and that we should return the length of 0 when that length is
- * present since that means the optional field is no longer present.
- * So we add the disallowStreaming flag which is passed in when
- * writing the contents, but for all recursive calls to
- * sec_asn1e_contents_length, we pass PR_FALSE, because this
- * function correctly calculates the length for children templates
- * from that point on. Confused yet? At least you didn't have
- * to figure it out. ;) -javi
- */
- encode_kind = theTemplate->kind;
-
- universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL)
- ? PR_TRUE : PR_FALSE;
-
- isExplicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~SEC_ASN1_EXPLICIT;
-
- optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~SEC_ASN1_OPTIONAL;
-
- PORT_Assert (!(isExplicit && universal)); /* bad templates */
-
- may_stream = (encode_kind & SEC_ASN1_MAY_STREAM) ? PR_TRUE : PR_FALSE;
- encode_kind &= ~SEC_ASN1_MAY_STREAM;
-
- /* Just clear this to get it out of the way; we do not need it here */
- encode_kind &= ~SEC_ASN1_DYNAMIC;
-
- if (encode_kind & SEC_ASN1_NO_STREAM) {
- disallowStreaming = PR_TRUE;
- }
- encode_kind &= ~SEC_ASN1_NO_STREAM;
-
- if (encode_kind & SEC_ASN1_CHOICE) {
- void *src2;
- int indx = sec_asn1e_which_choice(src, theTemplate);
- if (0 == indx) {
- /* XXX set an error? "choice not found" */
- /* state->top->status = encodeError; */
- return 0;
- }
-
- src2 = (void *)
- ((char *)src - theTemplate->offset + theTemplate[indx].offset);
-
- return sec_asn1e_contents_length(&theTemplate[indx], src2,
- disallowStreaming, insideIndefinite,
- pHdrException);
- }
-
- if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || !universal) {
- /* XXX any bits we want to disallow (PORT_Assert against) here? */
- theTemplate = SEC_ASN1GetSubtemplate (theTemplate, src, PR_TRUE);
- if (encode_kind & SEC_ASN1_POINTER) {
- src = *(void **)src;
- if (src == NULL) {
- *pHdrException = optional ? hdr_optional : hdr_normal;
- return 0;
- }
- } else if (encode_kind & SEC_ASN1_INLINE) {
- /* check that there are no extraneous bits */
- if (optional) {
- if (PR_FALSE != SEC_ASN1IsTemplateSimple(theTemplate)) {
- /* we now know that the target is a SECItem*, so we can check
- if the source contains one */
- SECItem* target = (SECItem*)src;
- if (!target || !target->data || !target->len) {
- /* no valid data to encode subtemplate */
- *pHdrException = hdr_optional;
- return 0;
- }
- } else {
- PORT_Assert(0); /* complex templates not handled as inline
- optional */
- }
- }
- }
-
- src = (char *)src + theTemplate->offset;
-
- /* recurse to find the length of the subtemplate */
- len = sec_asn1e_contents_length (theTemplate, src, disallowStreaming,
- insideIndefinite, pHdrException);
- if (len == 0 && optional) {
- *pHdrException = hdr_optional;
- } else if (isExplicit) {
- if (*pHdrException == hdr_any) {
- /* *we* do not want to add in a header,
- ** but our caller still does.
- */
- *pHdrException = hdr_normal;
- } else if (*pHdrException == hdr_normal) {
- /* if the inner content exists, our length is
- * len(identifier) + len(length) + len(innercontent)
- * XXX we currently assume len(identifier) == 1;
- * to support a high-tag-number this would need to be smarter.
- */
- len += 1 + SEC_ASN1LengthLength (len);
- }
- }
- return len;
- }
- underlying_kind = encode_kind;
-
- /* This is only used in decoding; it plays no part in encoding. */
- if (underlying_kind & SEC_ASN1_SAVE) {
- /* check that there are no extraneous bits */
- PORT_Assert (underlying_kind == SEC_ASN1_SAVE);
- *pHdrException = hdr_decoder;
- return 0;
- }
-
-#define UNEXPECTED_FLAGS \
- (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_INLINE | SEC_ASN1_POINTER |\
- SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM | SEC_ASN1_SAVE | SEC_ASN1_SKIP)
-
- /* Having any of these bits is not expected here... */
- PORT_Assert ((underlying_kind & UNEXPECTED_FLAGS) == 0);
- underlying_kind &= ~UNEXPECTED_FLAGS;
-#undef UNEXPECTED_FLAGS
-
- if (underlying_kind & SEC_ASN1_CHOICE) {
- void *src2;
- int indx = sec_asn1e_which_choice(src, theTemplate);
- if (0 == indx) {
- /* XXX set an error? "choice not found" */
- /* state->top->status = encodeError; */
- return 0;
- }
-
- src2 = (void *)
- ((char *)src - theTemplate->offset + theTemplate[indx].offset);
- len = sec_asn1e_contents_length(&theTemplate[indx], src2,
- disallowStreaming, insideIndefinite,
- pHdrException);
- } else {
- switch (underlying_kind) {
- case SEC_ASN1_SEQUENCE_OF:
- case SEC_ASN1_SET_OF:
- {
- const SEC_ASN1Template *tmpt;
- void *sub_src;
- unsigned long sub_len;
- void **group;
-
- len = 0;
-
- group = *(void ***)src;
- if (group == NULL)
- break;
-
- tmpt = SEC_ASN1GetSubtemplate (theTemplate, src, PR_TRUE);
-
- for (; *group != NULL; group++) {
- sub_src = (char *)(*group) + tmpt->offset;
- sub_len = sec_asn1e_contents_length (tmpt, sub_src,
- disallowStreaming,
- insideIndefinite,
- pHdrException);
- len += sub_len;
- /*
- * XXX The 1 below is the presumed length of the identifier;
- * to support a high-tag-number this would need to be smarter.
- */
- if (*pHdrException == hdr_normal)
- len += 1 + SEC_ASN1LengthLength (sub_len);
- }
- }
- break;
-
- case SEC_ASN1_SEQUENCE:
- case SEC_ASN1_SET:
- {
- const SEC_ASN1Template *tmpt;
- void *sub_src;
- unsigned long sub_len;
-
- len = 0;
- for (tmpt = theTemplate + 1; tmpt->kind; tmpt++) {
- sub_src = (char *)src + tmpt->offset;
- sub_len = sec_asn1e_contents_length (tmpt, sub_src,
- disallowStreaming,
- insideIndefinite,
- pHdrException);
- len += sub_len;
- /*
- * XXX The 1 below is the presumed length of the identifier;
- * to support a high-tag-number this would need to be smarter.
- */
- if (*pHdrException == hdr_normal)
- len += 1 + SEC_ASN1LengthLength (sub_len);
- }
- }
- break;
-
- case SEC_ASN1_BIT_STRING:
- /* convert bit length to byte */
- len = (((SECItem *)src)->len + 7) >> 3;
- /* bit string contents involve an extra octet */
- if (len)
- len++;
- break;
-
- case SEC_ASN1_INTEGER:
- /* ASN.1 INTEGERs are signed.
- * If the source is an unsigned integer, the encoder will need
- * to handle the conversion here.
- */
- {
- unsigned char *buf = ((SECItem *)src)->data;
- SECItemType integerType = ((SECItem *)src)->type;
- len = ((SECItem *)src)->len;
- while (len > 0) {
- if (*buf != 0) {
- if (*buf & 0x80 && integerType == siUnsignedInteger) {
- len++; /* leading zero needed to make number signed */
- }
- break; /* reached beginning of number */
- }
- if (len == 1) {
- break; /* the number 0 */
- }
- if (buf[1] & 0x80) {
- break; /* leading zero already present */
- }
- /* extraneous leading zero, keep going */
- buf++;
- len--;
- }
- }
- break;
-
- default:
- len = ((SECItem *)src)->len;
- break;
- } /* end switch */
-
-#ifndef WHAT_PROBLEM_DOES_THIS_SOLVE
- /* if we're streaming, we may have a secitem w/len 0 as placeholder */
- if (!len && insideIndefinite && may_stream && !disallowStreaming) {
- len = 1;
- }
-#endif
- } /* end else */
-
- if (len == 0 && optional)
- *pHdrException = hdr_optional;
- else if (underlying_kind == SEC_ASN1_ANY)
- *pHdrException = hdr_any;
- else
- *pHdrException = hdr_normal;
-
- return len;
-}
-
-
-static void
-sec_asn1e_write_header (sec_asn1e_state *state)
-{
- unsigned long contents_length;
- unsigned char tag_number, tag_modifiers;
- sec_asn1e_hdr_encoding hdrException = hdr_normal;
- PRBool indefinite = PR_FALSE;
-
- PORT_Assert (state->place == beforeHeader);
-
- tag_number = state->tag_number;
- tag_modifiers = state->tag_modifiers;
-
- if (state->underlying_kind == SEC_ASN1_ANY) {
- state->place = duringContents;
- return;
- }
-
- if (state->underlying_kind & SEC_ASN1_CHOICE) {
- int indx = sec_asn1e_which_choice(state->src, state->theTemplate);
- if( 0 == indx ) {
- /* XXX set an error? "choice not found" */
- state->top->status = encodeError;
- return;
- }
- state->place = afterChoice;
- state = sec_asn1e_push_state(state->top, &state->theTemplate[indx],
- (char *)state->src - state->theTemplate->offset,
- PR_TRUE);
- if (state) {
- /*
- * Do the "before" field notification.
- */
- sec_asn1e_notify_before (state->top, state->src, state->depth);
- state = sec_asn1e_init_state_based_on_template (state);
- }
- return;
- }
-
- /* The !isString test below is apparently intended to ensure that all
- ** constructed types receive indefinite length encoding.
- */
- indefinite = (PRBool)
- (state->top->streaming && state->may_stream &&
- (state->top->from_buf || !state->is_string));
-
- /*
- * If we are doing a definite-length encoding, first we have to
- * walk the data structure to calculate the entire contents length.
- * If we are doing an indefinite-length encoding, we still need to
- * know if the contents is:
- * optional and to be omitted, or
- * an ANY (header is pre-encoded), or
- * a SAVE or some other kind of template used only by the decoder.
- * So, we call this function either way.
- */
- contents_length = sec_asn1e_contents_length (state->theTemplate,
- state->src,
- state->disallowStreaming,
- indefinite,
- &hdrException);
- /*
- * We might be told explicitly not to put out a header.
- * But it can also be the case, via a pushed subtemplate, that
- * sec_asn1e_contents_length could not know that this field is
- * really optional. So check for that explicitly, too.
- */
- if (hdrException != hdr_normal ||
- (contents_length == 0 && state->optional)) {
- state->place = afterContents;
- if (state->top->streaming &&
- state->may_stream &&
- state->top->from_buf) {
- /* we did not find an optional indefinite string, so we
- * don't encode it. However, if TakeFromBuf is on, we stop
- * here anyway to give our caller a chance to intercept at the
- * same point where we would stop if the field were present.
- */
- state->top->status = needBytes;
- }
- return;
- }
-
- if (indefinite) {
- /*
- * We need to put out an indefinite-length encoding.
- * The only universal types that can be constructed are SETs,
- * SEQUENCEs, and strings; so check that it is one of those,
- * or that it is not universal (e.g. context-specific).
- */
- state->indefinite = PR_TRUE;
- PORT_Assert ((tag_number == SEC_ASN1_SET)
- || (tag_number == SEC_ASN1_SEQUENCE)
- || ((tag_modifiers & SEC_ASN1_CLASS_MASK) != 0)
- || state->is_string);
- tag_modifiers |= SEC_ASN1_CONSTRUCTED;
- contents_length = 0;
- }
-
- sec_asn1e_write_identifier_bytes (state,
- (unsigned char)(tag_number | tag_modifiers));
- sec_asn1e_write_length_bytes (state, contents_length, state->indefinite);
-
- if (contents_length == 0 && !state->indefinite) {
- /*
- * If no real contents to encode, then we are done with this field.
- */
- state->place = afterContents;
- return;
- }
-
- /*
- * An EXPLICIT is nothing but an outer header, which we have already
- * written. Now we need to do the inner header and contents.
- */
- if (state->isExplicit) {
- const SEC_ASN1Template *subt =
- SEC_ASN1GetSubtemplate(state->theTemplate, state->src, PR_TRUE);
- state->place = afterContents;
- state = sec_asn1e_push_state (state->top, subt, state->src, PR_TRUE);
- if (state != NULL)
- state = sec_asn1e_init_state_based_on_template (state);
- return;
- }
-
- switch (state->underlying_kind) {
- case SEC_ASN1_SET_OF:
- case SEC_ASN1_SEQUENCE_OF:
- /*
- * We need to push a child to handle each member.
- */
- {
- void **group;
- const SEC_ASN1Template *subt;
-
- group = *(void ***)state->src;
- if (group == NULL || *group == NULL) {
- /*
- * Group is empty; we are done.
- */
- state->place = afterContents;
- return;
- }
- state->place = duringGroup;
- subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->src,
- PR_TRUE);
- state = sec_asn1e_push_state (state->top, subt, *group, PR_TRUE);
- if (state != NULL)
- state = sec_asn1e_init_state_based_on_template (state);
- }
- break;
-
- case SEC_ASN1_SEQUENCE:
- case SEC_ASN1_SET:
- /*
- * We need to push a child to handle the individual fields.
- */
- state->place = duringSequence;
- state = sec_asn1e_push_state (state->top, state->theTemplate + 1,
- state->src, PR_TRUE);
- if (state != NULL) {
- /*
- * Do the "before" field notification.
- */
- sec_asn1e_notify_before (state->top, state->src, state->depth);
- state = sec_asn1e_init_state_based_on_template (state);
- }
- break;
-
- default:
- /*
- * I think we do not need to do anything else.
- * XXX Correct?
- */
- state->place = duringContents;
- break;
- }
-}
-
-
-static void
-sec_asn1e_write_contents_from_buf (sec_asn1e_state *state,
- const char *buf, unsigned long len)
-{
- PORT_Assert (state->place == duringContents);
- PORT_Assert (state->top->from_buf);
- PORT_Assert (state->may_stream && !state->disallowStreaming);
-
- /*
- * Probably they just turned on "take from buf", but have not
- * yet given us any bytes. If there is nothing in the buffer
- * then we have nothing to do but return and wait.
- */
- if (buf == NULL || len == 0) {
- state->top->status = needBytes;
- return;
- }
- /*
- * We are streaming, reading from a passed-in buffer.
- * This means we are encoding a simple string or an ANY.
- * For the former, we need to put out a substring, with its
- * own identifier and length. For an ANY, we just write it
- * out as is (our caller is required to ensure that it
- * is a properly encoded entity).
- */
- PORT_Assert (state->is_string); /* includes ANY */
- if (state->underlying_kind != SEC_ASN1_ANY) {
- unsigned char identifier;
-
- /*
- * Create the identifier based on underlying_kind. We cannot
- * use tag_number and tag_modifiers because this can be an
- * implicitly encoded field. In that case, the underlying
- * substrings *are* encoded with their real tag.
- */
- identifier = (unsigned char)
- (state->underlying_kind & SEC_ASN1_TAG_MASK);
- /*
- * The underlying kind should just be a simple string; there
- * should be no bits like CONTEXT_SPECIFIC or CONSTRUCTED set.
- */
- PORT_Assert ((identifier & SEC_ASN1_TAGNUM_MASK) == identifier);
- /*
- * Write out the tag and length for the substring.
- */
- sec_asn1e_write_identifier_bytes (state, identifier);
- if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
- char byte;
- /*
- * Assume we have a length in bytes but we need to output
- * a proper bit string. This interface only works for bit
- * strings that are full multiples of 8. If support for
- * real, variable length bit strings is needed then the
- * caller will have to know to pass in a bit length instead
- * of a byte length and then this code will have to
- * perform the encoding necessary (length written is length
- * in bytes plus 1, and the first octet of string is the
- * number of bits remaining between the end of the bit
- * string and the next byte boundary).
- */
- sec_asn1e_write_length_bytes (state, len + 1, PR_FALSE);
- byte = 0;
- sec_asn1e_write_contents_bytes (state, &byte, 1);
- } else {
- sec_asn1e_write_length_bytes (state, len, PR_FALSE);
- }
- }
- sec_asn1e_write_contents_bytes (state, buf, len);
- state->top->status = needBytes;
-}
-
-static void
-sec_asn1e_write_contents (sec_asn1e_state *state)
-{
- unsigned long len = 0;
-
- PORT_Assert (state->place == duringContents);
-
- switch (state->underlying_kind) {
- case SEC_ASN1_SET:
- case SEC_ASN1_SEQUENCE:
- PORT_Assert (0);
- break;
-
- case SEC_ASN1_BIT_STRING:
- {
- SECItem *item;
- char rem;
-
- item = (SECItem *)state->src;
- len = (item->len + 7) >> 3;
- rem = (unsigned char)((len << 3) - item->len); /* remaining bits */
- sec_asn1e_write_contents_bytes (state, &rem, 1);
- sec_asn1e_write_contents_bytes (state, (char *) item->data, len);
- }
- break;
-
- case SEC_ASN1_BMP_STRING:
- /* The number of bytes must be divisable by 2 */
- if ((((SECItem *)state->src)->len) % 2) {
- SEC_ASN1EncoderContext *cx;
-
- cx = state->top;
- cx->status = encodeError;
- break;
- }
- /* otherwise, fall through to write the content */
- goto process_string;
-
- case SEC_ASN1_UNIVERSAL_STRING:
- /* The number of bytes must be divisable by 4 */
- if ((((SECItem *)state->src)->len) % 4) {
- SEC_ASN1EncoderContext *cx;
-
- cx = state->top;
- cx->status = encodeError;
- break;
- }
- /* otherwise, fall through to write the content */
- goto process_string;
-
- case SEC_ASN1_INTEGER:
- /* ASN.1 INTEGERs are signed. If the source is an unsigned
- * integer, the encoder will need to handle the conversion here.
- */
- {
- unsigned int blen;
- unsigned char *buf;
- SECItemType integerType;
- blen = ((SECItem *)state->src)->len;
- buf = ((SECItem *)state->src)->data;
- integerType = ((SECItem *)state->src)->type;
- while (blen > 0) {
- if (*buf & 0x80 && integerType == siUnsignedInteger) {
- char zero = 0; /* write a leading 0 */
- sec_asn1e_write_contents_bytes(state, &zero, 1);
- /* and then the remaining buffer */
- sec_asn1e_write_contents_bytes(state,
- (char *)buf, blen);
- break;
- }
- /* Check three possibilities:
- * 1. No leading zeros, msb of MSB is not 1;
- * 2. The number is zero itself;
- * 3. Encoding a signed integer with a leading zero,
- * keep the zero so that the number is positive.
- */
- if (*buf != 0 ||
- blen == 1 ||
- (buf[1] & 0x80 && integerType != siUnsignedInteger) )
- {
- sec_asn1e_write_contents_bytes(state,
- (char *)buf, blen);
- break;
- }
- /* byte is 0, continue */
- buf++;
- blen--;
- }
- }
- /* done with this content */
- break;
-
-process_string:
- default:
- {
- SECItem *item;
-
- item = (SECItem *)state->src;
- sec_asn1e_write_contents_bytes (state, (char *) item->data,
- item->len);
- }
- break;
- }
- state->place = afterContents;
-}
-
-/*
- * We are doing a SET OF or SEQUENCE OF, and have just finished an item.
- */
-static void
-sec_asn1e_next_in_group (sec_asn1e_state *state)
-{
- sec_asn1e_state *child;
- void **group;
- void *member;
-
- PORT_Assert (state->place == duringGroup);
- PORT_Assert (state->child != NULL);
-
- child = state->child;
-
- group = *(void ***)state->src;
-
- /*
- * Find placement of current item.
- */
- member = (char *)(state->child->src) - child->theTemplate->offset;
- while (*group != member)
- group++;
-
- /*
- * Move forward to next item.
- */
- group++;
- if (*group == NULL) {
- /*
- * That was our last one; we are done now.
- */
- child->place = notInUse;
- state->place = afterContents;
- return;
- }
- child->src = (char *)(*group) + child->theTemplate->offset;
-
- /*
- * Re-"push" child.
- */
- sec_asn1e_scrub_state (child);
- state->top->current = child;
-}
-
-
-/*
- * We are moving along through a sequence; move forward by one,
- * (detecting end-of-sequence when it happens).
- */
-static void
-sec_asn1e_next_in_sequence (sec_asn1e_state *state)
-{
- sec_asn1e_state *child;
-
- PORT_Assert (state->place == duringSequence);
- PORT_Assert (state->child != NULL);
-
- child = state->child;
-
- /*
- * Do the "after" field notification.
- */
- sec_asn1e_notify_after (state->top, child->src, child->depth);
-
- /*
- * Move forward.
- */
- child->theTemplate++;
- if (child->theTemplate->kind == 0) {
- /*
- * We are done with this sequence.
- */
- child->place = notInUse;
- state->place = afterContents;
- return;
- }
-
- /*
- * Reset state and push.
- */
-
- child->src = (char *)state->src + child->theTemplate->offset;
-
- /*
- * Do the "before" field notification.
- */
- sec_asn1e_notify_before (state->top, child->src, child->depth);
-
- state->top->current = child;
- (void) sec_asn1e_init_state_based_on_template (child);
-}
-
-
-static void
-sec_asn1e_after_contents (sec_asn1e_state *state)
-{
- PORT_Assert (state->place == afterContents);
-
- if (state->indefinite)
- sec_asn1e_write_end_of_contents_bytes (state);
-
- /*
- * Just make my parent be the current state. It will then clean
- * up after me and free me (or reuse me).
- */
- state->top->current = state->parent;
-}
-
-
-/*
- * This function is called whether or not we are streaming; if we
- * *are* streaming, our caller can also instruct us to take bytes
- * from the passed-in buffer (at buf, for length len, which is likely
- * bytes but could even mean bits if the current field is a bit string).
- * If we have been so instructed, we will gobble up bytes from there
- * (rather than from our src structure) and output them, and then
- * we will just return, expecting to be called again -- either with
- * more bytes or after our caller has instructed us that we are done
- * (for now) with the buffer.
- */
-SECStatus
-SEC_ASN1EncoderUpdate (SEC_ASN1EncoderContext *cx,
- const char *buf, unsigned long len)
-{
- sec_asn1e_state *state;
-
- if (cx->status == needBytes) {
- cx->status = keepGoing;
- }
-
- while (cx->status == keepGoing) {
- state = cx->current;
- switch (state->place) {
- case beforeHeader:
- sec_asn1e_write_header (state);
- break;
- case duringContents:
- if (cx->from_buf)
- sec_asn1e_write_contents_from_buf (state, buf, len);
- else
- sec_asn1e_write_contents (state);
- break;
- case duringGroup:
- sec_asn1e_next_in_group (state);
- break;
- case duringSequence:
- sec_asn1e_next_in_sequence (state);
- break;
- case afterContents:
- sec_asn1e_after_contents (state);
- break;
- case afterImplicit:
- case afterInline:
- case afterPointer:
- case afterChoice:
- /*
- * These states are more documentation than anything.
- * They just need to force a pop.
- */
- PORT_Assert (!state->indefinite);
- state->place = afterContents;
- break;
- case notInUse:
- default:
- /* This is not an error, but rather a plain old BUG! */
- PORT_Assert (0);
- cx->status = encodeError;
- break;
- }
-
- if (cx->status == encodeError)
- break;
-
- /* It might have changed, so we have to update our local copy. */
- state = cx->current;
-
- /* If it is NULL, we have popped all the way to the top. */
- if (state == NULL) {
- cx->status = allDone;
- break;
- }
- }
-
- if (cx->status == encodeError) {
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-
-void
-SEC_ASN1EncoderFinish (SEC_ASN1EncoderContext *cx)
-{
- /*
- * XXX anything else that needs to be finished?
- */
-
- PORT_FreeArena (cx->our_pool, PR_FALSE);
-}
-
-
-SEC_ASN1EncoderContext *
-SEC_ASN1EncoderStart (const void *src, const SEC_ASN1Template *theTemplate,
- SEC_ASN1WriteProc output_proc, void *output_arg)
-{
- PRArenaPool *our_pool;
- SEC_ASN1EncoderContext *cx;
-
- our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (our_pool == NULL)
- return NULL;
-
- cx = (SEC_ASN1EncoderContext*)PORT_ArenaZAlloc (our_pool, sizeof(*cx));
- if (cx == NULL) {
- PORT_FreeArena (our_pool, PR_FALSE);
- return NULL;
- }
-
- cx->our_pool = our_pool;
- cx->output_proc = output_proc;
- cx->output_arg = output_arg;
-
- cx->status = keepGoing;
-
- if (sec_asn1e_push_state(cx, theTemplate, src, PR_FALSE) == NULL
- || sec_asn1e_init_state_based_on_template (cx->current) == NULL) {
- /*
- * Trouble initializing (probably due to failed allocations)
- * requires that we just give up.
- */
- PORT_FreeArena (our_pool, PR_FALSE);
- return NULL;
- }
-
- return cx;
-}
-
-
-/*
- * XXX Do we need a FilterProc, too?
- */
-
-
-void
-SEC_ASN1EncoderSetNotifyProc (SEC_ASN1EncoderContext *cx,
- SEC_ASN1NotifyProc fn, void *arg)
-{
- cx->notify_proc = fn;
- cx->notify_arg = arg;
-}
-
-
-void
-SEC_ASN1EncoderClearNotifyProc (SEC_ASN1EncoderContext *cx)
-{
- cx->notify_proc = NULL;
- cx->notify_arg = NULL; /* not necessary; just being clean */
-}
-
-void
-SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error)
-{
- PORT_Assert(cx);
- PORT_SetError(error);
- cx->status = encodeError;
-}
-
-void
-SEC_ASN1EncoderSetStreaming (SEC_ASN1EncoderContext *cx)
-{
- /* XXX is there a way to check that we are "between" fields here? */
-
- cx->streaming = PR_TRUE;
-}
-
-
-void
-SEC_ASN1EncoderClearStreaming (SEC_ASN1EncoderContext *cx)
-{
- /* XXX is there a way to check that we are "between" fields here? */
-
- cx->streaming = PR_FALSE;
-}
-
-
-void
-SEC_ASN1EncoderSetTakeFromBuf (SEC_ASN1EncoderContext *cx)
-{
- /*
- * XXX is there a way to check that we are "between" fields here? this
- * needs to include a check for being in between groups of items in
- * a SET_OF or SEQUENCE_OF.
- */
- PORT_Assert (cx->streaming);
-
- cx->from_buf = PR_TRUE;
-}
-
-
-void
-SEC_ASN1EncoderClearTakeFromBuf (SEC_ASN1EncoderContext *cx)
-{
- /* we should actually be taking from buf *now* */
- PORT_Assert (cx->from_buf);
- if (! cx->from_buf) /* if not, just do nothing */
- return;
-
- cx->from_buf = PR_FALSE;
-
- if (cx->status == needBytes) {
- cx->status = keepGoing;
- cx->current->place = afterContents;
- }
-}
-
-
-SECStatus
-SEC_ASN1Encode (const void *src, const SEC_ASN1Template *theTemplate,
- SEC_ASN1WriteProc output_proc, void *output_arg)
-{
- SEC_ASN1EncoderContext *ecx;
- SECStatus rv;
-
- ecx = SEC_ASN1EncoderStart (src, theTemplate, output_proc, output_arg);
- if (ecx == NULL)
- return SECFailure;
-
- rv = SEC_ASN1EncoderUpdate (ecx, NULL, 0);
-
- SEC_ASN1EncoderFinish (ecx);
- return rv;
-}
-
-
-/*
- * XXX depth and data_kind are unused; is there a PC way to silence warnings?
- * (I mean "politically correct", not anything to do with intel/win platform)
- */
-static void
-sec_asn1e_encode_item_count (void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
-{
- unsigned long *count;
-
- count = (unsigned long*)arg;
- PORT_Assert (count != NULL);
-
- *count += len;
-}
-
-
-/* XXX depth and data_kind are unused; is there a PC way to silence warnings? */
-static void
-sec_asn1e_encode_item_store (void *arg, const char *buf, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind)
-{
- SECItem *dest;
-
- dest = (SECItem*)arg;
- PORT_Assert (dest != NULL);
-
- PORT_Memcpy (dest->data + dest->len, buf, len);
- dest->len += len;
-}
-
-
-/*
- * Allocate an entire SECItem, or just the data part of it, to hold
- * "len" bytes of stuff. Allocate from the given pool, if specified,
- * otherwise just do a vanilla PORT_Alloc.
- *
- * XXX This seems like a reasonable general-purpose function (for SECITEM_)?
- */
-static SECItem *
-sec_asn1e_allocate_item (PRArenaPool *poolp, SECItem *dest, unsigned long len)
-{
- if (poolp != NULL) {
- void *release;
-
- release = PORT_ArenaMark (poolp);
- if (dest == NULL)
- dest = (SECItem*)PORT_ArenaAlloc (poolp, sizeof(SECItem));
- if (dest != NULL) {
- dest->data = (unsigned char*)PORT_ArenaAlloc (poolp, len);
- if (dest->data == NULL) {
- dest = NULL;
- }
- }
- if (dest == NULL) {
- /* one or both allocations failed; release everything */
- PORT_ArenaRelease (poolp, release);
- } else {
- /* everything okay; unmark the arena */
- PORT_ArenaUnmark (poolp, release);
- }
- } else {
- SECItem *indest;
-
- indest = dest;
- if (dest == NULL)
- dest = (SECItem*)PORT_Alloc (sizeof(SECItem));
- if (dest != NULL) {
- dest->type = siBuffer;
- dest->data = (unsigned char*)PORT_Alloc (len);
- if (dest->data == NULL) {
- if (indest == NULL)
- PORT_Free (dest);
- dest = NULL;
- }
- }
- }
-
- return dest;
-}
-
-
-SECItem *
-SEC_ASN1EncodeItem (PRArenaPool *poolp, SECItem *dest, const void *src,
- const SEC_ASN1Template *theTemplate)
-{
- unsigned long encoding_length;
- SECStatus rv;
-
- PORT_Assert (dest == NULL || dest->data == NULL);
-
- encoding_length = 0;
- rv = SEC_ASN1Encode (src, theTemplate,
- sec_asn1e_encode_item_count, &encoding_length);
- if (rv != SECSuccess)
- return NULL;
-
- dest = sec_asn1e_allocate_item (poolp, dest, encoding_length);
- if (dest == NULL)
- return NULL;
-
- /* XXX necessary? This really just checks for a bug in the allocate fn */
- PORT_Assert (dest->data != NULL);
- if (dest->data == NULL)
- return NULL;
-
- dest->len = 0;
- (void) SEC_ASN1Encode (src, theTemplate, sec_asn1e_encode_item_store, dest);
-
- PORT_Assert (encoding_length == dest->len);
- return dest;
-}
-
-
-static SECItem *
-sec_asn1e_integer(PRArenaPool *poolp, SECItem *dest, unsigned long value,
- PRBool is_unsigned)
-{
- unsigned long copy;
- unsigned char sign;
- int len = 0;
-
- /*
- * Determine the length of the encoded value (minimum of 1).
- */
- copy = value;
- do {
- len++;
- sign = (unsigned char)(copy & 0x80);
- copy >>= 8;
- } while (copy);
-
- /*
- * If 'value' is non-negative, and the high bit of the last
- * byte we counted was set, we need to add one to the length so
- * we put a high-order zero byte in the encoding.
- */
- if (sign && (is_unsigned || (long)value >= 0))
- len++;
-
- /*
- * Allocate the item (if necessary) and the data pointer within.
- */
- dest = sec_asn1e_allocate_item (poolp, dest, len);
- if (dest == NULL)
- return NULL;
-
- /*
- * Store the value, byte by byte, in the item.
- */
- dest->len = len;
- while (len) {
- dest->data[--len] = (unsigned char)value;
- value >>= 8;
- }
- PORT_Assert (value == 0);
-
- return dest;
-}
-
-
-SECItem *
-SEC_ASN1EncodeInteger(PRArenaPool *poolp, SECItem *dest, long value)
-{
- return sec_asn1e_integer (poolp, dest, (unsigned long) value, PR_FALSE);
-}
-
-
-SECItem *
-SEC_ASN1EncodeUnsignedInteger(PRArenaPool *poolp,
- SECItem *dest, unsigned long value)
-{
- return sec_asn1e_integer (poolp, dest, value, PR_TRUE);
-}
diff --git a/security/nss/lib/util/secasn1t.h b/security/nss/lib/util/secasn1t.h
deleted file mode 100644
index c662b0ea4..000000000
--- a/security/nss/lib/util/secasn1t.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Types for encoding/decoding of ASN.1 using BER/DER (Basic/Distinguished
- * Encoding Rules).
- *
- * $Id$
- */
-
-#ifndef _SECASN1T_H_
-#define _SECASN1T_H_
-
-#include "utilrename.h"
-
-/*
-** An array of these structures defines a BER/DER encoding for an object.
-**
-** The array usually starts with a dummy entry whose kind is SEC_ASN1_SEQUENCE;
-** such an array is terminated with an entry where kind == 0. (An array
-** which consists of a single component does not require a second dummy
-** entry -- the array is only searched as long as previous component(s)
-** instruct it.)
-*/
-typedef struct sec_ASN1Template_struct {
- /*
- ** Kind of item being decoded/encoded, including tags and modifiers.
- */
- unsigned long kind;
-
- /*
- ** The value is the offset from the base of the structure to the
- ** field that holds the value being decoded/encoded.
- */
- unsigned long offset;
-
- /*
- ** When kind suggests it (SEC_ASN1_POINTER, SEC_ASN1_GROUP, SEC_ASN1_INLINE,
- ** or a component that is *not* a SEC_ASN1_UNIVERSAL), this points to
- ** a sub-template for nested encoding/decoding,
- ** OR, iff SEC_ASN1_DYNAMIC is set, then this is a pointer to a pointer
- ** to a function which will return the appropriate template when called
- ** at runtime. NOTE! that explicit level of indirection, which is
- ** necessary because ANSI does not allow you to store a function
- ** pointer directly as a "void *" so we must store it separately and
- ** dereference it to get at the function pointer itself.
- */
- const void *sub;
-
- /*
- ** In the first element of a template array, the value is the size
- ** of the structure to allocate when this template is being referenced
- ** by another template via SEC_ASN1_POINTER or SEC_ASN1_GROUP.
- ** In all other cases, the value is ignored.
- */
- unsigned int size;
-} SEC_ASN1Template;
-
-
-/* default size used for allocation of encoding/decoding stuff */
-/* XXX what is the best value here? */
-#define SEC_ASN1_DEFAULT_ARENA_SIZE (2048)
-
-/*
-** BER/DER values for ASN.1 identifier octets.
-*/
-#define SEC_ASN1_TAG_MASK 0xff
-
-/*
- * BER/DER universal type tag numbers.
- * The values are defined by the X.208 standard; do not change them!
- * NOTE: if you add anything to this list, you must add code to secasn1d.c
- * to accept the tag, and probably also to secasn1e.c to encode it.
- * XXX It appears some have been added recently without being added to
- * the code; so need to go through the list now and double-check them all.
- * (Look especially at those added in revision 1.10.)
- */
-#define SEC_ASN1_TAGNUM_MASK 0x1f
-#define SEC_ASN1_BOOLEAN 0x01
-#define SEC_ASN1_INTEGER 0x02
-#define SEC_ASN1_BIT_STRING 0x03
-#define SEC_ASN1_OCTET_STRING 0x04
-#define SEC_ASN1_NULL 0x05
-#define SEC_ASN1_OBJECT_ID 0x06
-#define SEC_ASN1_OBJECT_DESCRIPTOR 0x07
-/* External type and instance-of type 0x08 */
-#define SEC_ASN1_REAL 0x09
-#define SEC_ASN1_ENUMERATED 0x0a
-#define SEC_ASN1_EMBEDDED_PDV 0x0b
-#define SEC_ASN1_UTF8_STRING 0x0c
-/* 0x0d */
-/* 0x0e */
-/* 0x0f */
-#define SEC_ASN1_SEQUENCE 0x10
-#define SEC_ASN1_SET 0x11
-#define SEC_ASN1_NUMERIC_STRING 0x12
-#define SEC_ASN1_PRINTABLE_STRING 0x13
-#define SEC_ASN1_T61_STRING 0x14
-#define SEC_ASN1_VIDEOTEX_STRING 0x15
-#define SEC_ASN1_IA5_STRING 0x16
-#define SEC_ASN1_UTC_TIME 0x17
-#define SEC_ASN1_GENERALIZED_TIME 0x18
-#define SEC_ASN1_GRAPHIC_STRING 0x19
-#define SEC_ASN1_VISIBLE_STRING 0x1a
-#define SEC_ASN1_GENERAL_STRING 0x1b
-#define SEC_ASN1_UNIVERSAL_STRING 0x1c
-/* 0x1d */
-#define SEC_ASN1_BMP_STRING 0x1e
-#define SEC_ASN1_HIGH_TAG_NUMBER 0x1f
-#define SEC_ASN1_TELETEX_STRING SEC_ASN1_T61_STRING
-
-/*
-** Modifiers to type tags. These are also specified by a/the
-** standard, and must not be changed.
-*/
-
-#define SEC_ASN1_METHOD_MASK 0x20
-#define SEC_ASN1_PRIMITIVE 0x00
-#define SEC_ASN1_CONSTRUCTED 0x20
-
-#define SEC_ASN1_CLASS_MASK 0xc0
-#define SEC_ASN1_UNIVERSAL 0x00
-#define SEC_ASN1_APPLICATION 0x40
-#define SEC_ASN1_CONTEXT_SPECIFIC 0x80
-#define SEC_ASN1_PRIVATE 0xc0
-
-/*
-** Our additions, used for templates.
-** These are not defined by any standard; the values are used internally only.
-** Just be careful to keep them out of the low 8 bits.
-** XXX finish comments
-*/
-#define SEC_ASN1_OPTIONAL 0x00100
-#define SEC_ASN1_EXPLICIT 0x00200
-#define SEC_ASN1_ANY 0x00400
-#define SEC_ASN1_INLINE 0x00800
-#define SEC_ASN1_POINTER 0x01000
-#define SEC_ASN1_GROUP 0x02000 /* with SET or SEQUENCE means
- * SET OF or SEQUENCE OF */
-#define SEC_ASN1_DYNAMIC 0x04000 /* subtemplate is found by calling
- * a function at runtime */
-#define SEC_ASN1_SKIP 0x08000 /* skip a field; only for decoding */
-#define SEC_ASN1_INNER 0x10000 /* with ANY means capture the
- * contents only (not the id, len,
- * or eoc); only for decoding */
-#define SEC_ASN1_SAVE 0x20000 /* stash away the encoded bytes first;
- * only for decoding */
-#define SEC_ASN1_MAY_STREAM 0x40000 /* field or one of its sub-fields may
- * stream in and so should encode as
- * indefinite-length when streaming
- * has been indicated; only for
- * encoding */
-#define SEC_ASN1_SKIP_REST 0x80000 /* skip all following fields;
- only for decoding */
-#define SEC_ASN1_CHOICE 0x100000 /* pick one from a template */
-#define SEC_ASN1_NO_STREAM 0X200000 /* This entry will not stream
- even if the sub-template says
- streaming is possible. Helps
- to solve ambiguities with potential
- streaming entries that are
- optional */
-#define SEC_ASN1_DEBUG_BREAK 0X400000 /* put this in your template and the
- decoder will assert when it
- processes it. Only for use with
- SEC_QuickDERDecodeItem */
-
-
-
-/* Shorthand/Aliases */
-#define SEC_ASN1_SEQUENCE_OF (SEC_ASN1_GROUP | SEC_ASN1_SEQUENCE)
-#define SEC_ASN1_SET_OF (SEC_ASN1_GROUP | SEC_ASN1_SET)
-#define SEC_ASN1_ANY_CONTENTS (SEC_ASN1_ANY | SEC_ASN1_INNER)
-
-/* Maximum depth of nested SEQUENCEs and SETs */
-#define SEC_ASN1D_MAX_DEPTH 32
-
-/*
-** Function used for SEC_ASN1_DYNAMIC.
-** "arg" is a pointer to the structure being encoded/decoded
-** "enc", when true, means that we are encoding (false means decoding)
-*/
-typedef const SEC_ASN1Template * SEC_ASN1TemplateChooser(void *arg, PRBool enc);
-typedef SEC_ASN1TemplateChooser * SEC_ASN1TemplateChooserPtr;
-
-#if defined(_WIN32) || defined(ANDROID)
-#define SEC_ASN1_GET(x) NSS_Get_##x(NULL, PR_FALSE)
-#define SEC_ASN1_SUB(x) &p_NSS_Get_##x
-#define SEC_ASN1_XTRN SEC_ASN1_DYNAMIC
-#define SEC_ASN1_MKSUB(x) \
-static const SEC_ASN1TemplateChooserPtr p_NSS_Get_##x = &NSS_Get_##x;
-#else
-#define SEC_ASN1_GET(x) x
-#define SEC_ASN1_SUB(x) x
-#define SEC_ASN1_XTRN 0
-#define SEC_ASN1_MKSUB(x)
-#endif
-
-#define SEC_ASN1_CHOOSER_DECLARE(x) \
-extern const SEC_ASN1Template * NSS_Get_##x (void *arg, PRBool enc);
-
-#define SEC_ASN1_CHOOSER_IMPLEMENT(x) \
-const SEC_ASN1Template * NSS_Get_##x(void * arg, PRBool enc) \
-{ return x; }
-
-/*
-** Opaque object used by the decoder to store state.
-*/
-typedef struct sec_DecoderContext_struct SEC_ASN1DecoderContext;
-
-/*
-** Opaque object used by the encoder to store state.
-*/
-typedef struct sec_EncoderContext_struct SEC_ASN1EncoderContext;
-
-/*
- * This is used to describe to a filter function the bytes that are
- * being passed to it. This is only useful when the filter is an "outer"
- * one, meaning it expects to get *all* of the bytes not just the
- * contents octets.
- */
-typedef enum {
- SEC_ASN1_Identifier = 0,
- SEC_ASN1_Length = 1,
- SEC_ASN1_Contents = 2,
- SEC_ASN1_EndOfContents = 3
-} SEC_ASN1EncodingPart;
-
-/*
- * Type of the function pointer used either for decoding or encoding,
- * when doing anything "funny" (e.g. manipulating the data stream)
- */
-typedef void (* SEC_ASN1NotifyProc)(void *arg, PRBool before,
- void *dest, int real_depth);
-
-/*
- * Type of the function pointer used for grabbing encoded bytes.
- * This can be used during either encoding or decoding, as follows...
- *
- * When decoding, this can be used to filter the encoded bytes as they
- * are parsed. This is what you would do if you wanted to process the data
- * along the way (like to decrypt it, or to perform a hash on it in order
- * to do a signature check later). See SEC_ASN1DecoderSetFilterProc().
- * When processing only part of the encoded bytes is desired, you "watch"
- * for the field(s) you are interested in with a "notify proc" (see
- * SEC_ASN1DecoderSetNotifyProc()) and for even finer granularity (e.g. to
- * ignore all by the contents bytes) you pay attention to the "data_kind"
- * parameter.
- *
- * When encoding, this is the specification for the output function which
- * will receive the bytes as they are encoded. The output function can
- * perform any postprocessing necessary (like hashing (some of) the data
- * to create a digest that gets included at the end) as well as shoving
- * the data off wherever it needs to go. (In order to "tune" any processing,
- * you can set a "notify proc" as described above in the decoding case.)
- *
- * The parameters:
- * - "arg" is an opaque pointer that you provided at the same time you
- * specified a function of this type
- * - "data" is a buffer of length "len", containing the encoded bytes
- * - "depth" is how deep in a nested encoding we are (it is not usually
- * valuable, but can be useful sometimes so I included it)
- * - "data_kind" tells you if these bytes are part of the ASN.1 encoded
- * octets for identifier, length, contents, or end-of-contents
- */
-typedef void (* SEC_ASN1WriteProc)(void *arg,
- const char *data, unsigned long len,
- int depth, SEC_ASN1EncodingPart data_kind);
-
-#endif /* _SECASN1T_H_ */
diff --git a/security/nss/lib/util/secasn1u.c b/security/nss/lib/util/secasn1u.c
deleted file mode 100644
index 98bdbe0af..000000000
--- a/security/nss/lib/util/secasn1u.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Utility routines to complement the ASN.1 encoding and decoding functions.
- *
- * $Id$
- */
-
-#include "secasn1.h"
-
-
-/*
- * We have a length that needs to be encoded; how many bytes will the
- * encoding take?
- *
- * The rules are that 0 - 0x7f takes one byte (the length itself is the
- * entire encoding); everything else takes one plus the number of bytes
- * in the length.
- */
-int
-SEC_ASN1LengthLength (unsigned long len)
-{
- int lenlen = 1;
-
- if (len > 0x7f) {
- do {
- lenlen++;
- len >>= 8;
- } while (len);
- }
-
- return lenlen;
-}
-
-
-/*
- * XXX Move over (and rewrite as appropriate) the rest of the
- * stuff in dersubr.c!
- */
-
-
-/*
- * Find the appropriate subtemplate for the given template.
- * This may involve calling a "chooser" function, or it may just
- * be right there. In either case, it is expected to *have* a
- * subtemplate; this is asserted in debug builds (in non-debug
- * builds, NULL will be returned).
- *
- * "thing" is a pointer to the structure being encoded/decoded
- * "encoding", when true, means that we are in the process of encoding
- * (as opposed to in the process of decoding)
- */
-const SEC_ASN1Template *
-SEC_ASN1GetSubtemplate (const SEC_ASN1Template *theTemplate, void *thing,
- PRBool encoding)
-{
- const SEC_ASN1Template *subt = NULL;
-
- PORT_Assert (theTemplate->sub != NULL);
- if (theTemplate->sub != NULL) {
- if (theTemplate->kind & SEC_ASN1_DYNAMIC) {
- SEC_ASN1TemplateChooserPtr chooserp;
-
- chooserp = *(SEC_ASN1TemplateChooserPtr *) theTemplate->sub;
- if (chooserp) {
- if (thing != NULL)
- thing = (char *)thing - theTemplate->offset;
- subt = (* chooserp)(thing, encoding);
- }
- } else {
- subt = (SEC_ASN1Template*)theTemplate->sub;
- }
- }
- return subt;
-}
-
-PRBool SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate)
-{
- if (!theTemplate) {
- return PR_TRUE; /* it doesn't get any simpler than NULL */
- }
- /* only templates made of one primitive type or a choice of primitive
- types are considered simple */
- if (! (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK))) {
- return PR_TRUE; /* primitive type */
- }
- if (!(theTemplate->kind & SEC_ASN1_CHOICE)) {
- return PR_FALSE; /* no choice means not simple */
- }
- while (++theTemplate && theTemplate->kind) {
- if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) {
- return PR_FALSE; /* complex type */
- }
- }
- return PR_TRUE; /* choice of primitive types */
-}
-
diff --git a/security/nss/lib/util/seccomon.h b/security/nss/lib/util/seccomon.h
deleted file mode 100644
index a29655627..000000000
--- a/security/nss/lib/util/seccomon.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * seccomon.h - common data structures for security libraries
- *
- * This file should have lowest-common-denominator datastructures
- * for security libraries. It should not be dependent on any other
- * headers, and should not require linking with any libraries.
- *
- * $Id$
- */
-
-#ifndef _SECCOMMON_H_
-#define _SECCOMMON_H_
-
-#include "utilrename.h"
-#include "prtypes.h"
-
-
-#ifdef __cplusplus
-# define SEC_BEGIN_PROTOS extern "C" {
-# define SEC_END_PROTOS }
-#else
-# define SEC_BEGIN_PROTOS
-# define SEC_END_PROTOS
-#endif
-
-#include "secport.h"
-
-typedef enum {
- siBuffer = 0,
- siClearDataBuffer = 1,
- siCipherDataBuffer = 2,
- siDERCertBuffer = 3,
- siEncodedCertBuffer = 4,
- siDERNameBuffer = 5,
- siEncodedNameBuffer = 6,
- siAsciiNameString = 7,
- siAsciiString = 8,
- siDEROID = 9,
- siUnsignedInteger = 10,
- siUTCTime = 11,
- siGeneralizedTime = 12,
- siVisibleString = 13,
- siUTF8String = 14,
- siBMPString = 15
-} SECItemType;
-
-typedef struct SECItemStr SECItem;
-
-struct SECItemStr {
- SECItemType type;
- unsigned char *data;
- unsigned int len;
-};
-
-typedef struct SECItemArrayStr SECItemArray;
-
-struct SECItemArrayStr {
- SECItem *items;
- unsigned int len;
-};
-
-/*
-** A status code. Status's are used by procedures that return status
-** values. Again the motivation is so that a compiler can generate
-** warnings when return values are wrong. Correct testing of status codes:
-**
-** SECStatus rv;
-** rv = some_function (some_argument);
-** if (rv != SECSuccess)
-** do_an_error_thing();
-**
-*/
-typedef enum _SECStatus {
- SECWouldBlock = -2,
- SECFailure = -1,
- SECSuccess = 0
-} SECStatus;
-
-/*
-** A comparison code. Used for procedures that return comparision
-** values. Again the motivation is so that a compiler can generate
-** warnings when return values are wrong.
-*/
-typedef enum _SECComparison {
- SECLessThan = -1,
- SECEqual = 0,
- SECGreaterThan = 1
-} SECComparison;
-
-#endif /* _SECCOMMON_H_ */
diff --git a/security/nss/lib/util/secder.h b/security/nss/lib/util/secder.h
deleted file mode 100644
index 25fd3c972..000000000
--- a/security/nss/lib/util/secder.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SECDER_H_
-#define _SECDER_H_
-
-#include "utilrename.h"
-
-/*
- * secder.h - public data structures and prototypes for the DER encoding and
- * decoding utilities library
- *
- * $Id$
- */
-
-#include <time.h>
-
-#include "plarena.h"
-#include "prlong.h"
-
-#include "seccomon.h"
-#include "secdert.h"
-#include "prtime.h"
-
-SEC_BEGIN_PROTOS
-
-/*
-** Encode a data structure into DER.
-** "dest" will be filled in (and memory allocated) to hold the der
-** encoded structure in "src"
-** "t" is a template structure which defines the shape of the
-** stored data
-** "src" is a pointer to the structure that will be encoded
-*/
-extern SECStatus DER_Encode(PLArenaPool *arena, SECItem *dest, DERTemplate *t,
- void *src);
-
-extern SECStatus DER_Lengths(SECItem *item, int *header_len_p,
- PRUint32 *contents_len_p);
-
-/*
-** Lower level der subroutine that stores the standard header into "to".
-** The header is of variable length, based on encodingLen.
-** The return value is the new value of "to" after skipping over the header.
-** "to" is where the header will be stored
-** "code" is the der code to write
-** "encodingLen" is the number of bytes of data that will follow
-** the header
-*/
-extern unsigned char *DER_StoreHeader(unsigned char *to, unsigned int code,
- PRUint32 encodingLen);
-
-/*
-** Return the number of bytes it will take to hold a der encoded length.
-*/
-extern int DER_LengthLength(PRUint32 len);
-
-/*
-** Store a der encoded *signed* integer (whose value is "src") into "dst".
-** XXX This should really be enhanced to take a long.
-*/
-extern SECStatus DER_SetInteger(PLArenaPool *arena, SECItem *dst, PRInt32 src);
-
-/*
-** Store a der encoded *unsigned* integer (whose value is "src") into "dst".
-** XXX This should really be enhanced to take an unsigned long.
-*/
-extern SECStatus DER_SetUInteger(PLArenaPool *arena, SECItem *dst, PRUint32 src);
-
-/*
-** Decode a der encoded *signed* integer that is stored in "src".
-** If "-1" is returned, then the caller should check the error in
-** XP_GetError() to see if an overflow occurred (SEC_ERROR_BAD_DER).
-*/
-extern long DER_GetInteger(SECItem *src);
-
-/*
-** Decode a der encoded *unsigned* integer that is stored in "src".
-** If the ULONG_MAX is returned, then the caller should check the error
-** in XP_GetError() to see if an overflow occurred (SEC_ERROR_BAD_DER).
-*/
-extern unsigned long DER_GetUInteger(SECItem *src);
-
-/*
-** Convert an NSPR time value to a der encoded time value.
-** "result" is the der encoded time (memory is allocated)
-** "time" is the NSPR time value (Since Jan 1st, 1970).
-** time must be on or after January 1, 1950, and
-** before January 1, 2050
-** The caller is responsible for freeing up the buffer which
-** result->data points to upon a successful operation.
-*/
-extern SECStatus DER_TimeToUTCTime(SECItem *result, PRTime time);
-extern SECStatus DER_TimeToUTCTimeArena(PLArenaPool* arenaOpt,
- SECItem *dst, PRTime gmttime);
-
-
-/*
-** Convert an ascii encoded time value (according to DER rules) into
-** an NSPR time value.
-** "result" the resulting NSPR time
-** "string" the der notation ascii value to decode
-*/
-extern SECStatus DER_AsciiToTime(PRTime *result, const char *string);
-
-/*
-** Same as DER_AsciiToTime except takes an SECItem instead of a string
-*/
-extern SECStatus DER_UTCTimeToTime(PRTime *result, const SECItem *time);
-
-/*
-** Convert a DER encoded UTC time to an ascii time representation
-** "utctime" is the DER encoded UTC time to be converted. The
-** caller is responsible for deallocating the returned buffer.
-*/
-extern char *DER_UTCTimeToAscii(SECItem *utcTime);
-
-/*
-** Convert a DER encoded UTC time to an ascii time representation, but only
-** include the day, not the time.
-** "utctime" is the DER encoded UTC time to be converted.
-** The caller is responsible for deallocating the returned buffer.
-*/
-extern char *DER_UTCDayToAscii(SECItem *utctime);
-/* same thing for DER encoded GeneralizedTime */
-extern char *DER_GeneralizedDayToAscii(SECItem *gentime);
-/* same thing for either DER UTCTime or GeneralizedTime */
-extern char *DER_TimeChoiceDayToAscii(SECItem *timechoice);
-
-/*
-** Convert a PRTime time to a DER encoded Generalized time
-** gmttime must be on or after January 1, year 1 and
-** before January 1, 10000.
-*/
-extern SECStatus DER_TimeToGeneralizedTime(SECItem *dst, PRTime gmttime);
-extern SECStatus DER_TimeToGeneralizedTimeArena(PLArenaPool* arenaOpt,
- SECItem *dst, PRTime gmttime);
-
-/*
-** Convert a DER encoded Generalized time value into an NSPR time value.
-** "dst" the resulting NSPR time
-** "string" the der notation ascii value to decode
-*/
-extern SECStatus DER_GeneralizedTimeToTime(PRTime *dst, const SECItem *time);
-
-/*
-** Convert from a PRTime UTC time value to a formatted ascii value. The
-** caller is responsible for deallocating the returned buffer.
-*/
-extern char *CERT_UTCTime2FormattedAscii (PRTime utcTime, char *format);
-#define CERT_GeneralizedTime2FormattedAscii CERT_UTCTime2FormattedAscii
-
-/*
-** Convert from a PRTime Generalized time value to a formatted ascii value. The
-** caller is responsible for deallocating the returned buffer.
-*/
-extern char *CERT_GenTime2FormattedAscii (PRTime genTime, char *format);
-
-/*
-** decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME
-** or a SEC_ASN1_UTC_TIME
-*/
-
-extern SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input);
-
-/* encode a PRTime to an ASN.1 DER SECItem containing either a
- SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */
-
-extern SECStatus DER_EncodeTimeChoice(PLArenaPool* arena, SECItem* output,
- PRTime input);
-
-SEC_END_PROTOS
-
-#endif /* _SECDER_H_ */
-
diff --git a/security/nss/lib/util/secdert.h b/security/nss/lib/util/secdert.h
deleted file mode 100644
index 5e5976078..000000000
--- a/security/nss/lib/util/secdert.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SECDERT_H_
-#define _SECDERT_H_
-/*
- * secdert.h - public data structures for the DER encoding and
- * decoding utilities library
- *
- * $Id$
- */
-
-#include "utilrename.h"
-#include "seccomon.h"
-
-typedef struct DERTemplateStr DERTemplate;
-
-/*
-** An array of these structures defines an encoding for an object using DER.
-** The array usually starts with a dummy entry whose kind is DER_SEQUENCE;
-** such an array is terminated with an entry where kind == 0. (An array
-** which consists of a single component does not require a second dummy
-** entry -- the array is only searched as long as previous component(s)
-** instruct it.)
-*/
-struct DERTemplateStr {
- /*
- ** Kind of item being decoded/encoded, including tags and modifiers.
- */
- unsigned long kind;
-
- /*
- ** Offset from base of structure to field that holds the value
- ** being decoded/encoded.
- */
- unsigned int offset;
-
- /*
- ** When kind suggests it (DER_POINTER, DER_INDEFINITE, DER_INLINE),
- ** this points to a sub-template for nested encoding/decoding.
- */
- DERTemplate *sub;
-
- /*
- ** Argument value, dependent on "kind" and/or template placement
- ** within an array of templates:
- ** - In the first element of a template array, the value is the
- ** size of the structure to allocate when this template is being
- ** referenced by another template via DER_POINTER or DER_INDEFINITE.
- ** - In a component of a DER_SET or DER_SEQUENCE which is *not* a
- ** DER_UNIVERSAL type (that is, it has a class tag for either
- ** DER_APPLICATION, DER_CONTEXT_SPECIFIC, or DER_PRIVATE), the
- ** value is the underlying type of item being decoded/encoded.
- */
- unsigned long arg;
-};
-
-/************************************************************************/
-
-/* default chunksize for arenas used for DER stuff */
-#define DER_DEFAULT_CHUNKSIZE (2048)
-
-/*
-** BER/DER values for ASN.1 identifier octets.
-*/
-#define DER_TAG_MASK 0xff
-
-/*
- * BER/DER universal type tag numbers.
- * The values are defined by the X.208 standard; do not change them!
- * NOTE: if you add anything to this list, you must add code to derdec.c
- * to accept the tag, and probably also to derenc.c to encode it.
- */
-#define DER_TAGNUM_MASK 0x1f
-#define DER_BOOLEAN 0x01
-#define DER_INTEGER 0x02
-#define DER_BIT_STRING 0x03
-#define DER_OCTET_STRING 0x04
-#define DER_NULL 0x05
-#define DER_OBJECT_ID 0x06
-#define DER_SEQUENCE 0x10
-#define DER_SET 0x11
-#define DER_PRINTABLE_STRING 0x13
-#define DER_T61_STRING 0x14
-#define DER_IA5_STRING 0x16
-#define DER_UTC_TIME 0x17
-#define DER_VISIBLE_STRING 0x1a
-#define DER_HIGH_TAG_NUMBER 0x1f
-
-/*
-** Modifiers to type tags. These are also specified by a/the
-** standard, and must not be changed.
-*/
-
-#define DER_METHOD_MASK 0x20
-#define DER_PRIMITIVE 0x00
-#define DER_CONSTRUCTED 0x20
-
-#define DER_CLASS_MASK 0xc0
-#define DER_UNIVERSAL 0x00
-#define DER_APPLICATION 0x40
-#define DER_CONTEXT_SPECIFIC 0x80
-#define DER_PRIVATE 0xc0
-
-/*
-** Our additions, used for templates.
-** These are not defined by any standard; the values are used internally only.
-** Just be careful to keep them out of the low 8 bits.
-*/
-#define DER_OPTIONAL 0x00100
-#define DER_EXPLICIT 0x00200
-#define DER_ANY 0x00400
-#define DER_INLINE 0x00800
-#define DER_POINTER 0x01000
-#define DER_INDEFINITE 0x02000
-#define DER_DERPTR 0x04000
-#define DER_SKIP 0x08000
-#define DER_FORCE 0x10000
-#define DER_OUTER 0x40000 /* for DER_DERPTR */
-
-/*
-** Macro to convert der decoded bit string into a decoded octet
-** string. All it needs to do is fiddle with the length code.
-*/
-#define DER_ConvertBitString(item) \
-{ \
- (item)->len = ((item)->len + 7) >> 3; \
-}
-
-#endif /* _SECDERT_H_ */
diff --git a/security/nss/lib/util/secdig.c b/security/nss/lib/util/secdig.c
deleted file mode 100644
index 530c520d0..000000000
--- a/security/nss/lib/util/secdig.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-#include "secdig.h"
-
-#include "secoid.h"
-#include "secasn1.h"
-#include "secerr.h"
-
-/*
- * XXX Want to have a SGN_DecodeDigestInfo, like:
- * SGNDigestInfo *SGN_DecodeDigestInfo(SECItem *didata);
- * that creates a pool and allocates from it and decodes didata into
- * the newly allocated DigestInfo structure. Then fix secvfy.c (it
- * will no longer need an arena itself) to call this and then call
- * DestroyDigestInfo when it is done, then can remove the old template
- * above and keep our new template static and "hidden".
- */
-
-/*
- * XXX It might be nice to combine the following two functions (create
- * and encode). I think that is all anybody ever wants to do anyway.
- */
-
-SECItem *
-SGN_EncodeDigestInfo(PRArenaPool *poolp, SECItem *dest, SGNDigestInfo *diginfo)
-{
- return SEC_ASN1EncodeItem (poolp, dest, diginfo, sgn_DigestInfoTemplate);
-}
-
-SGNDigestInfo *
-SGN_CreateDigestInfo(SECOidTag algorithm, unsigned char *sig, unsigned len)
-{
- SGNDigestInfo *di;
- SECStatus rv;
- PRArenaPool *arena;
- SECItem *null_param;
- SECItem dummy_value;
-
- switch (algorithm) {
- case SEC_OID_MD2:
- case SEC_OID_MD5:
- case SEC_OID_SHA1:
- case SEC_OID_SHA224:
- case SEC_OID_SHA256:
- case SEC_OID_SHA384:
- case SEC_OID_SHA512:
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return NULL;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return NULL;
- }
-
- di = (SGNDigestInfo *) PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo));
- if (di == NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
-
- di->arena = arena;
-
- /*
- * PKCS #1 specifies that the AlgorithmID must have a NULL parameter
- * (as opposed to no parameter at all).
- */
- dummy_value.data = NULL;
- dummy_value.len = 0;
- null_param = SEC_ASN1EncodeItem(NULL, NULL, &dummy_value, SEC_NullTemplate);
- if (null_param == NULL) {
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(arena, &di->digestAlgorithm, algorithm,
- null_param);
-
- SECITEM_FreeItem(null_param, PR_TRUE);
-
- if (rv != SECSuccess) {
- goto loser;
- }
-
- di->digest.data = (unsigned char *) PORT_ArenaAlloc(arena, len);
- if (di->digest.data == NULL) {
- goto loser;
- }
-
- di->digest.len = len;
- PORT_Memcpy(di->digest.data, sig, len);
- return di;
-
- loser:
- SGN_DestroyDigestInfo(di);
- return NULL;
-}
-
-SGNDigestInfo *
-SGN_DecodeDigestInfo(SECItem *didata)
-{
- PRArenaPool *arena;
- SGNDigestInfo *di;
- SECStatus rv = SECFailure;
- SECItem diCopy = {siBuffer, NULL, 0};
-
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(arena == NULL)
- return NULL;
-
- rv = SECITEM_CopyItem(arena, &diCopy, didata);
- if (rv != SECSuccess) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
-
- di = (SGNDigestInfo *)PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo));
- if (di != NULL) {
- di->arena = arena;
- rv = SEC_QuickDERDecodeItem(arena, di, sgn_DigestInfoTemplate, &diCopy);
- }
-
- if ((di == NULL) || (rv != SECSuccess)) {
- PORT_FreeArena(arena, PR_FALSE);
- di = NULL;
- }
-
- return di;
-}
-
-void
-SGN_DestroyDigestInfo(SGNDigestInfo *di)
-{
- if (di && di->arena) {
- PORT_FreeArena(di->arena, PR_FALSE);
- }
-
- return;
-}
-
-SECStatus
-SGN_CopyDigestInfo(PRArenaPool *poolp, SGNDigestInfo *a, SGNDigestInfo *b)
-{
- SECStatus rv;
- void *mark;
-
- if((poolp == NULL) || (a == NULL) || (b == NULL))
- return SECFailure;
-
- mark = PORT_ArenaMark(poolp);
- a->arena = poolp;
- rv = SECOID_CopyAlgorithmID(poolp, &a->digestAlgorithm,
- &b->digestAlgorithm);
- if (rv == SECSuccess)
- rv = SECITEM_CopyItem(poolp, &a->digest, &b->digest);
-
- if (rv != SECSuccess) {
- PORT_ArenaRelease(poolp, mark);
- } else {
- PORT_ArenaUnmark(poolp, mark);
- }
-
- return rv;
-}
-
-SECComparison
-SGN_CompareDigestInfo(SGNDigestInfo *a, SGNDigestInfo *b)
-{
- SECComparison rv;
-
- /* Check signature algorithm's */
- rv = SECOID_CompareAlgorithmID(&a->digestAlgorithm, &b->digestAlgorithm);
- if (rv) return rv;
-
- /* Compare signature block length's */
- rv = SECITEM_CompareItem(&a->digest, &b->digest);
- return rv;
-}
diff --git a/security/nss/lib/util/secdig.h b/security/nss/lib/util/secdig.h
deleted file mode 100644
index f01c543d9..000000000
--- a/security/nss/lib/util/secdig.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * crypto.h - public data structures and prototypes for the crypto library
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _SECDIG_H_
-#define _SECDIG_H_
-
-#include "utilrename.h"
-#include "secdigt.h"
-
-#include "seccomon.h"
-#include "secasn1t.h"
-#include "secdert.h"
-
-SEC_BEGIN_PROTOS
-
-
-extern const SEC_ASN1Template sgn_DigestInfoTemplate[];
-
-SEC_ASN1_CHOOSER_DECLARE(sgn_DigestInfoTemplate)
-
-/****************************************/
-/*
-** Digest-info functions
-*/
-
-/*
-** Create a new digest-info object
-** "algorithm" one of SEC_OID_MD2, SEC_OID_MD5, or SEC_OID_SHA1
-** "sig" the raw signature data (from MD2 or MD5)
-** "sigLen" the length of the signature data
-**
-** NOTE: this is a low level routine used to prepare some data for PKCS#1
-** digital signature formatting.
-**
-** XXX It might be nice to combine the create and encode functions.
-** I think that is all anybody ever wants to do anyway.
-*/
-extern SGNDigestInfo *SGN_CreateDigestInfo(SECOidTag algorithm,
- unsigned char *sig,
- unsigned int sigLen);
-
-/*
-** Destroy a digest-info object
-*/
-extern void SGN_DestroyDigestInfo(SGNDigestInfo *info);
-
-/*
-** Encode a digest-info object
-** "poolp" is where to allocate the result from; it can be NULL in
-** which case generic heap allocation (XP_ALLOC) will be used
-** "dest" is where to store the result; it can be NULL, in which case
-** it will be allocated (from poolp or heap, as explained above)
-** "diginfo" is the object to be encoded
-** The return value is NULL if any error occurred, otherwise it is the
-** resulting SECItem (either allocated or the same as the "dest" parameter).
-**
-** XXX It might be nice to combine the create and encode functions.
-** I think that is all anybody ever wants to do anyway.
-*/
-extern SECItem *SGN_EncodeDigestInfo(PLArenaPool *poolp, SECItem *dest,
- SGNDigestInfo *diginfo);
-
-/*
-** Decode a DER encoded digest info objct.
-** didata is thr source of the encoded digest.
-** The return value is NULL if an error occurs. Otherwise, a
-** digest info object which is allocated within it's own
-** pool is returned. The digest info should be deleted
-** by later calling SGN_DestroyDigestInfo.
-*/
-extern SGNDigestInfo *SGN_DecodeDigestInfo(SECItem *didata);
-
-
-/*
-** Copy digest info.
-** poolp is the arena to which the digest will be copied.
-** a is the destination digest, it must be non-NULL.
-** b is the source digest
-** This function is for copying digests. It allows digests
-** to be copied into a specified pool. If the digest is in
-** the same pool as other data, you do not want to delete
-** the digest by calling SGN_DestroyDigestInfo.
-** A return value of SECFailure indicates an error. A return
-** of SECSuccess indicates no error occurred.
-*/
-extern SECStatus SGN_CopyDigestInfo(PLArenaPool *poolp,
- SGNDigestInfo *a,
- SGNDigestInfo *b);
-
-/*
-** Compare two digest-info objects, returning the difference between
-** them.
-*/
-extern SECComparison SGN_CompareDigestInfo(SGNDigestInfo *a, SGNDigestInfo *b);
-
-
-SEC_END_PROTOS
-
-#endif /* _SECDIG_H_ */
diff --git a/security/nss/lib/util/secdigt.h b/security/nss/lib/util/secdigt.h
deleted file mode 100644
index 5729dcc85..000000000
--- a/security/nss/lib/util/secdigt.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * secdigt.h - public data structures for digestinfos from the util lib.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id$ */
-
-#ifndef _SECDIGT_H_
-#define _SECDIGT_H_
-
-#include "utilrename.h"
-#include "plarena.h"
-#include "secoidt.h"
-#include "secitem.h"
-
-/*
-** A PKCS#1 digest-info object
-*/
-struct SGNDigestInfoStr {
- PLArenaPool * arena;
- SECAlgorithmID digestAlgorithm;
- SECItem digest;
-};
-typedef struct SGNDigestInfoStr SGNDigestInfo;
-
-
-
-#endif /* _SECDIGT_H_ */
diff --git a/security/nss/lib/util/secerr.h b/security/nss/lib/util/secerr.h
deleted file mode 100644
index 490dabaf4..000000000
--- a/security/nss/lib/util/secerr.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __SEC_ERR_H_
-#define __SEC_ERR_H_
-
-#include "utilrename.h"
-
-#define SEC_ERROR_BASE (-0x2000)
-#define SEC_ERROR_LIMIT (SEC_ERROR_BASE + 1000)
-
-#define IS_SEC_ERROR(code) \
- (((code) >= SEC_ERROR_BASE) && ((code) < SEC_ERROR_LIMIT))
-
-#ifndef NO_SECURITY_ERROR_ENUM
-typedef enum {
-SEC_ERROR_IO = SEC_ERROR_BASE + 0,
-SEC_ERROR_LIBRARY_FAILURE = SEC_ERROR_BASE + 1,
-SEC_ERROR_BAD_DATA = SEC_ERROR_BASE + 2,
-SEC_ERROR_OUTPUT_LEN = SEC_ERROR_BASE + 3,
-SEC_ERROR_INPUT_LEN = SEC_ERROR_BASE + 4,
-SEC_ERROR_INVALID_ARGS = SEC_ERROR_BASE + 5,
-SEC_ERROR_INVALID_ALGORITHM = SEC_ERROR_BASE + 6,
-SEC_ERROR_INVALID_AVA = SEC_ERROR_BASE + 7,
-SEC_ERROR_INVALID_TIME = SEC_ERROR_BASE + 8,
-SEC_ERROR_BAD_DER = SEC_ERROR_BASE + 9,
-SEC_ERROR_BAD_SIGNATURE = SEC_ERROR_BASE + 10,
-SEC_ERROR_EXPIRED_CERTIFICATE = SEC_ERROR_BASE + 11,
-SEC_ERROR_REVOKED_CERTIFICATE = SEC_ERROR_BASE + 12,
-SEC_ERROR_UNKNOWN_ISSUER = SEC_ERROR_BASE + 13,
-SEC_ERROR_BAD_KEY = SEC_ERROR_BASE + 14,
-SEC_ERROR_BAD_PASSWORD = SEC_ERROR_BASE + 15,
-SEC_ERROR_RETRY_PASSWORD = SEC_ERROR_BASE + 16,
-SEC_ERROR_NO_NODELOCK = SEC_ERROR_BASE + 17,
-SEC_ERROR_BAD_DATABASE = SEC_ERROR_BASE + 18,
-SEC_ERROR_NO_MEMORY = SEC_ERROR_BASE + 19,
-SEC_ERROR_UNTRUSTED_ISSUER = SEC_ERROR_BASE + 20,
-SEC_ERROR_UNTRUSTED_CERT = SEC_ERROR_BASE + 21,
-SEC_ERROR_DUPLICATE_CERT = (SEC_ERROR_BASE + 22),
-SEC_ERROR_DUPLICATE_CERT_NAME = (SEC_ERROR_BASE + 23),
-SEC_ERROR_ADDING_CERT = (SEC_ERROR_BASE + 24),
-SEC_ERROR_FILING_KEY = (SEC_ERROR_BASE + 25),
-SEC_ERROR_NO_KEY = (SEC_ERROR_BASE + 26),
-SEC_ERROR_CERT_VALID = (SEC_ERROR_BASE + 27),
-SEC_ERROR_CERT_NOT_VALID = (SEC_ERROR_BASE + 28),
-SEC_ERROR_CERT_NO_RESPONSE = (SEC_ERROR_BASE + 29),
-SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = (SEC_ERROR_BASE + 30),
-SEC_ERROR_CRL_EXPIRED = (SEC_ERROR_BASE + 31),
-SEC_ERROR_CRL_BAD_SIGNATURE = (SEC_ERROR_BASE + 32),
-SEC_ERROR_CRL_INVALID = (SEC_ERROR_BASE + 33),
-SEC_ERROR_EXTENSION_VALUE_INVALID = (SEC_ERROR_BASE + 34),
-SEC_ERROR_EXTENSION_NOT_FOUND = (SEC_ERROR_BASE + 35),
-SEC_ERROR_CA_CERT_INVALID = (SEC_ERROR_BASE + 36),
-SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID = (SEC_ERROR_BASE + 37),
-SEC_ERROR_CERT_USAGES_INVALID = (SEC_ERROR_BASE + 38),
-SEC_INTERNAL_ONLY = (SEC_ERROR_BASE + 39),
-SEC_ERROR_INVALID_KEY = (SEC_ERROR_BASE + 40),
-SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION = (SEC_ERROR_BASE + 41),
-SEC_ERROR_OLD_CRL = (SEC_ERROR_BASE + 42),
-SEC_ERROR_NO_EMAIL_CERT = (SEC_ERROR_BASE + 43),
-SEC_ERROR_NO_RECIPIENT_CERTS_QUERY = (SEC_ERROR_BASE + 44),
-SEC_ERROR_NOT_A_RECIPIENT = (SEC_ERROR_BASE + 45),
-SEC_ERROR_PKCS7_KEYALG_MISMATCH = (SEC_ERROR_BASE + 46),
-SEC_ERROR_PKCS7_BAD_SIGNATURE = (SEC_ERROR_BASE + 47),
-SEC_ERROR_UNSUPPORTED_KEYALG = (SEC_ERROR_BASE + 48),
-SEC_ERROR_DECRYPTION_DISALLOWED = (SEC_ERROR_BASE + 49),
-/* Fortezza Alerts */
-XP_SEC_FORTEZZA_BAD_CARD = (SEC_ERROR_BASE + 50),
-XP_SEC_FORTEZZA_NO_CARD = (SEC_ERROR_BASE + 51),
-XP_SEC_FORTEZZA_NONE_SELECTED = (SEC_ERROR_BASE + 52),
-XP_SEC_FORTEZZA_MORE_INFO = (SEC_ERROR_BASE + 53),
-XP_SEC_FORTEZZA_PERSON_NOT_FOUND = (SEC_ERROR_BASE + 54),
-XP_SEC_FORTEZZA_NO_MORE_INFO = (SEC_ERROR_BASE + 55),
-XP_SEC_FORTEZZA_BAD_PIN = (SEC_ERROR_BASE + 56),
-XP_SEC_FORTEZZA_PERSON_ERROR = (SEC_ERROR_BASE + 57),
-SEC_ERROR_NO_KRL = (SEC_ERROR_BASE + 58),
-SEC_ERROR_KRL_EXPIRED = (SEC_ERROR_BASE + 59),
-SEC_ERROR_KRL_BAD_SIGNATURE = (SEC_ERROR_BASE + 60),
-SEC_ERROR_REVOKED_KEY = (SEC_ERROR_BASE + 61),
-SEC_ERROR_KRL_INVALID = (SEC_ERROR_BASE + 62),
-SEC_ERROR_NEED_RANDOM = (SEC_ERROR_BASE + 63),
-SEC_ERROR_NO_MODULE = (SEC_ERROR_BASE + 64),
-SEC_ERROR_NO_TOKEN = (SEC_ERROR_BASE + 65),
-SEC_ERROR_READ_ONLY = (SEC_ERROR_BASE + 66),
-SEC_ERROR_NO_SLOT_SELECTED = (SEC_ERROR_BASE + 67),
-SEC_ERROR_CERT_NICKNAME_COLLISION = (SEC_ERROR_BASE + 68),
-SEC_ERROR_KEY_NICKNAME_COLLISION = (SEC_ERROR_BASE + 69),
-SEC_ERROR_SAFE_NOT_CREATED = (SEC_ERROR_BASE + 70),
-SEC_ERROR_BAGGAGE_NOT_CREATED = (SEC_ERROR_BASE + 71),
-XP_JAVA_REMOVE_PRINCIPAL_ERROR = (SEC_ERROR_BASE + 72),
-XP_JAVA_DELETE_PRIVILEGE_ERROR = (SEC_ERROR_BASE + 73),
-XP_JAVA_CERT_NOT_EXISTS_ERROR = (SEC_ERROR_BASE + 74),
-SEC_ERROR_BAD_EXPORT_ALGORITHM = (SEC_ERROR_BASE + 75),
-SEC_ERROR_EXPORTING_CERTIFICATES = (SEC_ERROR_BASE + 76),
-SEC_ERROR_IMPORTING_CERTIFICATES = (SEC_ERROR_BASE + 77),
-SEC_ERROR_PKCS12_DECODING_PFX = (SEC_ERROR_BASE + 78),
-SEC_ERROR_PKCS12_INVALID_MAC = (SEC_ERROR_BASE + 79),
-SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM = (SEC_ERROR_BASE + 80),
-SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE = (SEC_ERROR_BASE + 81),
-SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE = (SEC_ERROR_BASE + 82),
-SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM = (SEC_ERROR_BASE + 83),
-SEC_ERROR_PKCS12_UNSUPPORTED_VERSION = (SEC_ERROR_BASE + 84),
-SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT = (SEC_ERROR_BASE + 85),
-SEC_ERROR_PKCS12_CERT_COLLISION = (SEC_ERROR_BASE + 86),
-SEC_ERROR_USER_CANCELLED = (SEC_ERROR_BASE + 87),
-SEC_ERROR_PKCS12_DUPLICATE_DATA = (SEC_ERROR_BASE + 88),
-SEC_ERROR_MESSAGE_SEND_ABORTED = (SEC_ERROR_BASE + 89),
-SEC_ERROR_INADEQUATE_KEY_USAGE = (SEC_ERROR_BASE + 90),
-SEC_ERROR_INADEQUATE_CERT_TYPE = (SEC_ERROR_BASE + 91),
-SEC_ERROR_CERT_ADDR_MISMATCH = (SEC_ERROR_BASE + 92),
-SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY = (SEC_ERROR_BASE + 93),
-SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN = (SEC_ERROR_BASE + 94),
-SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME = (SEC_ERROR_BASE + 95),
-SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY = (SEC_ERROR_BASE + 96),
-SEC_ERROR_PKCS12_UNABLE_TO_WRITE = (SEC_ERROR_BASE + 97),
-SEC_ERROR_PKCS12_UNABLE_TO_READ = (SEC_ERROR_BASE + 98),
-SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED = (SEC_ERROR_BASE + 99),
-SEC_ERROR_KEYGEN_FAIL = (SEC_ERROR_BASE + 100),
-SEC_ERROR_INVALID_PASSWORD = (SEC_ERROR_BASE + 101),
-SEC_ERROR_RETRY_OLD_PASSWORD = (SEC_ERROR_BASE + 102),
-SEC_ERROR_BAD_NICKNAME = (SEC_ERROR_BASE + 103),
-SEC_ERROR_NOT_FORTEZZA_ISSUER = (SEC_ERROR_BASE + 104),
-SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY = (SEC_ERROR_BASE + 105),
-SEC_ERROR_JS_INVALID_MODULE_NAME = (SEC_ERROR_BASE + 106),
-SEC_ERROR_JS_INVALID_DLL = (SEC_ERROR_BASE + 107),
-SEC_ERROR_JS_ADD_MOD_FAILURE = (SEC_ERROR_BASE + 108),
-SEC_ERROR_JS_DEL_MOD_FAILURE = (SEC_ERROR_BASE + 109),
-SEC_ERROR_OLD_KRL = (SEC_ERROR_BASE + 110),
-SEC_ERROR_CKL_CONFLICT = (SEC_ERROR_BASE + 111),
-SEC_ERROR_CERT_NOT_IN_NAME_SPACE = (SEC_ERROR_BASE + 112),
-SEC_ERROR_KRL_NOT_YET_VALID = (SEC_ERROR_BASE + 113),
-SEC_ERROR_CRL_NOT_YET_VALID = (SEC_ERROR_BASE + 114),
-SEC_ERROR_UNKNOWN_CERT = (SEC_ERROR_BASE + 115),
-SEC_ERROR_UNKNOWN_SIGNER = (SEC_ERROR_BASE + 116),
-SEC_ERROR_CERT_BAD_ACCESS_LOCATION = (SEC_ERROR_BASE + 117),
-SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE = (SEC_ERROR_BASE + 118),
-SEC_ERROR_OCSP_BAD_HTTP_RESPONSE = (SEC_ERROR_BASE + 119),
-SEC_ERROR_OCSP_MALFORMED_REQUEST = (SEC_ERROR_BASE + 120),
-SEC_ERROR_OCSP_SERVER_ERROR = (SEC_ERROR_BASE + 121),
-SEC_ERROR_OCSP_TRY_SERVER_LATER = (SEC_ERROR_BASE + 122),
-SEC_ERROR_OCSP_REQUEST_NEEDS_SIG = (SEC_ERROR_BASE + 123),
-SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST = (SEC_ERROR_BASE + 124),
-SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS = (SEC_ERROR_BASE + 125),
-SEC_ERROR_OCSP_UNKNOWN_CERT = (SEC_ERROR_BASE + 126),
-SEC_ERROR_OCSP_NOT_ENABLED = (SEC_ERROR_BASE + 127),
-SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER = (SEC_ERROR_BASE + 128),
-SEC_ERROR_OCSP_MALFORMED_RESPONSE = (SEC_ERROR_BASE + 129),
-SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE = (SEC_ERROR_BASE + 130),
-SEC_ERROR_OCSP_FUTURE_RESPONSE = (SEC_ERROR_BASE + 131),
-SEC_ERROR_OCSP_OLD_RESPONSE = (SEC_ERROR_BASE + 132),
-/* smime stuff */
-SEC_ERROR_DIGEST_NOT_FOUND = (SEC_ERROR_BASE + 133),
-SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE = (SEC_ERROR_BASE + 134),
-SEC_ERROR_MODULE_STUCK = (SEC_ERROR_BASE + 135),
-SEC_ERROR_BAD_TEMPLATE = (SEC_ERROR_BASE + 136),
-SEC_ERROR_CRL_NOT_FOUND = (SEC_ERROR_BASE + 137),
-SEC_ERROR_REUSED_ISSUER_AND_SERIAL = (SEC_ERROR_BASE + 138),
-SEC_ERROR_BUSY = (SEC_ERROR_BASE + 139),
-SEC_ERROR_EXTRA_INPUT = (SEC_ERROR_BASE + 140),
-/* error codes used by elliptic curve code */
-SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE = (SEC_ERROR_BASE + 141),
-SEC_ERROR_UNSUPPORTED_EC_POINT_FORM = (SEC_ERROR_BASE + 142),
-SEC_ERROR_UNRECOGNIZED_OID = (SEC_ERROR_BASE + 143),
-SEC_ERROR_OCSP_INVALID_SIGNING_CERT = (SEC_ERROR_BASE + 144),
-/* new revocation errors */
-SEC_ERROR_REVOKED_CERTIFICATE_CRL = (SEC_ERROR_BASE + 145),
-SEC_ERROR_REVOKED_CERTIFICATE_OCSP = (SEC_ERROR_BASE + 146),
-SEC_ERROR_CRL_INVALID_VERSION = (SEC_ERROR_BASE + 147),
-SEC_ERROR_CRL_V1_CRITICAL_EXTENSION = (SEC_ERROR_BASE + 148),
-SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION = (SEC_ERROR_BASE + 149),
-SEC_ERROR_UNKNOWN_OBJECT_TYPE = (SEC_ERROR_BASE + 150),
-SEC_ERROR_INCOMPATIBLE_PKCS11 = (SEC_ERROR_BASE + 151),
-SEC_ERROR_NO_EVENT = (SEC_ERROR_BASE + 152),
-SEC_ERROR_CRL_ALREADY_EXISTS = (SEC_ERROR_BASE + 153),
-SEC_ERROR_NOT_INITIALIZED = (SEC_ERROR_BASE + 154),
-SEC_ERROR_TOKEN_NOT_LOGGED_IN = (SEC_ERROR_BASE + 155),
-SEC_ERROR_OCSP_RESPONDER_CERT_INVALID = (SEC_ERROR_BASE + 156),
-SEC_ERROR_OCSP_BAD_SIGNATURE = (SEC_ERROR_BASE + 157),
-
-SEC_ERROR_OUT_OF_SEARCH_LIMITS = (SEC_ERROR_BASE + 158),
-SEC_ERROR_INVALID_POLICY_MAPPING = (SEC_ERROR_BASE + 159),
-SEC_ERROR_POLICY_VALIDATION_FAILED = (SEC_ERROR_BASE + 160),
-/* No longer used. Unknown AIA location types are now silently ignored. */
-SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE = (SEC_ERROR_BASE + 161),
-SEC_ERROR_BAD_HTTP_RESPONSE = (SEC_ERROR_BASE + 162),
-SEC_ERROR_BAD_LDAP_RESPONSE = (SEC_ERROR_BASE + 163),
-SEC_ERROR_FAILED_TO_ENCODE_DATA = (SEC_ERROR_BASE + 164),
-SEC_ERROR_BAD_INFO_ACCESS_LOCATION = (SEC_ERROR_BASE + 165),
-
-SEC_ERROR_LIBPKIX_INTERNAL = (SEC_ERROR_BASE + 166),
-
-SEC_ERROR_PKCS11_GENERAL_ERROR = (SEC_ERROR_BASE + 167),
-SEC_ERROR_PKCS11_FUNCTION_FAILED = (SEC_ERROR_BASE + 168),
-SEC_ERROR_PKCS11_DEVICE_ERROR = (SEC_ERROR_BASE + 169),
-
-SEC_ERROR_BAD_INFO_ACCESS_METHOD = (SEC_ERROR_BASE + 170),
-SEC_ERROR_CRL_IMPORT_FAILED = (SEC_ERROR_BASE + 171),
-
-SEC_ERROR_EXPIRED_PASSWORD = (SEC_ERROR_BASE + 172),
-SEC_ERROR_LOCKED_PASSWORD = (SEC_ERROR_BASE + 173),
-
-SEC_ERROR_UNKNOWN_PKCS11_ERROR = (SEC_ERROR_BASE + 174),
-
-SEC_ERROR_BAD_CRL_DP_URL = (SEC_ERROR_BASE + 175),
-
-SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = (SEC_ERROR_BASE + 176),
-
-SEC_ERROR_LEGACY_DATABASE = (SEC_ERROR_BASE + 177),
-
-SEC_ERROR_APPLICATION_CALLBACK_ERROR = (SEC_ERROR_BASE + 178),
-
-/* Add new error codes above here. */
-SEC_ERROR_END_OF_LIST
-} SECErrorCodes;
-#endif /* NO_SECURITY_ERROR_ENUM */
-
-#endif /* __SEC_ERR_H_ */
diff --git a/security/nss/lib/util/secitem.c b/security/nss/lib/util/secitem.c
deleted file mode 100644
index f03fb2c7a..000000000
--- a/security/nss/lib/util/secitem.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Support routines for SECItem data structure.
- *
- * $Id$
- */
-
-#include "seccomon.h"
-#include "secitem.h"
-#include "base64.h"
-#include "secerr.h"
-#include "secport.h"
-
-SECItem *
-SECITEM_AllocItem(PRArenaPool *arena, SECItem *item, unsigned int len)
-{
- SECItem *result = NULL;
- void *mark = NULL;
-
- if (arena != NULL) {
- mark = PORT_ArenaMark(arena);
- }
-
- if (item == NULL) {
- if (arena != NULL) {
- result = PORT_ArenaZAlloc(arena, sizeof(SECItem));
- } else {
- result = PORT_ZAlloc(sizeof(SECItem));
- }
- if (result == NULL) {
- goto loser;
- }
- } else {
- PORT_Assert(item->data == NULL);
- result = item;
- }
-
- result->len = len;
- if (len) {
- if (arena != NULL) {
- result->data = PORT_ArenaAlloc(arena, len);
- } else {
- result->data = PORT_Alloc(len);
- }
- if (result->data == NULL) {
- goto loser;
- }
- } else {
- result->data = NULL;
- }
-
- if (mark) {
- PORT_ArenaUnmark(arena, mark);
- }
- return(result);
-
-loser:
- if ( arena != NULL ) {
- if (mark) {
- PORT_ArenaRelease(arena, mark);
- }
- if (item != NULL) {
- item->data = NULL;
- item->len = 0;
- }
- } else {
- if (result != NULL) {
- SECITEM_FreeItem(result, (item == NULL) ? PR_TRUE : PR_FALSE);
- }
- /*
- * If item is not NULL, the above has set item->data and
- * item->len to 0.
- */
- }
- return(NULL);
-}
-
-SECStatus
-SECITEM_ReallocItem(PRArenaPool *arena, SECItem *item, unsigned int oldlen,
- unsigned int newlen)
-{
- PORT_Assert(item != NULL);
- if (item == NULL) {
- /* XXX Set error. But to what? */
- return SECFailure;
- }
-
- /*
- * If no old length, degenerate to just plain alloc.
- */
- if (oldlen == 0) {
- PORT_Assert(item->data == NULL || item->len == 0);
- if (newlen == 0) {
- /* Nothing to do. Weird, but not a failure. */
- return SECSuccess;
- }
- item->len = newlen;
- if (arena != NULL) {
- item->data = PORT_ArenaAlloc(arena, newlen);
- } else {
- item->data = PORT_Alloc(newlen);
- }
- } else {
- if (arena != NULL) {
- item->data = PORT_ArenaGrow(arena, item->data, oldlen, newlen);
- } else {
- item->data = PORT_Realloc(item->data, newlen);
- }
- }
-
- if (item->data == NULL) {
- return SECFailure;
- }
-
- return SECSuccess;
-}
-
-SECComparison
-SECITEM_CompareItem(const SECItem *a, const SECItem *b)
-{
- unsigned m;
- int rv;
-
- if (a == b)
- return SECEqual;
- if (!a || !a->len || !a->data)
- return (!b || !b->len || !b->data) ? SECEqual : SECLessThan;
- if (!b || !b->len || !b->data)
- return SECGreaterThan;
-
- m = ( ( a->len < b->len ) ? a->len : b->len );
-
- rv = PORT_Memcmp(a->data, b->data, m);
- if (rv) {
- return rv < 0 ? SECLessThan : SECGreaterThan;
- }
- if (a->len < b->len) {
- return SECLessThan;
- }
- if (a->len == b->len) {
- return SECEqual;
- }
- return SECGreaterThan;
-}
-
-PRBool
-SECITEM_ItemsAreEqual(const SECItem *a, const SECItem *b)
-{
- if (a->len != b->len)
- return PR_FALSE;
- if (!a->len)
- return PR_TRUE;
- if (!a->data || !b->data) {
- /* avoid null pointer crash. */
- return (PRBool)(a->data == b->data);
- }
- return (PRBool)!PORT_Memcmp(a->data, b->data, a->len);
-}
-
-SECItem *
-SECITEM_DupItem(const SECItem *from)
-{
- return SECITEM_ArenaDupItem(NULL, from);
-}
-
-SECItem *
-SECITEM_ArenaDupItem(PRArenaPool *arena, const SECItem *from)
-{
- SECItem *to;
-
- if ( from == NULL ) {
- return(NULL);
- }
-
- if ( arena != NULL ) {
- to = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));
- } else {
- to = (SECItem *)PORT_Alloc(sizeof(SECItem));
- }
- if ( to == NULL ) {
- return(NULL);
- }
-
- if ( arena != NULL ) {
- to->data = (unsigned char *)PORT_ArenaAlloc(arena, from->len);
- } else {
- to->data = (unsigned char *)PORT_Alloc(from->len);
- }
- if ( to->data == NULL ) {
- PORT_Free(to);
- return(NULL);
- }
-
- to->len = from->len;
- to->type = from->type;
- if ( to->len ) {
- PORT_Memcpy(to->data, from->data, to->len);
- }
-
- return(to);
-}
-
-SECStatus
-SECITEM_CopyItem(PRArenaPool *arena, SECItem *to, const SECItem *from)
-{
- to->type = from->type;
- if (from->data && from->len) {
- if ( arena ) {
- to->data = (unsigned char*) PORT_ArenaAlloc(arena, from->len);
- } else {
- to->data = (unsigned char*) PORT_Alloc(from->len);
- }
-
- if (!to->data) {
- return SECFailure;
- }
- PORT_Memcpy(to->data, from->data, from->len);
- to->len = from->len;
- } else {
- /*
- * If from->data is NULL but from->len is nonzero, this function
- * will succeed. Is this right?
- */
- to->data = 0;
- to->len = 0;
- }
- return SECSuccess;
-}
-
-void
-SECITEM_FreeItem(SECItem *zap, PRBool freeit)
-{
- if (zap) {
- PORT_Free(zap->data);
- zap->data = 0;
- zap->len = 0;
- if (freeit) {
- PORT_Free(zap);
- }
- }
-}
-
-void
-SECITEM_ZfreeItem(SECItem *zap, PRBool freeit)
-{
- if (zap) {
- PORT_ZFree(zap->data, zap->len);
- zap->data = 0;
- zap->len = 0;
- if (freeit) {
- PORT_ZFree(zap, sizeof(SECItem));
- }
- }
-}
-/* these reroutines were taken from pkix oid.c, which is supposed to
- * replace this file some day */
-/*
- * This is the hash function. We simply XOR the encoded form with
- * itself in sizeof(PLHashNumber)-byte chunks. Improving this
- * routine is left as an excercise for the more mathematically
- * inclined student.
- */
-PLHashNumber PR_CALLBACK
-SECITEM_Hash ( const void *key)
-{
- const SECItem *item = (const SECItem *)key;
- PLHashNumber rv = 0;
-
- PRUint8 *data = (PRUint8 *)item->data;
- PRUint32 i;
- PRUint8 *rvc = (PRUint8 *)&rv;
-
- for( i = 0; i < item->len; i++ ) {
- rvc[ i % sizeof(rv) ] ^= *data;
- data++;
- }
-
- return rv;
-}
-
-/*
- * This is the key-compare function. It simply does a lexical
- * comparison on the item data. This does not result in
- * quite the same ordering as the "sequence of numbers" order,
- * but heck it's only used internally by the hash table anyway.
- */
-PRIntn PR_CALLBACK
-SECITEM_HashCompare ( const void *k1, const void *k2)
-{
- const SECItem *i1 = (const SECItem *)k1;
- const SECItem *i2 = (const SECItem *)k2;
-
- return SECITEM_ItemsAreEqual(i1,i2);
-}
-
-SECItemArray *
-SECITEM_AllocArray(PLArenaPool *arena, SECItemArray *array, unsigned int len)
-{
- SECItemArray *result = NULL;
- void *mark = NULL;
-
- if (arena != NULL) {
- mark = PORT_ArenaMark(arena);
- }
-
- if (array == NULL) {
- if (arena != NULL) {
- result = PORT_ArenaZAlloc(arena, sizeof(SECItemArray));
- } else {
- result = PORT_ZAlloc(sizeof(SECItemArray));
- }
- if (result == NULL) {
- goto loser;
- }
- } else {
- PORT_Assert(array->items == NULL);
- result = array;
- }
-
- result->len = len;
- if (len) {
- if (arena != NULL) {
- result->items = PORT_ArenaZNewArray(arena, SECItem, len);
- } else {
- result->items = PORT_ZNewArray(SECItem, len);
- }
- if (result->items == NULL) {
- goto loser;
- }
- } else {
- result->items = NULL;
- }
-
- if (mark) {
- PORT_ArenaUnmark(arena, mark);
- }
- return(result);
-
-loser:
- if ( arena != NULL ) {
- if (mark) {
- PORT_ArenaRelease(arena, mark);
- }
- if (array != NULL) {
- array->items = NULL;
- array->len = 0;
- }
- } else {
- if (result != NULL && array == NULL) {
- PORT_Free(result);
- }
- /*
- * If array is not NULL, the above has set array->data and
- * array->len to 0.
- */
- }
- return(NULL);
-}
-
-void secitem_FreeArray(SECItemArray *array, PRBool zero_items, PRBool freeit)
-{
- unsigned int i;
-
- if (!array || !array->len || !array->items)
- return;
-
- for (i=0; i<array->len; ++i) {
- SECItem *item = &array->items[i];
-
- if (item->data) {
- if (zero_items) {
- SECITEM_ZfreeItem(item, PR_FALSE);
- } else {
- SECITEM_FreeItem(item, PR_FALSE);
- }
- }
- }
-
- if (freeit)
- PORT_Free(array);
-}
-
-void SECITEM_FreeArray(SECItemArray *array, PRBool freeit)
-{
- secitem_FreeArray(array, PR_FALSE, freeit);
-}
-
-void SECITEM_ZfreeArray(SECItemArray *array, PRBool freeit)
-{
- secitem_FreeArray(array, PR_TRUE, freeit);
-}
-
-SECItemArray *
-SECITEM_DupArray(PLArenaPool *arena, const SECItemArray *from)
-{
- SECItemArray *result;
- unsigned int i;
-
- if (!from || !from->items || !from->len)
- return NULL;
-
- result = SECITEM_AllocArray(arena, NULL, from->len);
- if (!result)
- return NULL;
-
- for (i=0; i<from->len; ++i) {
- SECStatus rv = SECITEM_CopyItem(arena,
- &result->items[i], &from->items[i]);
- if (rv != SECSuccess) {
- SECITEM_ZfreeArray(result, PR_TRUE);
- return NULL;
- }
- }
-
- return result;
-}
diff --git a/security/nss/lib/util/secitem.h b/security/nss/lib/util/secitem.h
deleted file mode 100644
index dd08da3ff..000000000
--- a/security/nss/lib/util/secitem.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SECITEM_H_
-#define _SECITEM_H_
-
-#include "utilrename.h"
-
-/*
- * secitem.h - public data structures and prototypes for handling
- * SECItems
- *
- * $Id$
- */
-
-#include "plarena.h"
-#include "plhash.h"
-#include "seccomon.h"
-
-SEC_BEGIN_PROTOS
-
-/*
-** Allocate an item. If "arena" is not NULL, then allocate from there,
-** otherwise allocate from the heap. If "item" is not NULL, allocate
-** only the data buffer for the item, not the item itself. If "len" is
-** 0, do not allocate the data buffer for the item; simply set the data
-** field to NULL and the len field to 0. The item structure is allocated
-** zero-filled; the data buffer is not zeroed. The caller is responsible
-** for initializing the type field of the item.
-**
-** The resulting item is returned; NULL if any error occurs.
-**
-** XXX This probably should take a SECItemType, but since that is mostly
-** unused and our improved APIs (aka Stan) are looming, I left it out.
-*/
-extern SECItem *SECITEM_AllocItem(PLArenaPool *arena, SECItem *item,
- unsigned int len);
-
-/*
-** Reallocate the data for the specified "item". If "arena" is not NULL,
-** then reallocate from there, otherwise reallocate from the heap.
-** In the case where oldlen is 0, the data is allocated (not reallocated).
-** In any case, "item" is expected to be a valid SECItem pointer;
-** SECFailure is returned if it is not. If the allocation succeeds,
-** SECSuccess is returned.
-*/
-extern SECStatus SECITEM_ReallocItem(PLArenaPool *arena, SECItem *item,
- unsigned int oldlen, unsigned int newlen);
-
-/*
-** Compare two items returning the difference between them.
-*/
-extern SECComparison SECITEM_CompareItem(const SECItem *a, const SECItem *b);
-
-/*
-** Compare two items -- if they are the same, return true; otherwise false.
-*/
-extern PRBool SECITEM_ItemsAreEqual(const SECItem *a, const SECItem *b);
-
-/*
-** Copy "from" to "to"
-*/
-extern SECStatus SECITEM_CopyItem(PLArenaPool *arena, SECItem *to,
- const SECItem *from);
-
-/*
-** Allocate an item and copy "from" into it.
-*/
-extern SECItem *SECITEM_DupItem(const SECItem *from);
-
-/*
-** Allocate an item and copy "from" into it. The item itself and the
-** data it points to are both allocated from the arena. If arena is
-** NULL, this function is equivalent to SECITEM_DupItem.
-*/
-extern SECItem *SECITEM_ArenaDupItem(PLArenaPool *arena, const SECItem *from);
-
-/*
-** Free "zap". If freeit is PR_TRUE then "zap" itself is freed.
-*/
-extern void SECITEM_FreeItem(SECItem *zap, PRBool freeit);
-
-/*
-** Zero and then free "zap". If freeit is PR_TRUE then "zap" itself is freed.
-*/
-extern void SECITEM_ZfreeItem(SECItem *zap, PRBool freeit);
-
-PLHashNumber PR_CALLBACK SECITEM_Hash ( const void *key);
-
-PRIntn PR_CALLBACK SECITEM_HashCompare ( const void *k1, const void *k2);
-
-extern SECItemArray *SECITEM_AllocArray(PLArenaPool *arena,
- SECItemArray *array,
- unsigned int len);
-extern SECItemArray *SECITEM_DupArray(PLArenaPool *arena, const SECItemArray *from);
-extern void SECITEM_FreeArray(SECItemArray *array, PRBool freeit);
-extern void SECITEM_ZfreeArray(SECItemArray *array, PRBool freeit);
-
-SEC_END_PROTOS
-
-#endif /* _SECITEM_H_ */
diff --git a/security/nss/lib/util/secload.c b/security/nss/lib/util/secload.c
deleted file mode 100644
index eb8a9ec61..000000000
--- a/security/nss/lib/util/secload.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secport.h"
-#include "nspr.h"
-
-#ifdef XP_UNIX
-#include <unistd.h>
-#define BL_MAXSYMLINKS 20
-
-/*
- * If 'link' is a symbolic link, this function follows the symbolic links
- * and returns the pathname of the ultimate source of the symbolic links.
- * If 'link' is not a symbolic link, this function returns NULL.
- * The caller should call PR_Free to free the string returned by this
- * function.
- */
-static char* loader_GetOriginalPathname(const char* link)
-{
- char* resolved = NULL;
- char* input = NULL;
- PRUint32 iterations = 0;
- PRInt32 len = 0, retlen = 0;
- if (!link) {
- PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
- return NULL;
- }
- len = PR_MAX(1024, strlen(link) + 1);
- resolved = PR_Malloc(len);
- input = PR_Malloc(len);
- if (!resolved || !input) {
- if (resolved) {
- PR_Free(resolved);
- }
- if (input) {
- PR_Free(input);
- }
- return NULL;
- }
- strcpy(input, link);
- while ( (iterations++ < BL_MAXSYMLINKS) &&
- ( (retlen = readlink(input, resolved, len - 1)) > 0) ) {
- char* tmp = input;
- resolved[retlen] = '\0'; /* NULL termination */
- input = resolved;
- resolved = tmp;
- }
- PR_Free(resolved);
- if (iterations == 1 && retlen < 0) {
- PR_Free(input);
- input = NULL;
- }
- return input;
-}
-#endif /* XP_UNIX */
-
-/*
- * Load the library with the file name 'name' residing in the same
- * directory as the reference library, whose pathname is 'referencePath'.
- */
-static PRLibrary *
-loader_LoadLibInReferenceDir(const char *referencePath, const char *name)
-{
- PRLibrary *dlh = NULL;
- char *fullName = NULL;
- char* c;
- PRLibSpec libSpec;
-
- /* Remove the trailing filename from referencePath and add the new one */
- c = strrchr(referencePath, PR_GetDirectorySeparator());
- if (c) {
- size_t referencePathSize = 1 + c - referencePath;
- fullName = (char*) PORT_Alloc(strlen(name) + referencePathSize + 1);
- if (fullName) {
- memcpy(fullName, referencePath, referencePathSize);
- strcpy(fullName + referencePathSize, name);
-#ifdef DEBUG_LOADER
- PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n",
- fullName);
-#endif
- libSpec.type = PR_LibSpec_Pathname;
- libSpec.value.pathname = fullName;
- dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL
-#ifdef PR_LD_ALT_SEARCH_PATH
- /* allow library's dependencies to be found in the same directory
- * on Windows even if PATH is not set. Requires NSPR 4.8.1 . */
- | PR_LD_ALT_SEARCH_PATH
-#endif
- );
- PORT_Free(fullName);
- }
- }
- return dlh;
-}
-
-/*
- * Load a shared library called "newShLibName" in the same directory as
- * a shared library that is already loaded, called existingShLibName.
- * A pointer to a static function in that shared library,
- * staticShLibFunc, is required.
- *
- * existingShLibName:
- * The file name of the shared library that shall be used as the
- * "reference library". The loader will attempt to load the requested
- * library from the same directory as the reference library.
- *
- * staticShLibFunc:
- * Pointer to a static function in the "reference library".
- *
- * newShLibName:
- * The simple file name of the new shared library to be loaded.
- *
- * We use PR_GetLibraryFilePathname to get the pathname of the loaded
- * shared lib that contains this function, and then do a
- * PR_LoadLibraryWithFlags with an absolute pathname for the shared
- * library to be loaded.
- *
- * On Windows, the "alternate search path" strategy is employed, if available.
- * On Unix, if existingShLibName is a symbolic link, and no link exists for the
- * new library, the original link will be resolved, and the new library loaded
- * from the resolved location.
- *
- * If the new shared library is not found in the same location as the reference
- * library, it will then be loaded from the normal system library path.
- *
- */
-
-PRLibrary *
-PORT_LoadLibraryFromOrigin(const char* existingShLibName,
- PRFuncPtr staticShLibFunc,
- const char *newShLibName)
-{
- PRLibrary *lib = NULL;
- char* fullPath = NULL;
- PRLibSpec libSpec;
-
- /* Get the pathname for existingShLibName, e.g. /usr/lib/libnss3.so
- * PR_GetLibraryFilePathname works with either the base library name or a
- * function pointer, depending on the platform.
- * We require the address of a function in the "reference library",
- * provided by the caller. To avoid getting the address of the stub/thunk
- * of an exported function by accident, use the address of a static
- * function rather than an exported function.
- */
- fullPath = PR_GetLibraryFilePathname(existingShLibName,
- staticShLibFunc);
-
- if (fullPath) {
- lib = loader_LoadLibInReferenceDir(fullPath, newShLibName);
-#ifdef XP_UNIX
- if (!lib) {
- /*
- * If fullPath is a symbolic link, resolve the symbolic
- * link and try again.
- */
- char* originalfullPath = loader_GetOriginalPathname(fullPath);
- if (originalfullPath) {
- PR_Free(fullPath);
- fullPath = originalfullPath;
- lib = loader_LoadLibInReferenceDir(fullPath, newShLibName);
- }
- }
-#endif
- PR_Free(fullPath);
- }
- if (!lib) {
-#ifdef DEBUG_LOADER
- PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", newShLibName);
-#endif
- libSpec.type = PR_LibSpec_Pathname;
- libSpec.value.pathname = newShLibName;
- lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
- }
- if (NULL == lib) {
-#ifdef DEBUG_LOADER
- PR_fprintf(PR_STDOUT, "\nLoading failed : %s.\n", newShLibName);
-#endif
- }
- return lib;
-}
-
diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c
deleted file mode 100644
index 14ce55636..000000000
--- a/security/nss/lib/util/secoid.c
+++ /dev/null
@@ -1,2194 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secoid.h"
-#include "pkcs11t.h"
-#include "secitem.h"
-#include "secerr.h"
-#include "prenv.h"
-#include "plhash.h"
-#include "nssrwlk.h"
-#include "nssutil.h"
-
-/* Library identity and versioning */
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information for the 'ident' and 'what commands
- *
- * NOTE: the first component of the concatenated rcsid string
- * must not end in a '$' to prevent rcs keyword substitution.
- */
-const char __nss_util_rcsid[] = "$Header: NSS " NSSUTIL_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__ " $";
-const char __nss_util_sccsid[] = "@(#)NSS " NSSUTIL_VERSION _DEBUG_STRING
- " " __DATE__ " " __TIME__;
-
-/* MISSI Mosaic Object ID space */
-/* USGov algorithm OID space: { 2 16 840 1 101 } */
-#define USGOV 0x60, 0x86, 0x48, 0x01, 0x65
-#define MISSI USGOV, 0x02, 0x01, 0x01
-#define MISSI_OLD_KEA_DSS MISSI, 0x0c
-#define MISSI_OLD_DSS MISSI, 0x02
-#define MISSI_KEA_DSS MISSI, 0x14
-#define MISSI_DSS MISSI, 0x13
-#define MISSI_KEA MISSI, 0x0a
-#define MISSI_ALT_KEA MISSI, 0x16
-
-#define NISTALGS USGOV, 3, 4
-#define AES NISTALGS, 1
-#define SHAXXX NISTALGS, 2
-#define DSA2 NISTALGS, 3
-
-/**
- ** The Netscape OID space is allocated by Terry Hayes. If you need
- ** a piece of the space, contact him at thayes@netscape.com.
- **/
-
-/* Netscape Communications Corporation Object ID space */
-/* { 2 16 840 1 113730 } */
-#define NETSCAPE_OID 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42
-#define NETSCAPE_CERT_EXT NETSCAPE_OID, 0x01
-#define NETSCAPE_DATA_TYPE NETSCAPE_OID, 0x02
-/* netscape directory oid - owned by Mark Smith (mcs@netscape.com) */
-#define NETSCAPE_DIRECTORY NETSCAPE_OID, 0x03
-#define NETSCAPE_POLICY NETSCAPE_OID, 0x04
-#define NETSCAPE_CERT_SERVER NETSCAPE_OID, 0x05
-#define NETSCAPE_ALGS NETSCAPE_OID, 0x06 /* algorithm OIDs */
-#define NETSCAPE_NAME_COMPONENTS NETSCAPE_OID, 0x07
-
-#define NETSCAPE_CERT_EXT_AIA NETSCAPE_CERT_EXT, 0x10
-#define NETSCAPE_CERT_SERVER_CRMF NETSCAPE_CERT_SERVER, 0x01
-
-/* these are old and should go away soon */
-#define OLD_NETSCAPE 0x60, 0x86, 0x48, 0xd8, 0x6a
-#define NS_CERT_EXT OLD_NETSCAPE, 0x01
-#define NS_FILE_TYPE OLD_NETSCAPE, 0x02
-#define NS_IMAGE_TYPE OLD_NETSCAPE, 0x03
-
-/* RSA OID name space */
-#define RSADSI 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d
-#define PKCS RSADSI, 0x01
-#define DIGEST RSADSI, 0x02
-#define CIPHER RSADSI, 0x03
-#define PKCS1 PKCS, 0x01
-#define PKCS5 PKCS, 0x05
-#define PKCS7 PKCS, 0x07
-#define PKCS9 PKCS, 0x09
-#define PKCS12 PKCS, 0x0c
-
-/* Other OID name spaces */
-#define ALGORITHM 0x2b, 0x0e, 0x03, 0x02
-#define X500 0x55
-#define X520_ATTRIBUTE_TYPE X500, 0x04
-#define X500_ALG X500, 0x08
-#define X500_ALG_ENCRYPTION X500_ALG, 0x01
-
-/** X.509 v3 Extension OID
- ** {joint-iso-ccitt (2) ds(5) 29}
- **/
-#define ID_CE_OID X500, 0x1d
-
-#define RFC1274_ATTR_TYPE 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x1
-/* #define RFC2247_ATTR_TYPE 0x09, 0x92, 0x26, 0xf5, 0x98, 0x1e, 0x64, 0x1 this is WRONG! */
-
-/* PKCS #12 name spaces */
-#define PKCS12_MODE_IDS PKCS12, 0x01
-#define PKCS12_ESPVK_IDS PKCS12, 0x02
-#define PKCS12_BAG_IDS PKCS12, 0x03
-#define PKCS12_CERT_BAG_IDS PKCS12, 0x04
-#define PKCS12_OIDS PKCS12, 0x05
-#define PKCS12_PBE_IDS PKCS12_OIDS, 0x01
-#define PKCS12_ENVELOPING_IDS PKCS12_OIDS, 0x02
-#define PKCS12_SIGNATURE_IDS PKCS12_OIDS, 0x03
-#define PKCS12_V2_PBE_IDS PKCS12, 0x01
-#define PKCS9_CERT_TYPES PKCS9, 0x16
-#define PKCS9_CRL_TYPES PKCS9, 0x17
-#define PKCS9_SMIME_IDS PKCS9, 0x10
-#define PKCS9_SMIME_ATTRS PKCS9_SMIME_IDS, 2
-#define PKCS9_SMIME_ALGS PKCS9_SMIME_IDS, 3
-#define PKCS12_VERSION1 PKCS12, 0x0a
-#define PKCS12_V1_BAG_IDS PKCS12_VERSION1, 1
-
-/* for DSA algorithm */
-/* { iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) } */
-#define ANSI_X9_ALGORITHM 0x2a, 0x86, 0x48, 0xce, 0x38, 0x4
-
-/* for DH algorithm */
-/* { iso(1) member-body(2) us(840) x9-57(10046) number-type(2) } */
-/* need real OID person to look at this, copied the above line
- * and added 6 to second to last value (and changed '4' to '2' */
-#define ANSI_X942_ALGORITHM 0x2a, 0x86, 0x48, 0xce, 0x3e, 0x2
-
-#define VERISIGN 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45
-
-#define PKIX 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07
-#define PKIX_CERT_EXTENSIONS PKIX, 1
-#define PKIX_POLICY_QUALIFIERS PKIX, 2
-#define PKIX_KEY_USAGE PKIX, 3
-#define PKIX_ACCESS_DESCRIPTION PKIX, 0x30
-#define PKIX_OCSP PKIX_ACCESS_DESCRIPTION, 1
-#define PKIX_CA_ISSUERS PKIX_ACCESS_DESCRIPTION, 2
-
-#define PKIX_ID_PKIP PKIX, 5
-#define PKIX_ID_REGCTRL PKIX_ID_PKIP, 1
-#define PKIX_ID_REGINFO PKIX_ID_PKIP, 2
-
-/* Microsoft Object ID space */
-/* { 1.3.6.1.4.1.311 } */
-#define MICROSOFT_OID 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0x37
-#define EV_NAME_ATTRIBUTE MICROSOFT_OID, 60, 2, 1
-
-/* Microsoft Crypto 2.0 ID space */
-/* { 1.3.6.1.4.1.311.10 } */
-#define MS_CRYPTO_20 MICROSOFT_OID, 10
-/* Microsoft Crypto 2.0 Extended Key Usage ID space */
-/* { 1.3.6.1.4.1.311.10.3 } */
-#define MS_CRYPTO_EKU MS_CRYPTO_20, 3
-
-#define CERTICOM_OID 0x2b, 0x81, 0x04
-#define SECG_OID CERTICOM_OID, 0x00
-
-#define ANSI_X962_OID 0x2a, 0x86, 0x48, 0xce, 0x3d
-#define ANSI_X962_CURVE_OID ANSI_X962_OID, 0x03
-#define ANSI_X962_GF2m_OID ANSI_X962_CURVE_OID, 0x00
-#define ANSI_X962_GFp_OID ANSI_X962_CURVE_OID, 0x01
-#define ANSI_X962_SIGNATURE_OID ANSI_X962_OID, 0x04
-#define ANSI_X962_SPECIFY_OID ANSI_X962_SIGNATURE_OID, 0x03
-
-/* for Camellia: iso(1) member-body(2) jisc(392)
- * mitsubishi(200011) isl(61) security(1) algorithm(1)
- */
-#define MITSUBISHI_ALG 0x2a,0x83,0x08,0x8c,0x9a,0x4b,0x3d,0x01,0x01
-#define CAMELLIA_ENCRYPT_OID MITSUBISHI_ALG,1
-#define CAMELLIA_WRAP_OID MITSUBISHI_ALG,3
-
-/* for SEED : iso(1) member-body(2) korea(410)
- * kisa(200004) algorithm(1)
- */
-#define SEED_OID 0x2a,0x83,0x1a,0x8c,0x9a,0x44,0x01
-
-#define CONST_OID static const unsigned char
-
-CONST_OID md2[] = { DIGEST, 0x02 };
-CONST_OID md4[] = { DIGEST, 0x04 };
-CONST_OID md5[] = { DIGEST, 0x05 };
-CONST_OID hmac_sha1[] = { DIGEST, 7 };
-CONST_OID hmac_sha224[] = { DIGEST, 8 };
-CONST_OID hmac_sha256[] = { DIGEST, 9 };
-CONST_OID hmac_sha384[] = { DIGEST, 10 };
-CONST_OID hmac_sha512[] = { DIGEST, 11 };
-
-CONST_OID rc2cbc[] = { CIPHER, 0x02 };
-CONST_OID rc4[] = { CIPHER, 0x04 };
-CONST_OID desede3cbc[] = { CIPHER, 0x07 };
-CONST_OID rc5cbcpad[] = { CIPHER, 0x09 };
-
-CONST_OID desecb[] = { ALGORITHM, 0x06 };
-CONST_OID descbc[] = { ALGORITHM, 0x07 };
-CONST_OID desofb[] = { ALGORITHM, 0x08 };
-CONST_OID descfb[] = { ALGORITHM, 0x09 };
-CONST_OID desmac[] = { ALGORITHM, 0x0a };
-CONST_OID sdn702DSASignature[] = { ALGORITHM, 0x0c };
-CONST_OID isoSHAWithRSASignature[] = { ALGORITHM, 0x0f };
-CONST_OID desede[] = { ALGORITHM, 0x11 };
-CONST_OID sha1[] = { ALGORITHM, 0x1a };
-CONST_OID bogusDSASignaturewithSHA1Digest[] = { ALGORITHM, 0x1b };
-CONST_OID isoSHA1WithRSASignature[] = { ALGORITHM, 0x1d };
-
-CONST_OID pkcs1RSAEncryption[] = { PKCS1, 0x01 };
-CONST_OID pkcs1MD2WithRSAEncryption[] = { PKCS1, 0x02 };
-CONST_OID pkcs1MD4WithRSAEncryption[] = { PKCS1, 0x03 };
-CONST_OID pkcs1MD5WithRSAEncryption[] = { PKCS1, 0x04 };
-CONST_OID pkcs1SHA1WithRSAEncryption[] = { PKCS1, 0x05 };
-CONST_OID pkcs1RSAOAEPEncryption[] = { PKCS1, 0x07 };
-CONST_OID pkcs1MGF1[] = { PKCS1, 0x08 };
-CONST_OID pkcs1PSpecified[] = { PKCS1, 0x09 };
-CONST_OID pkcs1RSAPSSSignature[] = { PKCS1, 10 };
-CONST_OID pkcs1SHA256WithRSAEncryption[] = { PKCS1, 11 };
-CONST_OID pkcs1SHA384WithRSAEncryption[] = { PKCS1, 12 };
-CONST_OID pkcs1SHA512WithRSAEncryption[] = { PKCS1, 13 };
-CONST_OID pkcs1SHA224WithRSAEncryption[] = { PKCS1, 14 };
-
-CONST_OID pkcs5PbeWithMD2AndDEScbc[] = { PKCS5, 0x01 };
-CONST_OID pkcs5PbeWithMD5AndDEScbc[] = { PKCS5, 0x03 };
-CONST_OID pkcs5PbeWithSha1AndDEScbc[] = { PKCS5, 0x0a };
-CONST_OID pkcs5Pbkdf2[] = { PKCS5, 12 };
-CONST_OID pkcs5Pbes2[] = { PKCS5, 13 };
-CONST_OID pkcs5Pbmac1[] = { PKCS5, 14 };
-
-CONST_OID pkcs7[] = { PKCS7 };
-CONST_OID pkcs7Data[] = { PKCS7, 0x01 };
-CONST_OID pkcs7SignedData[] = { PKCS7, 0x02 };
-CONST_OID pkcs7EnvelopedData[] = { PKCS7, 0x03 };
-CONST_OID pkcs7SignedEnvelopedData[] = { PKCS7, 0x04 };
-CONST_OID pkcs7DigestedData[] = { PKCS7, 0x05 };
-CONST_OID pkcs7EncryptedData[] = { PKCS7, 0x06 };
-
-CONST_OID pkcs9EmailAddress[] = { PKCS9, 0x01 };
-CONST_OID pkcs9UnstructuredName[] = { PKCS9, 0x02 };
-CONST_OID pkcs9ContentType[] = { PKCS9, 0x03 };
-CONST_OID pkcs9MessageDigest[] = { PKCS9, 0x04 };
-CONST_OID pkcs9SigningTime[] = { PKCS9, 0x05 };
-CONST_OID pkcs9CounterSignature[] = { PKCS9, 0x06 };
-CONST_OID pkcs9ChallengePassword[] = { PKCS9, 0x07 };
-CONST_OID pkcs9UnstructuredAddress[] = { PKCS9, 0x08 };
-CONST_OID pkcs9ExtendedCertificateAttributes[] = { PKCS9, 0x09 };
-CONST_OID pkcs9ExtensionRequest[] = { PKCS9, 14 };
-CONST_OID pkcs9SMIMECapabilities[] = { PKCS9, 15 };
-CONST_OID pkcs9FriendlyName[] = { PKCS9, 20 };
-CONST_OID pkcs9LocalKeyID[] = { PKCS9, 21 };
-
-CONST_OID pkcs9X509Certificate[] = { PKCS9_CERT_TYPES, 1 };
-CONST_OID pkcs9SDSICertificate[] = { PKCS9_CERT_TYPES, 2 };
-CONST_OID pkcs9X509CRL[] = { PKCS9_CRL_TYPES, 1 };
-
-/* RFC2630 (CMS) OIDs */
-CONST_OID cmsESDH[] = { PKCS9_SMIME_ALGS, 5 };
-CONST_OID cms3DESwrap[] = { PKCS9_SMIME_ALGS, 6 };
-CONST_OID cmsRC2wrap[] = { PKCS9_SMIME_ALGS, 7 };
-
-/* RFC2633 SMIME message attributes */
-CONST_OID smimeEncryptionKeyPreference[] = { PKCS9_SMIME_ATTRS, 11 };
-CONST_OID ms_smimeEncryptionKeyPreference[] = { MICROSOFT_OID, 0x10, 0x4 };
-
-CONST_OID x520CommonName[] = { X520_ATTRIBUTE_TYPE, 3 };
-CONST_OID x520SurName[] = { X520_ATTRIBUTE_TYPE, 4 };
-CONST_OID x520SerialNumber[] = { X520_ATTRIBUTE_TYPE, 5 };
-CONST_OID x520CountryName[] = { X520_ATTRIBUTE_TYPE, 6 };
-CONST_OID x520LocalityName[] = { X520_ATTRIBUTE_TYPE, 7 };
-CONST_OID x520StateOrProvinceName[] = { X520_ATTRIBUTE_TYPE, 8 };
-CONST_OID x520StreetAddress[] = { X520_ATTRIBUTE_TYPE, 9 };
-CONST_OID x520OrgName[] = { X520_ATTRIBUTE_TYPE, 10 };
-CONST_OID x520OrgUnitName[] = { X520_ATTRIBUTE_TYPE, 11 };
-CONST_OID x520Title[] = { X520_ATTRIBUTE_TYPE, 12 };
-CONST_OID x520BusinessCategory[] = { X520_ATTRIBUTE_TYPE, 15 };
-CONST_OID x520PostalAddress[] = { X520_ATTRIBUTE_TYPE, 16 };
-CONST_OID x520PostalCode[] = { X520_ATTRIBUTE_TYPE, 17 };
-CONST_OID x520PostOfficeBox[] = { X520_ATTRIBUTE_TYPE, 18 };
-CONST_OID x520GivenName[] = { X520_ATTRIBUTE_TYPE, 42 };
-CONST_OID x520Initials[] = { X520_ATTRIBUTE_TYPE, 43 };
-CONST_OID x520GenerationQualifier[] = { X520_ATTRIBUTE_TYPE, 44 };
-CONST_OID x520DnQualifier[] = { X520_ATTRIBUTE_TYPE, 46 };
-CONST_OID x520HouseIdentifier[] = { X520_ATTRIBUTE_TYPE, 51 };
-CONST_OID x520Pseudonym[] = { X520_ATTRIBUTE_TYPE, 65 };
-
-CONST_OID nsTypeGIF[] = { NETSCAPE_DATA_TYPE, 0x01 };
-CONST_OID nsTypeJPEG[] = { NETSCAPE_DATA_TYPE, 0x02 };
-CONST_OID nsTypeURL[] = { NETSCAPE_DATA_TYPE, 0x03 };
-CONST_OID nsTypeHTML[] = { NETSCAPE_DATA_TYPE, 0x04 };
-CONST_OID nsTypeCertSeq[] = { NETSCAPE_DATA_TYPE, 0x05 };
-
-CONST_OID missiCertKEADSSOld[] = { MISSI_OLD_KEA_DSS };
-CONST_OID missiCertDSSOld[] = { MISSI_OLD_DSS };
-CONST_OID missiCertKEADSS[] = { MISSI_KEA_DSS };
-CONST_OID missiCertDSS[] = { MISSI_DSS };
-CONST_OID missiCertKEA[] = { MISSI_KEA };
-CONST_OID missiCertAltKEA[] = { MISSI_ALT_KEA };
-CONST_OID x500RSAEncryption[] = { X500_ALG_ENCRYPTION, 0x01 };
-
-/* added for alg 1485 */
-CONST_OID rfc1274Uid[] = { RFC1274_ATTR_TYPE, 1 };
-CONST_OID rfc1274Mail[] = { RFC1274_ATTR_TYPE, 3 };
-CONST_OID rfc2247DomainComponent[] = { RFC1274_ATTR_TYPE, 25 };
-
-/* Netscape private certificate extensions */
-CONST_OID nsCertExtNetscapeOK[] = { NS_CERT_EXT, 1 };
-CONST_OID nsCertExtIssuerLogo[] = { NS_CERT_EXT, 2 };
-CONST_OID nsCertExtSubjectLogo[] = { NS_CERT_EXT, 3 };
-CONST_OID nsExtCertType[] = { NETSCAPE_CERT_EXT, 0x01 };
-CONST_OID nsExtBaseURL[] = { NETSCAPE_CERT_EXT, 0x02 };
-CONST_OID nsExtRevocationURL[] = { NETSCAPE_CERT_EXT, 0x03 };
-CONST_OID nsExtCARevocationURL[] = { NETSCAPE_CERT_EXT, 0x04 };
-CONST_OID nsExtCACRLURL[] = { NETSCAPE_CERT_EXT, 0x05 };
-CONST_OID nsExtCACertURL[] = { NETSCAPE_CERT_EXT, 0x06 };
-CONST_OID nsExtCertRenewalURL[] = { NETSCAPE_CERT_EXT, 0x07 };
-CONST_OID nsExtCAPolicyURL[] = { NETSCAPE_CERT_EXT, 0x08 };
-CONST_OID nsExtHomepageURL[] = { NETSCAPE_CERT_EXT, 0x09 };
-CONST_OID nsExtEntityLogo[] = { NETSCAPE_CERT_EXT, 0x0a };
-CONST_OID nsExtUserPicture[] = { NETSCAPE_CERT_EXT, 0x0b };
-CONST_OID nsExtSSLServerName[] = { NETSCAPE_CERT_EXT, 0x0c };
-CONST_OID nsExtComment[] = { NETSCAPE_CERT_EXT, 0x0d };
-
-/* the following 2 extensions are defined for and used by Cartman(NSM) */
-CONST_OID nsExtLostPasswordURL[] = { NETSCAPE_CERT_EXT, 0x0e };
-CONST_OID nsExtCertRenewalTime[] = { NETSCAPE_CERT_EXT, 0x0f };
-
-CONST_OID nsExtAIACertRenewal[] = { NETSCAPE_CERT_EXT_AIA, 0x01 };
-CONST_OID nsExtCertScopeOfUse[] = { NETSCAPE_CERT_EXT, 0x11 };
-/* Reserved Netscape (2 16 840 1 113730 1 18) = { NETSCAPE_CERT_EXT, 0x12 }; */
-
-/* Netscape policy values */
-CONST_OID nsKeyUsageGovtApproved[] = { NETSCAPE_POLICY, 0x01 };
-
-/* Netscape other name types */
-CONST_OID netscapeNickname[] = { NETSCAPE_NAME_COMPONENTS, 0x01 };
-CONST_OID netscapeAOLScreenname[] = { NETSCAPE_NAME_COMPONENTS, 0x02 };
-
-/* OIDs needed for cert server */
-CONST_OID netscapeRecoveryRequest[] = { NETSCAPE_CERT_SERVER_CRMF, 0x01 };
-
-
-/* Standard x.509 v3 Certificate & CRL Extensions */
-CONST_OID x509SubjectDirectoryAttr[] = { ID_CE_OID, 9 };
-CONST_OID x509SubjectKeyID[] = { ID_CE_OID, 14 };
-CONST_OID x509KeyUsage[] = { ID_CE_OID, 15 };
-CONST_OID x509PrivateKeyUsagePeriod[] = { ID_CE_OID, 16 };
-CONST_OID x509SubjectAltName[] = { ID_CE_OID, 17 };
-CONST_OID x509IssuerAltName[] = { ID_CE_OID, 18 };
-CONST_OID x509BasicConstraints[] = { ID_CE_OID, 19 };
-CONST_OID x509CRLNumber[] = { ID_CE_OID, 20 };
-CONST_OID x509ReasonCode[] = { ID_CE_OID, 21 };
-CONST_OID x509HoldInstructionCode[] = { ID_CE_OID, 23 };
-CONST_OID x509InvalidDate[] = { ID_CE_OID, 24 };
-CONST_OID x509DeltaCRLIndicator[] = { ID_CE_OID, 27 };
-CONST_OID x509IssuingDistributionPoint[] = { ID_CE_OID, 28 };
-CONST_OID x509CertIssuer[] = { ID_CE_OID, 29 };
-CONST_OID x509NameConstraints[] = { ID_CE_OID, 30 };
-CONST_OID x509CRLDistPoints[] = { ID_CE_OID, 31 };
-CONST_OID x509CertificatePolicies[] = { ID_CE_OID, 32 };
-CONST_OID x509PolicyMappings[] = { ID_CE_OID, 33 };
-CONST_OID x509AuthKeyID[] = { ID_CE_OID, 35 };
-CONST_OID x509PolicyConstraints[] = { ID_CE_OID, 36 };
-CONST_OID x509ExtKeyUsage[] = { ID_CE_OID, 37 };
-CONST_OID x509FreshestCRL[] = { ID_CE_OID, 46 };
-CONST_OID x509InhibitAnyPolicy[] = { ID_CE_OID, 54 };
-
-CONST_OID x509CertificatePoliciesAnyPolicy[] = { ID_CE_OID, 32, 0 };
-
-CONST_OID x509AuthInfoAccess[] = { PKIX_CERT_EXTENSIONS, 1 };
-CONST_OID x509SubjectInfoAccess[] = { PKIX_CERT_EXTENSIONS, 11 };
-
-CONST_OID x509SIATimeStamping[] = {PKIX_ACCESS_DESCRIPTION, 0x03};
-CONST_OID x509SIACaRepository[] = {PKIX_ACCESS_DESCRIPTION, 0x05};
-
-/* pkcs 12 additions */
-CONST_OID pkcs12[] = { PKCS12 };
-CONST_OID pkcs12ModeIDs[] = { PKCS12_MODE_IDS };
-CONST_OID pkcs12ESPVKIDs[] = { PKCS12_ESPVK_IDS };
-CONST_OID pkcs12BagIDs[] = { PKCS12_BAG_IDS };
-CONST_OID pkcs12CertBagIDs[] = { PKCS12_CERT_BAG_IDS };
-CONST_OID pkcs12OIDs[] = { PKCS12_OIDS };
-CONST_OID pkcs12PBEIDs[] = { PKCS12_PBE_IDS };
-CONST_OID pkcs12EnvelopingIDs[] = { PKCS12_ENVELOPING_IDS };
-CONST_OID pkcs12SignatureIDs[] = { PKCS12_SIGNATURE_IDS };
-CONST_OID pkcs12PKCS8KeyShrouding[] = { PKCS12_ESPVK_IDS, 0x01 };
-CONST_OID pkcs12KeyBagID[] = { PKCS12_BAG_IDS, 0x01 };
-CONST_OID pkcs12CertAndCRLBagID[] = { PKCS12_BAG_IDS, 0x02 };
-CONST_OID pkcs12SecretBagID[] = { PKCS12_BAG_IDS, 0x03 };
-CONST_OID pkcs12X509CertCRLBag[] = { PKCS12_CERT_BAG_IDS, 0x01 };
-CONST_OID pkcs12SDSICertBag[] = { PKCS12_CERT_BAG_IDS, 0x02 };
-CONST_OID pkcs12PBEWithSha1And128BitRC4[] = { PKCS12_PBE_IDS, 0x01 };
-CONST_OID pkcs12PBEWithSha1And40BitRC4[] = { PKCS12_PBE_IDS, 0x02 };
-CONST_OID pkcs12PBEWithSha1AndTripleDESCBC[] = { PKCS12_PBE_IDS, 0x03 };
-CONST_OID pkcs12PBEWithSha1And128BitRC2CBC[] = { PKCS12_PBE_IDS, 0x04 };
-CONST_OID pkcs12PBEWithSha1And40BitRC2CBC[] = { PKCS12_PBE_IDS, 0x05 };
-CONST_OID pkcs12RSAEncryptionWith128BitRC4[] = { PKCS12_ENVELOPING_IDS, 0x01 };
-CONST_OID pkcs12RSAEncryptionWith40BitRC4[] = { PKCS12_ENVELOPING_IDS, 0x02 };
-CONST_OID pkcs12RSAEncryptionWithTripleDES[] = { PKCS12_ENVELOPING_IDS, 0x03 };
-CONST_OID pkcs12RSASignatureWithSHA1Digest[] = { PKCS12_SIGNATURE_IDS, 0x01 };
-
-/* pkcs 12 version 1.0 ids */
-CONST_OID pkcs12V2PBEWithSha1And128BitRC4[] = { PKCS12_V2_PBE_IDS, 0x01 };
-CONST_OID pkcs12V2PBEWithSha1And40BitRC4[] = { PKCS12_V2_PBE_IDS, 0x02 };
-CONST_OID pkcs12V2PBEWithSha1And3KeyTripleDEScbc[]= { PKCS12_V2_PBE_IDS, 0x03 };
-CONST_OID pkcs12V2PBEWithSha1And2KeyTripleDEScbc[]= { PKCS12_V2_PBE_IDS, 0x04 };
-CONST_OID pkcs12V2PBEWithSha1And128BitRC2cbc[] = { PKCS12_V2_PBE_IDS, 0x05 };
-CONST_OID pkcs12V2PBEWithSha1And40BitRC2cbc[] = { PKCS12_V2_PBE_IDS, 0x06 };
-
-CONST_OID pkcs12SafeContentsID[] = { PKCS12_BAG_IDS, 0x04 };
-CONST_OID pkcs12PKCS8ShroudedKeyBagID[] = { PKCS12_BAG_IDS, 0x05 };
-
-CONST_OID pkcs12V1KeyBag[] = { PKCS12_V1_BAG_IDS, 0x01 };
-CONST_OID pkcs12V1PKCS8ShroudedKeyBag[] = { PKCS12_V1_BAG_IDS, 0x02 };
-CONST_OID pkcs12V1CertBag[] = { PKCS12_V1_BAG_IDS, 0x03 };
-CONST_OID pkcs12V1CRLBag[] = { PKCS12_V1_BAG_IDS, 0x04 };
-CONST_OID pkcs12V1SecretBag[] = { PKCS12_V1_BAG_IDS, 0x05 };
-CONST_OID pkcs12V1SafeContentsBag[] = { PKCS12_V1_BAG_IDS, 0x06 };
-
-/* The following encoding is INCORRECT, but correcting it would create a
- * duplicate OID in the table. So, we will leave it alone.
- */
-CONST_OID pkcs12KeyUsageAttr[] = { 2, 5, 29, 15 };
-
-CONST_OID ansix9DSASignature[] = { ANSI_X9_ALGORITHM, 0x01 };
-CONST_OID ansix9DSASignaturewithSHA1Digest[] = { ANSI_X9_ALGORITHM, 0x03 };
-CONST_OID nistDSASignaturewithSHA224Digest[] = { DSA2, 0x01 };
-CONST_OID nistDSASignaturewithSHA256Digest[] = { DSA2, 0x02 };
-
-/* verisign OIDs */
-CONST_OID verisignUserNotices[] = { VERISIGN, 1, 7, 1, 1 };
-
-/* pkix OIDs */
-CONST_OID pkixCPSPointerQualifier[] = { PKIX_POLICY_QUALIFIERS, 1 };
-CONST_OID pkixUserNoticeQualifier[] = { PKIX_POLICY_QUALIFIERS, 2 };
-
-CONST_OID pkixOCSP[] = { PKIX_OCSP };
-CONST_OID pkixOCSPBasicResponse[] = { PKIX_OCSP, 1 };
-CONST_OID pkixOCSPNonce[] = { PKIX_OCSP, 2 };
-CONST_OID pkixOCSPCRL[] = { PKIX_OCSP, 3 };
-CONST_OID pkixOCSPResponse[] = { PKIX_OCSP, 4 };
-CONST_OID pkixOCSPNoCheck[] = { PKIX_OCSP, 5 };
-CONST_OID pkixOCSPArchiveCutoff[] = { PKIX_OCSP, 6 };
-CONST_OID pkixOCSPServiceLocator[] = { PKIX_OCSP, 7 };
-
-CONST_OID pkixCAIssuers[] = { PKIX_CA_ISSUERS };
-
-CONST_OID pkixRegCtrlRegToken[] = { PKIX_ID_REGCTRL, 1};
-CONST_OID pkixRegCtrlAuthenticator[] = { PKIX_ID_REGCTRL, 2};
-CONST_OID pkixRegCtrlPKIPubInfo[] = { PKIX_ID_REGCTRL, 3};
-CONST_OID pkixRegCtrlPKIArchOptions[] = { PKIX_ID_REGCTRL, 4};
-CONST_OID pkixRegCtrlOldCertID[] = { PKIX_ID_REGCTRL, 5};
-CONST_OID pkixRegCtrlProtEncKey[] = { PKIX_ID_REGCTRL, 6};
-CONST_OID pkixRegInfoUTF8Pairs[] = { PKIX_ID_REGINFO, 1};
-CONST_OID pkixRegInfoCertReq[] = { PKIX_ID_REGINFO, 2};
-
-CONST_OID pkixExtendedKeyUsageServerAuth[] = { PKIX_KEY_USAGE, 1 };
-CONST_OID pkixExtendedKeyUsageClientAuth[] = { PKIX_KEY_USAGE, 2 };
-CONST_OID pkixExtendedKeyUsageCodeSign[] = { PKIX_KEY_USAGE, 3 };
-CONST_OID pkixExtendedKeyUsageEMailProtect[] = { PKIX_KEY_USAGE, 4 };
-CONST_OID pkixExtendedKeyUsageTimeStamp[] = { PKIX_KEY_USAGE, 8 };
-CONST_OID pkixOCSPResponderExtendedKeyUsage[] = { PKIX_KEY_USAGE, 9 };
-CONST_OID msExtendedKeyUsageTrustListSigning[] = { MS_CRYPTO_EKU, 1 };
-
-/* OIDs for Netscape defined algorithms */
-CONST_OID netscapeSMimeKEA[] = { NETSCAPE_ALGS, 0x01 };
-
-/* Fortezza algorithm OIDs */
-CONST_OID skipjackCBC[] = { MISSI, 0x04 };
-CONST_OID dhPublicKey[] = { ANSI_X942_ALGORITHM, 0x1 };
-
-CONST_OID aes128_ECB[] = { AES, 1 };
-CONST_OID aes128_CBC[] = { AES, 2 };
-#ifdef DEFINE_ALL_AES_CIPHERS
-CONST_OID aes128_OFB[] = { AES, 3 };
-CONST_OID aes128_CFB[] = { AES, 4 };
-#endif
-CONST_OID aes128_KEY_WRAP[] = { AES, 5 };
-
-CONST_OID aes192_ECB[] = { AES, 21 };
-CONST_OID aes192_CBC[] = { AES, 22 };
-#ifdef DEFINE_ALL_AES_CIPHERS
-CONST_OID aes192_OFB[] = { AES, 23 };
-CONST_OID aes192_CFB[] = { AES, 24 };
-#endif
-CONST_OID aes192_KEY_WRAP[] = { AES, 25 };
-
-CONST_OID aes256_ECB[] = { AES, 41 };
-CONST_OID aes256_CBC[] = { AES, 42 };
-#ifdef DEFINE_ALL_AES_CIPHERS
-CONST_OID aes256_OFB[] = { AES, 43 };
-CONST_OID aes256_CFB[] = { AES, 44 };
-#endif
-CONST_OID aes256_KEY_WRAP[] = { AES, 45 };
-
-CONST_OID camellia128_CBC[] = { CAMELLIA_ENCRYPT_OID, 2};
-CONST_OID camellia192_CBC[] = { CAMELLIA_ENCRYPT_OID, 3};
-CONST_OID camellia256_CBC[] = { CAMELLIA_ENCRYPT_OID, 4};
-CONST_OID camellia128_KEY_WRAP[] = { CAMELLIA_WRAP_OID, 2};
-CONST_OID camellia192_KEY_WRAP[] = { CAMELLIA_WRAP_OID, 3};
-CONST_OID camellia256_KEY_WRAP[] = { CAMELLIA_WRAP_OID, 4};
-
-CONST_OID sha256[] = { SHAXXX, 1 };
-CONST_OID sha384[] = { SHAXXX, 2 };
-CONST_OID sha512[] = { SHAXXX, 3 };
-CONST_OID sha224[] = { SHAXXX, 4 };
-
-CONST_OID ansix962ECPublicKey[] = { ANSI_X962_OID, 0x02, 0x01 };
-CONST_OID ansix962SignaturewithSHA1Digest[] = { ANSI_X962_SIGNATURE_OID, 0x01 };
-CONST_OID ansix962SignatureRecommended[] = { ANSI_X962_SIGNATURE_OID, 0x02 };
-CONST_OID ansix962SignatureSpecified[] = { ANSI_X962_SPECIFY_OID };
-CONST_OID ansix962SignaturewithSHA224Digest[] = { ANSI_X962_SPECIFY_OID, 0x01 };
-CONST_OID ansix962SignaturewithSHA256Digest[] = { ANSI_X962_SPECIFY_OID, 0x02 };
-CONST_OID ansix962SignaturewithSHA384Digest[] = { ANSI_X962_SPECIFY_OID, 0x03 };
-CONST_OID ansix962SignaturewithSHA512Digest[] = { ANSI_X962_SPECIFY_OID, 0x04 };
-
-/* ANSI X9.62 prime curve OIDs */
-/* NOTE: prime192v1 is the same as secp192r1, prime256v1 is the
- * same as secp256r1
- */
-CONST_OID ansiX962prime192v1[] = { ANSI_X962_GFp_OID, 0x01 };
-CONST_OID ansiX962prime192v2[] = { ANSI_X962_GFp_OID, 0x02 };
-CONST_OID ansiX962prime192v3[] = { ANSI_X962_GFp_OID, 0x03 };
-CONST_OID ansiX962prime239v1[] = { ANSI_X962_GFp_OID, 0x04 };
-CONST_OID ansiX962prime239v2[] = { ANSI_X962_GFp_OID, 0x05 };
-CONST_OID ansiX962prime239v3[] = { ANSI_X962_GFp_OID, 0x06 };
-CONST_OID ansiX962prime256v1[] = { ANSI_X962_GFp_OID, 0x07 };
-
-/* SECG prime curve OIDs */
-CONST_OID secgECsecp112r1[] = { SECG_OID, 0x06 };
-CONST_OID secgECsecp112r2[] = { SECG_OID, 0x07 };
-CONST_OID secgECsecp128r1[] = { SECG_OID, 0x1c };
-CONST_OID secgECsecp128r2[] = { SECG_OID, 0x1d };
-CONST_OID secgECsecp160k1[] = { SECG_OID, 0x09 };
-CONST_OID secgECsecp160r1[] = { SECG_OID, 0x08 };
-CONST_OID secgECsecp160r2[] = { SECG_OID, 0x1e };
-CONST_OID secgECsecp192k1[] = { SECG_OID, 0x1f };
-CONST_OID secgECsecp224k1[] = { SECG_OID, 0x20 };
-CONST_OID secgECsecp224r1[] = { SECG_OID, 0x21 };
-CONST_OID secgECsecp256k1[] = { SECG_OID, 0x0a };
-CONST_OID secgECsecp384r1[] = { SECG_OID, 0x22 };
-CONST_OID secgECsecp521r1[] = { SECG_OID, 0x23 };
-
-/* ANSI X9.62 characteristic two curve OIDs */
-CONST_OID ansiX962c2pnb163v1[] = { ANSI_X962_GF2m_OID, 0x01 };
-CONST_OID ansiX962c2pnb163v2[] = { ANSI_X962_GF2m_OID, 0x02 };
-CONST_OID ansiX962c2pnb163v3[] = { ANSI_X962_GF2m_OID, 0x03 };
-CONST_OID ansiX962c2pnb176v1[] = { ANSI_X962_GF2m_OID, 0x04 };
-CONST_OID ansiX962c2tnb191v1[] = { ANSI_X962_GF2m_OID, 0x05 };
-CONST_OID ansiX962c2tnb191v2[] = { ANSI_X962_GF2m_OID, 0x06 };
-CONST_OID ansiX962c2tnb191v3[] = { ANSI_X962_GF2m_OID, 0x07 };
-CONST_OID ansiX962c2onb191v4[] = { ANSI_X962_GF2m_OID, 0x08 };
-CONST_OID ansiX962c2onb191v5[] = { ANSI_X962_GF2m_OID, 0x09 };
-CONST_OID ansiX962c2pnb208w1[] = { ANSI_X962_GF2m_OID, 0x0a };
-CONST_OID ansiX962c2tnb239v1[] = { ANSI_X962_GF2m_OID, 0x0b };
-CONST_OID ansiX962c2tnb239v2[] = { ANSI_X962_GF2m_OID, 0x0c };
-CONST_OID ansiX962c2tnb239v3[] = { ANSI_X962_GF2m_OID, 0x0d };
-CONST_OID ansiX962c2onb239v4[] = { ANSI_X962_GF2m_OID, 0x0e };
-CONST_OID ansiX962c2onb239v5[] = { ANSI_X962_GF2m_OID, 0x0f };
-CONST_OID ansiX962c2pnb272w1[] = { ANSI_X962_GF2m_OID, 0x10 };
-CONST_OID ansiX962c2pnb304w1[] = { ANSI_X962_GF2m_OID, 0x11 };
-CONST_OID ansiX962c2tnb359v1[] = { ANSI_X962_GF2m_OID, 0x12 };
-CONST_OID ansiX962c2pnb368w1[] = { ANSI_X962_GF2m_OID, 0x13 };
-CONST_OID ansiX962c2tnb431r1[] = { ANSI_X962_GF2m_OID, 0x14 };
-
-/* SECG characterisitic two curve OIDs */
-CONST_OID secgECsect113r1[] = {SECG_OID, 0x04 };
-CONST_OID secgECsect113r2[] = {SECG_OID, 0x05 };
-CONST_OID secgECsect131r1[] = {SECG_OID, 0x16 };
-CONST_OID secgECsect131r2[] = {SECG_OID, 0x17 };
-CONST_OID secgECsect163k1[] = {SECG_OID, 0x01 };
-CONST_OID secgECsect163r1[] = {SECG_OID, 0x02 };
-CONST_OID secgECsect163r2[] = {SECG_OID, 0x0f };
-CONST_OID secgECsect193r1[] = {SECG_OID, 0x18 };
-CONST_OID secgECsect193r2[] = {SECG_OID, 0x19 };
-CONST_OID secgECsect233k1[] = {SECG_OID, 0x1a };
-CONST_OID secgECsect233r1[] = {SECG_OID, 0x1b };
-CONST_OID secgECsect239k1[] = {SECG_OID, 0x03 };
-CONST_OID secgECsect283k1[] = {SECG_OID, 0x10 };
-CONST_OID secgECsect283r1[] = {SECG_OID, 0x11 };
-CONST_OID secgECsect409k1[] = {SECG_OID, 0x24 };
-CONST_OID secgECsect409r1[] = {SECG_OID, 0x25 };
-CONST_OID secgECsect571k1[] = {SECG_OID, 0x26 };
-CONST_OID secgECsect571r1[] = {SECG_OID, 0x27 };
-
-CONST_OID seed_CBC[] = { SEED_OID, 4 };
-
-CONST_OID evIncorporationLocality[] = { EV_NAME_ATTRIBUTE, 1 };
-CONST_OID evIncorporationState[] = { EV_NAME_ATTRIBUTE, 2 };
-CONST_OID evIncorporationCountry[] = { EV_NAME_ATTRIBUTE, 3 };
-
-#define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
-#ifndef SECOID_NO_STRINGS
-#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, desc, mech, ext }
-#else
-#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, 0, mech, ext }
-#endif
-
-#if defined(NSS_ALLOW_UNSUPPORTED_CRITICAL)
-#define FAKE_SUPPORTED_CERT_EXTENSION SUPPORTED_CERT_EXTENSION
-#else
-#define FAKE_SUPPORTED_CERT_EXTENSION UNSUPPORTED_CERT_EXTENSION
-#endif
-
-/*
- * NOTE: the order of these entries must mach the SECOidTag enum in secoidt.h!
- */
-const static SECOidData oids[SEC_OID_TOTAL] = {
- { { siDEROID, NULL, 0 }, SEC_OID_UNKNOWN,
- "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
- OD( md2, SEC_OID_MD2, "MD2", CKM_MD2, INVALID_CERT_EXTENSION ),
- OD( md4, SEC_OID_MD4,
- "MD4", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( md5, SEC_OID_MD5, "MD5", CKM_MD5, INVALID_CERT_EXTENSION ),
- OD( sha1, SEC_OID_SHA1, "SHA-1", CKM_SHA_1, INVALID_CERT_EXTENSION ),
- OD( rc2cbc, SEC_OID_RC2_CBC,
- "RC2-CBC", CKM_RC2_CBC, INVALID_CERT_EXTENSION ),
- OD( rc4, SEC_OID_RC4, "RC4", CKM_RC4, INVALID_CERT_EXTENSION ),
- OD( desede3cbc, SEC_OID_DES_EDE3_CBC,
- "DES-EDE3-CBC", CKM_DES3_CBC, INVALID_CERT_EXTENSION ),
- OD( rc5cbcpad, SEC_OID_RC5_CBC_PAD,
- "RC5-CBCPad", CKM_RC5_CBC, INVALID_CERT_EXTENSION ),
- OD( desecb, SEC_OID_DES_ECB,
- "DES-ECB", CKM_DES_ECB, INVALID_CERT_EXTENSION ),
- OD( descbc, SEC_OID_DES_CBC,
- "DES-CBC", CKM_DES_CBC, INVALID_CERT_EXTENSION ),
- OD( desofb, SEC_OID_DES_OFB,
- "DES-OFB", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( descfb, SEC_OID_DES_CFB,
- "DES-CFB", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( desmac, SEC_OID_DES_MAC,
- "DES-MAC", CKM_DES_MAC, INVALID_CERT_EXTENSION ),
- OD( desede, SEC_OID_DES_EDE,
- "DES-EDE", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( isoSHAWithRSASignature, SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE,
- "ISO SHA with RSA Signature",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs1RSAEncryption, SEC_OID_PKCS1_RSA_ENCRYPTION,
- "PKCS #1 RSA Encryption", CKM_RSA_PKCS, INVALID_CERT_EXTENSION ),
-
- /* the following Signing mechanisms should get new CKM_ values when
- * values for CKM_RSA_WITH_MDX and CKM_RSA_WITH_SHA_1 get defined in
- * PKCS #11.
- */
- OD( pkcs1MD2WithRSAEncryption, SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION,
- "PKCS #1 MD2 With RSA Encryption", CKM_MD2_RSA_PKCS,
- INVALID_CERT_EXTENSION ),
- OD( pkcs1MD4WithRSAEncryption, SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION,
- "PKCS #1 MD4 With RSA Encryption",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs1MD5WithRSAEncryption, SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,
- "PKCS #1 MD5 With RSA Encryption", CKM_MD5_RSA_PKCS,
- INVALID_CERT_EXTENSION ),
- OD( pkcs1SHA1WithRSAEncryption, SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION,
- "PKCS #1 SHA-1 With RSA Encryption", CKM_SHA1_RSA_PKCS,
- INVALID_CERT_EXTENSION ),
-
- OD( pkcs5PbeWithMD2AndDEScbc, SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC,
- "PKCS #5 Password Based Encryption with MD2 and DES-CBC",
- CKM_PBE_MD2_DES_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs5PbeWithMD5AndDEScbc, SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC,
- "PKCS #5 Password Based Encryption with MD5 and DES-CBC",
- CKM_PBE_MD5_DES_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs5PbeWithSha1AndDEScbc, SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC,
- "PKCS #5 Password Based Encryption with SHA-1 and DES-CBC",
- CKM_NETSCAPE_PBE_SHA1_DES_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs7, SEC_OID_PKCS7,
- "PKCS #7", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs7Data, SEC_OID_PKCS7_DATA,
- "PKCS #7 Data", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs7SignedData, SEC_OID_PKCS7_SIGNED_DATA,
- "PKCS #7 Signed Data", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs7EnvelopedData, SEC_OID_PKCS7_ENVELOPED_DATA,
- "PKCS #7 Enveloped Data",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs7SignedEnvelopedData, SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA,
- "PKCS #7 Signed And Enveloped Data",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs7DigestedData, SEC_OID_PKCS7_DIGESTED_DATA,
- "PKCS #7 Digested Data",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs7EncryptedData, SEC_OID_PKCS7_ENCRYPTED_DATA,
- "PKCS #7 Encrypted Data",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9EmailAddress, SEC_OID_PKCS9_EMAIL_ADDRESS,
- "PKCS #9 Email Address",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9UnstructuredName, SEC_OID_PKCS9_UNSTRUCTURED_NAME,
- "PKCS #9 Unstructured Name",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9ContentType, SEC_OID_PKCS9_CONTENT_TYPE,
- "PKCS #9 Content Type",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9MessageDigest, SEC_OID_PKCS9_MESSAGE_DIGEST,
- "PKCS #9 Message Digest",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9SigningTime, SEC_OID_PKCS9_SIGNING_TIME,
- "PKCS #9 Signing Time",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9CounterSignature, SEC_OID_PKCS9_COUNTER_SIGNATURE,
- "PKCS #9 Counter Signature",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9ChallengePassword, SEC_OID_PKCS9_CHALLENGE_PASSWORD,
- "PKCS #9 Challenge Password",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9UnstructuredAddress, SEC_OID_PKCS9_UNSTRUCTURED_ADDRESS,
- "PKCS #9 Unstructured Address",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9ExtendedCertificateAttributes,
- SEC_OID_PKCS9_EXTENDED_CERTIFICATE_ATTRIBUTES,
- "PKCS #9 Extended Certificate Attributes",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9SMIMECapabilities, SEC_OID_PKCS9_SMIME_CAPABILITIES,
- "PKCS #9 S/MIME Capabilities",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520CommonName, SEC_OID_AVA_COMMON_NAME,
- "X520 Common Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520CountryName, SEC_OID_AVA_COUNTRY_NAME,
- "X520 Country Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520LocalityName, SEC_OID_AVA_LOCALITY,
- "X520 Locality Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520StateOrProvinceName, SEC_OID_AVA_STATE_OR_PROVINCE,
- "X520 State Or Province Name",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520OrgName, SEC_OID_AVA_ORGANIZATION_NAME,
- "X520 Organization Name",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520OrgUnitName, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
- "X520 Organizational Unit Name",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520DnQualifier, SEC_OID_AVA_DN_QUALIFIER,
- "X520 DN Qualifier", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( rfc2247DomainComponent, SEC_OID_AVA_DC,
- "RFC 2247 Domain Component",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- OD( nsTypeGIF, SEC_OID_NS_TYPE_GIF,
- "GIF", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( nsTypeJPEG, SEC_OID_NS_TYPE_JPEG,
- "JPEG", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( nsTypeURL, SEC_OID_NS_TYPE_URL,
- "URL", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( nsTypeHTML, SEC_OID_NS_TYPE_HTML,
- "HTML", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( nsTypeCertSeq, SEC_OID_NS_TYPE_CERT_SEQUENCE,
- "Certificate Sequence",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( missiCertKEADSSOld, SEC_OID_MISSI_KEA_DSS_OLD,
- "MISSI KEA and DSS Algorithm (Old)",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( missiCertDSSOld, SEC_OID_MISSI_DSS_OLD,
- "MISSI DSS Algorithm (Old)",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( missiCertKEADSS, SEC_OID_MISSI_KEA_DSS,
- "MISSI KEA and DSS Algorithm",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( missiCertDSS, SEC_OID_MISSI_DSS,
- "MISSI DSS Algorithm",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( missiCertKEA, SEC_OID_MISSI_KEA,
- "MISSI KEA Algorithm",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( missiCertAltKEA, SEC_OID_MISSI_ALT_KEA,
- "MISSI Alternate KEA Algorithm",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* Netscape private extensions */
- OD( nsCertExtNetscapeOK, SEC_OID_NS_CERT_EXT_NETSCAPE_OK,
- "Netscape says this cert is OK",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( nsCertExtIssuerLogo, SEC_OID_NS_CERT_EXT_ISSUER_LOGO,
- "Certificate Issuer Logo",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( nsCertExtSubjectLogo, SEC_OID_NS_CERT_EXT_SUBJECT_LOGO,
- "Certificate Subject Logo",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( nsExtCertType, SEC_OID_NS_CERT_EXT_CERT_TYPE,
- "Certificate Type",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( nsExtBaseURL, SEC_OID_NS_CERT_EXT_BASE_URL,
- "Certificate Extension Base URL",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( nsExtRevocationURL, SEC_OID_NS_CERT_EXT_REVOCATION_URL,
- "Certificate Revocation URL",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( nsExtCARevocationURL, SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL,
- "Certificate Authority Revocation URL",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( nsExtCACRLURL, SEC_OID_NS_CERT_EXT_CA_CRL_URL,
- "Certificate Authority CRL Download URL",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( nsExtCACertURL, SEC_OID_NS_CERT_EXT_CA_CERT_URL,
- "Certificate Authority Certificate Download URL",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( nsExtCertRenewalURL, SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL,
- "Certificate Renewal URL",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( nsExtCAPolicyURL, SEC_OID_NS_CERT_EXT_CA_POLICY_URL,
- "Certificate Authority Policy URL",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( nsExtHomepageURL, SEC_OID_NS_CERT_EXT_HOMEPAGE_URL,
- "Certificate Homepage URL",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( nsExtEntityLogo, SEC_OID_NS_CERT_EXT_ENTITY_LOGO,
- "Certificate Entity Logo",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( nsExtUserPicture, SEC_OID_NS_CERT_EXT_USER_PICTURE,
- "Certificate User Picture",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( nsExtSSLServerName, SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME,
- "Certificate SSL Server Name",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( nsExtComment, SEC_OID_NS_CERT_EXT_COMMENT,
- "Certificate Comment",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( nsExtLostPasswordURL, SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL,
- "Lost Password URL",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( nsExtCertRenewalTime, SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME,
- "Certificate Renewal Time",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( nsKeyUsageGovtApproved, SEC_OID_NS_KEY_USAGE_GOVT_APPROVED,
- "Strong Crypto Export Approved",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
-
-
- /* x.509 v3 certificate extensions */
- OD( x509SubjectDirectoryAttr, SEC_OID_X509_SUBJECT_DIRECTORY_ATTR,
- "Certificate Subject Directory Attributes",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION),
- OD( x509SubjectKeyID, SEC_OID_X509_SUBJECT_KEY_ID,
- "Certificate Subject Key ID",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( x509KeyUsage, SEC_OID_X509_KEY_USAGE,
- "Certificate Key Usage",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( x509PrivateKeyUsagePeriod, SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD,
- "Certificate Private Key Usage Period",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( x509SubjectAltName, SEC_OID_X509_SUBJECT_ALT_NAME,
- "Certificate Subject Alt Name",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( x509IssuerAltName, SEC_OID_X509_ISSUER_ALT_NAME,
- "Certificate Issuer Alt Name",
- CKM_INVALID_MECHANISM, FAKE_SUPPORTED_CERT_EXTENSION ),
- OD( x509BasicConstraints, SEC_OID_X509_BASIC_CONSTRAINTS,
- "Certificate Basic Constraints",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( x509NameConstraints, SEC_OID_X509_NAME_CONSTRAINTS,
- "Certificate Name Constraints",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( x509CRLDistPoints, SEC_OID_X509_CRL_DIST_POINTS,
- "CRL Distribution Points",
- CKM_INVALID_MECHANISM, FAKE_SUPPORTED_CERT_EXTENSION ),
- OD( x509CertificatePolicies, SEC_OID_X509_CERTIFICATE_POLICIES,
- "Certificate Policies",
- CKM_INVALID_MECHANISM, FAKE_SUPPORTED_CERT_EXTENSION ),
- OD( x509PolicyMappings, SEC_OID_X509_POLICY_MAPPINGS,
- "Certificate Policy Mappings",
- CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
- OD( x509PolicyConstraints, SEC_OID_X509_POLICY_CONSTRAINTS,
- "Certificate Policy Constraints",
- CKM_INVALID_MECHANISM, FAKE_SUPPORTED_CERT_EXTENSION ),
- OD( x509AuthKeyID, SEC_OID_X509_AUTH_KEY_ID,
- "Certificate Authority Key Identifier",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( x509ExtKeyUsage, SEC_OID_X509_EXT_KEY_USAGE,
- "Extended Key Usage",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( x509AuthInfoAccess, SEC_OID_X509_AUTH_INFO_ACCESS,
- "Authority Information Access",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
-
- /* x.509 v3 CRL extensions */
- OD( x509CRLNumber, SEC_OID_X509_CRL_NUMBER,
- "CRL Number", CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( x509ReasonCode, SEC_OID_X509_REASON_CODE,
- "CRL reason code", CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( x509InvalidDate, SEC_OID_X509_INVALID_DATE,
- "Invalid Date", CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
-
- OD( x500RSAEncryption, SEC_OID_X500_RSA_ENCRYPTION,
- "X500 RSA Encryption", CKM_RSA_X_509, INVALID_CERT_EXTENSION ),
-
- /* added for alg 1485 */
- OD( rfc1274Uid, SEC_OID_RFC1274_UID,
- "RFC1274 User Id", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( rfc1274Mail, SEC_OID_RFC1274_MAIL,
- "RFC1274 E-mail Address",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* pkcs 12 additions */
- OD( pkcs12, SEC_OID_PKCS12,
- "PKCS #12", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12ModeIDs, SEC_OID_PKCS12_MODE_IDS,
- "PKCS #12 Mode IDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12ESPVKIDs, SEC_OID_PKCS12_ESPVK_IDS,
- "PKCS #12 ESPVK IDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12BagIDs, SEC_OID_PKCS12_BAG_IDS,
- "PKCS #12 Bag IDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12CertBagIDs, SEC_OID_PKCS12_CERT_BAG_IDS,
- "PKCS #12 Cert Bag IDs",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12OIDs, SEC_OID_PKCS12_OIDS,
- "PKCS #12 OIDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12PBEIDs, SEC_OID_PKCS12_PBE_IDS,
- "PKCS #12 PBE IDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12SignatureIDs, SEC_OID_PKCS12_SIGNATURE_IDS,
- "PKCS #12 Signature IDs",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12EnvelopingIDs, SEC_OID_PKCS12_ENVELOPING_IDS,
- "PKCS #12 Enveloping IDs",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12PKCS8KeyShrouding, SEC_OID_PKCS12_PKCS8_KEY_SHROUDING,
- "PKCS #12 Key Shrouding",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12KeyBagID, SEC_OID_PKCS12_KEY_BAG_ID,
- "PKCS #12 Key Bag ID",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12CertAndCRLBagID, SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID,
- "PKCS #12 Cert And CRL Bag ID",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12SecretBagID, SEC_OID_PKCS12_SECRET_BAG_ID,
- "PKCS #12 Secret Bag ID",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12X509CertCRLBag, SEC_OID_PKCS12_X509_CERT_CRL_BAG,
- "PKCS #12 X509 Cert CRL Bag",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12SDSICertBag, SEC_OID_PKCS12_SDSI_CERT_BAG,
- "PKCS #12 SDSI Cert Bag",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12PBEWithSha1And128BitRC4,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4,
- "PKCS #12 PBE With SHA-1 and 128 Bit RC4",
- CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4, INVALID_CERT_EXTENSION ),
- OD( pkcs12PBEWithSha1And40BitRC4,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4,
- "PKCS #12 PBE With SHA-1 and 40 Bit RC4",
- CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4, INVALID_CERT_EXTENSION ),
- OD( pkcs12PBEWithSha1AndTripleDESCBC,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC,
- "PKCS #12 PBE With SHA-1 and Triple DES-CBC",
- CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs12PBEWithSha1And128BitRC2CBC,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC,
- "PKCS #12 PBE With SHA-1 and 128 Bit RC2 CBC",
- CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs12PBEWithSha1And40BitRC2CBC,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC,
- "PKCS #12 PBE With SHA-1 and 40 Bit RC2 CBC",
- CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs12RSAEncryptionWith128BitRC4,
- SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_128_BIT_RC4,
- "PKCS #12 RSA Encryption with 128 Bit RC4",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12RSAEncryptionWith40BitRC4,
- SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_40_BIT_RC4,
- "PKCS #12 RSA Encryption with 40 Bit RC4",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12RSAEncryptionWithTripleDES,
- SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_TRIPLE_DES,
- "PKCS #12 RSA Encryption with Triple DES",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12RSASignatureWithSHA1Digest,
- SEC_OID_PKCS12_RSA_SIGNATURE_WITH_SHA1_DIGEST,
- "PKCS #12 RSA Encryption with Triple DES",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* DSA signatures */
- OD( ansix9DSASignature, SEC_OID_ANSIX9_DSA_SIGNATURE,
- "ANSI X9.57 DSA Signature", CKM_DSA, INVALID_CERT_EXTENSION ),
- OD( ansix9DSASignaturewithSHA1Digest,
- SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST,
- "ANSI X9.57 DSA Signature with SHA-1 Digest",
- CKM_DSA_SHA1, INVALID_CERT_EXTENSION ),
- OD( bogusDSASignaturewithSHA1Digest,
- SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST,
- "FORTEZZA DSA Signature with SHA-1 Digest",
- CKM_DSA_SHA1, INVALID_CERT_EXTENSION ),
-
- /* verisign oids */
- OD( verisignUserNotices, SEC_OID_VERISIGN_USER_NOTICES,
- "Verisign User Notices",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* pkix oids */
- OD( pkixCPSPointerQualifier, SEC_OID_PKIX_CPS_POINTER_QUALIFIER,
- "PKIX CPS Pointer Qualifier",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkixUserNoticeQualifier, SEC_OID_PKIX_USER_NOTICE_QUALIFIER,
- "PKIX User Notice Qualifier",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- OD( pkixOCSP, SEC_OID_PKIX_OCSP,
- "PKIX Online Certificate Status Protocol",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkixOCSPBasicResponse, SEC_OID_PKIX_OCSP_BASIC_RESPONSE,
- "OCSP Basic Response", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkixOCSPNonce, SEC_OID_PKIX_OCSP_NONCE,
- "OCSP Nonce Extension", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkixOCSPCRL, SEC_OID_PKIX_OCSP_CRL,
- "OCSP CRL Reference Extension",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkixOCSPResponse, SEC_OID_PKIX_OCSP_RESPONSE,
- "OCSP Response Types Extension",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkixOCSPNoCheck, SEC_OID_PKIX_OCSP_NO_CHECK,
- "OCSP No Check Extension",
- CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
- OD( pkixOCSPArchiveCutoff, SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF,
- "OCSP Archive Cutoff Extension",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkixOCSPServiceLocator, SEC_OID_PKIX_OCSP_SERVICE_LOCATOR,
- "OCSP Service Locator Extension",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- OD( pkixRegCtrlRegToken, SEC_OID_PKIX_REGCTRL_REGTOKEN,
- "PKIX CRMF Registration Control, Registration Token",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkixRegCtrlAuthenticator, SEC_OID_PKIX_REGCTRL_AUTHENTICATOR,
- "PKIX CRMF Registration Control, Registration Authenticator",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkixRegCtrlPKIPubInfo, SEC_OID_PKIX_REGCTRL_PKIPUBINFO,
- "PKIX CRMF Registration Control, PKI Publication Info",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixRegCtrlPKIArchOptions,
- SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS,
- "PKIX CRMF Registration Control, PKI Archive Options",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixRegCtrlOldCertID, SEC_OID_PKIX_REGCTRL_OLD_CERT_ID,
- "PKIX CRMF Registration Control, Old Certificate ID",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixRegCtrlProtEncKey, SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY,
- "PKIX CRMF Registration Control, Protocol Encryption Key",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixRegInfoUTF8Pairs, SEC_OID_PKIX_REGINFO_UTF8_PAIRS,
- "PKIX CRMF Registration Info, UTF8 Pairs",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixRegInfoCertReq, SEC_OID_PKIX_REGINFO_CERT_REQUEST,
- "PKIX CRMF Registration Info, Certificate Request",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixExtendedKeyUsageServerAuth,
- SEC_OID_EXT_KEY_USAGE_SERVER_AUTH,
- "TLS Web Server Authentication Certificate",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixExtendedKeyUsageClientAuth,
- SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH,
- "TLS Web Client Authentication Certificate",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixExtendedKeyUsageCodeSign, SEC_OID_EXT_KEY_USAGE_CODE_SIGN,
- "Code Signing Certificate",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixExtendedKeyUsageEMailProtect,
- SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT,
- "E-Mail Protection Certificate",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixExtendedKeyUsageTimeStamp,
- SEC_OID_EXT_KEY_USAGE_TIME_STAMP,
- "Time Stamping Certifcate",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
- OD( pkixOCSPResponderExtendedKeyUsage, SEC_OID_OCSP_RESPONDER,
- "OCSP Responder Certificate",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
-
- /* Netscape Algorithm OIDs */
-
- OD( netscapeSMimeKEA, SEC_OID_NETSCAPE_SMIME_KEA,
- "Netscape S/MIME KEA", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* Skipjack OID -- ### mwelch temporary */
- OD( skipjackCBC, SEC_OID_FORTEZZA_SKIPJACK,
- "Skipjack CBC64", CKM_SKIPJACK_CBC64, INVALID_CERT_EXTENSION ),
-
- /* pkcs12 v2 oids */
- OD( pkcs12V2PBEWithSha1And128BitRC4,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4,
- "PKCS #12 V2 PBE With SHA-1 And 128 Bit RC4",
- CKM_PBE_SHA1_RC4_128, INVALID_CERT_EXTENSION ),
- OD( pkcs12V2PBEWithSha1And40BitRC4,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4,
- "PKCS #12 V2 PBE With SHA-1 And 40 Bit RC4",
- CKM_PBE_SHA1_RC4_40, INVALID_CERT_EXTENSION ),
- OD( pkcs12V2PBEWithSha1And3KeyTripleDEScbc,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC,
- "PKCS #12 V2 PBE With SHA-1 And 3KEY Triple DES-CBC",
- CKM_PBE_SHA1_DES3_EDE_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs12V2PBEWithSha1And2KeyTripleDEScbc,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC,
- "PKCS #12 V2 PBE With SHA-1 And 2KEY Triple DES-CBC",
- CKM_PBE_SHA1_DES2_EDE_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs12V2PBEWithSha1And128BitRC2cbc,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC,
- "PKCS #12 V2 PBE With SHA-1 And 128 Bit RC2 CBC",
- CKM_PBE_SHA1_RC2_128_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs12V2PBEWithSha1And40BitRC2cbc,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC,
- "PKCS #12 V2 PBE With SHA-1 And 40 Bit RC2 CBC",
- CKM_PBE_SHA1_RC2_40_CBC, INVALID_CERT_EXTENSION ),
- OD( pkcs12SafeContentsID, SEC_OID_PKCS12_SAFE_CONTENTS_ID,
- "PKCS #12 Safe Contents ID",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12PKCS8ShroudedKeyBagID,
- SEC_OID_PKCS12_PKCS8_SHROUDED_KEY_BAG_ID,
- "PKCS #12 Safe Contents ID",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12V1KeyBag, SEC_OID_PKCS12_V1_KEY_BAG_ID,
- "PKCS #12 V1 Key Bag",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12V1PKCS8ShroudedKeyBag,
- SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID,
- "PKCS #12 V1 PKCS8 Shrouded Key Bag",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12V1CertBag, SEC_OID_PKCS12_V1_CERT_BAG_ID,
- "PKCS #12 V1 Cert Bag",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12V1CRLBag, SEC_OID_PKCS12_V1_CRL_BAG_ID,
- "PKCS #12 V1 CRL Bag",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12V1SecretBag, SEC_OID_PKCS12_V1_SECRET_BAG_ID,
- "PKCS #12 V1 Secret Bag",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12V1SafeContentsBag, SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID,
- "PKCS #12 V1 Safe Contents Bag",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- OD( pkcs9X509Certificate, SEC_OID_PKCS9_X509_CERT,
- "PKCS #9 X509 Certificate",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9SDSICertificate, SEC_OID_PKCS9_SDSI_CERT,
- "PKCS #9 SDSI Certificate",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9X509CRL, SEC_OID_PKCS9_X509_CRL,
- "PKCS #9 X509 CRL", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9FriendlyName, SEC_OID_PKCS9_FRIENDLY_NAME,
- "PKCS #9 Friendly Name",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9LocalKeyID, SEC_OID_PKCS9_LOCAL_KEY_ID,
- "PKCS #9 Local Key ID",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs12KeyUsageAttr, SEC_OID_BOGUS_KEY_USAGE,
- "Bogus Key Usage", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( dhPublicKey, SEC_OID_X942_DIFFIE_HELMAN_KEY,
- "Diffie-Helman Public Key", CKM_DH_PKCS_DERIVE,
- INVALID_CERT_EXTENSION ),
- OD( netscapeNickname, SEC_OID_NETSCAPE_NICKNAME,
- "Netscape Nickname", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* Cert Server specific OIDs */
- OD( netscapeRecoveryRequest, SEC_OID_NETSCAPE_RECOVERY_REQUEST,
- "Recovery Request OID",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- OD( nsExtAIACertRenewal, SEC_OID_CERT_RENEWAL_LOCATOR,
- "Certificate Renewal Locator OID", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
-
- OD( nsExtCertScopeOfUse, SEC_OID_NS_CERT_EXT_SCOPE_OF_USE,
- "Certificate Scope-of-Use Extension", CKM_INVALID_MECHANISM,
- SUPPORTED_CERT_EXTENSION ),
-
- /* CMS stuff */
- OD( cmsESDH, SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN,
- "Ephemeral-Static Diffie-Hellman", CKM_INVALID_MECHANISM /* XXX */,
- INVALID_CERT_EXTENSION ),
- OD( cms3DESwrap, SEC_OID_CMS_3DES_KEY_WRAP,
- "CMS Triple DES Key Wrap", CKM_INVALID_MECHANISM /* XXX */,
- INVALID_CERT_EXTENSION ),
- OD( cmsRC2wrap, SEC_OID_CMS_RC2_KEY_WRAP,
- "CMS RC2 Key Wrap", CKM_INVALID_MECHANISM /* XXX */,
- INVALID_CERT_EXTENSION ),
- OD( smimeEncryptionKeyPreference, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE,
- "S/MIME Encryption Key Preference",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* AES algorithm OIDs */
- OD( aes128_ECB, SEC_OID_AES_128_ECB,
- "AES-128-ECB", CKM_AES_ECB, INVALID_CERT_EXTENSION ),
- OD( aes128_CBC, SEC_OID_AES_128_CBC,
- "AES-128-CBC", CKM_AES_CBC, INVALID_CERT_EXTENSION ),
- OD( aes192_ECB, SEC_OID_AES_192_ECB,
- "AES-192-ECB", CKM_AES_ECB, INVALID_CERT_EXTENSION ),
- OD( aes192_CBC, SEC_OID_AES_192_CBC,
- "AES-192-CBC", CKM_AES_CBC, INVALID_CERT_EXTENSION ),
- OD( aes256_ECB, SEC_OID_AES_256_ECB,
- "AES-256-ECB", CKM_AES_ECB, INVALID_CERT_EXTENSION ),
- OD( aes256_CBC, SEC_OID_AES_256_CBC,
- "AES-256-CBC", CKM_AES_CBC, INVALID_CERT_EXTENSION ),
-
- /* More bogus DSA OIDs */
- OD( sdn702DSASignature, SEC_OID_SDN702_DSA_SIGNATURE,
- "SDN.702 DSA Signature", CKM_DSA_SHA1, INVALID_CERT_EXTENSION ),
-
- OD( ms_smimeEncryptionKeyPreference,
- SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE,
- "Microsoft S/MIME Encryption Key Preference",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- OD( sha256, SEC_OID_SHA256, "SHA-256", CKM_SHA256, INVALID_CERT_EXTENSION),
- OD( sha384, SEC_OID_SHA384, "SHA-384", CKM_SHA384, INVALID_CERT_EXTENSION),
- OD( sha512, SEC_OID_SHA512, "SHA-512", CKM_SHA512, INVALID_CERT_EXTENSION),
-
- OD( pkcs1SHA256WithRSAEncryption, SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION,
- "PKCS #1 SHA-256 With RSA Encryption", CKM_SHA256_RSA_PKCS,
- INVALID_CERT_EXTENSION ),
- OD( pkcs1SHA384WithRSAEncryption, SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION,
- "PKCS #1 SHA-384 With RSA Encryption", CKM_SHA384_RSA_PKCS,
- INVALID_CERT_EXTENSION ),
- OD( pkcs1SHA512WithRSAEncryption, SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION,
- "PKCS #1 SHA-512 With RSA Encryption", CKM_SHA512_RSA_PKCS,
- INVALID_CERT_EXTENSION ),
-
- OD( aes128_KEY_WRAP, SEC_OID_AES_128_KEY_WRAP,
- "AES-128 Key Wrap", CKM_NSS_AES_KEY_WRAP, INVALID_CERT_EXTENSION),
- OD( aes192_KEY_WRAP, SEC_OID_AES_192_KEY_WRAP,
- "AES-192 Key Wrap", CKM_NSS_AES_KEY_WRAP, INVALID_CERT_EXTENSION),
- OD( aes256_KEY_WRAP, SEC_OID_AES_256_KEY_WRAP,
- "AES-256 Key Wrap", CKM_NSS_AES_KEY_WRAP, INVALID_CERT_EXTENSION),
-
- /* Elliptic Curve Cryptography (ECC) OIDs */
- OD( ansix962ECPublicKey, SEC_OID_ANSIX962_EC_PUBLIC_KEY,
- "X9.62 elliptic curve public key", CKM_ECDH1_DERIVE,
- INVALID_CERT_EXTENSION ),
- OD( ansix962SignaturewithSHA1Digest,
- SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE,
- "X9.62 ECDSA signature with SHA-1", CKM_ECDSA_SHA1,
- INVALID_CERT_EXTENSION ),
-
- /* Named curves */
-
- /* ANSI X9.62 named elliptic curves (prime field) */
- OD( ansiX962prime192v1, SEC_OID_ANSIX962_EC_PRIME192V1,
- "ANSI X9.62 elliptic curve prime192v1 (aka secp192r1, NIST P-192)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962prime192v2, SEC_OID_ANSIX962_EC_PRIME192V2,
- "ANSI X9.62 elliptic curve prime192v2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962prime192v3, SEC_OID_ANSIX962_EC_PRIME192V3,
- "ANSI X9.62 elliptic curve prime192v3",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962prime239v1, SEC_OID_ANSIX962_EC_PRIME239V1,
- "ANSI X9.62 elliptic curve prime239v1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962prime239v2, SEC_OID_ANSIX962_EC_PRIME239V2,
- "ANSI X9.62 elliptic curve prime239v2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962prime239v3, SEC_OID_ANSIX962_EC_PRIME239V3,
- "ANSI X9.62 elliptic curve prime239v3",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962prime256v1, SEC_OID_ANSIX962_EC_PRIME256V1,
- "ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
-
- /* SECG named elliptic curves (prime field) */
- OD( secgECsecp112r1, SEC_OID_SECG_EC_SECP112R1,
- "SECG elliptic curve secp112r1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp112r2, SEC_OID_SECG_EC_SECP112R2,
- "SECG elliptic curve secp112r2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp128r1, SEC_OID_SECG_EC_SECP128R1,
- "SECG elliptic curve secp128r1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp128r2, SEC_OID_SECG_EC_SECP128R2,
- "SECG elliptic curve secp128r2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp160k1, SEC_OID_SECG_EC_SECP160K1,
- "SECG elliptic curve secp160k1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp160r1, SEC_OID_SECG_EC_SECP160R1,
- "SECG elliptic curve secp160r1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp160r2, SEC_OID_SECG_EC_SECP160R2,
- "SECG elliptic curve secp160r2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp192k1, SEC_OID_SECG_EC_SECP192K1,
- "SECG elliptic curve secp192k1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp224k1, SEC_OID_SECG_EC_SECP224K1,
- "SECG elliptic curve secp224k1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp224r1, SEC_OID_SECG_EC_SECP224R1,
- "SECG elliptic curve secp224r1 (aka NIST P-224)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp256k1, SEC_OID_SECG_EC_SECP256K1,
- "SECG elliptic curve secp256k1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp384r1, SEC_OID_SECG_EC_SECP384R1,
- "SECG elliptic curve secp384r1 (aka NIST P-384)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsecp521r1, SEC_OID_SECG_EC_SECP521R1,
- "SECG elliptic curve secp521r1 (aka NIST P-521)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
-
- /* ANSI X9.62 named elliptic curves (characteristic two field) */
- OD( ansiX962c2pnb163v1, SEC_OID_ANSIX962_EC_C2PNB163V1,
- "ANSI X9.62 elliptic curve c2pnb163v1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2pnb163v2, SEC_OID_ANSIX962_EC_C2PNB163V2,
- "ANSI X9.62 elliptic curve c2pnb163v2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2pnb163v3, SEC_OID_ANSIX962_EC_C2PNB163V3,
- "ANSI X9.62 elliptic curve c2pnb163v3",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2pnb176v1, SEC_OID_ANSIX962_EC_C2PNB176V1,
- "ANSI X9.62 elliptic curve c2pnb176v1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2tnb191v1, SEC_OID_ANSIX962_EC_C2TNB191V1,
- "ANSI X9.62 elliptic curve c2tnb191v1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2tnb191v2, SEC_OID_ANSIX962_EC_C2TNB191V2,
- "ANSI X9.62 elliptic curve c2tnb191v2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2tnb191v3, SEC_OID_ANSIX962_EC_C2TNB191V3,
- "ANSI X9.62 elliptic curve c2tnb191v3",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2onb191v4, SEC_OID_ANSIX962_EC_C2ONB191V4,
- "ANSI X9.62 elliptic curve c2onb191v4",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2onb191v5, SEC_OID_ANSIX962_EC_C2ONB191V5,
- "ANSI X9.62 elliptic curve c2onb191v5",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2pnb208w1, SEC_OID_ANSIX962_EC_C2PNB208W1,
- "ANSI X9.62 elliptic curve c2pnb208w1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2tnb239v1, SEC_OID_ANSIX962_EC_C2TNB239V1,
- "ANSI X9.62 elliptic curve c2tnb239v1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2tnb239v2, SEC_OID_ANSIX962_EC_C2TNB239V2,
- "ANSI X9.62 elliptic curve c2tnb239v2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2tnb239v3, SEC_OID_ANSIX962_EC_C2TNB239V3,
- "ANSI X9.62 elliptic curve c2tnb239v3",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2onb239v4, SEC_OID_ANSIX962_EC_C2ONB239V4,
- "ANSI X9.62 elliptic curve c2onb239v4",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2onb239v5, SEC_OID_ANSIX962_EC_C2ONB239V5,
- "ANSI X9.62 elliptic curve c2onb239v5",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2pnb272w1, SEC_OID_ANSIX962_EC_C2PNB272W1,
- "ANSI X9.62 elliptic curve c2pnb272w1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2pnb304w1, SEC_OID_ANSIX962_EC_C2PNB304W1,
- "ANSI X9.62 elliptic curve c2pnb304w1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2tnb359v1, SEC_OID_ANSIX962_EC_C2TNB359V1,
- "ANSI X9.62 elliptic curve c2tnb359v1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2pnb368w1, SEC_OID_ANSIX962_EC_C2PNB368W1,
- "ANSI X9.62 elliptic curve c2pnb368w1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansiX962c2tnb431r1, SEC_OID_ANSIX962_EC_C2TNB431R1,
- "ANSI X9.62 elliptic curve c2tnb431r1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
-
- /* SECG named elliptic curves (characterisitic two field) */
- OD( secgECsect113r1, SEC_OID_SECG_EC_SECT113R1,
- "SECG elliptic curve sect113r1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect113r2, SEC_OID_SECG_EC_SECT113R2,
- "SECG elliptic curve sect113r2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect131r1, SEC_OID_SECG_EC_SECT131R1,
- "SECG elliptic curve sect131r1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect131r2, SEC_OID_SECG_EC_SECT131R2,
- "SECG elliptic curve sect131r2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect163k1, SEC_OID_SECG_EC_SECT163K1,
- "SECG elliptic curve sect163k1 (aka NIST K-163)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect163r1, SEC_OID_SECG_EC_SECT163R1,
- "SECG elliptic curve sect163r1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect163r2, SEC_OID_SECG_EC_SECT163R2,
- "SECG elliptic curve sect163r2 (aka NIST B-163)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect193r1, SEC_OID_SECG_EC_SECT193R1,
- "SECG elliptic curve sect193r1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect193r2, SEC_OID_SECG_EC_SECT193R2,
- "SECG elliptic curve sect193r2",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect233k1, SEC_OID_SECG_EC_SECT233K1,
- "SECG elliptic curve sect233k1 (aka NIST K-233)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect233r1, SEC_OID_SECG_EC_SECT233R1,
- "SECG elliptic curve sect233r1 (aka NIST B-233)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect239k1, SEC_OID_SECG_EC_SECT239K1,
- "SECG elliptic curve sect239k1",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect283k1, SEC_OID_SECG_EC_SECT283K1,
- "SECG elliptic curve sect283k1 (aka NIST K-283)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect283r1, SEC_OID_SECG_EC_SECT283R1,
- "SECG elliptic curve sect283r1 (aka NIST B-283)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect409k1, SEC_OID_SECG_EC_SECT409K1,
- "SECG elliptic curve sect409k1 (aka NIST K-409)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect409r1, SEC_OID_SECG_EC_SECT409R1,
- "SECG elliptic curve sect409r1 (aka NIST B-409)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect571k1, SEC_OID_SECG_EC_SECT571K1,
- "SECG elliptic curve sect571k1 (aka NIST K-571)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( secgECsect571r1, SEC_OID_SECG_EC_SECT571R1,
- "SECG elliptic curve sect571r1 (aka NIST B-571)",
- CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
-
- OD( netscapeAOLScreenname, SEC_OID_NETSCAPE_AOLSCREENNAME,
- "AOL Screenname", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
-
- OD( x520SurName, SEC_OID_AVA_SURNAME,
- "X520 Title", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520SerialNumber, SEC_OID_AVA_SERIAL_NUMBER,
- "X520 Serial Number", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520StreetAddress, SEC_OID_AVA_STREET_ADDRESS,
- "X520 Street Address", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520Title, SEC_OID_AVA_TITLE,
- "X520 Title", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520PostalAddress, SEC_OID_AVA_POSTAL_ADDRESS,
- "X520 Postal Address", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520PostalCode, SEC_OID_AVA_POSTAL_CODE,
- "X520 Postal Code", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520PostOfficeBox, SEC_OID_AVA_POST_OFFICE_BOX,
- "X520 Post Office Box", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520GivenName, SEC_OID_AVA_GIVEN_NAME,
- "X520 Given Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520Initials, SEC_OID_AVA_INITIALS,
- "X520 Initials", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520GenerationQualifier, SEC_OID_AVA_GENERATION_QUALIFIER,
- "X520 Generation Qualifier",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520HouseIdentifier, SEC_OID_AVA_HOUSE_IDENTIFIER,
- "X520 House Identifier",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520Pseudonym, SEC_OID_AVA_PSEUDONYM,
- "X520 Pseudonym", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* More OIDs */
- OD( pkixCAIssuers, SEC_OID_PKIX_CA_ISSUERS,
- "PKIX CA issuers access method",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs9ExtensionRequest, SEC_OID_PKCS9_EXTENSION_REQUEST,
- "PKCS #9 Extension Request",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* more ECC Signature Oids */
- OD( ansix962SignatureRecommended,
- SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST,
- "X9.62 ECDSA signature with recommended digest", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansix962SignatureSpecified,
- SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST,
- "X9.62 ECDSA signature with specified digest", CKM_ECDSA,
- INVALID_CERT_EXTENSION ),
- OD( ansix962SignaturewithSHA224Digest,
- SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE,
- "X9.62 ECDSA signature with SHA224", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansix962SignaturewithSHA256Digest,
- SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE,
- "X9.62 ECDSA signature with SHA256", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansix962SignaturewithSHA384Digest,
- SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE,
- "X9.62 ECDSA signature with SHA384", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( ansix962SignaturewithSHA512Digest,
- SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE,
- "X9.62 ECDSA signature with SHA512", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
-
- /* More id-ce and id-pe OIDs from RFC 3280 */
- OD( x509HoldInstructionCode, SEC_OID_X509_HOLD_INSTRUCTION_CODE,
- "CRL Hold Instruction Code", CKM_INVALID_MECHANISM,
- UNSUPPORTED_CERT_EXTENSION ),
- OD( x509DeltaCRLIndicator, SEC_OID_X509_DELTA_CRL_INDICATOR,
- "Delta CRL Indicator", CKM_INVALID_MECHANISM,
- FAKE_SUPPORTED_CERT_EXTENSION ),
- OD( x509IssuingDistributionPoint, SEC_OID_X509_ISSUING_DISTRIBUTION_POINT,
- "Issuing Distribution Point", CKM_INVALID_MECHANISM,
- FAKE_SUPPORTED_CERT_EXTENSION ),
- OD( x509CertIssuer, SEC_OID_X509_CERT_ISSUER,
- "Certificate Issuer Extension",CKM_INVALID_MECHANISM,
- FAKE_SUPPORTED_CERT_EXTENSION ),
- OD( x509FreshestCRL, SEC_OID_X509_FRESHEST_CRL,
- "Freshest CRL", CKM_INVALID_MECHANISM,
- UNSUPPORTED_CERT_EXTENSION ),
- OD( x509InhibitAnyPolicy, SEC_OID_X509_INHIBIT_ANY_POLICY,
- "Inhibit Any Policy", CKM_INVALID_MECHANISM,
- FAKE_SUPPORTED_CERT_EXTENSION ),
- OD( x509SubjectInfoAccess, SEC_OID_X509_SUBJECT_INFO_ACCESS,
- "Subject Info Access", CKM_INVALID_MECHANISM,
- UNSUPPORTED_CERT_EXTENSION ),
-
- /* Camellia algorithm OIDs */
- OD( camellia128_CBC, SEC_OID_CAMELLIA_128_CBC,
- "CAMELLIA-128-CBC", CKM_CAMELLIA_CBC, INVALID_CERT_EXTENSION ),
- OD( camellia192_CBC, SEC_OID_CAMELLIA_192_CBC,
- "CAMELLIA-192-CBC", CKM_CAMELLIA_CBC, INVALID_CERT_EXTENSION ),
- OD( camellia256_CBC, SEC_OID_CAMELLIA_256_CBC,
- "CAMELLIA-256-CBC", CKM_CAMELLIA_CBC, INVALID_CERT_EXTENSION ),
-
- /* PKCS 5 v2 OIDS */
- OD( pkcs5Pbkdf2, SEC_OID_PKCS5_PBKDF2,
- "PKCS #5 Password Based Key Dervive Function v2 ",
- CKM_PKCS5_PBKD2, INVALID_CERT_EXTENSION ),
- OD( pkcs5Pbes2, SEC_OID_PKCS5_PBES2,
- "PKCS #5 Password Based Encryption v2 ",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( pkcs5Pbmac1, SEC_OID_PKCS5_PBMAC1,
- "PKCS #5 Password Based Authentication v1 ",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( hmac_sha1, SEC_OID_HMAC_SHA1, "HMAC SHA-1",
- CKM_SHA_1_HMAC, INVALID_CERT_EXTENSION ),
- OD( hmac_sha224, SEC_OID_HMAC_SHA224, "HMAC SHA-224",
- CKM_SHA224_HMAC, INVALID_CERT_EXTENSION ),
- OD( hmac_sha256, SEC_OID_HMAC_SHA256, "HMAC SHA-256",
- CKM_SHA256_HMAC, INVALID_CERT_EXTENSION ),
- OD( hmac_sha384, SEC_OID_HMAC_SHA384, "HMAC SHA-384",
- CKM_SHA384_HMAC, INVALID_CERT_EXTENSION ),
- OD( hmac_sha512, SEC_OID_HMAC_SHA512, "HMAC SHA-512",
- CKM_SHA512_HMAC, INVALID_CERT_EXTENSION ),
-
- /* SIA extension OIDs */
- OD( x509SIATimeStamping, SEC_OID_PKIX_TIMESTAMPING,
- "SIA Time Stamping", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
- OD( x509SIACaRepository, SEC_OID_PKIX_CA_REPOSITORY,
- "SIA CA Repository", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
-
- OD( isoSHA1WithRSASignature, SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE,
- "ISO SHA-1 with RSA Signature",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- /* SEED algorithm OIDs */
- OD( seed_CBC, SEC_OID_SEED_CBC,
- "SEED-CBC", CKM_SEED_CBC, INVALID_CERT_EXTENSION),
-
- OD( x509CertificatePoliciesAnyPolicy, SEC_OID_X509_ANY_POLICY,
- "Certificate Policies AnyPolicy",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- OD( pkcs1RSAOAEPEncryption, SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION,
- "PKCS #1 RSA-OAEP Encryption", CKM_RSA_PKCS_OAEP,
- INVALID_CERT_EXTENSION ),
-
- OD( pkcs1MGF1, SEC_OID_PKCS1_MGF1,
- "PKCS #1 MGF1 Mask Generation Function", CKM_INVALID_MECHANISM,
- INVALID_CERT_EXTENSION ),
-
- OD( pkcs1PSpecified, SEC_OID_PKCS1_PSPECIFIED,
- "PKCS #1 RSA-OAEP Explicitly Specified Encoding Parameters",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- OD( pkcs1RSAPSSSignature, SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
- "PKCS #1 RSA-PSS Signature", CKM_RSA_PKCS_PSS,
- INVALID_CERT_EXTENSION ),
-
- OD( pkcs1SHA224WithRSAEncryption, SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION,
- "PKCS #1 SHA-224 With RSA Encryption", CKM_SHA224_RSA_PKCS,
- INVALID_CERT_EXTENSION ),
-
- OD( sha224, SEC_OID_SHA224, "SHA-224", CKM_SHA224, INVALID_CERT_EXTENSION),
-
- OD( evIncorporationLocality, SEC_OID_EV_INCORPORATION_LOCALITY,
- "Jurisdiction of Incorporation Locality Name",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( evIncorporationState, SEC_OID_EV_INCORPORATION_STATE,
- "Jurisdiction of Incorporation State Name",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( evIncorporationCountry, SEC_OID_EV_INCORPORATION_COUNTRY,
- "Jurisdiction of Incorporation Country Name",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
- OD( x520BusinessCategory, SEC_OID_BUSINESS_CATEGORY,
- "Business Category",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
-
- OD( nistDSASignaturewithSHA224Digest,
- SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST,
- "DSA with SHA-224 Signature",
- CKM_INVALID_MECHANISM /* not yet defined */, INVALID_CERT_EXTENSION),
- OD( nistDSASignaturewithSHA256Digest,
- SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST,
- "DSA with SHA-256 Signature",
- CKM_INVALID_MECHANISM /* not yet defined */, INVALID_CERT_EXTENSION),
- OD( msExtendedKeyUsageTrustListSigning,
- SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING,
- "Microsoft Trust List Signing",
- CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION )
-};
-
-/* PRIVATE EXTENDED SECOID Table
- * This table is private. Its structure is opaque to the outside.
- * It is indexed by the same SECOidTag as the oids table above.
- * Every member of this struct must have accessor functions (set, get)
- * and those functions must operate by value, not by reference.
- * The addresses of the contents of this table must not be exposed
- * by the accessor functions.
- */
-typedef struct privXOidStr {
- PRUint32 notPolicyFlags; /* ones complement of policy flags */
-} privXOid;
-
-static privXOid xOids[SEC_OID_TOTAL];
-
-/*
- * now the dynamic table. The dynamic table gets build at init time.
- * and conceivably gets modified if the user loads new crypto modules.
- * All this static data, and the allocated data to which it points,
- * is protected by a global reader/writer lock.
- * The c language guarantees that global and static data that is not
- * explicitly initialized will be initialized with zeros. If we
- * initialize it with zeros, the data goes into the initialized data
- * secment, and increases the size of the library. By leaving it
- * uninitialized, it is allocated in BSS, and does NOT increase the
- * library size.
- */
-
-typedef struct dynXOidStr {
- SECOidData data;
- privXOid priv;
-} dynXOid;
-
-static NSSRWLock * dynOidLock;
-static PLArenaPool * dynOidPool;
-static PLHashTable * dynOidHash;
-static dynXOid ** dynOidTable; /* not in the pool */
-static int dynOidEntriesAllocated;
-static int dynOidEntriesUsed;
-
-/* Creates NSSRWLock and dynOidPool at initialization time.
-*/
-static SECStatus
-secoid_InitDynOidData(void)
-{
- SECStatus rv = SECSuccess;
-
- dynOidLock = NSSRWLock_New(1, "dynamic OID data");
- if (!dynOidLock) {
- return SECFailure; /* Error code should already be set. */
- }
- dynOidPool = PORT_NewArena(2048);
- if (!dynOidPool) {
- rv = SECFailure /* Error code should already be set. */;
- }
- return rv;
-}
-
-/* Add oidData to hash table. Caller holds write lock dynOidLock. */
-static SECStatus
-secoid_HashDynamicOiddata(const SECOidData * oid)
-{
- PLHashEntry *entry;
-
- if (!dynOidHash) {
- dynOidHash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
- PL_CompareValues, NULL, NULL);
- if ( !dynOidHash ) {
- return SECFailure;
- }
- }
-
- entry = PL_HashTableAdd( dynOidHash, &oid->oid, (void *)oid );
- return entry ? SECSuccess : SECFailure;
-}
-
-
-/*
- * Lookup a Dynamic OID. Dynamic OID's still change slowly, so it's
- * cheaper to rehash the table when it changes than it is to do the loop
- * each time.
- */
-static SECOidData *
-secoid_FindDynamic(const SECItem *key)
-{
- SECOidData *ret = NULL;
-
- if (dynOidHash) {
- NSSRWLock_LockRead(dynOidLock);
- if (dynOidHash) { /* must check it again with lock held. */
- ret = (SECOidData *)PL_HashTableLookup(dynOidHash, key);
- }
- NSSRWLock_UnlockRead(dynOidLock);
- }
- if (ret == NULL) {
- PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
- }
- return ret;
-}
-
-static dynXOid *
-secoid_FindDynamicByTag(SECOidTag tagnum)
-{
- dynXOid *dxo = NULL;
- int tagNumDiff;
-
- if (tagnum < SEC_OID_TOTAL) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
- }
- tagNumDiff = tagnum - SEC_OID_TOTAL;
-
- if (dynOidTable) {
- NSSRWLock_LockRead(dynOidLock);
- if (dynOidTable != NULL && /* must check it again with lock held. */
- tagNumDiff < dynOidEntriesUsed) {
- dxo = dynOidTable[tagNumDiff];
- }
- NSSRWLock_UnlockRead(dynOidLock);
- }
- if (dxo == NULL) {
- PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
- }
- return dxo;
-}
-
-/*
- * This routine is thread safe now.
- */
-SECOidTag
-SECOID_AddEntry(const SECOidData * src)
-{
- SECOidData * dst;
- dynXOid **table;
- SECOidTag ret = SEC_OID_UNKNOWN;
- SECStatus rv;
- int tableEntries;
- int used;
-
- if (!src || !src->oid.data || !src->oid.len || \
- !src->desc || !strlen(src->desc)) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return ret;
- }
- if (src->supportedExtension != INVALID_CERT_EXTENSION &&
- src->supportedExtension != UNSUPPORTED_CERT_EXTENSION &&
- src->supportedExtension != SUPPORTED_CERT_EXTENSION ) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return ret;
- }
-
- if (!dynOidPool || !dynOidLock) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return ret;
- }
-
- NSSRWLock_LockWrite(dynOidLock);
-
- /* We've just acquired the write lock, and now we call FindOIDTag
- ** which will acquire and release the read lock. NSSRWLock has been
- ** designed to allow this very case without deadlock. This approach
- ** makes the test for the presence of the OID, and the subsequent
- ** addition of the OID to the table a single atomic write operation.
- */
- ret = SECOID_FindOIDTag(&src->oid);
- if (ret != SEC_OID_UNKNOWN) {
- /* we could return an error here, but I chose not to do that.
- ** This way, if we add an OID to the shared library's built in
- ** list of OIDs in some future release, and that OID is the same
- ** as some OID that a program has been adding, the program will
- ** not suddenly stop working.
- */
- goto done;
- }
-
- table = dynOidTable;
- tableEntries = dynOidEntriesAllocated;
- used = dynOidEntriesUsed;
-
- if (used + 1 > tableEntries) {
- dynXOid ** newTable;
- int newTableEntries = tableEntries + 16;
-
- newTable = (dynXOid **)PORT_Realloc(table,
- newTableEntries * sizeof(dynXOid *));
- if (newTable == NULL) {
- goto done;
- }
- dynOidTable = table = newTable;
- dynOidEntriesAllocated = tableEntries = newTableEntries;
- }
-
- /* copy oid structure */
- dst = (SECOidData *)PORT_ArenaZNew(dynOidPool, dynXOid);
- if (!dst) {
- goto done;
- }
- rv = SECITEM_CopyItem(dynOidPool, &dst->oid, &src->oid);
- if (rv != SECSuccess) {
- goto done;
- }
- dst->desc = PORT_ArenaStrdup(dynOidPool, src->desc);
- if (!dst->desc) {
- goto done;
- }
- dst->offset = (SECOidTag)(used + SEC_OID_TOTAL);
- dst->mechanism = src->mechanism;
- dst->supportedExtension = src->supportedExtension;
-
- rv = secoid_HashDynamicOiddata(dst);
- if (rv == SECSuccess) {
- table[used++] = (dynXOid *)dst;
- dynOidEntriesUsed = used;
- ret = dst->offset;
- }
-done:
- NSSRWLock_UnlockWrite(dynOidLock);
- return ret;
-}
-
-
-/* normal static table processing */
-static PLHashTable *oidhash = NULL;
-static PLHashTable *oidmechhash = NULL;
-
-static PLHashNumber
-secoid_HashNumber(const void *key)
-{
- return (PLHashNumber) key;
-}
-
-static void
-handleHashAlgSupport(char * envVal)
-{
- char * myVal = PORT_Strdup(envVal); /* Get a copy we can alter */
- char * arg = myVal;
-
- while (arg && *arg) {
- char * nextArg = PL_strpbrk(arg, ";");
- PRUint32 notEnable;
-
- if (nextArg) {
- while (*nextArg == ';') {
- *nextArg++ = '\0';
- }
- }
- notEnable = (*arg == '-') ? NSS_USE_ALG_IN_CERT_SIGNATURE : 0;
- if ((*arg == '+' || *arg == '-') && *++arg) {
- int i;
-
- for (i = 1; i < SEC_OID_TOTAL; i++) {
- if (oids[i].desc && strstr(arg, oids[i].desc)) {
- xOids[i].notPolicyFlags = notEnable |
- (xOids[i].notPolicyFlags & ~NSS_USE_ALG_IN_CERT_SIGNATURE);
- }
- }
- }
- arg = nextArg;
- }
- PORT_Free(myVal); /* can handle NULL argument OK */
-}
-
-SECStatus
-SECOID_Init(void)
-{
- PLHashEntry *entry;
- const SECOidData *oid;
- int i;
- char * envVal;
- volatile char c; /* force a reference that won't get optimized away */
-
- c = __nss_util_rcsid[0] + __nss_util_sccsid[0];
-
- if (oidhash) {
- return SECSuccess; /* already initialized */
- }
-
- if (!PR_GetEnv("NSS_ALLOW_WEAK_SIGNATURE_ALG")) {
- /* initialize any policy flags that are disabled by default */
- xOids[SEC_OID_MD2 ].notPolicyFlags = ~0;
- xOids[SEC_OID_MD4 ].notPolicyFlags = ~0;
- xOids[SEC_OID_MD5 ].notPolicyFlags = ~0;
- xOids[SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION ].notPolicyFlags = ~0;
- xOids[SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION ].notPolicyFlags = ~0;
- xOids[SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION ].notPolicyFlags = ~0;
- xOids[SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC].notPolicyFlags = ~0;
- xOids[SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC].notPolicyFlags = ~0;
- }
-
- envVal = PR_GetEnv("NSS_HASH_ALG_SUPPORT");
- if (envVal)
- handleHashAlgSupport(envVal);
-
- if (secoid_InitDynOidData() != SECSuccess) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- PORT_Assert(0); /* this function should never fail */
- return SECFailure;
- }
-
- oidhash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
- PL_CompareValues, NULL, NULL);
- oidmechhash = PL_NewHashTable(0, secoid_HashNumber, PL_CompareValues,
- PL_CompareValues, NULL, NULL);
-
- if ( !oidhash || !oidmechhash) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- PORT_Assert(0); /*This function should never fail. */
- return(SECFailure);
- }
-
- for ( i = 0; i < SEC_OID_TOTAL; i++ ) {
- oid = &oids[i];
-
- PORT_Assert ( oid->offset == i );
-
- entry = PL_HashTableAdd( oidhash, &oid->oid, (void *)oid );
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- PORT_Assert(0); /*This function should never fail. */
- return(SECFailure);
- }
-
- if ( oid->mechanism != CKM_INVALID_MECHANISM ) {
- entry = PL_HashTableAdd( oidmechhash,
- (void *)oid->mechanism, (void *)oid );
- if ( entry == NULL ) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- PORT_Assert(0); /* This function should never fail. */
- return(SECFailure);
- }
- }
- }
-
- PORT_Assert (i == SEC_OID_TOTAL);
-
- return(SECSuccess);
-}
-
-SECOidData *
-SECOID_FindOIDByMechanism(unsigned long mechanism)
-{
- SECOidData *ret;
-
- PR_ASSERT(oidhash != NULL);
-
- ret = PL_HashTableLookupConst ( oidmechhash, (void *)mechanism);
- if ( ret == NULL ) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- }
-
- return (ret);
-}
-
-SECOidData *
-SECOID_FindOID(const SECItem *oid)
-{
- SECOidData *ret;
-
- PR_ASSERT(oidhash != NULL);
-
- ret = PL_HashTableLookupConst ( oidhash, oid );
- if ( ret == NULL ) {
- ret = secoid_FindDynamic(oid);
- if (ret == NULL) {
- PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
- }
- }
-
- return(ret);
-}
-
-SECOidTag
-SECOID_FindOIDTag(const SECItem *oid)
-{
- SECOidData *oiddata;
-
- oiddata = SECOID_FindOID (oid);
- if (oiddata == NULL)
- return SEC_OID_UNKNOWN;
-
- return oiddata->offset;
-}
-
-/* This really should return const. */
-SECOidData *
-SECOID_FindOIDByTag(SECOidTag tagnum)
-{
- if (tagnum >= SEC_OID_TOTAL) {
- return (SECOidData *)secoid_FindDynamicByTag(tagnum);
- }
-
- PORT_Assert((unsigned int)tagnum < SEC_OID_TOTAL);
- return (SECOidData *)(&oids[tagnum]);
-}
-
-PRBool SECOID_KnownCertExtenOID (SECItem *extenOid)
-{
- SECOidData * oidData;
-
- oidData = SECOID_FindOID (extenOid);
- if (oidData == (SECOidData *)NULL)
- return (PR_FALSE);
- return ((oidData->supportedExtension == SUPPORTED_CERT_EXTENSION) ?
- PR_TRUE : PR_FALSE);
-}
-
-
-const char *
-SECOID_FindOIDTagDescription(SECOidTag tagnum)
-{
- const SECOidData *oidData = SECOID_FindOIDByTag(tagnum);
- return oidData ? oidData->desc : 0;
-}
-
-/* --------- opaque extended OID table accessor functions ---------------*/
-/*
- * Any of these functions may return SECSuccess or SECFailure with the error
- * code set to SEC_ERROR_UNKNOWN_OBJECT_TYPE if the SECOidTag is out of range.
- */
-
-static privXOid *
-secoid_FindXOidByTag(SECOidTag tagnum)
-{
- if (tagnum >= SEC_OID_TOTAL) {
- dynXOid *dxo = secoid_FindDynamicByTag(tagnum);
- return (dxo ? &dxo->priv : NULL);
- }
-
- PORT_Assert((unsigned int)tagnum < SEC_OID_TOTAL);
- return &xOids[tagnum];
-}
-
-/* The Get function outputs the 32-bit value associated with the SECOidTag.
- * Flags bits are the NSS_USE_ALG_ #defines in "secoidt.h".
- * Default value for any algorithm is 0xffffffff (enabled for all purposes).
- * No value is output if function returns SECFailure.
- */
-SECStatus
-NSS_GetAlgorithmPolicy(SECOidTag tag, PRUint32 *pValue)
-{
- privXOid * pxo = secoid_FindXOidByTag(tag);
- if (!pxo)
- return SECFailure;
- if (!pValue) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
- *pValue = ~(pxo->notPolicyFlags);
- return SECSuccess;
-}
-
-/* The Set function modifies the stored value according to the following
- * algorithm:
- * policy[tag] = (policy[tag] & ~clearBits) | setBits;
- */
-SECStatus
-NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits)
-{
- privXOid * pxo = secoid_FindXOidByTag(tag);
- PRUint32 policyFlags;
- if (!pxo)
- return SECFailure;
- /* The stored policy flags are the ones complement of the flags as
- * seen by the user. This is not atomic, but these changes should
- * be done rarely, e.g. at initialization time.
- */
- policyFlags = ~(pxo->notPolicyFlags);
- policyFlags = (policyFlags & ~clearBits) | setBits;
- pxo->notPolicyFlags = ~policyFlags;
- return SECSuccess;
-}
-
-/* --------- END OF opaque extended OID table accessor functions ---------*/
-
-/* for now, this is only used in a single place, so it can remain static */
-static PRBool parentForkedAfterC_Initialize;
-
-#define SKIP_AFTER_FORK(x) if (!parentForkedAfterC_Initialize) x
-
-/*
- * free up the oid tables.
- */
-SECStatus
-SECOID_Shutdown(void)
-{
- if (oidhash) {
- PL_HashTableDestroy(oidhash);
- oidhash = NULL;
- }
- if (oidmechhash) {
- PL_HashTableDestroy(oidmechhash);
- oidmechhash = NULL;
- }
- /* Have to handle the case where the lock was created, but
- ** the pool wasn't.
- ** I'm not going to attempt to create the lock, just to protect
- ** the destruction of data that probably isn't initialized anyway.
- */
- if (dynOidLock) {
- SKIP_AFTER_FORK(NSSRWLock_LockWrite(dynOidLock));
- if (dynOidHash) {
- PL_HashTableDestroy(dynOidHash);
- dynOidHash = NULL;
- }
- if (dynOidPool) {
- PORT_FreeArena(dynOidPool, PR_FALSE);
- dynOidPool = NULL;
- }
- if (dynOidTable) {
- PORT_Free(dynOidTable);
- dynOidTable = NULL;
- }
- dynOidEntriesAllocated = 0;
- dynOidEntriesUsed = 0;
-
- SKIP_AFTER_FORK(NSSRWLock_UnlockWrite(dynOidLock));
- SKIP_AFTER_FORK(NSSRWLock_Destroy(dynOidLock));
- dynOidLock = NULL;
- } else {
- /* Since dynOidLock doesn't exist, then all the data it protects
- ** should be uninitialized. We'll check that (in DEBUG builds),
- ** and then make sure it is so, in case NSS is reinitialized.
- */
- PORT_Assert(!dynOidHash && !dynOidPool && !dynOidTable && \
- !dynOidEntriesAllocated && !dynOidEntriesUsed);
- dynOidHash = NULL;
- dynOidPool = NULL;
- dynOidTable = NULL;
- dynOidEntriesAllocated = 0;
- dynOidEntriesUsed = 0;
- }
- memset(xOids, 0, sizeof xOids);
- return SECSuccess;
-}
-
-void UTIL_SetForkState(PRBool forked)
-{
- parentForkedAfterC_Initialize = forked;
-}
-
-const char *
-NSSUTIL_GetVersion(void)
-{
- return NSSUTIL_VERSION;
-}
diff --git a/security/nss/lib/util/secoid.h b/security/nss/lib/util/secoid.h
deleted file mode 100644
index 69e47a7db..000000000
--- a/security/nss/lib/util/secoid.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SECOID_H_
-#define _SECOID_H_
-
-#include "utilrename.h"
-
-/*
- * secoid.h - public data structures and prototypes for ASN.1 OID functions
- *
- * $Id$
- */
-
-#include "plarena.h"
-
-#include "seccomon.h"
-#include "secoidt.h"
-#include "secasn1t.h"
-
-SEC_BEGIN_PROTOS
-
-extern const SEC_ASN1Template SECOID_AlgorithmIDTemplate[];
-
-/* This functions simply returns the address of the above-declared template. */
-SEC_ASN1_CHOOSER_DECLARE(SECOID_AlgorithmIDTemplate)
-
-/*
- * OID handling routines
- */
-extern SECOidData *SECOID_FindOID( const SECItem *oid);
-extern SECOidTag SECOID_FindOIDTag(const SECItem *oid);
-extern SECOidData *SECOID_FindOIDByTag(SECOidTag tagnum);
-extern SECOidData *SECOID_FindOIDByMechanism(unsigned long mechanism);
-
-/****************************************/
-/*
-** Algorithm id handling operations
-*/
-
-/*
-** Fill in an algorithm-ID object given a tag and some parameters.
-** "aid" where the DER encoded algorithm info is stored (memory
-** is allocated)
-** "tag" the tag number defining the algorithm
-** "params" if not NULL, the parameters to go with the algorithm
-*/
-extern SECStatus SECOID_SetAlgorithmID(PLArenaPool *arena, SECAlgorithmID *aid,
- SECOidTag tag, SECItem *params);
-
-/*
-** Copy the "src" object to "dest". Memory is allocated in "dest" for
-** each of the appropriate sub-objects. Memory in "dest" is not freed
-** before memory is allocated (use SECOID_DestroyAlgorithmID(dest, PR_FALSE)
-** to do that).
-*/
-extern SECStatus SECOID_CopyAlgorithmID(PLArenaPool *arena, SECAlgorithmID *dest,
- SECAlgorithmID *src);
-
-/*
-** Get the tag number for the given algorithm-id object.
-*/
-extern SECOidTag SECOID_GetAlgorithmTag(SECAlgorithmID *aid);
-
-/*
-** Destroy an algorithm-id object.
-** "aid" the certificate-request to destroy
-** "freeit" if PR_TRUE then free the object as well as its sub-objects
-*/
-extern void SECOID_DestroyAlgorithmID(SECAlgorithmID *aid, PRBool freeit);
-
-/*
-** Compare two algorithm-id objects, returning the difference between
-** them.
-*/
-extern SECComparison SECOID_CompareAlgorithmID(SECAlgorithmID *a,
- SECAlgorithmID *b);
-
-extern PRBool SECOID_KnownCertExtenOID (SECItem *extenOid);
-
-/* Given a tag number, return a string describing it.
- */
-extern const char *SECOID_FindOIDTagDescription(SECOidTag tagnum);
-
-/* Add a dynamic SECOidData to the dynamic OID table.
-** Routine copies the src entry, and returns the new SECOidTag.
-** Returns SEC_OID_INVALID if failed to add for some reason.
-*/
-extern SECOidTag SECOID_AddEntry(const SECOidData * src);
-
-/*
- * initialize the oid data structures.
- */
-extern SECStatus SECOID_Init(void);
-
-/*
- * free up the oid data structures.
- */
-extern SECStatus SECOID_Shutdown(void);
-
-/* if to->data is not NULL, and to->len is large enough to hold the result,
- * then the resultant OID will be copyed into to->data, and to->len will be
- * changed to show the actual OID length.
- * Otherwise, memory for the OID will be allocated (from the caller's
- * PLArenaPool, if pool is non-NULL) and to->data will receive the address
- * of the allocated data, and to->len will receive the OID length.
- * The original value of to->data is not freed when a new buffer is allocated.
- *
- * The input string may begin with "OID." and this still be ignored.
- * The length of the input string is given in len. If len == 0, then
- * len will be computed as strlen(from), meaning it must be NUL terminated.
- * It is an error if from == NULL, or if *from == '\0'.
- */
-extern SECStatus SEC_StringToOID(PLArenaPool *pool, SECItem *to,
- const char *from, PRUint32 len);
-
-extern void UTIL_SetForkState(PRBool forked);
-
-/*
- * Accessor functions for new opaque extended SECOID table.
- * Any of these functions may return SECSuccess or SECFailure with the error
- * code set to SEC_ERROR_UNKNOWN_OBJECT_TYPE if the SECOidTag is out of range.
- */
-
-/* The Get function outputs the 32-bit value associated with the SECOidTag.
- * Flags bits are the NSS_USE_ALG_ #defines in "secoidt.h".
- * Default value for any algorithm is 0xffffffff (enabled for all purposes).
- * No value is output if function returns SECFailure.
- */
-extern SECStatus NSS_GetAlgorithmPolicy(SECOidTag tag, PRUint32 *pValue);
-
-/* The Set function modifies the stored value according to the following
- * algorithm:
- * policy[tag] = (policy[tag] & ~clearBits) | setBits;
- */
-extern SECStatus
-NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits);
-
-
-SEC_END_PROTOS
-
-#endif /* _SECOID_H_ */
diff --git a/security/nss/lib/util/secoidt.h b/security/nss/lib/util/secoidt.h
deleted file mode 100644
index 3f3b563df..000000000
--- a/security/nss/lib/util/secoidt.h
+++ /dev/null
@@ -1,486 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _SECOIDT_H_
-#define _SECOIDT_H_
-
-#include "utilrename.h"
-
-/*
- * secoidt.h - public data structures for ASN.1 OID functions
- *
- * $Id$
- */
-
-#include "secitem.h"
-
-typedef struct SECOidDataStr SECOidData;
-typedef struct SECAlgorithmIDStr SECAlgorithmID;
-
-/*
-** An X.500 algorithm identifier
-*/
-struct SECAlgorithmIDStr {
- SECItem algorithm;
- SECItem parameters;
-};
-
-/*
- * Misc object IDs - these numbers are for convenient handling.
- * They are mapped into real object IDs
- *
- * NOTE: the order of these entries must mach the array "oids" of SECOidData
- * in util/secoid.c.
- */
-typedef enum {
- SEC_OID_UNKNOWN = 0,
- SEC_OID_MD2 = 1,
- SEC_OID_MD4 = 2,
- SEC_OID_MD5 = 3,
- SEC_OID_SHA1 = 4,
- SEC_OID_RC2_CBC = 5,
- SEC_OID_RC4 = 6,
- SEC_OID_DES_EDE3_CBC = 7,
- SEC_OID_RC5_CBC_PAD = 8,
- SEC_OID_DES_ECB = 9,
- SEC_OID_DES_CBC = 10,
- SEC_OID_DES_OFB = 11,
- SEC_OID_DES_CFB = 12,
- SEC_OID_DES_MAC = 13,
- SEC_OID_DES_EDE = 14,
- SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE = 15,
- SEC_OID_PKCS1_RSA_ENCRYPTION = 16,
- SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION = 17,
- SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION = 18,
- SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION = 19,
- SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION = 20,
- SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC = 21,
- SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC = 22,
- SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC = 23,
- SEC_OID_PKCS7 = 24,
- SEC_OID_PKCS7_DATA = 25,
- SEC_OID_PKCS7_SIGNED_DATA = 26,
- SEC_OID_PKCS7_ENVELOPED_DATA = 27,
- SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA = 28,
- SEC_OID_PKCS7_DIGESTED_DATA = 29,
- SEC_OID_PKCS7_ENCRYPTED_DATA = 30,
- SEC_OID_PKCS9_EMAIL_ADDRESS = 31,
- SEC_OID_PKCS9_UNSTRUCTURED_NAME = 32,
- SEC_OID_PKCS9_CONTENT_TYPE = 33,
- SEC_OID_PKCS9_MESSAGE_DIGEST = 34,
- SEC_OID_PKCS9_SIGNING_TIME = 35,
- SEC_OID_PKCS9_COUNTER_SIGNATURE = 36,
- SEC_OID_PKCS9_CHALLENGE_PASSWORD = 37,
- SEC_OID_PKCS9_UNSTRUCTURED_ADDRESS = 38,
- SEC_OID_PKCS9_EXTENDED_CERTIFICATE_ATTRIBUTES = 39,
- SEC_OID_PKCS9_SMIME_CAPABILITIES = 40,
- SEC_OID_AVA_COMMON_NAME = 41,
- SEC_OID_AVA_COUNTRY_NAME = 42,
- SEC_OID_AVA_LOCALITY = 43,
- SEC_OID_AVA_STATE_OR_PROVINCE = 44,
- SEC_OID_AVA_ORGANIZATION_NAME = 45,
- SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME = 46,
- SEC_OID_AVA_DN_QUALIFIER = 47,
- SEC_OID_AVA_DC = 48,
-
- SEC_OID_NS_TYPE_GIF = 49,
- SEC_OID_NS_TYPE_JPEG = 50,
- SEC_OID_NS_TYPE_URL = 51,
- SEC_OID_NS_TYPE_HTML = 52,
- SEC_OID_NS_TYPE_CERT_SEQUENCE = 53,
- SEC_OID_MISSI_KEA_DSS_OLD = 54,
- SEC_OID_MISSI_DSS_OLD = 55,
- SEC_OID_MISSI_KEA_DSS = 56,
- SEC_OID_MISSI_DSS = 57,
- SEC_OID_MISSI_KEA = 58,
- SEC_OID_MISSI_ALT_KEA = 59,
-
- /* Netscape private certificate extensions */
- SEC_OID_NS_CERT_EXT_NETSCAPE_OK = 60,
- SEC_OID_NS_CERT_EXT_ISSUER_LOGO = 61,
- SEC_OID_NS_CERT_EXT_SUBJECT_LOGO = 62,
- SEC_OID_NS_CERT_EXT_CERT_TYPE = 63,
- SEC_OID_NS_CERT_EXT_BASE_URL = 64,
- SEC_OID_NS_CERT_EXT_REVOCATION_URL = 65,
- SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL = 66,
- SEC_OID_NS_CERT_EXT_CA_CRL_URL = 67,
- SEC_OID_NS_CERT_EXT_CA_CERT_URL = 68,
- SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL = 69,
- SEC_OID_NS_CERT_EXT_CA_POLICY_URL = 70,
- SEC_OID_NS_CERT_EXT_HOMEPAGE_URL = 71,
- SEC_OID_NS_CERT_EXT_ENTITY_LOGO = 72,
- SEC_OID_NS_CERT_EXT_USER_PICTURE = 73,
- SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME = 74,
- SEC_OID_NS_CERT_EXT_COMMENT = 75,
- SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL = 76,
- SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME = 77,
- SEC_OID_NS_KEY_USAGE_GOVT_APPROVED = 78,
-
- /* x.509 v3 Extensions */
- SEC_OID_X509_SUBJECT_DIRECTORY_ATTR = 79,
- SEC_OID_X509_SUBJECT_KEY_ID = 80,
- SEC_OID_X509_KEY_USAGE = 81,
- SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD = 82,
- SEC_OID_X509_SUBJECT_ALT_NAME = 83,
- SEC_OID_X509_ISSUER_ALT_NAME = 84,
- SEC_OID_X509_BASIC_CONSTRAINTS = 85,
- SEC_OID_X509_NAME_CONSTRAINTS = 86,
- SEC_OID_X509_CRL_DIST_POINTS = 87,
- SEC_OID_X509_CERTIFICATE_POLICIES = 88,
- SEC_OID_X509_POLICY_MAPPINGS = 89,
- SEC_OID_X509_POLICY_CONSTRAINTS = 90,
- SEC_OID_X509_AUTH_KEY_ID = 91,
- SEC_OID_X509_EXT_KEY_USAGE = 92,
- SEC_OID_X509_AUTH_INFO_ACCESS = 93,
-
- SEC_OID_X509_CRL_NUMBER = 94,
- SEC_OID_X509_REASON_CODE = 95,
- SEC_OID_X509_INVALID_DATE = 96,
- /* End of x.509 v3 Extensions */
-
- SEC_OID_X500_RSA_ENCRYPTION = 97,
-
- /* alg 1485 additions */
- SEC_OID_RFC1274_UID = 98,
- SEC_OID_RFC1274_MAIL = 99,
-
- /* PKCS 12 additions */
- SEC_OID_PKCS12 = 100,
- SEC_OID_PKCS12_MODE_IDS = 101,
- SEC_OID_PKCS12_ESPVK_IDS = 102,
- SEC_OID_PKCS12_BAG_IDS = 103,
- SEC_OID_PKCS12_CERT_BAG_IDS = 104,
- SEC_OID_PKCS12_OIDS = 105,
- SEC_OID_PKCS12_PBE_IDS = 106,
- SEC_OID_PKCS12_SIGNATURE_IDS = 107,
- SEC_OID_PKCS12_ENVELOPING_IDS = 108,
- /* SEC_OID_PKCS12_OFFLINE_TRANSPORT_MODE,
- SEC_OID_PKCS12_ONLINE_TRANSPORT_MODE, */
- SEC_OID_PKCS12_PKCS8_KEY_SHROUDING = 109,
- SEC_OID_PKCS12_KEY_BAG_ID = 110,
- SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID = 111,
- SEC_OID_PKCS12_SECRET_BAG_ID = 112,
- SEC_OID_PKCS12_X509_CERT_CRL_BAG = 113,
- SEC_OID_PKCS12_SDSI_CERT_BAG = 114,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4 = 115,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4 = 116,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC = 117,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC = 118,
- SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC = 119,
- SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_128_BIT_RC4 = 120,
- SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_40_BIT_RC4 = 121,
- SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_TRIPLE_DES = 122,
- SEC_OID_PKCS12_RSA_SIGNATURE_WITH_SHA1_DIGEST = 123,
- /* end of PKCS 12 additions */
-
- /* DSA signatures */
- SEC_OID_ANSIX9_DSA_SIGNATURE = 124,
- SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST = 125,
- SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST = 126,
-
- /* Verisign OIDs */
- SEC_OID_VERISIGN_USER_NOTICES = 127,
-
- /* PKIX OIDs */
- SEC_OID_PKIX_CPS_POINTER_QUALIFIER = 128,
- SEC_OID_PKIX_USER_NOTICE_QUALIFIER = 129,
- SEC_OID_PKIX_OCSP = 130,
- SEC_OID_PKIX_OCSP_BASIC_RESPONSE = 131,
- SEC_OID_PKIX_OCSP_NONCE = 132,
- SEC_OID_PKIX_OCSP_CRL = 133,
- SEC_OID_PKIX_OCSP_RESPONSE = 134,
- SEC_OID_PKIX_OCSP_NO_CHECK = 135,
- SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF = 136,
- SEC_OID_PKIX_OCSP_SERVICE_LOCATOR = 137,
- SEC_OID_PKIX_REGCTRL_REGTOKEN = 138,
- SEC_OID_PKIX_REGCTRL_AUTHENTICATOR = 139,
- SEC_OID_PKIX_REGCTRL_PKIPUBINFO = 140,
- SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS = 141,
- SEC_OID_PKIX_REGCTRL_OLD_CERT_ID = 142,
- SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY = 143,
- SEC_OID_PKIX_REGINFO_UTF8_PAIRS = 144,
- SEC_OID_PKIX_REGINFO_CERT_REQUEST = 145,
- SEC_OID_EXT_KEY_USAGE_SERVER_AUTH = 146,
- SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH = 147,
- SEC_OID_EXT_KEY_USAGE_CODE_SIGN = 148,
- SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT = 149,
- SEC_OID_EXT_KEY_USAGE_TIME_STAMP = 150,
- SEC_OID_OCSP_RESPONDER = 151,
-
- /* Netscape Algorithm OIDs */
- SEC_OID_NETSCAPE_SMIME_KEA = 152,
-
- /* Skipjack OID -- ### mwelch temporary */
- SEC_OID_FORTEZZA_SKIPJACK = 153,
-
- /* PKCS 12 V2 oids */
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4 = 154,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4 = 155,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC = 156,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC = 157,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC = 158,
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC = 159,
- SEC_OID_PKCS12_SAFE_CONTENTS_ID = 160,
- SEC_OID_PKCS12_PKCS8_SHROUDED_KEY_BAG_ID = 161,
-
- SEC_OID_PKCS12_V1_KEY_BAG_ID = 162,
- SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID = 163,
- SEC_OID_PKCS12_V1_CERT_BAG_ID = 164,
- SEC_OID_PKCS12_V1_CRL_BAG_ID = 165,
- SEC_OID_PKCS12_V1_SECRET_BAG_ID = 166,
- SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID = 167,
- SEC_OID_PKCS9_X509_CERT = 168,
- SEC_OID_PKCS9_SDSI_CERT = 169,
- SEC_OID_PKCS9_X509_CRL = 170,
- SEC_OID_PKCS9_FRIENDLY_NAME = 171,
- SEC_OID_PKCS9_LOCAL_KEY_ID = 172,
- SEC_OID_BOGUS_KEY_USAGE = 173,
-
- /*Diffe Helman OIDS */
- SEC_OID_X942_DIFFIE_HELMAN_KEY = 174,
-
- /* Netscape other name types */
- /* SEC_OID_NETSCAPE_NICKNAME is an otherName field of type IA5String
- * in the subjectAltName certificate extension. NSS dropped support
- * for SEC_OID_NETSCAPE_NICKNAME in NSS 3.13. */
- SEC_OID_NETSCAPE_NICKNAME = 175,
-
- /* Cert Server OIDS */
- SEC_OID_NETSCAPE_RECOVERY_REQUEST = 176,
-
- /* New PSM certificate management OIDs */
- SEC_OID_CERT_RENEWAL_LOCATOR = 177,
- SEC_OID_NS_CERT_EXT_SCOPE_OF_USE = 178,
-
- /* CMS (RFC2630) OIDs */
- SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN = 179,
- SEC_OID_CMS_3DES_KEY_WRAP = 180,
- SEC_OID_CMS_RC2_KEY_WRAP = 181,
-
- /* SMIME attributes */
- SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE = 182,
-
- /* AES OIDs */
- SEC_OID_AES_128_ECB = 183,
- SEC_OID_AES_128_CBC = 184,
- SEC_OID_AES_192_ECB = 185,
- SEC_OID_AES_192_CBC = 186,
- SEC_OID_AES_256_ECB = 187,
- SEC_OID_AES_256_CBC = 188,
-
- SEC_OID_SDN702_DSA_SIGNATURE = 189,
-
- SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE = 190,
-
- SEC_OID_SHA256 = 191,
- SEC_OID_SHA384 = 192,
- SEC_OID_SHA512 = 193,
-
- SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION = 194,
- SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION = 195,
- SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION = 196,
-
- SEC_OID_AES_128_KEY_WRAP = 197,
- SEC_OID_AES_192_KEY_WRAP = 198,
- SEC_OID_AES_256_KEY_WRAP = 199,
-
- /* Elliptic Curve Cryptography (ECC) OIDs */
- SEC_OID_ANSIX962_EC_PUBLIC_KEY = 200,
- SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE = 201,
-
-#define SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST \
- SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE
-
- /* ANSI X9.62 named elliptic curves (prime field) */
- SEC_OID_ANSIX962_EC_PRIME192V1 = 202,
- SEC_OID_ANSIX962_EC_PRIME192V2 = 203,
- SEC_OID_ANSIX962_EC_PRIME192V3 = 204,
- SEC_OID_ANSIX962_EC_PRIME239V1 = 205,
- SEC_OID_ANSIX962_EC_PRIME239V2 = 206,
- SEC_OID_ANSIX962_EC_PRIME239V3 = 207,
- SEC_OID_ANSIX962_EC_PRIME256V1 = 208,
-
- /* SECG named elliptic curves (prime field) */
- SEC_OID_SECG_EC_SECP112R1 = 209,
- SEC_OID_SECG_EC_SECP112R2 = 210,
- SEC_OID_SECG_EC_SECP128R1 = 211,
- SEC_OID_SECG_EC_SECP128R2 = 212,
- SEC_OID_SECG_EC_SECP160K1 = 213,
- SEC_OID_SECG_EC_SECP160R1 = 214,
- SEC_OID_SECG_EC_SECP160R2 = 215,
- SEC_OID_SECG_EC_SECP192K1 = 216,
- /* SEC_OID_SECG_EC_SECP192R1 is SEC_OID_ANSIX962_EC_PRIME192V1 */
- SEC_OID_SECG_EC_SECP224K1 = 217,
- SEC_OID_SECG_EC_SECP224R1 = 218,
- SEC_OID_SECG_EC_SECP256K1 = 219,
- /* SEC_OID_SECG_EC_SECP256R1 is SEC_OID_ANSIX962_EC_PRIME256V1 */
- SEC_OID_SECG_EC_SECP384R1 = 220,
- SEC_OID_SECG_EC_SECP521R1 = 221,
-
- /* ANSI X9.62 named elliptic curves (characteristic two field) */
- SEC_OID_ANSIX962_EC_C2PNB163V1 = 222,
- SEC_OID_ANSIX962_EC_C2PNB163V2 = 223,
- SEC_OID_ANSIX962_EC_C2PNB163V3 = 224,
- SEC_OID_ANSIX962_EC_C2PNB176V1 = 225,
- SEC_OID_ANSIX962_EC_C2TNB191V1 = 226,
- SEC_OID_ANSIX962_EC_C2TNB191V2 = 227,
- SEC_OID_ANSIX962_EC_C2TNB191V3 = 228,
- SEC_OID_ANSIX962_EC_C2ONB191V4 = 229,
- SEC_OID_ANSIX962_EC_C2ONB191V5 = 230,
- SEC_OID_ANSIX962_EC_C2PNB208W1 = 231,
- SEC_OID_ANSIX962_EC_C2TNB239V1 = 232,
- SEC_OID_ANSIX962_EC_C2TNB239V2 = 233,
- SEC_OID_ANSIX962_EC_C2TNB239V3 = 234,
- SEC_OID_ANSIX962_EC_C2ONB239V4 = 235,
- SEC_OID_ANSIX962_EC_C2ONB239V5 = 236,
- SEC_OID_ANSIX962_EC_C2PNB272W1 = 237,
- SEC_OID_ANSIX962_EC_C2PNB304W1 = 238,
- SEC_OID_ANSIX962_EC_C2TNB359V1 = 239,
- SEC_OID_ANSIX962_EC_C2PNB368W1 = 240,
- SEC_OID_ANSIX962_EC_C2TNB431R1 = 241,
-
- /* SECG named elliptic curves (characteristic two field) */
- SEC_OID_SECG_EC_SECT113R1 = 242,
- SEC_OID_SECG_EC_SECT113R2 = 243,
- SEC_OID_SECG_EC_SECT131R1 = 244,
- SEC_OID_SECG_EC_SECT131R2 = 245,
- SEC_OID_SECG_EC_SECT163K1 = 246,
- SEC_OID_SECG_EC_SECT163R1 = 247,
- SEC_OID_SECG_EC_SECT163R2 = 248,
- SEC_OID_SECG_EC_SECT193R1 = 249,
- SEC_OID_SECG_EC_SECT193R2 = 250,
- SEC_OID_SECG_EC_SECT233K1 = 251,
- SEC_OID_SECG_EC_SECT233R1 = 252,
- SEC_OID_SECG_EC_SECT239K1 = 253,
- SEC_OID_SECG_EC_SECT283K1 = 254,
- SEC_OID_SECG_EC_SECT283R1 = 255,
- SEC_OID_SECG_EC_SECT409K1 = 256,
- SEC_OID_SECG_EC_SECT409R1 = 257,
- SEC_OID_SECG_EC_SECT571K1 = 258,
- SEC_OID_SECG_EC_SECT571R1 = 259,
-
- SEC_OID_NETSCAPE_AOLSCREENNAME = 260,
-
- SEC_OID_AVA_SURNAME = 261,
- SEC_OID_AVA_SERIAL_NUMBER = 262,
- SEC_OID_AVA_STREET_ADDRESS = 263,
- SEC_OID_AVA_TITLE = 264,
- SEC_OID_AVA_POSTAL_ADDRESS = 265,
- SEC_OID_AVA_POSTAL_CODE = 266,
- SEC_OID_AVA_POST_OFFICE_BOX = 267,
- SEC_OID_AVA_GIVEN_NAME = 268,
- SEC_OID_AVA_INITIALS = 269,
- SEC_OID_AVA_GENERATION_QUALIFIER = 270,
- SEC_OID_AVA_HOUSE_IDENTIFIER = 271,
- SEC_OID_AVA_PSEUDONYM = 272,
-
- /* More OIDs */
- SEC_OID_PKIX_CA_ISSUERS = 273,
- SEC_OID_PKCS9_EXTENSION_REQUEST = 274,
-
- /* new EC Signature oids */
- SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST = 275,
- SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST = 276,
- SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE = 277,
- SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE = 278,
- SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE = 279,
- SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE = 280,
-
- /* More id-ce and id-pe OIDs from RFC 3280 */
- SEC_OID_X509_HOLD_INSTRUCTION_CODE = 281,
- SEC_OID_X509_DELTA_CRL_INDICATOR = 282,
- SEC_OID_X509_ISSUING_DISTRIBUTION_POINT = 283,
- SEC_OID_X509_CERT_ISSUER = 284,
- SEC_OID_X509_FRESHEST_CRL = 285,
- SEC_OID_X509_INHIBIT_ANY_POLICY = 286,
- SEC_OID_X509_SUBJECT_INFO_ACCESS = 287,
-
- /* Camellia OIDs (RFC3657)*/
- SEC_OID_CAMELLIA_128_CBC = 288,
- SEC_OID_CAMELLIA_192_CBC = 289,
- SEC_OID_CAMELLIA_256_CBC = 290,
-
- /* PKCS 5 V2 OIDS */
- SEC_OID_PKCS5_PBKDF2 = 291,
- SEC_OID_PKCS5_PBES2 = 292,
- SEC_OID_PKCS5_PBMAC1 = 293,
- SEC_OID_HMAC_SHA1 = 294,
- SEC_OID_HMAC_SHA224 = 295,
- SEC_OID_HMAC_SHA256 = 296,
- SEC_OID_HMAC_SHA384 = 297,
- SEC_OID_HMAC_SHA512 = 298,
-
- SEC_OID_PKIX_TIMESTAMPING = 299,
- SEC_OID_PKIX_CA_REPOSITORY = 300,
-
- SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE = 301,
-
- SEC_OID_SEED_CBC = 302,
-
- SEC_OID_X509_ANY_POLICY = 303,
-
- SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION = 304,
- SEC_OID_PKCS1_MGF1 = 305,
- SEC_OID_PKCS1_PSPECIFIED = 306,
- SEC_OID_PKCS1_RSA_PSS_SIGNATURE = 307,
- SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION = 308,
-
- SEC_OID_SHA224 = 309,
-
- SEC_OID_EV_INCORPORATION_LOCALITY = 310,
- SEC_OID_EV_INCORPORATION_STATE = 311,
- SEC_OID_EV_INCORPORATION_COUNTRY = 312,
- SEC_OID_BUSINESS_CATEGORY = 313,
-
- SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST = 314,
- SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST = 315,
-
- /* Microsoft Trust List Signing
- * szOID_KP_CTL_USAGE_SIGNING
- * where KP stands for Key Purpose
- */
- SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING = 316,
-
- SEC_OID_TOTAL
-} SECOidTag;
-
-#define SEC_OID_SECG_EC_SECP192R1 SEC_OID_ANSIX962_EC_PRIME192V1
-#define SEC_OID_SECG_EC_SECP256R1 SEC_OID_ANSIX962_EC_PRIME256V1
-#define SEC_OID_PKCS12_KEY_USAGE SEC_OID_X509_KEY_USAGE
-
-/* fake OID for DSS sign/verify */
-#define SEC_OID_SHA SEC_OID_MISS_DSS
-
-typedef enum {
- INVALID_CERT_EXTENSION = 0,
- UNSUPPORTED_CERT_EXTENSION = 1,
- SUPPORTED_CERT_EXTENSION = 2
-} SECSupportExtenTag;
-
-struct SECOidDataStr {
- SECItem oid;
- SECOidTag offset;
- const char * desc;
- unsigned long mechanism;
- SECSupportExtenTag supportedExtension;
- /* only used for x.509 v3 extensions, so
- that we can print the names of those
- extensions that we don't even support */
-};
-
-/* New Opaque extended OID table API.
- * These are algorithm policy Flags, used with functions
- * NSS_SetAlgorithmPolicy & NSS_GetAlgorithmPolicy.
- */
-#define NSS_USE_ALG_IN_CERT_SIGNATURE 0x00000001 /* CRLs and OCSP, too */
-#define NSS_USE_ALG_IN_CMS_SIGNATURE 0x00000002 /* used in S/MIME */
-#define NSS_USE_ALG_RESERVED 0xfffffffc /* may be used in future */
-
-/* Code MUST NOT SET or CLEAR reserved bits, and must NOT depend on them
- * being all zeros or having any other known value. The reserved bits
- * must be ignored.
- */
-
-
-#endif /* _SECOIDT_H_ */
diff --git a/security/nss/lib/util/secplcy.c b/security/nss/lib/util/secplcy.c
deleted file mode 100644
index 3b5523408..000000000
--- a/security/nss/lib/util/secplcy.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "secplcy.h"
-#include "prmem.h"
-
-SECCipherFind *sec_CipherFindInit(PRBool onlyAllowed,
- secCPStruct *policy,
- long *ciphers)
-{
- SECCipherFind *find = PR_NEWZAP(SECCipherFind);
- if (find)
- {
- find->policy = policy;
- find->ciphers = ciphers;
- find->onlyAllowed = onlyAllowed;
- find->index = -1;
- }
- return find;
-}
-
-long sec_CipherFindNext(SECCipherFind *find)
-{
- char *policy;
- long rv = -1;
- secCPStruct *policies = (secCPStruct *) find->policy;
- long *ciphers = (long *) find->ciphers;
- long numCiphers = policies->num_ciphers;
-
- find->index++;
- while((find->index < numCiphers) && (rv == -1))
- {
- /* Translate index to cipher. */
- rv = ciphers[find->index];
-
- /* If we're only looking for allowed ciphers, and if this
- cipher isn't allowed, loop around.*/
- if (find->onlyAllowed)
- {
- /* Find the appropriate policy flag. */
- policy = (&(policies->begin_ciphers)) + find->index + 1;
-
- /* If this cipher isn't allowed by policy, continue. */
- if (! (*policy))
- {
- rv = -1;
- find->index++;
- }
- }
- }
-
- return rv;
-}
-
-char sec_IsCipherAllowed(long cipher, secCPStruct *policies,
- long *ciphers)
-{
- char result = SEC_CIPHER_NOT_ALLOWED; /* our default answer */
- long numCiphers = policies->num_ciphers;
- char *policy;
- int i;
-
- /* Convert the cipher number into a policy flag location. */
- for (i=0, policy=(&(policies->begin_ciphers) + 1);
- i<numCiphers;
- i++, policy++)
- {
- if (cipher == ciphers[i])
- break;
- }
-
- if (i < numCiphers)
- {
- /* Found the cipher, get the policy value. */
- result = *policy;
- }
-
- return result;
-}
-
-void sec_CipherFindEnd(SECCipherFind *find)
-{
- PR_FREEIF(find);
-}
diff --git a/security/nss/lib/util/secplcy.h b/security/nss/lib/util/secplcy.h
deleted file mode 100644
index a34e23356..000000000
--- a/security/nss/lib/util/secplcy.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef __secplcy_h__
-#define __secplcy_h__
-
-#include "utilrename.h"
-
-#include "prtypes.h"
-
-/*
-** Cipher policy enforcement. This code isn't very pretty, but it accomplishes
-** the purpose of obscuring policy information from potential fortifiers. :-)
-**
-** The following routines are generic and intended for anywhere where cipher
-** policy enforcement is to be done, e.g. SSL and PKCS7&12.
-*/
-
-#define SEC_CIPHER_NOT_ALLOWED 0
-#define SEC_CIPHER_ALLOWED 1
-#define SEC_CIPHER_RESTRICTED 2 /* cipher is allowed in limited cases
- e.g. step-up */
-
-/* The length of the header string for each cipher table.
- (It's the same regardless of whether we're using md5 strings or not.) */
-#define SEC_POLICY_HEADER_LENGTH 48
-
-/* If we're testing policy stuff, we may want to use the plaintext version */
-#define SEC_POLICY_USE_MD5_STRINGS 1
-
-#define SEC_POLICY_THIS_IS_THE \
- "\x2a\x3a\x51\xbf\x2f\x71\xb7\x73\xaa\xca\x6b\x57\x70\xcd\xc8\x9f"
-#define SEC_POLICY_STRING_FOR_THE \
- "\x97\x15\xe2\x70\xd2\x8a\xde\xa9\xe7\xa7\x6a\xe2\x83\xe5\xb1\xf6"
-#define SEC_POLICY_SSL_TAIL \
- "\x70\x16\x25\xc0\x2a\xb2\x4a\xca\xb6\x67\xb1\x89\x20\xdf\x87\xca"
-#define SEC_POLICY_SMIME_TAIL \
- "\xdf\xd4\xe7\x2a\xeb\xc4\x1b\xb5\xd8\xe5\xe0\x2a\x16\x9f\xc4\xb9"
-#define SEC_POLICY_PKCS12_TAIL \
- "\x1c\xf8\xa4\x85\x4a\xc6\x8a\xfe\xe6\xca\x03\x72\x50\x1c\xe2\xc8"
-
-#if defined(SEC_POLICY_USE_MD5_STRINGS)
-
-/* We're not testing.
- Use md5 checksums of the strings. */
-
-#define SEC_POLICY_SSL_HEADER \
- SEC_POLICY_THIS_IS_THE SEC_POLICY_STRING_FOR_THE SEC_POLICY_SSL_TAIL
-
-#define SEC_POLICY_SMIME_HEADER \
- SEC_POLICY_THIS_IS_THE SEC_POLICY_STRING_FOR_THE SEC_POLICY_SMIME_TAIL
-
-#define SEC_POLICY_PKCS12_HEADER \
- SEC_POLICY_THIS_IS_THE SEC_POLICY_STRING_FOR_THE SEC_POLICY_PKCS12_TAIL
-
-#else
-
-/* We're testing.
- Use plaintext versions of the strings, for testing purposes. */
-#define SEC_POLICY_SSL_HEADER \
- "This is the string for the SSL policy table. "
-#define SEC_POLICY_SMIME_HEADER \
- "This is the string for the PKCS7 policy table. "
-#define SEC_POLICY_PKCS12_HEADER \
- "This is the string for the PKCS12 policy table. "
-
-#endif
-
-/* Local cipher tables have to have these members at the top. */
-typedef struct _sec_cp_struct
-{
- char policy_string[SEC_POLICY_HEADER_LENGTH];
- long unused; /* placeholder for max keybits in pkcs12 struct */
- char num_ciphers;
- char begin_ciphers;
- /* cipher policy settings follow. each is a char. */
-} secCPStruct;
-
-struct SECCipherFindStr
-{
- /* (policy) and (ciphers) are opaque to the outside world */
- void *policy;
- void *ciphers;
- long index;
- PRBool onlyAllowed;
-};
-
-typedef struct SECCipherFindStr SECCipherFind;
-
-SEC_BEGIN_PROTOS
-
-SECCipherFind *sec_CipherFindInit(PRBool onlyAllowed,
- secCPStruct *policy,
- long *ciphers);
-
-long sec_CipherFindNext(SECCipherFind *find);
-
-char sec_IsCipherAllowed(long cipher, secCPStruct *policies,
- long *ciphers);
-
-void sec_CipherFindEnd(SECCipherFind *find);
-
-SEC_END_PROTOS
-
-#endif /* __SECPLCY_H__ */
diff --git a/security/nss/lib/util/secport.c b/security/nss/lib/util/secport.c
deleted file mode 100644
index 2d7ad1e86..000000000
--- a/security/nss/lib/util/secport.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * secport.c - portability interfaces for security libraries
- *
- * This file abstracts out libc functionality that libsec depends on
- *
- * NOTE - These are not public interfaces
- *
- * $Id$
- */
-
-#include "seccomon.h"
-#include "prmem.h"
-#include "prerror.h"
-#include "plarena.h"
-#include "secerr.h"
-#include "prmon.h"
-#include "nssilock.h"
-#include "secport.h"
-#include "prenv.h"
-
-#ifdef DEBUG
-#define THREADMARK
-#endif /* DEBUG */
-
-#ifdef THREADMARK
-#include "prthread.h"
-#endif /* THREADMARK */
-
-#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
-#include <stdlib.h>
-#else
-#include "wtypes.h"
-#endif
-
-#define SET_ERROR_CODE /* place holder for code to set PR error code. */
-
-#ifdef THREADMARK
-typedef struct threadmark_mark_str {
- struct threadmark_mark_str *next;
- void *mark;
-} threadmark_mark;
-
-#endif /* THREADMARK */
-
-/* The value of this magic must change each time PORTArenaPool changes. */
-#define ARENAPOOL_MAGIC 0xB8AC9BDF
-
-typedef struct PORTArenaPool_str {
- PLArenaPool arena;
- PRUint32 magic;
- PRLock * lock;
-#ifdef THREADMARK
- PRThread *marking_thread;
- threadmark_mark *first_mark;
-#endif
-} PORTArenaPool;
-
-
-/* count of allocation failures. */
-unsigned long port_allocFailures;
-
-/* locations for registering Unicode conversion functions.
- * XXX is this the appropriate location? or should they be
- * moved to client/server specific locations?
- */
-PORTCharConversionFunc ucs4Utf8ConvertFunc;
-PORTCharConversionFunc ucs2Utf8ConvertFunc;
-PORTCharConversionWSwapFunc ucs2AsciiConvertFunc;
-
-void *
-PORT_Alloc(size_t bytes)
-{
- void *rv;
-
- /* Always allocate a non-zero amount of bytes */
- rv = (void *)PR_Malloc(bytes ? bytes : 1);
- if (!rv) {
- ++port_allocFailures;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- return rv;
-}
-
-void *
-PORT_Realloc(void *oldptr, size_t bytes)
-{
- void *rv;
-
- rv = (void *)PR_Realloc(oldptr, bytes);
- if (!rv) {
- ++port_allocFailures;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- return rv;
-}
-
-void *
-PORT_ZAlloc(size_t bytes)
-{
- void *rv;
-
- /* Always allocate a non-zero amount of bytes */
- rv = (void *)PR_Calloc(1, bytes ? bytes : 1);
- if (!rv) {
- ++port_allocFailures;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
- return rv;
-}
-
-void
-PORT_Free(void *ptr)
-{
- if (ptr) {
- PR_Free(ptr);
- }
-}
-
-void
-PORT_ZFree(void *ptr, size_t len)
-{
- if (ptr) {
- memset(ptr, 0, len);
- PR_Free(ptr);
- }
-}
-
-char *
-PORT_Strdup(const char *str)
-{
- size_t len = PORT_Strlen(str)+1;
- char *newstr;
-
- newstr = (char *)PORT_Alloc(len);
- if (newstr) {
- PORT_Memcpy(newstr, str, len);
- }
- return newstr;
-}
-
-void
-PORT_SetError(int value)
-{
-#ifdef DEBUG_jp96085
- PORT_Assert(value != SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
-#endif
- PR_SetError(value, 0);
- return;
-}
-
-int
-PORT_GetError(void)
-{
- return(PR_GetError());
-}
-
-/********************* Arena code follows *****************************
- * ArenaPools are like heaps. The memory in them consists of large blocks,
- * called arenas, which are allocated from the/a system heap. Inside an
- * ArenaPool, the arenas are organized as if they were in a stack. Newly
- * allocated arenas are "pushed" on that stack. When you attempt to
- * allocate memory from an ArenaPool, the code first looks to see if there
- * is enough unused space in the top arena on the stack to satisfy your
- * request, and if so, your request is satisfied from that arena.
- * Otherwise, a new arena is allocated (or taken from NSPR's list of freed
- * arenas) and pushed on to the stack. The new arena is always big enough
- * to satisfy the request, and is also at least a minimum size that is
- * established at the time that the ArenaPool is created.
- *
- * The ArenaMark function returns the address of a marker in the arena at
- * the top of the arena stack. It is the address of the place in the arena
- * on the top of the arena stack from which the next block of memory will
- * be allocated. Each ArenaPool has its own separate stack, and hence
- * marks are only relevant to the ArenaPool from which they are gotten.
- * Marks may be nested. That is, a thread can get a mark, and then get
- * another mark.
- *
- * It is intended that all the marks in an ArenaPool may only be owned by a
- * single thread. In DEBUG builds, this is enforced. In non-DEBUG builds,
- * it is not. In DEBUG builds, when a thread gets a mark from an
- * ArenaPool, no other thread may acquire a mark in that ArenaPool while
- * that mark exists, that is, until that mark is unmarked or released.
- * Therefore, it is important that every mark be unmarked or released when
- * the creating thread has no further need for exclusive ownership of the
- * right to manage the ArenaPool.
- *
- * The ArenaUnmark function discards the ArenaMark at the address given,
- * and all marks nested inside that mark (that is, acquired from that same
- * ArenaPool while that mark existed). It is an error for a thread other
- * than the mark's creator to try to unmark it. When a thread has unmarked
- * all its marks from an ArenaPool, then another thread is able to set
- * marks in that ArenaPool. ArenaUnmark does not deallocate (or "pop") any
- * memory allocated from the ArenaPool since the mark was created.
- *
- * ArenaRelease "pops" the stack back to the mark, deallocating all the
- * memory allocated from the arenas in the ArenaPool since that mark was
- * created, and removing any arenas from the ArenaPool that have no
- * remaining active allocations when that is done. It implicitly releases
- * any marks nested inside the mark being explicitly released. It is the
- * only operation, other than destroying the arenapool, that potentially
- * reduces the number of arenas on the stack. Otherwise, the stack grows
- * until the arenapool is destroyed, at which point all the arenas are
- * freed or returned to a "free arena list", depending on their sizes.
- */
-PLArenaPool *
-PORT_NewArena(unsigned long chunksize)
-{
- PORTArenaPool *pool;
-
- pool = PORT_ZNew(PORTArenaPool);
- if (!pool) {
- return NULL;
- }
- pool->magic = ARENAPOOL_MAGIC;
- pool->lock = PZ_NewLock(nssILockArena);
- if (!pool->lock) {
- ++port_allocFailures;
- PORT_Free(pool);
- return NULL;
- }
- PL_InitArenaPool(&pool->arena, "security", chunksize, sizeof(double));
- return(&pool->arena);
-}
-
-#define MAX_SIZE 0x7fffffffUL
-
-void *
-PORT_ArenaAlloc(PLArenaPool *arena, size_t size)
-{
- void *p = NULL;
-
- PORTArenaPool *pool = (PORTArenaPool *)arena;
-
- if (size <= 0) {
- size = 1;
- }
-
- if (size > MAX_SIZE) {
- /* you lose. */
- } else
- /* Is it one of ours? Assume so and check the magic */
- if (ARENAPOOL_MAGIC == pool->magic ) {
- PZ_Lock(pool->lock);
-#ifdef THREADMARK
- /* Most likely one of ours. Is there a thread id? */
- if (pool->marking_thread &&
- pool->marking_thread != PR_GetCurrentThread() ) {
- /* Another thread holds a mark in this arena */
- PZ_Unlock(pool->lock);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_Assert(0);
- return NULL;
- } /* tid != null */
-#endif /* THREADMARK */
- PL_ARENA_ALLOCATE(p, arena, size);
- PZ_Unlock(pool->lock);
- } else {
- PL_ARENA_ALLOCATE(p, arena, size);
- }
-
- if (!p) {
- ++port_allocFailures;
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- }
-
- return(p);
-}
-
-void *
-PORT_ArenaZAlloc(PLArenaPool *arena, size_t size)
-{
- void *p;
-
- if (size <= 0)
- size = 1;
-
- p = PORT_ArenaAlloc(arena, size);
-
- if (p) {
- PORT_Memset(p, 0, size);
- }
-
- return(p);
-}
-
-/*
- * If zero is true, zeroize the arena memory before freeing it.
- */
-void
-PORT_FreeArena(PLArenaPool *arena, PRBool zero)
-{
- PORTArenaPool *pool = (PORTArenaPool *)arena;
- PRLock * lock = (PRLock *)0;
- size_t len = sizeof *arena;
- static PRBool checkedEnv = PR_FALSE;
- static PRBool doFreeArenaPool = PR_FALSE;
-
- if (!pool)
- return;
- if (ARENAPOOL_MAGIC == pool->magic ) {
- len = sizeof *pool;
- lock = pool->lock;
- PZ_Lock(lock);
- }
- if (!checkedEnv) {
- /* no need for thread protection here */
- doFreeArenaPool = (PR_GetEnv("NSS_DISABLE_ARENA_FREE_LIST") == NULL);
- checkedEnv = PR_TRUE;
- }
- if (zero) {
- PL_ClearArenaPool(arena, 0);
- }
- if (doFreeArenaPool) {
- PL_FreeArenaPool(arena);
- } else {
- PL_FinishArenaPool(arena);
- }
- PORT_ZFree(arena, len);
- if (lock) {
- PZ_Unlock(lock);
- PZ_DestroyLock(lock);
- }
-}
-
-void *
-PORT_ArenaGrow(PLArenaPool *arena, void *ptr, size_t oldsize, size_t newsize)
-{
- PORTArenaPool *pool = (PORTArenaPool *)arena;
- PORT_Assert(newsize >= oldsize);
-
- if (ARENAPOOL_MAGIC == pool->magic ) {
- PZ_Lock(pool->lock);
- /* Do we do a THREADMARK check here? */
- PL_ARENA_GROW(ptr, arena, oldsize, ( newsize - oldsize ) );
- PZ_Unlock(pool->lock);
- } else {
- PL_ARENA_GROW(ptr, arena, oldsize, ( newsize - oldsize ) );
- }
-
- return(ptr);
-}
-
-void *
-PORT_ArenaMark(PLArenaPool *arena)
-{
- void * result;
-
- PORTArenaPool *pool = (PORTArenaPool *)arena;
- if (ARENAPOOL_MAGIC == pool->magic ) {
- PZ_Lock(pool->lock);
-#ifdef THREADMARK
- {
- threadmark_mark *tm, **pw;
- PRThread * currentThread = PR_GetCurrentThread();
-
- if (! pool->marking_thread ) {
- /* First mark */
- pool->marking_thread = currentThread;
- } else if (currentThread != pool->marking_thread ) {
- PZ_Unlock(pool->lock);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_Assert(0);
- return NULL;
- }
-
- result = PL_ARENA_MARK(arena);
- PL_ARENA_ALLOCATE(tm, arena, sizeof(threadmark_mark));
- if (!tm) {
- PZ_Unlock(pool->lock);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- return NULL;
- }
-
- tm->mark = result;
- tm->next = (threadmark_mark *)NULL;
-
- pw = &pool->first_mark;
- while( *pw ) {
- pw = &(*pw)->next;
- }
-
- *pw = tm;
- }
-#else /* THREADMARK */
- result = PL_ARENA_MARK(arena);
-#endif /* THREADMARK */
- PZ_Unlock(pool->lock);
- } else {
- /* a "pure" NSPR arena */
- result = PL_ARENA_MARK(arena);
- }
- return result;
-}
-
-static void
-port_ArenaZeroAfterMark(PLArenaPool *arena, void *mark)
-{
- PLArena *a = arena->current;
- if (a->base <= (PRUword)mark && (PRUword)mark <= a->avail) {
- /* fast path: mark falls in the current arena */
- memset(mark, 0, a->avail - (PRUword)mark);
- } else {
- /* slow path: need to find the arena that mark falls in */
- for (a = arena->first.next; a; a = a->next) {
- PR_ASSERT(a->base <= a->avail && a->avail <= a->limit);
- if (a->base <= (PRUword)mark && (PRUword)mark <= a->avail) {
- memset(mark, 0, a->avail - (PRUword)mark);
- a = a->next;
- break;
- }
- }
- for (; a; a = a->next) {
- PR_ASSERT(a->base <= a->avail && a->avail <= a->limit);
- memset((void *)a->base, 0, a->avail - a->base);
- }
- }
-}
-
-static void
-port_ArenaRelease(PLArenaPool *arena, void *mark, PRBool zero)
-{
- PORTArenaPool *pool = (PORTArenaPool *)arena;
- if (ARENAPOOL_MAGIC == pool->magic ) {
- PZ_Lock(pool->lock);
-#ifdef THREADMARK
- {
- threadmark_mark **pw, *tm;
-
- if (PR_GetCurrentThread() != pool->marking_thread ) {
- PZ_Unlock(pool->lock);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_Assert(0);
- return /* no error indication available */ ;
- }
-
- pw = &pool->first_mark;
- while( *pw && (mark != (*pw)->mark) ) {
- pw = &(*pw)->next;
- }
-
- if (! *pw ) {
- /* bad mark */
- PZ_Unlock(pool->lock);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_Assert(0);
- return /* no error indication available */ ;
- }
-
- tm = *pw;
- *pw = (threadmark_mark *)NULL;
-
- if (zero) {
- port_ArenaZeroAfterMark(arena, mark);
- }
- PL_ARENA_RELEASE(arena, mark);
-
- if (! pool->first_mark ) {
- pool->marking_thread = (PRThread *)NULL;
- }
- }
-#else /* THREADMARK */
- if (zero) {
- port_ArenaZeroAfterMark(arena, mark);
- }
- PL_ARENA_RELEASE(arena, mark);
-#endif /* THREADMARK */
- PZ_Unlock(pool->lock);
- } else {
- if (zero) {
- port_ArenaZeroAfterMark(arena, mark);
- }
- PL_ARENA_RELEASE(arena, mark);
- }
-}
-
-void
-PORT_ArenaRelease(PLArenaPool *arena, void *mark)
-{
- port_ArenaRelease(arena, mark, PR_FALSE);
-}
-
-/*
- * Zeroize the arena memory before releasing it.
- */
-void
-PORT_ArenaZRelease(PLArenaPool *arena, void *mark)
-{
- port_ArenaRelease(arena, mark, PR_TRUE);
-}
-
-void
-PORT_ArenaUnmark(PLArenaPool *arena, void *mark)
-{
-#ifdef THREADMARK
- PORTArenaPool *pool = (PORTArenaPool *)arena;
- if (ARENAPOOL_MAGIC == pool->magic ) {
- threadmark_mark **pw, *tm;
-
- PZ_Lock(pool->lock);
-
- if (PR_GetCurrentThread() != pool->marking_thread ) {
- PZ_Unlock(pool->lock);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_Assert(0);
- return /* no error indication available */ ;
- }
-
- pw = &pool->first_mark;
- while( ((threadmark_mark *)NULL != *pw) && (mark != (*pw)->mark) ) {
- pw = &(*pw)->next;
- }
-
- if ((threadmark_mark *)NULL == *pw ) {
- /* bad mark */
- PZ_Unlock(pool->lock);
- PORT_SetError(SEC_ERROR_NO_MEMORY);
- PORT_Assert(0);
- return /* no error indication available */ ;
- }
-
- tm = *pw;
- *pw = (threadmark_mark *)NULL;
-
- if (! pool->first_mark ) {
- pool->marking_thread = (PRThread *)NULL;
- }
-
- PZ_Unlock(pool->lock);
- }
-#endif /* THREADMARK */
-}
-
-char *
-PORT_ArenaStrdup(PLArenaPool *arena, const char *str) {
- int len = PORT_Strlen(str)+1;
- char *newstr;
-
- newstr = (char*)PORT_ArenaAlloc(arena,len);
- if (newstr) {
- PORT_Memcpy(newstr,str,len);
- }
- return newstr;
-}
-
-/********************** end of arena functions ***********************/
-
-/****************** unicode conversion functions ***********************/
-/*
- * NOTE: These conversion functions all assume that the multibyte
- * characters are going to be in NETWORK BYTE ORDER, not host byte
- * order. This is because the only time we deal with UCS-2 and UCS-4
- * are when the data was received from or is going to be sent out
- * over the wire (in, e.g. certificates).
- */
-
-void
-PORT_SetUCS4_UTF8ConversionFunction(PORTCharConversionFunc convFunc)
-{
- ucs4Utf8ConvertFunc = convFunc;
-}
-
-void
-PORT_SetUCS2_ASCIIConversionFunction(PORTCharConversionWSwapFunc convFunc)
-{
- ucs2AsciiConvertFunc = convFunc;
-}
-
-void
-PORT_SetUCS2_UTF8ConversionFunction(PORTCharConversionFunc convFunc)
-{
- ucs2Utf8ConvertFunc = convFunc;
-}
-
-PRBool
-PORT_UCS4_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen)
-{
- if(!ucs4Utf8ConvertFunc) {
- return sec_port_ucs4_utf8_conversion_function(toUnicode,
- inBuf, inBufLen, outBuf, maxOutBufLen, outBufLen);
- }
-
- return (*ucs4Utf8ConvertFunc)(toUnicode, inBuf, inBufLen, outBuf,
- maxOutBufLen, outBufLen);
-}
-
-PRBool
-PORT_UCS2_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen)
-{
- if(!ucs2Utf8ConvertFunc) {
- return sec_port_ucs2_utf8_conversion_function(toUnicode,
- inBuf, inBufLen, outBuf, maxOutBufLen, outBufLen);
- }
-
- return (*ucs2Utf8ConvertFunc)(toUnicode, inBuf, inBufLen, outBuf,
- maxOutBufLen, outBufLen);
-}
-
-PRBool
-PORT_ISO88591_UTF8Conversion(const unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen)
-{
- return sec_port_iso88591_utf8_conversion_function(inBuf, inBufLen,
- outBuf, maxOutBufLen, outBufLen);
-}
-
-PRBool
-PORT_UCS2_ASCIIConversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen,
- PRBool swapBytes)
-{
- if(!ucs2AsciiConvertFunc) {
- return PR_FALSE;
- }
-
- return (*ucs2AsciiConvertFunc)(toUnicode, inBuf, inBufLen, outBuf,
- maxOutBufLen, outBufLen, swapBytes);
-}
-
-
-/* Portable putenv. Creates/replaces an environment variable of the form
- * envVarName=envValue
- */
-int
-NSS_PutEnv(const char * envVarName, const char * envValue)
-{
- SECStatus result = SECSuccess;
- char * encoded;
- int putEnvFailed;
-#ifdef _WIN32
- PRBool setOK;
-
- setOK = SetEnvironmentVariable(envVarName, envValue);
- if (!setOK) {
- SET_ERROR_CODE
- return SECFailure;
- }
-#endif
-
- encoded = (char *)PORT_ZAlloc(strlen(envVarName) + 2 + strlen(envValue));
- strcpy(encoded, envVarName);
- strcat(encoded, "=");
- strcat(encoded, envValue);
-
- putEnvFailed = putenv(encoded); /* adopt. */
- if (putEnvFailed) {
- SET_ERROR_CODE
- result = SECFailure;
- PORT_Free(encoded);
- }
- return result;
-}
-
-/*
- * Perform a constant-time compare of two memory regions. The return value is
- * 0 if the memory regions are equal and non-zero otherwise.
- */
-int
-NSS_SecureMemcmp(const void *ia, const void *ib, size_t n)
-{
- const unsigned char *a = (const unsigned char*) ia;
- const unsigned char *b = (const unsigned char*) ib;
- size_t i;
- unsigned char r = 0;
-
- for (i = 0; i < n; ++i) {
- r |= *a++ ^ *b++;
- }
-
- return r;
-}
diff --git a/security/nss/lib/util/secport.h b/security/nss/lib/util/secport.h
deleted file mode 100644
index af0c6a82d..000000000
--- a/security/nss/lib/util/secport.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * secport.h - portability interfaces for security libraries
- *
- * $Id$
- */
-
-#ifndef _SECPORT_H_
-#define _SECPORT_H_
-
-#include "utilrename.h"
-#include "prlink.h"
-
-/*
- * define XP_WIN, XP_BEOS, or XP_UNIX, in case they are not defined
- * by anyone else
- */
-#ifdef _WINDOWS
-# ifndef XP_WIN
-# define XP_WIN
-# endif
-#if defined(_WIN32) || defined(WIN32)
-# ifndef XP_WIN32
-# define XP_WIN32
-# endif
-#endif
-#endif
-
-#ifdef __BEOS__
-# ifndef XP_BEOS
-# define XP_BEOS
-# endif
-#endif
-
-#ifdef unix
-# ifndef XP_UNIX
-# define XP_UNIX
-# endif
-#endif
-
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <string.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include "prtypes.h"
-#include "prlog.h" /* for PR_ASSERT */
-#include "plarena.h"
-#include "plstr.h"
-
-/*
- * HACK for NSS 2.8 to allow Admin to compile without source changes.
- */
-#ifndef SEC_BEGIN_PROTOS
-#include "seccomon.h"
-#endif
-
-SEC_BEGIN_PROTOS
-
-extern void *PORT_Alloc(size_t len);
-extern void *PORT_Realloc(void *old, size_t len);
-extern void *PORT_AllocBlock(size_t len);
-extern void *PORT_ReallocBlock(void *old, size_t len);
-extern void PORT_FreeBlock(void *ptr);
-extern void *PORT_ZAlloc(size_t len);
-extern void PORT_Free(void *ptr);
-extern void PORT_ZFree(void *ptr, size_t len);
-extern char *PORT_Strdup(const char *s);
-extern time_t PORT_Time(void);
-extern void PORT_SetError(int value);
-extern int PORT_GetError(void);
-
-extern PLArenaPool *PORT_NewArena(unsigned long chunksize);
-extern void *PORT_ArenaAlloc(PLArenaPool *arena, size_t size);
-extern void *PORT_ArenaZAlloc(PLArenaPool *arena, size_t size);
-extern void PORT_FreeArena(PLArenaPool *arena, PRBool zero);
-extern void *PORT_ArenaGrow(PLArenaPool *arena, void *ptr,
- size_t oldsize, size_t newsize);
-extern void *PORT_ArenaMark(PLArenaPool *arena);
-extern void PORT_ArenaRelease(PLArenaPool *arena, void *mark);
-extern void PORT_ArenaZRelease(PLArenaPool *arena, void *mark);
-extern void PORT_ArenaUnmark(PLArenaPool *arena, void *mark);
-extern char *PORT_ArenaStrdup(PLArenaPool *arena, const char *str);
-
-SEC_END_PROTOS
-
-#define PORT_Assert PR_ASSERT
-#define PORT_ZNew(type) (type*)PORT_ZAlloc(sizeof(type))
-#define PORT_New(type) (type*)PORT_Alloc(sizeof(type))
-#define PORT_ArenaNew(poolp, type) \
- (type*) PORT_ArenaAlloc(poolp, sizeof(type))
-#define PORT_ArenaZNew(poolp, type) \
- (type*) PORT_ArenaZAlloc(poolp, sizeof(type))
-#define PORT_NewArray(type, num) \
- (type*) PORT_Alloc (sizeof(type)*(num))
-#define PORT_ZNewArray(type, num) \
- (type*) PORT_ZAlloc (sizeof(type)*(num))
-#define PORT_ArenaNewArray(poolp, type, num) \
- (type*) PORT_ArenaAlloc (poolp, sizeof(type)*(num))
-#define PORT_ArenaZNewArray(poolp, type, num) \
- (type*) PORT_ArenaZAlloc (poolp, sizeof(type)*(num))
-
-/* Please, keep these defines sorted alphabetically. Thanks! */
-
-#define PORT_Atoi(buff) (int)strtol(buff, NULL, 10)
-
-/* Returns a UTF-8 encoded constant error string for err.
- * Returns NULL if initialization of the error tables fails
- * due to insufficient memory.
- *
- * This string must not be modified by the application.
- */
-#define PORT_ErrorToString(err) PR_ErrorToString((err), PR_LANGUAGE_I_DEFAULT)
-
-#define PORT_ErrorToName PR_ErrorToName
-
-#define PORT_Memcmp memcmp
-#define PORT_Memcpy memcpy
-#ifndef SUNOS4
-#define PORT_Memmove memmove
-#else /*SUNOS4*/
-#define PORT_Memmove(s,ct,n) bcopy ((ct), (s), (n))
-#endif/*SUNOS4*/
-#define PORT_Memset memset
-
-#define PORT_Strcasecmp PL_strcasecmp
-#define PORT_Strcat strcat
-#define PORT_Strchr strchr
-#define PORT_Strrchr strrchr
-#define PORT_Strcmp strcmp
-#define PORT_Strcpy strcpy
-#define PORT_Strlen(s) strlen(s)
-#define PORT_Strncasecmp PL_strncasecmp
-#define PORT_Strncat strncat
-#define PORT_Strncmp strncmp
-#define PORT_Strncpy strncpy
-#define PORT_Strpbrk strpbrk
-#define PORT_Strstr strstr
-#define PORT_Strtok strtok
-
-#define PORT_Tolower tolower
-
-typedef PRBool (PR_CALLBACK * PORTCharConversionWSwapFunc) (PRBool toUnicode,
- unsigned char *inBuf, unsigned int inBufLen,
- unsigned char *outBuf, unsigned int maxOutBufLen,
- unsigned int *outBufLen, PRBool swapBytes);
-
-typedef PRBool (PR_CALLBACK * PORTCharConversionFunc) (PRBool toUnicode,
- unsigned char *inBuf, unsigned int inBufLen,
- unsigned char *outBuf, unsigned int maxOutBufLen,
- unsigned int *outBufLen);
-
-SEC_BEGIN_PROTOS
-
-void PORT_SetUCS4_UTF8ConversionFunction(PORTCharConversionFunc convFunc);
-void PORT_SetUCS2_ASCIIConversionFunction(PORTCharConversionWSwapFunc convFunc);
-PRBool PORT_UCS4_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen);
-PRBool PORT_UCS2_ASCIIConversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen,
- PRBool swapBytes);
-void PORT_SetUCS2_UTF8ConversionFunction(PORTCharConversionFunc convFunc);
-PRBool PORT_UCS2_UTF8Conversion(PRBool toUnicode, unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen);
-
-/* One-way conversion from ISO-8859-1 to UTF-8 */
-PRBool PORT_ISO88591_UTF8Conversion(const unsigned char *inBuf,
- unsigned int inBufLen, unsigned char *outBuf,
- unsigned int maxOutBufLen, unsigned int *outBufLen);
-
-extern PRBool
-sec_port_ucs4_utf8_conversion_function
-(
- PRBool toUnicode,
- unsigned char *inBuf,
- unsigned int inBufLen,
- unsigned char *outBuf,
- unsigned int maxOutBufLen,
- unsigned int *outBufLen
-);
-
-extern PRBool
-sec_port_ucs2_utf8_conversion_function
-(
- PRBool toUnicode,
- unsigned char *inBuf,
- unsigned int inBufLen,
- unsigned char *outBuf,
- unsigned int maxOutBufLen,
- unsigned int *outBufLen
-);
-
-/* One-way conversion from ISO-8859-1 to UTF-8 */
-extern PRBool
-sec_port_iso88591_utf8_conversion_function
-(
- const unsigned char *inBuf,
- unsigned int inBufLen,
- unsigned char *outBuf,
- unsigned int maxOutBufLen,
- unsigned int *outBufLen
-);
-
-extern int NSS_PutEnv(const char * envVarName, const char * envValue);
-
-extern int NSS_SecureMemcmp(const void *a, const void *b, size_t n);
-
-/*
- * Load a shared library called "newShLibName" in the same directory as
- * a shared library that is already loaded, called existingShLibName.
- * A pointer to a static function in that shared library,
- * staticShLibFunc, is required.
- *
- * existingShLibName:
- * The file name of the shared library that shall be used as the
- * "reference library". The loader will attempt to load the requested
- * library from the same directory as the reference library.
- *
- * staticShLibFunc:
- * Pointer to a static function in the "reference library".
- *
- * newShLibName:
- * The simple file name of the new shared library to be loaded.
- *
- * We use PR_GetLibraryFilePathname to get the pathname of the loaded
- * shared lib that contains this function, and then do a
- * PR_LoadLibraryWithFlags with an absolute pathname for the shared
- * library to be loaded.
- *
- * On Windows, the "alternate search path" strategy is employed, if available.
- * On Unix, if existingShLibName is a symbolic link, and no link exists for the
- * new library, the original link will be resolved, and the new library loaded
- * from the resolved location.
- *
- * If the new shared library is not found in the same location as the reference
- * library, it will then be loaded from the normal system library path.
- */
-PRLibrary *
-PORT_LoadLibraryFromOrigin(const char* existingShLibName,
- PRFuncPtr staticShLibFunc,
- const char *newShLibName);
-
-SEC_END_PROTOS
-
-#endif /* _SECPORT_H_ */
diff --git a/security/nss/lib/util/sectime.c b/security/nss/lib/util/sectime.c
deleted file mode 100644
index a0045f4c7..000000000
--- a/security/nss/lib/util/sectime.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "prtime.h"
-#include "secder.h"
-#include "secitem.h"
-#include "secerr.h"
-
-static char *DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format);
-static char *DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format);
-
-/* convert DER utc time to ascii time string */
-char *
-DER_UTCTimeToAscii(SECItem *utcTime)
-{
- return (DecodeUTCTime2FormattedAscii (utcTime, "%a %b %d %H:%M:%S %Y"));
-}
-
-/* convert DER utc time to ascii time string, only include day, not time */
-char *
-DER_UTCDayToAscii(SECItem *utctime)
-{
- return (DecodeUTCTime2FormattedAscii (utctime, "%a %b %d, %Y"));
-}
-
-/* convert DER generalized time to ascii time string, only include day,
- not time */
-char *
-DER_GeneralizedDayToAscii(SECItem *gentime)
-{
- return (DecodeGeneralizedTime2FormattedAscii (gentime, "%a %b %d, %Y"));
-}
-
-/* convert DER generalized or UTC time to ascii time string, only include
- day, not time */
-char *
-DER_TimeChoiceDayToAscii(SECItem *timechoice)
-{
- switch (timechoice->type) {
-
- case siUTCTime:
- return DER_UTCDayToAscii(timechoice);
-
- case siGeneralizedTime:
- return DER_GeneralizedDayToAscii(timechoice);
-
- default:
- PORT_Assert(0);
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return NULL;
- }
-}
-
-char *
-CERT_UTCTime2FormattedAscii (int64 utcTime, char *format)
-{
- PRExplodedTime printableTime;
- char *timeString;
-
- /* Converse time to local time and decompose it into components */
- PR_ExplodeTime(utcTime, PR_LocalTimeParameters, &printableTime);
-
- timeString = (char *)PORT_Alloc(256);
-
- if ( timeString ) {
- if ( ! PR_FormatTime( timeString, 256, format, &printableTime )) {
- PORT_Free(timeString);
- timeString = NULL;
- }
- }
-
- return (timeString);
-}
-
-char *CERT_GenTime2FormattedAscii (int64 genTime, char *format)
-{
- PRExplodedTime printableTime;
- char *timeString;
-
- /* Decompose time into components */
- PR_ExplodeTime(genTime, PR_GMTParameters, &printableTime);
-
- timeString = (char *)PORT_Alloc(256);
-
- if ( timeString ) {
- if ( ! PR_FormatTime( timeString, 256, format, &printableTime )) {
- PORT_Free(timeString);
- timeString = NULL;
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- }
- }
-
- return (timeString);
-}
-
-
-/* convert DER utc time to ascii time string, The format of the time string
- depends on the input "format"
- */
-static char *
-DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format)
-{
- int64 utcTime;
- int rv;
-
- rv = DER_UTCTimeToTime(&utcTime, utcTimeDER);
- if (rv) {
- return(NULL);
- }
- return (CERT_UTCTime2FormattedAscii (utcTime, format));
-}
-
-/* convert DER utc time to ascii time string, The format of the time string
- depends on the input "format"
- */
-static char *
-DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format)
-{
- PRTime generalizedTime;
- int rv;
-
- rv = DER_GeneralizedTimeToTime(&generalizedTime, generalizedTimeDER);
- if (rv) {
- return(NULL);
- }
- return (CERT_GeneralizedTime2FormattedAscii (generalizedTime, format));
-}
-
-/* decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME
- or a SEC_ASN1_UTC_TIME */
-
-SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input)
-{
- switch (input->type) {
- case siGeneralizedTime:
- return DER_GeneralizedTimeToTime(output, input);
-
- case siUTCTime:
- return DER_UTCTimeToTime(output, input);
-
- default:
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- PORT_Assert(0);
- return SECFailure;
- }
-}
-
-/* encode a PRTime to an ASN.1 DER SECItem containing either a
- SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */
-
-SECStatus DER_EncodeTimeChoice(PRArenaPool* arena, SECItem* output, PRTime input)
-{
- SECStatus rv;
-
- rv = DER_TimeToUTCTimeArena(arena, output, input);
- if (rv == SECSuccess || PORT_GetError() != SEC_ERROR_INVALID_ARGS) {
- return rv;
- }
- return DER_TimeToGeneralizedTimeArena(arena, output, input);
-}
diff --git a/security/nss/lib/util/templates.c b/security/nss/lib/util/templates.c
deleted file mode 100644
index e5f1ebc24..000000000
--- a/security/nss/lib/util/templates.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * Templates that are compiled and exported from both libnss3 and libnssutil3.
- * They have to be, because they were previously exported from libnss3, and
- * there is no way to create data forwarder symbols on Unix.
- *
- * Please do not add to this file. New shared templates should be exported
- * from libnssutil3 only.
- *
- */
-
-#include "utilrename.h"
-#include "secasn1.h"
-#include "secder.h"
-#include "secoid.h"
-#include "secdig.h"
-
-const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SECAlgorithmID) },
- { SEC_ASN1_OBJECT_ID,
- offsetof(SECAlgorithmID,algorithm), },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
- offsetof(SECAlgorithmID,parameters), },
- { 0, }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SECOID_AlgorithmIDTemplate)
-
-const SEC_ASN1Template SEC_AnyTemplate[] = {
- { SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_AnyTemplate)
-
-const SEC_ASN1Template SEC_BMPStringTemplate[] = {
- { SEC_ASN1_BMP_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_BMPStringTemplate)
-
-const SEC_ASN1Template SEC_BitStringTemplate[] = {
- { SEC_ASN1_BIT_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_BitStringTemplate)
-
-const SEC_ASN1Template SEC_BooleanTemplate[] = {
- { SEC_ASN1_BOOLEAN, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_BooleanTemplate)
-
-const SEC_ASN1Template SEC_GeneralizedTimeTemplate[] = {
- { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_GeneralizedTimeTemplate)
-
-const SEC_ASN1Template SEC_IA5StringTemplate[] = {
- { SEC_ASN1_IA5_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_IA5StringTemplate)
-
-const SEC_ASN1Template SEC_IntegerTemplate[] = {
- { SEC_ASN1_INTEGER, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_IntegerTemplate)
-
-const SEC_ASN1Template SEC_NullTemplate[] = {
- { SEC_ASN1_NULL, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_NullTemplate)
-
-const SEC_ASN1Template SEC_ObjectIDTemplate[] = {
- { SEC_ASN1_OBJECT_ID, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_ObjectIDTemplate)
-
-const SEC_ASN1Template SEC_OctetStringTemplate[] = {
- { SEC_ASN1_OCTET_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_OctetStringTemplate)
-
-const SEC_ASN1Template SEC_PointerToAnyTemplate[] = {
- { SEC_ASN1_POINTER, 0, SEC_AnyTemplate }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToAnyTemplate)
-
-const SEC_ASN1Template SEC_PointerToOctetStringTemplate[] = {
- { SEC_ASN1_POINTER | SEC_ASN1_MAY_STREAM, 0, SEC_OctetStringTemplate }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_PointerToOctetStringTemplate)
-
-const SEC_ASN1Template SEC_SetOfAnyTemplate[] = {
- { SEC_ASN1_SET_OF, 0, SEC_AnyTemplate }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SetOfAnyTemplate)
-
-const SEC_ASN1Template SEC_UTCTimeTemplate[] = {
- { SEC_ASN1_UTC_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_UTCTimeTemplate)
-
-const SEC_ASN1Template SEC_UTF8StringTemplate[] = {
- { SEC_ASN1_UTF8_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(SEC_UTF8StringTemplate)
-
-/* XXX See comment below about SGN_DecodeDigestInfo -- keep this static! */
-/* XXX Changed from static -- need to change name? */
-const SEC_ASN1Template sgn_DigestInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SGNDigestInfo) },
- { SEC_ASN1_INLINE,
- offsetof(SGNDigestInfo,digestAlgorithm),
- SECOID_AlgorithmIDTemplate },
- { SEC_ASN1_OCTET_STRING,
- offsetof(SGNDigestInfo,digest) },
- { 0 }
-};
-
-SEC_ASN1_CHOOSER_IMPLEMENT(sgn_DigestInfoTemplate)
diff --git a/security/nss/lib/util/utf8.c b/security/nss/lib/util/utf8.c
deleted file mode 100644
index 117d8b335..000000000
--- a/security/nss/lib/util/utf8.c
+++ /dev/null
@@ -1,1800 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifdef DEBUG
-static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$";
-#endif /* DEBUG */
-
-#include "seccomon.h"
-#include "secport.h"
-
-#ifdef TEST_UTF8
-#include <assert.h>
-#undef PORT_Assert
-#define PORT_Assert assert
-#endif
-
-/*
- * From RFC 2044:
- *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- * 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- * 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
- * 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx
- */
-
-/*
- * From http://www.imc.org/draft-hoffman-utf16
- *
- * For U on [0x00010000,0x0010FFFF]: Let U' = U - 0x00010000
- *
- * U' = yyyyyyyyyyxxxxxxxxxx
- * W1 = 110110yyyyyyyyyy
- * W2 = 110111xxxxxxxxxx
- */
-
-/*
- * This code is assuming NETWORK BYTE ORDER for the 16- and 32-bit
- * character values. If you wish to use this code for working with
- * host byte order values, define the following:
- *
- * #if IS_BIG_ENDIAN
- * #define L_0 0
- * #define L_1 1
- * #define L_2 2
- * #define L_3 3
- * #define H_0 0
- * #define H_1 1
- * #else / * not everyone has elif * /
- * #if IS_LITTLE_ENDIAN
- * #define L_0 3
- * #define L_1 2
- * #define L_2 1
- * #define L_3 0
- * #define H_0 1
- * #define H_1 0
- * #else
- * #error "PDP and NUXI support deferred"
- * #endif / * IS_LITTLE_ENDIAN * /
- * #endif / * IS_BIG_ENDIAN * /
- */
-
-#define L_0 0
-#define L_1 1
-#define L_2 2
-#define L_3 3
-#define H_0 0
-#define H_1 1
-
-#define BAD_UTF8 ((PRUint32)-1)
-
-/*
- * Parse a single UTF-8 character per the spec. in section 3.9 (D36)
- * of Unicode 4.0.0.
- *
- * Parameters:
- * index - Points to the byte offset in inBuf of character to read. On success,
- * updated to the offset of the following character.
- * inBuf - Input buffer, UTF-8 encoded
- * inbufLen - Length of input buffer, in bytes.
- *
- * Returns:
- * Success - The UCS4 encoded character
- * Failure - BAD_UTF8
- */
-static PRUint32
-sec_port_read_utf8(unsigned int *index, unsigned char *inBuf, unsigned int inBufLen)
-{
- PRUint32 result;
- unsigned int i = *index;
- int bytes_left;
- PRUint32 min_value;
-
- PORT_Assert(i < inBufLen);
-
- if ( (inBuf[i] & 0x80) == 0x00 ) {
- result = inBuf[i++];
- bytes_left = 0;
- min_value = 0;
- } else if ( (inBuf[i] & 0xE0) == 0xC0 ) {
- result = inBuf[i++] & 0x1F;
- bytes_left = 1;
- min_value = 0x80;
- } else if ( (inBuf[i] & 0xF0) == 0xE0) {
- result = inBuf[i++] & 0x0F;
- bytes_left = 2;
- min_value = 0x800;
- } else if ( (inBuf[i] & 0xF8) == 0xF0) {
- result = inBuf[i++] & 0x07;
- bytes_left = 3;
- min_value = 0x10000;
- } else {
- return BAD_UTF8;
- }
-
- while (bytes_left--) {
- if (i >= inBufLen || (inBuf[i] & 0xC0) != 0x80) return BAD_UTF8;
- result = (result << 6) | (inBuf[i++] & 0x3F);
- }
-
- /* Check for overlong sequences, surrogates, and outside unicode range */
- if (result < min_value || (result & 0xFFFFF800) == 0xD800 || result > 0x10FFFF) {
- return BAD_UTF8;
- }
-
- *index = i;
- return result;
-}
-
-PRBool
-sec_port_ucs4_utf8_conversion_function
-(
- PRBool toUnicode,
- unsigned char *inBuf,
- unsigned int inBufLen,
- unsigned char *outBuf,
- unsigned int maxOutBufLen,
- unsigned int *outBufLen
-)
-{
- PORT_Assert((unsigned int *)NULL != outBufLen);
-
- if( toUnicode ) {
- unsigned int i, len = 0;
-
- for( i = 0; i < inBufLen; ) {
- if( (inBuf[i] & 0x80) == 0x00 ) i += 1;
- else if( (inBuf[i] & 0xE0) == 0xC0 ) i += 2;
- else if( (inBuf[i] & 0xF0) == 0xE0 ) i += 3;
- else if( (inBuf[i] & 0xF8) == 0xF0 ) i += 4;
- else return PR_FALSE;
-
- len += 4;
- }
-
- if( len > maxOutBufLen ) {
- *outBufLen = len;
- return PR_FALSE;
- }
-
- len = 0;
-
- for( i = 0; i < inBufLen; ) {
- PRUint32 ucs4 = sec_port_read_utf8(&i, inBuf, inBufLen);
-
- if (ucs4 == BAD_UTF8) return PR_FALSE;
-
- outBuf[len+L_0] = 0x00;
- outBuf[len+L_1] = (unsigned char)(ucs4 >> 16);
- outBuf[len+L_2] = (unsigned char)(ucs4 >> 8);
- outBuf[len+L_3] = (unsigned char)ucs4;
-
- len += 4;
- }
-
- *outBufLen = len;
- return PR_TRUE;
- } else {
- unsigned int i, len = 0;
- PORT_Assert((inBufLen % 4) == 0);
- if ((inBufLen % 4) != 0) {
- *outBufLen = 0;
- return PR_FALSE;
- }
-
- for( i = 0; i < inBufLen; i += 4 ) {
- if( (inBuf[i+L_0] > 0x00) || (inBuf[i+L_1] > 0x10) ) {
- *outBufLen = 0;
- return PR_FALSE;
- } else if( inBuf[i+L_1] >= 0x01 ) len += 4;
- else if( inBuf[i+L_2] >= 0x08 ) len += 3;
- else if( (inBuf[i+L_2] > 0x00) || (inBuf[i+L_3] >= 0x80) ) len += 2;
- else len += 1;
- }
-
- if( len > maxOutBufLen ) {
- *outBufLen = len;
- return PR_FALSE;
- }
-
- len = 0;
-
- for( i = 0; i < inBufLen; i += 4 ) {
- if( inBuf[i+L_1] >= 0x01 ) {
- /* 0001 0000-001F FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
- /* 00000000 000abcde fghijklm nopqrstu ->
- 11110abc 10defghi 10jklmno 10pqrstu */
-
- outBuf[len+0] = 0xF0 | ((inBuf[i+L_1] & 0x1C) >> 2);
- outBuf[len+1] = 0x80 | ((inBuf[i+L_1] & 0x03) << 4)
- | ((inBuf[i+L_2] & 0xF0) >> 4);
- outBuf[len+2] = 0x80 | ((inBuf[i+L_2] & 0x0F) << 2)
- | ((inBuf[i+L_3] & 0xC0) >> 6);
- outBuf[len+3] = 0x80 | ((inBuf[i+L_3] & 0x3F) >> 0);
-
- len += 4;
- } else if( inBuf[i+L_2] >= 0x08 ) {
- /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
- /* 00000000 00000000 abcdefgh ijklmnop ->
- 1110abcd 10efghij 10klmnop */
-
- outBuf[len+0] = 0xE0 | ((inBuf[i+L_2] & 0xF0) >> 4);
- outBuf[len+1] = 0x80 | ((inBuf[i+L_2] & 0x0F) << 2)
- | ((inBuf[i+L_3] & 0xC0) >> 6);
- outBuf[len+2] = 0x80 | ((inBuf[i+L_3] & 0x3F) >> 0);
-
- len += 3;
- } else if( (inBuf[i+L_2] > 0x00) || (inBuf[i+L_3] >= 0x80) ) {
- /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
- /* 00000000 00000000 00000abc defghijk ->
- 110abcde 10fghijk */
-
- outBuf[len+0] = 0xC0 | ((inBuf[i+L_2] & 0x07) << 2)
- | ((inBuf[i+L_3] & 0xC0) >> 6);
- outBuf[len+1] = 0x80 | ((inBuf[i+L_3] & 0x3F) >> 0);
-
- len += 2;
- } else {
- /* 0000 0000-0000 007F -> 0xxxxxx */
- /* 00000000 00000000 00000000 0abcdefg ->
- 0abcdefg */
-
- outBuf[len+0] = (inBuf[i+L_3] & 0x7F);
-
- len += 1;
- }
- }
-
- *outBufLen = len;
- return PR_TRUE;
- }
-}
-
-PRBool
-sec_port_ucs2_utf8_conversion_function
-(
- PRBool toUnicode,
- unsigned char *inBuf,
- unsigned int inBufLen,
- unsigned char *outBuf,
- unsigned int maxOutBufLen,
- unsigned int *outBufLen
-)
-{
- PORT_Assert((unsigned int *)NULL != outBufLen);
-
- if( toUnicode ) {
- unsigned int i, len = 0;
-
- for( i = 0; i < inBufLen; ) {
- if( (inBuf[i] & 0x80) == 0x00 ) {
- i += 1;
- len += 2;
- } else if( (inBuf[i] & 0xE0) == 0xC0 ) {
- i += 2;
- len += 2;
- } else if( (inBuf[i] & 0xF0) == 0xE0 ) {
- i += 3;
- len += 2;
- } else if( (inBuf[i] & 0xF8) == 0xF0 ) {
- i += 4;
- len += 4;
- } else return PR_FALSE;
- }
-
- if( len > maxOutBufLen ) {
- *outBufLen = len;
- return PR_FALSE;
- }
-
- len = 0;
-
- for( i = 0; i < inBufLen; ) {
- PRUint32 ucs4 = sec_port_read_utf8(&i, inBuf, inBufLen);
-
- if (ucs4 == BAD_UTF8) return PR_FALSE;
-
- if( ucs4 < 0x10000) {
- outBuf[len+H_0] = (unsigned char)(ucs4 >> 8);
- outBuf[len+H_1] = (unsigned char)ucs4;
- len += 2;
- } else {
- ucs4 -= 0x10000;
- outBuf[len+0+H_0] = (unsigned char)(0xD8 | ((ucs4 >> 18) & 0x3));
- outBuf[len+0+H_1] = (unsigned char)(ucs4 >> 10);
- outBuf[len+2+H_0] = (unsigned char)(0xDC | ((ucs4 >> 8) & 0x3));
- outBuf[len+2+H_1] = (unsigned char)ucs4;
- len += 4;
- }
- }
-
- *outBufLen = len;
- return PR_TRUE;
- } else {
- unsigned int i, len = 0;
- PORT_Assert((inBufLen % 2) == 0);
- if ((inBufLen % 2) != 0) {
- *outBufLen = 0;
- return PR_FALSE;
- }
-
- for( i = 0; i < inBufLen; i += 2 ) {
- if( (inBuf[i+H_0] == 0x00) && ((inBuf[i+H_0] & 0x80) == 0x00) ) len += 1;
- else if( inBuf[i+H_0] < 0x08 ) len += 2;
- else if( ((inBuf[i+0+H_0] & 0xDC) == 0xD8) ) {
- if( ((inBuf[i+2+H_0] & 0xDC) == 0xDC) && ((inBufLen - i) > 2) ) {
- i += 2;
- len += 4;
- } else {
- return PR_FALSE;
- }
- }
- else len += 3;
- }
-
- if( len > maxOutBufLen ) {
- *outBufLen = len;
- return PR_FALSE;
- }
-
- len = 0;
-
- for( i = 0; i < inBufLen; i += 2 ) {
- if( (inBuf[i+H_0] == 0x00) && ((inBuf[i+H_1] & 0x80) == 0x00) ) {
- /* 0000-007F -> 0xxxxxx */
- /* 00000000 0abcdefg -> 0abcdefg */
-
- outBuf[len] = inBuf[i+H_1] & 0x7F;
-
- len += 1;
- } else if( inBuf[i+H_0] < 0x08 ) {
- /* 0080-07FF -> 110xxxxx 10xxxxxx */
- /* 00000abc defghijk -> 110abcde 10fghijk */
-
- outBuf[len+0] = 0xC0 | ((inBuf[i+H_0] & 0x07) << 2)
- | ((inBuf[i+H_1] & 0xC0) >> 6);
- outBuf[len+1] = 0x80 | ((inBuf[i+H_1] & 0x3F) >> 0);
-
- len += 2;
- } else if( (inBuf[i+H_0] & 0xDC) == 0xD8 ) {
- int abcde, BCDE;
-
- PORT_Assert(((inBuf[i+2+H_0] & 0xDC) == 0xDC) && ((inBufLen - i) > 2));
-
- /* D800-DBFF DC00-DFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
- /* 110110BC DEfghijk 110111lm nopqrstu ->
- { Let abcde = BCDE + 1 }
- 11110abc 10defghi 10jklmno 10pqrstu */
-
- BCDE = ((inBuf[i+H_0] & 0x03) << 2) | ((inBuf[i+H_1] & 0xC0) >> 6);
- abcde = BCDE + 1;
-
- outBuf[len+0] = 0xF0 | ((abcde & 0x1C) >> 2);
- outBuf[len+1] = 0x80 | ((abcde & 0x03) << 4)
- | ((inBuf[i+0+H_1] & 0x3C) >> 2);
- outBuf[len+2] = 0x80 | ((inBuf[i+0+H_1] & 0x03) << 4)
- | ((inBuf[i+2+H_0] & 0x03) << 2)
- | ((inBuf[i+2+H_1] & 0xC0) >> 6);
- outBuf[len+3] = 0x80 | ((inBuf[i+2+H_1] & 0x3F) >> 0);
-
- i += 2;
- len += 4;
- } else {
- /* 0800-FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
- /* abcdefgh ijklmnop -> 1110abcd 10efghij 10klmnop */
-
- outBuf[len+0] = 0xE0 | ((inBuf[i+H_0] & 0xF0) >> 4);
- outBuf[len+1] = 0x80 | ((inBuf[i+H_0] & 0x0F) << 2)
- | ((inBuf[i+H_1] & 0xC0) >> 6);
- outBuf[len+2] = 0x80 | ((inBuf[i+H_1] & 0x3F) >> 0);
-
- len += 3;
- }
- }
-
- *outBufLen = len;
- return PR_TRUE;
- }
-}
-
-PRBool
-sec_port_iso88591_utf8_conversion_function
-(
- const unsigned char *inBuf,
- unsigned int inBufLen,
- unsigned char *outBuf,
- unsigned int maxOutBufLen,
- unsigned int *outBufLen
-)
-{
- unsigned int i, len = 0;
-
- PORT_Assert((unsigned int *)NULL != outBufLen);
-
- for( i = 0; i < inBufLen; i++) {
- if( (inBuf[i] & 0x80) == 0x00 ) len += 1;
- else len += 2;
- }
-
- if( len > maxOutBufLen ) {
- *outBufLen = len;
- return PR_FALSE;
- }
-
- len = 0;
-
- for( i = 0; i < inBufLen; i++) {
- if( (inBuf[i] & 0x80) == 0x00 ) {
- /* 00-7F -> 0xxxxxxx */
- /* 0abcdefg -> 0abcdefg */
-
- outBuf[len] = inBuf[i];
- len += 1;
- } else {
- /* 80-FF <- 110xxxxx 10xxxxxx */
- /* 00000000 abcdefgh -> 110000ab 10cdefgh */
-
- outBuf[len+0] = 0xC0 | ((inBuf[i] & 0xC0) >> 6);
- outBuf[len+1] = 0x80 | ((inBuf[i] & 0x3F) >> 0);
-
- len += 2;
- }
- }
-
- *outBufLen = len;
- return PR_TRUE;
-}
-
-#ifdef TEST_UTF8
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <netinet/in.h> /* for htonl and htons */
-
-/*
- * UCS-4 vectors
- */
-
-struct ucs4 {
- PRUint32 c;
- char *utf8;
-};
-
-/*
- * UCS-2 vectors
- */
-
-struct ucs2 {
- PRUint16 c;
- char *utf8;
-};
-
-/*
- * UTF-16 vectors
- */
-
-struct utf16 {
- PRUint32 c;
- PRUint16 w[2];
-};
-
-
-/*
- * UCS-4 vectors
- */
-
-struct ucs4 ucs4[] = {
- { 0x00000001, "\x01" },
- { 0x00000002, "\x02" },
- { 0x00000003, "\x03" },
- { 0x00000004, "\x04" },
- { 0x00000007, "\x07" },
- { 0x00000008, "\x08" },
- { 0x0000000F, "\x0F" },
- { 0x00000010, "\x10" },
- { 0x0000001F, "\x1F" },
- { 0x00000020, "\x20" },
- { 0x0000003F, "\x3F" },
- { 0x00000040, "\x40" },
- { 0x0000007F, "\x7F" },
-
- { 0x00000080, "\xC2\x80" },
- { 0x00000081, "\xC2\x81" },
- { 0x00000082, "\xC2\x82" },
- { 0x00000084, "\xC2\x84" },
- { 0x00000088, "\xC2\x88" },
- { 0x00000090, "\xC2\x90" },
- { 0x000000A0, "\xC2\xA0" },
- { 0x000000C0, "\xC3\x80" },
- { 0x000000FF, "\xC3\xBF" },
- { 0x00000100, "\xC4\x80" },
- { 0x00000101, "\xC4\x81" },
- { 0x00000102, "\xC4\x82" },
- { 0x00000104, "\xC4\x84" },
- { 0x00000108, "\xC4\x88" },
- { 0x00000110, "\xC4\x90" },
- { 0x00000120, "\xC4\xA0" },
- { 0x00000140, "\xC5\x80" },
- { 0x00000180, "\xC6\x80" },
- { 0x000001FF, "\xC7\xBF" },
- { 0x00000200, "\xC8\x80" },
- { 0x00000201, "\xC8\x81" },
- { 0x00000202, "\xC8\x82" },
- { 0x00000204, "\xC8\x84" },
- { 0x00000208, "\xC8\x88" },
- { 0x00000210, "\xC8\x90" },
- { 0x00000220, "\xC8\xA0" },
- { 0x00000240, "\xC9\x80" },
- { 0x00000280, "\xCA\x80" },
- { 0x00000300, "\xCC\x80" },
- { 0x000003FF, "\xCF\xBF" },
- { 0x00000400, "\xD0\x80" },
- { 0x00000401, "\xD0\x81" },
- { 0x00000402, "\xD0\x82" },
- { 0x00000404, "\xD0\x84" },
- { 0x00000408, "\xD0\x88" },
- { 0x00000410, "\xD0\x90" },
- { 0x00000420, "\xD0\xA0" },
- { 0x00000440, "\xD1\x80" },
- { 0x00000480, "\xD2\x80" },
- { 0x00000500, "\xD4\x80" },
- { 0x00000600, "\xD8\x80" },
- { 0x000007FF, "\xDF\xBF" },
-
- { 0x00000800, "\xE0\xA0\x80" },
- { 0x00000801, "\xE0\xA0\x81" },
- { 0x00000802, "\xE0\xA0\x82" },
- { 0x00000804, "\xE0\xA0\x84" },
- { 0x00000808, "\xE0\xA0\x88" },
- { 0x00000810, "\xE0\xA0\x90" },
- { 0x00000820, "\xE0\xA0\xA0" },
- { 0x00000840, "\xE0\xA1\x80" },
- { 0x00000880, "\xE0\xA2\x80" },
- { 0x00000900, "\xE0\xA4\x80" },
- { 0x00000A00, "\xE0\xA8\x80" },
- { 0x00000C00, "\xE0\xB0\x80" },
- { 0x00000FFF, "\xE0\xBF\xBF" },
- { 0x00001000, "\xE1\x80\x80" },
- { 0x00001001, "\xE1\x80\x81" },
- { 0x00001002, "\xE1\x80\x82" },
- { 0x00001004, "\xE1\x80\x84" },
- { 0x00001008, "\xE1\x80\x88" },
- { 0x00001010, "\xE1\x80\x90" },
- { 0x00001020, "\xE1\x80\xA0" },
- { 0x00001040, "\xE1\x81\x80" },
- { 0x00001080, "\xE1\x82\x80" },
- { 0x00001100, "\xE1\x84\x80" },
- { 0x00001200, "\xE1\x88\x80" },
- { 0x00001400, "\xE1\x90\x80" },
- { 0x00001800, "\xE1\xA0\x80" },
- { 0x00001FFF, "\xE1\xBF\xBF" },
- { 0x00002000, "\xE2\x80\x80" },
- { 0x00002001, "\xE2\x80\x81" },
- { 0x00002002, "\xE2\x80\x82" },
- { 0x00002004, "\xE2\x80\x84" },
- { 0x00002008, "\xE2\x80\x88" },
- { 0x00002010, "\xE2\x80\x90" },
- { 0x00002020, "\xE2\x80\xA0" },
- { 0x00002040, "\xE2\x81\x80" },
- { 0x00002080, "\xE2\x82\x80" },
- { 0x00002100, "\xE2\x84\x80" },
- { 0x00002200, "\xE2\x88\x80" },
- { 0x00002400, "\xE2\x90\x80" },
- { 0x00002800, "\xE2\xA0\x80" },
- { 0x00003000, "\xE3\x80\x80" },
- { 0x00003FFF, "\xE3\xBF\xBF" },
- { 0x00004000, "\xE4\x80\x80" },
- { 0x00004001, "\xE4\x80\x81" },
- { 0x00004002, "\xE4\x80\x82" },
- { 0x00004004, "\xE4\x80\x84" },
- { 0x00004008, "\xE4\x80\x88" },
- { 0x00004010, "\xE4\x80\x90" },
- { 0x00004020, "\xE4\x80\xA0" },
- { 0x00004040, "\xE4\x81\x80" },
- { 0x00004080, "\xE4\x82\x80" },
- { 0x00004100, "\xE4\x84\x80" },
- { 0x00004200, "\xE4\x88\x80" },
- { 0x00004400, "\xE4\x90\x80" },
- { 0x00004800, "\xE4\xA0\x80" },
- { 0x00005000, "\xE5\x80\x80" },
- { 0x00006000, "\xE6\x80\x80" },
- { 0x00007FFF, "\xE7\xBF\xBF" },
- { 0x00008000, "\xE8\x80\x80" },
- { 0x00008001, "\xE8\x80\x81" },
- { 0x00008002, "\xE8\x80\x82" },
- { 0x00008004, "\xE8\x80\x84" },
- { 0x00008008, "\xE8\x80\x88" },
- { 0x00008010, "\xE8\x80\x90" },
- { 0x00008020, "\xE8\x80\xA0" },
- { 0x00008040, "\xE8\x81\x80" },
- { 0x00008080, "\xE8\x82\x80" },
- { 0x00008100, "\xE8\x84\x80" },
- { 0x00008200, "\xE8\x88\x80" },
- { 0x00008400, "\xE8\x90\x80" },
- { 0x00008800, "\xE8\xA0\x80" },
- { 0x00009000, "\xE9\x80\x80" },
- { 0x0000A000, "\xEA\x80\x80" },
- { 0x0000C000, "\xEC\x80\x80" },
- { 0x0000FFFF, "\xEF\xBF\xBF" },
-
- { 0x00010000, "\xF0\x90\x80\x80" },
- { 0x00010001, "\xF0\x90\x80\x81" },
- { 0x00010002, "\xF0\x90\x80\x82" },
- { 0x00010004, "\xF0\x90\x80\x84" },
- { 0x00010008, "\xF0\x90\x80\x88" },
- { 0x00010010, "\xF0\x90\x80\x90" },
- { 0x00010020, "\xF0\x90\x80\xA0" },
- { 0x00010040, "\xF0\x90\x81\x80" },
- { 0x00010080, "\xF0\x90\x82\x80" },
- { 0x00010100, "\xF0\x90\x84\x80" },
- { 0x00010200, "\xF0\x90\x88\x80" },
- { 0x00010400, "\xF0\x90\x90\x80" },
- { 0x00010800, "\xF0\x90\xA0\x80" },
- { 0x00011000, "\xF0\x91\x80\x80" },
- { 0x00012000, "\xF0\x92\x80\x80" },
- { 0x00014000, "\xF0\x94\x80\x80" },
- { 0x00018000, "\xF0\x98\x80\x80" },
- { 0x0001FFFF, "\xF0\x9F\xBF\xBF" },
- { 0x00020000, "\xF0\xA0\x80\x80" },
- { 0x00020001, "\xF0\xA0\x80\x81" },
- { 0x00020002, "\xF0\xA0\x80\x82" },
- { 0x00020004, "\xF0\xA0\x80\x84" },
- { 0x00020008, "\xF0\xA0\x80\x88" },
- { 0x00020010, "\xF0\xA0\x80\x90" },
- { 0x00020020, "\xF0\xA0\x80\xA0" },
- { 0x00020040, "\xF0\xA0\x81\x80" },
- { 0x00020080, "\xF0\xA0\x82\x80" },
- { 0x00020100, "\xF0\xA0\x84\x80" },
- { 0x00020200, "\xF0\xA0\x88\x80" },
- { 0x00020400, "\xF0\xA0\x90\x80" },
- { 0x00020800, "\xF0\xA0\xA0\x80" },
- { 0x00021000, "\xF0\xA1\x80\x80" },
- { 0x00022000, "\xF0\xA2\x80\x80" },
- { 0x00024000, "\xF0\xA4\x80\x80" },
- { 0x00028000, "\xF0\xA8\x80\x80" },
- { 0x00030000, "\xF0\xB0\x80\x80" },
- { 0x0003FFFF, "\xF0\xBF\xBF\xBF" },
- { 0x00040000, "\xF1\x80\x80\x80" },
- { 0x00040001, "\xF1\x80\x80\x81" },
- { 0x00040002, "\xF1\x80\x80\x82" },
- { 0x00040004, "\xF1\x80\x80\x84" },
- { 0x00040008, "\xF1\x80\x80\x88" },
- { 0x00040010, "\xF1\x80\x80\x90" },
- { 0x00040020, "\xF1\x80\x80\xA0" },
- { 0x00040040, "\xF1\x80\x81\x80" },
- { 0x00040080, "\xF1\x80\x82\x80" },
- { 0x00040100, "\xF1\x80\x84\x80" },
- { 0x00040200, "\xF1\x80\x88\x80" },
- { 0x00040400, "\xF1\x80\x90\x80" },
- { 0x00040800, "\xF1\x80\xA0\x80" },
- { 0x00041000, "\xF1\x81\x80\x80" },
- { 0x00042000, "\xF1\x82\x80\x80" },
- { 0x00044000, "\xF1\x84\x80\x80" },
- { 0x00048000, "\xF1\x88\x80\x80" },
- { 0x00050000, "\xF1\x90\x80\x80" },
- { 0x00060000, "\xF1\xA0\x80\x80" },
- { 0x0007FFFF, "\xF1\xBF\xBF\xBF" },
- { 0x00080000, "\xF2\x80\x80\x80" },
- { 0x00080001, "\xF2\x80\x80\x81" },
- { 0x00080002, "\xF2\x80\x80\x82" },
- { 0x00080004, "\xF2\x80\x80\x84" },
- { 0x00080008, "\xF2\x80\x80\x88" },
- { 0x00080010, "\xF2\x80\x80\x90" },
- { 0x00080020, "\xF2\x80\x80\xA0" },
- { 0x00080040, "\xF2\x80\x81\x80" },
- { 0x00080080, "\xF2\x80\x82\x80" },
- { 0x00080100, "\xF2\x80\x84\x80" },
- { 0x00080200, "\xF2\x80\x88\x80" },
- { 0x00080400, "\xF2\x80\x90\x80" },
- { 0x00080800, "\xF2\x80\xA0\x80" },
- { 0x00081000, "\xF2\x81\x80\x80" },
- { 0x00082000, "\xF2\x82\x80\x80" },
- { 0x00084000, "\xF2\x84\x80\x80" },
- { 0x00088000, "\xF2\x88\x80\x80" },
- { 0x00090000, "\xF2\x90\x80\x80" },
- { 0x000A0000, "\xF2\xA0\x80\x80" },
- { 0x000C0000, "\xF3\x80\x80\x80" },
- { 0x000FFFFF, "\xF3\xBF\xBF\xBF" },
- { 0x00100000, "\xF4\x80\x80\x80" },
- { 0x00100001, "\xF4\x80\x80\x81" },
- { 0x00100002, "\xF4\x80\x80\x82" },
- { 0x00100004, "\xF4\x80\x80\x84" },
- { 0x00100008, "\xF4\x80\x80\x88" },
- { 0x00100010, "\xF4\x80\x80\x90" },
- { 0x00100020, "\xF4\x80\x80\xA0" },
- { 0x00100040, "\xF4\x80\x81\x80" },
- { 0x00100080, "\xF4\x80\x82\x80" },
- { 0x00100100, "\xF4\x80\x84\x80" },
- { 0x00100200, "\xF4\x80\x88\x80" },
- { 0x00100400, "\xF4\x80\x90\x80" },
- { 0x00100800, "\xF4\x80\xA0\x80" },
- { 0x00101000, "\xF4\x81\x80\x80" },
- { 0x00102000, "\xF4\x82\x80\x80" },
- { 0x00104000, "\xF4\x84\x80\x80" },
- { 0x00108000, "\xF4\x88\x80\x80" },
- { 0x0010FFFF, "\xF4\x8F\xBF\xBF" },
-};
-
-/*
- * UCS-2 vectors
- */
-
-struct ucs2 ucs2[] = {
- { 0x0001, "\x01" },
- { 0x0002, "\x02" },
- { 0x0003, "\x03" },
- { 0x0004, "\x04" },
- { 0x0007, "\x07" },
- { 0x0008, "\x08" },
- { 0x000F, "\x0F" },
- { 0x0010, "\x10" },
- { 0x001F, "\x1F" },
- { 0x0020, "\x20" },
- { 0x003F, "\x3F" },
- { 0x0040, "\x40" },
- { 0x007F, "\x7F" },
-
- { 0x0080, "\xC2\x80" },
- { 0x0081, "\xC2\x81" },
- { 0x0082, "\xC2\x82" },
- { 0x0084, "\xC2\x84" },
- { 0x0088, "\xC2\x88" },
- { 0x0090, "\xC2\x90" },
- { 0x00A0, "\xC2\xA0" },
- { 0x00C0, "\xC3\x80" },
- { 0x00FF, "\xC3\xBF" },
- { 0x0100, "\xC4\x80" },
- { 0x0101, "\xC4\x81" },
- { 0x0102, "\xC4\x82" },
- { 0x0104, "\xC4\x84" },
- { 0x0108, "\xC4\x88" },
- { 0x0110, "\xC4\x90" },
- { 0x0120, "\xC4\xA0" },
- { 0x0140, "\xC5\x80" },
- { 0x0180, "\xC6\x80" },
- { 0x01FF, "\xC7\xBF" },
- { 0x0200, "\xC8\x80" },
- { 0x0201, "\xC8\x81" },
- { 0x0202, "\xC8\x82" },
- { 0x0204, "\xC8\x84" },
- { 0x0208, "\xC8\x88" },
- { 0x0210, "\xC8\x90" },
- { 0x0220, "\xC8\xA0" },
- { 0x0240, "\xC9\x80" },
- { 0x0280, "\xCA\x80" },
- { 0x0300, "\xCC\x80" },
- { 0x03FF, "\xCF\xBF" },
- { 0x0400, "\xD0\x80" },
- { 0x0401, "\xD0\x81" },
- { 0x0402, "\xD0\x82" },
- { 0x0404, "\xD0\x84" },
- { 0x0408, "\xD0\x88" },
- { 0x0410, "\xD0\x90" },
- { 0x0420, "\xD0\xA0" },
- { 0x0440, "\xD1\x80" },
- { 0x0480, "\xD2\x80" },
- { 0x0500, "\xD4\x80" },
- { 0x0600, "\xD8\x80" },
- { 0x07FF, "\xDF\xBF" },
-
- { 0x0800, "\xE0\xA0\x80" },
- { 0x0801, "\xE0\xA0\x81" },
- { 0x0802, "\xE0\xA0\x82" },
- { 0x0804, "\xE0\xA0\x84" },
- { 0x0808, "\xE0\xA0\x88" },
- { 0x0810, "\xE0\xA0\x90" },
- { 0x0820, "\xE0\xA0\xA0" },
- { 0x0840, "\xE0\xA1\x80" },
- { 0x0880, "\xE0\xA2\x80" },
- { 0x0900, "\xE0\xA4\x80" },
- { 0x0A00, "\xE0\xA8\x80" },
- { 0x0C00, "\xE0\xB0\x80" },
- { 0x0FFF, "\xE0\xBF\xBF" },
- { 0x1000, "\xE1\x80\x80" },
- { 0x1001, "\xE1\x80\x81" },
- { 0x1002, "\xE1\x80\x82" },
- { 0x1004, "\xE1\x80\x84" },
- { 0x1008, "\xE1\x80\x88" },
- { 0x1010, "\xE1\x80\x90" },
- { 0x1020, "\xE1\x80\xA0" },
- { 0x1040, "\xE1\x81\x80" },
- { 0x1080, "\xE1\x82\x80" },
- { 0x1100, "\xE1\x84\x80" },
- { 0x1200, "\xE1\x88\x80" },
- { 0x1400, "\xE1\x90\x80" },
- { 0x1800, "\xE1\xA0\x80" },
- { 0x1FFF, "\xE1\xBF\xBF" },
- { 0x2000, "\xE2\x80\x80" },
- { 0x2001, "\xE2\x80\x81" },
- { 0x2002, "\xE2\x80\x82" },
- { 0x2004, "\xE2\x80\x84" },
- { 0x2008, "\xE2\x80\x88" },
- { 0x2010, "\xE2\x80\x90" },
- { 0x2020, "\xE2\x80\xA0" },
- { 0x2040, "\xE2\x81\x80" },
- { 0x2080, "\xE2\x82\x80" },
- { 0x2100, "\xE2\x84\x80" },
- { 0x2200, "\xE2\x88\x80" },
- { 0x2400, "\xE2\x90\x80" },
- { 0x2800, "\xE2\xA0\x80" },
- { 0x3000, "\xE3\x80\x80" },
- { 0x3FFF, "\xE3\xBF\xBF" },
- { 0x4000, "\xE4\x80\x80" },
- { 0x4001, "\xE4\x80\x81" },
- { 0x4002, "\xE4\x80\x82" },
- { 0x4004, "\xE4\x80\x84" },
- { 0x4008, "\xE4\x80\x88" },
- { 0x4010, "\xE4\x80\x90" },
- { 0x4020, "\xE4\x80\xA0" },
- { 0x4040, "\xE4\x81\x80" },
- { 0x4080, "\xE4\x82\x80" },
- { 0x4100, "\xE4\x84\x80" },
- { 0x4200, "\xE4\x88\x80" },
- { 0x4400, "\xE4\x90\x80" },
- { 0x4800, "\xE4\xA0\x80" },
- { 0x5000, "\xE5\x80\x80" },
- { 0x6000, "\xE6\x80\x80" },
- { 0x7FFF, "\xE7\xBF\xBF" },
- { 0x8000, "\xE8\x80\x80" },
- { 0x8001, "\xE8\x80\x81" },
- { 0x8002, "\xE8\x80\x82" },
- { 0x8004, "\xE8\x80\x84" },
- { 0x8008, "\xE8\x80\x88" },
- { 0x8010, "\xE8\x80\x90" },
- { 0x8020, "\xE8\x80\xA0" },
- { 0x8040, "\xE8\x81\x80" },
- { 0x8080, "\xE8\x82\x80" },
- { 0x8100, "\xE8\x84\x80" },
- { 0x8200, "\xE8\x88\x80" },
- { 0x8400, "\xE8\x90\x80" },
- { 0x8800, "\xE8\xA0\x80" },
- { 0x9000, "\xE9\x80\x80" },
- { 0xA000, "\xEA\x80\x80" },
- { 0xC000, "\xEC\x80\x80" },
- { 0xFFFF, "\xEF\xBF\xBF" }
-
-};
-
-/*
- * UTF-16 vectors
- */
-
-struct utf16 utf16[] = {
- { 0x00010000, { 0xD800, 0xDC00 } },
- { 0x00010001, { 0xD800, 0xDC01 } },
- { 0x00010002, { 0xD800, 0xDC02 } },
- { 0x00010003, { 0xD800, 0xDC03 } },
- { 0x00010004, { 0xD800, 0xDC04 } },
- { 0x00010007, { 0xD800, 0xDC07 } },
- { 0x00010008, { 0xD800, 0xDC08 } },
- { 0x0001000F, { 0xD800, 0xDC0F } },
- { 0x00010010, { 0xD800, 0xDC10 } },
- { 0x0001001F, { 0xD800, 0xDC1F } },
- { 0x00010020, { 0xD800, 0xDC20 } },
- { 0x0001003F, { 0xD800, 0xDC3F } },
- { 0x00010040, { 0xD800, 0xDC40 } },
- { 0x0001007F, { 0xD800, 0xDC7F } },
- { 0x00010080, { 0xD800, 0xDC80 } },
- { 0x00010081, { 0xD800, 0xDC81 } },
- { 0x00010082, { 0xD800, 0xDC82 } },
- { 0x00010084, { 0xD800, 0xDC84 } },
- { 0x00010088, { 0xD800, 0xDC88 } },
- { 0x00010090, { 0xD800, 0xDC90 } },
- { 0x000100A0, { 0xD800, 0xDCA0 } },
- { 0x000100C0, { 0xD800, 0xDCC0 } },
- { 0x000100FF, { 0xD800, 0xDCFF } },
- { 0x00010100, { 0xD800, 0xDD00 } },
- { 0x00010101, { 0xD800, 0xDD01 } },
- { 0x00010102, { 0xD800, 0xDD02 } },
- { 0x00010104, { 0xD800, 0xDD04 } },
- { 0x00010108, { 0xD800, 0xDD08 } },
- { 0x00010110, { 0xD800, 0xDD10 } },
- { 0x00010120, { 0xD800, 0xDD20 } },
- { 0x00010140, { 0xD800, 0xDD40 } },
- { 0x00010180, { 0xD800, 0xDD80 } },
- { 0x000101FF, { 0xD800, 0xDDFF } },
- { 0x00010200, { 0xD800, 0xDE00 } },
- { 0x00010201, { 0xD800, 0xDE01 } },
- { 0x00010202, { 0xD800, 0xDE02 } },
- { 0x00010204, { 0xD800, 0xDE04 } },
- { 0x00010208, { 0xD800, 0xDE08 } },
- { 0x00010210, { 0xD800, 0xDE10 } },
- { 0x00010220, { 0xD800, 0xDE20 } },
- { 0x00010240, { 0xD800, 0xDE40 } },
- { 0x00010280, { 0xD800, 0xDE80 } },
- { 0x00010300, { 0xD800, 0xDF00 } },
- { 0x000103FF, { 0xD800, 0xDFFF } },
- { 0x00010400, { 0xD801, 0xDC00 } },
- { 0x00010401, { 0xD801, 0xDC01 } },
- { 0x00010402, { 0xD801, 0xDC02 } },
- { 0x00010404, { 0xD801, 0xDC04 } },
- { 0x00010408, { 0xD801, 0xDC08 } },
- { 0x00010410, { 0xD801, 0xDC10 } },
- { 0x00010420, { 0xD801, 0xDC20 } },
- { 0x00010440, { 0xD801, 0xDC40 } },
- { 0x00010480, { 0xD801, 0xDC80 } },
- { 0x00010500, { 0xD801, 0xDD00 } },
- { 0x00010600, { 0xD801, 0xDE00 } },
- { 0x000107FF, { 0xD801, 0xDFFF } },
- { 0x00010800, { 0xD802, 0xDC00 } },
- { 0x00010801, { 0xD802, 0xDC01 } },
- { 0x00010802, { 0xD802, 0xDC02 } },
- { 0x00010804, { 0xD802, 0xDC04 } },
- { 0x00010808, { 0xD802, 0xDC08 } },
- { 0x00010810, { 0xD802, 0xDC10 } },
- { 0x00010820, { 0xD802, 0xDC20 } },
- { 0x00010840, { 0xD802, 0xDC40 } },
- { 0x00010880, { 0xD802, 0xDC80 } },
- { 0x00010900, { 0xD802, 0xDD00 } },
- { 0x00010A00, { 0xD802, 0xDE00 } },
- { 0x00010C00, { 0xD803, 0xDC00 } },
- { 0x00010FFF, { 0xD803, 0xDFFF } },
- { 0x00011000, { 0xD804, 0xDC00 } },
- { 0x00011001, { 0xD804, 0xDC01 } },
- { 0x00011002, { 0xD804, 0xDC02 } },
- { 0x00011004, { 0xD804, 0xDC04 } },
- { 0x00011008, { 0xD804, 0xDC08 } },
- { 0x00011010, { 0xD804, 0xDC10 } },
- { 0x00011020, { 0xD804, 0xDC20 } },
- { 0x00011040, { 0xD804, 0xDC40 } },
- { 0x00011080, { 0xD804, 0xDC80 } },
- { 0x00011100, { 0xD804, 0xDD00 } },
- { 0x00011200, { 0xD804, 0xDE00 } },
- { 0x00011400, { 0xD805, 0xDC00 } },
- { 0x00011800, { 0xD806, 0xDC00 } },
- { 0x00011FFF, { 0xD807, 0xDFFF } },
- { 0x00012000, { 0xD808, 0xDC00 } },
- { 0x00012001, { 0xD808, 0xDC01 } },
- { 0x00012002, { 0xD808, 0xDC02 } },
- { 0x00012004, { 0xD808, 0xDC04 } },
- { 0x00012008, { 0xD808, 0xDC08 } },
- { 0x00012010, { 0xD808, 0xDC10 } },
- { 0x00012020, { 0xD808, 0xDC20 } },
- { 0x00012040, { 0xD808, 0xDC40 } },
- { 0x00012080, { 0xD808, 0xDC80 } },
- { 0x00012100, { 0xD808, 0xDD00 } },
- { 0x00012200, { 0xD808, 0xDE00 } },
- { 0x00012400, { 0xD809, 0xDC00 } },
- { 0x00012800, { 0xD80A, 0xDC00 } },
- { 0x00013000, { 0xD80C, 0xDC00 } },
- { 0x00013FFF, { 0xD80F, 0xDFFF } },
- { 0x00014000, { 0xD810, 0xDC00 } },
- { 0x00014001, { 0xD810, 0xDC01 } },
- { 0x00014002, { 0xD810, 0xDC02 } },
- { 0x00014004, { 0xD810, 0xDC04 } },
- { 0x00014008, { 0xD810, 0xDC08 } },
- { 0x00014010, { 0xD810, 0xDC10 } },
- { 0x00014020, { 0xD810, 0xDC20 } },
- { 0x00014040, { 0xD810, 0xDC40 } },
- { 0x00014080, { 0xD810, 0xDC80 } },
- { 0x00014100, { 0xD810, 0xDD00 } },
- { 0x00014200, { 0xD810, 0xDE00 } },
- { 0x00014400, { 0xD811, 0xDC00 } },
- { 0x00014800, { 0xD812, 0xDC00 } },
- { 0x00015000, { 0xD814, 0xDC00 } },
- { 0x00016000, { 0xD818, 0xDC00 } },
- { 0x00017FFF, { 0xD81F, 0xDFFF } },
- { 0x00018000, { 0xD820, 0xDC00 } },
- { 0x00018001, { 0xD820, 0xDC01 } },
- { 0x00018002, { 0xD820, 0xDC02 } },
- { 0x00018004, { 0xD820, 0xDC04 } },
- { 0x00018008, { 0xD820, 0xDC08 } },
- { 0x00018010, { 0xD820, 0xDC10 } },
- { 0x00018020, { 0xD820, 0xDC20 } },
- { 0x00018040, { 0xD820, 0xDC40 } },
- { 0x00018080, { 0xD820, 0xDC80 } },
- { 0x00018100, { 0xD820, 0xDD00 } },
- { 0x00018200, { 0xD820, 0xDE00 } },
- { 0x00018400, { 0xD821, 0xDC00 } },
- { 0x00018800, { 0xD822, 0xDC00 } },
- { 0x00019000, { 0xD824, 0xDC00 } },
- { 0x0001A000, { 0xD828, 0xDC00 } },
- { 0x0001C000, { 0xD830, 0xDC00 } },
- { 0x0001FFFF, { 0xD83F, 0xDFFF } },
- { 0x00020000, { 0xD840, 0xDC00 } },
- { 0x00020001, { 0xD840, 0xDC01 } },
- { 0x00020002, { 0xD840, 0xDC02 } },
- { 0x00020004, { 0xD840, 0xDC04 } },
- { 0x00020008, { 0xD840, 0xDC08 } },
- { 0x00020010, { 0xD840, 0xDC10 } },
- { 0x00020020, { 0xD840, 0xDC20 } },
- { 0x00020040, { 0xD840, 0xDC40 } },
- { 0x00020080, { 0xD840, 0xDC80 } },
- { 0x00020100, { 0xD840, 0xDD00 } },
- { 0x00020200, { 0xD840, 0xDE00 } },
- { 0x00020400, { 0xD841, 0xDC00 } },
- { 0x00020800, { 0xD842, 0xDC00 } },
- { 0x00021000, { 0xD844, 0xDC00 } },
- { 0x00022000, { 0xD848, 0xDC00 } },
- { 0x00024000, { 0xD850, 0xDC00 } },
- { 0x00028000, { 0xD860, 0xDC00 } },
- { 0x0002FFFF, { 0xD87F, 0xDFFF } },
- { 0x00030000, { 0xD880, 0xDC00 } },
- { 0x00030001, { 0xD880, 0xDC01 } },
- { 0x00030002, { 0xD880, 0xDC02 } },
- { 0x00030004, { 0xD880, 0xDC04 } },
- { 0x00030008, { 0xD880, 0xDC08 } },
- { 0x00030010, { 0xD880, 0xDC10 } },
- { 0x00030020, { 0xD880, 0xDC20 } },
- { 0x00030040, { 0xD880, 0xDC40 } },
- { 0x00030080, { 0xD880, 0xDC80 } },
- { 0x00030100, { 0xD880, 0xDD00 } },
- { 0x00030200, { 0xD880, 0xDE00 } },
- { 0x00030400, { 0xD881, 0xDC00 } },
- { 0x00030800, { 0xD882, 0xDC00 } },
- { 0x00031000, { 0xD884, 0xDC00 } },
- { 0x00032000, { 0xD888, 0xDC00 } },
- { 0x00034000, { 0xD890, 0xDC00 } },
- { 0x00038000, { 0xD8A0, 0xDC00 } },
- { 0x0003FFFF, { 0xD8BF, 0xDFFF } },
- { 0x00040000, { 0xD8C0, 0xDC00 } },
- { 0x00040001, { 0xD8C0, 0xDC01 } },
- { 0x00040002, { 0xD8C0, 0xDC02 } },
- { 0x00040004, { 0xD8C0, 0xDC04 } },
- { 0x00040008, { 0xD8C0, 0xDC08 } },
- { 0x00040010, { 0xD8C0, 0xDC10 } },
- { 0x00040020, { 0xD8C0, 0xDC20 } },
- { 0x00040040, { 0xD8C0, 0xDC40 } },
- { 0x00040080, { 0xD8C0, 0xDC80 } },
- { 0x00040100, { 0xD8C0, 0xDD00 } },
- { 0x00040200, { 0xD8C0, 0xDE00 } },
- { 0x00040400, { 0xD8C1, 0xDC00 } },
- { 0x00040800, { 0xD8C2, 0xDC00 } },
- { 0x00041000, { 0xD8C4, 0xDC00 } },
- { 0x00042000, { 0xD8C8, 0xDC00 } },
- { 0x00044000, { 0xD8D0, 0xDC00 } },
- { 0x00048000, { 0xD8E0, 0xDC00 } },
- { 0x0004FFFF, { 0xD8FF, 0xDFFF } },
- { 0x00050000, { 0xD900, 0xDC00 } },
- { 0x00050001, { 0xD900, 0xDC01 } },
- { 0x00050002, { 0xD900, 0xDC02 } },
- { 0x00050004, { 0xD900, 0xDC04 } },
- { 0x00050008, { 0xD900, 0xDC08 } },
- { 0x00050010, { 0xD900, 0xDC10 } },
- { 0x00050020, { 0xD900, 0xDC20 } },
- { 0x00050040, { 0xD900, 0xDC40 } },
- { 0x00050080, { 0xD900, 0xDC80 } },
- { 0x00050100, { 0xD900, 0xDD00 } },
- { 0x00050200, { 0xD900, 0xDE00 } },
- { 0x00050400, { 0xD901, 0xDC00 } },
- { 0x00050800, { 0xD902, 0xDC00 } },
- { 0x00051000, { 0xD904, 0xDC00 } },
- { 0x00052000, { 0xD908, 0xDC00 } },
- { 0x00054000, { 0xD910, 0xDC00 } },
- { 0x00058000, { 0xD920, 0xDC00 } },
- { 0x00060000, { 0xD940, 0xDC00 } },
- { 0x00070000, { 0xD980, 0xDC00 } },
- { 0x0007FFFF, { 0xD9BF, 0xDFFF } },
- { 0x00080000, { 0xD9C0, 0xDC00 } },
- { 0x00080001, { 0xD9C0, 0xDC01 } },
- { 0x00080002, { 0xD9C0, 0xDC02 } },
- { 0x00080004, { 0xD9C0, 0xDC04 } },
- { 0x00080008, { 0xD9C0, 0xDC08 } },
- { 0x00080010, { 0xD9C0, 0xDC10 } },
- { 0x00080020, { 0xD9C0, 0xDC20 } },
- { 0x00080040, { 0xD9C0, 0xDC40 } },
- { 0x00080080, { 0xD9C0, 0xDC80 } },
- { 0x00080100, { 0xD9C0, 0xDD00 } },
- { 0x00080200, { 0xD9C0, 0xDE00 } },
- { 0x00080400, { 0xD9C1, 0xDC00 } },
- { 0x00080800, { 0xD9C2, 0xDC00 } },
- { 0x00081000, { 0xD9C4, 0xDC00 } },
- { 0x00082000, { 0xD9C8, 0xDC00 } },
- { 0x00084000, { 0xD9D0, 0xDC00 } },
- { 0x00088000, { 0xD9E0, 0xDC00 } },
- { 0x0008FFFF, { 0xD9FF, 0xDFFF } },
- { 0x00090000, { 0xDA00, 0xDC00 } },
- { 0x00090001, { 0xDA00, 0xDC01 } },
- { 0x00090002, { 0xDA00, 0xDC02 } },
- { 0x00090004, { 0xDA00, 0xDC04 } },
- { 0x00090008, { 0xDA00, 0xDC08 } },
- { 0x00090010, { 0xDA00, 0xDC10 } },
- { 0x00090020, { 0xDA00, 0xDC20 } },
- { 0x00090040, { 0xDA00, 0xDC40 } },
- { 0x00090080, { 0xDA00, 0xDC80 } },
- { 0x00090100, { 0xDA00, 0xDD00 } },
- { 0x00090200, { 0xDA00, 0xDE00 } },
- { 0x00090400, { 0xDA01, 0xDC00 } },
- { 0x00090800, { 0xDA02, 0xDC00 } },
- { 0x00091000, { 0xDA04, 0xDC00 } },
- { 0x00092000, { 0xDA08, 0xDC00 } },
- { 0x00094000, { 0xDA10, 0xDC00 } },
- { 0x00098000, { 0xDA20, 0xDC00 } },
- { 0x000A0000, { 0xDA40, 0xDC00 } },
- { 0x000B0000, { 0xDA80, 0xDC00 } },
- { 0x000C0000, { 0xDAC0, 0xDC00 } },
- { 0x000D0000, { 0xDB00, 0xDC00 } },
- { 0x000FFFFF, { 0xDBBF, 0xDFFF } },
- { 0x0010FFFF, { 0xDBFF, 0xDFFF } }
-
-};
-
-/* illegal utf8 sequences */
-char *utf8_bad[] = {
- "\xC0\x80",
- "\xC1\xBF",
- "\xE0\x80\x80",
- "\xE0\x9F\xBF",
- "\xF0\x80\x80\x80",
- "\xF0\x8F\xBF\xBF",
- "\xF4\x90\x80\x80",
- "\xF7\xBF\xBF\xBF",
- "\xF8\x80\x80\x80\x80",
- "\xF8\x88\x80\x80\x80",
- "\xF8\x92\x80\x80\x80",
- "\xF8\x9F\xBF\xBF\xBF",
- "\xF8\xA0\x80\x80\x80",
- "\xF8\xA8\x80\x80\x80",
- "\xF8\xB0\x80\x80\x80",
- "\xF8\xBF\xBF\xBF\xBF",
- "\xF9\x80\x80\x80\x88",
- "\xF9\x84\x80\x80\x80",
- "\xF9\xBF\xBF\xBF\xBF",
- "\xFA\x80\x80\x80\x80",
- "\xFA\x90\x80\x80\x80",
- "\xFB\xBF\xBF\xBF\xBF",
- "\xFC\x84\x80\x80\x80\x81",
- "\xFC\x85\x80\x80\x80\x80",
- "\xFC\x86\x80\x80\x80\x80",
- "\xFC\x87\xBF\xBF\xBF\xBF",
- "\xFC\x88\xA0\x80\x80\x80",
- "\xFC\x89\x80\x80\x80\x80",
- "\xFC\x8A\x80\x80\x80\x80",
- "\xFC\x90\x80\x80\x80\x82",
- "\xFD\x80\x80\x80\x80\x80",
- "\xFD\xBF\xBF\xBF\xBF\xBF",
- "\x80",
- "\xC3",
- "\xC3\xC3\x80",
- "\xED\xA0\x80",
- "\xED\xBF\x80",
- "\xED\xBF\xBF",
- "\xED\xA0\x80\xE0\xBF\xBF",
-};
-
-static void
-dump_utf8
-(
- char *word,
- unsigned char *utf8,
- char *end
-)
-{
- fprintf(stdout, "%s ", word);
- for( ; *utf8; utf8++ ) {
- fprintf(stdout, "%02.2x ", (unsigned int)*utf8);
- }
- fprintf(stdout, "%s", end);
-}
-
-static PRBool
-test_ucs4_chars
-(
- void
-)
-{
- PRBool rv = PR_TRUE;
- int i;
-
- for( i = 0; i < sizeof(ucs4)/sizeof(ucs4[0]); i++ ) {
- struct ucs4 *e = &ucs4[i];
- PRBool result;
- unsigned char utf8[8];
- unsigned int len = 0;
- PRUint32 back = 0;
-
- (void)memset(utf8, 0, sizeof(utf8));
-
- result = sec_port_ucs4_utf8_conversion_function(PR_FALSE,
- (unsigned char *)&e->c, sizeof(e->c), utf8, sizeof(utf8), &len);
-
- if( !result ) {
- fprintf(stdout, "Failed to convert UCS-4 0x%08.8x to UTF-8\n", e->c);
- rv = PR_FALSE;
- continue;
- }
-
- if( (len >= sizeof(utf8)) ||
- (strlen(e->utf8) != len) ||
- (utf8[len] = '\0', 0 != strcmp(e->utf8, utf8)) ) {
- fprintf(stdout, "Wrong conversion of UCS-4 0x%08.8x to UTF-8: ", e->c);
- dump_utf8("expected", e->utf8, ", ");
- dump_utf8("received", utf8, "\n");
- rv = PR_FALSE;
- continue;
- }
-
- result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
- utf8, len, (unsigned char *)&back, sizeof(back), &len);
-
- if( !result ) {
- dump_utf8("Failed to convert UTF-8", utf8, "to UCS-4\n");
- rv = PR_FALSE;
- continue;
- }
-
- if( (sizeof(back) != len) || (e->c != back) ) {
- dump_utf8("Wrong conversion of UTF-8", utf8, " to UCS-4:");
- fprintf(stdout, "expected 0x%08.8x, received 0x%08.8x\n", e->c, back);
- rv = PR_FALSE;
- continue;
- }
- }
-
- return rv;
-}
-
-static PRBool
-test_ucs2_chars
-(
- void
-)
-{
- PRBool rv = PR_TRUE;
- int i;
-
- for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
- struct ucs2 *e = &ucs2[i];
- PRBool result;
- unsigned char utf8[8];
- unsigned int len = 0;
- PRUint16 back = 0;
-
- (void)memset(utf8, 0, sizeof(utf8));
-
- result = sec_port_ucs2_utf8_conversion_function(PR_FALSE,
- (unsigned char *)&e->c, sizeof(e->c), utf8, sizeof(utf8), &len);
-
- if( !result ) {
- fprintf(stdout, "Failed to convert UCS-2 0x%04.4x to UTF-8\n", e->c);
- rv = PR_FALSE;
- continue;
- }
-
- if( (len >= sizeof(utf8)) ||
- (strlen(e->utf8) != len) ||
- (utf8[len] = '\0', 0 != strcmp(e->utf8, utf8)) ) {
- fprintf(stdout, "Wrong conversion of UCS-2 0x%04.4x to UTF-8: ", e->c);
- dump_utf8("expected", e->utf8, ", ");
- dump_utf8("received", utf8, "\n");
- rv = PR_FALSE;
- continue;
- }
-
- result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
- utf8, len, (unsigned char *)&back, sizeof(back), &len);
-
- if( !result ) {
- dump_utf8("Failed to convert UTF-8", utf8, "to UCS-2\n");
- rv = PR_FALSE;
- continue;
- }
-
- if( (sizeof(back) != len) || (e->c != back) ) {
- dump_utf8("Wrong conversion of UTF-8", utf8, "to UCS-2:");
- fprintf(stdout, "expected 0x%08.8x, received 0x%08.8x\n", e->c, back);
- rv = PR_FALSE;
- continue;
- }
- }
-
- return rv;
-}
-
-static PRBool
-test_utf16_chars
-(
- void
-)
-{
- PRBool rv = PR_TRUE;
- int i;
-
- for( i = 0; i < sizeof(utf16)/sizeof(utf16[0]); i++ ) {
- struct utf16 *e = &utf16[i];
- PRBool result;
- unsigned char utf8[8];
- unsigned int len = 0;
- PRUint32 back32 = 0;
- PRUint16 back[2];
-
- (void)memset(utf8, 0, sizeof(utf8));
-
- result = sec_port_ucs2_utf8_conversion_function(PR_FALSE,
- (unsigned char *)&e->w[0], sizeof(e->w), utf8, sizeof(utf8), &len);
-
- if( !result ) {
- fprintf(stdout, "Failed to convert UTF-16 0x%04.4x 0x%04.4x to UTF-8\n",
- e->w[0], e->w[1]);
- rv = PR_FALSE;
- continue;
- }
-
- result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
- utf8, len, (unsigned char *)&back32, sizeof(back32), &len);
-
- if( 4 != len ) {
- fprintf(stdout, "Failed to convert UTF-16 0x%04.4x 0x%04.4x to UTF-8: "
- "unexpected len %d\n", e->w[0], e->w[1], len);
- rv = PR_FALSE;
- continue;
- }
-
- utf8[len] = '\0'; /* null-terminate for printing */
-
- if( !result ) {
- dump_utf8("Failed to convert UTF-8", utf8, "to UCS-4 (utf-16 test)\n");
- rv = PR_FALSE;
- continue;
- }
-
- if( (sizeof(back32) != len) || (e->c != back32) ) {
- fprintf(stdout, "Wrong conversion of UTF-16 0x%04.4x 0x%04.4x ",
- e->w[0], e->w[1]);
- dump_utf8("to UTF-8", utf8, "and then to UCS-4: ");
- if( sizeof(back32) != len ) {
- fprintf(stdout, "len is %d\n", len);
- } else {
- fprintf(stdout, "expected 0x%08.8x, received 0x%08.8x\n", e->c, back32);
- }
- rv = PR_FALSE;
- continue;
- }
-
- (void)memset(utf8, 0, sizeof(utf8));
- back[0] = back[1] = 0;
-
- result = sec_port_ucs4_utf8_conversion_function(PR_FALSE,
- (unsigned char *)&e->c, sizeof(e->c), utf8, sizeof(utf8), &len);
-
- if( !result ) {
- fprintf(stdout, "Failed to convert UCS-4 0x%08.8x to UTF-8 (utf-16 test)\n",
- e->c);
- rv = PR_FALSE;
- continue;
- }
-
- result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
- utf8, len, (unsigned char *)&back[0], sizeof(back), &len);
-
- if( 4 != len ) {
- fprintf(stdout, "Failed to convert UCS-4 0x%08.8x to UTF-8: "
- "unexpected len %d\n", e->c, len);
- rv = PR_FALSE;
- continue;
- }
-
- utf8[len] = '\0'; /* null-terminate for printing */
-
- if( !result ) {
- dump_utf8("Failed to convert UTF-8", utf8, "to UTF-16\n");
- rv = PR_FALSE;
- continue;
- }
-
- if( (sizeof(back) != len) || (e->w[0] != back[0]) || (e->w[1] != back[1]) ) {
- fprintf(stdout, "Wrong conversion of UCS-4 0x%08.8x to UTF-8", e->c);
- dump_utf8("", utf8, "and then to UTF-16:");
- if( sizeof(back) != len ) {
- fprintf(stdout, "len is %d\n", len);
- } else {
- fprintf(stdout, "expected 0x%04.4x 0x%04.4x, received 0x%04.4x 0x%04.4xx\n",
- e->w[0], e->w[1], back[0], back[1]);
- }
- rv = PR_FALSE;
- continue;
- }
- }
-
- return rv;
-}
-
-static PRBool
-test_utf8_bad_chars
-(
- void
-)
-{
- PRBool rv = PR_TRUE;
- int i;
-
- for( i = 0; i < sizeof(utf8_bad)/sizeof(utf8_bad[0]); i++ ) {
- PRBool result;
- unsigned char destbuf[30];
- unsigned int len = 0;
-
- result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
- (unsigned char *)utf8_bad[i], strlen(utf8_bad[i]), destbuf, sizeof(destbuf), &len);
-
- if( result ) {
- dump_utf8("Failed to detect bad UTF-8 string converting to UCS2: ", utf8_bad[i], "\n");
- rv = PR_FALSE;
- continue;
- }
- result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
- (unsigned char *)utf8_bad[i], strlen(utf8_bad[i]), destbuf, sizeof(destbuf), &len);
-
- if( result ) {
- dump_utf8("Failed to detect bad UTF-8 string converting to UCS4: ", utf8_bad[i], "\n");
- rv = PR_FALSE;
- continue;
- }
-
- }
-
- return rv;
-}
-
-static PRBool
-test_iso88591_chars
-(
- void
-)
-{
- PRBool rv = PR_TRUE;
- int i;
-
- for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
- struct ucs2 *e = &ucs2[i];
- PRBool result;
- unsigned char iso88591;
- unsigned char utf8[3];
- unsigned int len = 0;
-
- if (ntohs(e->c) > 0xFF) continue;
-
- (void)memset(utf8, 0, sizeof(utf8));
- iso88591 = ntohs(e->c);
-
- result = sec_port_iso88591_utf8_conversion_function(&iso88591,
- 1, utf8, sizeof(utf8), &len);
-
- if( !result ) {
- fprintf(stdout, "Failed to convert ISO-8859-1 0x%02.2x to UTF-8\n", iso88591);
- rv = PR_FALSE;
- continue;
- }
-
- if( (len >= sizeof(utf8)) ||
- (strlen(e->utf8) != len) ||
- (utf8[len] = '\0', 0 != strcmp(e->utf8, utf8)) ) {
- fprintf(stdout, "Wrong conversion of ISO-8859-1 0x%02.2x to UTF-8: ", iso88591);
- dump_utf8("expected", e->utf8, ", ");
- dump_utf8("received", utf8, "\n");
- rv = PR_FALSE;
- continue;
- }
-
- }
-
- return rv;
-}
-
-static PRBool
-test_zeroes
-(
- void
-)
-{
- PRBool rv = PR_TRUE;
- PRBool result;
- PRUint32 lzero = 0;
- PRUint16 szero = 0;
- unsigned char utf8[8];
- unsigned int len = 0;
- PRUint32 lback = 1;
- PRUint16 sback = 1;
-
- (void)memset(utf8, 1, sizeof(utf8));
-
- result = sec_port_ucs4_utf8_conversion_function(PR_FALSE,
- (unsigned char *)&lzero, sizeof(lzero), utf8, sizeof(utf8), &len);
-
- if( !result ) {
- fprintf(stdout, "Failed to convert UCS-4 0x00000000 to UTF-8\n");
- rv = PR_FALSE;
- } else if( 1 != len ) {
- fprintf(stdout, "Wrong conversion of UCS-4 0x00000000: len = %d\n", len);
- rv = PR_FALSE;
- } else if( '\0' != *utf8 ) {
- fprintf(stdout, "Wrong conversion of UCS-4 0x00000000: expected 00 ,"
- "received %02.2x\n", (unsigned int)*utf8);
- rv = PR_FALSE;
- }
-
- result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
- "", 1, (unsigned char *)&lback, sizeof(lback), &len);
-
- if( !result ) {
- fprintf(stdout, "Failed to convert UTF-8 00 to UCS-4\n");
- rv = PR_FALSE;
- } else if( 4 != len ) {
- fprintf(stdout, "Wrong conversion of UTF-8 00 to UCS-4: len = %d\n", len);
- rv = PR_FALSE;
- } else if( 0 != lback ) {
- fprintf(stdout, "Wrong conversion of UTF-8 00 to UCS-4: "
- "expected 0x00000000, received 0x%08.8x\n", lback);
- rv = PR_FALSE;
- }
-
- (void)memset(utf8, 1, sizeof(utf8));
-
- result = sec_port_ucs2_utf8_conversion_function(PR_FALSE,
- (unsigned char *)&szero, sizeof(szero), utf8, sizeof(utf8), &len);
-
- if( !result ) {
- fprintf(stdout, "Failed to convert UCS-2 0x0000 to UTF-8\n");
- rv = PR_FALSE;
- } else if( 1 != len ) {
- fprintf(stdout, "Wrong conversion of UCS-2 0x0000: len = %d\n", len);
- rv = PR_FALSE;
- } else if( '\0' != *utf8 ) {
- fprintf(stdout, "Wrong conversion of UCS-2 0x0000: expected 00 ,"
- "received %02.2x\n", (unsigned int)*utf8);
- rv = PR_FALSE;
- }
-
- result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
- "", 1, (unsigned char *)&sback, sizeof(sback), &len);
-
- if( !result ) {
- fprintf(stdout, "Failed to convert UTF-8 00 to UCS-2\n");
- rv = PR_FALSE;
- } else if( 2 != len ) {
- fprintf(stdout, "Wrong conversion of UTF-8 00 to UCS-2: len = %d\n", len);
- rv = PR_FALSE;
- } else if( 0 != sback ) {
- fprintf(stdout, "Wrong conversion of UTF-8 00 to UCS-2: "
- "expected 0x0000, received 0x%04.4x\n", sback);
- rv = PR_FALSE;
- }
-
- return rv;
-}
-
-static PRBool
-test_multichars
-(
- void
-)
-{
- int i;
- unsigned int len, lenout;
- PRUint32 *ucs4s;
- char *ucs4_utf8;
- PRUint16 *ucs2s;
- char *ucs2_utf8;
- void *tmp;
- PRBool result;
-
- ucs4s = (PRUint32 *)calloc(sizeof(ucs4)/sizeof(ucs4[0]), sizeof(PRUint32));
- ucs2s = (PRUint16 *)calloc(sizeof(ucs2)/sizeof(ucs2[0]), sizeof(PRUint16));
-
- if( ((PRUint32 *)NULL == ucs4s) || ((PRUint16 *)NULL == ucs2s) ) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
-
- len = 0;
- for( i = 0; i < sizeof(ucs4)/sizeof(ucs4[0]); i++ ) {
- ucs4s[i] = ucs4[i].c;
- len += strlen(ucs4[i].utf8);
- }
-
- ucs4_utf8 = (char *)malloc(len);
-
- len = 0;
- for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
- ucs2s[i] = ucs2[i].c;
- len += strlen(ucs2[i].utf8);
- }
-
- ucs2_utf8 = (char *)malloc(len);
-
- if( ((char *)NULL == ucs4_utf8) || ((char *)NULL == ucs2_utf8) ) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
-
- *ucs4_utf8 = '\0';
- for( i = 0; i < sizeof(ucs4)/sizeof(ucs4[0]); i++ ) {
- strcat(ucs4_utf8, ucs4[i].utf8);
- }
-
- *ucs2_utf8 = '\0';
- for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
- strcat(ucs2_utf8, ucs2[i].utf8);
- }
-
- /* UTF-8 -> UCS-4 */
- len = sizeof(ucs4)/sizeof(ucs4[0]) * sizeof(PRUint32);
- tmp = calloc(len, 1);
- if( (void *)NULL == tmp ) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
-
- result = sec_port_ucs4_utf8_conversion_function(PR_TRUE,
- ucs4_utf8, strlen(ucs4_utf8), tmp, len, &lenout);
- if( !result ) {
- fprintf(stdout, "Failed to convert much UTF-8 to UCS-4\n");
- goto done;
- }
-
- if( lenout != len ) {
- fprintf(stdout, "Unexpected length converting much UTF-8 to UCS-4\n");
- goto loser;
- }
-
- if( 0 != memcmp(ucs4s, tmp, len) ) {
- fprintf(stdout, "Wrong conversion of much UTF-8 to UCS-4\n");
- goto loser;
- }
-
- free(tmp); tmp = (void *)NULL;
-
- /* UCS-4 -> UTF-8 */
- len = strlen(ucs4_utf8);
- tmp = calloc(len, 1);
- if( (void *)NULL == tmp ) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
-
- result = sec_port_ucs4_utf8_conversion_function(PR_FALSE,
- (unsigned char *)ucs4s, sizeof(ucs4)/sizeof(ucs4[0]) * sizeof(PRUint32),
- tmp, len, &lenout);
- if( !result ) {
- fprintf(stdout, "Failed to convert much UCS-4 to UTF-8\n");
- goto done;
- }
-
- if( lenout != len ) {
- fprintf(stdout, "Unexpected length converting much UCS-4 to UTF-8\n");
- goto loser;
- }
-
- if( 0 != strncmp(ucs4_utf8, tmp, len) ) {
- fprintf(stdout, "Wrong conversion of much UCS-4 to UTF-8\n");
- goto loser;
- }
-
- free(tmp); tmp = (void *)NULL;
-
- /* UTF-8 -> UCS-2 */
- len = sizeof(ucs2)/sizeof(ucs2[0]) * sizeof(PRUint16);
- tmp = calloc(len, 1);
- if( (void *)NULL == tmp ) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
-
- result = sec_port_ucs2_utf8_conversion_function(PR_TRUE,
- ucs2_utf8, strlen(ucs2_utf8), tmp, len, &lenout);
- if( !result ) {
- fprintf(stdout, "Failed to convert much UTF-8 to UCS-2\n");
- goto done;
- }
-
- if( lenout != len ) {
- fprintf(stdout, "Unexpected length converting much UTF-8 to UCS-2\n");
- goto loser;
- }
-
- if( 0 != memcmp(ucs2s, tmp, len) ) {
- fprintf(stdout, "Wrong conversion of much UTF-8 to UCS-2\n");
- goto loser;
- }
-
- free(tmp); tmp = (void *)NULL;
-
- /* UCS-2 -> UTF-8 */
- len = strlen(ucs2_utf8);
- tmp = calloc(len, 1);
- if( (void *)NULL == tmp ) {
- fprintf(stderr, "out of memory\n");
- exit(1);
- }
-
- result = sec_port_ucs2_utf8_conversion_function(PR_FALSE,
- (unsigned char *)ucs2s, sizeof(ucs2)/sizeof(ucs2[0]) * sizeof(PRUint16),
- tmp, len, &lenout);
- if( !result ) {
- fprintf(stdout, "Failed to convert much UCS-2 to UTF-8\n");
- goto done;
- }
-
- if( lenout != len ) {
- fprintf(stdout, "Unexpected length converting much UCS-2 to UTF-8\n");
- goto loser;
- }
-
- if( 0 != strncmp(ucs2_utf8, tmp, len) ) {
- fprintf(stdout, "Wrong conversion of much UCS-2 to UTF-8\n");
- goto loser;
- }
-
- /* implement UTF16 */
-
- result = PR_TRUE;
- goto done;
-
- loser:
- result = PR_FALSE;
- done:
- free(ucs4s);
- free(ucs4_utf8);
- free(ucs2s);
- free(ucs2_utf8);
- if( (void *)NULL != tmp ) free(tmp);
- return result;
-}
-
-void
-byte_order
-(
- void
-)
-{
- /*
- * The implementation (now) expects the 16- and 32-bit characters
- * to be in network byte order, not host byte order. Therefore I
- * have to byteswap all those test vectors above. hton[ls] may be
- * functions, so I have to do this dynamically. If you want to
- * use this code to do host byte order conversions, just remove
- * the call in main() to this function.
- */
-
- int i;
-
- for( i = 0; i < sizeof(ucs4)/sizeof(ucs4[0]); i++ ) {
- struct ucs4 *e = &ucs4[i];
- e->c = htonl(e->c);
- }
-
- for( i = 0; i < sizeof(ucs2)/sizeof(ucs2[0]); i++ ) {
- struct ucs2 *e = &ucs2[i];
- e->c = htons(e->c);
- }
-
- for( i = 0; i < sizeof(utf16)/sizeof(utf16[0]); i++ ) {
- struct utf16 *e = &utf16[i];
- e->c = htonl(e->c);
- e->w[0] = htons(e->w[0]);
- e->w[1] = htons(e->w[1]);
- }
-
- return;
-}
-
-int
-main
-(
- int argc,
- char *argv[]
-)
-{
- byte_order();
-
- if( test_ucs4_chars() &&
- test_ucs2_chars() &&
- test_utf16_chars() &&
- test_utf8_bad_chars() &&
- test_iso88591_chars() &&
- test_zeroes() &&
- test_multichars() &&
- PR_TRUE ) {
- fprintf(stderr, "PASS\n");
- return 1;
- } else {
- fprintf(stderr, "FAIL\n");
- return 0;
- }
-}
-
-#endif /* TEST_UTF8 */
diff --git a/security/nss/lib/util/utilmod.c b/security/nss/lib/util/utilmod.c
deleted file mode 100644
index d051f7fe8..000000000
--- a/security/nss/lib/util/utilmod.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * The following code handles the storage of PKCS 11 modules used by the
- * NSS. For the rest of NSS, only one kind of database handle exists:
- *
- * SFTKDBHandle
- *
- * There is one SFTKDBHandle for each key database and one for each cert
- * database. These databases are opened as associated pairs, one pair per
- * slot. SFTKDBHandles are reference counted objects.
- *
- * Each SFTKDBHandle points to a low level database handle (SDB). This handle
- * represents the underlying physical database. These objects are not
- * reference counted, and are 'owned' by their respective SFTKDBHandles.
- */
-
-#include "prprf.h"
-#include "prsystem.h"
-#include "secport.h"
-#include "utilpars.h"
-#include "secerr.h"
-#if defined (_WIN32)
-#include <io.h>
-#endif
-
-/****************************************************************
- *
- * Secmod database.
- *
- * The new secmod database is simply a text file with each of the module
- * entries in the following form:
- *
- * #
- * # This is a comment The next line is the library to load
- * library=libmypkcs11.so
- * name="My PKCS#11 module"
- * params="my library's param string"
- * nss="NSS parameters"
- * other="parameters for other libraries and applications"
- *
- * library=libmynextpk11.so
- * name="My other PKCS#11 module"
- */
-
-
-/*
- * Smart string cat functions. Automatically manage the memory.
- * The first parameter is the source string. If it's null, we
- * allocate memory for it. If it's not, we reallocate memory
- * so the the concanenated string fits.
- */
-static char *
-nssutil_DupnCat(char *baseString, const char *str, int str_len)
-{
- int len = (baseString ? PORT_Strlen(baseString) : 0) + 1;
- char *newString;
-
- len += str_len;
- newString = (char *) PORT_Realloc(baseString,len);
- if (newString == NULL) {
- PORT_Free(baseString);
- return NULL;
- }
- if (baseString == NULL) *newString = 0;
- return PORT_Strncat(newString,str, str_len);
-}
-
-/* Same as nssutil_DupnCat except it concatenates the full string, not a
- * partial one */
-static char *
-nssutil_DupCat(char *baseString, const char *str)
-{
- return nssutil_DupnCat(baseString, str, PORT_Strlen(str));
-}
-
-/* function to free up all the memory associated with a null terminated
- * array of module specs */
-static SECStatus
-nssutil_releaseSpecList(char **moduleSpecList)
-{
- if (moduleSpecList) {
- char **index;
- for(index = moduleSpecList; *index; index++) {
- PORT_Free(*index);
- }
- PORT_Free(moduleSpecList);
- }
- return SECSuccess;
-}
-
-#define SECMOD_STEP 10
-static SECStatus
-nssutil_growList(char ***pModuleList, int *useCount, int last)
-{
- char **newModuleList;
-
- *useCount += SECMOD_STEP;
- newModuleList = (char **)PORT_Realloc(*pModuleList,
- *useCount*sizeof(char *));
- if (newModuleList == NULL) {
- return SECFailure;
- }
- PORT_Memset(&newModuleList[last],0, sizeof(char *)*SECMOD_STEP);
- *pModuleList = newModuleList;
- return SECSuccess;
-}
-
-static
-char *_NSSUTIL_GetOldSecmodName(const char *dbname,const char *filename)
-{
- char *file = NULL;
- char *dirPath = PORT_Strdup(dbname);
- char *sep;
-
- sep = PORT_Strrchr(dirPath,*NSSUTIL_PATH_SEPARATOR);
-#ifdef _WIN32
- if (!sep) {
- /* utilparst.h defines NSSUTIL_PATH_SEPARATOR as "/" for all
- * platforms. */
- sep = PORT_Strrchr(dirPath,'\\');
- }
-#endif
- if (sep) {
- *sep = 0;
- file = PR_smprintf("%s"NSSUTIL_PATH_SEPARATOR"%s", dirPath, filename);
- } else {
- file = PR_smprintf("%s", filename);
- }
- PORT_Free(dirPath);
- return file;
-}
-
-static SECStatus nssutil_AddSecmodDB(const char *appName,
- const char *filename, const char *dbname,
- char *module, PRBool rw);
-
-#ifdef XP_UNIX
-#include <unistd.h>
-#endif
-#include <fcntl.h>
-
-/* same as fopen, except it doesn't use umask, but explicit */
-FILE *
-lfopen(const char *name, const char *mode, int flags)
-{
- int fd;
- FILE *file;
-
- fd = open(name, flags, 0600);
- if (fd < 0) {
- return NULL;
- }
- file = fdopen(fd, mode);
- if (!file) {
- close(fd);
- }
- /* file inherits fd */
- return file;
-}
-
-#define MAX_LINE_LENGTH 2048
-
-/*
- * Read all the existing modules in out of the file.
- */
-static char **
-nssutil_ReadSecmodDB(const char *appName,
- const char *filename, const char *dbname,
- char *params, PRBool rw)
-{
- FILE *fd = NULL;
- char **moduleList = NULL;
- int moduleCount = 1;
- int useCount = SECMOD_STEP;
- char line[MAX_LINE_LENGTH];
- PRBool internal = PR_FALSE;
- PRBool skipParams = PR_FALSE;
- char *moduleString = NULL;
- char *paramsValue=NULL;
- PRBool failed = PR_TRUE;
-
- moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **));
- if (moduleList == NULL) return NULL;
-
- if (dbname == NULL) {
- goto return_default;
- }
-
- /* do we really want to use streams here */
- fd = fopen(dbname, "r");
- if (fd == NULL) goto done;
-
- /*
- * the following loop takes line separated config lines and collapses
- * the lines to a single string, escaping and quoting as necessary.
- */
- /* loop state variables */
- moduleString = NULL; /* current concatenated string */
- internal = PR_FALSE; /* is this an internal module */
- skipParams = PR_FALSE; /* did we find an override parameter block*/
- paramsValue = NULL; /* the current parameter block value */
- while (fgets(line, sizeof(line), fd) != NULL) {
- int len = PORT_Strlen(line);
-
- /* remove the ending newline */
- if (len && line[len-1] == '\n') {
- len--;
- line[len] = 0;
- }
- if (*line == '#') {
- continue;
- }
- if (*line != 0) {
- /*
- * The PKCS #11 group standard assumes blocks of strings
- * separated by new lines, clumped by new lines. Internally
- * we take strings separated by spaces, so we may need to escape
- * certain spaces.
- */
- char *value = PORT_Strchr(line,'=');
-
- /* there is no value, write out the stanza as is */
- if (value == NULL || value[1] == 0) {
- if (moduleString) {
- moduleString = nssutil_DupnCat(moduleString," ", 1);
- if (moduleString == NULL) goto loser;
- }
- moduleString = nssutil_DupCat(moduleString, line);
- if (moduleString == NULL) goto loser;
- /* value is already quoted, just write it out */
- } else if (value[1] == '"') {
- if (moduleString) {
- moduleString = nssutil_DupnCat(moduleString," ", 1);
- if (moduleString == NULL) goto loser;
- }
- moduleString = nssutil_DupCat(moduleString, line);
- if (moduleString == NULL) goto loser;
- /* we have an override parameter section, remember that
- * we found this (see following comment about why this
- * is necessary). */
- if (PORT_Strncasecmp(line, "parameters", 10) == 0) {
- skipParams = PR_TRUE;
- }
- /*
- * The internal token always overrides it's parameter block
- * from the passed in parameters, so wait until then end
- * before we include the parameter block in case we need to
- * override it. NOTE: if the parameter block is quoted with ("),
- * this override does not happen. This allows you to override
- * the application's parameter configuration.
- *
- * parameter block state is controlled by the following variables:
- * skipParams - Bool : set to true of we have an override param
- * block (all other blocks, either implicit or explicit are
- * ignored).
- * paramsValue - char * : pointer to the current param block. In
- * the absence of overrides, paramsValue is set to the first
- * parameter block we find. All subsequent blocks are ignored.
- * When we find an internal token, the application passed
- * parameters take precident.
- */
- } else if (PORT_Strncasecmp(line, "parameters", 10) == 0) {
- /* already have parameters */
- if (paramsValue) {
- continue;
- }
- paramsValue = NSSUTIL_Quote(&value[1], '"');
- if (paramsValue == NULL) goto loser;
- continue;
- } else {
- /* may need to quote */
- char *newLine;
- if (moduleString) {
- moduleString = nssutil_DupnCat(moduleString," ", 1);
- if (moduleString == NULL) goto loser;
- }
- moduleString = nssutil_DupnCat(moduleString,line,value-line+1);
- if (moduleString == NULL) goto loser;
- newLine = NSSUTIL_Quote(&value[1],'"');
- if (newLine == NULL) goto loser;
- moduleString = nssutil_DupCat(moduleString,newLine);
- PORT_Free(newLine);
- if (moduleString == NULL) goto loser;
- }
-
- /* check to see if it's internal? */
- if (PORT_Strncasecmp(line, "NSS=", 4) == 0) {
- /* This should be case insensitive! reviewers make
- * me fix it if it's not */
- if (PORT_Strstr(line,"internal")) {
- internal = PR_TRUE;
- /* override the parameters */
- if (paramsValue) {
- PORT_Free(paramsValue);
- }
- paramsValue = NSSUTIL_Quote(params, '"');
- }
- }
- continue;
- }
- if ((moduleString == NULL) || (*moduleString == 0)) {
- continue;
- }
-
- /*
- * if we are here, we have found a complete stanza. Now write out
- * any param section we may have found.
- */
- if (paramsValue) {
- /* we had an override */
- if (!skipParams) {
- moduleString = nssutil_DupnCat(moduleString," parameters=", 12);
- if (moduleString == NULL) goto loser;
- moduleString = nssutil_DupCat(moduleString, paramsValue);
- if (moduleString == NULL) goto loser;
- }
- PORT_Free(paramsValue);
- paramsValue = NULL;
- }
-
- if ((moduleCount+1) >= useCount) {
- SECStatus rv;
- rv = nssutil_growList(&moduleList, &useCount, moduleCount+1);
- if (rv != SECSuccess) {
- goto loser;
- }
- }
-
- if (internal) {
- moduleList[0] = moduleString;
- } else {
- moduleList[moduleCount] = moduleString;
- moduleCount++;
- }
- moduleString = NULL;
- internal = PR_FALSE;
- skipParams = PR_FALSE;
- }
-
- if (moduleString) {
- PORT_Free(moduleString);
- moduleString = NULL;
- }
-done:
- /* if we couldn't open a pkcs11 database, look for the old one */
- if (fd == NULL) {
- char *olddbname = _NSSUTIL_GetOldSecmodName(dbname,filename);
- PRStatus status;
-
- /* couldn't get the old name */
- if (!olddbname) {
- goto bail;
- }
-
- /* old one exists */
- status = PR_Access(olddbname, PR_ACCESS_EXISTS);
- if (status == PR_SUCCESS) {
- PR_smprintf_free(olddbname);
- PORT_SetError(SEC_ERROR_LEGACY_DATABASE);
- return NULL;
- }
-
-bail:
- if (olddbname) {
- PR_smprintf_free(olddbname);
- }
- }
-
-return_default:
-
- if (!moduleList[0]) {
- char * newParams;
- moduleString = PORT_Strdup(NSSUTIL_DEFAULT_INTERNAL_INIT1);
- newParams = NSSUTIL_Quote(params,'"');
- if (newParams == NULL) goto loser;
- moduleString = nssutil_DupCat(moduleString, newParams);
- PORT_Free(newParams);
- if (moduleString == NULL) goto loser;
- moduleString = nssutil_DupCat(moduleString,
- NSSUTIL_DEFAULT_INTERNAL_INIT2);
- if (moduleString == NULL) goto loser;
- moduleString = nssutil_DupCat(moduleString,
- NSSUTIL_DEFAULT_SFTKN_FLAGS);
- if (moduleString == NULL) goto loser;
- moduleString = nssutil_DupCat(moduleString,
- NSSUTIL_DEFAULT_INTERNAL_INIT3);
- if (moduleString == NULL) goto loser;
- moduleList[0] = moduleString;
- moduleString = NULL;
- }
- failed = PR_FALSE;
-
-loser:
- /*
- * cleanup
- */
- /* deal with trust cert db here */
- if (moduleString) {
- PORT_Free(moduleString);
- moduleString = NULL;
- }
- if (paramsValue) {
- PORT_Free(paramsValue);
- paramsValue = NULL;
- }
- if (failed || (moduleList[0] == NULL)) {
- /* This is wrong! FIXME */
- nssutil_releaseSpecList(moduleList);
- moduleList = NULL;
- failed = PR_TRUE;
- }
- if (fd != NULL) {
- fclose(fd);
- } else if (!failed && rw) {
- /* update our internal module */
- nssutil_AddSecmodDB(appName,filename,dbname,moduleList[0],rw);
- }
- return moduleList;
-}
-
-static SECStatus
-nssutil_ReleaseSecmodDBData(const char *appName,
- const char *filename, const char *dbname,
- char **moduleSpecList, PRBool rw)
-{
- if (moduleSpecList) {
- nssutil_releaseSpecList(moduleSpecList);
- }
- return SECSuccess;
-}
-
-
-/*
- * Delete a module from the Data Base
- */
-static SECStatus
-nssutil_DeleteSecmodDB(const char *appName,
- const char *filename, const char *dbname,
- char *args, PRBool rw)
-{
- /* SHDB_FIXME implement */
- FILE *fd = NULL;
- FILE *fd2 = NULL;
- char line[MAX_LINE_LENGTH];
- char *dbname2 = NULL;
- char *block = NULL;
- char *name = NULL;
- char *lib = NULL;
- int name_len, lib_len;
- PRBool skip = PR_FALSE;
- PRBool found = PR_FALSE;
-
- if (dbname == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if (!rw) {
- PORT_SetError(SEC_ERROR_READ_ONLY);
- return SECFailure;
- }
-
- dbname2 = PORT_Strdup(dbname);
- if (dbname2 == NULL) goto loser;
- dbname2[strlen(dbname)-1]++;
-
- /* do we really want to use streams here */
- fd = fopen(dbname, "r");
- if (fd == NULL) goto loser;
- fd2 = lfopen(dbname2, "w+", O_CREAT|O_RDWR|O_TRUNC);
- if (fd2 == NULL) goto loser;
-
- name = NSSUTIL_ArgGetParamValue("name",args);
- if (name) {
- name_len = PORT_Strlen(name);
- }
- lib = NSSUTIL_ArgGetParamValue("library",args);
- if (lib) {
- lib_len = PORT_Strlen(lib);
- }
-
-
- /*
- * the following loop takes line separated config files and collapses
- * the lines to a single string, escaping and quoting as necessary.
- */
- /* loop state variables */
- block = NULL;
- skip = PR_FALSE;
- while (fgets(line, sizeof(line), fd) != NULL) {
- /* If we are processing a block (we haven't hit a blank line yet */
- if (*line != '\n') {
- /* skip means we are in the middle of a block we are deleting */
- if (skip) {
- continue;
- }
- /* if we haven't found the block yet, check to see if this block
- * matches our requirements */
- if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) &&
- (PORT_Strncmp(line+5,name,name_len) == 0)) ||
- (lib && (PORT_Strncasecmp(line,"library=",8) == 0) &&
- (PORT_Strncmp(line+8,lib,lib_len) == 0)))) {
-
- /* yup, we don't need to save any more data, */
- PORT_Free(block);
- block=NULL;
- /* we don't need to collect more of this block */
- skip = PR_TRUE;
- /* we don't need to continue searching for the block */
- found =PR_TRUE;
- continue;
- }
- /* not our match, continue to collect data in this block */
- block = nssutil_DupCat(block,line);
- continue;
- }
- /* we've collected a block of data that wasn't the module we were
- * looking for, write it out */
- if (block) {
- fwrite(block, PORT_Strlen(block), 1, fd2);
- PORT_Free(block);
- block = NULL;
- }
- /* If we didn't just delete the this block, keep the blank line */
- if (!skip) {
- fputs(line,fd2);
- }
- /* we are definately not in a deleted block anymore */
- skip = PR_FALSE;
- }
- fclose(fd);
- fclose(fd2);
- if (found) {
- /* rename dbname2 to dbname */
- PR_Delete(dbname);
- PR_Rename(dbname2,dbname);
- } else {
- PR_Delete(dbname2);
- }
- PORT_Free(dbname2);
- PORT_Free(lib);
- PORT_Free(name);
- PORT_Free(block);
- return SECSuccess;
-
-loser:
- if (fd != NULL) {
- fclose(fd);
- }
- if (fd2 != NULL) {
- fclose(fd2);
- }
- if (dbname2) {
- PR_Delete(dbname2);
- PORT_Free(dbname2);
- }
- PORT_Free(lib);
- PORT_Free(name);
- return SECFailure;
-}
-
-/*
- * Add a module to the Data base
- */
-static SECStatus
-nssutil_AddSecmodDB(const char *appName,
- const char *filename, const char *dbname,
- char *module, PRBool rw)
-{
- FILE *fd = NULL;
- char *block = NULL;
- PRBool libFound = PR_FALSE;
-
- if (dbname == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- /* can't write to a read only module */
- if (!rw) {
- PORT_SetError(SEC_ERROR_READ_ONLY);
- return SECFailure;
- }
-
- /* remove the previous version if it exists */
- (void) nssutil_DeleteSecmodDB(appName, filename,
- dbname, module, rw);
-
- fd = lfopen(dbname, "a+", O_CREAT|O_RDWR|O_APPEND);
- if (fd == NULL) {
- return SECFailure;
- }
- module = NSSUTIL_ArgStrip(module);
- while (*module) {
- int count;
- char *keyEnd = PORT_Strchr(module,'=');
- char *value;
-
- if (PORT_Strncmp(module, "library=", 8) == 0) {
- libFound=PR_TRUE;
- }
- if (keyEnd == NULL) {
- block = nssutil_DupCat(block, module);
- break;
- }
- block = nssutil_DupnCat(block, module, keyEnd-module+1);
- if (block == NULL) { goto loser; }
- value = NSSUTIL_ArgFetchValue(&keyEnd[1], &count);
- if (value) {
- block = nssutil_DupCat(block, NSSUTIL_ArgStrip(value));
- PORT_Free(value);
- }
- if (block == NULL) { goto loser; }
- block = nssutil_DupnCat(block, "\n", 1);
- module = keyEnd + 1 + count;
- module = NSSUTIL_ArgStrip(module);
- }
- if (block) {
- if (!libFound) {
- fprintf(fd,"library=\n");
- }
- fwrite(block, PORT_Strlen(block), 1, fd);
- fprintf(fd,"\n");
- PORT_Free(block);
- block = NULL;
- }
- fclose(fd);
- return SECSuccess;
-
-loser:
- PORT_Free(block);
- fclose(fd);
- return SECFailure;
-}
-
-
-char **
-NSSUTIL_DoModuleDBFunction(unsigned long function,char *parameters, void *args)
-{
- char *secmod = NULL;
- char *appName = NULL;
- char *filename = NULL;
- NSSDBType dbType = NSS_DB_TYPE_NONE;
- PRBool rw;
- static char *success="Success";
- char **rvstr = NULL;
-
-
- secmod = _NSSUTIL_GetSecmodName(parameters, &dbType, &appName,
- &filename, &rw);
- if ((dbType == NSS_DB_TYPE_LEGACY) ||
- (dbType == NSS_DB_TYPE_MULTIACCESS)) {
- /* we can't handle the old database, only softoken can */
- PORT_SetError(SEC_ERROR_LEGACY_DATABASE);
- rvstr = NULL;
- goto done;
- }
-
- switch (function) {
- case SECMOD_MODULE_DB_FUNCTION_FIND:
- rvstr = nssutil_ReadSecmodDB(appName,filename,
- secmod,(char *)parameters,rw);
- break;
- case SECMOD_MODULE_DB_FUNCTION_ADD:
- rvstr = (nssutil_AddSecmodDB(appName,filename,
- secmod,(char *)args,rw) == SECSuccess) ? &success: NULL;
- break;
- case SECMOD_MODULE_DB_FUNCTION_DEL:
- rvstr = (nssutil_DeleteSecmodDB(appName,filename,
- secmod,(char *)args,rw) == SECSuccess) ? &success: NULL;
- break;
- case SECMOD_MODULE_DB_FUNCTION_RELEASE:
- rvstr = (nssutil_ReleaseSecmodDBData(appName,filename,
- secmod, (char **)args,rw) == SECSuccess) ? &success: NULL;
- break;
- }
-done:
- if (secmod) PR_smprintf_free(secmod);
- if (appName) PORT_Free(appName);
- if (filename) PORT_Free(filename);
- return rvstr;
-}
diff --git a/security/nss/lib/util/utilmodt.h b/security/nss/lib/util/utilmodt.h
deleted file mode 100644
index 825e59f8f..000000000
--- a/security/nss/lib/util/utilmodt.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _UTILMODT_H_
-#define _UTILMODT_H_ 1
-
-/*
- * these are SECMOD flags that would normally be in secmodt.h, but are needed
- * for the parser in util. Fort this reason we preserve the SECMOD names.
- */
-#define SECMOD_RSA_FLAG 0x00000001L
-#define SECMOD_DSA_FLAG 0x00000002L
-#define SECMOD_RC2_FLAG 0x00000004L
-#define SECMOD_RC4_FLAG 0x00000008L
-#define SECMOD_DES_FLAG 0x00000010L
-#define SECMOD_DH_FLAG 0x00000020L
-#define SECMOD_FORTEZZA_FLAG 0x00000040L
-#define SECMOD_RC5_FLAG 0x00000080L
-#define SECMOD_SHA1_FLAG 0x00000100L
-#define SECMOD_MD5_FLAG 0x00000200L
-#define SECMOD_MD2_FLAG 0x00000400L
-#define SECMOD_SSL_FLAG 0x00000800L
-#define SECMOD_TLS_FLAG 0x00001000L
-#define SECMOD_AES_FLAG 0x00002000L
-#define SECMOD_SHA256_FLAG 0x00004000L
-#define SECMOD_SHA512_FLAG 0x00008000L /* also for SHA384 */
-#define SECMOD_CAMELLIA_FLAG 0x00010000L /* = PUBLIC_MECH_CAMELLIA_FLAG */
-#define SECMOD_SEED_FLAG 0x00020000L
-/* reserved bit for future, do not use */
-#define SECMOD_RESERVED_FLAG 0X08000000L
-#define SECMOD_FRIENDLY_FLAG 0x10000000L
-#define SECMOD_RANDOM_FLAG 0x80000000L
-
-#define PK11_OWN_PW_DEFAULTS 0x20000000L
-#define PK11_DISABLE_FLAG 0x40000000L
-
-/* need to make SECMOD and PK11 prefixes consistent. */
-#define SECMOD_OWN_PW_DEFAULTS PK11_OWN_PW_DEFAULTS
-#define SECMOD_DISABLE_FLAG PK11_DISABLE_FLAG
-
-#endif /* _UTILMODT_H_ */
diff --git a/security/nss/lib/util/utilpars.c b/security/nss/lib/util/utilpars.c
deleted file mode 100644
index 4bb2d3ff9..000000000
--- a/security/nss/lib/util/utilpars.c
+++ /dev/null
@@ -1,1117 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * The following code handles the storage of PKCS 11 modules used by the
- * NSS. This file is written to abstract away how the modules are
- * stored so we can decide that later.
- */
-#include "secport.h"
-#include "prprf.h"
-#include "prenv.h"
-#include "utilpars.h"
-#include "utilmodt.h"
-
-/*
- * return the expected matching quote value for the one specified
- */
-PRBool NSSUTIL_ArgGetPair(char c) {
- switch (c) {
- case '\'': return c;
- case '\"': return c;
- case '<': return '>';
- case '{': return '}';
- case '[': return ']';
- case '(': return ')';
- default: break;
- }
- return ' ';
-}
-
-PRBool NSSUTIL_ArgIsBlank(char c) {
- return isspace((unsigned char )c);
-}
-
-PRBool NSSUTIL_ArgIsEscape(char c) {
- return c == '\\';
-}
-
-PRBool NSSUTIL_ArgIsQuote(char c) {
- switch (c) {
- case '\'':
- case '\"':
- case '<':
- case '{': /* } end curly to keep vi bracket matching working */
- case '(': /* ) */
- case '[': /* ] */ return PR_TRUE;
- default: break;
- }
- return PR_FALSE;
-}
-
-char *NSSUTIL_ArgStrip(char *c) {
- while (*c && NSSUTIL_ArgIsBlank(*c)) c++;
- return c;
-}
-
-/*
- * find the end of the current tag/value pair. string should be pointing just
- * after the equal sign. Handles quoted characters.
- */
-char *
-NSSUTIL_ArgFindEnd(char *string) {
- char endChar = ' ';
- PRBool lastEscape = PR_FALSE;
-
- if (NSSUTIL_ArgIsQuote(*string)) {
- endChar = NSSUTIL_ArgGetPair(*string);
- string++;
- }
-
- for (;*string; string++) {
- if (lastEscape) {
- lastEscape = PR_FALSE;
- continue;
- }
- if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
- lastEscape = PR_TRUE;
- continue;
- }
- if ((endChar == ' ') && NSSUTIL_ArgIsBlank(*string)) break;
- if (*string == endChar) {
- break;
- }
- }
-
- return string;
-}
-
-/*
- * get the value pointed to by string. string should be pointing just beyond
- * the equal sign.
- */
-char *
-NSSUTIL_ArgFetchValue(char *string, int *pcount)
-{
- char *end = NSSUTIL_ArgFindEnd(string);
- char *retString, *copyString;
- PRBool lastEscape = PR_FALSE;
- int len;
-
- len = end - string;
- if (len == 0) {
- *pcount = 0;
- return NULL;
- }
-
- copyString = retString = (char *)PORT_Alloc(len+1);
-
- if (*end) len++;
- *pcount = len;
- if (retString == NULL) return NULL;
-
-
- if (NSSUTIL_ArgIsQuote(*string)) string++;
- for (; string < end; string++) {
- if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
- lastEscape = PR_TRUE;
- continue;
- }
- lastEscape = PR_FALSE;
- *copyString++ = *string;
- }
- *copyString = 0;
- return retString;
-}
-
-/*
- * point to the next parameter in string
- */
-char *
-NSSUTIL_ArgSkipParameter(char *string)
-{
- char *end;
- /* look for the end of the <name>= */
- for (;*string; string++) {
- if (*string == '=') { string++; break; }
- if (NSSUTIL_ArgIsBlank(*string)) return(string);
- }
-
- end = NSSUTIL_ArgFindEnd(string);
- if (*end) end++;
- return end;
-}
-
-/*
- * get the value from that tag value pair.
- */
-char *
-NSSUTIL_ArgGetParamValue(char *paramName,char *parameters)
-{
- char searchValue[256];
- int paramLen = strlen(paramName);
- char *returnValue = NULL;
- int next;
-
- if ((parameters == NULL) || (*parameters == 0)) return NULL;
-
- PORT_Assert(paramLen+2 < sizeof(searchValue));
-
- PORT_Strcpy(searchValue,paramName);
- PORT_Strcat(searchValue,"=");
- while (*parameters) {
- if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) {
- parameters += paramLen+1;
- returnValue = NSSUTIL_ArgFetchValue(parameters,&next);
- break;
- } else {
- parameters = NSSUTIL_ArgSkipParameter(parameters);
- }
- parameters = NSSUTIL_ArgStrip(parameters);
- }
- return returnValue;
-}
-
-/*
- * find the next flag in the parameter list
- */
-char *
-NSSUTIL_ArgNextFlag(char *flags)
-{
- for (; *flags ; flags++) {
- if (*flags == ',') {
- flags++;
- break;
- }
- }
- return flags;
-}
-
-/*
- * return true if the flag is set in the label parameter.
- */
-PRBool
-NSSUTIL_ArgHasFlag(char *label, char *flag, char *parameters)
-{
- char *flags,*index;
- int len = strlen(flag);
- PRBool found = PR_FALSE;
-
- flags = NSSUTIL_ArgGetParamValue(label,parameters);
- if (flags == NULL) return PR_FALSE;
-
- for (index=flags; *index; index=NSSUTIL_ArgNextFlag(index)) {
- if (PORT_Strncasecmp(index,flag,len) == 0) {
- found=PR_TRUE;
- break;
- }
- }
- PORT_Free(flags);
- return found;
-}
-
-/*
- * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal
- */
-long
-NSSUTIL_ArgDecodeNumber(char *num)
-{
- int radix = 10;
- unsigned long value = 0;
- long retValue = 0;
- int sign = 1;
- int digit;
-
- if (num == NULL) return retValue;
-
- num = NSSUTIL_ArgStrip(num);
-
- if (*num == '-') {
- sign = -1;
- num++;
- }
-
- if (*num == '0') {
- radix = 8;
- num++;
- if ((*num == 'x') || (*num == 'X')) {
- radix = 16;
- num++;
- }
- }
-
-
- for ( ;*num; num++ ) {
- if (isdigit(*num)) {
- digit = *num - '0';
- } else if ((*num >= 'a') && (*num <= 'f')) {
- digit = *num - 'a' + 10;
- } else if ((*num >= 'A') && (*num <= 'F')) {
- digit = *num - 'A' + 10;
- } else {
- break;
- }
- if (digit >= radix) break;
- value = value*radix + digit;
- }
-
- retValue = ((int) value) * sign;
- return retValue;
-}
-
-/*
- * parameters are tag value pairs. This function returns the tag or label (the
- * value before the equal size.
- */
-char *
-NSSUTIL_ArgGetLabel(char *inString, int *next)
-{
- char *name=NULL;
- char *string;
- int len;
-
- /* look for the end of the <label>= */
- for (string = inString;*string; string++) {
- if (*string == '=') { break; }
- if (NSSUTIL_ArgIsBlank(*string)) break;
- }
-
- len = string - inString;
-
- *next = len;
- if (*string == '=') (*next) += 1;
- if (len > 0) {
- name = PORT_Alloc(len+1);
- PORT_Strncpy(name,inString,len);
- name[len] = 0;
- }
- return name;
-}
-
-/*
- * read an argument at a Long integer
- */
-long
-NSSUTIL_ArgReadLong(char *label,char *params, long defValue, PRBool *isdefault)
-{
- char *value;
- long retValue;
- if (isdefault) *isdefault = PR_FALSE;
-
- value = NSSUTIL_ArgGetParamValue(label,params);
- if (value == NULL) {
- if (isdefault) *isdefault = PR_TRUE;
- return defValue;
- }
- retValue = NSSUTIL_ArgDecodeNumber(value);
- if (value) PORT_Free(value);
-
- return retValue;
-}
-
-
-/*
- * prepare a string to be quoted with 'quote' marks. We do that by adding
- * appropriate escapes.
- */
-static int
-nssutil_escapeQuotesSize(const char *string, char quote, PRBool addquotes)
-{
- int escapes = 0, size = 0;
- const char *src;
-
- size= addquotes ? 2 : 0;
- for (src=string; *src ; src++) {
- if ((*src == quote) || (*src == '\\')) escapes++;
- size++;
- }
- return size+escapes+1;
-
-}
-
-static char *
-nssutil_escapeQuotes(const char *string, char quote, PRBool addquotes)
-{
- char *newString = 0;
- int size = 0;
- const char *src;
- char *dest;
-
- size = nssutil_escapeQuotesSize(string, quote, addquotes);
-
- dest = newString = PORT_ZAlloc(size);
- if (newString == NULL) {
- return NULL;
- }
-
- if (addquotes) *dest++=quote;
- for (src=string; *src; src++,dest++) {
- if ((*src == '\\') || (*src == quote)) {
- *dest++ = '\\';
- }
- *dest = *src;
- }
- if (addquotes) *dest=quote;
-
- return newString;
-}
-
-int
-NSSUTIL_EscapeSize(const char *string, char quote)
-{
- return nssutil_escapeQuotesSize(string, quote, PR_FALSE);
-}
-
-char *
-NSSUTIL_Escape(const char *string, char quote)
-{
- return nssutil_escapeQuotes(string, quote, PR_FALSE);
-}
-
-
-int
-NSSUTIL_QuoteSize(const char *string, char quote)
-{
- return nssutil_escapeQuotesSize(string, quote, PR_TRUE);
-}
-
-char *
-NSSUTIL_Quote(const char *string, char quote)
-{
- return nssutil_escapeQuotes(string, quote, PR_TRUE);
-}
-
-int
-NSSUTIL_DoubleEscapeSize(const char *string, char quote1, char quote2)
-{
- int escapes = 0, size = 0;
- const char *src;
- for (src=string; *src ; src++) {
- if (*src == '\\') escapes+=3; /* \\\\ */
- if (*src == quote1) escapes+=2; /* \\quote1 */
- if (*src == quote2) escapes++; /* \quote2 */
- size++;
- }
-
- return escapes+size+1;
-}
-
-char *
-NSSUTIL_DoubleEscape(const char *string, char quote1, char quote2)
-{
- char *round1 = NULL;
- char *retValue = NULL;
- if (string == NULL) {
- goto done;
- }
- round1 = nssutil_escapeQuotes(string, quote1, PR_FALSE);
- if (round1) {
- retValue = nssutil_escapeQuotes(round1, quote2, PR_FALSE);
- PORT_Free(round1);
- }
-
-done:
- if (retValue == NULL) {
- retValue = PORT_Strdup("");
- }
- return retValue;
-}
-
-
-/************************************************************************
- * These functions are used in contructing strings.
- * NOTE: they will always return a string, but sometimes it will return
- * a specific NULL string. These strings must be freed with util_freePair.
- */
-
-/* string to return on error... */
-static char *nssutil_nullString = "";
-
-static char *
-nssutil_formatValue(PRArenaPool *arena, char *value, char quote)
-{
- char *vp,*vp2,*retval;
- int size = 0, escapes = 0;
-
- for (vp=value; *vp ;vp++) {
- if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) escapes++;
- size++;
- }
- if (arena) {
- retval = PORT_ArenaZAlloc(arena,size+escapes+1);
- } else {
- retval = PORT_ZAlloc(size+escapes+1);
- }
- if (retval == NULL) return NULL;
- vp2 = retval;
- for (vp=value; *vp; vp++) {
- if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE))
- *vp2++ = NSSUTIL_ARG_ESCAPE;
- *vp2++ = *vp;
- }
- return retval;
-}
-
-
-static PRBool nssutil_argHasChar(char *v, char c)
-{
- for ( ;*v; v++) {
- if (*v == c) return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-static PRBool nssutil_argHasBlanks(char *v)
-{
- for ( ;*v; v++) {
- if (NSSUTIL_ArgIsBlank(*v)) return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-static char *
-nssutil_formatPair(char *name, char *value, char quote)
-{
- char openQuote = quote;
- char closeQuote = NSSUTIL_ArgGetPair(quote);
- char *newValue = NULL;
- char *returnValue;
- PRBool need_quote = PR_FALSE;
-
- if (!value || (*value == 0)) return nssutil_nullString;
-
- if (nssutil_argHasBlanks(value) || NSSUTIL_ArgIsQuote(value[0]))
- need_quote=PR_TRUE;
-
- if ((need_quote && nssutil_argHasChar(value,closeQuote))
- || nssutil_argHasChar(value,NSSUTIL_ARG_ESCAPE)) {
- value = newValue = nssutil_formatValue(NULL, value,quote);
- if (newValue == NULL) return nssutil_nullString;
- }
- if (need_quote) {
- returnValue = PR_smprintf("%s=%c%s%c",name,openQuote,value,closeQuote);
- } else {
- returnValue = PR_smprintf("%s=%s",name,value);
- }
- if (returnValue == NULL) returnValue = nssutil_nullString;
-
- if (newValue) PORT_Free(newValue);
-
- return returnValue;
-}
-
-static char *nssutil_formatIntPair(char *name, unsigned long value,
- unsigned long def)
-{
- char *returnValue;
-
- if (value == def) return nssutil_nullString;
-
- returnValue = PR_smprintf("%s=%d",name,value);
-
- return returnValue;
-}
-
-static void
-nssutil_freePair(char *pair)
-{
- if (pair && pair != nssutil_nullString) {
- PR_smprintf_free(pair);
- }
-}
-
-
-/************************************************************************
- * Parse the Slot specific parameters in the NSS params.
- */
-
-struct nssutilArgSlotFlagTable {
- char *name;
- int len;
- unsigned long value;
-};
-
-#define NSSUTIL_ARG_ENTRY(arg,flag) \
-{ #arg , sizeof(#arg)-1, flag }
-static struct nssutilArgSlotFlagTable nssutil_argSlotFlagTable[] = {
- NSSUTIL_ARG_ENTRY(RSA,SECMOD_RSA_FLAG),
- NSSUTIL_ARG_ENTRY(DSA,SECMOD_RSA_FLAG),
- NSSUTIL_ARG_ENTRY(RC2,SECMOD_RC4_FLAG),
- NSSUTIL_ARG_ENTRY(RC4,SECMOD_RC2_FLAG),
- NSSUTIL_ARG_ENTRY(DES,SECMOD_DES_FLAG),
- NSSUTIL_ARG_ENTRY(DH,SECMOD_DH_FLAG),
- NSSUTIL_ARG_ENTRY(FORTEZZA,SECMOD_FORTEZZA_FLAG),
- NSSUTIL_ARG_ENTRY(RC5,SECMOD_RC5_FLAG),
- NSSUTIL_ARG_ENTRY(SHA1,SECMOD_SHA1_FLAG),
- NSSUTIL_ARG_ENTRY(SHA256,SECMOD_SHA256_FLAG),
- NSSUTIL_ARG_ENTRY(SHA512,SECMOD_SHA512_FLAG),
- NSSUTIL_ARG_ENTRY(MD5,SECMOD_MD5_FLAG),
- NSSUTIL_ARG_ENTRY(MD2,SECMOD_MD2_FLAG),
- NSSUTIL_ARG_ENTRY(SSL,SECMOD_SSL_FLAG),
- NSSUTIL_ARG_ENTRY(TLS,SECMOD_TLS_FLAG),
- NSSUTIL_ARG_ENTRY(AES,SECMOD_AES_FLAG),
- NSSUTIL_ARG_ENTRY(Camellia,SECMOD_CAMELLIA_FLAG),
- NSSUTIL_ARG_ENTRY(SEED,SECMOD_SEED_FLAG),
- NSSUTIL_ARG_ENTRY(PublicCerts,SECMOD_FRIENDLY_FLAG),
- NSSUTIL_ARG_ENTRY(RANDOM,SECMOD_RANDOM_FLAG),
- NSSUTIL_ARG_ENTRY(Disable, SECMOD_DISABLE_FLAG),
-};
-
-static int nssutil_argSlotFlagTableSize =
- sizeof(nssutil_argSlotFlagTable)/sizeof(nssutil_argSlotFlagTable[0]);
-
-
-/* turn the slot flags into a bit mask */
-unsigned long
-NSSUTIL_ArgParseSlotFlags(char *label,char *params)
-{
- char *flags,*index;
- unsigned long retValue = 0;
- int i;
- PRBool all = PR_FALSE;
-
- flags = NSSUTIL_ArgGetParamValue(label,params);
- if (flags == NULL) return 0;
-
- if (PORT_Strcasecmp(flags,"all") == 0) all = PR_TRUE;
-
- for (index=flags; *index; index=NSSUTIL_ArgNextFlag(index)) {
- for (i=0; i < nssutil_argSlotFlagTableSize; i++) {
- if (all ||
- (PORT_Strncasecmp(index, nssutil_argSlotFlagTable[i].name,
- nssutil_argSlotFlagTable[i].len) == 0)) {
- retValue |= nssutil_argSlotFlagTable[i].value;
- }
- }
- }
- PORT_Free(flags);
- return retValue;
-}
-
-
-/* parse a single slot specific parameter */
-static void
-nssutil_argDecodeSingleSlotInfo(char *name, char *params,
- struct NSSUTILPreSlotInfoStr *slotInfo)
-{
- char *askpw;
-
- slotInfo->slotID=NSSUTIL_ArgDecodeNumber(name);
- slotInfo->defaultFlags=NSSUTIL_ArgParseSlotFlags("slotFlags",params);
- slotInfo->timeout=NSSUTIL_ArgReadLong("timeout",params, 0, NULL);
-
- askpw = NSSUTIL_ArgGetParamValue("askpw",params);
- slotInfo->askpw = 0;
-
- if (askpw) {
- if (PORT_Strcasecmp(askpw,"every") == 0) {
- slotInfo->askpw = -1;
- } else if (PORT_Strcasecmp(askpw,"timeout") == 0) {
- slotInfo->askpw = 1;
- }
- PORT_Free(askpw);
- slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS;
- }
- slotInfo->hasRootCerts = NSSUTIL_ArgHasFlag("rootFlags", "hasRootCerts",
- params);
- slotInfo->hasRootTrust = NSSUTIL_ArgHasFlag("rootFlags", "hasRootTrust",
- params);
-}
-
-/* parse all the slot specific parameters. */
-struct NSSUTILPreSlotInfoStr *
-NSSUTIL_ArgParseSlotInfo(PRArenaPool *arena, char *slotParams, int *retCount)
-{
- char *slotIndex;
- struct NSSUTILPreSlotInfoStr *slotInfo = NULL;
- int i=0,count = 0,next;
-
- *retCount = 0;
- if ((slotParams == NULL) || (*slotParams == 0)) return NULL;
-
- /* first count the number of slots */
- for (slotIndex = NSSUTIL_ArgStrip(slotParams); *slotIndex;
- slotIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(slotIndex))) {
- count++;
- }
-
- /* get the data structures */
- if (arena) {
- slotInfo = PORT_ArenaZNewArray(arena,
- struct NSSUTILPreSlotInfoStr, count);
- } else {
- slotInfo = PORT_ZNewArray(struct NSSUTILPreSlotInfoStr, count);
- }
- if (slotInfo == NULL) return NULL;
-
- for (slotIndex = NSSUTIL_ArgStrip(slotParams), i = 0;
- *slotIndex && i < count ; ) {
- char *name;
- name = NSSUTIL_ArgGetLabel(slotIndex,&next);
- slotIndex += next;
-
- if (!NSSUTIL_ArgIsBlank(*slotIndex)) {
- char *args = NSSUTIL_ArgFetchValue(slotIndex,&next);
- slotIndex += next;
- if (args) {
- nssutil_argDecodeSingleSlotInfo(name,args,&slotInfo[i]);
- i++;
- PORT_Free(args);
- }
- }
- if (name) PORT_Free(name);
- slotIndex = NSSUTIL_ArgStrip(slotIndex);
- }
- *retCount = i;
- return slotInfo;
-}
-
-/************************************************************************
- * make a new slot specific parameter
- */
-/* first make the slot flags */
-static char *
-nssutil_mkSlotFlags(unsigned long defaultFlags)
-{
- char *flags=NULL;
- int i,j;
-
- for (i=0; i < sizeof(defaultFlags)*8; i++) {
- if (defaultFlags & (1<<i)) {
- char *string = NULL;
-
- for (j=0; j < nssutil_argSlotFlagTableSize; j++) {
- if (nssutil_argSlotFlagTable[j].value == ( 1UL << i )) {
- string = nssutil_argSlotFlagTable[j].name;
- break;
- }
- }
- if (string) {
- if (flags) {
- char *tmp;
- tmp = PR_smprintf("%s,%s",flags,string);
- PR_smprintf_free(flags);
- flags = tmp;
- } else {
- flags = PR_smprintf("%s",string);
- }
- }
- }
- }
-
- return flags;
-}
-
-/* now make the root flags */
-#define NSSUTIL_MAX_ROOT_FLAG_SIZE sizeof("hasRootCerts")+sizeof("hasRootTrust")
-static char *
-nssutil_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust)
-{
- char *flags= (char *)PORT_ZAlloc(NSSUTIL_MAX_ROOT_FLAG_SIZE);
- PRBool first = PR_TRUE;
-
- PORT_Memset(flags,0,NSSUTIL_MAX_ROOT_FLAG_SIZE);
- if (hasRootCerts) {
- PORT_Strcat(flags,"hasRootCerts");
- first = PR_FALSE;
- }
- if (hasRootTrust) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"hasRootTrust");
- first = PR_FALSE;
- }
- return flags;
-}
-
-/* now make a full slot string */
-char *
-NSSUTIL_MkSlotString(unsigned long slotID, unsigned long defaultFlags,
- unsigned long timeout, unsigned char askpw_in,
- PRBool hasRootCerts, PRBool hasRootTrust) {
- char *askpw,*flags,*rootFlags,*slotString;
- char *flagPair,*rootFlagsPair;
-
- switch (askpw_in) {
- case 0xff:
- askpw = "every";
- break;
- case 1:
- askpw = "timeout";
- break;
- default:
- askpw = "any";
- break;
- }
- flags = nssutil_mkSlotFlags(defaultFlags);
- rootFlags = nssutil_mkRootFlags(hasRootCerts,hasRootTrust);
- flagPair = nssutil_formatPair("slotFlags",flags,'\'');
- rootFlagsPair = nssutil_formatPair("rootFlags",rootFlags,'\'');
- if (flags) PR_smprintf_free(flags);
- if (rootFlags) PORT_Free(rootFlags);
- if (defaultFlags & PK11_OWN_PW_DEFAULTS) {
- slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]",
- (PRUint32)slotID,flagPair,askpw,timeout,
- rootFlagsPair);
- } else {
- slotString = PR_smprintf("0x%08lx=[%s %s]",
- (PRUint32)slotID,flagPair,rootFlagsPair);
- }
- nssutil_freePair(flagPair);
- nssutil_freePair(rootFlagsPair);
- return slotString;
-}
-
-
-/************************************************************************
- * Parse Full module specs into: library, commonName, module parameters,
- * and NSS specifi parameters.
- */
-SECStatus
-NSSUTIL_ArgParseModuleSpec(char *modulespec, char **lib, char **mod,
- char **parameters, char **nss)
-{
- int next;
- modulespec = NSSUTIL_ArgStrip(modulespec);
-
- *lib = *mod = *parameters = *nss = 0;
-
- while (*modulespec) {
- NSSUTIL_HANDLE_STRING_ARG(modulespec,*lib,"library=",;)
- NSSUTIL_HANDLE_STRING_ARG(modulespec,*mod,"name=",;)
- NSSUTIL_HANDLE_STRING_ARG(modulespec,*parameters,"parameters=",;)
- NSSUTIL_HANDLE_STRING_ARG(modulespec,*nss,"nss=",;)
- NSSUTIL_HANDLE_FINAL_ARG(modulespec)
- }
- return SECSuccess;
-}
-
-/************************************************************************
- * make a new module spec from it's components */
-char *
-NSSUTIL_MkModuleSpec(char *dllName, char *commonName, char *parameters,
- char *NSS)
-{
- char *moduleSpec;
- char *lib,*name,*param,*nss;
-
- /*
- * now the final spec
- */
- lib = nssutil_formatPair("library",dllName,'\"');
- name = nssutil_formatPair("name",commonName,'\"');
- param = nssutil_formatPair("parameters",parameters,'\"');
- nss = nssutil_formatPair("NSS",NSS,'\"');
- moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss);
- nssutil_freePair(lib);
- nssutil_freePair(name);
- nssutil_freePair(param);
- nssutil_freePair(nss);
- return (moduleSpec);
-}
-
-
-#define NSSUTIL_ARG_FORTEZZA_FLAG "FORTEZZA"
-/******************************************************************************
- * Parse the cipher flags from the NSS parameter
- */
-void
-NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers,char *cipherList)
-{
- newCiphers[0] = newCiphers[1] = 0;
- if ((cipherList == NULL) || (*cipherList == 0)) return;
-
- for (;*cipherList; cipherList=NSSUTIL_ArgNextFlag(cipherList)) {
- if (PORT_Strncasecmp(cipherList,NSSUTIL_ARG_FORTEZZA_FLAG,
- sizeof(NSSUTIL_ARG_FORTEZZA_FLAG)-1) == 0) {
- newCiphers[0] |= SECMOD_FORTEZZA_FLAG;
- }
-
- /* add additional flags here as necessary */
- /* direct bit mapping escape */
- if (*cipherList == 0) {
- if (cipherList[1] == 'l') {
- newCiphers[1] |= atoi(&cipherList[2]);
- } else {
- newCiphers[0] |= atoi(&cipherList[2]);
- }
- }
- }
-}
-
-
-/*********************************************************************
- * make NSS parameter...
- */
-/* First make NSS specific flags */
-#define MAX_FLAG_SIZE sizeof("internal")+sizeof("FIPS")+sizeof("moduleDB")+\
- sizeof("moduleDBOnly")+sizeof("critical")
-static char *
-nssutil_mkNSSFlags(PRBool internal, PRBool isFIPS,
- PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical)
-{
- char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE);
- PRBool first = PR_TRUE;
-
- PORT_Memset(flags,0,MAX_FLAG_SIZE);
- if (internal) {
- PORT_Strcat(flags,"internal");
- first = PR_FALSE;
- }
- if (isFIPS) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"FIPS");
- first = PR_FALSE;
- }
- if (isModuleDB) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"moduleDB");
- first = PR_FALSE;
- }
- if (isModuleDBOnly) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"moduleDBOnly");
- first = PR_FALSE;
- }
- if (isCritical) {
- if (!first) PORT_Strcat(flags,",");
- PORT_Strcat(flags,"critical");
- first = PR_FALSE;
- }
- return flags;
-}
-
-
-/* construct the NSS cipher flags */
-static char *
-nssutil_mkCipherFlags(unsigned long ssl0, unsigned long ssl1)
-{
- char *cipher = NULL;
- int i;
-
- for (i=0; i < sizeof(ssl0)*8; i++) {
- if (ssl0 & (1<<i)) {
- char *string;
- if ((1<<i) == SECMOD_FORTEZZA_FLAG) {
- string = PR_smprintf("%s",NSSUTIL_ARG_FORTEZZA_FLAG);
- } else {
- string = PR_smprintf("0h0x%08x",1<<i);
- }
- if (cipher) {
- char *tmp;
- tmp = PR_smprintf("%s,%s",cipher,string);
- PR_smprintf_free(cipher);
- PR_smprintf_free(string);
- cipher = tmp;
- } else {
- cipher = string;
- }
- }
- }
- for (i=0; i < sizeof(ssl0)*8; i++) {
- if (ssl1 & (1<<i)) {
- if (cipher) {
- char *tmp;
- tmp = PR_smprintf("%s,0l0x%08x",cipher,1<<i);
- PR_smprintf_free(cipher);
- cipher = tmp;
- } else {
- cipher = PR_smprintf("0l0x%08x",1<<i);
- }
- }
- }
-
- return cipher;
-}
-
-/* Assemble a full NSS string. */
-char *
-NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal,
- PRBool isFIPS, PRBool isModuleDB, PRBool isModuleDBOnly,
- PRBool isCritical, unsigned long trustOrder,
- unsigned long cipherOrder, unsigned long ssl0, unsigned long ssl1)
-{
- int slotLen, i;
- char *slotParams, *ciphers, *nss, *nssFlags, *tmp;
- char *trustOrderPair,*cipherOrderPair,*slotPair,*cipherPair,*flagPair;
-
-
- /* now let's build up the string
- * first the slot infos
- */
- slotLen=0;
- for (i=0; i < (int)slotCount; i++) {
- slotLen += PORT_Strlen(slotStrings[i])+1;
- }
- slotLen += 1; /* space for the final NULL */
-
- slotParams = (char *)PORT_ZAlloc(slotLen);
- PORT_Memset(slotParams,0,slotLen);
- for (i=0; i < (int)slotCount; i++) {
- PORT_Strcat(slotParams,slotStrings[i]);
- PORT_Strcat(slotParams," ");
- PR_smprintf_free(slotStrings[i]);
- slotStrings[i]=NULL;
- }
-
- /*
- * now the NSS structure
- */
- nssFlags = nssutil_mkNSSFlags(internal,isFIPS,isModuleDB,isModuleDBOnly,
- isCritical);
- /* for now only the internal module is critical */
- ciphers = nssutil_mkCipherFlags(ssl0, ssl1);
-
- trustOrderPair = nssutil_formatIntPair("trustOrder",trustOrder,
- NSSUTIL_DEFAULT_TRUST_ORDER);
- cipherOrderPair = nssutil_formatIntPair("cipherOrder",cipherOrder,
- NSSUTIL_DEFAULT_CIPHER_ORDER);
- slotPair=nssutil_formatPair("slotParams",slotParams,'{'); /* } */
- if (slotParams) PORT_Free(slotParams);
- cipherPair=nssutil_formatPair("ciphers",ciphers,'\'');
- if (ciphers) PR_smprintf_free(ciphers);
- flagPair=nssutil_formatPair("Flags",nssFlags,'\'');
- if (nssFlags) PORT_Free(nssFlags);
- nss = PR_smprintf("%s %s %s %s %s",trustOrderPair,
- cipherOrderPair,slotPair,cipherPair,flagPair);
- nssutil_freePair(trustOrderPair);
- nssutil_freePair(cipherOrderPair);
- nssutil_freePair(slotPair);
- nssutil_freePair(cipherPair);
- nssutil_freePair(flagPair);
- tmp = NSSUTIL_ArgStrip(nss);
- if (*tmp == '\0') {
- PR_smprintf_free(nss);
- nss = NULL;
- }
- return nss;
-}
-
-/*****************************************************************************
- *
- * Private calls for use by softoken and utilmod.c
- */
-
-#define SQLDB "sql:"
-#define EXTERNDB "extern:"
-#define LEGACY "dbm:"
-#define MULTIACCESS "multiaccess:"
-#define SECMOD_DB "secmod.db"
-const char *
-_NSSUTIL_EvaluateConfigDir(const char *configdir,
- NSSDBType *pdbType, char **appName)
-{
- NSSDBType dbType;
- *appName = NULL;
-/* force the default */
-#ifdef NSS_DISABLE_DBM
- dbType = NSS_DB_TYPE_SQL;
-#else
- dbType = NSS_DB_TYPE_LEGACY;
-#endif
- if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) {
- char *cdir;
- dbType = NSS_DB_TYPE_MULTIACCESS;
-
- *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1);
- if (*appName == NULL) {
- return configdir;
- }
- cdir = *appName;
- while (*cdir && *cdir != ':') {
- cdir++;
- }
- if (*cdir == ':') {
- *cdir = 0;
- cdir++;
- }
- configdir = cdir;
- } else if (PORT_Strncmp(configdir, SQLDB, sizeof(SQLDB)-1) == 0) {
- dbType = NSS_DB_TYPE_SQL;
- configdir = configdir + sizeof(SQLDB) -1;
- } else if (PORT_Strncmp(configdir, EXTERNDB, sizeof(EXTERNDB)-1) == 0) {
- dbType = NSS_DB_TYPE_EXTERN;
- configdir = configdir + sizeof(EXTERNDB) -1;
- } else if (PORT_Strncmp(configdir, LEGACY, sizeof(LEGACY)-1) == 0) {
- dbType = NSS_DB_TYPE_LEGACY;
- configdir = configdir + sizeof(LEGACY) -1;
- } else {
- /* look up the default from the environment */
- char *defaultType = PR_GetEnv("NSS_DEFAULT_DB_TYPE");
- if (defaultType != NULL) {
- if (PORT_Strncmp(defaultType, SQLDB, sizeof(SQLDB)-2) == 0) {
- dbType = NSS_DB_TYPE_SQL;
- } else if (PORT_Strncmp(defaultType,EXTERNDB,sizeof(EXTERNDB)-2)==0) {
- dbType = NSS_DB_TYPE_EXTERN;
- } else if (PORT_Strncmp(defaultType, LEGACY, sizeof(LEGACY)-2) == 0) {
- dbType = NSS_DB_TYPE_LEGACY;
- }
- }
- }
- /* if the caller has already set a type, don't change it */
- if (*pdbType == NSS_DB_TYPE_NONE) {
- *pdbType = dbType;
- }
- return configdir;
-}
-
-char *
-_NSSUTIL_GetSecmodName(char *param, NSSDBType *dbType, char **appName,
- char **filename, PRBool *rw)
-{
- int next;
- char *configdir = NULL;
- char *secmodName = NULL;
- char *value = NULL;
- char *save_params = param;
- const char *lconfigdir;
- PRBool noModDB = PR_FALSE;
- param = NSSUTIL_ArgStrip(param);
-
-
- while (*param) {
- NSSUTIL_HANDLE_STRING_ARG(param,configdir,"configDir=",;)
- NSSUTIL_HANDLE_STRING_ARG(param,secmodName,"secmod=",;)
- NSSUTIL_HANDLE_FINAL_ARG(param)
- }
-
- *rw = PR_TRUE;
- if (NSSUTIL_ArgHasFlag("flags","readOnly",save_params)) {
- *rw = PR_FALSE;
- }
-
- if (!secmodName || *secmodName == '\0') {
- if (secmodName) PORT_Free(secmodName);
- secmodName = PORT_Strdup(SECMOD_DB);
- }
-
- *filename = secmodName;
- lconfigdir = _NSSUTIL_EvaluateConfigDir(configdir, dbType, appName);
-
- if (NSSUTIL_ArgHasFlag("flags","noModDB",save_params)) {
- /* there isn't a module db, don't load the legacy support */
- noModDB = PR_TRUE;
- *dbType = NSS_DB_TYPE_SQL;
- PORT_Free(*filename);
- *filename = NULL;
- *rw = PR_FALSE;
- }
-
- /* only use the renamed secmod for legacy databases */
- if ((*dbType != NSS_DB_TYPE_LEGACY) &&
- (*dbType != NSS_DB_TYPE_MULTIACCESS)) {
- secmodName="pkcs11.txt";
- }
-
- if (noModDB) {
- value = NULL;
- } else if (lconfigdir && lconfigdir[0] != '\0') {
- value = PR_smprintf("%s" NSSUTIL_PATH_SEPARATOR "%s",
- lconfigdir,secmodName);
- } else {
- value = PR_smprintf("%s",secmodName);
- }
- if (configdir) PORT_Free(configdir);
- return value;
-}
-
-
diff --git a/security/nss/lib/util/utilpars.h b/security/nss/lib/util/utilpars.h
deleted file mode 100644
index 414dae36b..000000000
--- a/security/nss/lib/util/utilpars.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef _UTILPARS_H_
-#define _UTILPARS_H_ 1
-
-#include "utilparst.h"
-#include "plarena.h"
-
-/* handle a module db request */
-char ** NSSUTIL_DoModuleDBFunction(unsigned long function,char *parameters, void *args);
-
-/* parsing functions */
-char *NSSUTIL_ArgFetchValue(char *string, int *pcount);
-char *NSSUTIL_ArgStrip(char *c);
-char *NSSUTIL_ArgGetParamValue(char *paramName,char *parameters);
-char *NSSUTIL_ArgSkipParameter(char *string);
-char *NSSUTIL_ArgGetLabel(char *inString, int *next);
-long NSSUTIL_ArgDecodeNumber(char *num);
-PRBool NSSUTIL_ArgIsBlank(char c);
-PRBool NSSUTIL_ArgHasFlag(char *label, char *flag, char *parameters);
-long NSSUTIL_ArgReadLong(char *label,char *params, long defValue,
- PRBool *isdefault);
-
-/* quoting functions */
-int NSSUTIL_EscapeSize(const char *string, char quote);
-char *NSSUTIL_Escape(const char *string, char quote);
-int NSSUTIL_QuoteSize(const char *string, char quote);
-char *NSSUTIL_Quote(const char *string, char quote);
-int NSSUTIL_DoubleEscapeSize(const char *string, char quote1, char quote2);
-char *NSSUTIL_DoubleEscape(const char *string, char quote1, char quote2);
-
-unsigned long NSSUTIL_ArgParseSlotFlags(char *label,char *params);
-struct NSSUTILPreSlotInfoStr *NSSUTIL_ArgParseSlotInfo(PRArenaPool *arena,
- char *slotParams, int *retCount);
-char * NSSUTIL_MkSlotString(unsigned long slotID, unsigned long defaultFlags,
- unsigned long timeout, unsigned char askpw_in,
- PRBool hasRootCerts, PRBool hasRootTrust);
-SECStatus NSSUTIL_ArgParseModuleSpec(char *modulespec, char **lib, char **mod,
- char **parameters, char **nss);
-char *NSSUTIL_MkModuleSpec(char *dllName, char *commonName,
- char *parameters, char *NSS);
-void NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers,char *cipherList);
-char * NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal,
- PRBool isFIPS, PRBool isModuleDB, PRBool isModuleDBOnly,
- PRBool isCritical, unsigned long trustOrder,
- unsigned long cipherOrder, unsigned long ssl0, unsigned long ssl1);
-
-/*
- * private functions for softoken.
- */
-char * _NSSUTIL_GetSecmodName(char *param, NSSDBType *dbType, char **appName, char **filename,PRBool *rw);
-const char *_NSSUTIL_EvaluateConfigDir(const char *configdir, NSSDBType *dbType, char **app);
-
-#endif /* _UTILPARS_H_ */
diff --git a/security/nss/lib/util/utilparst.h b/security/nss/lib/util/utilparst.h
deleted file mode 100644
index 01d87addf..000000000
--- a/security/nss/lib/util/utilparst.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef UTILPARS_T_H
-#define UTILPARS_T_H 1
-#include "pkcs11t.h"
-
-/*
- * macros to handle parsing strings of blank sparated arguments.
- * Several NSSUTIL_HANDLE_STRING() macros should be places one after another with no intervening
- * code. The first ones have precedence over the later ones. The last Macro should be
- * NSSUTIL_HANDLE_FINAL_ARG.
- *
- * param is the input parameters. On exit param will point to the next parameter to parse. If the
- * last paramter has been returned, param points to a null byte (*param = '0');
- * target is the location to store any data aquired from the parameter. Caller is responsible to free this data.
- * value is the string value of the parameter.
- * command is any commands you need to run to help process the parameter's data.
- */
-#define NSSUTIL_HANDLE_STRING_ARG(param,target,value,command) \
- if (PORT_Strncasecmp(param,value,sizeof(value)-1) == 0) { \
- param += sizeof(value)-1; \
- if (target) PORT_Free(target); \
- target = NSSUTIL_ArgFetchValue(param,&next); \
- param += next; \
- command ;\
- } else
-
-#define NSSUTIL_HANDLE_FINAL_ARG(param) \
- { param = NSSUTIL_ArgSkipParameter(param); } param = NSSUTIL_ArgStrip(param);
-
-#define NSSUTIL_PATH_SEPARATOR "/"
-
-/* default module configuration strings */
-#define NSSUTIL_DEFAULT_INTERNAL_INIT1 \
- "library= name=\"NSS Internal PKCS #11 Module\" parameters="
-#define NSSUTIL_DEFAULT_INTERNAL_INIT2 \
- " NSS=\"Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={"
-#define NSSUTIL_DEFAULT_INTERNAL_INIT3 \
- " askpw=any timeout=30})\""
-#define NSSUTIL_DEFAULT_SFTKN_FLAGS \
- "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512]"
-
-#define NSSUTIL_DEFAULT_CIPHER_ORDER 0
-#define NSSUTIL_DEFAULT_TRUST_ORDER 50
-#define NSSUTIL_ARG_ESCAPE '\\'
-
-
-/* hold slot default flags until we initialize a slot. This structure is only
- * useful between the time we define a module (either by hand or from the
- * database) and the time the module is loaded. Not reference counted */
-struct NSSUTILPreSlotInfoStr {
- CK_SLOT_ID slotID; /* slot these flags are for */
- unsigned long defaultFlags; /* bit mask of default implementation this slot
- * provides */
- int askpw; /* slot specific password bits */
- long timeout; /* slot specific timeout value */
- char hasRootCerts; /* is this the root cert PKCS #11 module? */
- char hasRootTrust; /* is this the root cert PKCS #11 module? */
- int reserved0[2];
- void *reserved1[2];
-};
-
-
-/*
- * private functions for softoken.
- */
-typedef enum {
- NSS_DB_TYPE_NONE= 0,
- NSS_DB_TYPE_SQL,
- NSS_DB_TYPE_EXTERN,
- NSS_DB_TYPE_LEGACY,
- NSS_DB_TYPE_MULTIACCESS
-} NSSDBType;
-
-#endif /* UTILPARS_T_H */
diff --git a/security/nss/lib/util/utilrename.h b/security/nss/lib/util/utilrename.h
deleted file mode 100644
index 1aea3d284..000000000
--- a/security/nss/lib/util/utilrename.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * utilrename.h - rename symbols moved from libnss3 to libnssutil3
- *
- */
-
-#ifndef _LIBUTIL_H_
-#define _LIBUTIL_H_ _LIBUTIL_H__Util
-
-#ifdef USE_UTIL_DIRECTLY
-
-/* functions moved from libnss3 */
-#define ATOB_AsciiToData ATOB_AsciiToData_Util
-#define ATOB_ConvertAsciiToItem ATOB_ConvertAsciiToItem_Util
-#define BTOA_ConvertItemToAscii BTOA_ConvertItemToAscii_Util
-#define BTOA_DataToAscii BTOA_DataToAscii_Util
-#define CERT_GenTime2FormattedAscii CERT_GenTime2FormattedAscii_Util
-#define DER_AsciiToTime DER_AsciiToTime_Util
-#define DER_DecodeTimeChoice DER_DecodeTimeChoice_Util
-#define DER_Encode DER_Encode_Util
-#define DER_EncodeTimeChoice DER_EncodeTimeChoice_Util
-#define DER_GeneralizedDayToAscii DER_GeneralizedDayToAscii_Util
-#define DER_GeneralizedTimeToTime DER_GeneralizedTimeToTime_Util
-#define DER_GetInteger DER_GetInteger_Util
-#define DER_Lengths DER_Lengths_Util
-#define DER_TimeChoiceDayToAscii DER_TimeChoiceDayToAscii_Util
-#define DER_TimeToGeneralizedTime DER_TimeToGeneralizedTime_Util
-#define DER_TimeToGeneralizedTimeArena DER_TimeToGeneralizedTimeArena_Util
-#define DER_TimeToUTCTime DER_TimeToUTCTime_Util
-#define DER_UTCDayToAscii DER_UTCDayToAscii_Util
-#define DER_UTCTimeToAscii DER_UTCTimeToAscii_Util
-#define DER_UTCTimeToTime DER_UTCTimeToTime_Util
-#define NSS_PutEnv NSS_PutEnv_Util
-#define NSSBase64_DecodeBuffer NSSBase64_DecodeBuffer_Util
-#define NSSBase64_EncodeItem NSSBase64_EncodeItem_Util
-#define NSSBase64Decoder_Create NSSBase64Decoder_Create_Util
-#define NSSBase64Decoder_Destroy NSSBase64Decoder_Destroy_Util
-#define NSSBase64Decoder_Update NSSBase64Decoder_Update_Util
-#define NSSBase64Encoder_Create NSSBase64Encoder_Create_Util
-#define NSSBase64Encoder_Destroy NSSBase64Encoder_Destroy_Util
-#define NSSBase64Encoder_Update NSSBase64Encoder_Update_Util
-#define NSSRWLock_Destroy NSSRWLock_Destroy_Util
-#define NSSRWLock_HaveWriteLock NSSRWLock_HaveWriteLock_Util
-#define NSSRWLock_LockRead NSSRWLock_LockRead_Util
-#define NSSRWLock_LockWrite NSSRWLock_LockWrite_Util
-#define NSSRWLock_New NSSRWLock_New_Util
-#define NSSRWLock_UnlockRead NSSRWLock_UnlockRead_Util
-#define NSSRWLock_UnlockWrite NSSRWLock_UnlockWrite_Util
-#define PORT_Alloc PORT_Alloc_Util
-#define PORT_ArenaAlloc PORT_ArenaAlloc_Util
-#define PORT_ArenaGrow PORT_ArenaGrow_Util
-#define PORT_ArenaMark PORT_ArenaMark_Util
-#define PORT_ArenaRelease PORT_ArenaRelease_Util
-#define PORT_ArenaStrdup PORT_ArenaStrdup_Util
-#define PORT_ArenaUnmark PORT_ArenaUnmark_Util
-#define PORT_ArenaZAlloc PORT_ArenaZAlloc_Util
-#define PORT_Free PORT_Free_Util
-#define PORT_FreeArena PORT_FreeArena_Util
-#define PORT_GetError PORT_GetError_Util
-#define PORT_NewArena PORT_NewArena_Util
-#define PORT_Realloc PORT_Realloc_Util
-#define PORT_SetError PORT_SetError_Util
-#define PORT_SetUCS2_ASCIIConversionFunction PORT_SetUCS2_ASCIIConversionFunction_Util
-#define PORT_SetUCS2_UTF8ConversionFunction PORT_SetUCS2_UTF8ConversionFunction_Util
-#define PORT_SetUCS4_UTF8ConversionFunction PORT_SetUCS4_UTF8ConversionFunction_Util
-#define PORT_Strdup PORT_Strdup_Util
-#define PORT_UCS2_ASCIIConversion PORT_UCS2_ASCIIConversion_Util
-#define PORT_UCS2_UTF8Conversion PORT_UCS2_UTF8Conversion_Util
-#define PORT_ZAlloc PORT_ZAlloc_Util
-#define PORT_ZFree PORT_ZFree_Util
-#define SEC_ASN1Decode SEC_ASN1Decode_Util
-#define SEC_ASN1DecodeInteger SEC_ASN1DecodeInteger_Util
-#define SEC_ASN1DecodeItem SEC_ASN1DecodeItem_Util
-#define SEC_ASN1DecoderAbort SEC_ASN1DecoderAbort_Util
-#define SEC_ASN1DecoderClearFilterProc SEC_ASN1DecoderClearFilterProc_Util
-#define SEC_ASN1DecoderClearNotifyProc SEC_ASN1DecoderClearNotifyProc_Util
-#define SEC_ASN1DecoderFinish SEC_ASN1DecoderFinish_Util
-#define SEC_ASN1DecoderSetFilterProc SEC_ASN1DecoderSetFilterProc_Util
-#define SEC_ASN1DecoderSetNotifyProc SEC_ASN1DecoderSetNotifyProc_Util
-#define SEC_ASN1DecoderStart SEC_ASN1DecoderStart_Util
-#define SEC_ASN1DecoderUpdate SEC_ASN1DecoderUpdate_Util
-#define SEC_ASN1Encode SEC_ASN1Encode_Util
-#define SEC_ASN1EncodeInteger SEC_ASN1EncodeInteger_Util
-#define SEC_ASN1EncodeItem SEC_ASN1EncodeItem_Util
-#define SEC_ASN1EncoderAbort SEC_ASN1EncoderAbort_Util
-#define SEC_ASN1EncoderClearNotifyProc SEC_ASN1EncoderClearNotifyProc_Util
-#define SEC_ASN1EncoderClearStreaming SEC_ASN1EncoderClearStreaming_Util
-#define SEC_ASN1EncoderClearTakeFromBuf SEC_ASN1EncoderClearTakeFromBuf_Util
-#define SEC_ASN1EncoderFinish SEC_ASN1EncoderFinish_Util
-#define SEC_ASN1EncoderSetNotifyProc SEC_ASN1EncoderSetNotifyProc_Util
-#define SEC_ASN1EncoderSetStreaming SEC_ASN1EncoderSetStreaming_Util
-#define SEC_ASN1EncoderSetTakeFromBuf SEC_ASN1EncoderSetTakeFromBuf_Util
-#define SEC_ASN1EncoderStart SEC_ASN1EncoderStart_Util
-#define SEC_ASN1EncoderUpdate SEC_ASN1EncoderUpdate_Util
-#define SEC_ASN1EncodeUnsignedInteger SEC_ASN1EncodeUnsignedInteger_Util
-#define SEC_ASN1LengthLength SEC_ASN1LengthLength_Util
-#define SEC_QuickDERDecodeItem SEC_QuickDERDecodeItem_Util
-#define SECITEM_AllocItem SECITEM_AllocItem_Util
-#define SECITEM_ArenaDupItem SECITEM_ArenaDupItem_Util
-#define SECITEM_CompareItem SECITEM_CompareItem_Util
-#define SECITEM_CopyItem SECITEM_CopyItem_Util
-#define SECITEM_DupItem SECITEM_DupItem_Util
-#define SECITEM_FreeItem SECITEM_FreeItem_Util
-#define SECITEM_ItemsAreEqual SECITEM_ItemsAreEqual_Util
-#define SECITEM_ZfreeItem SECITEM_ZfreeItem_Util
-#define SECOID_AddEntry SECOID_AddEntry_Util
-#define SECOID_CompareAlgorithmID SECOID_CompareAlgorithmID_Util
-#define SECOID_CopyAlgorithmID SECOID_CopyAlgorithmID_Util
-#define SECOID_DestroyAlgorithmID SECOID_DestroyAlgorithmID_Util
-#define SECOID_FindOID SECOID_FindOID_Util
-#define SECOID_FindOIDByTag SECOID_FindOIDByTag_Util
-#define SECOID_FindOIDTag SECOID_FindOIDTag_Util
-#define SECOID_FindOIDTagDescription SECOID_FindOIDTagDescription_Util
-#define SECOID_GetAlgorithmTag SECOID_GetAlgorithmTag_Util
-#define SECOID_SetAlgorithmID SECOID_SetAlgorithmID_Util
-#define SGN_CompareDigestInfo SGN_CompareDigestInfo_Util
-#define SGN_CopyDigestInfo SGN_CopyDigestInfo_Util
-#define SGN_CreateDigestInfo SGN_CreateDigestInfo_Util
-#define SGN_DestroyDigestInfo SGN_DestroyDigestInfo_Util
-
-/* templates moved from libnss3 */
-#define NSS_Get_SEC_AnyTemplate NSS_Get_SEC_AnyTemplate_Util
-#define NSS_Get_SEC_BitStringTemplate NSS_Get_SEC_BitStringTemplate_Util
-#define NSS_Get_SEC_BMPStringTemplate NSS_Get_SEC_BMPStringTemplate_Util
-#define NSS_Get_SEC_BooleanTemplate NSS_Get_SEC_BooleanTemplate_Util
-#define NSS_Get_SEC_GeneralizedTimeTemplate NSS_Get_SEC_GeneralizedTimeTemplate_Util
-#define NSS_Get_SEC_IA5StringTemplate NSS_Get_SEC_IA5StringTemplate_Util
-#define NSS_Get_SEC_IntegerTemplate NSS_Get_SEC_IntegerTemplate_Util
-#define NSS_Get_SEC_NullTemplate NSS_Get_SEC_NullTemplate_Util
-#define NSS_Get_SEC_ObjectIDTemplate NSS_Get_SEC_ObjectIDTemplate_Util
-#define NSS_Get_SEC_OctetStringTemplate NSS_Get_SEC_OctetStringTemplate_Util
-#define NSS_Get_SEC_PointerToAnyTemplate NSS_Get_SEC_PointerToAnyTemplate_Util
-#define NSS_Get_SEC_PointerToOctetStringTemplate NSS_Get_SEC_PointerToOctetStringTemplate_Util
-#define NSS_Get_SEC_SetOfAnyTemplate NSS_Get_SEC_SetOfAnyTemplate_Util
-#define NSS_Get_SEC_UTCTimeTemplate NSS_Get_SEC_UTCTimeTemplate_Util
-#define NSS_Get_SEC_UTF8StringTemplate NSS_Get_SEC_UTF8StringTemplate_Util
-#define NSS_Get_SECOID_AlgorithmIDTemplate NSS_Get_SECOID_AlgorithmIDTemplate_Util
-#define NSS_Get_sgn_DigestInfoTemplate NSS_Get_sgn_DigestInfoTemplate_Util
-#define SEC_AnyTemplate SEC_AnyTemplate_Util
-#define SEC_BitStringTemplate SEC_BitStringTemplate_Util
-#define SEC_BMPStringTemplate SEC_BMPStringTemplate_Util
-#define SEC_BooleanTemplate SEC_BooleanTemplate_Util
-#define SEC_GeneralizedTimeTemplate SEC_GeneralizedTimeTemplate_Util
-#define SEC_IA5StringTemplate SEC_IA5StringTemplate_Util
-#define SEC_IntegerTemplate SEC_IntegerTemplate_Util
-#define SEC_NullTemplate SEC_NullTemplate_Util
-#define SEC_ObjectIDTemplate SEC_ObjectIDTemplate_Util
-#define SEC_OctetStringTemplate SEC_OctetStringTemplate_Util
-#define SEC_PointerToAnyTemplate SEC_PointerToAnyTemplate_Util
-#define SEC_PointerToOctetStringTemplate SEC_PointerToOctetStringTemplate_Util
-#define SEC_SetOfAnyTemplate SEC_SetOfAnyTemplate_Util
-#define SEC_UTCTimeTemplate SEC_UTCTimeTemplate_Util
-#define SEC_UTF8StringTemplate SEC_UTF8StringTemplate_Util
-#define SECOID_AlgorithmIDTemplate SECOID_AlgorithmIDTemplate_Util
-#define sgn_DigestInfoTemplate sgn_DigestInfoTemplate_Util
-
-#endif /* USE_UTIL_DIRECTLY */
-
-#endif /* _LIBUTIL_H_ */
diff --git a/security/nss/lib/zlib/Makefile b/security/nss/lib/zlib/Makefile
deleted file mode 100644
index 183294f86..000000000
--- a/security/nss/lib/zlib/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-#! gmake
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#######################################################################
-# (1) Include initial platform-independent assignments (MANDATORY). #
-#######################################################################
-
-include manifest.mn
-
-#######################################################################
-# (2) Include "global" configuration information. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/config.mk
-
-#######################################################################
-# (3) Include "component" configuration information. (OPTIONAL) #
-#######################################################################
-
-
-#######################################################################
-# (4) Include "local" platform-dependent assignments (OPTIONAL). #
-#######################################################################
-
-include config.mk
-
-#######################################################################
-# (5) Execute "global" rules. (OPTIONAL) #
-#######################################################################
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-#######################################################################
-# (6) Execute "component" rules. (OPTIONAL) #
-#######################################################################
-
-
-
-#######################################################################
-# (7) Execute "local" rules. (OPTIONAL). #
-#######################################################################
-
-export:: private_export
-
-test: $(PROGRAMS)
- @cd $(OBJDIR); \
- if echo hello world | ./minigzip | ./minigzip -d && ./example; then \
- echo ' *** zlib test OK ***'; \
- else \
- echo ' *** zlib test FAILED ***'; false; \
- fi
- -@rm -f foo.gz
diff --git a/security/nss/lib/zlib/README b/security/nss/lib/zlib/README
deleted file mode 100644
index d4219bf88..000000000
--- a/security/nss/lib/zlib/README
+++ /dev/null
@@ -1,115 +0,0 @@
-ZLIB DATA COMPRESSION LIBRARY
-
-zlib 1.2.5 is a general purpose data compression library. All the code is
-thread safe. The data format used by the zlib library is described by RFCs
-(Request for Comments) 1950 to 1952 in the files
-http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
-and rfc1952.txt (gzip format).
-
-All functions of the compression library are documented in the file zlib.h
-(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
-of the library is given in the file example.c which also tests that the library
-is working correctly. Another example is given in the file minigzip.c. The
-compression library itself is composed of all source files except example.c and
-minigzip.c.
-
-To compile all files and run the test program, follow the instructions given at
-the top of Makefile.in. In short "./configure; make test", and if that goes
-well, "make install" should work for most flavors of Unix. For Windows, use one
-of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
-make_vms.com.
-
-Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
-<info@winimage.com> for the Windows DLL version. The zlib home page is
-http://zlib.net/ . Before reporting a problem, please check this site to
-verify that you have the latest version of zlib; otherwise get the latest
-version and check whether the problem still exists or not.
-
-PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
-
-Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
-issue of Dr. Dobb's Journal; a copy of the article is available at
-http://marknelson.us/1997/01/01/zlib-engine/ .
-
-The changes made in version 1.2.5 are documented in the file ChangeLog.
-
-Unsupported third party contributions are provided in directory contrib/ .
-
-zlib is available in Java using the java.util.zip package, documented at
-http://java.sun.com/developer/technicalArticles/Programming/compression/ .
-
-A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
-at CPAN (Comprehensive Perl Archive Network) sites, including
-http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
-
-A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
-available in Python 1.5 and later versions, see
-http://www.python.org/doc/lib/module-zlib.html .
-
-zlib is built into tcl: http://wiki.tcl.tk/4610 .
-
-An experimental package to read and write files in .zip format, written on top
-of zlib by Gilles Vollant <info@winimage.com>, is available in the
-contrib/minizip directory of zlib.
-
-
-Notes for some targets:
-
-- For Windows DLL versions, please see win32/DLL_FAQ.txt
-
-- For 64-bit Irix, deflate.c must be compiled without any optimization. With
- -O, one libpng test fails. The test works in 32 bit mode (with the -n32
- compiler flag). The compiler bug has been reported to SGI.
-
-- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
- when compiled with cc.
-
-- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
- necessary to get gzprintf working correctly. This is done by configure.
-
-- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
- other compilers. Use "make test" to check your compiler.
-
-- gzdopen is not supported on RISCOS or BEOS.
-
-- For PalmOs, see http://palmzlib.sourceforge.net/
-
-
-Acknowledgments:
-
- The deflate format used by zlib was defined by Phil Katz. The deflate and
- zlib specifications were written by L. Peter Deutsch. Thanks to all the
- people who reported problems and suggested various improvements in zlib; they
- are too numerous to cite here.
-
-Copyright notice:
-
- (C) 1995-2010 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
-If you use the zlib library in a product, we would appreciate *not* receiving
-lengthy legal documents to sign. The sources are provided for free but without
-warranty of any kind. The library has been entirely written by Jean-loup
-Gailly and Mark Adler; it does not include third-party code.
-
-If you redistribute modified sources, we would appreciate that you include in
-the file ChangeLog history information documenting your changes. Please read
-the FAQ for more information on the distribution of modified source versions.
diff --git a/security/nss/lib/zlib/README.nss b/security/nss/lib/zlib/README.nss
deleted file mode 100644
index 58ad213a0..000000000
--- a/security/nss/lib/zlib/README.nss
+++ /dev/null
@@ -1,18 +0,0 @@
-zlib data compression library
-
-URL: http://zlib.net/
-Version: 1.2.5
-License: zlib License
-License File: http://zlib.net/zlib_license.html
-
-Description:
-
-NSS uses zlib in libSSL (for the DEFLATE compression method), modutil, and
-signtool.
-
-Local Modifications:
-
-- patches/prune-zlib.sh: run this shell script to remove unneeded files
- from the zlib distribution.
-- patches/msvc-vsnprintf.patch: define HAVE_VSNPRINTF for Visual C++ 2008
- (9.0) and later.
diff --git a/security/nss/lib/zlib/adler32.c b/security/nss/lib/zlib/adler32.c
deleted file mode 100644
index 65ad6a5ad..000000000
--- a/security/nss/lib/zlib/adler32.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2007 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zutil.h"
-
-#define local static
-
-local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
-
-#define BASE 65521UL /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* use NO_DIVIDE if your processor does not do division in hardware */
-#ifdef NO_DIVIDE
-# define MOD(a) \
- do { \
- if (a >= (BASE << 16)) a -= (BASE << 16); \
- if (a >= (BASE << 15)) a -= (BASE << 15); \
- if (a >= (BASE << 14)) a -= (BASE << 14); \
- if (a >= (BASE << 13)) a -= (BASE << 13); \
- if (a >= (BASE << 12)) a -= (BASE << 12); \
- if (a >= (BASE << 11)) a -= (BASE << 11); \
- if (a >= (BASE << 10)) a -= (BASE << 10); \
- if (a >= (BASE << 9)) a -= (BASE << 9); \
- if (a >= (BASE << 8)) a -= (BASE << 8); \
- if (a >= (BASE << 7)) a -= (BASE << 7); \
- if (a >= (BASE << 6)) a -= (BASE << 6); \
- if (a >= (BASE << 5)) a -= (BASE << 5); \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-# define MOD4(a) \
- do { \
- if (a >= (BASE << 4)) a -= (BASE << 4); \
- if (a >= (BASE << 3)) a -= (BASE << 3); \
- if (a >= (BASE << 2)) a -= (BASE << 2); \
- if (a >= (BASE << 1)) a -= (BASE << 1); \
- if (a >= BASE) a -= BASE; \
- } while (0)
-#else
-# define MOD(a) a %= BASE
-# define MOD4(a) a %= BASE
-#endif
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
- uLong adler;
- const Bytef *buf;
- uInt len;
-{
- unsigned long sum2;
- unsigned n;
-
- /* split Adler-32 into component sums */
- sum2 = (adler >> 16) & 0xffff;
- adler &= 0xffff;
-
- /* in case user likes doing a byte at a time, keep it fast */
- if (len == 1) {
- adler += buf[0];
- if (adler >= BASE)
- adler -= BASE;
- sum2 += adler;
- if (sum2 >= BASE)
- sum2 -= BASE;
- return adler | (sum2 << 16);
- }
-
- /* initial Adler-32 value (deferred check for len == 1 speed) */
- if (buf == Z_NULL)
- return 1L;
-
- /* in case short lengths are provided, keep it somewhat fast */
- if (len < 16) {
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- if (adler >= BASE)
- adler -= BASE;
- MOD4(sum2); /* only added so many BASE's */
- return adler | (sum2 << 16);
- }
-
- /* do length NMAX blocks -- requires just one modulo operation */
- while (len >= NMAX) {
- len -= NMAX;
- n = NMAX / 16; /* NMAX is divisible by 16 */
- do {
- DO16(buf); /* 16 sums unrolled */
- buf += 16;
- } while (--n);
- MOD(adler);
- MOD(sum2);
- }
-
- /* do remaining bytes (less than NMAX, still just one modulo) */
- if (len) { /* avoid modulos if none remaining */
- while (len >= 16) {
- len -= 16;
- DO16(buf);
- buf += 16;
- }
- while (len--) {
- adler += *buf++;
- sum2 += adler;
- }
- MOD(adler);
- MOD(sum2);
- }
-
- /* return recombined sums */
- return adler | (sum2 << 16);
-}
-
-/* ========================================================================= */
-local uLong adler32_combine_(adler1, adler2, len2)
- uLong adler1;
- uLong adler2;
- z_off64_t len2;
-{
- unsigned long sum1;
- unsigned long sum2;
- unsigned rem;
-
- /* the derivation of this formula is left as an exercise for the reader */
- rem = (unsigned)(len2 % BASE);
- sum1 = adler1 & 0xffff;
- sum2 = rem * sum1;
- MOD(sum2);
- sum1 += (adler2 & 0xffff) + BASE - 1;
- sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
- if (sum1 >= BASE) sum1 -= BASE;
- if (sum1 >= BASE) sum1 -= BASE;
- if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
- if (sum2 >= BASE) sum2 -= BASE;
- return sum1 | (sum2 << 16);
-}
-
-/* ========================================================================= */
-uLong ZEXPORT adler32_combine(adler1, adler2, len2)
- uLong adler1;
- uLong adler2;
- z_off_t len2;
-{
- return adler32_combine_(adler1, adler2, len2);
-}
-
-uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
- uLong adler1;
- uLong adler2;
- z_off64_t len2;
-{
- return adler32_combine_(adler1, adler2, len2);
-}
diff --git a/security/nss/lib/zlib/compress.c b/security/nss/lib/zlib/compress.c
deleted file mode 100644
index ea4dfbe9d..000000000
--- a/security/nss/lib/zlib/compress.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
- int level;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
-
-/* ===========================================================================
- If the default memLevel or windowBits for deflateInit() is changed, then
- this function needs to be updated.
- */
-uLong ZEXPORT compressBound (sourceLen)
- uLong sourceLen;
-{
- return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
- (sourceLen >> 25) + 13;
-}
diff --git a/security/nss/lib/zlib/config.mk b/security/nss/lib/zlib/config.mk
deleted file mode 100644
index 0091d01b6..000000000
--- a/security/nss/lib/zlib/config.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY) $(PROGRAMS)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
-EXTRA_LIBS = $(LIBRARY)
diff --git a/security/nss/lib/zlib/crc32.c b/security/nss/lib/zlib/crc32.c
deleted file mode 100644
index 91be372d2..000000000
--- a/security/nss/lib/zlib/crc32.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2006, 2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
- * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
- * tables for updating the shift register in one step with three exclusive-ors
- * instead of four steps with four exclusive-ors. This results in about a
- * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
- */
-
-/* @(#) $Id$ */
-
-/*
- Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
- protection on the static variables used to control the first-use generation
- of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
- first call get_crc_table() to initialize the tables before allowing more than
- one thread to use crc32().
- */
-
-#ifdef MAKECRCH
-# include <stdio.h>
-# ifndef DYNAMIC_CRC_TABLE
-# define DYNAMIC_CRC_TABLE
-# endif /* !DYNAMIC_CRC_TABLE */
-#endif /* MAKECRCH */
-
-#include "zutil.h" /* for STDC and FAR definitions */
-
-#define local static
-
-/* Find a four-byte integer type for crc32_little() and crc32_big(). */
-#ifndef NOBYFOUR
-# ifdef STDC /* need ANSI C limits.h to determine sizes */
-# include <limits.h>
-# define BYFOUR
-# if (UINT_MAX == 0xffffffffUL)
- typedef unsigned int u4;
-# else
-# if (ULONG_MAX == 0xffffffffUL)
- typedef unsigned long u4;
-# else
-# if (USHRT_MAX == 0xffffffffUL)
- typedef unsigned short u4;
-# else
-# undef BYFOUR /* can't find a four-byte integer type! */
-# endif
-# endif
-# endif
-# endif /* STDC */
-#endif /* !NOBYFOUR */
-
-/* Definitions for doing the crc four data bytes at a time. */
-#ifdef BYFOUR
-# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
- (((w)&0xff00)<<8)+(((w)&0xff)<<24))
- local unsigned long crc32_little OF((unsigned long,
- const unsigned char FAR *, unsigned));
- local unsigned long crc32_big OF((unsigned long,
- const unsigned char FAR *, unsigned));
-# define TBLS 8
-#else
-# define TBLS 1
-#endif /* BYFOUR */
-
-/* Local functions for crc concatenation */
-local unsigned long gf2_matrix_times OF((unsigned long *mat,
- unsigned long vec));
-local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
-local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
-
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local volatile int crc_table_empty = 1;
-local unsigned long FAR crc_table[TBLS][256];
-local void make_crc_table OF((void));
-#ifdef MAKECRCH
- local void write_table OF((FILE *, const unsigned long FAR *));
-#endif /* MAKECRCH */
-/*
- Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The first table is simply the CRC of all possible eight bit values. This is
- all the information needed to generate CRCs on data a byte at a time for all
- combinations of CRC register values and incoming bytes. The remaining tables
- allow for word-at-a-time CRC calculation for both big-endian and little-
- endian machines, where a word is four bytes.
-*/
-local void make_crc_table()
-{
- unsigned long c;
- int n, k;
- unsigned long poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static volatile int first = 1; /* flag to limit concurrent making */
- static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* See if another task is already doing this (not thread-safe, but better
- than nothing -- significantly reduces duration of vulnerability in
- case the advice about DYNAMIC_CRC_TABLE is ignored) */
- if (first) {
- first = 0;
-
- /* make exclusive-or pattern from polynomial (0xedb88320UL) */
- poly = 0UL;
- for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
- poly |= 1UL << (31 - p[n]);
-
- /* generate a crc for every 8-bit value */
- for (n = 0; n < 256; n++) {
- c = (unsigned long)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[0][n] = c;
- }
-
-#ifdef BYFOUR
- /* generate crc for each value followed by one, two, and three zeros,
- and then the byte reversal of those as well as the first table */
- for (n = 0; n < 256; n++) {
- c = crc_table[0][n];
- crc_table[4][n] = REV(c);
- for (k = 1; k < 4; k++) {
- c = crc_table[0][c & 0xff] ^ (c >> 8);
- crc_table[k][n] = c;
- crc_table[k + 4][n] = REV(c);
- }
- }
-#endif /* BYFOUR */
-
- crc_table_empty = 0;
- }
- else { /* not first */
- /* wait for the other guy to finish (not efficient, but rare) */
- while (crc_table_empty)
- ;
- }
-
-#ifdef MAKECRCH
- /* write out CRC tables to crc32.h */
- {
- FILE *out;
-
- out = fopen("crc32.h", "w");
- if (out == NULL) return;
- fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
- fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
- fprintf(out, "local const unsigned long FAR ");
- fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
- write_table(out, crc_table[0]);
-# ifdef BYFOUR
- fprintf(out, "#ifdef BYFOUR\n");
- for (k = 1; k < 8; k++) {
- fprintf(out, " },\n {\n");
- write_table(out, crc_table[k]);
- }
- fprintf(out, "#endif\n");
-# endif /* BYFOUR */
- fprintf(out, " }\n};\n");
- fclose(out);
- }
-#endif /* MAKECRCH */
-}
-
-#ifdef MAKECRCH
-local void write_table(out, table)
- FILE *out;
- const unsigned long FAR *table;
-{
- int n;
-
- for (n = 0; n < 256; n++)
- fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
- n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
-}
-#endif /* MAKECRCH */
-
-#else /* !DYNAMIC_CRC_TABLE */
-/* ========================================================================
- * Tables of CRC-32s of all single-byte values, made by make_crc_table().
- */
-#include "crc32.h"
-#endif /* DYNAMIC_CRC_TABLE */
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const unsigned long FAR * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
- return (const unsigned long FAR *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
-#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-
-/* ========================================================================= */
-unsigned long ZEXPORT crc32(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- uInt len;
-{
- if (buf == Z_NULL) return 0UL;
-
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif /* DYNAMIC_CRC_TABLE */
-
-#ifdef BYFOUR
- if (sizeof(void *) == sizeof(ptrdiff_t)) {
- u4 endian;
-
- endian = 1;
- if (*((unsigned char *)(&endian)))
- return crc32_little(crc, buf, len);
- else
- return crc32_big(crc, buf, len);
- }
-#endif /* BYFOUR */
- crc = crc ^ 0xffffffffUL;
- while (len >= 8) {
- DO8;
- len -= 8;
- }
- if (len) do {
- DO1;
- } while (--len);
- return crc ^ 0xffffffffUL;
-}
-
-#ifdef BYFOUR
-
-/* ========================================================================= */
-#define DOLIT4 c ^= *buf4++; \
- c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
- crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
-#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
-
-/* ========================================================================= */
-local unsigned long crc32_little(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = (u4)crc;
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- while (len >= 32) {
- DOLIT32;
- len -= 32;
- }
- while (len >= 4) {
- DOLIT4;
- len -= 4;
- }
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- } while (--len);
- c = ~c;
- return (unsigned long)c;
-}
-
-/* ========================================================================= */
-#define DOBIG4 c ^= *++buf4; \
- c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
- crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
-#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
-
-/* ========================================================================= */
-local unsigned long crc32_big(crc, buf, len)
- unsigned long crc;
- const unsigned char FAR *buf;
- unsigned len;
-{
- register u4 c;
- register const u4 FAR *buf4;
-
- c = REV((u4)crc);
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- len--;
- }
-
- buf4 = (const u4 FAR *)(const void FAR *)buf;
- buf4--;
- while (len >= 32) {
- DOBIG32;
- len -= 32;
- }
- while (len >= 4) {
- DOBIG4;
- len -= 4;
- }
- buf4++;
- buf = (const unsigned char FAR *)buf4;
-
- if (len) do {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
- } while (--len);
- c = ~c;
- return (unsigned long)(REV(c));
-}
-
-#endif /* BYFOUR */
-
-#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
-
-/* ========================================================================= */
-local unsigned long gf2_matrix_times(mat, vec)
- unsigned long *mat;
- unsigned long vec;
-{
- unsigned long sum;
-
- sum = 0;
- while (vec) {
- if (vec & 1)
- sum ^= *mat;
- vec >>= 1;
- mat++;
- }
- return sum;
-}
-
-/* ========================================================================= */
-local void gf2_matrix_square(square, mat)
- unsigned long *square;
- unsigned long *mat;
-{
- int n;
-
- for (n = 0; n < GF2_DIM; n++)
- square[n] = gf2_matrix_times(mat, mat[n]);
-}
-
-/* ========================================================================= */
-local uLong crc32_combine_(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off64_t len2;
-{
- int n;
- unsigned long row;
- unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
- unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
-
- /* degenerate case (also disallow negative lengths) */
- if (len2 <= 0)
- return crc1;
-
- /* put operator for one zero bit in odd */
- odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
- row = 1;
- for (n = 1; n < GF2_DIM; n++) {
- odd[n] = row;
- row <<= 1;
- }
-
- /* put operator for two zero bits in even */
- gf2_matrix_square(even, odd);
-
- /* put operator for four zero bits in odd */
- gf2_matrix_square(odd, even);
-
- /* apply len2 zeros to crc1 (first square will put the operator for one
- zero byte, eight zero bits, in even) */
- do {
- /* apply zeros operator for this bit of len2 */
- gf2_matrix_square(even, odd);
- if (len2 & 1)
- crc1 = gf2_matrix_times(even, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- if (len2 == 0)
- break;
-
- /* another iteration of the loop with odd and even swapped */
- gf2_matrix_square(odd, even);
- if (len2 & 1)
- crc1 = gf2_matrix_times(odd, crc1);
- len2 >>= 1;
-
- /* if no more bits set, then done */
- } while (len2 != 0);
-
- /* return combined crc */
- crc1 ^= crc2;
- return crc1;
-}
-
-/* ========================================================================= */
-uLong ZEXPORT crc32_combine(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off_t len2;
-{
- return crc32_combine_(crc1, crc2, len2);
-}
-
-uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
- uLong crc1;
- uLong crc2;
- z_off64_t len2;
-{
- return crc32_combine_(crc1, crc2, len2);
-}
diff --git a/security/nss/lib/zlib/crc32.h b/security/nss/lib/zlib/crc32.h
deleted file mode 100644
index 7156a5a73..000000000
--- a/security/nss/lib/zlib/crc32.h
+++ /dev/null
@@ -1,445 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* crc32.h -- tables for rapid CRC calculation
- * Generated automatically by crc32.c
- */
-
-local const unsigned long FAR crc_table[TBLS][256] =
-{
- {
- 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
- 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
- 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
- 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
- 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
- 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
- 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
- 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
- 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
- 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
- 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
- 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
- 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
- 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
- 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
- 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
- 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
- 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
- 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
- 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
- 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
- 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
- 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
- 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
- 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
- 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
- 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
- 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
- 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
- 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
- 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
- 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
- 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
- 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
- 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
- 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
- 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
- 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
- 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
- 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
- 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
- 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
- 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
- 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
- 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
- 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
- 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
- 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
- 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
- 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
- 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
- 0x2d02ef8dUL
-#ifdef BYFOUR
- },
- {
- 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
- 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
- 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
- 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
- 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
- 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
- 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
- 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
- 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
- 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
- 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
- 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
- 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
- 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
- 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
- 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
- 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
- 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
- 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
- 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
- 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
- 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
- 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
- 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
- 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
- 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
- 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
- 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
- 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
- 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
- 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
- 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
- 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
- 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
- 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
- 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
- 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
- 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
- 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
- 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
- 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
- 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
- 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
- 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
- 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
- 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
- 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
- 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
- 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
- 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
- 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
- 0x9324fd72UL
- },
- {
- 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
- 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
- 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
- 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
- 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
- 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
- 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
- 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
- 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
- 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
- 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
- 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
- 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
- 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
- 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
- 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
- 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
- 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
- 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
- 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
- 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
- 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
- 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
- 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
- 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
- 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
- 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
- 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
- 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
- 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
- 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
- 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
- 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
- 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
- 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
- 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
- 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
- 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
- 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
- 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
- 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
- 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
- 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
- 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
- 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
- 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
- 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
- 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
- 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
- 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
- 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
- 0xbe9834edUL
- },
- {
- 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
- 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
- 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
- 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
- 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
- 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
- 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
- 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
- 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
- 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
- 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
- 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
- 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
- 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
- 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
- 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
- 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
- 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
- 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
- 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
- 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
- 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
- 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
- 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
- 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
- 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
- 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
- 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
- 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
- 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
- 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
- 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
- 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
- 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
- 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
- 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
- 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
- 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
- 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
- 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
- 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
- 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
- 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
- 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
- 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
- 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
- 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
- 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
- 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
- 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
- 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
- 0xde0506f1UL
- },
- {
- 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
- 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
- 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
- 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
- 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
- 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
- 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
- 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
- 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
- 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
- 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
- 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
- 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
- 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
- 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
- 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
- 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
- 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
- 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
- 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
- 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
- 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
- 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
- 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
- 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
- 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
- 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
- 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
- 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
- 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
- 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
- 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
- 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
- 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
- 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
- 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
- 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
- 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
- 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
- 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
- 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
- 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
- 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
- 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
- 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
- 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
- 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
- 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
- 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
- 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
- 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
- 0x8def022dUL
- },
- {
- 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
- 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
- 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
- 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
- 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
- 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
- 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
- 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
- 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
- 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
- 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
- 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
- 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
- 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
- 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
- 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
- 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
- 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
- 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
- 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
- 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
- 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
- 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
- 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
- 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
- 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
- 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
- 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
- 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
- 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
- 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
- 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
- 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
- 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
- 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
- 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
- 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
- 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
- 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
- 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
- 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
- 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
- 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
- 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
- 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
- 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
- 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
- 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
- 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
- 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
- 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
- 0x72fd2493UL
- },
- {
- 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
- 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
- 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
- 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
- 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
- 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
- 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
- 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
- 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
- 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
- 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
- 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
- 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
- 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
- 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
- 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
- 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
- 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
- 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
- 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
- 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
- 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
- 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
- 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
- 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
- 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
- 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
- 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
- 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
- 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
- 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
- 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
- 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
- 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
- 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
- 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
- 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
- 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
- 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
- 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
- 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
- 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
- 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
- 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
- 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
- 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
- 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
- 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
- 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
- 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
- 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
- 0xed3498beUL
- },
- {
- 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
- 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
- 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
- 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
- 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
- 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
- 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
- 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
- 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
- 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
- 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
- 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
- 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
- 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
- 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
- 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
- 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
- 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
- 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
- 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
- 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
- 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
- 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
- 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
- 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
- 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
- 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
- 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
- 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
- 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
- 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
- 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
- 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
- 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
- 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
- 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
- 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
- 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
- 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
- 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
- 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
- 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
- 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
- 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
- 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
- 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
- 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
- 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
- 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
- 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
- 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
- 0xf10605deUL
-#endif
- }
-};
diff --git a/security/nss/lib/zlib/deflate.c b/security/nss/lib/zlib/deflate.c
deleted file mode 100644
index 5c4022f3d..000000000
--- a/security/nss/lib/zlib/deflate.c
+++ /dev/null
@@ -1,1834 +0,0 @@
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in http://www.ietf.org/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id$ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
- " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast OF((deflate_state *s, int flush));
-#ifndef FASTEST
-local block_state deflate_slow OF((deflate_state *s, int flush));
-#endif
-local block_state deflate_rle OF((deflate_state *s, int flush));
-local block_state deflate_huff OF((deflate_state *s, int flush));
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-#ifdef FASTEST
-local const config configuration_table[2] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
-#else
-local const config configuration_table[10] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
-/* 2 */ {4, 5, 16, 8, deflate_fast},
-/* 3 */ {4, 6, 32, 32, deflate_fast},
-
-/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-/* 5 */ {8, 16, 32, 32, deflate_slow},
-/* 6 */ {8, 16, 128, 128, deflate_slow},
-/* 7 */ {8, 32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
-#endif
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-#ifndef NO_DUMMY_DECL
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-#endif
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int wrap = 1;
- static const char my_version[] = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
-
- if (windowBits < 0) { /* suppress zlib wrapper */
- wrap = 0;
- windowBits = -windowBits;
- }
-#ifdef GZIP
- else if (windowBits > 15) {
- wrap = 2; /* write gzip wrapper instead */
- windowBits -= 16;
- }
-#endif
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->wrap = wrap;
- s->gzhead = Z_NULL;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->high_water = 0; /* nothing written to s->window yet */
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- s->status = FINISH_STATE;
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->wrap == 2 ||
- (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
- return Z_STREAM_ERROR;
-
- s = strm->state;
- if (s->wrap)
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > s->w_size) {
- length = s->w_size;
- dictionary += dictLength - length; /* use the tail of the dictionary */
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
- return Z_STREAM_ERROR;
- }
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->wrap < 0) {
- s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
- }
- s->status = s->wrap ? INIT_STATE : BUSY_STATE;
- strm->adler =
-#ifdef GZIP
- s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
-#endif
- adler32(0L, Z_NULL, 0);
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetHeader (strm, head)
- z_streamp strm;
- gz_headerp head;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- if (strm->state->wrap != 2) return Z_STREAM_ERROR;
- strm->state->gzhead = head;
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflatePrime (strm, bits, value)
- z_streamp strm;
- int bits;
- int value;
-{
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- strm->state->bi_valid = bits;
- strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
-#ifdef FASTEST
- if (level != 0) level = 1;
-#else
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#endif
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if ((strategy != s->strategy || func != configuration_table[level].func) &&
- strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_BLOCK);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
- z_streamp strm;
- int good_length;
- int max_lazy;
- int nice_length;
- int max_chain;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
- s->good_match = good_length;
- s->max_lazy_match = max_lazy;
- s->nice_match = nice_length;
- s->max_chain_length = max_chain;
- return Z_OK;
-}
-
-/* =========================================================================
- * For the default windowBits of 15 and memLevel of 8, this function returns
- * a close to exact, as well as small, upper bound on the compressed size.
- * They are coded as constants here for a reason--if the #define's are
- * changed, then this function needs to be changed as well. The return
- * value for 15 and 8 only works for those exact settings.
- *
- * For any setting other than those defaults for windowBits and memLevel,
- * the value returned is a conservative worst case for the maximum expansion
- * resulting from using fixed blocks instead of stored blocks, which deflate
- * can emit on compressed data for some combinations of the parameters.
- *
- * This function could be more sophisticated to provide closer upper bounds for
- * every combination of windowBits and memLevel. But even the conservative
- * upper bound of about 14% expansion does not seem onerous for output buffer
- * allocation.
- */
-uLong ZEXPORT deflateBound(strm, sourceLen)
- z_streamp strm;
- uLong sourceLen;
-{
- deflate_state *s;
- uLong complen, wraplen;
- Bytef *str;
-
- /* conservative upper bound for compressed data */
- complen = sourceLen +
- ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
-
- /* if can't get parameters, return conservative bound plus zlib wrapper */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return complen + 6;
-
- /* compute wrapper length */
- s = strm->state;
- switch (s->wrap) {
- case 0: /* raw deflate */
- wraplen = 0;
- break;
- case 1: /* zlib wrapper */
- wraplen = 6 + (s->strstart ? 4 : 0);
- break;
- case 2: /* gzip wrapper */
- wraplen = 18;
- if (s->gzhead != Z_NULL) { /* user-supplied gzip header */
- if (s->gzhead->extra != Z_NULL)
- wraplen += 2 + s->gzhead->extra_len;
- str = s->gzhead->name;
- if (str != Z_NULL)
- do {
- wraplen++;
- } while (*str++);
- str = s->gzhead->comment;
- if (str != Z_NULL)
- do {
- wraplen++;
- } while (*str++);
- if (s->gzhead->hcrc)
- wraplen += 2;
- }
- break;
- default: /* for compiler happiness */
- wraplen = 6;
- }
-
- /* if not default parameters, return conservative bound */
- if (s->w_bits != 15 || s->hash_bits != 8 + 7)
- return complen + wraplen;
-
- /* default settings: return tight bound for that case */
- return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
- (sourceLen >> 25) + 13 - 6 + wraplen;
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_BLOCK || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the header */
- if (s->status == INIT_STATE) {
-#ifdef GZIP
- if (s->wrap == 2) {
- strm->adler = crc32(0L, Z_NULL, 0);
- put_byte(s, 31);
- put_byte(s, 139);
- put_byte(s, 8);
- if (s->gzhead == Z_NULL) {
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, 0);
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, OS_CODE);
- s->status = BUSY_STATE;
- }
- else {
- put_byte(s, (s->gzhead->text ? 1 : 0) +
- (s->gzhead->hcrc ? 2 : 0) +
- (s->gzhead->extra == Z_NULL ? 0 : 4) +
- (s->gzhead->name == Z_NULL ? 0 : 8) +
- (s->gzhead->comment == Z_NULL ? 0 : 16)
- );
- put_byte(s, (Byte)(s->gzhead->time & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
- put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
- put_byte(s, s->level == 9 ? 2 :
- (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
- 4 : 0));
- put_byte(s, s->gzhead->os & 0xff);
- if (s->gzhead->extra != Z_NULL) {
- put_byte(s, s->gzhead->extra_len & 0xff);
- put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
- }
- if (s->gzhead->hcrc)
- strm->adler = crc32(strm->adler, s->pending_buf,
- s->pending);
- s->gzindex = 0;
- s->status = EXTRA_STATE;
- }
- }
- else
-#endif
- {
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags;
-
- if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
- level_flags = 0;
- else if (s->level < 6)
- level_flags = 1;
- else if (s->level == 6)
- level_flags = 2;
- else
- level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = adler32(0L, Z_NULL, 0);
- }
- }
-#ifdef GZIP
- if (s->status == EXTRA_STATE) {
- if (s->gzhead->extra != Z_NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
-
- while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size)
- break;
- }
- put_byte(s, s->gzhead->extra[s->gzindex]);
- s->gzindex++;
- }
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (s->gzindex == s->gzhead->extra_len) {
- s->gzindex = 0;
- s->status = NAME_STATE;
- }
- }
- else
- s->status = NAME_STATE;
- }
- if (s->status == NAME_STATE) {
- if (s->gzhead->name != Z_NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->name[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0) {
- s->gzindex = 0;
- s->status = COMMENT_STATE;
- }
- }
- else
- s->status = COMMENT_STATE;
- }
- if (s->status == COMMENT_STATE) {
- if (s->gzhead->comment != Z_NULL) {
- uInt beg = s->pending; /* start of bytes to update crc */
- int val;
-
- do {
- if (s->pending == s->pending_buf_size) {
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- flush_pending(strm);
- beg = s->pending;
- if (s->pending == s->pending_buf_size) {
- val = 1;
- break;
- }
- }
- val = s->gzhead->comment[s->gzindex++];
- put_byte(s, val);
- } while (val != 0);
- if (s->gzhead->hcrc && s->pending > beg)
- strm->adler = crc32(strm->adler, s->pending_buf + beg,
- s->pending - beg);
- if (val == 0)
- s->status = HCRC_STATE;
- }
- else
- s->status = HCRC_STATE;
- }
- if (s->status == HCRC_STATE) {
- if (s->gzhead->hcrc) {
- if (s->pending + 2 > s->pending_buf_size)
- flush_pending(strm);
- if (s->pending + 2 <= s->pending_buf_size) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- strm->adler = crc32(0L, Z_NULL, 0);
- s->status = BUSY_STATE;
- }
- }
- else
- s->status = BUSY_STATE;
- }
-#endif
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
- (s->strategy == Z_RLE ? deflate_rle(s, flush) :
- (*(configuration_table[s->level].func))(s, flush));
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- if (s->lookahead == 0) {
- s->strstart = 0;
- s->block_start = 0L;
- }
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->wrap <= 0) return Z_STREAM_END;
-
- /* Write the trailer */
-#ifdef GZIP
- if (s->wrap == 2) {
- put_byte(s, (Byte)(strm->adler & 0xff));
- put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
- put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
- put_byte(s, (Byte)(strm->total_in & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
- put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
- }
- else
-#endif
- {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE &&
- status != EXTRA_STATE &&
- status != NAME_STATE &&
- status != COMMENT_STATE &&
- status != HCRC_STATE &&
- status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
- z_streamp dest;
- z_streamp source;
-{
-#ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
-#else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- zmemcpy(dest, source, sizeof(z_stream));
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- zmemcpy(ds, ss, sizeof(deflate_state));
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
-#endif /* MAXSEG_64K */
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (strm->state->wrap == 1) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
-#ifdef GZIP
- else if (strm->state->wrap == 2) {
- strm->adler = crc32(strm->adler, strm->next_in, len);
- }
-#endif
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifndef FASTEST
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-#endif
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2. Note that the checks below
- * for insufficient lookahead only occur occasionally for performance
- * reasons. Therefore uninitialized memory will be accessed, and
- * conditional jumps will be made that depend on those values.
- * However the length of the match is limited to the lookahead, so
- * the output of deflate is not affected by the uninitialized values.
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-#endif /* ASMV */
-
-#else /* FASTEST */
-
-/* ---------------------------------------------------------------------------
- * Optimized version for FASTEST only
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
-}
-
-#endif /* FASTEST */
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
- deflate_state *s;
- IPos start, match;
- int length;
-{
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
-}
-#else
-# define check_match(s, start, match, length)
-#endif /* DEBUG */
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (sizeof(int) <= 2) {
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if
- * strstart == 0 && lookahead == 1 (input done a byte at time)
- */
- more--;
- }
- }
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-
- /* If the WIN_INIT bytes after the end of the current data have never been
- * written, then zero those bytes in order to avoid memory check reports of
- * the use of uninitialized (or uninitialised as Julian writes) bytes by
- * the longest match routines. Update the high water mark for the next
- * time through here. WIN_INIT is set to MAX_MATCH since the longest match
- * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
- */
- if (s->high_water < s->window_size) {
- ulg curr = s->strstart + (ulg)(s->lookahead);
- ulg init;
-
- if (s->high_water < curr) {
- /* Previous high water mark below current data -- zero WIN_INIT
- * bytes or up to end of window, whichever is less.
- */
- init = s->window_size - curr;
- if (init > WIN_INIT)
- init = WIN_INIT;
- zmemzero(s->window + curr, (unsigned)init);
- s->high_water = curr + init;
- }
- else if (s->high_water < (ulg)curr + WIN_INIT) {
- /* High water mark at or above current data, but below current data
- * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
- * to end of window, whichever is less.
- */
- init = (ulg)curr + WIN_INIT - s->high_water;
- if (init > s->window_size - s->high_water)
- init = s->window_size - s->high_water;
- zmemzero(s->window + s->high_water, (unsigned)init);
- s->high_water += init;
- }
- }
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, last) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (last)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, last) { \
- FLUSH_BLOCK_ONLY(s, last); \
- if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
- deflate_state *s;
- int flush;
-{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- hash_head = NIL;
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- s->match_length = longest_match (s, hash_head);
- /* longest_match() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
-#ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
-#endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-#ifndef FASTEST
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- hash_head = NIL;
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- s->match_length = longest_match (s, hash_head);
- /* longest_match() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED
-#if TOO_FAR <= 32767
- || (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR)
-#endif
- )) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-#endif /* FASTEST */
-
-/* ===========================================================================
- * For Z_RLE, simply look for runs of bytes, generate matches only of distance
- * one. Do not maintain a hash table. (It will be regenerated if this run of
- * deflate switches away from Z_RLE.)
- */
-local block_state deflate_rle(s, flush)
- deflate_state *s;
- int flush;
-{
- int bflush; /* set if current block must be flushed */
- uInt prev; /* byte at distance one to match */
- Bytef *scan, *strend; /* scan goes up to strend for length of run */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the longest encodable run.
- */
- if (s->lookahead < MAX_MATCH) {
- fill_window(s);
- if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* See how many times the previous byte repeats */
- s->match_length = 0;
- if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
- scan = s->window + s->strstart - 1;
- prev = *scan;
- if (prev == *++scan && prev == *++scan && prev == *++scan) {
- strend = s->window + s->strstart + MAX_MATCH;
- do {
- } while (prev == *++scan && prev == *++scan &&
- prev == *++scan && prev == *++scan &&
- prev == *++scan && prev == *++scan &&
- prev == *++scan && prev == *++scan &&
- scan < strend);
- s->match_length = MAX_MATCH - (int)(strend - scan);
- if (s->match_length > s->lookahead)
- s->match_length = s->lookahead;
- }
- }
-
- /* Emit match if have run of MIN_MATCH or longer, else emit literal */
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->strstart - 1, s->match_length);
-
- _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
- s->strstart += s->match_length;
- s->match_length = 0;
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
- * (It will be regenerated if this run of deflate switches away from Huffman.)
- */
-local block_state deflate_huff(s, flush)
- deflate_state *s;
- int flush;
-{
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we have a literal to write. */
- if (s->lookahead == 0) {
- fill_window(s);
- if (s->lookahead == 0) {
- if (flush == Z_NO_FLUSH)
- return need_more;
- break; /* flush the current block */
- }
- }
-
- /* Output a literal byte */
- s->match_length = 0;
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
diff --git a/security/nss/lib/zlib/deflate.h b/security/nss/lib/zlib/deflate.h
deleted file mode 100644
index cbf0d1ea5..000000000
--- a/security/nss/lib/zlib/deflate.h
+++ /dev/null
@@ -1,342 +0,0 @@
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-2010 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef DEFLATE_H
-#define DEFLATE_H
-
-#include "zutil.h"
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer creation by deflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip encoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GZIP
-#endif
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define EXTRA_STATE 69
-#define NAME_STATE 73
-#define COMMENT_STATE 91
-#define HCRC_STATE 103
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- uInt pending; /* nb of bytes in the pending buffer */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- gz_headerp gzhead; /* gzip header information to write */
- uInt gzindex; /* where in extra, name, or comment */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
-# define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
- ulg high_water;
- /* High water mark offset in window for initialized bytes -- bytes above
- * this are set to zero in order to avoid memory check warnings when
- * longest match routines access bytes past the input. This is then
- * updated to the new high water mark.
- */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
-#define WIN_INIT MAX_MATCH
-/* Number of bytes after end of data in window to initialize in order to avoid
- memory checker errors from longest match routines */
-
- /* in trees.c */
-void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
-int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
- ulg stored_len, int last));
-void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
-void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
- ulg stored_len, int last));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch ZLIB_INTERNAL _length_code[];
- extern uch ZLIB_INTERNAL _dist_code[];
-#else
- extern const uch ZLIB_INTERNAL _length_code[];
- extern const uch ZLIB_INTERNAL _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif /* DEFLATE_H */
diff --git a/security/nss/lib/zlib/example.c b/security/nss/lib/zlib/example.c
deleted file mode 100644
index 604736f15..000000000
--- a/security/nss/lib/zlib/example.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/* example.c -- usage example of the zlib compression library
- * Copyright (C) 1995-2006 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zlib.h"
-#include <stdio.h>
-
-#ifdef STDC
-# include <string.h>
-# include <stdlib.h>
-#endif
-
-#if defined(VMS) || defined(RISCOS)
-# define TESTFILE "foo-gz"
-#else
-# define TESTFILE "foo.gz"
-#endif
-
-#define CHECK_ERR(err, msg) { \
- if (err != Z_OK) { \
- fprintf(stderr, "%s error: %d\n", msg, err); \
- exit(1); \
- } \
-}
-
-const char hello[] = "hello, hello!";
-/* "hello world" would be more standard, but the repeated "hello"
- * stresses the compression code better, sorry...
- */
-
-const char dictionary[] = "hello";
-uLong dictId; /* Adler32 value of the dictionary */
-
-void test_compress OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_gzio OF((const char *fname,
- Byte *uncompr, uLong uncomprLen));
-void test_deflate OF((Byte *compr, uLong comprLen));
-void test_inflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_large_deflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_large_inflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_flush OF((Byte *compr, uLong *comprLen));
-void test_sync OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-void test_dict_deflate OF((Byte *compr, uLong comprLen));
-void test_dict_inflate OF((Byte *compr, uLong comprLen,
- Byte *uncompr, uLong uncomprLen));
-int main OF((int argc, char *argv[]));
-
-/* ===========================================================================
- * Test compress() and uncompress()
- */
-void test_compress(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- uLong len = (uLong)strlen(hello)+1;
-
- err = compress(compr, &comprLen, (const Bytef*)hello, len);
- CHECK_ERR(err, "compress");
-
- strcpy((char*)uncompr, "garbage");
-
- err = uncompress(uncompr, &uncomprLen, compr, comprLen);
- CHECK_ERR(err, "uncompress");
-
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad uncompress\n");
- exit(1);
- } else {
- printf("uncompress(): %s\n", (char *)uncompr);
- }
-}
-
-/* ===========================================================================
- * Test read/write of .gz files
- */
-void test_gzio(fname, uncompr, uncomprLen)
- const char *fname; /* compressed file name */
- Byte *uncompr;
- uLong uncomprLen;
-{
-#ifdef NO_GZCOMPRESS
- fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
-#else
- int err;
- int len = (int)strlen(hello)+1;
- gzFile file;
- z_off_t pos;
-
- file = gzopen(fname, "wb");
- if (file == NULL) {
- fprintf(stderr, "gzopen error\n");
- exit(1);
- }
- gzputc(file, 'h');
- if (gzputs(file, "ello") != 4) {
- fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
- exit(1);
- }
- if (gzprintf(file, ", %s!", "hello") != 8) {
- fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
- exit(1);
- }
- gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
- gzclose(file);
-
- file = gzopen(fname, "rb");
- if (file == NULL) {
- fprintf(stderr, "gzopen error\n");
- exit(1);
- }
- strcpy((char*)uncompr, "garbage");
-
- if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
- fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
- exit(1);
- }
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
- exit(1);
- } else {
- printf("gzread(): %s\n", (char*)uncompr);
- }
-
- pos = gzseek(file, -8L, SEEK_CUR);
- if (pos != 6 || gztell(file) != pos) {
- fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
- (long)pos, (long)gztell(file));
- exit(1);
- }
-
- if (gzgetc(file) != ' ') {
- fprintf(stderr, "gzgetc error\n");
- exit(1);
- }
-
- if (gzungetc(' ', file) != ' ') {
- fprintf(stderr, "gzungetc error\n");
- exit(1);
- }
-
- gzgets(file, (char*)uncompr, (int)uncomprLen);
- if (strlen((char*)uncompr) != 7) { /* " hello!" */
- fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
- exit(1);
- }
- if (strcmp((char*)uncompr, hello + 6)) {
- fprintf(stderr, "bad gzgets after gzseek\n");
- exit(1);
- } else {
- printf("gzgets() after gzseek: %s\n", (char*)uncompr);
- }
-
- gzclose(file);
-#endif
-}
-
-/* ===========================================================================
- * Test deflate() with small buffers
- */
-void test_deflate(compr, comprLen)
- Byte *compr;
- uLong comprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
- uLong len = (uLong)strlen(hello)+1;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
- CHECK_ERR(err, "deflateInit");
-
- c_stream.next_in = (Bytef*)hello;
- c_stream.next_out = compr;
-
- while (c_stream.total_in != len && c_stream.total_out < comprLen) {
- c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
- }
- /* Finish the stream, still forcing small buffers: */
- for (;;) {
- c_stream.avail_out = 1;
- err = deflate(&c_stream, Z_FINISH);
- if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "deflate");
- }
-
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-}
-
-/* ===========================================================================
- * Test inflate() with small buffers
- */
-void test_inflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = 0;
- d_stream.next_out = uncompr;
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
- d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "inflate");
- }
-
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad inflate\n");
- exit(1);
- } else {
- printf("inflate(): %s\n", (char *)uncompr);
- }
-}
-
-/* ===========================================================================
- * Test deflate() with large buffers and dynamic change of compression level
- */
-void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_BEST_SPEED);
- CHECK_ERR(err, "deflateInit");
-
- c_stream.next_out = compr;
- c_stream.avail_out = (uInt)comprLen;
-
- /* At this point, uncompr is still mostly zeroes, so it should compress
- * very well:
- */
- c_stream.next_in = uncompr;
- c_stream.avail_in = (uInt)uncomprLen;
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
- if (c_stream.avail_in != 0) {
- fprintf(stderr, "deflate not greedy\n");
- exit(1);
- }
-
- /* Feed in already compressed data and switch to no compression: */
- deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
- c_stream.next_in = compr;
- c_stream.avail_in = (uInt)comprLen/2;
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
-
- /* Switch back to compressing mode: */
- deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
- c_stream.next_in = uncompr;
- c_stream.avail_in = (uInt)uncomprLen;
- err = deflate(&c_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "deflate");
-
- err = deflate(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "deflate should report Z_STREAM_END\n");
- exit(1);
- }
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-}
-
-/* ===========================================================================
- * Test inflate() with large buffers
- */
-void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = (uInt)comprLen;
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- for (;;) {
- d_stream.next_out = uncompr; /* discard the output */
- d_stream.avail_out = (uInt)uncomprLen;
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- CHECK_ERR(err, "large inflate");
- }
-
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
- fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
- exit(1);
- } else {
- printf("large_inflate(): OK\n");
- }
-}
-
-/* ===========================================================================
- * Test deflate() with full flush
- */
-void test_flush(compr, comprLen)
- Byte *compr;
- uLong *comprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
- uInt len = (uInt)strlen(hello)+1;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
- CHECK_ERR(err, "deflateInit");
-
- c_stream.next_in = (Bytef*)hello;
- c_stream.next_out = compr;
- c_stream.avail_in = 3;
- c_stream.avail_out = (uInt)*comprLen;
- err = deflate(&c_stream, Z_FULL_FLUSH);
- CHECK_ERR(err, "deflate");
-
- compr[3]++; /* force an error in first compressed block */
- c_stream.avail_in = len - 3;
-
- err = deflate(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- CHECK_ERR(err, "deflate");
- }
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-
- *comprLen = c_stream.total_out;
-}
-
-/* ===========================================================================
- * Test inflateSync()
- */
-void test_sync(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = 2; /* just read the zlib header */
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- d_stream.next_out = uncompr;
- d_stream.avail_out = (uInt)uncomprLen;
-
- inflate(&d_stream, Z_NO_FLUSH);
- CHECK_ERR(err, "inflate");
-
- d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
- err = inflateSync(&d_stream); /* but skip the damaged part */
- CHECK_ERR(err, "inflateSync");
-
- err = inflate(&d_stream, Z_FINISH);
- if (err != Z_DATA_ERROR) {
- fprintf(stderr, "inflate should report DATA_ERROR\n");
- /* Because of incorrect adler32 */
- exit(1);
- }
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- printf("after inflateSync(): hel%s\n", (char *)uncompr);
-}
-
-/* ===========================================================================
- * Test deflate() with preset dictionary
- */
-void test_dict_deflate(compr, comprLen)
- Byte *compr;
- uLong comprLen;
-{
- z_stream c_stream; /* compression stream */
- int err;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
- CHECK_ERR(err, "deflateInit");
-
- err = deflateSetDictionary(&c_stream,
- (const Bytef*)dictionary, sizeof(dictionary));
- CHECK_ERR(err, "deflateSetDictionary");
-
- dictId = c_stream.adler;
- c_stream.next_out = compr;
- c_stream.avail_out = (uInt)comprLen;
-
- c_stream.next_in = (Bytef*)hello;
- c_stream.avail_in = (uInt)strlen(hello)+1;
-
- err = deflate(&c_stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- fprintf(stderr, "deflate should report Z_STREAM_END\n");
- exit(1);
- }
- err = deflateEnd(&c_stream);
- CHECK_ERR(err, "deflateEnd");
-}
-
-/* ===========================================================================
- * Test inflate() with a preset dictionary
- */
-void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
- Byte *compr, *uncompr;
- uLong comprLen, uncomprLen;
-{
- int err;
- z_stream d_stream; /* decompression stream */
-
- strcpy((char*)uncompr, "garbage");
-
- d_stream.zalloc = (alloc_func)0;
- d_stream.zfree = (free_func)0;
- d_stream.opaque = (voidpf)0;
-
- d_stream.next_in = compr;
- d_stream.avail_in = (uInt)comprLen;
-
- err = inflateInit(&d_stream);
- CHECK_ERR(err, "inflateInit");
-
- d_stream.next_out = uncompr;
- d_stream.avail_out = (uInt)uncomprLen;
-
- for (;;) {
- err = inflate(&d_stream, Z_NO_FLUSH);
- if (err == Z_STREAM_END) break;
- if (err == Z_NEED_DICT) {
- if (d_stream.adler != dictId) {
- fprintf(stderr, "unexpected dictionary");
- exit(1);
- }
- err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
- sizeof(dictionary));
- }
- CHECK_ERR(err, "inflate with dict");
- }
-
- err = inflateEnd(&d_stream);
- CHECK_ERR(err, "inflateEnd");
-
- if (strcmp((char*)uncompr, hello)) {
- fprintf(stderr, "bad inflate with dict\n");
- exit(1);
- } else {
- printf("inflate with dictionary: %s\n", (char *)uncompr);
- }
-}
-
-/* ===========================================================================
- * Usage: example [output.gz [input.gz]]
- */
-
-int main(argc, argv)
- int argc;
- char *argv[];
-{
- Byte *compr, *uncompr;
- uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
- uLong uncomprLen = comprLen;
- static const char* myVersion = ZLIB_VERSION;
-
- if (zlibVersion()[0] != myVersion[0]) {
- fprintf(stderr, "incompatible zlib version\n");
- exit(1);
-
- } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
- fprintf(stderr, "warning: different zlib version\n");
- }
-
- printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
- ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
-
- compr = (Byte*)calloc((uInt)comprLen, 1);
- uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
- /* compr and uncompr are cleared to avoid reading uninitialized
- * data and to ensure that uncompr compresses well.
- */
- if (compr == Z_NULL || uncompr == Z_NULL) {
- printf("out of memory\n");
- exit(1);
- }
- test_compress(compr, comprLen, uncompr, uncomprLen);
-
- test_gzio((argc > 1 ? argv[1] : TESTFILE),
- uncompr, uncomprLen);
-
- test_deflate(compr, comprLen);
- test_inflate(compr, comprLen, uncompr, uncomprLen);
-
- test_large_deflate(compr, comprLen, uncompr, uncomprLen);
- test_large_inflate(compr, comprLen, uncompr, uncomprLen);
-
- test_flush(compr, &comprLen);
- test_sync(compr, comprLen, uncompr, uncomprLen);
- comprLen = uncomprLen;
-
- test_dict_deflate(compr, comprLen);
- test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
-
- free(compr);
- free(uncompr);
-
- return 0;
-}
diff --git a/security/nss/lib/zlib/gzclose.c b/security/nss/lib/zlib/gzclose.c
deleted file mode 100644
index caeb99a31..000000000
--- a/security/nss/lib/zlib/gzclose.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* gzclose.c -- zlib gzclose() function
- * Copyright (C) 2004, 2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "gzguts.h"
-
-/* gzclose() is in a separate file so that it is linked in only if it is used.
- That way the other gzclose functions can be used instead to avoid linking in
- unneeded compression or decompression routines. */
-int ZEXPORT gzclose(file)
- gzFile file;
-{
-#ifndef NO_GZCOMPRESS
- gz_statep state;
-
- if (file == NULL)
- return Z_STREAM_ERROR;
- state = (gz_statep)file;
-
- return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
-#else
- return gzclose_r(file);
-#endif
-}
diff --git a/security/nss/lib/zlib/gzguts.h b/security/nss/lib/zlib/gzguts.h
deleted file mode 100644
index 0f8fb79f8..000000000
--- a/security/nss/lib/zlib/gzguts.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* gzguts.h -- zlib internal header definitions for gz* operations
- * Copyright (C) 2004, 2005, 2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#ifdef _LARGEFILE64_SOURCE
-# ifndef _LARGEFILE_SOURCE
-# define _LARGEFILE_SOURCE 1
-# endif
-# ifdef _FILE_OFFSET_BITS
-# undef _FILE_OFFSET_BITS
-# endif
-#endif
-
-#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
-# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
-#else
-# define ZLIB_INTERNAL
-#endif
-
-#include <stdio.h>
-#include "zlib.h"
-#ifdef STDC
-# include <string.h>
-# include <stdlib.h>
-# include <limits.h>
-#endif
-#include <fcntl.h>
-
-#ifdef NO_DEFLATE /* for compatibility with old definition */
-# define NO_GZCOMPRESS
-#endif
-
-#ifdef _MSC_VER
-# include <io.h>
-# define vsnprintf _vsnprintf
-#endif
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-/* gz* functions always use library allocation functions */
-#ifndef STDC
- extern voidp malloc OF((uInt size));
- extern void free OF((voidpf ptr));
-#endif
-
-/* get errno and strerror definition */
-#if defined UNDER_CE
-# include <windows.h>
-# define zstrerror() gz_strwinerror((DWORD)GetLastError())
-#else
-# ifdef STDC
-# include <errno.h>
-# define zstrerror() strerror(errno)
-# else
-# define zstrerror() "stdio error (consult errno)"
-# endif
-#endif
-
-/* provide prototypes for these when building zlib without LFS */
-#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
- ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
- ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
- ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
- ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
-#endif
-
-/* default i/o buffer size -- double this for output when reading */
-#define GZBUFSIZE 8192
-
-/* gzip modes, also provide a little integrity check on the passed structure */
-#define GZ_NONE 0
-#define GZ_READ 7247
-#define GZ_WRITE 31153
-#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
-
-/* values for gz_state how */
-#define LOOK 0 /* look for a gzip header */
-#define COPY 1 /* copy input directly */
-#define GZIP 2 /* decompress a gzip stream */
-
-/* internal gzip file state data structure */
-typedef struct {
- /* used for both reading and writing */
- int mode; /* see gzip modes above */
- int fd; /* file descriptor */
- char *path; /* path or fd for error messages */
- z_off64_t pos; /* current position in uncompressed data */
- unsigned size; /* buffer size, zero if not allocated yet */
- unsigned want; /* requested buffer size, default is GZBUFSIZE */
- unsigned char *in; /* input buffer */
- unsigned char *out; /* output buffer (double-sized when reading) */
- unsigned char *next; /* next output data to deliver or write */
- /* just for reading */
- unsigned have; /* amount of output data unused at next */
- int eof; /* true if end of input file reached */
- z_off64_t start; /* where the gzip data started, for rewinding */
- z_off64_t raw; /* where the raw data started, for seeking */
- int how; /* 0: get header, 1: copy, 2: decompress */
- int direct; /* true if last read direct, false if gzip */
- /* just for writing */
- int level; /* compression level */
- int strategy; /* compression strategy */
- /* seek request */
- z_off64_t skip; /* amount to skip (already rewound if backwards) */
- int seek; /* true if seek request pending */
- /* error information */
- int err; /* error code */
- char *msg; /* error message */
- /* zlib inflate or deflate stream */
- z_stream strm; /* stream structure in-place (not a pointer) */
-} gz_state;
-typedef gz_state FAR *gz_statep;
-
-/* shared functions */
-void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
-#if defined UNDER_CE
-char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
-#endif
-
-/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
- value -- needed when comparing unsigned to z_off64_t, which is signed
- (possible z_off64_t types off_t, off64_t, and long are all signed) */
-#ifdef INT_MAX
-# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
-#else
-unsigned ZLIB_INTERNAL gz_intmax OF((void));
-# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
-#endif
diff --git a/security/nss/lib/zlib/gzlib.c b/security/nss/lib/zlib/gzlib.c
deleted file mode 100644
index 603e60ed5..000000000
--- a/security/nss/lib/zlib/gzlib.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/* gzlib.c -- zlib functions common to reading and writing gzip files
- * Copyright (C) 2004, 2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "gzguts.h"
-
-#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
-# define LSEEK lseek64
-#else
-# define LSEEK lseek
-#endif
-
-/* Local functions */
-local void gz_reset OF((gz_statep));
-local gzFile gz_open OF((const char *, int, const char *));
-
-#if defined UNDER_CE
-
-/* Map the Windows error number in ERROR to a locale-dependent error message
- string and return a pointer to it. Typically, the values for ERROR come
- from GetLastError.
-
- The string pointed to shall not be modified by the application, but may be
- overwritten by a subsequent call to gz_strwinerror
-
- The gz_strwinerror function does not change the current setting of
- GetLastError. */
-char ZLIB_INTERNAL *gz_strwinerror (error)
- DWORD error;
-{
- static char buf[1024];
-
- wchar_t *msgbuf;
- DWORD lasterr = GetLastError();
- DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
- | FORMAT_MESSAGE_ALLOCATE_BUFFER,
- NULL,
- error,
- 0, /* Default language */
- (LPVOID)&msgbuf,
- 0,
- NULL);
- if (chars != 0) {
- /* If there is an \r\n appended, zap it. */
- if (chars >= 2
- && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
- chars -= 2;
- msgbuf[chars] = 0;
- }
-
- if (chars > sizeof (buf) - 1) {
- chars = sizeof (buf) - 1;
- msgbuf[chars] = 0;
- }
-
- wcstombs(buf, msgbuf, chars + 1);
- LocalFree(msgbuf);
- }
- else {
- sprintf(buf, "unknown win32 error (%ld)", error);
- }
-
- SetLastError(lasterr);
- return buf;
-}
-
-#endif /* UNDER_CE */
-
-/* Reset gzip file state */
-local void gz_reset(state)
- gz_statep state;
-{
- if (state->mode == GZ_READ) { /* for reading ... */
- state->have = 0; /* no output data available */
- state->eof = 0; /* not at end of file */
- state->how = LOOK; /* look for gzip header */
- state->direct = 1; /* default for empty file */
- }
- state->seek = 0; /* no seek request pending */
- gz_error(state, Z_OK, NULL); /* clear error */
- state->pos = 0; /* no uncompressed data yet */
- state->strm.avail_in = 0; /* no input data yet */
-}
-
-/* Open a gzip file either by name or file descriptor. */
-local gzFile gz_open(path, fd, mode)
- const char *path;
- int fd;
- const char *mode;
-{
- gz_statep state;
-
- /* allocate gzFile structure to return */
- state = malloc(sizeof(gz_state));
- if (state == NULL)
- return NULL;
- state->size = 0; /* no buffers allocated yet */
- state->want = GZBUFSIZE; /* requested buffer size */
- state->msg = NULL; /* no error message yet */
-
- /* interpret mode */
- state->mode = GZ_NONE;
- state->level = Z_DEFAULT_COMPRESSION;
- state->strategy = Z_DEFAULT_STRATEGY;
- while (*mode) {
- if (*mode >= '0' && *mode <= '9')
- state->level = *mode - '0';
- else
- switch (*mode) {
- case 'r':
- state->mode = GZ_READ;
- break;
-#ifndef NO_GZCOMPRESS
- case 'w':
- state->mode = GZ_WRITE;
- break;
- case 'a':
- state->mode = GZ_APPEND;
- break;
-#endif
- case '+': /* can't read and write at the same time */
- free(state);
- return NULL;
- case 'b': /* ignore -- will request binary anyway */
- break;
- case 'f':
- state->strategy = Z_FILTERED;
- break;
- case 'h':
- state->strategy = Z_HUFFMAN_ONLY;
- break;
- case 'R':
- state->strategy = Z_RLE;
- break;
- case 'F':
- state->strategy = Z_FIXED;
- default: /* could consider as an error, but just ignore */
- ;
- }
- mode++;
- }
-
- /* must provide an "r", "w", or "a" */
- if (state->mode == GZ_NONE) {
- free(state);
- return NULL;
- }
-
- /* save the path name for error messages */
- state->path = malloc(strlen(path) + 1);
- if (state->path == NULL) {
- free(state);
- return NULL;
- }
- strcpy(state->path, path);
-
- /* open the file with the appropriate mode (or just use fd) */
- state->fd = fd != -1 ? fd :
- open(path,
-#ifdef O_LARGEFILE
- O_LARGEFILE |
-#endif
-#ifdef O_BINARY
- O_BINARY |
-#endif
- (state->mode == GZ_READ ?
- O_RDONLY :
- (O_WRONLY | O_CREAT | (
- state->mode == GZ_WRITE ?
- O_TRUNC :
- O_APPEND))),
- 0666);
- if (state->fd == -1) {
- free(state->path);
- free(state);
- return NULL;
- }
- if (state->mode == GZ_APPEND)
- state->mode = GZ_WRITE; /* simplify later checks */
-
- /* save the current position for rewinding (only if reading) */
- if (state->mode == GZ_READ) {
- state->start = LSEEK(state->fd, 0, SEEK_CUR);
- if (state->start == -1) state->start = 0;
- }
-
- /* initialize stream */
- gz_reset(state);
-
- /* return stream */
- return (gzFile)state;
-}
-
-/* -- see zlib.h -- */
-gzFile ZEXPORT gzopen(path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open(path, -1, mode);
-}
-
-/* -- see zlib.h -- */
-gzFile ZEXPORT gzopen64(path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open(path, -1, mode);
-}
-
-/* -- see zlib.h -- */
-gzFile ZEXPORT gzdopen(fd, mode)
- int fd;
- const char *mode;
-{
- char *path; /* identifier for error messages */
- gzFile gz;
-
- if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
- return NULL;
- sprintf(path, "<fd:%d>", fd); /* for debugging */
- gz = gz_open(path, fd, mode);
- free(path);
- return gz;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzbuffer(file, size)
- gzFile file;
- unsigned size;
-{
- gz_statep state;
-
- /* get internal structure and check integrity */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
- if (state->mode != GZ_READ && state->mode != GZ_WRITE)
- return -1;
-
- /* make sure we haven't already allocated memory */
- if (state->size != 0)
- return -1;
-
- /* check and set requested size */
- if (size == 0)
- return -1;
- state->want = size;
- return 0;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzrewind(file)
- gzFile file;
-{
- gz_statep state;
-
- /* get internal structure */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
-
- /* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
- return -1;
-
- /* back up and start over */
- if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
- return -1;
- gz_reset(state);
- return 0;
-}
-
-/* -- see zlib.h -- */
-z_off64_t ZEXPORT gzseek64(file, offset, whence)
- gzFile file;
- z_off64_t offset;
- int whence;
-{
- unsigned n;
- z_off64_t ret;
- gz_statep state;
-
- /* get internal structure and check integrity */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
- if (state->mode != GZ_READ && state->mode != GZ_WRITE)
- return -1;
-
- /* check that there's no error */
- if (state->err != Z_OK)
- return -1;
-
- /* can only seek from start or relative to current position */
- if (whence != SEEK_SET && whence != SEEK_CUR)
- return -1;
-
- /* normalize offset to a SEEK_CUR specification */
- if (whence == SEEK_SET)
- offset -= state->pos;
- else if (state->seek)
- offset += state->skip;
- state->seek = 0;
-
- /* if within raw area while reading, just go there */
- if (state->mode == GZ_READ && state->how == COPY &&
- state->pos + offset >= state->raw) {
- ret = LSEEK(state->fd, offset - state->have, SEEK_CUR);
- if (ret == -1)
- return -1;
- state->have = 0;
- state->eof = 0;
- state->seek = 0;
- gz_error(state, Z_OK, NULL);
- state->strm.avail_in = 0;
- state->pos += offset;
- return state->pos;
- }
-
- /* calculate skip amount, rewinding if needed for back seek when reading */
- if (offset < 0) {
- if (state->mode != GZ_READ) /* writing -- can't go backwards */
- return -1;
- offset += state->pos;
- if (offset < 0) /* before start of file! */
- return -1;
- if (gzrewind(file) == -1) /* rewind, then skip to offset */
- return -1;
- }
-
- /* if reading, skip what's in output buffer (one less gzgetc() check) */
- if (state->mode == GZ_READ) {
- n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
- (unsigned)offset : state->have;
- state->have -= n;
- state->next += n;
- state->pos += n;
- offset -= n;
- }
-
- /* request skip (if not zero) */
- if (offset) {
- state->seek = 1;
- state->skip = offset;
- }
- return state->pos + offset;
-}
-
-/* -- see zlib.h -- */
-z_off_t ZEXPORT gzseek(file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- z_off64_t ret;
-
- ret = gzseek64(file, (z_off64_t)offset, whence);
- return ret == (z_off_t)ret ? (z_off_t)ret : -1;
-}
-
-/* -- see zlib.h -- */
-z_off64_t ZEXPORT gztell64(file)
- gzFile file;
-{
- gz_statep state;
-
- /* get internal structure and check integrity */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
- if (state->mode != GZ_READ && state->mode != GZ_WRITE)
- return -1;
-
- /* return position */
- return state->pos + (state->seek ? state->skip : 0);
-}
-
-/* -- see zlib.h -- */
-z_off_t ZEXPORT gztell(file)
- gzFile file;
-{
- z_off64_t ret;
-
- ret = gztell64(file);
- return ret == (z_off_t)ret ? (z_off_t)ret : -1;
-}
-
-/* -- see zlib.h -- */
-z_off64_t ZEXPORT gzoffset64(file)
- gzFile file;
-{
- z_off64_t offset;
- gz_statep state;
-
- /* get internal structure and check integrity */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
- if (state->mode != GZ_READ && state->mode != GZ_WRITE)
- return -1;
-
- /* compute and return effective offset in file */
- offset = LSEEK(state->fd, 0, SEEK_CUR);
- if (offset == -1)
- return -1;
- if (state->mode == GZ_READ) /* reading */
- offset -= state->strm.avail_in; /* don't count buffered input */
- return offset;
-}
-
-/* -- see zlib.h -- */
-z_off_t ZEXPORT gzoffset(file)
- gzFile file;
-{
- z_off64_t ret;
-
- ret = gzoffset64(file);
- return ret == (z_off_t)ret ? (z_off_t)ret : -1;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzeof(file)
- gzFile file;
-{
- gz_statep state;
-
- /* get internal structure and check integrity */
- if (file == NULL)
- return 0;
- state = (gz_statep)file;
- if (state->mode != GZ_READ && state->mode != GZ_WRITE)
- return 0;
-
- /* return end-of-file state */
- return state->mode == GZ_READ ?
- (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0;
-}
-
-/* -- see zlib.h -- */
-const char * ZEXPORT gzerror(file, errnum)
- gzFile file;
- int *errnum;
-{
- gz_statep state;
-
- /* get internal structure and check integrity */
- if (file == NULL)
- return NULL;
- state = (gz_statep)file;
- if (state->mode != GZ_READ && state->mode != GZ_WRITE)
- return NULL;
-
- /* return error information */
- if (errnum != NULL)
- *errnum = state->err;
- return state->msg == NULL ? "" : state->msg;
-}
-
-/* -- see zlib.h -- */
-void ZEXPORT gzclearerr(file)
- gzFile file;
-{
- gz_statep state;
-
- /* get internal structure and check integrity */
- if (file == NULL)
- return;
- state = (gz_statep)file;
- if (state->mode != GZ_READ && state->mode != GZ_WRITE)
- return;
-
- /* clear error and end-of-file */
- if (state->mode == GZ_READ)
- state->eof = 0;
- gz_error(state, Z_OK, NULL);
-}
-
-/* Create an error message in allocated memory and set state->err and
- state->msg accordingly. Free any previous error message already there. Do
- not try to free or allocate space if the error is Z_MEM_ERROR (out of
- memory). Simply save the error message as a static string. If there is an
- allocation failure constructing the error message, then convert the error to
- out of memory. */
-void ZLIB_INTERNAL gz_error(state, err, msg)
- gz_statep state;
- int err;
- const char *msg;
-{
- /* free previously allocated message and clear */
- if (state->msg != NULL) {
- if (state->err != Z_MEM_ERROR)
- free(state->msg);
- state->msg = NULL;
- }
-
- /* set error code, and if no message, then done */
- state->err = err;
- if (msg == NULL)
- return;
-
- /* for an out of memory error, save as static string */
- if (err == Z_MEM_ERROR) {
- state->msg = (char *)msg;
- return;
- }
-
- /* construct error message with path */
- if ((state->msg = malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
- state->err = Z_MEM_ERROR;
- state->msg = (char *)"out of memory";
- return;
- }
- strcpy(state->msg, state->path);
- strcat(state->msg, ": ");
- strcat(state->msg, msg);
- return;
-}
-
-#ifndef INT_MAX
-/* portably return maximum value for an int (when limits.h presumed not
- available) -- we need to do this to cover cases where 2's complement not
- used, since C standard permits 1's complement and sign-bit representations,
- otherwise we could just use ((unsigned)-1) >> 1 */
-unsigned ZLIB_INTERNAL gz_intmax()
-{
- unsigned p, q;
-
- p = 1;
- do {
- q = p;
- p <<= 1;
- p++;
- } while (p > q);
- return q >> 1;
-}
-#endif
diff --git a/security/nss/lib/zlib/gzread.c b/security/nss/lib/zlib/gzread.c
deleted file mode 100644
index 548201ab0..000000000
--- a/security/nss/lib/zlib/gzread.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/* gzread.c -- zlib functions for reading gzip files
- * Copyright (C) 2004, 2005, 2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "gzguts.h"
-
-/* Local functions */
-local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
-local int gz_avail OF((gz_statep));
-local int gz_next4 OF((gz_statep, unsigned long *));
-local int gz_head OF((gz_statep));
-local int gz_decomp OF((gz_statep));
-local int gz_make OF((gz_statep));
-local int gz_skip OF((gz_statep, z_off64_t));
-
-/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
- state->fd, and update state->eof, state->err, and state->msg as appropriate.
- This function needs to loop on read(), since read() is not guaranteed to
- read the number of bytes requested, depending on the type of descriptor. */
-local int gz_load(state, buf, len, have)
- gz_statep state;
- unsigned char *buf;
- unsigned len;
- unsigned *have;
-{
- int ret;
-
- *have = 0;
- do {
- ret = read(state->fd, buf + *have, len - *have);
- if (ret <= 0)
- break;
- *have += ret;
- } while (*have < len);
- if (ret < 0) {
- gz_error(state, Z_ERRNO, zstrerror());
- return -1;
- }
- if (ret == 0)
- state->eof = 1;
- return 0;
-}
-
-/* Load up input buffer and set eof flag if last data loaded -- return -1 on
- error, 0 otherwise. Note that the eof flag is set when the end of the input
- file is reached, even though there may be unused data in the buffer. Once
- that data has been used, no more attempts will be made to read the file.
- gz_avail() assumes that strm->avail_in == 0. */
-local int gz_avail(state)
- gz_statep state;
-{
- z_streamp strm = &(state->strm);
-
- if (state->err != Z_OK)
- return -1;
- if (state->eof == 0) {
- if (gz_load(state, state->in, state->size,
- (unsigned *)&(strm->avail_in)) == -1)
- return -1;
- strm->next_in = state->in;
- }
- return 0;
-}
-
-/* Get next byte from input, or -1 if end or error. */
-#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
- (strm->avail_in == 0 ? -1 : \
- (strm->avail_in--, *(strm->next_in)++)))
-
-/* Get a four-byte little-endian integer and return 0 on success and the value
- in *ret. Otherwise -1 is returned and *ret is not modified. */
-local int gz_next4(state, ret)
- gz_statep state;
- unsigned long *ret;
-{
- int ch;
- unsigned long val;
- z_streamp strm = &(state->strm);
-
- val = NEXT();
- val += (unsigned)NEXT() << 8;
- val += (unsigned long)NEXT() << 16;
- ch = NEXT();
- if (ch == -1)
- return -1;
- val += (unsigned long)ch << 24;
- *ret = val;
- return 0;
-}
-
-/* Look for gzip header, set up for inflate or copy. state->have must be zero.
- If this is the first time in, allocate required memory. state->how will be
- left unchanged if there is no more input data available, will be set to COPY
- if there is no gzip header and direct copying will be performed, or it will
- be set to GZIP for decompression, and the gzip header will be skipped so
- that the next available input data is the raw deflate stream. If direct
- copying, then leftover input data from the input buffer will be copied to
- the output buffer. In that case, all further file reads will be directly to
- either the output buffer or a user buffer. If decompressing, the inflate
- state and the check value will be initialized. gz_head() will return 0 on
- success or -1 on failure. Failures may include read errors or gzip header
- errors. */
-local int gz_head(state)
- gz_statep state;
-{
- z_streamp strm = &(state->strm);
- int flags;
- unsigned len;
-
- /* allocate read buffers and inflate memory */
- if (state->size == 0) {
- /* allocate buffers */
- state->in = malloc(state->want);
- state->out = malloc(state->want << 1);
- if (state->in == NULL || state->out == NULL) {
- if (state->out != NULL)
- free(state->out);
- if (state->in != NULL)
- free(state->in);
- gz_error(state, Z_MEM_ERROR, "out of memory");
- return -1;
- }
- state->size = state->want;
-
- /* allocate inflate memory */
- state->strm.zalloc = Z_NULL;
- state->strm.zfree = Z_NULL;
- state->strm.opaque = Z_NULL;
- state->strm.avail_in = 0;
- state->strm.next_in = Z_NULL;
- if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */
- free(state->out);
- free(state->in);
- state->size = 0;
- gz_error(state, Z_MEM_ERROR, "out of memory");
- return -1;
- }
- }
-
- /* get some data in the input buffer */
- if (strm->avail_in == 0) {
- if (gz_avail(state) == -1)
- return -1;
- if (strm->avail_in == 0)
- return 0;
- }
-
- /* look for the gzip magic header bytes 31 and 139 */
- if (strm->next_in[0] == 31) {
- strm->avail_in--;
- strm->next_in++;
- if (strm->avail_in == 0 && gz_avail(state) == -1)
- return -1;
- if (strm->avail_in && strm->next_in[0] == 139) {
- /* we have a gzip header, woo hoo! */
- strm->avail_in--;
- strm->next_in++;
-
- /* skip rest of header */
- if (NEXT() != 8) { /* compression method */
- gz_error(state, Z_DATA_ERROR, "unknown compression method");
- return -1;
- }
- flags = NEXT();
- if (flags & 0xe0) { /* reserved flag bits */
- gz_error(state, Z_DATA_ERROR, "unknown header flags set");
- return -1;
- }
- NEXT(); /* modification time */
- NEXT();
- NEXT();
- NEXT();
- NEXT(); /* extra flags */
- NEXT(); /* operating system */
- if (flags & 4) { /* extra field */
- len = (unsigned)NEXT();
- len += (unsigned)NEXT() << 8;
- while (len--)
- if (NEXT() < 0)
- break;
- }
- if (flags & 8) /* file name */
- while (NEXT() > 0)
- ;
- if (flags & 16) /* comment */
- while (NEXT() > 0)
- ;
- if (flags & 2) { /* header crc */
- NEXT();
- NEXT();
- }
- /* an unexpected end of file is not checked for here -- it will be
- noticed on the first request for uncompressed data */
-
- /* set up for decompression */
- inflateReset(strm);
- strm->adler = crc32(0L, Z_NULL, 0);
- state->how = GZIP;
- state->direct = 0;
- return 0;
- }
- else {
- /* not a gzip file -- save first byte (31) and fall to raw i/o */
- state->out[0] = 31;
- state->have = 1;
- }
- }
-
- /* doing raw i/o, save start of raw data for seeking, copy any leftover
- input to output -- this assumes that the output buffer is larger than
- the input buffer, which also assures space for gzungetc() */
- state->raw = state->pos;
- state->next = state->out;
- if (strm->avail_in) {
- memcpy(state->next + state->have, strm->next_in, strm->avail_in);
- state->have += strm->avail_in;
- strm->avail_in = 0;
- }
- state->how = COPY;
- state->direct = 1;
- return 0;
-}
-
-/* Decompress from input to the provided next_out and avail_out in the state.
- If the end of the compressed data is reached, then verify the gzip trailer
- check value and length (modulo 2^32). state->have and state->next are set
- to point to the just decompressed data, and the crc is updated. If the
- trailer is verified, state->how is reset to LOOK to look for the next gzip
- stream or raw data, once state->have is depleted. Returns 0 on success, -1
- on failure. Failures may include invalid compressed data or a failed gzip
- trailer verification. */
-local int gz_decomp(state)
- gz_statep state;
-{
- int ret;
- unsigned had;
- unsigned long crc, len;
- z_streamp strm = &(state->strm);
-
- /* fill output buffer up to end of deflate stream */
- had = strm->avail_out;
- do {
- /* get more input for inflate() */
- if (strm->avail_in == 0 && gz_avail(state) == -1)
- return -1;
- if (strm->avail_in == 0) {
- gz_error(state, Z_DATA_ERROR, "unexpected end of file");
- return -1;
- }
-
- /* decompress and handle errors */
- ret = inflate(strm, Z_NO_FLUSH);
- if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
- gz_error(state, Z_STREAM_ERROR,
- "internal error: inflate stream corrupt");
- return -1;
- }
- if (ret == Z_MEM_ERROR) {
- gz_error(state, Z_MEM_ERROR, "out of memory");
- return -1;
- }
- if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
- gz_error(state, Z_DATA_ERROR,
- strm->msg == NULL ? "compressed data error" : strm->msg);
- return -1;
- }
- } while (strm->avail_out && ret != Z_STREAM_END);
-
- /* update available output and crc check value */
- state->have = had - strm->avail_out;
- state->next = strm->next_out - state->have;
- strm->adler = crc32(strm->adler, state->next, state->have);
-
- /* check gzip trailer if at end of deflate stream */
- if (ret == Z_STREAM_END) {
- if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
- gz_error(state, Z_DATA_ERROR, "unexpected end of file");
- return -1;
- }
- if (crc != strm->adler) {
- gz_error(state, Z_DATA_ERROR, "incorrect data check");
- return -1;
- }
- if (len != (strm->total_out & 0xffffffffL)) {
- gz_error(state, Z_DATA_ERROR, "incorrect length check");
- return -1;
- }
- state->how = LOOK; /* ready for next stream, once have is 0 (leave
- state->direct unchanged to remember how) */
- }
-
- /* good decompression */
- return 0;
-}
-
-/* Make data and put in the output buffer. Assumes that state->have == 0.
- Data is either copied from the input file or decompressed from the input
- file depending on state->how. If state->how is LOOK, then a gzip header is
- looked for (and skipped if found) to determine wither to copy or decompress.
- Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
- or GZIP unless the end of the input file has been reached and all data has
- been processed. */
-local int gz_make(state)
- gz_statep state;
-{
- z_streamp strm = &(state->strm);
-
- if (state->how == LOOK) { /* look for gzip header */
- if (gz_head(state) == -1)
- return -1;
- if (state->have) /* got some data from gz_head() */
- return 0;
- }
- if (state->how == COPY) { /* straight copy */
- if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
- return -1;
- state->next = state->out;
- }
- else if (state->how == GZIP) { /* decompress */
- strm->avail_out = state->size << 1;
- strm->next_out = state->out;
- if (gz_decomp(state) == -1)
- return -1;
- }
- return 0;
-}
-
-/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
-local int gz_skip(state, len)
- gz_statep state;
- z_off64_t len;
-{
- unsigned n;
-
- /* skip over len bytes or reach end-of-file, whichever comes first */
- while (len)
- /* skip over whatever is in output buffer */
- if (state->have) {
- n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
- (unsigned)len : state->have;
- state->have -= n;
- state->next += n;
- state->pos += n;
- len -= n;
- }
-
- /* output buffer empty -- return if we're at the end of the input */
- else if (state->eof && state->strm.avail_in == 0)
- break;
-
- /* need more data to skip -- load up output buffer */
- else {
- /* get more output, looking for header if required */
- if (gz_make(state) == -1)
- return -1;
- }
- return 0;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzread(file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- unsigned got, n;
- gz_statep state;
- z_streamp strm;
-
- /* get internal structure */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
- strm = &(state->strm);
-
- /* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
- return -1;
-
- /* since an int is returned, make sure len fits in one, otherwise return
- with an error (this avoids the flaw in the interface) */
- if ((int)len < 0) {
- gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
- return -1;
- }
-
- /* if len is zero, avoid unnecessary operations */
- if (len == 0)
- return 0;
-
- /* process a skip request */
- if (state->seek) {
- state->seek = 0;
- if (gz_skip(state, state->skip) == -1)
- return -1;
- }
-
- /* get len bytes to buf, or less than len if at the end */
- got = 0;
- do {
- /* first just try copying data from the output buffer */
- if (state->have) {
- n = state->have > len ? len : state->have;
- memcpy(buf, state->next, n);
- state->next += n;
- state->have -= n;
- }
-
- /* output buffer empty -- return if we're at the end of the input */
- else if (state->eof && strm->avail_in == 0)
- break;
-
- /* need output data -- for small len or new stream load up our output
- buffer */
- else if (state->how == LOOK || len < (state->size << 1)) {
- /* get more output, looking for header if required */
- if (gz_make(state) == -1)
- return -1;
- continue; /* no progress yet -- go back to memcpy() above */
- /* the copy above assures that we will leave with space in the
- output buffer, allowing at least one gzungetc() to succeed */
- }
-
- /* large len -- read directly into user buffer */
- else if (state->how == COPY) { /* read directly */
- if (gz_load(state, buf, len, &n) == -1)
- return -1;
- }
-
- /* large len -- decompress directly into user buffer */
- else { /* state->how == GZIP */
- strm->avail_out = len;
- strm->next_out = buf;
- if (gz_decomp(state) == -1)
- return -1;
- n = state->have;
- state->have = 0;
- }
-
- /* update progress */
- len -= n;
- buf = (char *)buf + n;
- got += n;
- state->pos += n;
- } while (len);
-
- /* return number of bytes read into user buffer (will fit in int) */
- return (int)got;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- int ret;
- unsigned char buf[1];
- gz_statep state;
-
- /* get internal structure */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
-
- /* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
- return -1;
-
- /* try output buffer (no need to check for skip request) */
- if (state->have) {
- state->have--;
- state->pos++;
- return *(state->next)++;
- }
-
- /* nothing there -- try gzread() */
- ret = gzread(file, buf, 1);
- return ret < 1 ? -1 : buf[0];
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzungetc(c, file)
- int c;
- gzFile file;
-{
- gz_statep state;
-
- /* get internal structure */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
-
- /* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
- return -1;
-
- /* process a skip request */
- if (state->seek) {
- state->seek = 0;
- if (gz_skip(state, state->skip) == -1)
- return -1;
- }
-
- /* can't push EOF */
- if (c < 0)
- return -1;
-
- /* if output buffer empty, put byte at end (allows more pushing) */
- if (state->have == 0) {
- state->have = 1;
- state->next = state->out + (state->size << 1) - 1;
- state->next[0] = c;
- state->pos--;
- return c;
- }
-
- /* if no room, give up (must have already done a gzungetc()) */
- if (state->have == (state->size << 1)) {
- gz_error(state, Z_BUF_ERROR, "out of room to push characters");
- return -1;
- }
-
- /* slide output data if needed and insert byte before existing data */
- if (state->next == state->out) {
- unsigned char *src = state->out + state->have;
- unsigned char *dest = state->out + (state->size << 1);
- while (src > state->out)
- *--dest = *--src;
- state->next = dest;
- }
- state->have++;
- state->next--;
- state->next[0] = c;
- state->pos--;
- return c;
-}
-
-/* -- see zlib.h -- */
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- unsigned left, n;
- char *str;
- unsigned char *eol;
- gz_statep state;
-
- /* check parameters and get internal structure */
- if (file == NULL || buf == NULL || len < 1)
- return NULL;
- state = (gz_statep)file;
-
- /* check that we're reading and that there's no error */
- if (state->mode != GZ_READ || state->err != Z_OK)
- return NULL;
-
- /* process a skip request */
- if (state->seek) {
- state->seek = 0;
- if (gz_skip(state, state->skip) == -1)
- return NULL;
- }
-
- /* copy output bytes up to new line or len - 1, whichever comes first --
- append a terminating zero to the string (we don't check for a zero in
- the contents, let the user worry about that) */
- str = buf;
- left = (unsigned)len - 1;
- if (left) do {
- /* assure that something is in the output buffer */
- if (state->have == 0) {
- if (gz_make(state) == -1)
- return NULL; /* error */
- if (state->have == 0) { /* end of file */
- if (buf == str) /* got bupkus */
- return NULL;
- break; /* got something -- return it */
- }
- }
-
- /* look for end-of-line in current output buffer */
- n = state->have > left ? left : state->have;
- eol = memchr(state->next, '\n', n);
- if (eol != NULL)
- n = (unsigned)(eol - state->next) + 1;
-
- /* copy through end-of-line, or remainder if not found */
- memcpy(buf, state->next, n);
- state->have -= n;
- state->next += n;
- state->pos += n;
- left -= n;
- buf += n;
- } while (left && eol == NULL);
-
- /* found end-of-line or out of space -- terminate string and return it */
- buf[0] = 0;
- return str;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzdirect(file)
- gzFile file;
-{
- gz_statep state;
-
- /* get internal structure */
- if (file == NULL)
- return 0;
- state = (gz_statep)file;
-
- /* check that we're reading */
- if (state->mode != GZ_READ)
- return 0;
-
- /* if the state is not known, but we can find out, then do so (this is
- mainly for right after a gzopen() or gzdopen()) */
- if (state->how == LOOK && state->have == 0)
- (void)gz_head(state);
-
- /* return 1 if reading direct, 0 if decompressing a gzip stream */
- return state->direct;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzclose_r(file)
- gzFile file;
-{
- int ret;
- gz_statep state;
-
- /* get internal structure */
- if (file == NULL)
- return Z_STREAM_ERROR;
- state = (gz_statep)file;
-
- /* check that we're reading */
- if (state->mode != GZ_READ)
- return Z_STREAM_ERROR;
-
- /* free memory and close file */
- if (state->size) {
- inflateEnd(&(state->strm));
- free(state->out);
- free(state->in);
- }
- gz_error(state, Z_OK, NULL);
- free(state->path);
- ret = close(state->fd);
- free(state);
- return ret ? Z_ERRNO : Z_OK;
-}
diff --git a/security/nss/lib/zlib/gzwrite.c b/security/nss/lib/zlib/gzwrite.c
deleted file mode 100644
index e8defc688..000000000
--- a/security/nss/lib/zlib/gzwrite.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/* gzwrite.c -- zlib functions for writing gzip files
- * Copyright (C) 2004, 2005, 2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "gzguts.h"
-
-/* Local functions */
-local int gz_init OF((gz_statep));
-local int gz_comp OF((gz_statep, int));
-local int gz_zero OF((gz_statep, z_off64_t));
-
-/* Initialize state for writing a gzip file. Mark initialization by setting
- state->size to non-zero. Return -1 on failure or 0 on success. */
-local int gz_init(state)
- gz_statep state;
-{
- int ret;
- z_streamp strm = &(state->strm);
-
- /* allocate input and output buffers */
- state->in = malloc(state->want);
- state->out = malloc(state->want);
- if (state->in == NULL || state->out == NULL) {
- if (state->out != NULL)
- free(state->out);
- if (state->in != NULL)
- free(state->in);
- gz_error(state, Z_MEM_ERROR, "out of memory");
- return -1;
- }
-
- /* allocate deflate memory, set up for gzip compression */
- strm->zalloc = Z_NULL;
- strm->zfree = Z_NULL;
- strm->opaque = Z_NULL;
- ret = deflateInit2(strm, state->level, Z_DEFLATED,
- 15 + 16, 8, state->strategy);
- if (ret != Z_OK) {
- free(state->in);
- gz_error(state, Z_MEM_ERROR, "out of memory");
- return -1;
- }
-
- /* mark state as initialized */
- state->size = state->want;
-
- /* initialize write buffer */
- strm->avail_out = state->size;
- strm->next_out = state->out;
- state->next = strm->next_out;
- return 0;
-}
-
-/* Compress whatever is at avail_in and next_in and write to the output file.
- Return -1 if there is an error writing to the output file, otherwise 0.
- flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
- then the deflate() state is reset to start a new gzip stream. */
-local int gz_comp(state, flush)
- gz_statep state;
- int flush;
-{
- int ret, got;
- unsigned have;
- z_streamp strm = &(state->strm);
-
- /* allocate memory if this is the first time through */
- if (state->size == 0 && gz_init(state) == -1)
- return -1;
-
- /* run deflate() on provided input until it produces no more output */
- ret = Z_OK;
- do {
- /* write out current buffer contents if full, or if flushing, but if
- doing Z_FINISH then don't write until we get to Z_STREAM_END */
- if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
- (flush != Z_FINISH || ret == Z_STREAM_END))) {
- have = (unsigned)(strm->next_out - state->next);
- if (have && ((got = write(state->fd, state->next, have)) < 0 ||
- (unsigned)got != have)) {
- gz_error(state, Z_ERRNO, zstrerror());
- return -1;
- }
- if (strm->avail_out == 0) {
- strm->avail_out = state->size;
- strm->next_out = state->out;
- }
- state->next = strm->next_out;
- }
-
- /* compress */
- have = strm->avail_out;
- ret = deflate(strm, flush);
- if (ret == Z_STREAM_ERROR) {
- gz_error(state, Z_STREAM_ERROR,
- "internal error: deflate stream corrupt");
- return -1;
- }
- have -= strm->avail_out;
- } while (have);
-
- /* if that completed a deflate stream, allow another to start */
- if (flush == Z_FINISH)
- deflateReset(strm);
-
- /* all done, no errors */
- return 0;
-}
-
-/* Compress len zeros to output. Return -1 on error, 0 on success. */
-local int gz_zero(state, len)
- gz_statep state;
- z_off64_t len;
-{
- int first;
- unsigned n;
- z_streamp strm = &(state->strm);
-
- /* consume whatever's left in the input buffer */
- if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
- return -1;
-
- /* compress len zeros (len guaranteed > 0) */
- first = 1;
- while (len) {
- n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
- (unsigned)len : state->size;
- if (first) {
- memset(state->in, 0, n);
- first = 0;
- }
- strm->avail_in = n;
- strm->next_in = state->in;
- state->pos += n;
- if (gz_comp(state, Z_NO_FLUSH) == -1)
- return -1;
- len -= n;
- }
- return 0;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzwrite(file, buf, len)
- gzFile file;
- voidpc buf;
- unsigned len;
-{
- unsigned put = len;
- unsigned n;
- gz_statep state;
- z_streamp strm;
-
- /* get internal structure */
- if (file == NULL)
- return 0;
- state = (gz_statep)file;
- strm = &(state->strm);
-
- /* check that we're writing and that there's no error */
- if (state->mode != GZ_WRITE || state->err != Z_OK)
- return 0;
-
- /* since an int is returned, make sure len fits in one, otherwise return
- with an error (this avoids the flaw in the interface) */
- if ((int)len < 0) {
- gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
- return 0;
- }
-
- /* if len is zero, avoid unnecessary operations */
- if (len == 0)
- return 0;
-
- /* allocate memory if this is the first time through */
- if (state->size == 0 && gz_init(state) == -1)
- return 0;
-
- /* check for seek request */
- if (state->seek) {
- state->seek = 0;
- if (gz_zero(state, state->skip) == -1)
- return 0;
- }
-
- /* for small len, copy to input buffer, otherwise compress directly */
- if (len < state->size) {
- /* copy to input buffer, compress when full */
- do {
- if (strm->avail_in == 0)
- strm->next_in = state->in;
- n = state->size - strm->avail_in;
- if (n > len)
- n = len;
- memcpy(strm->next_in + strm->avail_in, buf, n);
- strm->avail_in += n;
- state->pos += n;
- buf = (char *)buf + n;
- len -= n;
- if (len && gz_comp(state, Z_NO_FLUSH) == -1)
- return 0;
- } while (len);
- }
- else {
- /* consume whatever's left in the input buffer */
- if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
- return 0;
-
- /* directly compress user buffer to file */
- strm->avail_in = len;
- strm->next_in = (voidp)buf;
- state->pos += len;
- if (gz_comp(state, Z_NO_FLUSH) == -1)
- return 0;
- }
-
- /* input was all buffered or compressed (put will fit in int) */
- return (int)put;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char buf[1];
- gz_statep state;
- z_streamp strm;
-
- /* get internal structure */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
- strm = &(state->strm);
-
- /* check that we're writing and that there's no error */
- if (state->mode != GZ_WRITE || state->err != Z_OK)
- return -1;
-
- /* check for seek request */
- if (state->seek) {
- state->seek = 0;
- if (gz_zero(state, state->skip) == -1)
- return -1;
- }
-
- /* try writing to input buffer for speed (state->size == 0 if buffer not
- initialized) */
- if (strm->avail_in < state->size) {
- if (strm->avail_in == 0)
- strm->next_in = state->in;
- strm->next_in[strm->avail_in++] = c;
- state->pos++;
- return c;
- }
-
- /* no room in buffer or not initialized, use gz_write() */
- buf[0] = c;
- if (gzwrite(file, buf, 1) != 1)
- return -1;
- return c;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzputs(file, str)
- gzFile file;
- const char *str;
-{
- int ret;
- unsigned len;
-
- /* write string */
- len = (unsigned)strlen(str);
- ret = gzwrite(file, str, len);
- return ret == 0 && len != 0 ? -1 : ret;
-}
-
-#ifdef STDC
-#include <stdarg.h>
-
-/* -- see zlib.h -- */
-int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
-{
- int size, len;
- gz_statep state;
- z_streamp strm;
- va_list va;
-
- /* get internal structure */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
- strm = &(state->strm);
-
- /* check that we're writing and that there's no error */
- if (state->mode != GZ_WRITE || state->err != Z_OK)
- return 0;
-
- /* make sure we have some buffer space */
- if (state->size == 0 && gz_init(state) == -1)
- return 0;
-
- /* check for seek request */
- if (state->seek) {
- state->seek = 0;
- if (gz_zero(state, state->skip) == -1)
- return 0;
- }
-
- /* consume whatever's left in the input buffer */
- if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
- return 0;
-
- /* do the printf() into the input buffer, put length in len */
- size = (int)(state->size);
- state->in[size - 1] = 0;
- va_start(va, format);
-#ifdef NO_vsnprintf
-# ifdef HAS_vsprintf_void
- (void)vsprintf(state->in, format, va);
- va_end(va);
- for (len = 0; len < size; len++)
- if (state->in[len] == 0) break;
-# else
- len = vsprintf(state->in, format, va);
- va_end(va);
-# endif
-#else
-# ifdef HAS_vsnprintf_void
- (void)vsnprintf(state->in, size, format, va);
- va_end(va);
- len = strlen(state->in);
-# else
- len = vsnprintf((char *)(state->in), size, format, va);
- va_end(va);
-# endif
-#endif
-
- /* check that printf() results fit in buffer */
- if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
- return 0;
-
- /* update buffer and position, defer compression until needed */
- strm->avail_in = (unsigned)len;
- strm->next_in = state->in;
- state->pos += len;
- return len;
-}
-
-#else /* !STDC */
-
-/* -- see zlib.h -- */
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- int size, len;
- gz_statep state;
- z_streamp strm;
-
- /* get internal structure */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
- strm = &(state->strm);
-
- /* check that we're writing and that there's no error */
- if (state->mode != GZ_WRITE || state->err != Z_OK)
- return 0;
-
- /* make sure we have some buffer space */
- if (state->size == 0 && gz_init(state) == -1)
- return 0;
-
- /* check for seek request */
- if (state->seek) {
- state->seek = 0;
- if (gz_zero(state, state->skip) == -1)
- return 0;
- }
-
- /* consume whatever's left in the input buffer */
- if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
- return 0;
-
- /* do the printf() into the input buffer, put length in len */
- size = (int)(state->size);
- state->in[size - 1] = 0;
-#ifdef NO_snprintf
-# ifdef HAS_sprintf_void
- sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- for (len = 0; len < size; len++)
- if (state->in[len] == 0) break;
-# else
- len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#else
-# ifdef HAS_snprintf_void
- snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
- len = strlen(state->in);
-# else
- len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-# endif
-#endif
-
- /* check that printf() results fit in buffer */
- if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
- return 0;
-
- /* update buffer and position, defer compression until needed */
- strm->avail_in = (unsigned)len;
- strm->next_in = state->in;
- state->pos += len;
- return len;
-}
-
-#endif
-
-/* -- see zlib.h -- */
-int ZEXPORT gzflush(file, flush)
- gzFile file;
- int flush;
-{
- gz_statep state;
-
- /* get internal structure */
- if (file == NULL)
- return -1;
- state = (gz_statep)file;
-
- /* check that we're writing and that there's no error */
- if (state->mode != GZ_WRITE || state->err != Z_OK)
- return Z_STREAM_ERROR;
-
- /* check flush parameter */
- if (flush < 0 || flush > Z_FINISH)
- return Z_STREAM_ERROR;
-
- /* check for seek request */
- if (state->seek) {
- state->seek = 0;
- if (gz_zero(state, state->skip) == -1)
- return -1;
- }
-
- /* compress remaining data with requested flush */
- gz_comp(state, flush);
- return state->err;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzsetparams(file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_statep state;
- z_streamp strm;
-
- /* get internal structure */
- if (file == NULL)
- return Z_STREAM_ERROR;
- state = (gz_statep)file;
- strm = &(state->strm);
-
- /* check that we're writing and that there's no error */
- if (state->mode != GZ_WRITE || state->err != Z_OK)
- return Z_STREAM_ERROR;
-
- /* if no change is requested, then do nothing */
- if (level == state->level && strategy == state->strategy)
- return Z_OK;
-
- /* check for seek request */
- if (state->seek) {
- state->seek = 0;
- if (gz_zero(state, state->skip) == -1)
- return -1;
- }
-
- /* change compression parameters for subsequent input */
- if (state->size) {
- /* flush previous input with previous parameters before changing */
- if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
- return state->err;
- deflateParams(strm, level, strategy);
- }
- state->level = level;
- state->strategy = strategy;
- return Z_OK;
-}
-
-/* -- see zlib.h -- */
-int ZEXPORT gzclose_w(file)
- gzFile file;
-{
- int ret = 0;
- gz_statep state;
-
- /* get internal structure */
- if (file == NULL)
- return Z_STREAM_ERROR;
- state = (gz_statep)file;
-
- /* check that we're writing */
- if (state->mode != GZ_WRITE)
- return Z_STREAM_ERROR;
-
- /* check for seek request */
- if (state->seek) {
- state->seek = 0;
- ret += gz_zero(state, state->skip);
- }
-
- /* flush, free memory, and close file */
- ret += gz_comp(state, Z_FINISH);
- (void)deflateEnd(&(state->strm));
- free(state->out);
- free(state->in);
- gz_error(state, Z_OK, NULL);
- free(state->path);
- ret += close(state->fd);
- free(state);
- return ret ? Z_ERRNO : Z_OK;
-}
diff --git a/security/nss/lib/zlib/infback.c b/security/nss/lib/zlib/infback.c
deleted file mode 100644
index af3a8c965..000000000
--- a/security/nss/lib/zlib/infback.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/* infback.c -- inflate using a call-back interface
- * Copyright (C) 1995-2009 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- This code is largely copied from inflate.c. Normally either infback.o or
- inflate.o would be linked into an application--not both. The interface
- with inffast.c is retained so that optimized assembler-coded versions of
- inflate_fast() can be used with either inflate.c or infback.c.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-
-/*
- strm provides memory allocation functions in zalloc and zfree, or
- Z_NULL to use the library memory allocation functions.
-
- windowBits is in the range 8..15, and window is a user-supplied
- window and output buffer that is 2**windowBits bytes.
- */
-int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
-z_streamp strm;
-int windowBits;
-unsigned char FAR *window;
-const char *version;
-int stream_size;
-{
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL || window == Z_NULL ||
- windowBits < 8 || windowBits > 15)
- return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)ZALLOC(strm, 1,
- sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- state->dmax = 32768U;
- state->wbits = windowBits;
- state->wsize = 1U << windowBits;
- state->window = window;
- state->wnext = 0;
- state->whave = 0;
- return Z_OK;
-}
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-#ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
-#else /* !BUILDFIXED */
-# include "inffixed.h"
-#endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
-}
-
-/* Macros for inflateBack(): */
-
-/* Load returned state from inflate_fast() */
-#define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
-/* Set state from registers for inflate_fast() */
-#define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Assure that some input is available. If input is requested, but denied,
- then return a Z_BUF_ERROR from inflateBack(). */
-#define PULL() \
- do { \
- if (have == 0) { \
- have = in(in_desc, &next); \
- if (have == 0) { \
- next = Z_NULL; \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflateBack()
- with an error if there is no input available. */
-#define PULLBYTE() \
- do { \
- PULL(); \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflateBack() with
- an error. */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Assure that some output space is available, by writing out the window
- if it's full. If the write fails, return from inflateBack() with a
- Z_BUF_ERROR. */
-#define ROOM() \
- do { \
- if (left == 0) { \
- put = state->window; \
- left = state->wsize; \
- state->whave = left; \
- if (out(out_desc, put, left)) { \
- ret = Z_BUF_ERROR; \
- goto inf_leave; \
- } \
- } \
- } while (0)
-
-/*
- strm provides the memory allocation functions and window buffer on input,
- and provides information on the unused input on return. For Z_DATA_ERROR
- returns, strm will also provide an error message.
-
- in() and out() are the call-back input and output functions. When
- inflateBack() needs more input, it calls in(). When inflateBack() has
- filled the window with output, or when it completes with data in the
- window, it calls out() to write out the data. The application must not
- change the provided input until in() is called again or inflateBack()
- returns. The application must not change the window/output buffer until
- inflateBack() returns.
-
- in() and out() are called with a descriptor parameter provided in the
- inflateBack() call. This parameter can be a structure that provides the
- information required to do the read or write, as well as accumulated
- information on the input and output such as totals and check values.
-
- in() should return zero on failure. out() should return non-zero on
- failure. If either in() or out() fails, than inflateBack() returns a
- Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
- was in() or out() that caused in the error. Otherwise, inflateBack()
- returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
- error, or Z_MEM_ERROR if it could not allocate memory for the state.
- inflateBack() can also return Z_STREAM_ERROR if the input parameters
- are not correct, i.e. strm is Z_NULL or the state was not initialized.
- */
-int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
-z_streamp strm;
-in_func in;
-void FAR *in_desc;
-out_func out;
-void FAR *out_desc;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code here; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- /* Check that the strm exists and that the state was initialized */
- if (strm == Z_NULL || strm->state == Z_NULL)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
-
- /* Reset the state */
- strm->msg = Z_NULL;
- state->mode = TYPE;
- state->last = 0;
- state->whave = 0;
- next = strm->next_in;
- have = next != Z_NULL ? strm->avail_in : 0;
- hold = 0;
- bits = 0;
- put = state->window;
- left = state->wsize;
-
- /* Inflate until end of block marked as last */
- for (;;)
- switch (state->mode) {
- case TYPE:
- /* determine and dispatch block type */
- if (state->last) {
- BYTEBITS();
- state->mode = DONE;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN; /* decode codes */
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
-
- case STORED:
- /* get and verify stored block length */
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
-
- /* copy stored block from input to output */
- while (state->length != 0) {
- copy = state->length;
- PULL();
- ROOM();
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
-
- case TABLE:
- /* get dynamic table entries descriptor */
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
-#endif
- Tracev((stderr, "inflate: table sizes ok\n"));
-
- /* get code length code lengths (not a typo) */
- state->have = 0;
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
-
- /* get length and distance code code lengths */
- state->have = 0;
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- here = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(here.bits) <= bits) break;
- PULLBYTE();
- }
- if (here.val < 16) {
- NEEDBITS(here.bits);
- DROPBITS(here.bits);
- state->lens[state->have++] = here.val;
- }
- else {
- if (here.val == 16) {
- NEEDBITS(here.bits + 2);
- DROPBITS(here.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = (unsigned)(state->lens[state->have - 1]);
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (here.val == 17) {
- NEEDBITS(here.bits + 3);
- DROPBITS(here.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(here.bits + 7);
- DROPBITS(here.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* check for end-of-block code (better have one) */
- if (state->lens[256] == 0) {
- strm->msg = (char *)"invalid code -- missing end-of-block";
- state->mode = BAD;
- break;
- }
-
- /* build code tables -- note: do not change the lenbits or distbits
- values here (9 and 6) without reading the comments in inftrees.h
- concerning the ENOUGH constants, which depend on those values */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN;
-
- case LEN:
- /* use inflate_fast() if we have enough input and output */
- if (have >= 6 && left >= 258) {
- RESTORE();
- if (state->whave < state->wsize)
- state->whave = state->wsize - left;
- inflate_fast(strm, state->wsize);
- LOAD();
- break;
- }
-
- /* get a literal, length, or end-of-block code */
- for (;;) {
- here = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(here.bits) <= bits) break;
- PULLBYTE();
- }
- if (here.op && (here.op & 0xf0) == 0) {
- last = here;
- for (;;) {
- here = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + here.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(here.bits);
- state->length = (unsigned)here.val;
-
- /* process literal */
- if (here.op == 0) {
- Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", here.val));
- ROOM();
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- }
-
- /* process end of block */
- if (here.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
-
- /* invalid code */
- if (here.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
-
- /* length code -- get extra bits, if any */
- state->extra = (unsigned)(here.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
-
- /* get distance code */
- for (;;) {
- here = state->distcode[BITS(state->distbits)];
- if ((unsigned)(here.bits) <= bits) break;
- PULLBYTE();
- }
- if ((here.op & 0xf0) == 0) {
- last = here;
- for (;;) {
- here = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + here.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- }
- DROPBITS(here.bits);
- if (here.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)here.val;
-
- /* get distance extra bits, if any */
- state->extra = (unsigned)(here.op) & 15;
- if (state->extra != 0) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- }
- if (state->offset > state->wsize - (state->whave < state->wsize ?
- left : 0)) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
-
- /* copy match from window to output */
- do {
- ROOM();
- copy = state->wsize - state->offset;
- if (copy < left) {
- from = put + copy;
- copy = left - copy;
- }
- else {
- from = put - state->offset;
- copy = left;
- }
- if (copy > state->length) copy = state->length;
- state->length -= copy;
- left -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- } while (state->length != 0);
- break;
-
- case DONE:
- /* inflate stream terminated properly -- write leftover output */
- ret = Z_STREAM_END;
- if (left < state->wsize) {
- if (out(out_desc, state->window, state->wsize - left))
- ret = Z_BUF_ERROR;
- }
- goto inf_leave;
-
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
-
- default: /* can't happen, but makes compilers happy */
- ret = Z_STREAM_ERROR;
- goto inf_leave;
- }
-
- /* Return unused input */
- inf_leave:
- strm->next_in = next;
- strm->avail_in = have;
- return ret;
-}
-
-int ZEXPORT inflateBackEnd(strm)
-z_streamp strm;
-{
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
diff --git a/security/nss/lib/zlib/inffast.c b/security/nss/lib/zlib/inffast.c
deleted file mode 100644
index 2f1d60b43..000000000
--- a/security/nss/lib/zlib/inffast.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/* inffast.c -- fast decoding
- * Copyright (C) 1995-2008, 2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifndef ASMINF
-
-/* Allow machine dependent optimization for post-increment or pre-increment.
- Based on testing to date,
- Pre-increment preferred for:
- - PowerPC G3 (Adler)
- - MIPS R5000 (Randers-Pehrson)
- Post-increment preferred for:
- - none
- No measurable difference:
- - Pentium III (Anderson)
- - M68060 (Nikl)
- */
-#ifdef POSTINC
-# define OFF 0
-# define PUP(a) *(a)++
-#else
-# define OFF 1
-# define PUP(a) *++(a)
-#endif
-
-/*
- Decode literal, length, and distance codes and write out the resulting
- literal and match bytes until either not enough input or output is
- available, an end-of-block is encountered, or a data error is encountered.
- When large enough input and output buffers are supplied to inflate(), for
- example, a 16K input buffer and a 64K output buffer, more than 95% of the
- inflate execution time is spent in this routine.
-
- Entry assumptions:
-
- state->mode == LEN
- strm->avail_in >= 6
- strm->avail_out >= 258
- start >= strm->avail_out
- state->bits < 8
-
- On return, state->mode is one of:
-
- LEN -- ran out of enough output space or enough available input
- TYPE -- reached end of block code, inflate() to interpret next block
- BAD -- error in block data
-
- Notes:
-
- - The maximum input bits used by a length/distance pair is 15 bits for the
- length code, 5 bits for the length extra, 15 bits for the distance code,
- and 13 bits for the distance extra. This totals 48 bits, or six bytes.
- Therefore if strm->avail_in >= 6, then there is enough input to avoid
- checking for available input while decoding.
-
- - The maximum bytes that a single length/distance pair can output is 258
- bytes, which is the maximum length that can be coded. inflate_fast()
- requires strm->avail_out >= 258 for each loop to avoid checking for
- output space.
- */
-void ZLIB_INTERNAL inflate_fast(strm, start)
-z_streamp strm;
-unsigned start; /* inflate()'s starting value for strm->avail_out */
-{
- struct inflate_state FAR *state;
- unsigned char FAR *in; /* local strm->next_in */
- unsigned char FAR *last; /* while in < last, enough input available */
- unsigned char FAR *out; /* local strm->next_out */
- unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
- unsigned char FAR *end; /* while out < end, enough space available */
-#ifdef INFLATE_STRICT
- unsigned dmax; /* maximum distance from zlib header */
-#endif
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned wnext; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
- unsigned long hold; /* local strm->hold */
- unsigned bits; /* local strm->bits */
- code const FAR *lcode; /* local strm->lencode */
- code const FAR *dcode; /* local strm->distcode */
- unsigned lmask; /* mask for first level of length codes */
- unsigned dmask; /* mask for first level of distance codes */
- code here; /* retrieved table entry */
- unsigned op; /* code bits, operation, extra bits, or */
- /* window position, window bytes to copy */
- unsigned len; /* match length, unused bytes */
- unsigned dist; /* match distance */
- unsigned char FAR *from; /* where to copy match from */
-
- /* copy state to local variables */
- state = (struct inflate_state FAR *)strm->state;
- in = strm->next_in - OFF;
- last = in + (strm->avail_in - 5);
- out = strm->next_out - OFF;
- beg = out - (start - strm->avail_out);
- end = out + (strm->avail_out - 257);
-#ifdef INFLATE_STRICT
- dmax = state->dmax;
-#endif
- wsize = state->wsize;
- whave = state->whave;
- wnext = state->wnext;
- window = state->window;
- hold = state->hold;
- bits = state->bits;
- lcode = state->lencode;
- dcode = state->distcode;
- lmask = (1U << state->lenbits) - 1;
- dmask = (1U << state->distbits) - 1;
-
- /* decode literals and length/distances until end-of-block or not enough
- input data or output space */
- do {
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- here = lcode[hold & lmask];
- dolen:
- op = (unsigned)(here.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(here.op);
- if (op == 0) { /* literal */
- Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", here.val));
- PUP(out) = (unsigned char)(here.val);
- }
- else if (op & 16) { /* length base */
- len = (unsigned)(here.val);
- op &= 15; /* number of extra bits */
- if (op) {
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- len += (unsigned)hold & ((1U << op) - 1);
- hold >>= op;
- bits -= op;
- }
- Tracevv((stderr, "inflate: length %u\n", len));
- if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- here = dcode[hold & dmask];
- dodist:
- op = (unsigned)(here.bits);
- hold >>= op;
- bits -= op;
- op = (unsigned)(here.op);
- if (op & 16) { /* distance base */
- dist = (unsigned)(here.val);
- op &= 15; /* number of extra bits */
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
- bits += 8;
- }
- }
- dist += (unsigned)hold & ((1U << op) - 1);
-#ifdef INFLATE_STRICT
- if (dist > dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- hold >>= op;
- bits -= op;
- Tracevv((stderr, "inflate: distance %u\n", dist));
- op = (unsigned)(out - beg); /* max distance in output */
- if (dist > op) { /* see if copy from window */
- op = dist - op; /* distance back in window */
- if (op > whave) {
- if (state->sane) {
- strm->msg =
- (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
- if (len <= op - whave) {
- do {
- PUP(out) = 0;
- } while (--len);
- continue;
- }
- len -= op - whave;
- do {
- PUP(out) = 0;
- } while (--op > whave);
- if (op == 0) {
- from = out - dist;
- do {
- PUP(out) = PUP(from);
- } while (--len);
- continue;
- }
-#endif
- }
- from = window - OFF;
- if (wnext == 0) { /* very common case */
- from += wsize - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- else if (wnext < op) { /* wrap around window */
- from += wsize + wnext - op;
- op -= wnext;
- if (op < len) { /* some from end of window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = window - OFF;
- if (wnext < len) { /* some from start of window */
- op = wnext;
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- }
- else { /* contiguous in window */
- from += wnext - op;
- if (op < len) { /* some from window */
- len -= op;
- do {
- PUP(out) = PUP(from);
- } while (--op);
- from = out - dist; /* rest from output */
- }
- }
- while (len > 2) {
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- }
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- else {
- from = out - dist; /* copy direct from output */
- do { /* minimum length is three */
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- len -= 3;
- } while (len > 2);
- if (len) {
- PUP(out) = PUP(from);
- if (len > 1)
- PUP(out) = PUP(from);
- }
- }
- }
- else if ((op & 64) == 0) { /* 2nd level distance code */
- here = dcode[here.val + (hold & ((1U << op) - 1))];
- goto dodist;
- }
- else {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- }
- else if ((op & 64) == 0) { /* 2nd level length code */
- here = lcode[here.val + (hold & ((1U << op) - 1))];
- goto dolen;
- }
- else if (op & 32) { /* end-of-block */
- Tracevv((stderr, "inflate: end of block\n"));
- state->mode = TYPE;
- break;
- }
- else {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- } while (in < last && out < end);
-
- /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
- len = bits >> 3;
- in -= len;
- bits -= len << 3;
- hold &= (1U << bits) - 1;
-
- /* update state and return */
- strm->next_in = in + OFF;
- strm->next_out = out + OFF;
- strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
- strm->avail_out = (unsigned)(out < end ?
- 257 + (end - out) : 257 - (out - end));
- state->hold = hold;
- state->bits = bits;
- return;
-}
-
-/*
- inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- - Using bit fields for code structure
- - Different op definition to avoid & for extra bits (do & for table bits)
- - Three separate decoding do-loops for direct, window, and wnext == 0
- - Special case for distance > 1 copies to do overlapped load and store copy
- - Explicit branch predictions (based on measured branch probabilities)
- - Deferring match copy and interspersed it with decoding subsequent codes
- - Swapping literal/length else
- - Swapping window/direct else
- - Larger unrolled copy loops (three is about right)
- - Moving len -= 3 statement into middle of loop
- */
-
-#endif /* !ASMINF */
diff --git a/security/nss/lib/zlib/inffast.h b/security/nss/lib/zlib/inffast.h
deleted file mode 100644
index e5c1aa4ca..000000000
--- a/security/nss/lib/zlib/inffast.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2003, 2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/security/nss/lib/zlib/inffixed.h b/security/nss/lib/zlib/inffixed.h
deleted file mode 100644
index 05640fec3..000000000
--- a/security/nss/lib/zlib/inffixed.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
- /* inffixed.h -- table for decoding fixed codes
- * Generated automatically by makefixed().
- */
-
- /* WARNING: this file should *not* be used by applications. It
- is part of the implementation of the compression library and
- is subject to change. Applications should only use zlib.h.
- */
-
- static const code lenfix[512] = {
- {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
- {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
- {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
- {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
- {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
- {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
- {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
- {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
- {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
- {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
- {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
- {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
- {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
- {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
- {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
- {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
- {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
- {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
- {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
- {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
- {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
- {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
- {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
- {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
- {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
- {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
- {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
- {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
- {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
- {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
- {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
- {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
- {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
- {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
- {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
- {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
- {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
- {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
- {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
- {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
- {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
- {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
- {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
- {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
- {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
- {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
- {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
- {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
- {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
- {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
- {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
- {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
- {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
- {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
- {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
- {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
- {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
- {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
- {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
- {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
- {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
- {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
- {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
- {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
- {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
- {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
- {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
- {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
- {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
- {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
- {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
- {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
- {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
- {0,9,255}
- };
-
- static const code distfix[32] = {
- {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
- {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
- {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
- {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
- {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
- {22,5,193},{64,5,0}
- };
diff --git a/security/nss/lib/zlib/inflate.c b/security/nss/lib/zlib/inflate.c
deleted file mode 100644
index a8431abea..000000000
--- a/security/nss/lib/zlib/inflate.c
+++ /dev/null
@@ -1,1480 +0,0 @@
-/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * Change history:
- *
- * 1.2.beta0 24 Nov 2002
- * - First version -- complete rewrite of inflate to simplify code, avoid
- * creation of window when not needed, minimize use of window when it is
- * needed, make inffast.c even faster, implement gzip decoding, and to
- * improve code readability and style over the previous zlib inflate code
- *
- * 1.2.beta1 25 Nov 2002
- * - Use pointers for available input and output checking in inffast.c
- * - Remove input and output counters in inffast.c
- * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
- * - Remove unnecessary second byte pull from length extra in inffast.c
- * - Unroll direct copy to three copies per loop in inffast.c
- *
- * 1.2.beta2 4 Dec 2002
- * - Change external routine names to reduce potential conflicts
- * - Correct filename to inffixed.h for fixed tables in inflate.c
- * - Make hbuf[] unsigned char to match parameter type in inflate.c
- * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
- * to avoid negation problem on Alphas (64 bit) in inflate.c
- *
- * 1.2.beta3 22 Dec 2002
- * - Add comments on state->bits assertion in inffast.c
- * - Add comments on op field in inftrees.h
- * - Fix bug in reuse of allocated window after inflateReset()
- * - Remove bit fields--back to byte structure for speed
- * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
- * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
- * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
- * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
- * - Use local copies of stream next and avail values, as well as local bit
- * buffer and bit count in inflate()--for speed when inflate_fast() not used
- *
- * 1.2.beta4 1 Jan 2003
- * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
- * - Move a comment on output buffer sizes from inffast.c to inflate.c
- * - Add comments in inffast.c to introduce the inflate_fast() routine
- * - Rearrange window copies in inflate_fast() for speed and simplification
- * - Unroll last copy for window match in inflate_fast()
- * - Use local copies of window variables in inflate_fast() for speed
- * - Pull out common wnext == 0 case for speed in inflate_fast()
- * - Make op and len in inflate_fast() unsigned for consistency
- * - Add FAR to lcode and dcode declarations in inflate_fast()
- * - Simplified bad distance check in inflate_fast()
- * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
- * source file infback.c to provide a call-back interface to inflate for
- * programs like gzip and unzip -- uses window as output buffer to avoid
- * window copying
- *
- * 1.2.beta5 1 Jan 2003
- * - Improved inflateBack() interface to allow the caller to provide initial
- * input in strm.
- * - Fixed stored blocks bug in inflateBack()
- *
- * 1.2.beta6 4 Jan 2003
- * - Added comments in inffast.c on effectiveness of POSTINC
- * - Typecasting all around to reduce compiler warnings
- * - Changed loops from while (1) or do {} while (1) to for (;;), again to
- * make compilers happy
- * - Changed type of window in inflateBackInit() to unsigned char *
- *
- * 1.2.beta7 27 Jan 2003
- * - Changed many types to unsigned or unsigned short to avoid warnings
- * - Added inflateCopy() function
- *
- * 1.2.0 9 Mar 2003
- * - Changed inflateBack() interface to provide separate opaque descriptors
- * for the in() and out() functions
- * - Changed inflateBack() argument and in_func typedef to swap the length
- * and buffer address return values for the input function
- * - Check next_in and next_out for Z_NULL on entry to inflate()
- *
- * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "inflate.h"
-#include "inffast.h"
-
-#ifdef MAKEFIXED
-# ifndef BUILDFIXED
-# define BUILDFIXED
-# endif
-#endif
-
-/* function prototypes */
-local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, unsigned out));
-#ifdef BUILDFIXED
- void makefixed OF((void));
-#endif
-local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
- unsigned len));
-
-int ZEXPORT inflateReset(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- strm->total_in = strm->total_out = state->total = 0;
- strm->msg = Z_NULL;
- strm->adler = 1; /* to support ill-conceived Java test suite */
- state->mode = HEAD;
- state->last = 0;
- state->havedict = 0;
- state->dmax = 32768U;
- state->head = Z_NULL;
- state->wsize = 0;
- state->whave = 0;
- state->wnext = 0;
- state->hold = 0;
- state->bits = 0;
- state->lencode = state->distcode = state->next = state->codes;
- state->sane = 1;
- state->back = -1;
- Tracev((stderr, "inflate: reset\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateReset2(strm, windowBits)
-z_streamp strm;
-int windowBits;
-{
- int wrap;
- struct inflate_state FAR *state;
-
- /* get the state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
-
- /* extract wrap request from windowBits parameter */
- if (windowBits < 0) {
- wrap = 0;
- windowBits = -windowBits;
- }
- else {
- wrap = (windowBits >> 4) + 1;
-#ifdef GUNZIP
- if (windowBits < 48)
- windowBits &= 15;
-#endif
- }
-
- /* set number of window bits, free window if different */
- if (windowBits && (windowBits < 8 || windowBits > 15))
- return Z_STREAM_ERROR;
- if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
- ZFREE(strm, state->window);
- state->window = Z_NULL;
- }
-
- /* update state and reset the rest of it */
- state->wrap = wrap;
- state->wbits = (unsigned)windowBits;
- return inflateReset(strm);
-}
-
-int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
-z_streamp strm;
-int windowBits;
-const char *version;
-int stream_size;
-{
- int ret;
- struct inflate_state FAR *state;
-
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
- if (strm == Z_NULL) return Z_STREAM_ERROR;
- strm->msg = Z_NULL; /* in case we return an error */
- if (strm->zalloc == (alloc_func)0) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == (free_func)0) strm->zfree = zcfree;
- state = (struct inflate_state FAR *)
- ZALLOC(strm, 1, sizeof(struct inflate_state));
- if (state == Z_NULL) return Z_MEM_ERROR;
- Tracev((stderr, "inflate: allocated\n"));
- strm->state = (struct internal_state FAR *)state;
- state->window = Z_NULL;
- ret = inflateReset2(strm, windowBits);
- if (ret != Z_OK) {
- ZFREE(strm, state);
- strm->state = Z_NULL;
- }
- return ret;
-}
-
-int ZEXPORT inflateInit_(strm, version, stream_size)
-z_streamp strm;
-const char *version;
-int stream_size;
-{
- return inflateInit2_(strm, DEF_WBITS, version, stream_size);
-}
-
-int ZEXPORT inflatePrime(strm, bits, value)
-z_streamp strm;
-int bits;
-int value;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (bits < 0) {
- state->hold = 0;
- state->bits = 0;
- return Z_OK;
- }
- if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
- value &= (1L << bits) - 1;
- state->hold += value << state->bits;
- state->bits += bits;
- return Z_OK;
-}
-
-/*
- Return state with length and distance decoding tables and index sizes set to
- fixed code decoding. Normally this returns fixed tables from inffixed.h.
- If BUILDFIXED is defined, then instead this routine builds the tables the
- first time it's called, and returns those tables the first time and
- thereafter. This reduces the size of the code by about 2K bytes, in
- exchange for a little execution time. However, BUILDFIXED should not be
- used for threaded applications, since the rewriting of the tables and virgin
- may not be thread-safe.
- */
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-#ifdef BUILDFIXED
- static int virgin = 1;
- static code *lenfix, *distfix;
- static code fixed[544];
-
- /* build fixed huffman tables if first call (may not be thread safe) */
- if (virgin) {
- unsigned sym, bits;
- static code *next;
-
- /* literal/length table */
- sym = 0;
- while (sym < 144) state->lens[sym++] = 8;
- while (sym < 256) state->lens[sym++] = 9;
- while (sym < 280) state->lens[sym++] = 7;
- while (sym < 288) state->lens[sym++] = 8;
- next = fixed;
- lenfix = next;
- bits = 9;
- inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
-
- /* distance table */
- sym = 0;
- while (sym < 32) state->lens[sym++] = 5;
- distfix = next;
- bits = 5;
- inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
-
- /* do this just once */
- virgin = 0;
- }
-#else /* !BUILDFIXED */
-# include "inffixed.h"
-#endif /* BUILDFIXED */
- state->lencode = lenfix;
- state->lenbits = 9;
- state->distcode = distfix;
- state->distbits = 5;
-}
-
-#ifdef MAKEFIXED
-#include <stdio.h>
-
-/*
- Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
- defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
- those tables to stdout, which would be piped to inffixed.h. A small program
- can simply call makefixed to do this:
-
- void makefixed(void);
-
- int main(void)
- {
- makefixed();
- return 0;
- }
-
- Then that can be linked with zlib built with MAKEFIXED defined and run:
-
- a.out > inffixed.h
- */
-void makefixed()
-{
- unsigned low, size;
- struct inflate_state state;
-
- fixedtables(&state);
- puts(" /* inffixed.h -- table for decoding fixed codes");
- puts(" * Generated automatically by makefixed().");
- puts(" */");
- puts("");
- puts(" /* WARNING: this file should *not* be used by applications.");
- puts(" It is part of the implementation of this library and is");
- puts(" subject to change. Applications should only use zlib.h.");
- puts(" */");
- puts("");
- size = 1U << 9;
- printf(" static const code lenfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 7) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
- state.lencode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
- size = 1U << 5;
- printf("\n static const code distfix[%u] = {", size);
- low = 0;
- for (;;) {
- if ((low % 6) == 0) printf("\n ");
- printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
- state.distcode[low].val);
- if (++low == size) break;
- putchar(',');
- }
- puts("\n };");
-}
-#endif /* MAKEFIXED */
-
-/*
- Update the window with the last wsize (normally 32K) bytes written before
- returning. If window does not exist yet, create it. This is only called
- when a window is already in use, or when output has been written during this
- inflate call, but the end of the deflate stream has not been reached yet.
- It is also called to create a window for dictionary data when a dictionary
- is loaded.
-
- Providing output buffers larger than 32K to inflate() should provide a speed
- advantage, since only the last 32K of output is copied to the sliding window
- upon return from inflate(), and since all distances after the first 32K of
- output will fall in the output data, making match copies simpler and faster.
- The advantage may be dependent on the size of the processor's data caches.
- */
-local int updatewindow(strm, out)
-z_streamp strm;
-unsigned out;
-{
- struct inflate_state FAR *state;
- unsigned copy, dist;
-
- state = (struct inflate_state FAR *)strm->state;
-
- /* if it hasn't been done already, allocate space for the window */
- if (state->window == Z_NULL) {
- state->window = (unsigned char FAR *)
- ZALLOC(strm, 1U << state->wbits,
- sizeof(unsigned char));
- if (state->window == Z_NULL) return 1;
- }
-
- /* if window not in use yet, initialize */
- if (state->wsize == 0) {
- state->wsize = 1U << state->wbits;
- state->wnext = 0;
- state->whave = 0;
- }
-
- /* copy state->wsize or less output bytes into the circular window */
- copy = out - strm->avail_out;
- if (copy >= state->wsize) {
- zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
- state->wnext = 0;
- state->whave = state->wsize;
- }
- else {
- dist = state->wsize - state->wnext;
- if (dist > copy) dist = copy;
- zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
- copy -= dist;
- if (copy) {
- zmemcpy(state->window, strm->next_out - copy, copy);
- state->wnext = copy;
- state->whave = state->wsize;
- }
- else {
- state->wnext += dist;
- if (state->wnext == state->wsize) state->wnext = 0;
- if (state->whave < state->wsize) state->whave += dist;
- }
- }
- return 0;
-}
-
-/* Macros for inflate(): */
-
-/* check function to use adler32() for zlib or crc32() for gzip */
-#ifdef GUNZIP
-# define UPDATE(check, buf, len) \
- (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
-#else
-# define UPDATE(check, buf, len) adler32(check, buf, len)
-#endif
-
-/* check macros for header crc */
-#ifdef GUNZIP
-# define CRC2(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- check = crc32(check, hbuf, 2); \
- } while (0)
-
-# define CRC4(check, word) \
- do { \
- hbuf[0] = (unsigned char)(word); \
- hbuf[1] = (unsigned char)((word) >> 8); \
- hbuf[2] = (unsigned char)((word) >> 16); \
- hbuf[3] = (unsigned char)((word) >> 24); \
- check = crc32(check, hbuf, 4); \
- } while (0)
-#endif
-
-/* Load registers with state in inflate() for speed */
-#define LOAD() \
- do { \
- put = strm->next_out; \
- left = strm->avail_out; \
- next = strm->next_in; \
- have = strm->avail_in; \
- hold = state->hold; \
- bits = state->bits; \
- } while (0)
-
-/* Restore state from registers in inflate() */
-#define RESTORE() \
- do { \
- strm->next_out = put; \
- strm->avail_out = left; \
- strm->next_in = next; \
- strm->avail_in = have; \
- state->hold = hold; \
- state->bits = bits; \
- } while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
- do { \
- hold = 0; \
- bits = 0; \
- } while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflate()
- if there is no input available. */
-#define PULLBYTE() \
- do { \
- if (have == 0) goto inf_leave; \
- have--; \
- hold += (unsigned long)(*next++) << bits; \
- bits += 8; \
- } while (0)
-
-/* Assure that there are at least n bits in the bit accumulator. If there is
- not enough available input to do that, then return from inflate(). */
-#define NEEDBITS(n) \
- do { \
- while (bits < (unsigned)(n)) \
- PULLBYTE(); \
- } while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
- ((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
- do { \
- hold >>= (n); \
- bits -= (unsigned)(n); \
- } while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
- do { \
- hold >>= bits & 7; \
- bits -= bits & 7; \
- } while (0)
-
-/* Reverse the bytes in a 32-bit value */
-#define REVERSE(q) \
- ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
- (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
-/*
- inflate() uses a state machine to process as much input data and generate as
- much output data as possible before returning. The state machine is
- structured roughly as follows:
-
- for (;;) switch (state) {
- ...
- case STATEn:
- if (not enough input data or output space to make progress)
- return;
- ... make progress ...
- state = STATEm;
- break;
- ...
- }
-
- so when inflate() is called again, the same case is attempted again, and
- if the appropriate resources are provided, the machine proceeds to the
- next state. The NEEDBITS() macro is usually the way the state evaluates
- whether it can proceed or should return. NEEDBITS() does the return if
- the requested bits are not available. The typical use of the BITS macros
- is:
-
- NEEDBITS(n);
- ... do something with BITS(n) ...
- DROPBITS(n);
-
- where NEEDBITS(n) either returns from inflate() if there isn't enough
- input left to load n bits into the accumulator, or it continues. BITS(n)
- gives the low n bits in the accumulator. When done, DROPBITS(n) drops
- the low n bits off the accumulator. INITBITS() clears the accumulator
- and sets the number of available bits to zero. BYTEBITS() discards just
- enough bits to put the accumulator on a byte boundary. After BYTEBITS()
- and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
-
- NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
- if there is no input available. The decoding of variable length codes uses
- PULLBYTE() directly in order to pull just enough bytes to decode the next
- code, and no more.
-
- Some states loop until they get enough input, making sure that enough
- state information is maintained to continue the loop where it left off
- if NEEDBITS() returns in the loop. For example, want, need, and keep
- would all have to actually be part of the saved state in case NEEDBITS()
- returns:
-
- case STATEw:
- while (want < need) {
- NEEDBITS(n);
- keep[want++] = BITS(n);
- DROPBITS(n);
- }
- state = STATEx;
- case STATEx:
-
- As shown above, if the next state is also the next case, then the break
- is omitted.
-
- A state may also return if there is not enough output space available to
- complete that state. Those states are copying stored data, writing a
- literal byte, and copying a matching string.
-
- When returning, a "goto inf_leave" is used to update the total counters,
- update the check value, and determine whether any progress has been made
- during that inflate() call in order to return the proper return code.
- Progress is defined as a change in either strm->avail_in or strm->avail_out.
- When there is a window, goto inf_leave will update the window with the last
- output written. If a goto inf_leave occurs in the middle of decompression
- and there is no window currently, goto inf_leave will create one and copy
- output to the window for the next call of inflate().
-
- In this implementation, the flush parameter of inflate() only affects the
- return code (per zlib.h). inflate() always writes as much as possible to
- strm->next_out, given the space available and the provided input--the effect
- documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
- the allocation of and copying into a sliding window until necessary, which
- provides the effect documented in zlib.h for Z_FINISH when the entire input
- stream available. So the only thing the flush parameter actually does is:
- when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
- will return Z_BUF_ERROR if it has not reached the end of the stream.
- */
-
-int ZEXPORT inflate(strm, flush)
-z_streamp strm;
-int flush;
-{
- struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
- unsigned char FAR *put; /* next output */
- unsigned have, left; /* available input and output */
- unsigned long hold; /* bit buffer */
- unsigned bits; /* bits in bit buffer */
- unsigned in, out; /* save starting available input and output */
- unsigned copy; /* number of stored or match bytes to copy */
- unsigned char FAR *from; /* where to copy match bytes from */
- code here; /* current decoding table entry */
- code last; /* parent table entry */
- unsigned len; /* length to copy for repeats, bits to drop */
- int ret; /* return code */
-#ifdef GUNZIP
- unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
-#endif
- static const unsigned short order[19] = /* permutation of code lengths */
- {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
- if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0))
- return Z_STREAM_ERROR;
-
- state = (struct inflate_state FAR *)strm->state;
- if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
- LOAD();
- in = have;
- out = left;
- ret = Z_OK;
- for (;;)
- switch (state->mode) {
- case HEAD:
- if (state->wrap == 0) {
- state->mode = TYPEDO;
- break;
- }
- NEEDBITS(16);
-#ifdef GUNZIP
- if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
- state->check = crc32(0L, Z_NULL, 0);
- CRC2(state->check, hold);
- INITBITS();
- state->mode = FLAGS;
- break;
- }
- state->flags = 0; /* expect zlib header */
- if (state->head != Z_NULL)
- state->head->done = -1;
- if (!(state->wrap & 1) || /* check if zlib header allowed */
-#else
- if (
-#endif
- ((BITS(8) << 8) + (hold >> 8)) % 31) {
- strm->msg = (char *)"incorrect header check";
- state->mode = BAD;
- break;
- }
- if (BITS(4) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- DROPBITS(4);
- len = BITS(4) + 8;
- if (state->wbits == 0)
- state->wbits = len;
- else if (len > state->wbits) {
- strm->msg = (char *)"invalid window size";
- state->mode = BAD;
- break;
- }
- state->dmax = 1U << len;
- Tracev((stderr, "inflate: zlib header ok\n"));
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = hold & 0x200 ? DICTID : TYPE;
- INITBITS();
- break;
-#ifdef GUNZIP
- case FLAGS:
- NEEDBITS(16);
- state->flags = (int)(hold);
- if ((state->flags & 0xff) != Z_DEFLATED) {
- strm->msg = (char *)"unknown compression method";
- state->mode = BAD;
- break;
- }
- if (state->flags & 0xe000) {
- strm->msg = (char *)"unknown header flags set";
- state->mode = BAD;
- break;
- }
- if (state->head != Z_NULL)
- state->head->text = (int)((hold >> 8) & 1);
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = TIME;
- case TIME:
- NEEDBITS(32);
- if (state->head != Z_NULL)
- state->head->time = hold;
- if (state->flags & 0x0200) CRC4(state->check, hold);
- INITBITS();
- state->mode = OS;
- case OS:
- NEEDBITS(16);
- if (state->head != Z_NULL) {
- state->head->xflags = (int)(hold & 0xff);
- state->head->os = (int)(hold >> 8);
- }
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- state->mode = EXLEN;
- case EXLEN:
- if (state->flags & 0x0400) {
- NEEDBITS(16);
- state->length = (unsigned)(hold);
- if (state->head != Z_NULL)
- state->head->extra_len = (unsigned)hold;
- if (state->flags & 0x0200) CRC2(state->check, hold);
- INITBITS();
- }
- else if (state->head != Z_NULL)
- state->head->extra = Z_NULL;
- state->mode = EXTRA;
- case EXTRA:
- if (state->flags & 0x0400) {
- copy = state->length;
- if (copy > have) copy = have;
- if (copy) {
- if (state->head != Z_NULL &&
- state->head->extra != Z_NULL) {
- len = state->head->extra_len - state->length;
- zmemcpy(state->head->extra + len, next,
- len + copy > state->head->extra_max ?
- state->head->extra_max - len : copy);
- }
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- state->length -= copy;
- }
- if (state->length) goto inf_leave;
- }
- state->length = 0;
- state->mode = NAME;
- case NAME:
- if (state->flags & 0x0800) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->name != Z_NULL &&
- state->length < state->head->name_max)
- state->head->name[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->name = Z_NULL;
- state->length = 0;
- state->mode = COMMENT;
- case COMMENT:
- if (state->flags & 0x1000) {
- if (have == 0) goto inf_leave;
- copy = 0;
- do {
- len = (unsigned)(next[copy++]);
- if (state->head != Z_NULL &&
- state->head->comment != Z_NULL &&
- state->length < state->head->comm_max)
- state->head->comment[state->length++] = len;
- } while (len && copy < have);
- if (state->flags & 0x0200)
- state->check = crc32(state->check, next, copy);
- have -= copy;
- next += copy;
- if (len) goto inf_leave;
- }
- else if (state->head != Z_NULL)
- state->head->comment = Z_NULL;
- state->mode = HCRC;
- case HCRC:
- if (state->flags & 0x0200) {
- NEEDBITS(16);
- if (hold != (state->check & 0xffff)) {
- strm->msg = (char *)"header crc mismatch";
- state->mode = BAD;
- break;
- }
- INITBITS();
- }
- if (state->head != Z_NULL) {
- state->head->hcrc = (int)((state->flags >> 9) & 1);
- state->head->done = 1;
- }
- strm->adler = state->check = crc32(0L, Z_NULL, 0);
- state->mode = TYPE;
- break;
-#endif
- case DICTID:
- NEEDBITS(32);
- strm->adler = state->check = REVERSE(hold);
- INITBITS();
- state->mode = DICT;
- case DICT:
- if (state->havedict == 0) {
- RESTORE();
- return Z_NEED_DICT;
- }
- strm->adler = state->check = adler32(0L, Z_NULL, 0);
- state->mode = TYPE;
- case TYPE:
- if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
- case TYPEDO:
- if (state->last) {
- BYTEBITS();
- state->mode = CHECK;
- break;
- }
- NEEDBITS(3);
- state->last = BITS(1);
- DROPBITS(1);
- switch (BITS(2)) {
- case 0: /* stored block */
- Tracev((stderr, "inflate: stored block%s\n",
- state->last ? " (last)" : ""));
- state->mode = STORED;
- break;
- case 1: /* fixed block */
- fixedtables(state);
- Tracev((stderr, "inflate: fixed codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = LEN_; /* decode codes */
- if (flush == Z_TREES) {
- DROPBITS(2);
- goto inf_leave;
- }
- break;
- case 2: /* dynamic block */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- state->last ? " (last)" : ""));
- state->mode = TABLE;
- break;
- case 3:
- strm->msg = (char *)"invalid block type";
- state->mode = BAD;
- }
- DROPBITS(2);
- break;
- case STORED:
- BYTEBITS(); /* go to byte boundary */
- NEEDBITS(32);
- if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
- strm->msg = (char *)"invalid stored block lengths";
- state->mode = BAD;
- break;
- }
- state->length = (unsigned)hold & 0xffff;
- Tracev((stderr, "inflate: stored length %u\n",
- state->length));
- INITBITS();
- state->mode = COPY_;
- if (flush == Z_TREES) goto inf_leave;
- case COPY_:
- state->mode = COPY;
- case COPY:
- copy = state->length;
- if (copy) {
- if (copy > have) copy = have;
- if (copy > left) copy = left;
- if (copy == 0) goto inf_leave;
- zmemcpy(put, next, copy);
- have -= copy;
- next += copy;
- left -= copy;
- put += copy;
- state->length -= copy;
- break;
- }
- Tracev((stderr, "inflate: stored end\n"));
- state->mode = TYPE;
- break;
- case TABLE:
- NEEDBITS(14);
- state->nlen = BITS(5) + 257;
- DROPBITS(5);
- state->ndist = BITS(5) + 1;
- DROPBITS(5);
- state->ncode = BITS(4) + 4;
- DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
- if (state->nlen > 286 || state->ndist > 30) {
- strm->msg = (char *)"too many length or distance symbols";
- state->mode = BAD;
- break;
- }
-#endif
- Tracev((stderr, "inflate: table sizes ok\n"));
- state->have = 0;
- state->mode = LENLENS;
- case LENLENS:
- while (state->have < state->ncode) {
- NEEDBITS(3);
- state->lens[order[state->have++]] = (unsigned short)BITS(3);
- DROPBITS(3);
- }
- while (state->have < 19)
- state->lens[order[state->have++]] = 0;
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 7;
- ret = inflate_table(CODES, state->lens, 19, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid code lengths set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: code lengths ok\n"));
- state->have = 0;
- state->mode = CODELENS;
- case CODELENS:
- while (state->have < state->nlen + state->ndist) {
- for (;;) {
- here = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(here.bits) <= bits) break;
- PULLBYTE();
- }
- if (here.val < 16) {
- NEEDBITS(here.bits);
- DROPBITS(here.bits);
- state->lens[state->have++] = here.val;
- }
- else {
- if (here.val == 16) {
- NEEDBITS(here.bits + 2);
- DROPBITS(here.bits);
- if (state->have == 0) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- len = state->lens[state->have - 1];
- copy = 3 + BITS(2);
- DROPBITS(2);
- }
- else if (here.val == 17) {
- NEEDBITS(here.bits + 3);
- DROPBITS(here.bits);
- len = 0;
- copy = 3 + BITS(3);
- DROPBITS(3);
- }
- else {
- NEEDBITS(here.bits + 7);
- DROPBITS(here.bits);
- len = 0;
- copy = 11 + BITS(7);
- DROPBITS(7);
- }
- if (state->have + copy > state->nlen + state->ndist) {
- strm->msg = (char *)"invalid bit length repeat";
- state->mode = BAD;
- break;
- }
- while (copy--)
- state->lens[state->have++] = (unsigned short)len;
- }
- }
-
- /* handle error breaks in while */
- if (state->mode == BAD) break;
-
- /* check for end-of-block code (better have one) */
- if (state->lens[256] == 0) {
- strm->msg = (char *)"invalid code -- missing end-of-block";
- state->mode = BAD;
- break;
- }
-
- /* build code tables -- note: do not change the lenbits or distbits
- values here (9 and 6) without reading the comments in inftrees.h
- concerning the ENOUGH constants, which depend on those values */
- state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
- state->lenbits = 9;
- ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
- &(state->lenbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid literal/lengths set";
- state->mode = BAD;
- break;
- }
- state->distcode = (code const FAR *)(state->next);
- state->distbits = 6;
- ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
- &(state->next), &(state->distbits), state->work);
- if (ret) {
- strm->msg = (char *)"invalid distances set";
- state->mode = BAD;
- break;
- }
- Tracev((stderr, "inflate: codes ok\n"));
- state->mode = LEN_;
- if (flush == Z_TREES) goto inf_leave;
- case LEN_:
- state->mode = LEN;
- case LEN:
- if (have >= 6 && left >= 258) {
- RESTORE();
- inflate_fast(strm, out);
- LOAD();
- if (state->mode == TYPE)
- state->back = -1;
- break;
- }
- state->back = 0;
- for (;;) {
- here = state->lencode[BITS(state->lenbits)];
- if ((unsigned)(here.bits) <= bits) break;
- PULLBYTE();
- }
- if (here.op && (here.op & 0xf0) == 0) {
- last = here;
- for (;;) {
- here = state->lencode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + here.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- state->back += last.bits;
- }
- DROPBITS(here.bits);
- state->back += here.bits;
- state->length = (unsigned)here.val;
- if ((int)(here.op) == 0) {
- Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
- "inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", here.val));
- state->mode = LIT;
- break;
- }
- if (here.op & 32) {
- Tracevv((stderr, "inflate: end of block\n"));
- state->back = -1;
- state->mode = TYPE;
- break;
- }
- if (here.op & 64) {
- strm->msg = (char *)"invalid literal/length code";
- state->mode = BAD;
- break;
- }
- state->extra = (unsigned)(here.op) & 15;
- state->mode = LENEXT;
- case LENEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->length += BITS(state->extra);
- DROPBITS(state->extra);
- state->back += state->extra;
- }
- Tracevv((stderr, "inflate: length %u\n", state->length));
- state->was = state->length;
- state->mode = DIST;
- case DIST:
- for (;;) {
- here = state->distcode[BITS(state->distbits)];
- if ((unsigned)(here.bits) <= bits) break;
- PULLBYTE();
- }
- if ((here.op & 0xf0) == 0) {
- last = here;
- for (;;) {
- here = state->distcode[last.val +
- (BITS(last.bits + last.op) >> last.bits)];
- if ((unsigned)(last.bits + here.bits) <= bits) break;
- PULLBYTE();
- }
- DROPBITS(last.bits);
- state->back += last.bits;
- }
- DROPBITS(here.bits);
- state->back += here.bits;
- if (here.op & 64) {
- strm->msg = (char *)"invalid distance code";
- state->mode = BAD;
- break;
- }
- state->offset = (unsigned)here.val;
- state->extra = (unsigned)(here.op) & 15;
- state->mode = DISTEXT;
- case DISTEXT:
- if (state->extra) {
- NEEDBITS(state->extra);
- state->offset += BITS(state->extra);
- DROPBITS(state->extra);
- state->back += state->extra;
- }
-#ifdef INFLATE_STRICT
- if (state->offset > state->dmax) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#endif
- Tracevv((stderr, "inflate: distance %u\n", state->offset));
- state->mode = MATCH;
- case MATCH:
- if (left == 0) goto inf_leave;
- copy = out - left;
- if (state->offset > copy) { /* copy from window */
- copy = state->offset - copy;
- if (copy > state->whave) {
- if (state->sane) {
- strm->msg = (char *)"invalid distance too far back";
- state->mode = BAD;
- break;
- }
-#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
- Trace((stderr, "inflate.c too far\n"));
- copy -= state->whave;
- if (copy > state->length) copy = state->length;
- if (copy > left) copy = left;
- left -= copy;
- state->length -= copy;
- do {
- *put++ = 0;
- } while (--copy);
- if (state->length == 0) state->mode = LEN;
- break;
-#endif
- }
- if (copy > state->wnext) {
- copy -= state->wnext;
- from = state->window + (state->wsize - copy);
- }
- else
- from = state->window + (state->wnext - copy);
- if (copy > state->length) copy = state->length;
- }
- else { /* copy from output */
- from = put - state->offset;
- copy = state->length;
- }
- if (copy > left) copy = left;
- left -= copy;
- state->length -= copy;
- do {
- *put++ = *from++;
- } while (--copy);
- if (state->length == 0) state->mode = LEN;
- break;
- case LIT:
- if (left == 0) goto inf_leave;
- *put++ = (unsigned char)(state->length);
- left--;
- state->mode = LEN;
- break;
- case CHECK:
- if (state->wrap) {
- NEEDBITS(32);
- out -= left;
- strm->total_out += out;
- state->total += out;
- if (out)
- strm->adler = state->check =
- UPDATE(state->check, put - out, out);
- out = left;
- if ((
-#ifdef GUNZIP
- state->flags ? hold :
-#endif
- REVERSE(hold)) != state->check) {
- strm->msg = (char *)"incorrect data check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: check matches trailer\n"));
- }
-#ifdef GUNZIP
- state->mode = LENGTH;
- case LENGTH:
- if (state->wrap && state->flags) {
- NEEDBITS(32);
- if (hold != (state->total & 0xffffffffUL)) {
- strm->msg = (char *)"incorrect length check";
- state->mode = BAD;
- break;
- }
- INITBITS();
- Tracev((stderr, "inflate: length matches trailer\n"));
- }
-#endif
- state->mode = DONE;
- case DONE:
- ret = Z_STREAM_END;
- goto inf_leave;
- case BAD:
- ret = Z_DATA_ERROR;
- goto inf_leave;
- case MEM:
- return Z_MEM_ERROR;
- case SYNC:
- default:
- return Z_STREAM_ERROR;
- }
-
- /*
- Return from inflate(), updating the total counts and the check value.
- If there was no progress during the inflate() call, return a buffer
- error. Call updatewindow() to create and/or update the window state.
- Note: a memory error from inflate() is non-recoverable.
- */
- inf_leave:
- RESTORE();
- if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
- if (updatewindow(strm, out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- in -= strm->avail_in;
- out -= strm->avail_out;
- strm->total_in += in;
- strm->total_out += out;
- state->total += out;
- if (state->wrap && out)
- strm->adler = state->check =
- UPDATE(state->check, strm->next_out - out, out);
- strm->data_type = state->bits + (state->last ? 64 : 0) +
- (state->mode == TYPE ? 128 : 0) +
- (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
- if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
- ret = Z_BUF_ERROR;
- return ret;
-}
-
-int ZEXPORT inflateEnd(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->window != Z_NULL) ZFREE(strm, state->window);
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
- Tracev((stderr, "inflate: end\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
-z_streamp strm;
-const Bytef *dictionary;
-uInt dictLength;
-{
- struct inflate_state FAR *state;
- unsigned long id;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (state->wrap != 0 && state->mode != DICT)
- return Z_STREAM_ERROR;
-
- /* check for correct dictionary id */
- if (state->mode == DICT) {
- id = adler32(0L, Z_NULL, 0);
- id = adler32(id, dictionary, dictLength);
- if (id != state->check)
- return Z_DATA_ERROR;
- }
-
- /* copy dictionary to window */
- if (updatewindow(strm, strm->avail_out)) {
- state->mode = MEM;
- return Z_MEM_ERROR;
- }
- if (dictLength > state->wsize) {
- zmemcpy(state->window, dictionary + dictLength - state->wsize,
- state->wsize);
- state->whave = state->wsize;
- }
- else {
- zmemcpy(state->window + state->wsize - dictLength, dictionary,
- dictLength);
- state->whave = dictLength;
- }
- state->havedict = 1;
- Tracev((stderr, "inflate: dictionary set\n"));
- return Z_OK;
-}
-
-int ZEXPORT inflateGetHeader(strm, head)
-z_streamp strm;
-gz_headerp head;
-{
- struct inflate_state FAR *state;
-
- /* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
-
- /* save header structure */
- state->head = head;
- head->done = 0;
- return Z_OK;
-}
-
-/*
- Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
- or when out of input. When called, *have is the number of pattern bytes
- found in order so far, in 0..3. On return *have is updated to the new
- state. If on return *have equals four, then the pattern was found and the
- return value is how many bytes were read including the last byte of the
- pattern. If *have is less than four, then the pattern has not been found
- yet and the return value is len. In the latter case, syncsearch() can be
- called again with more data and the *have state. *have is initialized to
- zero for the first call.
- */
-local unsigned syncsearch(have, buf, len)
-unsigned FAR *have;
-unsigned char FAR *buf;
-unsigned len;
-{
- unsigned got;
- unsigned next;
-
- got = *have;
- next = 0;
- while (next < len && got < 4) {
- if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
- got++;
- else if (buf[next])
- got = 0;
- else
- got = 4 - got;
- next++;
- }
- *have = got;
- return next;
-}
-
-int ZEXPORT inflateSync(strm)
-z_streamp strm;
-{
- unsigned len; /* number of bytes to look at or looked at */
- unsigned long in, out; /* temporary to save total_in and total_out */
- unsigned char buf[4]; /* to restore bit buffer to byte string */
- struct inflate_state FAR *state;
-
- /* check parameters */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
-
- /* if first time, start search in bit buffer */
- if (state->mode != SYNC) {
- state->mode = SYNC;
- state->hold <<= state->bits & 7;
- state->bits -= state->bits & 7;
- len = 0;
- while (state->bits >= 8) {
- buf[len++] = (unsigned char)(state->hold);
- state->hold >>= 8;
- state->bits -= 8;
- }
- state->have = 0;
- syncsearch(&(state->have), buf, len);
- }
-
- /* search available input */
- len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
- strm->avail_in -= len;
- strm->next_in += len;
- strm->total_in += len;
-
- /* return no joy or set up to restart inflate() on a new block */
- if (state->have != 4) return Z_DATA_ERROR;
- in = strm->total_in; out = strm->total_out;
- inflateReset(strm);
- strm->total_in = in; strm->total_out = out;
- state->mode = TYPE;
- return Z_OK;
-}
-
-/*
- Returns true if inflate is currently at the end of a block generated by
- Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- implementation to provide an additional safety check. PPP uses
- Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
- block. When decompressing, PPP checks that at the end of input packet,
- inflate is waiting for these length bytes.
- */
-int ZEXPORT inflateSyncPoint(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- return state->mode == STORED && state->bits == 0;
-}
-
-int ZEXPORT inflateCopy(dest, source)
-z_streamp dest;
-z_streamp source;
-{
- struct inflate_state FAR *state;
- struct inflate_state FAR *copy;
- unsigned char FAR *window;
- unsigned wsize;
-
- /* check input */
- if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
- source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
- return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)source->state;
-
- /* allocate space */
- copy = (struct inflate_state FAR *)
- ZALLOC(source, 1, sizeof(struct inflate_state));
- if (copy == Z_NULL) return Z_MEM_ERROR;
- window = Z_NULL;
- if (state->window != Z_NULL) {
- window = (unsigned char FAR *)
- ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
- if (window == Z_NULL) {
- ZFREE(source, copy);
- return Z_MEM_ERROR;
- }
- }
-
- /* copy state */
- zmemcpy(dest, source, sizeof(z_stream));
- zmemcpy(copy, state, sizeof(struct inflate_state));
- if (state->lencode >= state->codes &&
- state->lencode <= state->codes + ENOUGH - 1) {
- copy->lencode = copy->codes + (state->lencode - state->codes);
- copy->distcode = copy->codes + (state->distcode - state->codes);
- }
- copy->next = copy->codes + (state->next - state->codes);
- if (window != Z_NULL) {
- wsize = 1U << state->wbits;
- zmemcpy(window, state->window, wsize);
- }
- copy->window = window;
- dest->state = (struct internal_state FAR *)copy;
- return Z_OK;
-}
-
-int ZEXPORT inflateUndermine(strm, subvert)
-z_streamp strm;
-int subvert;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- state = (struct inflate_state FAR *)strm->state;
- state->sane = !subvert;
-#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
- return Z_OK;
-#else
- state->sane = 1;
- return Z_DATA_ERROR;
-#endif
-}
-
-long ZEXPORT inflateMark(strm)
-z_streamp strm;
-{
- struct inflate_state FAR *state;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
- state = (struct inflate_state FAR *)strm->state;
- return ((long)(state->back) << 16) +
- (state->mode == COPY ? state->length :
- (state->mode == MATCH ? state->was - state->length : 0));
-}
diff --git a/security/nss/lib/zlib/inflate.h b/security/nss/lib/zlib/inflate.h
deleted file mode 100644
index 95f4986d4..000000000
--- a/security/nss/lib/zlib/inflate.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2009 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* define NO_GZIP when compiling if you want to disable gzip header and
- trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
- the crc code when it is not needed. For shared libraries, gzip decoding
- should be left enabled. */
-#ifndef NO_GZIP
-# define GUNZIP
-#endif
-
-/* Possible inflate modes between inflate() calls */
-typedef enum {
- HEAD, /* i: waiting for magic header */
- FLAGS, /* i: waiting for method and flags (gzip) */
- TIME, /* i: waiting for modification time (gzip) */
- OS, /* i: waiting for extra flags and operating system (gzip) */
- EXLEN, /* i: waiting for extra length (gzip) */
- EXTRA, /* i: waiting for extra bytes (gzip) */
- NAME, /* i: waiting for end of file name (gzip) */
- COMMENT, /* i: waiting for end of comment (gzip) */
- HCRC, /* i: waiting for header crc (gzip) */
- DICTID, /* i: waiting for dictionary check value */
- DICT, /* waiting for inflateSetDictionary() call */
- TYPE, /* i: waiting for type bits, including last-flag bit */
- TYPEDO, /* i: same, but skip check to exit inflate on new block */
- STORED, /* i: waiting for stored size (length and complement) */
- COPY_, /* i/o: same as COPY below, but only first time in */
- COPY, /* i/o: waiting for input or output to copy stored block */
- TABLE, /* i: waiting for dynamic block table lengths */
- LENLENS, /* i: waiting for code length code lengths */
- CODELENS, /* i: waiting for length/lit and distance code lengths */
- LEN_, /* i: same as LEN below, but only first time in */
- LEN, /* i: waiting for length/lit/eob code */
- LENEXT, /* i: waiting for length extra bits */
- DIST, /* i: waiting for distance code */
- DISTEXT, /* i: waiting for distance extra bits */
- MATCH, /* o: waiting for output space to copy string */
- LIT, /* o: waiting for output space to write literal */
- CHECK, /* i: waiting for 32-bit check value */
- LENGTH, /* i: waiting for 32-bit length (gzip) */
- DONE, /* finished check, done -- remain here until reset */
- BAD, /* got a data error -- remain here until reset */
- MEM, /* got an inflate() memory error -- remain here until reset */
- SYNC /* looking for synchronization bytes to restart inflate() */
-} inflate_mode;
-
-/*
- State transitions between above modes -
-
- (most modes can go to BAD or MEM on error -- not shown for clarity)
-
- Process header:
- HEAD -> (gzip) or (zlib) or (raw)
- (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
- HCRC -> TYPE
- (zlib) -> DICTID or TYPE
- DICTID -> DICT -> TYPE
- (raw) -> TYPEDO
- Read deflate blocks:
- TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
- STORED -> COPY_ -> COPY -> TYPE
- TABLE -> LENLENS -> CODELENS -> LEN_
- LEN_ -> LEN
- Read deflate codes in fixed or dynamic block:
- LEN -> LENEXT or LIT or TYPE
- LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
- LIT -> LEN
- Process trailer:
- CHECK -> LENGTH -> DONE
- */
-
-/* state maintained between inflate() calls. Approximately 10K bytes. */
-struct inflate_state {
- inflate_mode mode; /* current inflate mode */
- int last; /* true if processing last block */
- int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
- int havedict; /* true if dictionary provided */
- int flags; /* gzip header method and flags (0 if zlib) */
- unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
- unsigned long check; /* protected copy of check value */
- unsigned long total; /* protected copy of output count */
- gz_headerp head; /* where to save gzip header information */
- /* sliding window */
- unsigned wbits; /* log base 2 of requested window size */
- unsigned wsize; /* window size or zero if not using window */
- unsigned whave; /* valid bytes in the window */
- unsigned wnext; /* window write index */
- unsigned char FAR *window; /* allocated sliding window, if needed */
- /* bit accumulator */
- unsigned long hold; /* input bit accumulator */
- unsigned bits; /* number of bits in "in" */
- /* for string and stored block copying */
- unsigned length; /* literal or length of data to copy */
- unsigned offset; /* distance back to copy string from */
- /* for table and code decoding */
- unsigned extra; /* extra bits needed */
- /* fixed and dynamic code tables */
- code const FAR *lencode; /* starting table for length/literal codes */
- code const FAR *distcode; /* starting table for distance codes */
- unsigned lenbits; /* index bits for lencode */
- unsigned distbits; /* index bits for distcode */
- /* dynamic table building */
- unsigned ncode; /* number of code length code lengths */
- unsigned nlen; /* number of length code lengths */
- unsigned ndist; /* number of distance code lengths */
- unsigned have; /* number of code lengths in lens[] */
- code FAR *next; /* next available space in codes[] */
- unsigned short lens[320]; /* temporary storage for code lengths */
- unsigned short work[288]; /* work area for code table building */
- code codes[ENOUGH]; /* space for code tables */
- int sane; /* if false, allow invalid distance too far */
- int back; /* bits back of last unprocessed length/lit */
- unsigned was; /* initial length of match */
-};
diff --git a/security/nss/lib/zlib/inftrees.c b/security/nss/lib/zlib/inftrees.c
deleted file mode 100644
index 11e9c52ac..000000000
--- a/security/nss/lib/zlib/inftrees.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-
-#define MAXBITS 15
-
-const char inflate_copyright[] =
- " inflate 1.2.5 Copyright 1995-2010 Mark Adler ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/*
- Build a set of tables to decode the provided canonical Huffman code.
- The code lengths are lens[0..codes-1]. The result starts at *table,
- whose indices are 0..2^bits-1. work is a writable array of at least
- lens shorts, which is used as a work area. type is the type of code
- to be generated, CODES, LENS, or DISTS. On return, zero is success,
- -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
- on return points to the next available entry's address. bits is the
- requested root table index bits, and on return it is the actual root
- table index bits. It will differ if the request is greater than the
- longest code or if it is less than the shortest code.
- */
-int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
-codetype type;
-unsigned short FAR *lens;
-unsigned codes;
-code FAR * FAR *table;
-unsigned FAR *bits;
-unsigned short FAR *work;
-{
- unsigned len; /* a code's length in bits */
- unsigned sym; /* index of code symbols */
- unsigned min, max; /* minimum and maximum code lengths */
- unsigned root; /* number of index bits for root table */
- unsigned curr; /* number of index bits for current table */
- unsigned drop; /* code bits to drop for sub-table */
- int left; /* number of prefix codes available */
- unsigned used; /* code entries in table used */
- unsigned huff; /* Huffman code */
- unsigned incr; /* for incrementing code, index */
- unsigned fill; /* index for replicating entries */
- unsigned low; /* low bits for current root entry */
- unsigned mask; /* mask for low root bits */
- code here; /* table entry for duplication */
- code FAR *next; /* next available space in table */
- const unsigned short FAR *base; /* base value table to use */
- const unsigned short FAR *extra; /* extra bits table to use */
- int end; /* use base and extra for symbol > end */
- unsigned short count[MAXBITS+1]; /* number of codes of each length */
- unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
- static const unsigned short lbase[31] = { /* Length codes 257..285 base */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- static const unsigned short lext[31] = { /* Length codes 257..285 extra */
- 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
- 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195};
- static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577, 0, 0};
- static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
- 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
- 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
- 28, 28, 29, 29, 64, 64};
-
- /*
- Process a set of code lengths to create a canonical Huffman code. The
- code lengths are lens[0..codes-1]. Each length corresponds to the
- symbols 0..codes-1. The Huffman code is generated by first sorting the
- symbols by length from short to long, and retaining the symbol order
- for codes with equal lengths. Then the code starts with all zero bits
- for the first code of the shortest length, and the codes are integer
- increments for the same length, and zeros are appended as the length
- increases. For the deflate format, these bits are stored backwards
- from their more natural integer increment ordering, and so when the
- decoding tables are built in the large loop below, the integer codes
- are incremented backwards.
-
- This routine assumes, but does not check, that all of the entries in
- lens[] are in the range 0..MAXBITS. The caller must assure this.
- 1..MAXBITS is interpreted as that code length. zero means that that
- symbol does not occur in this code.
-
- The codes are sorted by computing a count of codes for each length,
- creating from that a table of starting indices for each length in the
- sorted table, and then entering the symbols in order in the sorted
- table. The sorted table is work[], with that space being provided by
- the caller.
-
- The length counts are used for other purposes as well, i.e. finding
- the minimum and maximum length codes, determining if there are any
- codes at all, checking for a valid set of lengths, and looking ahead
- at length counts to determine sub-table sizes when building the
- decoding tables.
- */
-
- /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
- for (len = 0; len <= MAXBITS; len++)
- count[len] = 0;
- for (sym = 0; sym < codes; sym++)
- count[lens[sym]]++;
-
- /* bound code lengths, force root to be within code lengths */
- root = *bits;
- for (max = MAXBITS; max >= 1; max--)
- if (count[max] != 0) break;
- if (root > max) root = max;
- if (max == 0) { /* no symbols to code at all */
- here.op = (unsigned char)64; /* invalid code marker */
- here.bits = (unsigned char)1;
- here.val = (unsigned short)0;
- *(*table)++ = here; /* make a table to force an error */
- *(*table)++ = here;
- *bits = 1;
- return 0; /* no symbols, but wait for decoding to report error */
- }
- for (min = 1; min < max; min++)
- if (count[min] != 0) break;
- if (root < min) root = min;
-
- /* check for an over-subscribed or incomplete set of lengths */
- left = 1;
- for (len = 1; len <= MAXBITS; len++) {
- left <<= 1;
- left -= count[len];
- if (left < 0) return -1; /* over-subscribed */
- }
- if (left > 0 && (type == CODES || max != 1))
- return -1; /* incomplete set */
-
- /* generate offsets into symbol table for each length for sorting */
- offs[1] = 0;
- for (len = 1; len < MAXBITS; len++)
- offs[len + 1] = offs[len] + count[len];
-
- /* sort symbols by length, by symbol order within each length */
- for (sym = 0; sym < codes; sym++)
- if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
-
- /*
- Create and fill in decoding tables. In this loop, the table being
- filled is at next and has curr index bits. The code being used is huff
- with length len. That code is converted to an index by dropping drop
- bits off of the bottom. For codes where len is less than drop + curr,
- those top drop + curr - len bits are incremented through all values to
- fill the table with replicated entries.
-
- root is the number of index bits for the root table. When len exceeds
- root, sub-tables are created pointed to by the root entry with an index
- of the low root bits of huff. This is saved in low to check for when a
- new sub-table should be started. drop is zero when the root table is
- being filled, and drop is root when sub-tables are being filled.
-
- When a new sub-table is needed, it is necessary to look ahead in the
- code lengths to determine what size sub-table is needed. The length
- counts are used for this, and so count[] is decremented as codes are
- entered in the tables.
-
- used keeps track of how many table entries have been allocated from the
- provided *table space. It is checked for LENS and DIST tables against
- the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
- the initial root table size constants. See the comments in inftrees.h
- for more information.
-
- sym increments through all symbols, and the loop terminates when
- all codes of length max, i.e. all codes, have been processed. This
- routine permits incomplete codes, so another loop after this one fills
- in the rest of the decoding tables with invalid code markers.
- */
-
- /* set up for code type */
- switch (type) {
- case CODES:
- base = extra = work; /* dummy value--not used */
- end = 19;
- break;
- case LENS:
- base = lbase;
- base -= 257;
- extra = lext;
- extra -= 257;
- end = 256;
- break;
- default: /* DISTS */
- base = dbase;
- extra = dext;
- end = -1;
- }
-
- /* initialize state for loop */
- huff = 0; /* starting code */
- sym = 0; /* starting code symbol */
- len = min; /* starting code length */
- next = *table; /* current table to fill in */
- curr = root; /* current table index bits */
- drop = 0; /* current bits to drop from code for index */
- low = (unsigned)(-1); /* trigger new sub-table when len > root */
- used = 1U << root; /* use root table entries */
- mask = used - 1; /* mask for comparing low */
-
- /* check available table space */
- if ((type == LENS && used >= ENOUGH_LENS) ||
- (type == DISTS && used >= ENOUGH_DISTS))
- return 1;
-
- /* process all codes and make table entries */
- for (;;) {
- /* create table entry */
- here.bits = (unsigned char)(len - drop);
- if ((int)(work[sym]) < end) {
- here.op = (unsigned char)0;
- here.val = work[sym];
- }
- else if ((int)(work[sym]) > end) {
- here.op = (unsigned char)(extra[work[sym]]);
- here.val = base[work[sym]];
- }
- else {
- here.op = (unsigned char)(32 + 64); /* end of block */
- here.val = 0;
- }
-
- /* replicate for those indices with low len bits equal to huff */
- incr = 1U << (len - drop);
- fill = 1U << curr;
- min = fill; /* save offset to next table */
- do {
- fill -= incr;
- next[(huff >> drop) + fill] = here;
- } while (fill != 0);
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
-
- /* go to next symbol, update count, len */
- sym++;
- if (--(count[len]) == 0) {
- if (len == max) break;
- len = lens[work[sym]];
- }
-
- /* create new sub-table if needed */
- if (len > root && (huff & mask) != low) {
- /* if first time, transition to sub-tables */
- if (drop == 0)
- drop = root;
-
- /* increment past last table */
- next += min; /* here min is 1 << curr */
-
- /* determine length of next table */
- curr = len - drop;
- left = (int)(1 << curr);
- while (curr + drop < max) {
- left -= count[curr + drop];
- if (left <= 0) break;
- curr++;
- left <<= 1;
- }
-
- /* check for enough space */
- used += 1U << curr;
- if ((type == LENS && used >= ENOUGH_LENS) ||
- (type == DISTS && used >= ENOUGH_DISTS))
- return 1;
-
- /* point entry in root table to sub-table */
- low = huff & mask;
- (*table)[low].op = (unsigned char)curr;
- (*table)[low].bits = (unsigned char)root;
- (*table)[low].val = (unsigned short)(next - *table);
- }
- }
-
- /*
- Fill in rest of table for incomplete codes. This loop is similar to the
- loop above in incrementing huff for table indices. It is assumed that
- len is equal to curr + drop, so there is no loop needed to increment
- through high index bits. When the current sub-table is filled, the loop
- drops back to the root table to fill in any remaining entries there.
- */
- here.op = (unsigned char)64; /* invalid code marker */
- here.bits = (unsigned char)(len - drop);
- here.val = (unsigned short)0;
- while (huff != 0) {
- /* when done with sub-table, drop back to root table */
- if (drop != 0 && (huff & mask) != low) {
- drop = 0;
- len = root;
- next = *table;
- here.bits = (unsigned char)len;
- }
-
- /* put invalid code marker in table */
- next[huff >> drop] = here;
-
- /* backwards increment the len-bit code huff */
- incr = 1U << (len - 1);
- while (huff & incr)
- incr >>= 1;
- if (incr != 0) {
- huff &= incr - 1;
- huff += incr;
- }
- else
- huff = 0;
- }
-
- /* set return parameters */
- *table += used;
- *bits = root;
- return 0;
-}
diff --git a/security/nss/lib/zlib/inftrees.h b/security/nss/lib/zlib/inftrees.h
deleted file mode 100644
index baa53a0b1..000000000
--- a/security/nss/lib/zlib/inftrees.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2005, 2010 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* Structure for decoding tables. Each entry provides either the
- information needed to do the operation requested by the code that
- indexed that table entry, or it provides a pointer to another
- table that indexes more bits of the code. op indicates whether
- the entry is a pointer to another table, a literal, a length or
- distance, an end-of-block, or an invalid code. For a table
- pointer, the low four bits of op is the number of index bits of
- that table. For a length or distance, the low four bits of op
- is the number of extra bits to get after the code. bits is
- the number of bits in this code or part of the code to drop off
- of the bit buffer. val is the actual byte to output in the case
- of a literal, the base length or distance, or the offset from
- the current table to the next table. Each entry is four bytes. */
-typedef struct {
- unsigned char op; /* operation, extra bits, table bits */
- unsigned char bits; /* bits in this part of the code */
- unsigned short val; /* offset in table or code value */
-} code;
-
-/* op values as set by inflate_table():
- 00000000 - literal
- 0000tttt - table link, tttt != 0 is the number of table index bits
- 0001eeee - length or distance, eeee is the number of extra bits
- 01100000 - end of block
- 01000000 - invalid code
- */
-
-/* Maximum size of the dynamic table. The maximum number of code structures is
- 1444, which is the sum of 852 for literal/length codes and 592 for distance
- codes. These values were found by exhaustive searches using the program
- examples/enough.c found in the zlib distribtution. The arguments to that
- program are the number of symbols, the initial root table size, and the
- maximum bit length of a code. "enough 286 9 15" for literal/length codes
- returns returns 852, and "enough 30 6 15" for distance codes returns 592.
- The initial root table size (9 or 6) is found in the fifth argument of the
- inflate_table() calls in inflate.c and infback.c. If the root table size is
- changed, then these maximum sizes would be need to be recalculated and
- updated. */
-#define ENOUGH_LENS 852
-#define ENOUGH_DISTS 592
-#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
-
-/* Type of code to build for inflate_table() */
-typedef enum {
- CODES,
- LENS,
- DISTS
-} codetype;
-
-int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
- unsigned codes, code FAR * FAR *table,
- unsigned FAR *bits, unsigned short FAR *work));
diff --git a/security/nss/lib/zlib/manifest.mn b/security/nss/lib/zlib/manifest.mn
deleted file mode 100644
index 5e75ac0f8..000000000
--- a/security/nss/lib/zlib/manifest.mn
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-CORE_DEPTH = ../../..
-
-MODULE = nss
-
-PRIVATE_EXPORTS = zlib.h zconf.h
-
-CSRCS = adler32.c \
- compress.c \
- crc32.c \
- deflate.c \
- gzclose.c \
- gzlib.c \
- gzread.c \
- gzwrite.c \
- infback.c \
- inffast.c \
- inflate.c \
- inftrees.c \
- trees.c \
- uncompr.c \
- zutil.c \
- $(NULL)
-
-LIBRARY_NAME = zlib
-
-PROGRAMS = example minigzip
-
-# REQUIRES = nss
-
-# Define verbose as -1 to turn off all zlib trace messages in
-# debug builds.
-DEFINES = -Dverbose=-1
-
-NO_MD_RELEASE = 1
diff --git a/security/nss/lib/zlib/minigzip.c b/security/nss/lib/zlib/minigzip.c
deleted file mode 100644
index 9825ccc3a..000000000
--- a/security/nss/lib/zlib/minigzip.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/* minigzip.c -- simulate gzip using the zlib compression library
- * Copyright (C) 1995-2006, 2010 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * minigzip is a minimal implementation of the gzip utility. This is
- * only an example of using zlib and isn't meant to replace the
- * full-featured gzip. No attempt is made to deal with file systems
- * limiting names to 14 or 8+3 characters, etc... Error checking is
- * very limited. So use minigzip only for testing; use gzip for the
- * real thing. On MSDOS, use only on file names without extension
- * or in pipe mode.
- */
-
-/* @(#) $Id$ */
-
-#include "zlib.h"
-#include <stdio.h>
-
-#ifdef STDC
-# include <string.h>
-# include <stdlib.h>
-#endif
-
-#ifdef USE_MMAP
-# include <sys/types.h>
-# include <sys/mman.h>
-# include <sys/stat.h>
-#endif
-
-#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
-# include <fcntl.h>
-# include <io.h>
-# ifdef UNDER_CE
-# include <stdlib.h>
-# endif
-# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-
-#ifdef VMS
-# define unlink delete
-# define GZ_SUFFIX "-gz"
-#endif
-#ifdef RISCOS
-# define unlink remove
-# define GZ_SUFFIX "-gz"
-# define fileno(file) file->__file
-#endif
-#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fileno */
-#endif
-
-#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
-#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
- extern int unlink OF((const char *));
-#endif
-#endif
-
-#if defined(UNDER_CE)
-# include <windows.h>
-# define perror(s) pwinerror(s)
-
-/* Map the Windows error number in ERROR to a locale-dependent error
- message string and return a pointer to it. Typically, the values
- for ERROR come from GetLastError.
-
- The string pointed to shall not be modified by the application,
- but may be overwritten by a subsequent call to strwinerror
-
- The strwinerror function does not change the current setting
- of GetLastError. */
-
-static char *strwinerror (error)
- DWORD error;
-{
- static char buf[1024];
-
- wchar_t *msgbuf;
- DWORD lasterr = GetLastError();
- DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
- | FORMAT_MESSAGE_ALLOCATE_BUFFER,
- NULL,
- error,
- 0, /* Default language */
- (LPVOID)&msgbuf,
- 0,
- NULL);
- if (chars != 0) {
- /* If there is an \r\n appended, zap it. */
- if (chars >= 2
- && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
- chars -= 2;
- msgbuf[chars] = 0;
- }
-
- if (chars > sizeof (buf) - 1) {
- chars = sizeof (buf) - 1;
- msgbuf[chars] = 0;
- }
-
- wcstombs(buf, msgbuf, chars + 1);
- LocalFree(msgbuf);
- }
- else {
- sprintf(buf, "unknown win32 error (%ld)", error);
- }
-
- SetLastError(lasterr);
- return buf;
-}
-
-static void pwinerror (s)
- const char *s;
-{
- if (s && *s)
- fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
- else
- fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
-}
-
-#endif /* UNDER_CE */
-
-#ifndef GZ_SUFFIX
-# define GZ_SUFFIX ".gz"
-#endif
-#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
-
-#define BUFLEN 16384
-#define MAX_NAME_LEN 1024
-
-#ifdef MAXSEG_64K
-# define local static
- /* Needed for systems with limitation on stack size. */
-#else
-# define local
-#endif
-
-char *prog;
-
-void error OF((const char *msg));
-void gz_compress OF((FILE *in, gzFile out));
-#ifdef USE_MMAP
-int gz_compress_mmap OF((FILE *in, gzFile out));
-#endif
-void gz_uncompress OF((gzFile in, FILE *out));
-void file_compress OF((char *file, char *mode));
-void file_uncompress OF((char *file));
-int main OF((int argc, char *argv[]));
-
-/* ===========================================================================
- * Display error message and exit
- */
-void error(msg)
- const char *msg;
-{
- fprintf(stderr, "%s: %s\n", prog, msg);
- exit(1);
-}
-
-/* ===========================================================================
- * Compress input to output then close both files.
- */
-
-void gz_compress(in, out)
- FILE *in;
- gzFile out;
-{
- local char buf[BUFLEN];
- int len;
- int err;
-
-#ifdef USE_MMAP
- /* Try first compressing with mmap. If mmap fails (minigzip used in a
- * pipe), use the normal fread loop.
- */
- if (gz_compress_mmap(in, out) == Z_OK) return;
-#endif
- for (;;) {
- len = (int)fread(buf, 1, sizeof(buf), in);
- if (ferror(in)) {
- perror("fread");
- exit(1);
- }
- if (len == 0) break;
-
- if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
- }
- fclose(in);
- if (gzclose(out) != Z_OK) error("failed gzclose");
-}
-
-#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
-
-/* Try compressing the input file at once using mmap. Return Z_OK if
- * if success, Z_ERRNO otherwise.
- */
-int gz_compress_mmap(in, out)
- FILE *in;
- gzFile out;
-{
- int len;
- int err;
- int ifd = fileno(in);
- caddr_t buf; /* mmap'ed buffer for the entire input file */
- off_t buf_len; /* length of the input file */
- struct stat sb;
-
- /* Determine the size of the file, needed for mmap: */
- if (fstat(ifd, &sb) < 0) return Z_ERRNO;
- buf_len = sb.st_size;
- if (buf_len <= 0) return Z_ERRNO;
-
- /* Now do the actual mmap: */
- buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
- if (buf == (caddr_t)(-1)) return Z_ERRNO;
-
- /* Compress the whole file at once: */
- len = gzwrite(out, (char *)buf, (unsigned)buf_len);
-
- if (len != (int)buf_len) error(gzerror(out, &err));
-
- munmap(buf, buf_len);
- fclose(in);
- if (gzclose(out) != Z_OK) error("failed gzclose");
- return Z_OK;
-}
-#endif /* USE_MMAP */
-
-/* ===========================================================================
- * Uncompress input to output then close both files.
- */
-void gz_uncompress(in, out)
- gzFile in;
- FILE *out;
-{
- local char buf[BUFLEN];
- int len;
- int err;
-
- for (;;) {
- len = gzread(in, buf, sizeof(buf));
- if (len < 0) error (gzerror(in, &err));
- if (len == 0) break;
-
- if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
- error("failed fwrite");
- }
- }
- if (fclose(out)) error("failed fclose");
-
- if (gzclose(in) != Z_OK) error("failed gzclose");
-}
-
-
-/* ===========================================================================
- * Compress the given file: create a corresponding .gz file and remove the
- * original.
- */
-void file_compress(file, mode)
- char *file;
- char *mode;
-{
- local char outfile[MAX_NAME_LEN];
- FILE *in;
- gzFile out;
-
- if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
- fprintf(stderr, "%s: filename too long\n", prog);
- exit(1);
- }
-
- strcpy(outfile, file);
- strcat(outfile, GZ_SUFFIX);
-
- in = fopen(file, "rb");
- if (in == NULL) {
- perror(file);
- exit(1);
- }
- out = gzopen(outfile, mode);
- if (out == NULL) {
- fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
- exit(1);
- }
- gz_compress(in, out);
-
- unlink(file);
-}
-
-
-/* ===========================================================================
- * Uncompress the given file and remove the original.
- */
-void file_uncompress(file)
- char *file;
-{
- local char buf[MAX_NAME_LEN];
- char *infile, *outfile;
- FILE *out;
- gzFile in;
- size_t len = strlen(file);
-
- if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
- fprintf(stderr, "%s: filename too long\n", prog);
- exit(1);
- }
-
- strcpy(buf, file);
-
- if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
- infile = file;
- outfile = buf;
- outfile[len-3] = '\0';
- } else {
- outfile = file;
- infile = buf;
- strcat(infile, GZ_SUFFIX);
- }
- in = gzopen(infile, "rb");
- if (in == NULL) {
- fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
- exit(1);
- }
- out = fopen(outfile, "wb");
- if (out == NULL) {
- perror(file);
- exit(1);
- }
-
- gz_uncompress(in, out);
-
- unlink(infile);
-}
-
-
-/* ===========================================================================
- * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
- * -c : write to standard output
- * -d : decompress
- * -f : compress with Z_FILTERED
- * -h : compress with Z_HUFFMAN_ONLY
- * -r : compress with Z_RLE
- * -1 to -9 : compression level
- */
-
-int main(argc, argv)
- int argc;
- char *argv[];
-{
- int copyout = 0;
- int uncompr = 0;
- gzFile file;
- char *bname, outmode[20];
-
- strcpy(outmode, "wb6 ");
-
- prog = argv[0];
- bname = strrchr(argv[0], '/');
- if (bname)
- bname++;
- else
- bname = argv[0];
- argc--, argv++;
-
- if (!strcmp(bname, "gunzip"))
- uncompr = 1;
- else if (!strcmp(bname, "zcat"))
- copyout = uncompr = 1;
-
- while (argc > 0) {
- if (strcmp(*argv, "-c") == 0)
- copyout = 1;
- else if (strcmp(*argv, "-d") == 0)
- uncompr = 1;
- else if (strcmp(*argv, "-f") == 0)
- outmode[3] = 'f';
- else if (strcmp(*argv, "-h") == 0)
- outmode[3] = 'h';
- else if (strcmp(*argv, "-r") == 0)
- outmode[3] = 'R';
- else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
- (*argv)[2] == 0)
- outmode[2] = (*argv)[1];
- else
- break;
- argc--, argv++;
- }
- if (outmode[3] == ' ')
- outmode[3] = 0;
- if (argc == 0) {
- SET_BINARY_MODE(stdin);
- SET_BINARY_MODE(stdout);
- if (uncompr) {
- file = gzdopen(fileno(stdin), "rb");
- if (file == NULL) error("can't gzdopen stdin");
- gz_uncompress(file, stdout);
- } else {
- file = gzdopen(fileno(stdout), outmode);
- if (file == NULL) error("can't gzdopen stdout");
- gz_compress(stdin, file);
- }
- } else {
- if (copyout) {
- SET_BINARY_MODE(stdout);
- }
- do {
- if (uncompr) {
- if (copyout) {
- file = gzopen(*argv, "rb");
- if (file == NULL)
- fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
- else
- gz_uncompress(file, stdout);
- } else {
- file_uncompress(*argv);
- }
- } else {
- if (copyout) {
- FILE * in = fopen(*argv, "rb");
-
- if (in == NULL) {
- perror(*argv);
- } else {
- file = gzdopen(fileno(stdout), outmode);
- if (file == NULL) error("can't gzdopen stdout");
-
- gz_compress(in, file);
- }
-
- } else {
- file_compress(*argv, outmode);
- }
- }
- } while (argv++, --argc);
- }
- return 0;
-}
diff --git a/security/nss/lib/zlib/patches/msvc-vsnprintf.patch b/security/nss/lib/zlib/patches/msvc-vsnprintf.patch
deleted file mode 100644
index 2b8d2a646..000000000
--- a/security/nss/lib/zlib/patches/msvc-vsnprintf.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- zlib-1.2.5/zutil.h 2010-04-18 12:29:24 -0700
-+++ zlib/zutil.h 2010-08-21 18:07:03 -0700
-@@ -172,17 +172,18 @@
- #endif
-
- #ifndef F_OPEN
- # define F_OPEN(name, mode) fopen((name), (mode))
- #endif
-
- /* functions */
-
--#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
-+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) || \
-+ (defined(_MSC_VER) && _MSC_VER >= 1500)
- # ifndef HAVE_VSNPRINTF
- # define HAVE_VSNPRINTF
- # endif
- #endif
- #if defined(__CYGWIN__)
- # ifndef HAVE_VSNPRINTF
- # define HAVE_VSNPRINTF
- # endif
diff --git a/security/nss/lib/zlib/patches/prune-zlib.sh b/security/nss/lib/zlib/patches/prune-zlib.sh
deleted file mode 100644
index 6a742fb4d..000000000
--- a/security/nss/lib/zlib/patches/prune-zlib.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-files_to_remove="
-CMakeLists.txt
-ChangeLog
-FAQ
-INDEX
-Makefile
-Makefile.in
-amiga
-configure
-contrib
-doc
-examples
-make_vms.com
-msdos
-nintendods
-old
-qnx
-treebuild.xml
-watcom
-win32
-zconf.h.cmakein
-zconf.h.in
-zlib.3
-zlib.3.pdf
-zlib.map
-zlib.pc.in
-zlib2ansi
-"
-
-rm -rf $files_to_remove
diff --git a/security/nss/lib/zlib/trees.c b/security/nss/lib/zlib/trees.c
deleted file mode 100644
index 56e9bb1c1..000000000
--- a/security/nss/lib/zlib/trees.c
+++ /dev/null
@@ -1,1244 +0,0 @@
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2010 Jean-loup Gailly
- * detect_data_type() function provided freely by Cosmin Truta, 2006
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process uses several Huffman trees. The more
- * common source values are represented by shorter bit sequences.
- *
- * Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values). The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- * Storer, James A.
- * Data Compression: Methods and Theory, pp. 49-50.
- * Computer Science Press, 1988. ISBN 0-7167-8156-5.
- *
- * Sedgewick, R.
- * Algorithms, p290.
- * Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* @(#) $Id$ */
-
-/* #define GEN_TREES_H */
-
-#include "deflate.h"
-
-#ifdef DEBUG
-# include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6 16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10 17
-/* repeat a zero length 3-10 times (3 bits of repeat count) */
-
-#define REPZ_11_138 18
-/* repeat a zero length 11-138 times (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
-/* non ANSI compilers may not accept trees.h */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-uch _dist_code[DIST_CODE_LEN];
-/* Distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-#else
-# include "trees.h"
-#endif /* GEN_TREES_H */
-
-struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
-};
-
-local static_tree_desc static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc static_d_desc =
-{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
-local static_tree_desc static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block OF((deflate_state *s));
-local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree OF((deflate_state *s, tree_desc *desc));
-local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local int build_bl_tree OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local int detect_data_type OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup OF((deflate_state *s));
-local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-# define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
- deflate_state *s;
- int value; /* value to send */
- int length; /* number of bits */
-{
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- /* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
- * unused bits in value.
- */
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (ush)value << s->bi_valid;
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= (ush)value << s->bi_valid;
- s->bi_valid += length;
- }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (ush)val << s->bi_valid;\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (ush)(value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
-}
-#endif /* DEBUG */
-
-
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
-#if defined(GEN_TREES_H) || !defined(STDC)
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
-#ifdef NO_INIT_GLOBAL_POINTERS
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-#endif
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- /* Note that the length 255 (match length 258) can be represented
- * in two different ways: code 284 + 5 bits or code 285, so we
- * overwrite length_code[255] to use the best encoding:
- */
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- /* Codes 286 and 287 do not exist, but we must include them in the
- * tree construction to get a canonical Huffman tree (longest code
- * all ones)
- */
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
-# ifdef GEN_TREES_H
- gen_trees_header();
-# endif
-#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-}
-
-/* ===========================================================================
- * Genererate the file trees.h describing the static trees.
- */
-#ifdef GEN_TREES_H
-# ifndef DEBUG
-# include <stdio.h>
-# endif
-
-# define SEPARATOR(i, last, width) \
- ((i) == (last)? "\n};\n\n" : \
- ((i) % (width) == (width)-1 ? ",\n" : ", "))
-
-void gen_trees_header()
-{
- FILE *header = fopen("trees.h", "w");
- int i;
-
- Assert (header != NULL, "Can't open trees.h");
- fprintf(header,
- "/* header created automatically with -DGEN_TREES_H */\n\n");
-
- fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
- for (i = 0; i < L_CODES+2; i++) {
- fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
- static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
- }
-
- fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
- static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
- }
-
- fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
- for (i = 0; i < DIST_CODE_LEN; i++) {
- fprintf(header, "%2u%s", _dist_code[i],
- SEPARATOR(i, DIST_CODE_LEN-1, 20));
- }
-
- fprintf(header,
- "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
- for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
- fprintf(header, "%2u%s", _length_code[i],
- SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
- }
-
- fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
- for (i = 0; i < LENGTH_CODES; i++) {
- fprintf(header, "%1u%s", base_length[i],
- SEPARATOR(i, LENGTH_CODES-1, 20));
- }
-
- fprintf(header, "local const int base_dist[D_CODES] = {\n");
- for (i = 0; i < D_CODES; i++) {
- fprintf(header, "%5u%s", base_dist[i],
- SEPARATOR(i, D_CODES-1, 10));
- }
-
- fclose(header);
-}
-#endif /* GEN_TREES_H */
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void ZLIB_INTERNAL _tr_init(s)
- deflate_state *s;
-{
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
-#endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
- deflate_state *s;
-{
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
- deflate_state *s;
- ct_data *tree; /* the tree to restore */
- int k; /* node to move down */
-{
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- * above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- * array bl_count contains the frequencies for each bit length.
- * The length opt_len is updated; static_len is also updated if stree is
- * not null.
- */
-local void gen_bitlen(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- /* In a first pass, compute the optimal bit lengths (which may
- * overflow in the case of the bit length tree).
- */
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- /* This happens for example on obj2 and pic of the Calgary corpus */
-
- /* Find the first bit length which could increase: */
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- /* The brother of the overflow item also moves one step up,
- * but this does not affect bl_count[max_length]
- */
- overflow -= 2;
- } while (overflow > 0);
-
- /* Now recompute all bit lengths, scanning in increasing frequency.
- * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
- * lengths instead of fixing only the wrong ones. This idea is taken
- * from 'ar' written by Haruhiko Okumura.)
- */
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if ((unsigned) tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- * zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
- ct_data *tree; /* the tree to decorate */
- int max_code; /* largest code with non zero frequency */
- ushf *bl_count; /* number of codes at each bit length */
-{
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- /* The distribution counts are first used to generate the code values
- * without bit reversal.
- */
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- /* Check that the bit counts in bl_count are consistent. The last code
- * must be all ones.
- */
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- * and corresponding code. The length opt_len is updated; static_len is
- * also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- /* Construct the initial heap, with least frequent element in
- * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
- * heap[0] is not used.
- */
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
-
- /* The pkzip format requires that at least one distance code exists,
- * and that at least one bit should be sent even if there is only one
- * possible code. So to avoid special checks later on we force at least
- * two codes of non zero frequency.
- */
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
- * establish sub-heaps of increasing lengths:
- */
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- /* Construct the Huffman tree by repeatedly combining the least two
- * frequent nodes.
- */
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
- s->depth[n] : s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
-#endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- /* At this point, the fields freq and dad are set. We can now
- * generate the bit lengths.
- */
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
- deflate_state *s;
-{
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- /* opt_len now includes the length of the tree representations, except
- * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
- */
-
- /* Determine the number of bit length codes to send. The pkzip format
- * requires that at least 4 bit length codes be sent. (appnote.txt says
- * 3 but the actual value used is 4.)
- */
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
- deflate_state *s;
- int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
- deflate_state *s;
- charf *buf; /* input block */
- ulg stored_len; /* length of input block */
- int last; /* one if this is the last block for a file */
-{
- send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
-#ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
-#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void ZLIB_INTERNAL _tr_align(s)
- deflate_state *s;
-{
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
- bi_flush(s);
- /* Of the 10 bits for the empty block, we have already sent
- * (10 - bi_valid) bits. The lookahead for the last real code (before
- * the EOB of the previous block) was thus at least one plus the length
- * of the EOB plus what we have just sent of the empty static block.
- */
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file.
- */
-void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
- deflate_state *s;
- charf *buf; /* input block, or NULL if too old */
- ulg stored_len; /* length of input block */
- int last; /* one if this is the last block for a file */
-{
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Check if the file is binary or text */
- if (s->strm->data_type == Z_UNKNOWN)
- s->strm->data_type = detect_data_type(s);
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- /* At this point, opt_len and static_len are the total bit lengths of
- * the compressed block data, excluding the tree representations.
- */
-
- /* Build the bit length tree for the above two trees, and get the index
- * in bl_order of the last bit length code to send.
- */
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute the block lengths in bytes. */
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
-#ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
-#else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
-#endif
- /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
- * Otherwise we can't have processed more than WSIZE input bytes since
- * the last block flush, because compression would have been
- * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- * transform a block into a stored block.
- */
- _tr_stored_block(s, buf, stored_len, last);
-
-#ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
-#else
- } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
-#endif
- send_bits(s, (STATIC_TREES<<1)+last, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
-#endif
- } else {
- send_bits(s, (DYN_TREES<<1)+last, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
-#endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
- /* The above check is made mod 2^32, for files larger than 512 MB
- * and uLong implemented on 32 bits.
- */
- init_block(s);
-
- if (last) {
- bi_windup(s);
-#ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
-#endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*last));
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int ZLIB_INTERNAL _tr_tally (s, dist, lc)
- deflate_state *s;
- unsigned dist; /* distance of matched string */
- unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
- /* We avoid equality with lit_bufsize because of wraparound at 64K
- * on 16 bit machines and because stored blocks are restricted to
- * 64K-1 bytes.
- */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
- deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
-{
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
- "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Check if the data type is TEXT or BINARY, using the following algorithm:
- * - TEXT if the two conditions below are satisfied:
- * a) There are no non-portable control characters belonging to the
- * "black list" (0..6, 14..25, 28..31).
- * b) There is at least one printable character belonging to the
- * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
- * - BINARY otherwise.
- * - The following partially-portable control characters form a
- * "gray list" that is ignored in this detection algorithm:
- * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
- * IN assertion: the fields Freq of dyn_ltree are set.
- */
-local int detect_data_type(s)
- deflate_state *s;
-{
- /* black_mask is the bit mask of black-listed bytes
- * set bits 0..6, 14..25, and 28..31
- * 0xf3ffc07f = binary 11110011111111111100000001111111
- */
- unsigned long black_mask = 0xf3ffc07fUL;
- int n;
-
- /* Check for non-textual ("black-listed") bytes. */
- for (n = 0; n <= 31; n++, black_mask >>= 1)
- if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
- return Z_BINARY;
-
- /* Check for textual ("white-listed") bytes. */
- if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
- || s->dyn_ltree[13].Freq != 0)
- return Z_TEXT;
- for (n = 32; n < LITERALS; n++)
- if (s->dyn_ltree[n].Freq != 0)
- return Z_TEXT;
-
- /* There are no "black-listed" or "white-listed" bytes:
- * this stream either is empty or has tolerated ("gray-listed") bytes only.
- */
- return Z_BINARY;
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
- unsigned code; /* the value to invert */
- int len; /* its bit length */
-{
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
- deflate_state *s;
-{
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
- deflate_state *s;
-{
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
-#ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
- put_short(s, (ush)~len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
diff --git a/security/nss/lib/zlib/trees.h b/security/nss/lib/zlib/trees.h
deleted file mode 100644
index d0868d9f2..000000000
--- a/security/nss/lib/zlib/trees.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* header created automatically with -DGEN_TREES_H */
-
-local const ct_data static_ltree[L_CODES+2] = {
-{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-};
-
-local const ct_data static_dtree[D_CODES] = {
-{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-};
-
-const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
- 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-};
-
-const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-};
-
-local const int base_length[LENGTH_CODES] = {
-0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-64, 80, 96, 112, 128, 160, 192, 224, 0
-};
-
-local const int base_dist[D_CODES] = {
- 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
- 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
- 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-};
-
diff --git a/security/nss/lib/zlib/uncompr.c b/security/nss/lib/zlib/uncompr.c
deleted file mode 100644
index ad98be3a5..000000000
--- a/security/nss/lib/zlib/uncompr.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define ZLIB_INTERNAL
-#include "zlib.h"
-
-/* ===========================================================================
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-int ZEXPORT uncompress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
-
- err = inflateInit(&stream);
- if (err != Z_OK) return err;
-
- err = inflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- inflateEnd(&stream);
- if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
- return Z_DATA_ERROR;
- return err;
- }
- *destLen = stream.total_out;
-
- err = inflateEnd(&stream);
- return err;
-}
diff --git a/security/nss/lib/zlib/zconf.h b/security/nss/lib/zlib/zconf.h
deleted file mode 100644
index 02ce56c43..000000000
--- a/security/nss/lib/zlib/zconf.h
+++ /dev/null
@@ -1,428 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2010 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- * Even better than compiling with -DZ_PREFIX would be to use configure to set
- * this permanently in zconf.h using "./configure --zprefix".
- */
-#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
-
-/* all linked symbols */
-# define _dist_code z__dist_code
-# define _length_code z__length_code
-# define _tr_align z__tr_align
-# define _tr_flush_block z__tr_flush_block
-# define _tr_init z__tr_init
-# define _tr_stored_block z__tr_stored_block
-# define _tr_tally z__tr_tally
-# define adler32 z_adler32
-# define adler32_combine z_adler32_combine
-# define adler32_combine64 z_adler32_combine64
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
-# define crc32 z_crc32
-# define crc32_combine z_crc32_combine
-# define crc32_combine64 z_crc32_combine64
-# define deflate z_deflate
-# define deflateBound z_deflateBound
-# define deflateCopy z_deflateCopy
-# define deflateEnd z_deflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateInit_ z_deflateInit_
-# define deflateParams z_deflateParams
-# define deflatePrime z_deflatePrime
-# define deflateReset z_deflateReset
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateSetHeader z_deflateSetHeader
-# define deflateTune z_deflateTune
-# define deflate_copyright z_deflate_copyright
-# define get_crc_table z_get_crc_table
-# define gz_error z_gz_error
-# define gz_intmax z_gz_intmax
-# define gz_strwinerror z_gz_strwinerror
-# define gzbuffer z_gzbuffer
-# define gzclearerr z_gzclearerr
-# define gzclose z_gzclose
-# define gzclose_r z_gzclose_r
-# define gzclose_w z_gzclose_w
-# define gzdirect z_gzdirect
-# define gzdopen z_gzdopen
-# define gzeof z_gzeof
-# define gzerror z_gzerror
-# define gzflush z_gzflush
-# define gzgetc z_gzgetc
-# define gzgets z_gzgets
-# define gzoffset z_gzoffset
-# define gzoffset64 z_gzoffset64
-# define gzopen z_gzopen
-# define gzopen64 z_gzopen64
-# define gzprintf z_gzprintf
-# define gzputc z_gzputc
-# define gzputs z_gzputs
-# define gzread z_gzread
-# define gzrewind z_gzrewind
-# define gzseek z_gzseek
-# define gzseek64 z_gzseek64
-# define gzsetparams z_gzsetparams
-# define gztell z_gztell
-# define gztell64 z_gztell64
-# define gzungetc z_gzungetc
-# define gzwrite z_gzwrite
-# define inflate z_inflate
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define inflateBackInit_ z_inflateBackInit_
-# define inflateCopy z_inflateCopy
-# define inflateEnd z_inflateEnd
-# define inflateGetHeader z_inflateGetHeader
-# define inflateInit2_ z_inflateInit2_
-# define inflateInit_ z_inflateInit_
-# define inflateMark z_inflateMark
-# define inflatePrime z_inflatePrime
-# define inflateReset z_inflateReset
-# define inflateReset2 z_inflateReset2
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateUndermine z_inflateUndermine
-# define inflate_copyright z_inflate_copyright
-# define inflate_fast z_inflate_fast
-# define inflate_table z_inflate_table
-# define uncompress z_uncompress
-# define zError z_zError
-# define zcalloc z_zcalloc
-# define zcfree z_zcfree
-# define zlibCompileFlags z_zlibCompileFlags
-# define zlibVersion z_zlibVersion
-
-/* all zlib typedefs in zlib.h and zconf.h */
-# define Byte z_Byte
-# define Bytef z_Bytef
-# define alloc_func z_alloc_func
-# define charf z_charf
-# define free_func z_free_func
-# define gzFile z_gzFile
-# define gz_header z_gz_header
-# define gz_headerp z_gz_headerp
-# define in_func z_in_func
-# define intf z_intf
-# define out_func z_out_func
-# define uInt z_uInt
-# define uIntf z_uIntf
-# define uLong z_uLong
-# define uLongf z_uLongf
-# define voidp z_voidp
-# define voidpc z_voidpc
-# define voidpf z_voidpf
-
-/* all zlib structs in zlib.h and zconf.h */
-# define gz_header_s z_gz_header_s
-# define internal_state z_internal_state
-
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-# define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-# define WINDOWS
-#endif
-#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
-# ifndef WIN32
-# define WIN32
-# endif
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-# ifndef SYS16BIT
-# define SYS16BIT
-# endif
-# endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-# ifndef STDC
-# define STDC
-# endif
-# if __STDC_VERSION__ >= 199901L
-# ifndef STDC99
-# define STDC99
-# endif
-# endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
-# define STDC
-#endif
-
-#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const /* note: need a more gentle solution here */
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-# if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-# if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
-# define SMALL_MEDIUM
-# ifdef __BORLANDC__
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
-# ifdef ZLIB_DLL
-# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-# ifdef ZLIB_INTERNAL
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-# endif
-# endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
-# ifdef ZLIB_WINAPI
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR CDECL
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# ifdef ZLIB_DLL
-# ifdef ZLIB_INTERNAL
-# define ZEXPORT __declspec(dllexport)
-# define ZEXPORTVA __declspec(dllexport)
-# else
-# define ZEXPORT __declspec(dllimport)
-# define ZEXPORTVA __declspec(dllimport)
-# endif
-# endif
-#endif
-
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
-# define Z_HAVE_UNISTD_H
-#endif
-
-#ifdef STDC
-# include <sys/types.h> /* for off_t */
-#endif
-
-/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
- * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
- * though the former does not conform to the LFS document), but considering
- * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
- * equivalently requesting no 64-bit operations
- */
-#if -_LARGEFILE64_SOURCE - -1 == 1
-# undef _LARGEFILE64_SOURCE
-#endif
-
-#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# ifndef z_off_t
-# define z_off_t off_t
-# endif
-#endif
-
-#ifndef SEEK_SET
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
-# define z_off64_t off64_t
-#else
-# define z_off64_t z_off_t
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
- #pragma map(deflateInit_,"DEIN")
- #pragma map(deflateInit2_,"DEIN2")
- #pragma map(deflateEnd,"DEEND")
- #pragma map(deflateBound,"DEBND")
- #pragma map(inflateInit_,"ININ")
- #pragma map(inflateInit2_,"ININ2")
- #pragma map(inflateEnd,"INEND")
- #pragma map(inflateSync,"INSY")
- #pragma map(inflateSetDictionary,"INSEDI")
- #pragma map(compressBound,"CMBND")
- #pragma map(inflate_table,"INTABL")
- #pragma map(inflate_fast,"INFA")
- #pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
diff --git a/security/nss/lib/zlib/zlib.h b/security/nss/lib/zlib/zlib.h
deleted file mode 100644
index bfbba83e8..000000000
--- a/security/nss/lib/zlib/zlib.h
+++ /dev/null
@@ -1,1613 +0,0 @@
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.5, April 19th, 2010
-
- Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef ZLIB_H
-#define ZLIB_H
-
-#include "zconf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZLIB_VERSION "1.2.5"
-#define ZLIB_VERNUM 0x1250
-#define ZLIB_VER_MAJOR 1
-#define ZLIB_VER_MINOR 2
-#define ZLIB_VER_REVISION 5
-#define ZLIB_VER_SUBREVISION 0
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed data.
- This version of the library supports only one compression method (deflation)
- but other algorithms will be added later and will have the same stream
- interface.
-
- Compression can be done in a single step if the buffers are large enough,
- or can be done by repeated calls of the compression function. In the latter
- case, the application must provide more input and/or consume the output
- (providing more output space) before each call.
-
- The compressed data format used by default by the in-memory functions is
- the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
- around a deflate stream, which is itself documented in RFC 1951.
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio using the functions that start
- with "gz". The gzip format is different from the zlib format. gzip is a
- gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
-
- This library can optionally read and write gzip streams in memory as well.
-
- The zlib format was designed to be compact and fast for use in memory
- and on communications channels. The gzip format was designed for single-
- file compression on file systems, has a larger header than zlib to maintain
- directory information, and uses a different, slower check method than zlib.
-
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never crash
- even in case of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidpf opaque; /* private data object passed to zalloc and zfree */
-
- int data_type; /* best guess about the data type: binary or text */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
- gzip header information passed to and from zlib routines. See RFC 1952
- for more details on the meanings of these fields.
-*/
-typedef struct gz_header_s {
- int text; /* true if compressed data believed to be text */
- uLong time; /* modification time */
- int xflags; /* extra flags (not used when writing a gzip file) */
- int os; /* operating system */
- Bytef *extra; /* pointer to extra field or Z_NULL if none */
- uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
- uInt extra_max; /* space at extra (only when reading header) */
- Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
- uInt name_max; /* space at name (only when reading header) */
- Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
- uInt comm_max; /* space at comment (only when reading header) */
- int hcrc; /* true if there was or will be a header crc */
- int done; /* true when done reading gzip header (not used
- when writing a gzip file) */
-} gz_header;
-
-typedef gz_header FAR *gz_headerp;
-
-/*
- The application must update next_in and avail_in when avail_in has dropped
- to zero. It must update next_out and avail_out when avail_out has dropped
- to zero. The application must initialize zalloc, zfree and opaque before
- calling the init function. All other fields are set by the compression
- library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, zalloc and zfree must be
- thread safe.
-
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this if
- the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
- returned by zalloc for objects of exactly 65536 bytes *must* have their
- offset normalized to zero. The default allocation function provided by this
- library ensures this (see zutil.c). To reduce memory requirements and avoid
- any allocation of 64K objects, at the expense of compression ratio, compile
- the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or progress
- reports. After compression, total_in holds the total size of the
- uncompressed data and may be saved for use in the decompressor (particularly
- if the decompressor wants to decompress everything in a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-#define Z_BLOCK 5
-#define Z_TREES 6
-/* Allowed flush values; see deflate() and inflate() below for details */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_NEED_DICT 2
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative values
- * are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION 0
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_RLE 3
-#define Z_FIXED 4
-#define Z_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_TEXT 1
-#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field (though see inflate()) */
-
-#define Z_DEFLATED 8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
-
- /* basic functions */
-
-ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is not
- compatible with the zlib.h header file used by the application. This check
- is automatically made by deflateInit and inflateInit.
- */
-
-/*
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller. If
- zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
- allocation functions.
-
- The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at all
- (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
- requests a default compromise between speed and compression (currently
- equivalent to level 6).
-
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if level is not a valid compression level, or
- Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION). msg is set to null
- if there is no error message. deflateInit does not perform any compression:
- this will be done by deflate().
-*/
-
-
-ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-/*
- deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
- some output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. deflate performs one or both of the
- following actions:
-
- - Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in and avail_in are updated and
- processing will resume at this point for the next call of deflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications). Some
- output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming more
- output, and updating avail_in or avail_out accordingly; avail_out should
- never be zero before the call. The application can consume the compressed
- output when it wants, for example when the output buffer is full (avail_out
- == 0), or after each call of deflate(). If deflate returns Z_OK and with
- zero avail_out, it must be called again after making room in the output
- buffer because there might be more output pending.
-
- Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
- decide how much data to accumulate before producing output, in order to
- maximize compression.
-
- If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
- flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In
- particular avail_in is zero after the call if enough output space has been
- provided before the call.) Flushing may degrade compression for some
- compression algorithms and so it should be used only when necessary. This
- completes the current deflate block and follows it with an empty stored block
- that is three bits plus filler bits to the next byte, followed by four bytes
- (00 00 ff ff).
-
- If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
- output buffer, but the output is not aligned to a byte boundary. All of the
- input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
- This completes the current deflate block and follows it with an empty fixed
- codes block that is 10 bits long. This assures that enough bytes are output
- in order for the decompressor to finish the block before the empty fixed code
- block.
-
- If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
- for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
- seven bits of the current block are held to be written as the next byte after
- the next deflate block is completed. In this case, the decompressor may not
- be provided enough bits at this point in order to complete decompression of
- the data provided so far to the compressor. It may need to wait for the next
- block to be emitted. This is for advanced applications that need to control
- the emission of deflate blocks.
-
- If flush is set to Z_FULL_FLUSH, all output is flushed as with
- Z_SYNC_FLUSH, and the compression state is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
- compression.
-
- If deflate returns with avail_out == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- avail_out), until the flush is complete (deflate returns with non-zero
- avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
- avail_out is greater than six to avoid repeated flush markers due to
- avail_out == 0 on return.
-
- If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there was
- enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the stream
- are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least the
- value returned by deflateBound (see below). If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() sets strm->adler to the adler32 checksum of all input read
- so far (that is, total_in bytes).
-
- deflate() may update strm->data_type if it can make a good guess about
- the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect the
- compression algorithm in any manner.
-
- deflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if all input has been
- consumed and all output has been produced (only when flush is set to
- Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
- fatal, and deflate() can be called again with more input and more output
- space to continue compressing.
-*/
-
-
-ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any pending
- output.
-
- deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
- stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case, msg
- may be set but then points to a static string (which must not be
- deallocated).
-*/
-
-
-/*
-ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-
- Initializes the internal stream state for decompression. The fields
- next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the
- exact value depends on the compression method), inflateInit determines the
- compression method from the zlib header and allocates all data structures
- accordingly; otherwise the allocation will be deferred to the first call of
- inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
- use default allocation functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller, or Z_STREAM_ERROR if the parameters are
- invalid, such as a null pointer to the structure. msg is set to null if
- there is no error message. inflateInit does not perform any decompression
- apart from possibly reading the zlib header if present: actual decompression
- will be done by inflate(). (So next_in and avail_in may be modified, but
- next_out and avail_out are unused and unchanged.) The current implementation
- of inflateInit() does not process any header information -- that is deferred
- until inflate() is called.
-*/
-
-
-ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-/*
- inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
- some output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. inflate performs one or both of the
- following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing will
- resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there is
- no more input data or no more space in the output buffer (see below about
- the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming more
- output, and updating the next_* and avail_* values accordingly. The
- application can consume the uncompressed output when it wants, for example
- when the output buffer is full (avail_out == 0), or after each call of
- inflate(). If inflate returns Z_OK and with zero avail_out, it must be
- called again after making room in the output buffer because there might be
- more output pending.
-
- The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
- Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
- output as possible to the output buffer. Z_BLOCK requests that inflate()
- stop if and when it gets to the next deflate block boundary. When decoding
- the zlib or gzip format, this will cause inflate() to return immediately
- after the header and before the first block. When doing a raw inflate,
- inflate() will go ahead and process the first block, and will return when it
- gets to the end of that block, or when it runs out of data.
-
- The Z_BLOCK option assists in appending to or combining deflate streams.
- Also to assist in this, on return inflate() will set strm->data_type to the
- number of unused bits in the last byte taken from strm->next_in, plus 64 if
- inflate() is currently decoding the last block in the deflate stream, plus
- 128 if inflate() returned immediately after decoding an end-of-block code or
- decoding the complete header up to just before the first byte of the deflate
- stream. The end-of-block will not be indicated until all of the uncompressed
- data from that block has been written to strm->next_out. The number of
- unused bits may in general be greater than seven, except when bit 7 of
- data_type is set, in which case the number of unused bits will be less than
- eight. data_type is set as noted here every time inflate() returns for all
- flush options, and so can be used to determine the amount of currently
- consumed input in bits.
-
- The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
- end of each deflate block header is reached, before any actual data in that
- block is decoded. This allows the caller to determine the length of the
- deflate block header for later use in random access within a deflate block.
- 256 is added to the value of strm->data_type when inflate() returns
- immediately after reaching the end of the deflate block header.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step (a
- single call of inflate), the parameter flush should be set to Z_FINISH. In
- this case all pending input is processed and all pending output is flushed;
- avail_out must be large enough to hold all the uncompressed data. (The size
- of the uncompressed data may have been saved by the compressor for this
- purpose.) The next operation on this stream must be inflateEnd to deallocate
- the decompression state. The use of Z_FINISH is never required, but can be
- used to inform inflate that a faster approach may be used for the single
- inflate() call.
-
- In this implementation, inflate() always flushes as much output as
- possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
- is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK or Z_TREES is used.
-
- If a preset dictionary is needed after this call (see inflateSetDictionary
- below), inflate sets strm->adler to the adler32 checksum of the dictionary
- chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
- strm->adler to the adler32 checksum of all output produced so far (that is,
- total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
- below. At the end of the stream, inflate() checks that its computed adler32
- checksum is equal to that saved by the compressor and returns Z_STREAM_END
- only if the checksum is correct.
-
- inflate() can decompress and check either zlib-wrapped or gzip-wrapped
- deflate data. The header type is detected automatically, if requested when
- initializing with inflateInit2(). Any information contained in the gzip
- header is not retained, so applications that need that information should
- instead use raw inflate, see inflateInit2() below, or inflateBack() and
- perform their own processing of the gzip header and trailer.
-
- inflate() returns Z_OK if some progress has been made (more input processed
- or more output produced), Z_STREAM_END if the end of the compressed data has
- been reached and all uncompressed output has been produced, Z_NEED_DICT if a
- preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect check
- value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
- next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
- Z_BUF_ERROR if no progress is possible or if there was not enough room in the
- output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
- inflate() can be called again with more input and more output space to
- continue decompressing. If Z_DATA_ERROR is returned, the application may
- then call inflateSync() to look for a good compression block if a partial
- recovery of the data is desired.
-*/
-
-
-ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any pending
- output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
-
- /* Advanced functions */
-
-/*
- The following functions are needed only in some special applications.
-*/
-
-/*
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by the
- caller.
-
- The method parameter is the compression method. It must be Z_DEFLATED in
- this version of the library.
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
- deflateInit is used instead.
-
- windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
- determines the window size. deflate() will then generate raw deflate data
- with no zlib header or trailer, and will not compute an adler32 check value.
-
- windowBits can also be greater than 15 for optional gzip encoding. Add
- 16 to windowBits to write a simple gzip header and trailer around the
- compressed data instead of a zlib wrapper. The gzip header will have no
- file name, no extra data, no comment, no modification time (set to zero), no
- header crc, and the operating system will be set to 255 (unknown). If a
- gzip stream is being written, strm->adler is a crc32 instead of an adler32.
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but is
- slow and reduces compression ratio; memLevel=9 uses maximum memory for
- optimal speed. The default value is 8. See zconf.h for total memory usage
- as a function of windowBits and memLevel.
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
- filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match), or Z_RLE to limit match distances to one (run-length
- encoding). Filtered data consists mostly of small values with a somewhat
- random distribution. In this case, the compression algorithm is tuned to
- compress them better. The effect of Z_FILTERED is to force more Huffman
- coding and less string matching; it is somewhat intermediate between
- Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
- fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
- strategy parameter only affects the compression ratio but not the
- correctness of the compressed output even if it is not set appropriately.
- Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
- decoder for special applications.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
- method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
- incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
- set to null if there is no error message. deflateInit2 does not perform any
- compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any call
- of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
-
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and can be
- predicted with good accuracy; the data can then be compressed better than
- with the default empty dictionary.
-
- Depending on the size of the compression data structures selected by
- deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size
- provided in deflateInit or deflateInit2. Thus the strings most likely to be
- useful should be put at the end of the dictionary, not at the front. In
- addition, the current implementation of deflate will use at most the window
- size minus 262 bytes of the provided dictionary.
-
- Upon return of this function, strm->adler is set to the adler32 value
- of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.) If a raw deflate was requested, then the
- adler32 value is not computed and strm->adler is not set.
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
- inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and can
- consume lots of memory.
-
- deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being Z_NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-/*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state. The
- stream will keep the same compression level and any other attributes that
- may have been set by deflateInit2.
-
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being Z_NULL).
-*/
-
-ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
- int level,
- int strategy));
-/*
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in deflateInit2. This can be
- used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different strategy.
- If the compression level is changed, the input available so far is
- compressed with the old level (and may be flushed); the new level will take
- effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to be
- compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
- strm->avail_out was zero.
-*/
-
-ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
- int good_length,
- int max_lazy,
- int nice_length,
- int max_chain));
-/*
- Fine tune deflate's internal compression parameters. This should only be
- used by someone who understands the algorithm used by zlib's deflate for
- searching for the best matching string, and even then only by the most
- fanatic optimizer trying to squeeze out the last compressed bit for their
- specific input data. Read the deflate.c source code for the meaning of the
- max_lazy, good_length, nice_length, and max_chain parameters.
-
- deflateTune() can be called after deflateInit() or deflateInit2(), and
- returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
- */
-
-ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
- uLong sourceLen));
-/*
- deflateBound() returns an upper bound on the compressed size after
- deflation of sourceLen bytes. It must be called after deflateInit() or
- deflateInit2(), and after deflateSetHeader(), if used. This would be used
- to allocate an output buffer for deflation in a single pass, and so would be
- called before deflate().
-*/
-
-ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- deflatePrime() inserts bits in the deflate output stream. The intent
- is that this function is used to start off the deflate output with the bits
- leftover from a previous deflate stream when appending to it. As such, this
- function can only be used for raw deflate, and must be used before the first
- deflate() call after a deflateInit2() or deflateReset(). bits must be less
- than or equal to 16, and that many of the least significant bits of value
- will be inserted in the output.
-
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- deflateSetHeader() provides gzip header information for when a gzip
- stream is requested by deflateInit2(). deflateSetHeader() may be called
- after deflateInit2() or deflateReset() and before the first call of
- deflate(). The text, time, os, extra field, name, and comment information
- in the provided gz_header structure are written to the gzip header (xflag is
- ignored -- the extra flags are set according to the compression level). The
- caller must assure that, if not Z_NULL, name and comment are terminated with
- a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
- available there. If hcrc is true, a gzip header crc is included. Note that
- the current versions of the command-line version of gzip (up through version
- 1.3.x) do not support header crc's, and will report that it is a "multi-part
- gzip file" and give up.
-
- If deflateSetHeader is not used, the default gzip header has text false,
- the time set to zero, and os set to 255, with no extra, name, or comment
- fields. The gzip header is returned to the default state by deflateReset().
-
- deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
- int windowBits));
-
- This is another version of inflateInit with an extra parameter. The
- fields next_in, avail_in, zalloc, zfree and opaque must be initialized
- before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. windowBits must be greater than or equal to the windowBits value
- provided to deflateInit2() while compressing, or it must be equal to 15 if
- deflateInit2() was not used. If a compressed stream with a larger window
- size is given as input, inflate() will return with the error code
- Z_DATA_ERROR instead of trying to allocate a larger window.
-
- windowBits can also be zero to request that inflate use the window size in
- the zlib header of the compressed stream.
-
- windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
- determines the window size. inflate() will then process raw deflate data,
- not looking for a zlib or gzip header, not generating a check value, and not
- looking for any check values for comparison at the end of the stream. This
- is for use with other formats that use the deflate compressed data format
- such as zip. Those formats provide their own check values. If a custom
- format is developed using the raw deflate format for compressed data, it is
- recommended that a check value such as an adler32 or a crc32 be applied to
- the uncompressed data as is done in the zlib, gzip, and zip formats. For
- most applications, the zlib format should be used as is. Note that comments
- above on the use in deflateInit2() applies to the magnitude of windowBits.
-
- windowBits can also be greater than 15 for optional gzip decoding. Add
- 32 to windowBits to enable zlib and gzip decoding with automatic header
- detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
- crc32 instead of an adler32.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller, or Z_STREAM_ERROR if the parameters are
- invalid, such as a null pointer to the structure. msg is set to null if
- there is no error message. inflateInit2 does not perform any decompression
- apart from possibly reading the zlib header if present: actual decompression
- will be done by inflate(). (So next_in and avail_in may be modified, but
- next_out and avail_out are unused and unchanged.) The current implementation
- of inflateInit2() does not process any header information -- that is
- deferred until inflate() is called.
-*/
-
-ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate,
- if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the adler32 value returned by that call of inflate.
- The compressor and decompressor must use exactly the same dictionary (see
- deflateSetDictionary). For raw inflate, this function can be called
- immediately after inflateInit2() or inflateReset() and before any call of
- inflate() to set the dictionary. The application must insure that the
- dictionary that was used for compression is provided.
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
- inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect adler32 value). inflateSetDictionary does not
- perform any decompression: this will be done by subsequent calls of
- inflate().
-*/
-
-ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
-
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been
- found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the
- success case, the application may save the current current value of total_in
- which indicates where valid compressed data was found. In the error case,
- the application may repeatedly call inflateSync, providing more input each
- time, until success or end of the input data.
-*/
-
-ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when randomly accessing a large stream. The
- first pass through the stream can periodically record the inflate state,
- allowing restarting inflate at those points when randomly accessing the
- stream.
-
- inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being Z_NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state. The
- stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being Z_NULL).
-*/
-
-ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
- int windowBits));
-/*
- This function is the same as inflateReset, but it also permits changing
- the wrap and window size requests. The windowBits parameter is interpreted
- the same as it is for inflateInit2.
-
- inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being Z_NULL), or if
- the windowBits parameter is invalid.
-*/
-
-ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- This function inserts bits in the inflate input stream. The intent is
- that this function is used to start inflating at a bit position in the
- middle of a byte. The provided bits will be used before any bytes are used
- from next_in. This function should only be used with raw inflate, and
- should be used before the first inflate() call after inflateInit2() or
- inflateReset(). bits must be less than or equal to 16, and that many of the
- least significant bits of value will be inserted in the input.
-
- If bits is negative, then the input stream bit buffer is emptied. Then
- inflatePrime() can be called again to put bits in the buffer. This is used
- to clear out bits leftover after feeding inflate a block description prior
- to feeding inflate codes.
-
- inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
-/*
- This function returns two values, one in the lower 16 bits of the return
- value, and the other in the remaining upper bits, obtained by shifting the
- return value down 16 bits. If the upper value is -1 and the lower value is
- zero, then inflate() is currently decoding information outside of a block.
- If the upper value is -1 and the lower value is non-zero, then inflate is in
- the middle of a stored block, with the lower value equaling the number of
- bytes from the input remaining to copy. If the upper value is not -1, then
- it is the number of bits back from the current bit position in the input of
- the code (literal or length/distance pair) currently being processed. In
- that case the lower value is the number of bytes already emitted for that
- code.
-
- A code is being processed if inflate is waiting for more input to complete
- decoding of the code, or if it has completed decoding but is waiting for
- more output space to write the literal or match data.
-
- inflateMark() is used to mark locations in the input data for random
- access, which may be at bit positions, and to note those cases where the
- output of a code may span boundaries of random access blocks. The current
- location in the input stream can be determined from avail_in and data_type
- as noted in the description for the Z_BLOCK flush parameter for inflate.
-
- inflateMark returns the value noted above or -1 << 16 if the provided
- source stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- inflateGetHeader() requests that gzip header information be stored in the
- provided gz_header structure. inflateGetHeader() may be called after
- inflateInit2() or inflateReset(), and before the first call of inflate().
- As inflate() processes the gzip stream, head->done is zero until the header
- is completed, at which time head->done is set to one. If a zlib stream is
- being decoded, then head->done is set to -1 to indicate that there will be
- no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
- used to force inflate() to return immediately after header processing is
- complete and before any actual data is decompressed.
-
- The text, time, xflags, and os fields are filled in with the gzip header
- contents. hcrc is set to true if there is a header CRC. (The header CRC
- was valid if done is set to one.) If extra is not Z_NULL, then extra_max
- contains the maximum number of bytes to write to extra. Once done is true,
- extra_len contains the actual extra field length, and extra contains the
- extra field, or that field truncated if extra_max is less than extra_len.
- If name is not Z_NULL, then up to name_max characters are written there,
- terminated with a zero unless the length is greater than name_max. If
- comment is not Z_NULL, then up to comm_max characters are written there,
- terminated with a zero unless the length is greater than comm_max. When any
- of extra, name, or comment are not Z_NULL and the respective field is not
- present in the header, then that field is set to Z_NULL to signal its
- absence. This allows the use of deflateSetHeader() with the returned
- structure to duplicate the header. However if those fields are set to
- allocated memory, then the application will need to save those pointers
- elsewhere so that they can be eventually freed.
-
- If inflateGetHeader is not used, then the header information is simply
- discarded. The header is always checked for validity, including the header
- CRC if present. inflateReset() will reset the process to discard the header
- information. The application would need to call inflateGetHeader() again to
- retrieve the header from the next gzip stream.
-
- inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
- unsigned char FAR *window));
-
- Initialize the internal stream state for decompression using inflateBack()
- calls. The fields zalloc, zfree and opaque in strm must be initialized
- before the call. If zalloc and zfree are Z_NULL, then the default library-
- derived memory allocation routines are used. windowBits is the base two
- logarithm of the window size, in the range 8..15. window is a caller
- supplied buffer of that size. Except for special applications where it is
- assured that deflate was used with small window sizes, windowBits must be 15
- and a 32K byte window must be supplied to be able to decompress general
- deflate streams.
-
- See inflateBack() for the usage of these routines.
-
- inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
- allocated, or Z_VERSION_ERROR if the version of the library does not match
- the version of the header file.
-*/
-
-typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
-typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
-
-ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
- in_func in, void FAR *in_desc,
- out_func out, void FAR *out_desc));
-/*
- inflateBack() does a raw inflate with a single call using a call-back
- interface for input and output. This is more efficient than inflate() for
- file i/o applications in that it avoids copying between the output and the
- sliding window by simply making the window itself the output buffer. This
- function trusts the application to not change the output buffer passed by
- the output function, at least until inflateBack() returns.
-
- inflateBackInit() must be called first to allocate the internal state
- and to initialize the state with the user-provided window buffer.
- inflateBack() may then be used multiple times to inflate a complete, raw
- deflate stream with each call. inflateBackEnd() is then called to free the
- allocated state.
-
- A raw deflate stream is one with no zlib or gzip header or trailer.
- This routine would normally be used in a utility that reads zip or gzip
- files and writes out uncompressed files. The utility would decode the
- header and process the trailer on its own, hence this routine expects only
- the raw deflate stream to decompress. This is different from the normal
- behavior of inflate(), which expects either a zlib or gzip header and
- trailer around the deflate stream.
-
- inflateBack() uses two subroutines supplied by the caller that are then
- called by inflateBack() for input and output. inflateBack() calls those
- routines until it reads a complete deflate stream and writes out all of the
- uncompressed data, or until it encounters an error. The function's
- parameters and return types are defined above in the in_func and out_func
- typedefs. inflateBack() will call in(in_desc, &buf) which should return the
- number of bytes of provided input, and a pointer to that input in buf. If
- there is no input available, in() must return zero--buf is ignored in that
- case--and inflateBack() will return a buffer error. inflateBack() will call
- out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
- should return zero on success, or non-zero on failure. If out() returns
- non-zero, inflateBack() will return with an error. Neither in() nor out()
- are permitted to change the contents of the window provided to
- inflateBackInit(), which is also the buffer that out() uses to write from.
- The length written by out() will be at most the window size. Any non-zero
- amount of input may be provided by in().
-
- For convenience, inflateBack() can be provided input on the first call by
- setting strm->next_in and strm->avail_in. If that input is exhausted, then
- in() will be called. Therefore strm->next_in must be initialized before
- calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
- immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
- must also be initialized, and then if strm->avail_in is not zero, input will
- initially be taken from strm->next_in[0 .. strm->avail_in - 1].
-
- The in_desc and out_desc parameters of inflateBack() is passed as the
- first parameter of in() and out() respectively when they are called. These
- descriptors can be optionally used to pass any information that the caller-
- supplied in() and out() functions need to do their job.
-
- On return, inflateBack() will set strm->next_in and strm->avail_in to
- pass back any unused input that was provided by the last in() call. The
- return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
- if in() or out() returned an error, Z_DATA_ERROR if there was a format error
- in the deflate stream (in which case strm->msg is set to indicate the nature
- of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
- In the case of Z_BUF_ERROR, an input or output error can be distinguished
- using strm->next_in which will be Z_NULL only if in() returned an error. If
- strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
- non-zero. (in() will always be called before out(), so strm->next_in is
- assured to be defined if out() returns non-zero.) Note that inflateBack()
- cannot return Z_OK.
-*/
-
-ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
-/*
- All memory allocated by inflateBackInit() is freed.
-
- inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
- state was inconsistent.
-*/
-
-ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
-/* Return flags indicating compile-time options.
-
- Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
- 1.0: size of uInt
- 3.2: size of uLong
- 5.4: size of voidpf (pointer)
- 7.6: size of z_off_t
-
- Compiler, assembler, and debug options:
- 8: DEBUG
- 9: ASMV or ASMINF -- use ASM code
- 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
- 11: 0 (reserved)
-
- One-time table building (smaller code, but not thread-safe if true):
- 12: BUILDFIXED -- build static block decoding tables when needed
- 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
- 14,15: 0 (reserved)
-
- Library content (indicates missing functionality):
- 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
- deflate code when not needed)
- 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
- and decode gzip streams (to avoid linking crc code)
- 18-19: 0 (reserved)
-
- Operation variations (changes in library functionality):
- 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
- 21: FASTEST -- deflate algorithm with only one, lowest compression level
- 22,23: 0 (reserved)
-
- The sprintf variant used by gzprintf (zero is best):
- 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
- 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
- 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
-
- Remainder:
- 27-31: 0 (reserved)
- */
-
-
- /* utility functions */
-
-/*
- The following utility functions are implemented on top of the basic
- stream-oriented functions. To simplify the interface, some default options
- are assumed (compression level and memory usage, standard memory allocation
- functions). The source code of these utility functions can be modified if
- you need special options.
-*/
-
-ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total size
- of the destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
-
- compress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer.
-*/
-
-ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen,
- int level));
-/*
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-
-ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
-/*
- compressBound() returns an upper bound on the compressed size after
- compress() or compress2() on sourceLen bytes. It would be used before a
- compress() or compress2() call to allocate the destination buffer.
-*/
-
-ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total size
- of the destination buffer, which must be large enough to hold the entire
- uncompressed data. (The size of the uncompressed data must have been saved
- previously by the compressor and transmitted to the decompressor by some
- mechanism outside the scope of this compression library.) Upon exit, destLen
- is the actual size of the uncompressed buffer.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
-*/
-
-
- /* gzip file access functions */
-
-/*
- This library supports reading and writing files in gzip (.gz) format with
- an interface similar to that of stdio, using the functions that start with
- "gz". The gzip format is different from the zlib format. gzip is a gzip
- wrapper, documented in RFC 1952, wrapped around a deflate stream.
-*/
-
-typedef voidp gzFile; /* opaque gzip file descriptor */
-
-/*
-ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-
- Opens a gzip (.gz) file for reading or writing. The mode parameter is as
- in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
- a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
- compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
- for fixed code compression as in "wb9F". (See the description of
- deflateInit2 for more information about the strategy parameter.) Also "a"
- can be used instead of "w" to request that the gzip stream that will be
- written be appended to the file. "+" will result in an error, since reading
- and writing to the same gzip file is not supported.
-
- gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
-
- gzopen returns NULL if the file could not be opened, if there was
- insufficient memory to allocate the gzFile state, or if an invalid mode was
- specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
- errno can be checked to determine if the reason gzopen failed was that the
- file could not be opened.
-*/
-
-ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-/*
- gzdopen associates a gzFile with the file descriptor fd. File descriptors
- are obtained from calls like open, dup, creat, pipe or fileno (if the file
- has been previously opened with fopen). The mode parameter is as in gzopen.
-
- The next call of gzclose on the returned gzFile will also close the file
- descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
- fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
- mode);. The duplicated descriptor should be saved to avoid a leak, since
- gzdopen does not close fd if it fails.
-
- gzdopen returns NULL if there was insufficient memory to allocate the
- gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
- provided, or '+' was provided), or if fd is -1. The file descriptor is not
- used until the next gz* read, write, seek, or close operation, so gzdopen
- will not detect if fd is invalid (unless fd is -1).
-*/
-
-ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
-/*
- Set the internal buffer size used by this library's functions. The
- default buffer size is 8192 bytes. This function must be called after
- gzopen() or gzdopen(), and before any other calls that read or write the
- file. The buffer memory allocation is always deferred to the first read or
- write. Two buffers are allocated, either both of the specified size when
- writing, or one of the specified size and the other twice that size when
- reading. A larger buffer size of, for example, 64K or 128K bytes will
- noticeably increase the speed of decompression (reading).
-
- The new buffer size also affects the maximum length for gzprintf().
-
- gzbuffer() returns 0 on success, or -1 on failure, such as being called
- too late.
-*/
-
-ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-/*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters.
-
- gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
- opened for writing.
-*/
-
-ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-/*
- Reads the given number of uncompressed bytes from the compressed file. If
- the input file was not in gzip format, gzread copies the given number of
- bytes into the buffer.
-
- After reaching the end of a gzip stream in the input, gzread will continue
- to read, looking for another gzip stream, or failing that, reading the rest
- of the input file directly without decompression. The entire input file
- will be read if gzread is called until it returns less than the requested
- len.
-
- gzread returns the number of uncompressed bytes actually read, less than
- len for end of file, or -1 for error.
-*/
-
-ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
-/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes written or 0 in case of
- error.
-*/
-
-ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-/*
- Converts, formats, and writes the arguments to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written, or 0 in case of error. The number of
- uncompressed bytes written is limited to 8191, or one less than the buffer
- size given to gzbuffer(). The caller should assure that this limit is not
- exceeded. If it is exceeded, then gzprintf() will return an error (0) with
- nothing written. In this case, there may also be a buffer overflow with
- unpredictable consequences, which is possible only if zlib was compiled with
- the insecure functions sprintf() or vsprintf() because the secure snprintf()
- or vsnprintf() functions were not available. This can be determined using
- zlibCompileFlags().
-*/
-
-ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-/*
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
-
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-
-ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-/*
- Reads bytes from the compressed file until len-1 characters are read, or a
- newline character is read and transferred to buf, or an end-of-file
- condition is encountered. If any characters are read or if len == 1, the
- string is terminated with a null character. If no characters are read due
- to an end-of-file or len < 1, then the buffer is left untouched.
-
- gzgets returns buf which is a null-terminated string, or it returns NULL
- for end-of-file or in case of error. If there was an error, the contents at
- buf are indeterminate.
-*/
-
-ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-/*
- Writes c, converted to an unsigned char, into the compressed file. gzputc
- returns the value that was written, or -1 in case of error.
-*/
-
-ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-/*
- Reads one byte from the compressed file. gzgetc returns this byte or -1
- in case of end of file or error.
-*/
-
-ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
-/*
- Push one character back onto the stream to be read as the first character
- on the next read. At least one character of push-back is allowed.
- gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
- fail if c is -1, and may fail if a character has been pushed but not read
- yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
- output buffer size of pushed characters is allowed. (See gzbuffer above.)
- The pushed character will be discarded if the stream is repositioned with
- gzseek() or gzrewind().
-*/
-
-ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-/*
- Flushes all pending output into the compressed file. The parameter flush
- is as in the deflate() function. The return value is the zlib error number
- (see function gzerror below). gzflush is only permitted when writing.
-
- If the flush parameter is Z_FINISH, the remaining data is written and the
- gzip stream is completed in the output. If gzwrite() is called again, a new
- gzip stream will be started in the output. gzread() is able to read such
- concatented gzip streams.
-
- gzflush should be called only when strictly necessary because it will
- degrade compression if called too often.
-*/
-
-/*
-ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
-
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
- the value SEEK_END is not supported.
-
- If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
- supported; gzseek then compresses a sequence of zeroes up to the new
- starting position.
-
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error, in
- particular if the file is opened for writing and the new starting position
- would be before the current position.
-*/
-
-ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-/*
- Rewinds the given file. This function is supported only for reading.
-
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-*/
-
-/*
-ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-
- Returns the starting position for the next gzread or gzwrite on the given
- compressed file. This position represents a number of bytes in the
- uncompressed data stream, and is zero when starting, even if appending or
- reading a gzip stream from the middle of a file using gzdopen().
-
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-*/
-
-/*
-ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
-
- Returns the current offset in the file being read or written. This offset
- includes the count of bytes that precede the gzip stream, for example when
- appending or when using gzdopen() for reading. When reading, the offset
- does not include as yet unused buffered input. This information can be used
- for a progress indicator. On error, gzoffset() returns -1.
-*/
-
-ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-/*
- Returns true (1) if the end-of-file indicator has been set while reading,
- false (0) otherwise. Note that the end-of-file indicator is set only if the
- read tried to go past the end of the input, but came up short. Therefore,
- just like feof(), gzeof() may return false even if there is no more data to
- read, in the event that the last read request was for the exact number of
- bytes remaining in the input file. This will happen if the input file size
- is an exact multiple of the buffer size.
-
- If gzeof() returns true, then the read functions will return no more data,
- unless the end-of-file indicator is reset by gzclearerr() and the input file
- has grown since the previous end of file was detected.
-*/
-
-ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
-/*
- Returns true (1) if file is being copied directly while reading, or false
- (0) if file is a gzip stream being decompressed. This state can change from
- false to true while reading the input file if the end of a gzip stream is
- reached, but is followed by data that is not another gzip stream.
-
- If the input file is empty, gzdirect() will return true, since the input
- does not contain a gzip stream.
-
- If gzdirect() is used immediately after gzopen() or gzdopen() it will
- cause buffers to be allocated to allow reading the file to determine if it
- is a gzip file. Therefore if gzbuffer() is used, it should be called before
- gzdirect().
-*/
-
-ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-/*
- Flushes all pending output if necessary, closes the compressed file and
- deallocates the (de)compression state. Note that once file is closed, you
- cannot call gzerror with file, since its structures have been deallocated.
- gzclose must not be called more than once on the same file, just as free
- must not be called more than once on the same allocation.
-
- gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
- file operation error, or Z_OK on success.
-*/
-
-ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
-ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
-/*
- Same as gzclose(), but gzclose_r() is only for use when reading, and
- gzclose_w() is only for use when writing or appending. The advantage to
- using these instead of gzclose() is that they avoid linking in zlib
- compression or decompression code that is not used when only reading or only
- writing respectively. If gzclose() is used, then both compression and
- decompression code will be included the application when linking to a static
- zlib library.
-*/
-
-ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-/*
- Returns the error message for the last error which occurred on the given
- compressed file. errnum is set to zlib error number. If an error occurred
- in the file system and not in the compression library, errnum is set to
- Z_ERRNO and the application may consult errno to get the exact error code.
-
- The application must not modify the returned string. Future calls to
- this function may invalidate the previously returned string. If file is
- closed, then the string previously returned by gzerror will no longer be
- available.
-
- gzerror() should be used to distinguish errors from end-of-file for those
- functions above that do not distinguish those cases in their return values.
-*/
-
-ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
-/*
- Clears the error and end-of-file flags for file. This is analogous to the
- clearerr() function in stdio. This is useful for continuing to read a gzip
- file that is being written concurrently.
-*/
-
-
- /* checksum functions */
-
-/*
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the compression
- library.
-*/
-
-ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is Z_NULL, this function returns the
- required initial value for the checksum.
-
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster.
-
- Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-/*
-ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
- z_off_t len2));
-
- Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
- and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
- each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
- seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
-*/
-
-ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-/*
- Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is Z_NULL, this function returns the required
- initial value for the for the crc. Pre- and post-conditioning (one's
- complement) is performed within this function so it shouldn't be done by the
- application.
-
- Usage example:
-
- uLong crc = crc32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = crc32(crc, buffer, length);
- }
- if (crc != original_crc) error();
-*/
-
-/*
-ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
-
- Combine two CRC-32 check values into one. For two sequences of bytes,
- seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
- calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
- check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
- len2.
-*/
-
-
- /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel,
- int strategy, const char *version,
- int stream_size));
-ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
- unsigned char FAR *window,
- const char *version,
- int stream_size));
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-#define inflateBackInit(strm, windowBits, window) \
- inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
-
-/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
- * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
- * both are true, the application gets the *64 functions, and the regular
- * functions are changed to 64 bits) -- in case these are set on systems
- * without large file support, _LFS64_LARGEFILE must also be true
- */
-#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
- ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
- ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
- ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
- ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
- ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
- ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
-#endif
-
-#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
-# define gzopen gzopen64
-# define gzseek gzseek64
-# define gztell gztell64
-# define gzoffset gzoffset64
-# define adler32_combine adler32_combine64
-# define crc32_combine crc32_combine64
-# ifdef _LARGEFILE64_SOURCE
- ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
- ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
- ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
- ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
- ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
- ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
-# endif
-#else
- ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
- ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
- ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
- ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
- ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
- ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
-#endif
-
-/* hack for buggy compilers */
-#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;};
-#endif
-
-/* undocumented functions */
-ZEXTERN const char * ZEXPORT zError OF((int));
-ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
-ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZLIB_H */
diff --git a/security/nss/lib/zlib/zutil.c b/security/nss/lib/zlib/zutil.c
deleted file mode 100644
index 898ed345b..000000000
--- a/security/nss/lib/zlib/zutil.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005, 2010 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zutil.h"
-
-#ifndef NO_DUMMY_DECL
-struct internal_state {int dummy;}; /* for buggy compilers */
-#endif
-
-const char * const z_errmsg[10] = {
-"need dictionary", /* Z_NEED_DICT 2 */
-"stream end", /* Z_STREAM_END 1 */
-"", /* Z_OK 0 */
-"file error", /* Z_ERRNO (-1) */
-"stream error", /* Z_STREAM_ERROR (-2) */
-"data error", /* Z_DATA_ERROR (-3) */
-"insufficient memory", /* Z_MEM_ERROR (-4) */
-"buffer error", /* Z_BUF_ERROR (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char * ZEXPORT zlibVersion()
-{
- return ZLIB_VERSION;
-}
-
-uLong ZEXPORT zlibCompileFlags()
-{
- uLong flags;
-
- flags = 0;
- switch ((int)(sizeof(uInt))) {
- case 2: break;
- case 4: flags += 1; break;
- case 8: flags += 2; break;
- default: flags += 3;
- }
- switch ((int)(sizeof(uLong))) {
- case 2: break;
- case 4: flags += 1 << 2; break;
- case 8: flags += 2 << 2; break;
- default: flags += 3 << 2;
- }
- switch ((int)(sizeof(voidpf))) {
- case 2: break;
- case 4: flags += 1 << 4; break;
- case 8: flags += 2 << 4; break;
- default: flags += 3 << 4;
- }
- switch ((int)(sizeof(z_off_t))) {
- case 2: break;
- case 4: flags += 1 << 6; break;
- case 8: flags += 2 << 6; break;
- default: flags += 3 << 6;
- }
-#ifdef DEBUG
- flags += 1 << 8;
-#endif
-#if defined(ASMV) || defined(ASMINF)
- flags += 1 << 9;
-#endif
-#ifdef ZLIB_WINAPI
- flags += 1 << 10;
-#endif
-#ifdef BUILDFIXED
- flags += 1 << 12;
-#endif
-#ifdef DYNAMIC_CRC_TABLE
- flags += 1 << 13;
-#endif
-#ifdef NO_GZCOMPRESS
- flags += 1L << 16;
-#endif
-#ifdef NO_GZIP
- flags += 1L << 17;
-#endif
-#ifdef PKZIP_BUG_WORKAROUND
- flags += 1L << 20;
-#endif
-#ifdef FASTEST
- flags += 1L << 21;
-#endif
-#ifdef STDC
-# ifdef NO_vsnprintf
- flags += 1L << 25;
-# ifdef HAS_vsprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_vsnprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#else
- flags += 1L << 24;
-# ifdef NO_snprintf
- flags += 1L << 25;
-# ifdef HAS_sprintf_void
- flags += 1L << 26;
-# endif
-# else
-# ifdef HAS_snprintf_void
- flags += 1L << 26;
-# endif
-# endif
-#endif
- return flags;
-}
-
-#ifdef DEBUG
-
-# ifndef verbose
-# define verbose 0
-# endif
-int ZLIB_INTERNAL z_verbose = verbose;
-
-void ZLIB_INTERNAL z_error (m)
- char *m;
-{
- fprintf(stderr, "%s\n", m);
- exit(1);
-}
-#endif
-
-/* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
-const char * ZEXPORT zError(err)
- int err;
-{
- return ERR_MSG(err);
-}
-
-#if defined(_WIN32_WCE)
- /* The Microsoft C Run-Time Library for Windows CE doesn't have
- * errno. We define it as a global variable to simplify porting.
- * Its value is always 0 and should not be used.
- */
- int errno = 0;
-#endif
-
-#ifndef HAVE_MEMCPY
-
-void ZLIB_INTERNAL zmemcpy(dest, source, len)
- Bytef* dest;
- const Bytef* source;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = *source++; /* ??? to be unrolled */
- } while (--len != 0);
-}
-
-int ZLIB_INTERNAL zmemcmp(s1, s2, len)
- const Bytef* s1;
- const Bytef* s2;
- uInt len;
-{
- uInt j;
-
- for (j = 0; j < len; j++) {
- if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
- }
- return 0;
-}
-
-void ZLIB_INTERNAL zmemzero(dest, len)
- Bytef* dest;
- uInt len;
-{
- if (len == 0) return;
- do {
- *dest++ = 0; /* ??? to be unrolled */
- } while (--len != 0);
-}
-#endif
-
-
-#ifdef SYS16BIT
-
-#ifdef __TURBOC__
-/* Turbo C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
- voidpf org_ptr;
- voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
- voidpf buf = opaque; /* just to make some compilers happy */
- ulg bsize = (ulg)items*size;
-
- /* If we allocate less than 65520 bytes, we assume that farmalloc
- * will return a usable pointer which doesn't have to be normalized.
- */
- if (bsize < 65520L) {
- buf = farmalloc(bsize);
- if (*(ush*)&buf != 0) return buf;
- } else {
- buf = farmalloc(bsize + 16L);
- }
- if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
- table[next_ptr].org_ptr = buf;
-
- /* Normalize the pointer to seg:0 */
- *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
- *(ush*)&buf = 0;
- table[next_ptr++].new_ptr = buf;
- return buf;
-}
-
-void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
-{
- int n;
- if (*(ush*)&ptr != 0) { /* object < 64K */
- farfree(ptr);
- return;
- }
- /* Find the original pointer */
- for (n = 0; n < next_ptr; n++) {
- if (ptr != table[n].new_ptr) continue;
-
- farfree(table[n].org_ptr);
- while (++n < next_ptr) {
- table[n-1] = table[n];
- }
- next_ptr--;
- return;
- }
- ptr = opaque; /* just to make some compilers happy */
- Assert(0, "zcfree: ptr not found");
-}
-
-#endif /* __TURBOC__ */
-
-
-#ifdef M_I86
-/* Microsoft C in 16-bit mode */
-
-# define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-# define _halloc halloc
-# define _hfree hfree
-#endif
-
-voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- return _halloc((long)items, size);
-}
-
-void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
-{
- if (opaque) opaque = 0; /* to make compiler happy */
- _hfree(ptr);
-}
-
-#endif /* M_I86 */
-
-#endif /* SYS16BIT */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp malloc OF((uInt size));
-extern voidp calloc OF((uInt items, uInt size));
-extern void free OF((voidpf ptr));
-#endif
-
-voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
- voidpf opaque;
- unsigned items;
- unsigned size;
-{
- if (opaque) items += size - size; /* make compiler happy */
- return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
- (voidpf)calloc(items, size);
-}
-
-void ZLIB_INTERNAL zcfree (opaque, ptr)
- voidpf opaque;
- voidpf ptr;
-{
- free(ptr);
- if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
diff --git a/security/nss/lib/zlib/zutil.h b/security/nss/lib/zlib/zutil.h
deleted file mode 100644
index d6ee23c6f..000000000
--- a/security/nss/lib/zlib/zutil.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2010 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZUTIL_H
-#define ZUTIL_H
-
-#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
-# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
-#else
-# define ZLIB_INTERNAL
-#endif
-
-#include "zlib.h"
-
-#ifdef STDC
-# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
-# include <stddef.h>
-# endif
-# include <string.h>
-# include <stdlib.h>
-#endif
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
- return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
- /* common constants */
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
- /* target dependencies */
-
-#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
-# define OS_CODE 0x00
-# if defined(__TURBOC__) || defined(__BORLANDC__)
-# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
- /* Allow compilation with ANSI keywords only enabled */
- void _Cdecl farfree( void *block );
- void *_Cdecl farmalloc( unsigned long nbytes );
-# else
-# include <alloc.h>
-# endif
-# else /* MSC or DJGPP */
-# include <malloc.h>
-# endif
-#endif
-
-#ifdef AMIGA
-# define OS_CODE 0x01
-#endif
-
-#if defined(VAXC) || defined(VMS)
-# define OS_CODE 0x02
-# define F_OPEN(name, mode) \
- fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#if defined(ATARI) || defined(atarist)
-# define OS_CODE 0x05
-#endif
-
-#ifdef OS2
-# define OS_CODE 0x06
-# ifdef M_I86
-# include <malloc.h>
-# endif
-#endif
-
-#if defined(MACOS) || defined(TARGET_OS_MAC)
-# define OS_CODE 0x07
-# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-# include <unix.h> /* for fdopen */
-# else
-# ifndef fdopen
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# endif
-# endif
-#endif
-
-#ifdef TOPS20
-# define OS_CODE 0x0a
-#endif
-
-#ifdef WIN32
-# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
-# define OS_CODE 0x0b
-# endif
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-# define OS_CODE 0x0f
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
-# if defined(_WIN32_WCE)
-# define fdopen(fd,mode) NULL /* No fdopen() */
-# ifndef _PTRDIFF_T_DEFINED
- typedef int ptrdiff_t;
-# define _PTRDIFF_T_DEFINED
-# endif
-# else
-# define fdopen(fd,type) _fdopen(fd,type)
-# endif
-#endif
-
-#if defined(__BORLANDC__)
- #pragma warn -8004
- #pragma warn -8008
- #pragma warn -8066
-#endif
-
-/* provide prototypes for these when building zlib without LFS */
-#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
- ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
- ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
-#endif
-
- /* common defaults */
-
-#ifndef OS_CODE
-# define OS_CODE 0x03 /* assume Unix */
-#endif
-
-#ifndef F_OPEN
-# define F_OPEN(name, mode) fopen((name), (mode))
-#endif
-
- /* functions */
-
-#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) || \
- (defined(_MSC_VER) && _MSC_VER >= 1500)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#if defined(__CYGWIN__)
-# ifndef HAVE_VSNPRINTF
-# define HAVE_VSNPRINTF
-# endif
-#endif
-#ifndef HAVE_VSNPRINTF
-# ifdef MSDOS
- /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
- but for now we just assume it doesn't. */
-# define NO_vsnprintf
-# endif
-# ifdef __TURBOC__
-# define NO_vsnprintf
-# endif
-# ifdef WIN32
- /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
-# if !defined(vsnprintf) && !defined(NO_vsnprintf)
-# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
-# define vsnprintf _vsnprintf
-# endif
-# endif
-# endif
-# ifdef __SASC
-# define NO_vsnprintf
-# endif
-#endif
-#ifdef VMS
-# define NO_vsnprintf
-#endif
-
-#if defined(pyr)
-# define NO_MEMCPY
-#endif
-#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
- /* Use our own functions for small and medium model with MSC <= 5.0.
- * You may have to use the same strategy for Borland C (untested).
- * The __SC__ check is for Symantec.
- */
-# define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-# define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-# define zmemcpy _fmemcpy
-# define zmemcmp _fmemcmp
-# define zmemzero(dest, len) _fmemset(dest, 0, len)
-# else
-# define zmemcpy memcpy
-# define zmemcmp memcmp
-# define zmemzero(dest, len) memset(dest, 0, len)
-# endif
-#else
- void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
- int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
- void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# include <stdio.h>
- extern int ZLIB_INTERNAL z_verbose;
- extern void ZLIB_INTERNAL z_error OF((char *m));
-# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-# define Assert(cond,msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
-#endif
-
-
-voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
- unsigned size));
-void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
- (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* ZUTIL_H */